diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/404.html b/404.html new file mode 100644 index 0000000000..bf57e98c52 --- /dev/null +++ b/404.html @@ -0,0 +1,23 @@ + + + + + +Page Not Found | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+ + \ No newline at end of file diff --git a/assets/css/styles.6d33ddd4.css b/assets/css/styles.6d33ddd4.css new file mode 100644 index 0000000000..6d89b6a6e7 --- /dev/null +++ b/assets/css/styles.6d33ddd4.css @@ -0,0 +1 @@ +.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}*,.loadingRing_RJI3 div{box-sizing:border-box}.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem;--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#0f5fe1;--ifm-color-primary-dark:##0e56cb;--ifm-color-primary-darker:##0c4cb4;--ifm-color-primary-darkest:##0b439e;--ifm-color-primary-light:##276fe4;--ifm-color-primary-lighter:##3f7fe7;--ifm-color-primary-lightest:##578fea;--ifm-code-font-size:95%;--docusaurus-highlighted-code-line-bg:#0000001a;--docusaurus-announcement-bar-height:auto;--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300)}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}html{-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);text-rendering:optimizelegibility}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.list_eTzJ article:last-child,.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none,.tabItem_LNqP{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}.container_lyt7,.container_lyt7>svg,img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul,.tabList__CuJ{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;margin-bottom:var(--ifm-spacing-vertical);display:table!important}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_Gvgb,.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after,.searchBarContainer_NW3z.searchIndexLoading_EJ1f .searchBarLoadingRing_YnHq{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);text-decoration:none}.content_knG7 a,.hitFooter_E9YW a,.suggestion_fB_2.cursor_eG29 mark{text-decoration:underline}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;pointer-events:none;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color);text-decoration:none}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item{margin-top:0}.admonitionContent_BuS1>:last-child,.cardContainer_fWXF :last-child,.collapsibleContent_i85q p:last-child,.details_lb9f>summary>p:last-child,.footer__items,.searchResultItem_U687>h2,.tabItem_Ymn6>:last-child{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title,.title_f1Hy{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color);text-decoration:none}.menu__caret:before,.menu__link--sublist-caret:after{content:"";height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem;filter:var(--ifm-menu-link-sublist-icon-filter)}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{left:0;opacity:0;position:fixed;top:0;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;bottom:0;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.modalH2_DhYb,.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}#nprogress,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{-webkit-appearance:none;appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:.9rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}#nprogress .bar,.modal__zVM{left:0;top:0;position:fixed}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.button_MlC2,.button_gV6k,.link_nBo6,.link_wr7g,.pagination__link:hover,.sidebarItemLink_mo7H:hover{text-decoration:none}.pagination-nav{grid-gap:var(--ifm-spacing-horizontal);display:grid;gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover);text-decoration:none}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]{--ifm-color-primary:#0f5fe1;--ifm-color-primary-dark:##0e56cb;--ifm-color-primary-darker:##0c4cb4;--ifm-color-primary-darkest:##0b439e;--ifm-color-primary-light:##276fe4;--ifm-color-primary-lighter:##3f7fe7;--ifm-color-primary-lightest:##578fea;--docusaurus-highlighted-code-line-bg:#0000004d}.button_MlC2,.button_gV6k{background-color:#50c3a5;border:none;border-radius:8px;color:#fff;cursor:pointer;display:inline-block;font-size:16px;font-weight:600;padding:15px 32px;text-align:center}.button_MlC2:hover,.button_gV6k:hover{background-color:#0f5fe1}.modal__zVM{align-items:center;background-color:#00000080;bottom:0;display:flex;justify-content:center;overflow-y:scroll;right:0;z-index:1000}.modalContent_zbmJ{background-color:#fff;max-height:100%;max-width:100%;width:500px}.sidebar_re4s,.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem)}.modalTitle_u975{border-bottom:2px solid #eee;padding:32px}.modalDescription_H8cB{padding:32px}.buttonBox_NbRn{text-align:left}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.contentCard_uSpk{border:2px solid #666;box-shadow:2px 2px 4px 4px #0a0a0a1a}.layerComponent_syzR{background:#43d8b24f;border:2px solid rgba(70,72,213,.539);border-radius:4px;font-weight:600}.layerComponentWip_fSEJ,.layerComponent_syzR{color:#000;font-size:10px;height:80px;margin:0 0 8px 8px;padding:8px;text-decoration:none;width:80px}.layerComponentWip_fSEJ{background-image:repeating-linear-gradient(45deg,#fff,#fff 2%,#43d8b24f 0,#43d8b24f 4%,#fff 0);border:2px dashed rgba(70,72,213,.539);border-radius:4px}.layerComponentWip_fSEJ:hover,.layerComponent_syzR:hover{background-color:#43d8b22f;color:#00f;text-decoration:none!important}.chipOptional_fyWu{background-color:#892be27b}.chipMandatory_Xe7e,.chipOptional_fyWu{border-radius:8px;color:#000;font-size:8px;margin:2px 2px 0 0;max-width:-moz-fit-content;max-width:fit-content;padding:2px 4px;text-align:center}.chipMandatory_Xe7e{background-color:#e2a82b94}.gradient_pRJN{background:linear-gradient(180deg,#0061ff33 20%,#50c3a5 50%,#50c3a5 80%);border-radius:16px;display:block;margin:4px}.border_XcL8{border:4px solid #0061ff;border-radius:16px;margin:4px}.bottom_ufNC{margin-bottom:16px}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}#__docusaurus-base-url-issue-banner-container,.docSidebarContainer_YfHR,.hideAction_vcyE>svg,.sidebarLogo_isFc,.themedComponent_mlkZ,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark] .themedComponent--dark_xIcU,[data-theme=light] .themedComponent--light_NVdE,html:not([data-theme]) .themedComponent--light_NVdE{display:initial}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.iconExternalLink_nPIU{margin-left:.3rem}.docMainContainer_TBSr,.docRoot_UBD9{display:flex;width:100%}.docsWrapper_hBAB{display:flex;flex:1 0 auto}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;user-select:none}.hash-link:before{content:"#"}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.cardContainer_fWXF{--ifm-link-color:var(--ifm-color-emphasis-800);--ifm-link-hover-color:var(--ifm-color-emphasis-700);--ifm-link-hover-decoration:none;border:1px solid var(--ifm-color-emphasis-200);box-shadow:0 1.5px 3px 0 #00000026;transition:all var(--ifm-transition-fast) ease;transition-property:border,box-shadow}.cardContainer_fWXF:hover{border-color:var(--ifm-color-primary);box-shadow:0 3px 6px 0 #0003}.cardTitle_rnsV{font-size:1.2rem}.cardDescription_PWke{font-size:.8rem}.dropdownNavbarItemMobile_S0Fm{cursor:pointer}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}.searchBar_RVTs .dropdownMenu_qbY6{background:var(--search-local-modal-background,#f5f6f7);border-radius:6px;box-shadow:var(--search-local-modal-shadow,inset 1px 1px 0 0 #ffffff80,0 3px 8px 0 #555a64);left:auto!important;margin-top:8px;padding:var(--search-local-spacing,12px);position:relative;right:0!important;width:var(--search-local-modal-width,560px)}html[data-theme=dark] .searchBar_RVTs .dropdownMenu_qbY6{background:var(--search-local-modal-background,var(--ifm-background-color));box-shadow:var(--search-local-modal-shadow,inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309)}.searchBar_RVTs .dropdownMenu_qbY6 .suggestion_fB_2{align-items:center;background:var(--search-local-hit-background,#fff);border-radius:4px;box-shadow:var(--search-local-hit-shadow,0 1px 3px 0 #d4d9e1);color:var(--search-local-hit-color,#444950);cursor:pointer;display:flex;flex-direction:row;height:var(--search-local-hit-height,56px);padding:0 var(--search-local-spacing,12px);width:100%}.hitTree_kk6K,.noResults_l6Q3{align-items:center;display:flex}html[data-theme=dark] .dropdownMenu_qbY6 .suggestion_fB_2{background:var(--search-local-hit-background,var(--ifm-color-emphasis-100));box-shadow:var(--search-local-hit-shadow,none);color:var(--search-local-hit-color,var(--ifm-font-color-base))}.searchBar_RVTs .dropdownMenu_qbY6 .suggestion_fB_2:not(:last-child){margin-bottom:4px}.searchBar_RVTs .dropdownMenu_qbY6 .suggestion_fB_2.cursor_eG29{background-color:var(--search-local-highlight-color,var(--ifm-color-primary))}.hitFooter_E9YW a,.hitIcon_a7Zy,.hitPath_ieM4,.hitTree_kk6K,.noResultsIcon_EBY5{color:var(--search-local-muted-color,#969faf)}html[data-theme=dark] .hitIcon_a7Zy,html[data-theme=dark] .hitPath_ieM4,html[data-theme=dark] .hitTree_kk6K,html[data-theme=dark] .noResultsIcon_EBY5{color:var(--search-local-muted-color,var(--ifm-color-secondary-darkest))}.hitTree_kk6K>svg{height:var(--search-local-hit-height,56px);opacity:.5;width:24px}.hitIcon_a7Zy,.hitTree_kk6K>svg{stroke-width:var(--search-local-icon-stroke-width,1.4)}.hitAction_NqkB,.hitIcon_a7Zy{height:20px;width:20px}.hitWrapper_sAK8{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;margin:0 8px;overflow-x:hidden;width:80%}.hitWrapper_sAK8 mark{background:none;color:var(--search-local-highlight-color,var(--ifm-color-primary))}.hitTitle_vyVt{font-size:.9em}.hitPath_ieM4{font-size:.75em}.hitPath_ieM4,.hitTitle_vyVt{overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.noResults_l6Q3{flex-direction:column;justify-content:center;padding:var(--search-local-spacing,12px) 0}.noResultsIcon_EBY5{margin-bottom:var(--search-local-spacing,12px)}.hitFooter_E9YW{font-size:.85em;margin-top:var(--search-local-spacing,12px);text-align:center}.cursor_eG29 .hideAction_vcyE>svg,.tocCollapsibleContent_vkbj a{display:block}.suggestion_fB_2.cursor_eG29,.suggestion_fB_2.cursor_eG29 .hitIcon_a7Zy,.suggestion_fB_2.cursor_eG29 .hitPath_ieM4,.suggestion_fB_2.cursor_eG29 .hitTree_kk6K,.suggestion_fB_2.cursor_eG29 mark{color:var(--search-local-hit-active-color,var(--ifm-color-white))!important}.searchBarContainer_NW3z{margin-left:16px}.searchBarContainer_NW3z .searchBarLoadingRing_YnHq{display:none;left:10px;position:absolute;top:6px}.searchBarContainer_NW3z .searchClearButton_qk4g{background:none;border:none;line-height:1rem;padding:0;position:absolute;right:.8rem;top:50%;transform:translateY(-50%)}.navbar__search{position:relative}.searchIndexLoading_EJ1f .navbar__search-input{background-image:none}.searchHintContainer_Pkmr{align-items:center;display:flex;gap:4px;height:100%;justify-content:center;pointer-events:none;position:absolute;right:10px;top:0}.searchHint_iIMx{background-color:var(--ifm-navbar-search-input-background-color);border:1px solid var(--ifm-color-emphasis-500);box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-500);color:var(--ifm-navbar-search-input-placeholder-color)}.loadingRing_RJI3{display:inline-block;height:20px;opacity:var(--search-local-loading-icon-opacity,.5);position:relative;width:20px}.loadingRing_RJI3 div{animation:1.2s cubic-bezier(.5,0,.5,1) infinite a;border:2px solid var(--search-load-loading-icon-color,var(--ifm-navbar-search-input-color));border-color:var(--search-load-loading-icon-color,var(--ifm-navbar-search-input-color)) #0000 #0000 #0000;border-radius:50%;display:block;height:16px;margin:2px;position:absolute;width:16px}.loadingRing_RJI3 div:first-child{animation-delay:-.45s}.loadingRing_RJI3 div:nth-child(2){animation-delay:-.3s}.loadingRing_RJI3 div:nth-child(3){animation-delay:-.15s}@keyframes a{0%{transform:rotate(0)}to{transform:rotate(1turn)}}@supports selector(:has(*)){.navbarSearchContainer_Bca1:not(:has(>*)){display:none}}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.errorBoundaryFallback_VBag{color:red;padding:.55rem}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.sidebar_re4s{overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 2rem)}.sidebarItemTitle_pO2u{font-size:var(--ifm-h3-font-size);font-weight:var(--ifm-font-weight-bold)}.container_mt6G,.sidebarItemList_Yudw{font-size:.9rem}.sidebarItem__DBe{margin-top:.7rem}.sidebarItemLink_mo7H{color:var(--ifm-font-color-base);display:block}.sidebarItemLinkActive_I1ZP{color:var(--ifm-color-primary)!important}.searchContextInput_mXoe,.searchQueryInput_CFBF{background:var(--ifm-background-color);border:var(--ifm-global-border-width) solid var(--ifm-color-content-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-font-color-base);font-size:var(--ifm-font-size-base);margin-bottom:1rem;padding:.5rem;width:100%}.searchResultItem_U687{border-bottom:1px solid #dfe3e8;padding:1rem 0}.searchResultItemPath_uIbk{color:var(--ifm-color-content-secondary);font-size:.8rem;margin:.5rem 0 0}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.searchResultItemSummary_oZHr{font-style:italic;margin:.5rem 0 0}.heroBanner_qdFl{overflow:hidden;padding:4rem 0;position:relative;text-align:center}.buttons_AeoN{align-items:center;display:flex;justify-content:center}#marg_HODB{margin-bottom:1rem;margin-top:1rem}.authorCol_Hf19{flex-grow:1!important;max-width:inherit!important}.imageOnlyAuthorRow_pa_O{display:flex;flex-flow:row wrap}.imageOnlyAuthorCol_G86a{margin-left:.3rem;margin-right:.3rem}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{fill:currentColor;height:inherit;left:0;opacity:inherit;position:absolute;top:0;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tag_Nnez{display:inline-block;margin:.5rem .5rem 0 1rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.lastUpdated_JAkA{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.img_ev3q{height:auto}.admonition_xJq3{margin-bottom:1em}.admonitionHeading_Gvgb{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family)}.admonitionHeading_Gvgb:not(:last-child){margin-bottom:.3rem}.admonitionHeading_Gvgb code{text-transform:none}.admonitionIcon_Rf37{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_Rf37 svg{fill:var(--ifm-alert-foreground-color);display:inline-block;height:1.6em;width:1.6em}.tableOfContents_bqdL{overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.title_kItE{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-leading)*1.25)}@media only screen and (min-width:996px){.card_N5DL{height:100%}}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_TmdG{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_i1dp,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_TmdG:focus,.expandButton_TmdG:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_TmdG{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_i1dp{transform:rotate(180deg)}.docSidebarContainer_YfHR{border-right:1px solid var(--ifm-toc-border-color);-webkit-clip-path:inset(0);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_DPk8{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_aRkj{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_TBSr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_lQrH{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_JWYK{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}.navbarSearchContainer_Bca1{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.lastUpdated_JAkA{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn,.generatedIndexPage_vN6x{max-width:75%!important}.list_eTzJ article:nth-last-child(-n+2){margin-bottom:0!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.sidebar_re4s,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.navbarSearchContainer_Bca1{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media not (max-width:996px){.searchBar_RVTs.searchBarLeft_MXDe .dropdownMenu_qbY6{left:0!important;right:auto!important}}@media only screen and (max-width:996px){.searchQueryColumn_q7nx{max-width:60%!important}.searchContextColumn_oWAF{max-width:40%!important}}@media screen and (max-width:996px){.heroBanner_qdFl{padding:2rem}}@media only screen and (max-width:600px){.modalContent_zbmJ{height:100%}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}.navbar__search-input:not(:focus){width:2rem}.searchBar_RVTs .dropdownMenu_qbY6{max-width:calc(100vw - var(--ifm-navbar-padding-horizontal)*2);width:var(--search-local-modal-width-sm,340px)}.searchBarContainer_NW3z:not(.focused_OWtg) .searchClearButton_qk4g,.searchHintContainer_Pkmr{display:none}.title_f1Hy{font-size:2rem}}@media screen and (max-width:576px){.searchQueryColumn_q7nx{max-width:100%!important}.searchContextColumn_oWAF{max-width:100%!important;padding-left:var(--ifm-spacing-horizontal)!important}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/assets/files/clouds-public-e9ba939dfde1c0efe3a32ec6f5d1f612.yaml b/assets/files/clouds-public-e9ba939dfde1c0efe3a32ec6f5d1f612.yaml new file mode 100644 index 0000000000..01f7a2db4d --- /dev/null +++ b/assets/files/clouds-public-e9ba939dfde1c0efe3a32ec6f5d1f612.yaml @@ -0,0 +1,38 @@ +--- +public-clouds: + betacloud: + auth: + auth_url: https://api-1.betacloud.de:5000 + interface: 'public' + regions: + - name: betacloud-1 + identity_api_version: 3 + image_format: raw + block_storage_api_version: 3 + pluscloudopen: + auth: + auth_url: https://prod1.api.pco.get-cloud.io:5000 + interface: 'public' + regions: + - name: prod1 + identity_api_version: 3 + image_format: raw + block_storage_api_version: 3 + gx-scs: + auth: + auth_url: https://api.gx-scs.sovereignit.cloud:5000 + interface: 'public' + regions: + - name: RegionOne + identity_api_version: 3 + image_format: raw + block_storage_api_version: 3 + wavestack: + auth: + auth_url: https://api.wavestack.de:5000 + interface: 'public' + regions: + - name: MUC5 + identity_api_version: 3 + image_format: raw + block_storage_api_version: 3 diff --git a/assets/files/clouds.yaml-9c0c983f9c293bc5adeae683d442174e.sample b/assets/files/clouds.yaml-9c0c983f9c293bc5adeae683d442174e.sample new file mode 100644 index 0000000000..9040467c63 --- /dev/null +++ b/assets/files/clouds.yaml-9c0c983f9c293bc5adeae683d442174e.sample @@ -0,0 +1,23 @@ +--- +clouds: + betacloud: + profile: betacloud + auth: + username: USERNAME + project_name: PROJECT + project_domain_name: DOMAIN + user_domain_name: DOMAIN + pluscloudopen: + profile: pluscloudopen + auth: + username: USERNAME + project_name: PROJECT + project_domain_name: DOMAIN + user_domain_name: DOMAIN + gx-scs: + profile: gx-scs + auth: + username: u500924-USERNAME + project_name: p500924-PROJECT + project_domain_name: d500924 + user_domain_name: d500924 diff --git a/assets/images/disk-layout-db64866af60ef6d2c41245db78dd15d1.png b/assets/images/disk-layout-db64866af60ef6d2c41245db78dd15d1.png new file mode 100644 index 0000000000..39ccd70263 Binary files /dev/null and b/assets/images/disk-layout-db64866af60ef6d2c41245db78dd15d1.png differ diff --git a/assets/images/flavors-1-bd8d085759b264b3e58020d1390803fd.png b/assets/images/flavors-1-bd8d085759b264b3e58020d1390803fd.png new file mode 100644 index 0000000000..ace5ca0fb4 Binary files /dev/null and b/assets/images/flavors-1-bd8d085759b264b3e58020d1390803fd.png differ diff --git a/assets/images/flavors-2-d9a87ab2a63ed62ace4303facc069b8b.png b/assets/images/flavors-2-d9a87ab2a63ed62ace4303facc069b8b.png new file mode 100644 index 0000000000..9c6bc97809 Binary files /dev/null and b/assets/images/flavors-2-d9a87ab2a63ed62ace4303facc069b8b.png differ diff --git a/assets/images/getting_started_openstack_anim-d88d134eff244cf8891c5ca1efcfc65a.gif b/assets/images/getting_started_openstack_anim-d88d134eff244cf8891c5ca1efcfc65a.gif new file mode 100644 index 0000000000..2ef81b7e50 Binary files /dev/null and b/assets/images/getting_started_openstack_anim-d88d134eff244cf8891c5ca1efcfc65a.gif differ diff --git a/assets/images/github-failed-dco-82f9dafea83c36769069087ceb522cdc.png b/assets/images/github-failed-dco-82f9dafea83c36769069087ceb522cdc.png new file mode 100644 index 0000000000..a21febb629 Binary files /dev/null and b/assets/images/github-failed-dco-82f9dafea83c36769069087ceb522cdc.png differ diff --git a/assets/images/harbor_migration-15d83bf7e5b37c0bdcb698280dde0684.png b/assets/images/harbor_migration-15d83bf7e5b37c0bdcb698280dde0684.png new file mode 100644 index 0000000000..52ee905bb9 Binary files /dev/null and b/assets/images/harbor_migration-15d83bf7e5b37c0bdcb698280dde0684.png differ diff --git a/assets/images/image-01d5564077ed43bda1d921e522df7dd7.png b/assets/images/image-01d5564077ed43bda1d921e522df7dd7.png new file mode 100644 index 0000000000..6bf653030f Binary files /dev/null and b/assets/images/image-01d5564077ed43bda1d921e522df7dd7.png differ diff --git a/assets/images/image-123702bb74539962d7c6839715583f29.png b/assets/images/image-123702bb74539962d7c6839715583f29.png new file mode 100644 index 0000000000..10e845bc52 Binary files /dev/null and b/assets/images/image-123702bb74539962d7c6839715583f29.png differ diff --git a/assets/images/inventory-reconciler-acd822767003069a8935e016081383a5.png b/assets/images/inventory-reconciler-acd822767003069a8935e016081383a5.png new file mode 100644 index 0000000000..8df13374af Binary files /dev/null and b/assets/images/inventory-reconciler-acd822767003069a8935e016081383a5.png differ diff --git a/assets/images/issue-6cc9ac7387e0589d625dded707510641.png b/assets/images/issue-6cc9ac7387e0589d625dded707510641.png new file mode 100644 index 0000000000..69137a9de8 Binary files /dev/null and b/assets/images/issue-6cc9ac7387e0589d625dded707510641.png differ diff --git a/assets/images/jaeger-91a4b48820447709f604d72c396cacf8.png b/assets/images/jaeger-91a4b48820447709f604d72c396cacf8.png new file mode 100644 index 0000000000..a37e429f03 Binary files /dev/null and b/assets/images/jaeger-91a4b48820447709f604d72c396cacf8.png differ diff --git a/assets/images/monitoring_scs_detailed-36c61be9b4deedd32e7babf1ddbc68ea.png b/assets/images/monitoring_scs_detailed-36c61be9b4deedd32e7babf1ddbc68ea.png new file mode 100644 index 0000000000..a13573fedd Binary files /dev/null and b/assets/images/monitoring_scs_detailed-36c61be9b4deedd32e7babf1ddbc68ea.png differ diff --git a/assets/images/monitoring_scs_experimental-3846febea17c1ecf9baaa074ee9b1a10.png b/assets/images/monitoring_scs_experimental-3846febea17c1ecf9baaa074ee9b1a10.png new file mode 100644 index 0000000000..245954e08c Binary files /dev/null and b/assets/images/monitoring_scs_experimental-3846febea17c1ecf9baaa074ee9b1a10.png differ diff --git a/assets/images/monitoring_scs_high_level-50f86d39d750e803a31513fb32942e41.png b/assets/images/monitoring_scs_high_level-50f86d39d750e803a31513fb32942e41.png new file mode 100644 index 0000000000..ccdcb69e3a Binary files /dev/null and b/assets/images/monitoring_scs_high_level-50f86d39d750e803a31513fb32942e41.png differ diff --git a/assets/images/openstackclusterstackrelease-controller-392111d1162c59f4787aad5267f85e04.png b/assets/images/openstackclusterstackrelease-controller-392111d1162c59f4787aad5267f85e04.png new file mode 100644 index 0000000000..0240212309 Binary files /dev/null and b/assets/images/openstackclusterstackrelease-controller-392111d1162c59f4787aad5267f85e04.png differ diff --git a/assets/images/openstacknodeimagerelease-controller-0b39df07c1e9d7a4e028f0795dd056d8.png b/assets/images/openstacknodeimagerelease-controller-0b39df07c1e9d7a4e028f0795dd056d8.png new file mode 100644 index 0000000000..a232597436 Binary files /dev/null and b/assets/images/openstacknodeimagerelease-controller-0b39df07c1e9d7a4e028f0795dd056d8.png differ diff --git a/assets/images/overview.drawio-f6a92d48381c9de5fcbbd5205e022b0a.png b/assets/images/overview.drawio-f6a92d48381c9de5fcbbd5205e022b0a.png new file mode 100644 index 0000000000..11b7df57ed Binary files /dev/null and b/assets/images/overview.drawio-f6a92d48381c9de5fcbbd5205e022b0a.png differ diff --git a/assets/images/python-osism.drawio-19e90813de60b4afa58bc7ee4a3aeae8.png b/assets/images/python-osism.drawio-19e90813de60b4afa58bc7ee4a3aeae8.png new file mode 100644 index 0000000000..7772f1484e Binary files /dev/null and b/assets/images/python-osism.drawio-19e90813de60b4afa58bc7ee4a3aeae8.png differ diff --git a/assets/images/screenshot1-c880f78ba33fc0577dce811dc2e42724.png b/assets/images/screenshot1-c880f78ba33fc0577dce811dc2e42724.png new file mode 100644 index 0000000000..87d3beb87c Binary files /dev/null and b/assets/images/screenshot1-c880f78ba33fc0577dce811dc2e42724.png differ diff --git a/assets/images/service-with-docker.drawio-21d9ff770c727c43ab477f857b5017e2.png b/assets/images/service-with-docker.drawio-21d9ff770c727c43ab477f857b5017e2.png new file mode 100644 index 0000000000..d07f19168a Binary files /dev/null and b/assets/images/service-with-docker.drawio-21d9ff770c727c43ab477f857b5017e2.png differ diff --git a/assets/images/service-with-kubernetes.drawio-9500d1fb61ca22792d8277f9f06e58ce.png b/assets/images/service-with-kubernetes.drawio-9500d1fb61ca22792d8277f9f06e58ce.png new file mode 100644 index 0000000000..c9ba4c4835 Binary files /dev/null and b/assets/images/service-with-kubernetes.drawio-9500d1fb61ca22792d8277f9f06e58ce.png differ diff --git a/assets/images/tilt-4af6fa61d9a6a82abdfa1c82985f182e.png b/assets/images/tilt-4af6fa61d9a6a82abdfa1c82985f182e.png new file mode 100644 index 0000000000..a00dec81f1 Binary files /dev/null and b/assets/images/tilt-4af6fa61d9a6a82abdfa1c82985f182e.png differ diff --git a/assets/images/user_data_backups_figure1-988dbd55659509cc1ddc9f68f2437648.png b/assets/images/user_data_backups_figure1-988dbd55659509cc1ddc9f68f2437648.png new file mode 100644 index 0000000000..1be96dd222 Binary files /dev/null and b/assets/images/user_data_backups_figure1-988dbd55659509cc1ddc9f68f2437648.png differ diff --git a/assets/images/zuul-hanging-jobs-in-a-pipeline-047d29fda9946dd80cebb88778249bce.png b/assets/images/zuul-hanging-jobs-in-a-pipeline-047d29fda9946dd80cebb88778249bce.png new file mode 100644 index 0000000000..129ffce4d1 Binary files /dev/null and b/assets/images/zuul-hanging-jobs-in-a-pipeline-047d29fda9946dd80cebb88778249bce.png differ diff --git a/assets/js/0047ab5d.234fa37c.js b/assets/js/0047ab5d.234fa37c.js new file mode 100644 index 0000000000..68bc967dfd --- /dev/null +++ b/assets/js/0047ab5d.234fa37c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5058],{4475:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>r,toc:()=>d});var n=s(74848),t=s(28453);const o={sidebar_label:"Services",sidebar_position:50},c="Services",r={id:"iaas/guides/configuration-guide/services/index",title:"Services",description:"This section contains the documentation of the Ansible collection",source:"@site/docs/02-iaas/guides/configuration-guide/services/index.md",sourceDirName:"02-iaas/guides/configuration-guide/services",slug:"/iaas/guides/configuration-guide/services/",permalink:"/docs/iaas/guides/configuration-guide/services/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/services/index.md",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"Services",sidebar_position:50},sidebar:"docs",previous:{title:"User",permalink:"/docs/iaas/guides/configuration-guide/commons/user"},next:{title:"Chrony",permalink:"/docs/iaas/guides/configuration-guide/services/chrony"}},a={},d=[];function u(e){const i={a:"a",h1:"h1",p:"p",...(0,t.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.h1,{id:"services",children:"Services"}),"\n",(0,n.jsxs)(i.p,{children:["This section contains the documentation of the Ansible collection\n",(0,n.jsx)(i.a,{href:"https://github.com/osism/ansible-collection-services",children:"osism.services"}),"."]})]})}function l(e={}){const{wrapper:i}={...(0,t.R)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,i,s)=>{s.d(i,{R:()=>c,x:()=>r});var n=s(96540);const t={},o=n.createContext(t);function c(e){const i=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),n.createElement(o.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0050251a.1dccdf1d.js b/assets/js/0050251a.1dccdf1d.js new file mode 100644 index 0000000000..88ee1b4e58 --- /dev/null +++ b/assets/js/0050251a.1dccdf1d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1945],{55146:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var o=n(74848),r=n(28453);const i={},s="Documentation for SCS Contributors",c={id:"index",title:"Documentation for SCS Contributors",description:"Welcome to the Contributor Docs. This section is primarily for SCS Contributors and will contain documentation regarding the Development and Architecture of the Sovereign Cloud Stack and its components. You will find documents, explanations and guides regarding the tooling necessary for the development of SCS.",source:"@site/contributor-docs/index.md",sourceDirName:".",slug:"/",permalink:"/contributor-docs/",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"devDocs",previous:{title:"SCS Conformance Test Implementation Guide",permalink:"/contributor-docs/development/tests/test-implementation-guide"},next:{title:"Identity Federation in SCS",permalink:"/contributor-docs/operations/iam/identity-federation-in-scs"}},a={},u=[];function d(t){const e={a:"a",h1:"h1",p:"p",...(0,r.R)(),...t.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(e.h1,{id:"documentation-for-scs-contributors",children:"Documentation for SCS Contributors"}),"\n",(0,o.jsx)(e.p,{children:"Welcome to the Contributor Docs. This section is primarily for SCS Contributors and will contain documentation regarding the Development and Architecture of the Sovereign Cloud Stack and its components. You will find documents, explanations and guides regarding the tooling necessary for the development of SCS."}),"\n",(0,o.jsxs)(e.p,{children:["If you want to contribute you can reach out to us via our ",(0,o.jsx)(e.a,{href:"https://matrix.to/#/!TiDqlLmEUaXqTemaLc:matrix.org?via=matrix.org",children:"Matrix Channel"}),"."]})]})}function l(t={}){const{wrapper:e}={...(0,r.R)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(d,{...t})}):d(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>s,x:()=>c});var o=n(96540);const r={},i=o.createContext(r);function s(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:s(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/0121636f.45072d36.js b/assets/js/0121636f.45072d36.js new file mode 100644 index 0000000000..2cc66af6cd --- /dev/null +++ b/assets/js/0121636f.45072d36.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5752],{95824:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>t,default:()=>p,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var o=a(74848),i=a(28453);const s={sidebar_label:"Project Manager",sidebar_position:53},t="Project Manager",r={id:"iaas/guides/operations-guide/openstack/tools/project-manager",title:"Project Manager",description:"Overview",source:"@site/docs/02-iaas/guides/operations-guide/openstack/tools/project-manager.md",sourceDirName:"02-iaas/guides/operations-guide/openstack/tools",slug:"/iaas/guides/operations-guide/openstack/tools/project-manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/project-manager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/project-manager.md",tags:[],version:"current",sidebarPosition:53,frontMatter:{sidebar_label:"Project Manager",sidebar_position:53},sidebar:"docs",previous:{title:"Resource Manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager"},next:{title:"Sandbox Manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager"}},c={},d=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Defaults",id:"defaults",level:2},{value:"create.py",id:"createpy",level:3},{value:"manage.py",id:"managepy",level:3},{value:"Usage",id:"usage",level:2},{value:"create.py",id:"createpy-1",level:3},{value:"Create a Domain and inital project",id:"create-a-domain-and-inital-project",level:4},{value:"Create a User for a project",id:"create-a-user-for-a-project",level:4},{value:"Create additional project with unlimited quota",id:"create-additional-project-with-unlimited-quota",level:4},{value:"Set quotas for a project",id:"set-quotas-for-a-project",level:4},{value:"Special project: images",id:"special-project-images",level:4},{value:"Special project: service",id:"special-project-service",level:4},{value:"manage.py",id:"managepy-1",level:3},{value:"Manage a specific domain only",id:"manage-a-specific-domain-only",level:4},{value:"Config files",id:"config-files",level:2},{value:"Quota Templates",id:"quota-templates",level:2},{value:"Setup Endpoints",id:"setup-endpoints",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"project-manager",children:"Project Manager"}),"\n",(0,o.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,o.jsx)(n.p,{children:"The OpenStack Project Manager manages the creation of Openstack Domains, Projects and Users."}),"\n",(0,o.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,o.jsx)(n.p,{children:"Prepare to use the Openstack Project Manager."}),"\n",(0,o.jsx)(n.p,{children:"During installation, ldap libraries are required under Linux; you should install libldap2-dev and libsasl2-dev beforehand."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"git clone https://github.com/osism/openstack-project-manager\ncd openstack-project-manager\npipenv install\npipenv shell\n"})}),"\n",(0,o.jsx)(n.h2,{id:"defaults",children:"Defaults"}),"\n",(0,o.jsx)(n.h3,{id:"createpy",children:"create.py"}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"create.py"})," command and his default options while executing the command."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:" --admin-domain default\n --assign-admin-user true\n --cloud admin\n --create-admin-user true\n --create-domain false\n --create-user false\n --domain-name-prefix true\n --has-service-network false\n --has-public-network true\n --has-shared-images true\n --internal-id unset\n --random false\n --managed-network-resources false\n --name sandbox\n --owner unset\n --password unset\n --password-length 16\n --public-network public\n --quota-class basic\n --service-network-cidr unset\n --quota-multiplier 1\n --quota-multiplier-compute unset\n --quota-multiplier-network unset\n --quota-multiplier-storage unset\n --quota-router 1\n"})}),"\n",(0,o.jsx)(n.h3,{id:"managepy",children:"manage.py"}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"manage.py"})," has also some defaults while executing and will touch all projects in your Openstack Cluster, if not --domain is used."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:" --admin-domain default\n --assign-admin-user false\n --classes etc/classes.yml\n --domain unset\n --dry-run false\n --endpoints etc/endpoints.yml\n --manage-endpoints false\n --manage-homeprojects false\n --name unset\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Default Openstack Roles to users are set to ",(0,o.jsx)(n.code,{children:"member"})," and ",(0,o.jsx)(n.code,{children:"load-balancer_member"})," at this time, the behavior can only be changed in the code."]}),"\n",(0,o.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,o.jsxs)(n.p,{children:["There must be a ",(0,o.jsx)(n.code,{children:"clouds.yml"})," and a ",(0,o.jsx)(n.code,{children:"secure.yml"})," file in the directory where the OpenStack Project Manager will be executed, examples are provided within the git repository."]}),"\n",(0,o.jsx)(n.p,{children:"The cloud profile to be used can be specified via the optional --cloud parameter. By default the cloud profile with the name admin is used. It has to be and admin account, to create and modify domains, projects, users and quotas."}),"\n",(0,o.jsxs)(n.p,{children:["The Openstack Project Manager essentially consists of two parts, the ",(0,o.jsx)(n.code,{children:"create.py"})," and the ",(0,o.jsx)(n.code,{children:"manage.py"}),", there are more scripts for handling users using ldap which needs more configuration setup."]}),"\n",(0,o.jsx)(n.h3,{id:"createpy-1",children:"create.py"}),"\n",(0,o.jsx)(n.p,{children:"This command is used to create and modify domains, projects, users and quotas. As default the domain is used as prefix for all projects and users created for easy alloction in Openstack."}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsx)(n.p,{children:"create.py can't delete once created objects, this must be done using Openstack commands to remove a project or domain."})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"python src/create.py -h\nusage: create [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--create-admin-user] [--create-domain] [--create-user]\n [--domain DOMAIN] [--domain-name-prefix] [--has-public-network] [--has-service-network] [--has-shared-images] [--internal-id INTERNAL_ID] [--managed-network-resources] [--name NAME]\n [--noassign-admin-user] [--nocreate-admin-user] [--nocreate-domain] [--nocreate-user] [--nodomain-name-prefix] [--nohas-public-network] [--nohas-service-network]\n [--nohas-shared-images] [--nomanaged-network-resources] [--norandom] [--owner OWNER] [--password PASSWORD] [--password-length PASSWORD_LENGTH] [--public-network PUBLIC_NETWORK]\n [--quota-class QUOTA_CLASS] [--quota-multiplier QUOTA_MULTIPLIER] [--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE] [--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK]\n [--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE] [--quota-router QUOTA_ROUTER] [--random] [--service-network-cidr SERVICE_NETWORK_CIDR]\n\noptions:\n -h, --help show this help message and exit\n --admin-domain ADMIN_DOMAIN\n Admin domain\n --assign-admin-user Assign admin user\n --cloud CLOUD Managed cloud\n --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set\n is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the\n command-line.\n --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the\n command-line.\n --create-admin-user Create admin user\n --create-domain Create domain only\n --create-user Create user\n --domain DOMAIN Domain\n --domain-name-prefix Add domain name as prefix to the project name\n --has-public-network Has public network infrastructure\n --has-service-network\n Has service network infrastructure\n --has-shared-images Has shared images\n --internal-id INTERNAL_ID\n Internal ID\n --managed-network-resources\n Manage the network resources\n --name NAME Projectname\n --noassign-admin-user\n The inverse of --assign-admin-user\n --nocreate-admin-user\n The inverse of --create-admin-user\n --nocreate-domain The inverse of --create-domain\n --nocreate-user The inverse of --create-user\n --nodomain-name-prefix\n The inverse of --domain-name-prefix\n --nohas-public-network\n The inverse of --has-public-network\n --nohas-service-network\n The inverse of --has-service-network\n --nohas-shared-images\n The inverse of --has-shared-images\n --nomanaged-network-resources\n The inverse of --managed-network-resources\n --norandom The inverse of --random\n --owner OWNER Owner of the project\n --password PASSWORD Password\n --password-length PASSWORD_LENGTH\n Password length\n --public-network PUBLIC_NETWORK\n Public network\n --quota-class QUOTA_CLASS\n Quota class\n --quota-multiplier QUOTA_MULTIPLIER\n Quota multiplier\n --quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE\n Quota multiplier compute\n --quota-multiplier-network QUOTA_MULTIPLIER_NETWORK\n Quota multiplier network\n --quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE\n Quota multiplier storage\n --quota-router QUOTA_ROUTER\n Quota router\n --random Generate random names\n --service-network-cidr SERVICE_NETWORK_CIDR\n Service network CIDR\n"})}),"\n",(0,o.jsx)(n.h4,{id:"create-a-domain-and-inital-project",children:"Create a Domain and inital project"}),"\n",(0,o.jsxs)(n.p,{children:["When executing the ",(0,o.jsx)(n.code,{children:"create.py"})," command, the first time with ",(0,o.jsx)(n.code,{children:"--domain"}),", it will create a new domain, an admin account and the first project ",(0,o.jsx)(n.code,{children:"webshop"}),". The admin account will be created in the default Domain of Openstack and can be used for the Service Provider to manager the complete domain."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name webshop\n+----------------+----------------------+----------------------------------+\n| name | value | id |\n|----------------+----------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-webshop | 645538bf67664cfeaed32476d58f95fb |\n| admin | democompany-admin | cc8d6bf7b61d4199ba5a4230c4ec6d62 |\n| admin_password | qawsEdfg2d45Fsxc | |\n+----------------+----------------------+----------------------------------+\n"})}),"\n",(0,o.jsx)(n.h4,{id:"create-a-user-for-a-project",children:"Create a User for a project"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name webshopuser --create-user \n+----------+-------------------------+----------------------------------+\n| name | value | id |\n|----------+-------------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-webshop | 5752b6701026478f9cac122fc54eb9cb |\n| user | democompany-webshopuser | ce213655559d47d7800501124fed4d02 |\n| password | vEvM9vgRESdffWE2 | |\n+----------+-------------------------+----------------------------------+\n"})}),"\n",(0,o.jsx)(n.h4,{id:"create-additional-project-with-unlimited-quota",children:"Create additional project with unlimited quota"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name styles --quota-class unlimited\n+----------+--------------------+----------------------------------+\n| name | value | id |\n|----------+--------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-styles | 666097e396fd4f9392d6aa55c76d8267 |\n+----------+--------------------+----------------------------------+\n"})}),"\n",(0,o.jsx)(n.h4,{id:"set-quotas-for-a-project",children:"Set quotas for a project"}),"\n",(0,o.jsxs)(n.p,{children:["All quota information must be set as a property to the Openstack project within your Openstack Cluster, if no property is set, the ",(0,o.jsx)(n.code,{children:"basic"})," quotaclass of ",(0,o.jsx)(n.code,{children:"etc/classes.yml"})," will be applied.\nIt is possible to set a quota multiplier for any project."]}),"\n",(0,o.jsx)(n.p,{children:"The following command you set a multiplier of 256 of the basic quota:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ openstack project set --property quotamultiplier=256 democompany-webshop\n"})}),"\n",(0,o.jsx)(n.p,{children:"Adjusting gigabyte quota for storage with a multiplier of 20 of the basic quota for a project:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ openstack project set --property quotamultiplier_storage=20 democompany-webshop\n"})}),"\n",(0,o.jsx)(n.p,{children:"This will override the general quotamultiplier only for storage."}),"\n",(0,o.jsxs)(n.p,{children:["Other possible multiplier which can be set individually are: ",(0,o.jsx)(n.code,{children:"quotamultiplier_compute"}),", ",(0,o.jsx)(n.code,{children:"quotamultiplier_network"}),", ",(0,o.jsx)(n.code,{children:"quota_router"})]}),"\n",(0,o.jsxs)(n.p,{children:["To change the quotaclass to unlimited from the ",(0,o.jsx)(n.code,{children:"etc/classes.yaml"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ openstack project set --property quotaclass=unlimited democompany-webshop\n"})}),"\n",(0,o.jsx)(n.h4,{id:"special-project-images",children:"Special project: images"}),"\n",(0,o.jsxs)(n.p,{children:["With this special Project you can share all images uploaded into this project to all other project in your domain which has set the property ",(0,o.jsx)(n.code,{children:"has-shared-images"}),", which is by default set.\nAlsoi only the domain-admin user has access to this project, other domain users won't see this, they will find the uploaded images in their projects.\nIf you want your grant other domain users also access to upload some images, you need to give them access to the images Project in Openstack."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name images\n+---------+---------------------+----------------------------------+\n| name | value | id |\n|---------+---------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-images | 6d57f39aacbe485d87733865b1e79d03 |\n+---------+---------------------+----------------------------------+\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Additionally you need to add the domain and domain-admin user to the ",(0,o.jsx)(n.code,{children:"clouds.yaml"}),", it is always named ",(0,o.jsx)(n.code,{children:"opm-domainname-admin:"})," so the manage.py can setup permissions to the projects later on and users are able to find the images."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:" opm-democompany-admin:\n auth:\n auth_url: https://keystone.my.cloud:5000/v3\n username: democompany-admin\n password: yourpassword\n user_domain_name: Default\n project_domain_name: democompany \n identity_api_version: 3\n"})}),"\n",(0,o.jsx)(n.h4,{id:"special-project-service",children:"Special project: service"}),"\n",(0,o.jsx)(n.p,{children:"With this special project you can share installed services, like a harbor, to all other projects in your domain. Per default, only the domain admin has access to this project."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name service\n+---------+---------------------+----------------------------------+\n| name | value | id |\n|---------+---------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-service | a5558f7338f94adea5f41858636256b5 |\n+---------+---------------------+----------------------------------+\n"})}),"\n",(0,o.jsx)(n.h3,{id:"managepy-1",children:"manage.py"}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsxs)(n.p,{children:["This command applies quotas, networks and routers to ",(0,o.jsx)(n.strong,{children:"all"})," projects in the Openstack Cluster, not only to those have been configured previously with the ",(0,o.jsx)(n.code,{children:"create.py"})," or ",(0,o.jsx)(n.code,{children:"openstack project set --property"})," commands."]})}),"\n",(0,o.jsx)(n.p,{children:"Best is to run this command by cron, every hour to apply all pending changes, it is also possible to run this at the command line to apply changes immediately."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"python3 src/manage.py -h\nusage: manage [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--classes CLASSES] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--domain DOMAIN] [--dry-run]\n [--endpoints ENDPOINTS] [--manage-endpoints] [--manage-homeprojects] [--name NAME] [--noassign-admin-user] [--nodry-run] [--nomanage-endpoints] [--nomanage-homeprojects]\n\noptions:\n -h, --help show this help message and exit\n --admin-domain ADMIN_DOMAIN\n Admin domain\n --assign-admin-user Assign admin user\n --classes CLASSES Path to the classes.yml file\n --cloud CLOUD Cloud name in clouds.yaml\n --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set\n is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the\n command-line.\n --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the\n command-line.\n --domain DOMAIN Domain to be managed\n --dry-run Do not really do anything\n --endpoints ENDPOINTS\n Path to the endpoints.yml file\n --manage-endpoints Manage endpoints\n --manage-homeprojects\n Manage home projects\n --name NAME Project to be managed\n --noassign-admin-user\n The inverse of --assign-admin-user\n --nodry-run The inverse of --dry-run\n --nomanage-endpoints The inverse of --manage-endpoints\n --nomanage-homeprojects\n The inverse of --manage-homeprojects\n"})}),"\n",(0,o.jsx)(n.h4,{id:"manage-a-specific-domain-only",children:"Manage a specific domain only"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ python3 src/manage.py --domain democompany\n\n2024-04-19 14:24:02.873 | INFO | democompany - domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03\n2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03, domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:04.953 | INFO | democompany-images - quotaclass {'compute': {'cores': 0, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 0, 'key_pairs': 0, 'metadata_items': 128, 'ram': 0, 'server_group_members': 0, 'server_groups': 0}, 'network': {'floatingip': 0, 'network': 0, 'port': 0, 'rbac_policy': 0, 'router': 0, 'security_group': 0, 'security_group_rule': 0, 'subnet': 0, 'subnetpool': 0}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 1000, 'per_volume_gigabytes': 25, 'snapshots': 0, 'volumes': 100}, 'parent': 'default'}\n2024-04-19 14:24:04.953 | INFO | democompany-images - check network quota\n2024-04-19 14:24:05.048 | INFO | democompany-images - check compute quota\n2024-04-19 14:24:05.175 | INFO | democompany-images - check volume quota\n2024-04-19 14:24:05.286 | INFO | democompany-images - check if external rbac policy must be deleted (public)\n2024-04-19 14:24:05.349 | INFO | democompany-images - check if service rbac policy must be deleted (democompany-service)\n2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5\n2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5, domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:06.131 | INFO | democompany-service - quotaclass {'compute': {'cores': 256, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 256, 'key_pairs': 256, 'metadata_items': 128, 'ram': 262144, 'server_group_members': 256, 'server_groups': 256}, 'network': {'floatingip': 256, 'network': 256, 'port': 256, 'rbac_policy': 1024, 'router': 256, 'security_group': 256, 'security_group_rule': 1024, 'subnet': 256, 'subnetpool': 256}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 0, 'per_volume_gigabytes': 0, 'snapshots': 0, 'volumes': 0}, 'parent': 'default'}\n2024-04-19 14:24:06.131 | INFO | democompany-service - check network quota\n2024-04-19 14:24:06.212 | INFO | democompany-service - check compute quota\n2024-04-19 14:24:06.330 | INFO | democompany-service - check volume quota\n2024-04-19 14:24:06.467 | INFO | democompany-service - check if external rbac policy must be created (public)\n2024-04-19 14:24:06.589 | INFO | democompany-service - check if service rbac policy must be deleted (democompany-service)\n2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb\n2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb, domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:06.915 | INFO | democompany-webshop - quotaclass {'compute': {'cores': 4, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': -1, 'key_pairs': 4, 'metadata_items': 128, 'ram': 8192, 'server_group_members': 4, 'server_groups': 4}, 'network': {'floatingip': 4, 'network': 1, 'port': 20, 'rbac_policy': 10, 'router': 0, 'security_group': 5, 'security_group_rule': 20, 'subnet': 2, 'subnetpool': 1}, 'volume': {'backup_gigabytes': 40, 'backups': 8, 'gigabytes': 20, 'per_volume_gigabytes': 200, 'snapshots': 4, 'volumes': 4}, 'parent': 'default'}\n2024-04-19 14:24:06.915 | INFO | democompany-webshop - check network quota\n2024-04-19 14:24:06.993 | INFO | democompany-webshop - check compute quota\n2024-04-19 14:24:07.114 | INFO | democompany-webshop - check volume quota\n2024-04-19 14:24:07.254 | INFO | democompany-webshop - check if external rbac policy must be created (public)\n2024-04-19 14:24:07.334 | INFO | democompany-webshop - check if service rbac policy must be deleted (democompany-service)\n"})}),"\n",(0,o.jsx)(n.h2,{id:"config-files",children:"Config files"}),"\n",(0,o.jsxs)(n.p,{children:["The config files which can be used for ",(0,o.jsx)(n.code,{children:"create.py"})," and ",(0,o.jsx)(n.code,{children:"manage.py"})," are using the ",(0,o.jsx)(n.a,{href:"https://docs.openstack.org/oslo.config/latest/configuration/quickstart.html",children:"oslo.config format"}),", you can set the command line options as ",(0,o.jsx)(n.code,{children:"key = value pair"})," and create your own config files matching your setup."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="democompany.conf"',children:"[DEFAULT]\ncloud = admin\ndomain = democompany\n"})}),"\n",(0,o.jsx)(n.h2,{id:"quota-templates",children:"Quota Templates"}),"\n",(0,o.jsxs)(n.p,{children:["Edit the ",(0,o.jsx)(n.code,{children:"etc/classes.yml"})," file if you want to change or add new quota templates"]}),"\n",(0,o.jsx)(n.h2,{id:"setup-endpoints",children:"Setup Endpoints"}),"\n",(0,o.jsxs)(n.p,{children:["Edit the ",(0,o.jsx)(n.code,{children:"etc/endpoints.yml"})," file to fit your available endpoints"]})]})}function p(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>t,x:()=>r});var o=a(96540);const i={},s=o.createContext(i);function t(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/012688b3.b692a51a.js b/assets/js/012688b3.b692a51a.js new file mode 100644 index 0000000000..9779e20624 --- /dev/null +++ b/assets/js/012688b3.b692a51a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5251],{90669:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>d,toc:()=>l});var t=n(74848),r=n(28453);const o={sidebar_label:"Hardware Bill of Materials",sidebar_position:50},i="Hardware Bill of Materials",d={id:"iaas/guides/concept-guide/hardware-bom",title:"Hardware Bill of Materials",description:"The brands, models and configurations listed are examples. There is no",source:"@site/docs/02-iaas/guides/concept-guide/hardware-bom.md",sourceDirName:"02-iaas/guides/concept-guide",slug:"/iaas/guides/concept-guide/hardware-bom",permalink:"/docs/iaas/guides/concept-guide/hardware-bom",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/hardware-bom.md",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"Hardware Bill of Materials",sidebar_position:50},sidebar:"docs",previous:{title:"Use cases",permalink:"/docs/iaas/guides/concept-guide/use-cases"},next:{title:"Deploy Guide",permalink:"/docs/iaas/guides/deploy-guide/"}},a={},l=[{value:"Control nodes",id:"control-nodes",level:2},{value:"Compute nodes",id:"compute-nodes",level:2},{value:"Storage nodes",id:"storage-nodes",level:2},{value:"Network nodes",id:"network-nodes",level:2},{value:"Manager nodes",id:"manager-nodes",level:2},{value:"Switches",id:"switches",level:2},{value:"Management switches",id:"management-switches",level:3},{value:"Leaf switches",id:"leaf-switches",level:3},{value:"Spine switches",id:"spine-switches",level:3},{value:"Network interface cards",id:"network-interface-cards",level:2}];function c(e){const s={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h1,{id:"hardware-bill-of-materials",children:"Hardware Bill of Materials"}),"\n",(0,t.jsx)(s.admonition,{type:"info",children:(0,t.jsx)(s.p,{children:"The brands, models and configurations listed are examples. There is no\nsingle best specification for building a cluster. It always depends very\nmuch on the requirements of the cluster and the situation. The examples\nare not minimal and include various preferences of ours. The choice of\nhardware always depends very much on the requirements, the available budget\nand also the future plans of the cluster. There is no universal hardware\nrecommendation that fits all cases. These are all just examples."})}),"\n",(0,t.jsx)(s.h2,{id:"control-nodes",children:"Control nodes"}),"\n",(0,t.jsx)(s.p,{children:"A control node is responsible for running all or most of the OpenStack\nservices that manage API services and their associated runtimes. These\nnodes are essential for users to interact with the cluster and maintain\nits managed state."}),"\n",(0,t.jsx)(s.p,{children:"However, control nodes typically do not run user virtual machines. It is\ntherefore advisable to replicate the control nodes to ensure high availability\nand fault tolerance. A good starting point for achieving RAFT quorum is to have\nthree control nodes."}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"2x SSD with at least 480 GByte for the operating system"}),"\n",(0,t.jsx)(s.li,{children:"4x NVMe with at least 960 GByte for the services"}),"\n",(0,t.jsx)(s.li,{children:"128 GByte memory (it should be possible to upgrade to 256 GByte, or use 256\nGByte directly)"}),"\n",(0,t.jsx)(s.li,{children:"Dual port NIC with 25G or 100G (depending on which leaf switches are used)"}),"\n",(0,t.jsx)(s.li,{children:"2 CPU sockets each with at least 32 cores or 1 CPU socket with at least 64 cores"}),"\n"]}),"\n",(0,t.jsx)(s.p,{children:"Real world example:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://www.supermicro.com/de/products/system/clouddc/1u/sys-121c-tn10r",children:"https://www.supermicro.com/de/products/system/clouddc/1u/sys-121c-tn10r"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"compute-nodes",children:"Compute nodes"}),"\n",(0,t.jsx)(s.p,{children:"Compute nodes are dedicated to running users' virtual machines. They do not\nhost API services, storage services or network routers, other than the basic\nnetwork infrastructure required to connect virtual machines."}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"2x SSD or NVMe with at least 480 GByte for the operating system"}),"\n",(0,t.jsx)(s.li,{children:"2x NVMe with at least 1.92 TByte for local storage recommended (if this is not implemented\nat the start, the model should be selected so that NVMe devices can be added later,\nthe size depends on which CPU and how much memory is used, 7.68 TByte is more likely to be used)"}),"\n",(0,t.jsx)(s.li,{children:"Dual port NIC with 25G or 100G (depending on which leaf switches are used)"}),"\n",(0,t.jsx)(s.li,{children:"CPU sockets and memory depends on the requirement"}),"\n"]}),"\n",(0,t.jsx)(s.p,{children:"Real world example:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://www.supermicro.com/de/products/twin",children:"https://www.supermicro.com/de/products/twin"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"storage-nodes",children:"Storage nodes"}),"\n",(0,t.jsx)(s.p,{children:"A dedicated storage node runs only storage services. This can be necessary in larger\ndeployments to protect the storage services from ressource starvation through user\nworkloads."}),"\n",(0,t.jsxs)(s.p,{children:["Read the ",(0,t.jsx)(s.a,{href:"https://docs.ceph.com/en/latest/start/hardware-recommendations/",children:"Ceph hardware recommendations"})," first."]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"2x SSD or NVMe with at least 480 GByte for the operating system"}),"\n",(0,t.jsx)(s.li,{children:"Dual port NIC with 100G (we recommend always using 100G for storage nodes)"}),"\n",(0,t.jsx)(s.li,{children:"Storage devices depends on the requirement"}),"\n",(0,t.jsx)(s.li,{children:"CPU sockets and memory depends on the storage devices used"}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"network-nodes",children:"Network nodes"}),"\n",(0,t.jsx)(s.p,{children:"A dedicated network node runs only network services. This is normally necessary to be\nable to map safety zones. External networks terminate on the network nodes."}),"\n",(0,t.jsx)(s.p,{children:"Real world example:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.a,{href:"https://www.supermicro.com/en/products/system/iot/1u/sys-110d-8c-fran8tp",children:"Supermicro SuperServer SYS-110D-8C-FRAN8TP"})}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"2x SSD or NVMe with at least 480 GByte for the operating system"}),"\n",(0,t.jsx)(s.li,{children:"2x DIMM slots with 32 GByte modules, leave 2 DIMM slots open for later expansion"}),"\n",(0,t.jsx)(s.li,{children:"If required, an additional dual port 25G or 100G NIC in the PCIe expansion slots"}),"\n",(0,t.jsx)(s.li,{children:"Intel Xeon Processor D-2733NT (this is onboard and not selectable)"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"manager-nodes",children:"Manager nodes"}),"\n",(0,t.jsx)(s.p,{children:"The manager node, also known as the deploy node or deployment node, is designated\nto manage the deployment process of all services. It is often also utilized to host\ncomponents of the monitoring services. It serves as the operator's entry point into\nthe cluster for operations."}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"2x SSD or NVMe with at least 1.92 TByte for the operating system and the services"}),"\n",(0,t.jsx)(s.li,{children:"64 GByte memory (it should be possible to upgrade to 128 GByte, or use 128 GByte directly)"}),"\n",(0,t.jsx)(s.li,{children:"Dual port NIC with 25G or 100G (depending on which leaf switches are used)"}),"\n",(0,t.jsx)(s.li,{children:"1 CPU socket with at least 16 cores"}),"\n"]}),"\n",(0,t.jsx)(s.p,{children:"Real world example:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://www.supermicro.com/de/products/system/clouddc/1u/sys-121c-tn10r",children:"https://www.supermicro.com/de/products/system/clouddc/1u/sys-121c-tn10r"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"switches",children:"Switches"}),"\n",(0,t.jsx)(s.h3,{id:"management-switches",children:"Management switches"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["1G: ",(0,t.jsx)(s.a,{href:"https://www.edge-core.com/product/as4610-54t/",children:"Edgecore AS4610-54T"})]}),"\n",(0,t.jsxs)(s.li,{children:["10G: ",(0,t.jsx)(s.a,{href:"https://www.edge-core.com/product/dcs202/",children:"Edgecore DCS202 - AS5835-54T"})]}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"leaf-switches",children:"Leaf switches"}),"\n",(0,t.jsx)(s.p,{children:"It is recommended to always use 100G for the data plane and the storage nodes.\nEspecially when using all-flash storage nodes, there is then enough bandwidth\navailable. The more and the larger flash devices you use, the more bandwidth is\nrequired."}),"\n",(0,t.jsx)(s.p,{children:"With the leaf switches for the compute plane, it depends on how large the compute\nnodes are. The more CPU sockets/cores and the more memory the compute nodes have,\nthe more bandwidth is required on the compute nodes. Depending on how large the racks\nare (or better how much power you can use in it), it may make sense to work with 100G\nswitches for the compute plane or with 25G switches if 4x 25G per compute node are used\ninstead of 2x 25G per compute node (if the compute nodes are large enough)."}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["25G: ",(0,t.jsx)(s.a,{href:"https://www.edge-core.com/product/dcs203/",children:"Edgecore DCS203 - AS7326-56X"})]}),"\n",(0,t.jsxs)(s.li,{children:["100G: ",(0,t.jsx)(s.a,{href:"https://www.edge-core.com/product/dcs204/",children:"Edgecore DCS204 - AS7726-32X"})]}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"spine-switches",children:"Spine switches"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["100G: ",(0,t.jsx)(s.a,{href:"https://www.edge-core.com/product/dcs204/",children:"Edgecore DCS204 - AS7726-32X"})]}),"\n",(0,t.jsxs)(s.li,{children:["400G: ",(0,t.jsx)(s.a,{href:"https://www.edge-core.com/product/dcs510/",children:"Edgecore DCS510 - AS9716-32D"})]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"network-interface-cards",children:"Network interface cards"})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>i,x:()=>d});var t=n(96540);const r={},o=t.createContext(r);function i(e){const s=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/013c29c1.c2633f9c.js b/assets/js/013c29c1.c2633f9c.js new file mode 100644 index 0000000000..c9aa6bc45c --- /dev/null +++ b/assets/js/013c29c1.c2633f9c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[923],{57919:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var t=o(74848),s=o(28453);const i={},r="Zuul monitoring",a={id:"operating-scs/components/monitoring/docs/zuul",title:"Zuul monitoring",description:"This page contains instructions on how to enable the Zuul monitoring in the Observer solution.",source:"@site/docs/04-operating-scs/components/monitoring/docs/zuul.md",sourceDirName:"04-operating-scs/components/monitoring/docs",slug:"/operating-scs/components/monitoring/docs/zuul",permalink:"/docs/operating-scs/components/monitoring/docs/zuul",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/zuul.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"KaaS monitoring (experimental)",permalink:"/docs/operating-scs/components/monitoring/docs/kaas"},next:{title:"Alertmanager notifications in Matrix chat",permalink:"/docs/operating-scs/components/monitoring/docs/alertmanager"}},c={},l=[];function u(e){const n={code:"code",h1:"h1",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"zuul-monitoring",children:"Zuul monitoring"}),"\n",(0,t.jsx)(n.p,{children:"This page contains instructions on how to enable the Zuul monitoring in the Observer solution."}),"\n",(0,t.jsx)(n.p,{children:"Zuul comes with support for the statsd protocol, hence the graphite instance is needed when\nwe want directly consume Zuul metrics."}),"\n",(0,t.jsx)(n.p,{children:"Graphite deployment:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"helm add repo kiwigrid https://kiwigrid.github.io\nhelm upgrade --install graphite kiwigrid/graphite -f zuul/values-zuul.yaml\n"})}),"\n",(0,t.jsx)(n.p,{children:"A UDP load balancer that exposes the Graphite receiver service:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f zuul/udp-lb-service.yaml\n"})}),"\n",(0,t.jsx)(n.p,{children:"Zuul dashboards:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f zuul/zuul-status-dashboard.yaml\nkubectl apply -f zuul/zuul-nodepool-dashboard.yaml\nkubectl create -f zuul/zuul-zookeeper-dashboard.yaml\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Find and uncomment a related section in ",(0,t.jsx)(n.code,{children:"values-observer.yaml"})," if you want to link the above\ndashboards to the L1 Zuul host dashboard.\nThe sections related to Zuul in the ",(0,t.jsx)(n.code,{children:"values-observer-scs.yaml"})," values file are already uncommented."]})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>r,x:()=>a});var t=o(96540);const s={},i=t.createContext(s);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/01a85c17.8945e087.js b/assets/js/01a85c17.8945e087.js new file mode 100644 index 0000000000..62cc1c2d33 --- /dev/null +++ b/assets/js/01a85c17.8945e087.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8209],{26535:(e,s,t)=>{t.d(s,{A:()=>v});var a=t(96540),i=t(18215),r=t(72415),l=t(24581),n=t(28774),c=t(21312),o=t(56347),d=t(99169);function m(e){const{pathname:s}=(0,o.zy)();return(0,a.useMemo)((()=>e.filter((e=>function(e,s){return!(e.unlisted&&!(0,d.ys)(e.permalink,s))}(e,s)))),[e,s])}const u={sidebar:"sidebar_re4s",sidebarItemTitle:"sidebarItemTitle_pO2u",sidebarItemList:"sidebarItemList_Yudw",sidebarItem:"sidebarItem__DBe",sidebarItemLink:"sidebarItemLink_mo7H",sidebarItemLinkActive:"sidebarItemLinkActive_I1ZP"};var b=t(74848);function g(e){let{sidebar:s}=e;const t=m(s.items);return(0,b.jsx)("aside",{className:"col col--3",children:(0,b.jsxs)("nav",{className:(0,i.A)(u.sidebar,"thin-scrollbar"),"aria-label":(0,c.T)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"}),children:[(0,b.jsx)("div",{className:(0,i.A)(u.sidebarItemTitle,"margin-bottom--md"),children:s.title}),(0,b.jsx)("ul",{className:(0,i.A)(u.sidebarItemList,"clean-list"),children:t.map((e=>(0,b.jsx)("li",{className:u.sidebarItem,children:(0,b.jsx)(n.A,{isNavLink:!0,to:e.permalink,className:u.sidebarItemLink,activeClassName:u.sidebarItemLinkActive,children:e.title})},e.permalink)))})]})})}var h=t(75600);function j(e){let{sidebar:s}=e;const t=m(s.items);return(0,b.jsx)("ul",{className:"menu__list",children:t.map((e=>(0,b.jsx)("li",{className:"menu__list-item",children:(0,b.jsx)(n.A,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active",children:e.title})},e.permalink)))})}function p(e){return(0,b.jsx)(h.GX,{component:j,props:e})}function x(e){let{sidebar:s}=e;const t=(0,l.l)();return s?.items.length?"mobile"===t?(0,b.jsx)(p,{sidebar:s}):(0,b.jsx)(g,{sidebar:s}):null}function v(e){const{sidebar:s,toc:t,children:a,...l}=e,n=s&&s.items.length>0;return(0,b.jsx)(r.A,{...l,children:(0,b.jsx)("div",{className:"container margin-vert--lg",children:(0,b.jsxs)("div",{className:"row",children:[(0,b.jsx)(x,{sidebar:s}),(0,b.jsx)("main",{className:(0,i.A)("col",{"col--7":n,"col--9 col--offset-1":!n}),children:a}),t&&(0,b.jsx)("div",{className:"col col--2",children:t})]})})})}},69158:(e,s,t)=>{t.r(s),t.d(s,{default:()=>j});t(96540);var a=t(18215),i=t(21312);const r=()=>(0,i.T)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});var l=t(61213),n=t(17559),c=t(26535),o=t(56133),d=t(51107);const m={tag:"tag_Nnez"};var u=t(74848);function b(e){let{letterEntry:s}=e;return(0,u.jsxs)("article",{children:[(0,u.jsx)(d.A,{as:"h2",id:s.letter,children:s.letter}),(0,u.jsx)("ul",{className:"padding--none",children:s.tags.map((e=>(0,u.jsx)("li",{className:m.tag,children:(0,u.jsx)(o.A,{...e})},e.permalink)))}),(0,u.jsx)("hr",{})]})}function g(e){let{tags:s}=e;const t=function(e){const s={};return Object.values(e).forEach((e=>{const t=function(e){return e[0].toUpperCase()}(e.label);s[t]??=[],s[t].push(e)})),Object.entries(s).sort(((e,s)=>{let[t]=e,[a]=s;return t.localeCompare(a)})).map((e=>{let[s,t]=e;return{letter:s,tags:t.sort(((e,s)=>e.label.localeCompare(s.label)))}}))}(s);return(0,u.jsx)("section",{className:"margin-vert--lg",children:t.map((e=>(0,u.jsx)(b,{letterEntry:e},e.letter)))})}var h=t(41463);function j(e){let{tags:s,sidebar:t}=e;const i=r();return(0,u.jsxs)(l.e3,{className:(0,a.A)(n.G.wrapper.blogPages,n.G.page.blogTagsListPage),children:[(0,u.jsx)(l.be,{title:i}),(0,u.jsx)(h.A,{tag:"blog_tags_list"}),(0,u.jsxs)(c.A,{sidebar:t,children:[(0,u.jsx)(d.A,{as:"h1",children:i}),(0,u.jsx)(g,{tags:s})]})]})}},56133:(e,s,t)=>{t.d(s,{A:()=>n});t(96540);var a=t(18215),i=t(28774);const r={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var l=t(74848);function n(e){let{permalink:s,label:t,count:n}=e;return(0,l.jsxs)(i.A,{href:s,className:(0,a.A)(r.tag,n?r.tagWithCount:r.tagRegular),children:[t,n&&(0,l.jsx)("span",{children:n})]})}}}]); \ No newline at end of file diff --git a/assets/js/03412b54.4e252d50.js b/assets/js/03412b54.4e252d50.js new file mode 100644 index 0000000000..10b7e67ad6 --- /dev/null +++ b/assets/js/03412b54.4e252d50.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9382],{11179:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>l,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=t(74848),o=t(28453);const r={},s="Developer Certificate of Origin + Licenses",c={id:"tools/github/dco-and-licenses",title:"Developer Certificate of Origin + Licenses",description:"The Developer Certificate of Origin (DCO) is a lightweight way for contributors",source:"@site/community/tools/github/dco-and-licenses.md",sourceDirName:"tools/github",slug:"/tools/github/dco-and-licenses",permalink:"/community/tools/github/dco-and-licenses",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Branch Protection Rules",permalink:"/community/tools/github/branchprotection"},next:{title:"Tips and Tricks",permalink:"/community/tools/github/tips-and-tricks"}},a={},d=[{value:"Further reading",id:"further-reading",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"developer-certificate-of-origin--licenses",children:"Developer Certificate of Origin + Licenses"}),"\n",(0,i.jsx)(n.p,{children:"The Developer Certificate of Origin (DCO) is a lightweight way for contributors\nto certify that they wrote or otherwise have the right to submit the code they\nare contributing to the Sovereign Cloud Stack."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"By making a contribution to this project, I certify that:\n\n(a) The contribution was created in whole or in part by me and I\n have the right to submit it under the open source license\n indicated in the file; or\n\n(b) The contribution is based upon previous work that, to the best\n of my knowledge, is covered under an appropriate open source\n license and I have the right under that license to submit that\n work with modifications, whether created in whole or in part\n by me, under the same open source license (unless I am\n permitted to submit under a different license), as indicated\n in the file; or\n\n(c) The contribution was provided directly to me by some other\n person who certified (a), (b) or (c) and I have not modified\n it.\n\n(d) I understand and agree that this project and the contribution\n are public and that a record of the contribution (including all\n personal information I submit with it, including my sign-off) is\n maintained indefinitely and may be redistributed consistent with\n this project or the open source license(s) involved.\n"})}),"\n",(0,i.jsxs)(n.p,{children:["All contributions to the Sovereign Cloud Stack are licensed under the\n(OSI approved) open source license of the upstream project being used therein\n(very often this is the ",(0,i.jsx)(n.a,{href:"https://www.apache.org/licenses/LICENSE-2.0",children:"Apache Software License v2"}),")."]}),"\n",(0,i.jsxs)(n.p,{children:["Where we create independent code, we prefer to use the ",(0,i.jsx)(n.a,{href:"https://www.gnu.org/licenses/agpl-3.0.html",children:"GNU Affero General Public License 3"}),",\nexcept for interface code which we would put under LGPL-3 (weak copyleft).\nOwn documentation content is licensed under ",(0,i.jsx)(n.a,{href:"https://creativecommons.org/licenses/by-sa/4.0/",children:"Creative Commons BY-SA 4.0"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Contributors sign-off that they adhere to these requirements by adding a ",(0,i.jsx)(n.code,{children:"Signed-off-by"}),"\nline to commit messages."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"My fancy commit message\n\nSigned-off-by: Christian Berendt \n"})}),"\n",(0,i.jsxs)(n.p,{children:["Git has a ",(0,i.jsx)(n.code,{children:"-s"})," command line option to append this automatically to your commit message:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"git commit -s -m 'My fancy commit message'\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The status of a pull request is set to failed if commits do not contain a valid ",(0,i.jsx)(n.code,{children:"Signed-off-by"})," line."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Failed DCO in GitHub",src:t(15120).A+"",width:"1868",height:"864"})}),"\n",(0,i.jsxs)(n.p,{children:["Considerations behind the choice of AGPLv3, CC-BY-SA and the usage of the DCO can be found ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/license-considerations.md",children:"license-considerations.md"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"further-reading",children:"Further reading"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://developercertificate.org/",children:"https://developercertificate.org/"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/",children:"https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://lwn.net/Articles/592503/",children:"https://lwn.net/Articles/592503/"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},15120:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/github-failed-dco-82f9dafea83c36769069087ceb522cdc.png"},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>c});var i=t(96540);const o={},r=i.createContext(o);function s(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03babb4a.4f8df050.js b/assets/js/03babb4a.4f8df050.js new file mode 100644 index 0000000000..67c629f133 --- /dev/null +++ b/assets/js/03babb4a.4f8df050.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2294],{85657:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>l,frontMatter:()=>r,metadata:()=>c,toc:()=>a});var i=n(74848),s=n(28453);const r={},o="Tips and Tricks",c={id:"tools/github/tips-and-tricks",title:"Tips and Tricks",description:"Octo Reminder - your friendly assistant",source:"@site/community/tools/github/tips-and-tricks.md",sourceDirName:"tools/github",slug:"/tools/github/tips-and-tricks",permalink:"/community/tools/github/tips-and-tricks",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Developer Certificate of Origin + Licenses",permalink:"/community/tools/github/dco-and-licenses"},next:{title:"Test and development cloud resources",permalink:"/community/cloud-resources/"}},d={},a=[{value:"Octo Reminder - your friendly assistant",id:"octo-reminder---your-friendly-assistant",level:2}];function u(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"tips-and-tricks",children:"Tips and Tricks"}),"\n",(0,i.jsx)(t.h2,{id:"octo-reminder---your-friendly-assistant",children:"Octo Reminder - your friendly assistant"}),"\n",(0,i.jsxs)(t.p,{children:["Are you tired of keeping track of planned changes or issues you scheduled for the future? Our ",(0,i.jsx)(t.a,{href:"https://github.com/apps/octo-reminder",children:"Octo Reminder"})," is here to safe you from unneeded cognitive load!"]}),"\n",(0,i.jsxs)(t.p,{children:["The app configuration is stored in our ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/.github/",children:(0,i.jsx)(t.code,{children:".github"})})," repository. Using the bot is fairly simple:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["To schedule a reminder, simply comment with ",(0,i.jsx)(t.code,{children:"/remind-me [date] [message]"})," on an issue or pull request. The bot will answer and mention you in the particular issue/pull request upon reaching the configured date."]}),"\n",(0,i.jsx)(t.li,{children:"If you don't specify a time for the reminder, the bot will use 9:00 CET as default reminder time."}),"\n",(0,i.jsxs)(t.li,{children:["The date and time can be anything that ",(0,i.jsx)(t.a,{href:"https://momentjs.com/docs/#/parsing/",children:"momentjs"})," understands, e.g. an ISO 8601 string or a relative string such as ",(0,i.jsx)(t.code,{children:"tomorrow"})," or ",(0,i.jsx)(t.code,{children:"next week"}),"."]}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>c});var i=n(96540);const s={},r=i.createContext(s);function o(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03c8668f.54609418.js b/assets/js/03c8668f.54609418.js new file mode 100644 index 0000000000..c7113ff0cf --- /dev/null +++ b/assets/js/03c8668f.54609418.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4507],{71141:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>o,contentTitle:()=>d,default:()=>l,frontMatter:()=>r,metadata:()=>i,toc:()=>c});var n=s(74848),a=s(28453);const r={},d="scs-0412: Exposition of IaaS metering data as JSON",i={id:"ops/scs-0412",title:"scs-0412: Exposition of IaaS metering data as JSON",description:"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format",source:"@site/standards/ops/scs-0412.md",sourceDirName:"ops",slug:"/ops/scs-0412",permalink:"/standards/ops/scs-0412",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Push-based approach for providing usage data",permalink:"/standards/scs-0411-v1-publishing_method_for_metering_data"},next:{title:"Exposition of IaaS metering data as JSON",permalink:"/standards/scs-0412-v1-metering-json"}},o={},c=[];function h(e){const t={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"scs-0412-exposition-of-iaas-metering-data-as-json",children:"scs-0412: Exposition of IaaS metering data as JSON"}),"\n",(0,n.jsx)(t.p,{children:"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format\nwithin the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with\ntheir existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format\nprovided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation\nlayers and implementation components."}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0412-v1-metering-json",children:"scs-0412-v1"})}),(0,n.jsx)(t.td,{children:"Standard"}),(0,n.jsx)(t.td,{children:"Draft"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>i});var n=s(96540);const a={},r=n.createContext(a);function d(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/04437fec.213a5ef8.js b/assets/js/04437fec.213a5ef8.js new file mode 100644 index 0000000000..a883ce9e07 --- /dev/null +++ b/assets/js/04437fec.213a5ef8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9075],{90697:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>l});var n=s(74848),i=s(28453);const o={title:"Volume Type Standard",type:"Standard",status:"Draft",track:"IaaS"},a=void 0,r={id:"scs-0114-v1-volume-type-standard",title:"Volume Type Standard",description:"Introduction",source:"@site/standards/scs-0114-v1-volume-type-standard.md",sourceDirName:".",slug:"/scs-0114-v1-volume-type-standard",permalink:"/standards/scs-0114-v1-volume-type-standard",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Volume Type Standard",type:"Standard",status:"Draft",track:"IaaS"},sidebar:"standards",previous:{title:"scs-0114: Volume Type Standard",permalink:"/standards/iaas/scs-0114"},next:{title:"scs-0115: Default Rules for Security Groups",permalink:"/standards/iaas/scs-0115"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Glossary",id:"glossary",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Systematic Description of Volume Types",id:"systematic-description-of-volume-types",level:3},{value:"Standardized Aspects",id:"standardized-aspects",level:3},{value:"DEFAULT volume type",id:"default-volume-type",level:2},{value:"REQUIRED volume types",id:"required-volume-types",level:2},{value:"RECOMMENDED volume types",id:"recommended-volume-types",level:2},{value:"OPTIONAL volume types",id:"optional-volume-types",level:2},{value:"Implementation Details",id:"implementation-details",level:2},{value:"Encryption",id:"encryption",level:3},{value:"Replication",id:"replication",level:3},{value:"Example",id:"example",level:3},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsx)(t.p,{children:"A volume is a virtual drive that is to be used by an instance (i. e., a virtual machine). With OpenStack,\neach volume is created per a type that determines basic features of the volume as provided by the backend,\nsuch as encryption, replication, or quality of service. As of the writing of this document, presence or absence of these\nfeatures can not be discovered with full certainty by non-privileged users via the OpenStack API."}),"\n",(0,n.jsx)(t.h3,{id:"glossary",children:"Glossary"}),"\n",(0,n.jsx)(t.p,{children:"The following special terms are used throughout this standard document:"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Term"}),(0,n.jsx)(t.th,{children:"Meaning"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"volume"}),(0,n.jsx)(t.td,{children:"OpenStack resource, virtual drive which usually resides in a network storage backend"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"volume feature"}),(0,n.jsx)(t.td,{children:"A certain feature a volume can possess"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"aspect"}),(0,n.jsx)(t.td,{children:"Part of a volume type that will activate a corresponding feature in a created volume"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"AZ"}),(0,n.jsx)(t.td,{children:"Availability Zone"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Volume QoS"}),(0,n.jsx)(t.td,{children:"Quality of Service object for Volumes"})]})]})]}),"\n",(0,n.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,n.jsx)(t.p,{children:"As an SCS user, I want to be able to create volumes with certain common features, such as encryption or\nreplication, and to do so in a standardized manner as well as programmatically.\nThis standard outlines a way of formally advertising these common aspects for a volume type to\nnon-privileged users, so that the most suitable volume type can be discovered and selected easily \u2014 both by\nthe human user and by a program."}),"\n",(0,n.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,n.jsxs)(t.p,{children:["All considerations can be looked up in detail in the ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0111-v1-volume-type-decisions.md",children:"Decision Record for the Volume Type Standard."})]}),"\n",(0,n.jsx)(t.h3,{id:"systematic-description-of-volume-types",children:"Systematic Description of Volume Types"}),"\n",(0,n.jsxs)(t.p,{children:["To test whether a deployment has volume types with certain aspects, the discoverability of the parameters in the volume type has to be given. As for the time this standard is created, there is no way for users to discover all aspects through OpenStack commands. Therefore the aspects, that are fulfilled within a volume type, should be stated in the beginning of the ",(0,n.jsx)(t.strong,{children:"description"})," of a volume type in the following manner:"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.code,{children:"[scs:aspect1, aspect2, ..., aspectN]..."})}),"\n",(0,n.jsx)(t.p,{children:"The mentioned aspects MUST be sorted alphebetically and every aspect should only be mentioned to the maximal amount of one."}),"\n",(0,n.jsx)(t.h3,{id:"standardized-aspects",children:"Standardized Aspects"}),"\n",(0,n.jsx)(t.p,{children:"The following table shows which aspects are considered in this standard. The third column shows how the description of the volume type has to be adjusted, if the aspect is fulfilled:"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Aspect"}),(0,n.jsx)(t.th,{children:"Requirement"}),(0,n.jsx)(t.th,{children:"standardized description"}),(0,n.jsx)(t.th,{children:"comment"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Encryption"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"Recommended"})}),(0,n.jsx)(t.td,{children:(0,n.jsxs)(t.strong,{children:['"[scs',":encrypted",']"']})}),(0,n.jsx)(t.td,{children:"volume is encrypted"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Replication"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"Recommended"})}),(0,n.jsx)(t.td,{children:(0,n.jsxs)(t.strong,{children:['"[scs',":replicated",']"']})}),(0,n.jsx)(t.td,{children:"volume is replicated to avoid data loss in a case of hardware failure"})]})]})]}),"\n",(0,n.jsx)(t.p,{children:"It is possible to use multiple of those aspects within one volume type. There don't have to be different volume types for each aspect.\nFor instance, one volume type that uses LUKS-encryption with a ceph storage with inherent replication would fulfill all recommendations of this standard."}),"\n",(0,n.jsx)(t.h2,{id:"default-volume-type",children:"DEFAULT volume type"}),"\n",(0,n.jsxs)(t.p,{children:["There is always a default volume type defined in an OpenStack deployment. This volume type is created in the setup of cinder and will always be present in any OpenStack deployments under the name ",(0,n.jsx)(t.code,{children:"__default__"}),". This standard does not have any requirements about this volume type at this moment, instead deployers are free to choose what fits best in their environment. Conversely, a cloud user can not expect any specific behavior or properties from volume types named ",(0,n.jsx)(t.code,{children:"__default__"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"required-volume-types",children:"REQUIRED volume types"}),"\n",(0,n.jsx)(t.p,{children:"Currently, this standard will not require volume types with certain specification."}),"\n",(0,n.jsx)(t.h2,{id:"recommended-volume-types",children:"RECOMMENDED volume types"}),"\n",(0,n.jsx)(t.p,{children:"This standard recommends to have one or more volume types, that feature encryption and replication."}),"\n",(0,n.jsx)(t.h2,{id:"optional-volume-types",children:"OPTIONAL volume types"}),"\n",(0,n.jsx)(t.p,{children:"Any other aspects of volume types, that can be found in the decision record are OPTIONAL. They SHOULD NOT be referenced in the way this standard describes. Some of them already are natively discoverable by users, while others could be described in the name or description of a volume type. Users should look into the provided volume types of the Cloud Service Providers, if they want to use some of these other aspects."}),"\n",(0,n.jsx)(t.h2,{id:"implementation-details",children:"Implementation Details"}),"\n",(0,n.jsx)(t.h3,{id:"encryption",children:"Encryption"}),"\n",(0,n.jsxs)(t.p,{children:["Encryption for volumes is an option which has to be configured within the volume type. As an admin it is possible to set encryption-provider, key size, cipher and control location. Additionally to be discoverable by users, the description should start with an aspect list such as ",(0,n.jsx)(t.code,{children:"[scs:encrypted]"})," (potentially with additional aspects). It should look like this example:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-text",children:"openstack volume type show LUKS\n+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Field | Value |\n+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| access_project_ids | None |\n| description | [scs:encrypted] This volume uses LUKS-encryption |\n| id | d63307fb-167a-4aa0-9066-66595ea9fb21 |\n| is_public | True |\n| name | LUKS |\n| qos_specs_id | None |\n+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+\n"})}),"\n",(0,n.jsx)(t.h3,{id:"replication",children:"Replication"}),"\n",(0,n.jsx)(t.p,{children:"Replication states whether or not there are multiple replicas of a volume. Thus, it answers the question whether the data could survive a node outage. Unfortunately there are two ways replication can be achieved:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"In the configuration of a volume type. It then is visible as extra_spec in the properties of a volume type."}),"\n",(0,n.jsx)(t.li,{children:"Via the used backend. Ceph for example provides automatic replication, that does not need to be specified in the volume type. This is currently not visible for users."}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["To fulfill this recommendation, the description should start with an aspect list such as ",(0,n.jsx)(t.code,{children:"[scs:replicated]"})," (potentially with additional aspects)."]}),"\n",(0,n.jsx)(t.h3,{id:"example",children:"Example"}),"\n",(0,n.jsx)(t.p,{children:"One volume type that is configured as an encrypted volume type in a ceph backend, with automated replication would fit both recommendations and will be enough to comply to this part of the volume type standard."}),"\n",(0,n.jsx)(t.p,{children:"It should look like the following part:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-text",children:"+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| Field | Value |\n+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+\n| access_project_ids | None |\n| description | [scs:encrypted, replicated] Content will be replicated three times to ensure consistency and availability for your data. LUKS encryption is used. |\n| id | d63307fb-167a-4aa0-9066-66595ea9fb21 |\n| is_public | True |\n| name | hdd-three-replicas-LUKS |\n| properties | |\n| qos_specs_id | None |\n+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+\n"})}),"\n",(0,n.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["corresponding ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0111-v1-volume-type-decisions.md",children:"decision record document"})]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,n.jsxs)(t.p,{children:["The script ",(0,n.jsx)(t.code,{children:"/Tests/iaas/volume-types/volume-types-check.py"})," connects to an OpenStack environment and tests\nthe following:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["for each volume type: if its description starts with ",(0,n.jsx)(t.code,{children:"[scs:....]"}),", then this prefix is a feature list\n(sorted, each entry at most once), and each entry is one of the possible features described here,"]}),"\n",(0,n.jsx)(t.li,{children:"the recommended volume types are present (otherwise, a WARNING is produced)."}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"The return code is zero precisely when the test could be performed and the conditions are satisfied.\nOtherwise, detailed errors and warnings are output to stderr."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>r});var n=s(96540);const i={},o=n.createContext(i);function a(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0476f709.806a849f.js b/assets/js/0476f709.806a849f.js new file mode 100644 index 0000000000..3825e1cece --- /dev/null +++ b/assets/js/0476f709.806a849f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[344],{698:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var i=n(74848),s=n(28453);const r={title:"Robustness features for Kubernetes clusters",type:"Standard",status:"Draft",track:"KaaS"},a=void 0,o={id:"scs-0215-v1-robustness-features",title:"Robustness features for Kubernetes clusters",description:"Introduction",source:"@site/standards/scs-0215-v1-robustness-features.md",sourceDirName:".",slug:"/scs-0215-v1-robustness-features",permalink:"/standards/scs-0215-v1-robustness-features",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Robustness features for Kubernetes clusters",type:"Standard",status:"Draft",track:"KaaS"},sidebar:"standards",previous:{title:"scs-0215: Robustness features for Kubernetes clusters",permalink:"/standards/kaas/scs-0215"},next:{title:"scs-0216: Requirements for testing cluster-stacks",permalink:"/standards/kaas/scs-0216"}},c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Glossary",id:"glossary",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Kube-API rate limiting",id:"kube-api-rate-limiting",level:3},{value:"API server flags",id:"api-server-flags",level:4},{value:"Ratelimit Admission Controller",id:"ratelimit-admission-controller",level:4},{value:"Flow control",id:"flow-control",level:4},{value:"etcd maintenance",id:"etcd-maintenance",level:3},{value:"etcd backup",id:"etcd-backup",level:3},{value:"Certificate rotation",id:"certificate-rotation",level:3},{value:"Automatic certificate rotation",id:"automatic-certificate-rotation",level:4},{value:"Decision",id:"decision",level:2},{value:"Kube-API rate limiting",id:"kube-api-rate-limiting-1",level:3},{value:"etcd compaction",id:"etcd-compaction",level:3},{value:"etcd backup",id:"etcd-backup-1",level:3},{value:"Certificate rotation",id:"certificate-rotation-1",level:3},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function d(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"Kubernetes clusters in a productive environment are under the assumption to always perform perfectly without any major\ninterruptions. But due to external or unforeseen influences, clusters can be disrupted in their normal workflow, which\ncould lead to slow responsiveness or even malfunctions.\nIn order to possibly mitigate some problems for the Kubernetes clusters, robustness features should be introduced into\nthe SCS standards. These would harden the cluster infrastructure against several problems, making failures less likely."}),"\n",(0,i.jsx)(t.h3,{id:"glossary",children:"Glossary"}),"\n",(0,i.jsx)(t.p,{children:"The following special terms are used throughout this standard document:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Term"}),(0,i.jsx)(t.th,{children:"Abbreviation"}),(0,i.jsx)(t.th,{children:"Meaning"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Certificate Authority"}),(0,i.jsx)(t.td,{children:"CA"}),(0,i.jsx)(t.td,{children:"Trusted organization that issues digital certificates entities"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Certificate Signing Request"}),(0,i.jsx)(t.td,{children:"CSR"}),(0,i.jsx)(t.td,{children:"Request in order to apply for a digital identity certificate"})]})]})]}),"\n",(0,i.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:"A typical productive Kubernetes cluster could be hardened in many different ways, whereas probably many of these actions\nwould overlap and target similar weaknesses of a cluster.\nFor this version of the standard, the following points should be addressed:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Kube-API rate limiting"}),"\n",(0,i.jsx)(t.li,{children:"etcd compaction/defragmentation"}),"\n",(0,i.jsx)(t.li,{children:"etcd backup"}),"\n",(0,i.jsx)(t.li,{children:"Certificate Authority (CA) expiration avoidance"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:'These robustness features should mainly increase the up-time of the Kubernetes cluster by avoiding downtimes either\nbecause of internal problems or external threads like "Denial of Service" attacks.\nAdditionally, the etcd database should be strengthened with these features in order to provide a secure and robust\nbackend for the Kubernetes cluster.'}),"\n",(0,i.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsx)(t.p,{children:"In order to provide a conclusive standard, some design considerations need to be set beforehand:"}),"\n",(0,i.jsx)(t.h3,{id:"kube-api-rate-limiting",children:"Kube-API rate limiting"}),"\n",(0,i.jsx)(t.p,{children:"Rate limiting is the practice of preventing too many requests to the same server in some time frame. This can help prevent\nservice interruptions due to congestion and therefore slow responsiveness or even service shutdown.\nKubernetes suggests multiple ways to integrate such a Ratelimit for its API server, a few of which will be mentioned here.\nIn order to provide a useful Ratelimit for the Kubernetes cluster, combination of these methods should be considered."}),"\n",(0,i.jsx)(t.h4,{id:"api-server-flags",children:"API server flags"}),"\n",(0,i.jsx)(t.p,{children:"The Kubernetes API server has some flags available to limit the amount of incoming requests that will be accepted by\nthe server, which should prevent crashing of the API server. This nevertheless shouldn't be the only measure to\nintroduce a rate limit, since important requests could get blocked during high traffic periods (at least according to\nthe official documentation).\nThe following controls are available to tune the server:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"max-requests-inflight"}),"\n",(0,i.jsx)(t.li,{children:"max-mutating-requests-inflight"}),"\n",(0,i.jsx)(t.li,{children:"min-request-timeout"}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["More details can be found in the following documents:\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/flow-control/",children:"Flow Control"})]}),"\n",(0,i.jsx)(t.h4,{id:"ratelimit-admission-controller",children:"Ratelimit Admission Controller"}),"\n",(0,i.jsxs)(t.p,{children:["From version 1.13 onwards, Kubernetes includes a EventRateLimit Admission Controller, which aims to mitigate Ratelimit\nproblems associated with the API server by providing limits for requests every second either to specific resources or\neven the whole API server. If requests are denied due to this Admission Controller, they're either cached or denied\ncompletely and need to be retried; this also depends on the EventRateLimit configuration.\nMore details can be found in the following documents:\n",(0,i.jsx)(t.a,{href:"https://rke.docs.rancher.com/config-options/rate-limiting",children:"Rancher rate limiting"}),"\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#eventratelimit",children:"EventRateLimit"}),"\nIt is important to note, that this only helps the API server against event overloads and not necessarily the network\nin front of it, which could still be overwhelmed."]}),"\n",(0,i.jsx)(t.h4,{id:"flow-control",children:"Flow control"}),"\n",(0,i.jsxs)(t.p,{children:["Flow control for the Kubernetes API server can be provided by the API priority and fairness feature, which classifies\nand isolates requests in a fine-grained way in order to prevent an overload of the API server.\nThe package introduces queues in order to not deny requests and dequeue them through Fair Queueing techniques.\nOverall, the Flow control package introduces many different features like request queues, rule-based flow control,\ndifferent priority levels and rate limit maximums.\nThe concept documentation offers a more in-depth explanation of the feature:\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/flow-control/",children:"Flow Control"})]}),"\n",(0,i.jsx)(t.h3,{id:"etcd-maintenance",children:"etcd maintenance"}),"\n",(0,i.jsx)(t.p,{children:"etcd is a strongly consistent, distributed key-value store that provides a reliable way to store data that needs to be\naccessed by a distributed system or cluster of machines. For these reasons, etcd was chosen as the default database\nfor Kubernetes.\nIn order to remain reliable, an etcd cluster needs periodic maintenance. This is necessary to maintain the etcd keyspace;\nfailure to do so could lead to a cluster-wide alarm, which would put the cluster into a limited-operation mode.\nTo mitigate this scenario, the etcd keyspace can be compacted. Additionally, an etcd cluster can be defragmented, which\ngives back disk space to the underlying file system and can help bring the cluster back into an operable state, if it\nran out of space earlier."}),"\n",(0,i.jsx)(t.p,{children:"etcd keyspace maintenance can be achieved by providing the necessary flags/parameters to etcd, either via the KubeadmControlPlane or in the\nconfiguration file of the etcd cluster, if it is managed independent of the Kubernetes cluster.\nPossible flags, that can be set for this feature, are:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"auto-compaction-mode"}),"\n",(0,i.jsx)(t.li,{children:"auto-compaction-retention"}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["More information about compaction can be found in the respective etcd documentation\n",(0,i.jsx)(t.a,{href:"https://etcd.io/docs/v3.3/op-guide/maintenance/",children:"etcd maintenance"})]}),"\n",(0,i.jsx)(t.h3,{id:"etcd-backup",children:"etcd backup"}),"\n",(0,i.jsxs)(t.p,{children:["An etcd cluster should be regularly backed up in order to be able to restore the cluster to a known good state at an\nearlier space in time if a failure or incorrect state happens.\nThe cluster should be backed up multiple times in order to have different possible states to go back to. This is especially\nuseful, if data in the newer backups was already corrupted in some way or important data was deleted in them.\nFor this reason, a backup strategy needs to be developed with a decreasing number of backups in an increasing period of time,\nmeaning that the previous year should only have 1 backup, but the current week should have multiple.\nInformation about the backup process can be found in the etcd documentation:\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/",children:"Upgrade etcd"})]}),"\n",(0,i.jsx)(t.h3,{id:"certificate-rotation",children:"Certificate rotation"}),"\n",(0,i.jsxs)(t.p,{children:["In order to secure the communication of a Kubernetes cluster, (TLS) certificates signed by a controlled\nCertificate Authority (CA) can be used.\nNormally, these certificates expire after a set period of time. In order to avoid expiration and failure of a cluster,\nthese certificates need to be rotated regularly and at best automatically.\nCertificates can either be rotated manually (a reference for manually working with certificates can be found\n",(0,i.jsx)(t.a,{href:"https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/79a3f79b27bd28f82f071bb877a266c2e62ee506/docs/04-certificate-authority.md",children:"here"}),")\nor automatically, which requires other things to care about in a deployment."]}),"\n",(0,i.jsxs)(t.p,{children:["Some tools or clusters provide possibilities to rotate certificates manually.\nFor example, ",(0,i.jsx)(t.code,{children:"kubeadm"})," and ",(0,i.jsx)(t.code,{children:"k3s"})," provides the following commands"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"# kubeadm\nkubeadm certs renew all\n\n# k3s\nk3s certificate rotate\n"})}),"\n",(0,i.jsx)(t.p,{children:"A CA might also expire. Unfortunately, not all Kubernetes tools have functionality to renew these certificates.\nInstead, documentation is provided to manually rotating a CA ([Manual rotation of ca certificate])."}),"\n",(0,i.jsx)(t.h4,{id:"automatic-certificate-rotation",children:"Automatic certificate rotation"}),"\n",(0,i.jsxs)(t.p,{children:["kubelet can be configured to obtain properly signed certificates from the ",(0,i.jsx)(t.code,{children:"certificates.k8s.io"})," API of Kubernetes.\nTo do this, set ",(0,i.jsx)(t.code,{children:"serverTLSBootstrap: true"})," in the configuration file of kubelet, which enables both the certificate request\nduring bootstrapping and the rotation mechanism. Setting ",(0,i.jsx)(t.code,{children:"rotateCertificates: true"})," only enables the certificate rotation [Kubeadm certs].\n",(0,i.jsx)(t.code,{children:"--rotate-certificates"})," or ",(0,i.jsx)(t.code,{children:"--rotate-server-certificates"})," shouldn't be used as command line arguments to set these flags,\nsince both parameters are deprecated according to [Certificate rotation]."]}),"\n",(0,i.jsxs)(t.p,{children:["It is also important to note that some Kubernetes clusters or admin tools provide additional ways to rotate certificates.\nFor example, ",(0,i.jsx)(t.code,{children:"kubeadm"})," automatically rotates certificates, if the cluster is updated with the tool (see [Automatic Certificate renewal]).\nThis would also mean, that at least ",(0,i.jsx)(t.code,{children:"kubeadm"}),"-based clusters can be assumed to rotate their certificates regularly,\nsince they would probably be updated within the time period described in the\nstandard ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Standards/scs-0210-v2-k8s-version-policy.md",children:"SCS-0210-v2"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["If an automatic certificate rotation happens, these certificates need to be approved either manually or by a third party\ncontroller like the ",(0,i.jsx)(t.a,{href:"https://github.com/postfinance/kubelet-csr-approver",children:"kubelet csr approver"}),", which can be deployed on\na Kubernetes cluster to automate this process."]}),"\n",(0,i.jsx)(t.p,{children:"A manual approval of these CSRs could be done with the commands"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"kubectl get csr\nkubectl certificate approve \n"})}),"\n",(0,i.jsx)(t.p,{children:"in order to complete a certificate rotation.\nBut it should be noted, that this is also most likely dependent on the Kubernetes cluster solution in use."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.code,{children:"kubectl get csr"})," allows to check, if a CSR needs to be approved; a ",(0,i.jsx)(t.code,{children:"Pending"})," CSR would need to be approved."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"NAME AGE SIGNERNAME REQUESTOR CONDITION\ncsr-9wvgt 112s kubernetes.io/kubelet-serving system:node:worker-1 Pending\n"})}),"\n",(0,i.jsxs)(t.p,{children:["Further information and examples can be found in the Kubernetes documentation:\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/",children:"Kubeadm certs"}),"\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/kubelet-tls-bootstrapping/",children:"Kubelete TLS bootstrapping"})]}),"\n",(0,i.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(t.p,{children:"Robustness features combine multiple aspects of increasing the security, hardness and\nlongevity of a Kubernetes cluster. The decisions will be separated into their respective\nareas."}),"\n",(0,i.jsx)(t.h3,{id:"kube-api-rate-limiting-1",children:"Kube-API rate limiting"}),"\n",(0,i.jsx)(t.p,{children:"The number of requests send to the kube-api or Kubernetes API server MUST be limited\nin order to protect the server against outages, deceleration or malfunctions due to an\noverload of requests.\nIn order to do so, at least the following parameters MUST be set on a Kubernetes cluster:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"max-requests-inflight"}),"\n",(0,i.jsx)(t.li,{children:"max-mutating-requests-inflight"}),"\n",(0,i.jsx)(t.li,{children:"min-request-timeout"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Values for these flags/parameters SHOULD be adapted to the needs of the environment and\nthe expected load."}),"\n",(0,i.jsxs)(t.p,{children:["A cluster MUST also activate and configure a Ratelimit admission controller.\nThis requires an ",(0,i.jsx)(t.code,{children:"EventRateLimit"})," resource to be deployed on the Kubernetes cluster.\nThe following settings are RECOMMENDED for a cluster-wide deployment, but more\nfine-grained rate limiting can also be applied, if this is necessary."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-yaml",children:"kind: Configuration\napiVersion: eventratelimit.admission.k8s.io/v1alpha1\nlimits:\n- burst: 20000\n qps: 5000\n type: Server\n"})}),"\n",(0,i.jsx)(t.p,{children:"It is also RECOMMENDED to activate the Kubernetes API priority and fairness feature,\nwhich also uses the aforementioned cluster parameters to better queue, schedule and\nprioritize incoming requests."}),"\n",(0,i.jsx)(t.h3,{id:"etcd-compaction",children:"etcd compaction"}),"\n",(0,i.jsx)(t.p,{children:"etcd MUST be cleaned up regularly, so that it functions correctly and doesn't take\nup too much space, which happens because of its increase of the keyspace."}),"\n",(0,i.jsx)(t.p,{children:"To compact the etcd keyspace, the following flags/parameters MUST be set for etcd:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"auto-compaction-mode = periodic"}),"\n",(0,i.jsx)(t.li,{children:"auto-compaction-retention = 8h"}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"etcd-backup-1",children:"etcd backup"}),"\n",(0,i.jsx)(t.p,{children:"An etcd cluster MUST be backed up regularly. It is RECOMMENDED to adapt\na strategy of decreasing backups over longer time periods, e.g. keeping snapshots every\n10 minutes for the last 120 minutes, then one hourly for 1 day, then one daily for 2 weeks,\nthen one weekly for 3 months, then one monthly for 2 years, and after that a yearly backup.\nAt the very least, a backup MUST be done once a week.\nThese numbers can be adapted to the security setup and concerns like storage or network\nusage. It is also RECOMMENDED to encrypt the backups in order to secure them further.\nHow this is done is up to the operator."}),"\n",(0,i.jsx)(t.h3,{id:"certificate-rotation-1",children:"Certificate rotation"}),"\n",(0,i.jsx)(t.p,{children:"It should be avoided, that certificates expire either on the whole cluster or for single components.\nTo avoid this scenario, certificates MUST be rotated regularly; in the\ncase of SCS, we REQUIRE at least a yearly certificate rotation."}),"\n",(0,i.jsx)(t.p,{children:"It is also RECOMMENDED to renew the CA regularly to avoid an expiration of the CA.\nThis standard doesn't set an exact timeline for a renewal, since it is dependent on lifetime and\ntherefore expiration date of the CA in question."}),"\n",(0,i.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/cluster-administration/flow-control/",children:"Flow Control"}),"\n",(0,i.jsx)(t.a,{href:"https://rke.docs.rancher.com/config-options/rate-limiting",children:"Rate limiting"}),"\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#eventratelimit",children:"EventRateLimit"}),"\n",(0,i.jsx)(t.a,{href:"https://etcd.io/docs/v3.3/op-guide/maintenance/",children:"etcd maintenance"}),"\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/",children:"Upgrade etcd"}),"\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/",children:"Kubeadm certs"}),"\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/kubelet-tls-bootstrapping/",children:"Kubelet TLS bootstrapping"}),"\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/kubelet-tls-bootstrapping/#certificate-rotation",children:"Certificate rotation"}),"\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/tls/manual-rotation-of-ca-certificates/",children:"Manual rotation of ca certificate"}),"\n",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#automatic-certificate-renewal",children:"Automatic Certificate renewal"})]}),"\n",(0,i.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,i.jsx)(t.p,{children:"Conformance Tests, OPTIONAL"})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const s={},r=i.createContext(s);function a(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/04fe2bfd.0fd858a8.js b/assets/js/04fe2bfd.0fd858a8.js new file mode 100644 index 0000000000..b9e3f287cd --- /dev/null +++ b/assets/js/04fe2bfd.0fd858a8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2106],{9142:(t,e,o)=>{o.r(e),o.d(e,{assets:()=>u,contentTitle:()=>r,default:()=>m,frontMatter:()=>n,metadata:()=>c,toc:()=>l});var s=o(74848),i=o(28453);const n={slug:"first-blog-post",title:"First Blog Post",authors:"itrich",tags:["community","howto"]},r=void 0,c={permalink:"/blog/first-blog-post",editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/blog/2022-10-28-first-blog-post.md",source:"@site/blog/2022-10-28-first-blog-post.md",title:"First Blog Post",description:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet",date:"2022-10-28T00:00:00.000Z",tags:[{label:"community",permalink:"/blog/tags/community"},{label:"howto",permalink:"/blog/tags/howto"}],readingTime:.12,hasTruncateMarker:!1,authors:[{name:"Eduard Itrich",title:"Community Manager @ SCS",url:"https://github.com/itrich",imageURL:"https://github.com/itrich.png",key:"itrich"}],frontMatter:{slug:"first-blog-post",title:"First Blog Post",authors:"itrich",tags:["community","howto"]},unlisted:!1},u={authorsImageUrls:[void 0]},l=[];function a(t){const e={p:"p",...(0,i.R)(),...t.components};return(0,s.jsx)(e.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"})}function m(t={}){const{wrapper:e}={...(0,i.R)(),...t.components};return e?(0,s.jsx)(e,{...t,children:(0,s.jsx)(a,{...t})}):a(t)}},28453:(t,e,o)=>{o.d(e,{R:()=>r,x:()=>c});var s=o(96540);const i={},n=s.createContext(i);function r(t){const e=s.useContext(n);return s.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:r(t.components),s.createElement(n.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/059c4264.bb649876.js b/assets/js/059c4264.bb649876.js new file mode 100644 index 0000000000..506aae8b35 --- /dev/null +++ b/assets/js/059c4264.bb649876.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7990],{80233:e=>{e.exports=JSON.parse('{"title":"Status Page API","slug":"/category/status-page-api","permalink":"/docs/category/status-page-api","navigation":{"previous":{"title":"Components","permalink":"/docs/category/components-2"},"next":{"title":"Overview","permalink":"/docs/operating-scs/components/status-page/docs/overview"}}}')}}]); \ No newline at end of file diff --git a/assets/js/05e7973d.e7395588.js b/assets/js/05e7973d.e7395588.js new file mode 100644 index 0000000000..6d64a47d83 --- /dev/null +++ b/assets/js/05e7973d.e7395588.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9823],{87699:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>d,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>c});var n=s(74848),i=s(28453);const o={sidebar_label:"SSH Config"},d="SSH Config",r={id:"iaas/guides/configuration-guide/commons/sshconfig",title:"SSH Config",description:"With the osism.commons.sshconfig role, it is possible to manage a SSH config",source:"@site/docs/02-iaas/guides/configuration-guide/commons/sshconfig.md",sourceDirName:"02-iaas/guides/configuration-guide/commons",slug:"/iaas/guides/configuration-guide/commons/sshconfig",permalink:"/docs/iaas/guides/configuration-guide/commons/sshconfig",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/sshconfig.md",tags:[],version:"current",frontMatter:{sidebar_label:"SSH Config"},sidebar:"docs",previous:{title:"Services",permalink:"/docs/iaas/guides/configuration-guide/commons/services"},next:{title:"Sysctl",permalink:"/docs/iaas/guides/configuration-guide/commons/sysctl"}},l={},c=[{value:"Extra config",id:"extra-config",level:2},{value:"Example",id:"example",level:2},{value:"Defaults",id:"defaults",level:2}];function a(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"ssh-config",children:"SSH Config"}),"\n",(0,n.jsxs)(t.p,{children:["With the ",(0,n.jsx)(t.code,{children:"osism.commons.sshconfig"})," role, it is possible to manage a SSH config\nfile in the home directory of the operator user."]}),"\n",(0,n.jsx)(t.h2,{id:"extra-config",children:"Extra config"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.code,{children:"sshconfig_extra"})," parameter can be used to add any other SSH configuration to the ",(0,n.jsx)(t.code,{children:".ssh/config"})," file."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",children:"sshconfig_extra: |\n Host github.com\n\t ProxyCommand nc -X connect -x :> ssh.github.com 443\n"})}),"\n",(0,n.jsx)(t.h2,{id:"example",children:"Example"}),"\n",(0,n.jsxs)(t.p,{children:["In the ",(0,n.jsx)(t.a,{href:"https://github.com/osism/testbed",children:"testbed"}),"\nthe ",(0,n.jsx)(t.code,{children:"/home/dragon/.ssh/config"})," file is created on the manager node ",(0,n.jsx)(t.code,{children:"testbed-manager"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-none",metastring:'title="Example for an assembled /home/dragon/.ssh/config file"',children:"Host testbed-manager\n HostName testbed-manager.testbed.osism.xyz\n User dragon\n Port 22\n IdentityFile /opt/ansible/secrets/id_rsa.operator\n\n####################\nHost testbed-node-0\n HostName testbed-node-0.testbed.osism.xyz\n User dragon\n Port 22\n IdentityFile /opt/ansible/secrets/id_rsa.operator\n\n####################\nHost testbed-node-1\n HostName testbed-node-1.testbed.osism.xyz\n User dragon\n Port 22\n IdentityFile /opt/ansible/secrets/id_rsa.operator\n\n####################\nHost testbed-node-2\n HostName testbed-node-2.testbed.osism.xyz\n User dragon\n Port 22\n IdentityFile /opt/ansible/secrets/id_rsa.operator\n"})}),"\n",(0,n.jsx)(t.h2,{id:"defaults",children:"Defaults"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Parameter"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Default"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"sshconfig_groupname"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"all"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"All nodes in this group are included."})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"sshconfig_order"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"20"})}),(0,n.jsxs)(t.td,{style:{textAlign:"left"},children:["The ",(0,n.jsx)(t.code,{children:".ssh/config.d"})," directory is used to prepare the ",(0,n.jsx)(t.code,{children:".ssh/config"})," file. You can add your own files in this directory. Everything with a filename prefix smaller than ",(0,n.jsx)(t.code,{children:"sshconfig_order"})," is placed at the beginning of the assembled ",(0,n.jsx)(t.code,{children:".ssh/config"})," file. Anything with a filename prefix greater than ",(0,n.jsx)(t.code,{children:"sshconfig_order"})," goes at the end."]})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"sshconfig_port"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"22"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"The SSH port."})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"sshconfig_private_key_file"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/ansible/secrets/id_rsa.operator"})}),(0,n.jsxs)(t.td,{style:{textAlign:"left"},children:["The identity file to use. The file itself must already exist there. The file is created by the ",(0,n.jsx)(t.code,{children:"osism.services.manager"})," role."]})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"sshconfig_user"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:'"{{ operator_user }}"'})}),(0,n.jsxs)(t.td,{style:{textAlign:"left"},children:["The user in which home directory the ",(0,n.jsx)(t.code,{children:".ssh/config"})," file will be generated."]})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"sshconfig_extra"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:'""'})}),(0,n.jsxs)(t.td,{style:{textAlign:"left"},children:["Add additional SSH configuration to the end of the ",(0,n.jsx)(t.code,{children:".ssh/config"})," file."]})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(a,{...e})}):a(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>r});var n=s(96540);const i={},o=n.createContext(i);function d(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/061d8128.ad00fbf8.js b/assets/js/061d8128.ad00fbf8.js new file mode 100644 index 0000000000..c6a12aa202 --- /dev/null +++ b/assets/js/061d8128.ad00fbf8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1009],{6056:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>d,default:()=>h,frontMatter:()=>t,metadata:()=>o,toc:()=>a});var i=s(74848),r=s(28453);const t={title:"SCS Flavor Naming Standard",type:"Standard",status:"Stable",stabilized_at:new Date("2023-06-14T00:00:00.000Z"),track:"IaaS",replaces:"scs-0100-v2-flavor-naming.md",description:"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack\nenvironments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM,\nand Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for\nusability and portability across all SCS flavors.\n"},d=void 0,o={id:"scs-0100-v3-flavor-naming",title:"SCS Flavor Naming Standard",description:"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack\nenvironments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM,\nand Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for\nusability and portability across all SCS flavors.\n",source:"@site/standards/scs-0100-v3-flavor-naming.md",sourceDirName:".",slug:"/scs-0100-v3-flavor-naming",permalink:"/standards/scs-0100-v3-flavor-naming",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS Flavor Naming Standard",type:"Standard",status:"Stable",stabilized_at:"2023-06-14T00:00:00.000Z",track:"IaaS",replaces:"scs-0100-v2-flavor-naming.md",description:"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack\nenvironments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM,\nand Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for\nusability and portability across all SCS flavors.\n"},sidebar:"standards",previous:{title:"SCS Flavor Naming Standard",permalink:"/standards/scs-0100-v2-flavor-naming"},next:{title:"SCS Flavor Naming Standard: Implementation and Testing Notes",permalink:"/standards/scs-0100-w1-flavor-naming-implementation-testing"}},l={},a=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Type of information included",id:"type-of-information-included",level:3},{value:"Complete Proposal for systematic flavor naming",id:"complete-proposal-for-systematic-flavor-naming",level:2},{value:"Proposal Details",id:"proposal-details",level:2},{value:"[REQUIRED] CPU Suffixes",id:"required-cpu-suffixes",level:3},{value:"Baseline",id:"baseline",level:4},{value:"Higher oversubscription",id:"higher-oversubscription",level:4},{value:"Insufficient microcode",id:"insufficient-microcode",level:4},{value:"Examples",id:"examples",level:4},{value:"[REQUIRED] Memory",id:"required-memory",level:3},{value:"Baseline",id:"baseline-1",level:4},{value:"No ECC",id:"no-ecc",level:4},{value:"Enabled Oversubscription",id:"enabled-oversubscription",level:4},{value:"Examples",id:"examples-1",level:4},{value:"[OPTIONAL] Disk sizes and types",id:"optional-disk-sizes-and-types",level:3},{value:"Baseline",id:"baseline-2",level:4},{value:"Multi-provisioned Disk",id:"multi-provisioned-disk",level:4},{value:"Examples",id:"examples-2",level:4},{value:"Naming policy compliance",id:"naming-policy-compliance",level:2},{value:"Extensions",id:"extensions",level:2},{value:"[OPTIONAL] Hypervisor",id:"optional-hypervisor",level:3},{value:"Examples",id:"examples-3",level:4},{value:"[OPTIONAL] Hardware virtualization / Nested virtualization",id:"optional-hardware-virtualization--nested-virtualization",level:3},{value:"Examples",id:"examples-4",level:4},{value:"[OPTIONAL] CPU Architecture Details",id:"optional-cpu-architecture-details",level:3},{value:"Generation and Vendor",id:"generation-and-vendor",level:4},{value:"Frequency Suffixes",id:"frequency-suffixes",level:4},{value:"Examples",id:"examples-5",level:4},{value:"[OPTIONAL] GPU support",id:"optional-gpu-support",level:3},{value:"[OPTIONAL] Infiniband",id:"optional-infiniband",level:3},{value:"Naming options advice",id:"naming-options-advice",level:3},{value:"Proposal Examples",id:"proposal-examples",level:2},{value:"Previous standard versions",id:"previous-standard-versions",level:2},{value:"Beyond SCS",id:"beyond-scs",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",del:"del",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"This is the standard v3.1 for SCS Release 5.\nNote that we intend to only extend it (so it's always backwards compatible),\nbut try to avoid changing in incompatible ways.\n(See at the end for the v1 to v2 transition where we have not met that\ngoal, but at least managed to have a 1:1 relationship between v1 and v2 names.)"}),"\n",(0,i.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(n.p,{children:"In OpenStack environments there is a need to define different flavors for instances.\nThe flavors are pre-defined by the operator, the customer can not change these.\nOpenStack providers thus typically offer a large selection of flavors."}),"\n",(0,i.jsxs)(n.p,{children:["While flavors can be discovered (",(0,i.jsx)(n.code,{children:"openstack flavor list"}),"), it is helpful for users (DevOps teams),\nto have a naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere."]}),"\n",(0,i.jsx)(n.p,{children:"While not all details will be encoded in the name, the key features should be obvious:\nNumber of vCPUs, RAM, Root Disk.\nExtra features are important as well: There will be flavors with GPU support, fast disks for databases,\nmemory-heavy applications, and other useful aspects of an instance."}),"\n",(0,i.jsx)(n.p,{children:"It may also be important to make the CPU generation clearly recognizable, as this is always a topic in\ndiscussions with customers."}),"\n",(0,i.jsx)(n.p,{children:"Note that not all relevant properties of flavors can be discovered; creating a specification\nto address this is a separate but related effort to the name standardization.\nCommonly used infrastructure-as-code tools do not provide a way to use discoverability\nfeatures to express something like \"I want a flavor with 2 vCPUs, 8GiB of RAM, a local\n20GB SSD disk and Infiniband support but I don't care whether it's AMD or intel\" in a\nreasonable manner. Using flavor names to express this will thus continue to be useful\nand we don't expect the need for standardization of flavor names to go away until\nthe commonly used IaC tools work on a higher abstraction layer than they currently do."}),"\n",(0,i.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsx)(n.h3,{id:"type-of-information-included",children:"Type of information included"}),"\n",(0,i.jsx)(n.p,{children:"From discussions of our operators with their customers we learned that\nthe following characteristics are important in a flavor description:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Type"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Generation"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"CPU Generation"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Number of CPU"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Number of vCPUs - suffixed by L,V,T,C (see below)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Amount of RAM"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Amount of memory available for the VM"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Performance Class"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Ability to label high-performance CPUs, disks, network"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"CPU Type"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"X86-intel, X86-amd, ARM, RISC-V, Generic"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:'"bms"'}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Bare Metal System (no virtualization/hypervisor)"})]})]})]}),"\n",(0,i.jsx)(n.p,{children:"This list is likely not comprehensive and will grow over time."}),"\n",(0,i.jsxs)(n.p,{children:["Rather than using random names ",(0,i.jsx)(n.code,{children:"s5a.medium"})," and assigning a discrete set of properties\nto them, we wanted to come up with a scheme that allows to systematically derive\nnames from properties and vice versa. The scheme allows for short names (by not\nencoding all details) as well as very detailed longer names."]}),"\n",(0,i.jsx)(n.h2,{id:"complete-proposal-for-systematic-flavor-naming",children:"Complete Proposal for systematic flavor naming"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Prefix"}),(0,i.jsx)(n.th,{children:"CPUs & Suffix"}),(0,i.jsx)(n.th,{children:"RAM[GiB]"}),(0,i.jsx)(n.th,{children:"optional: Disk[GB]&type"}),(0,i.jsx)(n.th,{children:"opt: extensions"})]})}),(0,i.jsx)(n.tbody,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"SCS-"})}),(0,i.jsxs)(n.td,{children:["N",(0,i.jsx)(n.code,{children:"L/V/T/C"}),"[",(0,i.jsx)(n.code,{children:"i"}),"]"]}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"-"}),"N[",(0,i.jsx)(n.code,{children:"u"}),"][",(0,i.jsx)(n.code,{children:"o"}),"]"]}),(0,i.jsxs)(n.td,{children:["[",(0,i.jsx)(n.code,{children:"-"}),"[M",(0,i.jsx)(n.code,{children:"x"}),"]N[",(0,i.jsx)(n.code,{children:"n/h/s/p"}),"]]"]}),(0,i.jsxs)(n.td,{children:["[",(0,i.jsx)(n.code,{children:"_"}),"EXT]"]})]})})]}),"\n",(0,i.jsx)(n.p,{children:"Note that N and M are placeholders for numbers here.\nThe optional fields are denoted in brackets (and have opt: in the header.\nSee below for extensions."}),"\n",(0,i.jsx)(n.p,{children:"Note that all letters are case-sensitive."}),"\n",(0,i.jsxs)(n.p,{children:["Typical flavor names look like ",(0,i.jsx)(n.code,{children:"SCS-4V-16-50"})," for a flavor with 4vCPUs (with limited\noversubscription), 16GiB RAM and a 50GB disk (of unspecified type)."]}),"\n",(0,i.jsx)(n.h2,{id:"proposal-details",children:"Proposal Details"}),"\n",(0,i.jsx)(n.h3,{id:"required-cpu-suffixes",children:"[REQUIRED] CPU Suffixes"}),"\n",(0,i.jsx)(n.p,{children:"Next to the number of vCPUs, these vCPUs need to be characterized to describe their nature."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Suffix"}),(0,i.jsx)(n.th,{children:"Meaning"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"C"}),(0,i.jsx)(n.td,{children:"dedicated Core"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"T"}),(0,i.jsx)(n.td,{children:"dedicated Thread (SMT)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V"}),(0,i.jsx)(n.td,{children:"vCPU (oversubscribed)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"L"}),(0,i.jsx)(n.td,{children:"vCPU (heavily oversubscribed)"})]})]})]}),"\n",(0,i.jsx)(n.h4,{id:"baseline",children:"Baseline"}),"\n",(0,i.jsxs)(n.p,{children:["Note that vCPU oversubscription for a ",(0,i.jsx)(n.code,{children:"V"})," vCPU should be implemented such, that we\ncan guarantee ",(0,i.jsx)(n.em,{children:"at least 20% of a core in >99% of the time"}),"; this can be achieved by\nlimiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled)\nor by more advanced workload management logic. Otherwise ",(0,i.jsx)(n.code,{children:"L"})," (low performance) instead\nof ",(0,i.jsx)(n.code,{children:"V"})," must be used. The >99% is measured over a month (1% is 7.2h/month)."]}),"\n",(0,i.jsx)(n.p,{children:"Note that CPUs should use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.).\nIn particular,"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"microcode must be updated within less than a month of a new release; for CVSS scores above 8,\nproviders should do it in less than a week."}),"\n",(0,i.jsx)(n.li,{children:"all mitigations that are enabled by default in the Linux kernel and the KVM hypervisor\nshould be enabled,"}),"\n",(0,i.jsx)(n.li,{children:"CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) should have hyperthreading\ndisabled OR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["That is to say, except when the suffix ",(0,i.jsx)(n.code,{children:"i"})," is used, the provider commits itself to implementing the appropriate mitigations\nif and when they become available, within the timeframes mentioned above."]}),"\n",(0,i.jsxs)(n.p,{children:["If a provider does not want to commit to deploying available microcode fixes and upstream kernel/hypervisor updates within a month or\nif the provider wants to enable hyperthreading on compute hosts despite having CPUs susceptible to L1TF there\n(and no SCS-accepted core-scheduling mechanism is used for mitigation),\nthe flavors must be declared insecure with the ",(0,i.jsx)(n.code,{children:"i"})," suffix (see below)."]}),"\n",(0,i.jsx)(n.h4,{id:"higher-oversubscription",children:"Higher oversubscription"}),"\n",(0,i.jsxs)(n.p,{children:["Must be indicated with a ",(0,i.jsx)(n.code,{children:"L"})," vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and\nthe lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month)."]}),"\n",(0,i.jsx)(n.h4,{id:"insufficient-microcode",children:"Insufficient microcode"}),"\n",(0,i.jsxs)(n.p,{children:["Not using these mitigations must be indicated by an additional ",(0,i.jsx)(n.code,{children:"i"})," suffix for insecure\n(weak protection against CPU vulns through insufficient microcode, lack of disabled hyperthreading\non L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor)."]}),"\n",(0,i.jsx)(n.h4,{id:"examples",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2C"}),"-4-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2T"}),"-4-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2V"}),"-4-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2L"}),"-4-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2Li"}),"-4-10n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2"}),"-**4-10n"]})," - CPU suffix missing"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2iT"}),"-4-10n"]})," - This order is forbidden"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"required-memory",children:"[REQUIRED] Memory"}),"\n",(0,i.jsx)(n.h4,{id:"baseline-1",children:"Baseline"}),"\n",(0,i.jsx)(n.p,{children:"Cloud providers should use ECC memory.\nMemory oversubscription should not be used.\nIt is allowed to specify half GiBs (e.g. 3.5), though this is should not be done for larger memory sizes (>= 10GiB)."}),"\n",(0,i.jsx)(n.h4,{id:"no-ecc",children:"No ECC"}),"\n",(0,i.jsxs)(n.p,{children:["If no ECC is used, the ",(0,i.jsx)(n.code,{children:"u"})," suffix must indicate this."]}),"\n",(0,i.jsx)(n.h4,{id:"enabled-oversubscription",children:"Enabled Oversubscription"}),"\n",(0,i.jsxs)(n.p,{children:["If memory is oversubscribed, you must expose this with the ",(0,i.jsx)(n.code,{children:"o"})," suffix."]}),"\n",(0,i.jsx)(n.h4,{id:"examples-1",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["SCS-2C-",(0,i.jsx)(n.strong,{children:"4"}),"-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-",(0,i.jsx)(n.strong,{children:"3.5"}),"-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-",(0,i.jsx)(n.strong,{children:"4u"}),"-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-",(0,i.jsx)(n.strong,{children:"4o"}),"-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-",(0,i.jsx)(n.strong,{children:"4uo"}),"-10n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-2C-",(0,i.jsx)(n.strong,{children:"4ou"}),"-10n"]})," - This order is forbidden"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-disk-sizes-and-types",children:"[OPTIONAL] Disk sizes and types"}),"\n",(0,i.jsx)(n.p,{children:"Disk sizes (in GB) should use sizes 5, 10, 20, 50, 100, 200, 500, 1000."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Disk type"}),(0,i.jsx)(n.th,{children:"Meaning"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"n"}),(0,i.jsx)(n.td,{children:"Network shared storage (ceph/cinder)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"h"}),(0,i.jsx)(n.td,{children:"Local disk (HDD: SATA/SAS class)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"s"}),(0,i.jsx)(n.td,{children:"Local SSD disk"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"p"}),(0,i.jsx)(n.td,{children:"Local high-perf NVMe"})]})]})]}),"\n",(0,i.jsx)(n.h4,{id:"baseline-2",children:"Baseline"}),"\n",(0,i.jsx)(n.p,{children:"Note that disk type might be omitted \u2014 the user then can not take any assumptions\non what storage is provided for the root disk (that the image gets provisioned to)."}),"\n",(0,i.jsxs)(n.p,{children:["It does make sense for ",(0,i.jsx)(n.code,{children:"n"})," to be requested explicitly to allow for smooth live migration.\n",(0,i.jsx)(n.code,{children:"h"})," typically provides latency advantages vs ",(0,i.jsx)(n.code,{children:"n"})," (but not necessarily bandwidth and\nalso is more likely to fail), ",(0,i.jsx)(n.code,{children:"s"})," and ",(0,i.jsx)(n.code,{children:"p"})," are for applications that need low\nlatency (high IOPS) and bandwidth disk I/O. ",(0,i.jsx)(n.code,{children:"n"})," storage is expected to survive\nsingle-disk and single-node failure."]}),"\n",(0,i.jsxs)(n.p,{children:["For specific requirements on the SSD and NVMe disks regarding IOPS and\npower-loss protection, refer to Decision Record ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0110-v1-ssd-flavors.md",children:"scs-0110-ssd-flavors"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["If the disk size is left out, the cloud is expected to allocate a disk (network or local)\nthat is large enough to fit the root file system (",(0,i.jsx)(n.code,{children:"min_disk"})," in image). This automatic\nallocation is indicated with ",(0,i.jsx)(n.code,{children:"-"})," without a disk size.\nIf the ",(0,i.jsx)(n.code,{children:"-"})," is left out completely, the user must create a boot volume manually and\ntell the instance to boot from it or use the\n",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/api-ref/compute/?expanded=create-server-detail#create-server",children:(0,i.jsx)(n.code,{children:"block_device_mapping_v2"})}),"\nmechanism explicitly to create the boot volume from an image."]}),"\n",(0,i.jsx)(n.h4,{id:"multi-provisioned-disk",children:"Multi-provisioned Disk"}),"\n",(0,i.jsxs)(n.p,{children:["The disk size can be prefixed with ",(0,i.jsx)(n.code,{children:"Mx prefix"}),", where M is an integer specifying that the disk\nis provisioned M times. Multiple disks provided this way should be independent storage media,\nso users can expect some level of parallelism and independence."]}),"\n",(0,i.jsx)(n.h4,{id:"examples-2",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"10n"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"10s"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"10s"}),"_bms_z3"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"3x10s"})," - Cloud creates three 10GB SSDs"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"3x10s"}),"_bms_z3"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"10"})," - Cloud decides disk type"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"10"}),"_bms_z3"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"n"})," - Cloud decides disk size (min_disk from image or larger)"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"n"}),"_bms_3"]}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4- - Cloud decides disk type and size"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-_bms_z3"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-_bms_z3h_GNa-64_ib"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-_ib"}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4 - You need to specify a boot volume yourself (boot from volume, or use ",(0,i.jsx)(n.code,{children:"block_device_mapping_v2"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4_bms_z3"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-3x10 - Cloud decides type and creates three 10GB volumes"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"1.5n"})]})," - You must not specify disk sizes which are not in full GiBs"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"naming-policy-compliance",children:"Naming policy compliance"}),"\n",(0,i.jsx)(n.p,{children:"Every flavor you offer MUST satisfy the following assertion:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["If its name starts with ",(0,i.jsx)(n.code,{children:"SCS-"}),", the name has to conform to the syntax outlined above, and\nthe flavor must ",(0,i.jsx)(n.em,{children:"at least"})," provide the capabilities indicated by the name."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"That is to say:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["You may offer flavors not following the above scheme, as long as the name does not\nstart with ",(0,i.jsx)(n.code,{children:"SCS-"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["You are allowed to understate your performance; for instance, a flavor that satisfies\n",(0,i.jsx)(n.code,{children:"SCS-1C-1.5-8s"})," (1 dedicated core, 1.5 GiB RAM, 8 GiB SSD) may also be named\n",(0,i.jsx)(n.code,{children:"SCS-1T-1-5n"})," (1 dedicated hyperthread, 1 GiB RAM, 5 GiB network volume) or even\n",(0,i.jsx)(n.code,{children:"SCS-1V-1-5"}),". Similarly, you may offer the (v3 mandatory) ",(0,i.jsx)(n.code,{children:"SCS-2V-4-20s"})," with a ",(0,i.jsx)(n.code,{children:"SCS-2V-4-20p"}),"\nimplementation (using a local NVMe instead of an SSD)."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["You must be very careful to expose low vCPU guarantees (",(0,i.jsx)(n.code,{children:"L"})," instead of ",(0,i.jsx)(n.code,{children:"V"}),"), insecure\nhyperthreading/microcode ",(0,i.jsx)(n.code,{children:"i"}),", non-ECC-RAM ",(0,i.jsx)(n.code,{children:"u"}),", memory oversubscription ",(0,i.jsx)(n.code,{children:"o"}),". Note that omitting these qualifiers\nis ",(0,i.jsx)(n.em,{children:"overstating"})," your security, reliability or performance properties and may be reason for\nclients to feel betrayed or claim damages. This would prevent SCS compliance and certification;\nin extreme cases, the SCS project might be forced to work with public statements."]}),"\n",(0,i.jsxs)(n.p,{children:["We expect all cloud providers to offer the short, less specific flavor names (such as ",(0,i.jsx)(n.code,{children:"SCS-8V-32-100"}),").\nLarger providers that offer more details (using the extension below) are expected to still also\noffer the short variants for usability and easier portability, even beyond the mandated flavors."]}),"\n",(0,i.jsx)(n.p,{children:"You must not extend the SCS naming scheme with your own extensions; you are encouraged however\nto suggest extensions that we can discuss and add to the official scheme."}),"\n",(0,i.jsx)(n.h2,{id:"extensions",children:"Extensions"}),"\n",(0,i.jsx)(n.p,{children:"Extensions provide a possibility for providers that offer a very differentiated set\nof flavors to indicate hypervisors, support for hardware/nested virtualization,\nCPU types and generations, high-frequency models, GPU support and GPU types as\nwell as Infiniband support. (More extensions may be appended in the future.)"}),"\n",(0,i.jsx)(n.p,{children:"Using the systematic naming approach ensures that two providers that offer flavors\nwith the same specific features will use the same name for them, thus simplifying\nlife for their customers when consuming these flavors."}),"\n",(0,i.jsxs)(n.p,{children:["Note that there is no need to indicate all details and extra features this way.\nFlavors may always perform better or have more features than indicated in a name.\nUnderperformance (CPU suffixes ",(0,i.jsx)(n.code,{children:"L"})," or ",(0,i.jsx)(n.code,{children:"i"})," or memory suffixes ",(0,i.jsx)(n.code,{children:"o"})," and ",(0,i.jsx)(n.code,{children:"u"}),") on the other\nhand MUST be indicated in the name; this happens rarely in practice."]}),"\n",(0,i.jsx)(n.p,{children:"For smaller providers, the ability to e.g. differentiate between an AMD Milan and an intel\nIceLake and exposed the slightly different feature set to customers and have slightly\ndifferent price points is often not worth the extra effort. This is because having\nthis extra differentiation causes fragmentation of the machines (host aggregates)\nthat can offer these flavors, thus resulting in a lower utilization (as the capacity\nmanagement will need to have a certain amount of headroom per machine pool to avoid\nrunning out of capacity)."}),"\n",(0,i.jsx)(n.p,{children:"Note that it is possible for providers to register both the generic short names and the\nlonger, more detailed names and allow them to use the same set of machines (host aggregates).\nNote that machines (hypervisors) can be part of more than one host aggregate."}),"\n",(0,i.jsx)(n.p,{children:"The extensions have the format:"}),"\n",(0,i.jsxs)(n.p,{children:["[",(0,i.jsx)(n.code,{children:"_"}),"hyp][",(0,i.jsx)(n.code,{children:"_hwv"}),"][",(0,i.jsx)(n.code,{children:"_"}),"arch[N][",(0,i.jsx)(n.code,{children:"h"}),"]][",(0,i.jsx)(n.code,{children:"_"}),"[",(0,i.jsx)(n.code,{children:"G/g"}),"]X[N][",(0,i.jsx)(n.code,{children:"-"}),"M][",(0,i.jsx)(n.code,{children:"h"}),"]][",(0,i.jsx)(n.code,{children:"_ib"}),"]"]}),"\n",(0,i.jsx)(n.p,{children:"Extensions are individually optional, but the ones that are used must appear in the order\ngiven in the above line."}),"\n",(0,i.jsxs)(n.p,{children:["Remember that letters are case-sensitive.\nIn case you wonder: Feature indicators are capitalized, modifiers are lower case.\n(An exception is the uppercase ",(0,i.jsx)(n.code,{children:"_G"})," for a pass-through GPU vs. lowercase ",(0,i.jsx)(n.code,{children:"_g"})," for vGPU.)"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-hypervisor",children:"[OPTIONAL] Hypervisor"}),"\n",(0,i.jsxs)(n.p,{children:["Format: ",(0,i.jsx)(n.code,{children:"_"}),"hyp"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.em,{children:"default Hypervisor"})," is assumed to be ",(0,i.jsx)(n.code,{children:"KVM"}),". Clouds that offer different hypervisors\nor Bare Metal Systems should indicate the Hypervisor according to the following table:"]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"hyp"}),(0,i.jsx)(n.th,{children:"Meaning"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"kvm"}),(0,i.jsx)(n.td,{children:"KVM"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"xen"}),(0,i.jsx)(n.td,{children:"Xen"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"vmw"}),(0,i.jsx)(n.td,{children:"VMware"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"hyv"}),(0,i.jsx)(n.td,{children:"Hyper-V"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"bms"}),(0,i.jsx)(n.td,{children:"Bare Metal System"})]})]})]}),"\n",(0,i.jsx)(n.h4,{id:"examples-3",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-10n"}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,i.jsx)(n.strong,{children:"bms"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,i.jsx)(n.strong,{children:"bms"}),"_z3h"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-hardware-virtualization--nested-virtualization",children:"[OPTIONAL] Hardware virtualization / Nested virtualization"}),"\n",(0,i.jsxs)(n.p,{children:["Format: ",(0,i.jsx)(n.code,{children:"_hwv"})]}),"\n",(0,i.jsxs)(n.p,{children:["If the instances that are created with this flavor support hardware-accelerated\nvirtualization, this can be reflected with the ",(0,i.jsx)(n.code,{children:"_hwv"})," flag (after the optional\nHypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel)\nor svm (AMD) is available. This will be the case on Bare Metal flavors on almost\nall non-ancient x86 CPUs or if your virtualization hypervisor is configured to\nsupport nested virtualization.\nFlavors without the ",(0,i.jsx)(n.code,{children:"_hwv"})," flag may or may not support hardware virtualization (as we\nrecommend enabling nesting, but don't require flavor names to reflect all\ncapabilities. Flavors may over-deliver ...)"]}),"\n",(0,i.jsx)(n.h4,{id:"examples-4",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-10 - may or may not support HW virtualization in VMs"}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10_kvm_",(0,i.jsx)(n.strong,{children:"hwv"})," - kvm with enabled nested virtualization"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10_",(0,i.jsx)(n.strong,{children:"hwv"})," - not recommended, but allowed"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10_bms_",(0,i.jsx)(n.strong,{children:"hwv"})," - better: bare metal with HW virt support (VMX on intel, SVM on AMD, ...)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-2C-4-10_",(0,i.jsx)(n.strong,{children:"hwv"}),"_xen"]})," - illegal, wrong ordering"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-cpu-architecture-details",children:"[OPTIONAL] CPU Architecture Details"}),"\n",(0,i.jsxs)(n.p,{children:["Format: ",(0,i.jsx)(n.code,{children:"_"}),"arch[N][",(0,i.jsx)(n.code,{children:"h"}),"]"]}),"\n",(0,i.jsx)(n.p,{children:"This extension provides more details on the specific CPU:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"vendor/architecture (arch)"}),"\n",(0,i.jsx)(n.li,{children:"generation (N)"}),"\n",(0,i.jsx)(n.li,{children:"frequency (h)"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"generation-and-vendor",children:"Generation and Vendor"}),"\n",(0,i.jsx)(n.p,{children:"The options for arch are as follows:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Letter"}),(0,i.jsx)(n.th,{children:"vendor/architecture"}),(0,i.jsx)(n.th,{children:"Corresponding image architecture"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"(none)"}),(0,i.jsx)(n.td,{children:"Generic x86-64"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"x86_64"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"i"})}),(0,i.jsx)(n.td,{children:"Intel x86-64"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"x86_64"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"z"})}),(0,i.jsx)(n.td,{children:"AMD (Zen) x86-64"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"x86_64"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"a"})}),(0,i.jsx)(n.td,{children:"ARM v8+"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"aarch64"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"r"})}),(0,i.jsx)(n.td,{children:"RISC-V"}),(0,i.jsx)(n.td,{children:"(not yet listed in Glance)"})]})]})]}),"\n",(0,i.jsx)(n.p,{children:"The generation is vendor specific and can be left out, but it can only be specified in\nconjunction with a vendor. At present, these values are possible:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Generation"}),(0,i.jsx)(n.th,{children:"i (Intel x86-64)"}),(0,i.jsx)(n.th,{children:"z (AMD x86-64)"}),(0,i.jsx)(n.th,{children:"\xa0a (AArch64)"}),(0,i.jsx)(n.th,{children:"r (RISC-V)"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"0"}),(0,i.jsx)(n.td,{children:"pre Skylake"}),(0,i.jsx)(n.td,{children:"pre Zen"}),(0,i.jsx)(n.td,{children:"pre Cortex A76"}),(0,i.jsx)(n.td,{children:"TBD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"1"}),(0,i.jsx)(n.td,{children:"Skylake"}),(0,i.jsx)(n.td,{children:"Zen-1 (Naples)"}),(0,i.jsx)(n.td,{children:"A76/NeoN1 class"}),(0,i.jsx)(n.td,{children:"TBD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"2"}),(0,i.jsx)(n.td,{children:"Cascade Lake"}),(0,i.jsx)(n.td,{children:"Zen-2 (Rome)"}),(0,i.jsx)(n.td,{children:"A78/x1/NeoV1 class"}),(0,i.jsx)(n.td,{children:"TBD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"3"}),(0,i.jsx)(n.td,{children:"Ice Lake"}),(0,i.jsx)(n.td,{children:"Zen-3 (Milan)"}),(0,i.jsx)(n.td,{children:"A71x/NeoN2 (ARMv9)"}),(0,i.jsx)(n.td,{children:"TBD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"4"}),(0,i.jsx)(n.td,{children:"Sapphire Rapids"}),(0,i.jsx)(n.td,{children:"Zen-4 (Genoa)"}),(0,i.jsx)(n.td,{}),(0,i.jsx)(n.td,{children:"TBD"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["It is recommended to leave out the ",(0,i.jsx)(n.code,{children:"0"}),' when specifying the old generation; this will\nhelp the parser tool, which assumes 0 for an unspecified value and does leave it\nout when generating the name for comparison. In other words: 0 has a meaning of\n"rather old or unspecified".']}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["We don't differentiate between Zen-4 (Genoa) and Zen-4c (Bergamo); L3 cache per\nSiena core is smaller on Bergamo and the frequency lower but the cores are otherwise\nidentical. As we already have a qualifier ",(0,i.jsx)(n.code,{children:"h"})," that allows to specify higher frequencies\n(which Genoa thus may use more and Bergamo less or not), we have enough distinction\ncapabilities."]})}),"\n",(0,i.jsx)(n.h4,{id:"frequency-suffixes",children:"Frequency Suffixes"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Suffix"}),(0,i.jsx)(n.th,{children:"Meaning"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"h"}),(0,i.jsx)(n.td,{children:">2.75GHz all-core"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"hh"}),(0,i.jsx)(n.td,{children:">3.25GHz all-core"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"hhh"}),(0,i.jsx)(n.td,{children:">3.75GHz all-core"})]})]})]}),"\n",(0,i.jsx)(n.h4,{id:"examples-5",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-10n"}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,i.jsx)(n.strong,{children:"z"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,i.jsx)(n.strong,{children:"z3"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,i.jsx)(n.strong,{children:"z3h"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,i.jsx)(n.strong,{children:"z3hh"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,i.jsx)(n.strong,{children:"z"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,i.jsx)(n.strong,{children:"z3"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,i.jsx)(n.strong,{children:"z3"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,i.jsx)(n.strong,{children:"z3h"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,i.jsx)(n.strong,{children:"z3hh"})," - Bare Metal, AMD Milan with > 3.25GHz all core freq"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-gpu-support",children:"[OPTIONAL] GPU support"}),"\n",(0,i.jsxs)(n.p,{children:["Format: ",(0,i.jsx)(n.code,{children:"_"}),"[",(0,i.jsx)(n.code,{children:"G/g"}),"]X[N][",(0,i.jsx)(n.code,{children:"-"}),"M][",(0,i.jsx)(n.code,{children:"h"}),"]"]}),"\n",(0,i.jsx)(n.p,{children:"This extension provides more details on the specific GPU:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["pass-through (",(0,i.jsx)(n.code,{children:"G"}),") vs. virtual GPU (",(0,i.jsx)(n.code,{children:"g"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"vendor (X)"}),"\n",(0,i.jsx)(n.li,{children:"generation (N)"}),"\n",(0,i.jsx)(n.li,{children:"number (M) of processing units that are exposed (for pass-through) or assigned; see table below for vendor-specific terminology"}),"\n",(0,i.jsxs)(n.li,{children:["high-performance indicator (",(0,i.jsx)(n.code,{children:"h"}),")"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Note that the vendor letter X is mandatory, generation and processing units are optional."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"letter X"}),(0,i.jsx)(n.th,{children:"vendor"}),(0,i.jsx)(n.th,{children:"processing units"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"N"})}),(0,i.jsx)(n.td,{children:"nVidia"}),(0,i.jsx)(n.td,{children:"streaming multiprocessors (SMs)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"A"})}),(0,i.jsx)(n.td,{children:"AMD"}),(0,i.jsx)(n.td,{children:"compute units (CUs)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"I"})}),(0,i.jsx)(n.td,{children:"Intel"}),(0,i.jsx)(n.td,{children:"execution units (EUs)"})]})]})]}),"\n",(0,i.jsx)(n.p,{children:"For nVidia, the generation N can be f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, l=Ada Lovelace, ...,\nfor AMD GCN-x=0.x, RDNA1=1, RDNA2=2, RDNA3=3,\nfor Intel Gen9=0.9, Xe(12.1)=1, ...\n(Note: This may need further work to properly reflect what's out there.)"}),"\n",(0,i.jsxs)(n.p,{children:["The optional ",(0,i.jsx)(n.code,{children:"h"})," suffix to the compute unit count indicates high-performance (e.g. high freq or special\nhigh bandwidth gfx memory such as HBM);\n",(0,i.jsx)(n.code,{children:"h"})," can be duplicated for even higher performance."]}),"\n",(0,i.jsxs)(n.p,{children:["Example: ",(0,i.jsx)(n.code,{children:"SCS-16V-64-500s_GNa-14h"}),"\nThis flavor has a pass-through GPU nVidia Ampere with 14 SMs and either high-bandwidth memory or specially high frequencies.\nLooking through GPU specs you could guess it's 1/4 of an A30."]}),"\n",(0,i.jsx)(n.h3,{id:"optional-infiniband",children:"[OPTIONAL] Infiniband"}),"\n",(0,i.jsxs)(n.p,{children:["Format: ",(0,i.jsx)(n.code,{children:"_ib"})]}),"\n",(0,i.jsx)(n.p,{children:"This extension indicates Infiniband networking."}),"\n",(0,i.jsx)(n.p,{children:"More extensions may be forthcoming and appended in a later revision of this spec."}),"\n",(0,i.jsx)(n.p,{children:"Extensions need to be specified in the above-mentioned order."}),"\n",(0,i.jsx)(n.h3,{id:"naming-options-advice",children:"Naming options advice"}),"\n",(0,i.jsx)(n.p,{children:"Note that we expect most clouds to prefer short flavor names,\nnot indicating CPU details or hypervisor types. See above list\nof standard flavors to get a feeling."}),"\n",(0,i.jsxs)(n.p,{children:["However, more successful providers will often need to differentiate their\nofferings in response to customer demand and allow customers to request\nflavors with specific detailed properties. The goal of this proposal is to avoid\nproviders to invent their own names and then refer customers to (currently\nincompletely standardized) ",(0,i.jsx)(n.code,{children:"extra_specs"}),"\nor worse a non-machine-readable service descriptions to find out the details."]}),"\n",(0,i.jsxs)(n.p,{children:["So a cloud provider might well evolve from offering ",(0,i.jsx)(n.code,{children:"SCS-8T-16-50"})," to offering\n",(0,i.jsx)(n.code,{children:"SCS-8T-16-50n"}),", ",(0,i.jsx)(n.code,{children:"SCS-8T-16-50n_i2"})," and ",(0,i.jsx)(n.code,{children:"SCS-8T-16-50n_z2"})," to specify that he\nis using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome.\nWe would expect the cloud provider to still offer the generic flavor\n",(0,i.jsx)(n.code,{children:"SCS-8T-16-50"})," and allow the scheduler (placement service) to pick both more\nspecific types (or just one if e.g. capacity management considerations suggest\nso). Providers in such cases should ensure that the price of a requested\nflavor does not depend on the scheduler decisions."]}),"\n",(0,i.jsxs)(n.p,{children:["We are looking into the ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/image-guide/introduction.html#metadata-definition-metadefs-service",children:"metadefs"}),"\nmechanism and ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/api-guide/compute/extra_specs_and_properties.html",children:"extra_specs"}),"\nto allow customers to ask for specific flavor properties without the need to\nencode all these flavor details into the flavor name, so the optional pieces\nmay not be needed much. However, there must be a way to request flavor\nproperties without encoding the need into an image \u2014 the indirection via\nan image is considered broken by the SCS team."]}),"\n",(0,i.jsx)(n.h2,{id:"proposal-examples",children:"Proposal Examples"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Example"}),(0,i.jsx)(n.th,{children:"Decoding"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-2C-4-10n"}),(0,i.jsx)(n.td,{children:"2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-8Ti-32-50p_i1"}),(0,i.jsx)(n.td,{children:"8 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-1L-1u-5"}),(0,i.jsx)(n.td,{children:"1 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-16T-64-200s_GNa-64_ib"}),(0,i.jsx)(n.td,{children:"16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 64 Passthrough nVidia Ampere SMs"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-4C-16-2x200p_a1"}),(0,i.jsx)(n.td,{children:"4 dedicated Arm64 cores (A76 class), 16GiB RAM, 2x200GB local NVMe drives"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-1V-0.5"}),(0,i.jsx)(n.td,{children:"1 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"previous-standard-versions",children:"Previous standard versions"}),"\n",(0,i.jsxs)(n.p,{children:["Previous versions up to version 3.0 contained the list of\nmandatory/recommended flavors, which has been moved to\n",(0,i.jsx)(n.a,{href:"/standards/scs-0103-v1-standard-flavors",children:"a standard of its own"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"/standards/scs-0100-v1-flavor-naming",children:"Version 1 of the standard"}),"\nused a slightly different naming syntax while the logic was exactly the same.\nWhat is a ",(0,i.jsx)(n.code,{children:"-"})," in v2 used to be a ",(0,i.jsx)(n.code,{children:":"}),"; ",(0,i.jsx)(n.code,{children:"_"})," used to be ",(0,i.jsx)(n.code,{children:"-"}),". The reason for\nthe change was certain Kubernetes tools using the flavor names as labels.\nLabels however are subject to stricter naming rules and in particular don't\nallow for a ",(0,i.jsx)(n.code,{children:":"}),". See ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/issues/190",children:"PR #190"}),"\nfor a discussion."]}),"\n",(0,i.jsx)(n.p,{children:"Version 1 flavor names can be translated to v2 using the following transformation:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"NAMEV2=$(echo \"$NAMEV1\" | sed -e 's/\\-/_/g' -e 's/:/-/g' -e 's/^SCS_/SCS-/')\n"})}),"\n",(0,i.jsx)(n.p,{children:"and the way back can be done with"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"NAMEV1=$(echo \"$NAMEV2\" | sed -e 's/\\-/:/g' -e 's/_/-/g' -e 's/^SCS:/SCS-/')\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For the time being, the validation tools still accept the old names with a warning\n(despite the unchanged ",(0,i.jsx)(n.code,{children:"SCS-"})," prefix) unless you pass option ",(0,i.jsx)(n.code,{children:"-2"})," to them. They will\nhowever not count v1 flavors towards fulfilling the needs against the corresponding\nv2 mandatory flavor list unless you pass the option ",(0,i.jsx)(n.code,{children:"-1"}),".\nIn other words: An IaaS infrastructure with the 26\nv1 mandatory flavors will produce 26 warnings (for using old flavors) and 26\nerrors (for missing the 26 mandatory v2 flavors) unless you pass ",(0,i.jsx)(n.code,{children:"-1"})," in which\ncase no errors and no warnings will be produced. Registering the 26 mandatory\nv2 flavor names in addition will result in passing the test with only 26\nwarnings \u2014 unless you specify ",(0,i.jsx)(n.code,{children:"-2"}),". If you do and want to pass you'll need\nto remove the old v1 names or rename them to no longer start with ",(0,i.jsx)(n.code,{children:"SCS-"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"beyond-scs",children:"Beyond SCS"}),"\n",(0,i.jsx)(n.p,{children:"The Gaia-X provider working group which could have created a superseding standard\ndoes no longer exist."}),"\n",(0,i.jsx)(n.p,{children:"However, we have been reaching out to the OpenStack Public Cloud SIG and the ALASCA\nmembers to seek further alignment."}),"\n",(0,i.jsx)(n.p,{children:"Getting upstream OpenStack support for flavor aliases would provide more flexibility\nand ease migrations between providers, also providers that don't offer the SCS-\nflavors."}),"\n",(0,i.jsxs)(n.p,{children:["We also would like to see upstream ",(0,i.jsx)(n.code,{children:"extra_specs"})," standardizing the discoverability of some\nproperties exposed via the SCS names and work on IaC tooling (terraform ...)\nto make use of these when selecting a flavor."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>o});var i=s(96540);const r={},t=i.createContext(r);function d(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/066abe51.ac412564.js b/assets/js/066abe51.ac412564.js new file mode 100644 index 0000000000..500a8e4701 --- /dev/null +++ b/assets/js/066abe51.ac412564.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1351],{25401:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>m,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var o=i(74848),t=i(28453);const c={},s="SONiC & OVN",a={id:"iaas/guides/concept-guide/components/sonic",title:"SONiC & OVN",description:"Lifecycle Management of SONiC in OSISM",source:"@site/docs/02-iaas/guides/concept-guide/components/sonic.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/sonic",permalink:"/docs/iaas/guides/concept-guide/components/sonic",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/sonic.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Proxmox VE",permalink:"/docs/iaas/guides/concept-guide/components/proxmox"},next:{title:"Teleport",permalink:"/docs/iaas/guides/concept-guide/components/teleport"}},r={},l=[{value:"## Lifecycle Management of SONiC in OSISM",id:"-lifecycle-management-of-sonic-in-osism",level:2},{value:"## Lifecycle Management of Open Virtual Network (OVN) in OSISM",id:"-lifecycle-management-of-open-virtual-network-ovn-in-osism",level:2},{value:"## Lifecycle Management of Open vSwitch (OVS) in OSISM",id:"-lifecycle-management-of-open-vswitch-ovs-in-osism",level:2}];function d(e){const n={h1:"h1",h2:"h2",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"sonic--ovn",children:"SONiC & OVN"}),"\n",(0,o.jsx)(n.h2,{id:"-lifecycle-management-of-sonic-in-osism",children:"## Lifecycle Management of SONiC in OSISM"}),"\n",(0,o.jsx)(n.h2,{id:"-lifecycle-management-of-open-virtual-network-ovn-in-osism",children:"## Lifecycle Management of Open Virtual Network (OVN) in OSISM"}),"\n",(0,o.jsx)(n.h2,{id:"-lifecycle-management-of-open-vswitch-ovs-in-osism",children:"## Lifecycle Management of Open vSwitch (OVS) in OSISM"})]})}function m(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>s,x:()=>a});var o=i(96540);const t={},c=o.createContext(t);function s(e){const n=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),o.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0683500c.5562918c.js b/assets/js/0683500c.5562918c.js new file mode 100644 index 0000000000..8e20302de3 --- /dev/null +++ b/assets/js/0683500c.5562918c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9866],{19378:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>p,frontMatter:()=>c,metadata:()=>s,toc:()=>d});var o=n(74848),r=n(28453);const c={},a="Application Credentials",s={id:"container/components/k8s-cluster-api-provider/doc/application-credentials",title:"Application Credentials",description:"OpenTofu creates an application credential that it passes into the created VM. This one is then used to authenticate the cluster API provider against the OpenStack API to allow it to create resources needed for the k8s cluster.",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/application-credentials.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc",slug:"/container/components/k8s-cluster-api-provider/doc/application-credentials",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/application-credentials",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/application-credentials.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Makefile reference",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/make-reference"},next:{title:"Configuration",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/configuration"}},i={},d=[];function l(e){const t={a:"a",code:"code",h1:"h1",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"application-credentials",children:"Application Credentials"}),"\n",(0,o.jsxs)(t.p,{children:["OpenTofu creates an ",(0,o.jsx)(t.a,{href:"https://docs.openstack.org/keystone/wallaby/user/application_credentials.html",children:"application credential"})," that it passes into the created VM. This one is then used to authenticate the cluster API provider against the OpenStack API to allow it to create resources needed for the k8s cluster."]}),"\n",(0,o.jsx)(t.p,{children:"The AppCredential has a few advantages:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"We take out variance in how the authentication works -- we don't have to deal with a mixture of project_id, project_name, project_domain_name, user_domain_name, only a subset of which is needed depending on the cloud."}),"\n",(0,o.jsx)(t.li,{children:"We do not leak the user credentials into the cluster, making any security breach easier to contain."}),"\n",(0,o.jsx)(t.li,{children:"AppCreds are connected to one project and can be revoked."}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"We are using an unrestricted AppCred for the management server which can then create further AppCreds, so we can each cluster its own (restricted) credentials. In the case of breaches, these AppCreds can be revoked."}),"\n",(0,o.jsxs)(t.p,{children:["Note that you can have additional projects or clouds listed in your ",(0,o.jsx)(t.code,{children:"~/.config/openstack/clouds.yaml"})," (and ",(0,o.jsx)(t.code,{children:"secure.yaml"}),") and reference them in the ",(0,o.jsx)(t.code,{children:"OPENSTACK_CLOUD"})," setting of your ",(0,o.jsx)(t.code,{children:"clusterctl.yaml"}),", so you can manage clusters in various projects and clouds from the same management server."]})]})}function p(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>s});var o=n(96540);const r={},c=o.createContext(r);function a(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/070e71f0.abcbc390.js b/assets/js/070e71f0.abcbc390.js new file mode 100644 index 0000000000..72fb4a41bd --- /dev/null +++ b/assets/js/070e71f0.abcbc390.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7255],{32966:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>a,contentTitle:()=>o,default:()=>p,frontMatter:()=>r,metadata:()=>d,toc:()=>c});var s=i(74848),n=i(28453);const r={sidebar_label:"Ceph",sidebar_position:20},o="Ceph",d={id:"iaas/guides/upgrade-guide/ceph",title:"Ceph",description:"",source:"@site/docs/02-iaas/guides/upgrade-guide/ceph.md",sourceDirName:"02-iaas/guides/upgrade-guide",slug:"/iaas/guides/upgrade-guide/ceph",permalink:"/docs/iaas/guides/upgrade-guide/ceph",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/ceph.md",tags:[],version:"current",sidebarPosition:20,frontMatter:{sidebar_label:"Ceph",sidebar_position:20},sidebar:"docs",previous:{title:"Network",permalink:"/docs/iaas/guides/upgrade-guide/network"},next:{title:"Docker",permalink:"/docs/iaas/guides/upgrade-guide/docker"}},a={},c=[];function u(e){const t={code:"code",h1:"h1",pre:"pre",...(0,n.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"ceph",children:"Ceph"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{children:"osism apply ceph-rolling_update -e ireallymeanit=yes\nosism apply cephclient\n"})})]})}function p(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>o,x:()=>d});var s=i(96540);const n={},r=s.createContext(n);function o(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/07d3bac7.95a25b7b.js b/assets/js/07d3bac7.95a25b7b.js new file mode 100644 index 0000000000..c9f9c76c19 --- /dev/null +++ b/assets/js/07d3bac7.95a25b7b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[458],{16775:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var a=t(74848),n=t(28453);const r={title:"SCS KaaS default storage class",type:"Standard",status:"Stable",stabilized_at:new Date("2023-02-13T00:00:00.000Z"),track:"KaaS",description:'The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).\nThe standard ensures that the default StorageClass, identified by the "storageclass.kubernetes.io/is-default-class"\nannotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or\nhost hardware failures.\n'},o=void 0,i={id:"scs-0211-v1-kaas-default-storage-class",title:"SCS KaaS default storage class",description:'The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).\nThe standard ensures that the default StorageClass, identified by the "storageclass.kubernetes.io/is-default-class"\nannotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or\nhost hardware failures.\n',source:"@site/standards/scs-0211-v1-kaas-default-storage-class.md",sourceDirName:".",slug:"/scs-0211-v1-kaas-default-storage-class",permalink:"/standards/scs-0211-v1-kaas-default-storage-class",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS KaaS default storage class",type:"Standard",status:"Stable",stabilized_at:"2023-02-13T00:00:00.000Z",track:"KaaS",description:'The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).\nThe standard ensures that the default StorageClass, identified by the "storageclass.kubernetes.io/is-default-class"\nannotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or\nhost hardware failures.\n'},sidebar:"standards",previous:{title:"scs-0211: SCS KaaS default storage class",permalink:"/standards/kaas/scs-0211"},next:{title:"scs-0212: Requirements for container registries",permalink:"/standards/kaas/scs-0212"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Decision",id:"decision",level:2},{value:"Required non-performance-related properties",id:"required-non-performance-related-properties",level:3},{value:"Required performance-related properties",id:"required-performance-related-properties",level:3},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const s={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,n.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(s.h2,{id:"introduction",children:"Introduction"}),"\n",(0,a.jsxs)(s.p,{children:["Cluster consumers can request persistent storage via ",(0,a.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims",children:(0,a.jsx)(s.code,{children:"PersistentVolumeClaims"})})," which is provisioned automatically by cloud-provided automation.\nStorage requirements may vary across use cases, so there is the concept of ",(0,a.jsx)(s.code,{children:"StorageClasses"}),". ",(0,a.jsx)(s.code,{children:"StorageClasses"})," define some set of storage properties. So, consumers can choose one of these depending on the use case."]}),"\n",(0,a.jsx)(s.p,{children:(0,a.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/",children:"Kubernetes documentation"})}),"\n",(0,a.jsx)(s.h2,{id:"motivation",children:"Motivation"}),"\n",(0,a.jsxs)(s.p,{children:["While often times, consumers will choose a ",(0,a.jsx)(s.code,{children:"StorageClass"})," explicitly, usually, there is also a default ",(0,a.jsx)(s.code,{children:"StorageClass"})," to fall back on in case it is ",(0,a.jsx)(s.em,{children:"not"})," chosen explicitly (that is, when ",(0,a.jsx)(s.code,{children:"storageClassName"})," is not set on the ",(0,a.jsx)(s.code,{children:"PersistentVolumeClaim"}),")."]}),"\n",(0,a.jsxs)(s.p,{children:["This document attempts to define the properties this default ",(0,a.jsx)(s.code,{children:"StorageClass"})," should have."]}),"\n",(0,a.jsx)(s.h2,{id:"decision",children:"Decision"}),"\n",(0,a.jsxs)(s.p,{children:["The default ",(0,a.jsx)(s.code,{children:"StorageClass"})," is made default using the ",(0,a.jsx)(s.code,{children:"storageclass.kubernetes.io/is-default-class"})," annotation, following ",(0,a.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/",children:"Kubernetes upstream"}),". Hence, standardizing its name is not required for the intents of this standard."]}),"\n",(0,a.jsx)(s.h3,{id:"required-non-performance-related-properties",children:"Required non-performance-related properties"}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsxs)(s.li,{children:[(0,a.jsx)(s.code,{children:"ReadWriteOnce"})," must be a supported ",(0,a.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes",children:"access mode"})]}),"\n",(0,a.jsx)(s.li,{children:"volume must be protected against data loss due to hardware failures of a single disk or host"}),"\n",(0,a.jsx)(s.li,{children:"volume must not be bound to the lifecycle of a Kubernetes Node"}),"\n"]}),"\n",(0,a.jsx)(s.p,{children:"Hence,"}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsx)(s.li,{children:"...volume must not be backed by local storage on the Kubernetes Node VM itself"}),"\n",(0,a.jsx)(s.li,{children:"...volume may be backed by some kind of redundant storage within an AZ, across hosts"}),"\n",(0,a.jsx)(s.li,{children:"...volume may be backed by some kind of redundant storage across AZ's"}),"\n"]}),"\n",(0,a.jsx)(s.h3,{id:"required-performance-related-properties",children:"Required performance-related properties"}),"\n",(0,a.jsxs)(s.ul,{children:["\n",(0,a.jsxs)(s.li,{children:[(0,a.jsx)(s.em,{children:"NO"})," fixed guarantees regarding latency/bandwidth/IOPS/..."]}),"\n"]}),"\n",(0,a.jsx)(s.p,{children:"Generally, customers should be able to expect low-tier performance without pricing surprises."}),"\n",(0,a.jsx)(s.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,a.jsx)(s.p,{children:"This document does not describe performance related properties.\nThis will be done in another document which is yet to be created."}),"\n",(0,a.jsx)(s.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,a.jsx)(s.p,{children:"TBD"})]})}function u(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,a.jsx)(s,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>o,x:()=>i});var a=t(96540);const n={},r=a.createContext(n);function o(e){const s=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/08602342.06e535ee.js b/assets/js/08602342.06e535ee.js new file mode 100644 index 0000000000..bde2ca6c17 --- /dev/null +++ b/assets/js/08602342.06e535ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[550],{82866:e=>{e.exports=JSON.parse('{"title":"Container Registry","slug":"/category/container-registry","permalink":"/docs/category/container-registry","navigation":{"previous":{"title":"Developer Guide","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop"},"next":{"title":"Quickstart","permalink":"/docs/container/components/container-registry/docs/quickstart"}}}')}}]); \ No newline at end of file diff --git a/assets/js/093291a8.3c7f3f62.js b/assets/js/093291a8.3c7f3f62.js new file mode 100644 index 0000000000..974be9eaa9 --- /dev/null +++ b/assets/js/093291a8.3c7f3f62.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1276],{760:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>o,contentTitle:()=>d,default:()=>p,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var n=t(74848),r=t(28453);const a={},d="scs-0411: Push-based approach for providing usage data",c={id:"ops/scs-0411",title:"scs-0411: Push-based approach for providing usage data",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/ops/scs-0411.md",sourceDirName:"ops",slug:"/ops/scs-0411",permalink:"/standards/ops/scs-0411",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Gnocchi as database for metering",permalink:"/standards/scs-0410-v1-gnocchi-as-metering-database"},next:{title:"Push-based approach for providing usage data",permalink:"/standards/scs-0411-v1-publishing_method_for_metering_data"}},o={},i=[];function h(e){const s={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"scs-0411-push-based-approach-for-providing-usage-data",children:"scs-0411: Push-based approach for providing usage data"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Version"}),(0,n.jsx)(s.th,{children:"Type"}),(0,n.jsx)(s.th,{children:"State"}),(0,n.jsx)(s.th,{children:"stabilized"}),(0,n.jsx)(s.th,{children:"deprecated"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0411-v1-publishing_method_for_metering_data",children:"scs-0411-v1"})}),(0,n.jsx)(s.td,{children:"Decision Record"}),(0,n.jsx)(s.td,{children:"Draft"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]})})]})]})}function p(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>d,x:()=>c});var n=t(96540);const r={},a=n.createContext(r);function d(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/096c51c8.35280a0c.js b/assets/js/096c51c8.35280a0c.js new file mode 100644 index 0000000000..d122d4734a --- /dev/null +++ b/assets/js/096c51c8.35280a0c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2544],{14886:(n,e,i)=>{i.r(e),i.d(e,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var t=i(74848),r=i(28453);const o={},l="Linting Guide",s={id:"contribute/linting-guide",title:"Linting Guide",description:"In order to have a clean content repository regarding all markdown files we enforce linting on:",source:"@site/community/contribute/linting-guide.md",sourceDirName:"contribute",slug:"/contribute/linting-guide",permalink:"/community/contribute/linting-guide",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Documentation workflow explanation",permalink:"/community/contribute/docs-workflow-explanation"},next:{title:"Installation",permalink:"/community/contribute/local-docusaurus-development-guide"}},c={},d=[{value:"Pre Commit",id:"pre-commit",level:2},{value:"Github Workflows",id:"github-workflows",level:2}];function a(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",...(0,r.R)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h1,{id:"linting-guide",children:"Linting Guide"}),"\n",(0,t.jsx)(e.p,{children:"In order to have a clean content repository regarding all markdown files we enforce linting on:"}),"\n",(0,t.jsxs)(e.ol,{children:["\n",(0,t.jsx)(e.li,{children:"all staged files prior committing"}),"\n",(0,t.jsx)(e.li,{children:"all Pull Requests"}),"\n"]}),"\n",(0,t.jsx)(e.h2,{id:"pre-commit",children:"Pre Commit"}),"\n",(0,t.jsx)(e.p,{children:"Run markdownlint against staged git files with Husky git hook:"}),"\n",(0,t.jsxs)(e.ol,{children:["\n",(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:"https://github.com/okonet/lint-staged",children:"lint-staged"})}),"\n",(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:"https://github.com/typicode/husky",children:"husky"})}),"\n"]}),"\n",(0,t.jsx)(e.p,{children:"The rules are enforced on markdown files, for which we use:"}),"\n",(0,t.jsxs)(e.ol,{children:["\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.a,{href:"https://github.com/DavidAnson/markdownlint-cli2",children:"markdownlint-cli2"})," for markdownlint"]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.a,{href:"https://github.com/prettier/prettier",children:"prettier"})," for code formatting"]}),"\n"]}),"\n",(0,t.jsxs)(e.p,{children:["The markdownlint rules are defined in the configuration file ",(0,t.jsx)(e.code,{children:".markdownlint-cli2.jsonc"})]}),"\n",(0,t.jsxs)(e.p,{children:["Additionally we use ",(0,t.jsx)(e.a,{href:"https://github.com/OnkarRuikar/markdownlint-rule-search-replace",children:"markdownlint-rule-search-replace"})," for fixing"]}),"\n",(0,t.jsx)(e.h2,{id:"github-workflows",children:"Github Workflows"}),"\n",(0,t.jsxs)(e.p,{children:["There are two actions running on every Pull Request on the ",(0,t.jsx)(e.code,{children:"main"})," branch."]}),"\n",(0,t.jsxs)(e.ol,{children:["\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:"link-validator.yml"}),"is checking every link in markdown files."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:"pr-markdownlint.yml"}),"is checking all markdown files regarding to the rules defined within ",(0,t.jsx)(e.code,{children:".markdownlint-cli2.jsonc"})]}),"\n"]})]})}function h(n={}){const{wrapper:e}={...(0,r.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(a,{...n})}):a(n)}},28453:(n,e,i)=>{i.d(e,{R:()=>l,x:()=>s});var t=i(96540);const r={},o=t.createContext(r);function l(n){const e=t.useContext(o);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function s(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(r):n.components||r:l(n.components),t.createElement(o.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/09adb968.8b72dde4.js b/assets/js/09adb968.8b72dde4.js new file mode 100644 index 0000000000..117172797c --- /dev/null +++ b/assets/js/09adb968.8b72dde4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6148],{38170:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var i=t(74848),o=t(28453);const s={},c="Overview",r={id:"operating-scs/incident-management/index",title:"Overview",description:"TODO",source:"@site/docs/04-operating-scs/03-incident-management/index.md",sourceDirName:"04-operating-scs/03-incident-management",slug:"/operating-scs/incident-management/",permalink:"/docs/operating-scs/incident-management/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/03-incident-management/index.md",tags:[],version:"current",frontMatter:{}},a={},d=[];function m(e){const n={h1:"h1",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(n.p,{children:"TODO"})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(m,{...e})}):m(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>r});var i=t(96540);const o={},s=i.createContext(o);function c(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/09ba26e2.743ba604.js b/assets/js/09ba26e2.743ba604.js new file mode 100644 index 0000000000..37ea28349b --- /dev/null +++ b/assets/js/09ba26e2.743ba604.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9244],{52181:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>t,metadata:()=>d,toc:()=>c});var s=n(74848),o=n(28453);const t={sidebar_label:"Deploy Guide",sidebar_position:10},r="Deploy Guide",d={id:"iaas/guides/deploy-guide/index",title:"Deploy Guide",description:"OSISM is deployed in a series of successive steps. The steps are documented in the Deploy Guide.",source:"@site/docs/02-iaas/guides/deploy-guide/index.md",sourceDirName:"02-iaas/guides/deploy-guide",slug:"/iaas/guides/deploy-guide/",permalink:"/docs/iaas/guides/deploy-guide/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/index.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Deploy Guide",sidebar_position:10},sidebar:"docs",previous:{title:"Hardware Bill of Materials",permalink:"/docs/iaas/guides/concept-guide/hardware-bom"},next:{title:"Seed",permalink:"/docs/iaas/guides/deploy-guide/seed"}},a={},c=[];function l(e){const i={a:"a",admonition:"admonition",h1:"h1",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h1,{id:"deploy-guide",children:"Deploy Guide"}),"\n",(0,s.jsx)(i.p,{children:"OSISM is deployed in a series of successive steps. The steps are documented in the Deploy Guide."}),"\n",(0,s.jsx)(i.admonition,{type:"info",children:(0,s.jsxs)(i.p,{children:["The prerequisite for the deployment of a cluster is a configuration repository.\nWhat a configuration repository is and how it is created is described in the\n",(0,s.jsx)(i.a,{href:"../configuration-guide/configuration-repository#creating-a-new-configuration-repository",children:"Configuration Guide"}),"."]})}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["Step 1: ",(0,s.jsx)(i.a,{href:"./seed",children:"Preparation of the seed node"})]}),"\n",(0,s.jsxs)(i.li,{children:["Step 2: ",(0,s.jsx)(i.a,{href:"./manager",children:"Preparation of the manager node"})]}),"\n",(0,s.jsxs)(i.li,{children:["Step 3: ",(0,s.jsx)(i.a,{href:"./provisioning",children:"Provisioning of the bare-metal nodes"})]}),"\n",(0,s.jsxs)(i.li,{children:["Step 4: ",(0,s.jsx)(i.a,{href:"./bootstrap",children:"Bootstrap of the bare-metal nodes"})]}),"\n",(0,s.jsxs)(i.li,{children:["Step 5: ",(0,s.jsx)(i.a,{href:"./services",children:"Deployment of the services"})]}),"\n"]})]})}function u(e={}){const{wrapper:i}={...(0,o.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>r,x:()=>d});var s=n(96540);const o={},t=s.createContext(o);function r(e){const i=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function d(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(t.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/09cf625e.f61956bd.js b/assets/js/09cf625e.f61956bd.js new file mode 100644 index 0000000000..a3cfcd2f96 --- /dev/null +++ b/assets/js/09cf625e.f61956bd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3767],{90408:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>p,frontMatter:()=>s,metadata:()=>i,toc:()=>d});var o=n(74848),r=n(28453);const s={sidebar:1},c="Overview",i={id:"operating-scs/overview",title:"Overview",description:"TODO",source:"@site/docs/04-operating-scs/overview.md",sourceDirName:"04-operating-scs",slug:"/operating-scs/overview",permalink:"/docs/operating-scs/overview",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/overview.md",tags:[],version:"current",frontMatter:{sidebar:1}},a={},d=[];function u(e){const t={h1:"h1",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"overview",children:"Overview"}),"\n",(0,o.jsx)(t.p,{children:"TODO"})]})}function p(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var o=n(96540);const r={},s=o.createContext(r);function c(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0a757274.4eb45089.js b/assets/js/0a757274.4eb45089.js new file mode 100644 index 0000000000..ce3cd8593f --- /dev/null +++ b/assets/js/0a757274.4eb45089.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8296],{81400:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>d});var o=t(74848),r=t(28453);const s={},c="Knowledge",i={id:"iaas/overview/knowledge",title:"Knowledge",description:"TODO",source:"@site/docs/02-iaas/overview/knowledge.md",sourceDirName:"02-iaas/overview",slug:"/iaas/overview/knowledge",permalink:"/docs/iaas/overview/knowledge",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/overview/knowledge.md",tags:[],version:"current",frontMatter:{}},a={},d=[];function l(e){const n={h1:"h1",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"knowledge",children:"Knowledge"}),"\n",(0,o.jsx)(n.p,{children:"TODO"})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var o=t(96540);const r={},s=o.createContext(r);function c(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0bb6d954.1f11afbc.js b/assets/js/0bb6d954.1f11afbc.js new file mode 100644 index 0000000000..1e7106bf1f --- /dev/null +++ b/assets/js/0bb6d954.1f11afbc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7479],{20462:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>p,frontMatter:()=>c,metadata:()=>i,toc:()=>r});var a=n(74848),o=n(28453);const c={},s="Netdata",i={id:"iaas/guides/concept-guide/components/netdata",title:"Netdata",description:"Lifecycle Management of Netdata in OSISM",source:"@site/docs/02-iaas/guides/concept-guide/components/netdata.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/netdata",permalink:"/docs/iaas/guides/concept-guide/components/netdata",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/netdata.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Keycloak",permalink:"/docs/iaas/guides/concept-guide/components/keycloak"},next:{title:"OpenStack",permalink:"/docs/iaas/guides/concept-guide/components/openstack"}},d={},r=[{value:"Lifecycle Management of Netdata in OSISM",id:"lifecycle-management-of-netdata-in-osism",level:2}];function u(e){const t={h1:"h1",h2:"h2",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h1,{id:"netdata",children:"Netdata"}),"\n",(0,a.jsx)(t.h2,{id:"lifecycle-management-of-netdata-in-osism",children:"Lifecycle Management of Netdata in OSISM"})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>i});var a=n(96540);const o={},c=a.createContext(o);function s(e){const t=a.useContext(c);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),a.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0bcc5672.a424e230.js b/assets/js/0bcc5672.a424e230.js new file mode 100644 index 0000000000..7b8b77d587 --- /dev/null +++ b/assets/js/0bcc5672.a424e230.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1085],{2033:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>l,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var o=n(74848),r=n(28453);const s={},a="Software Requirements",c={id:"container/deployment-examples/a/software",title:"Software Requirements",description:"TODO",source:"@site/docs/03-container/deployment-examples/a/software.md",sourceDirName:"03-container/deployment-examples/a",slug:"/container/deployment-examples/a/software",permalink:"/docs/container/deployment-examples/a/software",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/deployment-examples/a/software.md",tags:[],version:"current",frontMatter:{}},i={},d=[];function m(e){const t={h1:"h1",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"software-requirements",children:"Software Requirements"}),"\n",(0,o.jsx)(t.p,{children:"TODO"})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(m,{...e})}):m(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>c});var o=n(96540);const r={},s=o.createContext(r);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0cb1d654.f5b017f6.js b/assets/js/0cb1d654.f5b017f6.js new file mode 100644 index 0000000000..dd1ab827ab --- /dev/null +++ b/assets/js/0cb1d654.f5b017f6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6182],{54896:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>l});var t=o(74848),i=o(28453);const s={},r="Overview",c={id:"operating-scs/components/monitoring/docs/overview",title:"Overview",description:"This repository aims to build an Observer monitoring solution intended to offer a global metrics",source:"@site/docs/04-operating-scs/components/monitoring/docs/overview.md",sourceDirName:"04-operating-scs/components/monitoring/docs",slug:"/operating-scs/components/monitoring/docs/overview",permalink:"/docs/operating-scs/components/monitoring/docs/overview",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/overview.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Monitoring",permalink:"/docs/category/monitoring"},next:{title:"Quickstart",permalink:"/docs/operating-scs/components/monitoring/docs/quickstart"}},a={},l=[];function d(e){const n={a:"a",code:"code",h1:"h1",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"overview",children:"Overview"}),"\n",(0,t.jsxs)(n.p,{children:["This repository aims to build an Observer monitoring solution intended to offer a global ",(0,t.jsx)(n.strong,{children:"metrics"}),"\nview of the CSP infrastructure. It is the platform where CSP infrastructure ",(0,t.jsx)(n.strong,{children:"metrics"}),"\nare fetched, processed, stored, and visualized. Note that this monitoring solution could\nbe extended, and the other two observability signals (logs and traces) from the CSP\ninfrastructure could also be processed here."]}),"\n",(0,t.jsxs)(n.p,{children:["The Observer monitoring solution is developed on the foundation of the ",(0,t.jsx)(n.a,{href:"https://github.com/dNationCloud/kubernetes-monitoring",children:"dNation monitoring solution"}),".\nand it is intended to become an ",(0,t.jsx)(n.strong,{children:"SCS product"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"This repository includes the manifest for the stable deployment of the Observer monitoring solution,\nas well as experimental and illustrative examples of how this monitoring solution can be extended and utilized."}),"\n",(0,t.jsxs)(n.p,{children:["The stable version of the Observer monitoring solution empowers its reference SCS installation available\nat ",(0,t.jsx)(n.a,{href:"https://monitoring.scs.community",children:"https://monitoring.scs.community"}),". This deployment covers the monitoring of core SCS infrastructure services,\nsubsequently referred to as 'Monitoring of infrastructure services'. Refer to the details ",(0,t.jsx)(n.a,{href:"/docs/operating-scs/components/monitoring/docs/scs-deployment",children:"here"}),".\nThe high-level architecture could be visualized as follows:"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"monitoring_scs_high_level.png",src:o(38552).A+"",width:"970",height:"508"})}),"\n",(0,t.jsxs)(n.p,{children:["Some illustrative and experimental examples of how this monitoring solution can be utilized have been introduced\nwithin the MVP-0 version of this project (refer to the ",(0,t.jsx)(n.code,{children:"mvp-0"})," tag, related comments, and docs sections: ",(0,t.jsx)(n.a,{href:"/docs/operating-scs/components/monitoring/docs/kaas",children:"kaas"}),", ",(0,t.jsx)(n.a,{href:"/docs/operating-scs/components/monitoring/docs/iaas",children:"iaas"}),").\nThese examples include:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Monitoring of the KaaS layer"}),"\n",(0,t.jsx)(n.li,{children:"Monitoring of the IaaS layer"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The above experimental components ",(0,t.jsx)(n.strong,{children:"are not part"})," of the reference SCS installation available\nat ",(0,t.jsx)(n.a,{href:"https://monitoring.scs.community",children:"https://monitoring.scs.community"}),".\nThe high-level architecture of these experimental components could be visualized as follows:"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"monitoring_scs_experimental.png",src:o(3705).A+"",width:"946",height:"467"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},3705:(e,n,o)=>{o.d(n,{A:()=>t});const t=o.p+"assets/images/monitoring_scs_experimental-3846febea17c1ecf9baaa074ee9b1a10.png"},38552:(e,n,o)=>{o.d(n,{A:()=>t});const t=o.p+"assets/images/monitoring_scs_high_level-50f86d39d750e803a31513fb32942e41.png"},28453:(e,n,o)=>{o.d(n,{R:()=>r,x:()=>c});var t=o(96540);const i={},s=t.createContext(i);function r(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0d2860b1.8cb35890.js b/assets/js/0d2860b1.8cb35890.js new file mode 100644 index 0000000000..e5e782de61 --- /dev/null +++ b/assets/js/0d2860b1.8cb35890.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7148],{60874:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>o,contentTitle:()=>s,default:()=>m,frontMatter:()=>d,metadata:()=>c,toc:()=>r});var i=t(74848),n=t(28453);const d={sidebar_label:"Automated updates",sidebar_position:1},s="Image Manager update.py",c={id:"iaas/guides/operations-guide/openstack/tools/image-manager/update",title:"Image Manager update.py",description:"Overview",source:"@site/docs/02-iaas/guides/operations-guide/openstack/tools/image-manager/update.md",sourceDirName:"02-iaas/guides/operations-guide/openstack/tools/image-manager",slug:"/iaas/guides/operations-guide/openstack/tools/image-manager/update",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/image-manager/update.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_label:"Automated updates",sidebar_position:1},sidebar:"docs",previous:{title:"Image Manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/"},next:{title:"Flavor Manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager"}},o={},r=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Usage",id:"usage",level:2}];function u(e){const a={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,n.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(a.h1,{id:"image-manager-updatepy",children:"Image Manager update.py"}),"\n",(0,i.jsx)(a.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsxs)(a.p,{children:["The OpenStack Image Manager ",(0,i.jsx)(a.code,{children:"update.py"})," Script updates the ",(0,i.jsx)(a.code,{children:"/etc/images/*.yaml"})," files to the always latest release of the Distributions, set S3 Mirror Urls and uploads the Images to the mirror."]}),"\n",(0,i.jsx)(a.p,{children:"These updated yaml files are later processed by the Image Manger itself."}),"\n",(0,i.jsx)(a.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsxs)(a.p,{children:["Prepare to use the ",(0,i.jsx)(a.code,{children:"update.py"})," script."]}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{children:"git clone https://github.com/osism/openstack-image-manager/ \ncd openstack-image-manager\npipenv install\npipenv shell\n"})}),"\n",(0,i.jsx)(a.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{children:"python contrib/update.py --help\n \n Usage: update.py [OPTIONS] \n \n\u256d\u2500 Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 --debug Enable debug logging \u2502\n\u2502 --dry-run Do not perform any changes \u2502\n\u2502 --minio-access-key TEXT Minio access key [env var: MINIO_ACCESS_KEY] [default: None] \u2502\n\u2502 --minio-secret-key TEXT Minio secret key [env var: MINIO_SECRET_KEY] [default: None] \u2502\n\u2502 --minio-server TEXT Minio server [env var: MINIO_SERVER] [default: swift.services.a.regiocloud.tech] \u2502\n\u2502 --minio-bucket TEXT Minio bucket [env var: MINIO_BUCKET] [default: openstack-images] \u2502\n\u2502 --swift-prefix TEXT Swift prefix [env var: SWIFT_PREFIX] [default: swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/] \u2502\n\u2502 --install-completion Install completion for the current shell. \u2502\n\u2502 --show-completion Show completion for the current shell, to copy it or customize the installation. \u2502\n\u2502 --help Show this message and exit. \u2502\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n"})}),"\n",(0,i.jsx)(a.admonition,{type:"note",children:(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"At this time the update.py expects all yamls Files at /etc/images/, which can't be configured at the moment."}),"\n",(0,i.jsx)(a.li,{children:"Mirroring can't be disabled at the moment."}),"\n"]})}),"\n",(0,i.jsxs)(a.p,{children:["Best is to run this Script by cron or a CI job, to update all Distribution Files periodically to the latest release and afterwards run ",(0,i.jsx)(a.a,{href:"../image-manager/",children:"Openstack Image Manager"}),".\nThe Distribution Image yaml files must exists before running the script, you can use the files from Github repo at ",(0,i.jsx)(a.code,{children:"etc/images/"})," as template for your first run."]}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{children:"$ python contrib/update.py\n2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/centos.yml\n2024-04-24 09:29:44 | INFO | update_image:179 - Checking image CentOS Stream 9\n2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-HEREBE\\d+\\.\\dDRAGONS.x86_64.qcow2\n2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cloud.centos.org/centos/9-stream/x86_64/images/CHECKSUM\n2024-04-24 09:29:44 | INFO | get_latest_default:62 - Latest URL is now https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2\n2024-04-24 09:29:44 | INFO | get_latest_default:63 - Latest filename is now CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2\n2024-04-24 09:29:44 | INFO | update_image:192 - Checksum of current CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337\n2024-04-24 09:29:44 | INFO | update_image:208 - Our checksum is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337\n2024-04-24 09:29:44 | INFO | update_image:211 - Image CentOS Stream 9 is up-to-date, nothing to do\n2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/debian.yml\n2024-04-24 09:29:44 | INFO | update_image:179 - Checking image Debian 11\n2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bullseye/latest/debian-11-genericcloud-amd64.raw\n2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bullseye/latest/SHA512SUMS\n2024-04-24 09:29:45 | INFO | update_image:192 - Checksum of current debian-11-genericcloud-amd64-20240211-1654.raw is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4\n2024-04-24 09:29:45 | INFO | update_image:208 - Our checksum is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4\n2024-04-24 09:29:45 | INFO | update_image:211 - Image Debian 11 is up-to-date, nothing to do\n2024-04-24 09:29:45 | INFO | update_image:179 - Checking image Debian 12\n2024-04-24 09:29:45 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.raw\n2024-04-24 09:29:45 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS\n2024-04-24 09:29:46 | INFO | update_image:192 - Checksum of current debian-12-genericcloud-amd64-daily-20240424-1727.raw is sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e\n2024-04-24 09:29:46 | INFO | update_image:208 - Our checksum is sha512:5401f8c6361bb2a82c2c24b4b4606d95e77229152a80e61f9c613bc88e25de9257057d0ed68b0256b745c4059162a54970fe4a8daf456b2eb67b4f5db5c97fcc\n2024-04-24 09:29:46 | INFO | update_image:229 - New values are {'version': '20240424', 'build_date': datetime.date(2024, 4, 24), 'checksum': 'sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e', 'url': 'https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240424-1727/debian-12-genericcloud-amd64-daily-20240424-1727.raw'}\n2024-04-24 09:29:46 | INFO | main:300 - Processing file /etc/images/rockylinux.yml\n2024-04-24 09:29:46 | INFO | update_image:179 - Checking image Rocky 9\n2024-04-24 09:29:46 | INFO | update_image:182 - Latest download URL is https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2\n2024-04-24 09:29:46 | INFO | update_image:185 - Getting checksums from https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2.CHECKSUM\n2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current Rocky-9-GenericCloud.latest.x86_64.qcow2 is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651\n2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651\n2024-04-24 09:29:47 | INFO | update_image:211 - Image Rocky_9 is up-to-date, nothing to do\n2024-04-24 09:29:47 | INFO | main:300 - Processing file /etc/images/ubuntu.yml\n2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04\n2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img\n2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS\n2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current jammy-server-cloudimg-amd64.img is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710\n2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710\n2024-04-24 09:29:47 | INFO | update_image:211 - Image Ubuntu_22.04 is up-to-date, nothing to do\n2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04 Minimal\n2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64.img\n2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/minimal/releases/jammy/release/SHA256SUMS\n2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current ubuntu-22.04-minimal-cloudimg-amd64.img is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65\n2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65\n2024-04-24 09:29:48 | INFO | update_image:211 - Image Ubuntu 22.04 Minimal is up-to-date, nothing to do\n2024-04-24 09:29:48 | INFO | update_image:179 - Checking image Ubuntu 24.04\n2024-04-24 09:29:48 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img\n2024-04-24 09:29:48 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/noble/current/SHA256SUMS\n2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current noble-server-cloudimg-amd64.img is sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3\n2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:d7ba8d5d1d073f2dc8351973bf4f35157c846a0ea6ee16fb2a9f45a78953e4a7\n2024-04-24 09:29:48 | INFO | update_image:229 - New values are {'version': '20240423', 'build_date': datetime.date(2024, 4, 23), 'checksum': 'sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3', 'url': 'https://cloud-images.ubuntu.com/noble/20240423/noble-server-cloudimg-amd64.img'}\n"})}),"\n",(0,i.jsx)(a.p,{children:"These yaml files are now extended with additional fields and the update.py will take care of the versions, checksum, url and build date to the latest release in the yaml file on every run."}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"latest_checksum_url - URL of the distros checksum file"}),"\n",(0,i.jsx)(a.li,{children:"latest_url - URL of the distros latest image"}),"\n",(0,i.jsx)(a.li,{children:"mirror_url - URL of the Image File at the local S3 Mirror"}),"\n"]}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{className:"language-yaml",metastring:'title="someexample.yaml"',children:"---\nimages:\n - name: Debian 12\n enable: true\n shortname: debian-12\n format: qcow2\n login: debian\n min_disk: 8\n min_ram: 512\n status: active\n visibility: public\n multi: true\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_rng_model: virtio\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n hypervisor_type: qemu\n os_distro: debian\n os_version: '12'\n replace_frequency: quarterly\n uuid_validity: last-3\n provided_until: none\n tags: []\n latest_checksum_url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS\n latest_url:\n https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.qcow2\n versions:\n - build_date: 2024-04-11\n checksum:\n sha512:3d6f26616e2c8b705993ddef874232887cebe42f1e70fcc020827ac88e8990177d537d34538c71ae2afd3b8baca953fff71eaa7ef71e752e82532c93dcdca436\n url:\n https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240411-1714/debian-12-genericcloud-amd64-daily-20240411-1714.qcow2\n mirror_url:\n https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-images/debian-12/20240411-debian-12.qcow2\n version: '20240411'\n\n"})})]})}function m(e={}){const{wrapper:a}={...(0,n.R)(),...e.components};return a?(0,i.jsx)(a,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,a,t)=>{t.d(a,{R:()=>s,x:()=>c});var i=t(96540);const n={},d=i.createContext(n);function s(e){const a=i.useContext(d);return i.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function c(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:s(e.components),i.createElement(d.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0dfeccb2.6d504488.js b/assets/js/0dfeccb2.6d504488.js new file mode 100644 index 0000000000..a406bb4502 --- /dev/null +++ b/assets/js/0dfeccb2.6d504488.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4342],{24179:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var s=i(74848),t=i(28453);const a={title:"Gnocchi as database for metering",type:"Decision Record",status:"Draft",track:"Ops"},o=void 0,r={id:"scs-0410-v1-gnocchi-as-metering-database",title:"Gnocchi as database for metering",description:"for more info. --\x3e",source:"@site/standards/scs-0410-v1-gnocchi-as-metering-database.md",sourceDirName:".",slug:"/scs-0410-v1-gnocchi-as-metering-database",permalink:"/standards/scs-0410-v1-gnocchi-as-metering-database",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Gnocchi as database for metering",type:"Decision Record",status:"Draft",track:"Ops"},sidebar:"standards",previous:{title:"scs-0410: Gnocchi as database for metering",permalink:"/standards/ops/scs-0410"},next:{title:"scs-0411: Push-based approach for providing usage data",permalink:"/standards/ops/scs-0411"}},c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Definitions",id:"definitions",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options",id:"options",level:3},{value:"Using Gnocchi",id:"using-gnocchi",level:4},{value:"Using Prometheus",id:"using-prometheus",level:4},{value:"Using InfluxDB",id:"using-influxdb",level:4},{value:"Creating a custom TSDB implementation",id:"creating-a-custom-tsdb-implementation",level:4},{value:"Decision",id:"decision",level:2},{value:"Open questions",id:"open-questions",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function d(e){const n={a:"a",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"In the past we noticed missing events in the telemetry stack of OpenStack.\nThis results in situations where the Cloud Service Provider (CSP)\nmay think that a resource is still in use while the owner shut it down,\nor may not be aware of a resource which has been created."}),"\n",(0,s.jsx)(n.p,{children:"Such inaccurate data is a problem,\nwhen it is supposed to be used for billing purposes."}),"\n",(0,s.jsx)(n.p,{children:"This document discusses how such metering data should be stored\nwithin the SCS.\nIn partiuclar,\nit provides rationale for the choice of Gnocchi\nas time-series database for metering data\nwithin SCS."}),"\n",(0,s.jsx)(n.h2,{id:"definitions",children:"Definitions"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"TSDB, time-series database:\nDatabase which is specialised for storing data which is keyed by a timestamp.\nPopular examples are InfluxDB, Graphite, rrd, and Prometheus."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Metering:\nCollection of usage data of a cloud,\nfor the specific purpose of creating invoices\nto bill customers for the resources they have allocated."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"backfilling:\nThe process of adding and modifying data in the past\nwithin a time-series database."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Metric:\nA single time-series vector.\nTypically, a metric represents a single property of a resource,\nsuch as CPU usage of an instance."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Resource metrics:\nA group of metrics belonging to a single resource.\nA compute instance, for instance,\nmay have a metric indicating the number of CPUs allocated,\nanother metric indicating the amount of RAM allocated,\netc."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(n.p,{children:"Being able to hold users accountable\nfor the resources they use\nis a prerequisite for commercially operating a cloud.\nThe SCS project wants to deliver a cloud stack\nwhich can be used for that purpose,\nhence providing reliable metering data is a requirement."}),"\n",(0,s.jsx)(n.p,{children:"As metering data is inherently keyed by time,\na time-series database is required.\nThe choice of time-series database is an important one\nas different databases come with different trade-offs.\nNot all databases are suitable for the kind of data\nwhich is collected in a metering context."}),"\n",(0,s.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsx)(n.p,{children:"The following requirements for a time-series database exist:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"MUST support backfilling:\nAs we need to catch up on changes to resources\nwhich may have happened during a brief network interruption,\nwe need to be able to modify data after it has been written to the TSDB."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"MUST be able to handle lots of resources:\nAs billing should happen with a resource-level granularity,\nwe expect a lot of different metrics inside the TSDB."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"MUST scale to different timescales:\nWe expect to have metrics which change frequently (e.g. object store usage)\nand metrics which change rarely (e.g. cinder volume sizes).\nThe TSDB must be able to cope with both types of metrics efficiently."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"SHOULD provide an efficient way to query all currently alive resources."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"SHOULD allow truncation of storage to remove old data."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"MUST be available under an appropriate Open Source license,\neven for productive use cases."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"options",children:"Options"}),"\n",(0,s.jsx)(n.h4,{id:"using-gnocchi",children:"Using Gnocchi"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://gnocchi.osci.io/",children:"Gnocchi"})," is a time-series database\nwhich has its origins in the OpenStack ecosystem."]}),"\n",(0,s.jsx)(n.p,{children:"It supports all requirements except truncation,\nwhich might have to be implemented."}),"\n",(0,s.jsx)(n.h4,{id:"using-prometheus",children:"Using Prometheus"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://prometheus.io",children:"Prometheus"})," is a widely used time-series database\nwith its focus on monitoring and incident response.\nWhile it is considered efficient for this use-case,\nit has shortcomings which make it unsuitable for the metering use case:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Explicit recommendation ",(0,s.jsx)(n.a,{href:"https://prometheus.io/docs/practices/instrumentation/#do-not-overuse-labels",children:"against high-cardinality metrics"}),":\nAs we would have to label metrics by resource IDs and project IDs,\nwe have to expect a very high cardinality,\nalso with a significant amount of metric churn."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Backfilling, ",(0,s.jsx)(n.a,{href:"https://prometheus.io/docs/prometheus/latest/storage/#backfilling-from-openmetrics-format",children:"albeit possible"}),", is not well-supported."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"using-influxdb",children:"Using InfluxDB"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://www.influxdata.com/",children:"InfluxDB"})," is a widely used time-series database\nwith its focus on monitoring."]}),"\n",(0,s.jsxs)(n.p,{children:["In contrast to Prometheus, it does support backfilling.\nHowever, like Prometheus,\nit seems to run ",(0,s.jsx)(n.a,{href:"https://docs.influxdata.com/influxdb/cloud/write-data/best-practices/resolve-high-cardinality/",children:"into scalability issues in high-cardinality scenarios"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"In addition,\nclustering is only available in commercial licensing options."}),"\n",(0,s.jsx)(n.h4,{id:"creating-a-custom-tsdb-implementation",children:"Creating a custom TSDB implementation"}),"\n",(0,s.jsx)(n.p,{children:"A custom TSDB implementation\nis a non-trivial project to pursue."}),"\n",(0,s.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsx)(n.p,{children:"We use Gnocchi.\nAccording to research,\nit mostly fulfills the requirements.\nWhile some small development efforts may be needed,\nto make it fully usable,\nthe amount of work is anticipated much less\nthan making Prometheus or Influx fit the bill\n(due to backfilling / cardinality scaling constraints),\nlet alone rolling a custom implementation."}),"\n",(0,s.jsx)(n.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"What will be the granularity of the events meta information?"}),"\n",(0,s.jsx)(n.p,{children:"If we decide to use resource metadata\nas a place to store slow-changing information\n(e.g. instance flavors, volume sizes),\nwe need to know what the granularity of that is."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"SCS-0411-v1"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsx)(n.p,{children:"None (this is a decision record)."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>r});var s=i(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0e4c395f.c529dc49.js b/assets/js/0e4c395f.c529dc49.js new file mode 100644 index 0000000000..f6150965b7 --- /dev/null +++ b/assets/js/0e4c395f.c529dc49.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3384],{75486:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var t=s(74848),o=s(28453);const i={},r="SCS deployment",c={id:"operating-scs/components/monitoring/docs/scs-deployment",title:"SCS deployment",description:"The following steps were utilized to deploy the SCS reference installation of the Observer monitoring solution,",source:"@site/docs/04-operating-scs/components/monitoring/docs/scs-deployment.md",sourceDirName:"04-operating-scs/components/monitoring/docs",slug:"/operating-scs/components/monitoring/docs/scs-deployment",permalink:"/docs/operating-scs/components/monitoring/docs/scs-deployment",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/scs-deployment.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Quickstart",permalink:"/docs/operating-scs/components/monitoring/docs/quickstart"},next:{title:"K3s support",permalink:"/docs/operating-scs/components/monitoring/docs/k3s"}},l={},a=[{value:"Architecture",id:"architecture",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install Observer solution",id:"install-observer-solution",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"scs-deployment",children:"SCS deployment"}),"\n",(0,t.jsxs)(n.p,{children:["The following steps were utilized to deploy the SCS reference installation of the Observer monitoring solution,\nwhich is available at ",(0,t.jsx)(n.a,{href:"https://monitoring.scs.community",children:"https://monitoring.scs.community"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"architecture",children:"Architecture"}),"\n",(0,t.jsx)(n.p,{children:"Currently, the detailed architecture diagram can be visualized as follows:"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"monitoring_scs_detailed.png",src:s(79403).A+"",width:"1430",height:"1010"})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Kubernetes cluster","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["We used the R5 version of ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/",children:"SCS KaaS V1"}),", which includes an ingress controller and cert manager","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"export KUBECONFIG=/path/to/kubeconfig\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://kubernetes.io/docs/reference/kubectl/",children:"kubectl"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://helm.sh/",children:"helm"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"install-observer-solution",children:"Install Observer solution"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Apply SCS brand secrets and letsencrypt issuer manifest."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f scs/logo.yaml\nkubectl apply -f scs/brand.yaml\nkubectl apply -f scs/issuer.yaml\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Deploy the Zuul monitoring related Helm chart and all associated manifests according to the instructions provided on ",(0,t.jsx)(n.a,{href:"/docs/operating-scs/components/monitoring/docs/zuul",children:"this"})," documentation page."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Deploy the Alertmanager to Matrix chat notifications related manifest according to the instructions provided on ",(0,t.jsx)(n.a,{href:"/docs/operating-scs/components/monitoring/docs/alertmanager",children:"this"})," documentation page."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Deploy the OAUTH related manifest according to the instructions provided on ",(0,t.jsx)(n.a,{href:"/docs/operating-scs/components/monitoring/docs/oauth",children:"this"})," documentation page."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Review the ",(0,t.jsx)(n.code,{children:"values-observer-scs.yaml"}),' file and locate all instances of the placeholder text "replace-me".\nThese values relate to configuring access to the object store as well as the Grafana admin password.']}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Finally, install the monitoring stack using values that incorporate all the configurations mentioned above"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/\nhelm repo update dnationcloud\nhelm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer-scs.yaml\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},79403:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/monitoring_scs_detailed-36c61be9b4deedd32e7babf1ddbc68ea.png"},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>c});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0ea173ba.3011feb1.js b/assets/js/0ea173ba.3011feb1.js new file mode 100644 index 0000000000..6d1f5cb094 --- /dev/null +++ b/assets/js/0ea173ba.3011feb1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5341],{85377:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>n,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>d});var r=s(74848),i=s(28453);const o={},c="Certification",l={id:"certification/overview",title:"overview",description:"SCS certificates come with various scopes. See Scopes and Versions for details.",source:"@site/standards/certification/overview.md",sourceDirName:"certification",slug:"/certification/overview",permalink:"/standards/certification/overview",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Introduction",permalink:"/standards/"},next:{title:"Scopes and versions",permalink:"/standards/certification/scopes-versions"}},n={},d=[{value:"Becoming certified",id:"becoming-certified",level:2},{value:"Compliant cloud environments",id:"compliant-cloud-environments",level:2}];function a(t){const e={a:"a",em:"em",h1:"h1",h2:"h2",img:"img",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.h1,{id:"certification",children:"Certification"}),"\n",(0,r.jsxs)(e.p,{children:["SCS certificates come with various scopes. See ",(0,r.jsx)(e.a,{href:"/standards/certification/scopes-versions",children:"Scopes and Versions"})," for details."]}),"\n",(0,r.jsx)(e.h2,{id:"becoming-certified",children:"Becoming certified"}),"\n",(0,r.jsxs)(e.p,{children:["In order for a cloud service offering to obtain a certificate, it has to conform to all standards of the respective scope, which will be tested at regular intervals, and the results of these tests will be made available publicly. For more details on how to become certified, please consult the corresponding ",(0,r.jsx)(e.a,{href:"/standards/scs-0004-v1-achieving-certification",children:"document"}),"."]}),"\n",(0,r.jsx)(e.h2,{id:"compliant-cloud-environments",children:"Compliant cloud environments"}),"\n",(0,r.jsxs)(e.p,{children:["This is a list of clouds that we test on a nightly basis against the certificate scope ",(0,r.jsx)(e.em,{children:"SCS-compatible IaaS"}),"."]}),"\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Name"}),(0,r.jsx)(e.th,{children:"Description"}),(0,r.jsx)(e.th,{children:"Operator"}),(0,r.jsx)(e.th,{style:{textAlign:"center"},children:"IaaS Compliance Check"}),(0,r.jsx)(e.th,{style:{textAlign:"center"},children:"HealthMon"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/cloud-resources/plusserver-gx-scs.md",children:"gx-scs"})}),(0,r.jsx)(e.td,{children:"Dev environment provided for SCS & GAIA-X context"}),(0,r.jsx)(e.td,{children:"plusserver GmbH"}),(0,r.jsx)(e.td,{style:{textAlign:"center"},children:(0,r.jsx)(e.img,{src:"https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-gx-scs-v2.yml?label=compliant",alt:"GitHub Workflow Status"})}),(0,r.jsx)(e.td,{style:{textAlign:"center"},children:(0,r.jsx)(e.a,{href:"https://health.gx-scs.sovereignit.cloud:3000/",children:"HM"})})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsxs)(e.td,{children:[(0,r.jsx)(e.a,{href:"https://www.plusserver.com/en/products/pluscloud-open",children:"pluscloud open"}),(0,r.jsx)("br",{}),"- prod1",(0,r.jsx)("br",{}),"- prod2",(0,r.jsx)("br",{}),"- prod3",(0,r.jsx)("br",{}),"- prod4"]}),(0,r.jsx)(e.td,{children:"Public cloud for customers (4 regions)"}),(0,r.jsx)(e.td,{children:"plusserver GmbH"}),(0,r.jsxs)(e.td,{style:{textAlign:"center"},children:["\xa0",(0,r.jsx)("br",{}),(0,r.jsx)(e.img,{src:"https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-pco-prod1-v2.yml?label=compliant",alt:"GitHub Workflow Status"}),(0,r.jsx)("br",{}),(0,r.jsx)(e.img,{src:"https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-pco-prod2-v2.yml?label=compliant",alt:"GitHub Workflow Status"}),(0,r.jsx)("br",{}),(0,r.jsx)(e.img,{src:"https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-pco-prod3-v2.yml?label=compliant",alt:"GitHub Workflow Status"}),(0,r.jsx)("br",{}),(0,r.jsx)(e.img,{src:"https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-pco-prod4-v2.yml?label=compliant",alt:"GitHub Workflow Status"})]}),(0,r.jsxs)(e.td,{style:{textAlign:"center"},children:["\xa0",(0,r.jsx)("br",{}),(0,r.jsx)(e.a,{href:"https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-pco",children:"HM1"}),(0,r.jsx)("br",{}),(0,r.jsx)(e.a,{href:"https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-prod2",children:"HM2"}),(0,r.jsx)("br",{}),(0,r.jsx)(e.a,{href:"https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-prod3",children:"HM3"}),(0,r.jsx)("br",{}),(0,r.jsx)(e.a,{href:"https://health.prod1.plusserver.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?orgId=1&var-mycloud=plus-prod4",children:"HM4"})]})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"https://www.noris.de/wavestack-cloud/",children:"Wavestack"})}),(0,r.jsx)(e.td,{children:"Public cloud for customers"}),(0,r.jsx)(e.td,{children:"noris network AG/Wavecon GmbH"}),(0,r.jsx)(e.td,{style:{textAlign:"center"},children:(0,r.jsx)(e.img,{src:"https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-wavestack-v3.yml?label=compliant",alt:"GitHub Workflow Status"})}),(0,r.jsx)(e.td,{style:{textAlign:"center"},children:(0,r.jsx)(e.a,{href:"https://health.wavestack1.sovereignit.cloud:3000/",children:"HM"})})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"https://regio.digital",children:"REGIO.cloud"})}),(0,r.jsx)(e.td,{children:"Public cloud for customers"}),(0,r.jsx)(e.td,{children:"OSISM GmbH"}),(0,r.jsx)(e.td,{style:{textAlign:"center"},children:(0,r.jsx)(e.img,{src:"https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-regio-a-v3.yml?label=compliant",alt:"GitHub Workflow Status"})}),(0,r.jsx)(e.td,{style:{textAlign:"center"},children:"broken "})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"https://cnds.io/",children:"CNDS"})}),(0,r.jsx)(e.td,{children:"Public cloud for customers"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"https://artcodix.com/",children:"artcodix UG"})}),(0,r.jsx)(e.td,{style:{textAlign:"center"},children:(0,r.jsx)(e.img,{src:"https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-artcodix-v3.yml?label=compliant",alt:"GitHub Workflow Status"})}),(0,r.jsx)(e.td,{style:{textAlign:"center"},children:(0,r.jsx)(e.a,{href:"https://ohm.muc.cloud.cnds.io/",children:"HM"})})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"https://aov.de/",children:"aov"})}),(0,r.jsx)(e.td,{children:"Community cloud for customers"}),(0,r.jsx)(e.td,{children:"aov IT.Services GmbH"}),(0,r.jsx)(e.td,{style:{textAlign:"center"},children:"(soon)"}),(0,r.jsx)(e.td,{style:{textAlign:"center"},children:(0,r.jsx)(e.a,{href:"https://health.aov.cloud/",children:"HM"})})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:"PoC WG-Cloud OSBA"}),(0,r.jsx)(e.td,{children:"Cloud PoC for FITKO"}),(0,r.jsx)(e.td,{children:"Cloud&Heat Technologies GmbH"}),(0,r.jsx)(e.td,{style:{textAlign:"center"},children:(0,r.jsx)(e.img,{src:"https://img.shields.io/github/actions/workflow/status/SovereignCloudStack/standards/check-poc-wgcloud-v3.yml?label=compliant",alt:"GitHub Workflow Status"})}),(0,r.jsx)(e.td,{style:{textAlign:"center"},children:(0,r.jsx)(e.a,{href:"https://health.poc-wgcloud.osba.sovereignit.cloud:3000/d/9ltTEmlnk/openstack-health-monitor2?var-mycloud=poc-wgcloud&orgId=1",children:"HM"})})]})]})]})]})}function h(t={}){const{wrapper:e}={...(0,i.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(a,{...t})}):a(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>c,x:()=>l});var r=s(96540);const i={},o=r.createContext(i);function c(t){const e=r.useContext(o);return r.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function l(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:c(t.components),r.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/0f0de498.c14704ce.js b/assets/js/0f0de498.c14704ce.js new file mode 100644 index 0000000000..47de376f28 --- /dev/null +++ b/assets/js/0f0de498.c14704ce.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5013],{47031:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>g,frontMatter:()=>a,metadata:()=>c,toc:()=>r});var i=t(74848),s=t(28453);const a={sidebar_label:"Designate"},o="Designate",c={id:"iaas/guides/configuration-guide/openstack/designate",title:"Designate",description:"* Designate admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/designate.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/designate",permalink:"/docs/iaas/guides/configuration-guide/openstack/designate",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/designate.md",tags:[],version:"current",frontMatter:{sidebar_label:"Designate"},sidebar:"docs",previous:{title:"Cinder",permalink:"/docs/iaas/guides/configuration-guide/openstack/cinder"},next:{title:"Glance",permalink:"/docs/iaas/guides/configuration-guide/openstack/glance"}},d={},r=[];function u(e){const n={a:"a",h1:"h1",li:"li",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"designate",children:"Designate"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/designate/latest/admin/index.html",children:"Designate admin guide"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/designate/latest/configuration/index.html",children:"Designate configuration guide"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/designate/latest/admin/config.html",children:"Designate configuration reference"})}),"\n"]})]})}function g(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var i=t(96540);const s={},a=i.createContext(s);function o(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1.6d8e9162.js b/assets/js/1.6d8e9162.js new file mode 100644 index 0000000000..9c8a07f62f --- /dev/null +++ b/assets/js/1.6d8e9162.js @@ -0,0 +1,10323 @@ +"use strict"; +exports.id = 1; +exports.ids = [1]; +exports.modules = { + +/***/ 21176: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Zp: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(5664); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(74722); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(91395); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(697); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.A(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.A( + map/* default */.A(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.A(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.A(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.T(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.A(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.A(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.A(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.A(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.A(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.A('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.A(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.A(g.outEdges(v), function (e) { + if (has/* default */.A(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.A(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.A(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(98879); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(81942); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(23068); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.A)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(52528); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.A)(iteratee, 3); + + (0,_baseForOwn/* default */.A)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.A)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(41917); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.A.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.A(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.T().setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.T({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.A(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.A(range/* default */.A(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.A(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.A(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.A(layers, function (vs, i) { + if (isUndefined/* default */.A(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.A(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.A(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.A(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.A(children, dfs); + } + + if (has/* default */.A(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.A(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.A(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, reverseYOne); + if (has/* default */.A(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, swapXYOne); + if (has/* default */.A(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.A(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.A)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.A(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.A(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.A(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.T({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.A(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.A(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.A(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.A)(collection)) { + var iteratee = (0,_baseIteratee/* default */.A)(predicate, 3); + collection = (0,keys/* default */.A)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.A)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.A)(array, (0,_baseIteratee/* default */.A)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(69471); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(88496); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.A)(value) && (0,isObjectLike/* default */.A)(value) && (0,_baseGetTag/* default */.A)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.A)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.A)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.A)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.A)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.A(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.A(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.A(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.A(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.A(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.A(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.A(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.A(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(73046); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.A(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.A(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.A(tree.neighbors(v), function (w) { + if (!has/* default */.A(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.A(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.A(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.A(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.A(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.A(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.A(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.A(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.A(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.A( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(91641); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.A)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.A(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.T({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.A(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.A(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.A(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.A('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.A); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(52568); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.A)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.A)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + if ((0,isArray/* default */.A)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.A)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.A]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.A)(iteratees, (0,_baseUnary/* default */.A)(_baseIteratee/* default */.A)); + + var result = (0,_baseMap/* default */.A)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.A)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.A)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.A)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.A)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.A(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.A( + map/* default */.A(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.A(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.A(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.A( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.A(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.A(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.A(range/* default */.A(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.A(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.A(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.A(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.A(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.A( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.A(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.A(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.A(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.A(entryV) && !isUndefined/* default */.A(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.A(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.A(uEntry.barycenter) || + isUndefined/* default */.A(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.A(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.A(entry.out, handleOut(entry)); + } + + return map/* default */.A( + filter/* default */.A(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.A(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.A(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.A(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.A(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.A(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.A(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.A(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.A([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.A(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.A(entries, function (entry) { + entry.vs = flatten/* default */.A( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.A(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.A(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.A(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.A(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.T(); + forEach/* default */.A(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.A(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.A(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.A(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(99922); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(4574); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee), keysIn/* default */.A); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.A(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.A(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.A(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.A(range/* default */.A(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.A(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.A(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.A(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.A(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.A(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.A(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.T(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.A(layering, function (layer) { + var u; + forEach/* default */.A(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.A(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.A(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.A(['u', 'd'], function (vert) { + forEach/* default */.A(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.A(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.A(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.A(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.A(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.A(layering).reverse(); + forEach/* default */.A(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.A(adjustedLayering, function (inner) { + return values/* default */.A(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.A(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.A(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.A(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.A(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.A(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.A(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.A(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.T({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.A({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.A(graph, graphAttrs)) + ); + + forEach/* default */.A(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.A(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.A({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.A(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.A(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.A(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.A(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.A(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.A(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.A(layers, function (layer) { + var orderShift = 0; + forEach/* default */.A(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.A(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.A(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.A(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 73046: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + T: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(89610); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(66401); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.A)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(39857); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.A && (1 / (0,_setToArray/* default */.A)(new _Set/* default */.A([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.A(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.A)(set); + } + isCommon = false; + includes = _cacheHas/* default */.A; + seen = new _SetCache/* default */.A; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(53533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.A)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.A)(arrays, 1, isArrayLikeObject/* default */.A, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.A(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.A(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.A(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.A(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.A(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.A(this._nodes); + } + sources() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.A(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.A(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.A(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.A(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.A(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.A(keys/* default */.A(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.A(keys/* default */.A(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.A(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.A(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.A(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.A(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.A(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.A(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.A(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.A(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.A(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.A(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.A(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.A(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.A(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.A(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.A(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.A(inV); + if (!u) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.A(outV); + if (!w) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.A(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 697: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ T: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.T) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 62062: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(29471); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.A; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 72641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 2634: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 45572: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 76912: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 91641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(72641); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(22031); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keys/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keysIn/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(80154); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(39759); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(14792); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.A)(source, (0,_getSymbols/* default */.A)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(15647); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(13153); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.A : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.A)(result, (0,_getSymbols/* default */.A)(object)); + object = (0,_getPrototype/* default */.A)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.A)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(33831); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.A)(object, keysIn/* default */.A, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(90565); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.A)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(1801); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.A)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.A)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(18598); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(64841); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.A)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.A)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.A)(value)) { + return value; + } + var isArr = (0,isArray/* default */.A)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.A)(value, result); + } + } else { + var tag = (0,_getTag/* default */.A)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.A)(value)) { + return (0,_cloneBuffer/* default */.A)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.A)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.A); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.A) + : (isFlat ? keysIn/* default */.A : keys/* default */.A); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.A)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.A)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 6240: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.A)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.A); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 25707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 13588: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(52274); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.A ? _Symbol/* default */.A.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.A)(value) || (0,isArguments/* default */.A)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.A)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 79841: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4574); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 66318: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 33831: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76912); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 49574: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.A : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.A)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(43988); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(66984); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.A(object), new _Uint8Array/* default */.A(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.A)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.A); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.A)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.A)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(33858); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.A)(object), + othIsArr = (0,isArray/* default */.A)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.A)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.A)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.A)(object)) { + if (!(0,isBuffer/* default */.A)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.A); + return (objIsArr || (0,isTypedArray/* default */.A)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.A); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.A); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.A)(value) && !(0,isObjectLike/* default */.A)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.A; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.A)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.A)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.A)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.A)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.A)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.A)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.A)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.A)(path) ? (0,_baseProperty/* default */.A)((0,_toKey/* default */.A)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.A; + } + if (typeof value == 'object') { + return (0,isArray/* default */.A)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 52568: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6240); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 70805: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 64099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 99922: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(29008); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 7819: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(46632); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.A)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(28894); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.A)(value)) { + return value; + } + return (0,_isKey/* default */.A)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.A)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 19042: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33831); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14792); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 14792: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2634); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13153); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 85054: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(52274); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(92049); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25353); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5254); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 86586: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(61882); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 29959: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 30901: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61882); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 23068: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(24326); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66984); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6832); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55615); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 11662: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(2634); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.A)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.A)(collection) ? _arrayFilter/* default */.A : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.A)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 34098: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13588); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 8058: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72641); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6240); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99922); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 48585: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 39188: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 61882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(88496); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(53098); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 69592: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 27422: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(83607); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69471); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 74722: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(45572); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49574); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(52568); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 81942: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(7819); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(25353); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.A)(object)) { + return object; + } + path = (0,_castPath/* default */.A)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.A)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.A)(objValue) + ? objValue + : ((0,_isIndex/* default */.A)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.A)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.A)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.A)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.A)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(76875); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(67525); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.A)((0,_overRest/* default */.A)(func, undefined, flatten/* default */.A), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 91395: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.A)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.A)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.A)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.A)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 89463: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.A)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.A)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.A); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 13153: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 74342: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.A)(value)) { + return NAN; + } + if ((0,isObject/* default */.A)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.A)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 28894: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.A)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.A)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.A)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 5664: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28894); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 38207: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.A)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.A)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 79001: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + diagram: () => (/* binding */ diagram) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-f47111a7.js + 8 modules +var mermaid_f47111a7 = __webpack_require__(76257); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(697); +// EXTERNAL MODULE: ./node_modules/d3/src/index.js + 197 modules +var src = __webpack_require__(26312); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + 64 modules +var dagre = __webpack_require__(21176); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/stringify.js + +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ + +const byteToHex = []; + +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).slice(1)); +} + +function unsafeStringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]; +} + +function stringify(arr, offset = 0) { + const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields + + if (!validate(uuid)) { + throw TypeError('Stringified UUID is invalid'); + } + + return uuid; +} + +/* harmony default export */ const esm_node_stringify = ((/* unused pure expression or super */ null && (stringify))); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/regex.js +/* harmony default export */ const regex = (/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/validate.js + + +function validate_validate(uuid) { + return typeof uuid === 'string' && regex.test(uuid); +} + +/* harmony default export */ const esm_node_validate = (validate_validate); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/parse.js + + +function parse(uuid) { + if (!esm_node_validate(uuid)) { + throw TypeError('Invalid UUID'); + } + + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ + + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ + + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ + + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ + + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; +} + +/* harmony default export */ const esm_node_parse = (parse); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/v35.js + + + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +function v35(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + var _namespace; + + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = esm_node_parse(namespace); + } + + if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return unsafeStringify(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} +// EXTERNAL MODULE: external "crypto" +var external_crypto_ = __webpack_require__(76982); +var external_crypto_default = /*#__PURE__*/__webpack_require__.n(external_crypto_); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/sha1.js + + +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + + return external_crypto_default().createHash('sha1').update(bytes).digest(); +} + +/* harmony default export */ const esm_node_sha1 = (sha1); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/v5.js + + +const v5 = v35('v5', 0x50, esm_node_sha1); +/* harmony default export */ const esm_node_v5 = (v5); +// EXTERNAL MODULE: ./node_modules/dayjs/dayjs.min.js +var dayjs_min = __webpack_require__(74353); +// EXTERNAL MODULE: ./node_modules/@braintree/sanitize-url/dist/index.js +var dist = __webpack_require__(16750); +// EXTERNAL MODULE: ./node_modules/dompurify/dist/purify.es.mjs +var purify_es = __webpack_require__(99418); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/erDiagram-47591fe2.js + + + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [6, 8, 10, 20, 22, 24, 26, 27, 28], $V1 = [1, 10], $V2 = [1, 11], $V3 = [1, 12], $V4 = [1, 13], $V5 = [1, 14], $V6 = [1, 15], $V7 = [1, 21], $V8 = [1, 22], $V9 = [1, 23], $Va = [1, 24], $Vb = [1, 25], $Vc = [6, 8, 10, 13, 15, 18, 19, 20, 22, 24, 26, 27, 28, 41, 42, 43, 44, 45], $Vd = [1, 34], $Ve = [27, 28, 46, 47], $Vf = [41, 42, 43, 44, 45], $Vg = [17, 34], $Vh = [1, 54], $Vi = [1, 53], $Vj = [17, 34, 36, 38]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "ER_DIAGRAM": 4, "document": 5, "EOF": 6, "line": 7, "SPACE": 8, "statement": 9, "NEWLINE": 10, "entityName": 11, "relSpec": 12, ":": 13, "role": 14, "BLOCK_START": 15, "attributes": 16, "BLOCK_STOP": 17, "SQS": 18, "SQE": 19, "title": 20, "title_value": 21, "acc_title": 22, "acc_title_value": 23, "acc_descr": 24, "acc_descr_value": 25, "acc_descr_multiline_value": 26, "ALPHANUM": 27, "ENTITY_NAME": 28, "attribute": 29, "attributeType": 30, "attributeName": 31, "attributeKeyTypeList": 32, "attributeComment": 33, "ATTRIBUTE_WORD": 34, "attributeKeyType": 35, "COMMA": 36, "ATTRIBUTE_KEY": 37, "COMMENT": 38, "cardinality": 39, "relType": 40, "ZERO_OR_ONE": 41, "ZERO_OR_MORE": 42, "ONE_OR_MORE": 43, "ONLY_ONE": 44, "MD_PARENT": 45, "NON_IDENTIFYING": 46, "IDENTIFYING": 47, "WORD": 48, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "ER_DIAGRAM", 6: "EOF", 8: "SPACE", 10: "NEWLINE", 13: ":", 15: "BLOCK_START", 17: "BLOCK_STOP", 18: "SQS", 19: "SQE", 20: "title", 21: "title_value", 22: "acc_title", 23: "acc_title_value", 24: "acc_descr", 25: "acc_descr_value", 26: "acc_descr_multiline_value", 27: "ALPHANUM", 28: "ENTITY_NAME", 34: "ATTRIBUTE_WORD", 36: "COMMA", 37: "ATTRIBUTE_KEY", 38: "COMMENT", 41: "ZERO_OR_ONE", 42: "ZERO_OR_MORE", 43: "ONE_OR_MORE", 44: "ONLY_ONE", 45: "MD_PARENT", 46: "NON_IDENTIFYING", 47: "IDENTIFYING", 48: "WORD" }, + productions_: [0, [3, 3], [5, 0], [5, 2], [7, 2], [7, 1], [7, 1], [7, 1], [9, 5], [9, 4], [9, 3], [9, 1], [9, 7], [9, 6], [9, 4], [9, 2], [9, 2], [9, 2], [9, 1], [11, 1], [11, 1], [16, 1], [16, 2], [29, 2], [29, 3], [29, 3], [29, 4], [30, 1], [31, 1], [32, 1], [32, 3], [35, 1], [33, 1], [12, 3], [39, 1], [39, 1], [39, 1], [39, 1], [39, 1], [40, 1], [40, 1], [14, 1], [14, 1], [14, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 1: + break; + case 2: + this.$ = []; + break; + case 3: + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + break; + case 4: + case 5: + this.$ = $$[$0]; + break; + case 6: + case 7: + this.$ = []; + break; + case 8: + yy.addEntity($$[$0 - 4]); + yy.addEntity($$[$0 - 2]); + yy.addRelationship($$[$0 - 4], $$[$0], $$[$0 - 2], $$[$0 - 3]); + break; + case 9: + yy.addEntity($$[$0 - 3]); + yy.addAttributes($$[$0 - 3], $$[$0 - 1]); + break; + case 10: + yy.addEntity($$[$0 - 2]); + break; + case 11: + yy.addEntity($$[$0]); + break; + case 12: + yy.addEntity($$[$0 - 6], $$[$0 - 4]); + yy.addAttributes($$[$0 - 6], $$[$0 - 1]); + break; + case 13: + yy.addEntity($$[$0 - 5], $$[$0 - 3]); + break; + case 14: + yy.addEntity($$[$0 - 3], $$[$0 - 1]); + break; + case 15: + case 16: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 17: + case 18: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 19: + case 43: + this.$ = $$[$0]; + break; + case 20: + case 41: + case 42: + this.$ = $$[$0].replace(/"/g, ""); + break; + case 21: + case 29: + this.$ = [$$[$0]]; + break; + case 22: + $$[$0].push($$[$0 - 1]); + this.$ = $$[$0]; + break; + case 23: + this.$ = { attributeType: $$[$0 - 1], attributeName: $$[$0] }; + break; + case 24: + this.$ = { attributeType: $$[$0 - 2], attributeName: $$[$0 - 1], attributeKeyTypeList: $$[$0] }; + break; + case 25: + this.$ = { attributeType: $$[$0 - 2], attributeName: $$[$0 - 1], attributeComment: $$[$0] }; + break; + case 26: + this.$ = { attributeType: $$[$0 - 3], attributeName: $$[$0 - 2], attributeKeyTypeList: $$[$0 - 1], attributeComment: $$[$0] }; + break; + case 27: + case 28: + case 31: + this.$ = $$[$0]; + break; + case 30: + $$[$0 - 2].push($$[$0]); + this.$ = $$[$0 - 2]; + break; + case 32: + this.$ = $$[$0].replace(/"/g, ""); + break; + case 33: + this.$ = { cardA: $$[$0], relType: $$[$0 - 1], cardB: $$[$0 - 2] }; + break; + case 34: + this.$ = yy.Cardinality.ZERO_OR_ONE; + break; + case 35: + this.$ = yy.Cardinality.ZERO_OR_MORE; + break; + case 36: + this.$ = yy.Cardinality.ONE_OR_MORE; + break; + case 37: + this.$ = yy.Cardinality.ONLY_ONE; + break; + case 38: + this.$ = yy.Cardinality.MD_PARENT; + break; + case 39: + this.$ = yy.Identification.NON_IDENTIFYING; + break; + case 40: + this.$ = yy.Identification.IDENTIFYING; + break; + } + }, + table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: [1, 6], 9: 7, 10: [1, 8], 11: 9, 20: $V1, 22: $V2, 24: $V3, 26: $V4, 27: $V5, 28: $V6 }, o($V0, [2, 7], { 1: [2, 1] }), o($V0, [2, 3]), { 9: 16, 11: 9, 20: $V1, 22: $V2, 24: $V3, 26: $V4, 27: $V5, 28: $V6 }, o($V0, [2, 5]), o($V0, [2, 6]), o($V0, [2, 11], { 12: 17, 39: 20, 15: [1, 18], 18: [1, 19], 41: $V7, 42: $V8, 43: $V9, 44: $Va, 45: $Vb }), { 21: [1, 26] }, { 23: [1, 27] }, { 25: [1, 28] }, o($V0, [2, 18]), o($Vc, [2, 19]), o($Vc, [2, 20]), o($V0, [2, 4]), { 11: 29, 27: $V5, 28: $V6 }, { 16: 30, 17: [1, 31], 29: 32, 30: 33, 34: $Vd }, { 11: 35, 27: $V5, 28: $V6 }, { 40: 36, 46: [1, 37], 47: [1, 38] }, o($Ve, [2, 34]), o($Ve, [2, 35]), o($Ve, [2, 36]), o($Ve, [2, 37]), o($Ve, [2, 38]), o($V0, [2, 15]), o($V0, [2, 16]), o($V0, [2, 17]), { 13: [1, 39] }, { 17: [1, 40] }, o($V0, [2, 10]), { 16: 41, 17: [2, 21], 29: 32, 30: 33, 34: $Vd }, { 31: 42, 34: [1, 43] }, { 34: [2, 27] }, { 19: [1, 44] }, { 39: 45, 41: $V7, 42: $V8, 43: $V9, 44: $Va, 45: $Vb }, o($Vf, [2, 39]), o($Vf, [2, 40]), { 14: 46, 27: [1, 49], 28: [1, 48], 48: [1, 47] }, o($V0, [2, 9]), { 17: [2, 22] }, o($Vg, [2, 23], { 32: 50, 33: 51, 35: 52, 37: $Vh, 38: $Vi }), o([17, 34, 37, 38], [2, 28]), o($V0, [2, 14], { 15: [1, 55] }), o([27, 28], [2, 33]), o($V0, [2, 8]), o($V0, [2, 41]), o($V0, [2, 42]), o($V0, [2, 43]), o($Vg, [2, 24], { 33: 56, 36: [1, 57], 38: $Vi }), o($Vg, [2, 25]), o($Vj, [2, 29]), o($Vg, [2, 32]), o($Vj, [2, 31]), { 16: 58, 17: [1, 59], 29: 32, 30: 33, 34: $Vd }, o($Vg, [2, 26]), { 35: 60, 37: $Vh }, { 17: [1, 61] }, o($V0, [2, 13]), o($Vj, [2, 30]), o($V0, [2, 12])], + defaultActions: { 34: [2, 27], 41: [2, 22] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.begin("acc_title"); + return 22; + case 1: + this.popState(); + return "acc_title_value"; + case 2: + this.begin("acc_descr"); + return 24; + case 3: + this.popState(); + return "acc_descr_value"; + case 4: + this.begin("acc_descr_multiline"); + break; + case 5: + this.popState(); + break; + case 6: + return "acc_descr_multiline_value"; + case 7: + return 10; + case 8: + break; + case 9: + return 8; + case 10: + return 28; + case 11: + return 48; + case 12: + return 4; + case 13: + this.begin("block"); + return 15; + case 14: + return 36; + case 15: + break; + case 16: + return 37; + case 17: + return 34; + case 18: + return 34; + case 19: + return 38; + case 20: + break; + case 21: + this.popState(); + return 17; + case 22: + return yy_.yytext[0]; + case 23: + return 18; + case 24: + return 19; + case 25: + return 41; + case 26: + return 43; + case 27: + return 43; + case 28: + return 43; + case 29: + return 41; + case 30: + return 41; + case 31: + return 42; + case 32: + return 42; + case 33: + return 42; + case 34: + return 42; + case 35: + return 42; + case 36: + return 43; + case 37: + return 42; + case 38: + return 43; + case 39: + return 44; + case 40: + return 44; + case 41: + return 44; + case 42: + return 44; + case 43: + return 41; + case 44: + return 42; + case 45: + return 43; + case 46: + return 45; + case 47: + return 46; + case 48: + return 47; + case 49: + return 47; + case 50: + return 46; + case 51: + return 46; + case 52: + return 46; + case 53: + return 27; + case 54: + return yy_.yytext[0]; + case 55: + return 6; + } + }, + rules: [/^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:[\n]+)/i, /^(?:\s+)/i, /^(?:[\s]+)/i, /^(?:"[^"%\r\n\v\b\\]+")/i, /^(?:"[^"]*")/i, /^(?:erDiagram\b)/i, /^(?:\{)/i, /^(?:,)/i, /^(?:\s+)/i, /^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i, /^(?:(.*?)[~](.*?)*[~])/i, /^(?:[\*A-Za-z_][A-Za-z0-9\-_\[\]\(\)]*)/i, /^(?:"[^"]*")/i, /^(?:[\n]+)/i, /^(?:\})/i, /^(?:.)/i, /^(?:\[)/i, /^(?:\])/i, /^(?:one or zero\b)/i, /^(?:one or more\b)/i, /^(?:one or many\b)/i, /^(?:1\+)/i, /^(?:\|o\b)/i, /^(?:zero or one\b)/i, /^(?:zero or more\b)/i, /^(?:zero or many\b)/i, /^(?:0\+)/i, /^(?:\}o\b)/i, /^(?:many\(0\))/i, /^(?:many\(1\))/i, /^(?:many\b)/i, /^(?:\}\|)/i, /^(?:one\b)/i, /^(?:only one\b)/i, /^(?:1\b)/i, /^(?:\|\|)/i, /^(?:o\|)/i, /^(?:o\{)/i, /^(?:\|\{)/i, /^(?:\s*u\b)/i, /^(?:\.\.)/i, /^(?:--)/i, /^(?:to\b)/i, /^(?:optionally to\b)/i, /^(?:\.-)/i, /^(?:-\.)/i, /^(?:[A-Za-z_][A-Za-z0-9\-_]*)/i, /^(?:.)/i, /^(?:$)/i], + conditions: { "acc_descr_multiline": { "rules": [5, 6], "inclusive": false }, "acc_descr": { "rules": [3], "inclusive": false }, "acc_title": { "rules": [1], "inclusive": false }, "block": { "rules": [14, 15, 16, 17, 18, 19, 20, 21, 22], "inclusive": false }, "INITIAL": { "rules": [0, 2, 4, 7, 8, 9, 10, 11, 12, 13, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const erParser = parser; +let entities = {}; +let relationships = []; +const Cardinality = { + ZERO_OR_ONE: "ZERO_OR_ONE", + ZERO_OR_MORE: "ZERO_OR_MORE", + ONE_OR_MORE: "ONE_OR_MORE", + ONLY_ONE: "ONLY_ONE", + MD_PARENT: "MD_PARENT" +}; +const Identification = { + NON_IDENTIFYING: "NON_IDENTIFYING", + IDENTIFYING: "IDENTIFYING" +}; +const addEntity = function(name, alias = void 0) { + if (entities[name] === void 0) { + entities[name] = { attributes: [], alias }; + mermaid_f47111a7.l.info("Added new entity :", name); + } else if (entities[name] && !entities[name].alias && alias) { + entities[name].alias = alias; + mermaid_f47111a7.l.info(`Add alias '${alias}' to entity '${name}'`); + } + return entities[name]; +}; +const getEntities = () => entities; +const addAttributes = function(entityName, attribs) { + let entity = addEntity(entityName); + let i; + for (i = attribs.length - 1; i >= 0; i--) { + entity.attributes.push(attribs[i]); + mermaid_f47111a7.l.debug("Added attribute ", attribs[i].attributeName); + } +}; +const addRelationship = function(entA, rolA, entB, rSpec) { + let rel = { + entityA: entA, + roleA: rolA, + entityB: entB, + relSpec: rSpec + }; + relationships.push(rel); + mermaid_f47111a7.l.debug("Added new relationship :", rel); +}; +const getRelationships = () => relationships; +const clear = function() { + entities = {}; + relationships = []; + (0,mermaid_f47111a7.v)(); +}; +const erDb = { + Cardinality, + Identification, + getConfig: () => (0,mermaid_f47111a7.c)().er, + addEntity, + addAttributes, + getEntities, + addRelationship, + getRelationships, + clear, + setAccTitle: mermaid_f47111a7.s, + getAccTitle: mermaid_f47111a7.g, + setAccDescription: mermaid_f47111a7.b, + getAccDescription: mermaid_f47111a7.a, + setDiagramTitle: mermaid_f47111a7.q, + getDiagramTitle: mermaid_f47111a7.t +}; +const ERMarkers = { + ONLY_ONE_START: "ONLY_ONE_START", + ONLY_ONE_END: "ONLY_ONE_END", + ZERO_OR_ONE_START: "ZERO_OR_ONE_START", + ZERO_OR_ONE_END: "ZERO_OR_ONE_END", + ONE_OR_MORE_START: "ONE_OR_MORE_START", + ONE_OR_MORE_END: "ONE_OR_MORE_END", + ZERO_OR_MORE_START: "ZERO_OR_MORE_START", + ZERO_OR_MORE_END: "ZERO_OR_MORE_END", + MD_PARENT_END: "MD_PARENT_END", + MD_PARENT_START: "MD_PARENT_START" +}; +const insertMarkers = function(elem, conf2) { + let marker; + elem.append("defs").append("marker").attr("id", ERMarkers.MD_PARENT_START).attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", ERMarkers.MD_PARENT_END).attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", ERMarkers.ONLY_ONE_START).attr("refX", 0).attr("refY", 9).attr("markerWidth", 18).attr("markerHeight", 18).attr("orient", "auto").append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M9,0 L9,18 M15,0 L15,18"); + elem.append("defs").append("marker").attr("id", ERMarkers.ONLY_ONE_END).attr("refX", 18).attr("refY", 9).attr("markerWidth", 18).attr("markerHeight", 18).attr("orient", "auto").append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M3,0 L3,18 M9,0 L9,18"); + marker = elem.append("defs").append("marker").attr("id", ERMarkers.ZERO_OR_ONE_START).attr("refX", 0).attr("refY", 9).attr("markerWidth", 30).attr("markerHeight", 18).attr("orient", "auto"); + marker.append("circle").attr("stroke", conf2.stroke).attr("fill", "white").attr("cx", 21).attr("cy", 9).attr("r", 6); + marker.append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M9,0 L9,18"); + marker = elem.append("defs").append("marker").attr("id", ERMarkers.ZERO_OR_ONE_END).attr("refX", 30).attr("refY", 9).attr("markerWidth", 30).attr("markerHeight", 18).attr("orient", "auto"); + marker.append("circle").attr("stroke", conf2.stroke).attr("fill", "white").attr("cx", 9).attr("cy", 9).attr("r", 6); + marker.append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M21,0 L21,18"); + elem.append("defs").append("marker").attr("id", ERMarkers.ONE_OR_MORE_START).attr("refX", 18).attr("refY", 18).attr("markerWidth", 45).attr("markerHeight", 36).attr("orient", "auto").append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"); + elem.append("defs").append("marker").attr("id", ERMarkers.ONE_OR_MORE_END).attr("refX", 27).attr("refY", 18).attr("markerWidth", 45).attr("markerHeight", 36).attr("orient", "auto").append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18"); + marker = elem.append("defs").append("marker").attr("id", ERMarkers.ZERO_OR_MORE_START).attr("refX", 18).attr("refY", 18).attr("markerWidth", 57).attr("markerHeight", 36).attr("orient", "auto"); + marker.append("circle").attr("stroke", conf2.stroke).attr("fill", "white").attr("cx", 48).attr("cy", 18).attr("r", 6); + marker.append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M0,18 Q18,0 36,18 Q18,36 0,18"); + marker = elem.append("defs").append("marker").attr("id", ERMarkers.ZERO_OR_MORE_END).attr("refX", 39).attr("refY", 18).attr("markerWidth", 57).attr("markerHeight", 36).attr("orient", "auto"); + marker.append("circle").attr("stroke", conf2.stroke).attr("fill", "white").attr("cx", 9).attr("cy", 18).attr("r", 6); + marker.append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M21,18 Q39,0 57,18 Q39,36 21,18"); + return; +}; +const erMarkers = { + ERMarkers, + insertMarkers +}; +const BAD_ID_CHARS_REGEXP = /[^\dA-Za-z](\W)*/g; +let conf = {}; +let entityNameIds = /* @__PURE__ */ new Map(); +const setConf = function(cnf) { + const keys = Object.keys(cnf); + for (const key of keys) { + conf[key] = cnf[key]; + } +}; +const drawAttributes = (groupNode, entityTextNode, attributes) => { + const heightPadding = conf.entityPadding / 3; + const widthPadding = conf.entityPadding / 3; + const attrFontSize = conf.fontSize * 0.85; + const labelBBox = entityTextNode.node().getBBox(); + const attributeNodes = []; + let hasKeyType = false; + let hasComment = false; + let maxTypeWidth = 0; + let maxNameWidth = 0; + let maxKeyWidth = 0; + let maxCommentWidth = 0; + let cumulativeHeight = labelBBox.height + heightPadding * 2; + let attrNum = 1; + attributes.forEach((item) => { + if (item.attributeKeyTypeList !== void 0 && item.attributeKeyTypeList.length > 0) { + hasKeyType = true; + } + if (item.attributeComment !== void 0) { + hasComment = true; + } + }); + attributes.forEach((item) => { + const attrPrefix = `${entityTextNode.node().id}-attr-${attrNum}`; + let nodeHeight = 0; + const attributeType = (0,mermaid_f47111a7.x)(item.attributeType); + const typeNode = groupNode.append("text").classed("er entityLabel", true).attr("id", `${attrPrefix}-type`).attr("x", 0).attr("y", 0).style("dominant-baseline", "middle").style("text-anchor", "left").style("font-family", (0,mermaid_f47111a7.c)().fontFamily).style("font-size", attrFontSize + "px").text(attributeType); + const nameNode = groupNode.append("text").classed("er entityLabel", true).attr("id", `${attrPrefix}-name`).attr("x", 0).attr("y", 0).style("dominant-baseline", "middle").style("text-anchor", "left").style("font-family", (0,mermaid_f47111a7.c)().fontFamily).style("font-size", attrFontSize + "px").text(item.attributeName); + const attributeNode = {}; + attributeNode.tn = typeNode; + attributeNode.nn = nameNode; + const typeBBox = typeNode.node().getBBox(); + const nameBBox = nameNode.node().getBBox(); + maxTypeWidth = Math.max(maxTypeWidth, typeBBox.width); + maxNameWidth = Math.max(maxNameWidth, nameBBox.width); + nodeHeight = Math.max(typeBBox.height, nameBBox.height); + if (hasKeyType) { + const keyTypeNodeText = item.attributeKeyTypeList !== void 0 ? item.attributeKeyTypeList.join(",") : ""; + const keyTypeNode = groupNode.append("text").classed("er entityLabel", true).attr("id", `${attrPrefix}-key`).attr("x", 0).attr("y", 0).style("dominant-baseline", "middle").style("text-anchor", "left").style("font-family", (0,mermaid_f47111a7.c)().fontFamily).style("font-size", attrFontSize + "px").text(keyTypeNodeText); + attributeNode.kn = keyTypeNode; + const keyTypeBBox = keyTypeNode.node().getBBox(); + maxKeyWidth = Math.max(maxKeyWidth, keyTypeBBox.width); + nodeHeight = Math.max(nodeHeight, keyTypeBBox.height); + } + if (hasComment) { + const commentNode = groupNode.append("text").classed("er entityLabel", true).attr("id", `${attrPrefix}-comment`).attr("x", 0).attr("y", 0).style("dominant-baseline", "middle").style("text-anchor", "left").style("font-family", (0,mermaid_f47111a7.c)().fontFamily).style("font-size", attrFontSize + "px").text(item.attributeComment || ""); + attributeNode.cn = commentNode; + const commentNodeBBox = commentNode.node().getBBox(); + maxCommentWidth = Math.max(maxCommentWidth, commentNodeBBox.width); + nodeHeight = Math.max(nodeHeight, commentNodeBBox.height); + } + attributeNode.height = nodeHeight; + attributeNodes.push(attributeNode); + cumulativeHeight += nodeHeight + heightPadding * 2; + attrNum += 1; + }); + let widthPaddingFactor = 4; + if (hasKeyType) { + widthPaddingFactor += 2; + } + if (hasComment) { + widthPaddingFactor += 2; + } + const maxWidth = maxTypeWidth + maxNameWidth + maxKeyWidth + maxCommentWidth; + const bBox = { + width: Math.max( + conf.minEntityWidth, + Math.max( + labelBBox.width + conf.entityPadding * 2, + maxWidth + widthPadding * widthPaddingFactor + ) + ), + height: attributes.length > 0 ? cumulativeHeight : Math.max(conf.minEntityHeight, labelBBox.height + conf.entityPadding * 2) + }; + if (attributes.length > 0) { + const spareColumnWidth = Math.max( + 0, + (bBox.width - maxWidth - widthPadding * widthPaddingFactor) / (widthPaddingFactor / 2) + ); + entityTextNode.attr( + "transform", + "translate(" + bBox.width / 2 + "," + (heightPadding + labelBBox.height / 2) + ")" + ); + let heightOffset = labelBBox.height + heightPadding * 2; + let attribStyle = "attributeBoxOdd"; + attributeNodes.forEach((attributeNode) => { + const alignY = heightOffset + heightPadding + attributeNode.height / 2; + attributeNode.tn.attr("transform", "translate(" + widthPadding + "," + alignY + ")"); + const typeRect = groupNode.insert("rect", "#" + attributeNode.tn.node().id).classed(`er ${attribStyle}`, true).attr("x", 0).attr("y", heightOffset).attr("width", maxTypeWidth + widthPadding * 2 + spareColumnWidth).attr("height", attributeNode.height + heightPadding * 2); + const nameXOffset = parseFloat(typeRect.attr("x")) + parseFloat(typeRect.attr("width")); + attributeNode.nn.attr( + "transform", + "translate(" + (nameXOffset + widthPadding) + "," + alignY + ")" + ); + const nameRect = groupNode.insert("rect", "#" + attributeNode.nn.node().id).classed(`er ${attribStyle}`, true).attr("x", nameXOffset).attr("y", heightOffset).attr("width", maxNameWidth + widthPadding * 2 + spareColumnWidth).attr("height", attributeNode.height + heightPadding * 2); + let keyTypeAndCommentXOffset = parseFloat(nameRect.attr("x")) + parseFloat(nameRect.attr("width")); + if (hasKeyType) { + attributeNode.kn.attr( + "transform", + "translate(" + (keyTypeAndCommentXOffset + widthPadding) + "," + alignY + ")" + ); + const keyTypeRect = groupNode.insert("rect", "#" + attributeNode.kn.node().id).classed(`er ${attribStyle}`, true).attr("x", keyTypeAndCommentXOffset).attr("y", heightOffset).attr("width", maxKeyWidth + widthPadding * 2 + spareColumnWidth).attr("height", attributeNode.height + heightPadding * 2); + keyTypeAndCommentXOffset = parseFloat(keyTypeRect.attr("x")) + parseFloat(keyTypeRect.attr("width")); + } + if (hasComment) { + attributeNode.cn.attr( + "transform", + "translate(" + (keyTypeAndCommentXOffset + widthPadding) + "," + alignY + ")" + ); + groupNode.insert("rect", "#" + attributeNode.cn.node().id).classed(`er ${attribStyle}`, "true").attr("x", keyTypeAndCommentXOffset).attr("y", heightOffset).attr("width", maxCommentWidth + widthPadding * 2 + spareColumnWidth).attr("height", attributeNode.height + heightPadding * 2); + } + heightOffset += attributeNode.height + heightPadding * 2; + attribStyle = attribStyle === "attributeBoxOdd" ? "attributeBoxEven" : "attributeBoxOdd"; + }); + } else { + bBox.height = Math.max(conf.minEntityHeight, cumulativeHeight); + entityTextNode.attr("transform", "translate(" + bBox.width / 2 + "," + bBox.height / 2 + ")"); + } + return bBox; +}; +const drawEntities = function(svgNode, entities2, graph) { + const keys = Object.keys(entities2); + let firstOne; + keys.forEach(function(entityName) { + const entityId = generateId(entityName, "entity"); + entityNameIds.set(entityName, entityId); + const groupNode = svgNode.append("g").attr("id", entityId); + firstOne = firstOne === void 0 ? entityId : firstOne; + const textId = "text-" + entityId; + const textNode = groupNode.append("text").classed("er entityLabel", true).attr("id", textId).attr("x", 0).attr("y", 0).style("dominant-baseline", "middle").style("text-anchor", "middle").style("font-family", (0,mermaid_f47111a7.c)().fontFamily).style("font-size", conf.fontSize + "px").text(entities2[entityName].alias ?? entityName); + const { width: entityWidth, height: entityHeight } = drawAttributes( + groupNode, + textNode, + entities2[entityName].attributes + ); + const rectNode = groupNode.insert("rect", "#" + textId).classed("er entityBox", true).attr("x", 0).attr("y", 0).attr("width", entityWidth).attr("height", entityHeight); + const rectBBox = rectNode.node().getBBox(); + graph.setNode(entityId, { + width: rectBBox.width, + height: rectBBox.height, + shape: "rect", + id: entityId + }); + }); + return firstOne; +}; +const adjustEntities = function(svgNode, graph) { + graph.nodes().forEach(function(v) { + if (v !== void 0 && graph.node(v) !== void 0) { + svgNode.select("#" + v).attr( + "transform", + "translate(" + (graph.node(v).x - graph.node(v).width / 2) + "," + (graph.node(v).y - graph.node(v).height / 2) + " )" + ); + } + }); +}; +const getEdgeName = function(rel) { + return (rel.entityA + rel.roleA + rel.entityB).replace(/\s/g, ""); +}; +const addRelationships = function(relationships2, g) { + relationships2.forEach(function(r) { + g.setEdge( + entityNameIds.get(r.entityA), + entityNameIds.get(r.entityB), + { relationship: r }, + getEdgeName(r) + ); + }); + return relationships2; +}; +let relCnt = 0; +const drawRelationshipFromLayout = function(svg, rel, g, insert, diagObj) { + relCnt++; + const edge = g.edge( + entityNameIds.get(rel.entityA), + entityNameIds.get(rel.entityB), + getEdgeName(rel) + ); + const lineFunction = (0,src/* line */.n8j)().x(function(d) { + return d.x; + }).y(function(d) { + return d.y; + }).curve(src/* curveBasis */.qrM); + const svgPath = svg.insert("path", "#" + insert).classed("er relationshipLine", true).attr("d", lineFunction(edge.points)).style("stroke", conf.stroke).style("fill", "none"); + if (rel.relSpec.relType === diagObj.db.Identification.NON_IDENTIFYING) { + svgPath.attr("stroke-dasharray", "8,8"); + } + let url = ""; + if (conf.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + switch (rel.relSpec.cardA) { + case diagObj.db.Cardinality.ZERO_OR_ONE: + svgPath.attr("marker-end", "url(" + url + "#" + erMarkers.ERMarkers.ZERO_OR_ONE_END + ")"); + break; + case diagObj.db.Cardinality.ZERO_OR_MORE: + svgPath.attr("marker-end", "url(" + url + "#" + erMarkers.ERMarkers.ZERO_OR_MORE_END + ")"); + break; + case diagObj.db.Cardinality.ONE_OR_MORE: + svgPath.attr("marker-end", "url(" + url + "#" + erMarkers.ERMarkers.ONE_OR_MORE_END + ")"); + break; + case diagObj.db.Cardinality.ONLY_ONE: + svgPath.attr("marker-end", "url(" + url + "#" + erMarkers.ERMarkers.ONLY_ONE_END + ")"); + break; + case diagObj.db.Cardinality.MD_PARENT: + svgPath.attr("marker-end", "url(" + url + "#" + erMarkers.ERMarkers.MD_PARENT_END + ")"); + break; + } + switch (rel.relSpec.cardB) { + case diagObj.db.Cardinality.ZERO_OR_ONE: + svgPath.attr( + "marker-start", + "url(" + url + "#" + erMarkers.ERMarkers.ZERO_OR_ONE_START + ")" + ); + break; + case diagObj.db.Cardinality.ZERO_OR_MORE: + svgPath.attr( + "marker-start", + "url(" + url + "#" + erMarkers.ERMarkers.ZERO_OR_MORE_START + ")" + ); + break; + case diagObj.db.Cardinality.ONE_OR_MORE: + svgPath.attr( + "marker-start", + "url(" + url + "#" + erMarkers.ERMarkers.ONE_OR_MORE_START + ")" + ); + break; + case diagObj.db.Cardinality.ONLY_ONE: + svgPath.attr("marker-start", "url(" + url + "#" + erMarkers.ERMarkers.ONLY_ONE_START + ")"); + break; + case diagObj.db.Cardinality.MD_PARENT: + svgPath.attr("marker-start", "url(" + url + "#" + erMarkers.ERMarkers.MD_PARENT_START + ")"); + break; + } + const len = svgPath.node().getTotalLength(); + const labelPoint = svgPath.node().getPointAtLength(len * 0.5); + const labelId = "rel" + relCnt; + const labelNode = svg.append("text").classed("er relationshipLabel", true).attr("id", labelId).attr("x", labelPoint.x).attr("y", labelPoint.y).style("text-anchor", "middle").style("dominant-baseline", "middle").style("font-family", (0,mermaid_f47111a7.c)().fontFamily).style("font-size", conf.fontSize + "px").text(rel.roleA); + const labelBBox = labelNode.node().getBBox(); + svg.insert("rect", "#" + labelId).classed("er relationshipLabelBox", true).attr("x", labelPoint.x - labelBBox.width / 2).attr("y", labelPoint.y - labelBBox.height / 2).attr("width", labelBBox.width).attr("height", labelBBox.height); +}; +const draw = function(text, id, _version, diagObj) { + conf = (0,mermaid_f47111a7.c)().er; + mermaid_f47111a7.l.info("Drawing ER diagram"); + const securityLevel = (0,mermaid_f47111a7.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,src/* select */.Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,src/* select */.Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,src/* select */.Ltv)("body"); + const svg = root.select(`[id='${id}']`); + erMarkers.insertMarkers(svg, conf); + let g; + g = new graphlib/* Graph */.T({ + multigraph: true, + directed: true, + compound: false + }).setGraph({ + rankdir: conf.layoutDirection, + marginx: 20, + marginy: 20, + nodesep: 100, + edgesep: 100, + ranksep: 100 + }).setDefaultEdgeLabel(function() { + return {}; + }); + const firstEntity = drawEntities(svg, diagObj.db.getEntities(), g); + const relationships2 = addRelationships(diagObj.db.getRelationships(), g); + (0,dagre/* layout */.Zp)(g); + adjustEntities(svg, g); + relationships2.forEach(function(rel) { + drawRelationshipFromLayout(svg, rel, g, firstEntity, diagObj); + }); + const padding = conf.diagramPadding; + mermaid_f47111a7.u.insertTitle(svg, "entityTitleText", conf.titleTopMargin, diagObj.db.getDiagramTitle()); + const svgBounds = svg.node().getBBox(); + const width = svgBounds.width + padding * 2; + const height = svgBounds.height + padding * 2; + (0,mermaid_f47111a7.i)(svg, height, width, conf.useMaxWidth); + svg.attr("viewBox", `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`); +}; +const MERMAID_ERDIAGRAM_UUID = "28e9f9db-3c8d-5aa5-9faf-44286ae5937c"; +function generateId(str = "", prefix = "") { + const simplifiedStr = str.replace(BAD_ID_CHARS_REGEXP, ""); + return `${strWithHyphen(prefix)}${strWithHyphen(simplifiedStr)}${esm_node_v5( + str, + MERMAID_ERDIAGRAM_UUID + )}`; +} +function strWithHyphen(str = "") { + return str.length > 0 ? `${str}-` : ""; +} +const erRenderer = { + setConf, + draw +}; +const getStyles = (options) => ` + .entityBox { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + } + + .attributeBoxOdd { + fill: ${options.attributeBackgroundColorOdd}; + stroke: ${options.nodeBorder}; + } + + .attributeBoxEven { + fill: ${options.attributeBackgroundColorEven}; + stroke: ${options.nodeBorder}; + } + + .relationshipLabelBox { + fill: ${options.tertiaryColor}; + opacity: 0.7; + background-color: ${options.tertiaryColor}; + rect { + opacity: 0.5; + } + } + + .relationshipLine { + stroke: ${options.lineColor}; + } + + .entityTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } + #MD_PARENT_START { + fill: #f5f5f5 !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; + } + #MD_PARENT_END { + fill: #f5f5f5 !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; + } + +`; +const erStyles = getStyles; +const diagram = { + parser: erParser, + db: erDb, + renderer: erRenderer, + styles: erStyles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/1109f10b.ab17e07d.js b/assets/js/1109f10b.ab17e07d.js new file mode 100644 index 0000000000..be946d144c --- /dev/null +++ b/assets/js/1109f10b.ab17e07d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3605],{91128:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>d});var a=n(74848),s=n(28453);const o={title:"SSD Flavors",type:"Decision Record",status:"Stable",stabilized_at:new Date("2023-06-14T00:00:00.000Z"),track:"IaaS",enhances:"scs-0100-v2-flavor-naming.md"},i=void 0,r={id:"scs-0110-v1-ssd-flavors",title:"SSD Flavors",description:"Introduction",source:"@site/standards/scs-0110-v1-ssd-flavors.md",sourceDirName:".",slug:"/scs-0110-v1-ssd-flavors",permalink:"/standards/scs-0110-v1-ssd-flavors",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SSD Flavors",type:"Decision Record",status:"Stable",stabilized_at:"2023-06-14T00:00:00.000Z",track:"IaaS",enhances:"scs-0100-v2-flavor-naming.md"},sidebar:"standards",previous:{title:"scs-0110: SSD Flavors",permalink:"/standards/iaas/scs-0110"},next:{title:"scs-0111: Decisions for the Volume Type Standard",permalink:"/standards/iaas/scs-0111"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"One-node etcd (backed by redundant storage)",id:"one-node-etcd-backed-by-redundant-storage",level:4},{value:"RAM (tmpfs) etcd storage",id:"ram-tmpfs-etcd-storage",level:4},{value:"Heartbeat slowdown",id:"heartbeat-slowdown",level:4},{value:"Filesystem tuning",id:"filesystem-tuning",level:4},{value:"Flavors with local storage",id:"flavors-with-local-storage",level:4},{value:"Decision",id:"decision",level:2},{value:"Out of Scope",id:"out-of-scope",level:2},{value:"Implementation note",id:"implementation-note",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",p:"p",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,a.jsx)(t.p,{children:"SCS defines an IaaS Flavor Naming standard that mandates a number of standard flavors\nto be available in each SCS-compliant IaaS offering. While offering or exposing\nIaaS is not a requirement for SCS-compliant infrastructure offerings \u2014 SCS allows\nfor platforms only exposing the container layer (plus S3 compatible object storage)\nfor wave 2 (container-based) cloud-native workloads --\nthe SCS reference implementation does include a complete IaaS implementation that\nmany providers want to expose as they have customers desiring access at this layer\nfor wave 1 (VM-based) cloud-native workloads or for the virtualization of more\nclassical (not cloud-native) workloads. The IaaS implementation thus comes with\nstandards."}),"\n",(0,a.jsx)(t.p,{children:"This Decision Record is about adding a few mandatory flavors on the IaaS level\nthat include flavors with local SSD (or better) storage."}),"\n",(0,a.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0100-v2-flavor-naming.md",children:"currently defined standard flavors"}),"\ndo not include\nflavors that use local storage. For certain workloads such as databases or big data\nfilesystems, local storage is highly desirable as replication may be handled at\nthe application layer, making replication/redundancy in a networked storage solution\n(ceph in the SCS reference implementation) an unneeded and undesired property.\nFurthermore, write access to networked and replicated storage typically incurs\na certain latency, as the writes can only be acknowledged once all the replicas\nhave confirmed that the data has hit stable storage. Write latency is critical\nfor e.g. relational database performance."]}),"\n",(0,a.jsx)(t.p,{children:"The main purpose for the IaaS layer in SCS is to perform as a solid foundation\nto provide and manage kubernetes container clusters in a multi-tenant scenario.\nAs such the standards at the IaaS layer should ensure that all the needed\ntypes of resources are available for the container clusters. This is not\ncurrently the case: In a scenario with multiple k8s control-plane nodes set\nup via kubeadm (as part of the k8s cluster-api automation), the control plane\nnodes each run an etcd instance and together form an etcd cluster."}),"\n",(0,a.jsx)(t.p,{children:"etcd is sensitive to scheduling, network and storage latencies. While network\nlatencies and scheduling latencies have not been observed to be an issue in\nclusters within one cloud region, the storage latency is. With remote networked\nstorage as delivered from ceph, the long tail of write latency causes etcd\nto often time out heartbeats, causing a new leader election with a leader\nchange, preventing control plane changes on k8s for a few seconds. Too many\nleader changes can slow down cluster operation and even bring it to a halt."}),"\n",(0,a.jsxs)(t.p,{children:["The etcd requirements ",(0,a.jsx)(t.a,{href:"https://etcd.io/docs/v3.5/op-guide/hardware/#example-hardware-configurations",children:"are well documented"}),".\nIn particular, over a hundred of ",(0,a.jsx)(t.em,{children:"sequential"})," IOPS are recommended. This\nrequires write latencies in the range of a single-digit ms (or better)."]}),"\n",(0,a.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,a.jsx)(t.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,a.jsx)(t.h4,{id:"one-node-etcd-backed-by-redundant-storage",children:"One-node etcd (backed by redundant storage)"}),"\n",(0,a.jsx)(t.p,{children:"If k8s uses only one control plane node, there will only be only one etcd node,\navoiding timed out heartbeats. Single node control planes are typically not\nrecommended for production workloads though. They are limited with respect\nto control plane performance, have a higher chance to fail (as a single node failure\ncan create cluster control-plane downtime) and can not undergo rolling upgrades."}),"\n",(0,a.jsx)(t.p,{children:"Though not the normal setup with kubeadm, it is possible to use a multi-node\ncontrol plane using a single-node etcd. This shares some of the challenges of\nsingle-node control-planes, although recovery may be faster to perform at least\nin scenarios where the etcd backend storage is redundant and not affected by the\nsingle-node outage."}),"\n",(0,a.jsx)(t.p,{children:"Neither scenario fulfills typical requirements for production workloads."}),"\n",(0,a.jsx)(t.h4,{id:"ram-tmpfs-etcd-storage",children:"RAM (tmpfs) etcd storage"}),"\n",(0,a.jsx)(t.p,{children:"etcd could keep its database in volatile memory (e.g. on a tmpfs filesystem).\nFor multi-node etcd clusters, this could actually be made work, as long as at\nleast one cluster member stays alive and proper care is taken to remove shut-down\nnodes from the cluster. A loss of power affecting all nodes or a hardware\nmaintenance operation not tracking etcd needs would result in a complete\nloss of all cluster state. The control plane nodes would require live migration\nto avoid this in the maintenance case. For the power loss scenario, a frequent\nbackup might mitigate the cluster state loss case somewhat."}),"\n",(0,a.jsx)(t.p,{children:"The etcd database is normally limited to 2GiB in size, which is something\nthat is realistic to keep in main memory. (Typical database sizes are\nmuch smaller.)"}),"\n",(0,a.jsx)(t.p,{children:"This option requires additional care and may not be suitable for all\nproduction scenarios, but would seem a possible fallback position for\netcd. It does obviously not address the database scenario."}),"\n",(0,a.jsx)(t.h4,{id:"heartbeat-slowdown",children:"Heartbeat slowdown"}),"\n",(0,a.jsx)(t.p,{children:"To avoid causing too many fail-overs by occasional high latencies, the\nfrequency of heartbeats can be lowered from the default 1/100ms.\nThe reelection timeout should change along with it (typically set to\n10 beats)."}),"\n",(0,a.jsx)(t.p,{children:"This will cause etcd to take a bit more time to notice the loss of a node,\nwhich is not typically critical if done within reasonable limits.\nThis change however does not fully address the issue \u2014 occasional write latencies\nabove 100ms will still cause failed heartbeats, just less often."}),"\n",(0,a.jsxs)(t.p,{children:["This change has been implemented in SCS's\n",(0,a.jsx)(t.a,{href:"https://etcd.io/docs/v3.5/op-guide/hardware/#example-hardware-configurations",children:"k8s-cluster-api-provider"}),"\nreference implementation: The heartbeat has been changed from 1/100ms (10/s)\nto 1/250ms (4/s) and the reelection timeout from 1s to 2.5s."]}),"\n",(0,a.jsx)(t.p,{children:"The etcd process also is afforded a higher CPU priority (lower niceness),\nresulting in a lower scheduling latency, as high-prio processes preempt lower-prio\nones when they get woken up. The etcd process also gets its IO priority\nincreased to get treated preferentially in case the IO scheduler has many\noutstanding requests. This has some positive effects with the CFQ IO scheduler."}),"\n",(0,a.jsx)(t.p,{children:"The slower heartbeat and the priority tweaks do lower the amount of leader\nchanges but are insufficient to completely address the issue on the tests\nperformed against networked ceph-backed storage."}),"\n",(0,a.jsx)(t.h4,{id:"filesystem-tuning",children:"Filesystem tuning"}),"\n",(0,a.jsxs)(t.p,{children:["Databases must ensure that certain data has hit stable storage before acknowledging\nwrites \u2014 this is required in order to live up to the ",(0,a.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/ACID",children:"ACID"}),"\nguarantees in situations when disruptions might happen. Databases typically use\n",(0,a.jsx)(t.code,{children:"fsync()"})," calls to ensure that write buffers are written to real persistent storage\nunless they use raw/direct block devices circumventing Linux's page and buffer cache."]}),"\n",(0,a.jsxs)(t.p,{children:["etcd normally uses a write-ahead-log (WOL) file that lives on a Linux filesystem and\nuses ",(0,a.jsx)(t.code,{children:"fsync"})," to ensure the correct write ordering. Trouble with fsync is that it\nalso causes unrelated data to be written out with most existing Linux filesystems,\nadding to the latency."]}),"\n",(0,a.jsxs)(t.p,{children:["It is possible to tell the Linux filesystems to not wait for all data to have hit\nstorage before returning from fsync() calls. This avoids the latency caused by\n",(0,a.jsx)(t.code,{children:"fsync"})," but also subverts the very reason for using ",(0,a.jsx)(t.code,{children:"fsync"}),": In case of a disruption\n(OS crash, power outage, loss of connection to storage, ...), the state is likely\nnot consistent, as the kernel has lied to the application about data having been\nwritten out. Recovery from such a scenario can range from smooth to impossible."]}),"\n",(0,a.jsx)(t.p,{children:"In a multi-node cluster, this may not be as bad as it sounds \u2014 if only one\nnode is affected by a disruption, the crashed node can be recovered by resyncing\nthe data from other nodes. In practice an inconsistent state would be considered\ntoo risky and it should be preferred to set up a fresh node to join the\nexisting etcd cluster. This would need to be implemented to make this option\nless risky."}),"\n",(0,a.jsx)(t.p,{children:"The reference implementation has an option to use these unsafe filesystem settings.\nHowever, they are not enabled by default for good reasons."}),"\n",(0,a.jsx)(t.h4,{id:"flavors-with-local-storage",children:"Flavors with local storage"}),"\n",(0,a.jsx)(t.p,{children:"Flavors with local storage will have their root filesystem on a local storage\ndevice. To fulfill the need for high IOPS that etcd and especially databases\nhave, the local storage device should be a solid state device \u2014 an SSD or\nNVMe device. While some use cases might even be fulfilled with local\nspinning disks (or raid arrays of local spinning disks)."}),"\n",(0,a.jsx)(t.p,{children:"Local solid state storage avoids any network overhead and offers best latency.\nIt however is not typically redundant, meaning that the loss of the device\nor the complete hardware node will result in data loss. So it is meant to\nbe used with applications such as database clusters, replicating filesystems\nor block devices or etcd which can handle this at the application layer."}),"\n",(0,a.jsx)(t.p,{children:"The flavor naming spec in SCS allows performance to be understated \u2014 a\nflavor with NVMe storage can be advertised under the SSD storage name\n(and of course can be offered under both names)."}),"\n",(0,a.jsx)(t.p,{children:"Note that this addresses the simple case where the root disk with the\nroot filesystem (and possibly additional filesystems that are set up\nwhen first booting) uses the local storage. Scenarios where additional\nlow-latency networked or local storage are made available via cinder\nand attached for database storage are possible and viable options for\nsome scenarios, but not covered here."}),"\n",(0,a.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,a.jsxs)(t.p,{children:["Two new mandatory flavors: ",(0,a.jsx)(t.code,{children:"SCS-2V-4-20s"})," and ",(0,a.jsx)(t.code,{children:"SCS-4V-16-100s"})," are added\nto the SCS flavor naming standard. The first is meant to be a good fit for\nk8s control nodes with etcd while the latter is a solid base for a\nsmall database server. Clouds claiming SCS-compliance for their IaaS\nlayer MUST provide these two additional flavors."]}),"\n",(0,a.jsx)(t.p,{children:"Obviously providers MAY offer many more combinations and e.g. create\nflavors with large local SSDs."}),"\n",(0,a.jsxs)(t.p,{children:["The local storage advertised this way MUST support more than\n1000 ",(0,a.jsx)(t.em,{children:"sequential"})," IOPS per VM of both new mandatory types (which means a\nwrite latency lower than 1ms \u2014 this typically means SSDs/NVMEs that\nsupport at least several 10ks of parallel IOPS, not a challenge for\ncurrent hardware)."]}),"\n",(0,a.jsx)(t.p,{children:"Local disks, SSDs, NVMes MUST have Power-Loss-Protection such that\ndata reported to be written, but in reality being stored in RAM or SLC\ncache of an SSD or NVMe, is guaranteed to not be lost in case of a power\nloss."}),"\n",(0,a.jsx)(t.p,{children:"Like with networked storage, the provider must ensure that data\nfrom previous users is not accessible (e.g. by securely erasing it\nor by using a different encryption key) when local storage gets\nallocated to a new VM."}),"\n",(0,a.jsx)(t.h2,{id:"out-of-scope",children:"Out of Scope"}),"\n",(0,a.jsx)(t.p,{children:"Hardware nodes (hypervisors in OpenStack language) that support flavors\nwith local storage (are part of an appropriate OpenStack host aggregate)\nmay have many VMs competing for bandwidth to the attached local storage\ndevices; the host needs to be configured such that it can sustain VMs\nwriting at full speed without causing the host to be overloaded or\nto cause huge queues for these writes."}),"\n",(0,a.jsx)(t.p,{children:"A more generic approach is to apply storage QoS policies to the VMs to\nmanage bandwidth and IOPS and create the ability to have better\nperformance isolation with certain guarantees. While this is desirable,\nit has not been found a necessity for etcd in our tests.\nDisk IO QoS is not part of this spec but may be considered in another one."}),"\n",(0,a.jsx)(t.p,{children:"Live-migration with local storage is significantly more difficult than with\nnetworked storage: The contents of the local disks also need to be replicated\nover to the new host. Live-migration for these VMs may thus take significantly\nlonger or not be possible at all, depending the configuration from the provider.\nNot supporting live-migration is OK for flavors with local disks according\nto the flavor naming spec \u2014 a capability to indicate whether or not\nlive-migration is supported will be subject to a flavor-metadata discoverability\nspec that is planned for the future."}),"\n",(0,a.jsx)(t.h2,{id:"implementation-note",children:"Implementation note"}),"\n",(0,a.jsx)(t.p,{children:"Local storage in OpenStack can be provided directly via nova or via the\ncinder service. While the latter has the advantage of making volumes\nvisible and manageable via most of the normal cinder capabilities, it\nhas the disadvantage of creating an indirection via iSCSI. This\nresults in higher latency. The requirements in the above spec are\nnot meant to mandate or prevent the implementation via either route."}),"\n",(0,a.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,a.jsxs)(t.p,{children:["The flavors will be added as mandatory flavors to the\n",(0,a.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0100-v2-flavor-naming.md",children:"flavor-naming standard"}),",\nwhich will thus have to be released in a v3."]}),"\n",(0,a.jsxs)(t.p,{children:["The IOPS and Power-Loss requirements from this decision should become\npart of the flavor-naming standard for disk type ",(0,a.jsx)(t.code,{children:"s"}),"."]}),"\n",(0,a.jsx)(t.p,{children:"When we standardize storage types in the future, additional possibilities\nto solve the latency requirements for databases and etcd may emerge."}),"\n",(0,a.jsx)(t.p,{children:"When we standardize QoS features there, we may amend this standard with\nQoS recommendations or possibly requirements."}),"\n",(0,a.jsx)(t.p,{children:"A future flavor metadata discoverability standard will indicate whether or not\nthese flavors can be live-migrated. A future VM metadata standard will allow\nusers to request live-migration and/or cold migration or restart to be or to\nnot be performed."}),"\n",(0,a.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,a.jsxs)(t.p,{children:["The list of mandatory flavors that needs to be present should be added to the\n",(0,a.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/SCS-Spec.MandatoryFlavors.yaml",children:"SCS-Spec.MandatoryFlavors.yaml"}),"\nspec as soon as this ADR becomes part of the certification requirements."]}),"\n",(0,a.jsx)(t.p,{children:"Checks for conforming with IOPS and purging requirements will require\ntest instances to be launched and might become part of a monitoring\nsolution."})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var a=n(96540);const s={},o=a.createContext(s);function i(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1169.d139adc3.js b/assets/js/1169.d139adc3.js new file mode 100644 index 0000000000..eece539612 --- /dev/null +++ b/assets/js/1169.d139adc3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1169],{73046:(t,e,r)=>{r.d(e,{T:()=>k});var n=r(48585),o=r(39142),i=r(89610),s=r(27422),u=r(11662),c=r(66401),a=r(8058),f=r(69592),h=r(13588),A=r(24326),d=r(62062),l=r(25707);const v=function(t){return t!=t};const b=function(t,e,r){for(var n=r-1,o=t.length;++n-1};const g=function(t,e,r){for(var n=-1,o=null==t?0:t.length;++n=200){var a=e?null:C(t);if(a)return(0,w.A)(a);s=!1,o=j.A,c=new d.A}else c=e?[]:u;t:for(;++n1?n.setNode(t,e):n.setNode(t)})),this}setNode(t,e){return n.A(this._nodes,t)?(arguments.length>1&&(this._nodes[t]=e),this):(this._nodes[t]=arguments.length>1?e:this._defaultNodeLabelFn(t),this._isCompound&&(this._parent[t]=P,this._children[t]={},this._children[P][t]=!0),this._in[t]={},this._preds[t]={},this._out[t]={},this._sucs[t]={},++this._nodeCount,this)}node(t){return this._nodes[t]}hasNode(t){return n.A(this._nodes,t)}removeNode(t){var e=this;if(n.A(this._nodes,t)){var r=function(t){e.removeEdge(e._edgeObjs[t])};delete this._nodes[t],this._isCompound&&(this._removeFromParentsChildList(t),delete this._parent[t],a.A(this.children(t),(function(t){e.setParent(t)})),delete this._children[t]),a.A(s.A(this._in[t]),r),delete this._in[t],delete this._preds[t],a.A(s.A(this._out[t]),r),delete this._out[t],delete this._sucs[t],--this._nodeCount}return this}setParent(t,e){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(f.A(e))e=P;else{for(var r=e+="";!f.A(r);r=this.parent(r))if(r===t)throw new Error("Setting "+e+" as parent of "+t+" would create a cycle");this.setNode(e)}return this.setNode(t),this._removeFromParentsChildList(t),this._parent[t]=e,this._children[e][t]=!0,this}_removeFromParentsChildList(t){delete this._children[this._parent[t]][t]}parent(t){if(this._isCompound){var e=this._parent[t];if(e!==P)return e}}children(t){if(f.A(t)&&(t=P),this._isCompound){var e=this._children[t];if(e)return s.A(e)}else{if(t===P)return this.nodes();if(this.hasNode(t))return[]}}predecessors(t){var e=this._preds[t];if(e)return s.A(e)}successors(t){var e=this._sucs[t];if(e)return s.A(e)}neighbors(t){var e=this.predecessors(t);if(e)return N(e,this.successors(t))}isLeaf(t){return 0===(this.isDirected()?this.successors(t):this.neighbors(t)).length}filterNodes(t){var e=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});e.setGraph(this.graph());var r=this;a.A(this._nodes,(function(r,n){t(n)&&e.setNode(n,r)})),a.A(this._edgeObjs,(function(t){e.hasNode(t.v)&&e.hasNode(t.w)&&e.setEdge(t,r.edge(t))}));var n={};function o(t){var i=r.parent(t);return void 0===i||e.hasNode(i)?(n[t]=i,i):i in n?n[i]:o(i)}return this._isCompound&&a.A(e.nodes(),(function(t){e.setParent(t,o(t))})),e}setDefaultEdgeLabel(t){return i.A(t)||(t=o.A(t)),this._defaultEdgeLabelFn=t,this}edgeCount(){return this._edgeCount}edges(){return D.A(this._edgeObjs)}setPath(t,e){var r=this,n=arguments;return S.A(t,(function(t,o){return n.length>1?r.setEdge(t,o,e):r.setEdge(t,o),o})),this}setEdge(){var t,e,r,o,i=!1,s=arguments[0];"object"==typeof s&&null!==s&&"v"in s?(t=s.v,e=s.w,r=s.name,2===arguments.length&&(o=arguments[1],i=!0)):(t=s,e=arguments[1],r=arguments[3],arguments.length>2&&(o=arguments[2],i=!0)),t=""+t,e=""+e,f.A(r)||(r=""+r);var u=U(this._isDirected,t,e,r);if(n.A(this._edgeLabels,u))return i&&(this._edgeLabels[u]=o),this;if(!f.A(r)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(t),this.setNode(e),this._edgeLabels[u]=i?o:this._defaultEdgeLabelFn(t,e,r);var c=function(t,e,r,n){var o=""+e,i=""+r;if(!t&&o>i){var s=o;o=i,i=s}var u={v:o,w:i};n&&(u.name=n);return u}(this._isDirected,t,e,r);return t=c.v,e=c.w,Object.freeze(c),this._edgeObjs[u]=c,x(this._preds[e],t),x(this._sucs[t],e),this._in[e][u]=c,this._out[t][u]=c,this._edgeCount++,this}edge(t,e,r){var n=1===arguments.length?z(this._isDirected,arguments[0]):U(this._isDirected,t,e,r);return this._edgeLabels[n]}hasEdge(t,e,r){var o=1===arguments.length?z(this._isDirected,arguments[0]):U(this._isDirected,t,e,r);return n.A(this._edgeLabels,o)}removeEdge(t,e,r){var n=1===arguments.length?z(this._isDirected,arguments[0]):U(this._isDirected,t,e,r),o=this._edgeObjs[n];return o&&(t=o.v,e=o.w,delete this._edgeLabels[n],delete this._edgeObjs[n],I(this._preds[e],t),I(this._sucs[t],e),delete this._in[e][n],delete this._out[t][n],this._edgeCount--),this}inEdges(t,e){var r=this._in[t];if(r){var n=D.A(r);return e?u.A(n,(function(t){return t.v===e})):n}}outEdges(t,e){var r=this._out[t];if(r){var n=D.A(r);return e?u.A(n,(function(t){return t.w===e})):n}}nodeEdges(t,e){var r=this.inEdges(t,e);if(r)return r.concat(this.outEdges(t,e))}}function x(t,e){t[e]?t[e]++:t[e]=1}function I(t,e){--t[e]||delete t[e]}function U(t,e,r,n){var o=""+e,i=""+r;if(!t&&o>i){var s=o;o=i,i=s}return o+M+i+M+(f.A(n)?F:n)}function z(t,e){return U(t,e.v,e.w,e.name)}k.prototype._nodeCount=0,k.prototype._edgeCount=0},697:(t,e,r)=>{r.d(e,{T:()=>n.T});var n=r(73046)},62062:(t,e,r)=>{r.d(e,{A:()=>u});var n=r(29471);const o=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this};const i=function(t){return this.__data__.has(t)};function s(t){var e=-1,r=null==t?0:t.length;for(this.__data__=new n.A;++e{r.d(e,{A:()=>n});const n=function(t,e){for(var r=-1,n=null==t?0:t.length;++r{r.d(e,{A:()=>n});const n=function(t,e){for(var r=-1,n=null==t?0:t.length,o=0,i=[];++r{r.d(e,{A:()=>n});const n=function(t,e){for(var r=-1,n=null==t?0:t.length,o=Array(n);++r{r.d(e,{A:()=>n});const n=function(t,e){for(var r=-1,n=e.length,o=t.length;++r{r.d(e,{A:()=>Z});var n=r(11754),o=r(72641),i=r(52851),s=r(22031),u=r(27422);const c=function(t,e){return t&&(0,s.A)(e,(0,u.A)(e),t)};var a=r(55615);const f=function(t,e){return t&&(0,s.A)(e,(0,a.A)(e),t)};var h=r(80154),A=r(39759),d=r(14792);const l=function(t,e){return(0,s.A)(t,(0,d.A)(t),e)};var v=r(76912),b=r(15647),_=r(13153);const p=Object.getOwnPropertySymbols?function(t){for(var e=[];t;)(0,v.A)(e,(0,d.A)(t)),t=(0,b.A)(t);return e}:_.A;const g=function(t,e){return(0,s.A)(t,p(t),e)};var j=r(19042),y=r(33831);const m=function(t){return(0,y.A)(t,a.A,p)};var w=r(9779),O=Object.prototype.hasOwnProperty;const C=function(t){var e=t.length,r=new t.constructor(e);return e&&"string"==typeof t[0]&&O.call(t,"index")&&(r.index=t.index,r.input=t.input),r};var E=r(90565);const L=function(t,e){var r=e?(0,E.A)(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.byteLength)};var N=/\w*$/;const D=function(t){var e=new t.constructor(t.source,N.exec(t));return e.lastIndex=t.lastIndex,e};var S=r(241),F=S.A?S.A.prototype:void 0,P=F?F.valueOf:void 0;const M=function(t){return P?Object(P.call(t)):{}};var k=r(1801);const x=function(t,e,r){var n=t.constructor;switch(e){case"[object ArrayBuffer]":return(0,E.A)(t);case"[object Boolean]":case"[object Date]":return new n(+t);case"[object DataView]":return L(t,r);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return(0,k.A)(t,r);case"[object Map]":case"[object Set]":return new n;case"[object Number]":case"[object String]":return new n(t);case"[object RegExp]":return D(t);case"[object Symbol]":return M(t)}};var I=r(18598),U=r(92049),z=r(99912),B=r(53098);const $=function(t){return(0,B.A)(t)&&"[object Map]"==(0,w.A)(t)};var G=r(52789),R=r(64841),T=R.A&&R.A.isMap;const V=T?(0,G.A)(T):$;var W=r(23149);const q=function(t){return(0,B.A)(t)&&"[object Set]"==(0,w.A)(t)};var H=R.A&&R.A.isSet;const J=H?(0,G.A)(H):q;var K="[object Arguments]",Q="[object Function]",X="[object Object]",Y={};Y[K]=Y["[object Array]"]=Y["[object ArrayBuffer]"]=Y["[object DataView]"]=Y["[object Boolean]"]=Y["[object Date]"]=Y["[object Float32Array]"]=Y["[object Float64Array]"]=Y["[object Int8Array]"]=Y["[object Int16Array]"]=Y["[object Int32Array]"]=Y["[object Map]"]=Y["[object Number]"]=Y[X]=Y["[object RegExp]"]=Y["[object Set]"]=Y["[object String]"]=Y["[object Symbol]"]=Y["[object Uint8Array]"]=Y["[object Uint8ClampedArray]"]=Y["[object Uint16Array]"]=Y["[object Uint32Array]"]=!0,Y["[object Error]"]=Y[Q]=Y["[object WeakMap]"]=!1;const Z=function t(e,r,s,d,v,b){var _,p=1&r,y=2&r,O=4&r;if(s&&(_=v?s(e,d,v,b):s(e)),void 0!==_)return _;if(!(0,W.A)(e))return e;var E=(0,U.A)(e);if(E){if(_=C(e),!p)return(0,A.A)(e,_)}else{var L=(0,w.A)(e),N=L==Q||"[object GeneratorFunction]"==L;if((0,z.A)(e))return(0,h.A)(e,p);if(L==X||L==K||N&&!v){if(_=y||N?{}:(0,I.A)(e),!p)return y?g(e,f(_,e)):l(e,c(_,e))}else{if(!Y[L])return v?e:{};_=x(e,L,p)}}b||(b=new n.A);var D=b.get(e);if(D)return D;b.set(e,_),J(e)?e.forEach((function(n){_.add(t(n,r,s,n,e,b))})):V(e)&&e.forEach((function(n,o){_.set(o,t(n,r,s,o,e,b))}));var S=O?y?m:j.A:y?a.A:u.A,F=E?void 0:S(e);return(0,o.A)(F||e,(function(n,o){F&&(n=e[o=n]),(0,i.A)(_,o,t(n,r,s,o,e,b))})),_}},6240:(t,e,r)=>{r.d(e,{A:()=>i});var n=r(79841),o=r(38446);const i=function(t,e){return function(r,n){if(null==r)return r;if(!(0,o.A)(r))return t(r,n);for(var i=r.length,s=e?i:-1,u=Object(r);(e?s--:++s{r.d(e,{A:()=>n});const n=function(t,e,r,n){for(var o=t.length,i=r+(n?1:-1);n?i--:++i{r.d(e,{A:()=>a});var n=r(76912),o=r(241),i=r(52274),s=r(92049),u=o.A?o.A.isConcatSpreadable:void 0;const c=function(t){return(0,s.A)(t)||(0,i.A)(t)||!!(u&&t&&t[u])};const a=function t(e,r,o,i,s){var u=-1,a=e.length;for(o||(o=c),s||(s=[]);++u0&&o(f)?r>1?t(f,r-1,o,i,s):(0,n.A)(s,f):i||(s[s.length]=f)}return s}},79841:(t,e,r)=>{r.d(e,{A:()=>i});var n=r(4574),o=r(27422);const i=function(t,e){return t&&(0,n.A)(t,e,o.A)}},66318:(t,e,r)=>{r.d(e,{A:()=>i});var n=r(7819),o=r(30901);const i=function(t,e){for(var r=0,i=(e=(0,n.A)(e,t)).length;null!=t&&r{r.d(e,{A:()=>i});var n=r(76912),o=r(92049);const i=function(t,e,r){var i=e(t);return(0,o.A)(t)?i:(0,n.A)(i,r(t))}},49574:(t,e,r)=>{r.d(e,{A:()=>H});var n=r(11754),o=r(62062);const i=function(t,e){for(var r=-1,n=null==t?0:t.length;++rf))return!1;var A=c.get(t),d=c.get(e);if(A&&d)return A==e&&d==t;var l=-1,v=!0,b=2&r?new o.A:void 0;for(c.set(t,e),c.set(e,t);++l{r.d(e,{A:()=>n});const n=function(t){return function(e){return null==e?void 0:e[t]}}},64099:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(t,e){return t.has(e)}},99922:(t,e,r)=>{r.d(e,{A:()=>o});var n=r(29008);const o=function(t){return"function"==typeof t?t:n.A}},7819:(t,e,r)=>{r.d(e,{A:()=>f});var n=r(92049),o=r(86586),i=r(46632);var s=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,u=/\\(\\)?/g;const c=function(t){var e=(0,i.A)(t,(function(t){return 500===r.size&&r.clear(),t})),r=e.cache;return e}((function(t){var e=[];return 46===t.charCodeAt(0)&&e.push(""),t.replace(s,(function(t,r,n,o){e.push(n?o.replace(u,"$1"):r||t)})),e}));var a=r(28894);const f=function(t,e){return(0,n.A)(t)?t:(0,o.A)(t,e)?[t]:c((0,a.A)(t))}},19042:(t,e,r)=>{r.d(e,{A:()=>s});var n=r(33831),o=r(14792),i=r(27422);const s=function(t){return(0,n.A)(t,i.A,o.A)}},14792:(t,e,r)=>{r.d(e,{A:()=>u});var n=r(2634),o=r(13153),i=Object.prototype.propertyIsEnumerable,s=Object.getOwnPropertySymbols;const u=s?function(t){return null==t?[]:(t=Object(t),(0,n.A)(s(t),(function(e){return i.call(t,e)})))}:o.A},85054:(t,e,r)=>{r.d(e,{A:()=>a});var n=r(7819),o=r(52274),i=r(92049),s=r(25353),u=r(5254),c=r(30901);const a=function(t,e,r){for(var a=-1,f=(e=(0,n.A)(e,t)).length,h=!1;++a{r.d(e,{A:()=>u});var n=r(92049),o=r(61882),i=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,s=/^\w*$/;const u=function(t,e){if((0,n.A)(t))return!1;var r=typeof t;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=t&&!(0,o.A)(t))||(s.test(t)||!i.test(t)||null!=e&&t in Object(e))}},29959:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(t){var e=-1,r=Array(t.size);return t.forEach((function(t){r[++e]=t})),r}},30901:(t,e,r)=>{r.d(e,{A:()=>o});var n=r(61882);const o=function(t){if("string"==typeof t||(0,n.A)(t))return t;var e=t+"";return"0"==e&&1/t==-1/0?"-0":e}},11662:(t,e,r)=>{r.d(e,{A:()=>c});var n=r(2634),o=r(6240);const i=function(t,e){var r=[];return(0,o.A)(t,(function(t,n,o){e(t,n,o)&&r.push(t)})),r};var s=r(49574),u=r(92049);const c=function(t,e){return((0,u.A)(t)?n.A:i)(t,(0,s.A)(e,3))}},8058:(t,e,r)=>{r.d(e,{A:()=>u});var n=r(72641),o=r(6240),i=r(99922),s=r(92049);const u=function(t,e){return((0,s.A)(t)?n.A:o.A)(t,(0,i.A)(e))}},48585:(t,e,r)=>{r.d(e,{A:()=>s});var n=Object.prototype.hasOwnProperty;const o=function(t,e){return null!=t&&n.call(t,e)};var i=r(85054);const s=function(t,e){return null!=t&&(0,i.A)(t,e,o)}},39188:(t,e,r)=>{r.d(e,{A:()=>i});const n=function(t,e){return null!=t&&e in Object(t)};var o=r(85054);const i=function(t,e){return null!=t&&(0,o.A)(t,e,n)}},61882:(t,e,r)=>{r.d(e,{A:()=>i});var n=r(88496),o=r(53098);const i=function(t){return"symbol"==typeof t||(0,o.A)(t)&&"[object Symbol]"==(0,n.A)(t)}},69592:(t,e,r)=>{r.d(e,{A:()=>n});const n=function(t){return void 0===t}},27422:(t,e,r)=>{r.d(e,{A:()=>s});var n=r(83607),o=r(69471),i=r(38446);const s=function(t){return(0,i.A)(t)?(0,n.A)(t):(0,o.A)(t)}},89463:(t,e,r)=>{r.d(e,{A:()=>c});const n=function(t,e,r,n){var o=-1,i=null==t?0:t.length;for(n&&i&&(r=t[++o]);++o{r.d(e,{A:()=>n});const n=function(){return[]}},28894:(t,e,r)=>{r.d(e,{A:()=>f});var n=r(241),o=r(45572),i=r(92049),s=r(61882),u=n.A?n.A.prototype:void 0,c=u?u.toString:void 0;const a=function t(e){if("string"==typeof e)return e;if((0,i.A)(e))return(0,o.A)(e,t)+"";if((0,s.A)(e))return c?c.call(e):"";var r=e+"";return"0"==r&&1/e==-1/0?"-0":r};const f=function(t){return null==t?"":a(t)}},38207:(t,e,r)=>{r.d(e,{A:()=>s});var n=r(45572);const o=function(t,e){return(0,n.A)(e,(function(e){return t[e]}))};var i=r(27422);const s=function(t){return null==t?[]:o(t,(0,i.A)(t))}}}]); \ No newline at end of file diff --git a/assets/js/1176.dc521de4.js b/assets/js/1176.dc521de4.js new file mode 100644 index 0000000000..14d5acc3b1 --- /dev/null +++ b/assets/js/1176.dc521de4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1176],{21176:(n,e,r)=>{r.d(e,{Zp:()=>Ce});var t=r(8058),o=r(5664),i=r(48585),u=r(39142),a=r(34098),d=r(74722),c=r(91395),f=r(697);class s{constructor(){var n={};n._next=n._prev=n,this._sentinel=n}dequeue(){var n=this._sentinel,e=n._prev;if(e!==n)return v(e),e}enqueue(n){var e=this._sentinel;n._prev&&n._next&&v(n),n._next=e._next,e._next._prev=n,e._next=n,n._prev=e}toString(){for(var n=[],e=this._sentinel,r=e._prev;r!==e;)n.push(JSON.stringify(r,g)),r=r._prev;return"["+n.join(", ")+"]"}}function v(n){n._prev._next=n._next,n._next._prev=n._prev,delete n._next,delete n._prev}function g(n,e){if("_next"!==n&&"_prev"!==n)return e}var h=u.A(1);function l(n,e){if(n.nodeCount()<=1)return[];var r=function(n,e){var r=new f.T,o=0,i=0;t.A(n.nodes(),(function(n){r.setNode(n,{v:n,in:0,out:0})})),t.A(n.edges(),(function(n){var t=r.edge(n.v,n.w)||0,u=e(n),a=t+u;r.setEdge(n.v,n.w,a),i=Math.max(i,r.node(n.v).out+=u),o=Math.max(o,r.node(n.w).in+=u)}));var u=c.A(i+o+3).map((function(){return new s})),a=o+1;return t.A(r.nodes(),(function(n){p(u,a,r.node(n))})),{graph:r,buckets:u,zeroIdx:a}}(n,e||h),o=function(n,e,r){var t,o=[],i=e[e.length-1],u=e[0];for(;n.nodeCount();){for(;t=u.dequeue();)A(n,e,r,t);for(;t=i.dequeue();)A(n,e,r,t);if(n.nodeCount())for(var a=e.length-2;a>0;--a)if(t=e[a].dequeue()){o=o.concat(A(n,e,r,t,!0));break}}return o}(r.graph,r.buckets,r.zeroIdx);return a.A(d.A(o,(function(e){return n.outEdges(e.v,e.w)})))}function A(n,e,r,o,i){var u=i?[]:void 0;return t.A(n.inEdges(o.v),(function(t){var o=n.edge(t),a=n.node(t.v);i&&u.push({v:t.v,w:t.w}),a.out-=o,p(e,r,a)})),t.A(n.outEdges(o.v),(function(t){var o=n.edge(t),i=t.w,u=n.node(i);u.in-=o,p(e,r,u)})),n.removeNode(o.v),u}function p(n,e,r){r.out?r.in?n[r.out-r.in+e].enqueue(r):n[n.length-1].enqueue(r):n[0].enqueue(r)}function w(n){var e="greedy"===n.graph().acyclicer?l(n,function(n){return function(e){return n.edge(e).weight}}(n)):function(n){var e=[],r={},o={};function u(a){i.A(o,a)||(o[a]=!0,r[a]=!0,t.A(n.outEdges(a),(function(n){i.A(r,n.w)?e.push(n):u(n.w)})),delete r[a])}return t.A(n.nodes(),u),e}(n);t.A(e,(function(e){var r=n.edge(e);n.removeEdge(e),r.forwardName=e.name,r.reversed=!0,n.setEdge(e.w,e.v,r,o.A("rev"))}))}var m=r(98879),b=r(81942),y=r(23068),x=r(61882);const k=function(n,e,r){for(var t=-1,o=n.length;++te};var N=r(29008);const _=function(n){return n&&n.length?k(n,N.A,E):void 0};const I=function(n){var e=null==n?0:n.length;return e?n[e-1]:void 0};var T=r(52528),R=r(79841),M=r(49574);const L=function(n,e){var r={};return e=(0,M.A)(e,3),(0,R.A)(n,(function(n,t,o){(0,T.A)(r,t,e(n,t,o))})),r};var C=r(69592);const O=function(n,e){return nMath.abs(u)*c?(a<0&&(c=-c),r=c*u/a,t=c):(u<0&&(d=-d),r=d,t=d*a/u),{x:o+r,y:i+t}}function B(n){var e=d.A(c.A(Y(n)+1),(function(){return[]}));return t.A(n.nodes(),(function(r){var t=n.node(r),o=t.rank;C.A(o)||(e[o][t.order]=r)})),e}function q(n,e,r,t){var o={width:0,height:0};return arguments.length>=4&&(o.rank=r,o.order=t),F(n,"border",o,e)}function Y(n){return _(d.A(n.nodes(),(function(e){var r=n.node(e).rank;if(!C.A(r))return r})))}function z(n,e){var r=j();try{return e()}finally{console.log(n+" time: "+(j()-r)+"ms")}}function D(n,e){return e()}function $(n,e,r,t,o,i){var u={width:0,height:0,rank:i,borderType:e},a=o[e][i-1],d=F(n,"border",u,r);o[e][i]=d,n.setParent(d,t),a&&n.setEdge(a,d,{weight:1})}function J(n){var e=n.graph().rankdir.toLowerCase();"bt"!==e&&"rl"!==e||function(n){t.A(n.nodes(),(function(e){K(n.node(e))})),t.A(n.edges(),(function(e){var r=n.edge(e);t.A(r.points,K),i.A(r,"y")&&K(r)}))}(n),"lr"!==e&&"rl"!==e||(!function(n){t.A(n.nodes(),(function(e){Q(n.node(e))})),t.A(n.edges(),(function(e){var r=n.edge(e);t.A(r.points,Q),i.A(r,"x")&&Q(r)}))}(n),Z(n))}function Z(n){t.A(n.nodes(),(function(e){H(n.node(e))})),t.A(n.edges(),(function(e){H(n.edge(e))}))}function H(n){var e=n.width;n.width=n.height,n.height=e}function K(n){n.y=-n.y}function Q(n){var e=n.x;n.x=n.y,n.y=e}function U(n){n.graph().dummyChains=[],t.A(n.edges(),(function(e){!function(n,e){var r,t,o,i=e.v,u=n.node(i).rank,a=e.w,d=n.node(a).rank,c=e.name,f=n.edge(e),s=f.labelRank;if(d===u+1)return;for(n.removeEdge(e),o=0,++u;u-1?o[i?e[u]:u]:void 0}};var cn=r(25707),fn=r(74342);const sn=function(n){var e=(0,fn.A)(n),r=e%1;return e==e?r?e-r:e:0};var vn=Math.max;const gn=dn((function(n,e,r){var t=null==n?0:n.length;if(!t)return-1;var o=null==r?0:sn(r);return o<0&&(o=vn(t+o,0)),(0,cn.A)(n,(0,M.A)(e,3),o)}));var hn=r(11662);u.A(1);u.A(1);r(69471),r(9779),r(88496);var ln=r(92049);r(53098);(0,r(70805).A)("length");RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]");var An="\\ud800-\\udfff",pn="["+An+"]",wn="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",mn="\\ud83c[\\udffb-\\udfff]",bn="[^"+An+"]",yn="(?:\\ud83c[\\udde6-\\uddff]){2}",xn="[\\ud800-\\udbff][\\udc00-\\udfff]",kn="(?:"+wn+"|"+mn+")"+"?",En="[\\ufe0e\\ufe0f]?",Nn=En+kn+("(?:\\u200d(?:"+[bn,yn,xn].join("|")+")"+En+kn+")*"),_n="(?:"+[bn+wn+"?",wn,yn,xn,pn].join("|")+")";RegExp(mn+"(?="+mn+")|"+_n+Nn,"g");function In(){}function Tn(n,e,r){ln.A(e)||(e=[e]);var o=(n.isDirected()?n.successors:n.neighbors).bind(n),i=[],u={};return t.A(e,(function(e){if(!n.hasNode(e))throw new Error("Graph does not have node: "+e);Rn(n,e,"post"===r,u,o,i)})),i}function Rn(n,e,r,o,u,a){i.A(o,e)||(o[e]=!0,r||a.push(e),t.A(u(e),(function(e){Rn(n,e,r,o,u,a)})),r&&a.push(e))}In.prototype=new Error;r(73046);function Mn(n){n=function(n){var e=(new f.T).setGraph(n.graph());return t.A(n.nodes(),(function(r){e.setNode(r,n.node(r))})),t.A(n.edges(),(function(r){var t=e.edge(r.v,r.w)||{weight:0,minlen:1},o=n.edge(r);e.setEdge(r.v,r.w,{weight:t.weight+o.weight,minlen:Math.max(t.minlen,o.minlen)})})),e}(n),X(n);var e,r=en(n);for(On(r),Ln(r,n);e=Sn(r);)Fn(r,n,e,jn(r,n,e))}function Ln(n,e){var r=function(n,e){return Tn(n,e,"post")}(n,n.nodes());r=r.slice(0,r.length-1),t.A(r,(function(r){!function(n,e,r){var t=n.node(r),o=t.parent;n.edge(r,o).cutvalue=Cn(n,e,r)}(n,e,r)}))}function Cn(n,e,r){var o=n.node(r).parent,i=!0,u=e.edge(r,o),a=0;return u||(i=!1,u=e.edge(o,r)),a=u.weight,t.A(e.nodeEdges(r),(function(t){var u,d,c=t.v===r,f=c?t.w:t.v;if(f!==o){var s=c===i,v=e.edge(t).weight;if(a+=s?v:-v,u=r,d=f,n.hasEdge(u,d)){var g=n.edge(r,f).cutvalue;a+=s?-g:g}}})),a}function On(n,e){arguments.length<2&&(e=n.nodes()[0]),Pn(n,{},1,e)}function Pn(n,e,r,o,u){var a=r,d=n.node(o);return e[o]=!0,t.A(n.neighbors(o),(function(t){i.A(e,t)||(r=Pn(n,e,r,t,o))})),d.low=a,d.lim=r++,u?d.parent=u:delete d.parent,r}function Sn(n){return gn(n.edges(),(function(e){return n.edge(e).cutvalue<0}))}function jn(n,e,r){var t=r.v,o=r.w;e.hasEdge(t,o)||(t=r.w,o=r.v);var i=n.node(t),u=n.node(o),a=i,d=!1;i.lim>u.lim&&(a=u,d=!0);var c=hn.A(e.edges(),(function(e){return d===Gn(n,n.node(e.v),a)&&d!==Gn(n,n.node(e.w),a)}));return W(c,(function(n){return nn(e,n)}))}function Fn(n,e,r,o){var i=r.v,u=r.w;n.removeEdge(i,u),n.setEdge(o.v,o.w,{}),On(n),Ln(n,e),function(n,e){var r=gn(n.nodes(),(function(n){return!e.node(n).parent})),o=function(n,e){return Tn(n,e,"pre")}(n,r);o=o.slice(1),t.A(o,(function(r){var t=n.node(r).parent,o=e.edge(r,t),i=!1;o||(o=e.edge(t,r),i=!0),e.node(r).rank=e.node(t).rank+(i?o.minlen:-o.minlen)}))}(n,e)}function Gn(n,e,r){return r.low<=e.lim&&e.lim<=r.lim}function Vn(n){switch(n.graph().ranker){case"network-simplex":default:qn(n);break;case"tight-tree":!function(n){X(n),en(n)}(n);break;case"longest-path":Bn(n)}}Mn.initLowLimValues=On,Mn.initCutValues=Ln,Mn.calcCutValue=Cn,Mn.leaveEdge=Sn,Mn.enterEdge=jn,Mn.exchangeEdges=Fn;var Bn=X;function qn(n){Mn(n)}var Yn=r(38207),zn=r(89463);function Dn(n){var e=F(n,"root",{},"_root"),r=function(n){var e={};function r(o,i){var u=n.children(o);u&&u.length&&t.A(u,(function(n){r(n,i+1)})),e[o]=i}return t.A(n.children(),(function(n){r(n,1)})),e}(n),o=_(Yn.A(r))-1,i=2*o+1;n.graph().nestingRoot=e,t.A(n.edges(),(function(e){n.edge(e).minlen*=i}));var u=function(n){return zn.A(n.edges(),(function(e,r){return e+n.edge(r).weight}),0)}(n)+1;t.A(n.children(),(function(t){$n(n,e,i,u,o,r,t)})),n.graph().nodeRankFactor=i}function $n(n,e,r,o,i,u,a){var d=n.children(a);if(d.length){var c=q(n,"_bt"),f=q(n,"_bb"),s=n.node(a);n.setParent(c,a),s.borderTop=c,n.setParent(f,a),s.borderBottom=f,t.A(d,(function(t){$n(n,e,r,o,i,u,t);var d=n.node(t),s=d.borderTop?d.borderTop:t,v=d.borderBottom?d.borderBottom:t,g=d.borderTop?o:2*o,h=s!==v?1:i-u[a]+1;n.setEdge(c,s,{weight:g,minlen:h,nestingEdge:!0}),n.setEdge(v,f,{weight:g,minlen:h,nestingEdge:!0})})),n.parent(a)||n.setEdge(e,c,{weight:0,minlen:i+u[a]})}else a!==e&&n.setEdge(e,a,{weight:0,minlen:r})}var Jn=r(91641);const Zn=function(n){return(0,Jn.A)(n,5)};function Hn(n,e,r){var u=function(n){var e;for(;n.hasNode(e=o.A("_root")););return e}(n),a=new f.T({compound:!0}).setGraph({root:u}).setDefaultNodeLabel((function(e){return n.node(e)}));return t.A(n.nodes(),(function(o){var d=n.node(o),c=n.parent(o);(d.rank===e||d.minRank<=e&&e<=d.maxRank)&&(a.setNode(o),a.setParent(o,c||u),t.A(n[r](o),(function(e){var r=e.v===o?e.w:e.v,t=a.edge(r,o),i=C.A(t)?0:t.weight;a.setEdge(r,o,{weight:n.edge(e).weight+i})})),i.A(d,"minRank")&&a.setNode(o,{borderLeft:d.borderLeft[e],borderRight:d.borderRight[e]}))})),a}var Kn=r(52851);const Qn=function(n,e,r){for(var t=-1,o=n.length,i=e.length,u={};++te||i&&u&&d&&!a&&!c||t&&u&&d||!r&&d||!o)return 1;if(!t&&!i&&!c&&n=a?d:d*("desc"==r[t]?-1:1)}return n.index-e.index};const ue=function(n,e,r){e=e.length?(0,Xn.A)(e,(function(n){return(0,ln.A)(n)?function(e){return(0,ne.A)(e,1===n.length?n[0]:n)}:n})):[N.A];var t=-1;e=(0,Xn.A)(e,(0,te.A)(M.A));var o=(0,ee.A)(n,(function(n,r,o){return{criteria:(0,Xn.A)(e,(function(e){return e(n)})),index:++t,value:n}}));return re(o,(function(n,e){return ie(n,e,r)}))};var ae=r(24326),de=r(6832);const ce=(0,ae.A)((function(n,e){if(null==n)return[];var r=e.length;return r>1&&(0,de.A)(n,e[0],e[1])?e=[]:r>2&&(0,de.A)(e[0],e[1],e[2])&&(e=[e[0]]),ue(n,(0,Wn.A)(e,1),[])}));function fe(n,e){for(var r=0,t=1;t0;)e%2&&(r+=f[e+1]),f[e=e-1>>1]+=n.weight;s+=n.weight*r}))),s}function ve(n,e){var r={};return t.A(n,(function(n,e){var t=r[n.v]={indegree:0,in:[],out:[],vs:[n.v],i:e};C.A(n.barycenter)||(t.barycenter=n.barycenter,t.weight=n.weight)})),t.A(e.edges(),(function(n){var e=r[n.v],t=r[n.w];C.A(e)||C.A(t)||(t.indegree++,e.out.push(r[n.w]))})),function(n){var e=[];function r(n){return function(e){e.merged||(C.A(e.barycenter)||C.A(n.barycenter)||e.barycenter>=n.barycenter)&&function(n,e){var r=0,t=0;n.weight&&(r+=n.barycenter*n.weight,t+=n.weight);e.weight&&(r+=e.barycenter*e.weight,t+=e.weight);n.vs=e.vs.concat(n.vs),n.barycenter=r/t,n.weight=t,n.i=Math.min(e.i,n.i),e.merged=!0}(n,e)}}function o(e){return function(r){r.in.push(e),0==--r.indegree&&n.push(r)}}for(;n.length;){var i=n.pop();e.push(i),t.A(i.in.reverse(),r(i)),t.A(i.out,o(i))}return d.A(hn.A(e,(function(n){return!n.merged})),(function(n){return b.A(n,["vs","i","barycenter","weight"])}))}(hn.A(r,(function(n){return!n.indegree})))}function ge(n,e){var r,o=function(n,e){var r={lhs:[],rhs:[]};return t.A(n,(function(n){e(n)?r.lhs.push(n):r.rhs.push(n)})),r}(n,(function(n){return i.A(n,"barycenter")})),u=o.lhs,d=ce(o.rhs,(function(n){return-n.i})),c=[],f=0,s=0,v=0;u.sort((r=!!e,function(n,e){return n.barycentere.barycenter?1:r?e.i-n.i:n.i-e.i})),v=he(c,d,v),t.A(u,(function(n){v+=n.vs.length,c.push(n.vs),f+=n.barycenter*n.weight,s+=n.weight,v=he(c,d,v)}));var g={vs:a.A(c)};return s&&(g.barycenter=f/s,g.weight=s),g}function he(n,e,r){for(var t;e.length&&(t=I(e)).i<=r;)e.pop(),n.push(t.vs),r++;return r}function le(n,e,r,o){var u=n.children(e),c=n.node(e),f=c?c.borderLeft:void 0,s=c?c.borderRight:void 0,v={};f&&(u=hn.A(u,(function(n){return n!==f&&n!==s})));var g=function(n,e){return d.A(e,(function(e){var r=n.inEdges(e);if(r.length){var t=zn.A(r,(function(e,r){var t=n.edge(r),o=n.node(r.v);return{sum:e.sum+t.weight*o.order,weight:e.weight+t.weight}}),{sum:0,weight:0});return{v:e,barycenter:t.sum/t.weight,weight:t.weight}}return{v:e}}))}(n,u);t.A(g,(function(e){if(n.children(e.v).length){var t=le(n,e.v,r,o);v[e.v]=t,i.A(t,"barycenter")&&(u=e,a=t,C.A(u.barycenter)?(u.barycenter=a.barycenter,u.weight=a.weight):(u.barycenter=(u.barycenter*u.weight+a.barycenter*a.weight)/(u.weight+a.weight),u.weight+=a.weight))}var u,a}));var h=ve(g,r);!function(n,e){t.A(n,(function(n){n.vs=a.A(n.vs.map((function(n){return e[n]?e[n].vs:n})))}))}(h,v);var l=ge(h,o);if(f&&(l.vs=a.A([f,l.vs,s]),n.predecessors(f).length)){var A=n.node(n.predecessors(f)[0]),p=n.node(n.predecessors(s)[0]);i.A(l,"barycenter")||(l.barycenter=0,l.weight=0),l.barycenter=(l.barycenter*l.weight+A.order+p.order)/(l.weight+2),l.weight+=2}return l}function Ae(n){var e=Y(n),r=pe(n,c.A(1,e+1),"inEdges"),o=pe(n,c.A(e-1,-1,-1),"outEdges"),u=function(n){var e={},r=hn.A(n.nodes(),(function(e){return!n.children(e).length})),o=_(d.A(r,(function(e){return n.node(e).rank}))),u=d.A(c.A(o+1),(function(){return[]})),a=ce(r,(function(e){return n.node(e).rank}));return t.A(a,(function r(o){if(!i.A(e,o)){e[o]=!0;var a=n.node(o);u[a.rank].push(o),t.A(n.successors(o),r)}})),u}(n);me(n,u);for(var a,f=Number.POSITIVE_INFINITY,s=0,v=0;v<4;++s,++v){we(s%2?r:o,s%4>=2);var g=fe(n,u=B(n));gd||c>e[o].lim));i=o,o=t;for(;(o=n.parent(o))!==i;)a.push(o);return{path:u.concat(a.reverse()),lca:i}}(n,e,o.v,o.w),u=i.path,a=i.lca,d=0,c=u[d],f=!0;r!==o.w;){if(t=n.node(r),f){for(;(c=u[d])!==a&&n.node(c).maxRankr){var t=e;e=r,r=t}var o=n[e];o||(n[e]=o={}),o[r]=!0}function Te(n,e,r){if(e>r){var t=e;e=r,r=t}return i.A(n[e],r)}function Re(n,e,r,o,u){var a={},d=function(n,e,r,o){var u=new f.T,a=n.graph(),d=function(n,e,r){return function(t,o,u){var a,d=t.node(o),c=t.node(u),f=0;if(f+=d.width/2,i.A(d,"labelpos"))switch(d.labelpos.toLowerCase()){case"l":a=-d.width/2;break;case"r":a=d.width/2}if(a&&(f+=r?a:-a),a=0,f+=(d.dummy?e:n)/2,f+=(c.dummy?e:n)/2,f+=c.width/2,i.A(c,"labelpos"))switch(c.labelpos.toLowerCase()){case"l":a=c.width/2;break;case"r":a=-c.width/2}return a&&(f+=r?a:-a),a=0,f}}(a.nodesep,a.edgesep,o);return t.A(e,(function(e){var o;t.A(e,(function(e){var t=r[e];if(u.setNode(t),o){var i=r[o],a=u.edge(i,t);u.setEdge(i,t,Math.max(d(n,e,o),a||0))}o=e}))})),u}(n,e,r,u),c=u?"borderLeft":"borderRight";function s(n,e){for(var r=d.nodes(),t=r.pop(),o={};t;)o[t]?n(t):(o[t]=!0,r.push(t),r=r.concat(e(t))),t=r.pop()}return s((function(n){a[n]=d.inEdges(n).reduce((function(n,e){return Math.max(n,a[e.v]+d.edge(e))}),0)}),d.predecessors.bind(d)),s((function(e){var r=d.outEdges(e).reduce((function(n,e){return Math.min(n,a[e.w]-d.edge(e))}),Number.POSITIVE_INFINITY),t=n.node(e);r!==Number.POSITIVE_INFINITY&&t.borderType!==c&&(a[e]=Math.max(a[e],r))}),d.successors.bind(d)),t.A(o,(function(n){a[n]=a[r[n]]})),a}function Me(n){var e,r=B(n),o=m.A(_e(n,r),function(n,e){var r={};function o(e,o,i,u,a){var d;t.A(c.A(o,i),(function(o){d=e[o],n.node(d).dummy&&t.A(n.predecessors(d),(function(e){var t=n.node(e);t.dummy&&(t.ordera)&&Ie(r,e,d)}))}))}return zn.A(e,(function(e,r){var i,u=-1,a=0;return t.A(r,(function(t,d){if("border"===n.node(t).dummy){var c=n.predecessors(t);c.length&&(i=n.node(c[0]).order,o(r,a,d,u,i),a=d,u=i)}o(r,a,r.length,i,e.length)})),r})),r}(n,r)),i={};t.A(["u","d"],(function(u){e="u"===u?r:Yn.A(r).reverse(),t.A(["l","r"],(function(r){"r"===r&&(e=d.A(e,(function(n){return Yn.A(n).reverse()})));var a=("u"===u?n.predecessors:n.successors).bind(n),c=function(n,e,r,o){var i={},u={},a={};return t.A(e,(function(n){t.A(n,(function(n,e){i[n]=n,u[n]=n,a[n]=e}))})),t.A(e,(function(n){var e=-1;t.A(n,(function(n){var t=o(n);if(t.length){t=ce(t,(function(n){return a[n]}));for(var d=(t.length-1)/2,c=Math.floor(d),f=Math.ceil(d);c<=f;++c){var s=t[c];u[n]===n&&e{r.d(e,{A:()=>i});var t=r(6240),o=r(38446);const i=function(n,e){var r=-1,i=(0,o.A)(n)?Array(n.length):[];return(0,t.A)(n,(function(n,t,o){i[++r]=e(n,t,o)})),i}},23068:(n,e,r)=>{r.d(e,{A:()=>c});var t=r(24326),o=r(66984),i=r(6832),u=r(55615),a=Object.prototype,d=a.hasOwnProperty;const c=(0,t.A)((function(n,e){n=Object(n);var r=-1,t=e.length,c=t>2?e[2]:void 0;for(c&&(0,i.A)(e[0],e[1],c)&&(t=1);++r{r.d(e,{A:()=>o});var t=r(13588);const o=function(n){return(null==n?0:n.length)?(0,t.A)(n,1):[]}},74722:(n,e,r)=>{r.d(e,{A:()=>a});var t=r(45572),o=r(49574),i=r(52568),u=r(92049);const a=function(n,e){return((0,u.A)(n)?t.A:i.A)(n,(0,o.A)(e,3))}},81942:(n,e,r)=>{r.d(e,{A:()=>A});var t=r(66318),o=r(52851),i=r(7819),u=r(25353),a=r(23149),d=r(30901);const c=function(n,e,r,t){if(!(0,a.A)(n))return n;for(var c=-1,f=(e=(0,i.A)(e,n)).length,s=f-1,v=n;null!=v&&++c{r.d(e,{A:()=>d});var t=Math.ceil,o=Math.max;const i=function(n,e,r,i){for(var u=-1,a=o(t((e-n)/(r||1)),0),d=Array(a);a--;)d[i?a:++u]=n,n+=r;return d};var u=r(6832),a=r(74342);const d=function(n){return function(e,r,t){return t&&"number"!=typeof t&&(0,u.A)(e,r,t)&&(r=t=void 0),e=(0,a.A)(e),void 0===r?(r=e,e=0):r=(0,a.A)(r),t=void 0===t?e{r.d(e,{A:()=>l});var t=/\s/;const o=function(n){for(var e=n.length;e--&&t.test(n.charAt(e)););return e};var i=/^\s+/;const u=function(n){return n?n.slice(0,o(n)+1).replace(i,""):n};var a=r(23149),d=r(61882),c=/^[-+]0x[0-9a-f]+$/i,f=/^0b[01]+$/i,s=/^0o[0-7]+$/i,v=parseInt;const g=function(n){if("number"==typeof n)return n;if((0,d.A)(n))return NaN;if((0,a.A)(n)){var e="function"==typeof n.valueOf?n.valueOf():n;n=(0,a.A)(e)?e+"":e}if("string"!=typeof n)return 0===n?n:+n;n=u(n);var r=f.test(n);return r||s.test(n)?v(n.slice(2),r?2:8):c.test(n)?NaN:+n};var h=1/0;const l=function(n){return n?(n=g(n))===h||n===-1/0?17976931348623157e292*(n<0?-1:1):n==n?n:0:0===n?n:0}},5664:(n,e,r)=>{r.d(e,{A:()=>i});var t=r(28894),o=0;const i=function(n){var e=++o;return(0,t.A)(n)+e}}}]); \ No newline at end of file diff --git a/assets/js/119c53e5.1c68010a.js b/assets/js/119c53e5.1c68010a.js new file mode 100644 index 0000000000..6ba6add416 --- /dev/null +++ b/assets/js/119c53e5.1c68010a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8407],{91136:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>c,contentTitle:()=>t,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var r=n(74848),o=n(28453);const i={sidebar_label:"User"},t="User",a={id:"iaas/guides/configuration-guide/commons/user",title:"User",description:"With the osism.commons.user role, it is possible to manage additional",source:"@site/docs/02-iaas/guides/configuration-guide/commons/user.md",sourceDirName:"02-iaas/guides/configuration-guide/commons",slug:"/iaas/guides/configuration-guide/commons/user",permalink:"/docs/iaas/guides/configuration-guide/commons/user",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/user.md",tags:[],version:"current",frontMatter:{sidebar_label:"User"},sidebar:"docs",previous:{title:"Timezone",permalink:"/docs/iaas/guides/configuration-guide/commons/timezone"},next:{title:"Services",permalink:"/docs/iaas/guides/configuration-guide/services/"}},c={},d=[];function u(e){const s={code:"code",h1:"h1",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h1,{id:"user",children:"User"}),"\n",(0,r.jsxs)(s.p,{children:["With the ",(0,r.jsx)(s.code,{children:"osism.commons.user"})," role, it is possible to manage additional\nuser accounts on a node."]}),"\n",(0,r.jsxs)(s.p,{children:["Users are managed via the ",(0,r.jsx)(s.code,{children:"user_list"})," parameter."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"user_list:\n - name: testing\n key: ssh-rsa AAAAB...\n # default for groups is user_groups\n # groups:\n groups:\n - docker\n # default is a group with the name of the user\n # or user_primary_group if set\n # primary_group: dragon\n - name: testing_github\n key: https://github.com/testing.keys\n"})}),"\n",(0,r.jsxs)(s.p,{children:["By default a new group with the name of a user will be created and assigned as\nprimary group. It is possible to use an already existing group as primary group\nfor all users. Can be overwritten with the user specific ",(0,r.jsx)(s.code,{children:"primary_group"})," key."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"user_primary_group: dragon\n"})}),"\n",(0,r.jsxs)(s.p,{children:["If all users should be added to other specific groups by default, the ",(0,r.jsx)(s.code,{children:"user_groups"}),"\nparameter can be used. Can be overwritten with the user specific ",(0,r.jsx)(s.code,{children:"groups"})," key."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"user_groups:\n - docker\n"})}),"\n",(0,r.jsxs)(s.p,{children:["If users should be deleted, they are added to the ",(0,r.jsx)(s.code,{children:"user_delete"})," list."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"user_delete:\n - user_to_delete_1\n - user_to_delete_2\n"})})]})}function l(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>a});var r=n(96540);const o={},i=r.createContext(o);function t(e){const s=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),r.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/121.f97e3205.js b/assets/js/121.f97e3205.js new file mode 100644 index 0000000000..fc9be773e9 --- /dev/null +++ b/assets/js/121.f97e3205.js @@ -0,0 +1,28500 @@ +"use strict"; +exports.id = 121; +exports.ids = [121]; +exports.modules = { + +/***/ 10646: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ H: () => (/* binding */ addHtmlLabel) +/* harmony export */ }); +/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(82933); + + + + +function addHtmlLabel(root, node) { + var fo = root.append('foreignObject').attr('width', '100000'); + + var div = fo.append('xhtml:div'); + div.attr('xmlns', 'http://www.w3.org/1999/xhtml'); + + var label = node.label; + switch (typeof label) { + case 'function': + div.insert(label); + break; + case 'object': + // Currently we assume this is a DOM object. + div.insert(function () { + return label; + }); + break; + default: + div.html(label); + } + + _util_js__WEBPACK_IMPORTED_MODULE_0__/* .applyStyle */ .AV(div, node.labelStyle); + div.style('display', 'inline-block'); + // Fix for firefox + div.style('white-space', 'nowrap'); + + var client = div.node().getBoundingClientRect(); + fo.attr('width', client.width).attr('height', client.height); + + return fo; +} + + +/***/ }), + +/***/ 82933: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ AV: () => (/* binding */ applyStyle), +/* harmony export */ De: () => (/* binding */ isSubgraph), +/* harmony export */ c$: () => (/* binding */ applyTransition), +/* harmony export */ gh: () => (/* binding */ edgeToId), +/* harmony export */ nh: () => (/* binding */ applyClass) +/* harmony export */ }); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(34963); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(89610); + + +// Public utility functions + + +/* + * Returns true if the specified node in the graph is a subgraph node. A + * subgraph node is one that contains other nodes. + */ +function isSubgraph(g, v) { + return !!g.children(v).length; +} + +function edgeToId(e) { + return escapeId(e.v) + ':' + escapeId(e.w) + ':' + escapeId(e.name); +} + +var ID_DELIM = /:/g; +function escapeId(str) { + return str ? String(str).replace(ID_DELIM, '\\:') : ''; +} + +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr('style', styleFn); + } +} + +function applyClass(dom, classFn, otherClasses) { + if (classFn) { + dom.attr('class', classFn).attr('class', otherClasses + ' ' + dom.attr('class')); + } +} + +function applyTransition(selection, g) { + var graph = g.graph(); + + if (lodash_es__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A(graph)) { + var transition = graph.transition; + if (lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(transition)) { + return transition(selection); + } + } + + return selection; +} + + +/***/ }), + +/***/ 21176: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Zp: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(5664); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(74722); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(91395); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(697); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.A(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.A( + map/* default */.A(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.A(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.A(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.T(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.A(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.A(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.A(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.A(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.A(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.A('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.A(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.A(g.outEdges(v), function (e) { + if (has/* default */.A(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.A(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.A(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(98879); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(81942); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(23068); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.A)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(52528); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.A)(iteratee, 3); + + (0,_baseForOwn/* default */.A)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.A)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(41917); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.A.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.A(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.T().setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.T({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.A(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.A(range/* default */.A(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.A(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.A(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.A(layers, function (vs, i) { + if (isUndefined/* default */.A(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.A(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.A(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.A(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.A(children, dfs); + } + + if (has/* default */.A(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.A(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.A(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, reverseYOne); + if (has/* default */.A(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, swapXYOne); + if (has/* default */.A(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.A(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.A)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.A(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.A(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.A(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.T({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.A(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.A(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.A(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.A)(collection)) { + var iteratee = (0,_baseIteratee/* default */.A)(predicate, 3); + collection = (0,keys/* default */.A)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.A)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.A)(array, (0,_baseIteratee/* default */.A)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(69471); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(88496); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.A)(value) && (0,isObjectLike/* default */.A)(value) && (0,_baseGetTag/* default */.A)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.A)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.A)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.A)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.A)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.A(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.A(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.A(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.A(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.A(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.A(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.A(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.A(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(73046); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.A(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.A(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.A(tree.neighbors(v), function (w) { + if (!has/* default */.A(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.A(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.A(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.A(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.A(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.A(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.A(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.A(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.A(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.A( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(91641); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.A)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.A(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.T({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.A(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.A(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.A(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.A('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.A); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(52568); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.A)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.A)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + if ((0,isArray/* default */.A)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.A)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.A]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.A)(iteratees, (0,_baseUnary/* default */.A)(_baseIteratee/* default */.A)); + + var result = (0,_baseMap/* default */.A)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.A)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.A)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.A)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.A)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.A(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.A( + map/* default */.A(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.A(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.A(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.A( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.A(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.A(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.A(range/* default */.A(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.A(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.A(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.A(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.A(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.A( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.A(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.A(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.A(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.A(entryV) && !isUndefined/* default */.A(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.A(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.A(uEntry.barycenter) || + isUndefined/* default */.A(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.A(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.A(entry.out, handleOut(entry)); + } + + return map/* default */.A( + filter/* default */.A(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.A(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.A(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.A(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.A(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.A(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.A(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.A(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.A([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.A(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.A(entries, function (entry) { + entry.vs = flatten/* default */.A( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.A(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.A(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.A(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.A(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.T(); + forEach/* default */.A(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.A(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.A(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.A(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(99922); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(4574); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee), keysIn/* default */.A); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.A(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.A(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.A(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.A(range/* default */.A(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.A(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.A(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.A(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.A(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.A(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.A(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.T(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.A(layering, function (layer) { + var u; + forEach/* default */.A(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.A(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.A(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.A(['u', 'd'], function (vert) { + forEach/* default */.A(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.A(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.A(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.A(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.A(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.A(layering).reverse(); + forEach/* default */.A(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.A(adjustedLayering, function (inner) { + return values/* default */.A(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.A(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.A(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.A(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.A(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.A(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.A(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.A(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.T({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.A({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.A(graph, graphAttrs)) + ); + + forEach/* default */.A(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.A(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.A({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.A(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.A(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.A(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.A(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.A(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.A(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.A(layers, function (layer) { + var orderShift = 0; + forEach/* default */.A(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.A(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.A(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.A(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 73046: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + T: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(89610); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(66401); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.A)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(39857); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.A && (1 / (0,_setToArray/* default */.A)(new _Set/* default */.A([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.A(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.A)(set); + } + isCommon = false; + includes = _cacheHas/* default */.A; + seen = new _SetCache/* default */.A; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(53533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.A)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.A)(arrays, 1, isArrayLikeObject/* default */.A, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.A(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.A(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.A(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.A(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.A(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.A(this._nodes); + } + sources() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.A(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.A(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.A(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.A(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.A(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.A(keys/* default */.A(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.A(keys/* default */.A(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.A(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.A(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.A(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.A(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.A(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.A(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.A(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.A(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.A(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.A(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.A(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.A(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.A(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.A(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.A(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.A(inV); + if (!u) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.A(outV); + if (!w) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.A(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 697: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ T: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.T) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 14075: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ M: () => (/* binding */ write) +/* harmony export */ }); +/* unused harmony export read */ +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69592); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(50053); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74722); +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); + + + + + +function write(g) { + var json = { + options: { + directed: g.isDirected(), + multigraph: g.isMultigraph(), + compound: g.isCompound(), + }, + nodes: writeNodes(g), + edges: writeEdges(g), + }; + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(g.graph())) { + json.value = lodash_es__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A(g.graph()); + } + return json; +} + +function writeNodes(g) { + return lodash_es__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A(g.nodes(), function (v) { + var nodeValue = g.node(v); + var parent = g.parent(v); + var node = { v: v }; + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(nodeValue)) { + node.value = nodeValue; + } + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(parent)) { + node.parent = parent; + } + return node; + }); +} + +function writeEdges(g) { + return lodash_es__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A(g.edges(), function (e) { + var edgeValue = g.edge(e); + var edge = { v: e.v, w: e.w }; + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(e.name)) { + edge.name = e.name; + } + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(edgeValue)) { + edge.value = edgeValue; + } + return edge; + }); +} + +function read(json) { + var g = new Graph(json.options).setGraph(json.value); + _.each(json.nodes, function (entry) { + g.setNode(entry.v, entry.value); + if (entry.parent) { + g.setParent(entry.v, entry.parent); + } + }); + _.each(json.edges, function (entry) { + g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value); + }); + return g; +} + + +/***/ }), + +/***/ 75937: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _utils_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(72453); +/* harmony import */ var _color_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74886); +/* IMPORT */ + + +/* MAIN */ +const channel = (color, channel) => { + return _utils_index_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A.lang.round(_color_index_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A.parse(color)[channel]); +}; +/* EXPORT */ +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (channel); + + +/***/ }), + +/***/ 62062: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(29471); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.A; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 72641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 2634: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 45572: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 76912: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 91641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(72641); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(22031); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keys/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keysIn/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(80154); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(39759); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(14792); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.A)(source, (0,_getSymbols/* default */.A)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(15647); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(13153); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.A : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.A)(result, (0,_getSymbols/* default */.A)(object)); + object = (0,_getPrototype/* default */.A)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.A)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(33831); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.A)(object, keysIn/* default */.A, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(90565); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.A)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(1801); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.A)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.A)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(18598); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(64841); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.A)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.A)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.A)(value)) { + return value; + } + var isArr = (0,isArray/* default */.A)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.A)(value, result); + } + } else { + var tag = (0,_getTag/* default */.A)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.A)(value)) { + return (0,_cloneBuffer/* default */.A)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.A)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.A); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.A) + : (isFlat ? keysIn/* default */.A : keys/* default */.A); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.A)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.A)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 6240: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.A)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.A); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 25707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 13588: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(52274); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.A ? _Symbol/* default */.A.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.A)(value) || (0,isArguments/* default */.A)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.A)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 79841: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4574); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 66318: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 33831: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76912); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 49574: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.A : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.A)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(43988); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(66984); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.A(object), new _Uint8Array/* default */.A(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.A)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.A); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.A)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.A)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(33858); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.A)(object), + othIsArr = (0,isArray/* default */.A)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.A)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.A)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.A)(object)) { + if (!(0,isBuffer/* default */.A)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.A); + return (objIsArr || (0,isTypedArray/* default */.A)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.A); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.A); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.A)(value) && !(0,isObjectLike/* default */.A)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.A; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.A)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.A)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.A)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.A)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.A)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.A)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.A)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.A)(path) ? (0,_baseProperty/* default */.A)((0,_toKey/* default */.A)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.A; + } + if (typeof value == 'object') { + return (0,isArray/* default */.A)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 52568: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6240); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 70805: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 64099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 99922: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(29008); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 7819: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(46632); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.A)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(28894); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.A)(value)) { + return value; + } + return (0,_isKey/* default */.A)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.A)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 19042: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33831); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14792); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 14792: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2634); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13153); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 85054: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(52274); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(92049); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25353); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5254); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 86586: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(61882); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 29959: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 30901: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61882); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 50053: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseClone_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(91641); + + +/** Used to compose bitmasks for cloning. */ +var CLONE_SYMBOLS_FLAG = 4; + +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return (0,_baseClone_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value, CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (clone); + + +/***/ }), + +/***/ 23068: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(24326); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66984); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6832); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55615); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 11662: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(2634); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.A)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.A)(collection) ? _arrayFilter/* default */.A : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.A)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 34098: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13588); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 8058: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72641); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6240); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99922); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 48585: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 39188: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 61882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(88496); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(53098); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 69592: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 27422: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(83607); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69471); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 74722: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(45572); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49574); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(52568); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 81942: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(7819); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(25353); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.A)(object)) { + return object; + } + path = (0,_castPath/* default */.A)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.A)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.A)(objValue) + ? objValue + : ((0,_isIndex/* default */.A)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.A)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.A)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.A)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.A)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(76875); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(67525); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.A)((0,_overRest/* default */.A)(func, undefined, flatten/* default */.A), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 91395: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.A)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.A)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.A)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.A)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 89463: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.A)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.A)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.A); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 13153: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 74342: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.A)(value)) { + return NAN; + } + if ((0,isObject/* default */.A)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.A)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 28894: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.A)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.A)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.A)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 5664: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28894); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 38207: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.A)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.A)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 40351: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-f47111a7.js + 8 modules +var mermaid_f47111a7 = __webpack_require__(76257); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {Array} items + * Items to add to `list`. + * @returns {Array} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record} */ + const left = maybe || (all[hook] = {}) + /** @type {Record | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array} existing + * @param {Array} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array} */ + let parameters + /** @type {Array} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array} events + * @param {number} eventIndex + * @returns {Record} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record} */ + const gaps = {} + /** @type {Array} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record} */ + const columnStart = {} + /** @type {Array} */ + const resolveAllConstructs = [] + /** @type {Array} */ + let chunks = [] + /** @type {Array} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array} chunks + * @param {Pick} token + * @returns {Array} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * + * b> + * + * + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`` or `b`). + * @param {TokenType} literalType + * Type when enclosed (``). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * . + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * . + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After ` | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | &<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | + * ^^ + * > | + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > |
+ * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after ` | + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > |
+ * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + *

!^a

+ *

!^a

+ * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | ab + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a c + * ^ + * > | a c + * ^ + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * > | a c + * ^ + * > | a &<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after ` | a c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After ` | a &<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a &<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array} events + * @returns {Array} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract} Parent + * + * @typedef {Omit & {type: 'fragment', children: Array}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array} transforms + * Tree transforms. + * + * @typedef {Partial} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array} stack + * Stack of nodes. + * @property {Array} tokenStack + * Stack of tokens. + * @property {(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(60513); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-6b48ae7d.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.T)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "
"); + } else if (node.type === "strong") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "emphasis") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "paragraph") { + return `

${node.children.map(output).join("")}

`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + " + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_f47111a7.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_f47111a7.M)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 28747: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ insertMarkers$1), +/* harmony export */ b: () => (/* binding */ clear$1), +/* harmony export */ c: () => (/* binding */ createLabel$1), +/* harmony export */ d: () => (/* binding */ clear), +/* harmony export */ e: () => (/* binding */ insertNode), +/* harmony export */ f: () => (/* binding */ insertEdgeLabel), +/* harmony export */ g: () => (/* binding */ getSubGraphTitleMargins), +/* harmony export */ h: () => (/* binding */ insertEdge), +/* harmony export */ i: () => (/* binding */ intersectRect$1), +/* harmony export */ j: () => (/* binding */ positionEdgeLabel), +/* harmony export */ k: () => (/* binding */ getLineFunctionsWithOffset), +/* harmony export */ l: () => (/* binding */ labelHelper), +/* harmony export */ m: () => (/* binding */ addEdgeMarkers), +/* harmony export */ p: () => (/* binding */ positionNode), +/* harmony export */ s: () => (/* binding */ setNodeElem), +/* harmony export */ u: () => (/* binding */ updateNodeBounds) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(40351); + + + +const insertMarkers = (elem, markerArray, type, id) => { + markerArray.forEach((markerName) => { + markers[markerName](elem, type, id); + }); +}; +const extension = (elem, type, id) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Making markers for ", id); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); +}; +const composition = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const aggregation = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const dependency = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 6).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const lollipop = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopEnd").attr("class", "marker lollipop " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); +}; +const point = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 6).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 4.5).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const circle$1 = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const cross = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); +}; +const barb = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const markers = { + extension, + composition, + aggregation, + dependency, + lollipop, + point, + circle: circle$1, + cross, + barb +}; +const insertMarkers$1 = insertMarkers; +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlLabel(node) { + const fo = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + '" + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "inline-block"); + div.style("white-space", "nowrap"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + return fo.node(); +} +const createLabel = (_vertexText, style, isTitle, isNode) => { + let vertexText = _vertexText || ""; + if (typeof vertexText === "object") { + vertexText = vertexText[0]; + } + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + vertexText = vertexText.replace(/\\n|\n/g, "
"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("vertexText" + vertexText); + const node = { + isNode, + label: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(vertexText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + let vertexNode = addHtmlLabel(node); + return vertexNode; + } else { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", style.replace("color:", "fill:")); + let rows = []; + if (typeof vertexText === "string") { + rows = vertexText.split(/\\n|\n|/gi); + } else if (Array.isArray(vertexText)) { + rows = vertexText; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + if (isTitle) { + tspan.setAttribute("class", "title-row"); + } else { + tspan.setAttribute("class", "row"); + } + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; + } +}; +const createLabel$1 = createLabel; +const labelHelper = async (parent, node, _classes, isNode) => { + let classes; + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + if (!_classes) { + classes = "node default"; + } else { + classes = _classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle); + let labelText; + if (node.labelText === void 0) { + labelText = ""; + } else { + labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0]; + } + const textNode = label.node(); + let text; + if (node.labelType === "markdown") { + text = (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__.a)(label, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(labelText), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()), { + useHtmlLabels, + width: node.width || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.wrappingWidth, + classes: "markdown-node-label" + }); + } else { + text = textNode.appendChild( + createLabel$1( + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(labelText), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()), + node.labelStyle, + false, + isNode + ) + ); + } + let bbox = text.getBBox(); + const halfPadding = node.padding / 2; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text); + const images = div.getElementsByTagName("img"); + if (images) { + const noImgText = labelText.replace(/]*>/g, "").trim() === ""; + await Promise.all( + [...images].map( + (img) => new Promise((res) => { + function setupImage() { + img.style.display = "flex"; + img.style.flexDirection = "column"; + if (noImgText) { + const bodyFontSize = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize ? (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize : window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + const width = parseInt(bodyFontSize, 10) * enlargingFactor + "px"; + img.style.minWidth = width; + img.style.maxWidth = width; + } else { + img.style.width = "100%"; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener("error", setupImage); + img.addEventListener("load", setupImage); + }) + ) + ); + } + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (useHtmlLabels) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } else { + label.attr("transform", "translate(0, " + -bbox.height / 2 + ")"); + } + if (node.centerLabel) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } + label.insert("rect", ":first-child"); + return { shapeSvg, bbox, halfPadding, label }; +}; +const updateNodeBounds = (node, element) => { + const bbox = element.node().getBBox(); + node.width = bbox.width; + node.height = bbox.height; +}; +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +function intersectNode(node, point2) { + return node.intersect(point2); +} +function intersectEllipse(node, rx, ry, point2) { + var cx = node.x; + var cy = node.y; + var px = cx - point2.x; + var py = cy - point2.y; + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + var dx = Math.abs(rx * ry * px / det); + if (point2.x < cx) { + dx = -dx; + } + var dy = Math.abs(rx * ry * py / det); + if (point2.y < cy) { + dy = -dy; + } + return { x: cx + dx, y: cy + dy }; +} +function intersectCircle(node, rx, point2) { + return intersectEllipse(node, rx, rx, point2); +} +function intersectLine(p1, p2, q1, q2) { + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return; + } + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return; + } + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return; + } + offset = Math.abs(denom / 2); + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + return { x, y }; +} +function sameSign(r1, r2) { + return r1 * r2 > 0; +} +function intersectPolygon(node, polyPoints, point2) { + var x1 = node.x; + var y1 = node.y; + var intersections = []; + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + if (typeof polyPoints.forEach === "function") { + polyPoints.forEach(function(entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + } else { + minX = Math.min(minX, polyPoints.x); + minY = Math.min(minY, polyPoints.y); + } + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect2 = intersectLine( + node, + point2, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect2) { + intersections.push(intersect2); + } + } + if (!intersections.length) { + return node; + } + if (intersections.length > 1) { + intersections.sort(function(p, q) { + var pdx = p.x - point2.x; + var pdy = p.y - point2.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + var qdx = q.x - point2.x; + var qdy = q.y - point2.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} +const intersectRect = (node, point2) => { + var x = node.x; + var y = node.y; + var dx = point2.x - x; + var dy = point2.y - y; + var w = node.width / 2; + var h = node.height / 2; + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : h * dx / dy; + sy = h; + } else { + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : w * dy / dx; + } + return { x: x + sx, y: y + sy }; +}; +const intersectRect$1 = intersectRect; +const intersect = { + node: intersectNode, + circle: intersectCircle, + ellipse: intersectEllipse, + polygon: intersectPolygon, + rect: intersectRect$1 +}; +const note = async (parent, node) => { + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels; + if (!useHtmlLabels) { + node.centerLabel = true; + } + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Classes = ", node.classes); + const rect2 = shapeSvg.insert("rect", ":first-child"); + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const note$1 = note; +const expandAndDeduplicateDirections = (directions) => { + const uniqueDirections = /* @__PURE__ */ new Set(); + for (const direction of directions) { + switch (direction) { + case "x": + uniqueDirections.add("right"); + uniqueDirections.add("left"); + break; + case "y": + uniqueDirections.add("up"); + uniqueDirections.add("down"); + break; + default: + uniqueDirections.add(direction); + break; + } + } + return uniqueDirections; +}; +const getArrowPoints = (duplicatedDirections, bbox, node) => { + const directions = expandAndDeduplicateDirections(duplicatedDirections); + const f = 2; + const height = bbox.height + 2 * node.padding; + const midpoint = height / f; + const width = bbox.width + 2 * midpoint + node.padding; + const padding = node.padding / 2; + if (directions.has("right") && directions.has("left") && directions.has("up") && directions.has("down")) { + return [ + // Bottom + { x: 0, y: 0 }, + { x: midpoint, y: 0 }, + { x: width / 2, y: 2 * padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: 0 }, + // Right + { x: width, y: -height / 3 }, + { x: width + 2 * padding, y: -height / 2 }, + { x: width, y: -2 * height / 3 }, + { x: width, y: -height }, + // Top + { x: width - midpoint, y: -height }, + { x: width / 2, y: -height - 2 * padding }, + { x: midpoint, y: -height }, + // Left + { x: 0, y: -height }, + { x: 0, y: -2 * height / 3 }, + { x: -2 * padding, y: -height / 2 }, + { x: 0, y: -height / 3 } + ]; + } + if (directions.has("right") && directions.has("left") && directions.has("up")) { + return [ + { x: midpoint, y: 0 }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("right") && directions.has("left") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: midpoint, y: -height }, + { x: width - midpoint, y: -height }, + { x: width, y: 0 } + ]; + } + if (directions.has("right") && directions.has("up") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: width, y: -midpoint }, + { x: width, y: -height + midpoint }, + { x: 0, y: -height } + ]; + } + if (directions.has("left") && directions.has("up") && directions.has("down")) { + return [ + { x: width, y: 0 }, + { x: 0, y: -midpoint }, + { x: 0, y: -height + midpoint }, + { x: width, y: -height } + ]; + } + if (directions.has("right") && directions.has("left")) { + return [ + { x: midpoint, y: 0 }, + { x: midpoint, y: -padding }, + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: width - midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("up") && directions.has("down")) { + return [ + // Bottom center + { x: width / 2, y: 0 }, + // Left pont of bottom arrow + { x: 0, y: -padding }, + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: 0, y: -height + padding }, + // Top of arrow + { x: width / 2, y: -height }, + { x: width, y: -height + padding }, + // Top of right vertical bar + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding }, + { x: width, y: -padding } + ]; + } + if (directions.has("right") && directions.has("up")) { + return [ + { x: 0, y: 0 }, + { x: width, y: -midpoint }, + { x: 0, y: -height } + ]; + } + if (directions.has("right") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: width, y: 0 }, + { x: 0, y: -height } + ]; + } + if (directions.has("left") && directions.has("up")) { + return [ + { x: width, y: 0 }, + { x: 0, y: -midpoint }, + { x: width, y: -height } + ]; + } + if (directions.has("left") && directions.has("down")) { + return [ + { x: width, y: 0 }, + { x: 0, y: 0 }, + { x: width, y: -height } + ]; + } + if (directions.has("right")) { + return [ + { x: midpoint, y: -padding }, + { x: midpoint, y: -padding }, + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: width - midpoint, y: -height + padding }, + // top left corner of arrow + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding } + ]; + } + if (directions.has("left")) { + return [ + { x: midpoint, y: 0 }, + { x: midpoint, y: -padding }, + // Two points, the right corners + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("up")) { + return [ + // Bottom center + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: 0, y: -height + padding }, + // Top of arrow + { x: width / 2, y: -height }, + { x: width, y: -height + padding }, + // Top of right vertical bar + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding } + ]; + } + if (directions.has("down")) { + return [ + // Bottom center + { x: width / 2, y: 0 }, + // Left pont of bottom arrow + { x: 0, y: -padding }, + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding }, + { x: width, y: -padding } + ]; + } + return [{ x: 0, y: 0 }]; +}; +const formatClass = (str) => { + if (str) { + return " " + str; + } + return ""; +}; +const getClassesFromNode = (node, otherClasses) => { + return `${otherClasses ? otherClasses : "node default"}${formatClass(node.classes)} ${formatClass( + node.class + )}`; +}; +const question = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const s = w + h; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Question main (Circle)"); + const questionElem = insertPolygonShape(shapeSvg, s, s, points); + questionElem.attr("style", node.style); + updateNodeBounds(node, questionElem); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("Intersect called"); + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const choice = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const s = 28; + const points = [ + { x: 0, y: s / 2 }, + { x: s / 2, y: 0 }, + { x: 0, y: -s / 2 }, + { x: -s / 2, y: 0 } + ]; + const choice2 = shapeSvg.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ); + choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28); + node.width = 28; + node.height = 28; + node.intersect = function(point2) { + return intersect.circle(node, 14, point2); + }; + return shapeSvg; +}; +const hexagon = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const f = 4; + const h = bbox.height + node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const hex = insertPolygonShape(shapeSvg, w, h, points); + hex.attr("style", node.style); + updateNodeBounds(node, hex); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const block_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true); + const f = 2; + const h = bbox.height + 2 * node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = getArrowPoints(node.directions, bbox, node); + const blockArrow = insertPolygonShape(shapeSvg, w, h, points); + blockArrow.attr("style", node.style); + updateNodeBounds(node, blockArrow); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_left_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + node.width = w + h; + node.height = h; + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_right = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_left = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const inv_trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_right_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const cylinder = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry + node.padding; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const el = shapeSvg.attr("label-offset-y", ry).insert("path", ":first-child").attr("style", node.style).attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + updateNodeBounds(node, el); + node.intersect = function(point2) { + const pos = intersect.rect(node, point2); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point2.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +}; +const rect = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes + " " + node.class, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding; + const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding; + rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const composite = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding; + const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding; + rect2.attr("class", "basic cluster composite label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const labelRect = async (parent, node) => { + const { shapeSvg } = await labelHelper(parent, node, "label", true); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Classes = ", node.class); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = 0; + const totalHeight = 0; + rect2.attr("width", totalWidth).attr("height", totalHeight); + shapeSvg.attr("class", "label edgeLabel"); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) { + const strokeDashArray = []; + const addBorder = (length) => { + strokeDashArray.push(length, 0); + }; + const skipBorder = (length) => { + strokeDashArray.push(0, length); + }; + if (borders.includes("t")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add top border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("r")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add right border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + if (borders.includes("b")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add bottom border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("l")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add left border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + rect2.attr("stroke-dasharray", strokeDashArray.join(" ")); +} +const rectWithTitle = (parent, node) => { + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const innerLine = shapeSvg.insert("line"); + const label = shapeSvg.insert("g").attr("class", "label"); + const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText; + let title = ""; + if (typeof text2 === "object") { + title = text2[0]; + } else { + title = text2; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Label text abc79", title, text2, typeof text2 === "object"); + const text = label.node().appendChild(createLabel$1(title, node.labelStyle, true, true)); + let bbox = { width: 0, height: 0 }; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Text 2", text2); + const textRows = text2.slice(1, text2.length); + let titleBox = text.getBBox(); + const descr = label.node().appendChild( + createLabel$1(textRows.join ? textRows.join("
") : textRows, node.labelStyle, true, true) + ); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = descr.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(descr); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const halfPadding = node.padding / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(descr).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")" + ); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)" + ); + bbox = label.node().getBBox(); + label.attr( + "transform", + "translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")" + ); + rect2.attr("class", "outer title-state").attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + innerLine.attr("class", "divider").attr("x1", -bbox.width / 2 - halfPadding).attr("x2", bbox.width / 2 + halfPadding).attr("y1", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr("y2", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const stadium = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const h = bbox.height + node.padding; + const w = bbox.width + h / 4 + node.padding; + const rect2 = shapeSvg.insert("rect", ":first-child").attr("style", node.style).attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const circle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle main"); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle intersect", node, bbox.width / 2 + halfPadding, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding, point2); + }; + return shapeSvg; +}; +const doublecircle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const gap = 5; + const circleGroup = shapeSvg.insert("g", ":first-child"); + const outerCircle = circleGroup.insert("circle"); + const innerCircle = circleGroup.insert("circle"); + circleGroup.attr("class", node.class); + outerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding + gap).attr("width", bbox.width + node.padding + gap * 2).attr("height", bbox.height + node.padding + gap * 2); + innerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle main"); + updateNodeBounds(node, outerCircle); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point2); + }; + return shapeSvg; +}; +const subroutine = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const start = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const forkJoin = (parent, node, dir) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + let width = 70; + let height = 10; + if (dir === "LR") { + width = 10; + height = 70; + } + const shape = shapeSvg.append("rect").attr("x", -1 * width / 2).attr("y", -1 * height / 2).attr("width", width).attr("height", height).attr("class", "fork-join"); + updateNodeBounds(node, shape); + node.height = node.height + node.padding / 2; + node.width = node.width + node.padding / 2; + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const end = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const innerCircle = shapeSvg.insert("circle", ":first-child"); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const class_box = (parent, node) => { + const halfPadding = node.padding / 2; + const rowPadding = 4; + const lineHeight = 8; + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const topLine = shapeSvg.insert("line"); + const bottomLine = shapeSvg.insert("line"); + let maxWidth = 0; + let maxHeight = rowPadding; + const labelContainer = shapeSvg.insert("g").attr("class", "label"); + let verticalPos = 0; + const hasInterface = node.classData.annotations && node.classData.annotations[0]; + const interfaceLabelText = node.classData.annotations[0] ? "«" + node.classData.annotations[0] + "»" : ""; + const interfaceLabel = labelContainer.node().appendChild(createLabel$1(interfaceLabelText, node.labelStyle, true, true)); + let interfaceBBox = interfaceLabel.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = interfaceLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(interfaceLabel); + interfaceBBox = div.getBoundingClientRect(); + dv.attr("width", interfaceBBox.width); + dv.attr("height", interfaceBBox.height); + } + if (node.classData.annotations[0]) { + maxHeight += interfaceBBox.height + rowPadding; + maxWidth += interfaceBBox.width; + } + let classTitleString = node.classData.label; + if (node.classData.type !== void 0 && node.classData.type !== "") { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + classTitleString += "<" + node.classData.type + ">"; + } else { + classTitleString += "<" + node.classData.type + ">"; + } + } + const classTitleLabel = labelContainer.node().appendChild(createLabel$1(classTitleString, node.labelStyle, true, true)); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel).attr("class", "classTitle"); + let classTitleBBox = classTitleLabel.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = classTitleLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel); + classTitleBBox = div.getBoundingClientRect(); + dv.attr("width", classTitleBBox.width); + dv.attr("height", classTitleBBox.height); + } + maxHeight += classTitleBBox.height + rowPadding; + if (classTitleBBox.width > maxWidth) { + maxWidth = classTitleBBox.width; + } + const classAttributes = []; + node.classData.members.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let parsedText = parsedInfo.displayText; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + parsedText = parsedText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + parsedText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classAttributes.push(lbl); + }); + maxHeight += lineHeight; + const classMethods = []; + node.classData.methods.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let displayText = parsedInfo.displayText; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + displayText = displayText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + displayText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classMethods.push(lbl); + }); + maxHeight += lineHeight; + if (hasInterface) { + let diffX2 = (maxWidth - interfaceBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(interfaceLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")" + ); + verticalPos = interfaceBBox.height + rowPadding; + } + let diffX = (maxWidth - classTitleBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + verticalPos += classTitleBBox.height + rowPadding; + topLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classAttributes.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + verticalPos += lineHeight; + bottomLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classMethods.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + rect2.attr("style", node.style).attr("class", "outer title-state").attr("x", -maxWidth / 2 - halfPadding).attr("y", -(maxHeight / 2) - halfPadding).attr("width", maxWidth + node.padding).attr("height", maxHeight + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const shapes = { + rhombus: question, + composite, + question, + rect, + labelRect, + rectWithTitle, + choice, + circle, + doublecircle, + stadium, + hexagon, + block_arrow, + rect_left_inv_arrow, + lean_right, + lean_left, + trapezoid, + inv_trapezoid, + rect_right_inv_arrow, + cylinder, + start, + end, + note: note$1, + subroutine, + fork: forkJoin, + join: forkJoin, + class_box +}; +let nodeElems = {}; +const insertNode = async (elem, node, dir) => { + let newEl; + let el; + if (node.link) { + let target; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel === "sandbox") { + target = "_top"; + } else if (node.linkTarget) { + target = node.linkTarget || "_blank"; + } + newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target); + el = await shapes[node.shape](newEl, node, dir); + } else { + el = await shapes[node.shape](elem, node, dir); + newEl = el; + } + if (node.tooltip) { + el.attr("title", node.tooltip); + } + if (node.class) { + el.attr("class", "node default " + node.class); + } + newEl.attr("data-node", "true"); + newEl.attr("data-id", node.id); + nodeElems[node.id] = newEl; + if (node.haveCallback) { + nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable"); + } + return newEl; +}; +const setNodeElem = (elem, node) => { + nodeElems[node.id] = elem; +}; +const clear$1 = () => { + nodeElems = {}; +}; +const positionNode = (node) => { + const el = nodeElems[node.id]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace( + "Transforming node", + node.diff, + node, + "translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")" + ); + const padding = 8; + const diff = node.diff || 0; + if (node.clusterNode) { + el.attr( + "transform", + "translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")" + ); + } else { + el.attr("transform", "translate(" + node.x + ", " + node.y + ")"); + } + return diff; +}; +const getSubGraphTitleMargins = ({ + flowchart +}) => { + var _a, _b; + const subGraphTitleTopMargin = ((_a = flowchart == null ? void 0 : flowchart.subGraphTitleMargin) == null ? void 0 : _a.top) ?? 0; + const subGraphTitleBottomMargin = ((_b = flowchart == null ? void 0 : flowchart.subGraphTitleMargin) == null ? void 0 : _b.bottom) ?? 0; + const subGraphTitleTotalMargin = subGraphTitleTopMargin + subGraphTitleBottomMargin; + return { + subGraphTitleTopMargin, + subGraphTitleBottomMargin, + subGraphTitleTotalMargin + }; +}; +const markerOffsets = { + aggregation: 18, + extension: 18, + composition: 18, + dependency: 6, + lollipop: 13.5, + arrow_point: 5.3 +}; +function calculateDeltaAndAngle(point1, point2) { + if (point1 === void 0 || point2 === void 0) { + return { angle: 0, deltaX: 0, deltaY: 0 }; + } + point1 = pointTransformer(point1); + point2 = pointTransformer(point2); + const [x1, y1] = [point1.x, point1.y]; + const [x2, y2] = [point2.x, point2.y]; + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY }; +} +const pointTransformer = (data) => { + if (Array.isArray(data)) { + return { x: data[0], y: data[1] }; + } + return data; +}; +const getLineFunctionsWithOffset = (edge) => { + return { + x: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaX } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } + return pointTransformer(d).x + offset; + }, + y: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaY } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } + return pointTransformer(d).y + offset; + } + }; +}; +const addEdgeMarkers = (svgPath, edge, url, id, diagramType) => { + if (edge.arrowTypeStart) { + addEdgeMarker(svgPath, "start", edge.arrowTypeStart, url, id, diagramType); + } + if (edge.arrowTypeEnd) { + addEdgeMarker(svgPath, "end", edge.arrowTypeEnd, url, id, diagramType); + } +}; +const arrowTypesMap = { + arrow_cross: "cross", + arrow_point: "point", + arrow_barb: "barb", + arrow_circle: "circle", + aggregation: "aggregation", + extension: "extension", + composition: "composition", + dependency: "dependency", + lollipop: "lollipop" +}; +const addEdgeMarker = (svgPath, position, arrowType, url, id, diagramType) => { + const endMarkerType = arrowTypesMap[arrowType]; + if (!endMarkerType) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown arrow type: ${arrowType}`); + return; + } + const suffix = position === "start" ? "Start" : "End"; + svgPath.attr(`marker-${position}`, `url(${url}#${id}_${diagramType}-${endMarkerType}${suffix})`); +}; +let edgeLabels = {}; +let terminalLabels = {}; +const clear = () => { + edgeLabels = {}; + terminalLabels = {}; +}; +const insertEdgeLabel = (elem, edge) => { + const useHtmlLabels = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + const labelElement = edge.labelType === "markdown" ? (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__.a)(elem, edge.label, { + style: edge.labelStyle, + useHtmlLabels, + addSvgBackground: true + }) : createLabel$1(edge.label, edge.labelStyle); + const edgeLabel = elem.insert("g").attr("class", "edgeLabel"); + const label = edgeLabel.insert("g").attr("class", "label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + if (useHtmlLabels) { + const div = labelElement.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(labelElement); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + edgeLabels[edge.id] = edgeLabel; + edge.width = bbox.width; + edge.height = bbox.height; + let fo; + if (edge.startLabelLeft) { + const startLabelElement = createLabel$1(edge.startLabelLeft, edge.labelStyle); + const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startLeft = startEdgeLabelLeft; + setTerminalWidth(fo, edge.startLabelLeft); + } + if (edge.startLabelRight) { + const startLabelElement = createLabel$1(edge.startLabelRight, edge.labelStyle); + const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelRight.insert("g").attr("class", "inner"); + fo = startEdgeLabelRight.node().appendChild(startLabelElement); + inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startRight = startEdgeLabelRight; + setTerminalWidth(fo, edge.startLabelRight); + } + if (edge.endLabelLeft) { + const endLabelElement = createLabel$1(edge.endLabelLeft, edge.labelStyle); + const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelLeft.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endLeft = endEdgeLabelLeft; + setTerminalWidth(fo, edge.endLabelLeft); + } + if (edge.endLabelRight) { + const endLabelElement = createLabel$1(edge.endLabelRight, edge.labelStyle); + const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelRight.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelRight.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endRight = endEdgeLabelRight; + setTerminalWidth(fo, edge.endLabelRight); + } + return labelElement; +}; +function setTerminalWidth(fo, value) { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels && fo) { + fo.style.width = value.length * 9 + "px"; + fo.style.height = "12px"; + } +} +const positionEdgeLabel = (edge, paths) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("Moving label abc88 ", edge.id, edge.label, edgeLabels[edge.id], paths); + let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig); + if (edge.label) { + const el = edgeLabels[edge.id]; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcLabelPosition(path); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug( + "Moving label " + edge.label + " from (", + x, + ",", + y, + ") to (", + pos.x, + ",", + pos.y, + ") abc88" + ); + if (paths.updatedPath) { + x = pos.x; + y = pos.y; + } + } + el.attr("transform", `translate(${x}, ${y + subGraphTitleTotalMargin / 2})`); + } + if (edge.startLabelLeft) { + const el = terminalLabels[edge.id].startLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.startLabelRight) { + const el = terminalLabels[edge.id].startRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition( + edge.arrowTypeStart ? 10 : 0, + "start_right", + path + ); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.endLabelLeft) { + const el = terminalLabels[edge.id].endLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.endLabelRight) { + const el = terminalLabels[edge.id].endRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } +}; +const outsideNode = (node, point2) => { + const x = node.x; + const y = node.y; + const dx = Math.abs(point2.x - x); + const dy = Math.abs(point2.y - y); + const w = node.width / 2; + const h = node.height / 2; + if (dx >= w || dy >= h) { + return true; + } + return false; +}; +const intersection = (node, outsidePoint, insidePoint) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`intersection calc abc89: + outsidePoint: ${JSON.stringify(outsidePoint)} + insidePoint : ${JSON.stringify(insidePoint)} + node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`); + const x = node.x; + const y = node.y; + const dx = Math.abs(x - insidePoint.x); + const w = node.width / 2; + let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; + const h = node.height / 2; + const Q = Math.abs(outsidePoint.y - insidePoint.y); + const R = Math.abs(outsidePoint.x - insidePoint.x); + if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { + let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y; + r = R * q / Q; + const res = { + x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r, + y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q + }; + if (r === 0) { + res.x = outsidePoint.x; + res.y = outsidePoint.y; + } + if (R === 0) { + res.x = outsidePoint.x; + } + if (Q === 0) { + res.y = outsidePoint.y; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res); + return res; + } else { + if (insidePoint.x < outsidePoint.x) { + r = outsidePoint.x - w - x; + } else { + r = x - w - outsidePoint.x; + } + let q = Q * r / R; + let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r; + let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y }); + if (r === 0) { + _x = outsidePoint.x; + _y = outsidePoint.y; + } + if (R === 0) { + _x = outsidePoint.x; + } + if (Q === 0) { + _y = outsidePoint.y; + } + return { x: _x, y: _y }; + } +}; +const cutPathAtIntersect = (_points, boundaryNode) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("abc88 cutPathAtIntersect", _points, boundaryNode); + let points = []; + let lastPointOutside = _points[0]; + let isInside = false; + _points.forEach((point2) => { + if (!outsideNode(boundaryNode, point2) && !isInside) { + const inter = intersection(boundaryNode, lastPointOutside, point2); + let pointPresent = false; + points.forEach((p) => { + pointPresent = pointPresent || p.x === inter.x && p.y === inter.y; + }); + if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { + points.push(inter); + } + isInside = true; + } else { + lastPointOutside = point2; + if (!isInside) { + points.push(point2); + } + } + }); + return points; +}; +const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph, id) { + let points = edge.points; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("abc88 InsertEdge: edge=", edge, "e=", e); + let pointsHasChanged = false; + const tail = graph.node(e.v); + var head = graph.node(e.w); + if ((head == null ? void 0 : head.intersect) && (tail == null ? void 0 : tail.intersect)) { + points = points.slice(1, edge.points.length - 1); + points.unshift(tail.intersect(points[0])); + points.push(head.intersect(points[points.length - 1])); + } + if (edge.toCluster) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("to cluster abc88", clusterDb[edge.toCluster]); + points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); + pointsHasChanged = true; + } + if (edge.fromCluster) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("from cluster abc88", clusterDb[edge.fromCluster]); + points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse(); + pointsHasChanged = true; + } + const lineData = points.filter((p) => !Number.isNaN(p.y)); + let curve = d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .qrM; + if (edge.curve && (diagramType === "graph" || diagramType === "flowchart")) { + curve = edge.curve; + } + const { x, y } = getLineFunctionsWithOffset(edge); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .n8j)().x(x).y(y).curve(curve); + let strokeClasses; + switch (edge.thickness) { + case "normal": + strokeClasses = "edge-thickness-normal"; + break; + case "thick": + strokeClasses = "edge-thickness-thick"; + break; + case "invisible": + strokeClasses = "edge-thickness-thick"; + break; + default: + strokeClasses = ""; + } + switch (edge.pattern) { + case "solid": + strokeClasses += " edge-pattern-solid"; + break; + case "dotted": + strokeClasses += " edge-pattern-dotted"; + break; + case "dashed": + strokeClasses += " edge-pattern-dashed"; + break; + } + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style); + let url = ""; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.arrowMarkerAbsolute || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + addEdgeMarkers(svgPath, edge, url, id, diagramType); + let paths = {}; + if (pointsHasChanged) { + paths.updatedPath = points; + } + paths.originalPath = edge.points; + return paths; +}; + + + +/***/ }), + +/***/ 66216: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ f: () => (/* binding */ flowDb), +/* harmony export */ p: () => (/* binding */ parser$1) +/* harmony export */ }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 4], $V1 = [1, 3], $V2 = [1, 5], $V3 = [1, 8, 9, 10, 11, 27, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $V4 = [2, 2], $V5 = [1, 13], $V6 = [1, 14], $V7 = [1, 15], $V8 = [1, 16], $V9 = [1, 23], $Va = [1, 25], $Vb = [1, 26], $Vc = [1, 27], $Vd = [1, 49], $Ve = [1, 48], $Vf = [1, 29], $Vg = [1, 30], $Vh = [1, 31], $Vi = [1, 32], $Vj = [1, 33], $Vk = [1, 44], $Vl = [1, 46], $Vm = [1, 42], $Vn = [1, 47], $Vo = [1, 43], $Vp = [1, 50], $Vq = [1, 45], $Vr = [1, 51], $Vs = [1, 52], $Vt = [1, 34], $Vu = [1, 35], $Vv = [1, 36], $Vw = [1, 37], $Vx = [1, 57], $Vy = [1, 8, 9, 10, 11, 27, 32, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $Vz = [1, 61], $VA = [1, 60], $VB = [1, 62], $VC = [8, 9, 11, 73, 75], $VD = [1, 88], $VE = [1, 93], $VF = [1, 92], $VG = [1, 89], $VH = [1, 85], $VI = [1, 91], $VJ = [1, 87], $VK = [1, 94], $VL = [1, 90], $VM = [1, 95], $VN = [1, 86], $VO = [8, 9, 10, 11, 73, 75], $VP = [8, 9, 10, 11, 44, 73, 75], $VQ = [8, 9, 10, 11, 29, 42, 44, 46, 48, 50, 52, 54, 56, 58, 61, 63, 65, 66, 68, 73, 75, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VR = [8, 9, 11, 42, 58, 73, 75, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VS = [42, 58, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VT = [1, 121], $VU = [1, 120], $VV = [1, 128], $VW = [1, 142], $VX = [1, 143], $VY = [1, 144], $VZ = [1, 145], $V_ = [1, 130], $V$ = [1, 132], $V01 = [1, 136], $V11 = [1, 137], $V21 = [1, 138], $V31 = [1, 139], $V41 = [1, 140], $V51 = [1, 141], $V61 = [1, 146], $V71 = [1, 147], $V81 = [1, 126], $V91 = [1, 127], $Va1 = [1, 134], $Vb1 = [1, 129], $Vc1 = [1, 133], $Vd1 = [1, 131], $Ve1 = [8, 9, 10, 11, 27, 32, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $Vf1 = [1, 149], $Vg1 = [8, 9, 11], $Vh1 = [8, 9, 10, 11, 14, 42, 58, 86, 102, 103, 106, 108, 111, 112, 113], $Vi1 = [1, 169], $Vj1 = [1, 165], $Vk1 = [1, 166], $Vl1 = [1, 170], $Vm1 = [1, 167], $Vn1 = [1, 168], $Vo1 = [75, 113, 116], $Vp1 = [8, 9, 10, 11, 12, 14, 27, 29, 32, 42, 58, 73, 81, 82, 83, 84, 85, 86, 87, 102, 106, 108, 111, 112, 113], $Vq1 = [10, 103], $Vr1 = [31, 47, 49, 51, 53, 55, 60, 62, 64, 65, 67, 69, 113, 114, 115], $Vs1 = [1, 235], $Vt1 = [1, 233], $Vu1 = [1, 237], $Vv1 = [1, 231], $Vw1 = [1, 232], $Vx1 = [1, 234], $Vy1 = [1, 236], $Vz1 = [1, 238], $VA1 = [1, 255], $VB1 = [8, 9, 11, 103], $VC1 = [8, 9, 10, 11, 58, 81, 102, 103, 106, 107, 108, 109]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "graphConfig": 4, "document": 5, "line": 6, "statement": 7, "SEMI": 8, "NEWLINE": 9, "SPACE": 10, "EOF": 11, "GRAPH": 12, "NODIR": 13, "DIR": 14, "FirstStmtSeparator": 15, "ending": 16, "endToken": 17, "spaceList": 18, "spaceListNewline": 19, "vertexStatement": 20, "separator": 21, "styleStatement": 22, "linkStyleStatement": 23, "classDefStatement": 24, "classStatement": 25, "clickStatement": 26, "subgraph": 27, "textNoTags": 28, "SQS": 29, "text": 30, "SQE": 31, "end": 32, "direction": 33, "acc_title": 34, "acc_title_value": 35, "acc_descr": 36, "acc_descr_value": 37, "acc_descr_multiline_value": 38, "link": 39, "node": 40, "styledVertex": 41, "AMP": 42, "vertex": 43, "STYLE_SEPARATOR": 44, "idString": 45, "DOUBLECIRCLESTART": 46, "DOUBLECIRCLEEND": 47, "PS": 48, "PE": 49, "(-": 50, "-)": 51, "STADIUMSTART": 52, "STADIUMEND": 53, "SUBROUTINESTART": 54, "SUBROUTINEEND": 55, "VERTEX_WITH_PROPS_START": 56, "NODE_STRING[field]": 57, "COLON": 58, "NODE_STRING[value]": 59, "PIPE": 60, "CYLINDERSTART": 61, "CYLINDEREND": 62, "DIAMOND_START": 63, "DIAMOND_STOP": 64, "TAGEND": 65, "TRAPSTART": 66, "TRAPEND": 67, "INVTRAPSTART": 68, "INVTRAPEND": 69, "linkStatement": 70, "arrowText": 71, "TESTSTR": 72, "START_LINK": 73, "edgeText": 74, "LINK": 75, "edgeTextToken": 76, "STR": 77, "MD_STR": 78, "textToken": 79, "keywords": 80, "STYLE": 81, "LINKSTYLE": 82, "CLASSDEF": 83, "CLASS": 84, "CLICK": 85, "DOWN": 86, "UP": 87, "textNoTagsToken": 88, "stylesOpt": 89, "idString[vertex]": 90, "idString[class]": 91, "CALLBACKNAME": 92, "CALLBACKARGS": 93, "HREF": 94, "LINK_TARGET": 95, "STR[link]": 96, "STR[tooltip]": 97, "alphaNum": 98, "DEFAULT": 99, "numList": 100, "INTERPOLATE": 101, "NUM": 102, "COMMA": 103, "style": 104, "styleComponent": 105, "NODE_STRING": 106, "UNIT": 107, "BRKT": 108, "PCT": 109, "idStringToken": 110, "MINUS": 111, "MULT": 112, "UNICODE_TEXT": 113, "TEXT": 114, "TAGSTART": 115, "EDGE_TEXT": 116, "alphaNumToken": 117, "direction_tb": 118, "direction_bt": 119, "direction_rl": 120, "direction_lr": 121, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 8: "SEMI", 9: "NEWLINE", 10: "SPACE", 11: "EOF", 12: "GRAPH", 13: "NODIR", 14: "DIR", 27: "subgraph", 29: "SQS", 31: "SQE", 32: "end", 34: "acc_title", 35: "acc_title_value", 36: "acc_descr", 37: "acc_descr_value", 38: "acc_descr_multiline_value", 42: "AMP", 44: "STYLE_SEPARATOR", 46: "DOUBLECIRCLESTART", 47: "DOUBLECIRCLEEND", 48: "PS", 49: "PE", 50: "(-", 51: "-)", 52: "STADIUMSTART", 53: "STADIUMEND", 54: "SUBROUTINESTART", 55: "SUBROUTINEEND", 56: "VERTEX_WITH_PROPS_START", 57: "NODE_STRING[field]", 58: "COLON", 59: "NODE_STRING[value]", 60: "PIPE", 61: "CYLINDERSTART", 62: "CYLINDEREND", 63: "DIAMOND_START", 64: "DIAMOND_STOP", 65: "TAGEND", 66: "TRAPSTART", 67: "TRAPEND", 68: "INVTRAPSTART", 69: "INVTRAPEND", 72: "TESTSTR", 73: "START_LINK", 75: "LINK", 77: "STR", 78: "MD_STR", 81: "STYLE", 82: "LINKSTYLE", 83: "CLASSDEF", 84: "CLASS", 85: "CLICK", 86: "DOWN", 87: "UP", 90: "idString[vertex]", 91: "idString[class]", 92: "CALLBACKNAME", 93: "CALLBACKARGS", 94: "HREF", 95: "LINK_TARGET", 96: "STR[link]", 97: "STR[tooltip]", 99: "DEFAULT", 101: "INTERPOLATE", 102: "NUM", 103: "COMMA", 106: "NODE_STRING", 107: "UNIT", 108: "BRKT", 109: "PCT", 111: "MINUS", 112: "MULT", 113: "UNICODE_TEXT", 114: "TEXT", 115: "TAGSTART", 116: "EDGE_TEXT", 118: "direction_tb", 119: "direction_bt", 120: "direction_rl", 121: "direction_lr" }, + productions_: [0, [3, 2], [5, 0], [5, 2], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [4, 2], [4, 2], [4, 2], [4, 3], [16, 2], [16, 1], [17, 1], [17, 1], [17, 1], [15, 1], [15, 1], [15, 2], [19, 2], [19, 2], [19, 1], [19, 1], [18, 2], [18, 1], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 9], [7, 6], [7, 4], [7, 1], [7, 2], [7, 2], [7, 1], [21, 1], [21, 1], [21, 1], [20, 3], [20, 4], [20, 2], [20, 1], [40, 1], [40, 5], [41, 1], [41, 3], [43, 4], [43, 4], [43, 6], [43, 4], [43, 4], [43, 4], [43, 8], [43, 4], [43, 4], [43, 4], [43, 6], [43, 4], [43, 4], [43, 4], [43, 4], [43, 4], [43, 1], [39, 2], [39, 3], [39, 3], [39, 1], [39, 3], [74, 1], [74, 2], [74, 1], [74, 1], [70, 1], [71, 3], [30, 1], [30, 2], [30, 1], [30, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [28, 1], [28, 2], [28, 1], [28, 1], [24, 5], [25, 5], [26, 2], [26, 4], [26, 3], [26, 5], [26, 3], [26, 5], [26, 5], [26, 7], [26, 2], [26, 4], [26, 2], [26, 4], [26, 4], [26, 6], [22, 5], [23, 5], [23, 5], [23, 9], [23, 9], [23, 7], [23, 7], [100, 1], [100, 3], [89, 1], [89, 3], [104, 1], [104, 2], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [79, 1], [79, 1], [79, 1], [79, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [76, 1], [76, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [45, 1], [45, 2], [98, 1], [98, 2], [33, 1], [33, 1], [33, 1], [33, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 2: + this.$ = []; + break; + case 3: + if (!Array.isArray($$[$0]) || $$[$0].length > 0) { + $$[$0 - 1].push($$[$0]); + } + this.$ = $$[$0 - 1]; + break; + case 4: + case 176: + this.$ = $$[$0]; + break; + case 11: + yy.setDirection("TB"); + this.$ = "TB"; + break; + case 12: + yy.setDirection($$[$0 - 1]); + this.$ = $$[$0 - 1]; + break; + case 27: + this.$ = $$[$0 - 1].nodes; + break; + case 28: + case 29: + case 30: + case 31: + case 32: + this.$ = []; + break; + case 33: + this.$ = yy.addSubGraph($$[$0 - 6], $$[$0 - 1], $$[$0 - 4]); + break; + case 34: + this.$ = yy.addSubGraph($$[$0 - 3], $$[$0 - 1], $$[$0 - 3]); + break; + case 35: + this.$ = yy.addSubGraph(void 0, $$[$0 - 1], void 0); + break; + case 37: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 38: + case 39: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 43: + yy.addLink($$[$0 - 2].stmt, $$[$0], $$[$0 - 1]); + this.$ = { stmt: $$[$0], nodes: $$[$0].concat($$[$0 - 2].nodes) }; + break; + case 44: + yy.addLink($$[$0 - 3].stmt, $$[$0 - 1], $$[$0 - 2]); + this.$ = { stmt: $$[$0 - 1], nodes: $$[$0 - 1].concat($$[$0 - 3].nodes) }; + break; + case 45: + this.$ = { stmt: $$[$0 - 1], nodes: $$[$0 - 1] }; + break; + case 46: + this.$ = { stmt: $$[$0], nodes: $$[$0] }; + break; + case 47: + this.$ = [$$[$0]]; + break; + case 48: + this.$ = $$[$0 - 4].concat($$[$0]); + break; + case 49: + this.$ = $$[$0]; + break; + case 50: + this.$ = $$[$0 - 2]; + yy.setClass($$[$0 - 2], $$[$0]); + break; + case 51: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "square"); + break; + case 52: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "doublecircle"); + break; + case 53: + this.$ = $$[$0 - 5]; + yy.addVertex($$[$0 - 5], $$[$0 - 2], "circle"); + break; + case 54: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "ellipse"); + break; + case 55: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "stadium"); + break; + case 56: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "subroutine"); + break; + case 57: + this.$ = $$[$0 - 7]; + yy.addVertex($$[$0 - 7], $$[$0 - 1], "rect", void 0, void 0, void 0, Object.fromEntries([[$$[$0 - 5], $$[$0 - 3]]])); + break; + case 58: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "cylinder"); + break; + case 59: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "round"); + break; + case 60: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "diamond"); + break; + case 61: + this.$ = $$[$0 - 5]; + yy.addVertex($$[$0 - 5], $$[$0 - 2], "hexagon"); + break; + case 62: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "odd"); + break; + case 63: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "trapezoid"); + break; + case 64: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "inv_trapezoid"); + break; + case 65: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "lean_right"); + break; + case 66: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "lean_left"); + break; + case 67: + this.$ = $$[$0]; + yy.addVertex($$[$0]); + break; + case 68: + $$[$0 - 1].text = $$[$0]; + this.$ = $$[$0 - 1]; + break; + case 69: + case 70: + $$[$0 - 2].text = $$[$0 - 1]; + this.$ = $$[$0 - 2]; + break; + case 71: + this.$ = $$[$0]; + break; + case 72: + var inf = yy.destructLink($$[$0], $$[$0 - 2]); + this.$ = { "type": inf.type, "stroke": inf.stroke, "length": inf.length, "text": $$[$0 - 1] }; + break; + case 73: + this.$ = { text: $$[$0], type: "text" }; + break; + case 74: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 75: + this.$ = { text: $$[$0], type: "string" }; + break; + case 76: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 77: + var inf = yy.destructLink($$[$0]); + this.$ = { "type": inf.type, "stroke": inf.stroke, "length": inf.length }; + break; + case 78: + this.$ = $$[$0 - 1]; + break; + case 79: + this.$ = { text: $$[$0], type: "text" }; + break; + case 80: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 81: + this.$ = { text: $$[$0], type: "string" }; + break; + case 82: + case 97: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 94: + this.$ = { text: $$[$0], type: "text" }; + break; + case 95: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 96: + this.$ = { text: $$[$0], type: "text" }; + break; + case 98: + this.$ = $$[$0 - 4]; + yy.addClass($$[$0 - 2], $$[$0]); + break; + case 99: + this.$ = $$[$0 - 4]; + yy.setClass($$[$0 - 2], $$[$0]); + break; + case 100: + case 108: + this.$ = $$[$0 - 1]; + yy.setClickEvent($$[$0 - 1], $$[$0]); + break; + case 101: + case 109: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 102: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 103: + this.$ = $$[$0 - 4]; + yy.setClickEvent($$[$0 - 4], $$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 4], $$[$0]); + break; + case 104: + this.$ = $$[$0 - 2]; + yy.setLink($$[$0 - 2], $$[$0]); + break; + case 105: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 4], $$[$0 - 2]); + yy.setTooltip($$[$0 - 4], $$[$0]); + break; + case 106: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 4], $$[$0 - 2], $$[$0]); + break; + case 107: + this.$ = $$[$0 - 6]; + yy.setLink($$[$0 - 6], $$[$0 - 4], $$[$0]); + yy.setTooltip($$[$0 - 6], $$[$0 - 2]); + break; + case 110: + this.$ = $$[$0 - 1]; + yy.setLink($$[$0 - 1], $$[$0]); + break; + case 111: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 112: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 3], $$[$0 - 2], $$[$0]); + break; + case 113: + this.$ = $$[$0 - 5]; + yy.setLink($$[$0 - 5], $$[$0 - 4], $$[$0]); + yy.setTooltip($$[$0 - 5], $$[$0 - 2]); + break; + case 114: + this.$ = $$[$0 - 4]; + yy.addVertex($$[$0 - 2], void 0, void 0, $$[$0]); + break; + case 115: + this.$ = $$[$0 - 4]; + yy.updateLink([$$[$0 - 2]], $$[$0]); + break; + case 116: + this.$ = $$[$0 - 4]; + yy.updateLink($$[$0 - 2], $$[$0]); + break; + case 117: + this.$ = $$[$0 - 8]; + yy.updateLinkInterpolate([$$[$0 - 6]], $$[$0 - 2]); + yy.updateLink([$$[$0 - 6]], $$[$0]); + break; + case 118: + this.$ = $$[$0 - 8]; + yy.updateLinkInterpolate($$[$0 - 6], $$[$0 - 2]); + yy.updateLink($$[$0 - 6], $$[$0]); + break; + case 119: + this.$ = $$[$0 - 6]; + yy.updateLinkInterpolate([$$[$0 - 4]], $$[$0]); + break; + case 120: + this.$ = $$[$0 - 6]; + yy.updateLinkInterpolate($$[$0 - 4], $$[$0]); + break; + case 121: + case 123: + this.$ = [$$[$0]]; + break; + case 122: + case 124: + $$[$0 - 2].push($$[$0]); + this.$ = $$[$0 - 2]; + break; + case 126: + this.$ = $$[$0 - 1] + $$[$0]; + break; + case 174: + this.$ = $$[$0]; + break; + case 175: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + case 177: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + case 178: + this.$ = { stmt: "dir", value: "TB" }; + break; + case 179: + this.$ = { stmt: "dir", value: "BT" }; + break; + case 180: + this.$ = { stmt: "dir", value: "RL" }; + break; + case 181: + this.$ = { stmt: "dir", value: "LR" }; + break; + } + }, + table: [{ 3: 1, 4: 2, 9: $V0, 10: $V1, 12: $V2 }, { 1: [3] }, o($V3, $V4, { 5: 6 }), { 4: 7, 9: $V0, 10: $V1, 12: $V2 }, { 4: 8, 9: $V0, 10: $V1, 12: $V2 }, { 13: [1, 9], 14: [1, 10] }, { 1: [2, 1], 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, o($V3, [2, 9]), o($V3, [2, 10]), o($V3, [2, 11]), { 8: [1, 54], 9: [1, 55], 10: $Vx, 15: 53, 18: 56 }, o($Vy, [2, 3]), o($Vy, [2, 4]), o($Vy, [2, 5]), o($Vy, [2, 6]), o($Vy, [2, 7]), o($Vy, [2, 8]), { 8: $Vz, 9: $VA, 11: $VB, 21: 58, 39: 59, 70: 63, 73: [1, 64], 75: [1, 65] }, { 8: $Vz, 9: $VA, 11: $VB, 21: 66 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 67 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 68 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 69 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 70 }, { 8: $Vz, 9: $VA, 10: [1, 71], 11: $VB, 21: 72 }, o($Vy, [2, 36]), { 35: [1, 73] }, { 37: [1, 74] }, o($Vy, [2, 39]), o($VC, [2, 46], { 18: 75, 10: $Vx }), { 10: [1, 76] }, { 10: [1, 77] }, { 10: [1, 78] }, { 10: [1, 79] }, { 14: $VD, 42: $VE, 58: $VF, 77: [1, 83], 86: $VG, 92: [1, 80], 94: [1, 81], 98: 82, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, o($Vy, [2, 178]), o($Vy, [2, 179]), o($Vy, [2, 180]), o($Vy, [2, 181]), o($VO, [2, 47]), o($VO, [2, 49], { 44: [1, 96] }), o($VP, [2, 67], { 110: 109, 29: [1, 97], 42: $Vd, 46: [1, 98], 48: [1, 99], 50: [1, 100], 52: [1, 101], 54: [1, 102], 56: [1, 103], 58: $Ve, 61: [1, 104], 63: [1, 105], 65: [1, 106], 66: [1, 107], 68: [1, 108], 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), o($VQ, [2, 174]), o($VQ, [2, 135]), o($VQ, [2, 136]), o($VQ, [2, 137]), o($VQ, [2, 138]), o($VQ, [2, 139]), o($VQ, [2, 140]), o($VQ, [2, 141]), o($VQ, [2, 142]), o($VQ, [2, 143]), o($VQ, [2, 144]), o($VQ, [2, 145]), o($V3, [2, 12]), o($V3, [2, 18]), o($V3, [2, 19]), { 9: [1, 110] }, o($VR, [2, 26], { 18: 111, 10: $Vx }), o($Vy, [2, 27]), { 40: 112, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vy, [2, 40]), o($Vy, [2, 41]), o($Vy, [2, 42]), o($VS, [2, 71], { 71: 113, 60: [1, 115], 72: [1, 114] }), { 74: 116, 76: 117, 77: [1, 118], 78: [1, 119], 113: $VT, 116: $VU }, o([42, 58, 60, 72, 86, 99, 102, 103, 106, 108, 111, 112, 113], [2, 77]), o($Vy, [2, 28]), o($Vy, [2, 29]), o($Vy, [2, 30]), o($Vy, [2, 31]), o($Vy, [2, 32]), { 10: $VV, 12: $VW, 14: $VX, 27: $VY, 28: 122, 32: $VZ, 42: $V_, 58: $V$, 73: $V01, 77: [1, 124], 78: [1, 125], 80: 135, 81: $V11, 82: $V21, 83: $V31, 84: $V41, 85: $V51, 86: $V61, 87: $V71, 88: 123, 102: $V81, 106: $V91, 108: $Va1, 111: $Vb1, 112: $Vc1, 113: $Vd1 }, o($Ve1, $V4, { 5: 148 }), o($Vy, [2, 37]), o($Vy, [2, 38]), o($VC, [2, 45], { 42: $Vf1 }), { 42: $Vd, 45: 150, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 99: [1, 151], 100: 152, 102: [1, 153] }, { 42: $Vd, 45: 154, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 42: $Vd, 45: 155, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vg1, [2, 100], { 10: [1, 156], 93: [1, 157] }), { 77: [1, 158] }, o($Vg1, [2, 108], { 117: 160, 10: [1, 159], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 110], { 10: [1, 161] }), o($Vh1, [2, 176]), o($Vh1, [2, 163]), o($Vh1, [2, 164]), o($Vh1, [2, 165]), o($Vh1, [2, 166]), o($Vh1, [2, 167]), o($Vh1, [2, 168]), o($Vh1, [2, 169]), o($Vh1, [2, 170]), o($Vh1, [2, 171]), o($Vh1, [2, 172]), o($Vh1, [2, 173]), { 42: $Vd, 45: 162, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 30: 163, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 171, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 173, 48: [1, 172], 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 174, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 175, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 176, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 106: [1, 177] }, { 30: 178, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 179, 63: [1, 180], 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 181, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 182, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 183, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VQ, [2, 175]), o($V3, [2, 20]), o($VR, [2, 25]), o($VC, [2, 43], { 18: 184, 10: $Vx }), o($VS, [2, 68], { 10: [1, 185] }), { 10: [1, 186] }, { 30: 187, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 75: [1, 188], 76: 189, 113: $VT, 116: $VU }, o($Vo1, [2, 73]), o($Vo1, [2, 75]), o($Vo1, [2, 76]), o($Vo1, [2, 161]), o($Vo1, [2, 162]), { 8: $Vz, 9: $VA, 10: $VV, 11: $VB, 12: $VW, 14: $VX, 21: 191, 27: $VY, 29: [1, 190], 32: $VZ, 42: $V_, 58: $V$, 73: $V01, 80: 135, 81: $V11, 82: $V21, 83: $V31, 84: $V41, 85: $V51, 86: $V61, 87: $V71, 88: 192, 102: $V81, 106: $V91, 108: $Va1, 111: $Vb1, 112: $Vc1, 113: $Vd1 }, o($Vp1, [2, 94]), o($Vp1, [2, 96]), o($Vp1, [2, 97]), o($Vp1, [2, 150]), o($Vp1, [2, 151]), o($Vp1, [2, 152]), o($Vp1, [2, 153]), o($Vp1, [2, 154]), o($Vp1, [2, 155]), o($Vp1, [2, 156]), o($Vp1, [2, 157]), o($Vp1, [2, 158]), o($Vp1, [2, 159]), o($Vp1, [2, 160]), o($Vp1, [2, 83]), o($Vp1, [2, 84]), o($Vp1, [2, 85]), o($Vp1, [2, 86]), o($Vp1, [2, 87]), o($Vp1, [2, 88]), o($Vp1, [2, 89]), o($Vp1, [2, 90]), o($Vp1, [2, 91]), o($Vp1, [2, 92]), o($Vp1, [2, 93]), { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 193], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, { 10: $Vx, 18: 194 }, { 10: [1, 195], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: [1, 196] }, { 10: [1, 197], 103: [1, 198] }, o($Vq1, [2, 121]), { 10: [1, 199], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: [1, 200], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 77: [1, 201] }, o($Vg1, [2, 102], { 10: [1, 202] }), o($Vg1, [2, 104], { 10: [1, 203] }), { 77: [1, 204] }, o($Vh1, [2, 177]), { 77: [1, 205], 95: [1, 206] }, o($VO, [2, 50], { 110: 109, 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), { 31: [1, 207], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($Vr1, [2, 79]), o($Vr1, [2, 81]), o($Vr1, [2, 82]), o($Vr1, [2, 146]), o($Vr1, [2, 147]), o($Vr1, [2, 148]), o($Vr1, [2, 149]), { 47: [1, 209], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 210, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 49: [1, 211], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 51: [1, 212], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 53: [1, 213], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 55: [1, 214], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 58: [1, 215] }, { 62: [1, 216], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 64: [1, 217], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 218, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 31: [1, 219], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 65: $Vi1, 67: [1, 220], 69: [1, 221], 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 65: $Vi1, 67: [1, 223], 69: [1, 222], 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VC, [2, 44], { 42: $Vf1 }), o($VS, [2, 70]), o($VS, [2, 69]), { 60: [1, 224], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VS, [2, 72]), o($Vo1, [2, 74]), { 30: 225, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($Ve1, $V4, { 5: 226 }), o($Vp1, [2, 95]), o($Vy, [2, 35]), { 41: 227, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 228, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 239, 101: [1, 240], 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 241, 101: [1, 242], 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 102: [1, 243] }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 244, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 42: $Vd, 45: 245, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vg1, [2, 101]), { 77: [1, 246] }, { 77: [1, 247], 95: [1, 248] }, o($Vg1, [2, 109]), o($Vg1, [2, 111], { 10: [1, 249] }), o($Vg1, [2, 112]), o($VP, [2, 51]), o($Vr1, [2, 80]), o($VP, [2, 52]), { 49: [1, 250], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 59]), o($VP, [2, 54]), o($VP, [2, 55]), o($VP, [2, 56]), { 106: [1, 251] }, o($VP, [2, 58]), o($VP, [2, 60]), { 64: [1, 252], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 62]), o($VP, [2, 63]), o($VP, [2, 65]), o($VP, [2, 64]), o($VP, [2, 66]), o([10, 42, 58, 86, 99, 102, 103, 106, 108, 111, 112, 113], [2, 78]), { 31: [1, 253], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 254], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, o($VO, [2, 48]), o($Vg1, [2, 114], { 103: $VA1 }), o($VB1, [2, 123], { 105: 256, 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }), o($VC1, [2, 125]), o($VC1, [2, 127]), o($VC1, [2, 128]), o($VC1, [2, 129]), o($VC1, [2, 130]), o($VC1, [2, 131]), o($VC1, [2, 132]), o($VC1, [2, 133]), o($VC1, [2, 134]), o($Vg1, [2, 115], { 103: $VA1 }), { 10: [1, 257] }, o($Vg1, [2, 116], { 103: $VA1 }), { 10: [1, 258] }, o($Vq1, [2, 122]), o($Vg1, [2, 98], { 103: $VA1 }), o($Vg1, [2, 99], { 110: 109, 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), o($Vg1, [2, 103]), o($Vg1, [2, 105], { 10: [1, 259] }), o($Vg1, [2, 106]), { 95: [1, 260] }, { 49: [1, 261] }, { 60: [1, 262] }, { 64: [1, 263] }, { 8: $Vz, 9: $VA, 11: $VB, 21: 264 }, o($Vy, [2, 34]), { 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 104: 265, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, o($VC1, [2, 126]), { 14: $VD, 42: $VE, 58: $VF, 86: $VG, 98: 266, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, { 14: $VD, 42: $VE, 58: $VF, 86: $VG, 98: 267, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, { 95: [1, 268] }, o($Vg1, [2, 113]), o($VP, [2, 53]), { 30: 269, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 61]), o($Ve1, $V4, { 5: 270 }), o($VB1, [2, 124], { 105: 256, 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }), o($Vg1, [2, 119], { 117: 160, 10: [1, 271], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 120], { 117: 160, 10: [1, 272], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 107]), { 31: [1, 273], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 274], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 275, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 276, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, o($VP, [2, 57]), o($Vy, [2, 33]), o($Vg1, [2, 117], { 103: $VA1 }), o($Vg1, [2, 118], { 103: $VA1 })], + defaultActions: {}, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex2() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex2(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex2() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.begin("acc_title"); + return 34; + case 1: + this.popState(); + return "acc_title_value"; + case 2: + this.begin("acc_descr"); + return 36; + case 3: + this.popState(); + return "acc_descr_value"; + case 4: + this.begin("acc_descr_multiline"); + break; + case 5: + this.popState(); + break; + case 6: + return "acc_descr_multiline_value"; + case 7: + this.begin("callbackname"); + break; + case 8: + this.popState(); + break; + case 9: + this.popState(); + this.begin("callbackargs"); + break; + case 10: + return 92; + case 11: + this.popState(); + break; + case 12: + return 93; + case 13: + return "MD_STR"; + case 14: + this.popState(); + break; + case 15: + this.begin("md_string"); + break; + case 16: + return "STR"; + case 17: + this.popState(); + break; + case 18: + this.pushState("string"); + break; + case 19: + return 81; + case 20: + return 99; + case 21: + return 82; + case 22: + return 101; + case 23: + return 83; + case 24: + return 84; + case 25: + return 94; + case 26: + this.begin("click"); + break; + case 27: + this.popState(); + break; + case 28: + return 85; + case 29: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 30: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 31: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 32: + return 27; + case 33: + return 32; + case 34: + return 95; + case 35: + return 95; + case 36: + return 95; + case 37: + return 95; + case 38: + this.popState(); + return 13; + case 39: + this.popState(); + return 14; + case 40: + this.popState(); + return 14; + case 41: + this.popState(); + return 14; + case 42: + this.popState(); + return 14; + case 43: + this.popState(); + return 14; + case 44: + this.popState(); + return 14; + case 45: + this.popState(); + return 14; + case 46: + this.popState(); + return 14; + case 47: + this.popState(); + return 14; + case 48: + this.popState(); + return 14; + case 49: + return 118; + case 50: + return 119; + case 51: + return 120; + case 52: + return 121; + case 53: + return 102; + case 54: + return 108; + case 55: + return 44; + case 56: + return 58; + case 57: + return 42; + case 58: + return 8; + case 59: + return 103; + case 60: + return 112; + case 61: + this.popState(); + return 75; + case 62: + this.pushState("edgeText"); + return 73; + case 63: + return 116; + case 64: + this.popState(); + return 75; + case 65: + this.pushState("thickEdgeText"); + return 73; + case 66: + return 116; + case 67: + this.popState(); + return 75; + case 68: + this.pushState("dottedEdgeText"); + return 73; + case 69: + return 116; + case 70: + return 75; + case 71: + this.popState(); + return 51; + case 72: + return "TEXT"; + case 73: + this.pushState("ellipseText"); + return 50; + case 74: + this.popState(); + return 53; + case 75: + this.pushState("text"); + return 52; + case 76: + this.popState(); + return 55; + case 77: + this.pushState("text"); + return 54; + case 78: + return 56; + case 79: + this.pushState("text"); + return 65; + case 80: + this.popState(); + return 62; + case 81: + this.pushState("text"); + return 61; + case 82: + this.popState(); + return 47; + case 83: + this.pushState("text"); + return 46; + case 84: + this.popState(); + return 67; + case 85: + this.popState(); + return 69; + case 86: + return 114; + case 87: + this.pushState("trapText"); + return 66; + case 88: + this.pushState("trapText"); + return 68; + case 89: + return 115; + case 90: + return 65; + case 91: + return 87; + case 92: + return "SEP"; + case 93: + return 86; + case 94: + return 112; + case 95: + return 108; + case 96: + return 42; + case 97: + return 106; + case 98: + return 111; + case 99: + return 113; + case 100: + this.popState(); + return 60; + case 101: + this.pushState("text"); + return 60; + case 102: + this.popState(); + return 49; + case 103: + this.pushState("text"); + return 48; + case 104: + this.popState(); + return 31; + case 105: + this.pushState("text"); + return 29; + case 106: + this.popState(); + return 64; + case 107: + this.pushState("text"); + return 63; + case 108: + return "TEXT"; + case 109: + return "QUOTE"; + case 110: + return 9; + case 111: + return 10; + case 112: + return 11; + } + }, + rules: [/^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:call[\s]+)/, /^(?:\([\s]*\))/, /^(?:\()/, /^(?:[^(]*)/, /^(?:\))/, /^(?:[^)]*)/, /^(?:[^`"]+)/, /^(?:[`]["])/, /^(?:["][`])/, /^(?:[^"]+)/, /^(?:["])/, /^(?:["])/, /^(?:style\b)/, /^(?:default\b)/, /^(?:linkStyle\b)/, /^(?:interpolate\b)/, /^(?:classDef\b)/, /^(?:class\b)/, /^(?:href[\s])/, /^(?:click[\s]+)/, /^(?:[\s\n])/, /^(?:[^\s\n]*)/, /^(?:flowchart-elk\b)/, /^(?:graph\b)/, /^(?:flowchart\b)/, /^(?:subgraph\b)/, /^(?:end\b\s*)/, /^(?:_self\b)/, /^(?:_blank\b)/, /^(?:_parent\b)/, /^(?:_top\b)/, /^(?:(\r?\n)*\s*\n)/, /^(?:\s*LR\b)/, /^(?:\s*RL\b)/, /^(?:\s*TB\b)/, /^(?:\s*BT\b)/, /^(?:\s*TD\b)/, /^(?:\s*BR\b)/, /^(?:\s*<)/, /^(?:\s*>)/, /^(?:\s*\^)/, /^(?:\s*v\b)/, /^(?:.*direction\s+TB[^\n]*)/, /^(?:.*direction\s+BT[^\n]*)/, /^(?:.*direction\s+RL[^\n]*)/, /^(?:.*direction\s+LR[^\n]*)/, /^(?:[0-9]+)/, /^(?:#)/, /^(?::::)/, /^(?::)/, /^(?:&)/, /^(?:;)/, /^(?:,)/, /^(?:\*)/, /^(?:\s*[xo<]?--+[-xo>]\s*)/, /^(?:\s*[xo<]?--\s*)/, /^(?:[^-]|-(?!-)+)/, /^(?:\s*[xo<]?==+[=xo>]\s*)/, /^(?:\s*[xo<]?==\s*)/, /^(?:[^=]|=(?!))/, /^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/, /^(?:\s*[xo<]?-\.\s*)/, /^(?:[^\.]|\.(?!))/, /^(?:\s*~~[\~]+\s*)/, /^(?:[-/\)][\)])/, /^(?:[^\(\)\[\]\{\}]|!\)+)/, /^(?:\(-)/, /^(?:\]\))/, /^(?:\(\[)/, /^(?:\]\])/, /^(?:\[\[)/, /^(?:\[\|)/, /^(?:>)/, /^(?:\)\])/, /^(?:\[\()/, /^(?:\)\)\))/, /^(?:\(\(\()/, /^(?:[\\(?=\])][\]])/, /^(?:\/(?=\])\])/, /^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/, /^(?:\[\/)/, /^(?:\[\\)/, /^(?:<)/, /^(?:>)/, /^(?:\^)/, /^(?:\\\|)/, /^(?:v\b)/, /^(?:\*)/, /^(?:#)/, /^(?:&)/, /^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/, /^(?:-)/, /^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/, /^(?:\|)/, /^(?:\|)/, /^(?:\))/, /^(?:\()/, /^(?:\])/, /^(?:\[)/, /^(?:(\}))/, /^(?:\{)/, /^(?:[^\[\]\(\)\{\}\|\"]+)/, /^(?:")/, /^(?:(\r?\n)+)/, /^(?:\s)/, /^(?:$)/], + conditions: { "callbackargs": { "rules": [11, 12, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "callbackname": { "rules": [8, 9, 10, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "href": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "click": { "rules": [15, 18, 27, 28, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "dottedEdgeText": { "rules": [15, 18, 67, 69, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "thickEdgeText": { "rules": [15, 18, 64, 66, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "edgeText": { "rules": [15, 18, 61, 63, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "trapText": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 84, 85, 86, 87, 88, 101, 103, 105, 107], "inclusive": false }, "ellipseText": { "rules": [15, 18, 70, 71, 72, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "text": { "rules": [15, 18, 70, 73, 74, 75, 76, 77, 80, 81, 82, 83, 87, 88, 100, 101, 102, 103, 104, 105, 106, 107, 108], "inclusive": false }, "vertex": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "dir": { "rules": [15, 18, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_descr_multiline": { "rules": [5, 6, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_descr": { "rules": [3, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_title": { "rules": [1, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "md_string": { "rules": [13, 14, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "string": { "rules": [15, 16, 17, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "INITIAL": { "rules": [0, 2, 4, 7, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 67, 68, 70, 73, 75, 77, 78, 79, 81, 83, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 101, 103, 105, 107, 109, 110, 111, 112], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const MERMAID_DOM_ID_PREFIX = "flowchart-"; +let vertexCounter = 0; +let config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); +let vertices = {}; +let edges = []; +let classes = {}; +let subGraphs = []; +let subGraphLookup = {}; +let tooltips = {}; +let subCount = 0; +let firstGraphFlag = true; +let direction; +let version; +let funs = []; +const sanitizeText = (txt) => _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(txt, config); +const lookUpDomId = function(id) { + const vertexKeys = Object.keys(vertices); + for (const vertexKey of vertexKeys) { + if (vertices[vertexKey].id === id) { + return vertices[vertexKey].domId; + } + } + return id; +}; +const addVertex = function(_id, textObj, type, style, classes2, dir, props = {}) { + let txt; + let id = _id; + if (id === void 0) { + return; + } + if (id.trim().length === 0) { + return; + } + if (vertices[id] === void 0) { + vertices[id] = { + id, + labelType: "text", + domId: MERMAID_DOM_ID_PREFIX + id + "-" + vertexCounter, + styles: [], + classes: [] + }; + } + vertexCounter++; + if (textObj !== void 0) { + config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + txt = sanitizeText(textObj.text.trim()); + vertices[id].labelType = textObj.type; + if (txt[0] === '"' && txt[txt.length - 1] === '"') { + txt = txt.substring(1, txt.length - 1); + } + vertices[id].text = txt; + } else { + if (vertices[id].text === void 0) { + vertices[id].text = _id; + } + } + if (type !== void 0) { + vertices[id].type = type; + } + if (style !== void 0 && style !== null) { + style.forEach(function(s) { + vertices[id].styles.push(s); + }); + } + if (classes2 !== void 0 && classes2 !== null) { + classes2.forEach(function(s) { + vertices[id].classes.push(s); + }); + } + if (dir !== void 0) { + vertices[id].dir = dir; + } + if (vertices[id].props === void 0) { + vertices[id].props = props; + } else if (props !== void 0) { + Object.assign(vertices[id].props, props); + } +}; +const addSingleLink = function(_start, _end, type) { + let start = _start; + let end = _end; + const edge = { start, end, type: void 0, text: "", labelType: "text" }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc78 Got edge...", edge); + const linkTextObj = type.text; + if (linkTextObj !== void 0) { + edge.text = sanitizeText(linkTextObj.text.trim()); + if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') { + edge.text = edge.text.substring(1, edge.text.length - 1); + } + edge.labelType = linkTextObj.type; + } + if (type !== void 0) { + edge.type = type.type; + edge.stroke = type.stroke; + edge.length = type.length; + } + if ((edge == null ? void 0 : edge.length) > 10) { + edge.length = 10; + } + if (edges.length < (config.maxEdges ?? 500)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc78 pushing edge..."); + edges.push(edge); + } else { + throw new Error( + `Edge limit exceeded. ${edges.length} edges found, but the limit is ${config.maxEdges}. + +Initialize mermaid with maxEdges set to a higher number to allow more edges. +You cannot set this config via configuration inside the diagram as it is a secure config. +You have to call mermaid.initialize.` + ); + } +}; +const addLink = function(_start, _end, type) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("addLink (abc78)", _start, _end, type); + let i, j; + for (i = 0; i < _start.length; i++) { + for (j = 0; j < _end.length; j++) { + addSingleLink(_start[i], _end[j], type); + } + } +}; +const updateLinkInterpolate = function(positions, interp) { + positions.forEach(function(pos) { + if (pos === "default") { + edges.defaultInterpolate = interp; + } else { + edges[pos].interpolate = interp; + } + }); +}; +const updateLink = function(positions, style) { + positions.forEach(function(pos) { + if (pos >= edges.length) { + throw new Error( + `The index ${pos} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${edges.length - 1}. (Help: Ensure that the index is within the range of existing edges.)` + ); + } + if (pos === "default") { + edges.defaultStyle = style; + } else { + if (_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.isSubstringInArray("fill", style) === -1) { + style.push("fill:none"); + } + edges[pos].style = style; + } + }); +}; +const addClass = function(ids, style) { + ids.split(",").forEach(function(id) { + if (classes[id] === void 0) { + classes[id] = { id, styles: [], textStyles: [] }; + } + if (style !== void 0 && style !== null) { + style.forEach(function(s) { + if (s.match("color")) { + const newStyle = s.replace("fill", "bgFill").replace("color", "fill"); + classes[id].textStyles.push(newStyle); + } + classes[id].styles.push(s); + }); + } + }); +}; +const setDirection = function(dir) { + direction = dir; + if (direction.match(/.*/)) { + direction = "LR"; + } + if (direction.match(/.*v/)) { + direction = "TB"; + } + if (direction === "TD") { + direction = "TB"; + } +}; +const setClass = function(ids, className) { + ids.split(",").forEach(function(_id) { + let id = _id; + if (vertices[id] !== void 0) { + vertices[id].classes.push(className); + } + if (subGraphLookup[id] !== void 0) { + subGraphLookup[id].classes.push(className); + } + }); +}; +const setTooltip = function(ids, tooltip) { + ids.split(",").forEach(function(id) { + if (tooltip !== void 0) { + tooltips[version === "gen-1" ? lookUpDomId(id) : id] = sanitizeText(tooltip); + } + }); +}; +const setClickFun = function(id, functionName, functionArgs) { + let domId = lookUpDomId(id); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel !== "loose") { + return; + } + if (functionName === void 0) { + return; + } + let argList = []; + if (typeof functionArgs === "string") { + argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); + for (let i = 0; i < argList.length; i++) { + let item = argList[i].trim(); + if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') { + item = item.substr(1, item.length - 2); + } + argList[i] = item; + } + } + if (argList.length === 0) { + argList.push(id); + } + if (vertices[id] !== void 0) { + vertices[id].haveCallback = true; + funs.push(function() { + const elem = document.querySelector(`[id="${domId}"]`); + if (elem !== null) { + elem.addEventListener( + "click", + function() { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.runFunc(functionName, ...argList); + }, + false + ); + } + }); + } +}; +const setLink = function(ids, linkStr, target) { + ids.split(",").forEach(function(id) { + if (vertices[id] !== void 0) { + vertices[id].link = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.formatUrl(linkStr, config); + vertices[id].linkTarget = target; + } + }); + setClass(ids, "clickable"); +}; +const getTooltip = function(id) { + if (tooltips.hasOwnProperty(id)) { + return tooltips[id]; + } + return void 0; +}; +const setClickEvent = function(ids, functionName, functionArgs) { + ids.split(",").forEach(function(id) { + setClickFun(id, functionName, functionArgs); + }); + setClass(ids, "clickable"); +}; +const bindFunctions = function(element) { + funs.forEach(function(fun) { + fun(element); + }); +}; +const getDirection = function() { + return direction.trim(); +}; +const getVertices = function() { + return vertices; +}; +const getEdges = function() { + return edges; +}; +const getClasses = function() { + return classes; +}; +const setupToolTips = function(element) { + let tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(".mermaidTooltip"); + if ((tooltipElem._groups || tooltipElem)[0][0] === null) { + tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body").append("div").attr("class", "mermaidTooltip").style("opacity", 0); + } + const svg = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(element).select("svg"); + const nodes = svg.selectAll("g.node"); + nodes.on("mouseover", function() { + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(this); + const title = el.attr("title"); + if (title === null) { + return; + } + const rect = this.getBoundingClientRect(); + tooltipElem.transition().duration(200).style("opacity", ".9"); + tooltipElem.text(el.attr("title")).style("left", window.scrollX + rect.left + (rect.right - rect.left) / 2 + "px").style("top", window.scrollY + rect.bottom + "px"); + tooltipElem.html(tooltipElem.html().replace(/<br\/>/g, "
")); + el.classed("hover", true); + }).on("mouseout", function() { + tooltipElem.transition().duration(500).style("opacity", 0); + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(this); + el.classed("hover", false); + }); +}; +funs.push(setupToolTips); +const clear = function(ver = "gen-1") { + vertices = {}; + classes = {}; + edges = []; + funs = [setupToolTips]; + subGraphs = []; + subGraphLookup = {}; + subCount = 0; + tooltips = {}; + firstGraphFlag = true; + version = ver; + config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.v)(); +}; +const setGen = (ver) => { + version = ver || "gen-2"; +}; +const defaultStyle = function() { + return "fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"; +}; +const addSubGraph = function(_id, list, _title) { + let id = _id.text.trim(); + let title = _title.text; + if (_id === _title && _title.text.match(/\s/)) { + id = void 0; + } + function uniq(a) { + const prims = { boolean: {}, number: {}, string: {} }; + const objs = []; + let dir2; + const nodeList2 = a.filter(function(item) { + const type = typeof item; + if (item.stmt && item.stmt === "dir") { + dir2 = item.value; + return false; + } + if (item.trim() === "") { + return false; + } + if (type in prims) { + return prims[type].hasOwnProperty(item) ? false : prims[type][item] = true; + } else { + return objs.includes(item) ? false : objs.push(item); + } + }); + return { nodeList: nodeList2, dir: dir2 }; + } + let nodeList = []; + const { nodeList: nl, dir } = uniq(nodeList.concat.apply(nodeList, list)); + nodeList = nl; + if (version === "gen-1") { + for (let i = 0; i < nodeList.length; i++) { + nodeList[i] = lookUpDomId(nodeList[i]); + } + } + id = id || "subGraph" + subCount; + title = title || ""; + title = sanitizeText(title); + subCount = subCount + 1; + const subGraph = { + id, + nodes: nodeList, + title: title.trim(), + classes: [], + dir, + labelType: _title.type + }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Adding", subGraph.id, subGraph.nodes, subGraph.dir); + subGraph.nodes = makeUniq(subGraph, subGraphs).nodes; + subGraphs.push(subGraph); + subGraphLookup[id] = subGraph; + return id; +}; +const getPosForId = function(id) { + for (const [i, subGraph] of subGraphs.entries()) { + if (subGraph.id === id) { + return i; + } + } + return -1; +}; +let secCount = -1; +const posCrossRef = []; +const indexNodes2 = function(id, pos) { + const nodes = subGraphs[pos].nodes; + secCount = secCount + 1; + if (secCount > 2e3) { + return; + } + posCrossRef[secCount] = pos; + if (subGraphs[pos].id === id) { + return { + result: true, + count: 0 + }; + } + let count = 0; + let posCount = 1; + while (count < nodes.length) { + const childPos = getPosForId(nodes[count]); + if (childPos >= 0) { + const res = indexNodes2(id, childPos); + if (res.result) { + return { + result: true, + count: posCount + res.count + }; + } else { + posCount = posCount + res.count; + } + } + count = count + 1; + } + return { + result: false, + count: posCount + }; +}; +const getDepthFirstPos = function(pos) { + return posCrossRef[pos]; +}; +const indexNodes = function() { + secCount = -1; + if (subGraphs.length > 0) { + indexNodes2("none", subGraphs.length - 1); + } +}; +const getSubGraphs = function() { + return subGraphs; +}; +const firstGraph = () => { + if (firstGraphFlag) { + firstGraphFlag = false; + return true; + } + return false; +}; +const destructStartLink = (_str) => { + let str = _str.trim(); + let type = "arrow_open"; + switch (str[0]) { + case "<": + type = "arrow_point"; + str = str.slice(1); + break; + case "x": + type = "arrow_cross"; + str = str.slice(1); + break; + case "o": + type = "arrow_circle"; + str = str.slice(1); + break; + } + let stroke = "normal"; + if (str.includes("=")) { + stroke = "thick"; + } + if (str.includes(".")) { + stroke = "dotted"; + } + return { type, stroke }; +}; +const countChar = (char, str) => { + const length = str.length; + let count = 0; + for (let i = 0; i < length; ++i) { + if (str[i] === char) { + ++count; + } + } + return count; +}; +const destructEndLink = (_str) => { + const str = _str.trim(); + let line = str.slice(0, -1); + let type = "arrow_open"; + switch (str.slice(-1)) { + case "x": + type = "arrow_cross"; + if (str[0] === "x") { + type = "double_" + type; + line = line.slice(1); + } + break; + case ">": + type = "arrow_point"; + if (str[0] === "<") { + type = "double_" + type; + line = line.slice(1); + } + break; + case "o": + type = "arrow_circle"; + if (str[0] === "o") { + type = "double_" + type; + line = line.slice(1); + } + break; + } + let stroke = "normal"; + let length = line.length - 1; + if (line[0] === "=") { + stroke = "thick"; + } + if (line[0] === "~") { + stroke = "invisible"; + } + let dots = countChar(".", line); + if (dots) { + stroke = "dotted"; + length = dots; + } + return { type, stroke, length }; +}; +const destructLink = (_str, _startStr) => { + const info = destructEndLink(_str); + let startInfo; + if (_startStr) { + startInfo = destructStartLink(_startStr); + if (startInfo.stroke !== info.stroke) { + return { type: "INVALID", stroke: "INVALID" }; + } + if (startInfo.type === "arrow_open") { + startInfo.type = info.type; + } else { + if (startInfo.type !== info.type) { + return { type: "INVALID", stroke: "INVALID" }; + } + startInfo.type = "double_" + startInfo.type; + } + if (startInfo.type === "double_arrow") { + startInfo.type = "double_arrow_point"; + } + startInfo.length = info.length; + return startInfo; + } + return info; +}; +const exists = (allSgs, _id) => { + let res = false; + allSgs.forEach((sg) => { + const pos = sg.nodes.indexOf(_id); + if (pos >= 0) { + res = true; + } + }); + return res; +}; +const makeUniq = (sg, allSubgraphs) => { + const res = []; + sg.nodes.forEach((_id, pos) => { + if (!exists(allSubgraphs, _id)) { + res.push(sg.nodes[pos]); + } + }); + return { nodes: res }; +}; +const lex = { + firstGraph +}; +const flowDb = { + defaultConfig: () => _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.K.flowchart, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.g, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.a, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.b, + addVertex, + lookUpDomId, + addLink, + updateLinkInterpolate, + updateLink, + addClass, + setDirection, + setClass, + setTooltip, + getTooltip, + setClickEvent, + setLink, + bindFunctions, + getDirection, + getVertices, + getEdges, + getClasses, + clear, + setGen, + defaultStyle, + addSubGraph, + getDepthFirstPos, + indexNodes, + getSubGraphs, + destructLink, + lex, + exists, + makeUniq, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.t +}; +const db = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + addClass, + addLink, + addSingleLink, + addSubGraph, + addVertex, + bindFunctions, + clear, + default: flowDb, + defaultStyle, + destructLink, + firstGraph, + getClasses, + getDepthFirstPos, + getDirection, + getEdges, + getSubGraphs, + getTooltip, + getVertices, + indexNodes, + lex, + lookUpDomId, + setClass, + setClickEvent, + setDirection, + setGen, + setLink, + updateLink, + updateLinkInterpolate +}, Symbol.toStringTag, { value: "Module" })); + + + +/***/ }), + +/***/ 29502: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + diagram: () => (/* binding */ diagram) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/flowDb-4b19a42f.js +var flowDb_4b19a42f = __webpack_require__(66216); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(697); +// EXTERNAL MODULE: ./node_modules/d3/src/index.js + 197 modules +var src = __webpack_require__(26312); +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-f47111a7.js + 8 modules +var mermaid_f47111a7 = __webpack_require__(76257); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(23068); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + 64 modules +var dagre = __webpack_require__(21176); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/dagre-js/util.js +var util = __webpack_require__(82933); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/arrows.js + + + + +var arrows = { + normal, + vee, + undirected, +}; + +function setArrows(value) { + arrows = value; +} + +function normal(parent, id, edge, type) { + var marker = parent + .append('marker') + .attr('id', id) + .attr('viewBox', '0 0 10 10') + .attr('refX', 9) + .attr('refY', 5) + .attr('markerUnits', 'strokeWidth') + .attr('markerWidth', 8) + .attr('markerHeight', 6) + .attr('orient', 'auto'); + + var path = marker + .append('path') + .attr('d', 'M 0 0 L 10 5 L 0 10 z') + .style('stroke-width', 1) + .style('stroke-dasharray', '1,0'); + util/* applyStyle */.AV(path, edge[type + 'Style']); + if (edge[type + 'Class']) { + path.attr('class', edge[type + 'Class']); + } +} + +function vee(parent, id, edge, type) { + var marker = parent + .append('marker') + .attr('id', id) + .attr('viewBox', '0 0 10 10') + .attr('refX', 9) + .attr('refY', 5) + .attr('markerUnits', 'strokeWidth') + .attr('markerWidth', 8) + .attr('markerHeight', 6) + .attr('orient', 'auto'); + + var path = marker + .append('path') + .attr('d', 'M 0 0 L 10 5 L 0 10 L 4 5 z') + .style('stroke-width', 1) + .style('stroke-dasharray', '1,0'); + util/* applyStyle */.AV(path, edge[type + 'Style']); + if (edge[type + 'Class']) { + path.attr('class', edge[type + 'Class']); + } +} + +function undirected(parent, id, edge, type) { + var marker = parent + .append('marker') + .attr('id', id) + .attr('viewBox', '0 0 10 10') + .attr('refX', 9) + .attr('refY', 5) + .attr('markerUnits', 'strokeWidth') + .attr('markerWidth', 8) + .attr('markerHeight', 6) + .attr('orient', 'auto'); + + var path = marker + .append('path') + .attr('d', 'M 0 5 L 10 5') + .style('stroke-width', 1) + .style('stroke-dasharray', '1,0'); + util/* applyStyle */.AV(path, edge[type + 'Style']); + if (edge[type + 'Class']) { + path.attr('class', edge[type + 'Class']); + } +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/dagre-js/label/add-html-label.js +var add_html_label = __webpack_require__(10646); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/label/add-svg-label.js + + + + +function addSVGLabel(root, node) { + var domNode = root; + + domNode.node().appendChild(node.label); + + util/* applyStyle */.AV(domNode, node.labelStyle); + + return domNode; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/label/add-text-label.js + + + + +/* + * Attaches a text label to the specified root. Handles escape sequences. + */ +function addTextLabel(root, node) { + var domNode = root.append('text'); + + var lines = processEscapeSequences(node.label).split('\n'); + for (var i = 0; i < lines.length; i++) { + domNode + .append('tspan') + .attr('xml:space', 'preserve') + .attr('dy', '1em') + .attr('x', '1') + .text(lines[i]); + } + + util/* applyStyle */.AV(domNode, node.labelStyle); + + return domNode; +} + +function processEscapeSequences(text) { + var newText = ''; + var escaped = false; + var ch; + for (var i = 0; i < text.length; ++i) { + ch = text[i]; + if (escaped) { + switch (ch) { + case 'n': + newText += '\n'; + break; + default: + newText += ch; + } + escaped = false; + } else if (ch === '\\') { + escaped = true; + } else { + newText += ch; + } + } + return newText; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/label/add-label.js + + + + + + +function addLabel(root, node, location) { + var label = node.label; + var labelSvg = root.append('g'); + + // Allow the label to be a string, a function that returns a DOM element, or + // a DOM element itself. + if (node.labelType === 'svg') { + addSVGLabel(labelSvg, node); + } else if (typeof label !== 'string' || node.labelType === 'html') { + (0,add_html_label/* addHtmlLabel */.H)(labelSvg, node); + } else { + addTextLabel(labelSvg, node); + } + + var labelBBox = labelSvg.node().getBBox(); + var y; + switch (location) { + case 'top': + y = -node.height / 2; + break; + case 'bottom': + y = node.height / 2 - labelBBox.height; + break; + default: + y = -labelBBox.height / 2; + } + labelSvg.attr('transform', 'translate(' + -labelBBox.width / 2 + ',' + y + ')'); + + return labelSvg; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/create-clusters.js + + + + + + +var createClusters = function (selection, g) { + var clusters = g.nodes().filter(function (v) { + return util/* isSubgraph */.De(g, v); + }); + var svgClusters = selection.selectAll('g.cluster').data(clusters, function (v) { + return v; + }); + + util/* applyTransition */.c$(svgClusters.exit(), g).style('opacity', 0).remove(); + + var enterSelection = svgClusters + .enter() + .append('g') + .attr('class', 'cluster') + .attr('id', function (v) { + var node = g.node(v); + return node.id; + }) + .style('opacity', 0) + .each(function (v) { + var node = g.node(v); + var thisGroup = src/* select */.Ltv(this); + src/* select */.Ltv(this).append('rect'); + var labelGroup = thisGroup.append('g').attr('class', 'label'); + addLabel(labelGroup, node, node.clusterLabelPos); + }); + + svgClusters = svgClusters.merge(enterSelection); + + svgClusters = util/* applyTransition */.c$(svgClusters, g).style('opacity', 1); + + svgClusters.selectAll('rect').each(function (c) { + var node = g.node(c); + var domCluster = src/* select */.Ltv(this); + util/* applyStyle */.AV(domCluster, node.style); + }); + + return svgClusters; +}; + +function setCreateClusters(value) { + createClusters = value; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/create-edge-labels.js + + + + + + + +let createEdgeLabels = function (selection, g) { + var svgEdgeLabels = selection + .selectAll('g.edgeLabel') + .data(g.edges(), function (e) { + return util/* edgeToId */.gh(e); + }) + .classed('update', true); + + svgEdgeLabels.exit().remove(); + svgEdgeLabels.enter().append('g').classed('edgeLabel', true).style('opacity', 0); + + svgEdgeLabels = selection.selectAll('g.edgeLabel'); + + svgEdgeLabels.each(function (e) { + var root = src/* select */.Ltv(this); + root.select('.label').remove(); + var edge = g.edge(e); + var label = addLabel(root, g.edge(e), 0).classed('label', true); + var bbox = label.node().getBBox(); + + if (edge.labelId) { + label.attr('id', edge.labelId); + } + if (!has/* default */.A(edge, 'width')) { + edge.width = bbox.width; + } + if (!has/* default */.A(edge, 'height')) { + edge.height = bbox.height; + } + }); + + var exitSelection; + + if (svgEdgeLabels.exit) { + exitSelection = svgEdgeLabels.exit(); + } else { + exitSelection = svgEdgeLabels.selectAll(null); // empty selection + } + + util/* applyTransition */.c$(exitSelection, g).style('opacity', 0).remove(); + + return svgEdgeLabels; +}; + +function setCreateEdgeLabels(value) { + createEdgeLabels = value; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(5664); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(91395); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-node.js + + +function intersectNode(node, point) { + return node.intersect(point); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/create-edge-paths.js + + + + + + + +var createEdgePaths = function (selection, g, arrows) { + var previousPaths = selection + .selectAll('g.edgePath') + .data(g.edges(), function (e) { + return util/* edgeToId */.gh(e); + }) + .classed('update', true); + + var newPaths = enter(previousPaths, g); + exit(previousPaths, g); + + var svgPaths = previousPaths.merge !== undefined ? previousPaths.merge(newPaths) : previousPaths; + util/* applyTransition */.c$(svgPaths, g).style('opacity', 1); + + // Save DOM element in the path group, and set ID and class + svgPaths.each(function (e) { + var domEdge = src/* select */.Ltv(this); + var edge = g.edge(e); + edge.elem = this; + + if (edge.id) { + domEdge.attr('id', edge.id); + } + + util/* applyClass */.nh( + domEdge, + edge['class'], + (domEdge.classed('update') ? 'update ' : '') + 'edgePath' + ); + }); + + svgPaths.selectAll('path.path').each(function (e) { + var edge = g.edge(e); + edge.arrowheadId = uniqueId/* default */.A('arrowhead'); + + var domEdge = src/* select */.Ltv(this) + .attr('marker-end', function () { + return 'url(' + makeFragmentRef(location.href, edge.arrowheadId) + ')'; + }) + .style('fill', 'none'); + + util/* applyTransition */.c$(domEdge, g).attr('d', function (e) { + return calcPoints(g, e); + }); + + util/* applyStyle */.AV(domEdge, edge.style); + }); + + svgPaths.selectAll('defs *').remove(); + svgPaths.selectAll('defs').each(function (e) { + var edge = g.edge(e); + var arrowhead = arrows[edge.arrowhead]; + arrowhead(src/* select */.Ltv(this), edge.arrowheadId, edge, 'arrowhead'); + }); + + return svgPaths; +}; + +function setCreateEdgePaths(value) { + createEdgePaths = value; +} + +function makeFragmentRef(url, fragmentId) { + var baseUrl = url.split('#')[0]; + return baseUrl + '#' + fragmentId; +} + +function calcPoints(g, e) { + var edge = g.edge(e); + var tail = g.node(e.v); + var head = g.node(e.w); + var points = edge.points.slice(1, edge.points.length - 1); + points.unshift(intersectNode(tail, points[0])); + points.push(intersectNode(head, points[points.length - 1])); + + return createLine(edge, points); +} + +function createLine(edge, points) { + // @ts-expect-error + var line = (src/* line */.n8j || src/* svg */.JWy.line)() + .x(function (d) { + return d.x; + }) + .y(function (d) { + return d.y; + }); + + (line.curve || line.interpolate)(edge.curve); + + return line(points); +} + +function getCoords(elem) { + var bbox = elem.getBBox(); + var matrix = elem.ownerSVGElement + .getScreenCTM() + .inverse() + .multiply(elem.getScreenCTM()) + .translate(bbox.width / 2, bbox.height / 2); + return { x: matrix.e, y: matrix.f }; +} + +function enter(svgPaths, g) { + var svgPathsEnter = svgPaths.enter().append('g').attr('class', 'edgePath').style('opacity', 0); + svgPathsEnter + .append('path') + .attr('class', 'path') + .attr('d', function (e) { + var edge = g.edge(e); + var sourceElem = g.node(e.v).elem; + var points = range/* default */.A(edge.points.length).map(function () { + return getCoords(sourceElem); + }); + return createLine(edge, points); + }); + svgPathsEnter.append('defs'); + return svgPathsEnter; +} + +function exit(svgPaths, g) { + var svgPathExit = svgPaths.exit(); + util/* applyTransition */.c$(svgPathExit, g).style('opacity', 0).remove(); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(81942); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/create-nodes.js + + + + + + + +var createNodes = function (selection, g, shapes) { + var simpleNodes = g.nodes().filter(function (v) { + return !util/* isSubgraph */.De(g, v); + }); + var svgNodes = selection + .selectAll('g.node') + .data(simpleNodes, function (v) { + return v; + }) + .classed('update', true); + + svgNodes.exit().remove(); + + svgNodes.enter().append('g').attr('class', 'node').style('opacity', 0); + + svgNodes = selection.selectAll('g.node'); + + svgNodes.each(function (v) { + var node = g.node(v); + var thisGroup = src/* select */.Ltv(this); + util/* applyClass */.nh( + thisGroup, + node['class'], + (thisGroup.classed('update') ? 'update ' : '') + 'node' + ); + + thisGroup.select('g.label').remove(); + var labelGroup = thisGroup.append('g').attr('class', 'label'); + var labelDom = addLabel(labelGroup, node); + var shape = shapes[node.shape]; + var bbox = pick/* default */.A(labelDom.node().getBBox(), 'width', 'height'); + + node.elem = this; + + if (node.id) { + thisGroup.attr('id', node.id); + } + if (node.labelId) { + labelGroup.attr('id', node.labelId); + } + + if (has/* default */.A(node, 'width')) { + bbox.width = node.width; + } + if (has/* default */.A(node, 'height')) { + bbox.height = node.height; + } + + bbox.width += node.paddingLeft + node.paddingRight; + bbox.height += node.paddingTop + node.paddingBottom; + labelGroup.attr( + 'transform', + 'translate(' + + (node.paddingLeft - node.paddingRight) / 2 + + ',' + + (node.paddingTop - node.paddingBottom) / 2 + + ')' + ); + + var root = src/* select */.Ltv(this); + root.select('.label-container').remove(); + var shapeSvg = shape(root, bbox, node).classed('label-container', true); + util/* applyStyle */.AV(shapeSvg, node.style); + + var shapeBBox = shapeSvg.node().getBBox(); + node.width = shapeBBox.width; + node.height = shapeBBox.height; + }); + + var exitSelection; + + if (svgNodes.exit) { + exitSelection = svgNodes.exit(); + } else { + exitSelection = svgNodes.selectAll(null); // empty selection + } + + util/* applyTransition */.c$(exitSelection, g).style('opacity', 0).remove(); + + return svgNodes; +}; + +function setCreateNodes(value) { + createNodes = value; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/position-clusters.js + + + + + +function positionClusters(selection, g) { + var created = selection.filter(function () { + return !src/* select */.Ltv(this).classed('update'); + }); + + function translate(v) { + var node = g.node(v); + return 'translate(' + node.x + ',' + node.y + ')'; + } + + created.attr('transform', translate); + + util/* applyTransition */.c$(selection, g).style('opacity', 1).attr('transform', translate); + + util/* applyTransition */.c$(created.selectAll('rect'), g) + .attr('width', function (v) { + return g.node(v).width; + }) + .attr('height', function (v) { + return g.node(v).height; + }) + .attr('x', function (v) { + var node = g.node(v); + return -node.width / 2; + }) + .attr('y', function (v) { + var node = g.node(v); + return -node.height / 2; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/position-edge-labels.js + + + + + + +function positionEdgeLabels(selection, g) { + var created = selection.filter(function () { + return !src/* select */.Ltv(this).classed('update'); + }); + + function translate(e) { + var edge = g.edge(e); + return has/* default */.A(edge, 'x') ? 'translate(' + edge.x + ',' + edge.y + ')' : ''; + } + + created.attr('transform', translate); + + util/* applyTransition */.c$(selection, g).style('opacity', 1).attr('transform', translate); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/position-nodes.js + + + + + +function positionNodes(selection, g) { + var created = selection.filter(function () { + return !src/* select */.Ltv(this).classed('update'); + }); + + function translate(v) { + var node = g.node(v); + return 'translate(' + node.x + ',' + node.y + ')'; + } + + created.attr('transform', translate); + + util/* applyTransition */.c$(selection, g).style('opacity', 1).attr('transform', translate); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-ellipse.js + + +function intersectEllipse(node, rx, ry, point) { + // Formulae from: http://mathworld.wolfram.com/Ellipse-LineIntersection.html + + var cx = node.x; + var cy = node.y; + + var px = cx - point.x; + var py = cy - point.y; + + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + + var dx = Math.abs((rx * ry * px) / det); + if (point.x < cx) { + dx = -dx; + } + var dy = Math.abs((rx * ry * py) / det); + if (point.y < cy) { + dy = -dy; + } + + return { x: cx + dx, y: cy + dy }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-circle.js + + + + +function intersectCircle(node, rx, point) { + return intersectEllipse(node, rx, rx, point); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-line.js + + +/* + * Returns the point at which two lines, p and q, intersect or returns + * undefined if they do not intersect. + */ +function intersectLine(p1, p2, q1, q2) { + // Algorithm from J. Avro, (ed.) Graphics Gems, No 2, Morgan Kaufmann, 1994, + // p7 and p473. + + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + + // Compute a1, b1, c1, where line joining points 1 and 2 is F(x,y) = a1 x + + // b1 y + c1 = 0. + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + + // Compute r3 and r4. + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + + // Check signs of r3 and r4. If both point 3 and point 4 lie on + // same side of line 1, the line segments do not intersect. + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return /*DONT_INTERSECT*/; + } + + // Compute a2, b2, c2 where line joining points 3 and 4 is G(x,y) = a2 x + b2 y + c2 = 0 + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + + // Compute r1 and r2 + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + + // Check signs of r1 and r2. If both point 1 and point 2 lie + // on same side of second line segment, the line segments do + // not intersect. + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return /*DONT_INTERSECT*/; + } + + // Line segments intersect: compute intersection point. + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return /*COLLINEAR*/; + } + + offset = Math.abs(denom / 2); + + // The denom/2 is to get rounding instead of truncating. It + // is added or subtracted to the numerator, depending upon the + // sign of the numerator. + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + + return { x: x, y: y }; +} + +function sameSign(r1, r2) { + return r1 * r2 > 0; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-polygon.js + + + + +/* + * Returns the point ({x, y}) at which the point argument intersects with the + * node argument assuming that it has the shape specified by polygon. + */ +function intersectPolygon(node, polyPoints, point) { + var x1 = node.x; + var y1 = node.y; + + var intersections = []; + + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + polyPoints.forEach(function (entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect = intersectLine( + node, + point, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect) { + intersections.push(intersect); + } + } + + if (!intersections.length) { + console.log('NO INTERSECTION FOUND, RETURN NODE CENTER', node); + return node; + } + + if (intersections.length > 1) { + // More intersections, find the one nearest to edge end point + intersections.sort(function (p, q) { + var pdx = p.x - point.x; + var pdy = p.y - point.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + + var qdx = q.x - point.x; + var qdy = q.y - point.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-rect.js + + +function intersectRect(node, point) { + var x = node.x; + var y = node.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = node.width / 2; + var h = node.height / 2; + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/shapes.js + + + + + + + +var shapes = { + rect, + ellipse, + circle, + diamond, +}; + +function setShapes(value) { + shapes = value; +} + +function rect(parent, bbox, node) { + var shapeSvg = parent + .insert('rect', ':first-child') + .attr('rx', node.rx) + .attr('ry', node.ry) + .attr('x', -bbox.width / 2) + .attr('y', -bbox.height / 2) + .attr('width', bbox.width) + .attr('height', bbox.height); + + node.intersect = function (point) { + return intersectRect(node, point); + }; + + return shapeSvg; +} + +function ellipse(parent, bbox, node) { + var rx = bbox.width / 2; + var ry = bbox.height / 2; + var shapeSvg = parent + .insert('ellipse', ':first-child') + .attr('x', -bbox.width / 2) + .attr('y', -bbox.height / 2) + .attr('rx', rx) + .attr('ry', ry); + + node.intersect = function (point) { + return intersectEllipse(node, rx, ry, point); + }; + + return shapeSvg; +} + +function circle(parent, bbox, node) { + var r = Math.max(bbox.width, bbox.height) / 2; + var shapeSvg = parent + .insert('circle', ':first-child') + .attr('x', -bbox.width / 2) + .attr('y', -bbox.height / 2) + .attr('r', r); + + node.intersect = function (point) { + return intersectCircle(node, r, point); + }; + + return shapeSvg; +} + +// Circumscribe an ellipse for the bounding box with a diamond shape. I derived +// the function to calculate the diamond shape from: +// http://mathforum.org/kb/message.jspa?messageID=3750236 +function diamond(parent, bbox, node) { + var w = (bbox.width * Math.SQRT2) / 2; + var h = (bbox.height * Math.SQRT2) / 2; + var points = [ + { x: 0, y: -h }, + { x: -w, y: 0 }, + { x: 0, y: h }, + { x: w, y: 0 }, + ]; + var shapeSvg = parent.insert('polygon', ':first-child').attr( + 'points', + points + .map(function (p) { + return p.x + ',' + p.y; + }) + .join(' ') + ); + + node.intersect = function (p) { + return intersectPolygon(node, points, p); + }; + + return shapeSvg; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/render.js + + + + + + + + + + + + + + + +// This design is based on http://bost.ocks.org/mike/chart/. +function render() { + var fn = function (svg, g) { + preProcessGraph(g); + + var outputGroup = createOrSelectGroup(svg, 'output'); + var clustersGroup = createOrSelectGroup(outputGroup, 'clusters'); + var edgePathsGroup = createOrSelectGroup(outputGroup, 'edgePaths'); + var edgeLabels = createEdgeLabels(createOrSelectGroup(outputGroup, 'edgeLabels'), g); + var nodes = createNodes(createOrSelectGroup(outputGroup, 'nodes'), g, shapes); + + (0,dagre/* layout */.Zp)(g); + + positionNodes(nodes, g); + positionEdgeLabels(edgeLabels, g); + createEdgePaths(edgePathsGroup, g, arrows); + + var clusters = createClusters(clustersGroup, g); + positionClusters(clusters, g); + + postProcessGraph(g); + }; + + fn.createNodes = function (value) { + if (!arguments.length) return createNodes; + setCreateNodes(value); + return fn; + }; + + fn.createClusters = function (value) { + if (!arguments.length) return createClusters; + setCreateClusters(value); + return fn; + }; + + fn.createEdgeLabels = function (value) { + if (!arguments.length) return createEdgeLabels; + setCreateEdgeLabels(value); + return fn; + }; + + fn.createEdgePaths = function (value) { + if (!arguments.length) return createEdgePaths; + setCreateEdgePaths(value); + return fn; + }; + + fn.shapes = function (value) { + if (!arguments.length) return shapes; + setShapes(value); + return fn; + }; + + fn.arrows = function (value) { + if (!arguments.length) return arrows; + setArrows(value); + return fn; + }; + + return fn; +} + +var NODE_DEFAULT_ATTRS = { + paddingLeft: 10, + paddingRight: 10, + paddingTop: 10, + paddingBottom: 10, + rx: 0, + ry: 0, + shape: 'rect', +}; + +var EDGE_DEFAULT_ATTRS = { + arrowhead: 'normal', + curve: src/* curveLinear */.lUB, +}; + +function preProcessGraph(g) { + g.nodes().forEach(function (v) { + var node = g.node(v); + if (!has/* default */.A(node, 'label') && !g.children(v).length) { + node.label = v; + } + + if (has/* default */.A(node, 'paddingX')) { + defaults/* default */.A(node, { + paddingLeft: node.paddingX, + paddingRight: node.paddingX, + }); + } + + if (has/* default */.A(node, 'paddingY')) { + defaults/* default */.A(node, { + paddingTop: node.paddingY, + paddingBottom: node.paddingY, + }); + } + + if (has/* default */.A(node, 'padding')) { + defaults/* default */.A(node, { + paddingLeft: node.padding, + paddingRight: node.padding, + paddingTop: node.padding, + paddingBottom: node.padding, + }); + } + + defaults/* default */.A(node, NODE_DEFAULT_ATTRS); + + forEach/* default */.A(['paddingLeft', 'paddingRight', 'paddingTop', 'paddingBottom'], function (k) { + node[k] = Number(node[k]); + }); + + // Save dimensions for restore during post-processing + if (has/* default */.A(node, 'width')) { + node._prevWidth = node.width; + } + if (has/* default */.A(node, 'height')) { + node._prevHeight = node.height; + } + }); + + g.edges().forEach(function (e) { + var edge = g.edge(e); + if (!has/* default */.A(edge, 'label')) { + edge.label = ''; + } + defaults/* default */.A(edge, EDGE_DEFAULT_ATTRS); + }); +} + +function postProcessGraph(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + + // Restore original dimensions + if (has/* default */.A(node, '_prevWidth')) { + node.width = node._prevWidth; + } else { + delete node.width; + } + + if (has/* default */.A(node, '_prevHeight')) { + node.height = node._prevHeight; + } else { + delete node.height; + } + + delete node._prevWidth; + delete node._prevHeight; + }); +} + +function createOrSelectGroup(root, name) { + var selection = root.select('g.' + name); + if (selection.empty()) { + selection = root.append('g').attr('class', name); + } + return selection; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/index.js + + + + + + + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/styles-3ed67cfa.js +var styles_3ed67cfa = __webpack_require__(98696); +// EXTERNAL MODULE: ./node_modules/dayjs/dayjs.min.js +var dayjs_min = __webpack_require__(74353); +// EXTERNAL MODULE: ./node_modules/@braintree/sanitize-url/dist/index.js +var dist = __webpack_require__(16750); +// EXTERNAL MODULE: ./node_modules/dompurify/dist/purify.es.mjs +var purify_es = __webpack_require__(99418); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/json.js +var json = __webpack_require__(14075); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/flowDiagram-5540d9b9.js + + + + + + + + + + + + + + + + + + + + + + + + + +function question(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const s = (w + h) * 0.9; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + const shapeSvg = insertPolygonShape(parent, s, s, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function hexagon(parent, bbox, node) { + const f = 4; + const h = bbox.height; + const m = h / f; + const w = bbox.width + 2 * m; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function rect_left_inv_arrow(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function lean_right(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function lean_left(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function trapezoid(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function inv_trapezoid(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function rect_right_inv_arrow(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function stadium(parent, bbox, node) { + const h = bbox.height; + const w = bbox.width + h / 4; + const shapeSvg = parent.insert("rect", ":first-child").attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + node.intersect = function(point) { + return intersectRect(node, point); + }; + return shapeSvg; +} +function subroutine(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function cylinder(parent, bbox, node) { + const w = bbox.width; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const shapeSvg = parent.attr("label-offset-y", ry).insert("path", ":first-child").attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + node.intersect = function(point) { + const pos = intersectRect(node, point); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +} +function addToRender(render2) { + render2.shapes().question = question; + render2.shapes().hexagon = hexagon; + render2.shapes().stadium = stadium; + render2.shapes().subroutine = subroutine; + render2.shapes().cylinder = cylinder; + render2.shapes().rect_left_inv_arrow = rect_left_inv_arrow; + render2.shapes().lean_right = lean_right; + render2.shapes().lean_left = lean_left; + render2.shapes().trapezoid = trapezoid; + render2.shapes().inv_trapezoid = inv_trapezoid; + render2.shapes().rect_right_inv_arrow = rect_right_inv_arrow; +} +function addToRenderV2(addShape) { + addShape({ question }); + addShape({ hexagon }); + addShape({ stadium }); + addShape({ subroutine }); + addShape({ cylinder }); + addShape({ rect_left_inv_arrow }); + addShape({ lean_right }); + addShape({ lean_left }); + addShape({ trapezoid }); + addShape({ inv_trapezoid }); + addShape({ rect_right_inv_arrow }); +} +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +const flowChartShapes = { + addToRender, + addToRenderV2 +}; +const conf = {}; +const setConf = function(cnf) { + const keys = Object.keys(cnf); + for (const key of keys) { + conf[key] = cnf[key]; + } +}; +const addVertices = async function(vert, g, svgId, root, _doc, diagObj) { + const svg = !root ? (0,src/* select */.Ltv)(`[id="${svgId}"]`) : root.select(`[id="${svgId}"]`); + const doc = !_doc ? document : _doc; + const keys = Object.keys(vert); + for (const id of keys) { + const vertex = vert[id]; + let classStr = "default"; + if (vertex.classes.length > 0) { + classStr = vertex.classes.join(" "); + } + const styles = (0,mermaid_f47111a7.k)(vertex.styles); + let vertexText = vertex.text !== void 0 ? vertex.text : vertex.id; + let vertexNode; + if ((0,mermaid_f47111a7.m)((0,mermaid_f47111a7.c)().flowchart.htmlLabels)) { + const node = { + label: await (0,mermaid_f47111a7.r)( + vertexText.replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell:disable-line + (s) => `` + ), + (0,mermaid_f47111a7.c)() + ) + }; + vertexNode = (0,add_html_label/* addHtmlLabel */.H)(svg, node).node(); + vertexNode.parentNode.removeChild(vertexNode); + } else { + const svgLabel = doc.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", styles.labelStyle.replace("color:", "fill:")); + const rows = vertexText.split(mermaid_f47111a7.e.lineBreakRegex); + for (const row of rows) { + const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "1"); + tspan.textContent = row; + svgLabel.appendChild(tspan); + } + vertexNode = svgLabel; + } + let radius = 0; + let _shape = ""; + switch (vertex.type) { + case "round": + radius = 5; + _shape = "rect"; + break; + case "square": + _shape = "rect"; + break; + case "diamond": + _shape = "question"; + break; + case "hexagon": + _shape = "hexagon"; + break; + case "odd": + _shape = "rect_left_inv_arrow"; + break; + case "lean_right": + _shape = "lean_right"; + break; + case "lean_left": + _shape = "lean_left"; + break; + case "trapezoid": + _shape = "trapezoid"; + break; + case "inv_trapezoid": + _shape = "inv_trapezoid"; + break; + case "odd_right": + _shape = "rect_left_inv_arrow"; + break; + case "circle": + _shape = "circle"; + break; + case "ellipse": + _shape = "ellipse"; + break; + case "stadium": + _shape = "stadium"; + break; + case "subroutine": + _shape = "subroutine"; + break; + case "cylinder": + _shape = "cylinder"; + break; + case "group": + _shape = "rect"; + break; + default: + _shape = "rect"; + } + mermaid_f47111a7.l.warn("Adding node", vertex.id, vertex.domId); + g.setNode(diagObj.db.lookUpDomId(vertex.id), { + labelType: "svg", + labelStyle: styles.labelStyle, + shape: _shape, + label: vertexNode, + rx: radius, + ry: radius, + class: classStr, + style: styles.style, + id: diagObj.db.lookUpDomId(vertex.id) + }); + } +}; +const addEdges = async function(edges, g, diagObj) { + let cnt = 0; + let defaultStyle; + let defaultLabelStyle; + if (edges.defaultStyle !== void 0) { + const defaultStyles = (0,mermaid_f47111a7.k)(edges.defaultStyle); + defaultStyle = defaultStyles.style; + defaultLabelStyle = defaultStyles.labelStyle; + } + for (const edge of edges) { + cnt++; + const linkId = "L-" + edge.start + "-" + edge.end; + const linkNameStart = "LS-" + edge.start; + const linkNameEnd = "LE-" + edge.end; + const edgeData = {}; + if (edge.type === "arrow_open") { + edgeData.arrowhead = "none"; + } else { + edgeData.arrowhead = "normal"; + } + let style = ""; + let labelStyle = ""; + if (edge.style !== void 0) { + const styles = (0,mermaid_f47111a7.k)(edge.style); + style = styles.style; + labelStyle = styles.labelStyle; + } else { + switch (edge.stroke) { + case "normal": + style = "fill:none"; + if (defaultStyle !== void 0) { + style = defaultStyle; + } + if (defaultLabelStyle !== void 0) { + labelStyle = defaultLabelStyle; + } + break; + case "dotted": + style = "fill:none;stroke-width:2px;stroke-dasharray:3;"; + break; + case "thick": + style = " stroke-width: 3.5px;fill:none"; + break; + } + } + edgeData.style = style; + edgeData.labelStyle = labelStyle; + if (edge.interpolate !== void 0) { + edgeData.curve = (0,mermaid_f47111a7.n)(edge.interpolate, src/* curveLinear */.lUB); + } else if (edges.defaultInterpolate !== void 0) { + edgeData.curve = (0,mermaid_f47111a7.n)(edges.defaultInterpolate, src/* curveLinear */.lUB); + } else { + edgeData.curve = (0,mermaid_f47111a7.n)(conf.curve, src/* curveLinear */.lUB); + } + if (edge.text === void 0) { + if (edge.style !== void 0) { + edgeData.arrowheadStyle = "fill: #333"; + } + } else { + edgeData.arrowheadStyle = "fill: #333"; + edgeData.labelpos = "c"; + if ((0,mermaid_f47111a7.m)((0,mermaid_f47111a7.c)().flowchart.htmlLabels)) { + edgeData.labelType = "html"; + edgeData.label = `${await (0,mermaid_f47111a7.r)( + edge.text.replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell:disable-line + (s) => `` + ), + (0,mermaid_f47111a7.c)() + )}`; + } else { + edgeData.labelType = "text"; + edgeData.label = edge.text.replace(mermaid_f47111a7.e.lineBreakRegex, "\n"); + if (edge.style === void 0) { + edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none"; + } + edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:"); + } + } + edgeData.id = linkId; + edgeData.class = linkNameStart + " " + linkNameEnd; + edgeData.minlen = edge.length || 1; + g.setEdge(diagObj.db.lookUpDomId(edge.start), diagObj.db.lookUpDomId(edge.end), edgeData, cnt); + } +}; +const getClasses = function(text, diagObj) { + mermaid_f47111a7.l.info("Extracting classes"); + return diagObj.db.getClasses(); +}; +const draw = async function(text, id, _version, diagObj) { + mermaid_f47111a7.l.info("Drawing flowchart"); + const { securityLevel, flowchart: conf2 } = (0,mermaid_f47111a7.c)(); + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,src/* select */.Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,src/* select */.Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,src/* select */.Ltv)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + let dir = diagObj.db.getDirection(); + if (dir === void 0) { + dir = "TD"; + } + const nodeSpacing = conf2.nodeSpacing || 50; + const rankSpacing = conf2.rankSpacing || 50; + const g = new graphlib/* Graph */.T({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + nodesep: nodeSpacing, + ranksep: rankSpacing, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + let subG; + const subGraphs = diagObj.db.getSubGraphs(); + for (let i2 = subGraphs.length - 1; i2 >= 0; i2--) { + subG = subGraphs[i2]; + diagObj.db.addVertex(subG.id, subG.title, "group", void 0, subG.classes); + } + const vert = diagObj.db.getVertices(); + mermaid_f47111a7.l.warn("Get vertices", vert); + const edges = diagObj.db.getEdges(); + let i = 0; + for (i = subGraphs.length - 1; i >= 0; i--) { + subG = subGraphs[i]; + (0,src/* selectAll */.Ubm)("cluster").append("text"); + for (let j = 0; j < subG.nodes.length; j++) { + mermaid_f47111a7.l.warn( + "Setting subgraph", + subG.nodes[j], + diagObj.db.lookUpDomId(subG.nodes[j]), + diagObj.db.lookUpDomId(subG.id) + ); + g.setParent(diagObj.db.lookUpDomId(subG.nodes[j]), diagObj.db.lookUpDomId(subG.id)); + } + } + await addVertices(vert, g, id, root, doc, diagObj); + await addEdges(edges, g, diagObj); + const render$1 = new render(); + flowChartShapes.addToRender(render$1); + render$1.arrows().none = function normal(parent, id2, edge, type) { + const marker = parent.append("marker").attr("id", id2).attr("viewBox", "0 0 10 10").attr("refX", 9).attr("refY", 5).attr("markerUnits", "strokeWidth").attr("markerWidth", 8).attr("markerHeight", 6).attr("orient", "auto"); + const path = marker.append("path").attr("d", "M 0 0 L 0 0 L 0 0 z"); + (0,util/* applyStyle */.AV)(path, edge[type + "Style"]); + }; + render$1.arrows().normal = function normal(parent, id2) { + const marker = parent.append("marker").attr("id", id2).attr("viewBox", "0 0 10 10").attr("refX", 9).attr("refY", 5).attr("markerUnits", "strokeWidth").attr("markerWidth", 8).attr("markerHeight", 6).attr("orient", "auto"); + marker.append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowheadPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + }; + const svg = root.select(`[id="${id}"]`); + const element = root.select("#" + id + " g"); + render$1(element, g); + element.selectAll("g.node").attr("title", function() { + return diagObj.db.getTooltip(this.id); + }); + diagObj.db.indexNodes("subGraph" + i); + for (i = 0; i < subGraphs.length; i++) { + subG = subGraphs[i]; + if (subG.title !== "undefined") { + const clusterRects = doc.querySelectorAll( + "#" + id + ' [id="' + diagObj.db.lookUpDomId(subG.id) + '"] rect' + ); + const clusterEl = doc.querySelectorAll( + "#" + id + ' [id="' + diagObj.db.lookUpDomId(subG.id) + '"]' + ); + const xPos = clusterRects[0].x.baseVal.value; + const yPos = clusterRects[0].y.baseVal.value; + const _width = clusterRects[0].width.baseVal.value; + const cluster = (0,src/* select */.Ltv)(clusterEl[0]); + const te = cluster.select(".label"); + te.attr("transform", `translate(${xPos + _width / 2}, ${yPos + 14})`); + te.attr("id", id + "Text"); + for (let j = 0; j < subG.classes.length; j++) { + clusterEl[0].classList.add(subG.classes[j]); + } + } + } + if (!conf2.htmlLabels) { + const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); + for (const label of labels) { + const dim = label.getBBox(); + const rect = doc.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.setAttribute("rx", 0); + rect.setAttribute("ry", 0); + rect.setAttribute("width", dim.width); + rect.setAttribute("height", dim.height); + label.insertBefore(rect, label.firstChild); + } + } + (0,mermaid_f47111a7.o)(g, svg, conf2.diagramPadding, conf2.useMaxWidth); + const keys = Object.keys(vert); + keys.forEach(function(key) { + const vertex = vert[key]; + if (vertex.link) { + const node = root.select("#" + id + ' [id="' + diagObj.db.lookUpDomId(key) + '"]'); + if (node) { + const link = doc.createElementNS("http://www.w3.org/2000/svg", "a"); + link.setAttributeNS("http://www.w3.org/2000/svg", "class", vertex.classes.join(" ")); + link.setAttributeNS("http://www.w3.org/2000/svg", "href", vertex.link); + link.setAttributeNS("http://www.w3.org/2000/svg", "rel", "noopener"); + if (securityLevel === "sandbox") { + link.setAttributeNS("http://www.w3.org/2000/svg", "target", "_top"); + } else if (vertex.linkTarget) { + link.setAttributeNS("http://www.w3.org/2000/svg", "target", vertex.linkTarget); + } + const linkNode = node.insert(function() { + return link; + }, ":first-child"); + const shape = node.select(".label-container"); + if (shape) { + linkNode.append(function() { + return shape.node(); + }); + } + const label = node.select(".label"); + if (label) { + linkNode.append(function() { + return label.node(); + }); + } + } + } + }); +}; +const flowRenderer = { + setConf, + addVertices, + addEdges, + getClasses, + draw +}; +const diagram = { + parser: flowDb_4b19a42f.p, + db: flowDb_4b19a42f.f, + renderer: styles_3ed67cfa.f, + styles: styles_3ed67cfa.a, + init: (cnf) => { + if (!cnf.flowchart) { + cnf.flowchart = {}; + } + cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + flowRenderer.setConf(cnf.flowchart); + flowDb_4b19a42f.f.clear(); + flowDb_4b19a42f.f.setGen("gen-1"); + } +}; + + + +/***/ }), + +/***/ 92746: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ r: () => (/* binding */ render) +/* harmony export */ }); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(21176); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14075); +/* harmony import */ var _edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(28747); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(76257); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(697); +/* harmony import */ var _createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(40351); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(26312); + + + + + + + +let clusterDb = {}; +let descendants = {}; +let parents = {}; +const clear$1 = () => { + descendants = {}; + parents = {}; + clusterDb = {}; +}; +const isDescendant = (id, ancestorId) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("In isDescendant", ancestorId, " ", id, " = ", descendants[ancestorId].includes(id)); + if (descendants[ancestorId].includes(id)) { + return true; + } + return false; +}; +const edgeInCluster = (edge, clusterId) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Descendants of ", clusterId, " is ", descendants[clusterId]); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge is ", edge); + if (edge.v === clusterId) { + return false; + } + if (edge.w === clusterId) { + return false; + } + if (!descendants[clusterId]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Tilt, ", clusterId, ",not in descendants"); + return false; + } + return descendants[clusterId].includes(edge.v) || isDescendant(edge.v, clusterId) || isDescendant(edge.w, clusterId) || descendants[clusterId].includes(edge.w); +}; +const copy = (clusterId, graph, newGraph, rootId) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Copying children of ", + clusterId, + "root", + rootId, + "data", + graph.node(clusterId), + rootId + ); + const nodes = graph.children(clusterId) || []; + if (clusterId !== rootId) { + nodes.push(clusterId); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Copying (nodes) clusterId", clusterId, "nodes", nodes); + nodes.forEach((node) => { + if (graph.children(node).length > 0) { + copy(node, graph, newGraph, rootId); + } else { + const data = graph.node(node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("cp ", node, " to ", rootId, " with parent ", clusterId); + newGraph.setNode(node, data); + if (rootId !== graph.parent(node)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Setting parent", node, graph.parent(node)); + newGraph.setParent(node, graph.parent(node)); + } + if (clusterId !== rootId && node !== clusterId) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Setting parent", node, clusterId); + newGraph.setParent(node, clusterId); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("In copy ", clusterId, "root", rootId, "data", graph.node(clusterId), rootId); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Not Setting parent for node=", + node, + "cluster!==rootId", + clusterId !== rootId, + "node!==clusterId", + node !== clusterId + ); + } + const edges = graph.edges(node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Copying Edges", edges); + edges.forEach((edge) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge", edge); + const data2 = graph.edge(edge.v, edge.w, edge.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge data", data2, rootId); + try { + if (edgeInCluster(edge, rootId)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Copying as ", edge.v, edge.w, data2, edge.name); + newGraph.setEdge(edge.v, edge.w, data2, edge.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("newGraph edges ", newGraph.edges(), newGraph.edge(newGraph.edges()[0])); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Skipping copy of edge ", + edge.v, + "-->", + edge.w, + " rootId: ", + rootId, + " clusterId:", + clusterId + ); + } + } catch (e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error(e); + } + }); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Removing node", node); + graph.removeNode(node); + }); +}; +const extractDescendants = (id, graph) => { + const children = graph.children(id); + let res = [...children]; + for (const child of children) { + parents[child] = id; + res = [...res, ...extractDescendants(child, graph)]; + } + return res; +}; +const findNonClusterChild = (id, graph) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching", id); + const children = graph.children(id); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching children of id ", id, children); + if (children.length < 1) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("This is a valid node", id); + return id; + } + for (const child of children) { + const _id = findNonClusterChild(child, graph); + if (_id) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Found replacement for", id, " => ", _id); + return _id; + } + } +}; +const getAnchorId = (id) => { + if (!clusterDb[id]) { + return id; + } + if (!clusterDb[id].externalConnections) { + return id; + } + if (clusterDb[id]) { + return clusterDb[id].id; + } + return id; +}; +const adjustClustersAndEdges = (graph, depth) => { + if (!graph || depth > 10) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting out, no graph "); + return; + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting in, graph "); + } + graph.nodes().forEach(function(id) { + const children = graph.children(id); + if (children.length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster identified", + id, + " Replacement id in edges: ", + findNonClusterChild(id, graph) + ); + descendants[id] = extractDescendants(id, graph); + clusterDb[id] = { id: findNonClusterChild(id, graph), clusterData: graph.node(id) }; + } + }); + graph.nodes().forEach(function(id) { + const children = graph.children(id); + const edges = graph.edges(); + if (children.length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Cluster identified", id, descendants); + edges.forEach((edge) => { + if (edge.v !== id && edge.w !== id) { + const d1 = isDescendant(edge.v, id); + const d2 = isDescendant(edge.w, id); + if (d1 ^ d2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge: ", edge, " leaves cluster ", id); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Descendants of XXX ", id, ": ", descendants[id]); + clusterDb[id].externalConnections = true; + } + } + }); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster ", id, descendants); + } + }); + for (let id of Object.keys(clusterDb)) { + const nonClusterChild = clusterDb[id].id; + const parent = graph.parent(nonClusterChild); + if (parent !== id && clusterDb[parent] && !clusterDb[parent].externalConnections) { + clusterDb[id].id = parent; + } + } + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(graph.edge(e))); + let v = e.v; + let w = e.w; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Fix XXX", + clusterDb, + "ids:", + e.v, + e.w, + "Translating: ", + clusterDb[e.v], + " --- ", + clusterDb[e.w] + ); + if (clusterDb[e.v] && clusterDb[e.w] && clusterDb[e.v] === clusterDb[e.w]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing link to self - removing XXX", e.v, e.w, e.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + const specialId = e.w + "---" + e.v; + graph.setNode(specialId, { + domId: specialId, + id: specialId, + labelStyle: "", + labelText: edge.label, + padding: 0, + shape: "labelRect", + style: "" + }); + const edge1 = structuredClone(edge); + const edge2 = structuredClone(edge); + edge1.label = ""; + edge1.arrowTypeEnd = "none"; + edge2.label = ""; + edge1.fromCluster = e.v; + edge2.toCluster = e.v; + graph.setEdge(v, specialId, edge1, e.name + "-cyclic-special"); + graph.setEdge(specialId, w, edge2, e.name + "-cyclic-special"); + } else if (clusterDb[e.v] || clusterDb[e.w]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + if (v !== e.v) { + const parent = graph.parent(v); + clusterDb[parent].externalConnections = true; + edge.fromCluster = e.v; + } + if (w !== e.w) { + const parent = graph.parent(w); + clusterDb[parent].externalConnections = true; + edge.toCluster = e.w; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fix Replacing with XXX", v, w, e.name); + graph.setEdge(v, w, edge, e.name); + } + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Adjusted Graph", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + extractor(graph, 0); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace(clusterDb); +}; +const extractor = (graph, depth) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("extractor - ", depth, dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph), graph.children("D")); + if (depth > 10) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error("Bailing out"); + return; + } + let nodes = graph.nodes(); + let hasChildren = false; + for (const node of nodes) { + const children = graph.children(node); + hasChildren = hasChildren || children.length > 0; + } + if (!hasChildren) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Done, no node has children", graph.nodes()); + return; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Nodes = ", nodes, depth); + for (const node of nodes) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Extracting node", + node, + clusterDb, + clusterDb[node] && !clusterDb[node].externalConnections, + !graph.parent(node), + graph.node(node), + graph.children("D"), + " Depth ", + depth + ); + if (!clusterDb[node]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster", node, depth); + } else if (!clusterDb[node].externalConnections && // !graph.parent(node) && + graph.children(node) && graph.children(node).length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster without external connections, without a parent and with children", + node, + depth + ); + const graphSettings = graph.graph(); + let dir = graphSettings.rankdir === "TB" ? "LR" : "TB"; + if (clusterDb[node] && clusterDb[node].clusterData && clusterDb[node].clusterData.dir) { + dir = clusterDb[node].clusterData.dir; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing dir", clusterDb[node].clusterData.dir, dir); + } + const clusterGraph = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .T({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + // Todo: set proper spacing + nodesep: 50, + ranksep: 50, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Old graph before copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + copy(node, graph, clusterGraph, node); + graph.setNode(node, { + clusterNode: true, + id: node, + clusterData: clusterDb[node].clusterData, + labelText: clusterDb[node].labelText, + graph: clusterGraph + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New graph after copy node: (", node, ")", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(clusterGraph)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Old graph after copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster ** ", + node, + " **not meeting the criteria !externalConnections:", + !clusterDb[node].externalConnections, + " no parent: ", + !graph.parent(node), + " children ", + graph.children(node) && graph.children(node).length > 0, + graph.children("D"), + depth + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(clusterDb); + } + } + nodes = graph.nodes(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New list of nodes", nodes); + for (const node of nodes) { + const data = graph.node(node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn(" Now next level", node, data); + if (data.clusterNode) { + extractor(data.graph, depth + 1); + } + } +}; +const sorter = (graph, nodes) => { + if (nodes.length === 0) { + return []; + } + let result = Object.assign(nodes); + nodes.forEach((node) => { + const children = graph.children(node); + const sorted = sorter(graph, children); + result = [...result, ...sorted]; + }); + return result; +}; +const sortNodesByHierarchy = (graph) => sorter(graph, graph.children()); +const rect = (parent, node) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Creating subgraph rect for ", node.id, node); + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const shapeSvg = parent.insert("g").attr("class", "cluster" + (node.class ? " " + node.class : "")).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const useHtmlLabels = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const text = node.labelType === "markdown" ? (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_5__.a)(label, node.labelText, { style: node.labelStyle, useHtmlLabels }) : label.node().appendChild((0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width; + if (node.width <= bbox.width + padding) { + node.diff = (bbox.width - node.width) / 2 - node.padding / 2; + } else { + node.diff = -node.padding / 2; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Data ", node, JSON.stringify(node)); + rect2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - width / 2).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width).attr("height", node.height + padding); + const { subGraphTitleTopMargin } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.g)(siteConfig); + if (useHtmlLabels) { + label.attr( + "transform", + // This puts the label on top of the box instead of inside it + `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 + subGraphTitleTopMargin})` + ); + } else { + label.attr( + "transform", + // This puts the label on top of the box instead of inside it + `translate(${node.x}, ${node.y - node.height / 2 + subGraphTitleTopMargin})` + ); + } + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const noteGroup = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "note-cluster").attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", node.width + padding).attr("height", node.height + padding).attr("fill", "none"); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const roundedWithTitle = (parent, node) => { + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const innerRect = shapeSvg.append("rect"); + const text = label.node().appendChild((0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + bbox = text.getBBox(); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width; + if (node.width <= bbox.width + node.padding) { + node.diff = (bbox.width + node.padding * 0 - node.width) / 2; + } else { + node.diff = -node.padding / 2; + } + rect2.attr("class", "outer").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width + padding).attr("height", node.height + padding); + innerRect.attr("class", "inner").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding + bbox.height - 1).attr("width", width + padding).attr("height", node.height + padding - bbox.height - 3); + const { subGraphTitleTopMargin } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.g)(siteConfig); + label.attr( + "transform", + `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 - node.padding / 3 + ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels) ? 5 : 3) + subGraphTitleTopMargin})` + ); + const rectBox = rect2.node().getBBox(); + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const divider = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("class", "divider").attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2).attr("width", node.width + padding).attr("height", node.height + padding); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.diff = -node.padding / 2; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const shapes = { rect, roundedWithTitle, noteGroup, divider }; +let clusterElems = {}; +const insertCluster = (elem, node) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Inserting cluster"); + const shape = node.shape || "rect"; + clusterElems[node.id] = shapes[shape](elem, node); +}; +const clear = () => { + clusterElems = {}; +}; +const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, siteConfig) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph in recursive render: XXX", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph), parentCluster); + const dir = graph.graph().rankdir; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Dir in recursive render - dir:", dir); + const elem = _elem.insert("g").attr("class", "root"); + if (!graph.nodes()) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("No nodes found for", graph); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Recursive render XXX", graph.nodes()); + } + if (graph.edges().length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Recursive edges", graph.edge(graph.edges()[0])); + } + const clusters = elem.insert("g").attr("class", "clusters"); + const edgePaths = elem.insert("g").attr("class", "edgePaths"); + const edgeLabels = elem.insert("g").attr("class", "edgeLabels"); + const nodes = elem.insert("g").attr("class", "nodes"); + await Promise.all( + graph.nodes().map(async function(v) { + const node = graph.node(v); + if (parentCluster !== void 0) { + const data = JSON.parse(JSON.stringify(parentCluster.clusterData)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Setting data for cluster XXX (", v, ") ", data, parentCluster); + graph.setNode(parentCluster.id, data); + if (!graph.parent(v)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Setting parent", v, parentCluster.id); + graph.setParent(v, parentCluster.id, data); + } + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("(Insert) Node XXX" + v + ": " + JSON.stringify(graph.node(v))); + if (node && node.clusterNode) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster identified", v, node.width, graph.node(v)); + const o = await recursiveRender( + nodes, + node.graph, + diagramType, + id, + graph.node(v), + siteConfig + ); + const newEl = o.elem; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.u)(node, newEl); + node.diff = o.diff || 0; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node bounds (abc123)", v, node, node.width, node.x, node.y); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.s)(newEl, node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Recursive render complete ", newEl, node); + } else { + if (graph.children(v).length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster - the non recursive path XXX", v, node.id, node, graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info(findNonClusterChild(node.id, graph)); + clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node }; + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node - the non recursive path", v, node.id, node); + await (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.e)(nodes, graph.node(v), dir); + } + } + }) + ); + graph.edges().forEach(function(e) { + const edge = graph.edge(e.v, e.w, e.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": ", e, " ", JSON.stringify(graph.edge(e))); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Fix", clusterDb, "ids:", e.v, e.w, "Translating: ", clusterDb[e.v], clusterDb[e.w]); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.f)(edgeLabels, edge); + }); + graph.edges().forEach(function(e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("### Layout ###"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info(graph); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__/* .layout */ .Zp)(graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph after layout:", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + let diff = 0; + const { subGraphTitleTotalMargin } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.g)(siteConfig); + sortNodesByHierarchy(graph).forEach(function(v) { + const node = graph.node(v); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Position " + v + ": " + JSON.stringify(graph.node(v))); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Position " + v + ": (" + node.x, + "," + node.y, + ") width: ", + node.width, + " height: ", + node.height + ); + if (node && node.clusterNode) { + node.y += subGraphTitleTotalMargin; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } else { + if (graph.children(v).length > 0) { + node.height += subGraphTitleTotalMargin; + insertCluster(clusters, node); + clusterDb[node.id].node = node; + } else { + node.y += subGraphTitleTotalMargin / 2; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } + } + }); + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(edge), edge); + edge.points.forEach((point) => point.y += subGraphTitleTotalMargin / 2); + const paths = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.h)(edgePaths, e, edge, clusterDb, diagramType, graph, id); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.j)(edge, paths); + }); + graph.nodes().forEach(function(v) { + const n = graph.node(v); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info(v, n.type, n.diff); + if (n.type === "group") { + diff = n.diff; + } + }); + return { elem, diff }; +}; +const render = async (elem, graph, markers, diagramType, id) => { + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.a)(elem, markers, diagramType, id); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.b)(); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.d)(); + clear(); + clear$1(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph at first:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph))); + adjustClustersAndEdges(graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph after:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph))); + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + await recursiveRender(elem, graph, diagramType, id, void 0, siteConfig); +}; + + + +/***/ }), + +/***/ 98696: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ flowStyles), +/* harmony export */ f: () => (/* binding */ flowRendererV2) +/* harmony export */ }); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(697); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(26312); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(76257); +/* harmony import */ var _index_fc10efb0_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(92746); +/* harmony import */ var dagre_d3_es_src_dagre_js_label_add_html_label_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(10646); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(75937); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(25582); + + + + + + +const conf = {}; +const setConf = function(cnf) { + const keys = Object.keys(cnf); + for (const key of keys) { + conf[key] = cnf[key]; + } +}; +const addVertices = async function(vert, g, svgId, root, doc, diagObj) { + const svg = root.select(`[id="${svgId}"]`); + const keys = Object.keys(vert); + for (const id of keys) { + const vertex = vert[id]; + let classStr = "default"; + if (vertex.classes.length > 0) { + classStr = vertex.classes.join(" "); + } + classStr = classStr + " flowchart-label"; + const styles = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.k)(vertex.styles); + let vertexText = vertex.text !== void 0 ? vertex.text : vertex.id; + let vertexNode; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("vertex", vertex, vertex.labelType); + if (vertex.labelType === "markdown") { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("vertex", vertex, vertex.labelType); + } else { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.c)().flowchart.htmlLabels)) { + const node = { + label: vertexText + }; + vertexNode = (0,dagre_d3_es_src_dagre_js_label_add_html_label_js__WEBPACK_IMPORTED_MODULE_3__/* .addHtmlLabel */ .H)(svg, node).node(); + vertexNode.parentNode.removeChild(vertexNode); + } else { + const svgLabel = doc.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", styles.labelStyle.replace("color:", "fill:")); + const rows = vertexText.split(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.e.lineBreakRegex); + for (const row of rows) { + const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "1"); + tspan.textContent = row; + svgLabel.appendChild(tspan); + } + vertexNode = svgLabel; + } + } + let radius = 0; + let _shape = ""; + switch (vertex.type) { + case "round": + radius = 5; + _shape = "rect"; + break; + case "square": + _shape = "rect"; + break; + case "diamond": + _shape = "question"; + break; + case "hexagon": + _shape = "hexagon"; + break; + case "odd": + _shape = "rect_left_inv_arrow"; + break; + case "lean_right": + _shape = "lean_right"; + break; + case "lean_left": + _shape = "lean_left"; + break; + case "trapezoid": + _shape = "trapezoid"; + break; + case "inv_trapezoid": + _shape = "inv_trapezoid"; + break; + case "odd_right": + _shape = "rect_left_inv_arrow"; + break; + case "circle": + _shape = "circle"; + break; + case "ellipse": + _shape = "ellipse"; + break; + case "stadium": + _shape = "stadium"; + break; + case "subroutine": + _shape = "subroutine"; + break; + case "cylinder": + _shape = "cylinder"; + break; + case "group": + _shape = "rect"; + break; + case "doublecircle": + _shape = "doublecircle"; + break; + default: + _shape = "rect"; + } + const labelText = await (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.r)(vertexText, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.c)()); + g.setNode(vertex.id, { + labelStyle: styles.labelStyle, + shape: _shape, + labelText, + labelType: vertex.labelType, + rx: radius, + ry: radius, + class: classStr, + style: styles.style, + id: vertex.id, + link: vertex.link, + linkTarget: vertex.linkTarget, + tooltip: diagObj.db.getTooltip(vertex.id) || "", + domId: diagObj.db.lookUpDomId(vertex.id), + haveCallback: vertex.haveCallback, + width: vertex.type === "group" ? 500 : void 0, + dir: vertex.dir, + type: vertex.type, + props: vertex.props, + padding: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.c)().flowchart.padding + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("setNode", { + labelStyle: styles.labelStyle, + labelType: vertex.labelType, + shape: _shape, + labelText, + rx: radius, + ry: radius, + class: classStr, + style: styles.style, + id: vertex.id, + domId: diagObj.db.lookUpDomId(vertex.id), + width: vertex.type === "group" ? 500 : void 0, + type: vertex.type, + dir: vertex.dir, + props: vertex.props, + padding: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.c)().flowchart.padding + }); + } +}; +const addEdges = async function(edges, g, diagObj) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("abc78 edges = ", edges); + let cnt = 0; + let linkIdCnt = {}; + let defaultStyle; + let defaultLabelStyle; + if (edges.defaultStyle !== void 0) { + const defaultStyles = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.k)(edges.defaultStyle); + defaultStyle = defaultStyles.style; + defaultLabelStyle = defaultStyles.labelStyle; + } + for (const edge of edges) { + cnt++; + const linkIdBase = "L-" + edge.start + "-" + edge.end; + if (linkIdCnt[linkIdBase] === void 0) { + linkIdCnt[linkIdBase] = 0; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); + } else { + linkIdCnt[linkIdBase]++; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); + } + let linkId = linkIdBase + "-" + linkIdCnt[linkIdBase]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("abc78 new link id to be used is", linkIdBase, linkId, linkIdCnt[linkIdBase]); + const linkNameStart = "LS-" + edge.start; + const linkNameEnd = "LE-" + edge.end; + const edgeData = { style: "", labelStyle: "" }; + edgeData.minlen = edge.length || 1; + if (edge.type === "arrow_open") { + edgeData.arrowhead = "none"; + } else { + edgeData.arrowhead = "normal"; + } + edgeData.arrowTypeStart = "arrow_open"; + edgeData.arrowTypeEnd = "arrow_open"; + switch (edge.type) { + case "double_arrow_cross": + edgeData.arrowTypeStart = "arrow_cross"; + case "arrow_cross": + edgeData.arrowTypeEnd = "arrow_cross"; + break; + case "double_arrow_point": + edgeData.arrowTypeStart = "arrow_point"; + case "arrow_point": + edgeData.arrowTypeEnd = "arrow_point"; + break; + case "double_arrow_circle": + edgeData.arrowTypeStart = "arrow_circle"; + case "arrow_circle": + edgeData.arrowTypeEnd = "arrow_circle"; + break; + } + let style = ""; + let labelStyle = ""; + switch (edge.stroke) { + case "normal": + style = "fill:none;"; + if (defaultStyle !== void 0) { + style = defaultStyle; + } + if (defaultLabelStyle !== void 0) { + labelStyle = defaultLabelStyle; + } + edgeData.thickness = "normal"; + edgeData.pattern = "solid"; + break; + case "dotted": + edgeData.thickness = "normal"; + edgeData.pattern = "dotted"; + edgeData.style = "fill:none;stroke-width:2px;stroke-dasharray:3;"; + break; + case "thick": + edgeData.thickness = "thick"; + edgeData.pattern = "solid"; + edgeData.style = "stroke-width: 3.5px;fill:none;"; + break; + case "invisible": + edgeData.thickness = "invisible"; + edgeData.pattern = "solid"; + edgeData.style = "stroke-width: 0;fill:none;"; + break; + } + if (edge.style !== void 0) { + const styles = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.k)(edge.style); + style = styles.style; + labelStyle = styles.labelStyle; + } + edgeData.style = edgeData.style += style; + edgeData.labelStyle = edgeData.labelStyle += labelStyle; + if (edge.interpolate !== void 0) { + edgeData.curve = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.n)(edge.interpolate, d3__WEBPACK_IMPORTED_MODULE_1__/* .curveLinear */ .lUB); + } else if (edges.defaultInterpolate !== void 0) { + edgeData.curve = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.n)(edges.defaultInterpolate, d3__WEBPACK_IMPORTED_MODULE_1__/* .curveLinear */ .lUB); + } else { + edgeData.curve = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.n)(conf.curve, d3__WEBPACK_IMPORTED_MODULE_1__/* .curveLinear */ .lUB); + } + if (edge.text === void 0) { + if (edge.style !== void 0) { + edgeData.arrowheadStyle = "fill: #333"; + } + } else { + edgeData.arrowheadStyle = "fill: #333"; + edgeData.labelpos = "c"; + } + edgeData.labelType = edge.labelType; + edgeData.label = await (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.r)(edge.text.replace(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.e.lineBreakRegex, "\n"), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.c)()); + if (edge.style === void 0) { + edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none;"; + } + edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:"); + edgeData.id = linkId; + edgeData.classes = "flowchart-link " + linkNameStart + " " + linkNameEnd; + g.setEdge(edge.start, edge.end, edgeData, cnt); + } +}; +const getClasses = function(text, diagObj) { + return diagObj.db.getClasses(); +}; +const draw = async function(text, id, _version, diagObj) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("Drawing flowchart"); + let dir = diagObj.db.getDirection(); + if (dir === void 0) { + dir = "TD"; + } + const { securityLevel, flowchart: conf2 } = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.c)(); + const nodeSpacing = conf2.nodeSpacing || 50; + const rankSpacing = conf2.rankSpacing || 50; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + const g = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_0__/* .Graph */ .T({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + nodesep: nodeSpacing, + ranksep: rankSpacing, + marginx: 0, + marginy: 0 + }).setDefaultEdgeLabel(function() { + return {}; + }); + let subG; + const subGraphs = diagObj.db.getSubGraphs(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("Subgraphs - ", subGraphs); + for (let i2 = subGraphs.length - 1; i2 >= 0; i2--) { + subG = subGraphs[i2]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("Subgraph - ", subG); + diagObj.db.addVertex( + subG.id, + { text: subG.title, type: subG.labelType }, + "group", + void 0, + subG.classes, + subG.dir + ); + } + const vert = diagObj.db.getVertices(); + const edges = diagObj.db.getEdges(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("Edges", edges); + let i = 0; + for (i = subGraphs.length - 1; i >= 0; i--) { + subG = subGraphs[i]; + (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .selectAll */ .Ubm)("cluster").append("text"); + for (let j = 0; j < subG.nodes.length; j++) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("Setting up subgraphs", subG.nodes[j], subG.id); + g.setParent(subG.nodes[j], subG.id); + } + } + await addVertices(vert, g, id, root, doc, diagObj); + await addEdges(edges, g); + const svg = root.select(`[id="${id}"]`); + const element = root.select("#" + id + " g"); + await (0,_index_fc10efb0_js__WEBPACK_IMPORTED_MODULE_4__.r)(element, g, ["point", "circle", "cross"], "flowchart", id); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.u.insertTitle(svg, "flowchartTitleText", conf2.titleTopMargin, diagObj.db.getDiagramTitle()); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.o)(g, svg, conf2.diagramPadding, conf2.useMaxWidth); + diagObj.db.indexNodes("subGraph" + i); + if (!conf2.htmlLabels) { + const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); + for (const label of labels) { + const dim = label.getBBox(); + const rect = doc.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.setAttribute("rx", 0); + rect.setAttribute("ry", 0); + rect.setAttribute("width", dim.width); + rect.setAttribute("height", dim.height); + label.insertBefore(rect, label.firstChild); + } + } + const keys = Object.keys(vert); + keys.forEach(function(key) { + const vertex = vert[key]; + if (vertex.link) { + const node = (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)("#" + id + ' [id="' + key + '"]'); + if (node) { + const link = doc.createElementNS("http://www.w3.org/2000/svg", "a"); + link.setAttributeNS("http://www.w3.org/2000/svg", "class", vertex.classes.join(" ")); + link.setAttributeNS("http://www.w3.org/2000/svg", "href", vertex.link); + link.setAttributeNS("http://www.w3.org/2000/svg", "rel", "noopener"); + if (securityLevel === "sandbox") { + link.setAttributeNS("http://www.w3.org/2000/svg", "target", "_top"); + } else if (vertex.linkTarget) { + link.setAttributeNS("http://www.w3.org/2000/svg", "target", vertex.linkTarget); + } + const linkNode = node.insert(function() { + return link; + }, ":first-child"); + const shape = node.select(".label-container"); + if (shape) { + linkNode.append(function() { + return shape.node(); + }); + } + const label = node.select(".label"); + if (label) { + linkNode.append(function() { + return label.node(); + }); + } + } + } + }); +}; +const flowRendererV2 = { + setConf, + addVertices, + addEdges, + getClasses, + draw +}; +const fade = (color, opacity) => { + const channel = khroma__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A; + const r = channel(color, "r"); + const g = channel(color, "g"); + const b = channel(color, "b"); + return khroma__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A(r, g, b, opacity); +}; +const getStyles = (options) => `.label { + font-family: ${options.fontFamily}; + color: ${options.nodeTextColor || options.textColor}; + } + .cluster-label text { + fill: ${options.titleColor}; + } + .cluster-label span,p { + color: ${options.titleColor}; + } + + .label text,span,p { + fill: ${options.nodeTextColor || options.textColor}; + color: ${options.nodeTextColor || options.textColor}; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + .flowchart-label text { + text-anchor: middle; + } + // .flowchart-label .text-outer-tspan { + // text-anchor: middle; + // } + // .flowchart-label .text-inner-tspan { + // text-anchor: start; + // } + + .node .katex path { + fill: #000; + stroke: #000; + stroke-width: 1px; + } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${options.arrowheadColor}; + } + + .edgePath .path { + stroke: ${options.lineColor}; + stroke-width: 2.0px; + } + + .flowchart-link { + stroke: ${options.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${options.edgeLabelBackground}; + rect { + opacity: 0.5; + background-color: ${options.edgeLabelBackground}; + fill: ${options.edgeLabelBackground}; + } + text-align: center; + } + + /* For html labels only */ + .labelBkg { + background-color: ${fade(options.edgeLabelBackground, 0.5)}; + // background-color: + } + + .cluster rect { + fill: ${options.clusterBkg}; + stroke: ${options.clusterBorder}; + stroke-width: 1px; + } + + .cluster text { + fill: ${options.titleColor}; + } + + .cluster span,p { + color: ${options.titleColor}; + } + /* .cluster div { + color: ${options.titleColor}; + } */ + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${options.fontFamily}; + font-size: 12px; + background: ${options.tertiaryColor}; + border: 1px solid ${options.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } +`; +const flowStyles = getStyles; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/1276f6ab.d252c887.js b/assets/js/1276f6ab.d252c887.js new file mode 100644 index 0000000000..decb3815f5 --- /dev/null +++ b/assets/js/1276f6ab.d252c887.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4684],{35458:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>d});var t=s(74848),i=s(28453);const o={title:"Push-based approach for providing usage data",type:"Decision Record",status:"Draft",track:"Ops"},a=void 0,r={id:"scs-0411-v1-publishing_method_for_metering_data",title:"Push-based approach for providing usage data",description:"for more info. --\x3e",source:"@site/standards/scs-0411-v1-publishing_method_for_metering_data.md",sourceDirName:".",slug:"/scs-0411-v1-publishing_method_for_metering_data",permalink:"/standards/scs-0411-v1-publishing_method_for_metering_data",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Push-based approach for providing usage data",type:"Decision Record",status:"Draft",track:"Ops"},sidebar:"standards",previous:{title:"scs-0411: Push-based approach for providing usage data",permalink:"/standards/ops/scs-0411"},next:{title:"scs-0412: Exposition of IaaS metering data as JSON",permalink:"/standards/ops/scs-0412"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Definitions",id:"definitions",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options",id:"options",level:3},{value:"Push-based flow",id:"push-based-flow",level:4},{value:"Poll-based flow",id:"poll-based-flow",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const n={h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsx)(n.p,{children:"In the past we noticed missing events in the telemetry stack of OpenStack.\nThis results in situations where the Cloud Service Provider (CSP)\nmay think that a resource is still in use while the owner shut it down,\nor may not be aware of a resource which has been created."}),"\n",(0,t.jsx)(n.p,{children:"Such inaccurate data is a problem,\nwhen it is supposed to be used for billing purposes."}),"\n",(0,t.jsx)(n.p,{children:"This document discusses how such metering data should be made available\nto the cloud service provider\nfor forwarding into their own billing solution."}),"\n",(0,t.jsx)(n.h2,{id:"definitions",children:"Definitions"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Push-based flow:\nIn a push-based flow,\nthe system generating data actively sends that data to a consumer."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Pull-based flow:\nIn a pull-based flow,\nthe system generating data waits for the system consuming the data\nto ask for that data."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Metering:\nCollection of usage data of a cloud,\nfor the specific purpose of creating invoices\nto bill customers for the resources they have allocated."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Billing:\nThe entire process of creation, management and sending of invoices\ngenerated from metering data."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,t.jsx)(n.p,{children:"Being able to bill users\nfor the resources they use\nis a prerequisite for commercially operating a cloud.\nThe SCS project wants to deliver a cloud stack\nwhich can be used for that purpose,\nhence providing reliable metering data is a requirement."}),"\n",(0,t.jsx)(n.p,{children:"We generally expect that cloud providers already have\nsome kind of customer-relation management or billing system in place.\nHence, it is important that the SCS is not too opinionated\non this implementation detail,\nbut provides a system which can easily interface with other systems."}),"\n",(0,t.jsx)(n.p,{children:"This is similar to how the SCS specified the monitoring stack."}),"\n",(0,t.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,t.jsx)(n.p,{children:"The following requirements exist for the process for providing metrics to the cloud service provider:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"MUST scale to different timescales:\nWe expect to have metrics which change frequently (e.g. object store usage)\nand metrics which change rarely (e.g. cinder volume sizes)."}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"options",children:"Options"}),"\n",(0,t.jsx)(n.h4,{id:"push-based-flow",children:"Push-based flow"}),"\n",(0,t.jsx)(n.p,{children:"In a push-based flow,\nthe to-be-implemented metering system pushes events to the sink\nas soon as it is reasonably confident\nthat the event can be used for billing purposes."}),"\n",(0,t.jsx)(n.h4,{id:"poll-based-flow",children:"Poll-based flow"}),"\n",(0,t.jsx)(n.p,{children:"In the poll-based flow,\nwhichever system the CSP runs would be responsible for polling the metering API\nin a frequency sufficient to capture all data with sufficient granularity."}),"\n",(0,t.jsx)(n.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"What is necessary to extend the availability of sending to various sinks?"}),"\n",(0,t.jsx)(n.li,{children:"How does the configuration look like that is needed to push to a sink from the same type that will be already implemented?"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,t.jsx)(n.p,{children:"As we need to support very different time scales of data,\nthe push-based flow is more suitable:\nit allows the producer of the data,\nwhich knows about the interval in which it changes,\nwhen to provide new data to the consumer.\nIn contrast to that,\na poll-based flow would need the consumer to know about change intervals,\nor alternatively poll in the highest change frequency ever expected."}),"\n",(0,t.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"SCS-0410-v1"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,t.jsx)(n.p,{children:"None (this is a decision record)."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var t=s(96540);const i={},o=t.createContext(i);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/130.def7e228.js b/assets/js/130.def7e228.js new file mode 100644 index 0000000000..223d1a5663 --- /dev/null +++ b/assets/js/130.def7e228.js @@ -0,0 +1,18473 @@ +"use strict"; +exports.id = 130; +exports.ids = [130]; +exports.modules = { + +/***/ 22130: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ katex) +/* harmony export */ }); +/** + * Lexing or parsing positional information for error reporting. + * This object is immutable. + */ +class SourceLocation { + // The + prefix indicates that these fields aren't writeable + // Lexer holding the input string. + // Start offset, zero-based inclusive. + // End offset, zero-based exclusive. + constructor(lexer, start, end) { + this.lexer = void 0; + this.start = void 0; + this.end = void 0; + this.lexer = lexer; + this.start = start; + this.end = end; + } + /** + * Merges two `SourceLocation`s from location providers, given they are + * provided in order of appearance. + * - Returns the first one's location if only the first is provided. + * - Returns a merged range of the first and the last if both are provided + * and their lexers match. + * - Otherwise, returns null. + */ + + + static range(first, second) { + if (!second) { + return first && first.loc; + } else if (!first || !first.loc || !second.loc || first.loc.lexer !== second.loc.lexer) { + return null; + } else { + return new SourceLocation(first.loc.lexer, first.loc.start, second.loc.end); + } + } + +} + +/** + * Interface required to break circular dependency between Token, Lexer, and + * ParseError. + */ + +/** + * The resulting token returned from `lex`. + * + * It consists of the token text plus some position information. + * The position information is essentially a range in an input string, + * but instead of referencing the bare input string, we refer to the lexer. + * That way it is possible to attach extra metadata to the input string, + * like for example a file name or similar. + * + * The position information is optional, so it is OK to construct synthetic + * tokens if appropriate. Not providing available position information may + * lead to degraded error reporting, though. + */ +class Token { + // don't expand the token + // used in \noexpand + constructor(text, // the text of this token + loc) { + this.text = void 0; + this.loc = void 0; + this.noexpand = void 0; + this.treatAsRelax = void 0; + this.text = text; + this.loc = loc; + } + /** + * Given a pair of tokens (this and endToken), compute a `Token` encompassing + * the whole input range enclosed by these two. + */ + + + range(endToken, // last token of the range, inclusive + text // the text of the newly constructed token + ) { + return new Token(text, SourceLocation.range(this, endToken)); + } + +} + +/** + * This is the ParseError class, which is the main error thrown by KaTeX + * functions when something has gone wrong. This is used to distinguish internal + * errors from errors in the expression that the user provided. + * + * If possible, a caller should provide a Token or ParseNode with information + * about where in the source string the problem occurred. + */ +class ParseError { + // Error start position based on passed-in Token or ParseNode. + // Length of affected text based on passed-in Token or ParseNode. + // The underlying error message without any context added. + constructor(message, // The error message + token // An object providing position information + ) { + this.name = void 0; + this.position = void 0; + this.length = void 0; + this.rawMessage = void 0; + var error = "KaTeX parse error: " + message; + var start; + var end; + var loc = token && token.loc; + + if (loc && loc.start <= loc.end) { + // If we have the input and a position, make the error a bit fancier + // Get the input + var input = loc.lexer.input; // Prepend some information + + start = loc.start; + end = loc.end; + + if (start === input.length) { + error += " at end of input: "; + } else { + error += " at position " + (start + 1) + ": "; + } // Underline token in question using combining underscores + + + var underlined = input.slice(start, end).replace(/[^]/g, "$&\u0332"); // Extract some context from the input and add it to the error + + var left; + + if (start > 15) { + left = "…" + input.slice(start - 15, start); + } else { + left = input.slice(0, start); + } + + var right; + + if (end + 15 < input.length) { + right = input.slice(end, end + 15) + "…"; + } else { + right = input.slice(end); + } + + error += left + underlined + right; + } // Some hackery to make ParseError a prototype of Error + // See http://stackoverflow.com/a/8460753 + // $FlowFixMe + + + var self = new Error(error); + self.name = "ParseError"; // $FlowFixMe + + self.__proto__ = ParseError.prototype; + self.position = start; + + if (start != null && end != null) { + self.length = end - start; + } + + self.rawMessage = message; + return self; + } + +} // $FlowFixMe More hackery + + +ParseError.prototype.__proto__ = Error.prototype; + +/** + * This file contains a list of utility functions which are useful in other + * files. + */ + +/** + * Return whether an element is contained in a list + */ +var contains = function contains(list, elem) { + return list.indexOf(elem) !== -1; +}; +/** + * Provide a default value if a setting is undefined + * NOTE: Couldn't use `T` as the output type due to facebook/flow#5022. + */ + + +var deflt = function deflt(setting, defaultIfUndefined) { + return setting === undefined ? defaultIfUndefined : setting; +}; // hyphenate and escape adapted from Facebook's React under Apache 2 license + + +var uppercase = /([A-Z])/g; + +var hyphenate = function hyphenate(str) { + return str.replace(uppercase, "-$1").toLowerCase(); +}; + +var ESCAPE_LOOKUP = { + "&": "&", + ">": ">", + "<": "<", + "\"": """, + "'": "'" +}; +var ESCAPE_REGEX = /[&><"']/g; +/** + * Escapes text to prevent scripting attacks. + */ + +function escape(text) { + return String(text).replace(ESCAPE_REGEX, match => ESCAPE_LOOKUP[match]); +} +/** + * Sometimes we want to pull out the innermost element of a group. In most + * cases, this will just be the group itself, but when ordgroups and colors have + * a single element, we want to pull that out. + */ + + +var getBaseElem = function getBaseElem(group) { + if (group.type === "ordgroup") { + if (group.body.length === 1) { + return getBaseElem(group.body[0]); + } else { + return group; + } + } else if (group.type === "color") { + if (group.body.length === 1) { + return getBaseElem(group.body[0]); + } else { + return group; + } + } else if (group.type === "font") { + return getBaseElem(group.body); + } else { + return group; + } +}; +/** + * TeXbook algorithms often reference "character boxes", which are simply groups + * with a single character in them. To decide if something is a character box, + * we find its innermost group, and see if it is a single character. + */ + + +var isCharacterBox = function isCharacterBox(group) { + var baseElem = getBaseElem(group); // These are all they types of groups which hold single characters + + return baseElem.type === "mathord" || baseElem.type === "textord" || baseElem.type === "atom"; +}; + +var assert = function assert(value) { + if (!value) { + throw new Error('Expected non-null, but got ' + String(value)); + } + + return value; +}; +/** + * Return the protocol of a URL, or "_relative" if the URL does not specify a + * protocol (and thus is relative), or `null` if URL has invalid protocol + * (so should be outright rejected). + */ + +var protocolFromUrl = function protocolFromUrl(url) { + // Check for possible leading protocol. + // https://url.spec.whatwg.org/#url-parsing strips leading whitespace + // (U+20) or C0 control (U+00-U+1F) characters. + // eslint-disable-next-line no-control-regex + var protocol = /^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(url); + + if (!protocol) { + return "_relative"; + } // Reject weird colons + + + if (protocol[2] !== ":") { + return null; + } // Reject invalid characters in scheme according to + // https://datatracker.ietf.org/doc/html/rfc3986#section-3.1 + + + if (!/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(protocol[1])) { + return null; + } // Lowercase the protocol + + + return protocol[1].toLowerCase(); +}; +var utils = { + contains, + deflt, + escape, + hyphenate, + getBaseElem, + isCharacterBox, + protocolFromUrl +}; + +/* eslint no-console:0 */ +// TODO: automatically generate documentation +// TODO: check all properties on Settings exist +// TODO: check the type of a property on Settings matches +var SETTINGS_SCHEMA = { + displayMode: { + type: "boolean", + description: "Render math in display mode, which puts the math in " + "display style (so \\int and \\sum are large, for example), and " + "centers the math on the page on its own line.", + cli: "-d, --display-mode" + }, + output: { + type: { + enum: ["htmlAndMathml", "html", "mathml"] + }, + description: "Determines the markup language of the output.", + cli: "-F, --format " + }, + leqno: { + type: "boolean", + description: "Render display math in leqno style (left-justified tags)." + }, + fleqn: { + type: "boolean", + description: "Render display math flush left." + }, + throwOnError: { + type: "boolean", + default: true, + cli: "-t, --no-throw-on-error", + cliDescription: "Render errors (in the color given by --error-color) ins" + "tead of throwing a ParseError exception when encountering an error." + }, + errorColor: { + type: "string", + default: "#cc0000", + cli: "-c, --error-color ", + cliDescription: "A color string given in the format 'rgb' or 'rrggbb' " + "(no #). This option determines the color of errors rendered by the " + "-t option.", + cliProcessor: color => "#" + color + }, + macros: { + type: "object", + cli: "-m, --macro ", + cliDescription: "Define custom macro of the form '\\foo:expansion' (use " + "multiple -m arguments for multiple macros).", + cliDefault: [], + cliProcessor: (def, defs) => { + defs.push(def); + return defs; + } + }, + minRuleThickness: { + type: "number", + description: "Specifies a minimum thickness, in ems, for fraction lines," + " `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, " + "`\\hdashline`, `\\underline`, `\\overline`, and the borders of " + "`\\fbox`, `\\boxed`, and `\\fcolorbox`.", + processor: t => Math.max(0, t), + cli: "--min-rule-thickness ", + cliProcessor: parseFloat + }, + colorIsTextColor: { + type: "boolean", + description: "Makes \\color behave like LaTeX's 2-argument \\textcolor, " + "instead of LaTeX's one-argument \\color mode change.", + cli: "-b, --color-is-text-color" + }, + strict: { + type: [{ + enum: ["warn", "ignore", "error"] + }, "boolean", "function"], + description: "Turn on strict / LaTeX faithfulness mode, which throws an " + "error if the input uses features that are not supported by LaTeX.", + cli: "-S, --strict", + cliDefault: false + }, + trust: { + type: ["boolean", "function"], + description: "Trust the input, enabling all HTML features such as \\url.", + cli: "-T, --trust" + }, + maxSize: { + type: "number", + default: Infinity, + description: "If non-zero, all user-specified sizes, e.g. in " + "\\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, " + "elements and spaces can be arbitrarily large", + processor: s => Math.max(0, s), + cli: "-s, --max-size ", + cliProcessor: parseInt + }, + maxExpand: { + type: "number", + default: 1000, + description: "Limit the number of macro expansions to the specified " + "number, to prevent e.g. infinite macro loops. If set to Infinity, " + "the macro expander will try to fully expand as in LaTeX.", + processor: n => Math.max(0, n), + cli: "-e, --max-expand ", + cliProcessor: n => n === "Infinity" ? Infinity : parseInt(n) + }, + globalGroup: { + type: "boolean", + cli: false + } +}; + +function getDefaultValue(schema) { + if (schema.default) { + return schema.default; + } + + var type = schema.type; + var defaultType = Array.isArray(type) ? type[0] : type; + + if (typeof defaultType !== 'string') { + return defaultType.enum[0]; + } + + switch (defaultType) { + case 'boolean': + return false; + + case 'string': + return ''; + + case 'number': + return 0; + + case 'object': + return {}; + } +} +/** + * The main Settings object + * + * The current options stored are: + * - displayMode: Whether the expression should be typeset as inline math + * (false, the default), meaning that the math starts in + * \textstyle and is placed in an inline-block); or as display + * math (true), meaning that the math starts in \displaystyle + * and is placed in a block with vertical margin. + */ + + +class Settings { + constructor(options) { + this.displayMode = void 0; + this.output = void 0; + this.leqno = void 0; + this.fleqn = void 0; + this.throwOnError = void 0; + this.errorColor = void 0; + this.macros = void 0; + this.minRuleThickness = void 0; + this.colorIsTextColor = void 0; + this.strict = void 0; + this.trust = void 0; + this.maxSize = void 0; + this.maxExpand = void 0; + this.globalGroup = void 0; + // allow null options + options = options || {}; + + for (var prop in SETTINGS_SCHEMA) { + if (SETTINGS_SCHEMA.hasOwnProperty(prop)) { + // $FlowFixMe + var schema = SETTINGS_SCHEMA[prop]; // TODO: validate options + // $FlowFixMe + + this[prop] = options[prop] !== undefined ? schema.processor ? schema.processor(options[prop]) : options[prop] : getDefaultValue(schema); + } + } + } + /** + * Report nonstrict (non-LaTeX-compatible) input. + * Can safely not be called if `this.strict` is false in JavaScript. + */ + + + reportNonstrict(errorCode, errorMsg, token) { + var strict = this.strict; + + if (typeof strict === "function") { + // Allow return value of strict function to be boolean or string + // (or null/undefined, meaning no further processing). + strict = strict(errorCode, errorMsg, token); + } + + if (!strict || strict === "ignore") { + return; + } else if (strict === true || strict === "error") { + throw new ParseError("LaTeX-incompatible input and strict mode is set to 'error': " + (errorMsg + " [" + errorCode + "]"), token); + } else if (strict === "warn") { + typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + (errorMsg + " [" + errorCode + "]")); + } else { + // won't happen in type-safe code + typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to " + ("unrecognized '" + strict + "': " + errorMsg + " [" + errorCode + "]")); + } + } + /** + * Check whether to apply strict (LaTeX-adhering) behavior for unusual + * input (like `\\`). Unlike `nonstrict`, will not throw an error; + * instead, "error" translates to a return value of `true`, while "ignore" + * translates to a return value of `false`. May still print a warning: + * "warn" prints a warning and returns `false`. + * This is for the second category of `errorCode`s listed in the README. + */ + + + useStrictBehavior(errorCode, errorMsg, token) { + var strict = this.strict; + + if (typeof strict === "function") { + // Allow return value of strict function to be boolean or string + // (or null/undefined, meaning no further processing). + // But catch any exceptions thrown by function, treating them + // like "error". + try { + strict = strict(errorCode, errorMsg, token); + } catch (error) { + strict = "error"; + } + } + + if (!strict || strict === "ignore") { + return false; + } else if (strict === true || strict === "error") { + return true; + } else if (strict === "warn") { + typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + (errorMsg + " [" + errorCode + "]")); + return false; + } else { + // won't happen in type-safe code + typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to " + ("unrecognized '" + strict + "': " + errorMsg + " [" + errorCode + "]")); + return false; + } + } + /** + * Check whether to test potentially dangerous input, and return + * `true` (trusted) or `false` (untrusted). The sole argument `context` + * should be an object with `command` field specifying the relevant LaTeX + * command (as a string starting with `\`), and any other arguments, etc. + * If `context` has a `url` field, a `protocol` field will automatically + * get added by this function (changing the specified object). + */ + + + isTrusted(context) { + if (context.url && !context.protocol) { + var protocol = utils.protocolFromUrl(context.url); + + if (protocol == null) { + return false; + } + + context.protocol = protocol; + } + + var trust = typeof this.trust === "function" ? this.trust(context) : this.trust; + return Boolean(trust); + } + +} + +/** + * This file contains information and classes for the various kinds of styles + * used in TeX. It provides a generic `Style` class, which holds information + * about a specific style. It then provides instances of all the different kinds + * of styles possible, and provides functions to move between them and get + * information about them. + */ + +/** + * The main style class. Contains a unique id for the style, a size (which is + * the same for cramped and uncramped version of a style), and a cramped flag. + */ +class Style { + constructor(id, size, cramped) { + this.id = void 0; + this.size = void 0; + this.cramped = void 0; + this.id = id; + this.size = size; + this.cramped = cramped; + } + /** + * Get the style of a superscript given a base in the current style. + */ + + + sup() { + return styles[sup[this.id]]; + } + /** + * Get the style of a subscript given a base in the current style. + */ + + + sub() { + return styles[sub[this.id]]; + } + /** + * Get the style of a fraction numerator given the fraction in the current + * style. + */ + + + fracNum() { + return styles[fracNum[this.id]]; + } + /** + * Get the style of a fraction denominator given the fraction in the current + * style. + */ + + + fracDen() { + return styles[fracDen[this.id]]; + } + /** + * Get the cramped version of a style (in particular, cramping a cramped style + * doesn't change the style). + */ + + + cramp() { + return styles[cramp[this.id]]; + } + /** + * Get a text or display version of this style. + */ + + + text() { + return styles[text$1[this.id]]; + } + /** + * Return true if this style is tightly spaced (scriptstyle/scriptscriptstyle) + */ + + + isTight() { + return this.size >= 2; + } + +} // Export an interface for type checking, but don't expose the implementation. +// This way, no more styles can be generated. + + +// IDs of the different styles +var D = 0; +var Dc = 1; +var T = 2; +var Tc = 3; +var S = 4; +var Sc = 5; +var SS = 6; +var SSc = 7; // Instances of the different styles + +var styles = [new Style(D, 0, false), new Style(Dc, 0, true), new Style(T, 1, false), new Style(Tc, 1, true), new Style(S, 2, false), new Style(Sc, 2, true), new Style(SS, 3, false), new Style(SSc, 3, true)]; // Lookup tables for switching from one style to another + +var sup = [S, Sc, S, Sc, SS, SSc, SS, SSc]; +var sub = [Sc, Sc, Sc, Sc, SSc, SSc, SSc, SSc]; +var fracNum = [T, Tc, S, Sc, SS, SSc, SS, SSc]; +var fracDen = [Tc, Tc, Sc, Sc, SSc, SSc, SSc, SSc]; +var cramp = [Dc, Dc, Tc, Tc, Sc, Sc, SSc, SSc]; +var text$1 = [D, Dc, T, Tc, T, Tc, T, Tc]; // We only export some of the styles. + +var Style$1 = { + DISPLAY: styles[D], + TEXT: styles[T], + SCRIPT: styles[S], + SCRIPTSCRIPT: styles[SS] +}; + +/* + * This file defines the Unicode scripts and script families that we + * support. To add new scripts or families, just add a new entry to the + * scriptData array below. Adding scripts to the scriptData array allows + * characters from that script to appear in \text{} environments. + */ + +/** + * Each script or script family has a name and an array of blocks. + * Each block is an array of two numbers which specify the start and + * end points (inclusive) of a block of Unicode codepoints. + */ + +/** + * Unicode block data for the families of scripts we support in \text{}. + * Scripts only need to appear here if they do not have font metrics. + */ +var scriptData = [{ + // Latin characters beyond the Latin-1 characters we have metrics for. + // Needed for Czech, Hungarian and Turkish text, for example. + name: 'latin', + blocks: [[0x0100, 0x024f], // Latin Extended-A and Latin Extended-B + [0x0300, 0x036f] // Combining Diacritical marks + ] +}, { + // The Cyrillic script used by Russian and related languages. + // A Cyrillic subset used to be supported as explicitly defined + // symbols in symbols.js + name: 'cyrillic', + blocks: [[0x0400, 0x04ff]] +}, { + // Armenian + name: 'armenian', + blocks: [[0x0530, 0x058F]] +}, { + // The Brahmic scripts of South and Southeast Asia + // Devanagari (0900–097F) + // Bengali (0980–09FF) + // Gurmukhi (0A00–0A7F) + // Gujarati (0A80–0AFF) + // Oriya (0B00–0B7F) + // Tamil (0B80–0BFF) + // Telugu (0C00–0C7F) + // Kannada (0C80–0CFF) + // Malayalam (0D00–0D7F) + // Sinhala (0D80–0DFF) + // Thai (0E00–0E7F) + // Lao (0E80–0EFF) + // Tibetan (0F00–0FFF) + // Myanmar (1000–109F) + name: 'brahmic', + blocks: [[0x0900, 0x109F]] +}, { + name: 'georgian', + blocks: [[0x10A0, 0x10ff]] +}, { + // Chinese and Japanese. + // The "k" in cjk is for Korean, but we've separated Korean out + name: "cjk", + blocks: [[0x3000, 0x30FF], // CJK symbols and punctuation, Hiragana, Katakana + [0x4E00, 0x9FAF], // CJK ideograms + [0xFF00, 0xFF60] // Fullwidth punctuation + // TODO: add halfwidth Katakana and Romanji glyphs + ] +}, { + // Korean + name: 'hangul', + blocks: [[0xAC00, 0xD7AF]] +}]; +/** + * Given a codepoint, return the name of the script or script family + * it is from, or null if it is not part of a known block + */ + +function scriptFromCodepoint(codepoint) { + for (var i = 0; i < scriptData.length; i++) { + var script = scriptData[i]; + + for (var _i = 0; _i < script.blocks.length; _i++) { + var block = script.blocks[_i]; + + if (codepoint >= block[0] && codepoint <= block[1]) { + return script.name; + } + } + } + + return null; +} +/** + * A flattened version of all the supported blocks in a single array. + * This is an optimization to make supportedCodepoint() fast. + */ + +var allBlocks = []; +scriptData.forEach(s => s.blocks.forEach(b => allBlocks.push(...b))); +/** + * Given a codepoint, return true if it falls within one of the + * scripts or script families defined above and false otherwise. + * + * Micro benchmarks shows that this is faster than + * /[\u3000-\u30FF\u4E00-\u9FAF\uFF00-\uFF60\uAC00-\uD7AF\u0900-\u109F]/.test() + * in Firefox, Chrome and Node. + */ + +function supportedCodepoint(codepoint) { + for (var i = 0; i < allBlocks.length; i += 2) { + if (codepoint >= allBlocks[i] && codepoint <= allBlocks[i + 1]) { + return true; + } + } + + return false; +} + +/** + * This file provides support to domTree.js and delimiter.js. + * It's a storehouse of path geometry for SVG images. + */ +// In all paths below, the viewBox-to-em scale is 1000:1. +var hLinePad = 80; // padding above a sqrt vinculum. Prevents image cropping. +// The vinculum of a \sqrt can be made thicker by a KaTeX rendering option. +// Think of variable extraVinculum as two detours in the SVG path. +// The detour begins at the lower left of the area labeled extraVinculum below. +// The detour proceeds one extraVinculum distance up and slightly to the right, +// displacing the radiused corner between surd and vinculum. The radius is +// traversed as usual, then the detour resumes. It goes right, to the end of +// the very long vinculum, then down one extraVinculum distance, +// after which it resumes regular path geometry for the radical. + +/* vinculum + / + /▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒←extraVinculum + / █████████████████████←0.04em (40 unit) std vinculum thickness + / / + / / + / /\ + / / surd +*/ + +var sqrtMain = function sqrtMain(extraVinculum, hLinePad) { + // sqrtMain path geometry is from glyph U221A in the font KaTeX Main + return "M95," + (622 + extraVinculum + hLinePad) + "\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl" + extraVinculum / 2.075 + " -" + extraVinculum + "\nc5.3,-9.3,12,-14,20,-14\nH400000v" + (40 + extraVinculum) + "H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM" + (834 + extraVinculum) + " " + hLinePad + "h400000v" + (40 + extraVinculum) + "h-400000z"; +}; + +var sqrtSize1 = function sqrtSize1(extraVinculum, hLinePad) { + // size1 is from glyph U221A in the font KaTeX_Size1-Regular + return "M263," + (601 + extraVinculum + hLinePad) + "c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl" + extraVinculum / 2.084 + " -" + extraVinculum + "\nc4.7,-7.3,11,-11,19,-11\nH40000v" + (40 + extraVinculum) + "H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM" + (1001 + extraVinculum) + " " + hLinePad + "h400000v" + (40 + extraVinculum) + "h-400000z"; +}; + +var sqrtSize2 = function sqrtSize2(extraVinculum, hLinePad) { + // size2 is from glyph U221A in the font KaTeX_Size2-Regular + return "M983 " + (10 + extraVinculum + hLinePad) + "\nl" + extraVinculum / 3.13 + " -" + extraVinculum + "\nc4,-6.7,10,-10,18,-10 H400000v" + (40 + extraVinculum) + "\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM" + (1001 + extraVinculum) + " " + hLinePad + "h400000v" + (40 + extraVinculum) + "h-400000z"; +}; + +var sqrtSize3 = function sqrtSize3(extraVinculum, hLinePad) { + // size3 is from glyph U221A in the font KaTeX_Size3-Regular + return "M424," + (2398 + extraVinculum + hLinePad) + "\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl" + extraVinculum / 4.223 + " -" + extraVinculum + "c4,-6.7,10,-10,18,-10 H400000\nv" + (40 + extraVinculum) + "H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M" + (1001 + extraVinculum) + " " + hLinePad + "\nh400000v" + (40 + extraVinculum) + "h-400000z"; +}; + +var sqrtSize4 = function sqrtSize4(extraVinculum, hLinePad) { + // size4 is from glyph U221A in the font KaTeX_Size4-Regular + return "M473," + (2713 + extraVinculum + hLinePad) + "\nc339.3,-1799.3,509.3,-2700,510,-2702 l" + extraVinculum / 5.298 + " -" + extraVinculum + "\nc3.3,-7.3,9.3,-11,18,-11 H400000v" + (40 + extraVinculum) + "H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM" + (1001 + extraVinculum) + " " + hLinePad + "h400000v" + (40 + extraVinculum) + "H1017.7z"; +}; + +var phasePath = function phasePath(y) { + var x = y / 2; // x coordinate at top of angle + + return "M400000 " + y + " H0 L" + x + " 0 l65 45 L145 " + (y - 80) + " H400000z"; +}; + +var sqrtTall = function sqrtTall(extraVinculum, hLinePad, viewBoxHeight) { + // sqrtTall is from glyph U23B7 in the font KaTeX_Size4-Regular + // One path edge has a variable length. It runs vertically from the vinculum + // to a point near (14 units) the bottom of the surd. The vinculum + // is normally 40 units thick. So the length of the line in question is: + var vertSegment = viewBoxHeight - 54 - hLinePad - extraVinculum; + return "M702 " + (extraVinculum + hLinePad) + "H400000" + (40 + extraVinculum) + "\nH742v" + vertSegment + "l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 " + hLinePad + "H400000v" + (40 + extraVinculum) + "H742z"; +}; + +var sqrtPath = function sqrtPath(size, extraVinculum, viewBoxHeight) { + extraVinculum = 1000 * extraVinculum; // Convert from document ems to viewBox. + + var path = ""; + + switch (size) { + case "sqrtMain": + path = sqrtMain(extraVinculum, hLinePad); + break; + + case "sqrtSize1": + path = sqrtSize1(extraVinculum, hLinePad); + break; + + case "sqrtSize2": + path = sqrtSize2(extraVinculum, hLinePad); + break; + + case "sqrtSize3": + path = sqrtSize3(extraVinculum, hLinePad); + break; + + case "sqrtSize4": + path = sqrtSize4(extraVinculum, hLinePad); + break; + + case "sqrtTall": + path = sqrtTall(extraVinculum, hLinePad, viewBoxHeight); + } + + return path; +}; +var innerPath = function innerPath(name, height) { + // The inner part of stretchy tall delimiters + switch (name) { + case "\u239c": + return "M291 0 H417 V" + height + " H291z M291 0 H417 V" + height + " H291z"; + + case "\u2223": + return "M145 0 H188 V" + height + " H145z M145 0 H188 V" + height + " H145z"; + + case "\u2225": + return "M145 0 H188 V" + height + " H145z M145 0 H188 V" + height + " H145z" + ("M367 0 H410 V" + height + " H367z M367 0 H410 V" + height + " H367z"); + + case "\u239f": + return "M457 0 H583 V" + height + " H457z M457 0 H583 V" + height + " H457z"; + + case "\u23a2": + return "M319 0 H403 V" + height + " H319z M319 0 H403 V" + height + " H319z"; + + case "\u23a5": + return "M263 0 H347 V" + height + " H263z M263 0 H347 V" + height + " H263z"; + + case "\u23aa": + return "M384 0 H504 V" + height + " H384z M384 0 H504 V" + height + " H384z"; + + case "\u23d0": + return "M312 0 H355 V" + height + " H312z M312 0 H355 V" + height + " H312z"; + + case "\u2016": + return "M257 0 H300 V" + height + " H257z M257 0 H300 V" + height + " H257z" + ("M478 0 H521 V" + height + " H478z M478 0 H521 V" + height + " H478z"); + + default: + return ""; + } +}; +var path = { + // The doubleleftarrow geometry is from glyph U+21D0 in the font KaTeX Main + doubleleftarrow: "M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z", + // doublerightarrow is from glyph U+21D2 in font KaTeX Main + doublerightarrow: "M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z", + // leftarrow is from glyph U+2190 in font KaTeX Main + leftarrow: "M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z", + // overbrace is from glyphs U+23A9/23A8/23A7 in font KaTeX_Size4-Regular + leftbrace: "M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z", + leftbraceunder: "M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z", + // overgroup is from the MnSymbol package (public domain) + leftgroup: "M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z", + leftgroupunder: "M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z", + // Harpoons are from glyph U+21BD in font KaTeX Main + leftharpoon: "M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z", + leftharpoonplus: "M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z", + leftharpoondown: "M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z", + leftharpoondownplus: "M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z", + // hook is from glyph U+21A9 in font KaTeX Main + lefthook: "M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z", + leftlinesegment: "M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z", + leftmapsto: "M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z", + // tofrom is from glyph U+21C4 in font KaTeX AMS Regular + leftToFrom: "M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z", + longequal: "M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z", + midbrace: "M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z", + midbraceunder: "M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z", + oiintSize1: "M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z", + oiintSize2: "M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z", + oiiintSize1: "M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z", + oiiintSize2: "M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z", + rightarrow: "M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z", + rightbrace: "M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z", + rightbraceunder: "M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z", + rightgroup: "M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z", + rightgroupunder: "M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z", + rightharpoon: "M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z", + rightharpoonplus: "M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z", + rightharpoondown: "M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z", + rightharpoondownplus: "M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z", + righthook: "M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z", + rightlinesegment: "M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z", + rightToFrom: "M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z", + // twoheadleftarrow is from glyph U+219E in font KaTeX AMS Regular + twoheadleftarrow: "M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z", + twoheadrightarrow: "M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z", + // tilde1 is a modified version of a glyph from the MnSymbol package + tilde1: "M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z", + // ditto tilde2, tilde3, & tilde4 + tilde2: "M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z", + tilde3: "M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z", + tilde4: "M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z", + // vec is from glyph U+20D7 in font KaTeX Main + vec: "M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z", + // widehat1 is a modified version of a glyph from the MnSymbol package + widehat1: "M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z", + // ditto widehat2, widehat3, & widehat4 + widehat2: "M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z", + widehat3: "M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z", + widehat4: "M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z", + // widecheck paths are all inverted versions of widehat + widecheck1: "M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z", + widecheck2: "M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z", + widecheck3: "M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z", + widecheck4: "M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z", + // The next ten paths support reaction arrows from the mhchem package. + // Arrows for \ce{<-->} are offset from xAxis by 0.22ex, per mhchem in LaTeX + // baraboveleftarrow is mostly from glyph U+2190 in font KaTeX Main + baraboveleftarrow: "M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z", + // rightarrowabovebar is mostly from glyph U+2192, KaTeX Main + rightarrowabovebar: "M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z", + // The short left harpoon has 0.5em (i.e. 500 units) kern on the left end. + // Ref from mhchem.sty: \rlap{\raisebox{-.22ex}{$\kern0.5em + baraboveshortleftharpoon: "M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z", + rightharpoonaboveshortbar: "M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z", + shortbaraboveleftharpoon: "M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z", + shortrightharpoonabovebar: "M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z" +}; +var tallDelim = function tallDelim(label, midHeight) { + switch (label) { + case "lbrack": + return "M403 1759 V84 H666 V0 H319 V1759 v" + midHeight + " v1759 h347 v-84\nH403z M403 1759 V0 H319 V1759 v" + midHeight + " v1759 h84z"; + + case "rbrack": + return "M347 1759 V0 H0 V84 H263 V1759 v" + midHeight + " v1759 H0 v84 H347z\nM347 1759 V0 H263 V1759 v" + midHeight + " v1759 h84z"; + + case "vert": + return "M145 15 v585 v" + midHeight + " v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v" + -midHeight + " v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v" + midHeight + " v585 h43z"; + + case "doublevert": + return "M145 15 v585 v" + midHeight + " v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v" + -midHeight + " v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v" + midHeight + " v585 h43z\nM367 15 v585 v" + midHeight + " v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v" + -midHeight + " v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M410 15 H367 v585 v" + midHeight + " v585 h43z"; + + case "lfloor": + return "M319 602 V0 H403 V602 v" + midHeight + " v1715 h263 v84 H319z\nMM319 602 V0 H403 V602 v" + midHeight + " v1715 H319z"; + + case "rfloor": + return "M319 602 V0 H403 V602 v" + midHeight + " v1799 H0 v-84 H319z\nMM319 602 V0 H403 V602 v" + midHeight + " v1715 H319z"; + + case "lceil": + return "M403 1759 V84 H666 V0 H319 V1759 v" + midHeight + " v602 h84z\nM403 1759 V0 H319 V1759 v" + midHeight + " v602 h84z"; + + case "rceil": + return "M347 1759 V0 H0 V84 H263 V1759 v" + midHeight + " v602 h84z\nM347 1759 V0 h-84 V1759 v" + midHeight + " v602 h84z"; + + case "lparen": + return "M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1\nc-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349,\n-36,557 l0," + (midHeight + 84) + "c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210,\n949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9\nc0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5,\n-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189\nl0,-" + (midHeight + 92) + "c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3,\n-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z"; + + case "rparen": + return "M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3,\n63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5\nc11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0," + (midHeight + 9) + "\nc-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664\nc-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11\nc0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17\nc242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558\nl0,-" + (midHeight + 144) + "c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,\n-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z"; + + default: + // We should not ever get here. + throw new Error("Unknown stretchy delimiter."); + } +}; + +/** + * This node represents a document fragment, which contains elements, but when + * placed into the DOM doesn't have any representation itself. It only contains + * children and doesn't have any DOM node properties. + */ +class DocumentFragment { + // HtmlDomNode + // Never used; needed for satisfying interface. + constructor(children) { + this.children = void 0; + this.classes = void 0; + this.height = void 0; + this.depth = void 0; + this.maxFontSize = void 0; + this.style = void 0; + this.children = children; + this.classes = []; + this.height = 0; + this.depth = 0; + this.maxFontSize = 0; + this.style = {}; + } + + hasClass(className) { + return utils.contains(this.classes, className); + } + /** Convert the fragment into a node. */ + + + toNode() { + var frag = document.createDocumentFragment(); + + for (var i = 0; i < this.children.length; i++) { + frag.appendChild(this.children[i].toNode()); + } + + return frag; + } + /** Convert the fragment into HTML markup. */ + + + toMarkup() { + var markup = ""; // Simply concatenate the markup for the children together. + + for (var i = 0; i < this.children.length; i++) { + markup += this.children[i].toMarkup(); + } + + return markup; + } + /** + * Converts the math node into a string, similar to innerText. Applies to + * MathDomNode's only. + */ + + + toText() { + // To avoid this, we would subclass documentFragment separately for + // MathML, but polyfills for subclassing is expensive per PR 1469. + // $FlowFixMe: Only works for ChildType = MathDomNode. + var toText = child => child.toText(); + + return this.children.map(toText).join(""); + } + +} + +// This file is GENERATED by buildMetrics.sh. DO NOT MODIFY. +var fontMetricsData = { + "AMS-Regular": { + "32": [0, 0, 0, 0, 0.25], + "65": [0, 0.68889, 0, 0, 0.72222], + "66": [0, 0.68889, 0, 0, 0.66667], + "67": [0, 0.68889, 0, 0, 0.72222], + "68": [0, 0.68889, 0, 0, 0.72222], + "69": [0, 0.68889, 0, 0, 0.66667], + "70": [0, 0.68889, 0, 0, 0.61111], + "71": [0, 0.68889, 0, 0, 0.77778], + "72": [0, 0.68889, 0, 0, 0.77778], + "73": [0, 0.68889, 0, 0, 0.38889], + "74": [0.16667, 0.68889, 0, 0, 0.5], + "75": [0, 0.68889, 0, 0, 0.77778], + "76": [0, 0.68889, 0, 0, 0.66667], + "77": [0, 0.68889, 0, 0, 0.94445], + "78": [0, 0.68889, 0, 0, 0.72222], + "79": [0.16667, 0.68889, 0, 0, 0.77778], + "80": [0, 0.68889, 0, 0, 0.61111], + "81": [0.16667, 0.68889, 0, 0, 0.77778], + "82": [0, 0.68889, 0, 0, 0.72222], + "83": [0, 0.68889, 0, 0, 0.55556], + "84": [0, 0.68889, 0, 0, 0.66667], + "85": [0, 0.68889, 0, 0, 0.72222], + "86": [0, 0.68889, 0, 0, 0.72222], + "87": [0, 0.68889, 0, 0, 1.0], + "88": [0, 0.68889, 0, 0, 0.72222], + "89": [0, 0.68889, 0, 0, 0.72222], + "90": [0, 0.68889, 0, 0, 0.66667], + "107": [0, 0.68889, 0, 0, 0.55556], + "160": [0, 0, 0, 0, 0.25], + "165": [0, 0.675, 0.025, 0, 0.75], + "174": [0.15559, 0.69224, 0, 0, 0.94666], + "240": [0, 0.68889, 0, 0, 0.55556], + "295": [0, 0.68889, 0, 0, 0.54028], + "710": [0, 0.825, 0, 0, 2.33334], + "732": [0, 0.9, 0, 0, 2.33334], + "770": [0, 0.825, 0, 0, 2.33334], + "771": [0, 0.9, 0, 0, 2.33334], + "989": [0.08167, 0.58167, 0, 0, 0.77778], + "1008": [0, 0.43056, 0.04028, 0, 0.66667], + "8245": [0, 0.54986, 0, 0, 0.275], + "8463": [0, 0.68889, 0, 0, 0.54028], + "8487": [0, 0.68889, 0, 0, 0.72222], + "8498": [0, 0.68889, 0, 0, 0.55556], + "8502": [0, 0.68889, 0, 0, 0.66667], + "8503": [0, 0.68889, 0, 0, 0.44445], + "8504": [0, 0.68889, 0, 0, 0.66667], + "8513": [0, 0.68889, 0, 0, 0.63889], + "8592": [-0.03598, 0.46402, 0, 0, 0.5], + "8594": [-0.03598, 0.46402, 0, 0, 0.5], + "8602": [-0.13313, 0.36687, 0, 0, 1.0], + "8603": [-0.13313, 0.36687, 0, 0, 1.0], + "8606": [0.01354, 0.52239, 0, 0, 1.0], + "8608": [0.01354, 0.52239, 0, 0, 1.0], + "8610": [0.01354, 0.52239, 0, 0, 1.11111], + "8611": [0.01354, 0.52239, 0, 0, 1.11111], + "8619": [0, 0.54986, 0, 0, 1.0], + "8620": [0, 0.54986, 0, 0, 1.0], + "8621": [-0.13313, 0.37788, 0, 0, 1.38889], + "8622": [-0.13313, 0.36687, 0, 0, 1.0], + "8624": [0, 0.69224, 0, 0, 0.5], + "8625": [0, 0.69224, 0, 0, 0.5], + "8630": [0, 0.43056, 0, 0, 1.0], + "8631": [0, 0.43056, 0, 0, 1.0], + "8634": [0.08198, 0.58198, 0, 0, 0.77778], + "8635": [0.08198, 0.58198, 0, 0, 0.77778], + "8638": [0.19444, 0.69224, 0, 0, 0.41667], + "8639": [0.19444, 0.69224, 0, 0, 0.41667], + "8642": [0.19444, 0.69224, 0, 0, 0.41667], + "8643": [0.19444, 0.69224, 0, 0, 0.41667], + "8644": [0.1808, 0.675, 0, 0, 1.0], + "8646": [0.1808, 0.675, 0, 0, 1.0], + "8647": [0.1808, 0.675, 0, 0, 1.0], + "8648": [0.19444, 0.69224, 0, 0, 0.83334], + "8649": [0.1808, 0.675, 0, 0, 1.0], + "8650": [0.19444, 0.69224, 0, 0, 0.83334], + "8651": [0.01354, 0.52239, 0, 0, 1.0], + "8652": [0.01354, 0.52239, 0, 0, 1.0], + "8653": [-0.13313, 0.36687, 0, 0, 1.0], + "8654": [-0.13313, 0.36687, 0, 0, 1.0], + "8655": [-0.13313, 0.36687, 0, 0, 1.0], + "8666": [0.13667, 0.63667, 0, 0, 1.0], + "8667": [0.13667, 0.63667, 0, 0, 1.0], + "8669": [-0.13313, 0.37788, 0, 0, 1.0], + "8672": [-0.064, 0.437, 0, 0, 1.334], + "8674": [-0.064, 0.437, 0, 0, 1.334], + "8705": [0, 0.825, 0, 0, 0.5], + "8708": [0, 0.68889, 0, 0, 0.55556], + "8709": [0.08167, 0.58167, 0, 0, 0.77778], + "8717": [0, 0.43056, 0, 0, 0.42917], + "8722": [-0.03598, 0.46402, 0, 0, 0.5], + "8724": [0.08198, 0.69224, 0, 0, 0.77778], + "8726": [0.08167, 0.58167, 0, 0, 0.77778], + "8733": [0, 0.69224, 0, 0, 0.77778], + "8736": [0, 0.69224, 0, 0, 0.72222], + "8737": [0, 0.69224, 0, 0, 0.72222], + "8738": [0.03517, 0.52239, 0, 0, 0.72222], + "8739": [0.08167, 0.58167, 0, 0, 0.22222], + "8740": [0.25142, 0.74111, 0, 0, 0.27778], + "8741": [0.08167, 0.58167, 0, 0, 0.38889], + "8742": [0.25142, 0.74111, 0, 0, 0.5], + "8756": [0, 0.69224, 0, 0, 0.66667], + "8757": [0, 0.69224, 0, 0, 0.66667], + "8764": [-0.13313, 0.36687, 0, 0, 0.77778], + "8765": [-0.13313, 0.37788, 0, 0, 0.77778], + "8769": [-0.13313, 0.36687, 0, 0, 0.77778], + "8770": [-0.03625, 0.46375, 0, 0, 0.77778], + "8774": [0.30274, 0.79383, 0, 0, 0.77778], + "8776": [-0.01688, 0.48312, 0, 0, 0.77778], + "8778": [0.08167, 0.58167, 0, 0, 0.77778], + "8782": [0.06062, 0.54986, 0, 0, 0.77778], + "8783": [0.06062, 0.54986, 0, 0, 0.77778], + "8785": [0.08198, 0.58198, 0, 0, 0.77778], + "8786": [0.08198, 0.58198, 0, 0, 0.77778], + "8787": [0.08198, 0.58198, 0, 0, 0.77778], + "8790": [0, 0.69224, 0, 0, 0.77778], + "8791": [0.22958, 0.72958, 0, 0, 0.77778], + "8796": [0.08198, 0.91667, 0, 0, 0.77778], + "8806": [0.25583, 0.75583, 0, 0, 0.77778], + "8807": [0.25583, 0.75583, 0, 0, 0.77778], + "8808": [0.25142, 0.75726, 0, 0, 0.77778], + "8809": [0.25142, 0.75726, 0, 0, 0.77778], + "8812": [0.25583, 0.75583, 0, 0, 0.5], + "8814": [0.20576, 0.70576, 0, 0, 0.77778], + "8815": [0.20576, 0.70576, 0, 0, 0.77778], + "8816": [0.30274, 0.79383, 0, 0, 0.77778], + "8817": [0.30274, 0.79383, 0, 0, 0.77778], + "8818": [0.22958, 0.72958, 0, 0, 0.77778], + "8819": [0.22958, 0.72958, 0, 0, 0.77778], + "8822": [0.1808, 0.675, 0, 0, 0.77778], + "8823": [0.1808, 0.675, 0, 0, 0.77778], + "8828": [0.13667, 0.63667, 0, 0, 0.77778], + "8829": [0.13667, 0.63667, 0, 0, 0.77778], + "8830": [0.22958, 0.72958, 0, 0, 0.77778], + "8831": [0.22958, 0.72958, 0, 0, 0.77778], + "8832": [0.20576, 0.70576, 0, 0, 0.77778], + "8833": [0.20576, 0.70576, 0, 0, 0.77778], + "8840": [0.30274, 0.79383, 0, 0, 0.77778], + "8841": [0.30274, 0.79383, 0, 0, 0.77778], + "8842": [0.13597, 0.63597, 0, 0, 0.77778], + "8843": [0.13597, 0.63597, 0, 0, 0.77778], + "8847": [0.03517, 0.54986, 0, 0, 0.77778], + "8848": [0.03517, 0.54986, 0, 0, 0.77778], + "8858": [0.08198, 0.58198, 0, 0, 0.77778], + "8859": [0.08198, 0.58198, 0, 0, 0.77778], + "8861": [0.08198, 0.58198, 0, 0, 0.77778], + "8862": [0, 0.675, 0, 0, 0.77778], + "8863": [0, 0.675, 0, 0, 0.77778], + "8864": [0, 0.675, 0, 0, 0.77778], + "8865": [0, 0.675, 0, 0, 0.77778], + "8872": [0, 0.69224, 0, 0, 0.61111], + "8873": [0, 0.69224, 0, 0, 0.72222], + "8874": [0, 0.69224, 0, 0, 0.88889], + "8876": [0, 0.68889, 0, 0, 0.61111], + "8877": [0, 0.68889, 0, 0, 0.61111], + "8878": [0, 0.68889, 0, 0, 0.72222], + "8879": [0, 0.68889, 0, 0, 0.72222], + "8882": [0.03517, 0.54986, 0, 0, 0.77778], + "8883": [0.03517, 0.54986, 0, 0, 0.77778], + "8884": [0.13667, 0.63667, 0, 0, 0.77778], + "8885": [0.13667, 0.63667, 0, 0, 0.77778], + "8888": [0, 0.54986, 0, 0, 1.11111], + "8890": [0.19444, 0.43056, 0, 0, 0.55556], + "8891": [0.19444, 0.69224, 0, 0, 0.61111], + "8892": [0.19444, 0.69224, 0, 0, 0.61111], + "8901": [0, 0.54986, 0, 0, 0.27778], + "8903": [0.08167, 0.58167, 0, 0, 0.77778], + "8905": [0.08167, 0.58167, 0, 0, 0.77778], + "8906": [0.08167, 0.58167, 0, 0, 0.77778], + "8907": [0, 0.69224, 0, 0, 0.77778], + "8908": [0, 0.69224, 0, 0, 0.77778], + "8909": [-0.03598, 0.46402, 0, 0, 0.77778], + "8910": [0, 0.54986, 0, 0, 0.76042], + "8911": [0, 0.54986, 0, 0, 0.76042], + "8912": [0.03517, 0.54986, 0, 0, 0.77778], + "8913": [0.03517, 0.54986, 0, 0, 0.77778], + "8914": [0, 0.54986, 0, 0, 0.66667], + "8915": [0, 0.54986, 0, 0, 0.66667], + "8916": [0, 0.69224, 0, 0, 0.66667], + "8918": [0.0391, 0.5391, 0, 0, 0.77778], + "8919": [0.0391, 0.5391, 0, 0, 0.77778], + "8920": [0.03517, 0.54986, 0, 0, 1.33334], + "8921": [0.03517, 0.54986, 0, 0, 1.33334], + "8922": [0.38569, 0.88569, 0, 0, 0.77778], + "8923": [0.38569, 0.88569, 0, 0, 0.77778], + "8926": [0.13667, 0.63667, 0, 0, 0.77778], + "8927": [0.13667, 0.63667, 0, 0, 0.77778], + "8928": [0.30274, 0.79383, 0, 0, 0.77778], + "8929": [0.30274, 0.79383, 0, 0, 0.77778], + "8934": [0.23222, 0.74111, 0, 0, 0.77778], + "8935": [0.23222, 0.74111, 0, 0, 0.77778], + "8936": [0.23222, 0.74111, 0, 0, 0.77778], + "8937": [0.23222, 0.74111, 0, 0, 0.77778], + "8938": [0.20576, 0.70576, 0, 0, 0.77778], + "8939": [0.20576, 0.70576, 0, 0, 0.77778], + "8940": [0.30274, 0.79383, 0, 0, 0.77778], + "8941": [0.30274, 0.79383, 0, 0, 0.77778], + "8994": [0.19444, 0.69224, 0, 0, 0.77778], + "8995": [0.19444, 0.69224, 0, 0, 0.77778], + "9416": [0.15559, 0.69224, 0, 0, 0.90222], + "9484": [0, 0.69224, 0, 0, 0.5], + "9488": [0, 0.69224, 0, 0, 0.5], + "9492": [0, 0.37788, 0, 0, 0.5], + "9496": [0, 0.37788, 0, 0, 0.5], + "9585": [0.19444, 0.68889, 0, 0, 0.88889], + "9586": [0.19444, 0.74111, 0, 0, 0.88889], + "9632": [0, 0.675, 0, 0, 0.77778], + "9633": [0, 0.675, 0, 0, 0.77778], + "9650": [0, 0.54986, 0, 0, 0.72222], + "9651": [0, 0.54986, 0, 0, 0.72222], + "9654": [0.03517, 0.54986, 0, 0, 0.77778], + "9660": [0, 0.54986, 0, 0, 0.72222], + "9661": [0, 0.54986, 0, 0, 0.72222], + "9664": [0.03517, 0.54986, 0, 0, 0.77778], + "9674": [0.11111, 0.69224, 0, 0, 0.66667], + "9733": [0.19444, 0.69224, 0, 0, 0.94445], + "10003": [0, 0.69224, 0, 0, 0.83334], + "10016": [0, 0.69224, 0, 0, 0.83334], + "10731": [0.11111, 0.69224, 0, 0, 0.66667], + "10846": [0.19444, 0.75583, 0, 0, 0.61111], + "10877": [0.13667, 0.63667, 0, 0, 0.77778], + "10878": [0.13667, 0.63667, 0, 0, 0.77778], + "10885": [0.25583, 0.75583, 0, 0, 0.77778], + "10886": [0.25583, 0.75583, 0, 0, 0.77778], + "10887": [0.13597, 0.63597, 0, 0, 0.77778], + "10888": [0.13597, 0.63597, 0, 0, 0.77778], + "10889": [0.26167, 0.75726, 0, 0, 0.77778], + "10890": [0.26167, 0.75726, 0, 0, 0.77778], + "10891": [0.48256, 0.98256, 0, 0, 0.77778], + "10892": [0.48256, 0.98256, 0, 0, 0.77778], + "10901": [0.13667, 0.63667, 0, 0, 0.77778], + "10902": [0.13667, 0.63667, 0, 0, 0.77778], + "10933": [0.25142, 0.75726, 0, 0, 0.77778], + "10934": [0.25142, 0.75726, 0, 0, 0.77778], + "10935": [0.26167, 0.75726, 0, 0, 0.77778], + "10936": [0.26167, 0.75726, 0, 0, 0.77778], + "10937": [0.26167, 0.75726, 0, 0, 0.77778], + "10938": [0.26167, 0.75726, 0, 0, 0.77778], + "10949": [0.25583, 0.75583, 0, 0, 0.77778], + "10950": [0.25583, 0.75583, 0, 0, 0.77778], + "10955": [0.28481, 0.79383, 0, 0, 0.77778], + "10956": [0.28481, 0.79383, 0, 0, 0.77778], + "57350": [0.08167, 0.58167, 0, 0, 0.22222], + "57351": [0.08167, 0.58167, 0, 0, 0.38889], + "57352": [0.08167, 0.58167, 0, 0, 0.77778], + "57353": [0, 0.43056, 0.04028, 0, 0.66667], + "57356": [0.25142, 0.75726, 0, 0, 0.77778], + "57357": [0.25142, 0.75726, 0, 0, 0.77778], + "57358": [0.41951, 0.91951, 0, 0, 0.77778], + "57359": [0.30274, 0.79383, 0, 0, 0.77778], + "57360": [0.30274, 0.79383, 0, 0, 0.77778], + "57361": [0.41951, 0.91951, 0, 0, 0.77778], + "57366": [0.25142, 0.75726, 0, 0, 0.77778], + "57367": [0.25142, 0.75726, 0, 0, 0.77778], + "57368": [0.25142, 0.75726, 0, 0, 0.77778], + "57369": [0.25142, 0.75726, 0, 0, 0.77778], + "57370": [0.13597, 0.63597, 0, 0, 0.77778], + "57371": [0.13597, 0.63597, 0, 0, 0.77778] + }, + "Caligraphic-Regular": { + "32": [0, 0, 0, 0, 0.25], + "65": [0, 0.68333, 0, 0.19445, 0.79847], + "66": [0, 0.68333, 0.03041, 0.13889, 0.65681], + "67": [0, 0.68333, 0.05834, 0.13889, 0.52653], + "68": [0, 0.68333, 0.02778, 0.08334, 0.77139], + "69": [0, 0.68333, 0.08944, 0.11111, 0.52778], + "70": [0, 0.68333, 0.09931, 0.11111, 0.71875], + "71": [0.09722, 0.68333, 0.0593, 0.11111, 0.59487], + "72": [0, 0.68333, 0.00965, 0.11111, 0.84452], + "73": [0, 0.68333, 0.07382, 0, 0.54452], + "74": [0.09722, 0.68333, 0.18472, 0.16667, 0.67778], + "75": [0, 0.68333, 0.01445, 0.05556, 0.76195], + "76": [0, 0.68333, 0, 0.13889, 0.68972], + "77": [0, 0.68333, 0, 0.13889, 1.2009], + "78": [0, 0.68333, 0.14736, 0.08334, 0.82049], + "79": [0, 0.68333, 0.02778, 0.11111, 0.79611], + "80": [0, 0.68333, 0.08222, 0.08334, 0.69556], + "81": [0.09722, 0.68333, 0, 0.11111, 0.81667], + "82": [0, 0.68333, 0, 0.08334, 0.8475], + "83": [0, 0.68333, 0.075, 0.13889, 0.60556], + "84": [0, 0.68333, 0.25417, 0, 0.54464], + "85": [0, 0.68333, 0.09931, 0.08334, 0.62583], + "86": [0, 0.68333, 0.08222, 0, 0.61278], + "87": [0, 0.68333, 0.08222, 0.08334, 0.98778], + "88": [0, 0.68333, 0.14643, 0.13889, 0.7133], + "89": [0.09722, 0.68333, 0.08222, 0.08334, 0.66834], + "90": [0, 0.68333, 0.07944, 0.13889, 0.72473], + "160": [0, 0, 0, 0, 0.25] + }, + "Fraktur-Regular": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69141, 0, 0, 0.29574], + "34": [0, 0.69141, 0, 0, 0.21471], + "38": [0, 0.69141, 0, 0, 0.73786], + "39": [0, 0.69141, 0, 0, 0.21201], + "40": [0.24982, 0.74947, 0, 0, 0.38865], + "41": [0.24982, 0.74947, 0, 0, 0.38865], + "42": [0, 0.62119, 0, 0, 0.27764], + "43": [0.08319, 0.58283, 0, 0, 0.75623], + "44": [0, 0.10803, 0, 0, 0.27764], + "45": [0.08319, 0.58283, 0, 0, 0.75623], + "46": [0, 0.10803, 0, 0, 0.27764], + "47": [0.24982, 0.74947, 0, 0, 0.50181], + "48": [0, 0.47534, 0, 0, 0.50181], + "49": [0, 0.47534, 0, 0, 0.50181], + "50": [0, 0.47534, 0, 0, 0.50181], + "51": [0.18906, 0.47534, 0, 0, 0.50181], + "52": [0.18906, 0.47534, 0, 0, 0.50181], + "53": [0.18906, 0.47534, 0, 0, 0.50181], + "54": [0, 0.69141, 0, 0, 0.50181], + "55": [0.18906, 0.47534, 0, 0, 0.50181], + "56": [0, 0.69141, 0, 0, 0.50181], + "57": [0.18906, 0.47534, 0, 0, 0.50181], + "58": [0, 0.47534, 0, 0, 0.21606], + "59": [0.12604, 0.47534, 0, 0, 0.21606], + "61": [-0.13099, 0.36866, 0, 0, 0.75623], + "63": [0, 0.69141, 0, 0, 0.36245], + "65": [0, 0.69141, 0, 0, 0.7176], + "66": [0, 0.69141, 0, 0, 0.88397], + "67": [0, 0.69141, 0, 0, 0.61254], + "68": [0, 0.69141, 0, 0, 0.83158], + "69": [0, 0.69141, 0, 0, 0.66278], + "70": [0.12604, 0.69141, 0, 0, 0.61119], + "71": [0, 0.69141, 0, 0, 0.78539], + "72": [0.06302, 0.69141, 0, 0, 0.7203], + "73": [0, 0.69141, 0, 0, 0.55448], + "74": [0.12604, 0.69141, 0, 0, 0.55231], + "75": [0, 0.69141, 0, 0, 0.66845], + "76": [0, 0.69141, 0, 0, 0.66602], + "77": [0, 0.69141, 0, 0, 1.04953], + "78": [0, 0.69141, 0, 0, 0.83212], + "79": [0, 0.69141, 0, 0, 0.82699], + "80": [0.18906, 0.69141, 0, 0, 0.82753], + "81": [0.03781, 0.69141, 0, 0, 0.82699], + "82": [0, 0.69141, 0, 0, 0.82807], + "83": [0, 0.69141, 0, 0, 0.82861], + "84": [0, 0.69141, 0, 0, 0.66899], + "85": [0, 0.69141, 0, 0, 0.64576], + "86": [0, 0.69141, 0, 0, 0.83131], + "87": [0, 0.69141, 0, 0, 1.04602], + "88": [0, 0.69141, 0, 0, 0.71922], + "89": [0.18906, 0.69141, 0, 0, 0.83293], + "90": [0.12604, 0.69141, 0, 0, 0.60201], + "91": [0.24982, 0.74947, 0, 0, 0.27764], + "93": [0.24982, 0.74947, 0, 0, 0.27764], + "94": [0, 0.69141, 0, 0, 0.49965], + "97": [0, 0.47534, 0, 0, 0.50046], + "98": [0, 0.69141, 0, 0, 0.51315], + "99": [0, 0.47534, 0, 0, 0.38946], + "100": [0, 0.62119, 0, 0, 0.49857], + "101": [0, 0.47534, 0, 0, 0.40053], + "102": [0.18906, 0.69141, 0, 0, 0.32626], + "103": [0.18906, 0.47534, 0, 0, 0.5037], + "104": [0.18906, 0.69141, 0, 0, 0.52126], + "105": [0, 0.69141, 0, 0, 0.27899], + "106": [0, 0.69141, 0, 0, 0.28088], + "107": [0, 0.69141, 0, 0, 0.38946], + "108": [0, 0.69141, 0, 0, 0.27953], + "109": [0, 0.47534, 0, 0, 0.76676], + "110": [0, 0.47534, 0, 0, 0.52666], + "111": [0, 0.47534, 0, 0, 0.48885], + "112": [0.18906, 0.52396, 0, 0, 0.50046], + "113": [0.18906, 0.47534, 0, 0, 0.48912], + "114": [0, 0.47534, 0, 0, 0.38919], + "115": [0, 0.47534, 0, 0, 0.44266], + "116": [0, 0.62119, 0, 0, 0.33301], + "117": [0, 0.47534, 0, 0, 0.5172], + "118": [0, 0.52396, 0, 0, 0.5118], + "119": [0, 0.52396, 0, 0, 0.77351], + "120": [0.18906, 0.47534, 0, 0, 0.38865], + "121": [0.18906, 0.47534, 0, 0, 0.49884], + "122": [0.18906, 0.47534, 0, 0, 0.39054], + "160": [0, 0, 0, 0, 0.25], + "8216": [0, 0.69141, 0, 0, 0.21471], + "8217": [0, 0.69141, 0, 0, 0.21471], + "58112": [0, 0.62119, 0, 0, 0.49749], + "58113": [0, 0.62119, 0, 0, 0.4983], + "58114": [0.18906, 0.69141, 0, 0, 0.33328], + "58115": [0.18906, 0.69141, 0, 0, 0.32923], + "58116": [0.18906, 0.47534, 0, 0, 0.50343], + "58117": [0, 0.69141, 0, 0, 0.33301], + "58118": [0, 0.62119, 0, 0, 0.33409], + "58119": [0, 0.47534, 0, 0, 0.50073] + }, + "Main-Bold": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0, 0, 0.35], + "34": [0, 0.69444, 0, 0, 0.60278], + "35": [0.19444, 0.69444, 0, 0, 0.95833], + "36": [0.05556, 0.75, 0, 0, 0.575], + "37": [0.05556, 0.75, 0, 0, 0.95833], + "38": [0, 0.69444, 0, 0, 0.89444], + "39": [0, 0.69444, 0, 0, 0.31944], + "40": [0.25, 0.75, 0, 0, 0.44722], + "41": [0.25, 0.75, 0, 0, 0.44722], + "42": [0, 0.75, 0, 0, 0.575], + "43": [0.13333, 0.63333, 0, 0, 0.89444], + "44": [0.19444, 0.15556, 0, 0, 0.31944], + "45": [0, 0.44444, 0, 0, 0.38333], + "46": [0, 0.15556, 0, 0, 0.31944], + "47": [0.25, 0.75, 0, 0, 0.575], + "48": [0, 0.64444, 0, 0, 0.575], + "49": [0, 0.64444, 0, 0, 0.575], + "50": [0, 0.64444, 0, 0, 0.575], + "51": [0, 0.64444, 0, 0, 0.575], + "52": [0, 0.64444, 0, 0, 0.575], + "53": [0, 0.64444, 0, 0, 0.575], + "54": [0, 0.64444, 0, 0, 0.575], + "55": [0, 0.64444, 0, 0, 0.575], + "56": [0, 0.64444, 0, 0, 0.575], + "57": [0, 0.64444, 0, 0, 0.575], + "58": [0, 0.44444, 0, 0, 0.31944], + "59": [0.19444, 0.44444, 0, 0, 0.31944], + "60": [0.08556, 0.58556, 0, 0, 0.89444], + "61": [-0.10889, 0.39111, 0, 0, 0.89444], + "62": [0.08556, 0.58556, 0, 0, 0.89444], + "63": [0, 0.69444, 0, 0, 0.54305], + "64": [0, 0.69444, 0, 0, 0.89444], + "65": [0, 0.68611, 0, 0, 0.86944], + "66": [0, 0.68611, 0, 0, 0.81805], + "67": [0, 0.68611, 0, 0, 0.83055], + "68": [0, 0.68611, 0, 0, 0.88194], + "69": [0, 0.68611, 0, 0, 0.75555], + "70": [0, 0.68611, 0, 0, 0.72361], + "71": [0, 0.68611, 0, 0, 0.90416], + "72": [0, 0.68611, 0, 0, 0.9], + "73": [0, 0.68611, 0, 0, 0.43611], + "74": [0, 0.68611, 0, 0, 0.59444], + "75": [0, 0.68611, 0, 0, 0.90138], + "76": [0, 0.68611, 0, 0, 0.69166], + "77": [0, 0.68611, 0, 0, 1.09166], + "78": [0, 0.68611, 0, 0, 0.9], + "79": [0, 0.68611, 0, 0, 0.86388], + "80": [0, 0.68611, 0, 0, 0.78611], + "81": [0.19444, 0.68611, 0, 0, 0.86388], + "82": [0, 0.68611, 0, 0, 0.8625], + "83": [0, 0.68611, 0, 0, 0.63889], + "84": [0, 0.68611, 0, 0, 0.8], + "85": [0, 0.68611, 0, 0, 0.88472], + "86": [0, 0.68611, 0.01597, 0, 0.86944], + "87": [0, 0.68611, 0.01597, 0, 1.18888], + "88": [0, 0.68611, 0, 0, 0.86944], + "89": [0, 0.68611, 0.02875, 0, 0.86944], + "90": [0, 0.68611, 0, 0, 0.70277], + "91": [0.25, 0.75, 0, 0, 0.31944], + "92": [0.25, 0.75, 0, 0, 0.575], + "93": [0.25, 0.75, 0, 0, 0.31944], + "94": [0, 0.69444, 0, 0, 0.575], + "95": [0.31, 0.13444, 0.03194, 0, 0.575], + "97": [0, 0.44444, 0, 0, 0.55902], + "98": [0, 0.69444, 0, 0, 0.63889], + "99": [0, 0.44444, 0, 0, 0.51111], + "100": [0, 0.69444, 0, 0, 0.63889], + "101": [0, 0.44444, 0, 0, 0.52708], + "102": [0, 0.69444, 0.10903, 0, 0.35139], + "103": [0.19444, 0.44444, 0.01597, 0, 0.575], + "104": [0, 0.69444, 0, 0, 0.63889], + "105": [0, 0.69444, 0, 0, 0.31944], + "106": [0.19444, 0.69444, 0, 0, 0.35139], + "107": [0, 0.69444, 0, 0, 0.60694], + "108": [0, 0.69444, 0, 0, 0.31944], + "109": [0, 0.44444, 0, 0, 0.95833], + "110": [0, 0.44444, 0, 0, 0.63889], + "111": [0, 0.44444, 0, 0, 0.575], + "112": [0.19444, 0.44444, 0, 0, 0.63889], + "113": [0.19444, 0.44444, 0, 0, 0.60694], + "114": [0, 0.44444, 0, 0, 0.47361], + "115": [0, 0.44444, 0, 0, 0.45361], + "116": [0, 0.63492, 0, 0, 0.44722], + "117": [0, 0.44444, 0, 0, 0.63889], + "118": [0, 0.44444, 0.01597, 0, 0.60694], + "119": [0, 0.44444, 0.01597, 0, 0.83055], + "120": [0, 0.44444, 0, 0, 0.60694], + "121": [0.19444, 0.44444, 0.01597, 0, 0.60694], + "122": [0, 0.44444, 0, 0, 0.51111], + "123": [0.25, 0.75, 0, 0, 0.575], + "124": [0.25, 0.75, 0, 0, 0.31944], + "125": [0.25, 0.75, 0, 0, 0.575], + "126": [0.35, 0.34444, 0, 0, 0.575], + "160": [0, 0, 0, 0, 0.25], + "163": [0, 0.69444, 0, 0, 0.86853], + "168": [0, 0.69444, 0, 0, 0.575], + "172": [0, 0.44444, 0, 0, 0.76666], + "176": [0, 0.69444, 0, 0, 0.86944], + "177": [0.13333, 0.63333, 0, 0, 0.89444], + "184": [0.17014, 0, 0, 0, 0.51111], + "198": [0, 0.68611, 0, 0, 1.04166], + "215": [0.13333, 0.63333, 0, 0, 0.89444], + "216": [0.04861, 0.73472, 0, 0, 0.89444], + "223": [0, 0.69444, 0, 0, 0.59722], + "230": [0, 0.44444, 0, 0, 0.83055], + "247": [0.13333, 0.63333, 0, 0, 0.89444], + "248": [0.09722, 0.54167, 0, 0, 0.575], + "305": [0, 0.44444, 0, 0, 0.31944], + "338": [0, 0.68611, 0, 0, 1.16944], + "339": [0, 0.44444, 0, 0, 0.89444], + "567": [0.19444, 0.44444, 0, 0, 0.35139], + "710": [0, 0.69444, 0, 0, 0.575], + "711": [0, 0.63194, 0, 0, 0.575], + "713": [0, 0.59611, 0, 0, 0.575], + "714": [0, 0.69444, 0, 0, 0.575], + "715": [0, 0.69444, 0, 0, 0.575], + "728": [0, 0.69444, 0, 0, 0.575], + "729": [0, 0.69444, 0, 0, 0.31944], + "730": [0, 0.69444, 0, 0, 0.86944], + "732": [0, 0.69444, 0, 0, 0.575], + "733": [0, 0.69444, 0, 0, 0.575], + "915": [0, 0.68611, 0, 0, 0.69166], + "916": [0, 0.68611, 0, 0, 0.95833], + "920": [0, 0.68611, 0, 0, 0.89444], + "923": [0, 0.68611, 0, 0, 0.80555], + "926": [0, 0.68611, 0, 0, 0.76666], + "928": [0, 0.68611, 0, 0, 0.9], + "931": [0, 0.68611, 0, 0, 0.83055], + "933": [0, 0.68611, 0, 0, 0.89444], + "934": [0, 0.68611, 0, 0, 0.83055], + "936": [0, 0.68611, 0, 0, 0.89444], + "937": [0, 0.68611, 0, 0, 0.83055], + "8211": [0, 0.44444, 0.03194, 0, 0.575], + "8212": [0, 0.44444, 0.03194, 0, 1.14999], + "8216": [0, 0.69444, 0, 0, 0.31944], + "8217": [0, 0.69444, 0, 0, 0.31944], + "8220": [0, 0.69444, 0, 0, 0.60278], + "8221": [0, 0.69444, 0, 0, 0.60278], + "8224": [0.19444, 0.69444, 0, 0, 0.51111], + "8225": [0.19444, 0.69444, 0, 0, 0.51111], + "8242": [0, 0.55556, 0, 0, 0.34444], + "8407": [0, 0.72444, 0.15486, 0, 0.575], + "8463": [0, 0.69444, 0, 0, 0.66759], + "8465": [0, 0.69444, 0, 0, 0.83055], + "8467": [0, 0.69444, 0, 0, 0.47361], + "8472": [0.19444, 0.44444, 0, 0, 0.74027], + "8476": [0, 0.69444, 0, 0, 0.83055], + "8501": [0, 0.69444, 0, 0, 0.70277], + "8592": [-0.10889, 0.39111, 0, 0, 1.14999], + "8593": [0.19444, 0.69444, 0, 0, 0.575], + "8594": [-0.10889, 0.39111, 0, 0, 1.14999], + "8595": [0.19444, 0.69444, 0, 0, 0.575], + "8596": [-0.10889, 0.39111, 0, 0, 1.14999], + "8597": [0.25, 0.75, 0, 0, 0.575], + "8598": [0.19444, 0.69444, 0, 0, 1.14999], + "8599": [0.19444, 0.69444, 0, 0, 1.14999], + "8600": [0.19444, 0.69444, 0, 0, 1.14999], + "8601": [0.19444, 0.69444, 0, 0, 1.14999], + "8636": [-0.10889, 0.39111, 0, 0, 1.14999], + "8637": [-0.10889, 0.39111, 0, 0, 1.14999], + "8640": [-0.10889, 0.39111, 0, 0, 1.14999], + "8641": [-0.10889, 0.39111, 0, 0, 1.14999], + "8656": [-0.10889, 0.39111, 0, 0, 1.14999], + "8657": [0.19444, 0.69444, 0, 0, 0.70277], + "8658": [-0.10889, 0.39111, 0, 0, 1.14999], + "8659": [0.19444, 0.69444, 0, 0, 0.70277], + "8660": [-0.10889, 0.39111, 0, 0, 1.14999], + "8661": [0.25, 0.75, 0, 0, 0.70277], + "8704": [0, 0.69444, 0, 0, 0.63889], + "8706": [0, 0.69444, 0.06389, 0, 0.62847], + "8707": [0, 0.69444, 0, 0, 0.63889], + "8709": [0.05556, 0.75, 0, 0, 0.575], + "8711": [0, 0.68611, 0, 0, 0.95833], + "8712": [0.08556, 0.58556, 0, 0, 0.76666], + "8715": [0.08556, 0.58556, 0, 0, 0.76666], + "8722": [0.13333, 0.63333, 0, 0, 0.89444], + "8723": [0.13333, 0.63333, 0, 0, 0.89444], + "8725": [0.25, 0.75, 0, 0, 0.575], + "8726": [0.25, 0.75, 0, 0, 0.575], + "8727": [-0.02778, 0.47222, 0, 0, 0.575], + "8728": [-0.02639, 0.47361, 0, 0, 0.575], + "8729": [-0.02639, 0.47361, 0, 0, 0.575], + "8730": [0.18, 0.82, 0, 0, 0.95833], + "8733": [0, 0.44444, 0, 0, 0.89444], + "8734": [0, 0.44444, 0, 0, 1.14999], + "8736": [0, 0.69224, 0, 0, 0.72222], + "8739": [0.25, 0.75, 0, 0, 0.31944], + "8741": [0.25, 0.75, 0, 0, 0.575], + "8743": [0, 0.55556, 0, 0, 0.76666], + "8744": [0, 0.55556, 0, 0, 0.76666], + "8745": [0, 0.55556, 0, 0, 0.76666], + "8746": [0, 0.55556, 0, 0, 0.76666], + "8747": [0.19444, 0.69444, 0.12778, 0, 0.56875], + "8764": [-0.10889, 0.39111, 0, 0, 0.89444], + "8768": [0.19444, 0.69444, 0, 0, 0.31944], + "8771": [0.00222, 0.50222, 0, 0, 0.89444], + "8773": [0.027, 0.638, 0, 0, 0.894], + "8776": [0.02444, 0.52444, 0, 0, 0.89444], + "8781": [0.00222, 0.50222, 0, 0, 0.89444], + "8801": [0.00222, 0.50222, 0, 0, 0.89444], + "8804": [0.19667, 0.69667, 0, 0, 0.89444], + "8805": [0.19667, 0.69667, 0, 0, 0.89444], + "8810": [0.08556, 0.58556, 0, 0, 1.14999], + "8811": [0.08556, 0.58556, 0, 0, 1.14999], + "8826": [0.08556, 0.58556, 0, 0, 0.89444], + "8827": [0.08556, 0.58556, 0, 0, 0.89444], + "8834": [0.08556, 0.58556, 0, 0, 0.89444], + "8835": [0.08556, 0.58556, 0, 0, 0.89444], + "8838": [0.19667, 0.69667, 0, 0, 0.89444], + "8839": [0.19667, 0.69667, 0, 0, 0.89444], + "8846": [0, 0.55556, 0, 0, 0.76666], + "8849": [0.19667, 0.69667, 0, 0, 0.89444], + "8850": [0.19667, 0.69667, 0, 0, 0.89444], + "8851": [0, 0.55556, 0, 0, 0.76666], + "8852": [0, 0.55556, 0, 0, 0.76666], + "8853": [0.13333, 0.63333, 0, 0, 0.89444], + "8854": [0.13333, 0.63333, 0, 0, 0.89444], + "8855": [0.13333, 0.63333, 0, 0, 0.89444], + "8856": [0.13333, 0.63333, 0, 0, 0.89444], + "8857": [0.13333, 0.63333, 0, 0, 0.89444], + "8866": [0, 0.69444, 0, 0, 0.70277], + "8867": [0, 0.69444, 0, 0, 0.70277], + "8868": [0, 0.69444, 0, 0, 0.89444], + "8869": [0, 0.69444, 0, 0, 0.89444], + "8900": [-0.02639, 0.47361, 0, 0, 0.575], + "8901": [-0.02639, 0.47361, 0, 0, 0.31944], + "8902": [-0.02778, 0.47222, 0, 0, 0.575], + "8968": [0.25, 0.75, 0, 0, 0.51111], + "8969": [0.25, 0.75, 0, 0, 0.51111], + "8970": [0.25, 0.75, 0, 0, 0.51111], + "8971": [0.25, 0.75, 0, 0, 0.51111], + "8994": [-0.13889, 0.36111, 0, 0, 1.14999], + "8995": [-0.13889, 0.36111, 0, 0, 1.14999], + "9651": [0.19444, 0.69444, 0, 0, 1.02222], + "9657": [-0.02778, 0.47222, 0, 0, 0.575], + "9661": [0.19444, 0.69444, 0, 0, 1.02222], + "9667": [-0.02778, 0.47222, 0, 0, 0.575], + "9711": [0.19444, 0.69444, 0, 0, 1.14999], + "9824": [0.12963, 0.69444, 0, 0, 0.89444], + "9825": [0.12963, 0.69444, 0, 0, 0.89444], + "9826": [0.12963, 0.69444, 0, 0, 0.89444], + "9827": [0.12963, 0.69444, 0, 0, 0.89444], + "9837": [0, 0.75, 0, 0, 0.44722], + "9838": [0.19444, 0.69444, 0, 0, 0.44722], + "9839": [0.19444, 0.69444, 0, 0, 0.44722], + "10216": [0.25, 0.75, 0, 0, 0.44722], + "10217": [0.25, 0.75, 0, 0, 0.44722], + "10815": [0, 0.68611, 0, 0, 0.9], + "10927": [0.19667, 0.69667, 0, 0, 0.89444], + "10928": [0.19667, 0.69667, 0, 0, 0.89444], + "57376": [0.19444, 0.69444, 0, 0, 0] + }, + "Main-BoldItalic": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0.11417, 0, 0.38611], + "34": [0, 0.69444, 0.07939, 0, 0.62055], + "35": [0.19444, 0.69444, 0.06833, 0, 0.94444], + "37": [0.05556, 0.75, 0.12861, 0, 0.94444], + "38": [0, 0.69444, 0.08528, 0, 0.88555], + "39": [0, 0.69444, 0.12945, 0, 0.35555], + "40": [0.25, 0.75, 0.15806, 0, 0.47333], + "41": [0.25, 0.75, 0.03306, 0, 0.47333], + "42": [0, 0.75, 0.14333, 0, 0.59111], + "43": [0.10333, 0.60333, 0.03306, 0, 0.88555], + "44": [0.19444, 0.14722, 0, 0, 0.35555], + "45": [0, 0.44444, 0.02611, 0, 0.41444], + "46": [0, 0.14722, 0, 0, 0.35555], + "47": [0.25, 0.75, 0.15806, 0, 0.59111], + "48": [0, 0.64444, 0.13167, 0, 0.59111], + "49": [0, 0.64444, 0.13167, 0, 0.59111], + "50": [0, 0.64444, 0.13167, 0, 0.59111], + "51": [0, 0.64444, 0.13167, 0, 0.59111], + "52": [0.19444, 0.64444, 0.13167, 0, 0.59111], + "53": [0, 0.64444, 0.13167, 0, 0.59111], + "54": [0, 0.64444, 0.13167, 0, 0.59111], + "55": [0.19444, 0.64444, 0.13167, 0, 0.59111], + "56": [0, 0.64444, 0.13167, 0, 0.59111], + "57": [0, 0.64444, 0.13167, 0, 0.59111], + "58": [0, 0.44444, 0.06695, 0, 0.35555], + "59": [0.19444, 0.44444, 0.06695, 0, 0.35555], + "61": [-0.10889, 0.39111, 0.06833, 0, 0.88555], + "63": [0, 0.69444, 0.11472, 0, 0.59111], + "64": [0, 0.69444, 0.09208, 0, 0.88555], + "65": [0, 0.68611, 0, 0, 0.86555], + "66": [0, 0.68611, 0.0992, 0, 0.81666], + "67": [0, 0.68611, 0.14208, 0, 0.82666], + "68": [0, 0.68611, 0.09062, 0, 0.87555], + "69": [0, 0.68611, 0.11431, 0, 0.75666], + "70": [0, 0.68611, 0.12903, 0, 0.72722], + "71": [0, 0.68611, 0.07347, 0, 0.89527], + "72": [0, 0.68611, 0.17208, 0, 0.8961], + "73": [0, 0.68611, 0.15681, 0, 0.47166], + "74": [0, 0.68611, 0.145, 0, 0.61055], + "75": [0, 0.68611, 0.14208, 0, 0.89499], + "76": [0, 0.68611, 0, 0, 0.69777], + "77": [0, 0.68611, 0.17208, 0, 1.07277], + "78": [0, 0.68611, 0.17208, 0, 0.8961], + "79": [0, 0.68611, 0.09062, 0, 0.85499], + "80": [0, 0.68611, 0.0992, 0, 0.78721], + "81": [0.19444, 0.68611, 0.09062, 0, 0.85499], + "82": [0, 0.68611, 0.02559, 0, 0.85944], + "83": [0, 0.68611, 0.11264, 0, 0.64999], + "84": [0, 0.68611, 0.12903, 0, 0.7961], + "85": [0, 0.68611, 0.17208, 0, 0.88083], + "86": [0, 0.68611, 0.18625, 0, 0.86555], + "87": [0, 0.68611, 0.18625, 0, 1.15999], + "88": [0, 0.68611, 0.15681, 0, 0.86555], + "89": [0, 0.68611, 0.19803, 0, 0.86555], + "90": [0, 0.68611, 0.14208, 0, 0.70888], + "91": [0.25, 0.75, 0.1875, 0, 0.35611], + "93": [0.25, 0.75, 0.09972, 0, 0.35611], + "94": [0, 0.69444, 0.06709, 0, 0.59111], + "95": [0.31, 0.13444, 0.09811, 0, 0.59111], + "97": [0, 0.44444, 0.09426, 0, 0.59111], + "98": [0, 0.69444, 0.07861, 0, 0.53222], + "99": [0, 0.44444, 0.05222, 0, 0.53222], + "100": [0, 0.69444, 0.10861, 0, 0.59111], + "101": [0, 0.44444, 0.085, 0, 0.53222], + "102": [0.19444, 0.69444, 0.21778, 0, 0.4], + "103": [0.19444, 0.44444, 0.105, 0, 0.53222], + "104": [0, 0.69444, 0.09426, 0, 0.59111], + "105": [0, 0.69326, 0.11387, 0, 0.35555], + "106": [0.19444, 0.69326, 0.1672, 0, 0.35555], + "107": [0, 0.69444, 0.11111, 0, 0.53222], + "108": [0, 0.69444, 0.10861, 0, 0.29666], + "109": [0, 0.44444, 0.09426, 0, 0.94444], + "110": [0, 0.44444, 0.09426, 0, 0.64999], + "111": [0, 0.44444, 0.07861, 0, 0.59111], + "112": [0.19444, 0.44444, 0.07861, 0, 0.59111], + "113": [0.19444, 0.44444, 0.105, 0, 0.53222], + "114": [0, 0.44444, 0.11111, 0, 0.50167], + "115": [0, 0.44444, 0.08167, 0, 0.48694], + "116": [0, 0.63492, 0.09639, 0, 0.385], + "117": [0, 0.44444, 0.09426, 0, 0.62055], + "118": [0, 0.44444, 0.11111, 0, 0.53222], + "119": [0, 0.44444, 0.11111, 0, 0.76777], + "120": [0, 0.44444, 0.12583, 0, 0.56055], + "121": [0.19444, 0.44444, 0.105, 0, 0.56166], + "122": [0, 0.44444, 0.13889, 0, 0.49055], + "126": [0.35, 0.34444, 0.11472, 0, 0.59111], + "160": [0, 0, 0, 0, 0.25], + "168": [0, 0.69444, 0.11473, 0, 0.59111], + "176": [0, 0.69444, 0, 0, 0.94888], + "184": [0.17014, 0, 0, 0, 0.53222], + "198": [0, 0.68611, 0.11431, 0, 1.02277], + "216": [0.04861, 0.73472, 0.09062, 0, 0.88555], + "223": [0.19444, 0.69444, 0.09736, 0, 0.665], + "230": [0, 0.44444, 0.085, 0, 0.82666], + "248": [0.09722, 0.54167, 0.09458, 0, 0.59111], + "305": [0, 0.44444, 0.09426, 0, 0.35555], + "338": [0, 0.68611, 0.11431, 0, 1.14054], + "339": [0, 0.44444, 0.085, 0, 0.82666], + "567": [0.19444, 0.44444, 0.04611, 0, 0.385], + "710": [0, 0.69444, 0.06709, 0, 0.59111], + "711": [0, 0.63194, 0.08271, 0, 0.59111], + "713": [0, 0.59444, 0.10444, 0, 0.59111], + "714": [0, 0.69444, 0.08528, 0, 0.59111], + "715": [0, 0.69444, 0, 0, 0.59111], + "728": [0, 0.69444, 0.10333, 0, 0.59111], + "729": [0, 0.69444, 0.12945, 0, 0.35555], + "730": [0, 0.69444, 0, 0, 0.94888], + "732": [0, 0.69444, 0.11472, 0, 0.59111], + "733": [0, 0.69444, 0.11472, 0, 0.59111], + "915": [0, 0.68611, 0.12903, 0, 0.69777], + "916": [0, 0.68611, 0, 0, 0.94444], + "920": [0, 0.68611, 0.09062, 0, 0.88555], + "923": [0, 0.68611, 0, 0, 0.80666], + "926": [0, 0.68611, 0.15092, 0, 0.76777], + "928": [0, 0.68611, 0.17208, 0, 0.8961], + "931": [0, 0.68611, 0.11431, 0, 0.82666], + "933": [0, 0.68611, 0.10778, 0, 0.88555], + "934": [0, 0.68611, 0.05632, 0, 0.82666], + "936": [0, 0.68611, 0.10778, 0, 0.88555], + "937": [0, 0.68611, 0.0992, 0, 0.82666], + "8211": [0, 0.44444, 0.09811, 0, 0.59111], + "8212": [0, 0.44444, 0.09811, 0, 1.18221], + "8216": [0, 0.69444, 0.12945, 0, 0.35555], + "8217": [0, 0.69444, 0.12945, 0, 0.35555], + "8220": [0, 0.69444, 0.16772, 0, 0.62055], + "8221": [0, 0.69444, 0.07939, 0, 0.62055] + }, + "Main-Italic": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0.12417, 0, 0.30667], + "34": [0, 0.69444, 0.06961, 0, 0.51444], + "35": [0.19444, 0.69444, 0.06616, 0, 0.81777], + "37": [0.05556, 0.75, 0.13639, 0, 0.81777], + "38": [0, 0.69444, 0.09694, 0, 0.76666], + "39": [0, 0.69444, 0.12417, 0, 0.30667], + "40": [0.25, 0.75, 0.16194, 0, 0.40889], + "41": [0.25, 0.75, 0.03694, 0, 0.40889], + "42": [0, 0.75, 0.14917, 0, 0.51111], + "43": [0.05667, 0.56167, 0.03694, 0, 0.76666], + "44": [0.19444, 0.10556, 0, 0, 0.30667], + "45": [0, 0.43056, 0.02826, 0, 0.35778], + "46": [0, 0.10556, 0, 0, 0.30667], + "47": [0.25, 0.75, 0.16194, 0, 0.51111], + "48": [0, 0.64444, 0.13556, 0, 0.51111], + "49": [0, 0.64444, 0.13556, 0, 0.51111], + "50": [0, 0.64444, 0.13556, 0, 0.51111], + "51": [0, 0.64444, 0.13556, 0, 0.51111], + "52": [0.19444, 0.64444, 0.13556, 0, 0.51111], + "53": [0, 0.64444, 0.13556, 0, 0.51111], + "54": [0, 0.64444, 0.13556, 0, 0.51111], + "55": [0.19444, 0.64444, 0.13556, 0, 0.51111], + "56": [0, 0.64444, 0.13556, 0, 0.51111], + "57": [0, 0.64444, 0.13556, 0, 0.51111], + "58": [0, 0.43056, 0.0582, 0, 0.30667], + "59": [0.19444, 0.43056, 0.0582, 0, 0.30667], + "61": [-0.13313, 0.36687, 0.06616, 0, 0.76666], + "63": [0, 0.69444, 0.1225, 0, 0.51111], + "64": [0, 0.69444, 0.09597, 0, 0.76666], + "65": [0, 0.68333, 0, 0, 0.74333], + "66": [0, 0.68333, 0.10257, 0, 0.70389], + "67": [0, 0.68333, 0.14528, 0, 0.71555], + "68": [0, 0.68333, 0.09403, 0, 0.755], + "69": [0, 0.68333, 0.12028, 0, 0.67833], + "70": [0, 0.68333, 0.13305, 0, 0.65277], + "71": [0, 0.68333, 0.08722, 0, 0.77361], + "72": [0, 0.68333, 0.16389, 0, 0.74333], + "73": [0, 0.68333, 0.15806, 0, 0.38555], + "74": [0, 0.68333, 0.14028, 0, 0.525], + "75": [0, 0.68333, 0.14528, 0, 0.76888], + "76": [0, 0.68333, 0, 0, 0.62722], + "77": [0, 0.68333, 0.16389, 0, 0.89666], + "78": [0, 0.68333, 0.16389, 0, 0.74333], + "79": [0, 0.68333, 0.09403, 0, 0.76666], + "80": [0, 0.68333, 0.10257, 0, 0.67833], + "81": [0.19444, 0.68333, 0.09403, 0, 0.76666], + "82": [0, 0.68333, 0.03868, 0, 0.72944], + "83": [0, 0.68333, 0.11972, 0, 0.56222], + "84": [0, 0.68333, 0.13305, 0, 0.71555], + "85": [0, 0.68333, 0.16389, 0, 0.74333], + "86": [0, 0.68333, 0.18361, 0, 0.74333], + "87": [0, 0.68333, 0.18361, 0, 0.99888], + "88": [0, 0.68333, 0.15806, 0, 0.74333], + "89": [0, 0.68333, 0.19383, 0, 0.74333], + "90": [0, 0.68333, 0.14528, 0, 0.61333], + "91": [0.25, 0.75, 0.1875, 0, 0.30667], + "93": [0.25, 0.75, 0.10528, 0, 0.30667], + "94": [0, 0.69444, 0.06646, 0, 0.51111], + "95": [0.31, 0.12056, 0.09208, 0, 0.51111], + "97": [0, 0.43056, 0.07671, 0, 0.51111], + "98": [0, 0.69444, 0.06312, 0, 0.46], + "99": [0, 0.43056, 0.05653, 0, 0.46], + "100": [0, 0.69444, 0.10333, 0, 0.51111], + "101": [0, 0.43056, 0.07514, 0, 0.46], + "102": [0.19444, 0.69444, 0.21194, 0, 0.30667], + "103": [0.19444, 0.43056, 0.08847, 0, 0.46], + "104": [0, 0.69444, 0.07671, 0, 0.51111], + "105": [0, 0.65536, 0.1019, 0, 0.30667], + "106": [0.19444, 0.65536, 0.14467, 0, 0.30667], + "107": [0, 0.69444, 0.10764, 0, 0.46], + "108": [0, 0.69444, 0.10333, 0, 0.25555], + "109": [0, 0.43056, 0.07671, 0, 0.81777], + "110": [0, 0.43056, 0.07671, 0, 0.56222], + "111": [0, 0.43056, 0.06312, 0, 0.51111], + "112": [0.19444, 0.43056, 0.06312, 0, 0.51111], + "113": [0.19444, 0.43056, 0.08847, 0, 0.46], + "114": [0, 0.43056, 0.10764, 0, 0.42166], + "115": [0, 0.43056, 0.08208, 0, 0.40889], + "116": [0, 0.61508, 0.09486, 0, 0.33222], + "117": [0, 0.43056, 0.07671, 0, 0.53666], + "118": [0, 0.43056, 0.10764, 0, 0.46], + "119": [0, 0.43056, 0.10764, 0, 0.66444], + "120": [0, 0.43056, 0.12042, 0, 0.46389], + "121": [0.19444, 0.43056, 0.08847, 0, 0.48555], + "122": [0, 0.43056, 0.12292, 0, 0.40889], + "126": [0.35, 0.31786, 0.11585, 0, 0.51111], + "160": [0, 0, 0, 0, 0.25], + "168": [0, 0.66786, 0.10474, 0, 0.51111], + "176": [0, 0.69444, 0, 0, 0.83129], + "184": [0.17014, 0, 0, 0, 0.46], + "198": [0, 0.68333, 0.12028, 0, 0.88277], + "216": [0.04861, 0.73194, 0.09403, 0, 0.76666], + "223": [0.19444, 0.69444, 0.10514, 0, 0.53666], + "230": [0, 0.43056, 0.07514, 0, 0.71555], + "248": [0.09722, 0.52778, 0.09194, 0, 0.51111], + "338": [0, 0.68333, 0.12028, 0, 0.98499], + "339": [0, 0.43056, 0.07514, 0, 0.71555], + "710": [0, 0.69444, 0.06646, 0, 0.51111], + "711": [0, 0.62847, 0.08295, 0, 0.51111], + "713": [0, 0.56167, 0.10333, 0, 0.51111], + "714": [0, 0.69444, 0.09694, 0, 0.51111], + "715": [0, 0.69444, 0, 0, 0.51111], + "728": [0, 0.69444, 0.10806, 0, 0.51111], + "729": [0, 0.66786, 0.11752, 0, 0.30667], + "730": [0, 0.69444, 0, 0, 0.83129], + "732": [0, 0.66786, 0.11585, 0, 0.51111], + "733": [0, 0.69444, 0.1225, 0, 0.51111], + "915": [0, 0.68333, 0.13305, 0, 0.62722], + "916": [0, 0.68333, 0, 0, 0.81777], + "920": [0, 0.68333, 0.09403, 0, 0.76666], + "923": [0, 0.68333, 0, 0, 0.69222], + "926": [0, 0.68333, 0.15294, 0, 0.66444], + "928": [0, 0.68333, 0.16389, 0, 0.74333], + "931": [0, 0.68333, 0.12028, 0, 0.71555], + "933": [0, 0.68333, 0.11111, 0, 0.76666], + "934": [0, 0.68333, 0.05986, 0, 0.71555], + "936": [0, 0.68333, 0.11111, 0, 0.76666], + "937": [0, 0.68333, 0.10257, 0, 0.71555], + "8211": [0, 0.43056, 0.09208, 0, 0.51111], + "8212": [0, 0.43056, 0.09208, 0, 1.02222], + "8216": [0, 0.69444, 0.12417, 0, 0.30667], + "8217": [0, 0.69444, 0.12417, 0, 0.30667], + "8220": [0, 0.69444, 0.1685, 0, 0.51444], + "8221": [0, 0.69444, 0.06961, 0, 0.51444], + "8463": [0, 0.68889, 0, 0, 0.54028] + }, + "Main-Regular": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0, 0, 0.27778], + "34": [0, 0.69444, 0, 0, 0.5], + "35": [0.19444, 0.69444, 0, 0, 0.83334], + "36": [0.05556, 0.75, 0, 0, 0.5], + "37": [0.05556, 0.75, 0, 0, 0.83334], + "38": [0, 0.69444, 0, 0, 0.77778], + "39": [0, 0.69444, 0, 0, 0.27778], + "40": [0.25, 0.75, 0, 0, 0.38889], + "41": [0.25, 0.75, 0, 0, 0.38889], + "42": [0, 0.75, 0, 0, 0.5], + "43": [0.08333, 0.58333, 0, 0, 0.77778], + "44": [0.19444, 0.10556, 0, 0, 0.27778], + "45": [0, 0.43056, 0, 0, 0.33333], + "46": [0, 0.10556, 0, 0, 0.27778], + "47": [0.25, 0.75, 0, 0, 0.5], + "48": [0, 0.64444, 0, 0, 0.5], + "49": [0, 0.64444, 0, 0, 0.5], + "50": [0, 0.64444, 0, 0, 0.5], + "51": [0, 0.64444, 0, 0, 0.5], + "52": [0, 0.64444, 0, 0, 0.5], + "53": [0, 0.64444, 0, 0, 0.5], + "54": [0, 0.64444, 0, 0, 0.5], + "55": [0, 0.64444, 0, 0, 0.5], + "56": [0, 0.64444, 0, 0, 0.5], + "57": [0, 0.64444, 0, 0, 0.5], + "58": [0, 0.43056, 0, 0, 0.27778], + "59": [0.19444, 0.43056, 0, 0, 0.27778], + "60": [0.0391, 0.5391, 0, 0, 0.77778], + "61": [-0.13313, 0.36687, 0, 0, 0.77778], + "62": [0.0391, 0.5391, 0, 0, 0.77778], + "63": [0, 0.69444, 0, 0, 0.47222], + "64": [0, 0.69444, 0, 0, 0.77778], + "65": [0, 0.68333, 0, 0, 0.75], + "66": [0, 0.68333, 0, 0, 0.70834], + "67": [0, 0.68333, 0, 0, 0.72222], + "68": [0, 0.68333, 0, 0, 0.76389], + "69": [0, 0.68333, 0, 0, 0.68056], + "70": [0, 0.68333, 0, 0, 0.65278], + "71": [0, 0.68333, 0, 0, 0.78472], + "72": [0, 0.68333, 0, 0, 0.75], + "73": [0, 0.68333, 0, 0, 0.36111], + "74": [0, 0.68333, 0, 0, 0.51389], + "75": [0, 0.68333, 0, 0, 0.77778], + "76": [0, 0.68333, 0, 0, 0.625], + "77": [0, 0.68333, 0, 0, 0.91667], + "78": [0, 0.68333, 0, 0, 0.75], + "79": [0, 0.68333, 0, 0, 0.77778], + "80": [0, 0.68333, 0, 0, 0.68056], + "81": [0.19444, 0.68333, 0, 0, 0.77778], + "82": [0, 0.68333, 0, 0, 0.73611], + "83": [0, 0.68333, 0, 0, 0.55556], + "84": [0, 0.68333, 0, 0, 0.72222], + "85": [0, 0.68333, 0, 0, 0.75], + "86": [0, 0.68333, 0.01389, 0, 0.75], + "87": [0, 0.68333, 0.01389, 0, 1.02778], + "88": [0, 0.68333, 0, 0, 0.75], + "89": [0, 0.68333, 0.025, 0, 0.75], + "90": [0, 0.68333, 0, 0, 0.61111], + "91": [0.25, 0.75, 0, 0, 0.27778], + "92": [0.25, 0.75, 0, 0, 0.5], + "93": [0.25, 0.75, 0, 0, 0.27778], + "94": [0, 0.69444, 0, 0, 0.5], + "95": [0.31, 0.12056, 0.02778, 0, 0.5], + "97": [0, 0.43056, 0, 0, 0.5], + "98": [0, 0.69444, 0, 0, 0.55556], + "99": [0, 0.43056, 0, 0, 0.44445], + "100": [0, 0.69444, 0, 0, 0.55556], + "101": [0, 0.43056, 0, 0, 0.44445], + "102": [0, 0.69444, 0.07778, 0, 0.30556], + "103": [0.19444, 0.43056, 0.01389, 0, 0.5], + "104": [0, 0.69444, 0, 0, 0.55556], + "105": [0, 0.66786, 0, 0, 0.27778], + "106": [0.19444, 0.66786, 0, 0, 0.30556], + "107": [0, 0.69444, 0, 0, 0.52778], + "108": [0, 0.69444, 0, 0, 0.27778], + "109": [0, 0.43056, 0, 0, 0.83334], + "110": [0, 0.43056, 0, 0, 0.55556], + "111": [0, 0.43056, 0, 0, 0.5], + "112": [0.19444, 0.43056, 0, 0, 0.55556], + "113": [0.19444, 0.43056, 0, 0, 0.52778], + "114": [0, 0.43056, 0, 0, 0.39167], + "115": [0, 0.43056, 0, 0, 0.39445], + "116": [0, 0.61508, 0, 0, 0.38889], + "117": [0, 0.43056, 0, 0, 0.55556], + "118": [0, 0.43056, 0.01389, 0, 0.52778], + "119": [0, 0.43056, 0.01389, 0, 0.72222], + "120": [0, 0.43056, 0, 0, 0.52778], + "121": [0.19444, 0.43056, 0.01389, 0, 0.52778], + "122": [0, 0.43056, 0, 0, 0.44445], + "123": [0.25, 0.75, 0, 0, 0.5], + "124": [0.25, 0.75, 0, 0, 0.27778], + "125": [0.25, 0.75, 0, 0, 0.5], + "126": [0.35, 0.31786, 0, 0, 0.5], + "160": [0, 0, 0, 0, 0.25], + "163": [0, 0.69444, 0, 0, 0.76909], + "167": [0.19444, 0.69444, 0, 0, 0.44445], + "168": [0, 0.66786, 0, 0, 0.5], + "172": [0, 0.43056, 0, 0, 0.66667], + "176": [0, 0.69444, 0, 0, 0.75], + "177": [0.08333, 0.58333, 0, 0, 0.77778], + "182": [0.19444, 0.69444, 0, 0, 0.61111], + "184": [0.17014, 0, 0, 0, 0.44445], + "198": [0, 0.68333, 0, 0, 0.90278], + "215": [0.08333, 0.58333, 0, 0, 0.77778], + "216": [0.04861, 0.73194, 0, 0, 0.77778], + "223": [0, 0.69444, 0, 0, 0.5], + "230": [0, 0.43056, 0, 0, 0.72222], + "247": [0.08333, 0.58333, 0, 0, 0.77778], + "248": [0.09722, 0.52778, 0, 0, 0.5], + "305": [0, 0.43056, 0, 0, 0.27778], + "338": [0, 0.68333, 0, 0, 1.01389], + "339": [0, 0.43056, 0, 0, 0.77778], + "567": [0.19444, 0.43056, 0, 0, 0.30556], + "710": [0, 0.69444, 0, 0, 0.5], + "711": [0, 0.62847, 0, 0, 0.5], + "713": [0, 0.56778, 0, 0, 0.5], + "714": [0, 0.69444, 0, 0, 0.5], + "715": [0, 0.69444, 0, 0, 0.5], + "728": [0, 0.69444, 0, 0, 0.5], + "729": [0, 0.66786, 0, 0, 0.27778], + "730": [0, 0.69444, 0, 0, 0.75], + "732": [0, 0.66786, 0, 0, 0.5], + "733": [0, 0.69444, 0, 0, 0.5], + "915": [0, 0.68333, 0, 0, 0.625], + "916": [0, 0.68333, 0, 0, 0.83334], + "920": [0, 0.68333, 0, 0, 0.77778], + "923": [0, 0.68333, 0, 0, 0.69445], + "926": [0, 0.68333, 0, 0, 0.66667], + "928": [0, 0.68333, 0, 0, 0.75], + "931": [0, 0.68333, 0, 0, 0.72222], + "933": [0, 0.68333, 0, 0, 0.77778], + "934": [0, 0.68333, 0, 0, 0.72222], + "936": [0, 0.68333, 0, 0, 0.77778], + "937": [0, 0.68333, 0, 0, 0.72222], + "8211": [0, 0.43056, 0.02778, 0, 0.5], + "8212": [0, 0.43056, 0.02778, 0, 1.0], + "8216": [0, 0.69444, 0, 0, 0.27778], + "8217": [0, 0.69444, 0, 0, 0.27778], + "8220": [0, 0.69444, 0, 0, 0.5], + "8221": [0, 0.69444, 0, 0, 0.5], + "8224": [0.19444, 0.69444, 0, 0, 0.44445], + "8225": [0.19444, 0.69444, 0, 0, 0.44445], + "8230": [0, 0.123, 0, 0, 1.172], + "8242": [0, 0.55556, 0, 0, 0.275], + "8407": [0, 0.71444, 0.15382, 0, 0.5], + "8463": [0, 0.68889, 0, 0, 0.54028], + "8465": [0, 0.69444, 0, 0, 0.72222], + "8467": [0, 0.69444, 0, 0.11111, 0.41667], + "8472": [0.19444, 0.43056, 0, 0.11111, 0.63646], + "8476": [0, 0.69444, 0, 0, 0.72222], + "8501": [0, 0.69444, 0, 0, 0.61111], + "8592": [-0.13313, 0.36687, 0, 0, 1.0], + "8593": [0.19444, 0.69444, 0, 0, 0.5], + "8594": [-0.13313, 0.36687, 0, 0, 1.0], + "8595": [0.19444, 0.69444, 0, 0, 0.5], + "8596": [-0.13313, 0.36687, 0, 0, 1.0], + "8597": [0.25, 0.75, 0, 0, 0.5], + "8598": [0.19444, 0.69444, 0, 0, 1.0], + "8599": [0.19444, 0.69444, 0, 0, 1.0], + "8600": [0.19444, 0.69444, 0, 0, 1.0], + "8601": [0.19444, 0.69444, 0, 0, 1.0], + "8614": [0.011, 0.511, 0, 0, 1.0], + "8617": [0.011, 0.511, 0, 0, 1.126], + "8618": [0.011, 0.511, 0, 0, 1.126], + "8636": [-0.13313, 0.36687, 0, 0, 1.0], + "8637": [-0.13313, 0.36687, 0, 0, 1.0], + "8640": [-0.13313, 0.36687, 0, 0, 1.0], + "8641": [-0.13313, 0.36687, 0, 0, 1.0], + "8652": [0.011, 0.671, 0, 0, 1.0], + "8656": [-0.13313, 0.36687, 0, 0, 1.0], + "8657": [0.19444, 0.69444, 0, 0, 0.61111], + "8658": [-0.13313, 0.36687, 0, 0, 1.0], + "8659": [0.19444, 0.69444, 0, 0, 0.61111], + "8660": [-0.13313, 0.36687, 0, 0, 1.0], + "8661": [0.25, 0.75, 0, 0, 0.61111], + "8704": [0, 0.69444, 0, 0, 0.55556], + "8706": [0, 0.69444, 0.05556, 0.08334, 0.5309], + "8707": [0, 0.69444, 0, 0, 0.55556], + "8709": [0.05556, 0.75, 0, 0, 0.5], + "8711": [0, 0.68333, 0, 0, 0.83334], + "8712": [0.0391, 0.5391, 0, 0, 0.66667], + "8715": [0.0391, 0.5391, 0, 0, 0.66667], + "8722": [0.08333, 0.58333, 0, 0, 0.77778], + "8723": [0.08333, 0.58333, 0, 0, 0.77778], + "8725": [0.25, 0.75, 0, 0, 0.5], + "8726": [0.25, 0.75, 0, 0, 0.5], + "8727": [-0.03472, 0.46528, 0, 0, 0.5], + "8728": [-0.05555, 0.44445, 0, 0, 0.5], + "8729": [-0.05555, 0.44445, 0, 0, 0.5], + "8730": [0.2, 0.8, 0, 0, 0.83334], + "8733": [0, 0.43056, 0, 0, 0.77778], + "8734": [0, 0.43056, 0, 0, 1.0], + "8736": [0, 0.69224, 0, 0, 0.72222], + "8739": [0.25, 0.75, 0, 0, 0.27778], + "8741": [0.25, 0.75, 0, 0, 0.5], + "8743": [0, 0.55556, 0, 0, 0.66667], + "8744": [0, 0.55556, 0, 0, 0.66667], + "8745": [0, 0.55556, 0, 0, 0.66667], + "8746": [0, 0.55556, 0, 0, 0.66667], + "8747": [0.19444, 0.69444, 0.11111, 0, 0.41667], + "8764": [-0.13313, 0.36687, 0, 0, 0.77778], + "8768": [0.19444, 0.69444, 0, 0, 0.27778], + "8771": [-0.03625, 0.46375, 0, 0, 0.77778], + "8773": [-0.022, 0.589, 0, 0, 0.778], + "8776": [-0.01688, 0.48312, 0, 0, 0.77778], + "8781": [-0.03625, 0.46375, 0, 0, 0.77778], + "8784": [-0.133, 0.673, 0, 0, 0.778], + "8801": [-0.03625, 0.46375, 0, 0, 0.77778], + "8804": [0.13597, 0.63597, 0, 0, 0.77778], + "8805": [0.13597, 0.63597, 0, 0, 0.77778], + "8810": [0.0391, 0.5391, 0, 0, 1.0], + "8811": [0.0391, 0.5391, 0, 0, 1.0], + "8826": [0.0391, 0.5391, 0, 0, 0.77778], + "8827": [0.0391, 0.5391, 0, 0, 0.77778], + "8834": [0.0391, 0.5391, 0, 0, 0.77778], + "8835": [0.0391, 0.5391, 0, 0, 0.77778], + "8838": [0.13597, 0.63597, 0, 0, 0.77778], + "8839": [0.13597, 0.63597, 0, 0, 0.77778], + "8846": [0, 0.55556, 0, 0, 0.66667], + "8849": [0.13597, 0.63597, 0, 0, 0.77778], + "8850": [0.13597, 0.63597, 0, 0, 0.77778], + "8851": [0, 0.55556, 0, 0, 0.66667], + "8852": [0, 0.55556, 0, 0, 0.66667], + "8853": [0.08333, 0.58333, 0, 0, 0.77778], + "8854": [0.08333, 0.58333, 0, 0, 0.77778], + "8855": [0.08333, 0.58333, 0, 0, 0.77778], + "8856": [0.08333, 0.58333, 0, 0, 0.77778], + "8857": [0.08333, 0.58333, 0, 0, 0.77778], + "8866": [0, 0.69444, 0, 0, 0.61111], + "8867": [0, 0.69444, 0, 0, 0.61111], + "8868": [0, 0.69444, 0, 0, 0.77778], + "8869": [0, 0.69444, 0, 0, 0.77778], + "8872": [0.249, 0.75, 0, 0, 0.867], + "8900": [-0.05555, 0.44445, 0, 0, 0.5], + "8901": [-0.05555, 0.44445, 0, 0, 0.27778], + "8902": [-0.03472, 0.46528, 0, 0, 0.5], + "8904": [0.005, 0.505, 0, 0, 0.9], + "8942": [0.03, 0.903, 0, 0, 0.278], + "8943": [-0.19, 0.313, 0, 0, 1.172], + "8945": [-0.1, 0.823, 0, 0, 1.282], + "8968": [0.25, 0.75, 0, 0, 0.44445], + "8969": [0.25, 0.75, 0, 0, 0.44445], + "8970": [0.25, 0.75, 0, 0, 0.44445], + "8971": [0.25, 0.75, 0, 0, 0.44445], + "8994": [-0.14236, 0.35764, 0, 0, 1.0], + "8995": [-0.14236, 0.35764, 0, 0, 1.0], + "9136": [0.244, 0.744, 0, 0, 0.412], + "9137": [0.244, 0.745, 0, 0, 0.412], + "9651": [0.19444, 0.69444, 0, 0, 0.88889], + "9657": [-0.03472, 0.46528, 0, 0, 0.5], + "9661": [0.19444, 0.69444, 0, 0, 0.88889], + "9667": [-0.03472, 0.46528, 0, 0, 0.5], + "9711": [0.19444, 0.69444, 0, 0, 1.0], + "9824": [0.12963, 0.69444, 0, 0, 0.77778], + "9825": [0.12963, 0.69444, 0, 0, 0.77778], + "9826": [0.12963, 0.69444, 0, 0, 0.77778], + "9827": [0.12963, 0.69444, 0, 0, 0.77778], + "9837": [0, 0.75, 0, 0, 0.38889], + "9838": [0.19444, 0.69444, 0, 0, 0.38889], + "9839": [0.19444, 0.69444, 0, 0, 0.38889], + "10216": [0.25, 0.75, 0, 0, 0.38889], + "10217": [0.25, 0.75, 0, 0, 0.38889], + "10222": [0.244, 0.744, 0, 0, 0.412], + "10223": [0.244, 0.745, 0, 0, 0.412], + "10229": [0.011, 0.511, 0, 0, 1.609], + "10230": [0.011, 0.511, 0, 0, 1.638], + "10231": [0.011, 0.511, 0, 0, 1.859], + "10232": [0.024, 0.525, 0, 0, 1.609], + "10233": [0.024, 0.525, 0, 0, 1.638], + "10234": [0.024, 0.525, 0, 0, 1.858], + "10236": [0.011, 0.511, 0, 0, 1.638], + "10815": [0, 0.68333, 0, 0, 0.75], + "10927": [0.13597, 0.63597, 0, 0, 0.77778], + "10928": [0.13597, 0.63597, 0, 0, 0.77778], + "57376": [0.19444, 0.69444, 0, 0, 0] + }, + "Math-BoldItalic": { + "32": [0, 0, 0, 0, 0.25], + "48": [0, 0.44444, 0, 0, 0.575], + "49": [0, 0.44444, 0, 0, 0.575], + "50": [0, 0.44444, 0, 0, 0.575], + "51": [0.19444, 0.44444, 0, 0, 0.575], + "52": [0.19444, 0.44444, 0, 0, 0.575], + "53": [0.19444, 0.44444, 0, 0, 0.575], + "54": [0, 0.64444, 0, 0, 0.575], + "55": [0.19444, 0.44444, 0, 0, 0.575], + "56": [0, 0.64444, 0, 0, 0.575], + "57": [0.19444, 0.44444, 0, 0, 0.575], + "65": [0, 0.68611, 0, 0, 0.86944], + "66": [0, 0.68611, 0.04835, 0, 0.8664], + "67": [0, 0.68611, 0.06979, 0, 0.81694], + "68": [0, 0.68611, 0.03194, 0, 0.93812], + "69": [0, 0.68611, 0.05451, 0, 0.81007], + "70": [0, 0.68611, 0.15972, 0, 0.68889], + "71": [0, 0.68611, 0, 0, 0.88673], + "72": [0, 0.68611, 0.08229, 0, 0.98229], + "73": [0, 0.68611, 0.07778, 0, 0.51111], + "74": [0, 0.68611, 0.10069, 0, 0.63125], + "75": [0, 0.68611, 0.06979, 0, 0.97118], + "76": [0, 0.68611, 0, 0, 0.75555], + "77": [0, 0.68611, 0.11424, 0, 1.14201], + "78": [0, 0.68611, 0.11424, 0, 0.95034], + "79": [0, 0.68611, 0.03194, 0, 0.83666], + "80": [0, 0.68611, 0.15972, 0, 0.72309], + "81": [0.19444, 0.68611, 0, 0, 0.86861], + "82": [0, 0.68611, 0.00421, 0, 0.87235], + "83": [0, 0.68611, 0.05382, 0, 0.69271], + "84": [0, 0.68611, 0.15972, 0, 0.63663], + "85": [0, 0.68611, 0.11424, 0, 0.80027], + "86": [0, 0.68611, 0.25555, 0, 0.67778], + "87": [0, 0.68611, 0.15972, 0, 1.09305], + "88": [0, 0.68611, 0.07778, 0, 0.94722], + "89": [0, 0.68611, 0.25555, 0, 0.67458], + "90": [0, 0.68611, 0.06979, 0, 0.77257], + "97": [0, 0.44444, 0, 0, 0.63287], + "98": [0, 0.69444, 0, 0, 0.52083], + "99": [0, 0.44444, 0, 0, 0.51342], + "100": [0, 0.69444, 0, 0, 0.60972], + "101": [0, 0.44444, 0, 0, 0.55361], + "102": [0.19444, 0.69444, 0.11042, 0, 0.56806], + "103": [0.19444, 0.44444, 0.03704, 0, 0.5449], + "104": [0, 0.69444, 0, 0, 0.66759], + "105": [0, 0.69326, 0, 0, 0.4048], + "106": [0.19444, 0.69326, 0.0622, 0, 0.47083], + "107": [0, 0.69444, 0.01852, 0, 0.6037], + "108": [0, 0.69444, 0.0088, 0, 0.34815], + "109": [0, 0.44444, 0, 0, 1.0324], + "110": [0, 0.44444, 0, 0, 0.71296], + "111": [0, 0.44444, 0, 0, 0.58472], + "112": [0.19444, 0.44444, 0, 0, 0.60092], + "113": [0.19444, 0.44444, 0.03704, 0, 0.54213], + "114": [0, 0.44444, 0.03194, 0, 0.5287], + "115": [0, 0.44444, 0, 0, 0.53125], + "116": [0, 0.63492, 0, 0, 0.41528], + "117": [0, 0.44444, 0, 0, 0.68102], + "118": [0, 0.44444, 0.03704, 0, 0.56666], + "119": [0, 0.44444, 0.02778, 0, 0.83148], + "120": [0, 0.44444, 0, 0, 0.65903], + "121": [0.19444, 0.44444, 0.03704, 0, 0.59028], + "122": [0, 0.44444, 0.04213, 0, 0.55509], + "160": [0, 0, 0, 0, 0.25], + "915": [0, 0.68611, 0.15972, 0, 0.65694], + "916": [0, 0.68611, 0, 0, 0.95833], + "920": [0, 0.68611, 0.03194, 0, 0.86722], + "923": [0, 0.68611, 0, 0, 0.80555], + "926": [0, 0.68611, 0.07458, 0, 0.84125], + "928": [0, 0.68611, 0.08229, 0, 0.98229], + "931": [0, 0.68611, 0.05451, 0, 0.88507], + "933": [0, 0.68611, 0.15972, 0, 0.67083], + "934": [0, 0.68611, 0, 0, 0.76666], + "936": [0, 0.68611, 0.11653, 0, 0.71402], + "937": [0, 0.68611, 0.04835, 0, 0.8789], + "945": [0, 0.44444, 0, 0, 0.76064], + "946": [0.19444, 0.69444, 0.03403, 0, 0.65972], + "947": [0.19444, 0.44444, 0.06389, 0, 0.59003], + "948": [0, 0.69444, 0.03819, 0, 0.52222], + "949": [0, 0.44444, 0, 0, 0.52882], + "950": [0.19444, 0.69444, 0.06215, 0, 0.50833], + "951": [0.19444, 0.44444, 0.03704, 0, 0.6], + "952": [0, 0.69444, 0.03194, 0, 0.5618], + "953": [0, 0.44444, 0, 0, 0.41204], + "954": [0, 0.44444, 0, 0, 0.66759], + "955": [0, 0.69444, 0, 0, 0.67083], + "956": [0.19444, 0.44444, 0, 0, 0.70787], + "957": [0, 0.44444, 0.06898, 0, 0.57685], + "958": [0.19444, 0.69444, 0.03021, 0, 0.50833], + "959": [0, 0.44444, 0, 0, 0.58472], + "960": [0, 0.44444, 0.03704, 0, 0.68241], + "961": [0.19444, 0.44444, 0, 0, 0.6118], + "962": [0.09722, 0.44444, 0.07917, 0, 0.42361], + "963": [0, 0.44444, 0.03704, 0, 0.68588], + "964": [0, 0.44444, 0.13472, 0, 0.52083], + "965": [0, 0.44444, 0.03704, 0, 0.63055], + "966": [0.19444, 0.44444, 0, 0, 0.74722], + "967": [0.19444, 0.44444, 0, 0, 0.71805], + "968": [0.19444, 0.69444, 0.03704, 0, 0.75833], + "969": [0, 0.44444, 0.03704, 0, 0.71782], + "977": [0, 0.69444, 0, 0, 0.69155], + "981": [0.19444, 0.69444, 0, 0, 0.7125], + "982": [0, 0.44444, 0.03194, 0, 0.975], + "1009": [0.19444, 0.44444, 0, 0, 0.6118], + "1013": [0, 0.44444, 0, 0, 0.48333], + "57649": [0, 0.44444, 0, 0, 0.39352], + "57911": [0.19444, 0.44444, 0, 0, 0.43889] + }, + "Math-Italic": { + "32": [0, 0, 0, 0, 0.25], + "48": [0, 0.43056, 0, 0, 0.5], + "49": [0, 0.43056, 0, 0, 0.5], + "50": [0, 0.43056, 0, 0, 0.5], + "51": [0.19444, 0.43056, 0, 0, 0.5], + "52": [0.19444, 0.43056, 0, 0, 0.5], + "53": [0.19444, 0.43056, 0, 0, 0.5], + "54": [0, 0.64444, 0, 0, 0.5], + "55": [0.19444, 0.43056, 0, 0, 0.5], + "56": [0, 0.64444, 0, 0, 0.5], + "57": [0.19444, 0.43056, 0, 0, 0.5], + "65": [0, 0.68333, 0, 0.13889, 0.75], + "66": [0, 0.68333, 0.05017, 0.08334, 0.75851], + "67": [0, 0.68333, 0.07153, 0.08334, 0.71472], + "68": [0, 0.68333, 0.02778, 0.05556, 0.82792], + "69": [0, 0.68333, 0.05764, 0.08334, 0.7382], + "70": [0, 0.68333, 0.13889, 0.08334, 0.64306], + "71": [0, 0.68333, 0, 0.08334, 0.78625], + "72": [0, 0.68333, 0.08125, 0.05556, 0.83125], + "73": [0, 0.68333, 0.07847, 0.11111, 0.43958], + "74": [0, 0.68333, 0.09618, 0.16667, 0.55451], + "75": [0, 0.68333, 0.07153, 0.05556, 0.84931], + "76": [0, 0.68333, 0, 0.02778, 0.68056], + "77": [0, 0.68333, 0.10903, 0.08334, 0.97014], + "78": [0, 0.68333, 0.10903, 0.08334, 0.80347], + "79": [0, 0.68333, 0.02778, 0.08334, 0.76278], + "80": [0, 0.68333, 0.13889, 0.08334, 0.64201], + "81": [0.19444, 0.68333, 0, 0.08334, 0.79056], + "82": [0, 0.68333, 0.00773, 0.08334, 0.75929], + "83": [0, 0.68333, 0.05764, 0.08334, 0.6132], + "84": [0, 0.68333, 0.13889, 0.08334, 0.58438], + "85": [0, 0.68333, 0.10903, 0.02778, 0.68278], + "86": [0, 0.68333, 0.22222, 0, 0.58333], + "87": [0, 0.68333, 0.13889, 0, 0.94445], + "88": [0, 0.68333, 0.07847, 0.08334, 0.82847], + "89": [0, 0.68333, 0.22222, 0, 0.58056], + "90": [0, 0.68333, 0.07153, 0.08334, 0.68264], + "97": [0, 0.43056, 0, 0, 0.52859], + "98": [0, 0.69444, 0, 0, 0.42917], + "99": [0, 0.43056, 0, 0.05556, 0.43276], + "100": [0, 0.69444, 0, 0.16667, 0.52049], + "101": [0, 0.43056, 0, 0.05556, 0.46563], + "102": [0.19444, 0.69444, 0.10764, 0.16667, 0.48959], + "103": [0.19444, 0.43056, 0.03588, 0.02778, 0.47697], + "104": [0, 0.69444, 0, 0, 0.57616], + "105": [0, 0.65952, 0, 0, 0.34451], + "106": [0.19444, 0.65952, 0.05724, 0, 0.41181], + "107": [0, 0.69444, 0.03148, 0, 0.5206], + "108": [0, 0.69444, 0.01968, 0.08334, 0.29838], + "109": [0, 0.43056, 0, 0, 0.87801], + "110": [0, 0.43056, 0, 0, 0.60023], + "111": [0, 0.43056, 0, 0.05556, 0.48472], + "112": [0.19444, 0.43056, 0, 0.08334, 0.50313], + "113": [0.19444, 0.43056, 0.03588, 0.08334, 0.44641], + "114": [0, 0.43056, 0.02778, 0.05556, 0.45116], + "115": [0, 0.43056, 0, 0.05556, 0.46875], + "116": [0, 0.61508, 0, 0.08334, 0.36111], + "117": [0, 0.43056, 0, 0.02778, 0.57246], + "118": [0, 0.43056, 0.03588, 0.02778, 0.48472], + "119": [0, 0.43056, 0.02691, 0.08334, 0.71592], + "120": [0, 0.43056, 0, 0.02778, 0.57153], + "121": [0.19444, 0.43056, 0.03588, 0.05556, 0.49028], + "122": [0, 0.43056, 0.04398, 0.05556, 0.46505], + "160": [0, 0, 0, 0, 0.25], + "915": [0, 0.68333, 0.13889, 0.08334, 0.61528], + "916": [0, 0.68333, 0, 0.16667, 0.83334], + "920": [0, 0.68333, 0.02778, 0.08334, 0.76278], + "923": [0, 0.68333, 0, 0.16667, 0.69445], + "926": [0, 0.68333, 0.07569, 0.08334, 0.74236], + "928": [0, 0.68333, 0.08125, 0.05556, 0.83125], + "931": [0, 0.68333, 0.05764, 0.08334, 0.77986], + "933": [0, 0.68333, 0.13889, 0.05556, 0.58333], + "934": [0, 0.68333, 0, 0.08334, 0.66667], + "936": [0, 0.68333, 0.11, 0.05556, 0.61222], + "937": [0, 0.68333, 0.05017, 0.08334, 0.7724], + "945": [0, 0.43056, 0.0037, 0.02778, 0.6397], + "946": [0.19444, 0.69444, 0.05278, 0.08334, 0.56563], + "947": [0.19444, 0.43056, 0.05556, 0, 0.51773], + "948": [0, 0.69444, 0.03785, 0.05556, 0.44444], + "949": [0, 0.43056, 0, 0.08334, 0.46632], + "950": [0.19444, 0.69444, 0.07378, 0.08334, 0.4375], + "951": [0.19444, 0.43056, 0.03588, 0.05556, 0.49653], + "952": [0, 0.69444, 0.02778, 0.08334, 0.46944], + "953": [0, 0.43056, 0, 0.05556, 0.35394], + "954": [0, 0.43056, 0, 0, 0.57616], + "955": [0, 0.69444, 0, 0, 0.58334], + "956": [0.19444, 0.43056, 0, 0.02778, 0.60255], + "957": [0, 0.43056, 0.06366, 0.02778, 0.49398], + "958": [0.19444, 0.69444, 0.04601, 0.11111, 0.4375], + "959": [0, 0.43056, 0, 0.05556, 0.48472], + "960": [0, 0.43056, 0.03588, 0, 0.57003], + "961": [0.19444, 0.43056, 0, 0.08334, 0.51702], + "962": [0.09722, 0.43056, 0.07986, 0.08334, 0.36285], + "963": [0, 0.43056, 0.03588, 0, 0.57141], + "964": [0, 0.43056, 0.1132, 0.02778, 0.43715], + "965": [0, 0.43056, 0.03588, 0.02778, 0.54028], + "966": [0.19444, 0.43056, 0, 0.08334, 0.65417], + "967": [0.19444, 0.43056, 0, 0.05556, 0.62569], + "968": [0.19444, 0.69444, 0.03588, 0.11111, 0.65139], + "969": [0, 0.43056, 0.03588, 0, 0.62245], + "977": [0, 0.69444, 0, 0.08334, 0.59144], + "981": [0.19444, 0.69444, 0, 0.08334, 0.59583], + "982": [0, 0.43056, 0.02778, 0, 0.82813], + "1009": [0.19444, 0.43056, 0, 0.08334, 0.51702], + "1013": [0, 0.43056, 0, 0.05556, 0.4059], + "57649": [0, 0.43056, 0, 0.02778, 0.32246], + "57911": [0.19444, 0.43056, 0, 0.08334, 0.38403] + }, + "SansSerif-Bold": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0, 0, 0.36667], + "34": [0, 0.69444, 0, 0, 0.55834], + "35": [0.19444, 0.69444, 0, 0, 0.91667], + "36": [0.05556, 0.75, 0, 0, 0.55], + "37": [0.05556, 0.75, 0, 0, 1.02912], + "38": [0, 0.69444, 0, 0, 0.83056], + "39": [0, 0.69444, 0, 0, 0.30556], + "40": [0.25, 0.75, 0, 0, 0.42778], + "41": [0.25, 0.75, 0, 0, 0.42778], + "42": [0, 0.75, 0, 0, 0.55], + "43": [0.11667, 0.61667, 0, 0, 0.85556], + "44": [0.10556, 0.13056, 0, 0, 0.30556], + "45": [0, 0.45833, 0, 0, 0.36667], + "46": [0, 0.13056, 0, 0, 0.30556], + "47": [0.25, 0.75, 0, 0, 0.55], + "48": [0, 0.69444, 0, 0, 0.55], + "49": [0, 0.69444, 0, 0, 0.55], + "50": [0, 0.69444, 0, 0, 0.55], + "51": [0, 0.69444, 0, 0, 0.55], + "52": [0, 0.69444, 0, 0, 0.55], + "53": [0, 0.69444, 0, 0, 0.55], + "54": [0, 0.69444, 0, 0, 0.55], + "55": [0, 0.69444, 0, 0, 0.55], + "56": [0, 0.69444, 0, 0, 0.55], + "57": [0, 0.69444, 0, 0, 0.55], + "58": [0, 0.45833, 0, 0, 0.30556], + "59": [0.10556, 0.45833, 0, 0, 0.30556], + "61": [-0.09375, 0.40625, 0, 0, 0.85556], + "63": [0, 0.69444, 0, 0, 0.51945], + "64": [0, 0.69444, 0, 0, 0.73334], + "65": [0, 0.69444, 0, 0, 0.73334], + "66": [0, 0.69444, 0, 0, 0.73334], + "67": [0, 0.69444, 0, 0, 0.70278], + "68": [0, 0.69444, 0, 0, 0.79445], + "69": [0, 0.69444, 0, 0, 0.64167], + "70": [0, 0.69444, 0, 0, 0.61111], + "71": [0, 0.69444, 0, 0, 0.73334], + "72": [0, 0.69444, 0, 0, 0.79445], + "73": [0, 0.69444, 0, 0, 0.33056], + "74": [0, 0.69444, 0, 0, 0.51945], + "75": [0, 0.69444, 0, 0, 0.76389], + "76": [0, 0.69444, 0, 0, 0.58056], + "77": [0, 0.69444, 0, 0, 0.97778], + "78": [0, 0.69444, 0, 0, 0.79445], + "79": [0, 0.69444, 0, 0, 0.79445], + "80": [0, 0.69444, 0, 0, 0.70278], + "81": [0.10556, 0.69444, 0, 0, 0.79445], + "82": [0, 0.69444, 0, 0, 0.70278], + "83": [0, 0.69444, 0, 0, 0.61111], + "84": [0, 0.69444, 0, 0, 0.73334], + "85": [0, 0.69444, 0, 0, 0.76389], + "86": [0, 0.69444, 0.01528, 0, 0.73334], + "87": [0, 0.69444, 0.01528, 0, 1.03889], + "88": [0, 0.69444, 0, 0, 0.73334], + "89": [0, 0.69444, 0.0275, 0, 0.73334], + "90": [0, 0.69444, 0, 0, 0.67223], + "91": [0.25, 0.75, 0, 0, 0.34306], + "93": [0.25, 0.75, 0, 0, 0.34306], + "94": [0, 0.69444, 0, 0, 0.55], + "95": [0.35, 0.10833, 0.03056, 0, 0.55], + "97": [0, 0.45833, 0, 0, 0.525], + "98": [0, 0.69444, 0, 0, 0.56111], + "99": [0, 0.45833, 0, 0, 0.48889], + "100": [0, 0.69444, 0, 0, 0.56111], + "101": [0, 0.45833, 0, 0, 0.51111], + "102": [0, 0.69444, 0.07639, 0, 0.33611], + "103": [0.19444, 0.45833, 0.01528, 0, 0.55], + "104": [0, 0.69444, 0, 0, 0.56111], + "105": [0, 0.69444, 0, 0, 0.25556], + "106": [0.19444, 0.69444, 0, 0, 0.28611], + "107": [0, 0.69444, 0, 0, 0.53056], + "108": [0, 0.69444, 0, 0, 0.25556], + "109": [0, 0.45833, 0, 0, 0.86667], + "110": [0, 0.45833, 0, 0, 0.56111], + "111": [0, 0.45833, 0, 0, 0.55], + "112": [0.19444, 0.45833, 0, 0, 0.56111], + "113": [0.19444, 0.45833, 0, 0, 0.56111], + "114": [0, 0.45833, 0.01528, 0, 0.37222], + "115": [0, 0.45833, 0, 0, 0.42167], + "116": [0, 0.58929, 0, 0, 0.40417], + "117": [0, 0.45833, 0, 0, 0.56111], + "118": [0, 0.45833, 0.01528, 0, 0.5], + "119": [0, 0.45833, 0.01528, 0, 0.74445], + "120": [0, 0.45833, 0, 0, 0.5], + "121": [0.19444, 0.45833, 0.01528, 0, 0.5], + "122": [0, 0.45833, 0, 0, 0.47639], + "126": [0.35, 0.34444, 0, 0, 0.55], + "160": [0, 0, 0, 0, 0.25], + "168": [0, 0.69444, 0, 0, 0.55], + "176": [0, 0.69444, 0, 0, 0.73334], + "180": [0, 0.69444, 0, 0, 0.55], + "184": [0.17014, 0, 0, 0, 0.48889], + "305": [0, 0.45833, 0, 0, 0.25556], + "567": [0.19444, 0.45833, 0, 0, 0.28611], + "710": [0, 0.69444, 0, 0, 0.55], + "711": [0, 0.63542, 0, 0, 0.55], + "713": [0, 0.63778, 0, 0, 0.55], + "728": [0, 0.69444, 0, 0, 0.55], + "729": [0, 0.69444, 0, 0, 0.30556], + "730": [0, 0.69444, 0, 0, 0.73334], + "732": [0, 0.69444, 0, 0, 0.55], + "733": [0, 0.69444, 0, 0, 0.55], + "915": [0, 0.69444, 0, 0, 0.58056], + "916": [0, 0.69444, 0, 0, 0.91667], + "920": [0, 0.69444, 0, 0, 0.85556], + "923": [0, 0.69444, 0, 0, 0.67223], + "926": [0, 0.69444, 0, 0, 0.73334], + "928": [0, 0.69444, 0, 0, 0.79445], + "931": [0, 0.69444, 0, 0, 0.79445], + "933": [0, 0.69444, 0, 0, 0.85556], + "934": [0, 0.69444, 0, 0, 0.79445], + "936": [0, 0.69444, 0, 0, 0.85556], + "937": [0, 0.69444, 0, 0, 0.79445], + "8211": [0, 0.45833, 0.03056, 0, 0.55], + "8212": [0, 0.45833, 0.03056, 0, 1.10001], + "8216": [0, 0.69444, 0, 0, 0.30556], + "8217": [0, 0.69444, 0, 0, 0.30556], + "8220": [0, 0.69444, 0, 0, 0.55834], + "8221": [0, 0.69444, 0, 0, 0.55834] + }, + "SansSerif-Italic": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0.05733, 0, 0.31945], + "34": [0, 0.69444, 0.00316, 0, 0.5], + "35": [0.19444, 0.69444, 0.05087, 0, 0.83334], + "36": [0.05556, 0.75, 0.11156, 0, 0.5], + "37": [0.05556, 0.75, 0.03126, 0, 0.83334], + "38": [0, 0.69444, 0.03058, 0, 0.75834], + "39": [0, 0.69444, 0.07816, 0, 0.27778], + "40": [0.25, 0.75, 0.13164, 0, 0.38889], + "41": [0.25, 0.75, 0.02536, 0, 0.38889], + "42": [0, 0.75, 0.11775, 0, 0.5], + "43": [0.08333, 0.58333, 0.02536, 0, 0.77778], + "44": [0.125, 0.08333, 0, 0, 0.27778], + "45": [0, 0.44444, 0.01946, 0, 0.33333], + "46": [0, 0.08333, 0, 0, 0.27778], + "47": [0.25, 0.75, 0.13164, 0, 0.5], + "48": [0, 0.65556, 0.11156, 0, 0.5], + "49": [0, 0.65556, 0.11156, 0, 0.5], + "50": [0, 0.65556, 0.11156, 0, 0.5], + "51": [0, 0.65556, 0.11156, 0, 0.5], + "52": [0, 0.65556, 0.11156, 0, 0.5], + "53": [0, 0.65556, 0.11156, 0, 0.5], + "54": [0, 0.65556, 0.11156, 0, 0.5], + "55": [0, 0.65556, 0.11156, 0, 0.5], + "56": [0, 0.65556, 0.11156, 0, 0.5], + "57": [0, 0.65556, 0.11156, 0, 0.5], + "58": [0, 0.44444, 0.02502, 0, 0.27778], + "59": [0.125, 0.44444, 0.02502, 0, 0.27778], + "61": [-0.13, 0.37, 0.05087, 0, 0.77778], + "63": [0, 0.69444, 0.11809, 0, 0.47222], + "64": [0, 0.69444, 0.07555, 0, 0.66667], + "65": [0, 0.69444, 0, 0, 0.66667], + "66": [0, 0.69444, 0.08293, 0, 0.66667], + "67": [0, 0.69444, 0.11983, 0, 0.63889], + "68": [0, 0.69444, 0.07555, 0, 0.72223], + "69": [0, 0.69444, 0.11983, 0, 0.59722], + "70": [0, 0.69444, 0.13372, 0, 0.56945], + "71": [0, 0.69444, 0.11983, 0, 0.66667], + "72": [0, 0.69444, 0.08094, 0, 0.70834], + "73": [0, 0.69444, 0.13372, 0, 0.27778], + "74": [0, 0.69444, 0.08094, 0, 0.47222], + "75": [0, 0.69444, 0.11983, 0, 0.69445], + "76": [0, 0.69444, 0, 0, 0.54167], + "77": [0, 0.69444, 0.08094, 0, 0.875], + "78": [0, 0.69444, 0.08094, 0, 0.70834], + "79": [0, 0.69444, 0.07555, 0, 0.73611], + "80": [0, 0.69444, 0.08293, 0, 0.63889], + "81": [0.125, 0.69444, 0.07555, 0, 0.73611], + "82": [0, 0.69444, 0.08293, 0, 0.64584], + "83": [0, 0.69444, 0.09205, 0, 0.55556], + "84": [0, 0.69444, 0.13372, 0, 0.68056], + "85": [0, 0.69444, 0.08094, 0, 0.6875], + "86": [0, 0.69444, 0.1615, 0, 0.66667], + "87": [0, 0.69444, 0.1615, 0, 0.94445], + "88": [0, 0.69444, 0.13372, 0, 0.66667], + "89": [0, 0.69444, 0.17261, 0, 0.66667], + "90": [0, 0.69444, 0.11983, 0, 0.61111], + "91": [0.25, 0.75, 0.15942, 0, 0.28889], + "93": [0.25, 0.75, 0.08719, 0, 0.28889], + "94": [0, 0.69444, 0.0799, 0, 0.5], + "95": [0.35, 0.09444, 0.08616, 0, 0.5], + "97": [0, 0.44444, 0.00981, 0, 0.48056], + "98": [0, 0.69444, 0.03057, 0, 0.51667], + "99": [0, 0.44444, 0.08336, 0, 0.44445], + "100": [0, 0.69444, 0.09483, 0, 0.51667], + "101": [0, 0.44444, 0.06778, 0, 0.44445], + "102": [0, 0.69444, 0.21705, 0, 0.30556], + "103": [0.19444, 0.44444, 0.10836, 0, 0.5], + "104": [0, 0.69444, 0.01778, 0, 0.51667], + "105": [0, 0.67937, 0.09718, 0, 0.23889], + "106": [0.19444, 0.67937, 0.09162, 0, 0.26667], + "107": [0, 0.69444, 0.08336, 0, 0.48889], + "108": [0, 0.69444, 0.09483, 0, 0.23889], + "109": [0, 0.44444, 0.01778, 0, 0.79445], + "110": [0, 0.44444, 0.01778, 0, 0.51667], + "111": [0, 0.44444, 0.06613, 0, 0.5], + "112": [0.19444, 0.44444, 0.0389, 0, 0.51667], + "113": [0.19444, 0.44444, 0.04169, 0, 0.51667], + "114": [0, 0.44444, 0.10836, 0, 0.34167], + "115": [0, 0.44444, 0.0778, 0, 0.38333], + "116": [0, 0.57143, 0.07225, 0, 0.36111], + "117": [0, 0.44444, 0.04169, 0, 0.51667], + "118": [0, 0.44444, 0.10836, 0, 0.46111], + "119": [0, 0.44444, 0.10836, 0, 0.68334], + "120": [0, 0.44444, 0.09169, 0, 0.46111], + "121": [0.19444, 0.44444, 0.10836, 0, 0.46111], + "122": [0, 0.44444, 0.08752, 0, 0.43472], + "126": [0.35, 0.32659, 0.08826, 0, 0.5], + "160": [0, 0, 0, 0, 0.25], + "168": [0, 0.67937, 0.06385, 0, 0.5], + "176": [0, 0.69444, 0, 0, 0.73752], + "184": [0.17014, 0, 0, 0, 0.44445], + "305": [0, 0.44444, 0.04169, 0, 0.23889], + "567": [0.19444, 0.44444, 0.04169, 0, 0.26667], + "710": [0, 0.69444, 0.0799, 0, 0.5], + "711": [0, 0.63194, 0.08432, 0, 0.5], + "713": [0, 0.60889, 0.08776, 0, 0.5], + "714": [0, 0.69444, 0.09205, 0, 0.5], + "715": [0, 0.69444, 0, 0, 0.5], + "728": [0, 0.69444, 0.09483, 0, 0.5], + "729": [0, 0.67937, 0.07774, 0, 0.27778], + "730": [0, 0.69444, 0, 0, 0.73752], + "732": [0, 0.67659, 0.08826, 0, 0.5], + "733": [0, 0.69444, 0.09205, 0, 0.5], + "915": [0, 0.69444, 0.13372, 0, 0.54167], + "916": [0, 0.69444, 0, 0, 0.83334], + "920": [0, 0.69444, 0.07555, 0, 0.77778], + "923": [0, 0.69444, 0, 0, 0.61111], + "926": [0, 0.69444, 0.12816, 0, 0.66667], + "928": [0, 0.69444, 0.08094, 0, 0.70834], + "931": [0, 0.69444, 0.11983, 0, 0.72222], + "933": [0, 0.69444, 0.09031, 0, 0.77778], + "934": [0, 0.69444, 0.04603, 0, 0.72222], + "936": [0, 0.69444, 0.09031, 0, 0.77778], + "937": [0, 0.69444, 0.08293, 0, 0.72222], + "8211": [0, 0.44444, 0.08616, 0, 0.5], + "8212": [0, 0.44444, 0.08616, 0, 1.0], + "8216": [0, 0.69444, 0.07816, 0, 0.27778], + "8217": [0, 0.69444, 0.07816, 0, 0.27778], + "8220": [0, 0.69444, 0.14205, 0, 0.5], + "8221": [0, 0.69444, 0.00316, 0, 0.5] + }, + "SansSerif-Regular": { + "32": [0, 0, 0, 0, 0.25], + "33": [0, 0.69444, 0, 0, 0.31945], + "34": [0, 0.69444, 0, 0, 0.5], + "35": [0.19444, 0.69444, 0, 0, 0.83334], + "36": [0.05556, 0.75, 0, 0, 0.5], + "37": [0.05556, 0.75, 0, 0, 0.83334], + "38": [0, 0.69444, 0, 0, 0.75834], + "39": [0, 0.69444, 0, 0, 0.27778], + "40": [0.25, 0.75, 0, 0, 0.38889], + "41": [0.25, 0.75, 0, 0, 0.38889], + "42": [0, 0.75, 0, 0, 0.5], + "43": [0.08333, 0.58333, 0, 0, 0.77778], + "44": [0.125, 0.08333, 0, 0, 0.27778], + "45": [0, 0.44444, 0, 0, 0.33333], + "46": [0, 0.08333, 0, 0, 0.27778], + "47": [0.25, 0.75, 0, 0, 0.5], + "48": [0, 0.65556, 0, 0, 0.5], + "49": [0, 0.65556, 0, 0, 0.5], + "50": [0, 0.65556, 0, 0, 0.5], + "51": [0, 0.65556, 0, 0, 0.5], + "52": [0, 0.65556, 0, 0, 0.5], + "53": [0, 0.65556, 0, 0, 0.5], + "54": [0, 0.65556, 0, 0, 0.5], + "55": [0, 0.65556, 0, 0, 0.5], + "56": [0, 0.65556, 0, 0, 0.5], + "57": [0, 0.65556, 0, 0, 0.5], + "58": [0, 0.44444, 0, 0, 0.27778], + "59": [0.125, 0.44444, 0, 0, 0.27778], + "61": [-0.13, 0.37, 0, 0, 0.77778], + "63": [0, 0.69444, 0, 0, 0.47222], + "64": [0, 0.69444, 0, 0, 0.66667], + "65": [0, 0.69444, 0, 0, 0.66667], + "66": [0, 0.69444, 0, 0, 0.66667], + "67": [0, 0.69444, 0, 0, 0.63889], + "68": [0, 0.69444, 0, 0, 0.72223], + "69": [0, 0.69444, 0, 0, 0.59722], + "70": [0, 0.69444, 0, 0, 0.56945], + "71": [0, 0.69444, 0, 0, 0.66667], + "72": [0, 0.69444, 0, 0, 0.70834], + "73": [0, 0.69444, 0, 0, 0.27778], + "74": [0, 0.69444, 0, 0, 0.47222], + "75": [0, 0.69444, 0, 0, 0.69445], + "76": [0, 0.69444, 0, 0, 0.54167], + "77": [0, 0.69444, 0, 0, 0.875], + "78": [0, 0.69444, 0, 0, 0.70834], + "79": [0, 0.69444, 0, 0, 0.73611], + "80": [0, 0.69444, 0, 0, 0.63889], + "81": [0.125, 0.69444, 0, 0, 0.73611], + "82": [0, 0.69444, 0, 0, 0.64584], + "83": [0, 0.69444, 0, 0, 0.55556], + "84": [0, 0.69444, 0, 0, 0.68056], + "85": [0, 0.69444, 0, 0, 0.6875], + "86": [0, 0.69444, 0.01389, 0, 0.66667], + "87": [0, 0.69444, 0.01389, 0, 0.94445], + "88": [0, 0.69444, 0, 0, 0.66667], + "89": [0, 0.69444, 0.025, 0, 0.66667], + "90": [0, 0.69444, 0, 0, 0.61111], + "91": [0.25, 0.75, 0, 0, 0.28889], + "93": [0.25, 0.75, 0, 0, 0.28889], + "94": [0, 0.69444, 0, 0, 0.5], + "95": [0.35, 0.09444, 0.02778, 0, 0.5], + "97": [0, 0.44444, 0, 0, 0.48056], + "98": [0, 0.69444, 0, 0, 0.51667], + "99": [0, 0.44444, 0, 0, 0.44445], + "100": [0, 0.69444, 0, 0, 0.51667], + "101": [0, 0.44444, 0, 0, 0.44445], + "102": [0, 0.69444, 0.06944, 0, 0.30556], + "103": [0.19444, 0.44444, 0.01389, 0, 0.5], + "104": [0, 0.69444, 0, 0, 0.51667], + "105": [0, 0.67937, 0, 0, 0.23889], + "106": [0.19444, 0.67937, 0, 0, 0.26667], + "107": [0, 0.69444, 0, 0, 0.48889], + "108": [0, 0.69444, 0, 0, 0.23889], + "109": [0, 0.44444, 0, 0, 0.79445], + "110": [0, 0.44444, 0, 0, 0.51667], + "111": [0, 0.44444, 0, 0, 0.5], + "112": [0.19444, 0.44444, 0, 0, 0.51667], + "113": [0.19444, 0.44444, 0, 0, 0.51667], + "114": [0, 0.44444, 0.01389, 0, 0.34167], + "115": [0, 0.44444, 0, 0, 0.38333], + "116": [0, 0.57143, 0, 0, 0.36111], + "117": [0, 0.44444, 0, 0, 0.51667], + "118": [0, 0.44444, 0.01389, 0, 0.46111], + "119": [0, 0.44444, 0.01389, 0, 0.68334], + "120": [0, 0.44444, 0, 0, 0.46111], + "121": [0.19444, 0.44444, 0.01389, 0, 0.46111], + "122": [0, 0.44444, 0, 0, 0.43472], + "126": [0.35, 0.32659, 0, 0, 0.5], + "160": [0, 0, 0, 0, 0.25], + "168": [0, 0.67937, 0, 0, 0.5], + "176": [0, 0.69444, 0, 0, 0.66667], + "184": [0.17014, 0, 0, 0, 0.44445], + "305": [0, 0.44444, 0, 0, 0.23889], + "567": [0.19444, 0.44444, 0, 0, 0.26667], + "710": [0, 0.69444, 0, 0, 0.5], + "711": [0, 0.63194, 0, 0, 0.5], + "713": [0, 0.60889, 0, 0, 0.5], + "714": [0, 0.69444, 0, 0, 0.5], + "715": [0, 0.69444, 0, 0, 0.5], + "728": [0, 0.69444, 0, 0, 0.5], + "729": [0, 0.67937, 0, 0, 0.27778], + "730": [0, 0.69444, 0, 0, 0.66667], + "732": [0, 0.67659, 0, 0, 0.5], + "733": [0, 0.69444, 0, 0, 0.5], + "915": [0, 0.69444, 0, 0, 0.54167], + "916": [0, 0.69444, 0, 0, 0.83334], + "920": [0, 0.69444, 0, 0, 0.77778], + "923": [0, 0.69444, 0, 0, 0.61111], + "926": [0, 0.69444, 0, 0, 0.66667], + "928": [0, 0.69444, 0, 0, 0.70834], + "931": [0, 0.69444, 0, 0, 0.72222], + "933": [0, 0.69444, 0, 0, 0.77778], + "934": [0, 0.69444, 0, 0, 0.72222], + "936": [0, 0.69444, 0, 0, 0.77778], + "937": [0, 0.69444, 0, 0, 0.72222], + "8211": [0, 0.44444, 0.02778, 0, 0.5], + "8212": [0, 0.44444, 0.02778, 0, 1.0], + "8216": [0, 0.69444, 0, 0, 0.27778], + "8217": [0, 0.69444, 0, 0, 0.27778], + "8220": [0, 0.69444, 0, 0, 0.5], + "8221": [0, 0.69444, 0, 0, 0.5] + }, + "Script-Regular": { + "32": [0, 0, 0, 0, 0.25], + "65": [0, 0.7, 0.22925, 0, 0.80253], + "66": [0, 0.7, 0.04087, 0, 0.90757], + "67": [0, 0.7, 0.1689, 0, 0.66619], + "68": [0, 0.7, 0.09371, 0, 0.77443], + "69": [0, 0.7, 0.18583, 0, 0.56162], + "70": [0, 0.7, 0.13634, 0, 0.89544], + "71": [0, 0.7, 0.17322, 0, 0.60961], + "72": [0, 0.7, 0.29694, 0, 0.96919], + "73": [0, 0.7, 0.19189, 0, 0.80907], + "74": [0.27778, 0.7, 0.19189, 0, 1.05159], + "75": [0, 0.7, 0.31259, 0, 0.91364], + "76": [0, 0.7, 0.19189, 0, 0.87373], + "77": [0, 0.7, 0.15981, 0, 1.08031], + "78": [0, 0.7, 0.3525, 0, 0.9015], + "79": [0, 0.7, 0.08078, 0, 0.73787], + "80": [0, 0.7, 0.08078, 0, 1.01262], + "81": [0, 0.7, 0.03305, 0, 0.88282], + "82": [0, 0.7, 0.06259, 0, 0.85], + "83": [0, 0.7, 0.19189, 0, 0.86767], + "84": [0, 0.7, 0.29087, 0, 0.74697], + "85": [0, 0.7, 0.25815, 0, 0.79996], + "86": [0, 0.7, 0.27523, 0, 0.62204], + "87": [0, 0.7, 0.27523, 0, 0.80532], + "88": [0, 0.7, 0.26006, 0, 0.94445], + "89": [0, 0.7, 0.2939, 0, 0.70961], + "90": [0, 0.7, 0.24037, 0, 0.8212], + "160": [0, 0, 0, 0, 0.25] + }, + "Size1-Regular": { + "32": [0, 0, 0, 0, 0.25], + "40": [0.35001, 0.85, 0, 0, 0.45834], + "41": [0.35001, 0.85, 0, 0, 0.45834], + "47": [0.35001, 0.85, 0, 0, 0.57778], + "91": [0.35001, 0.85, 0, 0, 0.41667], + "92": [0.35001, 0.85, 0, 0, 0.57778], + "93": [0.35001, 0.85, 0, 0, 0.41667], + "123": [0.35001, 0.85, 0, 0, 0.58334], + "125": [0.35001, 0.85, 0, 0, 0.58334], + "160": [0, 0, 0, 0, 0.25], + "710": [0, 0.72222, 0, 0, 0.55556], + "732": [0, 0.72222, 0, 0, 0.55556], + "770": [0, 0.72222, 0, 0, 0.55556], + "771": [0, 0.72222, 0, 0, 0.55556], + "8214": [-0.00099, 0.601, 0, 0, 0.77778], + "8593": [1e-05, 0.6, 0, 0, 0.66667], + "8595": [1e-05, 0.6, 0, 0, 0.66667], + "8657": [1e-05, 0.6, 0, 0, 0.77778], + "8659": [1e-05, 0.6, 0, 0, 0.77778], + "8719": [0.25001, 0.75, 0, 0, 0.94445], + "8720": [0.25001, 0.75, 0, 0, 0.94445], + "8721": [0.25001, 0.75, 0, 0, 1.05556], + "8730": [0.35001, 0.85, 0, 0, 1.0], + "8739": [-0.00599, 0.606, 0, 0, 0.33333], + "8741": [-0.00599, 0.606, 0, 0, 0.55556], + "8747": [0.30612, 0.805, 0.19445, 0, 0.47222], + "8748": [0.306, 0.805, 0.19445, 0, 0.47222], + "8749": [0.306, 0.805, 0.19445, 0, 0.47222], + "8750": [0.30612, 0.805, 0.19445, 0, 0.47222], + "8896": [0.25001, 0.75, 0, 0, 0.83334], + "8897": [0.25001, 0.75, 0, 0, 0.83334], + "8898": [0.25001, 0.75, 0, 0, 0.83334], + "8899": [0.25001, 0.75, 0, 0, 0.83334], + "8968": [0.35001, 0.85, 0, 0, 0.47222], + "8969": [0.35001, 0.85, 0, 0, 0.47222], + "8970": [0.35001, 0.85, 0, 0, 0.47222], + "8971": [0.35001, 0.85, 0, 0, 0.47222], + "9168": [-0.00099, 0.601, 0, 0, 0.66667], + "10216": [0.35001, 0.85, 0, 0, 0.47222], + "10217": [0.35001, 0.85, 0, 0, 0.47222], + "10752": [0.25001, 0.75, 0, 0, 1.11111], + "10753": [0.25001, 0.75, 0, 0, 1.11111], + "10754": [0.25001, 0.75, 0, 0, 1.11111], + "10756": [0.25001, 0.75, 0, 0, 0.83334], + "10758": [0.25001, 0.75, 0, 0, 0.83334] + }, + "Size2-Regular": { + "32": [0, 0, 0, 0, 0.25], + "40": [0.65002, 1.15, 0, 0, 0.59722], + "41": [0.65002, 1.15, 0, 0, 0.59722], + "47": [0.65002, 1.15, 0, 0, 0.81111], + "91": [0.65002, 1.15, 0, 0, 0.47222], + "92": [0.65002, 1.15, 0, 0, 0.81111], + "93": [0.65002, 1.15, 0, 0, 0.47222], + "123": [0.65002, 1.15, 0, 0, 0.66667], + "125": [0.65002, 1.15, 0, 0, 0.66667], + "160": [0, 0, 0, 0, 0.25], + "710": [0, 0.75, 0, 0, 1.0], + "732": [0, 0.75, 0, 0, 1.0], + "770": [0, 0.75, 0, 0, 1.0], + "771": [0, 0.75, 0, 0, 1.0], + "8719": [0.55001, 1.05, 0, 0, 1.27778], + "8720": [0.55001, 1.05, 0, 0, 1.27778], + "8721": [0.55001, 1.05, 0, 0, 1.44445], + "8730": [0.65002, 1.15, 0, 0, 1.0], + "8747": [0.86225, 1.36, 0.44445, 0, 0.55556], + "8748": [0.862, 1.36, 0.44445, 0, 0.55556], + "8749": [0.862, 1.36, 0.44445, 0, 0.55556], + "8750": [0.86225, 1.36, 0.44445, 0, 0.55556], + "8896": [0.55001, 1.05, 0, 0, 1.11111], + "8897": [0.55001, 1.05, 0, 0, 1.11111], + "8898": [0.55001, 1.05, 0, 0, 1.11111], + "8899": [0.55001, 1.05, 0, 0, 1.11111], + "8968": [0.65002, 1.15, 0, 0, 0.52778], + "8969": [0.65002, 1.15, 0, 0, 0.52778], + "8970": [0.65002, 1.15, 0, 0, 0.52778], + "8971": [0.65002, 1.15, 0, 0, 0.52778], + "10216": [0.65002, 1.15, 0, 0, 0.61111], + "10217": [0.65002, 1.15, 0, 0, 0.61111], + "10752": [0.55001, 1.05, 0, 0, 1.51112], + "10753": [0.55001, 1.05, 0, 0, 1.51112], + "10754": [0.55001, 1.05, 0, 0, 1.51112], + "10756": [0.55001, 1.05, 0, 0, 1.11111], + "10758": [0.55001, 1.05, 0, 0, 1.11111] + }, + "Size3-Regular": { + "32": [0, 0, 0, 0, 0.25], + "40": [0.95003, 1.45, 0, 0, 0.73611], + "41": [0.95003, 1.45, 0, 0, 0.73611], + "47": [0.95003, 1.45, 0, 0, 1.04445], + "91": [0.95003, 1.45, 0, 0, 0.52778], + "92": [0.95003, 1.45, 0, 0, 1.04445], + "93": [0.95003, 1.45, 0, 0, 0.52778], + "123": [0.95003, 1.45, 0, 0, 0.75], + "125": [0.95003, 1.45, 0, 0, 0.75], + "160": [0, 0, 0, 0, 0.25], + "710": [0, 0.75, 0, 0, 1.44445], + "732": [0, 0.75, 0, 0, 1.44445], + "770": [0, 0.75, 0, 0, 1.44445], + "771": [0, 0.75, 0, 0, 1.44445], + "8730": [0.95003, 1.45, 0, 0, 1.0], + "8968": [0.95003, 1.45, 0, 0, 0.58334], + "8969": [0.95003, 1.45, 0, 0, 0.58334], + "8970": [0.95003, 1.45, 0, 0, 0.58334], + "8971": [0.95003, 1.45, 0, 0, 0.58334], + "10216": [0.95003, 1.45, 0, 0, 0.75], + "10217": [0.95003, 1.45, 0, 0, 0.75] + }, + "Size4-Regular": { + "32": [0, 0, 0, 0, 0.25], + "40": [1.25003, 1.75, 0, 0, 0.79167], + "41": [1.25003, 1.75, 0, 0, 0.79167], + "47": [1.25003, 1.75, 0, 0, 1.27778], + "91": [1.25003, 1.75, 0, 0, 0.58334], + "92": [1.25003, 1.75, 0, 0, 1.27778], + "93": [1.25003, 1.75, 0, 0, 0.58334], + "123": [1.25003, 1.75, 0, 0, 0.80556], + "125": [1.25003, 1.75, 0, 0, 0.80556], + "160": [0, 0, 0, 0, 0.25], + "710": [0, 0.825, 0, 0, 1.8889], + "732": [0, 0.825, 0, 0, 1.8889], + "770": [0, 0.825, 0, 0, 1.8889], + "771": [0, 0.825, 0, 0, 1.8889], + "8730": [1.25003, 1.75, 0, 0, 1.0], + "8968": [1.25003, 1.75, 0, 0, 0.63889], + "8969": [1.25003, 1.75, 0, 0, 0.63889], + "8970": [1.25003, 1.75, 0, 0, 0.63889], + "8971": [1.25003, 1.75, 0, 0, 0.63889], + "9115": [0.64502, 1.155, 0, 0, 0.875], + "9116": [1e-05, 0.6, 0, 0, 0.875], + "9117": [0.64502, 1.155, 0, 0, 0.875], + "9118": [0.64502, 1.155, 0, 0, 0.875], + "9119": [1e-05, 0.6, 0, 0, 0.875], + "9120": [0.64502, 1.155, 0, 0, 0.875], + "9121": [0.64502, 1.155, 0, 0, 0.66667], + "9122": [-0.00099, 0.601, 0, 0, 0.66667], + "9123": [0.64502, 1.155, 0, 0, 0.66667], + "9124": [0.64502, 1.155, 0, 0, 0.66667], + "9125": [-0.00099, 0.601, 0, 0, 0.66667], + "9126": [0.64502, 1.155, 0, 0, 0.66667], + "9127": [1e-05, 0.9, 0, 0, 0.88889], + "9128": [0.65002, 1.15, 0, 0, 0.88889], + "9129": [0.90001, 0, 0, 0, 0.88889], + "9130": [0, 0.3, 0, 0, 0.88889], + "9131": [1e-05, 0.9, 0, 0, 0.88889], + "9132": [0.65002, 1.15, 0, 0, 0.88889], + "9133": [0.90001, 0, 0, 0, 0.88889], + "9143": [0.88502, 0.915, 0, 0, 1.05556], + "10216": [1.25003, 1.75, 0, 0, 0.80556], + "10217": [1.25003, 1.75, 0, 0, 0.80556], + "57344": [-0.00499, 0.605, 0, 0, 1.05556], + "57345": [-0.00499, 0.605, 0, 0, 1.05556], + "57680": [0, 0.12, 0, 0, 0.45], + "57681": [0, 0.12, 0, 0, 0.45], + "57682": [0, 0.12, 0, 0, 0.45], + "57683": [0, 0.12, 0, 0, 0.45] + }, + "Typewriter-Regular": { + "32": [0, 0, 0, 0, 0.525], + "33": [0, 0.61111, 0, 0, 0.525], + "34": [0, 0.61111, 0, 0, 0.525], + "35": [0, 0.61111, 0, 0, 0.525], + "36": [0.08333, 0.69444, 0, 0, 0.525], + "37": [0.08333, 0.69444, 0, 0, 0.525], + "38": [0, 0.61111, 0, 0, 0.525], + "39": [0, 0.61111, 0, 0, 0.525], + "40": [0.08333, 0.69444, 0, 0, 0.525], + "41": [0.08333, 0.69444, 0, 0, 0.525], + "42": [0, 0.52083, 0, 0, 0.525], + "43": [-0.08056, 0.53055, 0, 0, 0.525], + "44": [0.13889, 0.125, 0, 0, 0.525], + "45": [-0.08056, 0.53055, 0, 0, 0.525], + "46": [0, 0.125, 0, 0, 0.525], + "47": [0.08333, 0.69444, 0, 0, 0.525], + "48": [0, 0.61111, 0, 0, 0.525], + "49": [0, 0.61111, 0, 0, 0.525], + "50": [0, 0.61111, 0, 0, 0.525], + "51": [0, 0.61111, 0, 0, 0.525], + "52": [0, 0.61111, 0, 0, 0.525], + "53": [0, 0.61111, 0, 0, 0.525], + "54": [0, 0.61111, 0, 0, 0.525], + "55": [0, 0.61111, 0, 0, 0.525], + "56": [0, 0.61111, 0, 0, 0.525], + "57": [0, 0.61111, 0, 0, 0.525], + "58": [0, 0.43056, 0, 0, 0.525], + "59": [0.13889, 0.43056, 0, 0, 0.525], + "60": [-0.05556, 0.55556, 0, 0, 0.525], + "61": [-0.19549, 0.41562, 0, 0, 0.525], + "62": [-0.05556, 0.55556, 0, 0, 0.525], + "63": [0, 0.61111, 0, 0, 0.525], + "64": [0, 0.61111, 0, 0, 0.525], + "65": [0, 0.61111, 0, 0, 0.525], + "66": [0, 0.61111, 0, 0, 0.525], + "67": [0, 0.61111, 0, 0, 0.525], + "68": [0, 0.61111, 0, 0, 0.525], + "69": [0, 0.61111, 0, 0, 0.525], + "70": [0, 0.61111, 0, 0, 0.525], + "71": [0, 0.61111, 0, 0, 0.525], + "72": [0, 0.61111, 0, 0, 0.525], + "73": [0, 0.61111, 0, 0, 0.525], + "74": [0, 0.61111, 0, 0, 0.525], + "75": [0, 0.61111, 0, 0, 0.525], + "76": [0, 0.61111, 0, 0, 0.525], + "77": [0, 0.61111, 0, 0, 0.525], + "78": [0, 0.61111, 0, 0, 0.525], + "79": [0, 0.61111, 0, 0, 0.525], + "80": [0, 0.61111, 0, 0, 0.525], + "81": [0.13889, 0.61111, 0, 0, 0.525], + "82": [0, 0.61111, 0, 0, 0.525], + "83": [0, 0.61111, 0, 0, 0.525], + "84": [0, 0.61111, 0, 0, 0.525], + "85": [0, 0.61111, 0, 0, 0.525], + "86": [0, 0.61111, 0, 0, 0.525], + "87": [0, 0.61111, 0, 0, 0.525], + "88": [0, 0.61111, 0, 0, 0.525], + "89": [0, 0.61111, 0, 0, 0.525], + "90": [0, 0.61111, 0, 0, 0.525], + "91": [0.08333, 0.69444, 0, 0, 0.525], + "92": [0.08333, 0.69444, 0, 0, 0.525], + "93": [0.08333, 0.69444, 0, 0, 0.525], + "94": [0, 0.61111, 0, 0, 0.525], + "95": [0.09514, 0, 0, 0, 0.525], + "96": [0, 0.61111, 0, 0, 0.525], + "97": [0, 0.43056, 0, 0, 0.525], + "98": [0, 0.61111, 0, 0, 0.525], + "99": [0, 0.43056, 0, 0, 0.525], + "100": [0, 0.61111, 0, 0, 0.525], + "101": [0, 0.43056, 0, 0, 0.525], + "102": [0, 0.61111, 0, 0, 0.525], + "103": [0.22222, 0.43056, 0, 0, 0.525], + "104": [0, 0.61111, 0, 0, 0.525], + "105": [0, 0.61111, 0, 0, 0.525], + "106": [0.22222, 0.61111, 0, 0, 0.525], + "107": [0, 0.61111, 0, 0, 0.525], + "108": [0, 0.61111, 0, 0, 0.525], + "109": [0, 0.43056, 0, 0, 0.525], + "110": [0, 0.43056, 0, 0, 0.525], + "111": [0, 0.43056, 0, 0, 0.525], + "112": [0.22222, 0.43056, 0, 0, 0.525], + "113": [0.22222, 0.43056, 0, 0, 0.525], + "114": [0, 0.43056, 0, 0, 0.525], + "115": [0, 0.43056, 0, 0, 0.525], + "116": [0, 0.55358, 0, 0, 0.525], + "117": [0, 0.43056, 0, 0, 0.525], + "118": [0, 0.43056, 0, 0, 0.525], + "119": [0, 0.43056, 0, 0, 0.525], + "120": [0, 0.43056, 0, 0, 0.525], + "121": [0.22222, 0.43056, 0, 0, 0.525], + "122": [0, 0.43056, 0, 0, 0.525], + "123": [0.08333, 0.69444, 0, 0, 0.525], + "124": [0.08333, 0.69444, 0, 0, 0.525], + "125": [0.08333, 0.69444, 0, 0, 0.525], + "126": [0, 0.61111, 0, 0, 0.525], + "127": [0, 0.61111, 0, 0, 0.525], + "160": [0, 0, 0, 0, 0.525], + "176": [0, 0.61111, 0, 0, 0.525], + "184": [0.19445, 0, 0, 0, 0.525], + "305": [0, 0.43056, 0, 0, 0.525], + "567": [0.22222, 0.43056, 0, 0, 0.525], + "711": [0, 0.56597, 0, 0, 0.525], + "713": [0, 0.56555, 0, 0, 0.525], + "714": [0, 0.61111, 0, 0, 0.525], + "715": [0, 0.61111, 0, 0, 0.525], + "728": [0, 0.61111, 0, 0, 0.525], + "730": [0, 0.61111, 0, 0, 0.525], + "770": [0, 0.61111, 0, 0, 0.525], + "771": [0, 0.61111, 0, 0, 0.525], + "776": [0, 0.61111, 0, 0, 0.525], + "915": [0, 0.61111, 0, 0, 0.525], + "916": [0, 0.61111, 0, 0, 0.525], + "920": [0, 0.61111, 0, 0, 0.525], + "923": [0, 0.61111, 0, 0, 0.525], + "926": [0, 0.61111, 0, 0, 0.525], + "928": [0, 0.61111, 0, 0, 0.525], + "931": [0, 0.61111, 0, 0, 0.525], + "933": [0, 0.61111, 0, 0, 0.525], + "934": [0, 0.61111, 0, 0, 0.525], + "936": [0, 0.61111, 0, 0, 0.525], + "937": [0, 0.61111, 0, 0, 0.525], + "8216": [0, 0.61111, 0, 0, 0.525], + "8217": [0, 0.61111, 0, 0, 0.525], + "8242": [0, 0.61111, 0, 0, 0.525], + "9251": [0.11111, 0.21944, 0, 0, 0.525] + } +}; + +/** + * This file contains metrics regarding fonts and individual symbols. The sigma + * and xi variables, as well as the metricMap map contain data extracted from + * TeX, TeX font metrics, and the TTF files. These data are then exposed via the + * `metrics` variable and the getCharacterMetrics function. + */ +// In TeX, there are actually three sets of dimensions, one for each of +// textstyle (size index 5 and higher: >=9pt), scriptstyle (size index 3 and 4: +// 7-8pt), and scriptscriptstyle (size index 1 and 2: 5-6pt). These are +// provided in the arrays below, in that order. +// +// The font metrics are stored in fonts cmsy10, cmsy7, and cmsy5 respectively. +// This was determined by running the following script: +// +// latex -interaction=nonstopmode \ +// '\documentclass{article}\usepackage{amsmath}\begin{document}' \ +// '$a$ \expandafter\show\the\textfont2' \ +// '\expandafter\show\the\scriptfont2' \ +// '\expandafter\show\the\scriptscriptfont2' \ +// '\stop' +// +// The metrics themselves were retrieved using the following commands: +// +// tftopl cmsy10 +// tftopl cmsy7 +// tftopl cmsy5 +// +// The output of each of these commands is quite lengthy. The only part we +// care about is the FONTDIMEN section. Each value is measured in EMs. +var sigmasAndXis = { + slant: [0.250, 0.250, 0.250], + // sigma1 + space: [0.000, 0.000, 0.000], + // sigma2 + stretch: [0.000, 0.000, 0.000], + // sigma3 + shrink: [0.000, 0.000, 0.000], + // sigma4 + xHeight: [0.431, 0.431, 0.431], + // sigma5 + quad: [1.000, 1.171, 1.472], + // sigma6 + extraSpace: [0.000, 0.000, 0.000], + // sigma7 + num1: [0.677, 0.732, 0.925], + // sigma8 + num2: [0.394, 0.384, 0.387], + // sigma9 + num3: [0.444, 0.471, 0.504], + // sigma10 + denom1: [0.686, 0.752, 1.025], + // sigma11 + denom2: [0.345, 0.344, 0.532], + // sigma12 + sup1: [0.413, 0.503, 0.504], + // sigma13 + sup2: [0.363, 0.431, 0.404], + // sigma14 + sup3: [0.289, 0.286, 0.294], + // sigma15 + sub1: [0.150, 0.143, 0.200], + // sigma16 + sub2: [0.247, 0.286, 0.400], + // sigma17 + supDrop: [0.386, 0.353, 0.494], + // sigma18 + subDrop: [0.050, 0.071, 0.100], + // sigma19 + delim1: [2.390, 1.700, 1.980], + // sigma20 + delim2: [1.010, 1.157, 1.420], + // sigma21 + axisHeight: [0.250, 0.250, 0.250], + // sigma22 + // These font metrics are extracted from TeX by using tftopl on cmex10.tfm; + // they correspond to the font parameters of the extension fonts (family 3). + // See the TeXbook, page 441. In AMSTeX, the extension fonts scale; to + // match cmex7, we'd use cmex7.tfm values for script and scriptscript + // values. + defaultRuleThickness: [0.04, 0.049, 0.049], + // xi8; cmex7: 0.049 + bigOpSpacing1: [0.111, 0.111, 0.111], + // xi9 + bigOpSpacing2: [0.166, 0.166, 0.166], + // xi10 + bigOpSpacing3: [0.2, 0.2, 0.2], + // xi11 + bigOpSpacing4: [0.6, 0.611, 0.611], + // xi12; cmex7: 0.611 + bigOpSpacing5: [0.1, 0.143, 0.143], + // xi13; cmex7: 0.143 + // The \sqrt rule width is taken from the height of the surd character. + // Since we use the same font at all sizes, this thickness doesn't scale. + sqrtRuleThickness: [0.04, 0.04, 0.04], + // This value determines how large a pt is, for metrics which are defined + // in terms of pts. + // This value is also used in katex.less; if you change it make sure the + // values match. + ptPerEm: [10.0, 10.0, 10.0], + // The space between adjacent `|` columns in an array definition. From + // `\showthe\doublerulesep` in LaTeX. Equals 2.0 / ptPerEm. + doubleRuleSep: [0.2, 0.2, 0.2], + // The width of separator lines in {array} environments. From + // `\showthe\arrayrulewidth` in LaTeX. Equals 0.4 / ptPerEm. + arrayRuleWidth: [0.04, 0.04, 0.04], + // Two values from LaTeX source2e: + fboxsep: [0.3, 0.3, 0.3], + // 3 pt / ptPerEm + fboxrule: [0.04, 0.04, 0.04] // 0.4 pt / ptPerEm + +}; // This map contains a mapping from font name and character code to character +// should have Latin-1 and Cyrillic characters, but may not depending on the +// operating system. The metrics do not account for extra height from the +// accents. In the case of Cyrillic characters which have both ascenders and +// descenders we prefer approximations with ascenders, primarily to prevent +// the fraction bar or root line from intersecting the glyph. +// TODO(kevinb) allow union of multiple glyph metrics for better accuracy. + +var extraCharacterMap = { + // Latin-1 + 'Å': 'A', + 'Ð': 'D', + 'Þ': 'o', + 'å': 'a', + 'ð': 'd', + 'þ': 'o', + // Cyrillic + 'А': 'A', + 'Б': 'B', + 'В': 'B', + 'Г': 'F', + 'Д': 'A', + 'Е': 'E', + 'Ж': 'K', + 'З': '3', + 'И': 'N', + 'Й': 'N', + 'К': 'K', + 'Л': 'N', + 'М': 'M', + 'Н': 'H', + 'О': 'O', + 'П': 'N', + 'Р': 'P', + 'С': 'C', + 'Т': 'T', + 'У': 'y', + 'Ф': 'O', + 'Х': 'X', + 'Ц': 'U', + 'Ч': 'h', + 'Ш': 'W', + 'Щ': 'W', + 'Ъ': 'B', + 'Ы': 'X', + 'Ь': 'B', + 'Э': '3', + 'Ю': 'X', + 'Я': 'R', + 'а': 'a', + 'б': 'b', + 'в': 'a', + 'г': 'r', + 'д': 'y', + 'е': 'e', + 'ж': 'm', + 'з': 'e', + 'и': 'n', + 'й': 'n', + 'к': 'n', + 'л': 'n', + 'м': 'm', + 'н': 'n', + 'о': 'o', + 'п': 'n', + 'р': 'p', + 'с': 'c', + 'т': 'o', + 'у': 'y', + 'ф': 'b', + 'х': 'x', + 'ц': 'n', + 'ч': 'n', + 'ш': 'w', + 'щ': 'w', + 'ъ': 'a', + 'ы': 'm', + 'ь': 'a', + 'э': 'e', + 'ю': 'm', + 'я': 'r' +}; + +/** + * This function adds new font metrics to default metricMap + * It can also override existing metrics + */ +function setFontMetrics(fontName, metrics) { + fontMetricsData[fontName] = metrics; +} +/** + * This function is a convenience function for looking up information in the + * metricMap table. It takes a character as a string, and a font. + * + * Note: the `width` property may be undefined if fontMetricsData.js wasn't + * built using `Make extended_metrics`. + */ + +function getCharacterMetrics(character, font, mode) { + if (!fontMetricsData[font]) { + throw new Error("Font metrics not found for font: " + font + "."); + } + + var ch = character.charCodeAt(0); + var metrics = fontMetricsData[font][ch]; + + if (!metrics && character[0] in extraCharacterMap) { + ch = extraCharacterMap[character[0]].charCodeAt(0); + metrics = fontMetricsData[font][ch]; + } + + if (!metrics && mode === 'text') { + // We don't typically have font metrics for Asian scripts. + // But since we support them in text mode, we need to return + // some sort of metrics. + // So if the character is in a script we support but we + // don't have metrics for it, just use the metrics for + // the Latin capital letter M. This is close enough because + // we (currently) only care about the height of the glyph + // not its width. + if (supportedCodepoint(ch)) { + metrics = fontMetricsData[font][77]; // 77 is the charcode for 'M' + } + } + + if (metrics) { + return { + depth: metrics[0], + height: metrics[1], + italic: metrics[2], + skew: metrics[3], + width: metrics[4] + }; + } +} +var fontMetricsBySizeIndex = {}; +/** + * Get the font metrics for a given size. + */ + +function getGlobalMetrics(size) { + var sizeIndex; + + if (size >= 5) { + sizeIndex = 0; + } else if (size >= 3) { + sizeIndex = 1; + } else { + sizeIndex = 2; + } + + if (!fontMetricsBySizeIndex[sizeIndex]) { + var metrics = fontMetricsBySizeIndex[sizeIndex] = { + cssEmPerMu: sigmasAndXis.quad[sizeIndex] / 18 + }; + + for (var key in sigmasAndXis) { + if (sigmasAndXis.hasOwnProperty(key)) { + metrics[key] = sigmasAndXis[key][sizeIndex]; + } + } + } + + return fontMetricsBySizeIndex[sizeIndex]; +} + +/** + * This file contains information about the options that the Parser carries + * around with it while parsing. Data is held in an `Options` object, and when + * recursing, a new `Options` object can be created with the `.with*` and + * `.reset` functions. + */ +var sizeStyleMap = [// Each element contains [textsize, scriptsize, scriptscriptsize]. +// The size mappings are taken from TeX with \normalsize=10pt. +[1, 1, 1], // size1: [5, 5, 5] \tiny +[2, 1, 1], // size2: [6, 5, 5] +[3, 1, 1], // size3: [7, 5, 5] \scriptsize +[4, 2, 1], // size4: [8, 6, 5] \footnotesize +[5, 2, 1], // size5: [9, 6, 5] \small +[6, 3, 1], // size6: [10, 7, 5] \normalsize +[7, 4, 2], // size7: [12, 8, 6] \large +[8, 6, 3], // size8: [14.4, 10, 7] \Large +[9, 7, 6], // size9: [17.28, 12, 10] \LARGE +[10, 8, 7], // size10: [20.74, 14.4, 12] \huge +[11, 10, 9] // size11: [24.88, 20.74, 17.28] \HUGE +]; +var sizeMultipliers = [// fontMetrics.js:getGlobalMetrics also uses size indexes, so if +// you change size indexes, change that function. +0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.44, 1.728, 2.074, 2.488]; + +var sizeAtStyle = function sizeAtStyle(size, style) { + return style.size < 2 ? size : sizeStyleMap[size - 1][style.size - 1]; +}; // In these types, "" (empty string) means "no change". + + +/** + * This is the main options class. It contains the current style, size, color, + * and font. + * + * Options objects should not be modified. To create a new Options with + * different properties, call a `.having*` method. + */ +class Options { + // A font family applies to a group of fonts (i.e. SansSerif), while a font + // represents a specific font (i.e. SansSerif Bold). + // See: https://tex.stackexchange.com/questions/22350/difference-between-textrm-and-mathrm + + /** + * The base size index. + */ + constructor(data) { + this.style = void 0; + this.color = void 0; + this.size = void 0; + this.textSize = void 0; + this.phantom = void 0; + this.font = void 0; + this.fontFamily = void 0; + this.fontWeight = void 0; + this.fontShape = void 0; + this.sizeMultiplier = void 0; + this.maxSize = void 0; + this.minRuleThickness = void 0; + this._fontMetrics = void 0; + this.style = data.style; + this.color = data.color; + this.size = data.size || Options.BASESIZE; + this.textSize = data.textSize || this.size; + this.phantom = !!data.phantom; + this.font = data.font || ""; + this.fontFamily = data.fontFamily || ""; + this.fontWeight = data.fontWeight || ''; + this.fontShape = data.fontShape || ''; + this.sizeMultiplier = sizeMultipliers[this.size - 1]; + this.maxSize = data.maxSize; + this.minRuleThickness = data.minRuleThickness; + this._fontMetrics = undefined; + } + /** + * Returns a new options object with the same properties as "this". Properties + * from "extension" will be copied to the new options object. + */ + + + extend(extension) { + var data = { + style: this.style, + size: this.size, + textSize: this.textSize, + color: this.color, + phantom: this.phantom, + font: this.font, + fontFamily: this.fontFamily, + fontWeight: this.fontWeight, + fontShape: this.fontShape, + maxSize: this.maxSize, + minRuleThickness: this.minRuleThickness + }; + + for (var key in extension) { + if (extension.hasOwnProperty(key)) { + data[key] = extension[key]; + } + } + + return new Options(data); + } + /** + * Return an options object with the given style. If `this.style === style`, + * returns `this`. + */ + + + havingStyle(style) { + if (this.style === style) { + return this; + } else { + return this.extend({ + style: style, + size: sizeAtStyle(this.textSize, style) + }); + } + } + /** + * Return an options object with a cramped version of the current style. If + * the current style is cramped, returns `this`. + */ + + + havingCrampedStyle() { + return this.havingStyle(this.style.cramp()); + } + /** + * Return an options object with the given size and in at least `\textstyle`. + * Returns `this` if appropriate. + */ + + + havingSize(size) { + if (this.size === size && this.textSize === size) { + return this; + } else { + return this.extend({ + style: this.style.text(), + size: size, + textSize: size, + sizeMultiplier: sizeMultipliers[size - 1] + }); + } + } + /** + * Like `this.havingSize(BASESIZE).havingStyle(style)`. If `style` is omitted, + * changes to at least `\textstyle`. + */ + + + havingBaseStyle(style) { + style = style || this.style.text(); + var wantSize = sizeAtStyle(Options.BASESIZE, style); + + if (this.size === wantSize && this.textSize === Options.BASESIZE && this.style === style) { + return this; + } else { + return this.extend({ + style: style, + size: wantSize + }); + } + } + /** + * Remove the effect of sizing changes such as \Huge. + * Keep the effect of the current style, such as \scriptstyle. + */ + + + havingBaseSizing() { + var size; + + switch (this.style.id) { + case 4: + case 5: + size = 3; // normalsize in scriptstyle + + break; + + case 6: + case 7: + size = 1; // normalsize in scriptscriptstyle + + break; + + default: + size = 6; + // normalsize in textstyle or displaystyle + } + + return this.extend({ + style: this.style.text(), + size: size + }); + } + /** + * Create a new options object with the given color. + */ + + + withColor(color) { + return this.extend({ + color: color + }); + } + /** + * Create a new options object with "phantom" set to true. + */ + + + withPhantom() { + return this.extend({ + phantom: true + }); + } + /** + * Creates a new options object with the given math font or old text font. + * @type {[type]} + */ + + + withFont(font) { + return this.extend({ + font + }); + } + /** + * Create a new options objects with the given fontFamily. + */ + + + withTextFontFamily(fontFamily) { + return this.extend({ + fontFamily, + font: "" + }); + } + /** + * Creates a new options object with the given font weight + */ + + + withTextFontWeight(fontWeight) { + return this.extend({ + fontWeight, + font: "" + }); + } + /** + * Creates a new options object with the given font weight + */ + + + withTextFontShape(fontShape) { + return this.extend({ + fontShape, + font: "" + }); + } + /** + * Return the CSS sizing classes required to switch from enclosing options + * `oldOptions` to `this`. Returns an array of classes. + */ + + + sizingClasses(oldOptions) { + if (oldOptions.size !== this.size) { + return ["sizing", "reset-size" + oldOptions.size, "size" + this.size]; + } else { + return []; + } + } + /** + * Return the CSS sizing classes required to switch to the base size. Like + * `this.havingSize(BASESIZE).sizingClasses(this)`. + */ + + + baseSizingClasses() { + if (this.size !== Options.BASESIZE) { + return ["sizing", "reset-size" + this.size, "size" + Options.BASESIZE]; + } else { + return []; + } + } + /** + * Return the font metrics for this size. + */ + + + fontMetrics() { + if (!this._fontMetrics) { + this._fontMetrics = getGlobalMetrics(this.size); + } + + return this._fontMetrics; + } + /** + * Gets the CSS color of the current options object + */ + + + getColor() { + if (this.phantom) { + return "transparent"; + } else { + return this.color; + } + } + +} + +Options.BASESIZE = 6; + +/** + * This file does conversion between units. In particular, it provides + * calculateSize to convert other units into ems. + */ +// Thus, multiplying a length by this number converts the length from units +// into pts. Dividing the result by ptPerEm gives the number of ems +// *assuming* a font size of ptPerEm (normal size, normal style). + +var ptPerUnit = { + // https://en.wikibooks.org/wiki/LaTeX/Lengths and + // https://tex.stackexchange.com/a/8263 + "pt": 1, + // TeX point + "mm": 7227 / 2540, + // millimeter + "cm": 7227 / 254, + // centimeter + "in": 72.27, + // inch + "bp": 803 / 800, + // big (PostScript) points + "pc": 12, + // pica + "dd": 1238 / 1157, + // didot + "cc": 14856 / 1157, + // cicero (12 didot) + "nd": 685 / 642, + // new didot + "nc": 1370 / 107, + // new cicero (12 new didot) + "sp": 1 / 65536, + // scaled point (TeX's internal smallest unit) + // https://tex.stackexchange.com/a/41371 + "px": 803 / 800 // \pdfpxdimen defaults to 1 bp in pdfTeX and LuaTeX + +}; // Dictionary of relative units, for fast validity testing. + +var relativeUnit = { + "ex": true, + "em": true, + "mu": true +}; + +/** + * Determine whether the specified unit (either a string defining the unit + * or a "size" parse node containing a unit field) is valid. + */ +var validUnit = function validUnit(unit) { + if (typeof unit !== "string") { + unit = unit.unit; + } + + return unit in ptPerUnit || unit in relativeUnit || unit === "ex"; +}; +/* + * Convert a "size" parse node (with numeric "number" and string "unit" fields, + * as parsed by functions.js argType "size") into a CSS em value for the + * current style/scale. `options` gives the current options. + */ + +var calculateSize = function calculateSize(sizeValue, options) { + var scale; + + if (sizeValue.unit in ptPerUnit) { + // Absolute units + scale = ptPerUnit[sizeValue.unit] // Convert unit to pt + / options.fontMetrics().ptPerEm // Convert pt to CSS em + / options.sizeMultiplier; // Unscale to make absolute units + } else if (sizeValue.unit === "mu") { + // `mu` units scale with scriptstyle/scriptscriptstyle. + scale = options.fontMetrics().cssEmPerMu; + } else { + // Other relative units always refer to the *textstyle* font + // in the current size. + var unitOptions; + + if (options.style.isTight()) { + // isTight() means current style is script/scriptscript. + unitOptions = options.havingStyle(options.style.text()); + } else { + unitOptions = options; + } // TODO: In TeX these units are relative to the quad of the current + // *text* font, e.g. cmr10. KaTeX instead uses values from the + // comparably-sized *Computer Modern symbol* font. At 10pt, these + // match. At 7pt and 5pt, they differ: cmr7=1.138894, cmsy7=1.170641; + // cmr5=1.361133, cmsy5=1.472241. Consider $\scriptsize a\kern1emb$. + // TeX \showlists shows a kern of 1.13889 * fontsize; + // KaTeX shows a kern of 1.171 * fontsize. + + + if (sizeValue.unit === "ex") { + scale = unitOptions.fontMetrics().xHeight; + } else if (sizeValue.unit === "em") { + scale = unitOptions.fontMetrics().quad; + } else { + throw new ParseError("Invalid unit: '" + sizeValue.unit + "'"); + } + + if (unitOptions !== options) { + scale *= unitOptions.sizeMultiplier / options.sizeMultiplier; + } + } + + return Math.min(sizeValue.number * scale, options.maxSize); +}; +/** + * Round `n` to 4 decimal places, or to the nearest 1/10,000th em. See + * https://github.com/KaTeX/KaTeX/pull/2460. + */ + +var makeEm = function makeEm(n) { + return +n.toFixed(4) + "em"; +}; + +/** + * These objects store the data about the DOM nodes we create, as well as some + * extra data. They can then be transformed into real DOM nodes with the + * `toNode` function or HTML markup using `toMarkup`. They are useful for both + * storing extra properties on the nodes, as well as providing a way to easily + * work with the DOM. + * + * Similar functions for working with MathML nodes exist in mathMLTree.js. + * + * TODO: refactor `span` and `anchor` into common superclass when + * target environments support class inheritance + */ + +/** + * Create an HTML className based on a list of classes. In addition to joining + * with spaces, we also remove empty classes. + */ +var createClass = function createClass(classes) { + return classes.filter(cls => cls).join(" "); +}; + +var initNode = function initNode(classes, options, style) { + this.classes = classes || []; + this.attributes = {}; + this.height = 0; + this.depth = 0; + this.maxFontSize = 0; + this.style = style || {}; + + if (options) { + if (options.style.isTight()) { + this.classes.push("mtight"); + } + + var color = options.getColor(); + + if (color) { + this.style.color = color; + } + } +}; +/** + * Convert into an HTML node + */ + + +var toNode = function toNode(tagName) { + var node = document.createElement(tagName); // Apply the class + + node.className = createClass(this.classes); // Apply inline styles + + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + // $FlowFixMe Flow doesn't seem to understand span.style's type. + node.style[style] = this.style[style]; + } + } // Apply attributes + + + for (var attr in this.attributes) { + if (this.attributes.hasOwnProperty(attr)) { + node.setAttribute(attr, this.attributes[attr]); + } + } // Append the children, also as HTML nodes + + + for (var i = 0; i < this.children.length; i++) { + node.appendChild(this.children[i].toNode()); + } + + return node; +}; +/** + * Convert into an HTML markup string + */ + + +var toMarkup = function toMarkup(tagName) { + var markup = "<" + tagName; // Add the class + + if (this.classes.length) { + markup += " class=\"" + utils.escape(createClass(this.classes)) + "\""; + } + + var styles = ""; // Add the styles, after hyphenation + + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + styles += utils.hyphenate(style) + ":" + this.style[style] + ";"; + } + } + + if (styles) { + markup += " style=\"" + utils.escape(styles) + "\""; + } // Add the attributes + + + for (var attr in this.attributes) { + if (this.attributes.hasOwnProperty(attr)) { + markup += " " + attr + "=\"" + utils.escape(this.attributes[attr]) + "\""; + } + } + + markup += ">"; // Add the markup of the children, also as markup + + for (var i = 0; i < this.children.length; i++) { + markup += this.children[i].toMarkup(); + } + + markup += ""; + return markup; +}; // Making the type below exact with all optional fields doesn't work due to +// - https://github.com/facebook/flow/issues/4582 +// - https://github.com/facebook/flow/issues/5688 +// However, since *all* fields are optional, $Shape<> works as suggested in 5688 +// above. +// This type does not include all CSS properties. Additional properties should +// be added as needed. + + +/** + * This node represents a span node, with a className, a list of children, and + * an inline style. It also contains information about its height, depth, and + * maxFontSize. + * + * Represents two types with different uses: SvgSpan to wrap an SVG and DomSpan + * otherwise. This typesafety is important when HTML builders access a span's + * children. + */ +class Span { + constructor(classes, children, options, style) { + this.children = void 0; + this.attributes = void 0; + this.classes = void 0; + this.height = void 0; + this.depth = void 0; + this.width = void 0; + this.maxFontSize = void 0; + this.style = void 0; + initNode.call(this, classes, options, style); + this.children = children || []; + } + /** + * Sets an arbitrary attribute on the span. Warning: use this wisely. Not + * all browsers support attributes the same, and having too many custom + * attributes is probably bad. + */ + + + setAttribute(attribute, value) { + this.attributes[attribute] = value; + } + + hasClass(className) { + return utils.contains(this.classes, className); + } + + toNode() { + return toNode.call(this, "span"); + } + + toMarkup() { + return toMarkup.call(this, "span"); + } + +} +/** + * This node represents an anchor () element with a hyperlink. See `span` + * for further details. + */ + +class Anchor { + constructor(href, classes, children, options) { + this.children = void 0; + this.attributes = void 0; + this.classes = void 0; + this.height = void 0; + this.depth = void 0; + this.maxFontSize = void 0; + this.style = void 0; + initNode.call(this, classes, options); + this.children = children || []; + this.setAttribute('href', href); + } + + setAttribute(attribute, value) { + this.attributes[attribute] = value; + } + + hasClass(className) { + return utils.contains(this.classes, className); + } + + toNode() { + return toNode.call(this, "a"); + } + + toMarkup() { + return toMarkup.call(this, "a"); + } + +} +/** + * This node represents an image embed () element. + */ + +class Img { + constructor(src, alt, style) { + this.src = void 0; + this.alt = void 0; + this.classes = void 0; + this.height = void 0; + this.depth = void 0; + this.maxFontSize = void 0; + this.style = void 0; + this.alt = alt; + this.src = src; + this.classes = ["mord"]; + this.style = style; + } + + hasClass(className) { + return utils.contains(this.classes, className); + } + + toNode() { + var node = document.createElement("img"); + node.src = this.src; + node.alt = this.alt; + node.className = "mord"; // Apply inline styles + + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + // $FlowFixMe + node.style[style] = this.style[style]; + } + } + + return node; + } + + toMarkup() { + var markup = "\"" 0) { + span = document.createElement("span"); + span.style.marginRight = makeEm(this.italic); + } + + if (this.classes.length > 0) { + span = span || document.createElement("span"); + span.className = createClass(this.classes); + } + + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + span = span || document.createElement("span"); // $FlowFixMe Flow doesn't seem to understand span.style's type. + + span.style[style] = this.style[style]; + } + } + + if (span) { + span.appendChild(node); + return span; + } else { + return node; + } + } + /** + * Creates markup for a symbol node. + */ + + + toMarkup() { + // TODO(alpert): More duplication than I'd like from + // span.prototype.toMarkup and symbolNode.prototype.toNode... + var needsSpan = false; + var markup = " 0) { + styles += "margin-right:" + this.italic + "em;"; + } + + for (var style in this.style) { + if (this.style.hasOwnProperty(style)) { + styles += utils.hyphenate(style) + ":" + this.style[style] + ";"; + } + } + + if (styles) { + needsSpan = true; + markup += " style=\"" + utils.escape(styles) + "\""; + } + + var escaped = utils.escape(this.text); + + if (needsSpan) { + markup += ">"; + markup += escaped; + markup += ""; + return markup; + } else { + return escaped; + } + } + +} +/** + * SVG nodes are used to render stretchy wide elements. + */ + +class SvgNode { + constructor(children, attributes) { + this.children = void 0; + this.attributes = void 0; + this.children = children || []; + this.attributes = attributes || {}; + } + + toNode() { + var svgNS = "http://www.w3.org/2000/svg"; + var node = document.createElementNS(svgNS, "svg"); // Apply attributes + + for (var attr in this.attributes) { + if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { + node.setAttribute(attr, this.attributes[attr]); + } + } + + for (var i = 0; i < this.children.length; i++) { + node.appendChild(this.children[i].toNode()); + } + + return node; + } + + toMarkup() { + var markup = ""; + } else { + return ""; + } + } + +} +class LineNode { + constructor(attributes) { + this.attributes = void 0; + this.attributes = attributes || {}; + } + + toNode() { + var svgNS = "http://www.w3.org/2000/svg"; + var node = document.createElementNS(svgNS, "line"); // Apply attributes + + for (var attr in this.attributes) { + if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { + node.setAttribute(attr, this.attributes[attr]); + } + } + + return node; + } + + toMarkup() { + var markup = " but got " + String(group) + "."); + } +} + +/** + * This file holds a list of all no-argument functions and single-character + * symbols (like 'a' or ';'). + * + * For each of the symbols, there are three properties they can have: + * - font (required): the font to be used for this symbol. Either "main" (the + normal font), or "ams" (the ams fonts). + * - group (required): the ParseNode group type the symbol should have (i.e. + "textord", "mathord", etc). + See https://github.com/KaTeX/KaTeX/wiki/Examining-TeX#group-types + * - replace: the character that this symbol or function should be + * replaced with (i.e. "\phi" has a replace value of "\u03d5", the phi + * character in the main font). + * + * The outermost map in the table indicates what mode the symbols should be + * accepted in (e.g. "math" or "text"). + */ +// Some of these have a "-token" suffix since these are also used as `ParseNode` +// types for raw text tokens, and we want to avoid conflicts with higher-level +// `ParseNode` types. These `ParseNode`s are constructed within `Parser` by +// looking up the `symbols` map. +var ATOMS = { + "bin": 1, + "close": 1, + "inner": 1, + "open": 1, + "punct": 1, + "rel": 1 +}; +var NON_ATOMS = { + "accent-token": 1, + "mathord": 1, + "op-token": 1, + "spacing": 1, + "textord": 1 +}; +var symbols = { + "math": {}, + "text": {} +}; +/** `acceptUnicodeChar = true` is only applicable if `replace` is set. */ + +function defineSymbol(mode, font, group, replace, name, acceptUnicodeChar) { + symbols[mode][name] = { + font, + group, + replace + }; + + if (acceptUnicodeChar && replace) { + symbols[mode][replace] = symbols[mode][name]; + } +} // Some abbreviations for commonly used strings. +// This helps minify the code, and also spotting typos using jshint. +// modes: + +var math = "math"; +var text = "text"; // fonts: + +var main = "main"; +var ams = "ams"; // groups: + +var accent = "accent-token"; +var bin = "bin"; +var close = "close"; +var inner = "inner"; +var mathord = "mathord"; +var op = "op-token"; +var open = "open"; +var punct = "punct"; +var rel = "rel"; +var spacing = "spacing"; +var textord = "textord"; // Now comes the symbol table +// Relation Symbols + +defineSymbol(math, main, rel, "\u2261", "\\equiv", true); +defineSymbol(math, main, rel, "\u227a", "\\prec", true); +defineSymbol(math, main, rel, "\u227b", "\\succ", true); +defineSymbol(math, main, rel, "\u223c", "\\sim", true); +defineSymbol(math, main, rel, "\u22a5", "\\perp"); +defineSymbol(math, main, rel, "\u2aaf", "\\preceq", true); +defineSymbol(math, main, rel, "\u2ab0", "\\succeq", true); +defineSymbol(math, main, rel, "\u2243", "\\simeq", true); +defineSymbol(math, main, rel, "\u2223", "\\mid", true); +defineSymbol(math, main, rel, "\u226a", "\\ll", true); +defineSymbol(math, main, rel, "\u226b", "\\gg", true); +defineSymbol(math, main, rel, "\u224d", "\\asymp", true); +defineSymbol(math, main, rel, "\u2225", "\\parallel"); +defineSymbol(math, main, rel, "\u22c8", "\\bowtie", true); +defineSymbol(math, main, rel, "\u2323", "\\smile", true); +defineSymbol(math, main, rel, "\u2291", "\\sqsubseteq", true); +defineSymbol(math, main, rel, "\u2292", "\\sqsupseteq", true); +defineSymbol(math, main, rel, "\u2250", "\\doteq", true); +defineSymbol(math, main, rel, "\u2322", "\\frown", true); +defineSymbol(math, main, rel, "\u220b", "\\ni", true); +defineSymbol(math, main, rel, "\u221d", "\\propto", true); +defineSymbol(math, main, rel, "\u22a2", "\\vdash", true); +defineSymbol(math, main, rel, "\u22a3", "\\dashv", true); +defineSymbol(math, main, rel, "\u220b", "\\owns"); // Punctuation + +defineSymbol(math, main, punct, "\u002e", "\\ldotp"); +defineSymbol(math, main, punct, "\u22c5", "\\cdotp"); // Misc Symbols + +defineSymbol(math, main, textord, "\u0023", "\\#"); +defineSymbol(text, main, textord, "\u0023", "\\#"); +defineSymbol(math, main, textord, "\u0026", "\\&"); +defineSymbol(text, main, textord, "\u0026", "\\&"); +defineSymbol(math, main, textord, "\u2135", "\\aleph", true); +defineSymbol(math, main, textord, "\u2200", "\\forall", true); +defineSymbol(math, main, textord, "\u210f", "\\hbar", true); +defineSymbol(math, main, textord, "\u2203", "\\exists", true); +defineSymbol(math, main, textord, "\u2207", "\\nabla", true); +defineSymbol(math, main, textord, "\u266d", "\\flat", true); +defineSymbol(math, main, textord, "\u2113", "\\ell", true); +defineSymbol(math, main, textord, "\u266e", "\\natural", true); +defineSymbol(math, main, textord, "\u2663", "\\clubsuit", true); +defineSymbol(math, main, textord, "\u2118", "\\wp", true); +defineSymbol(math, main, textord, "\u266f", "\\sharp", true); +defineSymbol(math, main, textord, "\u2662", "\\diamondsuit", true); +defineSymbol(math, main, textord, "\u211c", "\\Re", true); +defineSymbol(math, main, textord, "\u2661", "\\heartsuit", true); +defineSymbol(math, main, textord, "\u2111", "\\Im", true); +defineSymbol(math, main, textord, "\u2660", "\\spadesuit", true); +defineSymbol(math, main, textord, "\u00a7", "\\S", true); +defineSymbol(text, main, textord, "\u00a7", "\\S"); +defineSymbol(math, main, textord, "\u00b6", "\\P", true); +defineSymbol(text, main, textord, "\u00b6", "\\P"); // Math and Text + +defineSymbol(math, main, textord, "\u2020", "\\dag"); +defineSymbol(text, main, textord, "\u2020", "\\dag"); +defineSymbol(text, main, textord, "\u2020", "\\textdagger"); +defineSymbol(math, main, textord, "\u2021", "\\ddag"); +defineSymbol(text, main, textord, "\u2021", "\\ddag"); +defineSymbol(text, main, textord, "\u2021", "\\textdaggerdbl"); // Large Delimiters + +defineSymbol(math, main, close, "\u23b1", "\\rmoustache", true); +defineSymbol(math, main, open, "\u23b0", "\\lmoustache", true); +defineSymbol(math, main, close, "\u27ef", "\\rgroup", true); +defineSymbol(math, main, open, "\u27ee", "\\lgroup", true); // Binary Operators + +defineSymbol(math, main, bin, "\u2213", "\\mp", true); +defineSymbol(math, main, bin, "\u2296", "\\ominus", true); +defineSymbol(math, main, bin, "\u228e", "\\uplus", true); +defineSymbol(math, main, bin, "\u2293", "\\sqcap", true); +defineSymbol(math, main, bin, "\u2217", "\\ast"); +defineSymbol(math, main, bin, "\u2294", "\\sqcup", true); +defineSymbol(math, main, bin, "\u25ef", "\\bigcirc", true); +defineSymbol(math, main, bin, "\u2219", "\\bullet", true); +defineSymbol(math, main, bin, "\u2021", "\\ddagger"); +defineSymbol(math, main, bin, "\u2240", "\\wr", true); +defineSymbol(math, main, bin, "\u2a3f", "\\amalg"); +defineSymbol(math, main, bin, "\u0026", "\\And"); // from amsmath +// Arrow Symbols + +defineSymbol(math, main, rel, "\u27f5", "\\longleftarrow", true); +defineSymbol(math, main, rel, "\u21d0", "\\Leftarrow", true); +defineSymbol(math, main, rel, "\u27f8", "\\Longleftarrow", true); +defineSymbol(math, main, rel, "\u27f6", "\\longrightarrow", true); +defineSymbol(math, main, rel, "\u21d2", "\\Rightarrow", true); +defineSymbol(math, main, rel, "\u27f9", "\\Longrightarrow", true); +defineSymbol(math, main, rel, "\u2194", "\\leftrightarrow", true); +defineSymbol(math, main, rel, "\u27f7", "\\longleftrightarrow", true); +defineSymbol(math, main, rel, "\u21d4", "\\Leftrightarrow", true); +defineSymbol(math, main, rel, "\u27fa", "\\Longleftrightarrow", true); +defineSymbol(math, main, rel, "\u21a6", "\\mapsto", true); +defineSymbol(math, main, rel, "\u27fc", "\\longmapsto", true); +defineSymbol(math, main, rel, "\u2197", "\\nearrow", true); +defineSymbol(math, main, rel, "\u21a9", "\\hookleftarrow", true); +defineSymbol(math, main, rel, "\u21aa", "\\hookrightarrow", true); +defineSymbol(math, main, rel, "\u2198", "\\searrow", true); +defineSymbol(math, main, rel, "\u21bc", "\\leftharpoonup", true); +defineSymbol(math, main, rel, "\u21c0", "\\rightharpoonup", true); +defineSymbol(math, main, rel, "\u2199", "\\swarrow", true); +defineSymbol(math, main, rel, "\u21bd", "\\leftharpoondown", true); +defineSymbol(math, main, rel, "\u21c1", "\\rightharpoondown", true); +defineSymbol(math, main, rel, "\u2196", "\\nwarrow", true); +defineSymbol(math, main, rel, "\u21cc", "\\rightleftharpoons", true); // AMS Negated Binary Relations + +defineSymbol(math, ams, rel, "\u226e", "\\nless", true); // Symbol names preceded by "@" each have a corresponding macro. + +defineSymbol(math, ams, rel, "\ue010", "\\@nleqslant"); +defineSymbol(math, ams, rel, "\ue011", "\\@nleqq"); +defineSymbol(math, ams, rel, "\u2a87", "\\lneq", true); +defineSymbol(math, ams, rel, "\u2268", "\\lneqq", true); +defineSymbol(math, ams, rel, "\ue00c", "\\@lvertneqq"); +defineSymbol(math, ams, rel, "\u22e6", "\\lnsim", true); +defineSymbol(math, ams, rel, "\u2a89", "\\lnapprox", true); +defineSymbol(math, ams, rel, "\u2280", "\\nprec", true); // unicode-math maps \u22e0 to \npreccurlyeq. We'll use the AMS synonym. + +defineSymbol(math, ams, rel, "\u22e0", "\\npreceq", true); +defineSymbol(math, ams, rel, "\u22e8", "\\precnsim", true); +defineSymbol(math, ams, rel, "\u2ab9", "\\precnapprox", true); +defineSymbol(math, ams, rel, "\u2241", "\\nsim", true); +defineSymbol(math, ams, rel, "\ue006", "\\@nshortmid"); +defineSymbol(math, ams, rel, "\u2224", "\\nmid", true); +defineSymbol(math, ams, rel, "\u22ac", "\\nvdash", true); +defineSymbol(math, ams, rel, "\u22ad", "\\nvDash", true); +defineSymbol(math, ams, rel, "\u22ea", "\\ntriangleleft"); +defineSymbol(math, ams, rel, "\u22ec", "\\ntrianglelefteq", true); +defineSymbol(math, ams, rel, "\u228a", "\\subsetneq", true); +defineSymbol(math, ams, rel, "\ue01a", "\\@varsubsetneq"); +defineSymbol(math, ams, rel, "\u2acb", "\\subsetneqq", true); +defineSymbol(math, ams, rel, "\ue017", "\\@varsubsetneqq"); +defineSymbol(math, ams, rel, "\u226f", "\\ngtr", true); +defineSymbol(math, ams, rel, "\ue00f", "\\@ngeqslant"); +defineSymbol(math, ams, rel, "\ue00e", "\\@ngeqq"); +defineSymbol(math, ams, rel, "\u2a88", "\\gneq", true); +defineSymbol(math, ams, rel, "\u2269", "\\gneqq", true); +defineSymbol(math, ams, rel, "\ue00d", "\\@gvertneqq"); +defineSymbol(math, ams, rel, "\u22e7", "\\gnsim", true); +defineSymbol(math, ams, rel, "\u2a8a", "\\gnapprox", true); +defineSymbol(math, ams, rel, "\u2281", "\\nsucc", true); // unicode-math maps \u22e1 to \nsucccurlyeq. We'll use the AMS synonym. + +defineSymbol(math, ams, rel, "\u22e1", "\\nsucceq", true); +defineSymbol(math, ams, rel, "\u22e9", "\\succnsim", true); +defineSymbol(math, ams, rel, "\u2aba", "\\succnapprox", true); // unicode-math maps \u2246 to \simneqq. We'll use the AMS synonym. + +defineSymbol(math, ams, rel, "\u2246", "\\ncong", true); +defineSymbol(math, ams, rel, "\ue007", "\\@nshortparallel"); +defineSymbol(math, ams, rel, "\u2226", "\\nparallel", true); +defineSymbol(math, ams, rel, "\u22af", "\\nVDash", true); +defineSymbol(math, ams, rel, "\u22eb", "\\ntriangleright"); +defineSymbol(math, ams, rel, "\u22ed", "\\ntrianglerighteq", true); +defineSymbol(math, ams, rel, "\ue018", "\\@nsupseteqq"); +defineSymbol(math, ams, rel, "\u228b", "\\supsetneq", true); +defineSymbol(math, ams, rel, "\ue01b", "\\@varsupsetneq"); +defineSymbol(math, ams, rel, "\u2acc", "\\supsetneqq", true); +defineSymbol(math, ams, rel, "\ue019", "\\@varsupsetneqq"); +defineSymbol(math, ams, rel, "\u22ae", "\\nVdash", true); +defineSymbol(math, ams, rel, "\u2ab5", "\\precneqq", true); +defineSymbol(math, ams, rel, "\u2ab6", "\\succneqq", true); +defineSymbol(math, ams, rel, "\ue016", "\\@nsubseteqq"); +defineSymbol(math, ams, bin, "\u22b4", "\\unlhd"); +defineSymbol(math, ams, bin, "\u22b5", "\\unrhd"); // AMS Negated Arrows + +defineSymbol(math, ams, rel, "\u219a", "\\nleftarrow", true); +defineSymbol(math, ams, rel, "\u219b", "\\nrightarrow", true); +defineSymbol(math, ams, rel, "\u21cd", "\\nLeftarrow", true); +defineSymbol(math, ams, rel, "\u21cf", "\\nRightarrow", true); +defineSymbol(math, ams, rel, "\u21ae", "\\nleftrightarrow", true); +defineSymbol(math, ams, rel, "\u21ce", "\\nLeftrightarrow", true); // AMS Misc + +defineSymbol(math, ams, rel, "\u25b3", "\\vartriangle"); +defineSymbol(math, ams, textord, "\u210f", "\\hslash"); +defineSymbol(math, ams, textord, "\u25bd", "\\triangledown"); +defineSymbol(math, ams, textord, "\u25ca", "\\lozenge"); +defineSymbol(math, ams, textord, "\u24c8", "\\circledS"); +defineSymbol(math, ams, textord, "\u00ae", "\\circledR"); +defineSymbol(text, ams, textord, "\u00ae", "\\circledR"); +defineSymbol(math, ams, textord, "\u2221", "\\measuredangle", true); +defineSymbol(math, ams, textord, "\u2204", "\\nexists"); +defineSymbol(math, ams, textord, "\u2127", "\\mho"); +defineSymbol(math, ams, textord, "\u2132", "\\Finv", true); +defineSymbol(math, ams, textord, "\u2141", "\\Game", true); +defineSymbol(math, ams, textord, "\u2035", "\\backprime"); +defineSymbol(math, ams, textord, "\u25b2", "\\blacktriangle"); +defineSymbol(math, ams, textord, "\u25bc", "\\blacktriangledown"); +defineSymbol(math, ams, textord, "\u25a0", "\\blacksquare"); +defineSymbol(math, ams, textord, "\u29eb", "\\blacklozenge"); +defineSymbol(math, ams, textord, "\u2605", "\\bigstar"); +defineSymbol(math, ams, textord, "\u2222", "\\sphericalangle", true); +defineSymbol(math, ams, textord, "\u2201", "\\complement", true); // unicode-math maps U+F0 to \matheth. We map to AMS function \eth + +defineSymbol(math, ams, textord, "\u00f0", "\\eth", true); +defineSymbol(text, main, textord, "\u00f0", "\u00f0"); +defineSymbol(math, ams, textord, "\u2571", "\\diagup"); +defineSymbol(math, ams, textord, "\u2572", "\\diagdown"); +defineSymbol(math, ams, textord, "\u25a1", "\\square"); +defineSymbol(math, ams, textord, "\u25a1", "\\Box"); +defineSymbol(math, ams, textord, "\u25ca", "\\Diamond"); // unicode-math maps U+A5 to \mathyen. We map to AMS function \yen + +defineSymbol(math, ams, textord, "\u00a5", "\\yen", true); +defineSymbol(text, ams, textord, "\u00a5", "\\yen", true); +defineSymbol(math, ams, textord, "\u2713", "\\checkmark", true); +defineSymbol(text, ams, textord, "\u2713", "\\checkmark"); // AMS Hebrew + +defineSymbol(math, ams, textord, "\u2136", "\\beth", true); +defineSymbol(math, ams, textord, "\u2138", "\\daleth", true); +defineSymbol(math, ams, textord, "\u2137", "\\gimel", true); // AMS Greek + +defineSymbol(math, ams, textord, "\u03dd", "\\digamma", true); +defineSymbol(math, ams, textord, "\u03f0", "\\varkappa"); // AMS Delimiters + +defineSymbol(math, ams, open, "\u250c", "\\@ulcorner", true); +defineSymbol(math, ams, close, "\u2510", "\\@urcorner", true); +defineSymbol(math, ams, open, "\u2514", "\\@llcorner", true); +defineSymbol(math, ams, close, "\u2518", "\\@lrcorner", true); // AMS Binary Relations + +defineSymbol(math, ams, rel, "\u2266", "\\leqq", true); +defineSymbol(math, ams, rel, "\u2a7d", "\\leqslant", true); +defineSymbol(math, ams, rel, "\u2a95", "\\eqslantless", true); +defineSymbol(math, ams, rel, "\u2272", "\\lesssim", true); +defineSymbol(math, ams, rel, "\u2a85", "\\lessapprox", true); +defineSymbol(math, ams, rel, "\u224a", "\\approxeq", true); +defineSymbol(math, ams, bin, "\u22d6", "\\lessdot"); +defineSymbol(math, ams, rel, "\u22d8", "\\lll", true); +defineSymbol(math, ams, rel, "\u2276", "\\lessgtr", true); +defineSymbol(math, ams, rel, "\u22da", "\\lesseqgtr", true); +defineSymbol(math, ams, rel, "\u2a8b", "\\lesseqqgtr", true); +defineSymbol(math, ams, rel, "\u2251", "\\doteqdot"); +defineSymbol(math, ams, rel, "\u2253", "\\risingdotseq", true); +defineSymbol(math, ams, rel, "\u2252", "\\fallingdotseq", true); +defineSymbol(math, ams, rel, "\u223d", "\\backsim", true); +defineSymbol(math, ams, rel, "\u22cd", "\\backsimeq", true); +defineSymbol(math, ams, rel, "\u2ac5", "\\subseteqq", true); +defineSymbol(math, ams, rel, "\u22d0", "\\Subset", true); +defineSymbol(math, ams, rel, "\u228f", "\\sqsubset", true); +defineSymbol(math, ams, rel, "\u227c", "\\preccurlyeq", true); +defineSymbol(math, ams, rel, "\u22de", "\\curlyeqprec", true); +defineSymbol(math, ams, rel, "\u227e", "\\precsim", true); +defineSymbol(math, ams, rel, "\u2ab7", "\\precapprox", true); +defineSymbol(math, ams, rel, "\u22b2", "\\vartriangleleft"); +defineSymbol(math, ams, rel, "\u22b4", "\\trianglelefteq"); +defineSymbol(math, ams, rel, "\u22a8", "\\vDash", true); +defineSymbol(math, ams, rel, "\u22aa", "\\Vvdash", true); +defineSymbol(math, ams, rel, "\u2323", "\\smallsmile"); +defineSymbol(math, ams, rel, "\u2322", "\\smallfrown"); +defineSymbol(math, ams, rel, "\u224f", "\\bumpeq", true); +defineSymbol(math, ams, rel, "\u224e", "\\Bumpeq", true); +defineSymbol(math, ams, rel, "\u2267", "\\geqq", true); +defineSymbol(math, ams, rel, "\u2a7e", "\\geqslant", true); +defineSymbol(math, ams, rel, "\u2a96", "\\eqslantgtr", true); +defineSymbol(math, ams, rel, "\u2273", "\\gtrsim", true); +defineSymbol(math, ams, rel, "\u2a86", "\\gtrapprox", true); +defineSymbol(math, ams, bin, "\u22d7", "\\gtrdot"); +defineSymbol(math, ams, rel, "\u22d9", "\\ggg", true); +defineSymbol(math, ams, rel, "\u2277", "\\gtrless", true); +defineSymbol(math, ams, rel, "\u22db", "\\gtreqless", true); +defineSymbol(math, ams, rel, "\u2a8c", "\\gtreqqless", true); +defineSymbol(math, ams, rel, "\u2256", "\\eqcirc", true); +defineSymbol(math, ams, rel, "\u2257", "\\circeq", true); +defineSymbol(math, ams, rel, "\u225c", "\\triangleq", true); +defineSymbol(math, ams, rel, "\u223c", "\\thicksim"); +defineSymbol(math, ams, rel, "\u2248", "\\thickapprox"); +defineSymbol(math, ams, rel, "\u2ac6", "\\supseteqq", true); +defineSymbol(math, ams, rel, "\u22d1", "\\Supset", true); +defineSymbol(math, ams, rel, "\u2290", "\\sqsupset", true); +defineSymbol(math, ams, rel, "\u227d", "\\succcurlyeq", true); +defineSymbol(math, ams, rel, "\u22df", "\\curlyeqsucc", true); +defineSymbol(math, ams, rel, "\u227f", "\\succsim", true); +defineSymbol(math, ams, rel, "\u2ab8", "\\succapprox", true); +defineSymbol(math, ams, rel, "\u22b3", "\\vartriangleright"); +defineSymbol(math, ams, rel, "\u22b5", "\\trianglerighteq"); +defineSymbol(math, ams, rel, "\u22a9", "\\Vdash", true); +defineSymbol(math, ams, rel, "\u2223", "\\shortmid"); +defineSymbol(math, ams, rel, "\u2225", "\\shortparallel"); +defineSymbol(math, ams, rel, "\u226c", "\\between", true); +defineSymbol(math, ams, rel, "\u22d4", "\\pitchfork", true); +defineSymbol(math, ams, rel, "\u221d", "\\varpropto"); +defineSymbol(math, ams, rel, "\u25c0", "\\blacktriangleleft"); // unicode-math says that \therefore is a mathord atom. +// We kept the amssymb atom type, which is rel. + +defineSymbol(math, ams, rel, "\u2234", "\\therefore", true); +defineSymbol(math, ams, rel, "\u220d", "\\backepsilon"); +defineSymbol(math, ams, rel, "\u25b6", "\\blacktriangleright"); // unicode-math says that \because is a mathord atom. +// We kept the amssymb atom type, which is rel. + +defineSymbol(math, ams, rel, "\u2235", "\\because", true); +defineSymbol(math, ams, rel, "\u22d8", "\\llless"); +defineSymbol(math, ams, rel, "\u22d9", "\\gggtr"); +defineSymbol(math, ams, bin, "\u22b2", "\\lhd"); +defineSymbol(math, ams, bin, "\u22b3", "\\rhd"); +defineSymbol(math, ams, rel, "\u2242", "\\eqsim", true); +defineSymbol(math, main, rel, "\u22c8", "\\Join"); +defineSymbol(math, ams, rel, "\u2251", "\\Doteq", true); // AMS Binary Operators + +defineSymbol(math, ams, bin, "\u2214", "\\dotplus", true); +defineSymbol(math, ams, bin, "\u2216", "\\smallsetminus"); +defineSymbol(math, ams, bin, "\u22d2", "\\Cap", true); +defineSymbol(math, ams, bin, "\u22d3", "\\Cup", true); +defineSymbol(math, ams, bin, "\u2a5e", "\\doublebarwedge", true); +defineSymbol(math, ams, bin, "\u229f", "\\boxminus", true); +defineSymbol(math, ams, bin, "\u229e", "\\boxplus", true); +defineSymbol(math, ams, bin, "\u22c7", "\\divideontimes", true); +defineSymbol(math, ams, bin, "\u22c9", "\\ltimes", true); +defineSymbol(math, ams, bin, "\u22ca", "\\rtimes", true); +defineSymbol(math, ams, bin, "\u22cb", "\\leftthreetimes", true); +defineSymbol(math, ams, bin, "\u22cc", "\\rightthreetimes", true); +defineSymbol(math, ams, bin, "\u22cf", "\\curlywedge", true); +defineSymbol(math, ams, bin, "\u22ce", "\\curlyvee", true); +defineSymbol(math, ams, bin, "\u229d", "\\circleddash", true); +defineSymbol(math, ams, bin, "\u229b", "\\circledast", true); +defineSymbol(math, ams, bin, "\u22c5", "\\centerdot"); +defineSymbol(math, ams, bin, "\u22ba", "\\intercal", true); +defineSymbol(math, ams, bin, "\u22d2", "\\doublecap"); +defineSymbol(math, ams, bin, "\u22d3", "\\doublecup"); +defineSymbol(math, ams, bin, "\u22a0", "\\boxtimes", true); // AMS Arrows +// Note: unicode-math maps \u21e2 to their own function \rightdasharrow. +// We'll map it to AMS function \dashrightarrow. It produces the same atom. + +defineSymbol(math, ams, rel, "\u21e2", "\\dashrightarrow", true); // unicode-math maps \u21e0 to \leftdasharrow. We'll use the AMS synonym. + +defineSymbol(math, ams, rel, "\u21e0", "\\dashleftarrow", true); +defineSymbol(math, ams, rel, "\u21c7", "\\leftleftarrows", true); +defineSymbol(math, ams, rel, "\u21c6", "\\leftrightarrows", true); +defineSymbol(math, ams, rel, "\u21da", "\\Lleftarrow", true); +defineSymbol(math, ams, rel, "\u219e", "\\twoheadleftarrow", true); +defineSymbol(math, ams, rel, "\u21a2", "\\leftarrowtail", true); +defineSymbol(math, ams, rel, "\u21ab", "\\looparrowleft", true); +defineSymbol(math, ams, rel, "\u21cb", "\\leftrightharpoons", true); +defineSymbol(math, ams, rel, "\u21b6", "\\curvearrowleft", true); // unicode-math maps \u21ba to \acwopencirclearrow. We'll use the AMS synonym. + +defineSymbol(math, ams, rel, "\u21ba", "\\circlearrowleft", true); +defineSymbol(math, ams, rel, "\u21b0", "\\Lsh", true); +defineSymbol(math, ams, rel, "\u21c8", "\\upuparrows", true); +defineSymbol(math, ams, rel, "\u21bf", "\\upharpoonleft", true); +defineSymbol(math, ams, rel, "\u21c3", "\\downharpoonleft", true); +defineSymbol(math, main, rel, "\u22b6", "\\origof", true); // not in font + +defineSymbol(math, main, rel, "\u22b7", "\\imageof", true); // not in font + +defineSymbol(math, ams, rel, "\u22b8", "\\multimap", true); +defineSymbol(math, ams, rel, "\u21ad", "\\leftrightsquigarrow", true); +defineSymbol(math, ams, rel, "\u21c9", "\\rightrightarrows", true); +defineSymbol(math, ams, rel, "\u21c4", "\\rightleftarrows", true); +defineSymbol(math, ams, rel, "\u21a0", "\\twoheadrightarrow", true); +defineSymbol(math, ams, rel, "\u21a3", "\\rightarrowtail", true); +defineSymbol(math, ams, rel, "\u21ac", "\\looparrowright", true); +defineSymbol(math, ams, rel, "\u21b7", "\\curvearrowright", true); // unicode-math maps \u21bb to \cwopencirclearrow. We'll use the AMS synonym. + +defineSymbol(math, ams, rel, "\u21bb", "\\circlearrowright", true); +defineSymbol(math, ams, rel, "\u21b1", "\\Rsh", true); +defineSymbol(math, ams, rel, "\u21ca", "\\downdownarrows", true); +defineSymbol(math, ams, rel, "\u21be", "\\upharpoonright", true); +defineSymbol(math, ams, rel, "\u21c2", "\\downharpoonright", true); +defineSymbol(math, ams, rel, "\u21dd", "\\rightsquigarrow", true); +defineSymbol(math, ams, rel, "\u21dd", "\\leadsto"); +defineSymbol(math, ams, rel, "\u21db", "\\Rrightarrow", true); +defineSymbol(math, ams, rel, "\u21be", "\\restriction"); +defineSymbol(math, main, textord, "\u2018", "`"); +defineSymbol(math, main, textord, "$", "\\$"); +defineSymbol(text, main, textord, "$", "\\$"); +defineSymbol(text, main, textord, "$", "\\textdollar"); +defineSymbol(math, main, textord, "%", "\\%"); +defineSymbol(text, main, textord, "%", "\\%"); +defineSymbol(math, main, textord, "_", "\\_"); +defineSymbol(text, main, textord, "_", "\\_"); +defineSymbol(text, main, textord, "_", "\\textunderscore"); +defineSymbol(math, main, textord, "\u2220", "\\angle", true); +defineSymbol(math, main, textord, "\u221e", "\\infty", true); +defineSymbol(math, main, textord, "\u2032", "\\prime"); +defineSymbol(math, main, textord, "\u25b3", "\\triangle"); +defineSymbol(math, main, textord, "\u0393", "\\Gamma", true); +defineSymbol(math, main, textord, "\u0394", "\\Delta", true); +defineSymbol(math, main, textord, "\u0398", "\\Theta", true); +defineSymbol(math, main, textord, "\u039b", "\\Lambda", true); +defineSymbol(math, main, textord, "\u039e", "\\Xi", true); +defineSymbol(math, main, textord, "\u03a0", "\\Pi", true); +defineSymbol(math, main, textord, "\u03a3", "\\Sigma", true); +defineSymbol(math, main, textord, "\u03a5", "\\Upsilon", true); +defineSymbol(math, main, textord, "\u03a6", "\\Phi", true); +defineSymbol(math, main, textord, "\u03a8", "\\Psi", true); +defineSymbol(math, main, textord, "\u03a9", "\\Omega", true); +defineSymbol(math, main, textord, "A", "\u0391"); +defineSymbol(math, main, textord, "B", "\u0392"); +defineSymbol(math, main, textord, "E", "\u0395"); +defineSymbol(math, main, textord, "Z", "\u0396"); +defineSymbol(math, main, textord, "H", "\u0397"); +defineSymbol(math, main, textord, "I", "\u0399"); +defineSymbol(math, main, textord, "K", "\u039A"); +defineSymbol(math, main, textord, "M", "\u039C"); +defineSymbol(math, main, textord, "N", "\u039D"); +defineSymbol(math, main, textord, "O", "\u039F"); +defineSymbol(math, main, textord, "P", "\u03A1"); +defineSymbol(math, main, textord, "T", "\u03A4"); +defineSymbol(math, main, textord, "X", "\u03A7"); +defineSymbol(math, main, textord, "\u00ac", "\\neg", true); +defineSymbol(math, main, textord, "\u00ac", "\\lnot"); +defineSymbol(math, main, textord, "\u22a4", "\\top"); +defineSymbol(math, main, textord, "\u22a5", "\\bot"); +defineSymbol(math, main, textord, "\u2205", "\\emptyset"); +defineSymbol(math, ams, textord, "\u2205", "\\varnothing"); +defineSymbol(math, main, mathord, "\u03b1", "\\alpha", true); +defineSymbol(math, main, mathord, "\u03b2", "\\beta", true); +defineSymbol(math, main, mathord, "\u03b3", "\\gamma", true); +defineSymbol(math, main, mathord, "\u03b4", "\\delta", true); +defineSymbol(math, main, mathord, "\u03f5", "\\epsilon", true); +defineSymbol(math, main, mathord, "\u03b6", "\\zeta", true); +defineSymbol(math, main, mathord, "\u03b7", "\\eta", true); +defineSymbol(math, main, mathord, "\u03b8", "\\theta", true); +defineSymbol(math, main, mathord, "\u03b9", "\\iota", true); +defineSymbol(math, main, mathord, "\u03ba", "\\kappa", true); +defineSymbol(math, main, mathord, "\u03bb", "\\lambda", true); +defineSymbol(math, main, mathord, "\u03bc", "\\mu", true); +defineSymbol(math, main, mathord, "\u03bd", "\\nu", true); +defineSymbol(math, main, mathord, "\u03be", "\\xi", true); +defineSymbol(math, main, mathord, "\u03bf", "\\omicron", true); +defineSymbol(math, main, mathord, "\u03c0", "\\pi", true); +defineSymbol(math, main, mathord, "\u03c1", "\\rho", true); +defineSymbol(math, main, mathord, "\u03c3", "\\sigma", true); +defineSymbol(math, main, mathord, "\u03c4", "\\tau", true); +defineSymbol(math, main, mathord, "\u03c5", "\\upsilon", true); +defineSymbol(math, main, mathord, "\u03d5", "\\phi", true); +defineSymbol(math, main, mathord, "\u03c7", "\\chi", true); +defineSymbol(math, main, mathord, "\u03c8", "\\psi", true); +defineSymbol(math, main, mathord, "\u03c9", "\\omega", true); +defineSymbol(math, main, mathord, "\u03b5", "\\varepsilon", true); +defineSymbol(math, main, mathord, "\u03d1", "\\vartheta", true); +defineSymbol(math, main, mathord, "\u03d6", "\\varpi", true); +defineSymbol(math, main, mathord, "\u03f1", "\\varrho", true); +defineSymbol(math, main, mathord, "\u03c2", "\\varsigma", true); +defineSymbol(math, main, mathord, "\u03c6", "\\varphi", true); +defineSymbol(math, main, bin, "\u2217", "*", true); +defineSymbol(math, main, bin, "+", "+"); +defineSymbol(math, main, bin, "\u2212", "-", true); +defineSymbol(math, main, bin, "\u22c5", "\\cdot", true); +defineSymbol(math, main, bin, "\u2218", "\\circ", true); +defineSymbol(math, main, bin, "\u00f7", "\\div", true); +defineSymbol(math, main, bin, "\u00b1", "\\pm", true); +defineSymbol(math, main, bin, "\u00d7", "\\times", true); +defineSymbol(math, main, bin, "\u2229", "\\cap", true); +defineSymbol(math, main, bin, "\u222a", "\\cup", true); +defineSymbol(math, main, bin, "\u2216", "\\setminus", true); +defineSymbol(math, main, bin, "\u2227", "\\land"); +defineSymbol(math, main, bin, "\u2228", "\\lor"); +defineSymbol(math, main, bin, "\u2227", "\\wedge", true); +defineSymbol(math, main, bin, "\u2228", "\\vee", true); +defineSymbol(math, main, textord, "\u221a", "\\surd"); +defineSymbol(math, main, open, "\u27e8", "\\langle", true); +defineSymbol(math, main, open, "\u2223", "\\lvert"); +defineSymbol(math, main, open, "\u2225", "\\lVert"); +defineSymbol(math, main, close, "?", "?"); +defineSymbol(math, main, close, "!", "!"); +defineSymbol(math, main, close, "\u27e9", "\\rangle", true); +defineSymbol(math, main, close, "\u2223", "\\rvert"); +defineSymbol(math, main, close, "\u2225", "\\rVert"); +defineSymbol(math, main, rel, "=", "="); +defineSymbol(math, main, rel, ":", ":"); +defineSymbol(math, main, rel, "\u2248", "\\approx", true); +defineSymbol(math, main, rel, "\u2245", "\\cong", true); +defineSymbol(math, main, rel, "\u2265", "\\ge"); +defineSymbol(math, main, rel, "\u2265", "\\geq", true); +defineSymbol(math, main, rel, "\u2190", "\\gets"); +defineSymbol(math, main, rel, ">", "\\gt", true); +defineSymbol(math, main, rel, "\u2208", "\\in", true); +defineSymbol(math, main, rel, "\ue020", "\\@not"); +defineSymbol(math, main, rel, "\u2282", "\\subset", true); +defineSymbol(math, main, rel, "\u2283", "\\supset", true); +defineSymbol(math, main, rel, "\u2286", "\\subseteq", true); +defineSymbol(math, main, rel, "\u2287", "\\supseteq", true); +defineSymbol(math, ams, rel, "\u2288", "\\nsubseteq", true); +defineSymbol(math, ams, rel, "\u2289", "\\nsupseteq", true); +defineSymbol(math, main, rel, "\u22a8", "\\models"); +defineSymbol(math, main, rel, "\u2190", "\\leftarrow", true); +defineSymbol(math, main, rel, "\u2264", "\\le"); +defineSymbol(math, main, rel, "\u2264", "\\leq", true); +defineSymbol(math, main, rel, "<", "\\lt", true); +defineSymbol(math, main, rel, "\u2192", "\\rightarrow", true); +defineSymbol(math, main, rel, "\u2192", "\\to"); +defineSymbol(math, ams, rel, "\u2271", "\\ngeq", true); +defineSymbol(math, ams, rel, "\u2270", "\\nleq", true); +defineSymbol(math, main, spacing, "\u00a0", "\\ "); +defineSymbol(math, main, spacing, "\u00a0", "\\space"); // Ref: LaTeX Source 2e: \DeclareRobustCommand{\nobreakspace}{% + +defineSymbol(math, main, spacing, "\u00a0", "\\nobreakspace"); +defineSymbol(text, main, spacing, "\u00a0", "\\ "); +defineSymbol(text, main, spacing, "\u00a0", " "); +defineSymbol(text, main, spacing, "\u00a0", "\\space"); +defineSymbol(text, main, spacing, "\u00a0", "\\nobreakspace"); +defineSymbol(math, main, spacing, null, "\\nobreak"); +defineSymbol(math, main, spacing, null, "\\allowbreak"); +defineSymbol(math, main, punct, ",", ","); +defineSymbol(math, main, punct, ";", ";"); +defineSymbol(math, ams, bin, "\u22bc", "\\barwedge", true); +defineSymbol(math, ams, bin, "\u22bb", "\\veebar", true); +defineSymbol(math, main, bin, "\u2299", "\\odot", true); +defineSymbol(math, main, bin, "\u2295", "\\oplus", true); +defineSymbol(math, main, bin, "\u2297", "\\otimes", true); +defineSymbol(math, main, textord, "\u2202", "\\partial", true); +defineSymbol(math, main, bin, "\u2298", "\\oslash", true); +defineSymbol(math, ams, bin, "\u229a", "\\circledcirc", true); +defineSymbol(math, ams, bin, "\u22a1", "\\boxdot", true); +defineSymbol(math, main, bin, "\u25b3", "\\bigtriangleup"); +defineSymbol(math, main, bin, "\u25bd", "\\bigtriangledown"); +defineSymbol(math, main, bin, "\u2020", "\\dagger"); +defineSymbol(math, main, bin, "\u22c4", "\\diamond"); +defineSymbol(math, main, bin, "\u22c6", "\\star"); +defineSymbol(math, main, bin, "\u25c3", "\\triangleleft"); +defineSymbol(math, main, bin, "\u25b9", "\\triangleright"); +defineSymbol(math, main, open, "{", "\\{"); +defineSymbol(text, main, textord, "{", "\\{"); +defineSymbol(text, main, textord, "{", "\\textbraceleft"); +defineSymbol(math, main, close, "}", "\\}"); +defineSymbol(text, main, textord, "}", "\\}"); +defineSymbol(text, main, textord, "}", "\\textbraceright"); +defineSymbol(math, main, open, "{", "\\lbrace"); +defineSymbol(math, main, close, "}", "\\rbrace"); +defineSymbol(math, main, open, "[", "\\lbrack", true); +defineSymbol(text, main, textord, "[", "\\lbrack", true); +defineSymbol(math, main, close, "]", "\\rbrack", true); +defineSymbol(text, main, textord, "]", "\\rbrack", true); +defineSymbol(math, main, open, "(", "\\lparen", true); +defineSymbol(math, main, close, ")", "\\rparen", true); +defineSymbol(text, main, textord, "<", "\\textless", true); // in T1 fontenc + +defineSymbol(text, main, textord, ">", "\\textgreater", true); // in T1 fontenc + +defineSymbol(math, main, open, "\u230a", "\\lfloor", true); +defineSymbol(math, main, close, "\u230b", "\\rfloor", true); +defineSymbol(math, main, open, "\u2308", "\\lceil", true); +defineSymbol(math, main, close, "\u2309", "\\rceil", true); +defineSymbol(math, main, textord, "\\", "\\backslash"); +defineSymbol(math, main, textord, "\u2223", "|"); +defineSymbol(math, main, textord, "\u2223", "\\vert"); +defineSymbol(text, main, textord, "|", "\\textbar", true); // in T1 fontenc + +defineSymbol(math, main, textord, "\u2225", "\\|"); +defineSymbol(math, main, textord, "\u2225", "\\Vert"); +defineSymbol(text, main, textord, "\u2225", "\\textbardbl"); +defineSymbol(text, main, textord, "~", "\\textasciitilde"); +defineSymbol(text, main, textord, "\\", "\\textbackslash"); +defineSymbol(text, main, textord, "^", "\\textasciicircum"); +defineSymbol(math, main, rel, "\u2191", "\\uparrow", true); +defineSymbol(math, main, rel, "\u21d1", "\\Uparrow", true); +defineSymbol(math, main, rel, "\u2193", "\\downarrow", true); +defineSymbol(math, main, rel, "\u21d3", "\\Downarrow", true); +defineSymbol(math, main, rel, "\u2195", "\\updownarrow", true); +defineSymbol(math, main, rel, "\u21d5", "\\Updownarrow", true); +defineSymbol(math, main, op, "\u2210", "\\coprod"); +defineSymbol(math, main, op, "\u22c1", "\\bigvee"); +defineSymbol(math, main, op, "\u22c0", "\\bigwedge"); +defineSymbol(math, main, op, "\u2a04", "\\biguplus"); +defineSymbol(math, main, op, "\u22c2", "\\bigcap"); +defineSymbol(math, main, op, "\u22c3", "\\bigcup"); +defineSymbol(math, main, op, "\u222b", "\\int"); +defineSymbol(math, main, op, "\u222b", "\\intop"); +defineSymbol(math, main, op, "\u222c", "\\iint"); +defineSymbol(math, main, op, "\u222d", "\\iiint"); +defineSymbol(math, main, op, "\u220f", "\\prod"); +defineSymbol(math, main, op, "\u2211", "\\sum"); +defineSymbol(math, main, op, "\u2a02", "\\bigotimes"); +defineSymbol(math, main, op, "\u2a01", "\\bigoplus"); +defineSymbol(math, main, op, "\u2a00", "\\bigodot"); +defineSymbol(math, main, op, "\u222e", "\\oint"); +defineSymbol(math, main, op, "\u222f", "\\oiint"); +defineSymbol(math, main, op, "\u2230", "\\oiiint"); +defineSymbol(math, main, op, "\u2a06", "\\bigsqcup"); +defineSymbol(math, main, op, "\u222b", "\\smallint"); +defineSymbol(text, main, inner, "\u2026", "\\textellipsis"); +defineSymbol(math, main, inner, "\u2026", "\\mathellipsis"); +defineSymbol(text, main, inner, "\u2026", "\\ldots", true); +defineSymbol(math, main, inner, "\u2026", "\\ldots", true); +defineSymbol(math, main, inner, "\u22ef", "\\@cdots", true); +defineSymbol(math, main, inner, "\u22f1", "\\ddots", true); +defineSymbol(math, main, textord, "\u22ee", "\\varvdots"); // \vdots is a macro + +defineSymbol(math, main, accent, "\u02ca", "\\acute"); +defineSymbol(math, main, accent, "\u02cb", "\\grave"); +defineSymbol(math, main, accent, "\u00a8", "\\ddot"); +defineSymbol(math, main, accent, "\u007e", "\\tilde"); +defineSymbol(math, main, accent, "\u02c9", "\\bar"); +defineSymbol(math, main, accent, "\u02d8", "\\breve"); +defineSymbol(math, main, accent, "\u02c7", "\\check"); +defineSymbol(math, main, accent, "\u005e", "\\hat"); +defineSymbol(math, main, accent, "\u20d7", "\\vec"); +defineSymbol(math, main, accent, "\u02d9", "\\dot"); +defineSymbol(math, main, accent, "\u02da", "\\mathring"); // \imath and \jmath should be invariant to \mathrm, \mathbf, etc., so use PUA + +defineSymbol(math, main, mathord, "\ue131", "\\@imath"); +defineSymbol(math, main, mathord, "\ue237", "\\@jmath"); +defineSymbol(math, main, textord, "\u0131", "\u0131"); +defineSymbol(math, main, textord, "\u0237", "\u0237"); +defineSymbol(text, main, textord, "\u0131", "\\i", true); +defineSymbol(text, main, textord, "\u0237", "\\j", true); +defineSymbol(text, main, textord, "\u00df", "\\ss", true); +defineSymbol(text, main, textord, "\u00e6", "\\ae", true); +defineSymbol(text, main, textord, "\u0153", "\\oe", true); +defineSymbol(text, main, textord, "\u00f8", "\\o", true); +defineSymbol(text, main, textord, "\u00c6", "\\AE", true); +defineSymbol(text, main, textord, "\u0152", "\\OE", true); +defineSymbol(text, main, textord, "\u00d8", "\\O", true); +defineSymbol(text, main, accent, "\u02ca", "\\'"); // acute + +defineSymbol(text, main, accent, "\u02cb", "\\`"); // grave + +defineSymbol(text, main, accent, "\u02c6", "\\^"); // circumflex + +defineSymbol(text, main, accent, "\u02dc", "\\~"); // tilde + +defineSymbol(text, main, accent, "\u02c9", "\\="); // macron + +defineSymbol(text, main, accent, "\u02d8", "\\u"); // breve + +defineSymbol(text, main, accent, "\u02d9", "\\."); // dot above + +defineSymbol(text, main, accent, "\u00b8", "\\c"); // cedilla + +defineSymbol(text, main, accent, "\u02da", "\\r"); // ring above + +defineSymbol(text, main, accent, "\u02c7", "\\v"); // caron + +defineSymbol(text, main, accent, "\u00a8", '\\"'); // diaresis + +defineSymbol(text, main, accent, "\u02dd", "\\H"); // double acute + +defineSymbol(text, main, accent, "\u25ef", "\\textcircled"); // \bigcirc glyph +// These ligatures are detected and created in Parser.js's `formLigatures`. + +var ligatures = { + "--": true, + "---": true, + "``": true, + "''": true +}; +defineSymbol(text, main, textord, "\u2013", "--", true); +defineSymbol(text, main, textord, "\u2013", "\\textendash"); +defineSymbol(text, main, textord, "\u2014", "---", true); +defineSymbol(text, main, textord, "\u2014", "\\textemdash"); +defineSymbol(text, main, textord, "\u2018", "`", true); +defineSymbol(text, main, textord, "\u2018", "\\textquoteleft"); +defineSymbol(text, main, textord, "\u2019", "'", true); +defineSymbol(text, main, textord, "\u2019", "\\textquoteright"); +defineSymbol(text, main, textord, "\u201c", "``", true); +defineSymbol(text, main, textord, "\u201c", "\\textquotedblleft"); +defineSymbol(text, main, textord, "\u201d", "''", true); +defineSymbol(text, main, textord, "\u201d", "\\textquotedblright"); // \degree from gensymb package + +defineSymbol(math, main, textord, "\u00b0", "\\degree", true); +defineSymbol(text, main, textord, "\u00b0", "\\degree"); // \textdegree from inputenc package + +defineSymbol(text, main, textord, "\u00b0", "\\textdegree", true); // TODO: In LaTeX, \pounds can generate a different character in text and math +// mode, but among our fonts, only Main-Regular defines this character "163". + +defineSymbol(math, main, textord, "\u00a3", "\\pounds"); +defineSymbol(math, main, textord, "\u00a3", "\\mathsterling", true); +defineSymbol(text, main, textord, "\u00a3", "\\pounds"); +defineSymbol(text, main, textord, "\u00a3", "\\textsterling", true); +defineSymbol(math, ams, textord, "\u2720", "\\maltese"); +defineSymbol(text, ams, textord, "\u2720", "\\maltese"); // There are lots of symbols which are the same, so we add them in afterwards. +// All of these are textords in math mode + +var mathTextSymbols = "0123456789/@.\""; + +for (var i = 0; i < mathTextSymbols.length; i++) { + var ch = mathTextSymbols.charAt(i); + defineSymbol(math, main, textord, ch, ch); +} // All of these are textords in text mode + + +var textSymbols = "0123456789!@*()-=+\";:?/.,"; + +for (var _i = 0; _i < textSymbols.length; _i++) { + var _ch = textSymbols.charAt(_i); + + defineSymbol(text, main, textord, _ch, _ch); +} // All of these are textords in text mode, and mathords in math mode + + +var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +for (var _i2 = 0; _i2 < letters.length; _i2++) { + var _ch2 = letters.charAt(_i2); + + defineSymbol(math, main, mathord, _ch2, _ch2); + defineSymbol(text, main, textord, _ch2, _ch2); +} // Blackboard bold and script letters in Unicode range + + +defineSymbol(math, ams, textord, "C", "\u2102"); // blackboard bold + +defineSymbol(text, ams, textord, "C", "\u2102"); +defineSymbol(math, ams, textord, "H", "\u210D"); +defineSymbol(text, ams, textord, "H", "\u210D"); +defineSymbol(math, ams, textord, "N", "\u2115"); +defineSymbol(text, ams, textord, "N", "\u2115"); +defineSymbol(math, ams, textord, "P", "\u2119"); +defineSymbol(text, ams, textord, "P", "\u2119"); +defineSymbol(math, ams, textord, "Q", "\u211A"); +defineSymbol(text, ams, textord, "Q", "\u211A"); +defineSymbol(math, ams, textord, "R", "\u211D"); +defineSymbol(text, ams, textord, "R", "\u211D"); +defineSymbol(math, ams, textord, "Z", "\u2124"); +defineSymbol(text, ams, textord, "Z", "\u2124"); +defineSymbol(math, main, mathord, "h", "\u210E"); // italic h, Planck constant + +defineSymbol(text, main, mathord, "h", "\u210E"); // The next loop loads wide (surrogate pair) characters. +// We support some letters in the Unicode range U+1D400 to U+1D7FF, +// Mathematical Alphanumeric Symbols. +// Some editors do not deal well with wide characters. So don't write the +// string into this file. Instead, create the string from the surrogate pair. + +var wideChar = ""; + +for (var _i3 = 0; _i3 < letters.length; _i3++) { + var _ch3 = letters.charAt(_i3); // The hex numbers in the next line are a surrogate pair. + // 0xD835 is the high surrogate for all letters in the range we support. + // 0xDC00 is the low surrogate for bold A. + + + wideChar = String.fromCharCode(0xD835, 0xDC00 + _i3); // A-Z a-z bold + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDC34 + _i3); // A-Z a-z italic + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDC68 + _i3); // A-Z a-z bold italic + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDD04 + _i3); // A-Z a-z Fractur + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDD6C + _i3); // A-Z a-z bold Fractur + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDDA0 + _i3); // A-Z a-z sans-serif + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDDD4 + _i3); // A-Z a-z sans bold + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDE08 + _i3); // A-Z a-z sans italic + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDE70 + _i3); // A-Z a-z monospace + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(text, main, textord, _ch3, wideChar); + + if (_i3 < 26) { + // KaTeX fonts have only capital letters for blackboard bold and script. + // See exception for k below. + wideChar = String.fromCharCode(0xD835, 0xDD38 + _i3); // A-Z double struck + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(text, main, textord, _ch3, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDC9C + _i3); // A-Z script + + defineSymbol(math, main, mathord, _ch3, wideChar); + defineSymbol(text, main, textord, _ch3, wideChar); + } // TODO: Add bold script when it is supported by a KaTeX font. + +} // "k" is the only double struck lower case letter in the KaTeX fonts. + + +wideChar = String.fromCharCode(0xD835, 0xDD5C); // k double struck + +defineSymbol(math, main, mathord, "k", wideChar); +defineSymbol(text, main, textord, "k", wideChar); // Next, some wide character numerals + +for (var _i4 = 0; _i4 < 10; _i4++) { + var _ch4 = _i4.toString(); + + wideChar = String.fromCharCode(0xD835, 0xDFCE + _i4); // 0-9 bold + + defineSymbol(math, main, mathord, _ch4, wideChar); + defineSymbol(text, main, textord, _ch4, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDFE2 + _i4); // 0-9 sans serif + + defineSymbol(math, main, mathord, _ch4, wideChar); + defineSymbol(text, main, textord, _ch4, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDFEC + _i4); // 0-9 bold sans + + defineSymbol(math, main, mathord, _ch4, wideChar); + defineSymbol(text, main, textord, _ch4, wideChar); + wideChar = String.fromCharCode(0xD835, 0xDFF6 + _i4); // 0-9 monospace + + defineSymbol(math, main, mathord, _ch4, wideChar); + defineSymbol(text, main, textord, _ch4, wideChar); +} // We add these Latin-1 letters as symbols for backwards-compatibility, +// but they are not actually in the font, nor are they supported by the +// Unicode accent mechanism, so they fall back to Times font and look ugly. +// TODO(edemaine): Fix this. + + +var extraLatin = "\u00d0\u00de\u00fe"; + +for (var _i5 = 0; _i5 < extraLatin.length; _i5++) { + var _ch5 = extraLatin.charAt(_i5); + + defineSymbol(math, main, mathord, _ch5, _ch5); + defineSymbol(text, main, textord, _ch5, _ch5); +} + +/** + * This file provides support for Unicode range U+1D400 to U+1D7FF, + * Mathematical Alphanumeric Symbols. + * + * Function wideCharacterFont takes a wide character as input and returns + * the font information necessary to render it properly. + */ +/** + * Data below is from https://www.unicode.org/charts/PDF/U1D400.pdf + * That document sorts characters into groups by font type, say bold or italic. + * + * In the arrays below, each subarray consists three elements: + * * The CSS class of that group when in math mode. + * * The CSS class of that group when in text mode. + * * The font name, so that KaTeX can get font metrics. + */ + +var wideLatinLetterData = [["mathbf", "textbf", "Main-Bold"], // A-Z bold upright +["mathbf", "textbf", "Main-Bold"], // a-z bold upright +["mathnormal", "textit", "Math-Italic"], // A-Z italic +["mathnormal", "textit", "Math-Italic"], // a-z italic +["boldsymbol", "boldsymbol", "Main-BoldItalic"], // A-Z bold italic +["boldsymbol", "boldsymbol", "Main-BoldItalic"], // a-z bold italic +// Map fancy A-Z letters to script, not calligraphic. +// This aligns with unicode-math and math fonts (except Cambria Math). +["mathscr", "textscr", "Script-Regular"], // A-Z script +["", "", ""], // a-z script. No font +["", "", ""], // A-Z bold script. No font +["", "", ""], // a-z bold script. No font +["mathfrak", "textfrak", "Fraktur-Regular"], // A-Z Fraktur +["mathfrak", "textfrak", "Fraktur-Regular"], // a-z Fraktur +["mathbb", "textbb", "AMS-Regular"], // A-Z double-struck +["mathbb", "textbb", "AMS-Regular"], // k double-struck +// Note that we are using a bold font, but font metrics for regular Fraktur. +["mathboldfrak", "textboldfrak", "Fraktur-Regular"], // A-Z bold Fraktur +["mathboldfrak", "textboldfrak", "Fraktur-Regular"], // a-z bold Fraktur +["mathsf", "textsf", "SansSerif-Regular"], // A-Z sans-serif +["mathsf", "textsf", "SansSerif-Regular"], // a-z sans-serif +["mathboldsf", "textboldsf", "SansSerif-Bold"], // A-Z bold sans-serif +["mathboldsf", "textboldsf", "SansSerif-Bold"], // a-z bold sans-serif +["mathitsf", "textitsf", "SansSerif-Italic"], // A-Z italic sans-serif +["mathitsf", "textitsf", "SansSerif-Italic"], // a-z italic sans-serif +["", "", ""], // A-Z bold italic sans. No font +["", "", ""], // a-z bold italic sans. No font +["mathtt", "texttt", "Typewriter-Regular"], // A-Z monospace +["mathtt", "texttt", "Typewriter-Regular"] // a-z monospace +]; +var wideNumeralData = [["mathbf", "textbf", "Main-Bold"], // 0-9 bold +["", "", ""], // 0-9 double-struck. No KaTeX font. +["mathsf", "textsf", "SansSerif-Regular"], // 0-9 sans-serif +["mathboldsf", "textboldsf", "SansSerif-Bold"], // 0-9 bold sans-serif +["mathtt", "texttt", "Typewriter-Regular"] // 0-9 monospace +]; +var wideCharacterFont = function wideCharacterFont(wideChar, mode) { + // IE doesn't support codePointAt(). So work with the surrogate pair. + var H = wideChar.charCodeAt(0); // high surrogate + + var L = wideChar.charCodeAt(1); // low surrogate + + var codePoint = (H - 0xD800) * 0x400 + (L - 0xDC00) + 0x10000; + var j = mode === "math" ? 0 : 1; // column index for CSS class. + + if (0x1D400 <= codePoint && codePoint < 0x1D6A4) { + // wideLatinLetterData contains exactly 26 chars on each row. + // So we can calculate the relevant row. No traverse necessary. + var i = Math.floor((codePoint - 0x1D400) / 26); + return [wideLatinLetterData[i][2], wideLatinLetterData[i][j]]; + } else if (0x1D7CE <= codePoint && codePoint <= 0x1D7FF) { + // Numerals, ten per row. + var _i = Math.floor((codePoint - 0x1D7CE) / 10); + + return [wideNumeralData[_i][2], wideNumeralData[_i][j]]; + } else if (codePoint === 0x1D6A5 || codePoint === 0x1D6A6) { + // dotless i or j + return [wideLatinLetterData[0][2], wideLatinLetterData[0][j]]; + } else if (0x1D6A6 < codePoint && codePoint < 0x1D7CE) { + // Greek letters. Not supported, yet. + return ["", ""]; + } else { + // We don't support any wide characters outside 1D400–1D7FF. + throw new ParseError("Unsupported character: " + wideChar); + } +}; + +/* eslint no-console:0 */ + +/** + * Looks up the given symbol in fontMetrics, after applying any symbol + * replacements defined in symbol.js + */ +var lookupSymbol = function lookupSymbol(value, // TODO(#963): Use a union type for this. +fontName, mode) { + // Replace the value with its replaced value from symbol.js + if (symbols[mode][value] && symbols[mode][value].replace) { + value = symbols[mode][value].replace; + } + + return { + value: value, + metrics: getCharacterMetrics(value, fontName, mode) + }; +}; +/** + * Makes a symbolNode after translation via the list of symbols in symbols.js. + * Correctly pulls out metrics for the character, and optionally takes a list of + * classes to be attached to the node. + * + * TODO: make argument order closer to makeSpan + * TODO: add a separate argument for math class (e.g. `mop`, `mbin`), which + * should if present come first in `classes`. + * TODO(#953): Make `options` mandatory and always pass it in. + */ + + +var makeSymbol = function makeSymbol(value, fontName, mode, options, classes) { + var lookup = lookupSymbol(value, fontName, mode); + var metrics = lookup.metrics; + value = lookup.value; + var symbolNode; + + if (metrics) { + var italic = metrics.italic; + + if (mode === "text" || options && options.font === "mathit") { + italic = 0; + } + + symbolNode = new SymbolNode(value, metrics.height, metrics.depth, italic, metrics.skew, metrics.width, classes); + } else { + // TODO(emily): Figure out a good way to only print this in development + typeof console !== "undefined" && console.warn("No character metrics " + ("for '" + value + "' in style '" + fontName + "' and mode '" + mode + "'")); + symbolNode = new SymbolNode(value, 0, 0, 0, 0, 0, classes); + } + + if (options) { + symbolNode.maxFontSize = options.sizeMultiplier; + + if (options.style.isTight()) { + symbolNode.classes.push("mtight"); + } + + var color = options.getColor(); + + if (color) { + symbolNode.style.color = color; + } + } + + return symbolNode; +}; +/** + * Makes a symbol in Main-Regular or AMS-Regular. + * Used for rel, bin, open, close, inner, and punct. + */ + + +var mathsym = function mathsym(value, mode, options, classes) { + if (classes === void 0) { + classes = []; + } + + // Decide what font to render the symbol in by its entry in the symbols + // table. + // Have a special case for when the value = \ because the \ is used as a + // textord in unsupported command errors but cannot be parsed as a regular + // text ordinal and is therefore not present as a symbol in the symbols + // table for text, as well as a special case for boldsymbol because it + // can be used for bold + and - + if (options.font === "boldsymbol" && lookupSymbol(value, "Main-Bold", mode).metrics) { + return makeSymbol(value, "Main-Bold", mode, options, classes.concat(["mathbf"])); + } else if (value === "\\" || symbols[mode][value].font === "main") { + return makeSymbol(value, "Main-Regular", mode, options, classes); + } else { + return makeSymbol(value, "AMS-Regular", mode, options, classes.concat(["amsrm"])); + } +}; +/** + * Determines which of the two font names (Main-Bold and Math-BoldItalic) and + * corresponding style tags (mathbf or boldsymbol) to use for font "boldsymbol", + * depending on the symbol. Use this function instead of fontMap for font + * "boldsymbol". + */ + + +var boldsymbol = function boldsymbol(value, mode, options, classes, type) { + if (type !== "textord" && lookupSymbol(value, "Math-BoldItalic", mode).metrics) { + return { + fontName: "Math-BoldItalic", + fontClass: "boldsymbol" + }; + } else { + // Some glyphs do not exist in Math-BoldItalic so we need to use + // Main-Bold instead. + return { + fontName: "Main-Bold", + fontClass: "mathbf" + }; + } +}; +/** + * Makes either a mathord or textord in the correct font and color. + */ + + +var makeOrd = function makeOrd(group, options, type) { + var mode = group.mode; + var text = group.text; + var classes = ["mord"]; // Math mode or Old font (i.e. \rm) + + var isFont = mode === "math" || mode === "text" && options.font; + var fontOrFamily = isFont ? options.font : options.fontFamily; + var wideFontName = ""; + var wideFontClass = ""; + + if (text.charCodeAt(0) === 0xD835) { + [wideFontName, wideFontClass] = wideCharacterFont(text, mode); + } + + if (wideFontName.length > 0) { + // surrogate pairs get special treatment + return makeSymbol(text, wideFontName, mode, options, classes.concat(wideFontClass)); + } else if (fontOrFamily) { + var fontName; + var fontClasses; + + if (fontOrFamily === "boldsymbol") { + var fontData = boldsymbol(text, mode, options, classes, type); + fontName = fontData.fontName; + fontClasses = [fontData.fontClass]; + } else if (isFont) { + fontName = fontMap[fontOrFamily].fontName; + fontClasses = [fontOrFamily]; + } else { + fontName = retrieveTextFontName(fontOrFamily, options.fontWeight, options.fontShape); + fontClasses = [fontOrFamily, options.fontWeight, options.fontShape]; + } + + if (lookupSymbol(text, fontName, mode).metrics) { + return makeSymbol(text, fontName, mode, options, classes.concat(fontClasses)); + } else if (ligatures.hasOwnProperty(text) && fontName.slice(0, 10) === "Typewriter") { + // Deconstruct ligatures in monospace fonts (\texttt, \tt). + var parts = []; + + for (var i = 0; i < text.length; i++) { + parts.push(makeSymbol(text[i], fontName, mode, options, classes.concat(fontClasses))); + } + + return makeFragment(parts); + } + } // Makes a symbol in the default font for mathords and textords. + + + if (type === "mathord") { + return makeSymbol(text, "Math-Italic", mode, options, classes.concat(["mathnormal"])); + } else if (type === "textord") { + var font = symbols[mode][text] && symbols[mode][text].font; + + if (font === "ams") { + var _fontName = retrieveTextFontName("amsrm", options.fontWeight, options.fontShape); + + return makeSymbol(text, _fontName, mode, options, classes.concat("amsrm", options.fontWeight, options.fontShape)); + } else if (font === "main" || !font) { + var _fontName2 = retrieveTextFontName("textrm", options.fontWeight, options.fontShape); + + return makeSymbol(text, _fontName2, mode, options, classes.concat(options.fontWeight, options.fontShape)); + } else { + // fonts added by plugins + var _fontName3 = retrieveTextFontName(font, options.fontWeight, options.fontShape); // We add font name as a css class + + + return makeSymbol(text, _fontName3, mode, options, classes.concat(_fontName3, options.fontWeight, options.fontShape)); + } + } else { + throw new Error("unexpected type: " + type + " in makeOrd"); + } +}; +/** + * Returns true if subsequent symbolNodes have the same classes, skew, maxFont, + * and styles. + */ + + +var canCombine = (prev, next) => { + if (createClass(prev.classes) !== createClass(next.classes) || prev.skew !== next.skew || prev.maxFontSize !== next.maxFontSize) { + return false; + } // If prev and next both are just "mbin"s or "mord"s we don't combine them + // so that the proper spacing can be preserved. + + + if (prev.classes.length === 1) { + var cls = prev.classes[0]; + + if (cls === "mbin" || cls === "mord") { + return false; + } + } + + for (var style in prev.style) { + if (prev.style.hasOwnProperty(style) && prev.style[style] !== next.style[style]) { + return false; + } + } + + for (var _style in next.style) { + if (next.style.hasOwnProperty(_style) && prev.style[_style] !== next.style[_style]) { + return false; + } + } + + return true; +}; +/** + * Combine consecutive domTree.symbolNodes into a single symbolNode. + * Note: this function mutates the argument. + */ + + +var tryCombineChars = chars => { + for (var i = 0; i < chars.length - 1; i++) { + var prev = chars[i]; + var next = chars[i + 1]; + + if (prev instanceof SymbolNode && next instanceof SymbolNode && canCombine(prev, next)) { + prev.text += next.text; + prev.height = Math.max(prev.height, next.height); + prev.depth = Math.max(prev.depth, next.depth); // Use the last character's italic correction since we use + // it to add padding to the right of the span created from + // the combined characters. + + prev.italic = next.italic; + chars.splice(i + 1, 1); + i--; + } + } + + return chars; +}; +/** + * Calculate the height, depth, and maxFontSize of an element based on its + * children. + */ + + +var sizeElementFromChildren = function sizeElementFromChildren(elem) { + var height = 0; + var depth = 0; + var maxFontSize = 0; + + for (var i = 0; i < elem.children.length; i++) { + var child = elem.children[i]; + + if (child.height > height) { + height = child.height; + } + + if (child.depth > depth) { + depth = child.depth; + } + + if (child.maxFontSize > maxFontSize) { + maxFontSize = child.maxFontSize; + } + } + + elem.height = height; + elem.depth = depth; + elem.maxFontSize = maxFontSize; +}; +/** + * Makes a span with the given list of classes, list of children, and options. + * + * TODO(#953): Ensure that `options` is always provided (currently some call + * sites don't pass it) and make the type below mandatory. + * TODO: add a separate argument for math class (e.g. `mop`, `mbin`), which + * should if present come first in `classes`. + */ + + +var makeSpan$2 = function makeSpan(classes, children, options, style) { + var span = new Span(classes, children, options, style); + sizeElementFromChildren(span); + return span; +}; // SVG one is simpler -- doesn't require height, depth, max-font setting. +// This is also a separate method for typesafety. + + +var makeSvgSpan = (classes, children, options, style) => new Span(classes, children, options, style); + +var makeLineSpan = function makeLineSpan(className, options, thickness) { + var line = makeSpan$2([className], [], options); + line.height = Math.max(thickness || options.fontMetrics().defaultRuleThickness, options.minRuleThickness); + line.style.borderBottomWidth = makeEm(line.height); + line.maxFontSize = 1.0; + return line; +}; +/** + * Makes an anchor with the given href, list of classes, list of children, + * and options. + */ + + +var makeAnchor = function makeAnchor(href, classes, children, options) { + var anchor = new Anchor(href, classes, children, options); + sizeElementFromChildren(anchor); + return anchor; +}; +/** + * Makes a document fragment with the given list of children. + */ + + +var makeFragment = function makeFragment(children) { + var fragment = new DocumentFragment(children); + sizeElementFromChildren(fragment); + return fragment; +}; +/** + * Wraps group in a span if it's a document fragment, allowing to apply classes + * and styles + */ + + +var wrapFragment = function wrapFragment(group, options) { + if (group instanceof DocumentFragment) { + return makeSpan$2([], [group], options); + } + + return group; +}; // These are exact object types to catch typos in the names of the optional fields. + + +// Computes the updated `children` list and the overall depth. +// +// This helper function for makeVList makes it easier to enforce type safety by +// allowing early exits (returns) in the logic. +var getVListChildrenAndDepth = function getVListChildrenAndDepth(params) { + if (params.positionType === "individualShift") { + var oldChildren = params.children; + var children = [oldChildren[0]]; // Add in kerns to the list of params.children to get each element to be + // shifted to the correct specified shift + + var _depth = -oldChildren[0].shift - oldChildren[0].elem.depth; + + var currPos = _depth; + + for (var i = 1; i < oldChildren.length; i++) { + var diff = -oldChildren[i].shift - currPos - oldChildren[i].elem.depth; + var size = diff - (oldChildren[i - 1].elem.height + oldChildren[i - 1].elem.depth); + currPos = currPos + diff; + children.push({ + type: "kern", + size + }); + children.push(oldChildren[i]); + } + + return { + children, + depth: _depth + }; + } + + var depth; + + if (params.positionType === "top") { + // We always start at the bottom, so calculate the bottom by adding up + // all the sizes + var bottom = params.positionData; + + for (var _i = 0; _i < params.children.length; _i++) { + var child = params.children[_i]; + bottom -= child.type === "kern" ? child.size : child.elem.height + child.elem.depth; + } + + depth = bottom; + } else if (params.positionType === "bottom") { + depth = -params.positionData; + } else { + var firstChild = params.children[0]; + + if (firstChild.type !== "elem") { + throw new Error('First child must have type "elem".'); + } + + if (params.positionType === "shift") { + depth = -firstChild.elem.depth - params.positionData; + } else if (params.positionType === "firstBaseline") { + depth = -firstChild.elem.depth; + } else { + throw new Error("Invalid positionType " + params.positionType + "."); + } + } + + return { + children: params.children, + depth + }; +}; +/** + * Makes a vertical list by stacking elements and kerns on top of each other. + * Allows for many different ways of specifying the positioning method. + * + * See VListParam documentation above. + */ + + +var makeVList = function makeVList(params, options) { + var { + children, + depth + } = getVListChildrenAndDepth(params); // Create a strut that is taller than any list item. The strut is added to + // each item, where it will determine the item's baseline. Since it has + // `overflow:hidden`, the strut's top edge will sit on the item's line box's + // top edge and the strut's bottom edge will sit on the item's baseline, + // with no additional line-height spacing. This allows the item baseline to + // be positioned precisely without worrying about font ascent and + // line-height. + + var pstrutSize = 0; + + for (var i = 0; i < children.length; i++) { + var child = children[i]; + + if (child.type === "elem") { + var elem = child.elem; + pstrutSize = Math.max(pstrutSize, elem.maxFontSize, elem.height); + } + } + + pstrutSize += 2; + var pstrut = makeSpan$2(["pstrut"], []); + pstrut.style.height = makeEm(pstrutSize); // Create a new list of actual children at the correct offsets + + var realChildren = []; + var minPos = depth; + var maxPos = depth; + var currPos = depth; + + for (var _i2 = 0; _i2 < children.length; _i2++) { + var _child = children[_i2]; + + if (_child.type === "kern") { + currPos += _child.size; + } else { + var _elem = _child.elem; + var classes = _child.wrapperClasses || []; + var style = _child.wrapperStyle || {}; + var childWrap = makeSpan$2(classes, [pstrut, _elem], undefined, style); + childWrap.style.top = makeEm(-pstrutSize - currPos - _elem.depth); + + if (_child.marginLeft) { + childWrap.style.marginLeft = _child.marginLeft; + } + + if (_child.marginRight) { + childWrap.style.marginRight = _child.marginRight; + } + + realChildren.push(childWrap); + currPos += _elem.height + _elem.depth; + } + + minPos = Math.min(minPos, currPos); + maxPos = Math.max(maxPos, currPos); + } // The vlist contents go in a table-cell with `vertical-align:bottom`. + // This cell's bottom edge will determine the containing table's baseline + // without overly expanding the containing line-box. + + + var vlist = makeSpan$2(["vlist"], realChildren); + vlist.style.height = makeEm(maxPos); // A second row is used if necessary to represent the vlist's depth. + + var rows; + + if (minPos < 0) { + // We will define depth in an empty span with display: table-cell. + // It should render with the height that we define. But Chrome, in + // contenteditable mode only, treats that span as if it contains some + // text content. And that min-height over-rides our desired height. + // So we put another empty span inside the depth strut span. + var emptySpan = makeSpan$2([], []); + var depthStrut = makeSpan$2(["vlist"], [emptySpan]); + depthStrut.style.height = makeEm(-minPos); // Safari wants the first row to have inline content; otherwise it + // puts the bottom of the *second* row on the baseline. + + var topStrut = makeSpan$2(["vlist-s"], [new SymbolNode("\u200b")]); + rows = [makeSpan$2(["vlist-r"], [vlist, topStrut]), makeSpan$2(["vlist-r"], [depthStrut])]; + } else { + rows = [makeSpan$2(["vlist-r"], [vlist])]; + } + + var vtable = makeSpan$2(["vlist-t"], rows); + + if (rows.length === 2) { + vtable.classes.push("vlist-t2"); + } + + vtable.height = maxPos; + vtable.depth = -minPos; + return vtable; +}; // Glue is a concept from TeX which is a flexible space between elements in +// either a vertical or horizontal list. In KaTeX, at least for now, it's +// static space between elements in a horizontal layout. + + +var makeGlue = (measurement, options) => { + // Make an empty span for the space + var rule = makeSpan$2(["mspace"], [], options); + var size = calculateSize(measurement, options); + rule.style.marginRight = makeEm(size); + return rule; +}; // Takes font options, and returns the appropriate fontLookup name + + +var retrieveTextFontName = function retrieveTextFontName(fontFamily, fontWeight, fontShape) { + var baseFontName = ""; + + switch (fontFamily) { + case "amsrm": + baseFontName = "AMS"; + break; + + case "textrm": + baseFontName = "Main"; + break; + + case "textsf": + baseFontName = "SansSerif"; + break; + + case "texttt": + baseFontName = "Typewriter"; + break; + + default: + baseFontName = fontFamily; + // use fonts added by a plugin + } + + var fontStylesName; + + if (fontWeight === "textbf" && fontShape === "textit") { + fontStylesName = "BoldItalic"; + } else if (fontWeight === "textbf") { + fontStylesName = "Bold"; + } else if (fontWeight === "textit") { + fontStylesName = "Italic"; + } else { + fontStylesName = "Regular"; + } + + return baseFontName + "-" + fontStylesName; +}; +/** + * Maps TeX font commands to objects containing: + * - variant: string used for "mathvariant" attribute in buildMathML.js + * - fontName: the "style" parameter to fontMetrics.getCharacterMetrics + */ +// A map between tex font commands an MathML mathvariant attribute values + + +var fontMap = { + // styles + "mathbf": { + variant: "bold", + fontName: "Main-Bold" + }, + "mathrm": { + variant: "normal", + fontName: "Main-Regular" + }, + "textit": { + variant: "italic", + fontName: "Main-Italic" + }, + "mathit": { + variant: "italic", + fontName: "Main-Italic" + }, + "mathnormal": { + variant: "italic", + fontName: "Math-Italic" + }, + // "boldsymbol" is missing because they require the use of multiple fonts: + // Math-BoldItalic and Main-Bold. This is handled by a special case in + // makeOrd which ends up calling boldsymbol. + // families + "mathbb": { + variant: "double-struck", + fontName: "AMS-Regular" + }, + "mathcal": { + variant: "script", + fontName: "Caligraphic-Regular" + }, + "mathfrak": { + variant: "fraktur", + fontName: "Fraktur-Regular" + }, + "mathscr": { + variant: "script", + fontName: "Script-Regular" + }, + "mathsf": { + variant: "sans-serif", + fontName: "SansSerif-Regular" + }, + "mathtt": { + variant: "monospace", + fontName: "Typewriter-Regular" + } +}; +var svgData = { + // path, width, height + vec: ["vec", 0.471, 0.714], + // values from the font glyph + oiintSize1: ["oiintSize1", 0.957, 0.499], + // oval to overlay the integrand + oiintSize2: ["oiintSize2", 1.472, 0.659], + oiiintSize1: ["oiiintSize1", 1.304, 0.499], + oiiintSize2: ["oiiintSize2", 1.98, 0.659] +}; + +var staticSvg = function staticSvg(value, options) { + // Create a span with inline SVG for the element. + var [pathName, width, height] = svgData[value]; + var path = new PathNode(pathName); + var svgNode = new SvgNode([path], { + "width": makeEm(width), + "height": makeEm(height), + // Override CSS rule `.katex svg { width: 100% }` + "style": "width:" + makeEm(width), + "viewBox": "0 0 " + 1000 * width + " " + 1000 * height, + "preserveAspectRatio": "xMinYMin" + }); + var span = makeSvgSpan(["overlay"], [svgNode], options); + span.height = height; + span.style.height = makeEm(height); + span.style.width = makeEm(width); + return span; +}; + +var buildCommon = { + fontMap, + makeSymbol, + mathsym, + makeSpan: makeSpan$2, + makeSvgSpan, + makeLineSpan, + makeAnchor, + makeFragment, + wrapFragment, + makeVList, + makeOrd, + makeGlue, + staticSvg, + svgData, + tryCombineChars +}; + +/** + * Describes spaces between different classes of atoms. + */ +var thinspace = { + number: 3, + unit: "mu" +}; +var mediumspace = { + number: 4, + unit: "mu" +}; +var thickspace = { + number: 5, + unit: "mu" +}; // Making the type below exact with all optional fields doesn't work due to +// - https://github.com/facebook/flow/issues/4582 +// - https://github.com/facebook/flow/issues/5688 +// However, since *all* fields are optional, $Shape<> works as suggested in 5688 +// above. + +// Spacing relationships for display and text styles +var spacings = { + mord: { + mop: thinspace, + mbin: mediumspace, + mrel: thickspace, + minner: thinspace + }, + mop: { + mord: thinspace, + mop: thinspace, + mrel: thickspace, + minner: thinspace + }, + mbin: { + mord: mediumspace, + mop: mediumspace, + mopen: mediumspace, + minner: mediumspace + }, + mrel: { + mord: thickspace, + mop: thickspace, + mopen: thickspace, + minner: thickspace + }, + mopen: {}, + mclose: { + mop: thinspace, + mbin: mediumspace, + mrel: thickspace, + minner: thinspace + }, + mpunct: { + mord: thinspace, + mop: thinspace, + mrel: thickspace, + mopen: thinspace, + mclose: thinspace, + mpunct: thinspace, + minner: thinspace + }, + minner: { + mord: thinspace, + mop: thinspace, + mbin: mediumspace, + mrel: thickspace, + mopen: thinspace, + mpunct: thinspace, + minner: thinspace + } +}; // Spacing relationships for script and scriptscript styles + +var tightSpacings = { + mord: { + mop: thinspace + }, + mop: { + mord: thinspace, + mop: thinspace + }, + mbin: {}, + mrel: {}, + mopen: {}, + mclose: { + mop: thinspace + }, + mpunct: {}, + minner: { + mop: thinspace + } +}; + +/** Context provided to function handlers for error messages. */ +// Note: reverse the order of the return type union will cause a flow error. +// See https://github.com/facebook/flow/issues/3663. +// More general version of `HtmlBuilder` for nodes (e.g. \sum, accent types) +// whose presence impacts super/subscripting. In this case, ParseNode<"supsub"> +// delegates its HTML building to the HtmlBuilder corresponding to these nodes. + +/** + * Final function spec for use at parse time. + * This is almost identical to `FunctionPropSpec`, except it + * 1. includes the function handler, and + * 2. requires all arguments except argTypes. + * It is generated by `defineFunction()` below. + */ + +/** + * All registered functions. + * `functions.js` just exports this same dictionary again and makes it public. + * `Parser.js` requires this dictionary. + */ +var _functions = {}; +/** + * All HTML builders. Should be only used in the `define*` and the `build*ML` + * functions. + */ + +var _htmlGroupBuilders = {}; +/** + * All MathML builders. Should be only used in the `define*` and the `build*ML` + * functions. + */ + +var _mathmlGroupBuilders = {}; +function defineFunction(_ref) { + var { + type, + names, + props, + handler, + htmlBuilder, + mathmlBuilder + } = _ref; + // Set default values of functions + var data = { + type, + numArgs: props.numArgs, + argTypes: props.argTypes, + allowedInArgument: !!props.allowedInArgument, + allowedInText: !!props.allowedInText, + allowedInMath: props.allowedInMath === undefined ? true : props.allowedInMath, + numOptionalArgs: props.numOptionalArgs || 0, + infix: !!props.infix, + primitive: !!props.primitive, + handler: handler + }; + + for (var i = 0; i < names.length; ++i) { + _functions[names[i]] = data; + } + + if (type) { + if (htmlBuilder) { + _htmlGroupBuilders[type] = htmlBuilder; + } + + if (mathmlBuilder) { + _mathmlGroupBuilders[type] = mathmlBuilder; + } + } +} +/** + * Use this to register only the HTML and MathML builders for a function (e.g. + * if the function's ParseNode is generated in Parser.js rather than via a + * stand-alone handler provided to `defineFunction`). + */ + +function defineFunctionBuilders(_ref2) { + var { + type, + htmlBuilder, + mathmlBuilder + } = _ref2; + defineFunction({ + type, + names: [], + props: { + numArgs: 0 + }, + + handler() { + throw new Error('Should never be called.'); + }, + + htmlBuilder, + mathmlBuilder + }); +} +var normalizeArgument = function normalizeArgument(arg) { + return arg.type === "ordgroup" && arg.body.length === 1 ? arg.body[0] : arg; +}; // Since the corresponding buildHTML/buildMathML function expects a +// list of elements, we normalize for different kinds of arguments + +var ordargument = function ordargument(arg) { + return arg.type === "ordgroup" ? arg.body : [arg]; +}; + +/** + * This file does the main work of building a domTree structure from a parse + * tree. The entry point is the `buildHTML` function, which takes a parse tree. + * Then, the buildExpression, buildGroup, and various groupBuilders functions + * are called, to produce a final HTML tree. + */ +var makeSpan$1 = buildCommon.makeSpan; // Binary atoms (first class `mbin`) change into ordinary atoms (`mord`) +// depending on their surroundings. See TeXbook pg. 442-446, Rules 5 and 6, +// and the text before Rule 19. + +var binLeftCanceller = ["leftmost", "mbin", "mopen", "mrel", "mop", "mpunct"]; +var binRightCanceller = ["rightmost", "mrel", "mclose", "mpunct"]; +var styleMap$1 = { + "display": Style$1.DISPLAY, + "text": Style$1.TEXT, + "script": Style$1.SCRIPT, + "scriptscript": Style$1.SCRIPTSCRIPT +}; +var DomEnum = { + mord: "mord", + mop: "mop", + mbin: "mbin", + mrel: "mrel", + mopen: "mopen", + mclose: "mclose", + mpunct: "mpunct", + minner: "minner" +}; + +/** + * Take a list of nodes, build them in order, and return a list of the built + * nodes. documentFragments are flattened into their contents, so the + * returned list contains no fragments. `isRealGroup` is true if `expression` + * is a real group (no atoms will be added on either side), as opposed to + * a partial group (e.g. one created by \color). `surrounding` is an array + * consisting type of nodes that will be added to the left and right. + */ +var buildExpression$1 = function buildExpression(expression, options, isRealGroup, surrounding) { + if (surrounding === void 0) { + surrounding = [null, null]; + } + + // Parse expressions into `groups`. + var groups = []; + + for (var i = 0; i < expression.length; i++) { + var output = buildGroup$1(expression[i], options); + + if (output instanceof DocumentFragment) { + var children = output.children; + groups.push(...children); + } else { + groups.push(output); + } + } // Combine consecutive domTree.symbolNodes into a single symbolNode. + + + buildCommon.tryCombineChars(groups); // If `expression` is a partial group, let the parent handle spacings + // to avoid processing groups multiple times. + + if (!isRealGroup) { + return groups; + } + + var glueOptions = options; + + if (expression.length === 1) { + var node = expression[0]; + + if (node.type === "sizing") { + glueOptions = options.havingSize(node.size); + } else if (node.type === "styling") { + glueOptions = options.havingStyle(styleMap$1[node.style]); + } + } // Dummy spans for determining spacings between surrounding atoms. + // If `expression` has no atoms on the left or right, class "leftmost" + // or "rightmost", respectively, is used to indicate it. + + + var dummyPrev = makeSpan$1([surrounding[0] || "leftmost"], [], options); + var dummyNext = makeSpan$1([surrounding[1] || "rightmost"], [], options); // TODO: These code assumes that a node's math class is the first element + // of its `classes` array. A later cleanup should ensure this, for + // instance by changing the signature of `makeSpan`. + // Before determining what spaces to insert, perform bin cancellation. + // Binary operators change to ordinary symbols in some contexts. + + var isRoot = isRealGroup === "root"; + traverseNonSpaceNodes(groups, (node, prev) => { + var prevType = prev.classes[0]; + var type = node.classes[0]; + + if (prevType === "mbin" && utils.contains(binRightCanceller, type)) { + prev.classes[0] = "mord"; + } else if (type === "mbin" && utils.contains(binLeftCanceller, prevType)) { + node.classes[0] = "mord"; + } + }, { + node: dummyPrev + }, dummyNext, isRoot); + traverseNonSpaceNodes(groups, (node, prev) => { + var prevType = getTypeOfDomTree(prev); + var type = getTypeOfDomTree(node); // 'mtight' indicates that the node is script or scriptscript style. + + var space = prevType && type ? node.hasClass("mtight") ? tightSpacings[prevType][type] : spacings[prevType][type] : null; + + if (space) { + // Insert glue (spacing) after the `prev`. + return buildCommon.makeGlue(space, glueOptions); + } + }, { + node: dummyPrev + }, dummyNext, isRoot); + return groups; +}; // Depth-first traverse non-space `nodes`, calling `callback` with the current and +// previous node as arguments, optionally returning a node to insert after the +// previous node. `prev` is an object with the previous node and `insertAfter` +// function to insert after it. `next` is a node that will be added to the right. +// Used for bin cancellation and inserting spacings. + +var traverseNonSpaceNodes = function traverseNonSpaceNodes(nodes, callback, prev, next, isRoot) { + if (next) { + // temporarily append the right node, if exists + nodes.push(next); + } + + var i = 0; + + for (; i < nodes.length; i++) { + var node = nodes[i]; + var partialGroup = checkPartialGroup(node); + + if (partialGroup) { + // Recursive DFS + // $FlowFixMe: make nodes a $ReadOnlyArray by returning a new array + traverseNonSpaceNodes(partialGroup.children, callback, prev, null, isRoot); + continue; + } // Ignore explicit spaces (e.g., \;, \,) when determining what implicit + // spacing should go between atoms of different classes + + + var nonspace = !node.hasClass("mspace"); + + if (nonspace) { + var result = callback(node, prev.node); + + if (result) { + if (prev.insertAfter) { + prev.insertAfter(result); + } else { + // insert at front + nodes.unshift(result); + i++; + } + } + } + + if (nonspace) { + prev.node = node; + } else if (isRoot && node.hasClass("newline")) { + prev.node = makeSpan$1(["leftmost"]); // treat like beginning of line + } + + prev.insertAfter = (index => n => { + nodes.splice(index + 1, 0, n); + i++; + })(i); + } + + if (next) { + nodes.pop(); + } +}; // Check if given node is a partial group, i.e., does not affect spacing around. + + +var checkPartialGroup = function checkPartialGroup(node) { + if (node instanceof DocumentFragment || node instanceof Anchor || node instanceof Span && node.hasClass("enclosing")) { + return node; + } + + return null; +}; // Return the outermost node of a domTree. + + +var getOutermostNode = function getOutermostNode(node, side) { + var partialGroup = checkPartialGroup(node); + + if (partialGroup) { + var children = partialGroup.children; + + if (children.length) { + if (side === "right") { + return getOutermostNode(children[children.length - 1], "right"); + } else if (side === "left") { + return getOutermostNode(children[0], "left"); + } + } + } + + return node; +}; // Return math atom class (mclass) of a domTree. +// If `side` is given, it will get the type of the outermost node at given side. + + +var getTypeOfDomTree = function getTypeOfDomTree(node, side) { + if (!node) { + return null; + } + + if (side) { + node = getOutermostNode(node, side); + } // This makes a lot of assumptions as to where the type of atom + // appears. We should do a better job of enforcing this. + + + return DomEnum[node.classes[0]] || null; +}; +var makeNullDelimiter = function makeNullDelimiter(options, classes) { + var moreClasses = ["nulldelimiter"].concat(options.baseSizingClasses()); + return makeSpan$1(classes.concat(moreClasses)); +}; +/** + * buildGroup is the function that takes a group and calls the correct groupType + * function for it. It also handles the interaction of size and style changes + * between parents and children. + */ + +var buildGroup$1 = function buildGroup(group, options, baseOptions) { + if (!group) { + return makeSpan$1(); + } + + if (_htmlGroupBuilders[group.type]) { + // Call the groupBuilders function + // $FlowFixMe + var groupNode = _htmlGroupBuilders[group.type](group, options); // If the size changed between the parent and the current group, account + // for that size difference. + + if (baseOptions && options.size !== baseOptions.size) { + groupNode = makeSpan$1(options.sizingClasses(baseOptions), [groupNode], options); + var multiplier = options.sizeMultiplier / baseOptions.sizeMultiplier; + groupNode.height *= multiplier; + groupNode.depth *= multiplier; + } + + return groupNode; + } else { + throw new ParseError("Got group of unknown type: '" + group.type + "'"); + } +}; +/** + * Combine an array of HTML DOM nodes (e.g., the output of `buildExpression`) + * into an unbreakable HTML node of class .base, with proper struts to + * guarantee correct vertical extent. `buildHTML` calls this repeatedly to + * make up the entire expression as a sequence of unbreakable units. + */ + +function buildHTMLUnbreakable(children, options) { + // Compute height and depth of this chunk. + var body = makeSpan$1(["base"], children, options); // Add strut, which ensures that the top of the HTML element falls at + // the height of the expression, and the bottom of the HTML element + // falls at the depth of the expression. + + var strut = makeSpan$1(["strut"]); + strut.style.height = makeEm(body.height + body.depth); + + if (body.depth) { + strut.style.verticalAlign = makeEm(-body.depth); + } + + body.children.unshift(strut); + return body; +} +/** + * Take an entire parse tree, and build it into an appropriate set of HTML + * nodes. + */ + + +function buildHTML(tree, options) { + // Strip off outer tag wrapper for processing below. + var tag = null; + + if (tree.length === 1 && tree[0].type === "tag") { + tag = tree[0].tag; + tree = tree[0].body; + } // Build the expression contained in the tree + + + var expression = buildExpression$1(tree, options, "root"); + var eqnNum; + + if (expression.length === 2 && expression[1].hasClass("tag")) { + // An environment with automatic equation numbers, e.g. {gather}. + eqnNum = expression.pop(); + } + + var children = []; // Create one base node for each chunk between potential line breaks. + // The TeXBook [p.173] says "A formula will be broken only after a + // relation symbol like $=$ or $<$ or $\rightarrow$, or after a binary + // operation symbol like $+$ or $-$ or $\times$, where the relation or + // binary operation is on the ``outer level'' of the formula (i.e., not + // enclosed in {...} and not part of an \over construction)." + + var parts = []; + + for (var i = 0; i < expression.length; i++) { + parts.push(expression[i]); + + if (expression[i].hasClass("mbin") || expression[i].hasClass("mrel") || expression[i].hasClass("allowbreak")) { + // Put any post-operator glue on same line as operator. + // Watch for \nobreak along the way, and stop at \newline. + var nobreak = false; + + while (i < expression.length - 1 && expression[i + 1].hasClass("mspace") && !expression[i + 1].hasClass("newline")) { + i++; + parts.push(expression[i]); + + if (expression[i].hasClass("nobreak")) { + nobreak = true; + } + } // Don't allow break if \nobreak among the post-operator glue. + + + if (!nobreak) { + children.push(buildHTMLUnbreakable(parts, options)); + parts = []; + } + } else if (expression[i].hasClass("newline")) { + // Write the line except the newline + parts.pop(); + + if (parts.length > 0) { + children.push(buildHTMLUnbreakable(parts, options)); + parts = []; + } // Put the newline at the top level + + + children.push(expression[i]); + } + } + + if (parts.length > 0) { + children.push(buildHTMLUnbreakable(parts, options)); + } // Now, if there was a tag, build it too and append it as a final child. + + + var tagChild; + + if (tag) { + tagChild = buildHTMLUnbreakable(buildExpression$1(tag, options, true)); + tagChild.classes = ["tag"]; + children.push(tagChild); + } else if (eqnNum) { + children.push(eqnNum); + } + + var htmlNode = makeSpan$1(["katex-html"], children); + htmlNode.setAttribute("aria-hidden", "true"); // Adjust the strut of the tag to be the maximum height of all children + // (the height of the enclosing htmlNode) for proper vertical alignment. + + if (tagChild) { + var strut = tagChild.children[0]; + strut.style.height = makeEm(htmlNode.height + htmlNode.depth); + + if (htmlNode.depth) { + strut.style.verticalAlign = makeEm(-htmlNode.depth); + } + } + + return htmlNode; +} + +/** + * These objects store data about MathML nodes. This is the MathML equivalent + * of the types in domTree.js. Since MathML handles its own rendering, and + * since we're mainly using MathML to improve accessibility, we don't manage + * any of the styling state that the plain DOM nodes do. + * + * The `toNode` and `toMarkup` functions work similarly to how they do in + * domTree.js, creating namespaced DOM nodes and HTML text markup respectively. + */ +function newDocumentFragment(children) { + return new DocumentFragment(children); +} +/** + * This node represents a general purpose MathML node of any type. The + * constructor requires the type of node to create (for example, `"mo"` or + * `"mspace"`, corresponding to `` and `` tags). + */ + +class MathNode { + constructor(type, children, classes) { + this.type = void 0; + this.attributes = void 0; + this.children = void 0; + this.classes = void 0; + this.type = type; + this.attributes = {}; + this.children = children || []; + this.classes = classes || []; + } + /** + * Sets an attribute on a MathML node. MathML depends on attributes to convey a + * semantic content, so this is used heavily. + */ + + + setAttribute(name, value) { + this.attributes[name] = value; + } + /** + * Gets an attribute on a MathML node. + */ + + + getAttribute(name) { + return this.attributes[name]; + } + /** + * Converts the math node into a MathML-namespaced DOM element. + */ + + + toNode() { + var node = document.createElementNS("http://www.w3.org/1998/Math/MathML", this.type); + + for (var attr in this.attributes) { + if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { + node.setAttribute(attr, this.attributes[attr]); + } + } + + if (this.classes.length > 0) { + node.className = createClass(this.classes); + } + + for (var i = 0; i < this.children.length; i++) { + node.appendChild(this.children[i].toNode()); + } + + return node; + } + /** + * Converts the math node into an HTML markup string. + */ + + + toMarkup() { + var markup = "<" + this.type; // Add the attributes + + for (var attr in this.attributes) { + if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) { + markup += " " + attr + "=\""; + markup += utils.escape(this.attributes[attr]); + markup += "\""; + } + } + + if (this.classes.length > 0) { + markup += " class =\"" + utils.escape(createClass(this.classes)) + "\""; + } + + markup += ">"; + + for (var i = 0; i < this.children.length; i++) { + markup += this.children[i].toMarkup(); + } + + markup += ""; + return markup; + } + /** + * Converts the math node into a string, similar to innerText, but escaped. + */ + + + toText() { + return this.children.map(child => child.toText()).join(""); + } + +} +/** + * This node represents a piece of text. + */ + +class TextNode { + constructor(text) { + this.text = void 0; + this.text = text; + } + /** + * Converts the text node into a DOM text node. + */ + + + toNode() { + return document.createTextNode(this.text); + } + /** + * Converts the text node into escaped HTML markup + * (representing the text itself). + */ + + + toMarkup() { + return utils.escape(this.toText()); + } + /** + * Converts the text node into a string + * (representing the text itself). + */ + + + toText() { + return this.text; + } + +} +/** + * This node represents a space, but may render as or as text, + * depending on the width. + */ + +class SpaceNode { + /** + * Create a Space node with width given in CSS ems. + */ + constructor(width) { + this.width = void 0; + this.character = void 0; + this.width = width; // See https://www.w3.org/TR/2000/WD-MathML2-20000328/chapter6.html + // for a table of space-like characters. We use Unicode + // representations instead of &LongNames; as it's not clear how to + // make the latter via document.createTextNode. + + if (width >= 0.05555 && width <= 0.05556) { + this.character = "\u200a"; //   + } else if (width >= 0.1666 && width <= 0.1667) { + this.character = "\u2009"; //   + } else if (width >= 0.2222 && width <= 0.2223) { + this.character = "\u2005"; //   + } else if (width >= 0.2777 && width <= 0.2778) { + this.character = "\u2005\u200a"; //    + } else if (width >= -0.05556 && width <= -0.05555) { + this.character = "\u200a\u2063"; // ​ + } else if (width >= -0.1667 && width <= -0.1666) { + this.character = "\u2009\u2063"; // ​ + } else if (width >= -0.2223 && width <= -0.2222) { + this.character = "\u205f\u2063"; // ​ + } else if (width >= -0.2778 && width <= -0.2777) { + this.character = "\u2005\u2063"; // ​ + } else { + this.character = null; + } + } + /** + * Converts the math node into a MathML-namespaced DOM element. + */ + + + toNode() { + if (this.character) { + return document.createTextNode(this.character); + } else { + var node = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mspace"); + node.setAttribute("width", makeEm(this.width)); + return node; + } + } + /** + * Converts the math node into an HTML markup string. + */ + + + toMarkup() { + if (this.character) { + return "" + this.character + ""; + } else { + return ""; + } + } + /** + * Converts the math node into a string, similar to innerText. + */ + + + toText() { + if (this.character) { + return this.character; + } else { + return " "; + } + } + +} + +var mathMLTree = { + MathNode, + TextNode, + SpaceNode, + newDocumentFragment +}; + +/** + * This file converts a parse tree into a corresponding MathML tree. The main + * entry point is the `buildMathML` function, which takes a parse tree from the + * parser. + */ + +/** + * Takes a symbol and converts it into a MathML text node after performing + * optional replacement from symbols.js. + */ +var makeText = function makeText(text, mode, options) { + if (symbols[mode][text] && symbols[mode][text].replace && text.charCodeAt(0) !== 0xD835 && !(ligatures.hasOwnProperty(text) && options && (options.fontFamily && options.fontFamily.slice(4, 6) === "tt" || options.font && options.font.slice(4, 6) === "tt"))) { + text = symbols[mode][text].replace; + } + + return new mathMLTree.TextNode(text); +}; +/** + * Wrap the given array of nodes in an node if needed, i.e., + * unless the array has length 1. Always returns a single node. + */ + +var makeRow = function makeRow(body) { + if (body.length === 1) { + return body[0]; + } else { + return new mathMLTree.MathNode("mrow", body); + } +}; +/** + * Returns the math variant as a string or null if none is required. + */ + +var getVariant = function getVariant(group, options) { + // Handle \text... font specifiers as best we can. + // MathML has a limited list of allowable mathvariant specifiers; see + // https://www.w3.org/TR/MathML3/chapter3.html#presm.commatt + if (options.fontFamily === "texttt") { + return "monospace"; + } else if (options.fontFamily === "textsf") { + if (options.fontShape === "textit" && options.fontWeight === "textbf") { + return "sans-serif-bold-italic"; + } else if (options.fontShape === "textit") { + return "sans-serif-italic"; + } else if (options.fontWeight === "textbf") { + return "bold-sans-serif"; + } else { + return "sans-serif"; + } + } else if (options.fontShape === "textit" && options.fontWeight === "textbf") { + return "bold-italic"; + } else if (options.fontShape === "textit") { + return "italic"; + } else if (options.fontWeight === "textbf") { + return "bold"; + } + + var font = options.font; + + if (!font || font === "mathnormal") { + return null; + } + + var mode = group.mode; + + if (font === "mathit") { + return "italic"; + } else if (font === "boldsymbol") { + return group.type === "textord" ? "bold" : "bold-italic"; + } else if (font === "mathbf") { + return "bold"; + } else if (font === "mathbb") { + return "double-struck"; + } else if (font === "mathfrak") { + return "fraktur"; + } else if (font === "mathscr" || font === "mathcal") { + // MathML makes no distinction between script and calligraphic + return "script"; + } else if (font === "mathsf") { + return "sans-serif"; + } else if (font === "mathtt") { + return "monospace"; + } + + var text = group.text; + + if (utils.contains(["\\imath", "\\jmath"], text)) { + return null; + } + + if (symbols[mode][text] && symbols[mode][text].replace) { + text = symbols[mode][text].replace; + } + + var fontName = buildCommon.fontMap[font].fontName; + + if (getCharacterMetrics(text, fontName, mode)) { + return buildCommon.fontMap[font].variant; + } + + return null; +}; +/** + * Takes a list of nodes, builds them, and returns a list of the generated + * MathML nodes. Also combine consecutive outputs into a single + * tag. + */ + +var buildExpression = function buildExpression(expression, options, isOrdgroup) { + if (expression.length === 1) { + var group = buildGroup(expression[0], options); + + if (isOrdgroup && group instanceof MathNode && group.type === "mo") { + // When TeX writers want to suppress spacing on an operator, + // they often put the operator by itself inside braces. + group.setAttribute("lspace", "0em"); + group.setAttribute("rspace", "0em"); + } + + return [group]; + } + + var groups = []; + var lastGroup; + + for (var i = 0; i < expression.length; i++) { + var _group = buildGroup(expression[i], options); + + if (_group instanceof MathNode && lastGroup instanceof MathNode) { + // Concatenate adjacent s + if (_group.type === 'mtext' && lastGroup.type === 'mtext' && _group.getAttribute('mathvariant') === lastGroup.getAttribute('mathvariant')) { + lastGroup.children.push(..._group.children); + continue; // Concatenate adjacent s + } else if (_group.type === 'mn' && lastGroup.type === 'mn') { + lastGroup.children.push(..._group.children); + continue; // Concatenate ... followed by . + } else if (_group.type === 'mi' && _group.children.length === 1 && lastGroup.type === 'mn') { + var child = _group.children[0]; + + if (child instanceof TextNode && child.text === '.') { + lastGroup.children.push(..._group.children); + continue; + } + } else if (lastGroup.type === 'mi' && lastGroup.children.length === 1) { + var lastChild = lastGroup.children[0]; + + if (lastChild instanceof TextNode && lastChild.text === '\u0338' && (_group.type === 'mo' || _group.type === 'mi' || _group.type === 'mn')) { + var _child = _group.children[0]; + + if (_child instanceof TextNode && _child.text.length > 0) { + // Overlay with combining character long solidus + _child.text = _child.text.slice(0, 1) + "\u0338" + _child.text.slice(1); + groups.pop(); + } + } + } + } + + groups.push(_group); + lastGroup = _group; + } + + return groups; +}; +/** + * Equivalent to buildExpression, but wraps the elements in an + * if there's more than one. Returns a single node instead of an array. + */ + +var buildExpressionRow = function buildExpressionRow(expression, options, isOrdgroup) { + return makeRow(buildExpression(expression, options, isOrdgroup)); +}; +/** + * Takes a group from the parser and calls the appropriate groupBuilders function + * on it to produce a MathML node. + */ + +var buildGroup = function buildGroup(group, options) { + if (!group) { + return new mathMLTree.MathNode("mrow"); + } + + if (_mathmlGroupBuilders[group.type]) { + // Call the groupBuilders function + // $FlowFixMe + var result = _mathmlGroupBuilders[group.type](group, options); // $FlowFixMe + + return result; + } else { + throw new ParseError("Got group of unknown type: '" + group.type + "'"); + } +}; +/** + * Takes a full parse tree and settings and builds a MathML representation of + * it. In particular, we put the elements from building the parse tree into a + * tag so we can also include that TeX source as an annotation. + * + * Note that we actually return a domTree element with a `` inside it so + * we can do appropriate styling. + */ + +function buildMathML(tree, texExpression, options, isDisplayMode, forMathmlOnly) { + var expression = buildExpression(tree, options); // TODO: Make a pass thru the MathML similar to buildHTML.traverseNonSpaceNodes + // and add spacing nodes. This is necessary only adjacent to math operators + // like \sin or \lim or to subsup elements that contain math operators. + // MathML takes care of the other spacing issues. + // Wrap up the expression in an mrow so it is presented in the semantics + // tag correctly, unless it's a single or . + + var wrapper; + + if (expression.length === 1 && expression[0] instanceof MathNode && utils.contains(["mrow", "mtable"], expression[0].type)) { + wrapper = expression[0]; + } else { + wrapper = new mathMLTree.MathNode("mrow", expression); + } // Build a TeX annotation of the source + + + var annotation = new mathMLTree.MathNode("annotation", [new mathMLTree.TextNode(texExpression)]); + annotation.setAttribute("encoding", "application/x-tex"); + var semantics = new mathMLTree.MathNode("semantics", [wrapper, annotation]); + var math = new mathMLTree.MathNode("math", [semantics]); + math.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML"); + + if (isDisplayMode) { + math.setAttribute("display", "block"); + } // You can't style nodes, so we wrap the node in a span. + // NOTE: The span class is not typed to have nodes as children, and + // we don't want to make the children type more generic since the children + // of span are expected to have more fields in `buildHtml` contexts. + + + var wrapperClass = forMathmlOnly ? "katex" : "katex-mathml"; // $FlowFixMe + + return buildCommon.makeSpan([wrapperClass], [math]); +} + +var optionsFromSettings = function optionsFromSettings(settings) { + return new Options({ + style: settings.displayMode ? Style$1.DISPLAY : Style$1.TEXT, + maxSize: settings.maxSize, + minRuleThickness: settings.minRuleThickness + }); +}; + +var displayWrap = function displayWrap(node, settings) { + if (settings.displayMode) { + var classes = ["katex-display"]; + + if (settings.leqno) { + classes.push("leqno"); + } + + if (settings.fleqn) { + classes.push("fleqn"); + } + + node = buildCommon.makeSpan(classes, [node]); + } + + return node; +}; + +var buildTree = function buildTree(tree, expression, settings) { + var options = optionsFromSettings(settings); + var katexNode; + + if (settings.output === "mathml") { + return buildMathML(tree, expression, options, settings.displayMode, true); + } else if (settings.output === "html") { + var htmlNode = buildHTML(tree, options); + katexNode = buildCommon.makeSpan(["katex"], [htmlNode]); + } else { + var mathMLNode = buildMathML(tree, expression, options, settings.displayMode, false); + + var _htmlNode = buildHTML(tree, options); + + katexNode = buildCommon.makeSpan(["katex"], [mathMLNode, _htmlNode]); + } + + return displayWrap(katexNode, settings); +}; +var buildHTMLTree = function buildHTMLTree(tree, expression, settings) { + var options = optionsFromSettings(settings); + var htmlNode = buildHTML(tree, options); + var katexNode = buildCommon.makeSpan(["katex"], [htmlNode]); + return displayWrap(katexNode, settings); +}; + +/** + * This file provides support to buildMathML.js and buildHTML.js + * for stretchy wide elements rendered from SVG files + * and other CSS trickery. + */ +var stretchyCodePoint = { + widehat: "^", + widecheck: "ˇ", + widetilde: "~", + utilde: "~", + overleftarrow: "\u2190", + underleftarrow: "\u2190", + xleftarrow: "\u2190", + overrightarrow: "\u2192", + underrightarrow: "\u2192", + xrightarrow: "\u2192", + underbrace: "\u23df", + overbrace: "\u23de", + overgroup: "\u23e0", + undergroup: "\u23e1", + overleftrightarrow: "\u2194", + underleftrightarrow: "\u2194", + xleftrightarrow: "\u2194", + Overrightarrow: "\u21d2", + xRightarrow: "\u21d2", + overleftharpoon: "\u21bc", + xleftharpoonup: "\u21bc", + overrightharpoon: "\u21c0", + xrightharpoonup: "\u21c0", + xLeftarrow: "\u21d0", + xLeftrightarrow: "\u21d4", + xhookleftarrow: "\u21a9", + xhookrightarrow: "\u21aa", + xmapsto: "\u21a6", + xrightharpoondown: "\u21c1", + xleftharpoondown: "\u21bd", + xrightleftharpoons: "\u21cc", + xleftrightharpoons: "\u21cb", + xtwoheadleftarrow: "\u219e", + xtwoheadrightarrow: "\u21a0", + xlongequal: "=", + xtofrom: "\u21c4", + xrightleftarrows: "\u21c4", + xrightequilibrium: "\u21cc", + // Not a perfect match. + xleftequilibrium: "\u21cb", + // None better available. + "\\cdrightarrow": "\u2192", + "\\cdleftarrow": "\u2190", + "\\cdlongequal": "=" +}; + +var mathMLnode = function mathMLnode(label) { + var node = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode(stretchyCodePoint[label.replace(/^\\/, '')])]); + node.setAttribute("stretchy", "true"); + return node; +}; // Many of the KaTeX SVG images have been adapted from glyphs in KaTeX fonts. +// Copyright (c) 2009-2010, Design Science, Inc. () +// Copyright (c) 2014-2017 Khan Academy () +// Licensed under the SIL Open Font License, Version 1.1. +// See \nhttp://scripts.sil.org/OFL +// Very Long SVGs +// Many of the KaTeX stretchy wide elements use a long SVG image and an +// overflow: hidden tactic to achieve a stretchy image while avoiding +// distortion of arrowheads or brace corners. +// The SVG typically contains a very long (400 em) arrow. +// The SVG is in a container span that has overflow: hidden, so the span +// acts like a window that exposes only part of the SVG. +// The SVG always has a longer, thinner aspect ratio than the container span. +// After the SVG fills 100% of the height of the container span, +// there is a long arrow shaft left over. That left-over shaft is not shown. +// Instead, it is sliced off because the span's CSS has overflow: hidden. +// Thus, the reader sees an arrow that matches the subject matter width +// without distortion. +// Some functions, such as \cancel, need to vary their aspect ratio. These +// functions do not get the overflow SVG treatment. +// Second Brush Stroke +// Low resolution monitors struggle to display images in fine detail. +// So browsers apply anti-aliasing. A long straight arrow shaft therefore +// will sometimes appear as if it has a blurred edge. +// To mitigate this, these SVG files contain a second "brush-stroke" on the +// arrow shafts. That is, a second long thin rectangular SVG path has been +// written directly on top of each arrow shaft. This reinforcement causes +// some of the screen pixels to display as black instead of the anti-aliased +// gray pixel that a single path would generate. So we get arrow shafts +// whose edges appear to be sharper. +// In the katexImagesData object just below, the dimensions all +// correspond to path geometry inside the relevant SVG. +// For example, \overrightarrow uses the same arrowhead as glyph U+2192 +// from the KaTeX Main font. The scaling factor is 1000. +// That is, inside the font, that arrowhead is 522 units tall, which +// corresponds to 0.522 em inside the document. + + +var katexImagesData = { + // path(s), minWidth, height, align + overrightarrow: [["rightarrow"], 0.888, 522, "xMaxYMin"], + overleftarrow: [["leftarrow"], 0.888, 522, "xMinYMin"], + underrightarrow: [["rightarrow"], 0.888, 522, "xMaxYMin"], + underleftarrow: [["leftarrow"], 0.888, 522, "xMinYMin"], + xrightarrow: [["rightarrow"], 1.469, 522, "xMaxYMin"], + "\\cdrightarrow": [["rightarrow"], 3.0, 522, "xMaxYMin"], + // CD minwwidth2.5pc + xleftarrow: [["leftarrow"], 1.469, 522, "xMinYMin"], + "\\cdleftarrow": [["leftarrow"], 3.0, 522, "xMinYMin"], + Overrightarrow: [["doublerightarrow"], 0.888, 560, "xMaxYMin"], + xRightarrow: [["doublerightarrow"], 1.526, 560, "xMaxYMin"], + xLeftarrow: [["doubleleftarrow"], 1.526, 560, "xMinYMin"], + overleftharpoon: [["leftharpoon"], 0.888, 522, "xMinYMin"], + xleftharpoonup: [["leftharpoon"], 0.888, 522, "xMinYMin"], + xleftharpoondown: [["leftharpoondown"], 0.888, 522, "xMinYMin"], + overrightharpoon: [["rightharpoon"], 0.888, 522, "xMaxYMin"], + xrightharpoonup: [["rightharpoon"], 0.888, 522, "xMaxYMin"], + xrightharpoondown: [["rightharpoondown"], 0.888, 522, "xMaxYMin"], + xlongequal: [["longequal"], 0.888, 334, "xMinYMin"], + "\\cdlongequal": [["longequal"], 3.0, 334, "xMinYMin"], + xtwoheadleftarrow: [["twoheadleftarrow"], 0.888, 334, "xMinYMin"], + xtwoheadrightarrow: [["twoheadrightarrow"], 0.888, 334, "xMaxYMin"], + overleftrightarrow: [["leftarrow", "rightarrow"], 0.888, 522], + overbrace: [["leftbrace", "midbrace", "rightbrace"], 1.6, 548], + underbrace: [["leftbraceunder", "midbraceunder", "rightbraceunder"], 1.6, 548], + underleftrightarrow: [["leftarrow", "rightarrow"], 0.888, 522], + xleftrightarrow: [["leftarrow", "rightarrow"], 1.75, 522], + xLeftrightarrow: [["doubleleftarrow", "doublerightarrow"], 1.75, 560], + xrightleftharpoons: [["leftharpoondownplus", "rightharpoonplus"], 1.75, 716], + xleftrightharpoons: [["leftharpoonplus", "rightharpoondownplus"], 1.75, 716], + xhookleftarrow: [["leftarrow", "righthook"], 1.08, 522], + xhookrightarrow: [["lefthook", "rightarrow"], 1.08, 522], + overlinesegment: [["leftlinesegment", "rightlinesegment"], 0.888, 522], + underlinesegment: [["leftlinesegment", "rightlinesegment"], 0.888, 522], + overgroup: [["leftgroup", "rightgroup"], 0.888, 342], + undergroup: [["leftgroupunder", "rightgroupunder"], 0.888, 342], + xmapsto: [["leftmapsto", "rightarrow"], 1.5, 522], + xtofrom: [["leftToFrom", "rightToFrom"], 1.75, 528], + // The next three arrows are from the mhchem package. + // In mhchem.sty, min-length is 2.0em. But these arrows might appear in the + // document as \xrightarrow or \xrightleftharpoons. Those have + // min-length = 1.75em, so we set min-length on these next three to match. + xrightleftarrows: [["baraboveleftarrow", "rightarrowabovebar"], 1.75, 901], + xrightequilibrium: [["baraboveshortleftharpoon", "rightharpoonaboveshortbar"], 1.75, 716], + xleftequilibrium: [["shortbaraboveleftharpoon", "shortrightharpoonabovebar"], 1.75, 716] +}; + +var groupLength = function groupLength(arg) { + if (arg.type === "ordgroup") { + return arg.body.length; + } else { + return 1; + } +}; + +var svgSpan = function svgSpan(group, options) { + // Create a span with inline SVG for the element. + function buildSvgSpan_() { + var viewBoxWidth = 400000; // default + + var label = group.label.slice(1); + + if (utils.contains(["widehat", "widecheck", "widetilde", "utilde"], label)) { + // Each type in the `if` statement corresponds to one of the ParseNode + // types below. This narrowing is required to access `grp.base`. + // $FlowFixMe + var grp = group; // There are four SVG images available for each function. + // Choose a taller image when there are more characters. + + var numChars = groupLength(grp.base); + var viewBoxHeight; + var pathName; + + var _height; + + if (numChars > 5) { + if (label === "widehat" || label === "widecheck") { + viewBoxHeight = 420; + viewBoxWidth = 2364; + _height = 0.42; + pathName = label + "4"; + } else { + viewBoxHeight = 312; + viewBoxWidth = 2340; + _height = 0.34; + pathName = "tilde4"; + } + } else { + var imgIndex = [1, 1, 2, 2, 3, 3][numChars]; + + if (label === "widehat" || label === "widecheck") { + viewBoxWidth = [0, 1062, 2364, 2364, 2364][imgIndex]; + viewBoxHeight = [0, 239, 300, 360, 420][imgIndex]; + _height = [0, 0.24, 0.3, 0.3, 0.36, 0.42][imgIndex]; + pathName = label + imgIndex; + } else { + viewBoxWidth = [0, 600, 1033, 2339, 2340][imgIndex]; + viewBoxHeight = [0, 260, 286, 306, 312][imgIndex]; + _height = [0, 0.26, 0.286, 0.3, 0.306, 0.34][imgIndex]; + pathName = "tilde" + imgIndex; + } + } + + var path = new PathNode(pathName); + var svgNode = new SvgNode([path], { + "width": "100%", + "height": makeEm(_height), + "viewBox": "0 0 " + viewBoxWidth + " " + viewBoxHeight, + "preserveAspectRatio": "none" + }); + return { + span: buildCommon.makeSvgSpan([], [svgNode], options), + minWidth: 0, + height: _height + }; + } else { + var spans = []; + var data = katexImagesData[label]; + var [paths, _minWidth, _viewBoxHeight] = data; + + var _height2 = _viewBoxHeight / 1000; + + var numSvgChildren = paths.length; + var widthClasses; + var aligns; + + if (numSvgChildren === 1) { + // $FlowFixMe: All these cases must be of the 4-tuple type. + var align1 = data[3]; + widthClasses = ["hide-tail"]; + aligns = [align1]; + } else if (numSvgChildren === 2) { + widthClasses = ["halfarrow-left", "halfarrow-right"]; + aligns = ["xMinYMin", "xMaxYMin"]; + } else if (numSvgChildren === 3) { + widthClasses = ["brace-left", "brace-center", "brace-right"]; + aligns = ["xMinYMin", "xMidYMin", "xMaxYMin"]; + } else { + throw new Error("Correct katexImagesData or update code here to support\n " + numSvgChildren + " children."); + } + + for (var i = 0; i < numSvgChildren; i++) { + var _path = new PathNode(paths[i]); + + var _svgNode = new SvgNode([_path], { + "width": "400em", + "height": makeEm(_height2), + "viewBox": "0 0 " + viewBoxWidth + " " + _viewBoxHeight, + "preserveAspectRatio": aligns[i] + " slice" + }); + + var _span = buildCommon.makeSvgSpan([widthClasses[i]], [_svgNode], options); + + if (numSvgChildren === 1) { + return { + span: _span, + minWidth: _minWidth, + height: _height2 + }; + } else { + _span.style.height = makeEm(_height2); + spans.push(_span); + } + } + + return { + span: buildCommon.makeSpan(["stretchy"], spans, options), + minWidth: _minWidth, + height: _height2 + }; + } + } // buildSvgSpan_() + + + var { + span, + minWidth, + height + } = buildSvgSpan_(); // Note that we are returning span.depth = 0. + // Any adjustments relative to the baseline must be done in buildHTML. + + span.height = height; + span.style.height = makeEm(height); + + if (minWidth > 0) { + span.style.minWidth = makeEm(minWidth); + } + + return span; +}; + +var encloseSpan = function encloseSpan(inner, label, topPad, bottomPad, options) { + // Return an image span for \cancel, \bcancel, \xcancel, \fbox, or \angl + var img; + var totalHeight = inner.height + inner.depth + topPad + bottomPad; + + if (/fbox|color|angl/.test(label)) { + img = buildCommon.makeSpan(["stretchy", label], [], options); + + if (label === "fbox") { + var color = options.color && options.getColor(); + + if (color) { + img.style.borderColor = color; + } + } + } else { + // \cancel, \bcancel, or \xcancel + // Since \cancel's SVG is inline and it omits the viewBox attribute, + // its stroke-width will not vary with span area. + var lines = []; + + if (/^[bx]cancel$/.test(label)) { + lines.push(new LineNode({ + "x1": "0", + "y1": "0", + "x2": "100%", + "y2": "100%", + "stroke-width": "0.046em" + })); + } + + if (/^x?cancel$/.test(label)) { + lines.push(new LineNode({ + "x1": "0", + "y1": "100%", + "x2": "100%", + "y2": "0", + "stroke-width": "0.046em" + })); + } + + var svgNode = new SvgNode(lines, { + "width": "100%", + "height": makeEm(totalHeight) + }); + img = buildCommon.makeSvgSpan([], [svgNode], options); + } + + img.height = totalHeight; + img.style.height = makeEm(totalHeight); + return img; +}; + +var stretchy = { + encloseSpan, + mathMLnode, + svgSpan +}; + +/** + * Asserts that the node is of the given type and returns it with stricter + * typing. Throws if the node's type does not match. + */ +function assertNodeType(node, type) { + if (!node || node.type !== type) { + throw new Error("Expected node of type " + type + ", but got " + (node ? "node of type " + node.type : String(node))); + } // $FlowFixMe, >=0.125 + + + return node; +} +/** + * Returns the node more strictly typed iff it is of the given type. Otherwise, + * returns null. + */ + +function assertSymbolNodeType(node) { + var typedNode = checkSymbolNodeType(node); + + if (!typedNode) { + throw new Error("Expected node of symbol group type, but got " + (node ? "node of type " + node.type : String(node))); + } + + return typedNode; +} +/** + * Returns the node more strictly typed iff it is of the given type. Otherwise, + * returns null. + */ + +function checkSymbolNodeType(node) { + if (node && (node.type === "atom" || NON_ATOMS.hasOwnProperty(node.type))) { + // $FlowFixMe + return node; + } + + return null; +} + +// NOTE: Unlike most `htmlBuilder`s, this one handles not only "accent", but +// also "supsub" since an accent can affect super/subscripting. +var htmlBuilder$a = (grp, options) => { + // Accents are handled in the TeXbook pg. 443, rule 12. + var base; + var group; + var supSubGroup; + + if (grp && grp.type === "supsub") { + // If our base is a character box, and we have superscripts and + // subscripts, the supsub will defer to us. In particular, we want + // to attach the superscripts and subscripts to the inner body (so + // that the position of the superscripts and subscripts won't be + // affected by the height of the accent). We accomplish this by + // sticking the base of the accent into the base of the supsub, and + // rendering that, while keeping track of where the accent is. + // The real accent group is the base of the supsub group + group = assertNodeType(grp.base, "accent"); // The character box is the base of the accent group + + base = group.base; // Stick the character box into the base of the supsub group + + grp.base = base; // Rerender the supsub group with its new base, and store that + // result. + + supSubGroup = assertSpan(buildGroup$1(grp, options)); // reset original base + + grp.base = group; + } else { + group = assertNodeType(grp, "accent"); + base = group.base; + } // Build the base group + + + var body = buildGroup$1(base, options.havingCrampedStyle()); // Does the accent need to shift for the skew of a character? + + var mustShift = group.isShifty && utils.isCharacterBox(base); // Calculate the skew of the accent. This is based on the line "If the + // nucleus is not a single character, let s = 0; otherwise set s to the + // kern amount for the nucleus followed by the \skewchar of its font." + // Note that our skew metrics are just the kern between each character + // and the skewchar. + + var skew = 0; + + if (mustShift) { + // If the base is a character box, then we want the skew of the + // innermost character. To do that, we find the innermost character: + var baseChar = utils.getBaseElem(base); // Then, we render its group to get the symbol inside it + + var baseGroup = buildGroup$1(baseChar, options.havingCrampedStyle()); // Finally, we pull the skew off of the symbol. + + skew = assertSymbolDomNode(baseGroup).skew; // Note that we now throw away baseGroup, because the layers we + // removed with getBaseElem might contain things like \color which + // we can't get rid of. + // TODO(emily): Find a better way to get the skew + } + + var accentBelow = group.label === "\\c"; // calculate the amount of space between the body and the accent + + var clearance = accentBelow ? body.height + body.depth : Math.min(body.height, options.fontMetrics().xHeight); // Build the accent + + var accentBody; + + if (!group.isStretchy) { + var accent; + var width; + + if (group.label === "\\vec") { + // Before version 0.9, \vec used the combining font glyph U+20D7. + // But browsers, especially Safari, are not consistent in how they + // render combining characters when not preceded by a character. + // So now we use an SVG. + // If Safari reforms, we should consider reverting to the glyph. + accent = buildCommon.staticSvg("vec", options); + width = buildCommon.svgData.vec[1]; + } else { + accent = buildCommon.makeOrd({ + mode: group.mode, + text: group.label + }, options, "textord"); + accent = assertSymbolDomNode(accent); // Remove the italic correction of the accent, because it only serves to + // shift the accent over to a place we don't want. + + accent.italic = 0; + width = accent.width; + + if (accentBelow) { + clearance += accent.depth; + } + } + + accentBody = buildCommon.makeSpan(["accent-body"], [accent]); // "Full" accents expand the width of the resulting symbol to be + // at least the width of the accent, and overlap directly onto the + // character without any vertical offset. + + var accentFull = group.label === "\\textcircled"; + + if (accentFull) { + accentBody.classes.push('accent-full'); + clearance = body.height; + } // Shift the accent over by the skew. + + + var left = skew; // CSS defines `.katex .accent .accent-body:not(.accent-full) { width: 0 }` + // so that the accent doesn't contribute to the bounding box. + // We need to shift the character by its width (effectively half + // its width) to compensate. + + if (!accentFull) { + left -= width / 2; + } + + accentBody.style.left = makeEm(left); // \textcircled uses the \bigcirc glyph, so it needs some + // vertical adjustment to match LaTeX. + + if (group.label === "\\textcircled") { + accentBody.style.top = ".2em"; + } + + accentBody = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: body + }, { + type: "kern", + size: -clearance + }, { + type: "elem", + elem: accentBody + }] + }, options); + } else { + accentBody = stretchy.svgSpan(group, options); + accentBody = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: body + }, { + type: "elem", + elem: accentBody, + wrapperClasses: ["svg-align"], + wrapperStyle: skew > 0 ? { + width: "calc(100% - " + makeEm(2 * skew) + ")", + marginLeft: makeEm(2 * skew) + } : undefined + }] + }, options); + } + + var accentWrap = buildCommon.makeSpan(["mord", "accent"], [accentBody], options); + + if (supSubGroup) { + // Here, we replace the "base" child of the supsub with our newly + // generated accent. + supSubGroup.children[0] = accentWrap; // Since we don't rerun the height calculation after replacing the + // accent, we manually recalculate height. + + supSubGroup.height = Math.max(accentWrap.height, supSubGroup.height); // Accents should always be ords, even when their innards are not. + + supSubGroup.classes[0] = "mord"; + return supSubGroup; + } else { + return accentWrap; + } +}; + +var mathmlBuilder$9 = (group, options) => { + var accentNode = group.isStretchy ? stretchy.mathMLnode(group.label) : new mathMLTree.MathNode("mo", [makeText(group.label, group.mode)]); + var node = new mathMLTree.MathNode("mover", [buildGroup(group.base, options), accentNode]); + node.setAttribute("accent", "true"); + return node; +}; + +var NON_STRETCHY_ACCENT_REGEX = new RegExp(["\\acute", "\\grave", "\\ddot", "\\tilde", "\\bar", "\\breve", "\\check", "\\hat", "\\vec", "\\dot", "\\mathring"].map(accent => "\\" + accent).join("|")); // Accents + +defineFunction({ + type: "accent", + names: ["\\acute", "\\grave", "\\ddot", "\\tilde", "\\bar", "\\breve", "\\check", "\\hat", "\\vec", "\\dot", "\\mathring", "\\widecheck", "\\widehat", "\\widetilde", "\\overrightarrow", "\\overleftarrow", "\\Overrightarrow", "\\overleftrightarrow", "\\overgroup", "\\overlinesegment", "\\overleftharpoon", "\\overrightharpoon"], + props: { + numArgs: 1 + }, + handler: (context, args) => { + var base = normalizeArgument(args[0]); + var isStretchy = !NON_STRETCHY_ACCENT_REGEX.test(context.funcName); + var isShifty = !isStretchy || context.funcName === "\\widehat" || context.funcName === "\\widetilde" || context.funcName === "\\widecheck"; + return { + type: "accent", + mode: context.parser.mode, + label: context.funcName, + isStretchy: isStretchy, + isShifty: isShifty, + base: base + }; + }, + htmlBuilder: htmlBuilder$a, + mathmlBuilder: mathmlBuilder$9 +}); // Text-mode accents + +defineFunction({ + type: "accent", + names: ["\\'", "\\`", "\\^", "\\~", "\\=", "\\u", "\\.", '\\"', "\\c", "\\r", "\\H", "\\v", "\\textcircled"], + props: { + numArgs: 1, + allowedInText: true, + allowedInMath: true, + // unless in strict mode + argTypes: ["primitive"] + }, + handler: (context, args) => { + var base = args[0]; + var mode = context.parser.mode; + + if (mode === "math") { + context.parser.settings.reportNonstrict("mathVsTextAccents", "LaTeX's accent " + context.funcName + " works only in text mode"); + mode = "text"; + } + + return { + type: "accent", + mode: mode, + label: context.funcName, + isStretchy: false, + isShifty: true, + base: base + }; + }, + htmlBuilder: htmlBuilder$a, + mathmlBuilder: mathmlBuilder$9 +}); + +// Horizontal overlap functions +defineFunction({ + type: "accentUnder", + names: ["\\underleftarrow", "\\underrightarrow", "\\underleftrightarrow", "\\undergroup", "\\underlinesegment", "\\utilde"], + props: { + numArgs: 1 + }, + handler: (_ref, args) => { + var { + parser, + funcName + } = _ref; + var base = args[0]; + return { + type: "accentUnder", + mode: parser.mode, + label: funcName, + base: base + }; + }, + htmlBuilder: (group, options) => { + // Treat under accents much like underlines. + var innerGroup = buildGroup$1(group.base, options); + var accentBody = stretchy.svgSpan(group, options); + var kern = group.label === "\\utilde" ? 0.12 : 0; // Generate the vlist, with the appropriate kerns + + var vlist = buildCommon.makeVList({ + positionType: "top", + positionData: innerGroup.height, + children: [{ + type: "elem", + elem: accentBody, + wrapperClasses: ["svg-align"] + }, { + type: "kern", + size: kern + }, { + type: "elem", + elem: innerGroup + }] + }, options); + return buildCommon.makeSpan(["mord", "accentunder"], [vlist], options); + }, + mathmlBuilder: (group, options) => { + var accentNode = stretchy.mathMLnode(group.label); + var node = new mathMLTree.MathNode("munder", [buildGroup(group.base, options), accentNode]); + node.setAttribute("accentunder", "true"); + return node; + } +}); + +// Helper function +var paddedNode = group => { + var node = new mathMLTree.MathNode("mpadded", group ? [group] : []); + node.setAttribute("width", "+0.6em"); + node.setAttribute("lspace", "0.3em"); + return node; +}; // Stretchy arrows with an optional argument + + +defineFunction({ + type: "xArrow", + names: ["\\xleftarrow", "\\xrightarrow", "\\xLeftarrow", "\\xRightarrow", "\\xleftrightarrow", "\\xLeftrightarrow", "\\xhookleftarrow", "\\xhookrightarrow", "\\xmapsto", "\\xrightharpoondown", "\\xrightharpoonup", "\\xleftharpoondown", "\\xleftharpoonup", "\\xrightleftharpoons", "\\xleftrightharpoons", "\\xlongequal", "\\xtwoheadrightarrow", "\\xtwoheadleftarrow", "\\xtofrom", // The next 3 functions are here to support the mhchem extension. + // Direct use of these functions is discouraged and may break someday. + "\\xrightleftarrows", "\\xrightequilibrium", "\\xleftequilibrium", // The next 3 functions are here only to support the {CD} environment. + "\\\\cdrightarrow", "\\\\cdleftarrow", "\\\\cdlongequal"], + props: { + numArgs: 1, + numOptionalArgs: 1 + }, + + handler(_ref, args, optArgs) { + var { + parser, + funcName + } = _ref; + return { + type: "xArrow", + mode: parser.mode, + label: funcName, + body: args[0], + below: optArgs[0] + }; + }, + + // Flow is unable to correctly infer the type of `group`, even though it's + // unambiguously determined from the passed-in `type` above. + htmlBuilder(group, options) { + var style = options.style; // Build the argument groups in the appropriate style. + // Ref: amsmath.dtx: \hbox{$\scriptstyle\mkern#3mu{#6}\mkern#4mu$}% + // Some groups can return document fragments. Handle those by wrapping + // them in a span. + + var newOptions = options.havingStyle(style.sup()); + var upperGroup = buildCommon.wrapFragment(buildGroup$1(group.body, newOptions, options), options); + var arrowPrefix = group.label.slice(0, 2) === "\\x" ? "x" : "cd"; + upperGroup.classes.push(arrowPrefix + "-arrow-pad"); + var lowerGroup; + + if (group.below) { + // Build the lower group + newOptions = options.havingStyle(style.sub()); + lowerGroup = buildCommon.wrapFragment(buildGroup$1(group.below, newOptions, options), options); + lowerGroup.classes.push(arrowPrefix + "-arrow-pad"); + } + + var arrowBody = stretchy.svgSpan(group, options); // Re shift: Note that stretchy.svgSpan returned arrowBody.depth = 0. + // The point we want on the math axis is at 0.5 * arrowBody.height. + + var arrowShift = -options.fontMetrics().axisHeight + 0.5 * arrowBody.height; // 2 mu kern. Ref: amsmath.dtx: #7\if0#2\else\mkern#2mu\fi + + var upperShift = -options.fontMetrics().axisHeight - 0.5 * arrowBody.height - 0.111; // 0.111 em = 2 mu + + if (upperGroup.depth > 0.25 || group.label === "\\xleftequilibrium") { + upperShift -= upperGroup.depth; // shift up if depth encroaches + } // Generate the vlist + + + var vlist; + + if (lowerGroup) { + var lowerShift = -options.fontMetrics().axisHeight + lowerGroup.height + 0.5 * arrowBody.height + 0.111; + vlist = buildCommon.makeVList({ + positionType: "individualShift", + children: [{ + type: "elem", + elem: upperGroup, + shift: upperShift + }, { + type: "elem", + elem: arrowBody, + shift: arrowShift + }, { + type: "elem", + elem: lowerGroup, + shift: lowerShift + }] + }, options); + } else { + vlist = buildCommon.makeVList({ + positionType: "individualShift", + children: [{ + type: "elem", + elem: upperGroup, + shift: upperShift + }, { + type: "elem", + elem: arrowBody, + shift: arrowShift + }] + }, options); + } // $FlowFixMe: Replace this with passing "svg-align" into makeVList. + + + vlist.children[0].children[0].children[1].classes.push("svg-align"); + return buildCommon.makeSpan(["mrel", "x-arrow"], [vlist], options); + }, + + mathmlBuilder(group, options) { + var arrowNode = stretchy.mathMLnode(group.label); + arrowNode.setAttribute("minsize", group.label.charAt(0) === "x" ? "1.75em" : "3.0em"); + var node; + + if (group.body) { + var upperNode = paddedNode(buildGroup(group.body, options)); + + if (group.below) { + var lowerNode = paddedNode(buildGroup(group.below, options)); + node = new mathMLTree.MathNode("munderover", [arrowNode, lowerNode, upperNode]); + } else { + node = new mathMLTree.MathNode("mover", [arrowNode, upperNode]); + } + } else if (group.below) { + var _lowerNode = paddedNode(buildGroup(group.below, options)); + + node = new mathMLTree.MathNode("munder", [arrowNode, _lowerNode]); + } else { + // This should never happen. + // Parser.js throws an error if there is no argument. + node = paddedNode(); + node = new mathMLTree.MathNode("mover", [arrowNode, node]); + } + + return node; + } + +}); + +var makeSpan = buildCommon.makeSpan; + +function htmlBuilder$9(group, options) { + var elements = buildExpression$1(group.body, options, true); + return makeSpan([group.mclass], elements, options); +} + +function mathmlBuilder$8(group, options) { + var node; + var inner = buildExpression(group.body, options); + + if (group.mclass === "minner") { + node = new mathMLTree.MathNode("mpadded", inner); + } else if (group.mclass === "mord") { + if (group.isCharacterBox) { + node = inner[0]; + node.type = "mi"; + } else { + node = new mathMLTree.MathNode("mi", inner); + } + } else { + if (group.isCharacterBox) { + node = inner[0]; + node.type = "mo"; + } else { + node = new mathMLTree.MathNode("mo", inner); + } // Set spacing based on what is the most likely adjacent atom type. + // See TeXbook p170. + + + if (group.mclass === "mbin") { + node.attributes.lspace = "0.22em"; // medium space + + node.attributes.rspace = "0.22em"; + } else if (group.mclass === "mpunct") { + node.attributes.lspace = "0em"; + node.attributes.rspace = "0.17em"; // thinspace + } else if (group.mclass === "mopen" || group.mclass === "mclose") { + node.attributes.lspace = "0em"; + node.attributes.rspace = "0em"; + } else if (group.mclass === "minner") { + node.attributes.lspace = "0.0556em"; // 1 mu is the most likely option + + node.attributes.width = "+0.1111em"; + } // MathML default space is 5/18 em, so needs no action. + // Ref: https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mo + + } + + return node; +} // Math class commands except \mathop + + +defineFunction({ + type: "mclass", + names: ["\\mathord", "\\mathbin", "\\mathrel", "\\mathopen", "\\mathclose", "\\mathpunct", "\\mathinner"], + props: { + numArgs: 1, + primitive: true + }, + + handler(_ref, args) { + var { + parser, + funcName + } = _ref; + var body = args[0]; + return { + type: "mclass", + mode: parser.mode, + mclass: "m" + funcName.slice(5), + // TODO(kevinb): don't prefix with 'm' + body: ordargument(body), + isCharacterBox: utils.isCharacterBox(body) + }; + }, + + htmlBuilder: htmlBuilder$9, + mathmlBuilder: mathmlBuilder$8 +}); +var binrelClass = arg => { + // \binrel@ spacing varies with (bin|rel|ord) of the atom in the argument. + // (by rendering separately and with {}s before and after, and measuring + // the change in spacing). We'll do roughly the same by detecting the + // atom type directly. + var atom = arg.type === "ordgroup" && arg.body.length ? arg.body[0] : arg; + + if (atom.type === "atom" && (atom.family === "bin" || atom.family === "rel")) { + return "m" + atom.family; + } else { + return "mord"; + } +}; // \@binrel{x}{y} renders like y but as mbin/mrel/mord if x is mbin/mrel/mord. +// This is equivalent to \binrel@{x}\binrel@@{y} in AMSTeX. + +defineFunction({ + type: "mclass", + names: ["\\@binrel"], + props: { + numArgs: 2 + }, + + handler(_ref2, args) { + var { + parser + } = _ref2; + return { + type: "mclass", + mode: parser.mode, + mclass: binrelClass(args[0]), + body: ordargument(args[1]), + isCharacterBox: utils.isCharacterBox(args[1]) + }; + } + +}); // Build a relation or stacked op by placing one symbol on top of another + +defineFunction({ + type: "mclass", + names: ["\\stackrel", "\\overset", "\\underset"], + props: { + numArgs: 2 + }, + + handler(_ref3, args) { + var { + parser, + funcName + } = _ref3; + var baseArg = args[1]; + var shiftedArg = args[0]; + var mclass; + + if (funcName !== "\\stackrel") { + // LaTeX applies \binrel spacing to \overset and \underset. + mclass = binrelClass(baseArg); + } else { + mclass = "mrel"; // for \stackrel + } + + var baseOp = { + type: "op", + mode: baseArg.mode, + limits: true, + alwaysHandleSupSub: true, + parentIsSupSub: false, + symbol: false, + suppressBaseShift: funcName !== "\\stackrel", + body: ordargument(baseArg) + }; + var supsub = { + type: "supsub", + mode: shiftedArg.mode, + base: baseOp, + sup: funcName === "\\underset" ? null : shiftedArg, + sub: funcName === "\\underset" ? shiftedArg : null + }; + return { + type: "mclass", + mode: parser.mode, + mclass, + body: [supsub], + isCharacterBox: utils.isCharacterBox(supsub) + }; + }, + + htmlBuilder: htmlBuilder$9, + mathmlBuilder: mathmlBuilder$8 +}); + +// \pmb is a simulation of bold font. +// The version of \pmb in ambsy.sty works by typesetting three copies +// with small offsets. We use CSS text-shadow. +// It's a hack. Not as good as a real bold font. Better than nothing. +defineFunction({ + type: "pmb", + names: ["\\pmb"], + props: { + numArgs: 1, + allowedInText: true + }, + + handler(_ref, args) { + var { + parser + } = _ref; + return { + type: "pmb", + mode: parser.mode, + mclass: binrelClass(args[0]), + body: ordargument(args[0]) + }; + }, + + htmlBuilder(group, options) { + var elements = buildExpression$1(group.body, options, true); + var node = buildCommon.makeSpan([group.mclass], elements, options); + node.style.textShadow = "0.02em 0.01em 0.04px"; + return node; + }, + + mathmlBuilder(group, style) { + var inner = buildExpression(group.body, style); // Wrap with an element. + + var node = new mathMLTree.MathNode("mstyle", inner); + node.setAttribute("style", "text-shadow: 0.02em 0.01em 0.04px"); + return node; + } + +}); + +var cdArrowFunctionName = { + ">": "\\\\cdrightarrow", + "<": "\\\\cdleftarrow", + "=": "\\\\cdlongequal", + "A": "\\uparrow", + "V": "\\downarrow", + "|": "\\Vert", + ".": "no arrow" +}; + +var newCell = () => { + // Create an empty cell, to be filled below with parse nodes. + // The parseTree from this module must be constructed like the + // one created by parseArray(), so an empty CD cell must + // be a ParseNode<"styling">. And CD is always displaystyle. + // So these values are fixed and flow can do implicit typing. + return { + type: "styling", + body: [], + mode: "math", + style: "display" + }; +}; + +var isStartOfArrow = node => { + return node.type === "textord" && node.text === "@"; +}; + +var isLabelEnd = (node, endChar) => { + return (node.type === "mathord" || node.type === "atom") && node.text === endChar; +}; + +function cdArrow(arrowChar, labels, parser) { + // Return a parse tree of an arrow and its labels. + // This acts in a way similar to a macro expansion. + var funcName = cdArrowFunctionName[arrowChar]; + + switch (funcName) { + case "\\\\cdrightarrow": + case "\\\\cdleftarrow": + return parser.callFunction(funcName, [labels[0]], [labels[1]]); + + case "\\uparrow": + case "\\downarrow": + { + var leftLabel = parser.callFunction("\\\\cdleft", [labels[0]], []); + var bareArrow = { + type: "atom", + text: funcName, + mode: "math", + family: "rel" + }; + var sizedArrow = parser.callFunction("\\Big", [bareArrow], []); + var rightLabel = parser.callFunction("\\\\cdright", [labels[1]], []); + var arrowGroup = { + type: "ordgroup", + mode: "math", + body: [leftLabel, sizedArrow, rightLabel] + }; + return parser.callFunction("\\\\cdparent", [arrowGroup], []); + } + + case "\\\\cdlongequal": + return parser.callFunction("\\\\cdlongequal", [], []); + + case "\\Vert": + { + var arrow = { + type: "textord", + text: "\\Vert", + mode: "math" + }; + return parser.callFunction("\\Big", [arrow], []); + } + + default: + return { + type: "textord", + text: " ", + mode: "math" + }; + } +} + +function parseCD(parser) { + // Get the array's parse nodes with \\ temporarily mapped to \cr. + var parsedRows = []; + parser.gullet.beginGroup(); + parser.gullet.macros.set("\\cr", "\\\\\\relax"); + parser.gullet.beginGroup(); + + while (true) { + // eslint-disable-line no-constant-condition + // Get the parse nodes for the next row. + parsedRows.push(parser.parseExpression(false, "\\\\")); + parser.gullet.endGroup(); + parser.gullet.beginGroup(); + var next = parser.fetch().text; + + if (next === "&" || next === "\\\\") { + parser.consume(); + } else if (next === "\\end") { + if (parsedRows[parsedRows.length - 1].length === 0) { + parsedRows.pop(); // final row ended in \\ + } + + break; + } else { + throw new ParseError("Expected \\\\ or \\cr or \\end", parser.nextToken); + } + } + + var row = []; + var body = [row]; // Loop thru the parse nodes. Collect them into cells and arrows. + + for (var i = 0; i < parsedRows.length; i++) { + // Start a new row. + var rowNodes = parsedRows[i]; // Create the first cell. + + var cell = newCell(); + + for (var j = 0; j < rowNodes.length; j++) { + if (!isStartOfArrow(rowNodes[j])) { + // If a parseNode is not an arrow, it goes into a cell. + cell.body.push(rowNodes[j]); + } else { + // Parse node j is an "@", the start of an arrow. + // Before starting on the arrow, push the cell into `row`. + row.push(cell); // Now collect parseNodes into an arrow. + // The character after "@" defines the arrow type. + + j += 1; + var arrowChar = assertSymbolNodeType(rowNodes[j]).text; // Create two empty label nodes. We may or may not use them. + + var labels = new Array(2); + labels[0] = { + type: "ordgroup", + mode: "math", + body: [] + }; + labels[1] = { + type: "ordgroup", + mode: "math", + body: [] + }; // Process the arrow. + + if ("=|.".indexOf(arrowChar) > -1) ; else if ("<>AV".indexOf(arrowChar) > -1) { + // Four arrows, `@>>>`, `@<<<`, `@AAA`, and `@VVV`, each take + // two optional labels. E.g. the right-point arrow syntax is + // really: @>{optional label}>{optional label}> + // Collect parseNodes into labels. + for (var labelNum = 0; labelNum < 2; labelNum++) { + var inLabel = true; + + for (var k = j + 1; k < rowNodes.length; k++) { + if (isLabelEnd(rowNodes[k], arrowChar)) { + inLabel = false; + j = k; + break; + } + + if (isStartOfArrow(rowNodes[k])) { + throw new ParseError("Missing a " + arrowChar + " character to complete a CD arrow.", rowNodes[k]); + } + + labels[labelNum].body.push(rowNodes[k]); + } + + if (inLabel) { + // isLabelEnd never returned a true. + throw new ParseError("Missing a " + arrowChar + " character to complete a CD arrow.", rowNodes[j]); + } + } + } else { + throw new ParseError("Expected one of \"<>AV=|.\" after @", rowNodes[j]); + } // Now join the arrow to its labels. + + + var arrow = cdArrow(arrowChar, labels, parser); // Wrap the arrow in ParseNode<"styling">. + // This is done to match parseArray() behavior. + + var wrappedArrow = { + type: "styling", + body: [arrow], + mode: "math", + style: "display" // CD is always displaystyle. + + }; + row.push(wrappedArrow); // In CD's syntax, cells are implicit. That is, everything that + // is not an arrow gets collected into a cell. So create an empty + // cell now. It will collect upcoming parseNodes. + + cell = newCell(); + } + } + + if (i % 2 === 0) { + // Even-numbered rows consist of: cell, arrow, cell, arrow, ... cell + // The last cell is not yet pushed into `row`, so: + row.push(cell); + } else { + // Odd-numbered rows consist of: vert arrow, empty cell, ... vert arrow + // Remove the empty cell that was placed at the beginning of `row`. + row.shift(); + } + + row = []; + body.push(row); + } // End row group + + + parser.gullet.endGroup(); // End array group defining \\ + + parser.gullet.endGroup(); // define column separation. + + var cols = new Array(body[0].length).fill({ + type: "align", + align: "c", + pregap: 0.25, + // CD package sets \enskip between columns. + postgap: 0.25 // So pre and post each get half an \enskip, i.e. 0.25em. + + }); + return { + type: "array", + mode: "math", + body, + arraystretch: 1, + addJot: true, + rowGaps: [null], + cols, + colSeparationType: "CD", + hLinesBeforeRow: new Array(body.length + 1).fill([]) + }; +} // The functions below are not available for general use. +// They are here only for internal use by the {CD} environment in placing labels +// next to vertical arrows. +// We don't need any such functions for horizontal arrows because we can reuse +// the functionality that already exists for extensible arrows. + +defineFunction({ + type: "cdlabel", + names: ["\\\\cdleft", "\\\\cdright"], + props: { + numArgs: 1 + }, + + handler(_ref, args) { + var { + parser, + funcName + } = _ref; + return { + type: "cdlabel", + mode: parser.mode, + side: funcName.slice(4), + label: args[0] + }; + }, + + htmlBuilder(group, options) { + var newOptions = options.havingStyle(options.style.sup()); + var label = buildCommon.wrapFragment(buildGroup$1(group.label, newOptions, options), options); + label.classes.push("cd-label-" + group.side); + label.style.bottom = makeEm(0.8 - label.depth); // Zero out label height & depth, so vertical align of arrow is set + // by the arrow height, not by the label. + + label.height = 0; + label.depth = 0; + return label; + }, + + mathmlBuilder(group, options) { + var label = new mathMLTree.MathNode("mrow", [buildGroup(group.label, options)]); + label = new mathMLTree.MathNode("mpadded", [label]); + label.setAttribute("width", "0"); + + if (group.side === "left") { + label.setAttribute("lspace", "-1width"); + } // We have to guess at vertical alignment. We know the arrow is 1.8em tall, + // But we don't know the height or depth of the label. + + + label.setAttribute("voffset", "0.7em"); + label = new mathMLTree.MathNode("mstyle", [label]); + label.setAttribute("displaystyle", "false"); + label.setAttribute("scriptlevel", "1"); + return label; + } + +}); +defineFunction({ + type: "cdlabelparent", + names: ["\\\\cdparent"], + props: { + numArgs: 1 + }, + + handler(_ref2, args) { + var { + parser + } = _ref2; + return { + type: "cdlabelparent", + mode: parser.mode, + fragment: args[0] + }; + }, + + htmlBuilder(group, options) { + // Wrap the vertical arrow and its labels. + // The parent gets position: relative. The child gets position: absolute. + // So CSS can locate the label correctly. + var parent = buildCommon.wrapFragment(buildGroup$1(group.fragment, options), options); + parent.classes.push("cd-vert-arrow"); + return parent; + }, + + mathmlBuilder(group, options) { + return new mathMLTree.MathNode("mrow", [buildGroup(group.fragment, options)]); + } + +}); + +// {123} and converts into symbol with code 123. It is used by the *macro* +// \char defined in macros.js. + +defineFunction({ + type: "textord", + names: ["\\@char"], + props: { + numArgs: 1, + allowedInText: true + }, + + handler(_ref, args) { + var { + parser + } = _ref; + var arg = assertNodeType(args[0], "ordgroup"); + var group = arg.body; + var number = ""; + + for (var i = 0; i < group.length; i++) { + var node = assertNodeType(group[i], "textord"); + number += node.text; + } + + var code = parseInt(number); + var text; + + if (isNaN(code)) { + throw new ParseError("\\@char has non-numeric argument " + number); // If we drop IE support, the following code could be replaced with + // text = String.fromCodePoint(code) + } else if (code < 0 || code >= 0x10ffff) { + throw new ParseError("\\@char with invalid code point " + number); + } else if (code <= 0xffff) { + text = String.fromCharCode(code); + } else { + // Astral code point; split into surrogate halves + code -= 0x10000; + text = String.fromCharCode((code >> 10) + 0xd800, (code & 0x3ff) + 0xdc00); + } + + return { + type: "textord", + mode: parser.mode, + text: text + }; + } + +}); + +var htmlBuilder$8 = (group, options) => { + var elements = buildExpression$1(group.body, options.withColor(group.color), false); // \color isn't supposed to affect the type of the elements it contains. + // To accomplish this, we wrap the results in a fragment, so the inner + // elements will be able to directly interact with their neighbors. For + // example, `\color{red}{2 +} 3` has the same spacing as `2 + 3` + + return buildCommon.makeFragment(elements); +}; + +var mathmlBuilder$7 = (group, options) => { + var inner = buildExpression(group.body, options.withColor(group.color)); + var node = new mathMLTree.MathNode("mstyle", inner); + node.setAttribute("mathcolor", group.color); + return node; +}; + +defineFunction({ + type: "color", + names: ["\\textcolor"], + props: { + numArgs: 2, + allowedInText: true, + argTypes: ["color", "original"] + }, + + handler(_ref, args) { + var { + parser + } = _ref; + var color = assertNodeType(args[0], "color-token").color; + var body = args[1]; + return { + type: "color", + mode: parser.mode, + color, + body: ordargument(body) + }; + }, + + htmlBuilder: htmlBuilder$8, + mathmlBuilder: mathmlBuilder$7 +}); +defineFunction({ + type: "color", + names: ["\\color"], + props: { + numArgs: 1, + allowedInText: true, + argTypes: ["color"] + }, + + handler(_ref2, args) { + var { + parser, + breakOnTokenText + } = _ref2; + var color = assertNodeType(args[0], "color-token").color; // Set macro \current@color in current namespace to store the current + // color, mimicking the behavior of color.sty. + // This is currently used just to correctly color a \right + // that follows a \color command. + + parser.gullet.macros.set("\\current@color", color); // Parse out the implicit body that should be colored. + + var body = parser.parseExpression(true, breakOnTokenText); + return { + type: "color", + mode: parser.mode, + color, + body + }; + }, + + htmlBuilder: htmlBuilder$8, + mathmlBuilder: mathmlBuilder$7 +}); + +// Row breaks within tabular environments, and line breaks at top level + +defineFunction({ + type: "cr", + names: ["\\\\"], + props: { + numArgs: 0, + numOptionalArgs: 0, + allowedInText: true + }, + + handler(_ref, args, optArgs) { + var { + parser + } = _ref; + var size = parser.gullet.future().text === "[" ? parser.parseSizeGroup(true) : null; + var newLine = !parser.settings.displayMode || !parser.settings.useStrictBehavior("newLineInDisplayMode", "In LaTeX, \\\\ or \\newline " + "does nothing in display mode"); + return { + type: "cr", + mode: parser.mode, + newLine, + size: size && assertNodeType(size, "size").value + }; + }, + + // The following builders are called only at the top level, + // not within tabular/array environments. + htmlBuilder(group, options) { + var span = buildCommon.makeSpan(["mspace"], [], options); + + if (group.newLine) { + span.classes.push("newline"); + + if (group.size) { + span.style.marginTop = makeEm(calculateSize(group.size, options)); + } + } + + return span; + }, + + mathmlBuilder(group, options) { + var node = new mathMLTree.MathNode("mspace"); + + if (group.newLine) { + node.setAttribute("linebreak", "newline"); + + if (group.size) { + node.setAttribute("height", makeEm(calculateSize(group.size, options))); + } + } + + return node; + } + +}); + +var globalMap = { + "\\global": "\\global", + "\\long": "\\\\globallong", + "\\\\globallong": "\\\\globallong", + "\\def": "\\gdef", + "\\gdef": "\\gdef", + "\\edef": "\\xdef", + "\\xdef": "\\xdef", + "\\let": "\\\\globallet", + "\\futurelet": "\\\\globalfuture" +}; + +var checkControlSequence = tok => { + var name = tok.text; + + if (/^(?:[\\{}$&#^_]|EOF)$/.test(name)) { + throw new ParseError("Expected a control sequence", tok); + } + + return name; +}; + +var getRHS = parser => { + var tok = parser.gullet.popToken(); + + if (tok.text === "=") { + // consume optional equals + tok = parser.gullet.popToken(); + + if (tok.text === " ") { + // consume one optional space + tok = parser.gullet.popToken(); + } + } + + return tok; +}; + +var letCommand = (parser, name, tok, global) => { + var macro = parser.gullet.macros.get(tok.text); + + if (macro == null) { + // don't expand it later even if a macro with the same name is defined + // e.g., \let\foo=\frac \def\frac{\relax} \frac12 + tok.noexpand = true; + macro = { + tokens: [tok], + numArgs: 0, + // reproduce the same behavior in expansion + unexpandable: !parser.gullet.isExpandable(tok.text) + }; + } + + parser.gullet.macros.set(name, macro, global); +}; // -> | +// -> |\global +// -> | +// -> \global|\long|\outer + + +defineFunction({ + type: "internal", + names: ["\\global", "\\long", "\\\\globallong" // can’t be entered directly + ], + props: { + numArgs: 0, + allowedInText: true + }, + + handler(_ref) { + var { + parser, + funcName + } = _ref; + parser.consumeSpaces(); + var token = parser.fetch(); + + if (globalMap[token.text]) { + // KaTeX doesn't have \par, so ignore \long + if (funcName === "\\global" || funcName === "\\\\globallong") { + token.text = globalMap[token.text]; + } + + return assertNodeType(parser.parseFunction(), "internal"); + } + + throw new ParseError("Invalid token after macro prefix", token); + } + +}); // Basic support for macro definitions: \def, \gdef, \edef, \xdef +// -> +// -> \def|\gdef|\edef|\xdef +// -> + +defineFunction({ + type: "internal", + names: ["\\def", "\\gdef", "\\edef", "\\xdef"], + props: { + numArgs: 0, + allowedInText: true, + primitive: true + }, + + handler(_ref2) { + var { + parser, + funcName + } = _ref2; + var tok = parser.gullet.popToken(); + var name = tok.text; + + if (/^(?:[\\{}$&#^_]|EOF)$/.test(name)) { + throw new ParseError("Expected a control sequence", tok); + } + + var numArgs = 0; + var insert; + var delimiters = [[]]; // contains no braces + + while (parser.gullet.future().text !== "{") { + tok = parser.gullet.popToken(); + + if (tok.text === "#") { + // If the very last character of the is #, so that + // this # is immediately followed by {, TeX will behave as if the { + // had been inserted at the right end of both the parameter text + // and the replacement text. + if (parser.gullet.future().text === "{") { + insert = parser.gullet.future(); + delimiters[numArgs].push("{"); + break; + } // A parameter, the first appearance of # must be followed by 1, + // the next by 2, and so on; up to nine #’s are allowed + + + tok = parser.gullet.popToken(); + + if (!/^[1-9]$/.test(tok.text)) { + throw new ParseError("Invalid argument number \"" + tok.text + "\""); + } + + if (parseInt(tok.text) !== numArgs + 1) { + throw new ParseError("Argument number \"" + tok.text + "\" out of order"); + } + + numArgs++; + delimiters.push([]); + } else if (tok.text === "EOF") { + throw new ParseError("Expected a macro definition"); + } else { + delimiters[numArgs].push(tok.text); + } + } // replacement text, enclosed in '{' and '}' and properly nested + + + var { + tokens + } = parser.gullet.consumeArg(); + + if (insert) { + tokens.unshift(insert); + } + + if (funcName === "\\edef" || funcName === "\\xdef") { + tokens = parser.gullet.expandTokens(tokens); + tokens.reverse(); // to fit in with stack order + } // Final arg is the expansion of the macro + + + parser.gullet.macros.set(name, { + tokens, + numArgs, + delimiters + }, funcName === globalMap[funcName]); + return { + type: "internal", + mode: parser.mode + }; + } + +}); // -> +// -> \futurelet +// | \let +// -> |= + +defineFunction({ + type: "internal", + names: ["\\let", "\\\\globallet" // can’t be entered directly + ], + props: { + numArgs: 0, + allowedInText: true, + primitive: true + }, + + handler(_ref3) { + var { + parser, + funcName + } = _ref3; + var name = checkControlSequence(parser.gullet.popToken()); + parser.gullet.consumeSpaces(); + var tok = getRHS(parser); + letCommand(parser, name, tok, funcName === "\\\\globallet"); + return { + type: "internal", + mode: parser.mode + }; + } + +}); // ref: https://www.tug.org/TUGboat/tb09-3/tb22bechtolsheim.pdf + +defineFunction({ + type: "internal", + names: ["\\futurelet", "\\\\globalfuture" // can’t be entered directly + ], + props: { + numArgs: 0, + allowedInText: true, + primitive: true + }, + + handler(_ref4) { + var { + parser, + funcName + } = _ref4; + var name = checkControlSequence(parser.gullet.popToken()); + var middle = parser.gullet.popToken(); + var tok = parser.gullet.popToken(); + letCommand(parser, name, tok, funcName === "\\\\globalfuture"); + parser.gullet.pushToken(tok); + parser.gullet.pushToken(middle); + return { + type: "internal", + mode: parser.mode + }; + } + +}); + +/** + * This file deals with creating delimiters of various sizes. The TeXbook + * discusses these routines on page 441-442, in the "Another subroutine sets box + * x to a specified variable delimiter" paragraph. + * + * There are three main routines here. `makeSmallDelim` makes a delimiter in the + * normal font, but in either text, script, or scriptscript style. + * `makeLargeDelim` makes a delimiter in textstyle, but in one of the Size1, + * Size2, Size3, or Size4 fonts. `makeStackedDelim` makes a delimiter out of + * smaller pieces that are stacked on top of one another. + * + * The functions take a parameter `center`, which determines if the delimiter + * should be centered around the axis. + * + * Then, there are three exposed functions. `sizedDelim` makes a delimiter in + * one of the given sizes. This is used for things like `\bigl`. + * `customSizedDelim` makes a delimiter with a given total height+depth. It is + * called in places like `\sqrt`. `leftRightDelim` makes an appropriate + * delimiter which surrounds an expression of a given height an depth. It is + * used in `\left` and `\right`. + */ + +/** + * Get the metrics for a given symbol and font, after transformation (i.e. + * after following replacement from symbols.js) + */ +var getMetrics = function getMetrics(symbol, font, mode) { + var replace = symbols.math[symbol] && symbols.math[symbol].replace; + var metrics = getCharacterMetrics(replace || symbol, font, mode); + + if (!metrics) { + throw new Error("Unsupported symbol " + symbol + " and font size " + font + "."); + } + + return metrics; +}; +/** + * Puts a delimiter span in a given style, and adds appropriate height, depth, + * and maxFontSizes. + */ + + +var styleWrap = function styleWrap(delim, toStyle, options, classes) { + var newOptions = options.havingBaseStyle(toStyle); + var span = buildCommon.makeSpan(classes.concat(newOptions.sizingClasses(options)), [delim], options); + var delimSizeMultiplier = newOptions.sizeMultiplier / options.sizeMultiplier; + span.height *= delimSizeMultiplier; + span.depth *= delimSizeMultiplier; + span.maxFontSize = newOptions.sizeMultiplier; + return span; +}; + +var centerSpan = function centerSpan(span, options, style) { + var newOptions = options.havingBaseStyle(style); + var shift = (1 - options.sizeMultiplier / newOptions.sizeMultiplier) * options.fontMetrics().axisHeight; + span.classes.push("delimcenter"); + span.style.top = makeEm(shift); + span.height -= shift; + span.depth += shift; +}; +/** + * Makes a small delimiter. This is a delimiter that comes in the Main-Regular + * font, but is restyled to either be in textstyle, scriptstyle, or + * scriptscriptstyle. + */ + + +var makeSmallDelim = function makeSmallDelim(delim, style, center, options, mode, classes) { + var text = buildCommon.makeSymbol(delim, "Main-Regular", mode, options); + var span = styleWrap(text, style, options, classes); + + if (center) { + centerSpan(span, options, style); + } + + return span; +}; +/** + * Builds a symbol in the given font size (note size is an integer) + */ + + +var mathrmSize = function mathrmSize(value, size, mode, options) { + return buildCommon.makeSymbol(value, "Size" + size + "-Regular", mode, options); +}; +/** + * Makes a large delimiter. This is a delimiter that comes in the Size1, Size2, + * Size3, or Size4 fonts. It is always rendered in textstyle. + */ + + +var makeLargeDelim = function makeLargeDelim(delim, size, center, options, mode, classes) { + var inner = mathrmSize(delim, size, mode, options); + var span = styleWrap(buildCommon.makeSpan(["delimsizing", "size" + size], [inner], options), Style$1.TEXT, options, classes); + + if (center) { + centerSpan(span, options, Style$1.TEXT); + } + + return span; +}; +/** + * Make a span from a font glyph with the given offset and in the given font. + * This is used in makeStackedDelim to make the stacking pieces for the delimiter. + */ + + +var makeGlyphSpan = function makeGlyphSpan(symbol, font, mode) { + var sizeClass; // Apply the correct CSS class to choose the right font. + + if (font === "Size1-Regular") { + sizeClass = "delim-size1"; + } else + /* if (font === "Size4-Regular") */ + { + sizeClass = "delim-size4"; + } + + var corner = buildCommon.makeSpan(["delimsizinginner", sizeClass], [buildCommon.makeSpan([], [buildCommon.makeSymbol(symbol, font, mode)])]); // Since this will be passed into `makeVList` in the end, wrap the element + // in the appropriate tag that VList uses. + + return { + type: "elem", + elem: corner + }; +}; + +var makeInner = function makeInner(ch, height, options) { + // Create a span with inline SVG for the inner part of a tall stacked delimiter. + var width = fontMetricsData['Size4-Regular'][ch.charCodeAt(0)] ? fontMetricsData['Size4-Regular'][ch.charCodeAt(0)][4] : fontMetricsData['Size1-Regular'][ch.charCodeAt(0)][4]; + var path = new PathNode("inner", innerPath(ch, Math.round(1000 * height))); + var svgNode = new SvgNode([path], { + "width": makeEm(width), + "height": makeEm(height), + // Override CSS rule `.katex svg { width: 100% }` + "style": "width:" + makeEm(width), + "viewBox": "0 0 " + 1000 * width + " " + Math.round(1000 * height), + "preserveAspectRatio": "xMinYMin" + }); + var span = buildCommon.makeSvgSpan([], [svgNode], options); + span.height = height; + span.style.height = makeEm(height); + span.style.width = makeEm(width); + return { + type: "elem", + elem: span + }; +}; // Helpers for makeStackedDelim + + +var lapInEms = 0.008; +var lap = { + type: "kern", + size: -1 * lapInEms +}; +var verts = ["|", "\\lvert", "\\rvert", "\\vert"]; +var doubleVerts = ["\\|", "\\lVert", "\\rVert", "\\Vert"]; +/** + * Make a stacked delimiter out of a given delimiter, with the total height at + * least `heightTotal`. This routine is mentioned on page 442 of the TeXbook. + */ + +var makeStackedDelim = function makeStackedDelim(delim, heightTotal, center, options, mode, classes) { + // There are four parts, the top, an optional middle, a repeated part, and a + // bottom. + var top; + var middle; + var repeat; + var bottom; + var svgLabel = ""; + var viewBoxWidth = 0; + top = repeat = bottom = delim; + middle = null; // Also keep track of what font the delimiters are in + + var font = "Size1-Regular"; // We set the parts and font based on the symbol. Note that we use + // '\u23d0' instead of '|' and '\u2016' instead of '\\|' for the + // repeats of the arrows + + if (delim === "\\uparrow") { + repeat = bottom = "\u23d0"; + } else if (delim === "\\Uparrow") { + repeat = bottom = "\u2016"; + } else if (delim === "\\downarrow") { + top = repeat = "\u23d0"; + } else if (delim === "\\Downarrow") { + top = repeat = "\u2016"; + } else if (delim === "\\updownarrow") { + top = "\\uparrow"; + repeat = "\u23d0"; + bottom = "\\downarrow"; + } else if (delim === "\\Updownarrow") { + top = "\\Uparrow"; + repeat = "\u2016"; + bottom = "\\Downarrow"; + } else if (utils.contains(verts, delim)) { + repeat = "\u2223"; + svgLabel = "vert"; + viewBoxWidth = 333; + } else if (utils.contains(doubleVerts, delim)) { + repeat = "\u2225"; + svgLabel = "doublevert"; + viewBoxWidth = 556; + } else if (delim === "[" || delim === "\\lbrack") { + top = "\u23a1"; + repeat = "\u23a2"; + bottom = "\u23a3"; + font = "Size4-Regular"; + svgLabel = "lbrack"; + viewBoxWidth = 667; + } else if (delim === "]" || delim === "\\rbrack") { + top = "\u23a4"; + repeat = "\u23a5"; + bottom = "\u23a6"; + font = "Size4-Regular"; + svgLabel = "rbrack"; + viewBoxWidth = 667; + } else if (delim === "\\lfloor" || delim === "\u230a") { + repeat = top = "\u23a2"; + bottom = "\u23a3"; + font = "Size4-Regular"; + svgLabel = "lfloor"; + viewBoxWidth = 667; + } else if (delim === "\\lceil" || delim === "\u2308") { + top = "\u23a1"; + repeat = bottom = "\u23a2"; + font = "Size4-Regular"; + svgLabel = "lceil"; + viewBoxWidth = 667; + } else if (delim === "\\rfloor" || delim === "\u230b") { + repeat = top = "\u23a5"; + bottom = "\u23a6"; + font = "Size4-Regular"; + svgLabel = "rfloor"; + viewBoxWidth = 667; + } else if (delim === "\\rceil" || delim === "\u2309") { + top = "\u23a4"; + repeat = bottom = "\u23a5"; + font = "Size4-Regular"; + svgLabel = "rceil"; + viewBoxWidth = 667; + } else if (delim === "(" || delim === "\\lparen") { + top = "\u239b"; + repeat = "\u239c"; + bottom = "\u239d"; + font = "Size4-Regular"; + svgLabel = "lparen"; + viewBoxWidth = 875; + } else if (delim === ")" || delim === "\\rparen") { + top = "\u239e"; + repeat = "\u239f"; + bottom = "\u23a0"; + font = "Size4-Regular"; + svgLabel = "rparen"; + viewBoxWidth = 875; + } else if (delim === "\\{" || delim === "\\lbrace") { + top = "\u23a7"; + middle = "\u23a8"; + bottom = "\u23a9"; + repeat = "\u23aa"; + font = "Size4-Regular"; + } else if (delim === "\\}" || delim === "\\rbrace") { + top = "\u23ab"; + middle = "\u23ac"; + bottom = "\u23ad"; + repeat = "\u23aa"; + font = "Size4-Regular"; + } else if (delim === "\\lgroup" || delim === "\u27ee") { + top = "\u23a7"; + bottom = "\u23a9"; + repeat = "\u23aa"; + font = "Size4-Regular"; + } else if (delim === "\\rgroup" || delim === "\u27ef") { + top = "\u23ab"; + bottom = "\u23ad"; + repeat = "\u23aa"; + font = "Size4-Regular"; + } else if (delim === "\\lmoustache" || delim === "\u23b0") { + top = "\u23a7"; + bottom = "\u23ad"; + repeat = "\u23aa"; + font = "Size4-Regular"; + } else if (delim === "\\rmoustache" || delim === "\u23b1") { + top = "\u23ab"; + bottom = "\u23a9"; + repeat = "\u23aa"; + font = "Size4-Regular"; + } // Get the metrics of the four sections + + + var topMetrics = getMetrics(top, font, mode); + var topHeightTotal = topMetrics.height + topMetrics.depth; + var repeatMetrics = getMetrics(repeat, font, mode); + var repeatHeightTotal = repeatMetrics.height + repeatMetrics.depth; + var bottomMetrics = getMetrics(bottom, font, mode); + var bottomHeightTotal = bottomMetrics.height + bottomMetrics.depth; + var middleHeightTotal = 0; + var middleFactor = 1; + + if (middle !== null) { + var middleMetrics = getMetrics(middle, font, mode); + middleHeightTotal = middleMetrics.height + middleMetrics.depth; + middleFactor = 2; // repeat symmetrically above and below middle + } // Calculate the minimal height that the delimiter can have. + // It is at least the size of the top, bottom, and optional middle combined. + + + var minHeight = topHeightTotal + bottomHeightTotal + middleHeightTotal; // Compute the number of copies of the repeat symbol we will need + + var repeatCount = Math.max(0, Math.ceil((heightTotal - minHeight) / (middleFactor * repeatHeightTotal))); // Compute the total height of the delimiter including all the symbols + + var realHeightTotal = minHeight + repeatCount * middleFactor * repeatHeightTotal; // The center of the delimiter is placed at the center of the axis. Note + // that in this context, "center" means that the delimiter should be + // centered around the axis in the current style, while normally it is + // centered around the axis in textstyle. + + var axisHeight = options.fontMetrics().axisHeight; + + if (center) { + axisHeight *= options.sizeMultiplier; + } // Calculate the depth + + + var depth = realHeightTotal / 2 - axisHeight; // Now, we start building the pieces that will go into the vlist + // Keep a list of the pieces of the stacked delimiter + + var stack = []; + + if (svgLabel.length > 0) { + // Instead of stacking glyphs, create a single SVG. + // This evades browser problems with imprecise positioning of spans. + var midHeight = realHeightTotal - topHeightTotal - bottomHeightTotal; + var viewBoxHeight = Math.round(realHeightTotal * 1000); + var pathStr = tallDelim(svgLabel, Math.round(midHeight * 1000)); + var path = new PathNode(svgLabel, pathStr); + var width = (viewBoxWidth / 1000).toFixed(3) + "em"; + var height = (viewBoxHeight / 1000).toFixed(3) + "em"; + var svg = new SvgNode([path], { + "width": width, + "height": height, + "viewBox": "0 0 " + viewBoxWidth + " " + viewBoxHeight + }); + var wrapper = buildCommon.makeSvgSpan([], [svg], options); + wrapper.height = viewBoxHeight / 1000; + wrapper.style.width = width; + wrapper.style.height = height; + stack.push({ + type: "elem", + elem: wrapper + }); + } else { + // Stack glyphs + // Start by adding the bottom symbol + stack.push(makeGlyphSpan(bottom, font, mode)); + stack.push(lap); // overlap + + if (middle === null) { + // The middle section will be an SVG. Make it an extra 0.016em tall. + // We'll overlap by 0.008em at top and bottom. + var innerHeight = realHeightTotal - topHeightTotal - bottomHeightTotal + 2 * lapInEms; + stack.push(makeInner(repeat, innerHeight, options)); + } else { + // When there is a middle bit, we need the middle part and two repeated + // sections + var _innerHeight = (realHeightTotal - topHeightTotal - bottomHeightTotal - middleHeightTotal) / 2 + 2 * lapInEms; + + stack.push(makeInner(repeat, _innerHeight, options)); // Now insert the middle of the brace. + + stack.push(lap); + stack.push(makeGlyphSpan(middle, font, mode)); + stack.push(lap); + stack.push(makeInner(repeat, _innerHeight, options)); + } // Add the top symbol + + + stack.push(lap); + stack.push(makeGlyphSpan(top, font, mode)); + } // Finally, build the vlist + + + var newOptions = options.havingBaseStyle(Style$1.TEXT); + var inner = buildCommon.makeVList({ + positionType: "bottom", + positionData: depth, + children: stack + }, newOptions); + return styleWrap(buildCommon.makeSpan(["delimsizing", "mult"], [inner], newOptions), Style$1.TEXT, options, classes); +}; // All surds have 0.08em padding above the vinculum inside the SVG. +// That keeps browser span height rounding error from pinching the line. + + +var vbPad = 80; // padding above the surd, measured inside the viewBox. + +var emPad = 0.08; // padding, in ems, measured in the document. + +var sqrtSvg = function sqrtSvg(sqrtName, height, viewBoxHeight, extraVinculum, options) { + var path = sqrtPath(sqrtName, extraVinculum, viewBoxHeight); + var pathNode = new PathNode(sqrtName, path); + var svg = new SvgNode([pathNode], { + // Note: 1000:1 ratio of viewBox to document em width. + "width": "400em", + "height": makeEm(height), + "viewBox": "0 0 400000 " + viewBoxHeight, + "preserveAspectRatio": "xMinYMin slice" + }); + return buildCommon.makeSvgSpan(["hide-tail"], [svg], options); +}; +/** + * Make a sqrt image of the given height, + */ + + +var makeSqrtImage = function makeSqrtImage(height, options) { + // Define a newOptions that removes the effect of size changes such as \Huge. + // We don't pick different a height surd for \Huge. For it, we scale up. + var newOptions = options.havingBaseSizing(); // Pick the desired surd glyph from a sequence of surds. + + var delim = traverseSequence("\\surd", height * newOptions.sizeMultiplier, stackLargeDelimiterSequence, newOptions); + var sizeMultiplier = newOptions.sizeMultiplier; // default + // The standard sqrt SVGs each have a 0.04em thick vinculum. + // If Settings.minRuleThickness is larger than that, we add extraVinculum. + + var extraVinculum = Math.max(0, options.minRuleThickness - options.fontMetrics().sqrtRuleThickness); // Create a span containing an SVG image of a sqrt symbol. + + var span; + var spanHeight = 0; + var texHeight = 0; + var viewBoxHeight = 0; + var advanceWidth; // We create viewBoxes with 80 units of "padding" above each surd. + // Then browser rounding error on the parent span height will not + // encroach on the ink of the vinculum. But that padding is not + // included in the TeX-like `height` used for calculation of + // vertical alignment. So texHeight = span.height < span.style.height. + + if (delim.type === "small") { + // Get an SVG that is derived from glyph U+221A in font KaTeX-Main. + // 1000 unit normal glyph height. + viewBoxHeight = 1000 + 1000 * extraVinculum + vbPad; + + if (height < 1.0) { + sizeMultiplier = 1.0; // mimic a \textfont radical + } else if (height < 1.4) { + sizeMultiplier = 0.7; // mimic a \scriptfont radical + } + + spanHeight = (1.0 + extraVinculum + emPad) / sizeMultiplier; + texHeight = (1.00 + extraVinculum) / sizeMultiplier; + span = sqrtSvg("sqrtMain", spanHeight, viewBoxHeight, extraVinculum, options); + span.style.minWidth = "0.853em"; + advanceWidth = 0.833 / sizeMultiplier; // from the font. + } else if (delim.type === "large") { + // These SVGs come from fonts: KaTeX_Size1, _Size2, etc. + viewBoxHeight = (1000 + vbPad) * sizeToMaxHeight[delim.size]; + texHeight = (sizeToMaxHeight[delim.size] + extraVinculum) / sizeMultiplier; + spanHeight = (sizeToMaxHeight[delim.size] + extraVinculum + emPad) / sizeMultiplier; + span = sqrtSvg("sqrtSize" + delim.size, spanHeight, viewBoxHeight, extraVinculum, options); + span.style.minWidth = "1.02em"; + advanceWidth = 1.0 / sizeMultiplier; // 1.0 from the font. + } else { + // Tall sqrt. In TeX, this would be stacked using multiple glyphs. + // We'll use a single SVG to accomplish the same thing. + spanHeight = height + extraVinculum + emPad; + texHeight = height + extraVinculum; + viewBoxHeight = Math.floor(1000 * height + extraVinculum) + vbPad; + span = sqrtSvg("sqrtTall", spanHeight, viewBoxHeight, extraVinculum, options); + span.style.minWidth = "0.742em"; + advanceWidth = 1.056; + } + + span.height = texHeight; + span.style.height = makeEm(spanHeight); + return { + span, + advanceWidth, + // Calculate the actual line width. + // This actually should depend on the chosen font -- e.g. \boldmath + // should use the thicker surd symbols from e.g. KaTeX_Main-Bold, and + // have thicker rules. + ruleWidth: (options.fontMetrics().sqrtRuleThickness + extraVinculum) * sizeMultiplier + }; +}; // There are three kinds of delimiters, delimiters that stack when they become +// too large + + +var stackLargeDelimiters = ["(", "\\lparen", ")", "\\rparen", "[", "\\lbrack", "]", "\\rbrack", "\\{", "\\lbrace", "\\}", "\\rbrace", "\\lfloor", "\\rfloor", "\u230a", "\u230b", "\\lceil", "\\rceil", "\u2308", "\u2309", "\\surd"]; // delimiters that always stack + +var stackAlwaysDelimiters = ["\\uparrow", "\\downarrow", "\\updownarrow", "\\Uparrow", "\\Downarrow", "\\Updownarrow", "|", "\\|", "\\vert", "\\Vert", "\\lvert", "\\rvert", "\\lVert", "\\rVert", "\\lgroup", "\\rgroup", "\u27ee", "\u27ef", "\\lmoustache", "\\rmoustache", "\u23b0", "\u23b1"]; // and delimiters that never stack + +var stackNeverDelimiters = ["<", ">", "\\langle", "\\rangle", "/", "\\backslash", "\\lt", "\\gt"]; // Metrics of the different sizes. Found by looking at TeX's output of +// $\bigl| // \Bigl| \biggl| \Biggl| \showlists$ +// Used to create stacked delimiters of appropriate sizes in makeSizedDelim. + +var sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0]; +/** + * Used to create a delimiter of a specific size, where `size` is 1, 2, 3, or 4. + */ + +var makeSizedDelim = function makeSizedDelim(delim, size, options, mode, classes) { + // < and > turn into \langle and \rangle in delimiters + if (delim === "<" || delim === "\\lt" || delim === "\u27e8") { + delim = "\\langle"; + } else if (delim === ">" || delim === "\\gt" || delim === "\u27e9") { + delim = "\\rangle"; + } // Sized delimiters are never centered. + + + if (utils.contains(stackLargeDelimiters, delim) || utils.contains(stackNeverDelimiters, delim)) { + return makeLargeDelim(delim, size, false, options, mode, classes); + } else if (utils.contains(stackAlwaysDelimiters, delim)) { + return makeStackedDelim(delim, sizeToMaxHeight[size], false, options, mode, classes); + } else { + throw new ParseError("Illegal delimiter: '" + delim + "'"); + } +}; +/** + * There are three different sequences of delimiter sizes that the delimiters + * follow depending on the kind of delimiter. This is used when creating custom + * sized delimiters to decide whether to create a small, large, or stacked + * delimiter. + * + * In real TeX, these sequences aren't explicitly defined, but are instead + * defined inside the font metrics. Since there are only three sequences that + * are possible for the delimiters that TeX defines, it is easier to just encode + * them explicitly here. + */ + + +// Delimiters that never stack try small delimiters and large delimiters only +var stackNeverDelimiterSequence = [{ + type: "small", + style: Style$1.SCRIPTSCRIPT +}, { + type: "small", + style: Style$1.SCRIPT +}, { + type: "small", + style: Style$1.TEXT +}, { + type: "large", + size: 1 +}, { + type: "large", + size: 2 +}, { + type: "large", + size: 3 +}, { + type: "large", + size: 4 +}]; // Delimiters that always stack try the small delimiters first, then stack + +var stackAlwaysDelimiterSequence = [{ + type: "small", + style: Style$1.SCRIPTSCRIPT +}, { + type: "small", + style: Style$1.SCRIPT +}, { + type: "small", + style: Style$1.TEXT +}, { + type: "stack" +}]; // Delimiters that stack when large try the small and then large delimiters, and +// stack afterwards + +var stackLargeDelimiterSequence = [{ + type: "small", + style: Style$1.SCRIPTSCRIPT +}, { + type: "small", + style: Style$1.SCRIPT +}, { + type: "small", + style: Style$1.TEXT +}, { + type: "large", + size: 1 +}, { + type: "large", + size: 2 +}, { + type: "large", + size: 3 +}, { + type: "large", + size: 4 +}, { + type: "stack" +}]; +/** + * Get the font used in a delimiter based on what kind of delimiter it is. + * TODO(#963) Use more specific font family return type once that is introduced. + */ + +var delimTypeToFont = function delimTypeToFont(type) { + if (type.type === "small") { + return "Main-Regular"; + } else if (type.type === "large") { + return "Size" + type.size + "-Regular"; + } else if (type.type === "stack") { + return "Size4-Regular"; + } else { + throw new Error("Add support for delim type '" + type.type + "' here."); + } +}; +/** + * Traverse a sequence of types of delimiters to decide what kind of delimiter + * should be used to create a delimiter of the given height+depth. + */ + + +var traverseSequence = function traverseSequence(delim, height, sequence, options) { + // Here, we choose the index we should start at in the sequences. In smaller + // sizes (which correspond to larger numbers in style.size) we start earlier + // in the sequence. Thus, scriptscript starts at index 3-3=0, script starts + // at index 3-2=1, text starts at 3-1=2, and display starts at min(2,3-0)=2 + var start = Math.min(2, 3 - options.style.size); + + for (var i = start; i < sequence.length; i++) { + if (sequence[i].type === "stack") { + // This is always the last delimiter, so we just break the loop now. + break; + } + + var metrics = getMetrics(delim, delimTypeToFont(sequence[i]), "math"); + var heightDepth = metrics.height + metrics.depth; // Small delimiters are scaled down versions of the same font, so we + // account for the style change size. + + if (sequence[i].type === "small") { + var newOptions = options.havingBaseStyle(sequence[i].style); + heightDepth *= newOptions.sizeMultiplier; + } // Check if the delimiter at this size works for the given height. + + + if (heightDepth > height) { + return sequence[i]; + } + } // If we reached the end of the sequence, return the last sequence element. + + + return sequence[sequence.length - 1]; +}; +/** + * Make a delimiter of a given height+depth, with optional centering. Here, we + * traverse the sequences, and create a delimiter that the sequence tells us to. + */ + + +var makeCustomSizedDelim = function makeCustomSizedDelim(delim, height, center, options, mode, classes) { + if (delim === "<" || delim === "\\lt" || delim === "\u27e8") { + delim = "\\langle"; + } else if (delim === ">" || delim === "\\gt" || delim === "\u27e9") { + delim = "\\rangle"; + } // Decide what sequence to use + + + var sequence; + + if (utils.contains(stackNeverDelimiters, delim)) { + sequence = stackNeverDelimiterSequence; + } else if (utils.contains(stackLargeDelimiters, delim)) { + sequence = stackLargeDelimiterSequence; + } else { + sequence = stackAlwaysDelimiterSequence; + } // Look through the sequence + + + var delimType = traverseSequence(delim, height, sequence, options); // Get the delimiter from font glyphs. + // Depending on the sequence element we decided on, call the + // appropriate function. + + if (delimType.type === "small") { + return makeSmallDelim(delim, delimType.style, center, options, mode, classes); + } else if (delimType.type === "large") { + return makeLargeDelim(delim, delimType.size, center, options, mode, classes); + } else + /* if (delimType.type === "stack") */ + { + return makeStackedDelim(delim, height, center, options, mode, classes); + } +}; +/** + * Make a delimiter for use with `\left` and `\right`, given a height and depth + * of an expression that the delimiters surround. + */ + + +var makeLeftRightDelim = function makeLeftRightDelim(delim, height, depth, options, mode, classes) { + // We always center \left/\right delimiters, so the axis is always shifted + var axisHeight = options.fontMetrics().axisHeight * options.sizeMultiplier; // Taken from TeX source, tex.web, function make_left_right + + var delimiterFactor = 901; + var delimiterExtend = 5.0 / options.fontMetrics().ptPerEm; + var maxDistFromAxis = Math.max(height - axisHeight, depth + axisHeight); + var totalHeight = Math.max( // In real TeX, calculations are done using integral values which are + // 65536 per pt, or 655360 per em. So, the division here truncates in + // TeX but doesn't here, producing different results. If we wanted to + // exactly match TeX's calculation, we could do + // Math.floor(655360 * maxDistFromAxis / 500) * + // delimiterFactor / 655360 + // (To see the difference, compare + // x^{x^{\left(\rule{0.1em}{0.68em}\right)}} + // in TeX and KaTeX) + maxDistFromAxis / 500 * delimiterFactor, 2 * maxDistFromAxis - delimiterExtend); // Finally, we defer to `makeCustomSizedDelim` with our calculated total + // height + + return makeCustomSizedDelim(delim, totalHeight, true, options, mode, classes); +}; + +var delimiter = { + sqrtImage: makeSqrtImage, + sizedDelim: makeSizedDelim, + sizeToMaxHeight: sizeToMaxHeight, + customSizedDelim: makeCustomSizedDelim, + leftRightDelim: makeLeftRightDelim +}; + +// Extra data needed for the delimiter handler down below +var delimiterSizes = { + "\\bigl": { + mclass: "mopen", + size: 1 + }, + "\\Bigl": { + mclass: "mopen", + size: 2 + }, + "\\biggl": { + mclass: "mopen", + size: 3 + }, + "\\Biggl": { + mclass: "mopen", + size: 4 + }, + "\\bigr": { + mclass: "mclose", + size: 1 + }, + "\\Bigr": { + mclass: "mclose", + size: 2 + }, + "\\biggr": { + mclass: "mclose", + size: 3 + }, + "\\Biggr": { + mclass: "mclose", + size: 4 + }, + "\\bigm": { + mclass: "mrel", + size: 1 + }, + "\\Bigm": { + mclass: "mrel", + size: 2 + }, + "\\biggm": { + mclass: "mrel", + size: 3 + }, + "\\Biggm": { + mclass: "mrel", + size: 4 + }, + "\\big": { + mclass: "mord", + size: 1 + }, + "\\Big": { + mclass: "mord", + size: 2 + }, + "\\bigg": { + mclass: "mord", + size: 3 + }, + "\\Bigg": { + mclass: "mord", + size: 4 + } +}; +var delimiters = ["(", "\\lparen", ")", "\\rparen", "[", "\\lbrack", "]", "\\rbrack", "\\{", "\\lbrace", "\\}", "\\rbrace", "\\lfloor", "\\rfloor", "\u230a", "\u230b", "\\lceil", "\\rceil", "\u2308", "\u2309", "<", ">", "\\langle", "\u27e8", "\\rangle", "\u27e9", "\\lt", "\\gt", "\\lvert", "\\rvert", "\\lVert", "\\rVert", "\\lgroup", "\\rgroup", "\u27ee", "\u27ef", "\\lmoustache", "\\rmoustache", "\u23b0", "\u23b1", "/", "\\backslash", "|", "\\vert", "\\|", "\\Vert", "\\uparrow", "\\Uparrow", "\\downarrow", "\\Downarrow", "\\updownarrow", "\\Updownarrow", "."]; + +// Delimiter functions +function checkDelimiter(delim, context) { + var symDelim = checkSymbolNodeType(delim); + + if (symDelim && utils.contains(delimiters, symDelim.text)) { + return symDelim; + } else if (symDelim) { + throw new ParseError("Invalid delimiter '" + symDelim.text + "' after '" + context.funcName + "'", delim); + } else { + throw new ParseError("Invalid delimiter type '" + delim.type + "'", delim); + } +} + +defineFunction({ + type: "delimsizing", + names: ["\\bigl", "\\Bigl", "\\biggl", "\\Biggl", "\\bigr", "\\Bigr", "\\biggr", "\\Biggr", "\\bigm", "\\Bigm", "\\biggm", "\\Biggm", "\\big", "\\Big", "\\bigg", "\\Bigg"], + props: { + numArgs: 1, + argTypes: ["primitive"] + }, + handler: (context, args) => { + var delim = checkDelimiter(args[0], context); + return { + type: "delimsizing", + mode: context.parser.mode, + size: delimiterSizes[context.funcName].size, + mclass: delimiterSizes[context.funcName].mclass, + delim: delim.text + }; + }, + htmlBuilder: (group, options) => { + if (group.delim === ".") { + // Empty delimiters still count as elements, even though they don't + // show anything. + return buildCommon.makeSpan([group.mclass]); + } // Use delimiter.sizedDelim to generate the delimiter. + + + return delimiter.sizedDelim(group.delim, group.size, options, group.mode, [group.mclass]); + }, + mathmlBuilder: group => { + var children = []; + + if (group.delim !== ".") { + children.push(makeText(group.delim, group.mode)); + } + + var node = new mathMLTree.MathNode("mo", children); + + if (group.mclass === "mopen" || group.mclass === "mclose") { + // Only some of the delimsizing functions act as fences, and they + // return "mopen" or "mclose" mclass. + node.setAttribute("fence", "true"); + } else { + // Explicitly disable fencing if it's not a fence, to override the + // defaults. + node.setAttribute("fence", "false"); + } + + node.setAttribute("stretchy", "true"); + var size = makeEm(delimiter.sizeToMaxHeight[group.size]); + node.setAttribute("minsize", size); + node.setAttribute("maxsize", size); + return node; + } +}); + +function assertParsed(group) { + if (!group.body) { + throw new Error("Bug: The leftright ParseNode wasn't fully parsed."); + } +} + +defineFunction({ + type: "leftright-right", + names: ["\\right"], + props: { + numArgs: 1, + primitive: true + }, + handler: (context, args) => { + // \left case below triggers parsing of \right in + // `const right = parser.parseFunction();` + // uses this return value. + var color = context.parser.gullet.macros.get("\\current@color"); + + if (color && typeof color !== "string") { + throw new ParseError("\\current@color set to non-string in \\right"); + } + + return { + type: "leftright-right", + mode: context.parser.mode, + delim: checkDelimiter(args[0], context).text, + color // undefined if not set via \color + + }; + } +}); +defineFunction({ + type: "leftright", + names: ["\\left"], + props: { + numArgs: 1, + primitive: true + }, + handler: (context, args) => { + var delim = checkDelimiter(args[0], context); + var parser = context.parser; // Parse out the implicit body + + ++parser.leftrightDepth; // parseExpression stops before '\\right' + + var body = parser.parseExpression(false); + --parser.leftrightDepth; // Check the next token + + parser.expect("\\right", false); + var right = assertNodeType(parser.parseFunction(), "leftright-right"); + return { + type: "leftright", + mode: parser.mode, + body, + left: delim.text, + right: right.delim, + rightColor: right.color + }; + }, + htmlBuilder: (group, options) => { + assertParsed(group); // Build the inner expression + + var inner = buildExpression$1(group.body, options, true, ["mopen", "mclose"]); + var innerHeight = 0; + var innerDepth = 0; + var hadMiddle = false; // Calculate its height and depth + + for (var i = 0; i < inner.length; i++) { + // Property `isMiddle` not defined on `span`. See comment in + // "middle"'s htmlBuilder. + // $FlowFixMe + if (inner[i].isMiddle) { + hadMiddle = true; + } else { + innerHeight = Math.max(inner[i].height, innerHeight); + innerDepth = Math.max(inner[i].depth, innerDepth); + } + } // The size of delimiters is the same, regardless of what style we are + // in. Thus, to correctly calculate the size of delimiter we need around + // a group, we scale down the inner size based on the size. + + + innerHeight *= options.sizeMultiplier; + innerDepth *= options.sizeMultiplier; + var leftDelim; + + if (group.left === ".") { + // Empty delimiters in \left and \right make null delimiter spaces. + leftDelim = makeNullDelimiter(options, ["mopen"]); + } else { + // Otherwise, use leftRightDelim to generate the correct sized + // delimiter. + leftDelim = delimiter.leftRightDelim(group.left, innerHeight, innerDepth, options, group.mode, ["mopen"]); + } // Add it to the beginning of the expression + + + inner.unshift(leftDelim); // Handle middle delimiters + + if (hadMiddle) { + for (var _i = 1; _i < inner.length; _i++) { + var middleDelim = inner[_i]; // Property `isMiddle` not defined on `span`. See comment in + // "middle"'s htmlBuilder. + // $FlowFixMe + + var isMiddle = middleDelim.isMiddle; + + if (isMiddle) { + // Apply the options that were active when \middle was called + inner[_i] = delimiter.leftRightDelim(isMiddle.delim, innerHeight, innerDepth, isMiddle.options, group.mode, []); + } + } + } + + var rightDelim; // Same for the right delimiter, but using color specified by \color + + if (group.right === ".") { + rightDelim = makeNullDelimiter(options, ["mclose"]); + } else { + var colorOptions = group.rightColor ? options.withColor(group.rightColor) : options; + rightDelim = delimiter.leftRightDelim(group.right, innerHeight, innerDepth, colorOptions, group.mode, ["mclose"]); + } // Add it to the end of the expression. + + + inner.push(rightDelim); + return buildCommon.makeSpan(["minner"], inner, options); + }, + mathmlBuilder: (group, options) => { + assertParsed(group); + var inner = buildExpression(group.body, options); + + if (group.left !== ".") { + var leftNode = new mathMLTree.MathNode("mo", [makeText(group.left, group.mode)]); + leftNode.setAttribute("fence", "true"); + inner.unshift(leftNode); + } + + if (group.right !== ".") { + var rightNode = new mathMLTree.MathNode("mo", [makeText(group.right, group.mode)]); + rightNode.setAttribute("fence", "true"); + + if (group.rightColor) { + rightNode.setAttribute("mathcolor", group.rightColor); + } + + inner.push(rightNode); + } + + return makeRow(inner); + } +}); +defineFunction({ + type: "middle", + names: ["\\middle"], + props: { + numArgs: 1, + primitive: true + }, + handler: (context, args) => { + var delim = checkDelimiter(args[0], context); + + if (!context.parser.leftrightDepth) { + throw new ParseError("\\middle without preceding \\left", delim); + } + + return { + type: "middle", + mode: context.parser.mode, + delim: delim.text + }; + }, + htmlBuilder: (group, options) => { + var middleDelim; + + if (group.delim === ".") { + middleDelim = makeNullDelimiter(options, []); + } else { + middleDelim = delimiter.sizedDelim(group.delim, 1, options, group.mode, []); + var isMiddle = { + delim: group.delim, + options + }; // Property `isMiddle` not defined on `span`. It is only used in + // this file above. + // TODO: Fix this violation of the `span` type and possibly rename + // things since `isMiddle` sounds like a boolean, but is a struct. + // $FlowFixMe + + middleDelim.isMiddle = isMiddle; + } + + return middleDelim; + }, + mathmlBuilder: (group, options) => { + // A Firefox \middle will stretch a character vertically only if it + // is in the fence part of the operator dictionary at: + // https://www.w3.org/TR/MathML3/appendixc.html. + // So we need to avoid U+2223 and use plain "|" instead. + var textNode = group.delim === "\\vert" || group.delim === "|" ? makeText("|", "text") : makeText(group.delim, group.mode); + var middleNode = new mathMLTree.MathNode("mo", [textNode]); + middleNode.setAttribute("fence", "true"); // MathML gives 5/18em spacing to each element. + // \middle should get delimiter spacing instead. + + middleNode.setAttribute("lspace", "0.05em"); + middleNode.setAttribute("rspace", "0.05em"); + return middleNode; + } +}); + +var htmlBuilder$7 = (group, options) => { + // \cancel, \bcancel, \xcancel, \sout, \fbox, \colorbox, \fcolorbox, \phase + // Some groups can return document fragments. Handle those by wrapping + // them in a span. + var inner = buildCommon.wrapFragment(buildGroup$1(group.body, options), options); + var label = group.label.slice(1); + var scale = options.sizeMultiplier; + var img; + var imgShift = 0; // In the LaTeX cancel package, line geometry is slightly different + // depending on whether the subject is wider than it is tall, or vice versa. + // We don't know the width of a group, so as a proxy, we test if + // the subject is a single character. This captures most of the + // subjects that should get the "tall" treatment. + + var isSingleChar = utils.isCharacterBox(group.body); + + if (label === "sout") { + img = buildCommon.makeSpan(["stretchy", "sout"]); + img.height = options.fontMetrics().defaultRuleThickness / scale; + imgShift = -0.5 * options.fontMetrics().xHeight; + } else if (label === "phase") { + // Set a couple of dimensions from the steinmetz package. + var lineWeight = calculateSize({ + number: 0.6, + unit: "pt" + }, options); + var clearance = calculateSize({ + number: 0.35, + unit: "ex" + }, options); // Prevent size changes like \Huge from affecting line thickness + + var newOptions = options.havingBaseSizing(); + scale = scale / newOptions.sizeMultiplier; + var angleHeight = inner.height + inner.depth + lineWeight + clearance; // Reserve a left pad for the angle. + + inner.style.paddingLeft = makeEm(angleHeight / 2 + lineWeight); // Create an SVG + + var viewBoxHeight = Math.floor(1000 * angleHeight * scale); + var path = phasePath(viewBoxHeight); + var svgNode = new SvgNode([new PathNode("phase", path)], { + "width": "400em", + "height": makeEm(viewBoxHeight / 1000), + "viewBox": "0 0 400000 " + viewBoxHeight, + "preserveAspectRatio": "xMinYMin slice" + }); // Wrap it in a span with overflow: hidden. + + img = buildCommon.makeSvgSpan(["hide-tail"], [svgNode], options); + img.style.height = makeEm(angleHeight); + imgShift = inner.depth + lineWeight + clearance; + } else { + // Add horizontal padding + if (/cancel/.test(label)) { + if (!isSingleChar) { + inner.classes.push("cancel-pad"); + } + } else if (label === "angl") { + inner.classes.push("anglpad"); + } else { + inner.classes.push("boxpad"); + } // Add vertical padding + + + var topPad = 0; + var bottomPad = 0; + var ruleThickness = 0; // ref: cancel package: \advance\totalheight2\p@ % "+2" + + if (/box/.test(label)) { + ruleThickness = Math.max(options.fontMetrics().fboxrule, // default + options.minRuleThickness // User override. + ); + topPad = options.fontMetrics().fboxsep + (label === "colorbox" ? 0 : ruleThickness); + bottomPad = topPad; + } else if (label === "angl") { + ruleThickness = Math.max(options.fontMetrics().defaultRuleThickness, options.minRuleThickness); + topPad = 4 * ruleThickness; // gap = 3 × line, plus the line itself. + + bottomPad = Math.max(0, 0.25 - inner.depth); + } else { + topPad = isSingleChar ? 0.2 : 0; + bottomPad = topPad; + } + + img = stretchy.encloseSpan(inner, label, topPad, bottomPad, options); + + if (/fbox|boxed|fcolorbox/.test(label)) { + img.style.borderStyle = "solid"; + img.style.borderWidth = makeEm(ruleThickness); + } else if (label === "angl" && ruleThickness !== 0.049) { + img.style.borderTopWidth = makeEm(ruleThickness); + img.style.borderRightWidth = makeEm(ruleThickness); + } + + imgShift = inner.depth + bottomPad; + + if (group.backgroundColor) { + img.style.backgroundColor = group.backgroundColor; + + if (group.borderColor) { + img.style.borderColor = group.borderColor; + } + } + } + + var vlist; + + if (group.backgroundColor) { + vlist = buildCommon.makeVList({ + positionType: "individualShift", + children: [// Put the color background behind inner; + { + type: "elem", + elem: img, + shift: imgShift + }, { + type: "elem", + elem: inner, + shift: 0 + }] + }, options); + } else { + var classes = /cancel|phase/.test(label) ? ["svg-align"] : []; + vlist = buildCommon.makeVList({ + positionType: "individualShift", + children: [// Write the \cancel stroke on top of inner. + { + type: "elem", + elem: inner, + shift: 0 + }, { + type: "elem", + elem: img, + shift: imgShift, + wrapperClasses: classes + }] + }, options); + } + + if (/cancel/.test(label)) { + // The cancel package documentation says that cancel lines add their height + // to the expression, but tests show that isn't how it actually works. + vlist.height = inner.height; + vlist.depth = inner.depth; + } + + if (/cancel/.test(label) && !isSingleChar) { + // cancel does not create horiz space for its line extension. + return buildCommon.makeSpan(["mord", "cancel-lap"], [vlist], options); + } else { + return buildCommon.makeSpan(["mord"], [vlist], options); + } +}; + +var mathmlBuilder$6 = (group, options) => { + var fboxsep = 0; + var node = new mathMLTree.MathNode(group.label.indexOf("colorbox") > -1 ? "mpadded" : "menclose", [buildGroup(group.body, options)]); + + switch (group.label) { + case "\\cancel": + node.setAttribute("notation", "updiagonalstrike"); + break; + + case "\\bcancel": + node.setAttribute("notation", "downdiagonalstrike"); + break; + + case "\\phase": + node.setAttribute("notation", "phasorangle"); + break; + + case "\\sout": + node.setAttribute("notation", "horizontalstrike"); + break; + + case "\\fbox": + node.setAttribute("notation", "box"); + break; + + case "\\angl": + node.setAttribute("notation", "actuarial"); + break; + + case "\\fcolorbox": + case "\\colorbox": + // doesn't have a good notation option. So use + // instead. Set some attributes that come included with . + fboxsep = options.fontMetrics().fboxsep * options.fontMetrics().ptPerEm; + node.setAttribute("width", "+" + 2 * fboxsep + "pt"); + node.setAttribute("height", "+" + 2 * fboxsep + "pt"); + node.setAttribute("lspace", fboxsep + "pt"); // + + node.setAttribute("voffset", fboxsep + "pt"); + + if (group.label === "\\fcolorbox") { + var thk = Math.max(options.fontMetrics().fboxrule, // default + options.minRuleThickness // user override + ); + node.setAttribute("style", "border: " + thk + "em solid " + String(group.borderColor)); + } + + break; + + case "\\xcancel": + node.setAttribute("notation", "updiagonalstrike downdiagonalstrike"); + break; + } + + if (group.backgroundColor) { + node.setAttribute("mathbackground", group.backgroundColor); + } + + return node; +}; + +defineFunction({ + type: "enclose", + names: ["\\colorbox"], + props: { + numArgs: 2, + allowedInText: true, + argTypes: ["color", "text"] + }, + + handler(_ref, args, optArgs) { + var { + parser, + funcName + } = _ref; + var color = assertNodeType(args[0], "color-token").color; + var body = args[1]; + return { + type: "enclose", + mode: parser.mode, + label: funcName, + backgroundColor: color, + body + }; + }, + + htmlBuilder: htmlBuilder$7, + mathmlBuilder: mathmlBuilder$6 +}); +defineFunction({ + type: "enclose", + names: ["\\fcolorbox"], + props: { + numArgs: 3, + allowedInText: true, + argTypes: ["color", "color", "text"] + }, + + handler(_ref2, args, optArgs) { + var { + parser, + funcName + } = _ref2; + var borderColor = assertNodeType(args[0], "color-token").color; + var backgroundColor = assertNodeType(args[1], "color-token").color; + var body = args[2]; + return { + type: "enclose", + mode: parser.mode, + label: funcName, + backgroundColor, + borderColor, + body + }; + }, + + htmlBuilder: htmlBuilder$7, + mathmlBuilder: mathmlBuilder$6 +}); +defineFunction({ + type: "enclose", + names: ["\\fbox"], + props: { + numArgs: 1, + argTypes: ["hbox"], + allowedInText: true + }, + + handler(_ref3, args) { + var { + parser + } = _ref3; + return { + type: "enclose", + mode: parser.mode, + label: "\\fbox", + body: args[0] + }; + } + +}); +defineFunction({ + type: "enclose", + names: ["\\cancel", "\\bcancel", "\\xcancel", "\\sout", "\\phase"], + props: { + numArgs: 1 + }, + + handler(_ref4, args) { + var { + parser, + funcName + } = _ref4; + var body = args[0]; + return { + type: "enclose", + mode: parser.mode, + label: funcName, + body + }; + }, + + htmlBuilder: htmlBuilder$7, + mathmlBuilder: mathmlBuilder$6 +}); +defineFunction({ + type: "enclose", + names: ["\\angl"], + props: { + numArgs: 1, + argTypes: ["hbox"], + allowedInText: false + }, + + handler(_ref5, args) { + var { + parser + } = _ref5; + return { + type: "enclose", + mode: parser.mode, + label: "\\angl", + body: args[0] + }; + } + +}); + +/** + * All registered environments. + * `environments.js` exports this same dictionary again and makes it public. + * `Parser.js` requires this dictionary via `environments.js`. + */ +var _environments = {}; +function defineEnvironment(_ref) { + var { + type, + names, + props, + handler, + htmlBuilder, + mathmlBuilder + } = _ref; + // Set default values of environments. + var data = { + type, + numArgs: props.numArgs || 0, + allowedInText: false, + numOptionalArgs: 0, + handler + }; + + for (var i = 0; i < names.length; ++i) { + // TODO: The value type of _environments should be a type union of all + // possible `EnvSpec<>` possibilities instead of `EnvSpec<*>`, which is + // an existential type. + _environments[names[i]] = data; + } + + if (htmlBuilder) { + _htmlGroupBuilders[type] = htmlBuilder; + } + + if (mathmlBuilder) { + _mathmlGroupBuilders[type] = mathmlBuilder; + } +} + +/** + * All registered global/built-in macros. + * `macros.js` exports this same dictionary again and makes it public. + * `Parser.js` requires this dictionary via `macros.js`. + */ +var _macros = {}; // This function might one day accept an additional argument and do more things. + +function defineMacro(name, body) { + _macros[name] = body; +} + +// Helper functions +function getHLines(parser) { + // Return an array. The array length = number of hlines. + // Each element in the array tells if the line is dashed. + var hlineInfo = []; + parser.consumeSpaces(); + var nxt = parser.fetch().text; + + if (nxt === "\\relax") { + // \relax is an artifact of the \cr macro below + parser.consume(); + parser.consumeSpaces(); + nxt = parser.fetch().text; + } + + while (nxt === "\\hline" || nxt === "\\hdashline") { + parser.consume(); + hlineInfo.push(nxt === "\\hdashline"); + parser.consumeSpaces(); + nxt = parser.fetch().text; + } + + return hlineInfo; +} + +var validateAmsEnvironmentContext = context => { + var settings = context.parser.settings; + + if (!settings.displayMode) { + throw new ParseError("{" + context.envName + "} can be used only in" + " display mode."); + } +}; // autoTag (an argument to parseArray) can be one of three values: +// * undefined: Regular (not-top-level) array; no tags on each row +// * true: Automatic equation numbering, overridable by \tag +// * false: Tags allowed on each row, but no automatic numbering +// This function *doesn't* work with the "split" environment name. + + +function getAutoTag(name) { + if (name.indexOf("ed") === -1) { + return name.indexOf("*") === -1; + } // return undefined; + +} +/** + * Parse the body of the environment, with rows delimited by \\ and + * columns delimited by &, and create a nested list in row-major order + * with one group per cell. If given an optional argument style + * ("text", "display", etc.), then each cell is cast into that style. + */ + + +function parseArray(parser, _ref, style) { + var { + hskipBeforeAndAfter, + addJot, + cols, + arraystretch, + colSeparationType, + autoTag, + singleRow, + emptySingleRow, + maxNumCols, + leqno + } = _ref; + parser.gullet.beginGroup(); + + if (!singleRow) { + // \cr is equivalent to \\ without the optional size argument (see below) + // TODO: provide helpful error when \cr is used outside array environment + parser.gullet.macros.set("\\cr", "\\\\\\relax"); + } // Get current arraystretch if it's not set by the environment + + + if (!arraystretch) { + var stretch = parser.gullet.expandMacroAsText("\\arraystretch"); + + if (stretch == null) { + // Default \arraystretch from lttab.dtx + arraystretch = 1; + } else { + arraystretch = parseFloat(stretch); + + if (!arraystretch || arraystretch < 0) { + throw new ParseError("Invalid \\arraystretch: " + stretch); + } + } + } // Start group for first cell + + + parser.gullet.beginGroup(); + var row = []; + var body = [row]; + var rowGaps = []; + var hLinesBeforeRow = []; + var tags = autoTag != null ? [] : undefined; // amsmath uses \global\@eqnswtrue and \global\@eqnswfalse to represent + // whether this row should have an equation number. Simulate this with + // a \@eqnsw macro set to 1 or 0. + + function beginRow() { + if (autoTag) { + parser.gullet.macros.set("\\@eqnsw", "1", true); + } + } + + function endRow() { + if (tags) { + if (parser.gullet.macros.get("\\df@tag")) { + tags.push(parser.subparse([new Token("\\df@tag")])); + parser.gullet.macros.set("\\df@tag", undefined, true); + } else { + tags.push(Boolean(autoTag) && parser.gullet.macros.get("\\@eqnsw") === "1"); + } + } + } + + beginRow(); // Test for \hline at the top of the array. + + hLinesBeforeRow.push(getHLines(parser)); + + while (true) { + // eslint-disable-line no-constant-condition + // Parse each cell in its own group (namespace) + var cell = parser.parseExpression(false, singleRow ? "\\end" : "\\\\"); + parser.gullet.endGroup(); + parser.gullet.beginGroup(); + cell = { + type: "ordgroup", + mode: parser.mode, + body: cell + }; + + if (style) { + cell = { + type: "styling", + mode: parser.mode, + style, + body: [cell] + }; + } + + row.push(cell); + var next = parser.fetch().text; + + if (next === "&") { + if (maxNumCols && row.length === maxNumCols) { + if (singleRow || colSeparationType) { + // {equation} or {split} + throw new ParseError("Too many tab characters: &", parser.nextToken); + } else { + // {array} environment + parser.settings.reportNonstrict("textEnv", "Too few columns " + "specified in the {array} column argument."); + } + } + + parser.consume(); + } else if (next === "\\end") { + endRow(); // Arrays terminate newlines with `\crcr` which consumes a `\cr` if + // the last line is empty. However, AMS environments keep the + // empty row if it's the only one. + // NOTE: Currently, `cell` is the last item added into `row`. + + if (row.length === 1 && cell.type === "styling" && cell.body[0].body.length === 0 && (body.length > 1 || !emptySingleRow)) { + body.pop(); + } + + if (hLinesBeforeRow.length < body.length + 1) { + hLinesBeforeRow.push([]); + } + + break; + } else if (next === "\\\\") { + parser.consume(); + var size = void 0; // \def\Let@{\let\\\math@cr} + // \def\math@cr{...\math@cr@} + // \def\math@cr@{\new@ifnextchar[\math@cr@@{\math@cr@@[\z@]}} + // \def\math@cr@@[#1]{...\math@cr@@@...} + // \def\math@cr@@@{\cr} + + if (parser.gullet.future().text !== " ") { + size = parser.parseSizeGroup(true); + } + + rowGaps.push(size ? size.value : null); + endRow(); // check for \hline(s) following the row separator + + hLinesBeforeRow.push(getHLines(parser)); + row = []; + body.push(row); + beginRow(); + } else { + throw new ParseError("Expected & or \\\\ or \\cr or \\end", parser.nextToken); + } + } // End cell group + + + parser.gullet.endGroup(); // End array group defining \cr + + parser.gullet.endGroup(); + return { + type: "array", + mode: parser.mode, + addJot, + arraystretch, + body, + cols, + rowGaps, + hskipBeforeAndAfter, + hLinesBeforeRow, + colSeparationType, + tags, + leqno + }; +} // Decides on a style for cells in an array according to whether the given +// environment name starts with the letter 'd'. + + +function dCellStyle(envName) { + if (envName.slice(0, 1) === "d") { + return "display"; + } else { + return "text"; + } +} + +var htmlBuilder$6 = function htmlBuilder(group, options) { + var r; + var c; + var nr = group.body.length; + var hLinesBeforeRow = group.hLinesBeforeRow; + var nc = 0; + var body = new Array(nr); + var hlines = []; + var ruleThickness = Math.max( // From LaTeX \showthe\arrayrulewidth. Equals 0.04 em. + options.fontMetrics().arrayRuleWidth, options.minRuleThickness // User override. + ); // Horizontal spacing + + var pt = 1 / options.fontMetrics().ptPerEm; + var arraycolsep = 5 * pt; // default value, i.e. \arraycolsep in article.cls + + if (group.colSeparationType && group.colSeparationType === "small") { + // We're in a {smallmatrix}. Default column space is \thickspace, + // i.e. 5/18em = 0.2778em, per amsmath.dtx for {smallmatrix}. + // But that needs adjustment because LaTeX applies \scriptstyle to the + // entire array, including the colspace, but this function applies + // \scriptstyle only inside each element. + var localMultiplier = options.havingStyle(Style$1.SCRIPT).sizeMultiplier; + arraycolsep = 0.2778 * (localMultiplier / options.sizeMultiplier); + } // Vertical spacing + + + var baselineskip = group.colSeparationType === "CD" ? calculateSize({ + number: 3, + unit: "ex" + }, options) : 12 * pt; // see size10.clo + // Default \jot from ltmath.dtx + // TODO(edemaine): allow overriding \jot via \setlength (#687) + + var jot = 3 * pt; + var arrayskip = group.arraystretch * baselineskip; + var arstrutHeight = 0.7 * arrayskip; // \strutbox in ltfsstrc.dtx and + + var arstrutDepth = 0.3 * arrayskip; // \@arstrutbox in lttab.dtx + + var totalHeight = 0; // Set a position for \hline(s) at the top of the array, if any. + + function setHLinePos(hlinesInGap) { + for (var i = 0; i < hlinesInGap.length; ++i) { + if (i > 0) { + totalHeight += 0.25; + } + + hlines.push({ + pos: totalHeight, + isDashed: hlinesInGap[i] + }); + } + } + + setHLinePos(hLinesBeforeRow[0]); + + for (r = 0; r < group.body.length; ++r) { + var inrow = group.body[r]; + var height = arstrutHeight; // \@array adds an \@arstrut + + var depth = arstrutDepth; // to each tow (via the template) + + if (nc < inrow.length) { + nc = inrow.length; + } + + var outrow = new Array(inrow.length); + + for (c = 0; c < inrow.length; ++c) { + var elt = buildGroup$1(inrow[c], options); + + if (depth < elt.depth) { + depth = elt.depth; + } + + if (height < elt.height) { + height = elt.height; + } + + outrow[c] = elt; + } + + var rowGap = group.rowGaps[r]; + var gap = 0; + + if (rowGap) { + gap = calculateSize(rowGap, options); + + if (gap > 0) { + // \@argarraycr + gap += arstrutDepth; + + if (depth < gap) { + depth = gap; // \@xargarraycr + } + + gap = 0; + } + } // In AMS multiline environments such as aligned and gathered, rows + // correspond to lines that have additional \jot added to the + // \baselineskip via \openup. + + + if (group.addJot) { + depth += jot; + } + + outrow.height = height; + outrow.depth = depth; + totalHeight += height; + outrow.pos = totalHeight; + totalHeight += depth + gap; // \@yargarraycr + + body[r] = outrow; // Set a position for \hline(s), if any. + + setHLinePos(hLinesBeforeRow[r + 1]); + } + + var offset = totalHeight / 2 + options.fontMetrics().axisHeight; + var colDescriptions = group.cols || []; + var cols = []; + var colSep; + var colDescrNum; + var tagSpans = []; + + if (group.tags && group.tags.some(tag => tag)) { + // An environment with manual tags and/or automatic equation numbers. + // Create node(s), the latter of which trigger CSS counter increment. + for (r = 0; r < nr; ++r) { + var rw = body[r]; + var shift = rw.pos - offset; + var tag = group.tags[r]; + var tagSpan = void 0; + + if (tag === true) { + // automatic numbering + tagSpan = buildCommon.makeSpan(["eqn-num"], [], options); + } else if (tag === false) { + // \nonumber/\notag or starred environment + tagSpan = buildCommon.makeSpan([], [], options); + } else { + // manual \tag + tagSpan = buildCommon.makeSpan([], buildExpression$1(tag, options, true), options); + } + + tagSpan.depth = rw.depth; + tagSpan.height = rw.height; + tagSpans.push({ + type: "elem", + elem: tagSpan, + shift + }); + } + } + + for (c = 0, colDescrNum = 0; // Continue while either there are more columns or more column + // descriptions, so trailing separators don't get lost. + c < nc || colDescrNum < colDescriptions.length; ++c, ++colDescrNum) { + var colDescr = colDescriptions[colDescrNum] || {}; + var firstSeparator = true; + + while (colDescr.type === "separator") { + // If there is more than one separator in a row, add a space + // between them. + if (!firstSeparator) { + colSep = buildCommon.makeSpan(["arraycolsep"], []); + colSep.style.width = makeEm(options.fontMetrics().doubleRuleSep); + cols.push(colSep); + } + + if (colDescr.separator === "|" || colDescr.separator === ":") { + var lineType = colDescr.separator === "|" ? "solid" : "dashed"; + var separator = buildCommon.makeSpan(["vertical-separator"], [], options); + separator.style.height = makeEm(totalHeight); + separator.style.borderRightWidth = makeEm(ruleThickness); + separator.style.borderRightStyle = lineType; + separator.style.margin = "0 " + makeEm(-ruleThickness / 2); + + var _shift = totalHeight - offset; + + if (_shift) { + separator.style.verticalAlign = makeEm(-_shift); + } + + cols.push(separator); + } else { + throw new ParseError("Invalid separator type: " + colDescr.separator); + } + + colDescrNum++; + colDescr = colDescriptions[colDescrNum] || {}; + firstSeparator = false; + } + + if (c >= nc) { + continue; + } + + var sepwidth = void 0; + + if (c > 0 || group.hskipBeforeAndAfter) { + sepwidth = utils.deflt(colDescr.pregap, arraycolsep); + + if (sepwidth !== 0) { + colSep = buildCommon.makeSpan(["arraycolsep"], []); + colSep.style.width = makeEm(sepwidth); + cols.push(colSep); + } + } + + var col = []; + + for (r = 0; r < nr; ++r) { + var row = body[r]; + var elem = row[c]; + + if (!elem) { + continue; + } + + var _shift2 = row.pos - offset; + + elem.depth = row.depth; + elem.height = row.height; + col.push({ + type: "elem", + elem: elem, + shift: _shift2 + }); + } + + col = buildCommon.makeVList({ + positionType: "individualShift", + children: col + }, options); + col = buildCommon.makeSpan(["col-align-" + (colDescr.align || "c")], [col]); + cols.push(col); + + if (c < nc - 1 || group.hskipBeforeAndAfter) { + sepwidth = utils.deflt(colDescr.postgap, arraycolsep); + + if (sepwidth !== 0) { + colSep = buildCommon.makeSpan(["arraycolsep"], []); + colSep.style.width = makeEm(sepwidth); + cols.push(colSep); + } + } + } + + body = buildCommon.makeSpan(["mtable"], cols); // Add \hline(s), if any. + + if (hlines.length > 0) { + var line = buildCommon.makeLineSpan("hline", options, ruleThickness); + var dashes = buildCommon.makeLineSpan("hdashline", options, ruleThickness); + var vListElems = [{ + type: "elem", + elem: body, + shift: 0 + }]; + + while (hlines.length > 0) { + var hline = hlines.pop(); + var lineShift = hline.pos - offset; + + if (hline.isDashed) { + vListElems.push({ + type: "elem", + elem: dashes, + shift: lineShift + }); + } else { + vListElems.push({ + type: "elem", + elem: line, + shift: lineShift + }); + } + } + + body = buildCommon.makeVList({ + positionType: "individualShift", + children: vListElems + }, options); + } + + if (tagSpans.length === 0) { + return buildCommon.makeSpan(["mord"], [body], options); + } else { + var eqnNumCol = buildCommon.makeVList({ + positionType: "individualShift", + children: tagSpans + }, options); + eqnNumCol = buildCommon.makeSpan(["tag"], [eqnNumCol], options); + return buildCommon.makeFragment([body, eqnNumCol]); + } +}; + +var alignMap = { + c: "center ", + l: "left ", + r: "right " +}; + +var mathmlBuilder$5 = function mathmlBuilder(group, options) { + var tbl = []; + var glue = new mathMLTree.MathNode("mtd", [], ["mtr-glue"]); + var tag = new mathMLTree.MathNode("mtd", [], ["mml-eqn-num"]); + + for (var i = 0; i < group.body.length; i++) { + var rw = group.body[i]; + var row = []; + + for (var j = 0; j < rw.length; j++) { + row.push(new mathMLTree.MathNode("mtd", [buildGroup(rw[j], options)])); + } + + if (group.tags && group.tags[i]) { + row.unshift(glue); + row.push(glue); + + if (group.leqno) { + row.unshift(tag); + } else { + row.push(tag); + } + } + + tbl.push(new mathMLTree.MathNode("mtr", row)); + } + + var table = new mathMLTree.MathNode("mtable", tbl); // Set column alignment, row spacing, column spacing, and + // array lines by setting attributes on the table element. + // Set the row spacing. In MathML, we specify a gap distance. + // We do not use rowGap[] because MathML automatically increases + // cell height with the height/depth of the element content. + // LaTeX \arraystretch multiplies the row baseline-to-baseline distance. + // We simulate this by adding (arraystretch - 1)em to the gap. This + // does a reasonable job of adjusting arrays containing 1 em tall content. + // The 0.16 and 0.09 values are found empirically. They produce an array + // similar to LaTeX and in which content does not interfere with \hlines. + + var gap = group.arraystretch === 0.5 ? 0.1 // {smallmatrix}, {subarray} + : 0.16 + group.arraystretch - 1 + (group.addJot ? 0.09 : 0); + table.setAttribute("rowspacing", makeEm(gap)); // MathML table lines go only between cells. + // To place a line on an edge we'll use , if necessary. + + var menclose = ""; + var align = ""; + + if (group.cols && group.cols.length > 0) { + // Find column alignment, column spacing, and vertical lines. + var cols = group.cols; + var columnLines = ""; + var prevTypeWasAlign = false; + var iStart = 0; + var iEnd = cols.length; + + if (cols[0].type === "separator") { + menclose += "top "; + iStart = 1; + } + + if (cols[cols.length - 1].type === "separator") { + menclose += "bottom "; + iEnd -= 1; + } + + for (var _i = iStart; _i < iEnd; _i++) { + if (cols[_i].type === "align") { + align += alignMap[cols[_i].align]; + + if (prevTypeWasAlign) { + columnLines += "none "; + } + + prevTypeWasAlign = true; + } else if (cols[_i].type === "separator") { + // MathML accepts only single lines between cells. + // So we read only the first of consecutive separators. + if (prevTypeWasAlign) { + columnLines += cols[_i].separator === "|" ? "solid " : "dashed "; + prevTypeWasAlign = false; + } + } + } + + table.setAttribute("columnalign", align.trim()); + + if (/[sd]/.test(columnLines)) { + table.setAttribute("columnlines", columnLines.trim()); + } + } // Set column spacing. + + + if (group.colSeparationType === "align") { + var _cols = group.cols || []; + + var spacing = ""; + + for (var _i2 = 1; _i2 < _cols.length; _i2++) { + spacing += _i2 % 2 ? "0em " : "1em "; + } + + table.setAttribute("columnspacing", spacing.trim()); + } else if (group.colSeparationType === "alignat" || group.colSeparationType === "gather") { + table.setAttribute("columnspacing", "0em"); + } else if (group.colSeparationType === "small") { + table.setAttribute("columnspacing", "0.2778em"); + } else if (group.colSeparationType === "CD") { + table.setAttribute("columnspacing", "0.5em"); + } else { + table.setAttribute("columnspacing", "1em"); + } // Address \hline and \hdashline + + + var rowLines = ""; + var hlines = group.hLinesBeforeRow; + menclose += hlines[0].length > 0 ? "left " : ""; + menclose += hlines[hlines.length - 1].length > 0 ? "right " : ""; + + for (var _i3 = 1; _i3 < hlines.length - 1; _i3++) { + rowLines += hlines[_i3].length === 0 ? "none " // MathML accepts only a single line between rows. Read one element. + : hlines[_i3][0] ? "dashed " : "solid "; + } + + if (/[sd]/.test(rowLines)) { + table.setAttribute("rowlines", rowLines.trim()); + } + + if (menclose !== "") { + table = new mathMLTree.MathNode("menclose", [table]); + table.setAttribute("notation", menclose.trim()); + } + + if (group.arraystretch && group.arraystretch < 1) { + // A small array. Wrap in scriptstyle so row gap is not too large. + table = new mathMLTree.MathNode("mstyle", [table]); + table.setAttribute("scriptlevel", "1"); + } + + return table; +}; // Convenience function for align, align*, aligned, alignat, alignat*, alignedat. + + +var alignedHandler = function alignedHandler(context, args) { + if (context.envName.indexOf("ed") === -1) { + validateAmsEnvironmentContext(context); + } + + var cols = []; + var separationType = context.envName.indexOf("at") > -1 ? "alignat" : "align"; + var isSplit = context.envName === "split"; + var res = parseArray(context.parser, { + cols, + addJot: true, + autoTag: isSplit ? undefined : getAutoTag(context.envName), + emptySingleRow: true, + colSeparationType: separationType, + maxNumCols: isSplit ? 2 : undefined, + leqno: context.parser.settings.leqno + }, "display"); // Determining number of columns. + // 1. If the first argument is given, we use it as a number of columns, + // and makes sure that each row doesn't exceed that number. + // 2. Otherwise, just count number of columns = maximum number + // of cells in each row ("aligned" mode -- isAligned will be true). + // + // At the same time, prepend empty group {} at beginning of every second + // cell in each row (starting with second cell) so that operators become + // binary. This behavior is implemented in amsmath's \start@aligned. + + var numMaths; + var numCols = 0; + var emptyGroup = { + type: "ordgroup", + mode: context.mode, + body: [] + }; + + if (args[0] && args[0].type === "ordgroup") { + var arg0 = ""; + + for (var i = 0; i < args[0].body.length; i++) { + var textord = assertNodeType(args[0].body[i], "textord"); + arg0 += textord.text; + } + + numMaths = Number(arg0); + numCols = numMaths * 2; + } + + var isAligned = !numCols; + res.body.forEach(function (row) { + for (var _i4 = 1; _i4 < row.length; _i4 += 2) { + // Modify ordgroup node within styling node + var styling = assertNodeType(row[_i4], "styling"); + var ordgroup = assertNodeType(styling.body[0], "ordgroup"); + ordgroup.body.unshift(emptyGroup); + } + + if (!isAligned) { + // Case 1 + var curMaths = row.length / 2; + + if (numMaths < curMaths) { + throw new ParseError("Too many math in a row: " + ("expected " + numMaths + ", but got " + curMaths), row[0]); + } + } else if (numCols < row.length) { + // Case 2 + numCols = row.length; + } + }); // Adjusting alignment. + // In aligned mode, we add one \qquad between columns; + // otherwise we add nothing. + + for (var _i5 = 0; _i5 < numCols; ++_i5) { + var align = "r"; + var pregap = 0; + + if (_i5 % 2 === 1) { + align = "l"; + } else if (_i5 > 0 && isAligned) { + // "aligned" mode. + pregap = 1; // add one \quad + } + + cols[_i5] = { + type: "align", + align: align, + pregap: pregap, + postgap: 0 + }; + } + + res.colSeparationType = isAligned ? "align" : "alignat"; + return res; +}; // Arrays are part of LaTeX, defined in lttab.dtx so its documentation +// is part of the source2e.pdf file of LaTeX2e source documentation. +// {darray} is an {array} environment where cells are set in \displaystyle, +// as defined in nccmath.sty. + + +defineEnvironment({ + type: "array", + names: ["array", "darray"], + props: { + numArgs: 1 + }, + + handler(context, args) { + // Since no types are specified above, the two possibilities are + // - The argument is wrapped in {} or [], in which case Parser's + // parseGroup() returns an "ordgroup" wrapping some symbol node. + // - The argument is a bare symbol node. + var symNode = checkSymbolNodeType(args[0]); + var colalign = symNode ? [args[0]] : assertNodeType(args[0], "ordgroup").body; + var cols = colalign.map(function (nde) { + var node = assertSymbolNodeType(nde); + var ca = node.text; + + if ("lcr".indexOf(ca) !== -1) { + return { + type: "align", + align: ca + }; + } else if (ca === "|") { + return { + type: "separator", + separator: "|" + }; + } else if (ca === ":") { + return { + type: "separator", + separator: ":" + }; + } + + throw new ParseError("Unknown column alignment: " + ca, nde); + }); + var res = { + cols, + hskipBeforeAndAfter: true, + // \@preamble in lttab.dtx + maxNumCols: cols.length + }; + return parseArray(context.parser, res, dCellStyle(context.envName)); + }, + + htmlBuilder: htmlBuilder$6, + mathmlBuilder: mathmlBuilder$5 +}); // The matrix environments of amsmath builds on the array environment +// of LaTeX, which is discussed above. +// The mathtools package adds starred versions of the same environments. +// These have an optional argument to choose left|center|right justification. + +defineEnvironment({ + type: "array", + names: ["matrix", "pmatrix", "bmatrix", "Bmatrix", "vmatrix", "Vmatrix", "matrix*", "pmatrix*", "bmatrix*", "Bmatrix*", "vmatrix*", "Vmatrix*"], + props: { + numArgs: 0 + }, + + handler(context) { + var delimiters = { + "matrix": null, + "pmatrix": ["(", ")"], + "bmatrix": ["[", "]"], + "Bmatrix": ["\\{", "\\}"], + "vmatrix": ["|", "|"], + "Vmatrix": ["\\Vert", "\\Vert"] + }[context.envName.replace("*", "")]; // \hskip -\arraycolsep in amsmath + + var colAlign = "c"; + var payload = { + hskipBeforeAndAfter: false, + cols: [{ + type: "align", + align: colAlign + }] + }; + + if (context.envName.charAt(context.envName.length - 1) === "*") { + // It's one of the mathtools starred functions. + // Parse the optional alignment argument. + var parser = context.parser; + parser.consumeSpaces(); + + if (parser.fetch().text === "[") { + parser.consume(); + parser.consumeSpaces(); + colAlign = parser.fetch().text; + + if ("lcr".indexOf(colAlign) === -1) { + throw new ParseError("Expected l or c or r", parser.nextToken); + } + + parser.consume(); + parser.consumeSpaces(); + parser.expect("]"); + parser.consume(); + payload.cols = [{ + type: "align", + align: colAlign + }]; + } + } + + var res = parseArray(context.parser, payload, dCellStyle(context.envName)); // Populate cols with the correct number of column alignment specs. + + var numCols = Math.max(0, ...res.body.map(row => row.length)); + res.cols = new Array(numCols).fill({ + type: "align", + align: colAlign + }); + return delimiters ? { + type: "leftright", + mode: context.mode, + body: [res], + left: delimiters[0], + right: delimiters[1], + rightColor: undefined // \right uninfluenced by \color in array + + } : res; + }, + + htmlBuilder: htmlBuilder$6, + mathmlBuilder: mathmlBuilder$5 +}); +defineEnvironment({ + type: "array", + names: ["smallmatrix"], + props: { + numArgs: 0 + }, + + handler(context) { + var payload = { + arraystretch: 0.5 + }; + var res = parseArray(context.parser, payload, "script"); + res.colSeparationType = "small"; + return res; + }, + + htmlBuilder: htmlBuilder$6, + mathmlBuilder: mathmlBuilder$5 +}); +defineEnvironment({ + type: "array", + names: ["subarray"], + props: { + numArgs: 1 + }, + + handler(context, args) { + // Parsing of {subarray} is similar to {array} + var symNode = checkSymbolNodeType(args[0]); + var colalign = symNode ? [args[0]] : assertNodeType(args[0], "ordgroup").body; + var cols = colalign.map(function (nde) { + var node = assertSymbolNodeType(nde); + var ca = node.text; // {subarray} only recognizes "l" & "c" + + if ("lc".indexOf(ca) !== -1) { + return { + type: "align", + align: ca + }; + } + + throw new ParseError("Unknown column alignment: " + ca, nde); + }); + + if (cols.length > 1) { + throw new ParseError("{subarray} can contain only one column"); + } + + var res = { + cols, + hskipBeforeAndAfter: false, + arraystretch: 0.5 + }; + res = parseArray(context.parser, res, "script"); + + if (res.body.length > 0 && res.body[0].length > 1) { + throw new ParseError("{subarray} can contain only one column"); + } + + return res; + }, + + htmlBuilder: htmlBuilder$6, + mathmlBuilder: mathmlBuilder$5 +}); // A cases environment (in amsmath.sty) is almost equivalent to +// \def\arraystretch{1.2}% +// \left\{\begin{array}{@{}l@{\quad}l@{}} … \end{array}\right. +// {dcases} is a {cases} environment where cells are set in \displaystyle, +// as defined in mathtools.sty. +// {rcases} is another mathtools environment. It's brace is on the right side. + +defineEnvironment({ + type: "array", + names: ["cases", "dcases", "rcases", "drcases"], + props: { + numArgs: 0 + }, + + handler(context) { + var payload = { + arraystretch: 1.2, + cols: [{ + type: "align", + align: "l", + pregap: 0, + // TODO(kevinb) get the current style. + // For now we use the metrics for TEXT style which is what we were + // doing before. Before attempting to get the current style we + // should look at TeX's behavior especially for \over and matrices. + postgap: 1.0 + /* 1em quad */ + + }, { + type: "align", + align: "l", + pregap: 0, + postgap: 0 + }] + }; + var res = parseArray(context.parser, payload, dCellStyle(context.envName)); + return { + type: "leftright", + mode: context.mode, + body: [res], + left: context.envName.indexOf("r") > -1 ? "." : "\\{", + right: context.envName.indexOf("r") > -1 ? "\\}" : ".", + rightColor: undefined + }; + }, + + htmlBuilder: htmlBuilder$6, + mathmlBuilder: mathmlBuilder$5 +}); // In the align environment, one uses ampersands, &, to specify number of +// columns in each row, and to locate spacing between each column. +// align gets automatic numbering. align* and aligned do not. +// The alignedat environment can be used in math mode. +// Note that we assume \nomallineskiplimit to be zero, +// so that \strut@ is the same as \strut. + +defineEnvironment({ + type: "array", + names: ["align", "align*", "aligned", "split"], + props: { + numArgs: 0 + }, + handler: alignedHandler, + htmlBuilder: htmlBuilder$6, + mathmlBuilder: mathmlBuilder$5 +}); // A gathered environment is like an array environment with one centered +// column, but where rows are considered lines so get \jot line spacing +// and contents are set in \displaystyle. + +defineEnvironment({ + type: "array", + names: ["gathered", "gather", "gather*"], + props: { + numArgs: 0 + }, + + handler(context) { + if (utils.contains(["gather", "gather*"], context.envName)) { + validateAmsEnvironmentContext(context); + } + + var res = { + cols: [{ + type: "align", + align: "c" + }], + addJot: true, + colSeparationType: "gather", + autoTag: getAutoTag(context.envName), + emptySingleRow: true, + leqno: context.parser.settings.leqno + }; + return parseArray(context.parser, res, "display"); + }, + + htmlBuilder: htmlBuilder$6, + mathmlBuilder: mathmlBuilder$5 +}); // alignat environment is like an align environment, but one must explicitly +// specify maximum number of columns in each row, and can adjust spacing between +// each columns. + +defineEnvironment({ + type: "array", + names: ["alignat", "alignat*", "alignedat"], + props: { + numArgs: 1 + }, + handler: alignedHandler, + htmlBuilder: htmlBuilder$6, + mathmlBuilder: mathmlBuilder$5 +}); +defineEnvironment({ + type: "array", + names: ["equation", "equation*"], + props: { + numArgs: 0 + }, + + handler(context) { + validateAmsEnvironmentContext(context); + var res = { + autoTag: getAutoTag(context.envName), + emptySingleRow: true, + singleRow: true, + maxNumCols: 1, + leqno: context.parser.settings.leqno + }; + return parseArray(context.parser, res, "display"); + }, + + htmlBuilder: htmlBuilder$6, + mathmlBuilder: mathmlBuilder$5 +}); +defineEnvironment({ + type: "array", + names: ["CD"], + props: { + numArgs: 0 + }, + + handler(context) { + validateAmsEnvironmentContext(context); + return parseCD(context.parser); + }, + + htmlBuilder: htmlBuilder$6, + mathmlBuilder: mathmlBuilder$5 +}); +defineMacro("\\nonumber", "\\gdef\\@eqnsw{0}"); +defineMacro("\\notag", "\\nonumber"); // Catch \hline outside array environment + +defineFunction({ + type: "text", + // Doesn't matter what this is. + names: ["\\hline", "\\hdashline"], + props: { + numArgs: 0, + allowedInText: true, + allowedInMath: true + }, + + handler(context, args) { + throw new ParseError(context.funcName + " valid only within array environment"); + } + +}); + +var environments = _environments; + +// defineEnvironment definitions. + +defineFunction({ + type: "environment", + names: ["\\begin", "\\end"], + props: { + numArgs: 1, + argTypes: ["text"] + }, + + handler(_ref, args) { + var { + parser, + funcName + } = _ref; + var nameGroup = args[0]; + + if (nameGroup.type !== "ordgroup") { + throw new ParseError("Invalid environment name", nameGroup); + } + + var envName = ""; + + for (var i = 0; i < nameGroup.body.length; ++i) { + envName += assertNodeType(nameGroup.body[i], "textord").text; + } + + if (funcName === "\\begin") { + // begin...end is similar to left...right + if (!environments.hasOwnProperty(envName)) { + throw new ParseError("No such environment: " + envName, nameGroup); + } // Build the environment object. Arguments and other information will + // be made available to the begin and end methods using properties. + + + var env = environments[envName]; + var { + args: _args, + optArgs + } = parser.parseArguments("\\begin{" + envName + "}", env); + var context = { + mode: parser.mode, + envName, + parser + }; + var result = env.handler(context, _args, optArgs); + parser.expect("\\end", false); + var endNameToken = parser.nextToken; + var end = assertNodeType(parser.parseFunction(), "environment"); + + if (end.name !== envName) { + throw new ParseError("Mismatch: \\begin{" + envName + "} matched by \\end{" + end.name + "}", endNameToken); + } // $FlowFixMe, "environment" handler returns an environment ParseNode + + + return result; + } + + return { + type: "environment", + mode: parser.mode, + name: envName, + nameGroup + }; + } + +}); + +// TODO(kevinb): implement \\sl and \\sc + +var htmlBuilder$5 = (group, options) => { + var font = group.font; + var newOptions = options.withFont(font); + return buildGroup$1(group.body, newOptions); +}; + +var mathmlBuilder$4 = (group, options) => { + var font = group.font; + var newOptions = options.withFont(font); + return buildGroup(group.body, newOptions); +}; + +var fontAliases = { + "\\Bbb": "\\mathbb", + "\\bold": "\\mathbf", + "\\frak": "\\mathfrak", + "\\bm": "\\boldsymbol" +}; +defineFunction({ + type: "font", + names: [// styles, except \boldsymbol defined below + "\\mathrm", "\\mathit", "\\mathbf", "\\mathnormal", // families + "\\mathbb", "\\mathcal", "\\mathfrak", "\\mathscr", "\\mathsf", "\\mathtt", // aliases, except \bm defined below + "\\Bbb", "\\bold", "\\frak"], + props: { + numArgs: 1, + allowedInArgument: true + }, + handler: (_ref, args) => { + var { + parser, + funcName + } = _ref; + var body = normalizeArgument(args[0]); + var func = funcName; + + if (func in fontAliases) { + func = fontAliases[func]; + } + + return { + type: "font", + mode: parser.mode, + font: func.slice(1), + body + }; + }, + htmlBuilder: htmlBuilder$5, + mathmlBuilder: mathmlBuilder$4 +}); +defineFunction({ + type: "mclass", + names: ["\\boldsymbol", "\\bm"], + props: { + numArgs: 1 + }, + handler: (_ref2, args) => { + var { + parser + } = _ref2; + var body = args[0]; + var isCharacterBox = utils.isCharacterBox(body); // amsbsy.sty's \boldsymbol uses \binrel spacing to inherit the + // argument's bin|rel|ord status + + return { + type: "mclass", + mode: parser.mode, + mclass: binrelClass(body), + body: [{ + type: "font", + mode: parser.mode, + font: "boldsymbol", + body + }], + isCharacterBox: isCharacterBox + }; + } +}); // Old font changing functions + +defineFunction({ + type: "font", + names: ["\\rm", "\\sf", "\\tt", "\\bf", "\\it", "\\cal"], + props: { + numArgs: 0, + allowedInText: true + }, + handler: (_ref3, args) => { + var { + parser, + funcName, + breakOnTokenText + } = _ref3; + var { + mode + } = parser; + var body = parser.parseExpression(true, breakOnTokenText); + var style = "math" + funcName.slice(1); + return { + type: "font", + mode: mode, + font: style, + body: { + type: "ordgroup", + mode: parser.mode, + body + } + }; + }, + htmlBuilder: htmlBuilder$5, + mathmlBuilder: mathmlBuilder$4 +}); + +var adjustStyle = (size, originalStyle) => { + // Figure out what style this fraction should be in based on the + // function used + var style = originalStyle; + + if (size === "display") { + // Get display style as a default. + // If incoming style is sub/sup, use style.text() to get correct size. + style = style.id >= Style$1.SCRIPT.id ? style.text() : Style$1.DISPLAY; + } else if (size === "text" && style.size === Style$1.DISPLAY.size) { + // We're in a \tfrac but incoming style is displaystyle, so: + style = Style$1.TEXT; + } else if (size === "script") { + style = Style$1.SCRIPT; + } else if (size === "scriptscript") { + style = Style$1.SCRIPTSCRIPT; + } + + return style; +}; + +var htmlBuilder$4 = (group, options) => { + // Fractions are handled in the TeXbook on pages 444-445, rules 15(a-e). + var style = adjustStyle(group.size, options.style); + var nstyle = style.fracNum(); + var dstyle = style.fracDen(); + var newOptions; + newOptions = options.havingStyle(nstyle); + var numerm = buildGroup$1(group.numer, newOptions, options); + + if (group.continued) { + // \cfrac inserts a \strut into the numerator. + // Get \strut dimensions from TeXbook page 353. + var hStrut = 8.5 / options.fontMetrics().ptPerEm; + var dStrut = 3.5 / options.fontMetrics().ptPerEm; + numerm.height = numerm.height < hStrut ? hStrut : numerm.height; + numerm.depth = numerm.depth < dStrut ? dStrut : numerm.depth; + } + + newOptions = options.havingStyle(dstyle); + var denomm = buildGroup$1(group.denom, newOptions, options); + var rule; + var ruleWidth; + var ruleSpacing; + + if (group.hasBarLine) { + if (group.barSize) { + ruleWidth = calculateSize(group.barSize, options); + rule = buildCommon.makeLineSpan("frac-line", options, ruleWidth); + } else { + rule = buildCommon.makeLineSpan("frac-line", options); + } + + ruleWidth = rule.height; + ruleSpacing = rule.height; + } else { + rule = null; + ruleWidth = 0; + ruleSpacing = options.fontMetrics().defaultRuleThickness; + } // Rule 15b + + + var numShift; + var clearance; + var denomShift; + + if (style.size === Style$1.DISPLAY.size || group.size === "display") { + numShift = options.fontMetrics().num1; + + if (ruleWidth > 0) { + clearance = 3 * ruleSpacing; + } else { + clearance = 7 * ruleSpacing; + } + + denomShift = options.fontMetrics().denom1; + } else { + if (ruleWidth > 0) { + numShift = options.fontMetrics().num2; + clearance = ruleSpacing; + } else { + numShift = options.fontMetrics().num3; + clearance = 3 * ruleSpacing; + } + + denomShift = options.fontMetrics().denom2; + } + + var frac; + + if (!rule) { + // Rule 15c + var candidateClearance = numShift - numerm.depth - (denomm.height - denomShift); + + if (candidateClearance < clearance) { + numShift += 0.5 * (clearance - candidateClearance); + denomShift += 0.5 * (clearance - candidateClearance); + } + + frac = buildCommon.makeVList({ + positionType: "individualShift", + children: [{ + type: "elem", + elem: denomm, + shift: denomShift + }, { + type: "elem", + elem: numerm, + shift: -numShift + }] + }, options); + } else { + // Rule 15d + var axisHeight = options.fontMetrics().axisHeight; + + if (numShift - numerm.depth - (axisHeight + 0.5 * ruleWidth) < clearance) { + numShift += clearance - (numShift - numerm.depth - (axisHeight + 0.5 * ruleWidth)); + } + + if (axisHeight - 0.5 * ruleWidth - (denomm.height - denomShift) < clearance) { + denomShift += clearance - (axisHeight - 0.5 * ruleWidth - (denomm.height - denomShift)); + } + + var midShift = -(axisHeight - 0.5 * ruleWidth); + frac = buildCommon.makeVList({ + positionType: "individualShift", + children: [{ + type: "elem", + elem: denomm, + shift: denomShift + }, { + type: "elem", + elem: rule, + shift: midShift + }, { + type: "elem", + elem: numerm, + shift: -numShift + }] + }, options); + } // Since we manually change the style sometimes (with \dfrac or \tfrac), + // account for the possible size change here. + + + newOptions = options.havingStyle(style); + frac.height *= newOptions.sizeMultiplier / options.sizeMultiplier; + frac.depth *= newOptions.sizeMultiplier / options.sizeMultiplier; // Rule 15e + + var delimSize; + + if (style.size === Style$1.DISPLAY.size) { + delimSize = options.fontMetrics().delim1; + } else if (style.size === Style$1.SCRIPTSCRIPT.size) { + delimSize = options.havingStyle(Style$1.SCRIPT).fontMetrics().delim2; + } else { + delimSize = options.fontMetrics().delim2; + } + + var leftDelim; + var rightDelim; + + if (group.leftDelim == null) { + leftDelim = makeNullDelimiter(options, ["mopen"]); + } else { + leftDelim = delimiter.customSizedDelim(group.leftDelim, delimSize, true, options.havingStyle(style), group.mode, ["mopen"]); + } + + if (group.continued) { + rightDelim = buildCommon.makeSpan([]); // zero width for \cfrac + } else if (group.rightDelim == null) { + rightDelim = makeNullDelimiter(options, ["mclose"]); + } else { + rightDelim = delimiter.customSizedDelim(group.rightDelim, delimSize, true, options.havingStyle(style), group.mode, ["mclose"]); + } + + return buildCommon.makeSpan(["mord"].concat(newOptions.sizingClasses(options)), [leftDelim, buildCommon.makeSpan(["mfrac"], [frac]), rightDelim], options); +}; + +var mathmlBuilder$3 = (group, options) => { + var node = new mathMLTree.MathNode("mfrac", [buildGroup(group.numer, options), buildGroup(group.denom, options)]); + + if (!group.hasBarLine) { + node.setAttribute("linethickness", "0px"); + } else if (group.barSize) { + var ruleWidth = calculateSize(group.barSize, options); + node.setAttribute("linethickness", makeEm(ruleWidth)); + } + + var style = adjustStyle(group.size, options.style); + + if (style.size !== options.style.size) { + node = new mathMLTree.MathNode("mstyle", [node]); + var isDisplay = style.size === Style$1.DISPLAY.size ? "true" : "false"; + node.setAttribute("displaystyle", isDisplay); + node.setAttribute("scriptlevel", "0"); + } + + if (group.leftDelim != null || group.rightDelim != null) { + var withDelims = []; + + if (group.leftDelim != null) { + var leftOp = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode(group.leftDelim.replace("\\", ""))]); + leftOp.setAttribute("fence", "true"); + withDelims.push(leftOp); + } + + withDelims.push(node); + + if (group.rightDelim != null) { + var rightOp = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode(group.rightDelim.replace("\\", ""))]); + rightOp.setAttribute("fence", "true"); + withDelims.push(rightOp); + } + + return makeRow(withDelims); + } + + return node; +}; + +defineFunction({ + type: "genfrac", + names: ["\\dfrac", "\\frac", "\\tfrac", "\\dbinom", "\\binom", "\\tbinom", "\\\\atopfrac", // can’t be entered directly + "\\\\bracefrac", "\\\\brackfrac" // ditto + ], + props: { + numArgs: 2, + allowedInArgument: true + }, + handler: (_ref, args) => { + var { + parser, + funcName + } = _ref; + var numer = args[0]; + var denom = args[1]; + var hasBarLine; + var leftDelim = null; + var rightDelim = null; + var size = "auto"; + + switch (funcName) { + case "\\dfrac": + case "\\frac": + case "\\tfrac": + hasBarLine = true; + break; + + case "\\\\atopfrac": + hasBarLine = false; + break; + + case "\\dbinom": + case "\\binom": + case "\\tbinom": + hasBarLine = false; + leftDelim = "("; + rightDelim = ")"; + break; + + case "\\\\bracefrac": + hasBarLine = false; + leftDelim = "\\{"; + rightDelim = "\\}"; + break; + + case "\\\\brackfrac": + hasBarLine = false; + leftDelim = "["; + rightDelim = "]"; + break; + + default: + throw new Error("Unrecognized genfrac command"); + } + + switch (funcName) { + case "\\dfrac": + case "\\dbinom": + size = "display"; + break; + + case "\\tfrac": + case "\\tbinom": + size = "text"; + break; + } + + return { + type: "genfrac", + mode: parser.mode, + continued: false, + numer, + denom, + hasBarLine, + leftDelim, + rightDelim, + size, + barSize: null + }; + }, + htmlBuilder: htmlBuilder$4, + mathmlBuilder: mathmlBuilder$3 +}); +defineFunction({ + type: "genfrac", + names: ["\\cfrac"], + props: { + numArgs: 2 + }, + handler: (_ref2, args) => { + var { + parser, + funcName + } = _ref2; + var numer = args[0]; + var denom = args[1]; + return { + type: "genfrac", + mode: parser.mode, + continued: true, + numer, + denom, + hasBarLine: true, + leftDelim: null, + rightDelim: null, + size: "display", + barSize: null + }; + } +}); // Infix generalized fractions -- these are not rendered directly, but replaced +// immediately by one of the variants above. + +defineFunction({ + type: "infix", + names: ["\\over", "\\choose", "\\atop", "\\brace", "\\brack"], + props: { + numArgs: 0, + infix: true + }, + + handler(_ref3) { + var { + parser, + funcName, + token + } = _ref3; + var replaceWith; + + switch (funcName) { + case "\\over": + replaceWith = "\\frac"; + break; + + case "\\choose": + replaceWith = "\\binom"; + break; + + case "\\atop": + replaceWith = "\\\\atopfrac"; + break; + + case "\\brace": + replaceWith = "\\\\bracefrac"; + break; + + case "\\brack": + replaceWith = "\\\\brackfrac"; + break; + + default: + throw new Error("Unrecognized infix genfrac command"); + } + + return { + type: "infix", + mode: parser.mode, + replaceWith, + token + }; + } + +}); +var stylArray = ["display", "text", "script", "scriptscript"]; + +var delimFromValue = function delimFromValue(delimString) { + var delim = null; + + if (delimString.length > 0) { + delim = delimString; + delim = delim === "." ? null : delim; + } + + return delim; +}; + +defineFunction({ + type: "genfrac", + names: ["\\genfrac"], + props: { + numArgs: 6, + allowedInArgument: true, + argTypes: ["math", "math", "size", "text", "math", "math"] + }, + + handler(_ref4, args) { + var { + parser + } = _ref4; + var numer = args[4]; + var denom = args[5]; // Look into the parse nodes to get the desired delimiters. + + var leftNode = normalizeArgument(args[0]); + var leftDelim = leftNode.type === "atom" && leftNode.family === "open" ? delimFromValue(leftNode.text) : null; + var rightNode = normalizeArgument(args[1]); + var rightDelim = rightNode.type === "atom" && rightNode.family === "close" ? delimFromValue(rightNode.text) : null; + var barNode = assertNodeType(args[2], "size"); + var hasBarLine; + var barSize = null; + + if (barNode.isBlank) { + // \genfrac acts differently than \above. + // \genfrac treats an empty size group as a signal to use a + // standard bar size. \above would see size = 0 and omit the bar. + hasBarLine = true; + } else { + barSize = barNode.value; + hasBarLine = barSize.number > 0; + } // Find out if we want displaystyle, textstyle, etc. + + + var size = "auto"; + var styl = args[3]; + + if (styl.type === "ordgroup") { + if (styl.body.length > 0) { + var textOrd = assertNodeType(styl.body[0], "textord"); + size = stylArray[Number(textOrd.text)]; + } + } else { + styl = assertNodeType(styl, "textord"); + size = stylArray[Number(styl.text)]; + } + + return { + type: "genfrac", + mode: parser.mode, + numer, + denom, + continued: false, + hasBarLine, + barSize, + leftDelim, + rightDelim, + size + }; + }, + + htmlBuilder: htmlBuilder$4, + mathmlBuilder: mathmlBuilder$3 +}); // \above is an infix fraction that also defines a fraction bar size. + +defineFunction({ + type: "infix", + names: ["\\above"], + props: { + numArgs: 1, + argTypes: ["size"], + infix: true + }, + + handler(_ref5, args) { + var { + parser, + funcName, + token + } = _ref5; + return { + type: "infix", + mode: parser.mode, + replaceWith: "\\\\abovefrac", + size: assertNodeType(args[0], "size").value, + token + }; + } + +}); +defineFunction({ + type: "genfrac", + names: ["\\\\abovefrac"], + props: { + numArgs: 3, + argTypes: ["math", "size", "math"] + }, + handler: (_ref6, args) => { + var { + parser, + funcName + } = _ref6; + var numer = args[0]; + var barSize = assert(assertNodeType(args[1], "infix").size); + var denom = args[2]; + var hasBarLine = barSize.number > 0; + return { + type: "genfrac", + mode: parser.mode, + numer, + denom, + continued: false, + hasBarLine, + barSize, + leftDelim: null, + rightDelim: null, + size: "auto" + }; + }, + htmlBuilder: htmlBuilder$4, + mathmlBuilder: mathmlBuilder$3 +}); + +// NOTE: Unlike most `htmlBuilder`s, this one handles not only "horizBrace", but +// also "supsub" since an over/underbrace can affect super/subscripting. +var htmlBuilder$3 = (grp, options) => { + var style = options.style; // Pull out the `ParseNode<"horizBrace">` if `grp` is a "supsub" node. + + var supSubGroup; + var group; + + if (grp.type === "supsub") { + // Ref: LaTeX source2e: }}}}\limits} + // i.e. LaTeX treats the brace similar to an op and passes it + // with \limits, so we need to assign supsub style. + supSubGroup = grp.sup ? buildGroup$1(grp.sup, options.havingStyle(style.sup()), options) : buildGroup$1(grp.sub, options.havingStyle(style.sub()), options); + group = assertNodeType(grp.base, "horizBrace"); + } else { + group = assertNodeType(grp, "horizBrace"); + } // Build the base group + + + var body = buildGroup$1(group.base, options.havingBaseStyle(Style$1.DISPLAY)); // Create the stretchy element + + var braceBody = stretchy.svgSpan(group, options); // Generate the vlist, with the appropriate kerns ┏━━━━━━━━┓ + // This first vlist contains the content and the brace: equation + + var vlist; + + if (group.isOver) { + vlist = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: body + }, { + type: "kern", + size: 0.1 + }, { + type: "elem", + elem: braceBody + }] + }, options); // $FlowFixMe: Replace this with passing "svg-align" into makeVList. + + vlist.children[0].children[0].children[1].classes.push("svg-align"); + } else { + vlist = buildCommon.makeVList({ + positionType: "bottom", + positionData: body.depth + 0.1 + braceBody.height, + children: [{ + type: "elem", + elem: braceBody + }, { + type: "kern", + size: 0.1 + }, { + type: "elem", + elem: body + }] + }, options); // $FlowFixMe: Replace this with passing "svg-align" into makeVList. + + vlist.children[0].children[0].children[0].classes.push("svg-align"); + } + + if (supSubGroup) { + // To write the supsub, wrap the first vlist in another vlist: + // They can't all go in the same vlist, because the note might be + // wider than the equation. We want the equation to control the + // brace width. + // note long note long note + // ┏━━━━━━━━┓ or ┏━━━┓ not ┏━━━━━━━━━┓ + // equation eqn eqn + var vSpan = buildCommon.makeSpan(["mord", group.isOver ? "mover" : "munder"], [vlist], options); + + if (group.isOver) { + vlist = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: vSpan + }, { + type: "kern", + size: 0.2 + }, { + type: "elem", + elem: supSubGroup + }] + }, options); + } else { + vlist = buildCommon.makeVList({ + positionType: "bottom", + positionData: vSpan.depth + 0.2 + supSubGroup.height + supSubGroup.depth, + children: [{ + type: "elem", + elem: supSubGroup + }, { + type: "kern", + size: 0.2 + }, { + type: "elem", + elem: vSpan + }] + }, options); + } + } + + return buildCommon.makeSpan(["mord", group.isOver ? "mover" : "munder"], [vlist], options); +}; + +var mathmlBuilder$2 = (group, options) => { + var accentNode = stretchy.mathMLnode(group.label); + return new mathMLTree.MathNode(group.isOver ? "mover" : "munder", [buildGroup(group.base, options), accentNode]); +}; // Horizontal stretchy braces + + +defineFunction({ + type: "horizBrace", + names: ["\\overbrace", "\\underbrace"], + props: { + numArgs: 1 + }, + + handler(_ref, args) { + var { + parser, + funcName + } = _ref; + return { + type: "horizBrace", + mode: parser.mode, + label: funcName, + isOver: /^\\over/.test(funcName), + base: args[0] + }; + }, + + htmlBuilder: htmlBuilder$3, + mathmlBuilder: mathmlBuilder$2 +}); + +defineFunction({ + type: "href", + names: ["\\href"], + props: { + numArgs: 2, + argTypes: ["url", "original"], + allowedInText: true + }, + handler: (_ref, args) => { + var { + parser + } = _ref; + var body = args[1]; + var href = assertNodeType(args[0], "url").url; + + if (!parser.settings.isTrusted({ + command: "\\href", + url: href + })) { + return parser.formatUnsupportedCmd("\\href"); + } + + return { + type: "href", + mode: parser.mode, + href, + body: ordargument(body) + }; + }, + htmlBuilder: (group, options) => { + var elements = buildExpression$1(group.body, options, false); + return buildCommon.makeAnchor(group.href, [], elements, options); + }, + mathmlBuilder: (group, options) => { + var math = buildExpressionRow(group.body, options); + + if (!(math instanceof MathNode)) { + math = new MathNode("mrow", [math]); + } + + math.setAttribute("href", group.href); + return math; + } +}); +defineFunction({ + type: "href", + names: ["\\url"], + props: { + numArgs: 1, + argTypes: ["url"], + allowedInText: true + }, + handler: (_ref2, args) => { + var { + parser + } = _ref2; + var href = assertNodeType(args[0], "url").url; + + if (!parser.settings.isTrusted({ + command: "\\url", + url: href + })) { + return parser.formatUnsupportedCmd("\\url"); + } + + var chars = []; + + for (var i = 0; i < href.length; i++) { + var c = href[i]; + + if (c === "~") { + c = "\\textasciitilde"; + } + + chars.push({ + type: "textord", + mode: "text", + text: c + }); + } + + var body = { + type: "text", + mode: parser.mode, + font: "\\texttt", + body: chars + }; + return { + type: "href", + mode: parser.mode, + href, + body: ordargument(body) + }; + } +}); + +// In LaTeX, \vcenter can act only on a box, as in +// \vcenter{\hbox{$\frac{a+b}{\dfrac{c}{d}}$}} +// This function by itself doesn't do anything but prevent a soft line break. + +defineFunction({ + type: "hbox", + names: ["\\hbox"], + props: { + numArgs: 1, + argTypes: ["text"], + allowedInText: true, + primitive: true + }, + + handler(_ref, args) { + var { + parser + } = _ref; + return { + type: "hbox", + mode: parser.mode, + body: ordargument(args[0]) + }; + }, + + htmlBuilder(group, options) { + var elements = buildExpression$1(group.body, options, false); + return buildCommon.makeFragment(elements); + }, + + mathmlBuilder(group, options) { + return new mathMLTree.MathNode("mrow", buildExpression(group.body, options)); + } + +}); + +defineFunction({ + type: "html", + names: ["\\htmlClass", "\\htmlId", "\\htmlStyle", "\\htmlData"], + props: { + numArgs: 2, + argTypes: ["raw", "original"], + allowedInText: true + }, + handler: (_ref, args) => { + var { + parser, + funcName, + token + } = _ref; + var value = assertNodeType(args[0], "raw").string; + var body = args[1]; + + if (parser.settings.strict) { + parser.settings.reportNonstrict("htmlExtension", "HTML extension is disabled on strict mode"); + } + + var trustContext; + var attributes = {}; + + switch (funcName) { + case "\\htmlClass": + attributes.class = value; + trustContext = { + command: "\\htmlClass", + class: value + }; + break; + + case "\\htmlId": + attributes.id = value; + trustContext = { + command: "\\htmlId", + id: value + }; + break; + + case "\\htmlStyle": + attributes.style = value; + trustContext = { + command: "\\htmlStyle", + style: value + }; + break; + + case "\\htmlData": + { + var data = value.split(","); + + for (var i = 0; i < data.length; i++) { + var keyVal = data[i].split("="); + + if (keyVal.length !== 2) { + throw new ParseError("Error parsing key-value for \\htmlData"); + } + + attributes["data-" + keyVal[0].trim()] = keyVal[1].trim(); + } + + trustContext = { + command: "\\htmlData", + attributes + }; + break; + } + + default: + throw new Error("Unrecognized html command"); + } + + if (!parser.settings.isTrusted(trustContext)) { + return parser.formatUnsupportedCmd(funcName); + } + + return { + type: "html", + mode: parser.mode, + attributes, + body: ordargument(body) + }; + }, + htmlBuilder: (group, options) => { + var elements = buildExpression$1(group.body, options, false); + var classes = ["enclosing"]; + + if (group.attributes.class) { + classes.push(...group.attributes.class.trim().split(/\s+/)); + } + + var span = buildCommon.makeSpan(classes, elements, options); + + for (var attr in group.attributes) { + if (attr !== "class" && group.attributes.hasOwnProperty(attr)) { + span.setAttribute(attr, group.attributes[attr]); + } + } + + return span; + }, + mathmlBuilder: (group, options) => { + return buildExpressionRow(group.body, options); + } +}); + +defineFunction({ + type: "htmlmathml", + names: ["\\html@mathml"], + props: { + numArgs: 2, + allowedInText: true + }, + handler: (_ref, args) => { + var { + parser + } = _ref; + return { + type: "htmlmathml", + mode: parser.mode, + html: ordargument(args[0]), + mathml: ordargument(args[1]) + }; + }, + htmlBuilder: (group, options) => { + var elements = buildExpression$1(group.html, options, false); + return buildCommon.makeFragment(elements); + }, + mathmlBuilder: (group, options) => { + return buildExpressionRow(group.mathml, options); + } +}); + +var sizeData = function sizeData(str) { + if (/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(str)) { + // str is a number with no unit specified. + // default unit is bp, per graphix package. + return { + number: +str, + unit: "bp" + }; + } else { + var match = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(str); + + if (!match) { + throw new ParseError("Invalid size: '" + str + "' in \\includegraphics"); + } + + var data = { + number: +(match[1] + match[2]), + // sign + magnitude, cast to number + unit: match[3] + }; + + if (!validUnit(data)) { + throw new ParseError("Invalid unit: '" + data.unit + "' in \\includegraphics."); + } + + return data; + } +}; + +defineFunction({ + type: "includegraphics", + names: ["\\includegraphics"], + props: { + numArgs: 1, + numOptionalArgs: 1, + argTypes: ["raw", "url"], + allowedInText: false + }, + handler: (_ref, args, optArgs) => { + var { + parser + } = _ref; + var width = { + number: 0, + unit: "em" + }; + var height = { + number: 0.9, + unit: "em" + }; // sorta character sized. + + var totalheight = { + number: 0, + unit: "em" + }; + var alt = ""; + + if (optArgs[0]) { + var attributeStr = assertNodeType(optArgs[0], "raw").string; // Parser.js does not parse key/value pairs. We get a string. + + var attributes = attributeStr.split(","); + + for (var i = 0; i < attributes.length; i++) { + var keyVal = attributes[i].split("="); + + if (keyVal.length === 2) { + var str = keyVal[1].trim(); + + switch (keyVal[0].trim()) { + case "alt": + alt = str; + break; + + case "width": + width = sizeData(str); + break; + + case "height": + height = sizeData(str); + break; + + case "totalheight": + totalheight = sizeData(str); + break; + + default: + throw new ParseError("Invalid key: '" + keyVal[0] + "' in \\includegraphics."); + } + } + } + } + + var src = assertNodeType(args[0], "url").url; + + if (alt === "") { + // No alt given. Use the file name. Strip away the path. + alt = src; + alt = alt.replace(/^.*[\\/]/, ''); + alt = alt.substring(0, alt.lastIndexOf('.')); + } + + if (!parser.settings.isTrusted({ + command: "\\includegraphics", + url: src + })) { + return parser.formatUnsupportedCmd("\\includegraphics"); + } + + return { + type: "includegraphics", + mode: parser.mode, + alt: alt, + width: width, + height: height, + totalheight: totalheight, + src: src + }; + }, + htmlBuilder: (group, options) => { + var height = calculateSize(group.height, options); + var depth = 0; + + if (group.totalheight.number > 0) { + depth = calculateSize(group.totalheight, options) - height; + } + + var width = 0; + + if (group.width.number > 0) { + width = calculateSize(group.width, options); + } + + var style = { + height: makeEm(height + depth) + }; + + if (width > 0) { + style.width = makeEm(width); + } + + if (depth > 0) { + style.verticalAlign = makeEm(-depth); + } + + var node = new Img(group.src, group.alt, style); + node.height = height; + node.depth = depth; + return node; + }, + mathmlBuilder: (group, options) => { + var node = new mathMLTree.MathNode("mglyph", []); + node.setAttribute("alt", group.alt); + var height = calculateSize(group.height, options); + var depth = 0; + + if (group.totalheight.number > 0) { + depth = calculateSize(group.totalheight, options) - height; + node.setAttribute("valign", makeEm(-depth)); + } + + node.setAttribute("height", makeEm(height + depth)); + + if (group.width.number > 0) { + var width = calculateSize(group.width, options); + node.setAttribute("width", makeEm(width)); + } + + node.setAttribute("src", group.src); + return node; + } +}); + +// Horizontal spacing commands + +defineFunction({ + type: "kern", + names: ["\\kern", "\\mkern", "\\hskip", "\\mskip"], + props: { + numArgs: 1, + argTypes: ["size"], + primitive: true, + allowedInText: true + }, + + handler(_ref, args) { + var { + parser, + funcName + } = _ref; + var size = assertNodeType(args[0], "size"); + + if (parser.settings.strict) { + var mathFunction = funcName[1] === 'm'; // \mkern, \mskip + + var muUnit = size.value.unit === 'mu'; + + if (mathFunction) { + if (!muUnit) { + parser.settings.reportNonstrict("mathVsTextUnits", "LaTeX's " + funcName + " supports only mu units, " + ("not " + size.value.unit + " units")); + } + + if (parser.mode !== "math") { + parser.settings.reportNonstrict("mathVsTextUnits", "LaTeX's " + funcName + " works only in math mode"); + } + } else { + // !mathFunction + if (muUnit) { + parser.settings.reportNonstrict("mathVsTextUnits", "LaTeX's " + funcName + " doesn't support mu units"); + } + } + } + + return { + type: "kern", + mode: parser.mode, + dimension: size.value + }; + }, + + htmlBuilder(group, options) { + return buildCommon.makeGlue(group.dimension, options); + }, + + mathmlBuilder(group, options) { + var dimension = calculateSize(group.dimension, options); + return new mathMLTree.SpaceNode(dimension); + } + +}); + +// Horizontal overlap functions +defineFunction({ + type: "lap", + names: ["\\mathllap", "\\mathrlap", "\\mathclap"], + props: { + numArgs: 1, + allowedInText: true + }, + handler: (_ref, args) => { + var { + parser, + funcName + } = _ref; + var body = args[0]; + return { + type: "lap", + mode: parser.mode, + alignment: funcName.slice(5), + body + }; + }, + htmlBuilder: (group, options) => { + // mathllap, mathrlap, mathclap + var inner; + + if (group.alignment === "clap") { + // ref: https://www.math.lsu.edu/~aperlis/publications/mathclap/ + inner = buildCommon.makeSpan([], [buildGroup$1(group.body, options)]); // wrap, since CSS will center a .clap > .inner > span + + inner = buildCommon.makeSpan(["inner"], [inner], options); + } else { + inner = buildCommon.makeSpan(["inner"], [buildGroup$1(group.body, options)]); + } + + var fix = buildCommon.makeSpan(["fix"], []); + var node = buildCommon.makeSpan([group.alignment], [inner, fix], options); // At this point, we have correctly set horizontal alignment of the + // two items involved in the lap. + // Next, use a strut to set the height of the HTML bounding box. + // Otherwise, a tall argument may be misplaced. + // This code resolved issue #1153 + + var strut = buildCommon.makeSpan(["strut"]); + strut.style.height = makeEm(node.height + node.depth); + + if (node.depth) { + strut.style.verticalAlign = makeEm(-node.depth); + } + + node.children.unshift(strut); // Next, prevent vertical misplacement when next to something tall. + // This code resolves issue #1234 + + node = buildCommon.makeSpan(["thinbox"], [node], options); + return buildCommon.makeSpan(["mord", "vbox"], [node], options); + }, + mathmlBuilder: (group, options) => { + // mathllap, mathrlap, mathclap + var node = new mathMLTree.MathNode("mpadded", [buildGroup(group.body, options)]); + + if (group.alignment !== "rlap") { + var offset = group.alignment === "llap" ? "-1" : "-0.5"; + node.setAttribute("lspace", offset + "width"); + } + + node.setAttribute("width", "0px"); + return node; + } +}); + +defineFunction({ + type: "styling", + names: ["\\(", "$"], + props: { + numArgs: 0, + allowedInText: true, + allowedInMath: false + }, + + handler(_ref, args) { + var { + funcName, + parser + } = _ref; + var outerMode = parser.mode; + parser.switchMode("math"); + var close = funcName === "\\(" ? "\\)" : "$"; + var body = parser.parseExpression(false, close); + parser.expect(close); + parser.switchMode(outerMode); + return { + type: "styling", + mode: parser.mode, + style: "text", + body + }; + } + +}); // Check for extra closing math delimiters + +defineFunction({ + type: "text", + // Doesn't matter what this is. + names: ["\\)", "\\]"], + props: { + numArgs: 0, + allowedInText: true, + allowedInMath: false + }, + + handler(context, args) { + throw new ParseError("Mismatched " + context.funcName); + } + +}); + +var chooseMathStyle = (group, options) => { + switch (options.style.size) { + case Style$1.DISPLAY.size: + return group.display; + + case Style$1.TEXT.size: + return group.text; + + case Style$1.SCRIPT.size: + return group.script; + + case Style$1.SCRIPTSCRIPT.size: + return group.scriptscript; + + default: + return group.text; + } +}; + +defineFunction({ + type: "mathchoice", + names: ["\\mathchoice"], + props: { + numArgs: 4, + primitive: true + }, + handler: (_ref, args) => { + var { + parser + } = _ref; + return { + type: "mathchoice", + mode: parser.mode, + display: ordargument(args[0]), + text: ordargument(args[1]), + script: ordargument(args[2]), + scriptscript: ordargument(args[3]) + }; + }, + htmlBuilder: (group, options) => { + var body = chooseMathStyle(group, options); + var elements = buildExpression$1(body, options, false); + return buildCommon.makeFragment(elements); + }, + mathmlBuilder: (group, options) => { + var body = chooseMathStyle(group, options); + return buildExpressionRow(body, options); + } +}); + +var assembleSupSub = (base, supGroup, subGroup, options, style, slant, baseShift) => { + base = buildCommon.makeSpan([], [base]); + var subIsSingleCharacter = subGroup && utils.isCharacterBox(subGroup); + var sub; + var sup; // We manually have to handle the superscripts and subscripts. This, + // aside from the kern calculations, is copied from supsub. + + if (supGroup) { + var elem = buildGroup$1(supGroup, options.havingStyle(style.sup()), options); + sup = { + elem, + kern: Math.max(options.fontMetrics().bigOpSpacing1, options.fontMetrics().bigOpSpacing3 - elem.depth) + }; + } + + if (subGroup) { + var _elem = buildGroup$1(subGroup, options.havingStyle(style.sub()), options); + + sub = { + elem: _elem, + kern: Math.max(options.fontMetrics().bigOpSpacing2, options.fontMetrics().bigOpSpacing4 - _elem.height) + }; + } // Build the final group as a vlist of the possible subscript, base, + // and possible superscript. + + + var finalGroup; + + if (sup && sub) { + var bottom = options.fontMetrics().bigOpSpacing5 + sub.elem.height + sub.elem.depth + sub.kern + base.depth + baseShift; + finalGroup = buildCommon.makeVList({ + positionType: "bottom", + positionData: bottom, + children: [{ + type: "kern", + size: options.fontMetrics().bigOpSpacing5 + }, { + type: "elem", + elem: sub.elem, + marginLeft: makeEm(-slant) + }, { + type: "kern", + size: sub.kern + }, { + type: "elem", + elem: base + }, { + type: "kern", + size: sup.kern + }, { + type: "elem", + elem: sup.elem, + marginLeft: makeEm(slant) + }, { + type: "kern", + size: options.fontMetrics().bigOpSpacing5 + }] + }, options); + } else if (sub) { + var top = base.height - baseShift; // Shift the limits by the slant of the symbol. Note + // that we are supposed to shift the limits by 1/2 of the slant, + // but since we are centering the limits adding a full slant of + // margin will shift by 1/2 that. + + finalGroup = buildCommon.makeVList({ + positionType: "top", + positionData: top, + children: [{ + type: "kern", + size: options.fontMetrics().bigOpSpacing5 + }, { + type: "elem", + elem: sub.elem, + marginLeft: makeEm(-slant) + }, { + type: "kern", + size: sub.kern + }, { + type: "elem", + elem: base + }] + }, options); + } else if (sup) { + var _bottom = base.depth + baseShift; + + finalGroup = buildCommon.makeVList({ + positionType: "bottom", + positionData: _bottom, + children: [{ + type: "elem", + elem: base + }, { + type: "kern", + size: sup.kern + }, { + type: "elem", + elem: sup.elem, + marginLeft: makeEm(slant) + }, { + type: "kern", + size: options.fontMetrics().bigOpSpacing5 + }] + }, options); + } else { + // This case probably shouldn't occur (this would mean the + // supsub was sending us a group with no superscript or + // subscript) but be safe. + return base; + } + + var parts = [finalGroup]; + + if (sub && slant !== 0 && !subIsSingleCharacter) { + // A negative margin-left was applied to the lower limit. + // Avoid an overlap by placing a spacer on the left on the group. + var spacer = buildCommon.makeSpan(["mspace"], [], options); + spacer.style.marginRight = makeEm(slant); + parts.unshift(spacer); + } + + return buildCommon.makeSpan(["mop", "op-limits"], parts, options); +}; + +// Limits, symbols +// Most operators have a large successor symbol, but these don't. +var noSuccessor = ["\\smallint"]; // NOTE: Unlike most `htmlBuilder`s, this one handles not only "op", but also +// "supsub" since some of them (like \int) can affect super/subscripting. + +var htmlBuilder$2 = (grp, options) => { + // Operators are handled in the TeXbook pg. 443-444, rule 13(a). + var supGroup; + var subGroup; + var hasLimits = false; + var group; + + if (grp.type === "supsub") { + // If we have limits, supsub will pass us its group to handle. Pull + // out the superscript and subscript and set the group to the op in + // its base. + supGroup = grp.sup; + subGroup = grp.sub; + group = assertNodeType(grp.base, "op"); + hasLimits = true; + } else { + group = assertNodeType(grp, "op"); + } + + var style = options.style; + var large = false; + + if (style.size === Style$1.DISPLAY.size && group.symbol && !utils.contains(noSuccessor, group.name)) { + // Most symbol operators get larger in displaystyle (rule 13) + large = true; + } + + var base; + + if (group.symbol) { + // If this is a symbol, create the symbol. + var fontName = large ? "Size2-Regular" : "Size1-Regular"; + var stash = ""; + + if (group.name === "\\oiint" || group.name === "\\oiiint") { + // No font glyphs yet, so use a glyph w/o the oval. + // TODO: When font glyphs are available, delete this code. + stash = group.name.slice(1); + group.name = stash === "oiint" ? "\\iint" : "\\iiint"; + } + + base = buildCommon.makeSymbol(group.name, fontName, "math", options, ["mop", "op-symbol", large ? "large-op" : "small-op"]); + + if (stash.length > 0) { + // We're in \oiint or \oiiint. Overlay the oval. + // TODO: When font glyphs are available, delete this code. + var italic = base.italic; + var oval = buildCommon.staticSvg(stash + "Size" + (large ? "2" : "1"), options); + base = buildCommon.makeVList({ + positionType: "individualShift", + children: [{ + type: "elem", + elem: base, + shift: 0 + }, { + type: "elem", + elem: oval, + shift: large ? 0.08 : 0 + }] + }, options); + group.name = "\\" + stash; + base.classes.unshift("mop"); // $FlowFixMe + + base.italic = italic; + } + } else if (group.body) { + // If this is a list, compose that list. + var inner = buildExpression$1(group.body, options, true); + + if (inner.length === 1 && inner[0] instanceof SymbolNode) { + base = inner[0]; + base.classes[0] = "mop"; // replace old mclass + } else { + base = buildCommon.makeSpan(["mop"], inner, options); + } + } else { + // Otherwise, this is a text operator. Build the text from the + // operator's name. + var output = []; + + for (var i = 1; i < group.name.length; i++) { + output.push(buildCommon.mathsym(group.name[i], group.mode, options)); + } + + base = buildCommon.makeSpan(["mop"], output, options); + } // If content of op is a single symbol, shift it vertically. + + + var baseShift = 0; + var slant = 0; + + if ((base instanceof SymbolNode || group.name === "\\oiint" || group.name === "\\oiiint") && !group.suppressBaseShift) { + // We suppress the shift of the base of \overset and \underset. Otherwise, + // shift the symbol so its center lies on the axis (rule 13). It + // appears that our fonts have the centers of the symbols already + // almost on the axis, so these numbers are very small. Note we + // don't actually apply this here, but instead it is used either in + // the vlist creation or separately when there are no limits. + baseShift = (base.height - base.depth) / 2 - options.fontMetrics().axisHeight; // The slant of the symbol is just its italic correction. + // $FlowFixMe + + slant = base.italic; + } + + if (hasLimits) { + return assembleSupSub(base, supGroup, subGroup, options, style, slant, baseShift); + } else { + if (baseShift) { + base.style.position = "relative"; + base.style.top = makeEm(baseShift); + } + + return base; + } +}; + +var mathmlBuilder$1 = (group, options) => { + var node; + + if (group.symbol) { + // This is a symbol. Just add the symbol. + node = new MathNode("mo", [makeText(group.name, group.mode)]); + + if (utils.contains(noSuccessor, group.name)) { + node.setAttribute("largeop", "false"); + } + } else if (group.body) { + // This is an operator with children. Add them. + node = new MathNode("mo", buildExpression(group.body, options)); + } else { + // This is a text operator. Add all of the characters from the + // operator's name. + node = new MathNode("mi", [new TextNode(group.name.slice(1))]); // Append an . + // ref: https://www.w3.org/TR/REC-MathML/chap3_2.html#sec3.2.4 + + var operator = new MathNode("mo", [makeText("\u2061", "text")]); + + if (group.parentIsSupSub) { + node = new MathNode("mrow", [node, operator]); + } else { + node = newDocumentFragment([node, operator]); + } + } + + return node; +}; + +var singleCharBigOps = { + "\u220F": "\\prod", + "\u2210": "\\coprod", + "\u2211": "\\sum", + "\u22c0": "\\bigwedge", + "\u22c1": "\\bigvee", + "\u22c2": "\\bigcap", + "\u22c3": "\\bigcup", + "\u2a00": "\\bigodot", + "\u2a01": "\\bigoplus", + "\u2a02": "\\bigotimes", + "\u2a04": "\\biguplus", + "\u2a06": "\\bigsqcup" +}; +defineFunction({ + type: "op", + names: ["\\coprod", "\\bigvee", "\\bigwedge", "\\biguplus", "\\bigcap", "\\bigcup", "\\intop", "\\prod", "\\sum", "\\bigotimes", "\\bigoplus", "\\bigodot", "\\bigsqcup", "\\smallint", "\u220F", "\u2210", "\u2211", "\u22c0", "\u22c1", "\u22c2", "\u22c3", "\u2a00", "\u2a01", "\u2a02", "\u2a04", "\u2a06"], + props: { + numArgs: 0 + }, + handler: (_ref, args) => { + var { + parser, + funcName + } = _ref; + var fName = funcName; + + if (fName.length === 1) { + fName = singleCharBigOps[fName]; + } + + return { + type: "op", + mode: parser.mode, + limits: true, + parentIsSupSub: false, + symbol: true, + name: fName + }; + }, + htmlBuilder: htmlBuilder$2, + mathmlBuilder: mathmlBuilder$1 +}); // Note: calling defineFunction with a type that's already been defined only +// works because the same htmlBuilder and mathmlBuilder are being used. + +defineFunction({ + type: "op", + names: ["\\mathop"], + props: { + numArgs: 1, + primitive: true + }, + handler: (_ref2, args) => { + var { + parser + } = _ref2; + var body = args[0]; + return { + type: "op", + mode: parser.mode, + limits: false, + parentIsSupSub: false, + symbol: false, + body: ordargument(body) + }; + }, + htmlBuilder: htmlBuilder$2, + mathmlBuilder: mathmlBuilder$1 +}); // There are 2 flags for operators; whether they produce limits in +// displaystyle, and whether they are symbols and should grow in +// displaystyle. These four groups cover the four possible choices. + +var singleCharIntegrals = { + "\u222b": "\\int", + "\u222c": "\\iint", + "\u222d": "\\iiint", + "\u222e": "\\oint", + "\u222f": "\\oiint", + "\u2230": "\\oiiint" +}; // No limits, not symbols + +defineFunction({ + type: "op", + names: ["\\arcsin", "\\arccos", "\\arctan", "\\arctg", "\\arcctg", "\\arg", "\\ch", "\\cos", "\\cosec", "\\cosh", "\\cot", "\\cotg", "\\coth", "\\csc", "\\ctg", "\\cth", "\\deg", "\\dim", "\\exp", "\\hom", "\\ker", "\\lg", "\\ln", "\\log", "\\sec", "\\sin", "\\sinh", "\\sh", "\\tan", "\\tanh", "\\tg", "\\th"], + props: { + numArgs: 0 + }, + + handler(_ref3) { + var { + parser, + funcName + } = _ref3; + return { + type: "op", + mode: parser.mode, + limits: false, + parentIsSupSub: false, + symbol: false, + name: funcName + }; + }, + + htmlBuilder: htmlBuilder$2, + mathmlBuilder: mathmlBuilder$1 +}); // Limits, not symbols + +defineFunction({ + type: "op", + names: ["\\det", "\\gcd", "\\inf", "\\lim", "\\max", "\\min", "\\Pr", "\\sup"], + props: { + numArgs: 0 + }, + + handler(_ref4) { + var { + parser, + funcName + } = _ref4; + return { + type: "op", + mode: parser.mode, + limits: true, + parentIsSupSub: false, + symbol: false, + name: funcName + }; + }, + + htmlBuilder: htmlBuilder$2, + mathmlBuilder: mathmlBuilder$1 +}); // No limits, symbols + +defineFunction({ + type: "op", + names: ["\\int", "\\iint", "\\iiint", "\\oint", "\\oiint", "\\oiiint", "\u222b", "\u222c", "\u222d", "\u222e", "\u222f", "\u2230"], + props: { + numArgs: 0 + }, + + handler(_ref5) { + var { + parser, + funcName + } = _ref5; + var fName = funcName; + + if (fName.length === 1) { + fName = singleCharIntegrals[fName]; + } + + return { + type: "op", + mode: parser.mode, + limits: false, + parentIsSupSub: false, + symbol: true, + name: fName + }; + }, + + htmlBuilder: htmlBuilder$2, + mathmlBuilder: mathmlBuilder$1 +}); + +// NOTE: Unlike most `htmlBuilder`s, this one handles not only +// "operatorname", but also "supsub" since \operatorname* can +// affect super/subscripting. +var htmlBuilder$1 = (grp, options) => { + // Operators are handled in the TeXbook pg. 443-444, rule 13(a). + var supGroup; + var subGroup; + var hasLimits = false; + var group; + + if (grp.type === "supsub") { + // If we have limits, supsub will pass us its group to handle. Pull + // out the superscript and subscript and set the group to the op in + // its base. + supGroup = grp.sup; + subGroup = grp.sub; + group = assertNodeType(grp.base, "operatorname"); + hasLimits = true; + } else { + group = assertNodeType(grp, "operatorname"); + } + + var base; + + if (group.body.length > 0) { + var body = group.body.map(child => { + // $FlowFixMe: Check if the node has a string `text` property. + var childText = child.text; + + if (typeof childText === "string") { + return { + type: "textord", + mode: child.mode, + text: childText + }; + } else { + return child; + } + }); // Consolidate function names into symbol characters. + + var expression = buildExpression$1(body, options.withFont("mathrm"), true); + + for (var i = 0; i < expression.length; i++) { + var child = expression[i]; + + if (child instanceof SymbolNode) { + // Per amsopn package, + // change minus to hyphen and \ast to asterisk + child.text = child.text.replace(/\u2212/, "-").replace(/\u2217/, "*"); + } + } + + base = buildCommon.makeSpan(["mop"], expression, options); + } else { + base = buildCommon.makeSpan(["mop"], [], options); + } + + if (hasLimits) { + return assembleSupSub(base, supGroup, subGroup, options, options.style, 0, 0); + } else { + return base; + } +}; + +var mathmlBuilder = (group, options) => { + // The steps taken here are similar to the html version. + var expression = buildExpression(group.body, options.withFont("mathrm")); // Is expression a string or has it something like a fraction? + + var isAllString = true; // default + + for (var i = 0; i < expression.length; i++) { + var node = expression[i]; + + if (node instanceof mathMLTree.SpaceNode) ; else if (node instanceof mathMLTree.MathNode) { + switch (node.type) { + case "mi": + case "mn": + case "ms": + case "mspace": + case "mtext": + break; + // Do nothing yet. + + case "mo": + { + var child = node.children[0]; + + if (node.children.length === 1 && child instanceof mathMLTree.TextNode) { + child.text = child.text.replace(/\u2212/, "-").replace(/\u2217/, "*"); + } else { + isAllString = false; + } + + break; + } + + default: + isAllString = false; + } + } else { + isAllString = false; + } + } + + if (isAllString) { + // Write a single TextNode instead of multiple nested tags. + var word = expression.map(node => node.toText()).join(""); + expression = [new mathMLTree.TextNode(word)]; + } + + var identifier = new mathMLTree.MathNode("mi", expression); + identifier.setAttribute("mathvariant", "normal"); // \u2061 is the same as ⁡ + // ref: https://www.w3schools.com/charsets/ref_html_entities_a.asp + + var operator = new mathMLTree.MathNode("mo", [makeText("\u2061", "text")]); + + if (group.parentIsSupSub) { + return new mathMLTree.MathNode("mrow", [identifier, operator]); + } else { + return mathMLTree.newDocumentFragment([identifier, operator]); + } +}; // \operatorname +// amsopn.dtx: \mathop{#1\kern\z@\operator@font#3}\newmcodes@ + + +defineFunction({ + type: "operatorname", + names: ["\\operatorname@", "\\operatornamewithlimits"], + props: { + numArgs: 1 + }, + handler: (_ref, args) => { + var { + parser, + funcName + } = _ref; + var body = args[0]; + return { + type: "operatorname", + mode: parser.mode, + body: ordargument(body), + alwaysHandleSupSub: funcName === "\\operatornamewithlimits", + limits: false, + parentIsSupSub: false + }; + }, + htmlBuilder: htmlBuilder$1, + mathmlBuilder +}); +defineMacro("\\operatorname", "\\@ifstar\\operatornamewithlimits\\operatorname@"); + +defineFunctionBuilders({ + type: "ordgroup", + + htmlBuilder(group, options) { + if (group.semisimple) { + return buildCommon.makeFragment(buildExpression$1(group.body, options, false)); + } + + return buildCommon.makeSpan(["mord"], buildExpression$1(group.body, options, true), options); + }, + + mathmlBuilder(group, options) { + return buildExpressionRow(group.body, options, true); + } + +}); + +defineFunction({ + type: "overline", + names: ["\\overline"], + props: { + numArgs: 1 + }, + + handler(_ref, args) { + var { + parser + } = _ref; + var body = args[0]; + return { + type: "overline", + mode: parser.mode, + body + }; + }, + + htmlBuilder(group, options) { + // Overlines are handled in the TeXbook pg 443, Rule 9. + // Build the inner group in the cramped style. + var innerGroup = buildGroup$1(group.body, options.havingCrampedStyle()); // Create the line above the body + + var line = buildCommon.makeLineSpan("overline-line", options); // Generate the vlist, with the appropriate kerns + + var defaultRuleThickness = options.fontMetrics().defaultRuleThickness; + var vlist = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: innerGroup + }, { + type: "kern", + size: 3 * defaultRuleThickness + }, { + type: "elem", + elem: line + }, { + type: "kern", + size: defaultRuleThickness + }] + }, options); + return buildCommon.makeSpan(["mord", "overline"], [vlist], options); + }, + + mathmlBuilder(group, options) { + var operator = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode("\u203e")]); + operator.setAttribute("stretchy", "true"); + var node = new mathMLTree.MathNode("mover", [buildGroup(group.body, options), operator]); + node.setAttribute("accent", "true"); + return node; + } + +}); + +defineFunction({ + type: "phantom", + names: ["\\phantom"], + props: { + numArgs: 1, + allowedInText: true + }, + handler: (_ref, args) => { + var { + parser + } = _ref; + var body = args[0]; + return { + type: "phantom", + mode: parser.mode, + body: ordargument(body) + }; + }, + htmlBuilder: (group, options) => { + var elements = buildExpression$1(group.body, options.withPhantom(), false); // \phantom isn't supposed to affect the elements it contains. + // See "color" for more details. + + return buildCommon.makeFragment(elements); + }, + mathmlBuilder: (group, options) => { + var inner = buildExpression(group.body, options); + return new mathMLTree.MathNode("mphantom", inner); + } +}); +defineFunction({ + type: "hphantom", + names: ["\\hphantom"], + props: { + numArgs: 1, + allowedInText: true + }, + handler: (_ref2, args) => { + var { + parser + } = _ref2; + var body = args[0]; + return { + type: "hphantom", + mode: parser.mode, + body + }; + }, + htmlBuilder: (group, options) => { + var node = buildCommon.makeSpan([], [buildGroup$1(group.body, options.withPhantom())]); + node.height = 0; + node.depth = 0; + + if (node.children) { + for (var i = 0; i < node.children.length; i++) { + node.children[i].height = 0; + node.children[i].depth = 0; + } + } // See smash for comment re: use of makeVList + + + node = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: node + }] + }, options); // For spacing, TeX treats \smash as a math group (same spacing as ord). + + return buildCommon.makeSpan(["mord"], [node], options); + }, + mathmlBuilder: (group, options) => { + var inner = buildExpression(ordargument(group.body), options); + var phantom = new mathMLTree.MathNode("mphantom", inner); + var node = new mathMLTree.MathNode("mpadded", [phantom]); + node.setAttribute("height", "0px"); + node.setAttribute("depth", "0px"); + return node; + } +}); +defineFunction({ + type: "vphantom", + names: ["\\vphantom"], + props: { + numArgs: 1, + allowedInText: true + }, + handler: (_ref3, args) => { + var { + parser + } = _ref3; + var body = args[0]; + return { + type: "vphantom", + mode: parser.mode, + body + }; + }, + htmlBuilder: (group, options) => { + var inner = buildCommon.makeSpan(["inner"], [buildGroup$1(group.body, options.withPhantom())]); + var fix = buildCommon.makeSpan(["fix"], []); + return buildCommon.makeSpan(["mord", "rlap"], [inner, fix], options); + }, + mathmlBuilder: (group, options) => { + var inner = buildExpression(ordargument(group.body), options); + var phantom = new mathMLTree.MathNode("mphantom", inner); + var node = new mathMLTree.MathNode("mpadded", [phantom]); + node.setAttribute("width", "0px"); + return node; + } +}); + +defineFunction({ + type: "raisebox", + names: ["\\raisebox"], + props: { + numArgs: 2, + argTypes: ["size", "hbox"], + allowedInText: true + }, + + handler(_ref, args) { + var { + parser + } = _ref; + var amount = assertNodeType(args[0], "size").value; + var body = args[1]; + return { + type: "raisebox", + mode: parser.mode, + dy: amount, + body + }; + }, + + htmlBuilder(group, options) { + var body = buildGroup$1(group.body, options); + var dy = calculateSize(group.dy, options); + return buildCommon.makeVList({ + positionType: "shift", + positionData: -dy, + children: [{ + type: "elem", + elem: body + }] + }, options); + }, + + mathmlBuilder(group, options) { + var node = new mathMLTree.MathNode("mpadded", [buildGroup(group.body, options)]); + var dy = group.dy.number + group.dy.unit; + node.setAttribute("voffset", dy); + return node; + } + +}); + +defineFunction({ + type: "internal", + names: ["\\relax"], + props: { + numArgs: 0, + allowedInText: true + }, + + handler(_ref) { + var { + parser + } = _ref; + return { + type: "internal", + mode: parser.mode + }; + } + +}); + +defineFunction({ + type: "rule", + names: ["\\rule"], + props: { + numArgs: 2, + numOptionalArgs: 1, + argTypes: ["size", "size", "size"] + }, + + handler(_ref, args, optArgs) { + var { + parser + } = _ref; + var shift = optArgs[0]; + var width = assertNodeType(args[0], "size"); + var height = assertNodeType(args[1], "size"); + return { + type: "rule", + mode: parser.mode, + shift: shift && assertNodeType(shift, "size").value, + width: width.value, + height: height.value + }; + }, + + htmlBuilder(group, options) { + // Make an empty span for the rule + var rule = buildCommon.makeSpan(["mord", "rule"], [], options); // Calculate the shift, width, and height of the rule, and account for units + + var width = calculateSize(group.width, options); + var height = calculateSize(group.height, options); + var shift = group.shift ? calculateSize(group.shift, options) : 0; // Style the rule to the right size + + rule.style.borderRightWidth = makeEm(width); + rule.style.borderTopWidth = makeEm(height); + rule.style.bottom = makeEm(shift); // Record the height and width + + rule.width = width; + rule.height = height + shift; + rule.depth = -shift; // Font size is the number large enough that the browser will + // reserve at least `absHeight` space above the baseline. + // The 1.125 factor was empirically determined + + rule.maxFontSize = height * 1.125 * options.sizeMultiplier; + return rule; + }, + + mathmlBuilder(group, options) { + var width = calculateSize(group.width, options); + var height = calculateSize(group.height, options); + var shift = group.shift ? calculateSize(group.shift, options) : 0; + var color = options.color && options.getColor() || "black"; + var rule = new mathMLTree.MathNode("mspace"); + rule.setAttribute("mathbackground", color); + rule.setAttribute("width", makeEm(width)); + rule.setAttribute("height", makeEm(height)); + var wrapper = new mathMLTree.MathNode("mpadded", [rule]); + + if (shift >= 0) { + wrapper.setAttribute("height", makeEm(shift)); + } else { + wrapper.setAttribute("height", makeEm(shift)); + wrapper.setAttribute("depth", makeEm(-shift)); + } + + wrapper.setAttribute("voffset", makeEm(shift)); + return wrapper; + } + +}); + +function sizingGroup(value, options, baseOptions) { + var inner = buildExpression$1(value, options, false); + var multiplier = options.sizeMultiplier / baseOptions.sizeMultiplier; // Add size-resetting classes to the inner list and set maxFontSize + // manually. Handle nested size changes. + + for (var i = 0; i < inner.length; i++) { + var pos = inner[i].classes.indexOf("sizing"); + + if (pos < 0) { + Array.prototype.push.apply(inner[i].classes, options.sizingClasses(baseOptions)); + } else if (inner[i].classes[pos + 1] === "reset-size" + options.size) { + // This is a nested size change: e.g., inner[i] is the "b" in + // `\Huge a \small b`. Override the old size (the `reset-` class) + // but not the new size. + inner[i].classes[pos + 1] = "reset-size" + baseOptions.size; + } + + inner[i].height *= multiplier; + inner[i].depth *= multiplier; + } + + return buildCommon.makeFragment(inner); +} +var sizeFuncs = ["\\tiny", "\\sixptsize", "\\scriptsize", "\\footnotesize", "\\small", "\\normalsize", "\\large", "\\Large", "\\LARGE", "\\huge", "\\Huge"]; +var htmlBuilder = (group, options) => { + // Handle sizing operators like \Huge. Real TeX doesn't actually allow + // these functions inside of math expressions, so we do some special + // handling. + var newOptions = options.havingSize(group.size); + return sizingGroup(group.body, newOptions, options); +}; +defineFunction({ + type: "sizing", + names: sizeFuncs, + props: { + numArgs: 0, + allowedInText: true + }, + handler: (_ref, args) => { + var { + breakOnTokenText, + funcName, + parser + } = _ref; + var body = parser.parseExpression(false, breakOnTokenText); + return { + type: "sizing", + mode: parser.mode, + // Figure out what size to use based on the list of functions above + size: sizeFuncs.indexOf(funcName) + 1, + body + }; + }, + htmlBuilder, + mathmlBuilder: (group, options) => { + var newOptions = options.havingSize(group.size); + var inner = buildExpression(group.body, newOptions); + var node = new mathMLTree.MathNode("mstyle", inner); // TODO(emily): This doesn't produce the correct size for nested size + // changes, because we don't keep state of what style we're currently + // in, so we can't reset the size to normal before changing it. Now + // that we're passing an options parameter we should be able to fix + // this. + + node.setAttribute("mathsize", makeEm(newOptions.sizeMultiplier)); + return node; + } +}); + +// smash, with optional [tb], as in AMS +defineFunction({ + type: "smash", + names: ["\\smash"], + props: { + numArgs: 1, + numOptionalArgs: 1, + allowedInText: true + }, + handler: (_ref, args, optArgs) => { + var { + parser + } = _ref; + var smashHeight = false; + var smashDepth = false; + var tbArg = optArgs[0] && assertNodeType(optArgs[0], "ordgroup"); + + if (tbArg) { + // Optional [tb] argument is engaged. + // ref: amsmath: \renewcommand{\smash}[1][tb]{% + // def\mb@t{\ht}\def\mb@b{\dp}\def\mb@tb{\ht\z@\z@\dp}% + var letter = ""; + + for (var i = 0; i < tbArg.body.length; ++i) { + var node = tbArg.body[i]; // $FlowFixMe: Not every node type has a `text` property. + + letter = node.text; + + if (letter === "t") { + smashHeight = true; + } else if (letter === "b") { + smashDepth = true; + } else { + smashHeight = false; + smashDepth = false; + break; + } + } + } else { + smashHeight = true; + smashDepth = true; + } + + var body = args[0]; + return { + type: "smash", + mode: parser.mode, + body, + smashHeight, + smashDepth + }; + }, + htmlBuilder: (group, options) => { + var node = buildCommon.makeSpan([], [buildGroup$1(group.body, options)]); + + if (!group.smashHeight && !group.smashDepth) { + return node; + } + + if (group.smashHeight) { + node.height = 0; // In order to influence makeVList, we have to reset the children. + + if (node.children) { + for (var i = 0; i < node.children.length; i++) { + node.children[i].height = 0; + } + } + } + + if (group.smashDepth) { + node.depth = 0; + + if (node.children) { + for (var _i = 0; _i < node.children.length; _i++) { + node.children[_i].depth = 0; + } + } + } // At this point, we've reset the TeX-like height and depth values. + // But the span still has an HTML line height. + // makeVList applies "display: table-cell", which prevents the browser + // from acting on that line height. So we'll call makeVList now. + + + var smashedNode = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: node + }] + }, options); // For spacing, TeX treats \hphantom as a math group (same spacing as ord). + + return buildCommon.makeSpan(["mord"], [smashedNode], options); + }, + mathmlBuilder: (group, options) => { + var node = new mathMLTree.MathNode("mpadded", [buildGroup(group.body, options)]); + + if (group.smashHeight) { + node.setAttribute("height", "0px"); + } + + if (group.smashDepth) { + node.setAttribute("depth", "0px"); + } + + return node; + } +}); + +defineFunction({ + type: "sqrt", + names: ["\\sqrt"], + props: { + numArgs: 1, + numOptionalArgs: 1 + }, + + handler(_ref, args, optArgs) { + var { + parser + } = _ref; + var index = optArgs[0]; + var body = args[0]; + return { + type: "sqrt", + mode: parser.mode, + body, + index + }; + }, + + htmlBuilder(group, options) { + // Square roots are handled in the TeXbook pg. 443, Rule 11. + // First, we do the same steps as in overline to build the inner group + // and line + var inner = buildGroup$1(group.body, options.havingCrampedStyle()); + + if (inner.height === 0) { + // Render a small surd. + inner.height = options.fontMetrics().xHeight; + } // Some groups can return document fragments. Handle those by wrapping + // them in a span. + + + inner = buildCommon.wrapFragment(inner, options); // Calculate the minimum size for the \surd delimiter + + var metrics = options.fontMetrics(); + var theta = metrics.defaultRuleThickness; + var phi = theta; + + if (options.style.id < Style$1.TEXT.id) { + phi = options.fontMetrics().xHeight; + } // Calculate the clearance between the body and line + + + var lineClearance = theta + phi / 4; + var minDelimiterHeight = inner.height + inner.depth + lineClearance + theta; // Create a sqrt SVG of the required minimum size + + var { + span: img, + ruleWidth, + advanceWidth + } = delimiter.sqrtImage(minDelimiterHeight, options); + var delimDepth = img.height - ruleWidth; // Adjust the clearance based on the delimiter size + + if (delimDepth > inner.height + inner.depth + lineClearance) { + lineClearance = (lineClearance + delimDepth - inner.height - inner.depth) / 2; + } // Shift the sqrt image + + + var imgShift = img.height - inner.height - lineClearance - ruleWidth; + inner.style.paddingLeft = makeEm(advanceWidth); // Overlay the image and the argument. + + var body = buildCommon.makeVList({ + positionType: "firstBaseline", + children: [{ + type: "elem", + elem: inner, + wrapperClasses: ["svg-align"] + }, { + type: "kern", + size: -(inner.height + imgShift) + }, { + type: "elem", + elem: img + }, { + type: "kern", + size: ruleWidth + }] + }, options); + + if (!group.index) { + return buildCommon.makeSpan(["mord", "sqrt"], [body], options); + } else { + // Handle the optional root index + // The index is always in scriptscript style + var newOptions = options.havingStyle(Style$1.SCRIPTSCRIPT); + var rootm = buildGroup$1(group.index, newOptions, options); // The amount the index is shifted by. This is taken from the TeX + // source, in the definition of `\r@@t`. + + var toShift = 0.6 * (body.height - body.depth); // Build a VList with the superscript shifted up correctly + + var rootVList = buildCommon.makeVList({ + positionType: "shift", + positionData: -toShift, + children: [{ + type: "elem", + elem: rootm + }] + }, options); // Add a class surrounding it so we can add on the appropriate + // kerning + + var rootVListWrap = buildCommon.makeSpan(["root"], [rootVList]); + return buildCommon.makeSpan(["mord", "sqrt"], [rootVListWrap, body], options); + } + }, + + mathmlBuilder(group, options) { + var { + body, + index + } = group; + return index ? new mathMLTree.MathNode("mroot", [buildGroup(body, options), buildGroup(index, options)]) : new mathMLTree.MathNode("msqrt", [buildGroup(body, options)]); + } + +}); + +var styleMap = { + "display": Style$1.DISPLAY, + "text": Style$1.TEXT, + "script": Style$1.SCRIPT, + "scriptscript": Style$1.SCRIPTSCRIPT +}; +defineFunction({ + type: "styling", + names: ["\\displaystyle", "\\textstyle", "\\scriptstyle", "\\scriptscriptstyle"], + props: { + numArgs: 0, + allowedInText: true, + primitive: true + }, + + handler(_ref, args) { + var { + breakOnTokenText, + funcName, + parser + } = _ref; + // parse out the implicit body + var body = parser.parseExpression(true, breakOnTokenText); // TODO: Refactor to avoid duplicating styleMap in multiple places (e.g. + // here and in buildHTML and de-dupe the enumeration of all the styles). + // $FlowFixMe: The names above exactly match the styles. + + var style = funcName.slice(1, funcName.length - 5); + return { + type: "styling", + mode: parser.mode, + // Figure out what style to use by pulling out the style from + // the function name + style, + body + }; + }, + + htmlBuilder(group, options) { + // Style changes are handled in the TeXbook on pg. 442, Rule 3. + var newStyle = styleMap[group.style]; + var newOptions = options.havingStyle(newStyle).withFont(''); + return sizingGroup(group.body, newOptions, options); + }, + + mathmlBuilder(group, options) { + // Figure out what style we're changing to. + var newStyle = styleMap[group.style]; + var newOptions = options.havingStyle(newStyle); + var inner = buildExpression(group.body, newOptions); + var node = new mathMLTree.MathNode("mstyle", inner); + var styleAttributes = { + "display": ["0", "true"], + "text": ["0", "false"], + "script": ["1", "false"], + "scriptscript": ["2", "false"] + }; + var attr = styleAttributes[group.style]; + node.setAttribute("scriptlevel", attr[0]); + node.setAttribute("displaystyle", attr[1]); + return node; + } + +}); + +/** + * Sometimes, groups perform special rules when they have superscripts or + * subscripts attached to them. This function lets the `supsub` group know that + * Sometimes, groups perform special rules when they have superscripts or + * its inner element should handle the superscripts and subscripts instead of + * handling them itself. + */ +var htmlBuilderDelegate = function htmlBuilderDelegate(group, options) { + var base = group.base; + + if (!base) { + return null; + } else if (base.type === "op") { + // Operators handle supsubs differently when they have limits + // (e.g. `\displaystyle\sum_2^3`) + var delegate = base.limits && (options.style.size === Style$1.DISPLAY.size || base.alwaysHandleSupSub); + return delegate ? htmlBuilder$2 : null; + } else if (base.type === "operatorname") { + var _delegate = base.alwaysHandleSupSub && (options.style.size === Style$1.DISPLAY.size || base.limits); + + return _delegate ? htmlBuilder$1 : null; + } else if (base.type === "accent") { + return utils.isCharacterBox(base.base) ? htmlBuilder$a : null; + } else if (base.type === "horizBrace") { + var isSup = !group.sub; + return isSup === base.isOver ? htmlBuilder$3 : null; + } else { + return null; + } +}; // Super scripts and subscripts, whose precise placement can depend on other +// functions that precede them. + + +defineFunctionBuilders({ + type: "supsub", + + htmlBuilder(group, options) { + // Superscript and subscripts are handled in the TeXbook on page + // 445-446, rules 18(a-f). + // Here is where we defer to the inner group if it should handle + // superscripts and subscripts itself. + var builderDelegate = htmlBuilderDelegate(group, options); + + if (builderDelegate) { + return builderDelegate(group, options); + } + + var { + base: valueBase, + sup: valueSup, + sub: valueSub + } = group; + var base = buildGroup$1(valueBase, options); + var supm; + var subm; + var metrics = options.fontMetrics(); // Rule 18a + + var supShift = 0; + var subShift = 0; + var isCharacterBox = valueBase && utils.isCharacterBox(valueBase); + + if (valueSup) { + var newOptions = options.havingStyle(options.style.sup()); + supm = buildGroup$1(valueSup, newOptions, options); + + if (!isCharacterBox) { + supShift = base.height - newOptions.fontMetrics().supDrop * newOptions.sizeMultiplier / options.sizeMultiplier; + } + } + + if (valueSub) { + var _newOptions = options.havingStyle(options.style.sub()); + + subm = buildGroup$1(valueSub, _newOptions, options); + + if (!isCharacterBox) { + subShift = base.depth + _newOptions.fontMetrics().subDrop * _newOptions.sizeMultiplier / options.sizeMultiplier; + } + } // Rule 18c + + + var minSupShift; + + if (options.style === Style$1.DISPLAY) { + minSupShift = metrics.sup1; + } else if (options.style.cramped) { + minSupShift = metrics.sup3; + } else { + minSupShift = metrics.sup2; + } // scriptspace is a font-size-independent size, so scale it + // appropriately for use as the marginRight. + + + var multiplier = options.sizeMultiplier; + var marginRight = makeEm(0.5 / metrics.ptPerEm / multiplier); + var marginLeft = null; + + if (subm) { + // Subscripts shouldn't be shifted by the base's italic correction. + // Account for that by shifting the subscript back the appropriate + // amount. Note we only do this when the base is a single symbol. + var isOiint = group.base && group.base.type === "op" && group.base.name && (group.base.name === "\\oiint" || group.base.name === "\\oiiint"); + + if (base instanceof SymbolNode || isOiint) { + // $FlowFixMe + marginLeft = makeEm(-base.italic); + } + } + + var supsub; + + if (supm && subm) { + supShift = Math.max(supShift, minSupShift, supm.depth + 0.25 * metrics.xHeight); + subShift = Math.max(subShift, metrics.sub2); + var ruleWidth = metrics.defaultRuleThickness; // Rule 18e + + var maxWidth = 4 * ruleWidth; + + if (supShift - supm.depth - (subm.height - subShift) < maxWidth) { + subShift = maxWidth - (supShift - supm.depth) + subm.height; + var psi = 0.8 * metrics.xHeight - (supShift - supm.depth); + + if (psi > 0) { + supShift += psi; + subShift -= psi; + } + } + + var vlistElem = [{ + type: "elem", + elem: subm, + shift: subShift, + marginRight, + marginLeft + }, { + type: "elem", + elem: supm, + shift: -supShift, + marginRight + }]; + supsub = buildCommon.makeVList({ + positionType: "individualShift", + children: vlistElem + }, options); + } else if (subm) { + // Rule 18b + subShift = Math.max(subShift, metrics.sub1, subm.height - 0.8 * metrics.xHeight); + var _vlistElem = [{ + type: "elem", + elem: subm, + marginLeft, + marginRight + }]; + supsub = buildCommon.makeVList({ + positionType: "shift", + positionData: subShift, + children: _vlistElem + }, options); + } else if (supm) { + // Rule 18c, d + supShift = Math.max(supShift, minSupShift, supm.depth + 0.25 * metrics.xHeight); + supsub = buildCommon.makeVList({ + positionType: "shift", + positionData: -supShift, + children: [{ + type: "elem", + elem: supm, + marginRight + }] + }, options); + } else { + throw new Error("supsub must have either sup or sub."); + } // Wrap the supsub vlist in a span.msupsub to reset text-align. + + + var mclass = getTypeOfDomTree(base, "right") || "mord"; + return buildCommon.makeSpan([mclass], [base, buildCommon.makeSpan(["msupsub"], [supsub])], options); + }, + + mathmlBuilder(group, options) { + // Is the inner group a relevant horizonal brace? + var isBrace = false; + var isOver; + var isSup; + + if (group.base && group.base.type === "horizBrace") { + isSup = !!group.sup; + + if (isSup === group.base.isOver) { + isBrace = true; + isOver = group.base.isOver; + } + } + + if (group.base && (group.base.type === "op" || group.base.type === "operatorname")) { + group.base.parentIsSupSub = true; + } + + var children = [buildGroup(group.base, options)]; + + if (group.sub) { + children.push(buildGroup(group.sub, options)); + } + + if (group.sup) { + children.push(buildGroup(group.sup, options)); + } + + var nodeType; + + if (isBrace) { + nodeType = isOver ? "mover" : "munder"; + } else if (!group.sub) { + var base = group.base; + + if (base && base.type === "op" && base.limits && (options.style === Style$1.DISPLAY || base.alwaysHandleSupSub)) { + nodeType = "mover"; + } else if (base && base.type === "operatorname" && base.alwaysHandleSupSub && (base.limits || options.style === Style$1.DISPLAY)) { + nodeType = "mover"; + } else { + nodeType = "msup"; + } + } else if (!group.sup) { + var _base = group.base; + + if (_base && _base.type === "op" && _base.limits && (options.style === Style$1.DISPLAY || _base.alwaysHandleSupSub)) { + nodeType = "munder"; + } else if (_base && _base.type === "operatorname" && _base.alwaysHandleSupSub && (_base.limits || options.style === Style$1.DISPLAY)) { + nodeType = "munder"; + } else { + nodeType = "msub"; + } + } else { + var _base2 = group.base; + + if (_base2 && _base2.type === "op" && _base2.limits && options.style === Style$1.DISPLAY) { + nodeType = "munderover"; + } else if (_base2 && _base2.type === "operatorname" && _base2.alwaysHandleSupSub && (options.style === Style$1.DISPLAY || _base2.limits)) { + nodeType = "munderover"; + } else { + nodeType = "msubsup"; + } + } + + return new mathMLTree.MathNode(nodeType, children); + } + +}); + +defineFunctionBuilders({ + type: "atom", + + htmlBuilder(group, options) { + return buildCommon.mathsym(group.text, group.mode, options, ["m" + group.family]); + }, + + mathmlBuilder(group, options) { + var node = new mathMLTree.MathNode("mo", [makeText(group.text, group.mode)]); + + if (group.family === "bin") { + var variant = getVariant(group, options); + + if (variant === "bold-italic") { + node.setAttribute("mathvariant", variant); + } + } else if (group.family === "punct") { + node.setAttribute("separator", "true"); + } else if (group.family === "open" || group.family === "close") { + // Delims built here should not stretch vertically. + // See delimsizing.js for stretchy delims. + node.setAttribute("stretchy", "false"); + } + + return node; + } + +}); + +// "mathord" and "textord" ParseNodes created in Parser.js from symbol Groups in +// src/symbols.js. +var defaultVariant = { + "mi": "italic", + "mn": "normal", + "mtext": "normal" +}; +defineFunctionBuilders({ + type: "mathord", + + htmlBuilder(group, options) { + return buildCommon.makeOrd(group, options, "mathord"); + }, + + mathmlBuilder(group, options) { + var node = new mathMLTree.MathNode("mi", [makeText(group.text, group.mode, options)]); + var variant = getVariant(group, options) || "italic"; + + if (variant !== defaultVariant[node.type]) { + node.setAttribute("mathvariant", variant); + } + + return node; + } + +}); +defineFunctionBuilders({ + type: "textord", + + htmlBuilder(group, options) { + return buildCommon.makeOrd(group, options, "textord"); + }, + + mathmlBuilder(group, options) { + var text = makeText(group.text, group.mode, options); + var variant = getVariant(group, options) || "normal"; + var node; + + if (group.mode === 'text') { + node = new mathMLTree.MathNode("mtext", [text]); + } else if (/[0-9]/.test(group.text)) { + node = new mathMLTree.MathNode("mn", [text]); + } else if (group.text === "\\prime") { + node = new mathMLTree.MathNode("mo", [text]); + } else { + node = new mathMLTree.MathNode("mi", [text]); + } + + if (variant !== defaultVariant[node.type]) { + node.setAttribute("mathvariant", variant); + } + + return node; + } + +}); + +var cssSpace = { + "\\nobreak": "nobreak", + "\\allowbreak": "allowbreak" +}; // A lookup table to determine whether a spacing function/symbol should be +// treated like a regular space character. If a symbol or command is a key +// in this table, then it should be a regular space character. Furthermore, +// the associated value may have a `className` specifying an extra CSS class +// to add to the created `span`. + +var regularSpace = { + " ": {}, + "\\ ": {}, + "~": { + className: "nobreak" + }, + "\\space": {}, + "\\nobreakspace": { + className: "nobreak" + } +}; // ParseNode<"spacing"> created in Parser.js from the "spacing" symbol Groups in +// src/symbols.js. + +defineFunctionBuilders({ + type: "spacing", + + htmlBuilder(group, options) { + if (regularSpace.hasOwnProperty(group.text)) { + var className = regularSpace[group.text].className || ""; // Spaces are generated by adding an actual space. Each of these + // things has an entry in the symbols table, so these will be turned + // into appropriate outputs. + + if (group.mode === "text") { + var ord = buildCommon.makeOrd(group, options, "textord"); + ord.classes.push(className); + return ord; + } else { + return buildCommon.makeSpan(["mspace", className], [buildCommon.mathsym(group.text, group.mode, options)], options); + } + } else if (cssSpace.hasOwnProperty(group.text)) { + // Spaces based on just a CSS class. + return buildCommon.makeSpan(["mspace", cssSpace[group.text]], [], options); + } else { + throw new ParseError("Unknown type of space \"" + group.text + "\""); + } + }, + + mathmlBuilder(group, options) { + var node; + + if (regularSpace.hasOwnProperty(group.text)) { + node = new mathMLTree.MathNode("mtext", [new mathMLTree.TextNode("\u00a0")]); + } else if (cssSpace.hasOwnProperty(group.text)) { + // CSS-based MathML spaces (\nobreak, \allowbreak) are ignored + return new mathMLTree.MathNode("mspace"); + } else { + throw new ParseError("Unknown type of space \"" + group.text + "\""); + } + + return node; + } + +}); + +var pad = () => { + var padNode = new mathMLTree.MathNode("mtd", []); + padNode.setAttribute("width", "50%"); + return padNode; +}; + +defineFunctionBuilders({ + type: "tag", + + mathmlBuilder(group, options) { + var table = new mathMLTree.MathNode("mtable", [new mathMLTree.MathNode("mtr", [pad(), new mathMLTree.MathNode("mtd", [buildExpressionRow(group.body, options)]), pad(), new mathMLTree.MathNode("mtd", [buildExpressionRow(group.tag, options)])])]); + table.setAttribute("width", "100%"); + return table; // TODO: Left-aligned tags. + // Currently, the group and options passed here do not contain + // enough info to set tag alignment. `leqno` is in Settings but it is + // not passed to Options. On the HTML side, leqno is + // set by a CSS class applied in buildTree.js. That would have worked + // in MathML if browsers supported . Since they don't, we + // need to rewrite the way this function is called. + } + +}); + +var textFontFamilies = { + "\\text": undefined, + "\\textrm": "textrm", + "\\textsf": "textsf", + "\\texttt": "texttt", + "\\textnormal": "textrm" +}; +var textFontWeights = { + "\\textbf": "textbf", + "\\textmd": "textmd" +}; +var textFontShapes = { + "\\textit": "textit", + "\\textup": "textup" +}; + +var optionsWithFont = (group, options) => { + var font = group.font; // Checks if the argument is a font family or a font style. + + if (!font) { + return options; + } else if (textFontFamilies[font]) { + return options.withTextFontFamily(textFontFamilies[font]); + } else if (textFontWeights[font]) { + return options.withTextFontWeight(textFontWeights[font]); + } else { + return options.withTextFontShape(textFontShapes[font]); + } +}; + +defineFunction({ + type: "text", + names: [// Font families + "\\text", "\\textrm", "\\textsf", "\\texttt", "\\textnormal", // Font weights + "\\textbf", "\\textmd", // Font Shapes + "\\textit", "\\textup"], + props: { + numArgs: 1, + argTypes: ["text"], + allowedInArgument: true, + allowedInText: true + }, + + handler(_ref, args) { + var { + parser, + funcName + } = _ref; + var body = args[0]; + return { + type: "text", + mode: parser.mode, + body: ordargument(body), + font: funcName + }; + }, + + htmlBuilder(group, options) { + var newOptions = optionsWithFont(group, options); + var inner = buildExpression$1(group.body, newOptions, true); + return buildCommon.makeSpan(["mord", "text"], inner, newOptions); + }, + + mathmlBuilder(group, options) { + var newOptions = optionsWithFont(group, options); + return buildExpressionRow(group.body, newOptions); + } + +}); + +defineFunction({ + type: "underline", + names: ["\\underline"], + props: { + numArgs: 1, + allowedInText: true + }, + + handler(_ref, args) { + var { + parser + } = _ref; + return { + type: "underline", + mode: parser.mode, + body: args[0] + }; + }, + + htmlBuilder(group, options) { + // Underlines are handled in the TeXbook pg 443, Rule 10. + // Build the inner group. + var innerGroup = buildGroup$1(group.body, options); // Create the line to go below the body + + var line = buildCommon.makeLineSpan("underline-line", options); // Generate the vlist, with the appropriate kerns + + var defaultRuleThickness = options.fontMetrics().defaultRuleThickness; + var vlist = buildCommon.makeVList({ + positionType: "top", + positionData: innerGroup.height, + children: [{ + type: "kern", + size: defaultRuleThickness + }, { + type: "elem", + elem: line + }, { + type: "kern", + size: 3 * defaultRuleThickness + }, { + type: "elem", + elem: innerGroup + }] + }, options); + return buildCommon.makeSpan(["mord", "underline"], [vlist], options); + }, + + mathmlBuilder(group, options) { + var operator = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode("\u203e")]); + operator.setAttribute("stretchy", "true"); + var node = new mathMLTree.MathNode("munder", [buildGroup(group.body, options), operator]); + node.setAttribute("accentunder", "true"); + return node; + } + +}); + +defineFunction({ + type: "vcenter", + names: ["\\vcenter"], + props: { + numArgs: 1, + argTypes: ["original"], + // In LaTeX, \vcenter can act only on a box. + allowedInText: false + }, + + handler(_ref, args) { + var { + parser + } = _ref; + return { + type: "vcenter", + mode: parser.mode, + body: args[0] + }; + }, + + htmlBuilder(group, options) { + var body = buildGroup$1(group.body, options); + var axisHeight = options.fontMetrics().axisHeight; + var dy = 0.5 * (body.height - axisHeight - (body.depth + axisHeight)); + return buildCommon.makeVList({ + positionType: "shift", + positionData: dy, + children: [{ + type: "elem", + elem: body + }] + }, options); + }, + + mathmlBuilder(group, options) { + // There is no way to do this in MathML. + // Write a class as a breadcrumb in case some post-processor wants + // to perform a vcenter adjustment. + return new mathMLTree.MathNode("mpadded", [buildGroup(group.body, options)], ["vcenter"]); + } + +}); + +defineFunction({ + type: "verb", + names: ["\\verb"], + props: { + numArgs: 0, + allowedInText: true + }, + + handler(context, args, optArgs) { + // \verb and \verb* are dealt with directly in Parser.js. + // If we end up here, it's because of a failure to match the two delimiters + // in the regex in Lexer.js. LaTeX raises the following error when \verb is + // terminated by end of line (or file). + throw new ParseError("\\verb ended by end of line instead of matching delimiter"); + }, + + htmlBuilder(group, options) { + var text = makeVerb(group); + var body = []; // \verb enters text mode and therefore is sized like \textstyle + + var newOptions = options.havingStyle(options.style.text()); + + for (var i = 0; i < text.length; i++) { + var c = text[i]; + + if (c === '~') { + c = '\\textasciitilde'; + } + + body.push(buildCommon.makeSymbol(c, "Typewriter-Regular", group.mode, newOptions, ["mord", "texttt"])); + } + + return buildCommon.makeSpan(["mord", "text"].concat(newOptions.sizingClasses(options)), buildCommon.tryCombineChars(body), newOptions); + }, + + mathmlBuilder(group, options) { + var text = new mathMLTree.TextNode(makeVerb(group)); + var node = new mathMLTree.MathNode("mtext", [text]); + node.setAttribute("mathvariant", "monospace"); + return node; + } + +}); +/** + * Converts verb group into body string. + * + * \verb* replaces each space with an open box \u2423 + * \verb replaces each space with a no-break space \xA0 + */ + +var makeVerb = group => group.body.replace(/ /g, group.star ? '\u2423' : '\xA0'); + +/** Include this to ensure that all functions are defined. */ +var functions = _functions; + +/** + * The Lexer class handles tokenizing the input in various ways. Since our + * parser expects us to be able to backtrack, the lexer allows lexing from any + * given starting point. + * + * Its main exposed function is the `lex` function, which takes a position to + * lex from and a type of token to lex. It defers to the appropriate `_innerLex` + * function. + * + * The various `_innerLex` functions perform the actual lexing of different + * kinds. + */ + +/* The following tokenRegex + * - matches typical whitespace (but not NBSP etc.) using its first group + * - does not match any control character \x00-\x1f except whitespace + * - does not match a bare backslash + * - matches any ASCII character except those just mentioned + * - does not match the BMP private use area \uE000-\uF8FF + * - does not match bare surrogate code units + * - matches any BMP character except for those just described + * - matches any valid Unicode surrogate pair + * - matches a backslash followed by one or more whitespace characters + * - matches a backslash followed by one or more letters then whitespace + * - matches a backslash followed by any BMP character + * Capturing groups: + * [1] regular whitespace + * [2] backslash followed by whitespace + * [3] anything else, which may include: + * [4] left character of \verb* + * [5] left character of \verb + * [6] backslash followed by word, excluding any trailing whitespace + * Just because the Lexer matches something doesn't mean it's valid input: + * If there is no matching function or symbol definition, the Parser will + * still reject the input. + */ +var spaceRegexString = "[ \r\n\t]"; +var controlWordRegexString = "\\\\[a-zA-Z@]+"; +var controlSymbolRegexString = "\\\\[^\uD800-\uDFFF]"; +var controlWordWhitespaceRegexString = "(" + controlWordRegexString + ")" + spaceRegexString + "*"; +var controlSpaceRegexString = "\\\\(\n|[ \r\t]+\n?)[ \r\t]*"; +var combiningDiacriticalMarkString = "[\u0300-\u036f]"; +var combiningDiacriticalMarksEndRegex = new RegExp(combiningDiacriticalMarkString + "+$"); +var tokenRegexString = "(" + spaceRegexString + "+)|" + ( // whitespace +controlSpaceRegexString + "|") + // \whitespace +"([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + ( // single codepoint +combiningDiacriticalMarkString + "*") + // ...plus accents +"|[\uD800-\uDBFF][\uDC00-\uDFFF]" + ( // surrogate pair +combiningDiacriticalMarkString + "*") + // ...plus accents +"|\\\\verb\\*([^]).*?\\4" + // \verb* +"|\\\\verb([^*a-zA-Z]).*?\\5" + ( // \verb unstarred +"|" + controlWordWhitespaceRegexString) + ( // \macroName + spaces +"|" + controlSymbolRegexString + ")"); // \\, \', etc. + +/** Main Lexer class */ + +class Lexer { + // Category codes. The lexer only supports comment characters (14) for now. + // MacroExpander additionally distinguishes active (13). + constructor(input, settings) { + this.input = void 0; + this.settings = void 0; + this.tokenRegex = void 0; + this.catcodes = void 0; + // Separate accents from characters + this.input = input; + this.settings = settings; + this.tokenRegex = new RegExp(tokenRegexString, 'g'); + this.catcodes = { + "%": 14, + // comment character + "~": 13 // active character + + }; + } + + setCatcode(char, code) { + this.catcodes[char] = code; + } + /** + * This function lexes a single token. + */ + + + lex() { + var input = this.input; + var pos = this.tokenRegex.lastIndex; + + if (pos === input.length) { + return new Token("EOF", new SourceLocation(this, pos, pos)); + } + + var match = this.tokenRegex.exec(input); + + if (match === null || match.index !== pos) { + throw new ParseError("Unexpected character: '" + input[pos] + "'", new Token(input[pos], new SourceLocation(this, pos, pos + 1))); + } + + var text = match[6] || match[3] || (match[2] ? "\\ " : " "); + + if (this.catcodes[text] === 14) { + // comment character + var nlIndex = input.indexOf('\n', this.tokenRegex.lastIndex); + + if (nlIndex === -1) { + this.tokenRegex.lastIndex = input.length; // EOF + + this.settings.reportNonstrict("commentAtEnd", "% comment has no terminating newline; LaTeX would " + "fail because of commenting the end of math mode (e.g. $)"); + } else { + this.tokenRegex.lastIndex = nlIndex + 1; + } + + return this.lex(); + } + + return new Token(text, new SourceLocation(this, pos, this.tokenRegex.lastIndex)); + } + +} + +/** + * A `Namespace` refers to a space of nameable things like macros or lengths, + * which can be `set` either globally or local to a nested group, using an + * undo stack similar to how TeX implements this functionality. + * Performance-wise, `get` and local `set` take constant time, while global + * `set` takes time proportional to the depth of group nesting. + */ +class Namespace { + /** + * Both arguments are optional. The first argument is an object of + * built-in mappings which never change. The second argument is an object + * of initial (global-level) mappings, which will constantly change + * according to any global/top-level `set`s done. + */ + constructor(builtins, globalMacros) { + if (builtins === void 0) { + builtins = {}; + } + + if (globalMacros === void 0) { + globalMacros = {}; + } + + this.current = void 0; + this.builtins = void 0; + this.undefStack = void 0; + this.current = globalMacros; + this.builtins = builtins; + this.undefStack = []; + } + /** + * Start a new nested group, affecting future local `set`s. + */ + + + beginGroup() { + this.undefStack.push({}); + } + /** + * End current nested group, restoring values before the group began. + */ + + + endGroup() { + if (this.undefStack.length === 0) { + throw new ParseError("Unbalanced namespace destruction: attempt " + "to pop global namespace; please report this as a bug"); + } + + var undefs = this.undefStack.pop(); + + for (var undef in undefs) { + if (undefs.hasOwnProperty(undef)) { + if (undefs[undef] == null) { + delete this.current[undef]; + } else { + this.current[undef] = undefs[undef]; + } + } + } + } + /** + * Ends all currently nested groups (if any), restoring values before the + * groups began. Useful in case of an error in the middle of parsing. + */ + + + endGroups() { + while (this.undefStack.length > 0) { + this.endGroup(); + } + } + /** + * Detect whether `name` has a definition. Equivalent to + * `get(name) != null`. + */ + + + has(name) { + return this.current.hasOwnProperty(name) || this.builtins.hasOwnProperty(name); + } + /** + * Get the current value of a name, or `undefined` if there is no value. + * + * Note: Do not use `if (namespace.get(...))` to detect whether a macro + * is defined, as the definition may be the empty string which evaluates + * to `false` in JavaScript. Use `if (namespace.get(...) != null)` or + * `if (namespace.has(...))`. + */ + + + get(name) { + if (this.current.hasOwnProperty(name)) { + return this.current[name]; + } else { + return this.builtins[name]; + } + } + /** + * Set the current value of a name, and optionally set it globally too. + * Local set() sets the current value and (when appropriate) adds an undo + * operation to the undo stack. Global set() may change the undo + * operation at every level, so takes time linear in their number. + * A value of undefined means to delete existing definitions. + */ + + + set(name, value, global) { + if (global === void 0) { + global = false; + } + + if (global) { + // Global set is equivalent to setting in all groups. Simulate this + // by destroying any undos currently scheduled for this name, + // and adding an undo with the *new* value (in case it later gets + // locally reset within this environment). + for (var i = 0; i < this.undefStack.length; i++) { + delete this.undefStack[i][name]; + } + + if (this.undefStack.length > 0) { + this.undefStack[this.undefStack.length - 1][name] = value; + } + } else { + // Undo this set at end of this group (possibly to `undefined`), + // unless an undo is already in place, in which case that older + // value is the correct one. + var top = this.undefStack[this.undefStack.length - 1]; + + if (top && !top.hasOwnProperty(name)) { + top[name] = this.current[name]; + } + } + + if (value == null) { + delete this.current[name]; + } else { + this.current[name] = value; + } + } + +} + +/** + * Predefined macros for KaTeX. + * This can be used to define some commands in terms of others. + */ +var macros = _macros; +// macro tools + +defineMacro("\\noexpand", function (context) { + // The expansion is the token itself; but that token is interpreted + // as if its meaning were ‘\relax’ if it is a control sequence that + // would ordinarily be expanded by TeX’s expansion rules. + var t = context.popToken(); + + if (context.isExpandable(t.text)) { + t.noexpand = true; + t.treatAsRelax = true; + } + + return { + tokens: [t], + numArgs: 0 + }; +}); +defineMacro("\\expandafter", function (context) { + // TeX first reads the token that comes immediately after \expandafter, + // without expanding it; let’s call this token t. Then TeX reads the + // token that comes after t (and possibly more tokens, if that token + // has an argument), replacing it by its expansion. Finally TeX puts + // t back in front of that expansion. + var t = context.popToken(); + context.expandOnce(true); // expand only an expandable token + + return { + tokens: [t], + numArgs: 0 + }; +}); // LaTeX's \@firstoftwo{#1}{#2} expands to #1, skipping #2 +// TeX source: \long\def\@firstoftwo#1#2{#1} + +defineMacro("\\@firstoftwo", function (context) { + var args = context.consumeArgs(2); + return { + tokens: args[0], + numArgs: 0 + }; +}); // LaTeX's \@secondoftwo{#1}{#2} expands to #2, skipping #1 +// TeX source: \long\def\@secondoftwo#1#2{#2} + +defineMacro("\\@secondoftwo", function (context) { + var args = context.consumeArgs(2); + return { + tokens: args[1], + numArgs: 0 + }; +}); // LaTeX's \@ifnextchar{#1}{#2}{#3} looks ahead to the next (unexpanded) +// symbol that isn't a space, consuming any spaces but not consuming the +// first nonspace character. If that nonspace character matches #1, then +// the macro expands to #2; otherwise, it expands to #3. + +defineMacro("\\@ifnextchar", function (context) { + var args = context.consumeArgs(3); // symbol, if, else + + context.consumeSpaces(); + var nextToken = context.future(); + + if (args[0].length === 1 && args[0][0].text === nextToken.text) { + return { + tokens: args[1], + numArgs: 0 + }; + } else { + return { + tokens: args[2], + numArgs: 0 + }; + } +}); // LaTeX's \@ifstar{#1}{#2} looks ahead to the next (unexpanded) symbol. +// If it is `*`, then it consumes the symbol, and the macro expands to #1; +// otherwise, the macro expands to #2 (without consuming the symbol). +// TeX source: \def\@ifstar#1{\@ifnextchar *{\@firstoftwo{#1}}} + +defineMacro("\\@ifstar", "\\@ifnextchar *{\\@firstoftwo{#1}}"); // LaTeX's \TextOrMath{#1}{#2} expands to #1 in text mode, #2 in math mode + +defineMacro("\\TextOrMath", function (context) { + var args = context.consumeArgs(2); + + if (context.mode === 'text') { + return { + tokens: args[0], + numArgs: 0 + }; + } else { + return { + tokens: args[1], + numArgs: 0 + }; + } +}); // Lookup table for parsing numbers in base 8 through 16 + +var digitToNumber = { + "0": 0, + "1": 1, + "2": 2, + "3": 3, + "4": 4, + "5": 5, + "6": 6, + "7": 7, + "8": 8, + "9": 9, + "a": 10, + "A": 10, + "b": 11, + "B": 11, + "c": 12, + "C": 12, + "d": 13, + "D": 13, + "e": 14, + "E": 14, + "f": 15, + "F": 15 +}; // TeX \char makes a literal character (catcode 12) using the following forms: +// (see The TeXBook, p. 43) +// \char123 -- decimal +// \char'123 -- octal +// \char"123 -- hex +// \char`x -- character that can be written (i.e. isn't active) +// \char`\x -- character that cannot be written (e.g. %) +// These all refer to characters from the font, so we turn them into special +// calls to a function \@char dealt with in the Parser. + +defineMacro("\\char", function (context) { + var token = context.popToken(); + var base; + var number = ''; + + if (token.text === "'") { + base = 8; + token = context.popToken(); + } else if (token.text === '"') { + base = 16; + token = context.popToken(); + } else if (token.text === "`") { + token = context.popToken(); + + if (token.text[0] === "\\") { + number = token.text.charCodeAt(1); + } else if (token.text === "EOF") { + throw new ParseError("\\char` missing argument"); + } else { + number = token.text.charCodeAt(0); + } + } else { + base = 10; + } + + if (base) { + // Parse a number in the given base, starting with first `token`. + number = digitToNumber[token.text]; + + if (number == null || number >= base) { + throw new ParseError("Invalid base-" + base + " digit " + token.text); + } + + var digit; + + while ((digit = digitToNumber[context.future().text]) != null && digit < base) { + number *= base; + number += digit; + context.popToken(); + } + } + + return "\\@char{" + number + "}"; +}); // \newcommand{\macro}[args]{definition} +// \renewcommand{\macro}[args]{definition} +// TODO: Optional arguments: \newcommand{\macro}[args][default]{definition} + +var newcommand = (context, existsOK, nonexistsOK) => { + var arg = context.consumeArg().tokens; + + if (arg.length !== 1) { + throw new ParseError("\\newcommand's first argument must be a macro name"); + } + + var name = arg[0].text; + var exists = context.isDefined(name); + + if (exists && !existsOK) { + throw new ParseError("\\newcommand{" + name + "} attempting to redefine " + (name + "; use \\renewcommand")); + } + + if (!exists && !nonexistsOK) { + throw new ParseError("\\renewcommand{" + name + "} when command " + name + " " + "does not yet exist; use \\newcommand"); + } + + var numArgs = 0; + arg = context.consumeArg().tokens; + + if (arg.length === 1 && arg[0].text === "[") { + var argText = ''; + var token = context.expandNextToken(); + + while (token.text !== "]" && token.text !== "EOF") { + // TODO: Should properly expand arg, e.g., ignore {}s + argText += token.text; + token = context.expandNextToken(); + } + + if (!argText.match(/^\s*[0-9]+\s*$/)) { + throw new ParseError("Invalid number of arguments: " + argText); + } + + numArgs = parseInt(argText); + arg = context.consumeArg().tokens; + } // Final arg is the expansion of the macro + + + context.macros.set(name, { + tokens: arg, + numArgs + }); + return ''; +}; + +defineMacro("\\newcommand", context => newcommand(context, false, true)); +defineMacro("\\renewcommand", context => newcommand(context, true, false)); +defineMacro("\\providecommand", context => newcommand(context, true, true)); // terminal (console) tools + +defineMacro("\\message", context => { + var arg = context.consumeArgs(1)[0]; // eslint-disable-next-line no-console + + console.log(arg.reverse().map(token => token.text).join("")); + return ''; +}); +defineMacro("\\errmessage", context => { + var arg = context.consumeArgs(1)[0]; // eslint-disable-next-line no-console + + console.error(arg.reverse().map(token => token.text).join("")); + return ''; +}); +defineMacro("\\show", context => { + var tok = context.popToken(); + var name = tok.text; // eslint-disable-next-line no-console + + console.log(tok, context.macros.get(name), functions[name], symbols.math[name], symbols.text[name]); + return ''; +}); ////////////////////////////////////////////////////////////////////// +// Grouping +// \let\bgroup={ \let\egroup=} + +defineMacro("\\bgroup", "{"); +defineMacro("\\egroup", "}"); // Symbols from latex.ltx: +// \def~{\nobreakspace{}} +// \def\lq{`} +// \def\rq{'} +// \def \aa {\r a} +// \def \AA {\r A} + +defineMacro("~", "\\nobreakspace"); +defineMacro("\\lq", "`"); +defineMacro("\\rq", "'"); +defineMacro("\\aa", "\\r a"); +defineMacro("\\AA", "\\r A"); // Copyright (C) and registered (R) symbols. Use raw symbol in MathML. +// \DeclareTextCommandDefault{\textcopyright}{\textcircled{c}} +// \DeclareTextCommandDefault{\textregistered}{\textcircled{% +// \check@mathfonts\fontsize\sf@size\z@\math@fontsfalse\selectfont R}} +// \DeclareRobustCommand{\copyright}{% +// \ifmmode{\nfss@text{\textcopyright}}\else\textcopyright\fi} + +defineMacro("\\textcopyright", "\\html@mathml{\\textcircled{c}}{\\char`©}"); +defineMacro("\\copyright", "\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}"); +defineMacro("\\textregistered", "\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`®}"); // Characters omitted from Unicode range 1D400–1D7FF + +defineMacro("\u212C", "\\mathscr{B}"); // script + +defineMacro("\u2130", "\\mathscr{E}"); +defineMacro("\u2131", "\\mathscr{F}"); +defineMacro("\u210B", "\\mathscr{H}"); +defineMacro("\u2110", "\\mathscr{I}"); +defineMacro("\u2112", "\\mathscr{L}"); +defineMacro("\u2133", "\\mathscr{M}"); +defineMacro("\u211B", "\\mathscr{R}"); +defineMacro("\u212D", "\\mathfrak{C}"); // Fraktur + +defineMacro("\u210C", "\\mathfrak{H}"); +defineMacro("\u2128", "\\mathfrak{Z}"); // Define \Bbbk with a macro that works in both HTML and MathML. + +defineMacro("\\Bbbk", "\\Bbb{k}"); // Unicode middle dot +// The KaTeX fonts do not contain U+00B7. Instead, \cdotp displays +// the dot at U+22C5 and gives it punct spacing. + +defineMacro("\u00b7", "\\cdotp"); // \llap and \rlap render their contents in text mode + +defineMacro("\\llap", "\\mathllap{\\textrm{#1}}"); +defineMacro("\\rlap", "\\mathrlap{\\textrm{#1}}"); +defineMacro("\\clap", "\\mathclap{\\textrm{#1}}"); // \mathstrut from the TeXbook, p 360 + +defineMacro("\\mathstrut", "\\vphantom{(}"); // \underbar from TeXbook p 353 + +defineMacro("\\underbar", "\\underline{\\text{#1}}"); // \not is defined by base/fontmath.ltx via +// \DeclareMathSymbol{\not}{\mathrel}{symbols}{"36} +// It's thus treated like a \mathrel, but defined by a symbol that has zero +// width but extends to the right. We use \rlap to get that spacing. +// For MathML we write U+0338 here. buildMathML.js will then do the overlay. + +defineMacro("\\not", '\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'); // Negated symbols from base/fontmath.ltx: +// \def\neq{\not=} \let\ne=\neq +// \DeclareRobustCommand +// \notin{\mathrel{\m@th\mathpalette\c@ncel\in}} +// \def\c@ncel#1#2{\m@th\ooalign{$\hfil#1\mkern1mu/\hfil$\crcr$#1#2$}} + +defineMacro("\\neq", "\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`≠}}"); +defineMacro("\\ne", "\\neq"); +defineMacro("\u2260", "\\neq"); +defineMacro("\\notin", "\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}" + "{\\mathrel{\\char`∉}}"); +defineMacro("\u2209", "\\notin"); // Unicode stacked relations + +defineMacro("\u2258", "\\html@mathml{" + "\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}" + "}{\\mathrel{\\char`\u2258}}"); +defineMacro("\u2259", "\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}"); +defineMacro("\u225A", "\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225A}}"); +defineMacro("\u225B", "\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}" + "{\\mathrel{\\char`\u225B}}"); +defineMacro("\u225D", "\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}" + "{\\mathrel{\\char`\u225D}}"); +defineMacro("\u225E", "\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}" + "{\\mathrel{\\char`\u225E}}"); +defineMacro("\u225F", "\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225F}}"); // Misc Unicode + +defineMacro("\u27C2", "\\perp"); +defineMacro("\u203C", "\\mathclose{!\\mkern-0.8mu!}"); +defineMacro("\u220C", "\\notni"); +defineMacro("\u231C", "\\ulcorner"); +defineMacro("\u231D", "\\urcorner"); +defineMacro("\u231E", "\\llcorner"); +defineMacro("\u231F", "\\lrcorner"); +defineMacro("\u00A9", "\\copyright"); +defineMacro("\u00AE", "\\textregistered"); +defineMacro("\uFE0F", "\\textregistered"); // The KaTeX fonts have corners at codepoints that don't match Unicode. +// For MathML purposes, use the Unicode code point. + +defineMacro("\\ulcorner", "\\html@mathml{\\@ulcorner}{\\mathop{\\char\"231c}}"); +defineMacro("\\urcorner", "\\html@mathml{\\@urcorner}{\\mathop{\\char\"231d}}"); +defineMacro("\\llcorner", "\\html@mathml{\\@llcorner}{\\mathop{\\char\"231e}}"); +defineMacro("\\lrcorner", "\\html@mathml{\\@lrcorner}{\\mathop{\\char\"231f}}"); ////////////////////////////////////////////////////////////////////// +// LaTeX_2ε +// \vdots{\vbox{\baselineskip4\p@ \lineskiplimit\z@ +// \kern6\p@\hbox{.}\hbox{.}\hbox{.}}} +// We'll call \varvdots, which gets a glyph from symbols.js. +// The zero-width rule gets us an equivalent to the vertical 6pt kern. + +defineMacro("\\vdots", "\\mathord{\\varvdots\\rule{0pt}{15pt}}"); +defineMacro("\u22ee", "\\vdots"); ////////////////////////////////////////////////////////////////////// +// amsmath.sty +// http://mirrors.concertpass.com/tex-archive/macros/latex/required/amsmath/amsmath.pdf +// Italic Greek capital letters. AMS defines these with \DeclareMathSymbol, +// but they are equivalent to \mathit{\Letter}. + +defineMacro("\\varGamma", "\\mathit{\\Gamma}"); +defineMacro("\\varDelta", "\\mathit{\\Delta}"); +defineMacro("\\varTheta", "\\mathit{\\Theta}"); +defineMacro("\\varLambda", "\\mathit{\\Lambda}"); +defineMacro("\\varXi", "\\mathit{\\Xi}"); +defineMacro("\\varPi", "\\mathit{\\Pi}"); +defineMacro("\\varSigma", "\\mathit{\\Sigma}"); +defineMacro("\\varUpsilon", "\\mathit{\\Upsilon}"); +defineMacro("\\varPhi", "\\mathit{\\Phi}"); +defineMacro("\\varPsi", "\\mathit{\\Psi}"); +defineMacro("\\varOmega", "\\mathit{\\Omega}"); //\newcommand{\substack}[1]{\subarray{c}#1\endsubarray} + +defineMacro("\\substack", "\\begin{subarray}{c}#1\\end{subarray}"); // \renewcommand{\colon}{\nobreak\mskip2mu\mathpunct{}\nonscript +// \mkern-\thinmuskip{:}\mskip6muplus1mu\relax} + +defineMacro("\\colon", "\\nobreak\\mskip2mu\\mathpunct{}" + "\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax"); // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}} + +defineMacro("\\boxed", "\\fbox{$\\displaystyle{#1}$}"); // \def\iff{\DOTSB\;\Longleftrightarrow\;} +// \def\implies{\DOTSB\;\Longrightarrow\;} +// \def\impliedby{\DOTSB\;\Longleftarrow\;} + +defineMacro("\\iff", "\\DOTSB\\;\\Longleftrightarrow\\;"); +defineMacro("\\implies", "\\DOTSB\\;\\Longrightarrow\\;"); +defineMacro("\\impliedby", "\\DOTSB\\;\\Longleftarrow\\;"); // AMSMath's automatic \dots, based on \mdots@@ macro. + +var dotsByToken = { + ',': '\\dotsc', + '\\not': '\\dotsb', + // \keybin@ checks for the following: + '+': '\\dotsb', + '=': '\\dotsb', + '<': '\\dotsb', + '>': '\\dotsb', + '-': '\\dotsb', + '*': '\\dotsb', + ':': '\\dotsb', + // Symbols whose definition starts with \DOTSB: + '\\DOTSB': '\\dotsb', + '\\coprod': '\\dotsb', + '\\bigvee': '\\dotsb', + '\\bigwedge': '\\dotsb', + '\\biguplus': '\\dotsb', + '\\bigcap': '\\dotsb', + '\\bigcup': '\\dotsb', + '\\prod': '\\dotsb', + '\\sum': '\\dotsb', + '\\bigotimes': '\\dotsb', + '\\bigoplus': '\\dotsb', + '\\bigodot': '\\dotsb', + '\\bigsqcup': '\\dotsb', + '\\And': '\\dotsb', + '\\longrightarrow': '\\dotsb', + '\\Longrightarrow': '\\dotsb', + '\\longleftarrow': '\\dotsb', + '\\Longleftarrow': '\\dotsb', + '\\longleftrightarrow': '\\dotsb', + '\\Longleftrightarrow': '\\dotsb', + '\\mapsto': '\\dotsb', + '\\longmapsto': '\\dotsb', + '\\hookrightarrow': '\\dotsb', + '\\doteq': '\\dotsb', + // Symbols whose definition starts with \mathbin: + '\\mathbin': '\\dotsb', + // Symbols whose definition starts with \mathrel: + '\\mathrel': '\\dotsb', + '\\relbar': '\\dotsb', + '\\Relbar': '\\dotsb', + '\\xrightarrow': '\\dotsb', + '\\xleftarrow': '\\dotsb', + // Symbols whose definition starts with \DOTSI: + '\\DOTSI': '\\dotsi', + '\\int': '\\dotsi', + '\\oint': '\\dotsi', + '\\iint': '\\dotsi', + '\\iiint': '\\dotsi', + '\\iiiint': '\\dotsi', + '\\idotsint': '\\dotsi', + // Symbols whose definition starts with \DOTSX: + '\\DOTSX': '\\dotsx' +}; +defineMacro("\\dots", function (context) { + // TODO: If used in text mode, should expand to \textellipsis. + // However, in KaTeX, \textellipsis and \ldots behave the same + // (in text mode), and it's unlikely we'd see any of the math commands + // that affect the behavior of \dots when in text mode. So fine for now + // (until we support \ifmmode ... \else ... \fi). + var thedots = '\\dotso'; + var next = context.expandAfterFuture().text; + + if (next in dotsByToken) { + thedots = dotsByToken[next]; + } else if (next.slice(0, 4) === '\\not') { + thedots = '\\dotsb'; + } else if (next in symbols.math) { + if (utils.contains(['bin', 'rel'], symbols.math[next].group)) { + thedots = '\\dotsb'; + } + } + + return thedots; +}); +var spaceAfterDots = { + // \rightdelim@ checks for the following: + ')': true, + ']': true, + '\\rbrack': true, + '\\}': true, + '\\rbrace': true, + '\\rangle': true, + '\\rceil': true, + '\\rfloor': true, + '\\rgroup': true, + '\\rmoustache': true, + '\\right': true, + '\\bigr': true, + '\\biggr': true, + '\\Bigr': true, + '\\Biggr': true, + // \extra@ also tests for the following: + '$': true, + // \extrap@ checks for the following: + ';': true, + '.': true, + ',': true +}; +defineMacro("\\dotso", function (context) { + var next = context.future().text; + + if (next in spaceAfterDots) { + return "\\ldots\\,"; + } else { + return "\\ldots"; + } +}); +defineMacro("\\dotsc", function (context) { + var next = context.future().text; // \dotsc uses \extra@ but not \extrap@, instead specially checking for + // ';' and '.', but doesn't check for ','. + + if (next in spaceAfterDots && next !== ',') { + return "\\ldots\\,"; + } else { + return "\\ldots"; + } +}); +defineMacro("\\cdots", function (context) { + var next = context.future().text; + + if (next in spaceAfterDots) { + return "\\@cdots\\,"; + } else { + return "\\@cdots"; + } +}); +defineMacro("\\dotsb", "\\cdots"); +defineMacro("\\dotsm", "\\cdots"); +defineMacro("\\dotsi", "\\!\\cdots"); // amsmath doesn't actually define \dotsx, but \dots followed by a macro +// starting with \DOTSX implies \dotso, and then \extra@ detects this case +// and forces the added `\,`. + +defineMacro("\\dotsx", "\\ldots\\,"); // \let\DOTSI\relax +// \let\DOTSB\relax +// \let\DOTSX\relax + +defineMacro("\\DOTSI", "\\relax"); +defineMacro("\\DOTSB", "\\relax"); +defineMacro("\\DOTSX", "\\relax"); // Spacing, based on amsmath.sty's override of LaTeX defaults +// \DeclareRobustCommand{\tmspace}[3]{% +// \ifmmode\mskip#1#2\else\kern#1#3\fi\relax} + +defineMacro("\\tmspace", "\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"); // \renewcommand{\,}{\tmspace+\thinmuskip{.1667em}} +// TODO: math mode should use \thinmuskip + +defineMacro("\\,", "\\tmspace+{3mu}{.1667em}"); // \let\thinspace\, + +defineMacro("\\thinspace", "\\,"); // \def\>{\mskip\medmuskip} +// \renewcommand{\:}{\tmspace+\medmuskip{.2222em}} +// TODO: \> and math mode of \: should use \medmuskip = 4mu plus 2mu minus 4mu + +defineMacro("\\>", "\\mskip{4mu}"); +defineMacro("\\:", "\\tmspace+{4mu}{.2222em}"); // \let\medspace\: + +defineMacro("\\medspace", "\\:"); // \renewcommand{\;}{\tmspace+\thickmuskip{.2777em}} +// TODO: math mode should use \thickmuskip = 5mu plus 5mu + +defineMacro("\\;", "\\tmspace+{5mu}{.2777em}"); // \let\thickspace\; + +defineMacro("\\thickspace", "\\;"); // \renewcommand{\!}{\tmspace-\thinmuskip{.1667em}} +// TODO: math mode should use \thinmuskip + +defineMacro("\\!", "\\tmspace-{3mu}{.1667em}"); // \let\negthinspace\! + +defineMacro("\\negthinspace", "\\!"); // \newcommand{\negmedspace}{\tmspace-\medmuskip{.2222em}} +// TODO: math mode should use \medmuskip + +defineMacro("\\negmedspace", "\\tmspace-{4mu}{.2222em}"); // \newcommand{\negthickspace}{\tmspace-\thickmuskip{.2777em}} +// TODO: math mode should use \thickmuskip + +defineMacro("\\negthickspace", "\\tmspace-{5mu}{.277em}"); // \def\enspace{\kern.5em } + +defineMacro("\\enspace", "\\kern.5em "); // \def\enskip{\hskip.5em\relax} + +defineMacro("\\enskip", "\\hskip.5em\\relax"); // \def\quad{\hskip1em\relax} + +defineMacro("\\quad", "\\hskip1em\\relax"); // \def\qquad{\hskip2em\relax} + +defineMacro("\\qquad", "\\hskip2em\\relax"); // \tag@in@display form of \tag + +defineMacro("\\tag", "\\@ifstar\\tag@literal\\tag@paren"); +defineMacro("\\tag@paren", "\\tag@literal{({#1})}"); +defineMacro("\\tag@literal", context => { + if (context.macros.get("\\df@tag")) { + throw new ParseError("Multiple \\tag"); + } + + return "\\gdef\\df@tag{\\text{#1}}"; +}); // \renewcommand{\bmod}{\nonscript\mskip-\medmuskip\mkern5mu\mathbin +// {\operator@font mod}\penalty900 +// \mkern5mu\nonscript\mskip-\medmuskip} +// \newcommand{\pod}[1]{\allowbreak +// \if@display\mkern18mu\else\mkern8mu\fi(#1)} +// \renewcommand{\pmod}[1]{\pod{{\operator@font mod}\mkern6mu#1}} +// \newcommand{\mod}[1]{\allowbreak\if@display\mkern18mu +// \else\mkern12mu\fi{\operator@font mod}\,\,#1} +// TODO: math mode should use \medmuskip = 4mu plus 2mu minus 4mu + +defineMacro("\\bmod", "\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}" + "\\mathbin{\\rm mod}" + "\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"); +defineMacro("\\pod", "\\allowbreak" + "\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"); +defineMacro("\\pmod", "\\pod{{\\rm mod}\\mkern6mu#1}"); +defineMacro("\\mod", "\\allowbreak" + "\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}" + "{\\rm mod}\\,\\,#1"); ////////////////////////////////////////////////////////////////////// +// LaTeX source2e +// \expandafter\let\expandafter\@normalcr +// \csname\expandafter\@gobble\string\\ \endcsname +// \DeclareRobustCommand\newline{\@normalcr\relax} + +defineMacro("\\newline", "\\\\\\relax"); // \def\TeX{T\kern-.1667em\lower.5ex\hbox{E}\kern-.125emX\@} +// TODO: Doesn't normally work in math mode because \@ fails. KaTeX doesn't +// support \@ yet, so that's omitted, and we add \text so that the result +// doesn't look funny in math mode. + +defineMacro("\\TeX", "\\textrm{\\html@mathml{" + "T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX" + "}{TeX}}"); // \DeclareRobustCommand{\LaTeX}{L\kern-.36em% +// {\sbox\z@ T% +// \vbox to\ht\z@{\hbox{\check@mathfonts +// \fontsize\sf@size\z@ +// \math@fontsfalse\selectfont +// A}% +// \vss}% +// }% +// \kern-.15em% +// \TeX} +// This code aligns the top of the A with the T (from the perspective of TeX's +// boxes, though visually the A appears to extend above slightly). +// We compute the corresponding \raisebox when A is rendered in \normalsize +// \scriptstyle, which has a scale factor of 0.7 (see Options.js). + +var latexRaiseA = makeEm(fontMetricsData['Main-Regular']["T".charCodeAt(0)][1] - 0.7 * fontMetricsData['Main-Regular']["A".charCodeAt(0)][1]); +defineMacro("\\LaTeX", "\\textrm{\\html@mathml{" + ("L\\kern-.36em\\raisebox{" + latexRaiseA + "}{\\scriptstyle A}") + "\\kern-.15em\\TeX}{LaTeX}}"); // New KaTeX logo based on tweaking LaTeX logo + +defineMacro("\\KaTeX", "\\textrm{\\html@mathml{" + ("K\\kern-.17em\\raisebox{" + latexRaiseA + "}{\\scriptstyle A}") + "\\kern-.15em\\TeX}{KaTeX}}"); // \DeclareRobustCommand\hspace{\@ifstar\@hspacer\@hspace} +// \def\@hspace#1{\hskip #1\relax} +// \def\@hspacer#1{\vrule \@width\z@\nobreak +// \hskip #1\hskip \z@skip} + +defineMacro("\\hspace", "\\@ifstar\\@hspacer\\@hspace"); +defineMacro("\\@hspace", "\\hskip #1\\relax"); +defineMacro("\\@hspacer", "\\rule{0pt}{0pt}\\hskip #1\\relax"); ////////////////////////////////////////////////////////////////////// +// mathtools.sty +//\providecommand\ordinarycolon{:} + +defineMacro("\\ordinarycolon", ":"); //\def\vcentcolon{\mathrel{\mathop\ordinarycolon}} +//TODO(edemaine): Not yet centered. Fix via \raisebox or #726 + +defineMacro("\\vcentcolon", "\\mathrel{\\mathop\\ordinarycolon}"); // \providecommand*\dblcolon{\vcentcolon\mathrel{\mkern-.9mu}\vcentcolon} + +defineMacro("\\dblcolon", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}" + "{\\mathop{\\char\"2237}}"); // \providecommand*\coloneqq{\vcentcolon\mathrel{\mkern-1.2mu}=} + +defineMacro("\\coloneqq", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}" + "{\\mathop{\\char\"2254}}"); // ≔ +// \providecommand*\Coloneqq{\dblcolon\mathrel{\mkern-1.2mu}=} + +defineMacro("\\Coloneqq", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}" + "{\\mathop{\\char\"2237\\char\"3d}}"); // \providecommand*\coloneq{\vcentcolon\mathrel{\mkern-1.2mu}\mathrel{-}} + +defineMacro("\\coloneq", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}" + "{\\mathop{\\char\"3a\\char\"2212}}"); // \providecommand*\Coloneq{\dblcolon\mathrel{\mkern-1.2mu}\mathrel{-}} + +defineMacro("\\Coloneq", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}" + "{\\mathop{\\char\"2237\\char\"2212}}"); // \providecommand*\eqqcolon{=\mathrel{\mkern-1.2mu}\vcentcolon} + +defineMacro("\\eqqcolon", "\\html@mathml{" + "\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}" + "{\\mathop{\\char\"2255}}"); // ≕ +// \providecommand*\Eqqcolon{=\mathrel{\mkern-1.2mu}\dblcolon} + +defineMacro("\\Eqqcolon", "\\html@mathml{" + "\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}" + "{\\mathop{\\char\"3d\\char\"2237}}"); // \providecommand*\eqcolon{\mathrel{-}\mathrel{\mkern-1.2mu}\vcentcolon} + +defineMacro("\\eqcolon", "\\html@mathml{" + "\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}" + "{\\mathop{\\char\"2239}}"); // \providecommand*\Eqcolon{\mathrel{-}\mathrel{\mkern-1.2mu}\dblcolon} + +defineMacro("\\Eqcolon", "\\html@mathml{" + "\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}" + "{\\mathop{\\char\"2212\\char\"2237}}"); // \providecommand*\colonapprox{\vcentcolon\mathrel{\mkern-1.2mu}\approx} + +defineMacro("\\colonapprox", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}" + "{\\mathop{\\char\"3a\\char\"2248}}"); // \providecommand*\Colonapprox{\dblcolon\mathrel{\mkern-1.2mu}\approx} + +defineMacro("\\Colonapprox", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}" + "{\\mathop{\\char\"2237\\char\"2248}}"); // \providecommand*\colonsim{\vcentcolon\mathrel{\mkern-1.2mu}\sim} + +defineMacro("\\colonsim", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}" + "{\\mathop{\\char\"3a\\char\"223c}}"); // \providecommand*\Colonsim{\dblcolon\mathrel{\mkern-1.2mu}\sim} + +defineMacro("\\Colonsim", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}" + "{\\mathop{\\char\"2237\\char\"223c}}"); // Some Unicode characters are implemented with macros to mathtools functions. + +defineMacro("\u2237", "\\dblcolon"); // :: + +defineMacro("\u2239", "\\eqcolon"); // -: + +defineMacro("\u2254", "\\coloneqq"); // := + +defineMacro("\u2255", "\\eqqcolon"); // =: + +defineMacro("\u2A74", "\\Coloneqq"); // ::= +////////////////////////////////////////////////////////////////////// +// colonequals.sty +// Alternate names for mathtools's macros: + +defineMacro("\\ratio", "\\vcentcolon"); +defineMacro("\\coloncolon", "\\dblcolon"); +defineMacro("\\colonequals", "\\coloneqq"); +defineMacro("\\coloncolonequals", "\\Coloneqq"); +defineMacro("\\equalscolon", "\\eqqcolon"); +defineMacro("\\equalscoloncolon", "\\Eqqcolon"); +defineMacro("\\colonminus", "\\coloneq"); +defineMacro("\\coloncolonminus", "\\Coloneq"); +defineMacro("\\minuscolon", "\\eqcolon"); +defineMacro("\\minuscoloncolon", "\\Eqcolon"); // \colonapprox name is same in mathtools and colonequals. + +defineMacro("\\coloncolonapprox", "\\Colonapprox"); // \colonsim name is same in mathtools and colonequals. + +defineMacro("\\coloncolonsim", "\\Colonsim"); // Additional macros, implemented by analogy with mathtools definitions: + +defineMacro("\\simcolon", "\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"); +defineMacro("\\simcoloncolon", "\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"); +defineMacro("\\approxcolon", "\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"); +defineMacro("\\approxcoloncolon", "\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"); // Present in newtxmath, pxfonts and txfonts + +defineMacro("\\notni", "\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220C}}"); +defineMacro("\\limsup", "\\DOTSB\\operatorname*{lim\\,sup}"); +defineMacro("\\liminf", "\\DOTSB\\operatorname*{lim\\,inf}"); ////////////////////////////////////////////////////////////////////// +// From amsopn.sty + +defineMacro("\\injlim", "\\DOTSB\\operatorname*{inj\\,lim}"); +defineMacro("\\projlim", "\\DOTSB\\operatorname*{proj\\,lim}"); +defineMacro("\\varlimsup", "\\DOTSB\\operatorname*{\\overline{lim}}"); +defineMacro("\\varliminf", "\\DOTSB\\operatorname*{\\underline{lim}}"); +defineMacro("\\varinjlim", "\\DOTSB\\operatorname*{\\underrightarrow{lim}}"); +defineMacro("\\varprojlim", "\\DOTSB\\operatorname*{\\underleftarrow{lim}}"); ////////////////////////////////////////////////////////////////////// +// MathML alternates for KaTeX glyphs in the Unicode private area + +defineMacro("\\gvertneqq", "\\html@mathml{\\@gvertneqq}{\u2269}"); +defineMacro("\\lvertneqq", "\\html@mathml{\\@lvertneqq}{\u2268}"); +defineMacro("\\ngeqq", "\\html@mathml{\\@ngeqq}{\u2271}"); +defineMacro("\\ngeqslant", "\\html@mathml{\\@ngeqslant}{\u2271}"); +defineMacro("\\nleqq", "\\html@mathml{\\@nleqq}{\u2270}"); +defineMacro("\\nleqslant", "\\html@mathml{\\@nleqslant}{\u2270}"); +defineMacro("\\nshortmid", "\\html@mathml{\\@nshortmid}{∤}"); +defineMacro("\\nshortparallel", "\\html@mathml{\\@nshortparallel}{∦}"); +defineMacro("\\nsubseteqq", "\\html@mathml{\\@nsubseteqq}{\u2288}"); +defineMacro("\\nsupseteqq", "\\html@mathml{\\@nsupseteqq}{\u2289}"); +defineMacro("\\varsubsetneq", "\\html@mathml{\\@varsubsetneq}{⊊}"); +defineMacro("\\varsubsetneqq", "\\html@mathml{\\@varsubsetneqq}{⫋}"); +defineMacro("\\varsupsetneq", "\\html@mathml{\\@varsupsetneq}{⊋}"); +defineMacro("\\varsupsetneqq", "\\html@mathml{\\@varsupsetneqq}{⫌}"); +defineMacro("\\imath", "\\html@mathml{\\@imath}{\u0131}"); +defineMacro("\\jmath", "\\html@mathml{\\@jmath}{\u0237}"); ////////////////////////////////////////////////////////////////////// +// stmaryrd and semantic +// The stmaryrd and semantic packages render the next four items by calling a +// glyph. Those glyphs do not exist in the KaTeX fonts. Hence the macros. + +defineMacro("\\llbracket", "\\html@mathml{" + "\\mathopen{[\\mkern-3.2mu[}}" + "{\\mathopen{\\char`\u27e6}}"); +defineMacro("\\rrbracket", "\\html@mathml{" + "\\mathclose{]\\mkern-3.2mu]}}" + "{\\mathclose{\\char`\u27e7}}"); +defineMacro("\u27e6", "\\llbracket"); // blackboard bold [ + +defineMacro("\u27e7", "\\rrbracket"); // blackboard bold ] + +defineMacro("\\lBrace", "\\html@mathml{" + "\\mathopen{\\{\\mkern-3.2mu[}}" + "{\\mathopen{\\char`\u2983}}"); +defineMacro("\\rBrace", "\\html@mathml{" + "\\mathclose{]\\mkern-3.2mu\\}}}" + "{\\mathclose{\\char`\u2984}}"); +defineMacro("\u2983", "\\lBrace"); // blackboard bold { + +defineMacro("\u2984", "\\rBrace"); // blackboard bold } +// TODO: Create variable sized versions of the last two items. I believe that +// will require new font glyphs. +// The stmaryrd function `\minuso` provides a "Plimsoll" symbol that +// superimposes the characters \circ and \mathminus. Used in chemistry. + +defineMacro("\\minuso", "\\mathbin{\\html@mathml{" + "{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}" + "{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}" + "{\\char`⦵}}"); +defineMacro("⦵", "\\minuso"); ////////////////////////////////////////////////////////////////////// +// texvc.sty +// The texvc package contains macros available in mediawiki pages. +// We omit the functions deprecated at +// https://en.wikipedia.org/wiki/Help:Displaying_a_formula#Deprecated_syntax +// We also omit texvc's \O, which conflicts with \text{\O} + +defineMacro("\\darr", "\\downarrow"); +defineMacro("\\dArr", "\\Downarrow"); +defineMacro("\\Darr", "\\Downarrow"); +defineMacro("\\lang", "\\langle"); +defineMacro("\\rang", "\\rangle"); +defineMacro("\\uarr", "\\uparrow"); +defineMacro("\\uArr", "\\Uparrow"); +defineMacro("\\Uarr", "\\Uparrow"); +defineMacro("\\N", "\\mathbb{N}"); +defineMacro("\\R", "\\mathbb{R}"); +defineMacro("\\Z", "\\mathbb{Z}"); +defineMacro("\\alef", "\\aleph"); +defineMacro("\\alefsym", "\\aleph"); +defineMacro("\\Alpha", "\\mathrm{A}"); +defineMacro("\\Beta", "\\mathrm{B}"); +defineMacro("\\bull", "\\bullet"); +defineMacro("\\Chi", "\\mathrm{X}"); +defineMacro("\\clubs", "\\clubsuit"); +defineMacro("\\cnums", "\\mathbb{C}"); +defineMacro("\\Complex", "\\mathbb{C}"); +defineMacro("\\Dagger", "\\ddagger"); +defineMacro("\\diamonds", "\\diamondsuit"); +defineMacro("\\empty", "\\emptyset"); +defineMacro("\\Epsilon", "\\mathrm{E}"); +defineMacro("\\Eta", "\\mathrm{H}"); +defineMacro("\\exist", "\\exists"); +defineMacro("\\harr", "\\leftrightarrow"); +defineMacro("\\hArr", "\\Leftrightarrow"); +defineMacro("\\Harr", "\\Leftrightarrow"); +defineMacro("\\hearts", "\\heartsuit"); +defineMacro("\\image", "\\Im"); +defineMacro("\\infin", "\\infty"); +defineMacro("\\Iota", "\\mathrm{I}"); +defineMacro("\\isin", "\\in"); +defineMacro("\\Kappa", "\\mathrm{K}"); +defineMacro("\\larr", "\\leftarrow"); +defineMacro("\\lArr", "\\Leftarrow"); +defineMacro("\\Larr", "\\Leftarrow"); +defineMacro("\\lrarr", "\\leftrightarrow"); +defineMacro("\\lrArr", "\\Leftrightarrow"); +defineMacro("\\Lrarr", "\\Leftrightarrow"); +defineMacro("\\Mu", "\\mathrm{M}"); +defineMacro("\\natnums", "\\mathbb{N}"); +defineMacro("\\Nu", "\\mathrm{N}"); +defineMacro("\\Omicron", "\\mathrm{O}"); +defineMacro("\\plusmn", "\\pm"); +defineMacro("\\rarr", "\\rightarrow"); +defineMacro("\\rArr", "\\Rightarrow"); +defineMacro("\\Rarr", "\\Rightarrow"); +defineMacro("\\real", "\\Re"); +defineMacro("\\reals", "\\mathbb{R}"); +defineMacro("\\Reals", "\\mathbb{R}"); +defineMacro("\\Rho", "\\mathrm{P}"); +defineMacro("\\sdot", "\\cdot"); +defineMacro("\\sect", "\\S"); +defineMacro("\\spades", "\\spadesuit"); +defineMacro("\\sub", "\\subset"); +defineMacro("\\sube", "\\subseteq"); +defineMacro("\\supe", "\\supseteq"); +defineMacro("\\Tau", "\\mathrm{T}"); +defineMacro("\\thetasym", "\\vartheta"); // TODO: defineMacro("\\varcoppa", "\\\mbox{\\coppa}"); + +defineMacro("\\weierp", "\\wp"); +defineMacro("\\Zeta", "\\mathrm{Z}"); ////////////////////////////////////////////////////////////////////// +// statmath.sty +// https://ctan.math.illinois.edu/macros/latex/contrib/statmath/statmath.pdf + +defineMacro("\\argmin", "\\DOTSB\\operatorname*{arg\\,min}"); +defineMacro("\\argmax", "\\DOTSB\\operatorname*{arg\\,max}"); +defineMacro("\\plim", "\\DOTSB\\mathop{\\operatorname{plim}}\\limits"); ////////////////////////////////////////////////////////////////////// +// braket.sty +// http://ctan.math.washington.edu/tex-archive/macros/latex/contrib/braket/braket.pdf + +defineMacro("\\bra", "\\mathinner{\\langle{#1}|}"); +defineMacro("\\ket", "\\mathinner{|{#1}\\rangle}"); +defineMacro("\\braket", "\\mathinner{\\langle{#1}\\rangle}"); +defineMacro("\\Bra", "\\left\\langle#1\\right|"); +defineMacro("\\Ket", "\\left|#1\\right\\rangle"); + +var braketHelper = one => context => { + var left = context.consumeArg().tokens; + var middle = context.consumeArg().tokens; + var middleDouble = context.consumeArg().tokens; + var right = context.consumeArg().tokens; + var oldMiddle = context.macros.get("|"); + var oldMiddleDouble = context.macros.get("\\|"); + context.macros.beginGroup(); + + var midMacro = double => context => { + if (one) { + // Only modify the first instance of | or \| + context.macros.set("|", oldMiddle); + + if (middleDouble.length) { + context.macros.set("\\|", oldMiddleDouble); + } + } + + var doubled = double; + + if (!double && middleDouble.length) { + // Mimic \@ifnextchar + var nextToken = context.future(); + + if (nextToken.text === "|") { + context.popToken(); + doubled = true; + } + } + + return { + tokens: doubled ? middleDouble : middle, + numArgs: 0 + }; + }; + + context.macros.set("|", midMacro(false)); + + if (middleDouble.length) { + context.macros.set("\\|", midMacro(true)); + } + + var arg = context.consumeArg().tokens; + var expanded = context.expandTokens([...right, ...arg, ...left // reversed + ]); + context.macros.endGroup(); + return { + tokens: expanded.reverse(), + numArgs: 0 + }; +}; + +defineMacro("\\bra@ket", braketHelper(false)); +defineMacro("\\bra@set", braketHelper(true)); +defineMacro("\\Braket", "\\bra@ket{\\left\\langle}" + "{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"); +defineMacro("\\Set", "\\bra@set{\\left\\{\\:}" + "{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"); +defineMacro("\\set", "\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"); // has no support for special || or \| +////////////////////////////////////////////////////////////////////// +// actuarialangle.dtx + +defineMacro("\\angln", "{\\angl n}"); // Custom Khan Academy colors, should be moved to an optional package + +defineMacro("\\blue", "\\textcolor{##6495ed}{#1}"); +defineMacro("\\orange", "\\textcolor{##ffa500}{#1}"); +defineMacro("\\pink", "\\textcolor{##ff00af}{#1}"); +defineMacro("\\red", "\\textcolor{##df0030}{#1}"); +defineMacro("\\green", "\\textcolor{##28ae7b}{#1}"); +defineMacro("\\gray", "\\textcolor{gray}{#1}"); +defineMacro("\\purple", "\\textcolor{##9d38bd}{#1}"); +defineMacro("\\blueA", "\\textcolor{##ccfaff}{#1}"); +defineMacro("\\blueB", "\\textcolor{##80f6ff}{#1}"); +defineMacro("\\blueC", "\\textcolor{##63d9ea}{#1}"); +defineMacro("\\blueD", "\\textcolor{##11accd}{#1}"); +defineMacro("\\blueE", "\\textcolor{##0c7f99}{#1}"); +defineMacro("\\tealA", "\\textcolor{##94fff5}{#1}"); +defineMacro("\\tealB", "\\textcolor{##26edd5}{#1}"); +defineMacro("\\tealC", "\\textcolor{##01d1c1}{#1}"); +defineMacro("\\tealD", "\\textcolor{##01a995}{#1}"); +defineMacro("\\tealE", "\\textcolor{##208170}{#1}"); +defineMacro("\\greenA", "\\textcolor{##b6ffb0}{#1}"); +defineMacro("\\greenB", "\\textcolor{##8af281}{#1}"); +defineMacro("\\greenC", "\\textcolor{##74cf70}{#1}"); +defineMacro("\\greenD", "\\textcolor{##1fab54}{#1}"); +defineMacro("\\greenE", "\\textcolor{##0d923f}{#1}"); +defineMacro("\\goldA", "\\textcolor{##ffd0a9}{#1}"); +defineMacro("\\goldB", "\\textcolor{##ffbb71}{#1}"); +defineMacro("\\goldC", "\\textcolor{##ff9c39}{#1}"); +defineMacro("\\goldD", "\\textcolor{##e07d10}{#1}"); +defineMacro("\\goldE", "\\textcolor{##a75a05}{#1}"); +defineMacro("\\redA", "\\textcolor{##fca9a9}{#1}"); +defineMacro("\\redB", "\\textcolor{##ff8482}{#1}"); +defineMacro("\\redC", "\\textcolor{##f9685d}{#1}"); +defineMacro("\\redD", "\\textcolor{##e84d39}{#1}"); +defineMacro("\\redE", "\\textcolor{##bc2612}{#1}"); +defineMacro("\\maroonA", "\\textcolor{##ffbde0}{#1}"); +defineMacro("\\maroonB", "\\textcolor{##ff92c6}{#1}"); +defineMacro("\\maroonC", "\\textcolor{##ed5fa6}{#1}"); +defineMacro("\\maroonD", "\\textcolor{##ca337c}{#1}"); +defineMacro("\\maroonE", "\\textcolor{##9e034e}{#1}"); +defineMacro("\\purpleA", "\\textcolor{##ddd7ff}{#1}"); +defineMacro("\\purpleB", "\\textcolor{##c6b9fc}{#1}"); +defineMacro("\\purpleC", "\\textcolor{##aa87ff}{#1}"); +defineMacro("\\purpleD", "\\textcolor{##7854ab}{#1}"); +defineMacro("\\purpleE", "\\textcolor{##543b78}{#1}"); +defineMacro("\\mintA", "\\textcolor{##f5f9e8}{#1}"); +defineMacro("\\mintB", "\\textcolor{##edf2df}{#1}"); +defineMacro("\\mintC", "\\textcolor{##e0e5cc}{#1}"); +defineMacro("\\grayA", "\\textcolor{##f6f7f7}{#1}"); +defineMacro("\\grayB", "\\textcolor{##f0f1f2}{#1}"); +defineMacro("\\grayC", "\\textcolor{##e3e5e6}{#1}"); +defineMacro("\\grayD", "\\textcolor{##d6d8da}{#1}"); +defineMacro("\\grayE", "\\textcolor{##babec2}{#1}"); +defineMacro("\\grayF", "\\textcolor{##888d93}{#1}"); +defineMacro("\\grayG", "\\textcolor{##626569}{#1}"); +defineMacro("\\grayH", "\\textcolor{##3b3e40}{#1}"); +defineMacro("\\grayI", "\\textcolor{##21242c}{#1}"); +defineMacro("\\kaBlue", "\\textcolor{##314453}{#1}"); +defineMacro("\\kaGreen", "\\textcolor{##71B307}{#1}"); + +/** + * This file contains the “gullet” where macros are expanded + * until only non-macro tokens remain. + */ +// List of commands that act like macros but aren't defined as a macro, +// function, or symbol. Used in `isDefined`. +var implicitCommands = { + "^": true, + // Parser.js + "_": true, + // Parser.js + "\\limits": true, + // Parser.js + "\\nolimits": true // Parser.js + +}; +class MacroExpander { + constructor(input, settings, mode) { + this.settings = void 0; + this.expansionCount = void 0; + this.lexer = void 0; + this.macros = void 0; + this.stack = void 0; + this.mode = void 0; + this.settings = settings; + this.expansionCount = 0; + this.feed(input); // Make new global namespace + + this.macros = new Namespace(macros, settings.macros); + this.mode = mode; + this.stack = []; // contains tokens in REVERSE order + } + /** + * Feed a new input string to the same MacroExpander + * (with existing macros etc.). + */ + + + feed(input) { + this.lexer = new Lexer(input, this.settings); + } + /** + * Switches between "text" and "math" modes. + */ + + + switchMode(newMode) { + this.mode = newMode; + } + /** + * Start a new group nesting within all namespaces. + */ + + + beginGroup() { + this.macros.beginGroup(); + } + /** + * End current group nesting within all namespaces. + */ + + + endGroup() { + this.macros.endGroup(); + } + /** + * Ends all currently nested groups (if any), restoring values before the + * groups began. Useful in case of an error in the middle of parsing. + */ + + + endGroups() { + this.macros.endGroups(); + } + /** + * Returns the topmost token on the stack, without expanding it. + * Similar in behavior to TeX's `\futurelet`. + */ + + + future() { + if (this.stack.length === 0) { + this.pushToken(this.lexer.lex()); + } + + return this.stack[this.stack.length - 1]; + } + /** + * Remove and return the next unexpanded token. + */ + + + popToken() { + this.future(); // ensure non-empty stack + + return this.stack.pop(); + } + /** + * Add a given token to the token stack. In particular, this get be used + * to put back a token returned from one of the other methods. + */ + + + pushToken(token) { + this.stack.push(token); + } + /** + * Append an array of tokens to the token stack. + */ + + + pushTokens(tokens) { + this.stack.push(...tokens); + } + /** + * Find an macro argument without expanding tokens and append the array of + * tokens to the token stack. Uses Token as a container for the result. + */ + + + scanArgument(isOptional) { + var start; + var end; + var tokens; + + if (isOptional) { + this.consumeSpaces(); // \@ifnextchar gobbles any space following it + + if (this.future().text !== "[") { + return null; + } + + start = this.popToken(); // don't include [ in tokens + + ({ + tokens, + end + } = this.consumeArg(["]"])); + } else { + ({ + tokens, + start, + end + } = this.consumeArg()); + } // indicate the end of an argument + + + this.pushToken(new Token("EOF", end.loc)); + this.pushTokens(tokens); + return start.range(end, ""); + } + /** + * Consume all following space tokens, without expansion. + */ + + + consumeSpaces() { + for (;;) { + var token = this.future(); + + if (token.text === " ") { + this.stack.pop(); + } else { + break; + } + } + } + /** + * Consume an argument from the token stream, and return the resulting array + * of tokens and start/end token. + */ + + + consumeArg(delims) { + // The argument for a delimited parameter is the shortest (possibly + // empty) sequence of tokens with properly nested {...} groups that is + // followed ... by this particular list of non-parameter tokens. + // The argument for an undelimited parameter is the next nonblank + // token, unless that token is ‘{’, when the argument will be the + // entire {...} group that follows. + var tokens = []; + var isDelimited = delims && delims.length > 0; + + if (!isDelimited) { + // Ignore spaces between arguments. As the TeXbook says: + // "After you have said ‘\def\row#1#2{...}’, you are allowed to + // put spaces between the arguments (e.g., ‘\row x n’), because + // TeX doesn’t use single spaces as undelimited arguments." + this.consumeSpaces(); + } + + var start = this.future(); + var tok; + var depth = 0; + var match = 0; + + do { + tok = this.popToken(); + tokens.push(tok); + + if (tok.text === "{") { + ++depth; + } else if (tok.text === "}") { + --depth; + + if (depth === -1) { + throw new ParseError("Extra }", tok); + } + } else if (tok.text === "EOF") { + throw new ParseError("Unexpected end of input in a macro argument" + ", expected '" + (delims && isDelimited ? delims[match] : "}") + "'", tok); + } + + if (delims && isDelimited) { + if ((depth === 0 || depth === 1 && delims[match] === "{") && tok.text === delims[match]) { + ++match; + + if (match === delims.length) { + // don't include delims in tokens + tokens.splice(-match, match); + break; + } + } else { + match = 0; + } + } + } while (depth !== 0 || isDelimited); // If the argument found ... has the form ‘{}’, + // ... the outermost braces enclosing the argument are removed + + + if (start.text === "{" && tokens[tokens.length - 1].text === "}") { + tokens.pop(); + tokens.shift(); + } + + tokens.reverse(); // to fit in with stack order + + return { + tokens, + start, + end: tok + }; + } + /** + * Consume the specified number of (delimited) arguments from the token + * stream and return the resulting array of arguments. + */ + + + consumeArgs(numArgs, delimiters) { + if (delimiters) { + if (delimiters.length !== numArgs + 1) { + throw new ParseError("The length of delimiters doesn't match the number of args!"); + } + + var delims = delimiters[0]; + + for (var i = 0; i < delims.length; i++) { + var tok = this.popToken(); + + if (delims[i] !== tok.text) { + throw new ParseError("Use of the macro doesn't match its definition", tok); + } + } + } + + var args = []; + + for (var _i = 0; _i < numArgs; _i++) { + args.push(this.consumeArg(delimiters && delimiters[_i + 1]).tokens); + } + + return args; + } + /** + * Increment `expansionCount` by the specified amount. + * Throw an error if it exceeds `maxExpand`. + */ + + + countExpansion(amount) { + this.expansionCount += amount; + + if (this.expansionCount > this.settings.maxExpand) { + throw new ParseError("Too many expansions: infinite loop or " + "need to increase maxExpand setting"); + } + } + /** + * Expand the next token only once if possible. + * + * If the token is expanded, the resulting tokens will be pushed onto + * the stack in reverse order, and the number of such tokens will be + * returned. This number might be zero or positive. + * + * If not, the return value is `false`, and the next token remains at the + * top of the stack. + * + * In either case, the next token will be on the top of the stack, + * or the stack will be empty (in case of empty expansion + * and no other tokens). + * + * Used to implement `expandAfterFuture` and `expandNextToken`. + * + * If expandableOnly, only expandable tokens are expanded and + * an undefined control sequence results in an error. + */ + + + expandOnce(expandableOnly) { + var topToken = this.popToken(); + var name = topToken.text; + var expansion = !topToken.noexpand ? this._getExpansion(name) : null; + + if (expansion == null || expandableOnly && expansion.unexpandable) { + if (expandableOnly && expansion == null && name[0] === "\\" && !this.isDefined(name)) { + throw new ParseError("Undefined control sequence: " + name); + } + + this.pushToken(topToken); + return false; + } + + this.countExpansion(1); + var tokens = expansion.tokens; + var args = this.consumeArgs(expansion.numArgs, expansion.delimiters); + + if (expansion.numArgs) { + // paste arguments in place of the placeholders + tokens = tokens.slice(); // make a shallow copy + + for (var i = tokens.length - 1; i >= 0; --i) { + var tok = tokens[i]; + + if (tok.text === "#") { + if (i === 0) { + throw new ParseError("Incomplete placeholder at end of macro body", tok); + } + + tok = tokens[--i]; // next token on stack + + if (tok.text === "#") { + // ## → # + tokens.splice(i + 1, 1); // drop first # + } else if (/^[1-9]$/.test(tok.text)) { + // replace the placeholder with the indicated argument + tokens.splice(i, 2, ...args[+tok.text - 1]); + } else { + throw new ParseError("Not a valid argument number", tok); + } + } + } + } // Concatenate expansion onto top of stack. + + + this.pushTokens(tokens); + return tokens.length; + } + /** + * Expand the next token only once (if possible), and return the resulting + * top token on the stack (without removing anything from the stack). + * Similar in behavior to TeX's `\expandafter\futurelet`. + * Equivalent to expandOnce() followed by future(). + */ + + + expandAfterFuture() { + this.expandOnce(); + return this.future(); + } + /** + * Recursively expand first token, then return first non-expandable token. + */ + + + expandNextToken() { + for (;;) { + if (this.expandOnce() === false) { + // fully expanded + var token = this.stack.pop(); // the token after \noexpand is interpreted as if its meaning + // were ‘\relax’ + + if (token.treatAsRelax) { + token.text = "\\relax"; + } + + return token; + } + } // Flow unable to figure out that this pathway is impossible. + // https://github.com/facebook/flow/issues/4808 + + + throw new Error(); // eslint-disable-line no-unreachable + } + /** + * Fully expand the given macro name and return the resulting list of + * tokens, or return `undefined` if no such macro is defined. + */ + + + expandMacro(name) { + return this.macros.has(name) ? this.expandTokens([new Token(name)]) : undefined; + } + /** + * Fully expand the given token stream and return the resulting list of + * tokens. Note that the input tokens are in reverse order, but the + * output tokens are in forward order. + */ + + + expandTokens(tokens) { + var output = []; + var oldStackLength = this.stack.length; + this.pushTokens(tokens); + + while (this.stack.length > oldStackLength) { + // Expand only expandable tokens + if (this.expandOnce(true) === false) { + // fully expanded + var token = this.stack.pop(); + + if (token.treatAsRelax) { + // the expansion of \noexpand is the token itself + token.noexpand = false; + token.treatAsRelax = false; + } + + output.push(token); + } + } // Count all of these tokens as additional expansions, to prevent + // exponential blowup from linearly many \edef's. + + + this.countExpansion(output.length); + return output; + } + /** + * Fully expand the given macro name and return the result as a string, + * or return `undefined` if no such macro is defined. + */ + + + expandMacroAsText(name) { + var tokens = this.expandMacro(name); + + if (tokens) { + return tokens.map(token => token.text).join(""); + } else { + return tokens; + } + } + /** + * Returns the expanded macro as a reversed array of tokens and a macro + * argument count. Or returns `null` if no such macro. + */ + + + _getExpansion(name) { + var definition = this.macros.get(name); + + if (definition == null) { + // mainly checking for undefined here + return definition; + } // If a single character has an associated catcode other than 13 + // (active character), then don't expand it. + + + if (name.length === 1) { + var catcode = this.lexer.catcodes[name]; + + if (catcode != null && catcode !== 13) { + return; + } + } + + var expansion = typeof definition === "function" ? definition(this) : definition; + + if (typeof expansion === "string") { + var numArgs = 0; + + if (expansion.indexOf("#") !== -1) { + var stripped = expansion.replace(/##/g, ""); + + while (stripped.indexOf("#" + (numArgs + 1)) !== -1) { + ++numArgs; + } + } + + var bodyLexer = new Lexer(expansion, this.settings); + var tokens = []; + var tok = bodyLexer.lex(); + + while (tok.text !== "EOF") { + tokens.push(tok); + tok = bodyLexer.lex(); + } + + tokens.reverse(); // to fit in with stack using push and pop + + var expanded = { + tokens, + numArgs + }; + return expanded; + } + + return expansion; + } + /** + * Determine whether a command is currently "defined" (has some + * functionality), meaning that it's a macro (in the current group), + * a function, a symbol, or one of the special commands listed in + * `implicitCommands`. + */ + + + isDefined(name) { + return this.macros.has(name) || functions.hasOwnProperty(name) || symbols.math.hasOwnProperty(name) || symbols.text.hasOwnProperty(name) || implicitCommands.hasOwnProperty(name); + } + /** + * Determine whether a command is expandable. + */ + + + isExpandable(name) { + var macro = this.macros.get(name); + return macro != null ? typeof macro === "string" || typeof macro === "function" || !macro.unexpandable : functions.hasOwnProperty(name) && !functions[name].primitive; + } + +} + +// Helpers for Parser.js handling of Unicode (sub|super)script characters. +var unicodeSubRegEx = /^[₊₋₌₍₎₀₁₂₃₄₅₆₇₈₉ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ]/; +var uSubsAndSups = Object.freeze({ + '₊': '+', + '₋': '-', + '₌': '=', + '₍': '(', + '₎': ')', + '₀': '0', + '₁': '1', + '₂': '2', + '₃': '3', + '₄': '4', + '₅': '5', + '₆': '6', + '₇': '7', + '₈': '8', + '₉': '9', + '\u2090': 'a', + '\u2091': 'e', + '\u2095': 'h', + '\u1D62': 'i', + '\u2C7C': 'j', + '\u2096': 'k', + '\u2097': 'l', + '\u2098': 'm', + '\u2099': 'n', + '\u2092': 'o', + '\u209A': 'p', + '\u1D63': 'r', + '\u209B': 's', + '\u209C': 't', + '\u1D64': 'u', + '\u1D65': 'v', + '\u2093': 'x', + '\u1D66': 'β', + '\u1D67': 'γ', + '\u1D68': 'ρ', + '\u1D69': '\u03d5', + '\u1D6A': 'χ', + '⁺': '+', + '⁻': '-', + '⁼': '=', + '⁽': '(', + '⁾': ')', + '⁰': '0', + '¹': '1', + '²': '2', + '³': '3', + '⁴': '4', + '⁵': '5', + '⁶': '6', + '⁷': '7', + '⁸': '8', + '⁹': '9', + '\u1D2C': 'A', + '\u1D2E': 'B', + '\u1D30': 'D', + '\u1D31': 'E', + '\u1D33': 'G', + '\u1D34': 'H', + '\u1D35': 'I', + '\u1D36': 'J', + '\u1D37': 'K', + '\u1D38': 'L', + '\u1D39': 'M', + '\u1D3A': 'N', + '\u1D3C': 'O', + '\u1D3E': 'P', + '\u1D3F': 'R', + '\u1D40': 'T', + '\u1D41': 'U', + '\u2C7D': 'V', + '\u1D42': 'W', + '\u1D43': 'a', + '\u1D47': 'b', + '\u1D9C': 'c', + '\u1D48': 'd', + '\u1D49': 'e', + '\u1DA0': 'f', + '\u1D4D': 'g', + '\u02B0': 'h', + '\u2071': 'i', + '\u02B2': 'j', + '\u1D4F': 'k', + '\u02E1': 'l', + '\u1D50': 'm', + '\u207F': 'n', + '\u1D52': 'o', + '\u1D56': 'p', + '\u02B3': 'r', + '\u02E2': 's', + '\u1D57': 't', + '\u1D58': 'u', + '\u1D5B': 'v', + '\u02B7': 'w', + '\u02E3': 'x', + '\u02B8': 'y', + '\u1DBB': 'z', + '\u1D5D': 'β', + '\u1D5E': 'γ', + '\u1D5F': 'δ', + '\u1D60': '\u03d5', + '\u1D61': 'χ', + '\u1DBF': 'θ' +}); + +/* eslint no-constant-condition:0 */ + +var unicodeAccents = { + "́": { + "text": "\\'", + "math": "\\acute" + }, + "̀": { + "text": "\\`", + "math": "\\grave" + }, + "̈": { + "text": "\\\"", + "math": "\\ddot" + }, + "̃": { + "text": "\\~", + "math": "\\tilde" + }, + "̄": { + "text": "\\=", + "math": "\\bar" + }, + "̆": { + "text": "\\u", + "math": "\\breve" + }, + "̌": { + "text": "\\v", + "math": "\\check" + }, + "̂": { + "text": "\\^", + "math": "\\hat" + }, + "̇": { + "text": "\\.", + "math": "\\dot" + }, + "̊": { + "text": "\\r", + "math": "\\mathring" + }, + "̋": { + "text": "\\H" + }, + "̧": { + "text": "\\c" + } +}; +var unicodeSymbols = { + "á": "á", + "à": "à", + "ä": "ä", + "ǟ": "ǟ", + "ã": "ã", + "ā": "ā", + "ă": "ă", + "ắ": "ắ", + "ằ": "ằ", + "ẵ": "ẵ", + "ǎ": "ǎ", + "â": "â", + "ấ": "ấ", + "ầ": "ầ", + "ẫ": "ẫ", + "ȧ": "ȧ", + "ǡ": "ǡ", + "å": "å", + "ǻ": "ǻ", + "ḃ": "ḃ", + "ć": "ć", + "ḉ": "ḉ", + "č": "č", + "ĉ": "ĉ", + "ċ": "ċ", + "ç": "ç", + "ď": "ď", + "ḋ": "ḋ", + "ḑ": "ḑ", + "é": "é", + "è": "è", + "ë": "ë", + "ẽ": "ẽ", + "ē": "ē", + "ḗ": "ḗ", + "ḕ": "ḕ", + "ĕ": "ĕ", + "ḝ": "ḝ", + "ě": "ě", + "ê": "ê", + "ế": "ế", + "ề": "ề", + "ễ": "ễ", + "ė": "ė", + "ȩ": "ȩ", + "ḟ": "ḟ", + "ǵ": "ǵ", + "ḡ": "ḡ", + "ğ": "ğ", + "ǧ": "ǧ", + "ĝ": "ĝ", + "ġ": "ġ", + "ģ": "ģ", + "ḧ": "ḧ", + "ȟ": "ȟ", + "ĥ": "ĥ", + "ḣ": "ḣ", + "ḩ": "ḩ", + "í": "í", + "ì": "ì", + "ï": "ï", + "ḯ": "ḯ", + "ĩ": "ĩ", + "ī": "ī", + "ĭ": "ĭ", + "ǐ": "ǐ", + "î": "î", + "ǰ": "ǰ", + "ĵ": "ĵ", + "ḱ": "ḱ", + "ǩ": "ǩ", + "ķ": "ķ", + "ĺ": "ĺ", + "ľ": "ľ", + "ļ": "ļ", + "ḿ": "ḿ", + "ṁ": "ṁ", + "ń": "ń", + "ǹ": "ǹ", + "ñ": "ñ", + "ň": "ň", + "ṅ": "ṅ", + "ņ": "ņ", + "ó": "ó", + "ò": "ò", + "ö": "ö", + "ȫ": "ȫ", + "õ": "õ", + "ṍ": "ṍ", + "ṏ": "ṏ", + "ȭ": "ȭ", + "ō": "ō", + "ṓ": "ṓ", + "ṑ": "ṑ", + "ŏ": "ŏ", + "ǒ": "ǒ", + "ô": "ô", + "ố": "ố", + "ồ": "ồ", + "ỗ": "ỗ", + "ȯ": "ȯ", + "ȱ": "ȱ", + "ő": "ő", + "ṕ": "ṕ", + "ṗ": "ṗ", + "ŕ": "ŕ", + "ř": "ř", + "ṙ": "ṙ", + "ŗ": "ŗ", + "ś": "ś", + "ṥ": "ṥ", + "š": "š", + "ṧ": "ṧ", + "ŝ": "ŝ", + "ṡ": "ṡ", + "ş": "ş", + "ẗ": "ẗ", + "ť": "ť", + "ṫ": "ṫ", + "ţ": "ţ", + "ú": "ú", + "ù": "ù", + "ü": "ü", + "ǘ": "ǘ", + "ǜ": "ǜ", + "ǖ": "ǖ", + "ǚ": "ǚ", + "ũ": "ũ", + "ṹ": "ṹ", + "ū": "ū", + "ṻ": "ṻ", + "ŭ": "ŭ", + "ǔ": "ǔ", + "û": "û", + "ů": "ů", + "ű": "ű", + "ṽ": "ṽ", + "ẃ": "ẃ", + "ẁ": "ẁ", + "ẅ": "ẅ", + "ŵ": "ŵ", + "ẇ": "ẇ", + "ẘ": "ẘ", + "ẍ": "ẍ", + "ẋ": "ẋ", + "ý": "ý", + "ỳ": "ỳ", + "ÿ": "ÿ", + "ỹ": "ỹ", + "ȳ": "ȳ", + "ŷ": "ŷ", + "ẏ": "ẏ", + "ẙ": "ẙ", + "ź": "ź", + "ž": "ž", + "ẑ": "ẑ", + "ż": "ż", + "Á": "Á", + "À": "À", + "Ä": "Ä", + "Ǟ": "Ǟ", + "Ã": "Ã", + "Ā": "Ā", + "Ă": "Ă", + "Ắ": "Ắ", + "Ằ": "Ằ", + "Ẵ": "Ẵ", + "Ǎ": "Ǎ", + "Â": "Â", + "Ấ": "Ấ", + "Ầ": "Ầ", + "Ẫ": "Ẫ", + "Ȧ": "Ȧ", + "Ǡ": "Ǡ", + "Å": "Å", + "Ǻ": "Ǻ", + "Ḃ": "Ḃ", + "Ć": "Ć", + "Ḉ": "Ḉ", + "Č": "Č", + "Ĉ": "Ĉ", + "Ċ": "Ċ", + "Ç": "Ç", + "Ď": "Ď", + "Ḋ": "Ḋ", + "Ḑ": "Ḑ", + "É": "É", + "È": "È", + "Ë": "Ë", + "Ẽ": "Ẽ", + "Ē": "Ē", + "Ḗ": "Ḗ", + "Ḕ": "Ḕ", + "Ĕ": "Ĕ", + "Ḝ": "Ḝ", + "Ě": "Ě", + "Ê": "Ê", + "Ế": "Ế", + "Ề": "Ề", + "Ễ": "Ễ", + "Ė": "Ė", + "Ȩ": "Ȩ", + "Ḟ": "Ḟ", + "Ǵ": "Ǵ", + "Ḡ": "Ḡ", + "Ğ": "Ğ", + "Ǧ": "Ǧ", + "Ĝ": "Ĝ", + "Ġ": "Ġ", + "Ģ": "Ģ", + "Ḧ": "Ḧ", + "Ȟ": "Ȟ", + "Ĥ": "Ĥ", + "Ḣ": "Ḣ", + "Ḩ": "Ḩ", + "Í": "Í", + "Ì": "Ì", + "Ï": "Ï", + "Ḯ": "Ḯ", + "Ĩ": "Ĩ", + "Ī": "Ī", + "Ĭ": "Ĭ", + "Ǐ": "Ǐ", + "Î": "Î", + "İ": "İ", + "Ĵ": "Ĵ", + "Ḱ": "Ḱ", + "Ǩ": "Ǩ", + "Ķ": "Ķ", + "Ĺ": "Ĺ", + "Ľ": "Ľ", + "Ļ": "Ļ", + "Ḿ": "Ḿ", + "Ṁ": "Ṁ", + "Ń": "Ń", + "Ǹ": "Ǹ", + "Ñ": "Ñ", + "Ň": "Ň", + "Ṅ": "Ṅ", + "Ņ": "Ņ", + "Ó": "Ó", + "Ò": "Ò", + "Ö": "Ö", + "Ȫ": "Ȫ", + "Õ": "Õ", + "Ṍ": "Ṍ", + "Ṏ": "Ṏ", + "Ȭ": "Ȭ", + "Ō": "Ō", + "Ṓ": "Ṓ", + "Ṑ": "Ṑ", + "Ŏ": "Ŏ", + "Ǒ": "Ǒ", + "Ô": "Ô", + "Ố": "Ố", + "Ồ": "Ồ", + "Ỗ": "Ỗ", + "Ȯ": "Ȯ", + "Ȱ": "Ȱ", + "Ő": "Ő", + "Ṕ": "Ṕ", + "Ṗ": "Ṗ", + "Ŕ": "Ŕ", + "Ř": "Ř", + "Ṙ": "Ṙ", + "Ŗ": "Ŗ", + "Ś": "Ś", + "Ṥ": "Ṥ", + "Š": "Š", + "Ṧ": "Ṧ", + "Ŝ": "Ŝ", + "Ṡ": "Ṡ", + "Ş": "Ş", + "Ť": "Ť", + "Ṫ": "Ṫ", + "Ţ": "Ţ", + "Ú": "Ú", + "Ù": "Ù", + "Ü": "Ü", + "Ǘ": "Ǘ", + "Ǜ": "Ǜ", + "Ǖ": "Ǖ", + "Ǚ": "Ǚ", + "Ũ": "Ũ", + "Ṹ": "Ṹ", + "Ū": "Ū", + "Ṻ": "Ṻ", + "Ŭ": "Ŭ", + "Ǔ": "Ǔ", + "Û": "Û", + "Ů": "Ů", + "Ű": "Ű", + "Ṽ": "Ṽ", + "Ẃ": "Ẃ", + "Ẁ": "Ẁ", + "Ẅ": "Ẅ", + "Ŵ": "Ŵ", + "Ẇ": "Ẇ", + "Ẍ": "Ẍ", + "Ẋ": "Ẋ", + "Ý": "Ý", + "Ỳ": "Ỳ", + "Ÿ": "Ÿ", + "Ỹ": "Ỹ", + "Ȳ": "Ȳ", + "Ŷ": "Ŷ", + "Ẏ": "Ẏ", + "Ź": "Ź", + "Ž": "Ž", + "Ẑ": "Ẑ", + "Ż": "Ż", + "ά": "ά", + "ὰ": "ὰ", + "ᾱ": "ᾱ", + "ᾰ": "ᾰ", + "έ": "έ", + "ὲ": "ὲ", + "ή": "ή", + "ὴ": "ὴ", + "ί": "ί", + "ὶ": "ὶ", + "ϊ": "ϊ", + "ΐ": "ΐ", + "ῒ": "ῒ", + "ῑ": "ῑ", + "ῐ": "ῐ", + "ό": "ό", + "ὸ": "ὸ", + "ύ": "ύ", + "ὺ": "ὺ", + "ϋ": "ϋ", + "ΰ": "ΰ", + "ῢ": "ῢ", + "ῡ": "ῡ", + "ῠ": "ῠ", + "ώ": "ώ", + "ὼ": "ὼ", + "Ύ": "Ύ", + "Ὺ": "Ὺ", + "Ϋ": "Ϋ", + "Ῡ": "Ῡ", + "Ῠ": "Ῠ", + "Ώ": "Ώ", + "Ὼ": "Ὼ" +}; + +/** + * This file contains the parser used to parse out a TeX expression from the + * input. Since TeX isn't context-free, standard parsers don't work particularly + * well. + * + * The strategy of this parser is as such: + * + * The main functions (the `.parse...` ones) take a position in the current + * parse string to parse tokens from. The lexer (found in Lexer.js, stored at + * this.gullet.lexer) also supports pulling out tokens at arbitrary places. When + * individual tokens are needed at a position, the lexer is called to pull out a + * token, which is then used. + * + * The parser has a property called "mode" indicating the mode that + * the parser is currently in. Currently it has to be one of "math" or + * "text", which denotes whether the current environment is a math-y + * one or a text-y one (e.g. inside \text). Currently, this serves to + * limit the functions which can be used in text mode. + * + * The main functions then return an object which contains the useful data that + * was parsed at its given point, and a new position at the end of the parsed + * data. The main functions can call each other and continue the parsing by + * using the returned position as a new starting point. + * + * There are also extra `.handle...` functions, which pull out some reused + * functionality into self-contained functions. + * + * The functions return ParseNodes. + */ +class Parser { + constructor(input, settings) { + this.mode = void 0; + this.gullet = void 0; + this.settings = void 0; + this.leftrightDepth = void 0; + this.nextToken = void 0; + // Start in math mode + this.mode = "math"; // Create a new macro expander (gullet) and (indirectly via that) also a + // new lexer (mouth) for this parser (stomach, in the language of TeX) + + this.gullet = new MacroExpander(input, settings, this.mode); // Store the settings for use in parsing + + this.settings = settings; // Count leftright depth (for \middle errors) + + this.leftrightDepth = 0; + } + /** + * Checks a result to make sure it has the right type, and throws an + * appropriate error otherwise. + */ + + + expect(text, consume) { + if (consume === void 0) { + consume = true; + } + + if (this.fetch().text !== text) { + throw new ParseError("Expected '" + text + "', got '" + this.fetch().text + "'", this.fetch()); + } + + if (consume) { + this.consume(); + } + } + /** + * Discards the current lookahead token, considering it consumed. + */ + + + consume() { + this.nextToken = null; + } + /** + * Return the current lookahead token, or if there isn't one (at the + * beginning, or if the previous lookahead token was consume()d), + * fetch the next token as the new lookahead token and return it. + */ + + + fetch() { + if (this.nextToken == null) { + this.nextToken = this.gullet.expandNextToken(); + } + + return this.nextToken; + } + /** + * Switches between "text" and "math" modes. + */ + + + switchMode(newMode) { + this.mode = newMode; + this.gullet.switchMode(newMode); + } + /** + * Main parsing function, which parses an entire input. + */ + + + parse() { + if (!this.settings.globalGroup) { + // Create a group namespace for the math expression. + // (LaTeX creates a new group for every $...$, $$...$$, \[...\].) + this.gullet.beginGroup(); + } // Use old \color behavior (same as LaTeX's \textcolor) if requested. + // We do this within the group for the math expression, so it doesn't + // pollute settings.macros. + + + if (this.settings.colorIsTextColor) { + this.gullet.macros.set("\\color", "\\textcolor"); + } + + try { + // Try to parse the input + var parse = this.parseExpression(false); // If we succeeded, make sure there's an EOF at the end + + this.expect("EOF"); // End the group namespace for the expression + + if (!this.settings.globalGroup) { + this.gullet.endGroup(); + } + + return parse; // Close any leftover groups in case of a parse error. + } finally { + this.gullet.endGroups(); + } + } + /** + * Fully parse a separate sequence of tokens as a separate job. + * Tokens should be specified in reverse order, as in a MacroDefinition. + */ + + + subparse(tokens) { + // Save the next token from the current job. + var oldToken = this.nextToken; + this.consume(); // Run the new job, terminating it with an excess '}' + + this.gullet.pushToken(new Token("}")); + this.gullet.pushTokens(tokens); + var parse = this.parseExpression(false); + this.expect("}"); // Restore the next token from the current job. + + this.nextToken = oldToken; + return parse; + } + + /** + * Parses an "expression", which is a list of atoms. + * + * `breakOnInfix`: Should the parsing stop when we hit infix nodes? This + * happens when functions have higher precedence han infix + * nodes in implicit parses. + * + * `breakOnTokenText`: The text of the token that the expression should end + * with, or `null` if something else should end the + * expression. + */ + parseExpression(breakOnInfix, breakOnTokenText) { + var body = []; // Keep adding atoms to the body until we can't parse any more atoms (either + // we reached the end, a }, or a \right) + + while (true) { + // Ignore spaces in math mode + if (this.mode === "math") { + this.consumeSpaces(); + } + + var lex = this.fetch(); + + if (Parser.endOfExpression.indexOf(lex.text) !== -1) { + break; + } + + if (breakOnTokenText && lex.text === breakOnTokenText) { + break; + } + + if (breakOnInfix && functions[lex.text] && functions[lex.text].infix) { + break; + } + + var atom = this.parseAtom(breakOnTokenText); + + if (!atom) { + break; + } else if (atom.type === "internal") { + continue; + } + + body.push(atom); + } + + if (this.mode === "text") { + this.formLigatures(body); + } + + return this.handleInfixNodes(body); + } + /** + * Rewrites infix operators such as \over with corresponding commands such + * as \frac. + * + * There can only be one infix operator per group. If there's more than one + * then the expression is ambiguous. This can be resolved by adding {}. + */ + + + handleInfixNodes(body) { + var overIndex = -1; + var funcName; + + for (var i = 0; i < body.length; i++) { + if (body[i].type === "infix") { + if (overIndex !== -1) { + throw new ParseError("only one infix operator per group", body[i].token); + } + + overIndex = i; + funcName = body[i].replaceWith; + } + } + + if (overIndex !== -1 && funcName) { + var numerNode; + var denomNode; + var numerBody = body.slice(0, overIndex); + var denomBody = body.slice(overIndex + 1); + + if (numerBody.length === 1 && numerBody[0].type === "ordgroup") { + numerNode = numerBody[0]; + } else { + numerNode = { + type: "ordgroup", + mode: this.mode, + body: numerBody + }; + } + + if (denomBody.length === 1 && denomBody[0].type === "ordgroup") { + denomNode = denomBody[0]; + } else { + denomNode = { + type: "ordgroup", + mode: this.mode, + body: denomBody + }; + } + + var node; + + if (funcName === "\\\\abovefrac") { + node = this.callFunction(funcName, [numerNode, body[overIndex], denomNode], []); + } else { + node = this.callFunction(funcName, [numerNode, denomNode], []); + } + + return [node]; + } else { + return body; + } + } + /** + * Handle a subscript or superscript with nice errors. + */ + + + handleSupSubscript(name // For error reporting. + ) { + var symbolToken = this.fetch(); + var symbol = symbolToken.text; + this.consume(); + this.consumeSpaces(); // ignore spaces before sup/subscript argument + + var group = this.parseGroup(name); + + if (!group) { + throw new ParseError("Expected group after '" + symbol + "'", symbolToken); + } + + return group; + } + /** + * Converts the textual input of an unsupported command into a text node + * contained within a color node whose color is determined by errorColor + */ + + + formatUnsupportedCmd(text) { + var textordArray = []; + + for (var i = 0; i < text.length; i++) { + textordArray.push({ + type: "textord", + mode: "text", + text: text[i] + }); + } + + var textNode = { + type: "text", + mode: this.mode, + body: textordArray + }; + var colorNode = { + type: "color", + mode: this.mode, + color: this.settings.errorColor, + body: [textNode] + }; + return colorNode; + } + /** + * Parses a group with optional super/subscripts. + */ + + + parseAtom(breakOnTokenText) { + // The body of an atom is an implicit group, so that things like + // \left(x\right)^2 work correctly. + var base = this.parseGroup("atom", breakOnTokenText); // In text mode, we don't have superscripts or subscripts + + if (this.mode === "text") { + return base; + } // Note that base may be empty (i.e. null) at this point. + + + var superscript; + var subscript; + + while (true) { + // Guaranteed in math mode, so eat any spaces first. + this.consumeSpaces(); // Lex the first token + + var lex = this.fetch(); + + if (lex.text === "\\limits" || lex.text === "\\nolimits") { + // We got a limit control + if (base && base.type === "op") { + var limits = lex.text === "\\limits"; + base.limits = limits; + base.alwaysHandleSupSub = true; + } else if (base && base.type === "operatorname") { + if (base.alwaysHandleSupSub) { + base.limits = lex.text === "\\limits"; + } + } else { + throw new ParseError("Limit controls must follow a math operator", lex); + } + + this.consume(); + } else if (lex.text === "^") { + // We got a superscript start + if (superscript) { + throw new ParseError("Double superscript", lex); + } + + superscript = this.handleSupSubscript("superscript"); + } else if (lex.text === "_") { + // We got a subscript start + if (subscript) { + throw new ParseError("Double subscript", lex); + } + + subscript = this.handleSupSubscript("subscript"); + } else if (lex.text === "'") { + // We got a prime + if (superscript) { + throw new ParseError("Double superscript", lex); + } + + var prime = { + type: "textord", + mode: this.mode, + text: "\\prime" + }; // Many primes can be grouped together, so we handle this here + + var primes = [prime]; + this.consume(); // Keep lexing tokens until we get something that's not a prime + + while (this.fetch().text === "'") { + // For each one, add another prime to the list + primes.push(prime); + this.consume(); + } // If there's a superscript following the primes, combine that + // superscript in with the primes. + + + if (this.fetch().text === "^") { + primes.push(this.handleSupSubscript("superscript")); + } // Put everything into an ordgroup as the superscript + + + superscript = { + type: "ordgroup", + mode: this.mode, + body: primes + }; + } else if (uSubsAndSups[lex.text]) { + // A Unicode subscript or superscript character. + // We treat these similarly to the unicode-math package. + // So we render a string of Unicode (sub|super)scripts the + // same as a (sub|super)script of regular characters. + var isSub = unicodeSubRegEx.test(lex.text); + var subsupTokens = []; + subsupTokens.push(new Token(uSubsAndSups[lex.text])); + this.consume(); // Continue fetching tokens to fill out the string. + + while (true) { + var token = this.fetch().text; + + if (!uSubsAndSups[token]) { + break; + } + + if (unicodeSubRegEx.test(token) !== isSub) { + break; + } + + subsupTokens.unshift(new Token(uSubsAndSups[token])); + this.consume(); + } // Now create a (sub|super)script. + + + var body = this.subparse(subsupTokens); + + if (isSub) { + subscript = { + type: "ordgroup", + mode: "math", + body + }; + } else { + superscript = { + type: "ordgroup", + mode: "math", + body + }; + } + } else { + // If it wasn't ^, _, or ', stop parsing super/subscripts + break; + } + } // Base must be set if superscript or subscript are set per logic above, + // but need to check here for type check to pass. + + + if (superscript || subscript) { + // If we got either a superscript or subscript, create a supsub + return { + type: "supsub", + mode: this.mode, + base: base, + sup: superscript, + sub: subscript + }; + } else { + // Otherwise return the original body + return base; + } + } + /** + * Parses an entire function, including its base and all of its arguments. + */ + + + parseFunction(breakOnTokenText, name // For determining its context + ) { + var token = this.fetch(); + var func = token.text; + var funcData = functions[func]; + + if (!funcData) { + return null; + } + + this.consume(); // consume command token + + if (name && name !== "atom" && !funcData.allowedInArgument) { + throw new ParseError("Got function '" + func + "' with no arguments" + (name ? " as " + name : ""), token); + } else if (this.mode === "text" && !funcData.allowedInText) { + throw new ParseError("Can't use function '" + func + "' in text mode", token); + } else if (this.mode === "math" && funcData.allowedInMath === false) { + throw new ParseError("Can't use function '" + func + "' in math mode", token); + } + + var { + args, + optArgs + } = this.parseArguments(func, funcData); + return this.callFunction(func, args, optArgs, token, breakOnTokenText); + } + /** + * Call a function handler with a suitable context and arguments. + */ + + + callFunction(name, args, optArgs, token, breakOnTokenText) { + var context = { + funcName: name, + parser: this, + token, + breakOnTokenText + }; + var func = functions[name]; + + if (func && func.handler) { + return func.handler(context, args, optArgs); + } else { + throw new ParseError("No function handler for " + name); + } + } + /** + * Parses the arguments of a function or environment + */ + + + parseArguments(func, // Should look like "\name" or "\begin{name}". + funcData) { + var totalArgs = funcData.numArgs + funcData.numOptionalArgs; + + if (totalArgs === 0) { + return { + args: [], + optArgs: [] + }; + } + + var args = []; + var optArgs = []; + + for (var i = 0; i < totalArgs; i++) { + var argType = funcData.argTypes && funcData.argTypes[i]; + var isOptional = i < funcData.numOptionalArgs; + + if (funcData.primitive && argType == null || // \sqrt expands into primitive if optional argument doesn't exist + funcData.type === "sqrt" && i === 1 && optArgs[0] == null) { + argType = "primitive"; + } + + var arg = this.parseGroupOfType("argument to '" + func + "'", argType, isOptional); + + if (isOptional) { + optArgs.push(arg); + } else if (arg != null) { + args.push(arg); + } else { + // should be unreachable + throw new ParseError("Null argument, please report this as a bug"); + } + } + + return { + args, + optArgs + }; + } + /** + * Parses a group when the mode is changing. + */ + + + parseGroupOfType(name, type, optional) { + switch (type) { + case "color": + return this.parseColorGroup(optional); + + case "size": + return this.parseSizeGroup(optional); + + case "url": + return this.parseUrlGroup(optional); + + case "math": + case "text": + return this.parseArgumentGroup(optional, type); + + case "hbox": + { + // hbox argument type wraps the argument in the equivalent of + // \hbox, which is like \text but switching to \textstyle size. + var group = this.parseArgumentGroup(optional, "text"); + return group != null ? { + type: "styling", + mode: group.mode, + body: [group], + style: "text" // simulate \textstyle + + } : null; + } + + case "raw": + { + var token = this.parseStringGroup("raw", optional); + return token != null ? { + type: "raw", + mode: "text", + string: token.text + } : null; + } + + case "primitive": + { + if (optional) { + throw new ParseError("A primitive argument cannot be optional"); + } + + var _group = this.parseGroup(name); + + if (_group == null) { + throw new ParseError("Expected group as " + name, this.fetch()); + } + + return _group; + } + + case "original": + case null: + case undefined: + return this.parseArgumentGroup(optional); + + default: + throw new ParseError("Unknown group type as " + name, this.fetch()); + } + } + /** + * Discard any space tokens, fetching the next non-space token. + */ + + + consumeSpaces() { + while (this.fetch().text === " ") { + this.consume(); + } + } + /** + * Parses a group, essentially returning the string formed by the + * brace-enclosed tokens plus some position information. + */ + + + parseStringGroup(modeName, // Used to describe the mode in error messages. + optional) { + var argToken = this.gullet.scanArgument(optional); + + if (argToken == null) { + return null; + } + + var str = ""; + var nextToken; + + while ((nextToken = this.fetch()).text !== "EOF") { + str += nextToken.text; + this.consume(); + } + + this.consume(); // consume the end of the argument + + argToken.text = str; + return argToken; + } + /** + * Parses a regex-delimited group: the largest sequence of tokens + * whose concatenated strings match `regex`. Returns the string + * formed by the tokens plus some position information. + */ + + + parseRegexGroup(regex, modeName // Used to describe the mode in error messages. + ) { + var firstToken = this.fetch(); + var lastToken = firstToken; + var str = ""; + var nextToken; + + while ((nextToken = this.fetch()).text !== "EOF" && regex.test(str + nextToken.text)) { + lastToken = nextToken; + str += lastToken.text; + this.consume(); + } + + if (str === "") { + throw new ParseError("Invalid " + modeName + ": '" + firstToken.text + "'", firstToken); + } + + return firstToken.range(lastToken, str); + } + /** + * Parses a color description. + */ + + + parseColorGroup(optional) { + var res = this.parseStringGroup("color", optional); + + if (res == null) { + return null; + } + + var match = /^(#[a-f0-9]{3}|#?[a-f0-9]{6}|[a-z]+)$/i.exec(res.text); + + if (!match) { + throw new ParseError("Invalid color: '" + res.text + "'", res); + } + + var color = match[0]; + + if (/^[0-9a-f]{6}$/i.test(color)) { + // We allow a 6-digit HTML color spec without a leading "#". + // This follows the xcolor package's HTML color model. + // Predefined color names are all missed by this RegEx pattern. + color = "#" + color; + } + + return { + type: "color-token", + mode: this.mode, + color + }; + } + /** + * Parses a size specification, consisting of magnitude and unit. + */ + + + parseSizeGroup(optional) { + var res; + var isBlank = false; // don't expand before parseStringGroup + + this.gullet.consumeSpaces(); + + if (!optional && this.gullet.future().text !== "{") { + res = this.parseRegexGroup(/^[-+]? *(?:$|\d+|\d+\.\d*|\.\d*) *[a-z]{0,2} *$/, "size"); + } else { + res = this.parseStringGroup("size", optional); + } + + if (!res) { + return null; + } + + if (!optional && res.text.length === 0) { + // Because we've tested for what is !optional, this block won't + // affect \kern, \hspace, etc. It will capture the mandatory arguments + // to \genfrac and \above. + res.text = "0pt"; // Enable \above{} + + isBlank = true; // This is here specifically for \genfrac + } + + var match = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(res.text); + + if (!match) { + throw new ParseError("Invalid size: '" + res.text + "'", res); + } + + var data = { + number: +(match[1] + match[2]), + // sign + magnitude, cast to number + unit: match[3] + }; + + if (!validUnit(data)) { + throw new ParseError("Invalid unit: '" + data.unit + "'", res); + } + + return { + type: "size", + mode: this.mode, + value: data, + isBlank + }; + } + /** + * Parses an URL, checking escaped letters and allowed protocols, + * and setting the catcode of % as an active character (as in \hyperref). + */ + + + parseUrlGroup(optional) { + this.gullet.lexer.setCatcode("%", 13); // active character + + this.gullet.lexer.setCatcode("~", 12); // other character + + var res = this.parseStringGroup("url", optional); + this.gullet.lexer.setCatcode("%", 14); // comment character + + this.gullet.lexer.setCatcode("~", 13); // active character + + if (res == null) { + return null; + } // hyperref package allows backslashes alone in href, but doesn't + // generate valid links in such cases; we interpret this as + // "undefined" behaviour, and keep them as-is. Some browser will + // replace backslashes with forward slashes. + + + var url = res.text.replace(/\\([#$%&~_^{}])/g, '$1'); + return { + type: "url", + mode: this.mode, + url + }; + } + /** + * Parses an argument with the mode specified. + */ + + + parseArgumentGroup(optional, mode) { + var argToken = this.gullet.scanArgument(optional); + + if (argToken == null) { + return null; + } + + var outerMode = this.mode; + + if (mode) { + // Switch to specified mode + this.switchMode(mode); + } + + this.gullet.beginGroup(); + var expression = this.parseExpression(false, "EOF"); // TODO: find an alternative way to denote the end + + this.expect("EOF"); // expect the end of the argument + + this.gullet.endGroup(); + var result = { + type: "ordgroup", + mode: this.mode, + loc: argToken.loc, + body: expression + }; + + if (mode) { + // Switch mode back + this.switchMode(outerMode); + } + + return result; + } + /** + * Parses an ordinary group, which is either a single nucleus (like "x") + * or an expression in braces (like "{x+y}") or an implicit group, a group + * that starts at the current position, and ends right before a higher explicit + * group ends, or at EOF. + */ + + + parseGroup(name, // For error reporting. + breakOnTokenText) { + var firstToken = this.fetch(); + var text = firstToken.text; + var result; // Try to parse an open brace or \begingroup + + if (text === "{" || text === "\\begingroup") { + this.consume(); + var groupEnd = text === "{" ? "}" : "\\endgroup"; + this.gullet.beginGroup(); // If we get a brace, parse an expression + + var expression = this.parseExpression(false, groupEnd); + var lastToken = this.fetch(); + this.expect(groupEnd); // Check that we got a matching closing brace + + this.gullet.endGroup(); + result = { + type: "ordgroup", + mode: this.mode, + loc: SourceLocation.range(firstToken, lastToken), + body: expression, + // A group formed by \begingroup...\endgroup is a semi-simple group + // which doesn't affect spacing in math mode, i.e., is transparent. + // https://tex.stackexchange.com/questions/1930/when-should-one- + // use-begingroup-instead-of-bgroup + semisimple: text === "\\begingroup" || undefined + }; + } else { + // If there exists a function with this name, parse the function. + // Otherwise, just return a nucleus + result = this.parseFunction(breakOnTokenText, name) || this.parseSymbol(); + + if (result == null && text[0] === "\\" && !implicitCommands.hasOwnProperty(text)) { + if (this.settings.throwOnError) { + throw new ParseError("Undefined control sequence: " + text, firstToken); + } + + result = this.formatUnsupportedCmd(text); + this.consume(); + } + } + + return result; + } + /** + * Form ligature-like combinations of characters for text mode. + * This includes inputs like "--", "---", "``" and "''". + * The result will simply replace multiple textord nodes with a single + * character in each value by a single textord node having multiple + * characters in its value. The representation is still ASCII source. + * The group will be modified in place. + */ + + + formLigatures(group) { + var n = group.length - 1; + + for (var i = 0; i < n; ++i) { + var a = group[i]; // $FlowFixMe: Not every node type has a `text` property. + + var v = a.text; + + if (v === "-" && group[i + 1].text === "-") { + if (i + 1 < n && group[i + 2].text === "-") { + group.splice(i, 3, { + type: "textord", + mode: "text", + loc: SourceLocation.range(a, group[i + 2]), + text: "---" + }); + n -= 2; + } else { + group.splice(i, 2, { + type: "textord", + mode: "text", + loc: SourceLocation.range(a, group[i + 1]), + text: "--" + }); + n -= 1; + } + } + + if ((v === "'" || v === "`") && group[i + 1].text === v) { + group.splice(i, 2, { + type: "textord", + mode: "text", + loc: SourceLocation.range(a, group[i + 1]), + text: v + v + }); + n -= 1; + } + } + } + /** + * Parse a single symbol out of the string. Here, we handle single character + * symbols and special functions like \verb. + */ + + + parseSymbol() { + var nucleus = this.fetch(); + var text = nucleus.text; + + if (/^\\verb[^a-zA-Z]/.test(text)) { + this.consume(); + var arg = text.slice(5); + var star = arg.charAt(0) === "*"; + + if (star) { + arg = arg.slice(1); + } // Lexer's tokenRegex is constructed to always have matching + // first/last characters. + + + if (arg.length < 2 || arg.charAt(0) !== arg.slice(-1)) { + throw new ParseError("\\verb assertion failed --\n please report what input caused this bug"); + } + + arg = arg.slice(1, -1); // remove first and last char + + return { + type: "verb", + mode: "text", + body: arg, + star + }; + } // At this point, we should have a symbol, possibly with accents. + // First expand any accented base symbol according to unicodeSymbols. + + + if (unicodeSymbols.hasOwnProperty(text[0]) && !symbols[this.mode][text[0]]) { + // This behavior is not strict (XeTeX-compatible) in math mode. + if (this.settings.strict && this.mode === "math") { + this.settings.reportNonstrict("unicodeTextInMathMode", "Accented Unicode text character \"" + text[0] + "\" used in " + "math mode", nucleus); + } + + text = unicodeSymbols[text[0]] + text.slice(1); + } // Strip off any combining characters + + + var match = combiningDiacriticalMarksEndRegex.exec(text); + + if (match) { + text = text.substring(0, match.index); + + if (text === 'i') { + text = '\u0131'; // dotless i, in math and text mode + } else if (text === 'j') { + text = '\u0237'; // dotless j, in math and text mode + } + } // Recognize base symbol + + + var symbol; + + if (symbols[this.mode][text]) { + if (this.settings.strict && this.mode === 'math' && extraLatin.indexOf(text) >= 0) { + this.settings.reportNonstrict("unicodeTextInMathMode", "Latin-1/Unicode text character \"" + text[0] + "\" used in " + "math mode", nucleus); + } + + var group = symbols[this.mode][text].group; + var loc = SourceLocation.range(nucleus); + var s; + + if (ATOMS.hasOwnProperty(group)) { + // $FlowFixMe + var family = group; + s = { + type: "atom", + mode: this.mode, + family, + loc, + text + }; + } else { + // $FlowFixMe + s = { + type: group, + mode: this.mode, + loc, + text + }; + } // $FlowFixMe + + + symbol = s; + } else if (text.charCodeAt(0) >= 0x80) { + // no symbol for e.g. ^ + if (this.settings.strict) { + if (!supportedCodepoint(text.charCodeAt(0))) { + this.settings.reportNonstrict("unknownSymbol", "Unrecognized Unicode character \"" + text[0] + "\"" + (" (" + text.charCodeAt(0) + ")"), nucleus); + } else if (this.mode === "math") { + this.settings.reportNonstrict("unicodeTextInMathMode", "Unicode text character \"" + text[0] + "\" used in math mode", nucleus); + } + } // All nonmathematical Unicode characters are rendered as if they + // are in text mode (wrapped in \text) because that's what it + // takes to render them in LaTeX. Setting `mode: this.mode` is + // another natural choice (the user requested math mode), but + // this makes it more difficult for getCharacterMetrics() to + // distinguish Unicode characters without metrics and those for + // which we want to simulate the letter M. + + + symbol = { + type: "textord", + mode: "text", + loc: SourceLocation.range(nucleus), + text + }; + } else { + return null; // EOF, ^, _, {, }, etc. + } + + this.consume(); // Transform combining characters into accents + + if (match) { + for (var i = 0; i < match[0].length; i++) { + var accent = match[0][i]; + + if (!unicodeAccents[accent]) { + throw new ParseError("Unknown accent ' " + accent + "'", nucleus); + } + + var command = unicodeAccents[accent][this.mode] || unicodeAccents[accent].text; + + if (!command) { + throw new ParseError("Accent " + accent + " unsupported in " + this.mode + " mode", nucleus); + } + + symbol = { + type: "accent", + mode: this.mode, + loc: SourceLocation.range(nucleus), + label: command, + isStretchy: false, + isShifty: true, + // $FlowFixMe + base: symbol + }; + } + } // $FlowFixMe + + + return symbol; + } + +} +Parser.endOfExpression = ["}", "\\endgroup", "\\end", "\\right", "&"]; + +/** + * Provides a single function for parsing an expression using a Parser + * TODO(emily): Remove this + */ + +/** + * Parses an expression using a Parser, then returns the parsed result. + */ +var parseTree = function parseTree(toParse, settings) { + if (!(typeof toParse === 'string' || toParse instanceof String)) { + throw new TypeError('KaTeX can only parse string typed expression'); + } + + var parser = new Parser(toParse, settings); // Blank out any \df@tag to avoid spurious "Duplicate \tag" errors + + delete parser.gullet.macros.current["\\df@tag"]; + var tree = parser.parse(); // Prevent a color definition from persisting between calls to katex.render(). + + delete parser.gullet.macros.current["\\current@color"]; + delete parser.gullet.macros.current["\\color"]; // If the input used \tag, it will set the \df@tag macro to the tag. + // In this case, we separately parse the tag and wrap the tree. + + if (parser.gullet.macros.get("\\df@tag")) { + if (!settings.displayMode) { + throw new ParseError("\\tag works only in display equations"); + } + + tree = [{ + type: "tag", + mode: "text", + body: tree, + tag: parser.subparse([new Token("\\df@tag")]) + }]; + } + + return tree; +}; + +/* eslint no-console:0 */ + +/** + * Parse and build an expression, and place that expression in the DOM node + * given. + */ +var render = function render(expression, baseNode, options) { + baseNode.textContent = ""; + var node = renderToDomTree(expression, options).toNode(); + baseNode.appendChild(node); +}; // KaTeX's styles don't work properly in quirks mode. Print out an error, and +// disable rendering. + + +if (typeof document !== "undefined") { + if (document.compatMode !== "CSS1Compat") { + typeof console !== "undefined" && console.warn("Warning: KaTeX doesn't work in quirks mode. Make sure your " + "website has a suitable doctype."); + + render = function render() { + throw new ParseError("KaTeX doesn't work in quirks mode."); + }; + } +} +/** + * Parse and build an expression, and return the markup for that. + */ + + +var renderToString = function renderToString(expression, options) { + var markup = renderToDomTree(expression, options).toMarkup(); + return markup; +}; +/** + * Parse an expression and return the parse tree. + */ + + +var generateParseTree = function generateParseTree(expression, options) { + var settings = new Settings(options); + return parseTree(expression, settings); +}; +/** + * If the given error is a KaTeX ParseError and options.throwOnError is false, + * renders the invalid LaTeX as a span with hover title giving the KaTeX + * error message. Otherwise, simply throws the error. + */ + + +var renderError = function renderError(error, expression, options) { + if (options.throwOnError || !(error instanceof ParseError)) { + throw error; + } + + var node = buildCommon.makeSpan(["katex-error"], [new SymbolNode(expression)]); + node.setAttribute("title", error.toString()); + node.setAttribute("style", "color:" + options.errorColor); + return node; +}; +/** + * Generates and returns the katex build tree. This is used for advanced + * use cases (like rendering to custom output). + */ + + +var renderToDomTree = function renderToDomTree(expression, options) { + var settings = new Settings(options); + + try { + var tree = parseTree(expression, settings); + return buildTree(tree, expression, settings); + } catch (error) { + return renderError(error, expression, settings); + } +}; +/** + * Generates and returns the katex build tree, with just HTML (no MathML). + * This is used for advanced use cases (like rendering to custom output). + */ + + +var renderToHTMLTree = function renderToHTMLTree(expression, options) { + var settings = new Settings(options); + + try { + var tree = parseTree(expression, settings); + return buildHTMLTree(tree, expression, settings); + } catch (error) { + return renderError(error, expression, settings); + } +}; + +var katex = { + /** + * Current KaTeX version + */ + version: "0.16.10", + + /** + * Renders the given LaTeX into an HTML+MathML combination, and adds + * it as a child to the specified DOM node. + */ + render, + + /** + * Renders the given LaTeX into an HTML+MathML combination string, + * for sending to the client. + */ + renderToString, + + /** + * KaTeX error, usually during parsing. + */ + ParseError, + + /** + * The shema of Settings + */ + SETTINGS_SCHEMA, + + /** + * Parses the given LaTeX into KaTeX's internal parse tree structure, + * without rendering to HTML or MathML. + * + * NOTE: This method is not currently recommended for public use. + * The internal tree representation is unstable and is very likely + * to change. Use at your own risk. + */ + __parse: generateParseTree, + + /** + * Renders the given LaTeX into an HTML+MathML internal DOM tree + * representation, without flattening that representation to a string. + * + * NOTE: This method is not currently recommended for public use. + * The internal tree representation is unstable and is very likely + * to change. Use at your own risk. + */ + __renderToDomTree: renderToDomTree, + + /** + * Renders the given LaTeX into an HTML internal DOM tree representation, + * without MathML and without flattening that representation to a string. + * + * NOTE: This method is not currently recommended for public use. + * The internal tree representation is unstable and is very likely + * to change. Use at your own risk. + */ + __renderToHTMLTree: renderToHTMLTree, + + /** + * extends internal font metrics object with a new object + * each key in the new object represents a font name + */ + __setFontMetrics: setFontMetrics, + + /** + * adds a new symbol to builtin symbols table + */ + __defineSymbol: defineSymbol, + + /** + * adds a new function to builtin function list, + * which directly produce parse tree elements + * and have their own html/mathml builders + */ + __defineFunction: defineFunction, + + /** + * adds a new macro to builtin macro list + */ + __defineMacro: defineMacro, + + /** + * Expose the dom tree node types, which can be useful for type checking nodes. + * + * NOTE: This method is not currently recommended for public use. + * The internal tree representation is unstable and is very likely + * to change. Use at your own risk. + */ + __domTree: { + Span, + Anchor, + SymbolNode, + SvgNode, + PathNode, + LineNode + } +}; + + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/147.7b14dc77.js b/assets/js/147.7b14dc77.js new file mode 100644 index 0000000000..5deed85f35 --- /dev/null +++ b/assets/js/147.7b14dc77.js @@ -0,0 +1,20433 @@ +"use strict"; +exports.id = 147; +exports.ids = [147]; +exports.modules = { + +/***/ 73046: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + T: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(89610); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(66401); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.A)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(39857); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.A && (1 / (0,_setToArray/* default */.A)(new _Set/* default */.A([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.A(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.A)(set); + } + isCommon = false; + includes = _cacheHas/* default */.A; + seen = new _SetCache/* default */.A; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(53533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.A)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.A)(arrays, 1, isArrayLikeObject/* default */.A, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.A(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.A(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.A(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.A(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.A(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.A(this._nodes); + } + sources() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.A(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.A(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.A(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.A(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.A(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.A(keys/* default */.A(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.A(keys/* default */.A(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.A(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.A(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.A(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.A(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.A(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.A(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.A(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.A(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.A(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.A(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.A(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.A(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.A(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.A(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.A(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.A(inV); + if (!u) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.A(outV); + if (!w) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.A(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 697: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ T: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.T) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 75937: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _utils_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(72453); +/* harmony import */ var _color_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74886); +/* IMPORT */ + + +/* MAIN */ +const channel = (color, channel) => { + return _utils_index_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A.lang.round(_color_index_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A.parse(color)[channel]); +}; +/* EXPORT */ +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (channel); + + +/***/ }), + +/***/ 62062: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(29471); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.A; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 72641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 2634: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 45572: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 76912: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 91641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(72641); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(22031); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keys/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keysIn/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(80154); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(39759); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(14792); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.A)(source, (0,_getSymbols/* default */.A)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(15647); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(13153); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.A : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.A)(result, (0,_getSymbols/* default */.A)(object)); + object = (0,_getPrototype/* default */.A)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.A)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(33831); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.A)(object, keysIn/* default */.A, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(90565); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.A)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(1801); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.A)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.A)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(18598); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(64841); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.A)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.A)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.A)(value)) { + return value; + } + var isArr = (0,isArray/* default */.A)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.A)(value, result); + } + } else { + var tag = (0,_getTag/* default */.A)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.A)(value)) { + return (0,_cloneBuffer/* default */.A)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.A)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.A); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.A) + : (isFlat ? keysIn/* default */.A : keys/* default */.A); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.A)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.A)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 6240: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.A)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.A); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 25707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 13588: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(52274); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.A ? _Symbol/* default */.A.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.A)(value) || (0,isArguments/* default */.A)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.A)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 79841: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4574); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 66318: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 33831: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76912); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 49574: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.A : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.A)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(43988); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(66984); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.A(object), new _Uint8Array/* default */.A(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.A)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.A); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.A)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.A)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(33858); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.A)(object), + othIsArr = (0,isArray/* default */.A)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.A)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.A)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.A)(object)) { + if (!(0,isBuffer/* default */.A)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.A); + return (objIsArr || (0,isTypedArray/* default */.A)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.A); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.A); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.A)(value) && !(0,isObjectLike/* default */.A)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.A; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.A)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.A)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.A)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.A)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.A)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.A)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.A)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.A)(path) ? (0,_baseProperty/* default */.A)((0,_toKey/* default */.A)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.A; + } + if (typeof value == 'object') { + return (0,isArray/* default */.A)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 70805: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 64099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 99922: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(29008); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 7819: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(46632); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.A)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(28894); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.A)(value)) { + return value; + } + return (0,_isKey/* default */.A)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.A)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 19042: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33831); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14792); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 14792: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2634); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13153); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 85054: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(52274); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(92049); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25353); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5254); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 86586: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(61882); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 29959: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 30901: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61882); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 50053: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseClone_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(91641); + + +/** Used to compose bitmasks for cloning. */ +var CLONE_SYMBOLS_FLAG = 4; + +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return (0,_baseClone_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value, CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (clone); + + +/***/ }), + +/***/ 11662: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(2634); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.A)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.A)(collection) ? _arrayFilter/* default */.A : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.A)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 8058: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72641); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6240); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99922); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 48585: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 39188: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 61882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(88496); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(53098); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 69592: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 27422: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(83607); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69471); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 89463: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.A)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.A)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.A); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 13153: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 28894: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.A)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.A)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.A)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 38207: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.A)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.A)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 87147: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(76257); +/* harmony import */ var lodash_es_clone_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(50053); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(75937); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(25582); +/* harmony import */ var _edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(28747); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(697); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(26312); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(99418); +var _a, _b; + + + + + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 7], $V1 = [1, 13], $V2 = [1, 14], $V3 = [1, 15], $V4 = [1, 19], $V5 = [1, 16], $V6 = [1, 17], $V7 = [1, 18], $V8 = [8, 30], $V9 = [8, 21, 28, 29, 30, 31, 32, 40, 44, 47], $Va = [1, 23], $Vb = [1, 24], $Vc = [8, 15, 16, 21, 28, 29, 30, 31, 32, 40, 44, 47], $Vd = [8, 15, 16, 21, 27, 28, 29, 30, 31, 32, 40, 44, 47], $Ve = [1, 49]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "spaceLines": 3, "SPACELINE": 4, "NL": 5, "separator": 6, "SPACE": 7, "EOF": 8, "start": 9, "BLOCK_DIAGRAM_KEY": 10, "document": 11, "stop": 12, "statement": 13, "link": 14, "LINK": 15, "START_LINK": 16, "LINK_LABEL": 17, "STR": 18, "nodeStatement": 19, "columnsStatement": 20, "SPACE_BLOCK": 21, "blockStatement": 22, "classDefStatement": 23, "cssClassStatement": 24, "styleStatement": 25, "node": 26, "SIZE": 27, "COLUMNS": 28, "id-block": 29, "end": 30, "block": 31, "NODE_ID": 32, "nodeShapeNLabel": 33, "dirList": 34, "DIR": 35, "NODE_DSTART": 36, "NODE_DEND": 37, "BLOCK_ARROW_START": 38, "BLOCK_ARROW_END": 39, "classDef": 40, "CLASSDEF_ID": 41, "CLASSDEF_STYLEOPTS": 42, "DEFAULT": 43, "class": 44, "CLASSENTITY_IDS": 45, "STYLECLASS": 46, "style": 47, "STYLE_ENTITY_IDS": 48, "STYLE_DEFINITION_DATA": 49, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "SPACELINE", 5: "NL", 7: "SPACE", 8: "EOF", 10: "BLOCK_DIAGRAM_KEY", 15: "LINK", 16: "START_LINK", 17: "LINK_LABEL", 18: "STR", 21: "SPACE_BLOCK", 27: "SIZE", 28: "COLUMNS", 29: "id-block", 30: "end", 31: "block", 32: "NODE_ID", 35: "DIR", 36: "NODE_DSTART", 37: "NODE_DEND", 38: "BLOCK_ARROW_START", 39: "BLOCK_ARROW_END", 40: "classDef", 41: "CLASSDEF_ID", 42: "CLASSDEF_STYLEOPTS", 43: "DEFAULT", 44: "class", 45: "CLASSENTITY_IDS", 46: "STYLECLASS", 47: "style", 48: "STYLE_ENTITY_IDS", 49: "STYLE_DEFINITION_DATA" }, + productions_: [0, [3, 1], [3, 2], [3, 2], [6, 1], [6, 1], [6, 1], [9, 3], [12, 1], [12, 1], [12, 2], [12, 2], [11, 1], [11, 2], [14, 1], [14, 4], [13, 1], [13, 1], [13, 1], [13, 1], [13, 1], [13, 1], [13, 1], [19, 3], [19, 2], [19, 1], [20, 1], [22, 4], [22, 3], [26, 1], [26, 2], [34, 1], [34, 2], [33, 3], [33, 4], [23, 3], [23, 3], [24, 3], [25, 3]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 4: + yy.getLogger().debug("Rule: separator (NL) "); + break; + case 5: + yy.getLogger().debug("Rule: separator (Space) "); + break; + case 6: + yy.getLogger().debug("Rule: separator (EOF) "); + break; + case 7: + yy.getLogger().debug("Rule: hierarchy: ", $$[$0 - 1]); + yy.setHierarchy($$[$0 - 1]); + break; + case 8: + yy.getLogger().debug("Stop NL "); + break; + case 9: + yy.getLogger().debug("Stop EOF "); + break; + case 10: + yy.getLogger().debug("Stop NL2 "); + break; + case 11: + yy.getLogger().debug("Stop EOF2 "); + break; + case 12: + yy.getLogger().debug("Rule: statement: ", $$[$0]); + typeof $$[$0].length === "number" ? this.$ = $$[$0] : this.$ = [$$[$0]]; + break; + case 13: + yy.getLogger().debug("Rule: statement #2: ", $$[$0 - 1]); + this.$ = [$$[$0 - 1]].concat($$[$0]); + break; + case 14: + yy.getLogger().debug("Rule: link: ", $$[$0], yytext); + this.$ = { edgeTypeStr: $$[$0], label: "" }; + break; + case 15: + yy.getLogger().debug("Rule: LABEL link: ", $$[$0 - 3], $$[$0 - 1], $$[$0]); + this.$ = { edgeTypeStr: $$[$0], label: $$[$0 - 1] }; + break; + case 18: + const num = parseInt($$[$0]); + const spaceId = yy.generateId(); + this.$ = { id: spaceId, type: "space", label: "", width: num, children: [] }; + break; + case 23: + yy.getLogger().debug("Rule: (nodeStatement link node) ", $$[$0 - 2], $$[$0 - 1], $$[$0], " typestr: ", $$[$0 - 1].edgeTypeStr); + const edgeData = yy.edgeStrToEdgeData($$[$0 - 1].edgeTypeStr); + this.$ = [ + { id: $$[$0 - 2].id, label: $$[$0 - 2].label, type: $$[$0 - 2].type, directions: $$[$0 - 2].directions }, + { id: $$[$0 - 2].id + "-" + $$[$0].id, start: $$[$0 - 2].id, end: $$[$0].id, label: $$[$0 - 1].label, type: "edge", directions: $$[$0].directions, arrowTypeEnd: edgeData, arrowTypeStart: "arrow_open" }, + { id: $$[$0].id, label: $$[$0].label, type: yy.typeStr2Type($$[$0].typeStr), directions: $$[$0].directions } + ]; + break; + case 24: + yy.getLogger().debug("Rule: nodeStatement (abc88 node size) ", $$[$0 - 1], $$[$0]); + this.$ = { id: $$[$0 - 1].id, label: $$[$0 - 1].label, type: yy.typeStr2Type($$[$0 - 1].typeStr), directions: $$[$0 - 1].directions, widthInColumns: parseInt($$[$0], 10) }; + break; + case 25: + yy.getLogger().debug("Rule: nodeStatement (node) ", $$[$0]); + this.$ = { id: $$[$0].id, label: $$[$0].label, type: yy.typeStr2Type($$[$0].typeStr), directions: $$[$0].directions, widthInColumns: 1 }; + break; + case 26: + yy.getLogger().debug("APA123", this ? this : "na"); + yy.getLogger().debug("COLUMNS: ", $$[$0]); + this.$ = { type: "column-setting", columns: $$[$0] === "auto" ? -1 : parseInt($$[$0]) }; + break; + case 27: + yy.getLogger().debug("Rule: id-block statement : ", $$[$0 - 2], $$[$0 - 1]); + yy.generateId(); + this.$ = { ...$$[$0 - 2], type: "composite", children: $$[$0 - 1] }; + break; + case 28: + yy.getLogger().debug("Rule: blockStatement : ", $$[$0 - 2], $$[$0 - 1], $$[$0]); + const id = yy.generateId(); + this.$ = { id, type: "composite", label: "", children: $$[$0 - 1] }; + break; + case 29: + yy.getLogger().debug("Rule: node (NODE_ID separator): ", $$[$0]); + this.$ = { id: $$[$0] }; + break; + case 30: + yy.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ", $$[$0 - 1], $$[$0]); + this.$ = { id: $$[$0 - 1], label: $$[$0].label, typeStr: $$[$0].typeStr, directions: $$[$0].directions }; + break; + case 31: + yy.getLogger().debug("Rule: dirList: ", $$[$0]); + this.$ = [$$[$0]]; + break; + case 32: + yy.getLogger().debug("Rule: dirList: ", $$[$0 - 1], $$[$0]); + this.$ = [$$[$0 - 1]].concat($$[$0]); + break; + case 33: + yy.getLogger().debug("Rule: nodeShapeNLabel: ", $$[$0 - 2], $$[$0 - 1], $$[$0]); + this.$ = { typeStr: $$[$0 - 2] + $$[$0], label: $$[$0 - 1] }; + break; + case 34: + yy.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ", $$[$0 - 3], $$[$0 - 2], " #3:", $$[$0 - 1], $$[$0]); + this.$ = { typeStr: $$[$0 - 3] + $$[$0], label: $$[$0 - 2], directions: $$[$0 - 1] }; + break; + case 35: + case 36: + this.$ = { type: "classDef", id: $$[$0 - 1].trim(), css: $$[$0].trim() }; + break; + case 37: + this.$ = { type: "applyClass", id: $$[$0 - 1].trim(), styleClass: $$[$0].trim() }; + break; + case 38: + this.$ = { type: "applyStyles", id: $$[$0 - 1].trim(), stylesStr: $$[$0].trim() }; + break; + } + }, + table: [{ 9: 1, 10: [1, 2] }, { 1: [3] }, { 11: 3, 13: 4, 19: 5, 20: 6, 21: $V0, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 28: $V1, 29: $V2, 31: $V3, 32: $V4, 40: $V5, 44: $V6, 47: $V7 }, { 8: [1, 20] }, o($V8, [2, 12], { 13: 4, 19: 5, 20: 6, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 11: 21, 21: $V0, 28: $V1, 29: $V2, 31: $V3, 32: $V4, 40: $V5, 44: $V6, 47: $V7 }), o($V9, [2, 16], { 14: 22, 15: $Va, 16: $Vb }), o($V9, [2, 17]), o($V9, [2, 18]), o($V9, [2, 19]), o($V9, [2, 20]), o($V9, [2, 21]), o($V9, [2, 22]), o($Vc, [2, 25], { 27: [1, 25] }), o($V9, [2, 26]), { 19: 26, 26: 12, 32: $V4 }, { 11: 27, 13: 4, 19: 5, 20: 6, 21: $V0, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 28: $V1, 29: $V2, 31: $V3, 32: $V4, 40: $V5, 44: $V6, 47: $V7 }, { 41: [1, 28], 43: [1, 29] }, { 45: [1, 30] }, { 48: [1, 31] }, o($Vd, [2, 29], { 33: 32, 36: [1, 33], 38: [1, 34] }), { 1: [2, 7] }, o($V8, [2, 13]), { 26: 35, 32: $V4 }, { 32: [2, 14] }, { 17: [1, 36] }, o($Vc, [2, 24]), { 11: 37, 13: 4, 14: 22, 15: $Va, 16: $Vb, 19: 5, 20: 6, 21: $V0, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 28: $V1, 29: $V2, 31: $V3, 32: $V4, 40: $V5, 44: $V6, 47: $V7 }, { 30: [1, 38] }, { 42: [1, 39] }, { 42: [1, 40] }, { 46: [1, 41] }, { 49: [1, 42] }, o($Vd, [2, 30]), { 18: [1, 43] }, { 18: [1, 44] }, o($Vc, [2, 23]), { 18: [1, 45] }, { 30: [1, 46] }, o($V9, [2, 28]), o($V9, [2, 35]), o($V9, [2, 36]), o($V9, [2, 37]), o($V9, [2, 38]), { 37: [1, 47] }, { 34: 48, 35: $Ve }, { 15: [1, 50] }, o($V9, [2, 27]), o($Vd, [2, 33]), { 39: [1, 51] }, { 34: 52, 35: $Ve, 39: [2, 31] }, { 32: [2, 15] }, o($Vd, [2, 34]), { 39: [2, 32] }], + defaultActions: { 20: [2, 7], 23: [2, 14], 50: [2, 15], 52: [2, 32] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 10; + case 1: + yy.getLogger().debug("Found space-block"); + return 31; + case 2: + yy.getLogger().debug("Found nl-block"); + return 31; + case 3: + yy.getLogger().debug("Found space-block"); + return 29; + case 4: + yy.getLogger().debug(".", yy_.yytext); + break; + case 5: + yy.getLogger().debug("_", yy_.yytext); + break; + case 6: + return 5; + case 7: + yy_.yytext = -1; + return 28; + case 8: + yy_.yytext = yy_.yytext.replace(/columns\s+/, ""); + yy.getLogger().debug("COLUMNS (LEX)", yy_.yytext); + return 28; + case 9: + this.pushState("md_string"); + break; + case 10: + return "MD_STR"; + case 11: + this.popState(); + break; + case 12: + this.pushState("string"); + break; + case 13: + yy.getLogger().debug("LEX: POPPING STR:", yy_.yytext); + this.popState(); + break; + case 14: + yy.getLogger().debug("LEX: STR end:", yy_.yytext); + return "STR"; + case 15: + yy_.yytext = yy_.yytext.replace(/space\:/, ""); + yy.getLogger().debug("SPACE NUM (LEX)", yy_.yytext); + return 21; + case 16: + yy_.yytext = "1"; + yy.getLogger().debug("COLUMNS (LEX)", yy_.yytext); + return 21; + case 17: + return 43; + case 18: + return "LINKSTYLE"; + case 19: + return "INTERPOLATE"; + case 20: + this.pushState("CLASSDEF"); + return 40; + case 21: + this.popState(); + this.pushState("CLASSDEFID"); + return "DEFAULT_CLASSDEF_ID"; + case 22: + this.popState(); + this.pushState("CLASSDEFID"); + return 41; + case 23: + this.popState(); + return 42; + case 24: + this.pushState("CLASS"); + return 44; + case 25: + this.popState(); + this.pushState("CLASS_STYLE"); + return 45; + case 26: + this.popState(); + return 46; + case 27: + this.pushState("STYLE_STMNT"); + return 47; + case 28: + this.popState(); + this.pushState("STYLE_DEFINITION"); + return 48; + case 29: + this.popState(); + return 49; + case 30: + this.pushState("acc_title"); + return "acc_title"; + case 31: + this.popState(); + return "acc_title_value"; + case 32: + this.pushState("acc_descr"); + return "acc_descr"; + case 33: + this.popState(); + return "acc_descr_value"; + case 34: + this.pushState("acc_descr_multiline"); + break; + case 35: + this.popState(); + break; + case 36: + return "acc_descr_multiline_value"; + case 37: + return 30; + case 38: + this.popState(); + yy.getLogger().debug("Lex: (("); + return "NODE_DEND"; + case 39: + this.popState(); + yy.getLogger().debug("Lex: (("); + return "NODE_DEND"; + case 40: + this.popState(); + yy.getLogger().debug("Lex: ))"); + return "NODE_DEND"; + case 41: + this.popState(); + yy.getLogger().debug("Lex: (("); + return "NODE_DEND"; + case 42: + this.popState(); + yy.getLogger().debug("Lex: (("); + return "NODE_DEND"; + case 43: + this.popState(); + yy.getLogger().debug("Lex: (-"); + return "NODE_DEND"; + case 44: + this.popState(); + yy.getLogger().debug("Lex: -)"); + return "NODE_DEND"; + case 45: + this.popState(); + yy.getLogger().debug("Lex: (("); + return "NODE_DEND"; + case 46: + this.popState(); + yy.getLogger().debug("Lex: ]]"); + return "NODE_DEND"; + case 47: + this.popState(); + yy.getLogger().debug("Lex: ("); + return "NODE_DEND"; + case 48: + this.popState(); + yy.getLogger().debug("Lex: ])"); + return "NODE_DEND"; + case 49: + this.popState(); + yy.getLogger().debug("Lex: /]"); + return "NODE_DEND"; + case 50: + this.popState(); + yy.getLogger().debug("Lex: /]"); + return "NODE_DEND"; + case 51: + this.popState(); + yy.getLogger().debug("Lex: )]"); + return "NODE_DEND"; + case 52: + this.popState(); + yy.getLogger().debug("Lex: )"); + return "NODE_DEND"; + case 53: + this.popState(); + yy.getLogger().debug("Lex: ]>"); + return "NODE_DEND"; + case 54: + this.popState(); + yy.getLogger().debug("Lex: ]"); + return "NODE_DEND"; + case 55: + yy.getLogger().debug("Lexa: -)"); + this.pushState("NODE"); + return 36; + case 56: + yy.getLogger().debug("Lexa: (-"); + this.pushState("NODE"); + return 36; + case 57: + yy.getLogger().debug("Lexa: ))"); + this.pushState("NODE"); + return 36; + case 58: + yy.getLogger().debug("Lexa: )"); + this.pushState("NODE"); + return 36; + case 59: + yy.getLogger().debug("Lex: ((("); + this.pushState("NODE"); + return 36; + case 60: + yy.getLogger().debug("Lexa: )"); + this.pushState("NODE"); + return 36; + case 61: + yy.getLogger().debug("Lexa: )"); + this.pushState("NODE"); + return 36; + case 62: + yy.getLogger().debug("Lexa: )"); + this.pushState("NODE"); + return 36; + case 63: + yy.getLogger().debug("Lexc: >"); + this.pushState("NODE"); + return 36; + case 64: + yy.getLogger().debug("Lexa: (["); + this.pushState("NODE"); + return 36; + case 65: + yy.getLogger().debug("Lexa: )"); + this.pushState("NODE"); + return 36; + case 66: + this.pushState("NODE"); + return 36; + case 67: + this.pushState("NODE"); + return 36; + case 68: + this.pushState("NODE"); + return 36; + case 69: + this.pushState("NODE"); + return 36; + case 70: + this.pushState("NODE"); + return 36; + case 71: + this.pushState("NODE"); + return 36; + case 72: + this.pushState("NODE"); + return 36; + case 73: + yy.getLogger().debug("Lexa: ["); + this.pushState("NODE"); + return 36; + case 74: + this.pushState("BLOCK_ARROW"); + yy.getLogger().debug("LEX ARR START"); + return 38; + case 75: + yy.getLogger().debug("Lex: NODE_ID", yy_.yytext); + return 32; + case 76: + yy.getLogger().debug("Lex: EOF", yy_.yytext); + return 8; + case 77: + this.pushState("md_string"); + break; + case 78: + this.pushState("md_string"); + break; + case 79: + return "NODE_DESCR"; + case 80: + this.popState(); + break; + case 81: + yy.getLogger().debug("Lex: Starting string"); + this.pushState("string"); + break; + case 82: + yy.getLogger().debug("LEX ARR: Starting string"); + this.pushState("string"); + break; + case 83: + yy.getLogger().debug("LEX: NODE_DESCR:", yy_.yytext); + return "NODE_DESCR"; + case 84: + yy.getLogger().debug("LEX POPPING"); + this.popState(); + break; + case 85: + yy.getLogger().debug("Lex: =>BAE"); + this.pushState("ARROW_DIR"); + break; + case 86: + yy_.yytext = yy_.yytext.replace(/^,\s*/, ""); + yy.getLogger().debug("Lex (right): dir:", yy_.yytext); + return "DIR"; + case 87: + yy_.yytext = yy_.yytext.replace(/^,\s*/, ""); + yy.getLogger().debug("Lex (left):", yy_.yytext); + return "DIR"; + case 88: + yy_.yytext = yy_.yytext.replace(/^,\s*/, ""); + yy.getLogger().debug("Lex (x):", yy_.yytext); + return "DIR"; + case 89: + yy_.yytext = yy_.yytext.replace(/^,\s*/, ""); + yy.getLogger().debug("Lex (y):", yy_.yytext); + return "DIR"; + case 90: + yy_.yytext = yy_.yytext.replace(/^,\s*/, ""); + yy.getLogger().debug("Lex (up):", yy_.yytext); + return "DIR"; + case 91: + yy_.yytext = yy_.yytext.replace(/^,\s*/, ""); + yy.getLogger().debug("Lex (down):", yy_.yytext); + return "DIR"; + case 92: + yy_.yytext = "]>"; + yy.getLogger().debug("Lex (ARROW_DIR end):", yy_.yytext); + this.popState(); + this.popState(); + return "BLOCK_ARROW_END"; + case 93: + yy.getLogger().debug("Lex: LINK", "#" + yy_.yytext + "#"); + return 15; + case 94: + yy.getLogger().debug("Lex: LINK", yy_.yytext); + return 15; + case 95: + yy.getLogger().debug("Lex: LINK", yy_.yytext); + return 15; + case 96: + yy.getLogger().debug("Lex: LINK", yy_.yytext); + return 15; + case 97: + yy.getLogger().debug("Lex: START_LINK", yy_.yytext); + this.pushState("LLABEL"); + return 16; + case 98: + yy.getLogger().debug("Lex: START_LINK", yy_.yytext); + this.pushState("LLABEL"); + return 16; + case 99: + yy.getLogger().debug("Lex: START_LINK", yy_.yytext); + this.pushState("LLABEL"); + return 16; + case 100: + this.pushState("md_string"); + break; + case 101: + yy.getLogger().debug("Lex: Starting string"); + this.pushState("string"); + return "LINK_LABEL"; + case 102: + this.popState(); + yy.getLogger().debug("Lex: LINK", "#" + yy_.yytext + "#"); + return 15; + case 103: + this.popState(); + yy.getLogger().debug("Lex: LINK", yy_.yytext); + return 15; + case 104: + this.popState(); + yy.getLogger().debug("Lex: LINK", yy_.yytext); + return 15; + case 105: + yy.getLogger().debug("Lex: COLON", yy_.yytext); + yy_.yytext = yy_.yytext.slice(1); + return 27; + } + }, + rules: [/^(?:block-beta\b)/, /^(?:block\s+)/, /^(?:block\n+)/, /^(?:block:)/, /^(?:[\s]+)/, /^(?:[\n]+)/, /^(?:((\u000D\u000A)|(\u000A)))/, /^(?:columns\s+auto\b)/, /^(?:columns\s+[\d]+)/, /^(?:["][`])/, /^(?:[^`"]+)/, /^(?:[`]["])/, /^(?:["])/, /^(?:["])/, /^(?:[^"]*)/, /^(?:space[:]\d+)/, /^(?:space\b)/, /^(?:default\b)/, /^(?:linkStyle\b)/, /^(?:interpolate\b)/, /^(?:classDef\s+)/, /^(?:DEFAULT\s+)/, /^(?:\w+\s+)/, /^(?:[^\n]*)/, /^(?:class\s+)/, /^(?:(\w+)+((,\s*\w+)*))/, /^(?:[^\n]*)/, /^(?:style\s+)/, /^(?:(\w+)+((,\s*\w+)*))/, /^(?:[^\n]*)/, /^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:end\b\s*)/, /^(?:\(\(\()/, /^(?:\)\)\))/, /^(?:[\)]\))/, /^(?:\}\})/, /^(?:\})/, /^(?:\(-)/, /^(?:-\))/, /^(?:\(\()/, /^(?:\]\])/, /^(?:\()/, /^(?:\]\))/, /^(?:\\\])/, /^(?:\/\])/, /^(?:\)\])/, /^(?:[\)])/, /^(?:\]>)/, /^(?:[\]])/, /^(?:-\))/, /^(?:\(-)/, /^(?:\)\))/, /^(?:\))/, /^(?:\(\(\()/, /^(?:\(\()/, /^(?:\{\{)/, /^(?:\{)/, /^(?:>)/, /^(?:\(\[)/, /^(?:\()/, /^(?:\[\[)/, /^(?:\[\|)/, /^(?:\[\()/, /^(?:\)\)\))/, /^(?:\[\\)/, /^(?:\[\/)/, /^(?:\[\\)/, /^(?:\[)/, /^(?:<\[)/, /^(?:[^\(\[\n\-\)\{\}\s\<\>:]+)/, /^(?:$)/, /^(?:["][`])/, /^(?:["][`])/, /^(?:[^`"]+)/, /^(?:[`]["])/, /^(?:["])/, /^(?:["])/, /^(?:[^"]+)/, /^(?:["])/, /^(?:\]>\s*\()/, /^(?:,?\s*right\s*)/, /^(?:,?\s*left\s*)/, /^(?:,?\s*x\s*)/, /^(?:,?\s*y\s*)/, /^(?:,?\s*up\s*)/, /^(?:,?\s*down\s*)/, /^(?:\)\s*)/, /^(?:\s*[xo<]?--+[-xo>]\s*)/, /^(?:\s*[xo<]?==+[=xo>]\s*)/, /^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/, /^(?:\s*~~[\~]+\s*)/, /^(?:\s*[xo<]?--\s*)/, /^(?:\s*[xo<]?==\s*)/, /^(?:\s*[xo<]?-\.\s*)/, /^(?:["][`])/, /^(?:["])/, /^(?:\s*[xo<]?--+[-xo>]\s*)/, /^(?:\s*[xo<]?==+[=xo>]\s*)/, /^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/, /^(?::\d+)/], + conditions: { "STYLE_DEFINITION": { "rules": [29], "inclusive": false }, "STYLE_STMNT": { "rules": [28], "inclusive": false }, "CLASSDEFID": { "rules": [23], "inclusive": false }, "CLASSDEF": { "rules": [21, 22], "inclusive": false }, "CLASS_STYLE": { "rules": [26], "inclusive": false }, "CLASS": { "rules": [25], "inclusive": false }, "LLABEL": { "rules": [100, 101, 102, 103, 104], "inclusive": false }, "ARROW_DIR": { "rules": [86, 87, 88, 89, 90, 91, 92], "inclusive": false }, "BLOCK_ARROW": { "rules": [77, 82, 85], "inclusive": false }, "NODE": { "rules": [38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 78, 81], "inclusive": false }, "md_string": { "rules": [10, 11, 79, 80], "inclusive": false }, "space": { "rules": [], "inclusive": false }, "string": { "rules": [13, 14, 83, 84], "inclusive": false }, "acc_descr_multiline": { "rules": [35, 36], "inclusive": false }, "acc_descr": { "rules": [33], "inclusive": false }, "acc_title": { "rules": [31], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 15, 16, 17, 18, 19, 20, 24, 27, 30, 32, 34, 37, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 93, 94, 95, 96, 97, 98, 99, 105], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let blockDatabase = {}; +let edgeList = []; +let edgeCount = {}; +const COLOR_KEYWORD = "color"; +const FILL_KEYWORD = "fill"; +const BG_FILL = "bgFill"; +const STYLECLASS_SEP = ","; +let classes = {}; +const addStyleClass = function(id, styleAttributes = "") { + if (classes[id] === void 0) { + classes[id] = { id, styles: [], textStyles: [] }; + } + const foundClass = classes[id]; + if (styleAttributes !== void 0 && styleAttributes !== null) { + styleAttributes.split(STYLECLASS_SEP).forEach((attrib) => { + const fixedAttrib = attrib.replace(/([^;]*);/, "$1").trim(); + if (attrib.match(COLOR_KEYWORD)) { + const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL); + const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD); + foundClass.textStyles.push(newStyle2); + } + foundClass.styles.push(fixedAttrib); + }); + } +}; +const addStyle2Node = function(id, styles = "") { + const foundBlock = blockDatabase[id]; + if (styles !== void 0 && styles !== null) { + foundBlock.styles = styles.split(STYLECLASS_SEP); + } +}; +const setCssClass = function(itemIds, cssClassName) { + itemIds.split(",").forEach(function(id) { + let foundBlock = blockDatabase[id]; + if (foundBlock === void 0) { + const trimmedId = id.trim(); + blockDatabase[trimmedId] = { id: trimmedId, type: "na", children: [] }; + foundBlock = blockDatabase[trimmedId]; + } + if (!foundBlock.classes) { + foundBlock.classes = []; + } + foundBlock.classes.push(cssClassName); + }); +}; +const populateBlockDatabase = (_blockList, parent) => { + const blockList = _blockList.flat(); + const children = []; + for (const block of blockList) { + if (block.type === "classDef") { + addStyleClass(block.id, block.css); + continue; + } + if (block.type === "applyClass") { + setCssClass(block.id, (block == null ? void 0 : block.styleClass) || ""); + continue; + } + if (block.type === "applyStyles") { + if (block == null ? void 0 : block.stylesStr) { + addStyle2Node(block.id, block == null ? void 0 : block.stylesStr); + } + continue; + } + if (block.type === "column-setting") { + parent.columns = block.columns || -1; + } else if (block.type === "edge") { + if (edgeCount[block.id]) { + edgeCount[block.id]++; + } else { + edgeCount[block.id] = 1; + } + block.id = edgeCount[block.id] + "-" + block.id; + edgeList.push(block); + } else { + if (!block.label) { + if (block.type === "composite") { + block.label = ""; + } else { + block.label = block.id; + } + } + const newBlock = !blockDatabase[block.id]; + if (newBlock) { + blockDatabase[block.id] = block; + } else { + if (block.type !== "na") { + blockDatabase[block.id].type = block.type; + } + if (block.label !== block.id) { + blockDatabase[block.id].label = block.label; + } + } + if (block.children) { + populateBlockDatabase(block.children, block); + } + if (block.type === "space") { + const w = block.width || 1; + for (let j = 0; j < w; j++) { + const newBlock2 = (0,lodash_es_clone_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(block); + newBlock2.id = newBlock2.id + "-" + j; + blockDatabase[newBlock2.id] = newBlock2; + children.push(newBlock2); + } + } else if (newBlock) { + children.push(block); + } + } + } + parent.children = children; +}; +let blocks = []; +let rootBlock = { id: "root", type: "composite", children: [], columns: -1 }; +const clear = () => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Clear called"); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.v)(); + rootBlock = { id: "root", type: "composite", children: [], columns: -1 }; + blockDatabase = { root: rootBlock }; + blocks = []; + classes = {}; + edgeList = []; + edgeCount = {}; +}; +function typeStr2Type(typeStr) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("typeStr2Type", typeStr); + switch (typeStr) { + case "[]": + return "square"; + case "()": + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("we have a round"); + return "round"; + case "(())": + return "circle"; + case ">]": + return "rect_left_inv_arrow"; + case "{}": + return "diamond"; + case "{{}}": + return "hexagon"; + case "([])": + return "stadium"; + case "[[]]": + return "subroutine"; + case "[()]": + return "cylinder"; + case "((()))": + return "doublecircle"; + case "[//]": + return "lean_right"; + case "[\\\\]": + return "lean_left"; + case "[/\\]": + return "trapezoid"; + case "[\\/]": + return "inv_trapezoid"; + case "<[]>": + return "block_arrow"; + default: + return "na"; + } +} +function edgeTypeStr2Type(typeStr) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("typeStr2Type", typeStr); + switch (typeStr) { + case "==": + return "thick"; + default: + return "normal"; + } +} +function edgeStrToEdgeData(typeStr) { + switch (typeStr.trim()) { + case "--x": + return "arrow_cross"; + case "--o": + return "arrow_circle"; + default: + return "arrow_point"; + } +} +let cnt = 0; +const generateId = () => { + cnt++; + return "id-" + Math.random().toString(36).substr(2, 12) + "-" + cnt; +}; +const setHierarchy = (block) => { + rootBlock.children = block; + populateBlockDatabase(block, rootBlock); + blocks = rootBlock.children; +}; +const getColumns = (blockId) => { + const block = blockDatabase[blockId]; + if (!block) { + return -1; + } + if (block.columns) { + return block.columns; + } + if (!block.children) { + return -1; + } + return block.children.length; +}; +const getBlocksFlat = () => { + return [...Object.values(blockDatabase)]; +}; +const getBlocks = () => { + return blocks || []; +}; +const getEdges = () => { + return edgeList; +}; +const getBlock = (id) => { + return blockDatabase[id]; +}; +const setBlock = (block) => { + blockDatabase[block.id] = block; +}; +const getLogger = () => console; +const getClasses$1 = function() { + return classes; +}; +const db = { + getConfig: () => (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.F)().block, + typeStr2Type, + edgeTypeStr2Type, + edgeStrToEdgeData, + getLogger, + getBlocksFlat, + getBlocks, + getEdges, + setHierarchy, + getBlock, + setBlock, + getColumns, + getClasses: getClasses$1, + clear, + generateId +}; +const db$1 = db; +const fade = (color, opacity) => { + const channel = khroma__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A; + const r = channel(color, "r"); + const g = channel(color, "g"); + const b = channel(color, "b"); + return khroma__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A(r, g, b, opacity); +}; +const getStyles = (options) => `.label { + font-family: ${options.fontFamily}; + color: ${options.nodeTextColor || options.textColor}; + } + .cluster-label text { + fill: ${options.titleColor}; + } + .cluster-label span,p { + color: ${options.titleColor}; + } + + + + .label text,span,p { + fill: ${options.nodeTextColor || options.textColor}; + color: ${options.nodeTextColor || options.textColor}; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + .flowchart-label text { + text-anchor: middle; + } + // .flowchart-label .text-outer-tspan { + // text-anchor: middle; + // } + // .flowchart-label .text-inner-tspan { + // text-anchor: start; + // } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${options.arrowheadColor}; + } + + .edgePath .path { + stroke: ${options.lineColor}; + stroke-width: 2.0px; + } + + .flowchart-link { + stroke: ${options.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${options.edgeLabelBackground}; + rect { + opacity: 0.5; + background-color: ${options.edgeLabelBackground}; + fill: ${options.edgeLabelBackground}; + } + text-align: center; + } + + /* For html labels only */ + .labelBkg { + background-color: ${fade(options.edgeLabelBackground, 0.5)}; + // background-color: + } + + .node .cluster { + // fill: ${fade(options.mainBkg, 0.5)}; + fill: ${fade(options.clusterBkg, 0.5)}; + stroke: ${fade(options.clusterBorder, 0.2)}; + box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + stroke-width: 1px; + } + + .cluster text { + fill: ${options.titleColor}; + } + + .cluster span,p { + color: ${options.titleColor}; + } + /* .cluster div { + color: ${options.titleColor}; + } */ + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${options.fontFamily}; + font-size: 12px; + background: ${options.tertiaryColor}; + border: 1px solid ${options.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } +`; +const flowStyles = getStyles; +function getNodeFromBlock(block, db2, positioned = false) { + var _a2, _b2, _c; + const vertex = block; + let classStr = "default"; + if ((((_a2 = vertex == null ? void 0 : vertex.classes) == null ? void 0 : _a2.length) || 0) > 0) { + classStr = ((vertex == null ? void 0 : vertex.classes) || []).join(" "); + } + classStr = classStr + " flowchart-label"; + let radius = 0; + let shape = ""; + let padding2; + switch (vertex.type) { + case "round": + radius = 5; + shape = "rect"; + break; + case "composite": + radius = 0; + shape = "composite"; + padding2 = 0; + break; + case "square": + shape = "rect"; + break; + case "diamond": + shape = "question"; + break; + case "hexagon": + shape = "hexagon"; + break; + case "block_arrow": + shape = "block_arrow"; + break; + case "odd": + shape = "rect_left_inv_arrow"; + break; + case "lean_right": + shape = "lean_right"; + break; + case "lean_left": + shape = "lean_left"; + break; + case "trapezoid": + shape = "trapezoid"; + break; + case "inv_trapezoid": + shape = "inv_trapezoid"; + break; + case "rect_left_inv_arrow": + shape = "rect_left_inv_arrow"; + break; + case "circle": + shape = "circle"; + break; + case "ellipse": + shape = "ellipse"; + break; + case "stadium": + shape = "stadium"; + break; + case "subroutine": + shape = "subroutine"; + break; + case "cylinder": + shape = "cylinder"; + break; + case "group": + shape = "rect"; + break; + case "doublecircle": + shape = "doublecircle"; + break; + default: + shape = "rect"; + } + const styles = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.k)((vertex == null ? void 0 : vertex.styles) || []); + const vertexText = vertex.label; + const bounds = vertex.size || { width: 0, height: 0, x: 0, y: 0 }; + const node = { + labelStyle: styles.labelStyle, + shape, + labelText: vertexText, + rx: radius, + ry: radius, + class: classStr, + style: styles.style, + id: vertex.id, + directions: vertex.directions, + width: bounds.width, + height: bounds.height, + x: bounds.x, + y: bounds.y, + positioned, + intersect: void 0, + type: vertex.type, + padding: padding2 ?? (((_c = (_b2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.F)()) == null ? void 0 : _b2.block) == null ? void 0 : _c.padding) || 0) + }; + return node; +} +async function calculateBlockSize(elem, block, db2) { + const node = getNodeFromBlock(block, db2, false); + if (node.type === "group") { + return; + } + const nodeEl = await (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_9__.e)(elem, node); + const boundingBox = nodeEl.node().getBBox(); + const obj = db2.getBlock(node.id); + obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl }; + db2.setBlock(obj); + nodeEl.remove(); +} +async function insertBlockPositioned(elem, block, db2) { + const node = getNodeFromBlock(block, db2, true); + const obj = db2.getBlock(node.id); + if (obj.type !== "space") { + await (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_9__.e)(elem, node); + block.intersect = node == null ? void 0 : node.intersect; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_9__.p)(node); + } +} +async function performOperations(elem, blocks2, db2, operation) { + for (const block of blocks2) { + await operation(elem, block, db2); + if (block.children) { + await performOperations(elem, block.children, db2, operation); + } + } +} +async function calculateBlockSizes(elem, blocks2, db2) { + await performOperations(elem, blocks2, db2, calculateBlockSize); +} +async function insertBlocks(elem, blocks2, db2) { + await performOperations(elem, blocks2, db2, insertBlockPositioned); +} +async function insertEdges(elem, edges, blocks2, db2, id) { + const g = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_0__/* .Graph */ .T({ + multigraph: true, + compound: true + }); + g.setGraph({ + rankdir: "TB", + nodesep: 10, + ranksep: 10, + marginx: 8, + marginy: 8 + }); + for (const block of blocks2) { + if (block.size) { + g.setNode(block.id, { + width: block.size.width, + height: block.size.height, + intersect: block.intersect + }); + } + } + for (const edge of edges) { + if (edge.start && edge.end) { + const startBlock = db2.getBlock(edge.start); + const endBlock = db2.getBlock(edge.end); + if ((startBlock == null ? void 0 : startBlock.size) && (endBlock == null ? void 0 : endBlock.size)) { + const start = startBlock.size; + const end = endBlock.size; + const points = [ + { x: start.x, y: start.y }, + { x: start.x + (end.x - start.x) / 2, y: start.y + (end.y - start.y) / 2 }, + { x: end.x, y: end.y } + ]; + await (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_9__.h)( + elem, + { v: edge.start, w: edge.end, name: edge.id }, + { + ...edge, + arrowTypeEnd: edge.arrowTypeEnd, + arrowTypeStart: edge.arrowTypeStart, + points, + classes: "edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1" + }, + void 0, + "block", + g, + id + ); + if (edge.label) { + await (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_9__.f)(elem, { + ...edge, + label: edge.label, + labelStyle: "stroke: #333; stroke-width: 1.5px;fill:none;", + arrowTypeEnd: edge.arrowTypeEnd, + arrowTypeStart: edge.arrowTypeStart, + points, + classes: "edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1" + }); + await (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_9__.j)( + { ...edge, x: points[1].x, y: points[1].y }, + { + originalPath: points + } + ); + } + } + } + } +} +const padding = ((_b = (_a = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)()) == null ? void 0 : _a.block) == null ? void 0 : _b.padding) || 8; +function calculateBlockPosition(columns, position) { + if (columns === 0 || !Number.isInteger(columns)) { + throw new Error("Columns must be an integer !== 0."); + } + if (position < 0 || !Number.isInteger(position)) { + throw new Error("Position must be a non-negative integer." + position); + } + if (columns < 0) { + return { px: position, py: 0 }; + } + if (columns === 1) { + return { px: 0, py: position }; + } + const px = position % columns; + const py = Math.floor(position / columns); + return { px, py }; +} +const getMaxChildSize = (block) => { + let maxWidth = 0; + let maxHeight = 0; + for (const child of block.children) { + const { width, height, x, y } = child.size || { width: 0, height: 0, x: 0, y: 0 }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug( + "getMaxChildSize abc95 child:", + child.id, + "width:", + width, + "height:", + height, + "x:", + x, + "y:", + y, + child.type + ); + if (child.type === "space") { + continue; + } + if (width > maxWidth) { + maxWidth = width / (block.widthInColumns || 1); + } + if (height > maxHeight) { + maxHeight = height; + } + } + return { width: maxWidth, height: maxHeight }; +}; +function setBlockSizes(block, db2, siblingWidth = 0, siblingHeight = 0) { + var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug( + "setBlockSizes abc95 (start)", + block.id, + (_a2 = block == null ? void 0 : block.size) == null ? void 0 : _a2.x, + "block width =", + block == null ? void 0 : block.size, + "sieblingWidth", + siblingWidth + ); + if (!((_b2 = block == null ? void 0 : block.size) == null ? void 0 : _b2.width)) { + block.size = { + width: siblingWidth, + height: siblingHeight, + x: 0, + y: 0 + }; + } + let maxWidth = 0; + let maxHeight = 0; + if (((_c = block.children) == null ? void 0 : _c.length) > 0) { + for (const child of block.children) { + setBlockSizes(child, db2); + } + const childSize = getMaxChildSize(block); + maxWidth = childSize.width; + maxHeight = childSize.height; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("setBlockSizes abc95 maxWidth of", block.id, ":s children is ", maxWidth, maxHeight); + for (const child of block.children) { + if (child.size) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug( + `abc95 Setting size of children of ${block.id} id=${child.id} ${maxWidth} ${maxHeight} ${child.size}` + ); + child.size.width = maxWidth * (child.widthInColumns || 1) + padding * ((child.widthInColumns || 1) - 1); + child.size.height = maxHeight; + child.size.x = 0; + child.size.y = 0; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug( + `abc95 updating size of ${block.id} children child:${child.id} maxWidth:${maxWidth} maxHeight:${maxHeight}` + ); + } + } + for (const child of block.children) { + setBlockSizes(child, db2, maxWidth, maxHeight); + } + const columns = block.columns || -1; + let numItems = 0; + for (const child of block.children) { + numItems += child.widthInColumns || 1; + } + let xSize = block.children.length; + if (columns > 0 && columns < numItems) { + xSize = columns; + } + block.widthInColumns || 1; + const ySize = Math.ceil(numItems / xSize); + let width = xSize * (maxWidth + padding) + padding; + let height = ySize * (maxHeight + padding) + padding; + if (width < siblingWidth) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug( + `Detected to small siebling: abc95 ${block.id} sieblingWidth ${siblingWidth} sieblingHeight ${siblingHeight} width ${width}` + ); + width = siblingWidth; + height = siblingHeight; + const childWidth = (siblingWidth - xSize * padding - padding) / xSize; + const childHeight = (siblingHeight - ySize * padding - padding) / ySize; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Size indata abc88", block.id, "childWidth", childWidth, "maxWidth", maxWidth); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Size indata abc88", block.id, "childHeight", childHeight, "maxHeight", maxHeight); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Size indata abc88 xSize", xSize, "padding", padding); + for (const child of block.children) { + if (child.size) { + child.size.width = childWidth; + child.size.height = childHeight; + child.size.x = 0; + child.size.y = 0; + } + } + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug( + `abc95 (finale calc) ${block.id} xSize ${xSize} ySize ${ySize} columns ${columns}${block.children.length} width=${Math.max(width, ((_d = block.size) == null ? void 0 : _d.width) || 0)}` + ); + if (width < (((_e = block == null ? void 0 : block.size) == null ? void 0 : _e.width) || 0)) { + width = ((_f = block == null ? void 0 : block.size) == null ? void 0 : _f.width) || 0; + const num = columns > 0 ? Math.min(block.children.length, columns) : block.children.length; + if (num > 0) { + const childWidth = (width - num * padding - padding) / num; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("abc95 (growing to fit) width", block.id, width, (_g = block.size) == null ? void 0 : _g.width, childWidth); + for (const child of block.children) { + if (child.size) { + child.size.width = childWidth; + } + } + } + } + block.size = { + width, + height, + x: 0, + y: 0 + }; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug( + "setBlockSizes abc94 (done)", + block.id, + (_h = block == null ? void 0 : block.size) == null ? void 0 : _h.x, + (_i = block == null ? void 0 : block.size) == null ? void 0 : _i.width, + (_j = block == null ? void 0 : block.size) == null ? void 0 : _j.y, + (_k = block == null ? void 0 : block.size) == null ? void 0 : _k.height + ); +} +function layoutBlocks(block, db2) { + var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug( + `abc85 layout blocks (=>layoutBlocks) ${block.id} x: ${(_a2 = block == null ? void 0 : block.size) == null ? void 0 : _a2.x} y: ${(_b2 = block == null ? void 0 : block.size) == null ? void 0 : _b2.y} width: ${(_c = block == null ? void 0 : block.size) == null ? void 0 : _c.width}` + ); + const columns = block.columns || -1; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("layoutBlocks columns abc95", block.id, "=>", columns, block); + if (block.children && // find max width of children + block.children.length > 0) { + const width = ((_e = (_d = block == null ? void 0 : block.children[0]) == null ? void 0 : _d.size) == null ? void 0 : _e.width) || 0; + const widthOfChildren = block.children.length * width + (block.children.length - 1) * padding; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("widthOfChildren 88", widthOfChildren, "posX"); + let columnPos = 0; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("abc91 block?.size?.x", block.id, (_f = block == null ? void 0 : block.size) == null ? void 0 : _f.x); + let startingPosX = ((_g = block == null ? void 0 : block.size) == null ? void 0 : _g.x) ? ((_h = block == null ? void 0 : block.size) == null ? void 0 : _h.x) + (-((_i = block == null ? void 0 : block.size) == null ? void 0 : _i.width) / 2 || 0) : -padding; + let rowPos = 0; + for (const child of block.children) { + const parent = block; + if (!child.size) { + continue; + } + const { width: width2, height } = child.size; + const { px, py } = calculateBlockPosition(columns, columnPos); + if (py != rowPos) { + rowPos = py; + startingPosX = ((_j = block == null ? void 0 : block.size) == null ? void 0 : _j.x) ? ((_k = block == null ? void 0 : block.size) == null ? void 0 : _k.x) + (-((_l = block == null ? void 0 : block.size) == null ? void 0 : _l.width) / 2 || 0) : -padding; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("New row in layout for block", block.id, " and child ", child.id, rowPos); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug( + `abc89 layout blocks (child) id: ${child.id} Pos: ${columnPos} (px, py) ${px},${py} (${(_m = parent == null ? void 0 : parent.size) == null ? void 0 : _m.x},${(_n = parent == null ? void 0 : parent.size) == null ? void 0 : _n.y}) parent: ${parent.id} width: ${width2}${padding}` + ); + if (parent.size) { + const halfWidth = width2 / 2; + child.size.x = startingPosX + padding + halfWidth; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug( + `abc91 layout blocks (calc) px, pyid:${child.id} startingPos=X${startingPosX} new startingPosX${child.size.x} ${halfWidth} padding=${padding} width=${width2} halfWidth=${halfWidth} => x:${child.size.x} y:${child.size.y} ${child.widthInColumns} (width * (child?.w || 1)) / 2 ${width2 * ((child == null ? void 0 : child.widthInColumns) || 1) / 2}` + ); + startingPosX = child.size.x + halfWidth; + child.size.y = parent.size.y - parent.size.height / 2 + py * (height + padding) + height / 2 + padding; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug( + `abc88 layout blocks (calc) px, pyid:${child.id}startingPosX${startingPosX}${padding}${halfWidth}=>x:${child.size.x}y:${child.size.y}${child.widthInColumns}(width * (child?.w || 1)) / 2${width2 * ((child == null ? void 0 : child.widthInColumns) || 1) / 2}` + ); + } + if (child.children) { + layoutBlocks(child); + } + columnPos += (child == null ? void 0 : child.widthInColumns) || 1; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("abc88 columnsPos", child, columnPos); + } + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug( + `layout blocks (<==layoutBlocks) ${block.id} x: ${(_o = block == null ? void 0 : block.size) == null ? void 0 : _o.x} y: ${(_p = block == null ? void 0 : block.size) == null ? void 0 : _p.y} width: ${(_q = block == null ? void 0 : block.size) == null ? void 0 : _q.width}` + ); +} +function findBounds(block, { minX, minY, maxX, maxY } = { minX: 0, minY: 0, maxX: 0, maxY: 0 }) { + if (block.size && block.id !== "root") { + const { x, y, width, height } = block.size; + if (x - width / 2 < minX) { + minX = x - width / 2; + } + if (y - height / 2 < minY) { + minY = y - height / 2; + } + if (x + width / 2 > maxX) { + maxX = x + width / 2; + } + if (y + height / 2 > maxY) { + maxY = y + height / 2; + } + } + if (block.children) { + for (const child of block.children) { + ({ minX, minY, maxX, maxY } = findBounds(child, { minX, minY, maxX, maxY })); + } + } + return { minX, minY, maxX, maxY }; +} +function layout(db2) { + const root = db2.getBlock("root"); + if (!root) { + return; + } + setBlockSizes(root, db2, 0, 0); + layoutBlocks(root); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("getBlocks", JSON.stringify(root, null, 2)); + const { minX, minY, maxX, maxY } = findBounds(root); + const height = maxY - minY; + const width = maxX - minX; + return { x: minX, y: minY, width, height }; +} +const getClasses = function(text, diagObj) { + return diagObj.db.getClasses(); +}; +const draw = async function(text, id, _version, diagObj) { + const { securityLevel, block: conf } = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.F)(); + const db2 = diagObj.db; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)("body"); + const svg = securityLevel === "sandbox" ? root.select(`[id="${id}"]`) : (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)(`[id="${id}"]`); + const markers = ["point", "circle", "cross"]; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_9__.a)(svg, markers, diagObj.type, id); + const bl = db2.getBlocks(); + const blArr = db2.getBlocksFlat(); + const edges = db2.getEdges(); + const nodes = svg.insert("g").attr("class", "block"); + await calculateBlockSizes(nodes, bl, db2); + const bounds = layout(db2); + await insertBlocks(nodes, bl, db2); + await insertEdges(nodes, edges, blArr, db2, id); + if (bounds) { + const bounds2 = bounds; + const magicFactor = Math.max(1, Math.round(0.125 * (bounds2.width / bounds2.height))); + const height = bounds2.height + magicFactor + 10; + const width = bounds2.width + 10; + const { useMaxWidth } = conf; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.i)(svg, height, width, !!useMaxWidth); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Here Bounds", bounds, bounds2); + svg.attr( + "viewBox", + `${bounds2.x - 5} ${bounds2.y - 5} ${bounds2.width + 10} ${bounds2.height + 10}` + ); + } + (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .scaleOrdinal */ .UMr)(d3__WEBPACK_IMPORTED_MODULE_1__/* .schemeTableau10 */ .zt); +}; +const renderer = { + draw, + getClasses +}; +const diagram = { + parser: parser$1, + db: db$1, + renderer, + styles: flowStyles +}; + + + +/***/ }), + +/***/ 40351: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-f47111a7.js + 8 modules +var mermaid_f47111a7 = __webpack_require__(76257); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {Array} items + * Items to add to `list`. + * @returns {Array} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record} */ + const left = maybe || (all[hook] = {}) + /** @type {Record | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array} existing + * @param {Array} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array} */ + let parameters + /** @type {Array} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array} events + * @param {number} eventIndex + * @returns {Record} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record} */ + const gaps = {} + /** @type {Array} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record} */ + const columnStart = {} + /** @type {Array} */ + const resolveAllConstructs = [] + /** @type {Array} */ + let chunks = [] + /** @type {Array} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array} chunks + * @param {Pick} token + * @returns {Array} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * + * b> + * + * + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`` or `b`). + * @param {TokenType} literalType + * Type when enclosed (``). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * . + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * . + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After ` | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | &<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | + * ^^ + * > | + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > |
+ * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after ` | + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > |
+ * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + *

!^a

+ *

!^a

+ * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | ab + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a c + * ^ + * > | a c + * ^ + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * > | a c + * ^ + * > | a &<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after ` | a c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After ` | a &<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a &<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array} events + * @returns {Array} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract} Parent + * + * @typedef {Omit & {type: 'fragment', children: Array}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array} transforms + * Tree transforms. + * + * @typedef {Partial} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array} stack + * Stack of nodes. + * @property {Array} tokenStack + * Stack of tokens. + * @property {(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(60513); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-6b48ae7d.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.T)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "
"); + } else if (node.type === "strong") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "emphasis") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "paragraph") { + return `

${node.children.map(output).join("")}

`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + " + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_f47111a7.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_f47111a7.M)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 28747: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ insertMarkers$1), +/* harmony export */ b: () => (/* binding */ clear$1), +/* harmony export */ c: () => (/* binding */ createLabel$1), +/* harmony export */ d: () => (/* binding */ clear), +/* harmony export */ e: () => (/* binding */ insertNode), +/* harmony export */ f: () => (/* binding */ insertEdgeLabel), +/* harmony export */ g: () => (/* binding */ getSubGraphTitleMargins), +/* harmony export */ h: () => (/* binding */ insertEdge), +/* harmony export */ i: () => (/* binding */ intersectRect$1), +/* harmony export */ j: () => (/* binding */ positionEdgeLabel), +/* harmony export */ k: () => (/* binding */ getLineFunctionsWithOffset), +/* harmony export */ l: () => (/* binding */ labelHelper), +/* harmony export */ m: () => (/* binding */ addEdgeMarkers), +/* harmony export */ p: () => (/* binding */ positionNode), +/* harmony export */ s: () => (/* binding */ setNodeElem), +/* harmony export */ u: () => (/* binding */ updateNodeBounds) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(40351); + + + +const insertMarkers = (elem, markerArray, type, id) => { + markerArray.forEach((markerName) => { + markers[markerName](elem, type, id); + }); +}; +const extension = (elem, type, id) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Making markers for ", id); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); +}; +const composition = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const aggregation = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const dependency = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 6).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const lollipop = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopEnd").attr("class", "marker lollipop " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); +}; +const point = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 6).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 4.5).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const circle$1 = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const cross = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); +}; +const barb = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const markers = { + extension, + composition, + aggregation, + dependency, + lollipop, + point, + circle: circle$1, + cross, + barb +}; +const insertMarkers$1 = insertMarkers; +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlLabel(node) { + const fo = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + '" + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "inline-block"); + div.style("white-space", "nowrap"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + return fo.node(); +} +const createLabel = (_vertexText, style, isTitle, isNode) => { + let vertexText = _vertexText || ""; + if (typeof vertexText === "object") { + vertexText = vertexText[0]; + } + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + vertexText = vertexText.replace(/\\n|\n/g, "
"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("vertexText" + vertexText); + const node = { + isNode, + label: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(vertexText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + let vertexNode = addHtmlLabel(node); + return vertexNode; + } else { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", style.replace("color:", "fill:")); + let rows = []; + if (typeof vertexText === "string") { + rows = vertexText.split(/\\n|\n|/gi); + } else if (Array.isArray(vertexText)) { + rows = vertexText; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + if (isTitle) { + tspan.setAttribute("class", "title-row"); + } else { + tspan.setAttribute("class", "row"); + } + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; + } +}; +const createLabel$1 = createLabel; +const labelHelper = async (parent, node, _classes, isNode) => { + let classes; + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + if (!_classes) { + classes = "node default"; + } else { + classes = _classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle); + let labelText; + if (node.labelText === void 0) { + labelText = ""; + } else { + labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0]; + } + const textNode = label.node(); + let text; + if (node.labelType === "markdown") { + text = (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__.a)(label, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(labelText), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()), { + useHtmlLabels, + width: node.width || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.wrappingWidth, + classes: "markdown-node-label" + }); + } else { + text = textNode.appendChild( + createLabel$1( + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(labelText), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()), + node.labelStyle, + false, + isNode + ) + ); + } + let bbox = text.getBBox(); + const halfPadding = node.padding / 2; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text); + const images = div.getElementsByTagName("img"); + if (images) { + const noImgText = labelText.replace(/]*>/g, "").trim() === ""; + await Promise.all( + [...images].map( + (img) => new Promise((res) => { + function setupImage() { + img.style.display = "flex"; + img.style.flexDirection = "column"; + if (noImgText) { + const bodyFontSize = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize ? (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize : window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + const width = parseInt(bodyFontSize, 10) * enlargingFactor + "px"; + img.style.minWidth = width; + img.style.maxWidth = width; + } else { + img.style.width = "100%"; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener("error", setupImage); + img.addEventListener("load", setupImage); + }) + ) + ); + } + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (useHtmlLabels) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } else { + label.attr("transform", "translate(0, " + -bbox.height / 2 + ")"); + } + if (node.centerLabel) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } + label.insert("rect", ":first-child"); + return { shapeSvg, bbox, halfPadding, label }; +}; +const updateNodeBounds = (node, element) => { + const bbox = element.node().getBBox(); + node.width = bbox.width; + node.height = bbox.height; +}; +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +function intersectNode(node, point2) { + return node.intersect(point2); +} +function intersectEllipse(node, rx, ry, point2) { + var cx = node.x; + var cy = node.y; + var px = cx - point2.x; + var py = cy - point2.y; + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + var dx = Math.abs(rx * ry * px / det); + if (point2.x < cx) { + dx = -dx; + } + var dy = Math.abs(rx * ry * py / det); + if (point2.y < cy) { + dy = -dy; + } + return { x: cx + dx, y: cy + dy }; +} +function intersectCircle(node, rx, point2) { + return intersectEllipse(node, rx, rx, point2); +} +function intersectLine(p1, p2, q1, q2) { + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return; + } + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return; + } + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return; + } + offset = Math.abs(denom / 2); + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + return { x, y }; +} +function sameSign(r1, r2) { + return r1 * r2 > 0; +} +function intersectPolygon(node, polyPoints, point2) { + var x1 = node.x; + var y1 = node.y; + var intersections = []; + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + if (typeof polyPoints.forEach === "function") { + polyPoints.forEach(function(entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + } else { + minX = Math.min(minX, polyPoints.x); + minY = Math.min(minY, polyPoints.y); + } + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect2 = intersectLine( + node, + point2, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect2) { + intersections.push(intersect2); + } + } + if (!intersections.length) { + return node; + } + if (intersections.length > 1) { + intersections.sort(function(p, q) { + var pdx = p.x - point2.x; + var pdy = p.y - point2.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + var qdx = q.x - point2.x; + var qdy = q.y - point2.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} +const intersectRect = (node, point2) => { + var x = node.x; + var y = node.y; + var dx = point2.x - x; + var dy = point2.y - y; + var w = node.width / 2; + var h = node.height / 2; + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : h * dx / dy; + sy = h; + } else { + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : w * dy / dx; + } + return { x: x + sx, y: y + sy }; +}; +const intersectRect$1 = intersectRect; +const intersect = { + node: intersectNode, + circle: intersectCircle, + ellipse: intersectEllipse, + polygon: intersectPolygon, + rect: intersectRect$1 +}; +const note = async (parent, node) => { + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels; + if (!useHtmlLabels) { + node.centerLabel = true; + } + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Classes = ", node.classes); + const rect2 = shapeSvg.insert("rect", ":first-child"); + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const note$1 = note; +const expandAndDeduplicateDirections = (directions) => { + const uniqueDirections = /* @__PURE__ */ new Set(); + for (const direction of directions) { + switch (direction) { + case "x": + uniqueDirections.add("right"); + uniqueDirections.add("left"); + break; + case "y": + uniqueDirections.add("up"); + uniqueDirections.add("down"); + break; + default: + uniqueDirections.add(direction); + break; + } + } + return uniqueDirections; +}; +const getArrowPoints = (duplicatedDirections, bbox, node) => { + const directions = expandAndDeduplicateDirections(duplicatedDirections); + const f = 2; + const height = bbox.height + 2 * node.padding; + const midpoint = height / f; + const width = bbox.width + 2 * midpoint + node.padding; + const padding = node.padding / 2; + if (directions.has("right") && directions.has("left") && directions.has("up") && directions.has("down")) { + return [ + // Bottom + { x: 0, y: 0 }, + { x: midpoint, y: 0 }, + { x: width / 2, y: 2 * padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: 0 }, + // Right + { x: width, y: -height / 3 }, + { x: width + 2 * padding, y: -height / 2 }, + { x: width, y: -2 * height / 3 }, + { x: width, y: -height }, + // Top + { x: width - midpoint, y: -height }, + { x: width / 2, y: -height - 2 * padding }, + { x: midpoint, y: -height }, + // Left + { x: 0, y: -height }, + { x: 0, y: -2 * height / 3 }, + { x: -2 * padding, y: -height / 2 }, + { x: 0, y: -height / 3 } + ]; + } + if (directions.has("right") && directions.has("left") && directions.has("up")) { + return [ + { x: midpoint, y: 0 }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("right") && directions.has("left") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: midpoint, y: -height }, + { x: width - midpoint, y: -height }, + { x: width, y: 0 } + ]; + } + if (directions.has("right") && directions.has("up") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: width, y: -midpoint }, + { x: width, y: -height + midpoint }, + { x: 0, y: -height } + ]; + } + if (directions.has("left") && directions.has("up") && directions.has("down")) { + return [ + { x: width, y: 0 }, + { x: 0, y: -midpoint }, + { x: 0, y: -height + midpoint }, + { x: width, y: -height } + ]; + } + if (directions.has("right") && directions.has("left")) { + return [ + { x: midpoint, y: 0 }, + { x: midpoint, y: -padding }, + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: width - midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("up") && directions.has("down")) { + return [ + // Bottom center + { x: width / 2, y: 0 }, + // Left pont of bottom arrow + { x: 0, y: -padding }, + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: 0, y: -height + padding }, + // Top of arrow + { x: width / 2, y: -height }, + { x: width, y: -height + padding }, + // Top of right vertical bar + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding }, + { x: width, y: -padding } + ]; + } + if (directions.has("right") && directions.has("up")) { + return [ + { x: 0, y: 0 }, + { x: width, y: -midpoint }, + { x: 0, y: -height } + ]; + } + if (directions.has("right") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: width, y: 0 }, + { x: 0, y: -height } + ]; + } + if (directions.has("left") && directions.has("up")) { + return [ + { x: width, y: 0 }, + { x: 0, y: -midpoint }, + { x: width, y: -height } + ]; + } + if (directions.has("left") && directions.has("down")) { + return [ + { x: width, y: 0 }, + { x: 0, y: 0 }, + { x: width, y: -height } + ]; + } + if (directions.has("right")) { + return [ + { x: midpoint, y: -padding }, + { x: midpoint, y: -padding }, + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: width - midpoint, y: -height + padding }, + // top left corner of arrow + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding } + ]; + } + if (directions.has("left")) { + return [ + { x: midpoint, y: 0 }, + { x: midpoint, y: -padding }, + // Two points, the right corners + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("up")) { + return [ + // Bottom center + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: 0, y: -height + padding }, + // Top of arrow + { x: width / 2, y: -height }, + { x: width, y: -height + padding }, + // Top of right vertical bar + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding } + ]; + } + if (directions.has("down")) { + return [ + // Bottom center + { x: width / 2, y: 0 }, + // Left pont of bottom arrow + { x: 0, y: -padding }, + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding }, + { x: width, y: -padding } + ]; + } + return [{ x: 0, y: 0 }]; +}; +const formatClass = (str) => { + if (str) { + return " " + str; + } + return ""; +}; +const getClassesFromNode = (node, otherClasses) => { + return `${otherClasses ? otherClasses : "node default"}${formatClass(node.classes)} ${formatClass( + node.class + )}`; +}; +const question = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const s = w + h; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Question main (Circle)"); + const questionElem = insertPolygonShape(shapeSvg, s, s, points); + questionElem.attr("style", node.style); + updateNodeBounds(node, questionElem); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("Intersect called"); + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const choice = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const s = 28; + const points = [ + { x: 0, y: s / 2 }, + { x: s / 2, y: 0 }, + { x: 0, y: -s / 2 }, + { x: -s / 2, y: 0 } + ]; + const choice2 = shapeSvg.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ); + choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28); + node.width = 28; + node.height = 28; + node.intersect = function(point2) { + return intersect.circle(node, 14, point2); + }; + return shapeSvg; +}; +const hexagon = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const f = 4; + const h = bbox.height + node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const hex = insertPolygonShape(shapeSvg, w, h, points); + hex.attr("style", node.style); + updateNodeBounds(node, hex); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const block_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true); + const f = 2; + const h = bbox.height + 2 * node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = getArrowPoints(node.directions, bbox, node); + const blockArrow = insertPolygonShape(shapeSvg, w, h, points); + blockArrow.attr("style", node.style); + updateNodeBounds(node, blockArrow); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_left_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + node.width = w + h; + node.height = h; + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_right = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_left = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const inv_trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_right_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const cylinder = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry + node.padding; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const el = shapeSvg.attr("label-offset-y", ry).insert("path", ":first-child").attr("style", node.style).attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + updateNodeBounds(node, el); + node.intersect = function(point2) { + const pos = intersect.rect(node, point2); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point2.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +}; +const rect = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes + " " + node.class, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding; + const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding; + rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const composite = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding; + const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding; + rect2.attr("class", "basic cluster composite label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const labelRect = async (parent, node) => { + const { shapeSvg } = await labelHelper(parent, node, "label", true); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Classes = ", node.class); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = 0; + const totalHeight = 0; + rect2.attr("width", totalWidth).attr("height", totalHeight); + shapeSvg.attr("class", "label edgeLabel"); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) { + const strokeDashArray = []; + const addBorder = (length) => { + strokeDashArray.push(length, 0); + }; + const skipBorder = (length) => { + strokeDashArray.push(0, length); + }; + if (borders.includes("t")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add top border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("r")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add right border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + if (borders.includes("b")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add bottom border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("l")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add left border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + rect2.attr("stroke-dasharray", strokeDashArray.join(" ")); +} +const rectWithTitle = (parent, node) => { + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const innerLine = shapeSvg.insert("line"); + const label = shapeSvg.insert("g").attr("class", "label"); + const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText; + let title = ""; + if (typeof text2 === "object") { + title = text2[0]; + } else { + title = text2; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Label text abc79", title, text2, typeof text2 === "object"); + const text = label.node().appendChild(createLabel$1(title, node.labelStyle, true, true)); + let bbox = { width: 0, height: 0 }; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Text 2", text2); + const textRows = text2.slice(1, text2.length); + let titleBox = text.getBBox(); + const descr = label.node().appendChild( + createLabel$1(textRows.join ? textRows.join("
") : textRows, node.labelStyle, true, true) + ); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = descr.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(descr); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const halfPadding = node.padding / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(descr).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")" + ); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)" + ); + bbox = label.node().getBBox(); + label.attr( + "transform", + "translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")" + ); + rect2.attr("class", "outer title-state").attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + innerLine.attr("class", "divider").attr("x1", -bbox.width / 2 - halfPadding).attr("x2", bbox.width / 2 + halfPadding).attr("y1", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr("y2", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const stadium = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const h = bbox.height + node.padding; + const w = bbox.width + h / 4 + node.padding; + const rect2 = shapeSvg.insert("rect", ":first-child").attr("style", node.style).attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const circle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle main"); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle intersect", node, bbox.width / 2 + halfPadding, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding, point2); + }; + return shapeSvg; +}; +const doublecircle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const gap = 5; + const circleGroup = shapeSvg.insert("g", ":first-child"); + const outerCircle = circleGroup.insert("circle"); + const innerCircle = circleGroup.insert("circle"); + circleGroup.attr("class", node.class); + outerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding + gap).attr("width", bbox.width + node.padding + gap * 2).attr("height", bbox.height + node.padding + gap * 2); + innerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle main"); + updateNodeBounds(node, outerCircle); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point2); + }; + return shapeSvg; +}; +const subroutine = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const start = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const forkJoin = (parent, node, dir) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + let width = 70; + let height = 10; + if (dir === "LR") { + width = 10; + height = 70; + } + const shape = shapeSvg.append("rect").attr("x", -1 * width / 2).attr("y", -1 * height / 2).attr("width", width).attr("height", height).attr("class", "fork-join"); + updateNodeBounds(node, shape); + node.height = node.height + node.padding / 2; + node.width = node.width + node.padding / 2; + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const end = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const innerCircle = shapeSvg.insert("circle", ":first-child"); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const class_box = (parent, node) => { + const halfPadding = node.padding / 2; + const rowPadding = 4; + const lineHeight = 8; + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const topLine = shapeSvg.insert("line"); + const bottomLine = shapeSvg.insert("line"); + let maxWidth = 0; + let maxHeight = rowPadding; + const labelContainer = shapeSvg.insert("g").attr("class", "label"); + let verticalPos = 0; + const hasInterface = node.classData.annotations && node.classData.annotations[0]; + const interfaceLabelText = node.classData.annotations[0] ? "«" + node.classData.annotations[0] + "»" : ""; + const interfaceLabel = labelContainer.node().appendChild(createLabel$1(interfaceLabelText, node.labelStyle, true, true)); + let interfaceBBox = interfaceLabel.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = interfaceLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(interfaceLabel); + interfaceBBox = div.getBoundingClientRect(); + dv.attr("width", interfaceBBox.width); + dv.attr("height", interfaceBBox.height); + } + if (node.classData.annotations[0]) { + maxHeight += interfaceBBox.height + rowPadding; + maxWidth += interfaceBBox.width; + } + let classTitleString = node.classData.label; + if (node.classData.type !== void 0 && node.classData.type !== "") { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + classTitleString += "<" + node.classData.type + ">"; + } else { + classTitleString += "<" + node.classData.type + ">"; + } + } + const classTitleLabel = labelContainer.node().appendChild(createLabel$1(classTitleString, node.labelStyle, true, true)); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel).attr("class", "classTitle"); + let classTitleBBox = classTitleLabel.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = classTitleLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel); + classTitleBBox = div.getBoundingClientRect(); + dv.attr("width", classTitleBBox.width); + dv.attr("height", classTitleBBox.height); + } + maxHeight += classTitleBBox.height + rowPadding; + if (classTitleBBox.width > maxWidth) { + maxWidth = classTitleBBox.width; + } + const classAttributes = []; + node.classData.members.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let parsedText = parsedInfo.displayText; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + parsedText = parsedText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + parsedText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classAttributes.push(lbl); + }); + maxHeight += lineHeight; + const classMethods = []; + node.classData.methods.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let displayText = parsedInfo.displayText; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + displayText = displayText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + displayText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classMethods.push(lbl); + }); + maxHeight += lineHeight; + if (hasInterface) { + let diffX2 = (maxWidth - interfaceBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(interfaceLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")" + ); + verticalPos = interfaceBBox.height + rowPadding; + } + let diffX = (maxWidth - classTitleBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + verticalPos += classTitleBBox.height + rowPadding; + topLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classAttributes.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + verticalPos += lineHeight; + bottomLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classMethods.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + rect2.attr("style", node.style).attr("class", "outer title-state").attr("x", -maxWidth / 2 - halfPadding).attr("y", -(maxHeight / 2) - halfPadding).attr("width", maxWidth + node.padding).attr("height", maxHeight + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const shapes = { + rhombus: question, + composite, + question, + rect, + labelRect, + rectWithTitle, + choice, + circle, + doublecircle, + stadium, + hexagon, + block_arrow, + rect_left_inv_arrow, + lean_right, + lean_left, + trapezoid, + inv_trapezoid, + rect_right_inv_arrow, + cylinder, + start, + end, + note: note$1, + subroutine, + fork: forkJoin, + join: forkJoin, + class_box +}; +let nodeElems = {}; +const insertNode = async (elem, node, dir) => { + let newEl; + let el; + if (node.link) { + let target; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel === "sandbox") { + target = "_top"; + } else if (node.linkTarget) { + target = node.linkTarget || "_blank"; + } + newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target); + el = await shapes[node.shape](newEl, node, dir); + } else { + el = await shapes[node.shape](elem, node, dir); + newEl = el; + } + if (node.tooltip) { + el.attr("title", node.tooltip); + } + if (node.class) { + el.attr("class", "node default " + node.class); + } + newEl.attr("data-node", "true"); + newEl.attr("data-id", node.id); + nodeElems[node.id] = newEl; + if (node.haveCallback) { + nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable"); + } + return newEl; +}; +const setNodeElem = (elem, node) => { + nodeElems[node.id] = elem; +}; +const clear$1 = () => { + nodeElems = {}; +}; +const positionNode = (node) => { + const el = nodeElems[node.id]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace( + "Transforming node", + node.diff, + node, + "translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")" + ); + const padding = 8; + const diff = node.diff || 0; + if (node.clusterNode) { + el.attr( + "transform", + "translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")" + ); + } else { + el.attr("transform", "translate(" + node.x + ", " + node.y + ")"); + } + return diff; +}; +const getSubGraphTitleMargins = ({ + flowchart +}) => { + var _a, _b; + const subGraphTitleTopMargin = ((_a = flowchart == null ? void 0 : flowchart.subGraphTitleMargin) == null ? void 0 : _a.top) ?? 0; + const subGraphTitleBottomMargin = ((_b = flowchart == null ? void 0 : flowchart.subGraphTitleMargin) == null ? void 0 : _b.bottom) ?? 0; + const subGraphTitleTotalMargin = subGraphTitleTopMargin + subGraphTitleBottomMargin; + return { + subGraphTitleTopMargin, + subGraphTitleBottomMargin, + subGraphTitleTotalMargin + }; +}; +const markerOffsets = { + aggregation: 18, + extension: 18, + composition: 18, + dependency: 6, + lollipop: 13.5, + arrow_point: 5.3 +}; +function calculateDeltaAndAngle(point1, point2) { + if (point1 === void 0 || point2 === void 0) { + return { angle: 0, deltaX: 0, deltaY: 0 }; + } + point1 = pointTransformer(point1); + point2 = pointTransformer(point2); + const [x1, y1] = [point1.x, point1.y]; + const [x2, y2] = [point2.x, point2.y]; + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY }; +} +const pointTransformer = (data) => { + if (Array.isArray(data)) { + return { x: data[0], y: data[1] }; + } + return data; +}; +const getLineFunctionsWithOffset = (edge) => { + return { + x: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaX } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } + return pointTransformer(d).x + offset; + }, + y: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaY } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } + return pointTransformer(d).y + offset; + } + }; +}; +const addEdgeMarkers = (svgPath, edge, url, id, diagramType) => { + if (edge.arrowTypeStart) { + addEdgeMarker(svgPath, "start", edge.arrowTypeStart, url, id, diagramType); + } + if (edge.arrowTypeEnd) { + addEdgeMarker(svgPath, "end", edge.arrowTypeEnd, url, id, diagramType); + } +}; +const arrowTypesMap = { + arrow_cross: "cross", + arrow_point: "point", + arrow_barb: "barb", + arrow_circle: "circle", + aggregation: "aggregation", + extension: "extension", + composition: "composition", + dependency: "dependency", + lollipop: "lollipop" +}; +const addEdgeMarker = (svgPath, position, arrowType, url, id, diagramType) => { + const endMarkerType = arrowTypesMap[arrowType]; + if (!endMarkerType) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown arrow type: ${arrowType}`); + return; + } + const suffix = position === "start" ? "Start" : "End"; + svgPath.attr(`marker-${position}`, `url(${url}#${id}_${diagramType}-${endMarkerType}${suffix})`); +}; +let edgeLabels = {}; +let terminalLabels = {}; +const clear = () => { + edgeLabels = {}; + terminalLabels = {}; +}; +const insertEdgeLabel = (elem, edge) => { + const useHtmlLabels = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + const labelElement = edge.labelType === "markdown" ? (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__.a)(elem, edge.label, { + style: edge.labelStyle, + useHtmlLabels, + addSvgBackground: true + }) : createLabel$1(edge.label, edge.labelStyle); + const edgeLabel = elem.insert("g").attr("class", "edgeLabel"); + const label = edgeLabel.insert("g").attr("class", "label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + if (useHtmlLabels) { + const div = labelElement.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(labelElement); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + edgeLabels[edge.id] = edgeLabel; + edge.width = bbox.width; + edge.height = bbox.height; + let fo; + if (edge.startLabelLeft) { + const startLabelElement = createLabel$1(edge.startLabelLeft, edge.labelStyle); + const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startLeft = startEdgeLabelLeft; + setTerminalWidth(fo, edge.startLabelLeft); + } + if (edge.startLabelRight) { + const startLabelElement = createLabel$1(edge.startLabelRight, edge.labelStyle); + const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelRight.insert("g").attr("class", "inner"); + fo = startEdgeLabelRight.node().appendChild(startLabelElement); + inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startRight = startEdgeLabelRight; + setTerminalWidth(fo, edge.startLabelRight); + } + if (edge.endLabelLeft) { + const endLabelElement = createLabel$1(edge.endLabelLeft, edge.labelStyle); + const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelLeft.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endLeft = endEdgeLabelLeft; + setTerminalWidth(fo, edge.endLabelLeft); + } + if (edge.endLabelRight) { + const endLabelElement = createLabel$1(edge.endLabelRight, edge.labelStyle); + const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelRight.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelRight.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endRight = endEdgeLabelRight; + setTerminalWidth(fo, edge.endLabelRight); + } + return labelElement; +}; +function setTerminalWidth(fo, value) { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels && fo) { + fo.style.width = value.length * 9 + "px"; + fo.style.height = "12px"; + } +} +const positionEdgeLabel = (edge, paths) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("Moving label abc88 ", edge.id, edge.label, edgeLabels[edge.id], paths); + let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig); + if (edge.label) { + const el = edgeLabels[edge.id]; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcLabelPosition(path); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug( + "Moving label " + edge.label + " from (", + x, + ",", + y, + ") to (", + pos.x, + ",", + pos.y, + ") abc88" + ); + if (paths.updatedPath) { + x = pos.x; + y = pos.y; + } + } + el.attr("transform", `translate(${x}, ${y + subGraphTitleTotalMargin / 2})`); + } + if (edge.startLabelLeft) { + const el = terminalLabels[edge.id].startLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.startLabelRight) { + const el = terminalLabels[edge.id].startRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition( + edge.arrowTypeStart ? 10 : 0, + "start_right", + path + ); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.endLabelLeft) { + const el = terminalLabels[edge.id].endLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.endLabelRight) { + const el = terminalLabels[edge.id].endRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } +}; +const outsideNode = (node, point2) => { + const x = node.x; + const y = node.y; + const dx = Math.abs(point2.x - x); + const dy = Math.abs(point2.y - y); + const w = node.width / 2; + const h = node.height / 2; + if (dx >= w || dy >= h) { + return true; + } + return false; +}; +const intersection = (node, outsidePoint, insidePoint) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`intersection calc abc89: + outsidePoint: ${JSON.stringify(outsidePoint)} + insidePoint : ${JSON.stringify(insidePoint)} + node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`); + const x = node.x; + const y = node.y; + const dx = Math.abs(x - insidePoint.x); + const w = node.width / 2; + let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; + const h = node.height / 2; + const Q = Math.abs(outsidePoint.y - insidePoint.y); + const R = Math.abs(outsidePoint.x - insidePoint.x); + if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { + let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y; + r = R * q / Q; + const res = { + x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r, + y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q + }; + if (r === 0) { + res.x = outsidePoint.x; + res.y = outsidePoint.y; + } + if (R === 0) { + res.x = outsidePoint.x; + } + if (Q === 0) { + res.y = outsidePoint.y; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res); + return res; + } else { + if (insidePoint.x < outsidePoint.x) { + r = outsidePoint.x - w - x; + } else { + r = x - w - outsidePoint.x; + } + let q = Q * r / R; + let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r; + let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y }); + if (r === 0) { + _x = outsidePoint.x; + _y = outsidePoint.y; + } + if (R === 0) { + _x = outsidePoint.x; + } + if (Q === 0) { + _y = outsidePoint.y; + } + return { x: _x, y: _y }; + } +}; +const cutPathAtIntersect = (_points, boundaryNode) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("abc88 cutPathAtIntersect", _points, boundaryNode); + let points = []; + let lastPointOutside = _points[0]; + let isInside = false; + _points.forEach((point2) => { + if (!outsideNode(boundaryNode, point2) && !isInside) { + const inter = intersection(boundaryNode, lastPointOutside, point2); + let pointPresent = false; + points.forEach((p) => { + pointPresent = pointPresent || p.x === inter.x && p.y === inter.y; + }); + if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { + points.push(inter); + } + isInside = true; + } else { + lastPointOutside = point2; + if (!isInside) { + points.push(point2); + } + } + }); + return points; +}; +const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph, id) { + let points = edge.points; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("abc88 InsertEdge: edge=", edge, "e=", e); + let pointsHasChanged = false; + const tail = graph.node(e.v); + var head = graph.node(e.w); + if ((head == null ? void 0 : head.intersect) && (tail == null ? void 0 : tail.intersect)) { + points = points.slice(1, edge.points.length - 1); + points.unshift(tail.intersect(points[0])); + points.push(head.intersect(points[points.length - 1])); + } + if (edge.toCluster) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("to cluster abc88", clusterDb[edge.toCluster]); + points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); + pointsHasChanged = true; + } + if (edge.fromCluster) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("from cluster abc88", clusterDb[edge.fromCluster]); + points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse(); + pointsHasChanged = true; + } + const lineData = points.filter((p) => !Number.isNaN(p.y)); + let curve = d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .qrM; + if (edge.curve && (diagramType === "graph" || diagramType === "flowchart")) { + curve = edge.curve; + } + const { x, y } = getLineFunctionsWithOffset(edge); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .n8j)().x(x).y(y).curve(curve); + let strokeClasses; + switch (edge.thickness) { + case "normal": + strokeClasses = "edge-thickness-normal"; + break; + case "thick": + strokeClasses = "edge-thickness-thick"; + break; + case "invisible": + strokeClasses = "edge-thickness-thick"; + break; + default: + strokeClasses = ""; + } + switch (edge.pattern) { + case "solid": + strokeClasses += " edge-pattern-solid"; + break; + case "dotted": + strokeClasses += " edge-pattern-dotted"; + break; + case "dashed": + strokeClasses += " edge-pattern-dashed"; + break; + } + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style); + let url = ""; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.arrowMarkerAbsolute || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + addEdgeMarkers(svgPath, edge, url, id, diagramType); + let paths = {}; + if (pointsHasChanged) { + paths.updatedPath = points; + } + paths.originalPath = edge.points; + return paths; +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/14c1041d.5375728f.js b/assets/js/14c1041d.5375728f.js new file mode 100644 index 0000000000..af1d9eca62 --- /dev/null +++ b/assets/js/14c1041d.5375728f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5019],{38799:o=>{o.exports=JSON.parse('{"permalink":"/blog/tags/howto","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/14eb3368.09aca591.js b/assets/js/14eb3368.09aca591.js new file mode 100644 index 0000000000..7b54232be8 --- /dev/null +++ b/assets/js/14eb3368.09aca591.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6969],{71243:(e,t,n)=>{n.d(t,{A:()=>g});n(96540);var s=n(18215),r=n(17559),i=n(84142),a=n(99169),l=n(28774),o=n(21312),c=n(86025),d=n(74848);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,c.A)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(l.A,{"aria-label":(0,o.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}const b={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function x(e){let{children:t,href:n,isLast:s}=e;const r="breadcrumbs__link";return s?(0,d.jsx)("span",{className:r,itemProp:"name",children:t}):n?(0,d.jsx)(l.A,{className:r,href:n,itemProp:"item",children:(0,d.jsx)("span",{itemProp:"name",children:t})}):(0,d.jsx)("span",{className:r,children:t})}function p(e){let{children:t,active:n,index:r,addMicrodata:i}=e;return(0,d.jsxs)("li",{...i&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,s.A)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,d.jsx)("meta",{itemProp:"position",content:String(r+1)})]})}function g(){const e=(0,i.OF)(),t=(0,a.Dt)();return e?(0,d.jsx)("nav",{className:(0,s.A)(r.G.docs.docBreadcrumbs,b.breadcrumbsContainer),"aria-label":(0,o.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,d.jsx)(h,{}),e.map(((t,n)=>{const s=n===e.length-1,r="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,d.jsx)(p,{active:s,index:n,addMicrodata:!!r,children:(0,d.jsx)(x,{href:r,isLast:s,children:t.label})},n)}))]})}):null}},34136:(e,t,n)=>{n.r(t),n.d(t,{default:()=>w});n(96540);var s=n(61213),r=n(84142),i=n(86025),a=n(18215),l=n(28774),o=n(53465),c=n(16654),d=n(21312),u=n(51107);const m={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var h=n(74848);function b(e){let{href:t,children:n}=e;return(0,h.jsx)(l.A,{href:t,className:(0,a.A)("card padding--lg",m.cardContainer),children:n})}function x(e){let{href:t,icon:n,title:s,description:r}=e;return(0,h.jsxs)(b,{href:t,children:[(0,h.jsxs)(u.A,{as:"h2",className:(0,a.A)("text--truncate",m.cardTitle),title:s,children:[n," ",s]}),r&&(0,h.jsx)("p",{className:(0,a.A)("text--truncate",m.cardDescription),title:r,children:r})]})}function p(e){let{item:t}=e;const n=(0,r.Nr)(t),s=function(){const{selectMessage:e}=(0,o.W)();return t=>e(t,(0,d.T)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,h.jsx)(x,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??s(t.items.length)}):null}function g(e){let{item:t}=e;const n=(0,c.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",s=(0,r.cC)(t.docId??void 0);return(0,h.jsx)(x,{href:t.href,icon:n,title:t.label,description:t.description??s?.description})}function v(e){let{item:t}=e;switch(t.type){case"link":return(0,h.jsx)(g,{item:t});case"category":return(0,h.jsx)(p,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function f(e){let{className:t}=e;const n=(0,r.$S)();return(0,h.jsx)(j,{items:n.items,className:t})}function j(e){const{items:t,className:n}=e;if(!t)return(0,h.jsx)(f,{...e});const s=(0,r.d1)(t);return(0,h.jsx)("section",{className:(0,a.A)("row",n),children:s.map(((e,t)=>(0,h.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,h.jsx)(v,{item:e})},t)))})}var A=n(27719),N=n(51878),T=n(4267),L=n(71243);const _={generatedIndexPage:"generatedIndexPage_vN6x",list:"list_eTzJ",title:"title_kItE"};function k(e){let{categoryGeneratedIndex:t}=e;return(0,h.jsx)(s.be,{title:t.title,description:t.description,keywords:t.keywords,image:(0,i.A)(t.image)})}function y(e){let{categoryGeneratedIndex:t}=e;const n=(0,r.$S)();return(0,h.jsxs)("div",{className:_.generatedIndexPage,children:[(0,h.jsx)(N.A,{}),(0,h.jsx)(L.A,{}),(0,h.jsx)(T.A,{}),(0,h.jsxs)("header",{children:[(0,h.jsx)(u.A,{as:"h1",className:_.title,children:t.title}),t.description&&(0,h.jsx)("p",{children:t.description})]}),(0,h.jsx)("article",{className:"margin-top--lg",children:(0,h.jsx)(j,{items:n.items,className:_.list})}),(0,h.jsx)("footer",{className:"margin-top--lg",children:(0,h.jsx)(A.A,{previous:t.navigation.previous,next:t.navigation.next})})]})}function w(e){return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(k,{...e}),(0,h.jsx)(y,{...e})]})}},27719:(e,t,n)=>{n.d(t,{A:()=>a});n(96540);var s=n(21312),r=n(39022),i=n(74848);function a(e){const{previous:t,next:n}=e;return(0,i.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,s.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,i.jsx)(r.A,{...t,subLabel:(0,i.jsx)(s.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),n&&(0,i.jsx)(r.A,{...n,subLabel:(0,i.jsx)(s.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},4267:(e,t,n)=>{n.d(t,{A:()=>o});n(96540);var s=n(18215),r=n(21312),i=n(17559),a=n(32252),l=n(74848);function o(e){let{className:t}=e;const n=(0,a.r)();return n.badge?(0,l.jsx)("span",{className:(0,s.A)(t,i.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,l.jsx)(r.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}},51878:(e,t,n)=>{n.d(t,{A:()=>p});n(96540);var s=n(18215),r=n(44586),i=n(28774),a=n(21312),l=n(44070),o=n(17559),c=n(55597),d=n(32252),u=n(74848);const m={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(a.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(a.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const t=m[e.versionMetadata.banner];return(0,u.jsx)(t,{...e})}function b(e){let{versionLabel:t,to:n,onClick:s}=e;return(0,u.jsx)(a.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(i.A,{to:n,onClick:s,children:(0,u.jsx)(a.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function x(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:i}}=(0,r.A)(),{pluginId:a}=(0,l.vT)({failfast:!0}),{savePreferredVersionName:d}=(0,c.g1)(a),{latestDocSuggestion:m,latestVersionSuggestion:x}=(0,l.HW)(a),p=m??(g=x).docs.find((e=>e.id===g.mainDocId));var g;return(0,u.jsxs)("div",{className:(0,s.A)(t,o.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:i,versionMetadata:n})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(b,{versionLabel:x.label,to:p.path,onClick:()=>d(x.name)})})]})}function p(e){let{className:t}=e;const n=(0,d.r)();return n.banner?(0,u.jsx)(x,{className:t,versionMetadata:n}):null}},39022:(e,t,n)=>{n.d(t,{A:()=>a});n(96540);var s=n(18215),r=n(28774),i=n(74848);function a(e){const{permalink:t,title:n,subLabel:a,isNext:l}=e;return(0,i.jsxs)(r.A,{className:(0,s.A)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[a&&(0,i.jsx)("div",{className:"pagination-nav__sublabel",children:a}),(0,i.jsx)("div",{className:"pagination-nav__label",children:n})]})}},53465:(e,t,n)=>{n.d(t,{W:()=>c});var s=n(96540),r=n(44586);const i=["zero","one","two","few","many","other"];function a(e){return i.filter((t=>e.includes(t)))}const l={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,r.A)();return(0,s.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:a(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),l}}),[e])}function c(){const e=o();return{selectMessage:(t,n)=>function(e,t,n){const s=e.split("|");if(1===s.length)return s[0];s.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${s.length}: ${e}`);const r=n.select(t),i=n.pluralForms.indexOf(r);return s[Math.min(i,s.length-1)]}(n,t,e)}}}}]); \ No newline at end of file diff --git a/assets/js/15336817.730364fd.js b/assets/js/15336817.730364fd.js new file mode 100644 index 0000000000..519ba9f6cc --- /dev/null +++ b/assets/js/15336817.730364fd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5533],{31570:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>d});var r=t(74848),o=t(28453);const s={},c="Quickstart",i={id:"container/components/k8s-cluster-api-provider/doc/quickstart",title:"Quickstart",description:"This guide shows you how to get working Kubernetes clusters on a SCS cloud",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/quickstart.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc",slug:"/container/components/k8s-cluster-api-provider/doc/quickstart",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/quickstart",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/quickstart.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Requirements",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/requirements"},next:{title:"Makefile reference",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/make-reference"}},a={},d=[{value:"Requirements",id:"requirements",level:2},{value:"Prepare the environment",id:"prepare-the-environment",level:2},{value:"Create a test cluster",id:"create-a-test-cluster",level:2},{value:"Teardown",id:"teardown",level:2},{value:"Beyond quickstart",id:"beyond-quickstart",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"quickstart",children:"Quickstart"}),"\n",(0,r.jsxs)(n.p,{children:["This guide shows you how to get working Kubernetes clusters on a SCS cloud\nvia ",(0,r.jsx)(n.a,{href:"https://cluster-api.sigs.k8s.io/",children:"cluster-api"}),"(CAPI)."]}),"\n",(0,r.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"make"}),"\n",(0,r.jsx)(n.li,{children:"kubectl"}),"\n",(0,r.jsx)(n.li,{children:"opentofu"}),"\n",(0,r.jsx)(n.li,{children:"yq"}),"\n",(0,r.jsx)(n.li,{children:"python3-openstackclient, python3-octaviaclient"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"prepare-the-environment",children:"Prepare the environment"}),"\n",(0,r.jsx)(n.p,{children:"You need access to an OpenStack project.\nCopy the default environment and adjust the options according to your cloud."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"cp terraform/environments/environment-{default,}.tfvars\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Edit ",(0,r.jsx)(n.code,{children:"terraform/environments/environment-.tfvars"})," with your favourite text editor. Every option without a\ndefault value must be set.\nAdd\na ",(0,r.jsx)(n.a,{href:"https://docs.openstack.org/python-openstackclient/latest/configuration/index.html#configuration-files",children:"clouds.yaml"}),"\ninside the ",(0,r.jsx)(n.code,{children:"terraform"})," dir, in ",(0,r.jsx)(n.code,{children:"~/.config/openstack"})," or ",(0,r.jsx)(n.code,{children:"/etc/openstack"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["It is recommended to set the name of the cloud in the ",(0,r.jsx)(n.code,{children:"clouds.yml"})," to the same value as the ",(0,r.jsx)(n.code,{children:"cloud_provider"})," in\nthe ",(0,r.jsx)(n.code,{children:"environment-.tfvars"}),", then you only have to specify the ",(0,r.jsx)(n.code,{children:"ENVIRONMENT"})," or ",(0,r.jsx)(n.code,{children:"OS_CLOUD"})," variable."]}),"\n",(0,r.jsx)(n.h2,{id:"create-a-test-cluster",children:"Create a test cluster"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# Set the ENVIRONMENT to the name specified in the name of the file\n# `cloud_provider` option has to be set in the environment file\n# to the name of the cloud in the clouds.yaml\nexport ENVIRONMENT=\n\n# Create your environment. This includes a management node as virtual machine\n# in your OpenStack environment as well as a Kubernetes testcluster.\nmake create\n\n# Get the kubeconfig of the testcluster\nmake get-kubeconfig\n\n# Interact with the testcluster\nkubectl --kubeconfig testcluster.yaml. get nodes\n"})}),"\n",(0,r.jsx)(n.h2,{id:"teardown",children:"Teardown"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"make clean\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If ",(0,r.jsx)(n.code,{children:"make clean"})," fails to clean up completely, you can also use the ",(0,r.jsx)(n.code,{children:"fullclean"})," target.\nReview the ",(0,r.jsx)(n.a,{href:"/docs/container/components/k8s-cluster-api-provider/doc/make-reference#teardown",children:"Teardown section of the Makefile reference"})," document for more details."]}),"\n",(0,r.jsx)(n.h2,{id:"beyond-quickstart",children:"Beyond quickstart"}),"\n",(0,r.jsxs)(n.p,{children:["This guide assumes you just create one test cluster directly when creating the\nmanagement server.\nIn a production setting, you would not use this test cluster but create clusters\nvia the management server. You can read more about this in the ",(0,r.jsx)(n.a,{href:"/docs/container/components/k8s-cluster-api-provider/doc/usage/",children:"usage guide"}),"."]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var r=t(96540);const o={},s=r.createContext(o);function c(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1555.5c3ca885.js b/assets/js/1555.5c3ca885.js new file mode 100644 index 0000000000..cfa0886984 --- /dev/null +++ b/assets/js/1555.5c3ca885.js @@ -0,0 +1 @@ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1555],{97375:function(t){t.exports=function(){"use strict";return function(t,e){var n=e.prototype,i=n.format;n.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return i.bind(this)(t);var s=this.$utils(),r=(t||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,(function(t){switch(t){case"Q":return Math.ceil((e.$M+1)/3);case"Do":return n.ordinal(e.$D);case"gggg":return e.weekYear();case"GGGG":return e.isoWeekYear();case"wo":return n.ordinal(e.week(),"W");case"w":case"ww":return s.s(e.week(),"w"===t?1:2,"0");case"W":case"WW":return s.s(e.isoWeek(),"W"===t?1:2,"0");case"k":case"kk":return s.s(String(0===e.$H?24:e.$H),"k"===t?1:2,"0");case"X":return Math.floor(e.$d.getTime()/1e3);case"x":return e.$d.getTime();case"z":return"["+e.offsetName()+"]";case"zzz":return"["+e.offsetName("long")+"]";default:return t}}));return i.bind(this)(r)}}}()},90445:function(t){t.exports=function(){"use strict";var t={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},e=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,n=/\d\d/,i=/\d\d?/,s=/\d*[^-_:/,()\s\d]+/,r={},a=function(t){return(t=+t)+(t>68?1900:2e3)},o=function(t){return function(e){this[t]=+e}},c=[/[+-]\d\d:?(\d\d)?|Z/,function(t){(this.zone||(this.zone={})).offset=function(t){if(!t)return 0;if("Z"===t)return 0;var e=t.match(/([+-]|\d\d)/g),n=60*e[1]+(+e[2]||0);return 0===n?0:"+"===e[0]?-n:n}(t)}],l=function(t){var e=r[t];return e&&(e.indexOf?e:e.s.concat(e.f))},d=function(t,e){var n,i=r.meridiem;if(i){for(var s=1;s<=24;s+=1)if(t.indexOf(i(s,0,e))>-1){n=s>12;break}}else n=t===(e?"pm":"PM");return n},u={A:[s,function(t){this.afternoon=d(t,!1)}],a:[s,function(t){this.afternoon=d(t,!0)}],S:[/\d/,function(t){this.milliseconds=100*+t}],SS:[n,function(t){this.milliseconds=10*+t}],SSS:[/\d{3}/,function(t){this.milliseconds=+t}],s:[i,o("seconds")],ss:[i,o("seconds")],m:[i,o("minutes")],mm:[i,o("minutes")],H:[i,o("hours")],h:[i,o("hours")],HH:[i,o("hours")],hh:[i,o("hours")],D:[i,o("day")],DD:[n,o("day")],Do:[s,function(t){var e=r.ordinal,n=t.match(/\d+/);if(this.day=n[0],e)for(var i=1;i<=31;i+=1)e(i).replace(/\[|\]/g,"")===t&&(this.day=i)}],M:[i,o("month")],MM:[n,o("month")],MMM:[s,function(t){var e=l("months"),n=(l("monthsShort")||e.map((function(t){return t.slice(0,3)}))).indexOf(t)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[s,function(t){var e=l("months").indexOf(t)+1;if(e<1)throw new Error;this.month=e%12||e}],Y:[/[+-]?\d+/,o("year")],YY:[n,function(t){this.year=a(t)}],YYYY:[/\d{4}/,o("year")],Z:c,ZZ:c};function h(n){var i,s;i=n,s=r&&r.formats;for(var a=(n=i.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(e,n,i){var r=i&&i.toUpperCase();return n||s[i]||t[i]||s[r].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(t,e,n){return e||n.slice(1)}))}))).match(e),o=a.length,c=0;c-1)return new Date(("X"===e?1e3:1)*t);var i=h(e)(t),s=i.year,r=i.month,a=i.day,o=i.hours,c=i.minutes,l=i.seconds,d=i.milliseconds,u=i.zone,f=new Date,y=a||(s||r?1:f.getDate()),m=s||f.getFullYear(),k=0;s&&!r||(k=r>0?r-1:f.getMonth());var p=o||0,g=c||0,b=l||0,v=d||0;return u?new Date(Date.UTC(m,k,y,p,g,b,v+60*u.offset*1e3)):n?new Date(Date.UTC(m,k,y,p,g,b,v)):new Date(m,k,y,p,g,b,v)}catch(t){return new Date("")}}(e,o,i),this.init(),u&&!0!==u&&(this.$L=this.locale(u).$L),d&&e!=this.format(o)&&(this.$d=new Date("")),r={}}else if(o instanceof Array)for(var f=o.length,y=1;y<=f;y+=1){a[1]=o[y-1];var m=n.apply(this,a);if(m.isValid()){this.$d=m.$d,this.$L=m.$L,this.init();break}y===f&&(this.$d=new Date(""))}else s.call(this,t)}}}()},68313:function(t){t.exports=function(){"use strict";var t="day";return function(e,n,i){var s=function(e){return e.add(4-e.isoWeekday(),t)},r=n.prototype;r.isoWeekYear=function(){return s(this).year()},r.isoWeek=function(e){if(!this.$utils().u(e))return this.add(7*(e-this.isoWeek()),t);var n,r,a,o=s(this),c=(n=this.isoWeekYear(),a=4-(r=(this.$u?i.utc:i)().year(n).startOf("year")).isoWeekday(),r.isoWeekday()>4&&(a+=7),r.add(a,t));return o.diff(c,"week")+1},r.isoWeekday=function(t){return this.$utils().u(t)?this.day()||7:this.day(this.day()%7?t:t-7)};var a=r.startOf;r.startOf=function(t,e){var n=this.$utils(),i=!!n.u(e)||e;return"isoweek"===n.p(t)?i?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):a.bind(this)(t,e)}}}()},71555:(t,e,n)=>{"use strict";n.d(e,{diagram:()=>q});var i=n(16750),s=n(74353),r=n(68313),a=n(90445),o=n(97375),c=n(76257),l=n(26312),d=(n(42838),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[6,8,10,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,30,32,33,35,37],n=[1,25],i=[1,26],s=[1,27],r=[1,28],a=[1,29],o=[1,30],c=[1,31],l=[1,9],d=[1,10],u=[1,11],h=[1,12],f=[1,13],y=[1,14],m=[1,15],k=[1,16],p=[1,18],g=[1,19],b=[1,20],v=[1,21],T=[1,22],x=[1,24],w=[1,32],_={trace:function(){},yy:{},symbols_:{error:2,start:3,gantt:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NL:10,weekday:11,weekday_monday:12,weekday_tuesday:13,weekday_wednesday:14,weekday_thursday:15,weekday_friday:16,weekday_saturday:17,weekday_sunday:18,dateFormat:19,inclusiveEndDates:20,topAxis:21,axisFormat:22,tickInterval:23,excludes:24,includes:25,todayMarker:26,title:27,acc_title:28,acc_title_value:29,acc_descr:30,acc_descr_value:31,acc_descr_multiline_value:32,section:33,clickStatement:34,taskTxt:35,taskData:36,click:37,callbackname:38,callbackargs:39,href:40,clickStatementDebug:41,$accept:0,$end:1},terminals_:{2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",12:"weekday_monday",13:"weekday_tuesday",14:"weekday_wednesday",15:"weekday_thursday",16:"weekday_friday",17:"weekday_saturday",18:"weekday_sunday",19:"dateFormat",20:"inclusiveEndDates",21:"topAxis",22:"axisFormat",23:"tickInterval",24:"excludes",25:"includes",26:"todayMarker",27:"title",28:"acc_title",29:"acc_title_value",30:"acc_descr",31:"acc_descr_value",32:"acc_descr_multiline_value",33:"section",35:"taskTxt",36:"taskData",37:"click",38:"callbackname",39:"callbackargs",40:"href"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[34,2],[34,3],[34,3],[34,4],[34,3],[34,4],[34,2],[41,2],[41,3],[41,3],[41,4],[41,3],[41,4],[41,2]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.setWeekday("monday");break;case 9:i.setWeekday("tuesday");break;case 10:i.setWeekday("wednesday");break;case 11:i.setWeekday("thursday");break;case 12:i.setWeekday("friday");break;case 13:i.setWeekday("saturday");break;case 14:i.setWeekday("sunday");break;case 15:i.setDateFormat(r[o].substr(11)),this.$=r[o].substr(11);break;case 16:i.enableInclusiveEndDates(),this.$=r[o].substr(18);break;case 17:i.TopAxis(),this.$=r[o].substr(8);break;case 18:i.setAxisFormat(r[o].substr(11)),this.$=r[o].substr(11);break;case 19:i.setTickInterval(r[o].substr(13)),this.$=r[o].substr(13);break;case 20:i.setExcludes(r[o].substr(9)),this.$=r[o].substr(9);break;case 21:i.setIncludes(r[o].substr(9)),this.$=r[o].substr(9);break;case 22:i.setTodayMarker(r[o].substr(12)),this.$=r[o].substr(12);break;case 24:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 25:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 26:case 27:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 28:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 30:i.addTask(r[o-1],r[o]),this.$="task";break;case 31:this.$=r[o-1],i.setClickEvent(r[o-1],r[o],null);break;case 32:this.$=r[o-2],i.setClickEvent(r[o-2],r[o-1],r[o]);break;case 33:this.$=r[o-2],i.setClickEvent(r[o-2],r[o-1],null),i.setLink(r[o-2],r[o]);break;case 34:this.$=r[o-3],i.setClickEvent(r[o-3],r[o-2],r[o-1]),i.setLink(r[o-3],r[o]);break;case 35:this.$=r[o-2],i.setClickEvent(r[o-2],r[o],null),i.setLink(r[o-2],r[o-1]);break;case 36:this.$=r[o-3],i.setClickEvent(r[o-3],r[o-1],r[o]),i.setLink(r[o-3],r[o-2]);break;case 37:this.$=r[o-1],i.setLink(r[o-1],r[o]);break;case 38:case 44:this.$=r[o-1]+" "+r[o];break;case 39:case 40:case 42:this.$=r[o-2]+" "+r[o-1]+" "+r[o];break;case 41:case 43:this.$=r[o-3]+" "+r[o-2]+" "+r[o-1]+" "+r[o]}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:n,13:i,14:s,15:r,16:a,17:o,18:c,19:l,20:d,21:u,22:h,23:f,24:y,25:m,26:k,27:p,28:g,30:b,32:v,33:T,34:23,35:x,37:w},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:33,11:17,12:n,13:i,14:s,15:r,16:a,17:o,18:c,19:l,20:d,21:u,22:h,23:f,24:y,25:m,26:k,27:p,28:g,30:b,32:v,33:T,34:23,35:x,37:w},t(e,[2,5]),t(e,[2,6]),t(e,[2,15]),t(e,[2,16]),t(e,[2,17]),t(e,[2,18]),t(e,[2,19]),t(e,[2,20]),t(e,[2,21]),t(e,[2,22]),t(e,[2,23]),t(e,[2,24]),{29:[1,34]},{31:[1,35]},t(e,[2,27]),t(e,[2,28]),t(e,[2,29]),{36:[1,36]},t(e,[2,8]),t(e,[2,9]),t(e,[2,10]),t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),{38:[1,37],40:[1,38]},t(e,[2,4]),t(e,[2,25]),t(e,[2,26]),t(e,[2,30]),t(e,[2,31],{39:[1,39],40:[1,40]}),t(e,[2,37],{38:[1,41]}),t(e,[2,32],{40:[1,42]}),t(e,[2,33]),t(e,[2,35],{39:[1,43]}),t(e,[2,34]),t(e,[2,36])],defaultActions:{},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,o="",c=0,l=0,d=r.slice.call(arguments,1),u=Object.create(this.lexer),h={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(h.yy[f]=this.yy[f]);u.setInput(t,h.yy),h.yy.lexer=u,h.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var y=u.yylloc;r.push(y);var m=u.options&&u.options.ranges;"function"==typeof h.yy.parseError?this.parseError=h.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var k,p,g,b,v,T,x,w,_,$={};;){if(p=n[n.length-1],this.defaultActions[p]?g=this.defaultActions[p]:(null==k&&(_=void 0,"number"!=typeof(_=i.pop()||u.lex()||1)&&(_ instanceof Array&&(_=(i=_).pop()),_=e.symbols_[_]||_),k=_),g=a[p]&&a[p][k]),void 0===g||!g.length||!g[0]){var D="";for(v in w=[],a[p])this.terminals_[v]&&v>2&&w.push("'"+this.terminals_[v]+"'");D=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[k]||k)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==k?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(D,{text:u.match,token:this.terminals_[k]||k,line:u.yylineno,loc:y,expected:w})}if(g[0]instanceof Array&&g.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+k);switch(g[0]){case 1:n.push(k),s.push(u.yytext),r.push(u.yylloc),n.push(g[1]),k=null,l=u.yyleng,o=u.yytext,c=u.yylineno,y=u.yylloc;break;case 2:if(T=this.productions_[g[1]][1],$.$=s[s.length-T],$._$={first_line:r[r.length-(T||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(T||1)].first_column,last_column:r[r.length-1].last_column},m&&($._$.range=[r[r.length-(T||1)].range[0],r[r.length-1].range[1]]),void 0!==(b=this.performAction.apply($,[o,l,c,h.yy,g[1],s,r].concat(d))))return b;T&&(n=n.slice(0,-1*T*2),s=s.slice(0,-1*T),r=r.slice(0,-1*T)),n.push(this.productions_[g[1]][0]),s.push($.$),r.push($._$),x=a[n[n.length-2]][n[n.length-1]],n.push(x);break;case 3:return!0}}return!0}},$={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;re[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),"open_directive";case 1:return this.begin("acc_title"),28;case 2:return this.popState(),"acc_title_value";case 3:return this.begin("acc_descr"),30;case 4:return this.popState(),"acc_descr_value";case 5:this.begin("acc_descr_multiline");break;case 6:case 15:case 18:case 21:case 24:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:case 9:case 10:case 12:case 13:break;case 11:return 10;case 14:this.begin("href");break;case 16:return 40;case 17:this.begin("callbackname");break;case 19:this.popState(),this.begin("callbackargs");break;case 20:return 38;case 22:return 39;case 23:this.begin("click");break;case 25:return 37;case 26:return 4;case 27:return 19;case 28:return 20;case 29:return 21;case 30:return 22;case 31:return 23;case 32:return 25;case 33:return 24;case 34:return 26;case 35:return 12;case 36:return 13;case 37:return 14;case 38:return 15;case 39:return 16;case 40:return 17;case 41:return 18;case 42:return"date";case 43:return 27;case 44:return"accDescription";case 45:return 33;case 46:return 35;case 47:return 36;case 48:return":";case 49:return 6;case 50:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:tickInterval\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:weekday\s+monday\b)/i,/^(?:weekday\s+tuesday\b)/i,/^(?:weekday\s+wednesday\b)/i,/^(?:weekday\s+thursday\b)/i,/^(?:weekday\s+friday\b)/i,/^(?:weekday\s+saturday\b)/i,/^(?:weekday\s+sunday\b)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^\n]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^\n]+)/i,/^(?:[^:\n]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},callbackargs:{rules:[21,22],inclusive:!1},callbackname:{rules:[18,19,20],inclusive:!1},href:{rules:[15,16],inclusive:!1},click:{rules:[24,25],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,17,23,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50],inclusive:!0}}};function D(){this.yy={}}return _.lexer=$,D.prototype=_,_.Parser=D,new D}());d.parser=d;const u=d;s.extend(r),s.extend(a),s.extend(o);let h,f="",y="",m="",k=[],p=[],g={},b=[],v=[],T="",x="";const w=["active","done","crit","milestone"];let _=[],$=!1,D=!1,C="sunday",S=0;const E=function(t,e,n,i){return!i.includes(t.format(e.trim()))&&(!!(t.isoWeekday()>=6&&n.includes("weekends"))||(!!n.includes(t.format("dddd").toLowerCase())||n.includes(t.format(e.trim()))))},A=function(t,e,n,i){if(!n.length||t.manualEndTime)return;let r,a;r=t.startTime instanceof Date?s(t.startTime):s(t.startTime,e,!0),r=r.add(1,"d"),a=t.endTime instanceof Date?s(t.endTime):s(t.endTime,e,!0);const[o,c]=M(r,a,e,n,i);t.endTime=o.toDate(),t.renderEndTime=c},M=function(t,e,n,i,s){let r=!1,a=null;for(;t<=e;)r||(a=e.toDate()),r=E(t,n,i,s),r&&(e=e.add(1,"d")),t=t.add(1,"d");return[e,a]},Y=function(t,e,n){n=n.trim();const i=/^after\s+(?[\d\w- ]+)/.exec(n);if(null!==i){let t=null;for(const n of i.groups.ids.split(" ")){let e=N(n);void 0!==e&&(!t||e.endTime>t.endTime)&&(t=e)}if(t)return t.endTime;const e=new Date;return e.setHours(0,0,0,0),e}let r=s(n,e.trim(),!0);if(r.isValid())return r.toDate();{c.l.debug("Invalid date:"+n),c.l.debug("With date format:"+e.trim());const t=new Date(n);if(void 0===t||isNaN(t.getTime())||t.getFullYear()<-1e4||t.getFullYear()>1e4)throw new Error("Invalid date:"+n);return t}},L=function(t){const e=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(t.trim());return null!==e?[Number.parseFloat(e[1]),e[2]]:[NaN,"ms"]},I=function(t,e,n,i=!1){n=n.trim();const r=/^until\s+(?[\d\w- ]+)/.exec(n);if(null!==r){let t=null;for(const n of r.groups.ids.split(" ")){let e=N(n);void 0!==e&&(!t||e.startTime(0,c.c)().gantt,clear:function(){b=[],v=[],T="",_=[],O=0,F=void 0,P=void 0,B=[],f="",y="",x="",h=void 0,m="",k=[],p=[],$=!1,D=!1,S=0,g={},(0,c.v)(),C="sunday"},setDateFormat:function(t){f=t},getDateFormat:function(){return f},enableInclusiveEndDates:function(){$=!0},endDatesAreInclusive:function(){return $},enableTopAxis:function(){D=!0},topAxisEnabled:function(){return D},setAxisFormat:function(t){y=t},getAxisFormat:function(){return y},setTickInterval:function(t){h=t},getTickInterval:function(){return h},setTodayMarker:function(t){m=t},getTodayMarker:function(){return m},setAccTitle:c.s,getAccTitle:c.g,setDiagramTitle:c.q,getDiagramTitle:c.t,setDisplayMode:function(t){x=t},getDisplayMode:function(){return x},setAccDescription:c.b,getAccDescription:c.a,addSection:function(t){T=t,b.push(t)},getSections:function(){return b},getTasks:function(){let t=G();let e=0;for(;!t&&e<10;)t=G(),e++;return v=B,v},addTask:function(t,e){const n={section:T,type:T,processed:!1,manualEndTime:!1,renderEndTime:null,raw:{data:e},task:t,classes:[]},i=function(t,e){let n;n=":"===e.substr(0,1)?e.substr(1,e.length):e;const i=n.split(","),s={};R(i,s,w);for(let r=0;r{c.u.runFunc(e,...i)}))}(t,e,n)})),H(t,"clickable")},setLink:function(t,e){let n=e;"loose"!==(0,c.c)().securityLevel&&(n=(0,i.Jf)(e)),t.split(",").forEach((function(t){void 0!==N(t)&&(j(t,(()=>{window.open(n,"_self")})),g[t]=n)})),H(t,"clickable")},getLinks:function(){return g},bindFunctions:function(t){_.forEach((function(e){e(t)}))},parseDuration:L,isInvalidDate:E,setWeekday:function(t){C=t},getWeekday:function(){return C}};function R(t,e,n){let i=!0;for(;i;)i=!1,n.forEach((function(n){const s=new RegExp("^\\s*"+n+"\\s*$");t[0].match(s)&&(e[n]=!0,t.shift(1),i=!0)}))}const V={monday:l.ABi,tuesday:l.PGu,wednesday:l.GuW,thursday:l.Mol,friday:l.TUC,saturday:l.rGn,sunday:l.YPH},Z=(t,e)=>{let n=[...t].map((()=>-1/0)),i=[...t].sort(((t,e)=>t.startTime-e.startTime||t.order-e.order)),s=0;for(const r of i)for(let t=0;t=n[t]){n[t]=r.endTime,r.order=t+e,t>s&&(s=t);break}return s};let X;const q={parser:u,db:U,renderer:{setConf:function(){c.l.debug("Something is calling, setConf, remove the call")},draw:function(t,e,n,i){const r=(0,c.c)().gantt,a=(0,c.c)().securityLevel;let o;"sandbox"===a&&(o=(0,l.Ltv)("#i"+e));const d="sandbox"===a?(0,l.Ltv)(o.nodes()[0].contentDocument.body):(0,l.Ltv)("body"),u="sandbox"===a?o.nodes()[0].contentDocument:document,h=u.getElementById(e);X=h.parentElement.offsetWidth,void 0===X&&(X=1200),void 0!==r.useWidth&&(X=r.useWidth);const f=i.db.getTasks();let y=[];for(const s of f)y.push(s.type);y=function(t){const e={},n=[];for(let i=0,s=t.length;ie.type===t)).length}h.setAttribute("viewBox","0 0 "+X+" "+k);const p=d.select(`[id="${e}"]`),g=(0,l.w7C)().domain([(0,l.jkA)(f,(function(t){return t.startTime})),(0,l.T9B)(f,(function(t){return t.endTime}))]).rangeRound([0,X-r.leftPadding-r.rightPadding]);f.sort((function(t,e){const n=t.startTime,i=e.startTime;let s=0;return n>i?s=1:nf)&&(f=s);if(!h||!f)return;if(s(f).diff(s(h),"year")>5)return void c.l.warn("The difference between the min and max time is more than 5 years. This will cause performance issues. Skipping drawing exclude days.");const y=i.db.getDateFormat(),m=[];let k=null,b=s(h);for(;b.valueOf()<=f;)i.db.isInvalidDate(b,y,d,u)?k?k.end=b:k={start:b,end:b}:k&&(m.push(k),k=null),b=b.add(1,"d");p.append("g").selectAll("rect").data(m).enter().append("rect").attr("id",(function(t){return"exclude-"+t.start.format("YYYY-MM-DD")})).attr("x",(function(t){return g(t.start)+n})).attr("y",r.gridLineStartPadding).attr("width",(function(t){const e=t.end.add(1,"day");return g(e)-g(t.start)})).attr("height",o-e-r.gridLineStartPadding).attr("transform-origin",(function(e,i){return(g(e.start)+n+.5*(g(e.end)-g(e.start))).toString()+"px "+(i*t+.5*o).toString()+"px"})).attr("class","exclude-range")})(d,h,f,0,a,t,i.db.getExcludes(),i.db.getIncludes()),function(t,e,n,s){let a=(0,l.l78)(g).tickSize(-s+e+r.gridLineStartPadding).tickFormat((0,l.DCK)(i.db.getAxisFormat()||r.axisFormat||"%Y-%m-%d"));const o=/^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/.exec(i.db.getTickInterval()||r.tickInterval);if(null!==o){const t=o[1],e=o[2],n=i.db.getWeekday()||r.weekday;switch(e){case"millisecond":a.ticks(l.t6C.every(t));break;case"second":a.ticks(l.ucG.every(t));break;case"minute":a.ticks(l.wXd.every(t));break;case"hour":a.ticks(l.Agd.every(t));break;case"day":a.ticks(l.UAC.every(t));break;case"week":a.ticks(V[n].every(t));break;case"month":a.ticks(l.Ui6.every(t))}}if(p.append("g").attr("class","grid").attr("transform","translate("+t+", "+(s-50)+")").call(a).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),i.db.topAxisEnabled()||r.topAxis){let n=(0,l.tlR)(g).tickSize(-s+e+r.gridLineStartPadding).tickFormat((0,l.DCK)(i.db.getAxisFormat()||r.axisFormat||"%Y-%m-%d"));if(null!==o){const t=o[1],e=o[2],s=i.db.getWeekday()||r.weekday;switch(e){case"millisecond":n.ticks(l.t6C.every(t));break;case"second":n.ticks(l.ucG.every(t));break;case"minute":n.ticks(l.wXd.every(t));break;case"hour":n.ticks(l.Agd.every(t));break;case"day":n.ticks(l.UAC.every(t));break;case"week":n.ticks(V[s].every(t));break;case"month":n.ticks(l.Ui6.every(t))}}p.append("g").attr("class","grid").attr("transform","translate("+t+", "+e+")").call(n).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}(f,h,0,a),function(t,n,s,a,o,d,u){const h=[...new Set(t.map((t=>t.order)))].map((e=>t.find((t=>t.order===e))));p.append("g").selectAll("rect").data(h).enter().append("rect").attr("x",0).attr("y",(function(t,e){return t.order*n+s-2})).attr("width",(function(){return u-r.rightPadding/2})).attr("height",n).attr("class",(function(t){for(const[e,n]of y.entries())if(t.type===n)return"section section"+e%r.numberSectionStyles;return"section section0"}));const f=p.append("g").selectAll("rect").data(t).enter(),m=i.db.getLinks();f.append("rect").attr("id",(function(t){return t.id})).attr("rx",3).attr("ry",3).attr("x",(function(t){return t.milestone?g(t.startTime)+a+.5*(g(t.endTime)-g(t.startTime))-.5*o:g(t.startTime)+a})).attr("y",(function(t,e){return t.order*n+s})).attr("width",(function(t){return t.milestone?o:g(t.renderEndTime||t.endTime)-g(t.startTime)})).attr("height",o).attr("transform-origin",(function(t,e){return e=t.order,(g(t.startTime)+a+.5*(g(t.endTime)-g(t.startTime))).toString()+"px "+(e*n+s+.5*o).toString()+"px"})).attr("class",(function(t){const e="task";let n="";t.classes.length>0&&(n=t.classes.join(" "));let i=0;for(const[a,o]of y.entries())t.type===o&&(i=a%r.numberSectionStyles);let s="";return t.active?t.crit?s+=" activeCrit":s=" active":t.done?s=t.crit?" doneCrit":" done":t.crit&&(s+=" crit"),0===s.length&&(s=" task"),t.milestone&&(s=" milestone "+s),s+=i,s+=" "+n,e+s})),f.append("text").attr("id",(function(t){return t.id+"-text"})).text((function(t){return t.task})).attr("font-size",r.fontSize).attr("x",(function(t){let e=g(t.startTime),n=g(t.renderEndTime||t.endTime);t.milestone&&(e+=.5*(g(t.endTime)-g(t.startTime))-.5*o),t.milestone&&(n=e+o);const i=this.getBBox().width;return i>n-e?n+i+1.5*r.leftPadding>u?e+a-5:n+a+5:(n-e)/2+e+a})).attr("y",(function(t,e){return t.order*n+r.barHeight/2+(r.fontSize/2-2)+s})).attr("text-height",o).attr("class",(function(t){const e=g(t.startTime);let n=g(t.endTime);t.milestone&&(n=e+o);const i=this.getBBox().width;let s="";t.classes.length>0&&(s=t.classes.join(" "));let a=0;for(const[o,l]of y.entries())t.type===l&&(a=o%r.numberSectionStyles);let c="";return t.active&&(c=t.crit?"activeCritText"+a:"activeText"+a),t.done?c=t.crit?c+" doneCritText"+a:c+" doneText"+a:t.crit&&(c=c+" critText"+a),t.milestone&&(c+=" milestoneText"),i>n-e?n+i+1.5*r.leftPadding>u?s+" taskTextOutsideLeft taskTextOutside"+a+" "+c:s+" taskTextOutsideRight taskTextOutside"+a+" "+c+" width-"+i:s+" taskText taskText"+a+" "+c+" width-"+i}));if("sandbox"===(0,c.c)().securityLevel){let t;t=(0,l.Ltv)("#i"+e);const n=t.nodes()[0].contentDocument;f.filter((function(t){return void 0!==m[t.id]})).each((function(t){var e=n.querySelector("#"+t.id),i=n.querySelector("#"+t.id+"-text");const s=e.parentNode;var r=n.createElement("a");r.setAttribute("xlink:href",m[t.id]),r.setAttribute("target","_top"),s.appendChild(r),r.appendChild(e),r.appendChild(i)}))}}(t,d,h,f,o,0,n),function(t,e){let n=0;const i=Object.keys(m).map((t=>[t,m[t]]));p.append("g").selectAll("text").data(i).enter().append((function(t){const e=t[0].split(c.e.lineBreakRegex),n=-(e.length-1)/2,i=u.createElementNS("http://www.w3.org/2000/svg","text");i.setAttribute("dy",n+"em");for(const[s,r]of e.entries()){const t=u.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttribute("alignment-baseline","central"),t.setAttribute("x","10"),s>0&&t.setAttribute("dy","1em"),t.textContent=r,i.appendChild(t)}return i})).attr("x",10).attr("y",(function(s,r){if(!(r>0))return s[1]*t/2+e;for(let a=0;a`\n .mermaid-main-font {\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n\n .exclude-range {\n fill: ${t.excludeBkgColor};\n }\n\n .section {\n stroke: none;\n opacity: 0.2;\n }\n\n .section0 {\n fill: ${t.sectionBkgColor};\n }\n\n .section2 {\n fill: ${t.sectionBkgColor2};\n }\n\n .section1,\n .section3 {\n fill: ${t.altSectionBkgColor};\n opacity: 0.2;\n }\n\n .sectionTitle0 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle1 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle2 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle3 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle {\n text-anchor: start;\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n\n\n /* Grid and axis */\n\n .grid .tick {\n stroke: ${t.gridColor};\n opacity: 0.8;\n shape-rendering: crispEdges;\n }\n\n .grid .tick text {\n font-family: ${t.fontFamily};\n fill: ${t.textColor};\n }\n\n .grid path {\n stroke-width: 0;\n }\n\n\n /* Today line */\n\n .today {\n fill: none;\n stroke: ${t.todayLineColor};\n stroke-width: 2px;\n }\n\n\n /* Task styling */\n\n /* Default task */\n\n .task {\n stroke-width: 2;\n }\n\n .taskText {\n text-anchor: middle;\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n\n .taskTextOutsideRight {\n fill: ${t.taskTextDarkColor};\n text-anchor: start;\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n\n .taskTextOutsideLeft {\n fill: ${t.taskTextDarkColor};\n text-anchor: end;\n }\n\n\n /* Special case clickable */\n\n .task.clickable {\n cursor: pointer;\n }\n\n .taskText.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideLeft.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideRight.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n\n /* Specific task settings for the sections*/\n\n .taskText0,\n .taskText1,\n .taskText2,\n .taskText3 {\n fill: ${t.taskTextColor};\n }\n\n .task0,\n .task1,\n .task2,\n .task3 {\n fill: ${t.taskBkgColor};\n stroke: ${t.taskBorderColor};\n }\n\n .taskTextOutside0,\n .taskTextOutside2\n {\n fill: ${t.taskTextOutsideColor};\n }\n\n .taskTextOutside1,\n .taskTextOutside3 {\n fill: ${t.taskTextOutsideColor};\n }\n\n\n /* Active task */\n\n .active0,\n .active1,\n .active2,\n .active3 {\n fill: ${t.activeTaskBkgColor};\n stroke: ${t.activeTaskBorderColor};\n }\n\n .activeText0,\n .activeText1,\n .activeText2,\n .activeText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Completed task */\n\n .done0,\n .done1,\n .done2,\n .done3 {\n stroke: ${t.doneTaskBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneText0,\n .doneText1,\n .doneText2,\n .doneText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Tasks on the critical line */\n\n .crit0,\n .crit1,\n .crit2,\n .crit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.critBkgColor};\n stroke-width: 2;\n }\n\n .activeCrit0,\n .activeCrit1,\n .activeCrit2,\n .activeCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.activeTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneCrit0,\n .doneCrit1,\n .doneCrit2,\n .doneCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n cursor: pointer;\n shape-rendering: crispEdges;\n }\n\n .milestone {\n transform: rotate(45deg) scale(0.8,0.8);\n }\n\n .milestoneText {\n font-style: italic;\n }\n .doneCritText0,\n .doneCritText1,\n .doneCritText2,\n .doneCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .activeCritText0,\n .activeCritText1,\n .activeCritText2,\n .activeCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .titleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.titleColor||t.textColor};\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/15e4a743.23ea2fbb.js b/assets/js/15e4a743.23ea2fbb.js new file mode 100644 index 0000000000..e9b2fee8c5 --- /dev/null +++ b/assets/js/15e4a743.23ea2fbb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5609],{23427:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>a,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var o=t(74848),r=t(28453);const i={},s="Overview",c={id:"operating-scs/monitoring/index",title:"Overview",description:"TODO",source:"@site/docs/04-operating-scs/02-monitoring/index.md",sourceDirName:"04-operating-scs/02-monitoring",slug:"/operating-scs/monitoring/",permalink:"/docs/operating-scs/monitoring/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/02-monitoring/index.md",tags:[],version:"current",frontMatter:{}},a={},d=[];function u(n){const e={h1:"h1",p:"p",...(0,r.R)(),...n.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(e.h1,{id:"overview",children:"Overview"}),"\n",(0,o.jsx)(e.p,{children:"TODO"})]})}function p(n={}){const{wrapper:e}={...(0,r.R)(),...n.components};return e?(0,o.jsx)(e,{...n,children:(0,o.jsx)(u,{...n})}):u(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>s,x:()=>c});var o=t(96540);const r={},i=o.createContext(r);function s(n){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(r):n.components||r:s(n.components),o.createElement(i.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/16c50622.a60a3434.js b/assets/js/16c50622.a60a3434.js new file mode 100644 index 0000000000..2572c068b3 --- /dev/null +++ b/assets/js/16c50622.a60a3434.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4712],{36661:(i,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>s,metadata:()=>d,toc:()=>r});var t=n(74848),o=n(28453);const s={sidebar_label:"Validations",sidebar_position:50},a="Validations",d={id:"iaas/guides/configuration-guide/validations/index",title:"Validations",description:"This section contains the documentation of the Ansible collection",source:"@site/docs/02-iaas/guides/configuration-guide/validations/index.md",sourceDirName:"02-iaas/guides/configuration-guide/validations",slug:"/iaas/guides/configuration-guide/validations/",permalink:"/docs/iaas/guides/configuration-guide/validations/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/validations/index.md",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"Validations",sidebar_position:50},sidebar:"docs",previous:{title:"Tuned",permalink:"/docs/iaas/guides/configuration-guide/services/tuned"},next:{title:"Operations Guide",permalink:"/docs/iaas/guides/operations-guide/"}},c={},r=[];function u(i){const e={a:"a",h1:"h1",p:"p",...(0,o.R)(),...i.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h1,{id:"validations",children:"Validations"}),"\n",(0,t.jsxs)(e.p,{children:["This section contains the documentation of the Ansible collection\n",(0,t.jsx)(e.a,{href:"https://github.com/osism/ansible-collection-validations",children:"osism.validations"}),"."]})]})}function l(i={}){const{wrapper:e}={...(0,o.R)(),...i.components};return e?(0,t.jsx)(e,{...i,children:(0,t.jsx)(u,{...i})}):u(i)}},28453:(i,e,n)=>{n.d(e,{R:()=>a,x:()=>d});var t=n(96540);const o={},s=t.createContext(o);function a(i){const e=t.useContext(s);return t.useMemo((function(){return"function"==typeof i?i(e):{...e,...i}}),[e,i])}function d(i){let e;return e=i.disableParentContext?"function"==typeof i.components?i.components(o):i.components||o:a(i.components),t.createElement(s.Provider,{value:e},i.children)}}}]); \ No newline at end of file diff --git a/assets/js/1722e234.73593b86.js b/assets/js/1722e234.73593b86.js new file mode 100644 index 0000000000..bfe53cfb3d --- /dev/null +++ b/assets/js/1722e234.73593b86.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1255],{94409:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>o,frontMatter:()=>r,metadata:()=>l,toc:()=>h});var d=n(74848),s=n(28453);const r={},c="Test and development cloud resources",l={id:"cloud-resources/cloud-resources",title:"Test and development cloud resources",description:"This document gives an overview of the test and development cloud resources currently provided by our partners.",source:"@site/community/cloud-resources/cloud-resources.md",sourceDirName:"cloud-resources",slug:"/cloud-resources/",permalink:"/community/cloud-resources/",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Tips and Tricks",permalink:"/community/tools/github/tips-and-tricks"},next:{title:"Getting Started with OpenStack",permalink:"/community/cloud-resources/getting-started-openstack"}},i={},h=[{value:"How to request cloud resources",id:"how-to-request-cloud-resources",level:2},{value:"plusserver",id:"plusserver",level:2},{value:"Usage",id:"usage",level:3},{value:"Users",id:"users",level:3},{value:"Service Users",id:"service-users",level:3},{value:"Projects",id:"projects",level:3},{value:"Wavecon",id:"wavecon",level:2},{value:"Service Users",id:"service-users-1",level:3},{value:"Projects",id:"projects-1",level:3}];function x(e){const t={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(t.h1,{id:"test-and-development-cloud-resources",children:"Test and development cloud resources"}),"\n",(0,d.jsx)(t.p,{children:"This document gives an overview of the test and development cloud resources currently provided by our partners."}),"\n",(0,d.jsx)(t.h2,{id:"how-to-request-cloud-resources",children:"How to request cloud resources"}),"\n",(0,d.jsxs)(t.p,{children:["To request access to an existing project, please contact the responsible community member. To apply for a new project, please create a pull request against this document (leave ",(0,d.jsx)(t.code,{children:"Unique Identifier"})," blank) and assign it to the particular CSP team (e.g. @SovereignCloudStack/plusserver, @SovereignCloudStack/wavecon, ...)"]}),"\n",(0,d.jsx)(t.h2,{id:"plusserver",children:"plusserver"}),"\n",(0,d.jsx)(t.h3,{id:"usage",children:"Usage"}),"\n",(0,d.jsxs)(t.p,{children:["A brief guide on how to use the resources provided by plusserver GmbH can be found ",(0,d.jsx)(t.a,{href:"/community/cloud-resources/plusserver-gx-scs",children:"here"})]}),"\n",(0,d.jsx)(t.h3,{id:"users",children:"Users"}),"\n",(0,d.jsxs)(t.p,{children:["As suggested in ",(0,d.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/issues/155",children:"#155"}),' the username for non-"service users" will contain the users github handle and are prefixed with a plusserver default.\n',(0,d.jsx)(t.code,{children:"prefix-<$github handle>"})]}),"\n",(0,d.jsxs)(t.blockquote,{children:["\n",(0,d.jsxs)(t.p,{children:[(0,d.jsx)(t.strong,{children:"Note"}),"\nATM this is not directly connected to the SovereignCloudStack github org membership, accounts will be created manually for now."]}),"\n"]}),"\n",(0,d.jsx)(t.p,{children:"Example:"}),"\n",(0,d.jsxs)(t.table,{children:[(0,d.jsx)(t.thead,{children:(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.th,{style:{textAlign:"center"},children:"github handle"}),(0,d.jsx)(t.th,{style:{textAlign:"center"},children:"plusserver login"})]})}),(0,d.jsxs)(t.tbody,{children:[(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"frosty-geek"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"u500924-frosty-geek"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"fkr"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"u500924-fkr"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"}}),(0,d.jsx)(t.td,{style:{textAlign:"center"}})]})]})]}),"\n",(0,d.jsxs)(t.blockquote,{children:["\n",(0,d.jsxs)(t.p,{children:[(0,d.jsx)(t.strong,{children:"Note"}),"\nTo easy collaboration & transparency within the SCS team all users will have their default_project_id set to ",(0,d.jsx)(t.code,{children:"p500924-scs-community"})," by default and will have full access on all projects listed below."]}),"\n"]}),"\n",(0,d.jsx)(t.h3,{id:"service-users",children:"Service Users"}),"\n",(0,d.jsx)(t.p,{children:"Service users will have their default_project_id set to a specific project and will NOT be granted full access to other projects by default."}),"\n",(0,d.jsxs)(t.table,{children:[(0,d.jsx)(t.thead,{children:(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.th,{style:{textAlign:"center"},children:"Unique Identifier"}),(0,d.jsx)(t.th,{children:"Service User Name"}),(0,d.jsx)(t.th,{children:"Full Access on"}),(0,d.jsx)(t.th,{children:"Community Contact"}),(0,d.jsx)(t.th,{children:"Description"}),(0,d.jsx)(t.th,{style:{textAlign:"center"},children:"Needed until"})]})}),(0,d.jsxs)(t.tbody,{children:[(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"9a1576af59644a2dbbace773ad17158d"}),(0,d.jsx)(t.td,{children:"u500924-svc-sig-monitoring"}),(0,d.jsx)(t.td,{children:"p500924-sig-monitoring1"}),(0,d.jsx)(t.td,{children:"fkr"}),(0,d.jsx)(t.td,{children:"Service User - SIG Monitoring"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"31.12.2023"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"4925967416894fd78be6701689059653"}),(0,d.jsx)(t.td,{children:"u500924-svc-cloudmon"}),(0,d.jsx)(t.td,{children:"p500924-cloudmon-target"}),(0,d.jsx)(t.td,{children:"Erik-Kostelansky-dNation"}),(0,d.jsx)(t.td,{children:"Service User - VP12 Test Project"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"31.12.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"f89b3d64ddff4d9d8cadb5e06fa22299"}),(0,d.jsx)(t.td,{children:"u500924-svc-healthmonitor"}),(0,d.jsx)(t.td,{children:"p500924-scs-healthmonitor"}),(0,d.jsx)(t.td,{children:"garloff"}),(0,d.jsx)(t.td,{children:"Service User - SCS Health Monitor"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"49cc3d72fbdf41fe8dc407f57f026dbf"}),(0,d.jsx)(t.td,{children:"u500924-svc-standards"}),(0,d.jsx)(t.td,{children:"p500924-scs-healthmonitor"}),(0,d.jsx)(t.td,{children:"garloff"}),(0,d.jsx)(t.td,{children:"Service User - SCS Standards Compliance Check"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"1b6bb583fc5e40e49f2a7e9b4301de65"}),(0,d.jsx)(t.td,{children:"u500924-svc-zuul"}),(0,d.jsx)(t.td,{children:"p500924-scs-zuul"}),(0,d.jsx)(t.td,{children:"o-otte"}),(0,d.jsx)(t.td,{children:"Service User - SCS Zuul"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.11.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"}}),(0,d.jsx)(t.td,{}),(0,d.jsx)(t.td,{}),(0,d.jsx)(t.td,{}),(0,d.jsx)(t.td,{}),(0,d.jsx)(t.td,{style:{textAlign:"center"}})]})]})]}),"\n",(0,d.jsx)(t.h3,{id:"projects",children:"Projects"}),"\n",(0,d.jsxs)(t.table,{children:[(0,d.jsx)(t.thead,{children:(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.th,{style:{textAlign:"center"},children:"Unique Identifier"}),(0,d.jsx)(t.th,{children:"Project Name"}),(0,d.jsx)(t.th,{children:"Community Contact"}),(0,d.jsx)(t.th,{children:"Description"}),(0,d.jsx)(t.th,{style:{textAlign:"center"},children:"Needed until"})]})}),(0,d.jsxs)(t.tbody,{children:[(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"2237c767cf5f456da19359ed31c1c16b"}),(0,d.jsx)(t.td,{children:"p500924-scs-community"}),(0,d.jsx)(t.td,{children:"fkr"}),(0,d.jsx)(t.td,{children:"SCS Community Project"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"b43cfafbcf1f4eb08865b2886c29e09b"}),(0,d.jsx)(t.td,{children:"p500924-cluster-api-session"}),(0,d.jsx)(t.td,{children:"garloff"}),(0,d.jsx)(t.td,{children:"cluster-api hands on session"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"9b7a73e516be4cd1acbd63d543985c52"}),(0,d.jsx)(t.td,{children:"p500924-gonicus-dev"}),(0,d.jsx)(t.td,{children:"o-otte"}),(0,d.jsx)(t.td,{children:"GONICUS GmbH"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"3829cc7c8f034fc985f5055a1df6f247"}),(0,d.jsx)(t.td,{children:"p500924-scs-healthmonitor"}),(0,d.jsx)(t.td,{children:"garloff"}),(0,d.jsx)(t.td,{children:"SCS Health Monitor"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"b97d38bf128b4479981c4dbe2ef70cd5"}),(0,d.jsx)(t.td,{children:"p500924-SIG-IAM"}),(0,d.jsx)(t.td,{children:"fkr"}),(0,d.jsx)(t.td,{children:"SIG IAM and VP08"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"9de7d8dc2d674e52be44904d6b338b0b"}),(0,d.jsx)(t.td,{children:"p500924-cloudmon"}),(0,d.jsx)(t.td,{children:"Erik-Kostelansky-dNation"}),(0,d.jsx)(t.td,{children:"VP12 Test Project"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"31.12.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"2c9e0e4ef8d44c36807df50b06b3c81d"}),(0,d.jsx)(t.td,{children:"p500924-cloudmon-target"}),(0,d.jsx)(t.td,{children:"Erik-Kostelansky-dNation"}),(0,d.jsx)(t.td,{children:"Target project for VP12 tests"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"31.12.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"3501db829014406884990a1016f3e25d"}),(0,d.jsx)(t.td,{children:"p500924-sig-monitoring1"}),(0,d.jsx)(t.td,{children:"fkr"}),(0,d.jsx)(t.td,{children:"SIG Monitoring - cloudmon target"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"602778bad3d3470cbe58c4f7611e8eb7"}),(0,d.jsx)(t.td,{children:"p500924-dnation"}),(0,d.jsx)(t.td,{children:"chess-knight"}),(0,d.jsx)(t.td,{children:"dNation dev for VP06c"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"91091d4039a6457db27d48d58bb1b4e4"}),(0,d.jsx)(t.td,{children:"p500924-jschoone"}),(0,d.jsx)(t.td,{children:"jschoone"}),(0,d.jsx)(t.td,{children:"KaaS dev and evaluation"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"93956190702b4a7d8a8886806d57713f"}),(0,d.jsx)(t.td,{children:"p500924-metering"}),(0,d.jsx)(t.td,{children:"cah-link"}),(0,d.jsx)(t.td,{children:"Dev Environment for VP13"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"31.12.2023"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"abbe6561cf6248b6af395334aa09af85"}),(0,d.jsx)(t.td,{children:"p500924-harbor"}),(0,d.jsx)(t.td,{children:"chess-knight"}),(0,d.jsx)(t.td,{children:"SCS Harbor for VP06c"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"e7622c1048ac4520a2d050ae141e826b"}),(0,d.jsx)(t.td,{children:"p500924-tender-6a"}),(0,d.jsx)(t.td,{children:"mxmxchere"}),(0,d.jsx)(t.td,{children:"Dev Environment for VP06a"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"eeed7e0ad33f42f189fb4165116f5a1b"}),(0,d.jsx)(t.td,{children:"p500924-dnation-k8s"}),(0,d.jsx)(t.td,{children:"matofeder"}),(0,d.jsx)(t.td,{children:"dNation dev for VP06c"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"b342f37804f14459bdf703573169bf79"}),(0,d.jsx)(t.td,{children:"p500924-minery"}),(0,d.jsx)(t.td,{children:"90n20"}),(0,d.jsx)(t.td,{children:"Testbed env for Pentesting"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.11.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"0fa3c3559f0d4f39ba7aa70c7f7188ca"}),(0,d.jsx)(t.td,{children:"p500924-tender-10-3"}),(0,d.jsx)(t.td,{children:"tonifinger"}),(0,d.jsx)(t.td,{children:"Dev Environment for VP10-3"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"b682eb90fb834278afb1182018dd2133"}),(0,d.jsx)(t.td,{children:"p500924-scoopex"}),(0,d.jsx)(t.td,{children:"scoopex"}),(0,d.jsx)(t.td,{children:"Marc's gx-scs project"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"021af0688c594bf88ed675b942d3bea8"}),(0,d.jsx)(t.td,{children:"p500924-gx-cred-generator"}),(0,d.jsx)(t.td,{children:"anjastrunk"}),(0,d.jsx)(t.td,{children:"SCS Gaia-X Self-Description Generator"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"a07c811315ad40f585945b2939ef12dd"}),(0,d.jsx)(t.td,{children:"p500924-scs-zuul"}),(0,d.jsx)(t.td,{children:"o-otte"}),(0,d.jsx)(t.td,{children:"SCS Zuul"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.11.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"1846709967a744b69f9eb48cac89bb04"}),(0,d.jsx)(t.td,{children:"p500924-scs-k8s-e2e"}),(0,d.jsx)(t.td,{children:"chess-knight"}),(0,d.jsx)(t.td,{children:"E2E-Test for KaaS"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"6ee4b373cb6d42a5bb59d5080987b70d"}),(0,d.jsx)(t.td,{children:"p500924-bitkeks"}),(0,d.jsx)(t.td,{children:"bitkeks"}),(0,d.jsx)(t.td,{children:"Cluster Stacks and Sec"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"4ea22ba875474d039cb57d20b7f710b5"}),(0,d.jsx)(t.td,{children:"p500924-kaas-playground0"}),(0,d.jsx)(t.td,{children:"jschoone"}),(0,d.jsx)(t.td,{children:"Playground0 for Hackathon"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"476672f1023b4bac8837f95a76881757"}),(0,d.jsx)(t.td,{children:"p500924-kaas-playground1"}),(0,d.jsx)(t.td,{children:"jschoone"}),(0,d.jsx)(t.td,{children:"Playground1 for Hackathon"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"04dac2927f744479a5d4c23dd0a3c378"}),(0,d.jsx)(t.td,{children:"p500924-kaas-playground2"}),(0,d.jsx)(t.td,{children:"jschoone"}),(0,d.jsx)(t.td,{children:"Playground2 for Hackathon"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"75279777029847ab9b399390c0dd6042"}),(0,d.jsx)(t.td,{children:"p500924-kaas-playground3"}),(0,d.jsx)(t.td,{children:"jschoone"}),(0,d.jsx)(t.td,{children:"Playground3 for Hackathon"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"0b3c75f80b6743778daccec0da423465"}),(0,d.jsx)(t.td,{children:"p500924-kaas-playground4"}),(0,d.jsx)(t.td,{children:"jschoone"}),(0,d.jsx)(t.td,{children:"Playground4 for Hackathon"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"2340a73644ca47189329061e9c2a0bfe"}),(0,d.jsx)(t.td,{children:"p500924-kaas-playground5"}),(0,d.jsx)(t.td,{children:"jschoone"}),(0,d.jsx)(t.td,{children:"Playground5 for Hackathon"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"3c5bae4a233c4a9d8ae2e4b799d757c9"}),(0,d.jsx)(t.td,{children:"p500924-kaas-playground6"}),(0,d.jsx)(t.td,{children:"jschoone"}),(0,d.jsx)(t.td,{children:"Playground6 for Hackathon"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"03783b4952344c849af37d26818d19f0"}),(0,d.jsx)(t.td,{children:"p500924-kaas-playground7"}),(0,d.jsx)(t.td,{children:"jschoone"}),(0,d.jsx)(t.td,{children:"Playground7 for Hackathon"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"5c6d4d7183834eafbc20108ad647a9c0"}),(0,d.jsx)(t.td,{children:"p500924-kaas-playground8"}),(0,d.jsx)(t.td,{children:"jschoone"}),(0,d.jsx)(t.td,{children:"Playground8 for Hackathon"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"7e18881932f749baa7d547ebd407b8d8"}),(0,d.jsx)(t.td,{children:"p500924-kaas-playground9"}),(0,d.jsx)(t.td,{children:"jschoone"}),(0,d.jsx)(t.td,{children:"Playground9 for Hackathon"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.09.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"d9dc2f33e76240219db484526e9f601d"}),(0,d.jsx)(t.td,{children:"p500924-akafazov"}),(0,d.jsx)(t.td,{children:"akafazov"}),(0,d.jsx)(t.td,{children:"akafazov Testbed"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"30.04.2024"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"b07ad6a84982471b9a344ef9947f0e0f"}),(0,d.jsx)(t.td,{children:"p500924-gtema"}),(0,d.jsx)(t.td,{children:"gtema"}),(0,d.jsx)(t.td,{children:"Testbed for gtema"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"e89ac8c9f66f46b5a983b2a05d2a66ec"}),(0,d.jsx)(t.td,{children:"p500924-zuse-z3"}),(0,d.jsx)(t.td,{children:"zuse-z3"}),(0,d.jsx)(t.td,{children:"Josefine's gx-scs project"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"fc1f7a0e10a64d6083dcdbcb7ccf6ff4"}),(0,d.jsx)(t.td,{children:"p500924-compliance-monitor"}),(0,d.jsx)(t.td,{children:"mbuechse"}),(0,d.jsx)(t.td,{children:"SCS Compliance Monitor Deployment"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]})]})]}),"\n",(0,d.jsx)(t.h2,{id:"wavecon",children:"Wavecon"}),"\n",(0,d.jsx)(t.h3,{id:"service-users-1",children:"Service Users"}),"\n",(0,d.jsxs)(t.table,{children:[(0,d.jsx)(t.thead,{children:(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.th,{style:{textAlign:"center"},children:"Unique Identifier"}),(0,d.jsx)(t.th,{children:"Service User Name"}),(0,d.jsx)(t.th,{children:"Full Access on"}),(0,d.jsx)(t.th,{children:"Community Contact"}),(0,d.jsx)(t.th,{children:"Description"}),(0,d.jsx)(t.th,{style:{textAlign:"center"},children:"Needed until"})]})}),(0,d.jsx)(t.tbody,{children:(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"df4af5376bbd4de587c4335622149be7"}),(0,d.jsx)(t.td,{children:"scs-standards"}),(0,d.jsx)(t.td,{children:"scs-standards"}),(0,d.jsx)(t.td,{children:"itrich"}),(0,d.jsx)(t.td,{children:"Service User - SCS Standards Compliance Check"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]})})]}),"\n",(0,d.jsx)(t.h3,{id:"projects-1",children:"Projects"}),"\n",(0,d.jsxs)(t.table,{children:[(0,d.jsx)(t.thead,{children:(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.th,{style:{textAlign:"center"},children:"Unique Identifier"}),(0,d.jsx)(t.th,{children:"Project Name"}),(0,d.jsx)(t.th,{children:"Community Contact"}),(0,d.jsx)(t.th,{children:"Description"}),(0,d.jsx)(t.th,{style:{textAlign:"center"},children:"Needed until"})]})}),(0,d.jsxs)(t.tbody,{children:[(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"718964b4b87446688ac04b151519fb51"}),(0,d.jsx)(t.td,{children:"scs"}),(0,d.jsx)(t.td,{children:"garloff"}),(0,d.jsx)(t.td,{children:"SCS Health Monitor"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"c46ccc9e695c4b23bacee2ad11145d9a"}),(0,d.jsx)(t.td,{children:"scs-health-monitor"}),(0,d.jsx)(t.td,{children:"garloff"}),(0,d.jsx)(t.td,{children:"SCS Health Monitor"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]}),(0,d.jsxs)(t.tr,{children:[(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"00de553df86949b49365baee6375fb5a"}),(0,d.jsx)(t.td,{children:"scs-standards"}),(0,d.jsx)(t.td,{children:"itrich"}),(0,d.jsx)(t.td,{children:"SCS Health Monitor"}),(0,d.jsx)(t.td,{style:{textAlign:"center"},children:"\u221e"})]})]})]})]})}function o(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,d.jsx)(t,{...e,children:(0,d.jsx)(x,{...e})}):x(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>l});var d=n(96540);const s={},r=d.createContext(s);function c(e){const t=d.useContext(r);return d.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),d.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/17896441.c03dac50.js b/assets/js/17896441.c03dac50.js new file mode 100644 index 0000000000..d9b910b8d3 --- /dev/null +++ b/assets/js/17896441.c03dac50.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8401],{71243:(e,n,t)=>{t.d(n,{A:()=>f});t(96540);var s=t(18215),a=t(17559),i=t(84142),o=t(99169),l=t(28774),r=t(21312),c=t(86025),d=t(74848);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,c.A)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(l.A,{"aria-label":(0,r.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}const v={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function b(e){let{children:n,href:t,isLast:s}=e;const a="breadcrumbs__link";return s?(0,d.jsx)("span",{className:a,itemProp:"name",children:n}):t?(0,d.jsx)(l.A,{className:a,href:t,itemProp:"item",children:(0,d.jsx)("span",{itemProp:"name",children:n})}):(0,d.jsx)("span",{className:a,children:n})}function x(e){let{children:n,active:t,index:a,addMicrodata:i}=e;return(0,d.jsxs)("li",{...i&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,s.A)("breadcrumbs__item",{"breadcrumbs__item--active":t}),children:[n,(0,d.jsx)("meta",{itemProp:"position",content:String(a+1)})]})}function f(){const e=(0,i.OF)(),n=(0,o.Dt)();return e?(0,d.jsx)("nav",{className:(0,s.A)(a.G.docs.docBreadcrumbs,v.breadcrumbsContainer),"aria-label":(0,r.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[n&&(0,d.jsx)(h,{}),e.map(((n,t)=>{const s=t===e.length-1,a="category"===n.type&&n.linkUnlisted?void 0:n.href;return(0,d.jsx)(x,{active:s,index:t,addMicrodata:!!a,children:(0,d.jsx)(b,{href:a,isLast:s,children:n.label})},t)}))]})}):null}},46011:(e,n,t)=>{t.r(n),t.d(n,{default:()=>P});var s=t(96540),a=t(61213),i=t(89532),o=t(74848);const l=s.createContext(null);function r(e){let{children:n,content:t}=e;const a=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(t);return(0,o.jsx)(l.Provider,{value:a,children:n})}function c(){const e=(0,s.useContext)(l);if(null===e)throw new i.dV("DocProvider");return e}function d(){const{metadata:e,frontMatter:n,assets:t}=c();return(0,o.jsx)(a.be,{title:e.title,description:e.description,keywords:n.keywords,image:t.image??n.image})}var u=t(18215),m=t(24581),h=t(27719);function v(){const{metadata:e}=c();return(0,o.jsx)(h.A,{previous:e.previous,next:e.next})}var b=t(51878),x=t(4267),f=t(17559),p=t(62053),g=t(4336);function j(){const{metadata:e}=c(),{editUrl:n,lastUpdatedAt:t,lastUpdatedBy:s,tags:a}=e,i=a.length>0,l=!!(n||t||s);return i||l?(0,o.jsxs)("footer",{className:(0,u.A)(f.G.docs.docFooter,"docusaurus-mt-lg"),children:[i&&(0,o.jsx)("div",{className:(0,u.A)("row margin-top--sm",f.G.docs.docFooterTagsRow),children:(0,o.jsx)("div",{className:"col",children:(0,o.jsx)(p.A,{tags:a})})}),l&&(0,o.jsx)(g.A,{className:(0,u.A)("margin-top--sm",f.G.docs.docFooterEditMetaRow),editUrl:n,lastUpdatedAt:t,lastUpdatedBy:s})]}):null}var A=t(41422),C=t(65195),L=t(21312);const N={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function _(e){let{collapsed:n,...t}=e;return(0,o.jsx)("button",{type:"button",...t,className:(0,u.A)("clean-btn",N.tocCollapsibleButton,!n&&N.tocCollapsibleButtonExpanded,t.className),children:(0,o.jsx)(L.A,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const T={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function k(e){let{toc:n,className:t,minHeadingLevel:s,maxHeadingLevel:a}=e;const{collapsed:i,toggleCollapsed:l}=(0,A.u)({initialState:!0});return(0,o.jsxs)("div",{className:(0,u.A)(T.tocCollapsible,!i&&T.tocCollapsibleExpanded,t),children:[(0,o.jsx)(_,{collapsed:i,onClick:l}),(0,o.jsx)(A.N,{lazy:!0,className:T.tocCollapsibleContent,collapsed:i,children:(0,o.jsx)(C.A,{toc:n,minHeadingLevel:s,maxHeadingLevel:a})})]})}const H={tocMobile:"tocMobile_ITEo"};function M(){const{toc:e,frontMatter:n}=c();return(0,o.jsx)(k,{toc:e,minHeadingLevel:n.toc_min_heading_level,maxHeadingLevel:n.toc_max_heading_level,className:(0,u.A)(f.G.docs.docTocMobile,H.tocMobile)})}var I=t(67763);function w(){const{toc:e,frontMatter:n}=c();return(0,o.jsx)(I.A,{toc:e,minHeadingLevel:n.toc_min_heading_level,maxHeadingLevel:n.toc_max_heading_level,className:f.G.docs.docTocDesktop})}var y=t(51107),E=t(11544);function B(e){let{children:n}=e;const t=function(){const{metadata:e,frontMatter:n,contentTitle:t}=c();return n.hide_title||void 0!==t?null:e.title}();return(0,o.jsxs)("div",{className:(0,u.A)(f.G.docs.docMarkdown,"markdown"),children:[t&&(0,o.jsx)("header",{children:(0,o.jsx)(y.A,{as:"h1",children:t})}),(0,o.jsx)(E.A,{children:n})]})}var O=t(71243),V=t(50996);const S={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function G(e){let{children:n}=e;const t=function(){const{frontMatter:e,toc:n}=c(),t=(0,m.l)(),s=e.hide_table_of_contents,a=!s&&n.length>0;return{hidden:s,mobile:a?(0,o.jsx)(M,{}):void 0,desktop:!a||"desktop"!==t&&"ssr"!==t?void 0:(0,o.jsx)(w,{})}}(),{metadata:{unlisted:s}}=c();return(0,o.jsxs)("div",{className:"row",children:[(0,o.jsxs)("div",{className:(0,u.A)("col",!t.hidden&&S.docItemCol),children:[s&&(0,o.jsx)(V.A,{}),(0,o.jsx)(b.A,{}),(0,o.jsxs)("div",{className:S.docItemContainer,children:[(0,o.jsxs)("article",{children:[(0,o.jsx)(O.A,{}),(0,o.jsx)(x.A,{}),t.mobile,(0,o.jsx)(B,{children:n}),(0,o.jsx)(j,{})]}),(0,o.jsx)(v,{})]})]}),t.desktop&&(0,o.jsx)("div",{className:"col col--3",children:t.desktop})]})}function P(e){const n=`docs-doc-id-${e.content.metadata.id}`,t=e.content;return(0,o.jsx)(r,{content:e.content,children:(0,o.jsxs)(a.e3,{className:n,children:[(0,o.jsx)(d,{}),(0,o.jsx)(G,{children:(0,o.jsx)(t,{})})]})})}},27719:(e,n,t)=>{t.d(n,{A:()=>o});t(96540);var s=t(21312),a=t(39022),i=t(74848);function o(e){const{previous:n,next:t}=e;return(0,i.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,s.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[n&&(0,i.jsx)(a.A,{...n,subLabel:(0,i.jsx)(s.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),t&&(0,i.jsx)(a.A,{...t,subLabel:(0,i.jsx)(s.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},4267:(e,n,t)=>{t.d(n,{A:()=>r});t(96540);var s=t(18215),a=t(21312),i=t(17559),o=t(32252),l=t(74848);function r(e){let{className:n}=e;const t=(0,o.r)();return t.badge?(0,l.jsx)("span",{className:(0,s.A)(n,i.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,l.jsx)(a.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:t.label},children:"Version: {versionLabel}"})}):null}},51878:(e,n,t)=>{t.d(n,{A:()=>x});t(96540);var s=t(18215),a=t(44586),i=t(28774),o=t(21312),l=t(44070),r=t(17559),c=t(55597),d=t(32252),u=t(74848);const m={unreleased:function(e){let{siteTitle:n,versionMetadata:t}=e;return(0,u.jsx)(o.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:n,versionLabel:(0,u.jsx)("b",{children:t.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:n,versionMetadata:t}=e;return(0,u.jsx)(o.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:n,versionLabel:(0,u.jsx)("b",{children:t.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const n=m[e.versionMetadata.banner];return(0,u.jsx)(n,{...e})}function v(e){let{versionLabel:n,to:t,onClick:s}=e;return(0,u.jsx)(o.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:n,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(i.A,{to:t,onClick:s,children:(0,u.jsx)(o.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function b(e){let{className:n,versionMetadata:t}=e;const{siteConfig:{title:i}}=(0,a.A)(),{pluginId:o}=(0,l.vT)({failfast:!0}),{savePreferredVersionName:d}=(0,c.g1)(o),{latestDocSuggestion:m,latestVersionSuggestion:b}=(0,l.HW)(o),x=m??(f=b).docs.find((e=>e.id===f.mainDocId));var f;return(0,u.jsxs)("div",{className:(0,s.A)(n,r.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:i,versionMetadata:t})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(v,{versionLabel:b.label,to:x.path,onClick:()=>d(b.name)})})]})}function x(e){let{className:n}=e;const t=(0,d.r)();return t.banner?(0,u.jsx)(b,{className:n,versionMetadata:t}):null}},67763:(e,n,t)=>{t.d(n,{A:()=>c});t(96540);var s=t(18215),a=t(65195);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var o=t(74848);const l="table-of-contents__link toc-highlight",r="table-of-contents__link--active";function c(e){let{className:n,...t}=e;return(0,o.jsx)("div",{className:(0,s.A)(i.tableOfContents,"thin-scrollbar",n),children:(0,o.jsx)(a.A,{...t,linkClassName:l,linkActiveClassName:r})})}},65195:(e,n,t)=>{t.d(n,{A:()=>b});var s=t(96540),a=t(6342);function i(e){const n=e.map((e=>({...e,parentIndex:-1,children:[]}))),t=Array(7).fill(-1);n.forEach(((e,n)=>{const s=t.slice(2,e.level);e.parentIndex=Math.max(...s),t[e.level]=n}));const s=[];return n.forEach((e=>{const{parentIndex:t,...a}=e;t>=0?n[t].children.push(a):s.push(a)})),s}function o(e){let{toc:n,minHeadingLevel:t,maxHeadingLevel:s}=e;return n.flatMap((e=>{const n=o({toc:e.children,minHeadingLevel:t,maxHeadingLevel:s});return function(e){return e.level>=t&&e.level<=s}(e)?[{...e,children:n}]:n}))}function l(e){const n=e.getBoundingClientRect();return n.top===n.bottom?l(e.parentNode):n}function r(e,n){let{anchorTopOffset:t}=n;const s=e.find((e=>l(e).top>=t));if(s){return function(e){return e.top>0&&e.bottom{e.current=n?0:document.querySelector(".navbar").clientHeight}),[n]),e}function d(e){const n=(0,s.useRef)(void 0),t=c();(0,s.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:a,minHeadingLevel:i,maxHeadingLevel:o}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),l=function(e){let{minHeadingLevel:n,maxHeadingLevel:t}=e;const s=[];for(let a=n;a<=t;a+=1)s.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(s.join()))}({minHeadingLevel:i,maxHeadingLevel:o}),c=r(l,{anchorTopOffset:t.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,t){t?(n.current&&n.current!==e&&n.current.classList.remove(a),e.classList.add(a),n.current=e):e.classList.remove(a)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,t])}var u=t(28774),m=t(74848);function h(e){let{toc:n,className:t,linkClassName:s,isChild:a}=e;return n.length?(0,m.jsx)("ul",{className:a?void 0:t,children:n.map((e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.A,{to:`#${e.id}`,className:s??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(h,{isChild:!0,toc:e.children,className:t,linkClassName:s})]},e.id)))}):null}const v=s.memo(h);function b(e){let{toc:n,className:t="table-of-contents table-of-contents__left-border",linkClassName:l="table-of-contents__link",linkActiveClassName:r,minHeadingLevel:c,maxHeadingLevel:u,...h}=e;const b=(0,a.p)(),x=c??b.tableOfContents.minHeadingLevel,f=u??b.tableOfContents.maxHeadingLevel,p=function(e){let{toc:n,minHeadingLevel:t,maxHeadingLevel:a}=e;return(0,s.useMemo)((()=>o({toc:i(n),minHeadingLevel:t,maxHeadingLevel:a})),[n,t,a])}({toc:n,minHeadingLevel:x,maxHeadingLevel:f});return d((0,s.useMemo)((()=>{if(l&&r)return{linkClassName:l,linkActiveClassName:r,minHeadingLevel:x,maxHeadingLevel:f}}),[l,r,x,f])),(0,m.jsx)(v,{toc:p,className:t,linkClassName:l,...h})}},50996:(e,n,t)=>{t.d(n,{A:()=>h});t(96540);var s=t(18215),a=t(21312),i=t(5260),o=t(74848);function l(){return(0,o.jsx)(a.A,{id:"theme.unlistedContent.title",description:"The unlisted content banner title",children:"Unlisted page"})}function r(){return(0,o.jsx)(a.A,{id:"theme.unlistedContent.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,o.jsx)(i.A,{children:(0,o.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}var d=t(17559),u=t(27293);function m(e){let{className:n}=e;return(0,o.jsx)(u.A,{type:"caution",title:(0,o.jsx)(l,{}),className:(0,s.A)(n,d.G.common.unlistedBanner),children:(0,o.jsx)(r,{})})}function h(e){return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(c,{}),(0,o.jsx)(m,{...e})]})}}}]); \ No newline at end of file diff --git a/assets/js/178df98e.f5c2a862.js b/assets/js/178df98e.f5c2a862.js new file mode 100644 index 0000000000..f40af82313 --- /dev/null +++ b/assets/js/178df98e.f5c2a862.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8029],{12218:(s,e,t)=>{t.r(e),t.d(e,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>o});var n=t(74848),d=t(28453);const r={},a="Ops Standards",i={id:"ops/index",title:"Ops Standards",description:"Operational Tooling Standards cover the protocols and guidelines associated with tools and utilities used for monitoring, management, and maintenance of the cloud environment. This includes standards for status pages, alerts, logs, and other operational tools, aiming to optimize the reliability, performance, and security of cloud services and resources.",source:"@site/standards/ops/index.md",sourceDirName:"ops",slug:"/ops/",permalink:"/standards/ops/",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Domain Manager configuration for Keystone",permalink:"/standards/scs-0302-v1-domain-manager-role"},next:{title:"scs-0400: Status Page create decision",permalink:"/standards/ops/scs-0400"}},c={},o=[];function l(s){const e={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"ops-standards",children:"Ops Standards"}),"\n",(0,n.jsx)(e.p,{children:"Operational Tooling Standards cover the protocols and guidelines associated with tools and utilities used for monitoring, management, and maintenance of the cloud environment. This includes standards for status pages, alerts, logs, and other operational tools, aiming to optimize the reliability, performance, and security of cloud services and resources."}),"\n",(0,n.jsx)(e.p,{children:"*Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective)."}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:"Standard"}),(0,n.jsx)(e.th,{children:"Description"}),(0,n.jsx)(e.th,{children:"Draft"}),(0,n.jsx)(e.th,{children:"Stable*"}),(0,n.jsx)(e.th,{children:"Effective"}),(0,n.jsx)(e.th,{children:"Deprecated*"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/ops/scs-0400",children:"scs-0400"})}),(0,n.jsx)(e.td,{children:"Status Page create decision"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0400-v1-status-page-create-decision",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/ops/scs-0401",children:"scs-0401"})}),(0,n.jsx)(e.td,{children:"Status page reference implementation decision"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0401-v1-status-page-reference-implementation-decision",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/ops/scs-0402",children:"scs-0402"})}),(0,n.jsx)(e.td,{children:"Status page OpenAPI decision"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0402-v1-status-page-openapi-spec-decision",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/ops/scs-0403",children:"scs-0403"})}),(0,n.jsx)(e.td,{children:"Architecture for the Cloud Service provider Observability System for the KaaS Layer"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0403-v1-csp-kaas-observability-stack",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/ops/scs-0410",children:"scs-0410"})}),(0,n.jsx)(e.td,{children:"Gnocchi as database for metering"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0410-v1-gnocchi-as-metering-database",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/ops/scs-0411",children:"scs-0411"})}),(0,n.jsx)(e.td,{children:"Push-based approach for providing usage data"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0411-v1-publishing_method_for_metering_data",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/ops/scs-0412",children:"scs-0412"})}),(0,n.jsx)(e.td,{children:"Exposition of IaaS metering data as JSON"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0412-v1-metering-json",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]})]})]})]})}function h(s={}){const{wrapper:e}={...(0,d.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(l,{...s})}):l(s)}},28453:(s,e,t)=>{t.d(e,{R:()=>a,x:()=>i});var n=t(96540);const d={},r=n.createContext(d);function a(s){const e=n.useContext(r);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function i(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(d):s.components||d:a(s.components),n.createElement(r.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/184e5ead.35bcfc20.js b/assets/js/184e5ead.35bcfc20.js new file mode 100644 index 0000000000..218e3700ed --- /dev/null +++ b/assets/js/184e5ead.35bcfc20.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[988],{20737:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>d,metadata:()=>i,toc:()=>o});var n=a(74848),s=a(28453);const d={},r="scs-0102: SCS Image Metadata Standard",i={id:"iaas/scs-0102",title:"scs-0102: SCS Image Metadata Standard",description:"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating",source:"@site/standards/iaas/scs-0102.md",sourceDirName:"iaas",slug:"/iaas/scs-0102",permalink:"/standards/iaas/scs-0102",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"SCS Entropy: Implementation and Testing Notes",permalink:"/standards/scs-0101-w1-entropy-implementation-testing"},next:{title:"SCS Image Metadata Standard",permalink:"/standards/scs-0102-v1-image-metadata"}},c={},o=[];function l(e){const t={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"scs-0102-scs-image-metadata-standard",children:"scs-0102: SCS Image Metadata Standard"}),"\n",(0,n.jsx)(t.p,{children:"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating\nsystem images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements,\nimage handling protocols including updating and origin, and licensing/support details. These guidelines ensure\nthat users can understand, access, and utilize OS images effectively, with clear information on features, updates,\nand licensing provided through well-defined metadata properties."}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0102-v1-image-metadata",children:"scs-0102-v1"})}),(0,n.jsx)(t.td,{children:"Standard"}),(0,n.jsx)(t.td,{children:"Stable"}),(0,n.jsx)(t.td,{children:"2022-10-31"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,a)=>{a.d(t,{R:()=>r,x:()=>i});var n=a(96540);const s={},d=n.createContext(s);function r(e){const t=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(d.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/193dc870.7589d2a8.js b/assets/js/193dc870.7589d2a8.js new file mode 100644 index 0000000000..cd4f6e54d1 --- /dev/null +++ b/assets/js/193dc870.7589d2a8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8220],{33046:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>p,frontMatter:()=>s,metadata:()=>r,toc:()=>l});var o=n(74848),c=n(28453);const s={},i="Teleport",r={id:"iaas/guides/concept-guide/components/teleport",title:"Teleport",description:"Lifecycle Management of Teleport in OSISM",source:"@site/docs/02-iaas/guides/concept-guide/components/teleport.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/teleport",permalink:"/docs/iaas/guides/concept-guide/components/teleport",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/teleport.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"SONiC & OVN",permalink:"/docs/iaas/guides/concept-guide/components/sonic"},next:{title:"Layers in a cluster",permalink:"/docs/iaas/guides/concept-guide/layers"}},a={},l=[{value:"Lifecycle Management of Teleport in OSISM",id:"lifecycle-management-of-teleport-in-osism",level:2}];function d(e){const t={h1:"h1",h2:"h2",...(0,c.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"teleport",children:"Teleport"}),"\n",(0,o.jsx)(t.h2,{id:"lifecycle-management-of-teleport-in-osism",children:"Lifecycle Management of Teleport in OSISM"})]})}function p(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var o=n(96540);const c={},s=o.createContext(c);function i(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1967361e.967b6b8f.js b/assets/js/1967361e.967b6b8f.js new file mode 100644 index 0000000000..b4c946467a --- /dev/null +++ b/assets/js/1967361e.967b6b8f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4485],{41434:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>d,contentTitle:()=>i,default:()=>p,frontMatter:()=>t,metadata:()=>r,toc:()=>c});var n=s(74848),a=s(28453);const t={sidebar_label:"Sandbox Manager",sidebar_position:54},i="Sandbox Manager",r={id:"iaas/guides/operations-guide/openstack/tools/sandbox-manager",title:"Sandbox Manager",description:"",source:"@site/docs/02-iaas/guides/operations-guide/openstack/tools/sandbox-manager.md",sourceDirName:"02-iaas/guides/operations-guide/openstack/tools",slug:"/iaas/guides/operations-guide/openstack/tools/sandbox-manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/sandbox-manager.md",tags:[],version:"current",sidebarPosition:54,frontMatter:{sidebar_label:"Sandbox Manager",sidebar_position:54},sidebar:"docs",previous:{title:"Project Manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/project-manager"},next:{title:"Simple Stress",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress"}},d={},c=[];function u(e){const o={h1:"h1",...(0,a.R)(),...e.components};return(0,n.jsx)(o.h1,{id:"sandbox-manager",children:"Sandbox Manager"})}function p(e={}){const{wrapper:o}={...(0,a.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,o,s)=>{s.d(o,{R:()=>i,x:()=>r});var n=s(96540);const a={},t=n.createContext(a);function i(e){const o=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function r(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),n.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/19afbcc8.6a8cd82b.js b/assets/js/19afbcc8.6a8cd82b.js new file mode 100644 index 0000000000..6c8712ea07 --- /dev/null +++ b/assets/js/19afbcc8.6a8cd82b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4840],{75134:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>v,frontMatter:()=>s,metadata:()=>c,toc:()=>a});var r=n(74848),o=n(28453);const s={sidebar:1},i="Overview",c={id:"getting-started/overview",title:"Overview",description:"TODO",source:"@site/docs/01-getting-started/overview.md",sourceDirName:"01-getting-started",slug:"/getting-started/overview",permalink:"/docs/getting-started/overview",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/01-getting-started/overview.md",tags:[],version:"current",frontMatter:{sidebar:1}},d={},a=[];function u(e){const t={h1:"h1",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"overview",children:"Overview"}),"\n",(0,r.jsx)(t.p,{children:"TODO"})]})}function v(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var r=n(96540);const o={},s=r.createContext(o);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/19cb43cd.51059fbb.js b/assets/js/19cb43cd.51059fbb.js new file mode 100644 index 0000000000..4cbdea5046 --- /dev/null +++ b/assets/js/19cb43cd.51059fbb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1572],{88211:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>d});var o=n(74848),t=n(28453);const a={},i="Upgrade",s={id:"container/components/container-registry/docs/upgrade",title:"Upgrade",description:"This page aims at providing additional information for upgrading Harbor",source:"@site/docs/03-container/components/container-registry/docs/upgrade.md",sourceDirName:"03-container/components/container-registry/docs",slug:"/container/components/container-registry/docs/upgrade",permalink:"/docs/container/components/container-registry/docs/upgrade",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/upgrade.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Rate limit",permalink:"/docs/container/components/container-registry/docs/rate_limit"},next:{title:"Backup and restore",permalink:"/docs/container/components/container-registry/docs/backup_and_restore"}},c={},d=[];function p(e){const r={a:"a",code:"code",h1:"h1",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(r.h1,{id:"upgrade",children:"Upgrade"}),"\n",(0,o.jsxs)(r.p,{children:["This page aims at providing additional information for upgrading ",(0,o.jsx)(r.a,{href:"https://goharbor.io/",children:"Harbor"}),"\ncontainer registry, which operates in the Kubernetes environment and is deployed with Helm.\nIt extends the official ",(0,o.jsx)(r.a,{href:"https://goharbor.io/docs/main/administration/upgrade/helm-upgrade/",children:"Upgrading Harbor Deployed with Helm page"}),",\nwhere the upgrade process is well described. See the following upgrade hints:"]}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:["Always ",(0,o.jsx)(r.a,{href:"/docs/container/components/container-registry/docs/backup_and_restore",children:"backup"})," your Harbor instance before upgrade"]}),"\n",(0,o.jsxs)(r.li,{children:["Normally Harbor helm upgrade from 2 minor versions lower should be ",(0,o.jsx)(r.a,{href:"https://github.com/goharbor/harbor-helm/issues/500#issuecomment-647029797",children:"tested"}),", but always\nvalidate your planned upgrade path with recommendations in the official ",(0,o.jsx)(r.a,{href:"https://goharbor.io/docs/main/administration/upgrade/",children:"docs"}),"."]}),"\n",(0,o.jsxs)(r.li,{children:["The step-by-step upgrade is needed because of possible DDL changes in the Harbor database.\nHarbor core service executes the ",(0,o.jsx)(r.a,{href:"https://github.com/goharbor/harbor/tree/main/make/migrations/postgresql",children:"migrations scripts"})," automatically.\nThe helm upgrade process may fail in the case of the failure of migration scripts.\nHence, it is a good idea to run migration scripts with a pre-upgrade job. Harbor Helm\nhas an option ",(0,o.jsx)(r.code,{children:"enableMigrateHelmHook"})," which separates the database migration from Harbor core\nand runs the migration job as a pre-upgrade hook."]}),"\n"]})]})}function h(e={}){const{wrapper:r}={...(0,t.R)(),...e.components};return r?(0,o.jsx)(r,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},28453:(e,r,n)=>{n.d(r,{R:()=>i,x:()=>s});var o=n(96540);const t={},a=o.createContext(t);function i(e){const r=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function s(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),o.createElement(a.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/19e9bde5.ea612119.js b/assets/js/19e9bde5.ea612119.js new file mode 100644 index 0000000000..4c65d207d0 --- /dev/null +++ b/assets/js/19e9bde5.ea612119.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4175],{50594:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>a});var t=s(74848),r=s(28453);const o={},i="Quickstart",c={id:"operating-scs/components/monitoring/docs/quickstart",title:"Quickstart",description:"These page covers the process of deploying the Observer monitoring solution",source:"@site/docs/04-operating-scs/components/monitoring/docs/quickstart.md",sourceDirName:"04-operating-scs/components/monitoring/docs",slug:"/operating-scs/components/monitoring/docs/quickstart",permalink:"/docs/operating-scs/components/monitoring/docs/quickstart",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/quickstart.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Overview",permalink:"/docs/operating-scs/components/monitoring/docs/overview"},next:{title:"SCS deployment",permalink:"/docs/operating-scs/components/monitoring/docs/scs-deployment"}},l={},a=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Prepare Kubernetes cluster",id:"prepare-kubernetes-cluster",level:2},{value:"Deploy Observer monitoring solution",id:"deploy-observer-monitoring-solution",level:2},{value:"Access the Observer monitoring UIs",id:"access-the-observer-monitoring-uis",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"quickstart",children:"Quickstart"}),"\n",(0,t.jsx)(n.p,{children:"These page covers the process of deploying the Observer monitoring solution\ninto the Kubernetes cluster."}),"\n",(0,t.jsx)(n.p,{children:"The configuration options used in this tutorial result in a non-productive and simple\ndeployment of the Observer monitoring solution. The steps do not guide users to register\ncertain observer targets, such as existing Kubernetes clusters or virtual machines.\nAdditionally, the tutorial lacks guidance for deploying optional and experimental components\nlike IaaS and KaaS monitoring."}),"\n",(0,t.jsx)(n.p,{children:"At the end of this tutorial, the reader should end up with a Kubernetes cluster where the Observer solution will\nbe installed and will monitor the Kubernetes cluster hosting it."}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Kubernetes cluster"}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://kubernetes.io/docs/reference/kubectl/",children:"kubectl"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://helm.sh/",children:"helm"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"prepare-kubernetes-cluster",children:"Prepare Kubernetes cluster"}),"\n",(0,t.jsxs)(n.p,{children:["The Observer monitoring solution is designed to operate on Kubernetes clusters. We have continuously tested it with\nvarious Kubernetes distributions, including vanilla Kubernetes, OKD, ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/",children:"SCS KaaS V1"}),",\nand ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks",children:"SCS KaaS V2"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["To set up the SCS KaaS V2 Kubernetes cluster, please refer to the ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks/blob/feat/r6-docs/docs/quickstart.md",children:"quickstart guide"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["For local testing purposes, we recommend using ",(0,t.jsx)(n.a,{href:"https://kind.sigs.k8s.io/docs/user/quick-start/",children:"KinD"})," (Kubernetes in Docker) as follows:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kind create cluster --config kind-observer-config.yaml --image kindest/node:v1.27.3 --name observer\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you opt not to use KinD with the custom config we provided here, and prefer utilizing another Kubernetes cluster,\nensure that the metric endpoints for various control plane components are properly exposed.\nRefer to the ",(0,t.jsx)(n.a,{href:"https://dnationcloud.github.io/kubernetes-monitoring/helpers/FAQ/#kubernetes-monitoring-shows-or-0-state-for-some-control-plane-components-are-control-plane-components-working-correctly",children:"docs"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"deploy-observer-monitoring-solution",children:"Deploy Observer monitoring solution"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/\nhelm repo update dnationcloud\nhelm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml\n"})}),"\n",(0,t.jsx)(n.h2,{id:"access-the-observer-monitoring-uis",children:"Access the Observer monitoring UIs"}),"\n",(0,t.jsx)(n.p,{children:"At this point, you should have the ability to access the Grafana, Alertmanager and Thanos UIs\nwithin the Observer monitoring cluster."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Grafana UI"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"http://localhost:30000\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Use the following credentials:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["username: ",(0,t.jsx)(n.code,{children:"admin"})]}),"\n",(0,t.jsxs)(n.li,{children:["password: ",(0,t.jsx)(n.code,{children:"pass"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Visit the Layer 0 dashboard, ",(0,t.jsx)(n.code,{children:"infrastructure-services-monitoring"}),", and drill down to explore cluster metrics"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"http://localhost:30000/d/monitoring/infrastructure-services-monitoring",children:"http://localhost:30000/d/monitoring/infrastructure-services-monitoring"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Alertmanager UI"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"http://localhost:30001\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Thanos UI"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"http://localhost:30002\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/19f6a518.99481938.js b/assets/js/19f6a518.99481938.js new file mode 100644 index 0000000000..48f6a1c482 --- /dev/null +++ b/assets/js/19f6a518.99481938.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3444],{49476:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var o=n(74848),i=n(28453);const r={},s="Mission Statement",a={id:"mission-statement",title:"Mission Statement",description:"Sovereign Cloud Stack (SCS) offers more than just a software stack \u2014 it's the embodiment of a collaborative open-source spirit, united by the aim of achieving digital sovereignty. At the heart of this initiative is a foundational pillar: the community.",source:"@site/community/mission-statement.md",sourceDirName:".",slug:"/mission-statement",permalink:"/community/mission-statement",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Overview",permalink:"/community/"},next:{title:"Collaboration",permalink:"/community/collaboration/"}},l={},c=[{value:"Values of our collaboration",id:"values-of-our-collaboration",level:2},{value:"4+1 Open",id:"41-open",level:3},{value:"The 'Four Open"",id:"the-four-open",level:3},{value:"+1 Open",id:"1-open",level:3},{value:"Code of Conduct",id:"code-of-conduct",level:2},{value:"Sovereign Cloud Stack Community",id:"sovereign-cloud-stack-community",level:3},{value:"Our Standards",id:"our-standards",level:3},{value:"Attribution",id:"attribution",level:4}];function d(e){const t={a:"a",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"mission-statement",children:"Mission Statement"}),"\n",(0,o.jsx)(t.p,{children:"Sovereign Cloud Stack (SCS) offers more than just a software stack \u2014 it's the embodiment of a collaborative open-source spirit, united by the aim of achieving digital sovereignty. At the heart of this initiative is a foundational pillar: the community."}),"\n",(0,o.jsx)(t.p,{children:"Open Source technology has become increasingly mature. However, the greatest software is useless if it cannot be developed and operated with full confidence. For this to happen, it is imperative that skills and knowledge be built up, fostered, and retained. In an increasingly competitive market for skilled people and complex IT systems, this is becoming an ever greater challenge for governments, institutions, and companies. How can we operate digital offerings in a self-determined, secure, and excellent manner?"}),"\n",(0,o.jsx)(t.p,{children:"The answer to this must be the collectivization of operational knowledge, just as it has been practiced for many years with software development."}),"\n",(0,o.jsx)(t.p,{children:"In essence, the community is the core of the Sovereign Cloud Stack. It not only propels its evolution but also ensures its relevance, reliability, and resilience in an ever-evolving digital landscape."}),"\n",(0,o.jsxs)(t.p,{children:["Read our ",(0,o.jsx)(t.a,{href:"https://openoperations.org/",children:"open operations manifesto"})," or join our Community either by joining our ",(0,o.jsx)(t.a,{href:"/community/collaboration",children:"team meetings"})," or by joining our ",(0,o.jsx)(t.a,{href:"https://matrix.to/#/#scs-tech:matrix.org",children:"matrix channel"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"Check out the different meetings and working topics within our team and SIG introductions."}),"\n",(0,o.jsx)(t.h2,{id:"values-of-our-collaboration",children:"Values of our collaboration"}),"\n",(0,o.jsx)(t.h3,{id:"41-open",children:"4+1 Open"}),"\n",(0,o.jsx)(t.p,{children:'For us as a community, the "Four Open" are more than a philosophy; rather, we see them as fundamental values that are essential for working collaborativly.'}),"\n",(0,o.jsx)(t.p,{children:"The Four Opens give us the frame to develop SCS as a community that can be considered an important cornerstone tomorrow. We can also contribute to future developments and play an active role in shaping them."}),"\n",(0,o.jsx)(t.h3,{id:"the-four-open",children:"The 'Four Open\""}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Open Source: source code - open software that can be modified without restriction, on the condition that it is not limited in functionality or performance"}),"\n",(0,o.jsx)(t.li,{children:"Open Design: the open process for designing the software"}),"\n",(0,o.jsx)(t.li,{children:"Open Development: the opportunity to participate in the transparent development process on an equal footing"}),"\n",(0,o.jsx)(t.li,{children:"Open Community: an equal community where everyone can be heard"}),"\n"]}),"\n",(0,o.jsx)(t.h3,{id:"1-open",children:"+1 Open"}),"\n",(0,o.jsx)(t.p,{children:"For us, the 5th Open is the Open Operation. At its core, the manifesto encompasses the collective, transparent exchange of knowledge. It describes the way to encourage everyone - regardless of their level of knowledge - to contribute to the community. The 5th Open has the principle that we can only learn from mistakes and therefore has an open and friendly mistake tolerance."}),"\n",(0,o.jsxs)(t.p,{children:["Our SCS '5-Open' community is just as open as described above - join us and leave your mark on the technologies of tomorrow. Join our ",(0,o.jsx)(t.a,{href:"https://www.meetup.com/open-operations-meetup/",children:"Open Operations Meetup"}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"code-of-conduct",children:"Code of Conduct"}),"\n",(0,o.jsx)(t.h3,{id:"sovereign-cloud-stack-community",children:"Sovereign Cloud Stack Community"}),"\n",(0,o.jsx)(t.p,{children:"Sovereign Cloud Stack (SCS) is a network of organizations and individuals: providers, integrators, contributors, users, developers, operators, and associates of standardized sovereign cloud infrastructure. We join forces in defining, implementing and operating a fully open, federated, compatible, interoperable cloud infrastructure and platform."}),"\n",(0,o.jsxs)(t.p,{children:["We are committed to ",(0,o.jsx)(t.a,{href:"https://www.openstack.org/four-opens/",children:'"The Four Opens"'})," of the ",(0,o.jsx)(t.a,{href:"https://openinfra.dev/",children:"Open Infrastructure Foundation"})," and align our actions according to these four non-negotiable core principles of open collaboration. To include the whole DevOps approach we added the fifth open: ",(0,o.jsx)(t.a,{href:"https://openoperations.org/",children:"Open Operations"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"We do believe that an open and welcoming environment is essential for an active and engaged community. As contributors and maintainers we pledge to make participation in our project and our community a harassment-free experience for everyone."}),"\n",(0,o.jsx)(t.p,{children:"No list is ever exhaustive, so we encourage members of the SCS community to adhere to the spirit, rather than the letter, of this code, as that is how it will be enforced. Places where this code may be particularly applicable are GitHub issues and pull requests, chat, mailing lists, team meetings, discussions on social networks broadly directed at or between members of the community, and other direct interactions within the community. Violations may lead to verbal or even public warnings or - especially in case of continued or flagrant offenses - may affect an individual's (or organization's) ability to participate within the SCS community."}),"\n",(0,o.jsx)(t.p,{children:"We encourage you to confront someone or a group of people that you observe to be in violation of the CoC (whether in letter or in spirit) with your observation, so that the person(s) can correct his/her/their behavior. If this is not successful or it is difficult for you to confront the people and you seek support for this, you may contact the SCS project lead at project-lead(at)lists.scs.community"}),"\n",(0,o.jsx)(t.p,{children:"A large fraction of SCS consists of contributions to upstream projects. All SCS contributors are expected to adhere to the respective upstream Codes of Conduct when interacting with such projects, or developing code intended for upstreaming."}),"\n",(0,o.jsx)(t.h3,{id:"our-standards",children:"Our Standards"}),"\n",(0,o.jsx)(t.p,{children:"We ask you to please adhere to the following basic rules:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Be friendly and patient."})," We were all new or lacked knowledge at various points in time. Please try to remember what it felt like to be on that end, and treat people accordingly."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Use welcoming and inclusive language."})," We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, organization, color, immigration status, social and economic status, educational level, level of experience, sex characteristics, gender identity and expression, sexual orientation, gender identity and expression, age, body size and personal appearance, disability, family status, political belief, religion, and mental and physical ability."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Be helpful."})," By helping others to learn our entire ecosystem is enriched. We encourage members of the SCS community to mentor each other and help to raise the general level of knowledge in the community whenever possible."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Choose words that shows respect, empathy and promote constructive dialogue."})," We are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable. This includes, but is not limited to:","\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Violent threats or language directed against another person."}),"\n",(0,o.jsx)(t.li,{children:"Discriminatory jokes and language."}),"\n",(0,o.jsx)(t.li,{children:"Posting sexually explicit or violent material."}),"\n",(0,o.jsx)(t.li,{children:'Posting (or threatening to post) other people\'s personally identifying information ("doxing"), regardless of whether it is publicly available.'}),"\n",(0,o.jsx)(t.li,{children:"Personal insults, especially those using racist, sexist, or otherwise discriminatory terms."}),"\n",(0,o.jsx)(t.li,{children:"Deliberately referring to others by names or pronouns counter to their identity."}),"\n",(0,o.jsx)(t.li,{children:"Unwelcome sexual attention."}),"\n",(0,o.jsx)(t.li,{children:"Repeated harassment of others, e.g. not stopping behavior when someone asks you to stop."}),"\n",(0,o.jsx)(t.li,{children:"Advocating for, or encouraging, any of the above behavior."}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Be respectful, accept differing viewpoints and focus on what is best for the community."})," Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It's important to remember that a community where people feel uncomfortable or threatened is not a productive one. Members of the SCS community should be respectful when dealing with other members as well as with people outside the SCS community."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"When we disagree, try to understand why."})," Disagreements, both social and technical, happen all the time and SCS is no exception. It is important that we resolve disagreements and differing views constructively. Remember that we're different. The strength of SCS comes from its broad community, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn't mean that they're wrong. Don't forget that it is human to err and blaming each other doesn't get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes."]}),"\n"]}),"\n",(0,o.jsx)(t.h4,{id:"attribution",children:"Attribution"}),"\n",(0,o.jsxs)(t.p,{children:["This Code of Conduct is mainly adapted from the ",(0,o.jsx)(t.a,{href:"https://asahilinux.org/code-of-conduct/",children:"Asahi Linux Code of Conduct"})," and the ",(0,o.jsx)(t.a,{href:"https://www.contributor-covenant.org/version/2/1/code_of_conduct/",children:"Contributor Covenant Code of Conduct"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>a});var o=n(96540);const i={},r=o.createContext(i);function s(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1a4e3797.146bb652.js b/assets/js/1a4e3797.146bb652.js new file mode 100644 index 0000000000..576184a182 --- /dev/null +++ b/assets/js/1a4e3797.146bb652.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2138],{53465:(e,t,r)=>{r.d(t,{W:()=>u});var s=r(96540),a=r(44586);const n=["zero","one","two","few","many","other"];function c(e){return n.filter((t=>e.includes(t)))}const l={locale:"en",pluralForms:c(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,a.A)();return(0,s.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:c(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),l}}),[e])}function u(){const e=o();return{selectMessage:(t,r)=>function(e,t,r){const s=e.split("|");if(1===s.length)return s[0];s.length>r.pluralForms.length&&console.error(`For locale=${r.locale}, a maximum of ${r.pluralForms.length} plural forms are expected (${r.pluralForms.join(",")}), but the message contains ${s.length}: ${e}`);const a=r.select(t),n=r.pluralForms.indexOf(a);return s[Math.min(n,s.length-1)]}(r,t,e)}}},41283:(e,t,r)=>{r.r(t),r.d(t,{default:()=>P});var s=r(96540),a=r(44586),n=r(72415),c=r(5260),l=r(28774),o=r(21312),u=r(53465),h=r(20053),i=r(56347),m=r(92303),d=r(11088);const p=function(){const e=(0,m.A)(),t=(0,i.W6)(),r=(0,i.zy)(),{siteConfig:{baseUrl:s}}=(0,a.A)(),n=e?new URLSearchParams(r.search):null,c=n?.get("q")||"",l=n?.get("ctx")||"",o=n?.get("version")||"",u=e=>{const t=new URLSearchParams(r.search);return e?t.set("q",e):t.delete("q"),t};return{searchValue:c,searchContext:l&&Array.isArray(d.Hg)&&d.Hg.some((e=>"string"==typeof e?e===l:e.path===l))?l:"",searchVersion:o,updateSearchPath:e=>{const r=u(e);t.replace({search:r.toString()})},updateSearchContext:e=>{const s=new URLSearchParams(r.search);s.set("ctx",e),t.replace({search:s.toString()})},generateSearchPageLink:e=>{const t=u(e);return`${s}search?${t.toString()}`}}};var g=r(5891),x=r(32384),f=r(86841),y=r(43810),C=r(27674),S=r(2849),j=r(4471);const A={searchContextInput:"searchContextInput_mXoe",searchQueryInput:"searchQueryInput_CFBF",searchResultItem:"searchResultItem_U687",searchResultItemPath:"searchResultItemPath_uIbk",searchResultItemSummary:"searchResultItemSummary_oZHr",searchQueryColumn:"searchQueryColumn_q7nx",searchContextColumn:"searchContextColumn_oWAF"};var I=r(43385),v=r(74848);function w(){const{siteConfig:{baseUrl:e},i18n:{currentLocale:t}}=(0,a.A)(),{selectMessage:r}=(0,u.W)(),{searchValue:n,searchContext:l,searchVersion:i,updateSearchPath:m,updateSearchContext:f}=p(),[y,C]=(0,s.useState)(n),[j,w]=(0,s.useState)(),[P,b]=(0,s.useState)(),F=`${e}${i}`,_=(0,s.useMemo)((()=>y?(0,o.T)({id:"theme.SearchPage.existingResultsTitle",message:'Search results for "{query}"',description:"The search page title for non-empty query"},{query:y}):(0,o.T)({id:"theme.SearchPage.emptyResultsTitle",message:"Search the documentation",description:"The search page title for empty query"})),[y]);(0,s.useEffect)((()=>{m(y),j&&(y?j(y,(e=>{b(e)})):b(void 0))}),[y,j]);const T=(0,s.useCallback)((e=>{C(e.target.value)}),[]);return(0,s.useEffect)((()=>{n&&n!==y&&C(n)}),[n]),(0,s.useEffect)((()=>{!async function(){const{wrappedIndexes:e,zhDictionary:t}=!Array.isArray(d.Hg)||l||d.dz?await(0,g.Z)(F,l):{wrappedIndexes:[],zhDictionary:[]};w((()=>(0,x.m)(e,t,100)))}()}),[l,F]),(0,v.jsxs)(s.Fragment,{children:[(0,v.jsxs)(c.A,{children:[(0,v.jsx)("meta",{property:"robots",content:"noindex, follow"}),(0,v.jsx)("title",{children:_})]}),(0,v.jsxs)("div",{className:"container margin-vert--lg",children:[(0,v.jsx)("h1",{children:_}),(0,v.jsxs)("div",{className:"row",children:[(0,v.jsx)("div",{className:(0,h.A)("col",{[A.searchQueryColumn]:Array.isArray(d.Hg),"col--9":Array.isArray(d.Hg),"col--12":!Array.isArray(d.Hg)}),children:(0,v.jsx)("input",{type:"search",name:"q",className:A.searchQueryInput,"aria-label":"Search",onChange:T,value:y,autoComplete:"off",autoFocus:!0})}),Array.isArray(d.Hg)?(0,v.jsx)("div",{className:(0,h.A)("col","col--3","padding-left--none",A.searchContextColumn),children:(0,v.jsxs)("select",{name:"search-context",className:A.searchContextInput,id:"context-selector",value:l,onChange:e=>f(e.target.value),children:[d.dz&&(0,v.jsx)("option",{value:"",children:(0,o.T)({id:"theme.SearchPage.searchContext.everywhere",message:"everywhere"})}),d.Hg.map((e=>{const{label:r,path:s}=(0,I.p)(e,t);return(0,v.jsx)("option",{value:s,children:r},s)}))]})}):null]}),!j&&y&&(0,v.jsx)("div",{children:(0,v.jsx)(S.A,{})}),P&&(P.length>0?(0,v.jsx)("p",{children:r(P.length,(0,o.T)({id:"theme.SearchPage.documentsFound.plurals",message:"1 document found|{count} documents found",description:'Pluralized label for "{count} documents found". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)'},{count:P.length}))}):(0,v.jsx)("p",{children:(0,o.T)({id:"theme.SearchPage.noResultsText",message:"No documents were found",description:"The paragraph for empty search result"})})),(0,v.jsx)("section",{children:P&&P.map((e=>(0,v.jsx)(R,{searchResult:e},e.document.i)))})]})]})}function R(e){let{searchResult:{document:t,type:r,page:s,tokens:a,metadata:n}}=e;const c=0===r,o=2===r,u=(c?t.b:s.b).slice(),h=o?t.s:t.t;c||u.push(s.t);let i="";if(d.CU&&a.length>0){const e=new URLSearchParams;for(const t of a)e.append("_highlight",t);i=`?${e.toString()}`}return(0,v.jsxs)("article",{className:A.searchResultItem,children:[(0,v.jsx)("h2",{children:(0,v.jsx)(l.A,{to:t.u+i+(t.h||""),dangerouslySetInnerHTML:{__html:o?(0,f.Z)(h,a):(0,y.C)(h,(0,C.g)(n,"t"),a,100)}})}),u.length>0&&(0,v.jsx)("p",{className:A.searchResultItemPath,children:(0,j.$)(u)}),o&&(0,v.jsx)("p",{className:A.searchResultItemSummary,dangerouslySetInnerHTML:{__html:(0,y.C)(t.t,(0,C.g)(n,"t"),a,100)}})]})}const P=function(){return(0,v.jsx)(n.A,{children:(0,v.jsx)(w,{})})}}}]); \ No newline at end of file diff --git a/assets/js/1bc22123.ee840646.js b/assets/js/1bc22123.ee840646.js new file mode 100644 index 0000000000..c77a92cfa1 --- /dev/null +++ b/assets/js/1bc22123.ee840646.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4111],{78427:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>d});var i=n(74848),t=n(28453);const o={},r="Release Notes for SCS Release X",l={id:"releases/ReleaseX",title:"Release Notes for SCS Release X",description:"This document is work in progress for the upcoming Release X.",source:"@site/docs/06-releases/ReleaseX.md",sourceDirName:"06-releases",slug:"/releases/ReleaseX",permalink:"/docs/releases/ReleaseX",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/ReleaseX.md",tags:[],version:"current",frontMatter:{}},a={},d=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"New Features (Highlights)",id:"new-features-highlights",level:2},{value:"Operator focused improvements",id:"operator-focused-improvements",level:3},{value:"SCS Developer focused improvements (testbed and k8s cluster management)",id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Resolved Issues",id:"resolved-issues",level:2},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in RX",id:"list-of-known-issues--restrictions-in-rx",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Thanks",id:"thanks",level:2}];function c(e){const s={a:"a",h1:"h1",h2:"h2",h3:"h3",p:"p",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h1,{id:"release-notes-for-scs-release-x",children:"Release Notes for SCS Release X"}),"\n",(0,i.jsx)(s.p,{children:"This document is work in progress for the upcoming Release X.\nRelease X will be released in Months/Year.\nThis note will be removed, once Release X is released and these notes are valid."}),"\n",(0,i.jsx)(s.h2,{id:"scope",children:"Scope"}),"\n",(0,i.jsx)(s.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,i.jsx)(s.h2,{id:"new-features-highlights",children:"New Features (Highlights)"}),"\n",(0,i.jsx)(s.h3,{id:"operator-focused-improvements",children:"Operator focused improvements"}),"\n",(0,i.jsx)(s.h3,{id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",children:"SCS Developer focused improvements (testbed and k8s cluster management)"}),"\n",(0,i.jsx)(s.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,i.jsx)(s.h2,{id:"removals",children:"Removals"}),"\n",(0,i.jsx)(s.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,i.jsx)(s.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,i.jsx)(s.h2,{id:"resolved-issues",children:"Resolved Issues"}),"\n",(0,i.jsx)(s.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,i.jsx)(s.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,i.jsx)(s.h2,{id:"list-of-known-issues--restrictions-in-rx",children:"List of known issues & restrictions in RX"}),"\n",(0,i.jsx)(s.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(s.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,i.jsx)(s.a,{href:"https://scs.community/contribute/",children:"How to contribute page"}),"."]}),"\n",(0,i.jsx)(s.h2,{id:"thanks",children:"Thanks"})]})}function u(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>l});var i=n(96540);const t={},o=i.createContext(t);function r(e){const s=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1c091541.6bb09c75.js b/assets/js/1c091541.6bb09c75.js new file mode 100644 index 0000000000..0437b68673 --- /dev/null +++ b/assets/js/1c091541.6bb09c75.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1153],{52945:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-blog","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/1c894279.f0b684a4.js b/assets/js/1c894279.f0b684a4.js new file mode 100644 index 0000000000..854a6eb055 --- /dev/null +++ b/assets/js/1c894279.f0b684a4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1804],{67490:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>d,metadata:()=>a,toc:()=>c});var i=t(74848),s=t(28453);const d={title:"Sovereign Cloud Standards",type:"Procedural",status:"Stable",track:"Global",stabilized_at:new Date("2022-11-28T00:00:00.000Z"),description:"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision\nrecords within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in\nthe development and maintenance of interoperable and transparent cloud infrastructure standards.\n"},r=void 0,a={id:"scs-0001-v1-sovereign-cloud-standards",title:"Sovereign Cloud Standards",description:"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision\nrecords within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in\nthe development and maintenance of interoperable and transparent cloud infrastructure standards.\n",source:"@site/standards/scs-0001-v1-sovereign-cloud-standards.md",sourceDirName:".",slug:"/scs-0001-v1-sovereign-cloud-standards",permalink:"/standards/scs-0001-v1-sovereign-cloud-standards",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Sovereign Cloud Standards",type:"Procedural",status:"Stable",track:"Global",stabilized_at:"2022-11-28T00:00:00.000Z",description:"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision\nrecords within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in\nthe development and maintenance of interoperable and transparent cloud infrastructure standards.\n"},sidebar:"standards",previous:{title:"scs-0001: Sovereign Cloud Standards",permalink:"/standards/global/scs-0001"},next:{title:"scs-0002: Standards, Docs and Organisation",permalink:"/standards/global/scs-0002"}},o={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Requirements",id:"requirements",level:2},{value:"Sovereign Cloud Standard documents",id:"sovereign-cloud-standard-documents",level:2},{value:"Types of documents",id:"types-of-documents",level:3},{value:"Procedural",id:"procedural",level:4},{value:"Standard",id:"standard",level:4},{value:"Decision Record",id:"decision-record",level:4},{value:"Supplement",id:"supplement",level:4},{value:"Document format",id:"document-format",level:3},{value:"Sections",id:"sections",level:3},{value:"Standard",id:"standard-1",level:4},{value:"Decision Record",id:"decision-record-1",level:4},{value:"Process",id:"process",level:2},{value:"Proposal phase",id:"proposal-phase",level:3},{value:"Proposal of a new document",id:"proposal-of-a-new-document",level:4},{value:"Proposal of a major update to a stable document",id:"proposal-of-a-major-update-to-a-stable-document",level:4},{value:"Development phase (Draft)",id:"development-phase-draft",level:3},{value:"Stabilized phase (Stable)",id:"stabilized-phase-stable",level:3},{value:"Deprecation phase (Deprecated)",id:"deprecation-phase-deprecated",level:3},{value:"Rejection",id:"rejection",level:3},{value:"Open Questions",id:"open-questions",level:2},{value:"Stabilization criteria",id:"stabilization-criteria",level:3},{value:"Breaking change criteria",id:"breaking-change-criteria",level:3},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Versioning",id:"versioning",level:3},{value:"Acknowledgements",id:"acknowledgements",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",mermaid:"mermaid",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"https://scs.community",children:"Sovereign Cloud Stack (SCS)"})," provides standards\nfor a range of cloud infrastructure types.\nIt strives for interoperable and sovereign cloud stacks\nwhich can be deployed and used by a wide range of organizations and individuals.\nWherever feasible,\ntransparency and openness both in respect to the inner workings of the platforms standardised by SCS,\nas well as the SCS organisation itself\nare a paradigm we intend to live."]}),"\n",(0,i.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,i.jsxs)(n.p,{children:['The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in ',(0,i.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2119",children:"RFC 2119"}),"."]}),"\n",(0,i.jsx)(n.p,{children:'In addition, "FORBIDDEN" is to be interpreted equivalent to "MUST NOT".'}),"\n",(0,i.jsx)(n.h2,{id:"sovereign-cloud-standard-documents",children:"Sovereign Cloud Standard documents"}),"\n",(0,i.jsx)(n.p,{children:"One of the main products of the SCS organisation are Sovereign Cloud Standard documents."}),"\n",(0,i.jsx)(n.h3,{id:"types-of-documents",children:"Types of documents"}),"\n",(0,i.jsx)(n.h4,{id:"procedural",children:"Procedural"}),"\n",(0,i.jsx)(n.p,{children:"A procedural SCS document describes a process, a policy or a guideline\nto which the SCS community adheres."}),"\n",(0,i.jsx)(n.h4,{id:"standard",children:"Standard"}),"\n",(0,i.jsx)(n.p,{children:"A standard SCS document describes a technical standard for SCS compliant clouds.\nNote that it may not be necessary for all clouds to implement all standards."}),"\n",(0,i.jsx)(n.h4,{id:"decision-record",children:"Decision Record"}),"\n",(0,i.jsx)(n.p,{children:"Sometimes during the development of the SCS standard,\na complex technical decision needs to be taken,\nwhich does not directly result in a new standard."}),"\n",(0,i.jsxs)(n.p,{children:["The SCS document format formally integrates\nthe documentation of such decisions\nas documents of type ",(0,i.jsx)(n.code,{children:"Decision Record"}),"."]}),"\n",(0,i.jsx)(n.h4,{id:"supplement",children:"Supplement"}),"\n",(0,i.jsx)(n.p,{children:"A supplement extends a Standard with additional information, such as implementation and testing notes,\nthat is merely informative, but not authoritative, and that may be subject to change more frequently\nthan the standard itself."}),"\n",(0,i.jsx)(n.h3,{id:"document-format",children:"Document format"}),"\n",(0,i.jsxs)(n.p,{children:["The SCS documents are provided in GitHub flavored markdown.\nEach document is assigned a unique number.\nTo disambiguate with other organisations using similar schemes\n(such as XEPs, PEPs or IETF RFCs),\nthe numbers are prefixed with ",(0,i.jsx)(n.code,{children:"SCS-"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"To allow a concept to evolve while allowing breaking changes,\neach SCS document is associated with a major version number.\nThis major version number is a positive number\nand the numbering starts at one for each document."}),"\n",(0,i.jsx)(n.p,{children:"In order to make organisation of the SCS documents easier,\neach document also has a slugified title.\nThe slugified title MUST NOT be changed after the acceptance of the document into the repository,\nas it is part of its canonical URL.\nIt MUST consist only of lower-case ASCII letters, numbers and hyphens.\nIt MUST NOT start with a hyphen and SHOULD start with a lower-case letter.\nIt SHOULD NOT contain more than one subsequent hyphen."}),"\n",(0,i.jsxs)(n.p,{children:["The file name of an SCS document is formed using the following pattern:\n",(0,i.jsx)(n.code,{children:"scs-XXXX-vN-T.md"}),", where\n",(0,i.jsx)(n.code,{children:"XXXX"})," is replaced with the zero-padded document number,\n",(0,i.jsx)(n.code,{children:"N"})," is replaced with the major version of the document, and\n",(0,i.jsx)(n.code,{children:"T"})," is replaced with the slugified title.\nFor a document with the number 190, with a major version number 2 and a slugified title ",(0,i.jsx)(n.code,{children:"flavor-naming"}),",\nthe resulting file name would be ",(0,i.jsx)(n.code,{children:"scs-0190-v2-flavor-naming.md"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Supplements deviate from this pattern in that they employ a ",(0,i.jsx)(n.code,{children:"w"})," instead of a ",(0,i.jsx)(n.code,{children:"v"})," in front of the version\nnumber, and each supplement uses the same document number as the main document it is extending."]}),"\n",(0,i.jsxs)(n.p,{children:["The second digit in ",(0,i.jsx)(n.code,{children:"XXXX"})," describes the track where the document belongs:"]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Track"}),(0,i.jsx)(n.th,{children:"Number"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Global"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"IaaS"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"KaaS"}),(0,i.jsx)(n.td,{children:"2"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"IAM"}),(0,i.jsx)(n.td,{children:"3"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Ops"}),(0,i.jsx)(n.td,{children:"4"})]})]})]}),"\n",(0,i.jsx)(n.p,{children:"In addition to the number, each document has the following metadata,\nembedded in the markdown header."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Field name"}),(0,i.jsx)(n.th,{children:"Requirement"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"type"})}),(0,i.jsx)(n.td,{children:"REQUIRED"}),(0,i.jsxs)(n.td,{children:["one of ",(0,i.jsx)(n.code,{children:"Procedural"}),", ",(0,i.jsx)(n.code,{children:"Standard"}),", ",(0,i.jsx)(n.code,{children:"Decision Record"}),", or ",(0,i.jsx)(n.code,{children:"Supplement"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"status"})}),(0,i.jsx)(n.td,{children:"REQUIRED"}),(0,i.jsxs)(n.td,{children:["one of ",(0,i.jsx)(n.code,{children:"Proposal"}),", ",(0,i.jsx)(n.code,{children:"Draft"}),", ",(0,i.jsx)(n.code,{children:"Stable"}),", ",(0,i.jsx)(n.code,{children:"Deprecated"}),", or ",(0,i.jsx)(n.code,{children:"Rejected"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"track"})}),(0,i.jsx)(n.td,{children:"REQUIRED"}),(0,i.jsxs)(n.td,{children:["one of ",(0,i.jsx)(n.code,{children:"Global"}),", ",(0,i.jsx)(n.code,{children:"IaaS"}),", ",(0,i.jsx)(n.code,{children:"KaaS"}),", ",(0,i.jsx)(n.code,{children:"IAM"}),", ",(0,i.jsx)(n.code,{children:"Ops"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"supplements"})}),(0,i.jsxs)(n.td,{children:["REQUIRED precisely when ",(0,i.jsx)(n.code,{children:"type"})," is ",(0,i.jsx)(n.code,{children:"Supplement"})]}),(0,i.jsx)(n.td,{children:"list of documents that are extended by this document (e.g., multiple major versions)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"deprecated_at"})}),(0,i.jsxs)(n.td,{children:["REQUIRED if ",(0,i.jsx)(n.code,{children:"status"})," is ",(0,i.jsx)(n.code,{children:"Deprecated"})]}),(0,i.jsx)(n.td,{children:"ISO formatted date indicating the date after which the deprecation is in effect"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"stabilized_at"})}),(0,i.jsxs)(n.td,{children:["REQUIRED if ",(0,i.jsx)(n.code,{children:"status"})," was ever ",(0,i.jsx)(n.code,{children:"Stable"})]}),(0,i.jsx)(n.td,{children:"ISO formatted date indicating the date after which the document was considered stable"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"rejected_at"})}),(0,i.jsxs)(n.td,{children:["REQUIRED if ",(0,i.jsx)(n.code,{children:"status"})," is ",(0,i.jsx)(n.code,{children:"Rejected"})]}),(0,i.jsx)(n.td,{children:"ISO formatted date indicating the date on which the document was rejected"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"replaced_by"})}),(0,i.jsxs)(n.td,{children:["RECOMMENDED if ",(0,i.jsx)(n.code,{children:"status"})," is ",(0,i.jsx)(n.code,{children:"Deprecated"})," or ",(0,i.jsx)(n.code,{children:"Rejected"}),", FORBIDDEN otherwise"]}),(0,i.jsx)(n.td,{children:"List of documents which replace this document."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"replaces"})}),(0,i.jsx)(n.td,{children:"OPTIONAL"}),(0,i.jsx)(n.td,{children:"List of documents which this document replaces."})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"sections",children:"Sections"}),"\n",(0,i.jsx)(n.h4,{id:"standard-1",children:"Standard"}),"\n",(0,i.jsx)(n.p,{children:"Each Standard document MUST have the following sections:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["An ",(0,i.jsx)(n.em,{children:"Introduction"})," providing context on the document and linking to other relevant materials."]}),"\n",(0,i.jsxs)(n.li,{children:["A ",(0,i.jsx)(n.em,{children:"Motivation"})," section which details why this document or the thing it describes is necessary."]}),"\n",(0,i.jsx)(n.li,{children:"A section containing the actual standardization decision."}),"\n",(0,i.jsxs)(n.li,{children:["A ",(0,i.jsx)(n.em,{children:"Conformance Tests"})," section that contains hints on how to validate\nconformance with this spec, ideally links to conformance test cases."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"We also RECOMMEND the following sections:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["A ",(0,i.jsx)(n.em,{children:"Terminology"})," section which briefly describes terms used in the document, including possible abbreviations."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"In addition, the following OPTIONAL sections should be considered:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["A ",(0,i.jsx)(n.em,{children:"Design Considerations"})," section for Standard type documents,\nwhich details other choices\nwhich have been considered for the specific feature\nbut were ultimately rejected."]}),"\n",(0,i.jsxs)(n.li,{children:["An ",(0,i.jsx)(n.em,{children:"Open Questions"}),' section which links to issues\ndetailing any open discussion points with respect to a document.\nThis section is RECOMMENDED during the discussion phase (pre 1.0.0)\nas a "table of contents" of things to work on in that context.']}),"\n",(0,i.jsxs)(n.li,{children:["A ",(0,i.jsx)(n.em,{children:"Related Documents"})," section which references related Standards\nor Decisions, both upstream and/or other SCS documents."]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"decision-record-1",children:"Decision Record"}),"\n",(0,i.jsx)(n.p,{children:"Each Decision Record document MUST have the following sections:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["An ",(0,i.jsx)(n.em,{children:"Abstract"})," providing a brief introduction on the topic of the document."]}),"\n",(0,i.jsxs)(n.li,{children:["A ",(0,i.jsx)(n.em,{children:"Context"})," section describing the issue relevant for motivating this Decision Record."]}),"\n",(0,i.jsx)(n.li,{children:"A section containing the actual decision that is introduced. The section should also include\nreasoning for this decision."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"We also RECOMMEND the following sections:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["A ",(0,i.jsx)(n.em,{children:"Terminology"})," section which shortly describes terms used in the document, including possible abbreviations."]}),"\n",(0,i.jsxs)(n.li,{children:["A ",(0,i.jsx)(n.em,{children:"Related Documents"})," section which references related Standards\nor Decisions, both upstream and/or other SCS documents."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"In addition, the following OPTIONAL sections should be considered:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["A ",(0,i.jsx)(n.em,{children:"Consequences"})," section describing outcomes from implementing the changes described."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"process",children:"Process"}),"\n",(0,i.jsx)(n.p,{children:"The lifecycle of an SCS document goes through the following phases:\nProposal, Draft, Stable, Deprecated, and Rejected."}),"\n",(0,i.jsx)(n.mermaid,{value:"graph TD\n A[Proposal] --\x3e|Pull Request| B[Draft]\n B --\x3e|Pull Request| D[Stable]\n B --\x3e|Pull Request| E[Rejected]\n D --\x3e|Pull Request| F[Deprecated]"}),"\n",(0,i.jsxs)(n.p,{children:["All decisions for phase transitions follow loose consensus,\nwhere the group which has to form the consensus depends on the ",(0,i.jsx)(n.code,{children:"track"})," of the document:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"IaaS: The team working on infrastructure-as-a-service topics"}),"\n",(0,i.jsx)(n.li,{children:"KaaS: The team working on Kubernetes-as-a-service topics"}),"\n",(0,i.jsx)(n.li,{children:"Ops: The team working on operations topics"}),"\n",(0,i.jsx)(n.li,{children:"IAM: The team working on identity and access management topics"}),"\n",(0,i.jsx)(n.li,{children:"Global: The entire SCS community"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Supplements may be kept in Draft state, because they are not authoritative."}),"\n",(0,i.jsx)(n.h3,{id:"proposal-phase",children:"Proposal phase"}),"\n",(0,i.jsx)(n.h4,{id:"proposal-of-a-new-document",children:"Proposal of a new document"}),"\n",(0,i.jsxs)(n.p,{children:["To propose a new SCS document,\na community participant creates a pull request on GitHub\nagainst the ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards",children:"standards repository in the SovereignCloudStack organisation"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The pull request MUST add exactly one SCS document,\nin the ",(0,i.jsx)(n.code,{children:"Standards"})," folder.\nIn the proposal phase,\nthe document number MUST be replaced with ",(0,i.jsx)(n.code,{children:"xxxx"})," in the file name,\nexcept for a Supplement, which uses the document number of the document it refers to.\nThe major version MUST be 1."]}),"\n",(0,i.jsxs)(n.p,{children:["For a document with a slugified title ",(0,i.jsx)(n.code,{children:"flavor-naming"}),",\nthe file name would for instance be ",(0,i.jsx)(n.code,{children:"scs-xxxx-v1-flavor-naming.md"}),";\nfor a Supplement of ",(0,i.jsx)(n.code,{children:"scs-0100-v3-flavor-naming.md"}),",\nthe file name might be ",(0,i.jsx)(n.code,{children:"scs-0100-w1-flavor-naming-implementation-testing.md"})," (note the ",(0,i.jsx)(n.code,{children:"w1"}),"!)."]}),"\n",(0,i.jsxs)(n.p,{children:["The metadata MUST indicate the intended ",(0,i.jsx)(n.code,{children:"track"})," and ",(0,i.jsx)(n.code,{children:"type"})," of the document,\nand the ",(0,i.jsx)(n.code,{children:"status"})," MUST be set to ",(0,i.jsx)(n.code,{children:"Proposal"}),";\nfor a Supplement, the ",(0,i.jsx)(n.code,{children:"supplements"})," field MUST be set\nto a list of documents (usually containing one element)."]}),"\n",(0,i.jsxs)(n.p,{children:["Upon acceptance by the group of people identified by the ",(0,i.jsx)(n.code,{children:"track"}),",\na number is assigned\n(the next unused number)\nand the proposer is asked\nto rename the file to replace the ",(0,i.jsx)(n.code,{children:"xxxx"})," with that number."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note:"}),"\nDocuments on the ",(0,i.jsx)(n.code,{children:"Design Record"})," track MAY be proposed or accepted directly into ",(0,i.jsx)(n.code,{children:"Stable"})," state,\nif no further discussion is required."]}),"\n",(0,i.jsxs)(n.p,{children:["Hereafter,\nthe pull request can be merged\nand henceforth the document is an official SCS document in ",(0,i.jsx)(n.code,{children:"Draft"})," state."]}),"\n",(0,i.jsx)(n.h4,{id:"proposal-of-a-major-update-to-a-stable-document",children:"Proposal of a major update to a stable document"}),"\n",(0,i.jsxs)(n.p,{children:["To propose major update to a Stable SCS document,\na community participant creates a pull request on GitHub\nagainst the ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards",children:"standards repository in the SovereignCloudStack organisation"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The pull request MUST add exactly one SCS document,\nin the ",(0,i.jsx)(n.code,{children:"Standards"})," folder.\nThe document number MUST be the same as the document it is updating,\nand the major version number MUST be incremented by 1.\nThe slugified title MAY be changed."]}),"\n",(0,i.jsxs)(n.p,{children:["It MUST refer to the old document in its ",(0,i.jsx)(n.code,{children:"replaces"})," metadata.\nThe pull request SHOULD NOT modify the previous document;\ndeprecation of the previous document\nas well as adding the ",(0,i.jsx)(n.code,{children:"replaced_by"})," metadata is a separate step,\nand can only be executed once the new document is ",(0,i.jsx)(n.code,{children:"Stable"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["For a document updating a hypothetical SCS-0390-v3 document,\nthe file name may be ",(0,i.jsx)(n.code,{children:"scs-0390-v4-flavor-naming-this-time-its-serious.md"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Other than the file naming difference,\nthe proposal process is the same as for new documents.\nIn particular, the new document starts out in ",(0,i.jsx)(n.code,{children:"Draft"})," state\nand does not automatically become part of the normative corpus of an SCS release."]}),"\n",(0,i.jsx)(n.h3,{id:"development-phase-draft",children:"Development phase (Draft)"}),"\n",(0,i.jsx)(n.p,{children:"In this phase,\nthe document is developed inside the SCS community."}),"\n",(0,i.jsx)(n.p,{children:"It should not be considered to be normative for any SCS release,\neven if an SCS release happens after the acceptance of the document."}),"\n",(0,i.jsx)(n.p,{children:"Experimental and exploratory implementations are encouraged,\nhowever, implementors must be prepared for breaking changes."}),"\n",(0,i.jsx)(n.p,{children:"Changes to the documents are gated through pull requests."}),"\n",(0,i.jsx)(n.h3,{id:"stabilized-phase-stable",children:"Stabilized phase (Stable)"}),"\n",(0,i.jsxs)(n.p,{children:["Once the document is deemed ready for production use,\nits ",(0,i.jsx)(n.code,{children:"status"})," is changed to ",(0,i.jsx)(n.code,{children:"Stable"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["If the document in question is a ",(0,i.jsx)(n.code,{children:"Standard"}),"\n(and if applicable),\nthe following conditions MUST all be satisfied before stabilizing:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"the corresponding conformance tests have been implemented\naccording to the general guidelines,"}),"\n",(0,i.jsx)(n.li,{children:"they have been shown to work with the reference implementation,"}),"\n",(0,i.jsxs)(n.li,{children:["they are documented in the standard or one of its ",(0,i.jsx)(n.code,{children:"Supplement"}),"\ndocuments."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"After stabilization,\nchanges to the document which may render existing implementations non-conformant\nMUST NOT be made."}),"\n",(0,i.jsx)(n.p,{children:"If a breaking change to an existing SCS document is deemed necessary,\na new document with a new number shall be created\nand the old document SHOULD be deprecated."}),"\n",(0,i.jsx)(n.h3,{id:"deprecation-phase-deprecated",children:"Deprecation phase (Deprecated)"}),"\n",(0,i.jsx)(n.p,{children:"Should a document become obsolete,\nit can be deprecated."}),"\n",(0,i.jsxs)(n.p,{children:["Obsoletions SHOULD be announced ahead of their execution by setting the\n",(0,i.jsx)(n.code,{children:"deprecated_at"})," field to a future date and moving the ",(0,i.jsx)(n.code,{children:"status"})," to ",(0,i.jsx)(n.code,{children:"Deprecated"}),".\nThis signals current and future implementors\nthat the subject matter of the document\nis not considered necessary or state of the art anymore."]}),"\n",(0,i.jsxs)(n.p,{children:["If one or more replacement documents for the document exists,\nit MUST be listed in the ",(0,i.jsx)(n.code,{children:"replaced_by"})," metadata field."]}),"\n",(0,i.jsx)(n.h3,{id:"rejection",children:"Rejection"}),"\n",(0,i.jsxs)(n.p,{children:["If a document is removed from the normative corpus of SCS standards,\nits status is changed to ",(0,i.jsx)(n.code,{children:"Rejected"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["If one or more replacement documents for the document exists,\nit MUST be listed in the ",(0,i.jsx)(n.code,{children:"replaced_by"})," metadata field."]}),"\n",(0,i.jsx)(n.h2,{id:"open-questions",children:"Open Questions"}),"\n",(0,i.jsx)(n.h3,{id:"stabilization-criteria",children:"Stabilization criteria"}),"\n",(0,i.jsx)(n.p,{children:"When should a document be stabilized?\nShould we require at least one public implementation?\nShould we require a minimum experimental time?\nWhat about non-Standard track documents?"}),"\n",(0,i.jsx)(n.h3,{id:"breaking-change-criteria",children:"Breaking change criteria"}),"\n",(0,i.jsx)(n.p,{children:'When is a change breaking and cannot be applied to a Stable document?\nWhat about previously undefined behaviour (uncovered edge case)?\nWhat about ambiguous wording?\nDo we need a separate "Errata" section?'}),"\n",(0,i.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsx)(n.h3,{id:"versioning",children:"Versioning"}),"\n",(0,i.jsxs)(n.p,{children:["An alternative to the proposed scheme for stabilization\nis the use of ",(0,i.jsx)(n.a,{href:"https://semver.org/",children:"SemVer-like"})," versioning."]}),"\n",(0,i.jsxs)(n.p,{children:["In that case, one would have an individual version number with each document,\nwhere a major version greater than zero indicates a stable document.\nThe ",(0,i.jsx)(n.code,{children:"Stable"})," state would be merged with ",(0,i.jsx)(n.code,{children:"Draft"})," state into an ",(0,i.jsx)(n.em,{children:"Active"})," state\nand shared between the stabilized and the development phase."]}),"\n",(0,i.jsx)(n.p,{children:"The advantages of such an approach are:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"It is easy to recognize whether an SCS document has changed between two SCS\nreleases, just by looking at the released version number."}),"\n",(0,i.jsx)(n.li,{children:"It is possible to make breaking changes after stabilization by increasing the\nmajor version number."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The disadvantages of that approach are:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"It is possible to make breaking changes after stabilization.\nPotentially, an hypothetical SCS-1234 document might refer to something completely different\nin a hypothetical R15 release than what it meant in R5,\nif there have been sufficient, gradual breaking changes to the document."}),"\n",(0,i.jsx)(n.p,{children:"That means that for proper linking,\nit would be required to always include the major version number\nwhen referring to an SCS document."}),"\n",(0,i.jsx)(n.p,{children:'This implies having to keep all former versions around in a canonical, linkable form.\nThis induces non-trivial organizational and editorial overhead\nand raises questions around which changes are acceptable to "archived" versions,\nif any.'}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"It would require a clone of the SemVer spec,\nas that spec is highly specific toward software\nand does not fully\n(at least not in the standard-as-written)\ncover specifics of a standards organisation's use-cases."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"acknowledgements",children:"Acknowledgements"}),"\n",(0,i.jsxs)(n.p,{children:["This document is heavily inspired by ",(0,i.jsx)(n.a,{href:"https://xmpp.org/extensions/xep-0001.html",children:"XEP-0001"}),", as published by the XMPP Standards Foundation."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(96540);const s={},d=i.createContext(s);function r(e){const n=i.useContext(d);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1ca0f8e7.53b97c85.js b/assets/js/1ca0f8e7.53b97c85.js new file mode 100644 index 0000000000..40843e841c --- /dev/null +++ b/assets/js/1ca0f8e7.53b97c85.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7810],{62654:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>a});var t=s(74848),r=s(28453);const i={},c="SCS deployment",o={id:"container/components/container-registry/docs/scs-deployment",title:"SCS deployment",description:"The following steps were utilized for deploying the SCS reference installation of the Harbor container registry,",source:"@site/docs/03-container/components/container-registry/docs/scs-deployment.md",sourceDirName:"03-container/components/container-registry/docs",slug:"/container/components/container-registry/docs/scs-deployment",permalink:"/docs/container/components/container-registry/docs/scs-deployment",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/scs-deployment.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Quickstart",permalink:"/docs/container/components/container-registry/docs/quickstart"},next:{title:"Rate limit",permalink:"/docs/container/components/container-registry/docs/rate_limit"}},l={},a=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install Harbor",id:"install-harbor",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"scs-deployment",children:"SCS deployment"}),"\n",(0,t.jsxs)(n.p,{children:["The following steps were utilized for deploying the SCS reference installation of the Harbor container registry,\nwhich is available at ",(0,t.jsx)(n.a,{href:"https://registry.scs.community",children:"https://registry.scs.community"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Kubernetes cluster v1.20+","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["We used the R5 version of SCS KaaS V1, which includes an ingress controller and cert manager","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"export KUBECONFIG=/path/to/kubeconfig\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Flux CLI (it is part of SCS KaaS V1)","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Installation documentation: ",(0,t.jsx)(n.a,{href:"https://fluxcd.io/flux/installation/#install-the-flux-cli",children:"https://fluxcd.io/flux/installation/#install-the-flux-cli"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s https://fluxcd.io/install.sh | sudo FLUX_VERSION=2.2.3 bash\nflux install\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://kubernetes.io/docs/reference/kubectl/",children:"kubectl"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"install-harbor",children:"Install Harbor"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Take ",(0,t.jsx)(n.em,{children:"ingress-nginx-controller"})," LoadBalancer IP address and create DNS record for Harbor."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"kubectl get svc -n ingress-nginx\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\ningress-nginx-controller LoadBalancer 100.92.14.168 81.163.194.219 80:30799/TCP,443:32482/TCP 2m51s\ningress-nginx-controller-admission ClusterIP 100.88.40.231 443/TCP 2m51s\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Generate secrets and install Harbor:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"base/harbor-secrets.bash # pwgen and htpasswd need to be installed\nenvs/public/s3-credentials.bash \nkubectl apply -k envs/public/\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>o});var t=s(96540);const r={},i=t.createContext(r);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1df93b7f.6e5e7eaa.js b/assets/js/1df93b7f.6e5e7eaa.js new file mode 100644 index 0000000000..fba424757c --- /dev/null +++ b/assets/js/1df93b7f.6e5e7eaa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4583],{54368:(e,t,l)=>{l.d(t,{A:()=>d});l(96540);var s=l(89839);const a="gradient_pRJN",n="border_XcL8",o="bottom_ufNC";var i=l(44586),r=l(74848);const d=e=>{const{topLayers:t}=e,l=(0,i.A)().globalData["global-data-plugin"].default.architecturalOverviewData;return l?(0,r.jsxs)("div",{className:`${a} ${n} row`,children:[!t&&(0,r.jsx)("div",{style:{display:"flex",margin:" 10px 0 4px 12px"},children:(0,r.jsx)("h5",{style:{marginBottom:0},children:"SCS Component Map"})}),(0,r.jsxs)("div",{style:{display:"flex",flexWrap:"wrap"},children:[(0,r.jsx)("div",{style:{padding:"8px 8px 8px 8px",margin:"0 0 0 0"},className:`${o} col col--3`,children:l.ops.map(((e,l)=>(0,r.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components},l)))}),(0,r.jsxs)("div",{className:"col col--6",style:{padding:"8px 8px 8px 8px",margin:"0 0 0 0"},children:[l.container.map(((e,a)=>(0,r.jsx)("div",{style:{marginBottom:e===l.container[0]?"8px":"0"},children:(0,r.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components})},a))),l.iaas.map(((e,l)=>(0,r.jsx)("div",{children:(0,r.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components})},l)))]}),(0,r.jsx)("div",{className:"col col--3",style:{padding:"8px 8px 8px 8px",margin:"0 0 0 0"},children:l.iam.map(((e,l)=>(0,r.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components},l)))})]})]}):(0,r.jsx)("div",{children:"No data available."})}},89839:(e,t,l)=>{l.d(t,{A:()=>d});l(96540);const s="contentCard_uSpk",a="layerComponent_syzR",n="layerComponentWip_fSEJ";var o=l(28774),i=l(56347),r=l(74848);const d=e=>{const{title:t,body:l,url:d,buttonText:c,style:x,small:m,components:p}=e,h=(0,i.zy)();return(0,r.jsxs)("div",{style:x,className:`${s} card`,children:[(0,r.jsx)("div",{className:"card__header",children:m?(0,r.jsx)("h5",{style:{marginLeft:"-6px"},children:t}):(0,r.jsx)("h3",{children:t})}),(0,r.jsx)("div",{className:"card__body",children:(0,r.jsx)("p",{children:l})}),(0,r.jsx)("div",{style:{display:"flex",flexWrap:"wrap"},children:p&&p.map(((e,t)=>(0,r.jsx)(o.A,{to:e.url,children:(0,r.jsx)("div",{style:h.pathname==e.url?{color:"blue",backgroundColor:"#0066ff44"}:{},className:"true"==e.stable?a:n,children:e.title})},t)))}),c&&(0,r.jsx)("div",{className:"card__footer",children:(0,r.jsx)(o.A,{className:"button button--secondary button--md",to:d,children:c})})]})}},68198:(e,t,l)=>{l.r(t),l.d(t,{default:()=>r});l(96540),l(28774);var s=l(44586),a=l(72415);var n=l(89839),o=l(54368),i=l(74848);function r(){const e=(0,s.A)().globalData,t=e["global-data-plugin"].default.featureContentData,l=e["global-data-plugin"].default.additionalResourcesData;return(0,i.jsx)(a.A,{description:"Documentation and Community Platform for the Sovereign Cloud Stack",children:(0,i.jsx)("main",{children:(0,i.jsxs)("div",{className:"container",children:[(0,i.jsx)("div",{className:"row",style:{marginTop:"2rem"},children:(0,i.jsxs)("div",{className:"col col--12",children:[(0,i.jsx)("h1",{children:"Welcome to the SCS Documentation"}),(0,i.jsx)("p",{children:"Find user guides, code samples, deployment examples, reference, community pages and more."})]})}),(0,i.jsx)("div",{className:"row",children:t.map(((e,t)=>(0,i.jsx)("div",{className:"col col--3",children:(0,i.jsx)(n.A,{title:e.title,body:e.body,url:e.url,buttonText:e.buttonText})},t)))}),(0,i.jsxs)("div",{className:"row",style:{marginTop:"3rem"},children:[(0,i.jsx)("div",{className:"col col--12",children:(0,i.jsx)("h1",{children:"Architectural Layers"})}),(0,i.jsx)("div",{style:{marginLeft:"16px",marginRight:"16px"},children:(0,i.jsx)(o.A,{topLayers:!0})})]}),(0,i.jsx)("div",{className:"row",style:{marginTop:"3rem"},children:(0,i.jsx)("div",{className:"col col--12",children:(0,i.jsx)("h1",{children:"Additional Resources"})})}),(0,i.jsx)("div",{className:"row",style:{marginBottom:"5rem"},children:l.map(((e,t)=>(0,i.jsx)("div",{className:"col col--3",children:(0,i.jsx)(n.A,{title:e.title,body:e.body,url:e.url,buttonText:e.buttonText})},t)))})]})})})}}}]); \ No newline at end of file diff --git a/assets/js/1e818dbe.234b8edf.js b/assets/js/1e818dbe.234b8edf.js new file mode 100644 index 0000000000..0c367b533e --- /dev/null +++ b/assets/js/1e818dbe.234b8edf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1335],{33168:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var o=n(74848),s=n(28453);const i={},c="Nextcloud",r={id:"tools/nextcloud",title:"Nextcloud",description:"We have a Nextcloud",source:"@site/community/tools/nextcloud.md",sourceDirName:"tools",slug:"/tools/nextcloud",permalink:"/community/tools/nextcloud",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Mailing Lists",permalink:"/community/tools/mailinglists"},next:{title:"Zuul",permalink:"/community/tools/zuul"}},a={},l=[];function u(t){const e={a:"a",code:"code",h1:"h1",p:"p",...(0,s.R)(),...t.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(e.h1,{id:"nextcloud",children:"Nextcloud"}),"\n",(0,o.jsxs)(e.p,{children:["We have a ",(0,o.jsx)(e.a,{href:"https://nextcloud.com",children:"Nextcloud"}),"\n",(0,o.jsx)(e.a,{href:"https://scs.sovereignit.de",children:"instance"})," for sharing files, doing polls, ...\nsetup for things that are not public."]}),"\n",(0,o.jsxs)(e.p,{children:["You can contribute to SCS via the github workflows, asking questions there (via\nopening issues against the issues repository), submitting pull requests, ...\nIf you want to contribute on a regular basis, we are happy to also onboard you\nto the nextcloud and do an onboarding call. Nextcloud onboarding also adds you\nto the ",(0,o.jsx)(e.code,{children:"scs-member@lists.scs.community"})," mailing list which also add you to the\nannouncement list (described in the next paragraph)."]})]})}function d(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>c,x:()=>r});var o=n(96540);const s={},i=o.createContext(s);function c(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function r(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:c(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/1f34ee25.7b047a05.js b/assets/js/1f34ee25.7b047a05.js new file mode 100644 index 0000000000..689ed9f504 --- /dev/null +++ b/assets/js/1f34ee25.7b047a05.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3894],{6031:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>c,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=n(74848),i=n(28453);const r={title:"Getting Started with Wavestack",version:new Date("2023-03-02T00:00:00.000Z"),author:"Linus Walther"},c=void 0,a={id:"cloud-resources/wavestack",title:"Getting Started with Wavestack",description:"Getting Started with Wavestack",source:"@site/community/cloud-resources/wavestack.md",sourceDirName:"cloud-resources",slug:"/cloud-resources/wavestack",permalink:"/community/cloud-resources/wavestack",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Getting Started with Wavestack",version:"2023-03-02T00:00:00.000Z",author:"Linus Walther"},sidebar:"community",previous:{title:"Getting Started Gaia-X Demonstrator @ plusserver",permalink:"/community/cloud-resources/plusserver-gx-scs"},next:{title:"Contribute to Docs",permalink:"/community/category/contribute-to-docs"}},o={},l=[{value:"Getting Started with Wavestack",id:"getting-started-with-wavestack",level:2},{value:"URLs for access",id:"urls-for-access",level:2},{value:"Authentication (UI)",id:"authentication-ui",level:2},{value:"OpenStackClient (CLI)",id:"openstackclient-cli",level:2}];function d(e){const t={a:"a",h2:"h2",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"getting-started-with-wavestack",children:"Getting Started with Wavestack"}),"\n",(0,s.jsx)(t.h2,{id:"urls-for-access",children:"URLs for access"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["UI (Horizon): ",(0,s.jsx)(t.a,{href:"https://dashboard.wavestack.de/",children:"https://dashboard.wavestack.de/"})]}),"\n",(0,s.jsxs)(t.li,{children:["API auth url (Keystone): ",(0,s.jsx)(t.a,{href:"https://api.wavestack.de:5000",children:"https://api.wavestack.de:5000"})]}),"\n",(0,s.jsxs)(t.li,{children:["Object Storage endpoint (S3/SWIFT): ",(0,s.jsx)(t.a,{href:"https://rgw.muc5.wavestack.de:443",children:"https://rgw.muc5.wavestack.de:443"})]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"authentication-ui",children:"Authentication (UI)"}),"\n",(0,s.jsx)(t.p,{children:"For your login you will need:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Username"}),"\n",(0,s.jsx)(t.li,{children:"Password"}),"\n",(0,s.jsx)(t.li,{children:"Domain"}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"openstackclient-cli",children:"OpenStackClient (CLI)"}),"\n",(0,s.jsxs)(t.p,{children:["See: ",(0,s.jsx)(t.a,{href:"/community/cloud-resources/getting-started-openstack",children:"Getting Started with OpenStack"})]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>a});var s=n(96540);const i={},r=s.createContext(i);function c(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/200.2e717c82.js b/assets/js/200.2e717c82.js new file mode 100644 index 0000000000..07c060f0a8 --- /dev/null +++ b/assets/js/200.2e717c82.js @@ -0,0 +1,1227 @@ +"use strict"; +exports.id = 200; +exports.ids = [200]; +exports.modules = { + +/***/ 57200: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99418); + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 3], $V1 = [1, 4], $V2 = [1, 5], $V3 = [1, 6], $V4 = [1, 7], $V5 = [1, 5, 13, 15, 17, 19, 20, 25, 27, 28, 29, 30, 31, 32, 33, 34, 37, 38, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50], $V6 = [1, 5, 6, 13, 15, 17, 19, 20, 25, 27, 28, 29, 30, 31, 32, 33, 34, 37, 38, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50], $V7 = [32, 33, 34], $V8 = [2, 7], $V9 = [1, 13], $Va = [1, 17], $Vb = [1, 18], $Vc = [1, 19], $Vd = [1, 20], $Ve = [1, 21], $Vf = [1, 22], $Vg = [1, 23], $Vh = [1, 24], $Vi = [1, 25], $Vj = [1, 26], $Vk = [1, 27], $Vl = [1, 30], $Vm = [1, 31], $Vn = [1, 32], $Vo = [1, 33], $Vp = [1, 34], $Vq = [1, 35], $Vr = [1, 36], $Vs = [1, 37], $Vt = [1, 38], $Vu = [1, 39], $Vv = [1, 40], $Vw = [1, 41], $Vx = [1, 42], $Vy = [1, 57], $Vz = [1, 58], $VA = [5, 22, 26, 32, 33, 34, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "eol": 4, "SPACE": 5, "QUADRANT": 6, "document": 7, "line": 8, "statement": 9, "axisDetails": 10, "quadrantDetails": 11, "points": 12, "title": 13, "title_value": 14, "acc_title": 15, "acc_title_value": 16, "acc_descr": 17, "acc_descr_value": 18, "acc_descr_multiline_value": 19, "section": 20, "text": 21, "point_start": 22, "point_x": 23, "point_y": 24, "X-AXIS": 25, "AXIS-TEXT-DELIMITER": 26, "Y-AXIS": 27, "QUADRANT_1": 28, "QUADRANT_2": 29, "QUADRANT_3": 30, "QUADRANT_4": 31, "NEWLINE": 32, "SEMI": 33, "EOF": 34, "alphaNumToken": 35, "textNoTagsToken": 36, "STR": 37, "MD_STR": 38, "alphaNum": 39, "PUNCTUATION": 40, "AMP": 41, "NUM": 42, "ALPHA": 43, "COMMA": 44, "PLUS": 45, "EQUALS": 46, "MULT": 47, "DOT": 48, "BRKT": 49, "UNDERSCORE": 50, "MINUS": 51, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 5: "SPACE", 6: "QUADRANT", 13: "title", 14: "title_value", 15: "acc_title", 16: "acc_title_value", 17: "acc_descr", 18: "acc_descr_value", 19: "acc_descr_multiline_value", 20: "section", 22: "point_start", 23: "point_x", 24: "point_y", 25: "X-AXIS", 26: "AXIS-TEXT-DELIMITER", 27: "Y-AXIS", 28: "QUADRANT_1", 29: "QUADRANT_2", 30: "QUADRANT_3", 31: "QUADRANT_4", 32: "NEWLINE", 33: "SEMI", 34: "EOF", 37: "STR", 38: "MD_STR", 40: "PUNCTUATION", 41: "AMP", 42: "NUM", 43: "ALPHA", 44: "COMMA", 45: "PLUS", 46: "EQUALS", 47: "MULT", 48: "DOT", 49: "BRKT", 50: "UNDERSCORE", 51: "MINUS" }, + productions_: [0, [3, 2], [3, 2], [3, 2], [7, 0], [7, 2], [8, 2], [9, 0], [9, 2], [9, 1], [9, 1], [9, 1], [9, 2], [9, 2], [9, 2], [9, 1], [9, 1], [12, 4], [10, 4], [10, 3], [10, 2], [10, 4], [10, 3], [10, 2], [11, 2], [11, 2], [11, 2], [11, 2], [4, 1], [4, 1], [4, 1], [21, 1], [21, 2], [21, 1], [21, 1], [39, 1], [39, 2], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [36, 1], [36, 1], [36, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 12: + this.$ = $$[$0].trim(); + yy.setDiagramTitle(this.$); + break; + case 13: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 14: + case 15: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 16: + yy.addSection($$[$0].substr(8)); + this.$ = $$[$0].substr(8); + break; + case 17: + yy.addPoint($$[$0 - 3], $$[$0 - 1], $$[$0]); + break; + case 18: + yy.setXAxisLeftText($$[$0 - 2]); + yy.setXAxisRightText($$[$0]); + break; + case 19: + $$[$0 - 1].text += " ⟶ "; + yy.setXAxisLeftText($$[$0 - 1]); + break; + case 20: + yy.setXAxisLeftText($$[$0]); + break; + case 21: + yy.setYAxisBottomText($$[$0 - 2]); + yy.setYAxisTopText($$[$0]); + break; + case 22: + $$[$0 - 1].text += " ⟶ "; + yy.setYAxisBottomText($$[$0 - 1]); + break; + case 23: + yy.setYAxisBottomText($$[$0]); + break; + case 24: + yy.setQuadrant1Text($$[$0]); + break; + case 25: + yy.setQuadrant2Text($$[$0]); + break; + case 26: + yy.setQuadrant3Text($$[$0]); + break; + case 27: + yy.setQuadrant4Text($$[$0]); + break; + case 31: + this.$ = { text: $$[$0], type: "text" }; + break; + case 32: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 33: + this.$ = { text: $$[$0], type: "text" }; + break; + case 34: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 35: + this.$ = $$[$0]; + break; + case 36: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + } + }, + table: [{ 3: 1, 4: 2, 5: $V0, 6: $V1, 32: $V2, 33: $V3, 34: $V4 }, { 1: [3] }, { 3: 8, 4: 2, 5: $V0, 6: $V1, 32: $V2, 33: $V3, 34: $V4 }, { 3: 9, 4: 2, 5: $V0, 6: $V1, 32: $V2, 33: $V3, 34: $V4 }, o($V5, [2, 4], { 7: 10 }), o($V6, [2, 28]), o($V6, [2, 29]), o($V6, [2, 30]), { 1: [2, 1] }, { 1: [2, 2] }, o($V7, $V8, { 8: 11, 9: 12, 10: 14, 11: 15, 12: 16, 21: 28, 35: 29, 1: [2, 3], 5: $V9, 13: $Va, 15: $Vb, 17: $Vc, 19: $Vd, 20: $Ve, 25: $Vf, 27: $Vg, 28: $Vh, 29: $Vi, 30: $Vj, 31: $Vk, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }), o($V5, [2, 5]), { 4: 43, 32: $V2, 33: $V3, 34: $V4 }, o($V7, $V8, { 10: 14, 11: 15, 12: 16, 21: 28, 35: 29, 9: 44, 5: $V9, 13: $Va, 15: $Vb, 17: $Vc, 19: $Vd, 20: $Ve, 25: $Vf, 27: $Vg, 28: $Vh, 29: $Vi, 30: $Vj, 31: $Vk, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }), o($V7, [2, 9]), o($V7, [2, 10]), o($V7, [2, 11]), { 14: [1, 45] }, { 16: [1, 46] }, { 18: [1, 47] }, o($V7, [2, 15]), o($V7, [2, 16]), { 21: 48, 35: 29, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }, { 21: 49, 35: 29, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }, { 21: 50, 35: 29, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }, { 21: 51, 35: 29, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }, { 21: 52, 35: 29, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }, { 21: 53, 35: 29, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }, { 5: $Vy, 22: [1, 54], 35: 56, 36: 55, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }, o($VA, [2, 31]), o($VA, [2, 33]), o($VA, [2, 34]), o($VA, [2, 37]), o($VA, [2, 38]), o($VA, [2, 39]), o($VA, [2, 40]), o($VA, [2, 41]), o($VA, [2, 42]), o($VA, [2, 43]), o($VA, [2, 44]), o($VA, [2, 45]), o($VA, [2, 46]), o($VA, [2, 47]), o($V5, [2, 6]), o($V7, [2, 8]), o($V7, [2, 12]), o($V7, [2, 13]), o($V7, [2, 14]), o($V7, [2, 20], { 36: 55, 35: 56, 5: $Vy, 26: [1, 59], 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 23], { 36: 55, 35: 56, 5: $Vy, 26: [1, 60], 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 24], { 36: 55, 35: 56, 5: $Vy, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 25], { 36: 55, 35: 56, 5: $Vy, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 26], { 36: 55, 35: 56, 5: $Vy, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 27], { 36: 55, 35: 56, 5: $Vy, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), { 23: [1, 61] }, o($VA, [2, 32]), o($VA, [2, 48]), o($VA, [2, 49]), o($VA, [2, 50]), o($V7, [2, 19], { 35: 29, 21: 62, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }), o($V7, [2, 22], { 35: 29, 21: 63, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }), { 24: [1, 64] }, o($V7, [2, 18], { 36: 55, 35: 56, 5: $Vy, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 21], { 36: 55, 35: 56, 5: $Vy, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 17])], + defaultActions: { 8: [2, 1], 9: [2, 2] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + break; + case 1: + break; + case 2: + return 32; + case 3: + break; + case 4: + this.begin("title"); + return 13; + case 5: + this.popState(); + return "title_value"; + case 6: + this.begin("acc_title"); + return 15; + case 7: + this.popState(); + return "acc_title_value"; + case 8: + this.begin("acc_descr"); + return 17; + case 9: + this.popState(); + return "acc_descr_value"; + case 10: + this.begin("acc_descr_multiline"); + break; + case 11: + this.popState(); + break; + case 12: + return "acc_descr_multiline_value"; + case 13: + return 25; + case 14: + return 27; + case 15: + return 26; + case 16: + return 28; + case 17: + return 29; + case 18: + return 30; + case 19: + return 31; + case 20: + this.begin("md_string"); + break; + case 21: + return "MD_STR"; + case 22: + this.popState(); + break; + case 23: + this.begin("string"); + break; + case 24: + this.popState(); + break; + case 25: + return "STR"; + case 26: + this.begin("point_start"); + return 22; + case 27: + this.begin("point_x"); + return 23; + case 28: + this.popState(); + break; + case 29: + this.popState(); + this.begin("point_y"); + break; + case 30: + this.popState(); + return 24; + case 31: + return 6; + case 32: + return 43; + case 33: + return "COLON"; + case 34: + return 45; + case 35: + return 44; + case 36: + return 46; + case 37: + return 46; + case 38: + return 47; + case 39: + return 49; + case 40: + return 50; + case 41: + return 48; + case 42: + return 41; + case 43: + return 51; + case 44: + return 42; + case 45: + return 5; + case 46: + return 33; + case 47: + return 40; + case 48: + return 34; + } + }, + rules: [/^(?:%%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[\n\r]+)/i, /^(?:%%[^\n]*)/i, /^(?:title\b)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?: *x-axis *)/i, /^(?: *y-axis *)/i, /^(?: *--+> *)/i, /^(?: *quadrant-1 *)/i, /^(?: *quadrant-2 *)/i, /^(?: *quadrant-3 *)/i, /^(?: *quadrant-4 *)/i, /^(?:["][`])/i, /^(?:[^`"]+)/i, /^(?:[`]["])/i, /^(?:["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:\s*:\s*\[\s*)/i, /^(?:(1)|(0(.\d+)?))/i, /^(?:\s*\] *)/i, /^(?:\s*,\s*)/i, /^(?:(1)|(0(.\d+)?))/i, /^(?: *quadrantChart *)/i, /^(?:[A-Za-z]+)/i, /^(?::)/i, /^(?:\+)/i, /^(?:,)/i, /^(?:=)/i, /^(?:=)/i, /^(?:\*)/i, /^(?:#)/i, /^(?:[\_])/i, /^(?:\.)/i, /^(?:&)/i, /^(?:-)/i, /^(?:[0-9]+)/i, /^(?:\s)/i, /^(?:;)/i, /^(?:[!"#$%&'*+,-.`?\\_/])/i, /^(?:$)/i], + conditions: { "point_y": { "rules": [30], "inclusive": false }, "point_x": { "rules": [29], "inclusive": false }, "point_start": { "rules": [27, 28], "inclusive": false }, "acc_descr_multiline": { "rules": [11, 12], "inclusive": false }, "acc_descr": { "rules": [9], "inclusive": false }, "acc_title": { "rules": [7], "inclusive": false }, "title": { "rules": [5], "inclusive": false }, "md_string": { "rules": [21, 22], "inclusive": false }, "string": { "rules": [24, 25], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 6, 8, 10, 13, 14, 15, 16, 17, 18, 19, 20, 23, 26, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const defaultThemeVariables = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.E)(); +class QuadrantBuilder { + constructor() { + this.config = this.getDefaultConfig(); + this.themeConfig = this.getDefaultThemeConfig(); + this.data = this.getDefaultData(); + } + getDefaultData() { + return { + titleText: "", + quadrant1Text: "", + quadrant2Text: "", + quadrant3Text: "", + quadrant4Text: "", + xAxisLeftText: "", + xAxisRightText: "", + yAxisBottomText: "", + yAxisTopText: "", + points: [] + }; + } + getDefaultConfig() { + var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r; + return { + showXAxis: true, + showYAxis: true, + showTitle: true, + chartHeight: ((_a = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _a.chartWidth) || 500, + chartWidth: ((_b = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _b.chartHeight) || 500, + titlePadding: ((_c = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _c.titlePadding) || 10, + titleFontSize: ((_d = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _d.titleFontSize) || 20, + quadrantPadding: ((_e = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _e.quadrantPadding) || 5, + xAxisLabelPadding: ((_f = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _f.xAxisLabelPadding) || 5, + yAxisLabelPadding: ((_g = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _g.yAxisLabelPadding) || 5, + xAxisLabelFontSize: ((_h = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _h.xAxisLabelFontSize) || 16, + yAxisLabelFontSize: ((_i = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _i.yAxisLabelFontSize) || 16, + quadrantLabelFontSize: ((_j = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _j.quadrantLabelFontSize) || 16, + quadrantTextTopPadding: ((_k = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _k.quadrantTextTopPadding) || 5, + pointTextPadding: ((_l = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _l.pointTextPadding) || 5, + pointLabelFontSize: ((_m = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _m.pointLabelFontSize) || 12, + pointRadius: ((_n = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _n.pointRadius) || 5, + xAxisPosition: ((_o = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _o.xAxisPosition) || "top", + yAxisPosition: ((_p = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _p.yAxisPosition) || "left", + quadrantInternalBorderStrokeWidth: ((_q = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _q.quadrantInternalBorderStrokeWidth) || 1, + quadrantExternalBorderStrokeWidth: ((_r = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.quadrantChart) == null ? void 0 : _r.quadrantExternalBorderStrokeWidth) || 2 + }; + } + getDefaultThemeConfig() { + return { + quadrant1Fill: defaultThemeVariables.quadrant1Fill, + quadrant2Fill: defaultThemeVariables.quadrant2Fill, + quadrant3Fill: defaultThemeVariables.quadrant3Fill, + quadrant4Fill: defaultThemeVariables.quadrant4Fill, + quadrant1TextFill: defaultThemeVariables.quadrant1TextFill, + quadrant2TextFill: defaultThemeVariables.quadrant2TextFill, + quadrant3TextFill: defaultThemeVariables.quadrant3TextFill, + quadrant4TextFill: defaultThemeVariables.quadrant4TextFill, + quadrantPointFill: defaultThemeVariables.quadrantPointFill, + quadrantPointTextFill: defaultThemeVariables.quadrantPointTextFill, + quadrantXAxisTextFill: defaultThemeVariables.quadrantXAxisTextFill, + quadrantYAxisTextFill: defaultThemeVariables.quadrantYAxisTextFill, + quadrantTitleFill: defaultThemeVariables.quadrantTitleFill, + quadrantInternalBorderStrokeFill: defaultThemeVariables.quadrantInternalBorderStrokeFill, + quadrantExternalBorderStrokeFill: defaultThemeVariables.quadrantExternalBorderStrokeFill + }; + } + clear() { + this.config = this.getDefaultConfig(); + this.themeConfig = this.getDefaultThemeConfig(); + this.data = this.getDefaultData(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("clear called"); + } + setData(data) { + this.data = { ...this.data, ...data }; + } + addPoints(points) { + this.data.points = [...points, ...this.data.points]; + } + setConfig(config2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("setConfig called with: ", config2); + this.config = { ...this.config, ...config2 }; + } + setThemeConfig(themeConfig) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("setThemeConfig called with: ", themeConfig); + this.themeConfig = { ...this.themeConfig, ...themeConfig }; + } + calculateSpace(xAxisPosition, showXAxis, showYAxis, showTitle) { + const xAxisSpaceCalculation = this.config.xAxisLabelPadding * 2 + this.config.xAxisLabelFontSize; + const xAxisSpace = { + top: xAxisPosition === "top" && showXAxis ? xAxisSpaceCalculation : 0, + bottom: xAxisPosition === "bottom" && showXAxis ? xAxisSpaceCalculation : 0 + }; + const yAxisSpaceCalculation = this.config.yAxisLabelPadding * 2 + this.config.yAxisLabelFontSize; + const yAxisSpace = { + left: this.config.yAxisPosition === "left" && showYAxis ? yAxisSpaceCalculation : 0, + right: this.config.yAxisPosition === "right" && showYAxis ? yAxisSpaceCalculation : 0 + }; + const titleSpaceCalculation = this.config.titleFontSize + this.config.titlePadding * 2; + const titleSpace = { + top: showTitle ? titleSpaceCalculation : 0 + }; + const quadrantLeft = this.config.quadrantPadding + yAxisSpace.left; + const quadrantTop = this.config.quadrantPadding + xAxisSpace.top + titleSpace.top; + const quadrantWidth = this.config.chartWidth - this.config.quadrantPadding * 2 - yAxisSpace.left - yAxisSpace.right; + const quadrantHeight = this.config.chartHeight - this.config.quadrantPadding * 2 - xAxisSpace.top - xAxisSpace.bottom - titleSpace.top; + const quadrantHalfWidth = quadrantWidth / 2; + const quadrantHalfHeight = quadrantHeight / 2; + const quadrantSpace = { + quadrantLeft, + quadrantTop, + quadrantWidth, + quadrantHalfWidth, + quadrantHeight, + quadrantHalfHeight + }; + return { + xAxisSpace, + yAxisSpace, + titleSpace, + quadrantSpace + }; + } + getAxisLabels(xAxisPosition, showXAxis, showYAxis, spaceData) { + const { quadrantSpace, titleSpace } = spaceData; + const { + quadrantHalfHeight, + quadrantHeight, + quadrantLeft, + quadrantHalfWidth, + quadrantTop, + quadrantWidth + } = quadrantSpace; + const drawXAxisLabelsInMiddle = Boolean(this.data.xAxisRightText); + const drawYAxisLabelsInMiddle = Boolean(this.data.yAxisTopText); + const axisLabels = []; + if (this.data.xAxisLeftText && showXAxis) { + axisLabels.push({ + text: this.data.xAxisLeftText, + fill: this.themeConfig.quadrantXAxisTextFill, + x: quadrantLeft + (drawXAxisLabelsInMiddle ? quadrantHalfWidth / 2 : 0), + y: xAxisPosition === "top" ? this.config.xAxisLabelPadding + titleSpace.top : this.config.xAxisLabelPadding + quadrantTop + quadrantHeight + this.config.quadrantPadding, + fontSize: this.config.xAxisLabelFontSize, + verticalPos: drawXAxisLabelsInMiddle ? "center" : "left", + horizontalPos: "top", + rotation: 0 + }); + } + if (this.data.xAxisRightText && showXAxis) { + axisLabels.push({ + text: this.data.xAxisRightText, + fill: this.themeConfig.quadrantXAxisTextFill, + x: quadrantLeft + quadrantHalfWidth + (drawXAxisLabelsInMiddle ? quadrantHalfWidth / 2 : 0), + y: xAxisPosition === "top" ? this.config.xAxisLabelPadding + titleSpace.top : this.config.xAxisLabelPadding + quadrantTop + quadrantHeight + this.config.quadrantPadding, + fontSize: this.config.xAxisLabelFontSize, + verticalPos: drawXAxisLabelsInMiddle ? "center" : "left", + horizontalPos: "top", + rotation: 0 + }); + } + if (this.data.yAxisBottomText && showYAxis) { + axisLabels.push({ + text: this.data.yAxisBottomText, + fill: this.themeConfig.quadrantYAxisTextFill, + x: this.config.yAxisPosition === "left" ? this.config.yAxisLabelPadding : this.config.yAxisLabelPadding + quadrantLeft + quadrantWidth + this.config.quadrantPadding, + y: quadrantTop + quadrantHeight - (drawYAxisLabelsInMiddle ? quadrantHalfHeight / 2 : 0), + fontSize: this.config.yAxisLabelFontSize, + verticalPos: drawYAxisLabelsInMiddle ? "center" : "left", + horizontalPos: "top", + rotation: -90 + }); + } + if (this.data.yAxisTopText && showYAxis) { + axisLabels.push({ + text: this.data.yAxisTopText, + fill: this.themeConfig.quadrantYAxisTextFill, + x: this.config.yAxisPosition === "left" ? this.config.yAxisLabelPadding : this.config.yAxisLabelPadding + quadrantLeft + quadrantWidth + this.config.quadrantPadding, + y: quadrantTop + quadrantHalfHeight - (drawYAxisLabelsInMiddle ? quadrantHalfHeight / 2 : 0), + fontSize: this.config.yAxisLabelFontSize, + verticalPos: drawYAxisLabelsInMiddle ? "center" : "left", + horizontalPos: "top", + rotation: -90 + }); + } + return axisLabels; + } + getQuadrants(spaceData) { + const { quadrantSpace } = spaceData; + const { quadrantHalfHeight, quadrantLeft, quadrantHalfWidth, quadrantTop } = quadrantSpace; + const quadrants = [ + { + text: { + text: this.data.quadrant1Text, + fill: this.themeConfig.quadrant1TextFill, + x: 0, + y: 0, + fontSize: this.config.quadrantLabelFontSize, + verticalPos: "center", + horizontalPos: "middle", + rotation: 0 + }, + x: quadrantLeft + quadrantHalfWidth, + y: quadrantTop, + width: quadrantHalfWidth, + height: quadrantHalfHeight, + fill: this.themeConfig.quadrant1Fill + }, + { + text: { + text: this.data.quadrant2Text, + fill: this.themeConfig.quadrant2TextFill, + x: 0, + y: 0, + fontSize: this.config.quadrantLabelFontSize, + verticalPos: "center", + horizontalPos: "middle", + rotation: 0 + }, + x: quadrantLeft, + y: quadrantTop, + width: quadrantHalfWidth, + height: quadrantHalfHeight, + fill: this.themeConfig.quadrant2Fill + }, + { + text: { + text: this.data.quadrant3Text, + fill: this.themeConfig.quadrant3TextFill, + x: 0, + y: 0, + fontSize: this.config.quadrantLabelFontSize, + verticalPos: "center", + horizontalPos: "middle", + rotation: 0 + }, + x: quadrantLeft, + y: quadrantTop + quadrantHalfHeight, + width: quadrantHalfWidth, + height: quadrantHalfHeight, + fill: this.themeConfig.quadrant3Fill + }, + { + text: { + text: this.data.quadrant4Text, + fill: this.themeConfig.quadrant4TextFill, + x: 0, + y: 0, + fontSize: this.config.quadrantLabelFontSize, + verticalPos: "center", + horizontalPos: "middle", + rotation: 0 + }, + x: quadrantLeft + quadrantHalfWidth, + y: quadrantTop + quadrantHalfHeight, + width: quadrantHalfWidth, + height: quadrantHalfHeight, + fill: this.themeConfig.quadrant4Fill + } + ]; + for (const quadrant of quadrants) { + quadrant.text.x = quadrant.x + quadrant.width / 2; + if (this.data.points.length === 0) { + quadrant.text.y = quadrant.y + quadrant.height / 2; + quadrant.text.horizontalPos = "middle"; + } else { + quadrant.text.y = quadrant.y + this.config.quadrantTextTopPadding; + quadrant.text.horizontalPos = "top"; + } + } + return quadrants; + } + getQuadrantPoints(spaceData) { + const { quadrantSpace } = spaceData; + const { quadrantHeight, quadrantLeft, quadrantTop, quadrantWidth } = quadrantSpace; + const xAxis = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleLinear */ .m4Y)().domain([0, 1]).range([quadrantLeft, quadrantWidth + quadrantLeft]); + const yAxis = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleLinear */ .m4Y)().domain([0, 1]).range([quadrantHeight + quadrantTop, quadrantTop]); + const points = this.data.points.map((point) => { + const props = { + x: xAxis(point.x), + y: yAxis(point.y), + fill: this.themeConfig.quadrantPointFill, + radius: this.config.pointRadius, + text: { + text: point.text, + fill: this.themeConfig.quadrantPointTextFill, + x: xAxis(point.x), + y: yAxis(point.y) + this.config.pointTextPadding, + verticalPos: "center", + horizontalPos: "top", + fontSize: this.config.pointLabelFontSize, + rotation: 0 + } + }; + return props; + }); + return points; + } + getBorders(spaceData) { + const halfExternalBorderWidth = this.config.quadrantExternalBorderStrokeWidth / 2; + const { quadrantSpace } = spaceData; + const { + quadrantHalfHeight, + quadrantHeight, + quadrantLeft, + quadrantHalfWidth, + quadrantTop, + quadrantWidth + } = quadrantSpace; + const borderLines = [ + // top border + { + strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill, + strokeWidth: this.config.quadrantExternalBorderStrokeWidth, + x1: quadrantLeft - halfExternalBorderWidth, + y1: quadrantTop, + x2: quadrantLeft + quadrantWidth + halfExternalBorderWidth, + y2: quadrantTop + }, + // right border + { + strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill, + strokeWidth: this.config.quadrantExternalBorderStrokeWidth, + x1: quadrantLeft + quadrantWidth, + y1: quadrantTop + halfExternalBorderWidth, + x2: quadrantLeft + quadrantWidth, + y2: quadrantTop + quadrantHeight - halfExternalBorderWidth + }, + // bottom border + { + strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill, + strokeWidth: this.config.quadrantExternalBorderStrokeWidth, + x1: quadrantLeft - halfExternalBorderWidth, + y1: quadrantTop + quadrantHeight, + x2: quadrantLeft + quadrantWidth + halfExternalBorderWidth, + y2: quadrantTop + quadrantHeight + }, + // left border + { + strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill, + strokeWidth: this.config.quadrantExternalBorderStrokeWidth, + x1: quadrantLeft, + y1: quadrantTop + halfExternalBorderWidth, + x2: quadrantLeft, + y2: quadrantTop + quadrantHeight - halfExternalBorderWidth + }, + // vertical inner border + { + strokeFill: this.themeConfig.quadrantInternalBorderStrokeFill, + strokeWidth: this.config.quadrantInternalBorderStrokeWidth, + x1: quadrantLeft + quadrantHalfWidth, + y1: quadrantTop + halfExternalBorderWidth, + x2: quadrantLeft + quadrantHalfWidth, + y2: quadrantTop + quadrantHeight - halfExternalBorderWidth + }, + // horizontal inner border + { + strokeFill: this.themeConfig.quadrantInternalBorderStrokeFill, + strokeWidth: this.config.quadrantInternalBorderStrokeWidth, + x1: quadrantLeft + halfExternalBorderWidth, + y1: quadrantTop + quadrantHalfHeight, + x2: quadrantLeft + quadrantWidth - halfExternalBorderWidth, + y2: quadrantTop + quadrantHalfHeight + } + ]; + return borderLines; + } + getTitle(showTitle) { + if (showTitle) { + return { + text: this.data.titleText, + fill: this.themeConfig.quadrantTitleFill, + fontSize: this.config.titleFontSize, + horizontalPos: "top", + verticalPos: "center", + rotation: 0, + y: this.config.titlePadding, + x: this.config.chartWidth / 2 + }; + } + return; + } + build() { + const showXAxis = this.config.showXAxis && !!(this.data.xAxisLeftText || this.data.xAxisRightText); + const showYAxis = this.config.showYAxis && !!(this.data.yAxisTopText || this.data.yAxisBottomText); + const showTitle = this.config.showTitle && !!this.data.titleText; + const xAxisPosition = this.data.points.length > 0 ? "bottom" : this.config.xAxisPosition; + const calculatedSpace = this.calculateSpace(xAxisPosition, showXAxis, showYAxis, showTitle); + return { + points: this.getQuadrantPoints(calculatedSpace), + quadrants: this.getQuadrants(calculatedSpace), + axisLabels: this.getAxisLabels(xAxisPosition, showXAxis, showYAxis, calculatedSpace), + borderLines: this.getBorders(calculatedSpace), + title: this.getTitle(showTitle) + }; + } +} +const config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); +function textSanitizer(text) { + return (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.d)(text.trim(), config); +} +const quadrantBuilder = new QuadrantBuilder(); +function setQuadrant1Text(textObj) { + quadrantBuilder.setData({ quadrant1Text: textSanitizer(textObj.text) }); +} +function setQuadrant2Text(textObj) { + quadrantBuilder.setData({ quadrant2Text: textSanitizer(textObj.text) }); +} +function setQuadrant3Text(textObj) { + quadrantBuilder.setData({ quadrant3Text: textSanitizer(textObj.text) }); +} +function setQuadrant4Text(textObj) { + quadrantBuilder.setData({ quadrant4Text: textSanitizer(textObj.text) }); +} +function setXAxisLeftText(textObj) { + quadrantBuilder.setData({ xAxisLeftText: textSanitizer(textObj.text) }); +} +function setXAxisRightText(textObj) { + quadrantBuilder.setData({ xAxisRightText: textSanitizer(textObj.text) }); +} +function setYAxisTopText(textObj) { + quadrantBuilder.setData({ yAxisTopText: textSanitizer(textObj.text) }); +} +function setYAxisBottomText(textObj) { + quadrantBuilder.setData({ yAxisBottomText: textSanitizer(textObj.text) }); +} +function addPoint(textObj, x, y) { + quadrantBuilder.addPoints([{ x, y, text: textSanitizer(textObj.text) }]); +} +function setWidth(width) { + quadrantBuilder.setConfig({ chartWidth: width }); +} +function setHeight(height) { + quadrantBuilder.setConfig({ chartHeight: height }); +} +function getQuadrantData() { + const config2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const { themeVariables, quadrantChart: quadrantChartConfig } = config2; + if (quadrantChartConfig) { + quadrantBuilder.setConfig(quadrantChartConfig); + } + quadrantBuilder.setThemeConfig({ + quadrant1Fill: themeVariables.quadrant1Fill, + quadrant2Fill: themeVariables.quadrant2Fill, + quadrant3Fill: themeVariables.quadrant3Fill, + quadrant4Fill: themeVariables.quadrant4Fill, + quadrant1TextFill: themeVariables.quadrant1TextFill, + quadrant2TextFill: themeVariables.quadrant2TextFill, + quadrant3TextFill: themeVariables.quadrant3TextFill, + quadrant4TextFill: themeVariables.quadrant4TextFill, + quadrantPointFill: themeVariables.quadrantPointFill, + quadrantPointTextFill: themeVariables.quadrantPointTextFill, + quadrantXAxisTextFill: themeVariables.quadrantXAxisTextFill, + quadrantYAxisTextFill: themeVariables.quadrantYAxisTextFill, + quadrantExternalBorderStrokeFill: themeVariables.quadrantExternalBorderStrokeFill, + quadrantInternalBorderStrokeFill: themeVariables.quadrantInternalBorderStrokeFill, + quadrantTitleFill: themeVariables.quadrantTitleFill + }); + quadrantBuilder.setData({ titleText: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.t)() }); + return quadrantBuilder.build(); +} +const clear = function() { + quadrantBuilder.clear(); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.v)(); +}; +const db = { + setWidth, + setHeight, + setQuadrant1Text, + setQuadrant2Text, + setQuadrant3Text, + setQuadrant4Text, + setXAxisLeftText, + setXAxisRightText, + setYAxisTopText, + setYAxisBottomText, + addPoint, + getQuadrantData, + clear, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.g, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.t, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.a, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.b +}; +const draw = (txt, id, _version, diagObj) => { + var _a, _b, _c; + function getDominantBaseLine(horizontalPos) { + return horizontalPos === "top" ? "hanging" : "middle"; + } + function getTextAnchor(verticalPos) { + return verticalPos === "left" ? "start" : "middle"; + } + function getTransformation(data) { + return `translate(${data.x}, ${data.y}) rotate(${data.rotation || 0})`; + } + const conf = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Rendering quadrant chart\n" + txt); + const securityLevel = conf.securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body"); + const svg = root.select(`[id="${id}"]`); + const group = svg.append("g").attr("class", "main"); + const width = ((_a = conf.quadrantChart) == null ? void 0 : _a.chartWidth) || 500; + const height = ((_b = conf.quadrantChart) == null ? void 0 : _b.chartHeight) || 500; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.i)(svg, height, width, ((_c = conf.quadrantChart) == null ? void 0 : _c.useMaxWidth) || true); + svg.attr("viewBox", "0 0 " + width + " " + height); + diagObj.db.setHeight(height); + diagObj.db.setWidth(width); + const quadrantData = diagObj.db.getQuadrantData(); + const quadrantsGroup = group.append("g").attr("class", "quadrants"); + const borderGroup = group.append("g").attr("class", "border"); + const dataPointGroup = group.append("g").attr("class", "data-points"); + const labelGroup = group.append("g").attr("class", "labels"); + const titleGroup = group.append("g").attr("class", "title"); + if (quadrantData.title) { + titleGroup.append("text").attr("x", 0).attr("y", 0).attr("fill", quadrantData.title.fill).attr("font-size", quadrantData.title.fontSize).attr("dominant-baseline", getDominantBaseLine(quadrantData.title.horizontalPos)).attr("text-anchor", getTextAnchor(quadrantData.title.verticalPos)).attr("transform", getTransformation(quadrantData.title)).text(quadrantData.title.text); + } + if (quadrantData.borderLines) { + borderGroup.selectAll("line").data(quadrantData.borderLines).enter().append("line").attr("x1", (data) => data.x1).attr("y1", (data) => data.y1).attr("x2", (data) => data.x2).attr("y2", (data) => data.y2).style("stroke", (data) => data.strokeFill).style("stroke-width", (data) => data.strokeWidth); + } + const quadrants = quadrantsGroup.selectAll("g.quadrant").data(quadrantData.quadrants).enter().append("g").attr("class", "quadrant"); + quadrants.append("rect").attr("x", (data) => data.x).attr("y", (data) => data.y).attr("width", (data) => data.width).attr("height", (data) => data.height).attr("fill", (data) => data.fill); + quadrants.append("text").attr("x", 0).attr("y", 0).attr("fill", (data) => data.text.fill).attr("font-size", (data) => data.text.fontSize).attr( + "dominant-baseline", + (data) => getDominantBaseLine(data.text.horizontalPos) + ).attr("text-anchor", (data) => getTextAnchor(data.text.verticalPos)).attr("transform", (data) => getTransformation(data.text)).text((data) => data.text.text); + const labels = labelGroup.selectAll("g.label").data(quadrantData.axisLabels).enter().append("g").attr("class", "label"); + labels.append("text").attr("x", 0).attr("y", 0).text((data) => data.text).attr("fill", (data) => data.fill).attr("font-size", (data) => data.fontSize).attr("dominant-baseline", (data) => getDominantBaseLine(data.horizontalPos)).attr("text-anchor", (data) => getTextAnchor(data.verticalPos)).attr("transform", (data) => getTransformation(data)); + const dataPoints = dataPointGroup.selectAll("g.data-point").data(quadrantData.points).enter().append("g").attr("class", "data-point"); + dataPoints.append("circle").attr("cx", (data) => data.x).attr("cy", (data) => data.y).attr("r", (data) => data.radius).attr("fill", (data) => data.fill); + dataPoints.append("text").attr("x", 0).attr("y", 0).text((data) => data.text.text).attr("fill", (data) => data.text.fill).attr("font-size", (data) => data.text.fontSize).attr( + "dominant-baseline", + (data) => getDominantBaseLine(data.text.horizontalPos) + ).attr("text-anchor", (data) => getTextAnchor(data.text.verticalPos)).attr("transform", (data) => getTransformation(data.text)); +}; +const renderer = { + draw +}; +const diagram = { + parser: parser$1, + db, + renderer, + styles: () => "" +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/2049.521b0348.js b/assets/js/2049.521b0348.js new file mode 100644 index 0000000000..e5cefe7cee --- /dev/null +++ b/assets/js/2049.521b0348.js @@ -0,0 +1 @@ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2049],{76225:e=>{var t,n,r,i;(t=e.exports).foldLength=75,t.newLineChar="\r\n",t.helpers={updateTimezones:function(e){var n,r,i,s,o,a;if(!e||"vcalendar"!==e.name)return e;for(n=e.getAllSubcomponents(),r=[],i={},o=0;o0&&"\\"===e[n-1]))return n;n+=1}return-1},binsearchInsert:function(e,t,n){if(!e.length)return 0;for(var r,i,s=0,o=e.length-1;s<=o;)if((i=n(t,e[r=s+Math.floor((o-s)/2)]))<0)o=r-1;else{if(!(i>0))break;s=r+1}return i<0?r:i>0?r+1:r},dumpn:function(){t.debug&&("undefined"!=typeof console&&"log"in console?t.helpers.dumpn=function(e){console.log(e)}:t.helpers.dumpn=function(e){dump(e+"\n")},t.helpers.dumpn(arguments[0]))},clone:function(e,n){if(e&&"object"==typeof e){if(e instanceof Date)return new Date(e.getTime());if("clone"in e)return e.clone();if(Array.isArray(e)){for(var r=[],i=0;i65535?2:1:(n+=t.newLineChar+" "+r.substring(0,i),r=r.substring(i),i=s=0)}return n.substr(t.newLineChar.length+1)},pad2:function(e){switch("string"!=typeof e&&("number"==typeof e&&(e=parseInt(e)),e=String(e)),e.length){case 0:return"00";case 1:return"0"+e;default:return e}},trunc:function(e){return e<0?Math.ceil(e):Math.floor(e)},inherits:function(e,n,r){function i(){}i.prototype=e.prototype,n.prototype=new i,r&&t.helpers.extend(r,n.prototype)},extend:function(e,t){for(var n in e){var r=Object.getOwnPropertyDescriptor(e,n);r&&!Object.getOwnPropertyDescriptor(t,n)&&Object.defineProperty(t,n,r)}return t}},t.design=function(){"use strict";var e=/\\\\|\\,|\\[Nn]/g,n=/\\|,|\n/g;function r(e,t){return{matches:/.*/,fromICAL:function(t,n){return function(e,t,n){if(-1===e.indexOf("\\"))return e;n&&(t=new RegExp(t.source+"|\\\\"+n));return e.replace(t,p)}(t,e,n)},toICAL:function(e,n){var r=t;return n&&(r=new RegExp(r.source+"|"+n)),e.replace(r,(function(e){switch(e){case"\\":return"\\\\";case";":return"\\;";case",":return"\\,";case"\n":return"\\n";default:return e}}))}}}var i={defaultType:"text"},s={defaultType:"text",multiValue:","},o={defaultType:"text",structuredValue:";"},a={defaultType:"integer"},l={defaultType:"date-time",allowedTypes:["date-time","date"]},c={defaultType:"date-time"},u={defaultType:"uri"},d={defaultType:"utc-offset"},h={defaultType:"recur"},f={defaultType:"date-and-or-time",allowedTypes:["date-time","date","text"]};function p(e){switch(e){case"\\\\":return"\\";case"\\;":return";";case"\\,":return",";case"\\n":case"\\N":return"\n";default:return e}}var g={categories:s,url:u,version:i,uid:i},m={boolean:{values:["TRUE","FALSE"],fromICAL:function(e){return"TRUE"===e},toICAL:function(e){return e?"TRUE":"FALSE"}},float:{matches:/^[+-]?\d+\.\d+$/,fromICAL:function(e){var n=parseFloat(e);return t.helpers.isStrictlyNaN(n)?0:n},toICAL:function(e){return String(e)}},integer:{fromICAL:function(e){var n=parseInt(e);return t.helpers.isStrictlyNaN(n)?0:n},toICAL:function(e){return String(e)}},"utc-offset":{toICAL:function(e){return e.length<7?e.substr(0,3)+e.substr(4,2):e.substr(0,3)+e.substr(4,2)+e.substr(7,2)},fromICAL:function(e){return e.length<6?e.substr(0,3)+":"+e.substr(3,2):e.substr(0,3)+":"+e.substr(3,2)+":"+e.substr(5,2)},decorate:function(e){return t.UtcOffset.fromString(e)},undecorate:function(e){return e.toString()}}},v=t.helpers.extend(m,{text:r(/\\\\|\\;|\\,|\\[Nn]/g,/\\|;|,|\n/g),uri:{},binary:{decorate:function(e){return t.Binary.fromString(e)},undecorate:function(e){return e.toString()}},"cal-address":{},date:{decorate:function(e,n){return w.strict?t.Time.fromDateString(e,n):t.Time.fromString(e,n)},undecorate:function(e){return e.toString()},fromICAL:function(e){return!w.strict&&e.length>=15?v["date-time"].fromICAL(e):e.substr(0,4)+"-"+e.substr(4,2)+"-"+e.substr(6,2)},toICAL:function(e){var t=e.length;return 10==t?e.substr(0,4)+e.substr(5,2)+e.substr(8,2):t>=19?v["date-time"].toICAL(e):e}},"date-time":{fromICAL:function(e){if(w.strict||8!=e.length){var t=e.substr(0,4)+"-"+e.substr(4,2)+"-"+e.substr(6,2)+"T"+e.substr(9,2)+":"+e.substr(11,2)+":"+e.substr(13,2);return e[15]&&"Z"===e[15]&&(t+="Z"),t}return v.date.fromICAL(e)},toICAL:function(e){var t=e.length;if(10!=t||w.strict){if(t>=19){var n=e.substr(0,4)+e.substr(5,2)+e.substr(8,5)+e.substr(14,2)+e.substr(17,2);return e[19]&&"Z"===e[19]&&(n+="Z"),n}return e}return v.date.toICAL(e)},decorate:function(e,n){return w.strict?t.Time.fromDateTimeString(e,n):t.Time.fromString(e,n)},undecorate:function(e){return e.toString()}},duration:{decorate:function(e){return t.Duration.fromString(e)},undecorate:function(e){return e.toString()}},period:{fromICAL:function(e){var n=e.split("/");return n[0]=v["date-time"].fromICAL(n[0]),t.Duration.isValueString(n[1])||(n[1]=v["date-time"].fromICAL(n[1])),n},toICAL:function(e){return w.strict||10!=e[0].length?e[0]=v["date-time"].toICAL(e[0]):e[0]=v.date.toICAL(e[0]),t.Duration.isValueString(e[1])||(w.strict||10!=e[1].length?e[1]=v["date-time"].toICAL(e[1]):e[1]=v.date.toICAL(e[1])),e.join("/")},decorate:function(e,n){return t.Period.fromJSON(e,n,!w.strict)},undecorate:function(e){return e.toJSON()}},recur:{fromICAL:function(e){return t.Recur._stringToData(e,!0)},toICAL:function(e){var n="";for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){var i=e[r];"until"==r?i=i.length>10?v["date-time"].toICAL(i):v.date.toICAL(i):"wkst"==r?"number"==typeof i&&(i=t.Recur.numericDayToIcalDay(i)):Array.isArray(i)&&(i=i.join(",")),n+=r.toUpperCase()+"="+i+";"}return n.substr(0,n.length-1)},decorate:function(e){return t.Recur.fromData(e)},undecorate:function(e){return e.toJSON()}},time:{fromICAL:function(e){if(e.length<6)return e;var t=e.substr(0,2)+":"+e.substr(2,2)+":"+e.substr(4,2);return"Z"===e[6]&&(t+="Z"),t},toICAL:function(e){if(e.length<8)return e;var t=e.substr(0,2)+e.substr(3,2)+e.substr(6,2);return"Z"===e[8]&&(t+="Z"),t}}}),y=t.helpers.extend(g,{action:i,attach:{defaultType:"uri"},attendee:{defaultType:"cal-address"},calscale:i,class:i,comment:i,completed:c,contact:i,created:c,description:i,dtend:l,dtstamp:c,dtstart:l,due:l,duration:{defaultType:"duration"},exdate:{defaultType:"date-time",allowedTypes:["date-time","date"],multiValue:","},exrule:h,freebusy:{defaultType:"period",multiValue:","},geo:{defaultType:"float",structuredValue:";"},"last-modified":c,location:i,method:i,organizer:{defaultType:"cal-address"},"percent-complete":a,priority:a,prodid:i,"related-to":i,repeat:a,rdate:{defaultType:"date-time",allowedTypes:["date-time","date","period"],multiValue:",",detectType:function(e){return-1!==e.indexOf("/")?"period":-1===e.indexOf("T")?"date":"date-time"}},"recurrence-id":l,resources:s,"request-status":o,rrule:h,sequence:a,status:i,summary:i,transp:i,trigger:{defaultType:"duration",allowedTypes:["duration","date-time"]},tzoffsetfrom:d,tzoffsetto:d,tzurl:u,tzid:i,tzname:i}),b=t.helpers.extend(m,{text:r(e,n),uri:r(e,n),date:{decorate:function(e){return t.VCardTime.fromDateAndOrTimeString(e,"date")},undecorate:function(e){return e.toString()},fromICAL:function(e){return 8==e.length?v.date.fromICAL(e):"-"==e[0]&&6==e.length?e.substr(0,4)+"-"+e.substr(4):e},toICAL:function(e){return 10==e.length?v.date.toICAL(e):"-"==e[0]&&7==e.length?e.substr(0,4)+e.substr(5):e}},time:{decorate:function(e){return t.VCardTime.fromDateAndOrTimeString("T"+e,"time")},undecorate:function(e){return e.toString()},fromICAL:function(e){var t=b.time._splitZone(e,!0),n=t[0],r=t[1];return 6==r.length?r=r.substr(0,2)+":"+r.substr(2,2)+":"+r.substr(4,2):4==r.length&&"-"!=r[0]?r=r.substr(0,2)+":"+r.substr(2,2):5==r.length&&(r=r.substr(0,3)+":"+r.substr(3,2)),5!=n.length||"-"!=n[0]&&"+"!=n[0]||(n=n.substr(0,3)+":"+n.substr(3)),r+n},toICAL:function(e){var t=b.time._splitZone(e),n=t[0],r=t[1];return 8==r.length?r=r.substr(0,2)+r.substr(3,2)+r.substr(6,2):5==r.length&&"-"!=r[0]?r=r.substr(0,2)+r.substr(3,2):6==r.length&&(r=r.substr(0,3)+r.substr(4,2)),6!=n.length||"-"!=n[0]&&"+"!=n[0]||(n=n.substr(0,3)+n.substr(4)),r+n},_splitZone:function(e,t){var n,r,i=e.length-1,s=e.length-(t?5:6),o=e[s];return"Z"==e[i]?(n=e[i],r=e.substr(0,i)):e.length>6&&("-"==o||"+"==o)?(n=e.substr(s),r=e.substr(0,s)):(n="",r=e),[n,r]}},"date-time":{decorate:function(e){return t.VCardTime.fromDateAndOrTimeString(e,"date-time")},undecorate:function(e){return e.toString()},fromICAL:function(e){return b["date-and-or-time"].fromICAL(e)},toICAL:function(e){return b["date-and-or-time"].toICAL(e)}},"date-and-or-time":{decorate:function(e){return t.VCardTime.fromDateAndOrTimeString(e,"date-and-or-time")},undecorate:function(e){return e.toString()},fromICAL:function(e){var t=e.split("T");return(t[0]?b.date.fromICAL(t[0]):"")+(t[1]?"T"+b.time.fromICAL(t[1]):"")},toICAL:function(e){var t=e.split("T");return b.date.toICAL(t[0])+(t[1]?"T"+b.time.toICAL(t[1]):"")}},timestamp:v["date-time"],"language-tag":{matches:/^[a-zA-Z0-9-]+$/}}),D=t.helpers.extend(g,{adr:{defaultType:"text",structuredValue:";",multiValue:","},anniversary:f,bday:f,caladruri:u,caluri:u,clientpidmap:o,email:i,fburl:u,fn:i,gender:o,geo:u,impp:u,key:u,kind:i,lang:{defaultType:"language-tag"},logo:u,member:u,n:{defaultType:"text",structuredValue:";",multiValue:","},nickname:s,note:i,org:{defaultType:"text",structuredValue:";"},photo:u,related:u,rev:{defaultType:"timestamp"},role:i,sound:u,source:u,tel:{defaultType:"uri",allowedTypes:["uri","text"]},title:i,tz:{defaultType:"text",allowedTypes:["text","utc-offset","uri"]},xml:i}),A=t.helpers.extend(m,{binary:v.binary,date:b.date,"date-time":b["date-time"],"phone-number":{},uri:v.uri,text:v.text,time:v.time,vcard:v.text,"utc-offset":{toICAL:function(e){return e.substr(0,7)},fromICAL:function(e){return e.substr(0,7)},decorate:function(e){return t.UtcOffset.fromString(e)},undecorate:function(e){return e.toString()}}}),E=t.helpers.extend(g,{fn:i,n:{defaultType:"text",structuredValue:";",multiValue:","},nickname:s,photo:{defaultType:"binary",allowedTypes:["binary","uri"]},bday:{defaultType:"date-time",allowedTypes:["date-time","date"],detectType:function(e){return-1===e.indexOf("T")?"date":"date-time"}},adr:{defaultType:"text",structuredValue:";",multiValue:","},label:i,tel:{defaultType:"phone-number"},email:i,mailer:i,tz:{defaultType:"utc-offset",allowedTypes:["utc-offset","text"]},geo:{defaultType:"float",structuredValue:";"},title:i,role:i,logo:{defaultType:"binary",allowedTypes:["binary","uri"]},agent:{defaultType:"vcard",allowedTypes:["vcard","text","uri"]},org:o,note:s,prodid:i,rev:{defaultType:"date-time",allowedTypes:["date-time","date"],detectType:function(e){return-1===e.indexOf("T")?"date":"date-time"}},"sort-string":i,sound:{defaultType:"binary",allowedTypes:["binary","uri"]},class:i,key:{defaultType:"binary",allowedTypes:["binary","text"]}}),_={value:v,param:{cutype:{values:["INDIVIDUAL","GROUP","RESOURCE","ROOM","UNKNOWN"],allowXName:!0,allowIanaToken:!0},"delegated-from":{valueType:"cal-address",multiValue:",",multiValueSeparateDQuote:!0},"delegated-to":{valueType:"cal-address",multiValue:",",multiValueSeparateDQuote:!0},encoding:{values:["8BIT","BASE64"]},fbtype:{values:["FREE","BUSY","BUSY-UNAVAILABLE","BUSY-TENTATIVE"],allowXName:!0,allowIanaToken:!0},member:{valueType:"cal-address",multiValue:",",multiValueSeparateDQuote:!0},partstat:{values:["NEEDS-ACTION","ACCEPTED","DECLINED","TENTATIVE","DELEGATED","COMPLETED","IN-PROCESS"],allowXName:!0,allowIanaToken:!0},range:{values:["THISANDFUTURE"]},related:{values:["START","END"]},reltype:{values:["PARENT","CHILD","SIBLING"],allowXName:!0,allowIanaToken:!0},role:{values:["REQ-PARTICIPANT","CHAIR","OPT-PARTICIPANT","NON-PARTICIPANT"],allowXName:!0,allowIanaToken:!0},rsvp:{values:["TRUE","FALSE"]},"sent-by":{valueType:"cal-address"},tzid:{matches:/^\//},value:{values:["binary","boolean","cal-address","date","date-time","duration","float","integer","period","recur","text","time","uri","utc-offset"],allowXName:!0,allowIanaToken:!0}},property:y},S={value:b,param:{type:{valueType:"text",multiValue:","},value:{values:["text","uri","date","time","date-time","date-and-or-time","timestamp","boolean","integer","float","utc-offset","language-tag"],allowXName:!0,allowIanaToken:!0}},property:D},T={value:A,param:{type:{valueType:"text",multiValue:","},value:{values:["text","uri","date","date-time","phone-number","time","boolean","integer","float","utc-offset","vcard","binary"],allowXName:!0,allowIanaToken:!0}},property:E},w={strict:!0,defaultSet:_,defaultType:"unknown",components:{vcard:S,vcard3:T,vevent:_,vtodo:_,vjournal:_,valarm:_,vtimezone:_,daylight:_,standard:_},icalendar:_,vcard:S,vcard3:T,getDesignSet:function(e){return e&&e in w.components?w.components[e]:w.defaultSet}};return w}(),t.stringify=function(){"use strict";var e="\r\n",n="unknown",r=t.design,i=t.helpers;function s(t){"string"==typeof t[0]&&(t=[t]);for(var n=0,r=t.length,i="";n0&&("version"!==t[1][0][0]||"4.0"!==t[1][0][3])&&(u="vcard3"),n=n||r.getDesignSet(u);l1)throw new i("invalid ical body. component began but did not end");return t=null,1==n.length?n[0]:n}i.prototype=Error.prototype,s.property=function(e,t){var r={component:[[],[]],designSet:t||n.defaultSet};return s._handleContentLine(e,r),r.component[1][0]},s.component=function(e){return s(e)},s.ParserError=i,s._handleContentLine=function(e,t){var r,o,a,l,c,u,d=e.indexOf(":"),h=e.indexOf(";"),f={};if(-1!==h&&-1!==d&&h>d&&(h=-1),-1!==h){if(a=e.substring(0,h).toLowerCase(),-1==(c=s._parseParameters(e.substring(h),0,t.designSet))[2])throw new i("Invalid parameters in '"+e+"'");if(f=c[0],r=c[1].length+c[2]+h,-1===(o=e.substring(r).indexOf(":")))throw new i("Missing parameter value in '"+e+"'");l=e.substring(r+o+1)}else{if(-1===d)throw new i('invalid line (no token ";" or ":") "'+e+'"');if(a=e.substring(0,d).toLowerCase(),l=e.substring(d+1),"begin"===a){var p=[l.toLowerCase(),[],[]];return 1===t.stack.length?t.component.push(p):t.component[2].push(p),t.stack.push(t.component),t.component=p,void(t.designSet||(t.designSet=n.getDesignSet(t.component[0])))}if("end"===a)return void(t.component=t.stack.pop())}var g,m,v=!1,y=!1;a in t.designSet.property&&("multiValue"in(g=t.designSet.property[a])&&(v=g.multiValue),"structuredValue"in g&&(y=g.structuredValue),l&&"detectType"in g&&(u=g.detectType(l))),u||(u="value"in f?f.value.toLowerCase():g?g.defaultType:"unknown"),delete f.value,v&&y?m=[a,f,u,l=s._parseMultiValue(l,y,u,[],v,t.designSet,y)]:v?(m=[a,f,u],s._parseMultiValue(l,v,u,m,null,t.designSet,!1)):m=y?[a,f,u,l=s._parseMultiValue(l,y,u,[],null,t.designSet,y)]:[a,f,u,l=s._parseValue(l,u,t.designSet,!1)],"vcard"!==t.component[0]||0!==t.component[1].length||"version"===a&&"4.0"===l||(t.designSet=n.getDesignSet("vcard3")),t.component[1].push(m)},s._parseValue=function(e,t,n,r){return t in n.value&&"fromICAL"in n.value[t]?n.value[t].fromICAL(e,r):e},s._parseParameters=function(e,t,n){for(var o,a,l,c,u,d,h=t,f=0,p={},g=-1;!1!==f&&-1!==(f=r.unescapedIndexOf(e,"=",f+1));){if(0==(o=e.substr(h+1,f-h-1)).length)throw new i("Empty parameter name in '"+e+"'");if(d=!1,u=!1,c=(a=o.toLowerCase())in n.param&&n.param[a].valueType?n.param[a].valueType:"text",a in n.param&&(u=n.param[a].multiValue,n.param[a].multiValueSeparateDQuote&&(d=s._rfc6868Escape('"'+u+'"'))),'"'===e[f+1]){if(g=f+2,f=r.unescapedIndexOf(e,'"',g),u&&-1!=f)for(var m=!0;m;)e[f+1]==u&&'"'==e[f+2]?f=r.unescapedIndexOf(e,'"',f+3):m=!1;if(-1===f)throw new i('invalid line (no matching double quote) "'+e+'"');l=e.substr(g,f-g),-1===(h=r.unescapedIndexOf(e,";",f))&&(f=!1)}else{g=f+1;var v=r.unescapedIndexOf(e,";",g),y=r.unescapedIndexOf(e,":",g);-1!==y&&v>y?(v=y,f=!1):-1===v?(v=-1===y?e.length:y,f=!1):(h=v,f=v),l=e.substr(g,v-g)}if(l=s._rfc6868Escape(l),u){var b=d||u;l=s._parseMultiValue(l,b,c,[],null,n)}else l=s._parseValue(l,c,n);u&&a in p?Array.isArray(p[a])?p[a].push(l):p[a]=[p[a],l]:p[a]=l}return[p,l,g]},s._rfc6868Escape=function(e){return e.replace(/\^['n^]/g,(function(e){return o[e]}))};var o={"^'":'"',"^n":"\n","^^":"^"};return s._parseMultiValue=function(e,t,n,i,o,a,l){var c,u=0,d=0;if(0===t.length)return e;for(;-1!==(u=r.unescapedIndexOf(e,t,d));)c=e.substr(d,u-d),c=o?s._parseMultiValue(c,o,n,[],null,a,l):s._parseValue(c,n,a,l),i.push(c),d=u+t.length;return c=e.substr(d),c=o?s._parseMultiValue(c,o,n,[],null,a,l):s._parseValue(c,n,a,l),i.push(c),1==i.length?i[0]:i},s._eachLine=function(t,n){var r,i,s,o=t.length,a=t.search(e),l=a;do{s=(l=t.indexOf("\n",a)+1)>1&&"\r"===t[l-2]?2:1,0===l&&(l=o,s=0)," "===(i=t[a])||"\t"===i?r+=t.substr(a+1,l-a-(s+1)):(r&&n(null,r),r=t.substr(a,l-a-s)),a=l}while(l!==o);(r=r.trim()).length&&n(null,r)},s}(),t.Component=function(){"use strict";function e(e,t){"string"==typeof e&&(e=[e,[],[]]),this.jCal=e,this.parent=t||null}return e.prototype={_hydratedPropertyCount:0,_hydratedComponentCount:0,get name(){return this.jCal[0]},get _designSet(){return this.parent&&this.parent._designSet||t.design.getDesignSet(this.name)},_hydrateComponent:function(t){if(this._components||(this._components=[],this._hydratedComponentCount=0),this._components[t])return this._components[t];var n=new e(this.jCal[2][t],this);return this._hydratedComponentCount++,this._components[t]=n},_hydrateProperty:function(e){if(this._properties||(this._properties=[],this._hydratedPropertyCount=0),this._properties[e])return this._properties[e];var n=new t.Property(this.jCal[1][e],this);return this._hydratedPropertyCount++,this._properties[e]=n},getFirstSubcomponent:function(e){if(e)for(var t=0,n=this.jCal[2],r=n.length;t=0;s--)n&&i[s][0]!==n||this._removeObjectByIndex(e,r,s)},addSubcomponent:function(e){this._components||(this._components=[],this._hydratedComponentCount=0),e.parent&&e.parent.removeSubcomponent(e);var t=this.jCal[2].push(e.jCal);return this._components[t-1]=e,this._hydratedComponentCount++,e.parent=this,e},removeSubcomponent:function(e){var t=this._removeObject(2,"_components",e);return t&&this._hydratedComponentCount--,t},removeAllSubcomponents:function(e){var t=this._removeAllObjects(2,"_components",e);return this._hydratedComponentCount=0,t},addProperty:function(e){if(!(e instanceof t.Property))throw new TypeError("must instance of ICAL.Property");this._properties||(this._properties=[],this._hydratedPropertyCount=0),e.parent&&e.parent.removeProperty(e);var n=this.jCal[1].push(e.jCal);return this._properties[n-1]=e,this._hydratedPropertyCount++,e.parent=this,e},addPropertyWithValue:function(e,n){var r=new t.Property(e);return r.setValue(n),this.addProperty(r),r},updatePropertyWithValue:function(e,t){var n=this.getFirstProperty(e);return n?n.setValue(t):n=this.addPropertyWithValue(e,t),n},removeProperty:function(e){var t=this._removeObject(1,"_properties",e);return t&&this._hydratedPropertyCount--,t},removeAllProperties:function(e){var t=this._removeAllObjects(1,"_properties",e);return this._hydratedPropertyCount=0,t},toJSON:function(){return this.jCal},toString:function(){return t.stringify.component(this.jCal,this._designSet)}},e.fromString=function(n){return new e(t.parse.component(n))},e}(),t.Property=function(){"use strict";var e=t.design;function n(t,n){this._parent=n||null,"string"==typeof t?(this.jCal=[t,{},e.defaultType],this.jCal[2]=this.getDefaultType()):this.jCal=t,this._updateType()}return n.prototype={get type(){return this.jCal[2]},get name(){return this.jCal[0]},get parent(){return this._parent},set parent(t){var n=!this._parent||t&&t._designSet!=this._parent._designSet;return this._parent=t,this.type==e.defaultType&&n&&(this.jCal[2]=this.getDefaultType(),this._updateType()),t},get _designSet(){return this.parent?this.parent._designSet:e.defaultSet},_updateType:function(){var e=this._designSet;if(this.type in e.value){e.value[this.type];"decorate"in e.value[this.type]?this.isDecorated=!0:this.isDecorated=!1,this.name in e.property&&(this.isMultiValue="multiValue"in e.property[this.name],this.isStructuredValue="structuredValue"in e.property[this.name])}},_hydrateValue:function(e){return this._values&&this._values[e]?this._values[e]:this.jCal.length<=3+e?null:this.isDecorated?(this._values||(this._values=[]),this._values[e]=this._decorate(this.jCal[3+e])):this.jCal[3+e]},_decorate:function(e){return this._designSet.value[this.type].decorate(e,this)},_undecorate:function(e){return this._designSet.value[this.type].undecorate(e,this)},_setDecoratedValue:function(e,t){this._values||(this._values=[]),"object"==typeof e&&"icaltype"in e?(this.jCal[3+t]=this._undecorate(e),this._values[t]=e):(this.jCal[3+t]=e,this._values[t]=this._decorate(e))},getParameter:function(e){return e in this.jCal[1]?this.jCal[1][e]:void 0},getFirstParameter:function(e){var t=this.getParameter(e);return Array.isArray(t)?t[0]:t},setParameter:function(e,t){var n=e.toLowerCase();"string"==typeof t&&n in this._designSet.param&&"multiValue"in this._designSet.param[n]&&(t=[t]),this.jCal[1][e]=t},removeParameter:function(e){delete this.jCal[1][e]},getDefaultType:function(){var t=this.jCal[0],n=this._designSet;if(t in n.property){var r=n.property[t];if("defaultType"in r)return r.defaultType}return e.defaultType},resetType:function(e){this.removeAllValues(),this.jCal[2]=e,this._updateType()},getFirstValue:function(){return this._hydrateValue(0)},getValues:function(){var e=this.jCal.length-3;if(e<1)return[];for(var t=0,n=[];t0&&"object"==typeof e[0]&&"icaltype"in e[0]&&this.resetType(e[0].icaltype),this.isDecorated)for(;nn)-(n>t)},_normalize:function(){for(var e=this.toSeconds(),t=this.factor;e<-43200;)e+=97200;for(;e>50400;)e-=97200;this.fromSeconds(e),0==e&&(this.factor=t)},toICALString:function(){return t.design.icalendar.value["utc-offset"].toICAL(this.toString())},toString:function(){return(1==this.factor?"+":"-")+t.helpers.pad2(this.hours)+":"+t.helpers.pad2(this.minutes)}},e.fromString=function(e){var n={};return n.factor="+"===e[0]?1:-1,n.hours=t.helpers.strictParseInt(e.substr(1,2)),n.minutes=t.helpers.strictParseInt(e.substr(4,2)),new t.UtcOffset(n)},e.fromSeconds=function(t){var n=new e;return n.fromSeconds(t),n},e}(),t.Binary=function(){function e(e){this.value=e}return e.prototype={icaltype:"binary",decodeValue:function(){return this._b64_decode(this.value)},setEncodedValue:function(e){this.value=this._b64_encode(e)},_b64_encode:function(e){var t,n,r,i,s,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",a=0,l=0,c="",u=[];if(!e)return e;do{t=(s=e.charCodeAt(a++)<<16|e.charCodeAt(a++)<<8|e.charCodeAt(a++))>>18&63,n=s>>12&63,r=s>>6&63,i=63&s,u[l++]=o.charAt(t)+o.charAt(n)+o.charAt(r)+o.charAt(i)}while(a>16&255,n=o>>8&255,r=255&o,u[c++]=64==i?String.fromCharCode(t):64==s?String.fromCharCode(t,n):String.fromCharCode(t,n,r)}while(ln)-(t=0?i=r:s=-1,-1==s&&-1!=i)break;if((r+=s)<0)return 0;if(r>=this.changes.length)break}var a=this.changes[i];if(a.utcOffset-a.prevUtcOffset<0&&i>0){var l=t.helpers.clone(a,!0);if(t.Timezone.adjust_change(l,0,0,0,l.prevUtcOffset),t.Timezone._compare_change_fn(n,l)<0){var c=this.changes[i-1],u=!1;a.is_daylight!=u&&c.is_daylight==u&&(a=c)}}return a.utcOffset},_findNearbyChange:function(e){var n=t.helpers.binsearchInsert(this.changes,e,t.Timezone._compare_change_fn);return n>=this.changes.length?this.changes.length-1:n},_ensureCoverage:function(e){if(-1==t.Timezone._minimumExpansionYear){var n=t.Time.now();t.Timezone._minimumExpansionYear=n.year}var r=e;if(rt.Timezone.MAX_YEAR&&(r=t.Timezone.MAX_YEAR),!this.changes.length||this.expandedUntilYearn)&&h);)i.year=h.year,i.month=h.month,i.day=h.day,i.hour=h.hour,i.minute=h.minute,i.second=h.second,i.isDate=h.isDate,t.Timezone.adjust_change(i,0,0,0,-i.prevUtcOffset),r.push(i)}}else(i=a()).year=s.year,i.month=s.month,i.day=s.day,i.hour=s.hour,i.minute=s.minute,i.second=s.second,t.Timezone.adjust_change(i,0,0,0,-i.prevUtcOffset),r.push(i);return r},toString:function(){return this.tznames?this.tznames:this.tzid}},t.Timezone._compare_change_fn=function(e,t){return e.yeart.year?1:e.montht.month?1:e.dayt.day?1:e.hourt.hour?1:e.minutet.minute?1:e.secondt.second?1:0},t.Timezone.convert_time=function(e,n,r){if(e.isDate||n.tzid==r.tzid||n==t.Timezone.localTimezone||r==t.Timezone.localTimezone)return e.zone=r,e;var i=n.utcOffset(e);return e.adjust(0,0,0,-i),i=r.utcOffset(e),e.adjust(0,0,0,i),null},t.Timezone.fromData=function(e){return(new t.Timezone).fromData(e)},t.Timezone.utcTimezone=t.Timezone.fromData({tzid:"UTC"}),t.Timezone.localTimezone=t.Timezone.fromData({tzid:"floating"}),t.Timezone.adjust_change=function(e,n,r,i,s){return t.Time.prototype.adjust.call(e,n,r,i,s,e)},t.Timezone._minimumExpansionYear=-1,t.Timezone.MAX_YEAR=2035,t.Timezone.EXTRA_COVERAGE=5,t.TimezoneService=((i={get count(){return Object.keys(r).length},reset:function(){r=Object.create(null);var e=t.Timezone.utcTimezone;r.Z=e,r.UTC=e,r.GMT=e},has:function(e){return!!r[e]},get:function(e){return r[e]},register:function(e,n){if(e instanceof t.Component&&"vtimezone"===e.name&&(e=(n=new t.Timezone(e)).tzid),!(n instanceof t.Timezone))throw new TypeError("timezone must be ICAL.Timezone or ICAL.Component");r[e]=n},remove:function(e){return delete r[e]}}).reset(),i),t.Time=function(e,t){this.wrappedJSObject=this;var n=this._time=Object.create(null);n.year=0,n.month=1,n.day=1,n.hour=0,n.minute=0,n.second=0,n.isDate=!1,this.fromData(e,t)},t.Time._dowCache={},t.Time._wnCache={},t.Time.prototype={icalclass:"icaltime",_cachedUnixTime:null,get icaltype(){return this.isDate?"date":"date-time"},zone:null,_pendingNormalization:!1,clone:function(){return new t.Time(this._time,this.zone)},reset:function(){this.fromData(t.Time.epochTime),this.zone=t.Timezone.utcTimezone},resetTo:function(e,t,n,r,i,s,o){this.fromData({year:e,month:t,day:n,hour:r,minute:i,second:s,zone:o})},fromJSDate:function(e,n){return e?n?(this.zone=t.Timezone.utcTimezone,this.year=e.getUTCFullYear(),this.month=e.getUTCMonth()+1,this.day=e.getUTCDate(),this.hour=e.getUTCHours(),this.minute=e.getUTCMinutes(),this.second=e.getUTCSeconds()):(this.zone=t.Timezone.localTimezone,this.year=e.getFullYear(),this.month=e.getMonth()+1,this.day=e.getDate(),this.hour=e.getHours(),this.minute=e.getMinutes(),this.second=e.getSeconds()):this.reset(),this._cachedUnixTime=null,this},fromData:function(e,n){if(e)for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){if("icaltype"===r)continue;this[r]=e[r]}if(n&&(this.zone=n),e&&!("isDate"in e)?this.isDate=!("hour"in e):e&&"isDate"in e&&(this.isDate=e.isDate),e&&"timezone"in e){var i=t.TimezoneService.get(e.timezone);this.zone=i||t.Timezone.localTimezone}return e&&"zone"in e&&(this.zone=e.zone),this.zone||(this.zone=t.Timezone.localTimezone),this._cachedUnixTime=null,this},dayOfWeek:function(e){var n=e||t.Time.SUNDAY,r=(this.year<<12)+(this.month<<8)+(this.day<<3)+n;if(r in t.Time._dowCache)return t.Time._dowCache[r];var i=this.day,s=this.month+(this.month<3?12:0),o=this.year-(this.month<3?1:0),a=i+o+t.helpers.trunc(26*(s+1)/10)+t.helpers.trunc(o/4);return a=((a+=6*t.helpers.trunc(o/100)+t.helpers.trunc(o/400))+7-n)%7+1,t.Time._dowCache[r]=a,a},dayOfYear:function(){var e=t.Time.isLeapYear(this.year)?1:0;return t.Time.daysInYearPassedMonth[e][this.month-1]+this.day},startOfWeek:function(e){var n=e||t.Time.SUNDAY,r=this.clone();return r.day-=(this.dayOfWeek()+7-n)%7,r.isDate=!0,r.hour=0,r.minute=0,r.second=0,r},endOfWeek:function(e){var n=e||t.Time.SUNDAY,r=this.clone();return r.day+=(7-this.dayOfWeek()+n-t.Time.SUNDAY)%7,r.isDate=!0,r.hour=0,r.minute=0,r.second=0,r},startOfMonth:function(){var e=this.clone();return e.day=1,e.isDate=!0,e.hour=0,e.minute=0,e.second=0,e},endOfMonth:function(){var e=this.clone();return e.day=t.Time.daysInMonth(e.month,e.year),e.isDate=!0,e.hour=0,e.minute=0,e.second=0,e},startOfYear:function(){var e=this.clone();return e.day=1,e.month=1,e.isDate=!0,e.hour=0,e.minute=0,e.second=0,e},endOfYear:function(){var e=this.clone();return e.day=31,e.month=12,e.isDate=!0,e.hour=0,e.minute=0,e.second=0,e},startDoyWeek:function(e){var n=e||t.Time.SUNDAY,r=this.dayOfWeek()-n;return r<0&&(r+=7),this.dayOfYear()-r},getDominicalLetter:function(){return t.Time.getDominicalLetter(this.year)},nthWeekDay:function(e,n){var r,i=t.Time.daysInMonth(this.month,this.year),s=n,o=0,a=this.clone();if(s>=0){a.day=1,0!=s&&s--,o=a.day;var l=e-a.dayOfWeek();l<0&&(l+=7),o+=l,o-=e,r=e}else a.day=i,s++,(r=a.dayOfWeek()-e)<0&&(r+=7),r=i-r;return o+(r+=7*s)},isNthWeekDay:function(e,t){var n=this.dayOfWeek();return 0===t&&n===e||this.nthWeekDay(e,t)===this.day},weekNumber:function(e){var n,r=(this.year<<12)+(this.month<<8)+(this.day<<3)+e;if(r in t.Time._wnCache)return t.Time._wnCache[r];var i=this.clone();i.isDate=!0;var s=this.year;12==i.month&&i.day>25?(n=t.Time.weekOneStarts(s+1,e),i.compare(n)<0?n=t.Time.weekOneStarts(s,e):s++):(n=t.Time.weekOneStarts(s,e),i.compare(n)<0&&(n=t.Time.weekOneStarts(--s,e)));var o=i.subtractDate(n).toSeconds()/86400,a=t.helpers.trunc(o/7)+1;return t.Time._wnCache[r]=a,a},addDuration:function(e){var t=e.isNegative?-1:1,n=this.second,r=this.minute,i=this.hour,s=this.day;n+=t*e.seconds,r+=t*e.minutes,i+=t*e.hours,s+=t*e.days,s+=7*t*e.weeks,this.second=n,this.minute=r,this.hour=i,this.day=s,this._cachedUnixTime=null},subtractDate:function(e){var n=this.toUnixTime()+this.utcOffset(),r=e.toUnixTime()+e.utcOffset();return t.Duration.fromSeconds(n-r)},subtractDateTz:function(e){var n=this.toUnixTime(),r=e.toUnixTime();return t.Duration.fromSeconds(n-r)},compare:function(e){var t=this.toUnixTime(),n=e.toUnixTime();return t>n?1:n>t?-1:0},compareDateOnlyTz:function(e,n){function r(e){return t.Time._cmp_attr(i,s,e)}var i=this.convertToZone(n),s=e.convertToZone(n),o=0;return 0!=(o=r("year"))||0!=(o=r("month"))||(o=r("day")),o},convertToZone:function(e){var n=this.clone(),r=this.zone.tzid==e.tzid;return this.isDate||r||t.Timezone.convert_time(n,this.zone,e),n.zone=e,n},utcOffset:function(){return this.zone==t.Timezone.localTimezone||this.zone==t.Timezone.utcTimezone?0:this.zone.utcOffset(this)},toICALString:function(){var e=this.toString();return e.length>10?t.design.icalendar.value["date-time"].toICAL(e):t.design.icalendar.value.date.toICAL(e)},toString:function(){var e=this.year+"-"+t.helpers.pad2(this.month)+"-"+t.helpers.pad2(this.day);return this.isDate||(e+="T"+t.helpers.pad2(this.hour)+":"+t.helpers.pad2(this.minute)+":"+t.helpers.pad2(this.second),this.zone===t.Timezone.utcTimezone&&(e+="Z")),e},toJSDate:function(){return this.zone==t.Timezone.localTimezone?this.isDate?new Date(this.year,this.month-1,this.day):new Date(this.year,this.month-1,this.day,this.hour,this.minute,this.second,0):new Date(1e3*this.toUnixTime())},_normalize:function(){return this._time.isDate,this._time.isDate&&(this._time.hour=0,this._time.minute=0,this._time.second=0),this.adjust(0,0,0,0),this},adjust:function(e,n,r,i,s){var o,a,l,c,u,d,h,f=0,p=0,g=s||this._time;if(g.isDate||(l=g.second+i,g.second=l%60,o=t.helpers.trunc(l/60),g.second<0&&(g.second+=60,o--),c=g.minute+r+o,g.minute=c%60,a=t.helpers.trunc(c/60),g.minute<0&&(g.minute+=60,a--),u=g.hour+n+a,g.hour=u%24,f=t.helpers.trunc(u/24),g.hour<0&&(g.hour+=24,f--)),g.month>12?p=t.helpers.trunc((g.month-1)/12):g.month<1&&(p=t.helpers.trunc(g.month/12)-1),g.year+=p,g.month-=12*p,(d=g.day+e+f)>0)for(;!(d<=(h=t.Time.daysInMonth(g.month,g.year)));)g.month++,g.month>12&&(g.year++,g.month=1),d-=h;else for(;d<=0;)1==g.month?(g.year--,g.month=12):g.month--,d+=t.Time.daysInMonth(g.month,g.year);return g.day=d,this._cachedUnixTime=null,this},fromUnixTime:function(e){this.zone=t.Timezone.utcTimezone;var n=t.Time.epochTime.clone();n.adjust(0,0,0,e),this.year=n.year,this.month=n.month,this.day=n.day,this.hour=n.hour,this.minute=n.minute,this.second=Math.floor(n.second),this._cachedUnixTime=null},toUnixTime:function(){if(null!==this._cachedUnixTime)return this._cachedUnixTime;var e=this.utcOffset(),t=Date.UTC(this.year,this.month-1,this.day,this.hour,this.minute,this.second-e);return this._cachedUnixTime=t/1e3,this._cachedUnixTime},toJSON:function(){for(var e,t=["year","month","day","hour","minute","second","isDate"],n=Object.create(null),r=0,i=t.length;r12||(r=[0,31,28,31,30,31,30,31,31,30,31,30,31][e],2==e&&(r+=t.Time.isLeapYear(n))),r},t.Time.isLeapYear=function(e){return e<=1752?e%4==0:e%4==0&&e%100!=0||e%400==0},t.Time.fromDayOfYear=function(e,n){var r=n,i=e,s=new t.Time;s.auto_normalize=!1;var o=t.Time.isLeapYear(r)?1:0;if(i<1)return r--,o=t.Time.isLeapYear(r)?1:0,i+=t.Time.daysInYearPassedMonth[o][12],t.Time.fromDayOfYear(i,r);if(i>t.Time.daysInYearPassedMonth[o][12])return o=t.Time.isLeapYear(r)?1:0,i-=t.Time.daysInYearPassedMonth[o][12],r++,t.Time.fromDayOfYear(i,r);s.year=r,s.isDate=!0;for(var a=11;a>=0;a--)if(i>t.Time.daysInYearPassedMonth[o][a]){s.month=a+1,s.day=i-t.Time.daysInYearPassedMonth[o][a];break}return s.auto_normalize=!0,s},t.Time.fromStringv2=function(e){return new t.Time({year:parseInt(e.substr(0,4),10),month:parseInt(e.substr(5,2),10),day:parseInt(e.substr(8,2),10),isDate:!0})},t.Time.fromDateString=function(e){return new t.Time({year:t.helpers.strictParseInt(e.substr(0,4)),month:t.helpers.strictParseInt(e.substr(5,2)),day:t.helpers.strictParseInt(e.substr(8,2)),isDate:!0})},t.Time.fromDateTimeString=function(e,n){if(e.length<19)throw new Error('invalid date-time value: "'+e+'"');var r;return e[19]&&"Z"===e[19]?r="Z":n&&(r=n.getParameter("tzid")),new t.Time({year:t.helpers.strictParseInt(e.substr(0,4)),month:t.helpers.strictParseInt(e.substr(5,2)),day:t.helpers.strictParseInt(e.substr(8,2)),hour:t.helpers.strictParseInt(e.substr(11,2)),minute:t.helpers.strictParseInt(e.substr(14,2)),second:t.helpers.strictParseInt(e.substr(17,2)),timezone:r})},t.Time.fromString=function(e,n){return e.length>10?t.Time.fromDateTimeString(e,n):t.Time.fromDateString(e)},t.Time.fromJSDate=function(e,n){return(new t.Time).fromJSDate(e,n)},t.Time.fromData=function(e,n){return(new t.Time).fromData(e,n)},t.Time.now=function(){return t.Time.fromJSDate(new Date,!1)},t.Time.weekOneStarts=function(e,n){var r=t.Time.fromData({year:e,month:1,day:1,isDate:!0}),i=r.dayOfWeek(),s=n||t.Time.DEFAULT_WEEK_START;return i>t.Time.THURSDAY&&(r.day+=7),s>t.Time.THURSDAY&&(r.day-=7),r.day-=i-s,r},t.Time.getDominicalLetter=function(e){var n="GFEDCBA",r=(e+(e/4|0)+(e/400|0)-(e/100|0)-1)%7;return t.Time.isLeapYear(e)?n[(r+6)%7]+n[r]:n[r]},t.Time.epochTime=t.Time.fromData({year:1970,month:1,day:1,hour:0,minute:0,second:0,isDate:!1,timezone:"Z"}),t.Time._cmp_attr=function(e,t,n){return e[n]>t[n]?1:e[n]4?r(c,f?1:3,2):null,second:4==d?r(c,2,2):6==d?r(c,4,2):8==d?r(c,6,2):null};return l="Z"==l?t.Timezone.utcTimezone:l&&":"==l[3]?t.UtcOffset.fromString(l):null,new t.VCardTime(p,l,n)},function(){var e={SU:t.Time.SUNDAY,MO:t.Time.MONDAY,TU:t.Time.TUESDAY,WE:t.Time.WEDNESDAY,TH:t.Time.THURSDAY,FR:t.Time.FRIDAY,SA:t.Time.SATURDAY},n={};for(var r in e)e.hasOwnProperty(r)&&(n[e[r]]=r);function i(e,n,r,i){var s=i;if("+"===i[0]&&(s=i.substr(1)),s=t.helpers.strictParseInt(s),void 0!==n&&i '+n);if(void 0!==r&&i>r)throw new Error(e+': invalid value "'+i+'" must be < '+n);return s}t.Recur=function(e){this.wrappedJSObject=this,this.parts={},e&&"object"==typeof e&&this.fromData(e)},t.Recur.prototype={parts:null,interval:1,wkst:t.Time.MONDAY,until:null,count:null,freq:null,icalclass:"icalrecur",icaltype:"recur",iterator:function(e){return new t.RecurIterator({rule:this,dtstart:e})},clone:function(){return new t.Recur(this.toJSON())},isFinite:function(){return!(!this.count&&!this.until)},isByCount:function(){return!(!this.count||this.until)},addComponent:function(e,t){var n=e.toUpperCase();n in this.parts?this.parts[n].push(t):this.parts[n]=[t]},setComponent:function(e,t){this.parts[e.toUpperCase()]=t.slice()},getComponent:function(e){var t=e.toUpperCase();return t in this.parts?this.parts[t].slice():[]},getNextOccurrence:function(e,t){var n,r=this.iterator(e);do{n=r.next()}while(n&&n.compare(t)<=0);return n&&t.zone&&(n.zone=t.zone),n},fromData:function(e){for(var n in e){var r=n.toUpperCase();r in c?Array.isArray(e[n])?this.parts[r]=e[n]:this.parts[r]=[e[n]]:this[n]=e[n]}this.interval&&"number"!=typeof this.interval&&l.INTERVAL(this.interval,this),this.wkst&&"number"!=typeof this.wkst&&(this.wkst=t.Recur.icalDayToNumericDay(this.wkst)),!this.until||this.until instanceof t.Time||(this.until=t.Time.fromString(this.until))},toJSON:function(){var e=Object.create(null);for(var n in e.freq=this.freq,this.count&&(e.count=this.count),this.interval>1&&(e.interval=this.interval),this.parts)if(this.parts.hasOwnProperty(n)){var r=this.parts[n];Array.isArray(r)&&1==r.length?e[n.toLowerCase()]=r[0]:e[n.toLowerCase()]=t.helpers.clone(this.parts[n])}return this.until&&(e.until=this.until.toString()),"wkst"in this&&this.wkst!==t.Time.DEFAULT_WEEK_START&&(e.wkst=t.Recur.numericDayToIcalDay(this.wkst)),e},toString:function(){var e="FREQ="+this.freq;for(var n in this.count&&(e+=";COUNT="+this.count),this.interval>1&&(e+=";INTERVAL="+this.interval),this.parts)this.parts.hasOwnProperty(n)&&(e+=";"+n+"="+this.parts[n]);return this.until&&(e+=";UNTIL="+this.until.toICALString()),"wkst"in this&&this.wkst!==t.Time.DEFAULT_WEEK_START&&(e+=";WKST="+t.Recur.numericDayToIcalDay(this.wkst)),e}},t.Recur.icalDayToNumericDay=function(n,r){var i=r||t.Time.SUNDAY;return(e[n]-i+7)%7+1},t.Recur.numericDayToIcalDay=function(e,r){var i=e+(r||t.Time.SUNDAY)-t.Time.SUNDAY;return i>7&&(i-=7),n[i]};var s=/^(SU|MO|TU|WE|TH|FR|SA)$/,o=/^([+-])?(5[0-3]|[1-4][0-9]|[1-9])?(SU|MO|TU|WE|TH|FR|SA)$/,a=["SECONDLY","MINUTELY","HOURLY","DAILY","WEEKLY","MONTHLY","YEARLY"],l={FREQ:function(e,t,n){if(-1===a.indexOf(e))throw new Error('invalid frequency "'+e+'" expected: "'+a.join(", ")+'"');t.freq=e},COUNT:function(e,n,r){n.count=t.helpers.strictParseInt(e)},INTERVAL:function(e,n,r){n.interval=t.helpers.strictParseInt(e),n.interval<1&&(n.interval=1)},UNTIL:function(e,n,r){e.length>10?n.until=t.design.icalendar.value["date-time"].fromICAL(e):n.until=t.design.icalendar.value.date.fromICAL(e),r||(n.until=t.Time.fromString(n.until))},WKST:function(e,n,r){if(!s.test(e))throw new Error('invalid WKST value "'+e+'"');n.wkst=t.Recur.icalDayToNumericDay(e)}},c={BYSECOND:i.bind(this,"BYSECOND",0,60),BYMINUTE:i.bind(this,"BYMINUTE",0,59),BYHOUR:i.bind(this,"BYHOUR",0,23),BYDAY:function(e){if(o.test(e))return e;throw new Error('invalid BYDAY value "'+e+'"')},BYMONTHDAY:i.bind(this,"BYMONTHDAY",-31,31),BYYEARDAY:i.bind(this,"BYYEARDAY",-366,366),BYWEEKNO:i.bind(this,"BYWEEKNO",-53,53),BYMONTH:i.bind(this,"BYMONTH",1,12),BYSETPOS:i.bind(this,"BYSETPOS",-366,366)};t.Recur.fromString=function(e){var n=t.Recur._stringToData(e,!1);return new t.Recur(n)},t.Recur.fromData=function(e){return new t.Recur(e)},t.Recur._stringToData=function(e,t){for(var n=Object.create(null),r=e.split(";"),i=r.length,s=0;s=0||r<0)&&(this.last.day+=r)}else{var i=t.Recur.numericDayToIcalDay(this.dtstart.dayOfWeek());e.BYDAY=[i]}if("YEARLY"==this.rule.freq){for(;this.expand_year_days(this.last.year),!(this.days.length>0);)this.increment_year(this.rule.interval);this._nextByYearDay()}if("MONTHLY"==this.rule.freq&&this.has_by_data("BYDAY")){var s=null,o=this.last.clone(),a=t.Time.daysInMonth(this.last.month,this.last.year);for(var l in this.by_data.BYDAY)if(this.by_data.BYDAY.hasOwnProperty(l)){this.last=o.clone();n=(c=this.ruleDayOfWeek(this.by_data.BYDAY[l]))[0];var c,u=c[1],d=this.last.nthWeekDay(u,n);if(n>=6||n<=-6)throw new Error("Malformed values in BYDAY part");if(d>a||d<=0){if(s&&s.month==o.month)continue;for(;d>a||d<=0;)this.increment_month(),a=t.Time.daysInMonth(this.last.month,this.last.year),d=this.last.nthWeekDay(u,n)}this.last.day=d,(!s||this.last.compare(s)<0)&&(s=this.last.clone())}if(this.last=s.clone(),this.has_by_data("BYMONTHDAY")&&this._byDayAndMonthDay(!0),this.last.day>a||0==this.last.day)throw new Error("Malformed values in BYDAY part")}else if(this.has_by_data("BYMONTHDAY")&&this.last.day<0){a=t.Time.daysInMonth(this.last.month,this.last.year);this.last.day=a+this.last.day+1}},next:function(){var e,t=this.last?this.last.clone():null;if(this.rule.count&&this.occurrence_number>=this.rule.count||this.rule.until&&this.last.compare(this.rule.until)>0)return this.completed=!0,null;if(0==this.occurrence_number&&this.last.compare(this.dtstart)>=0)return this.occurrence_number++,this.last;do{switch(e=1,this.rule.freq){case"SECONDLY":this.next_second();break;case"MINUTELY":this.next_minute();break;case"HOURLY":this.next_hour();break;case"DAILY":this.next_day();break;case"WEEKLY":this.next_week();break;case"MONTHLY":e=this.next_month();break;case"YEARLY":this.next_year();break;default:return null}}while(!this.check_contracting_rules()||this.last.compare(this.dtstart)<0||!e);if(0==this.last.compare(t))throw new Error("Same occurrence found twice, protecting you from death by recursion");return this.rule.until&&this.last.compare(this.rule.until)>0?(this.completed=!0,null):(this.occurrence_number++,this.last)},next_second:function(){return this.next_generic("BYSECOND","SECONDLY","second","minute")},increment_second:function(e){return this.increment_generic(e,"second",60,"minute")},next_minute:function(){return this.next_generic("BYMINUTE","MINUTELY","minute","hour","next_second")},increment_minute:function(e){return this.increment_generic(e,"minute",60,"hour")},next_hour:function(){return this.next_generic("BYHOUR","HOURLY","hour","monthday","next_minute")},increment_hour:function(e){this.increment_generic(e,"hour",24,"monthday")},next_day:function(){this.by_data;var e="DAILY"==this.rule.freq;return 0==this.next_hour()||(e?this.increment_monthday(this.rule.interval):this.increment_monthday(1)),0},next_week:function(){var e=0;if(0==this.next_weekday_by_week())return e;if(this.has_by_data("BYWEEKNO")){++this.by_indices.BYWEEKNO;this.by_indices.BYWEEKNO==this.by_data.BYWEEKNO.length&&(this.by_indices.BYWEEKNO=0,e=1),this.last.month=1,this.last.day=1;var t=this.by_data.BYWEEKNO[this.by_indices.BYWEEKNO];this.last.day+=7*t,e&&this.increment_year(1)}else this.increment_monthday(7*this.rule.interval);return e},normalizeByMonthDayRules:function(e,n,r){for(var i,s=t.Time.daysInMonth(n,e),o=[],a=0,l=r.length;as)){if(i<0)i=s+(i+1);else if(0===i)continue;-1===o.indexOf(i)&&o.push(i)}return o.sort((function(e,t){return e-t}))},_byDayAndMonthDay:function(e){var n,r,i,s,o=this.by_data.BYDAY,a=0,l=o.length,c=0,u=this,d=this.last.day;function h(){for(s=t.Time.daysInMonth(u.last.month,u.last.year),n=u.normalizeByMonthDayRules(u.last.year,u.last.month,u.by_data.BYMONTHDAY),i=n.length;n[a]<=d&&(!e||n[a]!=d)&&as)f();else{var g=n[a++];if(g>=r){d=g;for(var m=0;mn&&(this.last.day=1,this.increment_month(),this.is_day_in_byday(this.last)?this.has_by_data("BYSETPOS")&&!this.check_set_position(1)||(e=1):e=0)}else if(this.has_by_data("BYMONTHDAY")){this.by_indices.BYMONTHDAY++,this.by_indices.BYMONTHDAY>=this.by_data.BYMONTHDAY.length&&(this.by_indices.BYMONTHDAY=0,this.increment_month());n=t.Time.daysInMonth(this.last.month,this.last.year);(o=this.by_data.BYMONTHDAY[this.by_indices.BYMONTHDAY])<0&&(o=n+o+1),o>n?(this.last.day=1,e=this.is_day_in_byday(this.last)):this.last.day=o}else{this.increment_month();n=t.Time.daysInMonth(this.last.month,this.last.year);this.by_data.BYMONTHDAY[0]>n?e=0:this.last.day=this.by_data.BYMONTHDAY[0]}return e},next_weekday_by_week:function(){var e=0;if(0==this.next_hour())return e;if(!this.has_by_data("BYDAY"))return 1;for(;;){var n=new t.Time;this.by_indices.BYDAY++,this.by_indices.BYDAY==Object.keys(this.by_data.BYDAY).length&&(this.by_indices.BYDAY=0,e=1);var r=this.by_data.BYDAY[this.by_indices.BYDAY],i=this.ruleDayOfWeek(r)[1];(i-=this.rule.wkst)<0&&(i+=7),n.year=this.last.year,n.month=this.last.month,n.day=this.last.day;var s=n.startDoyWeek(this.rule.wkst);if(!(i+s<1)||e){var o=t.Time.fromDayOfYear(s+i,this.last.year);return this.last.year=o.year,this.last.month=o.month,this.last.day=o.day,e}}},next_year:function(){if(0==this.next_hour())return 0;if(++this.days_index==this.days.length){this.days_index=0;do{this.increment_year(this.rule.interval),this.expand_year_days(this.last.year)}while(0==this.days.length)}return this._nextByYearDay(),1},_nextByYearDay:function(){var e=this.days[this.days_index],n=this.last.year;e<1&&(e+=1,n+=1);var r=t.Time.fromDayOfYear(e,n);this.last.day=r.day,this.last.month=r.month},ruleDayOfWeek:function(e,n){var r=e.match(/([+-]?[0-9])?(MO|TU|WE|TH|FR|SA|SU)/);return r?[parseInt(r[1]||0,10),e=t.Recur.icalDayToNumericDay(r[2],n)]:[0,0]},next_generic:function(e,t,n,r,i){var s=e in this.by_data,o=this.rule.freq==t,a=0;if(i&&0==this[i]())return a;if(s){this.by_indices[e]++;this.by_indices[e];var l=this.by_data[e];this.by_indices[e]==l.length&&(this.by_indices[e]=0,a=1),this.last[n]=l[this.by_indices[e]]}else o&&this["increment_"+n](this.rule.interval);return s&&a&&o&&this["increment_"+r](1),a},increment_monthday:function(e){for(var n=0;nr&&(this.last.day-=r,this.increment_month())}},increment_month:function(){if(this.last.day=1,this.has_by_data("BYMONTH"))this.by_indices.BYMONTH++,this.by_indices.BYMONTH==this.by_data.BYMONTH.length&&(this.by_indices.BYMONTH=0,this.increment_year(1)),this.last.month=this.by_data.BYMONTH[this.by_indices.BYMONTH];else{"MONTHLY"==this.rule.freq?this.last.month+=this.rule.interval:this.last.month++,this.last.month--;var e=t.helpers.trunc(this.last.month/12);this.last.month%=12,this.last.month++,0!=e&&this.increment_year(e)}},increment_year:function(e){this.last.year+=e},increment_generic:function(e,n,r,i){this.last[n]+=e;var s=t.helpers.trunc(this.last[n]/r);this.last[n]%=r,0!=s&&this["increment_"+i](s)},has_by_data:function(e){return e in this.rule.parts},expand_year_days:function(e){var n=new t.Time;this.days=[];var r={},i=["BYDAY","BYWEEKNO","BYMONTHDAY","BYMONTH","BYYEARDAY"];for(var s in i)if(i.hasOwnProperty(s)){var o=i[s];o in this.rule.parts&&(r[o]=this.rule.parts[o])}if("BYMONTH"in r&&"BYWEEKNO"in r){var a=1,l={};n.year=e,n.isDate=!0;for(var c=0;c0?(O=P+7*(M-1))<=A&&this.days.push(S+O):(O=B+7*(M+1))>0&&this.days.push(S+O)}}this.days.sort((function(e,t){return e-t}))}else if(2==p&&"BYDAY"in r&&"BYMONTHDAY"in r){var z=this.expand_by_day(e);for(var H in z)if(z.hasOwnProperty(H)){C=z[H];var Y=t.Time.fromDayOfYear(C,e);this.by_data.BYMONTHDAY.indexOf(Y.day)>=0&&this.days.push(C)}}else if(3==p&&"BYDAY"in r&&"BYMONTHDAY"in r&&"BYMONTH"in r){z=this.expand_by_day(e);for(var H in z)if(z.hasOwnProperty(H)){C=z[H],Y=t.Time.fromDayOfYear(C,e);this.by_data.BYMONTH.indexOf(Y.month)>=0&&this.by_data.BYMONTHDAY.indexOf(Y.day)>=0&&this.days.push(C)}}else if(2==p&&"BYDAY"in r&&"BYWEEKNO"in r){z=this.expand_by_day(e);for(var H in z)if(z.hasOwnProperty(H)){C=z[H];var U=(Y=t.Time.fromDayOfYear(C,e)).weekNumber(this.rule.wkst);this.by_data.BYWEEKNO.indexOf(U)&&this.days.push(C)}}else 3==p&&"BYDAY"in r&&"BYWEEKNO"in r&&"BYMONTHDAY"in r||(this.days=1==p&&"BYYEARDAY"in r?this.days.concat(this.by_data.BYYEARDAY):[]);return 0},expand_by_day:function(e){var t=[],n=this.last.clone();n.year=e,n.month=1,n.day=1,n.isDate=!0;var r=n.dayOfWeek();n.month=12,n.day=31,n.isDate=!0;var i=n.dayOfWeek(),s=n.dayOfYear();for(var o in this.by_data.BYDAY)if(this.by_data.BYDAY.hasOwnProperty(o)){var a=this.by_data.BYDAY[o],l=this.ruleDayOfWeek(a),c=l[0],u=l[1];if(0==c)for(var d=(u+7-r)%7+1;d<=s;d+=7)t.push(d);else if(c>0){var h;h=u>=r?u-r+1:u-r+8,t.push(h+7*(c-1))}else{var f;c=-c,f=u<=i?s-i+u:s-i+u-7,t.push(f-7*(c-1))}}return t},is_day_in_byday:function(e){for(var t in this.by_data.BYDAY)if(this.by_data.BYDAY.hasOwnProperty(t)){var n=this.by_data.BYDAY[t],r=this.ruleDayOfWeek(n),i=r[0],s=r[1],o=e.dayOfWeek();if(0==i&&s==o||e.nthWeekDay(s,i)==e.day)return 1}return 0},check_set_position:function(e){return!!this.has_by_data("BYSETPOS")&&-1!==this.by_data.BYSETPOS.indexOf(e)},sort_byday_rules:function(e){for(var t=0;tthis.ruleDayOfWeek(e[t],this.rule.wkst)[1]){var r=e[t];e[t]=e[n],e[n]=r}}},check_contract_restriction:function(t,n){var r=e._indexMap[t],i=e._expandMap[this.rule.freq][r],s=!1;if(t in this.by_data&&i==e.CONTRACT){var o=this.by_data[t];for(var a in o)if(o.hasOwnProperty(a)&&o[a]==n){s=!0;break}}else s=!0;return s},check_contracting_rules:function(){var e=this.last.dayOfWeek(),n=this.last.weekNumber(this.rule.wkst),r=this.last.dayOfYear();return this.check_contract_restriction("BYSECOND",this.last.second)&&this.check_contract_restriction("BYMINUTE",this.last.minute)&&this.check_contract_restriction("BYHOUR",this.last.hour)&&this.check_contract_restriction("BYDAY",t.Recur.numericDayToIcalDay(e))&&this.check_contract_restriction("BYWEEKNO",n)&&this.check_contract_restriction("BYMONTHDAY",this.last.day)&&this.check_contract_restriction("BYMONTH",this.last.month)&&this.check_contract_restriction("BYYEARDAY",r)},setup_defaults:function(t,n,r){var i=e._indexMap[t];return e._expandMap[this.rule.freq][i]!=e.CONTRACT&&(t in this.by_data||(this.by_data[t]=[r]),this.rule.freq!=n)?this.by_data[t][0]:r},toJSON:function(){var e=Object.create(null);return e.initialized=this.initialized,e.rule=this.rule.toJSON(),e.dtstart=this.dtstart.toJSON(),e.by_data=this.by_data,e.days=this.days,e.last=this.last.toJSON(),e.by_indices=this.by_indices,e.occurrence_number=this.occurrence_number,e}},e._indexMap={BYSECOND:0,BYMINUTE:1,BYHOUR:2,BYDAY:3,BYMONTHDAY:4,BYYEARDAY:5,BYWEEKNO:6,BYMONTH:7,BYSETPOS:8},e._expandMap={SECONDLY:[1,1,1,1,1,1,1,1],MINUTELY:[2,1,1,1,1,1,1,1],HOURLY:[2,2,1,1,1,1,1,1],DAILY:[2,2,2,1,1,1,1,1],WEEKLY:[2,2,2,2,3,3,1,1],MONTHLY:[2,2,2,2,2,3,3,1],YEARLY:[2,2,2,2,2,2,2,2]},e.UNKNOWN=0,e.CONTRACT=1,e.EXPAND=2,e.ILLEGAL=3,e}(),t.RecurExpansion=function(){function e(e){return t.helpers.formatClassType(e,t.Time)}function n(e,t){return e.compare(t)}function r(e){this.ruleDates=[],this.exDates=[],this.fromData(e)}return r.prototype={complete:!1,ruleIterators:null,ruleDates:null,exDates:null,ruleDateInc:0,exDateInc:0,exDate:null,ruleDate:null,dtstart:null,last:null,fromData:function(n){var r=t.helpers.formatClassType(n.dtstart,t.Time);if(!r)throw new Error(".dtstart (ICAL.Time) must be given");if(this.dtstart=r,n.component)this._init(n.component);else{if(this.last=e(n.last)||r.clone(),!n.ruleIterators)throw new Error(".ruleIterators or .component must be given");this.ruleIterators=n.ruleIterators.map((function(e){return t.helpers.formatClassType(e,t.RecurIterator)})),this.ruleDateInc=n.ruleDateInc,this.exDateInc=n.exDateInc,n.ruleDates&&(this.ruleDates=n.ruleDates.map(e),this.ruleDate=this.ruleDates[this.ruleDateInc]),n.exDates&&(this.exDates=n.exDates.map(e),this.exDate=this.exDates[this.exDateInc]),void 0!==n.complete&&(this.complete=n.complete)}},next:function(){for(var e,t,n,r=0;;){if(r++>500)throw new Error("max tries have occured, rule may be impossible to forfill.");if(t=this.ruleDate,e=this._nextRecurrenceIter(this.last),!t&&!e){this.complete=!0;break}if((!t||e&&t.compare(e.last)>0)&&(t=e.last.clone(),e.next()),this.ruleDate===t&&this._nextRuleDay(),this.last=t,!this.exDate||((n=this.exDate.compare(this.last))<0&&this._nextExDay(),0!==n))return this.last;this._nextExDay()}},toJSON:function(){function e(e){return e.toJSON()}var t=Object.create(null);return t.ruleIterators=this.ruleIterators.map(e),this.ruleDates&&(t.ruleDates=this.ruleDates.map(e)),this.exDates&&(t.exDates=this.exDates.map(e)),t.ruleDateInc=this.ruleDateInc,t.exDateInc=this.exDateInc,t.last=this.last.toJSON(),t.dtstart=this.dtstart.toJSON(),t.complete=this.complete,t},_extractDates:function(e,r){function i(e){s=t.helpers.binsearchInsert(o,e,n),o.splice(s,0,e)}for(var s,o=[],a=e.getAllProperties(r),l=a.length,c=0;c0)&&(r=t);return r}},r}(),t.Event=function(){function e(e,n){e instanceof t.Component||(n=e,e=null),this.component=e||new t.Component("vevent"),this._rangeExceptionCache=Object.create(null),this.exceptions=Object.create(null),this.rangeExceptions=[],n&&n.strictExceptions&&(this.strictExceptions=n.strictExceptions),n&&n.exceptions?n.exceptions.forEach(this.relateException,this):this.component.parent&&!this.isRecurrenceException()&&this.component.parent.getAllSubcomponents("vevent").forEach((function(e){e.hasProperty("recurrence-id")&&this.relateException(e)}),this)}function n(e,t){return e[0]>t[0]?1:t[0]>e[0]?-1:0}return e.prototype={THISANDFUTURE:"THISANDFUTURE",exceptions:null,strictExceptions:!1,relateException:function(e){if(this.isRecurrenceException())throw new Error("cannot relate exception to exceptions");if(e instanceof t.Component&&(e=new t.Event(e)),this.strictExceptions&&e.uid!==this.uid)throw new Error("attempted to relate unrelated exception");var r=e.recurrenceId.toString();if(this.exceptions[r]=e,e.modifiesFuture()){var i=[e.recurrenceId.toUnixTime(),r],s=t.helpers.binsearchInsert(this.rangeExceptions,i,n);this.rangeExceptions.splice(s,0,i)}},modifiesFuture:function(){return!!this.component.hasProperty("recurrence-id")&&this.component.getFirstProperty("recurrence-id").getParameter("range")===this.THISANDFUTURE},findRangeException:function(e){if(!this.rangeExceptions.length)return null;var r=e.toUnixTime(),i=t.helpers.binsearchInsert(this.rangeExceptions,[r],n);if((i-=1)<0)return null;var s=this.rangeExceptions[i];return r{"use strict";n.d(t,{d5:()=>N});var r,i,s,o=n(50172),a=[],l=[],c=o.fF.__b,u=o.fF.__r,d=o.fF.diffed,h=o.fF.__c,f=o.fF.unmount;function p(){for(var e;e=a.shift();)if(e.__P&&e.__H)try{e.__H.__h.forEach(v),e.__H.__h.forEach(y),e.__H.__h=[]}catch(r){e.__H.__h=[],o.fF.__e(r,e.__v)}}o.fF.__b=function(e){r=null,c&&c(e)},o.fF.__r=function(e){u&&u(e),0;var t=(r=e.__c).__H;t&&(i===r?(t.__h=[],r.__h=[],t.__.forEach((function(e){e.__N&&(e.__=e.__N),e.__V=l,e.__N=e.i=void 0}))):(t.__h.forEach(v),t.__h.forEach(y),t.__h=[])),i=r},o.fF.diffed=function(e){d&&d(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&(1!==a.push(t)&&s===o.fF.requestAnimationFrame||((s=o.fF.requestAnimationFrame)||m)(p)),t.__H.__.forEach((function(e){e.i&&(e.__H=e.i),e.__V!==l&&(e.__=e.__V),e.i=void 0,e.__V=l}))),i=r=null},o.fF.__c=function(e,t){t.some((function(e){try{e.__h.forEach(v),e.__h=e.__h.filter((function(e){return!e.__||y(e)}))}catch(i){t.some((function(e){e.__h&&(e.__h=[])})),t=[],o.fF.__e(i,e.__v)}})),h&&h(e,t)},o.fF.unmount=function(e){f&&f(e);var t,n=e.__c;n&&n.__H&&(n.__H.__.forEach((function(e){try{v(e)}catch(e){t=e}})),n.__H=void 0,t&&o.fF.__e(t,n.__v))};var g="function"==typeof requestAnimationFrame;function m(e){var t,n=function(){clearTimeout(r),g&&cancelAnimationFrame(t),setTimeout(e)},r=setTimeout(n,100);g&&(t=requestAnimationFrame(n))}function v(e){var t=r,n=e.__c;"function"==typeof n&&(e.__c=void 0,n()),r=t}function y(e){var t=r;e.__c=e.__(),r=t}function b(e,t){for(var n in t)e[n]=t[n];return e}function D(e,t){for(var n in e)if("__source"!==n&&!(n in t))return!0;for(var r in t)if("__source"!==r&&e[r]!==t[r])return!0;return!1}function A(e){this.props=e}(A.prototype=new o.uA).isPureReactComponent=!0,A.prototype.shouldComponentUpdate=function(e,t){return D(this.props,e)||D(this.state,t)};var E=o.fF.__b;o.fF.__b=function(e){e.type&&e.type.__f&&e.ref&&(e.props.ref=e.ref,e.ref=null),E&&E(e)};"undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.forward_ref");var _=function(e,t){return null==e?null:(0,o.v2)((0,o.v2)(e).map(t))},S=(o.v2,o.fF.__e);o.fF.__e=function(e,t,n,r){if(e.then)for(var i,s=t;s=s.__;)if((i=s.__c)&&i.__c)return null==t.__e&&(t.__e=n.__e,t.__k=n.__k),i.__c(e,t);S(e,t,n,r)};var T=o.fF.unmount;function w(e,t,n){return e&&(e.__c&&e.__c.__H&&(e.__c.__H.__.forEach((function(e){"function"==typeof e.__c&&e.__c()})),e.__c.__H=null),null!=(e=b({},e)).__c&&(e.__c.__P===n&&(e.__c.__P=t),e.__c=null),e.__k=e.__k&&e.__k.map((function(e){return w(e,t,n)}))),e}function C(e,t,n){return e&&(e.__v=null,e.__k=e.__k&&e.__k.map((function(e){return C(e,t,n)})),e.__c&&e.__c.__P===t&&(e.__e&&n.insertBefore(e.__e,e.__d),e.__c.__e=!0,e.__c.__P=n)),e}function x(){this.__u=0,this.t=null,this.__b=null}function R(e){var t=e.__.__c;return t&&t.__a&&t.__a(e)}function O(){this.u=null,this.o=null}o.fF.unmount=function(e){var t=e.__c;t&&t.__R&&t.__R(),t&&!0===e.__h&&(e.type=null),T&&T(e)},(x.prototype=new o.uA).__c=function(e,t){var n=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(n);var i=R(r.__v),s=!1,o=function(){s||(s=!0,n.__R=null,i?i(a):a())};n.__R=o;var a=function(){if(! --r.__u){if(r.state.__a){var e=r.state.__a;r.__v.__k[0]=C(e,e.__c.__P,e.__c.__O)}var t;for(r.setState({__a:r.__b=null});t=r.t.pop();)t.forceUpdate()}},l=!0===t.__h;r.__u++||l||r.setState({__a:r.__b=r.__v.__k[0]}),e.then(o,o)},x.prototype.componentWillUnmount=function(){this.t=[]},x.prototype.render=function(e,t){if(this.__b){if(this.__v.__k){var n=document.createElement("div"),r=this.__v.__k[0].__c;this.__v.__k[0]=w(this.__b,n,r.__O=r.__P)}this.__b=null}var i=t.__a&&(0,o.n)(o.FK,null,e.fallback);return i&&(i.__h=null),[(0,o.n)(o.FK,null,t.__a?null:e.children),i]};var k=function(e,t,n){if(++n[1]===n[0]&&e.o.delete(t),e.props.revealOrder&&("t"!==e.props.revealOrder[0]||!e.o.size))for(n=e.u;n;){for(;n.length>3;)n.pop()();if(n[1]>>1,1),t.i.removeChild(e)}}),(0,o.XX)((0,o.n)(I,{context:t.context},e.__v),t.l)):t.l&&t.componentWillUnmount()}function N(e,t){var n=(0,o.n)(M,{__v:e,i:t});return n.containerInfo=t,n}(O.prototype=new o.uA).__a=function(e){var t=this,n=R(t.__v),r=t.o.get(e);return r[0]++,function(i){var s=function(){t.props.revealOrder?(r.push(i),k(t,e,r)):i()};n?n(s):s()}},O.prototype.render=function(e){this.u=null,this.o=new Map;var t=(0,o.v2)(e.children);e.revealOrder&&"b"===e.revealOrder[0]&&t.reverse();for(var n=t.length;n--;)this.o.set(t[n],this.u=[1,0,this.u]);return e.children},O.prototype.componentDidUpdate=O.prototype.componentDidMount=function(){var e=this;this.o.forEach((function(t,n){k(e,n,t)}))};var P="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,B=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,z="undefined"!=typeof document,H=function(e){return("undefined"!=typeof Symbol&&"symbol"==typeof Symbol()?/fil|che|rad/i:/fil|che|ra/i).test(e)};o.uA.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach((function(e){Object.defineProperty(o.uA.prototype,e,{configurable:!0,get:function(){return this["UNSAFE_"+e]},set:function(t){Object.defineProperty(this,e,{configurable:!0,writable:!0,value:t})}})}));var Y=o.fF.event;function U(){}function j(){return this.cancelBubble}function L(){return this.defaultPrevented}o.fF.event=function(e){return Y&&(e=Y(e)),e.persist=U,e.isPropagationStopped=j,e.isDefaultPrevented=L,e.nativeEvent=e};var W={configurable:!0,get:function(){return this.class}},F=o.fF.vnode;o.fF.vnode=function(e){var t=e.type,n=e.props,r=n;if("string"==typeof t){var i=-1===t.indexOf("-");for(var s in r={},n){var a=n[s];z&&"children"===s&&"noscript"===t||"value"===s&&"defaultValue"in n&&null==a||("defaultValue"===s&&"value"in n&&null==n.value?s="value":"download"===s&&!0===a?a="":/ondoubleclick/i.test(s)?s="ondblclick":/^onchange(textarea|input)/i.test(s+t)&&!H(n.type)?s="oninput":/^onfocus$/i.test(s)?s="onfocusin":/^onblur$/i.test(s)?s="onfocusout":/^on(Ani|Tra|Tou|BeforeInp|Compo)/.test(s)?s=s.toLowerCase():i&&B.test(s)?s=s.replace(/[A-Z0-9]/g,"-$&").toLowerCase():null===a&&(a=void 0),/^oninput$/i.test(s)&&(s=s.toLowerCase(),r[s]&&(s="oninputCapture")),r[s]=a)}"select"==t&&r.multiple&&Array.isArray(r.value)&&(r.value=(0,o.v2)(n.children).forEach((function(e){e.props.selected=-1!=r.value.indexOf(e.props.value)}))),"select"==t&&null!=r.defaultValue&&(r.value=(0,o.v2)(n.children).forEach((function(e){e.props.selected=r.multiple?-1!=r.defaultValue.indexOf(e.props.value):r.defaultValue==e.props.value}))),e.props=r,n.class!=n.className&&(W.enumerable="className"in n,null!=n.className&&(r.class=n.className),Object.defineProperty(r,"className",W))}e.$$typeof=P,F&&F(e)};var V=o.fF.__r;o.fF.__r=function(e){V&&V(e),e.__c};o.FK;o.n,o.q6,o._3,o.FK,o.uA},50172:(e,t,n)=>{"use strict";n.d(t,{FK:()=>D,Ob:()=>F,Qv:()=>W,XX:()=>L,_3:()=>b,fF:()=>i,n:()=>v,q6:()=>V,uA:()=>T,v2:()=>M,zO:()=>o});var r,i,s,o,a,l,c,u,d,h={},f=[],p=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function g(e,t){for(var n in t)e[n]=t[n];return e}function m(e){var t=e.parentNode;t&&t.removeChild(e)}function v(e,t,n){var i,s,o,a={};for(o in t)"key"==o?i=t[o]:"ref"==o?s=t[o]:a[o]=t[o];if(arguments.length>2&&(a.children=arguments.length>3?r.call(arguments,2):n),"function"==typeof e&&null!=e.defaultProps)for(o in e.defaultProps)void 0===a[o]&&(a[o]=e.defaultProps[o]);return y(e,a,i,s,null)}function y(e,t,n,r,o){var a={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++s:o};return null==o&&null!=i.vnode&&i.vnode(a),a}function b(){return{current:null}}function D(e){return e.children}function A(e,t,n){"-"===t[0]?e.setProperty(t,null==n?"":n):e[t]=null==n?"":"number"!=typeof n||p.test(t)?n:n+"px"}function E(e,t,n,r,i){var s;e:if("style"===t)if("string"==typeof n)e.style.cssText=n;else{if("string"==typeof r&&(e.style.cssText=r=""),r)for(t in r)n&&t in n||A(e.style,t,"");if(n)for(t in n)r&&n[t]===r[t]||A(e.style,t,n[t])}else if("o"===t[0]&&"n"===t[1])s=t!==(t=t.replace(/Capture$/,"")),t=t.toLowerCase()in e?t.toLowerCase().slice(2):t.slice(2),e.l||(e.l={}),e.l[t+s]=n,n?r||e.addEventListener(t,s?S:_,s):e.removeEventListener(t,s?S:_,s);else if("dangerouslySetInnerHTML"!==t){if(i)t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==t&&"height"!==t&&"href"!==t&&"list"!==t&&"form"!==t&&"tabIndex"!==t&&"download"!==t&&t in e)try{e[t]=null==n?"":n;break e}catch(e){}"function"==typeof n||(null==n||!1===n&&-1==t.indexOf("-")?e.removeAttribute(t):e.setAttribute(t,n))}}function _(e){a=!0;try{return this.l[e.type+!1](i.event?i.event(e):e)}finally{a=!1}}function S(e){a=!0;try{return this.l[e.type+!0](i.event?i.event(e):e)}finally{a=!1}}function T(e,t){this.props=e,this.context=t}function w(e,t){if(null==t)return e.__?w(e.__,e.__.__k.indexOf(e)+1):null;for(var n;tt&&l.sort((function(e,t){return e.__v.__b-t.__v.__b})));O.__r=0}function k(e,t,n,r,i,s,o,a,l,c){var u,d,p,g,m,v,b,A=r&&r.__k||f,E=A.length;for(n.__k=[],u=0;u0?y(g.type,g.props,g.key,g.ref?g.ref:null,g.__v):g)){if(g.__=n,g.__b=n.__b+1,null===(p=A[u])||p&&g.key==p.key&&g.type===p.type)A[u]=void 0;else for(d=0;d=0;t--)if((n=e.__k[t])&&(r=P(n)))return r;return null}function B(e,t,n,r,s,o,a,l,c){var u,d,h,f,p,m,v,y,b,A,E,_,S,w,C,x=t.type;if(void 0!==t.constructor)return null;null!=n.__h&&(c=n.__h,l=t.__e=n.__e,t.__h=null,o=[l]),(u=i.__b)&&u(t);try{e:if("function"==typeof x){if(y=t.props,b=(u=x.contextType)&&r[u.__c],A=u?b?b.props.value:u.__:r,n.__c?v=(d=t.__c=n.__c).__=d.__E:("prototype"in x&&x.prototype.render?t.__c=d=new x(y,A):(t.__c=d=new T(y,A),d.constructor=x,d.render=j),b&&b.sub(d),d.props=y,d.state||(d.state={}),d.context=A,d.__n=r,h=d.__d=!0,d.__h=[],d._sb=[]),null==d.__s&&(d.__s=d.state),null!=x.getDerivedStateFromProps&&(d.__s==d.state&&(d.__s=g({},d.__s)),g(d.__s,x.getDerivedStateFromProps(y,d.__s))),f=d.props,p=d.state,d.__v=t,h)null==x.getDerivedStateFromProps&&null!=d.componentWillMount&&d.componentWillMount(),null!=d.componentDidMount&&d.__h.push(d.componentDidMount);else{if(null==x.getDerivedStateFromProps&&y!==f&&null!=d.componentWillReceiveProps&&d.componentWillReceiveProps(y,A),!d.__e&&null!=d.shouldComponentUpdate&&!1===d.shouldComponentUpdate(y,d.__s,A)||t.__v===n.__v){for(t.__v!==n.__v&&(d.props=y,d.state=d.__s,d.__d=!1),t.__e=n.__e,t.__k=n.__k,t.__k.forEach((function(e){e&&(e.__=t)})),E=0;E2&&(a.children=arguments.length>3?r.call(arguments,2):n),y(e.type,a,i||e.key,s||e.ref,null)}function V(e,t){var n={__c:t="__cC"+d++,__:e,Consumer:function(e,t){return e.children(t)},Provider:function(e){var n,r;return this.getChildContext||(n=[],(r={})[t]=this,this.getChildContext=function(){return r},this.shouldComponentUpdate=function(e){this.props.value!==e.value&&n.some((function(e){e.__e=!0,R(e)}))},this.sub=function(e){n.push(e);var t=e.componentWillUnmount;e.componentWillUnmount=function(){n.splice(n.indexOf(e),1),t&&t.call(e)}}),e.children}};return n.Provider.__=n.Consumer.contextType=n}r=f.slice,i={__e:function(e,t,n,r){for(var i,s,o;t=t.__;)if((i=t.__c)&&!i.__)try{if((s=i.constructor)&&null!=s.getDerivedStateFromError&&(i.setState(s.getDerivedStateFromError(e)),o=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(e,r||{}),o=i.__d),o)return i.__E=i}catch(t){e=t}throw e}},s=0,o=function(e){return null!=e&&void 0===e.constructor},a=!1,T.prototype.setState=function(e,t){var n;n=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=g({},this.state),"function"==typeof e&&(e=e(g({},n),this.props)),e&&g(n,e),null!=e&&this.__v&&(t&&this._sb.push(t),R(this))},T.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),R(this))},T.prototype.render=D,l=[],u="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,O.__r=0,d=0},67363:(e,t,n)=>{"use strict";n.d(t,{Vv:()=>de,i1:()=>d});var r=n(29174),i=n(50172);n(81098);const s=[],o={code:"en",week:{dow:0,doy:4},direction:"ltr",buttonText:{prev:"prev",next:"next",prevYear:"prev year",nextYear:"next year",year:"year",today:"today",month:"month",week:"week",day:"day",list:"list"},weekText:"W",weekTextLong:"Week",closeHint:"Close",timeHint:"Time",eventHint:"Event",allDayText:"all-day",moreLinkText:"more",noEventsText:"No events to display"},a=Object.assign(Object.assign({},o),{buttonHints:{prev:"Previous $0",next:"Next $0",today:(e,t)=>"day"===t?"Today":`This ${e}`},viewHint:"$0 view",navLinkHint:"Go to $0",moreLinkHint:e=>`Show ${e} more event${1===e?"":"s"}`});function l(e){let t=e.length>0?e[0].code:"en",n=s.concat(e),r={en:a};for(let i of n)r[i.code]=i;return{map:r,defaultCode:t}}function c(e,t){return"object"!=typeof e||Array.isArray(e)?function(e,t){let n=[].concat(e||[]),r=function(e,t){for(let n=0;n0;e-=1){let n=r.slice(0,e).join("-");if(t[n])return t[n]}}return null}(n,t)||a;return u(e,n,r)}(e,t):u(e.code,[e.code],e)}function u(e,t,n){let i=(0,r.m)([o,n],["buttonText"]);delete i.code;let{week:s}=i;return delete i.week,{codeArg:e,codes:t,week:s,simpleNumberFormat:new Intl.NumberFormat(e),options:i}}function d(e){return{id:(0,r.g)(),name:e.name,premiumReleaseDate:e.premiumReleaseDate?new Date(e.premiumReleaseDate):void 0,deps:e.deps||[],reducers:e.reducers||[],isLoadingFuncs:e.isLoadingFuncs||[],contextInit:[].concat(e.contextInit||[]),eventRefiners:e.eventRefiners||{},eventDefMemberAdders:e.eventDefMemberAdders||[],eventSourceRefiners:e.eventSourceRefiners||{},isDraggableTransformers:e.isDraggableTransformers||[],eventDragMutationMassagers:e.eventDragMutationMassagers||[],eventDefMutationAppliers:e.eventDefMutationAppliers||[],dateSelectionTransformers:e.dateSelectionTransformers||[],datePointTransforms:e.datePointTransforms||[],dateSpanTransforms:e.dateSpanTransforms||[],views:e.views||{},viewPropsTransformers:e.viewPropsTransformers||[],isPropsValid:e.isPropsValid||null,externalDefTransforms:e.externalDefTransforms||[],viewContainerAppends:e.viewContainerAppends||[],eventDropTransformers:e.eventDropTransformers||[],componentInteractions:e.componentInteractions||[],calendarInteractions:e.calendarInteractions||[],themeClasses:e.themeClasses||{},eventSourceDefs:e.eventSourceDefs||[],cmdFormatter:e.cmdFormatter,recurringTypes:e.recurringTypes||[],namedTimeZonedImpl:e.namedTimeZonedImpl,initialView:e.initialView||"",elementDraggingImpl:e.elementDraggingImpl,optionChangeHandlers:e.optionChangeHandlers||{},scrollGridImpl:e.scrollGridImpl||null,listenerRefiners:e.listenerRefiners||{},optionRefiners:e.optionRefiners||{},propSetHandlers:e.propSetHandlers||{}}}function h(){let e,t=[],n=[];return(i,s)=>(e&&(0,r.i)(i,t)&&(0,r.i)(s,n)||(e=function(e,t){let n={},r={premiumReleaseDate:void 0,reducers:[],isLoadingFuncs:[],contextInit:[],eventRefiners:{},eventDefMemberAdders:[],eventSourceRefiners:{},isDraggableTransformers:[],eventDragMutationMassagers:[],eventDefMutationAppliers:[],dateSelectionTransformers:[],datePointTransforms:[],dateSpanTransforms:[],views:{},viewPropsTransformers:[],isPropsValid:null,externalDefTransforms:[],viewContainerAppends:[],eventDropTransformers:[],componentInteractions:[],calendarInteractions:[],themeClasses:{},eventSourceDefs:[],cmdFormatter:null,recurringTypes:[],namedTimeZonedImpl:null,initialView:"",elementDraggingImpl:null,optionChangeHandlers:{},scrollGridImpl:null,listenerRefiners:{},optionRefiners:{},propSetHandlers:{}};function i(e){for(let o of e){const e=o.name,a=n[e];void 0===a?(n[e]=o.id,i(o.deps),s=o,r={premiumReleaseDate:f((t=r).premiumReleaseDate,s.premiumReleaseDate),reducers:t.reducers.concat(s.reducers),isLoadingFuncs:t.isLoadingFuncs.concat(s.isLoadingFuncs),contextInit:t.contextInit.concat(s.contextInit),eventRefiners:Object.assign(Object.assign({},t.eventRefiners),s.eventRefiners),eventDefMemberAdders:t.eventDefMemberAdders.concat(s.eventDefMemberAdders),eventSourceRefiners:Object.assign(Object.assign({},t.eventSourceRefiners),s.eventSourceRefiners),isDraggableTransformers:t.isDraggableTransformers.concat(s.isDraggableTransformers),eventDragMutationMassagers:t.eventDragMutationMassagers.concat(s.eventDragMutationMassagers),eventDefMutationAppliers:t.eventDefMutationAppliers.concat(s.eventDefMutationAppliers),dateSelectionTransformers:t.dateSelectionTransformers.concat(s.dateSelectionTransformers),datePointTransforms:t.datePointTransforms.concat(s.datePointTransforms),dateSpanTransforms:t.dateSpanTransforms.concat(s.dateSpanTransforms),views:Object.assign(Object.assign({},t.views),s.views),viewPropsTransformers:t.viewPropsTransformers.concat(s.viewPropsTransformers),isPropsValid:s.isPropsValid||t.isPropsValid,externalDefTransforms:t.externalDefTransforms.concat(s.externalDefTransforms),viewContainerAppends:t.viewContainerAppends.concat(s.viewContainerAppends),eventDropTransformers:t.eventDropTransformers.concat(s.eventDropTransformers),calendarInteractions:t.calendarInteractions.concat(s.calendarInteractions),componentInteractions:t.componentInteractions.concat(s.componentInteractions),themeClasses:Object.assign(Object.assign({},t.themeClasses),s.themeClasses),eventSourceDefs:t.eventSourceDefs.concat(s.eventSourceDefs),cmdFormatter:s.cmdFormatter||t.cmdFormatter,recurringTypes:t.recurringTypes.concat(s.recurringTypes),namedTimeZonedImpl:s.namedTimeZonedImpl||t.namedTimeZonedImpl,initialView:t.initialView||s.initialView,elementDraggingImpl:t.elementDraggingImpl||s.elementDraggingImpl,optionChangeHandlers:Object.assign(Object.assign({},t.optionChangeHandlers),s.optionChangeHandlers),scrollGridImpl:s.scrollGridImpl||t.scrollGridImpl,listenerRefiners:Object.assign(Object.assign({},t.listenerRefiners),s.listenerRefiners),optionRefiners:Object.assign(Object.assign({},t.optionRefiners),s.optionRefiners),propSetHandlers:Object.assign(Object.assign({},t.propSetHandlers),s.propSetHandlers)}):a!==o.id&&console.warn(`Duplicate plugin '${e}'`)}var t,s}return e&&i(e),i(t),r}(i,s)),t=i,n=s,e)}function f(e,t){return void 0===e?t:void 0===t?e:new Date(Math.max(e.valueOf(),t.valueOf()))}class p extends r.T{}function g(e,t,n,r){if(t[e])return t[e];let i=function(e,t,n,r){let i=n[e],s=r[e],o=e=>i&&null!==i[e]?i[e]:s&&null!==s[e]?s[e]:null,a=o("component"),l=o("superType"),c=null;if(l){if(l===e)throw new Error("Can't have a custom view type that references itself");c=g(l,t,n,r)}!a&&c&&(a=c.component);if(!a)return null;return{type:e,component:a,defaults:Object.assign(Object.assign({},c?c.defaults:{}),i?i.rawOptions:{}),overrides:Object.assign(Object.assign({},c?c.overrides:{}),s?s.rawOptions:{})}}(e,t,n,r);return i&&(t[e]=i),i}function m(e){return(0,r.a)(e,v)}function v(e){let t="function"==typeof e?{component:e}:e,{component:n}=t;return t.content?n=y(t):!n||n.prototype instanceof r.B||(n=y(Object.assign(Object.assign({},t),{content:n}))),{superType:t.type,component:n,rawOptions:t}}function y(e){return t=>(0,i.n)(r.V.Consumer,null,(n=>(0,i.n)(r.C,{elTag:"div",elClasses:(0,r.b)(n.viewSpec),renderProps:Object.assign(Object.assign({},t),{nextDayThreshold:n.options.nextDayThreshold}),generatorName:void 0,customGenerator:e.content,classNameGenerator:e.classNames,didMount:e.didMount,willUnmount:e.willUnmount})))}function b(e,t,n,i){let s=m(e),o=m(t.views),a=function(e,t){let n,r={};for(n in e)g(n,r,e,t);for(n in t)g(n,r,e,t);return r}(s,o);return(0,r.a)(a,(e=>function(e,t,n,i,s){let o=e.overrides.duration||e.defaults.duration||i.duration||n.duration,a=null,l="",c="",u={};if(o&&(a=function(e){let t=JSON.stringify(e),n=D[t];void 0===n&&(n=(0,r.d)(e),D[t]=n);return n}(o),a)){let e=(0,r.c)(a);l=e.unit,1===e.value&&(c=l,u=t[l]?t[l].rawOptions:{})}let d=t=>{let n=t.buttonText||{},r=e.defaults.buttonTextKey;return null!=r&&null!=n[r]?n[r]:null!=n[e.type]?n[e.type]:null!=n[c]?n[c]:null},h=t=>{let n=t.buttonHints||{},r=e.defaults.buttonTextKey;return null!=r&&null!=n[r]?n[r]:null!=n[e.type]?n[e.type]:null!=n[c]?n[c]:null};return{type:e.type,component:e.component,duration:a,durationUnit:l,singleUnit:c,optionDefaults:e.defaults,optionOverrides:Object.assign(Object.assign({},u),e.overrides),buttonTextOverride:d(i)||d(n)||e.overrides.buttonText,buttonTextDefault:d(s)||e.defaults.buttonText||d(r.e)||e.type,buttonTitleOverride:h(i)||h(n)||e.overrides.buttonHint,buttonTitleDefault:h(s)||e.defaults.buttonHint||h(r.e)}}(e,o,t,n,i)))}p.prototype.classes={root:"fc-theme-standard",tableCellShaded:"fc-cell-shaded",buttonGroup:"fc-button-group",button:"fc-button fc-button-primary",buttonActive:"fc-button-active"},p.prototype.baseIconClass="fc-icon",p.prototype.iconClasses={close:"fc-icon-x",prev:"fc-icon-chevron-left",next:"fc-icon-chevron-right",prevYear:"fc-icon-chevrons-left",nextYear:"fc-icon-chevrons-right"},p.prototype.rtlIconClasses={prev:"fc-icon-chevron-right",next:"fc-icon-chevron-left",prevYear:"fc-icon-chevrons-right",nextYear:"fc-icon-chevrons-left"},p.prototype.iconOverrideOption="buttonIcons",p.prototype.iconOverrideCustomButtonOption="icon",p.prototype.iconOverridePrefix="fc-icon-";let D={};function A(e,t,n){let i=t?t.activeRange:null;return S({},function(e,t){let n=(0,r.j)(t),i=[].concat(e.eventSources||[]),s=[];e.initialEvents&&i.unshift(e.initialEvents);e.events&&i.unshift(e.events);for(let o of i){let e=(0,r.p)(o,t,n);e&&s.push(e)}return s}(e,n),i,n)}function E(e,t,n,i){let s=n?n.activeRange:null;switch(t.type){case"ADD_EVENT_SOURCES":return S(e,t.sources,s,i);case"REMOVE_EVENT_SOURCE":return o=e,a=t.sourceId,(0,r.h)(o,(e=>e.sourceId!==a));case"PREV":case"NEXT":case"CHANGE_DATE":case"CHANGE_VIEW_TYPE":return n?T(e,s,i):e;case"FETCH_EVENT_SOURCES":return w(e,t.sourceIds?(0,r.f)(t.sourceIds):x(e,i),s,t.isRefetch||!1,i);case"RECEIVE_EVENTS":case"RECEIVE_EVENT_ERROR":return function(e,t,n,r){let i=e[t];if(i&&n===i.latestFetchId)return Object.assign(Object.assign({},e),{[t]:Object.assign(Object.assign({},i),{isFetching:!1,fetchRange:r})});return e}(e,t.sourceId,t.fetchId,t.fetchRange);case"REMOVE_ALL_EVENT_SOURCES":return{};default:return e}var o,a}function _(e){for(let t in e)if(e[t].isFetching)return!0;return!1}function S(e,t,n,r){let i={};for(let s of t)i[s.sourceId]=s;return n&&(i=T(i,n,r)),Object.assign(Object.assign({},e),i)}function T(e,t,n){return w(e,(0,r.h)(e,(e=>function(e,t,n){if(!R(e,n))return!e.latestFetchId;return!n.options.lazyFetching||!e.fetchRange||e.isFetching||t.starte.fetchRange.end}(e,t,n))),t,!1,n)}function w(e,t,n,r,i){let s={};for(let o in e){let a=e[o];t[o]?s[o]=C(a,n,r,i):s[o]=a}return s}function C(e,t,n,i){let{options:s,calendarApi:o}=i,a=i.pluginHooks.eventSourceDefs[e.sourceDefId],l=(0,r.g)();return a.fetch({eventSource:e,range:t,isRefetch:n,context:i},(n=>{let{rawEvents:r}=n;s.eventSourceSuccess&&(r=s.eventSourceSuccess.call(o,r,n.response)||r),e.success&&(r=e.success.call(o,r,n.response)||r),i.dispatch({type:"RECEIVE_EVENTS",sourceId:e.sourceId,fetchId:l,fetchRange:t,rawEvents:r})}),(n=>{let r=!1;s.eventSourceFailure&&(s.eventSourceFailure.call(o,n),r=!0),e.failure&&(e.failure(n),r=!0),r||console.warn(n.message,n),i.dispatch({type:"RECEIVE_EVENT_ERROR",sourceId:e.sourceId,fetchId:l,fetchRange:t,error:n})})),Object.assign(Object.assign({},e),{isFetching:!0,latestFetchId:l})}function x(e,t){return(0,r.h)(e,(e=>R(e,t)))}function R(e,t){return!t.pluginHooks.eventSourceDefs[e.sourceDefId].ignoreRange}function O(e,t){switch(t.type){case"UNSELECT_DATES":return null;case"SELECT_DATES":return t.selection;default:return e}}function k(e,t){switch(t.type){case"UNSELECT_EVENT":return"";case"SELECT_EVENT":return t.eventInstanceId;default:return e}}function I(e,t){let n;switch(t.type){case"UNSET_EVENT_DRAG":return null;case"SET_EVENT_DRAG":return n=t.state,{affectedEvents:n.affectedEvents,mutatedEvents:n.mutatedEvents,isEvent:n.isEvent};default:return e}}function M(e,t){let n;switch(t.type){case"UNSET_EVENT_RESIZE":return null;case"SET_EVENT_RESIZE":return n=t.state,{affectedEvents:n.affectedEvents,mutatedEvents:n.mutatedEvents,isEvent:n.isEvent};default:return e}}function N(e,t,n,r,i){return{header:e.headerToolbar?P(e.headerToolbar,e,t,n,r,i):null,footer:e.footerToolbar?P(e.footerToolbar,e,t,n,r,i):null}}function P(e,t,n,r,i,s){let o={},a=[],l=!1;for(let c in e){let u=B(e[c],t,n,r,i,s);o[c]=u.widgets,a.push(...u.viewsWithButtons),l=l||u.hasTitle}return{sectionWidgets:o,viewsWithButtons:a,hasTitle:l}}function B(e,t,n,i,s,o){let a="rtl"===t.direction,l=t.customButtons||{},c=n.buttonText||{},u=t.buttonText||{},d=n.buttonHints||{},h=t.buttonHints||{},f=e?e.split(" "):[],p=[],g=!1;return{widgets:f.map((e=>e.split(",").map((e=>{if("title"===e)return g=!0,{buttonName:e};let n,f,m,v,y,b;if(n=l[e])m=e=>{n.click&&n.click.call(e.target,e,e.target)},(v=i.getCustomButtonIconClass(n))||(v=i.getIconClass(e,a))||(y=n.text),b=n.hint||n.text;else if(f=s[e]){p.push(e),m=()=>{o.changeView(e)},(y=f.buttonTextOverride)||(v=i.getIconClass(e,a))||(y=f.buttonTextDefault);let n=f.buttonTextOverride||f.buttonTextDefault;b=(0,r.k)(f.buttonTitleOverride||f.buttonTitleDefault||t.viewHint,[n,e],n)}else if(o[e])if(m=()=>{o[e]()},(y=c[e])||(v=i.getIconClass(e,a))||(y=u[e]),"prevYear"===e||"nextYear"===e){let t="prevYear"===e?"prev":"next";b=(0,r.k)(d[t]||h[t],[u.year||"year","year"],u[e])}else b=t=>(0,r.k)(d[e]||h[e],[u[t]||t,t],u[e]);return{buttonName:e,buttonClick:m,buttonIcon:v,buttonText:y,buttonHint:b}})))),viewsWithButtons:p,hasTitle:g}}class z{constructor(e,t,n){this.type=e,this.getCurrentData=t,this.dateEnv=n}get calendar(){return this.getCurrentData().calendarApi}get title(){return this.getCurrentData().viewTitle}get activeStart(){return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start)}get activeEnd(){return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end)}get currentStart(){return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start)}get currentEnd(){return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end)}getOption(e){return this.getCurrentData().options[e]}}const H=d({name:"array-event-source",eventSourceDefs:[{ignoreRange:!0,parseMeta:e=>Array.isArray(e.events)?e.events:null,fetch(e,t){t({rawEvents:e.eventSource.meta})}}]});const Y=d({name:"func-event-source",eventSourceDefs:[{parseMeta:e=>"function"==typeof e.events?e.events:null,fetch(e,t,n){const{dateEnv:i}=e.context,s=e.eventSource.meta;(0,r.u)(s.bind(null,(0,r.l)(e.range,i)),(e=>t({rawEvents:e})),n)}}]});const U=d({name:"json-event-source",eventSourceRefiners:{method:String,extraParams:r.n,startParam:String,endParam:String,timeZoneParam:String},eventSourceDefs:[{parseMeta:e=>!e.url||"json"!==e.format&&e.format?null:{url:e.url,format:"json",method:(e.method||"GET").toUpperCase(),extraParams:e.extraParams,startParam:e.startParam,endParam:e.endParam,timeZoneParam:e.timeZoneParam},fetch(e,t,n){const{meta:i}=e.eventSource,s=function(e,t,n){let r,i,s,o,{dateEnv:a,options:l}=n,c={};r=e.startParam,null==r&&(r=l.startParam);i=e.endParam,null==i&&(i=l.endParam);s=e.timeZoneParam,null==s&&(s=l.timeZoneParam);o="function"==typeof e.extraParams?e.extraParams():e.extraParams||{};Object.assign(c,o),c[r]=a.formatIso(t.start),c[i]=a.formatIso(t.end),"local"!==a.timeZone&&(c[s]=a.timeZone);return c}(i,e.range,e.context);(0,r.r)(i.method,i.url,s).then((([e,n])=>{t({rawEvents:e,response:n})}),n)}}]});const j={daysOfWeek:r.n,startTime:r.d,endTime:r.d,duration:r.d,startRecur:r.n,endRecur:r.n};function L(e,t){let n=(0,r.v)(t.getCurrentData().eventSources);if(1===n.length&&1===e.length&&Array.isArray(n[0]._raw)&&Array.isArray(e[0]))return void t.dispatch({type:"RESET_RAW_EVENTS",sourceId:n[0].sourceId,rawEvents:e[0]});let i=[];for(let r of e){let e=!1;for(let t=0;t_(e.eventSources)],propSetHandlers:{dateProfile:function(e,t){t.emitter.trigger("datesSet",Object.assign(Object.assign({},(0,r.l)(e.activeRange,t.dateEnv)),{view:t.viewApi}))},eventStore:function(e,t){let{emitter:n}=t;n.hasHandlers("eventsSet")&&n.trigger("eventsSet",(0,r.w)(e,t))}}})];class F{constructor(e,t){this.runTaskOption=e,this.drainedOption=t,this.queue=[],this.delayedRunner=new r.D(this.drain.bind(this))}request(e,t){this.queue.push(e),this.delayedRunner.request(t)}pause(e){this.delayedRunner.pause(e)}resume(e,t){this.delayedRunner.resume(e,t)}drain(){let{queue:e}=this;for(;e.length;){let t,n=[];for(;t=e.shift();)this.runTask(t),n.push(t);this.drained(n)}}runTask(e){this.runTaskOption&&this.runTaskOption(e)}drained(e){this.drainedOption&&this.drainedOption(e)}}function V(e,t,n){let i;return i=/^(year|month)$/.test(e.currentRangeUnit)?e.currentRange:e.activeRange,n.formatRange(i.start,i.end,(0,r.x)(t.titleFormat||function(e){let{currentRangeUnit:t}=e;if("year"===t)return{year:"numeric"};if("month"===t)return{year:"numeric",month:"long"};let n=(0,r.y)(e.currentRange.start,e.currentRange.end);if(null!==n&&n>1)return{year:"numeric",month:"short",day:"numeric"};return{year:"numeric",month:"long",day:"numeric"}}(e)),{isEndExclusive:e.isRangeAllDay,defaultSeparator:t.titleRangeSeparator})}class G{constructor(e){this.computeCurrentViewData=(0,r.z)(this._computeCurrentViewData),this.organizeRawLocales=(0,r.z)(l),this.buildLocale=(0,r.z)(c),this.buildPluginHooks=h(),this.buildDateEnv=(0,r.z)(q),this.buildTheme=(0,r.z)(Q),this.parseToolbars=(0,r.z)(N),this.buildViewSpecs=(0,r.z)(b),this.buildDateProfileGenerator=(0,r.A)(Z),this.buildViewApi=(0,r.z)(X),this.buildViewUiProps=(0,r.A)($),this.buildEventUiBySource=(0,r.z)(K,r.E),this.buildEventUiBases=(0,r.z)(J),this.parseContextBusinessHours=(0,r.A)(te),this.buildTitle=(0,r.z)(V),this.emitter=new r.F,this.actionRunner=new F(this._handleAction.bind(this),this.updateData.bind(this)),this.currentCalendarOptionsInput={},this.currentCalendarOptionsRefined={},this.currentViewOptionsInput={},this.currentViewOptionsRefined={},this.currentCalendarOptionsRefiners={},this.optionsForRefining=[],this.optionsForHandling=[],this.getCurrentData=()=>this.data,this.dispatch=e=>{this.actionRunner.request(e)},this.props=e,this.actionRunner.pause();let t={},n=this.computeOptionsData(e.optionOverrides,t,e.calendarApi),i=n.calendarOptions.initialView||n.pluginHooks.initialView,s=this.computeCurrentViewData(i,n,e.optionOverrides,t);e.calendarApi.currentDataManager=this,this.emitter.setThisContext(e.calendarApi),this.emitter.setOptions(s.options);let o=(0,r.G)(n.calendarOptions,n.dateEnv),a=s.dateProfileGenerator.build(o);(0,r.H)(a.activeRange,o)||(o=a.currentRange.start);let u={dateEnv:n.dateEnv,options:n.calendarOptions,pluginHooks:n.pluginHooks,calendarApi:e.calendarApi,dispatch:this.dispatch,emitter:this.emitter,getCurrentData:this.getCurrentData};for(let r of n.pluginHooks.contextInit)r(u);let d=A(n.calendarOptions,a,u),f={dynamicOptionOverrides:t,currentViewType:i,currentDate:o,dateProfile:a,businessHours:this.parseContextBusinessHours(u),eventSources:d,eventUiBases:{},eventStore:(0,r.I)(),renderableEventStore:(0,r.I)(),dateSelection:null,eventSelection:"",eventDrag:null,eventResize:null,selectionConfig:this.buildViewUiProps(u).selectionConfig},p=Object.assign(Object.assign({},u),f);for(let r of n.pluginHooks.reducers)Object.assign(f,r(null,null,p));ee(f,u)&&this.emitter.trigger("loading",!0),this.state=f,this.updateData(),this.actionRunner.resume()}resetOptions(e,t){let{props:n}=this;void 0===t?n.optionOverrides=e:(n.optionOverrides=Object.assign(Object.assign({},n.optionOverrides||{}),e),this.optionsForRefining.push(...t)),(void 0===t||t.length)&&this.actionRunner.request({type:"NOTHING"})}_handleAction(e){let{props:t,state:n,emitter:i}=this,s=function(e,t){return"SET_OPTION"===t.type?Object.assign(Object.assign({},e),{[t.optionName]:t.rawOptionValue}):e}(n.dynamicOptionOverrides,e),o=this.computeOptionsData(t.optionOverrides,s,t.calendarApi),a=function(e,t){"CHANGE_VIEW_TYPE"===t.type&&(e=t.viewType);return e}(n.currentViewType,e),l=this.computeCurrentViewData(a,o,t.optionOverrides,s);t.calendarApi.currentDataManager=this,i.setThisContext(t.calendarApi),i.setOptions(l.options);let c={dateEnv:o.dateEnv,options:o.calendarOptions,pluginHooks:o.pluginHooks,calendarApi:t.calendarApi,dispatch:this.dispatch,emitter:i,getCurrentData:this.getCurrentData},{currentDate:u,dateProfile:d}=n;this.data&&this.data.dateProfileGenerator!==l.dateProfileGenerator&&(d=l.dateProfileGenerator.build(u)),u=(0,r.J)(u,e),d=function(e,t,n,r){let i;switch(t.type){case"CHANGE_VIEW_TYPE":return r.build(t.dateMarker||n);case"CHANGE_DATE":return r.build(t.dateMarker);case"PREV":if(i=r.buildPrev(e,n),i.isValid)return i;break;case"NEXT":if(i=r.buildNext(e,n),i.isValid)return i}return e}(d,e,u,l.dateProfileGenerator),"PREV"!==e.type&&"NEXT"!==e.type&&(0,r.H)(d.currentRange,u)||(u=d.currentRange.start);let h=E(n.eventSources,e,d,c),f=(0,r.K)(n.eventStore,e,h,d,c),p=_(h)&&!l.options.progressiveEventRendering&&n.renderableEventStore||f,{eventUiSingleBase:g,selectionConfig:m}=this.buildViewUiProps(c),v=this.buildEventUiBySource(h),y={dynamicOptionOverrides:s,currentViewType:a,currentDate:u,dateProfile:d,eventSources:h,eventStore:f,renderableEventStore:p,selectionConfig:m,eventUiBases:this.buildEventUiBases(p.defs,g,v),businessHours:this.parseContextBusinessHours(c),dateSelection:O(n.dateSelection,e),eventSelection:k(n.eventSelection,e),eventDrag:I(n.eventDrag,e),eventResize:M(n.eventResize,e)},b=Object.assign(Object.assign({},c),y);for(let r of o.pluginHooks.reducers)Object.assign(y,r(n,e,b));let D=ee(n,c),A=ee(y,c);!D&&A?i.trigger("loading",!0):D&&!A&&i.trigger("loading",!1),this.state=y,t.onAction&&t.onAction(e)}updateData(){let{props:e,state:t}=this,n=this.data,i=this.computeOptionsData(e.optionOverrides,t.dynamicOptionOverrides,e.calendarApi),s=this.computeCurrentViewData(t.currentViewType,i,e.optionOverrides,t.dynamicOptionOverrides),o=this.data=Object.assign(Object.assign(Object.assign({viewTitle:this.buildTitle(t.dateProfile,s.options,i.dateEnv),calendarApi:e.calendarApi,dispatch:this.dispatch,emitter:this.emitter,getCurrentData:this.getCurrentData},i),s),t),a=i.pluginHooks.optionChangeHandlers,l=n&&n.calendarOptions,c=i.calendarOptions;if(l&&l!==c){l.timeZone!==c.timeZone&&(t.eventSources=o.eventSources=function(e,t,n){let r=t?t.activeRange:null;return w(e,x(e,n),r,!0,n)}(o.eventSources,t.dateProfile,o),t.eventStore=o.eventStore=(0,r.L)(o.eventStore,n.dateEnv,o.dateEnv),t.renderableEventStore=o.renderableEventStore=(0,r.L)(o.renderableEventStore,n.dateEnv,o.dateEnv));for(let e in a)-1===this.optionsForHandling.indexOf(e)&&l[e]===c[e]||a[e](c[e],o)}this.optionsForHandling=[],e.onData&&e.onData(o)}computeOptionsData(e,t,n){if(!this.optionsForRefining.length&&e===this.stableOptionOverrides&&t===this.stableDynamicOptionOverrides)return this.stableCalendarOptionsData;let{refinedOptions:r,pluginHooks:i,localeDefaults:s,availableLocaleData:o,extra:a}=this.processRawCalendarOptions(e,t);ne(a);let l=this.buildDateEnv(r.timeZone,r.locale,r.weekNumberCalculation,r.firstDay,r.weekText,i,o,r.defaultRangeSeparator),c=this.buildViewSpecs(i.views,this.stableOptionOverrides,this.stableDynamicOptionOverrides,s),u=this.buildTheme(r,i),d=this.parseToolbars(r,this.stableOptionOverrides,u,c,n);return this.stableCalendarOptionsData={calendarOptions:r,pluginHooks:i,dateEnv:l,viewSpecs:c,theme:u,toolbarConfig:d,localeDefaults:s,availableRawLocales:o.map}}processRawCalendarOptions(e,t){let{locales:n,locale:i}=(0,r.M)([r.e,e,t]),s=this.organizeRawLocales(n),o=s.map,a=this.buildLocale(i||s.defaultCode,o).options,l=this.buildPluginHooks(e.plugins||[],W),c=this.currentCalendarOptionsRefiners=Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},r.N),r.O),r.P),l.listenerRefiners),l.optionRefiners),u={},d=(0,r.M)([r.e,a,e,t]),h={},f=this.currentCalendarOptionsInput,p=this.currentCalendarOptionsRefined,g=!1;for(let m in d)-1===this.optionsForRefining.indexOf(m)&&(d[m]===f[m]||r.Q[m]&&m in f&&r.Q[m](f[m],d[m]))?h[m]=p[m]:c[m]?(h[m]=c[m](d[m]),g=!0):u[m]=f[m];return g&&(this.currentCalendarOptionsInput=d,this.currentCalendarOptionsRefined=h,this.stableOptionOverrides=e,this.stableDynamicOptionOverrides=t),this.optionsForHandling.push(...this.optionsForRefining),this.optionsForRefining=[],{rawOptions:this.currentCalendarOptionsInput,refinedOptions:this.currentCalendarOptionsRefined,pluginHooks:l,availableLocaleData:s,localeDefaults:a,extra:u}}_computeCurrentViewData(e,t,n,r){let i=t.viewSpecs[e];if(!i)throw new Error(`viewType "${e}" is not available. Please make sure you've loaded all neccessary plugins`);let{refinedOptions:s,extra:o}=this.processRawViewOptions(i,t.pluginHooks,t.localeDefaults,n,r);return ne(o),{viewSpec:i,options:s,dateProfileGenerator:this.buildDateProfileGenerator({dateProfileGeneratorClass:i.optionDefaults.dateProfileGeneratorClass,duration:i.duration,durationUnit:i.durationUnit,usesMinMaxTime:i.optionDefaults.usesMinMaxTime,dateEnv:t.dateEnv,calendarApi:this.props.calendarApi,slotMinTime:s.slotMinTime,slotMaxTime:s.slotMaxTime,showNonCurrentDates:s.showNonCurrentDates,dayCount:s.dayCount,dateAlignment:s.dateAlignment,dateIncrement:s.dateIncrement,hiddenDays:s.hiddenDays,weekends:s.weekends,nowInput:s.now,validRangeInput:s.validRange,visibleRangeInput:s.visibleRange,fixedWeekCount:s.fixedWeekCount}),viewApi:this.buildViewApi(e,this.getCurrentData,t.dateEnv)}}processRawViewOptions(e,t,n,i,s){let o=(0,r.M)([r.e,e.optionDefaults,n,i,e.optionOverrides,s]),a=Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},r.N),r.O),r.P),r.R),t.listenerRefiners),t.optionRefiners),l={},c=this.currentViewOptionsInput,u=this.currentViewOptionsRefined,d=!1,h={};for(let f in o)o[f]===c[f]||r.Q[f]&&r.Q[f](o[f],c[f])?l[f]=u[f]:(o[f]===this.currentCalendarOptionsInput[f]||r.Q[f]&&r.Q[f](o[f],this.currentCalendarOptionsInput[f])?f in this.currentCalendarOptionsRefined&&(l[f]=this.currentCalendarOptionsRefined[f]):a[f]?l[f]=a[f](o[f]):h[f]=o[f],d=!0);return d&&(this.currentViewOptionsInput=o,this.currentViewOptionsRefined=l),{rawOptions:this.currentViewOptionsInput,refinedOptions:this.currentViewOptionsRefined,extra:h}}}function q(e,t,n,i,s,o,a,l){let u=c(t||a.defaultCode,a.map);return new r.S({calendarSystem:"gregory",timeZone:e,namedTimeZoneImpl:o.namedTimeZonedImpl,locale:u,weekNumberCalculation:n,firstDay:i,weekText:s,cmdFormatter:o.cmdFormatter,defaultSeparator:l})}function Q(e,t){return new(t.themeClasses[e.themeSystem]||p)(e)}function Z(e){return new(e.dateProfileGeneratorClass||r.U)(e)}function X(e,t,n){return new z(e,t,n)}function K(e){return(0,r.a)(e,(e=>e.ui))}function J(e,t,n){let r={"":t};for(let i in e){let t=e[i];t.sourceId&&n[t.sourceId]&&(r[i]=n[t.sourceId])}return r}function $(e){let{options:t}=e;return{eventUiSingleBase:(0,r.W)({display:t.eventDisplay,editable:t.editable,startEditable:t.eventStartEditable,durationEditable:t.eventDurationEditable,constraint:t.eventConstraint,overlap:"boolean"==typeof t.eventOverlap?t.eventOverlap:void 0,allow:t.eventAllow,backgroundColor:t.eventBackgroundColor,borderColor:t.eventBorderColor,textColor:t.eventTextColor,color:t.eventColor},e),selectionConfig:(0,r.W)({constraint:t.selectConstraint,overlap:"boolean"==typeof t.selectOverlap?t.selectOverlap:void 0,allow:t.selectAllow},e)}}function ee(e,t){for(let n of t.pluginHooks.isLoadingFuncs)if(n(e))return!0;return!1}function te(e){return(0,r.X)(e.options.businessHours,e)}function ne(e,t){for(let n in e)console.warn(`Unknown option '${n}'`+(t?` for view '${t}'`:""))}class re extends r.B{render(){let e=this.props.widgetGroups.map((e=>this.renderWidgetGroup(e)));return(0,i.n)("div",{className:"fc-toolbar-chunk"},...e)}renderWidgetGroup(e){let{props:t}=this,{theme:n}=this.context,r=[],s=!0;for(let o of e){let{buttonName:e,buttonClick:a,buttonText:l,buttonIcon:c,buttonHint:u}=o;if("title"===e)s=!1,r.push((0,i.n)("h2",{className:"fc-toolbar-title",id:t.titleId},t.title));else{let s=e===t.activeButton,o=!t.isTodayEnabled&&"today"===e||!t.isPrevEnabled&&"prev"===e||!t.isNextEnabled&&"next"===e,d=[`fc-${e}-button`,n.getClass("button")];s&&d.push(n.getClass("buttonActive")),r.push((0,i.n)("button",{type:"button",title:"function"==typeof u?u(t.navUnit):u,disabled:o,"aria-pressed":s,className:d.join(" "),onClick:a},l||(c?(0,i.n)("span",{className:c,role:"img"}):"")))}}if(r.length>1){let e=s&&n.getClass("buttonGroup")||"";return(0,i.n)("div",{className:e},...r)}return r[0]}}class ie extends r.B{render(){let e,t,{model:n,extraClassName:r}=this.props,s=!1,o=n.sectionWidgets,a=o.center;o.left?(s=!0,e=o.left):e=o.start,o.right?(s=!0,t=o.right):t=o.end;let l=[r||"","fc-toolbar",s?"fc-toolbar-ltr":""];return(0,i.n)("div",{className:l.join(" ")},this.renderSection("start",e||[]),this.renderSection("center",a||[]),this.renderSection("end",t||[]))}renderSection(e,t){let{props:n}=this;return(0,i.n)(re,{key:e,widgetGroups:t,title:n.title,navUnit:n.navUnit,activeButton:n.activeButton,isTodayEnabled:n.isTodayEnabled,isPrevEnabled:n.isPrevEnabled,isNextEnabled:n.isNextEnabled,titleId:n.titleId})}}class se extends r.B{constructor(){super(...arguments),this.state={availableWidth:null},this.handleEl=e=>{this.el=e,(0,r.Y)(this.props.elRef,e),this.updateAvailableWidth()},this.handleResize=()=>{this.updateAvailableWidth()}}render(){let{props:e,state:t}=this,{aspectRatio:n}=e,r=["fc-view-harness",n||e.liquid||e.height?"fc-view-harness-active":"fc-view-harness-passive"],s="",o="";return n?null!==t.availableWidth?s=t.availableWidth/n:o=1/n*100+"%":s=e.height||"",(0,i.n)("div",{"aria-labelledby":e.labeledById,ref:this.handleEl,className:r.join(" "),style:{height:s,paddingBottom:o}},e.children)}componentDidMount(){this.context.addResizeHandler(this.handleResize)}componentWillUnmount(){this.context.removeResizeHandler(this.handleResize)}updateAvailableWidth(){this.el&&this.props.aspectRatio&&this.setState({availableWidth:this.el.offsetWidth})}}class oe extends r.Z{constructor(e){super(e),this.handleSegClick=(e,t)=>{let{component:n}=this,{context:i}=n,s=(0,r._)(t);if(s&&n.isValidSegDownEl(e.target)){let o=(0,r.$)(e.target,".fc-event-forced-url"),a=o?o.querySelector("a[href]").href:"";i.emitter.trigger("eventClick",{el:t,event:new r.a0(n.context,s.eventRange.def,s.eventRange.instance),jsEvent:e,view:i.viewApi}),a&&!e.defaultPrevented&&(window.location.href=a)}},this.destroy=(0,r.a1)(e.el,"click",".fc-event",this.handleSegClick)}}class ae extends r.Z{constructor(e){super(e),this.handleEventElRemove=e=>{e===this.currentSegEl&&this.handleSegLeave(null,this.currentSegEl)},this.handleSegEnter=(e,t)=>{(0,r._)(t)&&(this.currentSegEl=t,this.triggerEvent("eventMouseEnter",e,t))},this.handleSegLeave=(e,t)=>{this.currentSegEl&&(this.currentSegEl=null,this.triggerEvent("eventMouseLeave",e,t))},this.removeHoverListeners=(0,r.a2)(e.el,".fc-event",this.handleSegEnter,this.handleSegLeave)}destroy(){this.removeHoverListeners()}triggerEvent(e,t,n){let{component:i}=this,{context:s}=i,o=(0,r._)(n);t&&!i.isValidSegDownEl(t.target)||s.emitter.trigger(e,{el:n,event:new r.a0(s,o.eventRange.def,o.eventRange.instance),jsEvent:t,view:s.viewApi})}}class le extends r.a3{constructor(){super(...arguments),this.buildViewContext=(0,r.z)(r.a4),this.buildViewPropTransformers=(0,r.z)(ue),this.buildToolbarProps=(0,r.z)(ce),this.headerRef=(0,i._3)(),this.footerRef=(0,i._3)(),this.interactionsStore={},this.state={viewLabelId:(0,r.a5)()},this.registerInteractiveComponent=(e,t)=>{let n=(0,r.a6)(e,t),i=[oe,ae].concat(this.props.pluginHooks.componentInteractions).map((e=>new e(n)));this.interactionsStore[e.uid]=i,r.a7[e.uid]=n},this.unregisterInteractiveComponent=e=>{let t=this.interactionsStore[e.uid];if(t){for(let e of t)e.destroy();delete this.interactionsStore[e.uid]}delete r.a7[e.uid]},this.resizeRunner=new r.D((()=>{this.props.emitter.trigger("_resize",!0),this.props.emitter.trigger("windowResize",{view:this.props.viewApi})})),this.handleWindowResize=e=>{let{options:t}=this.props;t.handleWindowResize&&e.target===window&&this.resizeRunner.request(t.windowResizeDelay)}}render(){let e,{props:t}=this,{toolbarConfig:n,options:s}=t,o=this.buildToolbarProps(t.viewSpec,t.dateProfile,t.dateProfileGenerator,t.currentDate,(0,r.a8)(t.options.now,t.dateEnv),t.viewTitle),a=!1,l="";t.isHeightAuto||t.forPrint?l="":null!=s.height?a=!0:null!=s.contentHeight?l=s.contentHeight:e=Math.max(s.aspectRatio,.5);let c=this.buildViewContext(t.viewSpec,t.viewApi,t.options,t.dateProfileGenerator,t.dateEnv,t.theme,t.pluginHooks,t.dispatch,t.getCurrentData,t.emitter,t.calendarApi,this.registerInteractiveComponent,this.unregisterInteractiveComponent),u=n.header&&n.header.hasTitle?this.state.viewLabelId:void 0;return(0,i.n)(r.V.Provider,{value:c},n.header&&(0,i.n)(ie,Object.assign({ref:this.headerRef,extraClassName:"fc-header-toolbar",model:n.header,titleId:u},o)),(0,i.n)(se,{liquid:a,height:l,aspectRatio:e,labeledById:u},this.renderView(t),this.buildAppendContent()),n.footer&&(0,i.n)(ie,Object.assign({ref:this.footerRef,extraClassName:"fc-footer-toolbar",model:n.footer,titleId:""},o)))}componentDidMount(){let{props:e}=this;this.calendarInteractions=e.pluginHooks.calendarInteractions.map((t=>new t(e))),window.addEventListener("resize",this.handleWindowResize);let{propSetHandlers:t}=e.pluginHooks;for(let n in t)t[n](e[n],e)}componentDidUpdate(e){let{props:t}=this,{propSetHandlers:n}=t.pluginHooks;for(let r in n)t[r]!==e[r]&&n[r](t[r],t)}componentWillUnmount(){window.removeEventListener("resize",this.handleWindowResize),this.resizeRunner.clear();for(let e of this.calendarInteractions)e.destroy();this.props.emitter.trigger("_unmount")}buildAppendContent(){let{props:e}=this,t=e.pluginHooks.viewContainerAppends.map((t=>t(e)));return(0,i.n)(i.FK,{},...t)}renderView(e){let{pluginHooks:t}=e,{viewSpec:n}=e,r={dateProfile:e.dateProfile,businessHours:e.businessHours,eventStore:e.renderableEventStore,eventUiBases:e.eventUiBases,dateSelection:e.dateSelection,eventSelection:e.eventSelection,eventDrag:e.eventDrag,eventResize:e.eventResize,isHeightAuto:e.isHeightAuto,forPrint:e.forPrint},s=this.buildViewPropTransformers(t.viewPropsTransformers);for(let i of s)Object.assign(r,i.transform(r,e));let o=n.component;return(0,i.n)(o,Object.assign({},r))}}function ce(e,t,n,i,s,o){let a=n.build(s,void 0,!1),l=n.buildPrev(t,i,!1),c=n.buildNext(t,i,!1);return{title:o,activeButton:e.type,navUnit:e.singleUnit,isTodayEnabled:a.isValid&&!(0,r.H)(t.currentRange,s),isPrevEnabled:l.isValid,isNextEnabled:c.isValid}}function ue(e){return e.map((e=>new e))}class de extends r.a9{constructor(e,t={}){super(),this.isRendering=!1,this.isRendered=!1,this.currentClassNames=[],this.customContentRenderId=0,this.handleAction=e=>{switch(e.type){case"SET_EVENT_DRAG":case"SET_EVENT_RESIZE":this.renderRunner.tryDrain()}},this.handleData=e=>{this.currentData=e,this.renderRunner.request(e.calendarOptions.rerenderDelay)},this.handleRenderRequest=()=>{if(this.isRendering){this.isRendered=!0;let{currentData:e}=this;(0,r.aa)((()=>{(0,i.XX)((0,i.n)(r.ab,{options:e.calendarOptions,theme:e.theme,emitter:e.emitter},((t,n,s,o)=>(this.setClassNames(t),this.setHeight(n),(0,i.n)(r.ac.Provider,{value:this.customContentRenderId},(0,i.n)(le,Object.assign({isHeightAuto:s,forPrint:o},e)))))),this.el)}))}else this.isRendered&&(this.isRendered=!1,(0,i.XX)(null,this.el),this.setClassNames([]),this.setHeight(""))},(0,r.ad)(e),this.el=e,this.renderRunner=new r.D(this.handleRenderRequest),new G({optionOverrides:t,calendarApi:this,onAction:this.handleAction,onData:this.handleData})}render(){let e=this.isRendering;e?this.customContentRenderId+=1:this.isRendering=!0,this.renderRunner.request(),e&&this.updateSize()}destroy(){this.isRendering&&(this.isRendering=!1,this.renderRunner.request())}updateSize(){(0,r.aa)((()=>{super.updateSize()}))}batchRendering(e){this.renderRunner.pause("batchRendering"),e(),this.renderRunner.resume("batchRendering")}pauseRendering(){this.renderRunner.pause("pauseRendering")}resumeRendering(){this.renderRunner.resume("pauseRendering",!0)}resetOptions(e,t){this.currentDataManager.resetOptions(e,t)}setClassNames(e){if(!(0,r.i)(e,this.currentClassNames)){let{classList:t}=this.el;for(let e of this.currentClassNames)t.remove(e);for(let n of e)t.add(n);this.currentClassNames=e}}setHeight(e){(0,r.ae)(this.el,"height",e)}}},29174:(e,t,n)=>{"use strict";n.d(t,{$:()=>p,A:()=>_e,B:()=>bt,C:()=>wt,D:()=>h,E:()=>tt,F:()=>Dn,G:()=>Ut,H:()=>Pt,I:()=>nn,J:()=>Yt,K:()=>gn,L:()=>yn,M:()=>Ge,N:()=>He,O:()=>Ue,P:()=>je,Q:()=>Le,R:()=>Ve,S:()=>ut,T:()=>dt,U:()=>Lt,V:()=>mt,W:()=>cn,X:()=>En,Y:()=>Dt,Z:()=>or,_:()=>Bn,a:()=>Je,a0:()=>On,a1:()=>_,a2:()=>S,a3:()=>yt,a4:()=>vt,a5:()=>A,a6:()=>ar,a7:()=>cr,a8:()=>jt,a9:()=>ur,aA:()=>Ht,aE:()=>hr,aF:()=>dr,aG:()=>fr,aH:()=>pr,aI:()=>gr,aO:()=>f,aP:()=>v,aR:()=>b,aV:()=>tn,aY:()=>vr,aa:()=>ht,ab:()=>sr,ac:()=>Tt,ad:()=>l,ae:()=>y,ar:()=>M,as:()=>N,at:()=>P,au:()=>B,av:()=>U,aw:()=>I,ax:()=>k,b:()=>Rt,b$:()=>wi,b0:()=>_r,b2:()=>w,b3:()=>Rr,b5:()=>kr,b6:()=>Or,b9:()=>Nt,bA:()=>Hr,bB:()=>Ur,bC:()=>Yr,bD:()=>Fr,bE:()=>jr,bF:()=>Lr,bG:()=>lr,bH:()=>Vr,bI:()=>Gr,bK:()=>ei,bO:()=>ni,bP:()=>Nn,bQ:()=>Fn,bR:()=>Yn,bS:()=>Vn,bT:()=>qn,bU:()=>Qn,bV:()=>ri,bW:()=>ii,bX:()=>wn,bZ:()=>oi,b_:()=>ai,ba:()=>Ir,bb:()=>Nr,bc:()=>Pr,bd:()=>Br,be:()=>zr,bf:()=>Kn,bg:()=>ie,bh:()=>ne,bi:()=>se,bl:()=>oe,bo:()=>Z,bp:()=>q,bs:()=>K,bt:()=>J,bu:()=>De,bv:()=>ye,bw:()=>ve,bx:()=>be,c:()=>$,ca:()=>_i,cb:()=>Ti,cc:()=>Si,cf:()=>mi,ch:()=>Jr,cj:()=>xi,ck:()=>Oi,cl:()=>Ii,cm:()=>Mi,cn:()=>Ci,co:()=>zi,cp:()=>Pi,cq:()=>Hi,cr:()=>Li,cs:()=>Vi,ct:()=>xt,cu:()=>_n,cw:()=>a,cy:()=>Zi,d:()=>V,e:()=>Ye,f:()=>$e,g:()=>O,h:()=>Ke,i:()=>ee,j:()=>pn,k:()=>Y,l:()=>Jn,m:()=>Xe,n:()=>Qe,o:()=>It,p:()=>fn,q:()=>le,r:()=>nr,s:()=>Q,t:()=>re,u:()=>er,v:()=>et,w:()=>In,x:()=>ze,y:()=>ae,z:()=>Ee});var r=n(50172),i=n(81098);const s=[],o=new Map;function a(e){s.push(e),o.forEach((t=>{u(t,e)}))}function l(e){e.isConnected&&e.getRootNode&&c(e.getRootNode())}function c(e){let t=o.get(e);if(!t||!t.isConnected){if(t=e.querySelector("style[data-fullcalendar]"),!t){t=document.createElement("style"),t.setAttribute("data-fullcalendar","");const n=function(){void 0===d&&(d=function(){const e=document.querySelector('meta[name="csp-nonce"]');if(e&&e.hasAttribute("content"))return e.getAttribute("content");const t=document.querySelector("script[nonce]");if(t)return t.nonce||"";return""}());return d}();n&&(t.nonce=n);const r=e===document?document.head:e,i=e===document?r.querySelector("script,link[rel=stylesheet],link[as=style],style"):r.firstChild;r.insertBefore(t,i)}o.set(e,t),function(e){for(const t of s)u(e,t)}(t)}}function u(e,t){const{sheet:n}=e,r=n.cssRules.length;t.split("}").forEach(((e,t)=>{(e=e.trim())&&n.insertRule(e+"}",r+t)}))}let d;"undefined"!=typeof document&&c(document);a(':root{--fc-small-font-size:.85em;--fc-page-bg-color:#fff;--fc-neutral-bg-color:hsla(0,0%,82%,.3);--fc-neutral-text-color:grey;--fc-border-color:#ddd;--fc-button-text-color:#fff;--fc-button-bg-color:#2c3e50;--fc-button-border-color:#2c3e50;--fc-button-hover-bg-color:#1e2b37;--fc-button-hover-border-color:#1a252f;--fc-button-active-bg-color:#1a252f;--fc-button-active-border-color:#151e27;--fc-event-bg-color:#3788d8;--fc-event-border-color:#3788d8;--fc-event-text-color:#fff;--fc-event-selected-overlay-color:rgba(0,0,0,.25);--fc-more-link-bg-color:#d0d0d0;--fc-more-link-text-color:inherit;--fc-event-resizer-thickness:8px;--fc-event-resizer-dot-total-width:8px;--fc-event-resizer-dot-border-width:1px;--fc-non-business-color:hsla(0,0%,84%,.3);--fc-bg-event-color:#8fdf82;--fc-bg-event-opacity:0.3;--fc-highlight-color:rgba(188,232,241,.3);--fc-today-bg-color:rgba(255,220,40,.15);--fc-now-indicator-color:red}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc{display:flex;flex-direction:column;font-size:1em}.fc,.fc *,.fc :after,.fc :before{box-sizing:border-box}.fc table{border-collapse:collapse;border-spacing:0;font-size:1em}.fc th{text-align:center}.fc td,.fc th{padding:0;vertical-align:top}.fc a[data-navlink]{cursor:pointer}.fc a[data-navlink]:hover{text-decoration:underline}.fc-direction-ltr{direction:ltr;text-align:left}.fc-direction-rtl{direction:rtl;text-align:right}.fc-theme-standard td,.fc-theme-standard th{border:1px solid var(--fc-border-color)}.fc-liquid-hack td,.fc-liquid-hack th{position:relative}@font-face{font-family:fcicons;font-style:normal;font-weight:400;src:url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBfAAAAC8AAAAYGNtYXAXVtKNAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5ZgYydxIAAAF4AAAFNGhlYWQUJ7cIAAAGrAAAADZoaGVhB20DzAAABuQAAAAkaG10eCIABhQAAAcIAAAALGxvY2ED4AU6AAAHNAAAABhtYXhwAA8AjAAAB0wAAAAgbmFtZXsr690AAAdsAAABhnBvc3QAAwAAAAAI9AAAACAAAwPAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpBgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6Qb//f//AAAAAAAg6QD//f//AAH/4xcEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAWIAjQKeAskAEwAAJSc3NjQnJiIHAQYUFwEWMjc2NCcCnuLiDQ0MJAz/AA0NAQAMJAwNDcni4gwjDQwM/wANIwz/AA0NDCMNAAAAAQFiAI0CngLJABMAACUBNjQnASYiBwYUHwEHBhQXFjI3AZ4BAA0N/wAMJAwNDeLiDQ0MJAyNAQAMIw0BAAwMDSMM4uINIwwNDQAAAAIA4gC3Ax4CngATACcAACUnNzY0JyYiDwEGFB8BFjI3NjQnISc3NjQnJiIPAQYUHwEWMjc2NCcB87e3DQ0MIw3VDQ3VDSMMDQ0BK7e3DQ0MJAzVDQ3VDCQMDQ3zuLcMJAwNDdUNIwzWDAwNIwy4twwkDA0N1Q0jDNYMDA0jDAAAAgDiALcDHgKeABMAJwAAJTc2NC8BJiIHBhQfAQcGFBcWMjchNzY0LwEmIgcGFB8BBwYUFxYyNwJJ1Q0N1Q0jDA0Nt7cNDQwjDf7V1Q0N1QwkDA0Nt7cNDQwkDLfWDCMN1Q0NDCQMt7gMIw0MDNYMIw3VDQ0MJAy3uAwjDQwMAAADAFUAAAOrA1UAMwBoAHcAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMhMjY1NCYjISIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAAVYRGRkR/qoRGRkRA1UFBAUOCQkVDAsZDf2rDRkLDBUJCA4FBQUFBQUOCQgVDAsZDQJVDRkLDBUJCQ4FBAVVAgECBQMCBwQECAX9qwQJAwQHAwMFAQICAgIBBQMDBwQDCQQCVQUIBAQHAgMFAgEC/oAZEhEZGRESGQAAAAADAFUAAAOrA1UAMwBoAIkAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMzFRQWMzI2PQEzMjY1NCYrATU0JiMiBh0BIyIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAgBkSEhmAERkZEYAZEhIZgBEZGREDVQUEBQ4JCRUMCxkN/asNGQsMFQkIDgUFBQUFBQ4JCBUMCxkNAlUNGQsMFQkJDgUEBVUCAQIFAwIHBAQIBf2rBAkDBAcDAwUBAgICAgEFAwMHBAMJBAJVBQgEBAcCAwUCAQL+gIASGRkSgBkSERmAEhkZEoAZERIZAAABAOIAjQMeAskAIAAAExcHBhQXFjI/ARcWMjc2NC8BNzY0JyYiDwEnJiIHBhQX4uLiDQ0MJAzi4gwkDA0N4uINDQwkDOLiDCQMDQ0CjeLiDSMMDQ3h4Q0NDCMN4uIMIw0MDOLiDAwNIwwAAAABAAAAAQAAa5n0y18PPPUACwQAAAAAANivOVsAAAAA2K85WwAAAAADqwNVAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAOrAAEAAAAAAAAAAAAAAAAAAAALBAAAAAAAAAAAAAAAAgAAAAQAAWIEAAFiBAAA4gQAAOIEAABVBAAAVQQAAOIAAAAAAAoAFAAeAEQAagCqAOoBngJkApoAAQAAAAsAigADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAcAAAABAAAAAAACAAcAYAABAAAAAAADAAcANgABAAAAAAAEAAcAdQABAAAAAAAFAAsAFQABAAAAAAAGAAcASwABAAAAAAAKABoAigADAAEECQABAA4ABwADAAEECQACAA4AZwADAAEECQADAA4APQADAAEECQAEAA4AfAADAAEECQAFABYAIAADAAEECQAGAA4AUgADAAEECQAKADQApGZjaWNvbnMAZgBjAGkAYwBvAG4Ac1ZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMGZjaWNvbnMAZgBjAGkAYwBvAG4Ac2ZjaWNvbnMAZgBjAGkAYwBvAG4Ac1JlZ3VsYXIAUgBlAGcAdQBsAGEAcmZjaWNvbnMAZgBjAGkAYwBvAG4Ac0ZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") format("truetype")}.fc-icon{speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;font-family:fcicons!important;font-style:normal;font-variant:normal;font-weight:400;height:1em;line-height:1;text-align:center;text-transform:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:1em}.fc-icon-chevron-left:before{content:"\\e900"}.fc-icon-chevron-right:before{content:"\\e901"}.fc-icon-chevrons-left:before{content:"\\e902"}.fc-icon-chevrons-right:before{content:"\\e903"}.fc-icon-minus-square:before{content:"\\e904"}.fc-icon-plus-square:before{content:"\\e905"}.fc-icon-x:before{content:"\\e906"}.fc .fc-button{border-radius:0;font-family:inherit;font-size:inherit;line-height:inherit;margin:0;overflow:visible;text-transform:none}.fc .fc-button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.fc .fc-button{-webkit-appearance:button}.fc .fc-button:not(:disabled){cursor:pointer}.fc .fc-button{background-color:transparent;border:1px solid transparent;border-radius:.25em;display:inline-block;font-size:1em;font-weight:400;line-height:1.5;padding:.4em .65em;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle}.fc .fc-button:hover{text-decoration:none}.fc .fc-button:focus{box-shadow:0 0 0 .2rem rgba(44,62,80,.25);outline:0}.fc .fc-button:disabled{opacity:.65}.fc .fc-button-primary{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:hover{background-color:var(--fc-button-hover-bg-color);border-color:var(--fc-button-hover-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:disabled{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button-primary:not(:disabled).fc-button-active,.fc .fc-button-primary:not(:disabled):active{background-color:var(--fc-button-active-bg-color);border-color:var(--fc-button-active-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:not(:disabled).fc-button-active:focus,.fc .fc-button-primary:not(:disabled):active:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button .fc-icon{font-size:1.5em;vertical-align:middle}.fc .fc-button-group{display:inline-flex;position:relative;vertical-align:middle}.fc .fc-button-group>.fc-button{flex:1 1 auto;position:relative}.fc .fc-button-group>.fc-button.fc-button-active,.fc .fc-button-group>.fc-button:active,.fc .fc-button-group>.fc-button:focus,.fc .fc-button-group>.fc-button:hover{z-index:1}.fc-direction-ltr .fc-button-group>.fc-button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0;margin-left:-1px}.fc-direction-ltr .fc-button-group>.fc-button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.fc-direction-rtl .fc-button-group>.fc-button:not(:first-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.fc-direction-rtl .fc-button-group>.fc-button:not(:last-child){border-bottom-left-radius:0;border-top-left-radius:0}.fc .fc-toolbar{align-items:center;display:flex;justify-content:space-between}.fc .fc-toolbar.fc-header-toolbar{margin-bottom:1.5em}.fc .fc-toolbar.fc-footer-toolbar{margin-top:1.5em}.fc .fc-toolbar-title{font-size:1.75em;margin:0}.fc-direction-ltr .fc-toolbar>*>:not(:first-child){margin-left:.75em}.fc-direction-rtl .fc-toolbar>*>:not(:first-child){margin-right:.75em}.fc-direction-rtl .fc-toolbar-ltr{flex-direction:row-reverse}.fc .fc-scroller{-webkit-overflow-scrolling:touch;position:relative}.fc .fc-scroller-liquid{height:100%}.fc .fc-scroller-liquid-absolute{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-scroller-harness{direction:ltr;overflow:hidden;position:relative}.fc .fc-scroller-harness-liquid{height:100%}.fc-direction-rtl .fc-scroller-harness>.fc-scroller{direction:rtl}.fc-theme-standard .fc-scrollgrid{border:1px solid var(--fc-border-color)}.fc .fc-scrollgrid,.fc .fc-scrollgrid table{table-layout:fixed;width:100%}.fc .fc-scrollgrid table{border-left-style:hidden;border-right-style:hidden;border-top-style:hidden}.fc .fc-scrollgrid{border-bottom-width:0;border-collapse:separate;border-right-width:0}.fc .fc-scrollgrid-liquid{height:100%}.fc .fc-scrollgrid-section,.fc .fc-scrollgrid-section table,.fc .fc-scrollgrid-section>td{height:1px}.fc .fc-scrollgrid-section-liquid>td{height:100%}.fc .fc-scrollgrid-section>*{border-left-width:0;border-top-width:0}.fc .fc-scrollgrid-section-footer>*,.fc .fc-scrollgrid-section-header>*{border-bottom-width:0}.fc .fc-scrollgrid-section-body table,.fc .fc-scrollgrid-section-footer table{border-bottom-style:hidden}.fc .fc-scrollgrid-section-sticky>*{background:var(--fc-page-bg-color);position:sticky;z-index:3}.fc .fc-scrollgrid-section-header.fc-scrollgrid-section-sticky>*{top:0}.fc .fc-scrollgrid-section-footer.fc-scrollgrid-section-sticky>*{bottom:0}.fc .fc-scrollgrid-sticky-shim{height:1px;margin-bottom:-1px}.fc-sticky{position:sticky}.fc .fc-view-harness{flex-grow:1;position:relative}.fc .fc-view-harness-active>.fc-view{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-col-header-cell-cushion{display:inline-block;padding:2px 4px}.fc .fc-bg-event,.fc .fc-highlight,.fc .fc-non-business{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-non-business{background:var(--fc-non-business-color)}.fc .fc-bg-event{background:var(--fc-bg-event-color);opacity:var(--fc-bg-event-opacity)}.fc .fc-bg-event .fc-event-title{font-size:var(--fc-small-font-size);font-style:italic;margin:.5em}.fc .fc-highlight{background:var(--fc-highlight-color)}.fc .fc-cell-shaded,.fc .fc-day-disabled{background:var(--fc-neutral-bg-color)}a.fc-event,a.fc-event:hover{text-decoration:none}.fc-event.fc-event-draggable,.fc-event[href]{cursor:pointer}.fc-event .fc-event-main{position:relative;z-index:2}.fc-event-dragging:not(.fc-event-selected){opacity:.75}.fc-event-dragging.fc-event-selected{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-event .fc-event-resizer{display:none;position:absolute;z-index:4}.fc-event-selected .fc-event-resizer,.fc-event:hover .fc-event-resizer{display:block}.fc-event-selected .fc-event-resizer{background:var(--fc-page-bg-color);border-color:inherit;border-radius:calc(var(--fc-event-resizer-dot-total-width)/2);border-style:solid;border-width:var(--fc-event-resizer-dot-border-width);height:var(--fc-event-resizer-dot-total-width);width:var(--fc-event-resizer-dot-total-width)}.fc-event-selected .fc-event-resizer:before{bottom:-20px;content:"";left:-20px;position:absolute;right:-20px;top:-20px}.fc-event-selected,.fc-event:focus{box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event-selected:before,.fc-event:focus:before{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:3}.fc-event-selected:after,.fc-event:focus:after{background:var(--fc-event-selected-overlay-color);bottom:-1px;content:"";left:-1px;position:absolute;right:-1px;top:-1px;z-index:1}.fc-h-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-h-event .fc-event-main{color:var(--fc-event-text-color)}.fc-h-event .fc-event-main-frame{display:flex}.fc-h-event .fc-event-time{max-width:100%;overflow:hidden}.fc-h-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-width:0}.fc-h-event .fc-event-title{display:inline-block;left:0;max-width:100%;overflow:hidden;right:0;vertical-align:top}.fc-h-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-start),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-end){border-bottom-left-radius:0;border-left-width:0;border-top-left-radius:0}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-end),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-start){border-bottom-right-radius:0;border-right-width:0;border-top-right-radius:0}.fc-h-event:not(.fc-event-selected) .fc-event-resizer{bottom:0;top:0;width:var(--fc-event-resizer-thickness)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end{cursor:w-resize;left:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start{cursor:e-resize;right:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-h-event.fc-event-selected .fc-event-resizer{margin-top:calc(var(--fc-event-resizer-dot-total-width)*-.5);top:50%}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-start,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-end{left:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-end,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-start{right:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc .fc-popover{box-shadow:0 2px 6px rgba(0,0,0,.15);position:absolute;z-index:9999}.fc .fc-popover-header{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:3px 4px}.fc .fc-popover-title{margin:0 2px}.fc .fc-popover-close{cursor:pointer;font-size:1.1em;opacity:.65}.fc-theme-standard .fc-popover{background:var(--fc-page-bg-color);border:1px solid var(--fc-border-color)}.fc-theme-standard .fc-popover-header{background:var(--fc-neutral-bg-color)}');class h{constructor(e){this.drainedOption=e,this.isRunning=!1,this.isDirty=!1,this.pauseDepths={},this.timeoutId=0}request(e){this.isDirty=!0,this.isPaused()||(this.clearTimeout(),null==e?this.tryDrain():this.timeoutId=setTimeout(this.tryDrain.bind(this),e))}pause(e=""){let{pauseDepths:t}=this;t[e]=(t[e]||0)+1,this.clearTimeout()}resume(e="",t){let{pauseDepths:n}=this;if(e in n){if(t)delete n[e];else{n[e]-=1,n[e]<=0&&delete n[e]}this.tryDrain()}}isPaused(){return Object.keys(this.pauseDepths).length}tryDrain(){if(!this.isRunning&&!this.isPaused()){for(this.isRunning=!0;this.isDirty;)this.isDirty=!1,this.drained();this.isRunning=!1}}clear(){this.clearTimeout(),this.isDirty=!1,this.pauseDepths={}}clearTimeout(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=0)}drained(){this.drainedOption&&this.drainedOption()}}function f(e){e.parentNode&&e.parentNode.removeChild(e)}function p(e,t){if(e.closest)return e.closest(t);if(!document.documentElement.contains(e))return null;do{if(g(e,t))return e;e=e.parentElement||e.parentNode}while(null!==e&&1===e.nodeType);return null}function g(e,t){return(e.matches||e.matchesSelector||e.msMatchesSelector).call(e,t)}const m=/(top|left|right|bottom|width|height)$/i;function v(e,t){for(let n in t)y(e,n,t[n])}function y(e,t,n){null==n?e.style[t]="":"number"==typeof n&&m.test(t)?e.style[t]=`${n}px`:e.style[t]=n}function b(e){var t,n;return null!==(n=null===(t=e.composedPath)||void 0===t?void 0:t.call(e)[0])&&void 0!==n?n:e.target}let D=0;function A(){return D+=1,"fc-dom-"+D}function E(e){e.preventDefault()}function _(e,t,n,r){let i=function(e,t){return n=>{let r=p(n.target,e);r&&t.call(r,n,r)}}(n,r);return e.addEventListener(t,i),()=>{e.removeEventListener(t,i)}}function S(e,t,n,r){let i;return _(e,"mouseover",t,((e,t)=>{if(t!==i){i=t,n(e,t);let s=e=>{i=null,r(e,t),t.removeEventListener("mouseleave",s)};t.addEventListener("mouseleave",s)}}))}const T=["webkitTransitionEnd","otransitionend","oTransitionEnd","msTransitionEnd","transitionend"];function w(e,t){let n=r=>{t(r),T.forEach((t=>{e.removeEventListener(t,n)}))};T.forEach((t=>{e.addEventListener(t,n)}))}function C(e){return Object.assign({onClick:e},x(e))}function x(e){return{tabIndex:0,onKeyDown(t){"Enter"!==t.key&&" "!==t.key||(e(t),t.preventDefault())}}}let R=0;function O(){return R+=1,String(R)}function k(){document.body.classList.add("fc-not-allowed")}function I(){document.body.classList.remove("fc-not-allowed")}function M(e){e.style.userSelect="none",e.style.webkitUserSelect="none",e.addEventListener("selectstart",E)}function N(e){e.style.userSelect="",e.style.webkitUserSelect="",e.removeEventListener("selectstart",E)}function P(e){e.addEventListener("contextmenu",E)}function B(e){e.removeEventListener("contextmenu",E)}function z(e,t,n){return n.func?n.func(e,t):function(e,t){if(!e&&!t)return 0;if(null==t)return-1;if(null==e)return 1;if("string"==typeof e||"string"==typeof t)return String(e).localeCompare(String(t));return e-t}(e[n.field],t[n.field])*(n.order||1)}function H(e,t){let n=String(e);return"000".substr(0,t-n.length)+n}function Y(e,t,n){return"function"==typeof e?e(...t):"string"==typeof e?t.reduce(((e,t,n)=>e.replace("$"+n,t||"")),e):n}function U(e,t){return e-t}function j(e){return e%1==0}function L(e){let t=e.querySelector(".fc-scrollgrid-shrink-frame"),n=e.querySelector(".fc-scrollgrid-shrink-cushion");if(!t)throw new Error("needs fc-scrollgrid-shrink-frame className");if(!n)throw new Error("needs fc-scrollgrid-shrink-cushion className");return e.getBoundingClientRect().width-t.getBoundingClientRect().width+n.getBoundingClientRect().width}const W=["years","months","days","milliseconds"],F=/^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;function V(e,t){return"string"==typeof e?function(e){let t=F.exec(e);if(t){let e=t[1]?-1:1;return{years:0,months:0,days:e*(t[2]?parseInt(t[2],10):0),milliseconds:e*(60*(t[3]?parseInt(t[3],10):0)*60*1e3+60*(t[4]?parseInt(t[4],10):0)*1e3+1e3*(t[5]?parseInt(t[5],10):0)+(t[6]?parseInt(t[6],10):0))}}return null}(e):"object"==typeof e&&e?G(e):"number"==typeof e?G({[t||"milliseconds"]:e}):null}function G(e){let t={years:e.years||e.year||0,months:e.months||e.month||0,days:e.days||e.day||0,milliseconds:60*(e.hours||e.hour||0)*60*1e3+60*(e.minutes||e.minute||0)*1e3+1e3*(e.seconds||e.second||0)+(e.milliseconds||e.millisecond||e.ms||0)},n=e.weeks||e.week;return n&&(t.days+=7*n,t.specifiedWeeks=!0),t}function q(e,t){return{years:e.years+t.years,months:e.months+t.months,days:e.days+t.days,milliseconds:e.milliseconds+t.milliseconds}}function Q(e,t){return{years:e.years-t.years,months:e.months-t.months,days:e.days-t.days,milliseconds:e.milliseconds-t.milliseconds}}function Z(e,t){return{years:e.years*t,months:e.months*t,days:e.days*t,milliseconds:e.milliseconds*t}}function X(e){return K(e)/864e5}function K(e){return 31536e6*e.years+2592e6*e.months+864e5*e.days+e.milliseconds}function J(e,t){let n=null;for(let r=0;r10&&(null==t?r=r.replace("Z",""):0!==t&&(r=r.replace("Z",Ae(t,!0)))),r}function ye(e){return e.toISOString().replace(/T.*$/,"")}function be(e){return e.toISOString().match(/^\d{4}-\d{2}/)[0]}function De(e){return H(e.getUTCHours(),2)+":"+H(e.getUTCMinutes(),2)+":"+H(e.getUTCSeconds(),2)}function Ae(e,t=!1){let n=e<0?"-":"+",r=Math.abs(e),i=Math.floor(r/60),s=Math.round(r%60);return t?`${n+H(i,2)}:${H(s,2)}`:`GMT${n}${i}${s?`:${H(s,2)}`:""}`}function Ee(e,t,n){let r,i;return function(...s){if(r){if(!ee(r,s)){n&&n(i);let r=e.apply(this,s);t&&t(r,i)||(i=r)}}else i=e.apply(this,s);return r=s,i}}function _e(e,t,n){let r,i;return s=>{if(r){if(!tt(r,s)){n&&n(i);let r=e.call(this,s);t&&t(r,i)||(i=r)}}else i=e.call(this,s);return r=s,i}}const Se={week:3,separator:0,omitZeroMinute:0,meridiem:0,omitCommas:0},Te={timeZoneName:7,era:6,year:5,month:4,day:2,weekday:2,hour:1,minute:1,second:1},we=/\s*([ap])\.?m\.?/i,Ce=/,/g,xe=/\s+/g,Re=/\u200e/g,Oe=/UTC|GMT/;class ke{constructor(e){let t={},n={},r=0;for(let i in e)i in Se?(n[i]=e[i],r=Math.max(Se[i],r)):(t[i]=e[i],i in Te&&(r=Math.max(Te[i],r)));this.standardDateProps=t,this.extendedSettings=n,this.severity=r,this.buildFormattingFunc=Ee(Ie)}format(e,t){return this.buildFormattingFunc(this.standardDateProps,this.extendedSettings,t)(e)}formatRange(e,t,n,r){let{standardDateProps:i,extendedSettings:s}=this,o=function(e,t,n){if(n.getMarkerYear(e)!==n.getMarkerYear(t))return 5;if(n.getMarkerMonth(e)!==n.getMarkerMonth(t))return 4;if(n.getMarkerDay(e)!==n.getMarkerDay(t))return 2;if(me(e)!==me(t))return 1;return 0}(e.marker,t.marker,n.calendarSystem);if(!o)return this.format(e,n);let a=o;!(a>1)||"numeric"!==i.year&&"2-digit"!==i.year||"numeric"!==i.month&&"2-digit"!==i.month||"numeric"!==i.day&&"2-digit"!==i.day||(a=1);let l=this.format(e,n),c=this.format(t,n);if(l===c)return l;let u=Ie(function(e,t){let n={};for(let r in e)(!(r in Te)||Te[r]<=t)&&(n[r]=e[r]);return n}(i,a),s,n),d=u(e),h=u(t),f=function(e,t,n,r){let i=0;for(;iAe(e.timeZoneOffset):0===r&&t.week?e=>function(e,t,n,r,i){let s=[];"long"===i?s.push(n):"short"!==i&&"narrow"!==i||s.push(t);"long"!==i&&"short"!==i||s.push(" ");s.push(r.simpleNumberFormat.format(e)),"rtl"===r.options.direction&&s.reverse();return s.join("")}(n.computeWeekNumber(e.marker),n.weekText,n.weekTextLong,n.locale,t.week):function(e,t,n){e=Object.assign({},e),t=Object.assign({},t),function(e,t){e.timeZoneName&&(e.hour||(e.hour="2-digit"),e.minute||(e.minute="2-digit"));"long"===e.timeZoneName&&(e.timeZoneName="short");t.omitZeroMinute&&(e.second||e.millisecond)&&delete t.omitZeroMinute}(e,t),e.timeZone="UTC";let r,i=new Intl.DateTimeFormat(n.locale.codes,e);if(t.omitZeroMinute){let t=Object.assign({},e);delete t.minute,r=new Intl.DateTimeFormat(n.locale.codes,t)}return s=>{let o,{marker:a}=s;return o=r&&!a.getUTCMinutes()?r:i,function(e,t,n,r,i){e=e.replace(Re,""),"short"===n.timeZoneName&&(e=function(e,t){let n=!1;e=e.replace(Oe,(()=>(n=!0,t))),n||(e+=` ${t}`);return e}(e,"UTC"===i.timeZone||null==t.timeZoneOffset?"UTC":Ae(t.timeZoneOffset)));r.omitCommas&&(e=e.replace(Ce,"").trim());r.omitZeroMinute&&(e=e.replace(":00",""));!1===r.meridiem?e=e.replace(we,"").trim():"narrow"===r.meridiem?e=e.replace(we,((e,t)=>t.toLocaleLowerCase())):"short"===r.meridiem?e=e.replace(we,((e,t)=>`${t.toLocaleLowerCase()}m`)):"lowercase"===r.meridiem&&(e=e.replace(we,(e=>e.toLocaleLowerCase())));return e=e.replace(xe," "),e=e.trim(),e}(o.format(a),s,e,t,n)}}(e,t,n)}function Me(e,t){let n=t.markerToArray(e.marker);return{marker:e.marker,timeZoneOffset:e.timeZoneOffset,array:n,year:n[0],month:n[1],day:n[2],hour:n[3],minute:n[4],second:n[5],millisecond:n[6]}}function Ne(e,t,n,r){let i=Me(e,n.calendarSystem);return{date:i,start:i,end:t?Me(t,n.calendarSystem):null,timeZone:n.timeZone,localeCodes:n.locale.codes,defaultSeparator:r||n.defaultSeparator}}class Pe{constructor(e){this.cmdStr=e}format(e,t,n){return t.cmdFormatter(this.cmdStr,Ne(e,null,t,n))}formatRange(e,t,n,r){return n.cmdFormatter(this.cmdStr,Ne(e,t,n,r))}}class Be{constructor(e){this.func=e}format(e,t,n){return this.func(Ne(e,null,t,n))}formatRange(e,t,n,r){return this.func(Ne(e,t,n,r))}}function ze(e){return"object"==typeof e&&e?new ke(e):"string"==typeof e?new Pe(e):"function"==typeof e?new Be(e):null}const He={navLinkDayClick:Qe,navLinkWeekClick:Qe,duration:V,bootstrapFontAwesome:Qe,buttonIcons:Qe,customButtons:Qe,defaultAllDayEventDuration:V,defaultTimedEventDuration:V,nextDayThreshold:V,scrollTime:V,scrollTimeReset:Boolean,slotMinTime:V,slotMaxTime:V,dayPopoverFormat:ze,slotDuration:V,snapDuration:V,headerToolbar:Qe,footerToolbar:Qe,defaultRangeSeparator:String,titleRangeSeparator:String,forceEventDuration:Boolean,dayHeaders:Boolean,dayHeaderFormat:ze,dayHeaderClassNames:Qe,dayHeaderContent:Qe,dayHeaderDidMount:Qe,dayHeaderWillUnmount:Qe,dayCellClassNames:Qe,dayCellContent:Qe,dayCellDidMount:Qe,dayCellWillUnmount:Qe,initialView:String,aspectRatio:Number,weekends:Boolean,weekNumberCalculation:Qe,weekNumbers:Boolean,weekNumberClassNames:Qe,weekNumberContent:Qe,weekNumberDidMount:Qe,weekNumberWillUnmount:Qe,editable:Boolean,viewClassNames:Qe,viewDidMount:Qe,viewWillUnmount:Qe,nowIndicator:Boolean,nowIndicatorClassNames:Qe,nowIndicatorContent:Qe,nowIndicatorDidMount:Qe,nowIndicatorWillUnmount:Qe,showNonCurrentDates:Boolean,lazyFetching:Boolean,startParam:String,endParam:String,timeZoneParam:String,timeZone:String,locales:Qe,locale:Qe,themeSystem:String,dragRevertDuration:Number,dragScroll:Boolean,allDayMaintainDuration:Boolean,unselectAuto:Boolean,dropAccept:Qe,eventOrder:function(e){let t,n,r=[],i=[];for("string"==typeof e?i=e.split(/\s*,\s*/):"function"==typeof e?i=[e]:Array.isArray(e)&&(i=e),t=0;t=0;i-=1){let s=e[i][r];if("object"==typeof s&&s)t.unshift(s);else if(void 0!==s){n[r]=s;break}}t.length&&(n[r]=Xe(t))}for(let r=e.length-1;r>=0;r-=1){let t=e[r];for(let e in t)e in n||(n[e]=t[e])}return n}function Ke(e,t){let n={};for(let r in e)t(e[r],r)&&(n[r]=e[r]);return n}function Je(e,t){let n={};for(let r in e)n[r]=t(e[r],r);return n}function $e(e){let t={};for(let n of e)t[n]=!0;return t}function et(e){let t=[];for(let n in e)t.push(e[n]);return t}function tt(e,t){if(e===t)return!0;for(let n in e)if(Ze.call(e,n)&&!(n in t))return!1;for(let n in t)if(Ze.call(t,n)&&e[n]!==t[n])return!1;return!0}const nt=/^on[A-Z]/;function rt(e,t){let n=[];for(let r in e)Ze.call(e,r)&&(r in t||n.push(r));for(let r in t)Ze.call(t,r)&&e[r]!==t[r]&&n.push(r);return n}function it(e,t,n={}){if(e===t)return!0;for(let r in t)if(!(r in e)||!st(e[r],t[r],n[r]))return!1;for(let r in e)if(!(r in t))return!1;return!0}function st(e,t,n){return e===t||!0===n||!!n&&n(e,t)}let ot={};var at,lt;at="gregory",lt=class{getMarkerYear(e){return e.getUTCFullYear()}getMarkerMonth(e){return e.getUTCMonth()}getMarkerDay(e){return e.getUTCDate()}arrayToMarker(e){return pe(e)}markerToArray(e){return fe(e)}},ot[at]=lt;const ct=/^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;class ut{constructor(e){let t=this.timeZone=e.timeZone,n="local"!==t&&"UTC"!==t;e.namedTimeZoneImpl&&n&&(this.namedTimeZoneImpl=new e.namedTimeZoneImpl(t)),this.canComputeOffset=Boolean(!n||this.namedTimeZoneImpl),this.calendarSystem=function(e){return new ot[e]}(e.calendarSystem),this.locale=e.locale,this.weekDow=e.locale.week.dow,this.weekDoy=e.locale.week.doy,"ISO"===e.weekNumberCalculation&&(this.weekDow=1,this.weekDoy=4),"number"==typeof e.firstDay&&(this.weekDow=e.firstDay),"function"==typeof e.weekNumberCalculation&&(this.weekNumberFunc=e.weekNumberCalculation),this.weekText=null!=e.weekText?e.weekText:e.locale.options.weekText,this.weekTextLong=(null!=e.weekTextLong?e.weekTextLong:e.locale.options.weekTextLong)||this.weekText,this.cmdFormatter=e.cmdFormatter,this.defaultSeparator=e.defaultSeparator}createMarker(e){let t=this.createMarkerMeta(e);return null===t?null:t.marker}createNowMarker(){return this.canComputeOffset?this.timestampToMarker((new Date).valueOf()):pe(de(new Date))}createMarkerMeta(e){if("string"==typeof e)return this.parse(e);let t=null;return"number"==typeof e?t=this.timestampToMarker(e):e instanceof Date?(e=e.valueOf(),isNaN(e)||(t=this.timestampToMarker(e))):Array.isArray(e)&&(t=pe(e)),null!==t&&ge(t)?{marker:t,isTimeUnspecified:!1,forcedTzo:null}:null}parse(e){let t=function(e){let t=ct.exec(e);if(t){let e=new Date(Date.UTC(Number(t[1]),t[3]?Number(t[3])-1:0,Number(t[5]||1),Number(t[7]||0),Number(t[8]||0),Number(t[10]||0),t[12]?1e3*Number(`0.${t[12]}`):0));if(ge(e)){let n=null;return t[13]&&(n=("-"===t[15]?-1:1)*(60*Number(t[16]||0)+Number(t[18]||0))),{marker:e,isTimeUnspecified:!t[6],timeZoneOffset:n}}}return null}(e);if(null===t)return null;let{marker:n}=t,r=null;return null!==t.timeZoneOffset&&(this.canComputeOffset?n=this.timestampToMarker(n.valueOf()-60*t.timeZoneOffset*1e3):r=t.timeZoneOffset),{marker:n,isTimeUnspecified:t.isTimeUnspecified,forcedTzo:r}}getYear(e){return this.calendarSystem.getMarkerYear(e)}getMonth(e){return this.calendarSystem.getMarkerMonth(e)}getDay(e){return this.calendarSystem.getMarkerDay(e)}add(e,t){let n=this.calendarSystem.markerToArray(e);return n[0]+=t.years,n[1]+=t.months,n[2]+=t.days,n[6]+=t.milliseconds,this.calendarSystem.arrayToMarker(n)}subtract(e,t){let n=this.calendarSystem.markerToArray(e);return n[0]-=t.years,n[1]-=t.months,n[2]-=t.days,n[6]-=t.milliseconds,this.calendarSystem.arrayToMarker(n)}addYears(e,t){let n=this.calendarSystem.markerToArray(e);return n[0]+=t,this.calendarSystem.arrayToMarker(n)}addMonths(e,t){let n=this.calendarSystem.markerToArray(e);return n[1]+=t,this.calendarSystem.arrayToMarker(n)}diffWholeYears(e,t){let{calendarSystem:n}=this;return me(e)===me(t)&&n.getMarkerDay(e)===n.getMarkerDay(t)&&n.getMarkerMonth(e)===n.getMarkerMonth(t)?n.getMarkerYear(t)-n.getMarkerYear(e):null}diffWholeMonths(e,t){let{calendarSystem:n}=this;return me(e)===me(t)&&n.getMarkerDay(e)===n.getMarkerDay(t)?n.getMarkerMonth(t)-n.getMarkerMonth(e)+12*(n.getMarkerYear(t)-n.getMarkerYear(e)):null}greatestWholeUnit(e,t){let n=this.diffWholeYears(e,t);return null!==n?{unit:"year",value:n}:(n=this.diffWholeMonths(e,t),null!==n?{unit:"month",value:n}:(n=function(e,t){let n=ae(e,t);return null!==n&&n%7==0?n/7:null}(e,t),null!==n?{unit:"week",value:n}:(n=ae(e,t),null!==n?{unit:"day",value:n}:(n=function(e,t){return(t.valueOf()-e.valueOf())/36e5}(e,t),j(n)?{unit:"hour",value:n}:(n=function(e,t){return(t.valueOf()-e.valueOf())/6e4}(e,t),j(n)?{unit:"minute",value:n}:(n=function(e,t){return(t.valueOf()-e.valueOf())/1e3}(e,t),j(n)?{unit:"second",value:n}:{unit:"millisecond",value:t.valueOf()-e.valueOf()}))))))}countDurationsBetween(e,t,n){let r;return n.years&&(r=this.diffWholeYears(e,t),null!==r)?r/(X(n)/365):n.months&&(r=this.diffWholeMonths(e,t),null!==r)?r/function(e){return X(e)/30}(n):n.days&&(r=ae(e,t),null!==r)?r/X(n):(t.valueOf()-e.valueOf())/K(n)}startOf(e,t){return"year"===t?this.startOfYear(e):"month"===t?this.startOfMonth(e):"week"===t?this.startOfWeek(e):"day"===t?le(e):"hour"===t?function(e){return pe([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours()])}(e):"minute"===t?function(e){return pe([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes()])}(e):"second"===t?function(e){return pe([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds()])}(e):null}startOfYear(e){return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(e)])}startOfMonth(e){return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(e),this.calendarSystem.getMarkerMonth(e)])}startOfWeek(e){return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(e),this.calendarSystem.getMarkerMonth(e),e.getUTCDate()-(e.getUTCDay()-this.weekDow+7)%7])}computeWeekNumber(e){return this.weekNumberFunc?this.weekNumberFunc(this.toDate(e)):function(e,t,n){let r=e.getUTCFullYear(),i=ce(e,r,t,n);if(i<1)return ce(e,r-1,t,n);let s=ce(e,r+1,t,n);return s>=1?Math.min(i,s):i}(e,this.weekDow,this.weekDoy)}format(e,t,n={}){return t.format({marker:e,timeZoneOffset:null!=n.forcedTzo?n.forcedTzo:this.offsetForMarker(e)},this)}formatRange(e,t,n,r={}){return r.isEndExclusive&&(t=ie(t,-1)),n.formatRange({marker:e,timeZoneOffset:null!=r.forcedStartTzo?r.forcedStartTzo:this.offsetForMarker(e)},{marker:t,timeZoneOffset:null!=r.forcedEndTzo?r.forcedEndTzo:this.offsetForMarker(t)},this,r.defaultSeparator)}formatIso(e,t={}){let n=null;return t.omitTimeZoneOffset||(n=null!=t.forcedTzo?t.forcedTzo:this.offsetForMarker(e)),ve(e,n,t.omitTime)}timestampToMarker(e){return"local"===this.timeZone?pe(de(new Date(e))):"UTC"!==this.timeZone&&this.namedTimeZoneImpl?pe(this.namedTimeZoneImpl.timestampToArray(e)):new Date(e)}offsetForMarker(e){return"local"===this.timeZone?-he(fe(e)).getTimezoneOffset():"UTC"===this.timeZone?0:this.namedTimeZoneImpl?this.namedTimeZoneImpl.offsetForArray(fe(e)):null}toDate(e,t){return"local"===this.timeZone?he(fe(e)):"UTC"===this.timeZone?new Date(e.valueOf()):this.namedTimeZoneImpl?new Date(e.valueOf()-1e3*this.namedTimeZoneImpl.offsetForArray(fe(e))*60):new Date(e.valueOf()-(t||0))}}class dt{constructor(e){this.iconOverrideOption&&this.setIconOverride(e[this.iconOverrideOption])}setIconOverride(e){let t,n;if("object"==typeof e&&e){for(n in t=Object.assign({},this.iconClasses),e)t[n]=this.applyIconOverridePrefix(e[n]);this.iconClasses=t}else!1===e&&(this.iconClasses={})}applyIconOverridePrefix(e){let t=this.iconOverridePrefix;return t&&0!==e.indexOf(t)&&(e=t+e),e}getClass(e){return this.classes[e]||""}getIconClass(e,t){let n;return n=t&&this.rtlIconClasses&&this.rtlIconClasses[e]||this.iconClasses[e],n?`${this.baseIconClass} ${n}`:""}getCustomButtonIconClass(e){let t;return this.iconOverrideCustomButtonOption&&(t=e[this.iconOverrideCustomButtonOption],t)?`${this.baseIconClass} ${this.applyIconOverridePrefix(t)}`:""}}function ht(e){e();let t=r.fF.debounceRendering,n=[];for(r.fF.debounceRendering=function(e){n.push(e)},r.XX(r.n(ft,{}),document.createElement("div"));n.length;)n.shift()();r.fF.debounceRendering=t}dt.prototype.classes={},dt.prototype.iconClasses={},dt.prototype.baseIconClass="",dt.prototype.iconOverridePrefix="";class ft extends r.uA{render(){return r.n("div",{})}componentDidMount(){this.setState({})}}function pt(e){let t=r.q6(e),n=t.Provider;return t.Provider=function(){let e=!this.getChildContext,t=n.apply(this,arguments);if(e){let e=[];this.shouldComponentUpdate=t=>{this.props.value!==t.value&&e.forEach((e=>{e.context=t.value,e.forceUpdate()}))},this.sub=t=>{e.push(t);let n=t.componentWillUnmount;t.componentWillUnmount=()=>{e.splice(e.indexOf(t),1),n&&n.call(t)}}}return t},t}class gt{constructor(e,t,n,r){this.execFunc=e,this.emitter=t,this.scrollTime=n,this.scrollTimeReset=r,this.handleScrollRequest=e=>{this.queuedRequest=Object.assign({},this.queuedRequest||{},e),this.drain()},t.on("_scrollRequest",this.handleScrollRequest),this.fireInitialScroll()}detach(){this.emitter.off("_scrollRequest",this.handleScrollRequest)}update(e){e&&this.scrollTimeReset?this.fireInitialScroll():this.drain()}fireInitialScroll(){this.handleScrollRequest({time:this.scrollTime})}drain(){this.queuedRequest&&this.execFunc(this.queuedRequest)&&(this.queuedRequest=null)}}const mt=pt({});function vt(e,t,n,r,i,s,o,a,l,c,u,d,h){return{dateEnv:i,options:n,pluginHooks:o,emitter:c,dispatch:a,getCurrentData:l,calendarApi:u,viewSpec:e,viewApi:t,dateProfileGenerator:r,theme:s,isRtl:"rtl"===n.direction,addResizeHandler(e){c.on("_resize",e)},removeResizeHandler(e){c.off("_resize",e)},createScrollResponder:e=>new gt(e,c,V(n.scrollTime),n.scrollTimeReset),registerInteractiveComponent:d,unregisterInteractiveComponent:h}}class yt extends r.uA{shouldComponentUpdate(e,t){return this.debug&&console.log(rt(e,this.props),rt(t,this.state)),!it(this.props,e,this.propEquality)||!it(this.state,t,this.stateEquality)}safeSetState(e){it(this.state,Object.assign(Object.assign({},this.state),e),this.stateEquality)||this.setState(e)}}yt.addPropsEquality=function(e){let t=Object.create(this.prototype.propEquality);Object.assign(t,e),this.prototype.propEquality=t},yt.addStateEquality=function(e){let t=Object.create(this.prototype.stateEquality);Object.assign(t,e),this.prototype.stateEquality=t},yt.contextType=mt,yt.prototype.propEquality={},yt.prototype.stateEquality={};class bt extends yt{}function Dt(e,t){"function"==typeof e?e(t):e&&(e.current=t)}bt.contextType=mt;class At extends bt{constructor(){super(...arguments),this.id=O(),this.queuedDomNodes=[],this.currentDomNodes=[],this.handleEl=e=>{const{options:t}=this.context,{generatorName:n}=this.props;t.customRenderingReplaces&&Et(n,t)||this.updateElRef(e)},this.updateElRef=e=>{this.props.elRef&&Dt(this.props.elRef,e)}}render(){const{props:e,context:t}=this,{options:n}=t,{customGenerator:i,defaultGenerator:s,renderProps:o}=e,a=_t(e,[],this.handleEl);let l,c,u=!1,d=[];if(null!=i){const e="function"==typeof i?i(o,r.n):i;if(!0===e)u=!0;else{const t=e&&"object"==typeof e;t&&"html"in e?a.dangerouslySetInnerHTML={__html:e.html}:t&&"domNodes"in e?d=Array.prototype.slice.call(e.domNodes):(t?(0,r.zO)(e):"function"!=typeof e)?l=e:c=e}}else u=!Et(e.generatorName,n);return u&&s&&(l=s(o)),this.queuedDomNodes=d,this.currentGeneratorMeta=c,(0,r.n)(e.elTag,a,l)}componentDidMount(){this.applyQueueudDomNodes(),this.triggerCustomRendering(!0)}componentDidUpdate(){this.applyQueueudDomNodes(),this.triggerCustomRendering(!0)}componentWillUnmount(){this.triggerCustomRendering(!1)}triggerCustomRendering(e){var t;const{props:n,context:r}=this,{handleCustomRendering:i,customRenderingMetaMap:s}=r.options;if(i){const r=null!==(t=this.currentGeneratorMeta)&&void 0!==t?t:null==s?void 0:s[n.generatorName];r&&i(Object.assign(Object.assign({id:this.id,isActive:e,containerEl:this.base,reportNewContainerEl:this.updateElRef,generatorMeta:r},n),{elClasses:(n.elClasses||[]).filter(St)}))}}applyQueueudDomNodes(){const{queuedDomNodes:e,currentDomNodes:t}=this,n=this.base;if(!ee(e,t)){t.forEach(f);for(let t of e)n.appendChild(t);this.currentDomNodes=e}}}function Et(e,t){var n;return Boolean(t.handleCustomRendering&&e&&(null===(n=t.customRenderingMetaMap)||void 0===n?void 0:n[e]))}function _t(e,t,n){const r=Object.assign(Object.assign({},e.elAttrs),{ref:n});return(e.elClasses||t)&&(r.className=(e.elClasses||[]).concat(t||[]).concat(r.className||[]).filter(Boolean).join(" ")),e.elStyle&&(r.style=e.elStyle),r}function St(e){return Boolean(e)}At.addPropsEquality({elClasses:ee,elStyle:tt,elAttrs:function(e,t){const n=rt(e,t);for(let r of n)if(!nt.test(r))return!1;return!0},renderProps:tt});const Tt=pt(0);class wt extends r.uA{constructor(){super(...arguments),this.InnerContent=Ct.bind(void 0,this),this.handleEl=e=>{this.el=e,this.props.elRef&&(Dt(this.props.elRef,e),e&&this.didMountMisfire&&this.componentDidMount())}}render(){const{props:e}=this,t=function(e,t){const n="function"==typeof e?e(t):e||[];return"string"==typeof n?[n]:n}(e.classNameGenerator,e.renderProps);if(e.children){const n=_t(e,t,this.handleEl),i=e.children(this.InnerContent,e.renderProps,n);return e.elTag?(0,r.n)(e.elTag,n,i):i}return(0,r.n)(At,Object.assign(Object.assign({},e),{elRef:this.handleEl,elTag:e.elTag||"div",elClasses:(e.elClasses||[]).concat(t),renderId:this.context}))}componentDidMount(){var e,t;this.el?null===(t=(e=this.props).didMount)||void 0===t||t.call(e,Object.assign(Object.assign({},this.props.renderProps),{el:this.el})):this.didMountMisfire=!0}componentWillUnmount(){var e,t;null===(t=(e=this.props).willUnmount)||void 0===t||t.call(e,Object.assign(Object.assign({},this.props.renderProps),{el:this.el}))}}function Ct(e,t){const n=e.props;return(0,r.n)(At,Object.assign({renderProps:n.renderProps,generatorName:n.generatorName,customGenerator:n.customGenerator,defaultGenerator:n.defaultGenerator,renderId:e.context},t))}wt.contextType=Tt;class xt extends bt{render(){let{props:e,context:t}=this,{options:n}=t,i={view:t.viewApi};return(0,r.n)(wt,Object.assign({},e,{elTag:e.elTag||"div",elClasses:[...Rt(e.viewSpec),...e.elClasses||[]],renderProps:i,classNameGenerator:n.viewClassNames,generatorName:void 0,didMount:n.viewDidMount,willUnmount:n.viewWillUnmount}),(()=>e.children))}}function Rt(e){return[`fc-${e.type}-view`,"fc-view"]}function Ot(e,t){let n,r,i=[],{start:s}=t;for(e.sort(kt),n=0;ns&&i.push({start:s,end:r.start}),r.end>s&&(s=r.end);return st.start)&&(null===e.start||null===t.end||e.start=e.start)&&(null===e.end||null!==t.end&&t.end<=e.end)}function Pt(e,t){return(null===e.start||t>=e.start)&&(null===e.end||t=K(t)&&(r=re(r,1))}return e.start&&(n=le(e.start),r&&r<=n&&(r=re(n,1))),{start:n,end:r}}function Ht(e,t,n,r){return"year"===r?V(n.diffWholeYears(e,t),"year"):"month"===r?V(n.diffWholeMonths(e,t),"month"):function(e,t){let n=le(e),r=le(t);return{years:0,months:0,days:Math.round(oe(n,r)),milliseconds:t.valueOf()-r.valueOf()-(e.valueOf()-n.valueOf())}}(e,t)}function Yt(e,t){return"CHANGE_DATE"===t.type?t.dateMarker:e}function Ut(e,t){let n=e.initialDate;return null!=n?t.createMarker(n):jt(e.now,t)}function jt(e,t){return"function"==typeof e&&(e=e()),null==e?t.createNowMarker():t.createMarker(e)}class Lt{constructor(e){this.props=e,this.nowDate=jt(e.nowInput,e.dateEnv),this.initHiddenDays()}buildPrev(e,t,n){let{dateEnv:r}=this.props,i=r.subtract(r.startOf(t,e.currentRangeUnit),e.dateIncrement);return this.build(i,-1,n)}buildNext(e,t,n){let{dateEnv:r}=this.props,i=r.add(r.startOf(t,e.currentRangeUnit),e.dateIncrement);return this.build(i,1,n)}build(e,t,n=!0){let r,i,s,o,a,l,{props:c}=this;var u,d;return r=this.buildValidRange(),r=this.trimHiddenDays(r),n&&(u=e,e=null!=(d=r).start&&u=d.end?new Date(d.end.valueOf()-1):u),i=this.buildCurrentRangeInfo(e,t),s=/^(year|month|week|day)$/.test(i.unit),o=this.buildRenderRange(this.trimHiddenDays(i.range),i.unit,s),o=this.trimHiddenDays(o),a=o,c.showNonCurrentDates||(a=It(a,i.range)),a=this.adjustActiveRange(a),a=It(a,r),l=Mt(i.range,r),Pt(o,e)||(e=o.start),{currentDate:e,validRange:r,currentRange:i.range,currentRangeUnit:i.unit,isRangeAllDay:s,activeRange:a,renderRange:o,slotMinTime:c.slotMinTime,slotMaxTime:c.slotMaxTime,isValid:l,dateIncrement:this.buildDateIncrement(i.duration)}}buildValidRange(){let e=this.props.validRangeInput,t="function"==typeof e?e.call(this.props.calendarApi,this.nowDate):e;return this.refineRange(t)||{start:null,end:null}}buildCurrentRangeInfo(e,t){let n,{props:r}=this,i=null,s=null,o=null;return r.duration?(i=r.duration,s=r.durationUnit,o=this.buildRangeFromDuration(e,t,i,s)):(n=this.props.dayCount)?(s="day",o=this.buildRangeFromDayCount(e,t,n)):(o=this.buildCustomVisibleRange(e))?s=r.dateEnv.greatestWholeUnit(o.start,o.end).unit:(i=this.getFallbackDuration(),s=$(i).unit,o=this.buildRangeFromDuration(e,t,i,s)),{duration:i,unit:s,range:o}}getFallbackDuration(){return V({day:1})}adjustActiveRange(e){let{dateEnv:t,usesMinMaxTime:n,slotMinTime:r,slotMaxTime:i}=this.props,{start:s,end:o}=e;return n&&(X(r)<0&&(s=le(s),s=t.add(s,r)),X(i)>1&&(o=le(o),o=re(o,-1),o=t.add(o,i))),{start:s,end:o}}buildRangeFromDuration(e,t,n,r){let i,s,o,{dateEnv:a,dateAlignment:l}=this.props;if(!l){let{dateIncrement:e}=this.props;l=e&&K(e)!o[e.defId].recurringDef));for(let l in o){let e=o[l];if(e.recurringDef){let{duration:n}=e.recurringDef;n||(n=e.allDay?s.defaultAllDayEventDuration:s.defaultTimedEventDuration);let o=Vt(e,n,t,r,i.recurringTypes);for(let e of o){let t=Wt(l,{start:e,end:r.add(e,n)});a[t.instanceId]=t}}}return{defs:o,instances:a}}function Vt(e,t,n,r,i){let s=i[e.recurringDef.typeId].expand(e.recurringDef.typeData,{start:r.subtract(n.start,t),end:n.end},r);return e.allDay&&(s=s.map(le)),s}const Gt={id:String,groupId:String,title:String,url:String,interactive:Boolean},qt={start:Qe,end:Qe,date:Qe,allDay:Boolean},Qt=Object.assign(Object.assign(Object.assign({},Gt),qt),{extendedProps:Qe});function Zt(e,t,n,r,i=Kt(n),s,o){let{refined:a,extra:l}=Xt(e,n,i),c=function(e,t){let n=null;e&&(n=e.defaultAllDay);null==n&&(n=t.options.defaultAllDay);return n}(t,n),u=function(e,t,n,r){for(let i=0;i{return n=t,r=e,Boolean(n.groupId&&n.groupId===r.groupId);var n,r}));return r.defs[t.defId]=t,r.instances[n.instanceId]=n,r}return{defs:{},instances:{}}}function nn(){return{defs:{},instances:{}}}function rn(e,t){return{defs:Object.assign(Object.assign({},e.defs),t.defs),instances:Object.assign(Object.assign({},e.instances),t.instances)}}function sn(e,t){let n=Ke(e.defs,t),r=Ke(e.instances,(e=>n[e.defId]));return{defs:n,instances:r}}function on(e){return Array.isArray(e)?e:"string"==typeof e?e.split(/\s+/):[]}const an={display:String,editable:Boolean,startEditable:Boolean,durationEditable:Boolean,constraint:Qe,overlap:Qe,allow:Qe,className:on,classNames:on,color:String,backgroundColor:String,borderColor:String,textColor:String},ln={display:null,startEditable:null,durationEditable:null,constraints:[],overlap:null,allows:[],backgroundColor:"",borderColor:"",textColor:"",classNames:[]};function cn(e,t){let n=function(e,t){return Array.isArray(e)?$t(e,null,t,!0):"object"==typeof e&&e?$t([e],null,t,!0):null!=e?String(e):null}(e.constraint,t);return{display:e.display||null,startEditable:null!=e.startEditable?e.startEditable:e.editable,durationEditable:null!=e.durationEditable?e.durationEditable:e.editable,constraints:null!=n?[n]:[],overlap:null!=e.overlap?e.overlap:null,allows:null!=e.allow?[e.allow]:[],backgroundColor:e.backgroundColor||e.color||"",borderColor:e.borderColor||e.color||"",textColor:e.textColor||"",classNames:(e.className||[]).concat(e.classNames||[])}}function un(e){return e.reduce(dn,ln)}function dn(e,t){return{display:null!=t.display?t.display:e.display,startEditable:null!=t.startEditable?t.startEditable:e.startEditable,durationEditable:null!=t.durationEditable?t.durationEditable:e.durationEditable,constraints:e.constraints.concat(t.constraints),overlap:"boolean"==typeof t.overlap?t.overlap:e.overlap,allows:e.allows.concat(t.allows),backgroundColor:t.backgroundColor||e.backgroundColor,borderColor:t.borderColor||e.borderColor,textColor:t.textColor||e.textColor,classNames:e.classNames.concat(t.classNames)}}const hn={id:String,defaultAllDay:Boolean,url:String,format:String,events:Qe,eventDataTransform:Qe,success:Qe,failure:Qe};function fn(e,t,n=pn(t)){let r;if("string"==typeof e?r={url:e}:"function"==typeof e||Array.isArray(e)?r={events:e}:"object"==typeof e&&e&&(r=e),r){let{refined:i,extra:s}=qe(r,n),o=function(e,t){let n=t.pluginHooks.eventSourceDefs;for(let r=n.length-1;r>=0;r-=1){let t=n[r].parseMeta(e);if(t)return{sourceDefId:r,meta:t}}return null}(i,t);if(o)return{_raw:e,isFetching:!1,latestFetchId:"",fetchRange:null,defaultAllDay:i.defaultAllDay,eventDataTransform:i.eventDataTransform,success:i.success,failure:i.failure,publicId:i.id||"",sourceId:O(),sourceDefId:o.sourceDefId,meta:o.meta,ui:cn(i,t),extendedProps:s}}return null}function pn(e){return Object.assign(Object.assign(Object.assign({},an),hn),e.pluginHooks.eventSourceRefiners)}function gn(e,t,n,r,i){switch(t.type){case"RECEIVE_EVENTS":return function(e,t,n,r,i,s){if(t&&n===t.latestFetchId){let n=$t(mn(i,t,s),t,s);return r&&(n=Ft(n,r,s)),rn(bn(e,t.sourceId),n)}return e}(e,n[t.sourceId],t.fetchId,t.fetchRange,t.rawEvents,i);case"RESET_RAW_EVENTS":return function(e,t,n,r,i){const{defIdMap:s,instanceIdMap:o}=function(e){const{defs:t,instances:n}=e,r={},i={};for(let s in t){const e=t[s],{publicId:n}=e;n&&(r[n]=s)}for(let s in n){const e=t[n[s].defId],{publicId:r}=e;r&&(i[r]=s)}return{defIdMap:r,instanceIdMap:i}}(e);let a=$t(mn(n,t,i),t,i,!1,s,o);return Ft(a,r,i)}(e,n[t.sourceId],t.rawEvents,r.activeRange,i);case"ADD_EVENTS":return function(e,t,n,r){n&&(t=Ft(t,n,r));return rn(e,t)}(e,t.eventStore,r?r.activeRange:null,i);case"RESET_EVENTS":return t.eventStore;case"MERGE_EVENTS":return rn(e,t.eventStore);case"PREV":case"NEXT":case"CHANGE_DATE":case"CHANGE_VIEW_TYPE":return r?Ft(e,r.activeRange,i):e;case"REMOVE_EVENTS":return function(e,t){let{defs:n,instances:r}=e,i={},s={};for(let o in n)t.defs[o]||(i[o]=n[o]);for(let o in r)!t.instances[o]&&i[r[o].defId]&&(s[o]=r[o]);return{defs:i,instances:s}}(e,t.eventStore);case"REMOVE_EVENT_SOURCE":return bn(e,t.sourceId);case"REMOVE_ALL_EVENT_SOURCES":return sn(e,(e=>!e.sourceId));case"REMOVE_ALL_EVENTS":return{defs:{},instances:{}};default:return e}}function mn(e,t,n){let r=n.options.eventDataTransform,i=t?t.eventDataTransform:null;return i&&(e=vn(e,i)),r&&(e=vn(e,r)),e}function vn(e,t){let n;if(t){n=[];for(let r of e){let e=t(r);e?n.push(e):null==e&&n.push(r)}}else n=e;return n}function yn(e,t,n){let{defs:r}=e,i=Je(e.instances,(e=>r[e.defId].allDay?e:Object.assign(Object.assign({},e),{range:{start:n.createMarker(t.toDate(e.range.start,e.forcedStartTzo)),end:n.createMarker(t.toDate(e.range.end,e.forcedEndTzo))},forcedStartTzo:n.canComputeOffset?null:e.forcedStartTzo,forcedEndTzo:n.canComputeOffset?null:e.forcedEndTzo})));return{defs:r,instances:i}}function bn(e,t){return sn(e,(e=>e.sourceId!==t))}class Dn{constructor(){this.handlers={},this.thisContext=null}setThisContext(e){this.thisContext=e}setOptions(e){this.options=e}on(e,t){!function(e,t,n){(e[t]||(e[t]=[])).push(n)}(this.handlers,e,t)}off(e,t){!function(e,t,n){n?e[t]&&(e[t]=e[t].filter((e=>e!==n))):delete e[t]}(this.handlers,e,t)}trigger(e,...t){let n=this.handlers[e]||[],r=this.options&&this.options[e],i=[].concat(r||[],n);for(let s of i)s.apply(this.thisContext,t)}hasHandlers(e){return Boolean(this.handlers[e]&&this.handlers[e].length||this.options&&this.options[e])}}const An={startTime:"09:00",endTime:"17:00",daysOfWeek:[1,2,3,4,5],display:"inverse-background",classNames:"fc-non-business",groupId:"_businessHours"};function En(e,t){return $t(function(e){let t;t=!0===e?[{}]:Array.isArray(e)?e.filter((e=>e.daysOfWeek)):"object"==typeof e&&e?[e]:[];return t=t.map((e=>Object.assign(Object.assign({},An),e))),t}(e),null,t)}function _n(e,t,n){n.emitter.trigger("select",Object.assign(Object.assign({},Sn(e,n)),{jsEvent:t?t.origEvent:null,view:n.viewApi||n.calendarApi.view}))}function Sn(e,t){let n={};for(let s of t.pluginHooks.dateSpanTransforms)Object.assign(n,s(e,t));var r,i;return Object.assign(n,(r=e,i=t.dateEnv,Object.assign(Object.assign({},$n(r.range,i,r.allDay)),{allDay:r.allDay}))),n}function Tn(e,t,n){let{dateEnv:r,options:i}=n,s=t;return e?(s=le(s),s=r.add(s,i.defaultAllDayEventDuration)):s=r.add(s,i.defaultTimedEventDuration),s}function wn(e,t,n,r){let i=zn(e.defs,t),s={defs:{},instances:{}};for(let o in e.defs){let t=e.defs[o];s.defs[o]=Cn(t,i[o],n,r)}for(let o in e.instances){let t=e.instances[o],a=s.defs[t.defId];s.instances[o]=xn(t,a,i[t.defId],n,r)}return s}function Cn(e,t,n,r){let i=n.standardProps||{};null==i.hasEnd&&t.durationEditable&&(n.startDelta||n.endDelta)&&(i.hasEnd=!0);let s=Object.assign(Object.assign(Object.assign({},e),i),{ui:Object.assign(Object.assign({},e.ui),i.ui)});n.extendedProps&&(s.extendedProps=Object.assign(Object.assign({},s.extendedProps),n.extendedProps));for(let o of r.pluginHooks.eventDefMutationAppliers)o(s,n,r);return!s.hasEnd&&r.options.forceEventDuration&&(s.hasEnd=!0),s}function xn(e,t,n,r,i){let{dateEnv:s}=i,o=r.standardProps&&!0===r.standardProps.allDay,a=r.standardProps&&!1===r.standardProps.hasEnd,l=Object.assign({},e);return o&&(l.range=Bt(l.range)),r.datesDelta&&n.startEditable&&(l.range={start:s.add(l.range.start,r.datesDelta),end:s.add(l.range.end,r.datesDelta)}),r.startDelta&&n.durationEditable&&(l.range={start:s.add(l.range.start,r.startDelta),end:l.range.end}),r.endDelta&&n.durationEditable&&(l.range={start:l.range.start,end:s.add(l.range.end,r.endDelta)}),a&&(l.range={start:l.range.start,end:Tn(t.allDay,l.range.start,i)}),t.allDay&&(l.range={start:le(l.range.start),end:le(l.range.end)}),l.range.endHn(e,t)))}function Hn(e,t){let n=[];return t[""]&&n.push(t[""]),t[e.defId]&&n.push(t[e.defId]),n.push(e.ui),un(n)}function Yn(e,t){let n=e.map(Un);return n.sort(((e,n)=>function(e,t,n){let r,i;for(r=0;re._seg))}function Un(e){let{eventRange:t}=e,n=t.def,r=t.instance?t.instance.range:t.range,i=r.start?r.start.valueOf():0,s=r.end?r.end.valueOf():0;return Object.assign(Object.assign(Object.assign({},n.extendedProps),n),{id:n.publicId,start:i,end:s,duration:s-i,allDay:Number(n.allDay),_seg:e})}function jn(e,t){let{pluginHooks:n}=t,r=n.isDraggableTransformers,{def:i,ui:s}=e.eventRange,o=s.startEditable;for(let a of r)o=a(o,i,s,t);return o}function Ln(e,t){return e.isStart&&e.eventRange.ui.durationEditable&&t.options.eventResizableFromStart}function Wn(e,t){return e.isEnd&&e.eventRange.ui.durationEditable}function Fn(e,t,n,r,i,s,o){let{dateEnv:a,options:l}=n,{displayEventTime:c,displayEventEnd:u}=l,d=e.eventRange.def,h=e.eventRange.instance;null==c&&(c=!1!==r),null==u&&(u=!1!==i);let f=h.range.start,p=h.range.end,g=s||e.start||e.eventRange.range.start,m=o||e.end||e.eventRange.range.end,v=le(f).valueOf()===le(g).valueOf(),y=le(ie(p,-1)).valueOf()===le(ie(m,-1)).valueOf();return c&&!d.allDay&&(v||y)?(g=v?f:g,m=y?p:m,u&&d.hasEnd?a.formatRange(g,m,t,{forcedStartTzo:s?null:h.forcedStartTzo,forcedEndTzo:o?null:h.forcedEndTzo}):a.format(g,t,{forcedTzo:s?null:h.forcedStartTzo})):""}function Vn(e,t,n){let r=e.eventRange.range;return{isPast:r.end<=(n||t.start),isFuture:r.start>=(n||t.end),isToday:t&&Pt(t,r.start)}}function Gn(e){let t=["fc-event"];return e.isMirror&&t.push("fc-event-mirror"),e.isDraggable&&t.push("fc-event-draggable"),(e.isStartResizable||e.isEndResizable)&&t.push("fc-event-resizable"),e.isDragging&&t.push("fc-event-dragging"),e.isResizing&&t.push("fc-event-resizing"),e.isSelected&&t.push("fc-event-selected"),e.isStart&&t.push("fc-event-start"),e.isEnd&&t.push("fc-event-end"),e.isPast&&t.push("fc-event-past"),e.isToday&&t.push("fc-event-today"),e.isFuture&&t.push("fc-event-future"),t}function qn(e){return e.instance?e.instance.instanceId:`${e.def.defId}:${e.range.start.toISOString()}`}function Qn(e,t){let{def:n,instance:r}=e.eventRange,{url:i}=n;if(i)return{href:i};let{emitter:s,options:o}=t,{eventInteractive:a}=o;return null==a&&(a=n.interactive,null==a&&(a=Boolean(s.hasHandlers("eventClick")))),a?x((e=>{s.trigger("eventClick",{el:e.target,event:new On(t,n,r),jsEvent:e,view:t.viewApi})})):{}}const Zn={start:Qe,end:Qe,allDay:Boolean};function Xn(e,t,n){let r=function(e,t){let{refined:n,extra:r}=qe(e,Zn),i=n.start?t.createMarkerMeta(n.start):null,s=n.end?t.createMarkerMeta(n.end):null,{allDay:o}=n;null==o&&(o=i&&i.isTimeUnspecified&&(!s||s.isTimeUnspecified));return Object.assign({range:{start:i?i.marker:null,end:s?s.marker:null},allDay:o},r)}(e,t),{range:i}=r;if(!i.start)return null;if(!i.end){if(null==n)return null;i.end=t.add(i.start,n)}return r}function Kn(e,t){return n=e.range,r=t.range,(null===n.start?null:n.start.valueOf())===(null===r.start?null:r.start.valueOf())&&(null===n.end?null:n.end.valueOf())===(null===r.end?null:r.end.valueOf())&&e.allDay===t.allDay&&function(e,t){for(let n in t)if("range"!==n&&"allDay"!==n&&e[n]!==t[n])return!1;for(let n in e)if(!(n in t))return!1;return!0}(e,t);var n,r}function Jn(e,t,n){return Object.assign(Object.assign({},$n(e,t,n)),{timeZone:t.timeZone})}function $n(e,t,n){return{start:t.toDate(e.start),end:t.toDate(e.end),startStr:t.formatIso(e.start,{omitTime:n}),endStr:t.formatIso(e.end,{omitTime:n})}}function er(e,t,n){let r=!1,i=function(e){r||(r=!0,t(e))},s=function(e){r||(r=!0,n(e))},o=e(i,s);o&&"function"==typeof o.then&&o.then(i,s)}class tr extends Error{constructor(e,t){super(e),this.response=t}}function nr(e,t,n){const r={method:e=e.toUpperCase()};return"GET"===e?t+=(-1===t.indexOf("?")?"?":"&")+new URLSearchParams(n):(r.body=new URLSearchParams(n),r.headers={"Content-Type":"application/x-www-form-urlencoded"}),fetch(t,r).then((e=>{if(e.ok)return e.json().then((t=>[t,e]),(()=>{throw new tr("Failure parsing JSON",e)}));throw new tr("Request failed",e)}))}let rr;function ir(){return null==rr&&(rr=function(){if("undefined"==typeof document)return!0;let e=document.createElement("div");e.style.position="absolute",e.style.top="0px",e.style.left="0px",e.innerHTML="
",e.querySelector("table").style.height="100px",e.querySelector("div").style.height="100%",document.body.appendChild(e);let t=e.querySelector("div").offsetHeight>0;return document.body.removeChild(e),t}()),rr}class sr extends bt{constructor(){super(...arguments),this.state={forPrint:!1},this.handleBeforePrint=()=>{ht((()=>{this.setState({forPrint:!0})}))},this.handleAfterPrint=()=>{ht((()=>{this.setState({forPrint:!1})}))}}render(){let{props:e}=this,{options:t}=e,{forPrint:n}=this.state,r=n||"auto"===t.height||"auto"===t.contentHeight,i=r||null==t.height?"":t.height,s=["fc",n?"fc-media-print":"fc-media-screen",`fc-direction-${t.direction}`,e.theme.getClass("root")];return ir()||s.push("fc-liquid-hack"),e.children(s,i,r,n)}componentDidMount(){let{emitter:e}=this.props;e.on("_beforeprint",this.handleBeforePrint),e.on("_afterprint",this.handleAfterPrint)}componentWillUnmount(){let{emitter:e}=this.props;e.off("_beforeprint",this.handleBeforePrint),e.off("_afterprint",this.handleAfterPrint)}}class or{constructor(e){this.component=e.component,this.isHitComboAllowed=e.isHitComboAllowed||null}destroy(){}}function ar(e,t){return{component:e,el:t.el,useEventCenter:null==t.useEventCenter||t.useEventCenter,isHitComboAllowed:t.isHitComboAllowed||null}}function lr(e){return{[e.component.uid]:e}}const cr={};class ur{getCurrentData(){return this.currentDataManager.getCurrentData()}dispatch(e){this.currentDataManager.dispatch(e)}get view(){return this.getCurrentData().viewApi}batchRendering(e){e()}updateSize(){this.trigger("_resize",!0)}setOption(e,t){this.dispatch({type:"SET_OPTION",optionName:e,rawOptionValue:t})}getOption(e){return this.currentDataManager.currentCalendarOptionsInput[e]}getAvailableLocaleCodes(){return Object.keys(this.getCurrentData().availableRawLocales)}on(e,t){let{currentDataManager:n}=this;n.currentCalendarOptionsRefiners[e]?n.emitter.on(e,t):console.warn(`Unknown listener name '${e}'`)}off(e,t){this.currentDataManager.emitter.off(e,t)}trigger(e,...t){this.currentDataManager.emitter.trigger(e,...t)}changeView(e,t){this.batchRendering((()=>{if(this.unselect(),t)if(t.start&&t.end)this.dispatch({type:"CHANGE_VIEW_TYPE",viewType:e}),this.dispatch({type:"SET_OPTION",optionName:"visibleRange",rawOptionValue:t});else{let{dateEnv:n}=this.getCurrentData();this.dispatch({type:"CHANGE_VIEW_TYPE",viewType:e,dateMarker:n.createMarker(t)})}else this.dispatch({type:"CHANGE_VIEW_TYPE",viewType:e})}))}zoomTo(e,t){let n;t=t||"day",n=this.getCurrentData().viewSpecs[t]||this.getUnitViewSpec(t),this.unselect(),n?this.dispatch({type:"CHANGE_VIEW_TYPE",viewType:n.type,dateMarker:e}):this.dispatch({type:"CHANGE_DATE",dateMarker:e})}getUnitViewSpec(e){let t,n,{viewSpecs:r,toolbarConfig:i}=this.getCurrentData(),s=[].concat(i.header?i.header.viewsWithButtons:[],i.footer?i.footer.viewsWithButtons:[]);for(let o in r)s.push(o);for(t=0;t{this.dispatch({type:"REMOVE_EVENTS",eventStore:kn(e)})}})}getEventById(e){let t=this.getCurrentData(),{defs:n,instances:r}=t.eventStore;e=String(e);for(let i in n){let s=n[i];if(s.publicId===e){if(s.recurringDef)return new On(t,s,null);for(let e in r){let n=r[e];if(n.defId===s.defId)return new On(t,s,n)}}}return null}getEvents(){let e=this.getCurrentData();return In(e.eventStore,e)}removeAllEvents(){this.dispatch({type:"REMOVE_ALL_EVENTS"})}getEventSources(){let e=this.getCurrentData(),t=e.eventSources,n=[];for(let r in t)n.push(new Rn(e,t[r]));return n}getEventSourceById(e){let t=this.getCurrentData(),n=t.eventSources;e=String(e);for(let r in n)if(n[r].publicId===e)return new Rn(t,n[r]);return null}addEventSource(e){let t=this.getCurrentData();if(e instanceof Rn)return t.eventSources[e.internalEventSource.sourceId]||this.dispatch({type:"ADD_EVENT_SOURCES",sources:[e.internalEventSource]}),e;let n=fn(e,t);return n?(this.dispatch({type:"ADD_EVENT_SOURCES",sources:[n]}),new Rn(t,n)):null}removeAllEventSources(){this.dispatch({type:"REMOVE_ALL_EVENT_SOURCES"})}refetchEvents(){this.dispatch({type:"FETCH_EVENT_SOURCES",isRefetch:!0})}scrollToTime(e){let t=V(e);t&&this.trigger("_scrollRequest",{time:t})}}function dr(e,t){return e.left>=t.left&&e.left=t.top&&e.topthis.eventUiBuilders[t]||Ee(yr)));for(let c in t){let n=t[c],u=s[c]||mr,d=this.eventUiBuilders[c];l[c]={businessHours:n.businessHours||e.businessHours,dateSelection:r[c]||null,eventStore:u,eventUiBases:d(e.eventUiBases[""],n.ui,i[c]),eventSelection:u.instances[e.eventSelection]?e.eventSelection:"",eventDrag:o[c]||null,eventResize:a[c]||null}}return l}_splitDateSpan(e){let t={};if(e){let n=this.getKeysForDateSpan(e);for(let r of n)t[r]=e}return t}_getKeysForEventDefs(e){return Je(e.defs,(e=>this.getKeysForEventDef(e)))}_splitEventStore(e,t){let{defs:n,instances:r}=e,i={};for(let s in n)for(let e of t[s])i[e]||(i[e]={defs:{},instances:{}}),i[e].defs[s]=n[s];for(let s in r){let e=r[s];for(let n of t[e.defId])i[n]&&(i[n].instances[s]=e)}return i}_splitIndividualUi(e,t){let n={};for(let r in e)if(r)for(let i of t[r])n[i]||(n[i]={}),n[i][r]=e[r];return n}_splitInteraction(e){let t={};if(e){let n=this._splitEventStore(e.affectedEvents,this._getKeysForEventDefs(e.affectedEvents)),r=this._getKeysForEventDefs(e.mutatedEvents),i=this._splitEventStore(e.mutatedEvents,r),s=r=>{t[r]||(t[r]={affectedEvents:n[r]||mr,mutatedEvents:i[r]||mr,isEvent:e.isEvent})};for(let e in n)s(e);for(let e in i)s(e)}return t}}function yr(e,t,n){let r=[];e&&r.push(e),t&&r.push(t);let i={"":un(r)};return n&&Object.assign(i,n),i}function br(e,t,n,r){return{dow:e.getUTCDay(),isDisabled:Boolean(r&&!Pt(r.activeRange,e)),isOther:Boolean(r&&!Pt(r.currentRange,e)),isToday:Boolean(t&&Pt(t,e)),isPast:Boolean(n?en:!!t&&e>=t.end)}}function Dr(e,t){let n=["fc-day",`fc-day-${te[e.dow]}`];return e.isDisabled?n.push("fc-day-disabled"):(e.isToday&&(n.push("fc-day-today"),n.push(t.getClass("today"))),e.isPast&&n.push("fc-day-past"),e.isFuture&&n.push("fc-day-future"),e.isOther&&n.push("fc-day-other")),n}const Ar=ze({year:"numeric",month:"long",day:"numeric"}),Er=ze({week:"long"});function _r(e,t,n="day",r=!0){const{dateEnv:i,options:s,calendarApi:o}=e;let a=i.format(t,"week"===n?Er:Ar);if(s.navLinks){let e=i.toDate(t);const l=e=>{let r="day"===n?s.navLinkDayClick:"week"===n?s.navLinkWeekClick:null;"function"==typeof r?r.call(o,i.toDate(t),e):("string"==typeof r&&(n=r),o.zoomTo(t,n))};return Object.assign({title:Y(s.navLinkHint,[a,e],a),"data-navlink":""},r?C(l):{onClick:l})}return{"aria-label":a}}let Sr,Tr=null;function wr(){return null===Tr&&(Tr=function(){let e=document.createElement("div");v(e,{position:"absolute",top:-1e3,left:0,border:0,padding:0,overflow:"scroll",direction:"rtl"}),e.innerHTML="
",document.body.appendChild(e);let t=e.firstChild.getBoundingClientRect().left>e.getBoundingClientRect().left;return f(e),t}()),Tr}function Cr(){return Sr||(Sr=function(){let e=document.createElement("div");e.style.overflow="scroll",e.style.position="absolute",e.style.top="-9999px",e.style.left="-9999px",document.body.appendChild(e);let t=xr(e);return document.body.removeChild(e),t}()),Sr}function xr(e){return{x:e.offsetHeight-e.clientHeight,y:e.offsetWidth-e.clientWidth}}function Rr(e,t=!1,n){let r=n?e.getBoundingClientRect():Or(e),i=function(e,t=!1){let n=window.getComputedStyle(e),r=parseInt(n.borderLeftWidth,10)||0,i=parseInt(n.borderRightWidth,10)||0,s=parseInt(n.borderTopWidth,10)||0,o=parseInt(n.borderBottomWidth,10)||0,a=xr(e),l=a.y-r-i,c={borderLeft:r,borderRight:i,borderTop:s,borderBottom:o,scrollbarBottom:a.x-s-o,scrollbarLeft:0,scrollbarRight:0};return wr()&&"rtl"===n.direction?c.scrollbarLeft=l:c.scrollbarRight=l,t&&(c.paddingLeft=parseInt(n.paddingLeft,10)||0,c.paddingRight=parseInt(n.paddingRight,10)||0,c.paddingTop=parseInt(n.paddingTop,10)||0,c.paddingBottom=parseInt(n.paddingBottom,10)||0),c}(e,t),s={left:r.left+i.borderLeft+i.scrollbarLeft,right:r.right-i.borderRight-i.scrollbarRight,top:r.top+i.borderTop,bottom:r.bottom-i.borderBottom-i.scrollbarBottom};return t&&(s.left+=i.paddingLeft,s.right-=i.paddingRight,s.top+=i.paddingTop,s.bottom-=i.paddingBottom),s}function Or(e){let t=e.getBoundingClientRect();return{left:t.left+window.pageXOffset,top:t.top+window.pageYOffset,right:t.right+window.pageXOffset,bottom:t.bottom+window.pageYOffset}}function kr(e){let t=[];for(;e instanceof HTMLElement;){let n=window.getComputedStyle(e);if("fixed"===n.position)break;/(auto|scroll)/.test(n.overflow+n.overflowY+n.overflowX)&&t.push(e),e=e.parentNode}return t}class Ir{constructor(e,t,n,r){this.els=t;let i=this.originClientRect=e.getBoundingClientRect();n&&this.buildElHorizontals(i.left),r&&this.buildElVerticals(i.top)}buildElHorizontals(e){let t=[],n=[];for(let r of this.els){let i=r.getBoundingClientRect();t.push(i.left-e),n.push(i.right-e)}this.lefts=t,this.rights=n}buildElVerticals(e){let t=[],n=[];for(let r of this.els){let i=r.getBoundingClientRect();t.push(i.top-e),n.push(i.bottom-e)}this.tops=t,this.bottoms=n}leftToIndex(e){let t,{lefts:n,rights:r}=this,i=n.length;for(t=0;t=n[t]&&e=n[t]&&e0}canScrollHorizontally(){return this.getMaxScrollLeft()>0}canScrollUp(){return this.getScrollTop()>0}canScrollDown(){return this.getScrollTop()0}canScrollRight(){return this.getScrollLeft()e.thickness||1)){this.getEntryThickness=e,this.strictOrder=!1,this.allowReslicing=!1,this.maxCoord=-1,this.maxStackCnt=-1,this.levelCoords=[],this.entriesByLevel=[],this.stackCnts={}}addSegs(e){let t=[];for(let n of e)this.insertEntry(n,t);return t}insertEntry(e,t){let n=this.findInsertion(e);this.isInsertionValid(n,e)?this.insertEntryAt(e,n):this.handleInvalidInsertion(n,e,t)}isInsertionValid(e,t){return(-1===this.maxCoord||e.levelCoord+this.getEntryThickness(t)<=this.maxCoord)&&(-1===this.maxStackCnt||e.stackCnti.end&&this.insertEntry({index:e.index,thickness:e.thickness,span:{start:i.end,end:r.end}},n)}insertEntryAt(e,t){let{entriesByLevel:n,levelCoords:r}=this;-1===t.lateral?(Wr(r,t.level,t.levelCoord),Wr(n,t.level,[e])):Wr(n[t.level],t.lateral,e),this.stackCnts[Ur(e)]=t.stackCnt}findInsertion(e){let{levelCoords:t,entriesByLevel:n,strictOrder:r,stackCnts:i}=this,s=t.length,o=0,a=-1,l=-1,c=null,u=0;for(let f=0;f=o+this.getEntryThickness(e))break;let d,h=n[f],p=Fr(h,e.span.start,Yr),g=p[0]+p[1];for(;(d=h[g])&&d.span.starto&&(o=e,c=d,a=f,l=g),e===o&&(u=Math.max(u,i[Ur(d)]+1)),g+=1}}let d=0;if(c)for(d=a+1;dn(e[i-1]))return[i,0];for(;ro))return[s,1];r=s+1}}return[r,0]}class Vr{constructor(e,t){this.emitter=new Dn}destroy(){}setMirrorIsVisible(e){}setMirrorNeedsRevert(e){}setAutoScrollEnabled(e){}}const Gr={};Boolean;const qr="fc-col-header-cell";function Qr(e){return e.text}class Zr extends bt{render(){let{dateEnv:e,options:t,theme:n,viewApi:i}=this.context,{props:s}=this,{date:o,dateProfile:a}=s,l=br(o,s.todayRange,null,a),c=[qr].concat(Dr(l,n)),u=e.format(o,s.dayHeaderFormat),d=!l.isDisabled&&s.colCnt>1?_r(this.context,o):{},h=Object.assign(Object.assign(Object.assign({date:e.toDate(o),view:i},s.extraRenderProps),{text:u}),l);return(0,r.n)(wt,{elTag:"th",elClasses:c,elAttrs:Object.assign({role:"columnheader",colSpan:s.colSpan,"data-date":l.isDisabled?void 0:ye(o)},s.extraDataAttrs),renderProps:h,generatorName:"dayHeaderContent",customGenerator:t.dayHeaderContent,defaultGenerator:Qr,classNameGenerator:t.dayHeaderClassNames,didMount:t.dayHeaderDidMount,willUnmount:t.dayHeaderWillUnmount},(e=>(0,r.n)("div",{className:"fc-scrollgrid-sync-inner"},!l.isDisabled&&(0,r.n)(e,{elTag:"a",elAttrs:d,elClasses:["fc-col-header-cell-cushion",s.isSticky&&"fc-sticky"]}))))}}const Xr=ze({weekday:"long"});class Kr extends bt{render(){let{props:e}=this,{dateEnv:t,theme:n,viewApi:i,options:s}=this.context,o=re(new Date(2592e5),e.dow),a={dow:e.dow,isDisabled:!1,isFuture:!1,isPast:!1,isToday:!1,isOther:!1},l=t.format(o,e.dayHeaderFormat),c=Object.assign(Object.assign(Object.assign(Object.assign({date:o},a),{view:i}),e.extraRenderProps),{text:l});return(0,r.n)(wt,{elTag:"th",elClasses:[qr,...Dr(a,n),...e.extraClassNames||[]],elAttrs:Object.assign({role:"columnheader",colSpan:e.colSpan},e.extraDataAttrs),renderProps:c,generatorName:"dayHeaderContent",customGenerator:s.dayHeaderContent,defaultGenerator:Qr,classNameGenerator:s.dayHeaderClassNames,didMount:s.dayHeaderDidMount,willUnmount:s.dayHeaderWillUnmount},(n=>(0,r.n)("div",{className:"fc-scrollgrid-sync-inner"},(0,r.n)(n,{elTag:"a",elClasses:["fc-col-header-cell-cushion",e.isSticky&&"fc-sticky"],elAttrs:{"aria-label":t.format(o,Xr)}}))))}}class Jr extends r.uA{constructor(e,t){super(e,t),this.initialNowDate=jt(t.options.now,t.dateEnv),this.initialNowQueriedMs=(new Date).valueOf(),this.state=this.computeTiming().currentState}render(){let{props:e,state:t}=this;return e.children(t.nowDate,t.todayRange)}componentDidMount(){this.setTimeout()}componentDidUpdate(e){e.unit!==this.props.unit&&(this.clearTimeout(),this.setTimeout())}componentWillUnmount(){this.clearTimeout()}computeTiming(){let{props:e,context:t}=this,n=ie(this.initialNowDate,(new Date).valueOf()-this.initialNowQueriedMs),r=t.dateEnv.startOf(n,e.unit),i=t.dateEnv.add(r,V(1,e.unit)),s=i.valueOf()-n.valueOf();return s=Math.min(864e5,s),{currentState:{nowDate:r,todayRange:$r(r)},nextState:{nowDate:i,todayRange:$r(i)},waitMs:s}}setTimeout(){let{nextState:e,waitMs:t}=this.computeTiming();this.timeoutId=setTimeout((()=>{this.setState(e,(()=>{this.setTimeout()}))}),t)}clearTimeout(){this.timeoutId&&clearTimeout(this.timeoutId)}}function $r(e){let t=le(e);return{start:t,end:re(t,1)}}Jr.contextType=mt;class ei extends bt{constructor(){super(...arguments),this.createDayHeaderFormatter=Ee(ti)}render(){let{context:e}=this,{dates:t,dateProfile:n,datesRepDistinctDays:i,renderIntro:s}=this.props,o=this.createDayHeaderFormatter(e.options.dayHeaderFormat,i,t.length);return(0,r.n)(Jr,{unit:"day"},((e,a)=>(0,r.n)("tr",{role:"row"},s&&s("day"),t.map((e=>i?(0,r.n)(Zr,{key:e.toISOString(),date:e,dateProfile:n,todayRange:a,colCnt:t.length,dayHeaderFormat:o}):(0,r.n)(Kr,{key:e.getUTCDay(),dow:e.getUTCDay(),dayHeaderFormat:o}))))))}}function ti(e,t,n){return e||function(e,t){return ze(!e||t>10?{weekday:"short"}:t>1?{weekday:"short",month:"numeric",day:"numeric",omitCommas:!0}:{weekday:"long"})}(t,n)}class ni{constructor(e,t){let n=e.start,{end:r}=e,i=[],s=[],o=-1;for(;n=t.length?t[t.length-1]+1:t[n]}}class ri{constructor(e,t){let n,r,i,{dates:s}=e;if(t){for(r=s[0].getUTCDay(),n=1;n!g[e.instanceId]))}),d=u.defs,h=u.instances,f=zn(d,e.eventUiBases);var p,g;for(let m in l){let r=l[m],o=r.range,p=c[r.defId],g=a[r.defId];if(!ui(p.constraints,o,u,e.businessHours,t))return!1;let{eventOverlap:v}=t.options,y="function"==typeof v?v:null;for(let e in h){let n=h[e];if(Mt(o,n.range)){if(!1===f[n.defId].overlap&&s.isEvent)return!1;if(!1===p.overlap)return!1;if(y&&!y(new On(t,d[n.defId],n),new On(t,g,r)))return!1}}let b=i.eventStore;for(let e of p.allows){let i,s=Object.assign(Object.assign({},n),{range:r.range,allDay:g.allDay}),o=b.defs[g.defId],a=b.instances[m];if(i=o?new On(t,o,a):new On(t,g),!e(Sn(s,t),i))return!1}}return!0}(e,t,n,r))&&!(e.dateSelection&&!function(e,t,n,r){let i=e.eventStore,s=i.defs,o=i.instances,a=e.dateSelection,l=a.range,{selectionConfig:c}=t.getCurrentData();r&&(c=r(c));if(!ui(c.constraints,l,i,e.businessHours,t))return!1;let{selectOverlap:u}=t.options,d="function"==typeof u?u:null;for(let h in o){let e=o[h];if(Mt(l,e.range)){if(!1===c.overlap)return!1;if(d&&!d(new On(t,s[e.defId],e),null))return!1}}for(let h of c.allows){if(!h(Sn(Object.assign(Object.assign({},n),a),t),null))return!1}return!0}(e,t,n,r))}function ui(e,t,n,r,i){for(let s of e)if(!fi(di(s,t,n,r,i),t))return!1;return!0}function di(e,t,n,r,i){return"businessHours"===e?hi(Ft(r,t,i)):"string"==typeof e?hi(sn(n,(t=>t.groupId===e))):"object"==typeof e&&e?hi(Ft(e,t,i)):[]}function hi(e){let{instances:t}=e,n=[];for(let r in t)n.push(t[r].range);return n}function fi(e,t){for(let n of e)if(Nt(n,t))return!0;return!1}const pi=/^(visible|hidden)$/;class gi extends bt{constructor(){super(...arguments),this.handleEl=e=>{this.el=e,Dt(this.props.elRef,e)}}render(){let{props:e}=this,{liquid:t,liquidIsAbsolute:n}=e,i=t&&n,s=["fc-scroller"];return t&&(n?s.push("fc-scroller-liquid-absolute"):s.push("fc-scroller-liquid")),(0,r.n)("div",{ref:this.handleEl,className:s.join(" "),style:{overflowX:e.overflowX,overflowY:e.overflowY,left:i&&-(e.overcomeLeft||0)||"",right:i&&-(e.overcomeRight||0)||"",bottom:i&&-(e.overcomeBottom||0)||"",marginLeft:!i&&-(e.overcomeLeft||0)||"",marginRight:!i&&-(e.overcomeRight||0)||"",marginBottom:!i&&-(e.overcomeBottom||0)||"",maxHeight:e.maxHeight||""}},e.children)}needsXScrolling(){if(pi.test(this.props.overflowX))return!1;let{el:e}=this,t=this.el.getBoundingClientRect().width-this.getYScrollbarWidth(),{children:n}=e;for(let r=0;rt)return!0}return!1}needsYScrolling(){if(pi.test(this.props.overflowY))return!1;let{el:e}=this,t=this.el.getBoundingClientRect().height-this.getXScrollbarWidth(),{children:n}=e;for(let r=0;rt)return!0}return!1}getXScrollbarWidth(){return pi.test(this.props.overflowX)?0:this.el.offsetHeight-this.el.clientHeight}getYScrollbarWidth(){return pi.test(this.props.overflowY)?0:this.el.offsetWidth-this.el.clientWidth}}class mi{constructor(e){this.masterCallback=e,this.currentMap={},this.depths={},this.callbackMap={},this.handleValue=(e,t)=>{let{depths:n,currentMap:r}=this,i=!1,s=!1;null!==e?(i=t in r,r[t]=e,n[t]=(n[t]||0)+1,s=!0):(n[t]-=1,n[t]||(delete r[t],delete this.callbackMap[t],i=!0)),this.masterCallback&&(i&&this.masterCallback(null,String(t)),s&&this.masterCallback(e,String(t)))}}createRef(e){let t=this.callbackMap[e];return t||(t=this.callbackMap[e]=t=>{this.handleValue(t,String(e))}),t}collect(e,t,n){return function(e,t=0,n,r=1){let i=[];null==n&&(n=Object.keys(e).length);for(let s=t;se),bi),this.renderMicroColGroup=Ee(Di),this.scrollerRefs=new mi,this.scrollerElRefs=new mi(this._handleScrollerEl.bind(this)),this.state={shrinkWidth:null,forceYScrollbars:!1,scrollerClientWidths:{},scrollerClientHeights:{}},this.handleSizing=()=>{this.safeSetState(Object.assign({shrinkWidth:this.computeShrinkWidth()},this.computeScrollerDims()))}}render(){let{props:e,state:t,context:n}=this,i=e.sections||[],s=this.processCols(e.cols),o=this.renderMicroColGroup(s,t.shrinkWidth),a=function(e,t){let n=["fc-scrollgrid",t.theme.getClass("table")];return e&&n.push("fc-scrollgrid-liquid"),n}(e.liquid,n);e.collapsibleWidth&&a.push("fc-scrollgrid-collapsible");let l,c=i.length,u=0,d=[],h=[],f=[];for(;u{}},i);return(0,r.n)(i?"th":"td",{ref:n.elRef,role:"presentation"},(0,r.n)("div",{className:"fc-scroller-harness"+(u?" fc-scroller-harness-liquid":"")},(0,r.n)(gi,{ref:this.scrollerRefs.createRef(h),elRef:this.scrollerElRefs.createRef(h),overflowY:d,overflowX:s.liquid?"hidden":"visible",maxHeight:e.maxHeight,liquid:u,liquidIsAbsolute:!0},f)))}_handleScrollerEl(e,t){let n=function(e,t){for(let n of e)if(n.key===t)return n;return null}(this.props.sections,t);n&&Dt(n.chunk.scrollerElRef,e)}componentDidMount(){this.handleSizing(),this.context.addResizeHandler(this.handleSizing)}componentDidUpdate(){this.handleSizing()}componentWillUnmount(){this.context.removeResizeHandler(this.handleSizing)}computeShrinkWidth(){return function(e){for(let t of e)if("shrink"===t.width)return!0;return!1}(this.props.cols)?vi(this.scrollerElRefs.getAll()):0}computeScrollerDims(){let e=Cr(),{scrollerRefs:t,scrollerElRefs:n}=this,r=!1,i={},s={};for(let o in t.currentMap){let e=t.currentMap[o];if(e&&e.needsYScrolling()){r=!0;break}}for(let o of this.props.sections){let t=o.key,a=n.currentMap[t];if(a){let n=a.parentNode;i[t]=Math.floor(n.getBoundingClientRect().width-(r?e.y:0)),s[t]=Math.floor(n.getBoundingClientRect().height)}}return{forceYScrollbars:r,scrollerClientWidths:i,scrollerClientHeights:s}}}wi.addStateEquality({scrollerClientWidths:tt,scrollerClientHeights:tt});class Ci extends bt{constructor(){super(...arguments),this.handleEl=e=>{this.el=e,e&&Pn(e,this.props.seg)}}render(){const{props:e,context:t}=this,{options:n}=t,{seg:i}=e,{eventRange:s}=i,{ui:o}=s,a={event:new On(t,s.def,s.instance),view:t.viewApi,timeText:e.timeText,textColor:o.textColor,backgroundColor:o.backgroundColor,borderColor:o.borderColor,isDraggable:!e.disableDragging&&jn(i,t),isStartResizable:!e.disableResizing&&Ln(i,t),isEndResizable:!e.disableResizing&&Wn(i),isMirror:Boolean(e.isDragging||e.isResizing||e.isDateSelecting),isStart:Boolean(i.isStart),isEnd:Boolean(i.isEnd),isPast:Boolean(e.isPast),isFuture:Boolean(e.isFuture),isToday:Boolean(e.isToday),isSelected:Boolean(e.isSelected),isDragging:Boolean(e.isDragging),isResizing:Boolean(e.isResizing)};return(0,r.n)(wt,Object.assign({},e,{elRef:this.handleEl,elClasses:[...Gn(a),...i.eventRange.ui.classNames,...e.elClasses||[]],renderProps:a,generatorName:"eventContent",customGenerator:n.eventContent,defaultGenerator:e.defaultGenerator,classNameGenerator:n.eventClassNames,didMount:n.eventDidMount,willUnmount:n.eventWillUnmount}))}componentDidUpdate(e){this.el&&this.props.seg!==e.seg&&Pn(this.el,this.props.seg)}}class xi extends bt{render(){let{props:e,context:t}=this,{options:n}=t,{seg:i}=e,{ui:s}=i.eventRange,o=Fn(i,n.eventTimeFormat||e.defaultTimeFormat,t,e.defaultDisplayEventTime,e.defaultDisplayEventEnd);return(0,r.n)(Ci,Object.assign({},e,{elTag:"a",elStyle:{borderColor:s.borderColor,backgroundColor:s.backgroundColor},elAttrs:Qn(i,t),defaultGenerator:Ri,timeText:o}),((e,t)=>(0,r.n)(r.FK,null,(0,r.n)(e,{elTag:"div",elClasses:["fc-event-main"],elStyle:{color:t.textColor}}),Boolean(t.isStartResizable)&&(0,r.n)("div",{className:"fc-event-resizer fc-event-resizer-start"}),Boolean(t.isEndResizable)&&(0,r.n)("div",{className:"fc-event-resizer fc-event-resizer-end"}))))}}function Ri(e){return(0,r.n)("div",{className:"fc-event-main-frame"},e.timeText&&(0,r.n)("div",{className:"fc-event-time"},e.timeText),(0,r.n)("div",{className:"fc-event-title-container"},(0,r.n)("div",{className:"fc-event-title fc-sticky"},e.event.title||(0,r.n)(r.FK,null,"\xa0"))))}const Oi=e=>(0,r.n)(mt.Consumer,null,(t=>{let{options:n}=t,i={isAxis:e.isAxis,date:t.dateEnv.toDate(e.date),view:t.viewApi};return(0,r.n)(wt,Object.assign({},e,{elTag:e.elTag||"div",renderProps:i,generatorName:"nowIndicatorContent",customGenerator:n.nowIndicatorContent,classNameGenerator:n.nowIndicatorClassNames,didMount:n.nowIndicatorDidMount,willUnmount:n.nowIndicatorWillUnmount}))})),ki=ze({day:"numeric"});class Ii extends bt{constructor(){super(...arguments),this.refineRenderProps=_e(Ni)}render(){let{props:e,context:t}=this,{options:n}=t,i=this.refineRenderProps({date:e.date,dateProfile:e.dateProfile,todayRange:e.todayRange,isMonthStart:e.isMonthStart||!1,showDayNumber:e.showDayNumber,extraRenderProps:e.extraRenderProps,viewApi:t.viewApi,dateEnv:t.dateEnv,monthStartFormat:n.monthStartFormat});return(0,r.n)(wt,Object.assign({},e,{elClasses:[...Dr(i,t.theme),...e.elClasses||[]],elAttrs:Object.assign(Object.assign({},e.elAttrs),i.isDisabled?{}:{"data-date":ye(e.date)}),renderProps:i,generatorName:"dayCellContent",customGenerator:n.dayCellContent,defaultGenerator:e.defaultGenerator,classNameGenerator:i.isDisabled?void 0:n.dayCellClassNames,didMount:n.dayCellDidMount,willUnmount:n.dayCellWillUnmount}))}}function Mi(e){return Boolean(e.dayCellContent||Et("dayCellContent",e))}function Ni(e){let{date:t,dateEnv:n,dateProfile:r,isMonthStart:i}=e,s=br(t,e.todayRange,null,r),o=e.showDayNumber?n.format(t,i?e.monthStartFormat:ki):"";return Object.assign(Object.assign(Object.assign({date:n.toDate(t),view:e.viewApi},s),{isMonthStart:i,dayNumberText:o}),e.extraRenderProps)}class Pi extends bt{render(){let{props:e}=this,{seg:t}=e;return(0,r.n)(Ci,{elTag:"div",elClasses:["fc-bg-event"],elStyle:{backgroundColor:t.eventRange.ui.backgroundColor},defaultGenerator:Bi,seg:t,timeText:"",isDragging:!1,isResizing:!1,isDateSelecting:!1,isSelected:!1,isPast:e.isPast,isFuture:e.isFuture,isToday:e.isToday,disableDragging:!0,disableResizing:!0})}}function Bi(e){let{title:t}=e.event;return t&&(0,r.n)("div",{className:"fc-event-title"},e.event.title)}function zi(e){return(0,r.n)("div",{className:`fc-${e}`})}const Hi=e=>(0,r.n)(mt.Consumer,null,(t=>{let{dateEnv:n,options:i}=t,{date:s}=e,o=i.weekNumberFormat||e.defaultFormat,a={num:n.computeWeekNumber(s),text:n.format(s,o),date:s};return(0,r.n)(wt,Object.assign({},e,{renderProps:a,generatorName:"weekNumberContent",customGenerator:i.weekNumberContent,defaultGenerator:Yi,classNameGenerator:i.weekNumberClassNames,didMount:i.weekNumberDidMount,willUnmount:i.weekNumberWillUnmount}))}));function Yi(e){return e.text}class Ui extends bt{constructor(){super(...arguments),this.state={titleId:A()},this.handleRootEl=e=>{this.rootEl=e,this.props.elRef&&Dt(this.props.elRef,e)},this.handleDocumentMouseDown=e=>{const t=b(e);this.rootEl.contains(t)||this.handleCloseClick()},this.handleDocumentKeyDown=e=>{"Escape"===e.key&&this.handleCloseClick()},this.handleCloseClick=()=>{let{onClose:e}=this.props;e&&e()}}render(){let{theme:e,options:t}=this.context,{props:n,state:s}=this,o=["fc-popover",e.getClass("popover")].concat(n.extraClassNames||[]);return(0,i.d5)((0,r.n)("div",Object.assign({},n.extraAttrs,{id:n.id,className:o.join(" "),"aria-labelledby":s.titleId,ref:this.handleRootEl}),(0,r.n)("div",{className:"fc-popover-header "+e.getClass("popoverHeader")},(0,r.n)("span",{className:"fc-popover-title",id:s.titleId},n.title),(0,r.n)("span",{className:"fc-popover-close "+e.getIconClass("close"),title:t.closeHint,onClick:this.handleCloseClick})),(0,r.n)("div",{className:"fc-popover-body "+e.getClass("popoverContent")},n.children)),n.parentEl)}componentDidMount(){document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleDocumentKeyDown),this.updateSize()}componentWillUnmount(){document.removeEventListener("mousedown",this.handleDocumentMouseDown),document.removeEventListener("keydown",this.handleDocumentKeyDown)}updateSize(){let{isRtl:e}=this.context,{alignmentEl:t,alignGridTop:n}=this.props,{rootEl:r}=this,i=function(e){let t=kr(e),n=e.getBoundingClientRect();for(let r of t){let e=hr(n,r.getBoundingClientRect());if(!e)return null;n=e}return n}(t);if(i){let s=r.getBoundingClientRect(),o=n?p(t,".fc-scrollgrid").getBoundingClientRect().top:i.top,a=e?i.right-s.width:i.left;o=Math.max(o,10),a=Math.min(a,document.documentElement.clientWidth-10-s.width),a=Math.max(a,10);let l=r.offsetParent.getBoundingClientRect();v(r,{top:o-l.top,left:a-l.left})}}}class ji extends zr{constructor(){super(...arguments),this.handleRootEl=e=>{this.rootEl=e,e?this.context.registerInteractiveComponent(this,{el:e,useEventCenter:!1}):this.context.unregisterInteractiveComponent(this)}}render(){let{options:e,dateEnv:t}=this.context,{props:n}=this,{startDate:i,todayRange:s,dateProfile:o}=n,a=t.format(i,e.dayPopoverFormat);return(0,r.n)(Ii,{elRef:this.handleRootEl,date:i,dateProfile:o,todayRange:s},((t,i,s)=>(0,r.n)(Ui,{elRef:s.ref,id:n.id,title:a,extraClassNames:["fc-more-popover"].concat(s.className||[]),extraAttrs:s,parentEl:n.parentEl,alignmentEl:n.alignmentEl,alignGridTop:n.alignGridTop,onClose:n.onClose},Mi(e)&&(0,r.n)(t,{elTag:"div",elClasses:["fc-more-popover-misc"]}),n.children)))}queryHit(e,t,n,r){let{rootEl:i,props:s}=this;return e>=0&&e=0&&t{this.linkEl=e,this.props.elRef&&Dt(this.props.elRef,e)},this.handleClick=e=>{let{props:t,context:n}=this,{moreLinkClick:r}=n.options,i=Fi(t).start;function s(e){let{def:t,instance:r,range:i}=e.eventRange;return{event:new On(n,t,r),start:n.dateEnv.toDate(i.start),end:n.dateEnv.toDate(i.end),isStart:e.isStart,isEnd:e.isEnd}}"function"==typeof r&&(r=r({date:i,allDay:Boolean(t.allDayDate),allSegs:t.allSegs.map(s),hiddenSegs:t.hiddenSegs.map(s),jsEvent:e,view:n.viewApi})),r&&"popover"!==r?"string"==typeof r&&n.calendarApi.zoomTo(i,r):this.setState({isPopoverOpen:!0})},this.handlePopoverClose=()=>{this.setState({isPopoverOpen:!1})}}render(){let{props:e,state:t}=this;return(0,r.n)(mt.Consumer,null,(n=>{let{viewApi:i,options:s,calendarApi:o}=n,{moreLinkText:a}=s,{moreCnt:l}=e,c=Fi(e),u="function"==typeof a?a.call(o,l):`+${l} ${a}`,d=Y(s.moreLinkHint,[l],u),h={num:l,shortText:`+${l}`,text:u,view:i};return(0,r.n)(r.FK,null,Boolean(e.moreCnt)&&(0,r.n)(wt,{elTag:e.elTag||"a",elRef:this.handleLinkEl,elClasses:[...e.elClasses||[],"fc-more-link"],elStyle:e.elStyle,elAttrs:Object.assign(Object.assign(Object.assign({},e.elAttrs),C(this.handleClick)),{title:d,"aria-expanded":t.isPopoverOpen,"aria-controls":t.isPopoverOpen?t.popoverId:""}),renderProps:h,generatorName:"moreLinkContent",customGenerator:s.moreLinkContent,defaultGenerator:e.defaultGenerator||Wi,classNameGenerator:s.moreLinkClassNames,didMount:s.moreLinkDidMount,willUnmount:s.moreLinkWillUnmount},e.children),t.isPopoverOpen&&(0,r.n)(ji,{id:t.popoverId,startDate:c.start,endDate:c.end,dateProfile:e.dateProfile,todayRange:e.todayRange,extraDateSpan:e.extraDateSpan,parentEl:this.parentEl,alignmentEl:e.alignmentElRef?e.alignmentElRef.current:this.linkEl,alignGridTop:e.alignGridTop,forceTimed:e.forceTimed,onClose:this.handlePopoverClose},e.popoverContent()))}))}componentDidMount(){this.updateParentEl()}componentDidUpdate(){this.updateParentEl()}updateParentEl(){this.linkEl&&(this.parentEl=p(this.linkEl,".fc-view-harness"))}}function Wi(e){return e.text}function Fi(e){if(e.allDayDate)return{start:e.allDayDate,end:re(e.allDayDate,1)};let{hiddenSegs:t}=e;return{start:Vi(t),end:(n=t,n.reduce(qi).eventRange.range.end)};var n}function Vi(e){return e.reduce(Gi).eventRange.range.start}function Gi(e,t){return e.eventRange.range.startt.eventRange.range.end?e:t}class Qi{constructor(){this.handlers=[]}set(e){this.currentValue=e;for(let t of this.handlers)t(e)}subscribe(e){this.handlers.push(e),void 0!==this.currentValue&&e(this.currentValue)}}class Zi extends Qi{constructor(){super(...arguments),this.map=new Map}handle(e){const{map:t}=this;let n=!1;e.isActive?(t.set(e.id,e),n=!0):t.has(e.id)&&(t.delete(e.id),n=!0),n&&this.set(t)}}},97950:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var r=n(67363),i=n(78817),s=(0,r.i1)({name:"@fullcalendar/daygrid",initialView:"dayGridMonth",views:{dayGrid:{component:i.eu,dateProfileGeneratorClass:i.LH},dayGridDay:{type:"dayGrid",duration:{days:1}},dayGridWeek:{type:"dayGrid",duration:{weeks:1}},dayGridMonth:{type:"dayGrid",duration:{months:1},fixedWeekCount:!0},dayGridYear:{type:"dayGrid",duration:{years:1}}}})},78817:(e,t,n)=>{"use strict";n.d(t,{LH:()=>I,eu:()=>O,t7:()=>R});var r=n(29174),i=n(50172);class s extends r.be{constructor(){super(...arguments),this.headerElRef=(0,i._3)()}renderSimpleLayout(e,t){let{props:n,context:s}=this,o=[],a=(0,r.cc)(s.options);return e&&o.push({type:"header",key:"header",isSticky:a,chunk:{elRef:this.headerElRef,tableClassName:"fc-col-header",rowContent:e}}),o.push({type:"body",key:"body",liquid:!0,chunk:{content:t}}),(0,i.n)(r.ct,{elClasses:["fc-daygrid"],viewSpec:s.viewSpec},(0,i.n)(r.b$,{liquid:!n.isHeightAuto&&!n.forPrint,collapsibleWidth:n.forPrint,cols:[],sections:o}))}renderHScrollLayout(e,t,n,s){let o=this.context.pluginHooks.scrollGridImpl;if(!o)throw new Error("No ScrollGrid implementation");let{props:a,context:l}=this,c=!a.forPrint&&(0,r.cc)(l.options),u=!a.forPrint&&(0,r.cb)(l.options),d=[];return e&&d.push({type:"header",key:"header",isSticky:c,chunks:[{key:"main",elRef:this.headerElRef,tableClassName:"fc-col-header",rowContent:e}]}),d.push({type:"body",key:"body",liquid:!0,chunks:[{key:"main",content:t}]}),u&&d.push({type:"footer",key:"footer",isSticky:!0,chunks:[{key:"main",content:r.ca}]}),(0,i.n)(r.ct,{elClasses:["fc-daygrid"],viewSpec:l.viewSpec},(0,i.n)(o,{liquid:!a.isHeightAuto&&!a.forPrint,forPrint:a.forPrint,collapsibleWidth:a.forPrint,colGroups:[{cols:[{span:n,minWidth:s}]}],sections:d}))}}function o(e,t){let n=[];for(let r=0;r{let n=(e.eventDrag?e.eventDrag.affectedInstances:null)||(e.eventResize?e.eventResize.affectedInstances:null)||{};return(0,i.n)(i.FK,null,t.map((t=>{let s=t.eventRange.instance.instanceId;return(0,i.n)("div",{className:"fc-daygrid-event-harness",key:s,style:{visibility:n[s]?"hidden":""}},u(t)?(0,i.n)(h,Object.assign({seg:t,isDragging:!1,isSelected:s===e.eventSelection,defaultDisplayEventEnd:!1},(0,r.bS)(t,e.todayRange))):(0,i.n)(d,Object.assign({seg:t,isDragging:!1,isResizing:!1,isDateSelecting:!1,isSelected:s===e.eventSelection,defaultDisplayEventEnd:!1},(0,r.bS)(t,e.todayRange))))})))}})}}function g(e){let t=[],n=[];for(let r of e)t.push(r.seg),r.isVisible||n.push(r.seg);return{allSegs:t,invisibleSegs:n}}const m=(0,r.x)({week:"narrow"});class v extends r.be{constructor(){super(...arguments),this.rootElRef=(0,i._3)(),this.state={dayNumberId:(0,r.a5)()},this.handleRootEl=e=>{(0,r.Y)(this.rootElRef,e),(0,r.Y)(this.props.elRef,e)}}render(){let{context:e,props:t,state:n,rootElRef:s}=this,{options:o,dateEnv:a}=e,{date:l,dateProfile:c}=t;const u=t.showDayNumber&&function(e,t,n){const{start:i,end:s}=t,o=(0,r.bg)(s,-1),a=n.getYear(i),l=n.getMonth(i),c=n.getYear(o),u=n.getMonth(o);return!(a===c&&l===u)&&Boolean(e.valueOf()===i.valueOf()||1===n.getDay(e)&&e.valueOf()(0,i.n)("div",{ref:t.innerElRef,className:"fc-daygrid-day-frame fc-scrollgrid-sync-inner",style:{minHeight:t.minHeight}},t.showWeekNumber&&(0,i.n)(r.cq,{elTag:"a",elClasses:["fc-daygrid-week-number"],elAttrs:(0,r.b0)(e,l,"week"),date:l,defaultFormat:m}),!c.isDisabled&&(t.showDayNumber||(0,r.cm)(o)||t.forceDayTop)?(0,i.n)("div",{className:"fc-daygrid-day-top"},(0,i.n)(a,{elTag:"a",elClasses:["fc-daygrid-day-number",u&&"fc-daygrid-month-start"],elAttrs:Object.assign(Object.assign({},(0,r.b0)(e,l)),{id:n.dayNumberId})})):t.showDayNumber?(0,i.n)("div",{className:"fc-daygrid-day-top",style:{visibility:"hidden"}},(0,i.n)("a",{className:"fc-daygrid-day-number"},"\xa0")):void 0,(0,i.n)("div",{className:"fc-daygrid-day-events",ref:t.fgContentElRef},t.fgContent,(0,i.n)("div",{className:"fc-daygrid-day-bottom",style:{marginTop:t.moreMarginTop}},(0,i.n)(p,{allDayDate:l,singlePlacements:t.singlePlacements,moreCnt:t.moreCnt,alignmentElRef:s,alignGridTop:!t.showDayNumber,extraDateSpan:t.extraDateSpan,dateProfile:t.dateProfile,eventSelection:t.eventSelection,eventDrag:t.eventDrag,eventResize:t.eventResize,todayRange:t.todayRange}))),(0,i.n)("div",{className:"fc-daygrid-day-bg"},t.bgContent))))}}function y(e){return e.dayNumberText||(0,i.n)(i.FK,null,"\xa0")}function b(e){return e.eventRange.instance.instanceId+":"+e.firstCol}function D(e){return b(e)+":"+e.lastCol}function A(e,t,n,r,i,s,o){let a=new _((t=>{let n=e[t.index].eventRange.instance.instanceId+":"+t.span.start+":"+(t.span.end-1);return i[n]||1}));a.allowReslicing=!0,a.strictOrder=r,!0===t||!0===n?(a.maxCoord=s,a.hiddenConsumes=!0):"number"==typeof t?a.maxStackCnt=t:"number"==typeof n&&(a.maxStackCnt=n,a.hiddenConsumes=!0);let l=[],c=[];for(let v=0;v1,s=r.span.start===a;u+=r.levelCoord-c,c=r.levelCoord+r.thickness,i?(u+=r.thickness,s&&d.push({seg:E(e,r.span.start,r.span.end,n),isVisible:!0,isAbsolute:!0,absoluteTop:r.levelCoord,marginTop:0})):s&&(d.push({seg:E(e,r.span.start,r.span.end,n),isVisible:!0,isAbsolute:!1,absoluteTop:r.levelCoord,marginTop:u}),u=0)}i.push(l),s.push(d),o.push(u)}return{singleColPlacements:i,multiColPlacements:s,leftoverMargins:o}}(d,e,o),g=[],m=[];for(let v of c){f[v.firstCol].push({seg:v,isVisible:!1,isAbsolute:!0,absoluteTop:0,marginTop:0});for(let e=v.firstCol;e<=v.lastCol;e+=1)h[e].push({seg:E(v,e,e+1,o),isVisible:!1,isAbsolute:!1,absoluteTop:0,marginTop:0})}for(let v=0;v!this.forceHidden[(0,r.bB)(e)];for(let r=0;r{e&&this.updateSizing(!0)}}render(){let{props:e,state:t,context:n}=this,{options:s}=n,o=e.cells.length,l=a(e.businessHourSegs,o),c=a(e.bgEventSegs,o),u=a(this.getHighlightSegs(),o),d=a(this.getMirrorSegs(),o),{singleColPlacements:h,multiColPlacements:f,moreCnts:p,moreMarginTops:g}=A((0,r.bR)(e.fgEventSegs,s.eventOrder),e.dayMaxEvents,e.dayMaxEventRows,s.eventOrderStrict,t.segHeights,t.maxContentHeight,e.cells),m=e.eventDrag&&e.eventDrag.affectedInstances||e.eventResize&&e.eventResize.affectedInstances||{};return(0,i.n)("tr",{ref:this.rootElRef,role:"row"},e.renderIntro&&e.renderIntro(),e.cells.map(((t,n)=>{let r=this.renderFgSegs(n,e.forPrint?h[n]:f[n],e.todayRange,m),s=this.renderFgSegs(n,function(e,t){if(!e.length)return[];let n=function(e){let t={};for(let n of e)for(let e of n)t[e.seg.eventRange.instance.instanceId]=e.absoluteTop;return t}(t);return e.map((e=>({seg:e,isVisible:!0,isAbsolute:!0,absoluteTop:n[e.eventRange.instance.instanceId],marginTop:0})))}(d[n],f),e.todayRange,{},Boolean(e.eventDrag),Boolean(e.eventResize),!1);return(0,i.n)(v,{key:t.key,elRef:this.cellElRefs.createRef(t.key),innerElRef:this.frameElRefs.createRef(t.key),dateProfile:e.dateProfile,date:t.date,showDayNumber:e.showDayNumbers,showWeekNumber:e.showWeekNumbers&&0===n,forceDayTop:e.showWeekNumbers,todayRange:e.todayRange,eventSelection:e.eventSelection,eventDrag:e.eventDrag,eventResize:e.eventResize,extraRenderProps:t.extraRenderProps,extraDataAttrs:t.extraDataAttrs,extraClassNames:t.extraClassNames,extraDateSpan:t.extraDateSpan,moreCnt:p[n],moreMarginTop:g[n],singlePlacements:h[n],fgContentElRef:this.fgElRefs.createRef(t.key),fgContent:(0,i.n)(i.FK,null,(0,i.n)(i.FK,null,r),(0,i.n)(i.FK,null,s)),bgContent:(0,i.n)(i.FK,null,this.renderFillSegs(u[n],"highlight"),this.renderFillSegs(l[n],"non-business"),this.renderFillSegs(c[n],"bg-event")),minHeight:e.cellMinHeight})})))}componentDidMount(){this.updateSizing(!0),this.context.addResizeHandler(this.handleResize)}componentDidUpdate(e,t){let n=this.props;this.updateSizing(!(0,r.E)(e,n))}componentWillUnmount(){this.context.removeResizeHandler(this.handleResize)}getHighlightSegs(){let{props:e}=this;return e.eventDrag&&e.eventDrag.segs.length?e.eventDrag.segs:e.eventResize&&e.eventResize.segs.length?e.eventResize.segs:e.dateSelectionSegs}getMirrorSegs(){let{props:e}=this;return e.eventResize&&e.eventResize.segs.length?e.eventResize.segs:[]}renderFgSegs(e,t,n,s,o,a,l){let{context:c}=this,{eventSelection:f}=this.props,{framePositions:p}=this.state,g=1===this.props.cells.length,m=o||a||l,v=[];if(p)for(let y of t){let{seg:e}=y,{instanceId:t}=e.eventRange.instance,A=y.isVisible&&!s[t],E=y.isAbsolute,_="",S="";E&&(c.isRtl?(S=0,_=p.lefts[e.lastCol]-p.lefts[e.firstCol]):(_=0,S=p.rights[e.firstCol]-p.rights[e.lastCol])),v.push((0,i.n)("div",{className:"fc-daygrid-event-harness"+(E?" fc-daygrid-event-harness-abs":""),key:b(e),ref:m?null:this.segHarnessRefs.createRef(D(e)),style:{visibility:A?"":"hidden",marginTop:E?"":y.marginTop,top:E?y.absoluteTop:"",left:_,right:S}},u(e)?(0,i.n)(h,Object.assign({seg:e,isDragging:o,isSelected:t===f,defaultDisplayEventEnd:g},(0,r.bS)(e,n))):(0,i.n)(d,Object.assign({seg:e,isDragging:o,isResizing:a,isDateSelecting:l,isSelected:t===f,defaultDisplayEventEnd:g},(0,r.bS)(e,n)))))}return v}renderFillSegs(e,t){let{isRtl:n}=this.context,{todayRange:s}=this.props,{framePositions:o}=this.state,a=[];if(o)for(let l of e){let e=n?{right:0,left:o.lefts[l.lastCol]-o.lefts[l.firstCol]}:{left:0,right:o.rights[l.firstCol]-o.rights[l.lastCol]};a.push((0,i.n)("div",{key:(0,r.bT)(l.eventRange),className:"fc-daygrid-bg-harness",style:e},"bg-event"===t?(0,i.n)(r.cp,Object.assign({seg:l},(0,r.bS)(l,s))):(0,r.co)(t)))}return(0,i.n)(i.FK,{},...a)}updateSizing(e){let{props:t,state:n,frameElRefs:i}=this;if(!t.forPrint&&null!==t.clientWidth){if(e){let e=t.cells.map((e=>i.currentMap[e.key]));if(e.length){let t=this.rootElRef.current,i=new r.ba(t,e,!0,!1);n.framePositions&&n.framePositions.similarTo(i)||this.setState({framePositions:new r.ba(t,e,!0,!1)})}}const s=this.state.segHeights,o=this.querySegHeights(),a=!0===t.dayMaxEvents||!0===t.dayMaxEventRows;this.safeSetState({segHeights:Object.assign(Object.assign({},s),o),maxContentHeight:a?this.computeMaxContentHeight():null})}}querySegHeights(){let e=this.segHarnessRefs.currentMap,t={};for(let n in e){let r=Math.round(e[n].getBoundingClientRect().height);t[n]=Math.max(t[n]||0,r)}return t}computeMaxContentHeight(){let e=this.props.cells[0].key,t=this.cellElRefs.currentMap[e],n=this.fgElRefs.currentMap[e];return t.getBoundingClientRect().bottom-n.getBoundingClientRect().top}getCellEls(){let e=this.cellElRefs.currentMap;return this.props.cells.map((t=>e[t.key]))}}S.addStateEquality({segHeights:r.E});class T extends r.be{constructor(){super(...arguments),this.splitBusinessHourSegs=(0,r.z)(o),this.splitBgEventSegs=(0,r.z)(o),this.splitFgEventSegs=(0,r.z)(o),this.splitDateSelectionSegs=(0,r.z)(o),this.splitEventDrag=(0,r.z)(l),this.splitEventResize=(0,r.z)(l),this.rowRefs=new r.cf}render(){let{props:e,context:t}=this,n=e.cells.length,s=this.splitBusinessHourSegs(e.businessHourSegs,n),o=this.splitBgEventSegs(e.bgEventSegs,n),a=this.splitFgEventSegs(e.fgEventSegs,n),l=this.splitDateSelectionSegs(e.dateSelectionSegs,n),c=this.splitEventDrag(e.eventDrag,n),u=this.splitEventResize(e.eventResize,n),d=n>=7&&e.clientWidth?e.clientWidth/t.options.aspectRatio/6:null;return(0,i.n)(r.ch,{unit:"day"},((t,r)=>(0,i.n)(i.FK,null,e.cells.map(((t,h)=>(0,i.n)(S,{ref:this.rowRefs.createRef(h),key:t.length?t[0].date.toISOString():h,showDayNumbers:n>1,showWeekNumbers:e.showWeekNumbers,todayRange:r,dateProfile:e.dateProfile,cells:t,renderIntro:e.renderRowIntro,businessHourSegs:s[h],eventSelection:e.eventSelection,bgEventSegs:o[h].filter(w),fgEventSegs:a[h],dateSelectionSegs:l[h],eventDrag:c[h],eventResize:u[h],dayMaxEvents:e.dayMaxEvents,dayMaxEventRows:e.dayMaxEventRows,clientWidth:e.clientWidth,clientHeight:e.clientHeight,cellMinHeight:d,forPrint:e.forPrint}))))))}componentDidMount(){this.registerInteractiveComponent()}componentDidUpdate(){this.registerInteractiveComponent()}registerInteractiveComponent(){if(!this.rootEl){const e=this.rowRefs.currentMap[0].getCellEls()[0],t=e?e.closest(".fc-daygrid-body"):null;t&&(this.rootEl=t,this.context.registerInteractiveComponent(this,{el:t,isHitComboAllowed:this.props.isHitComboAllowed}))}}componentWillUnmount(){this.rootEl&&(this.context.unregisterInteractiveComponent(this),this.rootEl=null)}prepareHits(){this.rowPositions=new r.ba(this.rootEl,this.rowRefs.collect().map((e=>e.getCellEls()[0])),!1,!0),this.colPositions=new r.ba(this.rootEl,this.rowRefs.currentMap[0].getCellEls(),!0,!1)}queryHit(e,t){let{colPositions:n,rowPositions:r}=this,i=n.leftToIndex(e),s=r.topToIndex(t);if(null!=s&&null!=i){let e=this.props.cells[s][i];return{dateProfile:this.props.dateProfile,dateSpan:Object.assign({range:this.getCellRange(s,i),allDay:!0},e.extraDateSpan),dayEl:this.getCellEl(s,i),rect:{left:n.lefts[i],right:n.rights[i],top:r.tops[s],bottom:r.bottoms[s]},layer:0}}return null}getCellEl(e,t){return this.rowRefs.currentMap[e].getCellEls()[t]}getCellRange(e,t){let n=this.props.cells[e][t].date;return{start:n,end:(0,r.t)(n,1)}}}function w(e){return e.eventRange.def.allDay}class C extends r.be{constructor(){super(...arguments),this.elRef=(0,i._3)(),this.needsScrollReset=!1}render(){let{props:e}=this,{dayMaxEventRows:t,dayMaxEvents:n,expandRows:r}=e,s=!0===n||!0===t;s&&!r&&(s=!1,t=null,n=null);let o=["fc-daygrid-body",s?"fc-daygrid-body-balanced":"fc-daygrid-body-unbalanced",r?"":"fc-daygrid-body-natural"];return(0,i.n)("div",{ref:this.elRef,className:o.join(" "),style:{width:e.clientWidth,minWidth:e.tableMinWidth}},(0,i.n)("table",{role:"presentation",className:"fc-scrollgrid-sync-table",style:{width:e.clientWidth,minWidth:e.tableMinWidth,height:r?e.clientHeight:""}},e.colGroupNode,(0,i.n)("tbody",{role:"presentation"},(0,i.n)(T,{dateProfile:e.dateProfile,cells:e.cells,renderRowIntro:e.renderRowIntro,showWeekNumbers:e.showWeekNumbers,clientWidth:e.clientWidth,clientHeight:e.clientHeight,businessHourSegs:e.businessHourSegs,bgEventSegs:e.bgEventSegs,fgEventSegs:e.fgEventSegs,dateSelectionSegs:e.dateSelectionSegs,eventSelection:e.eventSelection,eventDrag:e.eventDrag,eventResize:e.eventResize,dayMaxEvents:n,dayMaxEventRows:t,forPrint:e.forPrint,isHitComboAllowed:e.isHitComboAllowed}))))}componentDidMount(){this.requestScrollReset()}componentDidUpdate(e){e.dateProfile!==this.props.dateProfile?this.requestScrollReset():this.flushScrollReset()}requestScrollReset(){this.needsScrollReset=!0,this.flushScrollReset()}flushScrollReset(){if(this.needsScrollReset&&this.props.clientWidth){const e=function(e,t){let n;t.currentRangeUnit.match(/year|month/)&&(n=e.querySelector(`[data-date="${(0,r.bx)(t.currentDate)}-01"]`));n||(n=e.querySelector(`[data-date="${(0,r.bv)(t.currentDate)}"]`));return n}(this.elRef.current,this.props.dateProfile);if(e){const t=e.closest(".fc-daygrid-body"),n=t.closest(".fc-scroller"),r=e.getBoundingClientRect().top-t.getBoundingClientRect().top;n.scrollTop=r?r+1:0}this.needsScrollReset=!1}}}class x extends r.bW{constructor(){super(...arguments),this.forceDayIfListItem=!0}sliceRange(e,t){return t.sliceRange(e)}}class R extends r.be{constructor(){super(...arguments),this.slicer=new x,this.tableRef=(0,i._3)()}render(){let{props:e,context:t}=this;return(0,i.n)(C,Object.assign({ref:this.tableRef},this.slicer.sliceProps(e,e.dateProfile,e.nextDayThreshold,t,e.dayTableModel),{dateProfile:e.dateProfile,cells:e.dayTableModel.cells,colGroupNode:e.colGroupNode,tableMinWidth:e.tableMinWidth,renderRowIntro:e.renderRowIntro,dayMaxEvents:e.dayMaxEvents,dayMaxEventRows:e.dayMaxEventRows,showWeekNumbers:e.showWeekNumbers,expandRows:e.expandRows,headerAlignElRef:e.headerAlignElRef,clientWidth:e.clientWidth,clientHeight:e.clientHeight,forPrint:e.forPrint}))}}class O extends s{constructor(){super(...arguments),this.buildDayTableModel=(0,r.z)(k),this.headerRef=(0,i._3)(),this.tableRef=(0,i._3)()}render(){let{options:e,dateProfileGenerator:t}=this.context,{props:n}=this,s=this.buildDayTableModel(n.dateProfile,t),o=e.dayHeaders&&(0,i.n)(r.bK,{ref:this.headerRef,dateProfile:n.dateProfile,dates:s.headerDates,datesRepDistinctDays:1===s.rowCnt}),a=t=>(0,i.n)(R,{ref:this.tableRef,dateProfile:n.dateProfile,dayTableModel:s,businessHours:n.businessHours,dateSelection:n.dateSelection,eventStore:n.eventStore,eventUiBases:n.eventUiBases,eventSelection:n.eventSelection,eventDrag:n.eventDrag,eventResize:n.eventResize,nextDayThreshold:e.nextDayThreshold,colGroupNode:t.tableColGroupNode,tableMinWidth:t.tableMinWidth,dayMaxEvents:e.dayMaxEvents,dayMaxEventRows:e.dayMaxEventRows,showWeekNumbers:e.weekNumbers,expandRows:!n.isHeightAuto,headerAlignElRef:this.headerElRef,clientWidth:t.clientWidth,clientHeight:t.clientHeight,forPrint:n.forPrint});return e.dayMinWidth?this.renderHScrollLayout(o,a,s.colCnt,e.dayMinWidth):this.renderSimpleLayout(o,a)}}function k(e,t){let n=new r.bO(e.renderRange,t);return new r.bV(n,/year|month|week/.test(e.currentRangeUnit))}class I extends r.U{buildRenderRange(e,t,n){let i=super.buildRenderRange(e,t,n),{props:s}=this;return function(e){let t,{dateEnv:n,currentRange:i}=e,{start:s,end:o}=i;e.snapToWeek&&(s=n.startOfWeek(s),t=n.startOfWeek(o),t.valueOf()!==o.valueOf()&&(o=(0,r.bh)(t,1)));if(e.fixedWeekCount){let e=n.startOfWeek(n.startOfMonth((0,r.t)(i.end,-1))),t=Math.ceil((0,r.bi)(e,o));o=(0,r.bh)(o,6-t)}return{start:s,end:o}}({currentRange:i,snapToWeek:/^(year|month)$/.test(t),fixedWeekCount:s.fixedWeekCount,dateEnv:s.dateEnv})}}(0,r.cw)(':root{--fc-daygrid-event-dot-width:8px}.fc-daygrid-day-events:after,.fc-daygrid-day-events:before,.fc-daygrid-day-frame:after,.fc-daygrid-day-frame:before,.fc-daygrid-event-harness:after,.fc-daygrid-event-harness:before{clear:both;content:"";display:table}.fc .fc-daygrid-body{position:relative;z-index:1}.fc .fc-daygrid-day.fc-day-today{background-color:var(--fc-today-bg-color)}.fc .fc-daygrid-day-frame{min-height:100%;position:relative}.fc .fc-daygrid-day-top{display:flex;flex-direction:row-reverse}.fc .fc-day-other .fc-daygrid-day-top{opacity:.3}.fc .fc-daygrid-day-number{padding:4px;position:relative;z-index:4}.fc .fc-daygrid-month-start{font-size:1.1em;font-weight:700}.fc .fc-daygrid-day-events{margin-top:1px}.fc .fc-daygrid-body-balanced .fc-daygrid-day-events{left:0;position:absolute;right:0}.fc .fc-daygrid-body-unbalanced .fc-daygrid-day-events{min-height:2em;position:relative}.fc .fc-daygrid-body-natural .fc-daygrid-day-events{margin-bottom:1em}.fc .fc-daygrid-event-harness{position:relative}.fc .fc-daygrid-event-harness-abs{left:0;position:absolute;right:0;top:0}.fc .fc-daygrid-bg-harness{bottom:0;position:absolute;top:0}.fc .fc-daygrid-day-bg .fc-non-business{z-index:1}.fc .fc-daygrid-day-bg .fc-bg-event{z-index:2}.fc .fc-daygrid-day-bg .fc-highlight{z-index:3}.fc .fc-daygrid-event{margin-top:1px;z-index:6}.fc .fc-daygrid-event.fc-event-mirror{z-index:7}.fc .fc-daygrid-day-bottom{font-size:.85em;margin:0 2px}.fc .fc-daygrid-day-bottom:after,.fc .fc-daygrid-day-bottom:before{clear:both;content:"";display:table}.fc .fc-daygrid-more-link{border-radius:3px;cursor:pointer;line-height:1;margin-top:1px;max-width:100%;overflow:hidden;padding:2px;position:relative;white-space:nowrap;z-index:4}.fc .fc-daygrid-more-link:hover{background-color:rgba(0,0,0,.1)}.fc .fc-daygrid-week-number{background-color:var(--fc-neutral-bg-color);color:var(--fc-neutral-text-color);min-width:1.5em;padding:2px;position:absolute;text-align:center;top:0;z-index:5}.fc .fc-more-popover .fc-popover-body{min-width:220px;padding:10px}.fc-direction-ltr .fc-daygrid-event.fc-event-start,.fc-direction-rtl .fc-daygrid-event.fc-event-end{margin-left:2px}.fc-direction-ltr .fc-daygrid-event.fc-event-end,.fc-direction-rtl .fc-daygrid-event.fc-event-start{margin-right:2px}.fc-direction-ltr .fc-daygrid-more-link{float:left}.fc-direction-ltr .fc-daygrid-week-number{border-radius:0 0 3px 0;left:0}.fc-direction-rtl .fc-daygrid-more-link{float:right}.fc-direction-rtl .fc-daygrid-week-number{border-radius:0 0 0 3px;right:0}.fc-liquid-hack .fc-daygrid-day-frame{position:static}.fc-daygrid-event{border-radius:3px;font-size:var(--fc-small-font-size);position:relative;white-space:nowrap}.fc-daygrid-block-event .fc-event-time{font-weight:700}.fc-daygrid-block-event .fc-event-time,.fc-daygrid-block-event .fc-event-title{padding:1px}.fc-daygrid-dot-event{align-items:center;display:flex;padding:2px 0}.fc-daygrid-dot-event .fc-event-title{flex-grow:1;flex-shrink:1;font-weight:700;min-width:0;overflow:hidden}.fc-daygrid-dot-event.fc-event-mirror,.fc-daygrid-dot-event:hover{background:rgba(0,0,0,.1)}.fc-daygrid-dot-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-daygrid-event-dot{border:calc(var(--fc-daygrid-event-dot-width)/2) solid var(--fc-event-border-color);border-radius:calc(var(--fc-daygrid-event-dot-width)/2);box-sizing:content-box;height:0;margin:0 4px;width:0}.fc-direction-ltr .fc-daygrid-event .fc-event-time{margin-right:3px}.fc-direction-rtl .fc-daygrid-event .fc-event-time{margin-left:3px}')},95257:(e,t,n)=>{"use strict";n.d(t,{A:()=>h});var r=n(67363),i=n(29174),s=n(76225);class o{constructor(e){this.maxIterations=null!=e.maxIterations?e.maxIterations:1e3,this.skipInvalidDates=null!=e.skipInvalidDates&&e.skipInvalidDates,this.jCalData=s.parse(e.ics),this.component=new s.Component(this.jCalData),this.events=this.component.getAllSubcomponents("vevent").map((e=>new s.Event(e))),this.skipInvalidDates&&(this.events=this.events.filter((e=>{try{return e.startDate.toJSDate(),e.endDate.toJSDate(),!0}catch(t){return!1}})))}between(e,t){function n(n,r){return(!e||r>=e.getTime())&&(!t||n<=t.getTime())}function r(e){const t=e.startDate.toJSDate().getTime();let n=e.endDate.toJSDate().getTime();return e.endDate.isDate&&n>t&&(n-=1),{startTime:t,endTime:n}}const i=[];this.events.forEach((e=>{e.isRecurrenceException()&&i.push(e)}));const s={events:[],occurrences:[]};return this.events.filter((e=>!e.isRecurrenceException())).forEach((e=>{const o=[];if(e.component.getAllProperties("exdate").forEach((e=>{const t=e.getFirstValue();o.push(t.toJSDate().getTime())})),e.isRecurring()){const a=e.iterator();let l,c=0;do{if(c+=1,l=a.next(),l){const a=e.getOccurrenceDetails(l),{startTime:c,endTime:u}=r(a),d=-1!==o.indexOf(c),h=i.find((t=>t.uid===e.uid&&t.recurrenceId.toJSDate().getTime()===a.startDate.toJSDate().getTime()));if(t&&c>t.getTime())break;n(c,u)&&(h?s.events.push(h):d||s.occurrences.push(a))}}while(l&&(!this.maxIterations||ce.url&&"ics"===e.format?{url:e.url,format:"ics"}:null,fetch(e,t,n){let r=e.eventSource.meta,{internalState:i}=r;i&&!e.isRefetch||(i=r.internalState={response:null,iCalExpanderPromise:fetch(r.url,{method:"GET"}).then((e=>e.text().then((t=>(i.response=e,new o({ics:t,skipInvalidDates:!0}))))))}),i.iCalExpanderPromise.then((n=>{t({rawEvents:l(n,e.range),response:i.response})}),n)}};function l(e,t){let n=(0,i.t)(t.start,-1),r=(0,i.t)(t.end,1),s=e.between(n,r),o=[];for(let i of s.events)o.push(Object.assign(Object.assign({},c(i)),{start:i.startDate.toString(),end:d(i)&&i.endDate?i.endDate.toString():null}));for(let i of s.occurrences){let e=i.item;o.push(Object.assign(Object.assign({},c(e)),{start:i.startDate.toString(),end:d(e)&&i.endDate?i.endDate.toString():null}))}return o}function c(e){return{title:e.summary,url:u(e),extendedProps:{location:e.location,organizer:e.organizer,description:e.description}}}function u(e){let t=e.component.getFirstProperty("url");return t?t.getFirstValue():""}function d(e){return Boolean(e.component.getFirstProperty("dtend"))||Boolean(e.component.getFirstProperty("duration"))}var h=(0,r.i1)({name:"@fullcalendar/icalendar",eventSourceDefs:[a]})},38680:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>x});var r=n(67363),i=n(29174);i.bI.touchMouseIgnoreWait=500;let s=0,o=0,a=!1;class l{constructor(e){this.subjectEl=null,this.selector="",this.handleSelector="",this.shouldIgnoreMove=!1,this.shouldWatchScroll=!0,this.isDragging=!1,this.isTouchDragging=!1,this.wasTouchScroll=!1,this.handleMouseDown=e=>{if(!this.shouldIgnoreMouse()&&function(e){return 0===e.button&&!e.ctrlKey}(e)&&this.tryStart(e)){let t=this.createEventFromMouse(e,!0);this.emitter.trigger("pointerdown",t),this.initScrollWatch(t),this.shouldIgnoreMove||document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("mouseup",this.handleMouseUp)}},this.handleMouseMove=e=>{let t=this.createEventFromMouse(e);this.recordCoords(t),this.emitter.trigger("pointermove",t)},this.handleMouseUp=e=>{document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp),this.emitter.trigger("pointerup",this.createEventFromMouse(e)),this.cleanup()},this.handleTouchStart=e=>{if(this.tryStart(e)){this.isTouchDragging=!0;let t=this.createEventFromTouch(e,!0);this.emitter.trigger("pointerdown",t),this.initScrollWatch(t);let n=e.target;this.shouldIgnoreMove||n.addEventListener("touchmove",this.handleTouchMove),n.addEventListener("touchend",this.handleTouchEnd),n.addEventListener("touchcancel",this.handleTouchEnd),window.addEventListener("scroll",this.handleTouchScroll,!0)}},this.handleTouchMove=e=>{let t=this.createEventFromTouch(e);this.recordCoords(t),this.emitter.trigger("pointermove",t)},this.handleTouchEnd=e=>{if(this.isDragging){let t=e.target;t.removeEventListener("touchmove",this.handleTouchMove),t.removeEventListener("touchend",this.handleTouchEnd),t.removeEventListener("touchcancel",this.handleTouchEnd),window.removeEventListener("scroll",this.handleTouchScroll,!0),this.emitter.trigger("pointerup",this.createEventFromTouch(e)),this.cleanup(),this.isTouchDragging=!1,s+=1,setTimeout((()=>{s-=1}),i.bI.touchMouseIgnoreWait)}},this.handleTouchScroll=()=>{this.wasTouchScroll=!0},this.handleScroll=e=>{if(!this.shouldIgnoreMove){let t=window.pageXOffset-this.prevScrollX+this.prevPageX,n=window.pageYOffset-this.prevScrollY+this.prevPageY;this.emitter.trigger("pointermove",{origEvent:e,isTouch:this.isTouchDragging,subjectEl:this.subjectEl,pageX:t,pageY:n,deltaX:t-this.origPageX,deltaY:n-this.origPageY})}},this.containerEl=e,this.emitter=new i.F,e.addEventListener("mousedown",this.handleMouseDown),e.addEventListener("touchstart",this.handleTouchStart,{passive:!0}),o+=1,1===o&&window.addEventListener("touchmove",c,{passive:!1})}destroy(){this.containerEl.removeEventListener("mousedown",this.handleMouseDown),this.containerEl.removeEventListener("touchstart",this.handleTouchStart,{passive:!0}),o-=1,o||window.removeEventListener("touchmove",c,{passive:!1})}tryStart(e){let t=this.querySubjectEl(e),n=e.target;return!(!t||this.handleSelector&&!(0,i.$)(n,this.handleSelector))&&(this.subjectEl=t,this.isDragging=!0,this.wasTouchScroll=!1,!0)}cleanup(){a=!1,this.isDragging=!1,this.subjectEl=null,this.destroyScrollWatch()}querySubjectEl(e){return this.selector?(0,i.$)(e.target,this.selector):this.containerEl}shouldIgnoreMouse(){return s||this.isTouchDragging}cancelTouchScroll(){this.isDragging&&(a=!0)}initScrollWatch(e){this.shouldWatchScroll&&(this.recordCoords(e),window.addEventListener("scroll",this.handleScroll,!0))}recordCoords(e){this.shouldWatchScroll&&(this.prevPageX=e.pageX,this.prevPageY=e.pageY,this.prevScrollX=window.pageXOffset,this.prevScrollY=window.pageYOffset)}destroyScrollWatch(){this.shouldWatchScroll&&window.removeEventListener("scroll",this.handleScroll,!0)}createEventFromMouse(e,t){let n=0,r=0;return t?(this.origPageX=e.pageX,this.origPageY=e.pageY):(n=e.pageX-this.origPageX,r=e.pageY-this.origPageY),{origEvent:e,isTouch:!1,subjectEl:this.subjectEl,pageX:e.pageX,pageY:e.pageY,deltaX:n,deltaY:r}}createEventFromTouch(e,t){let n,r,i=e.touches,s=0,o=0;return i&&i.length?(n=i[0].pageX,r=i[0].pageY):(n=e.pageX,r=e.pageY),t?(this.origPageX=n,this.origPageY=r):(s=n-this.origPageX,o=r-this.origPageY),{origEvent:e,isTouch:!0,subjectEl:this.subjectEl,pageX:n,pageY:r,deltaX:s,deltaY:o}}}function c(e){a&&e.preventDefault()}class u{constructor(){this.isVisible=!1,this.sourceEl=null,this.mirrorEl=null,this.sourceElRect=null,this.parentNode=document.body,this.zIndex=9999,this.revertDuration=0}start(e,t,n){this.sourceEl=e,this.sourceElRect=this.sourceEl.getBoundingClientRect(),this.origScreenX=t-window.pageXOffset,this.origScreenY=n-window.pageYOffset,this.deltaX=0,this.deltaY=0,this.updateElPosition()}handleMove(e,t){this.deltaX=e-window.pageXOffset-this.origScreenX,this.deltaY=t-window.pageYOffset-this.origScreenY,this.updateElPosition()}setIsVisible(e){e?this.isVisible||(this.mirrorEl&&(this.mirrorEl.style.display=""),this.isVisible=e,this.updateElPosition()):this.isVisible&&(this.mirrorEl&&(this.mirrorEl.style.display="none"),this.isVisible=e)}stop(e,t){let n=()=>{this.cleanup(),t()};e&&this.mirrorEl&&this.isVisible&&this.revertDuration&&(this.deltaX||this.deltaY)?this.doRevertAnimation(n,this.revertDuration):setTimeout(n,0)}doRevertAnimation(e,t){let n=this.mirrorEl,r=this.sourceEl.getBoundingClientRect();n.style.transition="top "+t+"ms,left "+t+"ms",(0,i.aP)(n,{left:r.left,top:r.top}),(0,i.b2)(n,(()=>{n.style.transition="",e()}))}cleanup(){this.mirrorEl&&((0,i.aO)(this.mirrorEl),this.mirrorEl=null),this.sourceEl=null}updateElPosition(){this.sourceEl&&this.isVisible&&(0,i.aP)(this.getMirrorEl(),{left:this.sourceElRect.left+this.deltaX,top:this.sourceElRect.top+this.deltaY})}getMirrorEl(){let e=this.sourceElRect,t=this.mirrorEl;return t||(t=this.mirrorEl=this.sourceEl.cloneNode(!0),t.style.userSelect="none",t.style.webkitUserSelect="none",t.classList.add("fc-event-dragging"),(0,i.aP)(t,{position:"fixed",zIndex:this.zIndex,visibility:"",boxSizing:"border-box",width:e.right-e.left,height:e.bottom-e.top,right:"auto",bottom:"auto",margin:0}),this.parentNode.appendChild(t)),t}}class d extends i.bb{constructor(e,t){super(),this.handleScroll=()=>{this.scrollTop=this.scrollController.getScrollTop(),this.scrollLeft=this.scrollController.getScrollLeft(),this.handleScrollChange()},this.scrollController=e,this.doesListening=t,this.scrollTop=this.origScrollTop=e.getScrollTop(),this.scrollLeft=this.origScrollLeft=e.getScrollLeft(),this.scrollWidth=e.getScrollWidth(),this.scrollHeight=e.getScrollHeight(),this.clientWidth=e.getClientWidth(),this.clientHeight=e.getClientHeight(),this.clientRect=this.computeClientRect(),this.doesListening&&this.getEventTarget().addEventListener("scroll",this.handleScroll)}destroy(){this.doesListening&&this.getEventTarget().removeEventListener("scroll",this.handleScroll)}getScrollTop(){return this.scrollTop}getScrollLeft(){return this.scrollLeft}setScrollTop(e){this.scrollController.setScrollTop(e),this.doesListening||(this.scrollTop=Math.max(Math.min(e,this.getMaxScrollTop()),0),this.handleScrollChange())}setScrollLeft(e){this.scrollController.setScrollLeft(e),this.doesListening||(this.scrollLeft=Math.max(Math.min(e,this.getMaxScrollLeft()),0),this.handleScrollChange())}getClientWidth(){return this.clientWidth}getClientHeight(){return this.clientHeight}getScrollWidth(){return this.scrollWidth}getScrollHeight(){return this.scrollHeight}handleScrollChange(){}}class h extends d{constructor(e,t){super(new i.bc(e),t)}getEventTarget(){return this.scrollController.el}computeClientRect(){return(0,i.b3)(this.scrollController.el)}}class f extends d{constructor(e){super(new i.bd,e)}getEventTarget(){return window}computeClientRect(){return{left:this.scrollLeft,right:this.scrollLeft+this.clientWidth,top:this.scrollTop,bottom:this.scrollTop+this.clientHeight}}handleScrollChange(){this.clientRect=this.computeClientRect()}}const p="function"==typeof performance?performance.now:Date.now;class g{constructor(){this.isEnabled=!0,this.scrollQuery=[window,".fc-scroller"],this.edgeThreshold=50,this.maxVelocity=300,this.pointerScreenX=null,this.pointerScreenY=null,this.isAnimating=!1,this.scrollCaches=null,this.everMovedUp=!1,this.everMovedDown=!1,this.everMovedLeft=!1,this.everMovedRight=!1,this.animate=()=>{if(this.isAnimating){let e=this.computeBestEdge(this.pointerScreenX+window.pageXOffset,this.pointerScreenY+window.pageYOffset);if(e){let t=p();this.handleSide(e,(t-this.msSinceRequest)/1e3),this.requestAnimation(t)}else this.isAnimating=!1}}}start(e,t,n){this.isEnabled&&(this.scrollCaches=this.buildCaches(n),this.pointerScreenX=null,this.pointerScreenY=null,this.everMovedUp=!1,this.everMovedDown=!1,this.everMovedLeft=!1,this.everMovedRight=!1,this.handleMove(e,t))}handleMove(e,t){if(this.isEnabled){let n=e-window.pageXOffset,r=t-window.pageYOffset,i=null===this.pointerScreenY?0:r-this.pointerScreenY,s=null===this.pointerScreenX?0:n-this.pointerScreenX;i<0?this.everMovedUp=!0:i>0&&(this.everMovedDown=!0),s<0?this.everMovedLeft=!0:s>0&&(this.everMovedRight=!0),this.pointerScreenX=n,this.pointerScreenY=r,this.isAnimating||(this.isAnimating=!0,this.requestAnimation(p()))}}stop(){if(this.isEnabled){this.isAnimating=!1;for(let e of this.scrollCaches)e.destroy();this.scrollCaches=null}}requestAnimation(e){this.msSinceRequest=e,requestAnimationFrame(this.animate)}handleSide(e,t){let{scrollCache:n}=e,{edgeThreshold:r}=this,i=r-e.distance,s=i*i/(r*r)*this.maxVelocity*t,o=1;switch(e.name){case"left":o=-1;case"right":n.setScrollLeft(n.getScrollLeft()+s*o);break;case"top":o=-1;case"bottom":n.setScrollTop(n.getScrollTop()+s*o)}}computeBestEdge(e,t){let{edgeThreshold:n}=this,r=null,i=this.scrollCaches||[];for(let s of i){let i=s.clientRect,o=e-i.left,a=i.right-e,l=t-i.top,c=i.bottom-t;o>=0&&a>=0&&l>=0&&c>=0&&(l<=n&&this.everMovedUp&&s.canScrollUp()&&(!r||r.distance>l)&&(r={scrollCache:s,name:"top",distance:l}),c<=n&&this.everMovedDown&&s.canScrollDown()&&(!r||r.distance>c)&&(r={scrollCache:s,name:"bottom",distance:c}),o<=n&&this.everMovedLeft&&s.canScrollLeft()&&(!r||r.distance>o)&&(r={scrollCache:s,name:"left",distance:o}),a<=n&&this.everMovedRight&&s.canScrollRight()&&(!r||r.distance>a)&&(r={scrollCache:s,name:"right",distance:a}))}return r}buildCaches(e){return this.queryScrollEls(e).map((e=>e===window?new f(!1):new h(e,!1)))}queryScrollEls(e){let t=[];for(let n of this.scrollQuery)"object"==typeof n?t.push(n):t.push(...Array.prototype.slice.call(e.getRootNode().querySelectorAll(n)));return t}}class m extends i.bH{constructor(e,t){super(e),this.containerEl=e,this.delay=null,this.minDistance=0,this.touchScrollAllowed=!0,this.mirrorNeedsRevert=!1,this.isInteracting=!1,this.isDragging=!1,this.isDelayEnded=!1,this.isDistanceSurpassed=!1,this.delayTimeoutId=null,this.onPointerDown=e=>{this.isDragging||(this.isInteracting=!0,this.isDelayEnded=!1,this.isDistanceSurpassed=!1,(0,i.ar)(document.body),(0,i.at)(document.body),e.isTouch||e.origEvent.preventDefault(),this.emitter.trigger("pointerdown",e),this.isInteracting&&!this.pointer.shouldIgnoreMove&&(this.mirror.setIsVisible(!1),this.mirror.start(e.subjectEl,e.pageX,e.pageY),this.startDelay(e),this.minDistance||this.handleDistanceSurpassed(e)))},this.onPointerMove=e=>{if(this.isInteracting){if(this.emitter.trigger("pointermove",e),!this.isDistanceSurpassed){let t,n=this.minDistance,{deltaX:r,deltaY:i}=e;t=r*r+i*i,t>=n*n&&this.handleDistanceSurpassed(e)}this.isDragging&&("scroll"!==e.origEvent.type&&(this.mirror.handleMove(e.pageX,e.pageY),this.autoScroller.handleMove(e.pageX,e.pageY)),this.emitter.trigger("dragmove",e))}},this.onPointerUp=e=>{this.isInteracting&&(this.isInteracting=!1,(0,i.as)(document.body),(0,i.au)(document.body),this.emitter.trigger("pointerup",e),this.isDragging&&(this.autoScroller.stop(),this.tryStopDrag(e)),this.delayTimeoutId&&(clearTimeout(this.delayTimeoutId),this.delayTimeoutId=null))};let n=this.pointer=new l(e);n.emitter.on("pointerdown",this.onPointerDown),n.emitter.on("pointermove",this.onPointerMove),n.emitter.on("pointerup",this.onPointerUp),t&&(n.selector=t),this.mirror=new u,this.autoScroller=new g}destroy(){this.pointer.destroy(),this.onPointerUp({})}startDelay(e){"number"==typeof this.delay?this.delayTimeoutId=setTimeout((()=>{this.delayTimeoutId=null,this.handleDelayEnd(e)}),this.delay):this.handleDelayEnd(e)}handleDelayEnd(e){this.isDelayEnded=!0,this.tryStartDrag(e)}handleDistanceSurpassed(e){this.isDistanceSurpassed=!0,this.tryStartDrag(e)}tryStartDrag(e){this.isDelayEnded&&this.isDistanceSurpassed&&(this.pointer.wasTouchScroll&&!this.touchScrollAllowed||(this.isDragging=!0,this.mirrorNeedsRevert=!1,this.autoScroller.start(e.pageX,e.pageY,this.containerEl),this.emitter.trigger("dragstart",e),!1===this.touchScrollAllowed&&this.pointer.cancelTouchScroll()))}tryStopDrag(e){this.mirror.stop(this.mirrorNeedsRevert,this.stopDrag.bind(this,e))}stopDrag(e){this.isDragging=!1,this.emitter.trigger("dragend",e)}setIgnoreMove(e){this.pointer.shouldIgnoreMove=e}setMirrorIsVisible(e){this.mirror.setIsVisible(e)}setMirrorNeedsRevert(e){this.mirrorNeedsRevert=e}setAutoScrollEnabled(e){this.autoScroller.isEnabled=e}}class v{constructor(e){this.origRect=(0,i.b6)(e),this.scrollCaches=(0,i.b5)(e).map((e=>new h(e,!0)))}destroy(){for(let e of this.scrollCaches)e.destroy()}computeLeft(){let e=this.origRect.left;for(let t of this.scrollCaches)e+=t.origScrollLeft-t.getScrollLeft();return e}computeTop(){let e=this.origRect.top;for(let t of this.scrollCaches)e+=t.origScrollTop-t.getScrollTop();return e}isWithinClipping(e,t){let n={left:e,top:t};for(let r of this.scrollCaches)if(!y(r.getEventTarget())&&!(0,i.aF)(n,r.clientRect))return!1;return!0}}function y(e){let t=e.tagName;return"HTML"===t||"BODY"===t}class b{constructor(e,t){this.useSubjectCenter=!1,this.requireInitial=!0,this.initialHit=null,this.movingHit=null,this.finalHit=null,this.handlePointerDown=e=>{let{dragging:t}=this;this.initialHit=null,this.movingHit=null,this.finalHit=null,this.prepareHits(),this.processFirstCoord(e),this.initialHit||!this.requireInitial?(t.setIgnoreMove(!1),this.emitter.trigger("pointerdown",e)):t.setIgnoreMove(!0)},this.handleDragStart=e=>{this.emitter.trigger("dragstart",e),this.handleMove(e,!0)},this.handleDragMove=e=>{this.emitter.trigger("dragmove",e),this.handleMove(e)},this.handlePointerUp=e=>{this.releaseHits(),this.emitter.trigger("pointerup",e)},this.handleDragEnd=e=>{this.movingHit&&this.emitter.trigger("hitupdate",null,!0,e),this.finalHit=this.movingHit,this.movingHit=null,this.emitter.trigger("dragend",e)},this.droppableStore=t,e.emitter.on("pointerdown",this.handlePointerDown),e.emitter.on("dragstart",this.handleDragStart),e.emitter.on("dragmove",this.handleDragMove),e.emitter.on("pointerup",this.handlePointerUp),e.emitter.on("dragend",this.handleDragEnd),this.dragging=e,this.emitter=new i.F}processFirstCoord(e){let t,n={left:e.pageX,top:e.pageY},r=n,s=e.subjectEl;s instanceof HTMLElement&&(t=(0,i.b6)(s),r=(0,i.aG)(r,t));let o=this.initialHit=this.queryHitForOffset(r.left,r.top);if(o){if(this.useSubjectCenter&&t){let e=(0,i.aE)(t,o.rect);e&&(r=(0,i.aH)(e))}this.coordAdjust=(0,i.aI)(r,n)}else this.coordAdjust={left:0,top:0}}handleMove(e,t){let n=this.queryHitForOffset(e.pageX+this.coordAdjust.left,e.pageY+this.coordAdjust.top);!t&&D(this.movingHit,n)||(this.movingHit=n,this.emitter.trigger("hitupdate",n,!1,e))}prepareHits(){this.offsetTrackers=(0,i.a)(this.droppableStore,(e=>(e.component.prepareHits(),new v(e.el))))}releaseHits(){let{offsetTrackers:e}=this;for(let t in e)e[t].destroy();this.offsetTrackers={}}queryHitForOffset(e,t){let{droppableStore:n,offsetTrackers:r}=this,s=null;for(let o in n){let a=n[o].component,l=r[o];if(l&&l.isWithinClipping(e,t)){let n=l.computeLeft(),r=l.computeTop(),c=e-n,u=t-r,{origRect:d}=l,h=d.right-d.left,f=d.bottom-d.top;if(c>=0&&c=0&&us.layer)&&(e.componentId=o,e.context=a.context,e.rect.left+=n,e.rect.right+=n,e.rect.top+=r,e.rect.bottom+=r,s=e)}}}return s}}function D(e,t){return!e&&!t||Boolean(e)===Boolean(t)&&(0,i.bf)(e.dateSpan,t.dateSpan)}function A(e,t){let n={};for(let s of t.pluginHooks.datePointTransforms)Object.assign(n,s(e,t));var r,i;return Object.assign(n,(r=e,{date:(i=t.dateEnv).toDate(r.range.start),dateStr:i.formatIso(r.range.start,{omitTime:r.allDay}),allDay:r.allDay})),n}class E extends i.Z{constructor(e){super(e),this.handlePointerDown=e=>{let{dragging:t}=this,n=e.origEvent.target;t.setIgnoreMove(!this.component.isValidDateDownEl(n))},this.handleDragEnd=e=>{let{component:t}=this,{pointer:n}=this.dragging;if(!n.wasTouchScroll){let{initialHit:n,finalHit:r}=this.hitDragging;if(n&&r&&D(n,r)){let{context:r}=t,i=Object.assign(Object.assign({},A(n.dateSpan,r)),{dayEl:n.dayEl,jsEvent:e.origEvent,view:r.viewApi||r.calendarApi.view});r.emitter.trigger("dateClick",i)}}},this.dragging=new m(e.el),this.dragging.autoScroller.isEnabled=!1;let t=this.hitDragging=new b(this.dragging,(0,i.bG)(e));t.emitter.on("pointerdown",this.handlePointerDown),t.emitter.on("dragend",this.handleDragEnd)}destroy(){this.dragging.destroy()}}class _ extends i.Z{constructor(e){super(e),this.dragSelection=null,this.handlePointerDown=e=>{let{component:t,dragging:n}=this,{options:r}=t.context,i=r.selectable&&t.isValidDateDownEl(e.origEvent.target);n.setIgnoreMove(!i),n.delay=e.isTouch?function(e){let{options:t}=e.context,n=t.selectLongPressDelay;null==n&&(n=t.longPressDelay);return n}(t):null},this.handleDragStart=e=>{this.component.context.calendarApi.unselect(e)},this.handleHitUpdate=(e,t)=>{let{context:n}=this.component,r=null,s=!1;if(e){let t=this.hitDragging.initialHit;e.componentId===t.componentId&&this.isHitComboAllowed&&!this.isHitComboAllowed(t,e)||(r=function(e,t,n){let r=e.dateSpan,s=t.dateSpan,o=[r.range.start,r.range.end,s.range.start,s.range.end];o.sort(i.av);let a={};for(let i of n){let n=i(e,t);if(!1===n)return null;n&&Object.assign(a,n)}return a.range={start:o[0],end:o[3]},a.allDay=r.allDay,a}(t,e,n.pluginHooks.dateSelectionTransformers)),r&&(0,i.b_)(r,e.dateProfile,n)||(s=!0,r=null)}r?n.dispatch({type:"SELECT_DATES",selection:r}):t||n.dispatch({type:"UNSELECT_DATES"}),s?(0,i.ax)():(0,i.aw)(),t||(this.dragSelection=r)},this.handlePointerUp=e=>{this.dragSelection&&((0,i.cu)(this.dragSelection,e,this.component.context),this.dragSelection=null)};let{component:t}=e,{options:n}=t.context,r=this.dragging=new m(e.el);r.touchScrollAllowed=!1,r.minDistance=n.selectMinDistance||0,r.autoScroller.isEnabled=n.dragScroll;let s=this.hitDragging=new b(this.dragging,(0,i.bG)(e));s.emitter.on("pointerdown",this.handlePointerDown),s.emitter.on("dragstart",this.handleDragStart),s.emitter.on("hitupdate",this.handleHitUpdate),s.emitter.on("pointerup",this.handlePointerUp)}destroy(){this.dragging.destroy()}}class S extends i.Z{constructor(e){super(e),this.subjectEl=null,this.subjectSeg=null,this.isDragging=!1,this.eventRange=null,this.relevantEvents=null,this.receivingContext=null,this.validMutation=null,this.mutatedRelevantEvents=null,this.handlePointerDown=e=>{let t=e.origEvent.target,{component:n,dragging:r}=this,{mirror:s}=r,{options:o}=n.context,a=n.context;this.subjectEl=e.subjectEl;let l=this.subjectSeg=(0,i._)(e.subjectEl),c=(this.eventRange=l.eventRange).instance.instanceId;this.relevantEvents=(0,i.aV)(a.getCurrentData().eventStore,c),r.minDistance=e.isTouch?0:o.eventDragMinDistance,r.delay=e.isTouch&&c!==n.props.eventSelection?function(e){let{options:t}=e.context,n=t.eventLongPressDelay;null==n&&(n=t.longPressDelay);return n}(n):null,o.fixedMirrorParent?s.parentNode=o.fixedMirrorParent:s.parentNode=(0,i.$)(t,".fc"),s.revertDuration=o.dragRevertDuration;let u=n.isValidSegDownEl(t)&&!(0,i.$)(t,".fc-event-resizer");r.setIgnoreMove(!u),this.isDragging=u&&e.subjectEl.classList.contains("fc-event-draggable")},this.handleDragStart=e=>{let t=this.component.context,n=this.eventRange,r=n.instance.instanceId;e.isTouch?r!==this.component.props.eventSelection&&t.dispatch({type:"SELECT_EVENT",eventInstanceId:r}):t.dispatch({type:"UNSELECT_EVENT"}),this.isDragging&&(t.calendarApi.unselect(e),t.emitter.trigger("eventDragStart",{el:this.subjectEl,event:new i.a0(t,n.def,n.instance),jsEvent:e.origEvent,view:t.viewApi}))},this.handleHitUpdate=(e,t)=>{if(!this.isDragging)return;let n=this.relevantEvents,r=this.hitDragging.initialHit,s=this.component.context,o=null,a=null,l=null,c=!1,u={affectedEvents:n,mutatedEvents:(0,i.I)(),isEvent:!0};if(e){o=e.context;let t=o.options;s===o||t.editable&&t.droppable?(a=function(e,t,n){let r=e.dateSpan,s=t.dateSpan,o=r.range.start,a=s.range.start,l={};r.allDay!==s.allDay&&(l.allDay=s.allDay,l.hasEnd=t.context.options.allDayMaintainDuration,s.allDay&&(o=(0,i.q)(o)));let c=(0,i.aA)(o,a,e.context.dateEnv,e.componentId===t.componentId?e.largeUnit:null);c.milliseconds&&(l.allDay=!1);let u={datesDelta:c,standardProps:l};for(let i of n)i(u,e,t);return u}(r,e,o.getCurrentData().pluginHooks.eventDragMutationMassagers),a&&(l=(0,i.bX)(n,o.getCurrentData().eventUiBases,a,o),u.mutatedEvents=l,(0,i.bZ)(u,e.dateProfile,o)||(c=!0,a=null,l=null,u.mutatedEvents=(0,i.I)()))):o=null}this.displayDrag(o,u),c?(0,i.ax)():(0,i.aw)(),t||(s===o&&D(r,e)&&(a=null),this.dragging.setMirrorNeedsRevert(!a),this.dragging.setMirrorIsVisible(!e||!this.subjectEl.getRootNode().querySelector(".fc-event-mirror")),this.receivingContext=o,this.validMutation=a,this.mutatedRelevantEvents=l)},this.handlePointerUp=()=>{this.isDragging||this.cleanup()},this.handleDragEnd=e=>{if(this.isDragging){let t=this.component.context,n=t.viewApi,{receivingContext:r,validMutation:s}=this,o=this.eventRange.def,a=this.eventRange.instance,l=new i.a0(t,o,a),c=this.relevantEvents,u=this.mutatedRelevantEvents,{finalHit:d}=this.hitDragging;if(this.clearDrag(),t.emitter.trigger("eventDragStop",{el:this.subjectEl,event:l,jsEvent:e.origEvent,view:n}),s){if(r===t){let r=new i.a0(t,u.defs[o.defId],a?u.instances[a.instanceId]:null);t.dispatch({type:"MERGE_EVENTS",eventStore:u});let d={oldEvent:l,event:r,relatedEvents:(0,i.w)(u,t,a),revert(){t.dispatch({type:"MERGE_EVENTS",eventStore:c})}},h={};for(let e of t.getCurrentData().pluginHooks.eventDropTransformers)Object.assign(h,e(s,t));t.emitter.trigger("eventDrop",Object.assign(Object.assign(Object.assign({},d),h),{el:e.subjectEl,delta:s.datesDelta,jsEvent:e.origEvent,view:n})),t.emitter.trigger("eventChange",d)}else if(r){let s={event:l,relatedEvents:(0,i.w)(c,t,a),revert(){t.dispatch({type:"MERGE_EVENTS",eventStore:c})}};t.emitter.trigger("eventLeave",Object.assign(Object.assign({},s),{draggedEl:e.subjectEl,view:n})),t.dispatch({type:"REMOVE_EVENTS",eventStore:c}),t.emitter.trigger("eventRemove",s);let h=u.defs[o.defId],f=u.instances[a.instanceId],p=new i.a0(r,h,f);r.dispatch({type:"MERGE_EVENTS",eventStore:u});let g={event:p,relatedEvents:(0,i.w)(u,r,f),revert(){r.dispatch({type:"REMOVE_EVENTS",eventStore:u})}};r.emitter.trigger("eventAdd",g),e.isTouch&&r.dispatch({type:"SELECT_EVENT",eventInstanceId:a.instanceId}),r.emitter.trigger("drop",Object.assign(Object.assign({},A(d.dateSpan,r)),{draggedEl:e.subjectEl,jsEvent:e.origEvent,view:d.context.viewApi})),r.emitter.trigger("eventReceive",Object.assign(Object.assign({},g),{draggedEl:e.subjectEl,view:d.context.viewApi}))}}else t.emitter.trigger("_noEventDrop")}this.cleanup()};let{component:t}=this,{options:n}=t.context,r=this.dragging=new m(e.el);r.pointer.selector=S.SELECTOR,r.touchScrollAllowed=!1,r.autoScroller.isEnabled=n.dragScroll;let s=this.hitDragging=new b(this.dragging,i.a7);s.useSubjectCenter=e.useEventCenter,s.emitter.on("pointerdown",this.handlePointerDown),s.emitter.on("dragstart",this.handleDragStart),s.emitter.on("hitupdate",this.handleHitUpdate),s.emitter.on("pointerup",this.handlePointerUp),s.emitter.on("dragend",this.handleDragEnd)}destroy(){this.dragging.destroy()}displayDrag(e,t){let n=this.component.context,r=this.receivingContext;r&&r!==e&&(r===n?r.dispatch({type:"SET_EVENT_DRAG",state:{affectedEvents:t.affectedEvents,mutatedEvents:(0,i.I)(),isEvent:!0}}):r.dispatch({type:"UNSET_EVENT_DRAG"})),e&&e.dispatch({type:"SET_EVENT_DRAG",state:t})}clearDrag(){let e=this.component.context,{receivingContext:t}=this;t&&t.dispatch({type:"UNSET_EVENT_DRAG"}),e!==t&&e.dispatch({type:"UNSET_EVENT_DRAG"})}cleanup(){this.subjectSeg=null,this.isDragging=!1,this.eventRange=null,this.relevantEvents=null,this.receivingContext=null,this.validMutation=null,this.mutatedRelevantEvents=null}}S.SELECTOR=".fc-event-draggable, .fc-event-resizable";class T extends i.Z{constructor(e){super(e),this.draggingSegEl=null,this.draggingSeg=null,this.eventRange=null,this.relevantEvents=null,this.validMutation=null,this.mutatedRelevantEvents=null,this.handlePointerDown=e=>{let{component:t}=this,n=this.querySegEl(e),r=(0,i._)(n),s=this.eventRange=r.eventRange;this.dragging.minDistance=t.context.options.eventDragMinDistance,this.dragging.setIgnoreMove(!this.component.isValidSegDownEl(e.origEvent.target)||e.isTouch&&this.component.props.eventSelection!==s.instance.instanceId)},this.handleDragStart=e=>{let{context:t}=this.component,n=this.eventRange;this.relevantEvents=(0,i.aV)(t.getCurrentData().eventStore,this.eventRange.instance.instanceId);let r=this.querySegEl(e);this.draggingSegEl=r,this.draggingSeg=(0,i._)(r),t.calendarApi.unselect(),t.emitter.trigger("eventResizeStart",{el:r,event:new i.a0(t,n.def,n.instance),jsEvent:e.origEvent,view:t.viewApi})},this.handleHitUpdate=(e,t,n)=>{let{context:r}=this.component,s=this.relevantEvents,o=this.hitDragging.initialHit,a=this.eventRange.instance,l=null,c=null,u=!1,d={affectedEvents:s,mutatedEvents:(0,i.I)(),isEvent:!0};if(e){e.componentId===o.componentId&&this.isHitComboAllowed&&!this.isHitComboAllowed(o,e)||(l=function(e,t,n,r){let s=e.context.dateEnv,o=e.dateSpan.range.start,a=t.dateSpan.range.start,l=(0,i.aA)(o,a,s,e.largeUnit);if(n){if(s.add(r.start,l)r.start)return{endDelta:l};return null}(o,e,n.subjectEl.classList.contains("fc-event-resizer-start"),a.range))}l&&(c=(0,i.bX)(s,r.getCurrentData().eventUiBases,l,r),d.mutatedEvents=c,(0,i.bZ)(d,e.dateProfile,r)||(u=!0,l=null,c=null,d.mutatedEvents=null)),c?r.dispatch({type:"SET_EVENT_RESIZE",state:d}):r.dispatch({type:"UNSET_EVENT_RESIZE"}),u?(0,i.ax)():(0,i.aw)(),t||(l&&D(o,e)&&(l=null),this.validMutation=l,this.mutatedRelevantEvents=c)},this.handleDragEnd=e=>{let{context:t}=this.component,n=this.eventRange.def,r=this.eventRange.instance,s=new i.a0(t,n,r),o=this.relevantEvents,a=this.mutatedRelevantEvents;if(t.emitter.trigger("eventResizeStop",{el:this.draggingSegEl,event:s,jsEvent:e.origEvent,view:t.viewApi}),this.validMutation){let l=new i.a0(t,a.defs[n.defId],r?a.instances[r.instanceId]:null);t.dispatch({type:"MERGE_EVENTS",eventStore:a});let c={oldEvent:s,event:l,relatedEvents:(0,i.w)(a,t,r),revert(){t.dispatch({type:"MERGE_EVENTS",eventStore:o})}};t.emitter.trigger("eventResize",Object.assign(Object.assign({},c),{el:this.draggingSegEl,startDelta:this.validMutation.startDelta||(0,i.d)(0),endDelta:this.validMutation.endDelta||(0,i.d)(0),jsEvent:e.origEvent,view:t.viewApi})),t.emitter.trigger("eventChange",c)}else t.emitter.trigger("_noEventResize");this.draggingSeg=null,this.relevantEvents=null,this.validMutation=null};let{component:t}=e,n=this.dragging=new m(e.el);n.pointer.selector=".fc-event-resizer",n.touchScrollAllowed=!1,n.autoScroller.isEnabled=t.context.options.dragScroll;let r=this.hitDragging=new b(this.dragging,(0,i.bG)(e));r.emitter.on("pointerdown",this.handlePointerDown),r.emitter.on("dragstart",this.handleDragStart),r.emitter.on("hitupdate",this.handleHitUpdate),r.emitter.on("dragend",this.handleDragEnd)}destroy(){this.dragging.destroy()}querySegEl(e){return(0,i.$)(e.subjectEl,".fc-event")}}const w={fixedMirrorParent:i.n},C={dateClick:i.n,eventDragStart:i.n,eventDragStop:i.n,eventDrop:i.n,eventResizeStart:i.n,eventResizeStop:i.n,eventResize:i.n,drop:i.n,eventReceive:i.n,eventLeave:i.n};i.bI.dataAttrPrefix="";i.bH;var x=(0,r.i1)({name:"@fullcalendar/interaction",componentInteractions:[E,_,S,T],calendarInteractions:[class{constructor(e){this.context=e,this.isRecentPointerDateSelect=!1,this.matchesCancel=!1,this.matchesEvent=!1,this.onSelect=e=>{e.jsEvent&&(this.isRecentPointerDateSelect=!0)},this.onDocumentPointerDown=e=>{let t=this.context.options.unselectCancel,n=(0,i.aR)(e.origEvent);this.matchesCancel=!!(0,i.$)(n,t),this.matchesEvent=!!(0,i.$)(n,S.SELECTOR)},this.onDocumentPointerUp=e=>{let{context:t}=this,{documentPointer:n}=this,r=t.getCurrentData();if(!n.wasTouchScroll){if(r.dateSelection&&!this.isRecentPointerDateSelect){let n=t.options.unselectAuto;!n||n&&this.matchesCancel||t.calendarApi.unselect(e)}r.eventSelection&&!this.matchesEvent&&t.dispatch({type:"UNSELECT_EVENT"})}this.isRecentPointerDateSelect=!1};let t=this.documentPointer=new l(document);t.shouldIgnoreMove=!0,t.shouldWatchScroll=!1,t.emitter.on("pointerdown",this.onDocumentPointerDown),t.emitter.on("pointerup",this.onDocumentPointerUp),e.emitter.on("select",this.onSelect)}destroy(){this.context.emitter.off("select",this.onSelect),this.documentPointer.destroy()}}],elementDraggingImpl:m,optionRefiners:w,listenerRefiners:C})},17632:(e,t,n)=>{"use strict";n.d(t,{A:()=>l});var r=n(96540),i=n(40961),s=n(67363),o=n(29174);const a=parseInt(String(r.version).split(".")[0])<18;class l extends r.Component{constructor(){super(...arguments),this.elRef=(0,r.createRef)(),this.isUpdating=!1,this.isUnmounting=!1,this.state={customRenderingMap:new Map},this.requestResize=()=>{this.isUnmounting||(this.cancelResize(),this.resizeId=requestAnimationFrame((()=>{this.doResize()})))}}render(){const e=[];for(const t of this.state.customRenderingMap.values())e.push(r.createElement(c,{key:t.id,customRendering:t}));return r.createElement("div",{ref:this.elRef},e)}componentDidMount(){this.isUnmounting=!1;const e=new o.cy;let t;this.handleCustomRendering=e.handle.bind(e),this.calendar=new s.Vv(this.elRef.current,Object.assign(Object.assign({},this.props),{handleCustomRendering:this.handleCustomRendering})),this.calendar.render(),e.subscribe((e=>{const n=Date.now(),r=!t;(a||r||this.isUpdating||this.isUnmounting||n-t<100?u:i.flushSync)((()=>{this.setState({customRenderingMap:e},(()=>{t=n,r?this.doResize():this.requestResize()}))}))}))}componentDidUpdate(){this.isUpdating=!0,this.calendar.resetOptions(Object.assign(Object.assign({},this.props),{handleCustomRendering:this.handleCustomRendering})),this.isUpdating=!1}componentWillUnmount(){this.isUnmounting=!0,this.cancelResize(),this.calendar.destroy()}doResize(){this.calendar.updateSize()}cancelResize(){void 0!==this.resizeId&&(cancelAnimationFrame(this.resizeId),this.resizeId=void 0)}getApi(){return this.calendar}}l.act=u;class c extends r.PureComponent{render(){const{customRendering:e}=this.props,{generatorMeta:t}=e,n="function"==typeof t?t(e.renderProps):t;return(0,i.createPortal)(n,e.containerEl)}}function u(e){e()}},11244:(e,t,n)=>{"use strict";n.d(t,{A:()=>W});var r=n(67363),i=n(29174),s=n(50172),o=n(78817);class a extends i.aY{getKeyInfo(){return{allDay:{},timed:{}}}getKeysForDateSpan(e){return e.allDay?["allDay"]:["timed"]}getKeysForEventDef(e){return e.allDay?(0,i.bP)(e)?["timed","allDay"]:["allDay"]:["timed"]}}const l=(0,i.x)({hour:"numeric",minute:"2-digit",omitZeroMinute:!0,meridiem:"short"});function c(e){let t=["fc-timegrid-slot","fc-timegrid-slot-label",e.isLabeled?"fc-scrollgrid-shrink":"fc-timegrid-slot-minor"];return(0,s.n)(i.V.Consumer,null,(n=>{if(!e.isLabeled)return(0,s.n)("td",{className:t.join(" "),"data-time":e.isoTimeStr});let{dateEnv:r,options:o,viewApi:a}=n,c=null==o.slotLabelFormat?l:Array.isArray(o.slotLabelFormat)?(0,i.x)(o.slotLabelFormat[0]):(0,i.x)(o.slotLabelFormat),d={level:0,time:e.time,date:r.toDate(e.date),view:a,text:r.format(e.date,c)};return(0,s.n)(i.C,{elTag:"td",elClasses:t,elAttrs:{"data-time":e.isoTimeStr},renderProps:d,generatorName:"slotLabelContent",customGenerator:o.slotLabelContent,defaultGenerator:u,classNameGenerator:o.slotLabelClassNames,didMount:o.slotLabelDidMount,willUnmount:o.slotLabelWillUnmount},(e=>(0,s.n)("div",{className:"fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame"},(0,s.n)(e,{elTag:"div",elClasses:["fc-timegrid-slot-label-cushion","fc-scrollgrid-shrink-cushion"]}))))}))}function u(e){return e.text}class d extends i.B{render(){return this.props.slatMetas.map((e=>(0,s.n)("tr",{key:e.key},(0,s.n)(c,Object.assign({},e)))))}}const h=(0,i.x)({week:"short"});class f extends i.be{constructor(){super(...arguments),this.allDaySplitter=new a,this.headerElRef=(0,s._3)(),this.rootElRef=(0,s._3)(),this.scrollerElRef=(0,s._3)(),this.state={slatCoords:null},this.handleScrollTopRequest=e=>{let t=this.scrollerElRef.current;t&&(t.scrollTop=e)},this.renderHeadAxis=(e,t="")=>{let{options:n}=this.context,{dateProfile:r}=this.props,o=r.renderRange,a=1===(0,i.bl)(o.start,o.end)?(0,i.b0)(this.context,o.start,"week"):{};return n.weekNumbers&&"day"===e?(0,s.n)(i.cq,{elTag:"th",elClasses:["fc-timegrid-axis","fc-scrollgrid-shrink"],elAttrs:{"aria-hidden":!0},date:o.start,defaultFormat:h},(e=>(0,s.n)("div",{className:["fc-timegrid-axis-frame","fc-scrollgrid-shrink-frame","fc-timegrid-axis-frame-liquid"].join(" "),style:{height:t}},(0,s.n)(e,{elTag:"a",elClasses:["fc-timegrid-axis-cushion","fc-scrollgrid-shrink-cushion","fc-scrollgrid-sync-inner"],elAttrs:a})))):(0,s.n)("th",{"aria-hidden":!0,className:"fc-timegrid-axis"},(0,s.n)("div",{className:"fc-timegrid-axis-frame",style:{height:t}}))},this.renderTableRowAxis=e=>{let{options:t,viewApi:n}=this.context,r={text:t.allDayText,view:n};return(0,s.n)(i.C,{elTag:"td",elClasses:["fc-timegrid-axis","fc-scrollgrid-shrink"],elAttrs:{"aria-hidden":!0},renderProps:r,generatorName:"allDayContent",customGenerator:t.allDayContent,defaultGenerator:p,classNameGenerator:t.allDayClassNames,didMount:t.allDayDidMount,willUnmount:t.allDayWillUnmount},(t=>(0,s.n)("div",{className:["fc-timegrid-axis-frame","fc-scrollgrid-shrink-frame",null==e?" fc-timegrid-axis-frame-liquid":""].join(" "),style:{height:e}},(0,s.n)(t,{elTag:"span",elClasses:["fc-timegrid-axis-cushion","fc-scrollgrid-shrink-cushion","fc-scrollgrid-sync-inner"]}))))},this.handleSlatCoords=e=>{this.setState({slatCoords:e})}}renderSimpleLayout(e,t,n){let{context:r,props:o}=this,a=[],l=(0,i.cc)(r.options);return e&&a.push({type:"header",key:"header",isSticky:l,chunk:{elRef:this.headerElRef,tableClassName:"fc-col-header",rowContent:e}}),t&&(a.push({type:"body",key:"all-day",chunk:{content:t}}),a.push({type:"body",key:"all-day-divider",outerContent:(0,s.n)("tr",{role:"presentation",className:"fc-scrollgrid-section"},(0,s.n)("td",{className:"fc-timegrid-divider "+r.theme.getClass("tableCellShaded")}))})),a.push({type:"body",key:"body",liquid:!0,expandRows:Boolean(r.options.expandRows),chunk:{scrollerElRef:this.scrollerElRef,content:n}}),(0,s.n)(i.ct,{elRef:this.rootElRef,elClasses:["fc-timegrid"],viewSpec:r.viewSpec},(0,s.n)(i.b$,{liquid:!o.isHeightAuto&&!o.forPrint,collapsibleWidth:o.forPrint,cols:[{width:"shrink"}],sections:a}))}renderHScrollLayout(e,t,n,r,o,a,l){let c=this.context.pluginHooks.scrollGridImpl;if(!c)throw new Error("No ScrollGrid implementation");let{context:u,props:h}=this,f=!h.forPrint&&(0,i.cc)(u.options),p=!h.forPrint&&(0,i.cb)(u.options),g=[];e&&g.push({type:"header",key:"header",isSticky:f,syncRowHeights:!0,chunks:[{key:"axis",rowContent:e=>(0,s.n)("tr",{role:"presentation"},this.renderHeadAxis("day",e.rowSyncHeights[0]))},{key:"cols",elRef:this.headerElRef,tableClassName:"fc-col-header",rowContent:e}]}),t&&(g.push({type:"body",key:"all-day",syncRowHeights:!0,chunks:[{key:"axis",rowContent:e=>(0,s.n)("tr",{role:"presentation"},this.renderTableRowAxis(e.rowSyncHeights[0]))},{key:"cols",content:t}]}),g.push({key:"all-day-divider",type:"body",outerContent:(0,s.n)("tr",{role:"presentation",className:"fc-scrollgrid-section"},(0,s.n)("td",{colSpan:2,className:"fc-timegrid-divider "+u.theme.getClass("tableCellShaded")}))}));let m=u.options.nowIndicator;return g.push({type:"body",key:"body",liquid:!0,expandRows:Boolean(u.options.expandRows),chunks:[{key:"axis",content:e=>(0,s.n)("div",{className:"fc-timegrid-axis-chunk"},(0,s.n)("table",{"aria-hidden":!0,style:{height:e.expandRows?e.clientHeight:""}},e.tableColGroupNode,(0,s.n)("tbody",null,(0,s.n)(d,{slatMetas:a}))),(0,s.n)("div",{className:"fc-timegrid-now-indicator-container"},(0,s.n)(i.ch,{unit:m?"minute":"day"},(e=>{let t=m&&l&&l.safeComputeTop(e);return"number"==typeof t?(0,s.n)(i.ck,{elClasses:["fc-timegrid-now-indicator-arrow"],elStyle:{top:t},isAxis:!0,date:e}):null}))))},{key:"cols",scrollerElRef:this.scrollerElRef,content:n}]}),p&&g.push({key:"footer",type:"footer",isSticky:!0,chunks:[{key:"axis",content:i.ca},{key:"cols",content:i.ca}]}),(0,s.n)(i.ct,{elRef:this.rootElRef,elClasses:["fc-timegrid"],viewSpec:u.viewSpec},(0,s.n)(c,{liquid:!h.isHeightAuto&&!h.forPrint,forPrint:h.forPrint,collapsibleWidth:!1,colGroups:[{width:"shrink",cols:[{width:"shrink"}]},{cols:[{span:r,minWidth:o}]}],sections:g}))}getAllDayMaxEventProps(){let{dayMaxEvents:e,dayMaxEventRows:t}=this.context.options;return!0!==e&&!0!==t||(e=void 0,t=5),{dayMaxEvents:e,dayMaxEventRows:t}}}function p(e){return e.text}class g{constructor(e,t,n){this.positions=e,this.dateProfile=t,this.slotDuration=n}safeComputeTop(e){let{dateProfile:t}=this;if((0,i.H)(t.currentRange,e)){let n=(0,i.q)(e),r=e.valueOf()-n.valueOf();if(r>=(0,i.bs)(t.slotMinTime)&&r<(0,i.bs)(t.slotMaxTime))return this.computeTimeTop((0,i.d)(r))}return null}computeDateTop(e,t){return t||(t=(0,i.q)(e)),this.computeTimeTop((0,i.d)(e.valueOf()-t.valueOf()))}computeTimeTop(e){let t,n,{positions:r,dateProfile:s}=this,o=r.els.length,a=(e.milliseconds-(0,i.bs)(s.slotMinTime))/(0,i.bs)(this.slotDuration);return a=Math.max(0,a),a=Math.min(o,a),t=Math.floor(a),t=Math.min(t,o-1),n=a-t,r.tops[t]+r.getHeight(t)*n}}class m extends i.B{render(){let{props:e,context:t}=this,{options:n}=t,{slatElRefs:r}=e;return(0,s.n)("tbody",null,e.slatMetas.map(((o,a)=>{let l={time:o.time,date:t.dateEnv.toDate(o.date),view:t.viewApi};return(0,s.n)("tr",{key:o.key,ref:r.createRef(o.key)},e.axis&&(0,s.n)(c,Object.assign({},o)),(0,s.n)(i.C,{elTag:"td",elClasses:["fc-timegrid-slot","fc-timegrid-slot-lane",!o.isLabeled&&"fc-timegrid-slot-minor"],elAttrs:{"data-time":o.isoTimeStr},renderProps:l,generatorName:"slotLaneContent",customGenerator:n.slotLaneContent,classNameGenerator:n.slotLaneClassNames,didMount:n.slotLaneDidMount,willUnmount:n.slotLaneWillUnmount}))})))}}class v extends i.B{constructor(){super(...arguments),this.rootElRef=(0,s._3)(),this.slatElRefs=new i.cf}render(){let{props:e,context:t}=this;return(0,s.n)("div",{ref:this.rootElRef,className:"fc-timegrid-slots"},(0,s.n)("table",{"aria-hidden":!0,className:t.theme.getClass("table"),style:{minWidth:e.tableMinWidth,width:e.clientWidth,height:e.minHeight}},e.tableColGroupNode,(0,s.n)(m,{slatElRefs:this.slatElRefs,axis:e.axis,slatMetas:e.slatMetas})))}componentDidMount(){this.updateSizing()}componentDidUpdate(){this.updateSizing()}componentWillUnmount(){this.props.onCoords&&this.props.onCoords(null)}updateSizing(){let{context:e,props:t}=this;if(t.onCoords&&null!==t.clientWidth){this.rootElRef.current.offsetHeight&&t.onCoords(new g(new i.ba(this.rootElRef.current,(n=this.slatElRefs.currentMap,t.slatMetas.map((e=>n[e.key]))),!1,!0),this.props.dateProfile,e.options.slotDuration))}var n}}function y(e,t){let n,r=[];for(n=0;nk(e.hiddenSegs,e),defaultGenerator:A,forceTimed:!0},(e=>(0,s.n)(e,{elTag:"div",elClasses:["fc-timegrid-more-link-inner","fc-sticky"]})))}}function A(e){return e.shortText}function E(e,t,n){let r=new i.bA;null!=t&&(r.strictOrder=t),null!=n&&(r.maxStackCnt=n);let s=r.addSegs(e),o=(0,i.bE)(s),a=function(e){const{entriesByLevel:t}=e,n=w(((e,t)=>e+":"+t),((r,s)=>{let o=function(e,t,n){let{levelCoords:r,entriesByLevel:s}=e,o=s[t][n],a=r[t]+o.thickness,l=r.length,c=t;for(;c(0,i.bB)(e)),((e,r,i)=>{let s,{nextLevelNodes:o,thickness:a}=e,l=a+i,c=a/l,u=[];if(o.length)for(let t of o)if(void 0===s){let e=n(t,r,l);s=e[0],u.push(e[1])}else{let e=n(t,s,0);u.push(e[1])}else s=t;let d=(s-r)*c;return[s-d,Object.assign(Object.assign({},e),{thickness:d,nextLevelNodes:u})]}));return e.map((e=>n(e,0,0)[1]))}(a,1),{segRects:function(e){let t=[];const n=w(((e,t,n)=>(0,i.bB)(e)),((e,n,i)=>{let s=Object.assign(Object.assign({},e),{levelCoord:n,stackDepth:i,stackForward:0});return t.push(s),s.stackForward=r(e.nextLevelNodes,n+e.thickness,i+1)+1}));function r(e,t,r){let i=0;for(let s of e)i=Math.max(n(s,t,r),i);return i}return r(e,0,0),t}(a),hiddenGroups:o}}function _(e,t){if(!e)return[[],0];let{level:n,lateralStart:r,lateralEnd:i}=e,s=r,o=[];for(;s{let i=e(...r);return i in n?n[i]:n[i]=t(...r)}}function C(e,t,n=null,r=0){let i=[];if(n)for(let s=0;s(0,s.n)("div",{className:"fc-timegrid-col-frame"},(0,s.n)("div",{className:"fc-timegrid-col-bg"},this.renderFillSegs(e.businessHourSegs,"non-business"),this.renderFillSegs(e.bgEventSegs,"bg-event"),this.renderFillSegs(e.dateSelectionSegs,"highlight")),(0,s.n)("div",{className:"fc-timegrid-col-events"},this.renderFgSegs(l,a,!1,!1,!1)),(0,s.n)("div",{className:"fc-timegrid-col-events"},this.renderFgSegs(o,{},Boolean(e.eventDrag),Boolean(e.eventResize),Boolean(r),"mirror")),(0,s.n)("div",{className:"fc-timegrid-now-indicator-container"},this.renderNowIndicator(e.nowIndicatorSegs)),(0,i.cm)(n)&&(0,s.n)(t,{elTag:"div",elClasses:["fc-timegrid-col-misc"]}))))}renderFgSegs(e,t,n,r,i,s){let{props:o}=this;return o.forPrint?k(e,o):this.renderPositionedFgSegs(e,t,n,r,i,s)}renderPositionedFgSegs(e,t,n,r,o,a){let{eventMaxStack:l,eventShortHeight:c,eventOrderStrict:u,eventMinHeight:d}=this.context.options,{date:h,slatCoords:f,eventSelection:p,todayRange:g,nowDate:m}=this.props,v=n||r||o,y=C(e,h,f,d),{segPlacements:b,hiddenGroups:D}=function(e,t,n,r){let i=[],s=[];for(let c=0;c{let{seg:l,rect:u}=e,d=l.eventRange.instance.instanceId,h=v||Boolean(!t[d]&&u),f=I(u&&u.span),y=!v&&u?this.computeSegHStyle(u):{left:0,right:0},b=Boolean(u)&&u.stackForward>0,D=Boolean(u)&&u.span.end-u.span.start{let d=I(e.span),h=(f=e.entries,p=t,f.map((e=>p[e.index])));var f,p;return(0,s.n)(D,{key:(0,i.bw)((0,i.cs)(h)),hiddenSegs:h,top:d.top,bottom:d.bottom,extraDateSpan:n,dateProfile:r,todayRange:o,nowDate:a,eventSelection:l,eventDrag:c,eventResize:u})})))}renderFillSegs(e,t){let{props:n,context:r}=this,o=C(e,n.date,n.slatCoords,r.options.eventMinHeight).map(((r,o)=>{let a=e[o];return(0,s.n)("div",{key:(0,i.bT)(a.eventRange),className:"fc-timegrid-bg-harness",style:I(r)},"bg-event"===t?(0,s.n)(i.cp,Object.assign({seg:a},(0,i.bS)(a,n.todayRange,n.nowDate))):(0,i.co)(t))}));return(0,s.n)(s.FK,null,o)}renderNowIndicator(e){let{slatCoords:t,date:n}=this.props;return t?e.map(((e,r)=>(0,s.n)(i.ck,{key:r,elClasses:["fc-timegrid-now-indicator-line"],elStyle:{top:t.computeDateTop(e.start,n)},isAxis:!1,date:n}))):null}computeSegHStyle(e){let t,n,{isRtl:r,options:i}=this.context,s=i.slotEventOverlap,o=e.levelCoord,a=e.levelCoord+e.thickness;s&&(a=Math.min(1,o+2*(a-o))),r?(t=1-a,n=o):(t=o,n=1-a);let l={zIndex:e.stackDepth+1,left:100*t+"%",right:100*n+"%"};return s&&!e.stackForward&&(l[r?"marginLeft":"marginRight"]=20),l}}function k(e,{todayRange:t,nowDate:n,eventSelection:r,eventDrag:o,eventResize:a}){let l=(o?o.affectedInstances:null)||(a?a.affectedInstances:null)||{};return(0,s.n)(s.FK,null,e.map((e=>{let o=e.eventRange.instance.instanceId;return(0,s.n)("div",{key:o,style:{visibility:l[o]?"hidden":""}},(0,s.n)(R,Object.assign({seg:e,isDragging:!1,isResizing:!1,isDateSelecting:!1,isSelected:o===r,isShort:!1},(0,i.bS)(e,t,n))))})))}function I(e){return e?{top:e.start,bottom:-e.end}:{top:"",bottom:""}}class M extends i.B{constructor(){super(...arguments),this.splitFgEventSegs=(0,i.z)(y),this.splitBgEventSegs=(0,i.z)(y),this.splitBusinessHourSegs=(0,i.z)(y),this.splitNowIndicatorSegs=(0,i.z)(y),this.splitDateSelectionSegs=(0,i.z)(y),this.splitEventDrag=(0,i.z)(b),this.splitEventResize=(0,i.z)(b),this.rootElRef=(0,s._3)(),this.cellElRefs=new i.cf}render(){let{props:e,context:t}=this,n=t.options.nowIndicator&&e.slatCoords&&e.slatCoords.safeComputeTop(e.nowDate),r=e.cells.length,o=this.splitFgEventSegs(e.fgEventSegs,r),a=this.splitBgEventSegs(e.bgEventSegs,r),l=this.splitBusinessHourSegs(e.businessHourSegs,r),c=this.splitNowIndicatorSegs(e.nowIndicatorSegs,r),u=this.splitDateSelectionSegs(e.dateSelectionSegs,r),d=this.splitEventDrag(e.eventDrag,r),h=this.splitEventResize(e.eventResize,r);return(0,s.n)("div",{className:"fc-timegrid-cols",ref:this.rootElRef},(0,s.n)("table",{role:"presentation",style:{minWidth:e.tableMinWidth,width:e.clientWidth}},e.tableColGroupNode,(0,s.n)("tbody",{role:"presentation"},(0,s.n)("tr",{role:"row"},e.axis&&(0,s.n)("td",{"aria-hidden":!0,className:"fc-timegrid-col fc-timegrid-axis"},(0,s.n)("div",{className:"fc-timegrid-col-frame"},(0,s.n)("div",{className:"fc-timegrid-now-indicator-container"},"number"==typeof n&&(0,s.n)(i.ck,{elClasses:["fc-timegrid-now-indicator-arrow"],elStyle:{top:n},isAxis:!0,date:e.nowDate})))),e.cells.map(((t,n)=>(0,s.n)(O,{key:t.key,elRef:this.cellElRefs.createRef(t.key),dateProfile:e.dateProfile,date:t.date,nowDate:e.nowDate,todayRange:e.todayRange,extraRenderProps:t.extraRenderProps,extraDataAttrs:t.extraDataAttrs,extraClassNames:t.extraClassNames,extraDateSpan:t.extraDateSpan,fgEventSegs:o[n],bgEventSegs:a[n],businessHourSegs:l[n],nowIndicatorSegs:c[n],dateSelectionSegs:u[n],eventDrag:d[n],eventResize:h[n],slatCoords:e.slatCoords,eventSelection:e.eventSelection,forPrint:e.forPrint})))))))}componentDidMount(){this.updateCoords()}componentDidUpdate(){this.updateCoords()}updateCoords(){let{props:e}=this;var t;e.onColCoords&&null!==e.clientWidth&&e.onColCoords(new i.ba(this.rootElRef.current,(t=this.cellElRefs.currentMap,e.cells.map((e=>t[e.key]))),!0,!1))}}class N extends i.be{constructor(){super(...arguments),this.processSlotOptions=(0,i.z)(P),this.state={slatCoords:null},this.handleRootEl=e=>{e?this.context.registerInteractiveComponent(this,{el:e,isHitComboAllowed:this.props.isHitComboAllowed}):this.context.unregisterInteractiveComponent(this)},this.handleScrollRequest=e=>{let{onScrollTopRequest:t}=this.props,{slatCoords:n}=this.state;if(t&&n){if(e.time){let r=n.computeTimeTop(e.time);r=Math.ceil(r),r&&(r+=1),t(r)}return!0}return!1},this.handleColCoords=e=>{this.colCoords=e},this.handleSlatCoords=e=>{this.setState({slatCoords:e}),this.props.onSlatCoords&&this.props.onSlatCoords(e)}}render(){let{props:e,state:t}=this;return(0,s.n)("div",{className:"fc-timegrid-body",ref:this.handleRootEl,style:{width:e.clientWidth,minWidth:e.tableMinWidth}},(0,s.n)(v,{axis:e.axis,dateProfile:e.dateProfile,slatMetas:e.slatMetas,clientWidth:e.clientWidth,minHeight:e.expandRows?e.clientHeight:"",tableMinWidth:e.tableMinWidth,tableColGroupNode:e.axis?e.tableColGroupNode:null,onCoords:this.handleSlatCoords}),(0,s.n)(M,{cells:e.cells,axis:e.axis,dateProfile:e.dateProfile,businessHourSegs:e.businessHourSegs,bgEventSegs:e.bgEventSegs,fgEventSegs:e.fgEventSegs,dateSelectionSegs:e.dateSelectionSegs,eventSelection:e.eventSelection,eventDrag:e.eventDrag,eventResize:e.eventResize,todayRange:e.todayRange,nowDate:e.nowDate,nowIndicatorSegs:e.nowIndicatorSegs,clientWidth:e.clientWidth,tableMinWidth:e.tableMinWidth,tableColGroupNode:e.tableColGroupNode,slatCoords:t.slatCoords,onColCoords:this.handleColCoords,forPrint:e.forPrint}))}componentDidMount(){this.scrollResponder=this.context.createScrollResponder(this.handleScrollRequest)}componentDidUpdate(e){this.scrollResponder.update(e.dateProfile!==this.props.dateProfile)}componentWillUnmount(){this.scrollResponder.detach()}queryHit(e,t){let{dateEnv:n,options:r}=this.context,{colCoords:s}=this,{dateProfile:o}=this.props,{slatCoords:a}=this.state,{snapDuration:l,snapsPerSlot:c}=this.processSlotOptions(this.props.slotDuration,r.snapDuration),u=s.leftToIndex(e),d=a.positions.topToIndex(t);if(null!=u&&null!=d){let e=this.props.cells[u],r=a.positions.tops[d],h=a.positions.getHeight(d),f=(t-r)/h,p=d*c+Math.floor(f*c),g=this.props.cells[u].date,m=(0,i.bp)(o.slotMinTime,(0,i.bo)(l,p)),v=n.add(g,m),y=n.add(v,l);return{dateProfile:o,dateSpan:Object.assign({range:{start:v,end:y},allDay:!1},e.extraDateSpan),dayEl:s.els[u],rect:{left:s.lefts[u],right:s.rights[u],top:r,bottom:r+h},layer:0}}return null}}function P(e,t){let n=t||e,r=(0,i.bt)(e,n);return null===r&&(n=e,r=1),{snapDuration:n,snapsPerSlot:r}}class B extends i.bW{sliceRange(e,t){let n=[];for(let r=0;r(0,s.n)(N,Object.assign({ref:this.timeColsRef},this.slicer.sliceProps(e,n,null,t,l),{forPrint:e.forPrint,axis:e.axis,dateProfile:n,slatMetas:e.slatMetas,slotDuration:e.slotDuration,cells:r.cells[0],tableColGroupNode:e.tableColGroupNode,tableMinWidth:e.tableMinWidth,clientWidth:e.clientWidth,clientHeight:e.clientHeight,expandRows:e.expandRows,nowDate:i,nowIndicatorSegs:o&&this.slicer.sliceNowDate(i,n,a,t,l),todayRange:c,onScrollTopRequest:e.onScrollTopRequest,onSlatCoords:e.onSlatCoords}))))}}function H(e,t,n){let r=[];for(let i of e.headerDates)r.push({start:n.add(i,t.slotMinTime),end:n.add(i,t.slotMaxTime)});return r}const Y=[{hours:1},{minutes:30},{minutes:15},{seconds:30},{seconds:15}];function U(e,t,n,r,s){let o=new Date(0),a=e,l=(0,i.d)(0),c=n||function(e){let t,n,r;for(t=Y.length-1;t>=0;t-=1)if(n=(0,i.d)(Y[t]),r=(0,i.bt)(n,e),null!==r&&r>1)return n;return e}(r),u=[];for(;(0,i.bs)(a)<(0,i.bs)(t);){let e=s.add(o,a),t=null!==(0,i.bt)(l,c);u.push({date:e,time:a,key:e.toISOString(),isoTimeStr:(0,i.bu)(e),isLabeled:t}),a=(0,i.bp)(a,r),l=(0,i.bp)(l,r)}return u}function j(e,t){let n=new i.bO(e.renderRange,t);return new i.bV(n,!1)}(0,i.cw)('.fc-v-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-v-event .fc-event-main{color:var(--fc-event-text-color);height:100%}.fc-v-event .fc-event-main-frame{display:flex;flex-direction:column;height:100%}.fc-v-event .fc-event-time{flex-grow:0;flex-shrink:0;max-height:100%;overflow:hidden}.fc-v-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-height:0}.fc-v-event .fc-event-title{bottom:0;max-height:100%;overflow:hidden;top:0}.fc-v-event:not(.fc-event-start){border-top-left-radius:0;border-top-right-radius:0;border-top-width:0}.fc-v-event:not(.fc-event-end){border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-width:0}.fc-v-event.fc-event-selected:before{left:-10px;right:-10px}.fc-v-event .fc-event-resizer-start{cursor:n-resize}.fc-v-event .fc-event-resizer-end{cursor:s-resize}.fc-v-event:not(.fc-event-selected) .fc-event-resizer{height:var(--fc-event-resizer-thickness);left:0;right:0}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-start{top:calc(var(--fc-event-resizer-thickness)/-2)}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-end{bottom:calc(var(--fc-event-resizer-thickness)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer{left:50%;margin-left:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer-start{top:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer-end{bottom:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc .fc-timegrid .fc-daygrid-body{z-index:2}.fc .fc-timegrid-divider{padding:0 0 2px}.fc .fc-timegrid-body{min-height:100%;position:relative;z-index:1}.fc .fc-timegrid-axis-chunk{position:relative}.fc .fc-timegrid-axis-chunk>table,.fc .fc-timegrid-slots{position:relative;z-index:1}.fc .fc-timegrid-slot{border-bottom:0;height:1.5em}.fc .fc-timegrid-slot:empty:before{content:"\\00a0"}.fc .fc-timegrid-slot-minor{border-top-style:dotted}.fc .fc-timegrid-slot-label-cushion{display:inline-block;white-space:nowrap}.fc .fc-timegrid-slot-label{vertical-align:middle}.fc .fc-timegrid-axis-cushion,.fc .fc-timegrid-slot-label-cushion{padding:0 4px}.fc .fc-timegrid-axis-frame-liquid{height:100%}.fc .fc-timegrid-axis-frame{align-items:center;display:flex;justify-content:flex-end;overflow:hidden}.fc .fc-timegrid-axis-cushion{flex-shrink:0;max-width:60px}.fc-direction-ltr .fc-timegrid-slot-label-frame{text-align:right}.fc-direction-rtl .fc-timegrid-slot-label-frame{text-align:left}.fc-liquid-hack .fc-timegrid-axis-frame-liquid{bottom:0;height:auto;left:0;position:absolute;right:0;top:0}.fc .fc-timegrid-col.fc-day-today{background-color:var(--fc-today-bg-color)}.fc .fc-timegrid-col-frame{min-height:100%;position:relative}.fc-media-screen.fc-liquid-hack .fc-timegrid-col-frame{bottom:0;height:auto;left:0;position:absolute;right:0;top:0}.fc-media-screen .fc-timegrid-cols{bottom:0;left:0;position:absolute;right:0;top:0}.fc-media-screen .fc-timegrid-cols>table{height:100%}.fc-media-screen .fc-timegrid-col-bg,.fc-media-screen .fc-timegrid-col-events,.fc-media-screen .fc-timegrid-now-indicator-container{left:0;position:absolute;right:0;top:0}.fc .fc-timegrid-col-bg{z-index:2}.fc .fc-timegrid-col-bg .fc-non-business{z-index:1}.fc .fc-timegrid-col-bg .fc-bg-event{z-index:2}.fc .fc-timegrid-col-bg .fc-highlight{z-index:3}.fc .fc-timegrid-bg-harness{left:0;position:absolute;right:0}.fc .fc-timegrid-col-events{z-index:3}.fc .fc-timegrid-now-indicator-container{bottom:0;overflow:hidden}.fc-direction-ltr .fc-timegrid-col-events{margin:0 2.5% 0 2px}.fc-direction-rtl .fc-timegrid-col-events{margin:0 2px 0 2.5%}.fc-timegrid-event-harness{position:absolute}.fc-timegrid-event-harness>.fc-timegrid-event{bottom:0;left:0;position:absolute;right:0;top:0}.fc-timegrid-event-harness-inset .fc-timegrid-event,.fc-timegrid-event.fc-event-mirror,.fc-timegrid-more-link{box-shadow:0 0 0 1px var(--fc-page-bg-color)}.fc-timegrid-event,.fc-timegrid-more-link{border-radius:3px;font-size:var(--fc-small-font-size)}.fc-timegrid-event{margin-bottom:1px}.fc-timegrid-event .fc-event-main{padding:1px 1px 0}.fc-timegrid-event .fc-event-time{font-size:var(--fc-small-font-size);margin-bottom:1px;white-space:nowrap}.fc-timegrid-event-short .fc-event-main-frame{flex-direction:row;overflow:hidden}.fc-timegrid-event-short .fc-event-time:after{content:"\\00a0-\\00a0"}.fc-timegrid-event-short .fc-event-title{font-size:var(--fc-small-font-size)}.fc-timegrid-more-link{background:var(--fc-more-link-bg-color);color:var(--fc-more-link-text-color);cursor:pointer;margin-bottom:1px;position:absolute;z-index:9999}.fc-timegrid-more-link-inner{padding:3px 2px;top:0}.fc-direction-ltr .fc-timegrid-more-link{right:0}.fc-direction-rtl .fc-timegrid-more-link{left:0}.fc .fc-timegrid-now-indicator-line{border-color:var(--fc-now-indicator-color);border-style:solid;border-width:1px 0 0;left:0;position:absolute;right:0;z-index:4}.fc .fc-timegrid-now-indicator-arrow{border-color:var(--fc-now-indicator-color);border-style:solid;margin-top:-5px;position:absolute;z-index:4}.fc-direction-ltr .fc-timegrid-now-indicator-arrow{border-bottom-color:transparent;border-top-color:transparent;border-width:5px 0 5px 6px;left:0}.fc-direction-rtl .fc-timegrid-now-indicator-arrow{border-bottom-color:transparent;border-top-color:transparent;border-width:5px 6px 5px 0;right:0}');const L={allDaySlot:Boolean};var W=(0,r.i1)({name:"@fullcalendar/timegrid",initialView:"timeGridWeek",optionRefiners:L,views:{timeGrid:{component:class extends f{constructor(){super(...arguments),this.buildTimeColsModel=(0,i.z)(j),this.buildSlatMetas=(0,i.z)(U)}render(){let{options:e,dateEnv:t,dateProfileGenerator:n}=this.context,{props:r}=this,{dateProfile:a}=r,l=this.buildTimeColsModel(a,n),c=this.allDaySplitter.splitProps(r),u=this.buildSlatMetas(a.slotMinTime,a.slotMaxTime,e.slotLabelInterval,e.slotDuration,t),{dayMinWidth:d}=e,h=!d,f=d,p=e.dayHeaders&&(0,s.n)(i.bK,{dates:l.headerDates,dateProfile:a,datesRepDistinctDays:!0,renderIntro:h?this.renderHeadAxis:null}),g=!1!==e.allDaySlot&&(t=>(0,s.n)(o.t7,Object.assign({},c.allDay,{dateProfile:a,dayTableModel:l,nextDayThreshold:e.nextDayThreshold,tableMinWidth:t.tableMinWidth,colGroupNode:t.tableColGroupNode,renderRowIntro:h?this.renderTableRowAxis:null,showWeekNumbers:!1,expandRows:!1,headerAlignElRef:this.headerElRef,clientWidth:t.clientWidth,clientHeight:t.clientHeight,forPrint:r.forPrint},this.getAllDayMaxEventProps()))),m=t=>(0,s.n)(z,Object.assign({},c.timed,{dayTableModel:l,dateProfile:a,axis:h,slotDuration:e.slotDuration,slatMetas:u,forPrint:r.forPrint,tableColGroupNode:t.tableColGroupNode,tableMinWidth:t.tableMinWidth,clientWidth:t.clientWidth,clientHeight:t.clientHeight,onSlatCoords:this.handleSlatCoords,expandRows:t.expandRows,onScrollTopRequest:this.handleScrollTopRequest}));return f?this.renderHScrollLayout(p,g,m,l.colCnt,d,u,this.state.slatCoords):this.renderSimpleLayout(p,g,m)}},usesMinMaxTime:!0,allDaySlot:!0,slotDuration:"00:30:00",slotEventOverlap:!0},timeGridDay:{type:"timeGrid",duration:{days:1}},timeGridWeek:{type:"timeGrid",duration:{weeks:1}}}})},28453:(e,t,n)=>{"use strict";n.d(t,{R:()=>o,x:()=>a});var r=n(96540);const i={},s=r.createContext(i);function o(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/20da611c.b1d46624.js b/assets/js/20da611c.b1d46624.js new file mode 100644 index 0000000000..7dff743266 --- /dev/null +++ b/assets/js/20da611c.b1d46624.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7491],{57432:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var t=s(74848),o=s(28453);const r={},i="K3s support",a={id:"operating-scs/components/monitoring/docs/k3s",title:"K3s support",description:"K3s is a certified Kubernetes distribution optimized for production environments, particularly in remote locations",source:"@site/docs/04-operating-scs/components/monitoring/docs/k3s.md",sourceDirName:"04-operating-scs/components/monitoring/docs",slug:"/operating-scs/components/monitoring/docs/k3s",permalink:"/docs/operating-scs/components/monitoring/docs/k3s",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/k3s.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"SCS deployment",permalink:"/docs/operating-scs/components/monitoring/docs/scs-deployment"},next:{title:"Infrastructure service endpoints",permalink:"/docs/operating-scs/components/monitoring/docs/infrastructure_services"}},l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Prepare K3s Kubernetes cluster via K3d",id:"prepare-k3s-kubernetes-cluster-via-k3d",level:2},{value:"Deploy Observer monitoring solution",id:"deploy-observer-monitoring-solution",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"k3s-support",children:"K3s support"}),"\n",(0,t.jsx)(n.p,{children:"K3s is a certified Kubernetes distribution optimized for production environments, particularly in remote locations\nor resource-constrained environments. Within the OSISM IaaS distribution, it serves as the management cluster,\naccommodating various management software. Our aim is to integrate the SCS Observability platform as an observer solution\nfor the IaaS layer. To achieve this, we deploy the SCS Observability solution within the IaaS k3s management cluster.\nThis setup enables us to monitor not only the management k3s cluster itself but also the surrounding IaaS control\nplane components."}),"\n",(0,t.jsx)(n.p,{children:"This page contains information on how to develop and/or test the Observer solution as a monitoring solution for a k3s\ncluster. It guides the user to create an HA k3s cluster via k3d (a wrapper to run k3s in Docker) and bootstrap\nit with the Observer solution."}),"\n",(0,t.jsxs)(n.p,{children:["Note that the following tutorial guides you to deploy an HA K3s cluster consisting of 3 control plane nodes (servers)\nand one worker node (agent). The reason is that the HA K3s cluster utilizes an embedded etcd cluster as cluster storage\n(refer to ",(0,t.jsx)(n.a,{href:"https://docs.k3s.io/datastore/ha-embedded",children:"https://docs.k3s.io/datastore/ha-embedded"}),") and the HA mode is also used in OSISM Testbed and productive bare\nmetal deployments.\nUsing a single-node K3s cluster that uses the SQLite database (default) requires additional tweaks of monitoring values,\nwhich are not covered in this guide."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://k3d.io/#installation",children:"K3d"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://helm.sh/",children:"helm"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://kubernetes.io/docs/reference/kubectl/",children:"kubectl"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"prepare-k3s-kubernetes-cluster-via-k3d",children:"Prepare K3s Kubernetes cluster via K3d"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"k3d cluster create --config k3s-config.yaml --image rancher/k3s:v1.28.8-k3s1 observer\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you opt not to use K3D with the custom config we provided here, and prefer utilizing another Kubernetes cluster,\nensure that the metric endpoints for various control plane components are properly exposed.\nRefer to the ",(0,t.jsx)(n.a,{href:"https://dnationcloud.github.io/kubernetes-monitoring/helpers/FAQ/#kubernetes-monitoring-shows-or-0-state-for-some-control-plane-components-are-control-plane-components-working-correctly",children:"docs"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"deploy-observer-monitoring-solution",children:"Deploy Observer monitoring solution"}),"\n",(0,t.jsxs)(n.p,{children:["K3s consolidates all Kubernetes control plane components into a single process, which means that the metrics for these\ncontrol plane components are exposed on the K3d hosts rather than through individual Kubernetes Services/PODs.\nTo customize monitoring values for K3s, refer to the specific custom HELM values file ",(0,t.jsx)(n.code,{children:"values-observer-k3s.yaml"}),".\nThis file contains the necessary configurations and adjustments needed to monitor K3s.\nNote that list of control plane node IPs (endpoints) should be overridden."]}),"\n",(0,t.jsx)(n.p,{children:"Get and store the K3d control plane node IPs:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NODE_IPS=$(kubectl get nodes -l node-role.kubernetes.io/control-plane=true -o jsonpath='{.items[*].status.addresses[?(@.type==\"InternalIP\")].address}' | tr ' ' ',' | sed 's/^/{&/;s/$/}/')\n"})}),"\n",(0,t.jsx)(n.p,{children:"Install the monitoring stack and set the control plane component endpoints"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/\nhelm repo update dnationcloud\nhelm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer-k3s.yaml \\\n --set "kube-prometheus-stack.kubeEtcd.endpoints=$NODE_IPS" \\\n --set "kube-prometheus-stack.kubeProxy.endpoints=$NODE_IPS" \\\n --set "kube-prometheus-stack.kubeControllerManager.endpoints=$NODE_IPS" \\\n --set "kube-prometheus-stack.kubeScheduler.endpoints=$NODE_IPS"\n'})}),"\n",(0,t.jsx)(n.h1,{id:"access-the-observer-monitoring-uis",children:"Access the Observer monitoring UIs"}),"\n",(0,t.jsx)(n.p,{children:"At this point, you should have the ability to access the Grafana, Alertmanager and Prometheus UIs\nwithin the Observer monitoring cluster."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Grafana UI"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"http://localhost:30000\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Use the following credentials:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["username: ",(0,t.jsx)(n.code,{children:"admin"})]}),"\n",(0,t.jsxs)(n.li,{children:["password: ",(0,t.jsx)(n.code,{children:"pass"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Visit the Layer 0 dashboard, ",(0,t.jsx)(n.code,{children:"infrastructure-services-monitoring"}),", and drill down to explore cluster metrics"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"http://localhost:30000/d/monitoring/infrastructure-services-monitoring",children:"http://localhost:30000/d/monitoring/infrastructure-services-monitoring"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Alertmanager UI"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"http://localhost:30001\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Prometheus UI"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"http://localhost:30002\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const o={},r=t.createContext(o);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/211.56f0ff97.js b/assets/js/211.56f0ff97.js new file mode 100644 index 0000000000..11412ad9f6 --- /dev/null +++ b/assets/js/211.56f0ff97.js @@ -0,0 +1,3478 @@ +"use strict"; +exports.id = 211; +exports.ids = [211]; +exports.modules = { + +/***/ 77211: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(58886); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16750); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(74353); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99418); + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 2], $V1 = [1, 3], $V2 = [1, 4], $V3 = [2, 4], $V4 = [1, 9], $V5 = [1, 11], $V6 = [1, 13], $V7 = [1, 14], $V8 = [1, 16], $V9 = [1, 17], $Va = [1, 18], $Vb = [1, 24], $Vc = [1, 25], $Vd = [1, 26], $Ve = [1, 27], $Vf = [1, 28], $Vg = [1, 29], $Vh = [1, 30], $Vi = [1, 31], $Vj = [1, 32], $Vk = [1, 33], $Vl = [1, 34], $Vm = [1, 35], $Vn = [1, 36], $Vo = [1, 37], $Vp = [1, 38], $Vq = [1, 39], $Vr = [1, 41], $Vs = [1, 42], $Vt = [1, 43], $Vu = [1, 44], $Vv = [1, 45], $Vw = [1, 46], $Vx = [1, 4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 47, 48, 49, 50, 52, 53, 54, 59, 60, 61, 62, 70], $Vy = [4, 5, 16, 50, 52, 53], $Vz = [4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 50, 52, 53, 54, 59, 60, 61, 62, 70], $VA = [4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 49, 50, 52, 53, 54, 59, 60, 61, 62, 70], $VB = [4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 48, 50, 52, 53, 54, 59, 60, 61, 62, 70], $VC = [4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 47, 50, 52, 53, 54, 59, 60, 61, 62, 70], $VD = [68, 69, 70], $VE = [1, 120]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "SPACE": 4, "NEWLINE": 5, "SD": 6, "document": 7, "line": 8, "statement": 9, "box_section": 10, "box_line": 11, "participant_statement": 12, "create": 13, "box": 14, "restOfLine": 15, "end": 16, "signal": 17, "autonumber": 18, "NUM": 19, "off": 20, "activate": 21, "actor": 22, "deactivate": 23, "note_statement": 24, "links_statement": 25, "link_statement": 26, "properties_statement": 27, "details_statement": 28, "title": 29, "legacy_title": 30, "acc_title": 31, "acc_title_value": 32, "acc_descr": 33, "acc_descr_value": 34, "acc_descr_multiline_value": 35, "loop": 36, "rect": 37, "opt": 38, "alt": 39, "else_sections": 40, "par": 41, "par_sections": 42, "par_over": 43, "critical": 44, "option_sections": 45, "break": 46, "option": 47, "and": 48, "else": 49, "participant": 50, "AS": 51, "participant_actor": 52, "destroy": 53, "note": 54, "placement": 55, "text2": 56, "over": 57, "actor_pair": 58, "links": 59, "link": 60, "properties": 61, "details": 62, "spaceList": 63, ",": 64, "left_of": 65, "right_of": 66, "signaltype": 67, "+": 68, "-": 69, "ACTOR": 70, "SOLID_OPEN_ARROW": 71, "DOTTED_OPEN_ARROW": 72, "SOLID_ARROW": 73, "DOTTED_ARROW": 74, "SOLID_CROSS": 75, "DOTTED_CROSS": 76, "SOLID_POINT": 77, "DOTTED_POINT": 78, "TXT": 79, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "SPACE", 5: "NEWLINE", 6: "SD", 13: "create", 14: "box", 15: "restOfLine", 16: "end", 18: "autonumber", 19: "NUM", 20: "off", 21: "activate", 23: "deactivate", 29: "title", 30: "legacy_title", 31: "acc_title", 32: "acc_title_value", 33: "acc_descr", 34: "acc_descr_value", 35: "acc_descr_multiline_value", 36: "loop", 37: "rect", 38: "opt", 39: "alt", 41: "par", 43: "par_over", 44: "critical", 46: "break", 47: "option", 48: "and", 49: "else", 50: "participant", 51: "AS", 52: "participant_actor", 53: "destroy", 54: "note", 57: "over", 59: "links", 60: "link", 61: "properties", 62: "details", 64: ",", 65: "left_of", 66: "right_of", 68: "+", 69: "-", 70: "ACTOR", 71: "SOLID_OPEN_ARROW", 72: "DOTTED_OPEN_ARROW", 73: "SOLID_ARROW", 74: "DOTTED_ARROW", 75: "SOLID_CROSS", 76: "DOTTED_CROSS", 77: "SOLID_POINT", 78: "DOTTED_POINT", 79: "TXT" }, + productions_: [0, [3, 2], [3, 2], [3, 2], [7, 0], [7, 2], [8, 2], [8, 1], [8, 1], [10, 0], [10, 2], [11, 2], [11, 1], [11, 1], [9, 1], [9, 2], [9, 4], [9, 2], [9, 4], [9, 3], [9, 3], [9, 2], [9, 3], [9, 3], [9, 2], [9, 2], [9, 2], [9, 2], [9, 2], [9, 1], [9, 1], [9, 2], [9, 2], [9, 1], [9, 4], [9, 4], [9, 4], [9, 4], [9, 4], [9, 4], [9, 4], [9, 4], [45, 1], [45, 4], [42, 1], [42, 4], [40, 1], [40, 4], [12, 5], [12, 3], [12, 5], [12, 3], [12, 3], [24, 4], [24, 4], [25, 3], [26, 3], [27, 3], [28, 3], [63, 2], [63, 1], [58, 3], [58, 1], [55, 1], [55, 1], [17, 5], [17, 5], [17, 4], [22, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [56, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 3: + yy.apply($$[$0]); + return $$[$0]; + case 4: + case 9: + this.$ = []; + break; + case 5: + case 10: + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + break; + case 6: + case 7: + case 11: + case 12: + this.$ = $$[$0]; + break; + case 8: + case 13: + this.$ = []; + break; + case 15: + $$[$0].type = "createParticipant"; + this.$ = $$[$0]; + break; + case 16: + $$[$0 - 1].unshift({ type: "boxStart", boxData: yy.parseBoxData($$[$0 - 2]) }); + $$[$0 - 1].push({ type: "boxEnd", boxText: $$[$0 - 2] }); + this.$ = $$[$0 - 1]; + break; + case 18: + this.$ = { type: "sequenceIndex", sequenceIndex: Number($$[$0 - 2]), sequenceIndexStep: Number($$[$0 - 1]), sequenceVisible: true, signalType: yy.LINETYPE.AUTONUMBER }; + break; + case 19: + this.$ = { type: "sequenceIndex", sequenceIndex: Number($$[$0 - 1]), sequenceIndexStep: 1, sequenceVisible: true, signalType: yy.LINETYPE.AUTONUMBER }; + break; + case 20: + this.$ = { type: "sequenceIndex", sequenceVisible: false, signalType: yy.LINETYPE.AUTONUMBER }; + break; + case 21: + this.$ = { type: "sequenceIndex", sequenceVisible: true, signalType: yy.LINETYPE.AUTONUMBER }; + break; + case 22: + this.$ = { type: "activeStart", signalType: yy.LINETYPE.ACTIVE_START, actor: $$[$0 - 1] }; + break; + case 23: + this.$ = { type: "activeEnd", signalType: yy.LINETYPE.ACTIVE_END, actor: $$[$0 - 1] }; + break; + case 29: + yy.setDiagramTitle($$[$0].substring(6)); + this.$ = $$[$0].substring(6); + break; + case 30: + yy.setDiagramTitle($$[$0].substring(7)); + this.$ = $$[$0].substring(7); + break; + case 31: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 32: + case 33: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 34: + $$[$0 - 1].unshift({ type: "loopStart", loopText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.LOOP_START }); + $$[$0 - 1].push({ type: "loopEnd", loopText: $$[$0 - 2], signalType: yy.LINETYPE.LOOP_END }); + this.$ = $$[$0 - 1]; + break; + case 35: + $$[$0 - 1].unshift({ type: "rectStart", color: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.RECT_START }); + $$[$0 - 1].push({ type: "rectEnd", color: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.RECT_END }); + this.$ = $$[$0 - 1]; + break; + case 36: + $$[$0 - 1].unshift({ type: "optStart", optText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.OPT_START }); + $$[$0 - 1].push({ type: "optEnd", optText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.OPT_END }); + this.$ = $$[$0 - 1]; + break; + case 37: + $$[$0 - 1].unshift({ type: "altStart", altText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.ALT_START }); + $$[$0 - 1].push({ type: "altEnd", signalType: yy.LINETYPE.ALT_END }); + this.$ = $$[$0 - 1]; + break; + case 38: + $$[$0 - 1].unshift({ type: "parStart", parText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.PAR_START }); + $$[$0 - 1].push({ type: "parEnd", signalType: yy.LINETYPE.PAR_END }); + this.$ = $$[$0 - 1]; + break; + case 39: + $$[$0 - 1].unshift({ type: "parStart", parText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.PAR_OVER_START }); + $$[$0 - 1].push({ type: "parEnd", signalType: yy.LINETYPE.PAR_END }); + this.$ = $$[$0 - 1]; + break; + case 40: + $$[$0 - 1].unshift({ type: "criticalStart", criticalText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.CRITICAL_START }); + $$[$0 - 1].push({ type: "criticalEnd", signalType: yy.LINETYPE.CRITICAL_END }); + this.$ = $$[$0 - 1]; + break; + case 41: + $$[$0 - 1].unshift({ type: "breakStart", breakText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.BREAK_START }); + $$[$0 - 1].push({ type: "breakEnd", optText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.BREAK_END }); + this.$ = $$[$0 - 1]; + break; + case 43: + this.$ = $$[$0 - 3].concat([{ type: "option", optionText: yy.parseMessage($$[$0 - 1]), signalType: yy.LINETYPE.CRITICAL_OPTION }, $$[$0]]); + break; + case 45: + this.$ = $$[$0 - 3].concat([{ type: "and", parText: yy.parseMessage($$[$0 - 1]), signalType: yy.LINETYPE.PAR_AND }, $$[$0]]); + break; + case 47: + this.$ = $$[$0 - 3].concat([{ type: "else", altText: yy.parseMessage($$[$0 - 1]), signalType: yy.LINETYPE.ALT_ELSE }, $$[$0]]); + break; + case 48: + $$[$0 - 3].draw = "participant"; + $$[$0 - 3].type = "addParticipant"; + $$[$0 - 3].description = yy.parseMessage($$[$0 - 1]); + this.$ = $$[$0 - 3]; + break; + case 49: + $$[$0 - 1].draw = "participant"; + $$[$0 - 1].type = "addParticipant"; + this.$ = $$[$0 - 1]; + break; + case 50: + $$[$0 - 3].draw = "actor"; + $$[$0 - 3].type = "addParticipant"; + $$[$0 - 3].description = yy.parseMessage($$[$0 - 1]); + this.$ = $$[$0 - 3]; + break; + case 51: + $$[$0 - 1].draw = "actor"; + $$[$0 - 1].type = "addParticipant"; + this.$ = $$[$0 - 1]; + break; + case 52: + $$[$0 - 1].type = "destroyParticipant"; + this.$ = $$[$0 - 1]; + break; + case 53: + this.$ = [$$[$0 - 1], { type: "addNote", placement: $$[$0 - 2], actor: $$[$0 - 1].actor, text: $$[$0] }]; + break; + case 54: + $$[$0 - 2] = [].concat($$[$0 - 1], $$[$0 - 1]).slice(0, 2); + $$[$0 - 2][0] = $$[$0 - 2][0].actor; + $$[$0 - 2][1] = $$[$0 - 2][1].actor; + this.$ = [$$[$0 - 1], { type: "addNote", placement: yy.PLACEMENT.OVER, actor: $$[$0 - 2].slice(0, 2), text: $$[$0] }]; + break; + case 55: + this.$ = [$$[$0 - 1], { type: "addLinks", actor: $$[$0 - 1].actor, text: $$[$0] }]; + break; + case 56: + this.$ = [$$[$0 - 1], { type: "addALink", actor: $$[$0 - 1].actor, text: $$[$0] }]; + break; + case 57: + this.$ = [$$[$0 - 1], { type: "addProperties", actor: $$[$0 - 1].actor, text: $$[$0] }]; + break; + case 58: + this.$ = [$$[$0 - 1], { type: "addDetails", actor: $$[$0 - 1].actor, text: $$[$0] }]; + break; + case 61: + this.$ = [$$[$0 - 2], $$[$0]]; + break; + case 62: + this.$ = $$[$0]; + break; + case 63: + this.$ = yy.PLACEMENT.LEFTOF; + break; + case 64: + this.$ = yy.PLACEMENT.RIGHTOF; + break; + case 65: + this.$ = [ + $$[$0 - 4], + $$[$0 - 1], + { type: "addMessage", from: $$[$0 - 4].actor, to: $$[$0 - 1].actor, signalType: $$[$0 - 3], msg: $$[$0], activate: true }, + { type: "activeStart", signalType: yy.LINETYPE.ACTIVE_START, actor: $$[$0 - 1] } + ]; + break; + case 66: + this.$ = [ + $$[$0 - 4], + $$[$0 - 1], + { type: "addMessage", from: $$[$0 - 4].actor, to: $$[$0 - 1].actor, signalType: $$[$0 - 3], msg: $$[$0] }, + { type: "activeEnd", signalType: yy.LINETYPE.ACTIVE_END, actor: $$[$0 - 4] } + ]; + break; + case 67: + this.$ = [$$[$0 - 3], $$[$0 - 1], { type: "addMessage", from: $$[$0 - 3].actor, to: $$[$0 - 1].actor, signalType: $$[$0 - 2], msg: $$[$0] }]; + break; + case 68: + this.$ = { type: "addParticipant", actor: $$[$0] }; + break; + case 69: + this.$ = yy.LINETYPE.SOLID_OPEN; + break; + case 70: + this.$ = yy.LINETYPE.DOTTED_OPEN; + break; + case 71: + this.$ = yy.LINETYPE.SOLID; + break; + case 72: + this.$ = yy.LINETYPE.DOTTED; + break; + case 73: + this.$ = yy.LINETYPE.SOLID_CROSS; + break; + case 74: + this.$ = yy.LINETYPE.DOTTED_CROSS; + break; + case 75: + this.$ = yy.LINETYPE.SOLID_POINT; + break; + case 76: + this.$ = yy.LINETYPE.DOTTED_POINT; + break; + case 77: + this.$ = yy.parseMessage($$[$0].trim().substring(1)); + break; + } + }, + table: [{ 3: 1, 4: $V0, 5: $V1, 6: $V2 }, { 1: [3] }, { 3: 5, 4: $V0, 5: $V1, 6: $V2 }, { 3: 6, 4: $V0, 5: $V1, 6: $V2 }, o([1, 4, 5, 13, 14, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 50, 52, 53, 54, 59, 60, 61, 62, 70], $V3, { 7: 7 }), { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3], 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, o($Vx, [2, 5]), { 9: 47, 12: 12, 13: $V6, 14: $V7, 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, o($Vx, [2, 7]), o($Vx, [2, 8]), o($Vx, [2, 14]), { 12: 48, 50: $Vo, 52: $Vp, 53: $Vq }, { 15: [1, 49] }, { 5: [1, 50] }, { 5: [1, 53], 19: [1, 51], 20: [1, 52] }, { 22: 54, 70: $Vw }, { 22: 55, 70: $Vw }, { 5: [1, 56] }, { 5: [1, 57] }, { 5: [1, 58] }, { 5: [1, 59] }, { 5: [1, 60] }, o($Vx, [2, 29]), o($Vx, [2, 30]), { 32: [1, 61] }, { 34: [1, 62] }, o($Vx, [2, 33]), { 15: [1, 63] }, { 15: [1, 64] }, { 15: [1, 65] }, { 15: [1, 66] }, { 15: [1, 67] }, { 15: [1, 68] }, { 15: [1, 69] }, { 15: [1, 70] }, { 22: 71, 70: $Vw }, { 22: 72, 70: $Vw }, { 22: 73, 70: $Vw }, { 67: 74, 71: [1, 75], 72: [1, 76], 73: [1, 77], 74: [1, 78], 75: [1, 79], 76: [1, 80], 77: [1, 81], 78: [1, 82] }, { 55: 83, 57: [1, 84], 65: [1, 85], 66: [1, 86] }, { 22: 87, 70: $Vw }, { 22: 88, 70: $Vw }, { 22: 89, 70: $Vw }, { 22: 90, 70: $Vw }, o([5, 51, 64, 71, 72, 73, 74, 75, 76, 77, 78, 79], [2, 68]), o($Vx, [2, 6]), o($Vx, [2, 15]), o($Vy, [2, 9], { 10: 91 }), o($Vx, [2, 17]), { 5: [1, 93], 19: [1, 92] }, { 5: [1, 94] }, o($Vx, [2, 21]), { 5: [1, 95] }, { 5: [1, 96] }, o($Vx, [2, 24]), o($Vx, [2, 25]), o($Vx, [2, 26]), o($Vx, [2, 27]), o($Vx, [2, 28]), o($Vx, [2, 31]), o($Vx, [2, 32]), o($Vz, $V3, { 7: 97 }), o($Vz, $V3, { 7: 98 }), o($Vz, $V3, { 7: 99 }), o($VA, $V3, { 40: 100, 7: 101 }), o($VB, $V3, { 42: 102, 7: 103 }), o($VB, $V3, { 7: 103, 42: 104 }), o($VC, $V3, { 45: 105, 7: 106 }), o($Vz, $V3, { 7: 107 }), { 5: [1, 109], 51: [1, 108] }, { 5: [1, 111], 51: [1, 110] }, { 5: [1, 112] }, { 22: 115, 68: [1, 113], 69: [1, 114], 70: $Vw }, o($VD, [2, 69]), o($VD, [2, 70]), o($VD, [2, 71]), o($VD, [2, 72]), o($VD, [2, 73]), o($VD, [2, 74]), o($VD, [2, 75]), o($VD, [2, 76]), { 22: 116, 70: $Vw }, { 22: 118, 58: 117, 70: $Vw }, { 70: [2, 63] }, { 70: [2, 64] }, { 56: 119, 79: $VE }, { 56: 121, 79: $VE }, { 56: 122, 79: $VE }, { 56: 123, 79: $VE }, { 4: [1, 126], 5: [1, 128], 11: 125, 12: 127, 16: [1, 124], 50: $Vo, 52: $Vp, 53: $Vq }, { 5: [1, 129] }, o($Vx, [2, 19]), o($Vx, [2, 20]), o($Vx, [2, 22]), o($Vx, [2, 23]), { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [1, 130], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [1, 131], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [1, 132], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 16: [1, 133] }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [2, 46], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 49: [1, 134], 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 16: [1, 135] }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [2, 44], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 48: [1, 136], 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 16: [1, 137] }, { 16: [1, 138] }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [2, 42], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 47: [1, 139], 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [1, 140], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 15: [1, 141] }, o($Vx, [2, 49]), { 15: [1, 142] }, o($Vx, [2, 51]), o($Vx, [2, 52]), { 22: 143, 70: $Vw }, { 22: 144, 70: $Vw }, { 56: 145, 79: $VE }, { 56: 146, 79: $VE }, { 56: 147, 79: $VE }, { 64: [1, 148], 79: [2, 62] }, { 5: [2, 55] }, { 5: [2, 77] }, { 5: [2, 56] }, { 5: [2, 57] }, { 5: [2, 58] }, o($Vx, [2, 16]), o($Vy, [2, 10]), { 12: 149, 50: $Vo, 52: $Vp, 53: $Vq }, o($Vy, [2, 12]), o($Vy, [2, 13]), o($Vx, [2, 18]), o($Vx, [2, 34]), o($Vx, [2, 35]), o($Vx, [2, 36]), o($Vx, [2, 37]), { 15: [1, 150] }, o($Vx, [2, 38]), { 15: [1, 151] }, o($Vx, [2, 39]), o($Vx, [2, 40]), { 15: [1, 152] }, o($Vx, [2, 41]), { 5: [1, 153] }, { 5: [1, 154] }, { 56: 155, 79: $VE }, { 56: 156, 79: $VE }, { 5: [2, 67] }, { 5: [2, 53] }, { 5: [2, 54] }, { 22: 157, 70: $Vw }, o($Vy, [2, 11]), o($VA, $V3, { 7: 101, 40: 158 }), o($VB, $V3, { 7: 103, 42: 159 }), o($VC, $V3, { 7: 106, 45: 160 }), o($Vx, [2, 48]), o($Vx, [2, 50]), { 5: [2, 65] }, { 5: [2, 66] }, { 79: [2, 61] }, { 16: [2, 47] }, { 16: [2, 45] }, { 16: [2, 43] }], + defaultActions: { 5: [2, 1], 6: [2, 2], 85: [2, 63], 86: [2, 64], 119: [2, 55], 120: [2, 77], 121: [2, 56], 122: [2, 57], 123: [2, 58], 145: [2, 67], 146: [2, 53], 147: [2, 54], 155: [2, 65], 156: [2, 66], 157: [2, 61], 158: [2, 47], 159: [2, 45], 160: [2, 43] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state2, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state2 = stack[stack.length - 1]; + if (this.defaultActions[state2]) { + action = this.defaultActions[state2]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state2] && table[state2][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state2]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state2 + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 5; + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + return 19; + case 7: + this.begin("LINE"); + return 14; + case 8: + this.begin("ID"); + return 50; + case 9: + this.begin("ID"); + return 52; + case 10: + return 13; + case 11: + this.begin("ID"); + return 53; + case 12: + yy_.yytext = yy_.yytext.trim(); + this.begin("ALIAS"); + return 70; + case 13: + this.popState(); + this.popState(); + this.begin("LINE"); + return 51; + case 14: + this.popState(); + this.popState(); + return 5; + case 15: + this.begin("LINE"); + return 36; + case 16: + this.begin("LINE"); + return 37; + case 17: + this.begin("LINE"); + return 38; + case 18: + this.begin("LINE"); + return 39; + case 19: + this.begin("LINE"); + return 49; + case 20: + this.begin("LINE"); + return 41; + case 21: + this.begin("LINE"); + return 43; + case 22: + this.begin("LINE"); + return 48; + case 23: + this.begin("LINE"); + return 44; + case 24: + this.begin("LINE"); + return 47; + case 25: + this.begin("LINE"); + return 46; + case 26: + this.popState(); + return 15; + case 27: + return 16; + case 28: + return 65; + case 29: + return 66; + case 30: + return 59; + case 31: + return 60; + case 32: + return 61; + case 33: + return 62; + case 34: + return 57; + case 35: + return 54; + case 36: + this.begin("ID"); + return 21; + case 37: + this.begin("ID"); + return 23; + case 38: + return 29; + case 39: + return 30; + case 40: + this.begin("acc_title"); + return 31; + case 41: + this.popState(); + return "acc_title_value"; + case 42: + this.begin("acc_descr"); + return 33; + case 43: + this.popState(); + return "acc_descr_value"; + case 44: + this.begin("acc_descr_multiline"); + break; + case 45: + this.popState(); + break; + case 46: + return "acc_descr_multiline_value"; + case 47: + return 6; + case 48: + return 18; + case 49: + return 20; + case 50: + return 64; + case 51: + return 5; + case 52: + yy_.yytext = yy_.yytext.trim(); + return 70; + case 53: + return 73; + case 54: + return 74; + case 55: + return 71; + case 56: + return 72; + case 57: + return 75; + case 58: + return 76; + case 59: + return 77; + case 60: + return 78; + case 61: + return 79; + case 62: + return 68; + case 63: + return 69; + case 64: + return 5; + case 65: + return "INVALID"; + } + }, + rules: [/^(?:[\n]+)/i, /^(?:\s+)/i, /^(?:((?!\n)\s)+)/i, /^(?:#[^\n]*)/i, /^(?:%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[0-9]+(?=[ \n]+))/i, /^(?:box\b)/i, /^(?:participant\b)/i, /^(?:actor\b)/i, /^(?:create\b)/i, /^(?:destroy\b)/i, /^(?:[^\->:\n,;]+?([\-]*[^\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i, /^(?:as\b)/i, /^(?:(?:))/i, /^(?:loop\b)/i, /^(?:rect\b)/i, /^(?:opt\b)/i, /^(?:alt\b)/i, /^(?:else\b)/i, /^(?:par\b)/i, /^(?:par_over\b)/i, /^(?:and\b)/i, /^(?:critical\b)/i, /^(?:option\b)/i, /^(?:break\b)/i, /^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i, /^(?:end\b)/i, /^(?:left of\b)/i, /^(?:right of\b)/i, /^(?:links\b)/i, /^(?:link\b)/i, /^(?:properties\b)/i, /^(?:details\b)/i, /^(?:over\b)/i, /^(?:note\b)/i, /^(?:activate\b)/i, /^(?:deactivate\b)/i, /^(?:title\s[^#\n;]+)/i, /^(?:title:\s[^#\n;]+)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:sequenceDiagram\b)/i, /^(?:autonumber\b)/i, /^(?:off\b)/i, /^(?:,)/i, /^(?:;)/i, /^(?:[^\+\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\->:\n,;]+)*)/i, /^(?:->>)/i, /^(?:-->>)/i, /^(?:->)/i, /^(?:-->)/i, /^(?:-[x])/i, /^(?:--[x])/i, /^(?:-[\)])/i, /^(?:--[\)])/i, /^(?::(?:(?:no)?wrap)?[^#\n;]+)/i, /^(?:\+)/i, /^(?:-)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "acc_descr_multiline": { "rules": [45, 46], "inclusive": false }, "acc_descr": { "rules": [43], "inclusive": false }, "acc_title": { "rules": [41], "inclusive": false }, "ID": { "rules": [2, 3, 12], "inclusive": false }, "ALIAS": { "rules": [2, 3, 13, 14], "inclusive": false }, "LINE": { "rules": [2, 3, 26], "inclusive": false }, "INITIAL": { "rules": [0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 42, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +class ImperativeState { + /** + * @param init - Function that creates the default state. + */ + constructor(init) { + this.init = init; + this.records = this.init(); + } + reset() { + this.records = this.init(); + } +} +const state = new ImperativeState(() => ({ + prevActor: void 0, + actors: {}, + createdActors: {}, + destroyedActors: {}, + boxes: [], + messages: [], + notes: [], + sequenceNumbersEnabled: false, + wrapEnabled: void 0, + currentBox: void 0, + lastCreated: void 0, + lastDestroyed: void 0 +})); +const addBox = function(data) { + state.records.boxes.push({ + name: data.text, + wrap: data.wrap === void 0 && autoWrap() || !!data.wrap, + fill: data.color, + actorKeys: [] + }); + state.records.currentBox = state.records.boxes.slice(-1)[0]; +}; +const addActor = function(id, name, description, type) { + let assignedBox = state.records.currentBox; + const old = state.records.actors[id]; + if (old) { + if (state.records.currentBox && old.box && state.records.currentBox !== old.box) { + throw new Error( + "A same participant should only be defined in one Box: " + old.name + " can't be in '" + old.box.name + "' and in '" + state.records.currentBox.name + "' at the same time." + ); + } + assignedBox = old.box ? old.box : state.records.currentBox; + old.box = assignedBox; + if (old && name === old.name && description == null) { + return; + } + } + if (description == null || description.text == null) { + description = { text: name, wrap: null, type }; + } + if (type == null || description.text == null) { + description = { text: name, wrap: null, type }; + } + state.records.actors[id] = { + box: assignedBox, + name, + description: description.text, + wrap: description.wrap === void 0 && autoWrap() || !!description.wrap, + prevActor: state.records.prevActor, + links: {}, + properties: {}, + actorCnt: null, + rectData: null, + type: type || "participant" + }; + if (state.records.prevActor && state.records.actors[state.records.prevActor]) { + state.records.actors[state.records.prevActor].nextActor = id; + } + if (state.records.currentBox) { + state.records.currentBox.actorKeys.push(id); + } + state.records.prevActor = id; +}; +const activationCount = (part) => { + let i; + let count = 0; + for (i = 0; i < state.records.messages.length; i++) { + if (state.records.messages[i].type === LINETYPE.ACTIVE_START && state.records.messages[i].from.actor === part) { + count++; + } + if (state.records.messages[i].type === LINETYPE.ACTIVE_END && state.records.messages[i].from.actor === part) { + count--; + } + } + return count; +}; +const addMessage = function(idFrom, idTo, message, answer) { + state.records.messages.push({ + from: idFrom, + to: idTo, + message: message.text, + wrap: message.wrap === void 0 && autoWrap() || !!message.wrap, + answer + }); +}; +const addSignal = function(idFrom, idTo, message = { text: void 0, wrap: void 0 }, messageType, activate = false) { + if (messageType === LINETYPE.ACTIVE_END) { + const cnt = activationCount(idFrom.actor); + if (cnt < 1) { + let error = new Error("Trying to inactivate an inactive participant (" + idFrom.actor + ")"); + error.hash = { + text: "->>-", + token: "->>-", + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["'ACTIVE_PARTICIPANT'"] + }; + throw error; + } + } + state.records.messages.push({ + from: idFrom, + to: idTo, + message: message.text, + wrap: message.wrap === void 0 && autoWrap() || !!message.wrap, + type: messageType, + activate + }); + return true; +}; +const hasAtLeastOneBox = function() { + return state.records.boxes.length > 0; +}; +const hasAtLeastOneBoxWithTitle = function() { + return state.records.boxes.some((b) => b.name); +}; +const getMessages = function() { + return state.records.messages; +}; +const getBoxes = function() { + return state.records.boxes; +}; +const getActors = function() { + return state.records.actors; +}; +const getCreatedActors = function() { + return state.records.createdActors; +}; +const getDestroyedActors = function() { + return state.records.destroyedActors; +}; +const getActor = function(id) { + return state.records.actors[id]; +}; +const getActorKeys = function() { + return Object.keys(state.records.actors); +}; +const enableSequenceNumbers = function() { + state.records.sequenceNumbersEnabled = true; +}; +const disableSequenceNumbers = function() { + state.records.sequenceNumbersEnabled = false; +}; +const showSequenceNumbers = () => state.records.sequenceNumbersEnabled; +const setWrap = function(wrapSetting) { + state.records.wrapEnabled = wrapSetting; +}; +const autoWrap = () => { + if (state.records.wrapEnabled !== void 0) { + return state.records.wrapEnabled; + } + return (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().sequence.wrap; +}; +const clear = function() { + state.reset(); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.v)(); +}; +const parseMessage = function(str) { + const _str = str.trim(); + const message = { + text: _str.replace(/^:?(?:no)?wrap:/, "").trim(), + wrap: _str.match(/^:?wrap:/) !== null ? true : _str.match(/^:?nowrap:/) !== null ? false : void 0 + }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("parseMessage:", message); + return message; +}; +const parseBoxData = function(str) { + const match = str.match(/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/); + let color = match != null && match[1] ? match[1].trim() : "transparent"; + let title = match != null && match[2] ? match[2].trim() : void 0; + if (window && window.CSS) { + if (!window.CSS.supports("color", color)) { + color = "transparent"; + title = str.trim(); + } + } else { + const style = new Option().style; + style.color = color; + if (style.color !== color) { + color = "transparent"; + title = str.trim(); + } + } + return { + color, + text: title !== void 0 ? (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.d)(title.replace(/^:?(?:no)?wrap:/, ""), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()) : void 0, + wrap: title !== void 0 ? title.match(/^:?wrap:/) !== null ? true : title.match(/^:?nowrap:/) !== null ? false : void 0 : void 0 + }; +}; +const LINETYPE = { + SOLID: 0, + DOTTED: 1, + NOTE: 2, + SOLID_CROSS: 3, + DOTTED_CROSS: 4, + SOLID_OPEN: 5, + DOTTED_OPEN: 6, + LOOP_START: 10, + LOOP_END: 11, + ALT_START: 12, + ALT_ELSE: 13, + ALT_END: 14, + OPT_START: 15, + OPT_END: 16, + ACTIVE_START: 17, + ACTIVE_END: 18, + PAR_START: 19, + PAR_AND: 20, + PAR_END: 21, + RECT_START: 22, + RECT_END: 23, + SOLID_POINT: 24, + DOTTED_POINT: 25, + AUTONUMBER: 26, + CRITICAL_START: 27, + CRITICAL_OPTION: 28, + CRITICAL_END: 29, + BREAK_START: 30, + BREAK_END: 31, + PAR_OVER_START: 32 +}; +const ARROWTYPE = { + FILLED: 0, + OPEN: 1 +}; +const PLACEMENT = { + LEFTOF: 0, + RIGHTOF: 1, + OVER: 2 +}; +const addNote = function(actor, placement, message) { + const note = { + actor, + placement, + message: message.text, + wrap: message.wrap === void 0 && autoWrap() || !!message.wrap + }; + const actors = [].concat(actor, actor); + state.records.notes.push(note); + state.records.messages.push({ + from: actors[0], + to: actors[1], + message: message.text, + wrap: message.wrap === void 0 && autoWrap() || !!message.wrap, + type: LINETYPE.NOTE, + placement + }); +}; +const addLinks = function(actorId, text) { + const actor = getActor(actorId); + try { + let sanitizedText = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.d)(text.text, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + sanitizedText = sanitizedText.replace(/&/g, "&"); + sanitizedText = sanitizedText.replace(/=/g, "="); + const links = JSON.parse(sanitizedText); + insertLinks(actor, links); + } catch (e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error("error while parsing actor link text", e); + } +}; +const addALink = function(actorId, text) { + const actor = getActor(actorId); + try { + const links = {}; + let sanitizedText = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.d)(text.text, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + var sep = sanitizedText.indexOf("@"); + sanitizedText = sanitizedText.replace(/&/g, "&"); + sanitizedText = sanitizedText.replace(/=/g, "="); + var label = sanitizedText.slice(0, sep - 1).trim(); + var link = sanitizedText.slice(sep + 1).trim(); + links[label] = link; + insertLinks(actor, links); + } catch (e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error("error while parsing actor link text", e); + } +}; +function insertLinks(actor, links) { + if (actor.links == null) { + actor.links = links; + } else { + for (let key in links) { + actor.links[key] = links[key]; + } + } +} +const addProperties = function(actorId, text) { + const actor = getActor(actorId); + try { + let sanitizedText = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.d)(text.text, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + const properties = JSON.parse(sanitizedText); + insertProperties(actor, properties); + } catch (e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error("error while parsing actor properties text", e); + } +}; +function insertProperties(actor, properties) { + if (actor.properties == null) { + actor.properties = properties; + } else { + for (let key in properties) { + actor.properties[key] = properties[key]; + } + } +} +function boxEnd() { + state.records.currentBox = void 0; +} +const addDetails = function(actorId, text) { + const actor = getActor(actorId); + const elem = document.getElementById(text.text); + try { + const text2 = elem.innerHTML; + const details = JSON.parse(text2); + if (details["properties"]) { + insertProperties(actor, details["properties"]); + } + if (details["links"]) { + insertLinks(actor, details["links"]); + } + } catch (e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error("error while parsing actor details text", e); + } +}; +const getActorProperty = function(actor, key) { + if (actor !== void 0 && actor.properties !== void 0) { + return actor.properties[key]; + } + return void 0; +}; +const apply = function(param) { + if (Array.isArray(param)) { + param.forEach(function(item) { + apply(item); + }); + } else { + switch (param.type) { + case "sequenceIndex": + state.records.messages.push({ + from: void 0, + to: void 0, + message: { + start: param.sequenceIndex, + step: param.sequenceIndexStep, + visible: param.sequenceVisible + }, + wrap: false, + type: param.signalType + }); + break; + case "addParticipant": + addActor(param.actor, param.actor, param.description, param.draw); + break; + case "createParticipant": + if (state.records.actors[param.actor]) { + throw new Error( + "It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior" + ); + } + state.records.lastCreated = param.actor; + addActor(param.actor, param.actor, param.description, param.draw); + state.records.createdActors[param.actor] = state.records.messages.length; + break; + case "destroyParticipant": + state.records.lastDestroyed = param.actor; + state.records.destroyedActors[param.actor] = state.records.messages.length; + break; + case "activeStart": + addSignal(param.actor, void 0, void 0, param.signalType); + break; + case "activeEnd": + addSignal(param.actor, void 0, void 0, param.signalType); + break; + case "addNote": + addNote(param.actor, param.placement, param.text); + break; + case "addLinks": + addLinks(param.actor, param.text); + break; + case "addALink": + addALink(param.actor, param.text); + break; + case "addProperties": + addProperties(param.actor, param.text); + break; + case "addDetails": + addDetails(param.actor, param.text); + break; + case "addMessage": + if (state.records.lastCreated) { + if (param.to !== state.records.lastCreated) { + throw new Error( + "The created participant " + state.records.lastCreated + " does not have an associated creating message after its declaration. Please check the sequence diagram." + ); + } else { + state.records.lastCreated = void 0; + } + } else if (state.records.lastDestroyed) { + if (param.to !== state.records.lastDestroyed && param.from !== state.records.lastDestroyed) { + throw new Error( + "The destroyed participant " + state.records.lastDestroyed + " does not have an associated destroying message after its declaration. Please check the sequence diagram." + ); + } else { + state.records.lastDestroyed = void 0; + } + } + addSignal(param.from, param.to, param.msg, param.signalType, param.activate); + break; + case "boxStart": + addBox(param.boxData); + break; + case "boxEnd": + boxEnd(); + break; + case "loopStart": + addSignal(void 0, void 0, param.loopText, param.signalType); + break; + case "loopEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + case "rectStart": + addSignal(void 0, void 0, param.color, param.signalType); + break; + case "rectEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + case "optStart": + addSignal(void 0, void 0, param.optText, param.signalType); + break; + case "optEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + case "altStart": + addSignal(void 0, void 0, param.altText, param.signalType); + break; + case "else": + addSignal(void 0, void 0, param.altText, param.signalType); + break; + case "altEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + case "setAccTitle": + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.s)(param.text); + break; + case "parStart": + addSignal(void 0, void 0, param.parText, param.signalType); + break; + case "and": + addSignal(void 0, void 0, param.parText, param.signalType); + break; + case "parEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + case "criticalStart": + addSignal(void 0, void 0, param.criticalText, param.signalType); + break; + case "option": + addSignal(void 0, void 0, param.optionText, param.signalType); + break; + case "criticalEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + case "breakStart": + addSignal(void 0, void 0, param.breakText, param.signalType); + break; + case "breakEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + } + } +}; +const db = { + addActor, + addMessage, + addSignal, + addLinks, + addDetails, + addProperties, + autoWrap, + setWrap, + enableSequenceNumbers, + disableSequenceNumbers, + showSequenceNumbers, + getMessages, + getActors, + getCreatedActors, + getDestroyedActors, + getActor, + getActorKeys, + getActorProperty, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.g, + getBoxes, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.t, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.q, + getConfig: () => (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().sequence, + clear, + parseMessage, + parseBoxData, + LINETYPE, + ARROWTYPE, + PLACEMENT, + addNote, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.s, + apply, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.b, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.a, + hasAtLeastOneBox, + hasAtLeastOneBoxWithTitle +}; +const getStyles = (options) => `.actor { + stroke: ${options.actorBorder}; + fill: ${options.actorBkg}; + } + + text.actor > tspan { + fill: ${options.actorTextColor}; + stroke: none; + } + + .actor-line { + stroke: ${options.actorLineColor}; + } + + .messageLine0 { + stroke-width: 1.5; + stroke-dasharray: none; + stroke: ${options.signalColor}; + } + + .messageLine1 { + stroke-width: 1.5; + stroke-dasharray: 2, 2; + stroke: ${options.signalColor}; + } + + #arrowhead path { + fill: ${options.signalColor}; + stroke: ${options.signalColor}; + } + + .sequenceNumber { + fill: ${options.sequenceNumberColor}; + } + + #sequencenumber { + fill: ${options.signalColor}; + } + + #crosshead path { + fill: ${options.signalColor}; + stroke: ${options.signalColor}; + } + + .messageText { + fill: ${options.signalTextColor}; + stroke: none; + } + + .labelBox { + stroke: ${options.labelBoxBorderColor}; + fill: ${options.labelBoxBkgColor}; + } + + .labelText, .labelText > tspan { + fill: ${options.labelTextColor}; + stroke: none; + } + + .loopText, .loopText > tspan { + fill: ${options.loopTextColor}; + stroke: none; + } + + .loopLine { + stroke-width: 2px; + stroke-dasharray: 2, 2; + stroke: ${options.labelBoxBorderColor}; + fill: ${options.labelBoxBorderColor}; + } + + .note { + //stroke: #decc93; + stroke: ${options.noteBorderColor}; + fill: ${options.noteBkgColor}; + } + + .noteText, .noteText > tspan { + fill: ${options.noteTextColor}; + stroke: none; + } + + .activation0 { + fill: ${options.activationBkgColor}; + stroke: ${options.activationBorderColor}; + } + + .activation1 { + fill: ${options.activationBkgColor}; + stroke: ${options.activationBorderColor}; + } + + .activation2 { + fill: ${options.activationBkgColor}; + stroke: ${options.activationBorderColor}; + } + + .actorPopupMenu { + position: absolute; + } + + .actorPopupMenuPanel { + position: absolute; + fill: ${options.actorBkg}; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4)); +} + .actor-man line { + stroke: ${options.actorBorder}; + fill: ${options.actorBkg}; + } + .actor-man circle, line { + stroke: ${options.actorBorder}; + fill: ${options.actorBkg}; + stroke-width: 2px; + } +`; +const styles = getStyles; +const ACTOR_TYPE_WIDTH = 18 * 2; +const TOP_ACTOR_CLASS = "actor-top"; +const BOTTOM_ACTOR_CLASS = "actor-bottom"; +const drawRect = function(elem, rectData) { + return (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.d)(elem, rectData); +}; +const drawPopup = function(elem, actor, minMenuWidth, textAttrs, forceMenus) { + if (actor.links === void 0 || actor.links === null || Object.keys(actor.links).length === 0) { + return { height: 0, width: 0 }; + } + const links = actor.links; + const actorCnt2 = actor.actorCnt; + const rectData = actor.rectData; + var displayValue = "none"; + if (forceMenus) { + displayValue = "block !important"; + } + const g = elem.append("g"); + g.attr("id", "actor" + actorCnt2 + "_popup"); + g.attr("class", "actorPopupMenu"); + g.attr("display", displayValue); + var actorClass = ""; + if (rectData.class !== void 0) { + actorClass = " " + rectData.class; + } + let menuWidth = rectData.width > minMenuWidth ? rectData.width : minMenuWidth; + const rectElem = g.append("rect"); + rectElem.attr("class", "actorPopupMenuPanel" + actorClass); + rectElem.attr("x", rectData.x); + rectElem.attr("y", rectData.height); + rectElem.attr("fill", rectData.fill); + rectElem.attr("stroke", rectData.stroke); + rectElem.attr("width", menuWidth); + rectElem.attr("height", rectData.height); + rectElem.attr("rx", rectData.rx); + rectElem.attr("ry", rectData.ry); + if (links != null) { + var linkY = 20; + for (let key in links) { + var linkElem = g.append("a"); + var sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_1__/* .sanitizeUrl */ .Jf)(links[key]); + linkElem.attr("xlink:href", sanitizedLink); + linkElem.attr("target", "_blank"); + _drawMenuItemTextCandidateFunc(textAttrs)( + key, + linkElem, + rectData.x + 10, + rectData.height + linkY, + menuWidth, + 20, + { class: "actor" }, + textAttrs + ); + linkY += 30; + } + } + rectElem.attr("height", linkY); + return { height: rectData.height + linkY, width: menuWidth }; +}; +const popupMenuToggle = function(popId) { + return "var pu = document.getElementById('" + popId + "'); if (pu != null) { pu.style.display = pu.style.display == 'block' ? 'none' : 'block'; }"; +}; +const drawKatex = async function(elem, textData, msgModel = null) { + let textElem = elem.append("foreignObject"); + const lines = await (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.r)(textData.text, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.F)()); + const divElem = textElem.append("xhtml:div").attr("style", "width: fit-content;").attr("xmlns", "http://www.w3.org/1999/xhtml").html(lines); + const dim = divElem.node().getBoundingClientRect(); + textElem.attr("height", Math.round(dim.height)).attr("width", Math.round(dim.width)); + if (textData.class === "noteText") { + const rectElem = elem.node().firstChild; + rectElem.setAttribute("height", dim.height + 2 * textData.textMargin); + const rectDim = rectElem.getBBox(); + textElem.attr("x", Math.round(rectDim.x + rectDim.width / 2 - dim.width / 2)).attr("y", Math.round(rectDim.y + rectDim.height / 2 - dim.height / 2)); + } else if (msgModel) { + let { startx, stopx, starty } = msgModel; + if (startx > stopx) { + const temp = startx; + startx = stopx; + stopx = temp; + } + textElem.attr("x", Math.round(startx + Math.abs(startx - stopx) / 2 - dim.width / 2)); + if (textData.class === "loopText") { + textElem.attr("y", Math.round(starty)); + } else { + textElem.attr("y", Math.round(starty - dim.height)); + } + } + return [textElem]; +}; +const drawText = function(elem, textData) { + let prevTextHeight = 0; + let textHeight = 0; + const lines = textData.text.split(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.lineBreakRegex); + const [_textFontSize, _textFontSizePx] = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.D)(textData.fontSize); + let textElems = []; + let dy = 0; + let yfunc = () => textData.y; + if (textData.valign !== void 0 && textData.textMargin !== void 0 && textData.textMargin > 0) { + switch (textData.valign) { + case "top": + case "start": + yfunc = () => Math.round(textData.y + textData.textMargin); + break; + case "middle": + case "center": + yfunc = () => Math.round(textData.y + (prevTextHeight + textHeight + textData.textMargin) / 2); + break; + case "bottom": + case "end": + yfunc = () => Math.round( + textData.y + (prevTextHeight + textHeight + 2 * textData.textMargin) - textData.textMargin + ); + break; + } + } + if (textData.anchor !== void 0 && textData.textMargin !== void 0 && textData.width !== void 0) { + switch (textData.anchor) { + case "left": + case "start": + textData.x = Math.round(textData.x + textData.textMargin); + textData.anchor = "start"; + textData.dominantBaseline = "middle"; + textData.alignmentBaseline = "middle"; + break; + case "middle": + case "center": + textData.x = Math.round(textData.x + textData.width / 2); + textData.anchor = "middle"; + textData.dominantBaseline = "middle"; + textData.alignmentBaseline = "middle"; + break; + case "right": + case "end": + textData.x = Math.round(textData.x + textData.width - textData.textMargin); + textData.anchor = "end"; + textData.dominantBaseline = "middle"; + textData.alignmentBaseline = "middle"; + break; + } + } + for (let [i, line] of lines.entries()) { + if (textData.textMargin !== void 0 && textData.textMargin === 0 && _textFontSize !== void 0) { + dy = i * _textFontSize; + } + const textElem = elem.append("text"); + textElem.attr("x", textData.x); + textElem.attr("y", yfunc()); + if (textData.anchor !== void 0) { + textElem.attr("text-anchor", textData.anchor).attr("dominant-baseline", textData.dominantBaseline).attr("alignment-baseline", textData.alignmentBaseline); + } + if (textData.fontFamily !== void 0) { + textElem.style("font-family", textData.fontFamily); + } + if (_textFontSizePx !== void 0) { + textElem.style("font-size", _textFontSizePx); + } + if (textData.fontWeight !== void 0) { + textElem.style("font-weight", textData.fontWeight); + } + if (textData.fill !== void 0) { + textElem.attr("fill", textData.fill); + } + if (textData.class !== void 0) { + textElem.attr("class", textData.class); + } + if (textData.dy !== void 0) { + textElem.attr("dy", textData.dy); + } else if (dy !== 0) { + textElem.attr("dy", dy); + } + const text = line || _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.Z; + if (textData.tspan) { + const span = textElem.append("tspan"); + span.attr("x", textData.x); + if (textData.fill !== void 0) { + span.attr("fill", textData.fill); + } + span.text(text); + } else { + textElem.text(text); + } + if (textData.valign !== void 0 && textData.textMargin !== void 0 && textData.textMargin > 0) { + textHeight += (textElem._groups || textElem)[0][0].getBBox().height; + prevTextHeight = textHeight; + } + textElems.push(textElem); + } + return textElems; +}; +const drawLabel = function(elem, txtObject) { + function genPoints(x, y, width, height, cut) { + return x + "," + y + " " + (x + width) + "," + y + " " + (x + width) + "," + (y + height - cut) + " " + (x + width - cut * 1.2) + "," + (y + height) + " " + x + "," + (y + height); + } + const polygon = elem.append("polygon"); + polygon.attr("points", genPoints(txtObject.x, txtObject.y, txtObject.width, txtObject.height, 7)); + polygon.attr("class", "labelBox"); + txtObject.y = txtObject.y + txtObject.height / 2; + drawText(elem, txtObject); + return polygon; +}; +let actorCnt = -1; +const fixLifeLineHeights = (diagram2, actors, actorKeys, conf2) => { + if (!diagram2.select) { + return; + } + actorKeys.forEach((actorKey) => { + const actor = actors[actorKey]; + const actorDOM = diagram2.select("#actor" + actor.actorCnt); + if (!conf2.mirrorActors && actor.stopy) { + actorDOM.attr("y2", actor.stopy + actor.height / 2); + } else if (conf2.mirrorActors) { + actorDOM.attr("y2", actor.stopy); + } + }); +}; +const drawActorTypeParticipant = async function(elem, actor, conf2, isFooter) { + const actorY = isFooter ? actor.stopy : actor.starty; + const center = actor.x + actor.width / 2; + const centerY = actorY + 5; + const boxplusLineGroup = elem.append("g").lower(); + var g = boxplusLineGroup; + if (!isFooter) { + actorCnt++; + if (Object.keys(actor.links || {}).length && !conf2.forceMenus) { + g.attr("onclick", popupMenuToggle(`actor${actorCnt}_popup`)).attr("cursor", "pointer"); + } + g.append("line").attr("id", "actor" + actorCnt).attr("x1", center).attr("y1", centerY).attr("x2", center).attr("y2", 2e3).attr("class", "actor-line").attr("class", "200").attr("stroke-width", "0.5px").attr("stroke", "#999"); + g = boxplusLineGroup.append("g"); + actor.actorCnt = actorCnt; + if (actor.links != null) { + g.attr("id", "root-" + actorCnt); + } + } + const rect = (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + var cssclass = "actor"; + if (actor.properties != null && actor.properties["class"]) { + cssclass = actor.properties["class"]; + } else { + rect.fill = "#eaeaea"; + } + if (isFooter) { + cssclass += ` ${BOTTOM_ACTOR_CLASS}`; + } else { + cssclass += ` ${TOP_ACTOR_CLASS}`; + } + rect.x = actor.x; + rect.y = actorY; + rect.width = actor.width; + rect.height = actor.height; + rect.class = cssclass; + rect.rx = 3; + rect.ry = 3; + rect.name = actor.name; + const rectElem = drawRect(g, rect); + actor.rectData = rect; + if (actor.properties != null && actor.properties["icon"]) { + const iconSrc = actor.properties["icon"].trim(); + if (iconSrc.charAt(0) === "@") { + (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.b)(g, rect.x + rect.width - 20, rect.y + 10, iconSrc.substr(1)); + } else { + (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.c)(g, rect.x + rect.width - 20, rect.y + 10, iconSrc); + } + } + await _drawTextCandidateFunc(conf2, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.G)(actor.description))( + actor.description, + g, + rect.x, + rect.y, + rect.width, + rect.height, + { class: "actor" }, + conf2 + ); + let height = actor.height; + if (rectElem.node) { + const bounds2 = rectElem.node().getBBox(); + actor.height = bounds2.height; + height = bounds2.height; + } + return height; +}; +const drawActorTypeActor = async function(elem, actor, conf2, isFooter) { + const actorY = isFooter ? actor.stopy : actor.starty; + const center = actor.x + actor.width / 2; + const centerY = actorY + 80; + elem.lower(); + if (!isFooter) { + actorCnt++; + elem.append("line").attr("id", "actor" + actorCnt).attr("x1", center).attr("y1", centerY).attr("x2", center).attr("y2", 2e3).attr("class", "actor-line").attr("class", "200").attr("stroke-width", "0.5px").attr("stroke", "#999"); + actor.actorCnt = actorCnt; + } + const actElem = elem.append("g"); + let cssClass = "actor-man"; + if (isFooter) { + cssClass += ` ${BOTTOM_ACTOR_CLASS}`; + } else { + cssClass += ` ${TOP_ACTOR_CLASS}`; + } + actElem.attr("class", cssClass); + actElem.attr("name", actor.name); + const rect = (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + rect.x = actor.x; + rect.y = actorY; + rect.fill = "#eaeaea"; + rect.width = actor.width; + rect.height = actor.height; + rect.class = "actor"; + rect.rx = 3; + rect.ry = 3; + actElem.append("line").attr("id", "actor-man-torso" + actorCnt).attr("x1", center).attr("y1", actorY + 25).attr("x2", center).attr("y2", actorY + 45); + actElem.append("line").attr("id", "actor-man-arms" + actorCnt).attr("x1", center - ACTOR_TYPE_WIDTH / 2).attr("y1", actorY + 33).attr("x2", center + ACTOR_TYPE_WIDTH / 2).attr("y2", actorY + 33); + actElem.append("line").attr("x1", center - ACTOR_TYPE_WIDTH / 2).attr("y1", actorY + 60).attr("x2", center).attr("y2", actorY + 45); + actElem.append("line").attr("x1", center).attr("y1", actorY + 45).attr("x2", center + ACTOR_TYPE_WIDTH / 2 - 2).attr("y2", actorY + 60); + const circle = actElem.append("circle"); + circle.attr("cx", actor.x + actor.width / 2); + circle.attr("cy", actorY + 10); + circle.attr("r", 15); + circle.attr("width", actor.width); + circle.attr("height", actor.height); + const bounds2 = actElem.node().getBBox(); + actor.height = bounds2.height; + await _drawTextCandidateFunc(conf2, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.G)(actor.description))( + actor.description, + actElem, + rect.x, + rect.y + 35, + rect.width, + rect.height, + { class: "actor" }, + conf2 + ); + return actor.height; +}; +const drawActor = async function(elem, actor, conf2, isFooter) { + switch (actor.type) { + case "actor": + return await drawActorTypeActor(elem, actor, conf2, isFooter); + case "participant": + return await drawActorTypeParticipant(elem, actor, conf2, isFooter); + } +}; +const drawBox = async function(elem, box, conf2) { + const boxplusTextGroup = elem.append("g"); + const g = boxplusTextGroup; + drawBackgroundRect(g, box); + if (box.name) { + await _drawTextCandidateFunc(conf2)( + box.name, + g, + box.x, + box.y + (box.textMaxHeight || 0) / 2, + box.width, + 0, + { class: "text" }, + conf2 + ); + } + g.lower(); +}; +const anchorElement = function(elem) { + return elem.append("g"); +}; +const drawActivation = function(elem, bounds2, verticalPos, conf2, actorActivations2) { + const rect = (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + const g = bounds2.anchored; + rect.x = bounds2.startx; + rect.y = bounds2.starty; + rect.class = "activation" + actorActivations2 % 3; + rect.width = bounds2.stopx - bounds2.startx; + rect.height = verticalPos - bounds2.starty; + drawRect(g, rect); +}; +const drawLoop = async function(elem, loopModel, labelText, conf2) { + const { + boxMargin, + boxTextMargin, + labelBoxHeight, + labelBoxWidth, + messageFontFamily: fontFamily, + messageFontSize: fontSize, + messageFontWeight: fontWeight + } = conf2; + const g = elem.append("g"); + const drawLoopLine = function(startx, starty, stopx, stopy) { + return g.append("line").attr("x1", startx).attr("y1", starty).attr("x2", stopx).attr("y2", stopy).attr("class", "loopLine"); + }; + drawLoopLine(loopModel.startx, loopModel.starty, loopModel.stopx, loopModel.starty); + drawLoopLine(loopModel.stopx, loopModel.starty, loopModel.stopx, loopModel.stopy); + drawLoopLine(loopModel.startx, loopModel.stopy, loopModel.stopx, loopModel.stopy); + drawLoopLine(loopModel.startx, loopModel.starty, loopModel.startx, loopModel.stopy); + if (loopModel.sections !== void 0) { + loopModel.sections.forEach(function(item) { + drawLoopLine(loopModel.startx, item.y, loopModel.stopx, item.y).style( + "stroke-dasharray", + "3, 3" + ); + }); + } + let txt = (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.e)(); + txt.text = labelText; + txt.x = loopModel.startx; + txt.y = loopModel.starty; + txt.fontFamily = fontFamily; + txt.fontSize = fontSize; + txt.fontWeight = fontWeight; + txt.anchor = "middle"; + txt.valign = "middle"; + txt.tspan = false; + txt.width = labelBoxWidth || 50; + txt.height = labelBoxHeight || 20; + txt.textMargin = boxTextMargin; + txt.class = "labelText"; + drawLabel(g, txt); + txt = getTextObj(); + txt.text = loopModel.title; + txt.x = loopModel.startx + labelBoxWidth / 2 + (loopModel.stopx - loopModel.startx) / 2; + txt.y = loopModel.starty + boxMargin + boxTextMargin; + txt.anchor = "middle"; + txt.valign = "middle"; + txt.textMargin = boxTextMargin; + txt.class = "loopText"; + txt.fontFamily = fontFamily; + txt.fontSize = fontSize; + txt.fontWeight = fontWeight; + txt.wrap = true; + let textElem = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.G)(txt.text) ? await drawKatex(g, txt, loopModel) : drawText(g, txt); + if (loopModel.sectionTitles !== void 0) { + for (const [idx, item] of Object.entries(loopModel.sectionTitles)) { + if (item.message) { + txt.text = item.message; + txt.x = loopModel.startx + (loopModel.stopx - loopModel.startx) / 2; + txt.y = loopModel.sections[idx].y + boxMargin + boxTextMargin; + txt.class = "loopText"; + txt.anchor = "middle"; + txt.valign = "middle"; + txt.tspan = false; + txt.fontFamily = fontFamily; + txt.fontSize = fontSize; + txt.fontWeight = fontWeight; + txt.wrap = loopModel.wrap; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.G)(txt.text)) { + loopModel.starty = loopModel.sections[idx].y; + await drawKatex(g, txt, loopModel); + } else { + drawText(g, txt); + } + let sectionHeight = Math.round( + textElem.map((te) => (te._groups || te)[0][0].getBBox().height).reduce((acc, curr) => acc + curr) + ); + loopModel.sections[idx].height += sectionHeight - (boxMargin + boxTextMargin); + } + } + } + loopModel.height = Math.round(loopModel.stopy - loopModel.starty); + return g; +}; +const drawBackgroundRect = function(elem, bounds2) { + (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.a)(elem, bounds2); +}; +const insertDatabaseIcon = function(elem) { + elem.append("defs").append("symbol").attr("id", "database").attr("fill-rule", "evenodd").attr("clip-rule", "evenodd").append("path").attr("transform", "scale(.5)").attr( + "d", + "M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z" + ); +}; +const insertComputerIcon = function(elem) { + elem.append("defs").append("symbol").attr("id", "computer").attr("width", "24").attr("height", "24").append("path").attr("transform", "scale(.5)").attr( + "d", + "M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z" + ); +}; +const insertClockIcon = function(elem) { + elem.append("defs").append("symbol").attr("id", "clock").attr("width", "24").attr("height", "24").append("path").attr("transform", "scale(.5)").attr( + "d", + "M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z" + ); +}; +const insertArrowHead = function(elem) { + elem.append("defs").append("marker").attr("id", "arrowhead").attr("refX", 7.9).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z"); +}; +const insertArrowFilledHead = function(elem) { + elem.append("defs").append("marker").attr("id", "filled-head").attr("refX", 15.5).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const insertSequenceNumber = function(elem) { + elem.append("defs").append("marker").attr("id", "sequencenumber").attr("refX", 15).attr("refY", 15).attr("markerWidth", 60).attr("markerHeight", 40).attr("orient", "auto").append("circle").attr("cx", 15).attr("cy", 15).attr("r", 6); +}; +const insertArrowCrossHead = function(elem) { + const defs = elem.append("defs"); + const marker = defs.append("marker").attr("id", "crosshead").attr("markerWidth", 15).attr("markerHeight", 8).attr("orient", "auto").attr("refX", 4).attr("refY", 4.5); + marker.append("path").attr("fill", "none").attr("stroke", "#000000").style("stroke-dasharray", "0, 0").attr("stroke-width", "1pt").attr("d", "M 1,2 L 6,7 M 6,2 L 1,7"); +}; +const getTextObj = function() { + return { + x: 0, + y: 0, + fill: void 0, + anchor: void 0, + style: "#666", + width: void 0, + height: void 0, + textMargin: 0, + rx: 0, + ry: 0, + tspan: true, + valign: void 0 + }; +}; +const getNoteRect = function() { + return { + x: 0, + y: 0, + fill: "#EDF2AE", + stroke: "#666", + width: 100, + anchor: "start", + height: 100, + rx: 0, + ry: 0 + }; +}; +const _drawTextCandidateFunc = function() { + function byText(content, g, x, y, width, height, textAttrs) { + const text = g.append("text").attr("x", x + width / 2).attr("y", y + height / 2 + 5).style("text-anchor", "middle").text(content); + _setTextAttrs(text, textAttrs); + } + function byTspan(content, g, x, y, width, height, textAttrs, conf2) { + const { actorFontSize, actorFontFamily, actorFontWeight } = conf2; + const [_actorFontSize, _actorFontSizePx] = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.D)(actorFontSize); + const lines = content.split(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.lineBreakRegex); + for (let i = 0; i < lines.length; i++) { + const dy = i * _actorFontSize - _actorFontSize * (lines.length - 1) / 2; + const text = g.append("text").attr("x", x + width / 2).attr("y", y).style("text-anchor", "middle").style("font-size", _actorFontSizePx).style("font-weight", actorFontWeight).style("font-family", actorFontFamily); + text.append("tspan").attr("x", x + width / 2).attr("dy", dy).text(lines[i]); + text.attr("y", y + height / 2).attr("dominant-baseline", "central").attr("alignment-baseline", "central"); + _setTextAttrs(text, textAttrs); + } + } + function byFo(content, g, x, y, width, height, textAttrs, conf2) { + const s = g.append("switch"); + const f = s.append("foreignObject").attr("x", x).attr("y", y).attr("width", width).attr("height", height); + const text = f.append("xhtml:div").style("display", "table").style("height", "100%").style("width", "100%"); + text.append("div").style("display", "table-cell").style("text-align", "center").style("vertical-align", "middle").text(content); + byTspan(content, s, x, y, width, height, textAttrs, conf2); + _setTextAttrs(text, textAttrs); + } + async function byKatex(content, g, x, y, width, height, textAttrs, conf2) { + const dim = await (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.H)(content, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.F)()); + const s = g.append("switch"); + const f = s.append("foreignObject").attr("x", x + width / 2 - dim.width / 2).attr("y", y + height / 2 - dim.height / 2).attr("width", dim.width).attr("height", dim.height); + const text = f.append("xhtml:div").style("height", "100%").style("width", "100%"); + text.append("div").style("text-align", "center").style("vertical-align", "middle").html(await (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.r)(content, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.F)())); + byTspan(content, s, x, y, width, height, textAttrs, conf2); + _setTextAttrs(text, textAttrs); + } + function _setTextAttrs(toText, fromTextAttrsDict) { + for (const key in fromTextAttrsDict) { + if (fromTextAttrsDict.hasOwnProperty(key)) { + toText.attr(key, fromTextAttrsDict[key]); + } + } + } + return function(conf2, hasKatex2 = false) { + if (hasKatex2) { + return byKatex; + } + return conf2.textPlacement === "fo" ? byFo : conf2.textPlacement === "old" ? byText : byTspan; + }; +}(); +const _drawMenuItemTextCandidateFunc = function() { + function byText(content, g, x, y, width, height, textAttrs) { + const text = g.append("text").attr("x", x).attr("y", y).style("text-anchor", "start").text(content); + _setTextAttrs(text, textAttrs); + } + function byTspan(content, g, x, y, width, height, textAttrs, conf2) { + const { actorFontSize, actorFontFamily, actorFontWeight } = conf2; + const lines = content.split(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.lineBreakRegex); + for (let i = 0; i < lines.length; i++) { + const dy = i * actorFontSize - actorFontSize * (lines.length - 1) / 2; + const text = g.append("text").attr("x", x).attr("y", y).style("text-anchor", "start").style("font-size", actorFontSize).style("font-weight", actorFontWeight).style("font-family", actorFontFamily); + text.append("tspan").attr("x", x).attr("dy", dy).text(lines[i]); + text.attr("y", y + height / 2).attr("dominant-baseline", "central").attr("alignment-baseline", "central"); + _setTextAttrs(text, textAttrs); + } + } + function byFo(content, g, x, y, width, height, textAttrs, conf2) { + const s = g.append("switch"); + const f = s.append("foreignObject").attr("x", x).attr("y", y).attr("width", width).attr("height", height); + const text = f.append("xhtml:div").style("display", "table").style("height", "100%").style("width", "100%"); + text.append("div").style("display", "table-cell").style("text-align", "center").style("vertical-align", "middle").text(content); + byTspan(content, s, x, y, width, height, textAttrs, conf2); + _setTextAttrs(text, textAttrs); + } + function _setTextAttrs(toText, fromTextAttrsDict) { + for (const key in fromTextAttrsDict) { + if (fromTextAttrsDict.hasOwnProperty(key)) { + toText.attr(key, fromTextAttrsDict[key]); + } + } + } + return function(conf2) { + return conf2.textPlacement === "fo" ? byFo : conf2.textPlacement === "old" ? byText : byTspan; + }; +}(); +const svgDraw = { + drawRect, + drawText, + drawLabel, + drawActor, + drawBox, + drawPopup, + anchorElement, + drawActivation, + drawLoop, + drawBackgroundRect, + insertArrowHead, + insertArrowFilledHead, + insertSequenceNumber, + insertArrowCrossHead, + insertDatabaseIcon, + insertComputerIcon, + insertClockIcon, + getTextObj, + getNoteRect, + fixLifeLineHeights, + sanitizeUrl: _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_1__/* .sanitizeUrl */ .Jf +}; +let conf = {}; +const bounds = { + data: { + startx: void 0, + stopx: void 0, + starty: void 0, + stopy: void 0 + }, + verticalPos: 0, + sequenceItems: [], + activations: [], + models: { + getHeight: function() { + return Math.max.apply( + null, + this.actors.length === 0 ? [0] : this.actors.map((actor) => actor.height || 0) + ) + (this.loops.length === 0 ? 0 : this.loops.map((it) => it.height || 0).reduce((acc, h) => acc + h)) + (this.messages.length === 0 ? 0 : this.messages.map((it) => it.height || 0).reduce((acc, h) => acc + h)) + (this.notes.length === 0 ? 0 : this.notes.map((it) => it.height || 0).reduce((acc, h) => acc + h)); + }, + clear: function() { + this.actors = []; + this.boxes = []; + this.loops = []; + this.messages = []; + this.notes = []; + }, + addBox: function(boxModel) { + this.boxes.push(boxModel); + }, + addActor: function(actorModel) { + this.actors.push(actorModel); + }, + addLoop: function(loopModel) { + this.loops.push(loopModel); + }, + addMessage: function(msgModel) { + this.messages.push(msgModel); + }, + addNote: function(noteModel) { + this.notes.push(noteModel); + }, + lastActor: function() { + return this.actors[this.actors.length - 1]; + }, + lastLoop: function() { + return this.loops[this.loops.length - 1]; + }, + lastMessage: function() { + return this.messages[this.messages.length - 1]; + }, + lastNote: function() { + return this.notes[this.notes.length - 1]; + }, + actors: [], + boxes: [], + loops: [], + messages: [], + notes: [] + }, + init: function() { + this.sequenceItems = []; + this.activations = []; + this.models.clear(); + this.data = { + startx: void 0, + stopx: void 0, + starty: void 0, + stopy: void 0 + }; + this.verticalPos = 0; + setConf((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + }, + updateVal: function(obj, key, val, fun) { + if (obj[key] === void 0) { + obj[key] = val; + } else { + obj[key] = fun(val, obj[key]); + } + }, + updateBounds: function(startx, starty, stopx, stopy) { + const _self = this; + let cnt = 0; + function updateFn(type) { + return function updateItemBounds(item) { + cnt++; + const n = _self.sequenceItems.length - cnt + 1; + _self.updateVal(item, "starty", starty - n * conf.boxMargin, Math.min); + _self.updateVal(item, "stopy", stopy + n * conf.boxMargin, Math.max); + _self.updateVal(bounds.data, "startx", startx - n * conf.boxMargin, Math.min); + _self.updateVal(bounds.data, "stopx", stopx + n * conf.boxMargin, Math.max); + if (!(type === "activation")) { + _self.updateVal(item, "startx", startx - n * conf.boxMargin, Math.min); + _self.updateVal(item, "stopx", stopx + n * conf.boxMargin, Math.max); + _self.updateVal(bounds.data, "starty", starty - n * conf.boxMargin, Math.min); + _self.updateVal(bounds.data, "stopy", stopy + n * conf.boxMargin, Math.max); + } + }; + } + this.sequenceItems.forEach(updateFn()); + this.activations.forEach(updateFn("activation")); + }, + insert: function(startx, starty, stopx, stopy) { + const _startx = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMin(startx, stopx); + const _stopx = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(startx, stopx); + const _starty = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMin(starty, stopy); + const _stopy = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(starty, stopy); + this.updateVal(bounds.data, "startx", _startx, Math.min); + this.updateVal(bounds.data, "starty", _starty, Math.min); + this.updateVal(bounds.data, "stopx", _stopx, Math.max); + this.updateVal(bounds.data, "stopy", _stopy, Math.max); + this.updateBounds(_startx, _starty, _stopx, _stopy); + }, + newActivation: function(message, diagram2, actors) { + const actorRect = actors[message.from.actor]; + const stackedSize = actorActivations(message.from.actor).length || 0; + const x = actorRect.x + actorRect.width / 2 + (stackedSize - 1) * conf.activationWidth / 2; + this.activations.push({ + startx: x, + starty: this.verticalPos + 2, + stopx: x + conf.activationWidth, + stopy: void 0, + actor: message.from.actor, + anchored: svgDraw.anchorElement(diagram2) + }); + }, + endActivation: function(message) { + const lastActorActivationIdx = this.activations.map(function(activation) { + return activation.actor; + }).lastIndexOf(message.from.actor); + return this.activations.splice(lastActorActivationIdx, 1)[0]; + }, + createLoop: function(title = { message: void 0, wrap: false, width: void 0 }, fill) { + return { + startx: void 0, + starty: this.verticalPos, + stopx: void 0, + stopy: void 0, + title: title.message, + wrap: title.wrap, + width: title.width, + height: 0, + fill + }; + }, + newLoop: function(title = { message: void 0, wrap: false, width: void 0 }, fill) { + this.sequenceItems.push(this.createLoop(title, fill)); + }, + endLoop: function() { + return this.sequenceItems.pop(); + }, + isLoopOverlap: function() { + return this.sequenceItems.length ? this.sequenceItems[this.sequenceItems.length - 1].overlap : false; + }, + addSectionToLoop: function(message) { + const loop = this.sequenceItems.pop(); + loop.sections = loop.sections || []; + loop.sectionTitles = loop.sectionTitles || []; + loop.sections.push({ y: bounds.getVerticalPos(), height: 0 }); + loop.sectionTitles.push(message); + this.sequenceItems.push(loop); + }, + saveVerticalPos: function() { + if (this.isLoopOverlap()) { + this.savedVerticalPos = this.verticalPos; + } + }, + resetVerticalPos: function() { + if (this.isLoopOverlap()) { + this.verticalPos = this.savedVerticalPos; + } + }, + bumpVerticalPos: function(bump) { + this.verticalPos = this.verticalPos + bump; + this.data.stopy = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(this.data.stopy, this.verticalPos); + }, + getVerticalPos: function() { + return this.verticalPos; + }, + getBounds: function() { + return { bounds: this.data, models: this.models }; + } +}; +const drawNote = async function(elem, noteModel) { + bounds.bumpVerticalPos(conf.boxMargin); + noteModel.height = conf.boxMargin; + noteModel.starty = bounds.getVerticalPos(); + const rect = (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + rect.x = noteModel.startx; + rect.y = noteModel.starty; + rect.width = noteModel.width || conf.width; + rect.class = "note"; + const g = elem.append("g"); + const rectElem = svgDraw.drawRect(g, rect); + const textObj = (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.e)(); + textObj.x = noteModel.startx; + textObj.y = noteModel.starty; + textObj.width = rect.width; + textObj.dy = "1em"; + textObj.text = noteModel.message; + textObj.class = "noteText"; + textObj.fontFamily = conf.noteFontFamily; + textObj.fontSize = conf.noteFontSize; + textObj.fontWeight = conf.noteFontWeight; + textObj.anchor = conf.noteAlign; + textObj.textMargin = conf.noteMargin; + textObj.valign = "center"; + const textElem = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.G)(textObj.text) ? await drawKatex(g, textObj) : drawText(g, textObj); + const textHeight = Math.round( + textElem.map((te) => (te._groups || te)[0][0].getBBox().height).reduce((acc, curr) => acc + curr) + ); + rectElem.attr("height", textHeight + 2 * conf.noteMargin); + noteModel.height += textHeight + 2 * conf.noteMargin; + bounds.bumpVerticalPos(textHeight + 2 * conf.noteMargin); + noteModel.stopy = noteModel.starty + textHeight + 2 * conf.noteMargin; + noteModel.stopx = noteModel.startx + rect.width; + bounds.insert(noteModel.startx, noteModel.starty, noteModel.stopx, noteModel.stopy); + bounds.models.addNote(noteModel); +}; +const messageFont = (cnf) => { + return { + fontFamily: cnf.messageFontFamily, + fontSize: cnf.messageFontSize, + fontWeight: cnf.messageFontWeight + }; +}; +const noteFont = (cnf) => { + return { + fontFamily: cnf.noteFontFamily, + fontSize: cnf.noteFontSize, + fontWeight: cnf.noteFontWeight + }; +}; +const actorFont = (cnf) => { + return { + fontFamily: cnf.actorFontFamily, + fontSize: cnf.actorFontSize, + fontWeight: cnf.actorFontWeight + }; +}; +async function boundMessage(_diagram, msgModel) { + bounds.bumpVerticalPos(10); + const { startx, stopx, message } = msgModel; + const lines = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.splitBreaks(message).length; + const isKatexMsg = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.G)(message); + const textDims = isKatexMsg ? await (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.H)(message, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()) : _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(message, messageFont(conf)); + if (!isKatexMsg) { + const lineHeight = textDims.height / lines; + msgModel.height += lineHeight; + bounds.bumpVerticalPos(lineHeight); + } + let lineStartY; + let totalOffset = textDims.height - 10; + const textWidth = textDims.width; + if (startx === stopx) { + lineStartY = bounds.getVerticalPos() + totalOffset; + if (!conf.rightAngles) { + totalOffset += conf.boxMargin; + lineStartY = bounds.getVerticalPos() + totalOffset; + } + totalOffset += 30; + const dx = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(textWidth / 2, conf.width / 2); + bounds.insert( + startx - dx, + bounds.getVerticalPos() - 10 + totalOffset, + stopx + dx, + bounds.getVerticalPos() + 30 + totalOffset + ); + } else { + totalOffset += conf.boxMargin; + lineStartY = bounds.getVerticalPos() + totalOffset; + bounds.insert(startx, lineStartY - 10, stopx, lineStartY); + } + bounds.bumpVerticalPos(totalOffset); + msgModel.height += totalOffset; + msgModel.stopy = msgModel.starty + msgModel.height; + bounds.insert(msgModel.fromBounds, msgModel.starty, msgModel.toBounds, msgModel.stopy); + return lineStartY; +} +const drawMessage = async function(diagram2, msgModel, lineStartY, diagObj) { + const { startx, stopx, starty, message, type, sequenceIndex, sequenceVisible } = msgModel; + const textDims = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(message, messageFont(conf)); + const textObj = (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.e)(); + textObj.x = startx; + textObj.y = starty + 10; + textObj.width = stopx - startx; + textObj.class = "messageText"; + textObj.dy = "1em"; + textObj.text = message; + textObj.fontFamily = conf.messageFontFamily; + textObj.fontSize = conf.messageFontSize; + textObj.fontWeight = conf.messageFontWeight; + textObj.anchor = conf.messageAlign; + textObj.valign = "center"; + textObj.textMargin = conf.wrapPadding; + textObj.tspan = false; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.G)(textObj.text) ? await drawKatex(diagram2, textObj, { startx, stopx, starty: lineStartY }) : drawText(diagram2, textObj); + const textWidth = textDims.width; + let line; + if (startx === stopx) { + if (conf.rightAngles) { + line = diagram2.append("path").attr( + "d", + `M ${startx},${lineStartY} H ${startx + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width / 2, textWidth / 2)} V ${lineStartY + 25} H ${startx}` + ); + } else { + line = diagram2.append("path").attr( + "d", + "M " + startx + "," + lineStartY + " C " + (startx + 60) + "," + (lineStartY - 10) + " " + (startx + 60) + "," + (lineStartY + 30) + " " + startx + "," + (lineStartY + 20) + ); + } + } else { + line = diagram2.append("line"); + line.attr("x1", startx); + line.attr("y1", lineStartY); + line.attr("x2", stopx); + line.attr("y2", lineStartY); + } + if (type === diagObj.db.LINETYPE.DOTTED || type === diagObj.db.LINETYPE.DOTTED_CROSS || type === diagObj.db.LINETYPE.DOTTED_POINT || type === diagObj.db.LINETYPE.DOTTED_OPEN) { + line.style("stroke-dasharray", "3, 3"); + line.attr("class", "messageLine1"); + } else { + line.attr("class", "messageLine0"); + } + let url = ""; + if (conf.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + line.attr("stroke-width", 2); + line.attr("stroke", "none"); + line.style("fill", "none"); + if (type === diagObj.db.LINETYPE.SOLID || type === diagObj.db.LINETYPE.DOTTED) { + line.attr("marker-end", "url(" + url + "#arrowhead)"); + } + if (type === diagObj.db.LINETYPE.SOLID_POINT || type === diagObj.db.LINETYPE.DOTTED_POINT) { + line.attr("marker-end", "url(" + url + "#filled-head)"); + } + if (type === diagObj.db.LINETYPE.SOLID_CROSS || type === diagObj.db.LINETYPE.DOTTED_CROSS) { + line.attr("marker-end", "url(" + url + "#crosshead)"); + } + if (sequenceVisible || conf.showSequenceNumbers) { + line.attr("marker-start", "url(" + url + "#sequencenumber)"); + diagram2.append("text").attr("x", startx).attr("y", lineStartY + 4).attr("font-family", "sans-serif").attr("font-size", "12px").attr("text-anchor", "middle").attr("class", "sequenceNumber").text(sequenceIndex); + } +}; +const addActorRenderingData = async function(diagram2, actors, createdActors, actorKeys, verticalPos, messages, isFooter) { + let prevWidth = 0; + let prevMargin = 0; + let prevBox = void 0; + let maxHeight = 0; + for (const actorKey of actorKeys) { + const actor = actors[actorKey]; + const box = actor.box; + if (prevBox && prevBox != box) { + if (!isFooter) { + bounds.models.addBox(prevBox); + } + prevMargin += conf.boxMargin + prevBox.margin; + } + if (box && box != prevBox) { + if (!isFooter) { + box.x = prevWidth + prevMargin; + box.y = verticalPos; + } + prevMargin += box.margin; + } + actor.width = actor.width || conf.width; + actor.height = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(actor.height || conf.height, conf.height); + actor.margin = actor.margin || conf.actorMargin; + maxHeight = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(maxHeight, actor.height); + if (createdActors[actor.name]) { + prevMargin += actor.width / 2; + } + actor.x = prevWidth + prevMargin; + actor.starty = bounds.getVerticalPos(); + bounds.insert(actor.x, verticalPos, actor.x + actor.width, actor.height); + prevWidth += actor.width + prevMargin; + if (actor.box) { + actor.box.width = prevWidth + box.margin - actor.box.x; + } + prevMargin = actor.margin; + prevBox = actor.box; + bounds.models.addActor(actor); + } + if (prevBox && !isFooter) { + bounds.models.addBox(prevBox); + } + bounds.bumpVerticalPos(maxHeight); +}; +const drawActors = async function(diagram2, actors, actorKeys, isFooter) { + if (!isFooter) { + for (const actorKey of actorKeys) { + const actor = actors[actorKey]; + await svgDraw.drawActor(diagram2, actor, conf, false); + } + } else { + let maxHeight = 0; + bounds.bumpVerticalPos(conf.boxMargin * 2); + for (const actorKey of actorKeys) { + const actor = actors[actorKey]; + if (!actor.stopy) { + actor.stopy = bounds.getVerticalPos(); + } + const height = await svgDraw.drawActor(diagram2, actor, conf, true); + maxHeight = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(maxHeight, height); + } + bounds.bumpVerticalPos(maxHeight + conf.boxMargin); + } +}; +const drawActorsPopup = function(diagram2, actors, actorKeys, doc) { + let maxHeight = 0; + let maxWidth = 0; + for (const actorKey of actorKeys) { + const actor = actors[actorKey]; + const minMenuWidth = getRequiredPopupWidth(actor); + const menuDimensions = svgDraw.drawPopup( + diagram2, + actor, + minMenuWidth, + conf, + conf.forceMenus, + doc + ); + if (menuDimensions.height > maxHeight) { + maxHeight = menuDimensions.height; + } + if (menuDimensions.width + actor.x > maxWidth) { + maxWidth = menuDimensions.width + actor.x; + } + } + return { maxHeight, maxWidth }; +}; +const setConf = function(cnf) { + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.f)(conf, cnf); + if (cnf.fontFamily) { + conf.actorFontFamily = conf.noteFontFamily = conf.messageFontFamily = cnf.fontFamily; + } + if (cnf.fontSize) { + conf.actorFontSize = conf.noteFontSize = conf.messageFontSize = cnf.fontSize; + } + if (cnf.fontWeight) { + conf.actorFontWeight = conf.noteFontWeight = conf.messageFontWeight = cnf.fontWeight; + } +}; +const actorActivations = function(actor) { + return bounds.activations.filter(function(activation) { + return activation.actor === actor; + }); +}; +const activationBounds = function(actor, actors) { + const actorObj = actors[actor]; + const activations = actorActivations(actor); + const left = activations.reduce(function(acc, activation) { + return _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMin(acc, activation.startx); + }, actorObj.x + actorObj.width / 2 - 1); + const right = activations.reduce(function(acc, activation) { + return _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(acc, activation.stopx); + }, actorObj.x + actorObj.width / 2 + 1); + return [left, right]; +}; +function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoopFn) { + bounds.bumpVerticalPos(preMargin); + let heightAdjust = postMargin; + if (msg.id && msg.message && loopWidths[msg.id]) { + const loopWidth = loopWidths[msg.id].width; + const textConf = messageFont(conf); + msg.message = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel(`[${msg.message}]`, loopWidth - 2 * conf.wrapPadding, textConf); + msg.width = loopWidth; + msg.wrap = true; + const textDims = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(msg.message, textConf); + const totalOffset = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(textDims.height, conf.labelBoxHeight); + heightAdjust = postMargin + totalOffset; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(`${totalOffset} - ${msg.message}`); + } + addLoopFn(msg); + bounds.bumpVerticalPos(heightAdjust); +} +function adjustCreatedDestroyedData(msg, msgModel, lineStartY, index, actors, createdActors, destroyedActors) { + function receiverAdjustment(actor, adjustment) { + if (actor.x < actors[msg.from].x) { + bounds.insert( + msgModel.stopx - adjustment, + msgModel.starty, + msgModel.startx, + msgModel.stopy + actor.height / 2 + conf.noteMargin + ); + msgModel.stopx = msgModel.stopx + adjustment; + } else { + bounds.insert( + msgModel.startx, + msgModel.starty, + msgModel.stopx + adjustment, + msgModel.stopy + actor.height / 2 + conf.noteMargin + ); + msgModel.stopx = msgModel.stopx - adjustment; + } + } + function senderAdjustment(actor, adjustment) { + if (actor.x < actors[msg.to].x) { + bounds.insert( + msgModel.startx - adjustment, + msgModel.starty, + msgModel.stopx, + msgModel.stopy + actor.height / 2 + conf.noteMargin + ); + msgModel.startx = msgModel.startx + adjustment; + } else { + bounds.insert( + msgModel.stopx, + msgModel.starty, + msgModel.startx + adjustment, + msgModel.stopy + actor.height / 2 + conf.noteMargin + ); + msgModel.startx = msgModel.startx - adjustment; + } + } + if (createdActors[msg.to] == index) { + const actor = actors[msg.to]; + const adjustment = actor.type == "actor" ? ACTOR_TYPE_WIDTH / 2 + 3 : actor.width / 2 + 3; + receiverAdjustment(actor, adjustment); + actor.starty = lineStartY - actor.height / 2; + bounds.bumpVerticalPos(actor.height / 2); + } else if (destroyedActors[msg.from] == index) { + const actor = actors[msg.from]; + if (conf.mirrorActors) { + const adjustment = actor.type == "actor" ? ACTOR_TYPE_WIDTH / 2 : actor.width / 2; + senderAdjustment(actor, adjustment); + } + actor.stopy = lineStartY - actor.height / 2; + bounds.bumpVerticalPos(actor.height / 2); + } else if (destroyedActors[msg.to] == index) { + const actor = actors[msg.to]; + if (conf.mirrorActors) { + const adjustment = actor.type == "actor" ? ACTOR_TYPE_WIDTH / 2 + 3 : actor.width / 2 + 3; + receiverAdjustment(actor, adjustment); + } + actor.stopy = lineStartY - actor.height / 2; + bounds.bumpVerticalPos(actor.height / 2); + } +} +const draw = async function(_text, id, _version, diagObj) { + const { securityLevel, sequence } = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + conf = sequence; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + bounds.init(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(diagObj.db); + const diagram2 = securityLevel === "sandbox" ? root.select(`[id="${id}"]`) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(`[id="${id}"]`); + const actors = diagObj.db.getActors(); + const createdActors = diagObj.db.getCreatedActors(); + const destroyedActors = diagObj.db.getDestroyedActors(); + const boxes = diagObj.db.getBoxes(); + let actorKeys = diagObj.db.getActorKeys(); + const messages = diagObj.db.getMessages(); + const title = diagObj.db.getDiagramTitle(); + const hasBoxes = diagObj.db.hasAtLeastOneBox(); + const hasBoxTitles = diagObj.db.hasAtLeastOneBoxWithTitle(); + const maxMessageWidthPerActor = await getMaxMessageWidthPerActor(actors, messages, diagObj); + conf.height = await calculateActorMargins(actors, maxMessageWidthPerActor, boxes); + svgDraw.insertComputerIcon(diagram2); + svgDraw.insertDatabaseIcon(diagram2); + svgDraw.insertClockIcon(diagram2); + if (hasBoxes) { + bounds.bumpVerticalPos(conf.boxMargin); + if (hasBoxTitles) { + bounds.bumpVerticalPos(boxes[0].textMaxHeight); + } + } + if (conf.hideUnusedParticipants === true) { + const newActors = /* @__PURE__ */ new Set(); + messages.forEach((message) => { + newActors.add(message.from); + newActors.add(message.to); + }); + actorKeys = actorKeys.filter((actorKey) => newActors.has(actorKey)); + } + await addActorRenderingData(diagram2, actors, createdActors, actorKeys, 0, messages, false); + const loopWidths = await calculateLoopBounds(messages, actors, maxMessageWidthPerActor, diagObj); + svgDraw.insertArrowHead(diagram2); + svgDraw.insertArrowCrossHead(diagram2); + svgDraw.insertArrowFilledHead(diagram2); + svgDraw.insertSequenceNumber(diagram2); + function activeEnd(msg, verticalPos) { + const activationData = bounds.endActivation(msg); + if (activationData.starty + 18 > verticalPos) { + activationData.starty = verticalPos - 6; + verticalPos += 12; + } + svgDraw.drawActivation( + diagram2, + activationData, + verticalPos, + conf, + actorActivations(msg.from.actor).length + ); + bounds.insert(activationData.startx, verticalPos - 10, activationData.stopx, verticalPos); + } + let sequenceIndex = 1; + let sequenceIndexStep = 1; + const messagesToDraw = []; + const backgrounds = []; + let index = 0; + for (const msg of messages) { + let loopModel, noteModel, msgModel; + switch (msg.type) { + case diagObj.db.LINETYPE.NOTE: + bounds.resetVerticalPos(); + noteModel = msg.noteModel; + await drawNote(diagram2, noteModel); + break; + case diagObj.db.LINETYPE.ACTIVE_START: + bounds.newActivation(msg, diagram2, actors); + break; + case diagObj.db.LINETYPE.ACTIVE_END: + activeEnd(msg, bounds.getVerticalPos()); + break; + case diagObj.db.LINETYPE.LOOP_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin + conf.boxTextMargin, + (message) => bounds.newLoop(message) + ); + break; + case diagObj.db.LINETYPE.LOOP_END: + loopModel = bounds.endLoop(); + await svgDraw.drawLoop(diagram2, loopModel, "loop", conf); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + bounds.models.addLoop(loopModel); + break; + case diagObj.db.LINETYPE.RECT_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin, + (message) => bounds.newLoop(void 0, message.message) + ); + break; + case diagObj.db.LINETYPE.RECT_END: + loopModel = bounds.endLoop(); + backgrounds.push(loopModel); + bounds.models.addLoop(loopModel); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + break; + case diagObj.db.LINETYPE.OPT_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin + conf.boxTextMargin, + (message) => bounds.newLoop(message) + ); + break; + case diagObj.db.LINETYPE.OPT_END: + loopModel = bounds.endLoop(); + await svgDraw.drawLoop(diagram2, loopModel, "opt", conf); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + bounds.models.addLoop(loopModel); + break; + case diagObj.db.LINETYPE.ALT_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin + conf.boxTextMargin, + (message) => bounds.newLoop(message) + ); + break; + case diagObj.db.LINETYPE.ALT_ELSE: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin + conf.boxTextMargin, + conf.boxMargin, + (message) => bounds.addSectionToLoop(message) + ); + break; + case diagObj.db.LINETYPE.ALT_END: + loopModel = bounds.endLoop(); + await svgDraw.drawLoop(diagram2, loopModel, "alt", conf); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + bounds.models.addLoop(loopModel); + break; + case diagObj.db.LINETYPE.PAR_START: + case diagObj.db.LINETYPE.PAR_OVER_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin + conf.boxTextMargin, + (message) => bounds.newLoop(message) + ); + bounds.saveVerticalPos(); + break; + case diagObj.db.LINETYPE.PAR_AND: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin + conf.boxTextMargin, + conf.boxMargin, + (message) => bounds.addSectionToLoop(message) + ); + break; + case diagObj.db.LINETYPE.PAR_END: + loopModel = bounds.endLoop(); + await svgDraw.drawLoop(diagram2, loopModel, "par", conf); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + bounds.models.addLoop(loopModel); + break; + case diagObj.db.LINETYPE.AUTONUMBER: + sequenceIndex = msg.message.start || sequenceIndex; + sequenceIndexStep = msg.message.step || sequenceIndexStep; + if (msg.message.visible) { + diagObj.db.enableSequenceNumbers(); + } else { + diagObj.db.disableSequenceNumbers(); + } + break; + case diagObj.db.LINETYPE.CRITICAL_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin + conf.boxTextMargin, + (message) => bounds.newLoop(message) + ); + break; + case diagObj.db.LINETYPE.CRITICAL_OPTION: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin + conf.boxTextMargin, + conf.boxMargin, + (message) => bounds.addSectionToLoop(message) + ); + break; + case diagObj.db.LINETYPE.CRITICAL_END: + loopModel = bounds.endLoop(); + await svgDraw.drawLoop(diagram2, loopModel, "critical", conf); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + bounds.models.addLoop(loopModel); + break; + case diagObj.db.LINETYPE.BREAK_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin + conf.boxTextMargin, + (message) => bounds.newLoop(message) + ); + break; + case diagObj.db.LINETYPE.BREAK_END: + loopModel = bounds.endLoop(); + await svgDraw.drawLoop(diagram2, loopModel, "break", conf); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + bounds.models.addLoop(loopModel); + break; + default: + try { + msgModel = msg.msgModel; + msgModel.starty = bounds.getVerticalPos(); + msgModel.sequenceIndex = sequenceIndex; + msgModel.sequenceVisible = diagObj.db.showSequenceNumbers(); + const lineStartY = await boundMessage(diagram2, msgModel); + adjustCreatedDestroyedData( + msg, + msgModel, + lineStartY, + index, + actors, + createdActors, + destroyedActors + ); + messagesToDraw.push({ messageModel: msgModel, lineStartY }); + bounds.models.addMessage(msgModel); + } catch (e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error("error while drawing message", e); + } + } + if ([ + diagObj.db.LINETYPE.SOLID_OPEN, + diagObj.db.LINETYPE.DOTTED_OPEN, + diagObj.db.LINETYPE.SOLID, + diagObj.db.LINETYPE.DOTTED, + diagObj.db.LINETYPE.SOLID_CROSS, + diagObj.db.LINETYPE.DOTTED_CROSS, + diagObj.db.LINETYPE.SOLID_POINT, + diagObj.db.LINETYPE.DOTTED_POINT + ].includes(msg.type)) { + sequenceIndex = sequenceIndex + sequenceIndexStep; + } + index++; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("createdActors", createdActors); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("destroyedActors", destroyedActors); + await drawActors(diagram2, actors, actorKeys, false); + for (const e of messagesToDraw) { + await drawMessage(diagram2, e.messageModel, e.lineStartY, diagObj); + } + if (conf.mirrorActors) { + await drawActors(diagram2, actors, actorKeys, true); + } + backgrounds.forEach((e) => svgDraw.drawBackgroundRect(diagram2, e)); + fixLifeLineHeights(diagram2, actors, actorKeys, conf); + for (const box2 of bounds.models.boxes) { + box2.height = bounds.getVerticalPos() - box2.y; + bounds.insert(box2.x, box2.y, box2.x + box2.width, box2.height); + box2.startx = box2.x; + box2.starty = box2.y; + box2.stopx = box2.startx + box2.width; + box2.stopy = box2.starty + box2.height; + box2.stroke = "rgb(0,0,0, 0.5)"; + await svgDraw.drawBox(diagram2, box2, conf); + } + if (hasBoxes) { + bounds.bumpVerticalPos(conf.boxMargin); + } + const requiredBoxSize = drawActorsPopup(diagram2, actors, actorKeys, doc); + const { bounds: box } = bounds.getBounds(); + let boxHeight = box.stopy - box.starty; + if (boxHeight < requiredBoxSize.maxHeight) { + boxHeight = requiredBoxSize.maxHeight; + } + let height = boxHeight + 2 * conf.diagramMarginY; + if (conf.mirrorActors) { + height = height - conf.boxMargin + conf.bottomMarginAdj; + } + let boxWidth = box.stopx - box.startx; + if (boxWidth < requiredBoxSize.maxWidth) { + boxWidth = requiredBoxSize.maxWidth; + } + const width = boxWidth + 2 * conf.diagramMarginX; + if (title) { + diagram2.append("text").text(title).attr("x", (box.stopx - box.startx) / 2 - 2 * conf.diagramMarginX).attr("y", -25); + } + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.i)(diagram2, height, width, conf.useMaxWidth); + const extraVertForTitle = title ? 40 : 0; + diagram2.attr( + "viewBox", + box.startx - conf.diagramMarginX + " -" + (conf.diagramMarginY + extraVertForTitle) + " " + width + " " + (height + extraVertForTitle) + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(`models:`, bounds.models); +}; +async function getMaxMessageWidthPerActor(actors, messages, diagObj) { + const maxMessageWidthPerActor = {}; + for (const msg of messages) { + if (actors[msg.to] && actors[msg.from]) { + const actor = actors[msg.to]; + if (msg.placement === diagObj.db.PLACEMENT.LEFTOF && !actor.prevActor) { + continue; + } + if (msg.placement === diagObj.db.PLACEMENT.RIGHTOF && !actor.nextActor) { + continue; + } + const isNote = msg.placement !== void 0; + const isMessage = !isNote; + const textFont = isNote ? noteFont(conf) : messageFont(conf); + const wrappedMessage = msg.wrap ? _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel(msg.message, conf.width - 2 * conf.wrapPadding, textFont) : msg.message; + const messageDimensions = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.G)(wrappedMessage) ? await (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.H)(msg.message, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()) : _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(wrappedMessage, textFont); + const messageWidth = messageDimensions.width + 2 * conf.wrapPadding; + if (isMessage && msg.from === actor.nextActor) { + maxMessageWidthPerActor[msg.to] = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[msg.to] || 0, + messageWidth + ); + } else if (isMessage && msg.from === actor.prevActor) { + maxMessageWidthPerActor[msg.from] = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[msg.from] || 0, + messageWidth + ); + } else if (isMessage && msg.from === msg.to) { + maxMessageWidthPerActor[msg.from] = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[msg.from] || 0, + messageWidth / 2 + ); + maxMessageWidthPerActor[msg.to] = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[msg.to] || 0, + messageWidth / 2 + ); + } else if (msg.placement === diagObj.db.PLACEMENT.RIGHTOF) { + maxMessageWidthPerActor[msg.from] = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[msg.from] || 0, + messageWidth + ); + } else if (msg.placement === diagObj.db.PLACEMENT.LEFTOF) { + maxMessageWidthPerActor[actor.prevActor] = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[actor.prevActor] || 0, + messageWidth + ); + } else if (msg.placement === diagObj.db.PLACEMENT.OVER) { + if (actor.prevActor) { + maxMessageWidthPerActor[actor.prevActor] = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[actor.prevActor] || 0, + messageWidth / 2 + ); + } + if (actor.nextActor) { + maxMessageWidthPerActor[msg.from] = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[msg.from] || 0, + messageWidth / 2 + ); + } + } + } + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("maxMessageWidthPerActor:", maxMessageWidthPerActor); + return maxMessageWidthPerActor; +} +const getRequiredPopupWidth = function(actor) { + let requiredPopupWidth = 0; + const textFont = actorFont(conf); + for (const key in actor.links) { + const labelDimensions = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(key, textFont); + const labelWidth = labelDimensions.width + 2 * conf.wrapPadding + 2 * conf.boxMargin; + if (requiredPopupWidth < labelWidth) { + requiredPopupWidth = labelWidth; + } + } + return requiredPopupWidth; +}; +async function calculateActorMargins(actors, actorToMessageWidth, boxes) { + let maxHeight = 0; + for (const prop of Object.keys(actors)) { + const actor = actors[prop]; + if (actor.wrap) { + actor.description = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel( + actor.description, + conf.width - 2 * conf.wrapPadding, + actorFont(conf) + ); + } + const actDims = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.G)(actor.description) ? await (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.H)(actor.description, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()) : _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(actor.description, actorFont(conf)); + actor.width = actor.wrap ? conf.width : _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width, actDims.width + 2 * conf.wrapPadding); + actor.height = actor.wrap ? _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(actDims.height, conf.height) : conf.height; + maxHeight = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(maxHeight, actor.height); + } + for (const actorKey in actorToMessageWidth) { + const actor = actors[actorKey]; + if (!actor) { + continue; + } + const nextActor = actors[actor.nextActor]; + if (!nextActor) { + const messageWidth2 = actorToMessageWidth[actorKey]; + const actorWidth2 = messageWidth2 + conf.actorMargin - actor.width / 2; + actor.margin = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(actorWidth2, conf.actorMargin); + continue; + } + const messageWidth = actorToMessageWidth[actorKey]; + const actorWidth = messageWidth + conf.actorMargin - actor.width / 2 - nextActor.width / 2; + actor.margin = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(actorWidth, conf.actorMargin); + } + let maxBoxHeight = 0; + boxes.forEach((box) => { + const textFont = messageFont(conf); + let totalWidth = box.actorKeys.reduce((total, aKey) => { + return total += actors[aKey].width + (actors[aKey].margin || 0); + }, 0); + totalWidth -= 2 * conf.boxTextMargin; + if (box.wrap) { + box.name = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel(box.name, totalWidth - 2 * conf.wrapPadding, textFont); + } + const boxMsgDimensions = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(box.name, textFont); + maxBoxHeight = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(boxMsgDimensions.height, maxBoxHeight); + const minWidth = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(totalWidth, boxMsgDimensions.width + 2 * conf.wrapPadding); + box.margin = conf.boxTextMargin; + if (totalWidth < minWidth) { + const missing = (minWidth - totalWidth) / 2; + box.margin += missing; + } + }); + boxes.forEach((box) => box.textMaxHeight = maxBoxHeight); + return _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(maxHeight, conf.height); +} +const buildNoteModel = async function(msg, actors, diagObj) { + const startx = actors[msg.from].x; + const stopx = actors[msg.to].x; + const shouldWrap = msg.wrap && msg.message; + let textDimensions = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.G)(msg.message) ? await (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.H)(msg.message, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()) : _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions( + shouldWrap ? _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel(msg.message, conf.width, noteFont(conf)) : msg.message, + noteFont(conf) + ); + const noteModel = { + width: shouldWrap ? conf.width : _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width, textDimensions.width + 2 * conf.noteMargin), + height: 0, + startx: actors[msg.from].x, + stopx: 0, + starty: 0, + stopy: 0, + message: msg.message + }; + if (msg.placement === diagObj.db.PLACEMENT.RIGHTOF) { + noteModel.width = shouldWrap ? _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width, textDimensions.width) : _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + actors[msg.from].width / 2 + actors[msg.to].width / 2, + textDimensions.width + 2 * conf.noteMargin + ); + noteModel.startx = startx + (actors[msg.from].width + conf.actorMargin) / 2; + } else if (msg.placement === diagObj.db.PLACEMENT.LEFTOF) { + noteModel.width = shouldWrap ? _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width, textDimensions.width + 2 * conf.noteMargin) : _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + actors[msg.from].width / 2 + actors[msg.to].width / 2, + textDimensions.width + 2 * conf.noteMargin + ); + noteModel.startx = startx - noteModel.width + (actors[msg.from].width - conf.actorMargin) / 2; + } else if (msg.to === msg.from) { + textDimensions = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions( + shouldWrap ? _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel( + msg.message, + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width, actors[msg.from].width), + noteFont(conf) + ) : msg.message, + noteFont(conf) + ); + noteModel.width = shouldWrap ? _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width, actors[msg.from].width) : _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + actors[msg.from].width, + conf.width, + textDimensions.width + 2 * conf.noteMargin + ); + noteModel.startx = startx + (actors[msg.from].width - noteModel.width) / 2; + } else { + noteModel.width = Math.abs(startx + actors[msg.from].width / 2 - (stopx + actors[msg.to].width / 2)) + conf.actorMargin; + noteModel.startx = startx < stopx ? startx + actors[msg.from].width / 2 - conf.actorMargin / 2 : stopx + actors[msg.to].width / 2 - conf.actorMargin / 2; + } + if (shouldWrap) { + noteModel.message = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel( + msg.message, + noteModel.width - 2 * conf.wrapPadding, + noteFont(conf) + ); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + `NM:[${noteModel.startx},${noteModel.stopx},${noteModel.starty},${noteModel.stopy}:${noteModel.width},${noteModel.height}=${msg.message}]` + ); + return noteModel; +}; +const buildMessageModel = function(msg, actors, diagObj) { + if (![ + diagObj.db.LINETYPE.SOLID_OPEN, + diagObj.db.LINETYPE.DOTTED_OPEN, + diagObj.db.LINETYPE.SOLID, + diagObj.db.LINETYPE.DOTTED, + diagObj.db.LINETYPE.SOLID_CROSS, + diagObj.db.LINETYPE.DOTTED_CROSS, + diagObj.db.LINETYPE.SOLID_POINT, + diagObj.db.LINETYPE.DOTTED_POINT + ].includes(msg.type)) { + return {}; + } + const [fromLeft, fromRight] = activationBounds(msg.from, actors); + const [toLeft, toRight] = activationBounds(msg.to, actors); + const isArrowToRight = fromLeft <= toLeft; + const startx = isArrowToRight ? fromRight : fromLeft; + let stopx = isArrowToRight ? toLeft : toRight; + const isArrowToActivation = Math.abs(toLeft - toRight) > 2; + const adjustValue = (value) => { + return isArrowToRight ? -value : value; + }; + if (msg.from === msg.to) { + stopx = startx; + } else { + if (msg.activate && !isArrowToActivation) { + stopx += adjustValue(conf.activationWidth / 2 - 1); + } + if (![diagObj.db.LINETYPE.SOLID_OPEN, diagObj.db.LINETYPE.DOTTED_OPEN].includes(msg.type)) { + stopx += adjustValue(3); + } + } + const allBounds = [fromLeft, fromRight, toLeft, toRight]; + const boundedWidth = Math.abs(startx - stopx); + if (msg.wrap && msg.message) { + msg.message = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel( + msg.message, + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(boundedWidth + 2 * conf.wrapPadding, conf.width), + messageFont(conf) + ); + } + const msgDims = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(msg.message, messageFont(conf)); + return { + width: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + msg.wrap ? 0 : msgDims.width + 2 * conf.wrapPadding, + boundedWidth + 2 * conf.wrapPadding, + conf.width + ), + height: 0, + startx, + stopx, + starty: 0, + stopy: 0, + message: msg.message, + type: msg.type, + wrap: msg.wrap, + fromBounds: Math.min.apply(null, allBounds), + toBounds: Math.max.apply(null, allBounds) + }; +}; +const calculateLoopBounds = async function(messages, actors, _maxWidthPerActor, diagObj) { + const loops = {}; + const stack = []; + let current, noteModel, msgModel; + for (const msg of messages) { + msg.id = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.random({ length: 10 }); + switch (msg.type) { + case diagObj.db.LINETYPE.LOOP_START: + case diagObj.db.LINETYPE.ALT_START: + case diagObj.db.LINETYPE.OPT_START: + case diagObj.db.LINETYPE.PAR_START: + case diagObj.db.LINETYPE.PAR_OVER_START: + case diagObj.db.LINETYPE.CRITICAL_START: + case diagObj.db.LINETYPE.BREAK_START: + stack.push({ + id: msg.id, + msg: msg.message, + from: Number.MAX_SAFE_INTEGER, + to: Number.MIN_SAFE_INTEGER, + width: 0 + }); + break; + case diagObj.db.LINETYPE.ALT_ELSE: + case diagObj.db.LINETYPE.PAR_AND: + case diagObj.db.LINETYPE.CRITICAL_OPTION: + if (msg.message) { + current = stack.pop(); + loops[current.id] = current; + loops[msg.id] = current; + stack.push(current); + } + break; + case diagObj.db.LINETYPE.LOOP_END: + case diagObj.db.LINETYPE.ALT_END: + case diagObj.db.LINETYPE.OPT_END: + case diagObj.db.LINETYPE.PAR_END: + case diagObj.db.LINETYPE.CRITICAL_END: + case diagObj.db.LINETYPE.BREAK_END: + current = stack.pop(); + loops[current.id] = current; + break; + case diagObj.db.LINETYPE.ACTIVE_START: + { + const actorRect = actors[msg.from ? msg.from.actor : msg.to.actor]; + const stackedSize = actorActivations(msg.from ? msg.from.actor : msg.to.actor).length; + const x = actorRect.x + actorRect.width / 2 + (stackedSize - 1) * conf.activationWidth / 2; + const toAdd = { + startx: x, + stopx: x + conf.activationWidth, + actor: msg.from.actor, + enabled: true + }; + bounds.activations.push(toAdd); + } + break; + case diagObj.db.LINETYPE.ACTIVE_END: + { + const lastActorActivationIdx = bounds.activations.map((a) => a.actor).lastIndexOf(msg.from.actor); + delete bounds.activations.splice(lastActorActivationIdx, 1)[0]; + } + break; + } + const isNote = msg.placement !== void 0; + if (isNote) { + noteModel = await buildNoteModel(msg, actors, diagObj); + msg.noteModel = noteModel; + stack.forEach((stk) => { + current = stk; + current.from = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMin(current.from, noteModel.startx); + current.to = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(current.to, noteModel.startx + noteModel.width); + current.width = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(current.width, Math.abs(current.from - current.to)) - conf.labelBoxWidth; + }); + } else { + msgModel = buildMessageModel(msg, actors, diagObj); + msg.msgModel = msgModel; + if (msgModel.startx && msgModel.stopx && stack.length > 0) { + stack.forEach((stk) => { + current = stk; + if (msgModel.startx === msgModel.stopx) { + const from = actors[msg.from]; + const to = actors[msg.to]; + current.from = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMin( + from.x - msgModel.width / 2, + from.x - from.width / 2, + current.from + ); + current.to = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + to.x + msgModel.width / 2, + to.x + from.width / 2, + current.to + ); + current.width = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(current.width, Math.abs(current.to - current.from)) - conf.labelBoxWidth; + } else { + current.from = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMin(msgModel.startx, current.from); + current.to = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(msgModel.stopx, current.to); + current.width = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(current.width, msgModel.width) - conf.labelBoxWidth; + } + }); + } + } + } + bounds.activations = []; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Loop type widths:", loops); + return loops; +}; +const renderer = { + bounds, + drawActors, + drawActorsPopup, + setConf, + draw +}; +const diagram = { + parser: parser$1, + db, + renderer, + styles, + init: ({ wrap }) => { + db.setWrap(wrap); + } +}; + + + +/***/ }), + +/***/ 58886: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ drawBackgroundRect), +/* harmony export */ b: () => (/* binding */ drawEmbeddedImage), +/* harmony export */ c: () => (/* binding */ drawImage), +/* harmony export */ d: () => (/* binding */ drawRect), +/* harmony export */ e: () => (/* binding */ getTextObj), +/* harmony export */ f: () => (/* binding */ drawText), +/* harmony export */ g: () => (/* binding */ getNoteRect) +/* harmony export */ }); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(16750); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); + + +const drawRect = (element, rectData) => { + const rectElement = element.append("rect"); + rectElement.attr("x", rectData.x); + rectElement.attr("y", rectData.y); + rectElement.attr("fill", rectData.fill); + rectElement.attr("stroke", rectData.stroke); + rectElement.attr("width", rectData.width); + rectElement.attr("height", rectData.height); + if (rectData.name) { + rectElement.attr("name", rectData.name); + } + rectData.rx !== void 0 && rectElement.attr("rx", rectData.rx); + rectData.ry !== void 0 && rectElement.attr("ry", rectData.ry); + if (rectData.attrs !== void 0) { + for (const attrKey in rectData.attrs) { + rectElement.attr(attrKey, rectData.attrs[attrKey]); + } + } + rectData.class !== void 0 && rectElement.attr("class", rectData.class); + return rectElement; +}; +const drawBackgroundRect = (element, bounds) => { + const rectData = { + x: bounds.startx, + y: bounds.starty, + width: bounds.stopx - bounds.startx, + height: bounds.stopy - bounds.starty, + fill: bounds.fill, + stroke: bounds.stroke, + class: "rect" + }; + const rectElement = drawRect(element, rectData); + rectElement.lower(); +}; +const drawText = (element, textData) => { + const nText = textData.text.replace(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.J, " "); + const textElem = element.append("text"); + textElem.attr("x", textData.x); + textElem.attr("y", textData.y); + textElem.attr("class", "legend"); + textElem.style("text-anchor", textData.anchor); + textData.class !== void 0 && textElem.attr("class", textData.class); + const tspan = textElem.append("tspan"); + tspan.attr("x", textData.x + textData.textMargin * 2); + tspan.text(nText); + return textElem; +}; +const drawImage = (elem, x, y, link) => { + const imageElement = elem.append("image"); + imageElement.attr("x", x); + imageElement.attr("y", y); + const sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Jf)(link); + imageElement.attr("xlink:href", sanitizedLink); +}; +const drawEmbeddedImage = (element, x, y, link) => { + const imageElement = element.append("use"); + imageElement.attr("x", x); + imageElement.attr("y", y); + const sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Jf)(link); + imageElement.attr("xlink:href", `#${sanitizedLink}`); +}; +const getNoteRect = () => { + const noteRectData = { + x: 0, + y: 0, + width: 100, + height: 100, + fill: "#EDF2AE", + stroke: "#666", + anchor: "start", + rx: 0, + ry: 0 + }; + return noteRectData; +}; +const getTextObj = () => { + const testObject = { + x: 0, + y: 0, + width: 100, + height: 100, + "text-anchor": "start", + style: "#666", + textMargin: 0, + rx: 0, + ry: 0, + tspan: true + }; + return testObject; +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/2130.4a68cd24.js b/assets/js/2130.4a68cd24.js new file mode 100644 index 0000000000..c08a0251d1 --- /dev/null +++ b/assets/js/2130.4a68cd24.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2130],{22130:(e,t,r)=>{r.d(t,{default:()=>Ja});class a{constructor(e,t,r){this.lexer=void 0,this.start=void 0,this.end=void 0,this.lexer=e,this.start=t,this.end=r}static range(e,t){return t?e&&e.loc&&t.loc&&e.loc.lexer===t.loc.lexer?new a(e.loc.lexer,e.loc.start,t.loc.end):null:e&&e.loc}}class n{constructor(e,t){this.text=void 0,this.loc=void 0,this.noexpand=void 0,this.treatAsRelax=void 0,this.text=e,this.loc=t}range(e,t){return new n(t,a.range(this,e))}}class i{constructor(e,t){this.name=void 0,this.position=void 0,this.length=void 0,this.rawMessage=void 0;var r,a,n="KaTeX parse error: "+e,o=t&&t.loc;if(o&&o.start<=o.end){var s=o.lexer.input;r=o.start,a=o.end,r===s.length?n+=" at end of input: ":n+=" at position "+(r+1)+": ";var l=s.slice(r,a).replace(/[^]/g,"$&\u0332");n+=(r>15?"\u2026"+s.slice(r-15,r):s.slice(0,r))+l+(a+15":">","<":"<",'"':""","'":"'"},l=/[&><"']/g;var h=function e(t){return"ordgroup"===t.type||"color"===t.type?1===t.body.length?e(t.body[0]):t:"font"===t.type?e(t.body):t},m={contains:function(e,t){return-1!==e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(l,(e=>s[e]))},hyphenate:function(e){return e.replace(o,"-$1").toLowerCase()},getBaseElem:h,isCharacterBox:function(e){var t=h(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},protocolFromUrl:function(e){var t=/^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(e);return t?":"!==t[2]?null:/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(t[1])?t[1].toLowerCase():null:"_relative"}},c={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:e=>"#"+e},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(e,t)=>(t.push(e),t)},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:e=>Math.max(0,e),cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:e=>Math.max(0,e),cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:e=>Math.max(0,e),cli:"-e, --max-expand ",cliProcessor:e=>"Infinity"===e?1/0:parseInt(e)},globalGroup:{type:"boolean",cli:!1}};function p(e){if(e.default)return e.default;var t=e.type,r=Array.isArray(t)?t[0]:t;if("string"!=typeof r)return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}class u{constructor(e){for(var t in this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},c)if(c.hasOwnProperty(t)){var r=c[t];this[t]=void 0!==e[t]?r.processor?r.processor(e[t]):e[t]:p(r)}}reportNonstrict(e,t,r){var a=this.strict;if("function"==typeof a&&(a=a(e,t,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new i("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]")}}useStrictBehavior(e,t,r){var a=this.strict;if("function"==typeof a)try{a=a(e,t,r)}catch(n){a="error"}return!(!a||"ignore"===a)&&(!0===a||"error"===a||("warn"===a?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]"),!1)))}isTrusted(e){if(e.url&&!e.protocol){var t=m.protocolFromUrl(e.url);if(null==t)return!1;e.protocol=t}var r="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(r)}}class d{constructor(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}sup(){return g[f[this.id]]}sub(){return g[v[this.id]]}fracNum(){return g[b[this.id]]}fracDen(){return g[y[this.id]]}cramp(){return g[x[this.id]]}text(){return g[w[this.id]]}isTight(){return this.size>=2}}var g=[new d(0,0,!1),new d(1,0,!0),new d(2,1,!1),new d(3,1,!0),new d(4,2,!1),new d(5,2,!0),new d(6,3,!1),new d(7,3,!0)],f=[4,5,4,5,6,7,6,7],v=[5,5,5,5,7,7,7,7],b=[2,3,4,5,6,7,6,7],y=[3,3,5,5,7,7,7,7],x=[1,1,3,3,5,5,7,7],w=[0,1,2,3,2,3,2,3],k={DISPLAY:g[0],TEXT:g[2],SCRIPT:g[4],SCRIPTSCRIPT:g[6]},S=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];var M=[];function z(e){for(var t=0;t=M[t]&&e<=M[t+1])return!0;return!1}S.forEach((e=>e.blocks.forEach((e=>M.push(...e)))));var A=80,T={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"};class B{constructor(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(e){return m.contains(this.classes,e)}toNode(){for(var e=document.createDocumentFragment(),t=0;te.toText())).join("")}}var C={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}},N={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},q={"\xc5":"A","\xd0":"D","\xde":"o","\xe5":"a","\xf0":"d","\xfe":"o","\u0410":"A","\u0411":"B","\u0412":"B","\u0413":"F","\u0414":"A","\u0415":"E","\u0416":"K","\u0417":"3","\u0418":"N","\u0419":"N","\u041a":"K","\u041b":"N","\u041c":"M","\u041d":"H","\u041e":"O","\u041f":"N","\u0420":"P","\u0421":"C","\u0422":"T","\u0423":"y","\u0424":"O","\u0425":"X","\u0426":"U","\u0427":"h","\u0428":"W","\u0429":"W","\u042a":"B","\u042b":"X","\u042c":"B","\u042d":"3","\u042e":"X","\u042f":"R","\u0430":"a","\u0431":"b","\u0432":"a","\u0433":"r","\u0434":"y","\u0435":"e","\u0436":"m","\u0437":"e","\u0438":"n","\u0439":"n","\u043a":"n","\u043b":"n","\u043c":"m","\u043d":"n","\u043e":"o","\u043f":"n","\u0440":"p","\u0441":"c","\u0442":"o","\u0443":"y","\u0444":"b","\u0445":"x","\u0446":"n","\u0447":"n","\u0448":"w","\u0449":"w","\u044a":"a","\u044b":"m","\u044c":"a","\u044d":"e","\u044e":"m","\u044f":"r"};function I(e,t,r){if(!C[t])throw new Error("Font metrics not found for font: "+t+".");var a=e.charCodeAt(0),n=C[t][a];if(!n&&e[0]in q&&(a=q[e[0]].charCodeAt(0),n=C[t][a]),n||"text"!==r||z(a)&&(n=C[t][77]),n)return{depth:n[0],height:n[1],italic:n[2],skew:n[3],width:n[4]}}var R={};var H=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],O=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],E=function(e,t){return t.size<2?e:H[e-1][t.size-1]};class L{constructor(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||L.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=O[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}extend(e){var t={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return new L(t)}havingStyle(e){return this.style===e?this:this.extend({style:e,size:E(this.textSize,e)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:O[e-1]})}havingBaseStyle(e){e=e||this.style.text();var t=E(L.BASESIZE,e);return this.size===t&&this.textSize===L.BASESIZE&&this.style===e?this:this.extend({style:e,size:t})}havingBaseSizing(){var e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})}withColor(e){return this.extend({color:e})}withPhantom(){return this.extend({phantom:!0})}withFont(e){return this.extend({font:e})}withTextFontFamily(e){return this.extend({fontFamily:e,font:""})}withTextFontWeight(e){return this.extend({fontWeight:e,font:""})}withTextFontShape(e){return this.extend({fontShape:e,font:""})}sizingClasses(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==L.BASESIZE?["sizing","reset-size"+this.size,"size"+L.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=function(e){var t;if(!R[t=e>=5?0:e>=3?1:2]){var r=R[t]={cssEmPerMu:N.quad[t]/18};for(var a in N)N.hasOwnProperty(a)&&(r[a]=N[a][t])}return R[t]}(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}}L.BASESIZE=6;var D={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},V={ex:!0,em:!0,mu:!0},P=function(e){return"string"!=typeof e&&(e=e.unit),e in D||e in V||"ex"===e},F=function(e,t){var r;if(e.unit in D)r=D[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{var a;if(a=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=a.fontMetrics().xHeight;else{if("em"!==e.unit)throw new i("Invalid unit: '"+e.unit+"'");r=a.fontMetrics().quad}a!==t&&(r*=a.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},G=function(e){return+e.toFixed(4)+"em"},U=function(e){return e.filter((e=>e)).join(" ")},Y=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var a=t.getColor();a&&(this.style.color=a)}},X=function(e){var t=document.createElement(e);for(var r in t.className=U(this.classes),this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var a in this.attributes)this.attributes.hasOwnProperty(a)&&t.setAttribute(a,this.attributes[a]);for(var n=0;n"};class _{constructor(e,t,r,a){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,Y.call(this,e,r,a),this.children=t||[]}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return m.contains(this.classes,e)}toNode(){return X.call(this,"span")}toMarkup(){return W.call(this,"span")}}class j{constructor(e,t,r,a){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,Y.call(this,t,a),this.children=r||[],this.setAttribute("href",e)}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return m.contains(this.classes,e)}toNode(){return X.call(this,"a")}toMarkup(){return W.call(this,"a")}}class ${constructor(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}hasClass(e){return m.contains(this.classes,e)}toNode(){var e=document.createElement("img");for(var t in e.src=this.src,e.alt=this.alt,e.className="mord",this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e}toMarkup(){var e=''+m.escape(this.alt)+'=n[0]&&e<=n[1])return r.name}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=Z[this.text])}hasClass(e){return m.contains(this.classes,e)}toNode(){var e=document.createTextNode(this.text),t=null;for(var r in this.italic>0&&((t=document.createElement("span")).style.marginRight=G(this.italic)),this.classes.length>0&&((t=t||document.createElement("span")).className=U(this.classes)),this.style)this.style.hasOwnProperty(r)&&((t=t||document.createElement("span")).style[r]=this.style[r]);return t?(t.appendChild(e),t):e}toMarkup(){var e=!1,t="0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(a)&&(r+=m.hyphenate(a)+":"+this.style[a]+";");r&&(e=!0,t+=' style="'+m.escape(r)+'"');var n=m.escape(this.text);return e?(t+=">",t+=n,t+=""):n}}class J{constructor(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}toNode(){var e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(var r=0;r':''}}class ee{constructor(e){this.attributes=void 0,this.attributes=e||{}}toNode(){var e=document.createElementNS("http://www.w3.org/2000/svg","line");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e}toMarkup(){var e="","\\gt",!0),ie(oe,le,be,"\u2208","\\in",!0),ie(oe,le,be,"\ue020","\\@not"),ie(oe,le,be,"\u2282","\\subset",!0),ie(oe,le,be,"\u2283","\\supset",!0),ie(oe,le,be,"\u2286","\\subseteq",!0),ie(oe,le,be,"\u2287","\\supseteq",!0),ie(oe,he,be,"\u2288","\\nsubseteq",!0),ie(oe,he,be,"\u2289","\\nsupseteq",!0),ie(oe,le,be,"\u22a8","\\models"),ie(oe,le,be,"\u2190","\\leftarrow",!0),ie(oe,le,be,"\u2264","\\le"),ie(oe,le,be,"\u2264","\\leq",!0),ie(oe,le,be,"<","\\lt",!0),ie(oe,le,be,"\u2192","\\rightarrow",!0),ie(oe,le,be,"\u2192","\\to"),ie(oe,he,be,"\u2271","\\ngeq",!0),ie(oe,he,be,"\u2270","\\nleq",!0),ie(oe,le,ye,"\xa0","\\ "),ie(oe,le,ye,"\xa0","\\space"),ie(oe,le,ye,"\xa0","\\nobreakspace"),ie(se,le,ye,"\xa0","\\ "),ie(se,le,ye,"\xa0"," "),ie(se,le,ye,"\xa0","\\space"),ie(se,le,ye,"\xa0","\\nobreakspace"),ie(oe,le,ye,null,"\\nobreak"),ie(oe,le,ye,null,"\\allowbreak"),ie(oe,le,ve,",",","),ie(oe,le,ve,";",";"),ie(oe,he,ce,"\u22bc","\\barwedge",!0),ie(oe,he,ce,"\u22bb","\\veebar",!0),ie(oe,le,ce,"\u2299","\\odot",!0),ie(oe,le,ce,"\u2295","\\oplus",!0),ie(oe,le,ce,"\u2297","\\otimes",!0),ie(oe,le,xe,"\u2202","\\partial",!0),ie(oe,le,ce,"\u2298","\\oslash",!0),ie(oe,he,ce,"\u229a","\\circledcirc",!0),ie(oe,he,ce,"\u22a1","\\boxdot",!0),ie(oe,le,ce,"\u25b3","\\bigtriangleup"),ie(oe,le,ce,"\u25bd","\\bigtriangledown"),ie(oe,le,ce,"\u2020","\\dagger"),ie(oe,le,ce,"\u22c4","\\diamond"),ie(oe,le,ce,"\u22c6","\\star"),ie(oe,le,ce,"\u25c3","\\triangleleft"),ie(oe,le,ce,"\u25b9","\\triangleright"),ie(oe,le,fe,"{","\\{"),ie(se,le,xe,"{","\\{"),ie(se,le,xe,"{","\\textbraceleft"),ie(oe,le,pe,"}","\\}"),ie(se,le,xe,"}","\\}"),ie(se,le,xe,"}","\\textbraceright"),ie(oe,le,fe,"{","\\lbrace"),ie(oe,le,pe,"}","\\rbrace"),ie(oe,le,fe,"[","\\lbrack",!0),ie(se,le,xe,"[","\\lbrack",!0),ie(oe,le,pe,"]","\\rbrack",!0),ie(se,le,xe,"]","\\rbrack",!0),ie(oe,le,fe,"(","\\lparen",!0),ie(oe,le,pe,")","\\rparen",!0),ie(se,le,xe,"<","\\textless",!0),ie(se,le,xe,">","\\textgreater",!0),ie(oe,le,fe,"\u230a","\\lfloor",!0),ie(oe,le,pe,"\u230b","\\rfloor",!0),ie(oe,le,fe,"\u2308","\\lceil",!0),ie(oe,le,pe,"\u2309","\\rceil",!0),ie(oe,le,xe,"\\","\\backslash"),ie(oe,le,xe,"\u2223","|"),ie(oe,le,xe,"\u2223","\\vert"),ie(se,le,xe,"|","\\textbar",!0),ie(oe,le,xe,"\u2225","\\|"),ie(oe,le,xe,"\u2225","\\Vert"),ie(se,le,xe,"\u2225","\\textbardbl"),ie(se,le,xe,"~","\\textasciitilde"),ie(se,le,xe,"\\","\\textbackslash"),ie(se,le,xe,"^","\\textasciicircum"),ie(oe,le,be,"\u2191","\\uparrow",!0),ie(oe,le,be,"\u21d1","\\Uparrow",!0),ie(oe,le,be,"\u2193","\\downarrow",!0),ie(oe,le,be,"\u21d3","\\Downarrow",!0),ie(oe,le,be,"\u2195","\\updownarrow",!0),ie(oe,le,be,"\u21d5","\\Updownarrow",!0),ie(oe,le,ge,"\u2210","\\coprod"),ie(oe,le,ge,"\u22c1","\\bigvee"),ie(oe,le,ge,"\u22c0","\\bigwedge"),ie(oe,le,ge,"\u2a04","\\biguplus"),ie(oe,le,ge,"\u22c2","\\bigcap"),ie(oe,le,ge,"\u22c3","\\bigcup"),ie(oe,le,ge,"\u222b","\\int"),ie(oe,le,ge,"\u222b","\\intop"),ie(oe,le,ge,"\u222c","\\iint"),ie(oe,le,ge,"\u222d","\\iiint"),ie(oe,le,ge,"\u220f","\\prod"),ie(oe,le,ge,"\u2211","\\sum"),ie(oe,le,ge,"\u2a02","\\bigotimes"),ie(oe,le,ge,"\u2a01","\\bigoplus"),ie(oe,le,ge,"\u2a00","\\bigodot"),ie(oe,le,ge,"\u222e","\\oint"),ie(oe,le,ge,"\u222f","\\oiint"),ie(oe,le,ge,"\u2230","\\oiiint"),ie(oe,le,ge,"\u2a06","\\bigsqcup"),ie(oe,le,ge,"\u222b","\\smallint"),ie(se,le,ue,"\u2026","\\textellipsis"),ie(oe,le,ue,"\u2026","\\mathellipsis"),ie(se,le,ue,"\u2026","\\ldots",!0),ie(oe,le,ue,"\u2026","\\ldots",!0),ie(oe,le,ue,"\u22ef","\\@cdots",!0),ie(oe,le,ue,"\u22f1","\\ddots",!0),ie(oe,le,xe,"\u22ee","\\varvdots"),ie(oe,le,me,"\u02ca","\\acute"),ie(oe,le,me,"\u02cb","\\grave"),ie(oe,le,me,"\xa8","\\ddot"),ie(oe,le,me,"~","\\tilde"),ie(oe,le,me,"\u02c9","\\bar"),ie(oe,le,me,"\u02d8","\\breve"),ie(oe,le,me,"\u02c7","\\check"),ie(oe,le,me,"^","\\hat"),ie(oe,le,me,"\u20d7","\\vec"),ie(oe,le,me,"\u02d9","\\dot"),ie(oe,le,me,"\u02da","\\mathring"),ie(oe,le,de,"\ue131","\\@imath"),ie(oe,le,de,"\ue237","\\@jmath"),ie(oe,le,xe,"\u0131","\u0131"),ie(oe,le,xe,"\u0237","\u0237"),ie(se,le,xe,"\u0131","\\i",!0),ie(se,le,xe,"\u0237","\\j",!0),ie(se,le,xe,"\xdf","\\ss",!0),ie(se,le,xe,"\xe6","\\ae",!0),ie(se,le,xe,"\u0153","\\oe",!0),ie(se,le,xe,"\xf8","\\o",!0),ie(se,le,xe,"\xc6","\\AE",!0),ie(se,le,xe,"\u0152","\\OE",!0),ie(se,le,xe,"\xd8","\\O",!0),ie(se,le,me,"\u02ca","\\'"),ie(se,le,me,"\u02cb","\\`"),ie(se,le,me,"\u02c6","\\^"),ie(se,le,me,"\u02dc","\\~"),ie(se,le,me,"\u02c9","\\="),ie(se,le,me,"\u02d8","\\u"),ie(se,le,me,"\u02d9","\\."),ie(se,le,me,"\xb8","\\c"),ie(se,le,me,"\u02da","\\r"),ie(se,le,me,"\u02c7","\\v"),ie(se,le,me,"\xa8",'\\"'),ie(se,le,me,"\u02dd","\\H"),ie(se,le,me,"\u25ef","\\textcircled");var we={"--":!0,"---":!0,"``":!0,"''":!0};ie(se,le,xe,"\u2013","--",!0),ie(se,le,xe,"\u2013","\\textendash"),ie(se,le,xe,"\u2014","---",!0),ie(se,le,xe,"\u2014","\\textemdash"),ie(se,le,xe,"\u2018","`",!0),ie(se,le,xe,"\u2018","\\textquoteleft"),ie(se,le,xe,"\u2019","'",!0),ie(se,le,xe,"\u2019","\\textquoteright"),ie(se,le,xe,"\u201c","``",!0),ie(se,le,xe,"\u201c","\\textquotedblleft"),ie(se,le,xe,"\u201d","''",!0),ie(se,le,xe,"\u201d","\\textquotedblright"),ie(oe,le,xe,"\xb0","\\degree",!0),ie(se,le,xe,"\xb0","\\degree"),ie(se,le,xe,"\xb0","\\textdegree",!0),ie(oe,le,xe,"\xa3","\\pounds"),ie(oe,le,xe,"\xa3","\\mathsterling",!0),ie(se,le,xe,"\xa3","\\pounds"),ie(se,le,xe,"\xa3","\\textsterling",!0),ie(oe,he,xe,"\u2720","\\maltese"),ie(se,he,xe,"\u2720","\\maltese");for(var ke='0123456789/@."',Se=0;Se<14;Se++){var Me=ke.charAt(Se);ie(oe,le,xe,Me,Me)}for(var ze='0123456789!@*()-=+";:?/.,',Ae=0;Ae<25;Ae++){var Te=ze.charAt(Ae);ie(se,le,xe,Te,Te)}for(var Be="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Ce=0;Ce<52;Ce++){var Ne=Be.charAt(Ce);ie(oe,le,de,Ne,Ne),ie(se,le,xe,Ne,Ne)}ie(oe,he,xe,"C","\u2102"),ie(se,he,xe,"C","\u2102"),ie(oe,he,xe,"H","\u210d"),ie(se,he,xe,"H","\u210d"),ie(oe,he,xe,"N","\u2115"),ie(se,he,xe,"N","\u2115"),ie(oe,he,xe,"P","\u2119"),ie(se,he,xe,"P","\u2119"),ie(oe,he,xe,"Q","\u211a"),ie(se,he,xe,"Q","\u211a"),ie(oe,he,xe,"R","\u211d"),ie(se,he,xe,"R","\u211d"),ie(oe,he,xe,"Z","\u2124"),ie(se,he,xe,"Z","\u2124"),ie(oe,le,de,"h","\u210e"),ie(se,le,de,"h","\u210e");for(var qe="",Ie=0;Ie<52;Ie++){var Re=Be.charAt(Ie);ie(oe,le,de,Re,qe=String.fromCharCode(55349,56320+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56372+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56424+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56580+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56684+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56736+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56788+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56840+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56944+Ie)),ie(se,le,xe,Re,qe),Ie<26&&(ie(oe,le,de,Re,qe=String.fromCharCode(55349,56632+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56476+Ie)),ie(se,le,xe,Re,qe))}ie(oe,le,de,"k",qe=String.fromCharCode(55349,56668)),ie(se,le,xe,"k",qe);for(var He=0;He<10;He++){var Oe=He.toString();ie(oe,le,de,Oe,qe=String.fromCharCode(55349,57294+He)),ie(se,le,xe,Oe,qe),ie(oe,le,de,Oe,qe=String.fromCharCode(55349,57314+He)),ie(se,le,xe,Oe,qe),ie(oe,le,de,Oe,qe=String.fromCharCode(55349,57324+He)),ie(se,le,xe,Oe,qe),ie(oe,le,de,Oe,qe=String.fromCharCode(55349,57334+He)),ie(se,le,xe,Oe,qe)}for(var Ee="\xd0\xde\xfe",Le=0;Le<3;Le++){var De=Ee.charAt(Le);ie(oe,le,de,De,De),ie(se,le,xe,De,De)}var Ve=[["mathbf","textbf","Main-Bold"],["mathbf","textbf","Main-Bold"],["mathnormal","textit","Math-Italic"],["mathnormal","textit","Math-Italic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["mathscr","textscr","Script-Regular"],["","",""],["","",""],["","",""],["mathfrak","textfrak","Fraktur-Regular"],["mathfrak","textfrak","Fraktur-Regular"],["mathbb","textbb","AMS-Regular"],["mathbb","textbb","AMS-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathitsf","textitsf","SansSerif-Italic"],["mathitsf","textitsf","SansSerif-Italic"],["","",""],["","",""],["mathtt","texttt","Typewriter-Regular"],["mathtt","texttt","Typewriter-Regular"]],Pe=[["mathbf","textbf","Main-Bold"],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathtt","texttt","Typewriter-Regular"]],Fe=function(e,t,r){return ne[r][e]&&ne[r][e].replace&&(e=ne[r][e].replace),{value:e,metrics:I(e,t,r)}},Ge=function(e,t,r,a,n){var i,o=Fe(e,t,r),s=o.metrics;if(e=o.value,s){var l=s.italic;("text"===r||a&&"mathit"===a.font)&&(l=0),i=new K(e,s.height,s.depth,l,s.skew,s.width,n)}else"undefined"!=typeof console&&console.warn("No character metrics for '"+e+"' in style '"+t+"' and mode '"+r+"'"),i=new K(e,0,0,0,0,0,n);if(a){i.maxFontSize=a.sizeMultiplier,a.style.isTight()&&i.classes.push("mtight");var h=a.getColor();h&&(i.style.color=h)}return i},Ue=(e,t)=>{if(U(e.classes)!==U(t.classes)||e.skew!==t.skew||e.maxFontSize!==t.maxFontSize)return!1;if(1===e.classes.length){var r=e.classes[0];if("mbin"===r||"mord"===r)return!1}for(var a in e.style)if(e.style.hasOwnProperty(a)&&e.style[a]!==t.style[a])return!1;for(var n in t.style)if(t.style.hasOwnProperty(n)&&e.style[n]!==t.style[n])return!1;return!0},Ye=function(e){for(var t=0,r=0,a=0,n=0;nt&&(t=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>a&&(a=i.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=a},Xe=function(e,t,r,a){var n=new _(e,t,r,a);return Ye(n),n},We=(e,t,r,a)=>new _(e,t,r,a),_e=function(e){var t=new B(e);return Ye(t),t},je=function(e,t,r){var a="";switch(e){case"amsrm":a="AMS";break;case"textrm":a="Main";break;case"textsf":a="SansSerif";break;case"texttt":a="Typewriter";break;default:a=e}return a+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")},$e={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},Ze={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},Ke={fontMap:$e,makeSymbol:Ge,mathsym:function(e,t,r,a){return void 0===a&&(a=[]),"boldsymbol"===r.font&&Fe(e,"Main-Bold",t).metrics?Ge(e,"Main-Bold",t,r,a.concat(["mathbf"])):"\\"===e||"main"===ne[t][e].font?Ge(e,"Main-Regular",t,r,a):Ge(e,"AMS-Regular",t,r,a.concat(["amsrm"]))},makeSpan:Xe,makeSvgSpan:We,makeLineSpan:function(e,t,r){var a=Xe([e],[],t);return a.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),a.style.borderBottomWidth=G(a.height),a.maxFontSize=1,a},makeAnchor:function(e,t,r,a){var n=new j(e,t,r,a);return Ye(n),n},makeFragment:_e,wrapFragment:function(e,t){return e instanceof B?Xe([],[e],t):e},makeVList:function(e,t){for(var{children:r,depth:a}=function(e){if("individualShift"===e.positionType){for(var t=e.children,r=[t[0]],a=-t[0].shift-t[0].elem.depth,n=a,i=1;i0)return Ge(n,h,a,t,o.concat(m));if(l){var c,p;if("boldsymbol"===l){var u=function(e,t,r,a,n){return"textord"!==n&&Fe(e,"Math-BoldItalic",t).metrics?{fontName:"Math-BoldItalic",fontClass:"boldsymbol"}:{fontName:"Main-Bold",fontClass:"mathbf"}}(n,a,0,0,r);c=u.fontName,p=[u.fontClass]}else s?(c=$e[l].fontName,p=[l]):(c=je(l,t.fontWeight,t.fontShape),p=[l,t.fontWeight,t.fontShape]);if(Fe(n,c,a).metrics)return Ge(n,c,a,t,o.concat(p));if(we.hasOwnProperty(n)&&"Typewriter"===c.slice(0,10)){for(var d=[],g=0;g{var r=Xe(["mspace"],[],t),a=F(e,t);return r.style.marginRight=G(a),r},staticSvg:function(e,t){var[r,a,n]=Ze[e],i=new Q(r),o=new J([i],{width:G(a),height:G(n),style:"width:"+G(a),viewBox:"0 0 "+1e3*a+" "+1e3*n,preserveAspectRatio:"xMinYMin"}),s=We(["overlay"],[o],t);return s.height=n,s.style.height=G(n),s.style.width=G(a),s},svgData:Ze,tryCombineChars:e=>{for(var t=0;t{var r=t.classes[0],a=e.classes[0];"mbin"===r&&m.contains(pt,a)?t.classes[0]="mord":"mbin"===a&&m.contains(ct,r)&&(e.classes[0]="mord")}),{node:c},p,u),ft(n,((e,t)=>{var r=yt(t),a=yt(e),n=r&&a?e.hasClass("mtight")?rt[r][a]:tt[r][a]:null;if(n)return Ke.makeGlue(n,l)}),{node:c},p,u),n},ft=function e(t,r,a,n,i){n&&t.push(n);for(var o=0;or=>{t.splice(e+1,0,r),o++})(o)}}n&&t.pop()},vt=function(e){return e instanceof B||e instanceof j||e instanceof _&&e.hasClass("enclosing")?e:null},bt=function e(t,r){var a=vt(t);if(a){var n=a.children;if(n.length){if("right"===r)return e(n[n.length-1],"right");if("left"===r)return e(n[0],"left")}}return t},yt=function(e,t){return e?(t&&(e=bt(e,t)),dt[e.classes[0]]||null):null},xt=function(e,t){var r=["nulldelimiter"].concat(e.baseSizingClasses());return mt(t.concat(r))},wt=function(e,t,r){if(!e)return mt();if(nt[e.type]){var a=nt[e.type](e,t);if(r&&t.size!==r.size){a=mt(t.sizingClasses(r),[a],t);var n=t.sizeMultiplier/r.sizeMultiplier;a.height*=n,a.depth*=n}return a}throw new i("Got group of unknown type: '"+e.type+"'")};function kt(e,t){var r=mt(["base"],e,t),a=mt(["strut"]);return a.style.height=G(r.height+r.depth),r.depth&&(a.style.verticalAlign=G(-r.depth)),r.children.unshift(a),r}function St(e,t){var r=null;1===e.length&&"tag"===e[0].type&&(r=e[0].tag,e=e[0].body);var a,n=gt(e,t,"root");2===n.length&&n[1].hasClass("tag")&&(a=n.pop());for(var i,o=[],s=[],l=0;l0&&(o.push(kt(s,t)),s=[]),o.push(n[l]));s.length>0&&o.push(kt(s,t)),r?((i=kt(gt(r,t,!0))).classes=["tag"],o.push(i)):a&&o.push(a);var m=mt(["katex-html"],o);if(m.setAttribute("aria-hidden","true"),i){var c=i.children[0];c.style.height=G(m.height+m.depth),m.depth&&(c.style.verticalAlign=G(-m.depth))}return m}function Mt(e){return new B(e)}class zt{constructor(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}setAttribute(e,t){this.attributes[e]=t}getAttribute(e){return this.attributes[e]}toNode(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=U(this.classes));for(var r=0;r0&&(e+=' class ="'+m.escape(U(this.classes))+'"'),e+=">";for(var r=0;r"}toText(){return this.children.map((e=>e.toText())).join("")}}class At{constructor(e){this.text=void 0,this.text=e}toNode(){return document.createTextNode(this.text)}toMarkup(){return m.escape(this.toText())}toText(){return this.text}}var Tt={MathNode:zt,TextNode:At,SpaceNode:class{constructor(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?"\u200a":e>=.1666&&e<=.1667?"\u2009":e>=.2222&&e<=.2223?"\u2005":e>=.2777&&e<=.2778?"\u2005\u200a":e>=-.05556&&e<=-.05555?"\u200a\u2063":e>=-.1667&&e<=-.1666?"\u2009\u2063":e>=-.2223&&e<=-.2222?"\u205f\u2063":e>=-.2778&&e<=-.2777?"\u2005\u2063":null}toNode(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",G(this.width)),e}toMarkup(){return this.character?""+this.character+"":''}toText(){return this.character?this.character:" "}},newDocumentFragment:Mt},Bt=function(e,t,r){return!ne[t][e]||!ne[t][e].replace||55349===e.charCodeAt(0)||we.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.slice(4,6)||r.font&&"tt"===r.font.slice(4,6))||(e=ne[t][e].replace),new Tt.TextNode(e)},Ct=function(e){return 1===e.length?e[0]:new Tt.MathNode("mrow",e)},Nt=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";var r=t.font;if(!r||"mathnormal"===r)return null;var a=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var n=e.text;return m.contains(["\\imath","\\jmath"],n)?null:(ne[a][n]&&ne[a][n].replace&&(n=ne[a][n].replace),I(n,Ke.fontMap[r].fontName,a)?Ke.fontMap[r].variant:null)},qt=function(e,t,r){if(1===e.length){var a=Rt(e[0],t);return r&&a instanceof zt&&"mo"===a.type&&(a.setAttribute("lspace","0em"),a.setAttribute("rspace","0em")),[a]}for(var n,i=[],o=0;o0&&(m.text=m.text.slice(0,1)+"\u0338"+m.text.slice(1),i.pop())}}}i.push(s),n=s}return i},It=function(e,t,r){return Ct(qt(e,t,r))},Rt=function(e,t){if(!e)return new Tt.MathNode("mrow");if(it[e.type])return it[e.type](e,t);throw new i("Got group of unknown type: '"+e.type+"'")};function Ht(e,t,r,a,n){var i,o=qt(e,r);i=1===o.length&&o[0]instanceof zt&&m.contains(["mrow","mtable"],o[0].type)?o[0]:new Tt.MathNode("mrow",o);var s=new Tt.MathNode("annotation",[new Tt.TextNode(t)]);s.setAttribute("encoding","application/x-tex");var l=new Tt.MathNode("semantics",[i,s]),h=new Tt.MathNode("math",[l]);h.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),a&&h.setAttribute("display","block");var c=n?"katex":"katex-mathml";return Ke.makeSpan([c],[h])}var Ot=function(e){return new L({style:e.displayMode?k.DISPLAY:k.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},Et=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=Ke.makeSpan(r,[e])}return e},Lt={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},Dt={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Vt=function(e,t,r,a,n){var i,o=e.height+e.depth+r+a;if(/fbox|color|angl/.test(t)){if(i=Ke.makeSpan(["stretchy",t],[],n),"fbox"===t){var s=n.color&&n.getColor();s&&(i.style.borderColor=s)}}else{var l=[];/^[bx]cancel$/.test(t)&&l.push(new ee({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&l.push(new ee({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var h=new J(l,{width:"100%",height:G(o)});i=Ke.makeSvgSpan([],[h],n)}return i.height=o,i.style.height=G(o),i},Pt=function(e){var t=new Tt.MathNode("mo",[new Tt.TextNode(Lt[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},Ft=function(e,t){var{span:r,minWidth:a,height:n}=function(){var r=4e5,a=e.label.slice(1);if(m.contains(["widehat","widecheck","widetilde","utilde"],a)){var n,i,o,s="ordgroup"===(d=e.base).type?d.body.length:1;if(s>5)"widehat"===a||"widecheck"===a?(n=420,r=2364,o=.42,i=a+"4"):(n=312,r=2340,o=.34,i="tilde4");else{var l=[1,1,2,2,3,3][s];"widehat"===a||"widecheck"===a?(r=[0,1062,2364,2364,2364][l],n=[0,239,300,360,420][l],o=[0,.24,.3,.3,.36,.42][l],i=a+l):(r=[0,600,1033,2339,2340][l],n=[0,260,286,306,312][l],o=[0,.26,.286,.3,.306,.34][l],i="tilde"+l)}var h=new Q(i),c=new J([h],{width:"100%",height:G(o),viewBox:"0 0 "+r+" "+n,preserveAspectRatio:"none"});return{span:Ke.makeSvgSpan([],[c],t),minWidth:0,height:o}}var p,u,d,g=[],f=Dt[a],[v,b,y]=f,x=y/1e3,w=v.length;if(1===w)p=["hide-tail"],u=[f[3]];else if(2===w)p=["halfarrow-left","halfarrow-right"],u=["xMinYMin","xMaxYMin"];else{if(3!==w)throw new Error("Correct katexImagesData or update code here to support\n "+w+" children.");p=["brace-left","brace-center","brace-right"],u=["xMinYMin","xMidYMin","xMaxYMin"]}for(var k=0;k0&&(r.style.minWidth=G(a)),r};function Gt(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Ut(e){var t=Yt(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Yt(e){return e&&("atom"===e.type||ae.hasOwnProperty(e.type))?e:null}var Xt=(e,t)=>{var r,a,n;e&&"supsub"===e.type?(r=(a=Gt(e.base,"accent")).base,e.base=r,n=function(e){if(e instanceof _)return e;throw new Error("Expected span but got "+String(e)+".")}(wt(e,t)),e.base=a):r=(a=Gt(e,"accent")).base;var i=wt(r,t.havingCrampedStyle()),o=0;if(a.isShifty&&m.isCharacterBox(r)){var s=m.getBaseElem(r);o=te(wt(s,t.havingCrampedStyle())).skew}var l,h="\\c"===a.label,c=h?i.height+i.depth:Math.min(i.height,t.fontMetrics().xHeight);if(a.isStretchy)l=Ft(a,t),l=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:l,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+G(2*o)+")",marginLeft:G(2*o)}:void 0}]},t);else{var p,u;"\\vec"===a.label?(p=Ke.staticSvg("vec",t),u=Ke.svgData.vec[1]):((p=te(p=Ke.makeOrd({mode:a.mode,text:a.label},t,"textord"))).italic=0,u=p.width,h&&(c+=p.depth)),l=Ke.makeSpan(["accent-body"],[p]);var d="\\textcircled"===a.label;d&&(l.classes.push("accent-full"),c=i.height);var g=o;d||(g-=u/2),l.style.left=G(g),"\\textcircled"===a.label&&(l.style.top=".2em"),l=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-c},{type:"elem",elem:l}]},t)}var f=Ke.makeSpan(["mord","accent"],[l],t);return n?(n.children[0]=f,n.height=Math.max(f.height,n.height),n.classes[0]="mord",n):f},Wt=(e,t)=>{var r=e.isStretchy?Pt(e.label):new Tt.MathNode("mo",[Bt(e.label,e.mode)]),a=new Tt.MathNode("mover",[Rt(e.base,t),r]);return a.setAttribute("accent","true"),a},_t=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map((e=>"\\"+e)).join("|"));ot({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:(e,t)=>{var r=lt(t[0]),a=!_t.test(e.funcName),n=!a||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:a,isShifty:n,base:r}},htmlBuilder:Xt,mathmlBuilder:Wt}),ot({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:(e,t)=>{var r=t[0],a=e.parser.mode;return"math"===a&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),a="text"),{type:"accent",mode:a,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Xt,mathmlBuilder:Wt}),ot({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0];return{type:"accentUnder",mode:r.mode,label:a,base:n}},htmlBuilder:(e,t)=>{var r=wt(e.base,t),a=Ft(e,t),n="\\utilde"===e.label?.12:0,i=Ke.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:a,wrapperClasses:["svg-align"]},{type:"kern",size:n},{type:"elem",elem:r}]},t);return Ke.makeSpan(["mord","accentunder"],[i],t)},mathmlBuilder:(e,t)=>{var r=Pt(e.label),a=new Tt.MathNode("munder",[Rt(e.base,t),r]);return a.setAttribute("accentunder","true"),a}});var jt=e=>{var t=new Tt.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};ot({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){var{parser:a,funcName:n}=e;return{type:"xArrow",mode:a.mode,label:n,body:t[0],below:r[0]}},htmlBuilder(e,t){var r,a=t.style,n=t.havingStyle(a.sup()),i=Ke.wrapFragment(wt(e.body,n,t),t),o="\\x"===e.label.slice(0,2)?"x":"cd";i.classes.push(o+"-arrow-pad"),e.below&&(n=t.havingStyle(a.sub()),(r=Ke.wrapFragment(wt(e.below,n,t),t)).classes.push(o+"-arrow-pad"));var s,l=Ft(e,t),h=-t.fontMetrics().axisHeight+.5*l.height,m=-t.fontMetrics().axisHeight-.5*l.height-.111;if((i.depth>.25||"\\xleftequilibrium"===e.label)&&(m-=i.depth),r){var c=-t.fontMetrics().axisHeight+r.height+.5*l.height+.111;s=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h},{type:"elem",elem:r,shift:c}]},t)}else s=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h}]},t);return s.children[0].children[0].children[1].classes.push("svg-align"),Ke.makeSpan(["mrel","x-arrow"],[s],t)},mathmlBuilder(e,t){var r,a=Pt(e.label);if(a.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){var n=jt(Rt(e.body,t));if(e.below){var i=jt(Rt(e.below,t));r=new Tt.MathNode("munderover",[a,i,n])}else r=new Tt.MathNode("mover",[a,n])}else if(e.below){var o=jt(Rt(e.below,t));r=new Tt.MathNode("munder",[a,o])}else r=jt(),r=new Tt.MathNode("mover",[a,r]);return r}});var $t=Ke.makeSpan;function Zt(e,t){var r=gt(e.body,t,!0);return $t([e.mclass],r,t)}function Kt(e,t){var r,a=qt(e.body,t);return"minner"===e.mclass?r=new Tt.MathNode("mpadded",a):"mord"===e.mclass?e.isCharacterBox?(r=a[0]).type="mi":r=new Tt.MathNode("mi",a):(e.isCharacterBox?(r=a[0]).type="mo":r=new Tt.MathNode("mo",a),"mbin"===e.mclass?(r.attributes.lspace="0.22em",r.attributes.rspace="0.22em"):"mpunct"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0.17em"):"mopen"===e.mclass||"mclose"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0em"):"minner"===e.mclass&&(r.attributes.lspace="0.0556em",r.attributes.width="+0.1111em")),r}ot({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];return{type:"mclass",mode:r.mode,mclass:"m"+a.slice(5),body:ht(n),isCharacterBox:m.isCharacterBox(n)}},htmlBuilder:Zt,mathmlBuilder:Kt});var Jt=e=>{var t="ordgroup"===e.type&&e.body.length?e.body[0]:e;return"atom"!==t.type||"bin"!==t.family&&"rel"!==t.family?"mord":"m"+t.family};ot({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(e,t){var{parser:r}=e;return{type:"mclass",mode:r.mode,mclass:Jt(t[0]),body:ht(t[1]),isCharacterBox:m.isCharacterBox(t[1])}}}),ot({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(e,t){var r,{parser:a,funcName:n}=e,i=t[1],o=t[0];r="\\stackrel"!==n?Jt(i):"mrel";var s={type:"op",mode:i.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:"\\stackrel"!==n,body:ht(i)},l={type:"supsub",mode:o.mode,base:s,sup:"\\underset"===n?null:o,sub:"\\underset"===n?o:null};return{type:"mclass",mode:a.mode,mclass:r,body:[l],isCharacterBox:m.isCharacterBox(l)}},htmlBuilder:Zt,mathmlBuilder:Kt}),ot({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"pmb",mode:r.mode,mclass:Jt(t[0]),body:ht(t[0])}},htmlBuilder(e,t){var r=gt(e.body,t,!0),a=Ke.makeSpan([e.mclass],r,t);return a.style.textShadow="0.02em 0.01em 0.04px",a},mathmlBuilder(e,t){var r=qt(e.body,t),a=new Tt.MathNode("mstyle",r);return a.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),a}});var Qt={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},er=e=>"textord"===e.type&&"@"===e.text;function tr(e,t,r){var a=Qt[e];switch(a){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(a,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":var n={type:"atom",text:a,mode:"math",family:"rel"},i={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[n],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[i],[]);case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":return r.callFunction("\\Big",[{type:"textord",text:"\\Vert",mode:"math"}],[]);default:return{type:"textord",text:" ",mode:"math"}}}ot({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:a}=e;return{type:"cdlabel",mode:r.mode,side:a.slice(4),label:t[0]}},htmlBuilder(e,t){var r=t.havingStyle(t.style.sup()),a=Ke.wrapFragment(wt(e.label,r,t),t);return a.classes.push("cd-label-"+e.side),a.style.bottom=G(.8-a.depth),a.height=0,a.depth=0,a},mathmlBuilder(e,t){var r=new Tt.MathNode("mrow",[Rt(e.label,t)]);return(r=new Tt.MathNode("mpadded",[r])).setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),(r=new Tt.MathNode("mstyle",[r])).setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),ot({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(e,t){var{parser:r}=e;return{type:"cdlabelparent",mode:r.mode,fragment:t[0]}},htmlBuilder(e,t){var r=Ke.wrapFragment(wt(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder:(e,t)=>new Tt.MathNode("mrow",[Rt(e.fragment,t)])}),ot({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(e,t){for(var{parser:r}=e,a=Gt(t[0],"ordgroup").body,n="",o=0;o=1114111)throw new i("\\@char with invalid code point "+n);return l<=65535?s=String.fromCharCode(l):(l-=65536,s=String.fromCharCode(55296+(l>>10),56320+(1023&l))),{type:"textord",mode:r.mode,text:s}}});var rr=(e,t)=>{var r=gt(e.body,t.withColor(e.color),!1);return Ke.makeFragment(r)},ar=(e,t)=>{var r=qt(e.body,t.withColor(e.color)),a=new Tt.MathNode("mstyle",r);return a.setAttribute("mathcolor",e.color),a};ot({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(e,t){var{parser:r}=e,a=Gt(t[0],"color-token").color,n=t[1];return{type:"color",mode:r.mode,color:a,body:ht(n)}},htmlBuilder:rr,mathmlBuilder:ar}),ot({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(e,t){var{parser:r,breakOnTokenText:a}=e,n=Gt(t[0],"color-token").color;r.gullet.macros.set("\\current@color",n);var i=r.parseExpression(!0,a);return{type:"color",mode:r.mode,color:n,body:i}},htmlBuilder:rr,mathmlBuilder:ar}),ot({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(e,t,r){var{parser:a}=e,n="["===a.gullet.future().text?a.parseSizeGroup(!0):null,i=!a.settings.displayMode||!a.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:a.mode,newLine:i,size:n&&Gt(n,"size").value}},htmlBuilder(e,t){var r=Ke.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=G(F(e.size,t)))),r},mathmlBuilder(e,t){var r=new Tt.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",G(F(e.size,t)))),r}});var nr={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},ir=e=>{var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new i("Expected a control sequence",e);return t},or=(e,t,r,a)=>{var n=e.gullet.macros.get(r.text);null==n&&(r.noexpand=!0,n={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,n,a)};ot({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(e){var{parser:t,funcName:r}=e;t.consumeSpaces();var a=t.fetch();if(nr[a.text])return"\\global"!==r&&"\\\\globallong"!==r||(a.text=nr[a.text]),Gt(t.parseFunction(),"internal");throw new i("Invalid token after macro prefix",a)}}),ot({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,a=t.gullet.popToken(),n=a.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(n))throw new i("Expected a control sequence",a);for(var o,s=0,l=[[]];"{"!==t.gullet.future().text;)if("#"===(a=t.gullet.popToken()).text){if("{"===t.gullet.future().text){o=t.gullet.future(),l[s].push("{");break}if(a=t.gullet.popToken(),!/^[1-9]$/.test(a.text))throw new i('Invalid argument number "'+a.text+'"');if(parseInt(a.text)!==s+1)throw new i('Argument number "'+a.text+'" out of order');s++,l.push([])}else{if("EOF"===a.text)throw new i("Expected a macro definition");l[s].push(a.text)}var{tokens:h}=t.gullet.consumeArg();return o&&h.unshift(o),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h)).reverse(),t.gullet.macros.set(n,{tokens:h,numArgs:s,delimiters:l},r===nr[r]),{type:"internal",mode:t.mode}}}),ot({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,a=ir(t.gullet.popToken());t.gullet.consumeSpaces();var n=(e=>{var t=e.gullet.popToken();return"="===t.text&&" "===(t=e.gullet.popToken()).text&&(t=e.gullet.popToken()),t})(t);return or(t,a,n,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),ot({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,a=ir(t.gullet.popToken()),n=t.gullet.popToken(),i=t.gullet.popToken();return or(t,a,i,"\\\\globalfuture"===r),t.gullet.pushToken(i),t.gullet.pushToken(n),{type:"internal",mode:t.mode}}});var sr=function(e,t,r){var a=I(ne.math[e]&&ne.math[e].replace||e,t,r);if(!a)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return a},lr=function(e,t,r,a){var n=r.havingBaseStyle(t),i=Ke.makeSpan(a.concat(n.sizingClasses(r)),[e],r),o=n.sizeMultiplier/r.sizeMultiplier;return i.height*=o,i.depth*=o,i.maxFontSize=n.sizeMultiplier,i},hr=function(e,t,r){var a=t.havingBaseStyle(r),n=(1-t.sizeMultiplier/a.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=G(n),e.height-=n,e.depth+=n},mr=function(e,t,r,a,n,i){var o=function(e,t,r,a){return Ke.makeSymbol(e,"Size"+t+"-Regular",r,a)}(e,t,n,a),s=lr(Ke.makeSpan(["delimsizing","size"+t],[o],a),k.TEXT,a,i);return r&&hr(s,a,k.TEXT),s},cr=function(e,t,r){var a;return a="Size1-Regular"===t?"delim-size1":"delim-size4",{type:"elem",elem:Ke.makeSpan(["delimsizinginner",a],[Ke.makeSpan([],[Ke.makeSymbol(e,t,r)])])}},pr=function(e,t,r){var a=C["Size4-Regular"][e.charCodeAt(0)]?C["Size4-Regular"][e.charCodeAt(0)][4]:C["Size1-Regular"][e.charCodeAt(0)][4],n=new Q("inner",function(e,t){switch(e){case"\u239c":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"\u239f":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23a2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23a5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23aa":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23d0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),i=new J([n],{width:G(a),height:G(t),style:"width:"+G(a),viewBox:"0 0 "+1e3*a+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=Ke.makeSvgSpan([],[i],r);return o.height=t,o.style.height=G(t),o.style.width=G(a),{type:"elem",elem:o}},ur={type:"kern",size:-.008},dr=["|","\\lvert","\\rvert","\\vert"],gr=["\\|","\\lVert","\\rVert","\\Vert"],fr=function(e,t,r,a,n,i){var o,s,l,h,c="",p=0;o=l=h=e,s=null;var u="Size1-Regular";"\\uparrow"===e?l=h="\u23d0":"\\Uparrow"===e?l=h="\u2016":"\\downarrow"===e?o=l="\u23d0":"\\Downarrow"===e?o=l="\u2016":"\\updownarrow"===e?(o="\\uparrow",l="\u23d0",h="\\downarrow"):"\\Updownarrow"===e?(o="\\Uparrow",l="\u2016",h="\\Downarrow"):m.contains(dr,e)?(l="\u2223",c="vert",p=333):m.contains(gr,e)?(l="\u2225",c="doublevert",p=556):"["===e||"\\lbrack"===e?(o="\u23a1",l="\u23a2",h="\u23a3",u="Size4-Regular",c="lbrack",p=667):"]"===e||"\\rbrack"===e?(o="\u23a4",l="\u23a5",h="\u23a6",u="Size4-Regular",c="rbrack",p=667):"\\lfloor"===e||"\u230a"===e?(l=o="\u23a2",h="\u23a3",u="Size4-Regular",c="lfloor",p=667):"\\lceil"===e||"\u2308"===e?(o="\u23a1",l=h="\u23a2",u="Size4-Regular",c="lceil",p=667):"\\rfloor"===e||"\u230b"===e?(l=o="\u23a5",h="\u23a6",u="Size4-Regular",c="rfloor",p=667):"\\rceil"===e||"\u2309"===e?(o="\u23a4",l=h="\u23a5",u="Size4-Regular",c="rceil",p=667):"("===e||"\\lparen"===e?(o="\u239b",l="\u239c",h="\u239d",u="Size4-Regular",c="lparen",p=875):")"===e||"\\rparen"===e?(o="\u239e",l="\u239f",h="\u23a0",u="Size4-Regular",c="rparen",p=875):"\\{"===e||"\\lbrace"===e?(o="\u23a7",s="\u23a8",h="\u23a9",l="\u23aa",u="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(o="\u23ab",s="\u23ac",h="\u23ad",l="\u23aa",u="Size4-Regular"):"\\lgroup"===e||"\u27ee"===e?(o="\u23a7",h="\u23a9",l="\u23aa",u="Size4-Regular"):"\\rgroup"===e||"\u27ef"===e?(o="\u23ab",h="\u23ad",l="\u23aa",u="Size4-Regular"):"\\lmoustache"===e||"\u23b0"===e?(o="\u23a7",h="\u23ad",l="\u23aa",u="Size4-Regular"):"\\rmoustache"!==e&&"\u23b1"!==e||(o="\u23ab",h="\u23a9",l="\u23aa",u="Size4-Regular");var d=sr(o,u,n),g=d.height+d.depth,f=sr(l,u,n),v=f.height+f.depth,b=sr(h,u,n),y=b.height+b.depth,x=0,w=1;if(null!==s){var S=sr(s,u,n);x=S.height+S.depth,w=2}var M=g+y+x,z=M+Math.max(0,Math.ceil((t-M)/(w*v)))*w*v,A=a.fontMetrics().axisHeight;r&&(A*=a.sizeMultiplier);var T=z/2-A,B=[];if(c.length>0){var C=z-g-y,N=Math.round(1e3*z),q=function(e,t){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v1759 h347 v-84\nH403z M403 1759 V0 H319 V1759 v"+t+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v1759 H0 v84 H347z\nM347 1759 V0 H263 V1759 v"+t+" v1759 h84z";case"vert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z";case"doublevert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z\nM367 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M410 15 H367 v585 v"+t+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+t+" v1715 h263 v84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+t+" v1799 H0 v-84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v602 h84z\nM403 1759 V0 H319 V1759 v"+t+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v602 h84z\nM347 1759 V0 h-84 V1759 v"+t+" v602 h84z";case"lparen":return"M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1\nc-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349,\n-36,557 l0,"+(t+84)+"c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210,\n949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9\nc0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5,\n-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189\nl0,-"+(t+92)+"c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3,\n-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z";case"rparen":return"M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3,\n63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5\nc11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0,"+(t+9)+"\nc-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664\nc-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11\nc0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17\nc242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558\nl0,-"+(t+144)+"c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,\n-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z";default:throw new Error("Unknown stretchy delimiter.")}}(c,Math.round(1e3*C)),I=new Q(c,q),R=(p/1e3).toFixed(3)+"em",H=(N/1e3).toFixed(3)+"em",O=new J([I],{width:R,height:H,viewBox:"0 0 "+p+" "+N}),E=Ke.makeSvgSpan([],[O],a);E.height=N/1e3,E.style.width=R,E.style.height=H,B.push({type:"elem",elem:E})}else{if(B.push(cr(h,u,n)),B.push(ur),null===s){var L=z-g-y+.016;B.push(pr(l,L,a))}else{var D=(z-g-y-x)/2+.016;B.push(pr(l,D,a)),B.push(ur),B.push(cr(s,u,n)),B.push(ur),B.push(pr(l,D,a))}B.push(ur),B.push(cr(o,u,n))}var V=a.havingBaseStyle(k.TEXT),P=Ke.makeVList({positionType:"bottom",positionData:T,children:B},V);return lr(Ke.makeSpan(["delimsizing","mult"],[P],V),k.TEXT,a,i)},vr=.08,br=function(e,t,r,a,n){var i=function(e,t,r){t*=1e3;var a="";switch(e){case"sqrtMain":a=function(e,t){return"M95,"+(622+e+t)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize1":a=function(e,t){return"M263,"+(601+e+t)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize2":a=function(e,t){return"M983 "+(10+e+t)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize3":a=function(e,t){return"M424,"+(2398+e+t)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" "+t+"\nh400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize4":a=function(e,t){return"M473,"+(2713+e+t)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"}(t,A);break;case"sqrtTall":a=function(e,t,r){return"M702 "+(e+t)+"H400000"+(40+e)+"\nH742v"+(r-54-t-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+t+"H400000v"+(40+e)+"H742z"}(t,A,r)}return a}(e,a,r),o=new Q(e,i),s=new J([o],{width:"400em",height:G(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return Ke.makeSvgSpan(["hide-tail"],[s],n)},yr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],xr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],wr=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],kr=[0,1.2,1.8,2.4,3],Sr=[{type:"small",style:k.SCRIPTSCRIPT},{type:"small",style:k.SCRIPT},{type:"small",style:k.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],Mr=[{type:"small",style:k.SCRIPTSCRIPT},{type:"small",style:k.SCRIPT},{type:"small",style:k.TEXT},{type:"stack"}],zr=[{type:"small",style:k.SCRIPTSCRIPT},{type:"small",style:k.SCRIPT},{type:"small",style:k.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],Ar=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},Tr=function(e,t,r,a){for(var n=Math.min(2,3-a.style.size);nt)return r[n]}return r[r.length-1]},Br=function(e,t,r,a,n,i){var o;"<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),o=m.contains(wr,e)?Sr:m.contains(yr,e)?zr:Mr;var s=Tr(e,t,o,a);return"small"===s.type?function(e,t,r,a,n,i){var o=Ke.makeSymbol(e,"Main-Regular",n,a),s=lr(o,t,a,i);return r&&hr(s,a,t),s}(e,s.style,r,a,n,i):"large"===s.type?mr(e,s.size,r,a,n,i):fr(e,t,r,a,n,i)},Cr={sqrtImage:function(e,t){var r,a,n=t.havingBaseSizing(),i=Tr("\\surd",e*n.sizeMultiplier,zr,n),o=n.sizeMultiplier,s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),l=0,h=0,m=0;return"small"===i.type?(e<1?o=1:e<1.4&&(o=.7),h=(1+s)/o,(r=br("sqrtMain",l=(1+s+vr)/o,m=1e3+1e3*s+80,s,t)).style.minWidth="0.853em",a=.833/o):"large"===i.type?(m=1080*kr[i.size],h=(kr[i.size]+s)/o,l=(kr[i.size]+s+vr)/o,(r=br("sqrtSize"+i.size,l,m,s,t)).style.minWidth="1.02em",a=1/o):(l=e+s+vr,h=e+s,m=Math.floor(1e3*e+s)+80,(r=br("sqrtTall",l,m,s,t)).style.minWidth="0.742em",a=1.056),r.height=h,r.style.height=G(l),{span:r,advanceWidth:a,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,a,n){if("<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),m.contains(yr,e)||m.contains(wr,e))return mr(e,t,!1,r,a,n);if(m.contains(xr,e))return fr(e,kr[t],!1,r,a,n);throw new i("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:kr,customSizedDelim:Br,leftRightDelim:function(e,t,r,a,n,i){var o=a.fontMetrics().axisHeight*a.sizeMultiplier,s=5/a.fontMetrics().ptPerEm,l=Math.max(t-o,r+o),h=Math.max(l/500*901,2*l-s);return Br(e,h,!0,a,n,i)}},Nr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},qr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Ir(e,t){var r=Yt(e);if(r&&m.contains(qr,r.text))return r;throw new i(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function Rr(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}ot({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:(e,t)=>{var r=Ir(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:Nr[e.funcName].size,mclass:Nr[e.funcName].mclass,delim:r.text}},htmlBuilder:(e,t)=>"."===e.delim?Ke.makeSpan([e.mclass]):Cr.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass]),mathmlBuilder:e=>{var t=[];"."!==e.delim&&t.push(Bt(e.delim,e.mode));var r=new Tt.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var a=G(Cr.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",a),r.setAttribute("maxsize",a),r}}),ot({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new i("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Ir(t[0],e).text,color:r}}}),ot({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=Ir(t[0],e),a=e.parser;++a.leftrightDepth;var n=a.parseExpression(!1);--a.leftrightDepth,a.expect("\\right",!1);var i=Gt(a.parseFunction(),"leftright-right");return{type:"leftright",mode:a.mode,body:n,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:(e,t)=>{Rr(e);for(var r,a,n=gt(e.body,t,!0,["mopen","mclose"]),i=0,o=0,s=!1,l=0;l{Rr(e);var r=qt(e.body,t);if("."!==e.left){var a=new Tt.MathNode("mo",[Bt(e.left,e.mode)]);a.setAttribute("fence","true"),r.unshift(a)}if("."!==e.right){var n=new Tt.MathNode("mo",[Bt(e.right,e.mode)]);n.setAttribute("fence","true"),e.rightColor&&n.setAttribute("mathcolor",e.rightColor),r.push(n)}return Ct(r)}}),ot({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=Ir(t[0],e);if(!e.parser.leftrightDepth)throw new i("\\middle without preceding \\left",r);return{type:"middle",mode:e.parser.mode,delim:r.text}},htmlBuilder:(e,t)=>{var r;if("."===e.delim)r=xt(t,[]);else{r=Cr.sizedDelim(e.delim,1,t,e.mode,[]);var a={delim:e.delim,options:t};r.isMiddle=a}return r},mathmlBuilder:(e,t)=>{var r="\\vert"===e.delim||"|"===e.delim?Bt("|","text"):Bt(e.delim,e.mode),a=new Tt.MathNode("mo",[r]);return a.setAttribute("fence","true"),a.setAttribute("lspace","0.05em"),a.setAttribute("rspace","0.05em"),a}});var Hr=(e,t)=>{var r,a,n,i=Ke.wrapFragment(wt(e.body,t),t),o=e.label.slice(1),s=t.sizeMultiplier,l=0,h=m.isCharacterBox(e.body);if("sout"===o)(r=Ke.makeSpan(["stretchy","sout"])).height=t.fontMetrics().defaultRuleThickness/s,l=-.5*t.fontMetrics().xHeight;else if("phase"===o){var c=F({number:.6,unit:"pt"},t),p=F({number:.35,unit:"ex"},t);s/=t.havingBaseSizing().sizeMultiplier;var u=i.height+i.depth+c+p;i.style.paddingLeft=G(u/2+c);var d=Math.floor(1e3*u*s),g="M400000 "+(a=d)+" H0 L"+a/2+" 0 l65 45 L145 "+(a-80)+" H400000z",f=new J([new Q("phase",g)],{width:"400em",height:G(d/1e3),viewBox:"0 0 400000 "+d,preserveAspectRatio:"xMinYMin slice"});(r=Ke.makeSvgSpan(["hide-tail"],[f],t)).style.height=G(u),l=i.depth+c+p}else{/cancel/.test(o)?h||i.classes.push("cancel-pad"):"angl"===o?i.classes.push("anglpad"):i.classes.push("boxpad");var v=0,b=0,y=0;/box/.test(o)?(y=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness),b=v=t.fontMetrics().fboxsep+("colorbox"===o?0:y)):"angl"===o?(v=4*(y=Math.max(t.fontMetrics().defaultRuleThickness,t.minRuleThickness)),b=Math.max(0,.25-i.depth)):b=v=h?.2:0,r=Vt(i,o,v,b,t),/fbox|boxed|fcolorbox/.test(o)?(r.style.borderStyle="solid",r.style.borderWidth=G(y)):"angl"===o&&.049!==y&&(r.style.borderTopWidth=G(y),r.style.borderRightWidth=G(y)),l=i.depth+b,e.backgroundColor&&(r.style.backgroundColor=e.backgroundColor,e.borderColor&&(r.style.borderColor=e.borderColor))}if(e.backgroundColor)n=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:r,shift:l},{type:"elem",elem:i,shift:0}]},t);else{var x=/cancel|phase/.test(o)?["svg-align"]:[];n=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:0},{type:"elem",elem:r,shift:l,wrapperClasses:x}]},t)}return/cancel/.test(o)&&(n.height=i.height,n.depth=i.depth),/cancel/.test(o)&&!h?Ke.makeSpan(["mord","cancel-lap"],[n],t):Ke.makeSpan(["mord"],[n],t)},Or=(e,t)=>{var r=0,a=new Tt.MathNode(e.label.indexOf("colorbox")>-1?"mpadded":"menclose",[Rt(e.body,t)]);switch(e.label){case"\\cancel":a.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":a.setAttribute("notation","downdiagonalstrike");break;case"\\phase":a.setAttribute("notation","phasorangle");break;case"\\sout":a.setAttribute("notation","horizontalstrike");break;case"\\fbox":a.setAttribute("notation","box");break;case"\\angl":a.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,a.setAttribute("width","+"+2*r+"pt"),a.setAttribute("height","+"+2*r+"pt"),a.setAttribute("lspace",r+"pt"),a.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){var n=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);a.setAttribute("style","border: "+n+"em solid "+String(e.borderColor))}break;case"\\xcancel":a.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&a.setAttribute("mathbackground",e.backgroundColor),a};ot({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(e,t,r){var{parser:a,funcName:n}=e,i=Gt(t[0],"color-token").color,o=t[1];return{type:"enclose",mode:a.mode,label:n,backgroundColor:i,body:o}},htmlBuilder:Hr,mathmlBuilder:Or}),ot({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(e,t,r){var{parser:a,funcName:n}=e,i=Gt(t[0],"color-token").color,o=Gt(t[1],"color-token").color,s=t[2];return{type:"enclose",mode:a.mode,label:n,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:Hr,mathmlBuilder:Or}),ot({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\fbox",body:t[0]}}}),ot({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];return{type:"enclose",mode:r.mode,label:a,body:n}},htmlBuilder:Hr,mathmlBuilder:Or}),ot({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(e,t){var{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\angl",body:t[0]}}});var Er={};function Lr(e){for(var{type:t,names:r,props:a,handler:n,htmlBuilder:i,mathmlBuilder:o}=e,s={type:t,numArgs:a.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:n},l=0;l{if(!e.parser.settings.displayMode)throw new i("{"+e.envName+"} can be used only in display mode.")};function Gr(e){if(-1===e.indexOf("ed"))return-1===e.indexOf("*")}function Ur(e,t,r){var{hskipBeforeAndAfter:a,addJot:o,cols:s,arraystretch:l,colSeparationType:h,autoTag:m,singleRow:c,emptySingleRow:p,maxNumCols:u,leqno:d}=t;if(e.gullet.beginGroup(),c||e.gullet.macros.set("\\cr","\\\\\\relax"),!l){var g=e.gullet.expandMacroAsText("\\arraystretch");if(null==g)l=1;else if(!(l=parseFloat(g))||l<0)throw new i("Invalid \\arraystretch: "+g)}e.gullet.beginGroup();var f=[],v=[f],b=[],y=[],x=null!=m?[]:void 0;function w(){m&&e.gullet.macros.set("\\@eqnsw","1",!0)}function k(){x&&(e.gullet.macros.get("\\df@tag")?(x.push(e.subparse([new n("\\df@tag")])),e.gullet.macros.set("\\df@tag",void 0,!0)):x.push(Boolean(m)&&"1"===e.gullet.macros.get("\\@eqnsw")))}for(w(),y.push(Pr(e));;){var S=e.parseExpression(!1,c?"\\end":"\\\\");e.gullet.endGroup(),e.gullet.beginGroup(),S={type:"ordgroup",mode:e.mode,body:S},r&&(S={type:"styling",mode:e.mode,style:r,body:[S]}),f.push(S);var M=e.fetch().text;if("&"===M){if(u&&f.length===u){if(c||h)throw new i("Too many tab characters: &",e.nextToken);e.settings.reportNonstrict("textEnv","Too few columns specified in the {array} column argument.")}e.consume()}else{if("\\end"===M){k(),1===f.length&&"styling"===S.type&&0===S.body[0].body.length&&(v.length>1||!p)&&v.pop(),y.length0&&(y+=.25),h.push({pos:y,isDashed:e[t]})}for(x(o[0]),r=0;r0&&(M<(B+=b)&&(M=B),B=0),e.addJot&&(M+=g),z.height=S,z.depth=M,y+=S,z.pos=y,y+=M+B,l[r]=z,x(o[r+1])}var C,N,q=y/2+t.fontMetrics().axisHeight,I=e.cols||[],R=[],H=[];if(e.tags&&e.tags.some((e=>e)))for(r=0;r=s)){var W=void 0;(a>0||e.hskipBeforeAndAfter)&&0!==(W=m.deflt(V.pregap,u))&&((C=Ke.makeSpan(["arraycolsep"],[])).style.width=G(W),R.push(C));var _=[];for(r=0;r0){for(var K=Ke.makeLineSpan("hline",t,c),J=Ke.makeLineSpan("hdashline",t,c),Q=[{type:"elem",elem:l,shift:0}];h.length>0;){var ee=h.pop(),te=ee.pos-q;ee.isDashed?Q.push({type:"elem",elem:J,shift:te}):Q.push({type:"elem",elem:K,shift:te})}l=Ke.makeVList({positionType:"individualShift",children:Q},t)}if(0===H.length)return Ke.makeSpan(["mord"],[l],t);var re=Ke.makeVList({positionType:"individualShift",children:H},t);return re=Ke.makeSpan(["tag"],[re],t),Ke.makeFragment([l,re])},Wr={c:"center ",l:"left ",r:"right "},_r=function(e,t){for(var r=[],a=new Tt.MathNode("mtd",[],["mtr-glue"]),n=new Tt.MathNode("mtd",[],["mml-eqn-num"]),i=0;i0){var u=e.cols,d="",g=!1,f=0,v=u.length;"separator"===u[0].type&&(c+="top ",f=1),"separator"===u[u.length-1].type&&(c+="bottom ",v-=1);for(var b=f;b0?"left ":"",c+=S[S.length-1].length>0?"right ":"";for(var M=1;M-1?"alignat":"align",o="split"===e.envName,s=Ur(e.parser,{cols:a,addJot:!0,autoTag:o?void 0:Gr(e.envName),emptySingleRow:!0,colSeparationType:n,maxNumCols:o?2:void 0,leqno:e.parser.settings.leqno},"display"),l=0,h={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){for(var m="",c=0;c0&&p&&(g=1),a[u]={type:"align",align:d,pregap:g,postgap:0}}return s.colSeparationType=p?"align":"alignat",s};Lr({type:"array",names:["array","darray"],props:{numArgs:1},handler(e,t){var r=(Yt(t[0])?[t[0]]:Gt(t[0],"ordgroup").body).map((function(e){var t=Ut(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new i("Unknown column alignment: "+t,e)})),a={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return Ur(e.parser,a,Yr(e.envName))},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(e){var t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")],r="c",a={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){var n=e.parser;if(n.consumeSpaces(),"["===n.fetch().text){if(n.consume(),n.consumeSpaces(),r=n.fetch().text,-1==="lcr".indexOf(r))throw new i("Expected l or c or r",n.nextToken);n.consume(),n.consumeSpaces(),n.expect("]"),n.consume(),a.cols=[{type:"align",align:r}]}}var o=Ur(e.parser,a,Yr(e.envName)),s=Math.max(0,...o.body.map((e=>e.length)));return o.cols=new Array(s).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[o],left:t[0],right:t[1],rightColor:void 0}:o},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(e){var t=Ur(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["subarray"],props:{numArgs:1},handler(e,t){var r=(Yt(t[0])?[t[0]]:Gt(t[0],"ordgroup").body).map((function(e){var t=Ut(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new i("Unknown column alignment: "+t,e)}));if(r.length>1)throw new i("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=Ur(e.parser,a,"script")).body.length>0&&a.body[0].length>1)throw new i("{subarray} can contain only one column");return a},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(e){var t=Ur(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},Yr(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:jr,htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(e){m.contains(["gather","gather*"],e.envName)&&Fr(e);var t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:Gr(e.envName),emptySingleRow:!0,leqno:e.parser.settings.leqno};return Ur(e.parser,t,"display")},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:jr,htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(e){Fr(e);var t={autoTag:Gr(e.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Ur(e.parser,t,"display")},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["CD"],props:{numArgs:0},handler:e=>(Fr(e),function(e){var t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();var r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new i("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}for(var a,n,o=[],s=[o],l=0;l-1);else{if(!("<>AV".indexOf(p)>-1))throw new i('Expected one of "<>AV=|." after @',h[c]);for(var d=0;d<2;d++){for(var g=!0,f=c+1;f{var r=e.font,a=t.withFont(r);return wt(e.body,a)},Kr=(e,t)=>{var r=e.font,a=t.withFont(r);return Rt(e.body,a)},Jr={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};ot({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=lt(t[0]),i=a;return i in Jr&&(i=Jr[i]),{type:"font",mode:r.mode,font:i.slice(1),body:n}},htmlBuilder:Zr,mathmlBuilder:Kr}),ot({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:(e,t)=>{var{parser:r}=e,a=t[0],n=m.isCharacterBox(a);return{type:"mclass",mode:r.mode,mclass:Jt(a),body:[{type:"font",mode:r.mode,font:"boldsymbol",body:a}],isCharacterBox:n}}}),ot({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{var{parser:r,funcName:a,breakOnTokenText:n}=e,{mode:i}=r,o=r.parseExpression(!0,n);return{type:"font",mode:i,font:"math"+a.slice(1),body:{type:"ordgroup",mode:r.mode,body:o}}},htmlBuilder:Zr,mathmlBuilder:Kr});var Qr=(e,t)=>{var r=t;return"display"===e?r=r.id>=k.SCRIPT.id?r.text():k.DISPLAY:"text"===e&&r.size===k.DISPLAY.size?r=k.TEXT:"script"===e?r=k.SCRIPT:"scriptscript"===e&&(r=k.SCRIPTSCRIPT),r},ea=(e,t)=>{var r,a=Qr(e.size,t.style),n=a.fracNum(),i=a.fracDen();r=t.havingStyle(n);var o=wt(e.numer,r,t);if(e.continued){var s=8.5/t.fontMetrics().ptPerEm,l=3.5/t.fontMetrics().ptPerEm;o.height=o.height0?3*c:7*c,d=t.fontMetrics().denom1):(m>0?(p=t.fontMetrics().num2,u=c):(p=t.fontMetrics().num3,u=3*c),d=t.fontMetrics().denom2),h){var x=t.fontMetrics().axisHeight;p-o.depth-(x+.5*m){var r=new Tt.MathNode("mfrac",[Rt(e.numer,t),Rt(e.denom,t)]);if(e.hasBarLine){if(e.barSize){var a=F(e.barSize,t);r.setAttribute("linethickness",G(a))}}else r.setAttribute("linethickness","0px");var n=Qr(e.size,t.style);if(n.size!==t.style.size){r=new Tt.MathNode("mstyle",[r]);var i=n.size===k.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",i),r.setAttribute("scriptlevel","0")}if(null!=e.leftDelim||null!=e.rightDelim){var o=[];if(null!=e.leftDelim){var s=new Tt.MathNode("mo",[new Tt.TextNode(e.leftDelim.replace("\\",""))]);s.setAttribute("fence","true"),o.push(s)}if(o.push(r),null!=e.rightDelim){var l=new Tt.MathNode("mo",[new Tt.TextNode(e.rightDelim.replace("\\",""))]);l.setAttribute("fence","true"),o.push(l)}return Ct(o)}return r};ot({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(e,t)=>{var r,{parser:a,funcName:n}=e,i=t[0],o=t[1],s=null,l=null,h="auto";switch(n){case"\\dfrac":case"\\frac":case"\\tfrac":r=!0;break;case"\\\\atopfrac":r=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":r=!1,s="(",l=")";break;case"\\\\bracefrac":r=!1,s="\\{",l="\\}";break;case"\\\\brackfrac":r=!1,s="[",l="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text"}return{type:"genfrac",mode:a.mode,continued:!1,numer:i,denom:o,hasBarLine:r,leftDelim:s,rightDelim:l,size:h,barSize:null}},htmlBuilder:ea,mathmlBuilder:ta}),ot({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0],i=t[1];return{type:"genfrac",mode:r.mode,continued:!0,numer:n,denom:i,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}}),ot({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(e){var t,{parser:r,funcName:a,token:n}=e;switch(a){case"\\over":t="\\frac";break;case"\\choose":t="\\binom";break;case"\\atop":t="\\\\atopfrac";break;case"\\brace":t="\\\\bracefrac";break;case"\\brack":t="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:r.mode,replaceWith:t,token:n}}});var ra=["display","text","script","scriptscript"],aa=function(e){var t=null;return e.length>0&&(t="."===(t=e)?null:t),t};ot({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(e,t){var r,{parser:a}=e,n=t[4],i=t[5],o=lt(t[0]),s="atom"===o.type&&"open"===o.family?aa(o.text):null,l=lt(t[1]),h="atom"===l.type&&"close"===l.family?aa(l.text):null,m=Gt(t[2],"size"),c=null;r=!!m.isBlank||(c=m.value).number>0;var p="auto",u=t[3];if("ordgroup"===u.type){if(u.body.length>0){var d=Gt(u.body[0],"textord");p=ra[Number(d.text)]}}else u=Gt(u,"textord"),p=ra[Number(u.text)];return{type:"genfrac",mode:a.mode,numer:n,denom:i,continued:!1,hasBarLine:r,barSize:c,leftDelim:s,rightDelim:h,size:p}},htmlBuilder:ea,mathmlBuilder:ta}),ot({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(e,t){var{parser:r,funcName:a,token:n}=e;return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Gt(t[0],"size").value,token:n}}}),ot({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0],i=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Gt(t[1],"infix").size),o=t[2],s=i.number>0;return{type:"genfrac",mode:r.mode,numer:n,denom:o,continued:!1,hasBarLine:s,barSize:i,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:ea,mathmlBuilder:ta});var na=(e,t)=>{var r,a,n=t.style;"supsub"===e.type?(r=e.sup?wt(e.sup,t.havingStyle(n.sup()),t):wt(e.sub,t.havingStyle(n.sub()),t),a=Gt(e.base,"horizBrace")):a=Gt(e,"horizBrace");var i,o=wt(a.base,t.havingBaseStyle(k.DISPLAY)),s=Ft(a,t);if(a.isOver?(i=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.1},{type:"elem",elem:s}]},t)).children[0].children[0].children[1].classes.push("svg-align"):(i=Ke.makeVList({positionType:"bottom",positionData:o.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:o}]},t)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=Ke.makeSpan(["mord",a.isOver?"mover":"munder"],[i],t);i=a.isOver?Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},t):Ke.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},t)}return Ke.makeSpan(["mord",a.isOver?"mover":"munder"],[i],t)};ot({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:a}=e;return{type:"horizBrace",mode:r.mode,label:a,isOver:/^\\over/.test(a),base:t[0]}},htmlBuilder:na,mathmlBuilder:(e,t)=>{var r=Pt(e.label);return new Tt.MathNode(e.isOver?"mover":"munder",[Rt(e.base,t),r])}}),ot({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[1],n=Gt(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:n})?{type:"href",mode:r.mode,href:n,body:ht(a)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:(e,t)=>{var r=gt(e.body,t,!1);return Ke.makeAnchor(e.href,[],r,t)},mathmlBuilder:(e,t)=>{var r=It(e.body,t);return r instanceof zt||(r=new zt("mrow",[r])),r.setAttribute("href",e.href),r}}),ot({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=Gt(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:a}))return r.formatUnsupportedCmd("\\url");for(var n=[],i=0;inew Tt.MathNode("mrow",qt(e.body,t))}),ot({type:"html",names:["\\htmlClass","\\htmlId","\\htmlStyle","\\htmlData"],props:{numArgs:2,argTypes:["raw","original"],allowedInText:!0},handler:(e,t)=>{var r,{parser:a,funcName:n,token:o}=e,s=Gt(t[0],"raw").string,l=t[1];a.settings.strict&&a.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var h={};switch(n){case"\\htmlClass":h.class=s,r={command:"\\htmlClass",class:s};break;case"\\htmlId":h.id=s,r={command:"\\htmlId",id:s};break;case"\\htmlStyle":h.style=s,r={command:"\\htmlStyle",style:s};break;case"\\htmlData":for(var m=s.split(","),c=0;c{var r=gt(e.body,t,!1),a=["enclosing"];e.attributes.class&&a.push(...e.attributes.class.trim().split(/\s+/));var n=Ke.makeSpan(a,r,t);for(var i in e.attributes)"class"!==i&&e.attributes.hasOwnProperty(i)&&n.setAttribute(i,e.attributes[i]);return n},mathmlBuilder:(e,t)=>It(e.body,t)}),ot({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e;return{type:"htmlmathml",mode:r.mode,html:ht(t[0]),mathml:ht(t[1])}},htmlBuilder:(e,t)=>{var r=gt(e.html,t,!1);return Ke.makeFragment(r)},mathmlBuilder:(e,t)=>It(e.mathml,t)});var ia=function(e){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(e))return{number:+e,unit:"bp"};var t=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e);if(!t)throw new i("Invalid size: '"+e+"' in \\includegraphics");var r={number:+(t[1]+t[2]),unit:t[3]};if(!P(r))throw new i("Invalid unit: '"+r.unit+"' in \\includegraphics.");return r};ot({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:(e,t,r)=>{var{parser:a}=e,n={number:0,unit:"em"},o={number:.9,unit:"em"},s={number:0,unit:"em"},l="";if(r[0])for(var h=Gt(r[0],"raw").string.split(","),m=0;m{var r=F(e.height,t),a=0;e.totalheight.number>0&&(a=F(e.totalheight,t)-r);var n=0;e.width.number>0&&(n=F(e.width,t));var i={height:G(r+a)};n>0&&(i.width=G(n)),a>0&&(i.verticalAlign=G(-a));var o=new $(e.src,e.alt,i);return o.height=r,o.depth=a,o},mathmlBuilder:(e,t)=>{var r=new Tt.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);var a=F(e.height,t),n=0;if(e.totalheight.number>0&&(n=F(e.totalheight,t)-a,r.setAttribute("valign",G(-n))),r.setAttribute("height",G(a+n)),e.width.number>0){var i=F(e.width,t);r.setAttribute("width",G(i))}return r.setAttribute("src",e.src),r}}),ot({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(e,t){var{parser:r,funcName:a}=e,n=Gt(t[0],"size");if(r.settings.strict){var i="m"===a[1],o="mu"===n.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" supports only mu units, not "+n.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:n.value}},htmlBuilder:(e,t)=>Ke.makeGlue(e.dimension,t),mathmlBuilder(e,t){var r=F(e.dimension,t);return new Tt.SpaceNode(r)}}),ot({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0];return{type:"lap",mode:r.mode,alignment:a.slice(5),body:n}},htmlBuilder:(e,t)=>{var r;"clap"===e.alignment?(r=Ke.makeSpan([],[wt(e.body,t)]),r=Ke.makeSpan(["inner"],[r],t)):r=Ke.makeSpan(["inner"],[wt(e.body,t)]);var a=Ke.makeSpan(["fix"],[]),n=Ke.makeSpan([e.alignment],[r,a],t),i=Ke.makeSpan(["strut"]);return i.style.height=G(n.height+n.depth),n.depth&&(i.style.verticalAlign=G(-n.depth)),n.children.unshift(i),n=Ke.makeSpan(["thinbox"],[n],t),Ke.makeSpan(["mord","vbox"],[n],t)},mathmlBuilder:(e,t)=>{var r=new Tt.MathNode("mpadded",[Rt(e.body,t)]);if("rlap"!==e.alignment){var a="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",a+"width")}return r.setAttribute("width","0px"),r}}),ot({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){var{funcName:r,parser:a}=e,n=a.mode;a.switchMode("math");var i="\\("===r?"\\)":"$",o=a.parseExpression(!1,i);return a.expect(i),a.switchMode(n),{type:"styling",mode:a.mode,style:"text",body:o}}}),ot({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){throw new i("Mismatched "+e.funcName)}});var oa=(e,t)=>{switch(t.style.size){case k.DISPLAY.size:return e.display;case k.TEXT.size:return e.text;case k.SCRIPT.size:return e.script;case k.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};ot({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:(e,t)=>{var{parser:r}=e;return{type:"mathchoice",mode:r.mode,display:ht(t[0]),text:ht(t[1]),script:ht(t[2]),scriptscript:ht(t[3])}},htmlBuilder:(e,t)=>{var r=oa(e,t),a=gt(r,t,!1);return Ke.makeFragment(a)},mathmlBuilder:(e,t)=>{var r=oa(e,t);return It(r,t)}});var sa=(e,t,r,a,n,i,o)=>{e=Ke.makeSpan([],[e]);var s,l,h,c=r&&m.isCharacterBox(r);if(t){var p=wt(t,a.havingStyle(n.sup()),a);l={elem:p,kern:Math.max(a.fontMetrics().bigOpSpacing1,a.fontMetrics().bigOpSpacing3-p.depth)}}if(r){var u=wt(r,a.havingStyle(n.sub()),a);s={elem:u,kern:Math.max(a.fontMetrics().bigOpSpacing2,a.fontMetrics().bigOpSpacing4-u.height)}}if(l&&s){var d=a.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+e.depth+o;h=Ke.makeVList({positionType:"bottom",positionData:d,children:[{type:"kern",size:a.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:G(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e},{type:"kern",size:l.kern},{type:"elem",elem:l.elem,marginLeft:G(i)},{type:"kern",size:a.fontMetrics().bigOpSpacing5}]},a)}else if(s){var g=e.height-o;h=Ke.makeVList({positionType:"top",positionData:g,children:[{type:"kern",size:a.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:G(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e}]},a)}else{if(!l)return e;var f=e.depth+o;h=Ke.makeVList({positionType:"bottom",positionData:f,children:[{type:"elem",elem:e},{type:"kern",size:l.kern},{type:"elem",elem:l.elem,marginLeft:G(i)},{type:"kern",size:a.fontMetrics().bigOpSpacing5}]},a)}var v=[h];if(s&&0!==i&&!c){var b=Ke.makeSpan(["mspace"],[],a);b.style.marginRight=G(i),v.unshift(b)}return Ke.makeSpan(["mop","op-limits"],v,a)},la=["\\smallint"],ha=(e,t)=>{var r,a,n,i=!1;"supsub"===e.type?(r=e.sup,a=e.sub,n=Gt(e.base,"op"),i=!0):n=Gt(e,"op");var o,s=t.style,l=!1;if(s.size===k.DISPLAY.size&&n.symbol&&!m.contains(la,n.name)&&(l=!0),n.symbol){var h=l?"Size2-Regular":"Size1-Regular",c="";if("\\oiint"!==n.name&&"\\oiiint"!==n.name||(c=n.name.slice(1),n.name="oiint"===c?"\\iint":"\\iiint"),o=Ke.makeSymbol(n.name,h,"math",t,["mop","op-symbol",l?"large-op":"small-op"]),c.length>0){var p=o.italic,u=Ke.staticSvg(c+"Size"+(l?"2":"1"),t);o=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:u,shift:l?.08:0}]},t),n.name="\\"+c,o.classes.unshift("mop"),o.italic=p}}else if(n.body){var d=gt(n.body,t,!0);1===d.length&&d[0]instanceof K?(o=d[0]).classes[0]="mop":o=Ke.makeSpan(["mop"],d,t)}else{for(var g=[],f=1;f{var r;if(e.symbol)r=new zt("mo",[Bt(e.name,e.mode)]),m.contains(la,e.name)&&r.setAttribute("largeop","false");else if(e.body)r=new zt("mo",qt(e.body,t));else{r=new zt("mi",[new At(e.name.slice(1))]);var a=new zt("mo",[Bt("\u2061","text")]);r=e.parentIsSupSub?new zt("mrow",[r,a]):Mt([r,a])}return r},ca={"\u220f":"\\prod","\u2210":"\\coprod","\u2211":"\\sum","\u22c0":"\\bigwedge","\u22c1":"\\bigvee","\u22c2":"\\bigcap","\u22c3":"\\bigcup","\u2a00":"\\bigodot","\u2a01":"\\bigoplus","\u2a02":"\\bigotimes","\u2a04":"\\biguplus","\u2a06":"\\bigsqcup"};ot({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","\u220f","\u2210","\u2211","\u22c0","\u22c1","\u22c2","\u22c3","\u2a00","\u2a01","\u2a02","\u2a04","\u2a06"],props:{numArgs:0},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=a;return 1===n.length&&(n=ca[n]),{type:"op",mode:r.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:n}},htmlBuilder:ha,mathmlBuilder:ma}),ot({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"op",mode:r.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:ht(a)}},htmlBuilder:ha,mathmlBuilder:ma});var pa={"\u222b":"\\int","\u222c":"\\iint","\u222d":"\\iiint","\u222e":"\\oint","\u222f":"\\oiint","\u2230":"\\oiiint"};ot({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:ha,mathmlBuilder:ma}),ot({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:ha,mathmlBuilder:ma}),ot({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","\u222b","\u222c","\u222d","\u222e","\u222f","\u2230"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e,a=r;return 1===a.length&&(a=pa[a]),{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:a}},htmlBuilder:ha,mathmlBuilder:ma});var ua=(e,t)=>{var r,a,n,i,o=!1;if("supsub"===e.type?(r=e.sup,a=e.sub,n=Gt(e.base,"operatorname"),o=!0):n=Gt(e,"operatorname"),n.body.length>0){for(var s=n.body.map((e=>{var t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e})),l=gt(s,t.withFont("mathrm"),!0),h=0;h{var{parser:r,funcName:a}=e,n=t[0];return{type:"operatorname",mode:r.mode,body:ht(n),alwaysHandleSupSub:"\\operatornamewithlimits"===a,limits:!1,parentIsSupSub:!1}},htmlBuilder:ua,mathmlBuilder:(e,t)=>{for(var r=qt(e.body,t.withFont("mathrm")),a=!0,n=0;ne.toText())).join("");r=[new Tt.TextNode(s)]}var l=new Tt.MathNode("mi",r);l.setAttribute("mathvariant","normal");var h=new Tt.MathNode("mo",[Bt("\u2061","text")]);return e.parentIsSupSub?new Tt.MathNode("mrow",[l,h]):Tt.newDocumentFragment([l,h])}}),Vr("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@"),st({type:"ordgroup",htmlBuilder:(e,t)=>e.semisimple?Ke.makeFragment(gt(e.body,t,!1)):Ke.makeSpan(["mord"],gt(e.body,t,!0),t),mathmlBuilder:(e,t)=>It(e.body,t,!0)}),ot({type:"overline",names:["\\overline"],props:{numArgs:1},handler(e,t){var{parser:r}=e,a=t[0];return{type:"overline",mode:r.mode,body:a}},htmlBuilder(e,t){var r=wt(e.body,t.havingCrampedStyle()),a=Ke.makeLineSpan("overline-line",t),n=t.fontMetrics().defaultRuleThickness,i=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r},{type:"kern",size:3*n},{type:"elem",elem:a},{type:"kern",size:n}]},t);return Ke.makeSpan(["mord","overline"],[i],t)},mathmlBuilder(e,t){var r=new Tt.MathNode("mo",[new Tt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var a=new Tt.MathNode("mover",[Rt(e.body,t),r]);return a.setAttribute("accent","true"),a}}),ot({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"phantom",mode:r.mode,body:ht(a)}},htmlBuilder:(e,t)=>{var r=gt(e.body,t.withPhantom(),!1);return Ke.makeFragment(r)},mathmlBuilder:(e,t)=>{var r=qt(e.body,t);return new Tt.MathNode("mphantom",r)}}),ot({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"hphantom",mode:r.mode,body:a}},htmlBuilder:(e,t)=>{var r=Ke.makeSpan([],[wt(e.body,t.withPhantom())]);if(r.height=0,r.depth=0,r.children)for(var a=0;a{var r=qt(ht(e.body),t),a=new Tt.MathNode("mphantom",r),n=new Tt.MathNode("mpadded",[a]);return n.setAttribute("height","0px"),n.setAttribute("depth","0px"),n}}),ot({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"vphantom",mode:r.mode,body:a}},htmlBuilder:(e,t)=>{var r=Ke.makeSpan(["inner"],[wt(e.body,t.withPhantom())]),a=Ke.makeSpan(["fix"],[]);return Ke.makeSpan(["mord","rlap"],[r,a],t)},mathmlBuilder:(e,t)=>{var r=qt(ht(e.body),t),a=new Tt.MathNode("mphantom",r),n=new Tt.MathNode("mpadded",[a]);return n.setAttribute("width","0px"),n}}),ot({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(e,t){var{parser:r}=e,a=Gt(t[0],"size").value,n=t[1];return{type:"raisebox",mode:r.mode,dy:a,body:n}},htmlBuilder(e,t){var r=wt(e.body,t),a=F(e.dy,t);return Ke.makeVList({positionType:"shift",positionData:-a,children:[{type:"elem",elem:r}]},t)},mathmlBuilder(e,t){var r=new Tt.MathNode("mpadded",[Rt(e.body,t)]),a=e.dy.number+e.dy.unit;return r.setAttribute("voffset",a),r}}),ot({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0},handler(e){var{parser:t}=e;return{type:"internal",mode:t.mode}}}),ot({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,argTypes:["size","size","size"]},handler(e,t,r){var{parser:a}=e,n=r[0],i=Gt(t[0],"size"),o=Gt(t[1],"size");return{type:"rule",mode:a.mode,shift:n&&Gt(n,"size").value,width:i.value,height:o.value}},htmlBuilder(e,t){var r=Ke.makeSpan(["mord","rule"],[],t),a=F(e.width,t),n=F(e.height,t),i=e.shift?F(e.shift,t):0;return r.style.borderRightWidth=G(a),r.style.borderTopWidth=G(n),r.style.bottom=G(i),r.width=a,r.height=n+i,r.depth=-i,r.maxFontSize=1.125*n*t.sizeMultiplier,r},mathmlBuilder(e,t){var r=F(e.width,t),a=F(e.height,t),n=e.shift?F(e.shift,t):0,i=t.color&&t.getColor()||"black",o=new Tt.MathNode("mspace");o.setAttribute("mathbackground",i),o.setAttribute("width",G(r)),o.setAttribute("height",G(a));var s=new Tt.MathNode("mpadded",[o]);return n>=0?s.setAttribute("height",G(n)):(s.setAttribute("height",G(n)),s.setAttribute("depth",G(-n))),s.setAttribute("voffset",G(n)),s}});var ga=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];ot({type:"sizing",names:ga,props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{var{breakOnTokenText:r,funcName:a,parser:n}=e,i=n.parseExpression(!1,r);return{type:"sizing",mode:n.mode,size:ga.indexOf(a)+1,body:i}},htmlBuilder:(e,t)=>{var r=t.havingSize(e.size);return da(e.body,r,t)},mathmlBuilder:(e,t)=>{var r=t.havingSize(e.size),a=qt(e.body,r),n=new Tt.MathNode("mstyle",a);return n.setAttribute("mathsize",G(r.sizeMultiplier)),n}}),ot({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:(e,t,r)=>{var{parser:a}=e,n=!1,i=!1,o=r[0]&&Gt(r[0],"ordgroup");if(o)for(var s="",l=0;l{var r=Ke.makeSpan([],[wt(e.body,t)]);if(!e.smashHeight&&!e.smashDepth)return r;if(e.smashHeight&&(r.height=0,r.children))for(var a=0;a{var r=new Tt.MathNode("mpadded",[Rt(e.body,t)]);return e.smashHeight&&r.setAttribute("height","0px"),e.smashDepth&&r.setAttribute("depth","0px"),r}}),ot({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){var{parser:a}=e,n=r[0],i=t[0];return{type:"sqrt",mode:a.mode,body:i,index:n}},htmlBuilder(e,t){var r=wt(e.body,t.havingCrampedStyle());0===r.height&&(r.height=t.fontMetrics().xHeight),r=Ke.wrapFragment(r,t);var a=t.fontMetrics().defaultRuleThickness,n=a;t.style.idr.height+r.depth+i&&(i=(i+m-r.height-r.depth)/2);var c=s.height-r.height-i-l;r.style.paddingLeft=G(h);var p=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+c)},{type:"elem",elem:s},{type:"kern",size:l}]},t);if(e.index){var u=t.havingStyle(k.SCRIPTSCRIPT),d=wt(e.index,u,t),g=.6*(p.height-p.depth),f=Ke.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:d}]},t),v=Ke.makeSpan(["root"],[f]);return Ke.makeSpan(["mord","sqrt"],[v,p],t)}return Ke.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder(e,t){var{body:r,index:a}=e;return a?new Tt.MathNode("mroot",[Rt(r,t),Rt(a,t)]):new Tt.MathNode("msqrt",[Rt(r,t)])}});var fa={display:k.DISPLAY,text:k.TEXT,script:k.SCRIPT,scriptscript:k.SCRIPTSCRIPT};ot({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e,t){var{breakOnTokenText:r,funcName:a,parser:n}=e,i=n.parseExpression(!0,r),o=a.slice(1,a.length-5);return{type:"styling",mode:n.mode,style:o,body:i}},htmlBuilder(e,t){var r=fa[e.style],a=t.havingStyle(r).withFont("");return da(e.body,a,t)},mathmlBuilder(e,t){var r=fa[e.style],a=t.havingStyle(r),n=qt(e.body,a),i=new Tt.MathNode("mstyle",n),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});st({type:"supsub",htmlBuilder(e,t){var r=function(e,t){var r=e.base;return r?"op"===r.type?r.limits&&(t.style.size===k.DISPLAY.size||r.alwaysHandleSupSub)?ha:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===k.DISPLAY.size||r.limits)?ua:null:"accent"===r.type?m.isCharacterBox(r.base)?Xt:null:"horizBrace"===r.type&&!e.sub===r.isOver?na:null:null}(e,t);if(r)return r(e,t);var a,n,i,{base:o,sup:s,sub:l}=e,h=wt(o,t),c=t.fontMetrics(),p=0,u=0,d=o&&m.isCharacterBox(o);if(s){var g=t.havingStyle(t.style.sup());a=wt(s,g,t),d||(p=h.height-g.fontMetrics().supDrop*g.sizeMultiplier/t.sizeMultiplier)}if(l){var f=t.havingStyle(t.style.sub());n=wt(l,f,t),d||(u=h.depth+f.fontMetrics().subDrop*f.sizeMultiplier/t.sizeMultiplier)}i=t.style===k.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;var v,b=t.sizeMultiplier,y=G(.5/c.ptPerEm/b),x=null;if(n){var w=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(h instanceof K||w)&&(x=G(-h.italic))}if(a&&n){p=Math.max(p,i,a.depth+.25*c.xHeight),u=Math.max(u,c.sub2);var S=4*c.defaultRuleThickness;if(p-a.depth-(n.height-u)0&&(p+=M,u-=M)}var z=[{type:"elem",elem:n,shift:u,marginRight:y,marginLeft:x},{type:"elem",elem:a,shift:-p,marginRight:y}];v=Ke.makeVList({positionType:"individualShift",children:z},t)}else if(n){u=Math.max(u,c.sub1,n.height-.8*c.xHeight);var A=[{type:"elem",elem:n,marginLeft:x,marginRight:y}];v=Ke.makeVList({positionType:"shift",positionData:u,children:A},t)}else{if(!a)throw new Error("supsub must have either sup or sub.");p=Math.max(p,i,a.depth+.25*c.xHeight),v=Ke.makeVList({positionType:"shift",positionData:-p,children:[{type:"elem",elem:a,marginRight:y}]},t)}var T=yt(h,"right")||"mord";return Ke.makeSpan([T],[h,Ke.makeSpan(["msupsub"],[v])],t)},mathmlBuilder(e,t){var r,a=!1;e.base&&"horizBrace"===e.base.type&&!!e.sup===e.base.isOver&&(a=!0,r=e.base.isOver),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);var n,i=[Rt(e.base,t)];if(e.sub&&i.push(Rt(e.sub,t)),e.sup&&i.push(Rt(e.sup,t)),a)n=r?"mover":"munder";else if(e.sub)if(e.sup){var o=e.base;n=o&&"op"===o.type&&o.limits&&t.style===k.DISPLAY||o&&"operatorname"===o.type&&o.alwaysHandleSupSub&&(t.style===k.DISPLAY||o.limits)?"munderover":"msubsup"}else{var s=e.base;n=s&&"op"===s.type&&s.limits&&(t.style===k.DISPLAY||s.alwaysHandleSupSub)||s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(s.limits||t.style===k.DISPLAY)?"munder":"msub"}else{var l=e.base;n=l&&"op"===l.type&&l.limits&&(t.style===k.DISPLAY||l.alwaysHandleSupSub)||l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||t.style===k.DISPLAY)?"mover":"msup"}return new Tt.MathNode(n,i)}}),st({type:"atom",htmlBuilder:(e,t)=>Ke.mathsym(e.text,e.mode,t,["m"+e.family]),mathmlBuilder(e,t){var r=new Tt.MathNode("mo",[Bt(e.text,e.mode)]);if("bin"===e.family){var a=Nt(e,t);"bold-italic"===a&&r.setAttribute("mathvariant",a)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});var va={mi:"italic",mn:"normal",mtext:"normal"};st({type:"mathord",htmlBuilder:(e,t)=>Ke.makeOrd(e,t,"mathord"),mathmlBuilder(e,t){var r=new Tt.MathNode("mi",[Bt(e.text,e.mode,t)]),a=Nt(e,t)||"italic";return a!==va[r.type]&&r.setAttribute("mathvariant",a),r}}),st({type:"textord",htmlBuilder:(e,t)=>Ke.makeOrd(e,t,"textord"),mathmlBuilder(e,t){var r,a=Bt(e.text,e.mode,t),n=Nt(e,t)||"normal";return r="text"===e.mode?new Tt.MathNode("mtext",[a]):/[0-9]/.test(e.text)?new Tt.MathNode("mn",[a]):"\\prime"===e.text?new Tt.MathNode("mo",[a]):new Tt.MathNode("mi",[a]),n!==va[r.type]&&r.setAttribute("mathvariant",n),r}});var ba={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},ya={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};st({type:"spacing",htmlBuilder(e,t){if(ya.hasOwnProperty(e.text)){var r=ya[e.text].className||"";if("text"===e.mode){var a=Ke.makeOrd(e,t,"textord");return a.classes.push(r),a}return Ke.makeSpan(["mspace",r],[Ke.mathsym(e.text,e.mode,t)],t)}if(ba.hasOwnProperty(e.text))return Ke.makeSpan(["mspace",ba[e.text]],[],t);throw new i('Unknown type of space "'+e.text+'"')},mathmlBuilder(e,t){if(!ya.hasOwnProperty(e.text)){if(ba.hasOwnProperty(e.text))return new Tt.MathNode("mspace");throw new i('Unknown type of space "'+e.text+'"')}return new Tt.MathNode("mtext",[new Tt.TextNode("\xa0")])}});var xa=()=>{var e=new Tt.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};st({type:"tag",mathmlBuilder(e,t){var r=new Tt.MathNode("mtable",[new Tt.MathNode("mtr",[xa(),new Tt.MathNode("mtd",[It(e.body,t)]),xa(),new Tt.MathNode("mtd",[It(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});var wa={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},ka={"\\textbf":"textbf","\\textmd":"textmd"},Sa={"\\textit":"textit","\\textup":"textup"},Ma=(e,t)=>{var r=e.font;return r?wa[r]?t.withTextFontFamily(wa[r]):ka[r]?t.withTextFontWeight(ka[r]):t.withTextFontShape(Sa[r]):t};ot({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];return{type:"text",mode:r.mode,body:ht(n),font:a}},htmlBuilder(e,t){var r=Ma(e,t),a=gt(e.body,r,!0);return Ke.makeSpan(["mord","text"],a,r)},mathmlBuilder(e,t){var r=Ma(e,t);return It(e.body,r)}}),ot({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"underline",mode:r.mode,body:t[0]}},htmlBuilder(e,t){var r=wt(e.body,t),a=Ke.makeLineSpan("underline-line",t),n=t.fontMetrics().defaultRuleThickness,i=Ke.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:n},{type:"elem",elem:a},{type:"kern",size:3*n},{type:"elem",elem:r}]},t);return Ke.makeSpan(["mord","underline"],[i],t)},mathmlBuilder(e,t){var r=new Tt.MathNode("mo",[new Tt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var a=new Tt.MathNode("munder",[Rt(e.body,t),r]);return a.setAttribute("accentunder","true"),a}}),ot({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(e,t){var{parser:r}=e;return{type:"vcenter",mode:r.mode,body:t[0]}},htmlBuilder(e,t){var r=wt(e.body,t),a=t.fontMetrics().axisHeight,n=.5*(r.height-a-(r.depth+a));return Ke.makeVList({positionType:"shift",positionData:n,children:[{type:"elem",elem:r}]},t)},mathmlBuilder:(e,t)=>new Tt.MathNode("mpadded",[Rt(e.body,t)],["vcenter"])}),ot({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(e,t,r){throw new i("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(e,t){for(var r=za(e),a=[],n=t.havingStyle(t.style.text()),i=0;ie.body.replace(/ /g,e.star?"\u2423":"\xa0"),Aa=at,Ta="[ \r\n\t]",Ba="(\\\\[a-zA-Z@]+)"+Ta+"*",Ca="[\u0300-\u036f]",Na=new RegExp(Ca+"+$"),qa="("+Ta+"+)|\\\\(\n|[ \r\t]+\n?)[ \r\t]*|([!-\\[\\]-\u2027\u202a-\ud7ff\uf900-\uffff]"+Ca+"*|[\ud800-\udbff][\udc00-\udfff]"+Ca+"*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5|"+Ba+"|\\\\[^\ud800-\udfff])";class Ia{constructor(e,t){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=e,this.settings=t,this.tokenRegex=new RegExp(qa,"g"),this.catcodes={"%":14,"~":13}}setCatcode(e,t){this.catcodes[e]=t}lex(){var e=this.input,t=this.tokenRegex.lastIndex;if(t===e.length)return new n("EOF",new a(this,t,t));var r=this.tokenRegex.exec(e);if(null===r||r.index!==t)throw new i("Unexpected character: '"+e[t]+"'",new n(e[t],new a(this,t,t+1)));var o=r[6]||r[3]||(r[2]?"\\ ":" ");if(14===this.catcodes[o]){var s=e.indexOf("\n",this.tokenRegex.lastIndex);return-1===s?(this.tokenRegex.lastIndex=e.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=s+1,this.lex()}return new n(o,new a(this,t,this.tokenRegex.lastIndex))}}class Ra{constructor(e,t){void 0===e&&(e={}),void 0===t&&(t={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=t,this.builtins=e,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(0===this.undefStack.length)throw new i("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var e=this.undefStack.pop();for(var t in e)e.hasOwnProperty(t)&&(null==e[t]?delete this.current[t]:this.current[t]=e[t])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)}get(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]}set(e,t,r){if(void 0===r&&(r=!1),r){for(var a=0;a0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var n=this.undefStack[this.undefStack.length-1];n&&!n.hasOwnProperty(e)&&(n[e]=this.current[e])}null==t?delete this.current[e]:this.current[e]=t}}var Ha=Dr;Vr("\\noexpand",(function(e){var t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}})),Vr("\\expandafter",(function(e){var t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}})),Vr("\\@firstoftwo",(function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}})),Vr("\\@secondoftwo",(function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}})),Vr("\\@ifnextchar",(function(e){var t=e.consumeArgs(3);e.consumeSpaces();var r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}})),Vr("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),Vr("\\TextOrMath",(function(e){var t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}}));var Oa={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};Vr("\\char",(function(e){var t,r=e.popToken(),a="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if("\\"===(r=e.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new i("\\char` missing argument");a=r.text.charCodeAt(0)}else t=10;if(t){if(null==(a=Oa[r.text])||a>=t)throw new i("Invalid base-"+t+" digit "+r.text);for(var n;null!=(n=Oa[e.future().text])&&n{var a=e.consumeArg().tokens;if(1!==a.length)throw new i("\\newcommand's first argument must be a macro name");var n=a[0].text,o=e.isDefined(n);if(o&&!t)throw new i("\\newcommand{"+n+"} attempting to redefine "+n+"; use \\renewcommand");if(!o&&!r)throw new i("\\renewcommand{"+n+"} when command "+n+" does not yet exist; use \\newcommand");var s=0;if(1===(a=e.consumeArg().tokens).length&&"["===a[0].text){for(var l="",h=e.expandNextToken();"]"!==h.text&&"EOF"!==h.text;)l+=h.text,h=e.expandNextToken();if(!l.match(/^\s*[0-9]+\s*$/))throw new i("Invalid number of arguments: "+l);s=parseInt(l),a=e.consumeArg().tokens}return e.macros.set(n,{tokens:a,numArgs:s}),""};Vr("\\newcommand",(e=>Ea(e,!1,!0))),Vr("\\renewcommand",(e=>Ea(e,!0,!1))),Vr("\\providecommand",(e=>Ea(e,!0,!0))),Vr("\\message",(e=>{var t=e.consumeArgs(1)[0];return console.log(t.reverse().map((e=>e.text)).join("")),""})),Vr("\\errmessage",(e=>{var t=e.consumeArgs(1)[0];return console.error(t.reverse().map((e=>e.text)).join("")),""})),Vr("\\show",(e=>{var t=e.popToken(),r=t.text;return console.log(t,e.macros.get(r),Aa[r],ne.math[r],ne.text[r]),""})),Vr("\\bgroup","{"),Vr("\\egroup","}"),Vr("~","\\nobreakspace"),Vr("\\lq","`"),Vr("\\rq","'"),Vr("\\aa","\\r a"),Vr("\\AA","\\r A"),Vr("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`\xa9}"),Vr("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}"),Vr("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xae}"),Vr("\u212c","\\mathscr{B}"),Vr("\u2130","\\mathscr{E}"),Vr("\u2131","\\mathscr{F}"),Vr("\u210b","\\mathscr{H}"),Vr("\u2110","\\mathscr{I}"),Vr("\u2112","\\mathscr{L}"),Vr("\u2133","\\mathscr{M}"),Vr("\u211b","\\mathscr{R}"),Vr("\u212d","\\mathfrak{C}"),Vr("\u210c","\\mathfrak{H}"),Vr("\u2128","\\mathfrak{Z}"),Vr("\\Bbbk","\\Bbb{k}"),Vr("\xb7","\\cdotp"),Vr("\\llap","\\mathllap{\\textrm{#1}}"),Vr("\\rlap","\\mathrlap{\\textrm{#1}}"),Vr("\\clap","\\mathclap{\\textrm{#1}}"),Vr("\\mathstrut","\\vphantom{(}"),Vr("\\underbar","\\underline{\\text{#1}}"),Vr("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'),Vr("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}"),Vr("\\ne","\\neq"),Vr("\u2260","\\neq"),Vr("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}"),Vr("\u2209","\\notin"),Vr("\u2258","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}"),Vr("\u2259","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}"),Vr("\u225a","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225a}}"),Vr("\u225b","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225b}}"),Vr("\u225d","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225d}}"),Vr("\u225e","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225e}}"),Vr("\u225f","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225f}}"),Vr("\u27c2","\\perp"),Vr("\u203c","\\mathclose{!\\mkern-0.8mu!}"),Vr("\u220c","\\notni"),Vr("\u231c","\\ulcorner"),Vr("\u231d","\\urcorner"),Vr("\u231e","\\llcorner"),Vr("\u231f","\\lrcorner"),Vr("\xa9","\\copyright"),Vr("\xae","\\textregistered"),Vr("\ufe0f","\\textregistered"),Vr("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}'),Vr("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}'),Vr("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}'),Vr("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}'),Vr("\\vdots","\\mathord{\\varvdots\\rule{0pt}{15pt}}"),Vr("\u22ee","\\vdots"),Vr("\\varGamma","\\mathit{\\Gamma}"),Vr("\\varDelta","\\mathit{\\Delta}"),Vr("\\varTheta","\\mathit{\\Theta}"),Vr("\\varLambda","\\mathit{\\Lambda}"),Vr("\\varXi","\\mathit{\\Xi}"),Vr("\\varPi","\\mathit{\\Pi}"),Vr("\\varSigma","\\mathit{\\Sigma}"),Vr("\\varUpsilon","\\mathit{\\Upsilon}"),Vr("\\varPhi","\\mathit{\\Phi}"),Vr("\\varPsi","\\mathit{\\Psi}"),Vr("\\varOmega","\\mathit{\\Omega}"),Vr("\\substack","\\begin{subarray}{c}#1\\end{subarray}"),Vr("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax"),Vr("\\boxed","\\fbox{$\\displaystyle{#1}$}"),Vr("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;"),Vr("\\implies","\\DOTSB\\;\\Longrightarrow\\;"),Vr("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;");var La={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};Vr("\\dots",(function(e){var t="\\dotso",r=e.expandAfterFuture().text;return r in La?t=La[r]:("\\not"===r.slice(0,4)||r in ne.math&&m.contains(["bin","rel"],ne.math[r].group))&&(t="\\dotsb"),t}));var Da={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};Vr("\\dotso",(function(e){return e.future().text in Da?"\\ldots\\,":"\\ldots"})),Vr("\\dotsc",(function(e){var t=e.future().text;return t in Da&&","!==t?"\\ldots\\,":"\\ldots"})),Vr("\\cdots",(function(e){return e.future().text in Da?"\\@cdots\\,":"\\@cdots"})),Vr("\\dotsb","\\cdots"),Vr("\\dotsm","\\cdots"),Vr("\\dotsi","\\!\\cdots"),Vr("\\dotsx","\\ldots\\,"),Vr("\\DOTSI","\\relax"),Vr("\\DOTSB","\\relax"),Vr("\\DOTSX","\\relax"),Vr("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),Vr("\\,","\\tmspace+{3mu}{.1667em}"),Vr("\\thinspace","\\,"),Vr("\\>","\\mskip{4mu}"),Vr("\\:","\\tmspace+{4mu}{.2222em}"),Vr("\\medspace","\\:"),Vr("\\;","\\tmspace+{5mu}{.2777em}"),Vr("\\thickspace","\\;"),Vr("\\!","\\tmspace-{3mu}{.1667em}"),Vr("\\negthinspace","\\!"),Vr("\\negmedspace","\\tmspace-{4mu}{.2222em}"),Vr("\\negthickspace","\\tmspace-{5mu}{.277em}"),Vr("\\enspace","\\kern.5em "),Vr("\\enskip","\\hskip.5em\\relax"),Vr("\\quad","\\hskip1em\\relax"),Vr("\\qquad","\\hskip2em\\relax"),Vr("\\tag","\\@ifstar\\tag@literal\\tag@paren"),Vr("\\tag@paren","\\tag@literal{({#1})}"),Vr("\\tag@literal",(e=>{if(e.macros.get("\\df@tag"))throw new i("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"})),Vr("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),Vr("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),Vr("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),Vr("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),Vr("\\newline","\\\\\\relax"),Vr("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var Va=G(C["Main-Regular"]["T".charCodeAt(0)][1]-.7*C["Main-Regular"]["A".charCodeAt(0)][1]);Vr("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Va+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),Vr("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Va+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),Vr("\\hspace","\\@ifstar\\@hspacer\\@hspace"),Vr("\\@hspace","\\hskip #1\\relax"),Vr("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),Vr("\\ordinarycolon",":"),Vr("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),Vr("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),Vr("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),Vr("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),Vr("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),Vr("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),Vr("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),Vr("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),Vr("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),Vr("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),Vr("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),Vr("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),Vr("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),Vr("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),Vr("\u2237","\\dblcolon"),Vr("\u2239","\\eqcolon"),Vr("\u2254","\\coloneqq"),Vr("\u2255","\\eqqcolon"),Vr("\u2a74","\\Coloneqq"),Vr("\\ratio","\\vcentcolon"),Vr("\\coloncolon","\\dblcolon"),Vr("\\colonequals","\\coloneqq"),Vr("\\coloncolonequals","\\Coloneqq"),Vr("\\equalscolon","\\eqqcolon"),Vr("\\equalscoloncolon","\\Eqqcolon"),Vr("\\colonminus","\\coloneq"),Vr("\\coloncolonminus","\\Coloneq"),Vr("\\minuscolon","\\eqcolon"),Vr("\\minuscoloncolon","\\Eqcolon"),Vr("\\coloncolonapprox","\\Colonapprox"),Vr("\\coloncolonsim","\\Colonsim"),Vr("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Vr("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Vr("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Vr("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Vr("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),Vr("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),Vr("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),Vr("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),Vr("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),Vr("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),Vr("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),Vr("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),Vr("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),Vr("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),Vr("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),Vr("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),Vr("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),Vr("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),Vr("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),Vr("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),Vr("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),Vr("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),Vr("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),Vr("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),Vr("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),Vr("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),Vr("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),Vr("\\imath","\\html@mathml{\\@imath}{\u0131}"),Vr("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),Vr("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),Vr("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),Vr("\u27e6","\\llbracket"),Vr("\u27e7","\\rrbracket"),Vr("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),Vr("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),Vr("\u2983","\\lBrace"),Vr("\u2984","\\rBrace"),Vr("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),Vr("\u29b5","\\minuso"),Vr("\\darr","\\downarrow"),Vr("\\dArr","\\Downarrow"),Vr("\\Darr","\\Downarrow"),Vr("\\lang","\\langle"),Vr("\\rang","\\rangle"),Vr("\\uarr","\\uparrow"),Vr("\\uArr","\\Uparrow"),Vr("\\Uarr","\\Uparrow"),Vr("\\N","\\mathbb{N}"),Vr("\\R","\\mathbb{R}"),Vr("\\Z","\\mathbb{Z}"),Vr("\\alef","\\aleph"),Vr("\\alefsym","\\aleph"),Vr("\\Alpha","\\mathrm{A}"),Vr("\\Beta","\\mathrm{B}"),Vr("\\bull","\\bullet"),Vr("\\Chi","\\mathrm{X}"),Vr("\\clubs","\\clubsuit"),Vr("\\cnums","\\mathbb{C}"),Vr("\\Complex","\\mathbb{C}"),Vr("\\Dagger","\\ddagger"),Vr("\\diamonds","\\diamondsuit"),Vr("\\empty","\\emptyset"),Vr("\\Epsilon","\\mathrm{E}"),Vr("\\Eta","\\mathrm{H}"),Vr("\\exist","\\exists"),Vr("\\harr","\\leftrightarrow"),Vr("\\hArr","\\Leftrightarrow"),Vr("\\Harr","\\Leftrightarrow"),Vr("\\hearts","\\heartsuit"),Vr("\\image","\\Im"),Vr("\\infin","\\infty"),Vr("\\Iota","\\mathrm{I}"),Vr("\\isin","\\in"),Vr("\\Kappa","\\mathrm{K}"),Vr("\\larr","\\leftarrow"),Vr("\\lArr","\\Leftarrow"),Vr("\\Larr","\\Leftarrow"),Vr("\\lrarr","\\leftrightarrow"),Vr("\\lrArr","\\Leftrightarrow"),Vr("\\Lrarr","\\Leftrightarrow"),Vr("\\Mu","\\mathrm{M}"),Vr("\\natnums","\\mathbb{N}"),Vr("\\Nu","\\mathrm{N}"),Vr("\\Omicron","\\mathrm{O}"),Vr("\\plusmn","\\pm"),Vr("\\rarr","\\rightarrow"),Vr("\\rArr","\\Rightarrow"),Vr("\\Rarr","\\Rightarrow"),Vr("\\real","\\Re"),Vr("\\reals","\\mathbb{R}"),Vr("\\Reals","\\mathbb{R}"),Vr("\\Rho","\\mathrm{P}"),Vr("\\sdot","\\cdot"),Vr("\\sect","\\S"),Vr("\\spades","\\spadesuit"),Vr("\\sub","\\subset"),Vr("\\sube","\\subseteq"),Vr("\\supe","\\supseteq"),Vr("\\Tau","\\mathrm{T}"),Vr("\\thetasym","\\vartheta"),Vr("\\weierp","\\wp"),Vr("\\Zeta","\\mathrm{Z}"),Vr("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),Vr("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),Vr("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),Vr("\\bra","\\mathinner{\\langle{#1}|}"),Vr("\\ket","\\mathinner{|{#1}\\rangle}"),Vr("\\braket","\\mathinner{\\langle{#1}\\rangle}"),Vr("\\Bra","\\left\\langle#1\\right|"),Vr("\\Ket","\\left|#1\\right\\rangle");var Pa=e=>t=>{var r=t.consumeArg().tokens,a=t.consumeArg().tokens,n=t.consumeArg().tokens,i=t.consumeArg().tokens,o=t.macros.get("|"),s=t.macros.get("\\|");t.macros.beginGroup();var l=t=>r=>{e&&(r.macros.set("|",o),n.length&&r.macros.set("\\|",s));var i=t;!t&&n.length&&("|"===r.future().text&&(r.popToken(),i=!0));return{tokens:i?n:a,numArgs:0}};t.macros.set("|",l(!1)),n.length&&t.macros.set("\\|",l(!0));var h=t.consumeArg().tokens,m=t.expandTokens([...i,...h,...r]);return t.macros.endGroup(),{tokens:m.reverse(),numArgs:0}};Vr("\\bra@ket",Pa(!1)),Vr("\\bra@set",Pa(!0)),Vr("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"),Vr("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"),Vr("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"),Vr("\\angln","{\\angl n}"),Vr("\\blue","\\textcolor{##6495ed}{#1}"),Vr("\\orange","\\textcolor{##ffa500}{#1}"),Vr("\\pink","\\textcolor{##ff00af}{#1}"),Vr("\\red","\\textcolor{##df0030}{#1}"),Vr("\\green","\\textcolor{##28ae7b}{#1}"),Vr("\\gray","\\textcolor{gray}{#1}"),Vr("\\purple","\\textcolor{##9d38bd}{#1}"),Vr("\\blueA","\\textcolor{##ccfaff}{#1}"),Vr("\\blueB","\\textcolor{##80f6ff}{#1}"),Vr("\\blueC","\\textcolor{##63d9ea}{#1}"),Vr("\\blueD","\\textcolor{##11accd}{#1}"),Vr("\\blueE","\\textcolor{##0c7f99}{#1}"),Vr("\\tealA","\\textcolor{##94fff5}{#1}"),Vr("\\tealB","\\textcolor{##26edd5}{#1}"),Vr("\\tealC","\\textcolor{##01d1c1}{#1}"),Vr("\\tealD","\\textcolor{##01a995}{#1}"),Vr("\\tealE","\\textcolor{##208170}{#1}"),Vr("\\greenA","\\textcolor{##b6ffb0}{#1}"),Vr("\\greenB","\\textcolor{##8af281}{#1}"),Vr("\\greenC","\\textcolor{##74cf70}{#1}"),Vr("\\greenD","\\textcolor{##1fab54}{#1}"),Vr("\\greenE","\\textcolor{##0d923f}{#1}"),Vr("\\goldA","\\textcolor{##ffd0a9}{#1}"),Vr("\\goldB","\\textcolor{##ffbb71}{#1}"),Vr("\\goldC","\\textcolor{##ff9c39}{#1}"),Vr("\\goldD","\\textcolor{##e07d10}{#1}"),Vr("\\goldE","\\textcolor{##a75a05}{#1}"),Vr("\\redA","\\textcolor{##fca9a9}{#1}"),Vr("\\redB","\\textcolor{##ff8482}{#1}"),Vr("\\redC","\\textcolor{##f9685d}{#1}"),Vr("\\redD","\\textcolor{##e84d39}{#1}"),Vr("\\redE","\\textcolor{##bc2612}{#1}"),Vr("\\maroonA","\\textcolor{##ffbde0}{#1}"),Vr("\\maroonB","\\textcolor{##ff92c6}{#1}"),Vr("\\maroonC","\\textcolor{##ed5fa6}{#1}"),Vr("\\maroonD","\\textcolor{##ca337c}{#1}"),Vr("\\maroonE","\\textcolor{##9e034e}{#1}"),Vr("\\purpleA","\\textcolor{##ddd7ff}{#1}"),Vr("\\purpleB","\\textcolor{##c6b9fc}{#1}"),Vr("\\purpleC","\\textcolor{##aa87ff}{#1}"),Vr("\\purpleD","\\textcolor{##7854ab}{#1}"),Vr("\\purpleE","\\textcolor{##543b78}{#1}"),Vr("\\mintA","\\textcolor{##f5f9e8}{#1}"),Vr("\\mintB","\\textcolor{##edf2df}{#1}"),Vr("\\mintC","\\textcolor{##e0e5cc}{#1}"),Vr("\\grayA","\\textcolor{##f6f7f7}{#1}"),Vr("\\grayB","\\textcolor{##f0f1f2}{#1}"),Vr("\\grayC","\\textcolor{##e3e5e6}{#1}"),Vr("\\grayD","\\textcolor{##d6d8da}{#1}"),Vr("\\grayE","\\textcolor{##babec2}{#1}"),Vr("\\grayF","\\textcolor{##888d93}{#1}"),Vr("\\grayG","\\textcolor{##626569}{#1}"),Vr("\\grayH","\\textcolor{##3b3e40}{#1}"),Vr("\\grayI","\\textcolor{##21242c}{#1}"),Vr("\\kaBlue","\\textcolor{##314453}{#1}"),Vr("\\kaGreen","\\textcolor{##71B307}{#1}");var Fa={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0};class Ga{constructor(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new Ra(Ha,t.macros),this.mode=r,this.stack=[]}feed(e){this.lexer=new Ia(e,this.settings)}switchMode(e){this.mode=e}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(e){this.stack.push(e)}pushTokens(e){this.stack.push(...e)}scanArgument(e){var t,r,a;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken(),({tokens:a,end:r}=this.consumeArg(["]"]))}else({tokens:a,start:t,end:r}=this.consumeArg());return this.pushToken(new n("EOF",r.loc)),this.pushTokens(a),t.range(r,"")}consumeSpaces(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}}consumeArg(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var a,n=this.future(),o=0,s=0;do{if(a=this.popToken(),t.push(a),"{"===a.text)++o;else if("}"===a.text){if(-1===--o)throw new i("Extra }",a)}else if("EOF"===a.text)throw new i("Unexpected end of input in a macro argument, expected '"+(e&&r?e[s]:"}")+"'",a);if(e&&r)if((0===o||1===o&&"{"===e[s])&&a.text===e[s]){if(++s===e.length){t.splice(-s,s);break}}else s=0}while(0!==o||r);return"{"===n.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:n,end:a}}consumeArgs(e,t){if(t){if(t.length!==e+1)throw new i("The length of delimiters doesn't match the number of args!");for(var r=t[0],a=0;athis.settings.maxExpand)throw new i("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(e){var t=this.popToken(),r=t.text,a=t.noexpand?null:this._getExpansion(r);if(null==a||e&&a.unexpandable){if(e&&null==a&&"\\"===r[0]&&!this.isDefined(r))throw new i("Undefined control sequence: "+r);return this.pushToken(t),!1}this.countExpansion(1);var n=a.tokens,o=this.consumeArgs(a.numArgs,a.delimiters);if(a.numArgs)for(var s=(n=n.slice()).length-1;s>=0;--s){var l=n[s];if("#"===l.text){if(0===s)throw new i("Incomplete placeholder at end of macro body",l);if("#"===(l=n[--s]).text)n.splice(s+1,1);else{if(!/^[1-9]$/.test(l.text))throw new i("Not a valid argument number",l);n.splice(s,2,...o[+l.text-1])}}}return this.pushTokens(n),n.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(!1===this.expandOnce()){var e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error}expandMacro(e){return this.macros.has(e)?this.expandTokens([new n(e)]):void 0}expandTokens(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;)if(!1===this.expandOnce(!0)){var a=this.stack.pop();a.treatAsRelax&&(a.noexpand=!1,a.treatAsRelax=!1),t.push(a)}return this.countExpansion(t.length),t}expandMacroAsText(e){var t=this.expandMacro(e);return t?t.map((e=>e.text)).join(""):t}_getExpansion(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){var r=this.lexer.catcodes[e];if(null!=r&&13!==r)return}var a="function"==typeof t?t(this):t;if("string"==typeof a){var n=0;if(-1!==a.indexOf("#"))for(var i=a.replace(/##/g,"");-1!==i.indexOf("#"+(n+1));)++n;for(var o=new Ia(a,this.settings),s=[],l=o.lex();"EOF"!==l.text;)s.push(l),l=o.lex();return s.reverse(),{tokens:s,numArgs:n}}return a}isDefined(e){return this.macros.has(e)||Aa.hasOwnProperty(e)||ne.math.hasOwnProperty(e)||ne.text.hasOwnProperty(e)||Fa.hasOwnProperty(e)}isExpandable(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:Aa.hasOwnProperty(e)&&!Aa[e].primitive}}var Ua=/^[\u208a\u208b\u208c\u208d\u208e\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2090\u2091\u2095\u1d62\u2c7c\u2096\u2097\u2098\u2099\u2092\u209a\u1d63\u209b\u209c\u1d64\u1d65\u2093\u1d66\u1d67\u1d68\u1d69\u1d6a]/,Ya=Object.freeze({"\u208a":"+","\u208b":"-","\u208c":"=","\u208d":"(","\u208e":")","\u2080":"0","\u2081":"1","\u2082":"2","\u2083":"3","\u2084":"4","\u2085":"5","\u2086":"6","\u2087":"7","\u2088":"8","\u2089":"9","\u2090":"a","\u2091":"e","\u2095":"h","\u1d62":"i","\u2c7c":"j","\u2096":"k","\u2097":"l","\u2098":"m","\u2099":"n","\u2092":"o","\u209a":"p","\u1d63":"r","\u209b":"s","\u209c":"t","\u1d64":"u","\u1d65":"v","\u2093":"x","\u1d66":"\u03b2","\u1d67":"\u03b3","\u1d68":"\u03c1","\u1d69":"\u03d5","\u1d6a":"\u03c7","\u207a":"+","\u207b":"-","\u207c":"=","\u207d":"(","\u207e":")","\u2070":"0","\xb9":"1","\xb2":"2","\xb3":"3","\u2074":"4","\u2075":"5","\u2076":"6","\u2077":"7","\u2078":"8","\u2079":"9","\u1d2c":"A","\u1d2e":"B","\u1d30":"D","\u1d31":"E","\u1d33":"G","\u1d34":"H","\u1d35":"I","\u1d36":"J","\u1d37":"K","\u1d38":"L","\u1d39":"M","\u1d3a":"N","\u1d3c":"O","\u1d3e":"P","\u1d3f":"R","\u1d40":"T","\u1d41":"U","\u2c7d":"V","\u1d42":"W","\u1d43":"a","\u1d47":"b","\u1d9c":"c","\u1d48":"d","\u1d49":"e","\u1da0":"f","\u1d4d":"g","\u02b0":"h","\u2071":"i","\u02b2":"j","\u1d4f":"k","\u02e1":"l","\u1d50":"m","\u207f":"n","\u1d52":"o","\u1d56":"p","\u02b3":"r","\u02e2":"s","\u1d57":"t","\u1d58":"u","\u1d5b":"v","\u02b7":"w","\u02e3":"x","\u02b8":"y","\u1dbb":"z","\u1d5d":"\u03b2","\u1d5e":"\u03b3","\u1d5f":"\u03b4","\u1d60":"\u03d5","\u1d61":"\u03c7","\u1dbf":"\u03b8"}),Xa={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"},"\u0327":{text:"\\c"}},Wa={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u1e09":"c\u0327\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\xe7":"c\u0327","\u010f":"d\u030c","\u1e0b":"d\u0307","\u1e11":"d\u0327","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u1e1d":"e\u0327\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u0229":"e\u0327","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u0123":"g\u0327","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\u1e29":"h\u0327","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u0137":"k\u0327","\u013a":"l\u0301","\u013e":"l\u030c","\u013c":"l\u0327","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\u0146":"n\u0327","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u0157":"r\u0327","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u015f":"s\u0327","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\u0163":"t\u0327","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u1e08":"C\u0327\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\xc7":"C\u0327","\u010e":"D\u030c","\u1e0a":"D\u0307","\u1e10":"D\u0327","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u1e1c":"E\u0327\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u0228":"E\u0327","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u0122":"G\u0327","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\u1e28":"H\u0327","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0136":"K\u0327","\u0139":"L\u0301","\u013d":"L\u030c","\u013b":"L\u0327","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\u0145":"N\u0327","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u0156":"R\u0327","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u015e":"S\u0327","\u0164":"T\u030c","\u1e6a":"T\u0307","\u0162":"T\u0327","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"};class _a{constructor(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new Ga(e,t,this.mode),this.settings=t,this.leftrightDepth=0}expect(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new i("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()}consume(){this.nextToken=null}fetch(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(e){this.mode=e,this.gullet.switchMode(e)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}}subparse(e){var t=this.nextToken;this.consume(),this.gullet.pushToken(new n("}")),this.gullet.pushTokens(e);var r=this.parseExpression(!1);return this.expect("}"),this.nextToken=t,r}parseExpression(e,t){for(var r=[];;){"math"===this.mode&&this.consumeSpaces();var a=this.fetch();if(-1!==_a.endOfExpression.indexOf(a.text))break;if(t&&a.text===t)break;if(e&&Aa[a.text]&&Aa[a.text].infix)break;var n=this.parseAtom(t);if(!n)break;"internal"!==n.type&&r.push(n)}return"text"===this.mode&&this.formLigatures(r),this.handleInfixNodes(r)}handleInfixNodes(e){for(var t,r=-1,a=0;a=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var l,h=ne[this.mode][t].group,m=a.range(e);if(re.hasOwnProperty(h)){var c=h;l={type:"atom",mode:this.mode,family:c,loc:m,text:t}}else l={type:h,mode:this.mode,loc:m,text:t};o=l}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(z(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),o={type:"textord",mode:"text",loc:a.range(e),text:t}}if(this.consume(),s)for(var p=0;p{e.exports=JSON.parse('{"title":"Components","slug":"/category/components-2","permalink":"/docs/category/components-2","navigation":{"previous":{"title":"Operating SCS","permalink":"/docs/category/operating-scs"},"next":{"title":"Status Page API","permalink":"/docs/category/status-page-api"}}}')}}]); \ No newline at end of file diff --git a/assets/js/2235.f5e36d9c.js b/assets/js/2235.f5e36d9c.js new file mode 100644 index 0000000000..04c51d1876 --- /dev/null +++ b/assets/js/2235.f5e36d9c.js @@ -0,0 +1 @@ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2235],{62954:(n,t,e)=>{n.exports=function(){function n(t,e,i){function r(a,o){if(!e[a]){if(!t[a]){if(c)return c(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var s=e[a]={exports:{}};t[a][0].call(s.exports,(function(n){return r(t[a][1][n]||n)}),s,s.exports,n,t,e,i)}return e[a].exports}for(var c=void 0,a=0;a0&&void 0!==arguments[0]?arguments[0]:{},i=e.defaultLayoutOptions,c=void 0===i?{}:i,o=e.algorithms,u=void 0===o?["layered","stress","mrtree","radial","force","disco","sporeOverlap","sporeCompaction","rectpacking"]:o,s=e.workerFactory,h=e.workerUrl;if(r(this,n),this.defaultLayoutOptions=c,this.initialized=!1,void 0===h&&void 0===s)throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'.");var f=s;void 0!==h&&void 0===s&&(f=function(n){return new Worker(n)});var l=f(h);if("function"!=typeof l.postMessage)throw new TypeError("Created worker does not provide the required 'postMessage' function.");this.worker=new a(l),this.worker.postMessage({cmd:"register",algorithms:u}).then((function(n){return t.initialized=!0})).catch(console.err)}return i(n,[{key:"layout",value:function(n){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},e=t.layoutOptions,i=void 0===e?this.defaultLayoutOptions:e,r=t.logging,c=void 0!==r&&r,a=t.measureExecutionTime,o=void 0!==a&&a;return n?this.worker.postMessage({cmd:"layout",graph:n,layoutOptions:i,options:{logging:c,measureExecutionTime:o}}):Promise.reject(new Error("Missing mandatory parameter 'graph'."))}},{key:"knownLayoutAlgorithms",value:function(){return this.worker.postMessage({cmd:"algorithms"})}},{key:"knownLayoutOptions",value:function(){return this.worker.postMessage({cmd:"options"})}},{key:"knownLayoutCategories",value:function(){return this.worker.postMessage({cmd:"categories"})}},{key:"terminateWorker",value:function(){this.worker.terminate()}}]),n}();e.default=c;var a=function(){function n(t){var e=this;if(r(this,n),void 0===t)throw new Error("Missing mandatory parameter 'worker'.");this.resolvers={},this.worker=t,this.worker.onmessage=function(n){setTimeout((function(){e.receive(e,n)}),0)}}return i(n,[{key:"postMessage",value:function(n){var t=this.id||0;this.id=t+1,n.id=t;var e=this;return new Promise((function(i,r){e.resolvers[t]=function(n,t){n?(e.convertGwtStyleError(n),r(n)):i(t)},e.worker.postMessage(n)}))}},{key:"receive",value:function(n,t){var e=t.data,i=n.resolvers[e.id];i&&(delete n.resolvers[e.id],e.error?i(e.error):i(null,e.data))}},{key:"terminate",value:function(){this.worker.terminate&&this.worker.terminate()}},{key:"convertGwtStyleError",value:function(n){if(n){var t=n.__java$exception;t&&(t.cause&&t.cause.backingJsObject&&(n.cause=t.cause.backingJsObject,this.convertGwtStyleError(n.cause)),delete n.__java$exception)}}}]),n}()},{}],2:[function(n,t,i){(function(n){(function(){"use strict";var e;function r(){}function c(){}function a(){}function o(){}function u(){}function s(){}function h(){}function f(){}function l(){}function b(){}function w(){}function d(){}function g(){}function p(){}function m(){}function v(){}function k(){}function y(){}function M(){}function T(){}function j(){}function E(){}function S(){}function P(){}function C(){}function I(){}function O(){}function A(){}function L(){}function N(){}function $(){}function D(){}function x(){}function R(){}function K(){}function F(){}function _(){}function B(){}function H(){}function U(){}function G(){}function q(){}function X(){}function z(){}function V(){}function W(){}function Q(){}function J(){}function Y(){}function Z(){}function nn(){}function tn(){}function en(){}function rn(){}function cn(){}function an(){}function on(){}function un(){}function sn(){}function hn(){}function fn(){}function ln(){}function bn(){}function wn(){}function dn(){}function gn(){}function pn(){}function mn(){}function vn(){}function kn(){}function yn(){}function Mn(){}function Tn(){}function jn(){}function En(){}function Sn(){}function Pn(){}function Cn(){}function In(){}function On(){}function An(){}function Ln(){}function Nn(){}function $n(){}function Dn(){}function xn(){}function Rn(){}function Kn(){}function Fn(){}function _n(){}function Bn(){}function Hn(){}function Un(){}function Gn(){}function qn(){}function Xn(){}function zn(){}function Vn(){}function Wn(){}function Qn(){}function Jn(){}function Yn(){}function Zn(){}function nt(){}function tt(){}function et(){}function it(){}function rt(){}function ct(){}function at(){}function ot(){}function ut(){}function st(){}function ht(){}function ft(){}function lt(){}function bt(){}function wt(){}function dt(){}function gt(){}function pt(){}function mt(){}function vt(){}function kt(){}function yt(){}function Mt(){}function Tt(){}function jt(){}function Et(){}function St(){}function Pt(){}function Ct(){}function It(){}function Ot(){}function At(){}function Lt(){}function Nt(){}function $t(){}function Dt(){}function xt(){}function Rt(){}function Kt(){}function Ft(){}function _t(){}function Bt(){}function Ht(){}function Ut(){}function Gt(){}function qt(){}function Xt(){}function zt(){}function Vt(){}function Wt(){}function Qt(){}function Jt(){}function Yt(){}function Zt(){}function ne(){}function te(){}function ee(){}function ie(){}function re(){}function ce(){}function ae(){}function oe(){}function ue(){}function se(){}function he(){}function fe(){}function le(){}function be(){}function we(){}function de(){}function ge(){}function pe(){}function me(){}function ve(){}function ke(){}function ye(){}function Me(){}function Te(){}function je(){}function Ee(){}function Se(){}function Pe(){}function Ce(){}function Ie(){}function Oe(){}function Ae(){}function Le(){}function Ne(){}function $e(){}function De(){}function xe(){}function Re(){}function Ke(){}function Fe(){}function _e(){}function Be(){}function He(){}function Ue(){}function Ge(){}function qe(){}function Xe(){}function ze(){}function Ve(){}function We(){}function Qe(){}function Je(){}function Ye(){}function Ze(){}function ni(){}function ti(){}function ei(){}function ii(){}function ri(){}function ci(){}function ai(){}function oi(){}function ui(){}function si(){}function hi(){}function fi(){}function li(){}function bi(){}function wi(){}function di(){}function gi(){}function pi(){}function mi(){}function vi(){}function ki(){}function yi(){}function Mi(){}function Ti(){}function ji(){}function Ei(){}function Si(){}function Pi(){}function Ci(){}function Ii(){}function Oi(){}function Ai(){}function Li(){}function Ni(){}function $i(){}function Di(){}function xi(){}function Ri(){}function Ki(){}function Fi(){}function _i(){}function Bi(){}function Hi(){}function Ui(){}function Gi(){}function qi(){}function Xi(){}function zi(){}function Vi(){}function Wi(){}function Qi(){}function Ji(){}function Yi(){}function Zi(){}function nr(){}function tr(){}function er(){}function ir(){}function rr(){}function cr(){}function ar(){}function or(){}function ur(){}function sr(){}function hr(){}function fr(){}function lr(){}function br(){}function wr(){}function dr(){}function gr(){}function pr(){}function mr(){}function vr(){}function kr(){}function yr(){}function Mr(){}function Tr(){}function jr(){}function Er(){}function Sr(){}function Pr(){}function Cr(){}function Ir(){}function Or(){}function Ar(){}function Lr(){}function Nr(){}function $r(){}function Dr(){}function xr(){}function Rr(){}function Kr(){}function Fr(){}function _r(){}function Br(){}function Hr(){}function Ur(){}function Gr(){}function qr(){}function Xr(){}function zr(){}function Vr(){}function Wr(){}function Qr(){}function Jr(){}function Yr(){}function Zr(){}function nc(){}function tc(){}function ec(){}function ic(){}function rc(){}function cc(){}function ac(){}function oc(){}function uc(){}function sc(){}function hc(){}function fc(){}function lc(){}function bc(){}function wc(){}function dc(){}function gc(){}function pc(){}function mc(){}function vc(){}function kc(){}function yc(){}function Mc(){}function Tc(){}function jc(){}function Ec(){}function Sc(){}function Pc(){}function Cc(){}function Ic(){}function Oc(){}function Ac(){}function Lc(){}function Nc(){}function $c(){}function Dc(){}function xc(){}function Rc(){}function Kc(){}function Fc(){}function _c(){}function Bc(){}function Hc(){}function Uc(){}function Gc(){}function qc(){}function Xc(){}function zc(){}function Vc(){}function Wc(){}function Qc(){}function Jc(){}function Yc(){}function Zc(){}function na(){}function ta(){}function ea(){}function ia(){}function ra(){}function ca(){}function aa(){}function oa(){}function ua(){}function sa(){}function ha(){}function fa(){}function la(){}function ba(){}function wa(){}function da(){}function ga(){}function pa(){}function ma(){}function va(){}function ka(){}function ya(){}function Ma(){}function Ta(){}function ja(){}function Ea(){}function Sa(){}function Pa(){}function Ca(){}function Ia(){}function Oa(){}function Aa(){}function La(){}function Na(){}function $a(){}function Da(){}function xa(){}function Ra(){}function Ka(){}function Fa(){}function _a(){}function Ba(){}function Ha(){}function Ua(){}function Ga(){}function qa(){}function Xa(){}function za(){}function Va(){}function Wa(){}function Qa(){}function Ja(){}function Ya(){}function Za(){}function no(){}function to(){}function eo(){}function io(){}function ro(){}function co(){}function ao(){}function oo(){}function uo(){}function so(){}function ho(){}function fo(){}function lo(){}function bo(){}function wo(){}function go(){}function po(){}function mo(){}function vo(){}function ko(){}function yo(){}function Mo(){}function To(){}function jo(){}function Eo(){}function So(){}function Po(){}function Co(){}function Io(){}function Oo(){}function Ao(){}function Lo(){}function No(){}function $o(){}function Do(){}function xo(){}function Ro(){}function Ko(){}function Fo(){}function _o(){}function Bo(){}function Ho(){}function Uo(){}function Go(){}function qo(){}function Xo(){}function zo(){}function Vo(){}function Wo(){}function Qo(){}function Jo(){}function Yo(){}function Zo(){}function nu(){}function tu(){}function eu(){}function iu(){}function ru(){}function cu(){}function au(){}function ou(){}function uu(){}function su(){}function hu(){}function fu(){}function lu(){}function bu(){}function wu(){}function du(){}function gu(){}function pu(){}function mu(){}function vu(){}function ku(){}function yu(){}function Mu(){}function Tu(){}function ju(){}function Eu(){}function Su(){}function Pu(){}function Cu(){}function Iu(){}function Ou(){}function Au(){}function Lu(){}function Nu(){}function $u(){}function Du(){}function xu(){}function Ru(){}function Ku(){}function Fu(){}function _u(){}function Bu(){}function Hu(){}function Uu(){}function Gu(){}function qu(){}function Xu(){}function zu(){}function Vu(){}function Wu(){}function Qu(){}function Ju(){}function Yu(){}function Zu(){}function ns(){}function ts(){}function es(){}function is(){}function rs(){}function cs(){}function as(){}function os(){}function us(){}function ss(){}function hs(){}function fs(){}function ls(){}function bs(){}function ws(){}function ds(){}function gs(){}function ps(){}function ms(){}function vs(){}function ks(){}function ys(){}function Ms(){}function Ts(){}function js(){}function Es(){}function Ss(){}function Ps(){}function Cs(){}function Is(){}function Os(){}function As(){}function Ls(){}function Ns(){}function $s(){}function Ds(){}function xs(){}function Rs(){}function Ks(){}function Fs(){}function _s(){}function Bs(){}function Hs(){}function Us(){}function Gs(){}function qs(){}function Xs(){}function zs(){}function Vs(){}function Ws(){}function Qs(){}function Js(){}function Ys(){}function Zs(){}function nh(){}function th(){}function eh(){}function ih(){}function rh(){}function ch(){}function ah(){}function oh(){}function uh(){}function sh(){}function hh(){}function fh(){}function lh(){}function bh(){}function wh(){}function dh(){}function gh(){}function ph(){}function mh(){}function vh(){}function kh(){}function yh(){}function Mh(){}function Th(){}function jh(){}function Eh(){}function Sh(){}function Ph(){}function Ch(){}function Ih(){}function Oh(){}function Ah(){}function Lh(){}function Nh(){}function $h(){}function Dh(){}function xh(){}function Rh(){}function Kh(){}function Fh(){}function _h(){}function Bh(){}function Hh(){}function Uh(){}function Gh(){}function qh(){}function Xh(){}function zh(){}function Vh(){}function Wh(){}function Qh(){}function Jh(){}function Yh(){}function Zh(){}function nf(){}function tf(){}function ef(){}function rf(){}function cf(){}function af(){}function of(){}function uf(){}function sf(){}function hf(){}function ff(){}function lf(){}function bf(){}function wf(){}function df(){}function gf(){}function pf(){}function mf(){}function vf(){}function kf(){}function yf(){}function Mf(){}function Tf(){}function jf(){}function Ef(){}function Sf(){}function Pf(){}function Cf(){}function If(){}function Of(){}function Af(){}function Lf(){}function Nf(){}function $f(){}function Df(){}function xf(){}function Rf(n){}function Kf(n){}function Ff(){gy()}function _f(){VS()}function Bf(){MEn()}function Hf(){pbn()}function Uf(){ryn()}function Gf(){oOn()}function qf(){cGn()}function Xf(){yjn()}function zf(){Bjn()}function Vf(){WS()}function Wf(){HB()}function Qf(){QS()}function Jf(){Pun()}function Yf(){F7()}function Zf(){Ean()}function nl(){Y0()}function tl(){Pan()}function el(){Unn()}function il(){Q0()}function rl(){Cln()}function cl(){Ian()}function al(){Can()}function ol(){c6()}function ul(){Oan()}function sl(){jIn()}function hl(){YS()}function fl(){VYn()}function ll(){jYn()}function bl(){Aan()}function wl(){Iun()}function dl(){Z0()}function gl(){Pjn()}function pl(){t2()}function ml(){gUn()}function vl(){eDn()}function kl(){tcn()}function yl(){Kdn()}function Ml(){QGn()}function Tl(){e3()}function jl(){ncn()}function El(){EHn()}function Sl(){jOn()}function Pl(){IHn()}function Cl(){S_n()}function Il(){fIn()}function Ol(){uBn()}function Al(){jMn()}function Ll(){oB()}function Nl(){Stn()}function $l(){lIn()}function Dl(){XYn()}function xl(){Iln()}function Rl(){Wmn()}function Kl(){Oun()}function Fl(){tXn()}function _l(){vGn()}function Bl(n){tJ(n)}function Hl(n){this.a=n}function Ul(n){this.a=n}function Gl(n){this.a=n}function ql(n){this.a=n}function Xl(n){this.a=n}function zl(n){this.a=n}function Vl(n){this.a=n}function Wl(n){this.a=n}function Ql(n){this.a=n}function Jl(n){this.a=n}function Yl(n){this.a=n}function Zl(n){this.a=n}function nb(n){this.a=n}function tb(n){this.a=n}function eb(n){this.a=n}function ib(n){this.a=n}function rb(n){this.a=n}function cb(n){this.a=n}function ab(n){this.a=n}function ob(n){this.a=n}function ub(n){this.a=n}function sb(n){this.a=n}function hb(n){this.b=n}function fb(n){this.c=n}function lb(n){this.a=n}function bb(n){this.a=n}function wb(n){this.a=n}function db(n){this.a=n}function gb(n){this.a=n}function pb(n){this.a=n}function mb(n){this.a=n}function vb(n){this.a=n}function kb(n){this.a=n}function yb(n){this.a=n}function Mb(n){this.a=n}function Tb(n){this.a=n}function jb(n){this.a=n}function Eb(n){this.a=n}function Sb(n){this.a=n}function Pb(n){this.a=n}function Cb(n){this.a=n}function Ib(){this.a=[]}function Ob(n,t){n.a=t}function Ab(n,t){n.a=t}function Lb(n,t){n.b=t}function Nb(n,t){n.b=t}function $b(n,t){n.b=t}function Db(n,t){n.j=t}function xb(n,t){n.g=t}function Rb(n,t){n.i=t}function Kb(n,t){n.c=t}function Fb(n,t){n.c=t}function _b(n,t){n.d=t}function Bb(n,t){n.d=t}function Hb(n,t){n.k=t}function Ub(n,t){n.c=t}function Gb(n,t){n.c=t}function qb(n,t){n.a=t}function Xb(n,t){n.a=t}function zb(n,t){n.f=t}function Vb(n,t){n.a=t}function Wb(n,t){n.b=t}function Qb(n,t){n.d=t}function Jb(n,t){n.i=t}function Yb(n,t){n.o=t}function Zb(n,t){n.r=t}function nw(n,t){n.a=t}function tw(n,t){n.b=t}function ew(n,t){n.e=t}function iw(n,t){n.f=t}function rw(n,t){n.g=t}function cw(n,t){n.e=t}function aw(n,t){n.f=t}function ow(n,t){n.f=t}function uw(n,t){n.a=t}function sw(n,t){n.b=t}function hw(n,t){n.n=t}function fw(n,t){n.a=t}function lw(n,t){n.c=t}function bw(n,t){n.c=t}function ww(n,t){n.c=t}function dw(n,t){n.a=t}function gw(n,t){n.a=t}function pw(n,t){n.d=t}function mw(n,t){n.d=t}function vw(n,t){n.e=t}function kw(n,t){n.e=t}function yw(n,t){n.g=t}function Mw(n,t){n.f=t}function Tw(n,t){n.j=t}function jw(n,t){n.a=t}function Ew(n,t){n.a=t}function Sw(n,t){n.b=t}function Pw(n){n.b=n.a}function Cw(n){n.c=n.d.d}function Iw(n){this.a=n}function Ow(n){this.a=n}function Aw(n){this.a=n}function Lw(n){this.a=n}function Nw(n){this.a=n}function $w(n){this.a=n}function Dw(n){this.a=n}function xw(n){this.a=n}function Rw(n){this.a=n}function Kw(n){this.a=n}function Fw(n){this.a=n}function _w(n){this.a=n}function Bw(n){this.a=n}function Hw(n){this.a=n}function Uw(n){this.b=n}function Gw(n){this.b=n}function qw(n){this.b=n}function Xw(n){this.a=n}function zw(n){this.a=n}function Vw(n){this.c=n}function Ww(n){this.c=n}function Qw(n){this.c=n}function Jw(n){this.d=n}function Yw(n){this.a=n}function Zw(n){this.a=n}function nd(n){this.a=n}function td(n){this.a=n}function ed(n){this.a=n}function id(n){this.a=n}function rd(n){this.a=n}function cd(n){this.a=n}function ad(n){this.a=n}function od(n){this.a=n}function ud(n){this.a=n}function sd(n){this.a=n}function hd(n){this.a=n}function fd(n){this.a=n}function ld(n){this.a=n}function bd(n){this.a=n}function wd(n){this.a=n}function dd(n){this.a=n}function gd(n){this.a=n}function pd(n){this.a=n}function md(n){this.a=n}function vd(n){this.a=n}function kd(n){this.a=n}function yd(n){this.a=n}function Md(n){this.a=n}function Td(n){this.a=n}function jd(n){this.a=n}function Ed(n){this.a=n}function Sd(n){this.a=n}function Pd(n){this.a=n}function Cd(n){this.a=n}function Id(n){this.a=n}function Od(n){this.a=n}function Ad(n){this.a=n}function Ld(n){this.a=n}function Nd(n){this.a=n}function $d(n){this.a=n}function Dd(n){this.a=n}function xd(n){this.a=n}function Rd(n){this.a=n}function Kd(n){this.a=n}function Fd(n){this.a=n}function _d(n){this.a=n}function Bd(n){this.a=n}function Hd(n){this.a=n}function Ud(n){this.a=n}function Gd(n){this.a=n}function qd(n){this.a=n}function Xd(n){this.e=n}function zd(n){this.a=n}function Vd(n){this.a=n}function Wd(n){this.a=n}function Qd(n){this.a=n}function Jd(n){this.a=n}function Yd(n){this.a=n}function Zd(n){this.a=n}function ng(n){this.a=n}function tg(n){this.a=n}function eg(n){this.a=n}function ig(n){this.a=n}function rg(n){this.a=n}function cg(n){this.a=n}function ag(n){this.a=n}function og(n){this.a=n}function ug(n){this.a=n}function sg(n){this.a=n}function hg(n){this.a=n}function fg(n){this.a=n}function lg(n){this.a=n}function bg(n){this.a=n}function wg(n){this.a=n}function dg(n){this.a=n}function gg(n){this.a=n}function pg(n){this.a=n}function mg(n){this.a=n}function vg(n){this.a=n}function kg(n){this.a=n}function yg(n){this.a=n}function Mg(n){this.a=n}function Tg(n){this.a=n}function jg(n){this.a=n}function Eg(n){this.a=n}function Sg(n){this.a=n}function Pg(n){this.a=n}function Cg(n){this.a=n}function Ig(n){this.a=n}function Og(n){this.a=n}function Ag(n){this.a=n}function Lg(n){this.a=n}function Ng(n){this.a=n}function $g(n){this.a=n}function Dg(n){this.a=n}function xg(n){this.a=n}function Rg(n){this.a=n}function Kg(n){this.a=n}function Fg(n){this.a=n}function _g(n){this.a=n}function Bg(n){this.a=n}function Hg(n){this.a=n}function Ug(n){this.a=n}function Gg(n){this.a=n}function qg(n){this.a=n}function Xg(n){this.a=n}function zg(n){this.c=n}function Vg(n){this.b=n}function Wg(n){this.a=n}function Qg(n){this.a=n}function Jg(n){this.a=n}function Yg(n){this.a=n}function Zg(n){this.a=n}function np(n){this.a=n}function tp(n){this.a=n}function ep(n){this.a=n}function ip(n){this.a=n}function rp(n){this.a=n}function cp(n){this.a=n}function ap(n){this.a=n}function op(n){this.a=n}function up(n){this.a=n}function sp(n){this.a=n}function hp(n){this.a=n}function fp(n){this.a=n}function lp(n){this.a=n}function bp(n){this.a=n}function wp(n){this.a=n}function dp(n){this.a=n}function gp(n){this.a=n}function pp(n){this.a=n}function mp(n){this.a=n}function vp(n){this.a=n}function kp(n){this.a=n}function yp(n){this.a=n}function Mp(n){this.a=n}function Tp(n){this.a=n}function jp(n){this.a=n}function Ep(n){this.a=n}function Sp(n){this.a=n}function Pp(n){this.a=n}function Cp(n){this.a=n}function Ip(n){this.a=n}function Op(n){this.a=n}function Ap(n){this.a=n}function Lp(n){this.a=n}function Np(n){this.a=n}function $p(n){this.a=n}function Dp(n){this.a=n}function xp(n){this.a=n}function Rp(n){this.a=n}function Kp(n){this.a=n}function Fp(n){this.a=n}function _p(n){this.a=n}function Bp(n){this.a=n}function Hp(n){this.a=n}function Up(n){this.a=n}function Gp(n){this.a=n}function qp(n){this.a=n}function Xp(n){this.a=n}function zp(n){this.a=n}function Vp(n){this.a=n}function Wp(n){this.a=n}function Qp(n){this.a=n}function Jp(n){this.f=n}function Yp(n){this.a=n}function Zp(n){this.a=n}function nm(n){this.a=n}function tm(n){this.a=n}function em(n){this.a=n}function im(n){this.a=n}function rm(n){this.a=n}function cm(n){this.a=n}function am(n){this.a=n}function om(n){this.a=n}function um(n){this.a=n}function sm(n){this.a=n}function hm(n){this.a=n}function fm(n){this.a=n}function lm(n){this.a=n}function bm(n){this.a=n}function wm(n){this.a=n}function dm(n){this.a=n}function gm(n){this.a=n}function pm(n){this.a=n}function mm(n){this.a=n}function vm(n){this.a=n}function km(n){this.a=n}function ym(n){this.a=n}function Mm(n){this.a=n}function Tm(n){this.a=n}function jm(n){this.a=n}function Em(n){this.a=n}function Sm(n){this.a=n}function Pm(n){this.a=n}function Cm(n){this.b=n}function Im(n){this.a=n}function Om(n){this.a=n}function Am(n){this.a=n}function Lm(n){this.a=n}function Nm(n){this.a=n}function $m(n){this.a=n}function Dm(n){this.a=n}function xm(n){this.b=n}function Rm(n){this.a=n}function Km(n){this.a=n}function Fm(n){this.a=n}function _m(n){this.a=n}function Bm(n){this.c=n}function Hm(n){this.e=n}function Um(n){this.a=n}function Gm(n){this.a=n}function qm(n){this.a=n}function Xm(n){this.d=n}function zm(n){this.a=n}function Vm(n){this.a=n}function Wm(n){this.a=n}function Qm(n){this.e=n}function Jm(){this.a=0}function Ym(){$V(this)}function Zm(){IN(this)}function nv(){XQ(this)}function tv(){Rf(this)}function ev(){this.c=nBt}function iv(n,t){n.b+=t}function rv(n,t){t.Wb(n)}function cv(n){return n.a}function av(n){return n.a}function ov(n){return n.a}function uv(n){return n.a}function sv(n){return n.a}function hv(n){return n.e}function fv(){return null}function lv(){return null}function bv(){mj(),xJn()}function wv(n){n.b.Of(n.e)}function dv(n){n.b=new rT}function gv(n,t){n.b=t-n.b}function pv(n,t){n.a=t-n.a}function mv(n,t){n.push(t)}function vv(n,t){n.sort(t)}function kv(n,t){t.jd(n.a)}function yv(n,t){NLn(t,n)}function Mv(n,t,e){n.Yd(e,t)}function Tv(n,t){n.e=t,t.b=n}function jv(n){sB(),this.a=n}function Ev(n){sB(),this.a=n}function Sv(n){sB(),this.a=n}function Pv(n){ZW(),this.a=n}function Cv(n){EZ(),_at.le(n)}function Iv(){Iv=E,new Ym}function Ov(){vx.call(this)}function Av(){vx.call(this)}function Lv(){Ov.call(this)}function Nv(){Ov.call(this)}function $v(){Ov.call(this)}function Dv(){Ov.call(this)}function xv(){Ov.call(this)}function Rv(){Ov.call(this)}function Kv(){Ov.call(this)}function Fv(){Ov.call(this)}function _v(){Ov.call(this)}function Bv(){Ov.call(this)}function Hv(){Ov.call(this)}function Uv(){this.a=this}function Gv(){this.Bb|=256}function qv(){this.b=new hL}function Xv(n,t){n.length=t}function zv(n,t){kD(n.a,t)}function Vv(n,t){LOn(n.c,t)}function Wv(n,t){FV(n.b,t)}function Qv(n,t){bMn(n.a,t)}function Jv(n,t){Vdn(n.a,t)}function Yv(n,t){Msn(n.e,t)}function Zv(n){C$n(n.c,n.b)}function nk(n,t){n.kc().Nb(t)}function tk(n){this.a=Agn(n)}function ek(){this.a=new Ym}function ik(){this.a=new Ym}function rk(){this.a=new hS}function ck(){this.a=new Zm}function ak(){this.a=new Zm}function ok(){this.a=new Zm}function uk(){this.a=new kn}function sk(){this.a=new g7}function hk(){this.a=new lt}function fk(){this.a=new V0}function lk(){this.a=new NF}function bk(){this.a=new Zm}function wk(){this.a=new Zm}function dk(){this.a=new Zm}function gk(){this.a=new Zm}function pk(){this.d=new Zm}function mk(){this.a=new i4}function vk(){this.a=new ek}function kk(){this.a=new Ym}function yk(){this.b=new Ym}function Mk(){this.b=new Zm}function Tk(){this.e=new Zm}function jk(){this.a=new sl}function Ek(){this.d=new Zm}function Sk(){BZ.call(this)}function Pk(){BZ.call(this)}function Ck(){Zm.call(this)}function Ik(){Lv.call(this)}function Ok(){ck.call(this)}function Ak(){HF.call(this)}function Lk(){gk.call(this)}function Nk(){tv.call(this)}function $k(){Nk.call(this)}function Dk(){tv.call(this)}function xk(){Dk.call(this)}function Rk(){oy.call(this)}function Kk(){oy.call(this)}function Fk(){oy.call(this)}function _k(){hy.call(this)}function Bk(){ts.call(this)}function Hk(){ts.call(this)}function Uk(){lS.call(this)}function Gk(){wy.call(this)}function qk(){wy.call(this)}function Xk(){Ym.call(this)}function zk(){Ym.call(this)}function Vk(){Ym.call(this)}function Wk(){Kan.call(this)}function Qk(){ek.call(this)}function Jk(){Gv.call(this)}function Yk(){$D.call(this)}function Zk(){Ym.call(this)}function ny(){$D.call(this)}function ty(){Ym.call(this)}function ey(){Ym.call(this)}function iy(){ps.call(this)}function ry(){iy.call(this)}function cy(){ps.call(this)}function ay(){$f.call(this)}function oy(){this.a=new ek}function uy(){this.a=new Ym}function sy(){this.a=new Zm}function hy(){this.a=new Ym}function fy(){this.a=new lS}function ly(){this.j=new Zm}function by(){this.a=new zj}function wy(){this.a=new gs}function dy(){this.a=new Do}function gy(){gy=E,wat=new c}function py(){py=E,Mat=new ky}function my(){my=E,Tat=new vy}function vy(){ib.call(this,"")}function ky(){ib.call(this,"")}function yy(n){Arn.call(this,n)}function My(n){Arn.call(this,n)}function Ty(n){Ql.call(this,n)}function jy(n){HE.call(this,n)}function Ey(n){HE.call(this,n)}function Sy(n){jy.call(this,n)}function Py(n){jy.call(this,n)}function Cy(n){jy.call(this,n)}function Iy(n){c8.call(this,n)}function Oy(n){c8.call(this,n)}function Ay(n){K_.call(this,n)}function Ly(n){XE.call(this,n)}function Ny(n){WE.call(this,n)}function $y(n){WE.call(this,n)}function Dy(n){WE.call(this,n)}function xy(n){cOn.call(this,n)}function Ry(n){xy.call(this,n)}function Ky(n){Uz.call(this,n)}function Fy(n){Ky.call(this,n)}function _y(){Cb.call(this,{})}function By(){By=E,Vat=new T}function Hy(){Hy=E,Iat=new X$}function Uy(){Uy=E,Dat=new r}function Gy(){Gy=E,Fat=new p}function qy(){qy=E,Hat=new k}function Xy(n){UD(),this.a=n}function zy(n){Cun(),this.a=n}function Vy(n){rz(),this.f=n}function Wy(n){rz(),this.f=n}function Qy(n){aB(),this.a=n}function Jy(n){n.b=null,n.c=0}function Yy(n,t){n.e=t,yFn(n,t)}function Zy(n,t){n.a=t,WAn(n)}function nM(n,t,e){n.a[t.g]=e}function tM(n,t,e){nSn(e,n,t)}function eM(n,t){F_(t.i,n.n)}function iM(n,t){yln(n).Cd(t)}function rM(n,t){n.a.ec().Mc(t)}function cM(n,t){return n.g-t.g}function aM(n,t){return n*n/t}function oM(n){return tJ(n),n}function uM(n){return tJ(n),n}function sM(n){return tJ(n),n}function hM(n){return new Pb(n)}function fM(n){return new QW(n)}function lM(n){return tJ(n),n}function bM(n){return tJ(n),n}function wM(n){Ky.call(this,n)}function dM(n){Ky.call(this,n)}function gM(n){Ky.call(this,n)}function pM(n){Uz.call(this,n)}function mM(n){Ky.call(this,n)}function vM(n){Ky.call(this,n)}function kM(n){Ky.call(this,n)}function yM(n){Ky.call(this,n)}function MM(n){Ky.call(this,n)}function TM(n){Ky.call(this,n)}function jM(n){Ky.call(this,n)}function EM(n){Ky.call(this,n)}function SM(n){Ky.call(this,n)}function PM(n){Ky.call(this,n)}function CM(n){Ky.call(this,n)}function IM(n){tJ(n),this.a=n}function OM(n){return hln(n),n}function AM(n){zV(n,n.length)}function LM(n){return n.b==n.c}function NM(n){return!!n&&n.b}function $M(n){return!!n&&n.k}function DM(n){return!!n&&n.j}function xM(n,t,e){n.c.Ef(t,e)}function RM(n,t){n.be(t),t.ae(n)}function KM(n){sB(),this.a=WW(n)}function FM(){this.a=mK(WW(TZn))}function _M(){throw hv(new Kv)}function BM(){throw hv(new Kv)}function HM(){throw hv(new Kv)}function UM(){throw hv(new Kv)}function GM(){throw hv(new Kv)}function qM(){throw hv(new Kv)}function XM(){XM=E,EZ()}function zM(){$w.call(this,"")}function VM(){$w.call(this,"")}function WM(){$w.call(this,"")}function QM(){$w.call(this,"")}function JM(n){dM.call(this,n)}function YM(n){dM.call(this,n)}function ZM(n){vM.call(this,n)}function nT(n){qw.call(this,n)}function tT(n){nT.call(this,n)}function eT(n){gx.call(this,n)}function iT(n){Qx.call(this,n,0)}function rT(){L2.call(this,12,3)}function cT(n,t){return B0(n,t)}function aT(n,t){return Ltn(n,t)}function oT(n,t){return n.a-t.a}function uT(n,t){return n.a-t.a}function sT(n,t){return n.a-t.a}function hT(n,t){return t in n.a}function fT(n){return n.a?n.b:0}function lT(n){return n.a?n.b:0}function bT(n,t,e){t.Cd(n.a[e])}function wT(n,t,e){t.Pe(n.a[e])}function dT(n,t){n.b=new eN(t)}function gT(n,t){return n.b=t,n}function pT(n,t){return n.c=t,n}function mT(n,t){return n.f=t,n}function vT(n,t){return n.g=t,n}function kT(n,t){return n.a=t,n}function yT(n,t){return n.f=t,n}function MT(n,t){return n.k=t,n}function TT(n,t){return n.a=t,n}function jT(n,t){return n.e=t,n}function ET(n,t){return n.e=t,n}function ST(n,t){return n.f=t,n}function PT(n,t){n.b=!0,n.d=t}function CT(n,t){return n.b-t.b}function IT(n,t){return n.g-t.g}function OT(n,t){return n?0:t-1}function AT(n,t){return n?0:t-1}function LT(n,t){return n?t-1:0}function NT(n,t){return n.s-t.s}function $T(n,t){return t.rg(n)}function DT(n,t){return n.b=t,n}function xT(n,t){return n.a=t,n}function RT(n,t){return n.c=t,n}function KT(n,t){return n.d=t,n}function FT(n,t){return n.e=t,n}function _T(n,t){return n.f=t,n}function BT(n,t){return n.a=t,n}function HT(n,t){return n.b=t,n}function UT(n,t){return n.c=t,n}function GT(n,t){return n.c=t,n}function qT(n,t){return n.b=t,n}function XT(n,t){return n.d=t,n}function zT(n,t){return n.e=t,n}function VT(n,t){return n.f=t,n}function WT(n,t){return n.g=t,n}function QT(n,t){return n.a=t,n}function JT(n,t){return n.i=t,n}function YT(n,t){return n.j=t,n}function ZT(n,t){jIn(),o2(t,n)}function nj(n,t,e){az(n.a,t,e)}function tj(n){Y_.call(this,n)}function ej(n){dpn.call(this,n)}function ij(n){TY.call(this,n)}function rj(n){TY.call(this,n)}function cj(n){Drn.call(this,n)}function aj(n){HY.call(this,n)}function oj(n){HY.call(this,n)}function uj(){S$.call(this,"")}function sj(){this.a=0,this.b=0}function hj(){this.b=0,this.a=0}function fj(n,t){n.b=0,Ccn(n,t)}function lj(n,t){return n.k=t,n}function bj(n,t){return n.j=t,n}function wj(n,t){n.c=t,n.b=!0}function dj(){dj=E,rut=ePn()}function gj(){gj=E,xKt=AEn()}function pj(){pj=E,RKt=VPn()}function mj(){mj=E,NFt=aan()}function vj(){vj=E,y_t=LEn()}function kj(){kj=E,xBt=NEn()}function yj(){yj=E,RBt=qAn()}function Mj(n){return n.e&&n.e()}function Tj(n){return n.l|n.m<<22}function jj(n,t){return n.c._b(t)}function Ej(n,t){return Uwn(n.b,t)}function Sj(n){return n?n.d:null}function Pj(n){return n?n.g:null}function Cj(n){return n?n.i:null}function Ij(n){return vK(n),n.o}function Oj(n,t){return n.a+=t,n}function Aj(n,t){return n.a+=t,n}function Lj(n,t){return n.a+=t,n}function Nj(n,t){return n.a+=t,n}function $j(n,t){for(;n.Bd(t););}function Dj(n){this.a=new sS(n)}function xj(){throw hv(new Kv)}function Rj(){throw hv(new Kv)}function Kj(){throw hv(new Kv)}function Fj(){throw hv(new Kv)}function _j(){throw hv(new Kv)}function Bj(){throw hv(new Kv)}function Hj(n){this.a=new Hz(n)}function Uj(){this.a=new mKn(iIt)}function Gj(){this.b=new mKn(ZSt)}function qj(){this.a=new mKn(dOt)}function Xj(){this.b=new mKn(VAt)}function zj(){this.b=new mKn(VAt)}function Vj(n){this.a=0,this.b=n}function Wj(n){CQn(),uYn(this,n)}function Qj(n){return GQ(n),n.a}function Jj(n){return n.b!=n.d.c}function Yj(n,t){return n.d[t.p]}function Zj(n,t){return vFn(n,t)}function nE(n,t,e){n.splice(t,e)}function tE(n,t){for(;n.Re(t););}function eE(n){n.c?P_n(n):C_n(n)}function iE(){throw hv(new Kv)}function rE(){throw hv(new Kv)}function cE(){throw hv(new Kv)}function aE(){throw hv(new Kv)}function oE(){throw hv(new Kv)}function uE(){throw hv(new Kv)}function sE(){throw hv(new Kv)}function hE(){throw hv(new Kv)}function fE(){throw hv(new Kv)}function lE(){throw hv(new Kv)}function bE(){throw hv(new Bv)}function wE(){throw hv(new Bv)}function dE(n){this.a=new gE(n)}function gE(n){Zan(this,n,fOn())}function pE(n){return!n||FQ(n)}function mE(n){return-1!=dHt[n]}function vE(){0!=Uat&&(Uat=0),qat=-1}function kE(){null==hZn&&(hZn=[])}function yE(n,t){RD.call(this,n,t)}function ME(n,t){yE.call(this,n,t)}function TE(n,t){this.a=n,this.b=t}function jE(n,t){this.a=n,this.b=t}function EE(n,t){this.a=n,this.b=t}function SE(n,t){this.a=n,this.b=t}function PE(n,t){this.a=n,this.b=t}function CE(n,t){this.a=n,this.b=t}function IE(n,t){this.a=n,this.b=t}function OE(n,t){this.e=n,this.d=t}function AE(n,t){this.b=n,this.c=t}function LE(n,t){this.b=n,this.a=t}function NE(n,t){this.b=n,this.a=t}function $E(n,t){this.b=n,this.a=t}function DE(n,t){this.b=n,this.a=t}function xE(n,t){this.a=n,this.b=t}function RE(n,t){this.a=n,this.b=t}function KE(n,t){this.a=n,this.f=t}function FE(n,t){this.g=n,this.i=t}function _E(n,t){this.f=n,this.g=t}function BE(n,t){this.b=n,this.c=t}function HE(n){FD(n.dc()),this.c=n}function UE(n,t){this.a=n,this.b=t}function GE(n,t){this.a=n,this.b=t}function qE(n){this.a=uG(WW(n),15)}function XE(n){this.a=uG(WW(n),15)}function zE(n){this.a=uG(WW(n),85)}function VE(n){this.b=uG(WW(n),85)}function WE(n){this.b=uG(WW(n),51)}function QE(){this.q=new e.Date}function JE(n,t){this.a=n,this.b=t}function YE(n,t){return PV(n.b,t)}function ZE(n,t){return n.b.Hc(t)}function nS(n,t){return n.b.Ic(t)}function tS(n,t){return n.b.Qc(t)}function eS(n,t){return n.b.Hc(t)}function iS(n,t){return n.c.uc(t)}function rS(n,t){return udn(n.c,t)}function cS(n,t){return n.a._b(t)}function aS(n,t){return n>t&&t0}function $P(n,t){return dwn(n,t)<0}function DP(n,t){return RX(n.a,t)}function xP(n,t){U0.call(this,n,t)}function RP(n){nQ(),K_.call(this,n)}function KP(n,t){zX(n,n.length,t)}function FP(n,t){dW(n,n.length,t)}function _P(n,t){return n.a.get(t)}function BP(n,t){return PV(n.e,t)}function HP(n){return tJ(n),!1}function UP(n){this.a=uG(WW(n),229)}function GP(n){h3.call(this,n,21)}function qP(n,t){_E.call(this,n,t)}function XP(n,t){_E.call(this,n,t)}function zP(n,t){this.b=n,this.a=t}function VP(n,t){this.d=n,this.e=t}function WP(n,t){this.a=n,this.b=t}function QP(n,t){this.a=n,this.b=t}function JP(n,t){this.a=n,this.b=t}function YP(n,t){this.a=n,this.b=t}function ZP(n,t){this.a=n,this.b=t}function nC(n,t){this.b=n,this.a=t}function tC(n,t){this.b=n,this.a=t}function eC(n,t){_E.call(this,n,t)}function iC(n,t){_E.call(this,n,t)}function rC(n,t){_E.call(this,n,t)}function cC(n,t){_E.call(this,n,t)}function aC(n,t){_E.call(this,n,t)}function oC(n,t){_E.call(this,n,t)}function uC(n,t){_E.call(this,n,t)}function sC(n,t){this.b=n,this.a=t}function hC(n,t){_E.call(this,n,t)}function fC(n,t){this.b=n,this.a=t}function lC(n,t){_E.call(this,n,t)}function bC(n,t){this.b=n,this.a=t}function wC(n,t){_E.call(this,n,t)}function dC(n,t){_E.call(this,n,t)}function gC(n,t){_E.call(this,n,t)}function pC(n,t,e){n.splice(t,0,e)}function mC(n,t,e){n.Mb(e)&&t.Cd(e)}function vC(n,t,e){t.Pe(n.a.Ye(e))}function kC(n,t,e){t.Dd(n.a.Ze(e))}function yC(n,t,e){t.Cd(n.a.Kb(e))}function MC(n,t){return $x(n.c,t)}function TC(n,t){return $x(n.e,t)}function jC(n,t){_E.call(this,n,t)}function EC(n,t){_E.call(this,n,t)}function SC(n,t){_E.call(this,n,t)}function PC(n,t){_E.call(this,n,t)}function CC(n,t){_E.call(this,n,t)}function IC(n,t){_E.call(this,n,t)}function OC(n,t){this.a=n,this.b=t}function AC(n,t){this.a=n,this.b=t}function LC(n,t){this.a=n,this.b=t}function NC(n,t){this.a=n,this.b=t}function $C(n,t){this.a=n,this.b=t}function DC(n,t){this.a=n,this.b=t}function xC(n,t){this.b=n,this.a=t}function RC(n,t){this.b=n,this.a=t}function KC(n,t){this.b=n,this.a=t}function FC(n,t){this.c=n,this.d=t}function _C(n,t){this.e=n,this.d=t}function BC(n,t){this.a=n,this.b=t}function HC(n,t){this.a=n,this.b=t}function UC(n,t){this.a=n,this.b=t}function GC(n,t){this.b=n,this.a=t}function qC(n,t){this.b=t,this.c=n}function XC(n,t){_E.call(this,n,t)}function zC(n,t){_E.call(this,n,t)}function VC(n,t){_E.call(this,n,t)}function WC(n,t){_E.call(this,n,t)}function QC(n,t){_E.call(this,n,t)}function JC(n,t){_E.call(this,n,t)}function YC(n,t){_E.call(this,n,t)}function ZC(n,t){_E.call(this,n,t)}function nI(n,t){_E.call(this,n,t)}function tI(n,t){_E.call(this,n,t)}function eI(n,t){_E.call(this,n,t)}function iI(n,t){_E.call(this,n,t)}function rI(n,t){_E.call(this,n,t)}function cI(n,t){_E.call(this,n,t)}function aI(n,t){_E.call(this,n,t)}function oI(n,t){_E.call(this,n,t)}function uI(n,t){_E.call(this,n,t)}function sI(n,t){_E.call(this,n,t)}function hI(n,t){_E.call(this,n,t)}function fI(n,t){_E.call(this,n,t)}function lI(n,t){_E.call(this,n,t)}function bI(n,t){_E.call(this,n,t)}function wI(n,t){_E.call(this,n,t)}function dI(n,t){_E.call(this,n,t)}function gI(n,t){_E.call(this,n,t)}function pI(n,t){_E.call(this,n,t)}function mI(n,t){_E.call(this,n,t)}function vI(n,t){_E.call(this,n,t)}function kI(n,t){_E.call(this,n,t)}function yI(n,t){_E.call(this,n,t)}function MI(n,t){_E.call(this,n,t)}function TI(n,t){_E.call(this,n,t)}function jI(n,t){_E.call(this,n,t)}function EI(n,t){this.b=n,this.a=t}function SI(n,t){_E.call(this,n,t)}function PI(n,t){this.a=n,this.b=t}function CI(n,t){this.a=n,this.b=t}function II(n,t){this.a=n,this.b=t}function OI(n,t){_E.call(this,n,t)}function AI(n,t){_E.call(this,n,t)}function LI(n,t){this.a=n,this.b=t}function NI(n,t){return PU(),t!=n}function $I(n){return MK(n.a),n.b}function DI(n){return K$n(n,n.c),n}function xI(){return dj(),new rut}function RI(){UB(),this.a=new xF}function KI(){oFn(),this.a=new ek}function FI(){e2(),this.b=new ek}function _I(n,t){this.b=n,this.d=t}function BI(n,t){this.a=n,this.b=t}function HI(n,t){this.a=n,this.b=t}function UI(n,t){this.a=n,this.b=t}function GI(n,t){this.b=n,this.a=t}function qI(n,t){_E.call(this,n,t)}function XI(n,t){_E.call(this,n,t)}function zI(n,t){_E.call(this,n,t)}function VI(n,t){_E.call(this,n,t)}function WI(n,t){_E.call(this,n,t)}function QI(n,t){_E.call(this,n,t)}function JI(n,t){_E.call(this,n,t)}function YI(n,t){_E.call(this,n,t)}function ZI(n,t){_E.call(this,n,t)}function nO(n,t){_E.call(this,n,t)}function tO(n,t){_E.call(this,n,t)}function eO(n,t){_E.call(this,n,t)}function iO(n,t){_E.call(this,n,t)}function rO(n,t){_E.call(this,n,t)}function cO(n,t){_E.call(this,n,t)}function aO(n,t){_E.call(this,n,t)}function oO(n,t){_E.call(this,n,t)}function uO(n,t){_E.call(this,n,t)}function sO(n,t){_E.call(this,n,t)}function hO(n,t){_E.call(this,n,t)}function fO(n,t){_E.call(this,n,t)}function lO(n,t){_E.call(this,n,t)}function bO(n,t){_E.call(this,n,t)}function wO(n,t){_E.call(this,n,t)}function dO(n,t){this.b=n,this.a=t}function gO(n,t){this.b=n,this.a=t}function pO(n,t){this.b=n,this.a=t}function mO(n,t){this.b=n,this.a=t}function vO(n,t){this.a=n,this.b=t}function kO(n,t){this.a=n,this.b=t}function yO(n,t){this.a=n,this.b=t}function MO(n,t){this.a=n,this.b=t}function TO(n,t){_E.call(this,n,t)}function jO(n,t){_E.call(this,n,t)}function EO(n,t){_E.call(this,n,t)}function SO(n,t){_E.call(this,n,t)}function PO(n,t){_E.call(this,n,t)}function CO(n,t){_E.call(this,n,t)}function IO(n,t){_E.call(this,n,t)}function OO(n,t){_E.call(this,n,t)}function AO(n,t){_E.call(this,n,t)}function LO(n,t){_E.call(this,n,t)}function NO(n,t){_E.call(this,n,t)}function $O(n,t){_E.call(this,n,t)}function DO(n,t){_E.call(this,n,t)}function xO(n,t){_E.call(this,n,t)}function RO(n,t){_E.call(this,n,t)}function KO(n,t){_E.call(this,n,t)}function FO(n,t){_E.call(this,n,t)}function _O(n,t){_E.call(this,n,t)}function BO(n,t){_E.call(this,n,t)}function HO(n,t){_E.call(this,n,t)}function UO(n,t){this.a=n,this.b=t}function GO(n,t){this.a=n,this.b=t}function qO(n,t){this.a=n,this.b=t}function XO(n,t){this.a=n,this.b=t}function zO(n,t){this.a=n,this.b=t}function VO(n,t){this.a=n,this.b=t}function WO(n,t){this.a=n,this.b=t}function QO(n,t){this.a=n,this.b=t}function JO(n,t){this.a=n,this.b=t}function YO(n,t){this.a=n,this.b=t}function ZO(n,t){this.a=n,this.b=t}function nA(n,t){this.a=n,this.b=t}function tA(n,t){this.a=n,this.b=t}function eA(n,t){this.b=n,this.a=t}function iA(n,t){this.b=n,this.a=t}function rA(n,t){this.b=n,this.a=t}function cA(n,t){this.b=n,this.a=t}function aA(n,t){this.a=n,this.b=t}function oA(n,t){this.a=n,this.b=t}function uA(n,t){_E.call(this,n,t)}function sA(n,t){this.a=n,this.b=t}function hA(n,t){this.a=n,this.b=t}function fA(n,t){_E.call(this,n,t)}function lA(n,t){this.f=n,this.c=t}function bA(n,t){return $x(n.g,t)}function wA(n,t){return $x(t.b,n)}function dA(n,t){return ymn(n.a,t)}function gA(n,t){return-n.b.af(t)}function pA(n,t){n&&vJ(AFt,n,t)}function mA(n,t){n.i=null,lon(n,t)}function vA(n,t,e){MSn(t,jAn(n,e))}function kA(n,t,e){MSn(t,jAn(n,e))}function yA(n,t){BRn(n.a,uG(t,58))}function MA(n,t){aen(n.a,uG(t,12))}function TA(n,t){this.a=n,this.b=t}function jA(n,t){this.a=n,this.b=t}function EA(n,t){this.a=n,this.b=t}function SA(n,t){this.a=n,this.b=t}function PA(n,t){this.a=n,this.b=t}function CA(n,t){this.d=n,this.b=t}function IA(n,t){this.e=n,this.a=t}function OA(n,t){this.b=n,this.c=t}function AA(n,t){this.i=n,this.g=t}function LA(n,t){this.d=n,this.e=t}function NA(n,t){Iin(new DD(n),t)}function $A(n){return kmn(n.c,n.b)}function DA(n){return n?n.md():null}function xA(n){return null==n?null:n}function RA(n){return typeof n===pZn}function KA(n){return typeof n===dZn}function FA(n){return typeof n===gZn}function _A(n,t){return 0==dwn(n,t)}function BA(n,t){return dwn(n,t)>=0}function HA(n,t){return 0!=dwn(n,t)}function UA(n,t){return Zun(n.Kc(),t)}function GA(n,t){return n.Rd().Xb(t)}function qA(n){return bpn(n),n.d.gc()}function XA(n){return Fq(null==n),n}function zA(n,t){return n.a+=""+t,n}function VA(n,t){return n.a+=""+t,n}function WA(n,t){return n.a+=""+t,n}function QA(n,t){return n.a+=""+t,n}function JA(n,t){return n.a+=""+t,n}function YA(n,t){return n.a+=""+t,n}function ZA(n){return""+(tJ(n),n)}function nL(n){$V(this),xun(this,n)}function tL(){J0(),ez.call(this)}function eL(n,t){Bz.call(this,n,t)}function iL(n,t){Bz.call(this,n,t)}function rL(n,t){Bz.call(this,n,t)}function cL(n,t){s8(n,t,n.c.b,n.c)}function aL(n,t){s8(n,t,n.a,n.a.a)}function oL(n){return u3(n,0),null}function uL(){this.b=0,this.a=!1}function sL(){this.b=0,this.a=!1}function hL(){this.b=new sS(orn(12))}function fL(){fL=E,fht=Abn(Nkn())}function lL(){lL=E,_wt=Abn(bKn())}function bL(){bL=E,bPt=Abn(usn())}function wL(){wL=E,Iv(),Bat=new Ym}function dL(n){return n.a=0,n.b=0,n}function gL(n,t){return n.a=t.g+1,n}function pL(n,t){w_.call(this,n,t)}function mL(n,t){uF.call(this,n,t)}function vL(n,t){AA.call(this,n,t)}function kL(n,t){zx.call(this,n,t)}function yL(n,t){Zsn.call(this,n,t)}function ML(n,t){TP(),vJ(_Ft,n,t)}function TL(n,t){n.q.setTime(W4(t))}function jL(n){e.clearTimeout(n)}function EL(n){return WW(n),new iN(n)}function SL(n,t){return xA(n)===xA(t)}function PL(n,t){return n.a.a.a.cc(t)}function CL(n,t){return r1(n.a,0,t)}function IL(n){return jW(uG(n,74))}function OL(n){return t0((tJ(n),n))}function AL(n){return t0((tJ(n),n))}function LL(n){return p$(n.l,n.m,n.h)}function NL(n,t){return d$(n.a,t.a)}function $L(n,t){return rW(n.a,t.a)}function DL(n,t){return ugn(n.a,t.a)}function xL(n,t){return n.indexOf(t)}function RL(n,t){return 2==n.j[t.p]}function KL(n,t){return n==t?0:n?1:-1}function FL(n){return n<10?"0"+n:""+n}function _L(n){return typeof n===gZn}function BL(n){return n==Flt||n==Hlt}function HL(n){return n==Flt||n==_lt}function UL(n,t){return d$(n.g,t.g)}function GL(n){return Ten(n.b.b,n,0)}function qL(){lX.call(this,0,0,0,0)}function XL(){td.call(this,new u8)}function zL(n,t){Ntn(n,0,n.length,t)}function VL(n,t){return kD(n.a,t),t}function WL(n,t){return GB(),t.a+=n}function QL(n,t){return GB(),t.a+=n}function JL(n,t){return GB(),t.c+=n}function YL(n,t){return kD(n.c,t),n}function ZL(n,t){return gsn(n.a,t),n}function nN(n){this.a=xI(),this.b=n}function tN(n){this.a=xI(),this.b=n}function eN(n){this.a=n.a,this.b=n.b}function iN(n){this.a=n,Ff.call(this)}function rN(n){this.a=n,Ff.call(this)}function cN(){gY.call(this,0,0,0,0)}function aN(n){return gsn(new wJ,n)}function oN(n){return xJ(uG(n,123))}function uN(n){return n.vh()&&n.wh()}function sN(n){return n!=uRt&&n!=sRt}function hN(n){return n==JDt||n==YDt}function fN(n){return n==nxt||n==QDt}function lN(n){return n==wjt||n==bjt}function bN(n,t){return d$(n.g,t.g)}function wN(n,t){return new Zsn(t,n)}function dN(n,t){return new Zsn(t,n)}function gN(n){return nG(n.b.Kc(),n.a)}function pN(n,t){sbn(n,t),Ocn(n,n.D)}function mN(n,t,e){Scn(n,t),pcn(n,e)}function vN(n,t,e){kcn(n,t),vcn(n,e)}function kN(n,t,e){ycn(n,t),Mcn(n,e)}function yN(n,t,e){mcn(n,t),jcn(n,e)}function MN(n,t,e){Tcn(n,t),Ecn(n,e)}function TN(n,t,e){AK.call(this,n,t,e)}function jN(n){lA.call(this,n,!0)}function EN(){qP.call(this,"Tail",3)}function SN(){qP.call(this,"Head",1)}function PN(n){cHn(),Bun.call(this,n)}function CN(n){lX.call(this,n,n,n,n)}function IN(n){n.c=Inn(dat,EZn,1,0,5,1)}function ON(n){return n.b&&sXn(n),n.a}function AN(n){return n.b&&sXn(n),n.c}function LN(n,t){Nut||(n.b=t)}function NN(n,t){return n[n.length]=t}function $N(n,t){return n[n.length]=t}function DN(n,t){return Ern(t,h0(n))}function xN(n,t){return Ern(t,h0(n))}function RN(n,t){return kan(UW(n.d),t)}function KN(n,t){return kan(UW(n.g),t)}function FN(n,t){return kan(UW(n.j),t)}function _N(n,t){uF.call(this,n.b,t)}function BN(n,t){ttn(z5(n.a),v2(t))}function HN(n,t){ttn(Aen(n.a),k2(t))}function UN(n,t,e){kN(e,e.i+n,e.j+t)}function GN(n,t,e){uQ(n.c[t.g],t.g,e)}function qN(n,t,e){uG(n.c,71).Gi(t,e)}function XN(n,t,e){return uQ(n,t,e),e}function zN(n){Prn(n.Sf(),new Od(n))}function VN(n){return null!=n?Hon(n):0}function WN(n){return null==n?0:Hon(n)}function QN(n){QYn(),Qm.call(this,n)}function JN(n){this.a=n,WU.call(this,n)}function YN(){YN=E,e.Math.log(2)}function ZN(){ZN=E,kP(),rBt=WKt}function n$(){n$=E,vSt=new rpn(kxt)}function t$(){t$=E,new e$,new Zm}function e$(){new Ym,new Ym,new Ym}function i$(){throw hv(new TM(hat))}function r$(){throw hv(new TM(hat))}function c$(){throw hv(new TM(fat))}function a$(){throw hv(new TM(fat))}function o$(n){this.a=n,VE.call(this,n)}function u$(n){this.a=n,VE.call(this,n)}function s$(n,t){ZW(),this.a=n,this.b=t}function h$(n,t){WW(t),uY(n).Jc(new b)}function f$(n,t){UX(n.c,n.c.length,t)}function l$(n){return n.at?1:0}function g$(n,t){return dwn(n,t)>0?n:t}function p$(n,t,e){return{l:n,m:t,h:e}}function m$(n,t){null!=n.a&&MA(t,n.a)}function v$(n){c2(n,null),u2(n,null)}function k$(n,t,e){return vJ(n.g,e,t)}function y$(n,t,e){return avn(t,e,n.c)}function M$(n,t,e){return vJ(n.k,e,t)}function T$(n,t,e){return gWn(n,t,e),e}function j$(n,t){return n2(),t.n.b+=n}function E$(n){HZ.call(this),this.b=n}function S$(n){LF.call(this),this.a=n}function P$(){qP.call(this,"Range",2)}function C$(n){this.b=n,this.a=new Zm}function I$(n){this.b=new tt,this.a=n}function O$(n){n.a=new R,n.c=new R}function A$(n){n.a=new Ym,n.d=new Ym}function L$(n){s2(n,null),h2(n,null)}function N$(n,t){return kWn(n.a,t,null)}function $$(n,t){return vJ(n.a,t.a,t)}function D$(n){return new MO(n.a,n.b)}function x$(n){return new MO(n.c,n.d)}function R$(n){return new MO(n.c,n.d)}function K$(n,t){return rVn(n.c,n.b,t)}function F$(n,t){return null!=n&&Eyn(n,t)}function _$(n,t){return-1!=Yhn(n.Kc(),t)}function B$(n){return n.Ob()?n.Pb():null}function H$(n){this.b=(hZ(),new Vw(n))}function U$(n){this.a=n,Ym.call(this)}function G$(){zx.call(this,null,null)}function q$(){Vx.call(this,null,null)}function X$(){_E.call(this,"INSTANCE",0)}function z$(){FEn(),this.a=new mKn(Llt)}function V$(n){return mvn(n,0,n.length)}function W$(n,t){return new ex(n.Kc(),t)}function Q$(n,t){return null!=n.a.Bc(t)}function J$(n,t){Czn(n),n.Gc(uG(t,15))}function Y$(n,t,e){n.c.bd(t,uG(e,136))}function Z$(n,t,e){n.c.Ui(t,uG(e,136))}function nD(n,t){n.c&&(cq(t),B1(t))}function tD(n,t){n.q.setHours(t),Iqn(n,t)}function eD(n,t){KR(t,n.a.a.a,n.a.a.b)}function iD(n,t,e,i){uQ(n.a[t.g],e.g,i)}function rD(n,t,e){return n.a[t.g][e.g]}function cD(n,t){return n.e[t.c.p][t.p]}function aD(n,t){return n.c[t.c.p][t.p]}function oD(n,t){return n.a[t.c.p][t.p]}function uD(n,t){return n.j[t.p]=oRn(t)}function sD(n,t){return null!=n.a.Bc(t)}function hD(n,t){return uM(pK(t.a))<=n}function fD(n,t){return uM(pK(t.a))>=n}function lD(n,t){return r7(n.f,t.Pg())}function bD(n,t){return n.a*t.a+n.b*t.b}function wD(n,t){return n.a0?t/(n*n):100*t}function jR(n,t){return n>0?t*t/n:t*t*100}function ER(n,t){return uG(ain(n.a,t),34)}function SR(n,t){return jIn(),UNn(n,t.e,t)}function PR(n,t,e){return ZS(),e.Mg(n,t)}function CR(n){return tcn(),n.e.a+n.f.a/2}function IR(n,t,e){return tcn(),e.e.a-n*t}function OR(n){return tcn(),n.e.b+n.f.b/2}function AR(n,t,e){return tcn(),e.e.b-n*t}function LR(n){n.d=new bR(n),n.e=new Ym}function NR(){this.a=new K1,this.b=new K1}function $R(n){this.c=n,this.a=1,this.b=1}function DR(n){aYn(),dv(this),this.Ff(n)}function xR(n,t,e){Stn(),n.pf(t)&&e.Cd(n)}function RR(n,t,e){return kD(t,xpn(n,e))}function KR(n,t,e){return n.a+=t,n.b+=e,n}function FR(n,t,e){return n.a*=t,n.b*=e,n}function _R(n,t){return n.a=t.a,n.b=t.b,n}function BR(n){return n.a=-n.a,n.b=-n.b,n}function HR(n,t,e){return n.a-=t,n.b-=e,n}function UR(n){lS.call(this),dan(this,n)}function GR(){_E.call(this,"GROW_TREE",0)}function qR(){_E.call(this,"POLYOMINO",0)}function XR(n,t,e){ltn.call(this,n,t,e,2)}function zR(n,t,e){$dn(z5(n.a),t,v2(e))}function VR(n,t){jP(),zx.call(this,n,t)}function WR(n,t){EP(),Vx.call(this,n,t)}function QR(n,t){EP(),WR.call(this,n,t)}function JR(n,t){EP(),Vx.call(this,n,t)}function YR(n,t){return n.c.Fc(uG(t,136))}function ZR(n,t,e){$dn(Aen(n.a),t,k2(e))}function nK(n){this.c=n,ycn(n,0),Mcn(n,0)}function tK(n,t){ZN(),OX.call(this,n,t)}function eK(n,t){ZN(),tK.call(this,n,t)}function iK(n,t){ZN(),tK.call(this,n,t)}function rK(n,t){ZN(),OX.call(this,n,t)}function cK(n,t){ZN(),iK.call(this,n,t)}function aK(n,t){ZN(),rK.call(this,n,t)}function oK(n,t){ZN(),OX.call(this,n,t)}function uK(n,t,e){return t.zl(n.e,n.c,e)}function sK(n,t,e){return t.Al(n.e,n.c,e)}function hK(n,t,e){return JXn(Len(n,t),e)}function fK(n,t){return mwn(n.e,uG(t,54))}function lK(n){return null==n?null:AQn(n)}function bK(n){return null==n?null:mOn(n)}function wK(n){return null==n?null:cpn(n)}function dK(n){return null==n?null:cpn(n)}function gK(n){return Fq(null==n||KA(n)),n}function pK(n){return Fq(null==n||FA(n)),n}function mK(n){return Fq(null==n||RA(n)),n}function vK(n){null==n.o&&axn(n)}function kK(n){if(!n)throw hv(new Dv)}function yK(n){if(!n)throw hv(new Nv)}function MK(n){if(!n)throw hv(new Bv)}function TK(n){if(!n)throw hv(new xv)}function jK(n){if(!n)throw hv(new Fv)}function EK(){EK=E,KFt=new Gk,new qk}function SK(){SK=E,zCt=new Cm("root")}function PK(){Kan.call(this),this.Bb|=P0n}function CK(n,t){this.d=n,Cw(this),this.b=t}function IK(n,t){Fnn.call(this,n),this.a=t}function OK(n,t){Fnn.call(this,n),this.a=t}function AK(n,t,e){A7.call(this,n,t,e,null)}function LK(n,t,e){A7.call(this,n,t,e,null)}function NK(n,t){this.c=n,OE.call(this,n,t)}function $K(n,t){this.a=n,NK.call(this,n,t)}function DK(n){this.q=new e.Date(W4(n))}function xK(n){return n>8?0:n+1}function RK(n,t){Nut||kD(n.a,t)}function KK(n,t){return WS(),jsn(t.d.i,n)}function FK(n,t){return Pun(),new oHn(t,n)}function _K(n,t,e){return n.Ne(t,e)<=0?e:t}function BK(n,t,e){return n.Ne(t,e)<=0?t:e}function HK(n,t){return uG(ain(n.b,t),143)}function UK(n,t){return uG(ain(n.c,t),233)}function GK(n){return uG(zq(n.a,n.b),294)}function qK(n){return new MO(n.c,n.d+n.a)}function XK(n){return tJ(n),n?1231:1237}function zK(n){return n2(),lN(uG(n,203))}function VK(){VK=E,lht=ggn((Qmn(),JRt))}function WK(n,t){t.a?W$n(n,t):sD(n.a,t.b)}function QK(n,t,e){++n.j,n.tj(),Ann(n,t,e)}function JK(n,t,e){++n.j,n.qj(t,n.Zi(t,e))}function YK(n,t,e){n.fd(t).Rb(e)}function ZK(n,t,e){return e=DUn(n,t,6,e)}function nF(n,t,e){return e=DUn(n,t,3,e)}function tF(n,t,e){return e=DUn(n,t,9,e)}function eF(n,t){return ZZ(t,W2n),n.f=t,n}function iF(n,t){return(t&vZn)%n.d.length}function rF(n,t,e){return fXn(n.c,n.b,t,e)}function cF(n,t){this.c=n,Drn.call(this,t)}function aF(n,t){this.a=n,xm.call(this,t)}function oF(n,t){this.a=n,xm.call(this,t)}function uF(n,t){Cm.call(this,n),this.a=t}function sF(n,t){Bm.call(this,n),this.a=t}function hF(n,t){Bm.call(this,n),this.a=t}function fF(n){smn.call(this,0,0),this.f=n}function lF(n,t,e){return n.a+=mvn(t,0,e),n}function bF(n){return!n.a&&(n.a=new M),n.a}function wF(n,t){var e;return e=n.e,n.e=t,e}function dF(n,t){var e;return e=t,!!n.Fe(e)}function gF(n,t){return qx(),n==t?0:n?1:-1}function pF(n,t){n.a.bd(n.b,t),++n.b,n.c=-1}function mF(n){n.b?mF(n.b):n.f.c.zc(n.e,n.d)}function vF(n){$V(n.e),n.d.b=n.d,n.d.a=n.d}function kF(n,t,e){vS(),Ob(n,t.Ve(n.a,e))}function yF(n,t,e){return UV(n,uG(t,22),e)}function MF(n,t){return aT(new Array(t),n)}function TF(n){return pz(Dz(n,32))^pz(n)}function jF(n){return String.fromCharCode(n)}function EF(n){return null==n?null:n.message}function SF(n,t,e){return n.apply(t,e)}function PF(n,t){n[U0n].call(n,t)}function CF(n,t){n[U0n].call(n,t)}function IF(n,t){return WS(),!jsn(t.d.i,n)}function OF(n,t,e,i){lX.call(this,n,t,e,i)}function AF(){HF.call(this),this.a=new sj}function LF(){this.n=new sj,this.o=new sj}function NF(){this.b=new sj,this.c=new Zm}function $F(){this.a=new Zm,this.b=new Zm}function DF(){this.a=new lt,this.b=new qv}function xF(){this.b=new u8,this.a=new u8}function RF(){this.b=new ek,this.a=new ek}function KF(){this.b=new Ym,this.a=new Ym}function FF(){this.b=new Gj,this.a=new Ma}function _F(){this.a=new hl,this.b=new oc}function BF(){this.a=new Zm,this.d=new Zm}function HF(){this.n=new Dk,this.i=new cN}function UF(n){this.a=(man(n,g1n),new R7(n))}function GF(n){this.a=(man(n,g1n),new R7(n))}function qF(n){return n<100?null:new cj(n)}function XF(n,t){return n.n.a=(tJ(t),t+10)}function zF(n,t){return n.n.a=(tJ(t),t+10)}function VF(n,t){return t==n||sSn(mRn(t),n)}function WF(n,t){return null==vJ(n.a,t,"")}function QF(n,t){return t.qi(n.a)}function JF(n,t){return n.a+=t.a,n.b+=t.b,n}function YF(n,t){return n.a-=t.a,n.b-=t.b,n}function ZF(n){return Xv(n.j.c,0),n.a=-1,n}function n_(n,t,e){return e=DUn(n,t,11,e)}function t_(n,t,e){null!=e&&Xan(t,gTn(n,e))}function e_(n,t,e){null!=e&&zan(t,gTn(n,e))}function i_(n,t,e,i){fV.call(this,n,t,e,i)}function r_(n,t,e,i){fV.call(this,n,t,e,i)}function c_(n,t,e,i){r_.call(this,n,t,e,i)}function a_(n,t,e,i){wV.call(this,n,t,e,i)}function o_(n,t,e,i){wV.call(this,n,t,e,i)}function u_(n,t,e,i){wV.call(this,n,t,e,i)}function s_(n,t,e,i){o_.call(this,n,t,e,i)}function h_(n,t,e,i){o_.call(this,n,t,e,i)}function f_(n,t,e,i){u_.call(this,n,t,e,i)}function l_(n,t,e,i){h_.call(this,n,t,e,i)}function b_(n,t,e,i){kV.call(this,n,t,e,i)}function w_(n,t){dM.call(this,Hit+n+Vet+t)}function d_(n,t){return n.jk().wi().ri(n,t)}function g_(n,t){return n.jk().wi().ti(n,t)}function p_(n,t){return tJ(n),xA(n)===xA(t)}function m_(n,t){return tJ(n),xA(n)===xA(t)}function v_(n,t){return n.b.Bd(new QP(n,t))}function k_(n,t){return n.b.Bd(new JP(n,t))}function y_(n,t){return n.b.Bd(new YP(n,t))}function M_(n,t){return n.e=uG(n.d.Kb(t),159)}function T_(n,t,e){return n.lastIndexOf(t,e)}function j_(n,t,e){return ugn(n[t.a],n[e.a])}function E_(n,t){return kfn(t,(jYn(),Oyt),n)}function S_(n,t){return d$(t.a.d.p,n.a.d.p)}function P_(n,t){return d$(n.a.d.p,t.a.d.p)}function C_(n,t){return ugn(n.c-n.s,t.c-t.s)}function I_(n,t){return ugn(n.b.e.a,t.b.e.a)}function O_(n,t){return ugn(n.c.e.a,t.c.e.a)}function A_(n){return n.c?Ten(n.c.a,n,0):-1}function L_(n){return n==rRt||n==aRt||n==cRt}function N_(n,t){this.c=n,QV.call(this,n,t)}function $_(n,t,e){this.a=n,Qx.call(this,t,e)}function D_(n){this.c=n,rL.call(this,YZn,0)}function x_(n,t,e){this.c=t,this.b=e,this.a=n}function R_(n){PU(),this.d=n,this.a=new ND}function K_(n){sB(),this.a=(hZ(),new nT(n))}function F_(n,t){hN(n.f)?JDn(n,t):wCn(n,t)}function __(n,t){sG.call(this,n,n.length,t)}function B_(n,t){Nut||t&&(n.d=t)}function H_(n,t){return F$(t,15)&&G_n(n.c,t)}function U_(n,t,e){return uG(n.c,71).Wk(t,e)}function G_(n,t,e){return uG(n.c,71).Xk(t,e)}function q_(n,t,e){return uK(n,uG(t,343),e)}function X_(n,t,e){return sK(n,uG(t,343),e)}function z_(n,t,e){return yPn(n,uG(t,343),e)}function V_(n,t,e){return FCn(n,uG(t,343),e)}function W_(n,t){return null==t?null:Xwn(n.b,t)}function Q_(n){return FA(n)?(tJ(n),n):n.ue()}function J_(n){return!isNaN(n)&&!isFinite(n)}function Y_(n){O$(this),BY(this),Qon(this,n)}function Z_(n){IN(this),dG(this.c,0,n.Pc())}function nB(n,t,e){this.a=n,this.b=t,this.c=e}function tB(n,t,e){this.a=n,this.b=t,this.c=e}function eB(n,t,e){this.d=n,this.b=e,this.a=t}function iB(n){this.a=n,bS(),Bsn(Date.now())}function rB(n){LQ(n.a),Lnn(n.c,n.b),n.b=null}function cB(){cB=E,out=new K,uut=new F}function aB(){aB=E,DFt=Inn(dat,EZn,1,0,5,1)}function oB(){oB=E,X_t=Inn(dat,EZn,1,0,5,1)}function uB(){uB=E,z_t=Inn(dat,EZn,1,0,5,1)}function sB(){sB=E,new jv((hZ(),hZ(),zot))}function hB(n){return Rtn(),Fcn((xtn(),Mut),n)}function fB(n){return ybn(),Fcn((bnn(),xut),n)}function lB(n){return _kn(),Fcn((k8(),Jut),n)}function bB(n){return Xin(),Fcn((y8(),tst),n)}function wB(n){return W_n(),Fcn((uhn(),kst),n)}function dB(n){return Yrn(),Fcn((fnn(),Cst),n)}function gB(n){return Ktn(),Fcn((hnn(),Dst),n)}function pB(n){return Yen(),Fcn((lnn(),Bst),n)}function mB(n){return JYn(),Fcn((fL(),fht),n)}function vB(n){return ehn(),Fcn((_tn(),vht),n)}function kB(n){return vyn(),Fcn((Htn(),Eht),n)}function yB(n){return myn(),Fcn((Btn(),Rht),n)}function MB(n){return BS(),Fcn((r6(),_ht),n)}function TB(n){return zin(),Fcn((M8(),vft),n)}function jB(n){return Jen(),Fcn((wnn(),vlt),n)}function EB(n){return uIn(),Fcn(($in(),Ilt),n)}function SB(n){return Xhn(),Fcn((Gtn(),Glt),n)}function PB(n){return Uvn(),Fcn((Utn(),ibt),n)}function CB(n,t){if(!n)throw hv(new vM(t))}function IB(n){if(!n)throw hv(new kM(PZn))}function OB(n,t){if(n!=t)throw hv(new Fv)}function AB(n,t,e){this.a=n,this.b=t,this.c=e}function LB(n,t,e){this.a=n,this.b=t,this.c=e}function NB(n,t,e){this.a=n,this.b=t,this.c=e}function $B(n,t,e){this.b=n,this.a=t,this.c=e}function DB(n,t,e){this.b=n,this.c=t,this.a=e}function xB(n,t,e){this.a=n,this.b=t,this.c=e}function RB(n,t,e){this.e=t,this.b=n,this.d=e}function KB(n,t,e){this.b=n,this.a=t,this.c=e}function FB(n,t,e){return vS(),n.a.Yd(t,e),t}function _B(n){var t;return(t=new yn).e=n,t}function BB(n){var t;return(t=new pk).b=n,t}function HB(){HB=E,Nbt=new $e,$bt=new De}function UB(){UB=E,Jwt=new ui,Qwt=new si}function GB(){GB=E,rdt=new mr,cdt=new vr}function qB(n){return gon(),Fcn((q7(),Cdt),n)}function XB(n){return zYn(),Fcn((lL(),_wt),n)}function zB(n){return Ghn(),Fcn((Xtn(),Wwt),n)}function VB(n){return qhn(),Fcn((qtn(),ldt),n)}function WB(n){return gPn(),Fcn((Din(),vdt),n)}function QB(n){return h_n(),Fcn((osn(),Kdt),n)}function JB(n){return vAn(),Fcn((ecn(),zdt),n)}function YB(n){return H7(),Fcn((I8(),Jdt),n)}function ZB(n){return jan(),Fcn((U7(),egt),n)}function nH(n){return ran(),Fcn((G7(),ogt),n)}function tH(n){return kvn(),Fcn((xin(),wgt),n)}function eH(n){return Vin(),Fcn((E8(),mgt),n)}function iH(n){return RIn(),Fcn((ccn(),Jgt),n)}function rH(n){return r_n(),Fcn((Efn(),spt),n)}function cH(n){return ihn(),Fcn((z7(),wpt),n)}function aH(n){return Zen(),Fcn((V7(),vpt),n)}function oH(n){return Y6(),Fcn((j8(),Tpt),n)}function uH(n){return ESn(),Fcn((rcn(),Ugt),n)}function sH(n){return Pfn(),Fcn((X7(),Tgt),n)}function hH(n){return tOn(),Fcn((icn(),Agt),n)}function fH(n){return Wtn(),Fcn((S8(),Dgt),n)}function lH(n){return Gpn(),Fcn((Kin(),$mt),n)}function bH(n){return MKn(),Fcn((chn(),ojt),n)}function wH(n){return Cwn(),Fcn((W7(),ljt),n)}function dH(n){return Yyn(),Fcn((ztn(),mjt),n)}function gH(n){return pyn(),Fcn((Rin(),Ejt),n)}function pH(n){return THn(),Fcn((Sfn(),Rjt),n)}function mH(n){return yvn(),Fcn((Vtn(),Ujt),n)}function vH(n){return nin(),Fcn((P8(),zjt),n)}function kH(n){return can(),Fcn((Y7(),Yjt),n)}function yH(n){return isn(),Fcn((Q7(),iEt),n)}function MH(n){return Sln(),Fcn((J7(),uEt),n)}function TH(n){return kbn(),Fcn((Z7(),bEt),n)}function jH(n){return ian(),Fcn((nnn(),mEt),n)}function EH(n){return zhn(),Fcn((tnn(),TEt),n)}function SH(n){return ean(),Fcn((snn(),GEt),n)}function PH(n){return Z6(),Fcn((C8(),nSt),n)}function CH(n){return b0(),Fcn((L8(),bSt),n)}function IH(n){return w0(),Fcn((N8(),pSt),n)}function OH(n){return _7(),Fcn(($8(),RSt),n)}function AH(n){return l0(),Fcn((D8(),XSt),n)}function LH(n){return Cjn(),Fcn((sen(),YSt),n)}function NH(n){return OHn(),Fcn((bL(),bPt),n)}function $H(n){return Pln(),Fcn((enn(),mPt),n)}function DH(n){return mbn(),Fcn((uen(),KCt),n)}function xH(n){return i3(),Fcn((O8(),HCt),n)}function RH(n){return pon(),Fcn((A8(),JCt),n)}function KH(n){return zPn(),Fcn((Fin(),rIt),n)}function FH(n){return vbn(),Fcn((inn(),bIt),n)}function _H(n){return Ptn(),Fcn((x8(),uIt),n)}function BH(n){return dTn(),Fcn((oen(),tOt),n)}function HH(n){return esn(),Fcn((rnn(),aOt),n)}function UH(n){return Jmn(),Fcn((cnn(),fOt),n)}function GH(n){return Zyn(),Fcn((ann(),gOt),n)}function qH(n){return Bgn(),Fcn((onn(),LOt),n)}function XH(n){return a9(),Fcn((R8(),jAt),n)}function zH(n){return Aun(),Fcn((T8(),Lbt),n)}function VH(n){return zIn(),Fcn((acn(),mbt),n)}function WH(n){return den(),Fcn((unn(),IAt),n)}function QH(n){return rhn(),Fcn((K8(),NAt),n)}function JH(n){return _Rn(),Fcn((_in(),BAt),n)}function YH(n){return nP(),Fcn(($6(),WAt),n)}function ZH(n){return Rdn(),Fcn((gnn(),XAt),n)}function nU(n){return tP(),Fcn((D6(),YAt),n)}function tU(n){return B7(),Fcn((F8(),eLt),n)}function eU(n){return pOn(),Fcn((Bin(),sLt),n)}function iU(n){return eP(),Fcn((x6(),XLt),n)}function rU(n){return Vhn(),Fcn((_8(),QLt),n)}function cU(n){return Rkn(),Fcn((Uin(),bNt),n)}function aU(n){return lAn(),Fcn((csn(),TNt),n)}function oU(n){return nMn(),Fcn((ocn(),DNt),n)}function uU(n){return ZSn(),Fcn((ucn(),t$t),n)}function sU(n){return xdn(),Fcn((Hin(),ext),n)}function hU(n){return Zrn(),Fcn((pnn(),oxt),n)}function fU(n){return _gn(),Fcn((hen(),bxt),n)}function lU(n){return RCn(),Fcn((scn(),yxt),n)}function bU(n){return Own(),Fcn((dnn(),Nxt),n)}function wU(n){return Ajn(),Fcn((fen(),Fxt),n)}function dU(n){return VDn(),Fcn((ohn(),Qxt),n)}function gU(n){return Vkn(),Fcn((Gin(),iRt),n)}function pU(n){return $Pn(),Fcn((hcn(),fRt),n)}function mU(n){return eNn(),Fcn((fcn(),vRt),n)}function vU(n){return KQn(),Fcn((qin(),HRt),n)}function kU(n){return Qmn(),Fcn((len(),ZRt),n)}function yU(n){return oUn(),Fcn((ahn(),hKt),n)}function MU(n){return Iwn(),Fcn((mnn(),dKt),n)}function TU(n,t){return tJ(n),n+(tJ(t),t)}function jU(n){return CU(),Fcn((B8(),vKt),n)}function EU(n){return qpn(),Fcn((ben(),EKt),n)}function SU(n){return Eln(),Fcn((wen(),LKt),n)}function PU(){PU=E,KQn(),zEt=_Rt,VEt=kRt}function CU(){CU=E,gKt=new Pq,pKt=new gV}function IU(n){return!n.e&&(n.e=new Zm),n.e}function OU(n,t){this.c=n,this.a=t,this.b=t-n}function AU(n,t,e){this.a=n,this.b=t,this.c=e}function LU(n,t,e){this.a=n,this.b=t,this.c=e}function NU(n,t,e){this.a=n,this.b=t,this.c=e}function $U(n,t,e){this.a=n,this.b=t,this.c=e}function DU(n,t,e){this.a=n,this.b=t,this.c=e}function xU(n,t,e){this.a=n,this.b=t,this.c=e}function RU(n,t,e){this.e=n,this.a=t,this.c=e}function KU(n,t,e){ZN(),_1.call(this,n,t,e)}function FU(n,t,e){ZN(),CQ.call(this,n,t,e)}function _U(n,t,e){ZN(),CQ.call(this,n,t,e)}function BU(n,t,e){ZN(),CQ.call(this,n,t,e)}function HU(n,t,e){ZN(),FU.call(this,n,t,e)}function UU(n,t,e){ZN(),FU.call(this,n,t,e)}function GU(n,t,e){ZN(),UU.call(this,n,t,e)}function qU(n,t,e){ZN(),_U.call(this,n,t,e)}function XU(n,t,e){ZN(),BU.call(this,n,t,e)}function zU(n){lX.call(this,n.d,n.c,n.a,n.b)}function VU(n){lX.call(this,n.d,n.c,n.a,n.b)}function WU(n){this.d=n,Cw(this),this.b=Ez(n.d)}function QU(n){return rDn(),Fcn((asn(),SFt),n)}function JU(n,t){return WW(n),WW(t),new jE(n,t)}function YU(n,t){return WW(n),WW(t),new WG(n,t)}function ZU(n,t){return WW(n),WW(t),new QG(n,t)}function nG(n,t){return WW(n),WW(t),new DE(n,t)}function tG(n){return MK(0!=n.b),Lrn(n,n.a.a)}function eG(n){return MK(0!=n.b),Lrn(n,n.c.b)}function iG(n){return!n.c&&(n.c=new Ks),n.c}function rG(n){var t;return cin(t=new Zm,n),t}function cG(n){var t;return cin(t=new ek,n),t}function aG(n){var t;return Fon(t=new rk,n),t}function oG(n){var t;return Fon(t=new lS,n),t}function uG(n,t){return Fq(null==n||Eyn(n,t)),n}function sG(n,t,e){_z.call(this,t,e),this.a=n}function hG(n,t){this.c=n,this.b=t,this.a=!1}function fG(){this.a=";,;",this.b="",this.c=""}function lG(n,t,e){this.b=n,eL.call(this,t,e)}function bG(n,t,e){this.c=n,VP.call(this,t,e)}function wG(n,t,e){FC.call(this,n,t),this.b=e}function dG(n,t,e){b$n(e,0,n,t,e.length,!1)}function gG(n,t,e,i,r){n.b=t,n.c=e,n.d=i,n.a=r}function pG(n,t,e,i,r){n.d=t,n.c=e,n.a=i,n.b=r}function mG(n,t){t&&(n.b=t,n.a=(GQ(t),t.a))}function vG(n,t){if(!n)throw hv(new vM(t))}function kG(n,t){if(!n)throw hv(new kM(t))}function yG(n,t){if(!n)throw hv(new gM(t))}function MG(n,t){return YS(),d$(n.d.p,t.d.p)}function TG(n,t){return tcn(),ugn(n.e.b,t.e.b)}function jG(n,t){return tcn(),ugn(n.e.a,t.e.a)}function EG(n,t){return d$(wq(n.d),wq(t.d))}function SG(n,t){return t&&$Q(n,t.d)?t:null}function PG(n,t){return t==(KQn(),_Rt)?n.c:n.d}function CG(n){return Esn(LV(_L(n)?Gsn(n):n))}function IG(n){return new MO(n.c+n.b,n.d+n.a)}function OG(n){return null!=n&&!mpn(n,n_t,t_t)}function AG(n,t){return(ldn(n)<<4|ldn(t))&D1n}function LG(n,t,e,i,r){n.c=t,n.d=e,n.b=i,n.a=r}function NG(n){var t,e;t=n.b,e=n.c,n.b=e,n.c=t}function $G(n){var t,e;e=n.d,t=n.a,n.d=t,n.a=e}function DG(n,t){var e;return e=n.c,Jan(n,t),e}function xG(n,t){return n.g=t<0?-1:t,n}function RG(n,t){return Brn(n),n.a*=t,n.b*=t,n}function KG(n,t,e){Orn.call(this,t,e),this.d=n}function FG(n,t,e){LA.call(this,n,t),this.c=e}function _G(n,t,e){LA.call(this,n,t),this.c=e}function BG(n){uB(),ps.call(this),this.ci(n)}function HG(){N7(),OQ.call(this,(MP(),l_t))}function UG(n){return QYn(),new IX(0,n)}function GG(){GG=E,hZ(),CBt=new Xw(bct)}function qG(){qG=E,new Gyn((my(),Tat),(py(),Mat))}function XG(){XG=E,bot=Inn(dot,zZn,17,256,0,1)}function zG(){this.b=uM(pK(Jkn((cGn(),Bft))))}function VG(n){this.b=n,this.a=Mz(this.b.a).Od()}function WG(n,t){this.b=n,this.a=t,Ff.call(this)}function QG(n,t){this.a=n,this.b=t,Ff.call(this)}function JG(n,t,e){this.a=n,vL.call(this,t,e)}function YG(n,t,e){this.a=n,vL.call(this,t,e)}function ZG(n,t,e){nrn(n,t,new QW(e))}function nq(n,t,e){var i;return i=n[t],n[t]=e,i}function tq(n){return Ltn(n.slice(),n)}function eq(n){var t;return t=n.n,n.a.b+t.d+t.a}function iq(n){var t;return t=n.n,n.e.b+t.d+t.a}function rq(n){var t;return t=n.n,n.e.a+t.b+t.c}function cq(n){n.a.b=n.b,n.b.a=n.a,n.a=n.b=null}function aq(n,t){return s8(n,t,n.c.b,n.c),!0}function oq(n){return n.a?n.a:sY(n)}function uq(n){return lZ(),bIn(n)==R0(gIn(n))}function sq(n){return lZ(),gIn(n)==R0(bIn(n))}function hq(n,t){return CEn(n,new FC(t.a,t.b))}function fq(n,t){return TJ(),IMn(n,t),new bJ(n,t)}function lq(n,t){return n.c=t)throw hv(new Ik)}function Wz(n,t){return cdn(n,(tJ(t),new ud(t)))}function Qz(n,t){return cdn(n,(tJ(t),new sd(t)))}function Jz(n,t,e){return BYn(n,uG(t,12),uG(e,12))}function Yz(n){return Lun(),0!=uG(n,12).g.c.length}function Zz(n){return Lun(),0!=uG(n,12).e.c.length}function nV(n,t){return Pun(),ugn(t.a.o.a,n.a.o.a)}function tV(n,t){t.Bb&Qtt&&!n.a.o&&(n.a.o=t)}function eV(n,t){t.Ug("General 'Rotator",1),lQn(n)}function iV(n,t,e){t.qf(e,uM(pK(cQ(n.b,e)))*n.a)}function rV(n,t,e){return l_n(),qun(n,t)&&qun(n,e)}function cV(n){return eNn(),!n.Hc(wRt)&&!n.Hc(gRt)}function aV(n){return n.e?T7(n.e):null}function oV(n){return _L(n)?""+n:K_n(n)}function uV(n){var t;for(t=n;t.f;)t=t.f;return t}function sV(n,t,e){return uQ(t,0,nX(t[0],e[0])),t}function hV(n,t,e,i){var r;(r=n.i).i=t,r.a=e,r.b=i}function fV(n,t,e,i){MD.call(this,n,t,e),this.b=i}function lV(n,t,e,i,r){btn.call(this,n,t,e,i,r,-1)}function bV(n,t,e,i,r){wtn.call(this,n,t,e,i,r,-1)}function wV(n,t,e,i){FG.call(this,n,t,e),this.b=i}function dV(n){lA.call(this,n,!1),this.a=!1}function gV(){BO.call(this,"LOOKAHEAD_LAYOUT",1)}function pV(n){this.b=n,Zx.call(this,n),qD(this)}function mV(n){this.b=n,tR.call(this,n),XD(this)}function vV(n,t,e){this.a=n,i_.call(this,t,e,5,6)}function kV(n,t,e,i){this.b=n,MD.call(this,t,e,i)}function yV(n,t){this.b=n,fb.call(this,n.b),this.a=t}function MV(n){this.a=Fyn(n.a),this.b=new Z_(n.b)}function TV(n,t){ZW(),UE.call(this,n,Dwn(new IM(t)))}function jV(n,t){return QYn(),new PQ(n,t,0)}function EV(n,t){return QYn(),new PQ(6,n,t)}function SV(n,t){for(tJ(t);n.Ob();)t.Cd(n.Pb())}function PV(n,t){return RA(t)?AZ(n,t):!!FX(n.f,t)}function CV(n,t){return t.Vh()?mwn(n.b,uG(t,54)):t}function IV(n,t){return m_(n.substr(0,t.length),t)}function OV(n){return new Fz(new YD(n.a.length,n.a))}function AV(n){return new MO(n.c+n.b/2,n.d+n.a/2)}function LV(n){return p$(~n.l&f0n,~n.m&f0n,~n.h&l0n)}function NV(n){return typeof n===wZn||typeof n===mZn}function $V(n){n.f=new nN(n),n.i=new tN(n),++n.g}function DV(n){if(!n)throw hv(new Bv);return n.d}function xV(n){var t;return MK(null!=(t=Rfn(n))),t}function RV(n){var t;return MK(null!=(t=sgn(n))),t}function KV(n,t){var e;return e7(t,e=n.a.gc()),e-t}function FV(n,t){return null==n.a.zc(t,n)}function _V(n,t){return null==n.a.zc(t,(qx(),tot))}function BV(n){return new fX(null,oW(n,n.length))}function HV(n,t,e){return HXn(n,uG(t,42),uG(e,176))}function UV(n,t,e){return Mon(n.a,t),nq(n.b,t.g,e)}function GV(n,t,e){Vz(e,n.a.c.length),Y8(n.a,e,t)}function qV(n,t,e,i){ubn(t,e,n.length),XV(n,t,e,i)}function XV(n,t,e,i){var r;for(r=t;r0?e.Math.log(n/t):-100}function rW(n,t){return dwn(n,t)<0?-1:dwn(n,t)>0?1:0}function cW(n,t){J$(n,F$(t,160)?t:uG(t,2036).Rl())}function aW(n,t){if(null==n)throw hv(new MM(t))}function oW(n,t){return $rn(t,n.length),new Sq(n,t)}function uW(n,t){return!!t&&Qon(n,t)}function sW(){return Hy(),Uhn(cT(Lat,1),p1n,549,0,[Iat])}function hW(n){return 0==n.e?n:new VV(-n.e,n.d,n.a)}function fW(n,t){return ugn(n.c.c+n.c.b,t.c.c+t.c.b)}function lW(n,t){s8(n.d,t,n.b.b,n.b),++n.a,n.c=null}function bW(n,t){return n.c?bW(n.c,t):kD(n.b,t),n}function wW(n,t,e){var i;return i=uin(n,t),W5(n,t,e),i}function dW(n,t,e){var i;for(i=0;i=n.g}function uQ(n,t,e){return yK(null==e||aGn(n,e)),n[t]=e}function sQ(n,t){return s3(t,n.length+1),n.substr(t)}function hQ(n,t){for(tJ(t);n.c=n?new mS:ton(n-1)}function HQ(n){return!n.a&&n.c?n.c.b:n.a}function UQ(n){return F$(n,616)?n:new e0(n)}function GQ(n){n.c?GQ(n.c):(vgn(n),n.d=!0)}function qQ(n){n.c?n.c.$e():(n.d=!0,uKn(n))}function XQ(n){n.b=!1,n.c=!1,n.d=!1,n.a=!1}function zQ(n){return n.c.i.c==n.d.i.c}function VQ(n,t){var e;(e=n.Ih(t))>=0?n.ki(e):zLn(n,t)}function WQ(n,t){n.c<0||n.b.b0;)n=n<<1|(n<0?1:0);return n}function CJ(n,t){var e;return e=new bQ(n),mv(t.c,e),e}function IJ(n,t){n.u.Hc((eNn(),wRt))&&vNn(n,t),knn(n,t)}function OJ(n,t){return xA(n)===xA(t)||null!=n&&udn(n,t)}function AJ(n,t){return RX(n.a,t)?n.b[uG(t,22).g]:null}function LJ(){return BS(),Uhn(cT(oft,1),p1n,489,0,[Kht])}function NJ(){return nP(),Uhn(cT(JAt,1),p1n,490,0,[zAt])}function $J(){return tP(),Uhn(cT(tLt,1),p1n,558,0,[QAt])}function DJ(){return eP(),Uhn(cT(WLt,1),p1n,539,0,[GLt])}function xJ(n){return!n.n&&(n.n=new fV(lFt,n,1,7)),n.n}function RJ(n){return!n.c&&(n.c=new fV(wFt,n,9,9)),n.c}function KJ(n){return!n.c&&(n.c=new f_(cFt,n,5,8)),n.c}function FJ(n){return!n.b&&(n.b=new f_(cFt,n,4,7)),n.b}function _J(n){return n.j.c.length=0,oY(n.c),ZF(n.a),n}function BJ(n){return n.e==wct&&kw(n,akn(n.g,n.b)),n.e}function HJ(n){return n.f==wct&&Mw(n,tEn(n.g,n.b)),n.f}function UJ(n,t,e,i){return Dsn(n,t,e,!1),pdn(n,i),n}function GJ(n,t){this.b=n,QV.call(this,n,t),qD(this)}function qJ(n,t){this.b=n,N_.call(this,n,t),XD(this)}function XJ(n){this.d=n,this.a=this.d.b,this.b=this.d.c}function zJ(n,t){this.b=n,this.c=t,this.a=new fS(this.b)}function VJ(n,t){return s3(t,n.length),n.charCodeAt(t)}function WJ(n,t){jgn(n,uM($cn(t,"x")),uM($cn(t,"y")))}function QJ(n,t){jgn(n,uM($cn(t,"x")),uM($cn(t,"y")))}function JJ(n,t){return vgn(n),new fX(n,new ien(t,n.a))}function YJ(n,t){return vgn(n),new fX(n,new f7(t,n.a))}function ZJ(n,t){return vgn(n),new IK(n,new s7(t,n.a))}function nY(n,t){return vgn(n),new OK(n,new h7(t,n.a))}function tY(n,t){return new MZ(uG(WW(n),50),uG(WW(t),50))}function eY(n,t){return ugn(n.d.c+n.d.b/2,t.d.c+t.d.b/2)}function iY(n,t,e){e.a?Mcn(n,t.b-n.f/2):ycn(n,t.a-n.g/2)}function rY(n,t){return ugn(n.g.c+n.g.b/2,t.g.c+t.g.b/2)}function cY(n,t){return qS(),ugn((tJ(n),n),(tJ(t),t))}function aY(n){return null!=n&&ZE(UFt,n.toLowerCase())}function oY(n){var t;for(t=n.Kc();t.Ob();)t.Pb(),t.Qb()}function uY(n){var t;return!(t=n.b)&&(n.b=t=new Yl(n)),t}function sY(n){return con(n)||null}function hY(n,t){var e,i;return(e=n/t)>(i=t0(e))&&++i,i}function fY(n,t,e){var i;(i=uG(n.d.Kb(e),159))&&i.Nb(t)}function lY(n,t,e){KXn(n.a,e),jhn(e),EDn(n.b,e),Tzn(t,e)}function bY(n,t,e,i){this.a=n,this.c=t,this.b=e,this.d=i}function wY(n,t,e,i){this.c=n,this.b=t,this.a=e,this.d=i}function dY(n,t,e,i){this.c=n,this.b=t,this.d=e,this.a=i}function gY(n,t,e,i){this.c=n,this.d=t,this.b=e,this.a=i}function pY(n,t,e,i){this.a=n,this.d=t,this.c=e,this.b=i}function mY(n,t,e,i){this.a=n,this.e=t,this.d=e,this.c=i}function vY(n,t,e,i){this.a=n,this.c=t,this.d=e,this.b=i}function kY(n,t,e){this.a=L1n,this.d=n,this.b=t,this.c=e}function yY(n,t,e,i){_E.call(this,n,t),this.a=e,this.b=i}function MY(n,t){this.d=(tJ(n),n),this.a=16449,this.c=t}function TY(n){this.a=new Zm,this.e=Inn(YHt,zZn,53,n,0,2)}function jY(n){n.Ug("No crossing minimization",1),n.Vg()}function EY(){Ky.call(this,"There is no more element.")}function SY(n,t,e,i){this.a=n,this.b=t,this.c=e,this.d=i}function PY(n,t,e,i){this.a=n,this.b=t,this.c=e,this.d=i}function CY(n,t,e,i){this.e=n,this.a=t,this.c=e,this.d=i}function IY(n,t,e,i){this.a=n,this.c=t,this.d=e,this.b=i}function OY(n,t,e,i){ZN(),l7.call(this,t,e,i),this.a=n}function AY(n,t,e,i){ZN(),l7.call(this,t,e,i),this.a=n}function LY(n,t,e){var i;return i=eJn(n),t.ti(e,i)}function NY(n){var t;return Urn(t=new ev,n),t}function $Y(n){var t;return MIn(t=new ev,n),t}function DY(n,t){return Qun(t,cQ(n.f,t)),null}function xY(n){return!n.b&&(n.b=new fV(aFt,n,12,3)),n.b}function RY(n){return Fq(null==n||NV(n)&&!(n.Tm===j)),n}function KY(n){return n.n&&(n.e!==E1n&&n.je(),n.j=null),n}function FY(n){if(bpn(n.d),n.d.d!=n.c)throw hv(new Fv)}function _Y(n){return MK(n.b0&&XEn(this)}function UY(n,t){this.a=n,CK.call(this,n,uG(n.d,15).fd(t))}function GY(n,t){return ugn(EX(n)*jX(n),EX(t)*jX(t))}function qY(n,t){return ugn(EX(n)*jX(n),EX(t)*jX(t))}function XY(n){return BNn(n)&&oM(gK(zDn(n,(jYn(),hMt))))}function zY(n,t){return UNn(n,uG(oIn(t,(jYn(),UMt)),17),t)}function VY(n,t){return uG(oIn(n,(GYn(),Vpt)),15).Fc(t),t}function WY(n,t){return n.b=t.b,n.c=t.c,n.d=t.d,n.a=t.a,n}function QY(n,t,e,i){this.b=n,this.c=i,rL.call(this,t,e)}function JY(n,t,e){n.i=0,n.e=0,t!=e&&tln(n,t,e)}function YY(n,t,e){n.i=0,n.e=0,t!=e&&eln(n,t,e)}function ZY(n,t,e){return JS(),opn(uG(cQ(n.e,t),529),e)}function nZ(n){return n.f||(n.f=new OE(n,n.c))}function tZ(n,t){return Hwn(n.j,t.s,t.c)+Hwn(t.e,n.s,n.c)}function eZ(n,t){n.e&&!n.e.a&&(iv(n.e,t),eZ(n.e,t))}function iZ(n,t){n.d&&!n.d.a&&(iv(n.d,t),iZ(n.d,t))}function rZ(n,t){return-ugn(EX(n)*jX(n),EX(t)*jX(t))}function cZ(n){return uG(n.ld(),149).Pg()+":"+cpn(n.md())}function aZ(){HIn(this,new Fl),this.wb=(tQ(),M_t),vj()}function oZ(n){this.b=new Zm,Ohn(this.b,this.b),this.a=n}function uZ(n,t){new lS,this.a=new Uk,this.b=n,this.c=t}function sZ(){sZ=E,Jot=new N,Yot=new N,Zot=new $}function hZ(){hZ=E,zot=new C,Vot=new O,Wot=new A}function fZ(){fZ=E,Gut=new dn,Xut=new tz,qut=new gn}function lZ(){lZ=E,aft=new Zm,cft=new Ym,rft=new Zm}function bZ(n,t){if(null==n)throw hv(new MM(t));return n}function wZ(n){return!n.a&&(n.a=new fV(bFt,n,10,11)),n.a}function dZ(n){return!n.q&&(n.q=new fV(p_t,n,11,10)),n.q}function gZ(n){return!n.s&&(n.s=new fV(o_t,n,21,17)),n.s}function pZ(n){return WW(n),KMn(new Fz(ix(n.a.Kc(),new h)))}function mZ(n,t){return Tbn(n),Tbn(t),cM(uG(n,22),uG(t,22))}function vZ(n,t,e){nrn(n,t,new Pb(Q_(e)))}function kZ(n,t,e,i,r,c){wtn.call(this,n,t,e,i,r,c?-2:-1)}function yZ(n,t,e,i){LA.call(this,t,e),this.b=n,this.a=i}function MZ(n,t){Sy.call(this,new Hz(n)),this.a=n,this.b=t}function TZ(n){this.b=n,this.c=n,n.e=null,n.c=null,this.a=1}function jZ(n){var t;GB(),(t=uG(n.g,10)).n.a=n.d.c+t.d.b}function EZ(){var n,t;EZ=E,t=!ovn(),n=new v,_at=t?new m:n}function SZ(n){return hZ(),F$(n,59)?new eT(n):new gx(n)}function PZ(n){return F$(n,16)?new oX(uG(n,16)):cG(n.Kc())}function CZ(n){return new WD(n,n.e.Rd().gc()*n.c.Rd().gc())}function IZ(n){return new QD(n,n.e.Rd().gc()*n.c.Rd().gc())}function OZ(n){return n&&n.hashCode?n.hashCode():xx(n)}function AZ(n,t){return null==t?!!FX(n.f,null):_X(n.i,t)}function LZ(n,t){var e;return(e=Q$(n.a,t))&&(t.d=null),e}function NZ(n,t,e){return!!n.f&&n.f.ef(t,e)}function $Z(n,t,e,i){uQ(n.c[t.g],e.g,i),uQ(n.c[e.g],t.g,i)}function DZ(n,t,e,i){uQ(n.c[t.g],t.g,e),uQ(n.b[t.g],t.g,i)}function xZ(n,t,e){return uM(pK(e.a))<=n&&uM(pK(e.b))>=t}function RZ(n,t){this.g=n,this.d=Uhn(cT(pbt,1),e6n,10,0,[t])}function KZ(n){this.c=n,this.b=new Hj(uG(WW(new pn),50))}function FZ(n){this.c=n,this.b=new Hj(uG(WW(new jt),50))}function _Z(n){this.b=n,this.a=new Hj(uG(WW(new nt),50))}function BZ(){this.b=new ek,this.d=new lS,this.e=new Ok}function HZ(){this.c=new sj,this.d=new sj,this.e=new sj}function UZ(){this.a=new Uk,this.b=(man(3,g1n),new R7(3))}function GZ(n,t){this.e=n,this.a=dat,this.b=$Bn(t),this.c=t}function qZ(n){this.c=n.c,this.d=n.d,this.b=n.b,this.a=n.a}function XZ(n,t,e,i,r,c){this.a=n,Ran.call(this,t,e,i,r,c)}function zZ(n,t,e,i,r,c){this.a=n,Ran.call(this,t,e,i,r,c)}function VZ(n,t,e,i,r,c,a){return new i8(n.e,t,e,i,r,c,a)}function WZ(n,t,e){return e>=0&&m_(n.substr(e,t.length),t)}function QZ(n,t){return F$(t,149)&&m_(n.b,uG(t,149).Pg())}function JZ(n,t){return n.a?t.Gh().Kc():uG(t.Gh(),71).Ii()}function YZ(n,t){var e;return w8(e=n.b.Qc(t),n.b.gc()),e}function ZZ(n,t){if(null==n)throw hv(new MM(t));return n}function n1(n){return n.u||(y9(n),n.u=new aF(n,n)),n.u}function t1(n){this.a=(hZ(),F$(n,59)?new eT(n):new gx(n))}function e1(n){return uG(Lsn(n,16),29)||n.ii()}function i1(n,t){var e;return e=Ij(n.Rm),null==t?e:e+": "+t}function r1(n,t,e){return Knn(t,e,n.length),n.substr(t,e-t)}function c1(n,t){HF.call(this),Qrn(this),this.a=n,this.c=t}function a1(n){n&&i1(n,n.ie()),String.fromCharCode(10)}function o1(n){XM(),e.setTimeout((function(){throw n}),0)}function u1(){return _kn(),Uhn(cT(nst,1),p1n,436,0,[Wut,Vut])}function s1(){return Xin(),Uhn(cT(mst,1),p1n,435,0,[Yut,Zut])}function h1(){return zin(),Uhn(cT(mlt,1),p1n,432,0,[gft,pft])}function f1(){return Aun(),Uhn(cT(Dbt,1),p1n,517,0,[Obt,Ibt])}function l1(){return Y6(),Uhn(cT(Nmt,1),p1n,429,0,[kpt,ypt])}function b1(){return Vin(),Uhn(cT(Mgt,1),p1n,428,0,[dgt,ggt])}function w1(){return H7(),Uhn(cT(tgt,1),p1n,431,0,[Vdt,Wdt])}function d1(){return nin(),Uhn(cT(Jjt,1),p1n,430,0,[Gjt,qjt])}function g1(){return Z6(),Uhn(cT(cSt,1),p1n,531,0,[YEt,JEt])}function p1(){return pon(),Uhn(cT(iIt,1),p1n,501,0,[VCt,WCt])}function m1(){return b0(),Uhn(cT(gSt,1),p1n,523,0,[fSt,hSt])}function v1(){return w0(),Uhn(cT(xSt,1),p1n,522,0,[wSt,dSt])}function k1(){return _7(),Uhn(cT(qSt,1),p1n,528,0,[DSt,$St])}function y1(){return Wtn(),Uhn(cT(Hgt,1),p1n,488,0,[Ngt,Lgt])}function M1(){return a9(),Uhn(cT(CAt,1),p1n,491,0,[yAt,MAt])}function T1(){return rhn(),Uhn(cT($At,1),p1n,492,0,[OAt,AAt])}function j1(){return i3(),Uhn(cT(QCt,1),p1n,433,0,[_Ct,FCt])}function E1(){return Ptn(),Uhn(cT(lIt,1),p1n,434,0,[cIt,aIt])}function S1(){return l0(),Uhn(cT(JSt,1),p1n,465,0,[USt,GSt])}function P1(){return B7(),Uhn(cT(uLt,1),p1n,438,0,[nLt,ZAt])}function C1(){return Vhn(),Uhn(cT(JLt,1),p1n,437,0,[VLt,zLt])}function I1(){return CU(),Uhn(cT(jKt,1),p1n,347,0,[gKt,pKt])}function O1(n,t,e,i){return e>=0?n.Uh(t,e,i):n.Ch(null,e,i)}function A1(n){return 0==n.b.b?n.a.sf():tG(n.b)}function L1(n){if(5!=n.p)throw hv(new xv);return pz(n.f)}function N1(n){if(5!=n.p)throw hv(new xv);return pz(n.k)}function $1(n){return xA(n.a)===xA((Oun(),Q_t))&&eVn(n),n.a}function D1(n,t){n.b=t,n.c>0&&n.b>0&&(n.g=mX(n.c,n.b,n.a))}function x1(n,t){n.c=t,n.c>0&&n.b>0&&(n.g=mX(n.c,n.b,n.a))}function R1(n,t){nw(this,new MO(n.a,n.b)),tw(this,oG(t))}function K1(){Py.call(this,new sS(orn(12))),FD(!0),this.a=2}function F1(n,t,e){QYn(),Qm.call(this,n),this.b=t,this.a=e}function _1(n,t,e){ZN(),Hm.call(this,t),this.a=n,this.b=e}function B1(n){var t;t=n.c.d.b,n.b=t,n.a=n.c.d,t.a=n.c.d.b=n}function H1(n){return 0==n.b?null:(MK(0!=n.b),Lrn(n,n.a.a))}function U1(n,t){return null==t?DA(FX(n.f,null)):_P(n.i,t)}function G1(n,t,e,i,r){return new AOn(n,(Rtn(),vut),t,e,i,r)}function q1(n,t){return V5(t),Jcn(n,Inn(YHt,W1n,28,t,15,1),t)}function X1(n,t){return bZ(n,"set1"),bZ(t,"set2"),new GE(n,t)}function z1(n,t){var e=Rat[n.charCodeAt(0)];return null==e?n:e}function V1(n,t){var e;return pWn(n,t,e=new B),e.d}function W1(n,t,e,i){var r;r=new AF,t.a[e.g]=r,UV(n.b,i,r)}function Q1(n,t){return JF(BR(Lcn(n.f,t)),n.f.d)}function J1(n){Lan(n.a),zN(n.a),Apn(new Ad(n.a))}function Y1(n,t){iBn(n,!0),Prn(n.e.Rf(),new DB(n,!0,t))}function Z1(n,t){return lZ(),n==R0(bIn(t))||n==R0(gIn(t))}function n0(n,t){return tcn(),uG(oIn(t,(QGn(),ACt)),17).a==n}function t0(n){return 0|Math.max(Math.min(n,vZn),-2147483648)}function e0(n){this.a=uG(WW(n),277),this.b=(hZ(),new mx(n))}function i0(n,t,e){this.i=new Zm,this.b=n,this.g=t,this.a=e}function r0(n,t,e){this.a=new Zm,this.e=n,this.f=t,this.c=e}function c0(n,t,e){this.c=new Zm,this.e=n,this.f=t,this.b=e}function a0(n){HF.call(this),Qrn(this),this.a=n,this.c=!0}function o0(n){function t(){}return t.prototype=n||{},new t}function u0(n){if(n.Ae())return null;var t=n.n;return sZn[t]}function s0(n){return n.Db>>16!=3?null:uG(n.Cb,27)}function h0(n){return n.Db>>16!=9?null:uG(n.Cb,27)}function f0(n){return n.Db>>16!=6?null:uG(n.Cb,74)}function l0(){l0=E,USt=new XI(z2n,0),GSt=new XI(V2n,1)}function b0(){b0=E,fSt=new OI(V2n,0),hSt=new OI(z2n,1)}function w0(){w0=E,wSt=new AI(c3n,0),dSt=new AI("UP",1)}function d0(){d0=E,Aat=Abn((Hy(),Uhn(cT(Lat,1),p1n,549,0,[Iat])))}function g0(n){var t;return Dfn(t=new Dj(orn(n.length)),n),t}function p0(n,t){return n.b+=t.b,n.c+=t.c,n.d+=t.d,n.a+=t.a,n}function m0(n,t){return!!Chn(n,t)&&(lan(n),!0)}function v0(n,t){if(null==t)throw hv(new Rv);return Tvn(n,t)}function k0(n,t){var e;e=n.q.getHours(),n.q.setDate(t),Iqn(n,e)}function y0(n,t,e){var i;(i=n.Ih(t))>=0?n.bi(i,e):lRn(n,t,e)}function M0(n,t){var e;return(e=n.Ih(t))>=0?n.Wh(e):$Nn(n,t)}function T0(n,t){var e;for(WW(t),e=n.a;e;e=e.c)t.Yd(e.g,e.i)}function j0(n,t,e){var i;i=Ufn(n,t,e),n.b=new Don(i.c.length)}function E0(n,t,e){W0(),n&&vJ(LFt,n,t),n&&vJ(AFt,n,e)}function S0(n,t){return UB(),qx(),uG(t.a,17).a0}function O0(n){var t;return t=n.d,t=n.bj(n.f),ttn(n,t),t.Ob()}function A0(n,t){var e;return zCn(e=new aX(t),n),new Z_(e)}function L0(n){if(0!=n.p)throw hv(new xv);return HA(n.f,0)}function N0(n){if(0!=n.p)throw hv(new xv);return HA(n.k,0)}function $0(n){return n.Db>>16!=7?null:uG(n.Cb,241)}function D0(n){return n.Db>>16!=6?null:uG(n.Cb,241)}function x0(n){return n.Db>>16!=7?null:uG(n.Cb,167)}function R0(n){return n.Db>>16!=11?null:uG(n.Cb,27)}function K0(n){return n.Db>>16!=17?null:uG(n.Cb,29)}function F0(n){return n.Db>>16!=3?null:uG(n.Cb,155)}function _0(n){return vgn(n),JJ(n,new Md(new ek))}function B0(n,t){var e=n.a=n.a||[];return e[t]||(e[t]=n.ve(t))}function H0(n,t){var e;e=n.q.getHours(),n.q.setMonth(t),Iqn(n,e)}function U0(n,t){LD(this),this.f=t,this.g=n,KY(this),this.je()}function G0(n,t){this.a=n,this.c=D$(this.a),this.b=new qZ(t)}function q0(n,t,e){this.a=t,this.c=n,this.b=(WW(e),new Z_(e))}function X0(n,t,e){this.a=t,this.c=n,this.b=(WW(e),new Z_(e))}function z0(n){this.a=n,this.b=Inn(WEt,zZn,2043,n.e.length,0,2)}function V0(){this.a=new XL,this.e=new ek,this.g=0,this.i=0}function W0(){W0=E,LFt=new Ym,AFt=new Ym,pA(iut,new fs)}function Q0(){Q0=E,jEt=wz(new wJ,(uIn(),Plt),(zYn(),Owt))}function J0(){J0=E,EEt=wz(new wJ,(uIn(),Plt),(zYn(),Owt))}function Y0(){Y0=E,PEt=wz(new wJ,(uIn(),Plt),(zYn(),Owt))}function Z0(){Z0=E,tSt=Aq(new wJ,(uIn(),Plt),(zYn(),ewt))}function n2(){n2=E,aSt=Aq(new wJ,(uIn(),Plt),(zYn(),ewt))}function t2(){t2=E,sSt=Aq(new wJ,(uIn(),Plt),(zYn(),ewt))}function e2(){e2=E,mSt=Aq(new wJ,(uIn(),Plt),(zYn(),ewt))}function i2(n,t,e,i,r,c){return new Ken(n.e,t,n.Lj(),e,i,r,c)}function r2(n,t,e){return null==t?VAn(n.f,null,e):kgn(n.i,t,e)}function c2(n,t){n.c&&men(n.c.g,n),n.c=t,n.c&&kD(n.c.g,n)}function a2(n,t){n.c&&men(n.c.a,n),n.c=t,n.c&&kD(n.c.a,n)}function o2(n,t){n.i&&men(n.i.j,n),n.i=t,n.i&&kD(n.i.j,n)}function u2(n,t){n.d&&men(n.d.e,n),n.d=t,n.d&&kD(n.d.e,n)}function s2(n,t){n.a&&men(n.a.k,n),n.a=t,n.a&&kD(n.a.k,n)}function h2(n,t){n.b&&men(n.b.f,n),n.b=t,n.b&&kD(n.b.f,n)}function f2(n,t){dQ(n,n.b,n.c),uG(n.b.b,68),t&&uG(t.b,68).b}function l2(n,t){return ugn(uG(n.c,65).c.e.b,uG(t.c,65).c.e.b)}function b2(n,t){return ugn(uG(n.c,65).c.e.a,uG(t.c,65).c.e.a)}function w2(n){return Mbn(),qx(),0!=uG(n.a,86).d.e}function d2(n,t){F$(n.Cb,184)&&(uG(n.Cb,184).tb=null),qon(n,t)}function g2(n,t){F$(n.Cb,90)&&yLn(y9(uG(n.Cb,90)),4),qon(n,t)}function p2(n,t){Pgn(n,t),F$(n.Cb,90)&&yLn(y9(uG(n.Cb,90)),2)}function m2(n,t){null!=t.c&&pQ(n,new QW(t.c))}function v2(n){var t;return vj(),Urn(t=new ev,n),t}function k2(n){var t;return vj(),Urn(t=new ev,n),t}function y2(n){for(var t;;)if(t=n.Pb(),!n.Ob())return t}function M2(n,t,e){return kD(n.a,(TJ(),IMn(t,e),new FE(t,e))),n}function T2(n,t){return PP(),ein(t)?new Cq(t,n):new OA(t,n)}function j2(n){return cHn(),dwn(n,0)>=0?Rmn(n):hW(Rmn(Men(n)))}function E2(n){var t;return t=uG(tq(n.b),9),new nB(n.a,t,n.c)}function S2(n,t){var e;return(e=uG(Xwn(nZ(n.a),t),16))?e.gc():0}function P2(n,t,e){var i;hdn(t,e,n.c.length),i=e-t,nE(n.c,t,i)}function C2(n,t,e){hdn(t,e,n.gc()),this.c=n,this.a=t,this.b=e-t}function I2(n){this.c=new lS,this.b=n.b,this.d=n.c,this.a=n.a}function O2(n){this.a=e.Math.cos(n),this.b=e.Math.sin(n)}function A2(n,t,e,i){this.c=n,this.d=i,s2(this,t),h2(this,e)}function L2(n,t){Ey.call(this,new sS(orn(n))),man(t,XZn),this.a=t}function N2(n,t,e){return new AOn(n,(Rtn(),mut),null,!1,t,e)}function $2(n,t,e){return new AOn(n,(Rtn(),kut),t,e,null,!1)}function D2(){return ybn(),Uhn(cT(Rut,1),p1n,108,0,[Cut,Iut,Out])}function x2(){return Yen(),Uhn(cT(hht,1),p1n,472,0,[Fst,Kst,Rst])}function R2(){return Ktn(),Uhn(cT(xst,1),p1n,471,0,[Ast,Ost,Lst])}function K2(){return Yrn(),Uhn(cT(Ist,1),p1n,237,0,[jst,Est,Sst])}function F2(){return Jen(),Uhn(cT(Clt,1),p1n,391,0,[glt,dlt,plt])}function _2(){return gon(),Uhn(cT(Rdt,1),p1n,372,0,[Sdt,Edt,jdt])}function B2(){return jan(),Uhn(cT(agt,1),p1n,322,0,[Zdt,Ydt,ngt])}function H2(){return ran(),Uhn(cT(bgt,1),p1n,351,0,[igt,cgt,rgt])}function U2(){return Pfn(),Uhn(cT(Ogt,1),p1n,460,0,[kgt,vgt,ygt])}function G2(){return ihn(),Uhn(cT(mpt,1),p1n,299,0,[fpt,lpt,hpt])}function q2(){return Zen(),Uhn(cT(Mpt,1),p1n,311,0,[gpt,ppt,dpt])}function X2(){return Cwn(),Uhn(cT(pjt,1),p1n,390,0,[ujt,sjt,hjt])}function z2(){return can(),Uhn(cT(eEt,1),p1n,463,0,[Qjt,Vjt,Wjt])}function V2(){return isn(),Uhn(cT(oEt,1),p1n,387,0,[Zjt,nEt,tEt])}function W2(){return Sln(),Uhn(cT(lEt,1),p1n,349,0,[aEt,rEt,cEt])}function Q2(){return kbn(),Uhn(cT(pEt,1),p1n,350,0,[sEt,hEt,fEt])}function J2(){return ian(),Uhn(cT(MEt,1),p1n,352,0,[gEt,wEt,dEt])}function Y2(){return zhn(),Uhn(cT(xEt,1),p1n,388,0,[kEt,yEt,vEt])}function Z2(){return ean(),Uhn(cT(qEt,1),p1n,464,0,[_Et,BEt,HEt])}function n3(n){return Gfn(Uhn(cT(PNt,1),zZn,8,0,[n.i.n,n.n,n.a]))}function t3(){return Pln(),Uhn(cT(RCt,1),p1n,392,0,[gPt,dPt,wPt])}function e3(){e3=E,UCt=wz(new wJ,(Cjn(),WSt),(OHn(),ePt))}function i3(){i3=E,_Ct=new JI("DFS",0),FCt=new JI("BFS",1)}function r3(n,t,e){var i;(i=new ia).b=t,i.a=e,++t.b,kD(n.d,i)}function c3(n,t,e){var i;JF(i=new eN(e.d),n),jgn(t,i.a,i.b)}function a3(n,t){pD(n,pz(E3($z(t,24),W0n)),pz(E3(t,W0n)))}function o3(n,t){if(n<0||n>t)throw hv(new dM(h2n+n+f2n+t))}function u3(n,t){if(n<0||n>=t)throw hv(new dM(h2n+n+f2n+t))}function s3(n,t){if(n<0||n>=t)throw hv(new JM(h2n+n+f2n+t))}function h3(n,t){this.b=(tJ(n),n),this.a=t&j0n?t:64|t|VZn}function f3(n){return vgn(n),sZ(),sZ(),krn(n,Yot)}function l3(n,t,e){var i;return(i=uXn(n,t,!1)).b<=t&&i.a<=e}function b3(){return den(),Uhn(cT(LAt,1),p1n,439,0,[EAt,PAt,SAt])}function w3(){return Bgn(),Uhn(cT(kAt,1),p1n,394,0,[IOt,OOt,COt])}function d3(){return Jmn(),Uhn(cT(dOt,1),p1n,445,0,[oOt,uOt,sOt])}function g3(){return Zyn(),Uhn(cT(AOt,1),p1n,456,0,[lOt,wOt,bOt])}function p3(){return vbn(),Uhn(cT(nOt,1),p1n,393,0,[sIt,hIt,fIt])}function m3(){return esn(),Uhn(cT(hOt,1),p1n,300,0,[iOt,rOt,eOt])}function v3(){return Own(),Uhn(cT(Kxt,1),p1n,346,0,[Oxt,Ixt,Axt])}function k3(){return Rdn(),Uhn(cT(VAt,1),p1n,444,0,[HAt,UAt,GAt])}function y3(){return Zrn(),Uhn(cT(lxt,1),p1n,278,0,[ixt,rxt,cxt])}function M3(){return Iwn(),Uhn(cT(mKt,1),p1n,280,0,[lKt,fKt,bKt])}function T3(n){return WW(n),F$(n,16)?new Z_(uG(n,16)):rG(n.Kc())}function j3(n,t){return n&&n.equals?n.equals(t):xA(n)===xA(t)}function E3(n,t){return Esn(Oz(_L(n)?Gsn(n):n,_L(t)?Gsn(t):t))}function S3(n,t){return Esn(Az(_L(n)?Gsn(n):n,_L(t)?Gsn(t):t))}function P3(n,t){return Esn(Lz(_L(n)?Gsn(n):n,_L(t)?Gsn(t):t))}function C3(n,t){var e;return kK(!!(e=(tJ(n),n).g)),tJ(t),e(t)}function I3(n,t){var e,i;return i=KV(n,t),e=n.a.fd(i),new BE(n,e)}function O3(n){return n.Db>>16!=6?null:uG(J$n(n),241)}function A3(n){if(2!=n.p)throw hv(new xv);return pz(n.f)&D1n}function L3(n){if(2!=n.p)throw hv(new xv);return pz(n.k)&D1n}function N3(n){return MK(n.ai?1:0}function Y3(n,t){var e;return e=jen(t),uG(cQ(n.c,e),17).a}function Z3(n,t,e){var i;i=n.d[t.p],n.d[t.p]=n.d[e.p],n.d[e.p]=i}function n4(n,t,e){var i;n.n&&t&&e&&(i=new Yu,kD(n.e,i))}function t4(n,t){if(FV(n.a,t),t.d)throw hv(new Ky(p2n));t.d=n}function e4(n,t){this.a=new Zm,this.d=new Zm,this.f=n,this.c=t}function i4(){this.c=new z$,this.a=new p7,this.b=new yk,XS()}function r4(){Whn(),this.b=new Ym,this.a=new Ym,this.c=new Zm}function c4(n,t,e){this.d=n,this.j=t,this.e=e,this.o=-1,this.p=3}function a4(n,t,e){this.d=n,this.k=t,this.f=e,this.o=-1,this.p=5}function o4(n,t,e,i,r,c){Bcn.call(this,n,t,e,i,r),c&&(this.o=-2)}function u4(n,t,e,i,r,c){Hcn.call(this,n,t,e,i,r),c&&(this.o=-2)}function s4(n,t,e,i,r,c){E9.call(this,n,t,e,i,r),c&&(this.o=-2)}function h4(n,t,e,i,r,c){qcn.call(this,n,t,e,i,r),c&&(this.o=-2)}function f4(n,t,e,i,r,c){S9.call(this,n,t,e,i,r),c&&(this.o=-2)}function l4(n,t,e,i,r,c){Ucn.call(this,n,t,e,i,r),c&&(this.o=-2)}function b4(n,t,e,i,r,c){Gcn.call(this,n,t,e,i,r),c&&(this.o=-2)}function w4(n,t,e,i,r,c){P9.call(this,n,t,e,i,r),c&&(this.o=-2)}function d4(n,t,e,i){Hm.call(this,e),this.b=n,this.c=t,this.d=i}function g4(n,t){this.f=n,this.a=(N7(),MBt),this.c=MBt,this.b=t}function p4(n,t){this.g=n,this.d=(N7(),TBt),this.a=TBt,this.b=t}function m4(n,t){!n.c&&(n.c=new wsn(n,0)),BXn(n.c,(uVn(),nHt),t)}function v4(n,t){return lxn(n,t,F$(t,102)&&!!(uG(t,19).Bb&P0n))}function k4(n,t){return rW(Bsn(n.q.getTime()),Bsn(t.q.getTime()))}function y4(n){return Dq(n.e.Rd().gc()*n.c.Rd().gc(),16,new zl(n))}function M4(n){return!(!n.u||0==z5(n.u.a).i||n.n&&yMn(n.n))}function T4(n){return!(!n.a||0==Aen(n.a.a).i||n.b&&MMn(n.b))}function j4(n,t){return 0==t?!!n.o&&0!=n.o.f:Wkn(n,t)}function E4(n,t,e){var i;return!!(i=uG(n.Zb().xc(t),16))&&i.Hc(e)}function S4(n,t,e){var i;return!!(i=uG(n.Zb().xc(t),16))&&i.Mc(e)}function P4(n,t){var e;return e=1-t,n.a[e]=Ton(n.a[e],e),Ton(n,t)}function C4(n,t){var e;return e=E3(n,L0n),S3(Nz(t,32),e)}function I4(n,t,e){WW(n),mjn(new q0(new Z_(n),t,e))}function O4(n,t,e){WW(n),vjn(new X0(new Z_(n),t,e))}function A4(n,t,e,i,r,c){return Dsn(n,t,e,c),gdn(n,i),vdn(n,r),n}function L4(n,t,e,i){return n.a+=""+r1(null==t?IZn:cpn(t),e,i),n}function N4(n,t){this.a=n,Jw.call(this,n),o3(t,n.gc()),this.b=t}function $4(n){this.a=Inn(dat,EZn,1,pfn(e.Math.max(8,n))<<1,5,1)}function D4(n){return uG(Ekn(n,Inn(pbt,e6n,10,n.c.length,0,1)),199)}function x4(n){return uG(Ekn(n,Inn(obt,t6n,18,n.c.length,0,1)),483)}function R4(n){return n.a?0==n.e.length?n.a.a:n.a.a+""+n.e:n.c}function K4(n){for(;n.d>0&&0==n.a[--n.d];);0==n.a[n.d++]&&(n.e=0)}function F4(n){return MK(n.b.b!=n.d.a),n.c=n.b=n.b.b,--n.a,n.c.c}function _4(n,t,e){n.a=t,n.c=e,n.b.a.$b(),BY(n.d),Xv(n.e.a.c,0)}function B4(n,t){var e;n.e=new dy,f$(e=GFn(t),n.c),T_n(n,e,0)}function H4(n,t,e,i){var r;(r=new gu).a=t,r.b=e,r.c=i,aq(n.a,r)}function U4(n,t,e,i){var r;(r=new gu).a=t,r.b=e,r.c=i,aq(n.b,r)}function G4(n,t,e){if(n<0||te)throw hv(new dM(QOn(n,t,e)))}function q4(n,t){if(n<0||n>=t)throw hv(new dM(TLn(n,t)));return n}function X4(n){if(!("stack"in n))try{throw n}catch(t){}return n}function z4(n){return JS(),F$(n.g,10)?uG(n.g,10):null}function V4(n){return!uY(n).dc()&&(h$(n,new w),!0)}function W4(n){var t;return _L(n)?-0==(t=n)?0:t:Gen(n)}function Q4(n,t){return!!F$(t,44)&&sTn(n.a,uG(t,44))}function J4(n,t){return!!F$(t,44)&&sTn(n.a,uG(t,44))}function Y4(n,t){return!!F$(t,44)&&sTn(n.a,uG(t,44))}function Z4(n){var t;return GQ(n),t=new D,tE(n.a,new vd(t)),t}function n6(){var n,t;return n=new ev,kD(gBt,t=n),t}function t6(n){var t;return GQ(n),t=new x,tE(n.a,new kd(t)),t}function e6(n,t){return n.a<=n.b&&(t.Dd(n.a++),!0)}function i6(n){dun.call(this,n,(Rtn(),put),null,!1,null,!1)}function r6(){r6=E,_ht=Abn((BS(),Uhn(cT(oft,1),p1n,489,0,[Kht])))}function c6(){c6=E,$Et=MJ(xwn(1),xwn(4)),NEt=MJ(xwn(1),xwn(2))}function a6(n,t){return new LU(t,HR(D$(t.e),n,n),(qx(),!0))}function o6(n){return new R7((man(n,v1n),arn(Lgn(Lgn(5,n),n/10|0))))}function u6(n){return Dq(n.e.Rd().gc()*n.c.Rd().gc(),273,new Xl(n))}function s6(n){return uG(Ekn(n,Inn(Abt,i6n,12,n.c.length,0,1)),2042)}function h6(n){return n2(),!(v9(n)||!v9(n)&&n.c.i.c==n.d.i.c)}function f6(n,t){return ncn(),uG(oIn(t,(QGn(),kCt)),17).a>=n.gc()}function l6(n,t){_Jn(t,n),NG(n.d),NG(uG(oIn(n,(jYn(),SMt)),214))}function b6(n,t){BJn(t,n),$G(n.d),$G(uG(oIn(n,(jYn(),SMt)),214))}function w6(n,t,e){n.d&&men(n.d.e,n),n.d=t,n.d&&GX(n.d.e,e,n)}function d6(n,t,e){return e.f.c.length>0?HV(n.a,t,e):HV(n.b,t,e)}function g6(n,t,e){var i;i=bkn();try{return SF(n,t,e)}finally{m8(i)}}function p6(n,t){var e,i;return i=null,(e=v0(n,t))&&(i=e.pe()),i}function m6(n,t){var e,i;return i=null,(e=v0(n,t))&&(i=e.se()),i}function v6(n,t){var e,i;return i=null,(e=uin(n,t))&&(i=e.se()),i}function k6(n,t){var e,i;return i=null,(e=v0(n,t))&&(i=uAn(e)),i}function y6(n,t,e){var i;return i=jvn(e),yHn(n.g,i,t),yHn(n.i,t,e),t}function M6(n,t,e){this.d=new qg(this),this.e=n,this.i=t,this.f=e}function T6(n,t,e,i){this.e=null,this.c=n,this.d=t,this.a=e,this.b=i}function j6(n,t,e,i){A$(this),this.c=n,this.e=t,this.f=e,this.b=i}function E6(n,t,e,i){this.d=n,this.n=t,this.g=e,this.o=i,this.p=-1}function S6(n,t,e,i){return F$(e,59)?new Yx(n,t,e,i):new qz(n,t,e,i)}function P6(n){return F$(n,16)?uG(n,16).dc():!n.Kc().Ob()}function C6(n){if(n.e.g!=n.b)throw hv(new Fv);return!!n.c&&n.d>0}function I6(n){return MK(n.b!=n.d.c),n.c=n.b,n.b=n.b.a,++n.a,n.c.c}function O6(n,t){tJ(t),uQ(n.a,n.c,t),n.c=n.c+1&n.a.length-1,JTn(n)}function A6(n,t){tJ(t),n.b=n.b-1&n.a.length-1,uQ(n.a,n.b,t),JTn(n)}function L6(n){var t;t=n.Gh(),this.a=F$(t,71)?uG(t,71).Ii():t.Kc()}function N6(n){return new h3(Vrn(uG(n.a.md(),16).gc(),n.a.ld()),16)}function $6(){$6=E,WAt=Abn((nP(),Uhn(cT(JAt,1),p1n,490,0,[zAt])))}function D6(){D6=E,YAt=Abn((tP(),Uhn(cT(tLt,1),p1n,558,0,[QAt])))}function x6(){x6=E,XLt=Abn((eP(),Uhn(cT(WLt,1),p1n,539,0,[GLt])))}function R6(){return Uvn(),Uhn(cT(abt,1),p1n,389,0,[tbt,Zlt,Ylt,nbt])}function K6(){return Rtn(),Uhn(cT(Tut,1),p1n,304,0,[put,mut,vut,kut])}function F6(){return vyn(),Uhn(cT(Sht,1),p1n,332,0,[yht,kht,Mht,Tht])}function _6(){return myn(),Uhn(cT(Fht,1),p1n,406,0,[Nht,Lht,$ht,Dht])}function B6(){return ehn(),Uhn(cT(jht,1),p1n,417,0,[pht,wht,dht,ght])}function H6(){return Xhn(),Uhn(cT(ebt,1),p1n,416,0,[Flt,Hlt,_lt,Blt])}function U6(){return qhn(),Uhn(cT(mdt,1),p1n,421,0,[odt,udt,sdt,hdt])}function G6(){return Ghn(),Uhn(cT(adt,1),p1n,371,0,[zwt,qwt,Xwt,Gwt])}function q6(){return Yyn(),Uhn(cT(jjt,1),p1n,203,0,[djt,gjt,wjt,bjt])}function X6(){return yvn(),Uhn(cT(Xjt,1),p1n,284,0,[Fjt,Kjt,_jt,Bjt])}function z6(n){return n.j==(KQn(),KRt)&&$x(_$n(n),kRt)}function V6(n,t){var e;c2(e=t.a,t.c.d),u2(e,t.d.d),Xun(e.a,n.n)}function W6(n,t){var e;return!(e=uG(ain(n.b,t),67))&&(e=new lS),e}function Q6(n){return JS(),F$(n.g,154)?uG(n.g,154):null}function J6(n){n.a=null,n.e=null,Xv(n.b.c,0),Xv(n.f.c,0),n.c=null}function Y6(){Y6=E,kpt=new sI(G2n,0),ypt=new sI("TOP_LEFT",1)}function Z6(){Z6=E,YEt=new SI("UPPER",0),JEt=new SI("LOWER",1)}function n5(n,t){return bD(new MO(t.e.a+t.f.a/2,t.e.b+t.f.b/2),n)}function t5(n,t){return uG(yx(Wz(uG(Y9(n.k,t),15).Oc(),Fdt)),113)}function e5(n,t){return uG(yx(Qz(uG(Y9(n.k,t),15).Oc(),Fdt)),113)}function i5(){return Cjn(),Uhn(cT(ZSt,1),p1n,405,0,[zSt,VSt,WSt,QSt])}function r5(){return mbn(),Uhn(cT(BCt,1),p1n,353,0,[xCt,$Ct,DCt,NCt])}function c5(){return dTn(),Uhn(cT(cOt,1),p1n,354,0,[ZIt,JIt,YIt,QIt])}function a5(){return Qmn(),Uhn(cT(sKt,1),p1n,386,0,[QRt,JRt,WRt,VRt])}function o5(){return Ajn(),Uhn(cT(Wxt,1),p1n,291,0,[Rxt,$xt,Dxt,xxt])}function u5(){return _gn(),Uhn(cT(kxt,1),p1n,223,0,[fxt,sxt,uxt,hxt])}function s5(){return qpn(),Uhn(cT(SKt,1),p1n,320,0,[TKt,kKt,MKt,yKt])}function h5(){return Eln(),Uhn(cT(DKt,1),p1n,415,0,[CKt,IKt,PKt,OKt])}function f5(n){return W0(),PV(LFt,n)?uG(cQ(LFt,n),341).Qg():null}function l5(n,t,e){return t<0?$Nn(n,e):uG(e,69).wk().Bk(n,n.hi(),t)}function b5(n,t,e){var i;return i=jvn(e),yHn(n.j,i,t),vJ(n.k,t,e),t}function w5(n,t,e){var i;return i=jvn(e),yHn(n.d,i,t),vJ(n.e,t,e),t}function d5(n){var t;return gj(),t=new es,n&&ARn(t,n),t}function g5(n){var t;return t=n.aj(n.i),n.i>0&&qGn(n.g,0,t,0,n.i),t}function p5(n,t){var e;for(e=n.j.c.length;e>24}function y5(n){if(1!=n.p)throw hv(new xv);return pz(n.k)<<24>>24}function M5(n){if(7!=n.p)throw hv(new xv);return pz(n.k)<<16>>16}function T5(n){if(7!=n.p)throw hv(new xv);return pz(n.f)<<16>>16}function j5(n,t){return 0==t.e||0==n.e?_ot:(b_n(),yKn(n,t))}function E5(n,t){return xA(t)===xA(n)?"(this Map)":null==t?IZn:cpn(t)}function S5(n,t,e){return Rz(pK(DA(FX(n.f,t))),pK(DA(FX(n.f,e))))}function P5(n,t,e){var i;i=uG(cQ(n.g,e),60),kD(n.a.c,new WO(t,i))}function C5(n,t,e){n.i=0,n.e=0,t!=e&&(eln(n,t,e),tln(n,t,e))}function I5(n,t,e,i,r){kD(t,uLn(r,Bxn(r,e,i))),LIn(n,r,t)}function O5(n,t,e,i,r){this.i=n,this.a=t,this.e=e,this.j=i,this.f=r}function A5(n,t){HZ.call(this),this.a=n,this.b=t,kD(this.a.b,this)}function L5(n){this.b=new Ym,this.c=new Ym,this.d=new Ym,this.a=n}function N5(n,t){var e;return e=new QM,n.Gd(e),e.a+="..",t.Hd(e),e.a}function $5(n,t){var e;for(e=t;e;)KR(n,e.i,e.j),e=R0(e);return n}function D5(n,t,e){var i;return i=jvn(e),vJ(n.b,i,t),vJ(n.c,t,e),t}function x5(n){var t;for(t=0;n.Ob();)n.Pb(),t=Lgn(t,1);return arn(t)}function R5(n,t){var e;return PP(),uOn(e=uG(n,69).vk(),t),e.xl(t)}function K5(n,t,e){if(e){var i=e.oe();n.a[t]=i(e)}else delete n.a[t]}function F5(n,t){var e;e=n.q.getHours(),n.q.setFullYear(t+V1n),Iqn(n,e)}function _5(n,t){return uG(null==t?DA(FX(n.f,null)):_P(n.i,t),288)}function B5(n,t){return n==(zIn(),dbt)&&t==dbt?4:n==dbt||t==dbt?8:32}function H5(n,t,e){return aqn(n,t,e,F$(t,102)&&!!(uG(t,19).Bb&P0n))}function U5(n,t,e){return Dqn(n,t,e,F$(t,102)&&!!(uG(t,19).Bb&P0n))}function G5(n,t,e){return Cxn(n,t,e,F$(t,102)&&!!(uG(t,19).Bb&P0n))}function q5(n){n.b!=n.c&&(n.a=Inn(dat,EZn,1,8,5,1),n.b=0,n.c=0)}function X5(n){return MK(n.a=0&&n.a[e]===t[e];e--);return e<0}function g8(n){var t;return n?new aX(n):(Fon(t=new XL,n),t)}function p8(n,t){var e,i;i=!1;do{i|=e=Tfn(n,t)}while(e);return i}function m8(n){n&&Cin((Gy(),Fat)),--Uat,n&&-1!=qat&&(jL(qat),qat=-1)}function v8(n){aCn(),pD(this,pz(E3($z(n,24),W0n)),pz(E3(n,W0n)))}function k8(){k8=E,Jut=Abn((_kn(),Uhn(cT(nst,1),p1n,436,0,[Wut,Vut])))}function y8(){y8=E,tst=Abn((Xin(),Uhn(cT(mst,1),p1n,435,0,[Yut,Zut])))}function M8(){M8=E,vft=Abn((zin(),Uhn(cT(mlt,1),p1n,432,0,[gft,pft])))}function T8(){T8=E,Lbt=Abn((Aun(),Uhn(cT(Dbt,1),p1n,517,0,[Obt,Ibt])))}function j8(){j8=E,Tpt=Abn((Y6(),Uhn(cT(Nmt,1),p1n,429,0,[kpt,ypt])))}function E8(){E8=E,mgt=Abn((Vin(),Uhn(cT(Mgt,1),p1n,428,0,[dgt,ggt])))}function S8(){S8=E,Dgt=Abn((Wtn(),Uhn(cT(Hgt,1),p1n,488,0,[Ngt,Lgt])))}function P8(){P8=E,zjt=Abn((nin(),Uhn(cT(Jjt,1),p1n,430,0,[Gjt,qjt])))}function C8(){C8=E,nSt=Abn((Z6(),Uhn(cT(cSt,1),p1n,531,0,[YEt,JEt])))}function I8(){I8=E,Jdt=Abn((H7(),Uhn(cT(tgt,1),p1n,431,0,[Vdt,Wdt])))}function O8(){O8=E,HCt=Abn((i3(),Uhn(cT(QCt,1),p1n,433,0,[_Ct,FCt])))}function A8(){A8=E,JCt=Abn((pon(),Uhn(cT(iIt,1),p1n,501,0,[VCt,WCt])))}function L8(){L8=E,bSt=Abn((b0(),Uhn(cT(gSt,1),p1n,523,0,[fSt,hSt])))}function N8(){N8=E,pSt=Abn((w0(),Uhn(cT(xSt,1),p1n,522,0,[wSt,dSt])))}function $8(){$8=E,RSt=Abn((_7(),Uhn(cT(qSt,1),p1n,528,0,[DSt,$St])))}function D8(){D8=E,XSt=Abn((l0(),Uhn(cT(JSt,1),p1n,465,0,[USt,GSt])))}function x8(){x8=E,uIt=Abn((Ptn(),Uhn(cT(lIt,1),p1n,434,0,[cIt,aIt])))}function R8(){R8=E,jAt=Abn((a9(),Uhn(cT(CAt,1),p1n,491,0,[yAt,MAt])))}function K8(){K8=E,NAt=Abn((rhn(),Uhn(cT($At,1),p1n,492,0,[OAt,AAt])))}function F8(){F8=E,eLt=Abn((B7(),Uhn(cT(uLt,1),p1n,438,0,[nLt,ZAt])))}function _8(){_8=E,QLt=Abn((Vhn(),Uhn(cT(JLt,1),p1n,437,0,[VLt,zLt])))}function B8(){B8=E,vKt=Abn((CU(),Uhn(cT(jKt,1),p1n,347,0,[gKt,pKt])))}function H8(){return xdn(),Uhn(cT(axt,1),p1n,88,0,[ZDt,YDt,JDt,QDt,nxt])}function U8(){return KQn(),Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt])}function G8(n,t,e){return uG(null==t?VAn(n.f,null,e):kgn(n.i,t,e),288)}function q8(n){return(n.k==(zIn(),dbt)||n.k==lbt)&&vR(n,(GYn(),$pt))}function X8(n){return n.c&&n.d?z3(n.c)+"->"+z3(n.d):"e_"+xx(n)}function z8(n,t){var e,i;for(tJ(t),i=n.Kc();i.Ob();)e=i.Pb(),t.Cd(e)}function V8(n,t){var e;vZ(e=new _y,"x",t.a),vZ(e,"y",t.b),pQ(n,e)}function W8(n,t){var e;vZ(e=new _y,"x",t.a),vZ(e,"y",t.b),pQ(n,e)}function Q8(n,t){var e;for(e=t;e;)KR(n,-e.i,-e.j),e=R0(e);return n}function J8(n,t){var e,i;for(e=t,i=0;e>0;)i+=n.a[e],e-=e&-e;return i}function Y8(n,t,e){var i;return u3(t,n.c.length),i=n.c[t],n.c[t]=e,i}function Z8(n,t,e){n.a.c.length=0,sVn(n,t,e),0==n.a.c.length||mUn(n,t)}function n9(n){n.i=0,FP(n.b,null),FP(n.c,null),n.a=null,n.e=null,++n.g}function t9(){t9=E,Nut=!0,Aut=!1,Lut=!1,Dut=!1,$ut=!1}function e9(n){t9(),Nut||(this.c=n,this.e=!0,this.a=new Zm)}function i9(n,t){this.c=0,this.b=t,iL.call(this,n,17493),this.a=this.c}function r9(n){NYn(),dv(this),this.a=new lS,Lln(this,n),aq(this.a,n)}function c9(){IN(this),this.b=new MO(M0n,M0n),this.a=new MO(T0n,T0n)}function a9(){a9=E,yAt=new oO(x6n,0),MAt=new oO("TARGET_WIDTH",1)}function o9(n,t){return(vgn(n),Qj(new fX(n,new ien(t,n.a)))).Bd(Kut)}function u9(){return uIn(),Uhn(cT(Llt,1),p1n,367,0,[Tlt,jlt,Elt,Slt,Plt])}function s9(){return gPn(),Uhn(cT(Pdt,1),p1n,375,0,[wdt,gdt,pdt,ddt,bdt])}function h9(){return kvn(),Uhn(cT(pgt,1),p1n,348,0,[sgt,ugt,fgt,lgt,hgt])}function f9(){return pyn(),Uhn(cT(xjt,1),p1n,323,0,[Tjt,kjt,yjt,vjt,Mjt])}function l9(){return Gpn(),Uhn(cT(ajt,1),p1n,171,0,[Lmt,Cmt,Imt,Omt,Amt])}function b9(){return zPn(),Uhn(cT(oIt,1),p1n,368,0,[tIt,YCt,eIt,ZCt,nIt])}function w9(){return _Rn(),Uhn(cT(qAt,1),p1n,373,0,[xAt,DAt,KAt,RAt,FAt])}function d9(){return pOn(),Uhn(cT(qLt,1),p1n,324,0,[iLt,rLt,oLt,cLt,aLt])}function g9(){return Rkn(),Uhn(cT(MNt,1),p1n,170,0,[hNt,sNt,oNt,fNt,uNt])}function p9(){return Vkn(),Uhn(cT(hRt,1),p1n,256,0,[Zxt,tRt,Jxt,Yxt,nRt])}function m9(n){return XM(),function(){return g6(n,this,arguments)}}function v9(n){return!(!n.c||!n.d||!n.c.i||n.c.i!=n.d.i)}function k9(n,t){return!!F$(t,143)&&m_(n.c,uG(t,143).c)}function y9(n){return n.t||(n.t=new $m(n),$dn(new Qy(n),0,n.t)),n.t}function M9(n){this.b=n,DD.call(this,n),this.a=uG(Lsn(this.b.a,4),129)}function T9(n){this.b=n,nR.call(this,n),this.a=uG(Lsn(this.b.a,4),129)}function j9(n,t,e,i,r){b7.call(this,t,i,r),Kf(this),this.c=n,this.b=e}function E9(n,t,e,i,r){c4.call(this,t,i,r),Kf(this),this.c=n,this.a=e}function S9(n,t,e,i,r){a4.call(this,t,i,r),Kf(this),this.c=n,this.a=e}function P9(n,t,e,i,r){b7.call(this,t,i,r),Kf(this),this.c=n,this.a=e}function C9(n,t){return uG(ain(n.d,t),23)||uG(ain(n.e,t),23)}function I9(n,t){var e,i;return e=t.ld(),!!(i=n.Fe(e))&&OJ(i.e,t.md())}function O9(n,t){var e;return new FE(e=t.ld(),n.e.pc(e,uG(t.md(),16)))}function A9(n,t){var e;return null==(e=n.a.get(t))?Inn(dat,EZn,1,0,5,1):e}function L9(n){var t;return t=n.length,m_(S0n.substr(S0n.length-t,t),n)}function N9(n){if(hDn(n))return n.c=n.a,n.a.Pb();throw hv(new Bv)}function $9(n,t){return 0==t||0==n.e?n:t>0?MFn(n,t):rvn(n,-t)}function D9(n,t){return 0==t||0==n.e?n:t>0?rvn(n,t):MFn(n,-t)}function x9(n){xP.call(this,null==n?IZn:cpn(n),F$(n,82)?uG(n,82):null)}function R9(n){var t;return n.c||F$(t=n.r,90)&&(n.c=uG(t,29)),n.c}function K9(n){var t;return zsn(t=new UZ,n),kfn(t,(jYn(),bMt),null),t}function F9(n){var t,e;return t=n.c.i,e=n.d.i,t.k==(zIn(),lbt)&&e.k==lbt}function _9(n){return p$(n&f0n,n>>22&f0n,n<0?l0n:0)}function B9(n){var t,e,i;for(e=0,i=(t=n).length;e=0?n.Lh(i,e,!0):YNn(n,t,e)}function G9(n,t,e){return ugn(bD($kn(n),D$(t.b)),bD($kn(n),D$(e.b)))}function q9(n,t,e){return ugn(bD($kn(n),D$(t.e)),bD($kn(n),D$(e.e)))}function X9(n,t){return e.Math.min(atn(t.a,n.d.d.c),atn(t.b,n.d.d.c))}function z9(n,t){n._i(n.i+1),yD(n,n.i,n.Zi(n.i,t)),n.Mi(n.i++,t),n.Ni()}function V9(n){var t,e;++n.j,t=n.g,e=n.i,n.g=null,n.i=0,n.Oi(e,t),n.Ni()}function W9(n,t,e){var i;xun(i=new U$(n.a),n.a.a),VAn(i.f,t,e),n.a.a=i}function Q9(n,t,e,i){var r;for(r=0;r<$st;r++)qX(n.a[r][t.g],e,i[t.g])}function J9(n,t,e,i){var r;for(r=0;rt)throw hv(new dM(iLn(n,t,"index")));return n}function i7(n,t){var e;return u3(t,n.c.length),e=n.c[t],nE(n.c,t,1),e}function r7(n,t){var e,i;return tJ(n),e=n,tJ(t),e==(i=t)?0:et.p?-1:0}function E7(n){var t;return n.a||F$(t=n.r,156)&&(n.a=uG(t,156)),n.a}function S7(n,t,e){return++n.e,--n.f,uG(n.d[t].gd(e),136).md()}function P7(n){var t;return t=n.ld(),JU(uG(n.md(),16).Nc(),new Wl(t))}function C7(n,t){return!!PV(n.a,t)&&(u7(n.a,t),!0)}function I7(n,t,e){return q4(t,n.e.Rd().gc()),q4(e,n.c.Rd().gc()),n.a[t][e]}function O7(n,t,e){this.a=n,this.b=t,this.c=e,kD(n.t,this),kD(t.i,this)}function A7(n,t,e,i){this.f=n,this.e=t,this.d=e,this.b=i,this.c=i?i.d:null}function L7(){this.b=new lS,this.a=new lS,this.b=new lS,this.a=new lS}function N7(){var n,t;N7=E,vj(),t=new Gv,MBt=t,n=new Wk,TBt=n}function $7(n){return vgn(n),new IK(n,new lG(n,n.a.e,4|n.a.d))}function D7(n){var t;for(GQ(n),t=0;n.a.Bd(new hn);)t=Lgn(t,1);return t}function x7(n,t){return tJ(t),n.c=0,"Initial capacity must not be negative")}function K7(){K7=E,jNt=new Cm("org.eclipse.elk.labels.labelManager")}function F7(){F7=E,Uwt=new uF("separateLayerConnections",(Ghn(),zwt))}function _7(){_7=E,DSt=new qI("REGULAR",0),$St=new qI("CRITICAL",1)}function B7(){B7=E,nLt=new lO("FIXED",0),ZAt=new lO("CENTER_NODE",1)}function H7(){H7=E,Vdt=new WC("QUADRATIC",0),Wdt=new WC("SCANLINE",1)}function U7(){U7=E,egt=Abn((jan(),Uhn(cT(agt,1),p1n,322,0,[Zdt,Ydt,ngt])))}function G7(){G7=E,ogt=Abn((ran(),Uhn(cT(bgt,1),p1n,351,0,[igt,cgt,rgt])))}function q7(){q7=E,Cdt=Abn((gon(),Uhn(cT(Rdt,1),p1n,372,0,[Sdt,Edt,jdt])))}function X7(){X7=E,Tgt=Abn((Pfn(),Uhn(cT(Ogt,1),p1n,460,0,[kgt,vgt,ygt])))}function z7(){z7=E,wpt=Abn((ihn(),Uhn(cT(mpt,1),p1n,299,0,[fpt,lpt,hpt])))}function V7(){V7=E,vpt=Abn((Zen(),Uhn(cT(Mpt,1),p1n,311,0,[gpt,ppt,dpt])))}function W7(){W7=E,ljt=Abn((Cwn(),Uhn(cT(pjt,1),p1n,390,0,[ujt,sjt,hjt])))}function Q7(){Q7=E,iEt=Abn((isn(),Uhn(cT(oEt,1),p1n,387,0,[Zjt,nEt,tEt])))}function J7(){J7=E,uEt=Abn((Sln(),Uhn(cT(lEt,1),p1n,349,0,[aEt,rEt,cEt])))}function Y7(){Y7=E,Yjt=Abn((can(),Uhn(cT(eEt,1),p1n,463,0,[Qjt,Vjt,Wjt])))}function Z7(){Z7=E,bEt=Abn((kbn(),Uhn(cT(pEt,1),p1n,350,0,[sEt,hEt,fEt])))}function nnn(){nnn=E,mEt=Abn((ian(),Uhn(cT(MEt,1),p1n,352,0,[gEt,wEt,dEt])))}function tnn(){tnn=E,TEt=Abn((zhn(),Uhn(cT(xEt,1),p1n,388,0,[kEt,yEt,vEt])))}function enn(){enn=E,mPt=Abn((Pln(),Uhn(cT(RCt,1),p1n,392,0,[gPt,dPt,wPt])))}function inn(){inn=E,bIt=Abn((vbn(),Uhn(cT(nOt,1),p1n,393,0,[sIt,hIt,fIt])))}function rnn(){rnn=E,aOt=Abn((esn(),Uhn(cT(hOt,1),p1n,300,0,[iOt,rOt,eOt])))}function cnn(){cnn=E,fOt=Abn((Jmn(),Uhn(cT(dOt,1),p1n,445,0,[oOt,uOt,sOt])))}function ann(){ann=E,gOt=Abn((Zyn(),Uhn(cT(AOt,1),p1n,456,0,[lOt,wOt,bOt])))}function onn(){onn=E,LOt=Abn((Bgn(),Uhn(cT(kAt,1),p1n,394,0,[IOt,OOt,COt])))}function unn(){unn=E,IAt=Abn((den(),Uhn(cT(LAt,1),p1n,439,0,[EAt,PAt,SAt])))}function snn(){snn=E,GEt=Abn((ean(),Uhn(cT(qEt,1),p1n,464,0,[_Et,BEt,HEt])))}function hnn(){hnn=E,Dst=Abn((Ktn(),Uhn(cT(xst,1),p1n,471,0,[Ast,Ost,Lst])))}function fnn(){fnn=E,Cst=Abn((Yrn(),Uhn(cT(Ist,1),p1n,237,0,[jst,Est,Sst])))}function lnn(){lnn=E,Bst=Abn((Yen(),Uhn(cT(hht,1),p1n,472,0,[Fst,Kst,Rst])))}function bnn(){bnn=E,xut=Abn((ybn(),Uhn(cT(Rut,1),p1n,108,0,[Cut,Iut,Out])))}function wnn(){wnn=E,vlt=Abn((Jen(),Uhn(cT(Clt,1),p1n,391,0,[glt,dlt,plt])))}function dnn(){dnn=E,Nxt=Abn((Own(),Uhn(cT(Kxt,1),p1n,346,0,[Oxt,Ixt,Axt])))}function gnn(){gnn=E,XAt=Abn((Rdn(),Uhn(cT(VAt,1),p1n,444,0,[HAt,UAt,GAt])))}function pnn(){pnn=E,oxt=Abn((Zrn(),Uhn(cT(lxt,1),p1n,278,0,[ixt,rxt,cxt])))}function mnn(){mnn=E,dKt=Abn((Iwn(),Uhn(cT(mKt,1),p1n,280,0,[lKt,fKt,bKt])))}function vnn(n,t){return!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),ymn(n.o,t)}function knn(n,t){var e;n.C&&((e=uG(AJ(n.b,t),127).n).d=n.C.d,e.a=n.C.a)}function ynn(n){var t,e,i,r;r=n.d,t=n.a,e=n.b,i=n.c,n.d=e,n.a=i,n.b=r,n.c=t}function Mnn(n){return!n.g&&(n.g=new ds),!n.g.b&&(n.g.b=new Om(n)),n.g.b}function Tnn(n){return!n.g&&(n.g=new ds),!n.g.c&&(n.g.c=new Nm(n)),n.g.c}function jnn(n){return!n.g&&(n.g=new ds),!n.g.d&&(n.g.d=new Am(n)),n.g.d}function Enn(n){return!n.g&&(n.g=new ds),!n.g.a&&(n.g.a=new Lm(n)),n.g.a}function Snn(n,t,e,i){return e&&(i=e.Rh(t,emn(e.Dh(),n.c.uk()),null,i)),i}function Pnn(n,t,e,i){return e&&(i=e.Th(t,emn(e.Dh(),n.c.uk()),null,i)),i}function Cnn(n,t,e,i){var r;return KGn(r=Inn(YHt,W1n,28,t+1,15,1),n,t,e,i),r}function Inn(n,t,e,i,r,c){var a;return a=PTn(r,i),10!=r&&Uhn(cT(n,c),t,e,r,a),a}function Onn(n,t,e){var i,r;for(r=new Zsn(t,n),i=0;ie||t=0?n.Lh(e,!0,!0):YNn(n,t,!0)}function ktn(n,t,e){var i;return i=Ufn(n,t,e),n.b=new Don(i.c.length),ZFn(n,i)}function ytn(n){if(n.b<=0)throw hv(new Bv);return--n.b,n.a-=n.c.c,xwn(n.a)}function Mtn(n){var t;if(!n.a)throw hv(new EY);return t=n.a,n.a=R0(n.a),t}function Ttn(n){for(;!n.a;)if(!y_(n.c,new yd(n)))return!1;return!0}function jtn(n){return WW(n),F$(n,204)?uG(n,204):new sb(n)}function Etn(n){Stn(),uG(n.of((XYn(),bDt)),181).Fc((eNn(),dRt)),n.qf(lDt,null)}function Stn(){Stn=E,tNt=new hu,iNt=new fu,eNt=Rln((XYn(),lDt),tNt,q$t,iNt)}function Ptn(){Ptn=E,cIt=new nO("LEAF_NUMBER",0),aIt=new nO("NODE_SIZE",1)}function Ctn(n){n.a=Inn(YHt,W1n,28,n.b+1,15,1),n.c=Inn(YHt,W1n,28,n.b,15,1),n.d=0}function Itn(n,t){n.a.Ne(t.d,n.b)>0&&(kD(n.c,new wG(t.c,t.d,n.d)),n.b=t.d)}function Otn(n,t){if(null==n.g||t>=n.i)throw hv(new pL(t,n.i));return n.g[t]}function Atn(n,t,e){if(gln(n,e),null!=e&&!n.fk(e))throw hv(new Nv);return e}function Ltn(n,t){return 10!=Min(t)&&Uhn(Tbn(t),t.Sm,t.__elementTypeId$,Min(t),n),n}function Ntn(n,t,e,i){sZ(),i=i||Jot,rLn(n.slice(t,e),n,t,e,-t,i)}function $tn(n,t,e,i,r){return t<0?YNn(n,e,i):uG(e,69).wk().yk(n,n.hi(),t,i,r)}function Dtn(n,t){return ugn(uM(pK(oIn(n,(GYn(),bmt)))),uM(pK(oIn(t,bmt))))}function xtn(){xtn=E,Mut=Abn((Rtn(),Uhn(cT(Tut,1),p1n,304,0,[put,mut,vut,kut])))}function Rtn(){Rtn=E,put=new qP("All",0),mut=new SN,vut=new P$,kut=new EN}function Ktn(){Ktn=E,Ast=new aC(z2n,0),Ost=new aC(G2n,1),Lst=new aC(V2n,2)}function Ftn(){Ftn=E,tXn(),sHt=M0n,uHt=T0n,fHt=new Rw(M0n),hHt=new Rw(T0n)}function _tn(){_tn=E,vht=Abn((ehn(),Uhn(cT(jht,1),p1n,417,0,[pht,wht,dht,ght])))}function Btn(){Btn=E,Rht=Abn((myn(),Uhn(cT(Fht,1),p1n,406,0,[Nht,Lht,$ht,Dht])))}function Htn(){Htn=E,Eht=Abn((vyn(),Uhn(cT(Sht,1),p1n,332,0,[yht,kht,Mht,Tht])))}function Utn(){Utn=E,ibt=Abn((Uvn(),Uhn(cT(abt,1),p1n,389,0,[tbt,Zlt,Ylt,nbt])))}function Gtn(){Gtn=E,Glt=Abn((Xhn(),Uhn(cT(ebt,1),p1n,416,0,[Flt,Hlt,_lt,Blt])))}function qtn(){qtn=E,ldt=Abn((qhn(),Uhn(cT(mdt,1),p1n,421,0,[odt,udt,sdt,hdt])))}function Xtn(){Xtn=E,Wwt=Abn((Ghn(),Uhn(cT(adt,1),p1n,371,0,[zwt,qwt,Xwt,Gwt])))}function ztn(){ztn=E,mjt=Abn((Yyn(),Uhn(cT(jjt,1),p1n,203,0,[djt,gjt,wjt,bjt])))}function Vtn(){Vtn=E,Ujt=Abn((yvn(),Uhn(cT(Xjt,1),p1n,284,0,[Fjt,Kjt,_jt,Bjt])))}function Wtn(){Wtn=E,Ngt=new iI(q4n,0),Lgt=new iI("IMPROVE_STRAIGHTNESS",1)}function Qtn(n,t){var e,i;return i=t/n.c.Rd().gc()|0,e=t%n.c.Rd().gc(),I7(n,i,e)}function Jtn(n){var t;if(n.nl())for(t=n.i-1;t>=0;--t)zrn(n,t);return g5(n)}function Ytn(n){var t,e;if(!n.b)return null;for(e=n.b;t=e.a[0];)e=t;return e}function Ztn(n){var t,e;if(!n.b)return null;for(e=n.b;t=e.a[1];)e=t;return e}function nen(n){return F$(n,180)?""+uG(n,180).a:null==n?null:cpn(n)}function ten(n){return F$(n,180)?""+uG(n,180).a:null==n?null:cpn(n)}function een(n,t){if(t.a)throw hv(new Ky(p2n));FV(n.a,t),t.a=n,!n.j&&(n.j=t)}function ien(n,t){rL.call(this,t.zd(),-16449&t.yd()),tJ(n),this.a=n,this.c=t}function ren(n,t){return new LU(t,KR(D$(t.e),t.f.a+n,t.f.b+n),(qx(),!1))}function cen(n,t){return PU(),kD(n,new WO(t,xwn(t.e.c.length+t.g.c.length)))}function aen(n,t){return PU(),kD(n,new WO(t,xwn(t.e.c.length+t.g.c.length)))}function oen(){oen=E,tOt=Abn((dTn(),Uhn(cT(cOt,1),p1n,354,0,[ZIt,JIt,YIt,QIt])))}function uen(){uen=E,KCt=Abn((mbn(),Uhn(cT(BCt,1),p1n,353,0,[xCt,$Ct,DCt,NCt])))}function sen(){sen=E,YSt=Abn((Cjn(),Uhn(cT(ZSt,1),p1n,405,0,[zSt,VSt,WSt,QSt])))}function hen(){hen=E,bxt=Abn((_gn(),Uhn(cT(kxt,1),p1n,223,0,[fxt,sxt,uxt,hxt])))}function fen(){fen=E,Fxt=Abn((Ajn(),Uhn(cT(Wxt,1),p1n,291,0,[Rxt,$xt,Dxt,xxt])))}function len(){len=E,ZRt=Abn((Qmn(),Uhn(cT(sKt,1),p1n,386,0,[QRt,JRt,WRt,VRt])))}function ben(){ben=E,EKt=Abn((qpn(),Uhn(cT(SKt,1),p1n,320,0,[TKt,kKt,MKt,yKt])))}function wen(){wen=E,LKt=Abn((Eln(),Uhn(cT(DKt,1),p1n,415,0,[CKt,IKt,PKt,OKt])))}function den(){den=E,EAt=new uO(g7n,0),PAt=new uO(k9n,1),SAt=new uO(q4n,2)}function gen(n,t,e,i,r){return tJ(n),tJ(t),tJ(e),tJ(i),tJ(r),new WV(n,t,i)}function pen(n,t){var e;return(e=uG(u7(n.e,t),400))?(cq(e),e.e):null}function men(n,t){var e;return-1!=(e=Ten(n,t,0))&&(i7(n,e),!0)}function ven(n,t,e){var i;return GQ(n),(i=new un).a=t,n.a.Nb(new nC(i,e)),i.a}function ken(n){var t;return GQ(n),t=Inn(eUt,I0n,28,0,15,1),tE(n.a,new md(t)),t}function yen(n){var t;if(!oon(n))throw hv(new Bv);return n.e=1,t=n.d,n.d=null,t}function Men(n){var t;return _L(n)&&(t=0-n,!isNaN(t))?t:Esn(gfn(n))}function Ten(n,t,e){for(;e=0?Dyn(n,e,!0,!0):YNn(n,t,!0)}function Ven(n){var t;return null==(t=Kcn(Lsn(n,32)))&&($vn(n),t=Kcn(Lsn(n,32))),t}function Wen(n){var t;return n.Oh()||(t=iQ(n.Dh())-n.ji(),n.$h().Mk(t)),n.zh()}function Qen(n,t){Iht=new et,xht=t,uG((Cht=n).b,68),Rnn(Cht,Iht,null),Szn(Cht)}function Jen(){Jen=E,glt=new dC("XY",0),dlt=new dC("X",1),plt=new dC("Y",2)}function Yen(){Yen=E,Fst=new oC("TOP",0),Kst=new oC(G2n,1),Rst=new oC(Q2n,2)}function Zen(){Zen=E,gpt=new uI(q4n,0),ppt=new uI("TOP",1),dpt=new uI(Q2n,2)}function nin(){nin=E,Gjt=new pI("INPUT_ORDER",0),qjt=new pI("PORT_DEGREE",1)}function tin(){tin=E,Jat=p$(f0n,f0n,524287),Yat=p$(0,0,b0n),Zat=_9(1),_9(2),not=_9(0)}function ein(n){var t;return n.d!=n.r&&(t=bEn(n),n.e=!!t&&t.lk()==srt,n.d=t),n.e}function iin(n,t,e){var i;return i=n.g[t],yD(n,t,n.Zi(t,e)),n.Ri(t,e,i),n.Ni(),i}function rin(n,t){var e;return(e=n.dd(t))>=0&&(n.gd(e),!0)}function cin(n,t){var e;for(WW(n),WW(t),e=!1;t.Ob();)e|=n.Fc(t.Pb());return e}function ain(n,t){var e;return(e=uG(cQ(n.e,t),400))?(nD(n,e),e.e):null}function oin(n){var t,e;return t=n/60|0,0==(e=n%60)?""+t:t+":"+e}function uin(n,t){var e=n.a[t],i=(Cfn(),Wat)[typeof e];return i?i(e):Vbn(typeof e)}function sin(n,t){return vgn(n),new fX(n,new D_(new f7(t,n.a)))}function hin(n){var t;return null!=(t=0==n.b.c.length?null:zq(n.b,0))&&Con(n,0),t}function fin(n,t){var e,i,r;r=t.c.i,i=(e=uG(cQ(n.f,r),60)).d.c-e.e.c,fun(t.a,i,0)}function lin(n,t){var e;for(++n.d,++n.c[t],e=t+1;e=0;)++t[0]}function din(n,t){ycn(n,null==t||J_((tJ(t),t))||isNaN((tJ(t),t))?0:(tJ(t),t))}function gin(n,t){Mcn(n,null==t||J_((tJ(t),t))||isNaN((tJ(t),t))?0:(tJ(t),t))}function pin(n,t){kcn(n,null==t||J_((tJ(t),t))||isNaN((tJ(t),t))?0:(tJ(t),t))}function min(n,t){vcn(n,null==t||J_((tJ(t),t))||isNaN((tJ(t),t))?0:(tJ(t),t))}function vin(n,t,e){return bD(new MO(e.e.a+e.f.a/2,e.e.b+e.f.b/2),n)==(tJ(t),t)}function kin(n,t){return F$(t,102)&&uG(t,19).Bb&P0n?new yL(t,n):new Zsn(t,n)}function yin(n,t){return F$(t,102)&&uG(t,19).Bb&P0n?new yL(t,n):new Zsn(t,n)}function Min(n){return null==n.__elementTypeCategory$?10:n.__elementTypeCategory$}function Tin(n,t){return t==(cB(),cB(),uut)?n.toLocaleLowerCase():n.toLowerCase()}function jin(n){if(!n.e)throw hv(new Bv);return n.c=n.a=n.e,n.e=n.e.e,--n.d,n.a.f}function Ein(n){if(!n.c)throw hv(new Bv);return n.e=n.a=n.c,n.c=n.c.c,++n.d,n.a.f}function Sin(n){var t;for(++n.a,t=n.c.a.length;n.an.a[i]&&(i=e);return i}function Lin(n){var t;return!!(t=uG(oIn(n,(GYn(),Spt)),313))&&t.a==n}function Nin(n){var t;return!!(t=uG(oIn(n,(GYn(),Spt)),313))&&t.i==n}function $in(){$in=E,Ilt=Abn((uIn(),Uhn(cT(Llt,1),p1n,367,0,[Tlt,jlt,Elt,Slt,Plt])))}function Din(){Din=E,vdt=Abn((gPn(),Uhn(cT(Pdt,1),p1n,375,0,[wdt,gdt,pdt,ddt,bdt])))}function xin(){xin=E,wgt=Abn((kvn(),Uhn(cT(pgt,1),p1n,348,0,[sgt,ugt,fgt,lgt,hgt])))}function Rin(){Rin=E,Ejt=Abn((pyn(),Uhn(cT(xjt,1),p1n,323,0,[Tjt,kjt,yjt,vjt,Mjt])))}function Kin(){Kin=E,$mt=Abn((Gpn(),Uhn(cT(ajt,1),p1n,171,0,[Lmt,Cmt,Imt,Omt,Amt])))}function Fin(){Fin=E,rIt=Abn((zPn(),Uhn(cT(oIt,1),p1n,368,0,[tIt,YCt,eIt,ZCt,nIt])))}function _in(){_in=E,BAt=Abn((_Rn(),Uhn(cT(qAt,1),p1n,373,0,[xAt,DAt,KAt,RAt,FAt])))}function Bin(){Bin=E,sLt=Abn((pOn(),Uhn(cT(qLt,1),p1n,324,0,[iLt,rLt,oLt,cLt,aLt])))}function Hin(){Hin=E,ext=Abn((xdn(),Uhn(cT(axt,1),p1n,88,0,[ZDt,YDt,JDt,QDt,nxt])))}function Uin(){Uin=E,bNt=Abn((Rkn(),Uhn(cT(MNt,1),p1n,170,0,[hNt,sNt,oNt,fNt,uNt])))}function Gin(){Gin=E,iRt=Abn((Vkn(),Uhn(cT(hRt,1),p1n,256,0,[Zxt,tRt,Jxt,Yxt,nRt])))}function qin(){qin=E,HRt=Abn((KQn(),Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt])))}function Xin(){Xin=E,Yut=new iC("BY_SIZE",0),Zut=new iC("BY_SIZE_AND_SHAPE",1)}function zin(){zin=E,gft=new wC("EADES",0),pft=new wC("FRUCHTERMAN_REINGOLD",1)}function Vin(){Vin=E,dgt=new nI("READING_DIRECTION",0),ggt=new nI("ROTATION",1)}function Win(){Win=E,zlt=new Pt,Vlt=new At,qlt=new Lt,Xlt=new Ot,Wlt=new Nt}function Qin(n){this.b=new Zm,this.a=new Zm,this.c=new Zm,this.d=new Zm,this.e=n}function Jin(n){this.g=n,this.f=new Zm,this.a=e.Math.min(this.g.c.c,this.g.d.c)}function Yin(n,t,e){HF.call(this),Qrn(this),this.a=n,this.c=e,this.b=t.d,this.f=t.e}function Zin(n,t,e){var i;for(i=new Ww(e);i.a=0&&t0?t-1:t,lj(bj(xcn(xG(new fy,e),n.n),n.j),n.k)}function rrn(n){var t;t=new Yk,ttn((!n.q&&(n.q=new fV(p_t,n,11,10)),n.q),t)}function crn(n){return(2&n.i?"interface ":1&n.i?"":"class ")+(vK(n),n.o)}function arn(n){return dwn(n,vZn)>0?vZn:dwn(n,j1n)<0?j1n:pz(n)}function orn(n){return n<3?(man(n,b1n),n+1):n=-.01&&n.a<=Z2n&&(n.a=0),n.b>=-.01&&n.b<=Z2n&&(n.b=0),n}function Trn(n){var t,e;for(l_n(),e=G9n,t=0;te&&(e=n[t]);return e}function jrn(n,t){var e;if(!(e=EKn(n.Dh(),t)))throw hv(new vM(Gtt+t+ztt));return e}function Ern(n,t){var e;for(e=n;R0(e);)if((e=R0(e))==t)return!0;return!1}function Srn(n,t){var e,i,r;for(i=t.a.ld(),e=uG(t.a.md(),16).gc(),r=0;rn||n>t)throw hv(new YM("fromIndex: 0, toIndex: "+n+Q0n+t))}function Drn(n){if(n<0)throw hv(new vM("Illegal Capacity: "+n));this.g=this.aj(n)}function xrn(n,t){return YN(),oan(T1n),e.Math.abs(n-t)<=T1n||n==t||isNaN(n)&&isNaN(t)}function Rrn(n,t){var e,i,r,c;for(r=0,c=(i=n.d).length;r0&&(n.a/=t,n.b/=t),n}function Hrn(n){var t;return n.w?n.w:((t=O3(n))&&!t.Vh()&&(n.w=t),t)}function Urn(n,t){var e,i;i=n.a,e=kdn(n,t,null),i!=t&&!n.e&&(e=PWn(n,t,e)),e&&e.oj()}function Grn(n,t,e){var i,r;i=t;do{r=uM(n.p[i.p])+e,n.p[i.p]=r,i=n.a[i.p]}while(i!=t)}function qrn(n,t,e){var i=function(){return n.apply(i,arguments)};return t.apply(i,e),i}function Xrn(n){var t;return null==n?null:NCn(t=uG(n,195),t.length)}function zrn(n,t){if(null==n.g||t>=n.i)throw hv(new pL(t,n.i));return n.Wi(t,n.g[t])}function Vrn(n,t){var e,i;for(hZ(),i=new Zm,e=0;e=14&&t<=16)),n}function Fcn(n,t){var e;return tJ(t),vG(!!(e=n[":"+t]),"Enum constant undefined: "+t),e}function _cn(n,t,e,i,r,c){var a;return Rcn(e,a=VW(n,t)),a.i=r?8:0,a.f=i,a.e=r,a.g=c,a}function Bcn(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=1,this.c=n,this.a=e}function Hcn(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=2,this.c=n,this.a=e}function Ucn(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=6,this.c=n,this.a=e}function Gcn(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=7,this.c=n,this.a=e}function qcn(n,t,e,i,r){this.d=t,this.j=i,this.e=r,this.o=-1,this.p=4,this.c=n,this.a=e}function Xcn(n,t){var e,i,r,c;for(r=0,c=(i=t).length;r=0))throw hv(new vM("tolerance ("+n+") must be >= 0"));return n}function uan(n,t){var e;return F$(t,44)?n.c.Mc(t):(e=ymn(n,t),Svn(n,t),e)}function san(n,t,e){return Kbn(n,t),qon(n,e),Pcn(n,0),Ccn(n,1),mdn(n,!0),ddn(n,!0),n}function han(n,t){var e;if(e=n.gc(),t<0||t>e)throw hv(new w_(t,e));return new N_(n,t)}function fan(n,t){n.b=e.Math.max(n.b,t.d),n.e+=t.r+(0==n.a.c.length?0:n.c),kD(n.a,t)}function lan(n){TK(n.c>=0),Rvn(n.d,n.c)<0&&(n.a=n.a-1&n.d.a.length-1,n.b=n.d.c),n.c=-1}function ban(n){var t;for(t=n.c.Cc().Kc();t.Ob();)uG(t.Pb(),16).$b();n.c.$b(),n.d=0}function wan(n){var t,e,i,r;for(i=0,r=(e=n.a).length;i=0}function Ban(n,t){n.r>0&&n.c0&&0!=n.g&&Ban(n.i,t/n.r*n.i.d))}function Han(n,t){var e;e=n.c,n.c=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,1,e,n.c))}function Uan(n,t){var e;e=n.c,n.c=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,4,e,n.c))}function Gan(n,t){var e;e=n.k,n.k=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,2,e,n.k))}function qan(n,t){var e;e=n.D,n.D=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,2,e,n.D))}function Xan(n,t){var e;e=n.f,n.f=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,8,e,n.f))}function zan(n,t){var e;e=n.i,n.i=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,7,e,n.i))}function Van(n,t){var e;e=n.a,n.a=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,8,e,n.a))}function Wan(n,t){var e;e=n.b,n.b=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,0,e,n.b))}function Qan(n,t){var e;e=n.b,n.b=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,0,e,n.b))}function Jan(n,t){var e;e=n.c,n.c=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,1,e,n.c))}function Yan(n,t){var e;e=n.d,n.d=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,1,e,n.d))}function Zan(n,t,e){var i;n.b=t,n.a=e,i=512&~n.a?new $f:new ay,n.c=qFn(i,n.b,n.a)}function non(n,t){return EFn(n.e,t)?(PP(),ein(t)?new Cq(t,n):new OA(t,n)):new PA(t,n)}function ton(n){return 0>n?new mS:new OK(null,new i9(n+1,n))}function eon(n,t){var e;return hZ(),e=new sS(1),RA(n)?r2(e,n,t):VAn(e.f,n,t),new Vw(e)}function ion(n,t){var e,i;return e=n.c,(i=t.e[n.p])>0?uG(zq(e.a,i-1),10):null}function ron(n,t){var e,i;return(e=n.o+n.p)<(i=t.o+t.p)?-1:e==i?0:1}function con(n){var t;return F$(t=oIn(n,(GYn(),rmt)),167)?Qpn(uG(t,167)):null}function aon(n){var t;return(n=e.Math.max(n,2))>(t=pfn(n))?(t<<=1)>0?t:d1n:t}function oon(n){switch(_D(3!=n.e),n.e){case 2:return!1;case 0:return!0}return a7(n)}function uon(n,t){var e;return!!F$(t,8)&&(e=uG(t,8),n.a==e.a&&n.b==e.b)}function son(n,t){var e;e=new et,uG(t.b,68),uG(t.b,68),uG(t.b,68),Prn(t.a,new $U(n,e,t))}function hon(n,t){var e,i;for(i=t.vc().Kc();i.Ob();)rSn(n,(e=uG(i.Pb(),44)).ld(),e.md())}function fon(n,t){var e;e=n.d,n.d=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,11,e,n.d))}function lon(n,t){var e;e=n.j,n.j=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,13,e,n.j))}function bon(n,t){var e;e=n.b,n.b=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,21,e,n.b))}function won(n,t){0==(t9(),Nut?null:t.c).length&&RK(t,new G),r2(n.a,Nut?null:t.c,t)}function don(n,t){t.Ug("Hierarchical port constraint processing",1),ayn(n),yYn(n),t.Vg()}function gon(){gon=E,Sdt=new VC("START",0),Edt=new VC("MIDDLE",1),jdt=new VC("END",2)}function pon(){pon=E,VCt=new YI("P1_NODE_PLACEMENT",0),WCt=new YI("P2_EDGE_ROUTING",1)}function mon(){mon=E,Wft=new Cm(E4n),Qft=new Cm(S4n),Vft=new Cm(P4n),zft=new Cm(C4n)}function von(n){var t;return OB(n.f.g,n.d),MK(n.b),n.c=n.a,t=uG(n.a.Pb(),44),n.b=Phn(n),t}function kon(n){return null==n.b?(EP(),EP(),eBt):n.ul()?n.tl():n.sl()}function yon(n,t){var e;return!((e=null==t?-1:Ten(n.b,t,0))<0||(Con(n,e),0))}function Mon(n,t){var e;return tJ(t),e=t.g,!n.b[e]&&(uQ(n.b,e,t),++n.c,!0)}function Ton(n,t){var e,i;return e=1-t,i=n.a[e],n.a[e]=i.a[t],i.a[t]=n,n.b=!0,i.b=!1,i}function jon(n,t){var e,i;for(i=t.Kc();i.Ob();)e=uG(i.Pb(),272),n.b=!0,FV(n.e,e),e.b=n}function Eon(n,t){var e,i;return e=uG(oIn(n,(jYn(),rTt)),8),i=uG(oIn(t,rTt),8),ugn(e.b,i.b)}function Son(n,t,e){var i,r;return r=t>>5,i=31&t,E3(Dz(n.n[e][r],pz(Nz(i,1))),3)}function Pon(n,t,e){var i,r,c;for(c=n.a.length-1,r=n.b,i=0;i0?1:0:(!n.c&&(n.c=j2(Bsn(n.f))),n.c).e}function tun(n,t){t?null==n.B&&(n.B=n.D,n.D=null):null!=n.B&&(n.D=n.B,n.B=null)}function eun(n,t){return Xhn(),n==Flt&&t==Hlt||n==Hlt&&t==Flt||n==Blt&&t==_lt||n==_lt&&t==Blt}function iun(n,t){return Xhn(),n==Flt&&t==_lt||n==Flt&&t==Blt||n==Hlt&&t==Blt||n==Hlt&&t==_lt}function run(n,t){return YN(),oan(Z2n),e.Math.abs(0-t)<=Z2n||0==t||isNaN(0)&&isNaN(t)?0:n/t}function cun(n,t){return uM(pK(yx(cdn(YJ(new fX(null,new h3(n.c.b,16)),new _g(n)),t))))}function aun(n,t){return uM(pK(yx(cdn(YJ(new fX(null,new h3(n.c.b,16)),new Fg(n)),t))))}function oun(){return r_n(),Uhn(cT(bpt,1),p1n,259,0,[Zgt,tpt,ept,ipt,rpt,cpt,opt,Ygt,npt,apt])}function uun(){return THn(),Uhn(cT(Hjt,1),p1n,243,0,[$jt,Ijt,Ljt,Ojt,Ajt,Sjt,Njt,Djt,Pjt,Cjt])}function sun(n,t){t.Ug("General Compactor",1),Bpn(uG(zDn(n,(jOn(),LIt)),393)).Cg(n)}function hun(n,t){var e,i;return e=uG(zDn(n,(jOn(),FIt)),17),i=uG(zDn(t,FIt),17),d$(e.a,i.a)}function fun(n,t,e){var i,r;for(r=Fkn(n,0);r.b!=r.d.c;)(i=uG(I6(r),8)).a+=t,i.b+=e;return n}function lun(n,t,e){var i;for(i=n.b[e&n.f];i;i=i.b)if(e==i.a&&xQ(t,i.g))return i;return null}function bun(n,t,e){var i;for(i=n.c[e&n.f];i;i=i.d)if(e==i.f&&xQ(t,i.i))return i;return null}function wun(n,t,e){var i,r,c;for(i=0,r=0;r>>31;0!=i&&(n[e]=i)}function dun(n,t,e,i,r,c){var a;this.c=n,tTn(n,a=new Zm,t,n.b,e,i,r,c),this.a=new N4(a,0)}function gun(){this.c=new Vj(0),this.b=new Vj(F9n),this.d=new Vj(K9n),this.a=new Vj(_3n)}function pun(n,t,e,i,r,c,a){_E.call(this,n,t),this.d=e,this.e=i,this.c=r,this.b=c,this.a=n7(a)}function mun(n,t,e,i,r,c,a,o,u,s,h,f,l){return eLn(n,t,e,i,r,c,a,o,u,s,h,f,l),Sgn(n,!1),n}function vun(n){return n.b.c.i.k==(zIn(),lbt)?uG(oIn(n.b.c.i,(GYn(),rmt)),12):n.b.c}function kun(n){return n.b.d.i.k==(zIn(),lbt)?uG(oIn(n.b.d.i,(GYn(),rmt)),12):n.b.d}function yun(n){var t;return _A((t=t6(n)).a,0)?(gS(),gS(),fut):(gS(),new dR(t.b))}function Mun(n){var t;return _A((t=Z4(n)).a,0)?(dS(),dS(),hut):(dS(),new wR(t.b))}function Tun(n){var t;return _A((t=Z4(n)).a,0)?(dS(),dS(),hut):(dS(),new wR(t.c))}function jun(n){switch(n.g){case 2:return KQn(),_Rt;case 4:return KQn(),kRt;default:return n}}function Eun(n){switch(n.g){case 1:return KQn(),KRt;case 3:return KQn(),yRt;default:return n}}function Sun(n){switch(n.g){case 0:return new Wo;case 1:return new Qo;default:return null}}function Pun(){Pun=E,Hwt=new uF("edgelabelcenterednessanalysis.includelabel",(qx(),tot))}function Cun(){Cun=E,FEt=Lvn(gL(Aq(Aq(new wJ,(uIn(),Elt),(zYn(),kwt)),Slt,hwt),Plt),vwt)}function Iun(){Iun=E,XEt=Lvn(gL(Aq(Aq(new wJ,(uIn(),Elt),(zYn(),kwt)),Slt,hwt),Plt),vwt)}function Oun(){Oun=E,V_t=new Qk,Q_t=Uhn(cT(o_t,1),krt,179,0,[]),W_t=Uhn(cT(p_t,1),yrt,62,0,[])}function Aun(){Aun=E,Obt=new PC("TO_INTERNAL_LTR",0),Ibt=new PC("TO_INPUT_DIRECTION",1)}function Lun(){Lun=E,Tbt=new Bt,ybt=new Ht,Mbt=new Ut,kbt=new Gt,jbt=new qt,Ebt=new Xt}function Nun(n,t){t.Ug(g6n,1),Apn(FS(new Ad((zS(),new mY(n,!1,!1,new Ft))))),t.Vg()}function $un(n,t,e){e.Ug("DFS Treeifying phase",1),qmn(n,t),qKn(n,t),n.a=null,n.b=null,e.Vg()}function Dun(n,t){return qx(),RA(n)?r7(n,mK(t)):FA(n)?Rz(n,pK(t)):KA(n)?xz(n,gK(t)):n.Fd(t)}function xun(n,t){var e,i;for(tJ(t),i=t.vc().Kc();i.Ob();)e=uG(i.Pb(),44),n.zc(e.ld(),e.md())}function Run(n,t,e){var i;for(i=e.Kc();i.Ob();)if(!H5(n,t,i.Pb()))return!1;return!0}function Kun(n,t,e,i,r){var c;return e&&(c=emn(t.Dh(),n.c),r=e.Rh(t,-1-(-1==c?i:c),null,r)),r}function Fun(n,t,e,i,r){var c;return e&&(c=emn(t.Dh(),n.c),r=e.Th(t,-1-(-1==c?i:c),null,r)),r}function _un(n){var t;if(-2==n.b){if(0==n.e)t=-1;else for(t=0;0==n.a[t];t++);n.b=t}return n.b}function Bun(n){if(tJ(n),0==n.length)throw hv(new ZM("Zero length BigInteger"));XHn(this,n)}function Hun(n){this.i=n.gc(),this.i>0&&(this.g=this.aj(this.i+(this.i/8|0)+1),n.Qc(this.g))}function Uun(n,t,e){this.g=n,this.d=t,this.e=e,this.a=new Zm,RLn(this),hZ(),f$(this.a,null)}function Gun(n,t){t.q=n,n.d=e.Math.max(n.d,t.r),n.b+=t.d+(0==n.a.c.length?0:n.c),kD(n.a,t)}function qun(n,t){var e,i,r,c;return r=n.c,e=n.c+n.b,c=n.d,i=n.d+n.a,t.a>r&&t.ac&&t.b(r=n.a.length)?e=r:s3(t,e+1),n.a=r1(n.a,0,t)+""+i+sQ(n.a,e)}function msn(n,t){n.a=Lgn(n.a,1),n.c=e.Math.min(n.c,t),n.b=e.Math.max(n.b,t),n.d=Lgn(n.d,t)}function vsn(n,t){return t1||n.Ob())return++n.a,n.g=0,t=n.i,n.Ob(),t;throw hv(new Bv)}function Fsn(n){switch(n.a.g){case 1:return new KI;case 3:return new zTn;default:return new ml}}function _sn(n,t){switch(t){case 1:return!!n.n&&0!=n.n.i;case 2:return null!=n.k}return j4(n,t)}function Bsn(n){return p0n>22),r=n.h+t.h+(i>>22),p$(e&f0n,i&f0n,r&l0n)}function Thn(n,t){var e,i,r;return e=n.l-t.l,i=n.m-t.m+(e>>22),r=n.h-t.h+(i>>22),p$(e&f0n,i&f0n,r&l0n)}function jhn(n){var t,e;for(BQn(n),e=new Ww(n.d);e.a(i=n.gc()))throw hv(new w_(t,i));return n.Si()&&(e=A0(n,e)),n.Ei(t,e)}function wfn(n,t,e,i,r){var c,a;for(a=e;a<=r;a++)for(c=t;c<=i;c++)eTn(n,c,a)||HBn(n,c,a,!0,!1)}function dfn(n){var t,e,i;for(l_n(),e=Inn(PNt,zZn,8,2,0,1),i=0,t=0;t<2;t++)i+=.5,e[t]=WMn(i,n);return e}function gfn(n){var t,e;return p$(t=1+~n.l&f0n,e=~n.m+(0==t?1:0)&f0n,~n.h+(0==t&&0==e?1:0)&l0n)}function pfn(n){var t;if(n<0)return j1n;if(0==n)return 0;for(t=d1n;!(t&n);t>>=1);return t}function mfn(n,t,e){return!(n>=128)&&HA(n<64?E3(Nz(1,n),e):E3(Nz(1,n-64),t),0)}function vfn(n,t,e){return null==e?(!n.q&&(n.q=new Ym),u7(n.q,t)):(!n.q&&(n.q=new Ym),vJ(n.q,t,e)),n}function kfn(n,t,e){return null==e?(!n.q&&(n.q=new Ym),u7(n.q,t)):(!n.q&&(n.q=new Ym),vJ(n.q,t,e)),n}function yfn(n){var t,e;return zsn(e=new d7,n),kfn(e,(mon(),Wft),n),kqn(n,e,t=new Ym),zWn(n,e,t),e}function Mfn(n){var t,e;return t=n.t-n.k[n.o.p]*n.d+n.j[n.o.p]>n.f,e=n.u+n.e[n.o.p]*n.d>n.f*n.s*n.d,t||e}function Tfn(n,t){var e,i,r;for(e=!1,i=n.a[t].length,r=0;r=0,"Negative initial capacity"),vG(t>=0,"Non-positive load factor"),$V(this)}function $fn(n,t,e,i,r){var c,a;if(a=n.length,c=e.length,t<0||i<0||r<0||t+r>a||i+r>c)throw hv(new Lv)}function Dfn(n,t){var e,i,r,c,a;for(hZ(),a=!1,r=0,c=(i=t).length;r1||t>=0&&n.b<3)}function Yfn(n){var t,e,i;t=1+~n.l&f0n,e=~n.m+(0==t?1:0)&f0n,i=~n.h+(0==t&&0==e?1:0)&l0n,n.l=t,n.m=e,n.h=i}function Zfn(n){var t,e,i;for(hZ(),i=1,e=n.Kc();e.Ob();)i=31*i+(null!=(t=e.Pb())?Hon(t):0),i|=0;return i}function nln(n,t,e,i,r){var c;return c=gDn(n,t),e&&Yfn(c),r&&(n=hTn(n,t),Qat=i?gfn(n):p$(n.l,n.m,n.h)),c}function tln(n,t,e){n.g=mAn(n,t,(KQn(),kRt),n.b),n.d=mAn(n,e,kRt,n.b),0!=n.g.c&&0!=n.d.c&&AIn(n)}function eln(n,t,e){n.g=mAn(n,t,(KQn(),_Rt),n.j),n.d=mAn(n,e,_Rt,n.j),0!=n.g.c&&0!=n.d.c&&AIn(n)}function iln(n,t){switch(t){case 7:return!!n.e&&0!=n.e.i;case 8:return!!n.d&&0!=n.d.i}return Kpn(n,t)}function rln(n,t){switch(t.g){case 0:F$(n.b,641)||(n.b=new lsn);break;case 1:F$(n.b,642)||(n.b=new zG)}}function cln(n){if(0===n.g)return new eu;throw hv(new vM(lnt+(null!=n.f?n.f:""+n.g)))}function aln(n){if(0===n.g)return new nu;throw hv(new vM(lnt+(null!=n.f?n.f:""+n.g)))}function oln(n,t,e){return!Qj(JJ(new fX(null,new h3(n.c,16)),new hd(new GO(t,e)))).Bd((vS(),Kut))}function uln(n,t){return bD($kn(uG(oIn(t,(QGn(),cCt)),88)),new MO(n.c.e.a-n.b.e.a,n.c.e.b-n.b.e.b))<=0}function sln(n,t){for(;null!=n.g||n.c?null==n.g||0!=n.i&&uG(n.g[n.i-1],51).Ob():O0(n);)yA(t,Wxn(n))}function hln(n){var t;for(t=new Ww(n.a.b);t.ai?1:0}function yln(n){return kD(n.c,(Whn(),ZLt)),xrn(n.a,uM(pK(Jkn((lmn(),WTt)))))?new zu:new zp(n)}function Mln(n){for(;!n.d||!n.d.Ob();){if(!n.b||LM(n.b))return null;n.d=uG(xV(n.b),51)}return n.d}function Tln(n){switch(n.g){case 1:return K9n;default:case 2:return 0;case 3:return _3n;case 4:return F9n}}function jln(){var n;return QYn(),VHt||(n=eR(kJn("M",!0)),n=CX(kJn("M",!1),n),VHt=n)}function Eln(){Eln=E,CKt=new uA("ELK",0),IKt=new uA("JSON",1),PKt=new uA("DOT",2),OKt=new uA("SVG",3)}function Sln(){Sln=E,aEt=new kI("STACKED",0),rEt=new kI("REVERSE_STACKED",1),cEt=new kI("SEQUENCED",2)}function Pln(){Pln=E,gPt=new WI(q4n,0),dPt=new WI("MIDDLE_TO_MIDDLE",1),wPt=new WI("AVOID_OVERLAP",2)}function Cln(){Cln=E,tdt=new ji,edt=new Ei,ndt=new Mi,Zwt=new Si,tJ(new Ti),Ywt=new L}function Iln(){Iln=E,Pxt=new CN(15),Sxt=new _N((XYn(),W$t),Pxt),Cxt=mDt,Mxt=a$t,Txt=_$t,Ext=U$t,jxt=H$t}function Oln(n,t){var e,i,r,c,a;for(r=0,c=(i=t).length;r=n.b.c.length||(_ln(n,2*t+1),(e=2*t+2)0&&(t.Cd(e),e.i&&Zdn(e))}function Hln(n,t,e){var i;for(i=e-1;i>=0&&n[i]===t[i];i--);return i<0?0:$P(E3(n[i],L0n),E3(t[i],L0n))?-1:1}function Uln(n,t,e){var i,r;this.g=n,this.c=t,this.a=this,this.d=this,r=aon(e),i=Inn($at,l1n,227,r,0,1),this.b=i}function Gln(n,t,e,i,r){var c,a;for(a=e;a<=r;a++)for(c=t;c<=i;c++)if(eTn(n,c,a))return!0;return!1}function qln(n,t){var e;for(e=n.Zb().Cc().Kc();e.Ob();)if(uG(e.Pb(),16).Hc(t))return!0;return!1}function Xln(n,t,e){var i,r,c,a;for(tJ(e),a=!1,c=n.fd(t),r=e.Kc();r.Ob();)i=r.Pb(),c.Rb(i),a=!0;return a}function zln(n,t){var e,i;return i=uG(Lsn(n.a,4),129),e=Inn(xFt,Uit,424,t,0,1),null!=i&&qGn(i,0,e,0,i.length),e}function Vln(n,t){var e;return e=new Z_n(!!(256&n.f),n.i,n.a,n.d,!!(16&n.f),n.j,n.g,t),null!=n.e||(e.c=n),e}function Wln(n,t){var e;return n===t||!!F$(t,85)&&(e=uG(t,85),OOn(Mz(n),e.vc()))}function Qln(n,t,e){var i,r;for(r=e.Kc();r.Ob();)if(i=uG(r.Pb(),44),n.Be(t,i.md()))return!0;return!1}function Jln(n,t,e){return n.d[t.p][e.p]||(Kyn(n,t,e),n.d[t.p][e.p]=!0,n.d[e.p][t.p]=!0),n.a[t.p][e.p]}function Yln(n,t){return!(!n||n==t||!vR(t,(GYn(),zpt)))&&uG(oIn(t,(GYn(),zpt)),10)!=n}function Zln(n){switch(n.i){case 2:return!0;case 1:return!1;case-1:++n.c;default:return n.$l()}}function nbn(n){switch(n.i){case-2:return!0;case-1:return!1;case 1:--n.c;default:return n._l()}}function tbn(n){U0.call(this,"The given string does not match the expected format for individual spacings.",n)}function ebn(n,t){var e;t.Ug("Min Size Preprocessing",1),e=xAn(n),Myn(n,(lBn(),EOt),e.a),Myn(n,MOt,e.b),t.Vg()}function ibn(n){var t,e,i;for(t=0,i=Inn(PNt,zZn,8,n.b,0,1),e=Fkn(n,0);e.b!=e.d.c;)i[t++]=uG(I6(e),8);return i}function rbn(n,t,e){var i,r;for(i=new lS,r=Fkn(e,0);r.b!=r.d.c;)aq(i,new eN(uG(I6(r),8)));Xln(n,t,i)}function cbn(n,t){var e;return e=Lgn(n,t),$P(P3(n,t),0)|BA(P3(n,e),0)?e:Lgn(YZn,P3(Dz(e,63),1))}function abn(n,t){var e,i;return(e=uG(n.d.Bc(t),16))?((i=n.e.hc()).Gc(e),n.e.d-=e.gc(),e.$b(),i):null}function obn(n){var t;if((t=n.a.c.length)>0)return Vz(t-1,n.a.c.length),i7(n.a,t-1);throw hv(new _v)}function ubn(n,t,e){if(n>t)throw hv(new vM(o2n+n+u2n+t));if(n<0||t>e)throw hv(new YM(o2n+n+s2n+t+Q0n+e))}function sbn(n,t){null==n.D&&null!=n.B&&(n.D=n.B,n.B=null),qan(n,null==t?null:(tJ(t),t)),n.C&&n.hl(null)}function hbn(n,t){var e;e=null!=Jkn((lmn(),WTt))&&null!=t.Sg()?uM(pK(t.Sg()))/uM(pK(Jkn(WTt))):1,vJ(n.b,t,e)}function fbn(n,t){var e,i;if(0!=(i=n.c[t]))for(n.c[t]=0,n.d-=i,e=t+1;eR9n?n-i>R9n:i-n>R9n)}function Qbn(n,t){var e;for(e=0;er&&(USn(t.q,r),i=e!=t.q.d)),i}function Zbn(n,t){var i,r,c,a,o;return a=t.i,o=t.j,r=a-(i=n.f).i,c=o-i.j,e.Math.sqrt(r*r+c*c)}function nwn(n,t){var e;return(e=Kvn(n))||(!ZKt&&(ZKt=new Ps),ZXn(),ttn((e=new Xm(sxn(t))).El(),n)),e}function twn(n,t){var e,i;return(e=uG(n.c.Bc(t),16))?((i=n.hc()).Gc(e),n.d-=e.gc(),e.$b(),n.mc(i)):n.jc()}function ewn(n,t){var e,i;for(i=0!=uRn(n.d,1),e=!0;e;)e=!1,e=t.c.mg(t.e,i),e|=PKn(n,t,i,!1),i=!i;Gon(n)}function iwn(n,t,e,i){var r,c;n.a=t,c=i?0:1,n.f=(r=new _On(n.c,n.a,e,c),new eBn(e,n.a,r,n.e,n.b,n.c==(ean(),BEt)))}function rwn(n){var t;return MK(n.a!=n.b),t=n.d.a[n.a],jK(n.b==n.d.c&&null!=t),n.c=n.a,n.a=n.a+1&n.d.a.length-1,t}function cwn(n){var t;if(0!=n.c)return n.c;for(t=0;t=n.c.b:n.a<=n.c.b))throw hv(new Bv);return t=n.a,n.a+=n.c.c,++n.b,xwn(t)}function own(n){var t;return zsn(t=new S$(n.a),n),kfn(t,(GYn(),rmt),n),t.o.a=n.g,t.o.b=n.f,t.n.a=n.i,t.n.b=n.j,t}function uwn(n){return(KQn(),LRt).Hc(n.j)?uM(pK(oIn(n,(GYn(),Mmt)))):Gfn(Uhn(cT(PNt,1),zZn,8,0,[n.i.n,n.n,n.a])).b}function swn(n){var t;return t=aN(KEt),uG(oIn(n,(GYn(),Hpt)),21).Hc((r_n(),rpt))&&Aq(t,(uIn(),Elt),(zYn(),Cwt)),t}function hwn(n){var t,e;for(e=new ek,t=new Ww(n);t.a=0?t:-t;i>0;)i%2==0?(e*=e,i=i/2|0):(r*=e,i-=1);return t<0?1/r:r}function pwn(n,t){var e,i,r;for(r=1,e=n,i=t>=0?t:-t;i>0;)i%2==0?(e*=e,i=i/2|0):(r*=e,i-=1);return t<0?1/r:r}function mwn(n,t){var e,i,r,c;return(c=fLn((i=t,(r=n?Kvn(n):null)&&r.Gl(),i)))==t&&(e=Kvn(n))&&e.Gl(),c}function vwn(n,t,e){var i,r;return r=n.f,n.f=t,4&n.Db&&!(1&n.Db)&&(i=new lV(n,1,0,r,t),e?e.nj(i):e=i),e}function kwn(n,t,e){var i,r;return r=n.b,n.b=t,4&n.Db&&!(1&n.Db)&&(i=new lV(n,1,3,r,t),e?e.nj(i):e=i),e}function ywn(n,t,e){var i,r;return r=n.a,n.a=t,4&n.Db&&!(1&n.Db)&&(i=new lV(n,1,1,r,t),e?e.nj(i):e=i),e}function Mwn(n){var t,e,i,r;if(null!=n)for(e=0;e=i||t-129&&n<128?(XG(),!(e=bot[t=n+128])&&(e=bot[t]=new Iw(n)),e):new Iw(n)}function Rwn(n){var t,e;return n>-129&&n<128?(eX(),!(e=Mot[t=n+128])&&(e=Mot[t]=new Aw(n)),e):new Aw(n)}function Kwn(n,t){n.a.c.length>0&&Lln(uG(zq(n.a,n.a.c.length-1),579),t)||kD(n.a,new r9(t))}function Fwn(n){var t,e;GB(),t=n.d.c-n.e.c,Prn((e=uG(n.g,154)).b,new Pg(t)),Prn(e.c,new Cg(t)),z8(e.i,new Ig(t))}function _wn(n){var t;return(t=new WM).a+="VerticalSegment ",QA(t,n.e),t.a+=" ",JA(t,KD(new FM,new Ww(n.k))),t.a}function Bwn(n,t){var e,i;for(e=0,i=Dgn(n,t).Kc();i.Ob();)e+=null!=oIn(uG(i.Pb(),12),(GYn(),lmt))?1:0;return e}function Hwn(n,t,e){var i,r,c;for(i=0,c=Fkn(n,0);c.b!=c.d.c&&!((r=uM(pK(I6(c))))>e);)r>=t&&++i;return i}function Uwn(n,t){WW(n);try{return n._b(t)}catch(e){if(F$(e=Ehn(e),212)||F$(e,169))return!1;throw hv(e)}}function Gwn(n,t){WW(n);try{return n.Hc(t)}catch(e){if(F$(e=Ehn(e),212)||F$(e,169))return!1;throw hv(e)}}function qwn(n,t){WW(n);try{return n.Mc(t)}catch(e){if(F$(e=Ehn(e),212)||F$(e,169))return!1;throw hv(e)}}function Xwn(n,t){WW(n);try{return n.xc(t)}catch(e){if(F$(e=Ehn(e),212)||F$(e,169))return null;throw hv(e)}}function zwn(n,t){WW(n);try{return n.Bc(t)}catch(e){if(F$(e=Ehn(e),212)||F$(e,169))return null;throw hv(e)}}function Vwn(n,t){switch(t.g){case 2:case 1:return Dgn(n,t);case 3:case 4:return Spn(Dgn(n,t))}return hZ(),hZ(),zot}function Wwn(n){var t;return 64&n.Db?vxn(n):((t=new fx(vxn(n))).a+=" (name: ",VA(t,n.zb),t.a+=")",t.a)}function Qwn(n){var t;return(t=uG(ain(n.c.c,""),233))||(t=new I2(UT(HT(new du,""),"Other")),Akn(n.c.c,"",t)),t}function Jwn(n,t,e){var i,r;return r=n.sb,n.sb=t,4&n.Db&&!(1&n.Db)&&(i=new lV(n,1,4,r,t),e?e.nj(i):e=i),e}function Ywn(n,t,e){var i,r;return r=n.r,n.r=t,4&n.Db&&!(1&n.Db)&&(i=new lV(n,1,8,r,n.r),e?e.nj(i):e=i),e}function Zwn(n,t,e){var i;return i=new Ken(n.e,4,13,t.c||(YYn(),N_t),null,Hyn(n,t),!1),e?e.nj(i):e=i,e}function ndn(n,t,e){var i;return i=new Ken(n.e,3,13,null,t.c||(YYn(),N_t),Hyn(n,t),!1),e?e.nj(i):e=i,e}function tdn(n,t){var e,i;return!(i=(e=uG(t,691)).el())&&e.fl(i=F$(t,90)?new CA(n,uG(t,29)):new g4(n,uG(t,156))),i}function edn(n,t,e){var i;n._i(n.i+1),i=n.Zi(t,e),t!=n.i&&qGn(n.g,t,n.g,t+1,n.i-t),uQ(n.g,t,i),++n.i,n.Mi(t,e),n.Ni()}function idn(n,t){var e;return t.a&&(e=t.a.a.length,n.a?JA(n.a,n.b):n.a=new lx(n.d),L4(n.a,t.a,t.d.length,e)),n}function rdn(n,t){var e;n.c=t,n.a=Jpn(t),n.a<54&&(n.f=(e=t.d>1?C4(t.a[0],t.a[1]):C4(t.a[0],0),W4(t.e>0?e:Men(e))))}function cdn(n,t){var e;return e=new un,n.a.Bd(e)?(UD(),new Xy(tJ(ven(n,e.a,t)))):(GQ(n),UD(),UD(),sut)}function adn(n,t){var e;0!=n.c.length&&(zL(e=uG(Ekn(n,Inn(pbt,e6n,10,n.c.length,0,1)),199),new Oe),WNn(e,t))}function odn(n,t){var e;0!=n.c.length&&(zL(e=uG(Ekn(n,Inn(pbt,e6n,10,n.c.length,0,1)),199),new Ae),WNn(e,t))}function udn(n,t){return RA(n)?m_(n,t):FA(n)?p_(n,t):KA(n)?(tJ(n),xA(n)===xA(t)):Cz(n)?n.Fb(t):xX(n)?SL(n,t):j3(n,t)}function sdn(n,t,e){if(t<0)zLn(n,e);else{if(!e.rk())throw hv(new vM(Gtt+e.xe()+qtt));uG(e,69).wk().Ek(n,n.hi(),t)}}function hdn(n,t,e){if(n<0||t>e)throw hv(new dM(o2n+n+s2n+t+", size: "+e));if(n>t)throw hv(new vM(o2n+n+u2n+t))}function fdn(n){var t;return 64&n.Db?vxn(n):((t=new fx(vxn(n))).a+=" (source: ",VA(t,n.d),t.a+=")",t.a)}function ldn(n){return n>=65&&n<=70?n-65+10:n>=97&&n<=102?n-97+10:n>=48&&n<=57?n-48:0}function bdn(n){var t,e,i,r;for(JYn(),i=0,r=(e=Nkn()).length;i=0?Rmn(n):hW(Rmn(Men(n))))}function Sdn(n,t,e,i,r,c){this.e=new Zm,this.f=(can(),Qjt),kD(this.e,n),this.d=t,this.a=e,this.b=i,this.f=r,this.c=c}function Pdn(n,t,i){n.n=Jq(nUt,[zZn,E0n],[376,28],14,[i,t0(e.Math.ceil(t/32))],2),n.o=t,n.p=i,n.j=t-1>>1,n.k=i-1>>1}function Cdn(n){return n=((n=((n-=n>>1&1431655765)>>2&858993459)+(858993459&n))>>4)+n&252645135,n+=n>>8,63&(n+=n>>16)}function Idn(n,t){var e,i;for(i=new DD(n);i.e!=i.i.gc();)if(e=uG(Zkn(i),142),xA(t)===xA(e))return!0;return!1}function Odn(n,t,e){var i,r;return(r=jxn(n.b,t))&&(i=uG(JXn(Len(n,r),""),29))?hxn(n,i,t,e):null}function Adn(n,t,e){var i,r;return(r=jxn(n.b,t))&&(i=uG(JXn(Len(n,r),""),29))?fxn(n,i,t,e):null}function Ldn(n,t){var e;if(null==(e=dcn(n.i,t)))throw hv(new SM("Node did not exist in input."));return Qun(t,e),null}function Ndn(n,t){var e;if(F$(e=EKn(n,t),331))return uG(e,35);throw hv(new vM(Gtt+t+"' is not a valid attribute"))}function $dn(n,t,e){var i;if(t>(i=n.gc()))throw hv(new w_(t,i));if(n.Si()&&n.Hc(e))throw hv(new vM(Xet));n.Gi(t,e)}function Ddn(n,t){t.Ug("Sort end labels",1),kS(JJ(sin(new fX(null,new h3(n.b,16)),new we),new de),new ge),t.Vg()}function xdn(){xdn=E,ZDt=new PO(Y2n,0),YDt=new PO(V2n,1),JDt=new PO(z2n,2),QDt=new PO(c3n,3),nxt=new PO("UP",4)}function Rdn(){Rdn=E,HAt=new fO("P1_STRUCTURE",0),UAt=new fO("P2_PROCESSING_ORDER",1),GAt=new fO("P3_EXECUTION",2)}function Kdn(){Kdn=E,qCt=Lvn(Lvn(gP(Lvn(Lvn(gP(Aq(new wJ,(Cjn(),VSt),(OHn(),fPt)),WSt),oPt),sPt),QSt),iPt),hPt)}function Fdn(n){switch(uG(oIn(n,(GYn(),Xpt)),311).g){case 1:kfn(n,Xpt,(Zen(),dpt));break;case 2:kfn(n,Xpt,(Zen(),ppt))}}function _dn(n){switch(n){case 0:return new Fk;case 1:return new Rk;case 2:return new Kk;default:throw hv(new Dv)}}function Bdn(n){switch(n.g){case 2:return YDt;case 1:return JDt;case 4:return QDt;case 3:return nxt;default:return ZDt}}function Hdn(n,t){switch(n.b.g){case 0:case 1:return t;case 2:case 3:return new gY(t.d,0,t.a,t.b);default:return null}}function Udn(n){switch(n.g){case 1:return _Rt;case 2:return yRt;case 3:return kRt;case 4:return KRt;default:return FRt}}function Gdn(n){switch(n.g){case 1:return KRt;case 2:return _Rt;case 3:return yRt;case 4:return kRt;default:return FRt}}function qdn(n){switch(n.g){case 1:return kRt;case 2:return KRt;case 3:return _Rt;case 4:return yRt;default:return FRt}}function Xdn(n,t,e,i){switch(t){case 1:return!n.n&&(n.n=new fV(lFt,n,1,7)),n.n;case 2:return n.k}return ajn(n,t,e,i)}function zdn(n,t,e){var i,r;return n.Pj()?(r=n.Qj(),i=HNn(n,t,e),n.Jj(n.Ij(7,xwn(e),i,t,r)),i):HNn(n,t,e)}function Vdn(n,t){var e,i,r;null==n.d?(++n.e,--n.f):(r=t.ld(),S7(n,i=((e=t.Bi())&vZn)%n.d.length,Txn(n,i,e,r)))}function Wdn(n,t){var e;e=!!(n.Bb&w1n),t?n.Bb|=w1n:n.Bb&=-1025,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,10,e,t))}function Qdn(n,t){var e;e=!!(n.Bb&j0n),t?n.Bb|=j0n:n.Bb&=-4097,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,12,e,t))}function Jdn(n,t){var e;e=!!(n.Bb&hrt),t?n.Bb|=hrt:n.Bb&=-8193,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,15,e,t))}function Ydn(n,t){var e;e=!!(n.Bb&frt),t?n.Bb|=frt:n.Bb&=-2049,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,11,e,t))}function Zdn(n){var t;n.g&&(CFn((t=n.c.kg()?n.f:n.a).a,n.o,!0),CFn(t.a,n.o,!1),kfn(n.o,(jYn(),JMt),($Pn(),rRt)))}function ngn(n){var t;if(!n.a)throw hv(new kM("Cannot offset an unassigned cut."));t=n.c-n.b,n.b+=t,iZ(n,t),eZ(n,t)}function tgn(n,t){var e;if(null==(e=cQ(n.k,t)))throw hv(new SM("Port did not exist in input."));return Qun(t,e),null}function egn(n){var t,e;for(e=bxn(Hrn(n)).Kc();e.Ob();)if(qUn(n,t=mK(e.Pb())))return h8((yP(),r_t),t);return null}function ign(n){var t,e;for(e=n.p.a.ec().Kc();e.Ob();)if((t=uG(e.Pb(),218)).f&&n.b[t.c]<-1e-10)return t;return null}function rgn(n){var t,e;for(e=jQ(new WM,91),t=!0;n.Ob();)t||(e.a+=TZn),t=!1,QA(e,n.Pb());return(e.a+="]",e).a}function cgn(n){var t,e,i;for(t=new Zm,i=new Ww(n.b);i.at?1:n==t?0==n?ugn(1/n,1/t):0:isNaN(n)?isNaN(t)?0:1:-1}function sgn(n){var t;return null==(t=n.a[n.c-1&n.a.length-1])?null:(n.c=n.c-1&n.a.length-1,uQ(n.a,n.c,null),t)}function hgn(n){var t,e,i;for(i=0,e=n.length,t=0;t=1?YDt:QDt:t}function mgn(n){switch(uG(oIn(n,(jYn(),Vyt)),223).g){case 1:return new ic;case 3:return new uc;default:return new ec}}function vgn(n){if(n.c)vgn(n.c);else if(n.d)throw hv(new kM("Stream already terminated, can't be modified or used"))}function kgn(n,t,e){var i;return i=n.a.get(t),n.a.set(t,void 0===e?null:e),void 0===i?(++n.c,++n.b.g):++n.d,i}function ygn(n,t,e){var i,r;for(r=n.a.ec().Kc();r.Ob();)if(i=uG(r.Pb(),10),yhn(e,uG(zq(t,i.p),16)))return i;return null}function Mgn(n,t,e){var i;return i=0,t&&(fN(n.a)?i+=t.f.a/2:i+=t.f.b/2),e&&(fN(n.a)?i+=e.f.a/2:i+=e.f.b/2),i}function Tgn(n,t,e){var i;!(i=e)&&(i=xG(new fy,0)),i.Ug(K4n,2),zyn(n.b,t,i.eh(1)),Xzn(n,t,i.eh(1)),hJn(t,i.eh(1)),i.Vg()}function jgn(n,t,e){var i;return gj(),Scn(i=new ns,t),pcn(i,e),n&&ttn((!n.a&&(n.a=new MD(eFt,n,5)),n.a),i),i}function Egn(n){var t;return 64&n.Db?vxn(n):((t=new fx(vxn(n))).a+=" (identifier: ",VA(t,n.k),t.a+=")",t.a)}function Sgn(n,t){var e;e=!!(n.Bb&Qtt),t?n.Bb|=Qtt:n.Bb&=-32769,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,18,e,t))}function Pgn(n,t){var e;e=!!(n.Bb&Qtt),t?n.Bb|=Qtt:n.Bb&=-32769,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,18,e,t))}function Cgn(n,t){var e;e=!!(n.Bb&VZn),t?n.Bb|=VZn:n.Bb&=-16385,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,16,e,t))}function Ign(n,t){var e;e=!!(n.Bb&P0n),t?n.Bb|=P0n:n.Bb&=-65537,4&n.Db&&!(1&n.Db)&&Msn(n,new j9(n,1,20,e,t))}function Ogn(n){var t;return t=Inn(JHt,N1n,28,2,15,1),n-=P0n,t[0]=(n>>10)+C0n&D1n,t[1]=56320+(1023&n)&D1n,mvn(t,0,t.length)}function Agn(n){var t;return(t=YIn(n))>34028234663852886e22?M0n:t<-34028234663852886e22?T0n:t}function Lgn(n,t){var e;return _L(n)&&_L(t)&&p0n<(e=n+t)&&e"+V3(t.c):"e_"+Hon(t),n.b&&n.c?V3(n.b)+"->"+V3(n.c):"e_"+Hon(n))}function Kgn(n,t){return m_(t.b&&t.c?V3(t.b)+"->"+V3(t.c):"e_"+Hon(t),n.b&&n.c?V3(n.b)+"->"+V3(n.c):"e_"+Hon(n))}function Fgn(n,t){return YN(),oan(T1n),e.Math.abs(n-t)<=T1n||n==t||isNaN(n)&&isNaN(t)?0:nt?1:KL(isNaN(n),isNaN(t))}function _gn(){_gn=E,fxt=new IO(Y2n,0),sxt=new IO("POLYLINE",1),uxt=new IO("ORTHOGONAL",2),hxt=new IO("SPLINES",3)}function Bgn(){Bgn=E,IOt=new aO("ASPECT_RATIO_DRIVEN",0),OOt=new aO("MAX_SCALE_DRIVEN",1),COt=new aO("AREA_DRIVEN",2)}function Hgn(n,t,e){try{Vfn(n,t,e)}catch(i){throw F$(i=Ehn(i),606)?hv(new x9(i)):hv(i)}return t}function Ugn(n){var t,e;for(t=0,e=n.length;tt&&i.Ne(n[c-1],n[c])>0;--c)a=n[c],uQ(n,c,n[c-1]),uQ(n,c-1,a)}function Zgn(n,t){var e,i,r,c,a;if(e=t.f,Akn(n.c.d,e,t),null!=t.g)for(c=0,a=(r=t.g).length;ct){F4(e);break}}lW(e,t)}function tpn(n,t){var i,r;r=uM(pK(Omn(z4(t),(jYn(),dTt)))),TEn(t,i=e.Math.max(0,r/2-.5),1),kD(n,new xC(t,i))}function epn(n,t,e){e.Ug("Straight Line Edge Routing",1),e.dh(t,l7n),DXn(n,uG(zDn(t,(SK(),zCt)),27)),e.dh(t,w7n)}function ipn(n,t){0==n.n.c.length&&kD(n.n,new c0(n.s,n.t,n.i)),kD(n.b,t),zMn(uG(zq(n.n,n.n.c.length-1),209),t),nqn(n,t)}function rpn(n){var t;this.a=new nB(t=uG(n.e&&n.e(),9),uG(MF(t,t.length),9),0),this.b=Inn(dat,EZn,1,this.a.a.length,5,1)}function cpn(n){return Array.isArray(n)&&n.Tm===j?Ij(Tbn(n))+"@"+(Hon(n)>>>0).toString(16):n.toString()}function apn(n,t){return n.h==b0n&&0==n.m&&0==n.l?(t&&(Qat=p$(0,0,0)),LL((tin(),Zat))):(t&&(Qat=p$(n.l,n.m,n.h)),p$(0,0,0))}function opn(n,t){switch(t.g){case 2:return n.b;case 1:return n.c;case 4:return n.d;case 3:return n.a;default:return!1}}function upn(n,t){switch(t.g){case 2:return n.b;case 1:return n.c;case 4:return n.d;case 3:return n.a;default:return!1}}function spn(n,t,e,i){switch(t){case 3:return n.f;case 4:return n.g;case 5:return n.i;case 6:return n.j}return Xdn(n,t,e,i)}function hpn(n,t){if(t==n.d)return n.e;if(t==n.e)return n.d;throw hv(new vM("Node "+t+" not part of edge "+n))}function fpn(n,t){var e;if(F$(e=EKn(n.Dh(),t),102))return uG(e,19);throw hv(new vM(Gtt+t+"' is not a valid reference"))}function lpn(n,t,e,i){if(t<0)lRn(n,e,i);else{if(!e.rk())throw hv(new vM(Gtt+e.xe()+qtt));uG(e,69).wk().Ck(n,n.hi(),t,i)}}function bpn(n){var t;if(n.b){if(bpn(n.b),n.b.d!=n.c)throw hv(new Fv)}else n.d.dc()&&(t=uG(n.f.c.xc(n.e),16))&&(n.d=t)}function wpn(n){var t,e;for(VK(),t=n.o.b,e=uG(uG(Y9(n.r,(KQn(),KRt)),21),87).Kc();e.Ob();)uG(e.Pb(),117).e.b+=t}function dpn(n){var t,e,i;for(this.a=new XL,i=new Ww(n);i.a=r)return t.c+e;return t.c+t.b.gc()}function ppn(n,t){var e,i,r,c;for(EK(),r=t,Ntn(i=Jtn(n),0,i.length,r),e=0;e0&&(i+=r,++e);return e>1&&(i+=n.d*(e-1)),i}function Mpn(n){var t,e,i;return i=gCn(n),!pE(n.c)&&(nrn(i,"knownLayouters",e=new Ib),t=new jm(e),z8(n.c,t)),i}function Tpn(n){var t,e,i;for((i=new zM).a+="[",t=0,e=n.gc();t0&&(s3(t-1,n.length),58==n.charCodeAt(t-1))&&!mpn(n,n_t,t_t)}function Cpn(n,t){var e;return xA(n)===xA(t)||!!F$(t,92)&&(e=uG(t,92),n.e==e.e&&n.d==e.d&&d8(n,e.a))}function Ipn(n){switch(KQn(),n.g){case 4:return yRt;case 1:return kRt;case 3:return KRt;case 2:return _Rt;default:return FRt}}function Opn(n){var t,e;if(n.b)return n.b;for(e=Nut?null:n.d;e;){if(t=Nut?null:e.b)return t;e=Nut?null:e.d}return pS(),Eut}function Apn(n){var t,e;for(e=uM(pK(n.a.of((XYn(),LDt)))),t=new Ww(n.a.Sf());t.a>5),15,1))[e]=1<3;)r*=10,--c;n=(n+(r>>1))/r|0}return i.i=n,!0}function emn(n,t){var e,i,r;if(null==n.i&&eqn(n),e=n.i,-1!=(i=t.Lj()))for(r=e.length;i=0;--i)for(t=e[i],r=0;r>1,this.k=t-1>>1}function hmn(n){Stn(),uG(n.of((XYn(),q$t)),181).Hc((oUn(),oKt))&&(uG(n.of(bDt),181).Fc((eNn(),pRt)),uG(n.of(q$t),181).Mc(oKt))}function fmn(n){var t,e;t=n.d==(vAn(),Bdt),e=dPn(n),kfn(n.a,(jYn(),byt),t&&!e||!t&&e?(nMn(),LNt):(nMn(),ANt))}function lmn(){lmn=E,ZS(),jYn(),WTt=ETt,QTt=n7(Uhn(cT(lNt,1),m9n,149,0,[wTt,dTt,pTt,mTt,yTt,MTt,TTt,jTt,PTt,ITt,gTt,vTt,STt]))}function bmn(n,t){var e;return(e=uG(l8(n,ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15)).Qc(Nq(e.gc()))}function wmn(n,t){var e,i;if((i=new od(n.a.ad(t,!0))).a.gc()<=1)throw hv(new Rv);return(e=i.a.ec().Kc()).Pb(),uG(e.Pb(),40)}function dmn(n,t,e){var i;return i=uM(n.p[t.i.p])+uM(n.d[t.i.p])+t.n.b+t.a.b,uM(n.p[e.i.p])+uM(n.d[e.i.p])+e.n.b+e.a.b-i}function gmn(n,t){return n.i>0&&(t.lengthn.i&&uQ(t,n.i,null),t}function pmn(n){var t;return 64&n.Db?Wwn(n):((t=new fx(Wwn(n))).a+=" (instanceClassName: ",VA(t,n.D),t.a+=")",t.a)}function mmn(n){var t,e,i,r;for(r=0,e=0,i=n.length;e0&&(n._j(),-1!=Txn(n,((e=null==t?0:Hon(t))&vZn)%n.d.length,e,t))}function Mmn(n,t){var i,r;n.a=Lgn(n.a,1),n.c=e.Math.min(n.c,t),n.b=e.Math.max(n.b,t),n.d+=t,i=t-n.f,r=n.e+i,n.f=r-n.e-i,n.e=r}function Tmn(n,t){switch(t){case 3:return void vcn(n,0);case 4:return void kcn(n,0);case 5:return void ycn(n,0);case 6:return void Mcn(n,0)}Awn(n,t)}function jmn(n,t){switch(t.g){case 1:return YU(n.j,(Lun(),ybt));case 2:return YU(n.j,(Lun(),Tbt));default:return hZ(),hZ(),zot}}function Emn(n){var t;switch(ZW(),(t=n.Pc()).length){case 0:return jat;case 1:return new Uq(WW(t[0]));default:return new t1(Ugn(t))}}function Smn(n,t){n.Xj();try{n.d.bd(n.e++,t),n.f=n.d.j,n.g=-1}catch(e){throw F$(e=Ehn(e),77)?hv(new Fv):hv(e)}}function Pmn(){Pmn=E,lBt=new Is,cBt=new Os,aBt=new As,oBt=new Ls,uBt=new Ns,sBt=new $s,hBt=new Ds,fBt=new xs,bBt=new Rs}function Cmn(n,t){var e,i;return wL(),i=null,t==(e=bF((qy(),qy(),Hat)))&&(i=uG(U1(Bat,n),624)),i||(i=new JW(n),t==e&&r2(Bat,n,i)),i}function Imn(n){return Yyn(),(n.q?n.q:(hZ(),hZ(),Vot))._b((jYn(),LMt))?uG(oIn(n,LMt),203):uG(oIn(HQ(n),NMt),203)}function Omn(n,t){var e,i;return i=null,vR(n,(jYn(),kTt))&&(e=uG(oIn(n,kTt),96)).pf(t)&&(i=e.of(t)),null==i&&(i=oIn(HQ(n),t)),i}function Amn(n,t){var e,i,r;return!!F$(t,44)&&(i=(e=uG(t,44)).ld(),xQ(r=Xwn(n.Rc(),i),e.md())&&(null!=r||n.Rc()._b(i)))}function Lmn(n,t){var e,i;return n.f>0&&(n._j(),e=ZNn(n,((i=null==t?0:Hon(t))&vZn)%n.d.length,i,t))?e.md():null}function Nmn(n,t,e){var i,r,c;return n.Pj()?(i=n.i,c=n.Qj(),edn(n,i,t),r=n.Ij(3,null,t,i,c),e?e.nj(r):e=r):edn(n,n.i,t),e}function $mn(n,t,e){var i,r;return i=new Ken(n.e,4,10,F$(r=t.c,90)?uG(r,29):(YYn(),x_t),null,Hyn(n,t),!1),e?e.nj(i):e=i,e}function Dmn(n,t,e){var i,r;return i=new Ken(n.e,3,10,null,F$(r=t.c,90)?uG(r,29):(YYn(),x_t),Hyn(n,t),!1),e?e.nj(i):e=i,e}function xmn(n){var t;return VK(),t=new eN(uG(n.e.of((XYn(),U$t)),8)),n.B.Hc((oUn(),eKt))&&(t.a<=0&&(t.a=20),t.b<=0&&(t.b=20)),t}function Rmn(n){var t,e;return cHn(),e=pz(n),0!=(t=pz(Dz(n,32)))?new x3(e,t):e>10||e<0?new Z5(1,e):Rot[e]}function Kmn(n,t){var e;return _L(n)&&_L(t)&&p0n<(e=n%t)&&e=0?c=c.a[1]:(r=c,c=c.a[0])}return r}function nvn(n,t,e){var i,r,c;for(r=null,c=n.b;c;){if(i=n.a.Ne(t,c.d),e&&0==i)return c;i<=0?c=c.a[0]:(r=c,c=c.a[1])}return r}function tvn(n,t,e,i){var r,c,a;return r=!1,nWn(n.f,e,i)&&(hkn(n.f,n.a[t][e],n.a[t][i]),a=(c=n.a[t])[i],c[i]=c[e],c[e]=a,r=!0),r}function evn(n,t,e){var i,r,c;for(r=uG(cQ(n.b,e),183),i=0,c=new Ww(t.j);c.a>5,t&=31,r=n.d+e+(0==t?0:1),kCn(i=Inn(YHt,W1n,28,r,15,1),n.a,e,t),K4(c=new VV(n.e,r,i)),c}function cvn(n,t){var e;for(e=new Fz(ix(Xgn(n).a.Kc(),new h));hDn(e);)if(uG(N9(e),18).d.i.c==t)return!1;return!0}function avn(n,t,i){var r,c,a,o,u;return o=n.k,u=t.k,c=pK(Omn(n,r=i[o.g][u.g])),a=pK(Omn(t,r)),e.Math.max((tJ(c),c),(tJ(a),a))}function ovn(){return Error.stackTraceLimit>0?(e.Error.stackTraceLimit=Error.stackTraceLimit=64,!0):"stack"in new Error}function uvn(n,t){return YN(),YN(),oan(T1n),(e.Math.abs(n-t)<=T1n||n==t||isNaN(n)&&isNaN(t)?0:nt?1:KL(isNaN(n),isNaN(t)))>0}function svn(n,t){return YN(),YN(),oan(T1n),(e.Math.abs(n-t)<=T1n||n==t||isNaN(n)&&isNaN(t)?0:nt?1:KL(isNaN(n),isNaN(t)))<0}function hvn(n,t){return YN(),YN(),oan(T1n),(e.Math.abs(n-t)<=T1n||n==t||isNaN(n)&&isNaN(t)?0:nt?1:KL(isNaN(n),isNaN(t)))<=0}function fvn(n,t){for(var e=0;!t[e]||""==t[e];)e++;for(var i=t[e++];e0&&this.b>0&&(this.g=mX(this.c,this.b,this.a))}function Tvn(n,t){var e,i=n.a;t=String(t),i.hasOwnProperty(t)&&(e=i[t]);var r=(Cfn(),Wat)[typeof e];return r?r(e):Vbn(typeof e)}function jvn(n){if(!(Iet in n.a))throw hv(new SM("Every element must have an id."));return fNn(v0(n,Iet))}function Evn(n){var t,e;for(e=WOn(n),t=null;2==n.c;)EYn(n),t||(QYn(),QYn(),kzn(t=new QN(2),e),e=t),e.Jm(WOn(n));return e}function Svn(n,t){var e,i;return n._j(),(e=ZNn(n,((i=null==t?0:Hon(t))&vZn)%n.d.length,i,t))?(uan(n,e),e.md()):null}function Pvn(n,t){return n.e>t.e?1:n.et.d?n.e:n.d=48&&n<48+e.Math.min(10,10)?n-48:n>=97&&n<97?n-97+10:n>=65&&n<65?n-65+10:-1}function Ivn(n,t){if(t.c==n)return t.d;if(t.d==n)return t.c;throw hv(new vM("Input edge is not connected to the input port."))}function Ovn(n){if(Bvn(Fnt,n))return qx(),eot;if(Bvn(_nt,n))return qx(),tot;throw hv(new vM("Expecting true or false"))}function Avn(n){switch(typeof n){case pZn:return pln(n);case gZn:return OL(n);case dZn:return XK(n);default:return null==n?0:xx(n)}}function Lvn(n,t){if(n.a<0)throw hv(new kM("Did not call before(...) or after(...) before calling add(...)."));return hR(n,n.a,t),n}function Nvn(n){return W0(),F$(n,162)?uG(cQ(AFt,iut),295).Rg(n):PV(AFt,Tbn(n))?uG(cQ(AFt,Tbn(n)),295).Rg(n):null}function $vn(n){var t;return 32&n.Db||0!=(t=iQ(uG(Lsn(n,16),29)||n.ii())-iQ(n.ii()))&&Dvn(n,32,Inn(dat,EZn,1,t,5,1)),n}function Dvn(n,t,e){var i;n.Db&t?null==e?H$n(n,t):-1==(i=jTn(n,t))?n.Eb=e:uQ(Kcn(n.Eb),i,e):null!=e&&lFn(n,t,e)}function xvn(n,t,e,i){var r;0!=t.c.length&&(r=gRn(e,i),kS(krn(new fX(null,new h3(WLn(t),1)),new ba),new pY(n,e,r,i)))}function Rvn(n,t){var e,i,r;return i=n.a.length-1,e=t-n.b&i,r=n.c-t&i,jK(e<(n.c-n.b&i)),e>=r?(Pbn(n,t),-1):(Sbn(n,t),1)}function Kvn(n){var t,e,i;if(!(i=n.Jh()))for(t=0,e=n.Ph();e;e=e.Ph()){if(++t>O0n)return e.Qh();if((i=e.Jh())||e==n)break}return i}function Fvn(n,t){var e;return xA(t)===xA(n)||!!F$(t,21)&&(e=uG(t,21)).gc()==n.gc()&&n.Ic(e)}function _vn(n,t){return n.et.e?1:n.ft.f?1:Hon(n)-Hon(t)}function Bvn(n,t){return tJ(n),null!=t&&(!!m_(n,t)||n.length==t.length&&m_(n.toLowerCase(),t.toLowerCase()))}function Hvn(n){var t,e;return dwn(n,-129)>0&&dwn(n,128)<0?(tX(),t=pz(n)+128,!(e=got[t])&&(e=got[t]=new Ow(n)),e):new Ow(n)}function Uvn(){Uvn=E,tbt=new EC(q4n,0),Zlt=new EC("INSIDE_PORT_SIDE_GROUPS",1),Ylt=new EC("GROUP_MODEL_ORDER",2),nbt=new EC(X4n,3)}function Gvn(n){var t;return n.b||wj(n,!(t=QF(n.e,n.a))||!m_(_nt,Lmn((!t.b&&(t.b=new XR((YYn(),H_t),wBt,t)),t.b),"qualified"))),n.c}function qvn(n,t){var e,i;for(s3(t,n.length),e=n.charCodeAt(t),i=t+1;i2e3&&(Gat=n,qat=e.setTimeout(vE,10)),0==Uat++&&(Pin((Gy(),Fat)),!0)}function wkn(n,t,e){var i;(Aut?(Opn(n),1):Lut||Dut?(pS(),1):$ut&&(pS(),0))&&((i=new iB(t)).b=e,qIn(n,i))}function dkn(n,t){var e;e=!n.A.Hc((Qmn(),JRt))||n.q==($Pn(),cRt),n.u.Hc((eNn(),wRt))?e?QQn(n,t):TQn(n,t):n.u.Hc(gRt)&&(e?YWn(n,t):MJn(n,t))}function gkn(n){var t;xA(zDn(n,(XYn(),E$t)))===xA((Own(),Oxt))&&(R0(n)?(t=uG(zDn(R0(n),E$t),346),Myn(n,E$t,t)):Myn(n,E$t,Axt))}function pkn(n){var t,e;return!!vR(n.d.i,(jYn(),UMt))&&(t=uG(oIn(n.c.i,UMt),17),e=uG(oIn(n.d.i,UMt),17),d$(t.a,e.a)>0)}function mkn(n,t,i){return new gY(e.Math.min(n.a,t.a)-i/2,e.Math.min(n.b,t.b)-i/2,e.Math.abs(n.a-t.a)+i,e.Math.abs(n.b-t.b)+i)}function vkn(n){var t;this.d=new Zm,this.j=new sj,this.g=new sj,t=n.g.b,this.f=uG(oIn(HQ(t),(jYn(),Byt)),88),this.e=uM(pK(eyn(t,yTt)))}function kkn(n){this.d=new Zm,this.e=new u8,this.c=Inn(YHt,W1n,28,(KQn(),Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt])).length,15,1),this.b=n}function ykn(n,t,e){var i;switch(i=e[n.g][t],n.g){case 1:case 3:return new MO(0,i);case 2:case 4:return new MO(i,0);default:return null}}function Mkn(n,t,e){var i;i=uG(A1(t.f),205);try{i.rf(n,e),WQ(t.f,i)}catch(r){throw F$(r=Ehn(r),103),hv(r)}}function Tkn(n,t,e){var i,r,c,a;return i=null,(c=DVn(aan(),t))&&(r=null,null!=(a=vVn(c,e))&&(r=n.qf(c,a)),i=r),i}function jkn(n,t,e,i){var r;if(t>=(r=n.length))return r;for(t=t>0?t:0;ti&&uQ(t,i,null),t}function Skn(n,t){var e,i;for(i=n.a.length,t.lengthi&&uQ(t,i,null),t}function Pkn(n,t){var e,i;++n.j,null!=t&&e$n(t,e=F$(i=n.a.Cb,99)?uG(i,99).th():null)?Dvn(n.a,4,e):Dvn(n.a,4,uG(t,129))}function Ckn(n){var t;if(null==n)return null;if(null==(t=Exn(yXn(n,!0))))throw hv(new PM("Invalid hexBinary value: '"+n+"'"));return t}function Ikn(n,t,e){var i;t.a.length>0&&(kD(n.b,new hG(t.a,e)),0<(i=t.a.length)?t.a=r1(t.a,0,0):0>i&&(t.a+=V$(Inn(JHt,N1n,28,-i,15,1))))}function Okn(n,t,e){var i;if(!e[t.d])for(e[t.d]=!0,i=new Ww(Ebn(t));i.a=n.b>>1)for(i=n.c,e=n.b;e>t;--e)i=i.b;else for(i=n.a.a,e=0;e=0?n.Wh(r):$Nn(n,i):e<0?$Nn(n,i):uG(i,69).wk().Bk(n,n.hi(),e)}function Qkn(n){var t,e;for(!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),t=(e=n.o).c.Kc();t.e!=t.i.gc();)uG(t.Yj(),44).md();return Tnn(e)}function Jkn(n){var t;if(F$(n.a,4)){if(null==(t=Nvn(n.a)))throw hv(new kM(Bnt+n.b+"'. "+Rnt+(vK($Ft),$Ft.k)+Knt));return t}return n.a}function Ykn(n,t){var e,i;if(n.j.length!=t.j.length)return!1;for(e=0,i=n.j.length;e=64&&t<128&&(r=S3(r,Nz(1,t-64)));return r}function eyn(n,t){var e,i;return i=null,vR(n,(XYn(),ODt))&&(e=uG(oIn(n,ODt),96)).pf(t)&&(i=e.of(t)),null==i&&HQ(n)&&(i=oIn(HQ(n),t)),i}function iyn(n,t){var e;return e=uG(oIn(n,(jYn(),bMt)),75),_$(t,cbt)?e?BY(e):(e=new Uk,kfn(n,bMt,e)):e&&kfn(n,bMt,null),e}function ryn(){ryn=E,XYn(),ift=SDt,Jht=M$t,Xht=c$t,Yht=W$t,MEn(),tft=cst,nft=ist,eft=ost,Zht=est,pbn(),Vht=Hht,zht=Bht,Wht=Ght,Qht=qht}function cyn(n){switch(qS(),this.c=new Zm,this.d=n,n.g){case 0:case 2:this.a=kJ(Qlt),this.b=M0n;break;case 3:case 1:this.a=Qlt,this.b=T0n}}function ayn(n){var t;L_(uG(oIn(n,(jYn(),JMt)),101))&&(c$n((u3(0,(t=n.b).c.length),uG(t.c[0],30))),c$n(uG(zq(t,t.c.length-1),30)))}function oyn(n,t){t.Ug("Self-Loop post-processing",1),kS(JJ(JJ(sin(new fX(null,new h3(n.b,16)),new Di),new xi),new Ri),new Ki),t.Vg()}function uyn(n,t,e){var i;if(n.c)ycn(n.c,n.c.i+t),Mcn(n.c,n.c.j+e);else for(i=new Ww(n.b);i.a=0&&(e.d=n.t);break;case 3:n.t>=0&&(e.a=n.t)}n.C&&(e.b=n.C.b,e.c=n.C.c)}function pyn(){pyn=E,Tjt=new wI(k9n,0),kjt=new wI(D6n,1),yjt=new wI("LINEAR_SEGMENTS",2),vjt=new wI("BRANDES_KOEPF",3),Mjt=new wI(v9n,4)}function myn(){myn=E,Nht=new lC(o3n,0),Lht=new lC(u3n,1),$ht=new lC(s3n,2),Dht=new lC(h3n,3),Nht.a=!1,Lht.a=!0,$ht.a=!1,Dht.a=!0}function vyn(){vyn=E,yht=new hC(o3n,0),kht=new hC(u3n,1),Mht=new hC(s3n,2),Tht=new hC(h3n,3),yht.a=!1,kht.a=!0,Mht.a=!1,Tht.a=!0}function kyn(n,t,e,i){var r;return e>=0?n.Sh(t,e,i):(n.Ph()&&(i=(r=n.Fh())>=0?n.Ah(i):n.Ph().Th(n,-1-r,null,i)),n.Ch(t,e,i))}function yyn(n,t){switch(t){case 7:return!n.e&&(n.e=new f_(aFt,n,7,4)),void Czn(n.e);case 8:return!n.d&&(n.d=new f_(aFt,n,8,5)),void Czn(n.d)}Tmn(n,t)}function Myn(n,t,e){return null==e?(!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),Svn(n.o,t)):(!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),rSn(n.o,t,e)),n}function Tyn(n,t){var e,i,r,c;for(hZ(),e=n,c=t,F$(n,21)&&!F$(t,21)&&(e=t,c=n),r=e.Kc();r.Ob();)if(i=r.Pb(),c.Hc(i))return!1;return!0}function jyn(n,t,e,i){if(t.ae.b)return!0}return!1}function Eyn(n,t){return RA(n)?!!bZn[t]:n.Sm?!!n.Sm[t]:FA(n)?!!lZn[t]:!!KA(n)&&!!fZn[t]}function Syn(n){var t;t=n.a;do{(t=uG(N9(new Fz(ix(qgn(t).a.Kc(),new h))),18).c.i).k==(zIn(),wbt)&&n.b.Fc(t)}while(t.k==(zIn(),wbt));n.b=Spn(n.b)}function Pyn(n,t){var i,r,c;for(c=n,r=new Fz(ix(qgn(t).a.Kc(),new h));hDn(r);)(i=uG(N9(r),18)).c.i.c&&(c=e.Math.max(c,i.c.i.c.p));return c}function Cyn(n,t){var e,i,r;for(r=0,i=uG(uG(Y9(n.r,t),21),87).Kc();i.Ob();)r+=(e=uG(i.Pb(),117)).d.d+e.b.Mf().b+e.d.a,i.Ob()&&(r+=n.w);return r}function Iyn(n,t){var e,i,r;for(r=0,i=uG(uG(Y9(n.r,t),21),87).Kc();i.Ob();)r+=(e=uG(i.Pb(),117)).d.b+e.b.Mf().a+e.d.c,i.Ob()&&(r+=n.w);return r}function Oyn(n){var t,e,i;if(e=0,0==(i=GFn(n)).c.length)return 1;for(t=new Ww(i);t.a=0?n.Lh(a,e,!0):YNn(n,c,e):uG(c,69).wk().yk(n,n.hi(),r,e,i)}function xyn(n,t,e,i){var r;(r=bdn(t.pf((XYn(),K$t))?uG(t.of(K$t),21):n.j))!=(JYn(),sht)&&(e&&!vvn(r)||LOn(Sxn(n,r,i),t))}function Ryn(n){switch(n.g){case 1:return ehn(),pht;case 3:return ehn(),wht;case 2:return ehn(),ght;case 4:return ehn(),dht;default:return null}}function Kyn(n,t,e){if(n.e)switch(n.b){case 1:JY(n.c,t,e);break;case 0:YY(n.c,t,e)}else C5(n.c,t,e);n.a[t.p][e.p]=n.c.i,n.a[e.p][t.p]=n.c.e}function Fyn(n){var t,e;if(null==n)return null;for(e=Inn(pbt,zZn,199,n.length,0,2),t=0;t=0)return i;if(n.ol())for(e=0;e=(r=n.gc()))throw hv(new w_(t,r));if(n.Si()&&(i=n.dd(e))>=0&&i!=t)throw hv(new vM(Xet));return n.Xi(t,e)}function Gyn(n,t){if(this.a=uG(WW(n),253),this.b=uG(WW(t),253),n.Ed(t)>0||n==(py(),Mat)||t==(my(),Tat))throw hv(new vM("Invalid range: "+N5(n,t)))}function qyn(n){var t,e;for(this.b=new Zm,this.c=n,this.a=!1,e=new Ww(n.a);e.a0),(t&-t)==t)return t0(t*uRn(n,31)*4.656612873077393e-10);do{i=(e=uRn(n,31))%t}while(e-i+(t-1)<0);return t0(i)}function rMn(n,t,e){switch(e.g){case 1:n.a=t.a/2,n.b=0;break;case 2:n.a=t.a,n.b=t.b/2;break;case 3:n.a=t.a/2,n.b=t.b;break;case 4:n.a=0,n.b=t.b/2}}function cMn(n,t,e,i){var r,c;for(r=t;r1&&(r=Xyn(n,t)),r}function sMn(n){var t;return new MO(t=uM(pK(zDn(n,(XYn(),BDt))))*e.Math.sqrt((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a).i),t/uM(pK(zDn(n,_Dt))))}function hMn(n){var t;return n.f&&n.f.Vh()&&(t=uG(n.f,54),n.f=uG(mwn(n,t),84),n.f!=t&&4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,9,8,t,n.f))),n.f}function fMn(n){var t;return n.i&&n.i.Vh()&&(t=uG(n.i,54),n.i=uG(mwn(n,t),84),n.i!=t&&4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,9,7,t,n.i))),n.i}function lMn(n){var t;return n.b&&64&n.b.Db&&(t=n.b,n.b=uG(mwn(n,t),19),n.b!=t&&4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,9,21,t,n.b))),n.b}function bMn(n,t){var e,i,r;null==n.d?(++n.e,++n.f):(i=t.Bi(),eKn(n,n.f+1),r=(i&vZn)%n.d.length,!(e=n.d[r])&&(e=n.d[r]=n.dk()),e.Fc(t),++n.f)}function wMn(n,t,e){var i;return!t.tk()&&(-2!=t.Ik()?null==(i=t.ik())?null==e:udn(i,e):t.qk()==n.e.Dh()&&null==e)}function dMn(){var n;man(16,b1n),n=aon(16),this.b=Inn(Cat,l1n,303,n,0,1),this.c=Inn(Cat,l1n,303,n,0,1),this.a=null,this.e=null,this.i=0,this.f=n-1,this.g=0}function gMn(n){LF.call(this),this.k=(zIn(),dbt),this.j=(man(6,g1n),new R7(6)),this.b=(man(2,g1n),new R7(2)),this.d=new $k,this.f=new xk,this.a=n}function pMn(n){var t,e;n.c.length<=1||(iAn(n,uG((t=w_n(n,(KQn(),KRt))).a,17).a,uG(t.b,17).a),iAn(n,uG((e=w_n(n,_Rt)).a,17).a,uG(e.b,17).a))}function mMn(n,t,e){var i,r;for(i=(r=n.a.b).c.length;i102?-1:n<=57?n-48:n<65?-1:n<=70?n-65+10:n<97?-1:n-97+10}function IMn(n,t){if(null==n)throw hv(new MM("null key in entry: null="+t));if(null==t)throw hv(new MM("null value in entry: "+n+"=null"))}function OMn(n,t){for(var e,i;n.Ob();){if(!t.Ob())return!1;if(e=n.Pb(),i=t.Pb(),!(xA(e)===xA(i)||null!=e&&udn(e,i)))return!1}return!t.Ob()}function AMn(n,t){var i;return i=Uhn(cT(eUt,1),I0n,28,15,[Nbn(n.a[0],t),Nbn(n.a[1],t),Nbn(n.a[2],t)]),n.d&&(i[0]=e.Math.max(i[0],i[2]),i[2]=i[0]),i}function LMn(n,t){var i;return i=Uhn(cT(eUt,1),I0n,28,15,[$bn(n.a[0],t),$bn(n.a[1],t),$bn(n.a[2],t)]),n.d&&(i[0]=e.Math.max(i[0],i[2]),i[2]=i[0]),i}function NMn(n,t,e){L_(uG(oIn(t,(jYn(),JMt)),101))||(Z8(n,t,yOn(t,e)),Z8(n,t,yOn(t,(KQn(),KRt))),Z8(n,t,yOn(t,yRt)),hZ(),f$(t.j,new Gg(n)))}function $Mn(n){var t,e;for(n.c||oVn(n),e=new Uk,N3(t=new Ww(n.a));t.a0&&(s3(0,t.length),43==t.charCodeAt(0))?(s3(1,t.length+1),t.substr(1)):t)}function nTn(n){var t;return null==n?null:new PN((t=yXn(n,!0)).length>0&&(s3(0,t.length),43==t.charCodeAt(0))?(s3(1,t.length+1),t.substr(1)):t)}function tTn(n,t,e,i,r,c,a,o){var u,s;i&&((u=i.a[0])&&tTn(n,t,e,u,r,c,a,o),ljn(n,e,i.d,r,c,a,o)&&t.Fc(i),(s=i.a[1])&&tTn(n,t,e,s,r,c,a,o))}function eTn(n,t,e){try{return _A(Son(n,t,e),1)}catch(i){throw F$(i=Ehn(i),333)?hv(new dM(b3n+n.o+"*"+n.p+w3n+t+TZn+e+d3n)):hv(i)}}function iTn(n,t,e){try{return _A(Son(n,t,e),0)}catch(i){throw F$(i=Ehn(i),333)?hv(new dM(b3n+n.o+"*"+n.p+w3n+t+TZn+e+d3n)):hv(i)}}function rTn(n,t,e){try{return _A(Son(n,t,e),2)}catch(i){throw F$(i=Ehn(i),333)?hv(new dM(b3n+n.o+"*"+n.p+w3n+t+TZn+e+d3n)):hv(i)}}function cTn(n,t){if(-1==n.g)throw hv(new xv);n.Xj();try{n.d.hd(n.g,t),n.f=n.d.j}catch(e){throw F$(e=Ehn(e),77)?hv(new Fv):hv(e)}}function aTn(n){var t,e,i;for(e=new Ww(n.b);e.ac&&uQ(t,c,null),t}function uTn(n,t){var e,i;if(i=n.gc(),null==t){for(e=0;e0&&(u+=r),s[h]=a,a+=o*(u+i)}function TTn(n){var t,e,i;for(i=n.f,n.n=Inn(eUt,I0n,28,i,15,1),n.d=Inn(eUt,I0n,28,i,15,1),t=0;t0?n.c:0),++c;n.b=r,n.d=a}function ATn(n,t){var i;return i=Uhn(cT(eUt,1),I0n,28,15,[eMn(n,(Yrn(),jst),t),eMn(n,Est,t),eMn(n,Sst,t)]),n.f&&(i[0]=e.Math.max(i[0],i[2]),i[2]=i[0]),i}function LTn(n,t,e){try{HBn(n,t+n.j,e+n.k,!1,!0)}catch(i){throw F$(i=Ehn(i),77)?hv(new dM(i.g+g3n+t+TZn+e+").")):hv(i)}}function NTn(n,t,e){try{HBn(n,t+n.j,e+n.k,!0,!1)}catch(i){throw F$(i=Ehn(i),77)?hv(new dM(i.g+g3n+t+TZn+e+").")):hv(i)}}function $Tn(n){var t;vR(n,(jYn(),PMt))&&((t=uG(oIn(n,PMt),21)).Hc((VDn(),Bxt))?(t.Mc(Bxt),t.Fc(Uxt)):t.Hc(Uxt)&&(t.Mc(Uxt),t.Fc(Bxt)))}function DTn(n){var t;vR(n,(jYn(),PMt))&&((t=uG(oIn(n,PMt),21)).Hc((VDn(),Vxt))?(t.Mc(Vxt),t.Fc(Xxt)):t.Hc(Xxt)&&(t.Mc(Xxt),t.Fc(Vxt)))}function xTn(n,t,e,i){var r,c,a;return null==n.a&&nOn(n,t),a=t.b.j.c.length,c=e.d.p,(r=i.d.p-1)<0&&(r=a-1),c<=r?n.a[r]-n.a[c]:n.a[a-1]-n.a[c]+n.a[r]}function RTn(n){var t,e;if(!n.b)for(n.b=o6(uG(n.f,27).kh().i),e=new DD(uG(n.f,27).kh());e.e!=e.i.gc();)t=uG(Zkn(e),135),kD(n.b,new Wy(t));return n.b}function KTn(n){var t,e;if(!n.e)for(n.e=o6(RJ(uG(n.f,27)).i),e=new DD(RJ(uG(n.f,27)));e.e!=e.i.gc();)t=uG(Zkn(e),123),kD(n.e,new Jp(t));return n.e}function FTn(n){var t,e;if(!n.a)for(n.a=o6(wZ(uG(n.f,27)).i),e=new DD(wZ(uG(n.f,27)));e.e!=e.i.gc();)t=uG(Zkn(e),27),kD(n.a,new Wx(n,t));return n.a}function _Tn(n){var t;if(!n.C&&(null!=n.D||null!=n.B))if(t=KWn(n))n.hl(t);else try{n.hl(null)}catch(e){if(!F$(e=Ehn(e),63))throw hv(e)}return n.C}function BTn(n){switch(n.q.g){case 5:QEn(n,(KQn(),yRt)),QEn(n,KRt);break;case 4:TVn(n,(KQn(),yRt)),TVn(n,KRt);break;default:PAn(n,(KQn(),yRt)),PAn(n,KRt)}}function HTn(n){switch(n.q.g){case 5:JEn(n,(KQn(),kRt)),JEn(n,_Rt);break;case 4:jVn(n,(KQn(),kRt)),jVn(n,_Rt);break;default:CAn(n,(KQn(),kRt)),CAn(n,_Rt)}}function UTn(n,t){var i,r,c;for(c=new sj,r=n.Kc();r.Ob();)tHn(i=uG(r.Pb(),36),c.a,0),c.a+=i.f.a+t,c.b=e.Math.max(c.b,i.f.b);return c.b>0&&(c.b+=t),c}function GTn(n,t){var i,r,c;for(c=new sj,r=n.Kc();r.Ob();)tHn(i=uG(r.Pb(),36),0,c.b),c.b+=i.f.b+t,c.a=e.Math.max(c.a,i.f.a);return c.a>0&&(c.a+=t),c}function qTn(n){var t,i,r;for(r=vZn,i=new Ww(n.a);i.a>16==6?n.Cb.Th(n,5,fFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||n.ii(),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function WTn(n){EZ();var t=n.e;if(t&&t.stack){var e=t.stack,i=t+"\n";return e.substring(0,i.length)==i&&(e=e.substring(i.length)),e.split("\n")}return[]}function QTn(n){var t;return Tan(),(t=wot)[n>>>28]|t[n>>24&15]<<4|t[n>>20&15]<<8|t[n>>16&15]<<12|t[n>>12&15]<<16|t[n>>8&15]<<20|t[n>>4&15]<<24|t[15&n]<<28}function JTn(n){var t,i,r;n.b==n.c&&(r=n.a.length,i=pfn(e.Math.max(8,r))<<1,0!=n.b?(Pon(n,t=MF(n.a,i),r),n.a=t,n.b=0):Xv(n.a,i),n.c=r)}function YTn(n,t){var e;return(e=n.b).pf((XYn(),uDt))?e.ag()==(KQn(),_Rt)?-e.Mf().a-uM(pK(e.of(uDt))):t+uM(pK(e.of(uDt))):e.ag()==(KQn(),_Rt)?-e.Mf().a:t}function ZTn(n){var t;return 0!=n.b.c.length&&uG(zq(n.b,0),72).a?uG(zq(n.b,0),72).a:null!=(t=sY(n))?t:""+(n.c?Ten(n.c.a,n,0):-1)}function njn(n){var t;return 0!=n.f.c.length&&uG(zq(n.f,0),72).a?uG(zq(n.f,0),72).a:null!=(t=sY(n))?t:""+(n.i?Ten(n.i.j,n,0):-1)}function tjn(n,t){var e,i;if(t<0||t>=n.gc())return null;for(e=t;e0?n.c:0),c=e.Math.max(c,t.d),++r;n.e=a,n.b=c}function rjn(n){var t,e;if(!n.b)for(n.b=o6(uG(n.f,123).kh().i),e=new DD(uG(n.f,123).kh());e.e!=e.i.gc();)t=uG(Zkn(e),135),kD(n.b,new Wy(t));return n.b}function cjn(n,t){var e,i,r;if(t.dc())return EK(),EK(),KFt;for(e=new cF(n,t.gc()),r=new DD(n);r.e!=r.i.gc();)i=Zkn(r),t.Hc(i)&&ttn(e,i);return e}function ajn(n,t,e,i){return 0==t?i?(!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),n.o):(!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),Tnn(n.o)):Dyn(n,t,e,i)}function ojn(n){var t,e;if(n.rb)for(t=0,e=n.rb.i;t>22))>>22)<0||(n.l=e&f0n,n.m=i&f0n,n.h=r&l0n,0)))}function ljn(n,t,e,i,r,c,a){var o,u;return!(t.Te()&&(u=n.a.Ne(e,i),u<0||!r&&0==u)||t.Ue()&&(o=n.a.Ne(e,c),o>0||!a&&0==o))}function bjn(n,t){if(Cln(),0!=n.j.g-t.j.g)return 0;switch(n.j.g){case 2:return Wgn(t,edt)-Wgn(n,edt);case 4:return Wgn(n,tdt)-Wgn(t,tdt)}return 0}function wjn(n){switch(n.g){case 0:return jgt;case 1:return Egt;case 2:return Sgt;case 3:return Pgt;case 4:return Cgt;case 5:return Igt;default:return null}}function djn(n,t,e){var i,r;return Kbn(r=new ny,t),qon(r,e),ttn((!n.c&&(n.c=new fV(m_t,n,12,10)),n.c),r),Pcn(i=r,0),Ccn(i,1),mdn(i,!0),ddn(i,!0),i}function gjn(n,t){var e,i;if(t>=n.i)throw hv(new pL(t,n.i));return++n.j,e=n.g[t],(i=n.i-t-1)>0&&qGn(n.g,t+1,n.g,t,i),uQ(n.g,--n.i,null),n.Qi(t,e),n.Ni(),e}function pjn(n,t){var e;return n.Db>>16==17?n.Cb.Th(n,21,h_t,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||n.ii(),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function mjn(n){var t,e,i;for(hZ(),f$(n.c,n.a),i=new Ww(n.c);i.ae.a.c.length))throw hv(new vM("index must be >= 0 and <= layer node count"));n.c&&men(n.c.a,n),n.c=e,e&&GX(e.a,t,n)}function Djn(n,t){var e,i,r;for(i=new Fz(ix(Ggn(n).a.Kc(),new h));hDn(i);)return e=uG(N9(i),18),new Ul(WW((r=uG(t.Kb(e),10)).n.b+r.o.b/2));return gy(),gy(),wat}function xjn(n,t){this.c=new Ym,this.a=n,this.b=t,this.d=uG(oIn(n,(GYn(),kmt)),312),xA(oIn(n,(jYn(),CMt)))===xA((Wtn(),Lgt))?this.e=new Pk:this.e=new Sk}function Rjn(n,t){var e,i;return i=null,n.pf((XYn(),ODt))&&(e=uG(n.of(ODt),96)).pf(t)&&(i=e.of(t)),null==i&&n.Tf()&&(i=n.Tf().of(t)),null==i&&(i=Jkn(t)),i}function Kjn(n,t){var e,i;e=n.fd(t);try{return i=e.Pb(),e.Qb(),i}catch(r){throw F$(r=Ehn(r),112)?hv(new dM("Can't remove element "+t)):hv(r)}}function Fjn(n,t){var e,i,r;if(0==(e=Wqn(n,t,r=new Lfn((i=new QE).q.getFullYear()-V1n,i.q.getMonth(),i.q.getDate())))||e0?t:0),++i;return new MO(r,c)}function zjn(n,t){var e;return n.Db>>16==6?n.Cb.Th(n,6,aFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(tYn(),BKt),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function Vjn(n,t){var e;return n.Db>>16==7?n.Cb.Th(n,1,iFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(tYn(),UKt),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function Wjn(n,t){var e;return n.Db>>16==9?n.Cb.Th(n,9,bFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(tYn(),qKt),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function Qjn(n,t){var e;return n.Db>>16==5?n.Cb.Th(n,9,w_t,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(YYn(),O_t),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function Jjn(n,t){var e;return n.Db>>16==7?n.Cb.Th(n,6,fFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(YYn(),F_t),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function Yjn(n,t){var e;return n.Db>>16==3?n.Cb.Th(n,0,uFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(YYn(),T_t),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function Zjn(){this.a=new ss,this.g=new dMn,this.j=new dMn,this.b=new Ym,this.d=new dMn,this.i=new dMn,this.k=new Ym,this.c=new Ym,this.e=new Ym,this.f=new Ym}function nEn(n,t,e){var i,r,c;for(e<0&&(e=0),c=n.i,r=e;rO0n)return eEn(n,i);if(i==n)return!0}}return!1}function iEn(n){switch(Gx(),n.q.g){case 5:uNn(n,(KQn(),yRt)),uNn(n,KRt);break;case 4:Kxn(n,(KQn(),yRt)),Kxn(n,KRt);break;default:$Qn(n,(KQn(),yRt)),$Qn(n,KRt)}}function rEn(n){switch(Gx(),n.q.g){case 5:k$n(n,(KQn(),kRt)),k$n(n,_Rt);break;case 4:fyn(n,(KQn(),kRt)),fyn(n,_Rt);break;default:DQn(n,(KQn(),kRt)),DQn(n,_Rt)}}function cEn(n){var t,e;(t=uG(oIn(n,(cGn(),Dft)),17))?(e=t.a,kfn(n,(mon(),Qft),0==e?new Upn:new v8(e))):kfn(n,(mon(),Qft),new v8(1))}function aEn(n,t){var e;switch(e=n.i,t.g){case 1:return-(n.n.b+n.o.b);case 2:return n.n.a-e.o.a;case 3:return n.n.b-e.o.b;case 4:return-(n.n.a+n.o.a)}return 0}function oEn(n,t){switch(n.g){case 0:return t==(Gpn(),Imt)?qwt:Xwt;case 1:return t==(Gpn(),Imt)?qwt:Gwt;case 2:return t==(Gpn(),Imt)?Gwt:Xwt;default:return Gwt}}function uEn(n,t){var i,r,c;for(men(n.a,t),n.e-=t.r+(0==n.a.c.length?0:n.c),c=b7n,r=new Ww(n.a);r.a>16==3?n.Cb.Th(n,12,bFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(tYn(),_Kt),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function hEn(n,t){var e;return n.Db>>16==11?n.Cb.Th(n,10,bFt,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(tYn(),GKt),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function fEn(n,t){var e;return n.Db>>16==10?n.Cb.Th(n,11,h_t,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(YYn(),R_t),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function lEn(n,t){var e;return n.Db>>16==10?n.Cb.Th(n,12,p_t,t):(e=lMn(uG(ern(uG(Lsn(n,16),29)||(YYn(),__t),n.Db>>16),19)),n.Cb.Th(n,e.n,e.f,t))}function bEn(n){var t;return 1&n.Bb||!n.r||!n.r.Vh()||(t=uG(n.r,54),n.r=uG(mwn(n,t),142),n.r!=t&&4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,9,8,t,n.r))),n.r}function wEn(n,t,i){var r;return r=Uhn(cT(eUt,1),I0n,28,15,[BCn(n,(Yrn(),jst),t,i),BCn(n,Est,t,i),BCn(n,Sst,t,i)]),n.f&&(r[0]=e.Math.max(r[0],r[2]),r[2]=r[0]),r}function dEn(n,t){var e,i,r;if(0!=(r=lyn(n,t)).c.length)for(f$(r,new ti),e=r.c.length,i=0;i>19)!=(o=t.h>>19)?o-a:(i=n.h)!=(c=t.h)?i-c:(e=n.m)!=(r=t.m)?e-r:n.l-t.l}function MEn(){MEn=E,W_n(),ost=new mL($2n,ust=dst),Xin(),cst=new mL(D2n,ast=Zut),_kn(),ist=new mL(x2n,rst=Wut),est=new mL(R2n,(qx(),!0))}function TEn(n,t,e){var i,r;i=t*e,F$(n.g,154)?(r=Q6(n)).f.d?r.f.a||(n.d.a+=i+Z2n):(n.d.d-=i+Z2n,n.d.a+=i+Z2n):F$(n.g,10)&&(n.d.d-=i,n.d.a+=2*i)}function jEn(n,t,i){var r,c,a,o,u;for(c=n[i.g],u=new Ww(t.d);u.a0?n.b:0),++i;t.b=r,t.e=c}function SEn(n){var t,e,i;if(i=n.b,aS(n.i,i.length)){for(e=2*i.length,n.b=Inn(Cat,l1n,303,e,0,1),n.c=Inn(Cat,l1n,303,e,0,1),n.f=e-1,n.i=0,t=n.a;t;t=t.c)HLn(n,t,t);++n.g}}function PEn(n,t,e,i){var r,c,a,o;for(r=0;ro&&(u=o/r),(c=e.Math.abs(n.b))>a&&(s=a/c),vD(n,e.Math.min(u,s)),n}function AEn(){var n,t;tXn();try{if(t=uG(ASn((MP(),l_t),aet),2113))return t}catch(e){if(!F$(e=Ehn(e),103))throw hv(e);n=e,AW((t$(),n))}return new rs}function LEn(){var n,t;tXn();try{if(t=uG(ASn((MP(),l_t),Drt),2040))return t}catch(e){if(!F$(e=Ehn(e),103))throw hv(e);n=e,AW((t$(),n))}return new _s}function NEn(){var n,t;Ftn();try{if(t=uG(ASn((MP(),l_t),lct),2122))return t}catch(e){if(!F$(e=Ehn(e),103))throw hv(e);n=e,AW((t$(),n))}return new Nh}function $En(n,t,e){var i,r;return r=n.e,n.e=t,4&n.Db&&!(1&n.Db)&&(i=new lV(n,1,4,r,t),e?e.nj(i):e=i),r!=t&&(e=PWn(n,t?bRn(n,t):n.a,e)),e}function DEn(){QE.call(this),this.e=-1,this.a=!1,this.p=j1n,this.k=-1,this.c=-1,this.b=-1,this.g=!1,this.f=-1,this.j=-1,this.n=-1,this.i=-1,this.d=-1,this.o=j1n}function xEn(n,t){var e,i,r;if(i=n.b.d.d,n.a||(i+=n.b.d.a),r=t.b.d.d,t.a||(r+=t.b.d.a),0==(e=ugn(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function REn(n,t){var e,i,r;if(i=n.b.b.d,n.a||(i+=n.b.b.a),r=t.b.b.d,t.a||(r+=t.b.b.a),0==(e=ugn(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function KEn(n,t){var e,i,r;if(i=n.b.g.d,n.a||(i+=n.b.g.a),r=t.b.g.d,t.a||(r+=t.b.g.a),0==(e=ugn(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function FEn(){FEn=E,klt=wz(Aq(Aq(Aq(new wJ,(uIn(),Slt),(zYn(),owt)),Slt,fwt),Plt,mwt),Plt,Wbt),Mlt=Aq(Aq(new wJ,Slt,Fbt),Slt,Qbt),ylt=wz(new wJ,Plt,Ybt)}function _En(n){var t,e,i,r,c;for(t=uG(oIn(n,(GYn(),$pt)),85),c=n.n,i=t.Cc().Kc();i.Ob();)(r=(e=uG(i.Pb(),314)).i).c+=c.a,r.d+=c.b,e.c?P_n(e):C_n(e);kfn(n,$pt,null)}function BEn(n,t,e){var i,r;switch(i=(r=n.b).d,t.g){case 1:return-i.d-e;case 2:return r.o.a+i.c+e;case 3:return r.o.b+i.a+e;case 4:return-i.b-e;default:return-1}}function HEn(n,t,e){var i;for(e.Ug("Interactive node placement",1),n.a=uG(oIn(t,(GYn(),kmt)),312),i=new Ww(t.b);i.a0&&(r=ZNn(n,(c&vZn)%n.d.length,c,t))?r.nd(e):(i=n.ck(c,t,e),n.c.Fc(i),null)}function cSn(n,t){var e,i,r,c;switch(tdn(n,t).Kl()){case 3:case 2:for(r=0,c=(e=hXn(t)).i;r=0;r--)if(m_(n[r].d,t)||m_(n[r].d,i)){n.length>=r+1&&n.splice(0,r+1);break}return n}function bSn(n,t){var i;return _L(n)&&_L(t)&&p0n<(i=n/t)&&i0&&(n.b+=2,n.a+=r):(n.b+=1,n.a+=e.Math.min(r,c))}function ySn(n){var t;t=uG(oIn(uG(hyn(n.b,0),40),(QGn(),pCt)),107),kfn(n,(OQn(),kPt),new MO(0,0)),rUn(new L7,n,t.b+t.c-uM(pK(oIn(n,PPt))),t.d+t.a-uM(pK(oIn(n,IPt))))}function MSn(n,t){var e;if(e=!1,RA(t)&&(e=!0,pQ(n,new QW(mK(t)))),e||F$(t,242)&&(e=!0,pQ(n,new Pb(Q_(uG(t,242))))),!e)throw hv(new pM(Cet))}function TSn(n,t,e,i){var r,c,a;return r=new Ken(n.e,1,10,F$(a=t.c,90)?uG(a,29):(YYn(),x_t),F$(c=e.c,90)?uG(c,29):(YYn(),x_t),Hyn(n,t),!1),i?i.nj(r):i=r,i}function jSn(n){var t,e;switch(uG(oIn(HQ(n),(jYn(),lMt)),429).g){case 0:return t=n.n,e=n.o,new MO(t.a+e.a/2,t.b+e.b/2);case 1:return new eN(n.n);default:return null}}function ESn(){ESn=E,Fgt=new rI(q4n,0),Kgt=new rI("LEFTUP",1),Bgt=new rI("RIGHTUP",2),Rgt=new rI("LEFTDOWN",3),_gt=new rI("RIGHTDOWN",4),xgt=new rI("BALANCED",5)}function SSn(n,t,e){var i,r,c;if(0==(i=ugn(n.a[t.p],n.a[e.p]))){if(r=uG(oIn(t,(GYn(),Vpt)),15),c=uG(oIn(e,Vpt),15),r.Hc(e))return-1;if(c.Hc(t))return 1}return i}function PSn(n){switch(n.g){case 1:return new So;case 2:return new Po;case 3:return new Eo;case 0:return null;default:throw hv(new vM(k7n+(null!=n.f?n.f:""+n.g)))}}function CSn(n,t,e){switch(t){case 1:return!n.n&&(n.n=new fV(lFt,n,1,7)),Czn(n.n),!n.n&&(n.n=new fV(lFt,n,1,7)),void CW(n.n,uG(e,16));case 2:return void Gan(n,mK(e))}bln(n,t,e)}function ISn(n,t,e){switch(t){case 3:return void vcn(n,uM(pK(e)));case 4:return void kcn(n,uM(pK(e)));case 5:return void ycn(n,uM(pK(e)));case 6:return void Mcn(n,uM(pK(e)))}CSn(n,t,e)}function OSn(n,t,e){var i,r;(i=CCn(r=new ny,t,null))&&i.oj(),qon(r,e),ttn((!n.c&&(n.c=new fV(m_t,n,12,10)),n.c),r),Pcn(r,0),Ccn(r,1),mdn(r,!0),ddn(r,!0)}function ASn(n,t){var e,i;return F$(e=_P(n.i,t),241)?((i=uG(e,241)).zi(),i.wi()):F$(e,507)?i=uG(e,2037).b:null}function LSn(n,t,e,i){var r,c;return WW(t),WW(e),Ren(!!(c=uG(W_(n.d,t),17)),"Row %s not in %s",t,n.e),Ren(!!(r=uG(W_(n.b,e),17)),"Column %s not in %s",e,n.c),Hhn(n,c.a,r.a,i)}function NSn(n,t,e,i,r,c,a){var o,u,s,h,f;if(f=PTn(o=(s=c==a-1)?i:0,h=r[c]),10!=i&&Uhn(cT(n,a-c),t[c],e[c],o,f),!s)for(++c,u=0;u1||-1==o?(c=uG(u,15),r.Wb(Vpn(n,c))):r.Wb(uUn(n,uG(u,58))))}function zSn(n,t,e,i){kE();var r=hZn;function c(){for(var n=0;n0)return!1;return!0}function QSn(n){var t,e,i,r,c;for(i=new bsn(new Nw(n.b).a);i.b;)t=uG((e=von(i)).ld(),10),c=uG(uG(e.md(),42).a,10),r=uG(uG(e.md(),42).b,8),JF(dL(t.n),JF(D$(c.n),r))}function JSn(n){switch(uG(oIn(n.b,(jYn(),Jyt)),387).g){case 1:kS(YJ(sin(new fX(null,new h3(n.d,16)),new Vr),new Wr),new Qr);break;case 2:gBn(n);break;case 0:mLn(n)}}function YSn(n,t,e){var i,r,c;for(!(i=e)&&(i=new fy),i.Ug("Layout",n.a.c.length),c=new Ww(n.a);c.a$9n)return e;i>-1e-6&&++e}return e}function rPn(n,t){var e;t!=n.b?(e=null,n.b&&(e=O1(n.b,n,-4,e)),t&&(e=kyn(t,n,-4,e)),(e=kwn(n,t,e))&&e.oj()):4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,3,t,t))}function cPn(n,t){var e;t!=n.f?(e=null,n.f&&(e=O1(n.f,n,-1,e)),t&&(e=kyn(t,n,-1,e)),(e=vwn(n,t,e))&&e.oj()):4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,0,t,t))}function aPn(n,t,e,i){var r,c,a;return uN(n.e)&&(a=VZ(n,1,r=t.Lk(),t.md(),c=e.md(),r.Jk()?Dqn(n,r,c,F$(r,102)&&!!(uG(r,19).Bb&P0n)):-1,!0),i?i.nj(a):i=a),i}function oPn(n){var t,e,i;if(null==n)return null;if((e=uG(n,15)).dc())return"";for(i=new zM,t=e.Kc();t.Ob();)VA(i,(uVn(),mK(t.Pb()))),i.a+=" ";return CL(i,i.a.length-1)}function uPn(n){var t,e,i;if(null==n)return null;if((e=uG(n,15)).dc())return"";for(i=new zM,t=e.Kc();t.Ob();)VA(i,(uVn(),mK(t.Pb()))),i.a+=" ";return CL(i,i.a.length-1)}function sPn(n,t,e){var i,r;return i=n.c[t.c.p][t.p],r=n.c[e.c.p][e.p],null!=i.a&&null!=r.a?Rz(i.a,r.a):null!=i.a?-1:null!=r.a?1:0}function hPn(n,t,e){return e.Ug("Tree layout",1),_J(n.b),JV(n.b,(Cjn(),zSt),zSt),JV(n.b,VSt,VSt),JV(n.b,WSt,WSt),JV(n.b,QSt,QSt),n.a=Qzn(n.b,t),YSn(n,t,e.eh(1)),e.Vg(),t}function fPn(n,t){var e,i,r;if(t)for(r=((e=new Gz(t.a.length)).b-e.a)*e.c<0?(CP(),XHt):new xD(e);r.Ob();)i=v6(t,uG(r.Pb(),17).a),QJ(new om(n).a,i)}function lPn(n,t){var e,i,r;if(t)for(r=((e=new Gz(t.a.length)).b-e.a)*e.c<0?(CP(),XHt):new xD(e);r.Ob();)i=v6(t,uG(r.Pb(),17).a),WJ(new Yp(n).a,i)}function bPn(n){if(null!=n&&n.length>0&&33==VJ(n,n.length-1))try{return null==sxn(r1(n,0,n.length-1)).e}catch(t){if(!F$(t=Ehn(t),33))throw hv(t)}return!1}function wPn(n,t,e){var i,r;switch(i=pgn(HQ(t)),o2(r=new lOn,t),e.g){case 1:NLn(r,Gdn(Ipn(i)));break;case 2:NLn(r,Ipn(i))}return kfn(r,(jYn(),QMt),pK(oIn(n,QMt))),r}function dPn(n){var t,e;return t=uG(N9(new Fz(ix(qgn(n.a).a.Kc(),new h))),18),e=uG(N9(new Fz(ix(Xgn(n.a).a.Kc(),new h))),18),oM(gK(oIn(t,(GYn(),pmt))))||oM(gK(oIn(e,pmt)))}function gPn(){gPn=E,wdt=new zC("ONE_SIDE",0),gdt=new zC("TWO_SIDES_CORNER",1),pdt=new zC("TWO_SIDES_OPPOSING",2),ddt=new zC("THREE_SIDES",3),bdt=new zC("FOUR_SIDES",4)}function pPn(n,t){var e,i,r,c;for(c=new Zm,r=0,i=t.Kc();i.Ob();){for(e=xwn(uG(i.Pb(),17).a+r);e.a=n.f)break;mv(c.c,e)}return c}function mPn(n,t){var e,i,r;for(i=new Ww(t.a);i.a0&&Mjn(this,this.c-1,(KQn(),kRt)),this.c0&&n[0].length>0&&(this.c=oM(gK(oIn(HQ(n[0][0]),(GYn(),Wpt))))),this.a=Inn(REt,zZn,2117,n.length,0,2),this.b=Inn(UEt,zZn,2118,n.length,0,2),this.d=new zbn}function LPn(n){return 0!=n.c.length&&((u3(0,n.c.length),uG(n.c[0],18)).c.i.k==(zIn(),wbt)||o9(YJ(new fX(null,new h3(n,16)),new xc),new Rc))}function NPn(n,t){var i,r,c,a,o,u;for(o=GFn(t),c=t.f,u=t.g,a=e.Math.sqrt(c*c+u*u),r=0,i=new Ww(o);i.a=0?(e=bSn(n,g0n),i=Kmn(n,g0n)):(e=bSn(t=Dz(n,1),5e8),i=Lgn(Nz(i=Kmn(t,5e8),1),E3(n,1))),S3(Nz(i,32),E3(e,L0n))}function YPn(n,t,e){var i;switch(MK(0!=t.b),i=uG(Lrn(t,t.a.a),8),e.g){case 0:i.b=0;break;case 2:i.b=n.f;break;case 3:i.a=0;break;default:i.a=n.g}return lW(Fkn(t,0),i),t}function ZPn(n,t,e,i){var r,c,a,o,u;switch(u=n.b,o=ykn(a=(c=t.d).j,u.d[a.g],e),r=JF(D$(c.n),c.a),c.j.g){case 1:case 3:o.a+=r.a;break;case 2:case 4:o.b+=r.b}s8(i,o,i.c.b,i.c)}function nCn(n,t,e){var i,r,c,a;for(a=Ten(n.e,t,0),(c=new Tk).b=e,i=new N4(n.e,a);i.b1;t>>=1)1&t&&(i=j5(i,e)),e=1==e.d?j5(e,e):new nkn(_Un(e.a,e.d,Inn(YHt,W1n,28,e.d<<1,15,1)));return i=j5(i,e)}function aCn(){var n,t,e,i;for(aCn=E,but=Inn(eUt,I0n,28,25,15,1),wut=Inn(eUt,I0n,28,33,15,1),i=152587890625e-16,t=32;t>=0;t--)wut[t]=i,i*=.5;for(e=1,n=24;n>=0;n--)but[n]=e,e*=.5}function oCn(n){var t,e;if(oM(gK(zDn(n,(jYn(),sMt)))))for(e=new Fz(ix(eRn(n).a.Kc(),new h));hDn(e);)if(BNn(t=uG(N9(e),74))&&oM(gK(zDn(t,hMt))))return!0;return!1}function uCn(n,t){var e,i,r;FV(n.f,t)&&(t.b=n,i=t.c,-1!=Ten(n.j,i,0)||kD(n.j,i),r=t.d,-1!=Ten(n.j,r,0)||kD(n.j,r),0!=(e=t.a.b).c.length&&(!n.i&&(n.i=new vkn(n)),Psn(n.i,e)))}function sCn(n){var t,e,i,r;return(e=(t=n.c.d).j)==(r=(i=n.d.d).j)?t.p=0&&m_(n.substr(t,3),"GMT")||t>=0&&m_(n.substr(t,3),"UTC")?(e[0]=t+3,PUn(n,e,i)):PUn(n,e,i)}function wCn(n,t){var e,i,r,c,a;for(c=n.g.a,a=n.g.b,i=new Ww(n.d);i.ae;c--)n[c]|=t[c-e-1]>>>a,n[c-1]=t[c-e-1]<0&&qGn(n.g,t,n.g,t+i,o),a=e.Kc(),n.i+=i,r=0;r>4&15,c=15&n[i],a[r++]=JKt[e],a[r++]=JKt[c];return mvn(a,0,a.length)}function $Cn(n){var t,e;return n>=P0n?(t=C0n+(n-P0n>>10&1023)&D1n,e=56320+(n-P0n&1023)&D1n,String.fromCharCode(t)+""+String.fromCharCode(e)):String.fromCharCode(n&D1n)}function DCn(n,t){var e,i,r,c;return VK(),(r=uG(uG(Y9(n.r,t),21),87)).gc()>=2&&(i=uG(r.Kc().Pb(),117),e=n.u.Hc((eNn(),bRt)),c=n.u.Hc(pRt),!i.a&&!e&&(2==r.gc()||c))}function xCn(n,t,e,i,r){var c,a,o;for(c=zFn(n,t,e,i,r),o=!1;!c;)gxn(n,r,!0),o=!0,c=zFn(n,t,e,i,r);o&&gxn(n,r,!1),0!=(a=Jhn(r)).c.length&&(n.d&&n.d.Gg(a),xCn(n,r,e,i,a))}function RCn(){RCn=E,mxt=new OO(q4n,0),gxt=new OO("DIRECTED",1),vxt=new OO("UNDIRECTED",2),wxt=new OO("ASSOCIATION",3),pxt=new OO("GENERALIZATION",4),dxt=new OO("DEPENDENCY",5)}function KCn(n,t){var e;if(!h0(n))throw hv(new kM(Stt));switch(e=h0(n),t.g){case 1:return-(n.j+n.f);case 2:return n.i-e.g;case 3:return n.j-e.f;case 4:return-(n.i+n.g)}return 0}function FCn(n,t,e){var i,r,c;return i=t.Lk(),c=t.md(),r=i.Jk()?VZ(n,4,i,c,null,Dqn(n,i,c,F$(i,102)&&!!(uG(i,19).Bb&P0n)),!0):VZ(n,i.tk()?2:1,i,c,i.ik(),-1,!0),e?e.nj(r):e=r,e}function _Cn(n,t){var e,i;for(tJ(t),i=n.b.c.length,kD(n.b,t);i>0;){if(e=i,i=(i-1)/2|0,n.a.Ne(zq(n.b,i),t)<=0)return Y8(n.b,e,t),!0;Y8(n.b,e,zq(n.b,i))}return Y8(n.b,i,t),!0}function BCn(n,t,i,r){var c,a;if(c=0,i)c=$bn(n.a[i.g][t.g],r);else for(a=0;a<$st;a++)c=e.Math.max(c,$bn(n.a[a][t.g],r));return t==(Yrn(),Est)&&n.b&&(c=e.Math.max(c,n.b.a)),c}function HCn(n,t){var e,i,r,c,a;return i=n.i,r=t.i,!(!i||!r)&&i.i==r.i&&i.i!=(KQn(),kRt)&&i.i!=(KQn(),_Rt)&&(e=(c=i.g.a)+i.j.a,c<=(a=r.g.a)+r.j.a&&e>=a)}function UCn(n){switch(n.g){case 0:return new Uo;case 1:return new qo;default:throw hv(new vM("No implementation is available for the width approximator "+(null!=n.f?n.f:""+n.g)))}}function GCn(n,t,e,i){var r;if(r=!1,RA(i)&&(r=!0,ZG(t,e,mK(i))),r||KA(i)&&(r=!0,GCn(n,t,e,i)),r||F$(i,242)&&(r=!0,vZ(t,e,uG(i,242))),!r)throw hv(new pM(Cet))}function qCn(n,t){var e,i,r;if((e=t.qi(n.a))&&null!=(r=Lmn((!e.b&&(e.b=new XR((YYn(),H_t),wBt,e)),e.b),Srt)))for(i=1;i<(gAn(),mBt).length;++i)if(m_(mBt[i],r))return i;return 0}function XCn(n,t){var e,i,r;if((e=t.qi(n.a))&&null!=(r=Lmn((!e.b&&(e.b=new XR((YYn(),H_t),wBt,e)),e.b),Srt)))for(i=1;i<(gAn(),vBt).length;++i)if(m_(vBt[i],r))return i;return 0}function zCn(n,t){var e,i,r,c;if(tJ(t),(c=n.a.gc())0?1:0;c.a[r]!=e;)c=c.a[r],r=n.a.Ne(e.d,c.d)>0?1:0;c.a[r]=i,i.b=e.b,i.a[0]=e.a[0],i.a[1]=e.a[1],e.a[0]=null,e.a[1]=null}function ZCn(n){var t,e,i,r;for(t=new Zm,zV(e=Inn(ZHt,B2n,28,n.a.c.length,16,1),e.length),r=new Ww(n.a);r.a0&&lUn((u3(0,e.c.length),uG(e.c[0],30)),n),e.c.length>1&&lUn(uG(zq(e,e.c.length-1),30),n),t.Vg()}function eIn(n){return eNn(),!(qsn(X1(WX(wRt,Uhn(cT(BRt,1),p1n,279,0,[gRt])),n))>1||qsn(X1(WX(bRt,Uhn(cT(BRt,1),p1n,279,0,[lRt,pRt])),n))>1)}function iIn(n,t){F$(U1((MP(),l_t),n),507)?r2(l_t,n,new EA(this,t)):r2(l_t,n,this),HIn(this,t),t==(vj(),y_t)?(this.wb=uG(this,2038),uG(t,2040)):this.wb=(tQ(),M_t)}function rIn(n){var t,e;if(null==n)return null;for(t=null,e=0;e=$1n?"error":i>=900?"warn":i>=800?"info":"log",n.a),n.b&&SKn(t,e,n.b,"Exception: ",!0))}function oIn(n,t){var e,i;return!n.q&&(n.q=new Ym),null!=(i=cQ(n.q,t))?i:(F$(e=t.Sg(),4)&&(null==e?(!n.q&&(n.q=new Ym),u7(n.q,t)):(!n.q&&(n.q=new Ym),vJ(n.q,t,e))),e)}function uIn(){uIn=E,Tlt=new gC("P1_CYCLE_BREAKING",0),jlt=new gC("P2_LAYERING",1),Elt=new gC("P3_NODE_ORDERING",2),Slt=new gC("P4_NODE_PLACEMENT",3),Plt=new gC("P5_EDGE_ROUTING",4)}function sIn(n,t){var e;if(Win(),n.c==t.c){if(n.b==t.b||eun(n.b,t.b)){if(e=BL(n.b)?1:-1,n.a&&!t.a)return e;if(!n.a&&t.a)return-e}return d$(n.b.g,t.b.g)}return ugn(n.c,t.c)}function hIn(n,t){var e,i;if(kIn(n,t))return!0;for(i=new Ww(t);i.a=(r=n.Ej())||t<0)throw hv(new dM(zet+t+Vet+r));if(e>=r||e<0)throw hv(new dM(Wet+e+Vet+r));return t!=e?(c=n.Cj(e),n.qj(t,c),i=c):i=n.xj(e),i}function mIn(n){var t,e,i;if(i=n,n)for(t=0,e=n.Eh();e;e=e.Eh()){if(++t>O0n)return mIn(e);if(i=e,e==n)throw hv(new kM("There is a cycle in the containment hierarchy of "+n))}return i}function vIn(n){var t,e,i;for(i=new Ysn(TZn,"[","]"),e=n.Kc();e.Ob();)o7(i,xA(t=e.Pb())===xA(n)?"(this Collection)":null==t?IZn:cpn(t));return i.a?0==i.e.length?i.a.a:i.a.a+""+i.e:i.c}function kIn(n,t){var e,i;if(i=!1,t.gc()<2)return!1;for(e=0;e1&&(n.j.b+=n.e)):(n.j.a+=i.a,n.j.b=e.Math.max(n.j.b,i.b),n.d.c.length>1&&(n.j.a+=n.e))}function jIn(){jIn=E,ydt=Uhn(cT(YRt,1),z4n,64,0,[(KQn(),yRt),kRt,KRt]),kdt=Uhn(cT(YRt,1),z4n,64,0,[kRt,KRt,_Rt]),Mdt=Uhn(cT(YRt,1),z4n,64,0,[KRt,_Rt,yRt]),Tdt=Uhn(cT(YRt,1),z4n,64,0,[_Rt,yRt,kRt])}function EIn(n,t,e,i){var r,c,a,o,u;if(c=n.c.d,a=n.d.d,c.j!=a.j)for(u=n.b,r=c.j,o=null;r!=a.j;)o=0==t?qdn(r):Udn(r),aq(i,JF(ykn(r,u.d[r.g],e),ykn(o,u.d[o.g],e))),r=o}function SIn(n,t,e,i){var r,c,a,o,u;return o=uG((a=Sjn(n.a,t,e)).a,17).a,c=uG(a.b,17).a,i&&(u=uG(oIn(t,(GYn(),lmt)),10),r=uG(oIn(e,lmt),10),u&&r&&(C5(n.b,u,r),o+=n.b.i,c+=n.b.e)),o>c}function PIn(n){var t,e,i,r,c,a,o,u;for(this.a=Fyn(n),this.b=new Zm,i=0,r=(e=n).length;iGK(n.d).c?(n.i+=n.g.c,Bmn(n.d)):GK(n.d).c>GK(n.g).c?(n.e+=n.d.c,Bmn(n.g)):(n.i+=TX(n.g),n.e+=TX(n.d),Bmn(n.g),Bmn(n.d))}function LIn(n,t,e){var i,r,c,a;for(c=t.q,a=t.r,new A2((_7(),$St),t,c,1),new A2($St,c,a,1),r=new Ww(e);r.au&&(s=u/r),(c=e.Math.abs(t.b-n.b))>a&&(h=a/c),o=e.Math.min(s,h),n.a+=o*(t.a-n.a),n.b+=o*(t.b-n.b)}function FIn(n,t,e,i,r){var c,a;for(a=!1,c=uG(zq(e.b,0),27);Sqn(n,t,c,i,r)&&(a=!0,HSn(e,c),0!=e.b.c.length);)c=uG(zq(e.b,0),27);return 0==e.b.c.length&&uEn(e.j,e),a&&OTn(t.q),a}function _In(n,t){var e,i,r,c;if(l_n(),t.b<2)return!1;for(i=e=uG(I6(c=Fkn(t,0)),8);c.b!=c.d.c;){if(VRn(n,i,r=uG(I6(c),8)))return!0;i=r}return!!VRn(n,i,e)}function BIn(n,t,e,i){return 0==e?(!n.o&&(n.o=new ltn((tYn(),XKt),EFt,n,0)),G_(n.o,t,i)):uG(ern(uG(Lsn(n,16),29)||n.ii(),e),69).wk().Ak(n,$vn(n),e-iQ(n.ii()),t,i)}function HIn(n,t){var e;t!=n.sb?(e=null,n.sb&&(e=uG(n.sb,54).Th(n,1,sFt,e)),t&&(e=uG(t,54).Rh(n,1,sFt,e)),(e=Jwn(n,t,e))&&e.oj()):4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,4,t,t))}function UIn(n,t){var e,i;if(!t)throw hv(new SM("All edge sections need an end point."));e=$cn(t,"x"),mcn(new rm(n).a,(tJ(e),e)),i=$cn(t,"y"),jcn(new cm(n).a,(tJ(i),i))}function GIn(n,t){var e,i;if(!t)throw hv(new SM("All edge sections need a start point."));e=$cn(t,"x"),Tcn(new tm(n).a,(tJ(e),e)),i=$cn(t,"y"),Ecn(new em(n).a,(tJ(i),i))}function qIn(n,t){var e,i,r,c,a;for(i=0,c=xln(n).length;i>22-t,r=n.h<>22-t):t<44?(e=0,i=n.l<>44-t):(e=0,i=0,r=n.l<n)throw hv(new vM("k must be smaller than n"));return 0==t||t==n?1:0==n?0:uSn(n)/(uSn(t)*uSn(n-t))}function iOn(n,t){var e,i,r,c;for(e=new jN(n);null!=e.g||e.c?null==e.g||0!=e.i&&uG(e.g[e.i-1],51).Ob():O0(e);)if(F$(c=uG(Wxn(e),58),167))for(i=uG(c,167),r=0;r>4],t[2*e+1]=mHt[15&r];return mvn(t,0,t.length)}function vOn(n){var t;switch(TJ(),n.c.length){case 0:return Eat;case 1:return fq((t=uG(ULn(new Ww(n)),44)).ld(),t.md());default:return new xy(uG(Ekn(n,Inn(Sat,c1n,44,n.c.length,0,1)),173))}}function kOn(n){var t,e,i,r,c;for(t=new ND,e=new ND,A6(t,n),A6(e,n);e.b!=e.c;)for(c=new Ww(uG(xV(e),36).a);c.a0&&sHn(n,e,t),r):j$n(n,t,e)}function jOn(){jOn=E,XYn(),BIt=mDt,VIt=DDt,$It=_$t,DIt=U$t,xIt=q$t,NIt=K$t,RIt=V$t,_It=bDt,EHn(),AIt=dIt,LIt=gIt,UIt=MIt,XIt=EIt,GIt=TIt,qIt=jIt,KIt=mIt,FIt=kIt,HIt=yIt,zIt=SIt,WIt=CIt,OIt=wIt}function EOn(n,t){var e,i,r,c,a;if(n.e<=t)return n.g;if(l3(n,n.g,t))return n.g;for(c=n.r,i=n.g,a=n.r,r=(c-i)/2+i;i+11&&(n.e.b+=n.a)):(n.e.a+=i.a,n.e.b=e.Math.max(n.e.b,i.b),n.d.c.length>1&&(n.e.a+=n.a))}function NOn(n){var t,e,i,r;switch(t=(r=n.i).b,i=r.j,e=r.g,r.a.g){case 0:e.a=(n.g.b.o.a-i.a)/2;break;case 1:e.a=t.d.n.a+t.d.a.a;break;case 2:e.a=t.d.n.a+t.d.a.a-i.a;break;case 3:e.b=t.d.n.b+t.d.a.b}}function $On(n,t,e){var i,r,c;for(r=new Fz(ix(Ggn(e).a.Kc(),new h));hDn(r);)v9(i=uG(N9(r),18))||!v9(i)&&i.c.i.c==i.d.i.c||(c=aRn(n,i,e,new Ck)).c.length>1&&mv(t.c,c)}function DOn(n,t,e,i,r){if(ii&&(n.a=i),n.br&&(n.b=r),n}function xOn(n){if(F$(n,143))return dKn(uG(n,143));if(F$(n,233))return Mpn(uG(n,233));if(F$(n,23))return WIn(uG(n,23));throw hv(new vM(Aet+vIn(new IM(Uhn(cT(dat,1),EZn,1,5,[n])))))}function ROn(n,t,e,i,r){var c,a,o;for(c=!0,a=0;a>>r|e[a+i+1]<>>r,++a}return c}function KOn(n,t,e,i){var r,c;if(t.k==(zIn(),wbt))for(c=new Fz(ix(qgn(t).a.Kc(),new h));hDn(c);)if((r=uG(N9(c),18)).c.i.k==wbt&&n.c.a[r.c.i.c.p]==i&&n.c.a[t.c.p]==e)return!0;return!1}function FOn(n,t){var e,i,r,c;return t&=63,e=n.h&l0n,t<22?(c=e>>>t,r=n.m>>t|e<<22-t,i=n.l>>t|n.m<<22-t):t<44?(c=0,r=e>>>t-22,i=n.m>>t-22|n.h<<44-t):(c=0,r=0,i=e>>>t-44),p$(i&f0n,r&f0n,c&l0n)}function _On(n,t,e,i){var r;this.b=i,this.e=n==(ean(),BEt),r=t[e],this.d=Jq(ZHt,[zZn,B2n],[183,28],16,[r.length,r.length],2),this.a=Jq(YHt,[zZn,W1n],[53,28],15,[r.length,r.length],2),this.c=new IPn(t,e)}function BOn(n){var t,e,i;for(n.k=new L2((KQn(),Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt])).length,n.j.c.length),i=new Ww(n.j);i.a=e)return YOn(n,t,i.p),!0;return!1}function XOn(n,t,e,i){var r,c,a,o,u,s;for(a=e.length,c=0,r=-1,s=Tin((s3(t,n.length+1),n.substr(t)),(cB(),out)),o=0;oc&&IV(s,Tin(e[o],out))&&(r=o,c=u);return r>=0&&(i[0]=t+c),r}function zOn(n){var t;return 64&n.Db?rOn(n):(t=new lx(Ftt),!n.a||JA(JA((t.a+=' "',t),n.a),'"'),JA(Nj(JA(Nj(JA(Nj(JA(Nj((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function VOn(n,t,e){var i,r,c,a,o;for(o=VKn(n.e.Dh(),t),r=uG(n.g,124),i=0,a=0;ae?iLn(n,e,"start index"):t<0||t>e?iLn(t,e,"end index"):LBn("end index (%s) must not be less than start index (%s)",Uhn(cT(dat,1),EZn,1,5,[xwn(t),xwn(n)]))}function JOn(n,t){var e,i,r,c;for(i=0,r=n.length;i0&&nAn(n,c,e));t.p=0}function tAn(n){var t;this.c=new lS,this.f=n.e,this.e=n.d,this.i=n.g,this.d=n.c,this.b=n.b,this.k=n.j,this.a=n.a,n.i?this.j=n.i:this.j=new nB(t=uG(Mj(MNt),9),uG(MF(t,t.length),9),0),this.g=n.f}function eAn(n){var t,e,i,r;for(t=jQ(JA(new lx("Predicates."),"and"),40),e=!0,r=new Jw(n);r.b0?o[a-1]:Inn(pbt,e6n,10,0,0,1),r=o[a],s=a=0?n.ki(r):zLn(n,i)}else sdn(n,e,i)}function uAn(n){var t,e;if(e=null,t=!1,F$(n,211)&&(t=!0,e=uG(n,211).a),t||F$(n,263)&&(t=!0,e=""+uG(n,263).a),t||F$(n,493)&&(t=!0,e=""+uG(n,493).a),!t)throw hv(new pM(Cet));return e}function sAn(n,t,e){var i,r,c,a,o,u;for(u=VKn(n.e.Dh(),t),i=0,o=n.i,r=uG(n.g,124),a=0;a=n.d.b.c.length&&((t=new bQ(n.d)).p=i.p-1,kD(n.d.b,t),(e=new bQ(n.d)).p=i.p,kD(n.d.b,e)),a2(i,uG(zq(n.d.b,i.p),30))}function yAn(n,t,e){var i,r,c;if(!n.b[t.g]){for(n.b[t.g]=!0,!(i=e)&&(i=new L7),aq(i.b,t),c=n.a[t.g].Kc();c.Ob();)(r=uG(c.Pb(),65)).b!=t&&yAn(n,r.b,i),r.c!=t&&yAn(n,r.c,i),aq(i.a,r);return i}return null}function MAn(n){switch(n.g){case 0:case 1:case 2:return KQn(),yRt;case 3:case 4:case 5:return KQn(),KRt;case 6:case 7:case 8:return KQn(),_Rt;case 9:case 10:case 11:return KQn(),kRt;default:return KQn(),FRt}}function TAn(n,t){var e;return 0!=n.c.length&&(e=Imn((u3(0,n.c.length),uG(n.c[0],18)).c.i),n2(),e==(Yyn(),wjt)||e==bjt||o9(YJ(new fX(null,new h3(n,16)),new Kc),new up(t)))}function jAn(n,t){if(F$(t,207))return KN(n,uG(t,27));if(F$(t,193))return FN(n,uG(t,123));if(F$(t,452))return RN(n,uG(t,166));throw hv(new vM(Aet+vIn(new IM(Uhn(cT(dat,1),EZn,1,5,[t])))))}function EAn(n,t,e){var i,r;if(this.f=n,e7(e,r=(i=uG(cQ(n.b,t),260))?i.a:0),e>=(r/2|0))for(this.e=i?i.c:null,this.d=r;e++0;)Ein(this);this.b=t,this.a=null}function SAn(n,t){var e,i;t.a?WKn(n,t):(!!(e=uG(jS(n.b,t.b),60))&&e==n.a[t.b.f]&&!!e.a&&e.a!=t.b.a&&e.c.Fc(t.b),!!(i=uG(TS(n.b,t.b),60))&&n.a[i.f]==t.b&&!!i.a&&i.a!=t.b.a&&t.b.c.Fc(i),sD(n.b,t.b))}function PAn(n,t){var e,i;if(e=uG(AJ(n.b,t),127),uG(uG(Y9(n.r,t),21),87).dc())return e.n.b=0,void(e.n.c=0);e.n.b=n.C.b,e.n.c=n.C.c,n.A.Hc((Qmn(),JRt))&&vBn(n,t),i=Iyn(n,t),M_n(n,t)==(Vkn(),Zxt)&&(i+=2*n.w),e.a.a=i}function CAn(n,t){var e,i;if(e=uG(AJ(n.b,t),127),uG(uG(Y9(n.r,t),21),87).dc())return e.n.d=0,void(e.n.a=0);e.n.d=n.C.d,e.n.a=n.C.a,n.A.Hc((Qmn(),JRt))&&kBn(n,t),i=Cyn(n,t),M_n(n,t)==(Vkn(),Zxt)&&(i+=2*n.w),e.a.b=i}function IAn(n,t){var e,i,r,c;for(c=new Zm,i=new Ww(t);i.ai&&(s3(t-1,n.length),n.charCodeAt(t-1)<=32);)--t;return i>0||te.a&&(i.Hc((ZSn(),VNt))?r=(t.a-e.a)/2:i.Hc(QNt)&&(r=t.a-e.a)),t.b>e.b&&(i.Hc((ZSn(),YNt))?c=(t.b-e.b)/2:i.Hc(JNt)&&(c=t.b-e.b)),JCn(n,r,c)}function eLn(n,t,e,i,r,c,a,o,u,s,h,f,l){F$(n.Cb,90)&&yLn(y9(uG(n.Cb,90)),4),qon(n,e),n.f=a,Qdn(n,o),Ydn(n,u),Wdn(n,s),Jdn(n,h),mdn(n,f),Cgn(n,l),ddn(n,!0),Pcn(n,r),n.Zk(c),Kbn(n,t),null!=i&&(n.i=null,lon(n,i))}function iLn(n,t,e){if(n<0)return LBn(jZn,Uhn(cT(dat,1),EZn,1,5,[e,xwn(n)]));if(t<0)throw hv(new vM(SZn+t));return LBn("%s (%s) must not be greater than size (%s)",Uhn(cT(dat,1),EZn,1,5,[e,xwn(n),xwn(t)]))}function rLn(n,t,e,i,r,c){var a,o,u;if(i-e<7)Ygn(t,e,i,c);else if(rLn(t,n,o=e+r,u=o+((a=i+r)-o>>1),-r,c),rLn(t,n,u,a,-r,c),c.Ne(n[u-1],n[u])<=0)for(;e=0?n.bi(c,e):lRn(n,r,e)}else lpn(n,i,r,e)}function hLn(n){var t,e;if(n.f){for(;n.n>0;){if(F$(e=(t=uG(n.k.Xb(n.n-1),76)).Lk(),102)&&uG(e,19).Bb&Qtt&&(!n.e||e.pk()!=tFt||0!=e.Lj())&&null!=t.md())return!0;--n.n}return!1}return n.n>0}function fLn(n){var t,e,i,r;if(e=uG(n,54)._h())try{if(i=null,(t=jxn((MP(),l_t),xUn(jpn(e))))&&(r=t.ai())&&(i=r.Fl(bM(e.e))),i&&i!=n)return fLn(i)}catch(c){if(!F$(c=Ehn(c),63))throw hv(c)}return n}function lLn(n,t,e){var i,r;e.Ug("Remove overlaps",1),e.dh(t,l7n),i=uG(zDn(t,(SK(),zCt)),27),n.f=i,n.a=aMn(uG(zDn(t,(jOn(),zIt)),300)),rw(n,(tJ(r=pK(zDn(t,(XYn(),DDt)))),r)),xWn(n,t,GFn(i),e),e.dh(t,w7n)}function bLn(n){var t,e,i;if(oM(gK(zDn(n,(XYn(),C$t))))){for(i=new Zm,e=new Fz(ix(eRn(n).a.Kc(),new h));hDn(e);)BNn(t=uG(N9(e),74))&&oM(gK(zDn(t,I$t)))&&mv(i.c,t);return i}return hZ(),hZ(),zot}function wLn(n){if(!n)return By(),Vat;var t=n.valueOf?n.valueOf():n;if(t!==n){var i=Wat[typeof t];return i?i(t):Vbn(typeof t)}return n instanceof Array||n instanceof e.Array?new Eb(n):new Cb(n)}function dLn(n,t,i){var r,c,a;switch(a=n.o,(c=(r=uG(AJ(n.p,i),252)).i).b=gNn(r),c.a=dNn(r),c.b=e.Math.max(c.b,a.a),c.b>a.a&&!t&&(c.b=a.a),c.c=-(c.b-a.a)/2,i.g){case 1:c.d=-c.a;break;case 3:c.d=a.b}YGn(r),rqn(r)}function gLn(n,t,i){var r,c,a;switch(a=n.o,(c=(r=uG(AJ(n.p,i),252)).i).b=gNn(r),c.a=dNn(r),c.a=e.Math.max(c.a,a.b),c.a>a.b&&!t&&(c.a=a.b),c.d=-(c.a-a.b)/2,i.g){case 4:c.c=-c.b;break;case 2:c.c=a.a}YGn(r),rqn(r)}function pLn(n,t){var e,i,r,c,a;if(!t.dc())if(r=uG(t.Xb(0),131),1!=t.gc())for(e=1;e0)try{i=vUn(t,j1n,vZn)}catch(r){throw F$(r=Ehn(r),130)?hv(new Pen(r)):hv(r)}return!n.a&&(n.a=new qm(n)),i<(e=n.a).i&&i>=0?uG(zrn(e,i),58):null}function TLn(n,t){if(n<0)return LBn(jZn,Uhn(cT(dat,1),EZn,1,5,["index",xwn(n)]));if(t<0)throw hv(new vM(SZn+t));return LBn("%s (%s) must be less than size (%s)",Uhn(cT(dat,1),EZn,1,5,["index",xwn(n),xwn(t)]))}function jLn(n){var t,e,i,r,c;if(null==n)return IZn;for(c=new Ysn(TZn,"[","]"),i=0,r=(e=n).length;i=0?n.Lh(e,!0,!0):YNn(n,r,!0),160),uG(i,220).Zl(t)}function VLn(n){var t,i;return n>-0x800000000000&&n<0x800000000000?0==n?0:((t=n<0)&&(n=-n),i=t0(e.Math.floor(e.Math.log(n)/.6931471805599453)),(!t||n!=e.Math.pow(2,i))&&++i,i):dhn(Bsn(n))}function WLn(n){var t,e,i,r,c,a,o;for(c=new XL,e=new Ww(n);e.a2&&o.e.b+o.j.b<=2&&(r=o,i=a),c.a.zc(r,c),r.q=i);return c}function QLn(n,t,e){e.Ug("Eades radial",1),e.dh(t,w7n),n.d=uG(zDn(t,(SK(),zCt)),27),n.c=uM(pK(zDn(t,(jOn(),HIt)))),n.e=aMn(uG(zDn(t,zIt),300)),n.a=_pn(uG(zDn(t,WIt),434)),n.b=PSn(uG(zDn(t,KIt),354)),UEn(n),e.dh(t,w7n)}function JLn(n,t){if(t.Ug("Target Width Setter",1),!vnn(n,(S_n(),vAt)))throw hv(new jM("A target width has to be set if the TargetWidthWidthApproximator should be used."));Myn(n,(lBn(),POt),pK(zDn(n,vAt))),t.Vg()}function YLn(n,t){var e,i,r;return zsn(i=new gMn(n),t),kfn(i,(GYn(),Kpt),t),kfn(i,(jYn(),JMt),($Pn(),cRt)),kfn(i,byt,(nMn(),ONt)),Hb(i,(zIn(),lbt)),o2(e=new lOn,i),NLn(e,(KQn(),_Rt)),o2(r=new lOn,i),NLn(r,kRt),i}function ZLn(n){switch(n.g){case 0:return new zy((ean(),_Et));case 1:return new bl;case 2:return new wl;default:throw hv(new vM("No implementation is available for the crossing minimizer "+(null!=n.f?n.f:""+n.g)))}}function nNn(n,t){var e,i,r,c;for(n.c[t.p]=!0,kD(n.a,t),c=new Ww(t.j);c.a=(c=a.gc()))a.$b();else for(r=a.Kc(),i=0;i0?HM():c<0&&bNn(n,t,-c),!0)}function dNn(n){var t,e,i,r,c,a;if(a=0,0==n.b){for(t=0,r=0,c=(i=AMn(n,!0)).length;r0&&(a+=e,++t);t>1&&(a+=n.c*(t-1))}else a=fT(Mun(ZJ(JJ(BV(n.a),new jn),new En)));return a>0?a+n.n.d+n.n.a:0}function gNn(n){var t,e,i,r,c,a;if(a=0,0==n.b)a=fT(Mun(ZJ(JJ(BV(n.a),new Mn),new Tn)));else{for(t=0,r=0,c=(i=LMn(n,!0)).length;r0&&(a+=e,++t);t>1&&(a+=n.c*(t-1))}return a>0?a+n.n.b+n.n.c:0}function pNn(n){var t,e;if(2!=n.c.length)throw hv(new kM("Order only allowed for two paths."));u3(0,n.c.length),t=uG(n.c[0],18),u3(1,n.c.length),e=uG(n.c[1],18),t.d.i!=e.c.i&&(n.c.length=0,mv(n.c,e),mv(n.c,t))}function mNn(n,t,e){var i;for(vN(e,t.g,t.f),kN(e,t.i,t.j),i=0;i<(!t.a&&(t.a=new fV(bFt,t,10,11)),t.a).i;i++)mNn(n,uG(zrn((!t.a&&(t.a=new fV(bFt,t,10,11)),t.a),i),27),uG(zrn((!e.a&&(e.a=new fV(bFt,e,10,11)),e.a),i),27))}function vNn(n,t){var i,r,c,a;for(i=(a=uG(AJ(n.b,t),127)).a,c=uG(uG(Y9(n.r,t),21),87).Kc();c.Ob();)(r=uG(c.Pb(),117)).c&&(i.a=e.Math.max(i.a,rq(r.c)));if(i.a>0)switch(t.g){case 2:a.n.c=n.s;break;case 4:a.n.b=n.s}}function kNn(n,t){var e,i,r;return 0==(e=uG(oIn(t,(cGn(),$ft)),17).a-uG(oIn(n,$ft),17).a)?(i=YF(D$(uG(oIn(n,(mon(),zft)),8)),uG(oIn(n,Vft),8)),r=YF(D$(uG(oIn(t,zft),8)),uG(oIn(t,Vft),8)),ugn(i.a*i.b,r.a*r.b)):e}function yNn(n,t){var e,i,r;return 0==(e=uG(oIn(t,(QGn(),yCt)),17).a-uG(oIn(n,yCt),17).a)?(i=YF(D$(uG(oIn(n,(OQn(),vPt)),8)),uG(oIn(n,kPt),8)),r=YF(D$(uG(oIn(t,vPt),8)),uG(oIn(t,kPt),8)),ugn(i.a*i.b,r.a*r.b)):e}function MNn(n){var t,e;return(e=new WM).a+="e_",null!=(t=bhn(n))&&(e.a+=""+t),n.c&&n.d&&(JA((e.a+=" ",e),njn(n.c)),JA(QA((e.a+="[",e),n.c.i),"]"),JA((e.a+=Y4n,e),njn(n.d)),JA(QA((e.a+="[",e),n.d.i),"]")),e.a}function TNn(n){switch(n.g){case 0:return new Tl;case 1:return new jl;case 2:return new yl;case 3:return new kl;default:throw hv(new vM("No implementation is available for the layout phase "+(null!=n.f?n.f:""+n.g)))}}function jNn(n,t,i,r,c){var a;switch(a=0,c.g){case 1:a=e.Math.max(0,t.b+n.b-(i.b+r));break;case 3:a=e.Math.max(0,-n.b-r);break;case 2:a=e.Math.max(0,-n.a-r);break;case 4:a=e.Math.max(0,t.a+n.a-(i.a+r))}return a}function ENn(n,t,e){var i,r,c;if(e)for(c=((i=new Gz(e.a.length)).b-i.a)*i.c<0?(CP(),XHt):new xD(i);c.Ob();)r=v6(e,uG(c.Pb(),17).a),vet in r.a||ket in r.a?bHn(n,r,t):JJn(n,r,t),GD(uG(cQ(n.b,jvn(r)),74))}function SNn(n){var t,e;switch(n.b){case-1:return!0;case 0:return(e=n.t)>1||-1==e||(t=bEn(n))&&(PP(),t.lk()==srt)?(n.b=-1,!0):(n.b=1,!1);default:return!1}}function PNn(n,t){var e,i,r,c;if(EYn(n),0!=n.c||123!=n.a)throw hv(new CM(rZn((t$(),bit))));if(c=112==t,i=n.d,(e=aR(n.i,125,i))<0)throw hv(new CM(rZn((t$(),wit))));return r=r1(n.i,i,e),n.d=e+1,itn(r,c,!(512&~n.e))}function CNn(n){var t,e,i,r,c,a,o;if((i=n.a.c.length)>0)for(a=n.c.d,r=vD(YF(new MO((o=n.d.d).a,o.b),a),1/(i+1)),c=new MO(a.a,a.b),e=new Ww(n.a);e.a=0&&i=0?n.Lh(e,!0,!0):YNn(n,r,!0),160),uG(i,220).Wl(t);throw hv(new vM(Gtt+t.xe()+ztt))}function DNn(){var n;return IP(),pBt?uG(jxn((MP(),l_t),Drt),2038):(ML(Sat,new Eh),yWn(),n=uG(F$(U1((MP(),l_t),Drt),560)?U1(l_t,Drt):new dJ,560),pBt=!0,HYn(n),oZn(n),vJ((pP(),k_t),n,new Bs),r2(l_t,Drt,n),n)}function xNn(n,t){var e,i,r,c;n.j=-1,uN(n.e)?(e=n.i,c=0!=n.i,z9(n,t),i=new Ken(n.e,3,n.c,null,t,e,c),r=t.zl(n.e,n.c,null),(r=yPn(n,t,r))?(r.nj(i),r.oj()):Msn(n.e,i)):(z9(n,t),(r=t.zl(n.e,n.c,null))&&r.oj())}function RNn(n,t){var e,i,r;if(r=0,(i=t[0])>=n.length)return-1;for(s3(i,n.length),e=n.charCodeAt(i);e>=48&&e<=57&&(r=10*r+(e-48),!(++i>=n.length));)s3(i,n.length),e=n.charCodeAt(i);return i>t[0]?t[0]=i:r=-1,r}function KNn(n){var t,i,r,c,a;return i=c=uG(n.a,17).a,r=a=uG(n.b,17).a,t=e.Math.max(e.Math.abs(c),e.Math.abs(a)),c<=0&&c==a?(i=0,r=a-1):c==-t&&a!=t?(i=a,r=c,a>=0&&++i):(i=-a,r=c),new WO(xwn(i),xwn(r))}function FNn(n,t,e,i){var r,c,a,o,u,s;for(r=0;r=0&&s>=0&&u=n.i)throw hv(new dM(zet+t+Vet+n.i));if(e>=n.i)throw hv(new dM(Wet+e+Vet+n.i));return i=n.g[e],t!=e&&(t>16))>>16&16),e+=t=(i=(n>>=t)-256)>>16&8,e+=t=(i=(n<<=t)-j0n)>>16&4,(e+=t=(i=(n<<=t)-VZn)>>16&2)+2-(t=(i=(n<<=t)>>14)&~(i>>1)))}function qNn(n){var t,e,i,r;for(lZ(),aft=new Zm,cft=new Ym,rft=new Zm,!n.a&&(n.a=new fV(bFt,n,10,11)),JQn(t=n.a),r=new DD(t);r.e!=r.i.gc();)i=uG(Zkn(r),27),-1==Ten(aft,i,0)&&(e=new Zm,kD(rft,e),skn(i,e));return rft}function XNn(n,t,e){var i,r,c,a;n.a=e.b.d,F$(t,326)?(z8(c=COn(r=JFn(uG(t,74),!1,!1)),i=new Kd(n)),sqn(c,r),null!=t.of((XYn(),L$t))&&z8(uG(t.of(L$t),75),i)):((a=uG(t,422)).rh(a.nh()+n.a.a),a.sh(a.oh()+n.a.b))}function zNn(n,t){var e,i,r;for(r=new Zm,i=Fkn(t.a,0);i.b!=i.d.c;)(e=uG(I6(i),65)).c.g==n.g&&xA(oIn(e.b,(QGn(),ACt)))!==xA(oIn(e.c,ACt))&&!o9(new fX(null,new h3(r,16)),new kp(e))&&mv(r.c,e);return f$(r,new ja),r}function VNn(n,t,e){var i,r,c,a;return F$(t,153)&&F$(e,153)?(c=uG(t,153),a=uG(e,153),n.a[c.a][a.a]+n.a[a.a][c.a]):F$(t,250)&&F$(e,250)&&(i=uG(t,250),r=uG(e,250),i.a==r.a)?uG(oIn(r.a,(cGn(),$ft)),17).a:0}function WNn(n,t){var i,r,c,a,o,u,s,h;for(h=uM(pK(oIn(t,(jYn(),ITt)))),s=n[0].n.a+n[0].o.a+n[0].d.c+h,u=1;u=0?e:(o=NQ(YF(new MO(a.c+a.b/2,a.d+a.a/2),new MO(c.c+c.b/2,c.d+c.a/2))),-(oGn(c,a)-1)*o)}function JNn(n,t,e){var i;kS(new fX(null,(!e.a&&(e.a=new fV(oFt,e,6,6)),new h3(e.a,16))),new zO(n,t)),kS(new fX(null,(!e.n&&(e.n=new fV(lFt,e,1,7)),new h3(e.n,16))),new VO(n,t)),(i=uG(zDn(e,(XYn(),L$t)),75))&&fun(i,n,t)}function YNn(n,t,e){var i,r,c;if(c=iVn((gAn(),kBt),n.Dh(),t))return PP(),uG(c,69).xk()||(c=_3(Nen(kBt,c))),r=uG((i=n.Ih(c))>=0?n.Lh(i,!0,!0):YNn(n,c,!0),160),uG(r,220).Sl(t,e);throw hv(new vM(Gtt+t.xe()+ztt))}function ZNn(n,t,e,i){var r,c,a,o,u;if(r=n.d[t])if(c=r.g,u=r.i,null!=i){for(o=0;o=e&&(i=t,c=(u=(o.c+o.a)/2)-e,o.c<=u-e&&GX(n,i++,new OU(o.c,c)),(a=u+e)<=o.a&&(r=new OU(a,o.a),o3(i,n.c.length),pC(n.c,i,r)))}function o$n(n,t,e){var i,r,c,a;if(!t.dc()){for(i=new lS,a=t.Kc();a.Ob();)for(c=uG(a.Pb(),40),vJ(n.a,xwn(c.g),xwn(e)),r=new Tp(Fkn(new Mp(c).a.d,0));Jj(r.a);)s8(i,uG(I6(r.a),65).c,i.c.b,i.c);o$n(n,i,e+1)}}function u$n(n){var t;if(n.c||null!=n.g){if(null==n.g)return!0;if(0==n.i)return!1;t=uG(n.g[n.i-1],51)}else n.d=n.bj(n.f),ttn(n,n.d),t=n.d;return t==n.b&&null.Vm>=null.Um()?(Wxn(n),u$n(n)):t.Ob()}function s$n(n){if(this.a=n,n.c.i.k==(zIn(),lbt))this.c=n.c,this.d=uG(oIn(n.c.i,(GYn(),Fpt)),64);else{if(n.d.i.k!=lbt)throw hv(new vM("Edge "+n+" is not an external edge."));this.c=n.d,this.d=uG(oIn(n.d.i,(GYn(),Fpt)),64)}}function h$n(n,t){var e,i,r;r=n.b,n.b=t,4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,3,r,n.b)),t?t!=n&&(qon(n,t.zb),Icn(n,t.d),Uan(n,null==(e=null==(i=t.c)?t.zb:i)||m_(e,t.zb)?null:e)):(qon(n,null),Icn(n,0),Uan(n,null))}function f$n(n,t){var e;this.e=(ZW(),WW(n),ZW(),Emn(n)),this.c=(WW(t),Emn(t)),FD(this.e.Rd().dc()==this.c.Rd().dc()),this.d=Qgn(this.e),this.b=Qgn(this.c),e=Jq(dat,[zZn,EZn],[5,1],5,[this.e.Rd().gc(),this.c.Rd().gc()],2),this.a=e,wan(this)}function l$n(n){var t=(!Rat&&(Rat=mJn()),Rat);return'"'+n.replace(/[\x00-\x1f\xad\u0600-\u0603\u06dd\u070f\u17b4\u17b5\u200b-\u200f\u2028-\u202e\u2060-\u2064\u206a-\u206f\ufeff\ufff9-\ufffb"\\]/g,(function(n){return z1(n,t)}))+'"'}function b$n(n,t,i,r,c,a){var o,u,s,h,f;if(0!=c)for(xA(n)===xA(i)&&(n=n.slice(t,t+c),t=0),s=i,u=t,h=t+c;u=(a=null==(e=uG(Lsn(n.a,4),129))?0:e.length))throw hv(new w_(t,a));return r=e[t],1==a?i=null:(qGn(e,0,i=Inn(xFt,Uit,424,a-1,0,1),0,t),(c=a-t-1)>0&&qGn(e,t+1,i,t,c)),Pkn(n,i),GAn(n,t,r),r}function p$n(n){var t,e;if(n.f){for(;n.n0?Ipn(e):Gdn(Ipn(e)),Myn(t,eTt,r)}function M$n(n,t){t.Ug("Partition preprocessing",1),kS(uG(l8(JJ(sin(JJ(new fX(null,new h3(n.a,16)),new mi),new vi),new ki),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15).Oc(),new yi),t.Vg()}function T$n(n,t){var e,i,r,c,a;for(a=n.j,t.a!=t.b&&f$(a,new Yr),r=a.c.length/2|0,i=0;i0&&sHn(n,e,t),c):null!=i.a?(sHn(n,t,e),-1):null!=r.a?(sHn(n,e,t),1):0}function E$n(n,t){var e,i,r,c,a;for(r=t.b.b,n.a=Inn(yat,H3n,15,r,0,1),n.b=Inn(ZHt,B2n,28,r,16,1),a=Fkn(t.b,0);a.b!=a.d.c;)c=uG(I6(a),40),n.a[c.g]=new lS;for(i=Fkn(t.a,0);i.b!=i.d.c;)e=uG(I6(i),65),n.a[e.b.g].Fc(e),n.a[e.c.g].Fc(e)}function S$n(n,t){var e,i,r,c;n.Pj()?(e=n.Ej(),c=n.Qj(),++n.j,n.qj(e,n.Zi(e,t)),i=n.Ij(3,null,t,e,c),n.Mj()&&(r=n.Nj(t,null))?(r.nj(i),r.oj()):n.Jj(i)):(vQ(n,t),n.Mj()&&(r=n.Nj(t,null))&&r.oj())}function P$n(n,t,e){var i,r,c;n.Pj()?(c=n.Qj(),edn(n,t,e),i=n.Ij(3,null,e,t,c),n.Mj()?(r=n.Nj(e,null),n.Tj()&&(r=n.Uj(e,r)),r?(r.nj(i),r.oj()):n.Jj(i)):n.Jj(i)):(edn(n,t,e),n.Mj()&&(r=n.Nj(e,null))&&r.oj())}function C$n(n,t){var e,i,r,c,a;for(a=VKn(n.e.Dh(),t),r=new ls,e=uG(n.g,124),c=n.i;--c>=0;)i=e[c],a.am(i.Lk())&&ttn(r,i);!PJn(n,r)&&uN(n.e)&&Yv(n,t.Jk()?VZ(n,6,t,(hZ(),zot),null,-1,!1):VZ(n,t.tk()?2:1,t,null,null,-1,!1))}function I$n(n,t){var e,i,r,c;return n.a==(RIn(),Vgt)||(r=t.a.c,e=t.a.c+t.a.b,!(t.j&&(c=(i=t.A).c.c.a-i.o.a/2,r-(i.n.a+i.o.a)>c)||t.q&&(c=(i=t.C).c.c.a-i.o.a/2,i.n.a-e>c)))}function O$n(n){var t,e,i,r,c,a;for(e2(),e=new u8,i=new Ww(n.e.b);i.a1?n.e*=uM(n.a):n.f/=uM(n.a),_bn(n),Vvn(n),EBn(n),kfn(n.b,(ryn(),Qht),n.g)}function x$n(n,t,e){var i,r,c,a,o;for(i=0,o=e,t||(i=e*(n.c.length-1),o*=-1),c=new Ww(n);c.a=0?n.Ah(null):n.Ph().Th(n,-1-t,null,null),n.Bh(uG(r,54),e),i&&i.oj(),n.vh()&&n.wh()&&e>-1&&Msn(n,new lV(n,9,e,c,r)),r):c}function Y$n(n,t){var e,i,r,c,a;for(c=n.b.Ce(t),i=null==(e=n.a.get(c))?Inn(dat,EZn,1,0,5,1):e,a=0;a>5)>=n.d)return n.e<0;if(e=n.a[r],t=1<<(31&t),n.e<0){if(r<(i=_un(n)))return!1;e=i==r?-e:~e}return!!(e&t)}function oDn(n,t,e,i){var r;uG(e.b,68),uG(e.b,68),uG(i.b,68),uG(i.b,68),RG(r=YF(D$(uG(e.b,68).c),uG(i.b,68).c),LLn(uG(e.b,68),uG(i.b,68),r)),uG(i.b,68),uG(i.b,68),uG(i.b,68).c.a,r.a,uG(i.b,68).c.b,r.b,uG(i.b,68),Prn(i.a,new $U(n,t,i))}function uDn(n,t){var e,i,r,c,a,o,u;if(c=t.e)for(e=J$n(c),i=uG(n.g,689),a=0;a>16)),15).dd(c))0&&((!hN(n.a.c)||!t.n.d)&&(!fN(n.a.c)||!t.n.b)&&(t.g.d+=e.Math.max(0,r/2-.5)),(!hN(n.a.c)||!t.n.a)&&(!fN(n.a.c)||!t.n.c)&&(t.g.a-=r-1))}function bDn(n){var t,i,r,c,a;if(a=VUn(n,c=new Zm),t=uG(oIn(n,(GYn(),lmt)),10))for(r=new Ww(t.j);r.a>t,c=n.m>>t|e<<22-t,r=n.l>>t|n.m<<22-t):t<44?(a=i?l0n:0,c=e>>t-22,r=n.m>>t-22|e<<44-t):(a=i?l0n:0,c=i?f0n:0,r=e>>t-44),p$(r&f0n,c&f0n,a&l0n)}function pDn(n){var t,i,r,c,a,o;for(this.c=new Zm,this.d=n,r=M0n,c=M0n,t=T0n,i=T0n,o=Fkn(n,0);o.b!=o.d.c;)a=uG(I6(o),8),r=e.Math.min(r,a.a),c=e.Math.min(c,a.b),t=e.Math.max(t,a.a),i=e.Math.max(i,a.b);this.a=new gY(r,c,t-r,i-c)}function mDn(n,t){var e,i,r,c;for(i=new Ww(n.b);i.a0&&F$(t,44)&&(n.a._j(),c=null==(u=(s=uG(t,44)).ld())?0:Hon(u),a=iF(n.a,c),e=n.a.d[a]))for(i=uG(e.g,379),h=e.i,o=0;o=2)for(t=pK((i=c.Kc()).Pb());i.Ob();)a=t,t=pK(i.Pb()),r=e.Math.min(r,(tJ(t),t-(tJ(a),a)));return r}function xDn(n,t){var e,i,r;for(r=new Zm,i=Fkn(t.a,0);i.b!=i.d.c;)(e=uG(I6(i),65)).b.g==n.g&&!m_(e.b.c,H9n)&&xA(oIn(e.b,(QGn(),ACt)))!==xA(oIn(e.c,ACt))&&!o9(new fX(null,new h3(r,16)),new yp(e))&&mv(r.c,e);return f$(r,new Ca),r}function RDn(n,t){var e,i,r;if(xA(t)===xA(WW(n)))return!0;if(!F$(t,15))return!1;if(i=uG(t,15),(r=n.gc())!=i.gc())return!1;if(F$(i,59)){for(e=0;e0&&(r=e),a=new Ww(n.f.e);a.a0?(t-=1,e-=1):i>=0&&r<0?(t+=1,e+=1):i>0&&r>=0?(t-=1,e+=1):(t+=1,e-=1),new WO(xwn(t),xwn(e))}function exn(n,t){return n.ct.c?1:n.bt.b?1:n.a!=t.a?Hon(n.a)-Hon(t.a):n.d==(Z6(),YEt)&&t.d==JEt?-1:n.d==JEt&&t.d==YEt?1:0}function ixn(n,t){var e,i,r,c,a;return a=(c=t.a).c.i==t.b?c.d:c.c,i=c.c.i==t.b?c.c:c.d,(r=dmn(n.a,a,i))>0&&r0):r<0&&-r0)}function rxn(n,t,e,i){var r,c,a,o,u,s;for(r=(t-n.d)/n.c.c.length,c=0,n.a+=e,n.d=t,s=new Ww(n.c);s.a>24;return a}function axn(n){if(n.ze()){var t=n.c;return t.Ae()?n.o="["+t.n:t.ze()?n.o="["+t.xe():n.o="[L"+t.xe()+";",n.b=t.we()+"[]",void(n.k=t.ye()+"[]")}var e=n.j,i=n.d;i=i.split("/"),n.o=fvn(".",[e,fvn("$",i)]),n.b=fvn(".",[e,fvn(".",i)]),n.k=i[i.length-1]}function oxn(n,t){var e,i,r,c,a;for(a=null,c=new Ww(n.e.a);c.a=0;t-=2)for(e=0;e<=t;e+=2)(n.b[e]>n.b[e+2]||n.b[e]===n.b[e+2]&&n.b[e+1]>n.b[e+3])&&(i=n.b[e+2],n.b[e+2]=n.b[e],n.b[e]=i,i=n.b[e+3],n.b[e+3]=n.b[e+1],n.b[e+1]=i);n.c=!0}}function mxn(n,t){var e,i,r,c,a,o,u,s,h;for(s=-1,h=0,o=0,u=(a=n).length;o0&&++h;++s}return h}function vxn(n){var t;return(t=new lx(Ij(n.Rm))).a+="@",JA(t,(Hon(n)>>>0).toString(16)),n.Vh()?(t.a+=" (eProxyURI: ",QA(t,n._h()),n.Kh()&&(t.a+=" eClass: ",QA(t,n.Kh())),t.a+=")"):n.Kh()&&(t.a+=" (eClass: ",QA(t,n.Kh()),t.a+=")"),t.a}function kxn(n){var t,e,i;if(n.e)throw hv(new kM((vK(Qut),v2n+Qut.k+k2n)));for(n.d==(xdn(),ZDt)&&GWn(n,JDt),e=new Ww(n.a.a);e.a>24}return e}function Sxn(n,t,e){var i,r,c;if(!(r=uG(AJ(n.i,t),314)))if(r=new Yin(n.d,t,e),UV(n.i,t,r),vvn(t))iD(n.a,t.c,t.b,r);else switch(c=MAn(t),i=uG(AJ(n.p,c),252),c.g){case 1:case 3:r.j=!0,nM(i,t.b,r);break;case 4:case 2:r.k=!0,nM(i,t.c,r)}return r}function Pxn(n,t){var e,i,r,c,a,o,u,s,h;for(u=iR(n.c-n.b&n.a.length-1),s=null,h=null,c=new XJ(n);c.a!=c.b;)r=uG(rwn(c),10),e=(o=uG(oIn(r,(GYn(),Zpt)),12))?o.i:null,i=(a=uG(oIn(r,nmt),12))?a.i:null,s==e&&h==i||(F$n(u,t),s=e,h=i),mv(u.c,r);F$n(u,t)}function Cxn(n,t,e,i){var r,c,a,o,u,s;if(o=new ls,u=VKn(n.e.Dh(),t),r=uG(n.g,124),PP(),uG(t,69).xk())for(a=0;a=0)return r;for(c=1,a=new Ww(t.j);a.a=0)return r;for(c=1,a=new Ww(t.j);a.a0&&t.Ne((u3(r-1,n.c.length),uG(n.c[r-1],10)),c)>0;)Y8(n,r,(u3(r-1,n.c.length),uG(n.c[r-1],10))),--r;u3(r,n.c.length),n.c[r]=c}e.a=new Ym,e.b=new Ym}function Lxn(n,t,e){var i,r,c,a,o,u,s;for(s=new nB(i=uG(t.e&&t.e(),9),uG(MF(i,i.length),9),0),a=0,o=(c=WGn(e,"[\\[\\]\\s,]+")).length;a=0?(t||(t=new VM,i>0&&VA(t,(Knn(0,i,n.length),n.substr(0,i)))),t.a+="\\",TQ(t,e&D1n)):t&&TQ(t,e&D1n);return t?t.a:n}function $xn(n){var t,i,r;for(i=new Ww(n.a.a.b);i.a0&&((!hN(n.a.c)||!t.n.d)&&(!fN(n.a.c)||!t.n.b)&&(t.g.d-=e.Math.max(0,r/2-.5)),(!hN(n.a.c)||!t.n.a)&&(!fN(n.a.c)||!t.n.c)&&(t.g.a+=e.Math.max(0,r-1)))}function Dxn(n,t,e){var i;if(2==(n.c-n.b&n.a.length-1))t==(KQn(),yRt)||t==kRt?(prn(uG(Rfn(n),15),(Ajn(),$xt)),prn(uG(Rfn(n),15),Dxt)):(prn(uG(Rfn(n),15),(Ajn(),Dxt)),prn(uG(Rfn(n),15),$xt));else for(i=new XJ(n);i.a!=i.b;)prn(uG(rwn(i),15),e)}function xxn(n,t){var e,i,r,c,a,o;for(a=new N4(i=rG(new Pm(n)),i.c.length),o=new N4(r=rG(new Pm(t)),r.c.length),c=null;a.b>0&&o.b>0&&(MK(a.b>0),e=uG(a.a.Xb(a.c=--a.b),27),MK(o.b>0),e==uG(o.a.Xb(o.c=--o.b),27));)c=e;return c}function Rxn(n,t,e){var i,r,c,a;Y3(n,t)>Y3(n,e)?(i=Dgn(e,(KQn(),kRt)),n.d=i.dc()?0:dq(uG(i.Xb(0),12)),a=Dgn(t,_Rt),n.b=a.dc()?0:dq(uG(a.Xb(0),12))):(r=Dgn(e,(KQn(),_Rt)),n.d=r.dc()?0:dq(uG(r.Xb(0),12)),c=Dgn(t,kRt),n.b=c.dc()?0:dq(uG(c.Xb(0),12)))}function Kxn(n,t){var e,i,r,c;for(e=n.o.a,c=uG(uG(Y9(n.r,t),21),87).Kc();c.Ob();)(r=uG(c.Pb(),117)).e.a=e*uM(pK(r.b.of(bht))),r.e.b=(i=r.b).pf((XYn(),uDt))?i.ag()==(KQn(),yRt)?-i.Mf().b-uM(pK(i.of(uDt))):uM(pK(i.of(uDt))):i.ag()==(KQn(),yRt)?-i.Mf().b:0}function Fxn(n,t){var e,i,r,c;for(t.Ug("Self-Loop pre-processing",1),i=new Ww(n.a);i.an.c));a++)r.a>=n.s&&(c<0&&(c=a),o=a);return u=(n.s+n.c)/2,c>=0&&(u=wP((u3(i=fHn(n,t,c,o),t.c.length),uG(t.c[i],339))),a$n(t,i,e)),u}function Hxn(n,t,e){var i,r,c,a,o;for(Yan(r=new vs,(tJ(t),t)),!r.b&&(r.b=new XR((YYn(),H_t),wBt,r)),o=r.b,a=1;a0&&tVn(this,r)}function Gxn(n,t,e,i,r,c){var a,o,u;if(!r[t.a]){for(r[t.a]=!0,!(a=i)&&(a=new d7),kD(a.e,t),u=c[t.a].Kc();u.Ob();)(o=uG(u.Pb(),290)).d!=e&&o.c!=e&&(o.c!=t&&Gxn(n,o.c,t,a,r,c),o.d!=t&&Gxn(n,o.d,t,a,r,c),kD(a.c,o),Ohn(a.d,o.b));return a}return null}function qxn(n){var t,e,i;for(t=0,e=new Ww(n.e);e.a=2}function Xxn(n,t,e,i,r){var c,a,o,u,s;for(c=n.c.d.j,a=uG(hyn(e,0),8),s=1;s1||qsn(X1(WX(Bxt,Uhn(cT(eRt,1),p1n,95,0,[_xt,Uxt])),n))>1||qsn(X1(WX(Vxt,Uhn(cT(eRt,1),p1n,95,0,[zxt,Xxt])),n))>1)}function Vxn(n,t,e){var i,r,c;for(c=new Ww(n.t);c.a0&&(i.b.n-=i.c,i.b.n<=0&&i.b.u>0&&aq(t,i.b));for(r=new Ww(n.i);r.a0&&(i.a.u-=i.c,i.a.u<=0&&i.a.n>0&&aq(e,i.a))}function Wxn(n){var t,e,i;if(null==n.g&&(n.d=n.bj(n.f),ttn(n,n.d),n.c))return n.f;if(i=(t=uG(n.g[n.i-1],51)).Pb(),n.e=t,(e=n.bj(i)).Ob())n.d=e,ttn(n,e);else for(n.d=null;!t.Ob()&&(uQ(n.g,--n.i,null),0!=n.i);)t=uG(n.g[n.i-1],51);return i}function Qxn(n,t){var e,i,r,c,a,o;if(r=(i=t).Lk(),EFn(n.e,r)){if(r.Si()&&H5(n,r,i.md()))return!1}else for(o=VKn(n.e.Dh(),r),e=uG(n.g,124),c=0;c1||e>1)return 2;return t+e==1?2:0}function uRn(n,t){var i,r,c,a;return c=n.a*X0n+1502*n.b,a=n.b*X0n+11,c+=i=e.Math.floor(a*z0n),a-=i*V0n,c%=V0n,n.a=c,n.b=a,t<=24?e.Math.floor(n.a*but[t]):((r=n.a*(1<=2147483648&&(r-=4294967296),r)}function sRn(n,t,e){var i,r,c,a,o,u,s;for(c=new Zm,Uqn(n,s=new lS,a=new lS,t),RVn(n,s,a,t,e),u=new Ww(n);u.ai.b.g&&mv(c.c,i);return c}function hRn(n,t,e){var i,r,c,a,o;for(a=n.c,c=(e.q?e.q:(hZ(),hZ(),Vot)).vc().Kc();c.Ob();)r=uG(c.Pb(),44),!Qj(JJ(new fX(null,new h3(a,16)),new hd(new kO(t,r)))).Bd((vS(),Kut))&&(F$(o=r.md(),4)&&null!=(i=Nvn(o))&&(o=i),t.qf(uG(r.ld(),149),o))}function fRn(n,t,e){var i;if(_J(n.b),JV(n.b,(Rdn(),HAt),(eP(),GLt)),JV(n.b,UAt,t.g),JV(n.b,GAt,t.a),n.a=Qzn(n.b,t),e.Ug("Compaction by shrinking a tree",n.a.c.length),t.i.c.length>1)for(i=new Ww(n.a);i.a=0?n.Lh(i,!0,!0):YNn(n,c,!0),160),uG(r,220).Xl(t,e)}function bRn(n,t){var e,i,r,c;if(t){for(c=!(r=F$(n.Cb,90)||F$(n.Cb,102))&&F$(n.Cb,331),e=new DD((!t.a&&(t.a=new AX(t,g_t,t)),t.a));e.e!=e.i.gc();)if(i=MGn(uG(Zkn(e),89)),r?F$(i,90):c?F$(i,156):i)return i;return r?(YYn(),x_t):(YYn(),N_t)}return null}function wRn(n,t){var e,i,r;for(t.Ug("Resize child graph to fit parent.",1),i=new Ww(n.b);i.a=2*t&&kD(e,new OU(a[i-1]+t,a[i]-t));return e}function pRn(n,t,e){var i,r,c,a,o;if(e)for(c=((i=new Gz(e.a.length)).b-i.a)*i.c<0?(CP(),XHt):new xD(i);c.Ob();)(r=v6(e,uG(c.Pb(),17).a))&&(Gan(a=b5(n,(gj(),o=new Hk,!!t&&LRn(o,t),o),r),k6(r,Iet)),fCn(r,a),kLn(r,a),qfn(n,r,a))}function mRn(n){var t,e,i,r;if(!n.j){if(r=new Ss,null==(t=V_t).a.zc(n,t)){for(i=new DD(n1(n));i.e!=i.i.gc();)CW(r,mRn(e=uG(Zkn(i),29))),ttn(r,e);t.a.Bc(n)}lbn(r),n.j=new vL((uG(zrn(gZ((tQ(),M_t).o),11),19),r.i),r.g),y9(n).b&=-33}return n.j}function vRn(n){var t,e,i,r;if(null==n)return null;if(i=yXn(n,!0),r=yct.length,m_(i.substr(i.length-r,r),yct))if(4==(e=i.length)){if(s3(0,i.length),43==(t=i.charCodeAt(0)))return fHt;if(45==t)return hHt}else if(3==e)return fHt;return new tk(i)}function kRn(n){var t,e,i;return(e=n.l)&e-1||(i=n.m)&i-1||(t=n.h)&t-1||0==t&&0==i&&0==e?-1:0==t&&0==i&&0!=e?pan(e):0==t&&0!=i&&0==e?pan(i)+22:0!=t&&0==i&&0==e?pan(t)+44:-1}function yRn(n,t){var e,i,r,c,a;for(r=t.a&n.f,c=null,i=n.b[r];;i=i.b){if(i==t){c?c.b=t.b:n.b[r]=t.b;break}c=i}for(a=t.f&n.f,c=null,e=n.c[a];;e=e.d){if(e==t){c?c.d=t.d:n.c[a]=t.d;break}c=e}t.e?t.e.c=t.c:n.a=t.c,t.c?t.c.e=t.e:n.e=t.e,--n.i,++n.g}function MRn(n,t){var e;t.d?t.d.b=t.b:n.a=t.b,t.b?t.b.d=t.d:n.e=t.d,t.e||t.c?(--(e=uG(nJ(uG(cQ(n.b,t.a),260)),260)).a,t.e?t.e.c=t.c:e.b=uG(nJ(t.c),511),t.c?t.c.e=t.e:e.c=uG(nJ(t.e),511)):((e=uG(nJ(uG(u7(n.b,t.a),260)),260)).a=0,++n.c),--n.d}function TRn(n){var t,i,r,c,a,o,u,s,h,f;for(i=n.o,t=n.p,o=vZn,c=j1n,u=vZn,a=j1n,h=0;h0),c.a.Xb(c.c=--c.b),pF(c,r),MK(c.b3&&Fen(n,0,t-3))}function CRn(n){var t,e,i,r;return xA(oIn(n,(jYn(),rMt)))===xA((Own(),Ixt))?!n.e&&xA(oIn(n,Oyt))!==xA((ihn(),hpt)):(i=uG(oIn(n,Ayt),299),r=oM(gK(oIn(n,Ryt)))||xA(oIn(n,Kyt))===xA((jan(),Ydt)),t=uG(oIn(n,Iyt),17).a,e=n.a.c.length,!r&&i!=(ihn(),hpt)&&(0==t||t>e))}function IRn(n){var t,e;for(e=0;e0);e++);if(e>0&&e0);t++);return t>0&&e>16!=6&&t){if(eEn(n,t))throw hv(new vM(net+A$n(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?zjn(n,i):n.Cb.Th(n,-1-e,null,i)),t&&(i=kyn(t,n,6,i)),(i=ZK(n,t,i))&&i.oj()}else 4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,6,t,t))}function ARn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=3&&t){if(eEn(n,t))throw hv(new vM(net+SXn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?sEn(n,i):n.Cb.Th(n,-1-e,null,i)),t&&(i=kyn(t,n,12,i)),(i=nF(n,t,i))&&i.oj()}else 4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,3,t,t))}function LRn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=9&&t){if(eEn(n,t))throw hv(new vM(net+VBn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Wjn(n,i):n.Cb.Th(n,-1-e,null,i)),t&&(i=kyn(t,n,9,i)),(i=tF(n,t,i))&&i.oj()}else 4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,9,t,t))}function NRn(n){var t,e,i,r,c;if(i=bEn(n),null==(c=n.j)&&i)return n.Jk()?null:i.ik();if(F$(i,156)){if((e=i.jk())&&(r=e.wi())!=n.i){if((t=uG(i,156)).nk())try{n.g=r.ti(t,c)}catch(a){if(!F$(a=Ehn(a),82))throw hv(a);n.g=null}n.i=r}return n.g}return null}function $Rn(n){var t;return kD(t=new Zm,new ZP(new MO(n.c,n.d),new MO(n.c+n.b,n.d))),kD(t,new ZP(new MO(n.c,n.d),new MO(n.c,n.d+n.a))),kD(t,new ZP(new MO(n.c+n.b,n.d+n.a),new MO(n.c+n.b,n.d))),kD(t,new ZP(new MO(n.c+n.b,n.d+n.a),new MO(n.c,n.d+n.a))),t}function DRn(n){var t,e;if(null==n)return IZn;try{return cpn(n)}catch(i){if(F$(i=Ehn(i),103))return t=i,e=Ij(Tbn(n))+"@"+(bS(),(Avn(n)>>>0).toString(16)),wkn(ghn(),(pS(),"Exception during lenientFormat for "+e),t),"<"+e+" threw "+Ij(t.Rm)+">";throw hv(i)}}function xRn(n,t,e){var i,r;for(r=t.a.ec().Kc();r.Ob();)i=uG(r.Pb(),74),!uG(cQ(n.b,i),272)&&(R0(bIn(i))==R0(gIn(i))?QKn(n,i,e):bIn(i)==R0(gIn(i))?null==cQ(n.c,i)&&null!=cQ(n.b,gIn(i))&&bWn(n,i,e,!1):null==cQ(n.d,i)&&null!=cQ(n.b,bIn(i))&&bWn(n,i,e,!0))}function RRn(n,t){var e,i,r,c,a,o,u;for(r=n.Kc();r.Ob();)for(i=uG(r.Pb(),10),o2(o=new lOn,i),NLn(o,(KQn(),kRt)),kfn(o,(GYn(),fmt),(qx(),!0)),a=t.Kc();a.Ob();)c=uG(a.Pb(),10),o2(u=new lOn,c),NLn(u,_Rt),kfn(u,fmt,!0),kfn(e=new UZ,fmt,!0),c2(e,o),u2(e,u)}function KRn(n,t,e,i){var r,c,a,o;r=evn(n,t,e),c=evn(n,e,t),a=uG(cQ(n.c,t),118),o=uG(cQ(n.c,e),118),r1)for(t=jx((e=new sk,++n.b,e),n.d),o=Fkn(c,0);o.b!=o.d.c;)a=uG(I6(o),125),RKn(xS(DS(RS($S(new uk,1),0),t),a))}function URn(n,t,e){var i,r,c,a;for(e.Ug("Breaking Point Removing",1),n.a=uG(oIn(t,(jYn(),Vyt)),223),r=new Ww(t.b);r.a>16!=11&&t){if(eEn(n,t))throw hv(new vM(net+zBn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?hEn(n,i):n.Cb.Th(n,-1-e,null,i)),t&&(i=kyn(t,n,10,i)),(i=n_(n,t,i))&&i.oj()}else 4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,11,t,t))}function qRn(n){var t,e,i,r;for(i=new bsn(new Nw(n.b).a);i.b;)r=uG((e=von(i)).ld(),12),kfn(t=uG(e.md(),10),(GYn(),rmt),r),kfn(r,lmt,t),kfn(r,qpt,(qx(),!0)),NLn(r,uG(oIn(t,Fpt),64)),oIn(t,Fpt),kfn(r.i,(jYn(),JMt),($Pn(),oRt)),uG(oIn(HQ(r.i),Hpt),21).Fc((r_n(),rpt))}function XRn(n,t,e){var i,r,c;if(i=0,r=0,n.c)for(c=new Ww(n.d.i.j);c.ac.a)return-1;if(r.a(u=null==n.d?0:n.d.length)){for(h=n.d,n.d=Inn(IFt,qit,66,2*u+4,0,1),c=0;c=0x8000000000000000?(tin(),Jat):(i=!1,n<0&&(i=!0,n=-n),e=0,n>=d0n&&(n-=(e=t0(n/d0n))*d0n),t=0,n>=w0n&&(n-=(t=t0(n/w0n))*w0n),r=p$(t0(n),t,e),i&&Yfn(r),r)}function uKn(n){var t,e,i,r,c;if(c=new Zm,Prn(n.b,new Ed(c)),n.b.c.length=0,0!=c.c.length){for(u3(0,c.c.length),t=uG(c.c[0],82),e=1,i=c.c.length;e=-t&&r==t?new WO(xwn(i-1),xwn(r)):new WO(xwn(i),xwn(r-1))}function bKn(){return zYn(),Uhn(cT(Vwt,1),p1n,81,0,[qbt,Hbt,Xbt,uwt,Pwt,lwt,Nwt,pwt,Ewt,iwt,ywt,gwt,Swt,Zbt,Dwt,xbt,kwt,Iwt,swt,Cwt,Rwt,Twt,Rbt,jwt,Kwt,Awt,xwt,hwt,Qbt,fwt,owt,$wt,_bt,Vbt,wwt,Fbt,dwt,cwt,nwt,mwt,ewt,Ubt,Bbt,awt,twt,vwt,Lwt,Kbt,Mwt,rwt,bwt,Jbt,Wbt,Owt,zbt,Ybt,Gbt])}function wKn(n,t,e){n.d=0,n.b=0,t.k==(zIn(),gbt)&&e.k==gbt&&uG(oIn(t,(GYn(),rmt)),10)==uG(oIn(e,rmt),10)&&(jen(t).j==(KQn(),yRt)?Rxn(n,t,e):Rxn(n,e,t)),t.k==gbt&&e.k==wbt?jen(t).j==(KQn(),yRt)?n.d=1:n.b=1:e.k==gbt&&t.k==wbt&&(jen(e).j==(KQn(),yRt)?n.b=1:n.d=1),GMn(n,t,e)}function dKn(n){var t,e,i,r,c;return c=gCn(n),null!=n.a&&ZG(c,"category",n.a),!pE(new Lw(n.d))&&(nrn(c,"knownOptions",i=new Ib),t=new Mm(i),z8(new Lw(n.d),t)),!pE(n.g)&&(nrn(c,"supportedFeatures",r=new Ib),e=new Tm(r),z8(n.g,e)),c}function gKn(n){var t,e,i,r,c,a,o,u;for(t=336,e=0,r=new UF(n.length),o=0,u=(a=n).length;o>16!=7&&t){if(eEn(n,t))throw hv(new vM(net+zOn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Vjn(n,i):n.Cb.Th(n,-1-e,null,i)),t&&(i=uG(t,54).Rh(n,1,iFt,i)),(i=dz(n,t,i))&&i.oj()}else 4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,7,t,t))}function kKn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=3&&t){if(eEn(n,t))throw hv(new vM(net+fdn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Yjn(n,i):n.Cb.Th(n,-1-e,null,i)),t&&(i=uG(t,54).Rh(n,0,uFt,i)),(i=gz(n,t,i))&&i.oj()}else 4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,3,t,t))}function yKn(n,t){var e,i,r,c,a,o,u,s,h;return b_n(),t.d>n.d&&(o=n,n=t,t=o),t.d<63?KFn(n,t):(s=$9(n,a=(-2&n.d)<<4),h=$9(t,a),i=mXn(n,D9(s,a)),r=mXn(t,D9(h,a)),u=yKn(s,h),e=yKn(i,r),c=D9(c=Zzn(Zzn(c=yKn(mXn(s,i),mXn(r,h)),u),e),a),Zzn(Zzn(u=D9(u,a<<1),c),e))}function MKn(){MKn=E,rjt=new fI(v9n,0),tjt=new fI("LONGEST_PATH",1),ejt=new fI("LONGEST_PATH_SOURCE",2),YTt=new fI("COFFMAN_GRAHAM",3),njt=new fI(D6n,4),cjt=new fI("STRETCH_WIDTH",5),ijt=new fI("MIN_WIDTH",6),JTt=new fI("BF_MODEL_ORDER",7),ZTt=new fI("DF_MODEL_ORDER",8)}function TKn(n,t,e){var i,r,c,a,o;for(a=Vwn(n,e),o=Inn(pbt,e6n,10,t.length,0,1),i=0,c=a.Kc();c.Ob();)oM(gK(oIn(r=uG(c.Pb(),12),(GYn(),qpt))))&&(o[i++]=uG(oIn(r,lmt),10));if(i=0;r+=e?1:-1)c|=t.c.lg(o,r,e,i&&!oM(gK(oIn(t.j,(GYn(),Bpt))))&&!oM(gK(oIn(t.j,(GYn(),mmt))))),c|=t.q.ug(o,r,e),c|=wBn(n,o[r],e,i);return FV(n.c,t),c}function CKn(n,t,e){var i,r,c,a,o,u,s,h;for(s=0,h=(u=s6(n.j)).length;s1&&(n.a=!0),YX(uG(e.b,68),JF(D$(uG(t.b,68).c),vD(YF(D$(uG(e.b,68).a),uG(t.b,68).a),r))),f2(n,t),AKn(n,e)}function LKn(n){var t,e,i,r,c,a;for(r=new Ww(n.a.a);r.a0&&c>0?t++:i>0?e++:c>0?r++:e++}hZ(),f$(n.j,new bi)}function $Kn(n){var t,e;e=null,t=uG(zq(n.g,0),18);do{if(vR(e=t.d.i,(GYn(),nmt)))return uG(oIn(e,nmt),12).i;if(e.k!=(zIn(),dbt)&&hDn(new Fz(ix(Xgn(e).a.Kc(),new h))))t=uG(N9(new Fz(ix(Xgn(e).a.Kc(),new h))),18);else if(e.k!=dbt)return null}while(e&&e.k!=(zIn(),dbt));return e}function DKn(n,t){var e,i,r,c,a,o,u,s,h;for(o=t.j,a=t.g,u=uG(zq(o,o.c.length-1),113),u3(0,o.c.length),s=xTn(n,a,u,h=uG(o.c[0],113)),c=1;cs&&(u=e,h=r,s=i);t.a=h,t.c=u}function xKn(n,t,e){var i,r,c,a,o,u,s;for(s=new Hj(new ip(n)),o=0,u=(a=Uhn(cT(Abt,1),i6n,12,0,[t,e])).length;ou-n.b&&ou-n.a&&o0?c.a?e>(o=c.b.Mf().a)&&(r=(e-o)/2,c.d.b=r,c.d.c=r):c.d.c=n.s+e:cV(n.u)&&((i=ECn(c.b)).c<0&&(c.d.b=-i.c),i.c+i.b>c.b.Mf().a&&(c.d.c=i.c+i.b-c.b.Mf().a))}function rFn(n,t){var e,i,r,c,a;a=new Zm,e=t;do{(c=uG(cQ(n.b,e),131)).B=e.c,c.D=e.d,mv(a.c,c),e=uG(cQ(n.k,e),18)}while(e);return u3(0,a.c.length),(i=uG(a.c[0],131)).j=!0,i.A=uG(i.d.a.ec().Kc().Pb(),18).c.i,(r=uG(zq(a,a.c.length-1),131)).q=!0,r.C=uG(r.d.a.ec().Kc().Pb(),18).d.i,a}function cFn(n){var t,i;if(t=uG(n.a,17).a,i=uG(n.b,17).a,t>=0){if(t==i)return new WO(xwn(-t-1),xwn(-t-1));if(t==-i)return new WO(xwn(-t),xwn(i+1))}return e.Math.abs(t)>e.Math.abs(i)?new WO(xwn(-t),xwn(t<0?i:i+1)):new WO(xwn(t+1),xwn(i))}function aFn(n){var t,e;e=uG(oIn(n,(jYn(),gMt)),171),t=uG(oIn(n,(GYn(),Xpt)),311),e==(Gpn(),Imt)?(kfn(n,gMt,Lmt),kfn(n,Xpt,(Zen(),ppt))):e==Amt?(kfn(n,gMt,Lmt),kfn(n,Xpt,(Zen(),dpt))):t==(Zen(),ppt)?(kfn(n,gMt,Imt),kfn(n,Xpt,gpt)):t==dpt&&(kfn(n,gMt,Amt),kfn(n,Xpt,gpt))}function oFn(){oFn=E,LSt=new oa,CSt=Aq(new wJ,(uIn(),Elt),(zYn(),swt)),ASt=wz(Aq(new wJ,Elt,Twt),Plt,Mwt),NSt=Lvn(Lvn(gP(wz(Aq(new wJ,Tlt,Nwt),Plt,Lwt),Slt),Awt),$wt),ISt=wz(Aq(Aq(Aq(new wJ,jlt,lwt),Slt,wwt),Slt,dwt),Plt,bwt),OSt=wz(Aq(Aq(new wJ,Slt,dwt),Slt,Vbt),Plt,zbt)}function uFn(){uFn=E,KSt=Aq(wz(new wJ,(uIn(),Plt),(zYn(),Jbt)),Elt,swt),HSt=Lvn(Lvn(gP(wz(Aq(new wJ,Tlt,Nwt),Plt,Lwt),Slt),Awt),$wt),FSt=wz(Aq(Aq(Aq(new wJ,jlt,lwt),Slt,wwt),Slt,dwt),Plt,bwt),BSt=Aq(Aq(new wJ,Elt,Twt),Plt,Mwt),_St=wz(Aq(Aq(new wJ,Slt,dwt),Slt,Vbt),Plt,zbt)}function sFn(n,t,e,i,r){var c,a;(v9(t)||t.c.i.c!=t.d.i.c)&&uon(Gfn(Uhn(cT(PNt,1),zZn,8,0,[r.i.n,r.n,r.a])),e)||v9(t)||(t.c==r?sR(t.a,0,new eN(e)):aq(t.a,new eN(e)),i&&!cS(n.a,e)&&((a=uG(oIn(t,(jYn(),bMt)),75))||(a=new Uk,kfn(t,bMt,a)),s8(a,c=new eN(e),a.c.b,a.c),FV(n.a,c)))}function hFn(n,t){var e,i,r,c;for(e=(c=pz(Ngn(h1n,PJ(pz(Ngn(null==t?0:Hon(t),f1n)),15))))&n.b.length-1,r=null,i=n.b[e];i;r=i,i=i.a)if(i.d==c&&xQ(i.i,t))return r?r.a=i.a:n.b[e]=i.a,RM(uG(nJ(i.c),604),uG(nJ(i.f),604)),Tv(uG(nJ(i.b),227),uG(nJ(i.e),227)),--n.f,++n.e,!0;return!1}function fFn(n){var t;for(t=new Fz(ix(qgn(n).a.Kc(),new h));hDn(t);)if(uG(N9(t),18).c.i.k!=(zIn(),bbt))throw hv(new jM(y6n+ZTn(n)+"' has its layer constraint set to FIRST, but has at least one incoming edge that does not come from a FIRST_SEPARATE node. That must not happen."))}function lFn(n,t,e){var i,r,c,a,o,u;if(0==(r=Cdn(254&n.Db)))n.Eb=e;else{if(1==r)a=Inn(dat,EZn,1,2,5,1),0==jTn(n,t)?(a[0]=e,a[1]=n.Eb):(a[0]=n.Eb,a[1]=e);else for(a=Inn(dat,EZn,1,r+1,5,1),c=Kcn(n.Eb),i=2,o=0,u=0;i<=128;i<<=1)i==t?a[u++]=e:n.Db&i&&(a[u++]=c[o++]);n.Eb=a}n.Db|=t}function bFn(n,t,i){var r,c,a,o;for(this.b=new Zm,c=0,r=0,o=new Ww(n);o.a0&&(c+=(a=uG(zq(this.b,0),176)).o,r+=a.p),c*=2,r*=2,t>1?c=t0(e.Math.ceil(c*t)):r=t0(e.Math.ceil(r/t)),this.a=new smn(c,r)}function wFn(n,t,i,r,c,a){var o,u,s,h,f,l,b,w,d,g;for(h=r,t.j&&t.o?(d=(b=uG(cQ(n.f,t.A),60)).d.c+b.d.b,--h):d=t.a.c+t.a.b,f=c,i.q&&i.o?(s=(b=uG(cQ(n.f,i.C),60)).d.c,++f):s=i.a.c,w=d+(u=(s-d)/e.Math.max(2,f-h)),l=h;l=0;a+=r?1:-1){for(o=t[a],u=i==(KQn(),kRt)?r?Dgn(o,i):Spn(Dgn(o,i)):r?Spn(Dgn(o,i)):Dgn(o,i),c&&(n.c[o.p]=u.gc()),f=u.Kc();f.Ob();)h=uG(f.Pb(),12),n.d[h.p]=s++;Ohn(e,u)}}function pFn(n,t,e){var i,r,c,a,o,u,s,h;for(c=uM(pK(n.b.Kc().Pb())),s=uM(pK(whn(t.b))),i=vD(D$(n.a),s-e),r=vD(D$(t.a),e-c),vD(h=JF(i,r),1/(s-c)),this.a=h,this.b=new Zm,o=!0,(a=n.b.Kc()).Pb();a.Ob();)u=uM(pK(a.Pb())),o&&u-e>$9n&&(this.b.Fc(e),o=!1),this.b.Fc(u);o&&this.b.Fc(e)}function mFn(n){var t,e,i,r;if(wHn(n,n.n),n.d.c.length>0){for(AM(n.c);fDn(n,uG(N3(new Ww(n.e.a)),125))>5,t&=31,i>=n.d)return n.e<0?(cHn(),Dot):(cHn(),_ot);if(c=n.d-i,ROn(r=Inn(YHt,W1n,28,c+1,15,1),c,n.a,i,t),n.e<0){for(e=0;e0&&n.a[e]<<32-t){for(e=0;e=0)&&(!(e=iVn((gAn(),kBt),r,t))||((i=e.Ik())>1||-1==i)&&3!=sJ(Nen(kBt,e))))}function SFn(n,t,e,i){var r,c,a,o,u;return o=lCn(uG(zrn((!t.b&&(t.b=new f_(cFt,t,4,7)),t.b),0),84)),u=lCn(uG(zrn((!t.c&&(t.c=new f_(cFt,t,5,8)),t.c),0),84)),R0(o)==R0(u)||Ern(u,o)?null:(a=s0(t))==e?i:(c=uG(cQ(n.a,a),10))&&(r=c.e)?r:null}function PFn(n,t,e){var i,r,c,a;for(e.Ug("Longest path to source layering",1),n.a=t,a=n.a.a,n.b=Inn(YHt,W1n,28,a.c.length,15,1),i=0,c=new Ww(a);c.a0&&(i[0]+=n.d,o-=i[0]),i[2]>0&&(i[2]+=n.d,o-=i[2]),a=e.Math.max(0,o),i[1]=e.Math.max(i[1],o),Q9(n,Est,c.c+r.b+i[0]-(i[1]-o)/2,i),t==Est&&(n.c.b=a,n.c.c=c.c+r.b+(a-o)/2)}function BFn(){this.c=Inn(eUt,I0n,28,(KQn(),Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt])).length,15,1),this.b=Inn(eUt,I0n,28,Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt]).length,15,1),this.a=Inn(eUt,I0n,28,Uhn(cT(YRt,1),z4n,64,0,[FRt,yRt,kRt,KRt,_Rt]).length,15,1),KP(this.c,M0n),KP(this.b,T0n),KP(this.a,T0n)}function HFn(n,t,e){var i,r,c,a;if(t<=e?(r=t,c=e):(r=e,c=t),i=0,null==n.b)n.b=Inn(YHt,W1n,28,2,15,1),n.b[0]=r,n.b[1]=c,n.c=!0;else{if(i=n.b.length,n.b[i-1]+1==r)return void(n.b[i-1]=c);a=Inn(YHt,W1n,28,i+2,15,1),qGn(n.b,0,a,0,i),n.b=a,n.b[i-1]>=r&&(n.c=!1,n.a=!1),n.b[i++]=r,n.b[i]=c,n.c||pxn(n)}}function UFn(n,t,e){var i,r,c,a,o,u,s;for(s=t.d,n.a=new R7(s.c.length),n.c=new Ym,o=new Ww(s);o.a=0?n.Lh(s,!1,!0):YNn(n,e,!1),61).Kc();c.Ob();){for(r=uG(c.Pb(),58),h=0;h1;)e_n(r,r.i-1);return i}function YFn(n,t){var e,i,r,c,a,o;for(e=new ND,r=new Ww(n.b);r.an.d[a.p]&&(e+=J8(n.b,c),A6(n.a,xwn(c)));for(;!LM(n.a);)lin(n.b,uG(xV(n.a),17).a)}return e}function n_n(n){var t,e,i,r,c,a,o;for(n.a=new xF,o=0,r=0,i=new Ww(n.i.b);i.au.d&&(f=u.d+u.a+h));i.c.d=f,t.a.zc(i,t),s=e.Math.max(s,i.c.d+i.c.a)}return s}function r_n(){r_n=E,Zgt=new aI("COMMENTS",0),tpt=new aI("EXTERNAL_PORTS",1),ept=new aI("HYPEREDGES",2),ipt=new aI("HYPERNODES",3),rpt=new aI("NON_FREE_PORTS",4),cpt=new aI("NORTH_SOUTH_PORTS",5),opt=new aI(F6n,6),Ygt=new aI("CENTER_LABELS",7),npt=new aI("END_LABELS",8),apt=new aI("PARTITIONS",9)}function c_n(n,t,e,i,r){return i<0?((i=XOn(n,r,Uhn(cT($ot,1),zZn,2,6,[x1n,R1n,K1n,F1n,_1n,B1n,H1n,U1n,G1n,q1n,X1n,z1n]),t))<0&&(i=XOn(n,r,Uhn(cT($ot,1),zZn,2,6,["Jan","Feb","Mar","Apr",_1n,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),!(i<0||(e.k=i,0))):i>0&&(e.k=i-1,!0)}function a_n(n,t,e,i,r){return i<0?((i=XOn(n,r,Uhn(cT($ot,1),zZn,2,6,[x1n,R1n,K1n,F1n,_1n,B1n,H1n,U1n,G1n,q1n,X1n,z1n]),t))<0&&(i=XOn(n,r,Uhn(cT($ot,1),zZn,2,6,["Jan","Feb","Mar","Apr",_1n,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),!(i<0||(e.k=i,0))):i>0&&(e.k=i-1,!0)}function o_n(n,t,e,i,r,c){var a,o,u;if(o=32,i<0){if(t[0]>=n.length)return!1;if(43!=(o=VJ(n,t[0]))&&45!=o)return!1;if(++t[0],(i=RNn(n,t))<0)return!1;45==o&&(i=-i)}return 32==o&&t[0]-e==2&&2==r.b&&(a=(u=(new QE).q.getFullYear()-V1n+V1n-80)%100,c.a=i==a,i+=100*(u/100|0)+(i=0?Rmn(n):hW(Rmn(Men(n)))),qot[t]=BA(Nz(n,t),0)?Rmn(Nz(n,t)):hW(Rmn(Men(Nz(n,t)))),n=Ngn(n,5);for(;t=h&&(s=r);s&&(f=e.Math.max(f,s.a.o.a)),f>b&&(l=h,b=f)}return l}function v_n(n){var t,e,i,r,c,a,o;for(c=new Hj(uG(WW(new Dn),50)),o=T0n,e=new Ww(n.d);e.aF7n?f$(s,n.b):r<=F7n&&r>_7n?f$(s,n.d):r<=_7n&&r>B7n?f$(s,n.c):r<=B7n&&f$(s,n.a),a=T_n(n,s,a);return c}function j_n(n,t,e,i){var r,c,a,o,u;for(r=(i.c+i.a)/2,BY(t.j),aq(t.j,r),BY(e.e),aq(e.e,r),u=new hj,a=new Ww(n.f);a.a1&&(i=new MO(r,e.b),aq(t.a,i)),dan(t.a,Uhn(cT(PNt,1),zZn,8,0,[f,h]))}function O_n(n,t,e){var i,r;for(t=48;e--)pHt[e]=e-48<<24>>24;for(i=70;i>=65;i--)pHt[i]=i-65+10<<24>>24;for(r=102;r>=97;r--)pHt[r]=r-97+10<<24>>24;for(c=0;c<10;c++)mHt[c]=48+c&D1n;for(n=10;n<=15;n++)mHt[n]=65+n-10&D1n}function N_n(n,t){t.Ug("Process graph bounds",1),kfn(n,(OQn(),PPt),$I(Tun(ZJ(new fX(null,new h3(n.b,16)),new Ka)))),kfn(n,IPt,$I(Tun(ZJ(new fX(null,new h3(n.b,16)),new Fa)))),kfn(n,SPt,$I(Mun(ZJ(new fX(null,new h3(n.b,16)),new _a)))),kfn(n,CPt,$I(Mun(ZJ(new fX(null,new h3(n.b,16)),new Ba)))),t.Vg()}function $_n(n){var t,i,r,c,a;c=uG(oIn(n,(jYn(),DMt)),21),a=uG(oIn(n,KMt),21),t=new eN(i=new MO(n.f.a+n.d.b+n.d.c,n.f.b+n.d.d+n.d.a)),c.Hc((Qmn(),VRt))&&(r=uG(oIn(n,RMt),8),a.Hc((oUn(),eKt))&&(r.a<=0&&(r.a=20),r.b<=0&&(r.b=20)),t.a=e.Math.max(i.a,r.a),t.b=e.Math.max(i.b,r.b)),oM(gK(oIn(n,xMt)))||cXn(n,i,t)}function D_n(n,t){var e,i,r,c;for(c=Dgn(t,(KQn(),KRt)).Kc();c.Ob();)i=uG(c.Pb(),12),(e=uG(oIn(i,(GYn(),lmt)),10))&&RKn(xS(DS(RS($S(new uk,0),.1),n.i[t.p].d),n.i[e.p].a));for(r=Dgn(t,yRt).Kc();r.Ob();)i=uG(r.Pb(),12),(e=uG(oIn(i,(GYn(),lmt)),10))&&RKn(xS(DS(RS($S(new uk,0),.1),n.i[e.p].d),n.i[t.p].a))}function x_n(n){var t,e,i,r,c;if(!n.c){if(c=new ks,null==(t=V_t).a.zc(n,t)){for(i=new DD(z5(n));i.e!=i.i.gc();)F$(r=MGn(e=uG(Zkn(i),89)),90)&&CW(c,x_n(uG(r,29))),ttn(c,e);t.a.Bc(n),t.a.gc()}imn(c),lbn(c),n.c=new vL((uG(zrn(gZ((tQ(),M_t).o),15),19),c.i),c.g),y9(n).b&=-33}return n.c}function R_n(n){var t;if(10!=n.c)throw hv(new CM(rZn((t$(),eit))));switch(t=n.a){case 110:t=10;break;case 114:t=13;break;case 116:t=9;break;case 92:case 124:case 46:case 94:case 45:case 63:case 42:case 43:case 123:case 125:case 40:case 41:case 91:case 93:break;default:throw hv(new CM(rZn((t$(),Lit))))}return t}function K_n(n){var t,e,i,r;if(0==n.l&&0==n.m&&0==n.h)return"0";if(n.h==b0n&&0==n.m&&0==n.l)return"-9223372036854775808";if(n.h>>19)return"-"+K_n(gfn(n));for(e=n,i="";0!=e.l||0!=e.m||0!=e.h;){if(e=Yzn(e,_9(g0n),!0),t=""+Tj(Qat),0!=e.l||0!=e.m||0!=e.h)for(r=9-t.length;r>0;r--)t="0"+t;i=t+i}return i}function F_n(n){var t,e,i,r,c,a,o;for(t=!1,e=0,r=new Ww(n.d.b);r.a=n.a)return-1;if(!_Pn(t,i))return-1;if(P6(uG(r.Kb(t),20)))return 1;for(c=0,o=uG(r.Kb(t),20).Kc();o.Ob();){if(-1==(u=U_n(n,(a=uG(o.Pb(),18)).c.i==t?a.d.i:a.c.i,i,r)))return-1;if((c=e.Math.max(c,u))>n.c-1)return-1}return c+1}function G_n(n,t){var e,i,r,c,a,o;if(xA(t)===xA(n))return!0;if(!F$(t,15))return!1;if(i=uG(t,15),o=n.gc(),i.gc()!=o)return!1;if(a=i.Kc(),n.Yi()){for(e=0;e0)if(n._j(),null!=t){for(c=0;c>24;case 97:case 98:case 99:case 100:case 101:case 102:return n-97+10<<24>>24;case 65:case 66:case 67:case 68:case 69:case 70:return n-65+10<<24>>24;default:throw hv(new ZM("Invalid hexadecimal"))}}function W_n(){W_n=E,pst=new rC("SPIRAL",0),lst=new rC("LINE_BY_LINE",1),bst=new rC("MANHATTAN",2),fst=new rC("JITTER",3),dst=new rC("QUADRANTS_LINE_BY_LINE",4),gst=new rC("QUADRANTS_MANHATTAN",5),wst=new rC("QUADRANTS_JITTER",6),hst=new rC("COMBINE_LINE_BY_LINE_MANHATTAN",7),sst=new rC("COMBINE_JITTER_MANHATTAN",8)}function Q_n(n,t,e,i){var r,c,a,o,u,s;for(u=pSn(n,e),s=pSn(t,e),r=!1;u&&s&&(i||ejn(u,s,e));)a=pSn(u,e),o=pSn(s,e),Ien(t),Ien(n),c=u.c,pVn(u,!1),pVn(s,!1),e?($jn(t,s.p,c),t.p=s.p,$jn(n,u.p+1,c),n.p=u.p):($jn(n,u.p,c),n.p=u.p,$jn(t,s.p+1,c),t.p=s.p),a2(u,null),a2(s,null),u=a,s=o,r=!0;return r}function J_n(n){switch(n.g){case 0:return new ul;case 1:return new al;case 3:return new iP;case 4:return new Sc;case 5:return new RF;case 6:return new ol;case 2:return new cl;case 7:return new Zf;case 8:return new tl;default:throw hv(new vM("No implementation is available for the layerer "+(null!=n.f?n.f:""+n.g)))}}function Y_n(n,t,e,i){var r,c,a,o,u;for(r=!1,c=!1,o=new Ww(i.j);o.a=t.length)throw hv(new dM("Greedy SwitchDecider: Free layer not in graph."));this.c=t[n],this.e=new R_(i),Aon(this.e,this.c,(KQn(),_Rt)),this.i=new R_(i),Aon(this.i,this.c,kRt),this.f=new sX(this.c),this.a=!c&&r.i&&!r.s&&this.c[0].k==(zIn(),lbt),this.a&&rAn(this,n,t.length)}function iBn(n,t){var e,i,r,c,a,o;c=!n.B.Hc((oUn(),nKt)),a=n.B.Hc(iKt),n.a=new umn(a,c,n.c),n.n&&WY(n.a.n,n.n),nM(n.g,(Yrn(),Est),n.a),t||((i=new tkn(1,c,n.c)).n.a=n.k,UV(n.p,(KQn(),yRt),i),(r=new tkn(1,c,n.c)).n.d=n.k,UV(n.p,KRt,r),(o=new tkn(0,c,n.c)).n.c=n.k,UV(n.p,_Rt,o),(e=new tkn(0,c,n.c)).n.b=n.k,UV(n.p,kRt,e))}function rBn(n){var t,e,i;switch((t=uG(oIn(n.d,(jYn(),Vyt)),223)).g){case 2:e=UJn(n);break;case 3:i=new Zm,kS(JJ(YJ(sin(sin(new fX(null,new h3(n.d.b,16)),new Or),new Ar),new Lr),new pr),new Ng(i)),e=i;break;default:throw hv(new kM("Compaction not supported for "+t+" edges."))}xzn(n,e),z8(new Lw(n.g),new Ag(n))}function cBn(n,t){var e,i,r,c,a,o,u;if(t.Ug("Process directions",1),(e=uG(oIn(n,(QGn(),cCt)),88))!=(xdn(),QDt))for(r=Fkn(n.b,0);r.b!=r.d.c;){switch(i=uG(I6(r),40),o=uG(oIn(i,(OQn(),GPt)),17).a,u=uG(oIn(i,qPt),17).a,e.g){case 4:u*=-1;break;case 1:c=o,o=u,u=c;break;case 2:a=o,o=-u,u=a}kfn(i,GPt,xwn(o)),kfn(i,qPt,xwn(u))}t.Vg()}function aBn(n,t){var e;return e=new Yn,t&&zsn(e,uG(cQ(n.a,iFt),96)),F$(t,422)&&zsn(e,uG(cQ(n.a,rFt),96)),F$(t,366)?(zsn(e,uG(cQ(n.a,lFt),96)),e):(F$(t,84)&&zsn(e,uG(cQ(n.a,cFt),96)),F$(t,207)?(zsn(e,uG(cQ(n.a,bFt),96)),e):F$(t,193)?(zsn(e,uG(cQ(n.a,wFt),96)),e):(F$(t,326)&&zsn(e,uG(cQ(n.a,aFt),96)),e))}function oBn(n){var t,e,i,r,c,a,o;for(o=new c9,a=new Ww(n.a);a.a0&&t=0)return!1;if(t.p=e.b,kD(e.e,t),i==(zIn(),wbt)||i==gbt)for(r=new Ww(t.j);r.an.d[o.p]&&(e+=J8(n.b,c),A6(n.a,xwn(c))):++a;for(e+=n.b.d*a;!LM(n.a);)lin(n.b,uG(xV(n.a),17).a)}return e}function $Bn(n){var t,e,i,r,c,a;return c=0,(t=bEn(n)).kk()&&(c|=4),n.Bb&hrt&&(c|=2),F$(n,102)?(r=lMn(e=uG(n,19)),e.Bb&Qtt&&(c|=32),r&&(iQ(K0(r)),c|=8,((a=r.t)>1||-1==a)&&(c|=16),r.Bb&Qtt&&(c|=64)),e.Bb&P0n&&(c|=frt),c|=w1n):F$(t,469)?c|=512:(i=t.kk())&&1&i.i&&(c|=256),512&n.Bb&&(c|=128),c}function DBn(n,t){var e;return n.f==CBt?(e=sJ(Nen((gAn(),kBt),t)),n.e?4==e&&t!=(m$n(),NBt)&&t!=(m$n(),OBt)&&t!=(m$n(),ABt)&&t!=(m$n(),LBt):2==e):!(!n.d||!(n.d.Hc(t)||n.d.Hc(_3(Nen((gAn(),kBt),t)))||n.d.Hc(iVn((gAn(),kBt),n.b,t))))||!(!n.f||!WRn((gAn(),n.f),HJ(Nen(kBt,t))))&&(e=sJ(Nen(kBt,t)),n.e?4==e:2==e)}function xBn(n){var t,e,i,r,c,a,o,u,s,h,f,l;for(f=-1,l=0,s=0,h=(u=n).length;s0&&++l;++f}return l}function RBn(n,t,i,r){var c,a,o,u,s,h,f,l;return s=(o=uG(zDn(i,(XYn(),mDt)),8)).a,f=o.b+n,(c=e.Math.atan2(f,s))<0&&(c+=f7n),(c+=t)>f7n&&(c-=f7n),h=(u=uG(zDn(r,mDt),8)).a,l=u.b+n,(a=e.Math.atan2(l,h))<0&&(a+=f7n),(a+=t)>f7n&&(a-=f7n),YN(),oan(1e-10),e.Math.abs(c-a)<=1e-10||c==a||isNaN(c)&&isNaN(a)?0:ca?1:KL(isNaN(c),isNaN(a))}function KBn(n){var t,e,i,r,c,a,o;for(o=new Ym,i=new Ww(n.a.b);i.a=n.o)throw hv(new Ik);a=t>>5,c=Nz(1,pz(Nz(31&t,1))),n.n[e][a]=r?S3(n.n[e][a],c):E3(n.n[e][a],CG(c)),c=Nz(c,1),n.n[e][a]=i?S3(n.n[e][a],c):E3(n.n[e][a],CG(c))}catch(o){throw F$(o=Ehn(o),333)?hv(new dM(b3n+n.o+"*"+n.p+w3n+t+TZn+e+d3n)):hv(o)}}function UBn(n,t,e,i){var r,c,a,o,u,s,h,f;for(f=new Hj(new ep(n)),o=0,u=(a=Uhn(cT(pbt,1),e6n,10,0,[t,e])).length;o0&&(!(i=(!n.n&&(n.n=new fV(lFt,n,1,7)),uG(zrn(n.n,0),135)).a)||JA(JA((t.a+=' "',t),i),'"'))),JA(Nj(JA(Nj(JA(Nj(JA(Nj((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function VBn(n){var t,e,i;return 64&n.Db?rOn(n):(t=new lx(Btt),(e=n.k)?JA(JA((t.a+=' "',t),e),'"'):(!n.n&&(n.n=new fV(lFt,n,1,7)),n.n.i>0&&(!(i=(!n.n&&(n.n=new fV(lFt,n,1,7)),uG(zrn(n.n,0),135)).a)||JA(JA((t.a+=' "',t),i),'"'))),JA(Nj(JA(Nj(JA(Nj(JA(Nj((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function WBn(n,t){var e,i,r,c,a;for(t==(Sln(),rEt)&&_An(uG(Y9(n.a,(gPn(),wdt)),15)),r=uG(Y9(n.a,(gPn(),wdt)),15).Kc();r.Ob();)switch(i=uG(r.Pb(),105),e=uG(zq(i.j,0),113).d.j,f$(c=new Z_(i.j),new Fr),t.g){case 2:TCn(n,c,e,(gon(),Edt),1);break;case 1:case 0:TCn(n,new C2(c,0,a=IRn(c)),e,(gon(),Edt),0),TCn(n,new C2(c,a,c.c.length),e,Edt,1)}}function QBn(n,t){var e,i,r,c,a,o;if(null==t||0==t.length)return null;if(!(r=uG(U1(n.a,t),143))){for(i=new _w(new Fw(n.b).a.vc().Kc());i.a.Ob();)if(c=uG(i.a.Pb(),44),a=(e=uG(c.md(),143)).c,o=t.length,m_(a.substr(a.length-o,o),t)&&(t.length==a.length||46==VJ(a,a.length-t.length-1))){if(r)return null;r=e}r&&r2(n.a,t,r)}return r}function JBn(n,t){var e,i,r;return e=new Bn,(i=uG(l8(YJ(new fX(null,new h3(n.f,16)),e),gen(new W,new Q,new rn,new cn,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Out),Iut]))),21).gc())<(r=uG(l8(YJ(new fX(null,new h3(t.f,16)),e),gen(new W,new Q,new rn,new cn,Uhn(cT(Rut,1),p1n,108,0,[Out,Iut]))),21).gc())?-1:i==r?0:1}function YBn(n){var t,e,i;vR(n,(jYn(),PMt))&&((i=uG(oIn(n,PMt),21)).dc()||(e=new nB(t=uG(Mj(eRt),9),uG(MF(t,t.length),9),0),i.Hc((VDn(),Gxt))?Mon(e,Gxt):Mon(e,qxt),i.Hc(Hxt)||Mon(e,Hxt),i.Hc(Bxt)?Mon(e,Vxt):i.Hc(_xt)?Mon(e,zxt):i.Hc(Uxt)&&Mon(e,Xxt),i.Hc(Vxt)?Mon(e,Bxt):i.Hc(zxt)?Mon(e,_xt):i.Hc(Xxt)&&Mon(e,Uxt),kfn(n,PMt,e)))}function ZBn(n){var t,e,i,r,c,a,o;for(r=uG(oIn(n,(GYn(),zpt)),10),u3(0,(i=n.j).c.length),e=uG(i.c[0],12),a=new Ww(r.j);a.ar.p?(NLn(c,KRt),c.d&&(o=c.o.b,t=c.a.b,c.a.b=o-t)):c.j==KRt&&r.p>n.p&&(NLn(c,yRt),c.d&&(o=c.o.b,t=c.a.b,c.a.b=-(o-t)));break}return r}function nHn(n,t,e,i,r){var c,a,o,u,s,h,f;if(!(F$(t,207)||F$(t,366)||F$(t,193)))throw hv(new vM("Method only works for ElkNode-, ElkLabel and ElkPort-objects."));return a=n.a/2,u=t.i+i-a,h=t.j+r-a,s=u+t.g+n.a,f=h+t.f+n.a,aq(c=new Uk,new MO(u,h)),aq(c,new MO(u,f)),aq(c,new MO(s,f)),aq(c,new MO(s,h)),zsn(o=new pDn(c),t),e&&vJ(n.b,t,o),o}function tHn(n,t,e){var i,r,c,a,o,u,s,h;for(c=new MO(t,e),s=new Ww(n.a);s.a1&&(i=new MO(r,e.b),aq(t.a,i)),dan(t.a,Uhn(cT(PNt,1),zZn,8,0,[f,h]))}function THn(){THn=E,$jt=new dI(q4n,0),Ijt=new dI("NIKOLOV",1),Ljt=new dI("NIKOLOV_PIXEL",2),Ojt=new dI("NIKOLOV_IMPROVED",3),Ajt=new dI("NIKOLOV_IMPROVED_PIXEL",4),Sjt=new dI("DUMMYNODE_PERCENTAGE",5),Njt=new dI("NODECOUNT_PERCENTAGE",6),Djt=new dI("NO_BOUNDARY",7),Pjt=new dI("MODEL_ORDER_LEFT_TO_RIGHT",8),Cjt=new dI("MODEL_ORDER_RIGHT_TO_LEFT",9)}function jHn(n){var t,e,i,r,c;for(i=n.length,t=new VM,c=0;c=40)&&IGn(n),rzn(n),mFn(n),e=ign(n),i=0;e&&i0&&aq(n.f,c)):(n.c[a]-=s+1,n.c[a]<=0&&n.a[a]>0&&aq(n.e,c))))}function rUn(n,t,e,i){var r,c,a,o,u,s,h;for(YF(u=new MO(e,i),uG(oIn(t,(OQn(),kPt)),8)),h=Fkn(t.b,0);h.b!=h.d.c;)JF((s=uG(I6(h),40)).e,u),aq(n.b,s);for(o=uG(l8(_0(new fX(null,new h3(t.a,16))),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15).Kc();o.Ob();){for(c=Fkn((a=uG(o.Pb(),65)).a,0);c.b!=c.d.c;)(r=uG(I6(c),8)).a+=u.a,r.b+=u.b;aq(n.a,a)}}function cUn(n,t){var e,i,r,c;if(0<(F$(n,16)?uG(n,16).gc():x5(n.Kc()))){if(1<(r=t)){for(--r,c=new Ea,i=n.Kc();i.Ob();)e=uG(i.Pb(),40),c=zcn(Uhn(cT(vat,1),EZn,20,0,[c,new Mp(e)]));return cUn(c,r)}if(r<0){for(c=new Sa,i=n.Kc();i.Ob();)e=uG(i.Pb(),40),c=zcn(Uhn(cT(vat,1),EZn,20,0,[c,new Mp(e)]));if(0<(F$(c,16)?uG(c,16).gc():x5(c.Kc())))return cUn(c,r)}}return uG(B$(n.Kc()),40)}function aUn(n,t,e){var i,r,c,a;for(e.Ug("Processor order nodes",2),n.b=uM(pK(oIn(t,(QGn(),ECt)))),n.a=uG(oIn(t,cCt),88),n.a==(xdn(),ZDt)&&(n.a=QDt,kfn(t,cCt,n.a)),r=new lS,a=Fkn(t.b,0);a.b!=a.d.c;)oM(gK(oIn(c=uG(I6(a),40),(OQn(),UPt))))&&s8(r,c,r.c.b,r.c);MK(0!=r.b),izn(n,i=uG(r.a.a.c,40)),e.fh(1),GBn(n,i,0-uM(pK(oIn(i,(OQn(),NPt))))/2,0),e.fh(1),e.Vg()}function oUn(){oUn=E,eKt=new FO("DEFAULT_MINIMUM_SIZE",0),rKt=new FO("MINIMUM_SIZE_ACCOUNTS_FOR_PADDING",1),tKt=new FO("COMPUTE_PADDING",2),cKt=new FO("OUTSIDE_NODE_LABELS_OVERHANG",3),aKt=new FO("PORTS_OVERHANG",4),uKt=new FO("UNIFORM_PORT_SPACING",5),oKt=new FO("SPACE_EFFICIENT_PORT_LABELS",6),iKt=new FO("FORCE_TABULAR_NODE_LABELS",7),nKt=new FO("ASYMMETRICAL",8)}function uUn(n,t){var e,i,r,c,a,o,u,s;if(t){if(e=(c=t.Dh())?Hrn(c).wi().si(c):null){for(Akn(n,t,e),u=0,s=(null==(r=t.Dh()).i&&eqn(r),r.i).length;u=0&&u2*c?(h=new Jrn(f),s=EX(a)/jX(a),u=KJn(h,t,new Dk,e,i,r,s),JF(dL(h.e),u),f.c.length=0,c=0,mv(f.c,h),mv(f.c,a),c=EX(h)*jX(h)+EX(a)*jX(a)):(mv(f.c,a),c+=EX(a)*jX(a));return f}function lUn(n,t){var e,i,r,c,a,o;if((o=uG(oIn(t,(jYn(),JMt)),101))==($Pn(),aRt)||o==cRt)for(r=new MO(t.f.a+t.d.b+t.d.c,t.f.b+t.d.d+t.d.a).b,a=new Ww(n.a);a.ae?t:e;s<=f;++s)s==e?o=i++:(c=r[s],h=w.am(c.Lk()),s==t&&(u=s!=f||h?i:i-1),h&&++i);return l=uG(zdn(n,t,e),76),o!=u&&Yv(n,new wtn(n.e,7,a,xwn(o),b.md(),u)),l}return uG(zdn(n,t,e),76)}function wUn(n,t){var e,i,r,c,a,o;for(t.Ug("Port order processing",1),o=uG(oIn(n,(jYn(),iTt)),430),e=new Ww(n.b);e.a=0&&(!fjn(n,a)||(u<22?o.l|=1<>>1,a.m=s>>>1|(1&h)<<21,a.l=f>>>1|(1&s)<<21,--u;return e&&Yfn(o),c&&(i?(Qat=gfn(n),r&&(Qat=Thn(Qat,(tin(),Zat)))):Qat=p$(n.l,n.m,n.h)),o}function mUn(n,t){var e,i,r,c,a,o,u,s,h,f;for(s=n.e[t.c.p][t.p]+1,u=t.c.a.c.length+1,o=new Ww(n.a);o.a0&&(s3(0,n.length),45==n.charCodeAt(0)||(s3(0,n.length),43==n.charCodeAt(0)))?1:0;ie)throw hv(new ZM(y0n+n+'"'));return a}function kUn(n){var t,i,r,c,a,o;for(a=new lS,c=new Ww(n.a);c.a1)&&1==t&&uG(n.a[n.b],10).k==(zIn(),bbt)?Gqn(uG(n.a[n.b],10),(Ajn(),$xt)):i&&(!e||(n.c-n.b&n.a.length-1)>1)&&1==t&&uG(n.a[n.c-1&n.a.length-1],10).k==(zIn(),bbt)?Gqn(uG(n.a[n.c-1&n.a.length-1],10),(Ajn(),Dxt)):2==(n.c-n.b&n.a.length-1)?(Gqn(uG(Rfn(n),10),(Ajn(),$xt)),Gqn(uG(Rfn(n),10),Dxt)):Pxn(n,r),q5(n)}function EUn(n,t,i){var r,c,a,o,u;for(a=0,c=new DD((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a));c.e!=c.i.gc();)o="",0==(!(r=uG(Zkn(c),27)).n&&(r.n=new fV(lFt,r,1,7)),r.n).i||(o=uG(zrn((!r.n&&(r.n=new fV(lFt,r,1,7)),r.n),0),135).a),zsn(u=new wln(a++,t,o),r),kfn(u,(OQn(),RPt),r),u.e.b=r.j+r.f/2,u.f.a=e.Math.max(r.g,1),u.e.a=r.i+r.g/2,u.f.b=e.Math.max(r.f,1),aq(t.b,u),VAn(i.f,r,u)}function SUn(n){var t,e,i,r,c;i=uG(oIn(n,(GYn(),rmt)),27),c=uG(zDn(i,(jYn(),DMt)),181).Hc((Qmn(),JRt)),n.e||(r=uG(oIn(n,Hpt),21),t=new MO(n.f.a+n.d.b+n.d.c,n.f.b+n.d.d+n.d.a),r.Hc((r_n(),tpt))?(Myn(i,JMt,($Pn(),cRt)),ZQn(i,t.a,t.b,!1,!0)):oM(gK(zDn(i,xMt)))||ZQn(i,t.a,t.b,!0,!0)),Myn(i,DMt,c?ggn(JRt):new nB(e=uG(Mj(sKt),9),uG(MF(e,e.length),9),0))}function PUn(n,t,e){var i,r,c,a;if(t[0]>=n.length)return e.o=0,!0;switch(VJ(n,t[0])){case 43:r=1;break;case 45:r=-1;break;default:return e.o=0,!0}if(++t[0],c=t[0],0==(a=RNn(n,t))&&t[0]==c)return!1;if(t[0]a&&(a=r,s.c.length=0),r==a&&kD(s,new WO(e.c.i,e)));hZ(),f$(s,n.c),GX(n.b,o.p,s)}}function AUn(n,t){var e,i,r,c,a,o,u,s;for(c=new Ww(t.b);c.aa&&(a=r,s.c.length=0),r==a&&kD(s,new WO(e.d.i,e)));hZ(),f$(s,n.c),GX(n.f,o.p,s)}}function LUn(n,t){var e,i,r,c,a,o,u;if(null==(u=gK(oIn(t,(QGn(),TCt))))||(tJ(u),u)){for(E$n(n,t),r=new Zm,o=Fkn(t.b,0);o.b!=o.d.c;)(e=yAn(n,uG(I6(o),40),null))&&(zsn(e,t),mv(r.c,e));if(n.a=null,n.b=null,r.c.length>1)for(i=new Ww(r);i.a=0&&o!=e&&(c=new lV(n,1,o,a,null),i?i.nj(c):i=c),e>=0&&(c=new lV(n,1,e,o==e?a:null,t),i?i.nj(c):i=c)),i}function xUn(n){var t,e,i;if(null==n.b){if(i=new zM,null!=n.i&&(VA(i,n.i),i.a+=":"),256&n.f){for(256&n.f&&null!=n.a&&(aY(n.i)||(i.a+="//"),VA(i,n.a)),null!=n.d&&(i.a+="/",VA(i,n.d)),16&n.f&&(i.a+="/"),t=0,e=n.j.length;ts)&&(u+o+uXn(i,s,!1).a<=t.b&&(dtn(e,c-e.s),e.c=!0,dtn(i,c-e.s),oMn(i,e.s,e.t+e.d+o),i.k=!0,Gun(e.q,i),h=!0,r&&(fan(t,i),i.j=t,n.c.length>a&&(uEn((u3(a,n.c.length),uG(n.c[a],186)),i),0==(u3(a,n.c.length),uG(n.c[a],186)).a.c.length&&i7(n,a)))),h)}function UUn(n,t){var e,i,r,c,a;if(t.Ug("Partition midprocessing",1),r=new K1,kS(JJ(new fX(null,new h3(n.a,16)),new di),new kg(r)),0!=r.d){for(a=uG(l8(f3(new fX(null,(r.i||(r.i=new RD(r,r.c))).Nc())),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15),e=uG((i=a.Kc()).Pb(),17);i.Ob();)c=uG(i.Pb(),17),RRn(uG(Y9(r,e),21),uG(Y9(r,c),21)),e=c;t.Vg()}}function GUn(n,t,e){var i,r,c,a,o;if(0==t.p){for(t.p=1,(r=e)||(r=new WO(new Zm,new nB(i=uG(Mj(YRt),9),uG(MF(i,i.length),9),0))),uG(r.a,15).Fc(t),t.k==(zIn(),lbt)&&uG(r.b,21).Fc(uG(oIn(t,(GYn(),Fpt)),64)),a=new Ww(t.j);a.a0)if(r=uG(n.Ab.g,2033),null==t){for(c=0;ci.s&&ua)return KQn(),kRt;break;case 4:case 3:if(h<0)return KQn(),yRt;if(h+e>c)return KQn(),KRt}return(u=(s+o/2)/a)+(i=(h+e/2)/c)<=1&&u-i<=0?(KQn(),_Rt):u+i>=1&&u-i>=0?(KQn(),kRt):i<.5?(KQn(),yRt):(KQn(),KRt)}function tGn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b;for(e=!1,u=uM(pK(oIn(t,(jYn(),ETt)))),l=T1n*u,r=new Ww(t.b);r.aa.n.b-a.d.d+h.a+l&&(b=s.g+h.g,h.a=(h.g*h.a+s.g*s.a)/b,h.g=b,s.f=h,e=!0)),c=a,s=h;return e}function eGn(n,t,e,i,r,c,a){var o,u,s,h,f;for(f=new cN,u=t.Kc();u.Ob();)for(h=new Ww(uG(u.Pb(),853).Rf());h.a0?o.a?r>(s=o.b.Mf().b)&&(n.v||1==o.c.d.c.length?(a=(r-s)/2,o.d.d=a,o.d.a=a):(i=(uG(zq(o.c.d,0),187).Mf().b-s)/2,o.d.d=e.Math.max(0,i),o.d.a=r-i-s)):o.d.a=n.t+r:cV(n.u)&&((c=ECn(o.b)).d<0&&(o.d.d=-c.d),c.d+c.a>o.b.Mf().b&&(o.d.a=c.d+c.a-o.b.Mf().b))}function cGn(){cGn=E,$ft=new _N((XYn(),vDt),xwn(1)),_ft=new _N(DDt,80),Fft=new _N(CDt,5),kft=new _N(c$t,r4n),Dft=new _N(kDt,xwn(1)),Kft=new _N(TDt,(qx(),!0)),Aft=new CN(50),Oft=new _N(W$t,Aft),Mft=O$t,Lft=sDt,yft=new _N(p$t,!1),Ift=V$t,Pft=H$t,Cft=q$t,Sft=_$t,Eft=K$t,Nft=bDt,oOn(),jft=sft,Bft=wft,Tft=uft,xft=fft,Rft=bft,Gft=HDt,Xft=XDt,Uft=BDt,Hft=_Dt,Iwn(),new _N(UDt,qft=fKt)}function aGn(n,t){var e;switch(Min(n)){case 6:return RA(t);case 7:return FA(t);case 8:return KA(t);case 3:return Array.isArray(t)&&!((e=Min(t))>=14&&e<=16);case 11:return null!=t&&typeof t===mZn;case 12:return null!=t&&(typeof t===wZn||typeof t==mZn);case 0:return Eyn(t,n.__elementTypeId$);case 2:return NV(t)&&!(t.Tm===j);case 1:return NV(t)&&!(t.Tm===j)||Eyn(t,n.__elementTypeId$);default:return!0}}function oGn(n,t){var i,r,c,a;return r=e.Math.min(e.Math.abs(n.c-(t.c+t.b)),e.Math.abs(n.c+n.b-t.c)),a=e.Math.min(e.Math.abs(n.d-(t.d+t.a)),e.Math.abs(n.d+n.a-t.d)),(i=e.Math.abs(n.c+n.b/2-(t.c+t.b/2)))>n.b/2+t.b/2||(c=e.Math.abs(n.d+n.a/2-(t.d+t.a/2)))>n.a/2+t.a/2?1:0==i&&0==c?0:0==i?a/c+1:0==c?r/i+1:e.Math.min(r/i,a/c)+1}function uGn(n,t){var e,i,r,c,a,o,u;for(c=0,o=0,u=0,r=new Ww(n.f.e);r.a0&&n.d!=(Jen(),plt)&&(o+=a*(i.d.a+n.a[t.a][i.a]*(t.d.a-i.d.a)/e)),e>0&&n.d!=(Jen(),dlt)&&(u+=a*(i.d.b+n.a[t.a][i.a]*(t.d.b-i.d.b)/e)));switch(n.d.g){case 1:return new MO(o/c,t.d.b);case 2:return new MO(t.d.a,u/c);default:return new MO(o/c,u/c)}}function sGn(n){var t,e,i,r,c;for(kD(c=new R7((!n.a&&(n.a=new MD(eFt,n,5)),n.a).i+2),new MO(n.j,n.k)),kS(new fX(null,(!n.a&&(n.a=new MD(eFt,n,5)),new h3(n.a,16))),new Vp(c)),kD(c,new MO(n.b,n.c)),t=1;t0&&(hfn(u,!1,(xdn(),JDt)),hfn(u,!0,YDt)),Prn(t.g,new UC(n,e)),vJ(n.g,t,e)}function lGn(){var n;for(lGn=E,pot=Uhn(cT(YHt,1),W1n,28,15,[-1,-1,30,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5]),mot=Inn(YHt,W1n,28,37,15,1),vot=Uhn(cT(YHt,1),W1n,28,15,[-1,-1,63,40,32,28,25,23,21,20,19,19,18,18,17,17,16,16,16,15,15,15,15,14,14,14,14,14,14,13,13,13,13,13,13,13,13]),kot=Inn(nUt,E0n,28,37,14,1),n=2;n<=36;n++)mot[n]=t0(e.Math.pow(n,pot[n])),kot[n]=bSn(YZn,mot[n])}function bGn(n){var t;if(1!=(!n.a&&(n.a=new fV(oFt,n,6,6)),n.a).i)throw hv(new vM(Ptt+(!n.a&&(n.a=new fV(oFt,n,6,6)),n.a).i));return t=new Uk,Shn(uG(zrn((!n.b&&(n.b=new f_(cFt,n,4,7)),n.b),0),84))&&Qon(t,pYn(n,Shn(uG(zrn((!n.b&&(n.b=new f_(cFt,n,4,7)),n.b),0),84)),!1)),Shn(uG(zrn((!n.c&&(n.c=new f_(cFt,n,5,8)),n.c),0),84))&&Qon(t,pYn(n,Shn(uG(zrn((!n.c&&(n.c=new f_(cFt,n,5,8)),n.c),0),84)),!0)),t}function wGn(n,t){var e,i,r;for(r=!1,i=new Fz(ix((t.d?n.a.c==(b0(),fSt)?qgn(t.b):Xgn(t.b):n.a.c==(b0(),hSt)?qgn(t.b):Xgn(t.b)).a.Kc(),new h));hDn(i);)if(e=uG(N9(i),18),(oM(n.a.f[n.a.g[t.b.p].p])||v9(e)||e.c.i.c!=e.d.i.c)&&!oM(n.a.n[n.a.g[t.b.p].p])&&!oM(n.a.n[n.a.g[t.b.p].p])&&(r=!0,cS(n.b,n.a.g[vTn(e,t.b).p])))return t.c=!0,t.a=e,t;return t.c=r,t.a=null,t}function dGn(n,t,e){var i,r,c,a,o,u,s;if(0==(i=e.gc()))return!1;if(n.Pj())if(u=n.Qj(),nmn(n,t,e),a=1==i?n.Ij(3,null,e.Kc().Pb(),t,u):n.Ij(5,null,e,t,u),n.Mj()){for(o=i<100?null:new cj(i),c=t+i,r=t;r0){for(o=0;o>16==-15&&n.Cb.Yh()&&Cen(new btn(n.Cb,9,13,e,n.c,Hyn(Aen(uG(n.Cb,62)),n))):F$(n.Cb,90)&&n.Db>>16==-23&&n.Cb.Yh()&&(F$(t=n.c,90)||(YYn(),t=x_t),F$(e,90)||(YYn(),e=x_t),Cen(new btn(n.Cb,9,10,e,t,Hyn(z5(uG(n.Cb,29)),n)))))),n.c}function TGn(n,t,e){var i,r,c,a,o,u,s,h;for(e.Ug("Hyperedge merging",1),CDn(n,t),o=new N4(t.b,0);o.b0,o=hpn(t,c),Px(e?o.b:o.g,t),1==Ebn(o).c.length&&s8(i,o,i.c.b,i.c),r=new WO(c,t),A6(n.o,r),men(n.e.a,c))}function OGn(n,t){var i,r,c,a;return r=e.Math.abs(AV(n.b).a-AV(t.b).a),a=e.Math.abs(AV(n.b).b-AV(t.b).b),i=1,c=1,r>n.b.b/2+t.b.b/2&&(i=1-e.Math.min(e.Math.abs(n.b.c-(t.b.c+t.b.b)),e.Math.abs(n.b.c+n.b.b-t.b.c))/r),a>n.b.a/2+t.b.a/2&&(c=1-e.Math.min(e.Math.abs(n.b.d-(t.b.d+t.b.a)),e.Math.abs(n.b.d+n.b.a-t.b.d))/a),(1-e.Math.min(i,c))*e.Math.sqrt(r*r+a*a)}function AGn(n){var t,e,i;for(wQn(n,n.e,n.f,(l0(),USt),!0,n.c,n.i),wQn(n,n.e,n.f,USt,!1,n.c,n.i),wQn(n,n.e,n.f,GSt,!0,n.c,n.i),wQn(n,n.e,n.f,GSt,!1,n.c,n.i),yGn(n,n.c,n.e,n.f,n.i),e=new N4(n.i,0);e.b=65;e--)dHt[e]=e-65<<24>>24;for(i=122;i>=97;i--)dHt[i]=i-97+26<<24>>24;for(r=57;r>=48;r--)dHt[r]=r-48+52<<24>>24;for(dHt[43]=62,dHt[47]=63,c=0;c<=25;c++)gHt[c]=65+c&D1n;for(a=26,u=0;a<=51;++a,u++)gHt[a]=97+u&D1n;for(n=52,o=0;n<=61;++n,o++)gHt[n]=48+o&D1n;gHt[62]=43,gHt[63]=47}function $Gn(n,t){var i,r,c,a,o,u;return(c=nun(n))==(u=nun(t))?n.e==t.e&&n.a<54&&t.a<54?n.ft.f?1:0:(r=n.e-t.e,(i=(n.d>0?n.d:e.Math.floor((n.a-1)*A0n)+1)-(t.d>0?t.d:e.Math.floor((t.a-1)*A0n)+1))>r+1?c:i0&&(o=j5(o,_qn(r))),Pvn(a,o))):cs&&(l=0,b+=u+t,u=0),tHn(a,l,b),i=e.Math.max(i,l+h.a),u=e.Math.max(u,h.b),l+=h.a+t;return new MO(i+t,b+u+t)}function RGn(n,t){var e,i,r,c,a,o,u;if(!h0(n))throw hv(new kM(Stt));if(c=(i=h0(n)).g,r=i.f,c<=0&&r<=0)return KQn(),FRt;switch(o=n.i,u=n.j,t.g){case 2:case 1:if(o<0)return KQn(),_Rt;if(o+n.g>c)return KQn(),kRt;break;case 4:case 3:if(u<0)return KQn(),yRt;if(u+n.f>r)return KQn(),KRt}return(a=(o+n.g/2)/c)+(e=(u+n.f/2)/r)<=1&&a-e<=0?(KQn(),_Rt):a+e>=1&&a-e>=0?(KQn(),kRt):e<.5?(KQn(),yRt):(KQn(),KRt)}function KGn(n,t,e,i,r){var c,a;if(c=Lgn(E3(t[0],L0n),E3(i[0],L0n)),n[0]=pz(c),c=$z(c,32),e>=r){for(a=1;a0&&(r.b[a++]=0,r.b[a++]=c.b[0]-1),t=1;t0&&(Qb(u,u.d-r.d),r.c==(_7(),$St)&&Vb(u,u.a-r.d),u.d<=0&&u.i>0&&s8(t,u,t.c.b,t.c));for(c=new Ww(n.f);c.a0&&(Jb(o,o.i-r.d),r.c==(_7(),$St)&&Wb(o,o.b-r.d),o.i<=0&&o.d>0&&s8(e,o,e.c.b,e.c))}function GGn(n,t,e,i,r){var c,a,o,u,s,h,f,l,b;for(hZ(),f$(n,new Bu),a=oG(n),b=new Zm,l=new Zm,o=null,u=0;0!=a.b;)c=uG(0==a.b?null:(MK(0!=a.b),Lrn(a,a.a.a)),163),!o||EX(o)*jX(o)/21&&(u>EX(o)*jX(o)/2||0==a.b)&&(f=new Jrn(l),h=EX(o)/jX(o),s=KJn(f,t,new Dk,e,i,r,h),JF(dL(f.e),s),o=f,mv(b.c,f),u=0,l.c.length=0));return Ohn(b,l),b}function qGn(n,t,e,i,r){var c,a,o,u,s,h,f;if(bS(),aW(n,"src"),aW(e,"dest"),f=Tbn(n),u=Tbn(e),yG(!!(4&f.i),"srcType is not an array"),yG(!!(4&u.i),"destType is not an array"),h=f.c,a=u.c,yG(1&h.i?h==a:!(1&a.i),"Array types don't match"),$fn(n,t,e,i,r),1&h.i||f==u)b$n(n,t,e,i,r,!0);else if(s=Kcn(n),c=Kcn(e),xA(n)===xA(e)&&ti;)uQ(c,o,s[--t]);else for(o=i+r;i0),i.a.Xb(i.c=--i.b),h>f+o&&LQ(i);for(c=new Ww(l);c.a0),i.a.Xb(i.c=--i.b)}}function VGn(){var n,t,e,i,r,c;if(QYn(),WHt)return WHt;for(TXn(n=new K3(4),kJn(iat,!0)),lWn(n,kJn("M",!0)),lWn(n,kJn("C",!0)),c=new K3(4),i=0;i<11;i++)HFn(c,i,i);return TXn(t=new K3(4),kJn("M",!0)),HFn(t,4448,4607),HFn(t,65438,65439),kzn(r=new QN(2),n),kzn(r,OHt),(e=new QN(2)).Jm(CX(c,kJn("L",!0))),e.Jm(t),e=new n8(3,e),e=new eW(r,e),WHt=e}function WGn(n,t){var e,i,r,c,a,o,u,s;for(e=new RegExp(t,"g"),u=Inn($ot,zZn,2,0,6,1),i=0,s=n,c=null;;){if(null==(o=e.exec(s))||""==s){u[i]=s;break}a=o.index,u[i]=(Knn(0,a,s.length),s.substr(0,a)),s=r1(s,a+o[0].length,s.length),e.lastIndex=0,c==s&&(u[i]=(Knn(0,1,s.length),s.substr(0,1)),s3(1,s.length+1),s=s.substr(1)),c=s,++i}if(n.length>0){for(r=u.length;r>0&&""==u[r-1];)--r;r0&&(l-=r[0]+n.c,r[0]+=n.c),r[2]>0&&(l-=r[2]+n.c),r[1]=e.Math.max(r[1],l),qX(n.a[1],i.c+t.b+r[0]-(r[1]-l)/2,r[1]);for(u=0,h=(a=n.a).length;u0?(n.n.c.length-1)*n.i:0,i=new Ww(n.n);i.a1)for(i=Fkn(r,0);i.b!=i.d.c;)for(c=0,o=new Ww((e=uG(I6(i),235)).e);o.a0&&(t[0]+=n.c,l-=t[0]),t[2]>0&&(l-=t[2]+n.c),t[1]=e.Math.max(t[1],l),XX(n.a[1],r.d+i.d+t[0]-(t[1]-l)/2,t[1]);else for(w=r.d+i.d,b=r.a-i.d-i.a,s=0,f=(o=n.a).length;s0||0==Fgn(c.b.d,n.b.d+n.b.a)&&r.b<0||0==Fgn(c.b.d+c.b.a,n.b.d)&&r.b>0){u=0;break}}else u=e.Math.min(u,LLn(n,c,r));u=e.Math.min(u,uqn(n,a,u,r))}return u}function sqn(n,t){var e,i,r,c,a,o;if(n.b<2)throw hv(new vM("The vector chain must contain at least a source and a target point."));for(MK(0!=n.b),MN(t,(i=uG(n.a.a.c,8)).a,i.b),o=new Zx((!t.a&&(t.a=new MD(eFt,t,5)),t.a)),c=Fkn(n,1);c.a=0&&c!=e)throw hv(new vM(Xet));for(r=0,u=0;uuM(oD(a.g,a.d[0]).a)?(MK(u.b>0),u.a.Xb(u.c=--u.b),pF(u,a),r=!0):o.e&&o.e.gc()>0&&(c=(!o.e&&(o.e=new Zm),o.e).Mc(t),s=(!o.e&&(o.e=new Zm),o.e).Mc(e),(c||s)&&((!o.e&&(o.e=new Zm),o.e).Fc(a),++a.c));r||mv(i.c,a)}function bqn(n,t,e){var i,r,c,a,o,u,s,h,f,l;return h=n.a.i+n.a.g/2,f=n.a.i+n.a.g/2,a=new MO(t.i+t.g/2,t.j+t.f/2),(u=uG(zDn(t,(XYn(),mDt)),8)).a=u.a+h,u.b=u.b+f,r=(a.b-u.b)/(a.a-u.a),i=a.b-r*a.a,o=new MO(e.i+e.g/2,e.j+e.f/2),(s=uG(zDn(e,mDt),8)).a=s.a+h,s.b=s.b+f,c=(o.b-s.b)/(o.a-s.a),l=(i-(o.b-c*o.a))/(c-r),!(u.a>>0).toString(16),t.length-2,t.length):n>=P0n?"\\v"+r1(t="0"+(n>>>0).toString(16),t.length-6,t.length):""+String.fromCharCode(n&D1n)}return e}function Tqn(n){var t,e,i;if(sN(uG(oIn(n,(jYn(),JMt)),101)))for(e=new Ww(n.j);e.a=t.o&&e.f<=t.f||.5*t.a<=e.f&&1.5*t.a>=e.f){if((c=uG(zq(t.n,t.n.c.length-1),209)).e+c.d+e.g+r<=i&&(uG(zq(t.n,t.n.c.length-1),209).f-n.f+e.f<=n.b||1==n.a.c.length))return ipn(t,e),!0;if(t.s+e.g<=i&&(t.t+t.d+e.f+r<=n.b||1==n.a.c.length))return kD(t.b,e),a=uG(zq(t.n,t.n.c.length-1),209),kD(t.n,new c0(t.s,a.f+a.a+t.i,t.i)),zMn(uG(zq(t.n,t.n.c.length-1),209),e),nqn(t,e),!0}return!1}function Pqn(n,t,e){var i,r,c,a;return n.Pj()?(r=null,c=n.Qj(),i=n.Ij(1,a=iin(n,t,e),e,t,c),n.Mj()&&!(n.Yi()&&null!=a?udn(a,e):xA(a)===xA(e))?(null!=a&&(r=n.Oj(a,r)),r=n.Nj(e,r),n.Tj()&&(r=n.Wj(a,e,r)),r?(r.nj(i),r.oj()):n.Jj(i)):(n.Tj()&&(r=n.Wj(a,e,r)),r?(r.nj(i),r.oj()):n.Jj(i)),a):(a=iin(n,t,e),n.Mj()&&!(n.Yi()&&null!=a?udn(a,e):xA(a)===xA(e))&&(r=null,null!=a&&(r=n.Oj(a,null)),(r=n.Nj(e,r))&&r.oj()),a)}function Cqn(n,t){var e,i,r,c;if(t.Ug("Path-Like Graph Wrapping",1),0!=n.b.c.length)if(null==(r=new dDn(n)).i&&(r.i=aun(r,new pc)),e=uM(r.i)*r.f/(null==r.i&&(r.i=aun(r,new pc)),uM(r.i)),r.b>e)t.Vg();else{switch(uG(oIn(n,(jYn(),BTt)),351).g){case 2:c=new kc;break;case 0:c=new hc;break;default:c=new yc}if(i=c.og(n,r),!c.pg())switch(uG(oIn(n,zTt),352).g){case 2:i=KLn(r,i);break;case 1:i=pPn(r,i)}yzn(n,r,i),t.Vg()}else t.Vg()}function Iqn(n,t){var i,r,c,a,o,u,s;t%=24,n.q.getHours()!=t&&((i=new e.Date(n.q.getTime())).setDate(i.getDate()+1),(o=n.q.getTimezoneOffset()-i.getTimezoneOffset())>0&&(u=o/60|0,s=o%60,r=n.q.getDate(),n.q.getHours()+u>=24&&++r,c=new e.Date(n.q.getFullYear(),n.q.getMonth(),r,t+u,n.q.getMinutes()+s,n.q.getSeconds(),n.q.getMilliseconds()),n.q.setTime(c.getTime()))),a=n.q.getTime(),n.q.setTime(a+36e5),n.q.getHours()!=t&&n.q.setTime(a)}function Oqn(n,t){var e,i,r,c;if(a3(n.d,n.e),n.c.a.$b(),0!=uM(pK(oIn(t.j,(jYn(),yyt))))||0!=uM(pK(oIn(t.j,yyt))))for(e=B3n,xA(oIn(t.j,Syt))!==xA((yvn(),Fjt))&&kfn(t.j,(GYn(),Bpt),(qx(),!0)),c=uG(oIn(t.j,OTt),17).a,r=0;r(u3(c+1,t.c.length),uG(t.c[c+1],17)).a-i&&++o,kD(r,(u3(c+o,t.c.length),uG(t.c[c+o],17))),a+=(u3(c+o,t.c.length),uG(t.c[c+o],17)).a-i,++e;e=g&&n.e[s.p]>w*n.b||v>=i*g)&&(mv(l.c,u),u=new Zm,Qon(o,a),a.a.$b(),h-=f,b=e.Math.max(b,h*n.b+d),h+=v,m=v,v=0,f=0,d=0);return new WO(b,l)}function $qn(n){var t,e,i,r,c;if(!n.d){if(c=new js,null==(t=V_t).a.zc(n,t)){for(e=new DD(n1(n));e.e!=e.i.gc();)CW(c,$qn(uG(Zkn(e),29)));t.a.Bc(n),t.a.gc()}for(r=c.i,!n.q&&(n.q=new fV(p_t,n,11,10)),i=new DD(n.q);i.e!=i.i.gc();++r)uG(Zkn(i),411);CW(c,(!n.q&&(n.q=new fV(p_t,n,11,10)),n.q)),lbn(c),n.d=new vL((uG(zrn(gZ((tQ(),M_t).o),9),19),c.i),c.g),n.e=uG(c.g,688),null==n.e&&(n.e=W_t),y9(n).b&=-17}return n.d}function Dqn(n,t,e,i){var r,c,a,o,u,s;if(s=VKn(n.e.Dh(),t),u=0,r=uG(n.g,124),PP(),uG(t,69).xk()){for(a=0;a1||-1==w)if(f=uG(d,71),l=uG(h,71),f.dc())l.$b();else for(a=!!lMn(t),c=0,o=n.a?f.Kc():f.Ii();o.Ob();)s=uG(o.Pb(),58),(r=uG(ain(n,s),58))?(a?-1==(u=l.dd(r))?l.Gi(c,r):c!=u&&l.Ui(c,r):l.Gi(c,r),++c):n.b&&!a&&(l.Gi(c,s),++c);else null==d?h.Wb(null):null==(r=ain(n,d))?n.b&&!lMn(t)&&h.Wb(d):h.Wb(r)}function Rqn(n,t){var i,r,c,a,o,u,s,f;for(i=new Ne,c=new Fz(ix(qgn(t).a.Kc(),new h));hDn(c);)if(!v9(r=uG(N9(c),18))&&_Pn(u=r.c.i,$bt)){if(-1==(f=U_n(n,u,$bt,Nbt)))continue;i.b=e.Math.max(i.b,f),!i.a&&(i.a=new Zm),kD(i.a,u)}for(o=new Fz(ix(Xgn(t).a.Kc(),new h));hDn(o);)if(!v9(a=uG(N9(o),18))&&_Pn(s=a.d.i,Nbt)){if(-1==(f=U_n(n,s,Nbt,$bt)))continue;i.d=e.Math.max(i.d,f),!i.c&&(i.c=new Zm),kD(i.c,s)}return i}function Kqn(n,t,e,i){var r,c,a,o,u,s,h;if(e.d.i!=t.i){for(Hb(r=new gMn(n),(zIn(),wbt)),kfn(r,(GYn(),rmt),e),kfn(r,(jYn(),JMt),($Pn(),cRt)),mv(i.c,r),o2(a=new lOn,r),NLn(a,(KQn(),_Rt)),o2(o=new lOn,r),NLn(o,kRt),h=e.d,u2(e,a),zsn(c=new UZ,e),kfn(c,bMt,null),c2(c,o),u2(c,h),s=new N4(e.b,0);s.b1e6)throw hv(new wM("power of ten too big"));if(n<=vZn)return D9(t$n(Got[1],t),t);for(r=i=t$n(Got[1],vZn),e=Bsn(n-vZn),t=t0(n%vZn);dwn(e,vZn)>0;)r=j5(r,i),e=$gn(e,vZn);for(r=D9(r=j5(r,t$n(Got[1],t)),vZn),e=Bsn(n-vZn);dwn(e,vZn)>0;)r=D9(r,vZn),e=$gn(e,vZn);return r=D9(r,t)}function Bqn(n){var t,e,i,r,c,a,o,u;for(a=new Ww(n.a);a.as&&i>s)){r=!1,e._g()&&e.bh("bk node placement breaks on "+o+" which should have been after "+h);break}h=o,s=uM(t.p[o.p])+uM(t.d[o.p])+o.o.b+o.d.a}if(!r)break}return e._g()&&e.bh(t+" is feasible: "+r),r}function Xqn(n,t,e,i){var r,c,a,o,u,s,h;if(Hb(c=new gMn(n),(zIn(),gbt)),kfn(c,(jYn(),JMt),($Pn(),cRt)),r=0,t){for(kfn(a=new lOn,(GYn(),rmt),t),kfn(c,rmt,t.i),NLn(a,(KQn(),_Rt)),o2(a,c),s=0,h=(u=x4(t.e)).length;s0)){if(r=-1,32==VJ(h.c,0)){if(f=s[0],win(t,s),s[0]>f)continue}else if(WZ(t,h.c,s[0])){s[0]+=h.c.length;continue}return 0}if(r<0&&h.a&&(r=u,c=s[0],i=0),r>=0){if(o=h.b,u==r&&0==(o-=i++))return 0;if(!rJn(t,s,h,o,a)){u=r-1,s[0]=c;continue}}else if(r=-1,!rJn(t,s,h,0,a))return 0}return LQn(a,e)?s[0]:0}function Qqn(n,t,e){var i,r,c,a,o,u,s,h,f,l;for(h=new Kz(new Fd(e)),zV(o=Inn(ZHt,B2n,28,n.f.e.c.length,16,1),o.length),e[t.a]=0,s=new Ww(n.f.e);s.a=0&&!eTn(n,h,f);)--f;r[h]=f}for(b=0;b=0&&!eTn(n,o,w);)--o;c[w]=o}for(u=0;ut[l]&&li[u]&&HBn(n,u,l,!1,!0)}function Yqn(n){var t,e,i,r,c,a,o,u;e=oM(gK(oIn(n,(cGn(),yft)))),c=n.a.c.d,o=n.a.d.d,e?(a=vD(YF(new MO(o.a,o.b),c),.5),u=vD(D$(n.e),.5),t=YF(JF(new MO(c.a,c.b),a),u),_R(n.d,t)):(r=uM(pK(oIn(n.a,Fft))),i=n.d,c.a>=o.a?c.b>=o.b?(i.a=o.a+(c.a-o.a)/2+r,i.b=o.b+(c.b-o.b)/2-r-n.e.b):(i.a=o.a+(c.a-o.a)/2+r,i.b=c.b+(o.b-c.b)/2+r):c.b>=o.b?(i.a=c.a+(o.a-c.a)/2+r,i.b=o.b+(c.b-o.b)/2+r):(i.a=c.a+(o.a-c.a)/2+r,i.b=c.b+(o.b-c.b)/2-r-n.e.b))}function Zqn(n){var t,e,i,r,c,a;if(!n.f){if(a=new Ms,c=new Ms,null==(t=V_t).a.zc(n,t)){for(r=new DD(n1(n));r.e!=r.i.gc();)CW(a,Zqn(uG(Zkn(r),29)));t.a.Bc(n),t.a.gc()}for(!n.s&&(n.s=new fV(o_t,n,21,17)),i=new DD(n.s);i.e!=i.i.gc();)F$(e=uG(Zkn(i),179),102)&&ttn(c,uG(e,19));lbn(c),n.r=new JG(n,(uG(zrn(gZ((tQ(),M_t).o),6),19),c.i),c.g),CW(a,n.r),lbn(a),n.f=new vL((uG(zrn(gZ(M_t.o),5),19),a.i),a.g),y9(n).b&=-3}return n.f}function nXn(n){hP(n,new hCn(FT(DT(KT(RT(new bu,$3n),"ELK DisCo"),"Layouter for arranging unconnected subgraphs. The subgraphs themselves are, by default, not laid out."),new ct))),U4(n,$3n,D3n,Jkn(ift)),U4(n,$3n,x3n,Jkn(Jht)),U4(n,$3n,R3n,Jkn(Xht)),U4(n,$3n,K3n,Jkn(Yht)),U4(n,$3n,D2n,Jkn(tft)),U4(n,$3n,x2n,Jkn(nft)),U4(n,$3n,$2n,Jkn(eft)),U4(n,$3n,R2n,Jkn(Zht)),U4(n,$3n,I3n,Jkn(Vht)),U4(n,$3n,O3n,Jkn(zht)),U4(n,$3n,A3n,Jkn(Wht)),U4(n,$3n,L3n,Jkn(Qht))}function tXn(){tXn=E,JKt=Uhn(cT(JHt,1),N1n,28,15,[48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70]),YKt=new RegExp("[ \t\n\r\f]+");try{QKt=Uhn(cT(iBt,1),EZn,2114,0,[new Km((wL(),Cmn("yyyy-MM-dd'T'HH:mm:ss'.'SSSZ",bF((qy(),qy(),Hat))))),new Km(Cmn("yyyy-MM-dd'T'HH:mm:ss'.'SSS",bF(Hat))),new Km(Cmn("yyyy-MM-dd'T'HH:mm:ss",bF(Hat))),new Km(Cmn("yyyy-MM-dd'T'HH:mm",bF(Hat))),new Km(Cmn("yyyy-MM-dd",bF(Hat)))])}catch(n){if(!F$(n=Ehn(n),82))throw hv(n)}}function eXn(n,t){var e,i,r;if(i=0!=uRn(n.d,1),0==rHn(n,t)&&oM(gK(oIn(t.j,(GYn(),Bpt)))))return 0;!oM(gK(oIn(t.j,(GYn(),Bpt))))&&!oM(gK(oIn(t.j,mmt)))||xA(oIn(t.j,(jYn(),Syt)))===xA((yvn(),Fjt))?t.c.mg(t.e,i):i=oM(gK(oIn(t.j,Bpt))),PKn(n,t,i,!0),oM(gK(oIn(t.j,mmt)))&&kfn(t.j,mmt,(qx(),!1)),oM(gK(oIn(t.j,Bpt)))&&(kfn(t.j,Bpt,(qx(),!1)),kfn(t.j,mmt,!0)),e=rHn(n,t);do{if(Gon(n),0==e)return 0;r=e,PKn(n,t,i=!i,!1),e=rHn(n,t)}while(r>e);return r}function iXn(n,t){var e,i,r;if(i=0!=uRn(n.d,1),0==BAn(n,t)&&oM(gK(oIn(t.j,(GYn(),Bpt)))))return 0;!oM(gK(oIn(t.j,(GYn(),Bpt))))&&!oM(gK(oIn(t.j,mmt)))||xA(oIn(t.j,(jYn(),Syt)))===xA((yvn(),Fjt))?t.c.mg(t.e,i):i=oM(gK(oIn(t.j,Bpt))),PKn(n,t,i,!0),oM(gK(oIn(t.j,mmt)))&&kfn(t.j,mmt,(qx(),!1)),oM(gK(oIn(t.j,Bpt)))&&(kfn(t.j,Bpt,(qx(),!1)),kfn(t.j,mmt,!0)),e=BAn(n,t);do{if(Gon(n),0==e)return 0;r=e,PKn(n,t,i=!i,!1),e=BAn(n,t)}while(r>e);return r}function rXn(n,t,i,r){var c,a,o,u,s,h,f,l,b;return h=(s=YF(new MO(i.a,i.b),n)).a*t.b-s.b*t.a,f=t.a*r.b-t.b*r.a,l=(s.a*r.b-s.b*r.a)/f,b=h/f,0==f?0==h?(a=atn(n,c=JF(new MO(i.a,i.b),vD(new MO(r.a,r.b),.5))),o=atn(JF(new MO(n.a,n.b),t),c),u=.5*e.Math.sqrt(r.a*r.a+r.b*r.b),a=0&&l<=1&&b>=0&&b<=1?JF(new MO(n.a,n.b),vD(new MO(t.a,t.b),l)):null}function cXn(n,t,e){var i,r,c,a,o;if(i=uG(oIn(n,(jYn(),Pyt)),21),e.a>t.a&&(i.Hc((ZSn(),VNt))?n.c.a+=(e.a-t.a)/2:i.Hc(QNt)&&(n.c.a+=e.a-t.a)),e.b>t.b&&(i.Hc((ZSn(),YNt))?n.c.b+=(e.b-t.b)/2:i.Hc(JNt)&&(n.c.b+=e.b-t.b)),uG(oIn(n,(GYn(),Hpt)),21).Hc((r_n(),tpt))&&(e.a>t.a||e.b>t.b))for(o=new Ww(n.a);o.at.a&&(i.Hc((ZSn(),VNt))?n.c.a+=(e.a-t.a)/2:i.Hc(QNt)&&(n.c.a+=e.a-t.a)),e.b>t.b&&(i.Hc((ZSn(),YNt))?n.c.b+=(e.b-t.b)/2:i.Hc(JNt)&&(n.c.b+=e.b-t.b)),uG(oIn(n,(GYn(),Hpt)),21).Hc((r_n(),tpt))&&(e.a>t.a||e.b>t.b))for(a=new Ww(n.a);a.a0?n.i:0)>t&&s>0&&(a=0,o+=s+n.i,c=e.Math.max(c,b),r+=s+n.i,s=0,b=0,i&&(++l,kD(n.n,new c0(n.s,o,n.i))),u=0),b+=h.g+(u>0?n.i:0),s=e.Math.max(s,h.f),i&&zMn(uG(zq(n.n,l),209),h),a+=h.g+(u>0?n.i:0),++u;return c=e.Math.max(c,b),r+=s,i&&(n.r=c,n.d=r,ijn(n.j)),new gY(n.s,n.t,c,r)}function sXn(n){var t,i,r,c,a,o,u,s,h,f,l;for(n.b=!1,f=M0n,u=T0n,l=M0n,s=T0n,i=n.e.a.ec().Kc();i.Ob();)for(r=(t=uG(i.Pb(),272)).a,f=e.Math.min(f,r.c),u=e.Math.max(u,r.c+r.b),l=e.Math.min(l,r.d),s=e.Math.max(s,r.d+r.a),a=new Ww(t.c);a.an.o.a&&(f=(s-n.o.a)/2,u.b=e.Math.max(u.b,f),u.c=e.Math.max(u.c,f))}}function wXn(n){var t,e,i,r,c,a;for(YL(r=new r4,(Whn(),YLt)),i=new Jw(new IM(new JE(n,Yon(n,Inn($ot,zZn,2,0,6,1))).b));i.bo?1:-1:Hln(n.a,t.a,c)))f=-u,h=a==u?t7(t.a,o,n.a,c):Cnn(t.a,o,n.a,c);else if(f=a,a==u){if(0==r)return cHn(),_ot;h=t7(n.a,c,t.a,o)}else h=Cnn(n.a,c,t.a,o);return K4(s=new VV(f,h.length,h)),s}function vXn(n,t){var e,i,r;if(r=PGn(t),!t.c&&(t.c=new fV(wFt,t,9,9)),kS(new fX(null,(!t.c&&(t.c=new fV(wFt,t,9,9)),new h3(t.c,16))),new Jd(r)),CWn(t,i=uG(oIn(r,(GYn(),Hpt)),21)),i.Hc((r_n(),tpt)))for(e=new DD((!t.c&&(t.c=new fV(wFt,t,9,9)),t.c));e.e!=e.i.gc();)pQn(n,t,r,uG(Zkn(e),123));return 0!=uG(zDn(t,(jYn(),DMt)),181).gc()&&u_n(t,r),oM(gK(oIn(r,HMt)))&&i.Fc(apt),vR(r,fTt)&&iM(new omn(uM(pK(oIn(r,fTt)))),r),xA(zDn(t,rMt))===xA((Own(),Ixt))?UYn(n,t,r):dYn(n,t,r),r}function kXn(n){var t,e,i,r,c,a,o;for(i=new Ww(n.b);i.a0?r1(e.a,0,c-1):"":(Knn(0,c-1,n.length),n.substr(0,c-1)):e?e.a:n}function MXn(n,t){var e,i,r,c,a,o,u;for(t.Ug("Sort By Input Model "+oIn(n,(jYn(),Syt)),1),r=0,i=new Ww(n.b);i.a=n.b.length?(c[r++]=a.b[i++],c[r++]=a.b[i++]):i>=a.b.length?(c[r++]=n.b[e++],c[r++]=n.b[e++]):a.b[i]0?n.i:0)),++t;for(dgn(n.n,s),n.d=i,n.r=r,n.g=0,n.f=0,n.e=0,n.o=M0n,n.p=M0n,a=new Ww(n.b);a.a0&&(!(r=(!n.n&&(n.n=new fV(lFt,n,1,7)),uG(zrn(n.n,0),135)).a)||JA(JA((t.a+=' "',t),r),'"'))),!n.b&&(n.b=new f_(cFt,n,4,7)),e=!(n.b.i<=1&&(!n.c&&(n.c=new f_(cFt,n,5,8)),n.c.i<=1)),t.a+=e?" [":" ",JA(t,KD(new FM,new DD(n.b))),e&&(t.a+="]"),t.a+=Y4n,e&&(t.a+="["),JA(t,KD(new FM,new DD(n.c))),e&&(t.a+="]"),t.a)}function PXn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E;for(k=n.c,y=t.c,e=Ten(k.a,n,0),i=Ten(y.a,t,0),m=uG(jmn(n,(can(),Vjt)).Kc().Pb(),12),j=uG(jmn(n,Wjt).Kc().Pb(),12),v=uG(jmn(t,Vjt).Kc().Pb(),12),E=uG(jmn(t,Wjt).Kc().Pb(),12),g=x4(m.e),M=x4(j.g),p=x4(v.e),T=x4(E.g),$jn(n,i,y),s=0,b=(c=p).length;sh?new A2((_7(),DSt),i,t,s-h):s>0&&h>0&&(new A2((_7(),DSt),t,i,0),new A2(DSt,i,t,0))),a)}function AXn(n,t,e){var i,r,c;for(n.a=new Zm,c=Fkn(t.b,0);c.b!=c.d.c;){for(r=uG(I6(c),40);uG(oIn(r,(QGn(),ACt)),17).a>n.a.c.length-1;)kD(n.a,new WO(B3n,G9n));i=uG(oIn(r,ACt),17).a,e==(xdn(),JDt)||e==YDt?(r.e.auM(pK(uG(zq(n.a,i),42).b))&&sw(uG(zq(n.a,i),42),r.e.a+r.f.a)):(r.e.buM(pK(uG(zq(n.a,i),42).b))&&sw(uG(zq(n.a,i),42),r.e.b+r.f.b))}}function LXn(n,t,e,i){var r,c,a,o,u,s;if(c=pgn(i),!oM(gK(oIn(i,(jYn(),jMt))))&&!oM(gK(oIn(n,uMt)))||sN(uG(oIn(n,JMt),101)))switch(o2(o=new lOn,n),t?((s=o.n).a=t.a-n.n.a,s.b=t.b-n.n.b,DOn(s,0,0,n.o.a,n.o.b),NLn(o,nGn(o,c))):(r=Ipn(c),NLn(o,e==(can(),Wjt)?r:Gdn(r))),a=uG(oIn(i,(GYn(),Hpt)),21),u=o.j,c.g){case 2:case 1:(u==(KQn(),yRt)||u==KRt)&&a.Fc((r_n(),cpt));break;case 4:case 3:(u==(KQn(),kRt)||u==_Rt)&&a.Fc((r_n(),cpt))}else r=Ipn(c),o=zUn(n,e,e==(can(),Wjt)?r:Gdn(r));return o}function NXn(n,t){var i,r,c,a,o;for(o=new bsn(new Nw(n.f.b).a);o.b;){if(c=uG((a=von(o)).ld(),602),1==t){if(c.Af()!=(xdn(),nxt)&&c.Af()!=QDt)continue}else if(c.Af()!=(xdn(),JDt)&&c.Af()!=YDt)continue;switch(r=uG(uG(a.md(),42).b,86),i=uG(uG(a.md(),42).a,194).c,c.Af().g){case 2:r.g.c=n.e.a,r.g.b=e.Math.max(1,r.g.b+i);break;case 1:r.g.c=r.g.c+i,r.g.b=e.Math.max(1,r.g.b-i);break;case 4:r.g.d=n.e.b,r.g.a=e.Math.max(1,r.g.a+i);break;case 3:r.g.d=r.g.d+i,r.g.a=e.Math.max(1,r.g.a-i)}}}function $Xn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g;for(u=Inn(YHt,W1n,28,t.b.c.length,15,1),h=Inn(vbt,p1n,273,t.b.c.length,0,1),s=Inn(pbt,e6n,10,t.b.c.length,0,1),b=0,w=(l=n.a).length;b0&&s[r]&&(d=y$(n.b,s[r],c)),g=e.Math.max(g,c.c.c.b+d);for(a=new Ww(f.e);a.a1)throw hv(new vM(dct));u||(c=R5(t,i.Kc().Pb()),a.Fc(c))}return bfn(n,sAn(n,t,e),a)}function BXn(n,t,e){var i,r,c,a,o,u,s;if(EFn(n.e,t))PP(),C$n((o=uG(t,69).xk()?new Cq(t,n):new OA(t,n)).c,o.b),K$(o,uG(e,16));else{for(s=VKn(n.e.Dh(),t),i=uG(n.g,124),c=0;c"}null!=u&&(t.a+=""+u)}else n.e?null!=(o=n.e.zb)&&(t.a+=""+o):(t.a+="?",n.b?(t.a+=" super ",XXn(n.b,t)):n.f&&(t.a+=" extends ",XXn(n.f,t)))}function zXn(n){n.b=null,n.a=null,n.o=null,n.q=null,n.v=null,n.w=null,n.B=null,n.p=null,n.Q=null,n.R=null,n.S=null,n.T=null,n.U=null,n.V=null,n.W=null,n.bb=null,n.eb=null,n.ab=null,n.H=null,n.db=null,n.c=null,n.d=null,n.f=null,n.n=null,n.r=null,n.s=null,n.u=null,n.G=null,n.J=null,n.e=null,n.j=null,n.i=null,n.g=null,n.k=null,n.t=null,n.F=null,n.I=null,n.L=null,n.M=null,n.O=null,n.P=null,n.$=null,n.N=null,n.Z=null,n.cb=null,n.K=null,n.D=null,n.A=null,n.C=null,n._=null,n.fb=null,n.X=null,n.Y=null,n.gb=!1,n.hb=!1}function VXn(n){var t,i,r,c;if(r=bYn((!n.c&&(n.c=j2(Bsn(n.f))),n.c),0),0==n.e||0==n.a&&-1!=n.f&&n.e<0)return r;if(t=nun(n)<0?1:0,i=n.e,r.length,e.Math.abs(t0(n.e)),c=new QM,1==t&&(c.a+="-"),n.e>0)if((i-=r.length-t)>=0){for(c.a+="0.";i>Pot.length;i-=Pot.length)Xq(c,Pot);lF(c,Pot,t0(i)),JA(c,(s3(t,r.length+1),r.substr(t)))}else JA(c,r1(r,t,t0(i=t-i))),c.a+=".",JA(c,sQ(r,t0(i)));else{for(JA(c,(s3(t,r.length+1),r.substr(t)));i<-Pot.length;i+=Pot.length)Xq(c,Pot);lF(c,Pot,t0(-i))}return c.a}function WXn(n){var t,e,i,r,c;if(n.k!=(zIn(),dbt))return!1;if(n.j.c.length<=1)return!1;if(uG(oIn(n,(jYn(),JMt)),101)==($Pn(),cRt))return!1;if(Yyn(),(i=(n.q?n.q:(hZ(),hZ(),Vot))._b(LMt)?uG(oIn(n,LMt),203):uG(oIn(HQ(n),NMt),203))==djt)return!1;if(i!=wjt&&i!=bjt){if(r=uM(pK(Omn(n,ITt))),!(t=uG(oIn(n,CTt),140))&&(t=new OF(r,r,r,r)),c=Dgn(n,(KQn(),_Rt)),t.d+t.a+(c.gc()-1)*r>n.o.b)return!1;if(e=Dgn(n,kRt),t.d+t.a+(e.gc()-1)*r>n.o.b)return!1}return!0}function QXn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d;t.Ug("Orthogonal edge routing",1),s=uM(pK(oIn(n,(jYn(),STt)))),e=uM(pK(oIn(n,gTt))),i=uM(pK(oIn(n,vTt))),l=new NW(0,e),d=0,a=new N4(n.b,0),o=null,h=null,u=null,f=null;do{f=(h=a.b0?(b=(w-1)*e,o&&(b+=i),h&&(b+=i),bt||oM(gK(zDn(o,(S_n(),nAt)))))&&(r=0,c+=s.b+e,mv(h.c,s),fan(s=new e4(c,e),i=new dln(0,s.f,s,e)),r=0),0==i.b.c.length||!oM(gK(zDn(R0(o),(S_n(),uAt))))&&(o.f>=i.o&&o.f<=i.f||.5*i.a<=o.f&&1.5*i.a>=o.f)?ipn(i,o):(fan(s,a=new dln(i.s+i.r+e,s.f,s,e)),ipn(a,o)),r=o.i+o.g;return mv(h.c,s),h}function szn(n){var t,e,i,r;if(!(null==n.b||n.b.length<=2||n.a)){for(t=0,r=0;r=n.b[r+1])r+=2;else{if(!(e0)for(i=new Z_(uG(Y9(n.a,c),21)),hZ(),f$(i,new Gd(t)),r=new N4(c.b,0);r.b0&&i>=-6?i>=0?Ex(c,e-t0(n.e),String.fromCharCode(46)):(psn(c,t-1,t-1,"0."),Ex(c,t+1,mvn(Pot,0,-t0(i)-1))):(e-t>=1&&(Ex(c,t,String.fromCharCode(46)),++e),Ex(c,e,String.fromCharCode(69)),i>0&&Ex(c,++e,String.fromCharCode(43)),Ex(c,++e,""+oV(Bsn(i)))),n.g=c.a,n.g))}function gzn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T;r=uM(pK(oIn(t,(jYn(),AMt)))),l=4,c=3,M=20/(y=uG(oIn(t,OTt),17).a),b=!1,s=0,o=vZn;do{for(a=1!=s,f=0!=s,T=0,m=0,k=(g=n.a).length;my)?(s=2,o=vZn):0==s?(s=1,o=T):(s=0,o=T):(b=T>=o||o-T0?1:KL(isNaN(r),isNaN(0)))>=0^(oan(I9n),(e.Math.abs(u)<=I9n||0==u||isNaN(u)&&isNaN(0)?0:u<0?-1:u>0?1:KL(isNaN(u),isNaN(0)))>=0)?e.Math.max(u,r):(oan(I9n),(e.Math.abs(r)<=I9n||0==r||isNaN(r)&&isNaN(0)?0:r<0?-1:r>0?1:KL(isNaN(r),isNaN(0)))>0?e.Math.sqrt(u*u+r*r):-e.Math.sqrt(u*u+r*r))}function kzn(n,t){var e,i,r,c,a;if(t)if(!n.a&&(n.a=new ck),2!=n.e)if(1!=t.e)0!=(a=n.a.a.c.length)?0!=(c=uG(DQ(n.a,a-1),122)).e&&10!=c.e||0!=t.e&&10!=t.e?zv(n.a,t):(0==t.e||t.Mm().length,0==c.e?(e=new VM,(i=c.Km())>=P0n?VA(e,Ogn(i)):TQ(e,i&D1n),c=new F1(10,null,0),GV(n.a,c,a-1)):(c.Mm().length,VA(e=new VM,c.Mm())),0==t.e?(i=t.Km())>=P0n?VA(e,Ogn(i)):TQ(e,i&D1n):VA(e,t.Mm()),uG(c,530).b=e.a):zv(n.a,t);else for(r=0;r1&&(u=s.Hg(u,n.a,o));return 1==u.c.length?uG(zq(u,u.c.length-1),238):2==u.c.length?ezn((u3(0,u.c.length),uG(u.c[0],238)),(u3(1,u.c.length),uG(u.c[1],238)),a,c):null}function Ezn(n,t,e){var i,r,c,a,o,u,s;for(e.Ug("Find roots",1),n.a.c.length=0,r=Fkn(t.b,0);r.b!=r.d.c;)0==(i=uG(I6(r),40)).b.b&&(kfn(i,(OQn(),UPt),(qx(),!0)),kD(n.a,i));switch(n.a.c.length){case 0:kfn(c=new wln(0,t,"DUMMY_ROOT"),(OQn(),UPt),(qx(),!0)),kfn(c,jPt,!0),aq(t.b,c);break;case 1:break;default:for(a=new wln(0,t,H9n),u=new Ww(n.a);u.a=e.Math.abs(r.b)?(r.b=0,a.d+a.a>o.d&&a.do.c&&a.c0){if(t=new AA(n.i,n.g),c=(e=n.i)<100?null:new cj(e),n.Tj())for(i=0;i0){for(o=n.g,s=n.i,V9(n),c=s<100?null:new cj(s),i=0;i>13|(15&n.m)<<9,r=n.m>>4&8191,c=n.m>>17|(255&n.h)<<5,a=(1048320&n.h)>>8,g=i*(o=8191&t.l),p=r*o,m=c*o,v=a*o,0!=(u=t.l>>13|(15&t.m)<<9)&&(g+=e*u,p+=i*u,m+=r*u,v+=c*u),0!=(s=t.m>>4&8191)&&(p+=e*s,m+=i*s,v+=r*s),0!=(h=t.m>>17|(255&t.h)<<5)&&(m+=e*h,v+=i*h),0!=(f=(1048320&t.h)>>8)&&(v+=e*f),b=((d=e*o)>>22)+(g>>9)+((262143&p)<<4)+((31&m)<<17),w=(p>>18)+(m>>5)+((4095&v)<<8),w+=(b+=(l=(d&f0n)+((511&g)<<13))>>22)>>22,p$(l&=f0n,b&=f0n,w&=l0n)}function Azn(n){var t,i,r,c,a,o,u;if(0!=(u=uG(zq(n.j,0),12)).g.c.length&&0!=u.e.c.length)throw hv(new kM("Interactive layout does not support NORTH/SOUTH ports with incoming _and_ outgoing edges."));if(0!=u.g.c.length){for(a=M0n,i=new Ww(u.g);i.a4){if(!n.fk(t))return!1;if(n.al()){if(o=(e=(i=uG(t,54)).Eh())==n.e&&(n.ml()?i.yh(i.Fh(),n.il())==n.jl():-1-i.Fh()==n.Lj()),n.nl()&&!o&&!e&&i.Jh())for(r=0;r0&&nAn(n,o,h);for(r=new Ww(h);r.an.d[r.p]&&(e+=J8(n.b,i)*uG(a.b,17).a,A6(n.a,xwn(i)));for(;!LM(n.a);)lin(n.b,uG(xV(n.a),17).a)}return e}function Dzn(n,t){var e,i,r,c,a,o,u,s,h,f;if(h=uG(oIn(n,(GYn(),Fpt)),64),i=uG(zq(n.j,0),12),h==(KQn(),yRt)?NLn(i,KRt):h==KRt&&NLn(i,yRt),uG(oIn(t,(jYn(),DMt)),181).Hc((Qmn(),JRt))){if(u=uM(pK(oIn(n,TTt))),s=uM(pK(oIn(n,jTt))),a=uM(pK(oIn(n,yTt))),(o=uG(oIn(t,nTt),21)).Hc((eNn(),wRt)))for(e=s,f=n.o.a/2-i.n.a,c=new Ww(i.f);c.a0&&(s=n.n.a/c);break;case 2:case 4:(r=n.i.o.b)>0&&(s=n.n.b/r)}kfn(n,(GYn(),bmt),s)}if(u=n.o,a=n.a,i)a.a=i.a,a.b=i.b,n.d=!0;else if(t!=uRt&&t!=sRt&&o!=FRt)switch(o.g){case 1:a.a=u.a/2;break;case 2:a.a=u.a,a.b=u.b/2;break;case 3:a.a=u.a/2,a.b=u.b;break;case 4:a.b=u.b/2}else a.a=u.a/2,a.b=u.b/2}function _zn(n){var t,e,i,r,c,a,o,u,s,h;if(n.Pj())if(h=n.Ej(),u=n.Qj(),h>0)if(t=new Hun(n.pj()),c=(e=h)<100?null:new cj(e),QK(n,e,t.g),r=1==e?n.Ij(4,zrn(t,0),null,0,u):n.Ij(6,t,null,-1,u),n.Mj()){for(i=new DD(t);i.e!=i.i.gc();)c=n.Oj(Zkn(i),c);c?(c.nj(r),c.oj()):n.Jj(r)}else c?(c.nj(r),c.oj()):n.Jj(r);else QK(n,n.Ej(),n.Fj()),n.Jj(n.Ij(6,(hZ(),zot),null,-1,u));else if(n.Mj())if((h=n.Ej())>0){for(o=n.Fj(),s=h,QK(n,h,o),c=s<100?null:new cj(s),i=0;i1&&EX(a)*jX(a)/2>o[0]){for(c=0;co[c];)++c;f=new Jrn(new C2(b,0,c+1)),h=EX(a)/jX(a),u=KJn(f,t,new Dk,e,i,r,h),JF(dL(f.e),u),kG(_Cn(l,f),D0n),_jn(l,new C2(b,c+1,b.c.length)),b.c.length=0,s=0,zX(o,o.length,0)}else null!=(0==l.b.c.length?null:zq(l.b,0))&&Con(l,0),s>0&&(o[s]=o[s-1]),o[s]+=EX(a)*jX(a),++s,mv(b.c,a);return b}function Hzn(n,t){var e,i,r,c;c=new Z_((e=t.b).j),r=0,(i=e.j).c.length=0,mW(uG(ssn(n.b,(KQn(),yRt),(gon(),Sdt)),15),e),r=cMn(c,r,new Br,i),mW(uG(ssn(n.b,yRt,Edt),15),e),r=cMn(c,r,new $r,i),mW(uG(ssn(n.b,yRt,jdt),15),e),mW(uG(ssn(n.b,kRt,Sdt),15),e),mW(uG(ssn(n.b,kRt,Edt),15),e),r=cMn(c,r,new Hr,i),mW(uG(ssn(n.b,kRt,jdt),15),e),mW(uG(ssn(n.b,KRt,Sdt),15),e),r=cMn(c,r,new Ur,i),mW(uG(ssn(n.b,KRt,Edt),15),e),r=cMn(c,r,new Gr,i),mW(uG(ssn(n.b,KRt,jdt),15),e),mW(uG(ssn(n.b,_Rt,Sdt),15),e),r=cMn(c,r,new Rr,i),mW(uG(ssn(n.b,_Rt,Edt),15),e),mW(uG(ssn(n.b,_Rt,jdt),15),e)}function Uzn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b;for(o=new Ww(t);o.a.5?p-=2*a*(w-.5):w<.5&&(p+=2*c*(.5-w)),p<(r=o.d.b)&&(p=r),d=o.d.c,p>g.a-d-h&&(p=g.a-d-h),o.n.a=t+p}}function Wzn(n){var t,e,i;if((e=uG(oIn(n,(jYn(),gMt)),171))==(Gpn(),Imt)){for(t=new Fz(ix(qgn(n).a.Kc(),new h));hDn(t);)if(!F9(uG(N9(t),18)))throw hv(new jM(y6n+ZTn(n)+"' has its layer constraint set to FIRST_SEPARATE, but has at least one incoming edge. FIRST_SEPARATE nodes must not have incoming edges."))}else if(e==Amt)for(i=new Fz(ix(Xgn(n).a.Kc(),new h));hDn(i);)if(!F9(uG(N9(i),18)))throw hv(new jM(y6n+ZTn(n)+"' has its layer constraint set to LAST_SEPARATE, but has at least one outgoing edge. LAST_SEPARATE nodes must not have outgoing edges."))}function Qzn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w;if(n.e&&n.c.c>19&&(t=gfn(t),u=!u),a=kRn(t),c=!1,r=!1,i=!1,n.h==b0n&&0==n.m&&0==n.l){if(r=!0,c=!0,-1!=a)return o=gDn(n,a),u&&Yfn(o),e&&(Qat=p$(0,0,0)),o;n=LL((tin(),Jat)),i=!0,u=!u}else n.h>>19&&(c=!0,n=gfn(n),i=!0,u=!u);return-1!=a?nln(n,a,u,c,e):yEn(n,t)<0?(e&&(Qat=c?gfn(n):p$(n.l,n.m,n.h)),p$(0,0,0)):pUn(i?n:p$(n.l,n.m,n.h),t,u,c,r,e)}function Zzn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w;if(a=n.e,u=t.e,0==a)return t;if(0==u)return n;if((c=n.d)+(o=t.d)==2)return e=E3(n.a[0],L0n),i=E3(t.a[0],L0n),a==u?(w=pz(h=Lgn(e,i)),0==(b=pz(Dz(h,32)))?new Z5(a,w):new VV(a,2,Uhn(cT(YHt,1),W1n,28,15,[w,b]))):(cHn(),BA(a<0?$gn(i,e):$gn(e,i),0)?Rmn(a<0?$gn(i,e):$gn(e,i)):hW(Rmn(Men(a<0?$gn(i,e):$gn(e,i)))));if(a==u)l=a,f=c>=o?Cnn(n.a,c,t.a,o):Cnn(t.a,o,n.a,c);else{if(0==(r=c!=o?c>o?1:-1:Hln(n.a,t.a,c)))return cHn(),_ot;1==r?(l=a,f=t7(n.a,c,t.a,o)):(l=u,f=t7(t.a,o,n.a,c))}return K4(s=new VV(l,f.length,f)),s}function nVn(n,t){var e,i,r,c,a,o,u;if(!(n.g>t.f||t.g>n.f)){for(e=0,i=0,a=n.w.a.ec().Kc();a.Ob();)r=uG(a.Pb(),12),Wbn(Gfn(Uhn(cT(PNt,1),zZn,8,0,[r.i.n,r.n,r.a])).b,t.g,t.f)&&++e;for(o=n.r.a.ec().Kc();o.Ob();)r=uG(o.Pb(),12),Wbn(Gfn(Uhn(cT(PNt,1),zZn,8,0,[r.i.n,r.n,r.a])).b,t.g,t.f)&&--e;for(u=t.w.a.ec().Kc();u.Ob();)r=uG(u.Pb(),12),Wbn(Gfn(Uhn(cT(PNt,1),zZn,8,0,[r.i.n,r.n,r.a])).b,n.g,n.f)&&++i;for(c=t.r.a.ec().Kc();c.Ob();)r=uG(c.Pb(),12),Wbn(Gfn(Uhn(cT(PNt,1),zZn,8,0,[r.i.n,r.n,r.a])).b,n.g,n.f)&&--i;e=0)return e;switch(sJ(Nen(n,e))){case 2:if(m_("",tdn(n,e.qk()).xe())){if(u=hxn(n,t,o=HJ(Nen(n,e)),BJ(Nen(n,e))))return u;for(a=0,s=(r=AHn(n,t)).gc();a1)throw hv(new vM(dct));for(h=VKn(n.e.Dh(),t),i=uG(n.g,124),a=0;a1,h=new w7(b.b);l$(h.a)||l$(h.b);)l=(s=uG(l$(h.a)?N3(h.a):N3(h.b),18)).c==b?s.d:s.c,e.Math.abs(Gfn(Uhn(cT(PNt,1),zZn,8,0,[l.i.n,l.n,l.a])).b-o.b)>1&&sFn(n,s,o,a,b)}}function oVn(n){var t,i,r,c,a,o;if(c=new N4(n.e,0),r=new N4(n.a,0),n.d)for(i=0;i$9n;){for(a=t,o=0;e.Math.abs(t-a)<$9n;)++o,t=uM((MK(c.b0),c.a.Xb(c.c=--c.b),zGn(n,n.b-o,a,r,c),MK(c.b0),r.a.Xb(r.c=--r.b)}if(!n.d)for(i=0;i0?(n.f[s.p]=l/(s.e.c.length+s.g.c.length),n.c=e.Math.min(n.c,n.f[s.p]),n.b=e.Math.max(n.b,n.f[s.p])):o&&(n.f[s.p]=l)}}function hVn(n){n.b=null,n.bb=null,n.fb=null,n.qb=null,n.a=null,n.c=null,n.d=null,n.e=null,n.f=null,n.n=null,n.M=null,n.L=null,n.Q=null,n.R=null,n.K=null,n.db=null,n.eb=null,n.g=null,n.i=null,n.j=null,n.k=null,n.gb=null,n.o=null,n.p=null,n.q=null,n.r=null,n.$=null,n.ib=null,n.S=null,n.T=null,n.t=null,n.s=null,n.u=null,n.v=null,n.w=null,n.B=null,n.A=null,n.C=null,n.D=null,n.F=null,n.G=null,n.H=null,n.I=null,n.J=null,n.P=null,n.Z=null,n.U=null,n.V=null,n.W=null,n.X=null,n.Y=null,n._=null,n.ab=null,n.cb=null,n.hb=null,n.nb=null,n.lb=null,n.mb=null,n.ob=null,n.pb=null,n.jb=null,n.kb=null,n.N=!1,n.O=!1}function fVn(n,t,e){var i,r;for(e.Ug("Graph transformation ("+n.a+")",1),r=T3(t.a),i=new Ww(t.b);i.a=o.b.c)&&(o.b=t),(!o.c||t.c<=o.c.c)&&(o.d=o.c,o.c=t),(!o.e||t.d>=o.e.d)&&(o.e=t),(!o.f||t.d<=o.f.d)&&(o.f=t);return i=new cyn((Xhn(),Flt)),O4(n,Vlt,new IM(Uhn(cT(Klt,1),EZn,382,0,[i]))),a=new cyn(Hlt),O4(n,zlt,new IM(Uhn(cT(Klt,1),EZn,382,0,[a]))),r=new cyn(_lt),O4(n,Xlt,new IM(Uhn(cT(Klt,1),EZn,382,0,[r]))),c=new cyn(Blt),O4(n,qlt,new IM(Uhn(cT(Klt,1),EZn,382,0,[c]))),jRn(i.c,Flt),jRn(r.c,_lt),jRn(c.c,Blt),jRn(a.c,Hlt),o.a.c.length=0,Ohn(o.a,i.c),Ohn(o.a,Spn(r.c)),Ohn(o.a,c.c),Ohn(o.a,Spn(a.c)),o}function wVn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d;for(t.Ug(snt,1),w=uM(pK(zDn(n,(lBn(),POt)))),o=uM(pK(zDn(n,(S_n(),bAt)))),u=uG(zDn(n,hAt),107),Non((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a)),f=uzn((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a),w,o),!n.a&&(n.a=new fV(bFt,n,10,11)),h=new Ww(f);h.a0&&(n.a=o+(l-1)*r,t.c.b+=n.a,t.f.b+=n.a),0!=b.a.gc()&&(l=YVn(new NW(1,r),t,b,w,t.f.b+o-t.c.b))>0&&(t.f.b+=o+(l-1)*r)}function gVn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y;for(f=uM(pK(oIn(n,(jYn(),mTt)))),r=uM(pK(oIn(n,RTt))),kfn(b=new Qu,mTt,f+r),m=(h=t).d,g=h.c.i,v=h.d.i,p=GL(g.c),k=GL(v.c),c=new Zm,l=p;l<=k;l++)Hb(u=new gMn(n),(zIn(),wbt)),kfn(u,(GYn(),rmt),h),kfn(u,JMt,($Pn(),cRt)),kfn(u,kTt,b),w=uG(zq(n.b,l),30),l==p?$jn(u,w.a.c.length-i,w):a2(u,w),(y=uM(pK(oIn(h,tMt))))<0&&kfn(h,tMt,y=0),u.o.b=y,d=e.Math.floor(y/2),NLn(o=new lOn,(KQn(),_Rt)),o2(o,u),o.n.b=d,NLn(s=new lOn,kRt),o2(s,u),s.n.b=d,u2(h,o),zsn(a=new UZ,h),kfn(a,bMt,null),c2(a,s),u2(a,m),IEn(u,h,a),mv(c.c,a),h=a;return c}function pVn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g;for(o=uG(yOn(n,(KQn(),_Rt)).Kc().Pb(),12).e,f=uG(yOn(n,kRt).Kc().Pb(),12).g,a=o.c.length,g=n3(uG(zq(n.j,0),12));a-- >0;){for(u3(0,o.c.length),b=uG(o.c[0],18),u3(0,f.c.length),r=Ten((i=uG(f.c[0],18)).d.e,i,0),w6(b,i.d,r),c2(i,null),u2(i,null),l=b.a,t&&aq(l,new eN(g)),e=Fkn(i.a,0);e.b!=e.d.c;)aq(l,new eN(uG(I6(e),8)));for(d=b.b,h=new Ww(i.b);h.aa)&&FV(n.b,uG(g.b,18));++o}c=a}}}function vVn(n,t){var e;if(null==t||m_(t,IZn))return null;if(0==t.length&&n.k!=(lAn(),pNt))return null;switch(n.k.g){case 1:return Bvn(t,Fnt)?(qx(),eot):Bvn(t,_nt)?(qx(),tot):null;case 2:try{return xwn(vUn(t,j1n,vZn))}catch(i){if(F$(i=Ehn(i),130))return null;throw hv(i)}case 4:try{return YIn(t)}catch(i){if(F$(i=Ehn(i),130))return null;throw hv(i)}case 3:return t;case 5:return wbn(n),NNn(n,t);case 6:return wbn(n),Lxn(n,n.a,t);case 7:try{return(e=Q$n(n)).cg(t),e}catch(i){if(F$(i=Ehn(i),33))return null;throw hv(i)}default:throw hv(new kM("Invalid type set for this layout option."))}}function kVn(n){var t;switch(n.d){case 1:if(n.Sj())return-2!=n.o;break;case 2:if(n.Sj())return-2==n.o;break;case 3:case 5:case 4:case 6:case 7:return n.o>-2;default:return!1}switch(t=n.Rj(),n.p){case 0:return null!=t&&oM(gK(t))!=HA(n.k,0);case 1:return null!=t&&uG(t,222).a!=pz(n.k)<<24>>24;case 2:return null!=t&&uG(t,180).a!=(pz(n.k)&D1n);case 6:return null!=t&&HA(uG(t,168).a,n.k);case 5:return null!=t&&uG(t,17).a!=pz(n.k);case 7:return null!=t&&uG(t,191).a!=pz(n.k)<<16>>16;case 3:return null!=t&&uM(pK(t))!=n.j;case 4:return null!=t&&uG(t,161).a!=n.j;default:return null==t?null!=n.n:!udn(t,n.n)}}function yVn(n,t,e){var i,r,c,a;return n.ol()&&n.nl()&&xA(a=CV(n,uG(e,58)))!==xA(e)?(n.xj(t),n.Dj(t,Atn(n,t,a)),n.al()&&(r=uG(e,54),c=n.ml()?n.kl()?r.Th(n.b,lMn(uG(ern(e1(n.b),n.Lj()),19)).n,uG(ern(e1(n.b),n.Lj()).Hk(),29).kk(),null):r.Th(n.b,emn(r.Dh(),lMn(uG(ern(e1(n.b),n.Lj()),19))),null,null):r.Th(n.b,-1-n.Lj(),null,null),!uG(a,54).Ph()&&(i=uG(a,54),c=n.ml()?n.kl()?i.Rh(n.b,lMn(uG(ern(e1(n.b),n.Lj()),19)).n,uG(ern(e1(n.b),n.Lj()).Hk(),29).kk(),c):i.Rh(n.b,emn(i.Dh(),lMn(uG(ern(e1(n.b),n.Lj()),19))),null,c):i.Rh(n.b,-1-n.Lj(),null,c)),c&&c.oj()),uN(n.b)&&n.Jj(n.Ij(9,e,a,t,!1)),a):e}function MVn(n){var t,e,i,r,c,a,o,u,s,h;for(i=new Zm,a=new Ww(n.e.a);a.a0&&(o=e.Math.max(o,run(n.C.b+r.d.b,c))),f=r,l=c,b=a;n.C&&n.C.c>0&&(w=b+n.C.c,h&&(w+=f.d.c),o=e.Math.max(o,(YN(),oan(Z2n),e.Math.abs(l-1)<=Z2n||1==l||isNaN(l)&&isNaN(1)?0:w/(1-l)))),i.n.b=0,i.a.a=o}function jVn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w;if(i=uG(AJ(n.b,t),127),(s=uG(uG(Y9(n.r,t),21),87)).dc())return i.n.d=0,void(i.n.a=0);for(h=n.u.Hc((eNn(),wRt)),o=0,n.A.Hc((Qmn(),JRt))&&kBn(n,t),u=s.Kc(),f=null,b=0,l=0;u.Ob();)a=uM(pK((r=uG(u.Pb(),117)).b.of((Gx(),bht)))),c=r.b.Mf().b,f?(w=l+f.d.a+n.w+r.d.d,o=e.Math.max(o,(YN(),oan(Z2n),e.Math.abs(b-a)<=Z2n||b==a||isNaN(b)&&isNaN(a)?0:w/(a-b)))):n.C&&n.C.d>0&&(o=e.Math.max(o,run(n.C.d+r.d.d,a))),f=r,b=a,l=c;n.C&&n.C.a>0&&(w=l+n.C.a,h&&(w+=f.d.a),o=e.Math.max(o,(YN(),oan(Z2n),e.Math.abs(b-1)<=Z2n||1==b||isNaN(b)&&isNaN(1)?0:w/(1-b)))),i.n.d=0,i.a.b=o}function EVn(n,t,e,i,r,c,a,o){var u,s,h,f,l,b,w,d;if(b=!1,u=cKn(e.q,t.f+t.b-e.q.f),l=i.f>t.b&&o,h=uXn(i,d=r-(e.q.e+u-a),!1).a,l&&h>i.f)return!1;if(l){for(f=0,w=new Ww(t.d);w.a=(u3(c,n.c.length),uG(n.c[c],186)).e,!(!l&&h>t.b&&!s)&&((s||l||h<=t.b)&&(s&&h>t.b?(e.d=h,dtn(e,EOn(e,h))):(USn(e.q,u),e.c=!0),dtn(i,r-(e.s+e.r)),oMn(i,e.q.e+e.q.d,t.f),fan(t,i),n.c.length>c&&(uEn((u3(c,n.c.length),uG(n.c[c],186)),i),0==(u3(c,n.c.length),uG(n.c[c],186)).a.c.length&&i7(n,c)),b=!0),b))}function SVn(n,t,e){var i,r,c,a,o,u;for(this.g=n,o=t.d.length,u=e.d.length,this.d=Inn(pbt,e6n,10,o+u,0,1),a=0;a0?Rrn(this,this.f/this.a):null!=oD(t.g,t.d[0]).a&&null!=oD(e.g,e.d[0]).a?Rrn(this,(uM(oD(t.g,t.d[0]).a)+uM(oD(e.g,e.d[0]).a))/2):null!=oD(t.g,t.d[0]).a?Rrn(this,oD(t.g,t.d[0]).a):null!=oD(e.g,e.d[0]).a&&Rrn(this,oD(e.g,e.d[0]).a)}function PVn(n,t){var e,i,r,c,a,o,u,s,h;for(n.a=new wQ(efn(axt)),i=new Ww(t.a);i.a=1&&(g-a>0&&f>=0?(u.n.a+=d,u.n.b+=c*a):g-a<0&&h>=0&&(u.n.a+=d*g,u.n.b+=c));n.o.a=t.a,n.o.b=t.b,kfn(n,(jYn(),DMt),(Qmn(),new nB(i=uG(Mj(sKt),9),uG(MF(i,i.length),9),0)))}function LVn(n,t,e,i,r,c){if(null!=t&&mpn(t,YFt,ZFt))throw hv(new vM("invalid scheme: "+t));if(!(n||null!=e&&-1==xL(e,$Cn(35))&&e.length>0&&(s3(0,e.length),47!=e.charCodeAt(0))))throw hv(new vM("invalid opaquePart: "+e));if(n&&(null==t||!ZE(UFt,t.toLowerCase()))&&null!=e&&mpn(e,n_t,t_t))throw hv(new vM(Vit+e));if(n&&null!=t&&ZE(UFt,t.toLowerCase())&&!bPn(e))throw hv(new vM(Vit+e));if(!Ppn(i))throw hv(new vM("invalid device: "+i));if(!Jbn(r))throw hv(new vM(null==r?"invalid segments: null":"invalid segment: "+Lbn(r)));if(null!=c&&-1!=xL(c,$Cn(35)))throw hv(new vM("invalid query: "+c))}function NVn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p;if(i.Ug("Network simplex layering",1),n.b=t,p=4*uG(oIn(t,(jYn(),OTt)),17).a,(g=n.b.a).c.length<1)i.Vg();else{for(d=null,c=Fkn(a=RHn(n,g),0);c.b!=c.d.c;){for(r=uG(I6(c),15),u=p*t0(e.Math.sqrt(r.gc())),YHn(kT(MT(yT(_B(o=dUn(r)),u),d),!0),i.eh(1)),l=n.b.b,w=new Ww(o.a);w.a1)for(d=Inn(YHt,W1n,28,n.b.b.c.length,15,1),f=0,h=new Ww(n.b.b);h.a0?(Ikn(n,e,0),e.a+=String.fromCharCode(i),Ikn(n,e,r=qvn(t,c)),c+=r-1):39==i?c+10&&w.a<=0){u.c.length=0,mv(u.c,w);break}(b=w.i-w.d)>=o&&(b>o&&(u.c.length=0,o=b),mv(u.c,w))}0!=u.c.length&&(a=uG(zq(u,iMn(r,u.c.length)),118),v.a.Bc(a),a.g=h++,UGn(a,t,e,i),u.c.length=0)}for(g=n.c.length+1,l=new Ww(n);l.aT0n||t.o==wSt&&s=o&&r<=u)o<=r&&c<=u?(e[h++]=r,e[h++]=c,i+=2):o<=r?(e[h++]=r,e[h++]=u,n.b[i]=u+1,a+=2):c<=u?(e[h++]=o,e[h++]=c,i+=2):(e[h++]=o,e[h++]=u,n.b[i]=u+1);else{if(!(uT1n)&&u<10);ET(n.c,new yt),_Vn(n),YV(n.c),lVn(n.f)}function XVn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g;for(i=uG(oIn(n,(jYn(),JMt)),101),o=n.f,a=n.d,u=o.a+a.b+a.c,s=0-a.d-n.c.b,f=o.b+a.d+a.a-n.c.b,h=new Zm,l=new Zm,c=new Ww(t);c.a=2){for(a=uG(I6(u=Fkn(e,0)),8),o=uG(I6(u),8);o.a0&&hfn(u,!0,(xdn(),YDt)),a.k==(zIn(),lbt)&&XQ(u),vJ(n.f,a,t)):((s=(i=uG(pZ(Ggn(a)),18)).c.i)==a&&(s=i.d.i),f=new WO(s,YF(D$(a.n),s.n)),vJ(n.b,a,f))}function WVn(n){var t,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v;for(i=uG(oIn(n,(OQn(),RPt)),27),u=vZn,s=vZn,a=j1n,o=j1n,m=Fkn(n.b,0);m.b!=m.d.c;)l=(g=uG(I6(m),40)).e,b=g.f,u=e.Math.min(u,l.a-b.a/2),s=e.Math.min(s,l.b-b.b/2),a=e.Math.max(a,l.a+b.a/2),o=e.Math.max(o,l.b+b.b/2);for(f=uG(zDn(i,(QGn(),pCt)),107),p=Fkn(n.b,0);p.b!=p.d.c;)F$(h=oIn(g=uG(I6(p),40),RPt),207)&&(kN(r=uG(h,27),g.e.a,g.e.b),aKn(r,g));for(d=Fkn(n.a,0);d.b!=d.d.c;)w=uG(I6(d),65),(t=uG(oIn(w,RPt),74))&&sqn(w.a,JFn(t,!0,!0));v=a-u+(f.b+f.c),c=o-s+(f.d+f.a),oM(gK(zDn(i,(XYn(),H$t))))||ZQn(i,v,c,!1,!1),Myn(i,h$t,v-(f.b+f.c)),Myn(i,s$t,c-(f.d+f.a))}function QVn(n,t){var e,i,r,c,a,o,u,s,f;for(o=!0,r=0,u=n.g[t.p],s=t.o.b+n.o,e=n.d[t.p][2],Y8(n.b,u,xwn(uG(zq(n.b,u),17).a-1+e)),Y8(n.c,u,uM(pK(zq(n.c,u)))-s+e*n.f),++u>=n.j?(++n.j,kD(n.b,xwn(1)),kD(n.c,s)):(i=n.d[t.p][1],Y8(n.b,u,xwn(uG(zq(n.b,u),17).a+1-i)),Y8(n.c,u,uM(pK(zq(n.c,u)))+s-i*n.f)),(n.r==(THn(),Ijt)&&(uG(zq(n.b,u),17).a>n.k||uG(zq(n.b,u-1),17).a>n.k)||n.r==Ljt&&(uM(pK(zq(n.c,u)))>n.n||uM(pK(zq(n.c,u-1)))>n.n))&&(o=!1),c=new Fz(ix(qgn(t).a.Kc(),new h));hDn(c);)a=uG(N9(c),18).c.i,n.g[a.p]==u&&(r+=uG((f=QVn(n,a)).a,17).a,o=o&&oM(gK(f.b)));return n.g[t.p]=u,new WO(xwn(r+=n.d[t.p][0]),(qx(),!!o))}function JVn(n,t){var e,i;uM(pK(oIn(t,(jYn(),dTt))))<2&&kfn(t,dTt,2),uG(oIn(t,Byt),88)==(xdn(),ZDt)&&kfn(t,Byt,pgn(t)),0==(e=uG(oIn(t,sTt),17)).a?kfn(t,(GYn(),dmt),new Upn):kfn(t,(GYn(),dmt),new v8(e.a)),null==gK(oIn(t,OMt))&&kfn(t,OMt,(qx(),xA(oIn(t,Vyt))===xA((_gn(),uxt)))),kS(new fX(null,new h3(t.a,16)),new Hd(n)),kS(sin(new fX(null,new h3(t.b,16)),new dt),new Ud(n)),i=new CVn(t),kfn(t,(GYn(),kmt),i),_J(n.a),JV(n.a,(uIn(),Tlt),uG(oIn(t,Fyt),188)),JV(n.a,jlt,uG(oIn(t,MMt),188)),JV(n.a,Elt,uG(oIn(t,Kyt),188)),JV(n.a,Slt,uG(oIn(t,$Mt),188)),JV(n.a,Plt,Rsn(uG(oIn(t,Vyt),223))),ZL(n.a,iYn(t)),kfn(t,wmt,Qzn(n.a,t))}function YVn(n,t,i,r,c){var a,o,u,s,h,f,l,b,w,d,g,p,m;for(l=new Ym,o=new Zm,HAn(n,i,n.d.Ag(),o,l),HAn(n,r,n.d.Bg(),o,l),n.b=.2*(g=DDn(sin(new fX(null,new h3(o,16)),new pa)),p=DDn(sin(new fX(null,new h3(o,16)),new ma)),e.Math.min(g,p)),a=0,u=0;u=2&&(m=sRn(o,!0,b),!n.e&&(n.e=new pp(n)),xvn(n.e,m,o,n.b)),BPn(o,b),oWn(o),w=-1,f=new Ww(o);f.ao)}function tWn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v;for(h=M0n,f=M0n,u=T0n,s=T0n,b=new Ww(t.i);b.a-1){for(r=Fkn(o,0);r.b!=r.d.c;)(i=uG(I6(r),131)).v=a;for(;0!=o.b;)for(t=new Ww((i=uG(Kjn(o,0),131)).i);t.a-1){for(c=new Ww(o);c.a0||(Yb(u,e.Math.min(u.o,r.o-1)),Jb(u,u.i-1),0==u.i&&mv(o.c,u))}}function uWn(n,t,i,r,c){var a,o,u,s;return s=M0n,o=!1,a=!!(u=rXn(n,YF(new MO(t.a,t.b),n),JF(new MO(i.a,i.b),c),YF(new MO(r.a,r.b),i)))&&!(e.Math.abs(u.a-n.a)<=Hnt&&e.Math.abs(u.b-n.b)<=Hnt||e.Math.abs(u.a-t.a)<=Hnt&&e.Math.abs(u.b-t.b)<=Hnt),(u=rXn(n,YF(new MO(t.a,t.b),n),i,c))&&((e.Math.abs(u.a-n.a)<=Hnt&&e.Math.abs(u.b-n.b)<=Hnt)==(e.Math.abs(u.a-t.a)<=Hnt&&e.Math.abs(u.b-t.b)<=Hnt)||a?s=e.Math.min(s,NQ(YF(u,i))):o=!0),(u=rXn(n,YF(new MO(t.a,t.b),n),r,c))&&(o||(e.Math.abs(u.a-n.a)<=Hnt&&e.Math.abs(u.b-n.b)<=Hnt)==(e.Math.abs(u.a-t.a)<=Hnt&&e.Math.abs(u.b-t.b)<=Hnt)||a)&&(s=e.Math.min(s,NQ(YF(u,r)))),s}function sWn(n){hP(n,new hCn(xT(FT(DT(KT(RT(new bu,$4n),D4n),"Minimizes the stress within a layout using stress majorization. Stress exists if the euclidean distance between a pair of nodes doesn't match their graph theoretic distance, that is, the shortest path between the two nodes. The method allows to specify individual edge lengths."),new gt),c4n))),U4(n,$4n,f4n,Jkn(olt)),U4(n,$4n,b4n,(qx(),!0)),U4(n,$4n,p4n,Jkn(hlt)),U4(n,$4n,x4n,Jkn(flt)),U4(n,$4n,g4n,Jkn(llt)),U4(n,$4n,m4n,Jkn(slt)),U4(n,$4n,w4n,Jkn(blt)),U4(n,$4n,v4n,Jkn(wlt)),U4(n,$4n,I4n,Jkn(alt)),U4(n,$4n,A4n,Jkn(rlt)),U4(n,$4n,L4n,Jkn(clt)),U4(n,$4n,N4n,Jkn(ult)),U4(n,$4n,O4n,Jkn(ilt))}function hWn(n){var t,e,i,r,c,a,o,u;for(t=null,i=new Ww(n);i.a0&&0==e.c&&(!t&&(t=new Zm),mv(t.c,e));if(t)for(;0!=t.c.length;){if((e=uG(i7(t,0),239)).b&&e.b.c.length>0)for(!e.b&&(e.b=new Zm),c=new Ww(e.b);c.aTen(n,e,0))return new WO(r,e)}else if(uM(oD(r.g,r.d[0]).a)>uM(oD(e.g,e.d[0]).a))return new WO(r,e);for(o=(!e.e&&(e.e=new Zm),e.e).Kc();o.Ob();)!(a=uG(o.Pb(),239)).b&&(a.b=new Zm),o3(0,(u=a.b).c.length),pC(u.c,0,e),a.c==u.c.length&&mv(t.c,a)}return null}function fWn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g;for(t.Ug("Interactive crossing minimization",1),a=0,c=new Ww(n.b);c.a0&&(e+=u.n.a+u.o.a/2,++f),b=new Ww(u.j);b.a0&&(e/=f),g=Inn(eUt,I0n,28,i.a.c.length,15,1),o=0,s=new Ww(i.a);s.a=o&&r<=u)o<=r&&c<=u?i+=2:o<=r?(n.b[i]=u+1,a+=2):c<=u?(e[h++]=r,e[h++]=o-1,i+=2):(e[h++]=r,e[h++]=o-1,n.b[i]=u+1,a+=2);else{if(!(u2?(Ohn(s=new Zm,new C2(w,1,w.b)),zsn(d=new pDn(vYn(s,g+n.a)),t),mv(i.c,d)):d=uG(cQ(n.b,r?bIn(t):gIn(t)),272),o=bIn(t),r&&(o=gIn(t)),a=GOn(b,o),u=g+n.a,a.a?(u+=e.Math.abs(b.b-h.b),l=new MO(h.a,(h.b+b.b)/2)):(u+=e.Math.abs(b.a-h.a),l=new MO((h.a+b.a)/2,h.b)),vJ(r?n.d:n.c,t,new bTn(d,a,l,u)),vJ(n.b,t,d),!t.n&&(t.n=new fV(lFt,t,1,7)),f=new DD(t.n);f.e!=f.i.gc();)c=nHn(n,uG(Zkn(f),135),!0,0,0),mv(i.c,c)}function wWn(n){var t,e,i,r,c,a,o;if(!n.A.dc()){if(n.A.Hc((Qmn(),QRt))&&(uG(AJ(n.b,(KQn(),yRt)),127).k=!0,uG(AJ(n.b,KRt),127).k=!0,t=n.q!=($Pn(),aRt)&&n.q!=cRt,Db(uG(AJ(n.b,kRt),127),t),Db(uG(AJ(n.b,_Rt),127),t),Db(n.g,t),n.A.Hc(JRt)&&(uG(AJ(n.b,yRt),127).j=!0,uG(AJ(n.b,KRt),127).j=!0,uG(AJ(n.b,kRt),127).k=!0,uG(AJ(n.b,_Rt),127).k=!0,n.g.k=!0)),n.A.Hc(WRt))for(n.a.j=!0,n.a.k=!0,n.g.j=!0,n.g.k=!0,o=n.B.Hc((oUn(),cKt)),c=0,a=(r=Nkn()).length;c0),c=uG(s.a.Xb(s.c=--s.b),18);c!=i&&s.b>0;)n.a[c.p]=!0,n.a[i.p]=!0,MK(s.b>0),c=uG(s.a.Xb(s.c=--s.b),18);s.b>0&&LQ(s)}}function pWn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b;if(!n.b)return!1;for(a=null,l=null,r=1,(u=new _nn(null,null)).a[1]=n.b,f=u;f.a[r];)s=r,o=l,l=f,f=f.a[r],r=(i=n.a.Ne(t,f.d))<0?0:1,0==i&&(!e.c||OJ(f.e,e.d))&&(a=f),f&&f.b||NM(f.a[r])||(NM(f.a[1-r])?l=l.a[s]=Ton(f,r):NM(f.a[1-r])||(b=l.a[1-s])&&(NM(b.a[1-s])||NM(b.a[s])?(c=o.a[1]==l?1:0,NM(b.a[s])?o.a[c]=P4(l,s):NM(b.a[1-s])&&(o.a[c]=Ton(l,s)),f.b=o.a[c].b=!0,o.a[c].a[0].b=!1,o.a[c].a[1].b=!1):(l.b=!1,b.b=!0,f.b=!0)));return a&&(e.b=!0,e.d=a.e,f!=a&&(YCn(n,u,a,h=new _nn(f.d,f.e)),l==a&&(l=h)),l.a[l.a[1]==f?1:0]=f.a[f.a[0]?0:1],--n.c),n.b=u.a[1],n.b&&(n.b.b=!1),e.b}function mWn(n){var t,i,r,c,a,o,u,s,h,f,l,b;for(c=new Ww(n.a.a.b);c.a0?r-=864e5:r+=864e5,u=new DK(Lgn(Bsn(t.q.getTime()),r))),h=new QM,s=n.a.length,c=0;c=97&&i<=122||i>=65&&i<=90){for(a=c+1;a=s)throw hv(new vM("Missing trailing '"));a+1=14&&o<=16?F$(i,183)?o7(e,PLn(uG(i,183))):F$(i,195)?o7(e,xPn(uG(i,195))):F$(i,201)?o7(e,aOn(uG(i,201))):F$(i,2111)?o7(e,RPn(uG(i,2111))):F$(i,53)?o7(e,SLn(uG(i,53))):F$(i,376)?o7(e,aNn(uG(i,376))):F$(i,846)?o7(e,ELn(uG(i,846))):F$(i,109)&&o7(e,jLn(uG(i,109))):t.a._b(i)?(e.a?JA(e.a,e.b):e.a=new lx(e.d),WA(e.a,"[...]")):o7(e,MWn(Kcn(i),new oX(t))):o7(e,null==i?IZn:cpn(i));return e.a?0==e.e.length?e.a.a:e.a.a+""+e.e:e.c}function TWn(n,t){var e,i,r,c;c=n.F,null==t?(n.F=null,sbn(n,null)):(n.F=(tJ(t),t),-1!=(i=xL(t,$Cn(60)))?(Knn(0,i,t.length),r=t.substr(0,i),-1==xL(t,$Cn(46))&&!m_(r,dZn)&&!m_(r,lrt)&&!m_(r,brt)&&!m_(r,wrt)&&!m_(r,drt)&&!m_(r,grt)&&!m_(r,prt)&&!m_(r,mrt)&&(r=vrt),-1!=(e=ax(t,$Cn(62)))&&(r+=""+(s3(e+1,t.length+1),t.substr(e+1))),sbn(n,r)):(r=t,-1==xL(t,$Cn(46))&&(-1!=(i=xL(t,$Cn(91)))&&(Knn(0,i,t.length),r=t.substr(0,i)),m_(r,dZn)||m_(r,lrt)||m_(r,brt)||m_(r,wrt)||m_(r,drt)||m_(r,grt)||m_(r,prt)||m_(r,mrt)?r=t:(r=vrt,-1!=i&&(r+=""+(s3(i,t.length+1),t.substr(i))))),sbn(n,r),r==t&&(n.F=n.D))),4&n.Db&&!(1&n.Db)&&Msn(n,new lV(n,1,5,c,t))}function jWn(n,t){var e,i,r,c,a,o,u,s;if(s3(o=t.length-1,t.length),93==(a=t.charCodeAt(o))){if((c=xL(t,$Cn(91)))>=0)return r=fpn(n,(Knn(1,c,t.length),t.substr(1,c-1))),Knn(c+1,o,t.length),GJn(n,t.substr(c+1,o-(c+1)),r)}else{if(e=-1,null==oot&&(oot=new RegExp("\\d")),oot.test(String.fromCharCode(a))&&(e=T_(t,$Cn(46),o-1))>=0){i=uG(U9(n,jrn(n,(Knn(1,e,t.length),t.substr(1,e-1))),!1),61),u=0;try{u=vUn((s3(e+1,t.length+1),t.substr(e+1)),j1n,vZn)}catch(h){throw F$(h=Ehn(h),130)?hv(new Pen(h)):hv(h)}if(u>16==-10?e=uG(n.Cb,292).Yk(t,e):n.Db>>16==-15&&(!t&&(YYn(),t=N_t),!o&&(YYn(),o=N_t),n.Cb.Yh()&&(a=new Ken(n.Cb,1,13,o,t,Hyn(Aen(uG(n.Cb,62)),n),!1),e?e.nj(a):e=a));else if(F$(n.Cb,90))n.Db>>16==-23&&(F$(t,90)||(YYn(),t=x_t),F$(o,90)||(YYn(),o=x_t),n.Cb.Yh()&&(a=new Ken(n.Cb,1,10,o,t,Hyn(z5(uG(n.Cb,29)),n),!1),e?e.nj(a):e=a));else if(F$(n.Cb,457))for(!(c=uG(n.Cb,850)).b&&(c.b=new Um(new ty)),r=new Gm(new bsn(new Nw(c.b.a).a));r.a.b;)e=PWn(i=uG(von(r.a).ld(),89),bRn(i,c),e);return e}function CWn(n,t){var e,i,r,c,a,o,u,s,h,f,l;for(a=oM(gK(zDn(n,(jYn(),sMt)))),l=uG(zDn(n,nTt),21),u=!1,s=!1,f=new DD((!n.c&&(n.c=new fV(wFt,n,9,9)),n.c));!(f.e==f.i.gc()||u&&s);){for(c=uG(Zkn(f),123),o=0,r=OV(zcn(Uhn(cT(vat,1),EZn,20,0,[(!c.d&&(c.d=new f_(aFt,c,8,5)),c.d),(!c.e&&(c.e=new f_(aFt,c,7,4)),c.e)])));hDn(r)&&(i=uG(N9(r),74),h=a&&BNn(i)&&oM(gK(zDn(i,hMt))),e=Lzn((!i.b&&(i.b=new f_(cFt,i,4,7)),i.b),c)?n==R0(lCn(uG(zrn((!i.c&&(i.c=new f_(cFt,i,5,8)),i.c),0),84))):n==R0(lCn(uG(zrn((!i.b&&(i.b=new f_(cFt,i,4,7)),i.b),0),84))),!((h||e)&&++o>1)););(o>0||l.Hc((eNn(),wRt))&&(!c.n&&(c.n=new fV(lFt,c,1,7)),c.n).i>0)&&(u=!0),o>1&&(s=!0)}u&&t.Fc((r_n(),tpt)),s&&t.Fc((r_n(),ept))}function IWn(n){var t,i,r,c,a,o,u,s,h,f,l,b;if((b=uG(zDn(n,(XYn(),_$t)),21)).dc())return null;if(u=0,o=0,b.Hc((Qmn(),QRt))){for(f=uG(zDn(n,sDt),101),r=2,i=2,c=2,a=2,t=R0(n)?uG(zDn(R0(n),d$t),88):uG(zDn(n,d$t),88),h=new DD((!n.c&&(n.c=new fV(wFt,n,9,9)),n.c));h.e!=h.i.gc();)if(s=uG(Zkn(h),123),(l=uG(zDn(s,gDt),64))==(KQn(),FRt)&&(l=RGn(s,t),Myn(s,gDt,l)),f==($Pn(),cRt))switch(l.g){case 1:r=e.Math.max(r,s.i+s.g);break;case 2:i=e.Math.max(i,s.j+s.f);break;case 3:c=e.Math.max(c,s.i+s.g);break;case 4:a=e.Math.max(a,s.j+s.f)}else switch(l.g){case 1:r+=s.g+2;break;case 2:i+=s.f+2;break;case 3:c+=s.g+2;break;case 4:a+=s.f+2}u=e.Math.max(r,c),o=e.Math.max(i,a)}return ZQn(n,u,o,!0,!0)}function OWn(n,t,i,r,c){var a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y;for(v=uG(l8(krn(JJ(new fX(null,new h3(t.d,16)),new Rg(i)),new Kg(i)),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15),l=vZn,f=j1n,s=new Ww(t.b.j);s.a0)?s&&(h=d.p,a?++h:--h,f=!(VRn(i=afn(uG(zq(d.c.a,h),10)),k,e[0])||rV(i,k,e[0]))):f=!0),l=!1,(v=t.D.i)&&v.c&&o.e&&(a&&v.p>0||!a&&v.p=0){for(u=null,o=new N4(h.a,s+1);o.ba?1:KL(isNaN(0),isNaN(a)))<0&&(oan(I9n),(e.Math.abs(a-1)<=I9n||1==a||isNaN(a)&&isNaN(1)?0:a<1?-1:a>1?1:KL(isNaN(a),isNaN(1)))<0)&&(oan(I9n),(e.Math.abs(0-o)<=I9n||0==o||isNaN(0)&&isNaN(o)?0:0o?1:KL(isNaN(0),isNaN(o)))<0)&&(oan(I9n),(e.Math.abs(o-1)<=I9n||1==o||isNaN(o)&&isNaN(1)?0:o<1?-1:o>1?1:KL(isNaN(o),isNaN(1)))<0))}function KWn(n){var t,e,i,r;if(-1!=(t=xL(e=null!=n.D?n.D:n.B,$Cn(91)))){Knn(0,t,e.length),i=e.substr(0,t),r=new zM;do{r.a+="["}while(-1!=(t=aR(e,91,++t)));m_(i,dZn)?r.a+="Z":m_(i,lrt)?r.a+="B":m_(i,brt)?r.a+="C":m_(i,wrt)?r.a+="D":m_(i,drt)?r.a+="F":m_(i,grt)?r.a+="I":m_(i,prt)?r.a+="J":m_(i,mrt)?r.a+="S":(r.a+="L",r.a+=""+i,r.a+=";");try{return null}catch(c){if(!F$(c=Ehn(c),63))throw hv(c)}}else if(-1==xL(e,$Cn(46))){if(m_(e,dZn))return ZHt;if(m_(e,lrt))return tUt;if(m_(e,brt))return JHt;if(m_(e,wrt))return eUt;if(m_(e,drt))return iUt;if(m_(e,grt))return YHt;if(m_(e,prt))return nUt;if(m_(e,mrt))return rUt}return null}function FWn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k;for(n.e=t,o=qNn(t),v=new Zm,i=new Ww(o);i.a=0&&d=s.c.c.length?B5((zIn(),dbt),wbt):B5((zIn(),wbt),wbt),h*=2,c=i.a.g,i.a.g=e.Math.max(c,c+(h-c)),a=i.b.g,i.b.g=e.Math.max(a,a+(h-a)),r=t}else pNn(o),WXn((u3(0,o.c.length),uG(o.c[0],18)).d.i)||kD(n.o,o)}function UWn(n){var t,i,r,c;for(kS(JJ(new fX(null,new h3(n.a.b,16)),new kr),new yr),QSn(n),kS(JJ(new fX(null,new h3(n.a.b,16)),new Mr),new Tr),n.c==(_gn(),hxt)&&(kS(JJ(sin(new fX(null,new h3(new Lw(n.f),1)),new jr),new Er),new Og(n)),kS(JJ(YJ(sin(sin(new fX(null,new h3(n.d.b,16)),new Sr),new Pr),new Cr),new Ir),new Lg(n))),c=new MO(M0n,M0n),t=new MO(T0n,T0n),r=new Ww(n.a.b);r.a0&&(t.a+=TZn),XWn(uG(Zkn(a),167),t);for(t.a+=Y4n,o=new Zx((!i.c&&(i.c=new f_(cFt,i,5,8)),i.c));o.e!=o.i.gc();)o.e>0&&(t.a+=TZn),XWn(uG(Zkn(o),167),t);t.a+=")"}}}function zWn(n,t,i){var r,c,a,o,u,s,f,l;for(s=new DD((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a));s.e!=s.i.gc();)for(c=new Fz(ix(eRn(u=uG(Zkn(s),27)).a.Kc(),new h));hDn(c);){if(!(r=uG(N9(c),74)).b&&(r.b=new f_(cFt,r,4,7)),!(r.b.i<=1&&(!r.c&&(r.c=new f_(cFt,r,5,8)),r.c.i<=1)))throw hv(new EM("Graph must not contain hyperedges."));if(!z$n(r)&&u!=lCn(uG(zrn((!r.c&&(r.c=new f_(cFt,r,5,8)),r.c),0),84)))for(zsn(f=new $F,r),kfn(f,(mon(),Wft),r),Kb(f,uG(DA(FX(i.f,u)),153)),Bb(f,uG(cQ(i,lCn(uG(zrn((!r.c&&(r.c=new f_(cFt,r,5,8)),r.c),0),84))),153)),kD(t.c,f),o=new DD((!r.n&&(r.n=new fV(lFt,r,1,7)),r.n));o.e!=o.i.gc();)zsn(l=new A5(f,(a=uG(Zkn(o),135)).a),a),kfn(l,Wft,a),l.e.a=e.Math.max(a.g,1),l.e.b=e.Math.max(a.f,1),Yqn(l),kD(t.d,l)}}function VWn(n,t,i){var r,c,a,o,u,s,h,f;switch(i.Ug("Node promotion heuristic",1),n.i=t,n.r=uG(oIn(t,(jYn(),yMt)),243),n.r!=(THn(),Pjt)&&n.r!=Cjt?RQn(n):n_n(n),f=uG(oIn(n.i,kMt),17).a,a=new hi,n.r.g){case 2:case 1:default:tzn(n,a);break;case 3:for(n.r=Djt,tzn(n,a),s=0,u=new Ww(n.b);u.an.k&&(n.r=Ijt,tzn(n,a));break;case 4:for(n.r=Djt,tzn(n,a),h=0,c=new Ww(n.c);c.an.n&&(n.r=Ljt,tzn(n,a));break;case 6:tzn(n,new mg(t0(e.Math.ceil(n.g.length*f/100))));break;case 5:tzn(n,new vg(t0(e.Math.ceil(n.e*f/100))));break;case 8:IYn(n,!0);break;case 9:IYn(n,!1)}n.r!=Pjt&&n.r!=Cjt?JKn(n,t):BBn(n,t),i.Vg()}function WWn(n){var t,e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p;for(pF(u=new N4(s=n.b,0),new bQ(n)),g=!1,c=1;u.b0&&(b.d+=f.n.d,b.d+=f.d),b.a>0&&(b.a+=f.n.a,b.a+=f.d),b.b>0&&(b.b+=f.n.b,b.b+=f.d),b.c>0&&(b.c+=f.n.c,b.c+=f.d),b}function JWn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d;for(b=i.d,l=i.c,o=(a=new MO(i.f.a+i.d.b+i.d.c,i.f.b+i.d.d+i.d.a)).b,h=new Ww(n.a);h.a0&&(n.c[t.c.p][t.p].d+=uRn(n.i,24)*z0n*.07000000029802322-.03500000014901161,n.c[t.c.p][t.p].a=n.c[t.c.p][t.p].d/n.c[t.c.p][t.p].b)}}function tQn(n){var t,e,i,r,c,a,o,u,s,h,f,l,b,w;for(l=new Ww(n);l.ar.d,r.d=e.Math.max(r.d,t),u&&i&&(r.d=e.Math.max(r.d,r.a),r.a=r.d+c);break;case 3:i=t>r.a,r.a=e.Math.max(r.a,t),u&&i&&(r.a=e.Math.max(r.a,r.d),r.d=r.a+c);break;case 2:i=t>r.c,r.c=e.Math.max(r.c,t),u&&i&&(r.c=e.Math.max(r.b,r.c),r.b=r.c+c);break;case 4:i=t>r.b,r.b=e.Math.max(r.b,t),u&&i&&(r.b=e.Math.max(r.b,r.c),r.c=r.b+c)}}}function rQn(n,t){var e,i,r,c,a,o,u,s,h;return s="",0==t.length?n.ne(L1n,O1n,-1,-1):(m_((h=KAn(t)).substr(0,3),"at ")&&(s3(3,h.length+1),h=h.substr(3)),-1==(a=(h=h.replace(/\[.*?\]/g,"")).indexOf("("))?-1==(a=h.indexOf("@"))?(s=h,h=""):(s=KAn((s3(a+1,h.length+1),h.substr(a+1))),h=KAn((Knn(0,a,h.length),h.substr(0,a)))):(Knn(a+1,e=h.indexOf(")",a),h.length),s=h.substr(a+1,e-(a+1)),h=KAn((Knn(0,a,h.length),h.substr(0,a)))),-1!=(a=xL(h,$Cn(46)))&&(s3(a+1,h.length+1),h=h.substr(a+1)),(0==h.length||m_(h,"Anonymous function"))&&(h=O1n),o=ax(s,$Cn(58)),r=T_(s,$Cn(58),o-1),u=-1,i=-1,c=L1n,-1!=o&&-1!=r&&(Knn(0,r,s.length),c=s.substr(0,r),u=rR((Knn(r+1,o,s.length),s.substr(r+1,o-(r+1)))),i=rR((s3(o+1,s.length+1),s.substr(o+1)))),n.ne(c,h,u,i))}function cQn(n){var t,e,i,r,c,a,o,u,s,h,f;for(s=new Ww(n);s.a0||h.j==_Rt&&h.e.c.length-h.g.c.length<0)){t=!1;break}for(r=new Ww(h.g);r.a=h&&M>=p&&(b+=d.n.b+g.n.b+g.a.b-y,++u));if(i)for(o=new Ww(v.e);o.a=h&&M>=p&&(b+=d.n.b+g.n.b+g.a.b-y,++u))}u>0&&(T+=b/u,++w)}w>0?(t.a=c*T/w,t.g=w):(t.a=0,t.g=0)}function oQn(n){var t,e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T;for(l=(c=n.f.b).a,h=c.b,w=n.e.g,b=n.e.f,vN(n.e,c.a,c.b),M=l/w,T=h/b,s=new DD(xJ(n.e));s.e!=s.i.gc();)ycn(u=uG(Zkn(s),135),u.i*M),Mcn(u,u.j*T);for(m=new DD(RJ(n.e));m.e!=m.i.gc();)k=(p=uG(Zkn(m),123)).i,y=p.j,k>0&&ycn(p,k*M),y>0&&Mcn(p,y*T);for(Yun(n.b,new ft),t=new Zm,o=new bsn(new Nw(n.c).a);o.b;)i=uG((a=von(o)).ld(),74),e=uG(a.md(),407).a,r=JFn(i,!1,!1),sqn(f=YPn(bIn(i),COn(r),e),r),(v=wIn(i))&&-1==Ten(t,v,0)&&(mv(t.c,v),iY(v,(MK(0!=f.b),uG(f.a.a.c,8)),e));for(g=new bsn(new Nw(n.d).a);g.b;)i=uG((d=von(g)).ld(),74),e=uG(d.md(),407).a,r=JFn(i,!1,!1),f=YPn(gIn(i),fln(COn(r)),e),sqn(f=fln(f),r),(v=dIn(i))&&-1==Ten(t,v,0)&&(mv(t.c,v),iY(v,(MK(0!=f.b),uG(f.c.b.c,8)),e))}function uQn(n,t,e,i){var r,c,a,o,u;return sKn(o=new kQn(t),i),r=!0,n&&n.pf((XYn(),d$t))&&(r=(c=uG(n.of((XYn(),d$t)),88))==(xdn(),ZDt)||c==JDt||c==YDt),iBn(o,!1),Prn(o.e.Rf(),new DB(o,!1,r)),W1(o,o.f,(Yrn(),jst),(KQn(),yRt)),W1(o,o.f,Sst,KRt),W1(o,o.g,jst,_Rt),W1(o,o.g,Sst,kRt),gyn(o,yRt),gyn(o,KRt),IJ(o,kRt),IJ(o,_Rt),VK(),(a=o.A.Hc((Qmn(),VRt))&&o.B.Hc((oUn(),rKt))?xmn(o):null)&&dT(o.a,a),iQn(o),BTn(o),HTn(o),wWn(o),NHn(o),iEn(o),dkn(o,yRt),dkn(o,KRt),IBn(o),UXn(o),e?(wpn(o),rEn(o),dkn(o,kRt),dkn(o,_Rt),u=o.B.Hc((oUn(),cKt)),dLn(o,u,yRt),dLn(o,u,KRt),gLn(o,u,kRt),gLn(o,u,_Rt),kS(new fX(null,new h3(new Fw(o.i),0)),new Cn),kS(JJ(new fX(null,FW(o.r).a.oc()),new In),new On),jPn(o),o.e.Pf(o.o),kS(new fX(null,FW(o.r).a.oc()),new An),o.o):o.o}function sQn(n){var t,i,r,c,a,o,u,s,h,f,l,b,w,d,g;for(h=M0n,r=new Ww(n.a.b);r.a1)for(z8(v,new BI(n,b=new Izn(w,v,r))),mv(o.c,b),f=v.a.ec().Kc();f.Ob();)men(a,uG(f.Pb(),42).b);if(u.a.gc()>1)for(z8(u,new HI(n,b=new Izn(w,u,r))),mv(o.c,b),f=u.a.ec().Kc();f.Ob();)men(a,uG(f.Pb(),42).b)}}function dQn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m;if(g=n.n,p=n.o,b=n.d,l=uM(pK(Omn(n,(jYn(),lTt)))),t){for(f=l*(t.gc()-1),w=0,s=t.Kc();s.Ob();)f+=(o=uG(s.Pb(),10)).o.a,w=e.Math.max(w,o.o.b);for(m=g.a-(f-p.a)/2,a=g.b-b.d+w,c=r=p.a/(t.gc()+1),u=t.Kc();u.Ob();)(o=uG(u.Pb(),10)).n.a=m,o.n.b=a-o.o.b,m+=o.o.a+l,(h=ERn(o)).n.a=o.o.a/2-h.a.a,h.n.b=o.o.b,(d=uG(oIn(o,(GYn(),Ppt)),12)).e.c.length+d.g.c.length==1&&(d.n.a=c-d.a.a,d.n.b=0,o2(d,n)),c+=r}if(i){for(f=l*(i.gc()-1),w=0,s=i.Kc();s.Ob();)f+=(o=uG(s.Pb(),10)).o.a,w=e.Math.max(w,o.o.b);for(m=g.a-(f-p.a)/2,a=g.b+p.b+b.a-w,c=r=p.a/(i.gc()+1),u=i.Kc();u.Ob();)(o=uG(u.Pb(),10)).n.a=m,o.n.b=a,m+=o.o.a+l,(h=ERn(o)).n.a=o.o.a/2-h.a.a,h.n.b=0,(d=uG(oIn(o,(GYn(),Ppt)),12)).e.c.length+d.g.c.length==1&&(d.n.a=c-d.a.a,d.n.b=p.b,o2(d,n)),c+=r}}function gQn(n,t){var i,r,c,a,o,u;if(uG(oIn(t,(GYn(),Hpt)),21).Hc((r_n(),tpt))){for(u=new Ww(t.a);u.a=0&&a0&&(uG(AJ(n.b,t),127).a.b=i)}function jQn(n,t,e,i){var r,c,a,o,u,s,h,f,l,b,w,d;if(l=uM(pK(oIn(n,(jYn(),TTt)))),b=uM(pK(oIn(n,jTt))),f=uM(pK(oIn(n,yTt))),o=n.o,a=(c=uG(zq(n.j,0),12)).n,d=hAn(c,f)){if(t.Hc((eNn(),wRt)))switch(uG(oIn(n,(GYn(),Fpt)),64).g){case 1:d.c=(o.a-d.b)/2-a.a,d.d=b;break;case 3:d.c=(o.a-d.b)/2-a.a,d.d=-b-d.a;break;case 2:e&&0==c.e.c.length&&0==c.g.c.length?(h=i?d.a:uG(zq(c.f,0),72).o.b,d.d=(o.b-h)/2-a.b):d.d=o.b+b-a.b,d.c=-l-d.b;break;case 4:e&&0==c.e.c.length&&0==c.g.c.length?(h=i?d.a:uG(zq(c.f,0),72).o.b,d.d=(o.b-h)/2-a.b):d.d=o.b+b-a.b,d.c=l}else if(t.Hc(gRt))switch(uG(oIn(n,(GYn(),Fpt)),64).g){case 1:case 3:d.c=a.a+l;break;case 2:case 4:e&&!c.c?(h=i?d.a:uG(zq(c.f,0),72).o.b,d.d=(o.b-h)/2-a.b):d.d=a.b+b}for(r=d.d,s=new Ww(c.f);s.a=n.length)return{done:!0};var i=n[e++];return{value:[i,t.get(i)],done:!1}}}},__n()||(n.prototype.createObject=function(){return{}},n.prototype.get=function(n){return this.obj[":"+n]},n.prototype.set=function(n,t){this.obj[":"+n]=t},n.prototype[U0n]=function(n){delete this.obj[":"+n]},n.prototype.keys=function(){var n=[];for(var t in this.obj)58==t.charCodeAt(0)&&n.push(t.substring(1));return n}),n}function OQn(){OQn=E,RPt=new Cm(E4n),new Cm(S4n),new uF("DEPTH",xwn(0)),EPt=new uF("FAN",xwn(0)),TPt=new uF(Q9n,xwn(0)),UPt=new uF("ROOT",(qx(),!1)),APt=new uF("LEFTNEIGHBOR",null),BPt=new uF("RIGHTNEIGHBOR",null),LPt=new uF("LEFTSIBLING",null),HPt=new uF("RIGHTSIBLING",null),jPt=new uF("DUMMY",!1),new uF("LEVEL",xwn(0)),_Pt=new uF("REMOVABLE_EDGES",new lS),GPt=new uF("XCOOR",xwn(0)),qPt=new uF("YCOOR",xwn(0)),NPt=new uF("LEVELHEIGHT",0),DPt=new uF("LEVELMIN",0),$Pt=new uF("LEVELMAX",0),PPt=new uF("GRAPH_XMIN",0),IPt=new uF("GRAPH_YMIN",0),SPt=new uF("GRAPH_XMAX",0),CPt=new uF("GRAPH_YMAX",0),MPt=new uF("COMPACT_LEVEL_ASCENSION",!1),yPt=new uF("COMPACT_CONSTRAINTS",new Zm),OPt=new uF("ID",""),KPt=new uF("POSITION",xwn(0)),FPt=new uF("PRELIM",0),xPt=new uF("MODIFIER",0),kPt=new Cm(P4n),vPt=new Cm(C4n)}function AQn(n){var t,e,i,r,c,a,o,u,s,h,f,l,b,w,d;if(NGn(),null==n)return null;if(0==(f=8*n.length))return"";for(l=f/24|0,c=null,c=Inn(JHt,N1n,28,4*(0!=(o=f%24)?l+1:l),15,1),s=0,h=0,t=0,e=0,i=0,a=0,r=0,u=0;u>24,s=(3&t)<<24>>24,b=-128&t?(t>>2^192)<<24>>24:t>>2<<24>>24,w=-128&e?(e>>4^240)<<24>>24:e>>4<<24>>24,d=-128&(i=n[r++])?(i>>6^252)<<24>>24:i>>6<<24>>24,c[a++]=gHt[b],c[a++]=gHt[w|s<<4],c[a++]=gHt[h<<2|d],c[a++]=gHt[63&i];return 8==o?(s=(3&(t=n[r]))<<24>>24,b=-128&t?(t>>2^192)<<24>>24:t>>2<<24>>24,c[a++]=gHt[b],c[a++]=gHt[s<<4],c[a++]=61,c[a++]=61):16==o&&(t=n[r],h=(15&(e=n[r+1]))<<24>>24,s=(3&t)<<24>>24,b=-128&t?(t>>2^192)<<24>>24:t>>2<<24>>24,w=-128&e?(e>>4^240)<<24>>24:e>>4<<24>>24,c[a++]=gHt[b],c[a++]=gHt[w|s<<4],c[a++]=gHt[h<<2],c[a++]=61),mvn(c,0,c.length)}function LQn(n,t){var i,r,c,a,o,u;if(0==n.e&&n.p>0&&(n.p=-(n.p-1)),n.p>j1n&&F5(t,n.p-V1n),o=t.q.getDate(),k0(t,1),n.k>=0&&H0(t,n.k),n.c>=0?k0(t,n.c):n.k>=0?(r=35-new Lfn(t.q.getFullYear()-V1n,t.q.getMonth(),35).q.getDate(),k0(t,e.Math.min(r,o))):k0(t,o),n.f<0&&(n.f=t.q.getHours()),n.b>0&&n.f<12&&(n.f+=12),tD(t,24==n.f&&n.g?0:n.f),n.j>=0&&y7(t,n.j),n.n>=0&&Nnn(t,n.n),n.i>=0&&TL(t,Lgn(Ngn(bSn(Bsn(t.q.getTime()),$1n),$1n),n.i)),n.a&&(F5(c=new QE,c.q.getFullYear()-V1n-80),$P(Bsn(t.q.getTime()),Bsn(c.q.getTime()))&&F5(t,c.q.getFullYear()-V1n+100)),n.d>=0)if(-1==n.c)(i=(7+n.d-t.q.getDay())%7)>3&&(i-=7),u=t.q.getMonth(),k0(t,t.q.getDate()+i),t.q.getMonth()!=u&&k0(t,t.q.getDate()+(i>0?-7:7));else if(t.q.getDay()!=n.d)return!1;return n.o>j1n&&(a=t.q.getTimezoneOffset(),TL(t,Lgn(Bsn(t.q.getTime()),60*(n.o-a)*$1n))),!0}function NQn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p;if(F$(r=oIn(t,(GYn(),rmt)),207)){for(b=uG(r,27),w=t.e,f=new eN(t.c),c=t.d,f.a+=c.b,f.b+=c.d,$x(uG(zDn(b,(jYn(),KMt)),181),(oUn(),tKt))&&(Ab(l=uG(zDn(b,_Mt),107),c.a),_b(l,c.d),Lb(l,c.b),Fb(l,c.c)),e=new Zm,s=new Ww(t.a);s.ai.c.length-1;)kD(i,new WO(B3n,G9n));e=uG(oIn(r,ACt),17).a,hN(uG(oIn(n,cCt),88))?(r.e.auM(pK((u3(e,i.c.length),uG(i.c[e],42)).b))&&sw((u3(e,i.c.length),uG(i.c[e],42)),r.e.a+r.f.a)):(r.e.buM(pK((u3(e,i.c.length),uG(i.c[e],42)).b))&&sw((u3(e,i.c.length),uG(i.c[e],42)),r.e.b+r.f.b))}for(c=Fkn(n.b,0);c.b!=c.d.c;)r=uG(I6(c),40),e=uG(oIn(r,(QGn(),ACt)),17).a,kfn(r,(OQn(),DPt),pK((u3(e,i.c.length),uG(i.c[e],42)).a)),kfn(r,$Pt,pK((u3(e,i.c.length),uG(i.c[e],42)).b));t.Vg()}function RQn(n){var t,i,r,c,a,o,u,s,f,l,b,w,d,g,p;for(n.o=uM(pK(oIn(n.i,(jYn(),ETt)))),n.f=uM(pK(oIn(n.i,vTt))),n.j=n.i.b.c.length,u=n.j-1,w=0,n.k=0,n.n=0,n.b=n7(Inn(dot,zZn,17,n.j,0,1)),n.c=n7(Inn(fot,zZn,345,n.j,7,1)),o=new Ww(n.i.b);o.a0&&kD(n.q,l),kD(n.p,l);d=s+(t-=r),f+=t*n.f,Y8(n.b,u,xwn(d)),Y8(n.c,u,f),n.k=e.Math.max(n.k,d),n.n=e.Math.max(n.n,f),n.e+=t,t+=p}}function KQn(){var n;KQn=E,FRt=new RO(Y2n,0),yRt=new RO(o3n,1),kRt=new RO(u3n,2),KRt=new RO(s3n,3),_Rt=new RO(h3n,4),hZ(),SRt=new nT(new nB(n=uG(Mj(YRt),9),uG(MF(n,n.length),9),0)),PRt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[]))),MRt=Nwn(WX(kRt,Uhn(cT(YRt,1),z4n,64,0,[]))),DRt=Nwn(WX(KRt,Uhn(cT(YRt,1),z4n,64,0,[]))),RRt=Nwn(WX(_Rt,Uhn(cT(YRt,1),z4n,64,0,[]))),LRt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[KRt]))),ERt=Nwn(WX(kRt,Uhn(cT(YRt,1),z4n,64,0,[_Rt]))),$Rt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[_Rt]))),CRt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[kRt]))),xRt=Nwn(WX(KRt,Uhn(cT(YRt,1),z4n,64,0,[_Rt]))),TRt=Nwn(WX(kRt,Uhn(cT(YRt,1),z4n,64,0,[KRt]))),ARt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[kRt,_Rt]))),jRt=Nwn(WX(kRt,Uhn(cT(YRt,1),z4n,64,0,[KRt,_Rt]))),NRt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[KRt,_Rt]))),IRt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[kRt,KRt]))),ORt=Nwn(WX(yRt,Uhn(cT(YRt,1),z4n,64,0,[kRt,KRt,_Rt])))}function FQn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y;for(t.Ug(j6n,1),w=new Zm,k=new Zm,s=new Ww(n.b);s.a0&&(y-=d),Vzn(o,y),l=0,w=new Ww(o.a);w.a0),u.a.Xb(u.c=--u.b)),s=.4*r*l,!a&&u.b0&&(s3(0,t.length),64!=(o=t.charCodeAt(0)))){if(37==o&&(u=!1,0!=(h=t.lastIndexOf("%"))&&(h==f-1||(s3(h+1,t.length),u=46==t.charCodeAt(h+1))))){if(Knn(1,h,t.length),m=m_("%",a=t.substr(1,h-1))?null:eJn(a),i=0,u)try{i=vUn((s3(h+2,t.length+1),t.substr(h+2)),j1n,vZn)}catch(v){throw F$(v=Ehn(v),130)?hv(new Pen(v)):hv(v)}for(d=kon(n.Gh());d.Ob();)if(F$(b=Ksn(d),519)&&(p=(r=uG(b,598)).d,(null==m?null==p:m_(m,p))&&0==i--))return r;return null}if(l=-1==(s=t.lastIndexOf("."))?t:(Knn(0,s,t.length),t.substr(0,s)),e=0,-1!=s)try{e=vUn((s3(s+1,t.length+1),t.substr(s+1)),j1n,vZn)}catch(v){if(!F$(v=Ehn(v),130))throw hv(v);l=t}for(l=m_("%",l)?null:eJn(l),w=kon(n.Gh());w.Ob();)if(F$(b=Ksn(w),197)&&(g=(c=uG(b,197)).xe(),(null==l?null==g:m_(l,g))&&0==e--))return c;return null}return jWn(n,t)}function WQn(n){var t,e,i,r,c,a,o,u,s,f,l,b,w,d,g,p,m;for(s=new Ym,o=new K1,i=new Ww(n.a.a.b);i.at.d.c){if((b=n.c[t.a.d])==(g=n.c[f.a.d]))continue;RKn(xS(DS(RS($S(new uk,1),100),b),g))}}}function QQn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T;if(b=uG(uG(Y9(n.r,t),21),87),t!=(KQn(),kRt)&&t!=_Rt){for(a=t==yRt?(ehn(),wht):(ehn(),pht),y=t==yRt?(Yen(),Fst):(Yen(),Rst),c=(r=(i=uG(AJ(n.b,t),127)).i).c+Trn(Uhn(cT(eUt,1),I0n,28,15,[i.n.b,n.C.b,n.k])),m=r.c+r.b-Trn(Uhn(cT(eUt,1),I0n,28,15,[i.n.c,n.C.c,n.k])),o=TT(BB(a),n.t),v=t==yRt?T0n:M0n,l=b.Kc();l.Ob();)!(h=uG(l.Pb(),117)).c||h.c.d.c.length<=0||(p=h.b.Mf(),g=h.e,(d=(w=h.c).i).b=(s=w.n,w.e.a+s.b+s.c),d.a=(u=w.n,w.e.b+u.d+u.a),ZZ(y,W2n),w.f=y,etn(w,(Ktn(),Lst)),d.c=g.a-(d.b-p.a)/2,M=e.Math.min(c,g.a),T=e.Math.max(m,g.a+p.a),d.cT&&(d.c=T-d.b),kD(o.d,new ZX(d,Hdn(o,d))),v=t==yRt?e.Math.max(v,g.b+h.b.Mf().b):e.Math.min(v,g.b));for(v+=t==yRt?n.t:-n.t,(k=cmn((o.e=v,o)))>0&&(uG(AJ(n.b,t),127).a.b=k),f=b.Kc();f.Ob();)!(h=uG(f.Pb(),117)).c||h.c.d.c.length<=0||((d=h.c.i).c-=h.e.a,d.d-=h.e.b)}else TQn(n,t)}function JQn(n){var t,e,i,r,c,a,o,u,s,f;for(t=new Ym,a=new DD(n);a.e!=a.i.gc();){for(c=uG(Zkn(a),27),e=new ek,vJ(cft,c,e),f=new at,i=uG(l8(new fX(null,new LW(new Fz(ix(tRn(c).a.Kc(),new h)))),HX(f,ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)])))),85),Ycn(e,uG(i.xc((qx(),!0)),16),new ot),r=uG(l8(JJ(uG(i.xc(!1),15).Lc(),new ut),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut]))),15).Kc();r.Ob();)(s=wIn(uG(r.Pb(),74)))&&((o=uG(DA(FX(t.f,s)),21))||(o=TFn(s),VAn(t.f,s,o)),Qon(e,o));for(i=uG(l8(new fX(null,new LW(new Fz(ix(eRn(c).a.Kc(),new h)))),HX(f,ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut])))),85),Ycn(e,uG(i.xc(!0),16),new st),u=uG(l8(JJ(uG(i.xc(!1),15).Lc(),new ht),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut]))),15).Kc();u.Ob();)(s=dIn(uG(u.Pb(),74)))&&((o=uG(DA(FX(t.f,s)),21))||(o=TFn(s),VAn(t.f,s,o)),Qon(e,o))}}function YQn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d;if(pXn(),(u=dwn(n,0)<0)&&(n=Men(n)),0==dwn(n,0))switch(t){case 0:return"0";case 1:return N0n;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return(b=new WM).a+=t<0?"0E+":"0E",b.a+=t==j1n?"2147483648":""+-t,b.a}f=Inn(JHt,N1n,28,1+(h=18),15,1),e=h,d=n;do{s=d,d=bSn(d,10),f[--e]=pz(Lgn(48,$gn(s,Ngn(d,10))))&D1n}while(0!=dwn(d,0));if(r=$gn($gn($gn(h,e),t),1),0==t)return u&&(f[--e]=45),mvn(f,e,h-e);if(t>0&&dwn(r,-6)>=0){if(dwn(r,0)>=0){for(c=e+pz(r),o=h-1;o>=c;o--)f[o+1]=f[o];return f[++c]=46,u&&(f[--e]=45),mvn(f,e,h-e+1)}for(a=2;$P(a,Lgn(Men(r),1));a++)f[--e]=48;return f[--e]=46,f[--e]=48,u&&(f[--e]=45),mvn(f,e,h-e)}return w=e+1,i=h,l=new QM,u&&(l.a+="-"),i-w>=1?(jQ(l,f[e]),l.a+=".",l.a+=mvn(f,e+1,h-e-1)):l.a+=mvn(f,e,h-e),l.a+="E",dwn(r,0)>0&&(l.a+="+"),l.a+=""+oV(r),l.a}function ZQn(n,t,i,r,c){var a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T;if(p=new MO(n.g,n.f),(g=xAn(n)).a=e.Math.max(g.a,t),g.b=e.Math.max(g.b,i),T=g.a/p.a,f=g.b/p.b,y=g.a-p.a,s=g.b-p.b,r)for(o=R0(n)?uG(zDn(R0(n),(XYn(),d$t)),88):uG(zDn(n,(XYn(),d$t)),88),u=xA(zDn(n,(XYn(),sDt)))===xA(($Pn(),cRt)),v=new DD((!n.c&&(n.c=new fV(wFt,n,9,9)),n.c));v.e!=v.i.gc();)switch(m=uG(Zkn(v),123),(k=uG(zDn(m,gDt),64))==(KQn(),FRt)&&(k=RGn(m,o),Myn(m,gDt,k)),k.g){case 1:u||ycn(m,m.i*T);break;case 2:ycn(m,m.i+y),u||Mcn(m,m.j*f);break;case 3:u||ycn(m,m.i*T),Mcn(m,m.j+s);break;case 4:u||Mcn(m,m.j*f)}if(vN(n,g.a,g.b),c)for(b=new DD((!n.n&&(n.n=new fV(lFt,n,1,7)),n.n));b.e!=b.i.gc();)w=(l=uG(Zkn(b),135)).i+l.g/2,d=l.j+l.f/2,(M=w/p.a)+(h=d/p.b)>=1&&(M-h>0&&d>=0?(ycn(l,l.i+y),Mcn(l,l.j+s*h)):M-h<0&&w>=0&&(ycn(l,l.i+y*M),Mcn(l,l.j+s)));return Myn(n,(XYn(),_$t),(Qmn(),new nB(a=uG(Mj(sKt),9),uG(MF(a,a.length),9),0))),new MO(T,f)}function nJn(n){hP(n,new hCn(xT(FT(DT(KT(RT(new bu,x7n),"ELK Radial"),'A radial layout provider which is based on the algorithm of Peter Eades published in "Drawing free trees.", published by International Institute for Advanced Study of Social Information Science, Fujitsu Limited in 1991. The radial layouter takes a tree and places the nodes in radial order around the root. The nodes of the same tree level are placed on the same radius.'),new Oo),x7n))),U4(n,x7n,b9n,Jkn(BIt)),U4(n,x7n,o4n,Jkn(VIt)),U4(n,x7n,p4n,Jkn($It)),U4(n,x7n,x4n,Jkn(DIt)),U4(n,x7n,g4n,Jkn(xIt)),U4(n,x7n,m4n,Jkn(NIt)),U4(n,x7n,w4n,Jkn(RIt)),U4(n,x7n,v4n,Jkn(_It)),U4(n,x7n,P7n,Jkn(AIt)),U4(n,x7n,S7n,Jkn(LIt)),U4(n,x7n,E7n,Jkn(UIt)),U4(n,x7n,A7n,Jkn(XIt)),U4(n,x7n,L7n,Jkn(GIt)),U4(n,x7n,N7n,Jkn(qIt)),U4(n,x7n,O7n,Jkn(KIt)),U4(n,x7n,T7n,Jkn(FIt)),U4(n,x7n,j7n,Jkn(HIt)),U4(n,x7n,C7n,Jkn(zIt)),U4(n,x7n,I7n,Jkn(WIt)),U4(n,x7n,M7n,Jkn(OIt))}function tJn(n){var t,e,i,r,c,a,o,u,s,h,f;if(null==n)throw hv(new ZM(IZn));if(s=n,u=!1,(c=n.length)>0&&(s3(0,n.length),45!=(t=n.charCodeAt(0))&&43!=t||(s3(1,n.length+1),n=n.substr(1),--c,u=45==t)),0==c)throw hv(new ZM(y0n+s+'"'));for(;n.length>0&&(s3(0,n.length),48==n.charCodeAt(0));)s3(1,n.length+1),n=n.substr(1),--c;if(c>(lGn(),vot)[10])throw hv(new ZM(y0n+s+'"'));for(r=0;r0&&(f=-parseInt((Knn(0,i,n.length),n.substr(0,i)),10),s3(i,n.length+1),n=n.substr(i),c-=i,e=!1);c>=a;){if(i=parseInt((Knn(0,a,n.length),n.substr(0,a)),10),s3(a,n.length+1),n=n.substr(a),c-=a,e)e=!1;else{if(dwn(f,o)<0)throw hv(new ZM(y0n+s+'"'));f=Ngn(f,h)}f=$gn(f,i)}if(dwn(f,0)>0)throw hv(new ZM(y0n+s+'"'));if(!u&&dwn(f=Men(f),0)<0)throw hv(new ZM(y0n+s+'"'));return f}function eJn(n){var t,e,i,r,c,a,o,u;if(ZXn(),null==n)return null;if((r=xL(n,$Cn(37)))<0)return n;for(u=new lx((Knn(0,r,n.length),n.substr(0,r))),t=Inn(tUt,ret,28,4,15,1),o=0,i=0,a=n.length;rr+2&&mfn((s3(r+1,n.length),n.charCodeAt(r+1)),QFt,JFt)&&mfn((s3(r+2,n.length),n.charCodeAt(r+2)),QFt,JFt))if(e=AG((s3(r+1,n.length),n.charCodeAt(r+1)),(s3(r+2,n.length),n.charCodeAt(r+2))),r+=2,i>0?128==(192&e)?t[o++]=e<<24>>24:i=0:e>=128&&(192==(224&e)?(t[o++]=e<<24>>24,i=2):224==(240&e)?(t[o++]=e<<24>>24,i=3):240==(248&e)&&(t[o++]=e<<24>>24,i=4)),i>0){if(o==i){switch(o){case 2:jQ(u,((31&t[0])<<6|63&t[1])&D1n);break;case 3:jQ(u,((15&t[0])<<12|(63&t[1])<<6|63&t[2])&D1n)}o=0,i=0}}else{for(c=0;c=2){if(0==(!n.a&&(n.a=new fV(oFt,n,6,6)),n.a).i)gj(),i=new is,ttn((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a),i);else if((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a).i>1)for(l=new Zx((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a));l.e!=l.i.gc();)$Sn(l);sqn(t,uG(zrn((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a),0),166))}if(f)for(r=new DD((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a));r.e!=r.i.gc();)for(s=new DD((!(i=uG(Zkn(r),166)).a&&(i.a=new MD(eFt,i,5)),i.a));s.e!=s.i.gc();)u=uG(Zkn(s),377),o.a=e.Math.max(o.a,u.a),o.b=e.Math.max(o.b,u.b);for(a=new DD((!n.n&&(n.n=new fV(lFt,n,1,7)),n.n));a.e!=a.i.gc();)c=uG(Zkn(a),135),(h=uG(zDn(c,Cxt),8))&&kN(c,h.a,h.b),f&&(o.a=e.Math.max(o.a,c.i+c.g),o.b=e.Math.max(o.b,c.j+c.f));return o}function rJn(n,t,e,i,r){var c,a,o;if(win(n,t),a=t[0],c=VJ(e.c,0),o=-1,Jfn(e))if(i>0){if(a+i>n.length)return!1;o=RNn((Knn(0,a+i,n.length),n.substr(0,a+i)),t)}else o=RNn(n,t);switch(c){case 71:return o=XOn(n,a,Uhn(cT($ot,1),zZn,2,6,[Q1n,J1n]),t),r.e=o,!0;case 77:return c_n(n,t,r,o,a);case 76:return a_n(n,t,r,o,a);case 69:return XAn(n,t,a,r);case 99:return zAn(n,t,a,r);case 97:return o=XOn(n,a,Uhn(cT($ot,1),zZn,2,6,["AM","PM"]),t),r.b=o,!0;case 121:return o_n(n,t,a,o,e,r);case 100:return!(o<=0||(r.c=o,0));case 83:return!(o<0)&&tmn(o,a,t[0],r);case 104:12==o&&(o=0);case 75:case 72:return!(o<0||(r.f=o,r.g=!1,0));case 107:return!(o<0||(r.f=o,r.g=!0,0));case 109:return!(o<0||(r.j=o,0));case 115:return!(o<0||(r.n=o,0));case 90:if(aT[s]&&(d=s),f=new Ww(n.a.b);f.a1;){if(c=nKn(t),l=a.g,d=uG(zDn(t,hAt),107),g=uM(pK(zDn(t,VOt))),(!t.a&&(t.a=new fV(bFt,t,10,11)),t.a).i>1&&uM(pK(zDn(t,(lBn(),jOt))))!=M0n&&(a.c+(d.b+d.c))/(a.b+(d.d+d.a))1&&uM(pK(zDn(t,(lBn(),TOt))))!=M0n&&(a.c+(d.b+d.c))/(a.b+(d.d+d.a))>g&&Myn(c,(lBn(),POt),e.Math.max(uM(pK(zDn(t,EOt))),uM(pK(zDn(c,POt)))-uM(pK(zDn(t,TOt))))),(h=(s=kYn(w=new vO(r,f),c,b)).g)>=l&&h==h){for(o=0;o<(!c.a&&(c.a=new fV(bFt,c,10,11)),c.a).i;o++)mNn(n,uG(zrn((!c.a&&(c.a=new fV(bFt,c,10,11)),c.a),o),27),uG(zrn((!t.a&&(t.a=new fV(bFt,t,10,11)),t.a),o),27));Irn(t,w),x1(a,s.c),D1(a,s.b)}--u}Myn(t,(lBn(),mOt),a.b),Myn(t,vOt,a.c),i.Vg()}function uJn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v;for(t.Ug("Interactive node layering",1),i=new Zm,b=new Ww(n.a);b.a=u){MK(v.b>0),v.a.Xb(v.c=--v.b);break}p.a>s&&(r?(Ohn(r.b,p.b),r.a=e.Math.max(r.a,p.a),LQ(v)):(kD(p.b,f),p.c=e.Math.min(p.c,s),p.a=e.Math.max(p.a,u),r=p))}r||((r=new Mk).c=s,r.a=u,pF(v,r),kD(r.b,f))}for(o=n.b,h=0,m=new Ww(i);m.aw&&(a&&(cL(M,b),cL(j,xwn(h.b-1))),I=i.b,O+=b+t,b=0,f=e.Math.max(f,i.b+i.c+C)),ycn(u,I),Mcn(u,O),f=e.Math.max(f,I+C+i.c),b=e.Math.max(b,l),I+=C+t;if(f=e.Math.max(f,r),(P=O+b+i.a)t4n,S=e.Math.abs(b.b-d.b)>t4n,(!i&&E&&S||i&&(E||S))&&aq(p.a,y)),Qon(p.a,r),0==r.b?b=y:(MK(0!=r.b),b=uG(r.c.b.c,8)),hhn(w,l,g),kun(c)==j&&(HQ(j.i)!=c.a&&pAn(g=new sj,HQ(j.i),v),kfn(p,Smt,g)),sOn(w,p,v),f.a.zc(w,f);c2(p,M),u2(p,j)}for(h=f.a.ec().Kc();h.Ob();)c2(s=uG(h.Pb(),18),null),u2(s,null);t.Vg()}function fJn(n,t){var e,i,r,c,a,o,u,s,h,f,l;for(h=(r=uG(oIn(n,(QGn(),cCt)),88))==(xdn(),JDt)||r==YDt?QDt:YDt,e=uG(l8(JJ(new fX(null,new h3(n.b,16)),new $a),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15),(u=uG(l8(YJ(e.Oc(),new Pp(t)),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut]))),15)).Gc(uG(l8(YJ(e.Oc(),new Cp(t)),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut]))),16)),u.jd(new Ip(h)),l=new Hj(new Op(r)),i=new Ym,o=u.Kc();o.Ob();)a=uG(o.Pb(),240),s=uG(a.a,40),oM(gK(a.c))?(l.a.zc(s,(qx(),tot)),new od(l.a.Zc(s,!1)).a.gc()>0&&vJ(i,s,uG(new od(l.a.Zc(s,!1)).a.Vc(),40)),new od(l.a.ad(s,!0)).a.gc()>1&&vJ(i,wmn(l,s),s)):(new od(l.a.Zc(s,!1)).a.gc()>0&&xA(c=uG(new od(l.a.Zc(s,!1)).a.Vc(),40))===xA(DA(FX(i.f,s)))&&uG(oIn(s,(OQn(),yPt)),15).Fc(c),new od(l.a.ad(s,!0)).a.gc()>1&&(f=wmn(l,s),xA(DA(FX(i.f,f)))===xA(s)&&uG(oIn(f,(OQn(),yPt)),15).Fc(s)),l.a.Bc(s))}function lJn(n){var t,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y;if(1==n.gc())return uG(n.Xb(0),235);if(n.gc()<=0)return new d7;for(c=n.Kc();c.Ob();){for(i=uG(c.Pb(),235),d=0,f=vZn,l=vZn,s=j1n,h=j1n,w=new Ww(i.e);w.au&&(k=0,y+=o+m,o=0),eUn(g,i,k,y),t=e.Math.max(t,k+p.a),o=e.Math.max(o,p.b),k+=p.a+m;return g}function bJn(n){var t,e,i,r,c,a,o,u,s,h,f,l,b,w,d,g;if(NGn(),null==n)return null;if((w=hgn(c=_en(n)))%4!=0)return null;if(0==(d=w/4|0))return Inn(tUt,ret,28,0,15,1);for(f=null,t=0,e=0,i=0,r=0,a=0,o=0,u=0,s=0,b=0,l=0,h=0,f=Inn(tUt,ret,28,3*d,15,1);b>4)<<24>>24,f[l++]=((15&e)<<4|i>>2&15)<<24>>24,f[l++]=(i<<6|r)<<24>>24}return mE(a=c[h++])&&mE(o=c[h++])?(t=dHt[a],e=dHt[o],u=c[h++],s=c[h++],-1==dHt[u]||-1==dHt[s]?61==u&&61==s?15&e?null:(qGn(f,0,g=Inn(tUt,ret,28,3*b+1,15,1),0,3*b),g[l]=(t<<2|e>>4)<<24>>24,g):61!=u&&61==s?3&(i=dHt[u])?null:(qGn(f,0,g=Inn(tUt,ret,28,3*b+2,15,1),0,3*b),g[l++]=(t<<2|e>>4)<<24>>24,g[l]=((15&e)<<4|i>>2&15)<<24>>24,g):null:(i=dHt[u],r=dHt[s],f[l++]=(t<<2|e>>4)<<24>>24,f[l++]=((15&e)<<4|i>>2&15)<<24>>24,f[l++]=(i<<6|r)<<24>>24,f)):null}function wJn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v;for(t.Ug(j6n,1),l=uG(oIn(n,(jYn(),Vyt)),223),i=new Ww(n.b);i.a=2){for(b=!0,e=uG(N3(h=new Ww(r.j)),12),f=null;h.a0)if(r=f.gc(),s=t0(e.Math.floor((r+1)/2))-1,c=t0(e.Math.ceil((r+1)/2))-1,t.o==dSt)for(h=c;h>=s;h--)t.a[k.p]==k&&(d=uG(f.Xb(h),42),w=uG(d.a,10),!cS(i,d.b)&&b>n.b.e[w.p]&&(t.a[w.p]=k,t.g[k.p]=t.g[w.p],t.a[k.p]=t.g[k.p],t.f[t.g[k.p].p]=(qx(),!!(oM(t.f[t.g[k.p].p])&k.k==(zIn(),wbt))),b=n.b.e[w.p]));else for(h=s;h<=c;h++)t.a[k.p]==k&&(p=uG(f.Xb(h),42),g=uG(p.a,10),!cS(i,p.b)&&b0&&(c=uG(zq(p.c.a,T-1),10),o=n.i[c.p],E=e.Math.ceil(y$(n.n,c,p)),a=M.a.e-p.d.d-(o.a.e+c.o.b+c.d.a)-E),h=M0n,T0&&j.a.e.e-j.a.a-(j.b.e.e-j.b.a)<0,d=k.a.e.e-k.a.a-(k.b.e.e-k.b.a)<0&&j.a.e.e-j.a.a-(j.b.e.e-j.b.a)>0,w=k.a.e.e+k.b.aj.b.e.e+j.a.a,y=0,!g&&!d&&(b?a+l>0?y=l:h-r>0&&(y=r):w&&(a+u>0?y=u:h-v>0&&(y=v))),M.a.e+=y,M.b&&(M.d.e+=y),1)))}function pJn(n,t,i){var r,c,a,o,u,s,h,f,l,b;if(r=new gY(t.Lf().a,t.Lf().b,t.Mf().a,t.Mf().b),c=new cN,n.c)for(o=new Ww(t.Rf());o.as&&(i.a+=V$(Inn(JHt,N1n,28,-s,15,1))),i.a+="Is",xL(u,$Cn(32))>=0)for(r=0;r=i.o.b/2}p?(g=uG(oIn(i,(GYn(),Pmt)),15))?l?c=g:(r=uG(oIn(i,Ept),15))?c=g.gc()<=r.gc()?g:r:(c=new Zm,kfn(i,Ept,c)):(c=new Zm,kfn(i,Pmt,c)):(r=uG(oIn(i,(GYn(),Ept)),15))?f?c=r:(g=uG(oIn(i,Pmt),15))?c=r.gc()<=g.gc()?r:g:(c=new Zm,kfn(i,Pmt,c)):(c=new Zm,kfn(i,Ept,c)),c.Fc(n),kfn(n,(GYn(),Ppt),e),t.d==e?(u2(t,null),e.e.c.length+e.g.c.length==0&&o2(e,null),Nln(e)):(c2(t,null),e.e.c.length+e.g.c.length==0&&o2(e,null)),BY(t.a)}function jJn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S,P,C,I,O,A;for(i.Ug("MinWidth layering",1),w=t.b,j=t.a,A=uG(oIn(t,(jYn(),mMt)),17).a,u=uG(oIn(t,vMt),17).a,n.b=uM(pK(oIn(t,dTt))),n.d=M0n,y=new Ww(j);y.a0?(h=0,p&&(h+=u),h+=(E-1)*o,v&&(h+=u),j&&v&&(h=e.Math.max(h,GKn(v,o,m,T))),h=n.a&&(r=Rqn(n,m),l=e.Math.max(l,r.b),k=e.Math.max(k,r.d),kD(u,new WO(m,r)));for(T=new Zm,f=0;f0),g.a.Xb(g.c=--g.b),pF(g,j=new bQ(n.b)),MK(g.b0){for(l=h<100?null:new cj(h),w=(s=new Hun(t)).g,g=Inn(YHt,W1n,28,h,15,1),i=0,v=new Drn(h),r=0;r=0;)if(null!=b?udn(b,w[u]):xA(b)===xA(w[u])){g.length<=i&&qGn(g,0,g=Inn(YHt,W1n,28,2*g.length,15,1),0,i),g[i++]=r,ttn(v,w[u]);break n}if(xA(b)===xA(o))break}}if(s=v,w=v.g,h=i,i>g.length&&qGn(g,0,g=Inn(YHt,W1n,28,i,15,1),0,i),i>0){for(m=!0,c=0;c=0;)gjn(n,g[a]);if(i!=h){for(r=h;--r>=i;)gjn(s,r);qGn(g,0,g=Inn(YHt,W1n,28,i,15,1),0,i)}t=s}}}else for(t=cjn(n,t),r=n.i;--r>=0;)t.Hc(n.g[r])&&(gjn(n,r),m=!0);if(m){if(null!=g){for(f=1==(e=t.gc())?i2(n,4,t.Kc().Pb(),null,g[0],d):i2(n,6,t,g,g[0],d),l=e<100?null:new cj(e),r=t.Kc();r.Ob();)l=X_(n,uG(b=r.Pb(),76),l);l?(l.nj(f),l.oj()):Msn(n.e,f)}else{for(l=qF(t.gc()),r=t.Kc();r.Ob();)l=X_(n,uG(b=r.Pb(),76),l);l&&l.oj()}return!0}return!1}function CJn(n,t){var e,i,r,c,a,o,u,s,f,l,b,w,d,g,p,m,v;for((e=new qyn(t)).a||TUn(t),s=oBn(t),u=new K1,g=new BFn,d=new Ww(t.a);d.a0||i.o==dSt&&c=e}function AJn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m;for(f=t,h=new K1,l=new K1,c=p6(f,yet),IOn((i=new SY(n,e,h,l)).a,i.b,i.c,i.d,c),d=(h.i||(h.i=new RD(h,h.c))).Kc();d.Ob();)for(w=uG(d.Pb(),166),o=uG(Y9(h,w),21).Kc();o.Ob();){if(a=o.Pb(),!(b=uG(dcn(n.d,a),166)))throw r=k6(f,Iet),hv(new SM(Det+a+xet+r+$et));!w.e&&(w.e=new f_(oFt,w,10,9)),ttn(w.e,b)}for(p=(l.i||(l.i=new RD(l,l.c))).Kc();p.Ob();)for(g=uG(p.Pb(),166),s=uG(Y9(l,g),21).Kc();s.Ob();){if(u=s.Pb(),!(b=uG(dcn(n.d,u),166)))throw r=k6(f,Iet),hv(new SM(Det+u+xet+r+$et));!g.g&&(g.g=new f_(oFt,g,9,10)),ttn(g.g,b)}!e.b&&(e.b=new f_(cFt,e,4,7)),0!=e.b.i&&(!e.c&&(e.c=new f_(cFt,e,5,8)),0!=e.c.i)&&(!e.b&&(e.b=new f_(cFt,e,4,7)),e.b.i<=1&&(!e.c&&(e.c=new f_(cFt,e,5,8)),e.c.i<=1))&&1==(!e.a&&(e.a=new fV(oFt,e,6,6)),e.a).i&&(hMn(m=uG(zrn((!e.a&&(e.a=new fV(oFt,e,6,6)),e.a),0),166))||fMn(m)||(Xan(m,uG(zrn((!e.b&&(e.b=new f_(cFt,e,4,7)),e.b),0),84)),zan(m,uG(zrn((!e.c&&(e.c=new f_(cFt,e,5,8)),e.c),0),84))))}function LJn(n){var t,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S;for(k=0,y=(v=n.a).length;k0?(f=uG(zq(l.c.a,a-1),10),j=y$(n.b,l,f),g=l.n.b-l.d.d-(f.n.b+f.o.b+f.d.a+j)):g=l.n.b-l.d.d,s=e.Math.min(g,s),a1&&(o=e.Math.min(o,e.Math.abs(uG(hyn(u.a,1),8).b-f.b)))));else for(d=new Ww(t.j);d.ac&&(a=b.a-c,o=vZn,r.c.length=0,c=b.a),b.a>=c&&(mv(r.c,u),u.a.b>1&&(o=e.Math.min(o,e.Math.abs(uG(hyn(u.a,u.a.b-2),8).b-b.b)))));if(0!=r.c.length&&a>t.o.a/2&&o>t.o.b/2){for(o2(w=new lOn,t),NLn(w,(KQn(),yRt)),w.n.a=t.o.a/2,o2(g=new lOn,t),NLn(g,KRt),g.n.a=t.o.a/2,g.n.b=t.o.b,s=new Ww(r);s.a=h.b?c2(u,g):c2(u,w)):(h=uG(eG(u.a),8),(0==u.a.b?n3(u.c):uG(pR(u.a),8)).b>=h.b?u2(u,g):u2(u,w)),(l=uG(oIn(u,(jYn(),bMt)),75))&&Wpn(l,h,!0);t.n.a=c-t.o.a/2}}function $Jn(n,t,i){var r,c,a,o,u,s,h,f,l;for(u=Fkn(n.b,0);u.b!=u.d.c;)if(!m_((o=uG(I6(u),40)).c,H9n))for(h=xDn(o,n),t==(xdn(),JDt)||t==YDt?f$(h,new co):f$(h,new ao),s=h.c.length,r=0;r=0?Ipn(o):Gdn(Ipn(o)),n.qf(eTt,b)),s=new sj,l=!1,n.pf(WMt)?(_R(s,uG(n.of(WMt),8)),l=!0):mD(s,a.a/2,a.b/2),b.g){case 4:kfn(h,gMt,(Gpn(),Imt)),kfn(h,Npt,(Pfn(),ygt)),h.o.b=a.b,d<0&&(h.o.a=-d),NLn(f,(KQn(),kRt)),l||(s.a=a.a),s.a-=a.a;break;case 2:kfn(h,gMt,(Gpn(),Amt)),kfn(h,Npt,(Pfn(),vgt)),h.o.b=a.b,d<0&&(h.o.a=-d),NLn(f,(KQn(),_Rt)),l||(s.a=0);break;case 1:kfn(h,Xpt,(Zen(),ppt)),h.o.a=a.a,d<0&&(h.o.b=-d),NLn(f,(KQn(),KRt)),l||(s.b=a.b),s.b-=a.b;break;case 3:kfn(h,Xpt,(Zen(),dpt)),h.o.a=a.a,d<0&&(h.o.b=-d),NLn(f,(KQn(),yRt)),l||(s.b=0)}if(_R(f.n,s),kfn(h,WMt,s),t==rRt||t==aRt||t==cRt){if(w=0,t==rRt&&n.pf(YMt))switch(b.g){case 1:case 2:w=uG(n.of(YMt),17).a;break;case 3:case 4:w=-uG(n.of(YMt),17).a}else switch(b.g){case 4:case 2:w=c.b,t==aRt&&(w/=r.b);break;case 1:case 3:w=c.a,t==aRt&&(w/=r.a)}kfn(h,bmt,w)}return kfn(h,Fpt,b),h}function xJn(){function n(n){var t=this;this.dispatch=function(t){var e=t.data;switch(e.cmd){case"algorithms":var i=rmn((hZ(),new qw(new Fw(NFt.b))));n.postMessage({id:e.id,data:i});break;case"categories":var r=rmn((hZ(),new qw(new Fw(NFt.c))));n.postMessage({id:e.id,data:r});break;case"options":var c=rmn((hZ(),new qw(new Fw(NFt.d))));n.postMessage({id:e.id,data:c});break;case"register":OVn(e.algorithms),n.postMessage({id:e.id});break;case"layout":Vqn(e.graph,e.layoutOptions||{},e.options||{}),n.postMessage({id:e.id,data:e.graph})}},this.saveDispatch=function(e){try{t.dispatch(e)}catch(i){n.postMessage({id:e.data.id,error:i})}}}function e(t){var e=this;this.dispatcher=new n({postMessage:function(n){e.onmessage({data:n})}}),this.postMessage=function(n){setTimeout((function(){e.dispatcher.saveDispatch({data:n})}),0)}}if(mj(),typeof document===r2n&&typeof self!==r2n){var r=new n(self);self.onmessage=r.saveDispatch}else typeof t!==r2n&&t.exports&&(Object.defineProperty(i,"__esModule",{value:!0}),t.exports={default:e,Worker:e})}function RJn(n,t,e){var i,r,c,a,o,u,s,h,f,l;for(zsn(h=new gMn(e),t),kfn(h,(GYn(),rmt),t),h.o.a=t.g,h.o.b=t.f,h.n.a=t.i,h.n.b=t.j,kD(e.a,h),vJ(n.a,t,h),(0!=(!t.a&&(t.a=new fV(bFt,t,10,11)),t.a).i||oM(gK(zDn(t,(jYn(),sMt)))))&&kfn(h,Cpt,(qx(),!0)),s=uG(oIn(e,Hpt),21),(f=uG(oIn(h,(jYn(),JMt)),101))==($Pn(),sRt)?kfn(h,JMt,uRt):f!=uRt&&s.Fc((r_n(),rpt)),l=0,i=uG(oIn(e,Byt),88),u=new DD((!t.c&&(t.c=new fV(wFt,t,9,9)),t.c));u.e!=u.i.gc();)o=uG(Zkn(u),123),(xA(zDn(r=R0(t),Syt))!==xA((yvn(),Fjt))||xA(zDn(r,Fyt))===xA((kvn(),lgt))||xA(zDn(r,Fyt))===xA((kvn(),hgt))||oM(gK(zDn(r,Cyt)))||xA(zDn(r,kyt))!==xA((Uvn(),tbt))||xA(zDn(r,yMt))===xA((THn(),Pjt))||xA(zDn(r,yMt))===xA((THn(),Cjt))||xA(zDn(r,MMt))===xA((MKn(),JTt))||xA(zDn(r,MMt))===xA((MKn(),ZTt)))&&!oM(gK(zDn(t,jyt)))&&Myn(o,imt,xwn(l++)),oM(gK(zDn(o,FMt)))||mQn(n,o,h,s,i,f);for(a=new DD((!t.n&&(t.n=new fV(lFt,t,1,7)),t.n));a.e!=a.i.gc();)!oM(gK(zDn(c=uG(Zkn(a),135),FMt)))&&c.a&&kD(h.b,own(c));return oM(gK(oIn(h,gyt)))&&s.Fc((r_n(),Zgt)),oM(gK(oIn(h,uMt)))&&(s.Fc((r_n(),ipt)),s.Fc(ept),kfn(h,JMt,uRt)),h}function KJn(n,t,i,r,c,a,o){var u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S,P,C,I,O,A;for(g=0,P=0,h=new Ww(n.b);h.ag&&(a&&(cL(T,w),cL(E,xwn(f.b-1)),kD(n.d,d),u.c.length=0),O=i.b,A+=w+t,w=0,l=e.Math.max(l,i.b+i.c+I)),mv(u.c,s),uyn(s,O,A),l=e.Math.max(l,O+I+i.c),w=e.Math.max(w,b),O+=I+t,d=s;if(Ohn(n.a,u),kD(n.d,uG(zq(u,u.c.length-1),163)),l=e.Math.max(l,r),(C=A+w+i.a)r.d.d+r.d.a?f.f.d=!0:(f.f.d=!0,f.f.a=!0))),i.b!=i.d.c&&(t=e);f&&(c=uG(cQ(n.f,a.d.i),60),t.bc.d.d+c.d.a?f.f.d=!0:(f.f.d=!0,f.f.a=!0))}for(o=new Fz(ix(qgn(b).a.Kc(),new h));hDn(o);)0!=(a=uG(N9(o),18)).a.b&&(t=uG(pR(a.a),8),a.d.j==(KQn(),yRt)&&((g=new Hqn(t,new MO(t.a,r.d.d),r,a)).f.a=!0,g.a=a.d,mv(d.c,g)),a.d.j==KRt&&((g=new Hqn(t,new MO(t.a,r.d.d+r.d.a),r,a)).f.d=!0,g.a=a.d,mv(d.c,g)))}return d}function GJn(n,t,e){var i,r,c,a,o,u,s,h,f,l;for(u=new Zm,f=t.length,a=Ffn(e),s=0;s=w&&(m>w&&(b.c.length=0,w=m),mv(b.c,a));0!=b.c.length&&(l=uG(zq(b,iMn(t,b.c.length)),131),P.a.Bc(l),l.s=d++,Vxn(l,E,M),b.c.length=0)}for(k=n.c.length+1,o=new Ww(n);o.aS.s&&(LQ(e),men(S.i,i),i.c>0&&(i.a=S,kD(S.t,i),i.b=T,kD(T.i,i)))}function zJn(n,t,e,i,r){var c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E;for(w=new R7(t.b),m=new R7(t.b),l=new R7(t.b),M=new R7(t.b),d=new R7(t.b),y=Fkn(t,0);y.b!=y.d.c;)for(o=new Ww((v=uG(I6(y),12)).g);o.a0,g=v.g.c.length>0,s&&g?mv(l.c,v):s?mv(w.c,v):g&&mv(m.c,v);for(b=new Ww(w);b.av.nh()-h.b&&(b=v.nh()-h.b),w>v.oh()-h.d&&(w=v.oh()-h.d),f0){for(k=Fkn(n.f,0);k.b!=k.d.c;)uG(I6(k),10).p+=w-n.e;kAn(n),BY(n.f),O_n(n,r,d)}else{for(aq(n.f,d),d.p=r,n.e=e.Math.max(n.e,r),a=new Fz(ix(qgn(d).a.Kc(),new h));hDn(a);)(c=uG(N9(a),18)).c.i.c||c.c.i.k!=(zIn(),bbt)||(aq(n.f,c.c.i),c.c.i.p=r-1);n.c=r}else kAn(n),BY(n.f),r=0,hDn(new Fz(ix(qgn(d).a.Kc(),new h)))?O_n(n,r=(w=Pyn(w=0,d))+2,d):(aq(n.f,d),d.p=0,n.e=e.Math.max(n.e,0),n.b=uG(zq(n.d.b,0),30),n.c=0);for(0==n.f.b||kAn(n),n.d.a.c.length=0,v=new Zm,f=new Ww(n.d.b);f.a=48&&t<=57))throw hv(new CM(rZn((t$(),Nit))));for(i=t-48;r=48&&t<=57;)if((i=10*i+t-48)<0)throw hv(new CM(rZn((t$(),Rit))));if(e=i,44==t){if(r>=n.j)throw hv(new CM(rZn((t$(),Dit))));if((t=VJ(n.i,r++))>=48&&t<=57){for(e=t-48;r=48&&t<=57;)if((e=10*e+t-48)<0)throw hv(new CM(rZn((t$(),Rit))));if(i>e)throw hv(new CM(rZn((t$(),xit))))}else e=-1}if(125!=t)throw hv(new CM(rZn((t$(),$it))));n.bm(r)?(QYn(),QYn(),c=new n8(9,c),n.d=r+1):(QYn(),QYn(),c=new n8(3,c),n.d=r),c.Om(i),c.Nm(e),EYn(n)}}return c}function iYn(n){var t,e,i;switch(e=uG(oIn(n,(GYn(),Hpt)),21),t=aN(klt),uG(oIn(n,(jYn(),rMt)),346)==(Own(),Ixt)&&gsn(t,ylt),oM(gK(oIn(n,eMt)))?Aq(t,(uIn(),Tlt),(zYn(),Iwt)):Aq(t,(uIn(),Elt),(zYn(),Iwt)),null!=oIn(n,(K7(),jNt))&&gsn(t,Mlt),(oM(gK(oIn(n,fMt)))||oM(gK(oIn(n,iMt))))&&wz(t,(uIn(),Plt),(zYn(),Ubt)),uG(oIn(n,Byt),88).g){case 2:case 3:case 4:wz(Aq(t,(uIn(),Tlt),(zYn(),qbt)),Plt,Gbt)}switch(e.Hc((r_n(),Zgt))&&wz(Aq(Aq(t,(uIn(),Tlt),(zYn(),Hbt)),Slt,_bt),Plt,Bbt),xA(oIn(n,yMt))!==xA((THn(),$jt))&&Aq(t,(uIn(),Elt),(zYn(),ywt)),e.Hc(apt)&&(Aq(t,(uIn(),Tlt),(zYn(),Pwt)),Aq(t,jlt,Ewt),Aq(t,Elt,Swt)),xA(oIn(n,vyt))!==xA((RIn(),Vgt))&&xA(oIn(n,Vyt))!==xA((_gn(),sxt))&&wz(t,(uIn(),Plt),(zYn(),rwt)),oM(gK(oIn(n,aMt)))&&Aq(t,(uIn(),Elt),(zYn(),iwt)),oM(gK(oIn(n,Ryt)))&&Aq(t,(uIn(),Elt),(zYn(),Dwt)),CRn(n)&&(i=(xA(oIn(n,rMt))===xA(Ixt)?uG(oIn(n,Oyt),299):uG(oIn(n,Ayt),299))==(ihn(),fpt)?(zYn(),jwt):(zYn(),Kwt),Aq(t,(uIn(),Slt),i)),uG(oIn(n,qTt),388).g){case 1:Aq(t,(uIn(),Slt),(zYn(),xwt));break;case 2:wz(Aq(Aq(t,(uIn(),Elt),(zYn(),xbt)),Slt,Rbt),Plt,Kbt)}return xA(oIn(n,Syt))!==xA((yvn(),Fjt))&&Aq(t,(uIn(),Elt),(zYn(),Rwt)),t}function rYn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v;if(PV(n.a,t)){if(cS(uG(cQ(n.a,t),49),e))return 1}else vJ(n.a,t,new ek);if(PV(n.a,e)){if(cS(uG(cQ(n.a,e),49),t))return-1}else vJ(n.a,e,new ek);if(PV(n.e,t)){if(cS(uG(cQ(n.e,t),49),e))return-1}else vJ(n.e,t,new ek);if(PV(n.e,e)){if(cS(uG(cQ(n.a,e),49),t))return 1}else vJ(n.e,e,new ek);if(n.c==(yvn(),_jt)||!vR(t,(GYn(),imt))||!vR(e,(GYn(),imt))){for(f=null,s=new Ww(t.j);s.a(a=_Sn(n,e))?uHn(n,t,e):uHn(n,e,t),ra?1:0}return(i=uG(oIn(t,(GYn(),imt)),17).a)>(c=uG(oIn(e,imt),17).a)?uHn(n,t,e):uHn(n,e,t),ic?1:0}function cYn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b,w,d;if(null==e)return null;if(n.a!=t.jk())throw hv(new vM(tet+t.xe()+eet));if(F$(t,469)){if(!(d=y_n(uG(t,685),e)))throw hv(new vM(iet+e+"' is not a valid enumerator of '"+t.xe()+"'"));return d}switch(tdn((gAn(),kBt),t).Nl()){case 2:e=yXn(e,!1);break;case 3:e=yXn(e,!0)}if(i=tdn(kBt,t).Jl())return i.jk().wi().ti(i,e);if(f=tdn(kBt,t).Ll()){for(d=new Zm,s=0,h=(u=Fln(e)).length;s1)for(b=new Zx((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a));b.e!=b.i.gc();)$Sn(b);for(d=C,C>k+v?d=k+v:Cy+w?g=y+w:Ik-v&&dy-w&&gC+P?T=C+P:kI+M?j=I+M:yC-P&&TI-M&&ji&&(f=i-1),(l=N+uRn(t,24)*z0n*h-h/2)<0?l=1:l>r&&(l=r-1),gj(),Scn(c=new ns,f),pcn(c,l),ttn((!o.a&&(o.a=new MD(eFt,o,5)),o.a),c)}function lYn(n){hP(n,new hCn(FT(DT(KT(RT(new bu,ant),"ELK Rectangle Packing"),"Algorithm for packing of unconnected boxes, i.e. graphs without edges. The given order of the boxes is always preserved and the main reading direction of the boxes is left to right. The algorithm is divided into two phases. One phase approximates the width in which the rectangles can be placed. The next phase places the rectangles in rows using the previously calculated width as bounding width and bundles rectangles with a similar height in blocks. A compaction step reduces the size of the drawing. Finally, the rectangles are expanded to fill their bounding box and eliminate empty unused spaces."),new _o))),U4(n,ant,R3n,1.3),U4(n,ant,d4n,(qx(),!1)),U4(n,ant,K3n,fAt),U4(n,ant,o4n,15),U4(n,ant,r9n,Jkn(WOt)),U4(n,ant,p4n,Jkn(eAt)),U4(n,ant,x4n,Jkn(rAt)),U4(n,ant,g4n,Jkn(cAt)),U4(n,ant,m4n,Jkn(tAt)),U4(n,ant,w4n,Jkn(aAt)),U4(n,ant,v4n,Jkn(lAt)),U4(n,ant,J7n,Jkn(pAt)),U4(n,ant,Y7n,Jkn(gAt)),U4(n,ant,Q7n,Jkn(vAt)),U4(n,ant,W7n,Jkn(mAt)),U4(n,ant,Z7n,Jkn(sAt)),U4(n,ant,nnt,Jkn(uAt)),U4(n,ant,tnt,Jkn(oAt)),U4(n,ant,ent,Jkn(dAt)),U4(n,ant,f4n,Jkn(YOt)),U4(n,ant,g9n,Jkn(ZOt)),U4(n,ant,z7n,Jkn(JOt)),U4(n,ant,X7n,Jkn(QOt)),U4(n,ant,V7n,Jkn(nAt)),U4(n,ant,q7n,Jkn(wAt))}function bYn(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S,P,C;if(pXn(),j=n.e,w=n.d,r=n.a,0==j)switch(t){case 0:return"0";case 1:return N0n;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return(M=new WM).a+=t<0?"0E+":"0E",M.a+=-t,M.a}if(k=Inn(JHt,N1n,28,1+(v=10*w+1+7),15,1),e=v,1==w)if((o=r[0])<0){C=E3(o,L0n);do{d=C,C=bSn(C,10),k[--e]=48+pz($gn(d,Ngn(C,10)))&D1n}while(0!=dwn(C,0))}else{C=o;do{d=C,C=C/10|0,k[--e]=d-10*C+48&D1n}while(0!=C)}else{qGn(r,0,S=Inn(YHt,W1n,28,w,15,1),0,P=w);n:for(;;){for(T=0,s=P-1;s>=0;s--)p=JPn(Lgn(Nz(T,32),E3(S[s],L0n))),S[s]=pz(p),T=pz($z(p,32));m=pz(T),g=e;do{k[--e]=48+m%10&D1n}while(0!=(m=m/10|0)&&0!=e);for(i=9-g+e,u=0;u0;u++)k[--e]=48;for(f=P-1;0==S[f];f--)if(0==f)break n;P=f+1}for(;48==k[e];)++e}if(b=j<0,a=v-e-t-1,0==t)return b&&(k[--e]=45),mvn(k,e,v-e);if(t>0&&a>=-6){if(a>=0){for(h=e+a,l=v-1;l>=h;l--)k[l+1]=k[l];return k[++h]=46,b&&(k[--e]=45),mvn(k,e,v-e+1)}for(f=2;f<1-a;f++)k[--e]=48;return k[--e]=46,k[--e]=48,b&&(k[--e]=45),mvn(k,e,v-e)}return E=e+1,c=v,y=new QM,b&&(y.a+="-"),c-E>=1?(jQ(y,k[e]),y.a+=".",y.a+=mvn(k,e+1,v-e-1)):y.a+=mvn(k,e,v-e),y.a+="E",a>0&&(y.a+="+"),y.a+=""+a,y.a}function wYn(n,t){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y;switch(n.c=t,n.g=new Ym,vP(),Apn(new Ad(new Vy(n.c))),m=mK(zDn(n.c,(fIn(),dLt))),o=uG(zDn(n.c,pLt),324),k=uG(zDn(n.c,mLt),437),c=uG(zDn(n.c,hLt),490),v=uG(zDn(n.c,gLt),438),n.j=uM(pK(zDn(n.c,vLt))),a=n.a,o.g){case 0:a=n.a;break;case 1:a=n.b;break;case 2:a=n.i;break;case 3:a=n.e;break;case 4:a=n.f;break;default:throw hv(new vM(lnt+(null!=o.f?o.f:""+o.g)))}if(n.d=new i0(a,k,c),kfn(n.d,(rsn(),Oht),gK(zDn(n.c,lLt))),n.d.c=oM(gK(zDn(n.c,fLt))),0==wZ(n.c).i)return n.d;for(h=new DD(wZ(n.c));h.e!=h.i.gc();){for(l=(s=uG(Zkn(h),27)).g/2,f=s.f/2,y=new MO(s.i+l,s.j+f);PV(n.g,y);)KR(y,(e.Math.random()-.5)*t4n,(e.Math.random()-.5)*t4n);w=uG(zDn(s,(XYn(),$$t)),140),d=new G0(y,new gY(y.a-l-n.j/2-w.b,y.b-f-n.j/2-w.d,s.g+n.j+(w.b+w.c),s.f+n.j+(w.d+w.a))),kD(n.d.i,d),vJ(n.g,y,new WO(d,s))}switch(v.g){case 0:if(null==m)n.d.d=uG(zq(n.d.i,0),68);else for(p=new Ww(n.d.i);p.a0?S+1:1);for(a=new Ww(y.g);a.a0?S+1:1)}0==n.c[s]?aq(n.e,d):0==n.a[s]&&aq(n.f,d),++s}for(w=-1,b=1,f=new Zm,n.d=uG(oIn(t,(GYn(),dmt)),234);A>0;){for(;0!=n.e.b;)C=uG(tG(n.e),10),n.b[C.p]=w--,iUn(n,C),--A;for(;0!=n.f.b;)I=uG(tG(n.f),10),n.b[I.p]=b++,iUn(n,I),--A;if(A>0){for(l=j1n,m=new Ww(v);m.a=l&&(k>l&&(f.c.length=0,l=k),mv(f.c,d));h=n.sg(f),n.b[h.p]=b++,iUn(n,h),--A}}for(P=v.c.length+1,s=0;sn.b[O]&&(pqn(i,!0),kfn(t,Lpt,(qx(),!0)));n.a=null,n.c=null,n.b=null,BY(n.f),BY(n.e),e.Vg()}function pYn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T;for(M=uG(zrn((!n.a&&(n.a=new fV(oFt,n,6,6)),n.a),0),166),f=new Uk,y=new Ym,T=sGn(M),VAn(y.f,M,T),b=new Ym,r=new lS,d=OV(zcn(Uhn(cT(vat,1),EZn,20,0,[(!t.d&&(t.d=new f_(aFt,t,8,5)),t.d),(!t.e&&(t.e=new f_(aFt,t,7,4)),t.e)])));hDn(d);){if(w=uG(N9(d),74),1!=(!n.a&&(n.a=new fV(oFt,n,6,6)),n.a).i)throw hv(new vM(Ptt+(!n.a&&(n.a=new fV(oFt,n,6,6)),n.a).i));w!=n&&(s8(r,p=uG(zrn((!w.a&&(w.a=new fV(oFt,w,6,6)),w.a),0),166),r.c.b,r.c),(g=uG(DA(FX(y.f,p)),13))||(g=sGn(p),VAn(y.f,p,g)),l=i?YF(new eN(uG(zq(T,T.c.length-1),8)),uG(zq(g,g.c.length-1),8)):YF(new eN((u3(0,T.c.length),uG(T.c[0],8))),(u3(0,g.c.length),uG(g.c[0],8))),VAn(b.f,p,l))}if(0!=r.b)for(m=uG(zq(T,i?T.c.length-1:0),8),h=1;h1&&s8(f,m,f.c.b,f.c),yrn(c)));m=v}return f}function mYn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S;for(e.Ug(o7n,1),S=uG(l8(JJ(new fX(null,new h3(t,16)),new wo),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15),h=uG(l8(JJ(new fX(null,new h3(t,16)),new Lp(t)),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut]))),15),w=uG(l8(JJ(new fX(null,new h3(t,16)),new Ap(t)),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[Iut]))),15),d=Inn(lPt,z9n,40,t.gc(),0,1),a=0;a=0&&E=0&&!d[b]){d[b]=r,h.gd(o),--o;break}if((b=E-l)=0&&!d[b]){d[b]=r,h.gd(o),--o;break}}for(w.jd(new go),u=d.length-1;u>=0;u--)d[u]||w.dc()||(d[u]=uG(w.Xb(0),40),w.gd(0));for(s=0;s=0;u--)aq(e,(u3(u,a.c.length),uG(a.c[u],8)));return e}function kYn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k;for(v=uM(pK(zDn(t,(lBn(),POt)))),b=uM(pK(zDn(t,EOt))),l=uM(pK(zDn(t,MOt))),Non((!t.a&&(t.a=new fV(bFt,t,10,11)),t.a)),p=uzn((!t.a&&(t.a=new fV(bFt,t,10,11)),t.a),v,n.b),g=0;gl&&uEn((u3(l,t.c.length),uG(t.c[l],186)),h),h=null;t.c.length>l&&0==(u3(l,t.c.length),uG(t.c[l],186)).a.c.length;)men(t,(u3(l,t.c.length),t.c[l]));if(!h){--a;continue}if(!oM(gK(uG(zq(h.b,0),27).of((S_n(),nAt))))&&HUn(t,w,c,h,g,e,l,i)){d=!0;continue}if(g){if(b=w.b,f=h.f,!oM(gK(uG(zq(h.b,0),27).of(nAt)))&&EVn(t,w,c,h,e,l,i,r)){if(d=!0,b=n.j)return n.a=-1,void(n.c=1);if(t=VJ(n.i,n.d++),n.a=t,1!=n.b){switch(t){case 124:i=2;break;case 42:i=3;break;case 43:i=4;break;case 63:i=5;break;case 41:i=7;break;case 46:i=8;break;case 91:i=9;break;case 94:i=11;break;case 36:i=12;break;case 40:if(i=6,n.d>=n.j)break;if(63!=VJ(n.i,n.d))break;if(++n.d>=n.j)throw hv(new CM(rZn((t$(),iit))));switch(t=VJ(n.i,n.d++)){case 58:i=13;break;case 61:i=14;break;case 33:i=15;break;case 91:i=19;break;case 62:i=18;break;case 60:if(n.d>=n.j)throw hv(new CM(rZn((t$(),iit))));if(61==(t=VJ(n.i,n.d++)))i=16;else{if(33!=t)throw hv(new CM(rZn((t$(),rit))));i=17}break;case 35:for(;n.d=n.j)throw hv(new CM(rZn((t$(),eit))));n.a=VJ(n.i,n.d++);break;default:i=0}n.c=i}else{switch(t){case 92:if(i=10,n.d>=n.j)throw hv(new CM(rZn((t$(),eit))));n.a=VJ(n.i,n.d++);break;case 45:!(512&~n.e)&&n.df&&(f=d.e.a+d.f.a+b),l=f+u.f.a;break;case 4:f=g.b-b-u.f.b,d.e.b-b-u.f.bf&&(f=d.e.b+d.f.b+b),l=f+u.f.b}else if(d)switch(r.g){case 2:l=(f=d.e.a-b-u.f.a)+u.f.a;break;case 1:l=(f=d.e.a+d.f.a+b)+u.f.a;break;case 4:l=(f=d.e.b-b-u.f.b)+u.f.b;break;case 3:l=(f=d.e.b+d.f.b+b)+u.f.b}xA(oIn(t,uCt))===xA((Pln(),wPt))?(c=f,a=l,null!=(o=lln(JJ(new fX(null,new h3(n.a,16)),new GI(c,a)))).a?r==(xdn(),JDt)||r==YDt?u.e.a=f:u.e.b=f:null!=(o=r==(xdn(),JDt)||r==nxt?lln(JJ(Wrn(new fX(null,new h3(n.a,16))),new Ep(c))):lln(JJ(Wrn(new fX(null,new h3(n.a,16))),new Sp(c)))).a&&(r==JDt||r==YDt?u.e.a=uM(pK((MK(null!=o.a),uG(o.a,42)).a)):u.e.b=uM(pK((MK(null!=o.a),uG(o.a,42)).a))),null!=o.a&&(h=Ten(n.a,(MK(null!=o.a),o.a),0))>0&&h!=uG(oIn(u,ACt),17).a&&(kfn(u,MPt,(qx(),!0)),kfn(u,ACt,xwn(h)))):r==(xdn(),JDt)||r==YDt?u.e.a=f:u.e.b=f}e.Vg()}}function PYn(n){var t,e,i,r,c,a,o,u;for(n.b=1,EYn(n),t=null,0==n.c&&94==n.a?(EYn(n),QYn(),QYn(),HFn(t=new K3(4),0,zct),a=new K3(4)):(QYn(),QYn(),a=new K3(4)),r=!0;1!=(u=n.c);){if(0==u&&93==n.a&&!r){t&&(lWn(t,a),a=t);break}if(e=n.a,i=!1,10==u)switch(e){case 100:case 68:case 119:case 87:case 115:case 83:TXn(a,MUn(e)),i=!0;break;case 105:case 73:case 99:case 67:TXn(a,MUn(e)),(e=-1)<0&&(i=!0);break;case 112:case 80:if(!(o=PNn(n,e)))throw hv(new CM(rZn((t$(),git))));TXn(a,o),i=!0;break;default:e=R_n(n)}else if(24==u&&!r){if(t&&(lWn(t,a),a=t),lWn(a,PYn(n)),0!=n.c||93!=n.a)throw hv(new CM(rZn((t$(),kit))));break}if(EYn(n),!i){if(0==u){if(91==e)throw hv(new CM(rZn((t$(),yit))));if(93==e)throw hv(new CM(rZn((t$(),Mit))));if(45==e&&!r&&93!=n.a)throw hv(new CM(rZn((t$(),Tit))))}if(0!=n.c||45!=n.a||45==e&&r)HFn(a,e,e);else{if(EYn(n),1==(u=n.c))throw hv(new CM(rZn((t$(),mit))));if(0==u&&93==n.a)HFn(a,e,e),HFn(a,45,45);else{if(0==u&&93==n.a||24==u)throw hv(new CM(rZn((t$(),Tit))));if(c=n.a,0==u){if(91==c)throw hv(new CM(rZn((t$(),yit))));if(93==c)throw hv(new CM(rZn((t$(),Mit))));if(45==c)throw hv(new CM(rZn((t$(),Tit))))}else 10==u&&(c=R_n(n));if(EYn(n),e>c)throw hv(new CM(rZn((t$(),Sit))));HFn(a,e,c)}}}r=!1}if(1==n.c)throw hv(new CM(rZn((t$(),mit))));return pxn(a),szn(a),n.b=0,EYn(n),a}function CYn(n,t,e){var i,r,c,a,o,u,s,f,l,b,w,d,g,p,m,v,k,y,M;if(e.Ug("Coffman-Graham Layering",1),0!=t.a.c.length){for(M=uG(oIn(t,(jYn(),wMt)),17).a,u=0,a=0,b=new Ww(t.a);b.a=M||!cvn(m,i))&&(i=CJ(t,f)),a2(m,i),c=new Fz(ix(qgn(m).a.Kc(),new h));hDn(c);)r=uG(N9(c),18),n.a[r.p]||(g=r.c.i,--n.e[g.p],0==n.e[g.p]&&kG(_Cn(w,g),D0n));for(s=f.c.length-1;s>=0;--s)kD(t.b,(u3(s,f.c.length),uG(f.c[s],30)));t.a.c.length=0,e.Vg()}else e.Vg()}function IYn(n,t){var e,i,r,c,a,o,u,s,f,l,b,w,d,g,p,m,v,k;k=!1;do{for(k=!1,c=t?new Lw(n.a.b).a.gc()-2:1;t?c>=0:cuG(oIn(g,imt),17).a)&&(v=!1);if(v){for(o=t?c+1:c-1,a=!1,m=!0,i=!1,s=Fkn(W6(n.a,xwn(o)),0);s.b!=s.d.c;)vR(u=uG(I6(s),10),imt)?u.p!=f.p&&(a|=t?uG(oIn(u,imt),17).auG(oIn(f,imt),17).a,m=!1):!a&&m&&u.k==(zIn(),bbt)&&(i=!0,(l=t?uG(N9(new Fz(ix(qgn(u).a.Kc(),new h))),18).c.i:uG(N9(new Fz(ix(Xgn(u).a.Kc(),new h))),18).d.i)==f&&(e=t?uG(N9(new Fz(ix(Xgn(u).a.Kc(),new h))),18).d.i:uG(N9(new Fz(ix(qgn(u).a.Kc(),new h))),18).c.i,(t?uG(ER(n.a,e),17).a-uG(ER(n.a,l),17).a:uG(ER(n.a,l),17).a-uG(ER(n.a,e),17).a)<=2&&(m=!1)));if(i&&m&&(e=t?uG(N9(new Fz(ix(Xgn(f).a.Kc(),new h))),18).d.i:uG(N9(new Fz(ix(qgn(f).a.Kc(),new h))),18).c.i,(t?uG(ER(n.a,e),17).a-uG(ER(n.a,f),17).a:uG(ER(n.a,f),17).a-uG(ER(n.a,e),17).a)<=2&&e.k==(zIn(),dbt)&&(m=!1)),a||m){for(d=SRn(n,f,t);0!=d.a.gc();)w=uG(d.a.ec().Kc().Pb(),10),d.a.Bc(w),Qon(d,SRn(n,w,t));--b,k=!0}}}}while(k)}function OYn(n){Hxn(n.c,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#decimal"])),Hxn(n.d,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#integer"])),Hxn(n.e,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#boolean"])),Hxn(n.f,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EBoolean",Bet,"EBoolean:Object"])),Hxn(n.i,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#byte"])),Hxn(n.g,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#hexBinary"])),Hxn(n.j,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EByte",Bet,"EByte:Object"])),Hxn(n.n,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EChar",Bet,"EChar:Object"])),Hxn(n.t,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#double"])),Hxn(n.u,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EDouble",Bet,"EDouble:Object"])),Hxn(n.F,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#float"])),Hxn(n.G,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EFloat",Bet,"EFloat:Object"])),Hxn(n.I,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#int"])),Hxn(n.J,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EInt",Bet,"EInt:Object"])),Hxn(n.N,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#long"])),Hxn(n.O,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"ELong",Bet,"ELong:Object"])),Hxn(n.Z,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#short"])),Hxn(n.$,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"EShort",Bet,"EShort:Object"])),Hxn(n._,Ert,Uhn(cT($ot,1),zZn,2,6,[Krt,"http://www.w3.org/2001/XMLSchema#string"]))}function AYn(n,t,e,i,r,c,a){var o,u,s,h,f,l,b,w;return l=uG(i.a,17).a,b=uG(i.b,17).a,f=n.b,w=n.c,o=0,h=0,t==(xdn(),JDt)||t==YDt?(h=$I(jdn(ZJ(YJ(new fX(null,new h3(e.b,16)),new mo),new Ya))),f.e.b+f.f.b/2>h?(s=++b,o=uM(pK(yx(Wz(YJ(new fX(null,new h3(e.b,16)),new pO(r,s)),new Za))))):(u=++l,o=uM(pK(yx(Qz(YJ(new fX(null,new h3(e.b,16)),new mO(r,u)),new no)))))):(h=$I(jdn(ZJ(YJ(new fX(null,new h3(e.b,16)),new ro),new Ja))),f.e.a+f.f.a/2>h?(s=++b,o=uM(pK(yx(Wz(YJ(new fX(null,new h3(e.b,16)),new dO(r,s)),new to))))):(u=++l,o=uM(pK(yx(Qz(YJ(new fX(null,new h3(e.b,16)),new gO(r,u)),new eo)))))),t==JDt?(cL(n.a,new MO(uM(pK(oIn(f,(OQn(),DPt))))-r,o)),cL(n.a,new MO(w.e.a+w.f.a+r+c,o)),cL(n.a,new MO(w.e.a+w.f.a+r+c,w.e.b+w.f.b/2)),cL(n.a,new MO(w.e.a+w.f.a,w.e.b+w.f.b/2))):t==YDt?(cL(n.a,new MO(uM(pK(oIn(f,(OQn(),$Pt))))+r,f.e.b+f.f.b/2)),cL(n.a,new MO(f.e.a+f.f.a+r,o)),cL(n.a,new MO(w.e.a-r-c,o)),cL(n.a,new MO(w.e.a-r-c,w.e.b+w.f.b/2)),cL(n.a,new MO(w.e.a,w.e.b+w.f.b/2))):t==nxt?(cL(n.a,new MO(o,uM(pK(oIn(f,(OQn(),DPt))))-r)),cL(n.a,new MO(o,w.e.b+w.f.b+r+c)),cL(n.a,new MO(w.e.a+w.f.a/2,w.e.b+w.f.b+r+c)),cL(n.a,new MO(w.e.a+w.f.a/2,w.e.b+w.f.b+r))):(0==n.a.b||(uG(pR(n.a),8).b=uM(pK(oIn(f,(OQn(),$Pt))))+r*uG(a.b,17).a),cL(n.a,new MO(o,uM(pK(oIn(f,(OQn(),$Pt))))+r*uG(a.b,17).a)),cL(n.a,new MO(o,w.e.b-r*uG(a.a,17).a-c))),new WO(xwn(l),xwn(b))}function LYn(n){var t,e,i,r,c,a,o,u,s,h,f,l,b;if(a=!0,f=null,i=null,r=null,t=!1,b=HFt,s=null,c=null,(u=jkn(n,o=0,YFt,ZFt))=0&&m_(n.substr(o,2),"//")?(Knn(o+=2,u=jkn(n,o,n_t,t_t),n.length),i=n.substr(o,u-o),o=u):null==f||o!=n.length&&(s3(o,n.length),47==n.charCodeAt(o))||(a=!1,-1==(u=cx(n,$Cn(35),o))&&(u=n.length),Knn(o,u,n.length),i=n.substr(o,u-o),o=u);if(!e&&o0&&58==VJ(h,h.length-1)&&(r=h,o=u)),ouxn(c))&&(f=c);for(!f&&(u3(0,d.c.length),f=uG(d.c[0],185)),w=new Ww(t.b);w.al&&(P=0,C+=f+T,f=0),rUn(y,o,P,C),t=e.Math.max(t,P+M.a),f=e.Math.max(f,M.b),P+=M.a+T;for(k=new Ym,i=new Ym,E=new Ww(n);E.a=-1900?1:0,JA(n,e>=4?Uhn(cT($ot,1),zZn,2,6,[Q1n,J1n])[a]:Uhn(cT($ot,1),zZn,2,6,["BC","AD"])[a]);break;case 121:Kkn(n,e,i);break;case 77:tUn(n,e,i);break;case 107:Fen(n,0==(o=r.q.getHours())?24:o,e);break;case 83:PRn(n,e,r);break;case 69:u=i.q.getDay(),JA(n,5==e?Uhn(cT($ot,1),zZn,2,6,["S","M","T","W","T","F","S"])[u]:4==e?Uhn(cT($ot,1),zZn,2,6,[Y1n,Z1n,n0n,t0n,e0n,i0n,r0n])[u]:Uhn(cT($ot,1),zZn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[u]);break;case 97:r.q.getHours()>=12&&r.q.getHours()<24?JA(n,Uhn(cT($ot,1),zZn,2,6,["AM","PM"])[1]):JA(n,Uhn(cT($ot,1),zZn,2,6,["AM","PM"])[0]);break;case 104:Fen(n,0==(s=r.q.getHours()%12)?12:s,e);break;case 75:Fen(n,r.q.getHours()%12,e);break;case 72:Fen(n,r.q.getHours(),e);break;case 99:h=i.q.getDay(),5==e?JA(n,Uhn(cT($ot,1),zZn,2,6,["S","M","T","W","T","F","S"])[h]):4==e?JA(n,Uhn(cT($ot,1),zZn,2,6,[Y1n,Z1n,n0n,t0n,e0n,i0n,r0n])[h]):3==e?JA(n,Uhn(cT($ot,1),zZn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[h]):Fen(n,h,1);break;case 76:f=i.q.getMonth(),5==e?JA(n,Uhn(cT($ot,1),zZn,2,6,["J","F","M","A","M","J","J","A","S","O","N","D"])[f]):4==e?JA(n,Uhn(cT($ot,1),zZn,2,6,[x1n,R1n,K1n,F1n,_1n,B1n,H1n,U1n,G1n,q1n,X1n,z1n])[f]):3==e?JA(n,Uhn(cT($ot,1),zZn,2,6,["Jan","Feb","Mar","Apr",_1n,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"])[f]):Fen(n,f+1,e);break;case 81:l=i.q.getMonth()/3|0,JA(n,e<4?Uhn(cT($ot,1),zZn,2,6,["Q1","Q2","Q3","Q4"])[l]:Uhn(cT($ot,1),zZn,2,6,["1st quarter","2nd quarter","3rd quarter","4th quarter"])[l]);break;case 100:Fen(n,i.q.getDate(),e);break;case 109:Fen(n,r.q.getMinutes(),e);break;case 115:Fen(n,r.q.getSeconds(),e);break;case 122:JA(n,e<4?c.c[0]:c.c[1]);break;case 118:JA(n,c.b);break;case 90:JA(n,e<3?GLn(c):3==e?rNn(c):cNn(c.a));break;default:return!1}return!0}function FYn(n,t,e,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S,P,C;if(iHn(t),u=uG(zrn((!t.b&&(t.b=new f_(cFt,t,4,7)),t.b),0),84),h=uG(zrn((!t.c&&(t.c=new f_(cFt,t,5,8)),t.c),0),84),o=lCn(u),s=lCn(h),a=0==(!t.a&&(t.a=new fV(oFt,t,6,6)),t.a).i?null:uG(zrn((!t.a&&(t.a=new fV(oFt,t,6,6)),t.a),0),166),M=uG(cQ(n.a,o),10),S=uG(cQ(n.a,s),10),T=null,P=null,F$(u,193)&&(F$(y=uG(cQ(n.a,u),305),12)?T=uG(y,12):F$(y,10)&&(M=uG(y,10),T=uG(zq(M.j,0),12))),F$(h,193)&&(F$(E=uG(cQ(n.a,h),305),12)?P=uG(E,12):F$(E,10)&&(S=uG(E,10),P=uG(zq(S.j,0),12))),!M||!S)throw hv(new EM("The source or the target of edge "+t+" could not be found. This usually happens when an edge connects a node laid out by ELK Layered to a node in another level of hierarchy laid out by either another instance of ELK Layered or another layout algorithm alltogether. The former can be solved by setting the hierarchyHandling option to INCLUDE_CHILDREN."));for(zsn(d=new UZ,t),kfn(d,(GYn(),rmt),t),kfn(d,(jYn(),bMt),null),b=uG(oIn(i,Hpt),21),M==S&&b.Fc((r_n(),opt)),T||(can(),k=Wjt,j=null,a&&sN(uG(oIn(M,JMt),101))&&($5(j=new MO(a.j,a.k),s0(t)),Q8(j,e),Ern(s,o)&&(k=Vjt,JF(j,M.n))),T=LXn(M,j,k,i)),P||(can(),k=Vjt,C=null,a&&sN(uG(oIn(S,JMt),101))&&($5(C=new MO(a.b,a.c),s0(t)),Q8(C,e)),P=LXn(S,C,k,HQ(S))),c2(d,T),u2(d,P),(T.e.c.length>1||T.g.c.length>1||P.e.c.length>1||P.g.c.length>1)&&b.Fc((r_n(),ept)),l=new DD((!t.n&&(t.n=new fV(lFt,t,1,7)),t.n));l.e!=l.i.gc();)if(!oM(gK(zDn(f=uG(Zkn(l),135),FMt)))&&f.a)switch(g=own(f),kD(d.b,g),uG(oIn(g,Xyt),278).g){case 1:case 2:b.Fc((r_n(),npt));break;case 0:b.Fc((r_n(),Ygt)),kfn(g,Xyt,(Zrn(),ixt))}if(c=uG(oIn(i,Kyt),322),p=uG(oIn(i,$Mt),323),r=c==(jan(),Ydt)||p==(pyn(),kjt),a&&0!=(!a.a&&(a.a=new MD(eFt,a,5)),a.a).i&&r){for(m=COn(a),w=new Uk,v=Fkn(m,0);v.b!=v.d.c;)aq(w,new eN(uG(I6(v),8)));kfn(d,cmt,w)}return d}function _Yn(n,t,e,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S,P,C,I;for(j=0,E=0,M=new Ym,k=uG(yx(Wz(YJ(new fX(null,new h3(n.b,16)),new io),new fo)),17).a+1,T=Inn(YHt,W1n,28,k,15,1),d=Inn(YHt,W1n,28,k,15,1),w=0;w1)for(o=P+1;ou.b.e.b*(1-g)+u.c.e.b*g));b++);if(y.gc()>0){if(C=0==u.a.b?D$(u.b.e):uG(pR(u.a),8),m=JF(D$(uG(y.Xb(y.gc()-1),40).e),uG(y.Xb(y.gc()-1),40).f),f=JF(D$(uG(y.Xb(0),40).e),uG(y.Xb(0),40).f),b>=y.gc()-1&&C.b>m.b&&u.c.e.b>m.b)continue;if(b<=0&&C.bu.b.e.a*(1-g)+u.c.e.a*g));b++);if(y.gc()>0){if(C=0==u.a.b?D$(u.b.e):uG(pR(u.a),8),m=JF(D$(uG(y.Xb(y.gc()-1),40).e),uG(y.Xb(y.gc()-1),40).f),f=JF(D$(uG(y.Xb(0),40).e),uG(y.Xb(0),40).f),b>=y.gc()-1&&C.a>m.a&&u.c.e.a>m.a)continue;if(b<=0&&C.a=uM(pK(oIn(n,(OQn(),CPt))))&&++E):(l.f&&l.d.e.a<=uM(pK(oIn(n,(OQn(),PPt))))&&++j,l.g&&l.c.e.a+l.c.f.a>=uM(pK(oIn(n,(OQn(),SPt))))&&++E)}else 0==v?hNn(u):v<0&&(++T[P],++d[I],j=uG((S=AYn(u,t,n,new WO(xwn(j),xwn(E)),e,i,new WO(xwn(d[I]),xwn(T[P])))).a,17).a,E=uG(S.b,17).a)}function BYn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m;if(i=t,u=e,n.b&&i.j==(KQn(),_Rt)&&u.j==(KQn(),_Rt)&&(m=i,i=u,u=m),PV(n.a,i)){if(cS(uG(cQ(n.a,i),49),u))return 1}else vJ(n.a,i,new ek);if(PV(n.a,u)){if(cS(uG(cQ(n.a,u),49),i))return-1}else vJ(n.a,u,new ek);if(PV(n.d,i)){if(cS(uG(cQ(n.d,i),49),u))return-1}else vJ(n.d,i,new ek);if(PV(n.d,u)){if(cS(uG(cQ(n.a,u),49),i))return 1}else vJ(n.d,u,new ek);if(i.j!=u.j)return-1==(p=bN(i.j,u.j))?hHn(n,u,i):hHn(n,i,u),p;if(0!=i.e.c.length&&0!=u.e.c.length){if(n.b&&0!=(p=Dbn(i,u)))return-1==p?hHn(n,u,i):1==p&&hHn(n,i,u),p;if((c=uG(zq(i.e,0),18).c.i)==(h=uG(zq(u.e,0),18).c.i))return(r=uG(oIn(uG(zq(i.e,0),18),(GYn(),imt)),17).a)>(s=uG(oIn(uG(zq(u.e,0),18),imt),17).a)?hHn(n,i,u):hHn(n,u,i),rs?1:0;for(d=0,g=(w=n.c).length;d(s=uG(oIn(l,imt),17).a)?hHn(n,i,u):hHn(n,u,i),rs?1:0):n.b&&0!=(p=Dbn(i,u))?(-1==p?hHn(n,u,i):1==p&&hHn(n,i,u),p):(a=0,f=0,vR(uG(zq(i.g,0),18),imt)&&(a=uG(oIn(uG(zq(i.g,0),18),imt),17).a),vR(uG(zq(u.g,0),18),imt)&&(f=uG(oIn(uG(zq(i.g,0),18),imt),17).a),o&&o==l?oM(gK(oIn(uG(zq(i.g,0),18),pmt)))&&!oM(gK(oIn(uG(zq(u.g,0),18),pmt)))?(hHn(n,i,u),1):!oM(gK(oIn(uG(zq(i.g,0),18),pmt)))&&oM(gK(oIn(uG(zq(u.g,0),18),pmt)))?(hHn(n,u,i),-1):(a>f?hHn(n,i,u):hHn(n,u,i),af?1:0):(n.f&&(n.f._b(o)&&(a=uG(n.f.xc(o),17).a),n.f._b(l)&&(f=uG(n.f.xc(l),17).a)),a>f?hHn(n,i,u):hHn(n,u,i),af?1:0))):0!=i.e.c.length&&0!=u.g.c.length?(hHn(n,i,u),1):0!=i.g.c.length&&0!=u.e.c.length?(hHn(n,u,i),-1):vR(i,(GYn(),imt))&&vR(u,imt)?((r=uG(oIn(i,imt),17).a)>(s=uG(oIn(u,imt),17).a)?hHn(n,i,u):hHn(n,u,i),rs?1:0):(hHn(n,u,i),-1)}function HYn(n){n.gb||(n.gb=!0,n.b=Nsn(n,0),Von(n.b,18),Won(n.b,19),n.a=Nsn(n,1),Von(n.a,1),Won(n.a,2),Won(n.a,3),Won(n.a,4),Won(n.a,5),n.o=Nsn(n,2),Von(n.o,8),Von(n.o,9),Won(n.o,10),Won(n.o,11),Won(n.o,12),Won(n.o,13),Won(n.o,14),Won(n.o,15),Won(n.o,16),Won(n.o,17),Won(n.o,18),Won(n.o,19),Won(n.o,20),Won(n.o,21),Won(n.o,22),Won(n.o,23),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),rrn(n.o),n.p=Nsn(n,3),Von(n.p,2),Von(n.p,3),Von(n.p,4),Von(n.p,5),Won(n.p,6),Won(n.p,7),rrn(n.p),rrn(n.p),n.q=Nsn(n,4),Von(n.q,8),n.v=Nsn(n,5),Won(n.v,9),rrn(n.v),rrn(n.v),rrn(n.v),n.w=Nsn(n,6),Von(n.w,2),Von(n.w,3),Von(n.w,4),Won(n.w,5),n.B=Nsn(n,7),Won(n.B,1),rrn(n.B),rrn(n.B),rrn(n.B),n.Q=Nsn(n,8),Won(n.Q,0),rrn(n.Q),n.R=Nsn(n,9),Von(n.R,1),n.S=Nsn(n,10),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),rrn(n.S),n.T=Nsn(n,11),Won(n.T,10),Won(n.T,11),Won(n.T,12),Won(n.T,13),Won(n.T,14),rrn(n.T),rrn(n.T),n.U=Nsn(n,12),Von(n.U,2),Von(n.U,3),Won(n.U,4),Won(n.U,5),Won(n.U,6),Won(n.U,7),rrn(n.U),n.V=Nsn(n,13),Won(n.V,10),n.W=Nsn(n,14),Von(n.W,18),Von(n.W,19),Von(n.W,20),Won(n.W,21),Won(n.W,22),Won(n.W,23),n.bb=Nsn(n,15),Von(n.bb,10),Von(n.bb,11),Von(n.bb,12),Von(n.bb,13),Von(n.bb,14),Von(n.bb,15),Von(n.bb,16),Won(n.bb,17),rrn(n.bb),rrn(n.bb),n.eb=Nsn(n,16),Von(n.eb,2),Von(n.eb,3),Von(n.eb,4),Von(n.eb,5),Von(n.eb,6),Von(n.eb,7),Won(n.eb,8),Won(n.eb,9),n.ab=Nsn(n,17),Von(n.ab,0),Von(n.ab,1),n.H=Nsn(n,18),Won(n.H,0),Won(n.H,1),Won(n.H,2),Won(n.H,3),Won(n.H,4),Won(n.H,5),rrn(n.H),n.db=Nsn(n,19),Won(n.db,2),n.c=$sn(n,20),n.d=$sn(n,21),n.e=$sn(n,22),n.f=$sn(n,23),n.i=$sn(n,24),n.g=$sn(n,25),n.j=$sn(n,26),n.k=$sn(n,27),n.n=$sn(n,28),n.r=$sn(n,29),n.s=$sn(n,30),n.t=$sn(n,31),n.u=$sn(n,32),n.fb=$sn(n,33),n.A=$sn(n,34),n.C=$sn(n,35),n.D=$sn(n,36),n.F=$sn(n,37),n.G=$sn(n,38),n.I=$sn(n,39),n.J=$sn(n,40),n.L=$sn(n,41),n.M=$sn(n,42),n.N=$sn(n,43),n.O=$sn(n,44),n.P=$sn(n,45),n.X=$sn(n,46),n.Y=$sn(n,47),n.Z=$sn(n,48),n.$=$sn(n,49),n._=$sn(n,50),n.cb=$sn(n,51),n.K=$sn(n,52))}function UYn(n,t,e){var i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E;for(a=new lS,v=uG(oIn(e,(jYn(),Byt)),88),d=0,Qon(a,(!t.a&&(t.a=new fV(bFt,t,10,11)),t.a));0!=a.b;)(xA(zDn(s=R0(h=uG(0==a.b?null:(MK(0!=a.b),Lrn(a,a.a.a)),27)),Syt))!==xA((yvn(),Fjt))||xA(zDn(s,Fyt))===xA((kvn(),lgt))||xA(zDn(s,Fyt))===xA((kvn(),hgt))||oM(gK(zDn(s,Cyt)))||xA(zDn(s,kyt))!==xA((Uvn(),tbt))||xA(zDn(s,yMt))===xA((THn(),Pjt))||xA(zDn(s,yMt))===xA((THn(),Cjt))||xA(zDn(s,MMt))===xA((MKn(),JTt))||xA(zDn(s,MMt))===xA((MKn(),ZTt)))&&!oM(gK(zDn(h,jyt)))&&Myn(h,(GYn(),imt),xwn(d++)),!oM(gK(zDn(h,FMt)))&&(l=0!=(!h.a&&(h.a=new fV(bFt,h,10,11)),h.a).i,w=oCn(h),b=xA(zDn(h,rMt))===xA((Own(),Ixt)),p=null,(E=!vnn(h,(XYn(),e$t))||L9(mK(zDn(h,e$t))))&&b&&(l||w)&&(kfn(p=PGn(h),Byt,v),vR(p,fTt)&&iM(new omn(uM(pK(oIn(p,fTt)))),p),0!=uG(zDn(h,DMt),181).gc()&&(f=p,kS(new fX(null,(!h.c&&(h.c=new fV(wFt,h,9,9)),new h3(h.c,16))),new Yd(f)),u_n(h,p))),k=e,(y=uG(cQ(n.a,R0(h)),10))&&(k=y.e),g=RJn(n,h,k),p&&(g.e=p,p.e=g,Qon(a,(!h.a&&(h.a=new fV(bFt,h,10,11)),h.a))));for(d=0,s8(a,t,a.c.b,a.c);0!=a.b;){for(u=new DD((!(c=uG(0==a.b?null:(MK(0!=a.b),Lrn(a,a.a.a)),27)).b&&(c.b=new fV(aFt,c,12,3)),c.b));u.e!=u.i.gc();)iHn(o=uG(Zkn(u),74)),(xA(zDn(t,Syt))!==xA((yvn(),Fjt))||xA(zDn(t,Fyt))===xA((kvn(),lgt))||xA(zDn(t,Fyt))===xA((kvn(),hgt))||oM(gK(zDn(t,Cyt)))||xA(zDn(t,kyt))!==xA((Uvn(),tbt))||xA(zDn(t,yMt))===xA((THn(),Pjt))||xA(zDn(t,yMt))===xA((THn(),Cjt))||xA(zDn(t,MMt))===xA((MKn(),JTt))||xA(zDn(t,MMt))===xA((MKn(),ZTt)))&&Myn(o,(GYn(),imt),xwn(d++)),T=lCn(uG(zrn((!o.b&&(o.b=new f_(cFt,o,4,7)),o.b),0),84)),j=lCn(uG(zrn((!o.c&&(o.c=new f_(cFt,o,5,8)),o.c),0),84)),oM(gK(zDn(o,FMt)))||oM(gK(zDn(T,FMt)))||oM(gK(zDn(j,FMt)))||(m=c,BNn(o)&&oM(gK(zDn(T,sMt)))&&oM(gK(zDn(o,hMt)))||Ern(j,T)?m=T:Ern(T,j)&&(m=j),k=e,(y=uG(cQ(n.a,m),10))&&(k=y.e),kfn(FYn(n,o,m,k),(GYn(),Ipt),SFn(n,o,t,e)));if(b=xA(zDn(c,rMt))===xA((Own(),Ixt)))for(r=new DD((!c.a&&(c.a=new fV(bFt,c,10,11)),c.a));r.e!=r.i.gc();)E=!vnn(i=uG(Zkn(r),27),(XYn(),e$t))||L9(mK(zDn(i,e$t))),M=xA(zDn(i,rMt))===xA(Ixt),E&&M&&s8(a,i,a.c.b,a.c)}}function GYn(){var n,t;GYn=E,rmt=new Cm(E4n),Ipt=new Cm("coordinateOrigin"),wmt=new Cm("processors"),Cpt=new uF("compoundNode",(qx(),!1)),qpt=new uF("insideConnections",!1),cmt=new Cm("originalBendpoints"),amt=new Cm("originalDummyNodePosition"),omt=new Cm("originalLabelEdge"),gmt=new Cm("representedLabels"),$pt=new Cm("endLabels"),Dpt=new Cm("endLabel.origin"),Qpt=new uF("labelSide",(Ajn(),Rxt)),emt=new uF("maxEdgeThickness",0),pmt=new uF("reversed",!1),dmt=new Cm(S4n),Zpt=new uF("longEdgeSource",null),nmt=new uF("longEdgeTarget",null),Ypt=new uF("longEdgeHasLabelDummies",!1),Jpt=new uF("longEdgeBeforeLabelDummy",!1),Npt=new uF("edgeConstraint",(Pfn(),kgt)),zpt=new Cm("inLayerLayoutUnit"),Xpt=new uF("inLayerConstraint",(Zen(),gpt)),Vpt=new uF("inLayerSuccessorConstraint",new Zm),Wpt=new uF("inLayerSuccessorConstraintBetweenNonDummies",!1),lmt=new Cm("portDummy"),Opt=new uF("crossingHint",xwn(0)),Hpt=new uF("graphProperties",new nB(t=uG(Mj(bpt),9),uG(MF(t,t.length),9),0)),Fpt=new uF("externalPortSide",(KQn(),FRt)),_pt=new uF("externalPortSize",new sj),Rpt=new Cm("externalPortReplacedDummies"),Kpt=new Cm("externalPortReplacedDummy"),xpt=new uF("externalPortConnections",new nB(n=uG(Mj(YRt),9),uG(MF(n,n.length),9),0)),bmt=new uF(i3n,0),jpt=new Cm("barycenterAssociates"),Pmt=new Cm("TopSideComments"),Ept=new Cm("BottomSideComments"),Ppt=new Cm("CommentConnectionPort"),Gpt=new uF("inputCollect",!1),hmt=new uF("outputCollect",!1),Lpt=new uF("cyclic",!1),Apt=new Cm("crossHierarchyMap"),Smt=new Cm("targetOffset"),new uF("splineLabelSize",new sj),kmt=new Cm("spacings"),fmt=new uF("partitionConstraint",!1),Spt=new Cm("breakingPoint.info"),jmt=new Cm("splines.survivingEdge"),Tmt=new Cm("splines.route.start"),ymt=new Cm("splines.edgeChain"),smt=new Cm("originalPortConstraints"),vmt=new Cm("selfLoopHolder"),Mmt=new Cm("splines.nsPortY"),imt=new Cm("modelOrder"),tmt=new Cm("longEdgeTargetNode"),Bpt=new uF(_6n,!1),mmt=new uF(_6n,!1),Upt=new Cm("layerConstraints.hiddenNodes"),umt=new Cm("layerConstraints.opposidePort"),Emt=new Cm("targetNode.modelOrder")}function qYn(n,t,i,r){var c,a,o,u,s,h,f,l,b,w,d;for(l=Fkn(n.b,0);l.b!=l.d.c;)if(!m_((f=uG(I6(l),40)).c,H9n))for(a=uG(l8(new fX(null,new h3(zNn(f,n),16)),ftn(new V,new z,new en,Uhn(cT(Rut,1),p1n,108,0,[(ybn(),Iut)]))),15),t==(xdn(),JDt)||t==YDt?a.jd(new oo):a.jd(new uo),d=a.gc(),c=0;c0&&(u=uG(pR(uG(a.Xb(c),65).a),8).a,b=f.e.a+f.f.a/2,s=uG(pR(uG(a.Xb(c),65).a),8).b,w=f.e.b+f.f.b/2,r>0&&e.Math.abs(s-w)/(e.Math.abs(u-b)/40)>50&&cL(uG(a.Xb(c),65).a,new MO(f.e.a+f.f.a+r/5.3,w>s?f.e.b+f.f.b*o-r/2:f.e.b+f.f.b*o+r/2))),cL(uG(a.Xb(c),65).a,new MO(f.e.a+f.f.a,f.e.b+f.f.b*o))):t==YDt?(h=uM(pK(oIn(f,(OQn(),DPt)))),f.e.a-r>h?cL(uG(a.Xb(c),65).a,new MO(h-i,f.e.b+f.f.b*o)):uG(a.Xb(c),65).a.b>0&&(u=uG(pR(uG(a.Xb(c),65).a),8).a,b=f.e.a+f.f.a/2,s=uG(pR(uG(a.Xb(c),65).a),8).b,w=f.e.b+f.f.b/2,r>0&&e.Math.abs(s-w)/(e.Math.abs(u-b)/40)>50&&cL(uG(a.Xb(c),65).a,new MO(f.e.a-r/5.3,w>s?f.e.b+f.f.b*o-r/2:f.e.b+f.f.b*o+r/2))),cL(uG(a.Xb(c),65).a,new MO(f.e.a,f.e.b+f.f.b*o))):t==nxt?(h=uM(pK(oIn(f,(OQn(),$Pt)))),f.e.b+f.f.b+r0&&(u=uG(pR(uG(a.Xb(c),65).a),8).a,b=f.e.a+f.f.a/2,s=uG(pR(uG(a.Xb(c),65).a),8).b,w=f.e.b+f.f.b/2,r>0&&e.Math.abs(u-b)/(e.Math.abs(s-w)/40)>50&&cL(uG(a.Xb(c),65).a,new MO(b>u?f.e.a+f.f.a*o-r/2:f.e.a+f.f.a*o+r/2,f.e.b+r/5.3+f.f.b))),cL(uG(a.Xb(c),65).a,new MO(f.e.a+f.f.a*o,f.e.b+f.f.b))):(h=uM(pK(oIn(f,(OQn(),DPt)))),uln(uG(a.Xb(c),65),n)?cL(uG(a.Xb(c),65).a,new MO(f.e.a+f.f.a*o,uG(pR(uG(a.Xb(c),65).a),8).b)):f.e.b-r>h?cL(uG(a.Xb(c),65).a,new MO(f.e.a+f.f.a*o,h-i)):uG(a.Xb(c),65).a.b>0&&(u=uG(pR(uG(a.Xb(c),65).a),8).a,b=f.e.a+f.f.a/2,s=uG(pR(uG(a.Xb(c),65).a),8).b,w=f.e.b+f.f.b/2,r>0&&e.Math.abs(u-b)/(e.Math.abs(s-w)/40)>50&&cL(uG(a.Xb(c),65).a,new MO(b>u?f.e.a+f.f.a*o-r/2:f.e.a+f.f.a*o+r/2,f.e.b-r/5.3))),cL(uG(a.Xb(c),65).a,new MO(f.e.a+f.f.a*o,f.e.b)))}function XYn(){var n,t;XYn=E,e$t=new Cm(Vnt),yDt=new Cm(Wnt),nMn(),i$t=new mL(X8n,r$t=CNt),new Jm,c$t=new mL(R3n,null),a$t=new Cm(Qnt),ZSn(),b$t=WX(ZNt,Uhn(cT(txt,1),p1n,298,0,[WNt])),l$t=new mL(r9n,b$t),w$t=new mL(q8n,(qx(),!1)),xdn(),d$t=new mL(W8n,g$t=ZDt),_gn(),k$t=new mL(m8n,y$t=fxt),j$t=new mL(Xnt,!1),Own(),E$t=new mL(b8n,S$t=Oxt),Q$t=new CN(12),W$t=new mL(K3n,Q$t),O$t=new mL(f4n,!1),A$t=new mL(g9n,!1),V$t=new mL(w4n,!1),$Pn(),sDt=new mL(l4n,hDt=sRt),mDt=new Cm(b9n),vDt=new Cm(a4n),kDt=new Cm(s4n),TDt=new Cm(h4n),N$t=new Uk,L$t=new mL(c9n,N$t),f$t=new mL(u9n,!1),P$t=new mL(s9n,!1),new Cm(Jnt),D$t=new Nk,$$t=new mL(w9n,D$t),z$t=new mL(U8n,!1),new Jm,MDt=new mL(Ynt,1),h$t=new Cm(Znt),s$t=new Cm(ntt),HDt=new mL(k4n,!1),new mL(ttt,!0),xwn(0),new mL(ett,xwn(100)),new mL(itt,!1),xwn(0),new mL(rtt,xwn(4e3)),xwn(0),new mL(ctt,xwn(400)),new mL(att,!1),new mL(ott,!1),new mL(utt,!0),new mL(stt,!1),qpn(),o$t=new mL(znt,u$t=TKt),jDt=new mL(A8n,10),EDt=new mL(L8n,10),SDt=new mL(D3n,20),PDt=new mL(N8n,10),CDt=new mL(u4n,2),IDt=new mL($8n,10),ADt=new mL(D8n,0),LDt=new mL(K8n,5),NDt=new mL(x8n,1),$Dt=new mL(R8n,1),DDt=new mL(o4n,20),xDt=new mL(F8n,10),FDt=new mL(_8n,10),ODt=new Cm(B8n),KDt=new qL,RDt=new mL(d9n,KDt),Z$t=new Cm(l9n),J$t=new mL(f9n,Y$t=!1),R$t=new CN(5),x$t=new mL(Q8n,R$t),VDn(),t=uG(Mj(eRt),9),F$t=new nB(t,uG(MF(t,t.length),9),0),K$t=new mL(m4n,F$t),Vkn(),tDt=new mL(Z8n,eDt=Zxt),rDt=new Cm(n9n),cDt=new Cm(t9n),aDt=new Cm(e9n),iDt=new Cm(i9n),n=uG(Mj(sKt),9),B$t=new nB(n,uG(MF(n,n.length),9),0),_$t=new mL(p4n,B$t),X$t=ggn((oUn(),eKt)),q$t=new mL(g4n,X$t),G$t=new MO(0,0),U$t=new mL(x4n,G$t),H$t=new mL(d4n,!1),Zrn(),m$t=new mL(a9n,v$t=ixt),p$t=new mL(b4n,!1),new Cm(htt),xwn(1),new mL(ftt,null),oDt=new Cm(h9n),fDt=new Cm(o9n),KQn(),gDt=new mL(G8n,pDt=FRt),uDt=new Cm(H8n),eNn(),wDt=ggn(gRt),bDt=new mL(v4n,wDt),lDt=new mL(J8n,!1),dDt=new mL(Y8n,!0),new Jm,XDt=new mL(y4n,1),VDt=new mL(ltt,null),BDt=new mL(M4n,150),_Dt=new mL(T4n,1.414),UDt=new mL(j4n,null),GDt=new mL(btt,1),C$t=new mL(z8n,!1),I$t=new mL(V8n,!1),M$t=new mL(x3n,1),RCn(),new mL(wtt,T$t=mxt),nDt=!0,Iwn(),zDt=fKt,WDt=fKt,qDt=fKt}function zYn(){zYn=E,qbt=new CC("DIRECTION_PREPROCESSOR",0),Hbt=new CC("COMMENT_PREPROCESSOR",1),Xbt=new CC("EDGE_AND_LAYER_CONSTRAINT_EDGE_REVERSER",2),uwt=new CC("INTERACTIVE_EXTERNAL_PORT_POSITIONER",3),Pwt=new CC("PARTITION_PREPROCESSOR",4),lwt=new CC("LABEL_DUMMY_INSERTER",5),Nwt=new CC("SELF_LOOP_PREPROCESSOR",6),pwt=new CC("LAYER_CONSTRAINT_PREPROCESSOR",7),Ewt=new CC("PARTITION_MIDPROCESSOR",8),iwt=new CC("HIGH_DEGREE_NODE_LAYER_PROCESSOR",9),ywt=new CC("NODE_PROMOTION",10),gwt=new CC("LAYER_CONSTRAINT_POSTPROCESSOR",11),Swt=new CC("PARTITION_POSTPROCESSOR",12),Zbt=new CC("HIERARCHICAL_PORT_CONSTRAINT_PROCESSOR",13),Dwt=new CC("SEMI_INTERACTIVE_CROSSMIN_PROCESSOR",14),xbt=new CC("BREAKING_POINT_INSERTER",15),kwt=new CC("LONG_EDGE_SPLITTER",16),Iwt=new CC("PORT_SIDE_PROCESSOR",17),swt=new CC("INVERTED_PORT_PROCESSOR",18),Cwt=new CC("PORT_LIST_SORTER",19),Rwt=new CC("SORT_BY_INPUT_ORDER_OF_MODEL",20),Twt=new CC("NORTH_SOUTH_PORT_PREPROCESSOR",21),Rbt=new CC("BREAKING_POINT_PROCESSOR",22),jwt=new CC(p6n,23),Kwt=new CC(m6n,24),Awt=new CC("SELF_LOOP_PORT_RESTORER",25),xwt=new CC("SINGLE_EDGE_GRAPH_WRAPPER",26),hwt=new CC("IN_LAYER_CONSTRAINT_PROCESSOR",27),Qbt=new CC("END_NODE_PORT_LABEL_MANAGEMENT_PROCESSOR",28),fwt=new CC("LABEL_AND_NODE_SIZE_PROCESSOR",29),owt=new CC("INNERMOST_NODE_MARGIN_CALCULATOR",30),$wt=new CC("SELF_LOOP_ROUTER",31),_bt=new CC("COMMENT_NODE_MARGIN_CALCULATOR",32),Vbt=new CC("END_LABEL_PREPROCESSOR",33),wwt=new CC("LABEL_DUMMY_SWITCHER",34),Fbt=new CC("CENTER_LABEL_MANAGEMENT_PROCESSOR",35),dwt=new CC("LABEL_SIDE_SELECTOR",36),cwt=new CC("HYPEREDGE_DUMMY_MERGER",37),nwt=new CC("HIERARCHICAL_PORT_DUMMY_SIZE_PROCESSOR",38),mwt=new CC("LAYER_SIZE_AND_GRAPH_HEIGHT_CALCULATOR",39),ewt=new CC("HIERARCHICAL_PORT_POSITION_PROCESSOR",40),Ubt=new CC("CONSTRAINTS_POSTPROCESSOR",41),Bbt=new CC("COMMENT_POSTPROCESSOR",42),awt=new CC("HYPERNODE_PROCESSOR",43),twt=new CC("HIERARCHICAL_PORT_ORTHOGONAL_EDGE_ROUTER",44),vwt=new CC("LONG_EDGE_JOINER",45),Lwt=new CC("SELF_LOOP_POSTPROCESSOR",46),Kbt=new CC("BREAKING_POINT_REMOVER",47),Mwt=new CC("NORTH_SOUTH_PORT_POSTPROCESSOR",48),rwt=new CC("HORIZONTAL_COMPACTOR",49),bwt=new CC("LABEL_DUMMY_REMOVER",50),Jbt=new CC("FINAL_SPLINE_BENDPOINTS_CALCULATOR",51),Wbt=new CC("END_LABEL_SORTER",52),Owt=new CC("REVERSED_EDGE_RESTORER",53),zbt=new CC("END_LABEL_POSTPROCESSOR",54),Ybt=new CC("HIERARCHICAL_NODE_RESIZER",55),Gbt=new CC("DIRECTION_POSTPROCESSOR",56)}function VYn(){VYn=E,Vin(),mvt=new mL(B6n,vvt=dgt),xvt=new mL(H6n,(qx(),!1)),Y6(),Bvt=new mL(U6n,Hvt=kpt),akt=new mL(G6n,!1),okt=new mL(q6n,!0),Dmt=new mL(X6n,!1),nin(),Skt=new mL(z6n,Pkt=Gjt),xwn(1),Dkt=new mL(V6n,xwn(7)),xkt=new mL(W6n,!1),Rvt=new mL(Q6n,!1),kvn(),gvt=new mL(J6n,pvt=sgt),MKn(),rkt=new mL(Y6n,ckt=rjt),Gpn(),Vvt=new mL(Z6n,Wvt=Lmt),xwn(-1),zvt=new mL(n5n,null),xwn(-1),Qvt=new mL(t5n,xwn(-1)),xwn(-1),Jvt=new mL(e5n,xwn(4)),xwn(-1),Zvt=new mL(i5n,xwn(2)),THn(),ekt=new mL(r5n,ikt=$jt),xwn(0),tkt=new mL(c5n,xwn(0)),qvt=new mL(a5n,xwn(vZn)),jan(),wvt=new mL(o5n,dvt=Zdt),Jmt=new mL(u5n,!1),avt=new mL(s5n,.1),lvt=new mL(h5n,!1),uvt=new mL(f5n,null),svt=new mL(l5n,null),xwn(-1),hvt=new mL(b5n,null),xwn(-1),fvt=new mL(w5n,xwn(-1)),xwn(0),Ymt=new mL(d5n,xwn(40)),ihn(),ivt=new mL(g5n,rvt=lpt),Zmt=new mL(p5n,nvt=hpt),pyn(),jkt=new mL(m5n,Ekt=vjt),wkt=new Cm(v5n),Wtn(),ukt=new mL(k5n,skt=Lgt),ESn(),fkt=new mL(y5n,lkt=Fgt),new Jm,pkt=new mL(M5n,.3),vkt=new Cm(T5n),Yyn(),kkt=new mL(j5n,ykt=djt),isn(),Svt=new mL(E5n,Pvt=nEt),Sln(),Cvt=new mL(S5n,Ivt=aEt),kbn(),Ovt=new mL(P5n,Avt=fEt),Nvt=new mL(C5n,.2),jvt=new mL(I5n,2),Akt=new mL(O5n,null),Nkt=new mL(A5n,10),Lkt=new mL(L5n,10),$kt=new mL(N5n,20),xwn(0),Ckt=new mL($5n,xwn(0)),xwn(0),Ikt=new mL(D5n,xwn(0)),xwn(0),Okt=new mL(x5n,xwn(0)),xmt=new mL(R5n,!1),RIn(),Fmt=new mL(K5n,_mt=Vgt),H7(),Rmt=new mL(F5n,Kmt=Wdt),Fvt=new mL(_5n,!1),xwn(0),Kvt=new mL(B5n,xwn(16)),xwn(0),_vt=new mL(H5n,xwn(5)),zhn(),ryt=new mL(U5n,cyt=kEt),Rkt=new mL(G5n,10),_kt=new mL(q5n,1),ran(),Vkt=new mL(X5n,Wkt=cgt),Ukt=new Cm(z5n),Xkt=xwn(1),xwn(0),qkt=new mL(V5n,Xkt),ian(),syt=new mL(W5n,hyt=wEt),ayt=new Cm(Q5n),nyt=new mL(J5n,!0),Ykt=new mL(Y5n,2),eyt=new mL(Z5n,!0),tOn(),Mvt=new mL(n8n,Tvt=Cgt),vAn(),kvt=new mL(t8n,yvt=Hdt),yvn(),Wmt=new mL(e8n,Qmt=Fjt),Vmt=new mL(i8n,!1),zmt=new mL(r8n,!1),Uvn(),Bmt=new mL(c8n,Hmt=tbt),Cwn(),qmt=new mL(a8n,Xmt=ujt),Umt=new mL(o8n,0),Gmt=new mL(u8n,0),Gvt=fgt,Uvt=Ydt,Yvt=ijt,nkt=ijt,Xvt=YTt,Own(),ovt=Ixt,bvt=Zdt,cvt=Zdt,tvt=Zdt,evt=Ixt,dkt=Mjt,gkt=vjt,hkt=vjt,bkt=vjt,mkt=yjt,Tkt=Mjt,Mkt=Mjt,_gn(),Lvt=hxt,$vt=hxt,Dvt=fEt,Evt=sxt,Kkt=yEt,Fkt=vEt,Bkt=yEt,Hkt=vEt,Qkt=yEt,Jkt=vEt,Gkt=rgt,zkt=cgt,fyt=yEt,lyt=vEt,oyt=yEt,uyt=vEt,tyt=vEt,Zkt=vEt,iyt=vEt}function WYn(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k,y,M,T,j,E,S,P,C,I,O,A,L,N,$,D,x,R,K,F,_,B,H,U,G,q,X,z,V,W,Q,J,Y,Z,nn,tn,en,rn,cn,an,on,un;for(Y=0,N=0,x=(O=t).length;N0&&(n.a[U.p]=Y++)}for(rn=0,$=0,R=(A=i).length;$0;){for(MK(z.b>0),X=0,u=new Ww((U=uG(z.a.Xb(z.c=--z.b),12)).e);u.a0&&(U.j==(KQn(),yRt)?(n.a[U.p]=rn,++rn):(n.a[U.p]=rn+K+_,++_))}rn+=_}for(q=new Ym,d=new XL,L=0,D=(I=t).length;Lh.b&&(h.b=V)):U.i.c==J&&(Vh.c&&(h.c=V));for(Ntn(g,0,g.length,null),en=Inn(YHt,W1n,28,g.length,15,1),r=Inn(YHt,W1n,28,rn+1,15,1),m=0;m0;)j%2>0&&(c+=on[j+1]),++on[j=(j-1)/2|0];for(S=Inn(ZEt,EZn,374,2*g.length,0,1),y=0;y0&&(A1(O.f),0)){if(uG(zDn(g,UDt),280)==fKt)throw hv(new jM("Topdown Layout Providers should only be used on parallel nodes."));XA(A1(O.f)),null.Um(),vN(g,e.Math.max(g.g,null.Vm),e.Math.max(g.f,null.Vm))}else null!=zDn(g,VDt)&&(H=uG(zDn(g,VDt),347).Tg(g),vN(g,e.Math.max(g.g,H.a),e.Math.max(g.f,H.b)));if(D=uG(zDn(t,W$t),107),b=t.g-(D.b+D.c),l=t.f-(D.d+D.a),G.bh("Available Child Area: ("+b+"|"+l+")"),Myn(t,c$t,b/l),Mkn(t,c,r.eh(N)),uG(zDn(t,UDt),280)==bKt&&(VJn(t),vN(t,D.b+uM(pK(zDn(t,h$t)))+D.c,D.d+uM(pK(zDn(t,s$t)))+D.a)),G.bh("Executed layout algorithm: "+mK(zDn(t,e$t))+" on node "+t.k),uG(zDn(t,UDt),280)==fKt){if(b<0||l<0)throw hv(new jM("The size defined by the parent parallel node is too small for the space provided by the paddings of the child hierarchical node. "+t.k));for(vnn(t,h$t)||vnn(t,s$t)||VJn(t),d=uM(pK(zDn(t,h$t))),w=uM(pK(zDn(t,s$t))),G.bh("Desired Child Area: ("+d+"|"+w+")"),R=b/d,K=l/w,x=e.Math.min(R,e.Math.min(K,uM(pK(zDn(t,GDt))))),Myn(t,XDt,x),G.bh(t.k+" -- Local Scale Factor (X|Y): ("+R+"|"+K+")"),v=uG(zDn(t,l$t),21),a=0,o=0,x'?":m_(rit,n)?"'(?<' or '(? toIndex: ",s2n=", toIndex: ",h2n="Index: ",f2n=", Size: ",l2n="org.eclipse.elk.alg.common",b2n={50:1},w2n="org.eclipse.elk.alg.common.compaction",d2n="Scanline/EventHandler",g2n="org.eclipse.elk.alg.common.compaction.oned",p2n="CNode belongs to another CGroup.",m2n="ISpacingsHandler/1",v2n="The ",k2n=" instance has been finished already.",y2n="The direction ",M2n=" is not supported by the CGraph instance.",T2n="OneDimensionalCompactor",j2n="OneDimensionalCompactor/lambda$0$Type",E2n="Quadruplet",S2n="ScanlineConstraintCalculator",P2n="ScanlineConstraintCalculator/ConstraintsScanlineHandler",C2n="ScanlineConstraintCalculator/ConstraintsScanlineHandler/lambda$0$Type",I2n="ScanlineConstraintCalculator/Timestamp",O2n="ScanlineConstraintCalculator/lambda$0$Type",A2n={178:1,46:1},L2n="org.eclipse.elk.alg.common.compaction.options",N2n="org.eclipse.elk.core.data",$2n="org.eclipse.elk.polyomino.traversalStrategy",D2n="org.eclipse.elk.polyomino.lowLevelSort",x2n="org.eclipse.elk.polyomino.highLevelSort",R2n="org.eclipse.elk.polyomino.fill",K2n={134:1},F2n="polyomino",_2n="org.eclipse.elk.alg.common.networksimplex",B2n={183:1,3:1,4:1},H2n="org.eclipse.elk.alg.common.nodespacing",U2n="org.eclipse.elk.alg.common.nodespacing.cellsystem",G2n="CENTER",q2n={217:1,336:1},X2n={3:1,4:1,5:1,603:1},z2n="LEFT",V2n="RIGHT",W2n="Vertical alignment cannot be null",Q2n="BOTTOM",J2n="org.eclipse.elk.alg.common.nodespacing.internal",Y2n="UNDEFINED",Z2n=.01,n3n="org.eclipse.elk.alg.common.nodespacing.internal.algorithm",t3n="LabelPlacer/lambda$0$Type",e3n="LabelPlacer/lambda$1$Type",i3n="portRatioOrPosition",r3n="org.eclipse.elk.alg.common.overlaps",c3n="DOWN",a3n="org.eclipse.elk.alg.common.polyomino",o3n="NORTH",u3n="EAST",s3n="SOUTH",h3n="WEST",f3n="org.eclipse.elk.alg.common.polyomino.structures",l3n="Direction",b3n="Grid is only of size ",w3n=". Requested point (",d3n=") is out of bounds.",g3n=" Given center based coordinates were (",p3n="org.eclipse.elk.graph.properties",m3n="IPropertyHolder",v3n={3:1,96:1,137:1},k3n="org.eclipse.elk.alg.common.spore",y3n="org.eclipse.elk.alg.common.utils",M3n={205:1},T3n="org.eclipse.elk.core",j3n="Connected Components Compaction",E3n="org.eclipse.elk.alg.disco",S3n="org.eclipse.elk.alg.disco.graph",P3n="org.eclipse.elk.alg.disco.options",C3n="CompactionStrategy",I3n="org.eclipse.elk.disco.componentCompaction.strategy",O3n="org.eclipse.elk.disco.componentCompaction.componentLayoutAlgorithm",A3n="org.eclipse.elk.disco.debug.discoGraph",L3n="org.eclipse.elk.disco.debug.discoPolys",N3n="componentCompaction",$3n="org.eclipse.elk.disco",D3n="org.eclipse.elk.spacing.componentComponent",x3n="org.eclipse.elk.edge.thickness",R3n="org.eclipse.elk.aspectRatio",K3n="org.eclipse.elk.padding",F3n="org.eclipse.elk.alg.disco.transform",_3n=1.5707963267948966,B3n=17976931348623157e292,H3n={3:1,4:1,5:1,198:1},U3n={3:1,6:1,4:1,5:1,100:1,115:1},G3n="org.eclipse.elk.alg.force",q3n="ComponentsProcessor",X3n="ComponentsProcessor/1",z3n="ElkGraphImporter/lambda$0$Type",V3n="org.eclipse.elk.alg.force.graph",W3n="Component Layout",Q3n="org.eclipse.elk.alg.force.model",J3n="org.eclipse.elk.force.model",Y3n="org.eclipse.elk.force.iterations",Z3n="org.eclipse.elk.force.repulsivePower",n4n="org.eclipse.elk.force.temperature",t4n=.001,e4n="org.eclipse.elk.force.repulsion",i4n="org.eclipse.elk.alg.force.options",r4n=1.600000023841858,c4n="org.eclipse.elk.force",a4n="org.eclipse.elk.priority",o4n="org.eclipse.elk.spacing.nodeNode",u4n="org.eclipse.elk.spacing.edgeLabel",s4n="org.eclipse.elk.randomSeed",h4n="org.eclipse.elk.separateConnectedComponents",f4n="org.eclipse.elk.interactive",l4n="org.eclipse.elk.portConstraints",b4n="org.eclipse.elk.edgeLabels.inline",w4n="org.eclipse.elk.omitNodeMicroLayout",d4n="org.eclipse.elk.nodeSize.fixedGraphSize",g4n="org.eclipse.elk.nodeSize.options",p4n="org.eclipse.elk.nodeSize.constraints",m4n="org.eclipse.elk.nodeLabels.placement",v4n="org.eclipse.elk.portLabels.placement",k4n="org.eclipse.elk.topdownLayout",y4n="org.eclipse.elk.topdown.scaleFactor",M4n="org.eclipse.elk.topdown.hierarchicalNodeWidth",T4n="org.eclipse.elk.topdown.hierarchicalNodeAspectRatio",j4n="org.eclipse.elk.topdown.nodeType",E4n="origin",S4n="random",P4n="boundingBox.upLeft",C4n="boundingBox.lowRight",I4n="org.eclipse.elk.stress.fixed",O4n="org.eclipse.elk.stress.desiredEdgeLength",A4n="org.eclipse.elk.stress.dimension",L4n="org.eclipse.elk.stress.epsilon",N4n="org.eclipse.elk.stress.iterationLimit",$4n="org.eclipse.elk.stress",D4n="ELK Stress",x4n="org.eclipse.elk.nodeSize.minimum",R4n="org.eclipse.elk.alg.force.stress",K4n="Layered layout",F4n="org.eclipse.elk.alg.layered",_4n="org.eclipse.elk.alg.layered.compaction.components",B4n="org.eclipse.elk.alg.layered.compaction.oned",H4n="org.eclipse.elk.alg.layered.compaction.oned.algs",U4n="org.eclipse.elk.alg.layered.compaction.recthull",G4n="org.eclipse.elk.alg.layered.components",q4n="NONE",X4n="MODEL_ORDER",z4n={3:1,6:1,4:1,9:1,5:1,126:1},V4n={3:1,6:1,4:1,5:1,150:1,100:1,115:1},W4n="org.eclipse.elk.alg.layered.compound",Q4n={47:1},J4n="org.eclipse.elk.alg.layered.graph",Y4n=" -> ",Z4n="Not supported by LGraph",n6n="Port side is undefined",t6n={3:1,6:1,4:1,5:1,483:1,150:1,100:1,115:1},e6n={3:1,6:1,4:1,5:1,150:1,199:1,210:1,100:1,115:1},i6n={3:1,6:1,4:1,5:1,150:1,2042:1,210:1,100:1,115:1},r6n="([{\"' \t\r\n",c6n=")]}\"' \t\r\n",a6n="The given string contains parts that cannot be parsed as numbers.",o6n="org.eclipse.elk.core.math",u6n={3:1,4:1,140:1,214:1,423:1},s6n={3:1,4:1,107:1,214:1,423:1},h6n="org.eclipse.elk.alg.layered.graph.transform",f6n="ElkGraphImporter",l6n="ElkGraphImporter/lambda$1$Type",b6n="ElkGraphImporter/lambda$2$Type",w6n="ElkGraphImporter/lambda$4$Type",d6n="org.eclipse.elk.alg.layered.intermediate",g6n="Node margin calculation",p6n="ONE_SIDED_GREEDY_SWITCH",m6n="TWO_SIDED_GREEDY_SWITCH",v6n="No implementation is available for the layout processor ",k6n="IntermediateProcessorStrategy",y6n="Node '",M6n="FIRST_SEPARATE",T6n="LAST_SEPARATE",j6n="Odd port side processing",E6n="org.eclipse.elk.alg.layered.intermediate.compaction",S6n="org.eclipse.elk.alg.layered.intermediate.greedyswitch",P6n="org.eclipse.elk.alg.layered.p3order.counting",C6n={230:1},I6n="org.eclipse.elk.alg.layered.intermediate.loops",O6n="org.eclipse.elk.alg.layered.intermediate.loops.ordering",A6n="org.eclipse.elk.alg.layered.intermediate.loops.routing",L6n="org.eclipse.elk.alg.layered.intermediate.preserveorder",N6n="org.eclipse.elk.alg.layered.intermediate.wrapping",$6n="org.eclipse.elk.alg.layered.options",D6n="INTERACTIVE",x6n="GREEDY",R6n="DEPTH_FIRST",K6n="EDGE_LENGTH",F6n="SELF_LOOPS",_6n="firstTryWithInitialOrder",B6n="org.eclipse.elk.layered.directionCongruency",H6n="org.eclipse.elk.layered.feedbackEdges",U6n="org.eclipse.elk.layered.interactiveReferencePoint",G6n="org.eclipse.elk.layered.mergeEdges",q6n="org.eclipse.elk.layered.mergeHierarchyEdges",X6n="org.eclipse.elk.layered.allowNonFlowPortsToSwitchSides",z6n="org.eclipse.elk.layered.portSortingStrategy",V6n="org.eclipse.elk.layered.thoroughness",W6n="org.eclipse.elk.layered.unnecessaryBendpoints",Q6n="org.eclipse.elk.layered.generatePositionAndLayerIds",J6n="org.eclipse.elk.layered.cycleBreaking.strategy",Y6n="org.eclipse.elk.layered.layering.strategy",Z6n="org.eclipse.elk.layered.layering.layerConstraint",n5n="org.eclipse.elk.layered.layering.layerChoiceConstraint",t5n="org.eclipse.elk.layered.layering.layerId",e5n="org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth",i5n="org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor",r5n="org.eclipse.elk.layered.layering.nodePromotion.strategy",c5n="org.eclipse.elk.layered.layering.nodePromotion.maxIterations",a5n="org.eclipse.elk.layered.layering.coffmanGraham.layerBound",o5n="org.eclipse.elk.layered.crossingMinimization.strategy",u5n="org.eclipse.elk.layered.crossingMinimization.forceNodeModelOrder",s5n="org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness",h5n="org.eclipse.elk.layered.crossingMinimization.semiInteractive",f5n="org.eclipse.elk.layered.crossingMinimization.inLayerPredOf",l5n="org.eclipse.elk.layered.crossingMinimization.inLayerSuccOf",b5n="org.eclipse.elk.layered.crossingMinimization.positionChoiceConstraint",w5n="org.eclipse.elk.layered.crossingMinimization.positionId",d5n="org.eclipse.elk.layered.crossingMinimization.greedySwitch.activationThreshold",g5n="org.eclipse.elk.layered.crossingMinimization.greedySwitch.type",p5n="org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type",m5n="org.eclipse.elk.layered.nodePlacement.strategy",v5n="org.eclipse.elk.layered.nodePlacement.favorStraightEdges",k5n="org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening",y5n="org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment",M5n="org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening",T5n="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility",j5n="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default",E5n="org.eclipse.elk.layered.edgeRouting.selfLoopDistribution",S5n="org.eclipse.elk.layered.edgeRouting.selfLoopOrdering",P5n="org.eclipse.elk.layered.edgeRouting.splines.mode",C5n="org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor",I5n="org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth",O5n="org.eclipse.elk.layered.spacing.baseValue",A5n="org.eclipse.elk.layered.spacing.edgeNodeBetweenLayers",L5n="org.eclipse.elk.layered.spacing.edgeEdgeBetweenLayers",N5n="org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers",$5n="org.eclipse.elk.layered.priority.direction",D5n="org.eclipse.elk.layered.priority.shortness",x5n="org.eclipse.elk.layered.priority.straightness",R5n="org.eclipse.elk.layered.compaction.connectedComponents",K5n="org.eclipse.elk.layered.compaction.postCompaction.strategy",F5n="org.eclipse.elk.layered.compaction.postCompaction.constraints",_5n="org.eclipse.elk.layered.highDegreeNodes.treatment",B5n="org.eclipse.elk.layered.highDegreeNodes.threshold",H5n="org.eclipse.elk.layered.highDegreeNodes.treeHeight",U5n="org.eclipse.elk.layered.wrapping.strategy",G5n="org.eclipse.elk.layered.wrapping.additionalEdgeSpacing",q5n="org.eclipse.elk.layered.wrapping.correctionFactor",X5n="org.eclipse.elk.layered.wrapping.cutting.strategy",z5n="org.eclipse.elk.layered.wrapping.cutting.cuts",V5n="org.eclipse.elk.layered.wrapping.cutting.msd.freedom",W5n="org.eclipse.elk.layered.wrapping.validify.strategy",Q5n="org.eclipse.elk.layered.wrapping.validify.forbiddenIndices",J5n="org.eclipse.elk.layered.wrapping.multiEdge.improveCuts",Y5n="org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty",Z5n="org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges",n8n="org.eclipse.elk.layered.edgeLabels.sideSelection",t8n="org.eclipse.elk.layered.edgeLabels.centerLabelPlacementStrategy",e8n="org.eclipse.elk.layered.considerModelOrder.strategy",i8n="org.eclipse.elk.layered.considerModelOrder.portModelOrder",r8n="org.eclipse.elk.layered.considerModelOrder.noModelOrder",c8n="org.eclipse.elk.layered.considerModelOrder.components",a8n="org.eclipse.elk.layered.considerModelOrder.longEdgeStrategy",o8n="org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence",u8n="org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence",s8n="layering",h8n="layering.minWidth",f8n="layering.nodePromotion",l8n="crossingMinimization",b8n="org.eclipse.elk.hierarchyHandling",w8n="crossingMinimization.greedySwitch",d8n="nodePlacement",g8n="nodePlacement.bk",p8n="edgeRouting",m8n="org.eclipse.elk.edgeRouting",v8n="spacing",k8n="priority",y8n="compaction",M8n="compaction.postCompaction",T8n="Specifies whether and how post-process compaction is applied.",j8n="highDegreeNodes",E8n="wrapping",S8n="wrapping.cutting",P8n="wrapping.validify",C8n="wrapping.multiEdge",I8n="edgeLabels",O8n="considerModelOrder",A8n="org.eclipse.elk.spacing.commentComment",L8n="org.eclipse.elk.spacing.commentNode",N8n="org.eclipse.elk.spacing.edgeEdge",$8n="org.eclipse.elk.spacing.edgeNode",D8n="org.eclipse.elk.spacing.labelLabel",x8n="org.eclipse.elk.spacing.labelPortHorizontal",R8n="org.eclipse.elk.spacing.labelPortVertical",K8n="org.eclipse.elk.spacing.labelNode",F8n="org.eclipse.elk.spacing.nodeSelfLoop",_8n="org.eclipse.elk.spacing.portPort",B8n="org.eclipse.elk.spacing.individual",H8n="org.eclipse.elk.port.borderOffset",U8n="org.eclipse.elk.noLayout",G8n="org.eclipse.elk.port.side",q8n="org.eclipse.elk.debugMode",X8n="org.eclipse.elk.alignment",z8n="org.eclipse.elk.insideSelfLoops.activate",V8n="org.eclipse.elk.insideSelfLoops.yo",W8n="org.eclipse.elk.direction",Q8n="org.eclipse.elk.nodeLabels.padding",J8n="org.eclipse.elk.portLabels.nextToPortIfPossible",Y8n="org.eclipse.elk.portLabels.treatAsGroup",Z8n="org.eclipse.elk.portAlignment.default",n9n="org.eclipse.elk.portAlignment.north",t9n="org.eclipse.elk.portAlignment.south",e9n="org.eclipse.elk.portAlignment.west",i9n="org.eclipse.elk.portAlignment.east",r9n="org.eclipse.elk.contentAlignment",c9n="org.eclipse.elk.junctionPoints",a9n="org.eclipse.elk.edgeLabels.placement",o9n="org.eclipse.elk.port.index",u9n="org.eclipse.elk.commentBox",s9n="org.eclipse.elk.hypernode",h9n="org.eclipse.elk.port.anchor",f9n="org.eclipse.elk.partitioning.activate",l9n="org.eclipse.elk.partitioning.partition",b9n="org.eclipse.elk.position",w9n="org.eclipse.elk.margins",d9n="org.eclipse.elk.spacing.portsSurrounding",g9n="org.eclipse.elk.interactiveLayout",p9n="org.eclipse.elk.core.util",m9n={3:1,4:1,5:1,601:1},v9n="NETWORK_SIMPLEX",k9n="SIMPLE",y9n={106:1,47:1},M9n="org.eclipse.elk.alg.layered.p1cycles",T9n="org.eclipse.elk.alg.layered.p2layers",j9n={413:1,230:1},E9n={846:1,3:1,4:1},S9n="org.eclipse.elk.alg.layered.p3order",P9n="org.eclipse.elk.alg.layered.p4nodes",C9n={3:1,4:1,5:1,854:1},I9n=1e-5,O9n="org.eclipse.elk.alg.layered.p4nodes.bk",A9n="org.eclipse.elk.alg.layered.p5edges",L9n="org.eclipse.elk.alg.layered.p5edges.orthogonal",N9n="org.eclipse.elk.alg.layered.p5edges.orthogonal.direction",$9n=1e-6,D9n="org.eclipse.elk.alg.layered.p5edges.splines",x9n=.09999999999999998,R9n=1e-8,K9n=4.71238898038469,F9n=3.141592653589793,_9n="org.eclipse.elk.alg.mrtree",B9n=.10000000149011612,H9n="SUPER_ROOT",U9n="org.eclipse.elk.alg.mrtree.graph",G9n=-17976931348623157e292,q9n="org.eclipse.elk.alg.mrtree.intermediate",X9n="Processor compute fanout",z9n={3:1,6:1,4:1,5:1,534:1,100:1,115:1},V9n="Set neighbors in level",W9n="org.eclipse.elk.alg.mrtree.options",Q9n="DESCENDANTS",J9n="org.eclipse.elk.mrtree.compaction",Y9n="org.eclipse.elk.mrtree.edgeEndTextureLength",Z9n="org.eclipse.elk.mrtree.treeLevel",n7n="org.eclipse.elk.mrtree.positionConstraint",t7n="org.eclipse.elk.mrtree.weighting",e7n="org.eclipse.elk.mrtree.edgeRoutingMode",i7n="org.eclipse.elk.mrtree.searchOrder",r7n="Position Constraint",c7n="org.eclipse.elk.mrtree",a7n="org.eclipse.elk.tree",o7n="Processor arrange level",u7n="org.eclipse.elk.alg.mrtree.p2order",s7n="org.eclipse.elk.alg.mrtree.p4route",h7n="org.eclipse.elk.alg.radial",f7n=6.283185307179586,l7n="Before",b7n=5e-324,w7n="After",d7n="org.eclipse.elk.alg.radial.intermediate",g7n="COMPACTION",p7n="org.eclipse.elk.alg.radial.intermediate.compaction",m7n={3:1,4:1,5:1,100:1},v7n="org.eclipse.elk.alg.radial.intermediate.optimization",k7n="No implementation is available for the layout option ",y7n="org.eclipse.elk.alg.radial.options",M7n="org.eclipse.elk.radial.centerOnRoot",T7n="org.eclipse.elk.radial.orderId",j7n="org.eclipse.elk.radial.radius",E7n="org.eclipse.elk.radial.rotate",S7n="org.eclipse.elk.radial.compactor",P7n="org.eclipse.elk.radial.compactionStepSize",C7n="org.eclipse.elk.radial.sorter",I7n="org.eclipse.elk.radial.wedgeCriteria",O7n="org.eclipse.elk.radial.optimizationCriteria",A7n="org.eclipse.elk.radial.rotation.targetAngle",L7n="org.eclipse.elk.radial.rotation.computeAdditionalWedgeSpace",N7n="org.eclipse.elk.radial.rotation.outgoingEdgeAngles",$7n="Compaction",D7n="rotation",x7n="org.eclipse.elk.radial",R7n="org.eclipse.elk.alg.radial.p1position.wedge",K7n="org.eclipse.elk.alg.radial.sorting",F7n=5.497787143782138,_7n=3.9269908169872414,B7n=2.356194490192345,H7n="org.eclipse.elk.alg.rectpacking",U7n="org.eclipse.elk.alg.rectpacking.intermediate",G7n="org.eclipse.elk.alg.rectpacking.options",q7n="org.eclipse.elk.rectpacking.trybox",X7n="org.eclipse.elk.rectpacking.currentPosition",z7n="org.eclipse.elk.rectpacking.desiredPosition",V7n="org.eclipse.elk.rectpacking.inNewRow",W7n="org.eclipse.elk.rectpacking.widthApproximation.strategy",Q7n="org.eclipse.elk.rectpacking.widthApproximation.targetWidth",J7n="org.eclipse.elk.rectpacking.widthApproximation.optimizationGoal",Y7n="org.eclipse.elk.rectpacking.widthApproximation.lastPlaceShift",Z7n="org.eclipse.elk.rectpacking.packing.strategy",nnt="org.eclipse.elk.rectpacking.packing.compaction.rowHeightReevaluation",tnt="org.eclipse.elk.rectpacking.packing.compaction.iterations",ent="org.eclipse.elk.rectpacking.whiteSpaceElimination.strategy",int="widthApproximation",rnt="Compaction Strategy",cnt="packing.compaction",ant="org.eclipse.elk.rectpacking",ont="org.eclipse.elk.alg.rectpacking.p1widthapproximation",unt="org.eclipse.elk.alg.rectpacking.p2packing",snt="No Compaction",hnt="org.eclipse.elk.alg.rectpacking.p3whitespaceelimination",fnt="org.eclipse.elk.alg.rectpacking.util",lnt="No implementation available for ",bnt="org.eclipse.elk.alg.spore",wnt="org.eclipse.elk.alg.spore.options",dnt="org.eclipse.elk.sporeCompaction",gnt="org.eclipse.elk.underlyingLayoutAlgorithm",pnt="org.eclipse.elk.processingOrder.treeConstruction",mnt="org.eclipse.elk.processingOrder.spanningTreeCostFunction",vnt="org.eclipse.elk.processingOrder.preferredRoot",knt="org.eclipse.elk.processingOrder.rootSelection",ynt="org.eclipse.elk.structure.structureExtractionStrategy",Mnt="org.eclipse.elk.compaction.compactionStrategy",Tnt="org.eclipse.elk.compaction.orthogonal",jnt="org.eclipse.elk.overlapRemoval.maxIterations",Ent="org.eclipse.elk.overlapRemoval.runScanline",Snt="processingOrder",Pnt="overlapRemoval",Cnt="org.eclipse.elk.sporeOverlap",Int="org.eclipse.elk.alg.spore.p1structure",Ont="org.eclipse.elk.alg.spore.p2processingorder",Ant="org.eclipse.elk.alg.spore.p3execution",Lnt="Topdown Layout",Nnt="Invalid index: ",$nt="org.eclipse.elk.core.alg",Dnt={341:1},xnt={295:1},Rnt="Make sure its type is registered with the ",Knt=" utility class.",Fnt="true",_nt="false",Bnt="Couldn't clone property '",Hnt=.05,Unt="org.eclipse.elk.core.options",Gnt=1.2999999523162842,qnt="org.eclipse.elk.box",Xnt="org.eclipse.elk.expandNodes",znt="org.eclipse.elk.box.packingMode",Vnt="org.eclipse.elk.algorithm",Wnt="org.eclipse.elk.resolvedAlgorithm",Qnt="org.eclipse.elk.bendPoints",Jnt="org.eclipse.elk.labelManager",Ynt="org.eclipse.elk.scaleFactor",Znt="org.eclipse.elk.childAreaWidth",ntt="org.eclipse.elk.childAreaHeight",ttt="org.eclipse.elk.animate",ett="org.eclipse.elk.animTimeFactor",itt="org.eclipse.elk.layoutAncestors",rtt="org.eclipse.elk.maxAnimTime",ctt="org.eclipse.elk.minAnimTime",att="org.eclipse.elk.progressBar",ott="org.eclipse.elk.validateGraph",utt="org.eclipse.elk.validateOptions",stt="org.eclipse.elk.zoomToFit",htt="org.eclipse.elk.font.name",ftt="org.eclipse.elk.font.size",ltt="org.eclipse.elk.topdown.sizeApproximator",btt="org.eclipse.elk.topdown.scaleCap",wtt="org.eclipse.elk.edge.type",dtt="partitioning",gtt="nodeLabels",ptt="portAlignment",mtt="nodeSize",vtt="port",ktt="portLabels",ytt="topdown",Mtt="insideSelfLoops",Ttt="org.eclipse.elk.fixed",jtt="org.eclipse.elk.random",Ett={3:1,34:1,22:1,347:1},Stt="port must have a parent node to calculate the port side",Ptt="The edge needs to have exactly one edge section. Found: ",Ctt="org.eclipse.elk.core.util.adapters",Itt="org.eclipse.emf.ecore",Ott="org.eclipse.elk.graph",Att="EMapPropertyHolder",Ltt="ElkBendPoint",Ntt="ElkGraphElement",$tt="ElkConnectableShape",Dtt="ElkEdge",xtt="ElkEdgeSection",Rtt="EModelElement",Ktt="ENamedElement",Ftt="ElkLabel",_tt="ElkNode",Btt="ElkPort",Htt={94:1,93:1},Utt="org.eclipse.emf.common.notify.impl",Gtt="The feature '",qtt="' is not a valid changeable feature",Xtt="Expecting null",ztt="' is not a valid feature",Vtt="The feature ID",Wtt=" is not a valid feature ID",Qtt=32768,Jtt={110:1,94:1,93:1,58:1,54:1,99:1},Ytt="org.eclipse.emf.ecore.impl",Ztt="org.eclipse.elk.graph.impl",net="Recursive containment not allowed for ",tet="The datatype '",eet="' is not a valid classifier",iet="The value '",ret={195:1,3:1,4:1},cet="The class '",aet="http://www.eclipse.org/elk/ElkGraph",oet="property",uet="value",set="source",het="properties",fet="identifier",bet="height",wet="width",det="parent",get="text",pet="children",met="hierarchical",vet="sources",ket="targets",yet="sections",Met="bendPoints",Tet="outgoingShape",jet="incomingShape",Eet="outgoingSections",Set="incomingSections",Pet="org.eclipse.emf.common.util",Cet="Severe implementation error in the Json to ElkGraph importer.",Iet="id",Oet="org.eclipse.elk.graph.json",Aet="Unhandled parameter types: ",Let="startPoint",Net="An edge must have at least one source and one target (edge id: '",$et="').",Det="Referenced edge section does not exist: ",xet=" (edge id: '",Ret="target",Ket="sourcePoint",Fet="targetPoint",_et="group",Bet="name",Het="connectableShape cannot be null",Uet="edge cannot be null",Get="Passed edge is not 'simple'.",qet="org.eclipse.elk.graph.util",Xet="The 'no duplicates' constraint is violated",zet="targetIndex=",Vet=", size=",Wet="sourceIndex=",Qet={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1},Jet={3:1,4:1,20:1,31:1,56:1,16:1,51:1,15:1,59:1,70:1,66:1,61:1,596:1},Yet="logging",Zet="measureExecutionTime",nit="parser.parse.1",tit="parser.parse.2",eit="parser.next.1",iit="parser.next.2",rit="parser.next.3",cit="parser.next.4",ait="parser.factor.1",oit="parser.factor.2",uit="parser.factor.3",sit="parser.factor.4",hit="parser.factor.5",fit="parser.factor.6",lit="parser.atom.1",bit="parser.atom.2",wit="parser.atom.3",dit="parser.atom.4",git="parser.atom.5",pit="parser.cc.1",mit="parser.cc.2",vit="parser.cc.3",kit="parser.cc.5",yit="parser.cc.6",Mit="parser.cc.7",Tit="parser.cc.8",jit="parser.ope.1",Eit="parser.ope.2",Sit="parser.ope.3",Pit="parser.descape.1",Cit="parser.descape.2",Iit="parser.descape.3",Oit="parser.descape.4",Ait="parser.descape.5",Lit="parser.process.1",Nit="parser.quantifier.1",$it="parser.quantifier.2",Dit="parser.quantifier.3",xit="parser.quantifier.4",Rit="parser.quantifier.5",Kit="org.eclipse.emf.common.notify",Fit={424:1,686:1},_it={3:1,4:1,20:1,31:1,56:1,16:1,15:1,70:1,61:1},Bit={378:1,152:1},Hit="index=",Uit={3:1,4:1,5:1,129:1},Git={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,61:1},qit={3:1,6:1,4:1,5:1,198:1},Xit={3:1,4:1,5:1,173:1,379:1},zit=";/?:@&=+$,",Vit="invalid authority: ",Wit="EAnnotation",Qit="ETypedElement",Jit="EStructuralFeature",Yit="EAttribute",Zit="EClassifier",nrt="EEnumLiteral",trt="EGenericType",ert="EOperation",irt="EParameter",rrt="EReference",crt="ETypeParameter",art="org.eclipse.emf.ecore.util",ort={79:1},urt={3:1,20:1,16:1,15:1,61:1,597:1,79:1,71:1,97:1},srt="org.eclipse.emf.ecore.util.FeatureMap$Entry",hrt=8192,frt=2048,lrt="byte",brt="char",wrt="double",drt="float",grt="int",prt="long",mrt="short",vrt="java.lang.Object",krt={3:1,4:1,5:1,254:1},yrt={3:1,4:1,5:1,688:1},Mrt={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1,71:1},Trt={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1,79:1,71:1,97:1},jrt="mixed",Ert="http:///org/eclipse/emf/ecore/util/ExtendedMetaData",Srt="kind",Prt={3:1,4:1,5:1,689:1},Crt={3:1,4:1,20:1,31:1,56:1,16:1,15:1,70:1,61:1,79:1,71:1,97:1},Irt={20:1,31:1,56:1,16:1,15:1,61:1,71:1},Ort={51:1,128:1,287:1},Art={76:1,343:1},Lrt="The value of type '",Nrt="' must be of type '",$rt=1352,Drt="http://www.eclipse.org/emf/2002/Ecore",xrt=-32768,Rrt="constraints",Krt="baseType",Frt="getEStructuralFeature",_rt="getFeatureID",Brt="feature",Hrt="getOperationID",Urt="operation",Grt="defaultValue",qrt="eTypeParameters",Xrt="isInstance",zrt="getEEnumLiteral",Vrt="eContainingClass",Wrt={57:1},Qrt={3:1,4:1,5:1,124:1},Jrt="org.eclipse.emf.ecore.resource",Yrt={94:1,93:1,599:1,2034:1},Zrt="org.eclipse.emf.ecore.resource.impl",nct="unspecified",tct="simple",ect="attribute",ict="attributeWildcard",rct="element",cct="elementWildcard",act="collapse",oct="itemType",uct="namespace",sct="##targetNamespace",hct="whiteSpace",fct="wildcards",lct="http://www.eclipse.org/emf/2003/XMLType",bct="##any",wct="uninitialized",dct="The multiplicity constraint is violated",gct="org.eclipse.emf.ecore.xml.type",pct="ProcessingInstruction",mct="SimpleAnyType",vct="XMLTypeDocumentRoot",kct="org.eclipse.emf.ecore.xml.type.impl",yct="INF",Mct="processing",Tct="ENTITIES_._base",jct="minLength",Ect="ENTITY",Sct="NCName",Pct="IDREFS_._base",Cct="integer",Ict="token",Oct="pattern",Act="[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*",Lct="\\i\\c*",Nct="[\\i-[:]][\\c-[:]]*",$ct="nonPositiveInteger",Dct="maxInclusive",xct="NMTOKEN",Rct="NMTOKENS_._base",Kct="nonNegativeInteger",Fct="minInclusive",_ct="normalizedString",Bct="unsignedByte",Hct="unsignedInt",Uct="18446744073709551615",Gct="unsignedShort",qct="processingInstruction",Xct="org.eclipse.emf.ecore.xml.type.internal",zct=1114111,Vct="Internal Error: shorthands: \\u",Wct="xml:isDigit",Qct="xml:isWord",Jct="xml:isSpace",Yct="xml:isNameChar",Zct="xml:isInitialNameChar",nat="09\u0660\u0669\u06f0\u06f9\u0966\u096f\u09e6\u09ef\u0a66\u0a6f\u0ae6\u0aef\u0b66\u0b6f\u0be7\u0bef\u0c66\u0c6f\u0ce6\u0cef\u0d66\u0d6f\u0e50\u0e59\u0ed0\u0ed9\u0f20\u0f29",tat="AZaz\xc0\xd6\xd8\xf6\xf8\u0131\u0134\u013e\u0141\u0148\u014a\u017e\u0180\u01c3\u01cd\u01f0\u01f4\u01f5\u01fa\u0217\u0250\u02a8\u02bb\u02c1\u0386\u0386\u0388\u038a\u038c\u038c\u038e\u03a1\u03a3\u03ce\u03d0\u03d6\u03da\u03da\u03dc\u03dc\u03de\u03de\u03e0\u03e0\u03e2\u03f3\u0401\u040c\u040e\u044f\u0451\u045c\u045e\u0481\u0490\u04c4\u04c7\u04c8\u04cb\u04cc\u04d0\u04eb\u04ee\u04f5\u04f8\u04f9\u0531\u0556\u0559\u0559\u0561\u0586\u05d0\u05ea\u05f0\u05f2\u0621\u063a\u0641\u064a\u0671\u06b7\u06ba\u06be\u06c0\u06ce\u06d0\u06d3\u06d5\u06d5\u06e5\u06e6\u0905\u0939\u093d\u093d\u0958\u0961\u0985\u098c\u098f\u0990\u0993\u09a8\u09aa\u09b0\u09b2\u09b2\u09b6\u09b9\u09dc\u09dd\u09df\u09e1\u09f0\u09f1\u0a05\u0a0a\u0a0f\u0a10\u0a13\u0a28\u0a2a\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59\u0a5c\u0a5e\u0a5e\u0a72\u0a74\u0a85\u0a8b\u0a8d\u0a8d\u0a8f\u0a91\u0a93\u0aa8\u0aaa\u0ab0\u0ab2\u0ab3\u0ab5\u0ab9\u0abd\u0abd\u0ae0\u0ae0\u0b05\u0b0c\u0b0f\u0b10\u0b13\u0b28\u0b2a\u0b30\u0b32\u0b33\u0b36\u0b39\u0b3d\u0b3d\u0b5c\u0b5d\u0b5f\u0b61\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95\u0b99\u0b9a\u0b9c\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8\u0baa\u0bae\u0bb5\u0bb7\u0bb9\u0c05\u0c0c\u0c0e\u0c10\u0c12\u0c28\u0c2a\u0c33\u0c35\u0c39\u0c60\u0c61\u0c85\u0c8c\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9\u0cde\u0cde\u0ce0\u0ce1\u0d05\u0d0c\u0d0e\u0d10\u0d12\u0d28\u0d2a\u0d39\u0d60\u0d61\u0e01\u0e2e\u0e30\u0e30\u0e32\u0e33\u0e40\u0e45\u0e81\u0e82\u0e84\u0e84\u0e87\u0e88\u0e8a\u0e8a\u0e8d\u0e8d\u0e94\u0e97\u0e99\u0e9f\u0ea1\u0ea3\u0ea5\u0ea5\u0ea7\u0ea7\u0eaa\u0eab\u0ead\u0eae\u0eb0\u0eb0\u0eb2\u0eb3\u0ebd\u0ebd\u0ec0\u0ec4\u0f40\u0f47\u0f49\u0f69\u10a0\u10c5\u10d0\u10f6\u1100\u1100\u1102\u1103\u1105\u1107\u1109\u1109\u110b\u110c\u110e\u1112\u113c\u113c\u113e\u113e\u1140\u1140\u114c\u114c\u114e\u114e\u1150\u1150\u1154\u1155\u1159\u1159\u115f\u1161\u1163\u1163\u1165\u1165\u1167\u1167\u1169\u1169\u116d\u116e\u1172\u1173\u1175\u1175\u119e\u119e\u11a8\u11a8\u11ab\u11ab\u11ae\u11af\u11b7\u11b8\u11ba\u11ba\u11bc\u11c2\u11eb\u11eb\u11f0\u11f0\u11f9\u11f9\u1e00\u1e9b\u1ea0\u1ef9\u1f00\u1f15\u1f18\u1f1d\u1f20\u1f45\u1f48\u1f4d\u1f50\u1f57\u1f59\u1f59\u1f5b\u1f5b\u1f5d\u1f5d\u1f5f\u1f7d\u1f80\u1fb4\u1fb6\u1fbc\u1fbe\u1fbe\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3\u1fd6\u1fdb\u1fe0\u1fec\u1ff2\u1ff4\u1ff6\u1ffc\u2126\u2126\u212a\u212b\u212e\u212e\u2180\u2182\u3007\u3007\u3021\u3029\u3041\u3094\u30a1\u30fa\u3105\u312c\u4e00\u9fa5\uac00\ud7a3",eat="Private Use",iat="ASSIGNED",rat="\0\x7f\x80\xff\u0100\u017f\u0180\u024f\u0250\u02af\u02b0\u02ff\u0300\u036f\u0370\u03ff\u0400\u04ff\u0530\u058f\u0590\u05ff\u0600\u06ff\u0700\u074f\u0780\u07bf\u0900\u097f\u0980\u09ff\u0a00\u0a7f\u0a80\u0aff\u0b00\u0b7f\u0b80\u0bff\u0c00\u0c7f\u0c80\u0cff\u0d00\u0d7f\u0d80\u0dff\u0e00\u0e7f\u0e80\u0eff\u0f00\u0fff\u1000\u109f\u10a0\u10ff\u1100\u11ff\u1200\u137f\u13a0\u13ff\u1400\u167f\u1680\u169f\u16a0\u16ff\u1780\u17ff\u1800\u18af\u1e00\u1eff\u1f00\u1fff\u2000\u206f\u2070\u209f\u20a0\u20cf\u20d0\u20ff\u2100\u214f\u2150\u218f\u2190\u21ff\u2200\u22ff\u2300\u23ff\u2400\u243f\u2440\u245f\u2460\u24ff\u2500\u257f\u2580\u259f\u25a0\u25ff\u2600\u26ff\u2700\u27bf\u2800\u28ff\u2e80\u2eff\u2f00\u2fdf\u2ff0\u2fff\u3000\u303f\u3040\u309f\u30a0\u30ff\u3100\u312f\u3130\u318f\u3190\u319f\u31a0\u31bf\u3200\u32ff\u3300\u33ff\u3400\u4db5\u4e00\u9fff\ua000\ua48f\ua490\ua4cf\uac00\ud7a3\ue000\uf8ff\uf900\ufaff\ufb00\ufb4f\ufb50\ufdff\ufe20\ufe2f\ufe30\ufe4f\ufe50\ufe6f\ufe70\ufefe\ufeff\ufeff\uff00\uffef",cat="UNASSIGNED",aat={3:1,122:1},oat="org.eclipse.emf.ecore.xml.type.util",uat={3:1,4:1,5:1,381:1},sat="org.eclipse.xtext.xbase.lib",hat="Cannot add elements to a Range",fat="Cannot set elements in a Range",lat="Cannot remove elements from a Range",bat="user.agent";e.goog=e.goog||{},e.goog.global=e.goog.global||e,sZn={},sDn(1,null,{},r),uZn.Fb=function(n){return SL(this,n)},uZn.Gb=function(){return this.Rm},uZn.Hb=function(){return xx(this)},uZn.Ib=function(){return Ij(Tbn(this))+"@"+(Hon(this)>>>0).toString(16)},uZn.equals=function(n){return this.Fb(n)},uZn.hashCode=function(){return this.Hb()},uZn.toString=function(){return this.Ib()},sDn(297,1,{297:1,2124:1},Ifn),uZn.ve=function(n){var t;return(t=new Ifn).i=4,t.c=n>1?B0(this,n-1):this,t},uZn.we=function(){return vK(this),this.b},uZn.xe=function(){return Ij(this)},uZn.ye=function(){return vK(this),this.k},uZn.ze=function(){return!!(4&this.i)},uZn.Ae=function(){return!!(1&this.i)},uZn.Ib=function(){return crn(this)},uZn.i=0;var wat,dat=zW(kZn,"Object",1),gat=zW(kZn,"Class",297);sDn(2096,1,yZn),zW(MZn,"Optional",2096),sDn(1191,2096,yZn,c),uZn.Fb=function(n){return n===this},uZn.Hb=function(){return 2040732332},uZn.Ib=function(){return"Optional.absent()"},uZn.Jb=function(n){return WW(n),gy(),wat},zW(MZn,"Absent",1191),sDn(636,1,{},FM),zW(MZn,"Joiner",636);var pat=Iq(MZn,"Predicate");sDn(589,1,{178:1,589:1,3:1,46:1},Hl),uZn.Mb=function(n){return Wfn(this,n)},uZn.Lb=function(n){return Wfn(this,n)},uZn.Fb=function(n){var t;return!!F$(n,589)&&(t=uG(n,589),PDn(this.a,t.a))},uZn.Hb=function(){return Zfn(this.a)+306654252},uZn.Ib=function(){return eAn(this.a)},zW(MZn,"Predicates/AndPredicate",589),sDn(419,2096,{419:1,3:1},Ul),uZn.Fb=function(n){var t;return!!F$(n,419)&&(t=uG(n,419),udn(this.a,t.a))},uZn.Hb=function(){return 1502476572+Hon(this.a)},uZn.Ib=function(){return CZn+this.a+")"},uZn.Jb=function(n){return new Ul(bZ(n.Kb(this.a),"the Function passed to Optional.transform() must not return null."))},zW(MZn,"Present",419),sDn(204,1,OZn),uZn.Nb=function(n){SV(this,n)},uZn.Qb=function(){_M()},zW(AZn,"UnmodifiableIterator",204),sDn(2076,204,LZn),uZn.Qb=function(){_M()},uZn.Rb=function(n){throw hv(new Kv)},uZn.Wb=function(n){throw hv(new Kv)},zW(AZn,"UnmodifiableListIterator",2076),sDn(399,2076,LZn),uZn.Ob=function(){return this.c0},uZn.Pb=function(){if(this.c>=this.d)throw hv(new Bv);return this.Xb(this.c++)},uZn.Tb=function(){return this.c},uZn.Ub=function(){if(this.c<=0)throw hv(new Bv);return this.Xb(--this.c)},uZn.Vb=function(){return this.c-1},uZn.c=0,uZn.d=0,zW(AZn,"AbstractIndexedListIterator",399),sDn(713,204,OZn),uZn.Ob=function(){return oon(this)},uZn.Pb=function(){return yen(this)},uZn.e=1,zW(AZn,"AbstractIterator",713),sDn(2084,1,{229:1}),uZn.Zb=function(){return this.f||(this.f=this.ac())},uZn.Fb=function(n){return Aln(this,n)},uZn.Hb=function(){return Hon(this.Zb())},uZn.dc=function(){return 0==this.gc()},uZn.ec=function(){return kz(this)},uZn.Ib=function(){return cpn(this.Zb())},zW(AZn,"AbstractMultimap",2084),sDn(742,2084,NZn),uZn.$b=function(){ban(this)},uZn._b=function(n){return jj(this,n)},uZn.ac=function(){return new OE(this,this.c)},uZn.ic=function(n){return this.hc()},uZn.bc=function(){return new RD(this,this.c)},uZn.jc=function(){return this.mc(this.hc())},uZn.kc=function(){return new My(this)},uZn.lc=function(){return ICn(this.c.vc().Nc(),new o,64,this.d)},uZn.cc=function(n){return Y9(this,n)},uZn.fc=function(n){return twn(this,n)},uZn.gc=function(){return this.d},uZn.mc=function(n){return hZ(),new qw(n)},uZn.nc=function(){return new yy(this)},uZn.oc=function(){return ICn(this.c.Cc().Nc(),new a,64,this.d)},uZn.pc=function(n,t){return new A7(this,n,t,null)},uZn.d=0,zW(AZn,"AbstractMapBasedMultimap",742),sDn(1696,742,NZn),uZn.hc=function(){return new R7(this.a)},uZn.jc=function(){return hZ(),hZ(),zot},uZn.cc=function(n){return uG(Y9(this,n),15)},uZn.fc=function(n){return uG(twn(this,n),15)},uZn.Zb=function(){return nZ(this)},uZn.Fb=function(n){return Aln(this,n)},uZn.qc=function(n){return uG(Y9(this,n),15)},uZn.rc=function(n){return uG(twn(this,n),15)},uZn.mc=function(n){return SZ(uG(n,15))},uZn.pc=function(n,t){return S6(this,n,uG(t,15),null)},zW(AZn,"AbstractListMultimap",1696),sDn(748,1,$Zn),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return this.c.Ob()||this.e.Ob()},uZn.Pb=function(){var n;return this.e.Ob()||(n=uG(this.c.Pb(),44),this.b=n.ld(),this.a=uG(n.md(),16),this.e=this.a.Kc()),this.sc(this.b,this.e.Pb())},uZn.Qb=function(){this.e.Qb(),uG(nJ(this.a),16).dc()&&this.c.Qb(),--this.d.d},zW(AZn,"AbstractMapBasedMultimap/Itr",748),sDn(1129,748,$Zn,yy),uZn.sc=function(n,t){return t},zW(AZn,"AbstractMapBasedMultimap/1",1129),sDn(1130,1,{},a),uZn.Kb=function(n){return uG(n,16).Nc()},zW(AZn,"AbstractMapBasedMultimap/1methodref$spliterator$Type",1130),sDn(1131,748,$Zn,My),uZn.sc=function(n,t){return new FE(n,t)},zW(AZn,"AbstractMapBasedMultimap/2",1131);var mat=Iq(DZn,"Map");sDn(2065,1,xZn),uZn.wc=function(n){Yun(this,n)},uZn.yc=function(n,t,e){return Jgn(this,n,t,e)},uZn.$b=function(){this.vc().$b()},uZn.tc=function(n){return sTn(this,n)},uZn._b=function(n){return!!TPn(this,n,!1)},uZn.uc=function(n){var t,e;for(t=this.vc().Kc();t.Ob();)if(e=uG(t.Pb(),44).md(),xA(n)===xA(e)||null!=n&&udn(n,e))return!0;return!1},uZn.Fb=function(n){var t,e,i;if(n===this)return!0;if(!F$(n,85))return!1;if(i=uG(n,85),this.gc()!=i.gc())return!1;for(e=i.vc().Kc();e.Ob();)if(t=uG(e.Pb(),44),!this.tc(t))return!1;return!0},uZn.xc=function(n){return DA(TPn(this,n,!1))},uZn.Hb=function(){return tfn(this.vc())},uZn.dc=function(){return 0==this.gc()},uZn.ec=function(){return new Lw(this)},uZn.zc=function(n,t){throw hv(new TM("Put not supported on this map"))},uZn.Ac=function(n){xun(this,n)},uZn.Bc=function(n){return DA(TPn(this,n,!0))},uZn.gc=function(){return this.vc().gc()},uZn.Ib=function(){return KPn(this)},uZn.Cc=function(){return new Fw(this)},zW(DZn,"AbstractMap",2065),sDn(2085,2065,xZn),uZn.bc=function(){return new VE(this)},uZn.vc=function(){return vz(this)},uZn.ec=function(){return this.g||(this.g=this.bc())},uZn.Cc=function(){return this.i||(this.i=new zE(this))},zW(AZn,"Maps/ViewCachingAbstractMap",2085),sDn(402,2085,xZn,OE),uZn.xc=function(n){return srn(this,n)},uZn.Bc=function(n){return abn(this,n)},uZn.$b=function(){this.d==this.e.c?this.e.$b():Hq(new Gq(this))},uZn._b=function(n){return Uwn(this.d,n)},uZn.Ec=function(){return new Gl(this)},uZn.Dc=function(){return this.Ec()},uZn.Fb=function(n){return this===n||udn(this.d,n)},uZn.Hb=function(){return Hon(this.d)},uZn.ec=function(){return this.e.ec()},uZn.gc=function(){return this.d.gc()},uZn.Ib=function(){return cpn(this.d)},zW(AZn,"AbstractMapBasedMultimap/AsMap",402);var vat=Iq(kZn,"Iterable");sDn(31,1,RZn),uZn.Jc=function(n){z8(this,n)},uZn.Lc=function(){return this.Oc()},uZn.Nc=function(){return new h3(this,0)},uZn.Oc=function(){return new fX(null,this.Nc())},uZn.Fc=function(n){throw hv(new TM("Add not supported on this collection"))},uZn.Gc=function(n){return Qon(this,n)},uZn.$b=function(){oY(this)},uZn.Hc=function(n){return Wpn(this,n,!1)},uZn.Ic=function(n){return yhn(this,n)},uZn.dc=function(){return 0==this.gc()},uZn.Mc=function(n){return Wpn(this,n,!0)},uZn.Pc=function(){return Sz(this)},uZn.Qc=function(n){return oTn(this,n)},uZn.Ib=function(){return vIn(this)},zW(DZn,"AbstractCollection",31);var kat=Iq(DZn,"Set");sDn(KZn,31,FZn),uZn.Nc=function(){return new h3(this,1)},uZn.Fb=function(n){return Fvn(this,n)},uZn.Hb=function(){return tfn(this)},zW(DZn,"AbstractSet",KZn),sDn(2068,KZn,FZn),zW(AZn,"Sets/ImprovedAbstractSet",2068),sDn(2069,2068,FZn),uZn.$b=function(){this.Rc().$b()},uZn.Hc=function(n){return Amn(this,n)},uZn.dc=function(){return this.Rc().dc()},uZn.Mc=function(n){var t;return!(!this.Hc(n)||!F$(n,44))&&(t=uG(n,44),this.Rc().ec().Mc(t.ld()))},uZn.gc=function(){return this.Rc().gc()},zW(AZn,"Maps/EntrySet",2069),sDn(1127,2069,FZn,Gl),uZn.Hc=function(n){return Gwn(this.a.d.vc(),n)},uZn.Kc=function(){return new Gq(this.a)},uZn.Rc=function(){return this.a},uZn.Mc=function(n){var t;return!!Gwn(this.a.d.vc(),n)&&(t=uG(nJ(uG(n,44)),44),H9(this.a.e,t.ld()),!0)},uZn.Nc=function(){return JU(this.a.d.vc().Nc(),new ql(this.a))},zW(AZn,"AbstractMapBasedMultimap/AsMap/AsMapEntries",1127),sDn(1128,1,{},ql),uZn.Kb=function(n){return O9(this.a,uG(n,44))},zW(AZn,"AbstractMapBasedMultimap/AsMap/AsMapEntries/0methodref$wrapEntry$Type",1128),sDn(746,1,$Zn,Gq),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){var n;return n=uG(this.b.Pb(),44),this.a=uG(n.md(),16),O9(this.c,n)},uZn.Ob=function(){return this.b.Ob()},uZn.Qb=function(){IB(!!this.a),this.b.Qb(),this.c.e.d-=this.a.gc(),this.a.$b(),this.a=null},zW(AZn,"AbstractMapBasedMultimap/AsMap/AsMapIterator",746),sDn(542,2068,FZn,VE),uZn.$b=function(){this.b.$b()},uZn.Hc=function(n){return this.b._b(n)},uZn.Jc=function(n){WW(n),this.b.wc(new db(n))},uZn.dc=function(){return this.b.dc()},uZn.Kc=function(){return new Ny(this.b.vc().Kc())},uZn.Mc=function(n){return!!this.b._b(n)&&(this.b.Bc(n),!0)},uZn.gc=function(){return this.b.gc()},zW(AZn,"Maps/KeySet",542),sDn(327,542,FZn,RD),uZn.$b=function(){Hq(new AE(this,this.b.vc().Kc()))},uZn.Ic=function(n){return this.b.ec().Ic(n)},uZn.Fb=function(n){return this===n||udn(this.b.ec(),n)},uZn.Hb=function(){return Hon(this.b.ec())},uZn.Kc=function(){return new AE(this,this.b.vc().Kc())},uZn.Mc=function(n){var t,e;return e=0,(t=uG(this.b.Bc(n),16))&&(e=t.gc(),t.$b(),this.a.d-=e),e>0},uZn.Nc=function(){return this.b.ec().Nc()},zW(AZn,"AbstractMapBasedMultimap/KeySet",327),sDn(747,1,$Zn,AE),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return this.c.Ob()},uZn.Pb=function(){return this.a=uG(this.c.Pb(),44),this.a.ld()},uZn.Qb=function(){var n;IB(!!this.a),n=uG(this.a.md(),16),this.c.Qb(),this.b.a.d-=n.gc(),n.$b(),this.a=null},zW(AZn,"AbstractMapBasedMultimap/KeySet/1",747),sDn(503,402,{85:1,133:1},NK),uZn.bc=function(){return this.Sc()},uZn.ec=function(){return this.Uc()},uZn.Sc=function(){return new yE(this.c,this.Wc())},uZn.Tc=function(){return this.Wc().Tc()},uZn.Uc=function(){return this.b||(this.b=this.Sc())},uZn.Vc=function(){return this.Wc().Vc()},uZn.Wc=function(){return uG(this.d,133)},zW(AZn,"AbstractMapBasedMultimap/SortedAsMap",503),sDn(446,503,_Zn,$K),uZn.bc=function(){return new ME(this.a,uG(uG(this.d,133),139))},uZn.Sc=function(){return new ME(this.a,uG(uG(this.d,133),139))},uZn.ec=function(){return uG(this.b||(this.b=new ME(this.a,uG(uG(this.d,133),139))),277)},uZn.Uc=function(){return uG(this.b||(this.b=new ME(this.a,uG(uG(this.d,133),139))),277)},uZn.Wc=function(){return uG(uG(this.d,133),139)},uZn.Xc=function(n){return uG(uG(this.d,133),139).Xc(n)},uZn.Yc=function(n){return uG(uG(this.d,133),139).Yc(n)},uZn.Zc=function(n,t){return new $K(this.a,uG(uG(this.d,133),139).Zc(n,t))},uZn.$c=function(n){return uG(uG(this.d,133),139).$c(n)},uZn._c=function(n){return uG(uG(this.d,133),139)._c(n)},uZn.ad=function(n,t){return new $K(this.a,uG(uG(this.d,133),139).ad(n,t))},zW(AZn,"AbstractMapBasedMultimap/NavigableAsMap",446),sDn(502,327,BZn,yE),uZn.Nc=function(){return this.b.ec().Nc()},zW(AZn,"AbstractMapBasedMultimap/SortedKeySet",502),sDn(401,502,HZn,ME),zW(AZn,"AbstractMapBasedMultimap/NavigableKeySet",401),sDn(551,31,RZn,A7),uZn.Fc=function(n){var t,e;return bpn(this),e=this.d.dc(),(t=this.d.Fc(n))&&(++this.f.d,e&&mF(this)),t},uZn.Gc=function(n){var t,e,i;return!n.dc()&&(bpn(this),i=this.d.gc(),(t=this.d.Gc(n))&&(e=this.d.gc(),this.f.d+=e-i,0==i&&mF(this)),t)},uZn.$b=function(){var n;bpn(this),0!=(n=this.d.gc())&&(this.d.$b(),this.f.d-=n,DX(this))},uZn.Hc=function(n){return bpn(this),this.d.Hc(n)},uZn.Ic=function(n){return bpn(this),this.d.Ic(n)},uZn.Fb=function(n){return n===this||(bpn(this),udn(this.d,n))},uZn.Hb=function(){return bpn(this),Hon(this.d)},uZn.Kc=function(){return bpn(this),new WU(this)},uZn.Mc=function(n){var t;return bpn(this),(t=this.d.Mc(n))&&(--this.f.d,DX(this)),t},uZn.gc=function(){return qA(this)},uZn.Nc=function(){return bpn(this),this.d.Nc()},uZn.Ib=function(){return bpn(this),cpn(this.d)},zW(AZn,"AbstractMapBasedMultimap/WrappedCollection",551);var yat=Iq(DZn,"List");sDn(744,551,{20:1,31:1,16:1,15:1},qz),uZn.jd=function(n){Lon(this,n)},uZn.Nc=function(){return bpn(this),this.d.Nc()},uZn.bd=function(n,t){var e;bpn(this),e=this.d.dc(),uG(this.d,15).bd(n,t),++this.a.d,e&&mF(this)},uZn.cd=function(n,t){var e,i,r;return!t.dc()&&(bpn(this),r=this.d.gc(),(e=uG(this.d,15).cd(n,t))&&(i=this.d.gc(),this.a.d+=i-r,0==r&&mF(this)),e)},uZn.Xb=function(n){return bpn(this),uG(this.d,15).Xb(n)},uZn.dd=function(n){return bpn(this),uG(this.d,15).dd(n)},uZn.ed=function(){return bpn(this),new JN(this)},uZn.fd=function(n){return bpn(this),new UY(this,n)},uZn.gd=function(n){var t;return bpn(this),t=uG(this.d,15).gd(n),--this.a.d,DX(this),t},uZn.hd=function(n,t){return bpn(this),uG(this.d,15).hd(n,t)},uZn.kd=function(n,t){return bpn(this),S6(this.a,this.e,uG(this.d,15).kd(n,t),this.b?this.b:this)},zW(AZn,"AbstractMapBasedMultimap/WrappedList",744),sDn(1126,744,{20:1,31:1,16:1,15:1,59:1},Yx),zW(AZn,"AbstractMapBasedMultimap/RandomAccessWrappedList",1126),sDn(628,1,$Zn,WU),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return FY(this),this.b.Ob()},uZn.Pb=function(){return FY(this),this.b.Pb()},uZn.Qb=function(){zD(this)},zW(AZn,"AbstractMapBasedMultimap/WrappedCollection/WrappedIterator",628),sDn(745,628,UZn,JN,UY),uZn.Qb=function(){zD(this)},uZn.Rb=function(n){var t;t=0==qA(this.a),(FY(this),uG(this.b,128)).Rb(n),++this.a.a.d,t&&mF(this.a)},uZn.Sb=function(){return(FY(this),uG(this.b,128)).Sb()},uZn.Tb=function(){return(FY(this),uG(this.b,128)).Tb()},uZn.Ub=function(){return(FY(this),uG(this.b,128)).Ub()},uZn.Vb=function(){return(FY(this),uG(this.b,128)).Vb()},uZn.Wb=function(n){(FY(this),uG(this.b,128)).Wb(n)},zW(AZn,"AbstractMapBasedMultimap/WrappedList/WrappedListIterator",745),sDn(743,551,BZn,AK),uZn.Nc=function(){return bpn(this),this.d.Nc()},zW(AZn,"AbstractMapBasedMultimap/WrappedSortedSet",743),sDn(1125,743,HZn,TN),zW(AZn,"AbstractMapBasedMultimap/WrappedNavigableSet",1125),sDn(1124,551,FZn,LK),uZn.Nc=function(){return bpn(this),this.d.Nc()},zW(AZn,"AbstractMapBasedMultimap/WrappedSet",1124),sDn(1133,1,{},o),uZn.Kb=function(n){return P7(uG(n,44))},zW(AZn,"AbstractMapBasedMultimap/lambda$1$Type",1133),sDn(1132,1,{},Wl),uZn.Kb=function(n){return new FE(this.a,n)},zW(AZn,"AbstractMapBasedMultimap/lambda$2$Type",1132);var Mat,Tat,jat,Eat,Sat=Iq(DZn,"Map/Entry");sDn(358,1,GZn),uZn.Fb=function(n){var t;return!!F$(n,44)&&(t=uG(n,44),xQ(this.ld(),t.ld())&&xQ(this.md(),t.md()))},uZn.Hb=function(){var n,t;return n=this.ld(),t=this.md(),(null==n?0:Hon(n))^(null==t?0:Hon(t))},uZn.nd=function(n){throw hv(new Kv)},uZn.Ib=function(){return this.ld()+"="+this.md()},zW(AZn,qZn,358),sDn(2086,31,RZn),uZn.$b=function(){this.od().$b()},uZn.Hc=function(n){var t;return!!F$(n,44)&&(t=uG(n,44),E4(this.od(),t.ld(),t.md()))},uZn.Mc=function(n){var t;return!!F$(n,44)&&(t=uG(n,44),S4(this.od(),t.ld(),t.md()))},uZn.gc=function(){return this.od().d},zW(AZn,"Multimaps/Entries",2086),sDn(749,2086,RZn,Ql),uZn.Kc=function(){return this.a.kc()},uZn.od=function(){return this.a},uZn.Nc=function(){return this.a.lc()},zW(AZn,"AbstractMultimap/Entries",749),sDn(750,749,FZn,Ty),uZn.Nc=function(){return this.a.lc()},uZn.Fb=function(n){return OOn(this,n)},uZn.Hb=function(){return Jon(this)},zW(AZn,"AbstractMultimap/EntrySet",750),sDn(751,31,RZn,Jl),uZn.$b=function(){this.a.$b()},uZn.Hc=function(n){return qln(this.a,n)},uZn.Kc=function(){return this.a.nc()},uZn.gc=function(){return this.a.d},uZn.Nc=function(){return this.a.oc()},zW(AZn,"AbstractMultimap/Values",751),sDn(2087,31,{849:1,20:1,31:1,16:1}),uZn.Jc=function(n){WW(n),uY(this).Jc(new yb(n))},uZn.Nc=function(){var n;return ICn(n=uY(this).Nc(),new d,64|1296&n.yd(),this.a.d)},uZn.Fc=function(n){return HM(),!0},uZn.Gc=function(n){return WW(this),WW(n),F$(n,552)?V4(uG(n,849)):!n.dc()&&cin(this,n.Kc())},uZn.Hc=function(n){var t;return((t=uG(Xwn(nZ(this.a),n),16))?t.gc():0)>0},uZn.Fb=function(n){return nxn(this,n)},uZn.Hb=function(){return Hon(uY(this))},uZn.dc=function(){return uY(this).dc()},uZn.Mc=function(n){return bNn(this,n,1)>0},uZn.Ib=function(){return cpn(uY(this))},zW(AZn,"AbstractMultiset",2087),sDn(2089,2068,FZn),uZn.$b=function(){ban(this.a.a)},uZn.Hc=function(n){var t;return!(!F$(n,504)||(t=uG(n,425),uG(t.a.md(),16).gc()<=0||S2(this.a,t.a.ld())!=uG(t.a.md(),16).gc()))},uZn.Mc=function(n){var t,e,i;return!(!F$(n,504)||(t=(e=uG(n,425)).a.ld(),0==(i=uG(e.a.md(),16).gc())))&&wNn(this.a,t,i)},zW(AZn,"Multisets/EntrySet",2089),sDn(1139,2089,FZn,Yl),uZn.Kc=function(){return new Dy(vz(nZ(this.a.a)).Kc())},uZn.gc=function(){return nZ(this.a.a).gc()},zW(AZn,"AbstractMultiset/EntrySet",1139),sDn(627,742,NZn),uZn.hc=function(){return this.pd()},uZn.jc=function(){return this.qd()},uZn.cc=function(n){return this.rd(n)},uZn.fc=function(n){return this.sd(n)},uZn.Zb=function(){return this.f||(this.f=this.ac())},uZn.qd=function(){return hZ(),hZ(),Wot},uZn.Fb=function(n){return Aln(this,n)},uZn.rd=function(n){return uG(Y9(this,n),21)},uZn.sd=function(n){return uG(twn(this,n),21)},uZn.mc=function(n){return hZ(),new nT(uG(n,21))},uZn.pc=function(n,t){return new LK(this,n,uG(t,21))},zW(AZn,"AbstractSetMultimap",627),sDn(1723,627,NZn),uZn.hc=function(){return new Hj(this.b)},uZn.pd=function(){return new Hj(this.b)},uZn.jc=function(){return UQ(new Hj(this.b))},uZn.qd=function(){return UQ(new Hj(this.b))},uZn.cc=function(n){return uG(uG(Y9(this,n),21),87)},uZn.rd=function(n){return uG(uG(Y9(this,n),21),87)},uZn.fc=function(n){return uG(uG(twn(this,n),21),87)},uZn.sd=function(n){return uG(uG(twn(this,n),21),87)},uZn.mc=function(n){return F$(n,277)?UQ(uG(n,277)):(hZ(),new mx(uG(n,87)))},uZn.Zb=function(){return this.f||(this.f=F$(this.c,139)?new $K(this,uG(this.c,139)):F$(this.c,133)?new NK(this,uG(this.c,133)):new OE(this,this.c))},uZn.pc=function(n,t){return F$(t,277)?new TN(this,n,uG(t,277)):new AK(this,n,uG(t,87))},zW(AZn,"AbstractSortedSetMultimap",1723),sDn(1724,1723,NZn),uZn.Zb=function(){return uG(uG(this.f||(this.f=F$(this.c,139)?new $K(this,uG(this.c,139)):F$(this.c,133)?new NK(this,uG(this.c,133)):new OE(this,this.c)),133),139)},uZn.ec=function(){return uG(uG(this.i||(this.i=F$(this.c,139)?new ME(this,uG(this.c,139)):F$(this.c,133)?new yE(this,uG(this.c,133)):new RD(this,this.c)),87),277)},uZn.bc=function(){return F$(this.c,139)?new ME(this,uG(this.c,139)):F$(this.c,133)?new yE(this,uG(this.c,133)):new RD(this,this.c)},zW(AZn,"AbstractSortedKeySortedSetMultimap",1724),sDn(2109,1,{2046:1}),uZn.Fb=function(n){return fSn(this,n)},uZn.Hb=function(){return tfn(this.g||(this.g=new nb(this)))},uZn.Ib=function(){return KPn(this.f||(this.f=new VD(this)))},zW(AZn,"AbstractTable",2109),sDn(679,KZn,FZn,nb),uZn.$b=function(){UM()},uZn.Hc=function(n){var t,e;return!!F$(n,479)&&(t=uG(n,697),!!(e=uG(Xwn(BW(this.a),GA(t.c.e,t.b)),85))&&Gwn(e.vc(),new FE(GA(t.c.c,t.a),I7(t.c,t.b,t.a))))},uZn.Kc=function(){return CZ(this.a)},uZn.Mc=function(n){var t,e;return!!F$(n,479)&&(t=uG(n,697),!!(e=uG(Xwn(BW(this.a),GA(t.c.e,t.b)),85))&&qwn(e.vc(),new FE(GA(t.c.c,t.a),I7(t.c,t.b,t.a))))},uZn.gc=function(){return $q(this.a)},uZn.Nc=function(){return u6(this.a)},zW(AZn,"AbstractTable/CellSet",679),sDn(2025,31,RZn,tb),uZn.$b=function(){UM()},uZn.Hc=function(n){return QPn(this.a,n)},uZn.Kc=function(){return IZ(this.a)},uZn.gc=function(){return $q(this.a)},uZn.Nc=function(){return y4(this.a)},zW(AZn,"AbstractTable/Values",2025),sDn(1697,1696,NZn),zW(AZn,"ArrayListMultimapGwtSerializationDependencies",1697),sDn(520,1697,NZn,rT,L2),uZn.hc=function(){return new R7(this.a)},uZn.a=0,zW(AZn,"ArrayListMultimap",520),sDn(678,2109,{678:1,2046:1,3:1},f$n),zW(AZn,"ArrayTable",678),sDn(2021,399,LZn,WD),uZn.Xb=function(n){return new Ofn(this.a,n)},zW(AZn,"ArrayTable/1",2021),sDn(2022,1,{},Xl),uZn.td=function(n){return new Ofn(this.a,n)},zW(AZn,"ArrayTable/1methodref$getCell$Type",2022),sDn(2110,1,{697:1}),uZn.Fb=function(n){var t;return n===this||!!F$(n,479)&&(t=uG(n,697),xQ(GA(this.c.e,this.b),GA(t.c.e,t.b))&&xQ(GA(this.c.c,this.a),GA(t.c.c,t.a))&&xQ(I7(this.c,this.b,this.a),I7(t.c,t.b,t.a)))},uZn.Hb=function(){return Obn(Uhn(cT(dat,1),EZn,1,5,[GA(this.c.e,this.b),GA(this.c.c,this.a),I7(this.c,this.b,this.a)]))},uZn.Ib=function(){return"("+GA(this.c.e,this.b)+","+GA(this.c.c,this.a)+")="+I7(this.c,this.b,this.a)},zW(AZn,"Tables/AbstractCell",2110),sDn(479,2110,{479:1,697:1},Ofn),uZn.a=0,uZn.b=0,uZn.d=0,zW(AZn,"ArrayTable/2",479),sDn(2024,1,{},zl),uZn.td=function(n){return Qtn(this.a,n)},zW(AZn,"ArrayTable/2methodref$getValue$Type",2024),sDn(2023,399,LZn,QD),uZn.Xb=function(n){return Qtn(this.a,n)},zW(AZn,"ArrayTable/3",2023),sDn(2077,2065,xZn),uZn.$b=function(){Hq(this.kc())},uZn.vc=function(){return new wb(this)},uZn.lc=function(){return new MY(this.kc(),this.gc())},zW(AZn,"Maps/IteratorBasedAbstractMap",2077),sDn(842,2077,xZn),uZn.$b=function(){throw hv(new Kv)},uZn._b=function(n){return Ej(this.c,n)},uZn.kc=function(){return new JD(this,this.c.b.c.gc())},uZn.lc=function(){return Dq(this.c.b.c.gc(),16,new Vl(this))},uZn.xc=function(n){var t;return(t=uG(W_(this.c,n),17))?this.vd(t.a):null},uZn.dc=function(){return this.c.b.c.dc()},uZn.ec=function(){return Tz(this.c)},uZn.zc=function(n,t){var e;if(!(e=uG(W_(this.c,n),17)))throw hv(new vM(this.ud()+" "+n+" not in "+Tz(this.c)));return this.wd(e.a,t)},uZn.Bc=function(n){throw hv(new Kv)},uZn.gc=function(){return this.c.b.c.gc()},zW(AZn,"ArrayTable/ArrayMap",842),sDn(2020,1,{},Vl),uZn.td=function(n){return qW(this.a,n)},zW(AZn,"ArrayTable/ArrayMap/0methodref$getEntry$Type",2020),sDn(2018,358,GZn,TE),uZn.ld=function(){return uR(this.a,this.b)},uZn.md=function(){return this.a.vd(this.b)},uZn.nd=function(n){return this.a.wd(this.b,n)},uZn.b=0,zW(AZn,"ArrayTable/ArrayMap/1",2018),sDn(2019,399,LZn,JD),uZn.Xb=function(n){return qW(this.a,n)},zW(AZn,"ArrayTable/ArrayMap/2",2019),sDn(2017,842,xZn,yV),uZn.ud=function(){return"Column"},uZn.vd=function(n){return I7(this.b,this.a,n)},uZn.wd=function(n,t){return Hhn(this.b,this.a,n,t)},uZn.a=0,zW(AZn,"ArrayTable/Row",2017),sDn(843,842,xZn,VD),uZn.vd=function(n){return new yV(this.a,n)},uZn.zc=function(n,t){return uG(t,85),GM()},uZn.wd=function(n,t){return uG(t,85),qM()},uZn.ud=function(){return"Row"},zW(AZn,"ArrayTable/RowMap",843),sDn(1157,1,WZn,jE),uZn.Ad=function(n){return!!(-262&this.a.yd()&n)},uZn.yd=function(){return-262&this.a.yd()},uZn.zd=function(){return this.a.zd()},uZn.Nb=function(n){this.a.Nb(new SE(n,this.b))},uZn.Bd=function(n){return this.a.Bd(new EE(n,this.b))},zW(AZn,"CollectSpliterators/1",1157),sDn(1158,1,QZn,EE),uZn.Cd=function(n){this.a.Cd(this.b.Kb(n))},zW(AZn,"CollectSpliterators/1/lambda$0$Type",1158),sDn(1159,1,QZn,SE),uZn.Cd=function(n){this.a.Cd(this.b.Kb(n))},zW(AZn,"CollectSpliterators/1/lambda$1$Type",1159),sDn(1154,1,WZn,x_),uZn.Ad=function(n){return!!((16464|this.b)&n)},uZn.yd=function(){return 16464|this.b},uZn.zd=function(){return this.a.zd()},uZn.Nb=function(n){this.a.Qe(new CE(n,this.c))},uZn.Bd=function(n){return this.a.Re(new PE(n,this.c))},uZn.b=0,zW(AZn,"CollectSpliterators/1WithCharacteristics",1154),sDn(1155,1,JZn,PE),uZn.Dd=function(n){this.a.Cd(this.b.td(n))},zW(AZn,"CollectSpliterators/1WithCharacteristics/lambda$0$Type",1155),sDn(1156,1,JZn,CE),uZn.Dd=function(n){this.a.Cd(this.b.td(n))},zW(AZn,"CollectSpliterators/1WithCharacteristics/lambda$1$Type",1156),sDn(1150,1,WZn),uZn.Ad=function(n){return!!(this.a&n)},uZn.yd=function(){return this.a},uZn.zd=function(){return this.e&&(this.b=g$(this.b,this.e.zd())),g$(this.b,0)},uZn.Nb=function(n){this.e&&(this.e.Nb(n),this.e=null),this.c.Nb(new IE(this,n)),this.b=0},uZn.Bd=function(n){for(;;){if(this.e&&this.e.Bd(n))return HA(this.b,YZn)&&(this.b=$gn(this.b,1)),!0;if(this.e=null,!this.c.Bd(new eb(this)))return!1}},uZn.a=0,uZn.b=0,zW(AZn,"CollectSpliterators/FlatMapSpliterator",1150),sDn(1152,1,QZn,eb),uZn.Cd=function(n){M_(this.a,n)},zW(AZn,"CollectSpliterators/FlatMapSpliterator/lambda$0$Type",1152),sDn(1153,1,QZn,IE),uZn.Cd=function(n){fY(this.a,this.b,n)},zW(AZn,"CollectSpliterators/FlatMapSpliterator/lambda$1$Type",1153),sDn(1151,1150,WZn,T6),zW(AZn,"CollectSpliterators/FlatMapSpliteratorOfObject",1151),sDn(253,1,ZZn),uZn.Fd=function(n){return this.Ed(uG(n,253))},uZn.Ed=function(n){var t;return n==(my(),Tat)?1:n==(py(),Mat)?-1:(qG(),0!=(t=Dun(this.a,n.a))?t:F$(this,526)==F$(n,526)?0:F$(this,526)?1:-1)},uZn.Id=function(){return this.a},uZn.Fb=function(n){return pTn(this,n)},zW(AZn,"Cut",253),sDn(1823,253,ZZn,ky),uZn.Ed=function(n){return n==this?0:1},uZn.Gd=function(n){throw hv(new Av)},uZn.Hd=function(n){n.a+="+\u221e)"},uZn.Id=function(){throw hv(new kM(n1n))},uZn.Hb=function(){return bS(),Avn(this)},uZn.Jd=function(n){return!1},uZn.Ib=function(){return"+\u221e"},zW(AZn,"Cut/AboveAll",1823),sDn(526,253,{253:1,526:1,3:1,34:1},bx),uZn.Gd=function(n){QA((n.a+="(",n),this.a)},uZn.Hd=function(n){jQ(QA(n,this.a),93)},uZn.Hb=function(){return~Hon(this.a)},uZn.Jd=function(n){return qG(),Dun(this.a,n)<0},uZn.Ib=function(){return"/"+this.a+"\\"},zW(AZn,"Cut/AboveValue",526),sDn(1822,253,ZZn,vy),uZn.Ed=function(n){return n==this?0:-1},uZn.Gd=function(n){n.a+="(-\u221e"},uZn.Hd=function(n){throw hv(new Av)},uZn.Id=function(){throw hv(new kM(n1n))},uZn.Hb=function(){return bS(),Avn(this)},uZn.Jd=function(n){return!0},uZn.Ib=function(){return"-\u221e"},zW(AZn,"Cut/BelowAll",1822),sDn(1824,253,ZZn,wx),uZn.Gd=function(n){QA((n.a+="[",n),this.a)},uZn.Hd=function(n){jQ(QA(n,this.a),41)},uZn.Hb=function(){return Hon(this.a)},uZn.Jd=function(n){return qG(),Dun(this.a,n)<=0},uZn.Ib=function(){return"\\"+this.a+"/"},zW(AZn,"Cut/BelowValue",1824),sDn(547,1,t1n),uZn.Jc=function(n){z8(this,n)},uZn.Ib=function(){return rgn(uG(bZ(this,"use Optional.orNull() instead of Optional.or(null)"),20).Kc())},zW(AZn,"FluentIterable",547),sDn(442,547,t1n,iN),uZn.Kc=function(){return new Fz(ix(this.a.Kc(),new h))},zW(AZn,"FluentIterable/2",442),sDn(1059,547,t1n,rN),uZn.Kc=function(){return OV(this)},zW(AZn,"FluentIterable/3",1059),sDn(724,399,LZn,YD),uZn.Xb=function(n){return this.a[n].Kc()},zW(AZn,"FluentIterable/3/1",724),sDn(2070,1,{}),uZn.Ib=function(){return cpn(this.Kd().b)},zW(AZn,"ForwardingObject",2070),sDn(2071,2070,e1n),uZn.Kd=function(){return this.Ld()},uZn.Jc=function(n){z8(this,n)},uZn.Lc=function(){return this.Oc()},uZn.Nc=function(){return new h3(this,0)},uZn.Oc=function(){return new fX(null,this.Nc())},uZn.Fc=function(n){return this.Ld(),Rj()},uZn.Gc=function(n){return this.Ld(),Kj()},uZn.$b=function(){this.Ld(),Fj()},uZn.Hc=function(n){return this.Ld().Hc(n)},uZn.Ic=function(n){return this.Ld().Ic(n)},uZn.dc=function(){return this.Ld().b.dc()},uZn.Kc=function(){return this.Ld().Kc()},uZn.Mc=function(n){return this.Ld(),_j()},uZn.gc=function(){return this.Ld().b.gc()},uZn.Pc=function(){return this.Ld().Pc()},uZn.Qc=function(n){return this.Ld().Qc(n)},zW(AZn,"ForwardingCollection",2071),sDn(2078,31,i1n),uZn.Kc=function(){return this.Od()},uZn.Fc=function(n){throw hv(new Kv)},uZn.Gc=function(n){throw hv(new Kv)},uZn.Md=function(){return this.c||(this.c=this.Nd())},uZn.$b=function(){throw hv(new Kv)},uZn.Hc=function(n){return null!=n&&Wpn(this,n,!1)},uZn.Nd=function(){switch(this.gc()){case 0:return ZW(),ZW(),jat;case 1:return ZW(),new Uq(WW(this.Od().Pb()));default:return new TV(this,this.Pc())}},uZn.Mc=function(n){throw hv(new Kv)},zW(AZn,"ImmutableCollection",2078),sDn(727,2078,i1n,jv),uZn.Kc=function(){return jtn(this.a.Kc())},uZn.Hc=function(n){return null!=n&&this.a.Hc(n)},uZn.Ic=function(n){return this.a.Ic(n)},uZn.dc=function(){return this.a.dc()},uZn.Od=function(){return jtn(this.a.Kc())},uZn.gc=function(){return this.a.gc()},uZn.Pc=function(){return this.a.Pc()},uZn.Qc=function(n){return this.a.Qc(n)},uZn.Ib=function(){return cpn(this.a)},zW(AZn,"ForwardingImmutableCollection",727),sDn(307,2078,r1n),uZn.Kc=function(){return this.Od()},uZn.ed=function(){return this.Pd(0)},uZn.fd=function(n){return this.Pd(n)},uZn.jd=function(n){Lon(this,n)},uZn.Nc=function(){return new h3(this,16)},uZn.kd=function(n,t){return this.Qd(n,t)},uZn.bd=function(n,t){throw hv(new Kv)},uZn.cd=function(n,t){throw hv(new Kv)},uZn.Md=function(){return this},uZn.Fb=function(n){return RDn(this,n)},uZn.Hb=function(){return Xsn(this)},uZn.dd=function(n){return null==n?-1:uTn(this,n)},uZn.Od=function(){return this.Pd(0)},uZn.Pd=function(n){return oR(this,n)},uZn.gd=function(n){throw hv(new Kv)},uZn.hd=function(n,t){throw hv(new Kv)},uZn.Qd=function(n,t){return Dwn(new C2(new qE(this),n,t))},zW(AZn,"ImmutableList",307),sDn(2105,307,r1n),uZn.Kc=function(){return jtn(this.Rd().Kc())},uZn.kd=function(n,t){return Dwn(this.Rd().kd(n,t))},uZn.Hc=function(n){return null!=n&&this.Rd().Hc(n)},uZn.Ic=function(n){return this.Rd().Ic(n)},uZn.Fb=function(n){return udn(this.Rd(),n)},uZn.Xb=function(n){return GA(this,n)},uZn.Hb=function(){return Hon(this.Rd())},uZn.dd=function(n){return this.Rd().dd(n)},uZn.dc=function(){return this.Rd().dc()},uZn.Od=function(){return jtn(this.Rd().Kc())},uZn.gc=function(){return this.Rd().gc()},uZn.Qd=function(n,t){return Dwn(this.Rd().kd(n,t))},uZn.Pc=function(){return this.Rd().Qc(Inn(dat,EZn,1,this.Rd().gc(),5,1))},uZn.Qc=function(n){return this.Rd().Qc(n)},uZn.Ib=function(){return cpn(this.Rd())},zW(AZn,"ForwardingImmutableList",2105),sDn(729,1,a1n),uZn.vc=function(){return Mz(this)},uZn.wc=function(n){Yun(this,n)},uZn.ec=function(){return Tz(this)},uZn.yc=function(n,t,e){return Jgn(this,n,t,e)},uZn.Cc=function(){return this.Vd()},uZn.$b=function(){throw hv(new Kv)},uZn._b=function(n){return null!=this.xc(n)},uZn.uc=function(n){return this.Vd().Hc(n)},uZn.Td=function(){return new Ev(this)},uZn.Ud=function(){return new Sv(this)},uZn.Fb=function(n){return Wln(this,n)},uZn.Hb=function(){return Mz(this).Hb()},uZn.dc=function(){return 0==this.gc()},uZn.zc=function(n,t){return BM()},uZn.Bc=function(n){throw hv(new Kv)},uZn.Ib=function(){return QIn(this)},uZn.Vd=function(){return this.e?this.e:this.e=this.Ud()},uZn.c=null,uZn.d=null,uZn.e=null,zW(AZn,"ImmutableMap",729),sDn(730,729,a1n),uZn._b=function(n){return Ej(this,n)},uZn.uc=function(n){return iS(this.b,n)},uZn.Sd=function(){return $wn(new Zl(this))},uZn.Td=function(){return $wn(SJ(this.b))},uZn.Ud=function(){return sB(),new jv(jJ(this.b))},uZn.Fb=function(n){return rS(this.b,n)},uZn.xc=function(n){return W_(this,n)},uZn.Hb=function(){return Hon(this.b.c)},uZn.dc=function(){return this.b.c.dc()},uZn.gc=function(){return this.b.c.gc()},uZn.Ib=function(){return cpn(this.b.c)},zW(AZn,"ForwardingImmutableMap",730),sDn(2072,2071,o1n),uZn.Kd=function(){return this.Wd()},uZn.Ld=function(){return this.Wd()},uZn.Nc=function(){return new h3(this,1)},uZn.Fb=function(n){return n===this||this.Wd().Fb(n)},uZn.Hb=function(){return this.Wd().Hb()},zW(AZn,"ForwardingSet",2072),sDn(1085,2072,o1n,Zl),uZn.Kd=function(){return EJ(this.a.b)},uZn.Ld=function(){return EJ(this.a.b)},uZn.Hc=function(n){if(F$(n,44)&&null==uG(n,44).ld())return!1;try{return eS(EJ(this.a.b),n)}catch(t){if(F$(t=Ehn(t),212))return!1;throw hv(t)}},uZn.Wd=function(){return EJ(this.a.b)},uZn.Qc=function(n){var t;return t=YZ(EJ(this.a.b),n),EJ(this.a.b).b.gc()=0?"+":"")+(i/60|0),t=FL(e.Math.abs(i)%60),(cIn(),nut)[this.q.getDay()]+" "+tut[this.q.getMonth()]+" "+FL(this.q.getDate())+" "+FL(this.q.getHours())+":"+FL(this.q.getMinutes())+":"+FL(this.q.getSeconds())+" GMT"+n+t+" "+this.q.getFullYear()};var Xat,zat,Vat,Wat,Qat,Jat,Yat,Zat,not,tot,eot,iot=zW(DZn,"Date",206);sDn(2015,206,s0n,DEn),uZn.a=!1,uZn.b=0,uZn.c=0,uZn.d=0,uZn.e=0,uZn.f=0,uZn.g=!1,uZn.i=0,uZn.j=0,uZn.k=0,uZn.n=0,uZn.o=0,uZn.p=0,zW("com.google.gwt.i18n.shared.impl","DateRecord",2015),sDn(2064,1,{}),uZn.pe=function(){return null},uZn.qe=function(){return null},uZn.re=function(){return null},uZn.se=function(){return null},uZn.te=function(){return null},zW(h0n,"JSONValue",2064),sDn(221,2064,{221:1},Ib,Eb),uZn.Fb=function(n){return!!F$(n,221)&&j3(this.a,uG(n,221).a)},uZn.oe=function(){return uv},uZn.Hb=function(){return OZ(this.a)},uZn.pe=function(){return this},uZn.Ib=function(){var n,t,e;for(e=new lx("["),t=0,n=this.a.length;t0&&(e.a+=","),QA(e,uin(this,t));return e.a+="]",e.a},zW(h0n,"JSONArray",221),sDn(493,2064,{493:1},Sb),uZn.oe=function(){return sv},uZn.qe=function(){return this},uZn.Ib=function(){return qx(),""+this.a},uZn.a=!1,zW(h0n,"JSONBoolean",493),sDn(997,63,S1n,Fy),zW(h0n,"JSONException",997),sDn(1036,2064,{},T),uZn.oe=function(){return fv},uZn.Ib=function(){return IZn},zW(h0n,"JSONNull",1036),sDn(263,2064,{263:1},Pb),uZn.Fb=function(n){return!!F$(n,263)&&this.a==uG(n,263).a},uZn.oe=function(){return av},uZn.Hb=function(){return OL(this.a)},uZn.re=function(){return this},uZn.Ib=function(){return this.a+""},uZn.a=0,zW(h0n,"JSONNumber",263),sDn(190,2064,{190:1},_y,Cb),uZn.Fb=function(n){return!!F$(n,190)&&j3(this.a,uG(n,190).a)},uZn.oe=function(){return ov},uZn.Hb=function(){return OZ(this.a)},uZn.se=function(){return this},uZn.Ib=function(){var n,t,e,i,r,c;for(c=new lx("{"),n=!0,i=0,r=(e=Yon(this,Inn($ot,zZn,2,0,6,1))).length;i=0?":"+this.c:"")+")"},uZn.c=0;var jot=zW(kZn,"StackTraceElement",319);bZn={3:1,484:1,34:1,2:1};var Eot,Sot,Pot,Cot,Iot,Oot,Aot,Lot,Not,$ot=zW(kZn,C1n,2);sDn(111,427,{484:1},zM,VM,fx),zW(kZn,"StringBuffer",111),sDn(104,427,{484:1},WM,QM,lx),zW(kZn,"StringBuilder",104),sDn(702,77,v0n,JM),zW(kZn,"StringIndexOutOfBoundsException",702),sDn(2145,1,{}),sDn(48,63,{3:1,103:1,63:1,82:1,48:1},Kv,TM),zW(kZn,"UnsupportedOperationException",48),sDn(247,242,{3:1,34:1,242:1,247:1},Edn,Wj),uZn.Fd=function(n){return $Gn(this,uG(n,247))},uZn.ue=function(){return YIn(dzn(this))},uZn.Fb=function(n){var t;return this===n||!!F$(n,247)&&(t=uG(n,247),this.e==t.e&&0==$Gn(this,t))},uZn.Hb=function(){var n;return 0!=this.b?this.b:this.a<54?(n=Bsn(this.f),this.b=pz(E3(n,-1)),this.b=33*this.b+pz(E3($z(n,32),-1)),this.b=17*this.b+t0(this.e),this.b):(this.b=17*cwn(this.c)+t0(this.e),this.b)},uZn.Ib=function(){return dzn(this)},uZn.a=0,uZn.b=0,uZn.d=0,uZn.e=0,uZn.f=0;var Dot,xot,Rot,Kot,Fot,_ot,Bot=zW("java.math","BigDecimal",247);sDn(92,242,{3:1,34:1,242:1,92:1},Z5,x3,VV,nkn,PN),uZn.Fd=function(n){return Pvn(this,uG(n,92))},uZn.ue=function(){return YIn(bYn(this,0))},uZn.Fb=function(n){return Cpn(this,n)},uZn.Hb=function(){return cwn(this)},uZn.Ib=function(){return bYn(this,0)},uZn.b=-2,uZn.c=0,uZn.d=0,uZn.e=0;var Hot,Uot,Got,qot,Xot=zW("java.math","BigInteger",92);sDn(498,2065,xZn),uZn.$b=function(){$V(this)},uZn._b=function(n){return PV(this,n)},uZn.uc=function(n){return Qln(this,n,this.i)||Qln(this,n,this.f)},uZn.vc=function(){return new Nw(this)},uZn.xc=function(n){return cQ(this,n)},uZn.zc=function(n,t){return vJ(this,n,t)},uZn.Bc=function(n){return u7(this,n)},uZn.gc=function(){return oS(this)},uZn.g=0,zW(DZn,"AbstractHashMap",498),sDn(267,KZn,FZn,Nw),uZn.$b=function(){this.a.$b()},uZn.Hc=function(n){return Q4(this,n)},uZn.Kc=function(){return new bsn(this.a)},uZn.Mc=function(n){var t;return!!Q4(this,n)&&(t=uG(n,44).ld(),this.a.Bc(t),!0)},uZn.gc=function(){return this.a.gc()},zW(DZn,"AbstractHashMap/EntrySet",267),sDn(268,1,$Zn,bsn),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){return von(this)},uZn.Ob=function(){return this.b},uZn.Qb=function(){Oen(this)},uZn.b=!1,uZn.d=0,zW(DZn,"AbstractHashMap/EntrySetIterator",268),sDn(426,1,$Zn,Jw),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return AP(this)},uZn.Pb=function(){return _Y(this)},uZn.Qb=function(){LQ(this)},uZn.b=0,uZn.c=-1,zW(DZn,"AbstractList/IteratorImpl",426),sDn(98,426,UZn,N4),uZn.Qb=function(){LQ(this)},uZn.Rb=function(n){pF(this,n)},uZn.Sb=function(){return this.b>0},uZn.Tb=function(){return this.b},uZn.Ub=function(){return MK(this.b>0),this.a.Xb(this.c=--this.b)},uZn.Vb=function(){return this.b-1},uZn.Wb=function(n){TK(-1!=this.c),this.a.hd(this.c,n)},zW(DZn,"AbstractList/ListIteratorImpl",98),sDn(244,56,m1n,C2),uZn.bd=function(n,t){o3(n,this.b),this.c.bd(this.a+n,t),++this.b},uZn.Xb=function(n){return u3(n,this.b),this.c.Xb(this.a+n)},uZn.gd=function(n){var t;return u3(n,this.b),t=this.c.gd(this.a+n),--this.b,t},uZn.hd=function(n,t){return u3(n,this.b),this.c.hd(this.a+n,t)},uZn.gc=function(){return this.b},uZn.a=0,uZn.b=0,zW(DZn,"AbstractList/SubList",244),sDn(266,KZn,FZn,Lw),uZn.$b=function(){this.a.$b()},uZn.Hc=function(n){return this.a._b(n)},uZn.Kc=function(){return new Kw(this.a.vc().Kc())},uZn.Mc=function(n){return!!this.a._b(n)&&(this.a.Bc(n),!0)},uZn.gc=function(){return this.a.gc()},zW(DZn,"AbstractMap/1",266),sDn(541,1,$Zn,Kw),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return this.a.Ob()},uZn.Pb=function(){return uG(this.a.Pb(),44).ld()},uZn.Qb=function(){this.a.Qb()},zW(DZn,"AbstractMap/1/1",541),sDn(231,31,RZn,Fw),uZn.$b=function(){this.a.$b()},uZn.Hc=function(n){return this.a.uc(n)},uZn.Kc=function(){return new _w(this.a.vc().Kc())},uZn.gc=function(){return this.a.gc()},zW(DZn,"AbstractMap/2",231),sDn(301,1,$Zn,_w),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return this.a.Ob()},uZn.Pb=function(){return uG(this.a.Pb(),44).md()},uZn.Qb=function(){this.a.Qb()},zW(DZn,"AbstractMap/2/1",301),sDn(494,1,{494:1,44:1}),uZn.Fb=function(n){var t;return!!F$(n,44)&&(t=uG(n,44),OJ(this.d,t.ld())&&OJ(this.e,t.md()))},uZn.ld=function(){return this.d},uZn.md=function(){return this.e},uZn.Hb=function(){return VN(this.d)^VN(this.e)},uZn.nd=function(n){return wF(this,n)},uZn.Ib=function(){return this.d+"="+this.e},zW(DZn,"AbstractMap/AbstractEntry",494),sDn(397,494,{494:1,397:1,44:1},VP),zW(DZn,"AbstractMap/SimpleEntry",397),sDn(2082,1,$0n),uZn.Fb=function(n){var t;return!!F$(n,44)&&(t=uG(n,44),OJ(this.ld(),t.ld())&&OJ(this.md(),t.md()))},uZn.Hb=function(){return VN(this.ld())^VN(this.md())},uZn.Ib=function(){return this.ld()+"="+this.md()},zW(DZn,qZn,2082),sDn(2090,2065,_Zn),uZn.Xc=function(n){return Sj(this.Ee(n))},uZn.tc=function(n){return I9(this,n)},uZn._b=function(n){return dF(this,n)},uZn.vc=function(){return new Uw(this)},uZn.Tc=function(){return DV(this.Ge())},uZn.Yc=function(n){return Sj(this.He(n))},uZn.xc=function(n){var t;return t=n,DA(this.Fe(t))},uZn.$c=function(n){return Sj(this.Ie(n))},uZn.ec=function(){return new Bw(this)},uZn.Vc=function(){return DV(this.Je())},uZn._c=function(n){return Sj(this.Ke(n))},zW(DZn,"AbstractNavigableMap",2090),sDn(629,KZn,FZn,Uw),uZn.Hc=function(n){return F$(n,44)&&I9(this.b,uG(n,44))},uZn.Kc=function(){return this.b.De()},uZn.Mc=function(n){var t;return!!F$(n,44)&&(t=uG(n,44),this.b.Le(t))},uZn.gc=function(){return this.b.gc()},zW(DZn,"AbstractNavigableMap/EntrySet",629),sDn(1146,KZn,HZn,Bw),uZn.Nc=function(){return new GP(this)},uZn.$b=function(){this.a.$b()},uZn.Hc=function(n){return dF(this.a,n)},uZn.Kc=function(){return new Hw(this.a.vc().b.De())},uZn.Mc=function(n){return!!dF(this.a,n)&&(this.a.Bc(n),!0)},uZn.gc=function(){return this.a.gc()},zW(DZn,"AbstractNavigableMap/NavigableKeySet",1146),sDn(1147,1,$Zn,Hw),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return AP(this.a.a)},uZn.Pb=function(){return kR(this.a).ld()},uZn.Qb=function(){rB(this.a)},zW(DZn,"AbstractNavigableMap/NavigableKeySet/1",1147),sDn(2103,31,RZn),uZn.Fc=function(n){return kG(_Cn(this,n),D0n),!0},uZn.Gc=function(n){return tJ(n),vG(n!=this,"Can't add a queue to itself"),Qon(this,n)},uZn.$b=function(){for(;null!=hin(this););},zW(DZn,"AbstractQueue",2103),sDn(310,31,{4:1,20:1,31:1,16:1},ND,$4),uZn.Fc=function(n){return O6(this,n),!0},uZn.$b=function(){q5(this)},uZn.Hc=function(n){return Chn(new XJ(this),n)},uZn.dc=function(){return LM(this)},uZn.Kc=function(){return new XJ(this)},uZn.Mc=function(n){return m0(new XJ(this),n)},uZn.gc=function(){return this.c-this.b&this.a.length-1},uZn.Nc=function(){return new h3(this,272)},uZn.Qc=function(n){var t;return t=this.c-this.b&this.a.length-1,n.lengtht&&uQ(n,t,null),n},uZn.b=0,uZn.c=0,zW(DZn,"ArrayDeque",310),sDn(459,1,$Zn,XJ),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return this.a!=this.b},uZn.Pb=function(){return rwn(this)},uZn.Qb=function(){lan(this)},uZn.a=0,uZn.b=0,uZn.c=-1,zW(DZn,"ArrayDeque/IteratorImpl",459),sDn(13,56,x0n,Zm,R7,Z_),uZn.bd=function(n,t){GX(this,n,t)},uZn.Fc=function(n){return kD(this,n)},uZn.cd=function(n,t){return Cbn(this,n,t)},uZn.Gc=function(n){return Ohn(this,n)},uZn.$b=function(){Xv(this.c,0)},uZn.Hc=function(n){return-1!=Ten(this,n,0)},uZn.Jc=function(n){Prn(this,n)},uZn.Xb=function(n){return zq(this,n)},uZn.dd=function(n){return Ten(this,n,0)},uZn.dc=function(){return 0==this.c.length},uZn.Kc=function(){return new Ww(this)},uZn.gd=function(n){return i7(this,n)},uZn.Mc=function(n){return men(this,n)},uZn.ce=function(n,t){P2(this,n,t)},uZn.hd=function(n,t){return Y8(this,n,t)},uZn.gc=function(){return this.c.length},uZn.jd=function(n){f$(this,n)},uZn.Pc=function(){return tq(this.c)},uZn.Qc=function(n){return Ekn(this,n)};var zot,Vot,Wot,Qot,Jot,Yot,Zot,nut,tut,eut=zW(DZn,"ArrayList",13);sDn(7,1,$Zn,Ww),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return l$(this)},uZn.Pb=function(){return N3(this)},uZn.Qb=function(){tW(this)},uZn.a=0,uZn.b=-1,zW(DZn,"ArrayList/1",7),sDn(2112,e.Function,{},P),uZn.Me=function(n,t){return ugn(n,t)},sDn(151,56,R0n,IM),uZn.Hc=function(n){return-1!=gan(this,n)},uZn.Jc=function(n){var t,e,i,r;for(tJ(n),i=0,r=(e=this.a).length;i0)throw hv(new vM(Y0n+n+" greater than "+this.e));return this.f.Te()?G1(this.c,this.b,this.a,n,t):N2(this.c,n,t)},uZn.zc=function(n,t){if(!ljn(this.c,this.f,n,this.b,this.a,this.e,this.d))throw hv(new vM(n+" outside the range "+this.b+" to "+this.e));return xfn(this.c,n,t)},uZn.Bc=function(n){var t;return t=n,ljn(this.c,this.f,t,this.b,this.a,this.e,this.d)?V1(this.c,t):null},uZn.Le=function(n){return $Q(this,n.ld())&&Lnn(this.c,n)},uZn.gc=function(){var n,t,e;if(!((t=this.f.Te()?this.a?Zmn(this.c,this.b,!0):Zmn(this.c,this.b,!1):Ytn(this.c))&&$Q(this,t.d)&&t))return 0;for(n=0,e=new dun(this.c,this.f,this.b,this.a,this.e,this.d);AP(e.a);e.b=uG(_Y(e.a),44))++n;return n},uZn.ad=function(n,t){if(this.f.Te()&&this.c.a.Ne(n,this.b)<0)throw hv(new vM(Y0n+n+Z0n+this.b));return this.f.Ue()?G1(this.c,n,t,this.e,this.d):$2(this.c,n,t)},uZn.a=!1,uZn.d=!1,zW(DZn,"TreeMap/SubMap",631),sDn(304,22,n2n,qP),uZn.Te=function(){return!1},uZn.Ue=function(){return!1};var Mut,Tut=_cn(DZn,"TreeMap/SubMapType",304,Oat,K6,hB);sDn(1143,304,n2n,SN),uZn.Ue=function(){return!0},_cn(DZn,"TreeMap/SubMapType/1",1143,Tut,null,null),sDn(1144,304,n2n,P$),uZn.Te=function(){return!0},uZn.Ue=function(){return!0},_cn(DZn,"TreeMap/SubMapType/2",1144,Tut,null,null),sDn(1145,304,n2n,EN),uZn.Te=function(){return!0},_cn(DZn,"TreeMap/SubMapType/3",1145,Tut,null,null),sDn(157,KZn,{3:1,20:1,31:1,16:1,277:1,21:1,87:1,157:1},rk,Hj,od),uZn.Nc=function(){return new GP(this)},uZn.Fc=function(n){return _V(this,n)},uZn.$b=function(){this.a.$b()},uZn.Hc=function(n){return this.a._b(n)},uZn.Kc=function(){return this.a.ec().Kc()},uZn.Mc=function(n){return sD(this,n)},uZn.gc=function(){return this.a.gc()};var jut=zW(DZn,"TreeSet",157);sDn(1082,1,{},ud),uZn.Ve=function(n,t){return _K(this.a,n,t)},zW(t2n,"BinaryOperator/lambda$0$Type",1082),sDn(1083,1,{},sd),uZn.Ve=function(n,t){return BK(this.a,n,t)},zW(t2n,"BinaryOperator/lambda$1$Type",1083),sDn(952,1,{},H),uZn.Kb=function(n){return n},zW(t2n,"Function/lambda$0$Type",952),sDn(395,1,y1n,hd),uZn.Mb=function(n){return!this.a.Mb(n)},zW(t2n,"Predicate/lambda$2$Type",395),sDn(581,1,{581:1});var Eut,Sut,Put=zW(e2n,"Handler",581);sDn(2107,1,yZn),uZn.xe=function(){return"DUMMY"},uZn.Ib=function(){return this.xe()},zW(e2n,"Level",2107),sDn(1706,2107,yZn,U),uZn.xe=function(){return"INFO"},zW(e2n,"Level/LevelInfo",1706),sDn(1843,1,{},ik),zW(e2n,"LogManager",1843),sDn(1896,1,yZn,iB),uZn.b=null,zW(e2n,"LogRecord",1896),sDn(525,1,{525:1},e9),uZn.e=!1;var Cut,Iut,Out,Aut=!1,Lut=!1,Nut=!1,$ut=!1,Dut=!1;zW(e2n,"Logger",525),sDn(835,581,{581:1},G),zW(e2n,"SimpleConsoleLogHandler",835),sDn(108,22,{3:1,34:1,22:1,108:1},XP);var xut,Rut=_cn(c2n,"Collector/Characteristics",108,Oat,D2,fB);sDn(758,1,{},WV),zW(c2n,"CollectorImpl",758),sDn(1074,1,{},q),uZn.Ve=function(n,t){return idn(uG(n,213),uG(t,213))},zW(c2n,"Collectors/10methodref$merge$Type",1074),sDn(1075,1,{},X),uZn.Kb=function(n){return R4(uG(n,213))},zW(c2n,"Collectors/11methodref$toString$Type",1075),sDn(1076,1,{},fd),uZn.Kb=function(n){return qx(),!!IL(n)},zW(c2n,"Collectors/12methodref$test$Type",1076),sDn(144,1,{},z),uZn.Yd=function(n,t){uG(n,16).Fc(t)},zW(c2n,"Collectors/20methodref$add$Type",144),sDn(146,1,{},V),uZn.Xe=function(){return new Zm},zW(c2n,"Collectors/21methodref$ctor$Type",146),sDn(359,1,{},W),uZn.Xe=function(){return new ek},zW(c2n,"Collectors/23methodref$ctor$Type",359),sDn(360,1,{},Q),uZn.Yd=function(n,t){FV(uG(n,49),t)},zW(c2n,"Collectors/24methodref$add$Type",360),sDn(1069,1,{},J),uZn.Ve=function(n,t){return IS(uG(n,15),uG(t,16))},zW(c2n,"Collectors/4methodref$addAll$Type",1069),sDn(1073,1,{},Y),uZn.Yd=function(n,t){o7(uG(n,213),uG(t,484))},zW(c2n,"Collectors/9methodref$add$Type",1073),sDn(1072,1,{},fG),uZn.Xe=function(){return new Ysn(this.a,this.b,this.c)},zW(c2n,"Collectors/lambda$15$Type",1072),sDn(1077,1,{},Z),uZn.Xe=function(){var n;return Akn(n=new u8,(qx(),!1),new Zm),Akn(n,!0,new Zm),n},zW(c2n,"Collectors/lambda$22$Type",1077),sDn(1078,1,{},ld),uZn.Xe=function(){return Uhn(cT(dat,1),EZn,1,5,[this.a])},zW(c2n,"Collectors/lambda$25$Type",1078),sDn(1079,1,{},bd),uZn.Yd=function(n,t){Yq(this.a,Kcn(n))},zW(c2n,"Collectors/lambda$26$Type",1079),sDn(1080,1,{},wd),uZn.Ve=function(n,t){return sV(this.a,Kcn(n),Kcn(t))},zW(c2n,"Collectors/lambda$27$Type",1080),sDn(1081,1,{},nn),uZn.Kb=function(n){return Kcn(n)[0]},zW(c2n,"Collectors/lambda$28$Type",1081),sDn(728,1,{},tn),uZn.Ve=function(n,t){return nX(n,t)},zW(c2n,"Collectors/lambda$4$Type",728),sDn(145,1,{},en),uZn.Ve=function(n,t){return ES(uG(n,16),uG(t,16))},zW(c2n,"Collectors/lambda$42$Type",145),sDn(361,1,{},rn),uZn.Ve=function(n,t){return SS(uG(n,49),uG(t,49))},zW(c2n,"Collectors/lambda$50$Type",361),sDn(362,1,{},cn),uZn.Kb=function(n){return uG(n,49)},zW(c2n,"Collectors/lambda$51$Type",362),sDn(1068,1,{},dd),uZn.Yd=function(n,t){vln(this.a,uG(n,85),t)},zW(c2n,"Collectors/lambda$7$Type",1068),sDn(1070,1,{},an),uZn.Ve=function(n,t){return Ahn(uG(n,85),uG(t,85),new J)},zW(c2n,"Collectors/lambda$8$Type",1070),sDn(1071,1,{},gd),uZn.Kb=function(n){return zgn(this.a,uG(n,85))},zW(c2n,"Collectors/lambda$9$Type",1071),sDn(550,1,{}),uZn.$e=function(){qQ(this)},uZn.d=!1,zW(c2n,"TerminatableStream",550),sDn(827,550,a2n,IK),uZn.$e=function(){qQ(this)},zW(c2n,"DoubleStreamImpl",827),sDn(1847,736,WZn,lG),uZn.Re=function(n){return FMn(this,uG(n,189))},uZn.a=null,zW(c2n,"DoubleStreamImpl/2",1847),sDn(1848,1,_0n,pd),uZn.Pe=function(n){$N(this.a,n)},zW(c2n,"DoubleStreamImpl/2/lambda$0$Type",1848),sDn(1845,1,_0n,md),uZn.Pe=function(n){NN(this.a,n)},zW(c2n,"DoubleStreamImpl/lambda$0$Type",1845),sDn(1846,1,_0n,vd),uZn.Pe=function(n){Mmn(this.a,n)},zW(c2n,"DoubleStreamImpl/lambda$2$Type",1846),sDn(1397,735,WZn,i9),uZn.Re=function(n){return e6(this,uG(n,202))},uZn.a=0,uZn.b=0,uZn.c=0,zW(c2n,"IntStream/5",1397),sDn(806,550,a2n,OK),uZn.$e=function(){qQ(this)},uZn._e=function(){return GQ(this),this.a},zW(c2n,"IntStreamImpl",806),sDn(807,550,a2n,mS),uZn.$e=function(){qQ(this)},uZn._e=function(){return GQ(this),BD(),dut},zW(c2n,"IntStreamImpl/Empty",807),sDn(1687,1,JZn,kd),uZn.Dd=function(n){msn(this.a,n)},zW(c2n,"IntStreamImpl/lambda$4$Type",1687);var Kut,Fut=Iq(c2n,"Stream");sDn(26,550,{533:1,687:1,848:1},fX),uZn.$e=function(){qQ(this)},zW(c2n,"StreamImpl",26),sDn(1102,500,WZn,D_),uZn.Bd=function(n){for(;Ttn(this);){if(this.a.Bd(n))return!0;qQ(this.b),this.b=null,this.a=null}return!1},zW(c2n,"StreamImpl/1",1102),sDn(1103,1,QZn,yd),uZn.Cd=function(n){mG(this.a,uG(n,848))},zW(c2n,"StreamImpl/1/lambda$0$Type",1103),sDn(1104,1,y1n,Md),uZn.Mb=function(n){return FV(this.a,n)},zW(c2n,"StreamImpl/1methodref$add$Type",1104),sDn(1105,500,WZn,QY),uZn.Bd=function(n){var t;return this.a||(t=new Zm,this.b.a.Nb(new Td(t)),hZ(),f$(t,this.c),this.a=new h3(t,16)),urn(this.a,n)},uZn.a=null,zW(c2n,"StreamImpl/5",1105),sDn(1106,1,QZn,Td),uZn.Cd=function(n){kD(this.a,n)},zW(c2n,"StreamImpl/5/2methodref$add$Type",1106),sDn(737,500,WZn,ien),uZn.Bd=function(n){for(this.b=!1;!this.b&&this.c.Bd(new WP(this,n)););return this.b},uZn.b=!1,zW(c2n,"StreamImpl/FilterSpliterator",737),sDn(1096,1,QZn,WP),uZn.Cd=function(n){Xz(this.a,this.b,n)},zW(c2n,"StreamImpl/FilterSpliterator/lambda$0$Type",1096),sDn(1091,736,WZn,s7),uZn.Re=function(n){return v_(this,uG(n,189))},zW(c2n,"StreamImpl/MapToDoubleSpliterator",1091),sDn(1095,1,QZn,QP),uZn.Cd=function(n){vC(this.a,this.b,n)},zW(c2n,"StreamImpl/MapToDoubleSpliterator/lambda$0$Type",1095),sDn(1090,735,WZn,h7),uZn.Re=function(n){return k_(this,uG(n,202))},zW(c2n,"StreamImpl/MapToIntSpliterator",1090),sDn(1094,1,QZn,JP),uZn.Cd=function(n){kC(this.a,this.b,n)},zW(c2n,"StreamImpl/MapToIntSpliterator/lambda$0$Type",1094),sDn(734,500,WZn,f7),uZn.Bd=function(n){return y_(this,n)},zW(c2n,"StreamImpl/MapToObjSpliterator",734),sDn(1093,1,QZn,YP),uZn.Cd=function(n){yC(this.a,this.b,n)},zW(c2n,"StreamImpl/MapToObjSpliterator/lambda$0$Type",1093),sDn(1092,500,WZn,Fan),uZn.Bd=function(n){for(;NP(this.b,0);){if(!this.a.Bd(new on))return!1;this.b=$gn(this.b,1)}return this.a.Bd(n)},uZn.b=0,zW(c2n,"StreamImpl/SkipSpliterator",1092),sDn(1097,1,QZn,on),uZn.Cd=function(n){},zW(c2n,"StreamImpl/SkipSpliterator/lambda$0$Type",1097),sDn(626,1,QZn,un),uZn.Cd=function(n){Ob(this,n)},zW(c2n,"StreamImpl/ValueConsumer",626),sDn(1098,1,QZn,sn),uZn.Cd=function(n){vS()},zW(c2n,"StreamImpl/lambda$0$Type",1098),sDn(1099,1,QZn,hn),uZn.Cd=function(n){vS()},zW(c2n,"StreamImpl/lambda$1$Type",1099),sDn(1100,1,{},jd),uZn.Ve=function(n,t){return FB(this.a,n,t)},zW(c2n,"StreamImpl/lambda$4$Type",1100),sDn(1101,1,QZn,nC),uZn.Cd=function(n){kF(this.b,this.a,n)},zW(c2n,"StreamImpl/lambda$5$Type",1101),sDn(1107,1,QZn,Ed),uZn.Cd=function(n){Usn(this.a,uG(n,380))},zW(c2n,"TerminatableStream/lambda$0$Type",1107),sDn(2142,1,{}),sDn(2014,1,{},fn),zW("javaemul.internal","ConsoleLogger",2014);var _ut=0;sDn(2134,1,{}),sDn(1830,1,QZn,ln),uZn.Cd=function(n){uG(n,317)},zW(l2n,"BowyerWatsonTriangulation/lambda$0$Type",1830),sDn(1831,1,QZn,Pd),uZn.Cd=function(n){Qon(this.a,uG(n,317).e)},zW(l2n,"BowyerWatsonTriangulation/lambda$1$Type",1831),sDn(1832,1,QZn,bn),uZn.Cd=function(n){uG(n,177)},zW(l2n,"BowyerWatsonTriangulation/lambda$2$Type",1832),sDn(1827,1,b2n,Cd),uZn.Ne=function(n,t){return S5(this.a,uG(n,177),uG(t,177))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(l2n,"NaiveMinST/lambda$0$Type",1827),sDn(449,1,{},Sd),zW(l2n,"NodeMicroLayout",449),sDn(177,1,{177:1},ZP),uZn.Fb=function(n){var t;return!!F$(n,177)&&(t=uG(n,177),OJ(this.a,t.a)&&OJ(this.b,t.b)||OJ(this.a,t.b)&&OJ(this.b,t.a))},uZn.Hb=function(){return VN(this.a)+VN(this.b)};var But=zW(l2n,"TEdge",177);sDn(317,1,{317:1},gqn),uZn.Fb=function(n){var t;return!!F$(n,317)&&Den(this,(t=uG(n,317)).a)&&Den(this,t.b)&&Den(this,t.c)},uZn.Hb=function(){return VN(this.a)+VN(this.b)+VN(this.c)},zW(l2n,"TTriangle",317),sDn(225,1,{225:1},C$),zW(l2n,"Tree",225),sDn(1218,1,{},q0),zW(w2n,"Scanline",1218);var Hut=Iq(w2n,d2n);sDn(1758,1,{},Qin),zW(g2n,"CGraph",1758),sDn(316,1,{316:1},V0),uZn.b=0,uZn.c=0,uZn.d=0,uZn.g=0,uZn.i=0,uZn.k=T0n,zW(g2n,"CGroup",316),sDn(830,1,{},fk),zW(g2n,"CGroup/CGroupBuilder",830),sDn(60,1,{60:1},NF),uZn.Ib=function(){return this.j?mK(this.j.Kb(this)):(vK(zut),zut.o+"@"+(xx(this)>>>0).toString(16))},uZn.f=0,uZn.i=T0n;var Uut,Gut,qut,Xut,zut=zW(g2n,"CNode",60);sDn(829,1,{},lk),zW(g2n,"CNode/CNodeBuilder",829),sDn(1590,1,{},wn),uZn.ff=function(n,t){return 0},uZn.gf=function(n,t){return 0},zW(g2n,m2n,1590),sDn(1853,1,{},dn),uZn.cf=function(n){var t,i,r,c,a,o,u,s,h,f,l,b,w,d,g;for(h=M0n,r=new Ww(n.a.b);r.ae.d.c||e.d.c==r.d.c&&e.d.b0?n+this.n.d+this.n.a:0},uZn.kf=function(){var n,t,i,r,c;if(c=0,this.e)this.b?c=this.b.a:this.a[1][1]&&(c=this.a[1][1].kf());else if(this.g)c=ypn(this,wEn(this,null,!0));else for(Yrn(),i=0,r=(t=Uhn(cT(Ist,1),p1n,237,0,[jst,Est,Sst])).length;i0?c+this.n.b+this.n.c:0},uZn.lf=function(){var n,t,e,i,r;if(this.g)for(n=wEn(this,null,!1),Yrn(),i=0,r=(e=Uhn(cT(Ist,1),p1n,237,0,[jst,Est,Sst])).length;i0&&(r[0]+=this.d,i-=r[0]),r[2]>0&&(r[2]+=this.d,i-=r[2]),this.c.a=e.Math.max(0,i),this.c.d=t.d+n.d+(this.c.a-i)/2,r[1]=e.Math.max(r[1],i),J9(this,Est,t.d+n.d+r[0]-(r[1]-i)/2,r)},uZn.b=null,uZn.d=0,uZn.e=!1,uZn.f=!1,uZn.g=!1;var Ost,Ast,Lst,Nst=0,$st=0;zW(U2n,"GridContainerCell",1538),sDn(471,22,{3:1,34:1,22:1,471:1},aC);var Dst,xst=_cn(U2n,"HorizontalLabelAlignment",471,Oat,R2,gB);sDn(314,217,{217:1,314:1},a0,Yin,c1),uZn.jf=function(){return iq(this)},uZn.kf=function(){return rq(this)},uZn.a=0,uZn.c=!1;var Rst,Kst,Fst,_st=zW(U2n,"LabelCell",314);sDn(252,336,{217:1,336:1,252:1},tkn),uZn.jf=function(){return dNn(this)},uZn.kf=function(){return gNn(this)},uZn.lf=function(){YGn(this)},uZn.mf=function(){rqn(this)},uZn.b=0,uZn.c=0,uZn.d=!1,zW(U2n,"StripContainerCell",252),sDn(1691,1,y1n,Mn),uZn.Mb=function(n){return $M(uG(n,217))},zW(U2n,"StripContainerCell/lambda$0$Type",1691),sDn(1692,1,{},Tn),uZn.Ye=function(n){return uG(n,217).kf()},zW(U2n,"StripContainerCell/lambda$1$Type",1692),sDn(1693,1,y1n,jn),uZn.Mb=function(n){return DM(uG(n,217))},zW(U2n,"StripContainerCell/lambda$2$Type",1693),sDn(1694,1,{},En),uZn.Ye=function(n){return uG(n,217).jf()},zW(U2n,"StripContainerCell/lambda$3$Type",1694),sDn(472,22,{3:1,34:1,22:1,472:1},oC);var Bst,Hst,Ust,Gst,qst,Xst,zst,Vst,Wst,Qst,Jst,Yst,Zst,nht,tht,eht,iht,rht,cht,aht,oht,uht,sht,hht=_cn(U2n,"VerticalLabelAlignment",472,Oat,x2,pB);sDn(800,1,{},kQn),uZn.c=0,uZn.d=0,uZn.k=0,uZn.s=0,uZn.t=0,uZn.v=!1,uZn.w=0,uZn.D=!1,zW(J2n,"NodeContext",800),sDn(1536,1,b2n,Sn),uZn.Ne=function(n,t){return UL(uG(n,64),uG(t,64))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(J2n,"NodeContext/0methodref$comparePortSides$Type",1536),sDn(1537,1,b2n,Pn),uZn.Ne=function(n,t){return ACn(uG(n,117),uG(t,117))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(J2n,"NodeContext/1methodref$comparePortContexts$Type",1537),sDn(164,22,{3:1,34:1,22:1,164:1},pun);var fht,lht,bht,wht,dht,ght,pht,mht=_cn(J2n,"NodeLabelLocation",164,Oat,Nkn,mB);sDn(117,1,{117:1},v$n),uZn.a=!1,zW(J2n,"PortContext",117),sDn(1541,1,QZn,Cn),uZn.Cd=function(n){eE(uG(n,314))},zW(n3n,t3n,1541),sDn(1542,1,y1n,In),uZn.Mb=function(n){return!!uG(n,117).c},zW(n3n,e3n,1542),sDn(1543,1,QZn,On),uZn.Cd=function(n){eE(uG(n,117).c)},zW(n3n,"LabelPlacer/lambda$2$Type",1543),sDn(1540,1,QZn,An),uZn.Cd=function(n){VK(),wv(uG(n,117))},zW(n3n,"NodeLabelAndSizeUtilities/lambda$0$Type",1540),sDn(801,1,QZn,DB),uZn.Cd=function(n){aP(this.b,this.c,this.a,uG(n,187))},uZn.a=!1,uZn.c=!1,zW(n3n,"NodeLabelCellCreator/lambda$0$Type",801),sDn(1539,1,QZn,Ld),uZn.Cd=function(n){Vv(this.a,uG(n,187))},zW(n3n,"PortContextCreator/lambda$0$Type",1539),sDn(1902,1,{},Ln),zW(r3n,"GreedyRectangleStripOverlapRemover",1902),sDn(1903,1,b2n,Nn),uZn.Ne=function(n,t){return Cx(uG(n,226),uG(t,226))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(r3n,"GreedyRectangleStripOverlapRemover/0methodref$compareByYCoordinate$Type",1903),sDn(1849,1,{},pk),uZn.a=5,uZn.e=0,zW(r3n,"RectangleStripOverlapRemover",1849),sDn(1850,1,b2n,$n),uZn.Ne=function(n,t){return Ix(uG(n,226),uG(t,226))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(r3n,"RectangleStripOverlapRemover/0methodref$compareLeftRectangleBorders$Type",1850),sDn(1852,1,b2n,Dn),uZn.Ne=function(n,t){return fW(uG(n,226),uG(t,226))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(r3n,"RectangleStripOverlapRemover/1methodref$compareRightRectangleBorders$Type",1852),sDn(417,22,{3:1,34:1,22:1,417:1},uC);var vht,kht,yht,Mht,Tht,jht=_cn(r3n,"RectangleStripOverlapRemover/OverlapRemovalDirection",417,Oat,B6,vB);sDn(226,1,{226:1},ZX),zW(r3n,"RectangleStripOverlapRemover/RectangleNode",226),sDn(1851,1,QZn,Nd),uZn.Cd=function(n){lTn(this.a,uG(n,226))},zW(r3n,"RectangleStripOverlapRemover/lambda$1$Type",1851),sDn(1323,1,b2n,xn),uZn.Ne=function(n,t){return fzn(uG(n,176),uG(t,176))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(a3n,"PolyominoCompactor/CornerCasesGreaterThanRestComparator",1323),sDn(1326,1,{},Rn),uZn.Kb=function(n){return uG(n,334).a},zW(a3n,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$0$Type",1326),sDn(1327,1,y1n,Kn),uZn.Mb=function(n){return uG(n,332).a},zW(a3n,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$1$Type",1327),sDn(1328,1,y1n,Fn),uZn.Mb=function(n){return uG(n,332).a},zW(a3n,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$2$Type",1328),sDn(1321,1,b2n,_n),uZn.Ne=function(n,t){return JBn(uG(n,176),uG(t,176))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(a3n,"PolyominoCompactor/MinNumOfExtensionDirectionsComparator",1321),sDn(1324,1,{},Bn),uZn.Kb=function(n){return uG(n,334).a},zW(a3n,"PolyominoCompactor/MinNumOfExtensionDirectionsComparator/lambda$0$Type",1324),sDn(781,1,b2n,Hn),uZn.Ne=function(n,t){return lhn(uG(n,176),uG(t,176))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(a3n,"PolyominoCompactor/MinNumOfExtensionsComparator",781),sDn(1319,1,b2n,Un),uZn.Ne=function(n,t){return ron(uG(n,330),uG(t,330))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(a3n,"PolyominoCompactor/MinPerimeterComparator",1319),sDn(1320,1,b2n,Gn),uZn.Ne=function(n,t){return Byn(uG(n,330),uG(t,330))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(a3n,"PolyominoCompactor/MinPerimeterComparatorWithShape",1320),sDn(1322,1,b2n,qn),uZn.Ne=function(n,t){return zHn(uG(n,176),uG(t,176))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(a3n,"PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator",1322),sDn(1325,1,{},Xn),uZn.Kb=function(n){return uG(n,334).a},zW(a3n,"PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator/lambda$0$Type",1325),sDn(782,1,{},sC),uZn.Ve=function(n,t){return d6(this,uG(n,42),uG(t,176))},zW(a3n,"SuccessorCombination",782),sDn(649,1,{},zn),uZn.Ve=function(n,t){var e;return KNn((e=uG(n,42),uG(t,176),e))},zW(a3n,"SuccessorJitter",649),sDn(648,1,{},Vn),uZn.Ve=function(n,t){var e;return cFn((e=uG(n,42),uG(t,176),e))},zW(a3n,"SuccessorLineByLine",648),sDn(573,1,{},Wn),uZn.Ve=function(n,t){var e;return txn((e=uG(n,42),uG(t,176),e))},zW(a3n,"SuccessorManhattan",573),sDn(1344,1,{},Qn),uZn.Ve=function(n,t){var e;return lKn((e=uG(n,42),uG(t,176),e))},zW(a3n,"SuccessorMaxNormWindingInMathPosSense",1344),sDn(409,1,{},$d),uZn.Ve=function(n,t){return HV(this,n,t)},uZn.c=!1,uZn.d=!1,uZn.e=!1,uZn.f=!1,zW(a3n,"SuccessorQuadrantsGeneric",409),sDn(1345,1,{},Jn),uZn.Kb=function(n){return uG(n,334).a},zW(a3n,"SuccessorQuadrantsGeneric/lambda$0$Type",1345),sDn(332,22,{3:1,34:1,22:1,332:1},hC),uZn.a=!1;var Eht,Sht=_cn(f3n,l3n,332,Oat,F6,kB);sDn(1317,1,{}),uZn.Ib=function(){var n,t,e,i,r,c;for(e=" ",n=xwn(0),r=0;r=0?"b"+n+"["+X8(this.a)+"]":"b["+X8(this.a)+"]":"b_"+xx(this)},zW(V3n,"FBendpoint",250),sDn(290,137,{3:1,290:1,96:1,137:1},$F),uZn.Ib=function(){return X8(this)},zW(V3n,"FEdge",290),sDn(235,137,{3:1,235:1,96:1,137:1},d7);var uft,sft,hft,fft,lft,bft,wft,dft,gft,pft,mft=zW(V3n,"FGraph",235);sDn(454,309,{3:1,454:1,309:1,96:1,137:1},A5),uZn.Ib=function(){return null==this.b||0==this.b.length?"l["+X8(this.a)+"]":"l_"+this.b},zW(V3n,"FLabel",454),sDn(153,309,{3:1,153:1,309:1,96:1,137:1},E$),uZn.Ib=function(){return z3(this)},uZn.a=0,zW(V3n,"FNode",153),sDn(2100,1,{}),uZn.vf=function(n){pGn(this,n)},uZn.wf=function(){ITn(this)},uZn.d=0,zW(Q3n,"AbstractForceModel",2100),sDn(641,2100,{641:1},lsn),uZn.uf=function(n,t){var i,r,c,a;return qzn(this.f,n,t),c=YF(D$(t.d),n.d),a=e.Math.sqrt(c.a*c.a+c.b*c.b),r=e.Math.max(0,a-NQ(n.e)/2-NQ(t.e)/2),vD(c,((i=VNn(this.e,n,t))>0?-iW(r,this.c)*i:TR(r,this.b)*uG(oIn(n,(cGn(),$ft)),17).a)/a),c},uZn.vf=function(n){pGn(this,n),this.a=uG(oIn(n,(cGn(),Tft)),17).a,this.c=uM(pK(oIn(n,_ft))),this.b=uM(pK(oIn(n,xft)))},uZn.xf=function(n){return n0&&(a-=aM(r,this.a)*i),vD(c,a*this.b/o),c},uZn.vf=function(n){var t,i,r,c,a,o,u;for(pGn(this,n),this.b=uM(pK(oIn(n,(cGn(),Bft)))),this.c=this.b/uG(oIn(n,Tft),17).a,r=n.e.c.length,a=0,c=0,u=new Ww(n.e);u.a0},uZn.a=0,uZn.b=0,uZn.c=0,zW(Q3n,"FruchtermanReingoldModel",642),sDn(860,1,K2n,Gf),uZn.hf=function(n){Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,J3n),""),"Force Model"),"Determines the model for force calculation."),hft),(lAn(),gNt)),mlt),ggn((Rkn(),hNt))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Y3n),""),"Iterations"),"The number of iterations on the force model."),xwn(300)),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Z3n),""),"Repulsive Power"),"Determines how many bend points are added to the edge; such bend points are regarded as repelling particles in the force model"),xwn(0)),mNt),dot),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,n4n),""),"FR Temperature"),"The temperature is used as a scaling factor for particle displacements."),t4n),dNt),fot),ggn(hNt)))),H4(n,n4n,J3n,dft),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,e4n),""),"Eades Repulsion"),"Factor for repulsive forces in Eades' model."),5),dNt),fot),ggn(hNt)))),H4(n,e4n,J3n,lft),vJn((new qf,n))},zW(i4n,"ForceMetaDataProvider",860),sDn(432,22,{3:1,34:1,22:1,432:1},wC);var vft,kft,yft,Mft,Tft,jft,Eft,Sft,Pft,Cft,Ift,Oft,Aft,Lft,Nft,$ft,Dft,xft,Rft,Kft,Fft,_ft,Bft,Hft,Uft,Gft,qft,Xft,zft,Vft,Wft,Qft,Jft,Yft,Zft,nlt,tlt,elt,ilt,rlt,clt,alt,olt,ult,slt,hlt,flt,llt,blt,wlt,dlt,glt,plt,mlt=_cn(i4n,"ForceModelStrategy",432,Oat,h1,TB);sDn($1n,1,K2n,qf),uZn.hf=function(n){vJn(n)},zW(i4n,"ForceOptions",$1n),sDn(1001,1,{},mt),uZn.sf=function(){return new hk},uZn.tf=function(n){},zW(i4n,"ForceOptions/ForceFactory",1001),sDn(861,1,K2n,Xf),uZn.hf=function(n){Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,I4n),""),"Fixed Position"),"Prevent that the node is moved by the layout algorithm."),(qx(),!1)),(lAn(),wNt)),cot),ggn((Rkn(),sNt))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,O4n),""),"Desired Edge Length"),"Either specified for parent nodes or for individual edges, where the latter takes higher precedence."),100),dNt),fot),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[oNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,A4n),""),"Layout Dimension"),"Dimensions that are permitted to be altered during layout."),Zft),gNt),Clt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,L4n),""),"Stress Epsilon"),"Termination criterion for the iterative process."),t4n),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,N4n),""),"Iteration Limit"),"Maximum number of performed iterations. Takes higher precedence than 'epsilon'."),xwn(vZn)),mNt),dot),ggn(hNt)))),sWn((new zf,n))},zW(i4n,"StressMetaDataProvider",861),sDn(1004,1,K2n,zf),uZn.hf=function(n){sWn(n)},zW(i4n,"StressOptions",1004),sDn(1005,1,{},gt),uZn.sf=function(){return new DF},uZn.tf=function(n){},zW(i4n,"StressOptions/StressFactory",1005),sDn(1110,205,M3n,DF),uZn.rf=function(n,t){var e,i,r,c;for(t.Ug(D4n,1),oM(gK(zDn(n,(Bjn(),olt))))?oM(gK(zDn(n,blt)))||J1(new Sd((vP(),new Vy(n)))):Zxn(new hk,n,t.eh(1)),i=yfn(n),c=(e=tqn(this.a,i)).Kc();c.Ob();)(r=uG(c.Pb(),235)).e.c.length<=1||(czn(this.b,r),QDn(this.b),Prn(r.d,new pt));YJn(i=lJn(e)),t.Vg()},zW(R4n,"StressLayoutProvider",1110),sDn(1111,1,QZn,pt),uZn.Cd=function(n){Yqn(uG(n,454))},zW(R4n,"StressLayoutProvider/lambda$0$Type",1111),sDn(1002,1,{},qv),uZn.c=0,uZn.e=0,uZn.g=0,zW(R4n,"StressMajorization",1002),sDn(391,22,{3:1,34:1,22:1,391:1},dC);var vlt,klt,ylt,Mlt,Tlt,jlt,Elt,Slt,Plt,Clt=_cn(R4n,"StressMajorization/Dimension",391,Oat,F2,jB);sDn(1003,1,b2n,Fd),uZn.Ne=function(n,t){return j_(this.a,uG(n,153),uG(t,153))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(R4n,"StressMajorization/lambda$0$Type",1003),sDn(1192,1,{},i4),zW(F4n,"ElkLayered",1192),sDn(1193,1,QZn,_d),uZn.Cd=function(n){OLn(this.a,uG(n,36))},zW(F4n,"ElkLayered/lambda$0$Type",1193),sDn(1194,1,QZn,Bd),uZn.Cd=function(n){E_(this.a,uG(n,36))},zW(F4n,"ElkLayered/lambda$1$Type",1194),sDn(1281,1,{},z$),zW(F4n,"GraphConfigurator",1281),sDn(770,1,QZn,Hd),uZn.Cd=function(n){XIn(this.a,uG(n,10))},zW(F4n,"GraphConfigurator/lambda$0$Type",770),sDn(771,1,{},dt),uZn.Kb=function(n){return FEn(),new fX(null,new h3(uG(n,30).a,16))},zW(F4n,"GraphConfigurator/lambda$1$Type",771),sDn(772,1,QZn,Ud),uZn.Cd=function(n){XIn(this.a,uG(n,10))},zW(F4n,"GraphConfigurator/lambda$2$Type",772),sDn(1109,205,M3n,mk),uZn.rf=function(n,t){var e;e=vXn(new kk,n),xA(zDn(n,(jYn(),rMt)))===xA((Own(),Ixt))?Tgn(this.a,e,t):BDn(this.a,e,t),t.$g()||NQn(new Vf,e)},zW(F4n,"LayeredLayoutProvider",1109),sDn(367,22,{3:1,34:1,22:1,367:1},gC);var Ilt,Olt,Alt,Llt=_cn(F4n,"LayeredPhases",367,Oat,u9,EB);sDn(1717,1,{},$an),uZn.i=0,zW(_4n,"ComponentsToCGraphTransformer",1717),sDn(1718,1,{},wt),uZn.yf=function(n,t){return e.Math.min(null!=n.a?uM(n.a):n.c.i,null!=t.a?uM(t.a):t.c.i)},uZn.zf=function(n,t){return e.Math.min(null!=n.a?uM(n.a):n.c.i,null!=t.a?uM(t.a):t.c.i)},zW(_4n,"ComponentsToCGraphTransformer/1",1718),sDn(86,1,{86:1}),uZn.i=0,uZn.k=!0,uZn.o=T0n;var Nlt,$lt,Dlt,xlt=zW(B4n,"CNode",86);sDn(470,86,{470:1,86:1},Jx,Yvn),uZn.Ib=function(){return""},zW(_4n,"ComponentsToCGraphTransformer/CRectNode",470),sDn(1688,1,{},vt),zW(_4n,"OneDimensionalComponentsCompaction",1688),sDn(1689,1,{},kt),uZn.Kb=function(n){return w2(uG(n,42))},uZn.Fb=function(n){return this===n},zW(_4n,"OneDimensionalComponentsCompaction/lambda$0$Type",1689),sDn(1690,1,{},yt),uZn.Kb=function(n){return xgn(uG(n,42))},uZn.Fb=function(n){return this===n},zW(_4n,"OneDimensionalComponentsCompaction/lambda$1$Type",1690),sDn(1720,1,{},wQ),zW(B4n,"CGraph",1720),sDn(194,1,{194:1},Zvn),uZn.b=0,uZn.c=0,uZn.e=0,uZn.g=!0,uZn.i=T0n,zW(B4n,"CGroup",194),sDn(1719,1,{},Mt),uZn.yf=function(n,t){return e.Math.max(null!=n.a?uM(n.a):n.c.i,null!=t.a?uM(t.a):t.c.i)},uZn.zf=function(n,t){return e.Math.max(null!=n.a?uM(n.a):n.c.i,null!=t.a?uM(t.a):t.c.i)},zW(B4n,m2n,1719),sDn(1721,1,{},i$n),uZn.d=!1;var Rlt=zW(B4n,T2n,1721);sDn(1722,1,{},Tt),uZn.Kb=function(n){return GS(),qx(),0!=uG(uG(n,42).a,86).d.e},uZn.Fb=function(n){return this===n},zW(B4n,j2n,1722),sDn(833,1,{},cX),uZn.a=!1,uZn.b=!1,uZn.c=!1,uZn.d=!1,zW(B4n,E2n,833),sDn(1898,1,{},nz),zW(H4n,S2n,1898);var Klt=Iq(U4n,d2n);sDn(1899,1,{382:1},FZ),uZn.bf=function(n){DFn(this,uG(n,476))},zW(H4n,P2n,1899),sDn(V1n,1,b2n,jt),uZn.Ne=function(n,t){return rY(uG(n,86),uG(t,86))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(H4n,C2n,V1n),sDn(476,1,{476:1},KC),uZn.a=!1,zW(H4n,I2n,476),sDn(1901,1,b2n,Et),uZn.Ne=function(n,t){return KEn(uG(n,476),uG(t,476))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(H4n,O2n,1901),sDn(148,1,{148:1},FC,wG),uZn.Fb=function(n){var t;return null!=n&&Ult==Tbn(n)&&(t=uG(n,148),OJ(this.c,t.c)&&OJ(this.d,t.d))},uZn.Hb=function(){return Obn(Uhn(cT(dat,1),EZn,1,5,[this.c,this.d]))},uZn.Ib=function(){return"("+this.c+TZn+this.d+(this.a?"cx":"")+this.b+")"},uZn.a=!0,uZn.c=0,uZn.d=0;var Flt,_lt,Blt,Hlt,Ult=zW(U4n,"Point",148);sDn(416,22,{3:1,34:1,22:1,416:1},jC);var Glt,qlt,Xlt,zlt,Vlt,Wlt,Qlt,Jlt,Ylt,Zlt,nbt,tbt,ebt=_cn(U4n,"Point/Quadrant",416,Oat,H6,SB);sDn(1708,1,{},dk),uZn.b=null,uZn.c=null,uZn.d=null,uZn.e=null,uZn.f=null,zW(U4n,"RectilinearConvexHull",1708),sDn(583,1,{382:1},cyn),uZn.bf=function(n){Itn(this,uG(n,148))},uZn.b=0,zW(U4n,"RectilinearConvexHull/MaximalElementsEventHandler",583),sDn(1710,1,b2n,St),uZn.Ne=function(n,t){return cY(pK(n),pK(t))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(U4n,"RectilinearConvexHull/MaximalElementsEventHandler/lambda$0$Type",1710),sDn(1709,1,{382:1},Jin),uZn.bf=function(n){pKn(this,uG(n,148))},uZn.a=0,uZn.b=null,uZn.c=null,uZn.d=null,uZn.e=null,zW(U4n,"RectilinearConvexHull/RectangleEventHandler",1709),sDn(1711,1,b2n,Pt),uZn.Ne=function(n,t){return H3(uG(n,148),uG(t,148))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(U4n,"RectilinearConvexHull/lambda$0$Type",1711),sDn(1712,1,b2n,At),uZn.Ne=function(n,t){return U3(uG(n,148),uG(t,148))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(U4n,"RectilinearConvexHull/lambda$1$Type",1712),sDn(1713,1,b2n,Lt),uZn.Ne=function(n,t){return B3(uG(n,148),uG(t,148))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(U4n,"RectilinearConvexHull/lambda$2$Type",1713),sDn(1714,1,b2n,Ot),uZn.Ne=function(n,t){return G3(uG(n,148),uG(t,148))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(U4n,"RectilinearConvexHull/lambda$3$Type",1714),sDn(1715,1,b2n,Nt),uZn.Ne=function(n,t){return sIn(uG(n,148),uG(t,148))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(U4n,"RectilinearConvexHull/lambda$4$Type",1715),sDn(1716,1,{},X0),zW(U4n,"Scanline",1716),sDn(2104,1,{}),zW(G4n,"AbstractGraphPlacer",2104),sDn(335,1,{335:1},DR),uZn.Ff=function(n){return!!this.Gf(n)&&(UNn(this.b,uG(oIn(n,(GYn(),xpt)),21),n),!0)},uZn.Gf=function(n){var t,e,i;for(t=uG(oIn(n,(GYn(),xpt)),21),i=uG(Y9(Jlt,t),21).Kc();i.Ob();)if(e=uG(i.Pb(),21),!uG(Y9(this.b,e),15).dc())return!1;return!0},zW(G4n,"ComponentGroup",335),sDn(779,2104,{},gk),uZn.Hf=function(n){var t;for(t=new Ww(this.a);t.ai&&(f=0,l+=u+r,u=0),tHn(a,f+(s=a.c).a,l+s.b),dL(s),c=e.Math.max(c,f+h.a),u=e.Math.max(u,h.b),f+=h.a+r;t.f.a=c,t.f.b=l+u},uZn.Jf=function(n,t){var e,i,r,c,a;if(xA(oIn(t,(jYn(),kyt)))===xA((Uvn(),tbt))){for(i=n.Kc();i.Ob();){for(a=0,c=new Ww((e=uG(i.Pb(),36)).a);c.ai&&!uG(oIn(a,(GYn(),xpt)),21).Hc((KQn(),yRt))||s&&uG(oIn(s,(GYn(),xpt)),21).Hc((KQn(),kRt))||uG(oIn(a,(GYn(),xpt)),21).Hc((KQn(),_Rt)))&&(b=l,w+=u+r,u=0),h=a.c,uG(oIn(a,(GYn(),xpt)),21).Hc((KQn(),yRt))&&(b=c+r),tHn(a,b+h.a,w+h.b),c=e.Math.max(c,b+f.a),uG(oIn(a,xpt),21).Hc(KRt)&&(l=e.Math.max(l,b+f.a+r)),dL(h),u=e.Math.max(u,f.b),b+=f.a+r,s=a;t.f.a=c,t.f.b=w+u},uZn.Jf=function(n,t){},zW(G4n,"ModelOrderRowGraphPlacer",1313),sDn(1311,1,b2n,xt),uZn.Ne=function(n,t){return Wsn(uG(n,36),uG(t,36))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(G4n,"SimpleRowGraphPlacer/1",1311),sDn(1280,1,A2n,Rt),uZn.Lb=function(n){var t;return!!(t=uG(oIn(uG(n,249).b,(jYn(),bMt)),75))&&0!=t.b},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){var t;return!!(t=uG(oIn(uG(n,249).b,(jYn(),bMt)),75))&&0!=t.b},zW(W4n,"CompoundGraphPostprocessor/1",1280),sDn(1279,1,Q4n,yk),uZn.Kf=function(n,t){zyn(this,uG(n,36),t)},zW(W4n,"CompoundGraphPreprocessor",1279),sDn(453,1,{453:1},Sdn),uZn.c=!1,zW(W4n,"CompoundGraphPreprocessor/ExternalPort",453),sDn(249,1,{249:1},$B),uZn.Ib=function(){return MR(this.c)+":"+MNn(this.b)},zW(W4n,"CrossHierarchyEdge",249),sDn(777,1,b2n,Gd),uZn.Ne=function(n,t){return Njn(this,uG(n,249),uG(t,249))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(W4n,"CrossHierarchyEdgeComparator",777),sDn(305,137,{3:1,305:1,96:1,137:1}),uZn.p=0,zW(J4n,"LGraphElement",305),sDn(18,305,{3:1,18:1,305:1,96:1,137:1},UZ),uZn.Ib=function(){return MNn(this)};var obt=zW(J4n,"LEdge",18);sDn(36,305,{3:1,20:1,36:1,305:1,96:1,137:1},Dan),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return new Ww(this.b)},uZn.Ib=function(){return 0==this.b.c.length?"G-unlayered"+vIn(this.a):0==this.a.c.length?"G-layered"+vIn(this.b):"G[layerless"+vIn(this.a)+", layers"+vIn(this.b)+"]"};var ubt,sbt=zW(J4n,"LGraph",36);sDn(666,1,{}),uZn.Lf=function(){return this.e.n},uZn.of=function(n){return oIn(this.e,n)},uZn.Mf=function(){return this.e.o},uZn.Nf=function(){return this.e.p},uZn.pf=function(n){return vR(this.e,n)},uZn.Of=function(n){this.e.n.a=n.a,this.e.n.b=n.b},uZn.Pf=function(n){this.e.o.a=n.a,this.e.o.b=n.b},uZn.Qf=function(n){this.e.p=n},zW(J4n,"LGraphAdapters/AbstractLShapeAdapter",666),sDn(474,1,{853:1},qd),uZn.Rf=function(){var n,t;if(!this.b)for(this.b=iR(this.a.b.c.length),t=new Ww(this.a.b);t.a0&&Hbn((s3(t-1,n.length),n.charCodeAt(t-1)),c6n);)--t;if(r> ",n),njn(e)),JA(QA((n.a+="[",n),e.i),"]")),n.a},uZn.c=!0,uZn.d=!1;var Pbt,Cbt,Ibt,Obt,Abt=zW(J4n,"LPort",12);sDn(408,1,t1n,zd),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return new Vd(new Ww(this.a.e))},zW(J4n,"LPort/1",408),sDn(1309,1,$Zn,Vd),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){return uG(N3(this.a),18).c},uZn.Ob=function(){return l$(this.a)},uZn.Qb=function(){tW(this.a)},zW(J4n,"LPort/1/1",1309),sDn(369,1,t1n,Wd),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return new Qd(new Ww(this.a.g))},zW(J4n,"LPort/2",369),sDn(776,1,$Zn,Qd),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){return uG(N3(this.a),18).d},uZn.Ob=function(){return l$(this.a)},uZn.Qb=function(){tW(this.a)},zW(J4n,"LPort/2/1",776),sDn(1302,1,t1n,LC),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return new w7(this)},zW(J4n,"LPort/CombineIter",1302),sDn(208,1,$Zn,w7),uZn.Nb=function(n){SV(this,n)},uZn.Qb=function(){xj()},uZn.Ob=function(){return Dx(this)},uZn.Pb=function(){return l$(this.a)?N3(this.a):N3(this.b)},zW(J4n,"LPort/CombineIter/1",208),sDn(1303,1,A2n,Bt),uZn.Lb=function(n){return Yz(n)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return Lun(),0!=uG(n,12).g.c.length},zW(J4n,"LPort/lambda$0$Type",1303),sDn(1304,1,A2n,Ht),uZn.Lb=function(n){return Zz(n)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return Lun(),0!=uG(n,12).e.c.length},zW(J4n,"LPort/lambda$1$Type",1304),sDn(1305,1,A2n,Ut),uZn.Lb=function(n){return Lun(),uG(n,12).j==(KQn(),yRt)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return Lun(),uG(n,12).j==(KQn(),yRt)},zW(J4n,"LPort/lambda$2$Type",1305),sDn(1306,1,A2n,Gt),uZn.Lb=function(n){return Lun(),uG(n,12).j==(KQn(),kRt)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return Lun(),uG(n,12).j==(KQn(),kRt)},zW(J4n,"LPort/lambda$3$Type",1306),sDn(1307,1,A2n,qt),uZn.Lb=function(n){return Lun(),uG(n,12).j==(KQn(),KRt)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return Lun(),uG(n,12).j==(KQn(),KRt)},zW(J4n,"LPort/lambda$4$Type",1307),sDn(1308,1,A2n,Xt),uZn.Lb=function(n){return Lun(),uG(n,12).j==(KQn(),_Rt)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return Lun(),uG(n,12).j==(KQn(),_Rt)},zW(J4n,"LPort/lambda$5$Type",1308),sDn(30,305,{3:1,20:1,305:1,30:1,96:1,137:1},bQ),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return new Ww(this.a)},uZn.Ib=function(){return"L_"+Ten(this.b.b,this,0)+vIn(this.a)},zW(J4n,"Layer",30),sDn(1330,1,{},kk),zW(h6n,f6n,1330),sDn(1334,1,{},zt),uZn.Kb=function(n){return lCn(uG(n,84))},zW(h6n,"ElkGraphImporter/0methodref$connectableShapeToNode$Type",1334),sDn(1337,1,{},Vt),uZn.Kb=function(n){return lCn(uG(n,84))},zW(h6n,"ElkGraphImporter/1methodref$connectableShapeToNode$Type",1337),sDn(1331,1,QZn,Jd),uZn.Cd=function(n){y$n(this.a,uG(n,123))},zW(h6n,z3n,1331),sDn(1332,1,QZn,Yd),uZn.Cd=function(n){y$n(this.a,uG(n,123))},zW(h6n,l6n,1332),sDn(1333,1,{},Wt),uZn.Kb=function(n){return new fX(null,new h3(KJ(uG(n,74)),16))},zW(h6n,b6n,1333),sDn(1335,1,y1n,Zd),uZn.Mb=function(n){return DN(this.a,uG(n,27))},zW(h6n,w6n,1335),sDn(1336,1,{},Qt),uZn.Kb=function(n){return new fX(null,new h3(FJ(uG(n,74)),16))},zW(h6n,"ElkGraphImporter/lambda$5$Type",1336),sDn(1338,1,y1n,ng),uZn.Mb=function(n){return xN(this.a,uG(n,27))},zW(h6n,"ElkGraphImporter/lambda$7$Type",1338),sDn(1339,1,y1n,Jt),uZn.Mb=function(n){return XY(uG(n,74))},zW(h6n,"ElkGraphImporter/lambda$8$Type",1339),sDn(1297,1,{},Vf),zW(h6n,"ElkGraphLayoutTransferrer",1297),sDn(1298,1,y1n,tg),uZn.Mb=function(n){return IF(this.a,uG(n,18))},zW(h6n,"ElkGraphLayoutTransferrer/lambda$0$Type",1298),sDn(1299,1,QZn,eg),uZn.Cd=function(n){WS(),kD(this.a,uG(n,18))},zW(h6n,"ElkGraphLayoutTransferrer/lambda$1$Type",1299),sDn(1300,1,y1n,ig),uZn.Mb=function(n){return KK(this.a,uG(n,18))},zW(h6n,"ElkGraphLayoutTransferrer/lambda$2$Type",1300),sDn(1301,1,QZn,rg),uZn.Cd=function(n){WS(),kD(this.a,uG(n,18))},zW(h6n,"ElkGraphLayoutTransferrer/lambda$3$Type",1301),sDn(819,1,{},xF),zW(d6n,"BiLinkedHashMultiMap",819),sDn(1550,1,Q4n,Yt),uZn.Kf=function(n,t){Bon(uG(n,36),t)},zW(d6n,"CommentNodeMarginCalculator",1550),sDn(1551,1,{},Zt),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"CommentNodeMarginCalculator/lambda$0$Type",1551),sDn(1552,1,QZn,ne),uZn.Cd=function(n){bXn(uG(n,10))},zW(d6n,"CommentNodeMarginCalculator/lambda$1$Type",1552),sDn(1553,1,Q4n,te),uZn.Kf=function(n,t){WFn(uG(n,36),t)},zW(d6n,"CommentPostprocessor",1553),sDn(1554,1,Q4n,ee),uZn.Kf=function(n,t){yQn(uG(n,36),t)},zW(d6n,"CommentPreprocessor",1554),sDn(1555,1,Q4n,ie),uZn.Kf=function(n,t){KKn(uG(n,36),t)},zW(d6n,"ConstraintsPostprocessor",1555),sDn(1556,1,Q4n,re),uZn.Kf=function(n,t){Csn(uG(n,36),t)},zW(d6n,"EdgeAndLayerConstraintEdgeReverser",1556),sDn(1557,1,Q4n,ce),uZn.Kf=function(n,t){amn(uG(n,36),t)},zW(d6n,"EndLabelPostprocessor",1557),sDn(1558,1,{},ae),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"EndLabelPostprocessor/lambda$0$Type",1558),sDn(1559,1,y1n,oe),uZn.Mb=function(n){return q8(uG(n,10))},zW(d6n,"EndLabelPostprocessor/lambda$1$Type",1559),sDn(1560,1,QZn,ue),uZn.Cd=function(n){_En(uG(n,10))},zW(d6n,"EndLabelPostprocessor/lambda$2$Type",1560),sDn(1561,1,Q4n,se),uZn.Kf=function(n,t){AAn(uG(n,36),t)},zW(d6n,"EndLabelPreprocessor",1561),sDn(1562,1,{},he),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"EndLabelPreprocessor/lambda$0$Type",1562),sDn(1563,1,QZn,NB),uZn.Cd=function(n){oP(this.a,this.b,this.c,uG(n,10))},uZn.a=0,uZn.b=0,uZn.c=!1,zW(d6n,"EndLabelPreprocessor/lambda$1$Type",1563),sDn(1564,1,y1n,fe),uZn.Mb=function(n){return xA(oIn(uG(n,72),(jYn(),Xyt)))===xA((Zrn(),cxt))},zW(d6n,"EndLabelPreprocessor/lambda$2$Type",1564),sDn(1565,1,QZn,cg),uZn.Cd=function(n){aq(this.a,uG(n,72))},zW(d6n,"EndLabelPreprocessor/lambda$3$Type",1565),sDn(1566,1,y1n,le),uZn.Mb=function(n){return xA(oIn(uG(n,72),(jYn(),Xyt)))===xA((Zrn(),rxt))},zW(d6n,"EndLabelPreprocessor/lambda$4$Type",1566),sDn(1567,1,QZn,ag),uZn.Cd=function(n){aq(this.a,uG(n,72))},zW(d6n,"EndLabelPreprocessor/lambda$5$Type",1567),sDn(1615,1,Q4n,_f),uZn.Kf=function(n,t){Ddn(uG(n,36),t)},zW(d6n,"EndLabelSorter",1615),sDn(1616,1,b2n,be),uZn.Ne=function(n,t){return okn(uG(n,466),uG(t,466))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"EndLabelSorter/1",1616),sDn(466,1,{466:1},oZ),zW(d6n,"EndLabelSorter/LabelGroup",466),sDn(1617,1,{},we),uZn.Kb=function(n){return VS(),new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"EndLabelSorter/lambda$0$Type",1617),sDn(1618,1,y1n,de),uZn.Mb=function(n){return VS(),uG(n,10).k==(zIn(),dbt)},zW(d6n,"EndLabelSorter/lambda$1$Type",1618),sDn(1619,1,QZn,ge),uZn.Cd=function(n){VIn(uG(n,10))},zW(d6n,"EndLabelSorter/lambda$2$Type",1619),sDn(1620,1,y1n,pe),uZn.Mb=function(n){return VS(),xA(oIn(uG(n,72),(jYn(),Xyt)))===xA((Zrn(),rxt))},zW(d6n,"EndLabelSorter/lambda$3$Type",1620),sDn(1621,1,y1n,me),uZn.Mb=function(n){return VS(),xA(oIn(uG(n,72),(jYn(),Xyt)))===xA((Zrn(),cxt))},zW(d6n,"EndLabelSorter/lambda$4$Type",1621),sDn(1568,1,Q4n,ve),uZn.Kf=function(n,t){qXn(this,uG(n,36))},uZn.b=0,uZn.c=0,zW(d6n,"FinalSplineBendpointsCalculator",1568),sDn(1569,1,{},ke),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"FinalSplineBendpointsCalculator/lambda$0$Type",1569),sDn(1570,1,{},ye),uZn.Kb=function(n){return new fX(null,new LW(new Fz(ix(Xgn(uG(n,10)).a.Kc(),new h))))},zW(d6n,"FinalSplineBendpointsCalculator/lambda$1$Type",1570),sDn(1571,1,y1n,Me),uZn.Mb=function(n){return!v9(uG(n,18))},zW(d6n,"FinalSplineBendpointsCalculator/lambda$2$Type",1571),sDn(1572,1,y1n,Te),uZn.Mb=function(n){return vR(uG(n,18),(GYn(),Tmt))},zW(d6n,"FinalSplineBendpointsCalculator/lambda$3$Type",1572),sDn(1573,1,QZn,og),uZn.Cd=function(n){ZHn(this.a,uG(n,131))},zW(d6n,"FinalSplineBendpointsCalculator/lambda$4$Type",1573),sDn(1574,1,QZn,je),uZn.Cd=function(n){_An(uG(n,18).a)},zW(d6n,"FinalSplineBendpointsCalculator/lambda$5$Type",1574),sDn(803,1,Q4n,ug),uZn.Kf=function(n,t){fVn(this,uG(n,36),t)},zW(d6n,"GraphTransformer",803),sDn(517,22,{3:1,34:1,22:1,517:1},PC);var Lbt,Nbt,$bt,Dbt=_cn(d6n,"GraphTransformer/Mode",517,Oat,f1,zH);sDn(1575,1,Q4n,Ee),uZn.Kf=function(n,t){wRn(uG(n,36),t)},zW(d6n,"HierarchicalNodeResizingProcessor",1575),sDn(1576,1,Q4n,Se),uZn.Kf=function(n,t){don(uG(n,36),t)},zW(d6n,"HierarchicalPortConstraintProcessor",1576),sDn(1577,1,b2n,Pe),uZn.Ne=function(n,t){return wyn(uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"HierarchicalPortConstraintProcessor/NodeComparator",1577),sDn(1578,1,Q4n,Ce),uZn.Kf=function(n,t){HGn(uG(n,36),t)},zW(d6n,"HierarchicalPortDummySizeProcessor",1578),sDn(1579,1,Q4n,Ie),uZn.Kf=function(n,t){z_n(this,uG(n,36),t)},uZn.a=0,zW(d6n,"HierarchicalPortOrthogonalEdgeRouter",1579),sDn(1580,1,b2n,Oe),uZn.Ne=function(n,t){return Ox(uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"HierarchicalPortOrthogonalEdgeRouter/1",1580),sDn(1581,1,b2n,Ae),uZn.Ne=function(n,t){return Dtn(uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"HierarchicalPortOrthogonalEdgeRouter/2",1581),sDn(1582,1,Q4n,Le),uZn.Kf=function(n,t){tIn(uG(n,36),t)},zW(d6n,"HierarchicalPortPositionProcessor",1582),sDn(1583,1,Q4n,Wf),uZn.Kf=function(n,t){SJn(this,uG(n,36))},uZn.a=0,uZn.c=0,zW(d6n,"HighDegreeNodeLayeringProcessor",1583),sDn(580,1,{580:1},Ne),uZn.b=-1,uZn.d=-1,zW(d6n,"HighDegreeNodeLayeringProcessor/HighDegreeNodeInformation",580),sDn(1584,1,{},$e),uZn.Kb=function(n){return HB(),qgn(uG(n,10))},uZn.Fb=function(n){return this===n},zW(d6n,"HighDegreeNodeLayeringProcessor/lambda$0$Type",1584),sDn(1585,1,{},De),uZn.Kb=function(n){return HB(),Xgn(uG(n,10))},uZn.Fb=function(n){return this===n},zW(d6n,"HighDegreeNodeLayeringProcessor/lambda$1$Type",1585),sDn(1591,1,Q4n,xe),uZn.Kf=function(n,t){TGn(this,uG(n,36),t)},zW(d6n,"HyperedgeDummyMerger",1591),sDn(804,1,{},xB),uZn.a=!1,uZn.b=!1,uZn.c=!1,zW(d6n,"HyperedgeDummyMerger/MergeState",804),sDn(1592,1,{},Re),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"HyperedgeDummyMerger/lambda$0$Type",1592),sDn(1593,1,{},Ke),uZn.Kb=function(n){return new fX(null,new h3(uG(n,10).j,16))},zW(d6n,"HyperedgeDummyMerger/lambda$1$Type",1593),sDn(1594,1,QZn,Fe),uZn.Cd=function(n){uG(n,12).p=-1},zW(d6n,"HyperedgeDummyMerger/lambda$2$Type",1594),sDn(1595,1,Q4n,_e),uZn.Kf=function(n,t){kGn(uG(n,36),t)},zW(d6n,"HypernodesProcessor",1595),sDn(1596,1,Q4n,Be),uZn.Kf=function(n,t){_Gn(uG(n,36),t)},zW(d6n,"InLayerConstraintProcessor",1596),sDn(1597,1,Q4n,He),uZn.Kf=function(n,t){Nun(uG(n,36),t)},zW(d6n,"InnermostNodeMarginCalculator",1597),sDn(1598,1,Q4n,Ue),uZn.Kf=function(n,t){gQn(this,uG(n,36))},uZn.a=T0n,uZn.b=T0n,uZn.c=M0n,uZn.d=M0n;var xbt,Rbt,Kbt,Fbt,_bt,Bbt,Hbt,Ubt,Gbt,qbt,Xbt,zbt,Vbt,Wbt,Qbt,Jbt,Ybt,Zbt,nwt,twt,ewt,iwt,rwt,cwt,awt,owt,uwt,swt,hwt,fwt,lwt,bwt,wwt,dwt,gwt,pwt,mwt,vwt,kwt,ywt,Mwt,Twt,jwt,Ewt,Swt,Pwt,Cwt,Iwt,Owt,Awt,Lwt,Nwt,$wt,Dwt,xwt,Rwt,Kwt,Fwt=zW(d6n,"InteractiveExternalPortPositioner",1598);sDn(1599,1,{},Ge),uZn.Kb=function(n){return uG(n,18).d.i},uZn.Fb=function(n){return this===n},zW(d6n,"InteractiveExternalPortPositioner/lambda$0$Type",1599),sDn(1600,1,{},sg),uZn.Kb=function(n){return Lx(this.a,pK(n))},uZn.Fb=function(n){return this===n},zW(d6n,"InteractiveExternalPortPositioner/lambda$1$Type",1600),sDn(1601,1,{},qe),uZn.Kb=function(n){return uG(n,18).c.i},uZn.Fb=function(n){return this===n},zW(d6n,"InteractiveExternalPortPositioner/lambda$2$Type",1601),sDn(1602,1,{},hg),uZn.Kb=function(n){return Nx(this.a,pK(n))},uZn.Fb=function(n){return this===n},zW(d6n,"InteractiveExternalPortPositioner/lambda$3$Type",1602),sDn(1603,1,{},fg),uZn.Kb=function(n){return XF(this.a,pK(n))},uZn.Fb=function(n){return this===n},zW(d6n,"InteractiveExternalPortPositioner/lambda$4$Type",1603),sDn(1604,1,{},lg),uZn.Kb=function(n){return zF(this.a,pK(n))},uZn.Fb=function(n){return this===n},zW(d6n,"InteractiveExternalPortPositioner/lambda$5$Type",1604),sDn(81,22,{3:1,34:1,22:1,81:1,196:1},CC),uZn.dg=function(){switch(this.g){case 15:return new fc;case 22:return new lc;case 47:return new dc;case 28:case 35:return new ei;case 32:return new Yt;case 42:return new te;case 1:return new ee;case 41:return new ie;case 56:return new ug((Aun(),Obt));case 0:return new ug((Aun(),Ibt));case 2:return new re;case 54:return new ce;case 33:return new se;case 51:return new ve;case 55:return new Ee;case 13:return new Se;case 38:return new Ce;case 44:return new Ie;case 40:return new Le;case 9:return new Wf;case 49:return new Ux;case 37:return new xe;case 43:return new _e;case 27:return new Be;case 30:return new He;case 3:return new Ue;case 18:return new ze;case 29:return new Ve;case 5:return new Qf;case 50:return new Xe;case 34:return new Jf;case 36:return new ii;case 52:return new _f;case 11:return new ri;case 7:return new Yf;case 39:return new ci;case 45:return new ai;case 16:return new oi;case 10:return new RI;case 48:return new fi;case 21:return new li;case 23:return new zy((ean(),BEt));case 8:return new wi;case 12:return new gi;case 4:return new pi;case 19:return new rl;case 17:return new Pi;case 53:return new Ci;case 6:return new Bi;case 25:return new jk;case 46:return new $i;case 31:return new _F;case 14:return new Wi;case 26:return new Mc;case 20:return new nr;case 24:return new zy((ean(),HEt));default:throw hv(new vM(v6n+(null!=this.f?this.f:""+this.g)))}};var _wt,Bwt,Hwt,Uwt,Gwt,qwt,Xwt,zwt,Vwt=_cn(d6n,k6n,81,Oat,bKn,XB);sDn(1605,1,Q4n,ze),uZn.Kf=function(n,t){bQn(uG(n,36),t)},zW(d6n,"InvertedPortProcessor",1605),sDn(1606,1,Q4n,Ve),uZn.Kf=function(n,t){xHn(uG(n,36),t)},zW(d6n,"LabelAndNodeSizeProcessor",1606),sDn(1607,1,y1n,We),uZn.Mb=function(n){return uG(n,10).k==(zIn(),dbt)},zW(d6n,"LabelAndNodeSizeProcessor/lambda$0$Type",1607),sDn(1608,1,y1n,Qe),uZn.Mb=function(n){return uG(n,10).k==(zIn(),lbt)},zW(d6n,"LabelAndNodeSizeProcessor/lambda$1$Type",1608),sDn(1609,1,QZn,KB),uZn.Cd=function(n){uP(this.b,this.a,this.c,uG(n,10))},uZn.a=!1,uZn.c=!1,zW(d6n,"LabelAndNodeSizeProcessor/lambda$2$Type",1609),sDn(1610,1,Q4n,Qf),uZn.Kf=function(n,t){EWn(uG(n,36),t)},zW(d6n,"LabelDummyInserter",1610),sDn(1611,1,A2n,Je),uZn.Lb=function(n){return xA(oIn(uG(n,72),(jYn(),Xyt)))===xA((Zrn(),ixt))},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return xA(oIn(uG(n,72),(jYn(),Xyt)))===xA((Zrn(),ixt))},zW(d6n,"LabelDummyInserter/1",1611),sDn(1612,1,Q4n,Xe),uZn.Kf=function(n,t){eWn(uG(n,36),t)},zW(d6n,"LabelDummyRemover",1612),sDn(1613,1,y1n,Ye),uZn.Mb=function(n){return oM(gK(oIn(uG(n,72),(jYn(),qyt))))},zW(d6n,"LabelDummyRemover/lambda$0$Type",1613),sDn(1378,1,Q4n,Jf),uZn.Kf=function(n,t){UVn(this,uG(n,36),t)},uZn.a=null,zW(d6n,"LabelDummySwitcher",1378),sDn(293,1,{293:1},oHn),uZn.c=0,uZn.d=null,uZn.f=0,zW(d6n,"LabelDummySwitcher/LabelDummyInfo",293),sDn(1379,1,{},Ze),uZn.Kb=function(n){return Pun(),new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"LabelDummySwitcher/lambda$0$Type",1379),sDn(1380,1,y1n,ni),uZn.Mb=function(n){return Pun(),uG(n,10).k==(zIn(),bbt)},zW(d6n,"LabelDummySwitcher/lambda$1$Type",1380),sDn(1381,1,{},bg),uZn.Kb=function(n){return FK(this.a,uG(n,10))},zW(d6n,"LabelDummySwitcher/lambda$2$Type",1381),sDn(1382,1,QZn,wg),uZn.Cd=function(n){gQ(this.a,uG(n,293))},zW(d6n,"LabelDummySwitcher/lambda$3$Type",1382),sDn(1383,1,b2n,ti),uZn.Ne=function(n,t){return nV(uG(n,293),uG(t,293))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"LabelDummySwitcher/lambda$4$Type",1383),sDn(802,1,Q4n,ei),uZn.Kf=function(n,t){Dnn(uG(n,36),t)},zW(d6n,"LabelManagementProcessor",802),sDn(1614,1,Q4n,ii),uZn.Kf=function(n,t){jFn(uG(n,36),t)},zW(d6n,"LabelSideSelector",1614),sDn(1622,1,Q4n,ri),uZn.Kf=function(n,t){yqn(uG(n,36),t)},zW(d6n,"LayerConstraintPostprocessor",1622),sDn(1623,1,Q4n,Yf),uZn.Kf=function(n,t){vDn(uG(n,36),t)},zW(d6n,"LayerConstraintPreprocessor",1623),sDn(371,22,{3:1,34:1,22:1,371:1},IC);var Wwt,Qwt,Jwt,Ywt,Zwt,ndt,tdt,edt,idt,rdt,cdt,adt=_cn(d6n,"LayerConstraintPreprocessor/HiddenNodeConnections",371,Oat,G6,zB);sDn(1624,1,Q4n,ci),uZn.Kf=function(n,t){zzn(uG(n,36),t)},zW(d6n,"LayerSizeAndGraphHeightCalculator",1624),sDn(1625,1,Q4n,ai),uZn.Kf=function(n,t){dRn(uG(n,36),t)},zW(d6n,"LongEdgeJoiner",1625),sDn(1626,1,Q4n,oi),uZn.Kf=function(n,t){bzn(uG(n,36),t)},zW(d6n,"LongEdgeSplitter",1626),sDn(1627,1,Q4n,RI),uZn.Kf=function(n,t){VWn(this,uG(n,36),t)},uZn.e=0,uZn.f=0,uZn.j=0,uZn.k=0,uZn.n=0,uZn.o=0,zW(d6n,"NodePromotion",1627),sDn(1628,1,b2n,ui),uZn.Ne=function(n,t){return $ln(uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"NodePromotion/1",1628),sDn(1629,1,b2n,si),uZn.Ne=function(n,t){return Dln(uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"NodePromotion/2",1629),sDn(1630,1,{},hi),uZn.Kb=function(n){return uG(n,42),UB(),qx(),!0},uZn.Fb=function(n){return this===n},zW(d6n,"NodePromotion/lambda$0$Type",1630),sDn(1631,1,{},mg),uZn.Kb=function(n){return P0(this.a,uG(n,42))},uZn.Fb=function(n){return this===n},uZn.a=0,zW(d6n,"NodePromotion/lambda$1$Type",1631),sDn(1632,1,{},vg),uZn.Kb=function(n){return S0(this.a,uG(n,42))},uZn.Fb=function(n){return this===n},uZn.a=0,zW(d6n,"NodePromotion/lambda$2$Type",1632),sDn(1633,1,Q4n,fi),uZn.Kf=function(n,t){wJn(uG(n,36),t)},zW(d6n,"NorthSouthPortPostprocessor",1633),sDn(1634,1,Q4n,li),uZn.Kf=function(n,t){FQn(uG(n,36),t)},zW(d6n,"NorthSouthPortPreprocessor",1634),sDn(1635,1,b2n,bi),uZn.Ne=function(n,t){return Qsn(uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"NorthSouthPortPreprocessor/lambda$0$Type",1635),sDn(1636,1,Q4n,wi),uZn.Kf=function(n,t){UUn(uG(n,36),t)},zW(d6n,"PartitionMidprocessor",1636),sDn(1637,1,y1n,di),uZn.Mb=function(n){return vR(uG(n,10),(jYn(),UMt))},zW(d6n,"PartitionMidprocessor/lambda$0$Type",1637),sDn(1638,1,QZn,kg),uZn.Cd=function(n){zY(this.a,uG(n,10))},zW(d6n,"PartitionMidprocessor/lambda$1$Type",1638),sDn(1639,1,Q4n,gi),uZn.Kf=function(n,t){JRn(uG(n,36),t)},zW(d6n,"PartitionPostprocessor",1639),sDn(1640,1,Q4n,pi),uZn.Kf=function(n,t){M$n(uG(n,36),t)},zW(d6n,"PartitionPreprocessor",1640),sDn(1641,1,y1n,mi),uZn.Mb=function(n){return vR(uG(n,10),(jYn(),UMt))},zW(d6n,"PartitionPreprocessor/lambda$0$Type",1641),sDn(1642,1,{},vi),uZn.Kb=function(n){return new fX(null,new LW(new Fz(ix(Xgn(uG(n,10)).a.Kc(),new h))))},zW(d6n,"PartitionPreprocessor/lambda$1$Type",1642),sDn(1643,1,y1n,ki),uZn.Mb=function(n){return pkn(uG(n,18))},zW(d6n,"PartitionPreprocessor/lambda$2$Type",1643),sDn(1644,1,QZn,yi),uZn.Cd=function(n){rfn(uG(n,18))},zW(d6n,"PartitionPreprocessor/lambda$3$Type",1644),sDn(1645,1,Q4n,rl),uZn.Kf=function(n,t){wUn(uG(n,36),t)},zW(d6n,"PortListSorter",1645),sDn(1648,1,b2n,Mi),uZn.Ne=function(n,t){return Q5(uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"PortListSorter/lambda$0$Type",1648),sDn(1650,1,b2n,Ti),uZn.Ne=function(n,t){return hGn(uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"PortListSorter/lambda$1$Type",1650),sDn(1646,1,{},ji),uZn.Kb=function(n){return Cln(),uG(n,12).e},zW(d6n,"PortListSorter/lambda$2$Type",1646),sDn(1647,1,{},Ei),uZn.Kb=function(n){return Cln(),uG(n,12).g},zW(d6n,"PortListSorter/lambda$3$Type",1647),sDn(1649,1,b2n,Si),uZn.Ne=function(n,t){return bjn(uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"PortListSorter/lambda$4$Type",1649),sDn(1651,1,Q4n,Pi),uZn.Kf=function(n,t){FDn(uG(n,36),t)},zW(d6n,"PortSideProcessor",1651),sDn(1652,1,Q4n,Ci),uZn.Kf=function(n,t){SBn(uG(n,36),t)},zW(d6n,"ReversedEdgeRestorer",1652),sDn(1657,1,Q4n,jk),uZn.Kf=function(n,t){kTn(this,uG(n,36),t)},zW(d6n,"SelfLoopPortRestorer",1657),sDn(1658,1,{},Ii),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"SelfLoopPortRestorer/lambda$0$Type",1658),sDn(1659,1,y1n,Oi),uZn.Mb=function(n){return uG(n,10).k==(zIn(),dbt)},zW(d6n,"SelfLoopPortRestorer/lambda$1$Type",1659),sDn(1660,1,y1n,Ai),uZn.Mb=function(n){return vR(uG(n,10),(GYn(),vmt))},zW(d6n,"SelfLoopPortRestorer/lambda$2$Type",1660),sDn(1661,1,{},Li),uZn.Kb=function(n){return uG(oIn(uG(n,10),(GYn(),vmt)),337)},zW(d6n,"SelfLoopPortRestorer/lambda$3$Type",1661),sDn(1662,1,QZn,gg),uZn.Cd=function(n){gOn(this.a,uG(n,337))},zW(d6n,"SelfLoopPortRestorer/lambda$4$Type",1662),sDn(805,1,QZn,Ni),uZn.Cd=function(n){BOn(uG(n,105))},zW(d6n,"SelfLoopPortRestorer/lambda$5$Type",805),sDn(1663,1,Q4n,$i),uZn.Kf=function(n,t){oyn(uG(n,36),t)},zW(d6n,"SelfLoopPostProcessor",1663),sDn(1664,1,{},Di),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"SelfLoopPostProcessor/lambda$0$Type",1664),sDn(1665,1,y1n,xi),uZn.Mb=function(n){return uG(n,10).k==(zIn(),dbt)},zW(d6n,"SelfLoopPostProcessor/lambda$1$Type",1665),sDn(1666,1,y1n,Ri),uZn.Mb=function(n){return vR(uG(n,10),(GYn(),vmt))},zW(d6n,"SelfLoopPostProcessor/lambda$2$Type",1666),sDn(1667,1,QZn,Ki),uZn.Cd=function(n){gSn(uG(n,10))},zW(d6n,"SelfLoopPostProcessor/lambda$3$Type",1667),sDn(1668,1,{},Fi),uZn.Kb=function(n){return new fX(null,new h3(uG(n,105).f,1))},zW(d6n,"SelfLoopPostProcessor/lambda$4$Type",1668),sDn(1669,1,QZn,dg),uZn.Cd=function(n){V6(this.a,uG(n,340))},zW(d6n,"SelfLoopPostProcessor/lambda$5$Type",1669),sDn(1670,1,y1n,_i),uZn.Mb=function(n){return!!uG(n,105).i},zW(d6n,"SelfLoopPostProcessor/lambda$6$Type",1670),sDn(1671,1,QZn,pg),uZn.Cd=function(n){eM(this.a,uG(n,105))},zW(d6n,"SelfLoopPostProcessor/lambda$7$Type",1671),sDn(1653,1,Q4n,Bi),uZn.Kf=function(n,t){Fxn(uG(n,36),t)},zW(d6n,"SelfLoopPreProcessor",1653),sDn(1654,1,{},Hi),uZn.Kb=function(n){return new fX(null,new h3(uG(n,105).f,1))},zW(d6n,"SelfLoopPreProcessor/lambda$0$Type",1654),sDn(1655,1,{},Ui),uZn.Kb=function(n){return uG(n,340).a},zW(d6n,"SelfLoopPreProcessor/lambda$1$Type",1655),sDn(1656,1,QZn,Gi),uZn.Cd=function(n){v$(uG(n,18))},zW(d6n,"SelfLoopPreProcessor/lambda$2$Type",1656),sDn(1672,1,Q4n,_F),uZn.Kf=function(n,t){xIn(this,uG(n,36),t)},zW(d6n,"SelfLoopRouter",1672),sDn(1673,1,{},qi),uZn.Kb=function(n){return new fX(null,new h3(uG(n,30).a,16))},zW(d6n,"SelfLoopRouter/lambda$0$Type",1673),sDn(1674,1,y1n,Xi),uZn.Mb=function(n){return uG(n,10).k==(zIn(),dbt)},zW(d6n,"SelfLoopRouter/lambda$1$Type",1674),sDn(1675,1,y1n,zi),uZn.Mb=function(n){return vR(uG(n,10),(GYn(),vmt))},zW(d6n,"SelfLoopRouter/lambda$2$Type",1675),sDn(1676,1,{},Vi),uZn.Kb=function(n){return uG(oIn(uG(n,10),(GYn(),vmt)),337)},zW(d6n,"SelfLoopRouter/lambda$3$Type",1676),sDn(1677,1,QZn,OC),uZn.Cd=function(n){lY(this.a,this.b,uG(n,337))},zW(d6n,"SelfLoopRouter/lambda$4$Type",1677),sDn(1678,1,Q4n,Wi),uZn.Kf=function(n,t){tFn(uG(n,36),t)},zW(d6n,"SemiInteractiveCrossMinProcessor",1678),sDn(1679,1,y1n,Qi),uZn.Mb=function(n){return uG(n,10).k==(zIn(),dbt)},zW(d6n,"SemiInteractiveCrossMinProcessor/lambda$0$Type",1679),sDn(1680,1,y1n,Ji),uZn.Mb=function(n){return MX(uG(n,10))._b((jYn(),rTt))},zW(d6n,"SemiInteractiveCrossMinProcessor/lambda$1$Type",1680),sDn(1681,1,b2n,Yi),uZn.Ne=function(n,t){return Eon(uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(d6n,"SemiInteractiveCrossMinProcessor/lambda$2$Type",1681),sDn(1682,1,{},Zi),uZn.Ve=function(n,t){return VY(uG(n,10),uG(t,10))},zW(d6n,"SemiInteractiveCrossMinProcessor/lambda$3$Type",1682),sDn(1684,1,Q4n,nr),uZn.Kf=function(n,t){MXn(uG(n,36),t)},zW(d6n,"SortByInputModelProcessor",1684),sDn(1685,1,y1n,tr),uZn.Mb=function(n){return 0!=uG(n,12).g.c.length},zW(d6n,"SortByInputModelProcessor/lambda$0$Type",1685),sDn(1686,1,QZn,yg),uZn.Cd=function(n){ZOn(this.a,uG(n,12))},zW(d6n,"SortByInputModelProcessor/lambda$1$Type",1686),sDn(1759,817,{},Kon),uZn.df=function(n){var t,e,i,r;switch(this.c=n,this.a.g){case 2:t=new Zm,kS(JJ(new fX(null,new h3(this.c.a.b,16)),new dr),new BC(this,t)),QAn(this,new ir),Prn(t,new rr),t.c.length=0,kS(JJ(new fX(null,new h3(this.c.a.b,16)),new cr),new Tg(t)),QAn(this,new ar),Prn(t,new or),t.c.length=0,e=w$(Tun(ZJ(new fX(null,new h3(this.c.a.b,16)),new jg(this))),new ur),kS(new fX(null,new h3(this.c.a.a,16)),new NC(e,t)),QAn(this,new hr),Prn(t,new fr),t.c.length=0;break;case 3:i=new Zm,QAn(this,new er),r=w$(Tun(ZJ(new fX(null,new h3(this.c.a.b,16)),new Mg(this))),new sr),kS(JJ(new fX(null,new h3(this.c.a.b,16)),new lr),new DC(r,i)),QAn(this,new br),Prn(i,new wr),i.c.length=0;break;default:throw hv(new Hv)}},uZn.b=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation",1759),sDn(1760,1,A2n,er),uZn.Lb=function(n){return F$(uG(n,60).g,154)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return F$(uG(n,60).g,154)},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$0$Type",1760),sDn(1761,1,{},Mg),uZn.Ye=function(n){return $Ln(this.a,uG(n,60))},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$1$Type",1761),sDn(1769,1,M1n,AC),uZn.de=function(){TEn(this.a,this.b,-1)},uZn.b=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$10$Type",1769),sDn(1771,1,A2n,ir),uZn.Lb=function(n){return F$(uG(n,60).g,154)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return F$(uG(n,60).g,154)},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$11$Type",1771),sDn(1772,1,QZn,rr),uZn.Cd=function(n){uG(n,380).de()},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$12$Type",1772),sDn(1773,1,y1n,cr),uZn.Mb=function(n){return F$(uG(n,60).g,10)},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$13$Type",1773),sDn(1775,1,QZn,Tg),uZn.Cd=function(n){tpn(this.a,uG(n,60))},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$14$Type",1775),sDn(1774,1,M1n,xC),uZn.de=function(){TEn(this.b,this.a,-1)},uZn.a=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$15$Type",1774),sDn(1776,1,A2n,ar),uZn.Lb=function(n){return F$(uG(n,60).g,10)},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return F$(uG(n,60).g,10)},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$16$Type",1776),sDn(1777,1,QZn,or),uZn.Cd=function(n){uG(n,380).de()},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$17$Type",1777),sDn(1778,1,{},jg),uZn.Ye=function(n){return DLn(this.a,uG(n,60))},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$18$Type",1778),sDn(1779,1,{},ur),uZn.We=function(){return 0},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$19$Type",1779),sDn(1762,1,{},sr),uZn.We=function(){return 0},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$2$Type",1762),sDn(1781,1,QZn,NC),uZn.Cd=function(n){uz(this.a,this.b,uG(n,316))},uZn.a=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$20$Type",1781),sDn(1780,1,M1n,$C),uZn.de=function(){HDn(this.a,this.b,-1)},uZn.b=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$21$Type",1780),sDn(1782,1,A2n,hr),uZn.Lb=function(n){return uG(n,60),!0},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return uG(n,60),!0},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$22$Type",1782),sDn(1783,1,QZn,fr),uZn.Cd=function(n){uG(n,380).de()},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$23$Type",1783),sDn(1763,1,y1n,lr),uZn.Mb=function(n){return F$(uG(n,60).g,10)},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$3$Type",1763),sDn(1765,1,QZn,DC),uZn.Cd=function(n){sz(this.a,this.b,uG(n,60))},uZn.a=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$4$Type",1765),sDn(1764,1,M1n,RC),uZn.de=function(){TEn(this.b,this.a,-1)},uZn.a=0,zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$5$Type",1764),sDn(1766,1,A2n,br),uZn.Lb=function(n){return uG(n,60),!0},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return uG(n,60),!0},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$6$Type",1766),sDn(1767,1,QZn,wr),uZn.Cd=function(n){uG(n,380).de()},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$7$Type",1767),sDn(1768,1,y1n,dr),uZn.Mb=function(n){return F$(uG(n,60).g,154)},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$8$Type",1768),sDn(1770,1,QZn,BC),uZn.Cd=function(n){mrn(this.a,this.b,uG(n,60))},zW(E6n,"EdgeAwareScanlineConstraintCalculation/lambda$9$Type",1770),sDn(1586,1,Q4n,Ux),uZn.Kf=function(n,t){Mzn(this,uG(n,36),t)},zW(E6n,"HorizontalGraphCompactor",1586),sDn(1587,1,{},Eg),uZn.ff=function(n,t){var e,i;return $en(n,t)?0:(e=z4(n),i=z4(t),e&&e.k==(zIn(),lbt)||i&&i.k==(zIn(),lbt)?0:_x(uG(oIn(this.a.a,(GYn(),kmt)),312),e?e.k:(zIn(),wbt),i?i.k:(zIn(),wbt)))},uZn.gf=function(n,t){var e,i;return $en(n,t)?1:(e=z4(n),i=z4(t),Bx(uG(oIn(this.a.a,(GYn(),kmt)),312),e?e.k:(zIn(),wbt),i?i.k:(zIn(),wbt)))},zW(E6n,"HorizontalGraphCompactor/1",1587),sDn(1588,1,{},gr),uZn.ef=function(n,t){return JS(),0==n.a.i},zW(E6n,"HorizontalGraphCompactor/lambda$0$Type",1588),sDn(1589,1,{},Sg),uZn.ef=function(n,t){return ZY(this.a,n,t)},zW(E6n,"HorizontalGraphCompactor/lambda$1$Type",1589),sDn(1730,1,{},Sen),zW(E6n,"LGraphToCGraphTransformer",1730),sDn(1738,1,y1n,pr),uZn.Mb=function(n){return null!=n},zW(E6n,"LGraphToCGraphTransformer/0methodref$nonNull$Type",1738),sDn(1731,1,{},mr),uZn.Kb=function(n){return GB(),cpn(oIn(uG(uG(n,60).g,10),(GYn(),rmt)))},zW(E6n,"LGraphToCGraphTransformer/lambda$0$Type",1731),sDn(1732,1,{},vr),uZn.Kb=function(n){return GB(),_wn(uG(uG(n,60).g,154))},zW(E6n,"LGraphToCGraphTransformer/lambda$1$Type",1732),sDn(1741,1,y1n,kr),uZn.Mb=function(n){return GB(),F$(uG(n,60).g,10)},zW(E6n,"LGraphToCGraphTransformer/lambda$10$Type",1741),sDn(1742,1,QZn,yr),uZn.Cd=function(n){jZ(uG(n,60))},zW(E6n,"LGraphToCGraphTransformer/lambda$11$Type",1742),sDn(1743,1,y1n,Mr),uZn.Mb=function(n){return GB(),F$(uG(n,60).g,154)},zW(E6n,"LGraphToCGraphTransformer/lambda$12$Type",1743),sDn(1747,1,QZn,Tr),uZn.Cd=function(n){Fwn(uG(n,60))},zW(E6n,"LGraphToCGraphTransformer/lambda$13$Type",1747),sDn(1744,1,QZn,Pg),uZn.Cd=function(n){WL(this.a,uG(n,8))},uZn.a=0,zW(E6n,"LGraphToCGraphTransformer/lambda$14$Type",1744),sDn(1745,1,QZn,Cg),uZn.Cd=function(n){JL(this.a,uG(n,116))},uZn.a=0,zW(E6n,"LGraphToCGraphTransformer/lambda$15$Type",1745),sDn(1746,1,QZn,Ig),uZn.Cd=function(n){QL(this.a,uG(n,8))},uZn.a=0,zW(E6n,"LGraphToCGraphTransformer/lambda$16$Type",1746),sDn(1748,1,{},jr),uZn.Kb=function(n){return GB(),new fX(null,new LW(new Fz(ix(Xgn(uG(n,10)).a.Kc(),new h))))},zW(E6n,"LGraphToCGraphTransformer/lambda$17$Type",1748),sDn(1749,1,y1n,Er),uZn.Mb=function(n){return GB(),v9(uG(n,18))},zW(E6n,"LGraphToCGraphTransformer/lambda$18$Type",1749),sDn(1750,1,QZn,Og),uZn.Cd=function(n){fin(this.a,uG(n,18))},zW(E6n,"LGraphToCGraphTransformer/lambda$19$Type",1750),sDn(1734,1,QZn,Ag),uZn.Cd=function(n){Q3(this.a,uG(n,154))},zW(E6n,"LGraphToCGraphTransformer/lambda$2$Type",1734),sDn(1751,1,{},Sr),uZn.Kb=function(n){return GB(),new fX(null,new h3(uG(n,30).a,16))},zW(E6n,"LGraphToCGraphTransformer/lambda$20$Type",1751),sDn(1752,1,{},Pr),uZn.Kb=function(n){return GB(),new fX(null,new LW(new Fz(ix(Xgn(uG(n,10)).a.Kc(),new h))))},zW(E6n,"LGraphToCGraphTransformer/lambda$21$Type",1752),sDn(1753,1,{},Cr),uZn.Kb=function(n){return GB(),uG(oIn(uG(n,18),(GYn(),Tmt)),15)},zW(E6n,"LGraphToCGraphTransformer/lambda$22$Type",1753),sDn(1754,1,y1n,Ir),uZn.Mb=function(n){return Hx(uG(n,15))},zW(E6n,"LGraphToCGraphTransformer/lambda$23$Type",1754),sDn(1755,1,QZn,Lg),uZn.Cd=function(n){pLn(this.a,uG(n,15))},zW(E6n,"LGraphToCGraphTransformer/lambda$24$Type",1755),sDn(1733,1,QZn,HC),uZn.Cd=function(n){P5(this.a,this.b,uG(n,154))},zW(E6n,"LGraphToCGraphTransformer/lambda$3$Type",1733),sDn(1735,1,{},Or),uZn.Kb=function(n){return GB(),new fX(null,new h3(uG(n,30).a,16))},zW(E6n,"LGraphToCGraphTransformer/lambda$4$Type",1735),sDn(1736,1,{},Ar),uZn.Kb=function(n){return GB(),new fX(null,new LW(new Fz(ix(Xgn(uG(n,10)).a.Kc(),new h))))},zW(E6n,"LGraphToCGraphTransformer/lambda$5$Type",1736),sDn(1737,1,{},Lr),uZn.Kb=function(n){return GB(),uG(oIn(uG(n,18),(GYn(),Tmt)),15)},zW(E6n,"LGraphToCGraphTransformer/lambda$6$Type",1737),sDn(1739,1,QZn,Ng),uZn.Cd=function(n){xLn(this.a,uG(n,15))},zW(E6n,"LGraphToCGraphTransformer/lambda$8$Type",1739),sDn(1740,1,QZn,UC),uZn.Cd=function(n){k$(this.a,this.b,uG(n,154))},zW(E6n,"LGraphToCGraphTransformer/lambda$9$Type",1740),sDn(1729,1,{},Nr),uZn.cf=function(n){var t,e,i,r,c;for(this.a=n,this.d=new ak,this.c=Inn(Tst,EZn,125,this.a.a.a.c.length,0,1),this.b=0,e=new Ww(this.a.a.a);e.a=g&&(kD(a,xwn(f)),v=e.Math.max(v,k[f-1]-l),u+=d,p+=k[f-1]-p,l=k[f-1],d=s[f]),d=e.Math.max(d,s[f]),++f;u+=d}(w=e.Math.min(1/v,1/t.b/u))>r&&(r=w,i=a)}return i},uZn.pg=function(){return!1},zW(N6n,"MSDCutIndexHeuristic",816),sDn(1683,1,Q4n,Mc),uZn.Kf=function(n,t){Cqn(uG(n,36),t)},zW(N6n,"SingleEdgeGraphWrapper",1683),sDn(232,22,{3:1,34:1,22:1,232:1},QC);var zdt,Vdt,Wdt,Qdt=_cn($6n,"CenterEdgeLabelPlacementStrategy",232,Oat,znn,JB);sDn(431,22,{3:1,34:1,22:1,431:1},WC);var Jdt,Ydt,Zdt,ngt,tgt=_cn($6n,"ConstraintCalculationStrategy",431,Oat,w1,YB);sDn(322,22,{3:1,34:1,22:1,322:1,188:1,196:1},JC),uZn.dg=function(){return ZLn(this)},uZn.qg=function(){return ZLn(this)};var egt,igt,rgt,cgt,agt=_cn($6n,"CrossingMinimizationStrategy",322,Oat,B2,ZB);sDn(351,22,{3:1,34:1,22:1,351:1},YC);var ogt,ugt,sgt,hgt,fgt,lgt,bgt=_cn($6n,"CuttingStrategy",351,Oat,H2,nH);sDn(348,22,{3:1,34:1,22:1,348:1,188:1,196:1},ZC),uZn.dg=function(){return ODn(this)},uZn.qg=function(){return ODn(this)};var wgt,dgt,ggt,pgt=_cn($6n,"CycleBreakingStrategy",348,Oat,h9,tH);sDn(428,22,{3:1,34:1,22:1,428:1},nI);var mgt,vgt,kgt,ygt,Mgt=_cn($6n,"DirectionCongruency",428,Oat,b1,eH);sDn(460,22,{3:1,34:1,22:1,460:1},tI);var Tgt,jgt,Egt,Sgt,Pgt,Cgt,Igt,Ogt=_cn($6n,"EdgeConstraint",460,Oat,U2,sH);sDn(283,22,{3:1,34:1,22:1,283:1},eI);var Agt,Lgt,Ngt,$gt=_cn($6n,"EdgeLabelSideSelection",283,Oat,Gnn,hH);sDn(488,22,{3:1,34:1,22:1,488:1},iI);var Dgt,xgt,Rgt,Kgt,Fgt,_gt,Bgt,Hgt=_cn($6n,"EdgeStraighteningStrategy",488,Oat,y1,fH);sDn(281,22,{3:1,34:1,22:1,281:1},rI);var Ugt,Ggt,qgt,Xgt,zgt,Vgt,Wgt,Qgt=_cn($6n,"FixedAlignment",281,Oat,qnn,uH);sDn(282,22,{3:1,34:1,22:1,282:1},cI);var Jgt,Ygt,Zgt,npt,tpt,ept,ipt,rpt,cpt,apt,opt,upt=_cn($6n,"GraphCompactionStrategy",282,Oat,Xnn,iH);sDn(259,22,{3:1,34:1,22:1,259:1},aI);var spt,hpt,fpt,lpt,bpt=_cn($6n,"GraphProperties",259,Oat,oun,rH);sDn(299,22,{3:1,34:1,22:1,299:1},oI);var wpt,dpt,gpt,ppt,mpt=_cn($6n,"GreedySwitchType",299,Oat,G2,cH);sDn(311,22,{3:1,34:1,22:1,311:1},uI);var vpt,kpt,ypt,Mpt=_cn($6n,"InLayerConstraint",311,Oat,q2,aH);sDn(429,22,{3:1,34:1,22:1,429:1},sI);var Tpt,jpt,Ept,Spt,Ppt,Cpt,Ipt,Opt,Apt,Lpt,Npt,$pt,Dpt,xpt,Rpt,Kpt,Fpt,_pt,Bpt,Hpt,Upt,Gpt,qpt,Xpt,zpt,Vpt,Wpt,Qpt,Jpt,Ypt,Zpt,nmt,tmt,emt,imt,rmt,cmt,amt,omt,umt,smt,hmt,fmt,lmt,bmt,wmt,dmt,gmt,pmt,mmt,vmt,kmt,ymt,Mmt,Tmt,jmt,Emt,Smt,Pmt,Cmt,Imt,Omt,Amt,Lmt,Nmt=_cn($6n,"InteractiveReferencePoint",429,Oat,l1,oH);sDn(171,22,{3:1,34:1,22:1,171:1},hI);var $mt,Dmt,xmt,Rmt,Kmt,Fmt,_mt,Bmt,Hmt,Umt,Gmt,qmt,Xmt,zmt,Vmt,Wmt,Qmt,Jmt,Ymt,Zmt,nvt,tvt,evt,ivt,rvt,cvt,avt,ovt,uvt,svt,hvt,fvt,lvt,bvt,wvt,dvt,gvt,pvt,mvt,vvt,kvt,yvt,Mvt,Tvt,jvt,Evt,Svt,Pvt,Cvt,Ivt,Ovt,Avt,Lvt,Nvt,$vt,Dvt,xvt,Rvt,Kvt,Fvt,_vt,Bvt,Hvt,Uvt,Gvt,qvt,Xvt,zvt,Vvt,Wvt,Qvt,Jvt,Yvt,Zvt,nkt,tkt,ekt,ikt,rkt,ckt,akt,okt,ukt,skt,hkt,fkt,lkt,bkt,wkt,dkt,gkt,pkt,mkt,vkt,kkt,ykt,Mkt,Tkt,jkt,Ekt,Skt,Pkt,Ckt,Ikt,Okt,Akt,Lkt,Nkt,$kt,Dkt,xkt,Rkt,Kkt,Fkt,_kt,Bkt,Hkt,Ukt,Gkt,qkt,Xkt,zkt,Vkt,Wkt,Qkt,Jkt,Ykt,Zkt,nyt,tyt,eyt,iyt,ryt,cyt,ayt,oyt,uyt,syt,hyt,fyt,lyt,byt,wyt,dyt,gyt,pyt,myt,vyt,kyt,yyt,Myt,Tyt,jyt,Eyt,Syt,Pyt,Cyt,Iyt,Oyt,Ayt,Lyt,Nyt,$yt,Dyt,xyt,Ryt,Kyt,Fyt,_yt,Byt,Hyt,Uyt,Gyt,qyt,Xyt,zyt,Vyt,Wyt,Qyt,Jyt,Yyt,Zyt,nMt,tMt,eMt,iMt,rMt,cMt,aMt,oMt,uMt,sMt,hMt,fMt,lMt,bMt,wMt,dMt,gMt,pMt,mMt,vMt,kMt,yMt,MMt,TMt,jMt,EMt,SMt,PMt,CMt,IMt,OMt,AMt,LMt,NMt,$Mt,DMt,xMt,RMt,KMt,FMt,_Mt,BMt,HMt,UMt,GMt,qMt,XMt,zMt,VMt,WMt,QMt,JMt,YMt,ZMt,nTt,tTt,eTt,iTt,rTt,cTt,aTt,oTt,uTt,sTt,hTt,fTt,lTt,bTt,wTt,dTt,gTt,pTt,mTt,vTt,kTt,yTt,MTt,TTt,jTt,ETt,STt,PTt,CTt,ITt,OTt,ATt,LTt,NTt,$Tt,DTt,xTt,RTt,KTt,FTt,_Tt,BTt,HTt,UTt,GTt,qTt,XTt,zTt,VTt,WTt,QTt,JTt,YTt,ZTt,njt,tjt,ejt,ijt,rjt,cjt,ajt=_cn($6n,"LayerConstraint",171,Oat,l9,lH);sDn(859,1,K2n,fl),uZn.hf=function(n){Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,B6n),""),"Direction Congruency"),"Specifies how drawings of the same graph with different layout directions compare to each other: either a natural reading direction is preserved or the drawings are rotated versions of each other."),vvt),(lAn(),gNt)),Mgt),ggn((Rkn(),hNt))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,H6n),""),"Feedback Edges"),"Whether feedback edges should be highlighted by routing around the nodes."),(qx(),!1)),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,U6n),""),"Interactive Reference Point"),"Determines which point of a node is considered by interactive layout phases."),Hvt),gNt),Nmt),ggn(hNt)))),H4(n,U6n,J6n,Gvt),H4(n,U6n,o5n,Uvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,G6n),""),"Merge Edges"),"Edges that have no ports are merged so they touch the connected nodes at the same points. When this option is disabled, one port is created for each edge directly connected to a node. When it is enabled, all such incoming edges share an input port, and all outgoing edges share an output port."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,q6n),""),"Merge Hierarchy-Crossing Edges"),"If hierarchical layout is active, hierarchy-crossing edges use as few hierarchical ports as possible. They are broken by the algorithm, with hierarchical ports inserted as required. Usually, one such port is created for each edge at each hierarchy crossing point. With this option set to true, we try to create as few hierarchical ports as possible in the process. In particular, all edges that form a hyperedge can share a port."),!0),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(VT(JT(QT(YT(qT(GT(WT(XT(zT(new xu,X6n),""),"Allow Non-Flow Ports To Switch Sides"),"Specifies whether non-flow ports may switch sides if their node's port constraints are either FIXED_SIDE or FIXED_ORDER. A non-flow port is a port on a side that is not part of the currently configured layout flow. For instance, given a left-to-right layout direction, north and south ports would be considered non-flow ports. Further note that the underlying criterium whether to switch sides or not solely relies on the minimization of edge crossings. Hence, edge length and other aesthetics criteria are not addressed."),!1),wNt),cot),ggn(fNt)),Uhn(cT($ot,1),zZn,2,6,["org.eclipse.elk.layered.northOrSouthPort"])))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,z6n),""),"Port Sorting Strategy"),"Only relevant for nodes with FIXED_SIDE port constraints. Determines the way a node's ports are distributed on the sides of a node if their order is not prescribed. The option is set on parent nodes."),Pkt),gNt),Jjt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,V6n),""),"Thoroughness"),"How much effort should be spent to produce a nice layout."),xwn(7)),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,W6n),""),"Add Unnecessary Bendpoints"),"Adds bend points even if an edge does not change direction. If true, each long edge dummy will contribute a bend point to its edges and hierarchy-crossing edges will always get a bend point where they cross hierarchy boundaries. By default, bend points are only added where an edge changes direction."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Q6n),""),"Generate Position and Layer IDs"),"If enabled position id and layer id are generated, which are usually only used internally when setting the interactiveLayout option. This option should be specified on the root node."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,J6n),"cycleBreaking"),"Cycle Breaking Strategy"),"Strategy for cycle breaking. Cycle breaking looks for cycles in the graph and determines which edges to reverse to break the cycles. Reversed edges will end up pointing to the opposite direction of regular edges (that is, reversed edges will point left if edges usually point right)."),pvt),gNt),pgt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Y6n),s8n),"Node Layering Strategy"),"Strategy for node layering."),ckt),gNt),fjt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Z6n),s8n),"Layer Constraint"),"Determines a constraint on the placement of the node regarding the layering."),Wvt),gNt),ajt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,n5n),s8n),"Layer Choice Constraint"),"Allows to set a constraint regarding the layer placement of a node. Let i be the value of teh constraint. Assumed the drawing has n layers and i < n. If set to i, it expresses that the node should be placed in i-th layer. Should i>=n be true then the node is placed in the last layer of the drawing. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),null),mNt),dot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,t5n),s8n),"Layer ID"),"Layer identifier that was calculated by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),xwn(-1)),mNt),dot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,e5n),h8n),"Upper Bound On Width [MinWidth Layerer]"),"Defines a loose upper bound on the width of the MinWidth layerer. If set to '-1' multiple values are tested and the best result is selected."),xwn(4)),mNt),dot),ggn(hNt)))),H4(n,e5n,Y6n,Yvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,i5n),h8n),"Upper Layer Estimation Scaling Factor [MinWidth Layerer]"),"Multiplied with Upper Bound On Width for defining an upper bound on the width of layers which haven't been determined yet, but whose maximum width had been (roughly) estimated by the MinWidth algorithm. Compensates for too high estimations. If set to '-1' multiple values are tested and the best result is selected."),xwn(2)),mNt),dot),ggn(hNt)))),H4(n,i5n,Y6n,nkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,r5n),f8n),"Node Promotion Strategy"),"Reduces number of dummy nodes after layering phase (if possible)."),ikt),gNt),Hjt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,c5n),f8n),"Max Node Promotion Iterations"),"Limits the number of iterations for node promotion."),xwn(0)),mNt),dot),ggn(hNt)))),H4(n,c5n,r5n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,a5n),"layering.coffmanGraham"),"Layer Bound"),"The maximum number of nodes allowed per layer."),xwn(vZn)),mNt),dot),ggn(hNt)))),H4(n,a5n,Y6n,Xvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,o5n),l8n),"Crossing Minimization Strategy"),"Strategy for crossing minimization."),dvt),gNt),agt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,u5n),l8n),"Force Node Model Order"),"The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,s5n),l8n),"Hierarchical Sweepiness"),"How likely it is to use cross-hierarchy (1) vs bottom-up (-1)."),.1),dNt),fot),ggn(hNt)))),H4(n,s5n,b8n,ovt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,h5n),l8n),"Semi-Interactive Crossing Minimization"),"Preserves the order of nodes within a layer but still minimizes crossings between edges connecting long edge dummies. Derives the desired order from positions specified by the 'org.eclipse.elk.position' layout option. Requires a crossing minimization strategy that is able to process 'in-layer' constraints."),!1),wNt),cot),ggn(hNt)))),H4(n,h5n,o5n,bvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,f5n),l8n),"In Layer Predecessor of"),"Allows to set a constraint which specifies of which node the current node is the predecessor. If set to 's' then the node is the predecessor of 's' and is in the same layer"),null),kNt),$ot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,l5n),l8n),"In Layer Successor of"),"Allows to set a constraint which specifies of which node the current node is the successor. If set to 's' then the node is the successor of 's' and is in the same layer"),null),kNt),$ot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,b5n),l8n),"Position Choice Constraint"),"Allows to set a constraint regarding the position placement of a node in a layer. Assumed the layer in which the node placed includes n other nodes and i < n. If set to i, it expresses that the node should be placed at the i-th position. Should i>=n be true then the node is placed at the last position in the layer. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),null),mNt),dot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,w5n),l8n),"Position ID"),"Position within a layer that was determined by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),xwn(-1)),mNt),dot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,d5n),w8n),"Greedy Switch Activation Threshold"),"By default it is decided automatically if the greedy switch is activated or not. The decision is based on whether the size of the input graph (without dummy nodes) is smaller than the value of this option. A '0' enforces the activation."),xwn(40)),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,g5n),w8n),"Greedy Switch Crossing Minimization"),"Greedy Switch strategy for crossing minimization. The greedy switch heuristic is executed after the regular crossing minimization as a post-processor. Note that if 'hierarchyHandling' is set to 'INCLUDE_CHILDREN', the 'greedySwitchHierarchical.type' option must be used."),rvt),gNt),mpt),ggn(hNt)))),H4(n,g5n,o5n,cvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,p5n),"crossingMinimization.greedySwitchHierarchical"),"Greedy Switch Crossing Minimization (hierarchical)"),"Activates the greedy switch heuristic in case hierarchical layout is used. The differences to the non-hierarchical case (see 'greedySwitch.type') are: 1) greedy switch is inactive by default, 3) only the option value set on the node at which hierarchical layout starts is relevant, and 2) if it's activated by the user, it properly addresses hierarchy-crossing edges."),nvt),gNt),mpt),ggn(hNt)))),H4(n,p5n,o5n,tvt),H4(n,p5n,b8n,evt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,m5n),d8n),"Node Placement Strategy"),"Strategy for node placement."),Ekt),gNt),xjt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,v5n),d8n),"Favor Straight Edges Over Balancing"),"Favor straight edges over a balanced node placement. The default behavior is determined automatically based on the used 'edgeRouting'. For an orthogonal style it is set to true, for all other styles to false."),wNt),cot),ggn(hNt)))),H4(n,v5n,m5n,dkt),H4(n,v5n,m5n,gkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,k5n),g8n),"BK Edge Straightening"),"Specifies whether the Brandes Koepf node placer tries to increase the number of straight edges at the expense of diagram size. There is a subtle difference to the 'favorStraightEdges' option, which decides whether a balanced placement of the nodes is desired, or not. In bk terms this means combining the four alignments into a single balanced one, or not. This option on the other hand tries to straighten additional edges during the creation of each of the four alignments."),skt),gNt),Hgt),ggn(hNt)))),H4(n,k5n,m5n,hkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,y5n),g8n),"BK Fixed Alignment"),"Tells the BK node placer to use a certain alignment (out of its four) instead of the one producing the smallest height, or the combination of all four."),lkt),gNt),Qgt),ggn(hNt)))),H4(n,y5n,m5n,bkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,M5n),"nodePlacement.linearSegments"),"Linear Segments Deflection Dampening"),"Dampens the movement of nodes to keep the diagram from getting too large."),.3),dNt),fot),ggn(hNt)))),H4(n,M5n,m5n,mkt),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,T5n),"nodePlacement.networkSimplex"),"Node Flexibility"),"Aims at shorter and straighter edges. Two configurations are possible: (a) allow ports to move freely on the side they are assigned to (the order is always defined beforehand), (b) additionally allow to enlarge a node wherever it helps. If this option is not configured for a node, the 'nodeFlexibility.default' value is used, which is specified for the node's parent."),gNt),jjt),ggn(sNt)))),H4(n,T5n,m5n,Tkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,j5n),"nodePlacement.networkSimplex.nodeFlexibility"),"Node Flexibility Default"),"Default value of the 'nodeFlexibility' option for the children of a hierarchical node."),ykt),gNt),jjt),ggn(hNt)))),H4(n,j5n,m5n,Mkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,E5n),p8n),"Self-Loop Distribution"),"Alter the distribution of the loops around the node. It only takes effect for PortConstraints.FREE."),Pvt),gNt),oEt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,S5n),p8n),"Self-Loop Ordering"),"Alter the ordering of the loops they can either be stacked or sequenced. It only takes effect for PortConstraints.FREE."),Ivt),gNt),lEt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,P5n),"edgeRouting.splines"),"Spline Routing Mode"),"Specifies the way control points are assembled for each individual edge. CONSERVATIVE ensures that edges are properly routed around the nodes but feels rather orthogonal at times. SLOPPY uses fewer control points to obtain curvier edge routes but may result in edges overlapping nodes."),Avt),gNt),pEt),ggn(hNt)))),H4(n,P5n,m8n,Lvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,C5n),"edgeRouting.splines.sloppy"),"Sloppy Spline Layer Spacing Factor"),"Spacing factor for routing area between layers when using sloppy spline routing."),.2),dNt),fot),ggn(hNt)))),H4(n,C5n,m8n,$vt),H4(n,C5n,P5n,Dvt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,I5n),"edgeRouting.polyline"),"Sloped Edge Zone Width"),"Width of the strip to the left and to the right of each layer where the polyline edge router is allowed to refrain from ensuring that edges are routed horizontally. This prevents awkward bend points for nodes that extent almost to the edge of their layer."),2),dNt),fot),ggn(hNt)))),H4(n,I5n,m8n,Evt),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,O5n),v8n),"Spacing Base Value"),"An optional base value for all other layout options of the 'spacing' group. It can be used to conveniently alter the overall 'spaciousness' of the drawing. Whenever an explicit value is set for the other layout options, this base value will have no effect. The base value is not inherited, i.e. it must be set for each hierarchical node."),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,A5n),v8n),"Edge Node Between Layers Spacing"),"The spacing to be preserved between nodes and edges that are routed next to the node's layer. For the spacing between nodes and edges that cross the node's layer 'spacing.edgeNode' is used."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,L5n),v8n),"Edge Edge Between Layer Spacing"),"Spacing to be preserved between pairs of edges that are routed between the same pair of layers. Note that 'spacing.edgeEdge' is used for the spacing between pairs of edges crossing the same layer."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,N5n),v8n),"Node Node Between Layers Spacing"),"The spacing to be preserved between any pair of nodes of two adjacent layers. Note that 'spacing.nodeNode' is used for the spacing between nodes within the layer itself."),20),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,$5n),k8n),"Direction Priority"),"Defines how important it is to have a certain edge point into the direction of the overall layout. This option is evaluated during the cycle breaking phase."),xwn(0)),mNt),dot),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,D5n),k8n),"Shortness Priority"),"Defines how important it is to keep an edge as short as possible. This option is evaluated during the layering phase."),xwn(0)),mNt),dot),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,x5n),k8n),"Straightness Priority"),"Defines how important it is to keep an edge straight, i.e. aligned with one of the two axes. This option is evaluated during node placement."),xwn(0)),mNt),dot),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,R5n),y8n),j3n),"Tries to further compact components (disconnected sub-graphs)."),!1),wNt),cot),ggn(hNt)))),H4(n,R5n,h4n,!0),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,K5n),M8n),"Post Compaction Strategy"),T8n),_mt),gNt),upt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,F5n),M8n),"Post Compaction Constraint Calculation"),T8n),Kmt),gNt),tgt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,_5n),j8n),"High Degree Node Treatment"),"Makes room around high degree nodes to place leafs and trees."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,B5n),j8n),"High Degree Node Threshold"),"Whether a node is considered to have a high degree."),xwn(16)),mNt),dot),ggn(hNt)))),H4(n,B5n,_5n,!0),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,H5n),j8n),"High Degree Node Maximum Tree Height"),"Maximum height of a subtree connected to a high degree node to be moved to separate layers."),xwn(5)),mNt),dot),ggn(hNt)))),H4(n,H5n,_5n,!0),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,U5n),E8n),"Graph Wrapping Strategy"),"For certain graphs and certain prescribed drawing areas it may be desirable to split the laid out graph into chunks that are placed side by side. The edges that connect different chunks are 'wrapped' around from the end of one chunk to the start of the other chunk. The points between the chunks are referred to as 'cuts'."),cyt),gNt),xEt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,G5n),E8n),"Additional Wrapped Edges Spacing"),"To visually separate edges that are wrapped from regularly routed edges an additional spacing value can be specified in form of this layout option. The spacing is added to the regular edgeNode spacing."),10),dNt),fot),ggn(hNt)))),H4(n,G5n,U5n,Kkt),H4(n,G5n,U5n,Fkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,q5n),E8n),"Correction Factor for Wrapping"),"At times and for certain types of graphs the executed wrapping may produce results that are consistently biased in the same fashion: either wrapping to often or to rarely. This factor can be used to correct the bias. Internally, it is simply multiplied with the 'aspect ratio' layout option."),1),dNt),fot),ggn(hNt)))),H4(n,q5n,U5n,Bkt),H4(n,q5n,U5n,Hkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,X5n),S8n),"Cutting Strategy"),"The strategy by which the layer indexes are determined at which the layering crumbles into chunks."),Wkt),gNt),bgt),ggn(hNt)))),H4(n,X5n,U5n,Qkt),H4(n,X5n,U5n,Jkt),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,z5n),S8n),"Manually Specified Cuts"),"Allows the user to specify her own cuts for a certain graph."),vNt),yat),ggn(hNt)))),H4(n,z5n,X5n,Gkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,V5n),"wrapping.cutting.msd"),"MSD Freedom"),"The MSD cutting strategy starts with an initial guess on the number of chunks the graph should be split into. The freedom specifies how much the strategy may deviate from this guess. E.g. if an initial number of 3 is computed, a freedom of 1 allows 2, 3, and 4 cuts."),Xkt),mNt),dot),ggn(hNt)))),H4(n,V5n,X5n,zkt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,W5n),P8n),"Validification Strategy"),"When wrapping graphs, one can specify indices that are not allowed as split points. The validification strategy makes sure every computed split point is allowed."),hyt),gNt),MEt),ggn(hNt)))),H4(n,W5n,U5n,fyt),H4(n,W5n,U5n,lyt),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,Q5n),P8n),"Valid Indices for Wrapping"),null),vNt),yat),ggn(hNt)))),H4(n,Q5n,U5n,oyt),H4(n,Q5n,U5n,uyt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,J5n),C8n),"Improve Cuts"),"For general graphs it is important that not too many edges wrap backwards. Thus a compromise between evenly-distributed cuts and the total number of cut edges is sought."),!0),wNt),cot),ggn(hNt)))),H4(n,J5n,U5n,tyt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Y5n),C8n),"Distance Penalty When Improving Cuts"),null),2),dNt),fot),ggn(hNt)))),H4(n,Y5n,U5n,Zkt),H4(n,Y5n,J5n,!0),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Z5n),C8n),"Improve Wrapped Edges"),"The initial wrapping is performed in a very simple way. As a consequence, edges that wrap from one chunk to another may be unnecessarily long. Activating this option tries to shorten such edges."),!0),wNt),cot),ggn(hNt)))),H4(n,Z5n,U5n,iyt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,n8n),I8n),"Edge Label Side Selection"),"Method to decide on edge label sides."),Tvt),gNt),$gt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,t8n),I8n),"Edge Center Label Placement Strategy"),"Determines in which layer center labels of long edges should be placed."),yvt),gNt),Qdt),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[uNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,e8n),O8n),"Consider Model Order"),"Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting."),Qmt),gNt),Xjt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,i8n),O8n),"Consider Port Order"),"If disabled the port order of output ports is derived from the edge order and input ports are ordered by their incoming connections. If enabled all ports are ordered by the port model order."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,r8n),O8n),"No Model Order"),"Set on a node to not set a model order for this node even though it is a real node."),!1),wNt),cot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,c8n),O8n),"Consider Model Order for Components"),"If set to NONE the usual ordering strategy (by cumulative node priority and size of nodes) is used. INSIDE_PORT_SIDES orders the components with external ports only inside the groups with the same port side. FORCE_MODEL_ORDER enforces the mode order on components. This option might produce bad alignments and sub optimal drawings in terms of used area since the ordering should be respected."),Hmt),gNt),abt),ggn(hNt)))),H4(n,c8n,h4n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,a8n),O8n),"Long Edge Ordering Strategy"),"Indicates whether long edges are sorted under, over, or equal to nodes that have no connection to a previous layer in a left-to-right or right-to-left layout. Under and over changes to right and left in a vertical layout."),Xmt),gNt),pjt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,o8n),O8n),"Crossing Counter Node Order Influence"),"Indicates with what percentage (1 for 100%) violations of the node model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal node order. Defaults to no influence (0)."),0),dNt),fot),ggn(hNt)))),H4(n,o8n,e8n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,u8n),O8n),"Crossing Counter Port Order Influence"),"Indicates with what percentage (1 for 100%) violations of the port model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal port order. Defaults to no influence (0)."),0),dNt),fot),ggn(hNt)))),H4(n,u8n,e8n,null),eZn((new ll,n))},zW($6n,"LayeredMetaDataProvider",859),sDn(998,1,K2n,ll),uZn.hf=function(n){eZn(n)},zW($6n,"LayeredOptions",998),sDn(999,1,{},Tc),uZn.sf=function(){return new mk},uZn.tf=function(n){},zW($6n,"LayeredOptions/LayeredFactory",999),sDn(1391,1,{}),uZn.a=0,zW(p9n,"ElkSpacings/AbstractSpacingsBuilder",1391),sDn(792,1391,{},omn),zW($6n,"LayeredSpacings/LayeredSpacingsBuilder",792),sDn(265,22,{3:1,34:1,22:1,265:1,188:1,196:1},fI),uZn.dg=function(){return J_n(this)},uZn.qg=function(){return J_n(this)};var ojt,ujt,sjt,hjt,fjt=_cn($6n,"LayeringStrategy",265,Oat,tan,bH);sDn(390,22,{3:1,34:1,22:1,390:1},lI);var ljt,bjt,wjt,djt,gjt,pjt=_cn($6n,"LongEdgeOrderingStrategy",390,Oat,X2,wH);sDn(203,22,{3:1,34:1,22:1,203:1},bI);var mjt,vjt,kjt,yjt,Mjt,Tjt,jjt=_cn($6n,"NodeFlexibility",203,Oat,q6,dH);sDn(323,22,{3:1,34:1,22:1,323:1,188:1,196:1},wI),uZn.dg=function(){return IDn(this)},uZn.qg=function(){return IDn(this)};var Ejt,Sjt,Pjt,Cjt,Ijt,Ojt,Ajt,Ljt,Njt,$jt,Djt,xjt=_cn($6n,"NodePlacementStrategy",323,Oat,f9,gH);sDn(243,22,{3:1,34:1,22:1,243:1},dI);var Rjt,Kjt,Fjt,_jt,Bjt,Hjt=_cn($6n,"NodePromotionStrategy",243,Oat,uun,pH);sDn(284,22,{3:1,34:1,22:1,284:1},gI);var Ujt,Gjt,qjt,Xjt=_cn($6n,"OrderingStrategy",284,Oat,X6,mH);sDn(430,22,{3:1,34:1,22:1,430:1},pI);var zjt,Vjt,Wjt,Qjt,Jjt=_cn($6n,"PortSortingStrategy",430,Oat,d1,vH);sDn(463,22,{3:1,34:1,22:1,463:1},mI);var Yjt,Zjt,nEt,tEt,eEt=_cn($6n,"PortType",463,Oat,z2,kH);sDn(387,22,{3:1,34:1,22:1,387:1},vI);var iEt,rEt,cEt,aEt,oEt=_cn($6n,"SelfLoopDistributionStrategy",387,Oat,V2,yH);sDn(349,22,{3:1,34:1,22:1,349:1},kI);var uEt,sEt,hEt,fEt,lEt=_cn($6n,"SelfLoopOrderingStrategy",349,Oat,W2,MH);sDn(312,1,{312:1},CVn),zW($6n,"Spacings",312),sDn(350,22,{3:1,34:1,22:1,350:1},yI);var bEt,wEt,dEt,gEt,pEt=_cn($6n,"SplineRoutingMode",350,Oat,Q2,TH);sDn(352,22,{3:1,34:1,22:1,352:1},MI);var mEt,vEt,kEt,yEt,MEt=_cn($6n,"ValidifyStrategy",352,Oat,J2,jH);sDn(388,22,{3:1,34:1,22:1,388:1},TI);var TEt,jEt,EEt,SEt,PEt,CEt,IEt,OEt,AEt,LEt,NEt,$Et,DEt,xEt=_cn($6n,"WrappingStrategy",388,Oat,Y2,EH);sDn(1398,1,y9n,il),uZn.rg=function(n){return uG(n,36),jEt},uZn.Kf=function(n,t){mzn(this,uG(n,36),t)},zW(M9n,"DepthFirstCycleBreaker",1398),sDn(793,1,y9n,ez),uZn.rg=function(n){return uG(n,36),EEt},uZn.Kf=function(n,t){gYn(this,uG(n,36),t)},uZn.sg=function(n){return uG(zq(n,iMn(this.d,n.c.length)),10)},zW(M9n,"GreedyCycleBreaker",793),sDn(1401,793,y9n,tL),uZn.sg=function(n){var t,e,i,r;for(r=null,t=vZn,i=new Ww(n);i.a1&&(oM(gK(oIn(HQ((u3(0,n.c.length),uG(n.c[0],10))),(jYn(),Cyt))))?Axn(n,this.d,uG(this,669)):(hZ(),f$(n,this.d)),xsn(this.e,n))},uZn.lg=function(n,t,e,i){var r,c,a,o,u,s,h;for(t!=vX(e,n.length)&&(c=n[t-(e?1:-1)],v7(this.f,c,e?(can(),Wjt):(can(),Vjt))),r=n[t][0],h=!i||r.k==(zIn(),lbt),s=n7(n[t]),this.vg(s,h,!1,e),a=0,u=new Ww(s);u.a"),n0?j0(this.a,n[t-1],n[t]):!e&&t1&&(oM(gK(oIn(HQ((u3(0,n.c.length),uG(n.c[0],10))),(jYn(),Cyt))))?Axn(n,this.d,this):(hZ(),f$(n,this.d)),oM(gK(oIn(HQ((u3(0,n.c.length),uG(n.c[0],10))),Cyt)))||xsn(this.e,n))},zW(S9n,"ModelOrderBarycenterHeuristic",669),sDn(1866,1,b2n,Zg),uZn.Ne=function(n,t){return TOn(this.a,uG(n,10),uG(t,10))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(S9n,"ModelOrderBarycenterHeuristic/lambda$0$Type",1866),sDn(1423,1,y9n,wl),uZn.rg=function(n){var t;return uG(n,36),Aq(t=aN(XEt),(uIn(),Elt),(zYn(),Cwt)),t},uZn.Kf=function(n,t){jY((uG(n,36),t))},zW(S9n,"NoCrossingMinimizer",1423),sDn(809,413,j9n,rj),uZn.tg=function(n,t,e){var i,r,c,a,o,u,s,h,f,l,b;switch(f=this.g,e.g){case 1:for(r=0,c=0,h=new Ww(n.j);h.a1&&(r.j==(KQn(),kRt)?this.b[n]=!0:r.j==_Rt&&n>0&&(this.b[n-1]=!0))},uZn.f=0,zW(P6n,"AllCrossingsCounter",1861),sDn(595,1,{},Don),uZn.b=0,uZn.d=0,zW(P6n,"BinaryIndexedTree",595),sDn(532,1,{},R_),zW(P6n,"CrossingsCounter",532),sDn(1950,1,b2n,np),uZn.Ne=function(n,t){return wX(this.a,uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(P6n,"CrossingsCounter/lambda$0$Type",1950),sDn(1951,1,b2n,tp),uZn.Ne=function(n,t){return dX(this.a,uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(P6n,"CrossingsCounter/lambda$1$Type",1951),sDn(1952,1,b2n,ep),uZn.Ne=function(n,t){return gX(this.a,uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(P6n,"CrossingsCounter/lambda$2$Type",1952),sDn(1953,1,b2n,ip),uZn.Ne=function(n,t){return pX(this.a,uG(n,12),uG(t,12))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(P6n,"CrossingsCounter/lambda$3$Type",1953),sDn(1954,1,QZn,rp),uZn.Cd=function(n){cen(this.a,uG(n,12))},zW(P6n,"CrossingsCounter/lambda$4$Type",1954),sDn(1955,1,y1n,cp),uZn.Mb=function(n){return NI(this.a,uG(n,12))},zW(P6n,"CrossingsCounter/lambda$5$Type",1955),sDn(1956,1,QZn,ap),uZn.Cd=function(n){MA(this,n)},zW(P6n,"CrossingsCounter/lambda$6$Type",1956),sDn(1957,1,QZn,EI),uZn.Cd=function(n){var t;PU(),A6(this.b,(t=this.a,uG(n,12),t))},zW(P6n,"CrossingsCounter/lambda$7$Type",1957),sDn(839,1,A2n,Nc),uZn.Lb=function(n){return PU(),vR(uG(n,12),(GYn(),lmt))},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return PU(),vR(uG(n,12),(GYn(),lmt))},zW(P6n,"CrossingsCounter/lambda$8$Type",839),sDn(1949,1,{},op),zW(P6n,"HyperedgeCrossingsCounter",1949),sDn(478,1,{34:1,478:1},BF),uZn.Fd=function(n){return _vn(this,uG(n,478))},uZn.b=0,uZn.c=0,uZn.e=0,uZn.f=0;var QEt=zW(P6n,"HyperedgeCrossingsCounter/Hyperedge",478);sDn(374,1,{34:1,374:1},bY),uZn.Fd=function(n){return exn(this,uG(n,374))},uZn.b=0,uZn.c=0;var JEt,YEt,ZEt=zW(P6n,"HyperedgeCrossingsCounter/HyperedgeCorner",374);sDn(531,22,{3:1,34:1,22:1,531:1},SI);var nSt,tSt,eSt,iSt,rSt,cSt=_cn(P6n,"HyperedgeCrossingsCounter/HyperedgeCorner/Type",531,Oat,g1,PH);sDn(1425,1,y9n,dl),uZn.rg=function(n){return uG(oIn(uG(n,36),(GYn(),Hpt)),21).Hc((r_n(),tpt))?tSt:null},uZn.Kf=function(n,t){HEn(this,uG(n,36),t)},zW(P9n,"InteractiveNodePlacer",1425),sDn(1426,1,y9n,gl),uZn.rg=function(n){return uG(oIn(uG(n,36),(GYn(),Hpt)),21).Hc((r_n(),tpt))?eSt:null},uZn.Kf=function(n,t){XMn(this,uG(n,36),t)},zW(P9n,"LinearSegmentsNodePlacer",1426),sDn(261,1,{34:1,261:1},Tk),uZn.Fd=function(n){return CT(this,uG(n,261))},uZn.Fb=function(n){var t;return!!F$(n,261)&&(t=uG(n,261),this.b==t.b)},uZn.Hb=function(){return this.b},uZn.Ib=function(){return"ls"+vIn(this.e)},uZn.a=0,uZn.b=0,uZn.c=-1,uZn.d=-1,uZn.g=0;var aSt,oSt=zW(P9n,"LinearSegmentsNodePlacer/LinearSegment",261);sDn(1428,1,y9n,iz),uZn.rg=function(n){return uG(oIn(uG(n,36),(GYn(),Hpt)),21).Hc((r_n(),tpt))?aSt:null},uZn.Kf=function(n,t){WJn(this,uG(n,36),t)},uZn.b=0,uZn.g=0,zW(P9n,"NetworkSimplexPlacer",1428),sDn(1447,1,b2n,$c),uZn.Ne=function(n,t){return d$(uG(n,17).a,uG(t,17).a)},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(P9n,"NetworkSimplexPlacer/0methodref$compare$Type",1447),sDn(1449,1,b2n,Dc),uZn.Ne=function(n,t){return d$(uG(n,17).a,uG(t,17).a)},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(P9n,"NetworkSimplexPlacer/1methodref$compare$Type",1449),sDn(655,1,{655:1},PI);var uSt=zW(P9n,"NetworkSimplexPlacer/EdgeRep",655);sDn(412,1,{412:1},wY),uZn.b=!1;var sSt,hSt,fSt,lSt=zW(P9n,"NetworkSimplexPlacer/NodeRep",412);sDn(515,13,{3:1,4:1,20:1,31:1,56:1,13:1,16:1,15:1,59:1,515:1},Ck),zW(P9n,"NetworkSimplexPlacer/Path",515),sDn(1429,1,{},xc),uZn.Kb=function(n){return uG(n,18).d.i.k},zW(P9n,"NetworkSimplexPlacer/Path/lambda$0$Type",1429),sDn(1430,1,y1n,Rc),uZn.Mb=function(n){return uG(n,273)==(zIn(),wbt)},zW(P9n,"NetworkSimplexPlacer/Path/lambda$1$Type",1430),sDn(1431,1,{},Kc),uZn.Kb=function(n){return uG(n,18).d.i},zW(P9n,"NetworkSimplexPlacer/Path/lambda$2$Type",1431),sDn(1432,1,y1n,up),uZn.Mb=function(n){return zK(Imn(uG(n,10)))},zW(P9n,"NetworkSimplexPlacer/Path/lambda$3$Type",1432),sDn(1433,1,y1n,Fc),uZn.Mb=function(n){return mq(uG(n,12))},zW(P9n,"NetworkSimplexPlacer/lambda$0$Type",1433),sDn(1434,1,QZn,CI),uZn.Cd=function(n){M$(this.a,this.b,uG(n,12))},zW(P9n,"NetworkSimplexPlacer/lambda$1$Type",1434),sDn(1443,1,QZn,sp),uZn.Cd=function(n){FLn(this.a,uG(n,18))},zW(P9n,"NetworkSimplexPlacer/lambda$10$Type",1443),sDn(1444,1,{},_c),uZn.Kb=function(n){return n2(),new fX(null,new h3(uG(n,30).a,16))},zW(P9n,"NetworkSimplexPlacer/lambda$11$Type",1444),sDn(1445,1,QZn,hp),uZn.Cd=function(n){D_n(this.a,uG(n,10))},zW(P9n,"NetworkSimplexPlacer/lambda$12$Type",1445),sDn(1446,1,{},Bc),uZn.Kb=function(n){return n2(),xwn(uG(n,125).e)},zW(P9n,"NetworkSimplexPlacer/lambda$13$Type",1446),sDn(1448,1,{},Hc),uZn.Kb=function(n){return n2(),xwn(uG(n,125).e)},zW(P9n,"NetworkSimplexPlacer/lambda$15$Type",1448),sDn(1450,1,y1n,Uc),uZn.Mb=function(n){return n2(),uG(n,412).c.k==(zIn(),dbt)},zW(P9n,"NetworkSimplexPlacer/lambda$17$Type",1450),sDn(1451,1,y1n,Gc),uZn.Mb=function(n){return n2(),uG(n,412).c.j.c.length>1},zW(P9n,"NetworkSimplexPlacer/lambda$18$Type",1451),sDn(1452,1,QZn,dY),uZn.Cd=function(n){Dpn(this.c,this.b,this.d,this.a,uG(n,412))},uZn.c=0,uZn.d=0,zW(P9n,"NetworkSimplexPlacer/lambda$19$Type",1452),sDn(1435,1,{},qc),uZn.Kb=function(n){return n2(),new fX(null,new h3(uG(n,30).a,16))},zW(P9n,"NetworkSimplexPlacer/lambda$2$Type",1435),sDn(1453,1,QZn,fp),uZn.Cd=function(n){j$(this.a,uG(n,12))},uZn.a=0,zW(P9n,"NetworkSimplexPlacer/lambda$20$Type",1453),sDn(1454,1,{},Xc),uZn.Kb=function(n){return n2(),new fX(null,new h3(uG(n,30).a,16))},zW(P9n,"NetworkSimplexPlacer/lambda$21$Type",1454),sDn(1455,1,QZn,lp),uZn.Cd=function(n){uD(this.a,uG(n,10))},zW(P9n,"NetworkSimplexPlacer/lambda$22$Type",1455),sDn(1456,1,y1n,zc),uZn.Mb=function(n){return zK(n)},zW(P9n,"NetworkSimplexPlacer/lambda$23$Type",1456),sDn(1457,1,{},Vc),uZn.Kb=function(n){return n2(),new fX(null,new h3(uG(n,30).a,16))},zW(P9n,"NetworkSimplexPlacer/lambda$24$Type",1457),sDn(1458,1,y1n,bp),uZn.Mb=function(n){return RL(this.a,uG(n,10))},zW(P9n,"NetworkSimplexPlacer/lambda$25$Type",1458),sDn(1459,1,QZn,II),uZn.Cd=function(n){$On(this.a,this.b,uG(n,10))},zW(P9n,"NetworkSimplexPlacer/lambda$26$Type",1459),sDn(1460,1,y1n,Wc),uZn.Mb=function(n){return n2(),!v9(uG(n,18))},zW(P9n,"NetworkSimplexPlacer/lambda$27$Type",1460),sDn(1461,1,y1n,Qc),uZn.Mb=function(n){return n2(),!v9(uG(n,18))},zW(P9n,"NetworkSimplexPlacer/lambda$28$Type",1461),sDn(1462,1,{},wp),uZn.Ve=function(n,t){return T$(this.a,uG(n,30),uG(t,30))},zW(P9n,"NetworkSimplexPlacer/lambda$29$Type",1462),sDn(1436,1,{},Jc),uZn.Kb=function(n){return n2(),new fX(null,new LW(new Fz(ix(Xgn(uG(n,10)).a.Kc(),new h))))},zW(P9n,"NetworkSimplexPlacer/lambda$3$Type",1436),sDn(1437,1,y1n,Yc),uZn.Mb=function(n){return n2(),h6(uG(n,18))},zW(P9n,"NetworkSimplexPlacer/lambda$4$Type",1437),sDn(1438,1,QZn,dp),uZn.Cd=function(n){vqn(this.a,uG(n,18))},zW(P9n,"NetworkSimplexPlacer/lambda$5$Type",1438),sDn(1439,1,{},Zc),uZn.Kb=function(n){return n2(),new fX(null,new h3(uG(n,30).a,16))},zW(P9n,"NetworkSimplexPlacer/lambda$6$Type",1439),sDn(1440,1,y1n,na),uZn.Mb=function(n){return n2(),uG(n,10).k==(zIn(),dbt)},zW(P9n,"NetworkSimplexPlacer/lambda$7$Type",1440),sDn(1441,1,{},ta),uZn.Kb=function(n){return n2(),new fX(null,new LW(new Fz(ix(Ggn(uG(n,10)).a.Kc(),new h))))},zW(P9n,"NetworkSimplexPlacer/lambda$8$Type",1441),sDn(1442,1,y1n,ea),uZn.Mb=function(n){return n2(),pq(uG(n,18))},zW(P9n,"NetworkSimplexPlacer/lambda$9$Type",1442),sDn(1424,1,y9n,pl),uZn.rg=function(n){return uG(oIn(uG(n,36),(GYn(),Hpt)),21).Hc((r_n(),tpt))?sSt:null},uZn.Kf=function(n,t){RXn(uG(n,36),t)},zW(P9n,"SimpleNodePlacer",1424),sDn(185,1,{185:1},WHn),uZn.Ib=function(){var n;return n="",this.c==(b0(),fSt)?n+=V2n:this.c==hSt&&(n+=z2n),this.o==(w0(),wSt)?n+=c3n:this.o==dSt?n+="UP":n+="BALANCED",n},zW(O9n,"BKAlignedLayout",185),sDn(523,22,{3:1,34:1,22:1,523:1},OI);var bSt,wSt,dSt,gSt=_cn(O9n,"BKAlignedLayout/HDirection",523,Oat,m1,CH);sDn(522,22,{3:1,34:1,22:1,522:1},AI);var pSt,mSt,vSt,kSt,ySt,MSt,TSt,jSt,ESt,SSt,PSt,CSt,ISt,OSt,ASt,LSt,NSt,$St,DSt,xSt=_cn(O9n,"BKAlignedLayout/VDirection",522,Oat,v1,IH);sDn(1699,1,{},LI),zW(O9n,"BKAligner",1699),sDn(1702,1,{},xjn),zW(O9n,"BKCompactor",1702),sDn(663,1,{663:1},ia),uZn.a=0,zW(O9n,"BKCompactor/ClassEdge",663),sDn(467,1,{467:1},Ek),uZn.a=null,uZn.b=0,zW(O9n,"BKCompactor/ClassNode",467),sDn(1427,1,y9n,FI),uZn.rg=function(n){return uG(oIn(uG(n,36),(GYn(),Hpt)),21).Hc((r_n(),tpt))?mSt:null},uZn.Kf=function(n,t){$Yn(this,uG(n,36),t)},uZn.d=!1,zW(O9n,"BKNodePlacer",1427),sDn(1700,1,{},ra),uZn.d=0,zW(O9n,"NeighborhoodInformation",1700),sDn(1701,1,b2n,gp),uZn.Ne=function(n,t){return vrn(this,uG(n,42),uG(t,42))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(O9n,"NeighborhoodInformation/NeighborComparator",1701),sDn(823,1,{}),zW(O9n,"ThresholdStrategy",823),sDn(1825,823,{},Sk),uZn.wg=function(n,t,e){return this.a.o==(w0(),dSt)?M0n:T0n},uZn.xg=function(){},zW(O9n,"ThresholdStrategy/NullThresholdStrategy",1825),sDn(587,1,{587:1},_I),uZn.c=!1,uZn.d=!1,zW(O9n,"ThresholdStrategy/Postprocessable",587),sDn(1826,823,{},Pk),uZn.wg=function(n,t,e){var i,r,c;return r=t==e,i=this.a.a[e.p]==t,r||i?(c=n,this.a.c,b0(),r&&(c=FXn(this,t,!0)),!isNaN(c)&&!isFinite(c)&&i&&(c=FXn(this,e,!1)),c):n},uZn.xg=function(){for(var n,t,e;0!=this.d.b;)(t=wGn(this,e=uG(H1(this.d),587))).a&&(n=t.a,(oM(this.a.f[this.a.g[e.b.p].p])||v9(n)||n.c.i.c!=n.d.i.c)&&(ixn(this,e)||VL(this.e,e)));for(;0!=this.e.a.c.length;)ixn(this,uG(obn(this.e),587))},zW(O9n,"ThresholdStrategy/SimpleThresholdStrategy",1826),sDn(645,1,{645:1,188:1,196:1},ca),uZn.dg=function(){return Fsn(this)},uZn.qg=function(){return Fsn(this)},zW(A9n,"EdgeRouterFactory",645),sDn(1485,1,y9n,ml),uZn.rg=function(n){return RFn(uG(n,36))},uZn.Kf=function(n,t){QXn(uG(n,36),t)},zW(A9n,"OrthogonalEdgeRouter",1485),sDn(1478,1,y9n,KI),uZn.rg=function(n){return oSn(uG(n,36))},uZn.Kf=function(n,t){XQn(this,uG(n,36),t)},zW(A9n,"PolylineEdgeRouter",1478),sDn(1479,1,A2n,oa),uZn.Lb=function(n){return shn(uG(n,10))},uZn.Fb=function(n){return this===n},uZn.Mb=function(n){return shn(uG(n,10))},zW(A9n,"PolylineEdgeRouter/1",1479),sDn(1872,1,y1n,ua),uZn.Mb=function(n){return uG(n,132).c==(_7(),$St)},zW(L9n,"HyperEdgeCycleDetector/lambda$0$Type",1872),sDn(1873,1,{},sa),uZn.Ze=function(n){return uG(n,132).d},zW(L9n,"HyperEdgeCycleDetector/lambda$1$Type",1873),sDn(1874,1,y1n,ha),uZn.Mb=function(n){return uG(n,132).c==(_7(),$St)},zW(L9n,"HyperEdgeCycleDetector/lambda$2$Type",1874),sDn(1875,1,{},fa),uZn.Ze=function(n){return uG(n,132).d},zW(L9n,"HyperEdgeCycleDetector/lambda$3$Type",1875),sDn(1876,1,{},la),uZn.Ze=function(n){return uG(n,132).d},zW(L9n,"HyperEdgeCycleDetector/lambda$4$Type",1876),sDn(1877,1,{},aa),uZn.Ze=function(n){return uG(n,132).d},zW(L9n,"HyperEdgeCycleDetector/lambda$5$Type",1877),sDn(118,1,{34:1,118:1},nhn),uZn.Fd=function(n){return IT(this,uG(n,118))},uZn.Fb=function(n){var t;return!!F$(n,118)&&(t=uG(n,118),this.g==t.g)},uZn.Hb=function(){return this.g},uZn.Ib=function(){var n,t,e,i;for(n=new lx("{"),i=new Ww(this.n);i.a"+this.b+" ("+yR(this.c)+")"},uZn.d=0,zW(L9n,"HyperEdgeSegmentDependency",132),sDn(528,22,{3:1,34:1,22:1,528:1},qI);var RSt,KSt,FSt,_St,BSt,HSt,USt,GSt,qSt=_cn(L9n,"HyperEdgeSegmentDependency/DependencyType",528,Oat,k1,OH);sDn(1878,1,{},pp),zW(L9n,"HyperEdgeSegmentSplitter",1878),sDn(1879,1,{},hj),uZn.a=0,uZn.b=0,zW(L9n,"HyperEdgeSegmentSplitter/AreaRating",1879),sDn(339,1,{339:1},OU),uZn.a=0,uZn.b=0,uZn.c=0,zW(L9n,"HyperEdgeSegmentSplitter/FreeArea",339),sDn(1880,1,b2n,ba),uZn.Ne=function(n,t){return C_(uG(n,118),uG(t,118))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(L9n,"HyperEdgeSegmentSplitter/lambda$0$Type",1880),sDn(1881,1,QZn,pY),uZn.Cd=function(n){I5(this.a,this.d,this.c,this.b,uG(n,118))},uZn.b=0,zW(L9n,"HyperEdgeSegmentSplitter/lambda$1$Type",1881),sDn(1882,1,{},wa),uZn.Kb=function(n){return new fX(null,new h3(uG(n,118).e,16))},zW(L9n,"HyperEdgeSegmentSplitter/lambda$2$Type",1882),sDn(1883,1,{},da),uZn.Kb=function(n){return new fX(null,new h3(uG(n,118).j,16))},zW(L9n,"HyperEdgeSegmentSplitter/lambda$3$Type",1883),sDn(1884,1,{},ga),uZn.Ye=function(n){return uM(pK(n))},zW(L9n,"HyperEdgeSegmentSplitter/lambda$4$Type",1884),sDn(664,1,{},NW),uZn.a=0,uZn.b=0,uZn.c=0,zW(L9n,"OrthogonalRoutingGenerator",664),sDn(1703,1,{},pa),uZn.Kb=function(n){return new fX(null,new h3(uG(n,118).e,16))},zW(L9n,"OrthogonalRoutingGenerator/lambda$0$Type",1703),sDn(1704,1,{},ma),uZn.Kb=function(n){return new fX(null,new h3(uG(n,118).j,16))},zW(L9n,"OrthogonalRoutingGenerator/lambda$1$Type",1704),sDn(670,1,{}),zW(N9n,"BaseRoutingDirectionStrategy",670),sDn(1870,670,{},Rk),uZn.yg=function(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t+n.o*i,h=new Ww(n.n);h.at4n&&(c=n,r=new MO(l,a=f),aq(o.a,r),WUn(this,o,c,r,!1),(b=n.r)&&(r=new MO(w=uM(pK(hyn(b.e,0))),a),aq(o.a,r),WUn(this,o,c,r,!1),c=b,r=new MO(w,a=t+b.o*i),aq(o.a,r),WUn(this,o,c,r,!1)),r=new MO(g,a),aq(o.a,r),WUn(this,o,c,r,!1)))},uZn.zg=function(n){return n.i.n.a+n.n.a+n.a.a},uZn.Ag=function(){return KQn(),KRt},uZn.Bg=function(){return KQn(),yRt},zW(N9n,"NorthToSouthRoutingStrategy",1870),sDn(1871,670,{},Kk),uZn.yg=function(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t-n.o*i,h=new Ww(n.n);h.at4n&&(c=n,r=new MO(l,a=f),aq(o.a,r),WUn(this,o,c,r,!1),(b=n.r)&&(r=new MO(w=uM(pK(hyn(b.e,0))),a),aq(o.a,r),WUn(this,o,c,r,!1),c=b,r=new MO(w,a=t-b.o*i),aq(o.a,r),WUn(this,o,c,r,!1)),r=new MO(g,a),aq(o.a,r),WUn(this,o,c,r,!1)))},uZn.zg=function(n){return n.i.n.a+n.n.a+n.a.a},uZn.Ag=function(){return KQn(),yRt},uZn.Bg=function(){return KQn(),KRt},zW(N9n,"SouthToNorthRoutingStrategy",1871),sDn(1869,670,{},Fk),uZn.yg=function(n,t,i){var r,c,a,o,u,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t+n.o*i,h=new Ww(n.n);h.at4n&&(c=n,r=new MO(a=f,l),aq(o.a,r),WUn(this,o,c,r,!0),(b=n.r)&&(r=new MO(a,w=uM(pK(hyn(b.e,0)))),aq(o.a,r),WUn(this,o,c,r,!0),c=b,r=new MO(a=t+b.o*i,w),aq(o.a,r),WUn(this,o,c,r,!0)),r=new MO(a,g),aq(o.a,r),WUn(this,o,c,r,!0)))},uZn.zg=function(n){return n.i.n.b+n.n.b+n.a.b},uZn.Ag=function(){return KQn(),kRt},uZn.Bg=function(){return KQn(),_Rt},zW(N9n,"WestToEastRoutingStrategy",1869),sDn(828,1,{},jqn),uZn.Ib=function(){return vIn(this.a)},uZn.b=0,uZn.c=!1,uZn.d=!1,uZn.f=0,zW(D9n,"NubSpline",828),sDn(418,1,{418:1},pFn,R1),zW(D9n,"NubSpline/PolarCP",418),sDn(1480,1,y9n,zTn),uZn.rg=function(n){return HPn(uG(n,36))},uZn.Kf=function(n,t){EJn(this,uG(n,36),t)},zW(D9n,"SplineEdgeRouter",1480),sDn(274,1,{274:1},O7),uZn.Ib=function(){return this.a+" ->("+this.c+") "+this.b},uZn.c=0,zW(D9n,"SplineEdgeRouter/Dependency",274),sDn(465,22,{3:1,34:1,22:1,465:1},XI);var XSt,zSt,VSt,WSt,QSt,JSt=_cn(D9n,"SplineEdgeRouter/SideToProcess",465,Oat,S1,AH);sDn(1481,1,y1n,va),uZn.Mb=function(n){return uFn(),!uG(n,131).o},zW(D9n,"SplineEdgeRouter/lambda$0$Type",1481),sDn(1482,1,{},ka),uZn.Ze=function(n){return uFn(),uG(n,131).v+1},zW(D9n,"SplineEdgeRouter/lambda$1$Type",1482),sDn(1483,1,QZn,BI),uZn.Cd=function(n){yq(this.a,this.b,uG(n,42))},zW(D9n,"SplineEdgeRouter/lambda$2$Type",1483),sDn(1484,1,QZn,HI),uZn.Cd=function(n){Mq(this.a,this.b,uG(n,42))},zW(D9n,"SplineEdgeRouter/lambda$3$Type",1484),sDn(131,1,{34:1,131:1},UAn,Izn),uZn.Fd=function(n){return NT(this,uG(n,131))},uZn.b=0,uZn.e=!1,uZn.f=0,uZn.g=0,uZn.j=!1,uZn.k=!1,uZn.n=0,uZn.o=!1,uZn.p=!1,uZn.q=!1,uZn.s=0,uZn.u=0,uZn.v=0,uZn.F=0,zW(D9n,"SplineSegment",131),sDn(468,1,{468:1},ya),uZn.a=0,uZn.b=!1,uZn.c=!1,uZn.d=!1,uZn.e=!1,uZn.f=0,zW(D9n,"SplineSegment/EdgeInformation",468),sDn(1198,1,{},Ma),zW(_9n,q3n,1198),sDn(1199,1,b2n,Ta),uZn.Ne=function(n,t){return yNn(uG(n,121),uG(t,121))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(_9n,X3n,1199),sDn(1197,1,{},Gj),zW(_9n,"MrTree",1197),sDn(405,22,{3:1,34:1,22:1,405:1,188:1,196:1},zI),uZn.dg=function(){return TNn(this)},uZn.qg=function(){return TNn(this)};var YSt,ZSt=_cn(_9n,"TreeLayoutPhases",405,Oat,i5,LH);sDn(1112,205,M3n,FF),uZn.rf=function(n,t){var e,i,r,c,a,o,u;for(oM(gK(zDn(n,(QGn(),gCt))))||J1(new Sd((vP(),new Vy(n)))),(c=t.eh(B9n)).Ug("build tGraph",1),zsn(o=new L7,n),kfn(o,(OQn(),RPt),n),EUn(n,o,u=new Ym),iGn(n,o,u),a=o,c.Vg(),(c=t.eh(B9n)).Ug("Split graph",1),r=LUn(this.a,a),c.Vg(),i=new Ww(r);i.a"+V3(this.c):"e_"+Hon(this)},zW(U9n,"TEdge",65),sDn(121,137,{3:1,121:1,96:1,137:1},L7),uZn.Ib=function(){var n,t,e,i,r;for(r=null,i=Fkn(this.b,0);i.b!=i.d.c;)r+=(null==(e=uG(I6(i),40)).c||0==e.c.length?"n_"+e.g:"n_"+e.c)+"\n";for(t=Fkn(this.a,0);t.b!=t.d.c;)r+=((n=uG(I6(t),65)).b&&n.c?V3(n.b)+"->"+V3(n.c):"e_"+Hon(n))+"\n";return r};var nPt=zW(U9n,"TGraph",121);sDn(643,508,{3:1,508:1,643:1,96:1,137:1}),zW(U9n,"TShape",643),sDn(40,643,{3:1,508:1,40:1,643:1,96:1,137:1},wln),uZn.Ib=function(){return V3(this)};var tPt,ePt,iPt,rPt,cPt,aPt,oPt,uPt,sPt,hPt,fPt,lPt=zW(U9n,"TNode",40);sDn(236,1,t1n,Mp),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return new Tp(Fkn(this.a.d,0))},zW(U9n,"TNode/2",236),sDn(329,1,$Zn,Tp),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){return uG(I6(this.a),65).c},uZn.Ob=function(){return Jj(this.a)},uZn.Qb=function(){yrn(this.a)},zW(U9n,"TNode/2/1",329),sDn(1923,1,Q4n,Oa),uZn.Kf=function(n,t){SYn(this,uG(n,121),t)},zW(q9n,"CompactionProcessor",1923),sDn(1924,1,b2n,jp),uZn.Ne=function(n,t){return ksn(this.a,uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$0$Type",1924),sDn(1925,1,y1n,GI),uZn.Mb=function(n){return xZ(this.b,this.a,uG(n,42))},uZn.a=0,uZn.b=0,zW(q9n,"CompactionProcessor/lambda$1$Type",1925),sDn(1934,1,b2n,Aa),uZn.Ne=function(n,t){return vW(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$10$Type",1934),sDn(1935,1,b2n,La),uZn.Ne=function(n,t){return Kx(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$11$Type",1935),sDn(1936,1,b2n,Na),uZn.Ne=function(n,t){return kW(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$12$Type",1936),sDn(1926,1,y1n,Ep),uZn.Mb=function(n){return hD(this.a,uG(n,42))},uZn.a=0,zW(q9n,"CompactionProcessor/lambda$2$Type",1926),sDn(1927,1,y1n,Sp),uZn.Mb=function(n){return fD(this.a,uG(n,42))},uZn.a=0,zW(q9n,"CompactionProcessor/lambda$3$Type",1927),sDn(1928,1,y1n,$a),uZn.Mb=function(n){return-1==uG(n,40).c.indexOf(H9n)},zW(q9n,"CompactionProcessor/lambda$4$Type",1928),sDn(1929,1,{},Pp),uZn.Kb=function(n){return a6(this.a,uG(n,40))},uZn.a=0,zW(q9n,"CompactionProcessor/lambda$5$Type",1929),sDn(1930,1,{},Cp),uZn.Kb=function(n){return ren(this.a,uG(n,40))},uZn.a=0,zW(q9n,"CompactionProcessor/lambda$6$Type",1930),sDn(1931,1,b2n,Ip),uZn.Ne=function(n,t){return G9(this.a,uG(n,240),uG(t,240))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$7$Type",1931),sDn(1932,1,b2n,Op),uZn.Ne=function(n,t){return q9(this.a,uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$8$Type",1932),sDn(1933,1,b2n,Da),uZn.Ne=function(n,t){return Fx(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(q9n,"CompactionProcessor/lambda$9$Type",1933),sDn(1921,1,Q4n,xa),uZn.Kf=function(n,t){cBn(uG(n,121),t)},zW(q9n,"DirectionProcessor",1921),sDn(1913,1,Q4n,KF),uZn.Kf=function(n,t){YUn(this,uG(n,121),t)},zW(q9n,"FanProcessor",1913),sDn(1937,1,Q4n,Ra),uZn.Kf=function(n,t){N_n(uG(n,121),t)},zW(q9n,"GraphBoundsProcessor",1937),sDn(1938,1,{},Ka),uZn.Ye=function(n){return uG(n,40).e.a},zW(q9n,"GraphBoundsProcessor/lambda$0$Type",1938),sDn(1939,1,{},Fa),uZn.Ye=function(n){return uG(n,40).e.b},zW(q9n,"GraphBoundsProcessor/lambda$1$Type",1939),sDn(1940,1,{},_a),uZn.Ye=function(n){return lP(uG(n,40))},zW(q9n,"GraphBoundsProcessor/lambda$2$Type",1940),sDn(1941,1,{},Ba),uZn.Ye=function(n){return fP(uG(n,40))},zW(q9n,"GraphBoundsProcessor/lambda$3$Type",1941),sDn(262,22,{3:1,34:1,22:1,262:1,196:1},VI),uZn.dg=function(){switch(this.g){case 0:return new sy;case 1:return new KF;case 2:return new uy;case 3:return new Xa;case 4:return new Ua;case 8:return new Ha;case 5:return new xa;case 6:return new Va;case 7:return new Oa;case 9:return new Ra;case 10:return new Wa;default:throw hv(new vM(v6n+(null!=this.f?this.f:""+this.g)))}};var bPt,wPt,dPt,gPt,pPt=_cn(q9n,k6n,262,Oat,usn,NH);sDn(1920,1,Q4n,Ha),uZn.Kf=function(n,t){xQn(uG(n,121),t)},zW(q9n,"LevelCoordinatesProcessor",1920),sDn(1918,1,Q4n,Ua),uZn.Kf=function(n,t){ZRn(this,uG(n,121),t)},uZn.a=0,zW(q9n,"LevelHeightProcessor",1918),sDn(1919,1,t1n,Ga),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return hZ(),wS(),Qot},zW(q9n,"LevelHeightProcessor/1",1919),sDn(1914,1,Q4n,uy),uZn.Kf=function(n,t){g_n(this,uG(n,121),t)},zW(q9n,"LevelProcessor",1914),sDn(1915,1,y1n,qa),uZn.Mb=function(n){return oM(gK(oIn(uG(n,40),(OQn(),UPt))))},zW(q9n,"LevelProcessor/lambda$0$Type",1915),sDn(1916,1,Q4n,Xa),uZn.Kf=function(n,t){DAn(this,uG(n,121),t)},uZn.a=0,zW(q9n,"NeighborsProcessor",1916),sDn(1917,1,t1n,za),uZn.Jc=function(n){z8(this,n)},uZn.Kc=function(){return hZ(),wS(),Qot},zW(q9n,"NeighborsProcessor/1",1917),sDn(1922,1,Q4n,Va),uZn.Kf=function(n,t){JUn(this,uG(n,121),t)},uZn.a=0,zW(q9n,"NodePositionProcessor",1922),sDn(1912,1,Q4n,sy),uZn.Kf=function(n,t){Ezn(this,uG(n,121),t)},zW(q9n,"RootProcessor",1912),sDn(1942,1,Q4n,Wa),uZn.Kf=function(n,t){Wyn(uG(n,121),t)},zW(q9n,"Untreeifyer",1942),sDn(392,22,{3:1,34:1,22:1,392:1},WI);var mPt,vPt,kPt,yPt,MPt,TPt,jPt,EPt,SPt,PPt,CPt,IPt,OPt,APt,LPt,NPt,$Pt,DPt,xPt,RPt,KPt,FPt,_Pt,BPt,HPt,UPt,GPt,qPt,XPt,zPt,VPt,WPt,QPt,JPt,YPt,ZPt,nCt,tCt,eCt,iCt,rCt,cCt,aCt,oCt,uCt,sCt,hCt,fCt,lCt,bCt,wCt,dCt,gCt,pCt,mCt,vCt,kCt,yCt,MCt,TCt,jCt,ECt,SCt,PCt,CCt,ICt,OCt,ACt,LCt,NCt,$Ct,DCt,xCt,RCt=_cn(W9n,"EdgeRoutingMode",392,Oat,t3,$H);sDn(862,1,K2n,vl),uZn.hf=function(n){Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,J9n),""),r7n),"Turns on Tree compaction which decreases the size of the whole tree by placing nodes of multiple levels in one large level"),(qx(),!1)),(lAn(),wNt)),cot),ggn((Rkn(),hNt))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Y9n),""),"Edge End Texture Length"),"Should be set to the length of the texture at the end of an edge. This value can be used to improve the Edge Routing."),7),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Z9n),""),"Tree Level"),"The index for the tree level the node is in"),xwn(0)),mNt),dot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,n7n),""),r7n),"When set to a positive number this option will force the algorithm to place the node to the specified position within the trees layer if weighting is set to constraint"),xwn(-1)),mNt),dot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,t7n),""),"Weighting of Nodes"),"Which weighting to use when computing a node order."),tCt),gNt),BCt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,e7n),""),"Edge Routing Mode"),"Chooses an Edge Routing algorithm."),WPt),gNt),RCt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,i7n),""),"Search Order"),"Which search order to use when computing a spanning tree."),YPt),gNt),QCt),ggn(hNt)))),yJn((new Ml,n))},zW(W9n,"MrTreeMetaDataProvider",862),sDn(1006,1,K2n,Ml),uZn.hf=function(n){yJn(n)},zW(W9n,"MrTreeOptions",1006),sDn(1007,1,{},Qa),uZn.sf=function(){return new FF},uZn.tf=function(n){},zW(W9n,"MrTreeOptions/MrtreeFactory",1007),sDn(353,22,{3:1,34:1,22:1,353:1},QI);var KCt,FCt,_Ct,BCt=_cn(W9n,"OrderWeighting",353,Oat,r5,DH);sDn(433,22,{3:1,34:1,22:1,433:1},JI);var HCt,UCt,GCt,qCt,XCt,zCt,VCt,WCt,QCt=_cn(W9n,"TreeifyingOrder",433,Oat,j1,xH);sDn(1486,1,y9n,Tl),uZn.rg=function(n){return uG(n,121),UCt},uZn.Kf=function(n,t){$un(this,uG(n,121),t)},zW("org.eclipse.elk.alg.mrtree.p1treeify","DFSTreeifyer",1486),sDn(1487,1,y9n,jl),uZn.rg=function(n){return uG(n,121),GCt},uZn.Kf=function(n,t){E_n(this,uG(n,121),t)},zW(u7n,"NodeOrderer",1487),sDn(1494,1,{},lo),uZn.td=function(n){return Nq(n)},zW(u7n,"NodeOrderer/0methodref$lambda$6$Type",1494),sDn(1488,1,y1n,bo),uZn.Mb=function(n){return ncn(),oM(gK(oIn(uG(n,40),(OQn(),UPt))))},zW(u7n,"NodeOrderer/lambda$0$Type",1488),sDn(1489,1,y1n,wo),uZn.Mb=function(n){return ncn(),uG(oIn(uG(n,40),(QGn(),kCt)),17).a<0},zW(u7n,"NodeOrderer/lambda$1$Type",1489),sDn(1490,1,y1n,Lp),uZn.Mb=function(n){return _an(this.a,uG(n,40))},zW(u7n,"NodeOrderer/lambda$2$Type",1490),sDn(1491,1,y1n,Ap),uZn.Mb=function(n){return f6(this.a,uG(n,40))},zW(u7n,"NodeOrderer/lambda$3$Type",1491),sDn(1492,1,b2n,go),uZn.Ne=function(n,t){return frn(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(u7n,"NodeOrderer/lambda$4$Type",1492),sDn(1493,1,y1n,po),uZn.Mb=function(n){return ncn(),0!=uG(oIn(uG(n,40),(OQn(),EPt)),17).a},zW(u7n,"NodeOrderer/lambda$5$Type",1493),sDn(1495,1,y9n,yl),uZn.rg=function(n){return uG(n,121),qCt},uZn.Kf=function(n,t){aUn(this,uG(n,121),t)},uZn.b=0,zW("org.eclipse.elk.alg.mrtree.p3place","NodePlacer",1495),sDn(1496,1,y9n,kl),uZn.rg=function(n){return uG(n,121),XCt},uZn.Kf=function(n,t){gHn(uG(n,121),t)},zW(s7n,"EdgeRouter",1496),sDn(1498,1,b2n,fo),uZn.Ne=function(n,t){return d$(uG(n,17).a,uG(t,17).a)},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/0methodref$compare$Type",1498),sDn(1503,1,{},Ya),uZn.Ye=function(n){return uM(pK(n))},zW(s7n,"EdgeRouter/1methodref$doubleValue$Type",1503),sDn(1505,1,b2n,Za),uZn.Ne=function(n,t){return ugn(uM(pK(n)),uM(pK(t)))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/2methodref$compare$Type",1505),sDn(1507,1,b2n,no),uZn.Ne=function(n,t){return ugn(uM(pK(n)),uM(pK(t)))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/3methodref$compare$Type",1507),sDn(1509,1,{},Ja),uZn.Ye=function(n){return uM(pK(n))},zW(s7n,"EdgeRouter/4methodref$doubleValue$Type",1509),sDn(1511,1,b2n,to),uZn.Ne=function(n,t){return ugn(uM(pK(n)),uM(pK(t)))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/5methodref$compare$Type",1511),sDn(1513,1,b2n,eo),uZn.Ne=function(n,t){return ugn(uM(pK(n)),uM(pK(t)))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/6methodref$compare$Type",1513),sDn(1497,1,{},io),uZn.Kb=function(n){return tcn(),uG(oIn(uG(n,40),(QGn(),ACt)),17)},zW(s7n,"EdgeRouter/lambda$0$Type",1497),sDn(1508,1,{},ro),uZn.Kb=function(n){return CR(uG(n,40))},zW(s7n,"EdgeRouter/lambda$11$Type",1508),sDn(1510,1,{},dO),uZn.Kb=function(n){return vq(this.b,this.a,uG(n,40))},uZn.a=0,uZn.b=0,zW(s7n,"EdgeRouter/lambda$13$Type",1510),sDn(1512,1,{},gO),uZn.Kb=function(n){return IR(this.b,this.a,uG(n,40))},uZn.a=0,uZn.b=0,zW(s7n,"EdgeRouter/lambda$15$Type",1512),sDn(1514,1,b2n,co),uZn.Ne=function(n,t){return Gkn(uG(n,65),uG(t,65))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/lambda$17$Type",1514),sDn(1515,1,b2n,ao),uZn.Ne=function(n,t){return qkn(uG(n,65),uG(t,65))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/lambda$18$Type",1515),sDn(1516,1,b2n,oo),uZn.Ne=function(n,t){return zkn(uG(n,65),uG(t,65))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/lambda$19$Type",1516),sDn(1499,1,y1n,Np),uZn.Mb=function(n){return n0(this.a,uG(n,40))},uZn.a=0,zW(s7n,"EdgeRouter/lambda$2$Type",1499),sDn(1517,1,b2n,uo),uZn.Ne=function(n,t){return Xkn(uG(n,65),uG(t,65))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/lambda$20$Type",1517),sDn(1500,1,b2n,so),uZn.Ne=function(n,t){return TG(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/lambda$3$Type",1500),sDn(1501,1,b2n,ho),uZn.Ne=function(n,t){return jG(uG(n,40),uG(t,40))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"EdgeRouter/lambda$4$Type",1501),sDn(1502,1,{},mo),uZn.Kb=function(n){return OR(uG(n,40))},zW(s7n,"EdgeRouter/lambda$5$Type",1502),sDn(1504,1,{},pO),uZn.Kb=function(n){return kq(this.b,this.a,uG(n,40))},uZn.a=0,uZn.b=0,zW(s7n,"EdgeRouter/lambda$7$Type",1504),sDn(1506,1,{},mO),uZn.Kb=function(n){return AR(this.b,this.a,uG(n,40))},uZn.a=0,uZn.b=0,zW(s7n,"EdgeRouter/lambda$9$Type",1506),sDn(675,1,{675:1},wTn),uZn.e=0,uZn.f=!1,uZn.g=!1,zW(s7n,"MultiLevelEdgeNodeNodeGap",675),sDn(1943,1,b2n,vo),uZn.Ne=function(n,t){return l2(uG(n,240),uG(t,240))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"MultiLevelEdgeNodeNodeGap/lambda$0$Type",1943),sDn(1944,1,b2n,ko),uZn.Ne=function(n,t){return b2(uG(n,240),uG(t,240))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(s7n,"MultiLevelEdgeNodeNodeGap/lambda$1$Type",1944),sDn(501,22,{3:1,34:1,22:1,501:1,188:1,196:1},YI),uZn.dg=function(){return Fpn(this)},uZn.qg=function(){return Fpn(this)};var JCt,YCt,ZCt,nIt,tIt,eIt,iIt=_cn(h7n,"RadialLayoutPhases",501,Oat,p1,RH);sDn(1113,205,M3n,Uj),uZn.rf=function(n,t){var e,i,r,c;if(e=_Kn(this,n),t.Ug("Radial layout",e.c.length),oM(gK(zDn(n,(jOn(),RIt))))||J1(new Sd((vP(),new Vy(n)))),c=XPn(n),Myn(n,(SK(),zCt),c),!c)throw hv(new vM("The given graph is not a tree!"));for(0==(i=uM(pK(zDn(n,HIt))))&&(i=tNn(n)),Myn(n,HIt,i),r=new Ww(_Kn(this,n));r.a=3)for(v=uG(zrn(p,0),27),k=uG(zrn(p,1),27),r=0;r+2=v.f+k.f+u||k.f>=m.f+v.f+u){y=!0;break}++r}else y=!0;if(!y){for(h=p.i,c=new DD(p);c.e!=c.i.gc();)Myn(uG(Zkn(c),27),(XYn(),vDt),xwn(h)),--h;return XGn(n,new fy),void t.Vg()}for(_J(this.a),JV(this.a,(Jmn(),oOt),uG(zDn(n,mAt),188)),JV(this.a,uOt,uG(zDn(n,sAt),188)),JV(this.a,sOt,uG(zDn(n,dAt),188)),ZL(this.a,(Aq(T=new wJ,oOt,(Zyn(),wOt)),Aq(T,uOt,bOt),oM(gK(zDn(n,YOt)))&&Aq(T,oOt,lOt),T)),o=1/(i=Qzn(this.a,n)).c.length,l=new Ww(i);l.a0&&Qbn((s3(t-1,n.length),n.charCodeAt(t-1)),c6n);)--t;if(e>=t)throw hv(new vM("The given string does not contain any numbers."));if(2!=(i=WGn((Knn(e,t,n.length),n.substr(e,t-e)),",|;|\r|\n")).length)throw hv(new vM("Exactly two numbers are expected, "+i.length+" were found."));try{this.a=YIn(KAn(i[0])),this.b=YIn(KAn(i[1]))}catch(r){throw F$(r=Ehn(r),130)?hv(new vM(a6n+r)):hv(r)}},uZn.Ib=function(){return"("+this.a+","+this.b+")"},uZn.a=0,uZn.b=0;var PNt=zW(o6n,"KVector",8);sDn(75,67,{3:1,4:1,20:1,31:1,56:1,16:1,67:1,15:1,75:1,423:1},Uk,tj,UR),uZn.Pc=function(){return ibn(this)},uZn.cg=function(n){var t,e,i,r,c;e=WGn(n,",|;|\\(|\\)|\\[|\\]|\\{|\\}| |\t|\n"),BY(this);try{for(t=0,r=0,i=0,c=0;t0&&(r%2==0?i=YIn(e[t]):c=YIn(e[t]),r>0&&r%2!=0&&aq(this,new MO(i,c)),++r),++t}catch(a){throw F$(a=Ehn(a),130)?hv(new vM("The given string does not match the expected format for vectors."+a)):hv(a)}},uZn.Ib=function(){var n,t,e;for(n=new lx("("),t=Fkn(this,0);t.b!=t.d.c;)JA(n,(e=uG(I6(t),8)).a+","+e.b),t.b!=t.d.c&&(n.a+="; ");return(n.a+=")",n).a};var CNt,INt,ONt,ANt,LNt,NNt,$Nt=zW(o6n,"KVectorChain",75);sDn(255,22,{3:1,34:1,22:1,255:1},TO);var DNt,xNt,RNt,KNt,FNt,_Nt,BNt,HNt,UNt,GNt,qNt,XNt,zNt,VNt,WNt,QNt,JNt,YNt,ZNt,n$t=_cn(Unt,"Alignment",255,Oat,Ynn,oU);sDn(991,1,K2n,$l),uZn.hf=function(n){ZUn(n)},zW(Unt,"BoxLayouterOptions",991),sDn(992,1,{},Ru),uZn.sf=function(){return new _u},uZn.tf=function(n){},zW(Unt,"BoxLayouterOptions/BoxFactory",992),sDn(298,22,{3:1,34:1,22:1,298:1},SO);var t$t,e$t,i$t,r$t,c$t,a$t,o$t,u$t,s$t,h$t,f$t,l$t,b$t,w$t,d$t,g$t,p$t,m$t,v$t,k$t,y$t,M$t,T$t,j$t,E$t,S$t,P$t,C$t,I$t,O$t,A$t,L$t,N$t,$$t,D$t,x$t,R$t,K$t,F$t,_$t,B$t,H$t,U$t,G$t,q$t,X$t,z$t,V$t,W$t,Q$t,J$t,Y$t,Z$t,nDt,tDt,eDt,iDt,rDt,cDt,aDt,oDt,uDt,sDt,hDt,fDt,lDt,bDt,wDt,dDt,gDt,pDt,mDt,vDt,kDt,yDt,MDt,TDt,jDt,EDt,SDt,PDt,CDt,IDt,ODt,ADt,LDt,NDt,$Dt,DDt,xDt,RDt,KDt,FDt,_Dt,BDt,HDt,UDt,GDt,qDt,XDt,zDt,VDt,WDt,QDt,JDt,YDt,ZDt,nxt,txt=_cn(Unt,"ContentAlignment",298,Oat,Znn,uU);sDn(699,1,K2n,Dl),uZn.hf=function(n){Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,Vnt),""),"Layout Algorithm"),"Select a specific layout algorithm."),(lAn(),kNt)),$ot),ggn((Rkn(),hNt))))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,Wnt),""),"Resolved Layout Algorithm"),"Meta data associated with the selected algorithm."),vNt),aNt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,X8n),""),"Alignment"),"Alignment of the selected node relative to other nodes; the exact meaning depends on the used algorithm."),r$t),gNt),n$t),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,R3n),""),"Aspect Ratio"),"The desired aspect ratio of the drawing, that is the quotient of width by height."),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,Qnt),""),"Bend Points"),"A fixed list of bend points for the edge. This is used by the 'Fixed Layout' algorithm to specify a pre-defined routing for an edge. The vector chain must include the source point, any bend points, and the target point, so it must have at least two points."),vNt),$Nt),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,r9n),""),"Content Alignment"),"Specifies how the content of a node are aligned. Each node can individually control the alignment of its contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that option."),b$t),pNt),txt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,q8n),""),"Debug Mode"),"Whether additional debug information shall be generated."),(qx(),!1)),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,W8n),""),l3n),"Overall direction of edges: horizontal (right / left) or vertical (down / up)."),g$t),gNt),axt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,m8n),""),"Edge Routing"),"What kind of edge routing style should be applied for the content of a parent node. Algorithms may also set this option to single edges in order to mark them as splines. The bend point list of edges with this option set to SPLINES must be interpreted as control points for a piecewise cubic spline."),y$t),gNt),kxt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Xnt),""),"Expand Nodes"),"If active, nodes are expanded to fill the area of their parent."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,b8n),""),"Hierarchy Handling"),"Determines whether separate layout runs are triggered for different compound nodes in a hierarchical graph. Setting a node's hierarchy handling to `INCLUDE_CHILDREN` will lay out that node and all of its descendants in a single layout run, until a descendant is encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that setting. Including multiple levels of hierarchy in a single layout run may allow cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` (or not set at all), the default behavior is `SEPARATE_CHILDREN`."),S$t),gNt),Kxt),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[sNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,K3n),""),"Padding"),"The padding to be left to a parent element's border when placing child elements. This can also serve as an output option of a layout algorithm if node size calculation is setup appropriately."),Q$t),vNt),Sbt),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[sNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,f4n),""),"Interactive"),"Whether the algorithm should be run in interactive mode for the content of a parent node. What this means exactly depends on how the specific algorithm interprets this option. Usually in the interactive mode algorithms try to modify the current layout as little as possible."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,g9n),""),"interactive Layout"),"Whether the graph should be changeable interactively and by setting constraints"),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,w4n),""),"Omit Node Micro Layout"),"Node micro layout comprises the computation of node dimensions (if requested), the placement of ports and their labels, and the placement of node labels. The functionality is implemented independent of any specific layout algorithm and shouldn't have any negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, this option allows to deactivate the micro layout."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,l4n),""),"Port Constraints"),"Defines constraints of the position of the ports of a node."),hDt),gNt),mRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,b9n),""),"Position"),"The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to specify a pre-defined position."),vNt),PNt),WX(sNt,Uhn(cT(MNt,1),p1n,170,0,[fNt,uNt]))))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,a4n),""),"Priority"),"Defines the priority of an object; its meaning depends on the specific layout algorithm and the context where it is used."),mNt),dot),WX(sNt,Uhn(cT(MNt,1),p1n,170,0,[oNt]))))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,s4n),""),"Randomization Seed"),"Seed used for pseudo-random number generators to control the layout algorithm. If the value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time)."),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,h4n),""),"Separate Connected Components"),"Whether each connected component should be processed separately."),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,c9n),""),"Junction Points"),"This option is not used as option, but as output of the layout algorithms. It is attached to edges and determines the points where junction symbols should be drawn in order to represent hyperedges with orthogonal routing. Whether such points are computed depends on the chosen layout algorithm and edge routing style. The points are put into the vector chain with no specific order."),N$t),vNt),$Nt),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,u9n),""),"Comment Box"),"Whether the node should be regarded as a comment box instead of a regular node. In that case its placement should be similar to how labels are handled. Any edges incident to a comment box specify to which graph elements the comment is related."),!1),wNt),cot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,s9n),""),"Hypernode"),"Whether the node should be handled as a hypernode."),!1),wNt),cot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,Jnt),""),"Label Manager"),"Label managers can shorten labels upon a layout algorithm's request."),vNt),cUt),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[uNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,w9n),""),"Margins"),"Margins define additional space around the actual bounds of a graph element. For instance, ports or labels being placed on the outside of a node's border might introduce such a margin. The margin is used to guarantee non-overlap of other graph elements with those ports or labels."),D$t),vNt),hbt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,U8n),""),"No Layout"),"No layout is done for the associated element. This is used to mark parts of a diagram to avoid their inclusion in the layout graph, or to mark parts of the layout graph to prevent layout engines from processing them. If you wish to exclude the contents of a compound node from automatic layout, while the node itself is still considered on its own layer, use the 'Fixed Layout' algorithm for that node."),!1),wNt),cot),WX(sNt,Uhn(cT(MNt,1),p1n,170,0,[oNt,fNt,uNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Ynt),""),"Scale Factor"),"The scaling factor to be applied to the corresponding node in recursive layout. It causes the corresponding node's size to be adjusted, and its ports and labels to be sized and placed accordingly after the layout of that node has been determined (and before the node itself and its siblings are arranged). The scaling is not reverted afterwards, so the resulting layout graph contains the adjusted size and position data. This option is currently not supported if 'Layout Hierarchy' is set."),1),dNt),fot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,Znt),""),"Child Area Width"),"The width of the area occupied by the laid out children of a node."),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,ntt),""),"Child Area Height"),"The height of the area occupied by the laid out children of a node."),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,k4n),""),Lnt),"Turns topdown layout on and off. If this option is enabled, hierarchical layout will be computed first for the root node and then for its children recursively. Layouts are then scaled down to fit the area provided by their parents. Graphs must follow a certain structure for topdown layout to work properly. {@link TopdownNodeTypes.PARALLEL_NODE} nodes must have children of type {@link TopdownNodeTypes.HIERARCHICAL_NODE} and must define {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} for their children. Furthermore they need to be laid out using an algorithm that is a {@link TopdownLayoutProvider}. Hierarchical nodes can also be parents of other hierarchical nodes and can optionally use a {@link TopdownSizeApproximator} to dynamically set sizes during topdown layout. In this case {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} should be set on the node itself rather than the parent. The values are then used by the size approximator as base values. Hierarchical nodes require the layout option {@link nodeSize.fixedGraphSize} to be true to prevent the algorithm used there from resizing the hierarchical node. This option is not supported if 'Hierarchy Handling' is set to 'INCLUDE_CHILDREN'"),!1),wNt),cot),ggn(hNt)))),H4(n,k4n,j4n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,ttt),""),"Animate"),"Whether the shift from the old layout to the new computed layout shall be animated."),!0),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,ett),""),"Animation Time Factor"),"Factor for computation of animation time. The higher the value, the longer the animation time. If the value is 0, the resulting time is always equal to the minimum defined by 'Minimal Animation Time'."),xwn(100)),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,itt),""),"Layout Ancestors"),"Whether the hierarchy levels on the path from the selected element to the root of the diagram shall be included in the layout process."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,rtt),""),"Maximal Animation Time"),"The maximal time for animations, in milliseconds."),xwn(4e3)),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,ctt),""),"Minimal Animation Time"),"The minimal time for animations, in milliseconds."),xwn(400)),mNt),dot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,att),""),"Progress Bar"),"Whether a progress bar shall be displayed during layout computations."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,ott),""),"Validate Graph"),"Whether the graph shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,utt),""),"Validate Options"),"Whether layout options shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!0),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,stt),""),"Zoom to Fit"),"Whether the zoom level shall be set to view the whole diagram after layout."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,znt),"box"),"Box Layout Mode"),"Configures the packing mode used by the {@link BoxLayoutProvider}. If SIMPLE is not required (neither priorities are used nor the interactive mode), GROUP_DEC can improve the packing and decrease the area. GROUP_MIXED and GROUP_INC may, in very specific scenarios, work better."),u$t),gNt),SKt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,A8n),v8n),"Comment Comment Spacing"),"Spacing to be preserved between a comment box and other comment boxes connected to the same node. The space left between comment boxes of different nodes is controlled by the node-node spacing."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,L8n),v8n),"Comment Node Spacing"),"Spacing to be preserved between a node and its connected comment boxes. The space left between a node and the comments of another node is controlled by the node-node spacing."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,D3n),v8n),"Components Spacing"),"Spacing to be preserved between pairs of connected components. This option is only relevant if 'separateConnectedComponents' is activated."),20),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,N8n),v8n),"Edge Spacing"),"Spacing to be preserved between any two edges. Note that while this can somewhat easily be satisfied for the segments of orthogonally drawn edges, it is harder for general polylines or splines."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,u4n),v8n),"Edge Label Spacing"),"The minimal distance to be preserved between a label and the edge it is associated with. Note that the placement of a label is influenced by the 'edgelabels.placement' option."),2),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,$8n),v8n),"Edge Node Spacing"),"Spacing to be preserved between nodes and edges."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,D8n),v8n),"Label Spacing"),"Determines the amount of space to be left between two labels of the same graph element."),0),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,K8n),v8n),"Label Node Spacing"),"Spacing to be preserved between labels and the border of node they are associated with. Note that the placement of a label is influenced by the 'nodelabels.placement' option."),5),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,x8n),v8n),"Horizontal spacing between Label and Port"),"Horizontal spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,R8n),v8n),"Vertical spacing between Label and Port"),"Vertical spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,o4n),v8n),"Node Spacing"),"The minimal distance to be preserved between each two nodes."),20),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,F8n),v8n),"Node Self Loop Spacing"),"Spacing to be preserved between a node and its self loops."),10),dNt),fot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,_8n),v8n),"Port Spacing"),"Spacing between pairs of ports of the same node."),10),dNt),fot),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[sNt]))))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,B8n),v8n),"Individual Spacing"),"Allows to specify individual spacing values for graph elements that shall be different from the value specified for the element's parent."),vNt),AKt),WX(sNt,Uhn(cT(MNt,1),p1n,170,0,[oNt,fNt,uNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,d9n),v8n),"Additional Port Space"),"Additional space around the sets of ports on each node side. For each side of a node, this option can reserve additional space before and after the ports on each side. For example, a top spacing of 20 makes sure that the first port on the western and eastern side is 20 units away from the northern border."),KDt),vNt),hbt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,l9n),dtt),"Layout Partition"),"Partition to which the node belongs. This requires Layout Partitioning to be active. Nodes with lower partition IDs will appear to the left of nodes with higher partition IDs (assuming a left-to-right layout direction)."),mNt),dot),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[sNt]))))),H4(n,l9n,f9n,nDt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,f9n),dtt),"Layout Partitioning"),"Whether to activate partitioned layout. This will allow to group nodes through the Layout Partition option. a pair of nodes with different partition indices is then placed such that the node with lower index is placed to the left of the other node (with left-to-right layout direction). Depending on the layout algorithm, this may only be guaranteed to work if all nodes have a layout partition configured, or at least if edges that cross partitions are not part of a partition-crossing cycle."),Y$t),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Q8n),gtt),"Node Label Padding"),"Define padding for node labels that are placed inside of a node."),R$t),vNt),Sbt),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,m4n),gtt),"Node Label Placement"),"Hints for where node labels are to be placed; if empty, the node label's position is not modified."),F$t),pNt),eRt),WX(sNt,Uhn(cT(MNt,1),p1n,170,0,[uNt]))))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Z8n),ptt),"Port Alignment"),"Defines the default port distribution for a node. May be overridden for each side individually."),eDt),gNt),hRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,n9n),ptt),"Port Alignment (North)"),"Defines how ports on the northern side are placed, overriding the node's general port alignment."),gNt),hRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,t9n),ptt),"Port Alignment (South)"),"Defines how ports on the southern side are placed, overriding the node's general port alignment."),gNt),hRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,e9n),ptt),"Port Alignment (West)"),"Defines how ports on the western side are placed, overriding the node's general port alignment."),gNt),hRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,i9n),ptt),"Port Alignment (East)"),"Defines how ports on the eastern side are placed, overriding the node's general port alignment."),gNt),hRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,p4n),mtt),"Node Size Constraints"),"What should be taken into account when calculating a node's size. Empty size constraints specify that a node's size is already fixed and should not be changed."),B$t),pNt),sKt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,g4n),mtt),"Node Size Options"),"Options modifying the behavior of the size constraints set on a node. Each member of the set specifies something that should be taken into account when calculating node sizes. The empty set corresponds to no further modifications."),X$t),pNt),wKt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,x4n),mtt),"Node Size Minimum"),"The minimal size to which a node can be reduced."),G$t),vNt),PNt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,d4n),mtt),"Fixed Graph Size"),"By default, the fixed layout provider will enlarge a graph until it is large enough to contain its children. If this option is set, it won't do so."),!1),wNt),cot),ggn(hNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,a9n),I8n),"Edge Label Placement"),"Gives a hint on where to put edge labels."),v$t),gNt),lxt),ggn(uNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,b4n),I8n),"Inline Edge Labels"),"If true, an edge label is placed directly on its edge. May only apply to center edge labels. This kind of label placement is only advisable if the label's rendering is such that it is not crossed by its edge and thus stays legible."),!1),wNt),cot),ggn(uNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,htt),"font"),"Font Name"),"Font name used for a label."),kNt),$ot),ggn(uNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,ftt),"font"),"Font Size"),"Font size used for a label."),mNt),dot),ggn(uNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,h9n),vtt),"Port Anchor Offset"),"The offset to the port position where connections shall be attached."),vNt),PNt),ggn(fNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,o9n),vtt),"Port Index"),"The index of a port in the fixed order around a node. The order is assumed as clockwise, starting with the leftmost port on the top side. This option must be set if 'Port Constraints' is set to FIXED_ORDER and no specific positions are given for the ports. Additionally, the option 'Port Side' must be defined in this case."),mNt),dot),ggn(fNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,G8n),vtt),"Port Side"),"The side of a node on which a port is situated. This option must be set if 'Port Constraints' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given for the ports."),pDt),gNt),YRt),ggn(fNt)))),Zgn(n,new tAn(JT(QT(YT(GT(WT(XT(zT(new xu,H8n),vtt),"Port Border Offset"),"The offset of ports on the node border. With a positive offset the port is moved outside of the node, while with a negative offset the port is moved towards the inside. An offset of 0 means that the port is placed directly on the node border, i.e. if the port side is north, the port's south border touches the nodes's north border; if the port side is east, the port's west border touches the nodes's east border; if the port side is south, the port's north border touches the node's south border; if the port side is west, the port's east border touches the node's west border."),dNt),fot),ggn(fNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,v4n),ktt),"Port Label Placement"),"Decides on a placement method for port labels; if empty, the node label's position is not modified."),wDt),pNt),BRt),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,J8n),ktt),"Port Labels Next to Port"),"Use 'portLabels.placement': NEXT_TO_PORT_OF_POSSIBLE."),!1),wNt),cot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,Y8n),ktt),"Treat Port Labels as Group"),"If this option is true (default), the labels of a port will be treated as a group when it comes to centering them next to their port. If this option is false, only the first label will be centered next to the port, with the others being placed below. This only applies to labels of eastern and western ports and will have no effect if labels are not placed next to their port."),!0),wNt),cot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,y4n),ytt),"Topdown Scale Factor"),"The scaling factor to be applied to the nodes laid out within the node in recursive topdown layout. The difference to 'Scale Factor' is that the node itself is not scaled. This value has to be set on hierarchical nodes."),1),dNt),fot),ggn(hNt)))),H4(n,y4n,j4n,zDt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,ltt),ytt),"Topdown Size Approximator"),"The size approximator to be used to set sizes of hierarchical nodes during topdown layout. The default value is null, which results in nodes keeping whatever size is defined for them e.g. through parent parallel node or by manually setting the size."),null),gNt),jKt),ggn(sNt)))),H4(n,ltt,j4n,WDt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,M4n),ytt),"Topdown Hierarchical Node Width"),"The fixed size of a hierarchical node when using topdown layout. If this value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to the node itself."),150),dNt),fot),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[sNt]))))),H4(n,M4n,j4n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,T4n),ytt),"Topdown Hierarchical Node Aspect Ratio"),"The fixed aspect ratio of a hierarchical node when using topdown layout. Default is 1/sqrt(2). If this value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to the node itself."),1.414),dNt),fot),WX(hNt,Uhn(cT(MNt,1),p1n,170,0,[sNt]))))),H4(n,T4n,j4n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,j4n),ytt),"Topdown Node Type"),"The different node types used for topdown layout. If the node type is set to {@link TopdownNodeTypes.PARALLEL_NODE} the algorithm must be set to a {@link TopdownLayoutProvider} such as {@link TopdownPacking}. The {@link nodeSize.fixedGraphSize} option is technically only required for hierarchical nodes."),null),gNt),mKt),ggn(sNt)))),H4(n,j4n,d4n,null),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,btt),ytt),"Topdown Scale Cap"),"Determines the upper limit for the topdown scale factor. The default value is 1.0 which ensures that nested children never end up appearing larger than their parents in terms of unit sizes such as the font size. If the limit is larger, nodes will fully utilize the available space, but it is counteriniuitive for inner nodes to have a larger scale than outer nodes."),1),dNt),fot),ggn(hNt)))),H4(n,btt,j4n,qDt),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,z8n),Mtt),"Activate Inside Self Loops"),"Whether this node allows to route self loops inside of it instead of around it. If set to true, this will make the node a compound node if it isn't already, and will require the layout algorithm to support compound nodes with hierarchical ports."),!1),wNt),cot),ggn(sNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,V8n),Mtt),"Inside Self Loop"),"Whether a self loop should be routed inside a node instead of around that node."),!1),wNt),cot),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,x3n),"edge"),"Edge Thickness"),"The thickness of an edge. This is a hint on the line width used to draw an edge, possibly requiring more space to be reserved for it."),1),dNt),fot),ggn(oNt)))),Zgn(n,new tAn(JT(QT(YT(qT(GT(WT(XT(zT(new xu,wtt),"edge"),"Edge Type"),"The type of an edge. This is usually used for UML class diagrams, where associations must be handled differently from generalizations."),T$t),gNt),Lxt),ggn(oNt)))),sP(n,new I2(BT(UT(HT(new du,S0n),"Layered"),'The layer-based method was introduced by Sugiyama, Tagawa and Toda in 1981. It emphasizes the direction of edges by pointing as many edges as possible into the same direction. The nodes are arranged in layers, which are sometimes called "hierarchies", and then reordered such that the number of edge crossings is minimized. Afterwards, concrete coordinates are computed for the nodes and edge bend points.'))),sP(n,new I2(BT(UT(HT(new du,"org.eclipse.elk.orthogonal"),"Orthogonal"),'Orthogonal methods that follow the "topology-shape-metrics" approach by Batini, Nardelli and Tamassia \'86. The first phase determines the topology of the drawing by applying a planarization technique, which results in a planar representation of the graph. The orthogonal shape is computed in the second phase, which aims at minimizing the number of edge bends, and is called orthogonalization. The third phase leads to concrete coordinates for nodes and edge bend points by applying a compaction method, thus defining the metrics.'))),sP(n,new I2(BT(UT(HT(new du,c4n),"Force"),"Layout algorithms that follow physical analogies by simulating a system of attractive and repulsive forces. The first successful method of this kind was proposed by Eades in 1984."))),sP(n,new I2(BT(UT(HT(new du,"org.eclipse.elk.circle"),"Circle"),"Circular layout algorithms emphasize cycles or biconnected components of a graph by arranging them in circles. This is useful if a drawing is desired where such components are clearly grouped, or where cycles are shown as prominent OPTIONS of the graph."))),sP(n,new I2(BT(UT(HT(new du,a7n),"Tree"),"Specialized layout methods for trees, i.e. acyclic graphs. The regular structure of graphs that have no undirected cycles can be emphasized using an algorithm of this type."))),sP(n,new I2(BT(UT(HT(new du,"org.eclipse.elk.planar"),"Planar"),"Algorithms that require a planar or upward planar graph. Most of these algorithms are theoretically interesting, but not practically usable."))),sP(n,new I2(BT(UT(HT(new du,x7n),"Radial"),"Radial layout algorithms usually position the nodes of the graph on concentric circles."))),kHn((new xl,n)),ZUn((new $l,n)),A_n((new Rl,n))},zW(Unt,"CoreOptions",699),sDn(88,22,{3:1,34:1,22:1,88:1},PO);var ext,ixt,rxt,cxt,axt=_cn(Unt,l3n,88,Oat,H8,sU);sDn(278,22,{3:1,34:1,22:1,278:1},CO);var oxt,uxt,sxt,hxt,fxt,lxt=_cn(Unt,"EdgeLabelPlacement",278,Oat,y3,hU);sDn(223,22,{3:1,34:1,22:1,223:1},IO);var bxt,wxt,dxt,gxt,pxt,mxt,vxt,kxt=_cn(Unt,"EdgeRouting",223,Oat,u5,fU);sDn(321,22,{3:1,34:1,22:1,321:1},OO);var yxt,Mxt,Txt,jxt,Ext,Sxt,Pxt,Cxt,Ixt,Oxt,Axt,Lxt=_cn(Unt,"EdgeType",321,Oat,Jnn,lU);sDn(989,1,K2n,xl),uZn.hf=function(n){kHn(n)},zW(Unt,"FixedLayouterOptions",989),sDn(990,1,{},Ku),uZn.sf=function(){return new Wu},uZn.tf=function(n){},zW(Unt,"FixedLayouterOptions/FixedFactory",990),sDn(346,22,{3:1,34:1,22:1,346:1},AO);var Nxt,$xt,Dxt,xxt,Rxt,Kxt=_cn(Unt,"HierarchyHandling",346,Oat,v3,bU);sDn(291,22,{3:1,34:1,22:1,291:1},LO);var Fxt,_xt,Bxt,Hxt,Uxt,Gxt,qxt,Xxt,zxt,Vxt,Wxt=_cn(Unt,"LabelSide",291,Oat,o5,wU);sDn(95,22,{3:1,34:1,22:1,95:1},NO);var Qxt,Jxt,Yxt,Zxt,nRt,tRt,eRt=_cn(Unt,"NodeLabelPlacement",95,Oat,bcn,dU);sDn(256,22,{3:1,34:1,22:1,256:1},$O);var iRt,rRt,cRt,aRt,oRt,uRt,sRt,hRt=_cn(Unt,"PortAlignment",256,Oat,p9,gU);sDn(101,22,{3:1,34:1,22:1,101:1},DO);var fRt,lRt,bRt,wRt,dRt,gRt,pRt,mRt=_cn(Unt,"PortConstraints",101,Oat,Qnn,pU);sDn(279,22,{3:1,34:1,22:1,279:1},xO);var vRt,kRt,yRt,MRt,TRt,jRt,ERt,SRt,PRt,CRt,IRt,ORt,ARt,LRt,NRt,$Rt,DRt,xRt,RRt,KRt,FRt,_Rt,BRt=_cn(Unt,"PortLabelPlacement",279,Oat,Wnn,mU);sDn(64,22,{3:1,34:1,22:1,64:1},RO);var HRt,URt,GRt,qRt,XRt,zRt,VRt,WRt,QRt,JRt,YRt=_cn(Unt,"PortSide",64,Oat,U8,vU);sDn(993,1,K2n,Rl),uZn.hf=function(n){A_n(n)},zW(Unt,"RandomLayouterOptions",993),sDn(994,1,{},Fu),uZn.sf=function(){return new Xu},uZn.tf=function(n){},zW(Unt,"RandomLayouterOptions/RandomFactory",994),sDn(386,22,{3:1,34:1,22:1,386:1},KO);var ZRt,nKt,tKt,eKt,iKt,rKt,cKt,aKt,oKt,uKt,sKt=_cn(Unt,"SizeConstraint",386,Oat,a5,kU);sDn(264,22,{3:1,34:1,22:1,264:1},FO);var hKt,fKt,lKt,bKt,wKt=_cn(Unt,"SizeOptions",264,Oat,Man,yU);sDn(280,22,{3:1,34:1,22:1,280:1},_O);var dKt,gKt,pKt,mKt=_cn(Unt,"TopdownNodeTypes",280,Oat,M3,MU);sDn(347,22,Ett);var vKt,kKt,yKt,MKt,TKt,jKt=_cn(Unt,"TopdownSizeApproximator",347,Oat,I1,jU);sDn(987,347,Ett,Pq),uZn.Tg=function(n){return sMn(n)},_cn(Unt,"TopdownSizeApproximator/1",987,jKt,null,null),sDn(988,347,Ett,gV),uZn.Tg=function(n){var t,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p,m,v,k;for(t=uG(zDn(n,(XYn(),yDt)),143),gj(),aKn(p=new Bk,n),m=new Ym,a=new DD((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a));a.e!=a.i.gc();)r=uG(Zkn(a),27),GRn(b=new Bk,p),aKn(b,r),k=sMn(r),vN(b,e.Math.max(r.g,k.a),e.Math.max(r.f,k.b)),VAn(m.f,r,b);for(c=new DD((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a));c.e!=c.i.gc();)for(s=new DD((!(r=uG(Zkn(c),27)).e&&(r.e=new f_(aFt,r,7,4)),r.e));s.e!=s.i.gc();)u=uG(Zkn(s),74),d=uG(DA(FX(m.f,r)),27),g=uG(cQ(m,zrn((!u.c&&(u.c=new f_(cFt,u,5,8)),u.c),0)),27),ttn((!(w=new es).b&&(w.b=new f_(cFt,w,4,7)),w.b),d),ttn((!w.c&&(w.c=new f_(cFt,w,5,8)),w.c),g),ARn(w,R0(d)),aKn(w,u);h=uG(A1(t.f),205);try{h.rf(p,new Zu),WQ(t.f,h)}catch(y){throw F$(y=Ehn(y),103),hv(y)}return vnn(p,h$t)||vnn(p,s$t)||VJn(p),o=uM(pK(zDn(p,h$t)))/uM(pK(zDn(p,s$t))),i=uM(pK(zDn(p,BDt)))*e.Math.sqrt((!p.a&&(p.a=new fV(bFt,p,10,11)),p.a).i),l=(v=uG(zDn(p,W$t),107)).b+v.c+1,f=v.d+v.a+1,new MO(e.Math.max(l,i),e.Math.max(f,i/o))},_cn(Unt,"TopdownSizeApproximator/2",988,jKt,null,null),sDn(344,1,{871:1},fy),uZn.Ug=function(n,t){return dCn(this,n,t)},uZn.Vg=function(){POn(this)},uZn.Wg=function(){return this.q},uZn.Xg=function(){return this.f?SZ(this.f):null},uZn.Yg=function(){return SZ(this.a)},uZn.Zg=function(){return this.p},uZn.$g=function(){return!1},uZn._g=function(){return this.n},uZn.ah=function(){return null!=this.p&&!this.b},uZn.bh=function(n){var t;this.n&&(t=n,kD(this.f,t))},uZn.dh=function(n,t){var e,i;this.n&&n&&n4(this,(i=uUn(e=new DW,n),_Wn(e),i),(Eln(),CKt))},uZn.eh=function(n){var t;return this.b?null:(t=irn(this,this.g),aq(this.a,t),t.i=this,this.d=n,t)},uZn.fh=function(n){n>0&&!this.b&&Ban(this,n)},uZn.b=!1,uZn.c=0,uZn.d=-1,uZn.e=null,uZn.f=null,uZn.g=-1,uZn.j=!1,uZn.k=!1,uZn.n=!1,uZn.o=0,uZn.q=0,uZn.r=0,zW(p9n,"BasicProgressMonitor",344),sDn(717,205,M3n,_u),uZn.rf=function(n,t){XGn(n,t)},zW(p9n,"BoxLayoutProvider",717),sDn(983,1,b2n,qp),uZn.Ne=function(n,t){return tKn(this,uG(n,27),uG(t,27))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},uZn.a=!1,zW(p9n,"BoxLayoutProvider/1",983),sDn(163,1,{163:1},Jrn,nK),uZn.Ib=function(){return this.c?zBn(this.c):vIn(this.b)},zW(p9n,"BoxLayoutProvider/Group",163),sDn(320,22,{3:1,34:1,22:1,320:1},HO);var EKt,SKt=_cn(p9n,"BoxLayoutProvider/PackingMode",320,Oat,s5,EU);sDn(984,1,b2n,Bu),uZn.Ne=function(n,t){return rZ(uG(n,163),uG(t,163))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(p9n,"BoxLayoutProvider/lambda$0$Type",984),sDn(985,1,b2n,Hu),uZn.Ne=function(n,t){return GY(uG(n,163),uG(t,163))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(p9n,"BoxLayoutProvider/lambda$1$Type",985),sDn(986,1,b2n,Uu),uZn.Ne=function(n,t){return qY(uG(n,163),uG(t,163))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(p9n,"BoxLayoutProvider/lambda$2$Type",986),sDn(1384,1,{845:1},Gu),uZn.Mg=function(n,t){return ZS(),!F$(t,167)||Zj((Whn(),uG(n,167)),t)},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$0$Type",1384),sDn(1385,1,QZn,Xp),uZn.Cd=function(n){hbn(this.a,uG(n,149))},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$1$Type",1385),sDn(1386,1,QZn,zu),uZn.Cd=function(n){uG(n,96),ZS()},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$2$Type",1386),sDn(1390,1,QZn,zp),uZn.Cd=function(n){_on(this.a,uG(n,96))},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$3$Type",1390),sDn(1388,1,y1n,UO),uZn.Mb=function(n){return oln(this.a,this.b,uG(n,149))},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$4$Type",1388),sDn(1387,1,y1n,GO),uZn.Mb=function(n){return PR(this.a,this.b,uG(n,845))},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$5$Type",1387),sDn(1389,1,QZn,qO),uZn.Cd=function(n){iV(this.a,this.b,uG(n,149))},zW(p9n,"ElkSpacings/AbstractSpacingsBuilder/lambda$6$Type",1389),sDn(947,1,{},Vu),uZn.Kb=function(n){return oN(n)},uZn.Fb=function(n){return this===n},zW(p9n,"ElkUtil/lambda$0$Type",947),sDn(948,1,QZn,XO),uZn.Cd=function(n){JNn(this.a,this.b,uG(n,74))},uZn.a=0,uZn.b=0,zW(p9n,"ElkUtil/lambda$1$Type",948),sDn(949,1,QZn,zO),uZn.Cd=function(n){tM(this.a,this.b,uG(n,166))},uZn.a=0,uZn.b=0,zW(p9n,"ElkUtil/lambda$2$Type",949),sDn(950,1,QZn,VO),uZn.Cd=function(n){UN(this.a,this.b,uG(n,135))},uZn.a=0,uZn.b=0,zW(p9n,"ElkUtil/lambda$3$Type",950),sDn(951,1,QZn,Vp),uZn.Cd=function(n){Lq(this.a,uG(n,377))},zW(p9n,"ElkUtil/lambda$4$Type",951),sDn(325,1,{34:1,325:1},Jm),uZn.Fd=function(n){return wD(this,uG(n,242))},uZn.Fb=function(n){var t;return!!F$(n,325)&&(t=uG(n,325),this.a==t.a)},uZn.Hb=function(){return t0(this.a)},uZn.Ib=function(){return this.a+" (exclusive)"},uZn.a=0,zW(p9n,"ExclusiveBounds/ExclusiveLowerBound",325),sDn(1119,205,M3n,Wu),uZn.rf=function(n,t){var i,r,c,a,o,u,s,f,l,b,w,d,g,p,m,v,k,y,M,T,j;for(t.Ug("Fixed Layout",1),a=uG(zDn(n,(XYn(),k$t)),223),b=0,w=0,m=new DD((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a));m.e!=m.i.gc();){for(g=uG(Zkn(m),27),(j=uG(zDn(g,(Iln(),Cxt)),8))&&(kN(g,j.a,j.b),uG(zDn(g,Txt),181).Hc((Qmn(),VRt))&&(d=uG(zDn(g,Ext),8)).a>0&&d.b>0&&ZQn(g,d.a,d.b,!0,!0)),b=e.Math.max(b,g.i+g.g),w=e.Math.max(w,g.j+g.f),f=new DD((!g.n&&(g.n=new fV(lFt,g,1,7)),g.n));f.e!=f.i.gc();)u=uG(Zkn(f),135),(j=uG(zDn(u,Cxt),8))&&kN(u,j.a,j.b),b=e.Math.max(b,g.i+u.i+u.g),w=e.Math.max(w,g.j+u.j+u.f);for(y=new DD((!g.c&&(g.c=new fV(wFt,g,9,9)),g.c));y.e!=y.i.gc();)for(k=uG(Zkn(y),123),(j=uG(zDn(k,Cxt),8))&&kN(k,j.a,j.b),M=g.i+k.i,T=g.j+k.j,b=e.Math.max(b,M+k.g),w=e.Math.max(w,T+k.f),s=new DD((!k.n&&(k.n=new fV(lFt,k,1,7)),k.n));s.e!=s.i.gc();)u=uG(Zkn(s),135),(j=uG(zDn(u,Cxt),8))&&kN(u,j.a,j.b),b=e.Math.max(b,M+u.i+u.g),w=e.Math.max(w,T+u.j+u.f);for(c=new Fz(ix(eRn(g).a.Kc(),new h));hDn(c);)l=iJn(i=uG(N9(c),74)),b=e.Math.max(b,l.a),w=e.Math.max(w,l.b);for(r=new Fz(ix(tRn(g).a.Kc(),new h));hDn(r);)R0(bIn(i=uG(N9(r),74)))!=n&&(l=iJn(i),b=e.Math.max(b,l.a),w=e.Math.max(w,l.b))}if(a==(_gn(),uxt))for(p=new DD((!n.a&&(n.a=new fV(bFt,n,10,11)),n.a));p.e!=p.i.gc();)for(r=new Fz(ix(eRn(g=uG(Zkn(p),27)).a.Kc(),new h));hDn(r);)0==(o=bGn(i=uG(N9(r),74))).b?Myn(i,L$t,null):Myn(i,L$t,o);oM(gK(zDn(n,(Iln(),jxt))))||ZQn(n,b+(v=uG(zDn(n,Sxt),107)).b+v.c,w+v.d+v.a,!0,!0),t.Vg()},zW(p9n,"FixedLayoutProvider",1119),sDn(385,137,{3:1,423:1,385:1,96:1,137:1},Qu,qen),uZn.cg=function(n){var t,e,i,r,c,a,o;if(n)try{for(a=WGn(n,";,;"),r=0,c=(i=a).length;r>16&D1n|n^(e&D1n)<<16},uZn.Kc=function(){return new Wp(this)},uZn.Ib=function(){return null==this.a&&null==this.b?"pair(null,null)":null==this.a?"pair(null,"+cpn(this.b)+")":null==this.b?"pair("+cpn(this.a)+",null)":"pair("+cpn(this.a)+","+cpn(this.b)+")"},zW(p9n,"Pair",42),sDn(995,1,$Zn,Wp),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return!this.c&&(!this.b&&null!=this.a.a||null!=this.a.b)},uZn.Pb=function(){if(!this.c&&!this.b&&null!=this.a.a)return this.b=!0,this.a.a;if(!this.c&&null!=this.a.b)return this.c=!0,this.a.b;throw hv(new Bv)},uZn.Qb=function(){throw this.c&&null!=this.a.b?this.a.b=null:this.b&&null!=this.a.a&&(this.a.a=null),hv(new xv)},uZn.b=!1,uZn.c=!1,zW(p9n,"Pair/1",995),sDn(455,1,{455:1},vY),uZn.Fb=function(n){return OJ(this.a,uG(n,455).a)&&OJ(this.c,uG(n,455).c)&&OJ(this.d,uG(n,455).d)&&OJ(this.b,uG(n,455).b)},uZn.Hb=function(){return Obn(Uhn(cT(dat,1),EZn,1,5,[this.a,this.c,this.d,this.b]))},uZn.Ib=function(){return"("+this.a+TZn+this.c+TZn+this.d+TZn+this.b+")"},zW(p9n,"Quadruple",455),sDn(1108,205,M3n,Xu),uZn.rf=function(n,t){var e;t.Ug("Random Layout",1),0!=(!n.a&&(n.a=new fV(bFt,n,10,11)),n.a).i?(vQn(n,(e=uG(zDn(n,(Wmn(),XRt)),17))&&0!=e.a?new v8(e.a):new Upn,sM(pK(zDn(n,URt))),sM(pK(zDn(n,zRt))),uG(zDn(n,GRt),107)),t.Vg()):t.Vg()},zW(p9n,"RandomLayoutProvider",1108),sDn(240,1,{240:1},LU),uZn.Fb=function(n){return OJ(this.a,uG(n,240).a)&&OJ(this.b,uG(n,240).b)&&OJ(this.c,uG(n,240).c)},uZn.Hb=function(){return Obn(Uhn(cT(dat,1),EZn,1,5,[this.a,this.b,this.c]))},uZn.Ib=function(){return"("+this.a+TZn+this.b+TZn+this.c+")"},zW(p9n,"Triple",240),sDn(562,1,{}),uZn.Lf=function(){return new MO(this.f.i,this.f.j)},uZn.of=function(n){return QZ(n,(XYn(),uDt))?zDn(this.f,$Kt):zDn(this.f,n)},uZn.Mf=function(){return new MO(this.f.g,this.f.f)},uZn.Nf=function(){return this.g},uZn.pf=function(n){return vnn(this.f,n)},uZn.Of=function(n){ycn(this.f,n.a),Mcn(this.f,n.b)},uZn.Pf=function(n){kcn(this.f,n.a),vcn(this.f,n.b)},uZn.Qf=function(n){this.g=n},uZn.g=0,zW(Ctt,"ElkGraphAdapters/AbstractElkGraphElementAdapter",562),sDn(563,1,{853:1},Qp),uZn.Rf=function(){var n,t;if(!this.b)for(this.b=o6(xJ(this.a).i),t=new DD(xJ(this.a));t.e!=t.i.gc();)n=uG(Zkn(t),135),kD(this.b,new Wy(n));return this.b},uZn.b=null,zW(Ctt,"ElkGraphAdapters/ElkEdgeAdapter",563),sDn(289,562,{},Vy),uZn.Sf=function(){return FTn(this)},uZn.a=null,zW(Ctt,"ElkGraphAdapters/ElkGraphAdapter",289),sDn(640,562,{187:1},Wy),zW(Ctt,"ElkGraphAdapters/ElkLabelAdapter",640),sDn(639,562,{695:1},Wx),uZn.Rf=function(){return RTn(this)},uZn.Vf=function(){var n;return!(n=uG(zDn(this.f,(XYn(),$$t)),140))&&(n=new Nk),n},uZn.Xf=function(){return KTn(this)},uZn.Zf=function(n){var t;t=new zU(n),Myn(this.f,(XYn(),$$t),t)},uZn.$f=function(n){Myn(this.f,(XYn(),W$t),new VU(n))},uZn.Tf=function(){return this.d},uZn.Uf=function(){var n,t;if(!this.a)for(this.a=new Zm,t=new Fz(ix(tRn(uG(this.f,27)).a.Kc(),new h));hDn(t);)n=uG(N9(t),74),kD(this.a,new Qp(n));return this.a},uZn.Wf=function(){var n,t;if(!this.c)for(this.c=new Zm,t=new Fz(ix(eRn(uG(this.f,27)).a.Kc(),new h));hDn(t);)n=uG(N9(t),74),kD(this.c,new Qp(n));return this.c},uZn.Yf=function(){return 0!=wZ(uG(this.f,27)).i||oM(gK(uG(this.f,27).of((XYn(),C$t))))},uZn._f=function(){Xen(this,(vP(),NKt))},uZn.a=null,uZn.b=null,uZn.c=null,uZn.d=null,uZn.e=null,zW(Ctt,"ElkGraphAdapters/ElkNodeAdapter",639),sDn(1284,562,{852:1},Jp),uZn.Rf=function(){return rjn(this)},uZn.Uf=function(){var n,t;if(!this.a)for(this.a=iR(uG(this.f,123).hh().i),t=new DD(uG(this.f,123).hh());t.e!=t.i.gc();)n=uG(Zkn(t),74),kD(this.a,new Qp(n));return this.a},uZn.Wf=function(){var n,t;if(!this.c)for(this.c=iR(uG(this.f,123).ih().i),t=new DD(uG(this.f,123).ih());t.e!=t.i.gc();)n=uG(Zkn(t),74),kD(this.c,new Qp(n));return this.c},uZn.ag=function(){return uG(uG(this.f,123).of((XYn(),gDt)),64)},uZn.bg=function(){var n,t,e,i,r,c,a;for(i=h0(uG(this.f,123)),e=new DD(uG(this.f,123).ih());e.e!=e.i.gc();)for(a=new DD((!(n=uG(Zkn(e),74)).c&&(n.c=new f_(cFt,n,5,8)),n.c));a.e!=a.i.gc();){if(Ern(lCn(c=uG(Zkn(a),84)),i))return!0;if(lCn(c)==i&&oM(gK(zDn(n,(XYn(),I$t)))))return!0}for(t=new DD(uG(this.f,123).hh());t.e!=t.i.gc();)for(r=new DD((!(n=uG(Zkn(t),74)).b&&(n.b=new f_(cFt,n,4,7)),n.b));r.e!=r.i.gc();)if(Ern(lCn(uG(Zkn(r),84)),i))return!0;return!1},uZn.a=null,uZn.b=null,uZn.c=null,zW(Ctt,"ElkGraphAdapters/ElkPortAdapter",1284),sDn(1285,1,b2n,qu),uZn.Ne=function(n,t){return XBn(uG(n,123),uG(t,123))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(Ctt,"ElkGraphAdapters/PortComparator",1285);var xKt,RKt,KKt,FKt,_Kt,BKt,HKt,UKt,GKt,qKt,XKt,zKt,VKt,WKt,QKt,JKt,YKt,ZKt,nFt=Iq(Itt,"EObject"),tFt=Iq(Ott,Att),eFt=Iq(Ott,Ltt),iFt=Iq(Ott,Ntt),rFt=Iq(Ott,"ElkShape"),cFt=Iq(Ott,$tt),aFt=Iq(Ott,Dtt),oFt=Iq(Ott,xtt),uFt=Iq(Itt,Rtt),sFt=Iq(Itt,"EFactory"),hFt=Iq(Itt,Ktt),fFt=Iq(Itt,"EPackage"),lFt=Iq(Ott,Ftt),bFt=Iq(Ott,_tt),wFt=Iq(Ott,Btt);sDn(93,1,Htt),uZn.th=function(){return this.uh(),null},uZn.uh=function(){return null},uZn.vh=function(){return this.uh(),!1},uZn.wh=function(){return!1},uZn.xh=function(n){Msn(this,n)},zW(Utt,"BasicNotifierImpl",93),sDn(99,93,Jtt),uZn.Yh=function(){return uN(this)},uZn.yh=function(n,t){return n},uZn.zh=function(){throw hv(new Kv)},uZn.Ah=function(n){var t;return t=lMn(uG(ern(this.Dh(),this.Fh()),19)),this.Ph().Th(this,t.n,t.f,n)},uZn.Bh=function(n,t){throw hv(new Kv)},uZn.Ch=function(n,t,e){return DUn(this,n,t,e)},uZn.Dh=function(){var n;return this.zh()&&(n=this.zh().Nk())?n:this.ii()},uZn.Eh=function(){return J$n(this)},uZn.Fh=function(){throw hv(new Kv)},uZn.Gh=function(){var n,t;return!(t=this.$h().Ok())&&this.zh().Tk((jP(),t=null==(n=$1(eqn(this.Dh())))?tBt:new zx(this,n))),t},uZn.Hh=function(n,t){return n},uZn.Ih=function(n){return n.pk()?n.Lj():emn(this.Dh(),n)},uZn.Jh=function(){var n;return(n=this.zh())?n.Qk():null},uZn.Kh=function(){return this.zh()?this.zh().Nk():null},uZn.Lh=function(n,t,e){return Dyn(this,n,t,e)},uZn.Mh=function(n){return vtn(this,n)},uZn.Nh=function(n,t){return U9(this,n,t)},uZn.Oh=function(){var n;return!!(n=this.zh())&&n.Rk()},uZn.Ph=function(){throw hv(new Kv)},uZn.Qh=function(){return Kvn(this)},uZn.Rh=function(n,t,e,i){return kyn(this,n,t,i)},uZn.Sh=function(n,t,e){return uG(ern(this.Dh(),t),69).wk().zk(this,this.hi(),t-this.ji(),n,e)},uZn.Th=function(n,t,e,i){return O1(this,n,t,i)},uZn.Uh=function(n,t,e){return uG(ern(this.Dh(),t),69).wk().Ak(this,this.hi(),t-this.ji(),n,e)},uZn.Vh=function(){return!!this.zh()&&!!this.zh().Pk()},uZn.Wh=function(n){return Wkn(this,n)},uZn.Xh=function(n){return M0(this,n)},uZn.Zh=function(n){return jWn(this,n)},uZn.$h=function(){throw hv(new Kv)},uZn._h=function(){return this.zh()?this.zh().Pk():null},uZn.ai=function(){return Kvn(this)},uZn.bi=function(n,t){sLn(this,n,t)},uZn.ci=function(n){this.$h().Sk(n)},uZn.di=function(n){this.$h().Vk(n)},uZn.ei=function(n){this.$h().Uk(n)},uZn.fi=function(n,t){var e,i,r,c;return(c=this.Jh())&&n&&(t=Nyn(c.El(),this,t),c.Il(this)),(i=this.Ph())&&(PHn(this,this.Ph(),this.Fh()).Bb&P0n?(r=i.Qh())&&(n?!c&&r.Il(this):r.Hl(this)):(t=(e=this.Fh())>=0?this.Ah(t):this.Ph().Th(this,-1-e,null,t),t=this.Ch(null,-1,t))),this.di(n),t},uZn.gi=function(n){var t,e,i,r,c,a,o;if((c=emn(e=this.Dh(),n))>=(t=this.ji()))return uG(n,69).wk().Dk(this,this.hi(),c-t);if(c<=-1){if(!(a=iVn((gAn(),kBt),e,n)))throw hv(new vM(Gtt+n.xe()+ztt));if(PP(),uG(a,69).xk()||(a=_3(Nen(kBt,a))),r=uG((i=this.Ih(a))>=0?this.Lh(i,!0,!0):YNn(this,a,!0),160),(o=a.Ik())>1||-1==o)return uG(uG(r,220).Sl(n,!1),79)}else if(n.Jk())return uG((i=this.Ih(n))>=0?this.Lh(i,!1,!0):YNn(this,n,!1),79);return new jA(this,n)},uZn.hi=function(){return Wen(this)},uZn.ii=function(){return(tQ(),M_t).S},uZn.ji=function(){return iQ(this.ii())},uZn.ki=function(n){oAn(this,n)},uZn.Ib=function(){return vxn(this)},zW(Ytt,"BasicEObjectImpl",99),sDn(119,99,{110:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1}),uZn.li=function(n){return Ven(this)[n]},uZn.mi=function(n,t){uQ(Ven(this),n,t)},uZn.ni=function(n){uQ(Ven(this),n,null)},uZn.th=function(){return uG(Lsn(this,4),129)},uZn.uh=function(){throw hv(new Kv)},uZn.vh=function(){return!!(4&this.Db)},uZn.zh=function(){throw hv(new Kv)},uZn.oi=function(n){Dvn(this,2,n)},uZn.Bh=function(n,t){this.Db=t<<16|255&this.Db,this.oi(n)},uZn.Dh=function(){return e1(this)},uZn.Fh=function(){return this.Db>>16},uZn.Gh=function(){var n;return jP(),null==(n=$1(eqn(uG(Lsn(this,16),29)||this.ii())))?tBt:new zx(this,n)},uZn.wh=function(){return!(1&this.Db)},uZn.Jh=function(){return uG(Lsn(this,128),2034)},uZn.Kh=function(){return uG(Lsn(this,16),29)},uZn.Oh=function(){return!!(32&this.Db)},uZn.Ph=function(){return uG(Lsn(this,2),54)},uZn.Vh=function(){return!!(64&this.Db)},uZn.$h=function(){throw hv(new Kv)},uZn._h=function(){return uG(Lsn(this,64),288)},uZn.ci=function(n){Dvn(this,16,n)},uZn.di=function(n){Dvn(this,128,n)},uZn.ei=function(n){Dvn(this,64,n)},uZn.hi=function(){return $vn(this)},uZn.Db=0,zW(Ytt,"MinimalEObjectImpl",119),sDn(120,119,{110:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),uZn.oi=function(n){this.Cb=n},uZn.Ph=function(){return this.Cb},zW(Ytt,"MinimalEObjectImpl/Container",120),sDn(2083,120,{110:1,342:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),uZn.Lh=function(n,t,e){return ajn(this,n,t,e)},uZn.Uh=function(n,t,e){return BIn(this,n,t,e)},uZn.Wh=function(n){return j4(this,n)},uZn.bi=function(n,t){bln(this,n,t)},uZn.ii=function(){return tYn(),VKt},uZn.ki=function(n){ffn(this,n)},uZn.nf=function(){return Qkn(this)},uZn.gh=function(){return!this.o&&(this.o=new ltn((tYn(),XKt),EFt,this,0)),this.o},uZn.of=function(n){return zDn(this,n)},uZn.pf=function(n){return vnn(this,n)},uZn.qf=function(n,t){return Myn(this,n,t)},zW(Ztt,"EMapPropertyHolderImpl",2083),sDn(572,120,{110:1,377:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},ns),uZn.Lh=function(n,t,e){switch(n){case 0:return this.a;case 1:return this.b}return Dyn(this,n,t,e)},uZn.Wh=function(n){switch(n){case 0:return 0!=this.a;case 1:return 0!=this.b}return Wkn(this,n)},uZn.bi=function(n,t){switch(n){case 0:return void Scn(this,uM(pK(t)));case 1:return void pcn(this,uM(pK(t)))}sLn(this,n,t)},uZn.ii=function(){return tYn(),KKt},uZn.ki=function(n){switch(n){case 0:return void Scn(this,0);case 1:return void pcn(this,0)}oAn(this,n)},uZn.Ib=function(){var n;return 64&this.Db?vxn(this):((n=new fx(vxn(this))).a+=" (x: ",Oj(n,this.a),n.a+=", y: ",Oj(n,this.b),n.a+=")",n.a)},uZn.a=0,uZn.b=0,zW(Ztt,"ElkBendPointImpl",572),sDn(739,2083,{110:1,342:1,167:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),uZn.Lh=function(n,t,e){return Xdn(this,n,t,e)},uZn.Sh=function(n,t,e){return SCn(this,n,t,e)},uZn.Uh=function(n,t,e){return phn(this,n,t,e)},uZn.Wh=function(n){return _sn(this,n)},uZn.bi=function(n,t){CSn(this,n,t)},uZn.ii=function(){return tYn(),HKt},uZn.ki=function(n){Awn(this,n)},uZn.jh=function(){return this.k},uZn.kh=function(){return xJ(this)},uZn.Ib=function(){return Egn(this)},uZn.k=null,zW(Ztt,"ElkGraphElementImpl",739),sDn(740,739,{110:1,342:1,167:1,422:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),uZn.Lh=function(n,t,e){return spn(this,n,t,e)},uZn.Wh=function(n){return Kpn(this,n)},uZn.bi=function(n,t){ISn(this,n,t)},uZn.ii=function(){return tYn(),zKt},uZn.ki=function(n){Tmn(this,n)},uZn.lh=function(){return this.f},uZn.mh=function(){return this.g},uZn.nh=function(){return this.i},uZn.oh=function(){return this.j},uZn.ph=function(n,t){vN(this,n,t)},uZn.qh=function(n,t){kN(this,n,t)},uZn.rh=function(n){ycn(this,n)},uZn.sh=function(n){Mcn(this,n)},uZn.Ib=function(){return rOn(this)},uZn.f=0,uZn.g=0,uZn.i=0,uZn.j=0,zW(Ztt,"ElkShapeImpl",740),sDn(741,740,{110:1,342:1,84:1,167:1,422:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1}),uZn.Lh=function(n,t,e){return SMn(this,n,t,e)},uZn.Sh=function(n,t,e){return tSn(this,n,t,e)},uZn.Uh=function(n,t,e){return eSn(this,n,t,e)},uZn.Wh=function(n){return iln(this,n)},uZn.bi=function(n,t){SDn(this,n,t)},uZn.ii=function(){return tYn(),FKt},uZn.ki=function(n){yyn(this,n)},uZn.hh=function(){return!this.d&&(this.d=new f_(aFt,this,8,5)),this.d},uZn.ih=function(){return!this.e&&(this.e=new f_(aFt,this,7,4)),this.e},zW(Ztt,"ElkConnectableShapeImpl",741),sDn(326,739,{110:1,342:1,74:1,167:1,326:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},es),uZn.Ah=function(n){return sEn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 3:return s0(this);case 4:return!this.b&&(this.b=new f_(cFt,this,4,7)),this.b;case 5:return!this.c&&(this.c=new f_(cFt,this,5,8)),this.c;case 6:return!this.a&&(this.a=new fV(oFt,this,6,6)),this.a;case 7:return qx(),!this.b&&(this.b=new f_(cFt,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new f_(cFt,this,5,8)),this.c.i<=1));case 8:return qx(),!!z$n(this);case 9:return qx(),!!BNn(this);case 10:return qx(),!this.b&&(this.b=new f_(cFt,this,4,7)),0!=this.b.i&&(!this.c&&(this.c=new f_(cFt,this,5,8)),0!=this.c.i)}return Xdn(this,n,t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 3:return this.Cb&&(e=(i=this.Db>>16)>=0?sEn(this,e):this.Cb.Th(this,-1-i,null,e)),nF(this,uG(n,27),e);case 4:return!this.b&&(this.b=new f_(cFt,this,4,7)),Nmn(this.b,n,e);case 5:return!this.c&&(this.c=new f_(cFt,this,5,8)),Nmn(this.c,n,e);case 6:return!this.a&&(this.a=new fV(oFt,this,6,6)),Nmn(this.a,n,e)}return SCn(this,n,t,e)},uZn.Uh=function(n,t,e){switch(t){case 3:return nF(this,null,e);case 4:return!this.b&&(this.b=new f_(cFt,this,4,7)),Nyn(this.b,n,e);case 5:return!this.c&&(this.c=new f_(cFt,this,5,8)),Nyn(this.c,n,e);case 6:return!this.a&&(this.a=new fV(oFt,this,6,6)),Nyn(this.a,n,e)}return phn(this,n,t,e)},uZn.Wh=function(n){switch(n){case 3:return!!s0(this);case 4:return!!this.b&&0!=this.b.i;case 5:return!!this.c&&0!=this.c.i;case 6:return!!this.a&&0!=this.a.i;case 7:return!this.b&&(this.b=new f_(cFt,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new f_(cFt,this,5,8)),this.c.i<=1));case 8:return z$n(this);case 9:return BNn(this);case 10:return!this.b&&(this.b=new f_(cFt,this,4,7)),0!=this.b.i&&(!this.c&&(this.c=new f_(cFt,this,5,8)),0!=this.c.i)}return _sn(this,n)},uZn.bi=function(n,t){switch(n){case 3:return void ARn(this,uG(t,27));case 4:return!this.b&&(this.b=new f_(cFt,this,4,7)),Czn(this.b),!this.b&&(this.b=new f_(cFt,this,4,7)),void CW(this.b,uG(t,16));case 5:return!this.c&&(this.c=new f_(cFt,this,5,8)),Czn(this.c),!this.c&&(this.c=new f_(cFt,this,5,8)),void CW(this.c,uG(t,16));case 6:return!this.a&&(this.a=new fV(oFt,this,6,6)),Czn(this.a),!this.a&&(this.a=new fV(oFt,this,6,6)),void CW(this.a,uG(t,16))}CSn(this,n,t)},uZn.ii=function(){return tYn(),_Kt},uZn.ki=function(n){switch(n){case 3:return void ARn(this,null);case 4:return!this.b&&(this.b=new f_(cFt,this,4,7)),void Czn(this.b);case 5:return!this.c&&(this.c=new f_(cFt,this,5,8)),void Czn(this.c);case 6:return!this.a&&(this.a=new fV(oFt,this,6,6)),void Czn(this.a)}Awn(this,n)},uZn.Ib=function(){return SXn(this)},zW(Ztt,"ElkEdgeImpl",326),sDn(452,2083,{110:1,342:1,166:1,452:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},is),uZn.Ah=function(n){return zjn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 1:return this.j;case 2:return this.k;case 3:return this.b;case 4:return this.c;case 5:return!this.a&&(this.a=new MD(eFt,this,5)),this.a;case 6:return f0(this);case 7:return t?fMn(this):this.i;case 8:return t?hMn(this):this.f;case 9:return!this.g&&(this.g=new f_(oFt,this,9,10)),this.g;case 10:return!this.e&&(this.e=new f_(oFt,this,10,9)),this.e;case 11:return this.d}return ajn(this,n,t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?zjn(this,e):this.Cb.Th(this,-1-i,null,e)),ZK(this,uG(n,74),e);case 9:return!this.g&&(this.g=new f_(oFt,this,9,10)),Nmn(this.g,n,e);case 10:return!this.e&&(this.e=new f_(oFt,this,10,9)),Nmn(this.e,n,e)}return uG(ern(uG(Lsn(this,16),29)||(tYn(),BKt),t),69).wk().zk(this,$vn(this),t-iQ((tYn(),BKt)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 5:return!this.a&&(this.a=new MD(eFt,this,5)),Nyn(this.a,n,e);case 6:return ZK(this,null,e);case 9:return!this.g&&(this.g=new f_(oFt,this,9,10)),Nyn(this.g,n,e);case 10:return!this.e&&(this.e=new f_(oFt,this,10,9)),Nyn(this.e,n,e)}return BIn(this,n,t,e)},uZn.Wh=function(n){switch(n){case 1:return 0!=this.j;case 2:return 0!=this.k;case 3:return 0!=this.b;case 4:return 0!=this.c;case 5:return!!this.a&&0!=this.a.i;case 6:return!!f0(this);case 7:return!!this.i;case 8:return!!this.f;case 9:return!!this.g&&0!=this.g.i;case 10:return!!this.e&&0!=this.e.i;case 11:return null!=this.d}return j4(this,n)},uZn.bi=function(n,t){switch(n){case 1:return void Tcn(this,uM(pK(t)));case 2:return void Ecn(this,uM(pK(t)));case 3:return void mcn(this,uM(pK(t)));case 4:return void jcn(this,uM(pK(t)));case 5:return!this.a&&(this.a=new MD(eFt,this,5)),Czn(this.a),!this.a&&(this.a=new MD(eFt,this,5)),void CW(this.a,uG(t,16));case 6:return void ORn(this,uG(t,74));case 7:return void zan(this,uG(t,84));case 8:return void Xan(this,uG(t,84));case 9:return!this.g&&(this.g=new f_(oFt,this,9,10)),Czn(this.g),!this.g&&(this.g=new f_(oFt,this,9,10)),void CW(this.g,uG(t,16));case 10:return!this.e&&(this.e=new f_(oFt,this,10,9)),Czn(this.e),!this.e&&(this.e=new f_(oFt,this,10,9)),void CW(this.e,uG(t,16));case 11:return void fon(this,mK(t))}bln(this,n,t)},uZn.ii=function(){return tYn(),BKt},uZn.ki=function(n){switch(n){case 1:return void Tcn(this,0);case 2:return void Ecn(this,0);case 3:return void mcn(this,0);case 4:return void jcn(this,0);case 5:return!this.a&&(this.a=new MD(eFt,this,5)),void Czn(this.a);case 6:return void ORn(this,null);case 7:return void zan(this,null);case 8:return void Xan(this,null);case 9:return!this.g&&(this.g=new f_(oFt,this,9,10)),void Czn(this.g);case 10:return!this.e&&(this.e=new f_(oFt,this,10,9)),void Czn(this.e);case 11:return void fon(this,null)}ffn(this,n)},uZn.Ib=function(){return A$n(this)},uZn.b=0,uZn.c=0,uZn.d=null,uZn.j=0,uZn.k=0,zW(Ztt,"ElkEdgeSectionImpl",452),sDn(158,120,{110:1,94:1,93:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1}),uZn.Lh=function(n,t,e){return 0==n?(!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab):$tn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t,e)},uZn.Sh=function(n,t,e){return 0==t?(!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e)):uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().zk(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Uh=function(n,t,e){return 0==t?(!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e)):uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().Ak(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Wh=function(n){return 0==n?!!this.Ab&&0!=this.Ab.i:l5(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.Zh=function(n){return VQn(this,n)},uZn.bi=function(n,t){if(0===n)return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));lpn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t)},uZn.di=function(n){Dvn(this,128,n)},uZn.ii=function(){return YYn(),$_t},uZn.ki=function(n){if(0===n)return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);sdn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.pi=function(){this.Bb|=1},uZn.qi=function(n){return qUn(this,n)},uZn.Bb=0,zW(Ytt,"EModelElementImpl",158),sDn(720,158,{110:1,94:1,93:1,480:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1},Fl),uZn.ri=function(n,t){return cWn(this,n,t)},uZn.si=function(n){var t,e,i,r;if(this.a!=Hrn(n)||256&n.Bb)throw hv(new vM(cet+n.zb+eet));for(e=n1(n);0!=z5(e.a).i;){if(_Tn(t=uG(yVn(e,0,F$(r=uG(zrn(z5(e.a),0),89).c,90)?uG(r,29):(YYn(),x_t)),29)))return uG(i=Hrn(t).wi().si(t),54).ci(n),i;e=n1(t)}return"java.util.Map$Entry"==(null!=n.D?n.D:n.B)?new Eq(n):new BG(n)},uZn.ti=function(n,t){return cYn(this,n,t)},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.a}return $tn(this,n-iQ((YYn(),A_t)),ern(uG(Lsn(this,16),29)||A_t,n),t,e)},uZn.Sh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 1:return this.a&&(e=uG(this.a,54).Th(this,4,fFt,e)),ywn(this,uG(n,241),e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),A_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),A_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 1:return ywn(this,null,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),A_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),A_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return!!this.a}return l5(this,n-iQ((YYn(),A_t)),ern(uG(Lsn(this,16),29)||A_t,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void yIn(this,uG(t,241))}lpn(this,n-iQ((YYn(),A_t)),ern(uG(Lsn(this,16),29)||A_t,n),t)},uZn.ii=function(){return YYn(),A_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void yIn(this,null)}sdn(this,n-iQ((YYn(),A_t)),ern(uG(Lsn(this,16),29)||A_t,n))},zW(Ytt,"EFactoryImpl",720),sDn(1037,720,{110:1,2113:1,94:1,93:1,480:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1},rs),uZn.ri=function(n,t){switch(n.hk()){case 12:return uG(t,149).Pg();case 13:return cpn(t);default:throw hv(new vM(tet+n.xe()+eet))}},uZn.si=function(n){var t;switch(-1==n.G&&(n.G=(t=Hrn(n))?Hyn(t.vi(),n):-1),n.G){case 4:return new cs;case 6:return new Bk;case 7:return new Hk;case 8:return new es;case 9:return new ns;case 10:return new is;case 11:return new as;default:throw hv(new vM(cet+n.zb+eet))}},uZn.ti=function(n,t){switch(n.hk()){case 13:case 12:return null;default:throw hv(new vM(tet+n.xe()+eet))}},zW(Ztt,"ElkGraphFactoryImpl",1037),sDn(448,158,{110:1,94:1,93:1,155:1,197:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1}),uZn.Gh=function(){var n;return null==(n=$1(eqn(uG(Lsn(this,16),29)||this.ii())))?(jP(),jP(),tBt):new VR(this,n)},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.xe()}return $tn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb}return l5(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void this.ui(mK(t))}lpn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t)},uZn.ii=function(){return YYn(),D_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void this.ui(null)}sdn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.xe=function(){return this.zb},uZn.ui=function(n){qon(this,n)},uZn.Ib=function(){return Wwn(this)},uZn.zb=null,zW(Ytt,"ENamedElementImpl",448),sDn(184,448,{110:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,54:1,99:1,158:1,184:1,119:1,120:1,690:1},aZ),uZn.Ah=function(n){return Jjn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.yb;case 3:return this.xb;case 4:return this.sb;case 5:return!this.rb&&(this.rb=new vV(this,s_t,this)),this.rb;case 6:return!this.vb&&(this.vb=new i_(fFt,this,6,7)),this.vb;case 7:return t?this.Db>>16==7?uG(this.Cb,241):null:$0(this)}return $tn(this,n-iQ((YYn(),F_t)),ern(uG(Lsn(this,16),29)||F_t,n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 4:return this.sb&&(e=uG(this.sb,54).Th(this,1,sFt,e)),Jwn(this,uG(n,480),e);case 5:return!this.rb&&(this.rb=new vV(this,s_t,this)),Nmn(this.rb,n,e);case 6:return!this.vb&&(this.vb=new i_(fFt,this,6,7)),Nmn(this.vb,n,e);case 7:return this.Cb&&(e=(i=this.Db>>16)>=0?Jjn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,7,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),F_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),F_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 4:return Jwn(this,null,e);case 5:return!this.rb&&(this.rb=new vV(this,s_t,this)),Nyn(this.rb,n,e);case 6:return!this.vb&&(this.vb=new i_(fFt,this,6,7)),Nyn(this.vb,n,e);case 7:return DUn(this,null,7,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),F_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),F_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.yb;case 3:return null!=this.xb;case 4:return!!this.sb;case 5:return!!this.rb&&0!=this.rb.i;case 6:return!!this.vb&&0!=this.vb.i;case 7:return!!$0(this)}return l5(this,n-iQ((YYn(),F_t)),ern(uG(Lsn(this,16),29)||F_t,n))},uZn.Zh=function(n){return jKn(this,n)||VQn(this,n)},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void qon(this,mK(t));case 2:return void zon(this,mK(t));case 3:return void Xon(this,mK(t));case 4:return void HIn(this,uG(t,480));case 5:return!this.rb&&(this.rb=new vV(this,s_t,this)),Czn(this.rb),!this.rb&&(this.rb=new vV(this,s_t,this)),void CW(this.rb,uG(t,16));case 6:return!this.vb&&(this.vb=new i_(fFt,this,6,7)),Czn(this.vb),!this.vb&&(this.vb=new i_(fFt,this,6,7)),void CW(this.vb,uG(t,16))}lpn(this,n-iQ((YYn(),F_t)),ern(uG(Lsn(this,16),29)||F_t,n),t)},uZn.ei=function(n){var t,e;if(n&&this.rb)for(e=new DD(this.rb);e.e!=e.i.gc();)F$(t=Zkn(e),364)&&(uG(t,364).w=null);Dvn(this,64,n)},uZn.ii=function(){return YYn(),F_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void qon(this,null);case 2:return void zon(this,null);case 3:return void Xon(this,null);case 4:return void HIn(this,null);case 5:return!this.rb&&(this.rb=new vV(this,s_t,this)),void Czn(this.rb);case 6:return!this.vb&&(this.vb=new i_(fFt,this,6,7)),void Czn(this.vb)}sdn(this,n-iQ((YYn(),F_t)),ern(uG(Lsn(this,16),29)||F_t,n))},uZn.pi=function(){ojn(this)},uZn.vi=function(){return!this.rb&&(this.rb=new vV(this,s_t,this)),this.rb},uZn.wi=function(){return this.sb},uZn.xi=function(){return this.ub},uZn.yi=function(){return this.xb},uZn.zi=function(){return this.yb},uZn.Ai=function(n){this.ub=n},uZn.Ib=function(){var n;return 64&this.Db?Wwn(this):((n=new fx(Wwn(this))).a+=" (nsURI: ",VA(n,this.yb),n.a+=", nsPrefix: ",VA(n,this.xb),n.a+=")",n.a)},uZn.xb=null,uZn.yb=null,zW(Ytt,"EPackageImpl",184),sDn(569,184,{110:1,2115:1,569:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,54:1,99:1,158:1,184:1,119:1,120:1,690:1},iDn),uZn.q=!1,uZn.r=!1;var dFt=!1;zW(Ztt,"ElkGraphPackageImpl",569),sDn(366,740,{110:1,342:1,167:1,135:1,422:1,366:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},cs),uZn.Ah=function(n){return Vjn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 7:return x0(this);case 8:return this.a}return spn(this,n,t,e)},uZn.Sh=function(n,t,e){var i;return 7===t?(this.Cb&&(e=(i=this.Db>>16)>=0?Vjn(this,e):this.Cb.Th(this,-1-i,null,e)),dz(this,uG(n,167),e)):SCn(this,n,t,e)},uZn.Uh=function(n,t,e){return 7==t?dz(this,null,e):phn(this,n,t,e)},uZn.Wh=function(n){switch(n){case 7:return!!x0(this);case 8:return!m_("",this.a)}return Kpn(this,n)},uZn.bi=function(n,t){switch(n){case 7:return void vKn(this,uG(t,167));case 8:return void Van(this,mK(t))}ISn(this,n,t)},uZn.ii=function(){return tYn(),UKt},uZn.ki=function(n){switch(n){case 7:return void vKn(this,null);case 8:return void Van(this,"")}Tmn(this,n)},uZn.Ib=function(){return zOn(this)},uZn.a="",zW(Ztt,"ElkLabelImpl",366),sDn(207,741,{110:1,342:1,84:1,167:1,27:1,422:1,207:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},Bk),uZn.Ah=function(n){return hEn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 9:return!this.c&&(this.c=new fV(wFt,this,9,9)),this.c;case 10:return!this.a&&(this.a=new fV(bFt,this,10,11)),this.a;case 11:return R0(this);case 12:return!this.b&&(this.b=new fV(aFt,this,12,3)),this.b;case 13:return qx(),!this.a&&(this.a=new fV(bFt,this,10,11)),this.a.i>0}return SMn(this,n,t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 9:return!this.c&&(this.c=new fV(wFt,this,9,9)),Nmn(this.c,n,e);case 10:return!this.a&&(this.a=new fV(bFt,this,10,11)),Nmn(this.a,n,e);case 11:return this.Cb&&(e=(i=this.Db>>16)>=0?hEn(this,e):this.Cb.Th(this,-1-i,null,e)),n_(this,uG(n,27),e);case 12:return!this.b&&(this.b=new fV(aFt,this,12,3)),Nmn(this.b,n,e)}return tSn(this,n,t,e)},uZn.Uh=function(n,t,e){switch(t){case 9:return!this.c&&(this.c=new fV(wFt,this,9,9)),Nyn(this.c,n,e);case 10:return!this.a&&(this.a=new fV(bFt,this,10,11)),Nyn(this.a,n,e);case 11:return n_(this,null,e);case 12:return!this.b&&(this.b=new fV(aFt,this,12,3)),Nyn(this.b,n,e)}return eSn(this,n,t,e)},uZn.Wh=function(n){switch(n){case 9:return!!this.c&&0!=this.c.i;case 10:return!!this.a&&0!=this.a.i;case 11:return!!R0(this);case 12:return!!this.b&&0!=this.b.i;case 13:return!this.a&&(this.a=new fV(bFt,this,10,11)),this.a.i>0}return iln(this,n)},uZn.bi=function(n,t){switch(n){case 9:return!this.c&&(this.c=new fV(wFt,this,9,9)),Czn(this.c),!this.c&&(this.c=new fV(wFt,this,9,9)),void CW(this.c,uG(t,16));case 10:return!this.a&&(this.a=new fV(bFt,this,10,11)),Czn(this.a),!this.a&&(this.a=new fV(bFt,this,10,11)),void CW(this.a,uG(t,16));case 11:return void GRn(this,uG(t,27));case 12:return!this.b&&(this.b=new fV(aFt,this,12,3)),Czn(this.b),!this.b&&(this.b=new fV(aFt,this,12,3)),void CW(this.b,uG(t,16))}SDn(this,n,t)},uZn.ii=function(){return tYn(),GKt},uZn.ki=function(n){switch(n){case 9:return!this.c&&(this.c=new fV(wFt,this,9,9)),void Czn(this.c);case 10:return!this.a&&(this.a=new fV(bFt,this,10,11)),void Czn(this.a);case 11:return void GRn(this,null);case 12:return!this.b&&(this.b=new fV(aFt,this,12,3)),void Czn(this.b)}yyn(this,n)},uZn.Ib=function(){return zBn(this)},zW(Ztt,"ElkNodeImpl",207),sDn(193,741,{110:1,342:1,84:1,167:1,123:1,422:1,193:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},Hk),uZn.Ah=function(n){return Wjn(this,n)},uZn.Lh=function(n,t,e){return 9==n?h0(this):SMn(this,n,t,e)},uZn.Sh=function(n,t,e){var i;return 9===t?(this.Cb&&(e=(i=this.Db>>16)>=0?Wjn(this,e):this.Cb.Th(this,-1-i,null,e)),tF(this,uG(n,27),e)):tSn(this,n,t,e)},uZn.Uh=function(n,t,e){return 9==t?tF(this,null,e):eSn(this,n,t,e)},uZn.Wh=function(n){return 9==n?!!h0(this):iln(this,n)},uZn.bi=function(n,t){9!==n?SDn(this,n,t):LRn(this,uG(t,27))},uZn.ii=function(){return tYn(),qKt},uZn.ki=function(n){9!==n?yyn(this,n):LRn(this,null)},uZn.Ib=function(){return VBn(this)},zW(Ztt,"ElkPortImpl",193);var gFt=Iq(Pet,"BasicEMap/Entry");sDn(1122,120,{110:1,44:1,94:1,93:1,136:1,58:1,114:1,54:1,99:1,119:1,120:1},as),uZn.Fb=function(n){return this===n},uZn.ld=function(){return this.b},uZn.Hb=function(){return xx(this)},uZn.Di=function(n){Wan(this,uG(n,149))},uZn.Lh=function(n,t,e){switch(n){case 0:return this.b;case 1:return this.c}return Dyn(this,n,t,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.b;case 1:return null!=this.c}return Wkn(this,n)},uZn.bi=function(n,t){switch(n){case 0:return void Wan(this,uG(t,149));case 1:return void Han(this,t)}sLn(this,n,t)},uZn.ii=function(){return tYn(),XKt},uZn.ki=function(n){switch(n){case 0:return void Wan(this,null);case 1:return void Han(this,null)}oAn(this,n)},uZn.Bi=function(){var n;return-1==this.a&&(n=this.b,this.a=n?Hon(n):0),this.a},uZn.md=function(){return this.c},uZn.Ci=function(n){this.a=n},uZn.nd=function(n){var t;return t=this.c,Han(this,n),t},uZn.Ib=function(){var n;return 64&this.Db?vxn(this):(JA(JA(JA(n=new WM,this.b?this.b.Pg():IZn),Y4n),ox(this.c)),n.a)},uZn.a=-1,uZn.c=null;var pFt,mFt,vFt,kFt,yFt,MFt,TFt,jFt,EFt=zW(Ztt,"ElkPropertyToValueMapEntryImpl",1122);sDn(996,1,{},ss),zW(Oet,"JsonAdapter",996),sDn(216,63,S1n,SM),zW(Oet,"JsonImportException",216),sDn(868,1,{},Zjn),zW(Oet,"JsonImporter",868),sDn(903,1,{},QO),zW(Oet,"JsonImporter/lambda$0$Type",903),sDn(904,1,{},JO),zW(Oet,"JsonImporter/lambda$1$Type",904),sDn(912,1,{},Yp),zW(Oet,"JsonImporter/lambda$10$Type",912),sDn(914,1,{},YO),zW(Oet,"JsonImporter/lambda$11$Type",914),sDn(915,1,{},ZO),zW(Oet,"JsonImporter/lambda$12$Type",915),sDn(921,1,{},SY),zW(Oet,"JsonImporter/lambda$13$Type",921),sDn(920,1,{},PY),zW(Oet,"JsonImporter/lambda$14$Type",920),sDn(916,1,{},nA),zW(Oet,"JsonImporter/lambda$15$Type",916),sDn(917,1,{},tA),zW(Oet,"JsonImporter/lambda$16$Type",917),sDn(918,1,{},eA),zW(Oet,"JsonImporter/lambda$17$Type",918),sDn(919,1,{},iA),zW(Oet,"JsonImporter/lambda$18$Type",919),sDn(924,1,{},Zp),zW(Oet,"JsonImporter/lambda$19$Type",924),sDn(905,1,{},nm),zW(Oet,"JsonImporter/lambda$2$Type",905),sDn(922,1,{},tm),zW(Oet,"JsonImporter/lambda$20$Type",922),sDn(923,1,{},em),zW(Oet,"JsonImporter/lambda$21$Type",923),sDn(927,1,{},im),zW(Oet,"JsonImporter/lambda$22$Type",927),sDn(925,1,{},rm),zW(Oet,"JsonImporter/lambda$23$Type",925),sDn(926,1,{},cm),zW(Oet,"JsonImporter/lambda$24$Type",926),sDn(929,1,{},am),zW(Oet,"JsonImporter/lambda$25$Type",929),sDn(928,1,{},om),zW(Oet,"JsonImporter/lambda$26$Type",928),sDn(930,1,QZn,rA),uZn.Cd=function(n){ptn(this.b,this.a,mK(n))},zW(Oet,"JsonImporter/lambda$27$Type",930),sDn(931,1,QZn,cA),uZn.Cd=function(n){mtn(this.b,this.a,mK(n))},zW(Oet,"JsonImporter/lambda$28$Type",931),sDn(932,1,{},aA),zW(Oet,"JsonImporter/lambda$29$Type",932),sDn(908,1,{},um),zW(Oet,"JsonImporter/lambda$3$Type",908),sDn(933,1,{},oA),zW(Oet,"JsonImporter/lambda$30$Type",933),sDn(934,1,{},sm),zW(Oet,"JsonImporter/lambda$31$Type",934),sDn(935,1,{},hm),zW(Oet,"JsonImporter/lambda$32$Type",935),sDn(936,1,{},fm),zW(Oet,"JsonImporter/lambda$33$Type",936),sDn(937,1,{},lm),zW(Oet,"JsonImporter/lambda$34$Type",937),sDn(870,1,{},bm),zW(Oet,"JsonImporter/lambda$35$Type",870),sDn(941,1,{},DU),zW(Oet,"JsonImporter/lambda$36$Type",941),sDn(938,1,QZn,wm),uZn.Cd=function(n){V8(this.a,uG(n,377))},zW(Oet,"JsonImporter/lambda$37$Type",938),sDn(939,1,QZn,sA),uZn.Cd=function(n){vA(this.a,this.b,uG(n,166))},zW(Oet,"JsonImporter/lambda$38$Type",939),sDn(940,1,QZn,hA),uZn.Cd=function(n){kA(this.a,this.b,uG(n,166))},zW(Oet,"JsonImporter/lambda$39$Type",940),sDn(906,1,{},dm),zW(Oet,"JsonImporter/lambda$4$Type",906),sDn(942,1,QZn,gm),uZn.Cd=function(n){W8(this.a,uG(n,8))},zW(Oet,"JsonImporter/lambda$40$Type",942),sDn(907,1,{},pm),zW(Oet,"JsonImporter/lambda$5$Type",907),sDn(911,1,{},mm),zW(Oet,"JsonImporter/lambda$6$Type",911),sDn(909,1,{},vm),zW(Oet,"JsonImporter/lambda$7$Type",909),sDn(910,1,{},km),zW(Oet,"JsonImporter/lambda$8$Type",910),sDn(913,1,{},ym),zW(Oet,"JsonImporter/lambda$9$Type",913),sDn(961,1,QZn,Mm),uZn.Cd=function(n){pQ(this.a,new QW(mK(n)))},zW(Oet,"JsonMetaDataConverter/lambda$0$Type",961),sDn(962,1,QZn,Tm),uZn.Cd=function(n){SW(this.a,uG(n,245))},zW(Oet,"JsonMetaDataConverter/lambda$1$Type",962),sDn(963,1,QZn,jm),uZn.Cd=function(n){m2(this.a,uG(n,143))},zW(Oet,"JsonMetaDataConverter/lambda$2$Type",963),sDn(964,1,QZn,Em),uZn.Cd=function(n){PW(this.a,uG(n,170))},zW(Oet,"JsonMetaDataConverter/lambda$3$Type",964),sDn(245,22,{3:1,34:1,22:1,245:1},fA);var SFt,PFt=_cn(p3n,"GraphFeature",245,Oat,brn,QU);sDn(11,1,{34:1,149:1},Cm,uF,mL,_N),uZn.Fd=function(n){return dD(this,uG(n,149))},uZn.Fb=function(n){return QZ(this,n)},uZn.Sg=function(){return Jkn(this)},uZn.Pg=function(){return this.b},uZn.Hb=function(){return pln(this.b)},uZn.Ib=function(){return this.b},zW(p3n,"Property",11),sDn(671,1,b2n,Sm),uZn.Ne=function(n,t){return wgn(this,uG(n,96),uG(t,96))},uZn.Fb=function(n){return this===n},uZn.Oe=function(){return new Zw(this)},zW(p3n,"PropertyHolderComparator",671),sDn(709,1,$Zn,Pm),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){return Mtn(this)},uZn.Qb=function(){xj()},uZn.Ob=function(){return!!this.a},zW(qet,"ElkGraphUtil/AncestorIterator",709);var CFt=Iq(Pet,"EList");sDn(70,56,{20:1,31:1,56:1,16:1,15:1,70:1,61:1}),uZn.bd=function(n,t){$dn(this,n,t)},uZn.Fc=function(n){return ttn(this,n)},uZn.cd=function(n,t){return bfn(this,n,t)},uZn.Gc=function(n){return CW(this,n)},uZn.Ii=function(){return new nR(this)},uZn.Ji=function(){return new tR(this)},uZn.Ki=function(n){return han(this,n)},uZn.Li=function(){return!0},uZn.Mi=function(n,t){},uZn.Ni=function(){},uZn.Oi=function(n,t){Ann(this,n,t)},uZn.Pi=function(n,t,e){},uZn.Qi=function(n,t){},uZn.Ri=function(n,t,e){},uZn.Fb=function(n){return G_n(this,n)},uZn.Hb=function(){return Bhn(this)},uZn.Si=function(){return!1},uZn.Kc=function(){return new DD(this)},uZn.ed=function(){return new Zx(this)},uZn.fd=function(n){var t;if(t=this.gc(),n<0||n>t)throw hv(new w_(n,t));return new QV(this,n)},uZn.Ui=function(n,t){this.Ti(n,this.dd(t))},uZn.Mc=function(n){return rin(this,n)},uZn.Wi=function(n,t){return t},uZn.hd=function(n,t){return Uyn(this,n,t)},uZn.Ib=function(){return Tpn(this)},uZn.Yi=function(){return!0},uZn.Zi=function(n,t){return gln(this,t)},zW(Pet,"AbstractEList",70),sDn(66,70,Qet,ls,Drn,Hun),uZn.Ei=function(n,t){return PCn(this,n,t)},uZn.Fi=function(n){return QMn(this,n)},uZn.Gi=function(n,t){edn(this,n,t)},uZn.Hi=function(n){z9(this,n)},uZn.$i=function(n){return Otn(this,n)},uZn.$b=function(){V9(this)},uZn.Hc=function(n){return sSn(this,n)},uZn.Xb=function(n){return zrn(this,n)},uZn._i=function(n){var t,e,i;++this.j,n>(e=null==this.g?0:this.g.length)&&(i=this.g,(t=e+(e/2|0)+4)=0&&(this.gd(t),!0)},uZn.Xi=function(n,t){return this.Dj(n,this.Zi(n,t))},uZn.gc=function(){return this.Ej()},uZn.Pc=function(){return this.Fj()},uZn.Qc=function(n){return this.Gj(n)},uZn.Ib=function(){return this.Hj()},zW(Pet,"DelegatingEList",2093),sDn(2094,2093,_it),uZn.Ei=function(n,t){return dGn(this,n,t)},uZn.Fi=function(n){return this.Ei(this.Ej(),n)},uZn.Gi=function(n,t){cDn(this,n,t)},uZn.Hi=function(n){S$n(this,n)},uZn.Li=function(){return!this.Mj()},uZn.$b=function(){_zn(this)},uZn.Ij=function(n,t,e,i,r){return new zZ(this,n,t,e,i,r)},uZn.Jj=function(n){Msn(this.jj(),n)},uZn.Kj=function(){return null},uZn.Lj=function(){return-1},uZn.jj=function(){return null},uZn.Mj=function(){return!1},uZn.Nj=function(n,t){return t},uZn.Oj=function(n,t){return t},uZn.Pj=function(){return!1},uZn.Qj=function(){return!this.Aj()},uZn.Ti=function(n,t){var e,i;return this.Pj()?(i=this.Qj(),e=pIn(this,n,t),this.Jj(this.Ij(7,xwn(t),e,n,i)),e):pIn(this,n,t)},uZn.gd=function(n){var t,e,i,r;return this.Pj()?(e=null,i=this.Qj(),t=this.Ij(4,r=Oq(this,n),null,n,i),this.Mj()&&r?(e=this.Oj(r,e))?(e.nj(t),e.oj()):this.Jj(t):e?(e.nj(t),e.oj()):this.Jj(t),r):(r=Oq(this,n),this.Mj()&&r&&(e=this.Oj(r,null))&&e.oj(),r)},uZn.Xi=function(n,t){return gGn(this,n,t)},zW(Utt,"DelegatingNotifyingListImpl",2094),sDn(152,1,Bit),uZn.nj=function(n){return kPn(this,n)},uZn.oj=function(){Cen(this)},uZn.gj=function(){return this.d},uZn.Kj=function(){return null},uZn.Rj=function(){return null},uZn.hj=function(n){return-1},uZn.ij=function(){return OFn(this)},uZn.jj=function(){return null},uZn.kj=function(){return AFn(this)},uZn.lj=function(){return this.o<0?this.o<-2?-2-this.o-1:-1:this.o},uZn.Sj=function(){return!1},uZn.mj=function(n){var t,e,i,r,c,a,o,u;switch(this.d){case 1:case 2:switch(n.gj()){case 1:case 2:if(xA(n.jj())===xA(this.jj())&&this.hj(null)==n.hj(null))return this.g=n.ij(),1==n.gj()&&(this.d=1),!0}case 4:if(4===n.gj()&&xA(n.jj())===xA(this.jj())&&this.hj(null)==n.hj(null))return a=kVn(this),c=this.o<0?this.o<-2?-2-this.o-1:-1:this.o,i=n.lj(),this.d=6,u=new Drn(2),c<=i?(ttn(u,this.n),ttn(u,n.kj()),this.g=Uhn(cT(YHt,1),W1n,28,15,[this.o=c,i+1])):(ttn(u,n.kj()),ttn(u,this.n),this.g=Uhn(cT(YHt,1),W1n,28,15,[this.o=i,c])),this.n=u,a||(this.o=-2-this.o-1),!0;break;case 6:if(4===n.gj()&&xA(n.jj())===xA(this.jj())&&this.hj(null)==n.hj(null)){for(a=kVn(this),i=n.lj(),o=uG(this.g,53),e=Inn(YHt,W1n,28,o.length+1,15,1),t=0;t>>0).toString(16))).a+=" (eventType: ",this.d){case 1:e.a+="SET";break;case 2:e.a+="UNSET";break;case 3:e.a+="ADD";break;case 5:e.a+="ADD_MANY";break;case 4:e.a+="REMOVE";break;case 6:e.a+="REMOVE_MANY";break;case 7:e.a+="MOVE";break;case 8:e.a+="REMOVING_ADAPTER";break;case 9:e.a+="RESOLVE";break;default:Aj(e,this.d)}if(pHn(this)&&(e.a+=", touch: true"),e.a+=", position: ",Aj(e,this.o<0?this.o<-2?-2-this.o-1:-1:this.o),e.a+=", notifier: ",zA(e,this.jj()),e.a+=", feature: ",zA(e,this.Kj()),e.a+=", oldValue: ",zA(e,AFn(this)),e.a+=", newValue: ",6==this.d&&F$(this.g,53)){for(t=uG(this.g,53),e.a+="[",n=0;n10?(this.b&&this.c.j==this.a||(this.b=new oX(this),this.a=this.j),cS(this.b,n)):sSn(this,n)},uZn.Yi=function(){return!0},uZn.a=0,zW(Pet,"AbstractEList/1",966),sDn(302,77,v0n,w_),zW(Pet,"AbstractEList/BasicIndexOutOfBoundsException",302),sDn(37,1,$Zn,DD),uZn.Nb=function(n){SV(this,n)},uZn.Xj=function(){if(this.i.j!=this.f)throw hv(new Fv)},uZn.Yj=function(){return Zkn(this)},uZn.Ob=function(){return this.e!=this.i.gc()},uZn.Pb=function(){return this.Yj()},uZn.Qb=function(){$Sn(this)},uZn.e=0,uZn.f=0,uZn.g=-1,zW(Pet,"AbstractEList/EIterator",37),sDn(286,37,UZn,Zx,QV),uZn.Qb=function(){$Sn(this)},uZn.Rb=function(n){Smn(this,n)},uZn.Zj=function(){var n;try{return n=this.d.Xb(--this.e),this.Xj(),this.g=this.e,n}catch(t){throw F$(t=Ehn(t),77)?(this.Xj(),hv(new Bv)):hv(t)}},uZn.$j=function(n){cTn(this,n)},uZn.Sb=function(){return 0!=this.e},uZn.Tb=function(){return this.e},uZn.Ub=function(){return this.Zj()},uZn.Vb=function(){return this.e-1},uZn.Wb=function(n){this.$j(n)},zW(Pet,"AbstractEList/EListIterator",286),sDn(355,37,$Zn,nR),uZn.Yj=function(){return nyn(this)},uZn.Qb=function(){throw hv(new Kv)},zW(Pet,"AbstractEList/NonResolvingEIterator",355),sDn(398,286,UZn,tR,N_),uZn.Rb=function(n){throw hv(new Kv)},uZn.Yj=function(){var n;try{return n=this.c.Vi(this.e),this.Xj(),this.g=this.e++,n}catch(t){throw F$(t=Ehn(t),77)?(this.Xj(),hv(new Bv)):hv(t)}},uZn.Zj=function(){var n;try{return n=this.c.Vi(--this.e),this.Xj(),this.g=this.e,n}catch(t){throw F$(t=Ehn(t),77)?(this.Xj(),hv(new Bv)):hv(t)}},uZn.Qb=function(){throw hv(new Kv)},uZn.Wb=function(n){throw hv(new Kv)},zW(Pet,"AbstractEList/NonResolvingEListIterator",398),sDn(2080,70,Git),uZn.Ei=function(n,t){var e,i,r,c,a,o,u,s,h;if(0!=(i=t.gc())){for(e=zln(this,(s=null==(u=uG(Lsn(this.a,4),129))?0:u.length)+i),(h=s-n)>0&&qGn(u,n,e,n+i,h),o=t.Kc(),c=0;ce)throw hv(new w_(n,e));return new qJ(this,n)},uZn.$b=function(){var n,t;++this.j,t=null==(n=uG(Lsn(this.a,4),129))?0:n.length,Pkn(this,null),Ann(this,t,n)},uZn.Hc=function(n){var t,e,i,r;if(null!=(t=uG(Lsn(this.a,4),129)))if(null!=n){for(i=0,r=(e=t).length;i=(e=null==(t=uG(Lsn(this.a,4),129))?0:t.length))throw hv(new w_(n,e));return t[n]},uZn.dd=function(n){var t,e,i;if(null!=(t=uG(Lsn(this.a,4),129)))if(null!=n){for(e=0,i=t.length;ee)throw hv(new w_(n,e));return new GJ(this,n)},uZn.Ti=function(n,t){var e,i,r;if(n>=(r=null==(e=lvn(this))?0:e.length))throw hv(new dM(zet+n+Vet+r));if(t>=r)throw hv(new dM(Wet+t+Vet+r));return i=e[t],n!=t&&(n0&&qGn(n,0,t,0,e),t},uZn.Qc=function(n){var t,e;return(e=null==(t=uG(Lsn(this.a,4),129))?0:t.length)>0&&(n.lengthe&&uQ(n,e,null),n},zW(Pet,"ArrayDelegatingEList",2080),sDn(1051,37,$Zn,M9),uZn.Xj=function(){if(this.b.j!=this.f||xA(uG(Lsn(this.b.a,4),129))!==xA(this.a))throw hv(new Fv)},uZn.Qb=function(){$Sn(this),this.a=uG(Lsn(this.b.a,4),129)},zW(Pet,"ArrayDelegatingEList/EIterator",1051),sDn(722,286,UZn,pV,GJ),uZn.Xj=function(){if(this.b.j!=this.f||xA(uG(Lsn(this.b.a,4),129))!==xA(this.a))throw hv(new Fv)},uZn.$j=function(n){cTn(this,n),this.a=uG(Lsn(this.b.a,4),129)},uZn.Qb=function(){$Sn(this),this.a=uG(Lsn(this.b.a,4),129)},zW(Pet,"ArrayDelegatingEList/EListIterator",722),sDn(1052,355,$Zn,T9),uZn.Xj=function(){if(this.b.j!=this.f||xA(uG(Lsn(this.b.a,4),129))!==xA(this.a))throw hv(new Fv)},zW(Pet,"ArrayDelegatingEList/NonResolvingEIterator",1052),sDn(723,398,UZn,mV,qJ),uZn.Xj=function(){if(this.b.j!=this.f||xA(uG(Lsn(this.b.a,4),129))!==xA(this.a))throw hv(new Fv)},zW(Pet,"ArrayDelegatingEList/NonResolvingEListIterator",723),sDn(615,302,v0n,pL),zW(Pet,"BasicEList/BasicIndexOutOfBoundsException",615),sDn(710,66,Qet,AA),uZn.bd=function(n,t){throw hv(new Kv)},uZn.Fc=function(n){throw hv(new Kv)},uZn.cd=function(n,t){throw hv(new Kv)},uZn.Gc=function(n){throw hv(new Kv)},uZn.$b=function(){throw hv(new Kv)},uZn._i=function(n){throw hv(new Kv)},uZn.Kc=function(){return this.Ii()},uZn.ed=function(){return this.Ji()},uZn.fd=function(n){return this.Ki(n)},uZn.Ti=function(n,t){throw hv(new Kv)},uZn.Ui=function(n,t){throw hv(new Kv)},uZn.gd=function(n){throw hv(new Kv)},uZn.Mc=function(n){throw hv(new Kv)},uZn.hd=function(n,t){throw hv(new Kv)},zW(Pet,"BasicEList/UnmodifiableEList",710),sDn(721,1,{3:1,20:1,16:1,15:1,61:1,597:1}),uZn.bd=function(n,t){Y$(this,n,uG(t,44))},uZn.Fc=function(n){return YR(this,uG(n,44))},uZn.Jc=function(n){z8(this,n)},uZn.Xb=function(n){return uG(zrn(this.c,n),136)},uZn.Ti=function(n,t){return uG(this.c.Ti(n,t),44)},uZn.Ui=function(n,t){Z$(this,n,uG(t,44))},uZn.Lc=function(){return new fX(null,new h3(this,16))},uZn.gd=function(n){return uG(this.c.gd(n),44)},uZn.hd=function(n,t){return EW(this,n,uG(t,44))},uZn.jd=function(n){Lon(this,n)},uZn.Nc=function(){return new h3(this,16)},uZn.Oc=function(){return new fX(null,new h3(this,16))},uZn.cd=function(n,t){return this.c.cd(n,t)},uZn.Gc=function(n){return this.c.Gc(n)},uZn.$b=function(){this.c.$b()},uZn.Hc=function(n){return this.c.Hc(n)},uZn.Ic=function(n){return yhn(this.c,n)},uZn._j=function(){var n,t;if(null==this.d){for(this.d=Inn(IFt,qit,66,2*this.f+1,0,1),t=this.e,this.f=0,n=this.c.Kc();n.e!=n.i.gc();)bMn(this,uG(n.Yj(),136));this.e=t}},uZn.Fb=function(n){return H_(this,n)},uZn.Hb=function(){return Bhn(this.c)},uZn.dd=function(n){return this.c.dd(n)},uZn.ak=function(){this.c=new Im(this)},uZn.dc=function(){return 0==this.f},uZn.Kc=function(){return this.c.Kc()},uZn.ed=function(){return this.c.ed()},uZn.fd=function(n){return this.c.fd(n)},uZn.bk=function(){return Tnn(this)},uZn.ck=function(n,t,e){return new xU(n,t,e)},uZn.dk=function(){return new ws},uZn.Mc=function(n){return uan(this,n)},uZn.gc=function(){return this.f},uZn.kd=function(n,t){return new C2(this.c,n,t)},uZn.Pc=function(){return this.c.Pc()},uZn.Qc=function(n){return this.c.Qc(n)},uZn.Ib=function(){return Tpn(this.c)},uZn.e=0,uZn.f=0,zW(Pet,"BasicEMap",721),sDn(1046,66,Qet,Im),uZn.Mi=function(n,t){Qv(this,uG(t,136))},uZn.Pi=function(n,t,e){var i;++(i=this,uG(t,136),i).a.e},uZn.Qi=function(n,t){Jv(this,uG(t,136))},uZn.Ri=function(n,t,e){fR(this,uG(t,136),uG(e,136))},uZn.Oi=function(n,t){Osn(this.a)},zW(Pet,"BasicEMap/1",1046),sDn(1047,66,Qet,ws),uZn.aj=function(n){return Inn(FFt,Xit,621,n,0,1)},zW(Pet,"BasicEMap/2",1047),sDn(1048,KZn,FZn,Om),uZn.$b=function(){this.a.c.$b()},uZn.Hc=function(n){return ymn(this.a,n)},uZn.Kc=function(){return 0==this.a.f?(EK(),KFt.a):new aj(this.a)},uZn.Mc=function(n){var t;return t=this.a.f,Svn(this.a,n),this.a.f!=t},uZn.gc=function(){return this.a.f},zW(Pet,"BasicEMap/3",1048),sDn(1049,31,RZn,Am),uZn.$b=function(){this.a.c.$b()},uZn.Hc=function(n){return q_n(this.a,n)},uZn.Kc=function(){return 0==this.a.f?(EK(),KFt.a):new oj(this.a)},uZn.gc=function(){return this.a.f},zW(Pet,"BasicEMap/4",1049),sDn(1050,KZn,FZn,Lm),uZn.$b=function(){this.a.c.$b()},uZn.Hc=function(n){var t,e,i,r,c,a,o,u,s;if(this.a.f>0&&F$(n,44)&&(this.a._j(),r=null==(o=(u=uG(n,44)).ld())?0:Hon(o),c=iF(this.a,r),t=this.a.d[c]))for(e=uG(t.g,379),s=t.i,a=0;a"+this.c},uZn.a=0;var KFt,FFt=zW(Pet,"BasicEMap/EntryImpl",621);sDn(546,1,{},ds),zW(Pet,"BasicEMap/View",546),sDn(783,1,{}),uZn.Fb=function(n){return PDn((hZ(),zot),n)},uZn.Hb=function(){return Zfn((hZ(),zot))},uZn.Ib=function(){return vIn((hZ(),zot))},zW(Pet,"ECollections/BasicEmptyUnmodifiableEList",783),sDn(1348,1,UZn,gs),uZn.Nb=function(n){SV(this,n)},uZn.Rb=function(n){throw hv(new Kv)},uZn.Ob=function(){return!1},uZn.Sb=function(){return!1},uZn.Pb=function(){throw hv(new Bv)},uZn.Tb=function(){return 0},uZn.Ub=function(){throw hv(new Bv)},uZn.Vb=function(){return-1},uZn.Qb=function(){throw hv(new Kv)},uZn.Wb=function(n){throw hv(new Kv)},zW(Pet,"ECollections/BasicEmptyUnmodifiableEList/1",1348),sDn(1346,783,{20:1,16:1,15:1,61:1},Gk),uZn.bd=function(n,t){iE()},uZn.Fc=function(n){return rE()},uZn.cd=function(n,t){return cE()},uZn.Gc=function(n){return aE()},uZn.$b=function(){oE()},uZn.Hc=function(n){return!1},uZn.Ic=function(n){return!1},uZn.Jc=function(n){z8(this,n)},uZn.Xb=function(n){return oL((hZ(),n)),null},uZn.dd=function(n){return-1},uZn.dc=function(){return!0},uZn.Kc=function(){return this.a},uZn.ed=function(){return this.a},uZn.fd=function(n){return this.a},uZn.Ti=function(n,t){return uE()},uZn.Ui=function(n,t){sE()},uZn.Lc=function(){return new fX(null,new h3(this,16))},uZn.gd=function(n){return hE()},uZn.Mc=function(n){return fE()},uZn.hd=function(n,t){return lE()},uZn.gc=function(){return 0},uZn.jd=function(n){Lon(this,n)},uZn.Nc=function(){return new h3(this,16)},uZn.Oc=function(){return new fX(null,new h3(this,16))},uZn.kd=function(n,t){return hZ(),new C2(zot,n,t)},uZn.Pc=function(){return Sz((hZ(),zot))},uZn.Qc=function(n){return hZ(),oTn(zot,n)},zW(Pet,"ECollections/EmptyUnmodifiableEList",1346),sDn(1347,783,{20:1,16:1,15:1,61:1,597:1},qk),uZn.bd=function(n,t){iE()},uZn.Fc=function(n){return rE()},uZn.cd=function(n,t){return cE()},uZn.Gc=function(n){return aE()},uZn.$b=function(){oE()},uZn.Hc=function(n){return!1},uZn.Ic=function(n){return!1},uZn.Jc=function(n){z8(this,n)},uZn.Xb=function(n){return oL((hZ(),n)),null},uZn.dd=function(n){return-1},uZn.dc=function(){return!0},uZn.Kc=function(){return this.a},uZn.ed=function(){return this.a},uZn.fd=function(n){return this.a},uZn.Ti=function(n,t){return uE()},uZn.Ui=function(n,t){sE()},uZn.Lc=function(){return new fX(null,new h3(this,16))},uZn.gd=function(n){return hE()},uZn.Mc=function(n){return fE()},uZn.hd=function(n,t){return lE()},uZn.gc=function(){return 0},uZn.jd=function(n){Lon(this,n)},uZn.Nc=function(){return new h3(this,16)},uZn.Oc=function(){return new fX(null,new h3(this,16))},uZn.kd=function(n,t){return hZ(),new C2(zot,n,t)},uZn.Pc=function(){return Sz((hZ(),zot))},uZn.Qc=function(n){return hZ(),oTn(zot,n)},uZn.bk=function(){return hZ(),hZ(),Vot},zW(Pet,"ECollections/EmptyUnmodifiableEMap",1347);var _Ft,BFt=Iq(Pet,"Enumerator");sDn(288,1,{288:1},Z_n),uZn.Fb=function(n){var t;return this===n||!!F$(n,288)&&(t=uG(n,288),this.f==t.f&&yX(this.i,t.i)&&kX(this.a,256&this.f?256&t.f?t.a:null:256&t.f?null:t.a)&&kX(this.d,t.d)&&kX(this.g,t.g)&&kX(this.e,t.e)&&Ykn(this,t))},uZn.Hb=function(){return this.f},uZn.Ib=function(){return xUn(this)},uZn.f=0;var HFt,UFt,GFt,qFt=0,XFt=0,zFt=0,VFt=0,WFt=0,QFt=0,JFt=0,YFt=0,ZFt=0,n_t=0,t_t=0,e_t=0,i_t=0;zW(Pet,"URI",288),sDn(1121,45,B0n,Xk),uZn.zc=function(n,t){return uG(r2(this,mK(n),uG(t,288)),288)},zW(Pet,"URI/URICache",1121),sDn(506,66,Qet,us,$X),uZn.Si=function(){return!0},zW(Pet,"UniqueEList",506),sDn(590,63,S1n,Pen),zW(Pet,"WrappedException",590);var r_t,c_t=Iq(Itt,Wit),a_t=Iq(Itt,Qit),o_t=Iq(Itt,Jit),u_t=Iq(Itt,Yit),s_t=Iq(Itt,Zit),h_t=Iq(Itt,"EClass"),f_t=Iq(Itt,"EDataType");sDn(1233,45,B0n,zk),uZn.xc=function(n){return RA(n)?U1(this,n):DA(FX(this.f,n))},zW(Itt,"EDataType/Internal/ConversionDelegate/Factory/Registry/Impl",1233);var l_t,b_t,w_t=Iq(Itt,"EEnum"),d_t=Iq(Itt,nrt),g_t=Iq(Itt,trt),p_t=Iq(Itt,ert),m_t=Iq(Itt,irt),v_t=Iq(Itt,rrt);sDn(1042,1,{},os),uZn.Ib=function(){return"NIL"},zW(Itt,"EStructuralFeature/Internal/DynamicValueHolder/1",1042),sDn(1041,45,B0n,Vk),uZn.xc=function(n){return RA(n)?U1(this,n):DA(FX(this.f,n))},zW(Itt,"EStructuralFeature/Internal/SettingDelegate/Factory/Registry/Impl",1041);var k_t,y_t,M_t,T_t,j_t,E_t,S_t,P_t,C_t,I_t,O_t,A_t,L_t,N_t,$_t,D_t,x_t,R_t,K_t,F_t,__t,B_t,H_t,U_t,G_t,q_t,X_t,z_t,V_t,W_t,Q_t,J_t=Iq(Itt,crt),Y_t=Iq(Itt,"EValidator/PatternMatcher"),Z_t=Iq(art,"FeatureMap/Entry");sDn(545,1,{76:1},TA),uZn.Lk=function(){return this.a},uZn.md=function(){return this.b},zW(Ytt,"BasicEObjectImpl/1",545),sDn(1040,1,ort,jA),uZn.Fk=function(n){return U9(this.a,this.b,n)},uZn.Qj=function(){return M0(this.a,this.b)},uZn.Wb=function(n){y0(this.a,this.b,n)},uZn.Gk=function(){VQ(this.a,this.b)},zW(Ytt,"BasicEObjectImpl/4",1040),sDn(2081,1,{114:1}),uZn.Mk=function(n){this.e=0==n?X_t:Inn(dat,EZn,1,n,5,1)},uZn.li=function(n){return this.e[n]},uZn.mi=function(n,t){this.e[n]=t},uZn.ni=function(n){this.e[n]=null},uZn.Nk=function(){return this.c},uZn.Ok=function(){throw hv(new Kv)},uZn.Pk=function(){throw hv(new Kv)},uZn.Qk=function(){return this.d},uZn.Rk=function(){return null!=this.e},uZn.Sk=function(n){this.c=n},uZn.Tk=function(n){throw hv(new Kv)},uZn.Uk=function(n){throw hv(new Kv)},uZn.Vk=function(n){this.d=n},zW(Ytt,"BasicEObjectImpl/EPropertiesHolderBaseImpl",2081),sDn(192,2081,{114:1},Ll),uZn.Ok=function(){return this.a},uZn.Pk=function(){return this.b},uZn.Tk=function(n){this.a=n},uZn.Uk=function(n){this.b=n},zW(Ytt,"BasicEObjectImpl/EPropertiesHolderImpl",192),sDn(516,99,Jtt,ps),uZn.uh=function(){return this.f},uZn.zh=function(){return this.k},uZn.Bh=function(n,t){this.g=n,this.i=t},uZn.Dh=function(){return 2&this.j?this.$h().Nk():this.ii()},uZn.Fh=function(){return this.i},uZn.wh=function(){return!!(1&this.j)},uZn.Ph=function(){return this.g},uZn.Vh=function(){return!!(4&this.j)},uZn.$h=function(){return!this.k&&(this.k=new Ll),this.k},uZn.ci=function(n){this.$h().Sk(n),n?this.j|=2:this.j&=-3},uZn.ei=function(n){this.$h().Uk(n),n?this.j|=4:this.j&=-5},uZn.ii=function(){return(tQ(),M_t).S},uZn.i=0,uZn.j=1,zW(Ytt,"EObjectImpl",516),sDn(798,516,{110:1,94:1,93:1,58:1,114:1,54:1,99:1},BG),uZn.li=function(n){return this.e[n]},uZn.mi=function(n,t){this.e[n]=t},uZn.ni=function(n){this.e[n]=null},uZn.Dh=function(){return this.d},uZn.Ih=function(n){return emn(this.d,n)},uZn.Kh=function(){return this.d},uZn.Oh=function(){return null!=this.e},uZn.$h=function(){return!this.k&&(this.k=new ms),this.k},uZn.ci=function(n){this.d=n},uZn.hi=function(){var n;return null==this.e&&(n=iQ(this.d),this.e=0==n?z_t:Inn(dat,EZn,1,n,5,1)),this},uZn.ji=function(){return 0},zW(Ytt,"DynamicEObjectImpl",798),sDn(1522,798,{110:1,44:1,94:1,93:1,136:1,58:1,114:1,54:1,99:1},Eq),uZn.Fb=function(n){return this===n},uZn.Hb=function(){return xx(this)},uZn.ci=function(n){this.d=n,this.b=EKn(n,"key"),this.c=EKn(n,uet)},uZn.Bi=function(){var n;return-1==this.a&&(n=zen(this,this.b),this.a=null==n?0:Hon(n)),this.a},uZn.ld=function(){return zen(this,this.b)},uZn.md=function(){return zen(this,this.c)},uZn.Ci=function(n){this.a=n},uZn.Di=function(n){y0(this,this.b,n)},uZn.nd=function(n){var t;return t=zen(this,this.c),y0(this,this.c,n),t},uZn.a=0,zW(Ytt,"DynamicEObjectImpl/BasicEMapEntry",1522),sDn(1523,1,{114:1},ms),uZn.Mk=function(n){throw hv(new Kv)},uZn.li=function(n){throw hv(new Kv)},uZn.mi=function(n,t){throw hv(new Kv)},uZn.ni=function(n){throw hv(new Kv)},uZn.Nk=function(){throw hv(new Kv)},uZn.Ok=function(){return this.a},uZn.Pk=function(){return this.b},uZn.Qk=function(){return this.c},uZn.Rk=function(){throw hv(new Kv)},uZn.Sk=function(n){throw hv(new Kv)},uZn.Tk=function(n){this.a=n},uZn.Uk=function(n){this.b=n},uZn.Vk=function(n){this.c=n},zW(Ytt,"DynamicEObjectImpl/DynamicEPropertiesHolderImpl",1523),sDn(519,158,{110:1,94:1,93:1,598:1,155:1,58:1,114:1,54:1,99:1,519:1,158:1,119:1,120:1},vs),uZn.Ah=function(n){return Yjn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.d;case 2:return e?(!this.b&&(this.b=new XR((YYn(),H_t),wBt,this)),this.b):(!this.b&&(this.b=new XR((YYn(),H_t),wBt,this)),Tnn(this.b));case 3:return F0(this);case 4:return!this.a&&(this.a=new MD(nFt,this,4)),this.a;case 5:return!this.c&&(this.c=new OD(nFt,this,5)),this.c}return $tn(this,n-iQ((YYn(),T_t)),ern(uG(Lsn(this,16),29)||T_t,n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 3:return this.Cb&&(e=(i=this.Db>>16)>=0?Yjn(this,e):this.Cb.Th(this,-1-i,null,e)),gz(this,uG(n,155),e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),T_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),T_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 2:return!this.b&&(this.b=new XR((YYn(),H_t),wBt,this)),G_(this.b,n,e);case 3:return gz(this,null,e);case 4:return!this.a&&(this.a=new MD(nFt,this,4)),Nyn(this.a,n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),T_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),T_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.d;case 2:return!!this.b&&0!=this.b.f;case 3:return!!F0(this);case 4:return!!this.a&&0!=this.a.i;case 5:return!!this.c&&0!=this.c.i}return l5(this,n-iQ((YYn(),T_t)),ern(uG(Lsn(this,16),29)||T_t,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void xq(this,mK(t));case 2:return!this.b&&(this.b=new XR((YYn(),H_t),wBt,this)),void Jun(this.b,t);case 3:return void kKn(this,uG(t,155));case 4:return!this.a&&(this.a=new MD(nFt,this,4)),Czn(this.a),!this.a&&(this.a=new MD(nFt,this,4)),void CW(this.a,uG(t,16));case 5:return!this.c&&(this.c=new OD(nFt,this,5)),Czn(this.c),!this.c&&(this.c=new OD(nFt,this,5)),void CW(this.c,uG(t,16))}lpn(this,n-iQ((YYn(),T_t)),ern(uG(Lsn(this,16),29)||T_t,n),t)},uZn.ii=function(){return YYn(),T_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void Yan(this,null);case 2:return!this.b&&(this.b=new XR((YYn(),H_t),wBt,this)),void this.b.c.$b();case 3:return void kKn(this,null);case 4:return!this.a&&(this.a=new MD(nFt,this,4)),void Czn(this.a);case 5:return!this.c&&(this.c=new OD(nFt,this,5)),void Czn(this.c)}sdn(this,n-iQ((YYn(),T_t)),ern(uG(Lsn(this,16),29)||T_t,n))},uZn.Ib=function(){return fdn(this)},uZn.d=null,zW(Ytt,"EAnnotationImpl",519),sDn(141,721,urt,ltn),uZn.Gi=function(n,t){qN(this,n,uG(t,44))},uZn.Wk=function(n,t){return U_(this,uG(n,44),t)},uZn.$i=function(n){return uG(uG(this.c,71).$i(n),136)},uZn.Ii=function(){return uG(this.c,71).Ii()},uZn.Ji=function(){return uG(this.c,71).Ji()},uZn.Ki=function(n){return uG(this.c,71).Ki(n)},uZn.Xk=function(n,t){return G_(this,n,t)},uZn.Fk=function(n){return uG(this.c,79).Fk(n)},uZn.ak=function(){},uZn.Qj=function(){return uG(this.c,79).Qj()},uZn.ck=function(n,t,e){var i;return(i=uG(Hrn(this.b).wi().si(this.b),136)).Ci(n),i.Di(t),i.nd(e),i},uZn.dk=function(){return new Vm(this)},uZn.Wb=function(n){Jun(this,n)},uZn.Gk=function(){uG(this.c,79).Gk()},zW(art,"EcoreEMap",141),sDn(165,141,urt,XR),uZn._j=function(){var n,t,e,i,r;if(null==this.d){for(r=Inn(IFt,qit,66,2*this.f+1,0,1),e=this.c.Kc();e.e!=e.i.gc();)!(n=r[i=((t=uG(e.Yj(),136)).Bi()&vZn)%r.length])&&(n=r[i]=new Vm(this)),n.Fc(t);this.d=r}},zW(Ytt,"EAnnotationImpl/1",165),sDn(292,448,{110:1,94:1,93:1,155:1,197:1,58:1,114:1,481:1,54:1,99:1,158:1,292:1,119:1,120:1}),uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return qx(),!!(256&this.Bb);case 3:return qx(),!!(512&this.Bb);case 4:return xwn(this.s);case 5:return xwn(this.t);case 6:return qx(),!!this.Jk();case 7:return qx(),this.s>=1;case 8:return t?bEn(this):this.r;case 9:return this.q}return $tn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 9:return IW(this,e)}return uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().Ak(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!(256&this.Bb);case 3:return!(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return this.Jk();case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yQ(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yQ(this.q).i)}return l5(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.bi=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void this.ui(mK(t));case 2:return void ddn(this,oM(gK(t)));case 3:return void mdn(this,oM(gK(t)));case 4:return void Pcn(this,uG(t,17).a);case 5:return void this.Zk(uG(t,17).a);case 8:return void Kbn(this,uG(t,142));case 9:return void((e=CCn(this,uG(t,89),null))&&e.oj())}lpn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t)},uZn.ii=function(){return YYn(),G_t},uZn.ki=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void this.ui(null);case 2:return void ddn(this,!0);case 3:return void mdn(this,!0);case 4:return void Pcn(this,0);case 5:return void this.Zk(1);case 8:return void Kbn(this,null);case 9:return void((t=CCn(this,null,null))&&t.oj())}sdn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.pi=function(){bEn(this),this.Bb|=1},uZn.Hk=function(){return bEn(this)},uZn.Ik=function(){return this.t},uZn.Jk=function(){var n;return(n=this.t)>1||-1==n},uZn.Si=function(){return!!(512&this.Bb)},uZn.Yk=function(n,t){return Ywn(this,n,t)},uZn.Zk=function(n){Ccn(this,n)},uZn.Ib=function(){return L$n(this)},uZn.s=0,uZn.t=1,zW(Ytt,"ETypedElementImpl",292),sDn(462,292,{110:1,94:1,93:1,155:1,197:1,58:1,179:1,69:1,114:1,481:1,54:1,99:1,158:1,462:1,292:1,119:1,120:1,692:1}),uZn.Ah=function(n){return pjn(this,n)},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return qx(),!!(256&this.Bb);case 3:return qx(),!!(512&this.Bb);case 4:return xwn(this.s);case 5:return xwn(this.t);case 6:return qx(),!!this.Jk();case 7:return qx(),this.s>=1;case 8:return t?bEn(this):this.r;case 9:return this.q;case 10:return qx(),!!(this.Bb&w1n);case 11:return qx(),!!(this.Bb&frt);case 12:return qx(),!!(this.Bb&j0n);case 13:return this.j;case 14:return NRn(this);case 15:return qx(),!!(this.Bb&hrt);case 16:return qx(),!!(this.Bb&VZn);case 17:return K0(this)}return $tn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 17:return this.Cb&&(e=(i=this.Db>>16)>=0?pjn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,17,e)}return uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().zk(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 9:return IW(this,e);case 17:return DUn(this,null,17,e)}return uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().Ak(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!(256&this.Bb);case 3:return!(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return this.Jk();case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yQ(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yQ(this.q).i);case 10:return!(this.Bb&w1n);case 11:return!!(this.Bb&frt);case 12:return!!(this.Bb&j0n);case 13:return null!=this.j;case 14:return null!=NRn(this);case 15:return!!(this.Bb&hrt);case 16:return!!(this.Bb&VZn);case 17:return!!K0(this)}return l5(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.bi=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void g2(this,mK(t));case 2:return void ddn(this,oM(gK(t)));case 3:return void mdn(this,oM(gK(t)));case 4:return void Pcn(this,uG(t,17).a);case 5:return void this.Zk(uG(t,17).a);case 8:return void Kbn(this,uG(t,142));case 9:return void((e=CCn(this,uG(t,89),null))&&e.oj());case 10:return void Wdn(this,oM(gK(t)));case 11:return void Ydn(this,oM(gK(t)));case 12:return void Qdn(this,oM(gK(t)));case 13:return void mA(this,mK(t));case 15:return void Jdn(this,oM(gK(t)));case 16:return void Cgn(this,oM(gK(t)))}lpn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t)},uZn.ii=function(){return YYn(),U_t},uZn.ki=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return F$(this.Cb,90)&&yLn(y9(uG(this.Cb,90)),4),void qon(this,null);case 2:return void ddn(this,!0);case 3:return void mdn(this,!0);case 4:return void Pcn(this,0);case 5:return void this.Zk(1);case 8:return void Kbn(this,null);case 9:return void((t=CCn(this,null,null))&&t.oj());case 10:return void Wdn(this,!0);case 11:return void Ydn(this,!1);case 12:return void Qdn(this,!1);case 13:return this.i=null,void lon(this,null);case 15:return void Jdn(this,!1);case 16:return void Cgn(this,!1)}sdn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.pi=function(){BJ(Nen((gAn(),kBt),this)),bEn(this),this.Bb|=1},uZn.pk=function(){return this.f},uZn.ik=function(){return NRn(this)},uZn.qk=function(){return K0(this)},uZn.uk=function(){return null},uZn.$k=function(){return this.k},uZn.Lj=function(){return this.n},uZn.vk=function(){return qSn(this)},uZn.wk=function(){var n,t,e,i,r,c,a,o,u;return this.p||((null==(e=K0(this)).i&&eqn(e),e.i).length,(i=this.uk())&&iQ(K0(i)),n=(a=(r=bEn(this)).kk())?1&a.i?a==ZHt?cot:a==YHt?dot:a==iUt?lot:a==eUt?fot:a==nUt?yot:a==rUt?Tot:a==tUt?uot:hot:a:null,t=NRn(this),o=r.ik(),Vgn(this),this.Bb&VZn&&((c=cSn((gAn(),kBt),e))&&c!=this||(c=_3(Nen(kBt,this))))?this.p=new SA(this,c):this.Jk()?this.al()?i?this.Bb&hrt?n?this.bl()?this.p=new CY(47,n,this,i):this.p=new CY(5,n,this,i):this.bl()?this.p=new r8(46,this,i):this.p=new r8(4,this,i):n?this.bl()?this.p=new CY(49,n,this,i):this.p=new CY(7,n,this,i):this.bl()?this.p=new r8(48,this,i):this.p=new r8(6,this,i):this.Bb&hrt?n?n==Sat?this.p=new RU(50,gFt,this):this.bl()?this.p=new RU(43,n,this):this.p=new RU(1,n,this):this.bl()?this.p=new GZ(42,this):this.p=new GZ(0,this):n?n==Sat?this.p=new RU(41,gFt,this):this.bl()?this.p=new RU(45,n,this):this.p=new RU(3,n,this):this.bl()?this.p=new GZ(44,this):this.p=new GZ(2,this):F$(r,156)?n==Z_t?this.p=new GZ(40,this):512&this.Bb?this.Bb&hrt?this.p=n?new RU(9,n,this):new GZ(8,this):this.p=n?new RU(11,n,this):new GZ(10,this):this.Bb&hrt?this.p=n?new RU(13,n,this):new GZ(12,this):this.p=n?new RU(15,n,this):new GZ(14,this):i?(u=i.t)>1||-1==u?this.bl()?this.Bb&hrt?this.p=n?new CY(25,n,this,i):new r8(24,this,i):this.p=n?new CY(27,n,this,i):new r8(26,this,i):this.Bb&hrt?this.p=n?new CY(29,n,this,i):new r8(28,this,i):this.p=n?new CY(31,n,this,i):new r8(30,this,i):this.bl()?this.Bb&hrt?this.p=n?new CY(33,n,this,i):new r8(32,this,i):this.p=n?new CY(35,n,this,i):new r8(34,this,i):this.Bb&hrt?this.p=n?new CY(37,n,this,i):new r8(36,this,i):this.p=n?new CY(39,n,this,i):new r8(38,this,i):this.bl()?this.Bb&hrt?this.p=n?new RU(17,n,this):new GZ(16,this):this.p=n?new RU(19,n,this):new GZ(18,this):this.Bb&hrt?this.p=n?new RU(21,n,this):new GZ(20,this):this.p=n?new RU(23,n,this):new GZ(22,this):this._k()?this.bl()?this.p=new KU(uG(r,29),this,i):this.p=new _1(uG(r,29),this,i):F$(r,156)?n==Z_t?this.p=new GZ(40,this):this.Bb&hrt?this.p=n?new bz(t,o,this,(Pmn(),a==YHt?hBt:a==ZHt?cBt:a==nUt?fBt:a==iUt?sBt:a==eUt?uBt:a==rUt?bBt:a==tUt?aBt:a==JHt?oBt:lBt)):new AY(uG(r,156),t,o,this):this.p=n?new lz(t,o,this,(Pmn(),a==YHt?hBt:a==ZHt?cBt:a==nUt?fBt:a==iUt?sBt:a==eUt?uBt:a==rUt?bBt:a==tUt?aBt:a==JHt?oBt:lBt)):new OY(uG(r,156),t,o,this):this.al()?i?this.Bb&hrt?this.bl()?this.p=new GU(uG(r,29),this,i):this.p=new UU(uG(r,29),this,i):this.bl()?this.p=new HU(uG(r,29),this,i):this.p=new FU(uG(r,29),this,i):this.Bb&hrt?this.bl()?this.p=new cK(uG(r,29),this):this.p=new iK(uG(r,29),this):this.bl()?this.p=new eK(uG(r,29),this):this.p=new tK(uG(r,29),this):this.bl()?i?this.Bb&hrt?this.p=new qU(uG(r,29),this,i):this.p=new _U(uG(r,29),this,i):this.Bb&hrt?this.p=new aK(uG(r,29),this):this.p=new rK(uG(r,29),this):i?this.Bb&hrt?this.p=new XU(uG(r,29),this,i):this.p=new BU(uG(r,29),this,i):this.Bb&hrt?this.p=new oK(uG(r,29),this):this.p=new OX(uG(r,29),this)),this.p},uZn.rk=function(){return!!(this.Bb&w1n)},uZn._k=function(){return!1},uZn.al=function(){return!1},uZn.sk=function(){return!!(this.Bb&VZn)},uZn.xk=function(){return ein(this)},uZn.bl=function(){return!1},uZn.tk=function(){return!!(this.Bb&hrt)},uZn.cl=function(n){this.k=n},uZn.ui=function(n){g2(this,n)},uZn.Ib=function(){return MBn(this)},uZn.e=!1,uZn.n=0,zW(Ytt,"EStructuralFeatureImpl",462),sDn(331,462,{110:1,94:1,93:1,35:1,155:1,197:1,58:1,179:1,69:1,114:1,481:1,54:1,99:1,331:1,158:1,462:1,292:1,119:1,120:1,692:1},Wk),uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return qx(),!!(256&this.Bb);case 3:return qx(),!!(512&this.Bb);case 4:return xwn(this.s);case 5:return xwn(this.t);case 6:return qx(),!!SNn(this);case 7:return qx(),this.s>=1;case 8:return t?bEn(this):this.r;case 9:return this.q;case 10:return qx(),!!(this.Bb&w1n);case 11:return qx(),!!(this.Bb&frt);case 12:return qx(),!!(this.Bb&j0n);case 13:return this.j;case 14:return NRn(this);case 15:return qx(),!!(this.Bb&hrt);case 16:return qx(),!!(this.Bb&VZn);case 17:return K0(this);case 18:return qx(),!!(this.Bb&Qtt);case 19:return t?khn(this):E7(this)}return $tn(this,n-iQ((YYn(),j_t)),ern(uG(Lsn(this,16),29)||j_t,n),t,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!(256&this.Bb);case 3:return!(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return SNn(this);case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yQ(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yQ(this.q).i);case 10:return!(this.Bb&w1n);case 11:return!!(this.Bb&frt);case 12:return!!(this.Bb&j0n);case 13:return null!=this.j;case 14:return null!=NRn(this);case 15:return!!(this.Bb&hrt);case 16:return!!(this.Bb&VZn);case 17:return!!K0(this);case 18:return!!(this.Bb&Qtt);case 19:return!!E7(this)}return l5(this,n-iQ((YYn(),j_t)),ern(uG(Lsn(this,16),29)||j_t,n))},uZn.bi=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void g2(this,mK(t));case 2:return void ddn(this,oM(gK(t)));case 3:return void mdn(this,oM(gK(t)));case 4:return void Pcn(this,uG(t,17).a);case 5:return void fj(this,uG(t,17).a);case 8:return void Kbn(this,uG(t,142));case 9:return void((e=CCn(this,uG(t,89),null))&&e.oj());case 10:return void Wdn(this,oM(gK(t)));case 11:return void Ydn(this,oM(gK(t)));case 12:return void Qdn(this,oM(gK(t)));case 13:return void mA(this,mK(t));case 15:return void Jdn(this,oM(gK(t)));case 16:return void Cgn(this,oM(gK(t)));case 18:return void Sgn(this,oM(gK(t)))}lpn(this,n-iQ((YYn(),j_t)),ern(uG(Lsn(this,16),29)||j_t,n),t)},uZn.ii=function(){return YYn(),j_t},uZn.ki=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return F$(this.Cb,90)&&yLn(y9(uG(this.Cb,90)),4),void qon(this,null);case 2:return void ddn(this,!0);case 3:return void mdn(this,!0);case 4:return void Pcn(this,0);case 5:return this.b=0,void Ccn(this,1);case 8:return void Kbn(this,null);case 9:return void((t=CCn(this,null,null))&&t.oj());case 10:return void Wdn(this,!0);case 11:return void Ydn(this,!1);case 12:return void Qdn(this,!1);case 13:return this.i=null,void lon(this,null);case 15:return void Jdn(this,!1);case 16:return void Cgn(this,!1);case 18:return void Sgn(this,!1)}sdn(this,n-iQ((YYn(),j_t)),ern(uG(Lsn(this,16),29)||j_t,n))},uZn.pi=function(){khn(this),BJ(Nen((gAn(),kBt),this)),bEn(this),this.Bb|=1},uZn.Jk=function(){return SNn(this)},uZn.Yk=function(n,t){return this.b=0,this.a=null,Ywn(this,n,t)},uZn.Zk=function(n){fj(this,n)},uZn.Ib=function(){var n;return 64&this.Db?MBn(this):((n=new fx(MBn(this))).a+=" (iD: ",Lj(n,!!(this.Bb&Qtt)),n.a+=")",n.a)},uZn.b=0,zW(Ytt,"EAttributeImpl",331),sDn(364,448,{110:1,94:1,93:1,142:1,155:1,197:1,58:1,114:1,54:1,99:1,364:1,158:1,119:1,120:1,691:1}),uZn.dl=function(n){return n.Dh()==this},uZn.Ah=function(n){return VTn(this,n)},uZn.Bh=function(n,t){this.w=null,this.Db=t<<16|255&this.Db,this.Cb=n},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return _Tn(this);case 4:return this.ik();case 5:return this.F;case 6:return t?Hrn(this):D0(this);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),this.A}return $tn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?VTn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,6,e)}return uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().zk(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 6:return DUn(this,null,6,e);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),Nyn(this.A,n,e)}return uG(ern(uG(Lsn(this,16),29)||this.ii(),t),69).wk().Ak(this,$vn(this),t-iQ(this.ii()),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!_Tn(this);case 4:return null!=this.ik();case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!D0(this);case 7:return!!this.A&&0!=this.A.i}return l5(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void d2(this,mK(t));case 2:return void pN(this,mK(t));case 5:return void TWn(this,mK(t));case 7:return!this.A&&(this.A=new PD(J_t,this,7)),Czn(this.A),!this.A&&(this.A=new PD(J_t,this,7)),void CW(this.A,uG(t,16))}lpn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n),t)},uZn.ii=function(){return YYn(),S_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return F$(this.Cb,184)&&(uG(this.Cb,184).tb=null),void qon(this,null);case 2:return sbn(this,null),void Ocn(this,this.D);case 5:return void TWn(this,null);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),void Czn(this.A)}sdn(this,n-iQ(this.ii()),ern(uG(Lsn(this,16),29)||this.ii(),n))},uZn.hk=function(){var n;return-1==this.G&&(this.G=(n=Hrn(this))?Hyn(n.vi(),this):-1),this.G},uZn.ik=function(){return null},uZn.jk=function(){return Hrn(this)},uZn.el=function(){return this.v},uZn.kk=function(){return _Tn(this)},uZn.lk=function(){return null!=this.D?this.D:this.B},uZn.mk=function(){return this.F},uZn.fk=function(n){return LGn(this,n)},uZn.fl=function(n){this.v=n},uZn.gl=function(n){tun(this,n)},uZn.hl=function(n){this.C=n},uZn.ui=function(n){d2(this,n)},uZn.Ib=function(){return pmn(this)},uZn.C=null,uZn.D=null,uZn.G=-1,zW(Ytt,"EClassifierImpl",364),sDn(90,364,{110:1,94:1,93:1,29:1,142:1,155:1,197:1,58:1,114:1,54:1,99:1,90:1,364:1,158:1,482:1,119:1,120:1,691:1},Kl),uZn.dl=function(n){return VF(this,n.Dh())},uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return _Tn(this);case 4:return null;case 5:return this.F;case 6:return t?Hrn(this):D0(this);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),this.A;case 8:return qx(),!!(256&this.Bb);case 9:return qx(),!!(512&this.Bb);case 10:return n1(this);case 11:return!this.q&&(this.q=new fV(p_t,this,11,10)),this.q;case 12:return hXn(this);case 13:return Zqn(this);case 14:return Zqn(this),this.r;case 15:return hXn(this),this.k;case 16:return RAn(this);case 17:return $qn(this);case 18:return eqn(this);case 19:return mRn(this);case 20:return hXn(this),this.o;case 21:return!this.s&&(this.s=new fV(o_t,this,21,17)),this.s;case 22:return z5(this);case 23:return x_n(this)}return $tn(this,n-iQ((YYn(),E_t)),ern(uG(Lsn(this,16),29)||E_t,n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?VTn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,6,e);case 11:return!this.q&&(this.q=new fV(p_t,this,11,10)),Nmn(this.q,n,e);case 21:return!this.s&&(this.s=new fV(o_t,this,21,17)),Nmn(this.s,n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),E_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),E_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 6:return DUn(this,null,6,e);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),Nyn(this.A,n,e);case 11:return!this.q&&(this.q=new fV(p_t,this,11,10)),Nyn(this.q,n,e);case 21:return!this.s&&(this.s=new fV(o_t,this,21,17)),Nyn(this.s,n,e);case 22:return Nyn(z5(this),n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),E_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),E_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!_Tn(this);case 4:return!1;case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!D0(this);case 7:return!!this.A&&0!=this.A.i;case 8:return!!(256&this.Bb);case 9:return!!(512&this.Bb);case 10:return!(!this.u||0==z5(this.u.a).i||this.n&&yMn(this.n));case 11:return!!this.q&&0!=this.q.i;case 12:return 0!=hXn(this).i;case 13:return 0!=Zqn(this).i;case 14:return Zqn(this),0!=this.r.i;case 15:return hXn(this),0!=this.k.i;case 16:return 0!=RAn(this).i;case 17:return 0!=$qn(this).i;case 18:return 0!=eqn(this).i;case 19:return 0!=mRn(this).i;case 20:return hXn(this),!!this.o;case 21:return!!this.s&&0!=this.s.i;case 22:return!!this.n&&yMn(this.n);case 23:return 0!=x_n(this).i}return l5(this,n-iQ((YYn(),E_t)),ern(uG(Lsn(this,16),29)||E_t,n))},uZn.Zh=function(n){return(null==this.i||this.q&&0!=this.q.i?null:EKn(this,n))||VQn(this,n)},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void d2(this,mK(t));case 2:return void pN(this,mK(t));case 5:return void TWn(this,mK(t));case 7:return!this.A&&(this.A=new PD(J_t,this,7)),Czn(this.A),!this.A&&(this.A=new PD(J_t,this,7)),void CW(this.A,uG(t,16));case 8:return void gdn(this,oM(gK(t)));case 9:return void vdn(this,oM(gK(t)));case 10:return _zn(n1(this)),void CW(n1(this),uG(t,16));case 11:return!this.q&&(this.q=new fV(p_t,this,11,10)),Czn(this.q),!this.q&&(this.q=new fV(p_t,this,11,10)),void CW(this.q,uG(t,16));case 21:return!this.s&&(this.s=new fV(o_t,this,21,17)),Czn(this.s),!this.s&&(this.s=new fV(o_t,this,21,17)),void CW(this.s,uG(t,16));case 22:return Czn(z5(this)),void CW(z5(this),uG(t,16))}lpn(this,n-iQ((YYn(),E_t)),ern(uG(Lsn(this,16),29)||E_t,n),t)},uZn.ii=function(){return YYn(),E_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return F$(this.Cb,184)&&(uG(this.Cb,184).tb=null),void qon(this,null);case 2:return sbn(this,null),void Ocn(this,this.D);case 5:return void TWn(this,null);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),void Czn(this.A);case 8:return void gdn(this,!1);case 9:return void vdn(this,!1);case 10:return void(this.u&&_zn(this.u));case 11:return!this.q&&(this.q=new fV(p_t,this,11,10)),void Czn(this.q);case 21:return!this.s&&(this.s=new fV(o_t,this,21,17)),void Czn(this.s);case 22:return void(this.n&&Czn(this.n))}sdn(this,n-iQ((YYn(),E_t)),ern(uG(Lsn(this,16),29)||E_t,n))},uZn.pi=function(){var n,t;if(hXn(this),Zqn(this),RAn(this),$qn(this),eqn(this),mRn(this),x_n(this),V9(iG(y9(this))),this.s)for(n=0,t=this.s.i;n=0;--t)zrn(this,t);return gmn(this,n)},uZn.Gk=function(){Czn(this)},uZn.Zi=function(n,t){return Dcn(this,n,t)},zW(art,"EcoreEList",632),sDn(505,632,Trt,FG),uZn.Li=function(){return!1},uZn.Lj=function(){return this.c},uZn.Mj=function(){return!1},uZn.ol=function(){return!0},uZn.Si=function(){return!0},uZn.Wi=function(n,t){return t},uZn.Yi=function(){return!1},uZn.c=0,zW(art,"EObjectEList",505),sDn(83,505,Trt,MD),uZn.Mj=function(){return!0},uZn.ml=function(){return!1},uZn.al=function(){return!0},zW(art,"EObjectContainmentEList",83),sDn(555,83,Trt,TD),uZn.Ni=function(){this.b=!0},uZn.Qj=function(){return this.b},uZn.Gk=function(){var n;Czn(this),uN(this.e)?(n=this.b,this.b=!1,Msn(this.e,new j9(this.e,2,this.c,n,!1))):this.b=!1},uZn.b=!1,zW(art,"EObjectContainmentEList/Unsettable",555),sDn(1161,555,Trt,hz),uZn.Ti=function(n,t){var e,i;return e=uG(zdn(this,n,t),89),uN(this.e)&&Yv(this,new wtn(this.a,7,(YYn(),P_t),xwn(t),F$(i=e.c,90)?uG(i,29):x_t,n)),e},uZn.Uj=function(n,t){return Dmn(this,uG(n,89),t)},uZn.Vj=function(n,t){return $mn(this,uG(n,89),t)},uZn.Wj=function(n,t,e){return TSn(this,uG(n,89),uG(t,89),e)},uZn.Ij=function(n,t,e,i,r){switch(n){case 3:return i2(this,n,t,e,i,this.i>1);case 5:return i2(this,n,t,e,i,this.i-uG(e,15).gc()>0);default:return new Ken(this.e,n,this.c,t,e,i,!0)}},uZn.Tj=function(){return!0},uZn.Qj=function(){return yMn(this)},uZn.Gk=function(){Czn(this)},zW(Ytt,"EClassImpl/1",1161),sDn(1175,1174,Fit),uZn.dj=function(n){var t,e,i,r,c,a,o;if(8!=(e=n.gj())){if(0==(i=xkn(n)))switch(e){case 1:case 9:null!=(o=n.kj())&&(!(t=y9(uG(o,482))).c&&(t.c=new Ks),rin(t.c,n.jj())),null!=(a=n.ij())&&(1&(r=uG(a,482)).Bb||(!(t=y9(r)).c&&(t.c=new Ks),ttn(t.c,uG(n.jj(),29))));break;case 3:null!=(a=n.ij())&&(1&(r=uG(a,482)).Bb||(!(t=y9(r)).c&&(t.c=new Ks),ttn(t.c,uG(n.jj(),29))));break;case 5:if(null!=(a=n.ij()))for(c=uG(a,16).Kc();c.Ob();)1&(r=uG(c.Pb(),482)).Bb||(!(t=y9(r)).c&&(t.c=new Ks),ttn(t.c,uG(n.jj(),29)));break;case 4:null!=(o=n.kj())&&(1&(r=uG(o,482)).Bb||(!(t=y9(r)).c&&(t.c=new Ks),rin(t.c,n.jj())));break;case 6:if(null!=(o=n.kj()))for(c=uG(o,16).Kc();c.Ob();)1&(r=uG(c.Pb(),482)).Bb||(!(t=y9(r)).c&&(t.c=new Ks),rin(t.c,n.jj()))}this.ql(i)}},uZn.ql=function(n){bBn(this,n)},uZn.b=63,zW(Ytt,"ESuperAdapter",1175),sDn(1176,1175,Fit,$m),uZn.ql=function(n){yLn(this,n)},zW(Ytt,"EClassImpl/10",1176),sDn(1165,710,Trt),uZn.Ei=function(n,t){return PCn(this,n,t)},uZn.Fi=function(n){return QMn(this,n)},uZn.Gi=function(n,t){edn(this,n,t)},uZn.Hi=function(n){z9(this,n)},uZn.$i=function(n){return Otn(this,n)},uZn.Xi=function(n,t){return iin(this,n,t)},uZn.Wk=function(n,t){throw hv(new Kv)},uZn.Ii=function(){return new nR(this)},uZn.Ji=function(){return new tR(this)},uZn.Ki=function(n){return han(this,n)},uZn.Xk=function(n,t){throw hv(new Kv)},uZn.Fk=function(n){return this},uZn.Qj=function(){return 0!=this.i},uZn.Wb=function(n){throw hv(new Kv)},uZn.Gk=function(){throw hv(new Kv)},zW(art,"EcoreEList/UnmodifiableEList",1165),sDn(328,1165,Trt,vL),uZn.Yi=function(){return!1},zW(art,"EcoreEList/UnmodifiableEList/FastCompare",328),sDn(1168,328,Trt,Afn),uZn.dd=function(n){var t,e;if(F$(n,179)&&-1!=(t=uG(n,179).Lj()))for(e=this.i;t4){if(!this.fk(n))return!1;if(this.al()){if(a=(t=(e=uG(n,54)).Eh())==this.b&&(this.ml()?e.yh(e.Fh(),uG(ern(e1(this.b),this.Lj()).Hk(),29).kk())==lMn(uG(ern(e1(this.b),this.Lj()),19)).n:-1-e.Fh()==this.Lj()),this.nl()&&!a&&!t&&e.Jh())for(i=0;i1||-1==e)},uZn.ml=function(){var n;return!!F$(n=ern(e1(this.b),this.Lj()),102)&&!!lMn(uG(n,19))},uZn.nl=function(){var n;return!!F$(n=ern(e1(this.b),this.Lj()),102)&&!!(uG(n,19).Bb&P0n)},uZn.dd=function(n){var t,e,i;if((e=this.zj(n))>=0)return e;if(this.ol())for(t=0,i=this.Ej();t=0;--n)yVn(this,n,this.xj(n));return this.Fj()},uZn.Qc=function(n){var t;if(this.nl())for(t=this.Ej()-1;t>=0;--t)yVn(this,t,this.xj(t));return this.Gj(n)},uZn.Gk=function(){_zn(this)},uZn.Zi=function(n,t){return Atn(this,n,t)},zW(art,"DelegatingEcoreEList",756),sDn(1171,756,Crt,aF),uZn.qj=function(n,t){zR(this,n,uG(t,29))},uZn.rj=function(n){BN(this,uG(n,29))},uZn.xj=function(n){var t;return F$(t=uG(zrn(z5(this.a),n),89).c,90)?uG(t,29):(YYn(),x_t)},uZn.Cj=function(n){var t;return F$(t=uG(e_n(z5(this.a),n),89).c,90)?uG(t,29):(YYn(),x_t)},uZn.Dj=function(n,t){return YMn(this,n,uG(t,29))},uZn.Li=function(){return!1},uZn.Ij=function(n,t,e,i,r){return null},uZn.sj=function(){return new Rm(this)},uZn.tj=function(){Czn(z5(this.a))},uZn.uj=function(n){return Mdn(this,n)},uZn.vj=function(n){var t;for(t=n.Kc();t.Ob();)if(!Mdn(this,t.Pb()))return!1;return!0},uZn.wj=function(n){var t,e,i;if(F$(n,15)&&(i=uG(n,15)).gc()==z5(this.a).i){for(t=i.Kc(),e=new DD(this);t.Ob();)if(xA(t.Pb())!==xA(Zkn(e)))return!1;return!0}return!1},uZn.yj=function(){var n,t,e,i;for(t=1,n=new DD(z5(this.a));n.e!=n.i.gc();)t=31*t+((e=F$(i=uG(Zkn(n),89).c,90)?uG(i,29):(YYn(),x_t))?xx(e):0);return t},uZn.zj=function(n){var t,e,i,r;for(i=0,e=new DD(z5(this.a));e.e!=e.i.gc();){if(t=uG(Zkn(e),89),xA(n)===xA(F$(r=t.c,90)?uG(r,29):(YYn(),x_t)))return i;++i}return-1},uZn.Aj=function(){return 0==z5(this.a).i},uZn.Bj=function(){return null},uZn.Ej=function(){return z5(this.a).i},uZn.Fj=function(){var n,t,e,i,r,c;for(c=z5(this.a).i,r=Inn(dat,EZn,1,c,5,1),e=0,t=new DD(z5(this.a));t.e!=t.i.gc();)n=uG(Zkn(t),89),r[e++]=F$(i=n.c,90)?uG(i,29):(YYn(),x_t);return r},uZn.Gj=function(n){var t,e,i,r;for(r=z5(this.a).i,n.lengthr&&uQ(n,r,null),e=0,t=new DD(z5(this.a));t.e!=t.i.gc();)uQ(n,e++,F$(i=uG(Zkn(t),89).c,90)?uG(i,29):(YYn(),x_t));return n},uZn.Hj=function(){var n,t,e,i,r;for((r=new zM).a+="[",n=z5(this.a),t=0,i=z5(this.a).i;t>16)>=0?VTn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,6,e);case 9:return!this.a&&(this.a=new fV(d_t,this,9,5)),Nmn(this.a,n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),I_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),I_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 6:return DUn(this,null,6,e);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),Nyn(this.A,n,e);case 9:return!this.a&&(this.a=new fV(d_t,this,9,5)),Nyn(this.a,n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),I_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),I_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!_Tn(this);case 4:return!!dbn(this);case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!D0(this);case 7:return!!this.A&&0!=this.A.i;case 8:return!(256&this.Bb);case 9:return!!this.a&&0!=this.a.i}return l5(this,n-iQ((YYn(),I_t)),ern(uG(Lsn(this,16),29)||I_t,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void d2(this,mK(t));case 2:return void pN(this,mK(t));case 5:return void TWn(this,mK(t));case 7:return!this.A&&(this.A=new PD(J_t,this,7)),Czn(this.A),!this.A&&(this.A=new PD(J_t,this,7)),void CW(this.A,uG(t,16));case 8:return void pdn(this,oM(gK(t)));case 9:return!this.a&&(this.a=new fV(d_t,this,9,5)),Czn(this.a),!this.a&&(this.a=new fV(d_t,this,9,5)),void CW(this.a,uG(t,16))}lpn(this,n-iQ((YYn(),I_t)),ern(uG(Lsn(this,16),29)||I_t,n),t)},uZn.ii=function(){return YYn(),I_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return F$(this.Cb,184)&&(uG(this.Cb,184).tb=null),void qon(this,null);case 2:return sbn(this,null),void Ocn(this,this.D);case 5:return void TWn(this,null);case 7:return!this.A&&(this.A=new PD(J_t,this,7)),void Czn(this.A);case 8:return void pdn(this,!0);case 9:return!this.a&&(this.a=new fV(d_t,this,9,5)),void Czn(this.a)}sdn(this,n-iQ((YYn(),I_t)),ern(uG(Lsn(this,16),29)||I_t,n))},uZn.pi=function(){var n,t;if(this.a)for(n=0,t=this.a.i;n>16==5?uG(this.Cb,685):null}return $tn(this,n-iQ((YYn(),O_t)),ern(uG(Lsn(this,16),29)||O_t,n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 5:return this.Cb&&(e=(i=this.Db>>16)>=0?Qjn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,5,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),O_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),O_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 5:return DUn(this,null,5,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),O_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),O_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0!=this.d;case 3:return!!this.b;case 4:return null!=this.c;case 5:return!(this.Db>>16!=5||!uG(this.Cb,685))}return l5(this,n-iQ((YYn(),O_t)),ern(uG(Lsn(this,16),29)||O_t,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void qon(this,mK(t));case 2:return void Icn(this,uG(t,17).a);case 3:return void h$n(this,uG(t,2039));case 4:return void Uan(this,mK(t))}lpn(this,n-iQ((YYn(),O_t)),ern(uG(Lsn(this,16),29)||O_t,n),t)},uZn.ii=function(){return YYn(),O_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void qon(this,null);case 2:return void Icn(this,0);case 3:return void h$n(this,null);case 4:return void Uan(this,null)}sdn(this,n-iQ((YYn(),O_t)),ern(uG(Lsn(this,16),29)||O_t,n))},uZn.Ib=function(){var n;return null==(n=this.c)?this.zb:n},uZn.b=null,uZn.c=null,uZn.d=0,zW(Ytt,"EEnumLiteralImpl",582);var nBt,tBt,eBt,iBt=Iq(Ytt,"EFactoryImpl/InternalEDateTimeFormat");sDn(499,1,{2114:1},Km),zW(Ytt,"EFactoryImpl/1ClientInternalEDateTimeFormat",499),sDn(248,120,{110:1,94:1,93:1,89:1,58:1,114:1,54:1,99:1,248:1,119:1,120:1},ev),uZn.Ch=function(n,t,e){var i;return e=DUn(this,n,t,e),this.e&&F$(n,179)&&(i=bRn(this,this.e))!=this.c&&(e=PWn(this,i,e)),e},uZn.Lh=function(n,t,e){switch(n){case 0:return this.f;case 1:return!this.d&&(this.d=new MD(g_t,this,1)),this.d;case 2:return t?MGn(this):this.c;case 3:return this.b;case 4:return this.e;case 5:return t?PMn(this):this.a}return $tn(this,n-iQ((YYn(),L_t)),ern(uG(Lsn(this,16),29)||L_t,n),t,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return vwn(this,null,e);case 1:return!this.d&&(this.d=new MD(g_t,this,1)),Nyn(this.d,n,e);case 3:return kwn(this,null,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),L_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),L_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.f;case 1:return!!this.d&&0!=this.d.i;case 2:return!!this.c;case 3:return!!this.b;case 4:return!!this.e;case 5:return!!this.a}return l5(this,n-iQ((YYn(),L_t)),ern(uG(Lsn(this,16),29)||L_t,n))},uZn.bi=function(n,t){switch(n){case 0:return void cPn(this,uG(t,89));case 1:return!this.d&&(this.d=new MD(g_t,this,1)),Czn(this.d),!this.d&&(this.d=new MD(g_t,this,1)),void CW(this.d,uG(t,16));case 3:return void rPn(this,uG(t,89));case 4:return void MIn(this,uG(t,850));case 5:return void Urn(this,uG(t,142))}lpn(this,n-iQ((YYn(),L_t)),ern(uG(Lsn(this,16),29)||L_t,n),t)},uZn.ii=function(){return YYn(),L_t},uZn.ki=function(n){switch(n){case 0:return void cPn(this,null);case 1:return!this.d&&(this.d=new MD(g_t,this,1)),void Czn(this.d);case 3:return void rPn(this,null);case 4:return void MIn(this,null);case 5:return void Urn(this,null)}sdn(this,n-iQ((YYn(),L_t)),ern(uG(Lsn(this,16),29)||L_t,n))},uZn.Ib=function(){var n;return(n=new lx(vxn(this))).a+=" (expression: ",XXn(this,n),n.a+=")",n.a},zW(Ytt,"EGenericTypeImpl",248),sDn(2067,2062,Irt),uZn.Gi=function(n,t){YK(this,n,t)},uZn.Wk=function(n,t){return YK(this,this.gc(),n),t},uZn.$i=function(n){return hyn(this.pj(),n)},uZn.Ii=function(){return this.Ji()},uZn.pj=function(){return new zm(this)},uZn.Ji=function(){return this.Ki(0)},uZn.Ki=function(n){return this.pj().fd(n)},uZn.Xk=function(n,t){return Wpn(this,n,!0),t},uZn.Ti=function(n,t){var e;return e=Kjn(this,t),this.fd(n).Rb(e),e},uZn.Ui=function(n,t){Wpn(this,t,!0),this.fd(n).Rb(t)},zW(art,"AbstractSequentialInternalEList",2067),sDn(496,2067,Irt,zx),uZn.$i=function(n){return hyn(this.pj(),n)},uZn.Ii=function(){return null==this.b?(EP(),EP(),eBt):this.sl()},uZn.pj=function(){return new kL(this.a,this.b)},uZn.Ji=function(){return null==this.b?(EP(),EP(),eBt):this.sl()},uZn.Ki=function(n){var t,e;if(null==this.b){if(n<0||n>1)throw hv(new dM(Hit+n+", size=0"));return EP(),EP(),eBt}for(e=this.sl(),t=0;t0;)if(t=this.c[--this.d],(!this.e||t.pk()!=tFt||0!=t.Lj())&&(!this.vl()||this.b.Xh(t)))if(c=this.b.Nh(t,this.ul()),this.f=(PP(),uG(t,69).xk()),this.f||t.Jk()){if(this.ul()?(i=uG(c,15),this.k=i):(i=uG(c,71),this.k=this.j=i),F$(this.k,59)?(this.o=this.k.gc(),this.n=this.o):this.p=this.j?this.j.Ki(this.k.gc()):this.k.fd(this.k.gc()),this.p?dAn(this,this.p):hLn(this))return r=this.p?this.p.Ub():this.j?this.j.$i(--this.n):this.k.Xb(--this.n),this.f?((n=uG(r,76)).Lk(),e=n.md(),this.i=e):(e=r,this.i=e),this.g=-3,!0}else if(null!=c)return this.k=null,this.p=null,e=c,this.i=e,this.g=-2,!0;return this.k=null,this.p=null,this.g=-1,!1}},uZn.Pb=function(){return Ksn(this)},uZn.Tb=function(){return this.a},uZn.Ub=function(){var n;if(this.g<-1||this.Sb())return--this.a,this.g=0,n=this.i,this.Sb(),n;throw hv(new Bv)},uZn.Vb=function(){return this.a-1},uZn.Qb=function(){throw hv(new Kv)},uZn.ul=function(){return!1},uZn.Wb=function(n){throw hv(new Kv)},uZn.vl=function(){return!0},uZn.a=0,uZn.d=0,uZn.f=!1,uZn.g=0,uZn.n=0,uZn.o=0,zW(art,"EContentsEList/FeatureIteratorImpl",287),sDn(711,287,Ort,WR),uZn.ul=function(){return!0},zW(art,"EContentsEList/ResolvingFeatureIteratorImpl",711),sDn(1178,711,Ort,QR),uZn.vl=function(){return!1},zW(Ytt,"ENamedElementImpl/1/1",1178),sDn(1179,287,Ort,JR),uZn.vl=function(){return!1},zW(Ytt,"ENamedElementImpl/1/2",1179),sDn(39,152,Bit,t8,e8,lV,btn,Ken,j9,Bcn,o4,Hcn,u4,E9,s4,qcn,h4,S9,f4,Ucn,l4,bV,wtn,kZ,Gcn,b4,P9,w4),uZn.Kj=function(){return ntn(this)},uZn.Rj=function(){var n;return(n=ntn(this))?n.ik():null},uZn.hj=function(n){return-1==this.b&&this.a&&(this.b=this.c.Hh(this.a.Lj(),this.a.pk())),this.c.yh(this.b,n)},uZn.jj=function(){return this.c},uZn.Sj=function(){var n;return!!(n=ntn(this))&&n.tk()},uZn.b=-1,zW(Ytt,"ENotificationImpl",39),sDn(411,292,{110:1,94:1,93:1,155:1,197:1,58:1,62:1,114:1,481:1,54:1,99:1,158:1,411:1,292:1,119:1,120:1},Yk),uZn.Ah=function(n){return fEn(this,n)},uZn.Lh=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return qx(),!!(256&this.Bb);case 3:return qx(),!!(512&this.Bb);case 4:return xwn(this.s);case 5:return xwn(this.t);case 6:return qx(),(i=this.t)>1||-1==i;case 7:return qx(),this.s>=1;case 8:return t?bEn(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?uG(this.Cb,29):null;case 11:return!this.d&&(this.d=new PD(J_t,this,11)),this.d;case 12:return!this.c&&(this.c=new fV(m_t,this,12,10)),this.c;case 13:return!this.a&&(this.a=new oF(this,this)),this.a;case 14:return Aen(this)}return $tn(this,n-iQ((YYn(),R_t)),ern(uG(Lsn(this,16),29)||R_t,n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 10:return this.Cb&&(e=(i=this.Db>>16)>=0?fEn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,10,e);case 12:return!this.c&&(this.c=new fV(m_t,this,12,10)),Nmn(this.c,n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),R_t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),R_t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 9:return IW(this,e);case 10:return DUn(this,null,10,e);case 11:return!this.d&&(this.d=new PD(J_t,this,11)),Nyn(this.d,n,e);case 12:return!this.c&&(this.c=new fV(m_t,this,12,10)),Nyn(this.c,n,e);case 14:return Nyn(Aen(this),n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),R_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),R_t)),n,e)},uZn.Wh=function(n){var t;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!(256&this.Bb);case 3:return!(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(t=this.t)>1||-1==t;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yQ(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yQ(this.q).i);case 10:return!(this.Db>>16!=10||!uG(this.Cb,29));case 11:return!!this.d&&0!=this.d.i;case 12:return!!this.c&&0!=this.c.i;case 13:return!(!this.a||0==Aen(this.a.a).i||this.b&&MMn(this.b));case 14:return!!this.b&&MMn(this.b)}return l5(this,n-iQ((YYn(),R_t)),ern(uG(Lsn(this,16),29)||R_t,n))},uZn.bi=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void qon(this,mK(t));case 2:return void ddn(this,oM(gK(t)));case 3:return void mdn(this,oM(gK(t)));case 4:return void Pcn(this,uG(t,17).a);case 5:return void Ccn(this,uG(t,17).a);case 8:return void Kbn(this,uG(t,142));case 9:return void((e=CCn(this,uG(t,89),null))&&e.oj());case 11:return!this.d&&(this.d=new PD(J_t,this,11)),Czn(this.d),!this.d&&(this.d=new PD(J_t,this,11)),void CW(this.d,uG(t,16));case 12:return!this.c&&(this.c=new fV(m_t,this,12,10)),Czn(this.c),!this.c&&(this.c=new fV(m_t,this,12,10)),void CW(this.c,uG(t,16));case 13:return!this.a&&(this.a=new oF(this,this)),_zn(this.a),!this.a&&(this.a=new oF(this,this)),void CW(this.a,uG(t,16));case 14:return Czn(Aen(this)),void CW(Aen(this),uG(t,16))}lpn(this,n-iQ((YYn(),R_t)),ern(uG(Lsn(this,16),29)||R_t,n),t)},uZn.ii=function(){return YYn(),R_t},uZn.ki=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void qon(this,null);case 2:return void ddn(this,!0);case 3:return void mdn(this,!0);case 4:return void Pcn(this,0);case 5:return void Ccn(this,1);case 8:return void Kbn(this,null);case 9:return void((t=CCn(this,null,null))&&t.oj());case 11:return!this.d&&(this.d=new PD(J_t,this,11)),void Czn(this.d);case 12:return!this.c&&(this.c=new fV(m_t,this,12,10)),void Czn(this.c);case 13:return void(this.a&&_zn(this.a));case 14:return void(this.b&&Czn(this.b))}sdn(this,n-iQ((YYn(),R_t)),ern(uG(Lsn(this,16),29)||R_t,n))},uZn.pi=function(){var n,t;if(this.c)for(n=0,t=this.c.i;ni&&uQ(n,i,null),e=0,t=new DD(Aen(this.a));t.e!=t.i.gc();)uQ(n,e++,uG(Zkn(t),89).c||(YYn(),N_t));return n},uZn.Hj=function(){var n,t,e,i;for((i=new zM).a+="[",n=Aen(this.a),t=0,e=Aen(this.a).i;t1);case 5:return i2(this,n,t,e,i,this.i-uG(e,15).gc()>0);default:return new Ken(this.e,n,this.c,t,e,i,!0)}},uZn.Tj=function(){return!0},uZn.Qj=function(){return MMn(this)},uZn.Gk=function(){Czn(this)},zW(Ytt,"EOperationImpl/2",1377),sDn(507,1,{2037:1,507:1},EA),zW(Ytt,"EPackageImpl/1",507),sDn(14,83,Trt,fV),uZn.il=function(){return this.d},uZn.jl=function(){return this.b},uZn.ml=function(){return!0},uZn.b=0,zW(art,"EObjectContainmentWithInverseEList",14),sDn(365,14,Trt,i_),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectContainmentWithInverseEList/Resolving",365),sDn(308,365,Trt,vV),uZn.Ni=function(){this.a.tb=null},zW(Ytt,"EPackageImpl/2",308),sDn(1278,1,{},Ps),zW(Ytt,"EPackageImpl/3",1278),sDn(733,45,B0n,Zk),uZn._b=function(n){return RA(n)?AZ(this,n):!!FX(this.f,n)},zW(Ytt,"EPackageRegistryImpl",733),sDn(518,292,{110:1,94:1,93:1,155:1,197:1,58:1,2116:1,114:1,481:1,54:1,99:1,158:1,518:1,292:1,119:1,120:1},ny),uZn.Ah=function(n){return lEn(this,n)},uZn.Lh=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return qx(),!!(256&this.Bb);case 3:return qx(),!!(512&this.Bb);case 4:return xwn(this.s);case 5:return xwn(this.t);case 6:return qx(),(i=this.t)>1||-1==i;case 7:return qx(),this.s>=1;case 8:return t?bEn(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?uG(this.Cb,62):null}return $tn(this,n-iQ((YYn(),__t)),ern(uG(Lsn(this,16),29)||__t,n),t,e)},uZn.Sh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nmn(this.Ab,n,e);case 10:return this.Cb&&(e=(i=this.Db>>16)>=0?lEn(this,e):this.Cb.Th(this,-1-i,null,e)),DUn(this,n,10,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),__t),t),69).wk().zk(this,$vn(this),t-iQ((YYn(),__t)),n,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 9:return IW(this,e);case 10:return DUn(this,null,10,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),__t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),__t)),n,e)},uZn.Wh=function(n){var t;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!(256&this.Bb);case 3:return!(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(t=this.t)>1||-1==t;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yQ(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yQ(this.q).i);case 10:return!(this.Db>>16!=10||!uG(this.Cb,62))}return l5(this,n-iQ((YYn(),__t)),ern(uG(Lsn(this,16),29)||__t,n))},uZn.ii=function(){return YYn(),__t},zW(Ytt,"EParameterImpl",518),sDn(102,462,{110:1,94:1,93:1,155:1,197:1,58:1,19:1,179:1,69:1,114:1,481:1,54:1,99:1,158:1,102:1,462:1,292:1,119:1,120:1,692:1},PK),uZn.Lh=function(n,t,e){var i,r;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return qx(),!!(256&this.Bb);case 3:return qx(),!!(512&this.Bb);case 4:return xwn(this.s);case 5:return xwn(this.t);case 6:return qx(),(r=this.t)>1||-1==r;case 7:return qx(),this.s>=1;case 8:return t?bEn(this):this.r;case 9:return this.q;case 10:return qx(),!!(this.Bb&w1n);case 11:return qx(),!!(this.Bb&frt);case 12:return qx(),!!(this.Bb&j0n);case 13:return this.j;case 14:return NRn(this);case 15:return qx(),!!(this.Bb&hrt);case 16:return qx(),!!(this.Bb&VZn);case 17:return K0(this);case 18:return qx(),!!(this.Bb&Qtt);case 19:return qx(),!!((i=lMn(this))&&i.Bb&Qtt);case 20:return qx(),!!(this.Bb&P0n);case 21:return t?lMn(this):this.b;case 22:return t?Ffn(this):R9(this);case 23:return!this.a&&(this.a=new OD(u_t,this,23)),this.a}return $tn(this,n-iQ((YYn(),B_t)),ern(uG(Lsn(this,16),29)||B_t,n),t,e)},uZn.Wh=function(n){var t,e;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!(256&this.Bb);case 3:return!(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(e=this.t)>1||-1==e;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yQ(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yQ(this.q).i);case 10:return!(this.Bb&w1n);case 11:return!!(this.Bb&frt);case 12:return!!(this.Bb&j0n);case 13:return null!=this.j;case 14:return null!=NRn(this);case 15:return!!(this.Bb&hrt);case 16:return!!(this.Bb&VZn);case 17:return!!K0(this);case 18:return!!(this.Bb&Qtt);case 19:return!!(t=lMn(this))&&!!(t.Bb&Qtt);case 20:return!(this.Bb&P0n);case 21:return!!this.b;case 22:return!!R9(this);case 23:return!!this.a&&0!=this.a.i}return l5(this,n-iQ((YYn(),B_t)),ern(uG(Lsn(this,16),29)||B_t,n))},uZn.bi=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void g2(this,mK(t));case 2:return void ddn(this,oM(gK(t)));case 3:return void mdn(this,oM(gK(t)));case 4:return void Pcn(this,uG(t,17).a);case 5:return void Ccn(this,uG(t,17).a);case 8:return void Kbn(this,uG(t,142));case 9:return void((e=CCn(this,uG(t,89),null))&&e.oj());case 10:return void Wdn(this,oM(gK(t)));case 11:return void Ydn(this,oM(gK(t)));case 12:return void Qdn(this,oM(gK(t)));case 13:return void mA(this,mK(t));case 15:return void Jdn(this,oM(gK(t)));case 16:return void Cgn(this,oM(gK(t)));case 18:return void p2(this,oM(gK(t)));case 20:return void Ign(this,oM(gK(t)));case 21:return void bon(this,uG(t,19));case 23:return!this.a&&(this.a=new OD(u_t,this,23)),Czn(this.a),!this.a&&(this.a=new OD(u_t,this,23)),void CW(this.a,uG(t,16))}lpn(this,n-iQ((YYn(),B_t)),ern(uG(Lsn(this,16),29)||B_t,n),t)},uZn.ii=function(){return YYn(),B_t},uZn.ki=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return F$(this.Cb,90)&&yLn(y9(uG(this.Cb,90)),4),void qon(this,null);case 2:return void ddn(this,!0);case 3:return void mdn(this,!0);case 4:return void Pcn(this,0);case 5:return void Ccn(this,1);case 8:return void Kbn(this,null);case 9:return void((t=CCn(this,null,null))&&t.oj());case 10:return void Wdn(this,!0);case 11:return void Ydn(this,!1);case 12:return void Qdn(this,!1);case 13:return this.i=null,void lon(this,null);case 15:return void Jdn(this,!1);case 16:return void Cgn(this,!1);case 18:return Pgn(this,!1),void(F$(this.Cb,90)&&yLn(y9(uG(this.Cb,90)),2));case 20:return void Ign(this,!0);case 21:return void bon(this,null);case 23:return!this.a&&(this.a=new OD(u_t,this,23)),void Czn(this.a)}sdn(this,n-iQ((YYn(),B_t)),ern(uG(Lsn(this,16),29)||B_t,n))},uZn.pi=function(){Ffn(this),BJ(Nen((gAn(),kBt),this)),bEn(this),this.Bb|=1},uZn.uk=function(){return lMn(this)},uZn._k=function(){var n;return!!(n=lMn(this))&&!!(n.Bb&Qtt)},uZn.al=function(){return!!(this.Bb&Qtt)},uZn.bl=function(){return!!(this.Bb&P0n)},uZn.Yk=function(n,t){return this.c=null,Ywn(this,n,t)},uZn.Ib=function(){var n;return 64&this.Db?MBn(this):((n=new fx(MBn(this))).a+=" (containment: ",Lj(n,!!(this.Bb&Qtt)),n.a+=", resolveProxies: ",Lj(n,!!(this.Bb&P0n)),n.a+=")",n.a)},zW(Ytt,"EReferenceImpl",102),sDn(561,120,{110:1,44:1,94:1,93:1,136:1,58:1,114:1,54:1,99:1,561:1,119:1,120:1},Cs),uZn.Fb=function(n){return this===n},uZn.ld=function(){return this.b},uZn.md=function(){return this.c},uZn.Hb=function(){return xx(this)},uZn.Di=function(n){Rq(this,mK(n))},uZn.nd=function(n){return DG(this,mK(n))},uZn.Lh=function(n,t,e){switch(n){case 0:return this.b;case 1:return this.c}return $tn(this,n-iQ((YYn(),H_t)),ern(uG(Lsn(this,16),29)||H_t,n),t,e)},uZn.Wh=function(n){switch(n){case 0:return null!=this.b;case 1:return null!=this.c}return l5(this,n-iQ((YYn(),H_t)),ern(uG(Lsn(this,16),29)||H_t,n))},uZn.bi=function(n,t){switch(n){case 0:return void Kq(this,mK(t));case 1:return void Jan(this,mK(t))}lpn(this,n-iQ((YYn(),H_t)),ern(uG(Lsn(this,16),29)||H_t,n),t)},uZn.ii=function(){return YYn(),H_t},uZn.ki=function(n){switch(n){case 0:return void Qan(this,null);case 1:return void Jan(this,null)}sdn(this,n-iQ((YYn(),H_t)),ern(uG(Lsn(this,16),29)||H_t,n))},uZn.Bi=function(){var n;return-1==this.a&&(n=this.b,this.a=null==n?0:pln(n)),this.a},uZn.Ci=function(n){this.a=n},uZn.Ib=function(){var n;return 64&this.Db?vxn(this):((n=new fx(vxn(this))).a+=" (key: ",VA(n,this.b),n.a+=", value: ",VA(n,this.c),n.a+=")",n.a)},uZn.a=-1,uZn.b=null,uZn.c=null;var rBt,cBt,aBt,oBt,uBt,sBt,hBt,fBt,lBt,bBt,wBt=zW(Ytt,"EStringToStringMapEntryImpl",561),dBt=Iq(art,"FeatureMap/Entry/Internal");sDn(576,1,Art),uZn.xl=function(n){return this.yl(uG(n,54))},uZn.yl=function(n){return this.xl(n)},uZn.Fb=function(n){var t,e;return this===n||!!F$(n,76)&&(t=uG(n,76)).Lk()==this.c&&(null==(e=this.md())?null==t.md():udn(e,t.md()))},uZn.Lk=function(){return this.c},uZn.Hb=function(){var n;return n=this.md(),Hon(this.c)^(null==n?0:Hon(n))},uZn.Ib=function(){var n,t;return t=Hrn((n=this.c).qk()).yi(),n.xe(),(null!=t&&0!=t.length?t+":"+n.xe():n.xe())+"="+this.md()},zW(Ytt,"EStructuralFeatureImpl/BasicFeatureMapEntry",576),sDn(791,576,Art,sF),uZn.yl=function(n){return new sF(this.c,n)},uZn.md=function(){return this.a},uZn.zl=function(n,t,e){return Kun(this,n,this.a,t,e)},uZn.Al=function(n,t,e){return Fun(this,n,this.a,t,e)},zW(Ytt,"EStructuralFeatureImpl/ContainmentUpdatingFeatureMapEntry",791),sDn(1350,1,{},SA),uZn.yk=function(n,t,e,i,r){return uG(vtn(n,this.b),220).Yl(this.a).Fk(i)},uZn.zk=function(n,t,e,i,r){return uG(vtn(n,this.b),220).Pl(this.a,i,r)},uZn.Ak=function(n,t,e,i,r){return uG(vtn(n,this.b),220).Ql(this.a,i,r)},uZn.Bk=function(n,t,e){return uG(vtn(n,this.b),220).Yl(this.a).Qj()},uZn.Ck=function(n,t,e,i){uG(vtn(n,this.b),220).Yl(this.a).Wb(i)},uZn.Dk=function(n,t,e){return uG(vtn(n,this.b),220).Yl(this.a)},uZn.Ek=function(n,t,e){uG(vtn(n,this.b),220).Yl(this.a).Gk()},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateFeatureMapDelegator",1350),sDn(91,1,{},RU,CY,GZ,r8),uZn.yk=function(n,t,e,i,r){var c;if(null==(c=t.li(e))&&t.mi(e,c=xYn(this,n)),!r)switch(this.e){case 50:case 41:return uG(c,597).bk();case 40:return uG(c,220).Vl()}return c},uZn.zk=function(n,t,e,i,r){var c;return null==(c=t.li(e))&&t.mi(e,c=xYn(this,n)),uG(c,71).Wk(i,r)},uZn.Ak=function(n,t,e,i,r){var c;return null!=(c=t.li(e))&&(r=uG(c,71).Xk(i,r)),r},uZn.Bk=function(n,t,e){var i;return null!=(i=t.li(e))&&uG(i,79).Qj()},uZn.Ck=function(n,t,e,i){var r;!(r=uG(t.li(e),79))&&t.mi(e,r=xYn(this,n)),r.Wb(i)},uZn.Dk=function(n,t,e){var i;return null==(i=t.li(e))&&t.mi(e,i=xYn(this,n)),F$(i,79)?uG(i,79):new _m(uG(t.li(e),15))},uZn.Ek=function(n,t,e){var i;!(i=uG(t.li(e),79))&&t.mi(e,i=xYn(this,n)),i.Gk()},uZn.b=0,uZn.e=0,zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateMany",91),sDn(512,1,{}),uZn.zk=function(n,t,e,i,r){throw hv(new Kv)},uZn.Ak=function(n,t,e,i,r){throw hv(new Kv)},uZn.Dk=function(n,t,e){return new IY(this,n,t,e)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingle",512),sDn(1367,1,ort,IY),uZn.Fk=function(n){return this.a.yk(this.c,this.d,this.b,n,!0)},uZn.Qj=function(){return this.a.Bk(this.c,this.d,this.b)},uZn.Wb=function(n){this.a.Ck(this.c,this.d,this.b,n)},uZn.Gk=function(){this.a.Ek(this.c,this.d,this.b)},uZn.b=0,zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingle/1",1367),sDn(784,512,{},_1),uZn.yk=function(n,t,e,i,r){return PHn(n,n.Ph(),n.Fh())==this.b?this.bl()&&i?J$n(n):n.Ph():null},uZn.zk=function(n,t,e,i,r){var c,a;return n.Ph()&&(r=(c=n.Fh())>=0?n.Ah(r):n.Ph().Th(n,-1-c,null,r)),a=emn(n.Dh(),this.e),n.Ch(i,a,r)},uZn.Ak=function(n,t,e,i,r){var c;return c=emn(n.Dh(),this.e),n.Ch(null,c,r)},uZn.Bk=function(n,t,e){var i;return i=emn(n.Dh(),this.e),!!n.Ph()&&n.Fh()==i},uZn.Ck=function(n,t,e,i){var r,c,a,o,u;if(null!=i&&!LGn(this.a,i))throw hv(new mM(Lrt+(F$(i,58)?nPn(uG(i,58).Dh()):crn(Tbn(i)))+Nrt+this.a+"'"));if(r=n.Ph(),a=emn(n.Dh(),this.e),xA(i)!==xA(r)||n.Fh()!=a&&null!=i){if(eEn(n,uG(i,58)))throw hv(new vM(net+n.Ib()));u=null,r&&(u=(c=n.Fh())>=0?n.Ah(u):n.Ph().Th(n,-1-c,null,u)),(o=uG(i,54))&&(u=o.Rh(n,emn(o.Dh(),this.b),null,u)),(u=n.Ch(o,a,u))&&u.oj()}else n.vh()&&n.wh()&&Msn(n,new lV(n,1,a,i,i))},uZn.Ek=function(n,t,e){var i,r,c;n.Ph()?(c=(i=n.Fh())>=0?n.Ah(null):n.Ph().Th(n,-1-i,null,null),r=emn(n.Dh(),this.e),(c=n.Ch(null,r,c))&&c.oj()):n.vh()&&n.wh()&&Msn(n,new bV(n,1,this.e,null,null))},uZn.bl=function(){return!1},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainer",784),sDn(1351,784,{},KU),uZn.bl=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainerResolving",1351),sDn(574,512,{}),uZn.yk=function(n,t,e,i,r){var c;return null==(c=t.li(e))?this.b:xA(c)===xA(rBt)?null:c},uZn.Bk=function(n,t,e){var i;return null!=(i=t.li(e))&&(xA(i)===xA(rBt)||!udn(i,this.b))},uZn.Ck=function(n,t,e,i){var r,c;n.vh()&&n.wh()?(r=null==(c=t.li(e))?this.b:xA(c)===xA(rBt)?null:c,null==i?null!=this.c?(t.mi(e,null),i=this.b):null!=this.b?t.mi(e,rBt):t.mi(e,null):(this.Bl(i),t.mi(e,i)),Msn(n,this.d.Cl(n,1,this.e,r,i))):null==i?null!=this.c?t.mi(e,null):null!=this.b?t.mi(e,rBt):t.mi(e,null):(this.Bl(i),t.mi(e,i))},uZn.Ek=function(n,t,e){var i,r;n.vh()&&n.wh()?(i=null==(r=t.li(e))?this.b:xA(r)===xA(rBt)?null:r,t.ni(e),Msn(n,this.d.Cl(n,1,this.e,i,this.b))):t.ni(e)},uZn.Bl=function(n){throw hv(new $v)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData",574),sDn($rt,1,{},Is),uZn.Cl=function(n,t,e,i,r){return new bV(n,t,e,i,r)},uZn.Dl=function(n,t,e,i,r,c){return new kZ(n,t,e,i,r,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator",$rt),sDn(1368,$rt,{},Os),uZn.Cl=function(n,t,e,i,r){return new P9(n,t,e,oM(gK(i)),oM(gK(r)))},uZn.Dl=function(n,t,e,i,r,c){return new w4(n,t,e,oM(gK(i)),oM(gK(r)),c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/1",1368),sDn(1369,$rt,{},As),uZn.Cl=function(n,t,e,i,r){return new Bcn(n,t,e,uG(i,222).a,uG(r,222).a)},uZn.Dl=function(n,t,e,i,r,c){return new o4(n,t,e,uG(i,222).a,uG(r,222).a,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/2",1369),sDn(1370,$rt,{},Ls),uZn.Cl=function(n,t,e,i,r){return new Hcn(n,t,e,uG(i,180).a,uG(r,180).a)},uZn.Dl=function(n,t,e,i,r,c){return new u4(n,t,e,uG(i,180).a,uG(r,180).a,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/3",1370),sDn(1371,$rt,{},Ns),uZn.Cl=function(n,t,e,i,r){return new E9(n,t,e,uM(pK(i)),uM(pK(r)))},uZn.Dl=function(n,t,e,i,r,c){return new s4(n,t,e,uM(pK(i)),uM(pK(r)),c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/4",1371),sDn(1372,$rt,{},$s),uZn.Cl=function(n,t,e,i,r){return new qcn(n,t,e,uG(i,161).a,uG(r,161).a)},uZn.Dl=function(n,t,e,i,r,c){return new h4(n,t,e,uG(i,161).a,uG(r,161).a,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/5",1372),sDn(1373,$rt,{},Ds),uZn.Cl=function(n,t,e,i,r){return new S9(n,t,e,uG(i,17).a,uG(r,17).a)},uZn.Dl=function(n,t,e,i,r,c){return new f4(n,t,e,uG(i,17).a,uG(r,17).a,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/6",1373),sDn(1374,$rt,{},xs),uZn.Cl=function(n,t,e,i,r){return new Ucn(n,t,e,uG(i,168).a,uG(r,168).a)},uZn.Dl=function(n,t,e,i,r,c){return new l4(n,t,e,uG(i,168).a,uG(r,168).a,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/7",1374),sDn(1375,$rt,{},Rs),uZn.Cl=function(n,t,e,i,r){return new Gcn(n,t,e,uG(i,191).a,uG(r,191).a)},uZn.Dl=function(n,t,e,i,r,c){return new b4(n,t,e,uG(i,191).a,uG(r,191).a,c)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/8",1375),sDn(1353,574,{},OY),uZn.Bl=function(n){if(!this.a.fk(n))throw hv(new mM(Lrt+Tbn(n)+Nrt+this.a+"'"))},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataDynamic",1353),sDn(1354,574,{},lz),uZn.Bl=function(n){},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataStatic",1354),sDn(785,574,{}),uZn.Bk=function(n,t,e){return null!=t.li(e)},uZn.Ck=function(n,t,e,i){var r,c;n.vh()&&n.wh()?(r=!0,null==(c=t.li(e))?(r=!1,c=this.b):xA(c)===xA(rBt)&&(c=null),null==i?null!=this.c?(t.mi(e,null),i=this.b):t.mi(e,rBt):(this.Bl(i),t.mi(e,i)),Msn(n,this.d.Dl(n,1,this.e,c,i,!r))):null==i?null!=this.c?t.mi(e,null):t.mi(e,rBt):(this.Bl(i),t.mi(e,i))},uZn.Ek=function(n,t,e){var i,r;n.vh()&&n.wh()?(i=!0,null==(r=t.li(e))?(i=!1,r=this.b):xA(r)===xA(rBt)&&(r=null),t.ni(e),Msn(n,this.d.Dl(n,2,this.e,r,this.b,i))):t.ni(e)},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettable",785),sDn(1355,785,{},AY),uZn.Bl=function(n){if(!this.a.fk(n))throw hv(new mM(Lrt+Tbn(n)+Nrt+this.a+"'"))},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableDynamic",1355),sDn(1356,785,{},bz),uZn.Bl=function(n){},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableStatic",1356),sDn(410,512,{},OX),uZn.yk=function(n,t,e,i,r){var c,a,o,u,s;if(s=t.li(e),this.tk()&&xA(s)===xA(rBt))return null;if(this.bl()&&i&&null!=s){if((o=uG(s,54)).Vh()&&o!=(u=mwn(n,o))){if(!LGn(this.a,u))throw hv(new mM(Lrt+Tbn(u)+Nrt+this.a+"'"));t.mi(e,s=u),this.al()&&(c=uG(u,54),a=o.Th(n,this.b?emn(o.Dh(),this.b):-1-emn(n.Dh(),this.e),null,null),!c.Ph()&&(a=c.Rh(n,this.b?emn(c.Dh(),this.b):-1-emn(n.Dh(),this.e),null,a)),a&&a.oj()),n.vh()&&n.wh()&&Msn(n,new bV(n,9,this.e,o,u))}return s}return s},uZn.zk=function(n,t,e,i,r){var c,a;return xA(a=t.li(e))===xA(rBt)&&(a=null),t.mi(e,i),this.Mj()?xA(a)!==xA(i)&&null!=a&&(r=(c=uG(a,54)).Th(n,emn(c.Dh(),this.b),null,r)):this.al()&&null!=a&&(r=uG(a,54).Th(n,-1-emn(n.Dh(),this.e),null,r)),n.vh()&&n.wh()&&(!r&&(r=new cj(4)),r.nj(new bV(n,1,this.e,a,i))),r},uZn.Ak=function(n,t,e,i,r){var c;return xA(c=t.li(e))===xA(rBt)&&(c=null),t.ni(e),n.vh()&&n.wh()&&(!r&&(r=new cj(4)),this.tk()?r.nj(new bV(n,2,this.e,c,null)):r.nj(new bV(n,1,this.e,c,null))),r},uZn.Bk=function(n,t,e){return null!=t.li(e)},uZn.Ck=function(n,t,e,i){var r,c,a,o,u;if(null!=i&&!LGn(this.a,i))throw hv(new mM(Lrt+(F$(i,58)?nPn(uG(i,58).Dh()):crn(Tbn(i)))+Nrt+this.a+"'"));o=null!=(u=t.li(e)),this.tk()&&xA(u)===xA(rBt)&&(u=null),a=null,this.Mj()?xA(u)!==xA(i)&&(null!=u&&(a=(r=uG(u,54)).Th(n,emn(r.Dh(),this.b),null,a)),null!=i&&(a=(r=uG(i,54)).Rh(n,emn(r.Dh(),this.b),null,a))):this.al()&&xA(u)!==xA(i)&&(null!=u&&(a=uG(u,54).Th(n,-1-emn(n.Dh(),this.e),null,a)),null!=i&&(a=uG(i,54).Rh(n,-1-emn(n.Dh(),this.e),null,a))),null==i&&this.tk()?t.mi(e,rBt):t.mi(e,i),n.vh()&&n.wh()?(c=new kZ(n,1,this.e,u,i,this.tk()&&!o),a?(a.nj(c),a.oj()):Msn(n,c)):a&&a.oj()},uZn.Ek=function(n,t,e){var i,r,c,a,o;a=null!=(o=t.li(e)),this.tk()&&xA(o)===xA(rBt)&&(o=null),c=null,null!=o&&(this.Mj()?c=(i=uG(o,54)).Th(n,emn(i.Dh(),this.b),null,c):this.al()&&(c=uG(o,54).Th(n,-1-emn(n.Dh(),this.e),null,c))),t.ni(e),n.vh()&&n.wh()?(r=new kZ(n,this.tk()?2:1,this.e,o,null,a),c?(c.nj(r),c.oj()):Msn(n,r)):c&&c.oj()},uZn.Mj=function(){return!1},uZn.al=function(){return!1},uZn.bl=function(){return!1},uZn.tk=function(){return!1},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObject",410),sDn(575,410,{},tK),uZn.al=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainment",575),sDn(1359,575,{},eK),uZn.bl=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentResolving",1359),sDn(787,575,{},iK),uZn.tk=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettable",787),sDn(1361,787,{},cK),uZn.bl=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettableResolving",1361),sDn(650,575,{},FU),uZn.Mj=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverse",650),sDn(1360,650,{},HU),uZn.bl=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseResolving",1360),sDn(788,650,{},UU),uZn.tk=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettable",788),sDn(1362,788,{},GU),uZn.bl=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettableResolving",1362),sDn(651,410,{},rK),uZn.bl=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolving",651),sDn(1363,651,{},aK),uZn.tk=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingUnsettable",1363),sDn(789,651,{},_U),uZn.Mj=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverse",789),sDn(1364,789,{},qU),uZn.tk=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverseUnsettable",1364),sDn(1357,410,{},oK),uZn.tk=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectUnsettable",1357),sDn(786,410,{},BU),uZn.Mj=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverse",786),sDn(1358,786,{},XU),uZn.tk=function(){return!0},zW(Ytt,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverseUnsettable",1358),sDn(790,576,Art,EQ),uZn.yl=function(n){return new EQ(this.a,this.c,n)},uZn.md=function(){return this.b},uZn.zl=function(n,t,e){return Snn(this,n,this.b,e)},uZn.Al=function(n,t,e){return Pnn(this,n,this.b,e)},zW(Ytt,"EStructuralFeatureImpl/InverseUpdatingFeatureMapEntry",790),sDn(1365,1,ort,_m),uZn.Fk=function(n){return this.a},uZn.Qj=function(){return F$(this.a,97)?uG(this.a,97).Qj():!this.a.dc()},uZn.Wb=function(n){this.a.$b(),this.a.Gc(uG(n,15))},uZn.Gk=function(){F$(this.a,97)?uG(this.a,97).Gk():this.a.$b()},zW(Ytt,"EStructuralFeatureImpl/SettingMany",1365),sDn(1366,576,Art,o8),uZn.xl=function(n){return new hF((uVn(),oHt),this.b.ri(this.a,n))},uZn.md=function(){return null},uZn.zl=function(n,t,e){return e},uZn.Al=function(n,t,e){return e},zW(Ytt,"EStructuralFeatureImpl/SimpleContentFeatureMapEntry",1366),sDn(652,576,Art,hF),uZn.xl=function(n){return new hF(this.c,n)},uZn.md=function(){return this.a},uZn.zl=function(n,t,e){return e},uZn.Al=function(n,t,e){return e},zW(Ytt,"EStructuralFeatureImpl/SimpleFeatureMapEntry",652),sDn(403,506,Qet,Ks),uZn.aj=function(n){return Inn(h_t,EZn,29,n,0,1)},uZn.Yi=function(){return!1},zW(Ytt,"ESuperAdapter/1",403),sDn(457,448,{110:1,94:1,93:1,155:1,197:1,58:1,114:1,850:1,54:1,99:1,158:1,457:1,119:1,120:1},Fs),uZn.Lh=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),this.Ab;case 1:return this.zb;case 2:return!this.a&&(this.a=new AX(this,g_t,this)),this.a}return $tn(this,n-iQ((YYn(),q_t)),ern(uG(Lsn(this,16),29)||q_t,n),t,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Nyn(this.Ab,n,e);case 2:return!this.a&&(this.a=new AX(this,g_t,this)),Nyn(this.a,n,e)}return uG(ern(uG(Lsn(this,16),29)||(YYn(),q_t),t),69).wk().Ak(this,$vn(this),t-iQ((YYn(),q_t)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!!this.a&&0!=this.a.i}return l5(this,n-iQ((YYn(),q_t)),ern(uG(Lsn(this,16),29)||q_t,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),Czn(this.Ab),!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void CW(this.Ab,uG(t,16));case 1:return void qon(this,mK(t));case 2:return!this.a&&(this.a=new AX(this,g_t,this)),Czn(this.a),!this.a&&(this.a=new AX(this,g_t,this)),void CW(this.a,uG(t,16))}lpn(this,n-iQ((YYn(),q_t)),ern(uG(Lsn(this,16),29)||q_t,n),t)},uZn.ii=function(){return YYn(),q_t},uZn.ki=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new fV(c_t,this,0,3)),void Czn(this.Ab);case 1:return void qon(this,null);case 2:return!this.a&&(this.a=new AX(this,g_t,this)),void Czn(this.a)}sdn(this,n-iQ((YYn(),q_t)),ern(uG(Lsn(this,16),29)||q_t,n))},zW(Ytt,"ETypeParameterImpl",457),sDn(458,83,Trt,AX),uZn.Nj=function(n,t){return mCn(this,uG(n,89),t)},uZn.Oj=function(n,t){return vCn(this,uG(n,89),t)},zW(Ytt,"ETypeParameterImpl/1",458),sDn(647,45,B0n,ty),uZn.ec=function(){return new Um(this)},zW(Ytt,"ETypeParameterImpl/2",647),sDn(570,KZn,FZn,Um),uZn.Fc=function(n){return WF(this,uG(n,89))},uZn.Gc=function(n){var t,e,i;for(i=!1,e=n.Kc();e.Ob();)t=uG(e.Pb(),89),null==vJ(this.a,t,"")&&(i=!0);return i},uZn.$b=function(){$V(this.a)},uZn.Hc=function(n){return PV(this.a,n)},uZn.Kc=function(){return new Gm(new bsn(new Nw(this.a).a))},uZn.Mc=function(n){return C7(this,n)},uZn.gc=function(){return oS(this.a)},zW(Ytt,"ETypeParameterImpl/2/1",570),sDn(571,1,$Zn,Gm),uZn.Nb=function(n){SV(this,n)},uZn.Pb=function(){return uG(von(this.a).ld(),89)},uZn.Ob=function(){return this.a.b},uZn.Qb=function(){Oen(this.a)},zW(Ytt,"ETypeParameterImpl/2/1/1",571),sDn(1329,45,B0n,ey),uZn._b=function(n){return RA(n)?AZ(this,n):!!FX(this.f,n)},uZn.xc=function(n){var t;return F$(t=RA(n)?U1(this,n):DA(FX(this.f,n)),851)?(t=uG(t,851).Kk(),vJ(this,uG(n,241),t),t):null!=t?t:null==n?(SP(),EBt):null},zW(Ytt,"EValidatorRegistryImpl",1329),sDn(1349,720,{110:1,94:1,93:1,480:1,155:1,58:1,114:1,2040:1,54:1,99:1,158:1,119:1,120:1},_s),uZn.ri=function(n,t){switch(n.hk()){case 21:case 22:case 23:case 24:case 26:case 31:case 32:case 37:case 38:case 39:case 40:case 43:case 44:case 48:case 49:case 20:return null==t?null:cpn(t);case 25:return Xrn(t);case 27:return nen(t);case 28:return ten(t);case 29:return null==t?null:N$(QKt[0],uG(t,206));case 41:return null==t?"":Ij(uG(t,297));case 42:return cpn(t);case 50:return mK(t);default:throw hv(new vM(tet+n.xe()+eet))}},uZn.si=function(n){var t;switch(-1==n.G&&(n.G=(t=Hrn(n))?Hyn(t.vi(),n):-1),n.G){case 0:return new Wk;case 1:return new vs;case 2:return new Kl;case 4:return new Gv;case 5:return new Jk;case 6:return new Uv;case 7:return new Fl;case 10:return new ps;case 11:return new Yk;case 12:return new aZ;case 13:return new ny;case 14:return new PK;case 17:return new Cs;case 18:return new ev;case 19:return new Fs;default:throw hv(new vM(cet+n.zb+eet))}},uZn.ti=function(n,t){switch(n.hk()){case 20:return null==t?null:new Wj(t);case 21:return null==t?null:new PN(t);case 23:case 22:return null==t?null:Ovn(t);case 26:case 24:return null==t?null:Ben(vUn(t,-128,127)<<24>>24);case 25:return cxn(t);case 27:return sjn(t);case 28:return hjn(t);case 29:return rIn(t);case 32:case 31:return null==t?null:YIn(t);case 38:case 37:return null==t?null:new tk(t);case 40:case 39:return null==t?null:xwn(vUn(t,j1n,vZn));case 41:case 42:return null;case 44:case 43:return null==t?null:Hvn(tJn(t));case 49:case 48:return null==t?null:Rwn(vUn(t,xrt,32767)<<16>>16);case 50:return t;default:throw hv(new vM(tet+n.xe()+eet))}},zW(Ytt,"EcoreFactoryImpl",1349),sDn(560,184,{110:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,2038:1,54:1,99:1,158:1,184:1,560:1,119:1,120:1,690:1},dJ),uZn.gb=!1,uZn.hb=!1;var gBt,pBt=!1;zW(Ytt,"EcorePackageImpl",560),sDn(1234,1,{851:1},Bs),uZn.Kk=function(){return HD(),SBt},zW(Ytt,"EcorePackageImpl/1",1234),sDn(1243,1,Wrt,Hs),uZn.fk=function(n){return F$(n,155)},uZn.gk=function(n){return Inn(uFt,EZn,155,n,0,1)},zW(Ytt,"EcorePackageImpl/10",1243),sDn(1244,1,Wrt,Us),uZn.fk=function(n){return F$(n,197)},uZn.gk=function(n){return Inn(hFt,EZn,197,n,0,1)},zW(Ytt,"EcorePackageImpl/11",1244),sDn(1245,1,Wrt,Gs),uZn.fk=function(n){return F$(n,58)},uZn.gk=function(n){return Inn(nFt,EZn,58,n,0,1)},zW(Ytt,"EcorePackageImpl/12",1245),sDn(1246,1,Wrt,qs),uZn.fk=function(n){return F$(n,411)},uZn.gk=function(n){return Inn(p_t,yrt,62,n,0,1)},zW(Ytt,"EcorePackageImpl/13",1246),sDn(1247,1,Wrt,Xs),uZn.fk=function(n){return F$(n,241)},uZn.gk=function(n){return Inn(fFt,EZn,241,n,0,1)},zW(Ytt,"EcorePackageImpl/14",1247),sDn(1248,1,Wrt,zs),uZn.fk=function(n){return F$(n,518)},uZn.gk=function(n){return Inn(m_t,EZn,2116,n,0,1)},zW(Ytt,"EcorePackageImpl/15",1248),sDn(1249,1,Wrt,Vs),uZn.fk=function(n){return F$(n,102)},uZn.gk=function(n){return Inn(v_t,krt,19,n,0,1)},zW(Ytt,"EcorePackageImpl/16",1249),sDn(1250,1,Wrt,Ws),uZn.fk=function(n){return F$(n,179)},uZn.gk=function(n){return Inn(o_t,krt,179,n,0,1)},zW(Ytt,"EcorePackageImpl/17",1250),sDn(1251,1,Wrt,Qs),uZn.fk=function(n){return F$(n,481)},uZn.gk=function(n){return Inn(a_t,EZn,481,n,0,1)},zW(Ytt,"EcorePackageImpl/18",1251),sDn(1252,1,Wrt,Js),uZn.fk=function(n){return F$(n,561)},uZn.gk=function(n){return Inn(wBt,Xit,561,n,0,1)},zW(Ytt,"EcorePackageImpl/19",1252),sDn(1235,1,Wrt,Ys),uZn.fk=function(n){return F$(n,331)},uZn.gk=function(n){return Inn(u_t,krt,35,n,0,1)},zW(Ytt,"EcorePackageImpl/2",1235),sDn(1253,1,Wrt,Zs),uZn.fk=function(n){return F$(n,248)},uZn.gk=function(n){return Inn(g_t,Prt,89,n,0,1)},zW(Ytt,"EcorePackageImpl/20",1253),sDn(1254,1,Wrt,nh),uZn.fk=function(n){return F$(n,457)},uZn.gk=function(n){return Inn(J_t,EZn,850,n,0,1)},zW(Ytt,"EcorePackageImpl/21",1254),sDn(1255,1,Wrt,th),uZn.fk=function(n){return KA(n)},uZn.gk=function(n){return Inn(cot,zZn,485,n,8,1)},zW(Ytt,"EcorePackageImpl/22",1255),sDn(1256,1,Wrt,eh),uZn.fk=function(n){return F$(n,195)},uZn.gk=function(n){return Inn(tUt,zZn,195,n,0,2)},zW(Ytt,"EcorePackageImpl/23",1256),sDn(1257,1,Wrt,ih),uZn.fk=function(n){return F$(n,222)},uZn.gk=function(n){return Inn(uot,zZn,222,n,0,1)},zW(Ytt,"EcorePackageImpl/24",1257),sDn(1258,1,Wrt,rh),uZn.fk=function(n){return F$(n,180)},uZn.gk=function(n){return Inn(hot,zZn,180,n,0,1)},zW(Ytt,"EcorePackageImpl/25",1258),sDn(1259,1,Wrt,ch),uZn.fk=function(n){return F$(n,206)},uZn.gk=function(n){return Inn(iot,zZn,206,n,0,1)},zW(Ytt,"EcorePackageImpl/26",1259),sDn(1260,1,Wrt,ah),uZn.fk=function(n){return!1},uZn.gk=function(n){return Inn(aUt,EZn,2215,n,0,1)},zW(Ytt,"EcorePackageImpl/27",1260),sDn(1261,1,Wrt,oh),uZn.fk=function(n){return FA(n)},uZn.gk=function(n){return Inn(fot,zZn,345,n,7,1)},zW(Ytt,"EcorePackageImpl/28",1261),sDn(1262,1,Wrt,uh),uZn.fk=function(n){return F$(n,61)},uZn.gk=function(n){return Inn(CFt,H3n,61,n,0,1)},zW(Ytt,"EcorePackageImpl/29",1262),sDn(1236,1,Wrt,sh),uZn.fk=function(n){return F$(n,519)},uZn.gk=function(n){return Inn(c_t,{3:1,4:1,5:1,2033:1},598,n,0,1)},zW(Ytt,"EcorePackageImpl/3",1236),sDn(1263,1,Wrt,hh),uZn.fk=function(n){return F$(n,582)},uZn.gk=function(n){return Inn(BFt,EZn,2039,n,0,1)},zW(Ytt,"EcorePackageImpl/30",1263),sDn(1264,1,Wrt,fh),uZn.fk=function(n){return F$(n,160)},uZn.gk=function(n){return Inn(IBt,H3n,160,n,0,1)},zW(Ytt,"EcorePackageImpl/31",1264),sDn(1265,1,Wrt,lh),uZn.fk=function(n){return F$(n,76)},uZn.gk=function(n){return Inn(Z_t,Qrt,76,n,0,1)},zW(Ytt,"EcorePackageImpl/32",1265),sDn(1266,1,Wrt,bh),uZn.fk=function(n){return F$(n,161)},uZn.gk=function(n){return Inn(lot,zZn,161,n,0,1)},zW(Ytt,"EcorePackageImpl/33",1266),sDn(1267,1,Wrt,wh),uZn.fk=function(n){return F$(n,17)},uZn.gk=function(n){return Inn(dot,zZn,17,n,0,1)},zW(Ytt,"EcorePackageImpl/34",1267),sDn(1268,1,Wrt,dh),uZn.fk=function(n){return F$(n,297)},uZn.gk=function(n){return Inn(gat,EZn,297,n,0,1)},zW(Ytt,"EcorePackageImpl/35",1268),sDn(1269,1,Wrt,gh),uZn.fk=function(n){return F$(n,168)},uZn.gk=function(n){return Inn(yot,zZn,168,n,0,1)},zW(Ytt,"EcorePackageImpl/36",1269),sDn(1270,1,Wrt,ph),uZn.fk=function(n){return F$(n,85)},uZn.gk=function(n){return Inn(mat,EZn,85,n,0,1)},zW(Ytt,"EcorePackageImpl/37",1270),sDn(1271,1,Wrt,mh),uZn.fk=function(n){return F$(n,599)},uZn.gk=function(n){return Inn(jBt,EZn,599,n,0,1)},zW(Ytt,"EcorePackageImpl/38",1271),sDn(1272,1,Wrt,vh),uZn.fk=function(n){return!1},uZn.gk=function(n){return Inn(oUt,EZn,2216,n,0,1)},zW(Ytt,"EcorePackageImpl/39",1272),sDn(1237,1,Wrt,kh),uZn.fk=function(n){return F$(n,90)},uZn.gk=function(n){return Inn(h_t,EZn,29,n,0,1)},zW(Ytt,"EcorePackageImpl/4",1237),sDn(1273,1,Wrt,yh),uZn.fk=function(n){return F$(n,191)},uZn.gk=function(n){return Inn(Tot,zZn,191,n,0,1)},zW(Ytt,"EcorePackageImpl/40",1273),sDn(1274,1,Wrt,Mh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(Ytt,"EcorePackageImpl/41",1274),sDn(1275,1,Wrt,Th),uZn.fk=function(n){return F$(n,596)},uZn.gk=function(n){return Inn(OFt,EZn,596,n,0,1)},zW(Ytt,"EcorePackageImpl/42",1275),sDn(1276,1,Wrt,jh),uZn.fk=function(n){return!1},uZn.gk=function(n){return Inn(uUt,zZn,2217,n,0,1)},zW(Ytt,"EcorePackageImpl/43",1276),sDn(1277,1,Wrt,Eh),uZn.fk=function(n){return F$(n,44)},uZn.gk=function(n){return Inn(Sat,c1n,44,n,0,1)},zW(Ytt,"EcorePackageImpl/44",1277),sDn(1238,1,Wrt,Sh),uZn.fk=function(n){return F$(n,142)},uZn.gk=function(n){return Inn(s_t,EZn,142,n,0,1)},zW(Ytt,"EcorePackageImpl/5",1238),sDn(1239,1,Wrt,Ph),uZn.fk=function(n){return F$(n,156)},uZn.gk=function(n){return Inn(f_t,EZn,156,n,0,1)},zW(Ytt,"EcorePackageImpl/6",1239),sDn(1240,1,Wrt,Ch),uZn.fk=function(n){return F$(n,469)},uZn.gk=function(n){return Inn(w_t,EZn,685,n,0,1)},zW(Ytt,"EcorePackageImpl/7",1240),sDn(1241,1,Wrt,Ih),uZn.fk=function(n){return F$(n,582)},uZn.gk=function(n){return Inn(d_t,EZn,694,n,0,1)},zW(Ytt,"EcorePackageImpl/8",1241),sDn(1242,1,Wrt,Oh),uZn.fk=function(n){return F$(n,480)},uZn.gk=function(n){return Inn(sFt,EZn,480,n,0,1)},zW(Ytt,"EcorePackageImpl/9",1242),sDn(1038,2080,Git,Qy),uZn.Mi=function(n,t){wdn(this,uG(t,424))},uZn.Qi=function(n,t){GAn(this,n,uG(t,424))},zW(Ytt,"MinimalEObjectImpl/1ArrayDelegatingAdapterList",1038),sDn(1039,152,Bit,SQ),uZn.jj=function(){return this.a.a},zW(Ytt,"MinimalEObjectImpl/1ArrayDelegatingAdapterList/1",1039),sDn(1067,1066,{},e$),zW("org.eclipse.emf.ecore.plugin","EcorePlugin",1067);var mBt,vBt,kBt,yBt,MBt,TBt,jBt=Iq(Jrt,"Resource");sDn(799,1524,Yrt),uZn.Hl=function(n){},uZn.Il=function(n){},uZn.El=function(){return!this.a&&(this.a=new qm(this)),this.a},uZn.Fl=function(n){var t,e,i,r,c;if((i=n.length)>0){if(s3(0,n.length),47==n.charCodeAt(0)){for(c=new R7(4),r=1,t=1;t0&&(Knn(0,e,n.length),n=n.substr(0,e))}return lNn(this,n)},uZn.Gl=function(){return this.c},uZn.Ib=function(){return Ij(this.Rm)+"@"+(Hon(this)>>>0).toString(16)+" uri='"+this.d+"'"},uZn.b=!1,zW(Zrt,"ResourceImpl",799),sDn(1525,799,Yrt,Xm),zW(Zrt,"BinaryResourceImpl",1525),sDn(1190,708,Jet),uZn.bj=function(n){return F$(n,58)?JZ(this,uG(n,58)):F$(n,599)?new DD(uG(n,599).El()):xA(n)===xA(this.f)?uG(n,16).Kc():(EK(),KFt.a)},uZn.Ob=function(){return u$n(this)},uZn.a=!1,zW(art,"EcoreUtil/ContentTreeIterator",1190),sDn(1526,1190,Jet,dV),uZn.bj=function(n){return xA(n)===xA(this.f)?uG(n,15).Kc():new L6(uG(n,58))},zW(Zrt,"ResourceImpl/5",1526),sDn(658,2092,Mrt,qm),uZn.Hc=function(n){return this.i<=4?sSn(this,n):F$(n,54)&&uG(n,54).Jh()==this.a},uZn.Mi=function(n,t){n==this.i-1&&(this.a.b||(this.a.b=!0))},uZn.Oi=function(n,t){0==n?this.a.b||(this.a.b=!0):Ann(this,n,t)},uZn.Qi=function(n,t){},uZn.Ri=function(n,t,e){},uZn.Lj=function(){return 2},uZn.jj=function(){return this.a},uZn.Mj=function(){return!0},uZn.Nj=function(n,t){return t=uG(n,54).fi(this.a,t)},uZn.Oj=function(n,t){return uG(n,54).fi(null,t)},uZn.Pj=function(){return!1},uZn.Si=function(){return!0},uZn.aj=function(n){return Inn(nFt,EZn,58,n,0,1)},uZn.Yi=function(){return!1},zW(Zrt,"ResourceImpl/ContentsEList",658),sDn(970,2062,m1n,zm),uZn.fd=function(n){return this.a.Ki(n)},uZn.gc=function(){return this.a.gc()},zW(art,"AbstractSequentialInternalEList/1",970),sDn(634,1,{},HG),zW(art,"BasicExtendedMetaData",634),sDn(1181,1,{},CA),uZn.Jl=function(){return null},uZn.Kl=function(){return-2==this.a&&fw(this,qCn(this.d,this.b)),this.a},uZn.Ll=function(){return null},uZn.Ml=function(){return hZ(),hZ(),zot},uZn.xe=function(){return this.c==wct&&lw(this,ckn(this.d,this.b)),this.c},uZn.Nl=function(){return 0},uZn.a=-2,uZn.c=wct,zW(art,"BasicExtendedMetaData/EClassExtendedMetaDataImpl",1181),sDn(1182,1,{},g4),uZn.Jl=function(){return this.a==(N7(),MBt)&&dw(this,TBn(this.f,this.b)),this.a},uZn.Kl=function(){return 0},uZn.Ll=function(){return this.c==(N7(),MBt)&&bw(this,jBn(this.f,this.b)),this.c},uZn.Ml=function(){return!this.d&&pw(this,iqn(this.f,this.b)),this.d},uZn.xe=function(){return this.e==wct&&vw(this,ckn(this.f,this.b)),this.e},uZn.Nl=function(){return-2==this.g&&yw(this,DPn(this.f,this.b)),this.g},uZn.e=wct,uZn.g=-2,zW(art,"BasicExtendedMetaData/EDataTypeExtendedMetaDataImpl",1182),sDn(1180,1,{},IA),uZn.b=!1,uZn.c=!1,zW(art,"BasicExtendedMetaData/EPackageExtendedMetaDataImpl",1180),sDn(1183,1,{},p4),uZn.c=-2,uZn.e=wct,uZn.f=wct,zW(art,"BasicExtendedMetaData/EStructuralFeatureExtendedMetaDataImpl",1183),sDn(593,632,Trt,_G),uZn.Lj=function(){return this.c},uZn.ol=function(){return!1},uZn.Wi=function(n,t){return t},uZn.c=0,zW(art,"EDataTypeEList",593);var EBt,SBt,PBt,CBt,IBt=Iq(art,"FeatureMap");sDn(78,593,{3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1,79:1,160:1,220:1,2036:1,71:1,97:1},wsn),uZn.bd=function(n,t){iKn(this,n,uG(t,76))},uZn.Fc=function(n){return Qxn(this,uG(n,76))},uZn.Hi=function(n){OW(this,uG(n,76))},uZn.Nj=function(n,t){return q_(this,uG(n,76),t)},uZn.Oj=function(n,t){return X_(this,uG(n,76),t)},uZn.Ti=function(n,t){return bUn(this,n,t)},uZn.Wi=function(n,t){return IVn(this,n,uG(t,76))},uZn.hd=function(n,t){return kFn(this,n,uG(t,76))},uZn.Uj=function(n,t){return z_(this,uG(n,76),t)},uZn.Vj=function(n,t){return V_(this,uG(n,76),t)},uZn.Wj=function(n,t,e){return aPn(this,uG(n,76),uG(t,76),e)},uZn.Zi=function(n,t){return WPn(this,n,uG(t,76))},uZn.Ol=function(n,t){return GHn(this,n,t)},uZn.cd=function(n,t){var e,i,r,c,a,o,u,s,h;for(s=new Drn(t.gc()),r=t.Kc();r.Ob();)if(c=(i=uG(r.Pb(),76)).Lk(),EFn(this.e,c))(!c.Si()||!H5(this,c,i.md())&&!sSn(s,i))&&ttn(s,i);else{for(h=VKn(this.e.Dh(),c),e=uG(this.g,124),a=!0,o=0;o=0;)if(t=n[this.c],this.k.am(t.Lk()))return this.j=this.f?t:t.md(),this.i=-2,!0;return this.i=-1,this.g=-1,!1},zW(art,"BasicFeatureMap/FeatureEIterator",420),sDn(676,420,UZn,yL),uZn.ul=function(){return!0},zW(art,"BasicFeatureMap/ResolvingFeatureEIterator",676),sDn(968,496,Irt,G$),uZn.pj=function(){return this},zW(art,"EContentsEList/1",968),sDn(969,496,Irt,kL),uZn.ul=function(){return!1},zW(art,"EContentsEList/2",969),sDn(967,287,Ort,q$),uZn.wl=function(n){},uZn.Ob=function(){return!1},uZn.Sb=function(){return!1},zW(art,"EContentsEList/FeatureIteratorImpl/1",967),sDn(840,593,Trt,jD),uZn.Ni=function(){this.a=!0},uZn.Qj=function(){return this.a},uZn.Gk=function(){var n;Czn(this),uN(this.e)?(n=this.a,this.a=!1,Msn(this.e,new j9(this.e,2,this.c,n,!1))):this.a=!1},uZn.a=!1,zW(art,"EDataTypeEList/Unsettable",840),sDn(1958,593,Trt,ED),uZn.Si=function(){return!0},zW(art,"EDataTypeUniqueEList",1958),sDn(1959,840,Trt,SD),uZn.Si=function(){return!0},zW(art,"EDataTypeUniqueEList/Unsettable",1959),sDn(147,83,Trt,PD),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectContainmentEList/Resolving",147),sDn(1184,555,Trt,CD),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectContainmentEList/Unsettable/Resolving",1184),sDn(766,14,Trt,r_),uZn.Ni=function(){this.a=!0},uZn.Qj=function(){return this.a},uZn.Gk=function(){var n;Czn(this),uN(this.e)?(n=this.a,this.a=!1,Msn(this.e,new j9(this.e,2,this.c,n,!1))):this.a=!1},uZn.a=!1,zW(art,"EObjectContainmentWithInverseEList/Unsettable",766),sDn(1222,766,Trt,c_),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectContainmentWithInverseEList/Unsettable/Resolving",1222),sDn(757,505,Trt,ID),uZn.Ni=function(){this.a=!0},uZn.Qj=function(){return this.a},uZn.Gk=function(){var n;Czn(this),uN(this.e)?(n=this.a,this.a=!1,Msn(this.e,new j9(this.e,2,this.c,n,!1))):this.a=!1},uZn.a=!1,zW(art,"EObjectEList/Unsettable",757),sDn(338,505,Trt,OD),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectResolvingEList",338),sDn(1844,757,Trt,AD),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectResolvingEList/Unsettable",1844),sDn(1527,1,{},Ah),zW(art,"EObjectValidator",1527),sDn(559,505,Trt,wV),uZn.il=function(){return this.d},uZn.jl=function(){return this.b},uZn.Mj=function(){return!0},uZn.ml=function(){return!0},uZn.b=0,zW(art,"EObjectWithInverseEList",559),sDn(1225,559,Trt,a_),uZn.ll=function(){return!0},zW(art,"EObjectWithInverseEList/ManyInverse",1225),sDn(635,559,Trt,o_),uZn.Ni=function(){this.a=!0},uZn.Qj=function(){return this.a},uZn.Gk=function(){var n;Czn(this),uN(this.e)?(n=this.a,this.a=!1,Msn(this.e,new j9(this.e,2,this.c,n,!1))):this.a=!1},uZn.a=!1,zW(art,"EObjectWithInverseEList/Unsettable",635),sDn(1224,635,Trt,s_),uZn.ll=function(){return!0},zW(art,"EObjectWithInverseEList/Unsettable/ManyInverse",1224),sDn(767,559,Trt,u_),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectWithInverseResolvingEList",767),sDn(32,767,Trt,f_),uZn.ll=function(){return!0},zW(art,"EObjectWithInverseResolvingEList/ManyInverse",32),sDn(768,635,Trt,h_),uZn.nl=function(){return!0},uZn.Wi=function(n,t){return R$n(this,n,uG(t,58))},zW(art,"EObjectWithInverseResolvingEList/Unsettable",768),sDn(1223,768,Trt,l_),uZn.ll=function(){return!0},zW(art,"EObjectWithInverseResolvingEList/Unsettable/ManyInverse",1223),sDn(1185,632,Trt),uZn.Li=function(){return!(1792&this.b)},uZn.Ni=function(){this.b|=1},uZn.kl=function(){return!!(4&this.b)},uZn.Mj=function(){return!!(40&this.b)},uZn.ll=function(){return!!(16&this.b)},uZn.ml=function(){return!!(8&this.b)},uZn.nl=function(){return!!(this.b&frt)},uZn.al=function(){return!!(32&this.b)},uZn.ol=function(){return!!(this.b&w1n)},uZn.fk=function(n){return this.d?v5(this.d,n):this.Lk().Hk().fk(n)},uZn.Qj=function(){return 2&this.b?!!(1&this.b):0!=this.i},uZn.Si=function(){return!!(128&this.b)},uZn.Gk=function(){var n;Czn(this),2&this.b&&(uN(this.e)?(n=!!(1&this.b),this.b&=-2,Yv(this,new j9(this.e,2,emn(this.e.Dh(),this.Lk()),n,!1))):this.b&=-2)},uZn.Yi=function(){return!(1536&this.b)},uZn.b=0,zW(art,"EcoreEList/Generic",1185),sDn(1186,1185,Trt,yZ),uZn.Lk=function(){return this.a},zW(art,"EcoreEList/Dynamic",1186),sDn(765,66,Qet,Vm),uZn.aj=function(n){return Acn(this.a.a,n)},zW(art,"EcoreEMap/1",765),sDn(764,83,Trt,kV),uZn.Mi=function(n,t){bMn(this.b,uG(t,136))},uZn.Oi=function(n,t){Osn(this.b)},uZn.Pi=function(n,t,e){var i;++(i=this.b,uG(t,136),i).e},uZn.Qi=function(n,t){Vdn(this.b,uG(t,136))},uZn.Ri=function(n,t,e){Vdn(this.b,uG(e,136)),xA(e)===xA(t)&&uG(e,136).Ci(WN(uG(t,136).ld())),bMn(this.b,uG(t,136))},zW(art,"EcoreEMap/DelegateEObjectContainmentEList",764),sDn(1220,141,urt,xan),zW(art,"EcoreEMap/Unsettable",1220),sDn(1221,764,Trt,b_),uZn.Ni=function(){this.a=!0},uZn.Qj=function(){return this.a},uZn.Gk=function(){var n;Czn(this),uN(this.e)?(n=this.a,this.a=!1,Msn(this.e,new j9(this.e,2,this.c,n,!1))):this.a=!1},uZn.a=!1,zW(art,"EcoreEMap/Unsettable/UnsettableDelegateEObjectContainmentEList",1221),sDn(1189,215,B0n,DW),uZn.a=!1,uZn.b=!1,zW(art,"EcoreUtil/Copier",1189),sDn(759,1,$Zn,L6),uZn.Nb=function(n){SV(this,n)},uZn.Ob=function(){return Ymn(this)},uZn.Pb=function(){var n;return Ymn(this),n=this.b,this.b=null,n},uZn.Qb=function(){this.a.Qb()},zW(art,"EcoreUtil/ProperContentIterator",759),sDn(1528,1527,{},_l),zW(art,"EcoreValidator",1528),Iq(art,"FeatureMapUtil/Validator"),sDn(1295,1,{2041:1},Lh),uZn.am=function(n){return!0},zW(art,"FeatureMapUtil/1",1295),sDn(773,1,{2041:1},MQn),uZn.am=function(n){var t;return this.c==n||(null==(t=gK(cQ(this.a,n)))?DBn(this,n)?(W9(this.a,n,(qx(),eot)),!0):(W9(this.a,n,(qx(),tot)),!1):t==(qx(),eot))},uZn.e=!1,zW(art,"FeatureMapUtil/BasicValidator",773),sDn(774,45,B0n,U$),zW(art,"FeatureMapUtil/BasicValidator/Cache",774),sDn(509,56,{20:1,31:1,56:1,16:1,15:1,61:1,79:1,71:1,97:1},OA),uZn.bd=function(n,t){LFn(this.c,this.b,n,t)},uZn.Fc=function(n){return GHn(this.c,this.b,n)},uZn.cd=function(n,t){return _Xn(this.c,this.b,n,t)},uZn.Gc=function(n){return K$(this,n)},uZn.Gi=function(n,t){hrn(this.c,this.b,n,t)},uZn.Wk=function(n,t){return OBn(this.c,this.b,n,t)},uZn.$i=function(n){return gXn(this.c,this.b,n,!1)},uZn.Ii=function(){return wN(this.c,this.b)},uZn.Ji=function(){return dN(this.c,this.b)},uZn.Ki=function(n){return Onn(this.c,this.b,n)},uZn.Xk=function(n,t){return rF(this,n,t)},uZn.$b=function(){Zv(this)},uZn.Hc=function(n){return H5(this.c,this.b,n)},uZn.Ic=function(n){return Run(this.c,this.b,n)},uZn.Xb=function(n){return gXn(this.c,this.b,n,!0)},uZn.Fk=function(n){return this},uZn.dd=function(n){return U5(this.c,this.b,n)},uZn.dc=function(){return $A(this)},uZn.Qj=function(){return!kmn(this.c,this.b)},uZn.Kc=function(){return kin(this.c,this.b)},uZn.ed=function(){return yin(this.c,this.b)},uZn.fd=function(n){return lgn(this.c,this.b,n)},uZn.Ti=function(n,t){return EGn(this.c,this.b,n,t)},uZn.Ui=function(n,t){xnn(this.c,this.b,n,t)},uZn.gd=function(n){return VOn(this.c,this.b,n)},uZn.Mc=function(n){return DHn(this.c,this.b,n)},uZn.hd=function(n,t){return hqn(this.c,this.b,n,t)},uZn.Wb=function(n){C$n(this.c,this.b),K$(this,uG(n,15))},uZn.gc=function(){return fgn(this.c,this.b)},uZn.Pc=function(){return v4(this.c,this.b)},uZn.Qc=function(n){return G5(this.c,this.b,n)},uZn.Ib=function(){var n,t;for((t=new zM).a+="[",n=wN(this.c,this.b);Zln(n);)VA(t,ox(_yn(n))),Zln(n)&&(t.a+=TZn);return t.a+="]",t.a},uZn.Gk=function(){C$n(this.c,this.b)},zW(art,"FeatureMapUtil/FeatureEList",509),sDn(644,39,Bit,i8),uZn.hj=function(n){return ydn(this,n)},uZn.mj=function(n){var t,e,i,r;switch(this.d){case 1:case 2:if(xA(n.jj())===xA(this.c)&&ydn(this,null)==n.hj(null))return this.g=n.ij(),1==n.gj()&&(this.d=1),!0;break;case 3:if(3===n.gj()&&xA(n.jj())===xA(this.c)&&ydn(this,null)==n.hj(null))return this.d=5,ttn(t=new Drn(2),this.g),ttn(t,n.ij()),this.g=t,!0;break;case 5:if(3===n.gj()&&xA(n.jj())===xA(this.c)&&ydn(this,null)==n.hj(null))return uG(this.g,16).Fc(n.ij()),!0;break;case 4:switch(n.gj()){case 3:if(xA(n.jj())===xA(this.c)&&ydn(this,null)==n.hj(null))return this.d=1,this.g=n.ij(),!0;break;case 4:if(xA(n.jj())===xA(this.c)&&ydn(this,null)==n.hj(null))return this.d=6,ttn(r=new Drn(2),this.n),ttn(r,n.kj()),this.n=r,i=Uhn(cT(YHt,1),W1n,28,15,[this.o,n.lj()]),this.g=i,!0}break;case 6:if(4===n.gj()&&xA(n.jj())===xA(this.c)&&ydn(this,null)==n.hj(null))return uG(this.n,16).Fc(n.kj()),qGn(i=uG(this.g,53),0,e=Inn(YHt,W1n,28,i.length+1,15,1),0,i.length),e[i.length]=n.lj(),this.g=e,!0}return!1},zW(art,"FeatureMapUtil/FeatureENotificationImpl",644),sDn(564,509,{20:1,31:1,56:1,16:1,15:1,61:1,79:1,160:1,220:1,2036:1,71:1,97:1},Cq),uZn.Ol=function(n,t){return GHn(this.c,n,t)},uZn.Pl=function(n,t,e){return OBn(this.c,n,t,e)},uZn.Ql=function(n,t,e){return fXn(this.c,n,t,e)},uZn.Rl=function(){return this},uZn.Sl=function(n,t){return dXn(this.c,n,t)},uZn.Tl=function(n){return uG(gXn(this.c,this.b,n,!1),76).Lk()},uZn.Ul=function(n){return uG(gXn(this.c,this.b,n,!1),76).md()},uZn.Vl=function(){return this.a},uZn.Wl=function(n){return!kmn(this.c,n)},uZn.Xl=function(n,t){BXn(this.c,n,t)},uZn.Yl=function(n){return non(this.c,n)},uZn.Zl=function(n){ETn(this.c,n)},zW(art,"FeatureMapUtil/FeatureFeatureMap",564),sDn(1294,1,ort,PA),uZn.Fk=function(n){return gXn(this.b,this.a,-1,n)},uZn.Qj=function(){return!kmn(this.b,this.a)},uZn.Wb=function(n){BXn(this.b,this.a,n)},uZn.Gk=function(){C$n(this.b,this.a)},zW(art,"FeatureMapUtil/FeatureValue",1294);var OBt,ABt,LBt,NBt,$Bt,DBt=Iq(gct,"AnyType");sDn(680,63,S1n,PM),zW(gct,"InvalidDatatypeValueException",680);var xBt,RBt,KBt,FBt,_Bt,BBt,HBt,UBt,GBt,qBt,XBt,zBt,VBt,WBt,QBt,JBt,YBt,ZBt,nHt,tHt,eHt,iHt,rHt,cHt,aHt,oHt,uHt,sHt,hHt,fHt,lHt=Iq(gct,pct),bHt=Iq(gct,mct),wHt=Iq(gct,vct);sDn(844,516,{110:1,94:1,93:1,58:1,54:1,99:1,857:1},iy),uZn.Lh=function(n,t,e){switch(n){case 0:return e?(!this.c&&(this.c=new wsn(this,0)),this.c):(!this.c&&(this.c=new wsn(this,0)),this.c.b);case 1:return e?(!this.c&&(this.c=new wsn(this,0)),uG(T2(this.c,(uVn(),FBt)),160)):(!this.c&&(this.c=new wsn(this,0)),uG(uG(T2(this.c,(uVn(),FBt)),160),220)).Vl();case 2:return e?(!this.b&&(this.b=new wsn(this,2)),this.b):(!this.b&&(this.b=new wsn(this,2)),this.b.b)}return $tn(this,n-iQ(this.ii()),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():this.ii(),n),t,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.c&&(this.c=new wsn(this,0)),$Hn(this.c,n,e);case 1:return(!this.c&&(this.c=new wsn(this,0)),uG(uG(T2(this.c,(uVn(),FBt)),160),71)).Xk(n,e);case 2:return!this.b&&(this.b=new wsn(this,2)),$Hn(this.b,n,e)}return uG(ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():this.ii(),t),69).wk().Ak(this,Wen(this),t-iQ(this.ii()),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.c&&0!=this.c.i;case 1:return!(!this.c&&(this.c=new wsn(this,0)),uG(T2(this.c,(uVn(),FBt)),160)).dc();case 2:return!!this.b&&0!=this.b.i}return l5(this,n-iQ(this.ii()),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():this.ii(),n))},uZn.bi=function(n,t){switch(n){case 0:return!this.c&&(this.c=new wsn(this,0)),void cW(this.c,t);case 1:return void(!this.c&&(this.c=new wsn(this,0)),uG(uG(T2(this.c,(uVn(),FBt)),160),220)).Wb(t);case 2:return!this.b&&(this.b=new wsn(this,2)),void cW(this.b,t)}lpn(this,n-iQ(this.ii()),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():this.ii(),n),t)},uZn.ii=function(){return uVn(),KBt},uZn.ki=function(n){switch(n){case 0:return!this.c&&(this.c=new wsn(this,0)),void Czn(this.c);case 1:return void(!this.c&&(this.c=new wsn(this,0)),uG(T2(this.c,(uVn(),FBt)),160)).$b();case 2:return!this.b&&(this.b=new wsn(this,2)),void Czn(this.b)}sdn(this,n-iQ(this.ii()),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():this.ii(),n))},uZn.Ib=function(){var n;return 4&this.j?vxn(this):((n=new fx(vxn(this))).a+=" (mixed: ",zA(n,this.c),n.a+=", anyAttribute: ",zA(n,this.b),n.a+=")",n.a)},zW(kct,"AnyTypeImpl",844),sDn(681,516,{110:1,94:1,93:1,58:1,54:1,99:1,2119:1,681:1},Uh),uZn.Lh=function(n,t,e){switch(n){case 0:return this.a;case 1:return this.b}return $tn(this,n-iQ((uVn(),JBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():JBt,n),t,e)},uZn.Wh=function(n){switch(n){case 0:return null!=this.a;case 1:return null!=this.b}return l5(this,n-iQ((uVn(),JBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():JBt,n))},uZn.bi=function(n,t){switch(n){case 0:return void jw(this,mK(t));case 1:return void Sw(this,mK(t))}lpn(this,n-iQ((uVn(),JBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():JBt,n),t)},uZn.ii=function(){return uVn(),JBt},uZn.ki=function(n){switch(n){case 0:return void(this.a=null);case 1:return void(this.b=null)}sdn(this,n-iQ((uVn(),JBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():JBt,n))},uZn.Ib=function(){var n;return 4&this.j?vxn(this):((n=new fx(vxn(this))).a+=" (data: ",VA(n,this.a),n.a+=", target: ",VA(n,this.b),n.a+=")",n.a)},uZn.a=null,uZn.b=null,zW(kct,"ProcessingInstructionImpl",681),sDn(682,844,{110:1,94:1,93:1,58:1,54:1,99:1,857:1,2120:1,682:1},ry),uZn.Lh=function(n,t,e){switch(n){case 0:return e?(!this.c&&(this.c=new wsn(this,0)),this.c):(!this.c&&(this.c=new wsn(this,0)),this.c.b);case 1:return e?(!this.c&&(this.c=new wsn(this,0)),uG(T2(this.c,(uVn(),FBt)),160)):(!this.c&&(this.c=new wsn(this,0)),uG(uG(T2(this.c,(uVn(),FBt)),160),220)).Vl();case 2:return e?(!this.b&&(this.b=new wsn(this,2)),this.b):(!this.b&&(this.b=new wsn(this,2)),this.b.b);case 3:return!this.c&&(this.c=new wsn(this,0)),mK(dXn(this.c,(uVn(),nHt),!0));case 4:return g_(this.a,(!this.c&&(this.c=new wsn(this,0)),mK(dXn(this.c,(uVn(),nHt),!0))));case 5:return this.a}return $tn(this,n-iQ((uVn(),ZBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():ZBt,n),t,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.c&&0!=this.c.i;case 1:return!(!this.c&&(this.c=new wsn(this,0)),uG(T2(this.c,(uVn(),FBt)),160)).dc();case 2:return!!this.b&&0!=this.b.i;case 3:return!this.c&&(this.c=new wsn(this,0)),null!=mK(dXn(this.c,(uVn(),nHt),!0));case 4:return null!=g_(this.a,(!this.c&&(this.c=new wsn(this,0)),mK(dXn(this.c,(uVn(),nHt),!0))));case 5:return!!this.a}return l5(this,n-iQ((uVn(),ZBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():ZBt,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.c&&(this.c=new wsn(this,0)),void cW(this.c,t);case 1:return void(!this.c&&(this.c=new wsn(this,0)),uG(uG(T2(this.c,(uVn(),FBt)),160),220)).Wb(t);case 2:return!this.b&&(this.b=new wsn(this,2)),void cW(this.b,t);case 3:return void m4(this,mK(t));case 4:return void m4(this,d_(this.a,t));case 5:return void Ew(this,uG(t,156))}lpn(this,n-iQ((uVn(),ZBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():ZBt,n),t)},uZn.ii=function(){return uVn(),ZBt},uZn.ki=function(n){switch(n){case 0:return!this.c&&(this.c=new wsn(this,0)),void Czn(this.c);case 1:return void(!this.c&&(this.c=new wsn(this,0)),uG(T2(this.c,(uVn(),FBt)),160)).$b();case 2:return!this.b&&(this.b=new wsn(this,2)),void Czn(this.b);case 3:return!this.c&&(this.c=new wsn(this,0)),void BXn(this.c,(uVn(),nHt),null);case 4:return void m4(this,d_(this.a,null));case 5:return void(this.a=null)}sdn(this,n-iQ((uVn(),ZBt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():ZBt,n))},zW(kct,"SimpleAnyTypeImpl",682),sDn(683,516,{110:1,94:1,93:1,58:1,54:1,99:1,2121:1,683:1},cy),uZn.Lh=function(n,t,e){switch(n){case 0:return e?(!this.a&&(this.a=new wsn(this,0)),this.a):(!this.a&&(this.a=new wsn(this,0)),this.a.b);case 1:return e?(!this.b&&(this.b=new ltn((YYn(),H_t),wBt,this,1)),this.b):(!this.b&&(this.b=new ltn((YYn(),H_t),wBt,this,1)),Tnn(this.b));case 2:return e?(!this.c&&(this.c=new ltn((YYn(),H_t),wBt,this,2)),this.c):(!this.c&&(this.c=new ltn((YYn(),H_t),wBt,this,2)),Tnn(this.c));case 3:return!this.a&&(this.a=new wsn(this,0)),T2(this.a,(uVn(),iHt));case 4:return!this.a&&(this.a=new wsn(this,0)),T2(this.a,(uVn(),rHt));case 5:return!this.a&&(this.a=new wsn(this,0)),T2(this.a,(uVn(),aHt));case 6:return!this.a&&(this.a=new wsn(this,0)),T2(this.a,(uVn(),oHt))}return $tn(this,n-iQ((uVn(),eHt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():eHt,n),t,e)},uZn.Uh=function(n,t,e){switch(t){case 0:return!this.a&&(this.a=new wsn(this,0)),$Hn(this.a,n,e);case 1:return!this.b&&(this.b=new ltn((YYn(),H_t),wBt,this,1)),G_(this.b,n,e);case 2:return!this.c&&(this.c=new ltn((YYn(),H_t),wBt,this,2)),G_(this.c,n,e);case 5:return!this.a&&(this.a=new wsn(this,0)),rF(T2(this.a,(uVn(),aHt)),n,e)}return uG(ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():(uVn(),eHt),t),69).wk().Ak(this,Wen(this),t-iQ((uVn(),eHt)),n,e)},uZn.Wh=function(n){switch(n){case 0:return!!this.a&&0!=this.a.i;case 1:return!!this.b&&0!=this.b.f;case 2:return!!this.c&&0!=this.c.f;case 3:return!this.a&&(this.a=new wsn(this,0)),!$A(T2(this.a,(uVn(),iHt)));case 4:return!this.a&&(this.a=new wsn(this,0)),!$A(T2(this.a,(uVn(),rHt)));case 5:return!this.a&&(this.a=new wsn(this,0)),!$A(T2(this.a,(uVn(),aHt)));case 6:return!this.a&&(this.a=new wsn(this,0)),!$A(T2(this.a,(uVn(),oHt)))}return l5(this,n-iQ((uVn(),eHt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():eHt,n))},uZn.bi=function(n,t){switch(n){case 0:return!this.a&&(this.a=new wsn(this,0)),void cW(this.a,t);case 1:return!this.b&&(this.b=new ltn((YYn(),H_t),wBt,this,1)),void Jun(this.b,t);case 2:return!this.c&&(this.c=new ltn((YYn(),H_t),wBt,this,2)),void Jun(this.c,t);case 3:return!this.a&&(this.a=new wsn(this,0)),Zv(T2(this.a,(uVn(),iHt))),!this.a&&(this.a=new wsn(this,0)),void K$(T2(this.a,iHt),uG(t,16));case 4:return!this.a&&(this.a=new wsn(this,0)),Zv(T2(this.a,(uVn(),rHt))),!this.a&&(this.a=new wsn(this,0)),void K$(T2(this.a,rHt),uG(t,16));case 5:return!this.a&&(this.a=new wsn(this,0)),Zv(T2(this.a,(uVn(),aHt))),!this.a&&(this.a=new wsn(this,0)),void K$(T2(this.a,aHt),uG(t,16));case 6:return!this.a&&(this.a=new wsn(this,0)),Zv(T2(this.a,(uVn(),oHt))),!this.a&&(this.a=new wsn(this,0)),void K$(T2(this.a,oHt),uG(t,16))}lpn(this,n-iQ((uVn(),eHt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():eHt,n),t)},uZn.ii=function(){return uVn(),eHt},uZn.ki=function(n){switch(n){case 0:return!this.a&&(this.a=new wsn(this,0)),void Czn(this.a);case 1:return!this.b&&(this.b=new ltn((YYn(),H_t),wBt,this,1)),void this.b.c.$b();case 2:return!this.c&&(this.c=new ltn((YYn(),H_t),wBt,this,2)),void this.c.c.$b();case 3:return!this.a&&(this.a=new wsn(this,0)),void Zv(T2(this.a,(uVn(),iHt)));case 4:return!this.a&&(this.a=new wsn(this,0)),void Zv(T2(this.a,(uVn(),rHt)));case 5:return!this.a&&(this.a=new wsn(this,0)),void Zv(T2(this.a,(uVn(),aHt)));case 6:return!this.a&&(this.a=new wsn(this,0)),void Zv(T2(this.a,(uVn(),oHt)))}sdn(this,n-iQ((uVn(),eHt)),ern(2&this.j?(!this.k&&(this.k=new Ll),this.k).Nk():eHt,n))},uZn.Ib=function(){var n;return 4&this.j?vxn(this):((n=new fx(vxn(this))).a+=" (mixed: ",zA(n,this.a),n.a+=")",n.a)},zW(kct,"XMLTypeDocumentRootImpl",683),sDn(2028,720,{110:1,94:1,93:1,480:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1,2122:1},Nh),uZn.ri=function(n,t){switch(n.hk()){case 7:case 8:case 9:case 10:case 16:case 22:case 23:case 24:case 25:case 26:case 32:case 33:case 34:case 36:case 37:case 44:case 45:case 50:case 51:case 53:case 55:case 56:case 57:case 58:case 60:case 61:case 4:return null==t?null:cpn(t);case 19:case 28:case 29:case 35:case 38:case 39:case 41:case 46:case 52:case 54:case 5:return mK(t);case 6:return lK(uG(t,195));case 12:case 47:case 49:case 11:return cWn(this,n,t);case 13:return null==t?null:VXn(uG(t,247));case 15:case 14:return null==t?null:MW(uM(pK(t)));case 17:return oPn((uVn(),t));case 18:return oPn(t);case 21:case 20:return null==t?null:TW(uG(t,161).a);case 27:return bK(uG(t,195));case 30:return STn((uVn(),uG(t,15)));case 31:return STn(uG(t,15));case 40:return dK((uVn(),t));case 42:return uPn((uVn(),t));case 43:return uPn(t);case 59:case 48:return wK((uVn(),t));default:throw hv(new vM(tet+n.xe()+eet))}},uZn.si=function(n){var t;switch(-1==n.G&&(n.G=(t=Hrn(n))?Hyn(t.vi(),n):-1),n.G){case 0:return new iy;case 1:return new Uh;case 2:return new ry;case 3:return new cy;default:throw hv(new vM(cet+n.zb+eet))}},uZn.ti=function(n,t){var e,i,r,c,a,o,u,s,h,f,l,b,w,d,g,p;switch(n.hk()){case 5:case 52:case 4:return t;case 6:return syn(t);case 8:case 7:return null==t?null:MPn(t);case 9:return null==t?null:Ben(vUn((i=yXn(t,!0)).length>0&&(s3(0,i.length),43==i.charCodeAt(0))?(s3(1,i.length+1),i.substr(1)):i,-128,127)<<24>>24);case 10:return null==t?null:Ben(vUn((r=yXn(t,!0)).length>0&&(s3(0,r.length),43==r.charCodeAt(0))?(s3(1,r.length+1),r.substr(1)):r,-128,127)<<24>>24);case 11:return mK(cYn(this,(uVn(),HBt),t));case 12:return mK(cYn(this,(uVn(),UBt),t));case 13:return null==t?null:new Wj(yXn(t,!0));case 15:case 14:return iRn(t);case 16:return mK(cYn(this,(uVn(),GBt),t));case 17:return bvn((uVn(),t));case 18:return bvn(t);case 28:case 29:case 35:case 38:case 39:case 41:case 54:case 19:return yXn(t,!0);case 21:case 20:return vRn(t);case 22:return mK(cYn(this,(uVn(),qBt),t));case 23:return mK(cYn(this,(uVn(),XBt),t));case 24:return mK(cYn(this,(uVn(),zBt),t));case 25:return mK(cYn(this,(uVn(),VBt),t));case 26:return mK(cYn(this,(uVn(),WBt),t));case 27:return Ckn(t);case 30:return wvn((uVn(),t));case 31:return wvn(t);case 32:return null==t?null:xwn(vUn((h=yXn(t,!0)).length>0&&(s3(0,h.length),43==h.charCodeAt(0))?(s3(1,h.length+1),h.substr(1)):h,j1n,vZn));case 33:return null==t?null:new PN((f=yXn(t,!0)).length>0&&(s3(0,f.length),43==f.charCodeAt(0))?(s3(1,f.length+1),f.substr(1)):f);case 34:return null==t?null:xwn(vUn((l=yXn(t,!0)).length>0&&(s3(0,l.length),43==l.charCodeAt(0))?(s3(1,l.length+1),l.substr(1)):l,j1n,vZn));case 36:return null==t?null:Hvn(tJn((b=yXn(t,!0)).length>0&&(s3(0,b.length),43==b.charCodeAt(0))?(s3(1,b.length+1),b.substr(1)):b));case 37:return null==t?null:Hvn(tJn((w=yXn(t,!0)).length>0&&(s3(0,w.length),43==w.charCodeAt(0))?(s3(1,w.length+1),w.substr(1)):w));case 40:return nTn((uVn(),t));case 42:return dvn((uVn(),t));case 43:return dvn(t);case 44:return null==t?null:new PN((d=yXn(t,!0)).length>0&&(s3(0,d.length),43==d.charCodeAt(0))?(s3(1,d.length+1),d.substr(1)):d);case 45:return null==t?null:new PN((g=yXn(t,!0)).length>0&&(s3(0,g.length),43==g.charCodeAt(0))?(s3(1,g.length+1),g.substr(1)):g);case 46:return yXn(t,!1);case 47:return mK(cYn(this,(uVn(),QBt),t));case 59:case 48:return ZMn((uVn(),t));case 49:return mK(cYn(this,(uVn(),YBt),t));case 50:return null==t?null:Rwn(vUn((p=yXn(t,!0)).length>0&&(s3(0,p.length),43==p.charCodeAt(0))?(s3(1,p.length+1),p.substr(1)):p,xrt,32767)<<16>>16);case 51:return null==t?null:Rwn(vUn((c=yXn(t,!0)).length>0&&(s3(0,c.length),43==c.charCodeAt(0))?(s3(1,c.length+1),c.substr(1)):c,xrt,32767)<<16>>16);case 53:return mK(cYn(this,(uVn(),tHt),t));case 55:return null==t?null:Rwn(vUn((a=yXn(t,!0)).length>0&&(s3(0,a.length),43==a.charCodeAt(0))?(s3(1,a.length+1),a.substr(1)):a,xrt,32767)<<16>>16);case 56:return null==t?null:Rwn(vUn((o=yXn(t,!0)).length>0&&(s3(0,o.length),43==o.charCodeAt(0))?(s3(1,o.length+1),o.substr(1)):o,xrt,32767)<<16>>16);case 57:return null==t?null:Hvn(tJn((u=yXn(t,!0)).length>0&&(s3(0,u.length),43==u.charCodeAt(0))?(s3(1,u.length+1),u.substr(1)):u));case 58:return null==t?null:Hvn(tJn((s=yXn(t,!0)).length>0&&(s3(0,s.length),43==s.charCodeAt(0))?(s3(1,s.length+1),s.substr(1)):s));case 60:return null==t?null:xwn(vUn((e=yXn(t,!0)).length>0&&(s3(0,e.length),43==e.charCodeAt(0))?(s3(1,e.length+1),e.substr(1)):e,j1n,vZn));case 61:return null==t?null:xwn(vUn(yXn(t,!0),j1n,vZn));default:throw hv(new vM(tet+n.xe()+eet))}},zW(kct,"XMLTypeFactoryImpl",2028),sDn(594,184,{110:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,54:1,99:1,158:1,184:1,119:1,120:1,690:1,2044:1,594:1},gJ),uZn.N=!1,uZn.O=!1;var dHt,gHt,pHt,mHt,vHt,kHt=!1;zW(kct,"XMLTypePackageImpl",594),sDn(1961,1,{851:1},$h),uZn.Kk=function(){return vGn(),qHt},zW(kct,"XMLTypePackageImpl/1",1961),sDn(1970,1,Wrt,Dh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/10",1970),sDn(1971,1,Wrt,xh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/11",1971),sDn(1972,1,Wrt,Rh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/12",1972),sDn(1973,1,Wrt,Kh),uZn.fk=function(n){return FA(n)},uZn.gk=function(n){return Inn(fot,zZn,345,n,7,1)},zW(kct,"XMLTypePackageImpl/13",1973),sDn(1974,1,Wrt,Fh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/14",1974),sDn(1975,1,Wrt,_h),uZn.fk=function(n){return F$(n,15)},uZn.gk=function(n){return Inn(yat,H3n,15,n,0,1)},zW(kct,"XMLTypePackageImpl/15",1975),sDn(1976,1,Wrt,Bh),uZn.fk=function(n){return F$(n,15)},uZn.gk=function(n){return Inn(yat,H3n,15,n,0,1)},zW(kct,"XMLTypePackageImpl/16",1976),sDn(1977,1,Wrt,Hh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/17",1977),sDn(1978,1,Wrt,Gh),uZn.fk=function(n){return F$(n,161)},uZn.gk=function(n){return Inn(lot,zZn,161,n,0,1)},zW(kct,"XMLTypePackageImpl/18",1978),sDn(1979,1,Wrt,qh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/19",1979),sDn(1962,1,Wrt,Xh),uZn.fk=function(n){return F$(n,857)},uZn.gk=function(n){return Inn(DBt,EZn,857,n,0,1)},zW(kct,"XMLTypePackageImpl/2",1962),sDn(1980,1,Wrt,zh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/20",1980),sDn(1981,1,Wrt,Vh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/21",1981),sDn(1982,1,Wrt,Wh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/22",1982),sDn(1983,1,Wrt,Qh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/23",1983),sDn(1984,1,Wrt,Jh),uZn.fk=function(n){return F$(n,195)},uZn.gk=function(n){return Inn(tUt,zZn,195,n,0,2)},zW(kct,"XMLTypePackageImpl/24",1984),sDn(1985,1,Wrt,Yh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/25",1985),sDn(1986,1,Wrt,Zh),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/26",1986),sDn(1987,1,Wrt,nf),uZn.fk=function(n){return F$(n,15)},uZn.gk=function(n){return Inn(yat,H3n,15,n,0,1)},zW(kct,"XMLTypePackageImpl/27",1987),sDn(1988,1,Wrt,tf),uZn.fk=function(n){return F$(n,15)},uZn.gk=function(n){return Inn(yat,H3n,15,n,0,1)},zW(kct,"XMLTypePackageImpl/28",1988),sDn(1989,1,Wrt,ef),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/29",1989),sDn(1963,1,Wrt,rf),uZn.fk=function(n){return F$(n,681)},uZn.gk=function(n){return Inn(lHt,EZn,2119,n,0,1)},zW(kct,"XMLTypePackageImpl/3",1963),sDn(1990,1,Wrt,cf),uZn.fk=function(n){return F$(n,17)},uZn.gk=function(n){return Inn(dot,zZn,17,n,0,1)},zW(kct,"XMLTypePackageImpl/30",1990),sDn(1991,1,Wrt,af),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/31",1991),sDn(1992,1,Wrt,of),uZn.fk=function(n){return F$(n,168)},uZn.gk=function(n){return Inn(yot,zZn,168,n,0,1)},zW(kct,"XMLTypePackageImpl/32",1992),sDn(1993,1,Wrt,uf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/33",1993),sDn(1994,1,Wrt,sf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/34",1994),sDn(1995,1,Wrt,hf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/35",1995),sDn(1996,1,Wrt,ff),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/36",1996),sDn(1997,1,Wrt,lf),uZn.fk=function(n){return F$(n,15)},uZn.gk=function(n){return Inn(yat,H3n,15,n,0,1)},zW(kct,"XMLTypePackageImpl/37",1997),sDn(1998,1,Wrt,bf),uZn.fk=function(n){return F$(n,15)},uZn.gk=function(n){return Inn(yat,H3n,15,n,0,1)},zW(kct,"XMLTypePackageImpl/38",1998),sDn(1999,1,Wrt,wf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/39",1999),sDn(1964,1,Wrt,df),uZn.fk=function(n){return F$(n,682)},uZn.gk=function(n){return Inn(bHt,EZn,2120,n,0,1)},zW(kct,"XMLTypePackageImpl/4",1964),sDn(2e3,1,Wrt,gf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/40",2e3),sDn(2001,1,Wrt,pf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/41",2001),sDn(2002,1,Wrt,mf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/42",2002),sDn(2003,1,Wrt,vf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/43",2003),sDn(2004,1,Wrt,kf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/44",2004),sDn(2005,1,Wrt,yf),uZn.fk=function(n){return F$(n,191)},uZn.gk=function(n){return Inn(Tot,zZn,191,n,0,1)},zW(kct,"XMLTypePackageImpl/45",2005),sDn(2006,1,Wrt,Mf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/46",2006),sDn(2007,1,Wrt,Tf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/47",2007),sDn(2008,1,Wrt,jf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/48",2008),sDn(2009,1,Wrt,Ef),uZn.fk=function(n){return F$(n,191)},uZn.gk=function(n){return Inn(Tot,zZn,191,n,0,1)},zW(kct,"XMLTypePackageImpl/49",2009),sDn(1965,1,Wrt,Sf),uZn.fk=function(n){return F$(n,683)},uZn.gk=function(n){return Inn(wHt,EZn,2121,n,0,1)},zW(kct,"XMLTypePackageImpl/5",1965),sDn(2010,1,Wrt,Pf),uZn.fk=function(n){return F$(n,168)},uZn.gk=function(n){return Inn(yot,zZn,168,n,0,1)},zW(kct,"XMLTypePackageImpl/50",2010),sDn(2011,1,Wrt,Cf),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/51",2011),sDn(2012,1,Wrt,If),uZn.fk=function(n){return F$(n,17)},uZn.gk=function(n){return Inn(dot,zZn,17,n,0,1)},zW(kct,"XMLTypePackageImpl/52",2012),sDn(1966,1,Wrt,Of),uZn.fk=function(n){return RA(n)},uZn.gk=function(n){return Inn($ot,zZn,2,n,6,1)},zW(kct,"XMLTypePackageImpl/6",1966),sDn(1967,1,Wrt,Af),uZn.fk=function(n){return F$(n,195)},uZn.gk=function(n){return Inn(tUt,zZn,195,n,0,2)},zW(kct,"XMLTypePackageImpl/7",1967),sDn(1968,1,Wrt,Lf),uZn.fk=function(n){return KA(n)},uZn.gk=function(n){return Inn(cot,zZn,485,n,8,1)},zW(kct,"XMLTypePackageImpl/8",1968),sDn(1969,1,Wrt,Nf),uZn.fk=function(n){return F$(n,222)},uZn.gk=function(n){return Inn(uot,zZn,222,n,0,1)},zW(kct,"XMLTypePackageImpl/9",1969),sDn(55,63,S1n,CM),zW(Xct,"RegEx/ParseException",55),sDn(836,1,{},$f),uZn.bm=function(n){return n16*e)throw hv(new CM(rZn((t$(),Cit))));e=16*e+r}if(125!=this.a)throw hv(new CM(rZn((t$(),Iit))));if(e>zct)throw hv(new CM(rZn((t$(),Oit))));n=e}else{if(r=0,0!=this.c||(r=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(e=r,EYn(this),0!=this.c||(r=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));n=e=16*e+r}break;case 117:if(i=0,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=16*t+i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=16*t+i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));n=t=16*t+i;break;case 118:if(EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=16*t+i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=16*t+i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=16*t+i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if(t=16*t+i,EYn(this),0!=this.c||(i=CMn(this.a))<0)throw hv(new CM(rZn((t$(),Pit))));if((t=16*t+i)>zct)throw hv(new CM(rZn((t$(),"parser.descappe.4"))));n=t;break;case 65:case 90:case 122:throw hv(new CM(rZn((t$(),Ait))))}return n},uZn.dm=function(n){var t;switch(n){case 100:t=32&~this.e?(QYn(),CHt):kJn("Nd",!0);break;case 68:t=32&~this.e?(QYn(),NHt):kJn("Nd",!1);break;case 119:t=32&~this.e?(QYn(),HHt):kJn("IsWord",!0);break;case 87:t=32&~this.e?(QYn(),DHt):kJn("IsWord",!1);break;case 115:t=32&~this.e?(QYn(),RHt):kJn("IsSpace",!0);break;case 83:t=32&~this.e?(QYn(),$Ht):kJn("IsSpace",!1);break;default:throw hv(new Ky(Vct+n.toString(16)))}return t},uZn.em=function(n){var t,e,i,r,c,a,o,u,s,h,f;for(this.b=1,EYn(this),t=null,0==this.c&&94==this.a?(EYn(this),n?(QYn(),QYn(),s=new K3(5)):(QYn(),QYn(),HFn(t=new K3(4),0,zct),s=new K3(4))):(QYn(),QYn(),s=new K3(4)),r=!0;1!=(f=this.c)&&(0!=f||93!=this.a||r);){if(r=!1,e=this.a,i=!1,10==f)switch(e){case 100:case 68:case 119:case 87:case 115:case 83:TXn(s,this.dm(e)),i=!0;break;case 105:case 73:case 99:case 67:(e=this.um(s,e))<0&&(i=!0);break;case 112:case 80:if(!(h=PNn(this,e)))throw hv(new CM(rZn((t$(),git))));TXn(s,h),i=!0;break;default:e=this.cm()}else if(20==f){if((c=aR(this.i,58,this.d))<0)throw hv(new CM(rZn((t$(),pit))));if(a=!0,94==VJ(this.i,this.d)&&(++this.d,a=!1),!(o=itn(r1(this.i,this.d,c),a,!(512&~this.e))))throw hv(new CM(rZn((t$(),vit))));if(TXn(s,o),i=!0,c+1>=this.j||93!=VJ(this.i,c+1))throw hv(new CM(rZn((t$(),pit))));this.d=c+2}if(EYn(this),!i)if(0!=this.c||45!=this.a)HFn(s,e,e);else{if(EYn(this),1==(f=this.c))throw hv(new CM(rZn((t$(),mit))));0==f&&93==this.a?(HFn(s,e,e),HFn(s,45,45)):(u=this.a,10==f&&(u=this.cm()),EYn(this),HFn(s,e,u))}(this.e&w1n)==w1n&&0==this.c&&44==this.a&&EYn(this)}if(1==this.c)throw hv(new CM(rZn((t$(),mit))));return t&&(lWn(t,s),s=t),pxn(s),szn(s),this.b=0,EYn(this),s},uZn.fm=function(){var n,t,e,i;for(e=this.em(!1);7!=(i=this.c);){if(n=this.a,(0!=i||45!=n&&38!=n)&&4!=i)throw hv(new CM(rZn((t$(),Eit))));if(EYn(this),9!=this.c)throw hv(new CM(rZn((t$(),jit))));if(t=this.em(!1),4==i)TXn(e,t);else if(45==n)lWn(e,t);else{if(38!=n)throw hv(new Ky("ASSERT"));GVn(e,t)}}return EYn(this),e},uZn.gm=function(){var n,t;return n=this.a-48,QYn(),QYn(),t=new F1(12,null,n),!this.g&&(this.g=new ck),zv(this.g,new Wm(n)),EYn(this),t},uZn.hm=function(){return EYn(this),QYn(),KHt},uZn.im=function(){return EYn(this),QYn(),xHt},uZn.jm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.km=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.lm=function(){return EYn(this),jln()},uZn.mm=function(){return EYn(this),QYn(),_Ht},uZn.nm=function(){return EYn(this),QYn(),UHt},uZn.om=function(){var n;if(this.d>=this.j||64!=(65504&(n=VJ(this.i,this.d++))))throw hv(new CM(rZn((t$(),lit))));return EYn(this),QYn(),QYn(),new IX(0,n-64)},uZn.pm=function(){return EYn(this),VGn()},uZn.qm=function(){return EYn(this),QYn(),GHt},uZn.rm=function(){var n;return QYn(),QYn(),n=new IX(0,105),EYn(this),n},uZn.sm=function(){return EYn(this),QYn(),BHt},uZn.tm=function(){return EYn(this),QYn(),FHt},uZn.um=function(n,t){return this.cm()},uZn.vm=function(){return EYn(this),QYn(),AHt},uZn.wm=function(){var n,t,e,i,r;if(this.d+1>=this.j)throw hv(new CM(rZn((t$(),sit))));if(i=-1,t=null,49<=(n=VJ(this.i,this.d))&&n<=57){if(i=n-48,!this.g&&(this.g=new ck),zv(this.g,new Wm(i)),++this.d,41!=VJ(this.i,this.d))throw hv(new CM(rZn((t$(),ait))));++this.d}else switch(63==n&&--this.d,EYn(this),(t=eYn(this)).e){case 20:case 21:case 22:case 23:break;case 8:if(7!=this.c)throw hv(new CM(rZn((t$(),ait))));break;default:throw hv(new CM(rZn((t$(),hit))))}if(EYn(this),e=null,2==(r=Evn(this)).e){if(2!=r.Pm())throw hv(new CM(rZn((t$(),fit))));e=r.Lm(1),r=r.Lm(0)}if(7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),QYn(),QYn(),new bin(i,t,r,e)},uZn.xm=function(){return EYn(this),QYn(),LHt},uZn.ym=function(){var n;if(EYn(this),n=jV(24,Evn(this)),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.zm=function(){var n;if(EYn(this),n=jV(20,Evn(this)),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.Am=function(){var n;if(EYn(this),n=jV(22,Evn(this)),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.Bm=function(){var n,t,e,i,r;for(n=0,e=0,t=-1;this.d=this.j)throw hv(new CM(rZn((t$(),oit))));if(45==t){for(++this.d;this.d=this.j)throw hv(new CM(rZn((t$(),oit))))}if(58==t){if(++this.d,EYn(this),i=GW(Evn(this),n,e),7!=this.c)throw hv(new CM(rZn((t$(),ait))));EYn(this)}else{if(41!=t)throw hv(new CM(rZn((t$(),uit))));++this.d,EYn(this),i=GW(Evn(this),n,e)}return i},uZn.Cm=function(){var n;if(EYn(this),n=jV(21,Evn(this)),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.Dm=function(){var n;if(EYn(this),n=jV(23,Evn(this)),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.Em=function(){var n,t;if(EYn(this),n=this.f++,t=EV(Evn(this),n),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),t},uZn.Fm=function(){var n;if(EYn(this),n=EV(Evn(this),0),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.Gm=function(n){return EYn(this),5==this.c?(EYn(this),CX(n,(QYn(),QYn(),new n8(9,n)))):CX(n,(QYn(),QYn(),new n8(3,n)))},uZn.Hm=function(n){var t;return EYn(this),QYn(),QYn(),t=new QN(2),5==this.c?(EYn(this),kzn(t,OHt),kzn(t,n)):(kzn(t,n),kzn(t,OHt)),t},uZn.Im=function(n){return EYn(this),5==this.c?(EYn(this),QYn(),QYn(),new n8(9,n)):(QYn(),QYn(),new n8(3,n))},uZn.a=0,uZn.b=0,uZn.c=0,uZn.d=0,uZn.e=0,uZn.f=1,uZn.g=null,uZn.j=0,zW(Xct,"RegEx/RegexParser",836),sDn(1947,836,{},ay),uZn.bm=function(n){return!1},uZn.cm=function(){return R_n(this)},uZn.dm=function(n){return MUn(n)},uZn.em=function(n){return PYn(this)},uZn.fm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.gm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.hm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.im=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.jm=function(){return EYn(this),MUn(67)},uZn.km=function(){return EYn(this),MUn(73)},uZn.lm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.mm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.nm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.om=function(){return EYn(this),MUn(99)},uZn.pm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.qm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.rm=function(){return EYn(this),MUn(105)},uZn.sm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.tm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.um=function(n,t){return TXn(n,MUn(t)),-1},uZn.vm=function(){return EYn(this),QYn(),QYn(),new IX(0,94)},uZn.wm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.xm=function(){return EYn(this),QYn(),QYn(),new IX(0,36)},uZn.ym=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.zm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.Am=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.Bm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.Cm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.Dm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.Em=function(){var n;if(EYn(this),n=EV(Evn(this),0),7!=this.c)throw hv(new CM(rZn((t$(),ait))));return EYn(this),n},uZn.Fm=function(){throw hv(new CM(rZn((t$(),Lit))))},uZn.Gm=function(n){return EYn(this),CX(n,(QYn(),QYn(),new n8(3,n)))},uZn.Hm=function(n){var t;return EYn(this),QYn(),QYn(),kzn(t=new QN(2),n),kzn(t,OHt),t},uZn.Im=function(n){return EYn(this),QYn(),QYn(),new n8(3,n)};var yHt=null,MHt=null;zW(Xct,"RegEx/ParserForXMLSchema",1947),sDn(122,1,aat,Qm),uZn.Jm=function(n){throw hv(new Ky("Not supported."))},uZn.Km=function(){return-1},uZn.Lm=function(n){return null},uZn.Mm=function(){return null},uZn.Nm=function(n){},uZn.Om=function(n){},uZn.Pm=function(){return 0},uZn.Ib=function(){return this.Qm(0)},uZn.Qm=function(n){return 11==this.e?".":""},uZn.e=0;var THt,jHt,EHt,SHt,PHt,CHt,IHt,OHt,AHt,LHt,NHt,$Ht,DHt,xHt,RHt,KHt,FHt,_Ht,BHt,HHt,UHt,GHt,qHt,XHt,zHt=null,VHt=null,WHt=null,QHt=zW(Xct,"RegEx/Token",122);sDn(138,122,{3:1,138:1,122:1},K3),uZn.Qm=function(n){var t,e,i;if(4==this.e)if(this==IHt)e=".";else if(this==CHt)e="\\d";else if(this==HHt)e="\\w";else if(this==RHt)e="\\s";else{for((i=new zM).a+="[",t=0;t0&&(i.a+=","),this.b[t]===this.b[t+1]?VA(i,Mqn(this.b[t])):(VA(i,Mqn(this.b[t])),i.a+="-",VA(i,Mqn(this.b[t+1])));i.a+="]",e=i.a}else if(this==NHt)e="\\D";else if(this==DHt)e="\\W";else if(this==$Ht)e="\\S";else{for((i=new zM).a+="[^",t=0;t0&&(i.a+=","),this.b[t]===this.b[t+1]?VA(i,Mqn(this.b[t])):(VA(i,Mqn(this.b[t])),i.a+="-",VA(i,Mqn(this.b[t+1])));i.a+="]",e=i.a}return e},uZn.a=!1,uZn.c=!1,zW(Xct,"RegEx/RangeToken",138),sDn(592,1,{592:1},Wm),uZn.a=0,zW(Xct,"RegEx/RegexParser/ReferencePosition",592),sDn(591,1,{3:1,591:1},gE),uZn.Fb=function(n){var t;return null!=n&&!!F$(n,591)&&(t=uG(n,591),m_(this.b,t.b)&&this.a==t.a)},uZn.Hb=function(){return pln(this.b+"/"+XKn(this.a))},uZn.Ib=function(){return this.c.Qm(this.a)},uZn.a=0,zW(Xct,"RegEx/RegularExpression",591),sDn(228,122,aat,IX),uZn.Km=function(){return this.a},uZn.Qm=function(n){var t,e;switch(this.e){case 0:switch(this.a){case 124:case 42:case 43:case 63:case 40:case 41:case 46:case 91:case 123:case 92:e="\\"+jF(this.a&D1n);break;case 12:e="\\f";break;case 10:e="\\n";break;case 13:e="\\r";break;case 9:e="\\t";break;case 27:e="\\e";break;default:e=this.a>=P0n?"\\v"+r1(t="0"+(this.a>>>0).toString(16),t.length-6,t.length):""+jF(this.a&D1n)}break;case 8:e=this==AHt||this==LHt?""+jF(this.a&D1n):"\\"+jF(this.a&D1n);break;default:e=null}return e},uZn.a=0,zW(Xct,"RegEx/Token/CharToken",228),sDn(318,122,aat,n8),uZn.Lm=function(n){return this.a},uZn.Nm=function(n){this.b=n},uZn.Om=function(n){this.c=n},uZn.Pm=function(){return 1},uZn.Qm=function(n){var t;if(3==this.e)if(this.c<0&&this.b<0)t=this.a.Qm(n)+"*";else if(this.c==this.b)t=this.a.Qm(n)+"{"+this.c+"}";else if(this.c>=0&&this.b>=0)t=this.a.Qm(n)+"{"+this.c+","+this.b+"}";else{if(!(this.c>=0&&this.b<0))throw hv(new Ky("Token#toString(): CLOSURE "+this.c+TZn+this.b));t=this.a.Qm(n)+"{"+this.c+",}"}else if(this.c<0&&this.b<0)t=this.a.Qm(n)+"*?";else if(this.c==this.b)t=this.a.Qm(n)+"{"+this.c+"}?";else if(this.c>=0&&this.b>=0)t=this.a.Qm(n)+"{"+this.c+","+this.b+"}?";else{if(!(this.c>=0&&this.b<0))throw hv(new Ky("Token#toString(): NONGREEDYCLOSURE "+this.c+TZn+this.b));t=this.a.Qm(n)+"{"+this.c+",}?"}return t},uZn.b=0,uZn.c=0,zW(Xct,"RegEx/Token/ClosureToken",318),sDn(837,122,aat,eW),uZn.Lm=function(n){return 0==n?this.a:this.b},uZn.Pm=function(){return 2},uZn.Qm=function(n){return 3==this.b.e&&this.b.Lm(0)==this.a?this.a.Qm(n)+"+":9==this.b.e&&this.b.Lm(0)==this.a?this.a.Qm(n)+"+?":this.a.Qm(n)+""+this.b.Qm(n)},zW(Xct,"RegEx/Token/ConcatToken",837),sDn(1945,122,aat,bin),uZn.Lm=function(n){if(0==n)return this.d;if(1==n)return this.b;throw hv(new Ky("Internal Error: "+n))},uZn.Pm=function(){return this.b?2:1},uZn.Qm=function(n){var t;return t=this.c>0?"(?("+this.c+")":8==this.a.e?"(?("+this.a+")":"(?"+this.a,this.b?t+=this.d+"|"+this.b+")":t+=this.d+")",t},uZn.c=0,zW(Xct,"RegEx/Token/ConditionToken",1945),sDn(1946,122,aat,R3),uZn.Lm=function(n){return this.b},uZn.Pm=function(){return 1},uZn.Qm=function(n){return"(?"+(0==this.a?"":XKn(this.a))+(0==this.c?"":XKn(this.c))+":"+this.b.Qm(n)+")"},uZn.a=0,uZn.c=0,zW(Xct,"RegEx/Token/ModifierToken",1946),sDn(838,122,aat,PQ),uZn.Lm=function(n){return this.a},uZn.Pm=function(){return 1},uZn.Qm=function(n){var t;switch(t=null,this.e){case 6:t=0==this.b?"(?:"+this.a.Qm(n)+")":"("+this.a.Qm(n)+")";break;case 20:t="(?="+this.a.Qm(n)+")";break;case 21:t="(?!"+this.a.Qm(n)+")";break;case 22:t="(?<="+this.a.Qm(n)+")";break;case 23:t="(?"+this.a.Qm(n)+")"}return t},uZn.b=0,zW(Xct,"RegEx/Token/ParenToken",838),sDn(530,122,{3:1,122:1,530:1},F1),uZn.Mm=function(){return this.b},uZn.Qm=function(n){return 12==this.e?"\\"+this.a:Nxn(this.b)},uZn.a=0,zW(Xct,"RegEx/Token/StringToken",530),sDn(477,122,aat,QN),uZn.Jm=function(n){kzn(this,n)},uZn.Lm=function(n){return uG(DQ(this.a,n),122)},uZn.Pm=function(){return this.a?this.a.a.c.length:0},uZn.Qm=function(n){var t,e,i,r,c;if(1==this.e){if(2==this.a.a.c.length)t=uG(DQ(this.a,0),122),r=3==(e=uG(DQ(this.a,1),122)).e&&e.Lm(0)==t?t.Qm(n)+"+":9==e.e&&e.Lm(0)==t?t.Qm(n)+"+?":t.Qm(n)+""+e.Qm(n);else{for(c=new zM,i=0;i=this.c.b:this.a<=this.c.b},uZn.Sb=function(){return this.b>0},uZn.Tb=function(){return this.b},uZn.Vb=function(){return this.b-1},uZn.Qb=function(){throw hv(new TM(lat))},uZn.a=0,uZn.b=0,zW(sat,"ExclusiveRange/RangeIterator",258);var JHt=hJ(brt,"C"),YHt=hJ(grt,"I"),ZHt=hJ(dZn,"Z"),nUt=hJ(prt,"J"),tUt=hJ(lrt,"B"),eUt=hJ(wrt,"D"),iUt=hJ(drt,"F"),rUt=hJ(mrt,"S"),cUt=Iq("org.eclipse.elk.core.labels","ILabelManager"),aUt=Iq(Pet,"DiagnosticChain"),oUt=Iq(Jrt,"ResourceSet"),uUt=zW(Pet,"InvocationTargetException",null),sUt=(XM(),m9),hUt=hUt=zSn;Nan(bv),van("permProps",[[["locale","default"],[bat,"gecko1_8"]],[["locale","default"],[bat,"safari"]]]),hUt(null,"elk",null)}).call(this)}).call(this,void 0!==e.g?e.g:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(n,t,e){"use strict";function i(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}function r(n,t){if(!n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?n:t}function c(n,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);n.prototype=Object.create(t&&t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(n,t):n.__proto__=t)}var a=function(t){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,e);var c=Object.assign({},t),a=!1;try{n.resolve("web-worker"),a=!0}catch(s){}if(t.workerUrl)if(a){var o=n("web-worker");c.workerFactory=function(n){return new o(n)}}else console.warn("Web worker requested but 'web-worker' package not installed. \nConsider installing the package or pass your own 'workerFactory' to ELK's constructor.\n... Falling back to non-web worker version.");if(!c.workerFactory){var u=n("./elk-worker.min.js").Worker;c.workerFactory=function(n){return new u(n)}}return r(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,c))}return c(e,t),e}(n("./elk-api.js").default);Object.defineProperty(t.exports,"__esModule",{value:!0}),t.exports=a,a.default=a},{"./elk-api.js":1,"./elk-worker.min.js":2,"web-worker":4}],4:[function(n,t,e){t.exports=Worker},{}]},{},[3])(3)},22235:(n,t,e)=>{"use strict";e.d(t,{diagram:()=>y});var i=e(66216),r=e(26312),c=e(28747),a=e(76257),o=e(62954);e(74353),e(16750),e(42838);const u=new o;let s={};const h={};let f={};const l=(n,t,e)=>{const i={TB:{in:{north:"north"},out:{south:"west",west:"east",east:"south"}},LR:{in:{west:"west"},out:{east:"south",south:"north",north:"east"}},RL:{in:{east:"east"},out:{west:"north",north:"south",south:"west"}},BT:{in:{south:"south"},out:{north:"east",east:"west",west:"north"}}};return i.TD=i.TB,i[e][t][n]},b=(n,t,e)=>{if(a.l.info("getNextPort",{node:n,edgeDirection:t,graphDirection:e}),!s[n])switch(e){case"TB":case"TD":s[n]={inPosition:"north",outPosition:"south"};break;case"BT":s[n]={inPosition:"south",outPosition:"north"};break;case"RL":s[n]={inPosition:"east",outPosition:"west"};break;case"LR":s[n]={inPosition:"west",outPosition:"east"}}const i="in"===t?s[n].inPosition:s[n].outPosition;return"in"===t?s[n].inPosition=l(s[n].inPosition,t,e):s[n].outPosition=l(s[n].outPosition,t,e),i},w=function(n,t,e,i){a.l.info("abc78 edges = ",n);const o=i.insert("g").attr("class","edgeLabels");let u,s,l={},w=t.db.getDirection();if(void 0!==n.defaultStyle){const t=(0,a.k)(n.defaultStyle);u=t.style,s=t.labelStyle}return n.forEach((function(t){const i="L-"+t.start+"-"+t.end;void 0===l[i]?(l[i]=0,a.l.info("abc78 new entry",i,l[i])):(l[i]++,a.l.info("abc78 new entry",i,l[i]));let d=i+"-"+l[i];a.l.info("abc78 new link id to be used is",i,d,l[i]);const g="LS-"+t.start,p="LE-"+t.end,m={style:"",labelStyle:""};switch(m.minlen=t.length||1,"arrow_open"===t.type?m.arrowhead="none":m.arrowhead="normal",m.arrowTypeStart="arrow_open",m.arrowTypeEnd="arrow_open",t.type){case"double_arrow_cross":m.arrowTypeStart="arrow_cross";case"arrow_cross":m.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":m.arrowTypeStart="arrow_point";case"arrow_point":m.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":m.arrowTypeStart="arrow_circle";case"arrow_circle":m.arrowTypeEnd="arrow_circle"}let v="",k="";switch(t.stroke){case"normal":v="fill:none;",void 0!==u&&(v=u),void 0!==s&&(k=s),m.thickness="normal",m.pattern="solid";break;case"dotted":m.thickness="normal",m.pattern="dotted",m.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":m.thickness="thick",m.pattern="solid",m.style="stroke-width: 3.5px;fill:none;"}if(void 0!==t.style){const n=(0,a.k)(t.style);v=n.style,k=n.labelStyle}m.style=m.style+=v,m.labelStyle=m.labelStyle+=k,void 0!==t.interpolate?m.curve=(0,a.n)(t.interpolate,r.lUB):void 0!==n.defaultInterpolate?m.curve=(0,a.n)(n.defaultInterpolate,r.lUB):m.curve=(0,a.n)(h.curve,r.lUB),void 0===t.text?void 0!==t.style&&(m.arrowheadStyle="fill: #333"):(m.arrowheadStyle="fill: #333",m.labelpos="c"),m.labelType=t.labelType,m.label=t.text.replace(a.e.lineBreakRegex,"\n"),void 0===t.style&&(m.style=m.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),m.labelStyle=m.labelStyle.replace("color:","fill:"),m.id=d,m.classes="flowchart-link "+g+" "+p;const y=(0,c.f)(o,m),{source:M,target:T,sourceId:j,targetId:E}=((n,t)=>{let e=n.start,i=n.end;const r=e,c=i,a=f[e],o=f[i];return a&&o?("diamond"===a.type&&(e=`${e}-${b(e,"out",t)}`),"diamond"===o.type&&(i=`${i}-${b(i,"in",t)}`),{source:e,target:i,sourceId:r,targetId:c}):{source:e,target:i}})(t,w);a.l.debug("abc78 source and target",M,T),e.edges.push({id:"e"+t.start+t.end,sources:[M],targets:[T],sourceId:j,targetId:E,labelEl:y,labels:[{width:m.width,height:m.height,orgWidth:m.width,orgHeight:m.height,text:m.label,layoutOptions:{"edgeLabels.inline":"true","edgeLabels.placement":"CENTER"}}],edgeData:m})})),e},d=function(n,t,e){const i=((n,t,e)=>{const{parentById:i}=e,r=new Set;let c=n;for(;c;){if(r.add(c),c===t)return c;c=i[c]}for(c=t;c;){if(r.has(c))return c;c=i[c]}return"root"})(n,t,e);if(void 0===i||"root"===i)return{x:0,y:0};const r=f[i].offset;return{x:r.posX,y:r.posY}},g=function(n,t,e,i,a,o){const u=d(t.sourceId,t.targetId,a),s=t.sections[0].startPoint,h=t.sections[0].endPoint,f=(t.sections[0].bendPoints?t.sections[0].bendPoints:[]).map((n=>[n.x+u.x,n.y+u.y])),l=[[s.x+u.x,s.y+u.y],...f,[h.x+u.x,h.y+u.y]],{x:b,y:w}=(0,c.k)(t.edgeData),g=(0,r.n8j)().x(b).y(w).curve(r.lUB),p=n.insert("path").attr("d",g(l)).attr("class","path "+e.classes).attr("fill","none"),m=n.insert("g").attr("class","edgeLabel"),v=(0,r.Ltv)(m.node().appendChild(t.labelEl)),k=v.node().firstChild.getBoundingClientRect();v.attr("width",k.width),v.attr("height",k.height),m.attr("transform",`translate(${t.labels[0].x+u.x}, ${t.labels[0].y+u.y})`),function(n,t,e,i,r){let a="";i&&(a=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,a=a.replace(/\(/g,"\\("),a=a.replace(/\)/g,"\\)")),(0,c.m)(n,t,a,r,e)}(p,e,i.type,i.arrowMarkerAbsolute,o)},p=(n,t)=>{n.forEach((n=>{n.children||(n.children=[]);const e=t.childrenById[n.id];e&&e.forEach((t=>{n.children.push(f[t])})),p(n.children,t)}))},m=(n,t,e,i,r,c,o)=>{e.forEach((function(e){if(e)if(f[e.id].offset={posX:e.x+n,posY:e.y+t,x:n,y:t,depth:o,width:e.width,height:e.height},"group"===e.type){const i=r.insert("g").attr("class","subgraph");i.insert("rect").attr("class","subgraph subgraph-lvl-"+o%5+" node").attr("x",e.x+n).attr("y",e.y+t).attr("width",e.width).attr("height",e.height);const c=i.insert("g").attr("class","label"),u=(0,a.F)().flowchart.htmlLabels?e.labelData.width/2:0;c.attr("transform",`translate(${e.labels[0].x+n+e.x+u}, ${e.labels[0].y+t+e.y+3})`),c.node().appendChild(e.labelData.labelNode),a.l.info("Id (UGH)= ",e.type,e.labels)}else a.l.info("Id (UGH)= ",e.id),e.el.attr("transform",`translate(${e.x+n+e.width/2}, ${e.y+t+e.height/2})`)})),e.forEach((function(e){e&&"group"===e.type&&m(n+e.x,t+e.y,e.children,i,r,c,o+1)}))},v={getClasses:function(n,t){return a.l.info("Extracting classes"),t.db.getClasses()},draw:async function(n,t,e,i){var o;i.db.clear(),f={},s={},i.db.setGen("gen-2"),i.parser.parse(n);const h=(0,r.Ltv)("body").append("div").attr("style","height:400px").attr("id","cy");let l={id:"root",layoutOptions:{"elk.hierarchyHandling":"INCLUDE_CHILDREN","org.eclipse.elk.padding":"[top=100, left=100, bottom=110, right=110]","elk.layered.spacing.edgeNodeBetweenLayers":"30","elk.direction":"DOWN"},children:[],edges:[]};switch(a.l.info("Drawing flowchart using v3 renderer",u),i.db.getDirection()){case"BT":l.layoutOptions["elk.direction"]="UP";break;case"TB":l.layoutOptions["elk.direction"]="DOWN";break;case"LR":l.layoutOptions["elk.direction"]="RIGHT";break;case"RL":l.layoutOptions["elk.direction"]="LEFT"}const{securityLevel:b,flowchart:d}=(0,a.F)();let v;"sandbox"===b&&(v=(0,r.Ltv)("#i"+t));const k="sandbox"===b?(0,r.Ltv)(v.nodes()[0].contentDocument.body):(0,r.Ltv)("body"),y="sandbox"===b?v.nodes()[0].contentDocument:document,M=k.select(`[id="${t}"]`);(0,c.a)(M,["point","circle","cross"],i.type,t);const T=i.db.getVertices();let j;const E=i.db.getSubGraphs();a.l.info("Subgraphs - ",E);for(let r=E.length-1;r>=0;r--)j=E[r],i.db.addVertex(j.id,{text:j.title,type:j.labelType},"group",void 0,j.classes,j.dir);const S=M.insert("g").attr("class","subgraphs"),P=function(n){const t={parentById:{},childrenById:{}},e=n.getSubGraphs();return a.l.info("Subgraphs - ",e),e.forEach((function(n){n.nodes.forEach((function(e){t.parentById[e]=n.id,void 0===t.childrenById[n.id]&&(t.childrenById[n.id]=[]),t.childrenById[n.id].push(e)}))})),e.forEach((function(n){n.id,void 0!==t.parentById[n.id]&&t.parentById[n.id]})),t}(i.db);l=await async function(n,t,e,i,r,o,u){const s=e.select(`[id="${t}"]`).insert("g").attr("class","nodes"),h=Object.keys(n);return await Promise.all(h.map((async function(t){const e=n[t];let u="default";e.classes.length>0&&(u=e.classes.join(" ")),u+=" flowchart-label";const h=(0,a.k)(e.styles);let l=void 0!==e.text?e.text:e.id;const b={width:0,height:0},w=[{id:e.id+"-west",layoutOptions:{"port.side":"WEST"}},{id:e.id+"-east",layoutOptions:{"port.side":"EAST"}},{id:e.id+"-south",layoutOptions:{"port.side":"SOUTH"}},{id:e.id+"-north",layoutOptions:{"port.side":"NORTH"}}];let d=0,g="",p={};switch(e.type){case"round":d=5,g="rect";break;case"square":case"group":default:g="rect";break;case"diamond":g="question",p={portConstraints:"FIXED_SIDE"};break;case"hexagon":g="hexagon";break;case"odd":case"odd_right":g="rect_left_inv_arrow";break;case"lean_right":g="lean_right";break;case"lean_left":g="lean_left";break;case"trapezoid":g="trapezoid";break;case"inv_trapezoid":g="inv_trapezoid";break;case"circle":g="circle";break;case"ellipse":g="ellipse";break;case"stadium":g="stadium";break;case"subroutine":g="subroutine";break;case"cylinder":g="cylinder";break;case"doublecircle":g="doublecircle"}const m={labelStyle:h.labelStyle,shape:g,labelText:l,labelType:e.labelType,rx:d,ry:d,class:u,style:h.style,id:e.id,link:e.link,linkTarget:e.linkTarget,tooltip:r.db.getTooltip(e.id)||"",domId:r.db.lookUpDomId(e.id),haveCallback:e.haveCallback,width:"group"===e.type?500:void 0,dir:e.dir,type:e.type,props:e.props,padding:(0,a.F)().flowchart.padding};let v,k;if("group"!==m.type)k=await(0,c.e)(s,m,e.dir),v=k.node().getBBox();else{i.createElementNS("http://www.w3.org/2000/svg","text");const{shapeSvg:n,bbox:t}=await(0,c.l)(s,m,void 0,!0);b.width=t.width,b.wrappingWidth=(0,a.F)().flowchart.wrappingWidth,b.height=t.height,b.labelNode=n.node(),m.labelData=b}const y={id:e.id,ports:"diamond"===e.type?w:[],layoutOptions:p,labelText:l,labelData:b,domId:r.db.lookUpDomId(e.id),width:null==v?void 0:v.width,height:null==v?void 0:v.height,type:e.type,el:k,parent:o.parentById[e.id]};f[m.id]=y}))),u}(T,t,k,y,i,P,l);const C=M.insert("g").attr("class","edges edgePath"),I=i.db.getEdges();l=w(I,i,l,M);Object.keys(f).forEach((n=>{const t=f[n];t.parent||l.children.push(t),void 0!==P.childrenById[n]&&(t.labels=[{text:t.labelText,layoutOptions:{"nodeLabels.placement":"[H_CENTER, V_TOP, INSIDE]"},width:t.labelData.width,height:t.labelData.height}],delete t.x,delete t.y,delete t.width,delete t.height)})),p(l.children,P),a.l.info("after layout",JSON.stringify(l,null,2));const O=await u.layout(l);m(0,0,O.children,M,S,i,0),a.l.info("after layout",O),null==(o=O.edges)||o.map((n=>{g(C,n,n.edgeData,i,P,t)})),(0,a.o)({},M,d.diagramPadding,d.useMaxWidth),h.remove()}},k=n=>`.label {\n font-family: ${n.fontFamily};\n color: ${n.nodeTextColor||n.textColor};\n }\n .cluster-label text {\n fill: ${n.titleColor};\n }\n .cluster-label span {\n color: ${n.titleColor};\n }\n\n .label text,span {\n fill: ${n.nodeTextColor||n.textColor};\n color: ${n.nodeTextColor||n.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${n.mainBkg};\n stroke: ${n.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${n.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${n.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${n.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${n.edgeLabelBackground};\n rect {\n opacity: 0.85;\n background-color: ${n.edgeLabelBackground};\n fill: ${n.edgeLabelBackground};\n }\n text-align: center;\n }\n\n .cluster rect {\n fill: ${n.clusterBkg};\n stroke: ${n.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${n.titleColor};\n }\n\n .cluster span {\n color: ${n.titleColor};\n }\n /* .cluster div {\n color: ${n.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${n.fontFamily};\n font-size: 12px;\n background: ${n.tertiaryColor};\n border: 1px solid ${n.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${n.textColor};\n }\n .subgraph {\n stroke-width:2;\n rx:3;\n }\n // .subgraph-lvl-1 {\n // fill:#ccc;\n // // stroke:black;\n // }\n\n .flowchart-label text {\n text-anchor: middle;\n }\n\n ${(n=>{let t="";for(let e=0;e<5;e++)t+=`\n .subgraph-lvl-${e} {\n fill: ${n[`surface${e}`]};\n stroke: ${n[`surfacePeer${e}`]};\n }\n `;return t})(n)}\n`,y={db:i.d,renderer:v,parser:i.p,styles:k}}}]); \ No newline at end of file diff --git a/assets/js/2237.ac9ee37e.js b/assets/js/2237.ac9ee37e.js new file mode 100644 index 0000000000..d011d23c1f --- /dev/null +++ b/assets/js/2237.ac9ee37e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2237],{23363:(e,t,n)=>{n.d(t,{A:()=>a});n(96540);var i=n(18215),o=n(21312),s=n(51107),r=n(74848);function a(e){let{className:t}=e;return(0,r.jsx)("main",{className:(0,i.A)("container margin-vert--xl",t),children:(0,r.jsx)("div",{className:"row",children:(0,r.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,r.jsx)(s.A,{as:"h1",className:"hero__title",children:(0,r.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,r.jsx)("p",{children:(0,r.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,r.jsx)("p",{children:(0,r.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}},82237:(e,t,n)=>{n.r(t),n.d(t,{default:()=>d});n(96540);var i=n(21312),o=n(61213),s=n(72415),r=n(23363),a=n(74848);function d(){const e=(0,i.T)({id:"theme.NotFound.title",message:"Page Not Found"});return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(o.be,{title:e}),(0,a.jsx)(s.A,{children:(0,a.jsx)(r.A,{})})]})}}}]); \ No newline at end of file diff --git a/assets/js/22aa5ce0.7a834602.js b/assets/js/22aa5ce0.7a834602.js new file mode 100644 index 0000000000..f1edf0d76d --- /dev/null +++ b/assets/js/22aa5ce0.7a834602.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6910],{34707:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>h,frontMatter:()=>n,metadata:()=>a,toc:()=>d});var r=s(74848),c=s(28453);const n={},i="scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer",a={id:"ops/scs-0403",title:"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/ops/scs-0403.md",sourceDirName:"ops",slug:"/ops/scs-0403",permalink:"/standards/ops/scs-0403",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Status page OpenAPI decision",permalink:"/standards/scs-0402-v1-status-page-openapi-spec-decision"},next:{title:"Architecture for the Cloud Service provider Observability System for the KaaS Layer",permalink:"/standards/scs-0403-v1-csp-kaas-observability-stack"}},o={},d=[];function l(e){const t={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"scs-0403-architecture-for-the-cloud-service-provider-observability-system-for-the-kaas-layer",children:"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0403-v1-csp-kaas-observability-stack",children:"scs-0403-v1"})}),(0,r.jsx)(t.td,{children:"Decision Record"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>a});var r=s(96540);const c={},n=r.createContext(c);function i(e){const t=r.useContext(n);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),r.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2317.dcc57e24.js b/assets/js/2317.dcc57e24.js new file mode 100644 index 0000000000..2e12a11dc9 --- /dev/null +++ b/assets/js/2317.dcc57e24.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2317],{10646:(e,t,n)=>{n.d(t,{H:()=>l});var r=n(82933);function l(e,t){var n=e.append("foreignObject").attr("width","100000"),l=n.append("xhtml:div");l.attr("xmlns","http://www.w3.org/1999/xhtml");var o=t.label;switch(typeof o){case"function":l.insert(o);break;case"object":l.insert((function(){return o}));break;default:l.html(o)}r.AV(l,t.labelStyle),l.style("display","inline-block"),l.style("white-space","nowrap");var a=l.node().getBoundingClientRect();return n.attr("width",a.width).attr("height",a.height),n}},82933:(e,t,n)=>{n.d(t,{AV:()=>c,De:()=>o,c$:()=>p,gh:()=>a,nh:()=>d});var r=n(34963),l=n(89610);function o(e,t){return!!e.children(t).length}function a(e){return i(e.v)+":"+i(e.w)+":"+i(e.name)}var s=/:/g;function i(e){return e?String(e).replace(s,"\\:"):""}function c(e,t){t&&e.attr("style",t)}function d(e,t,n){t&&e.attr("class",t).attr("class",n+" "+e.attr("class"))}function p(e,t){var n=t.graph();if(r.A(n)){var o=n.transition;if(l.A(o))return o(e)}return e}},75937:(e,t,n)=>{n.d(t,{A:()=>o});var r=n(72453),l=n(74886);const o=(e,t)=>r.A.lang.round(l.A.parse(e)[t])},62317:(e,t,n)=>{n.d(t,{diagram:()=>a});var r=n(66216),l=n(98696),o=n(76257);n(26312),n(697),n(21176),n(14075),n(74353),n(16750),n(42838);const a={parser:r.p,db:r.f,renderer:l.f,styles:l.a,init:e=>{e.flowchart||(e.flowchart={}),e.flowchart.arrowMarkerAbsolute=e.arrowMarkerAbsolute,(0,o.p)({flowchart:{arrowMarkerAbsolute:e.arrowMarkerAbsolute}}),l.f.setConf(e.flowchart),r.f.clear(),r.f.setGen("gen-2")}}},98696:(e,t,n)=>{n.d(t,{a:()=>f,f:()=>w});var r=n(697),l=n(26312),o=n(76257),a=n(92746),s=n(10646),i=n(75937),c=n(25582);const d={},p=async function(e,t,n,r,l,a){const i=r.select(`[id="${n}"]`),c=Object.keys(e);for(const d of c){const n=e[d];let r="default";n.classes.length>0&&(r=n.classes.join(" ")),r+=" flowchart-label";const c=(0,o.k)(n.styles);let p,b=void 0!==n.text?n.text:n.id;if(o.l.info("vertex",n,n.labelType),"markdown"===n.labelType)o.l.info("vertex",n,n.labelType);else if((0,o.m)((0,o.c)().flowchart.htmlLabels)){const e={label:b};p=(0,s.H)(i,e).node(),p.parentNode.removeChild(p)}else{const e=l.createElementNS("http://www.w3.org/2000/svg","text");e.setAttribute("style",c.labelStyle.replace("color:","fill:"));const t=b.split(o.e.lineBreakRegex);for(const n of t){const t=l.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","1"),t.textContent=n,e.appendChild(t)}p=e}let w=0,f="";switch(n.type){case"round":w=5,f="rect";break;case"square":case"group":default:f="rect";break;case"diamond":f="question";break;case"hexagon":f="hexagon";break;case"odd":case"odd_right":f="rect_left_inv_arrow";break;case"lean_right":f="lean_right";break;case"lean_left":f="lean_left";break;case"trapezoid":f="trapezoid";break;case"inv_trapezoid":f="inv_trapezoid";break;case"circle":f="circle";break;case"ellipse":f="ellipse";break;case"stadium":f="stadium";break;case"subroutine":f="subroutine";break;case"cylinder":f="cylinder";break;case"doublecircle":f="doublecircle"}const h=await(0,o.r)(b,(0,o.c)());t.setNode(n.id,{labelStyle:c.labelStyle,shape:f,labelText:h,labelType:n.labelType,rx:w,ry:w,class:r,style:c.style,id:n.id,link:n.link,linkTarget:n.linkTarget,tooltip:a.db.getTooltip(n.id)||"",domId:a.db.lookUpDomId(n.id),haveCallback:n.haveCallback,width:"group"===n.type?500:void 0,dir:n.dir,type:n.type,props:n.props,padding:(0,o.c)().flowchart.padding}),o.l.info("setNode",{labelStyle:c.labelStyle,labelType:n.labelType,shape:f,labelText:h,rx:w,ry:w,class:r,style:c.style,id:n.id,domId:a.db.lookUpDomId(n.id),width:"group"===n.type?500:void 0,type:n.type,dir:n.dir,props:n.props,padding:(0,o.c)().flowchart.padding})}},b=async function(e,t,n){o.l.info("abc78 edges = ",e);let r,a,s=0,i={};if(void 0!==e.defaultStyle){const t=(0,o.k)(e.defaultStyle);r=t.style,a=t.labelStyle}for(const c of e){s++;const n="L-"+c.start+"-"+c.end;void 0===i[n]?(i[n]=0,o.l.info("abc78 new entry",n,i[n])):(i[n]++,o.l.info("abc78 new entry",n,i[n]));let p=n+"-"+i[n];o.l.info("abc78 new link id to be used is",n,p,i[n]);const b="LS-"+c.start,w="LE-"+c.end,f={style:"",labelStyle:""};switch(f.minlen=c.length||1,"arrow_open"===c.type?f.arrowhead="none":f.arrowhead="normal",f.arrowTypeStart="arrow_open",f.arrowTypeEnd="arrow_open",c.type){case"double_arrow_cross":f.arrowTypeStart="arrow_cross";case"arrow_cross":f.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":f.arrowTypeStart="arrow_point";case"arrow_point":f.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":f.arrowTypeStart="arrow_circle";case"arrow_circle":f.arrowTypeEnd="arrow_circle"}let h="",u="";switch(c.stroke){case"normal":h="fill:none;",void 0!==r&&(h=r),void 0!==a&&(u=a),f.thickness="normal",f.pattern="solid";break;case"dotted":f.thickness="normal",f.pattern="dotted",f.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":f.thickness="thick",f.pattern="solid",f.style="stroke-width: 3.5px;fill:none;";break;case"invisible":f.thickness="invisible",f.pattern="solid",f.style="stroke-width: 0;fill:none;"}if(void 0!==c.style){const e=(0,o.k)(c.style);h=e.style,u=e.labelStyle}f.style=f.style+=h,f.labelStyle=f.labelStyle+=u,void 0!==c.interpolate?f.curve=(0,o.n)(c.interpolate,l.lUB):void 0!==e.defaultInterpolate?f.curve=(0,o.n)(e.defaultInterpolate,l.lUB):f.curve=(0,o.n)(d.curve,l.lUB),void 0===c.text?void 0!==c.style&&(f.arrowheadStyle="fill: #333"):(f.arrowheadStyle="fill: #333",f.labelpos="c"),f.labelType=c.labelType,f.label=await(0,o.r)(c.text.replace(o.e.lineBreakRegex,"\n"),(0,o.c)()),void 0===c.style&&(f.style=f.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),f.labelStyle=f.labelStyle.replace("color:","fill:"),f.id=p,f.classes="flowchart-link "+b+" "+w,t.setEdge(c.start,c.end,f,s)}},w={setConf:function(e){const t=Object.keys(e);for(const n of t)d[n]=e[n]},addVertices:p,addEdges:b,getClasses:function(e,t){return t.db.getClasses()},draw:async function(e,t,n,s){o.l.info("Drawing flowchart");let i=s.db.getDirection();void 0===i&&(i="TD");const{securityLevel:c,flowchart:d}=(0,o.c)(),w=d.nodeSpacing||50,f=d.rankSpacing||50;let h;"sandbox"===c&&(h=(0,l.Ltv)("#i"+t));const u="sandbox"===c?(0,l.Ltv)(h.nodes()[0].contentDocument.body):(0,l.Ltv)("body"),g="sandbox"===c?h.nodes()[0].contentDocument:document,y=new r.T({multigraph:!0,compound:!0}).setGraph({rankdir:i,nodesep:w,ranksep:f,marginx:0,marginy:0}).setDefaultEdgeLabel((function(){return{}}));let k;const x=s.db.getSubGraphs();o.l.info("Subgraphs - ",x);for(let r=x.length-1;r>=0;r--)k=x[r],o.l.info("Subgraph - ",k),s.db.addVertex(k.id,{text:k.title,type:k.labelType},"group",void 0,k.classes,k.dir);const v=s.db.getVertices(),m=s.db.getEdges();o.l.info("Edges",m);let S=0;for(S=x.length-1;S>=0;S--){k=x[S],(0,l.Ubm)("cluster").append("text");for(let e=0;e`.label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .cluster-label text {\n fill: ${e.titleColor};\n }\n .cluster-label span,p {\n color: ${e.titleColor};\n }\n\n .label text,span,p {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .katex path {\n fill: #000;\n stroke: #000;\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${e.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${e.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${e.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${e.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${e.edgeLabelBackground};\n fill: ${e.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${((e,t)=>{const n=i.A,r=n(e,"r"),l=n(e,"g"),o=n(e,"b");return c.A(r,l,o,t)})(e.edgeLabelBackground,.5)};\n // background-color: \n }\n\n .cluster rect {\n fill: ${e.clusterBkg};\n stroke: ${e.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${e.titleColor};\n }\n\n .cluster span,p {\n color: ${e.titleColor};\n }\n /* .cluster div {\n color: ${e.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${e.fontFamily};\n font-size: 12px;\n background: ${e.tertiaryColor};\n border: 1px solid ${e.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n }\n`}}]); \ No newline at end of file diff --git a/assets/js/235.d6ffdd87.js b/assets/js/235.d6ffdd87.js new file mode 100644 index 0000000000..8bfc6b29b9 --- /dev/null +++ b/assets/js/235.d6ffdd87.js @@ -0,0 +1,23923 @@ +exports.id = 235; +exports.ids = [235]; +exports.modules = { + +/***/ 62954: +/***/ ((module) => { + +(function(f){if(true){module.exports=f()}else { var g; }})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=undefined;if(!f&&c)return require(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=undefined,i=0;i 0 && arguments[0] !== undefined ? arguments[0] : {}, + _ref$defaultLayoutOpt = _ref.defaultLayoutOptions, + defaultLayoutOptions = _ref$defaultLayoutOpt === undefined ? {} : _ref$defaultLayoutOpt, + _ref$algorithms = _ref.algorithms, + algorithms = _ref$algorithms === undefined ? ['layered', 'stress', 'mrtree', 'radial', 'force', 'disco', 'sporeOverlap', 'sporeCompaction', 'rectpacking'] : _ref$algorithms, + workerFactory = _ref.workerFactory, + workerUrl = _ref.workerUrl; + + _classCallCheck(this, ELK); + + this.defaultLayoutOptions = defaultLayoutOptions; + this.initialized = false; + + // check valid worker construction possible + if (typeof workerUrl === 'undefined' && typeof workerFactory === 'undefined') { + throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'."); + } + var factory = workerFactory; + if (typeof workerUrl !== 'undefined' && typeof workerFactory === 'undefined') { + // use default Web Worker + factory = function factory(url) { + return new Worker(url); + }; + } + + // create the worker + var worker = factory(workerUrl); + if (typeof worker.postMessage !== 'function') { + throw new TypeError("Created worker does not provide" + " the required 'postMessage' function."); + } + + // wrap the worker to return promises + this.worker = new PromisedWorker(worker); + + // initially register algorithms + this.worker.postMessage({ + cmd: 'register', + algorithms: algorithms + }).then(function (r) { + return _this.initialized = true; + }).catch(console.err); + } + + _createClass(ELK, [{ + key: 'layout', + value: function layout(graph) { + var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref2$layoutOptions = _ref2.layoutOptions, + layoutOptions = _ref2$layoutOptions === undefined ? this.defaultLayoutOptions : _ref2$layoutOptions, + _ref2$logging = _ref2.logging, + logging = _ref2$logging === undefined ? false : _ref2$logging, + _ref2$measureExecutio = _ref2.measureExecutionTime, + measureExecutionTime = _ref2$measureExecutio === undefined ? false : _ref2$measureExecutio; + + if (!graph) { + return Promise.reject(new Error("Missing mandatory parameter 'graph'.")); + } + return this.worker.postMessage({ + cmd: 'layout', + graph: graph, + layoutOptions: layoutOptions, + options: { + logging: logging, + measureExecutionTime: measureExecutionTime + } + }); + } + }, { + key: 'knownLayoutAlgorithms', + value: function knownLayoutAlgorithms() { + return this.worker.postMessage({ cmd: 'algorithms' }); + } + }, { + key: 'knownLayoutOptions', + value: function knownLayoutOptions() { + return this.worker.postMessage({ cmd: 'options' }); + } + }, { + key: 'knownLayoutCategories', + value: function knownLayoutCategories() { + return this.worker.postMessage({ cmd: 'categories' }); + } + }, { + key: 'terminateWorker', + value: function terminateWorker() { + this.worker.terminate(); + } + }]); + + return ELK; +}(); + +exports.default = ELK; + +var PromisedWorker = function () { + function PromisedWorker(worker) { + var _this2 = this; + + _classCallCheck(this, PromisedWorker); + + if (worker === undefined) { + throw new Error("Missing mandatory parameter 'worker'."); + } + this.resolvers = {}; + this.worker = worker; + this.worker.onmessage = function (answer) { + // why is this necessary? + setTimeout(function () { + _this2.receive(_this2, answer); + }, 0); + }; + } + + _createClass(PromisedWorker, [{ + key: 'postMessage', + value: function postMessage(msg) { + var id = this.id || 0; + this.id = id + 1; + msg.id = id; + var self = this; + return new Promise(function (resolve, reject) { + // prepare the resolver + self.resolvers[id] = function (err, res) { + if (err) { + self.convertGwtStyleError(err); + reject(err); + } else { + resolve(res); + } + }; + // post the message + self.worker.postMessage(msg); + }); + } + }, { + key: 'receive', + value: function receive(self, answer) { + var json = answer.data; + var resolver = self.resolvers[json.id]; + if (resolver) { + delete self.resolvers[json.id]; + if (json.error) { + resolver(json.error); + } else { + resolver(null, json.data); + } + } + } + }, { + key: 'terminate', + value: function terminate() { + if (this.worker.terminate) { + this.worker.terminate(); + } + } + }, { + key: 'convertGwtStyleError', + value: function convertGwtStyleError(err) { + if (!err) { + return; + } + // Somewhat flatten the way GWT stores nested exception(s) + var javaException = err['__java$exception']; + if (javaException) { + // Note that the property name of the nested exception is different + // in the non-minified ('cause') and the minified (not deterministic) version. + // Hence, the version below only works for the non-minified version. + // However, as the minified stack trace is not of much use anyway, one + // should switch the used version for debugging in such a case. + if (javaException.cause && javaException.cause.backingJsObject) { + err.cause = javaException.cause.backingJsObject; + this.convertGwtStyleError(err.cause); + } + delete err['__java$exception']; + } + } + }]); + + return PromisedWorker; +}(); +},{}],2:[function(require,module,exports){ +(function (global){(function (){ +'use strict'; + +// -------------- FAKE ELEMENTS GWT ASSUMES EXIST -------------- +var $wnd; +if (typeof window !== 'undefined') + $wnd = window +else if (typeof global !== 'undefined') + $wnd = global // nodejs +else if (typeof self !== 'undefined') + $wnd = self // web worker + +var $moduleName, + $moduleBase; + +// -------------- WORKAROUND STRICT MODE, SEE #127 -------------- +var g, i, o; + +// -------------- GENERATED CODE -------------- +function nb(){} +function xb(){} +function Fd(){} +function hh(){} +function lq(){} +function Nq(){} +function ir(){} +function Ws(){} +function Zw(){} +function jx(){} +function rx(){} +function sx(){} +function My(){} +function bA(){} +function mA(){} +function tA(){} +function aB(){} +function dB(){} +function jB(){} +function dC(){} +function keb(){} +function geb(){} +function oeb(){} +function iob(){} +function Job(){} +function Rob(){} +function apb(){} +function ipb(){} +function nrb(){} +function wrb(){} +function Brb(){} +function Prb(){} +function ltb(){} +function svb(){} +function xvb(){} +function zvb(){} +function $xb(){} +function Gzb(){} +function NAb(){} +function VAb(){} +function rBb(){} +function RBb(){} +function TBb(){} +function XBb(){} +function ZBb(){} +function _Bb(){} +function bCb(){} +function dCb(){} +function fCb(){} +function jCb(){} +function rCb(){} +function uCb(){} +function wCb(){} +function yCb(){} +function ACb(){} +function ECb(){} +function FEb(){} +function IEb(){} +function KEb(){} +function MEb(){} +function gFb(){} +function FFb(){} +function JFb(){} +function xGb(){} +function AGb(){} +function YGb(){} +function oHb(){} +function tHb(){} +function xHb(){} +function pIb(){} +function BJb(){} +function kLb(){} +function mLb(){} +function oLb(){} +function qLb(){} +function FLb(){} +function JLb(){} +function KMb(){} +function MMb(){} +function OMb(){} +function YMb(){} +function MNb(){} +function ONb(){} +function aOb(){} +function eOb(){} +function xOb(){} +function BOb(){} +function DOb(){} +function FOb(){} +function IOb(){} +function MOb(){} +function POb(){} +function UOb(){} +function ZOb(){} +function cPb(){} +function gPb(){} +function nPb(){} +function qPb(){} +function tPb(){} +function wPb(){} +function CPb(){} +function qQb(){} +function GQb(){} +function bRb(){} +function gRb(){} +function kRb(){} +function pRb(){} +function wRb(){} +function xSb(){} +function TSb(){} +function VSb(){} +function XSb(){} +function ZSb(){} +function _Sb(){} +function tTb(){} +function DTb(){} +function FTb(){} +function FXb(){} +function hXb(){} +function hWb(){} +function mWb(){} +function CVb(){} +function XXb(){} +function $Xb(){} +function bYb(){} +function lYb(){} +function FYb(){} +function XYb(){} +function aZb(){} +function SZb(){} +function ZZb(){} +function Z_b(){} +function j_b(){} +function j$b(){} +function b$b(){} +function f$b(){} +function n$b(){} +function K_b(){} +function V_b(){} +function b0b(){} +function l0b(){} +function X1b(){} +function _1b(){} +function x3b(){} +function r4b(){} +function w4b(){} +function A4b(){} +function E4b(){} +function I4b(){} +function M4b(){} +function o5b(){} +function q5b(){} +function w5b(){} +function A5b(){} +function E5b(){} +function h6b(){} +function j6b(){} +function l6b(){} +function q6b(){} +function v6b(){} +function y6b(){} +function G6b(){} +function K6b(){} +function N6b(){} +function P6b(){} +function R6b(){} +function b7b(){} +function f7b(){} +function j7b(){} +function n7b(){} +function C7b(){} +function H7b(){} +function J7b(){} +function L7b(){} +function N7b(){} +function P7b(){} +function a8b(){} +function c8b(){} +function e8b(){} +function g8b(){} +function i8b(){} +function m8b(){} +function Z8b(){} +function f9b(){} +function i9b(){} +function o9b(){} +function C9b(){} +function F9b(){} +function K9b(){} +function Q9b(){} +function aac(){} +function bac(){} +function eac(){} +function mac(){} +function pac(){} +function rac(){} +function tac(){} +function xac(){} +function Aac(){} +function Dac(){} +function Iac(){} +function Oac(){} +function Uac(){} +function Ucc(){} +function scc(){} +function ycc(){} +function Acc(){} +function Ccc(){} +function Ncc(){} +function Wcc(){} +function ydc(){} +function Adc(){} +function Gdc(){} +function Ldc(){} +function Zdc(){} +function fec(){} +function Dec(){} +function Gec(){} +function Kec(){} +function efc(){} +function jfc(){} +function nfc(){} +function Bfc(){} +function Ifc(){} +function Lfc(){} +function Rfc(){} +function Ufc(){} +function Zfc(){} +function cgc(){} +function egc(){} +function ggc(){} +function igc(){} +function kgc(){} +function Dgc(){} +function Hgc(){} +function Lgc(){} +function Ngc(){} +function Pgc(){} +function Vgc(){} +function Ygc(){} +function chc(){} +function ehc(){} +function ghc(){} +function ihc(){} +function mhc(){} +function rhc(){} +function uhc(){} +function whc(){} +function yhc(){} +function Ahc(){} +function Chc(){} +function Ghc(){} +function Nhc(){} +function Phc(){} +function Rhc(){} +function Thc(){} +function $hc(){} +function aic(){} +function cic(){} +function eic(){} +function jic(){} +function nic(){} +function pic(){} +function ric(){} +function vic(){} +function yic(){} +function Dic(){} +function Ric(){} +function Zic(){} +function bjc(){} +function djc(){} +function jjc(){} +function njc(){} +function rjc(){} +function tjc(){} +function zjc(){} +function Djc(){} +function Fjc(){} +function Ljc(){} +function Pjc(){} +function Rjc(){} +function fkc(){} +function Kkc(){} +function Mkc(){} +function Okc(){} +function Qkc(){} +function Skc(){} +function Ukc(){} +function Wkc(){} +function clc(){} +function elc(){} +function klc(){} +function mlc(){} +function olc(){} +function qlc(){} +function wlc(){} +function ylc(){} +function Alc(){} +function Jlc(){} +function Joc(){} +function poc(){} +function roc(){} +function toc(){} +function voc(){} +function Boc(){} +function Foc(){} +function Hoc(){} +function Loc(){} +function Noc(){} +function Poc(){} +function qnc(){} +function unc(){} +function upc(){} +function kpc(){} +function mpc(){} +function opc(){} +function qpc(){} +function ypc(){} +function Cpc(){} +function Mpc(){} +function Qpc(){} +function dqc(){} +function jqc(){} +function Aqc(){} +function Eqc(){} +function Gqc(){} +function Sqc(){} +function arc(){} +function lrc(){} +function zrc(){} +function Hrc(){} +function bsc(){} +function dsc(){} +function fsc(){} +function ksc(){} +function msc(){} +function Asc(){} +function Csc(){} +function Esc(){} +function Ksc(){} +function Nsc(){} +function Ssc(){} +function CCc(){} +function tGc(){} +function aHc(){} +function gHc(){} +function nIc(){} +function PJc(){} +function XKc(){} +function fLc(){} +function hLc(){} +function lLc(){} +function eNc(){} +function IOc(){} +function MOc(){} +function WOc(){} +function YOc(){} +function $Oc(){} +function cPc(){} +function iPc(){} +function mPc(){} +function oPc(){} +function qPc(){} +function sPc(){} +function wPc(){} +function APc(){} +function FPc(){} +function HPc(){} +function NPc(){} +function PPc(){} +function TPc(){} +function VPc(){} +function ZPc(){} +function _Pc(){} +function bQc(){} +function dQc(){} +function SQc(){} +function hRc(){} +function HRc(){} +function HSc(){} +function pSc(){} +function xSc(){} +function zSc(){} +function BSc(){} +function DSc(){} +function FSc(){} +function CTc(){} +function ITc(){} +function KTc(){} +function MTc(){} +function XTc(){} +function ZTc(){} +function jVc(){} +function lVc(){} +function zVc(){} +function IVc(){} +function KVc(){} +function KWc(){} +function uWc(){} +function xWc(){} +function AWc(){} +function QWc(){} +function UWc(){} +function qXc(){} +function KXc(){} +function OXc(){} +function SXc(){} +function $Xc(){} +function mYc(){} +function rYc(){} +function zYc(){} +function DYc(){} +function FYc(){} +function HYc(){} +function JYc(){} +function cZc(){} +function gZc(){} +function iZc(){} +function pZc(){} +function tZc(){} +function vZc(){} +function AZc(){} +function GZc(){} +function l_c(){} +function l1c(){} +function b1c(){} +function d1c(){} +function h1c(){} +function n1c(){} +function r1c(){} +function v1c(){} +function x1c(){} +function D1c(){} +function H1c(){} +function L1c(){} +function R1c(){} +function V1c(){} +function Z1c(){} +function Z0c(){} +function a0c(){} +function c0c(){} +function e0c(){} +function k0c(){} +function o0c(){} +function b2c(){} +function l2c(){} +function p2c(){} +function Y2c(){} +function _2c(){} +function A3c(){} +function F3c(){} +function I3c(){} +function K3c(){} +function M3c(){} +function Q3c(){} +function U3c(){} +function c5c(){} +function D5c(){} +function G5c(){} +function J5c(){} +function N5c(){} +function V5c(){} +function p6c(){} +function s6c(){} +function H6c(){} +function K6c(){} +function _7c(){} +function h8c(){} +function j8c(){} +function o8c(){} +function r8c(){} +function u8c(){} +function R8c(){} +function X8c(){} +function o9c(){} +function s9c(){} +function x9c(){} +function Qad(){} +function rcd(){} +function Xcd(){} +function vdd(){} +function Tdd(){} +function _dd(){} +function qed(){} +function sed(){} +function ved(){} +function Hed(){} +function Zed(){} +function bfd(){} +function ifd(){} +function Gfd(){} +function Ifd(){} +function Igd(){} +function agd(){} +function dgd(){} +function pgd(){} +function Hgd(){} +function Kgd(){} +function Mgd(){} +function Ogd(){} +function Qgd(){} +function Sgd(){} +function Ugd(){} +function Wgd(){} +function Ygd(){} +function $gd(){} +function ahd(){} +function chd(){} +function ehd(){} +function ghd(){} +function ihd(){} +function khd(){} +function mhd(){} +function ohd(){} +function qhd(){} +function shd(){} +function Shd(){} +function lkd(){} +function znd(){} +function Jpd(){} +function jrd(){} +function Mrd(){} +function Qrd(){} +function Urd(){} +function Yrd(){} +function Yud(){} +function eud(){} +function asd(){} +function Lsd(){} +function btd(){} +function dtd(){} +function jtd(){} +function otd(){} +function ztd(){} +function Xxd(){} +function $yd(){} +function rzd(){} +function Rzd(){} +function KAd(){} +function hCd(){} +function _Cd(){} +function _Sd(){} +function OSd(){} +function BDd(){} +function BId(){} +function JId(){} +function YHd(){} +function fLd(){} +function cPd(){} +function hQd(){} +function AQd(){} +function kUd(){} +function VUd(){} +function pVd(){} +function W$d(){} +function Z$d(){} +function a_d(){} +function i_d(){} +function v_d(){} +function y_d(){} +function f1d(){} +function L5d(){} +function v6d(){} +function b8d(){} +function e8d(){} +function h8d(){} +function k8d(){} +function n8d(){} +function q8d(){} +function t8d(){} +function w8d(){} +function z8d(){} +function X9d(){} +function _9d(){} +function Mae(){} +function cbe(){} +function ebe(){} +function hbe(){} +function kbe(){} +function nbe(){} +function qbe(){} +function tbe(){} +function wbe(){} +function zbe(){} +function Cbe(){} +function Fbe(){} +function Ibe(){} +function Lbe(){} +function Obe(){} +function Rbe(){} +function Ube(){} +function Xbe(){} +function $be(){} +function bce(){} +function ece(){} +function hce(){} +function kce(){} +function nce(){} +function qce(){} +function tce(){} +function wce(){} +function zce(){} +function Cce(){} +function Fce(){} +function Ice(){} +function Lce(){} +function Oce(){} +function Rce(){} +function Uce(){} +function Xce(){} +function $ce(){} +function bde(){} +function ede(){} +function hde(){} +function kde(){} +function nde(){} +function qde(){} +function tde(){} +function wde(){} +function Hie(){} +function rke(){} +function rne(){} +function Ene(){} +function Gne(){} +function Jne(){} +function Mne(){} +function Pne(){} +function Sne(){} +function Vne(){} +function Yne(){} +function _ne(){} +function yme(){} +function coe(){} +function foe(){} +function ioe(){} +function loe(){} +function ooe(){} +function roe(){} +function uoe(){} +function xoe(){} +function Aoe(){} +function Doe(){} +function Goe(){} +function Joe(){} +function Moe(){} +function Poe(){} +function Soe(){} +function Voe(){} +function Yoe(){} +function _oe(){} +function cpe(){} +function fpe(){} +function ipe(){} +function lpe(){} +function ope(){} +function rpe(){} +function upe(){} +function xpe(){} +function Ape(){} +function Dpe(){} +function Gpe(){} +function Jpe(){} +function Mpe(){} +function Ppe(){} +function Spe(){} +function Vpe(){} +function Ype(){} +function _pe(){} +function cqe(){} +function fqe(){} +function iqe(){} +function lqe(){} +function oqe(){} +function rqe(){} +function uqe(){} +function Tqe(){} +function sue(){} +function Cue(){} +function A2b(a){} +function J3d(a){} +function zl(){wb()} +function z7b(){s7b()} +function ZHb(){YHb()} +function fSb(){eSb()} +function vSb(){tSb()} +function PUb(){OUb()} +function AVb(){yVb()} +function RVb(){QVb()} +function fWb(){dWb()} +function N5b(){H5b()} +function $9b(){U9b()} +function Lcc(){Hcc()} +function pdc(){Zcc()} +function pec(){iec()} +function pGc(){nGc()} +function jGc(){gGc()} +function YGc(){SGc()} +function cGc(){_Fc()} +function NFc(){KFc()} +function xgc(){sgc()} +function xHc(){tHc()} +function pHc(){lHc()} +function IHc(){CHc()} +function XHc(){RHc()} +function boc(){Mnc()} +function yqc(){mqc()} +function Pzc(){Ozc()} +function ACc(){yCc()} +function aKc(){YJc()} +function FLc(){DLc()} +function DNc(){ANc()} +function TNc(){JNc()} +function iQc(){gQc()} +function WRc(){TRc()} +function C$c(){B$c()} +function J0c(){B0c()} +function x0c(){r0c()} +function j_c(){h_c()} +function N_c(){H_c()} +function V_c(){R_c()} +function E4c(){D4c()} +function a5c(){$4c()} +function v7c(){u7c()} +function Z7c(){X7c()} +function pcd(){ncd()} +function Lcd(){Kcd()} +function Vcd(){Tcd()} +function fUd(){TTd()} +function Bfd(){Afd()} +function jkd(){hkd()} +function vmd(){umd()} +function xnd(){vnd()} +function Hpd(){Fpd()} +function HYd(){lYd()} +function yAd(){qAd()} +function gke(){rue()} +function Yxb(a){uFb(a)} +function Yb(a){this.a=a} +function cc(a){this.a=a} +function df(a){this.a=a} +function kf(a){this.a=a} +function kj(a){this.a=a} +function qj(a){this.a=a} +function Lj(a){this.a=a} +function jh(a){this.a=a} +function th(a){this.a=a} +function Bh(a){this.a=a} +function Xh(a){this.a=a} +function Xn(a){this.a=a} +function Di(a){this.a=a} +function Ki(a){this.a=a} +function Ik(a){this.a=a} +function Qk(a){this.a=a} +function mp(a){this.a=a} +function Lp(a){this.a=a} +function iq(a){this.a=a} +function Eq(a){this.a=a} +function Vq(a){this.a=a} +function Or(a){this.a=a} +function $r(a){this.b=a} +function Aj(a){this.c=a} +function vu(a){this.a=a} +function vw(a){this.a=a} +function gw(a){this.a=a} +function lw(a){this.a=a} +function Iw(a){this.a=a} +function Nw(a){this.a=a} +function Sw(a){this.a=a} +function ex(a){this.a=a} +function fx(a){this.a=a} +function lx(a){this.a=a} +function my(a){this.a=a} +function qy(a){this.a=a} +function Oy(a){this.a=a} +function NB(a){this.a=a} +function XB(a){this.a=a} +function hC(a){this.a=a} +function vC(a){this.a=a} +function MB(){this.a=[]} +function HEb(a,b){a.a=b} +function E2b(a,b){a.a=b} +function F2b(a,b){a.b=b} +function PRb(a,b){a.b=b} +function RRb(a,b){a.b=b} +function QJb(a,b){a.j=b} +function hQb(a,b){a.g=b} +function iQb(a,b){a.i=b} +function _Tb(a,b){a.c=b} +function G2b(a,b){a.c=b} +function H2b(a,b){a.d=b} +function aUb(a,b){a.d=b} +function h3b(a,b){a.k=b} +function O3b(a,b){a.c=b} +function Tmc(a,b){a.c=b} +function Smc(a,b){a.a=b} +function DJc(a,b){a.a=b} +function EJc(a,b){a.f=b} +function NSc(a,b){a.a=b} +function OSc(a,b){a.b=b} +function PSc(a,b){a.d=b} +function QSc(a,b){a.i=b} +function RSc(a,b){a.o=b} +function SSc(a,b){a.r=b} +function yUc(a,b){a.a=b} +function zUc(a,b){a.b=b} +function q3c(a,b){a.e=b} +function r3c(a,b){a.f=b} +function s3c(a,b){a.g=b} +function Y9c(a,b){a.e=b} +function Z9c(a,b){a.f=b} +function kad(a,b){a.f=b} +function Ntd(a,b){a.a=b} +function Otd(a,b){a.b=b} +function BWd(a,b){a.n=b} +function $ee(a,b){a.a=b} +function _ee(a,b){a.c=b} +function ife(a,b){a.c=b} +function Efe(a,b){a.c=b} +function hfe(a,b){a.a=b} +function Dfe(a,b){a.a=b} +function jfe(a,b){a.d=b} +function Ffe(a,b){a.d=b} +function kfe(a,b){a.e=b} +function Gfe(a,b){a.e=b} +function lfe(a,b){a.g=b} +function Hfe(a,b){a.f=b} +function Ife(a,b){a.j=b} +function wme(a,b){a.a=b} +function Fme(a,b){a.a=b} +function xme(a,b){a.b=b} +function gmc(a){a.b=a.a} +function Lg(a){a.c=a.d.d} +function fgb(a){this.a=a} +function zgb(a){this.a=a} +function Xgb(a){this.a=a} +function Xkb(a){this.a=a} +function mkb(a){this.a=a} +function reb(a){this.a=a} +function Seb(a){this.a=a} +function bfb(a){this.a=a} +function Tfb(a){this.a=a} +function blb(a){this.a=a} +function glb(a){this.a=a} +function llb(a){this.a=a} +function Ulb(a){this.a=a} +function _lb(a){this.a=a} +function Plb(a){this.b=a} +function Ppb(a){this.b=a} +function xpb(a){this.b=a} +function mpb(a){this.a=a} +function Yqb(a){this.a=a} +function uqb(a){this.c=a} +function Anb(a){this.c=a} +function zwb(a){this.c=a} +function Dkb(a){this.d=a} +function brb(a){this.a=a} +function Frb(a){this.a=a} +function hsb(a){this.a=a} +function ctb(a){this.a=a} +function cxb(a){this.a=a} +function axb(a){this.a=a} +function exb(a){this.a=a} +function gxb(a){this.a=a} +function wub(a){this.a=a} +function zAb(a){this.a=a} +function JAb(a){this.a=a} +function LAb(a){this.a=a} +function PAb(a){this.a=a} +function VBb(a){this.a=a} +function lCb(a){this.a=a} +function nCb(a){this.a=a} +function pCb(a){this.a=a} +function CCb(a){this.a=a} +function GCb(a){this.a=a} +function bDb(a){this.a=a} +function dDb(a){this.a=a} +function fDb(a){this.a=a} +function uDb(a){this.a=a} +function $Db(a){this.a=a} +function aEb(a){this.a=a} +function eEb(a){this.a=a} +function OEb(a){this.a=a} +function SEb(a){this.a=a} +function SFb(a){this.a=a} +function HFb(a){this.a=a} +function NFb(a){this.a=a} +function WGb(a){this.a=a} +function HJb(a){this.a=a} +function PJb(a){this.a=a} +function kNb(a){this.a=a} +function tOb(a){this.a=a} +function APb(a){this.a=a} +function IQb(a){this.a=a} +function bTb(a){this.a=a} +function dTb(a){this.a=a} +function wTb(a){this.a=a} +function GWb(a){this.a=a} +function UWb(a){this.a=a} +function WWb(a){this.a=a} +function fXb(a){this.a=a} +function jXb(a){this.a=a} +function M0b(a){this.a=a} +function r1b(a){this.a=a} +function D1b(a){this.e=a} +function T3b(a){this.a=a} +function W3b(a){this.a=a} +function _3b(a){this.a=a} +function c4b(a){this.a=a} +function s5b(a){this.a=a} +function u5b(a){this.a=a} +function y5b(a){this.a=a} +function C5b(a){this.a=a} +function Q5b(a){this.a=a} +function S5b(a){this.a=a} +function U5b(a){this.a=a} +function W5b(a){this.a=a} +function l7b(a){this.a=a} +function p7b(a){this.a=a} +function k8b(a){this.a=a} +function L8b(a){this.a=a} +function Rac(a){this.a=a} +function Xac(a){this.a=a} +function $ac(a){this.a=a} +function bbc(a){this.a=a} +function Cdc(a){this.a=a} +function Edc(a){this.a=a} +function Ehc(a){this.a=a} +function khc(a){this.a=a} +function Ihc(a){this.a=a} +function qfc(a){this.a=a} +function tfc(a){this.a=a} +function Wfc(a){this.a=a} +function Fic(a){this.a=a} +function Vic(a){this.a=a} +function fjc(a){this.a=a} +function pjc(a){this.a=a} +function ckc(a){this.a=a} +function hkc(a){this.a=a} +function Ykc(a){this.a=a} +function $kc(a){this.a=a} +function alc(a){this.a=a} +function glc(a){this.a=a} +function ilc(a){this.a=a} +function slc(a){this.a=a} +function Clc(a){this.a=a} +function xoc(a){this.a=a} +function zoc(a){this.a=a} +function spc(a){this.a=a} +function Vqc(a){this.a=a} +function Xqc(a){this.a=a} +function Gsc(a){this.a=a} +function Isc(a){this.a=a} +function JGc(a){this.a=a} +function NGc(a){this.a=a} +function MHc(a){this.a=a} +function JIc(a){this.a=a} +function fJc(a){this.a=a} +function BJc(a){this.a=a} +function dJc(a){this.c=a} +function Trc(a){this.b=a} +function eKc(a){this.a=a} +function IKc(a){this.a=a} +function KKc(a){this.a=a} +function MKc(a){this.a=a} +function yLc(a){this.a=a} +function HMc(a){this.a=a} +function LMc(a){this.a=a} +function PMc(a){this.a=a} +function TMc(a){this.a=a} +function XMc(a){this.a=a} +function ZMc(a){this.a=a} +function aNc(a){this.a=a} +function jNc(a){this.a=a} +function aPc(a){this.a=a} +function gPc(a){this.a=a} +function kPc(a){this.a=a} +function yPc(a){this.a=a} +function CPc(a){this.a=a} +function JPc(a){this.a=a} +function RPc(a){this.a=a} +function XPc(a){this.a=a} +function mRc(a){this.a=a} +function xTc(a){this.a=a} +function CWc(a){this.a=a} +function EWc(a){this.a=a} +function IWc(a){this.a=a} +function OWc(a){this.a=a} +function dXc(a){this.a=a} +function gXc(a){this.a=a} +function EXc(a){this.a=a} +function WXc(a){this.a=a} +function YXc(a){this.a=a} +function aYc(a){this.a=a} +function cYc(a){this.a=a} +function eYc(a){this.a=a} +function iYc(a){this.a=a} +function i0c(a){this.a=a} +function g0c(a){this.a=a} +function P1c(a){this.a=a} +function Sad(a){this.a=a} +function Uad(a){this.a=a} +function Wad(a){this.a=a} +function Yad(a){this.a=a} +function cbd(a){this.a=a} +function ydd(a){this.a=a} +function Kdd(a){this.a=a} +function Mdd(a){this.a=a} +function _ed(a){this.a=a} +function dfd(a){this.a=a} +function Kfd(a){this.a=a} +function prd(a){this.a=a} +function $rd(a){this.a=a} +function csd(a){this.a=a} +function Usd(a){this.a=a} +function Vtd(a){this.a=a} +function wud(a){this.a=a} +function Rud(a){this.f=a} +function LEd(a){this.a=a} +function UEd(a){this.a=a} +function VEd(a){this.a=a} +function WEd(a){this.a=a} +function XEd(a){this.a=a} +function YEd(a){this.a=a} +function ZEd(a){this.a=a} +function $Ed(a){this.a=a} +function _Ed(a){this.a=a} +function aFd(a){this.a=a} +function gFd(a){this.a=a} +function iFd(a){this.a=a} +function jFd(a){this.a=a} +function kFd(a){this.a=a} +function lFd(a){this.a=a} +function nFd(a){this.a=a} +function qFd(a){this.a=a} +function wFd(a){this.a=a} +function xFd(a){this.a=a} +function zFd(a){this.a=a} +function AFd(a){this.a=a} +function BFd(a){this.a=a} +function CFd(a){this.a=a} +function DFd(a){this.a=a} +function MFd(a){this.a=a} +function OFd(a){this.a=a} +function QFd(a){this.a=a} +function SFd(a){this.a=a} +function uGd(a){this.a=a} +function QGd(a){this.a=a} +function jGd(a){this.b=a} +function YOd(a){this.a=a} +function ePd(a){this.a=a} +function kPd(a){this.a=a} +function qPd(a){this.a=a} +function IPd(a){this.a=a} +function w$d(a){this.a=a} +function e_d(a){this.a=a} +function Q_d(a){this.b=a} +function c1d(a){this.a=a} +function c2d(a){this.a=a} +function l5d(a){this.a=a} +function I9d(a){this.a=a} +function L6d(a){this.c=a} +function t7d(a){this.e=a} +function pae(a){this.a=a} +function xae(a){this.a=a} +function Zde(a){this.a=a} +function Sde(a){this.d=a} +function mee(a){this.a=a} +function uje(a){this.a=a} +function Bte(a){this.a=a} +function Wse(a){this.e=a} +function Xsd(){this.a=0} +function Tsb(){akb(this)} +function bnb(){Pmb(this)} +function cHb(){bHb(this)} +function I2b(){A2b(this)} +function s2d(){this.c=d2d} +function Prc(a,b){a.b+=b} +function Uje(a,b){b.Wb(a)} +function UC(a){return a.a} +function nC(a){return a.a} +function BC(a){return a.a} +function TB(a){return a.a} +function _B(a){return a.a} +function Adb(a){return a.e} +function gC(){return null} +function MC(){return null} +function leb(){MId();OId()} +function qMb(a){a.b.Of(a.e)} +function A$b(a){a.b=new Ri} +function A8b(a,b){a.b=b-a.b} +function x8b(a,b){a.a=b-a.a} +function ZEb(a,b){a.push(b)} +function bFb(a,b){a.sort(b)} +function Q5c(a,b){b.jd(a.a)} +function Voc(a,b){Q3b(b,a)} +function tp(a,b,c){a.Yd(c,b)} +function Ss(a,b){a.e=b;b.b=a} +function im(a){_l();this.a=a} +function xq(a){_l();this.a=a} +function Gq(a){_l();this.a=a} +function Xq(a){tm();this.a=a} +function gA(a){fA();eA.le(a)} +function vA(){vA=geb;new Tsb} +function xz(){mz.call(this)} +function Ceb(){mz.call(this)} +function ueb(){xz.call(this)} +function yeb(){xz.call(this)} +function Hfb(){xz.call(this)} +function _fb(){xz.call(this)} +function cgb(){xz.call(this)} +function Ngb(){xz.call(this)} +function jib(){xz.call(this)} +function Jrb(){xz.call(this)} +function Srb(){xz.call(this)} +function Dvb(){xz.call(this)} +function Ied(){xz.call(this)} +function R1d(){this.a=this} +function k1d(){this.Bb|=256} +function vWb(){this.b=new Et} +function aFb(a,b){a.length=b} +function dyb(a,b){Rmb(a.a,b)} +function jNb(a,b){LKb(a.c,b)} +function qRc(a,b){Ysb(a.b,b)} +function VOd(a,b){UNd(a.a,b)} +function WOd(a,b){VNd(a.a,b)} +function eZd(a,b){qvd(a.e,b)} +function Cke(a){bge(a.c,a.b)} +function uj(a,b){a.kc().Nb(b)} +function Ufb(a){this.a=Zfb(a)} +function _sb(){this.a=new Tsb} +function $Ab(){this.a=new Tsb} +function xAb(){this.a=new dzb} +function gyb(){this.a=new bnb} +function BIb(){this.a=new bnb} +function GIb(){this.a=new bnb} +function wIb(){this.a=new pIb} +function gJb(){this.a=new DIb} +function TTb(){this.a=new DTb} +function jGb(){this.a=new fGb} +function qGb(){this.a=new kGb} +function q_b(){this.a=new bnb} +function E_b(){this.a=new bnb} +function EZb(){this.a=new bnb} +function J$b(){this.a=new bnb} +function YNb(){this.d=new bnb} +function lXb(){this.a=new RWb} +function y_b(){this.a=new _sb} +function k5b(){this.a=new Tsb} +function E0b(){this.b=new Tsb} +function jHc(){this.b=new bnb} +function ZNc(){this.e=new bnb} +function ahc(){this.a=new boc} +function UQc(){this.d=new bnb} +function uRc(){tRc.call(this)} +function BRc(){tRc.call(this)} +function VOc(){bnb.call(this)} +function web(){ueb.call(this)} +function Fyb(){gyb.call(this)} +function fKb(){RJb.call(this)} +function N$b(){J$b.call(this)} +function P2b(){I2b.call(this)} +function T2b(){P2b.call(this)} +function z3b(){I2b.call(this)} +function C3b(){z3b.call(this)} +function cUc(){aUc.call(this)} +function hUc(){aUc.call(this)} +function mUc(){aUc.call(this)} +function Hdd(){Ddd.call(this)} +function ACd(){$yd.call(this)} +function PCd(){$yd.call(this)} +function Ejd(){Yub.call(this)} +function LQd(){wQd.call(this)} +function lRd(){wQd.call(this)} +function MSd(){Tsb.call(this)} +function VSd(){Tsb.call(this)} +function eTd(){Tsb.call(this)} +function mXd(){HWd.call(this)} +function i1d(){_sb.call(this)} +function A1d(){k1d.call(this)} +function q4d(){dWd.call(this)} +function O5d(){Tsb.call(this)} +function R5d(){dWd.call(this)} +function lae(){Tsb.call(this)} +function Cae(){Tsb.call(this)} +function ome(){kUd.call(this)} +function Hme(){ome.call(this)} +function Nme(){kUd.call(this)} +function Gre(){Tqe.call(this)} +function aUc(){this.a=new _sb} +function nZc(){this.a=new Tsb} +function DZc(){this.a=new bnb} +function Ddd(){this.a=new Tsb} +function Oqd(){this.a=new Yub} +function Oed(){this.j=new bnb} +function obd(){this.a=new nbd} +function wQd(){this.a=new AQd} +function R5c(){this.a=new V5c} +function wb(){wb=geb;vb=new xb} +function Wk(){Wk=geb;Vk=new Xk} +function kl(){kl=geb;jl=new ll} +function ll(){Qk.call(this,'')} +function Xk(){Qk.call(this,'')} +function Dd(a){yd.call(this,a)} +function Hd(a){yd.call(this,a)} +function xh(a){th.call(this,a)} +function $h(a){Wc.call(this,a)} +function Qi(a){Wc.call(this,a)} +function wi(a){$h.call(this,a)} +function Sp(a){$h.call(this,a)} +function Js(a){$h.call(this,a)} +function Jp(a){Xo.call(this,a)} +function Qp(a){Xo.call(this,a)} +function dq(a){ho.call(this,a)} +function Fv(a){uv.call(this,a)} +function aw(a){Tr.call(this,a)} +function cw(a){Tr.call(this,a)} +function _w(a){Tr.call(this,a)} +function Mx(a){Gn.call(this,a)} +function Nx(a){Mx.call(this,a)} +function yz(a){nz.call(this,a)} +function aC(a){yz.call(this,a)} +function uC(){vC.call(this,{})} +function cC(){cC=geb;bC=new dC} +function zs(){zs=geb;ys=new As} +function Az(){Az=geb;zz=new nb} +function $z(){$z=geb;Zz=new bA} +function $A(){$A=geb;ZA=new aB} +function Ovb(a){Kvb();this.a=a} +function FKc(a){jKc();this.a=a} +function zud(a){nud();this.f=a} +function Bud(a){nud();this.f=a} +function Cde(a){KMd();this.a=a} +function Lyb(a){a.b=null;a.c=0} +function kz(a,b){a.e=b;hz(a,b)} +function NYb(a,b){a.a=b;PYb(a)} +function cLb(a,b,c){a.a[b.g]=c} +function zsd(a,b,c){Hsd(c,a,b)} +function shc(a,b){Xmc(b.i,a.n)} +function HCc(a,b){ICc(a).Cd(b)} +function yw(a,b){a.a.ec().Mc(b)} +function ns(a,b){return a.g-b.g} +function AUb(a,b){return a*a/b} +function Heb(a){return uFb(a),a} +function Kfb(a){return uFb(a),a} +function Mfb(a){return uFb(a),a} +function JC(a){return new hC(a)} +function LC(a){return new OC(a)} +function shb(a){return uFb(a),a} +function Chb(a){return uFb(a),a} +function teb(a){yz.call(this,a)} +function veb(a){yz.call(this,a)} +function zeb(a){yz.call(this,a)} +function Aeb(a){nz.call(this,a)} +function Ifb(a){yz.call(this,a)} +function agb(a){yz.call(this,a)} +function dgb(a){yz.call(this,a)} +function Mgb(a){yz.call(this,a)} +function Ogb(a){yz.call(this,a)} +function kib(a){yz.call(this,a)} +function Jed(a){yz.call(this,a)} +function Ked(a){yz.call(this,a)} +function CDd(a){yz.call(this,a)} +function Mle(a){yz.call(this,a)} +function Lqe(a){yz.call(this,a)} +function mob(a){uFb(a);this.a=a} +function yYb(a){sYb(a);return a} +function Nnb(a){Snb(a,a.length)} +function nmb(a){return a.b==a.c} +function Vyb(a){return !!a&&a.b} +function gLb(a){return !!a&&a.k} +function hLb(a){return !!a&&a.j} +function F_b(a,b,c){a.c.Ef(b,c)} +function Ts(a,b){a.be(b);b.ae(a)} +function Fy(a){_l();this.a=Qb(a)} +function Gb(){this.a=WD(Qb(pve))} +function jc(){throw Adb(new jib)} +function jn(){throw Adb(new jib)} +function Hh(){throw Adb(new jib)} +function Xi(){throw Adb(new jib)} +function Xj(){throw Adb(new jib)} +function Yj(){throw Adb(new jib)} +function Qz(){Qz=geb;!!(fA(),eA)} +function Qhb(){reb.call(this,'')} +function Rhb(){reb.call(this,'')} +function bib(){reb.call(this,'')} +function cib(){reb.call(this,'')} +function eib(a){veb.call(this,a)} +function xeb(a){veb.call(this,a)} +function Vgb(a){agb.call(this,a)} +function Lqb(a){xpb.call(this,a)} +function Sqb(a){Lqb.call(this,a)} +function irb(a){Upb.call(this,a)} +function pc(a){qc.call(this,a,0)} +function Ri(){Si.call(this,12,3)} +function WC(a,b){return xfb(a,b)} +function cFb(a,b){return dD(a,b)} +function Reb(a,b){return a.a-b.a} +function afb(a,b){return a.a-b.a} +function Wgb(a,b){return a.a-b.a} +function pC(b,a){return a in b.a} +function Vvb(a){return a.a?a.b:0} +function cwb(a){return a.a?a.b:0} +function Fxb(a,b,c){b.Cd(a.a[c])} +function Kxb(a,b,c){b.Pe(a.a[c])} +function uKb(a,b){a.b=new sjd(b)} +function QGb(a,b){a.b=b;return a} +function RGb(a,b){a.c=b;return a} +function SGb(a,b){a.f=b;return a} +function TGb(a,b){a.g=b;return a} +function yJb(a,b){a.a=b;return a} +function zJb(a,b){a.f=b;return a} +function AJb(a,b){a.k=b;return a} +function WNb(a,b){a.a=b;return a} +function XNb(a,b){a.e=b;return a} +function BYb(a,b){a.e=b;return a} +function CYb(a,b){a.f=b;return a} +function BRb(a,b){a.b=true;a.d=b} +function WNc(a,b){return a.b-b.b} +function KSc(a,b){return a.g-b.g} +function pmc(a,b){return a?0:b-1} +function qKc(a,b){return a?0:b-1} +function pKc(a,b){return a?b-1:0} +function uVc(a,b){return a.s-b.s} +function Xed(a,b){return b.rg(a)} +function Xfd(a,b){a.b=b;return a} +function Wfd(a,b){a.a=b;return a} +function Yfd(a,b){a.c=b;return a} +function Zfd(a,b){a.d=b;return a} +function $fd(a,b){a.e=b;return a} +function _fd(a,b){a.f=b;return a} +function mgd(a,b){a.a=b;return a} +function ngd(a,b){a.b=b;return a} +function ogd(a,b){a.c=b;return a} +function Khd(a,b){a.c=b;return a} +function Jhd(a,b){a.b=b;return a} +function Lhd(a,b){a.d=b;return a} +function Mhd(a,b){a.e=b;return a} +function Nhd(a,b){a.f=b;return a} +function Ohd(a,b){a.g=b;return a} +function Phd(a,b){a.a=b;return a} +function Qhd(a,b){a.i=b;return a} +function Rhd(a,b){a.j=b;return a} +function coc(a,b){Mnc();P3b(b,a)} +function bbd(a,b,c){_ad(a.a,b,c)} +function Fjd(a){Zub.call(this,a)} +function TRb(a){SRb.call(this,a)} +function pLc(a){CIc.call(this,a)} +function ILc(a){CIc.call(this,a)} +function gLd(a){ZHd.call(this,a)} +function DPd(a){xPd.call(this,a)} +function FPd(a){xPd.call(this,a)} +function x2b(){y2b.call(this,'')} +function pjd(){this.a=0;this.b=0} +function ATc(){this.b=0;this.a=0} +function lXd(a,b){a.b=0;bWd(a,b)} +function Kqd(a,b){a.k=b;return a} +function Lqd(a,b){a.j=b;return a} +function vfe(a,b){a.c=b;a.b=true} +function Etb(){Etb=geb;Dtb=Gtb()} +function bvd(){bvd=geb;avd=OAd()} +function dvd(){dvd=geb;cvd=aCd()} +function MId(){MId=geb;LId=ygd()} +function jTd(){jTd=geb;iTd=Qae()} +function Ole(){Ole=geb;Nle=vne()} +function Qle(){Qle=geb;Ple=Cne()} +function mfb(a){return a.e&&a.e()} +function FD(a){return a.l|a.m<<22} +function Oc(a,b){return a.c._b(b)} +function En(a,b){return Wv(a.b,b)} +function Vd(a){return !a?null:a.d} +function Vv(a){return !a?null:a.g} +function $v(a){return !a?null:a.i} +function nfb(a){lfb(a);return a.o} +function Khb(a,b){a.a+=b;return a} +function Lhb(a,b){a.a+=b;return a} +function Ohb(a,b){a.a+=b;return a} +function Uhb(a,b){a.a+=b;return a} +function _wb(a,b){while(a.Bd(b));} +function atb(a){this.a=new Usb(a)} +function $tb(){throw Adb(new jib)} +function qpb(){throw Adb(new jib)} +function rpb(){throw Adb(new jib)} +function spb(){throw Adb(new jib)} +function vpb(){throw Adb(new jib)} +function Opb(){throw Adb(new jib)} +function yAb(a){this.a=new ezb(a)} +function H2c(){this.a=new Wed(s0)} +function TVc(){this.b=new Wed(H$)} +function l6c(){this.a=new Wed(V0)} +function $ad(){this.b=new Wed(I1)} +function nbd(){this.b=new Wed(I1)} +function T2c(a){this.a=0;this.b=a} +function Bib(a){tib();vib(this,a)} +function QDb(a){LCb(a);return a.a} +function dvb(a){return a.b!=a.d.c} +function AMc(a,b){return a.d[b.p]} +function ued(a,b){return ned(a,b)} +function $Eb(a,b,c){a.splice(b,c)} +function ixb(a,b){while(a.Re(b));} +function NKb(a){a.c?MKb(a):OKb(a)} +function mQd(){throw Adb(new jib)} +function nQd(){throw Adb(new jib)} +function oQd(){throw Adb(new jib)} +function pQd(){throw Adb(new jib)} +function qQd(){throw Adb(new jib)} +function rQd(){throw Adb(new jib)} +function sQd(){throw Adb(new jib)} +function tQd(){throw Adb(new jib)} +function uQd(){throw Adb(new jib)} +function vQd(){throw Adb(new jib)} +function zue(){throw Adb(new Dvb)} +function Aue(){throw Adb(new Dvb)} +function oue(a){this.a=new Dte(a)} +function Dte(a){Cte(this,a,sse())} +function cve(a){return !a||bve(a)} +function Cqe(a){return xqe[a]!=-1} +function Yz(){Nz!=0&&(Nz=0);Pz=-1} +function beb(){_db==null&&(_db=[])} +function eg(a,b){zf.call(this,a,b)} +function gg(a,b){eg.call(this,a,b)} +function Nj(a,b){this.a=a;this.b=b} +function hk(a,b){this.a=a;this.b=b} +function nk(a,b){this.a=a;this.b=b} +function pk(a,b){this.a=a;this.b=b} +function xk(a,b){this.a=a;this.b=b} +function zk(a,b){this.a=a;this.b=b} +function Kk(a,b){this.a=a;this.b=b} +function ne(a,b){this.e=a;this.d=b} +function Hf(a,b){this.b=a;this.c=b} +function cp(a,b){this.b=a;this.a=b} +function Cp(a,b){this.b=a;this.a=b} +function qr(a,b){this.b=a;this.a=b} +function Rr(a,b){this.b=a;this.a=b} +function vr(a,b){this.a=a;this.b=b} +function su(a,b){this.a=a;this.b=b} +function Hu(a,b){this.a=a;this.f=b} +function gp(a,b){this.g=a;this.i=b} +function qs(a,b){this.f=a;this.g=b} +function Gv(a,b){this.b=a;this.c=b} +function Wc(a){Lb(a.dc());this.c=a} +function Ex(a,b){this.a=a;this.b=b} +function ey(a,b){this.a=a;this.b=b} +function pv(a){this.a=RD(Qb(a),15)} +function uv(a){this.a=RD(Qb(a),15)} +function nw(a){this.a=RD(Qb(a),85)} +function rf(a){this.b=RD(Qb(a),85)} +function Tr(a){this.b=RD(Qb(a),51)} +function uB(){this.q=new $wnd.Date} +function CC(a,b){this.a=a;this.b=b} +function Bt(a,b){return Ujb(a.b,b)} +function tpb(a,b){return a.b.Hc(b)} +function upb(a,b){return a.b.Ic(b)} +function wpb(a,b){return a.b.Qc(b)} +function Pqb(a,b){return a.b.Hc(b)} +function pqb(a,b){return a.c.uc(b)} +function rqb(a,b){return pb(a.c,b)} +function Zsb(a,b){return a.a._b(b)} +function Xp(a,b){return a>b&&b0} +function Ldb(a,b){return Ddb(a,b)<0} +function Urb(a,b){return Bsb(a.a,b)} +function Beb(a,b){oz.call(this,a,b)} +function Qx(a){Px();ho.call(this,a)} +function Lnb(a,b){Pnb(a,a.length,b)} +function Mnb(a,b){Rnb(a,a.length,b)} +function Ktb(a,b){return a.a.get(b)} +function bub(a,b){return Ujb(a.e,b)} +function Zxb(a){return uFb(a),false} +function zw(a){this.a=RD(Qb(a),229)} +function $wb(a){Swb.call(this,a,21)} +function dAb(a,b){qs.call(this,a,b)} +function yBb(a,b){qs.call(this,a,b)} +function ssb(a,b){this.b=a;this.a=b} +function xlb(a,b){this.d=a;this.e=b} +function jEb(a,b){this.a=a;this.b=b} +function pEb(a,b){this.a=a;this.b=b} +function vEb(a,b){this.a=a;this.b=b} +function BEb(a,b){this.a=a;this.b=b} +function TFb(a,b){this.a=a;this.b=b} +function QEb(a,b){this.b=a;this.a=b} +function sHb(a,b){this.b=a;this.a=b} +function EHb(a,b){qs.call(this,a,b)} +function MHb(a,b){qs.call(this,a,b)} +function jIb(a,b){qs.call(this,a,b)} +function $Jb(a,b){qs.call(this,a,b)} +function FKb(a,b){qs.call(this,a,b)} +function wLb(a,b){qs.call(this,a,b)} +function nOb(a,b){qs.call(this,a,b)} +function kPb(a,b){this.b=a;this.a=b} +function JPb(a,b){qs.call(this,a,b)} +function fRb(a,b){this.b=a;this.a=b} +function JRb(a,b){qs.call(this,a,b)} +function OTb(a,b){this.b=a;this.a=b} +function UUb(a,b){qs.call(this,a,b)} +function BWb(a,b){qs.call(this,a,b)} +function tXb(a,b){qs.call(this,a,b)} +function XEb(a,b,c){a.splice(b,0,c)} +function pr(a,b,c){a.Mb(c)&&b.Cd(c)} +function lEb(a,b,c){b.Pe(a.a.Ye(c))} +function rEb(a,b,c){b.Dd(a.a.Ze(c))} +function xEb(a,b,c){b.Cd(a.a.Kb(c))} +function eYb(a,b){return Csb(a.c,b)} +function cGb(a,b){return Csb(a.e,b)} +function qZb(a,b){qs.call(this,a,b)} +function V$b(a,b){qs.call(this,a,b)} +function s3b(a,b){qs.call(this,a,b)} +function Q8b(a,b){qs.call(this,a,b)} +function icc(a,b){qs.call(this,a,b)} +function xec(a,b){qs.call(this,a,b)} +function gic(a,b){this.a=a;this.b=b} +function Xic(a,b){this.a=a;this.b=b} +function h4b(a,b){this.a=a;this.b=b} +function vjc(a,b){this.a=a;this.b=b} +function xjc(a,b){this.a=a;this.b=b} +function Hjc(a,b){this.a=a;this.b=b} +function hjc(a,b){this.b=a;this.a=b} +function Jjc(a,b){this.b=a;this.a=b} +function _Yb(a,b){this.b=a;this.a=b} +function eZb(a,b){this.c=a;this.d=b} +function Q1b(a,b){this.e=a;this.d=b} +function Tjc(a,b){this.a=a;this.b=b} +function ulc(a,b){this.a=a;this.b=b} +function Elc(a,b){this.a=a;this.b=b} +function fqc(a,b){this.b=a;this.a=b} +function smc(a,b){this.b=b;this.c=a} +function fnc(a,b){qs.call(this,a,b)} +function Cnc(a,b){qs.call(this,a,b)} +function koc(a,b){qs.call(this,a,b)} +function ktc(a,b){qs.call(this,a,b)} +function ctc(a,b){qs.call(this,a,b)} +function utc(a,b){qs.call(this,a,b)} +function Ftc(a,b){qs.call(this,a,b)} +function Rtc(a,b){qs.call(this,a,b)} +function _tc(a,b){qs.call(this,a,b)} +function iuc(a,b){qs.call(this,a,b)} +function vuc(a,b){qs.call(this,a,b)} +function Duc(a,b){qs.call(this,a,b)} +function Puc(a,b){qs.call(this,a,b)} +function _uc(a,b){qs.call(this,a,b)} +function pvc(a,b){qs.call(this,a,b)} +function yvc(a,b){qs.call(this,a,b)} +function Hvc(a,b){qs.call(this,a,b)} +function Pvc(a,b){qs.call(this,a,b)} +function dxc(a,b){qs.call(this,a,b)} +function bDc(a,b){qs.call(this,a,b)} +function nDc(a,b){qs.call(this,a,b)} +function yDc(a,b){qs.call(this,a,b)} +function LDc(a,b){qs.call(this,a,b)} +function bEc(a,b){qs.call(this,a,b)} +function lEc(a,b){qs.call(this,a,b)} +function tEc(a,b){qs.call(this,a,b)} +function CEc(a,b){qs.call(this,a,b)} +function LEc(a,b){qs.call(this,a,b)} +function UEc(a,b){qs.call(this,a,b)} +function mFc(a,b){qs.call(this,a,b)} +function vFc(a,b){qs.call(this,a,b)} +function EFc(a,b){qs.call(this,a,b)} +function SKc(a,b){qs.call(this,a,b)} +function cNc(a,b){this.b=a;this.a=b} +function tNc(a,b){qs.call(this,a,b)} +function QOc(a,b){this.a=a;this.b=b} +function ePc(a,b){this.a=a;this.b=b} +function LPc(a,b){this.a=a;this.b=b} +function xQc(a,b){qs.call(this,a,b)} +function FQc(a,b){qs.call(this,a,b)} +function MQc(a,b){this.a=a;this.b=b} +function FMc(a,b){dMc();return b!=a} +function Uvb(a){sFb(a.a);return a.b} +function qYb(a){rYb(a,a.c);return a} +function Itb(){Etb();return new Dtb} +function _ec(){Rec();this.a=new e6b} +function lSc(){dSc();this.a=new _sb} +function aRc(){WQc();this.b=new _sb} +function xRc(a,b){this.b=a;this.d=b} +function nVc(a,b){this.a=a;this.b=b} +function pVc(a,b){this.a=a;this.b=b} +function GWc(a,b){this.a=a;this.b=b} +function IXc(a,b){this.b=a;this.a=b} +function gTc(a,b){qs.call(this,a,b)} +function eVc(a,b){qs.call(this,a,b)} +function $Vc(a,b){qs.call(this,a,b)} +function XYc(a,b){qs.call(this,a,b)} +function MZc(a,b){qs.call(this,a,b)} +function t_c(a,b){qs.call(this,a,b)} +function B_c(a,b){qs.call(this,a,b)} +function z2c(a,b){qs.call(this,a,b)} +function h3c(a,b){qs.call(this,a,b)} +function $3c(a,b){qs.call(this,a,b)} +function i4c(a,b){qs.call(this,a,b)} +function l5c(a,b){qs.call(this,a,b)} +function v5c(a,b){qs.call(this,a,b)} +function g6c(a,b){qs.call(this,a,b)} +function A6c(a,b){qs.call(this,a,b)} +function a7c(a,b){qs.call(this,a,b)} +function B8c(a,b){qs.call(this,a,b)} +function d9c(a,b){qs.call(this,a,b)} +function D9c(a,b){qs.call(this,a,b)} +function tad(a,b){qs.call(this,a,b)} +function hbd(a,b){qs.call(this,a,b)} +function Nbd(a,b){qs.call(this,a,b)} +function Ybd(a,b){qs.call(this,a,b)} +function ndd(a,b){qs.call(this,a,b)} +function z1c(a,b){this.b=a;this.a=b} +function B1c(a,b){this.b=a;this.a=b} +function d2c(a,b){this.b=a;this.a=b} +function f2c(a,b){this.b=a;this.a=b} +function m9c(a,b){this.a=a;this.b=b} +function xed(a,b){this.a=a;this.b=b} +function ffd(a,b){this.a=a;this.b=b} +function rjd(a,b){this.a=a;this.b=b} +function Sjd(a,b){qs.call(this,a,b)} +function Zhd(a,b){qs.call(this,a,b)} +function lid(a,b){qs.call(this,a,b)} +function vkd(a,b){qs.call(this,a,b)} +function Gmd(a,b){qs.call(this,a,b)} +function Pmd(a,b){qs.call(this,a,b)} +function Zmd(a,b){qs.call(this,a,b)} +function jnd(a,b){qs.call(this,a,b)} +function Gnd(a,b){qs.call(this,a,b)} +function Rnd(a,b){qs.call(this,a,b)} +function eod(a,b){qs.call(this,a,b)} +function qod(a,b){qs.call(this,a,b)} +function Eod(a,b){qs.call(this,a,b)} +function Qod(a,b){qs.call(this,a,b)} +function upd(a,b){qs.call(this,a,b)} +function Rpd(a,b){qs.call(this,a,b)} +function eqd(a,b){qs.call(this,a,b)} +function nqd(a,b){qs.call(this,a,b)} +function vqd(a,b){qs.call(this,a,b)} +function Hrd(a,b){qs.call(this,a,b)} +function esd(a,b){this.a=a;this.b=b} +function gsd(a,b){this.a=a;this.b=b} +function isd(a,b){this.a=a;this.b=b} +function Osd(a,b){this.a=a;this.b=b} +function Qsd(a,b){this.a=a;this.b=b} +function Ssd(a,b){this.a=a;this.b=b} +function Ptd(a,b){this.a=a;this.b=b} +function JEd(a,b){this.a=a;this.b=b} +function KEd(a,b){this.a=a;this.b=b} +function MEd(a,b){this.a=a;this.b=b} +function NEd(a,b){this.a=a;this.b=b} +function QEd(a,b){this.a=a;this.b=b} +function REd(a,b){this.a=a;this.b=b} +function SEd(a,b){this.b=a;this.a=b} +function TEd(a,b){this.b=a;this.a=b} +function bFd(a,b){this.b=a;this.a=b} +function dFd(a,b){this.b=a;this.a=b} +function fFd(a,b){this.a=a;this.b=b} +function hFd(a,b){this.a=a;this.b=b} +function utd(a,b){qs.call(this,a,b)} +function sFd(a,b){this.a=a;this.b=b} +function uFd(a,b){this.a=a;this.b=b} +function bGd(a,b){qs.call(this,a,b)} +function uId(a,b){this.f=a;this.c=b} +function Ofd(a,b){return Csb(a.g,b)} +function Tqc(a,b){return Csb(b.b,a)} +function HPd(a,b){return QNd(a.a,b)} +function Idd(a,b){return -a.b.af(b)} +function IId(a,b){!!a&&Zjb(CId,a,b)} +function yWd(a,b){a.i=null;zWd(a,b)} +function kEd(a,b,c){pDd(b,KDd(a,c))} +function lEd(a,b,c){pDd(b,KDd(a,c))} +function mFd(a,b){vEd(a.a,RD(b,58))} +function _Mc(a,b){GMc(a.a,RD(b,12))} +function KTd(a,b){this.a=a;this.b=b} +function NTd(a,b){this.a=a;this.b=b} +function B5d(a,b){this.a=a;this.b=b} +function Z6d(a,b){this.a=a;this.b=b} +function Ble(a,b){this.a=a;this.b=b} +function afe(a,b){this.d=a;this.b=b} +function wfe(a,b){this.e=a;this.a=b} +function Eke(a,b){this.b=a;this.c=b} +function zNd(a,b){this.i=a;this.g=b} +function kZd(a,b){this.d=a;this.e=b} +function ave(a,b){eve(new dMd(a),b)} +function Dke(a){return pge(a.c,a.b)} +function Wd(a){return !a?null:a.md()} +function dE(a){return a==null?null:a} +function bE(a){return typeof a===jve} +function $D(a){return typeof a===hve} +function _D(a){return typeof a===ive} +function Gdb(a,b){return Ddb(a,b)==0} +function Jdb(a,b){return Ddb(a,b)>=0} +function Pdb(a,b){return Ddb(a,b)!=0} +function ar(a,b){return zr(a.Kc(),b)} +function Qm(a,b){return a.Rd().Xb(b)} +function kg(a){ig(a);return a.d.gc()} +function fE(a){CFb(a==null);return a} +function Mhb(a,b){a.a+=''+b;return a} +function Nhb(a,b){a.a+=''+b;return a} +function Whb(a,b){a.a+=''+b;return a} +function Yhb(a,b){a.a+=''+b;return a} +function Zhb(a,b){a.a+=''+b;return a} +function Vhb(a,b){return a.a+=''+b,a} +function Pfb(a){return ''+(uFb(a),a)} +function Vsb(a){akb(this);Ld(this,a)} +function YFc(){RFc();UFc.call(this)} +function pxb(a,b){kxb.call(this,a,b)} +function txb(a,b){kxb.call(this,a,b)} +function xxb(a,b){kxb.call(this,a,b)} +function Oub(a,b){Pub(a,b,a.c.b,a.c)} +function Nub(a,b){Pub(a,b,a.a,a.a.a)} +function Iob(a){tFb(a,0);return null} +function Xvb(){this.b=0;this.a=false} +function dwb(){this.b=0;this.a=false} +function Et(){this.b=new Usb(Sv(12))} +function pMb(){pMb=geb;oMb=ss(nMb())} +function ncc(){ncc=geb;mcc=ss(lcc())} +function aZc(){aZc=geb;_Yc=ss($Yc())} +function WA(){WA=geb;vA();VA=new Tsb} +function hjd(a){a.a=0;a.b=0;return a} +function qfd(a,b){a.a=b.g+1;return a} +function yNd(a,b){aMd.call(this,a,b)} +function lGd(a,b){kGd.call(this,a,b)} +function N$d(a,b){zNd.call(this,a,b)} +function Whe(a,b){Q2d.call(this,a,b)} +function She(a,b){Phe.call(this,a,b)} +function RRd(a,b){PRd();Zjb(ORd,a,b)} +function sB(a,b){a.q.setTime(Xdb(b))} +function Xz(a){$wnd.clearTimeout(a)} +function cr(a){return Qb(a),new Dl(a)} +function mb(a,b){return dE(a)===dE(b)} +function Mw(a,b){return a.a.a.a.cc(b)} +function qeb(a,b){return zhb(a.a,0,b)} +function SSb(a){return MSb(RD(a,74))} +function Nfb(a){return eE((uFb(a),a))} +function Ofb(a){return eE((uFb(a),a))} +function gD(a){return hD(a.l,a.m,a.h)} +function egb(a,b){return hgb(a.a,b.a)} +function ygb(a,b){return Agb(a.a,b.a)} +function Sfb(a,b){return Qfb(a.a,b.a)} +function qhb(a,b){return a.indexOf(b)} +function nOc(a,b){return a.j[b.p]==2} +function cz(a,b){return a==b?0:a?1:-1} +function AB(a){return a<10?'0'+a:''+a} +function Kdb(a){return typeof a===ive} +function oZb(a){return a==jZb||a==mZb} +function pZb(a){return a==jZb||a==kZb} +function ELb(a,b){return hgb(a.g,b.g)} +function Q4b(a){return Wmb(a.b.b,a,0)} +function Q2b(){J2b.call(this,0,0,0,0)} +function Iub(){ctb.call(this,new gub)} +function Znb(a,b){Wnb(a,0,a.length,b)} +function Eyb(a,b){Rmb(a.a,b);return b} +function Fkc(a,b){lkc();return b.a+=a} +function Hkc(a,b){lkc();return b.a+=a} +function Gkc(a,b){lkc();return b.c+=a} +function ied(a,b){Rmb(a.c,b);return a} +function Ped(a,b){ofd(a.a,b);return a} +function ttb(a){this.a=Itb();this.b=a} +function Ntb(a){this.a=Itb();this.b=a} +function sjd(a){this.a=a.a;this.b=a.b} +function Dl(a){this.a=a;zl.call(this)} +function Gl(a){this.a=a;zl.call(this)} +function Tid(){Uid.call(this,0,0,0,0)} +function vfd(a){return ofd(new ufd,a)} +function Ksd(a){return iyd(RD(a,123))} +function Mvd(a){return a.vh()&&a.wh()} +function Dod(a){return a!=zod&&a!=Aod} +function Dmd(a){return a==ymd||a==zmd} +function Emd(a){return a==Bmd||a==xmd} +function xDc(a){return a==tDc||a==sDc} +function yrc(a,b){return hgb(a.g,b.g)} +function Yfe(a,b){return new Phe(b,a)} +function Zfe(a,b){return new Phe(b,a)} +function lr(a){return Dr(a.b.Kc(),a.a)} +function IXd(a,b){yXd(a,b);zXd(a,a.D)} +function Uxd(a,b,c){Vxd(a,b);Wxd(a,c)} +function zyd(a,b,c){Cyd(a,b);Ayd(a,c)} +function Byd(a,b,c){Dyd(a,b);Eyd(a,c)} +function Gzd(a,b,c){Hzd(a,b);Izd(a,c)} +function Nzd(a,b,c){Ozd(a,b);Pzd(a,c)} +function eh(a,b,c){bh.call(this,a,b,c)} +function zId(a){uId.call(this,a,true)} +function nAb(){dAb.call(this,'Tail',3)} +function iAb(){dAb.call(this,'Head',1)} +function ejb(a){Pib();fjb.call(this,a)} +function A3b(a){J2b.call(this,a,a,a,a)} +function Pmb(a){a.c=$C(jJ,rve,1,0,5,1)} +function yRb(a){a.b&&CRb(a);return a.a} +function zRb(a){a.b&&CRb(a);return a.c} +function mBb(a,b){if(dBb){return}a.b=b} +function YCb(a,b){return a[a.length]=b} +function _Cb(a,b){return a[a.length]=b} +function l5b(a,b){return NGd(b,MCd(a))} +function m5b(a,b){return NGd(b,MCd(a))} +function DDd(a,b){return lp(Co(a.d),b)} +function EDd(a,b){return lp(Co(a.g),b)} +function FDd(a,b){return lp(Co(a.j),b)} +function mGd(a,b){kGd.call(this,a.b,b)} +function s0d(a,b){WGd(tYd(a.a),v0d(b))} +function B4d(a,b){WGd(o4d(a.a),E4d(b))} +function Asd(a,b,c){Byd(c,c.i+a,c.j+b)} +function eFc(a,b,c){bD(a.c[b.g],b.g,c)} +function zVd(a,b,c){RD(a.c,71).Gi(b,c)} +function LMd(a,b,c){bD(a,b,c);return c} +function DJb(a){Umb(a.Sf(),new HJb(a))} +function Gvb(a){return a!=null?tb(a):0} +function aOd(a){return a==null?0:tb(a)} +function iue(a){Vse();Wse.call(this,a)} +function Ug(a){this.a=a;Og.call(this,a)} +function Zy(){Zy=geb;$wnd.Math.log(2)} +function s7d(){s7d=geb;r7d=($Sd(),ZSd)} +function FRc(){FRc=geb;ERc=new Zrb(u3)} +function Hde(){Hde=geb;new Ide;new bnb} +function Ide(){new Tsb;new Tsb;new Tsb} +function yue(){throw Adb(new kib(bMe))} +function Nue(){throw Adb(new kib(bMe))} +function Bue(){throw Adb(new kib(cMe))} +function Que(){throw Adb(new kib(cMe))} +function Gp(a){this.a=a;rf.call(this,a)} +function Np(a){this.a=a;rf.call(this,a)} +function Sq(a,b){tm();this.a=a;this.b=b} +function Jh(a,b){Qb(b);Ih(a).Jc(new jx)} +function _mb(a,b){Ynb(a.c,a.c.length,b)} +function xnb(a){return a.ab?1:0} +function Kgb(a,b){return Ddb(a,b)>0?a:b} +function hD(a,b,c){return {l:a,m:b,h:c}} +function Mvb(a,b){a.a!=null&&_Mc(b,a.a)} +function Lhc(a){Y0b(a,null);Z0b(a,null)} +function xkc(a,b,c){return Zjb(a.g,c,b)} +function bFc(a,b,c){return _Ec(b,c,a.c)} +function jOc(a,b,c){return Zjb(a.k,c,b)} +function pOc(a,b,c){qOc(a,b,c);return c} +function FOc(a,b){dOc();return b.n.b+=a} +function lUb(a){VTb.call(this);this.b=a} +function y2b(a){v2b.call(this);this.a=a} +function kAb(){dAb.call(this,'Range',2)} +function $Fb(a){this.b=a;this.a=new bnb} +function WQb(a){this.b=new gRb;this.a=a} +function Lub(a){a.a=new svb;a.c=new svb} +function nrc(a){a.a=new Tsb;a.d=new Tsb} +function $Sc(a){_Sc(a,null);aTc(a,null)} +function a2d(a,b){return xA(a.a,b,null)} +function Cdd(a,b){return Zjb(a.a,b.a,b)} +function ajd(a){return new rjd(a.a,a.b)} +function Pid(a){return new rjd(a.c,a.d)} +function Qid(a){return new rjd(a.c,a.d)} +function Ake(a,b){return Tfe(a.c,a.b,b)} +function ZD(a,b){return a!=null&&QD(a,b)} +function br(a,b){return Jr(a.Kc(),b)!=-1} +function Hr(a){return a.Ob()?a.Pb():null} +function _p(a){this.b=(yob(),new uqb(a))} +function zke(a){this.a=a;Tsb.call(this)} +function Uhe(){Q2d.call(this,null,null)} +function Yhe(){p3d.call(this,null,null)} +function As(){qs.call(this,'INSTANCE',0)} +function dXb(){_Wb();this.a=new Wed(UP)} +function Hhb(a){return Ihb(a,0,a.length)} +function Rv(a,b){return new ew(a.Kc(),b)} +function $sb(a,b){return a.a.Bc(b)!=null} +function hZd(a,b){sLd(a);a.Gc(RD(b,15))} +function ONd(a,b,c){a.c.bd(b,RD(c,136))} +function eOd(a,b,c){a.c.Ui(b,RD(c,136))} +function eub(a,b){if(a.c){rub(b);qub(b)}} +function oB(a,b){a.q.setHours(b);mB(a,b)} +function vTb(a,b){Zid(b,a.a.a.a,a.a.a.b)} +function tKb(a,b,c,d){bD(a.a[b.g],c.g,d)} +function oKb(a,b,c){return a.a[b.g][c.g]} +function AIc(a,b){return a.e[b.c.p][b.p]} +function TIc(a,b){return a.c[b.c.p][b.p]} +function pJc(a,b){return a.a[b.c.p][b.p]} +function mOc(a,b){return a.j[b.p]=AOc(b)} +function wAb(a,b){return a.a.Bc(b)!=null} +function wXc(a,b){return Kfb(UD(b.a))<=a} +function xXc(a,b){return Kfb(UD(b.a))>=a} +function vhd(a,b){return jhb(a.f,b.Pg())} +function cjd(a,b){return a.a*b.a+a.b*b.b} +function Wsd(a,b){return a.a0?b/(a*a):b*100} +function FUb(a,b){return a>0?b*b/a:b*b*100} +function $5b(a,b){return RD(cub(a.a,b),34)} +function doc(a,b){Mnc();return Rc(a,b.e,b)} +function NCc(a,b,c){GCc();return c.Mg(a,b)} +function L0c(a){B0c();return a.e.a+a.f.a/2} +function N0c(a,b,c){B0c();return c.e.a-a*b} +function V0c(a){B0c();return a.e.b+a.f.b/2} +function X0c(a,b,c){B0c();return c.e.b-a*b} +function _tb(a){a.d=new tub(a);a.e=new Tsb} +function x3c(){this.a=new Tp;this.b=new Tp} +function hmc(a){this.c=a;this.a=1;this.b=1} +function C$b(a){z$b();A$b(this);this.Ff(a)} +function Efd(a,b,c){Afd();a.pf(b)&&c.Cd(a)} +function Red(a,b,c){return Rmb(b,Ted(a,c))} +function Zid(a,b,c){a.a+=b;a.b+=c;return a} +function jjd(a,b,c){a.a*=b;a.b*=c;return a} +function mjd(a,b){a.a=b.a;a.b=b.b;return a} +function fjd(a){a.a=-a.a;a.b=-a.b;return a} +function njd(a,b,c){a.a-=b;a.b-=c;return a} +function Gjd(a){Yub.call(this);zjd(this,a)} +function Dbd(){qs.call(this,'GROW_TREE',0)} +function WRb(){qs.call(this,'POLYOMINO',0)} +function SVd(a,b,c){DVd.call(this,a,b,c,2)} +function r0d(a,b,c){VGd(tYd(a.a),b,v0d(c))} +function e3d(a,b){N2d();Q2d.call(this,a,b)} +function D3d(a,b){j3d();p3d.call(this,a,b)} +function F3d(a,b){j3d();D3d.call(this,a,b)} +function H3d(a,b){j3d();p3d.call(this,a,b)} +function PNd(a,b){return a.c.Fc(RD(b,136))} +function A4d(a,b,c){VGd(o4d(a.a),b,E4d(c))} +function Ard(a){this.c=a;Dyd(a,0);Eyd(a,0)} +function Z8d(a,b){s7d();N8d.call(this,a,b)} +function _8d(a,b){s7d();Z8d.call(this,a,b)} +function b9d(a,b){s7d();Z8d.call(this,a,b)} +function n9d(a,b){s7d();N8d.call(this,a,b)} +function d9d(a,b){s7d();b9d.call(this,a,b)} +function p9d(a,b){s7d();n9d.call(this,a,b)} +function v9d(a,b){s7d();N8d.call(this,a,b)} +function lge(a,b,c){return b.zl(a.e,a.c,c)} +function nge(a,b,c){return b.Al(a.e,a.c,c)} +function Wee(a,b,c){return tfe(Pee(a,b),c)} +function Age(a,b){return Vvd(a.e,RD(b,54))} +function _me(a){return a==null?null:Bqe(a)} +function dne(a){return a==null?null:Iqe(a)} +function gne(a){return a==null?null:jeb(a)} +function hne(a){return a==null?null:jeb(a)} +function TD(a){CFb(a==null||$D(a));return a} +function UD(a){CFb(a==null||_D(a));return a} +function WD(a){CFb(a==null||bE(a));return a} +function lfb(a){if(a.o!=null){return}Bfb(a)} +function lFb(a){if(!a){throw Adb(new _fb)}} +function pFb(a){if(!a){throw Adb(new yeb)}} +function sFb(a){if(!a){throw Adb(new Dvb)}} +function yFb(a){if(!a){throw Adb(new cgb)}} +function zmb(a){if(!a){throw Adb(new Jrb)}} +function jQd(){jQd=geb;iQd=new LQd;new lRd} +function u2c(){u2c=geb;t2c=new jGd('root')} +function d6d(){HWd.call(this);this.Bb|=txe} +function Pg(a,b){this.d=a;Lg(this);this.b=b} +function WCb(a,b){NCb.call(this,a);this.a=b} +function oDb(a,b){NCb.call(this,a);this.a=b} +function bh(a,b,c){lg.call(this,a,b,c,null)} +function fh(a,b,c){lg.call(this,a,b,c,null)} +function Mf(a,b){this.c=a;ne.call(this,a,b)} +function Uf(a,b){this.a=a;Mf.call(this,a,b)} +function wB(a){this.q=new $wnd.Date(Xdb(a))} +function OPb(a){if(a>8){return 0}return a+1} +function iBb(a,b){if(dBb){return}Rmb(a.a,b)} +function P5b(a,b){H5b();return n2b(b.d.i,a)} +function qdc(a,b){Zcc();return new xdc(b,a)} +function HAb(a,b,c){return a.Ne(b,c)<=0?c:b} +function IAb(a,b,c){return a.Ne(b,c)<=0?b:c} +function rgd(a,b){return RD(cub(a.b,b),143)} +function tgd(a,b){return RD(cub(a.c,b),233)} +function amc(a){return RD(Vmb(a.a,a.b),294)} +function Mid(a){return new rjd(a.c,a.d+a.a)} +function Jeb(a){return (uFb(a),a)?1231:1237} +function EPc(a){return dOc(),xDc(RD(a,203))} +function RMb(){RMb=geb;QMb=xsb((Qpd(),Ppd))} +function YQb(a,b){b.a?ZQb(a,b):wAb(a.a,b.b)} +function aJd(a,b,c){++a.j;a.tj();$Gd(a,b,c)} +function $Id(a,b,c){++a.j;a.qj(b,a.Zi(b,c))} +function B2d(a,b,c){var d;d=a.fd(b);d.Rb(c)} +function Bzd(a,b,c){c=xvd(a,b,6,c);return c} +function izd(a,b,c){c=xvd(a,b,3,c);return c} +function KCd(a,b,c){c=xvd(a,b,9,c);return c} +function SKb(a,b){Ivb(b,Pye);a.f=b;return a} +function bOd(a,b){return (b&lve)%a.d.length} +function Bke(a,b,c){return age(a.c,a.b,b,c)} +function ZLd(a,b){this.c=a;ZHd.call(this,b)} +function w0d(a,b){this.a=a;Q_d.call(this,b)} +function F4d(a,b){this.a=a;Q_d.call(this,b)} +function kGd(a,b){jGd.call(this,a);this.a=b} +function U6d(a,b){L6d.call(this,a);this.a=b} +function S9d(a,b){L6d.call(this,a);this.a=b} +function jQb(a){gQb.call(this,0,0);this.f=a} +function _hb(a,b,c){a.a+=Ihb(b,0,c);return a} +function _A(a){!a.a&&(a.a=new jB);return a.a} +function qlb(a,b){var c;c=a.e;a.e=b;return c} +function Clb(a,b){var c;c=b;return !!a.Fe(c)} +function Keb(a,b){Geb();return a==b?0:a?1:-1} +function Ikb(a,b){a.a.bd(a.b,b);++a.b;a.c=-1} +function hg(a){a.b?hg(a.b):a.f.c.zc(a.e,a.d)} +function aub(a){akb(a.e);a.d.b=a.d;a.d.a=a.d} +function VDb(a,b,c){xDb();HEb(a,b.Ve(a.a,c))} +function Xrb(a,b,c){return Wrb(a,RD(b,22),c)} +function WEb(a,b){return cFb(new Array(b),a)} +function Fgb(a){return Ydb(Udb(a,32))^Ydb(a)} +function XD(a){return String.fromCharCode(a)} +function Dz(a){return a==null?null:a.message} +function Rz(a,b,c){return a.apply(b,c);var d} +function Btb(a,b){var c;c=a[Jxe];c.call(a,b)} +function Ctb(a,b){var c;c=a[Jxe];c.call(a,b)} +function O5b(a,b){H5b();return !n2b(b.d.i,a)} +function R2b(a,b,c,d){J2b.call(this,a,b,c,d)} +function TJb(){RJb.call(this);this.a=new pjd} +function v2b(){this.n=new pjd;this.o=new pjd} +function kGb(){this.b=new pjd;this.c=new bnb} +function cUb(){this.a=new bnb;this.b=new bnb} +function kWb(){this.a=new DTb;this.b=new vWb} +function e6b(){this.b=new gub;this.a=new gub} +function jIc(){this.b=new _sb;this.a=new _sb} +function vYc(){this.b=new Tsb;this.a=new Tsb} +function fWc(){this.b=new TVc;this.a=new IVc} +function Yhc(){this.a=new yqc;this.b=new Sqc} +function lNc(){this.a=new bnb;this.d=new bnb} +function RJb(){this.n=new z3b;this.i=new Tid} +function hq(a){this.a=(dk(a,iwe),new cnb(a))} +function oq(a){this.a=(dk(a,iwe),new cnb(a))} +function tLd(a){return a<100?null:new gLd(a)} +function Lac(a,b){return a.n.a=(uFb(b),b)+10} +function Mac(a,b){return a.n.a=(uFb(b),b)+10} +function DYd(a,b){return b==a||PHd(sYd(b),a)} +function nae(a,b){return Zjb(a.a,b,'')==null} +function Hee(a,b){var c;c=b.qi(a.a);return c} +function $id(a,b){a.a+=b.a;a.b+=b.b;return a} +function ojd(a,b){a.a-=b.a;a.b-=b.b;return a} +function sfd(a){aFb(a.j.c,0);a.a=-1;return a} +function rCd(a,b,c){c=xvd(a,b,11,c);return c} +function SDd(a,b,c){c!=null&&Kzd(b,uEd(a,c))} +function TDd(a,b,c){c!=null&&Lzd(b,uEd(a,c))} +function G5d(a,b,c,d){C5d.call(this,a,b,c,d)} +function oie(a,b,c,d){C5d.call(this,a,b,c,d)} +function sie(a,b,c,d){oie.call(this,a,b,c,d)} +function Nie(a,b,c,d){Iie.call(this,a,b,c,d)} +function Pie(a,b,c,d){Iie.call(this,a,b,c,d)} +function Vie(a,b,c,d){Iie.call(this,a,b,c,d)} +function Tie(a,b,c,d){Pie.call(this,a,b,c,d)} +function $ie(a,b,c,d){Pie.call(this,a,b,c,d)} +function Yie(a,b,c,d){Vie.call(this,a,b,c,d)} +function bje(a,b,c,d){$ie.call(this,a,b,c,d)} +function Dje(a,b,c,d){wje.call(this,a,b,c,d)} +function aMd(a,b){veb.call(this,HJe+a+NIe+b)} +function Hje(a,b){return a.jk().wi().ri(a,b)} +function Ije(a,b){return a.jk().wi().ti(a,b)} +function Lfb(a,b){return uFb(a),dE(a)===dE(b)} +function lhb(a,b){return uFb(a),dE(a)===dE(b)} +function mEb(a,b){return a.b.Bd(new pEb(a,b))} +function sEb(a,b){return a.b.Bd(new vEb(a,b))} +function yEb(a,b){return a.b.Bd(new BEb(a,b))} +function Bk(a,b){return a.e=RD(a.d.Kb(b),159)} +function uhb(a,b,c){return a.lastIndexOf(b,c)} +function wWb(a,b,c){return Qfb(a[b.a],a[c.a])} +function TWb(a,b){return pQb(b,(yCc(),gAc),a)} +function Lpc(a,b){return hgb(b.a.d.p,a.a.d.p)} +function Kpc(a,b){return hgb(a.a.d.p,b.a.d.p)} +function zTc(a,b){return Qfb(a.c-a.s,b.c-b.s)} +function qWc(a,b){return Qfb(a.b.e.a,b.b.e.a)} +function sWc(a,b){return Qfb(a.c.e.a,b.c.e.a)} +function $2b(a){return !a.c?-1:Wmb(a.c.a,a,0)} +function Cod(a){return a==vod||a==xod||a==wod} +function CMd(a,b){this.c=a;nMd.call(this,a,b)} +function fq(a,b,c){this.a=a;qc.call(this,b,c)} +function YDb(a){this.c=a;xxb.call(this,Sve,0)} +function rk(a,b,c){this.c=b;this.b=c;this.a=a} +function DMc(a){dMc();this.d=a;this.a=new wmb} +function ho(a){_l();this.a=(yob(),new Lqb(a))} +function Xmc(a,b){Dmd(a.f)?Ymc(a,b):Zmc(a,b)} +function Lxb(a,b){Mxb.call(this,a,a.length,b)} +function nBb(a,b){if(dBb){return}!!b&&(a.d=b)} +function ZNd(a,b){return ZD(b,15)&&_Gd(a.c,b)} +function AVd(a,b,c){return RD(a.c,71).Wk(b,c)} +function BVd(a,b,c){return RD(a.c,71).Xk(b,c)} +function mge(a,b,c){return lge(a,RD(b,343),c)} +function oge(a,b,c){return nge(a,RD(b,343),c)} +function Ige(a,b,c){return Hge(a,RD(b,343),c)} +function Kge(a,b,c){return Jge(a,RD(b,343),c)} +function Fn(a,b){return b==null?null:Xv(a.b,b)} +function Qeb(a){return _D(a)?(uFb(a),a):a.ue()} +function Rfb(a){return !isNaN(a)&&!isFinite(a)} +function Zub(a){Lub(this);Xub(this);ye(this,a)} +function dnb(a){Pmb(this);YEb(this.c,0,a.Pc())} +function Fsb(a,b,c){this.a=a;this.b=b;this.c=c} +function Vtb(a,b,c){this.a=a;this.b=b;this.c=c} +function hvb(a,b,c){this.d=a;this.b=c;this.a=b} +function aBb(a){this.a=a;gib();Hdb(Date.now())} +function wzb(a){Ckb(a.a);Yyb(a.c,a.b);a.b=null} +function wvb(){wvb=geb;uvb=new xvb;vvb=new zvb} +function KMd(){KMd=geb;JMd=$C(jJ,rve,1,0,5,1)} +function TTd(){TTd=geb;STd=$C(jJ,rve,1,0,5,1)} +function yUd(){yUd=geb;xUd=$C(jJ,rve,1,0,5,1)} +function _l(){_l=geb;new im((yob(),yob(),vob))} +function gAb(a){cAb();return ws((qAb(),pAb),a)} +function zBb(a){xBb();return ws((CBb(),BBb),a)} +function FHb(a){DHb();return ws((IHb(),HHb),a)} +function NHb(a){LHb();return ws((QHb(),PHb),a)} +function kIb(a){iIb();return ws((nIb(),mIb),a)} +function _Jb(a){ZJb();return ws((cKb(),bKb),a)} +function GKb(a){EKb();return ws((JKb(),IKb),a)} +function xLb(a){vLb();return ws((ALb(),zLb),a)} +function mMb(a){hMb();return ws((pMb(),oMb),a)} +function oOb(a){mOb();return ws((rOb(),qOb),a)} +function KPb(a){IPb();return ws((NPb(),MPb),a)} +function KRb(a){IRb();return ws((NRb(),MRb),a)} +function XRb(a){VRb();return ws(($Rb(),ZRb),a)} +function VUb(a){TUb();return ws((YUb(),XUb),a)} +function CWb(a){AWb();return ws((FWb(),EWb),a)} +function uXb(a){sXb();return ws((xXb(),wXb),a)} +function tZb(a){nZb();return ws((wZb(),vZb),a)} +function W$b(a){U$b();return ws((Z$b(),Y$b),a)} +function Mb(a,b){if(!a){throw Adb(new agb(b))}} +function Vb(a){if(!a){throw Adb(new dgb(tve))}} +function rFb(a,b){if(a!=b){throw Adb(new Jrb)}} +function KQb(a,b,c){this.a=a;this.b=b;this.c=c} +function lRb(a,b,c){this.a=a;this.b=b;this.c=c} +function h7b(a,b,c){this.a=a;this.b=b;this.c=c} +function J0b(a,b,c){this.b=a;this.a=b;this.c=c} +function dNb(a,b,c){this.b=a;this.c=b;this.a=c} +function oac(a,b,c){this.a=a;this.b=b;this.c=c} +function F1b(a,b,c){this.e=b;this.b=a;this.d=c} +function Ecc(a,b,c){this.b=a;this.a=b;this.c=c} +function UDb(a,b,c){xDb();a.a.Yd(b,c);return b} +function CJb(a){var b;b=new BJb;b.e=a;return b} +function _Nb(a){var b;b=new YNb;b.b=a;return b} +function U9b(){U9b=geb;S9b=new bac;T9b=new eac} +function Rec(){Rec=geb;Qec=new efc;Pec=new jfc} +function lkc(){lkc=geb;jkc=new Mkc;kkc=new Okc} +function loc(a){joc();return ws((ooc(),noc),a)} +function kcc(a){hcc();return ws((ncc(),mcc),a)} +function yec(a){vec();return ws((Bec(),Aec),a)} +function gnc(a){enc();return ws((jnc(),inc),a)} +function Enc(a){Bnc();return ws((Hnc(),Gnc),a)} +function gpc(a){epc();return ws((jpc(),ipc),a)} +function dtc(a){btc();return ws((gtc(),ftc),a)} +function ltc(a){jtc();return ws((otc(),ntc),a)} +function xtc(a){stc();return ws((Atc(),ztc),a)} +function Gtc(a){Etc();return ws((Jtc(),Itc),a)} +function Utc(a){Ptc();return ws((Xtc(),Wtc),a)} +function auc(a){$tc();return ws((duc(),cuc),a)} +function avc(a){$uc();return ws((dvc(),cvc),a)} +function qvc(a){ovc();return ws((tvc(),svc),a)} +function zvc(a){xvc();return ws((Cvc(),Bvc),a)} +function Ivc(a){Gvc();return ws((Lvc(),Kvc),a)} +function Qvc(a){Ovc();return ws((Tvc(),Svc),a)} +function Quc(a){Ouc();return ws((Tuc(),Suc),a)} +function juc(a){huc();return ws((muc(),luc),a)} +function wuc(a){tuc();return ws((zuc(),yuc),a)} +function Euc(a){Cuc();return ws((Huc(),Guc),a)} +function exc(a){cxc();return ws((hxc(),gxc),a)} +function eDc(a){_Cc();return ws((hDc(),gDc),a)} +function oDc(a){lDc();return ws((rDc(),qDc),a)} +function ADc(a){wDc();return ws((DDc(),CDc),a)} +function ODc(a){JDc();return ws((RDc(),QDc),a)} +function cEc(a){aEc();return ws((fEc(),eEc),a)} +function mEc(a){kEc();return ws((pEc(),oEc),a)} +function uEc(a){sEc();return ws((xEc(),wEc),a)} +function DEc(a){BEc();return ws((GEc(),FEc),a)} +function MEc(a){KEc();return ws((PEc(),OEc),a)} +function VEc(a){TEc();return ws((YEc(),XEc),a)} +function nFc(a){lFc();return ws((qFc(),pFc),a)} +function wFc(a){uFc();return ws((zFc(),yFc),a)} +function FFc(a){DFc();return ws((IFc(),HFc),a)} +function TKc(a){RKc();return ws((WKc(),VKc),a)} +function uNc(a){sNc();return ws((xNc(),wNc),a)} +function yQc(a){wQc();return ws((BQc(),AQc),a)} +function GQc(a){EQc();return ws((JQc(),IQc),a)} +function hTc(a){fTc();return ws((kTc(),jTc),a)} +function fVc(a){dVc();return ws((iVc(),hVc),a)} +function bWc(a){YVc();return ws((eWc(),dWc),a)} +function ZYc(a){WYc();return ws((aZc(),_Yc),a)} +function NZc(a){LZc();return ws((QZc(),PZc),a)} +function u_c(a){s_c();return ws((x_c(),w_c),a)} +function C_c(a){A_c();return ws((F_c(),E_c),a)} +function C2c(a){x2c();return ws((F2c(),E2c),a)} +function j3c(a){g3c();return ws((m3c(),l3c),a)} +function j4c(a){g4c();return ws((m4c(),l4c),a)} +function _3c(a){Y3c();return ws((c4c(),b4c),a)} +function m5c(a){j5c();return ws((p5c(),o5c),a)} +function w5c(a){t5c();return ws((z5c(),y5c),a)} +function h6c(a){f6c();return ws((k6c(),j6c),a)} +function C6c(a){z6c();return ws((F6c(),E6c),a)} +function b7c(a){_6c();return ws((e7c(),d7c),a)} +function E8c(a){z8c();return ws((H8c(),G8c),a)} +function R8b(a){P8b();return ws((U8b(),T8b),a)} +function t3b(a){r3b();return ws((w3b(),v3b),a)} +function g9c(a){b9c();return ws((j9c(),i9c),a)} +function G9c(a){B9c();return ws((J9c(),I9c),a)} +function uad(a){sad();return ws((xad(),wad),a)} +function xbd(a){sbd();return ws((Abd(),zbd),a)} +function ibd(a){gbd();return ws((lbd(),kbd),a)} +function Gbd(a){Cbd();return ws((Jbd(),Ibd),a)} +function Obd(a){Mbd();return ws((Rbd(),Qbd),a)} +function Zbd(a){Xbd();return ws((acd(),_bd),a)} +function fdd(a){_cd();return ws((idd(),hdd),a)} +function qdd(a){ldd();return ws((tdd(),sdd),a)} +function $hd(a){Yhd();return ws((bid(),aid),a)} +function mid(a){kid();return ws((pid(),oid),a)} +function Tjd(a){Rjd();return ws((Wjd(),Vjd),a)} +function wkd(a){ukd();return ws((zkd(),ykd),a)} +function Hmd(a){Cmd();return ws((Kmd(),Jmd),a)} +function Qmd(a){Omd();return ws((Tmd(),Smd),a)} +function $md(a){Ymd();return ws((bnd(),and),a)} +function knd(a){ind();return ws((nnd(),mnd),a)} +function Hnd(a){Fnd();return ws((Knd(),Jnd),a)} +function Snd(a){Pnd();return ws((Vnd(),Und),a)} +function god(a){dod();return ws((jod(),iod),a)} +function rod(a){pod();return ws((uod(),tod),a)} +function Fod(a){Bod();return ws((Iod(),Hod),a)} +function Tod(a){Pod();return ws((Wod(),Vod),a)} +function wpd(a){qpd();return ws((zpd(),ypd),a)} +function Spd(a){Qpd();return ws((Vpd(),Upd),a)} +function fqd(a){dqd();return ws((iqd(),hqd),a)} +function oqd(a){mqd();return ws((rqd(),qqd),a)} +function zsc(a,b){return (uFb(a),a)+(uFb(b),b)} +function wqd(a){uqd();return ws((Eqd(),Dqd),a)} +function Ird(a){Grd();return ws((Lrd(),Krd),a)} +function vtd(a){ttd();return ws((ytd(),xtd),a)} +function dMc(){dMc=geb;bMc=(qpd(),ppd);cMc=Xod} +function uqd(){uqd=geb;sqd=new zqd;tqd=new Bqd} +function wJc(a){!a.e&&(a.e=new bnb);return a.e} +function BTc(a,b){this.c=a;this.a=b;this.b=b-a} +function g8c(a,b,c){this.a=a;this.b=b;this.c=c} +function gud(a,b,c){this.a=a;this.b=b;this.c=c} +function Wdd(a,b,c){this.a=a;this.b=b;this.c=c} +function ced(a,b,c){this.a=a;this.b=b;this.c=c} +function pFd(a,b,c){this.a=a;this.b=b;this.c=c} +function ZPd(a,b,c){this.a=a;this.b=b;this.c=c} +function g7d(a,b,c){this.e=a;this.a=b;this.c=c} +function K7d(a,b,c){s7d();C7d.call(this,a,b,c)} +function f9d(a,b,c){s7d();O8d.call(this,a,b,c)} +function r9d(a,b,c){s7d();O8d.call(this,a,b,c)} +function x9d(a,b,c){s7d();O8d.call(this,a,b,c)} +function h9d(a,b,c){s7d();f9d.call(this,a,b,c)} +function j9d(a,b,c){s7d();f9d.call(this,a,b,c)} +function l9d(a,b,c){s7d();j9d.call(this,a,b,c)} +function t9d(a,b,c){s7d();r9d.call(this,a,b,c)} +function z9d(a,b,c){s7d();x9d.call(this,a,b,c)} +function S2b(a){J2b.call(this,a.d,a.c,a.a,a.b)} +function B3b(a){J2b.call(this,a.d,a.c,a.a,a.b)} +function Og(a){this.d=a;Lg(this);this.b=ed(a.d)} +function cGd(a){aGd();return ws((fGd(),eGd),a)} +function gk(a,b){Qb(a);Qb(b);return new hk(a,b)} +function dr(a,b){Qb(a);Qb(b);return new mr(a,b)} +function hr(a,b){Qb(a);Qb(b);return new sr(a,b)} +function Dr(a,b){Qb(a);Qb(b);return new Rr(a,b)} +function Uub(a){sFb(a.b!=0);return Wub(a,a.a.a)} +function Vub(a){sFb(a.b!=0);return Wub(a,a.c.b)} +function q$d(a){!a.c&&(a.c=new X9d);return a.c} +function cv(a){var b;b=new bnb;xr(b,a);return b} +function Vx(a){var b;b=new _sb;xr(b,a);return b} +function Yx(a){var b;b=new xAb;_q(b,a);return b} +function gv(a){var b;b=new Yub;_q(b,a);return b} +function RD(a,b){CFb(a==null||QD(a,b));return a} +function Mxb(a,b,c){Axb.call(this,b,c);this.a=a} +function kB(a,b){this.c=a;this.b=b;this.a=false} +function hCb(){this.a=';,;';this.b='';this.c=''} +function $Cb(a,b,c){this.b=a;pxb.call(this,b,c)} +function uub(a,b,c){this.c=a;xlb.call(this,b,c)} +function fZb(a,b,c){eZb.call(this,a,b);this.b=c} +function YEb(a,b,c){VEb(c,0,a,b,c.length,false)} +function JYb(a,b,c,d,e){a.b=b;a.c=c;a.d=d;a.a=e} +function D2b(a,b,c,d,e){a.d=b;a.c=c;a.a=d;a.b=e} +function XDb(a,b){if(b){a.b=b;a.a=(LCb(b),b.a)}} +function mFb(a,b){if(!a){throw Adb(new agb(b))}} +function zFb(a,b){if(!a){throw Adb(new dgb(b))}} +function qFb(a,b){if(!a){throw Adb(new zeb(b))}} +function zqc(a,b){mqc();return hgb(a.d.p,b.d.p)} +function T0c(a,b){B0c();return Qfb(a.e.b,b.e.b)} +function U0c(a,b){B0c();return Qfb(a.e.a,b.e.a)} +function Xoc(a,b){return hgb(N3b(a.d),N3b(b.d))} +function Izb(a,b){return !!b&&Jzb(a,b.d)?b:null} +function $lc(a,b){return b==(qpd(),ppd)?a.c:a.d} +function Qdb(a){return Edb(yD(Kdb(a)?Wdb(a):a))} +function Nid(a){return new rjd(a.c+a.b,a.d+a.a)} +function GSd(a){return a!=null&&!mSd(a,aSd,bSd)} +function DSd(a,b){return (JSd(a)<<4|JSd(b))&Bwe} +function Rid(a,b,c,d,e){a.c=b;a.d=c;a.b=d;a.a=e} +function y8b(a){var b,c;b=a.b;c=a.c;a.b=c;a.c=b} +function B8b(a){var b,c;c=a.d;b=a.a;a.d=b;a.a=c} +function u6d(a,b){var c;c=a.c;t6d(a,b);return c} +function Nqd(a,b){b<0?(a.g=-1):(a.g=b);return a} +function kjd(a,b){gjd(a);a.a*=b;a.b*=b;return a} +function hrc(a,b,c){grc.call(this,b,c);this.d=a} +function PZd(a,b,c){kZd.call(this,a,b);this.c=c} +function Kfe(a,b,c){kZd.call(this,a,b);this.c=c} +function zUd(a){yUd();kUd.call(this);this.ci(a)} +function Yee(){ree();Zee.call(this,(YSd(),XSd))} +function Yse(a){Vse();++Use;return new Hte(0,a)} +function uke(){uke=geb;tke=(yob(),new mpb(eLe))} +function ux(){ux=geb;new wx((kl(),jl),(Wk(),Vk))} +function ugb(){ugb=geb;tgb=$C(bJ,Nve,17,256,0,1)} +function zUb(){this.b=Kfb(UD(iGd((yVb(),sVb))))} +function Pq(a){this.b=a;this.a=gn(this.b.a).Od()} +function mr(a,b){this.b=a;this.a=b;zl.call(this)} +function sr(a,b){this.a=a;this.b=b;zl.call(this)} +function s_d(a,b,c){this.a=a;N$d.call(this,b,c)} +function n_d(a,b,c){this.a=a;N$d.call(this,b,c)} +function sDd(a,b,c){var d;d=new OC(c);sC(a,b,d)} +function _Eb(a,b,c){var d;d=a[b];a[b]=c;return d} +function UEb(a){var b;b=a.slice();return dD(b,a)} +function SJb(a){var b;b=a.n;return a.a.b+b.d+b.a} +function PKb(a){var b;b=a.n;return a.e.b+b.d+b.a} +function QKb(a){var b;b=a.n;return a.e.a+b.b+b.c} +function rub(a){a.a.b=a.b;a.b.a=a.a;a.a=a.b=null} +function Mub(a,b){Pub(a,b,a.c.b,a.c);return true} +function w2b(a){if(a.a){return a.a}return R0b(a)} +function NSb(a){HSb();return JGd(a)==vCd(LGd(a))} +function OSb(a){HSb();return LGd(a)==vCd(JGd(a))} +function l_b(a,b){return k_b(a,new eZb(b.a,b.b))} +function xn(a,b){return fn(),ck(a,b),new zy(a,b)} +function fmc(a,b){return a.c=b){throw Adb(new web)}} +function JDb(a,b){return MDb(a,(uFb(b),new JAb(b)))} +function KDb(a,b){return MDb(a,(uFb(b),new LAb(b)))} +function prc(a,b,c){return qrc(a,RD(b,12),RD(c,12))} +function q4b(a){return J3b(),RD(a,12).g.c.length!=0} +function v4b(a){return J3b(),RD(a,12).e.c.length!=0} +function sdc(a,b){Zcc();return Qfb(b.a.o.a,a.a.o.a)} +function d_d(a,b){(b.Bb&QHe)!=0&&!a.a.o&&(a.a.o=b)} +function T3c(a,b){b.Ug("General 'Rotator",1);S3c(a)} +function MCc(a,b,c){b.qf(c,Kfb(UD(Wjb(a.b,c)))*a.a)} +function yid(a,b,c){tid();return xid(a,b)&&xid(a,c)} +function Rod(a){Pod();return !a.Hc(Lod)&&!a.Hc(Nod)} +function Nrc(a){if(a.e){return Src(a.e)}return null} +function Zdb(a){if(Kdb(a)){return ''+a}return GD(a)} +function XNc(a){var b;b=a;while(b.f){b=b.f}return b} +function HBb(a,b,c){bD(b,0,tCb(b[0],c[0]));return b} +function Gpc(a,b,c,d){var e;e=a.i;e.i=b;e.a=c;e.b=d} +function C5d(a,b,c,d){XZd.call(this,a,b,c);this.b=d} +function N3d(a,b,c,d,e){O3d.call(this,a,b,c,d,e,-1)} +function b4d(a,b,c,d,e){c4d.call(this,a,b,c,d,e,-1)} +function Iie(a,b,c,d){PZd.call(this,a,b,c);this.b=d} +function Xde(a){uId.call(this,a,false);this.a=false} +function Bqd(){vqd.call(this,'LOOKAHEAD_LAYOUT',1)} +function nNd(a){this.b=a;mMd.call(this,a);mNd(this)} +function vNd(a){this.b=a;BMd.call(this,a);uNd(this)} +function J5d(a,b,c){this.a=a;G5d.call(this,b,c,5,6)} +function wje(a,b,c,d){this.b=a;XZd.call(this,b,c,d)} +function Tj(a,b){this.b=a;Aj.call(this,a.b);this.a=b} +function NLc(a){this.a=LLc(a.a);this.b=new dnb(a.b)} +function Fx(a,b){tm();Ex.call(this,a,Pm(new mob(b)))} +function _se(a,b){Vse();++Use;return new aue(a,b,0)} +function bte(a,b){Vse();++Use;return new aue(6,a,b)} +function Ztb(a,b){uFb(b);while(a.Ob()){b.Cd(a.Pb())}} +function Ujb(a,b){return bE(b)?Yjb(a,b):!!qtb(a.f,b)} +function O_d(a,b){return b.Vh()?Vvd(a.b,RD(b,54)):b} +function whb(a,b){return lhb(a.substr(0,b.length),b)} +function Fl(a){return new is(new Il(a.a.length,a.a))} +function Oid(a){return new rjd(a.c+a.b/2,a.d+a.a/2)} +function yD(a){return hD(~a.l&dxe,~a.m&dxe,~a.h&exe)} +function cE(a){return typeof a===gve||typeof a===kve} +function akb(a){a.f=new ttb(a);a.i=new Ntb(a);++a.g} +function Klb(a){if(!a){throw Adb(new Dvb)}return a.d} +function smb(a){var b;b=omb(a);sFb(b!=null);return b} +function tmb(a){var b;b=pmb(a);sFb(b!=null);return b} +function tv(a,b){var c;c=a.a.gc();Sb(b,c);return c-b} +function Ysb(a,b){var c;c=a.a.zc(b,a);return c==null} +function rAb(a,b){return a.a.zc(b,(Geb(),Eeb))==null} +function _nb(a){return new SDb(null,$nb(a,a.length))} +function yPb(a,b,c){return zPb(a,RD(b,42),RD(c,176))} +function Wrb(a,b,c){zsb(a.a,b);return _Eb(a.b,b.g,c)} +function fyb(a,b,c){lyb(c,a.a.c.length);$mb(a.a,c,b)} +function Knb(a,b,c,d){nFb(b,c,a.length);Onb(a,b,c,d)} +function Onb(a,b,c,d){var e;for(e=b;e0?$wnd.Math.log(a/b):-100} +function Agb(a,b){return Ddb(a,b)<0?-1:Ddb(a,b)>0?1:0} +function Dge(a,b){hZd(a,ZD(b,160)?b:RD(b,2036).Rl())} +function vFb(a,b){if(a==null){throw Adb(new Ogb(b))}} +function $nb(a,b){return jxb(b,a.length),new Gxb(a,b)} +function hsc(a,b){if(!b){return false}return ye(a,b)} +function Gs(){zs();return cD(WC(RG,1),jwe,549,0,[ys])} +function Xib(a){return a.e==0?a:new cjb(-a.e,a.d,a.a)} +function $Nb(a,b){return Qfb(a.c.c+a.c.b,b.c.c+b.c.b)} +function cvb(a,b){Pub(a.d,b,a.b.b,a.b);++a.a;a.c=null} +function JCb(a,b){!a.c?Rmb(a.b,b):JCb(a.c,b);return a} +function KB(a,b,c){var d;d=JB(a,b);LB(a,b,c);return d} +function Rnb(a,b,c){var d;for(d=0;d=a.g} +function bD(a,b,c){pFb(c==null||VC(a,c));return a[b]=c} +function yhb(a,b){BFb(b,a.length+1);return a.substr(b)} +function yxb(a,b){uFb(b);while(a.c=a){return new rDb}return iDb(a-1)} +function Y2b(a){if(!a.a&&!!a.c){return a.c.b}return a.a} +function Zx(a){if(ZD(a,616)){return a}return new sy(a)} +function LCb(a){if(!a.c){MCb(a);a.d=true}else{LCb(a.c)}} +function ICb(a){if(!a.c){a.d=true;KCb(a)}else{a.c.$e()}} +function bHb(a){a.b=false;a.c=false;a.d=false;a.a=false} +function uMc(a){var b,c;b=a.c.i.c;c=a.d.i.c;return b==c} +function _vd(a,b){var c;c=a.Ih(b);c>=0?a.ki(c):Tvd(a,b)} +function mtd(a,b){a.c<0||a.b.b0){a=a<<1|(a<0?1:0)}return a} +function BGc(a,b){var c;c=new R4b(a);ZEb(b.c,c);return c} +function FMb(a,b){a.u.Hc((Pod(),Lod))&&DMb(a,b);HMb(a,b)} +function Fvb(a,b){return dE(a)===dE(b)||a!=null&&pb(a,b)} +function Vrb(a,b){return Bsb(a.a,b)?a.b[RD(b,22).g]:null} +function YRb(){VRb();return cD(WC($O,1),jwe,489,0,[URb])} +function ybd(){sbd();return cD(WC(M1,1),jwe,490,0,[rbd])} +function Hbd(){Cbd();return cD(WC(N1,1),jwe,558,0,[Bbd])} +function gdd(){_cd();return cD(WC(V1,1),jwe,539,0,[$cd])} +function iyd(a){!a.n&&(a.n=new C5d(I4,a,1,7));return a.n} +function wCd(a){!a.c&&(a.c=new C5d(K4,a,9,9));return a.c} +function mzd(a){!a.c&&(a.c=new Yie(E4,a,5,8));return a.c} +function lzd(a){!a.b&&(a.b=new Yie(E4,a,4,7));return a.b} +function Sed(a){a.j.c.length=0;Ae(a.c);sfd(a.a);return a} +function Afe(a){a.e==fLe&&Gfe(a,Aee(a.g,a.b));return a.e} +function Bfe(a){a.f==fLe&&Hfe(a,Bee(a.g,a.b));return a.f} +function xBd(a,b,c,d){wBd(a,b,c,false);j1d(a,d);return a} +function oNd(a,b){this.b=a;nMd.call(this,a,b);mNd(this)} +function wNd(a,b){this.b=a;CMd.call(this,a,b);uNd(this)} +function Kmb(a){this.d=a;this.a=this.d.b;this.b=this.d.c} +function oy(a,b){this.b=a;this.c=b;this.a=new Osb(this.b)} +function ihb(a,b){BFb(b,a.length);return a.charCodeAt(b)} +function NDd(a,b){CGd(a,Kfb(vDd(b,'x')),Kfb(vDd(b,'y')))} +function $Dd(a,b){CGd(a,Kfb(vDd(b,'x')),Kfb(vDd(b,'y')))} +function CDb(a,b){MCb(a);return new SDb(a,new hEb(b,a.a))} +function GDb(a,b){MCb(a);return new SDb(a,new zEb(b,a.a))} +function HDb(a,b){MCb(a);return new WCb(a,new nEb(b,a.a))} +function IDb(a,b){MCb(a);return new oDb(a,new tEb(b,a.a))} +function Ty(a,b){return new Ry(RD(Qb(a),50),RD(Qb(b),50))} +function nHb(a,b){return Qfb(a.d.c+a.d.b/2,b.d.c+b.d.b/2)} +function gTb(a,b,c){c.a?Eyd(a,b.b-a.f/2):Dyd(a,b.a-a.g/2)} +function WYb(a,b){return Qfb(a.g.c+a.g.b/2,b.g.c+b.g.b/2)} +function RZb(a,b){NZb();return Qfb((uFb(a),a),(uFb(b),b))} +function wSd(a){return a!=null&&tpb(eSd,a.toLowerCase())} +function Ae(a){var b;for(b=a.Kc();b.Ob();){b.Pb();b.Qb()}} +function Ih(a){var b;b=a.b;!b&&(a.b=b=new Xh(a));return b} +function R0b(a){var b;b=Z5b(a);if(b){return b}return null} +function BSb(a,b){var c,d;c=a/b;d=eE(c);c>d&&++d;return d} +function Ck(a,b,c){var d;d=RD(a.d.Kb(c),159);!!d&&d.Nb(b)} +function Vhc(a,b,c){tqc(a.a,c);Jpc(c);Kqc(a.b,c);bqc(b,c)} +function oNc(a,b,c,d){this.a=a;this.c=b;this.b=c;this.d=d} +function ROc(a,b,c,d){this.c=a;this.b=b;this.a=c;this.d=d} +function uPc(a,b,c,d){this.c=a;this.b=b;this.d=c;this.a=d} +function Uid(a,b,c,d){this.c=a;this.d=b;this.b=c;this.a=d} +function GTc(a,b,c,d){this.a=a;this.d=b;this.c=c;this.b=d} +function t1b(a,b,c,d){this.a=a;this.e=b;this.d=c;this.c=d} +function $td(a,b,c,d){this.a=a;this.c=b;this.d=c;this.b=d} +function ehb(a,b,c){this.a=ywe;this.d=a;this.b=b;this.c=c} +function fpc(a,b,c,d){qs.call(this,a,b);this.a=c;this.b=d} +function Uwb(a,b){this.d=(uFb(a),a);this.a=16449;this.c=b} +function CIc(a){this.a=new bnb;this.e=$C(kE,Nve,53,a,0,2)} +function ELc(a){a.Ug('No crossing minimization',1);a.Vg()} +function Evb(){yz.call(this,'There is no more element.')} +function OEd(a,b,c,d){this.a=a;this.b=b;this.c=c;this.d=d} +function PEd(a,b,c,d){this.a=a;this.b=b;this.c=c;this.d=d} +function h7d(a,b,c,d){this.e=a;this.a=b;this.c=c;this.d=d} +function x7d(a,b,c,d){this.a=a;this.c=b;this.d=c;this.b=d} +function C8d(a,b,c,d){s7d();M7d.call(this,b,c,d);this.a=a} +function J8d(a,b,c,d){s7d();M7d.call(this,b,c,d);this.a=a} +function lwd(a,b,c){var d,e;d=oSd(a);e=b.ti(c,d);return e} +function lBd(a){var b,c;c=(b=new s2d,b);l2d(c,a);return c} +function mBd(a){var b,c;c=(b=new s2d,b);p2d(c,a);return c} +function HDd(a,b){var c;c=Wjb(a.f,b);wEd(b,c);return null} +function uCd(a){!a.b&&(a.b=new C5d(G4,a,12,3));return a.b} +function VD(a){CFb(a==null||cE(a)&&!(a.Tm===keb));return a} +function gz(a){if(a.n){a.e!==rwe&&a.je();a.j=null}return a} +function Ng(a){ig(a.d);if(a.d.d!=a.c){throw Adb(new Jrb)}} +function Bkb(a){sFb(a.b0&&wPd(this)} +function Vg(a,b){this.a=a;Pg.call(this,a,RD(a.d,15).fd(b))} +function lrd(a,b){return Qfb(urd(a)*trd(a),urd(b)*trd(b))} +function mrd(a,b){return Qfb(urd(a)*trd(a),urd(b)*trd(b))} +function n5b(a){return ozd(a)&&Heb(TD(Gxd(a,(yCc(),OAc))))} +function Sfc(a,b){return Rc(a,RD(mQb(b,(yCc(),tBc)),17),b)} +function lic(a,b){RD(mQb(a,(Ywc(),qwc)),15).Fc(b);return b} +function C2b(a,b){a.b=b.b;a.c=b.c;a.d=b.d;a.a=b.a;return a} +function cEb(a,b,c,d){this.b=a;this.c=d;xxb.call(this,b,c)} +function Ulc(a,b,c){a.i=0;a.e=0;if(b==c){return}Qlc(a,b,c)} +function Vlc(a,b,c){a.i=0;a.e=0;if(b==c){return}Rlc(a,b,c)} +function akc(a,b,c){Wjc();return _Gb(RD(Wjb(a.e,b),529),c)} +function nd(a){var b;return b=a.f,!b?(a.f=new ne(a,a.c)):b} +function nTc(a,b){return VTc(a.j,b.s,b.c)+VTc(b.e,a.s,a.c)} +function Rrc(a,b){if(!!a.e&&!a.e.a){Prc(a.e,b);Rrc(a.e,b)}} +function Qrc(a,b){if(!!a.d&&!a.d.a){Prc(a.d,b);Qrc(a.d,b)}} +function krd(a,b){return -Qfb(urd(a)*trd(a),urd(b)*trd(b))} +function gtd(a){return RD(a.ld(),149).Pg()+':'+jeb(a.md())} +function EBd(){BBd(this,new yAd);this.wb=(lTd(),kTd);jTd()} +function G7b(a){this.b=new bnb;Tmb(this.b,this.b);this.a=a} +function WWc(a,b){new Yub;this.a=new Ejd;this.b=a;this.c=b} +function urb(){urb=geb;rrb=new wrb;srb=new wrb;trb=new Brb} +function yob(){yob=geb;vob=new Job;wob=new apb;xob=new ipb} +function FGb(){FGb=geb;CGb=new AGb;EGb=new fHb;DGb=new YGb} +function HSb(){HSb=geb;GSb=new bnb;FSb=new Tsb;ESb=new bnb} +function Rb(a,b){if(a==null){throw Adb(new Ogb(b))}return a} +function tCd(a){!a.a&&(a.a=new C5d(J4,a,10,11));return a.a} +function uYd(a){!a.q&&(a.q=new C5d(s7,a,11,10));return a.q} +function xYd(a){!a.s&&(a.s=new C5d(y7,a,21,17));return a.s} +function er(a){Qb(a);return Er(new is(Mr(a.a.Kc(),new ir)))} +function hfd(a,b){rb(a);rb(b);return ns(RD(a,22),RD(b,22))} +function qDd(a,b,c){var d,e;d=Qeb(c);e=new hC(d);sC(a,b,e)} +function d4d(a,b,c,d,e,f){c4d.call(this,a,b,c,d,e,f?-2:-1)} +function sje(a,b,c,d){kZd.call(this,b,c);this.b=a;this.a=d} +function Ry(a,b){wi.call(this,new ezb(a));this.a=a;this.b=b} +function Gu(a){this.b=a;this.c=a;a.e=null;a.c=null;this.a=1} +function Dkc(a){lkc();var b;b=RD(a.g,10);b.n.a=a.d.c+b.d.b} +function fA(){fA=geb;var a,b;b=!lA();a=new tA;eA=b?new mA:a} +function Hob(a){yob();return ZD(a,59)?new irb(a):new Upb(a)} +function Ux(a){return ZD(a,16)?new btb(RD(a,16)):Vx(a.Kc())} +function Vi(a){return new ij(a,a.e.Rd().gc()*a.c.Rd().gc())} +function fj(a){return new sj(a,a.e.Rd().gc()*a.c.Rd().gc())} +function Iz(a){return !!a&&!!a.hashCode?a.hashCode():kFb(a)} +function Yjb(a,b){return b==null?!!qtb(a.f,null):Jtb(a.i,b)} +function hYb(a,b){var c;c=$sb(a.a,b);c&&(b.d=null);return c} +function MGb(a,b,c){if(a.f){return a.f.ef(b,c)}return false} +function cFc(a,b,c,d){bD(a.c[b.g],c.g,d);bD(a.c[c.g],b.g,d)} +function fFc(a,b,c,d){bD(a.c[b.g],b.g,c);bD(a.b[b.g],b.g,d)} +function sXc(a,b,c){return Kfb(UD(c.a))<=a&&Kfb(UD(c.b))>=b} +function yJc(a,b){this.g=a;this.d=cD(WC(jR,1),WAe,10,0,[b])} +function lHb(a){this.c=a;this.b=new yAb(RD(Qb(new oHb),50))} +function UYb(a){this.c=a;this.b=new yAb(RD(Qb(new XYb),50))} +function $Qb(a){this.b=a;this.a=new yAb(RD(Qb(new bRb),50))} +function tRc(){this.b=new _sb;this.d=new Yub;this.e=new Fyb} +function VTb(){this.c=new pjd;this.d=new pjd;this.e=new pjd} +function a1b(){this.a=new Ejd;this.b=(dk(3,iwe),new cnb(3))} +function i7d(a,b){this.e=a;this.a=jJ;this.b=pje(b);this.c=b} +function Vid(a){this.c=a.c;this.d=a.d;this.b=a.b;this.a=a.a} +function VLd(a,b,c,d,e,f){this.a=a;NKd.call(this,b,c,d,e,f)} +function aLd(a,b,c,d,e,f){this.a=a;NKd.call(this,b,c,d,e,f)} +function fge(a,b,c,d,e,f,g){return new lle(a.e,b,c,d,e,f,g)} +function xhb(a,b,c){return c>=0&&lhb(a.substr(c,b.length),b)} +function hGd(a,b){return ZD(b,149)&&lhb(a.b,RD(b,149).Pg())} +function Tde(a,b){return a.a?b.Gh().Kc():RD(b.Gh(),71).Ii()} +function Qqb(a,b){var c;c=a.b.Qc(b);Rqb(c,a.b.gc());return c} +function Ivb(a,b){if(a==null){throw Adb(new Ogb(b))}return a} +function zYd(a){if(!a.u){yYd(a);a.u=new w0d(a,a)}return a.u} +function Kx(a){this.a=(yob(),ZD(a,59)?new irb(a):new Upb(a))} +function Uwd(a){var b;b=RD(Ywd(a,16),29);return !b?a.ii():b} +function lz(a,b){var c;c=nfb(a.Rm);return b==null?c:c+': '+b} +function zhb(a,b,c){AFb(b,c,a.length);return a.substr(b,c-b)} +function VKb(a,b){RJb.call(this);KKb(this);this.a=a;this.c=b} +function neb(a){!a?vve:lz(a,a.ie());String.fromCharCode(10)} +function Wz(a){Qz();$wnd.setTimeout(function(){throw a},0)} +function GHb(){DHb();return cD(WC(uN,1),jwe,436,0,[CHb,BHb])} +function OHb(){LHb();return cD(WC(vN,1),jwe,435,0,[JHb,KHb])} +function WUb(){TUb();return cD(WC(BP,1),jwe,432,0,[RUb,SUb])} +function S8b(){P8b();return cD(WC(vS,1),jwe,517,0,[O8b,N8b])} +function Rvc(){Ovc();return cD(WC(lX,1),jwe,429,0,[Mvc,Nvc])} +function buc(){$tc();return cD(WC(cX,1),jwe,428,0,[Ytc,Ztc])} +function mtc(){jtc();return cD(WC($W,1),jwe,431,0,[htc,itc])} +function vEc(){sEc();return cD(WC(xX,1),jwe,430,0,[qEc,rEc])} +function vNc(){sNc();return cD(WC(MY,1),jwe,531,0,[rNc,qNc])} +function D2c(){x2c();return cD(WC(s0,1),jwe,501,0,[v2c,w2c])} +function zQc(){wQc();return cD(WC(FZ,1),jwe,523,0,[vQc,uQc])} +function HQc(){EQc();return cD(WC(GZ,1),jwe,522,0,[CQc,DQc])} +function iTc(){fTc();return cD(WC(b$,1),jwe,528,0,[eTc,dTc])} +function Fuc(){Cuc();return cD(WC(fX,1),jwe,488,0,[Buc,Auc])} +function F8c(){z8c();return cD(WC(l1,1),jwe,491,0,[x8c,y8c])} +function H9c(){B9c();return cD(WC(t1,1),jwe,492,0,[z9c,A9c])} +function D_c(){A_c();return cD(WC(K_,1),jwe,433,0,[z_c,y_c])} +function a4c(){Y3c();return cD(WC(H0,1),jwe,434,0,[W3c,X3c])} +function gVc(){dVc();return cD(WC(w$,1),jwe,465,0,[bVc,cVc])} +function Pbd(){Mbd();return cD(WC(O1,1),jwe,438,0,[Lbd,Kbd])} +function rdd(){ldd();return cD(WC(W1,1),jwe,437,0,[kdd,jdd])} +function xqd(){uqd();return cD(WC(M3,1),jwe,347,0,[sqd,tqd])} +function Jvd(a,b,c,d){return c>=0?a.Uh(b,c,d):a.Ch(null,c,d)} +function ltd(a){if(a.b.b==0){return a.a.sf()}return Uub(a.b)} +function vKd(a){if(a.p!=5)throw Adb(new cgb);return Ydb(a.f)} +function EKd(a){if(a.p!=5)throw Adb(new cgb);return Ydb(a.k)} +function P$d(a){dE(a.a)===dE((lYd(),kYd))&&Q$d(a);return a.a} +function iad(a,b){a.b=b;a.c>0&&a.b>0&&(a.g=Aad(a.c,a.b,a.a))} +function jad(a,b){a.c=b;a.c>0&&a.b>0&&(a.g=Aad(a.c,a.b,a.a))} +function BUc(a,b){yUc(this,new rjd(a.a,a.b));zUc(this,gv(b))} +function Tp(){Sp.call(this,new Usb(Sv(12)));Lb(true);this.a=2} +function eue(a,b,c){Vse();Wse.call(this,a);this.b=b;this.a=c} +function C7d(a,b,c){s7d();t7d.call(this,b);this.a=a;this.b=c} +function qub(a){var b;b=a.c.d.b;a.b=b;a.a=a.c.d;b.a=a.c.d.b=a} +function Tub(a){return a.b==0?null:(sFb(a.b!=0),Wub(a,a.a.a))} +function Xjb(a,b){return b==null?Wd(qtb(a.f,null)):Ktb(a.i,b)} +function bzb(a,b,c,d,e){return new Kzb(a,(cAb(),aAb),b,c,d,e)} +function Fnb(a,b){oFb(b);return Hnb(a,$C(kE,Pwe,28,b,15,1),b)} +function Tx(a,b){Rb(a,'set1');Rb(b,'set2');return new ey(a,b)} +function Kz(a,b){var c=Jz[a.charCodeAt(0)];return c==null?a:c} +function Xyb(a,b){var c,d;c=b;d=new Gzb;Zyb(a,c,d);return d.d} +function EMb(a,b,c,d){var e;e=new TJb;b.a[c.g]=e;Wrb(a.b,d,e)} +function SXb(a,b){var c;c=BXb(a.f,b);return $id(fjd(c),a.f.d)} +function RFb(a){var b;EJb(a.a);DJb(a.a);b=new PJb(a.a);LJb(b)} +function _Mb(a,b){$Mb(a,true);Umb(a.e.Rf(),new dNb(a,true,b))} +function PSb(a,b){HSb();return a==vCd(JGd(b))||a==vCd(LGd(b))} +function R0c(a,b){B0c();return RD(mQb(b,(h_c(),f_c)),17).a==a} +function eE(a){return Math.max(Math.min(a,lve),-2147483648)|0} +function sy(a){this.a=RD(Qb(a),277);this.b=(yob(),new jrb(a))} +function qbd(a,b,c){this.i=new bnb;this.b=a;this.g=b;this.a=c} +function had(a,b,c){this.a=new bnb;this.e=a;this.f=b;this.c=c} +function _9c(a,b,c){this.c=new bnb;this.e=a;this.f=b;this.b=c} +function TKb(a){RJb.call(this);KKb(this);this.a=a;this.c=true} +function ieb(a){function b(){} +;b.prototype=a||{};return new b} +function zfb(a){if(a.Ae()){return null}var b=a.n;return eeb[b]} +function kzd(a){if(a.Db>>16!=3)return null;return RD(a.Cb,27)} +function MCd(a){if(a.Db>>16!=9)return null;return RD(a.Cb,27)} +function Fzd(a){if(a.Db>>16!=6)return null;return RD(a.Cb,74)} +function dVc(){dVc=geb;bVc=new eVc(Nye,0);cVc=new eVc(Oye,1)} +function wQc(){wQc=geb;vQc=new xQc(Oye,0);uQc=new xQc(Nye,1)} +function EQc(){EQc=geb;CQc=new FQc(Zye,0);DQc=new FQc('UP',1)} +function Is(){Is=geb;Hs=ss((zs(),cD(WC(RG,1),jwe,549,0,[ys])))} +function Wx(a){var b;b=new atb(Sv(a.length));zob(b,a);return b} +function B2b(a,b){a.b+=b.b;a.c+=b.c;a.d+=b.d;a.a+=b.a;return a} +function qmb(a,b){if(kmb(a,b)){Jmb(a);return true}return false} +function qC(a,b){if(b==null){throw Adb(new Ngb)}return rC(a,b)} +function nB(a,b){var c;c=a.q.getHours();a.q.setDate(b);mB(a,c)} +function Xvd(a,b,c){var d;d=a.Ih(b);d>=0?a.bi(d,c):Svd(a,b,c)} +function Lvd(a,b){var c;c=a.Ih(b);return c>=0?a.Wh(c):Rvd(a,b)} +function zo(a,b){var c;Qb(b);for(c=a.a;c;c=c.c){b.Yd(c.g,c.i)}} +function pMc(a,b,c){var d;d=qMc(a,b,c);a.b=new _Lc(d.c.length)} +function HId(a,b,c){EId();!!a&&Zjb(DId,a,b);!!a&&Zjb(CId,a,c)} +function bfc(a,b){Rec();return Geb(),RD(b.a,17).a0} +function sId(a){var b;b=a.d;b=a.bj(a.f);WGd(a,b);return b.Ob()} +function bHd(a,b){var c;c=new Kub(b);Ve(c,a);return new dnb(c)} +function qKd(a){if(a.p!=0)throw Adb(new cgb);return Pdb(a.f,0)} +function zKd(a){if(a.p!=0)throw Adb(new cgb);return Pdb(a.k,0)} +function gBd(a){if(a.Db>>16!=7)return null;return RD(a.Cb,241)} +function xXd(a){if(a.Db>>16!=6)return null;return RD(a.Cb,241)} +function dCd(a){if(a.Db>>16!=7)return null;return RD(a.Cb,167)} +function vCd(a){if(a.Db>>16!=11)return null;return RD(a.Cb,27)} +function uWd(a){if(a.Db>>16!=17)return null;return RD(a.Cb,29)} +function kVd(a){if(a.Db>>16!=3)return null;return RD(a.Cb,155)} +function BDb(a){var b;MCb(a);b=new _sb;return CDb(a,new aEb(b))} +function xfb(a,b){var c=a.a=a.a||[];return c[b]||(c[b]=a.ve(b))} +function qB(a,b){var c;c=a.q.getHours();a.q.setMonth(b);mB(a,c)} +function oz(a,b){ez(this);this.f=b;this.g=a;gz(this);this.je()} +function TQb(a,b){this.a=a;this.c=ajd(this.a);this.b=new Vid(b)} +function aGb(a,b,c){this.a=b;this.c=a;this.b=(Qb(c),new dnb(c))} +function s$b(a,b,c){this.a=b;this.c=a;this.b=(Qb(c),new dnb(c))} +function _Kc(a){this.a=a;this.b=$C(qY,Nve,2043,a.e.length,0,2)} +function fGb(){this.a=new Iub;this.e=new _sb;this.g=0;this.i=0} +function EId(){EId=geb;DId=new Tsb;CId=new Tsb;IId(zK,new JId)} +function KFc(){KFc=geb;JFc=nfd(new ufd,(sXb(),rXb),(hcc(),$bc))} +function RFc(){RFc=geb;QFc=nfd(new ufd,(sXb(),rXb),(hcc(),$bc))} +function gGc(){gGc=geb;fGc=nfd(new ufd,(sXb(),rXb),(hcc(),$bc))} +function ANc(){ANc=geb;zNc=pfd(new ufd,(sXb(),rXb),(hcc(),ybc))} +function dOc(){dOc=geb;cOc=pfd(new ufd,(sXb(),rXb),(hcc(),ybc))} +function gQc(){gQc=geb;fQc=pfd(new ufd,(sXb(),rXb),(hcc(),ybc))} +function WQc(){WQc=geb;VQc=pfd(new ufd,(sXb(),rXb),(hcc(),ybc))} +function dZd(a,b,c,d,e,f){return new P3d(a.e,b,a.Lj(),c,d,e,f)} +function $jb(a,b,c){return b==null?rtb(a.f,null,c):Ltb(a.i,b,c)} +function Y0b(a,b){!!a.c&&Ymb(a.c.g,a);a.c=b;!!a.c&&Rmb(a.c.g,a)} +function g3b(a,b){!!a.c&&Ymb(a.c.a,a);a.c=b;!!a.c&&Rmb(a.c.a,a)} +function P3b(a,b){!!a.i&&Ymb(a.i.j,a);a.i=b;!!a.i&&Rmb(a.i.j,a)} +function Z0b(a,b){!!a.d&&Ymb(a.d.e,a);a.d=b;!!a.d&&Rmb(a.d.e,a)} +function _Sc(a,b){!!a.a&&Ymb(a.a.k,a);a.a=b;!!a.a&&Rmb(a.a.k,a)} +function aTc(a,b){!!a.b&&Ymb(a.b.f,a);a.b=b;!!a.b&&Rmb(a.b.f,a)} +function Odd(a,b){Pdd(a,a.b,a.c);RD(a.b.b,68);!!b&&RD(b.b,68).b} +function j2c(a,b){return Qfb(RD(a.c,65).c.e.b,RD(b.c,65).c.e.b)} +function k2c(a,b){return Qfb(RD(a.c,65).c.e.a,RD(b.c,65).c.e.a)} +function YXb(a){NXb();return Geb(),RD(a.a,86).d.e!=0?true:false} +function LXd(a,b){ZD(a.Cb,184)&&(RD(a.Cb,184).tb=null);PAd(a,b)} +function CWd(a,b){ZD(a.Cb,90)&&v$d(yYd(RD(a.Cb,90)),4);PAd(a,b)} +function _5d(a,b){a6d(a,b);ZD(a.Cb,90)&&v$d(yYd(RD(a.Cb,90)),2)} +function JFd(a,b){var c,d;c=b.c;d=c!=null;d&&oDd(a,new OC(b.c))} +function v0d(a){var b,c;c=(jTd(),b=new s2d,b);l2d(c,a);return c} +function E4d(a){var b,c;c=(jTd(),b=new s2d,b);l2d(c,a);return c} +function Fr(a){var b;while(true){b=a.Pb();if(!a.Ob()){return b}}} +function nq(a,b,c){Rmb(a.a,(fn(),ck(b,c),new gp(b,c)));return a} +function rge(a,b){return nke(),wWd(b)?new ole(b,a):new Eke(b,a)} +function ojb(a){Pib();return Ddb(a,0)>=0?jjb(a):Xib(jjb(Odb(a)))} +function Asb(a){var b;b=RD(UEb(a.b),9);return new Fsb(a.a,b,a.c)} +function Qw(a,b){var c;c=RD(Xv(nd(a.a),b),16);return !c?0:c.gc()} +function Zmb(a,b,c){var d;xFb(b,c,a.c.length);d=c-b;$Eb(a.c,b,d)} +function Rkb(a,b,c){xFb(b,c,a.gc());this.c=a;this.a=b;this.b=c-b} +function fgd(a){this.c=new Yub;this.b=a.b;this.d=a.c;this.a=a.a} +function qjd(a){this.a=$wnd.Math.cos(a);this.b=$wnd.Math.sin(a)} +function bTc(a,b,c,d){this.c=a;this.d=d;_Sc(this,b);aTc(this,c)} +function Si(a,b){Qi.call(this,new Usb(Sv(a)));dk(b,Mve);this.a=b} +function Ryb(a,b,c){return new Kzb(a,(cAb(),_zb),null,false,b,c)} +function czb(a,b,c){return new Kzb(a,(cAb(),bAb),b,c,null,false)} +function ABb(){xBb();return cD(WC(QL,1),jwe,108,0,[uBb,vBb,wBb])} +function yLb(){vLb();return cD(WC(TN,1),jwe,472,0,[uLb,tLb,sLb])} +function HKb(){EKb();return cD(WC(MN,1),jwe,471,0,[CKb,BKb,DKb])} +function aKb(){ZJb();return cD(WC(JN,1),jwe,237,0,[WJb,XJb,YJb])} +function DWb(){AWb();return cD(WC(JP,1),jwe,391,0,[yWb,xWb,zWb])} +function moc(){joc();return cD(WC(UV,1),jwe,372,0,[ioc,hoc,goc])} +function ytc(){stc();return cD(WC(_W,1),jwe,322,0,[qtc,ptc,rtc])} +function Htc(){Etc();return cD(WC(aX,1),jwe,351,0,[Btc,Dtc,Ctc])} +function kuc(){huc();return cD(WC(dX,1),jwe,460,0,[fuc,euc,guc])} +function Avc(){xvc();return cD(WC(jX,1),jwe,299,0,[vvc,wvc,uvc])} +function Jvc(){Gvc();return cD(WC(kX,1),jwe,311,0,[Evc,Fvc,Dvc])} +function pDc(){lDc();return cD(WC(sX,1),jwe,390,0,[iDc,jDc,kDc])} +function EEc(){BEc();return cD(WC(yX,1),jwe,463,0,[AEc,yEc,zEc])} +function NEc(){KEc();return cD(WC(zX,1),jwe,387,0,[HEc,IEc,JEc])} +function WEc(){TEc();return cD(WC(AX,1),jwe,349,0,[SEc,QEc,REc])} +function oFc(){lFc();return cD(WC(CX,1),jwe,350,0,[iFc,jFc,kFc])} +function xFc(){uFc();return cD(WC(DX,1),jwe,352,0,[tFc,rFc,sFc])} +function GFc(){DFc();return cD(WC(EX,1),jwe,388,0,[BFc,CFc,AFc])} +function UKc(){RKc();return cD(WC(nY,1),jwe,464,0,[OKc,PKc,QKc])} +function K3b(a){return xjd(cD(WC(l3,1),Nve,8,0,[a.i.n,a.n,a.a]))} +function OZc(){LZc();return cD(WC(F_,1),jwe,392,0,[KZc,JZc,IZc])} +function H_c(){H_c=geb;G_c=nfd(new ufd,(YVc(),WVc),(WYc(),MYc))} +function A_c(){A_c=geb;z_c=new B_c('DFS',0);y_c=new B_c('BFS',1)} +function TQc(a,b,c){var d;d=new SQc;d.b=b;d.a=c;++b.b;Rmb(a.d,d)} +function NTb(a,b,c){var d;d=new sjd(c.d);$id(d,a);CGd(b,d.a,d.b)} +function Nwb(a,b){Mwb(a,Ydb(Cdb(Tdb(b,24),Pxe)),Ydb(Cdb(b,Pxe)))} +function wFb(a,b){if(a<0||a>b){throw Adb(new veb(cye+a+dye+b))}} +function tFb(a,b){if(a<0||a>=b){throw Adb(new veb(cye+a+dye+b))}} +function BFb(a,b){if(a<0||a>=b){throw Adb(new eib(cye+a+dye+b))}} +function Swb(a,b){this.b=(uFb(a),a);this.a=(b&qxe)==0?b|64|Ove:b} +function ODb(a){var b;MCb(a);b=(urb(),urb(),srb);return PDb(a,b)} +function R9c(a,b,c){var d;d=S9c(a,b,false);return d.b<=b&&d.a<=c} +function h9c(){b9c();return cD(WC(o1,1),jwe,439,0,[$8c,a9c,_8c])} +function c7c(){_6c();return cD(WC(a1,1),jwe,394,0,[Z6c,$6c,Y6c])} +function i6c(){f6c();return cD(WC(V0,1),jwe,445,0,[c6c,d6c,e6c])} +function D6c(){z6c();return cD(WC(Z0,1),jwe,456,0,[w6c,y6c,x6c])} +function k4c(){g4c();return cD(WC(I0,1),jwe,393,0,[d4c,e4c,f4c])} +function x5c(){t5c();return cD(WC(N0,1),jwe,300,0,[r5c,s5c,q5c])} +function Ind(){Fnd();return cD(WC(y3,1),jwe,346,0,[Dnd,Cnd,End])} +function jbd(){gbd();return cD(WC(I1,1),jwe,444,0,[dbd,ebd,fbd])} +function Rmd(){Omd();return cD(WC(t3,1),jwe,278,0,[Lmd,Mmd,Nmd])} +function pqd(){mqd();return cD(WC(J3,1),jwe,280,0,[kqd,jqd,lqd])} +function bv(a){Qb(a);return ZD(a,16)?new dnb(RD(a,16)):cv(a.Kc())} +function Hz(a,b){return !!a&&!!a.equals?a.equals(b):dE(a)===dE(b)} +function Cdb(a,b){return Edb(tD(Kdb(a)?Wdb(a):a,Kdb(b)?Wdb(b):b))} +function Rdb(a,b){return Edb(zD(Kdb(a)?Wdb(a):a,Kdb(b)?Wdb(b):b))} +function $db(a,b){return Edb(HD(Kdb(a)?Wdb(a):a,Kdb(b)?Wdb(b):b))} +function xs(a,b){var c;c=(uFb(a),a).g;lFb(!!c);uFb(b);return c(b)} +function rv(a,b){var c,d;d=tv(a,b);c=a.a.fd(d);return new Gv(a,c)} +function CXd(a){if(a.Db>>16!=6)return null;return RD(yvd(a),241)} +function sKd(a){if(a.p!=2)throw Adb(new cgb);return Ydb(a.f)&Bwe} +function BKd(a){if(a.p!=2)throw Adb(new cgb);return Ydb(a.k)&Bwe} +function ynb(a){sFb(a.ad?1:0} +function Hmc(a,b){var c,d;c=Gmc(b);d=c;return RD(Wjb(a.c,d),17).a} +function CMc(a,b,c){var d;d=a.d[b.p];a.d[b.p]=a.d[c.p];a.d[c.p]=d} +function Jqd(a,b,c){var d;if(a.n&&!!b&&!!c){d=new otd;Rmb(a.e,d)}} +function gYb(a,b){Ysb(a.a,b);if(b.d){throw Adb(new yz(jye))}b.d=a} +function Had(a,b){this.a=new bnb;this.d=new bnb;this.f=a;this.c=b} +function RWb(){this.c=new dXb;this.a=new I_b;this.b=new E0b;g0b()} +function med(){hed();this.b=new Tsb;this.a=new Tsb;this.c=new bnb} +function KKd(a,b,c){this.d=a;this.j=b;this.e=c;this.o=-1;this.p=3} +function LKd(a,b,c){this.d=a;this.k=b;this.f=c;this.o=-1;this.p=5} +function S3d(a,b,c,d,e,f){R3d.call(this,a,b,c,d,e);f&&(this.o=-2)} +function U3d(a,b,c,d,e,f){T3d.call(this,a,b,c,d,e);f&&(this.o=-2)} +function W3d(a,b,c,d,e,f){V3d.call(this,a,b,c,d,e);f&&(this.o=-2)} +function Y3d(a,b,c,d,e,f){X3d.call(this,a,b,c,d,e);f&&(this.o=-2)} +function $3d(a,b,c,d,e,f){Z3d.call(this,a,b,c,d,e);f&&(this.o=-2)} +function a4d(a,b,c,d,e,f){_3d.call(this,a,b,c,d,e);f&&(this.o=-2)} +function f4d(a,b,c,d,e,f){e4d.call(this,a,b,c,d,e);f&&(this.o=-2)} +function h4d(a,b,c,d,e,f){g4d.call(this,a,b,c,d,e);f&&(this.o=-2)} +function N7d(a,b,c,d){t7d.call(this,c);this.b=a;this.c=b;this.d=d} +function mfe(a,b){this.f=a;this.a=(ree(),pee);this.c=pee;this.b=b} +function Jfe(a,b){this.g=a;this.d=(ree(),qee);this.a=qee;this.b=b} +function Gme(a,b){!a.c&&(a.c=new Uge(a,0));Fge(a.c,(nme(),fme),b)} +function Oge(a,b){return Pge(a,b,ZD(b,102)&&(RD(b,19).Bb&txe)!=0)} +function lB(a,b){return Agb(Hdb(a.q.getTime()),Hdb(b.q.getTime()))} +function gj(a){return fk(a.e.Rd().gc()*a.c.Rd().gc(),16,new qj(a))} +function CYd(a){return !!a.u&&tYd(a.u.a).i!=0&&!(!!a.n&&d$d(a.n))} +function p4d(a){return !!a.a&&o4d(a.a.a).i!=0&&!(!!a.b&&o5d(a.b))} +function Cxd(a,b){if(b==0){return !!a.o&&a.o.f!=0}return Kvd(a,b)} +function Cc(a,b,c){var d;d=RD(a.Zb().xc(b),16);return !!d&&d.Hc(c)} +function Gc(a,b,c){var d;d=RD(a.Zb().xc(b),16);return !!d&&d.Mc(c)} +function _yb(a,b){var c;c=1-b;a.a[c]=azb(a.a[c],c);return azb(a,b)} +function DFb(a,b){var c,d;d=Cdb(a,yxe);c=Sdb(b,32);return Rdb(c,d)} +function bGb(a,b,c){var d;d=(Qb(a),new dnb(a));_Fb(new aGb(d,b,c))} +function t$b(a,b,c){var d;d=(Qb(a),new dnb(a));r$b(new s$b(d,b,c))} +function vBd(a,b,c,d,e,f){wBd(a,b,c,f);EYd(a,d);FYd(a,e);return a} +function Xhb(a,b,c,d){a.a+=''+zhb(b==null?vve:jeb(b),c,d);return a} +function Jkb(a,b){this.a=a;Dkb.call(this,a);wFb(b,a.gc());this.b=b} +function xmb(a){this.a=$C(jJ,rve,1,mgb($wnd.Math.max(8,a))<<1,5,1)} +function t2b(a){return RD(anb(a,$C(jR,WAe,10,a.c.length,0,1)),199)} +function s2b(a){return RD(anb(a,$C(WQ,VAe,18,a.c.length,0,1)),483)} +function Iyb(a){return !a.a?a.c:a.e.length==0?a.a.a:a.a.a+(''+a.e)} +function Rib(a){while(a.d>0&&a.a[--a.d]==0);a.a[a.d++]==0&&(a.e=0)} +function fvb(a){sFb(a.b.b!=a.d.a);a.c=a.b=a.b.b;--a.a;return a.c.c} +function sRc(a,b,c){a.a=b;a.c=c;a.b.a.$b();Xub(a.d);aFb(a.e.a.c,0)} +function Z5c(a,b){var c;a.e=new R5c;c=Q2c(b);_mb(c,a.c);$5c(a,c,0)} +function zgd(a,b,c,d){var e;e=new Hgd;e.a=b;e.b=c;e.c=d;Mub(a.a,e)} +function Agd(a,b,c,d){var e;e=new Hgd;e.a=b;e.b=c;e.c=d;Mub(a.b,e)} +function Tb(a,b,c){if(a<0||bc){throw Adb(new veb(Kb(a,b,c)))}} +function Pb(a,b){if(a<0||a>=b){throw Adb(new veb(Ib(a,b)))}return a} +function qz(b){if(!('stack' in b)){try{throw b}catch(a){}}return b} +function Zjc(a){Wjc();if(ZD(a.g,10)){return RD(a.g,10)}return null} +function nx(a){if(Ih(a).dc()){return false}Jh(a,new rx);return true} +function Xdb(a){var b;if(Kdb(a)){b=a;return b==-0.?0:b}return ED(a)} +function lkb(a,b){if(ZD(b,44)){return Jd(a.a,RD(b,44))}return false} +function gsb(a,b){if(ZD(b,44)){return Jd(a.a,RD(b,44))}return false} +function vub(a,b){if(ZD(b,44)){return Jd(a.a,RD(b,44))}return false} +function RCb(a){var b;LCb(a);b=new Prb;ixb(a.a,new fDb(b));return b} +function Vae(){var a,b,c;b=(c=(a=new s2d,a),c);Rmb(Rae,b);return b} +function mDb(a){var b;LCb(a);b=new ltb;ixb(a.a,new uDb(b));return b} +function jDb(a,b){if(a.a<=a.b){b.Dd(a.a++);return true}return false} +function xzb(a){yzb.call(this,a,(cAb(),$zb),null,false,null,false)} +function $Rb(){$Rb=geb;ZRb=ss((VRb(),cD(WC($O,1),jwe,489,0,[URb])))} +function CHc(){CHc=geb;BHc=yx(sgb(1),sgb(4));AHc=yx(sgb(1),sgb(2))} +function yXc(a,b){return new gud(b,njd(ajd(b.e),a,a),(Geb(),true))} +function fv(a){return new cnb((dk(a,lwe),dz(Bdb(Bdb(5,a),a/10|0))))} +function Wi(a){return fk(a.e.Rd().gc()*a.c.Rd().gc(),273,new kj(a))} +function u2b(a){return RD(anb(a,$C(xR,XAe,12,a.c.length,0,1)),2042)} +function COc(a){dOc();return !W0b(a)&&!(!W0b(a)&&a.c.i.c==a.d.i.c)} +function Y_c(a,b){R_c();return RD(mQb(b,(h_c(),W$c)),17).a>=a.gc()} +function q8b(a,b){w8b(b,a);y8b(a.d);y8b(RD(mQb(a,(yCc(),cBc)),214))} +function r8b(a,b){z8b(b,a);B8b(a.d);B8b(RD(mQb(a,(yCc(),cBc)),214))} +function $0b(a,b,c){!!a.d&&Ymb(a.d.e,a);a.d=b;!!a.d&&Qmb(a.d.e,c,a)} +function jPb(a,b,c){return c.f.c.length>0?yPb(a.a,b,c):yPb(a.b,b,c)} +function Uz(a,b,c){var d;d=Sz();try{return Rz(a,b,c)}finally{Vz(d)}} +function wDd(a,b){var c,d;c=qC(a,b);d=null;!!c&&(d=c.pe());return d} +function yDd(a,b){var c,d;c=qC(a,b);d=null;!!c&&(d=c.se());return d} +function xDd(a,b){var c,d;c=JB(a,b);d=null;!!c&&(d=c.se());return d} +function zDd(a,b){var c,d;c=qC(a,b);d=null;!!c&&(d=ADd(c));return d} +function rEd(a,b,c){var d;d=uDd(c);Do(a.g,d,b);Do(a.i,b,c);return b} +function UIc(a,b,c){this.d=new fJc(this);this.e=a;this.i=b;this.f=c} +function Mk(a,b,c,d){this.e=null;this.c=a;this.d=b;this.a=c;this.b=d} +function urc(a,b,c,d){nrc(this);this.c=a;this.e=b;this.f=c;this.b=d} +function MKd(a,b,c,d){this.d=a;this.n=b;this.g=c;this.o=d;this.p=-1} +function Vc(a,b,c,d){return ZD(c,59)?new Kg(a,b,c,d):new yg(a,b,c,d)} +function gr(a){if(ZD(a,16)){return RD(a,16).dc()}return !a.Kc().Ob()} +function Wo(a){if(a.e.g!=a.b){throw Adb(new Jrb)}return !!a.c&&a.d>0} +function evb(a){sFb(a.b!=a.d.c);a.c=a.b;a.b=a.b.a;++a.a;return a.c.c} +function imb(a,b){uFb(b);bD(a.a,a.c,b);a.c=a.c+1&a.a.length-1;mmb(a)} +function hmb(a,b){uFb(b);a.b=a.b-1&a.a.length-1;bD(a.a,a.b,b);mmb(a)} +function _je(a){var b;b=a.Gh();this.a=ZD(b,71)?RD(b,71).Ii():b.Kc()} +function px(a){return new Swb(Dob(RD(a.a.md(),16).gc(),a.a.ld()),16)} +function Abd(){Abd=geb;zbd=ss((sbd(),cD(WC(M1,1),jwe,490,0,[rbd])))} +function Jbd(){Jbd=geb;Ibd=ss((Cbd(),cD(WC(N1,1),jwe,558,0,[Bbd])))} +function idd(){idd=geb;hdd=ss((_cd(),cD(WC(V1,1),jwe,539,0,[$cd])))} +function X$b(){U$b();return cD(WC(CQ,1),jwe,389,0,[T$b,R$b,Q$b,S$b])} +function hAb(){cAb();return cD(WC(AL,1),jwe,304,0,[$zb,_zb,aAb,bAb])} +function LPb(){IPb();return cD(WC(DO,1),jwe,332,0,[FPb,EPb,GPb,HPb])} +function LRb(){IRb();return cD(WC(WO,1),jwe,406,0,[FRb,ERb,GRb,HRb])} +function pOb(){mOb();return cD(WC(hO,1),jwe,417,0,[lOb,iOb,jOb,kOb])} +function uZb(){nZb();return cD(WC(lQ,1),jwe,416,0,[jZb,mZb,kZb,lZb])} +function hnc(){enc();return cD(WC(LV,1),jwe,421,0,[anc,bnc,cnc,dnc])} +function zec(){vec();return cD(WC(qT,1),jwe,371,0,[uec,sec,tec,rec])} +function BDc(){wDc();return cD(WC(tX,1),jwe,203,0,[uDc,vDc,tDc,sDc])} +function nEc(){kEc();return cD(WC(wX,1),jwe,284,0,[hEc,gEc,iEc,jEc])} +function Unc(a){var b;return a.j==(qpd(),npd)&&(b=Vnc(a),Csb(b,Xod))} +function qhc(a,b){var c;c=b.a;Y0b(c,b.c.d);Z0b(c,b.d.d);Cjd(c.a,a.n)} +function _5b(a,b){var c;c=RD(cub(a.b,b),67);!c&&(c=new Yub);return c} +function $jc(a){Wjc();if(ZD(a.g,154)){return RD(a.g,154)}return null} +function gRc(a){a.a=null;a.e=null;aFb(a.b.c,0);aFb(a.f.c,0);a.c=null} +function Ovc(){Ovc=geb;Mvc=new Pvc(Kye,0);Nvc=new Pvc('TOP_LEFT',1)} +function sNc(){sNc=geb;rNc=new tNc('UPPER',0);qNc=new tNc('LOWER',1)} +function nWc(a,b){return cjd(new rjd(b.e.a+b.f.a/2,b.e.b+b.f.b/2),a)} +function wqc(a,b){return RD(Lvb(JDb(RD(Qc(a.k,b),15).Oc(),lqc)),113)} +function xqc(a,b){return RD(Lvb(KDb(RD(Qc(a.k,b),15).Oc(),lqc)),113)} +function cWc(){YVc();return cD(WC(H$,1),jwe,405,0,[UVc,VVc,WVc,XVc])} +function v_c(){s_c();return cD(WC(J_,1),jwe,353,0,[r_c,p_c,q_c,o_c])} +function n5c(){j5c();return cD(WC(M0,1),jwe,354,0,[i5c,g5c,h5c,f5c])} +function Tpd(){Qpd();return cD(WC(H3,1),jwe,386,0,[Opd,Ppd,Npd,Mpd])} +function Tnd(){Pnd();return cD(WC(z3,1),jwe,291,0,[Ond,Lnd,Mnd,Nnd])} +function _md(){Ymd();return cD(WC(u3,1),jwe,223,0,[Xmd,Vmd,Umd,Wmd])} +function Jrd(){Grd();return cD(WC(R3,1),jwe,320,0,[Frd,Crd,Erd,Drd])} +function wtd(){ttd();return cD(WC(n4,1),jwe,415,0,[qtd,rtd,ptd,std])} +function GId(a){EId();return Ujb(DId,a)?RD(Wjb(DId,a),341).Qg():null} +function Avd(a,b,c){return b<0?Rvd(a,c):RD(c,69).wk().Bk(a,a.hi(),b)} +function sEd(a,b,c){var d;d=uDd(c);Do(a.j,d,b);Zjb(a.k,b,c);return b} +function qEd(a,b,c){var d;d=uDd(c);Do(a.d,d,b);Zjb(a.e,b,c);return b} +function DGd(a){var b,c;b=(bvd(),c=new rzd,c);!!a&&pzd(b,a);return b} +function WHd(a){var b;b=a.aj(a.i);a.i>0&&hib(a.g,0,b,0,a.i);return b} +function Led(a,b){var c;for(c=a.j.c.length;c>24} +function AKd(a){if(a.p!=1)throw Adb(new cgb);return Ydb(a.k)<<24>>24} +function GKd(a){if(a.p!=7)throw Adb(new cgb);return Ydb(a.k)<<16>>16} +function xKd(a){if(a.p!=7)throw Adb(new cgb);return Ydb(a.f)<<16>>16} +function Wib(a,b){if(b.e==0||a.e==0){return Oib}return Ljb(),Mjb(a,b)} +function Nd(a,b){return dE(b)===dE(a)?'(this Map)':b==null?vve:jeb(b)} +function MFb(a,b,c){return Jfb(UD(Wd(qtb(a.f,b))),UD(Wd(qtb(a.f,c))))} +function wkc(a,b,c){var d;d=RD(Wjb(a.g,c),60);Rmb(a.a.c,new Ptd(b,d))} +function Slc(a,b,c){a.i=0;a.e=0;if(b==c){return}Rlc(a,b,c);Qlc(a,b,c)} +function rTc(a,b,c,d,e){var f;f=mTc(e,c,d);Rmb(b,TSc(e,f));vTc(a,e,b)} +function Jrc(a,b,c,d,e){this.i=a;this.a=b;this.e=c;this.j=d;this.f=e} +function iUb(a,b){VTb.call(this);this.a=a;this.b=b;Rmb(this.a.b,this)} +function rTb(a){this.b=new Tsb;this.c=new Tsb;this.d=new Tsb;this.a=a} +function Dx(a,b){var c;c=new cib;a.Gd(c);c.a+='..';b.Hd(c);return c.a} +function Fsd(a,b){var c;c=b;while(c){Zid(a,c.i,c.j);c=vCd(c)}return a} +function pEd(a,b,c){var d;d=uDd(c);Zjb(a.b,d,b);Zjb(a.c,b,c);return b} +function Kr(a){var b;b=0;while(a.Ob()){a.Pb();b=Bdb(b,1)}return dz(b)} +function oke(a,b){nke();var c;c=RD(a,69).vk();K6d(c,b);return c.xl(b)} +function tC(d,a,b){if(b){var c=b.oe();d.a[a]=c(b)}else{delete d.a[a]}} +function tB(a,b){var c;c=a.q.getHours();a.q.setFullYear(b+Owe);mB(a,c)} +function KSd(a,b){return RD(b==null?Wd(qtb(a.f,null)):Ktb(a.i,b),288)} +function hOc(a,b){return a==(r3b(),p3b)&&b==p3b?4:a==p3b||b==p3b?8:32} +function cge(a,b,c){return dge(a,b,c,ZD(b,102)&&(RD(b,19).Bb&txe)!=0)} +function jge(a,b,c){return kge(a,b,c,ZD(b,102)&&(RD(b,19).Bb&txe)!=0)} +function Qge(a,b,c){return Rge(a,b,c,ZD(b,102)&&(RD(b,19).Bb&txe)!=0)} +function jmb(a){if(a.b==a.c){return}a.a=$C(jJ,rve,1,8,5,1);a.b=0;a.c=0} +function Nsb(a){sFb(a.a=0&&a.a[c]===b[c];c--);return c<0} +function Xx(a){var b;if(a){return new Kub(a)}b=new Iub;_q(b,a);return b} +function nmc(a,b){var c,d;d=false;do{c=qmc(a,b);d=d|c}while(c);return d} +function Vz(a){a&&aA(($z(),Zz));--Nz;if(a){if(Pz!=-1){Xz(Pz);Pz=-1}}} +function Pwb(a){Hwb();Mwb(this,Ydb(Cdb(Tdb(a,24),Pxe)),Ydb(Cdb(a,Pxe)))} +function IHb(){IHb=geb;HHb=ss((DHb(),cD(WC(uN,1),jwe,436,0,[CHb,BHb])))} +function QHb(){QHb=geb;PHb=ss((LHb(),cD(WC(vN,1),jwe,435,0,[JHb,KHb])))} +function YUb(){YUb=geb;XUb=ss((TUb(),cD(WC(BP,1),jwe,432,0,[RUb,SUb])))} +function U8b(){U8b=geb;T8b=ss((P8b(),cD(WC(vS,1),jwe,517,0,[O8b,N8b])))} +function Tvc(){Tvc=geb;Svc=ss((Ovc(),cD(WC(lX,1),jwe,429,0,[Mvc,Nvc])))} +function duc(){duc=geb;cuc=ss(($tc(),cD(WC(cX,1),jwe,428,0,[Ytc,Ztc])))} +function Huc(){Huc=geb;Guc=ss((Cuc(),cD(WC(fX,1),jwe,488,0,[Buc,Auc])))} +function xEc(){xEc=geb;wEc=ss((sEc(),cD(WC(xX,1),jwe,430,0,[qEc,rEc])))} +function xNc(){xNc=geb;wNc=ss((sNc(),cD(WC(MY,1),jwe,531,0,[rNc,qNc])))} +function otc(){otc=geb;ntc=ss((jtc(),cD(WC($W,1),jwe,431,0,[htc,itc])))} +function F_c(){F_c=geb;E_c=ss((A_c(),cD(WC(K_,1),jwe,433,0,[z_c,y_c])))} +function F2c(){F2c=geb;E2c=ss((x2c(),cD(WC(s0,1),jwe,501,0,[v2c,w2c])))} +function BQc(){BQc=geb;AQc=ss((wQc(),cD(WC(FZ,1),jwe,523,0,[vQc,uQc])))} +function JQc(){JQc=geb;IQc=ss((EQc(),cD(WC(GZ,1),jwe,522,0,[CQc,DQc])))} +function kTc(){kTc=geb;jTc=ss((fTc(),cD(WC(b$,1),jwe,528,0,[eTc,dTc])))} +function iVc(){iVc=geb;hVc=ss((dVc(),cD(WC(w$,1),jwe,465,0,[bVc,cVc])))} +function c4c(){c4c=geb;b4c=ss((Y3c(),cD(WC(H0,1),jwe,434,0,[W3c,X3c])))} +function H8c(){H8c=geb;G8c=ss((z8c(),cD(WC(l1,1),jwe,491,0,[x8c,y8c])))} +function J9c(){J9c=geb;I9c=ss((B9c(),cD(WC(t1,1),jwe,492,0,[z9c,A9c])))} +function Rbd(){Rbd=geb;Qbd=ss((Mbd(),cD(WC(O1,1),jwe,438,0,[Lbd,Kbd])))} +function tdd(){tdd=geb;sdd=ss((ldd(),cD(WC(W1,1),jwe,437,0,[kdd,jdd])))} +function Eqd(){Eqd=geb;Dqd=ss((uqd(),cD(WC(M3,1),jwe,347,0,[sqd,tqd])))} +function Imd(){Cmd();return cD(WC(s3,1),jwe,88,0,[Amd,zmd,ymd,xmd,Bmd])} +function xpd(){qpd();return cD(WC(E3,1),NAe,64,0,[opd,Yod,Xod,npd,ppd])} +function LSd(a,b,c){return RD(b==null?rtb(a.f,null,c):Ltb(a.i,b,c),288)} +function L6b(a){return (a.k==(r3b(),p3b)||a.k==m3b)&&nQb(a,(Ywc(),cwc))} +function bUb(a){return !!a.c&&!!a.d?kUb(a.c)+'->'+kUb(a.d):'e_'+kFb(a)} +function xgb(a,b){var c,d;uFb(b);for(d=a.Kc();d.Ob();){c=d.Pb();b.Cd(c)}} +function jEd(a,b){var c;c=new uC;qDd(c,'x',b.a);qDd(c,'y',b.b);oDd(a,c)} +function mEd(a,b){var c;c=new uC;qDd(c,'x',b.a);qDd(c,'y',b.b);oDd(a,c)} +function Gsd(a,b){var c;c=b;while(c){Zid(a,-c.i,-c.j);c=vCd(c)}return a} +function ZLc(a,b){var c,d;c=b;d=0;while(c>0){d+=a.a[c];c-=c&-c}return d} +function $mb(a,b,c){var d;d=(tFb(b,a.c.length),a.c[b]);a.c[b]=c;return d} +function uIc(a,b,c){a.a.c.length=0;yIc(a,b,c);a.a.c.length==0||rIc(a,b)} +function wo(a){a.i=0;Mnb(a.b,null);Mnb(a.c,null);a.a=null;a.e=null;++a.g} +function gBb(){gBb=geb;dBb=true;bBb=false;cBb=false;fBb=false;eBb=false} +function oBb(a){gBb();if(dBb){return}this.c=a;this.e=true;this.a=new bnb} +function kDb(a,b){this.c=0;this.b=b;txb.call(this,a,17493);this.a=this.c} +function S_b(a){P_b();A$b(this);this.a=new Yub;Q_b(this,a);Mub(this.a,a)} +function m_b(){Pmb(this);this.b=new rjd(oxe,oxe);this.a=new rjd(pxe,pxe)} +function z8c(){z8c=geb;x8c=new B8c(CBe,0);y8c=new B8c('TARGET_WIDTH',1)} +function yDb(a,b){return (MCb(a),QDb(new SDb(a,new hEb(b,a.a)))).Bd(wDb)} +function vXb(){sXb();return cD(WC(UP,1),jwe,367,0,[nXb,oXb,pXb,qXb,rXb])} +function Fnc(){Bnc();return cD(WC(TV,1),jwe,375,0,[xnc,znc,Anc,ync,wnc])} +function Vtc(){Ptc();return cD(WC(bX,1),jwe,348,0,[Ltc,Ktc,Ntc,Otc,Mtc])} +function PDc(){JDc();return cD(WC(uX,1),jwe,323,0,[IDc,FDc,GDc,EDc,HDc])} +function fxc(){cxc();return cD(WC(mX,1),jwe,171,0,[bxc,Zwc,$wc,_wc,axc])} +function k3c(){g3c();return cD(WC(x0,1),jwe,368,0,[e3c,b3c,f3c,c3c,d3c])} +function vad(){sad();return cD(WC(x1,1),jwe,373,0,[oad,nad,qad,pad,rad])} +function $bd(){Xbd();return cD(WC(P1,1),jwe,324,0,[Sbd,Tbd,Wbd,Ubd,Vbd])} +function _hd(){Yhd();return cD(WC(d3,1),jwe,170,0,[Whd,Vhd,Thd,Xhd,Uhd])} +function sod(){pod();return cD(WC(B3,1),jwe,256,0,[mod,ood,kod,lod,nod])} +function Tz(b){Qz();return function(){return Uz(b,this,arguments);var a}} +function W0b(a){if(!a.c||!a.d){return false}return !!a.c.i&&a.c.i==a.d.i} +function Nfd(a,b){if(ZD(b,143)){return lhb(a.c,RD(b,143).c)}return false} +function yYd(a){if(!a.t){a.t=new w$d(a);VGd(new Cde(a),0,a.t)}return a.t} +function jNd(a){this.b=a;dMd.call(this,a);this.a=RD(Ywd(this.b.a,4),129)} +function sNd(a){this.b=a;yMd.call(this,a);this.a=RD(Ywd(this.b.a,4),129)} +function Q3d(a,b,c,d,e){OKd.call(this,b,d,e);J3d(this);this.c=a;this.b=c} +function V3d(a,b,c,d,e){KKd.call(this,b,d,e);J3d(this);this.c=a;this.a=c} +function Z3d(a,b,c,d,e){LKd.call(this,b,d,e);J3d(this);this.c=a;this.a=c} +function g4d(a,b,c,d,e){OKd.call(this,b,d,e);J3d(this);this.c=a;this.a=c} +function ugd(a,b){var c;c=RD(cub(a.d,b),23);return c?c:RD(cub(a.e,b),23)} +function Blb(a,b){var c,d;c=b.ld();d=a.Fe(c);return !!d&&Fvb(d.e,b.md())} +function me(a,b){var c;c=b.ld();return new gp(c,a.e.pc(c,RD(b.md(),16)))} +function ptb(a,b){var c;c=a.a.get(b);return c==null?$C(jJ,rve,1,0,5,1):c} +function khb(a){var b;b=a.length;return lhb(sxe.substr(sxe.length-b,b),a)} +function hs(a){if(gs(a)){a.c=a.a;return a.a.Pb()}else{throw Adb(new Dvb)}} +function $ib(a,b){if(b==0||a.e==0){return a}return b>0?tjb(a,b):qjb(a,-b)} +function Zib(a,b){if(b==0||a.e==0){return a}return b>0?qjb(a,b):tjb(a,-b)} +function Deb(a){Beb.call(this,a==null?vve:jeb(a),ZD(a,82)?RD(a,82):null)} +function Y5d(a){var b;if(!a.c){b=a.r;ZD(b,90)&&(a.c=RD(b,29))}return a.c} +function s0b(a){var b;b=new a1b;kQb(b,a);pQb(b,(yCc(),RAc),null);return b} +function lec(a){var b,c;b=a.c.i;c=a.d.i;return b.k==(r3b(),m3b)&&c.k==m3b} +function fD(a){var b,c,d;b=a&dxe;c=a>>22&dxe;d=a<0?exe:0;return hD(b,c,d)} +function Ky(a){var b,c,d,e;for(c=a,d=0,e=c.length;d=0?a.Lh(d,c,true):Qvd(a,b,c)} +function AXc(a,b,c){return Qfb(cjd(jWc(a),ajd(b.b)),cjd(jWc(a),ajd(c.b)))} +function BXc(a,b,c){return Qfb(cjd(jWc(a),ajd(b.e)),cjd(jWc(a),ajd(c.e)))} +function Kad(a,b){return $wnd.Math.min(bjd(b.a,a.d.d.c),bjd(b.b,a.d.d.c))} +function LHd(a,b){a._i(a.i+1);MHd(a,a.i,a.Zi(a.i,b));a.Mi(a.i++,b);a.Ni()} +function OHd(a){var b,c;++a.j;b=a.g;c=a.i;a.g=null;a.i=0;a.Oi(c,b);a.Ni()} +function yke(a,b,c){var d;d=new zke(a.a);Ld(d,a.a.a);rtb(d.f,b,c);a.a.a=d} +function mKb(a,b,c,d){var e;for(e=0;eb){throw Adb(new veb(Jb(a,b,'index')))}return a} +function Xmb(a,b){var c;c=(tFb(b,a.c.length),a.c[b]);$Eb(a.c,b,1);return c} +function jhb(a,b){var c,d;c=(uFb(a),a);d=(uFb(b),b);return c==d?0:cb.p){return -1}return 0} +function hXd(a){var b;if(!a.a){b=a.r;ZD(b,156)&&(a.a=RD(b,156))}return a.a} +function iOd(a,b,c){var d;++a.e;--a.f;d=RD(a.d[b].gd(c),136);return d.md()} +function fd(a){var b,c;b=a.ld();c=RD(a.md(),16);return gk(c.Nc(),new jh(b))} +function oae(a,b){if(Ujb(a.a,b)){_jb(a.a,b);return true}else{return false}} +function Ui(a,b,c){Pb(b,a.e.Rd().gc());Pb(c,a.c.Rd().gc());return a.a[b][c]} +function _Uc(a,b,c){this.a=a;this.b=b;this.c=c;Rmb(a.t,this);Rmb(b.i,this)} +function lg(a,b,c,d){this.f=a;this.e=b;this.d=c;this.b=d;this.c=!d?null:d.d} +function YWc(){this.b=new Yub;this.a=new Yub;this.b=new Yub;this.a=new Yub} +function ree(){ree=geb;var a,b;pee=(jTd(),b=new k1d,b);qee=(a=new mXd,a)} +function UCb(a){var b;MCb(a);b=new $Cb(a,a.a.e,a.a.d|4);return new WCb(a,b)} +function ADb(a){var b;LCb(a);b=0;while(a.a.Bd(new MEb)){b=Bdb(b,1)}return b} +function zxb(a,b){uFb(b);if(a.c=0,'Initial capacity must not be negative')} +function rid(){rid=geb;qid=new jGd('org.eclipse.elk.labels.labelManager')} +function iec(){iec=geb;hec=new kGd('separateLayerConnections',(vec(),uec))} +function fTc(){fTc=geb;eTc=new gTc('REGULAR',0);dTc=new gTc('CRITICAL',1)} +function Mbd(){Mbd=geb;Lbd=new Nbd('FIXED',0);Kbd=new Nbd('CENTER_NODE',1)} +function jtc(){jtc=geb;htc=new ktc('QUADRATIC',0);itc=new ktc('SCANLINE',1)} +function Atc(){Atc=geb;ztc=ss((stc(),cD(WC(_W,1),jwe,322,0,[qtc,ptc,rtc])))} +function Jtc(){Jtc=geb;Itc=ss((Etc(),cD(WC(aX,1),jwe,351,0,[Btc,Dtc,Ctc])))} +function ooc(){ooc=geb;noc=ss((joc(),cD(WC(UV,1),jwe,372,0,[ioc,hoc,goc])))} +function muc(){muc=geb;luc=ss((huc(),cD(WC(dX,1),jwe,460,0,[fuc,euc,guc])))} +function Cvc(){Cvc=geb;Bvc=ss((xvc(),cD(WC(jX,1),jwe,299,0,[vvc,wvc,uvc])))} +function Lvc(){Lvc=geb;Kvc=ss((Gvc(),cD(WC(kX,1),jwe,311,0,[Evc,Fvc,Dvc])))} +function rDc(){rDc=geb;qDc=ss((lDc(),cD(WC(sX,1),jwe,390,0,[iDc,jDc,kDc])))} +function PEc(){PEc=geb;OEc=ss((KEc(),cD(WC(zX,1),jwe,387,0,[HEc,IEc,JEc])))} +function YEc(){YEc=geb;XEc=ss((TEc(),cD(WC(AX,1),jwe,349,0,[SEc,QEc,REc])))} +function GEc(){GEc=geb;FEc=ss((BEc(),cD(WC(yX,1),jwe,463,0,[AEc,yEc,zEc])))} +function qFc(){qFc=geb;pFc=ss((lFc(),cD(WC(CX,1),jwe,350,0,[iFc,jFc,kFc])))} +function zFc(){zFc=geb;yFc=ss((uFc(),cD(WC(DX,1),jwe,352,0,[tFc,rFc,sFc])))} +function IFc(){IFc=geb;HFc=ss((DFc(),cD(WC(EX,1),jwe,388,0,[BFc,CFc,AFc])))} +function QZc(){QZc=geb;PZc=ss((LZc(),cD(WC(F_,1),jwe,392,0,[KZc,JZc,IZc])))} +function m4c(){m4c=geb;l4c=ss((g4c(),cD(WC(I0,1),jwe,393,0,[d4c,e4c,f4c])))} +function z5c(){z5c=geb;y5c=ss((t5c(),cD(WC(N0,1),jwe,300,0,[r5c,s5c,q5c])))} +function k6c(){k6c=geb;j6c=ss((f6c(),cD(WC(V0,1),jwe,445,0,[c6c,d6c,e6c])))} +function F6c(){F6c=geb;E6c=ss((z6c(),cD(WC(Z0,1),jwe,456,0,[w6c,y6c,x6c])))} +function e7c(){e7c=geb;d7c=ss((_6c(),cD(WC(a1,1),jwe,394,0,[Z6c,$6c,Y6c])))} +function j9c(){j9c=geb;i9c=ss((b9c(),cD(WC(o1,1),jwe,439,0,[$8c,a9c,_8c])))} +function WKc(){WKc=geb;VKc=ss((RKc(),cD(WC(nY,1),jwe,464,0,[OKc,PKc,QKc])))} +function JKb(){JKb=geb;IKb=ss((EKb(),cD(WC(MN,1),jwe,471,0,[CKb,BKb,DKb])))} +function cKb(){cKb=geb;bKb=ss((ZJb(),cD(WC(JN,1),jwe,237,0,[WJb,XJb,YJb])))} +function ALb(){ALb=geb;zLb=ss((vLb(),cD(WC(TN,1),jwe,472,0,[uLb,tLb,sLb])))} +function CBb(){CBb=geb;BBb=ss((xBb(),cD(WC(QL,1),jwe,108,0,[uBb,vBb,wBb])))} +function FWb(){FWb=geb;EWb=ss((AWb(),cD(WC(JP,1),jwe,391,0,[yWb,xWb,zWb])))} +function Knd(){Knd=geb;Jnd=ss((Fnd(),cD(WC(y3,1),jwe,346,0,[Dnd,Cnd,End])))} +function lbd(){lbd=geb;kbd=ss((gbd(),cD(WC(I1,1),jwe,444,0,[dbd,ebd,fbd])))} +function Tmd(){Tmd=geb;Smd=ss((Omd(),cD(WC(t3,1),jwe,278,0,[Lmd,Mmd,Nmd])))} +function rqd(){rqd=geb;qqd=ss((mqd(),cD(WC(J3,1),jwe,280,0,[kqd,jqd,lqd])))} +function Hxd(a,b){return !a.o&&(a.o=new DVd((pvd(),mvd),X4,a,0)),QNd(a.o,b)} +function HMb(a,b){var c;if(a.C){c=RD(Vrb(a.b,b),127).n;c.d=a.C.d;c.a=a.C.a}} +function F8b(a){var b,c,d,e;e=a.d;b=a.a;c=a.b;d=a.c;a.d=c;a.a=d;a.b=e;a.c=b} +function cOd(a){!a.g&&(a.g=new hQd);!a.g.b&&(a.g.b=new ePd(a));return a.g.b} +function dOd(a){!a.g&&(a.g=new hQd);!a.g.c&&(a.g.c=new IPd(a));return a.g.c} +function lOd(a){!a.g&&(a.g=new hQd);!a.g.d&&(a.g.d=new kPd(a));return a.g.d} +function YNd(a){!a.g&&(a.g=new hQd);!a.g.a&&(a.g.a=new qPd(a));return a.g.a} +function B9d(a,b,c,d){!!c&&(d=c.Rh(b,BYd(c.Dh(),a.c.uk()),null,d));return d} +function C9d(a,b,c,d){!!c&&(d=c.Th(b,BYd(c.Dh(),a.c.uk()),null,d));return d} +function Cjb(a,b,c,d){var e;e=$C(kE,Pwe,28,b+1,15,1);Djb(e,a,b,c,d);return e} +function $C(a,b,c,d,e,f){var g;g=_C(e,d);e!=10&&cD(WC(a,f),b,c,e,g);return g} +function $fe(a,b,c){var d,e;e=new Phe(b,a);for(d=0;dc||b=0?a.Lh(c,true,true):Qvd(a,b,true)} +function gMc(a,b,c){var d;d=qMc(a,b,c);a.b=new _Lc(d.c.length);return iMc(a,d)} +function Pue(a){if(a.b<=0)throw Adb(new Dvb);--a.b;a.a-=a.c.c;return sgb(a.a)} +function PGd(a){var b;if(!a.a){throw Adb(new Evb)}b=a.a;a.a=vCd(a.a);return b} +function WDb(a){while(!a.a){if(!yEb(a.c,new $Db(a))){return false}}return true} +function Nr(a){var b;Qb(a);if(ZD(a,204)){b=RD(a,204);return b}return new Or(a)} +function Cfd(a){Afd();RD(a.of((umd(),Lld)),181).Fc((Pod(),Mod));a.qf(Kld,null)} +function Afd(){Afd=geb;xfd=new Gfd;zfd=new Ifd;yfd=yn((umd(),Kld),xfd,pld,zfd)} +function Y3c(){Y3c=geb;W3c=new $3c('LEAF_NUMBER',0);X3c=new $3c('NODE_SIZE',1)} +function YLc(a){a.a=$C(kE,Pwe,28,a.b+1,15,1);a.c=$C(kE,Pwe,28,a.b,15,1);a.d=0} +function OZb(a,b){if(a.a.Ne(b.d,a.b)>0){Rmb(a.c,new fZb(b.c,b.d,a.d));a.b=b.d}} +function NHd(a,b){if(a.g==null||b>=a.i)throw Adb(new yNd(b,a.i));return a.g[b]} +function P_d(a,b,c){gHd(a,c);if(c!=null&&!a.fk(c)){throw Adb(new yeb)}return c} +function dD(a,b){XC(b)!=10&&cD(rb(b),b.Sm,b.__elementTypeId$,XC(b),a);return a} +function Wnb(a,b,c,d){var e;d=(urb(),!d?rrb:d);e=a.slice(b,c);Xnb(e,a,b,c,-b,d)} +function zvd(a,b,c,d,e){return b<0?Qvd(a,c,d):RD(c,69).wk().yk(a,a.hi(),b,d,e)} +function J9b(a,b){return Qfb(Kfb(UD(mQb(a,(Ywc(),Jwc)))),Kfb(UD(mQb(b,Jwc))))} +function qAb(){qAb=geb;pAb=ss((cAb(),cD(WC(AL,1),jwe,304,0,[$zb,_zb,aAb,bAb])))} +function cAb(){cAb=geb;$zb=new dAb('All',0);_zb=new iAb;aAb=new kAb;bAb=new nAb} +function EKb(){EKb=geb;CKb=new FKb(Nye,0);BKb=new FKb(Kye,1);DKb=new FKb(Oye,2)} +function Zme(){Zme=geb;qAd();Wme=oxe;Vme=pxe;Yme=new Tfb(oxe);Xme=new Tfb(pxe)} +function rOb(){rOb=geb;qOb=ss((mOb(),cD(WC(hO,1),jwe,417,0,[lOb,iOb,jOb,kOb])))} +function NRb(){NRb=geb;MRb=ss((IRb(),cD(WC(WO,1),jwe,406,0,[FRb,ERb,GRb,HRb])))} +function NPb(){NPb=geb;MPb=ss((IPb(),cD(WC(DO,1),jwe,332,0,[FPb,EPb,GPb,HPb])))} +function Z$b(){Z$b=geb;Y$b=ss((U$b(),cD(WC(CQ,1),jwe,389,0,[T$b,R$b,Q$b,S$b])))} +function wZb(){wZb=geb;vZb=ss((nZb(),cD(WC(lQ,1),jwe,416,0,[jZb,mZb,kZb,lZb])))} +function jnc(){jnc=geb;inc=ss((enc(),cD(WC(LV,1),jwe,421,0,[anc,bnc,cnc,dnc])))} +function Bec(){Bec=geb;Aec=ss((vec(),cD(WC(qT,1),jwe,371,0,[uec,sec,tec,rec])))} +function DDc(){DDc=geb;CDc=ss((wDc(),cD(WC(tX,1),jwe,203,0,[uDc,vDc,tDc,sDc])))} +function pEc(){pEc=geb;oEc=ss((kEc(),cD(WC(wX,1),jwe,284,0,[hEc,gEc,iEc,jEc])))} +function Cuc(){Cuc=geb;Buc=new Duc(LAe,0);Auc=new Duc('IMPROVE_STRAIGHTNESS',1)} +function _i(a,b){var c,d;d=b/a.c.Rd().gc()|0;c=b%a.c.Rd().gc();return Ui(a,d,c)} +function iZd(a){var b;if(a.nl()){for(b=a.i-1;b>=0;--b){QHd(a,b)}}return WHd(a)} +function Nyb(a){var b,c;if(!a.b){return null}c=a.b;while(b=c.a[0]){c=b}return c} +function Oyb(a){var b,c;if(!a.b){return null}c=a.b;while(b=c.a[1]){c=b}return c} +function Hae(a){if(ZD(a,180)){return ''+RD(a,180).a}return a==null?null:jeb(a)} +function Iae(a){if(ZD(a,180)){return ''+RD(a,180).a}return a==null?null:jeb(a)} +function eGb(a,b){if(b.a){throw Adb(new yz(jye))}Ysb(a.a,b);b.a=a;!a.j&&(a.j=b)} +function hEb(a,b){xxb.call(this,b.zd(),b.yd()&-16449);uFb(a);this.a=a;this.c=b} +function zXc(a,b){return new gud(b,Zid(ajd(b.e),b.f.a+a,b.f.b+a),(Geb(),false))} +function EMc(a,b){dMc();return Rmb(a,new Ptd(b,sgb(b.e.c.length+b.g.c.length)))} +function GMc(a,b){dMc();return Rmb(a,new Ptd(b,sgb(b.e.c.length+b.g.c.length)))} +function p5c(){p5c=geb;o5c=ss((j5c(),cD(WC(M0,1),jwe,354,0,[i5c,g5c,h5c,f5c])))} +function x_c(){x_c=geb;w_c=ss((s_c(),cD(WC(J_,1),jwe,353,0,[r_c,p_c,q_c,o_c])))} +function eWc(){eWc=geb;dWc=ss((YVc(),cD(WC(H$,1),jwe,405,0,[UVc,VVc,WVc,XVc])))} +function bnd(){bnd=geb;and=ss((Ymd(),cD(WC(u3,1),jwe,223,0,[Xmd,Vmd,Umd,Wmd])))} +function Vnd(){Vnd=geb;Und=ss((Pnd(),cD(WC(z3,1),jwe,291,0,[Ond,Lnd,Mnd,Nnd])))} +function Vpd(){Vpd=geb;Upd=ss((Qpd(),cD(WC(H3,1),jwe,386,0,[Opd,Ppd,Npd,Mpd])))} +function Lrd(){Lrd=geb;Krd=ss((Grd(),cD(WC(R3,1),jwe,320,0,[Frd,Crd,Erd,Drd])))} +function ytd(){ytd=geb;xtd=ss((ttd(),cD(WC(n4,1),jwe,415,0,[qtd,rtd,ptd,std])))} +function b9c(){b9c=geb;$8c=new d9c(iFe,0);a9c=new d9c(mEe,1);_8c=new d9c(LAe,2)} +function sBb(a,b,c,d,e){uFb(a);uFb(b);uFb(c);uFb(d);uFb(e);return new DBb(a,b,d)} +function fub(a,b){var c;c=RD(_jb(a.e,b),400);if(c){rub(c);return c.e}return null} +function Ymb(a,b){var c;c=Wmb(a,b,0);if(c==-1){return false}Xmb(a,c);return true} +function LDb(a,b,c){var d;LCb(a);d=new IEb;d.a=b;a.a.Nb(new QEb(d,c));return d.a} +function VCb(a){var b;LCb(a);b=$C(iE,vxe,28,0,15,1);ixb(a.a,new dDb(b));return b} +function yc(a){var b;if(!xc(a)){throw Adb(new Dvb)}a.e=1;b=a.d;a.d=null;return b} +function Odb(a){var b;if(Kdb(a)){b=0-a;if(!isNaN(b)){return b}}return Edb(xD(a))} +function Wmb(a,b,c){for(;c=0?Dvd(a,c,true,true):Qvd(a,b,true)} +function Vwd(a){var b;b=SD(Ywd(a,32));if(b==null){Wwd(a);b=SD(Ywd(a,32))}return b} +function Yvd(a){var b;if(!a.Oh()){b=AYd(a.Dh())-a.ji();a.$h().Mk(b)}return a.zh()} +function zQb(a,b){yQb=new kRb;wQb=b;xQb=a;RD(xQb.b,68);BQb(xQb,yQb,null);AQb(xQb)} +function AWb(){AWb=geb;yWb=new BWb('XY',0);xWb=new BWb('X',1);zWb=new BWb('Y',2)} +function vLb(){vLb=geb;uLb=new wLb('TOP',0);tLb=new wLb(Kye,1);sLb=new wLb(Qye,2)} +function Gvc(){Gvc=geb;Evc=new Hvc(LAe,0);Fvc=new Hvc('TOP',1);Dvc=new Hvc(Qye,2)} +function sEc(){sEc=geb;qEc=new tEc('INPUT_ORDER',0);rEc=new tEc('PORT_DEGREE',1)} +function MD(){MD=geb;ID=hD(dxe,dxe,524287);JD=hD(0,0,fxe);KD=fD(1);fD(2);LD=fD(0)} +function wWd(a){var b;if(a.d!=a.r){b=WVd(a);a.e=!!b&&b.lk()==aKe;a.d=b}return a.e} +function UHd(a,b,c){var d;d=a.g[b];MHd(a,b,a.Zi(b,c));a.Ri(b,c,d);a.Ni();return d} +function dHd(a,b){var c;c=a.dd(b);if(c>=0){a.gd(c);return true}else{return false}} +function xr(a,b){var c;Qb(a);Qb(b);c=false;while(b.Ob()){c=c|a.Fc(b.Pb())}return c} +function cub(a,b){var c;c=RD(Wjb(a.e,b),400);if(c){eub(a,c);return c.e}return null} +function iB(a){var b,c;b=a/60|0;c=a%60;if(c==0){return ''+b}return ''+b+':'+(''+c)} +function JB(d,a){var b=d.a[a];var c=(HC(),GC)[typeof b];return c?c(b):NC(typeof b)} +function EDb(a,b){var c,d;MCb(a);d=new zEb(b,a.a);c=new YDb(d);return new SDb(a,c)} +function mwb(a){var b;b=a.b.c.length==0?null:Vmb(a.b,0);b!=null&&owb(a,0);return b} +function ukc(a,b){var c,d,e;e=b.c.i;c=RD(Wjb(a.f,e),60);d=c.d.c-c.e.c;Bjd(b.a,d,0)} +function XLc(a,b){var c;++a.d;++a.c[b];c=b+1;while(c=0){++b[0]}} +function eEd(a,b){Dyd(a,b==null||Rfb((uFb(b),b))||isNaN((uFb(b),b))?0:(uFb(b),b))} +function fEd(a,b){Eyd(a,b==null||Rfb((uFb(b),b))||isNaN((uFb(b),b))?0:(uFb(b),b))} +function gEd(a,b){Cyd(a,b==null||Rfb((uFb(b),b))||isNaN((uFb(b),b))?0:(uFb(b),b))} +function hEd(a,b){Ayd(a,b==null||Rfb((uFb(b),b))||isNaN((uFb(b),b))?0:(uFb(b),b))} +function oWc(a,b,c){return cjd(new rjd(c.e.a+c.f.a/2,c.e.b+c.f.b/2),a)==(uFb(b),b)} +function qge(a,b){return ZD(b,102)&&(RD(b,19).Bb&txe)!=0?new She(b,a):new Phe(b,a)} +function sge(a,b){return ZD(b,102)&&(RD(b,19).Bb&txe)!=0?new She(b,a):new Phe(b,a)} +function XC(a){return a.__elementTypeCategory$==null?10:a.__elementTypeCategory$} +function Bhb(a,b){return b==(wvb(),wvb(),vvb)?a.toLocaleLowerCase():a.toLowerCase()} +function Mu(a){if(!a.e){throw Adb(new Dvb)}a.c=a.a=a.e;a.e=a.e.e;--a.d;return a.a.f} +function Lu(a){if(!a.c){throw Adb(new Dvb)}a.e=a.a=a.c;a.c=a.c.c;++a.d;return a.a.f} +function Lsb(a){var b;++a.a;for(b=a.c.a.length;a.aa.a[d]&&(d=c)}return d} +function Krc(a){var b;b=RD(mQb(a,(Ywc(),Wvc)),313);if(b){return b.a==a}return false} +function Lrc(a){var b;b=RD(mQb(a,(Ywc(),Wvc)),313);if(b){return b.i==a}return false} +function xXb(){xXb=geb;wXb=ss((sXb(),cD(WC(UP,1),jwe,367,0,[nXb,oXb,pXb,qXb,rXb])))} +function Hnc(){Hnc=geb;Gnc=ss((Bnc(),cD(WC(TV,1),jwe,375,0,[xnc,znc,Anc,ync,wnc])))} +function Xtc(){Xtc=geb;Wtc=ss((Ptc(),cD(WC(bX,1),jwe,348,0,[Ltc,Ktc,Ntc,Otc,Mtc])))} +function RDc(){RDc=geb;QDc=ss((JDc(),cD(WC(uX,1),jwe,323,0,[IDc,FDc,GDc,EDc,HDc])))} +function hxc(){hxc=geb;gxc=ss((cxc(),cD(WC(mX,1),jwe,171,0,[bxc,Zwc,$wc,_wc,axc])))} +function m3c(){m3c=geb;l3c=ss((g3c(),cD(WC(x0,1),jwe,368,0,[e3c,b3c,f3c,c3c,d3c])))} +function xad(){xad=geb;wad=ss((sad(),cD(WC(x1,1),jwe,373,0,[oad,nad,qad,pad,rad])))} +function acd(){acd=geb;_bd=ss((Xbd(),cD(WC(P1,1),jwe,324,0,[Sbd,Tbd,Wbd,Ubd,Vbd])))} +function Kmd(){Kmd=geb;Jmd=ss((Cmd(),cD(WC(s3,1),jwe,88,0,[Amd,zmd,ymd,xmd,Bmd])))} +function bid(){bid=geb;aid=ss((Yhd(),cD(WC(d3,1),jwe,170,0,[Whd,Vhd,Thd,Xhd,Uhd])))} +function uod(){uod=geb;tod=ss((pod(),cD(WC(B3,1),jwe,256,0,[mod,ood,kod,lod,nod])))} +function zpd(){zpd=geb;ypd=ss((qpd(),cD(WC(E3,1),NAe,64,0,[opd,Yod,Xod,npd,ppd])))} +function LHb(){LHb=geb;JHb=new MHb('BY_SIZE',0);KHb=new MHb('BY_SIZE_AND_SHAPE',1)} +function TUb(){TUb=geb;RUb=new UUb('EADES',0);SUb=new UUb('FRUCHTERMAN_REINGOLD',1)} +function $tc(){$tc=geb;Ytc=new _tc('READING_DIRECTION',0);Ztc=new _tc('ROTATION',1)} +function CZb(){CZb=geb;zZb=new ZZb;AZb=new b$b;xZb=new f$b;yZb=new j$b;BZb=new n$b} +function dGb(a){this.b=new bnb;this.a=new bnb;this.c=new bnb;this.d=new bnb;this.e=a} +function XZb(a){this.g=a;this.f=new bnb;this.a=$wnd.Math.min(this.g.c.c,this.g.d.c)} +function UKb(a,b,c){RJb.call(this);KKb(this);this.a=a;this.c=c;this.b=b.d;this.f=b.e} +function d6b(a,b,c){var d,e;for(e=new Anb(c);e.a=0&&b0?b-1:b;return Kqd(Lqd(Mqd(Nqd(new Oqd,c),a.n),a.j),a.k)} +function nBd(a){var b,c;c=(b=new q4d,b);WGd((!a.q&&(a.q=new C5d(s7,a,11,10)),a.q),c)} +function ofb(a){return ((a.i&2)!=0?'interface ':(a.i&1)!=0?'':'class ')+(lfb(a),a.o)} +function dz(a){if(Ddb(a,lve)>0){return lve}if(Ddb(a,qwe)<0){return qwe}return Ydb(a)} +function Sv(a){if(a<3){dk(a,fwe);return a+1}if(a=-0.01&&a.a<=Tye&&(a.a=0);a.b>=-0.01&&a.b<=Tye&&(a.b=0);return a} +function Hid(a){tid();var b,c;c=KEe;for(b=0;bc&&(c=a[b])}return c} +function Zvd(a,b){var c;c=wYd(a.Dh(),b);if(!c){throw Adb(new agb(KHe+b+NHe))}return c} +function NGd(a,b){var c;c=a;while(vCd(c)){c=vCd(c);if(c==b){return true}}return false} +function ix(a,b){var c,d,e;d=b.a.ld();c=RD(b.a.md(),16).gc();for(e=0;ea||a>b){throw Adb(new xeb('fromIndex: 0, toIndex: '+a+Qxe+b))}} +function ZHd(a){if(a<0){throw Adb(new agb('Illegal Capacity: '+a))}this.g=this.aj(a)} +function _y(a,b){Zy();bz(pwe);return $wnd.Math.abs(a-b)<=pwe||a==b||isNaN(a)&&isNaN(b)} +function xJc(a,b){var c,d,e,f;for(d=a.d,e=0,f=d.length;e0){a.a/=b;a.b/=b}return a} +function BXd(a){var b;if(a.w){return a.w}else{b=CXd(a);!!b&&!b.Vh()&&(a.w=b);return b}} +function l2d(a,b){var c,d;d=a.a;c=m2d(a,b,null);d!=b&&!a.e&&(c=o2d(a,b,c));!!c&&c.oj()} +function rQc(a,b,c){var d,e;d=b;do{e=Kfb(a.p[d.p])+c;a.p[d.p]=e;d=a.a[d.p]}while(d!=b)} +function heb(a,b,c){var d=function(){return a.apply(d,arguments)};b.apply(d,c);return d} +function Gae(a){var b;if(a==null){return null}else{b=RD(a,195);return sAd(b,b.length)}} +function QHd(a,b){if(a.g==null||b>=a.i)throw Adb(new yNd(b,a.i));return a.Wi(b,a.g[b])} +function Dob(a,b){yob();var c,d;d=new bnb;for(c=0;c=14&&b<=16)));return a} +function ws(a,b){var c;uFb(b);c=a[':'+b];mFb(!!c,'Enum constant undefined: '+b);return c} +function tfb(a,b,c,d,e,f){var g;g=rfb(a,b);Ffb(c,g);g.i=e?8:0;g.f=d;g.e=e;g.g=f;return g} +function R3d(a,b,c,d,e){this.d=b;this.k=d;this.f=e;this.o=-1;this.p=1;this.c=a;this.a=c} +function T3d(a,b,c,d,e){this.d=b;this.k=d;this.f=e;this.o=-1;this.p=2;this.c=a;this.a=c} +function _3d(a,b,c,d,e){this.d=b;this.k=d;this.f=e;this.o=-1;this.p=6;this.c=a;this.a=c} +function e4d(a,b,c,d,e){this.d=b;this.k=d;this.f=e;this.o=-1;this.p=7;this.c=a;this.a=c} +function X3d(a,b,c,d,e){this.d=b;this.j=d;this.e=e;this.o=-1;this.p=4;this.c=a;this.a=c} +function iGb(a,b){var c,d,e,f;for(d=b,e=0,f=d.length;e=0)){throw Adb(new agb('tolerance ('+a+') must be >= 0'))}return a} +function hOd(a,b){var c;if(ZD(b,44)){return a.c.Mc(b)}else{c=QNd(a,b);jOd(a,b);return c}} +function yBd(a,b,c){YVd(a,b);PAd(a,c);$Vd(a,0);bWd(a,1);aWd(a,true);_Vd(a,true);return a} +function ZGd(a,b){var c;c=a.gc();if(b<0||b>c)throw Adb(new aMd(b,c));return new CMd(a,b)} +function Cad(a,b){a.b=$wnd.Math.max(a.b,b.d);a.e+=b.r+(a.a.c.length==0?0:a.c);Rmb(a.a,b)} +function Jmb(a){yFb(a.c>=0);if(rmb(a.d,a.c)<0){a.a=a.a-1&a.d.a.length-1;a.b=a.d.c}a.c=-1} +function Nc(a){var b,c;for(c=a.c.Cc().Kc();c.Ob();){b=RD(c.Pb(),16);b.$b()}a.c.$b();a.d=0} +function Zi(a){var b,c,d,e;for(c=a.a,d=0,e=c.length;d=0} +function Iqd(a,b){if(a.r>0&&a.c0&&a.g!=0&&Iqd(a.i,b/a.r*a.i.d)}} +function $Cd(a,b){var c;c=a.c;a.c=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,1,c,a.c))} +function P1d(a,b){var c;c=a.c;a.c=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,4,c,a.c))} +function jyd(a,b){var c;c=a.k;a.k=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,2,c,a.k))} +function JXd(a,b){var c;c=a.D;a.D=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,2,c,a.D))} +function Kzd(a,b){var c;c=a.f;a.f=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,8,c,a.f))} +function Lzd(a,b){var c;c=a.i;a.i=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,7,c,a.i))} +function fCd(a,b){var c;c=a.a;a.a=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,8,c,a.a))} +function ZCd(a,b){var c;c=a.b;a.b=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,0,c,a.b))} +function s6d(a,b){var c;c=a.b;a.b=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,0,c,a.b))} +function t6d(a,b){var c;c=a.c;a.c=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,1,c,a.c))} +function nVd(a,b){var c;c=a.d;a.d=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,1,c,a.d))} +function Cte(a,b,c){var d;a.b=b;a.a=c;d=(a.a&512)==512?new Gre:new Tqe;a.c=Nqe(d,a.b,a.a)} +function Gge(a,b){return qke(a.e,b)?(nke(),wWd(b)?new ole(b,a):new Eke(b,a)):new Ble(b,a)} +function iDb(a){var b,c;if(0>a){return new rDb}b=a+1;c=new kDb(b,a);return new oDb(null,c)} +function Gob(a,b){yob();var c;c=new Usb(1);bE(a)?$jb(c,a,b):rtb(c.f,a,b);return new uqb(c)} +function pQc(a,b){var c,d;c=a.c;d=b.e[a.p];if(d>0){return RD(Vmb(c.a,d-1),10)}return null} +function TOb(a,b){var c,d;c=a.o+a.p;d=b.o+b.p;if(cb){b<<=1;return b>0?b:hwe}return b} +function xc(a){Ub(a.e!=3);switch(a.e){case 2:return false;case 0:return true;}return zc(a)} +function djd(a,b){var c;if(ZD(b,8)){c=RD(b,8);return a.a==c.a&&a.b==c.b}else{return false}} +function Ydd(a,b){var c;c=new kRb;RD(b.b,68);RD(b.b,68);RD(b.b,68);Umb(b.a,new ced(a,c,b))} +function gOd(a,b){var c,d;for(d=b.vc().Kc();d.Ob();){c=RD(d.Pb(),44);fOd(a,c.ld(),c.md())}} +function Jzd(a,b){var c;c=a.d;a.d=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,11,c,a.d))} +function zWd(a,b){var c;c=a.j;a.j=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,13,c,a.j))} +function b6d(a,b){var c;c=a.b;a.b=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,21,c,a.b))} +function YAb(a,b){((gBb(),dBb)?null:b.c).length==0&&iBb(b,new rBb);$jb(a.a,dBb?null:b.c,b)} +function b9b(a,b){b.Ug('Hierarchical port constraint processing',1);c9b(a);e9b(a);b.Vg()} +function joc(){joc=geb;ioc=new koc('START',0);hoc=new koc('MIDDLE',1);goc=new koc('END',2)} +function x2c(){x2c=geb;v2c=new z2c('P1_NODE_PLACEMENT',0);w2c=new z2c('P2_EDGE_ROUTING',1)} +function JVb(){JVb=geb;HVb=new jGd(rAe);IVb=new jGd(sAe);GVb=new jGd(tAe);FVb=new jGd(uAe)} +function tkb(a){var b;rFb(a.f.g,a.d);sFb(a.b);a.c=a.a;b=RD(a.a.Pb(),44);a.b=skb(a);return b} +function P2d(a){var b;if(a.b==null){return j3d(),j3d(),i3d}b=a.ul()?a.tl():a.sl();return b} +function nwb(a,b){var c;c=b==null?-1:Wmb(a.b,b,0);if(c<0){return false}owb(a,c);return true} +function zsb(a,b){var c;uFb(b);c=b.g;if(!a.b[c]){bD(a.b,c,b);++a.c;return true}return false} +function azb(a,b){var c,d;c=1-b;d=a.a[c];a.a[c]=d.a[b];d.a[b]=a;a.b=true;d.b=false;return d} +function xRb(a,b){var c,d;for(d=b.Kc();d.Ob();){c=RD(d.Pb(),272);a.b=true;Ysb(a.e,c);c.b=a}} +function kic(a,b){var c,d;c=RD(mQb(a,(yCc(),IBc)),8);d=RD(mQb(b,IBc),8);return Qfb(c.b,d.b)} +function SPb(a,b,c){var d,e,f;f=b>>5;e=b&31;d=Cdb(Udb(a.n[c][f],Ydb(Sdb(e,1))),3);return d} +function lmb(a,b,c){var d,e,f;f=a.a.length-1;for(e=a.b,d=0;d0?1:0}return (!a.c&&(a.c=ojb(Hdb(a.f))),a.c).e} +function GXd(a,b){if(b){if(a.B==null){a.B=a.D;a.D=null}}else if(a.B!=null){a.D=a.B;a.B=null}} +function rZb(a,b){nZb();return a==jZb&&b==mZb||a==mZb&&b==jZb||a==lZb&&b==kZb||a==kZb&&b==lZb} +function sZb(a,b){nZb();return a==jZb&&b==kZb||a==jZb&&b==lZb||a==mZb&&b==lZb||a==mZb&&b==kZb} +function zMb(a,b){return Zy(),bz(Tye),$wnd.Math.abs(0-b)<=Tye||0==b||isNaN(0)&&isNaN(b)?0:a/b} +function qsc(a,b){return Kfb(UD(Lvb(MDb(GDb(new SDb(null,new Swb(a.c.b,16)),new Isc(a)),b))))} +function tsc(a,b){return Kfb(UD(Lvb(MDb(GDb(new SDb(null,new Swb(a.c.b,16)),new Gsc(a)),b))))} +function rvc(){ovc();return cD(WC(iX,1),jwe,259,0,[fvc,hvc,ivc,jvc,kvc,lvc,nvc,evc,gvc,mvc])} +function dEc(){aEc();return cD(WC(vX,1),jwe,243,0,[$Dc,VDc,YDc,WDc,XDc,SDc,ZDc,_Dc,TDc,UDc])} +function z3c(a,b){var c;b.Ug('General Compactor',1);c=h4c(RD(Gxd(a,($4c(),I4c)),393));c.Cg(a)} +function T5c(a,b){var c,d;c=RD(Gxd(a,($4c(),P4c)),17);d=RD(Gxd(b,P4c),17);return hgb(c.a,d.a)} +function Bjd(a,b,c){var d,e;for(e=Sub(a,0);e.b!=e.d.c;){d=RD(evb(e),8);d.a+=b;d.b+=c}return a} +function Go(a,b,c){var d;for(d=a.b[c&a.f];d;d=d.b){if(c==d.a&&Hb(b,d.g)){return d}}return null} +function Ho(a,b,c){var d;for(d=a.c[c&a.f];d;d=d.d){if(c==d.f&&Hb(b,d.i)){return d}}return null} +function sjb(a,b,c){var d,e,f;d=0;for(e=0;e>>31}d!=0&&(a[c]=d)} +function yzb(a,b,c,d,e,f){var g;this.c=a;g=new bnb;Syb(a,g,b,a.b,c,d,e,f);this.a=new Jkb(g,0)} +function _5c(){this.c=new T2c(0);this.b=new T2c(FEe);this.d=new T2c(EEe);this.a=new T2c(Gze)} +function kMb(a,b,c,d,e,f,g){qs.call(this,a,b);this.d=c;this.e=d;this.c=e;this.b=f;this.a=dv(g)} +function tBd(a,b,c,d,e,f,g,h,i,j,k,l,m){ABd(a,b,c,d,e,f,g,h,i,j,k,l,m);kXd(a,false);return a} +function H0b(a){if(a.b.c.i.k==(r3b(),m3b)){return RD(mQb(a.b.c.i,(Ywc(),Awc)),12)}return a.b.c} +function I0b(a){if(a.b.d.i.k==(r3b(),m3b)){return RD(mQb(a.b.d.i,(Ywc(),Awc)),12)}return a.b.d} +function nDb(a){var b;b=mDb(a);if(Gdb(b.a,0)){return bwb(),bwb(),awb}return bwb(),new ewb(b.b)} +function SCb(a){var b;b=RCb(a);if(Gdb(b.a,0)){return Tvb(),Tvb(),Svb}return Tvb(),new Yvb(b.b)} +function TCb(a){var b;b=RCb(a);if(Gdb(b.a,0)){return Tvb(),Tvb(),Svb}return Tvb(),new Yvb(b.c)} +function o8b(a){switch(a.g){case 2:return qpd(),ppd;case 4:return qpd(),Xod;default:return a;}} +function p8b(a){switch(a.g){case 1:return qpd(),npd;case 3:return qpd(),Yod;default:return a;}} +function C9c(a){switch(a.g){case 0:return new s9c;case 1:return new x9c;default:return null;}} +function Zcc(){Zcc=geb;Ycc=new kGd('edgelabelcenterednessanalysis.includelabel',(Geb(),Eeb))} +function jKc(){jKc=geb;iKc=mfd(qfd(pfd(pfd(new ufd,(sXb(),pXb),(hcc(),Qbc)),qXb,Gbc),rXb),Pbc)} +function DLc(){DLc=geb;CLc=mfd(qfd(pfd(pfd(new ufd,(sXb(),pXb),(hcc(),Qbc)),qXb,Gbc),rXb),Pbc)} +function lYd(){lYd=geb;iYd=new i1d;kYd=cD(WC(y7,1),lKe,179,0,[]);jYd=cD(WC(s7,1),mKe,62,0,[])} +function P8b(){P8b=geb;O8b=new Q8b('TO_INTERNAL_LTR',0);N8b=new Q8b('TO_INPUT_DIRECTION',1)} +function J3b(){J3b=geb;G3b=new r4b;E3b=new w4b;F3b=new A4b;D3b=new E4b;H3b=new I4b;I3b=new M4b} +function Cac(a,b){b.Ug(iBe,1);LJb(KJb(new PJb((i1b(),new t1b(a,false,false,new _1b)))));b.Vg()} +function M_c(a,b,c){c.Ug('DFS Treeifying phase',1);L_c(a,b);J_c(a,b);a.a=null;a.b=null;c.Vg()} +function Leb(a,b){Geb();return bE(a)?jhb(a,WD(b)):_D(a)?Jfb(a,UD(b)):$D(a)?Ieb(a,TD(b)):a.Fd(b)} +function Ld(a,b){var c,d;uFb(b);for(d=b.vc().Kc();d.Ob();){c=RD(d.Pb(),44);a.zc(c.ld(),c.md())}} +function ege(a,b,c){var d;for(d=c.Kc();d.Ob();){if(!cge(a,b,d.Pb())){return false}}return true} +function S6d(a,b,c,d,e){var f;if(c){f=BYd(b.Dh(),a.c);e=c.Rh(b,-1-(f==-1?d:f),null,e)}return e} +function T6d(a,b,c,d,e){var f;if(c){f=BYd(b.Dh(),a.c);e=c.Th(b,-1-(f==-1?d:f),null,e)}return e} +function Uib(a){var b;if(a.b==-2){if(a.e==0){b=-1}else{for(b=0;a.a[b]==0;b++);}a.b=b}return a.b} +function fjb(a){uFb(a);if(a.length==0){throw Adb(new Vgb('Zero length BigInteger'))}mjb(this,a)} +function $Hd(a){this.i=a.gc();if(this.i>0){this.g=this.aj(this.i+(this.i/8|0)+1);a.Qc(this.g)}} +function dmc(a,b,c){this.g=a;this.d=b;this.e=c;this.a=new bnb;bmc(this);yob();_mb(this.a,null)} +function aad(a,b){b.q=a;a.d=$wnd.Math.max(a.d,b.r);a.b+=b.d+(a.a.c.length==0?0:a.c);Rmb(a.a,b)} +function xid(a,b){var c,d,e,f;e=a.c;c=a.c+a.b;f=a.d;d=a.d+a.a;return b.a>e&&b.af&&b.be?(c=e):BFb(b,c+1);a.a=zhb(a.a,0,b)+(''+d)+yhb(a.a,c)} +function ktb(a,b){a.a=Bdb(a.a,1);a.c=$wnd.Math.min(a.c,b);a.b=$wnd.Math.max(a.b,b);a.d=Bdb(a.d,b)} +function wdc(a,b){return b1||a.Ob()){++a.a;a.g=0;b=a.i;a.Ob();return b}else{throw Adb(new Dvb)}} +function GRc(a){switch(a.a.g){case 1:return new lSc;case 3:return new VUc;default:return new WRc;}} +function fyd(a,b){switch(b){case 1:return !!a.n&&a.n.i!=0;case 2:return a.k!=null;}return Cxd(a,b)} +function Hdb(a){if(jxe>22);e=a.h+b.h+(d>>22);return hD(c&dxe,d&dxe,e&exe)} +function DD(a,b){var c,d,e;c=a.l-b.l;d=a.m-b.m+(c>>22);e=a.h-b.h+(d>>22);return hD(c&dxe,d&dxe,e&exe)} +function Jpc(a){var b,c;Hpc(a);for(c=new Anb(a.d);c.ad)throw Adb(new aMd(b,d));a.Si()&&(c=bHd(a,c));return a.Ei(b,c)} +function eQb(a,b,c,d,e){var f,g;for(g=c;g<=e;g++){for(f=b;f<=d;f++){PPb(a,f,g)||TPb(a,f,g,true,false)}}} +function uid(a){tid();var b,c,d;c=$C(l3,Nve,8,2,0,1);d=0;for(b=0;b<2;b++){d+=0.5;c[b]=Cid(d,a)}return c} +function xD(a){var b,c,d;b=~a.l+1&dxe;c=~a.m+(b==0?1:0)&dxe;d=~a.h+(b==0&&c==0?1:0)&exe;return hD(b,c,d)} +function mgb(a){var b;if(a<0){return qwe}else if(a==0){return 0}else{for(b=hwe;(b&a)==0;b>>=1);return b}} +function zSd(a,b,c){if(a>=128)return false;return a<64?Pdb(Cdb(Sdb(1,a),c),0):Pdb(Cdb(Sdb(1,a-64),b),0)} +function oQb(a,b,c){return c==null?(!a.q&&(a.q=new Tsb),_jb(a.q,b)):(!a.q&&(a.q=new Tsb),Zjb(a.q,b,c)),a} +function pQb(a,b,c){c==null?(!a.q&&(a.q=new Tsb),_jb(a.q,b)):(!a.q&&(a.q=new Tsb),Zjb(a.q,b,c));return a} +function KTb(a){var b,c;c=new gUb;kQb(c,a);pQb(c,(JVb(),HVb),a);b=new Tsb;MTb(a,c,b);LTb(a,c,b);return c} +function cIc(a){var b,c;b=a.t-a.k[a.o.p]*a.d+a.j[a.o.p]>a.f;c=a.u+a.e[a.o.p]*a.d>a.f*a.s*a.d;return b||c} +function qmc(a,b){var c,d,e,f;c=false;d=a.a[b].length;for(f=0;f=0,'Negative initial capacity');mFb(b>=0,'Non-positive load factor');akb(this)} +function iib(a,b,c,d,e){var f,g;g=a.length;f=c.length;if(b<0||d<0||e<0||b+e>g||d+e>f){throw Adb(new ueb)}} +function zob(a,b){yob();var c,d,e,f,g;g=false;for(d=b,e=0,f=d.length;e1||b>=0&&a.b<3} +function nD(a){var b,c,d;b=~a.l+1&dxe;c=~a.m+(b==0?1:0)&dxe;d=~a.h+(b==0&&c==0?1:0)&exe;a.l=b;a.m=c;a.h=d} +function Cob(a){yob();var b,c,d;d=1;for(c=a.Kc();c.Ob();){b=c.Pb();d=31*d+(b!=null?tb(b):0);d=d|0}return d} +function kD(a,b,c,d,e){var f;f=BD(a,b);c&&nD(f);if(e){a=mD(a,b);d?(eD=xD(a)):(eD=hD(a.l,a.m,a.h))}return f} +function Qlc(a,b,c){a.g=Wlc(a,b,(qpd(),Xod),a.b);a.d=Wlc(a,c,Xod,a.b);if(a.g.c==0||a.d.c==0){return}Tlc(a)} +function Rlc(a,b,c){a.g=Wlc(a,b,(qpd(),ppd),a.j);a.d=Wlc(a,c,ppd,a.j);if(a.g.c==0||a.d.c==0){return}Tlc(a)} +function Xyd(a,b){switch(b){case 7:return !!a.e&&a.e.i!=0;case 8:return !!a.d&&a.d.i!=0;}return wyd(a,b)} +function STb(a,b){switch(b.g){case 0:ZD(a.b,641)||(a.b=new tUb);break;case 1:ZD(a.b,642)||(a.b=new zUb);}} +function tbd(a){switch(a.g){case 0:return new _dd;default:throw Adb(new agb(eGe+(a.f!=null?a.f:''+a.g)));}} +function bdd(a){switch(a.g){case 0:return new vdd;default:throw Adb(new agb(eGe+(a.f!=null?a.f:''+a.g)));}} +function LCc(a,b,c){return !QDb(CDb(new SDb(null,new Swb(a.c,16)),new PAb(new gsd(b,c)))).Bd((xDb(),wDb))} +function mWc(a,b){return cjd(jWc(RD(mQb(b,(h_c(),H$c)),88)),new rjd(a.c.e.a-a.b.e.a,a.c.e.b-a.b.e.b))<=0} +function dve(a,b){while(a.g==null&&!a.c?sId(a):a.g==null||a.i!=0&&RD(a.g[a.i-1],51).Ob()){mFd(b,tId(a))}} +function sYb(a){var b,c;for(c=new Anb(a.a.b);c.ad?1:0} +function ICc(a){Rmb(a.c,(hed(),fed));if(_y(a.a,Kfb(UD(iGd((QCc(),OCc)))))){return new asd}return new csd(a)} +function fs(a){while(!a.d||!a.d.Ob()){if(!!a.b&&!nmb(a.b)){a.d=RD(smb(a.b),51)}else{return null}}return a.d} +function BVc(a){switch(a.g){case 1:return EEe;default:case 2:return 0;case 3:return Gze;case 4:return FEe;}} +function fte(){Vse();var a;if(Cse)return Cse;a=Zse(hte('M',true));a=$se(hte('M',false),a);Cse=a;return Cse} +function ttd(){ttd=geb;qtd=new utd('ELK',0);rtd=new utd('JSON',1);ptd=new utd('DOT',2);std=new utd('SVG',3)} +function TEc(){TEc=geb;SEc=new UEc('STACKED',0);QEc=new UEc('REVERSE_STACKED',1);REc=new UEc('SEQUENCED',2)} +function LZc(){LZc=geb;KZc=new MZc(LAe,0);JZc=new MZc('MIDDLE_TO_MIDDLE',1);IZc=new MZc('AVOID_OVERLAP',2)} +function sgc(){sgc=geb;qgc=new Lgc;rgc=new Ngc;pgc=new Dgc;ogc=new Pgc;ngc=new Hgc;mgc=(uFb(ngc),new nrb)} +function vnd(){vnd=geb;tnd=new A3b(15);snd=new mGd((umd(),tld),tnd);und=Qld;ond=Ekd;pnd=kld;rnd=nld;qnd=mld} +function wgd(a,b){var c,d,e,f,g;for(d=b,e=0,f=d.length;e=a.b.c.length){return}jwb(a,2*b+1);c=2*b+2;c0){b.Cd(c);c.i&&zKc(c)}}} +function Ejb(a,b,c){var d;for(d=c-1;d>=0&&a[d]===b[d];d--);return d<0?0:Ldb(Cdb(a[d],yxe),Cdb(b[d],yxe))?-1:1} +function it(a,b,c){var d,e;this.g=a;this.c=b;this.a=this;this.d=this;e=Wp(c);d=$C(UG,ewe,227,e,0,1);this.b=d} +function fQb(a,b,c,d,e){var f,g;for(g=c;g<=e;g++){for(f=b;f<=d;f++){if(PPb(a,f,g)){return true}}}return false} +function Dc(a,b){var c,d;for(d=a.Zb().Cc().Kc();d.Ob();){c=RD(d.Pb(),16);if(c.Hc(b)){return true}}return false} +function iu(a,b,c){var d,e,f,g;uFb(c);g=false;f=a.fd(b);for(e=c.Kc();e.Ob();){d=e.Pb();f.Rb(d);g=true}return g} +function NMd(a,b){var c,d;d=RD(Ywd(a.a,4),129);c=$C(d6,IJe,424,b,0,1);d!=null&&hib(d,0,c,0,d.length);return c} +function hSd(a,b){var c;c=new lSd((a.f&256)!=0,a.i,a.a,a.d,(a.f&16)!=0,a.j,a.g,b);a.e!=null||(c.c=a);return c} +function Tv(a,b){var c;if(a===b){return true}else if(ZD(b,85)){c=RD(b,85);return Rx(gn(a),c.vc())}return false} +function Vjb(a,b,c){var d,e;for(e=c.Kc();e.Ob();){d=RD(e.Pb(),44);if(a.Be(b,d.md())){return true}}return false} +function lmc(a,b,c){if(!a.d[b.p][c.p]){kmc(a,b,c);a.d[b.p][c.p]=true;a.d[c.p][b.p]=true}return a.a[b.p][c.p]} +function vMc(a,b){var c;if(!a||a==b||!nQb(b,(Ywc(),pwc))){return false}c=RD(mQb(b,(Ywc(),pwc)),10);return c!=a} +function Bhe(a){switch(a.i){case 2:{return true}case 1:{return false}case -1:{++a.c}default:{return a.$l()}}} +function Che(a){switch(a.i){case -2:{return true}case -1:{return false}case 1:{--a.c}default:{return a._l()}}} +function bgb(a){oz.call(this,'The given string does not match the expected format for individual spacings.',a)} +function J6c(a,b){var c;b.Ug('Min Size Preprocessing',1);c=vsd(a);Ixd(a,(X6c(),U6c),c.a);Ixd(a,R6c,c.b);b.Vg()} +function Djd(a){var b,c,d;b=0;d=$C(l3,Nve,8,a.b,0,1);c=Sub(a,0);while(c.b!=c.d.c){d[b++]=RD(evb(c),8)}return d} +function Ajd(a,b,c){var d,e,f;d=new Yub;for(f=Sub(c,0);f.b!=f.d.c;){e=RD(evb(f),8);Mub(d,new sjd(e))}iu(a,b,d)} +function az(a,b){var c;c=Bdb(a,b);if(Ldb($db(a,b),0)|Jdb($db(a,c),0)){return c}return Bdb(Sve,$db(Udb(c,63),1))} +function le(a,b){var c,d;c=RD(a.d.Bc(b),16);if(!c){return null}d=a.e.hc();d.Gc(c);a.e.d-=c.gc();c.$b();return d} +function Dyb(a){var b;b=a.a.c.length;if(b>0){return lyb(b-1,a.a.c.length),Xmb(a.a,b-1)}else{throw Adb(new Srb)}} +function nFb(a,b,c){if(a>b){throw Adb(new agb(_xe+a+aye+b))}if(a<0||b>c){throw Adb(new xeb(_xe+a+bye+b+Qxe+c))}} +function yXd(a,b){if(a.D==null&&a.B!=null){a.D=a.B;a.B=null}JXd(a,b==null?null:(uFb(b),b));!!a.C&&a.hl(null)} +function JCc(a,b){var c;c=iGd((QCc(),OCc))!=null&&b.Sg()!=null?Kfb(UD(b.Sg()))/Kfb(UD(iGd(OCc))):1;Zjb(a.b,b,c)} +function $Lc(a,b){var c,d;d=a.c[b];if(d==0){return}a.c[b]=0;a.d-=d;c=b+1;while(cDEe?a-c>DEe:c-a>DEe} +function vjd(a,b){var c;for(c=0;ce){ead(b.q,e);d=c!=b.q.d}}return d} +function C3c(a,b){var c,d,e,f,g,h,i,j;i=b.i;j=b.j;d=a.f;e=d.i;f=d.j;g=i-e;h=j-f;c=$wnd.Math.sqrt(g*g+h*h);return c} +function pBd(a,b){var c,d;d=Hvd(a);if(!d){!$Ad&&($Ad=new L5d);c=(gSd(),nSd(b));d=new Sde(c);WGd(d.El(),a)}return d} +function Sc(a,b){var c,d;c=RD(a.c.Bc(b),16);if(!c){return a.jc()}d=a.hc();d.Gc(c);a.d-=c.gc();c.$b();return a.mc(d)} +function tKc(a,b){var c,d;d=Kwb(a.d,1)!=0;c=true;while(c){c=false;c=b.c.mg(b.e,d);c=c|DKc(a,b,d,false);d=!d}yKc(a)} +function omc(a,b,c,d){var e,f;a.a=b;f=d?0:1;a.f=(e=new mmc(a.c,a.a,c,f),new Pmc(c,a.a,e,a.e,a.b,a.c==(RKc(),PKc)))} +function Imb(a){var b;sFb(a.a!=a.b);b=a.d.a[a.a];zmb(a.b==a.d.c&&b!=null);a.c=a.a;a.a=a.a+1&a.d.a.length-1;return b} +function Vib(a){var b;if(a.c!=0){return a.c}for(b=0;b=a.c.b:a.a<=a.c.b)){throw Adb(new Dvb)}b=a.a;a.a+=a.c.c;++a.b;return sgb(b)} +function h5b(a){var b;b=new y2b(a.a);kQb(b,a);pQb(b,(Ywc(),Awc),a);b.o.a=a.g;b.o.b=a.f;b.n.a=a.i;b.n.b=a.j;return b} +function tVc(a){return (qpd(),hpd).Hc(a.j)?Kfb(UD(mQb(a,(Ywc(),Swc)))):xjd(cD(WC(l3,1),Nve,8,0,[a.i.n,a.n,a.a])).b} +function ZJc(a){var b;b=vfd(XJc);RD(mQb(a,(Ywc(),kwc)),21).Hc((ovc(),kvc))&&pfd(b,(sXb(),pXb),(hcc(),Ybc));return b} +function M2c(a){var b,c,d,e;e=new _sb;for(d=new Anb(a);d.a=0?b:-b;while(d>0){if(d%2==0){c*=c;d=d/2|0}else{e*=c;d-=1}}return b<0?1/e:e} +function Jid(a,b){var c,d,e;e=1;c=a;d=b>=0?b:-b;while(d>0){if(d%2==0){c*=c;d=d/2|0}else{e*=c;d-=1}}return b<0?1/e:e} +function Vvd(a,b){var c,d,e,f;f=(e=a?Hvd(a):null,Pje((d=b,e?e.Gl():null,d)));if(f==b){c=Hvd(a);!!c&&c.Gl()}return f} +function g2d(a,b,c){var d,e;e=a.f;a.f=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new N3d(a,1,0,e,b);!c?(c=d):c.nj(d)}return c} +function e2d(a,b,c){var d,e;e=a.b;a.b=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new N3d(a,1,3,e,b);!c?(c=d):c.nj(d)}return c} +function rAd(a,b,c){var d,e;e=a.a;a.a=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new N3d(a,1,1,e,b);!c?(c=d):c.nj(d)}return c} +function SNd(a){var b,c,d,e;if(a!=null){for(c=0;c=d||b-129&&a<128){return ugb(),b=a+128,c=tgb[b],!c&&(c=tgb[b]=new fgb(a)),c}return new fgb(a)} +function bhb(a){var b,c;if(a>-129&&a<128){return dhb(),b=a+128,c=chb[b],!c&&(c=chb[b]=new Xgb(a)),c}return new Xgb(a)} +function M$b(a,b){var c;if(a.a.c.length>0){c=RD(Vmb(a.a,a.a.c.length-1),579);if(Q_b(c,b)){return}}Rmb(a.a,new S_b(b))} +function Ekc(a){lkc();var b,c;b=a.d.c-a.e.c;c=RD(a.g,154);Umb(c.b,new Ykc(b));Umb(c.c,new $kc(b));xgb(c.i,new alc(b))} +function Mlc(a){var b;b=new bib;b.a+='VerticalSegment ';Yhb(b,a.e);b.a+=' ';Zhb(b,Eb(new Gb,new Anb(a.k)));return b.a} +function Fmc(a,b){var c,d,e;c=0;for(e=b3b(a,b).Kc();e.Ob();){d=RD(e.Pb(),12);c+=mQb(d,(Ywc(),Iwc))!=null?1:0}return c} +function VTc(a,b,c){var d,e,f;d=0;for(f=Sub(a,0);f.b!=f.d.c;){e=Kfb(UD(evb(f)));if(e>c){break}else e>=b&&++d}return d} +function Wv(b,c){Qb(b);try{return b._b(c)}catch(a){a=zdb(a);if(ZD(a,212)||ZD(a,169)){return false}else throw Adb(a)}} +function Nk(b,c){Qb(b);try{return b.Hc(c)}catch(a){a=zdb(a);if(ZD(a,212)||ZD(a,169)){return false}else throw Adb(a)}} +function Ok(b,c){Qb(b);try{return b.Mc(c)}catch(a){a=zdb(a);if(ZD(a,212)||ZD(a,169)){return false}else throw Adb(a)}} +function Xv(b,c){Qb(b);try{return b.xc(c)}catch(a){a=zdb(a);if(ZD(a,212)||ZD(a,169)){return null}else throw Adb(a)}} +function Yv(b,c){Qb(b);try{return b.Bc(c)}catch(a){a=zdb(a);if(ZD(a,212)||ZD(a,169)){return null}else throw Adb(a)}} +function aMc(a,b){switch(b.g){case 2:case 1:return b3b(a,b);case 3:case 4:return hv(b3b(a,b));}return yob(),yob(),vob} +function QAd(a){var b;if((a.Db&64)!=0)return awd(a);b=new Shb(awd(a));b.a+=' (name: ';Nhb(b,a.zb);b.a+=')';return b.a} +function Fgd(a){var b;b=RD(cub(a.c.c,''),233);if(!b){b=new fgd(ogd(ngd(new pgd,''),'Other'));dub(a.c.c,'',b)}return b} +function hBd(a,b,c){var d,e;e=a.sb;a.sb=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new N3d(a,1,4,e,b);!c?(c=d):c.nj(d)}return c} +function ZVd(a,b,c){var d,e;e=a.r;a.r=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new N3d(a,1,8,e,a.r);!c?(c=d):c.nj(d)}return c} +function q5d(a,b,c){var d,e;d=new P3d(a.e,4,13,(e=b.c,e?e:(JTd(),wTd)),null,fZd(a,b),false);!c?(c=d):c.nj(d);return c} +function p5d(a,b,c){var d,e;d=new P3d(a.e,3,13,null,(e=b.c,e?e:(JTd(),wTd)),fZd(a,b),false);!c?(c=d):c.nj(d);return c} +function Oee(a,b){var c,d;c=RD(b,691);d=c.el();!d&&c.fl(d=ZD(b,90)?new afe(a,RD(b,29)):new mfe(a,RD(b,156)));return d} +function KHd(a,b,c){var d;a._i(a.i+1);d=a.Zi(b,c);b!=a.i&&hib(a.g,b,a.g,b+1,a.i-b);bD(a.g,b,d);++a.i;a.Mi(b,c);a.Ni()} +function Hyb(a,b){var c;if(b.a){c=b.a.a.length;!a.a?(a.a=new dib(a.d)):Zhb(a.a,a.b);Xhb(a.a,b.a,b.d.length,c)}return a} +function wib(a,b){var c;a.c=b;a.a=pjb(b);a.a<54&&(a.f=(c=b.d>1?DFb(b.a[0],b.a[1]):DFb(b.a[0],0),Xdb(b.e>0?c:Odb(c))))} +function MDb(a,b){var c;c=new IEb;if(!a.a.Bd(c)){LCb(a);return Kvb(),Kvb(),Jvb}return Kvb(),new Ovb(uFb(LDb(a,c.a,b)))} +function t9b(a,b){var c;if(a.c.length==0){return}c=RD(anb(a,$C(jR,WAe,10,a.c.length,0,1)),199);Znb(c,new F9b);q9b(c,b)} +function z9b(a,b){var c;if(a.c.length==0){return}c=RD(anb(a,$C(jR,WAe,10,a.c.length,0,1)),199);Znb(c,new K9b);q9b(c,b)} +function pb(a,b){return bE(a)?lhb(a,b):_D(a)?Lfb(a,b):$D(a)?(uFb(a),dE(a)===dE(b)):YD(a)?a.Fb(b):aD(a)?mb(a,b):Hz(a,b)} +function Cvd(a,b,c){if(b<0){Tvd(a,c)}else{if(!c.rk()){throw Adb(new agb(KHe+c.xe()+LHe))}RD(c,69).wk().Ek(a,a.hi(),b)}} +function xFb(a,b,c){if(a<0||b>c){throw Adb(new veb(_xe+a+bye+b+', size: '+c))}if(a>b){throw Adb(new agb(_xe+a+aye+b))}} +function oVd(a){var b;if((a.Db&64)!=0)return awd(a);b=new Shb(awd(a));b.a+=' (source: ';Nhb(b,a.d);b.a+=')';return b.a} +function JSd(a){if(a>=65&&a<=70){return a-65+10}if(a>=97&&a<=102){return a-97+10}if(a>=48&&a<=57){return a-48}return 0} +function lMb(a){hMb();var b,c,d,e;for(c=nMb(),d=0,e=c.length;d=0?jjb(a):Xib(jjb(Odb(a)))))} +function G0b(a,b,c,d,e,f){this.e=new bnb;this.f=(BEc(),AEc);Rmb(this.e,a);this.d=b;this.a=c;this.b=d;this.f=e;this.c=f} +function bQb(a,b,c){a.n=YC(lE,[Nve,rxe],[376,28],14,[c,eE($wnd.Math.ceil(b/32))],2);a.o=b;a.p=c;a.j=b-1>>1;a.k=c-1>>1} +function ggb(a){a-=a>>1&1431655765;a=(a>>2&858993459)+(a&858993459);a=(a>>4)+a&252645135;a+=a>>8;a+=a>>16;return a&63} +function C4d(a,b){var c,d;for(d=new dMd(a);d.e!=d.i.gc();){c=RD(bMd(d),142);if(dE(b)===dE(c)){return true}}return false} +function Iee(a,b,c){var d,e,f;f=(e=N5d(a.b,b),e);if(f){d=RD(tfe(Pee(a,f),''),29);if(d){return Ree(a,d,b,c)}}return null} +function Lee(a,b,c){var d,e,f;f=(e=N5d(a.b,b),e);if(f){d=RD(tfe(Pee(a,f),''),29);if(d){return See(a,d,b,c)}}return null} +function IDd(a,b){var c;c=Ao(a.i,b);if(c==null){throw Adb(new CDd('Node did not exist in input.'))}wEd(b,c);return null} +function wvd(a,b){var c;c=wYd(a,b);if(ZD(c,331)){return RD(c,35)}throw Adb(new agb(KHe+b+"' is not a valid attribute"))} +function VGd(a,b,c){var d;d=a.gc();if(b>d)throw Adb(new aMd(b,d));if(a.Si()&&a.Hc(c)){throw Adb(new agb(LIe))}a.Gi(b,c)} +function w7b(a,b){b.Ug('Sort end labels',1);FDb(CDb(EDb(new SDb(null,new Swb(a.b,16)),new H7b),new J7b),new L7b);b.Vg()} +function Cmd(){Cmd=geb;Amd=new Gmd(Sye,0);zmd=new Gmd(Oye,1);ymd=new Gmd(Nye,2);xmd=new Gmd(Zye,3);Bmd=new Gmd('UP',4)} +function gbd(){gbd=geb;dbd=new hbd('P1_STRUCTURE',0);ebd=new hbd('P2_PROCESSING_ORDER',1);fbd=new hbd('P3_EXECUTION',2)} +function r0c(){r0c=geb;q0c=mfd(mfd(rfd(mfd(mfd(rfd(pfd(new ufd,(YVc(),VVc),(WYc(),VYc)),WVc),RYc),TYc),XVc),NYc),UYc)} +function s8b(a){switch(RD(mQb(a,(Ywc(),owc)),311).g){case 1:pQb(a,owc,(Gvc(),Dvc));break;case 2:pQb(a,owc,(Gvc(),Fvc));}} +function bUc(a){switch(a){case 0:return new mUc;case 1:return new cUc;case 2:return new hUc;default:throw Adb(new _fb);}} +function Fmd(a){switch(a.g){case 2:return zmd;case 1:return ymd;case 4:return xmd;case 3:return Bmd;default:return Amd;}} +function UNb(a,b){switch(a.b.g){case 0:case 1:return b;case 2:case 3:return new Uid(b.d,0,b.a,b.b);default:return null;}} +function rpd(a){switch(a.g){case 1:return ppd;case 2:return Yod;case 3:return Xod;case 4:return npd;default:return opd;}} +function spd(a){switch(a.g){case 1:return npd;case 2:return ppd;case 3:return Yod;case 4:return Xod;default:return opd;}} +function tpd(a){switch(a.g){case 1:return Xod;case 2:return npd;case 3:return ppd;case 4:return Yod;default:return opd;}} +function cyd(a,b,c,d){switch(b){case 1:return !a.n&&(a.n=new C5d(I4,a,1,7)),a.n;case 2:return a.k;}return Axd(a,b,c,d)} +function uLd(a,b,c){var d,e;if(a.Pj()){e=a.Qj();d=SHd(a,b,c);a.Jj(a.Ij(7,sgb(c),d,b,e));return d}else{return SHd(a,b,c)}} +function VNd(a,b){var c,d,e;if(a.d==null){++a.e;--a.f}else{e=b.ld();c=b.Bi();d=(c&lve)%a.d.length;iOd(a,d,XNd(a,d,c,e))}} +function xWd(a,b){var c;c=(a.Bb&gwe)!=0;b?(a.Bb|=gwe):(a.Bb&=-1025);(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new Q3d(a,1,10,c,b))} +function DWd(a,b){var c;c=(a.Bb&qxe)!=0;b?(a.Bb|=qxe):(a.Bb&=-4097);(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new Q3d(a,1,12,c,b))} +function EWd(a,b){var c;c=(a.Bb&bKe)!=0;b?(a.Bb|=bKe):(a.Bb&=-8193);(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new Q3d(a,1,15,c,b))} +function FWd(a,b){var c;c=(a.Bb&cKe)!=0;b?(a.Bb|=cKe):(a.Bb&=-2049);(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new Q3d(a,1,11,c,b))} +function zKc(a){var b;if(a.g){b=a.c.kg()?a.f:a.a;BKc(b.a,a.o,true);BKc(b.a,a.o,false);pQb(a.o,(yCc(),BBc),(Bod(),vod))}} +function Orc(a){var b;if(!a.a){throw Adb(new dgb('Cannot offset an unassigned cut.'))}b=a.c-a.b;a.b+=b;Qrc(a,b);Rrc(a,b)} +function JDd(a,b){var c;c=Wjb(a.k,b);if(c==null){throw Adb(new CDd('Port did not exist in input.'))}wEd(b,c);return null} +function Jje(a){var b,c;for(c=Kje(BXd(a)).Kc();c.Ob();){b=WD(c.Pb());if(bAd(a,b)){return USd((TSd(),SSd),b)}}return null} +function qJb(a){var b,c;for(c=a.p.a.ec().Kc();c.Ob();){b=RD(c.Pb(),218);if(b.f&&a.b[b.c]<-1.0E-10){return b}}return null} +function Lr(a){var b,c;c=Thb(new bib,91);b=true;while(a.Ob()){b||(c.a+=pve,c);b=false;Yhb(c,a.Pb())}return (c.a+=']',c).a} +function o_b(a){var b,c,d;b=new bnb;for(d=new Anb(a.b);d.ab){return 1}if(a==b){return a==0?Qfb(1/a,1/b):0}return isNaN(a)?isNaN(b)?0:1:-1} +function pmb(a){var b;b=a.a[a.c-1&a.a.length-1];if(b==null){return null}a.c=a.c-1&a.a.length-1;bD(a.a,a.c,null);return b} +function Dqe(a){var b,c,d;d=0;c=a.length;for(b=0;b=1?zmd:xmd}return c} +function Xhc(a){switch(RD(mQb(a,(yCc(),yAc)),223).g){case 1:return new jqc;case 3:return new arc;default:return new dqc;}} +function MCb(a){if(a.c){MCb(a.c)}else if(a.d){throw Adb(new dgb("Stream already terminated, can't be modified or used"))}} +function Ltb(a,b,c){var d;d=a.a.get(b);a.a.set(b,c===undefined?null:c);if(d===undefined){++a.c;++a.b.g}else{++a.d}return d} +function HHc(a,b,c){var d,e;for(e=a.a.ec().Kc();e.Ob();){d=RD(e.Pb(),10);if(Be(c,RD(Vmb(b,d.p),16))){return d}}return null} +function u0c(a,b,c){var d;d=0;!!b&&(Emd(a.a)?(d+=b.f.a/2):(d+=b.f.b/2));!!c&&(Emd(a.a)?(d+=c.f.a/2):(d+=c.f.b/2));return d} +function LWb(a,b,c){var d;d=c;!d&&(d=Nqd(new Oqd,0));d.Ug(EAe,2);y0b(a.b,b,d.eh(1));NWb(a,b,d.eh(1));h0b(b,d.eh(1));d.Vg()} +function CGd(a,b,c){var d,e;d=(bvd(),e=new Xxd,e);Vxd(d,b);Wxd(d,c);!!a&&WGd((!a.a&&(a.a=new XZd(D4,a,5)),a.a),d);return d} +function kyd(a){var b;if((a.Db&64)!=0)return awd(a);b=new Shb(awd(a));b.a+=' (identifier: ';Nhb(b,a.k);b.a+=')';return b.a} +function kXd(a,b){var c;c=(a.Bb&QHe)!=0;b?(a.Bb|=QHe):(a.Bb&=-32769);(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new Q3d(a,1,18,c,b))} +function a6d(a,b){var c;c=(a.Bb&QHe)!=0;b?(a.Bb|=QHe):(a.Bb&=-32769);(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new Q3d(a,1,18,c,b))} +function AWd(a,b){var c;c=(a.Bb&Ove)!=0;b?(a.Bb|=Ove):(a.Bb&=-16385);(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new Q3d(a,1,16,c,b))} +function c6d(a,b){var c;c=(a.Bb&txe)!=0;b?(a.Bb|=txe):(a.Bb&=-65537);(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new Q3d(a,1,20,c,b))} +function qse(a){var b;b=$C(hE,zwe,28,2,15,1);a-=txe;b[0]=(a>>10)+uxe&Bwe;b[1]=(a&1023)+56320&Bwe;return Ihb(b,0,b.length)} +function Zfb(a){var b;b=Neb(a);if(b>3.4028234663852886E38){return oxe}else if(b<-3.4028234663852886E38){return pxe}return b} +function Bdb(a,b){var c;if(Kdb(a)&&Kdb(b)){c=a+b;if(jxe'+aXc(b.c):'e_'+tb(b),!!a.b&&!!a.c?aXc(a.b)+'->'+aXc(a.c):'e_'+tb(a))} +function rWc(a,b){return lhb(!!b.b&&!!b.c?aXc(b.b)+'->'+aXc(b.c):'e_'+tb(b),!!a.b&&!!a.c?aXc(a.b)+'->'+aXc(a.c):'e_'+tb(a))} +function $y(a,b){Zy();return bz(pwe),$wnd.Math.abs(a-b)<=pwe||a==b||isNaN(a)&&isNaN(b)?0:ab?1:cz(isNaN(a),isNaN(b))} +function Ymd(){Ymd=geb;Xmd=new Zmd(Sye,0);Vmd=new Zmd('POLYLINE',1);Umd=new Zmd('ORTHOGONAL',2);Wmd=new Zmd('SPLINES',3)} +function _6c(){_6c=geb;Z6c=new a7c('ASPECT_RATIO_DRIVEN',0);$6c=new a7c('MAX_SCALE_DRIVEN',1);Y6c=new a7c('AREA_DRIVEN',2)} +function Db(b,c,d){var e;try{Cb(b,c,d)}catch(a){a=zdb(a);if(ZD(a,606)){e=a;throw Adb(new Deb(e))}else throw Adb(a)}return c} +function Im(a){var b,c,d;for(c=0,d=a.length;cb&&d.Ne(a[f-1],a[f])>0;--f){g=a[f];bD(a,f,a[f-1]);bD(a,f-1,g)}}} +function Egd(a,b){var c,d,e,f,g;c=b.f;dub(a.c.d,c,b);if(b.g!=null){for(e=b.g,f=0,g=e.length;fb){fvb(c);break}}cvb(c,b)} +function Kic(a,b){var c,d,e;d=Zjc(b);e=Kfb(UD(hFc(d,(yCc(),TBc))));c=$wnd.Math.max(0,e/2-0.5);Iic(b,c,1);Rmb(a,new hjc(b,c))} +function L5c(a,b,c){var d;c.Ug('Straight Line Edge Routing',1);c.dh(b,eFe);d=RD(Gxd(b,(u2c(),t2c)),27);M5c(a,d);c.dh(b,gFe)} +function K9c(a,b){a.n.c.length==0&&Rmb(a.n,new _9c(a.s,a.t,a.i));Rmb(a.b,b);W9c(RD(Vmb(a.n,a.n.c.length-1),209),b);M9c(a,b)} +function Zrb(a){var b;this.a=(b=RD(a.e&&a.e(),9),new Fsb(b,RD(WEb(b,b.length),9),0));this.b=$C(jJ,rve,1,this.a.a.length,5,1)} +function jeb(a){var b;if(Array.isArray(a)&&a.Tm===keb){return nfb(rb(a))+'@'+(b=tb(a)>>>0,b.toString(16))}return a.toString()} +function jD(a,b){if(a.h==fxe&&a.m==0&&a.l==0){b&&(eD=hD(0,0,0));return gD((MD(),KD))}b&&(eD=hD(a.l,a.m,a.h));return hD(0,0,0)} +function _Gb(a,b){switch(b.g){case 2:return a.b;case 1:return a.c;case 4:return a.d;case 3:return a.a;default:return false;}} +function IYb(a,b){switch(b.g){case 2:return a.b;case 1:return a.c;case 4:return a.d;case 3:return a.a;default:return false;}} +function vyd(a,b,c,d){switch(b){case 3:return a.f;case 4:return a.g;case 5:return a.i;case 6:return a.j;}return cyd(a,b,c,d)} +function oIb(a,b){if(b==a.d){return a.e}else if(b==a.e){return a.d}else{throw Adb(new agb('Node '+b+' not part of edge '+a))}} +function Uvd(a,b){var c;c=wYd(a.Dh(),b);if(ZD(c,102)){return RD(c,19)}throw Adb(new agb(KHe+b+"' is not a valid reference"))} +function Bvd(a,b,c,d){if(b<0){Svd(a,c,d)}else{if(!c.rk()){throw Adb(new agb(KHe+c.xe()+LHe))}RD(c,69).wk().Ck(a,a.hi(),b,d)}} +function ig(a){var b;if(a.b){ig(a.b);if(a.b.d!=a.c){throw Adb(new Jrb)}}else if(a.d.dc()){b=RD(a.f.c.xc(a.e),16);!!b&&(a.d=b)}} +function VMb(a){RMb();var b,c,d,e;b=a.o.b;for(d=RD(RD(Qc(a.r,(qpd(),npd)),21),87).Kc();d.Ob();){c=RD(d.Pb(),117);e=c.e;e.b+=b}} +function SRb(a){var b,c,d;this.a=new Iub;for(d=new Anb(a);d.a=e){return b.c+c}}return b.c+b.b.gc()} +function lQd(a,b){jQd();var c,d,e,f;d=iZd(a);e=b;Wnb(d,0,d.length,e);for(c=0;c0){d+=e;++c}}c>1&&(d+=a.d*(c-1));return d} +function FFd(a){var b,c,d,e,f;f=HFd(a);c=cve(a.c);d=!c;if(d){e=new MB;sC(f,'knownLayouters',e);b=new QFd(e);xgb(a.c,b)}return f} +function fHd(a){var b,c,d;d=new Qhb;d.a+='[';for(b=0,c=a.gc();b0&&(BFb(b-1,a.length),a.charCodeAt(b-1)==58)&&!mSd(a,aSd,bSd)} +function Sib(a,b){var c;if(dE(a)===dE(b)){return true}if(ZD(b,92)){c=RD(b,92);return a.e==c.e&&a.d==c.d&&Tib(a,c.a)}return false} +function vpd(a){qpd();switch(a.g){case 4:return Yod;case 1:return Xod;case 3:return npd;case 2:return ppd;default:return opd;}} +function jBb(a){var b,c;if(a.b){return a.b}c=dBb?null:a.d;while(c){b=dBb?null:c.b;if(b){return b}c=dBb?null:c.d}return SAb(),RAb} +function LJb(a){var b,c,d;d=Kfb(UD(a.a.of((umd(),cmd))));for(c=new Anb(a.a.Sf());c.a>5;b=a&31;d=$C(kE,Pwe,28,c+1,15,1);d[c]=1<3){e*=10;--f}a=(a+(e>>1))/e|0}d.i=a;return true} +function BYd(a,b){var c,d,e;c=(a.i==null&&rYd(a),a.i);d=b.Lj();if(d!=-1){for(e=c.length;d=0;--d){b=c[d];for(e=0;e>1;this.k=b-1>>1} +function Dfd(a){Afd();if(RD(a.of((umd(),pld)),181).Hc((dqd(),bqd))){RD(a.of(Lld),181).Fc((Pod(),Ood));RD(a.of(pld),181).Mc(bqd)}} +function ndc(a){var b,c;b=a.d==(btc(),Ysc);c=jdc(a);b&&!c||!b&&c?pQb(a.a,(yCc(),Rzc),(Rjd(),Pjd)):pQb(a.a,(yCc(),Rzc),(Rjd(),Ojd))} +function QCc(){QCc=geb;GCc();OCc=(yCc(),bCc);PCc=dv(cD(WC(V5,1),kEe,149,0,[SBc,TBc,VBc,WBc,ZBc,$Bc,_Bc,aCc,dCc,fCc,UBc,XBc,cCc]))} +function RDb(a,b){var c;c=RD(zDb(a,tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[(xBb(),vBb)]))),15);return c.Qc(__c(c.gc()))} +function nXc(a,b){var c,d;d=new zAb(a.a.ad(b,true));if(d.a.gc()<=1){throw Adb(new Ngb)}c=d.a.ec().Kc();c.Pb();return RD(c.Pb(),40)} +function lQc(a,b,c){var d,e;d=Kfb(a.p[b.i.p])+Kfb(a.d[b.i.p])+b.n.b+b.a.b;e=Kfb(a.p[c.i.p])+Kfb(a.d[c.i.p])+c.n.b+c.a.b;return e-d} +function XHd(a,b){var c;if(a.i>0){if(b.lengtha.i&&bD(b,a.i,null);return b} +function MXd(a){var b;if((a.Db&64)!=0)return QAd(a);b=new Shb(QAd(a));b.a+=' (instanceClassName: ';Nhb(b,a.D);b.a+=')';return b.a} +function ySd(a){var b,c,d,e;e=0;for(c=0,d=a.length;c0){a._j();d=b==null?0:tb(b);e=(d&lve)%a.d.length;c=XNd(a,e,d,b);return c!=-1}else{return false}} +function Nrb(a,b){var c,d;a.a=Bdb(a.a,1);a.c=$wnd.Math.min(a.c,b);a.b=$wnd.Math.max(a.b,b);a.d+=b;c=b-a.f;d=a.e+c;a.f=d-a.e-c;a.e=d} +function yyd(a,b){switch(b){case 3:Ayd(a,0);return;case 4:Cyd(a,0);return;case 5:Dyd(a,0);return;case 6:Eyd(a,0);return;}hyd(a,b)} +function c3b(a,b){switch(b.g){case 1:return dr(a.j,(J3b(),E3b));case 2:return dr(a.j,(J3b(),G3b));default:return yob(),yob(),vob;}} +function zm(a){tm();var b;b=a.Pc();switch(b.length){case 0:return sm;case 1:return new Dy(Qb(b[0]));default:return new Kx(Im(b));}} +function kMd(b,c){b.Xj();try{b.d.bd(b.e++,c);b.f=b.d.j;b.g=-1}catch(a){a=zdb(a);if(ZD(a,77)){throw Adb(new Jrb)}else throw Adb(a)}} +function a8d(){a8d=geb;$7d=new b8d;T7d=new e8d;U7d=new h8d;V7d=new k8d;W7d=new n8d;X7d=new q8d;Y7d=new t8d;Z7d=new w8d;_7d=new z8d} +function YA(a,b){WA();var c,d;c=_A(($A(),$A(),ZA));d=null;b==c&&(d=RD(Xjb(VA,a),624));if(!d){d=new XA(a);b==c&&$jb(VA,a,d)}return d} +function zDc(a){wDc();var b;(!a.q?(yob(),yob(),wob):a.q)._b((yCc(),iBc))?(b=RD(mQb(a,iBc),203)):(b=RD(mQb(Y2b(a),jBc),203));return b} +function hFc(a,b){var c,d;d=null;if(nQb(a,(yCc(),YBc))){c=RD(mQb(a,YBc),96);c.pf(b)&&(d=c.of(b))}d==null&&(d=mQb(Y2b(a),b));return d} +function Ze(a,b){var c,d,e;if(ZD(b,44)){c=RD(b,44);d=c.ld();e=Xv(a.Rc(),d);return Hb(e,c.md())&&(e!=null||a.Rc()._b(d))}return false} +function $Nd(a,b){var c,d,e;if(a.f>0){a._j();d=b==null?0:tb(b);e=(d&lve)%a.d.length;c=WNd(a,e,d,b);if(c){return c.md()}}return null} +function qLd(a,b,c){var d,e,f;if(a.Pj()){d=a.i;f=a.Qj();KHd(a,d,b);e=a.Ij(3,null,b,d,f);!c?(c=e):c.nj(e)}else{KHd(a,a.i,b)}return c} +function f$d(a,b,c){var d,e;d=new P3d(a.e,4,10,(e=b.c,ZD(e,90)?RD(e,29):(JTd(),zTd)),null,fZd(a,b),false);!c?(c=d):c.nj(d);return c} +function e$d(a,b,c){var d,e;d=new P3d(a.e,3,10,null,(e=b.c,ZD(e,90)?RD(e,29):(JTd(),zTd)),fZd(a,b),false);!c?(c=d):c.nj(d);return c} +function SMb(a){RMb();var b;b=new sjd(RD(a.e.of((umd(),nld)),8));if(a.B.Hc((dqd(),Ypd))){b.a<=0&&(b.a=20);b.b<=0&&(b.b=20)}return b} +function jjb(a){Pib();var b,c;c=Ydb(a);b=Ydb(Udb(a,32));if(b!=0){return new bjb(c,b)}if(c>10||c<0){return new ajb(1,c)}return Lib[c]} +function Mdb(a,b){var c;if(Kdb(a)&&Kdb(b)){c=a%b;if(jxe=0){f=f.a[1]}else{e=f;f=f.a[0]}}return e} +function Qyb(a,b,c){var d,e,f;e=null;f=a.b;while(f){d=a.a.Ne(b,f.d);if(c&&d==0){return f}if(d<=0){f=f.a[0]}else{e=f;f=f.a[1]}}return e} +function rmc(a,b,c,d){var e,f,g;e=false;if(Lmc(a.f,c,d)){Omc(a.f,a.a[b][c],a.a[b][d]);f=a.a[b];g=f[d];f[d]=f[c];f[c]=g;e=true}return e} +function Nqc(a,b,c){var d,e,f,g;e=RD(Wjb(a.b,c),183);d=0;for(g=new Anb(b.j);g.a>5;b&=31;e=a.d+c+(b==0?0:1);d=$C(kE,Pwe,28,e,15,1);rjb(d,a.a,c,b);f=new cjb(a.e,e,d);Rib(f);return f} +function zGc(a,b){var c,d,e;for(d=new is(Mr(a3b(a).a.Kc(),new ir));gs(d);){c=RD(hs(d),18);e=c.d.i;if(e.c==b){return false}}return true} +function _Ec(a,b,c){var d,e,f,g,h;g=a.k;h=b.k;d=c[g.g][h.g];e=UD(hFc(a,d));f=UD(hFc(b,d));return $wnd.Math.max((uFb(e),e),(uFb(f),f))} +function lA(){if(Error.stackTraceLimit>0){$wnd.Error.stackTraceLimit=Error.stackTraceLimit=64;return true}return 'stack' in new Error} +function sGb(a,b){return Zy(),Zy(),bz(pwe),($wnd.Math.abs(a-b)<=pwe||a==b||isNaN(a)&&isNaN(b)?0:ab?1:cz(isNaN(a),isNaN(b)))>0} +function uGb(a,b){return Zy(),Zy(),bz(pwe),($wnd.Math.abs(a-b)<=pwe||a==b||isNaN(a)&&isNaN(b)?0:ab?1:cz(isNaN(a),isNaN(b)))<0} +function tGb(a,b){return Zy(),Zy(),bz(pwe),($wnd.Math.abs(a-b)<=pwe||a==b||isNaN(a)&&isNaN(b)?0:ab?1:cz(isNaN(a),isNaN(b)))<=0} +function Efb(a,b){var c=0;while(!b[c]||b[c]==''){c++}var d=b[c++];for(;c0&&this.b>0&&(this.g=Aad(this.c,this.b,this.a))} +function rC(f,a){var b=f.a;var c;a=String(a);b.hasOwnProperty(a)&&(c=b[a]);var d=(HC(),GC)[typeof c];var e=d?d(c):NC(typeof c);return e} +function uDd(a){var b,c,d;d=null;b=uIe in a.a;c=!b;if(c){throw Adb(new CDd('Every element must have an id.'))}d=tDd(qC(a,uIe));return d} +function Qqe(a){var b,c;c=Rqe(a);b=null;while(a.c==2){Mqe(a);if(!b){b=(Vse(),Vse(),++Use,new iue(2));hue(b,c);c=b}c.Jm(Rqe(a))}return c} +function jOd(a,b){var c,d,e;a._j();d=b==null?0:tb(b);e=(d&lve)%a.d.length;c=WNd(a,e,d,b);if(c){hOd(a,c);return c.md()}else{return null}} +function Qib(a,b){if(a.e>b.e){return 1}if(a.eb.d){return a.e}if(a.d=48&&a<48+$wnd.Math.min(10,10)){return a-48}if(a>=97&&a<97){return a-97+10}if(a>=65&&a<65){return a-65+10}return -1} +function UHc(a,b){if(b.c==a){return b.d}else if(b.d==a){return b.c}throw Adb(new agb('Input edge is not connected to the input port.'))} +function Fae(a){if(mhb(FGe,a)){return Geb(),Feb}else if(mhb(GGe,a)){return Geb(),Eeb}else{throw Adb(new agb('Expecting true or false'))}} +function jFb(a){switch(typeof(a)){case jve:return ohb(a);case ive:return Nfb(a);case hve:return Jeb(a);default:return a==null?0:kFb(a);}} +function mfd(a,b){if(a.a<0){throw Adb(new dgb('Did not call before(...) or after(...) before calling add(...).'))}tfd(a,a.a,b);return a} +function FId(a){EId();if(ZD(a,162)){return RD(Wjb(CId,zK),295).Rg(a)}if(Ujb(CId,rb(a))){return RD(Wjb(CId,rb(a)),295).Rg(a)}return null} +function Wwd(a){var b,c;if((a.Db&32)==0){c=(b=RD(Ywd(a,16),29),AYd(!b?a.ii():b)-AYd(a.ii()));c!=0&&$wd(a,32,$C(jJ,rve,1,c,5,1))}return a} +function $wd(a,b,c){var d;if((a.Db&b)!=0){if(c==null){Zwd(a,b)}else{d=Xwd(a,b);d==-1?(a.Eb=c):bD(SD(a.Eb),d,c)}}else c!=null&&Twd(a,b,c)} +function tTc(a,b,c,d){var e,f;if(b.c.length==0){return}e=pTc(c,d);f=oTc(b);FDb(PDb(new SDb(null,new Swb(f,1)),new CTc),new GTc(a,c,e,d))} +function rmb(a,b){var c,d,e,f;d=a.a.length-1;c=b-a.b&d;f=a.c-b&d;e=a.c-a.b&d;zmb(c=f){umb(a,b);return -1}else{vmb(a,b);return 1}} +function Hvd(a){var b,c,d;d=a.Jh();if(!d){b=0;for(c=a.Ph();c;c=c.Ph()){if(++b>wxe){return c.Qh()}d=c.Jh();if(!!d||c==a){break}}}return d} +function Ue(a,b){var c;if(dE(b)===dE(a)){return true}if(!ZD(b,21)){return false}c=RD(b,21);if(c.gc()!=a.gc()){return false}return a.Ic(c)} +function kNc(a,b){if(a.eb.e){return 1}else if(a.fb.f){return 1}return tb(a)-tb(b)} +function mhb(a,b){uFb(a);if(b==null){return false}if(lhb(a,b)){return true}return a.length==b.length&&lhb(a.toLowerCase(),b.toLowerCase())} +function Hgb(a){var b,c;if(Ddb(a,-129)>0&&Ddb(a,128)<0){return Jgb(),b=Ydb(a)+128,c=Igb[b],!c&&(c=Igb[b]=new zgb(a)),c}return new zgb(a)} +function U$b(){U$b=geb;T$b=new V$b(LAe,0);R$b=new V$b('INSIDE_PORT_SIDE_GROUPS',1);Q$b=new V$b('GROUP_MODEL_ORDER',2);S$b=new V$b(MAe,3)} +function ufe(a){var b;a.b||vfe(a,(b=Hee(a.e,a.a),!b||!lhb(GGe,$Nd((!b.b&&(b.b=new SVd((JTd(),FTd),C8,b)),b.b),'qualified'))));return a.c} +function BA(a,b){var c,d;c=(BFb(b,a.length),a.charCodeAt(b));d=b+1;while(d2000){Oz=a;Pz=$wnd.setTimeout(Yz,10)}}if(Nz++==0){_z(($z(),Zz));return true}return false} +function lBb(a,b,c){var d;(bBb?(jBb(a),true):cBb?(SAb(),true):fBb?(SAb(),true):eBb&&(SAb(),false))&&(d=new aBb(b),d.b=c,hBb(a,d),undefined)} +function oNb(a,b){var c;c=!a.A.Hc((Qpd(),Ppd))||a.q==(Bod(),wod);a.u.Hc((Pod(),Lod))?c?mNb(a,b):qNb(a,b):a.u.Hc(Nod)&&(c?nNb(a,b):rNb(a,b))} +function Bed(a){var b;if(dE(Gxd(a,(umd(),Xkd)))===dE((Fnd(),Dnd))){if(!vCd(a)){Ixd(a,Xkd,End)}else{b=RD(Gxd(vCd(a),Xkd),346);Ixd(a,Xkd,b)}}} +function _fc(a){var b,c;if(nQb(a.d.i,(yCc(),tBc))){b=RD(mQb(a.c.i,tBc),17);c=RD(mQb(a.d.i,tBc),17);return hgb(b.a,c.a)>0}else{return false}} +function g_b(a,b,c){return new Uid($wnd.Math.min(a.a,b.a)-c/2,$wnd.Math.min(a.b,b.b)-c/2,$wnd.Math.abs(a.a-b.a)+c,$wnd.Math.abs(a.b-b.b)+c)} +function _mc(a){var b;this.d=new bnb;this.j=new pjd;this.g=new pjd;b=a.g.b;this.f=RD(mQb(Y2b(b),(yCc(),rAc)),88);this.e=Kfb(UD(k2b(b,ZBc)))} +function onc(a){this.d=new bnb;this.e=new gub;this.c=$C(kE,Pwe,28,(qpd(),cD(WC(E3,1),NAe,64,0,[opd,Yod,Xod,npd,ppd])).length,15,1);this.b=a} +function $pc(a,b,c){var d;d=c[a.g][b];switch(a.g){case 1:case 3:return new rjd(0,d);case 2:case 4:return new rjd(d,0);default:return null;}} +function Ced(b,c,d){var e,f;f=RD(ltd(c.f),205);try{f.rf(b,d);mtd(c.f,f)}catch(a){a=zdb(a);if(ZD(a,103)){e=a;throw Adb(e)}else throw Adb(a)}} +function tEd(a,b,c){var d,e,f,g,h,i;d=null;h=vgd(ygd(),b);f=null;if(h){e=null;i=zhd(h,c);g=null;i!=null&&(g=a.qf(h,i));e=g;f=e}d=f;return d} +function sSd(a,b,c,d){var e;e=a.length;if(b>=e)return e;for(b=b>0?b:0;bd&&bD(b,d,null);return b} +function lob(a,b){var c,d;d=a.a.length;b.lengthd&&bD(b,d,null);return b} +function Bde(a,b){var c,d;++a.j;if(b!=null){c=(d=a.a.Cb,ZD(d,99)?RD(d,99).th():null);if(Jnb(b,c)){$wd(a.a,4,c);return}}$wd(a.a,4,RD(b,129))} +function mne(a){var b;if(a==null)return null;b=Hqe(nue(a,true));if(b==null){throw Adb(new Mle("Invalid hexBinary value: '"+a+"'"))}return b} +function wA(a,b,c){var d;if(b.a.length>0){Rmb(a.b,new kB(b.a,c));d=b.a.length;0d&&(b.a+=Hhb($C(hE,zwe,28,-d,15,1)))}} +function yIb(a,b,c){var d,e,f;if(c[b.d]){return}c[b.d]=true;for(e=new Anb(CIb(b));e.a=a.b>>1){d=a.c;for(c=a.b;c>b;--c){d=d.b}}else{d=a.a.a;for(c=0;c=0?a.Wh(e):Rvd(a,d)):c<0?Rvd(a,d):RD(d,69).wk().Bk(a,a.hi(),c)} +function Fxd(a){var b,c,d;d=(!a.o&&(a.o=new DVd((pvd(),mvd),X4,a,0)),a.o);for(c=d.c.Kc();c.e!=c.i.gc();){b=RD(c.Yj(),44);b.md()}return dOd(d)} +function iGd(a){var b;if(ZD(a.a,4)){b=FId(a.a);if(b==null){throw Adb(new dgb(HGe+a.b+"'. "+DGe+(lfb(b6),b6.k)+EGe))}return b}else{return a.a}} +function iSd(a,b){var c,d;if(a.j.length!=b.j.length)return false;for(c=0,d=a.j.length;c=64&&b<128&&(e=Rdb(e,Sdb(1,b-64)))}return e} +function k2b(a,b){var c,d;d=null;if(nQb(a,(umd(),amd))){c=RD(mQb(a,amd),96);c.pf(b)&&(d=c.of(b))}d==null&&!!Y2b(a)&&(d=mQb(Y2b(a),b));return d} +function i0b(a,b){var c;c=RD(mQb(a,(yCc(),RAc)),75);if(br(b,f0b)){if(!c){c=new Ejd;pQb(a,RAc,c)}else{Xub(c)}}else !!c&&pQb(a,RAc,null);return c} +function tSb(){tSb=geb;sSb=(umd(),Yld);mSb=Ukd;hSb=Dkd;nSb=tld;qSb=(YHb(),UHb);pSb=SHb;rSb=WHb;oSb=RHb;jSb=(eSb(),aSb);iSb=_Rb;kSb=cSb;lSb=dSb} +function PZb(a){NZb();this.c=new bnb;this.d=a;switch(a.g){case 0:case 2:this.a=Fob(MZb);this.b=oxe;break;case 3:case 1:this.a=MZb;this.b=pxe;}} +function c9b(a){var b;if(!Cod(RD(mQb(a,(yCc(),BBc)),101))){return}b=a.b;d9b((tFb(0,b.c.length),RD(b.c[0],30)));d9b(RD(Vmb(b,b.c.length-1),30))} +function ohc(a,b){b.Ug('Self-Loop post-processing',1);FDb(CDb(CDb(EDb(new SDb(null,new Swb(a.b,16)),new uhc),new whc),new yhc),new Ahc);b.Vg()} +function xrd(a,b,c){var d,e;if(a.c){Dyd(a.c,a.c.i+b);Eyd(a.c,a.c.j+c)}else{for(e=new Anb(a.b);e.a=0&&(c.d=a.t);break;case 3:a.t>=0&&(c.a=a.t);}if(a.C){c.b=a.C.b;c.c=a.C.c}} +function JDc(){JDc=geb;IDc=new LDc(mEe,0);FDc=new LDc(BBe,1);GDc=new LDc('LINEAR_SEGMENTS',2);EDc=new LDc('BRANDES_KOEPF',3);HDc=new LDc(lEe,4)} +function IRb(){IRb=geb;FRb=new JRb(_ye,0);ERb=new JRb(aze,1);GRb=new JRb(bze,2);HRb=new JRb(cze,3);FRb.a=false;ERb.a=true;GRb.a=false;HRb.a=true} +function IPb(){IPb=geb;FPb=new JPb(_ye,0);EPb=new JPb(aze,1);GPb=new JPb(bze,2);HPb=new JPb(cze,3);FPb.a=false;EPb.a=true;GPb.a=false;HPb.a=true} +function Ivd(a,b,c,d){var e;if(c>=0){return a.Sh(b,c,d)}else{!!a.Ph()&&(d=(e=a.Fh(),e>=0?a.Ah(d):a.Ph().Th(a,-1-e,null,d)));return a.Ch(b,c,d)}} +function Zyd(a,b){switch(b){case 7:!a.e&&(a.e=new Yie(G4,a,7,4));sLd(a.e);return;case 8:!a.d&&(a.d=new Yie(G4,a,8,5));sLd(a.d);return;}yyd(a,b)} +function Ixd(a,b,c){c==null?(!a.o&&(a.o=new DVd((pvd(),mvd),X4,a,0)),jOd(a.o,b)):(!a.o&&(a.o=new DVd((pvd(),mvd),X4,a,0)),fOd(a.o,b,c));return a} +function Aob(a,b){yob();var c,d,e,f;c=a;f=b;if(ZD(a,21)&&!ZD(b,21)){c=b;f=a}for(e=c.Kc();e.Ob();){d=e.Pb();if(f.Hc(d)){return false}}return true} +function qTc(a,b,c,d){if(b.ac.b){return true}}}return false} +function QD(a,b){if(bE(a)){return !!PD[b]}else if(a.Sm){return !!a.Sm[b]}else if(_D(a)){return !!OD[b]}else if($D(a)){return !!ND[b]}return false} +function udc(a){var b;b=a.a;do{b=RD(hs(new is(Mr(Z2b(b).a.Kc(),new ir))),18).c.i;b.k==(r3b(),o3b)&&a.b.Fc(b)}while(b.k==(r3b(),o3b));a.b=hv(a.b)} +function UGc(a,b){var c,d,e;e=a;for(d=new is(Mr(Z2b(b).a.Kc(),new ir));gs(d);){c=RD(hs(d),18);!!c.c.i.c&&(e=$wnd.Math.max(e,c.c.i.c.p))}return e} +function INb(a,b){var c,d,e;e=0;d=RD(RD(Qc(a.r,b),21),87).Kc();while(d.Ob()){c=RD(d.Pb(),117);e+=c.d.d+c.b.Mf().b+c.d.a;d.Ob()&&(e+=a.w)}return e} +function AMb(a,b){var c,d,e;e=0;d=RD(RD(Qc(a.r,b),21),87).Kc();while(d.Ob()){c=RD(d.Pb(),117);e+=c.d.b+c.b.Mf().a+c.d.c;d.Ob()&&(e+=a.w)}return e} +function O2c(a){var b,c,d,e;d=0;e=Q2c(a);if(e.c.length==0){return 1}else{for(c=new Anb(e);c.a=0?a.Lh(g,c,true):Qvd(a,f,c)):RD(f,69).wk().yk(a,a.hi(),e,c,d)} +function aNb(a,b,c,d){var e,f;f=b.pf((umd(),ild))?RD(b.of(ild),21):a.j;e=lMb(f);if(e==(hMb(),gMb)){return}if(c&&!jMb(e)){return}LKb(cNb(a,e,d),b)} +function Y6b(a){switch(a.g){case 1:return mOb(),lOb;case 3:return mOb(),iOb;case 2:return mOb(),kOb;case 4:return mOb(),jOb;default:return null;}} +function kmc(a,b,c){if(a.e){switch(a.b){case 1:Ulc(a.c,b,c);break;case 0:Vlc(a.c,b,c);}}else{Slc(a.c,b,c)}a.a[b.p][c.p]=a.c.i;a.a[c.p][b.p]=a.c.e} +function LLc(a){var b,c;if(a==null){return null}c=$C(jR,Nve,199,a.length,0,2);for(b=0;b=0)return e;if(a.ol()){for(d=0;d=e)throw Adb(new aMd(b,e));if(a.Si()){d=a.dd(c);if(d>=0&&d!=b){throw Adb(new agb(LIe))}}return a.Xi(b,c)} +function wx(a,b){this.a=RD(Qb(a),253);this.b=RD(Qb(b),253);if(a.Ed(b)>0||a==(Wk(),Vk)||b==(kl(),jl)){throw Adb(new agb('Invalid range: '+Dx(a,b)))}} +function p_b(a){var b,c;this.b=new bnb;this.c=a;this.a=false;for(c=new Anb(a.a);c.a0);if((b&-b)==b){return eE(b*Kwb(a,31)*4.6566128730773926E-10)}do{c=Kwb(a,31);d=c%b}while(c-d+(b-1)<0);return eE(d)} +function d2b(a,b,c){switch(c.g){case 1:a.a=b.a/2;a.b=0;break;case 2:a.a=b.a;a.b=b.b/2;break;case 3:a.a=b.a/2;a.b=b.b;break;case 4:a.a=0;a.b=b.b/2;}} +function Onc(a,b,c,d){var e,f;for(e=b;e1&&(f=xIb(a,b));return f} +function yqd(a){var b;b=Kfb(UD(Gxd(a,(umd(),lmd))))*$wnd.Math.sqrt((!a.a&&(a.a=new C5d(J4,a,10,11)),a.a).i);return new rjd(b,b/Kfb(UD(Gxd(a,kmd))))} +function Dzd(a){var b;if(!!a.f&&a.f.Vh()){b=RD(a.f,54);a.f=RD(Vvd(a,b),84);a.f!=b&&(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,9,8,b,a.f))}return a.f} +function Ezd(a){var b;if(!!a.i&&a.i.Vh()){b=RD(a.i,54);a.i=RD(Vvd(a,b),84);a.i!=b&&(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,9,7,b,a.i))}return a.i} +function Z5d(a){var b;if(!!a.b&&(a.b.Db&64)!=0){b=a.b;a.b=RD(Vvd(a,b),19);a.b!=b&&(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,9,21,b,a.b))}return a.b} +function UNd(a,b){var c,d,e;if(a.d==null){++a.e;++a.f}else{d=b.Bi();_Nd(a,a.f+1);e=(d&lve)%a.d.length;c=a.d[e];!c&&(c=a.d[e]=a.dk());c.Fc(b);++a.f}} +function Mge(a,b,c){var d;if(b.tk()){return false}else if(b.Ik()!=-2){d=b.ik();return d==null?c==null:pb(d,c)}else return b.qk()==a.e.Dh()&&c==null} +function Io(){var a;dk(16,fwe);a=Wp(16);this.b=$C(XF,ewe,303,a,0,1);this.c=$C(XF,ewe,303,a,0,1);this.a=null;this.e=null;this.i=0;this.f=a-1;this.g=0} +function j3b(a){v2b.call(this);this.k=(r3b(),p3b);this.j=(dk(6,iwe),new cnb(6));this.b=(dk(2,iwe),new cnb(2));this.d=new T2b;this.f=new C3b;this.a=a} +function wgc(a){var b,c;if(a.c.length<=1){return}b=tgc(a,(qpd(),npd));vgc(a,RD(b.a,17).a,RD(b.b,17).a);c=tgc(a,ppd);vgc(a,RD(c.a,17).a,RD(c.b,17).a)} +function vHc(a,b,c){var d,e;e=a.a.b;for(d=e.c.length;d102)return -1;if(a<=57)return a-48;if(a<65)return -1;if(a<=70)return a-65+10;if(a<97)return -1;return a-97+10} +function ck(a,b){if(a==null){throw Adb(new Ogb('null key in entry: null='+b))}else if(b==null){throw Adb(new Ogb('null value in entry: '+a+'=null'))}} +function Cr(a,b){var c,d;while(a.Ob()){if(!b.Ob()){return false}c=a.Pb();d=b.Pb();if(!(dE(c)===dE(d)||c!=null&&pb(c,d))){return false}}return !b.Ob()} +function aLb(a,b){var c;c=cD(WC(iE,1),vxe,28,15,[gKb(a.a[0],b),gKb(a.a[1],b),gKb(a.a[2],b)]);if(a.d){c[0]=$wnd.Math.max(c[0],c[2]);c[2]=c[0]}return c} +function bLb(a,b){var c;c=cD(WC(iE,1),vxe,28,15,[hKb(a.a[0],b),hKb(a.a[1],b),hKb(a.a[2],b)]);if(a.d){c[0]=$wnd.Math.max(c[0],c[2]);c[2]=c[0]}return c} +function vIc(a,b,c){if(!Cod(RD(mQb(b,(yCc(),BBc)),101))){uIc(a,b,e3b(b,c));uIc(a,b,e3b(b,(qpd(),npd)));uIc(a,b,e3b(b,Yod));yob();_mb(b.j,new JIc(a))}} +function sUc(a){var b,c;a.c||vUc(a);c=new Ejd;b=new Anb(a.a);ynb(b);while(b.a0&&(BFb(0,b.length),b.charCodeAt(0)==43)?(BFb(1,b.length+1),b.substr(1)):b))} +function qne(a){var b;return a==null?null:new ejb((b=nue(a,true),b.length>0&&(BFb(0,b.length),b.charCodeAt(0)==43)?(BFb(1,b.length+1),b.substr(1)):b))} +function Syb(a,b,c,d,e,f,g,h){var i,j;if(!d){return}i=d.a[0];!!i&&Syb(a,b,c,i,e,f,g,h);Tyb(a,c,d.d,e,f,g,h)&&b.Fc(d);j=d.a[1];!!j&&Syb(a,b,c,j,e,f,g,h)} +function PPb(b,c,d){try{return Gdb(SPb(b,c,d),1)}catch(a){a=zdb(a);if(ZD(a,333)){throw Adb(new veb(fze+b.o+'*'+b.p+gze+c+pve+d+hze))}else throw Adb(a)}} +function QPb(b,c,d){try{return Gdb(SPb(b,c,d),0)}catch(a){a=zdb(a);if(ZD(a,333)){throw Adb(new veb(fze+b.o+'*'+b.p+gze+c+pve+d+hze))}else throw Adb(a)}} +function RPb(b,c,d){try{return Gdb(SPb(b,c,d),2)}catch(a){a=zdb(a);if(ZD(a,333)){throw Adb(new veb(fze+b.o+'*'+b.p+gze+c+pve+d+hze))}else throw Adb(a)}} +function lMd(b,c){if(b.g==-1){throw Adb(new cgb)}b.Xj();try{b.d.hd(b.g,c);b.f=b.d.j}catch(a){a=zdb(a);if(ZD(a,77)){throw Adb(new Jrb)}else throw Adb(a)}} +function Y7b(a){var b,c,d,e,f;for(d=new Anb(a.b);d.af&&bD(b,f,null);return b} +function av(a,b){var c,d;d=a.gc();if(b==null){for(c=0;c0&&(i+=e);j[k]=g;g+=h*(i+d)}} +function vsc(a){var b,c,d;d=a.f;a.n=$C(iE,vxe,28,d,15,1);a.d=$C(iE,vxe,28,d,15,1);for(b=0;b0?a.c:0);++e}a.b=d;a.d=f} +function rKb(a,b){var c;c=cD(WC(iE,1),vxe,28,15,[qKb(a,(ZJb(),WJb),b),qKb(a,XJb,b),qKb(a,YJb,b)]);if(a.f){c[0]=$wnd.Math.max(c[0],c[2]);c[2]=c[0]}return c} +function cQb(b,c,d){var e;try{TPb(b,c+b.j,d+b.k,false,true)}catch(a){a=zdb(a);if(ZD(a,77)){e=a;throw Adb(new veb(e.g+ize+c+pve+d+').'))}else throw Adb(a)}} +function dQb(b,c,d){var e;try{TPb(b,c+b.j,d+b.k,true,false)}catch(a){a=zdb(a);if(ZD(a,77)){e=a;throw Adb(new veb(e.g+ize+c+pve+d+').'))}else throw Adb(a)}} +function u8b(a){var b;if(!nQb(a,(yCc(),dBc))){return}b=RD(mQb(a,dBc),21);if(b.Hc((dod(),Xnd))){b.Mc(Xnd);b.Fc(Znd)}else if(b.Hc(Znd)){b.Mc(Znd);b.Fc(Xnd)}} +function v8b(a){var b;if(!nQb(a,(yCc(),dBc))){return}b=RD(mQb(a,dBc),21);if(b.Hc((dod(),cod))){b.Mc(cod);b.Fc(aod)}else if(b.Hc(aod)){b.Mc(aod);b.Fc(cod)}} +function oqc(a,b,c,d){var e,f,g,h;a.a==null&&rqc(a,b);g=b.b.j.c.length;f=c.d.p;h=d.d.p;e=h-1;e<0&&(e=g-1);return f<=e?a.a[e]-a.a[f]:a.a[g-1]-a.a[f]+a.a[e]} +function Cud(a){var b,c;if(!a.b){a.b=fv(RD(a.f,27).kh().i);for(c=new dMd(RD(a.f,27).kh());c.e!=c.i.gc();){b=RD(bMd(c),135);Rmb(a.b,new Bud(b))}}return a.b} +function Dud(a){var b,c;if(!a.e){a.e=fv(wCd(RD(a.f,27)).i);for(c=new dMd(wCd(RD(a.f,27)));c.e!=c.i.gc();){b=RD(bMd(c),123);Rmb(a.e,new Rud(b))}}return a.e} +function yud(a){var b,c;if(!a.a){a.a=fv(tCd(RD(a.f,27)).i);for(c=new dMd(tCd(RD(a.f,27)));c.e!=c.i.gc();){b=RD(bMd(c),27);Rmb(a.a,new Fud(a,b))}}return a.a} +function DXd(b){var c;if(!b.C&&(b.D!=null||b.B!=null)){c=EXd(b);if(c){b.hl(c)}else{try{b.hl(null)}catch(a){a=zdb(a);if(!ZD(a,63))throw Adb(a)}}}return b.C} +function xMb(a){switch(a.q.g){case 5:uMb(a,(qpd(),Yod));uMb(a,npd);break;case 4:vMb(a,(qpd(),Yod));vMb(a,npd);break;default:wMb(a,(qpd(),Yod));wMb(a,npd);}} +function GNb(a){switch(a.q.g){case 5:DNb(a,(qpd(),Xod));DNb(a,ppd);break;case 4:ENb(a,(qpd(),Xod));ENb(a,ppd);break;default:FNb(a,(qpd(),Xod));FNb(a,ppd);}} +function G$b(a,b){var c,d,e;e=new pjd;for(d=a.Kc();d.Ob();){c=RD(d.Pb(),36);w$b(c,e.a,0);e.a+=c.f.a+b;e.b=$wnd.Math.max(e.b,c.f.b)}e.b>0&&(e.b+=b);return e} +function I$b(a,b){var c,d,e;e=new pjd;for(d=a.Kc();d.Ob();){c=RD(d.Pb(),36);w$b(c,0,e.b);e.b+=c.f.b+b;e.a=$wnd.Math.max(e.a,c.f.a)}e.a>0&&(e.a+=b);return e} +function l2b(a){var b,c,d;d=lve;for(c=new Anb(a.a);c.a>16==6){return a.Cb.Th(a,5,t7,b)}return d=Z5d(RD(vYd((c=RD(Ywd(a,16),29),!c?a.ii():c),a.Db>>16),19)),a.Cb.Th(a,d.n,d.f,b)} +function kA(a){fA();var b=a.e;if(b&&b.stack){var c=b.stack;var d=b+'\n';c.substring(0,d.length)==d&&(c=c.substring(d.length));return c.split('\n')}return []} +function pgb(a){var b;b=(wgb(),vgb);return b[a>>>28]|b[a>>24&15]<<4|b[a>>20&15]<<8|b[a>>16&15]<<12|b[a>>12&15]<<16|b[a>>8&15]<<20|b[a>>4&15]<<24|b[a&15]<<28} +function mmb(a){var b,c,d;if(a.b!=a.c){return}d=a.a.length;c=mgb($wnd.Math.max(8,d))<<1;if(a.b!=0){b=WEb(a.a,c);lmb(a,b,d);a.a=b;a.b=0}else{aFb(a.a,c)}a.c=d} +function uNb(a,b){var c;c=a.b;return c.pf((umd(),Gld))?c.ag()==(qpd(),ppd)?-c.Mf().a-Kfb(UD(c.of(Gld))):b+Kfb(UD(c.of(Gld))):c.ag()==(qpd(),ppd)?-c.Mf().a:b} +function X2b(a){var b;if(a.b.c.length!=0&&!!RD(Vmb(a.b,0),72).a){return RD(Vmb(a.b,0),72).a}b=R0b(a);if(b!=null){return b}return ''+(!a.c?-1:Wmb(a.c.a,a,0))} +function M3b(a){var b;if(a.f.c.length!=0&&!!RD(Vmb(a.f,0),72).a){return RD(Vmb(a.f,0),72).a}b=R0b(a);if(b!=null){return b}return ''+(!a.i?-1:Wmb(a.i.j,a,0))} +function skc(a,b){var c,d;if(b<0||b>=a.gc()){return null}for(c=b;c0?a.c:0);e=$wnd.Math.max(e,b.d);++d}a.e=f;a.b=e} +function Qud(a){var b,c;if(!a.b){a.b=fv(RD(a.f,123).kh().i);for(c=new dMd(RD(a.f,123).kh());c.e!=c.i.gc();){b=RD(bMd(c),135);Rmb(a.b,new Bud(b))}}return a.b} +function aHd(a,b){var c,d,e;if(b.dc()){return jQd(),jQd(),iQd}else{c=new ZLd(a,b.gc());for(e=new dMd(a);e.e!=e.i.gc();){d=bMd(e);b.Hc(d)&&WGd(c,d)}return c}} +function Axd(a,b,c,d){if(b==0){return d?(!a.o&&(a.o=new DVd((pvd(),mvd),X4,a,0)),a.o):(!a.o&&(a.o=new DVd((pvd(),mvd),X4,a,0)),dOd(a.o))}return Dvd(a,b,c,d)} +function rBd(a){var b,c;if(a.rb){for(b=0,c=a.rb.i;b>22);e+=d>>22;if(e<0){return false}a.l=c&dxe;a.m=d&dxe;a.h=e&exe;return true} +function Tyb(a,b,c,d,e,f,g){var h,i;if(b.Te()&&(i=a.a.Ne(c,d),i<0||!e&&i==0)){return false}if(b.Ue()&&(h=a.a.Ne(c,f),h>0||!g&&h==0)){return false}return true} +function Agc(a,b){sgc();var c;c=a.j.g-b.j.g;if(c!=0){return 0}switch(a.j.g){case 2:return Cgc(b,rgc)-Cgc(a,rgc);case 4:return Cgc(a,qgc)-Cgc(b,qgc);}return 0} +function uuc(a){switch(a.g){case 0:return nuc;case 1:return ouc;case 2:return puc;case 3:return quc;case 4:return ruc;case 5:return suc;default:return null;}} +function cBd(a,b,c){var d,e;d=(e=new R5d,YVd(e,b),PAd(e,c),WGd((!a.c&&(a.c=new C5d(u7,a,12,10)),a.c),e),e);$Vd(d,0);bWd(d,1);aWd(d,true);_Vd(d,true);return d} +function THd(a,b){var c,d;if(b>=a.i)throw Adb(new yNd(b,a.i));++a.j;c=a.g[b];d=a.i-b-1;d>0&&hib(a.g,b+1,a.g,b,d);bD(a.g,--a.i,null);a.Qi(b,c);a.Ni();return c} +function sWd(a,b){var c,d;if(a.Db>>16==17){return a.Cb.Th(a,21,h7,b)}return d=Z5d(RD(vYd((c=RD(Ywd(a,16),29),!c?a.ii():c),a.Db>>16),19)),a.Cb.Th(a,d.n,d.f,b)} +function _Fb(a){var b,c,d,e;yob();_mb(a.c,a.a);for(e=new Anb(a.c);e.ac.a.c.length)){throw Adb(new agb('index must be >= 0 and <= layer node count'))}!!a.c&&Ymb(a.c.a,a);a.c=c;!!c&&Qmb(c.a,b,a)} +function Gac(a,b){var c,d,e;for(d=new is(Mr(W2b(a).a.Kc(),new ir));gs(d);){c=RD(hs(d),18);e=RD(b.Kb(c),10);return new cc(Qb(e.n.b+e.o.b/2))}return wb(),wb(),vb} +function RQc(a,b){this.c=new Tsb;this.a=a;this.b=b;this.d=RD(mQb(a,(Ywc(),Qwc)),312);dE(mQb(a,(yCc(),eBc)))===dE((Cuc(),Auc))?(this.e=new BRc):(this.e=new uRc)} +function ftd(a,b){var c,d;d=null;if(a.pf((umd(),amd))){c=RD(a.of(amd),96);c.pf(b)&&(d=c.of(b))}d==null&&!!a.Tf()&&(d=a.Tf().of(b));d==null&&(d=iGd(b));return d} +function ku(b,c){var d,e;d=b.fd(c);try{e=d.Pb();d.Qb();return e}catch(a){a=zdb(a);if(ZD(a,112)){throw Adb(new veb("Can't remove element "+c))}else throw Adb(a)}} +function GA(a,b){var c,d,e;d=new uB;e=new vB(d.q.getFullYear()-Owe,d.q.getMonth(),d.q.getDate());c=FA(a,b,e);if(c==0||c0?b:0);++c}return new rjd(d,e)} +function Czd(a,b){var c,d;if(a.Db>>16==6){return a.Cb.Th(a,6,G4,b)}return d=Z5d(RD(vYd((c=RD(Ywd(a,16),29),!c?(pvd(),hvd):c),a.Db>>16),19)),a.Cb.Th(a,d.n,d.f,b)} +function cCd(a,b){var c,d;if(a.Db>>16==7){return a.Cb.Th(a,1,H4,b)}return d=Z5d(RD(vYd((c=RD(Ywd(a,16),29),!c?(pvd(),jvd):c),a.Db>>16),19)),a.Cb.Th(a,d.n,d.f,b)} +function LCd(a,b){var c,d;if(a.Db>>16==9){return a.Cb.Th(a,9,J4,b)}return d=Z5d(RD(vYd((c=RD(Ywd(a,16),29),!c?(pvd(),lvd):c),a.Db>>16),19)),a.Cb.Th(a,d.n,d.f,b)} +function M1d(a,b){var c,d;if(a.Db>>16==5){return a.Cb.Th(a,9,m7,b)}return d=Z5d(RD(vYd((c=RD(Ywd(a,16),29),!c?(JTd(),tTd):c),a.Db>>16),19)),a.Cb.Th(a,d.n,d.f,b)} +function qBd(a,b){var c,d;if(a.Db>>16==7){return a.Cb.Th(a,6,t7,b)}return d=Z5d(RD(vYd((c=RD(Ywd(a,16),29),!c?(JTd(),CTd):c),a.Db>>16),19)),a.Cb.Th(a,d.n,d.f,b)} +function iVd(a,b){var c,d;if(a.Db>>16==3){return a.Cb.Th(a,0,p7,b)}return d=Z5d(RD(vYd((c=RD(Ywd(a,16),29),!c?(JTd(),mTd):c),a.Db>>16),19)),a.Cb.Th(a,d.n,d.f,b)} +function IEd(){this.a=new BDd;this.g=new Io;this.j=new Io;this.b=new Tsb;this.d=new Io;this.i=new Io;this.k=new Tsb;this.c=new Tsb;this.e=new Tsb;this.f=new Tsb} +function kQd(a,b,c){var d,e,f;c<0&&(c=0);f=a.i;for(e=c;ewxe){return Oje(a,d)}if(d==a){return true}}}return false} +function yNb(a){tNb();switch(a.q.g){case 5:vNb(a,(qpd(),Yod));vNb(a,npd);break;case 4:wNb(a,(qpd(),Yod));wNb(a,npd);break;default:xNb(a,(qpd(),Yod));xNb(a,npd);}} +function CNb(a){tNb();switch(a.q.g){case 5:zNb(a,(qpd(),Xod));zNb(a,ppd);break;case 4:ANb(a,(qpd(),Xod));ANb(a,ppd);break;default:BNb(a,(qpd(),Xod));BNb(a,ppd);}} +function RTb(a){var b,c;b=RD(mQb(a,(yVb(),mVb)),17);if(b){c=b.a;c==0?pQb(a,(JVb(),IVb),new Owb):pQb(a,(JVb(),IVb),new Pwb(c))}else{pQb(a,(JVb(),IVb),new Pwb(1))}} +function b2b(a,b){var c;c=a.i;switch(b.g){case 1:return -(a.n.b+a.o.b);case 2:return a.n.a-c.o.a;case 3:return a.n.b-c.o.b;case 4:return -(a.n.a+a.o.a);}return 0} +function wec(a,b){switch(a.g){case 0:return b==(cxc(),$wc)?sec:tec;case 1:return b==(cxc(),$wc)?sec:rec;case 2:return b==(cxc(),$wc)?rec:tec;default:return rec;}} +function Fad(a,b){var c,d,e;Ymb(a.a,b);a.e-=b.r+(a.a.c.length==0?0:a.c);e=fFe;for(d=new Anb(a.a);d.a>16==3){return a.Cb.Th(a,12,J4,b)}return d=Z5d(RD(vYd((c=RD(Ywd(a,16),29),!c?(pvd(),gvd):c),a.Db>>16),19)),a.Cb.Th(a,d.n,d.f,b)} +function sCd(a,b){var c,d;if(a.Db>>16==11){return a.Cb.Th(a,10,J4,b)}return d=Z5d(RD(vYd((c=RD(Ywd(a,16),29),!c?(pvd(),kvd):c),a.Db>>16),19)),a.Cb.Th(a,d.n,d.f,b)} +function n4d(a,b){var c,d;if(a.Db>>16==10){return a.Cb.Th(a,11,h7,b)}return d=Z5d(RD(vYd((c=RD(Ywd(a,16),29),!c?(JTd(),ATd):c),a.Db>>16),19)),a.Cb.Th(a,d.n,d.f,b)} +function Q5d(a,b){var c,d;if(a.Db>>16==10){return a.Cb.Th(a,12,s7,b)}return d=Z5d(RD(vYd((c=RD(Ywd(a,16),29),!c?(JTd(),DTd):c),a.Db>>16),19)),a.Cb.Th(a,d.n,d.f,b)} +function WVd(a){var b;if((a.Bb&1)==0&&!!a.r&&a.r.Vh()){b=RD(a.r,54);a.r=RD(Vvd(a,b),142);a.r!=b&&(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,9,8,b,a.r))}return a.r} +function pKb(a,b,c){var d;d=cD(WC(iE,1),vxe,28,15,[sKb(a,(ZJb(),WJb),b,c),sKb(a,XJb,b,c),sKb(a,YJb,b,c)]);if(a.f){d[0]=$wnd.Math.max(d[0],d[2]);d[2]=d[0]}return d} +function ddc(a,b){var c,d,e;e=kdc(a,b);if(e.c.length==0){return}_mb(e,new Gdc);c=e.c.length;for(d=0;d>19;j=b.h>>19;if(i!=j){return j-i}e=a.h;h=b.h;if(e!=h){return e-h}d=a.m;g=b.m;if(d!=g){return d-g}c=a.l;f=b.l;return c-f} +function YHb(){YHb=geb;XHb=(iIb(),fIb);WHb=new lGd(Aye,XHb);VHb=(LHb(),KHb);UHb=new lGd(Bye,VHb);THb=(DHb(),CHb);SHb=new lGd(Cye,THb);RHb=new lGd(Dye,(Geb(),true))} +function Iic(a,b,c){var d,e;d=b*c;if(ZD(a.g,154)){e=$jc(a);if(e.f.d){e.f.a||(a.d.a+=d+Tye)}else{a.d.d-=d+Tye;a.d.a+=d+Tye}}else if(ZD(a.g,10)){a.d.d-=d;a.d.a+=2*d}} +function _pc(a,b,c){var d,e,f,g,h;e=a[c.g];for(h=new Anb(b.d);h.a0?a.b:0);++c}b.b=d;b.e=e} +function Fo(a){var b,c,d;d=a.b;if(Xp(a.i,d.length)){c=d.length*2;a.b=$C(XF,ewe,303,c,0,1);a.c=$C(XF,ewe,303,c,0,1);a.f=c-1;a.i=0;for(b=a.a;b;b=b.c){Bo(a,b,b)}++a.g}} +function VPb(a,b,c,d){var e,f,g,h;for(e=0;eg&&(h=g/d);e>f&&(i=f/e);ijd(a,$wnd.Math.min(h,i));return a} +function OAd(){qAd();var b,c;try{c=RD(M5d((YSd(),XSd),$He),2113);if(c){return c}}catch(a){a=zdb(a);if(ZD(a,103)){b=a;UId((Hde(),b))}else throw Adb(a)}return new KAd} +function Qae(){qAd();var b,c;try{c=RD(M5d((YSd(),XSd),AKe),2040);if(c){return c}}catch(a){a=zdb(a);if(ZD(a,103)){b=a;UId((Hde(),b))}else throw Adb(a)}return new Mae} +function vne(){Zme();var b,c;try{c=RD(M5d((YSd(),XSd),dLe),2122);if(c){return c}}catch(a){a=zdb(a);if(ZD(a,103)){b=a;UId((Hde(),b))}else throw Adb(a)}return new rne} +function f2d(a,b,c){var d,e;e=a.e;a.e=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new N3d(a,1,4,e,b);!c?(c=d):c.nj(d)}e!=b&&(b?(c=o2d(a,k2d(a,b),c)):(c=o2d(a,a.a,c)));return c} +function DB(){uB.call(this);this.e=-1;this.a=false;this.p=qwe;this.k=-1;this.c=-1;this.b=-1;this.g=false;this.f=-1;this.j=-1;this.n=-1;this.i=-1;this.d=-1;this.o=qwe} +function hHb(a,b){var c,d,e;d=a.b.d.d;a.a||(d+=a.b.d.a);e=b.b.d.d;b.a||(e+=b.b.d.a);c=Qfb(d,e);if(c==0){if(!a.a&&b.a){return -1}else if(!b.a&&a.a){return 1}}return c} +function XQb(a,b){var c,d,e;d=a.b.b.d;a.a||(d+=a.b.b.a);e=b.b.b.d;b.a||(e+=b.b.b.a);c=Qfb(d,e);if(c==0){if(!a.a&&b.a){return -1}else if(!b.a&&a.a){return 1}}return c} +function RYb(a,b){var c,d,e;d=a.b.g.d;a.a||(d+=a.b.g.a);e=b.b.g.d;b.a||(e+=b.b.g.a);c=Qfb(d,e);if(c==0){if(!a.a&&b.a){return -1}else if(!b.a&&a.a){return 1}}return c} +function _Wb(){_Wb=geb;YWb=nfd(pfd(pfd(pfd(new ufd,(sXb(),qXb),(hcc(),Dbc)),qXb,Hbc),rXb,Obc),rXb,rbc);$Wb=pfd(pfd(new ufd,qXb,hbc),qXb,sbc);ZWb=nfd(new ufd,rXb,ubc)} +function J6b(a){var b,c,d,e,f;b=RD(mQb(a,(Ywc(),cwc)),85);f=a.n;for(d=b.Cc().Kc();d.Ob();){c=RD(d.Pb(),314);e=c.i;e.c+=f.a;e.d+=f.b;c.c?MKb(c):OKb(c)}pQb(a,cwc,null)} +function Wpc(a,b,c){var d,e;e=a.b;d=e.d;switch(b.g){case 1:return -d.d-c;case 2:return e.o.a+d.c+c;case 3:return e.o.b+d.a+c;case 4:return -d.b-c;default:return -1;}} +function CNc(a,b,c){var d,e;c.Ug('Interactive node placement',1);a.a=RD(mQb(b,(Ywc(),Qwc)),312);for(e=new Anb(b.b);e.a0){g=(f&lve)%a.d.length;e=WNd(a,g,f,b);if(e){h=e.nd(c);return h}}d=a.ck(f,b,c);a.c.Fc(d);return null} +function Tee(a,b){var c,d,e,f;switch(Oee(a,b).Kl()){case 3:case 2:{c=mYd(b);for(e=0,f=c.i;e=0;d--){if(lhb(a[d].d,b)||lhb(a[d].d,c)){a.length>=d+1&&a.splice(0,d+1);break}}return a} +function Fdb(a,b){var c;if(Kdb(a)&&Kdb(b)){c=a/b;if(jxe0){a.b+=2;a.a+=d}}else{a.b+=1;a.a+=$wnd.Math.min(d,e)}} +function CVc(a){var b;b=RD(mQb(RD(ju(a.b,0),40),(h_c(),T$c)),107);pQb(a,(q$c(),SZc),new rjd(0,0));FVc(new YWc,a,b.b+b.c-Kfb(UD(mQb(a,ZZc))),b.d+b.a-Kfb(UD(mQb(a,_Zc))))} +function pDd(a,b){var c,d;d=false;if(bE(b)){d=true;oDd(a,new OC(WD(b)))}if(!d){if(ZD(b,242)){d=true;oDd(a,(c=Qeb(RD(b,242)),new hC(c)))}}if(!d){throw Adb(new Aeb(tIe))}} +function g$d(a,b,c,d){var e,f,g;e=new P3d(a.e,1,10,(g=b.c,ZD(g,90)?RD(g,29):(JTd(),zTd)),(f=c.c,ZD(f,90)?RD(f,29):(JTd(),zTd)),fZd(a,b),false);!d?(d=e):d.nj(e);return d} +function _2b(a){var b,c;switch(RD(mQb(Y2b(a),(yCc(),QAc)),429).g){case 0:b=a.n;c=a.o;return new rjd(b.a+c.a/2,b.b+c.b/2);case 1:return new sjd(a.n);default:return null;}} +function Ouc(){Ouc=geb;Luc=new Puc(LAe,0);Kuc=new Puc('LEFTUP',1);Nuc=new Puc('RIGHTUP',2);Juc=new Puc('LEFTDOWN',3);Muc=new Puc('RIGHTDOWN',4);Iuc=new Puc('BALANCED',5)} +function dKc(a,b,c){var d,e,f;d=Qfb(a.a[b.p],a.a[c.p]);if(d==0){e=RD(mQb(b,(Ywc(),qwc)),15);f=RD(mQb(c,qwc),15);if(e.Hc(c)){return -1}else if(f.Hc(b)){return 1}}return d} +function k5c(a){switch(a.g){case 1:return new K3c;case 2:return new M3c;case 3:return new I3c;case 0:return null;default:throw Adb(new agb(mFe+(a.f!=null?a.f:''+a.g)));}} +function gyd(a,b,c){switch(b){case 1:!a.n&&(a.n=new C5d(I4,a,1,7));sLd(a.n);!a.n&&(a.n=new C5d(I4,a,1,7));YGd(a.n,RD(c,16));return;case 2:jyd(a,WD(c));return;}Dxd(a,b,c)} +function xyd(a,b,c){switch(b){case 3:Ayd(a,Kfb(UD(c)));return;case 4:Cyd(a,Kfb(UD(c)));return;case 5:Dyd(a,Kfb(UD(c)));return;case 6:Eyd(a,Kfb(UD(c)));return;}gyd(a,b,c)} +function dBd(a,b,c){var d,e,f;f=(d=new R5d,d);e=XVd(f,b,null);!!e&&e.oj();PAd(f,c);WGd((!a.c&&(a.c=new C5d(u7,a,12,10)),a.c),f);$Vd(f,0);bWd(f,1);aWd(f,true);_Vd(f,true)} +function M5d(a,b){var c,d,e;c=Ktb(a.i,b);if(ZD(c,241)){e=RD(c,241);e.zi()==null&&undefined;return e.wi()}else if(ZD(c,507)){d=RD(c,2037);e=d.b;return e}else{return null}} +function aj(a,b,c,d){var e,f;Qb(b);Qb(c);f=RD(Fn(a.d,b),17);Ob(!!f,'Row %s not in %s',b,a.e);e=RD(Fn(a.b,c),17);Ob(!!e,'Column %s not in %s',c,a.c);return cj(a,f.a,e.a,d)} +function ZC(a,b,c,d,e,f,g){var h,i,j,k,l;k=e[f];j=f==g-1;h=j?d:0;l=_C(h,k);d!=10&&cD(WC(a,g-f),b[f],c[f],h,l);if(!j){++f;for(i=0;i1||h==-1){f=RD(i,15);e.Wb(Sje(a,f))}else{e.Wb(Rje(a,RD(i,58)))}}}} +function ceb(b,c,d,e){beb();var f=_db;$moduleName=c;$moduleBase=d;ydb=e;function g(){for(var a=0;a0){return false}}return true} +function okc(a){var b,c,d,e,f;for(d=new vkb((new mkb(a.b)).a);d.b;){c=tkb(d);b=RD(c.ld(),10);f=RD(RD(c.md(),42).a,10);e=RD(RD(c.md(),42).b,8);$id(hjd(b.n),$id(ajd(f.n),e))}} +function Roc(a){switch(RD(mQb(a.b,(yCc(),BAc)),387).g){case 1:FDb(GDb(EDb(new SDb(null,new Swb(a.d,16)),new kpc),new mpc),new opc);break;case 2:Toc(a);break;case 0:Soc(a);}} +function SVc(a,b,c){var d,e,f;d=c;!d&&(d=new Oqd);d.Ug('Layout',a.a.c.length);for(f=new Anb(a.a);f.aAEe){return c}else e>-1.0E-6&&++c}return c} +function n2d(a,b){var c;if(b!=a.b){c=null;!!a.b&&(c=Jvd(a.b,a,-4,c));!!b&&(c=Ivd(b,a,-4,c));c=e2d(a,b,c);!!c&&c.oj()}else (a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,3,b,b))} +function q2d(a,b){var c;if(b!=a.f){c=null;!!a.f&&(c=Jvd(a.f,a,-1,c));!!b&&(c=Ivd(b,a,-1,c));c=g2d(a,b,c);!!c&&c.oj()}else (a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,0,b,b))} +function Lge(a,b,c,d){var e,f,g,h;if(Mvd(a.e)){e=b.Lk();h=b.md();f=c.md();g=fge(a,1,e,h,f,e.Jk()?kge(a,e,f,ZD(e,102)&&(RD(e,19).Bb&txe)!=0):-1,true);d?d.nj(g):(d=g)}return d} +function bne(a){var b,c,d;if(a==null)return null;c=RD(a,15);if(c.dc())return '';d=new Qhb;for(b=c.Kc();b.Ob();){Nhb(d,(nme(),WD(b.Pb())));d.a+=' '}return qeb(d,d.a.length-1)} +function fne(a){var b,c,d;if(a==null)return null;c=RD(a,15);if(c.dc())return '';d=new Qhb;for(b=c.Kc();b.Ob();){Nhb(d,(nme(),WD(b.Pb())));d.a+=' '}return qeb(d,d.a.length-1)} +function QIc(a,b,c){var d,e;d=a.c[b.c.p][b.p];e=a.c[c.c.p][c.p];if(d.a!=null&&e.a!=null){return Jfb(d.a,e.a)}else if(d.a!=null){return -1}else if(e.a!=null){return 1}return 0} +function RVc(a,b,c){c.Ug('Tree layout',1);Sed(a.b);Ved(a.b,(YVc(),UVc),UVc);Ved(a.b,VVc,VVc);Ved(a.b,WVc,WVc);Ved(a.b,XVc,XVc);a.a=Qed(a.b,b);SVc(a,b,c.eh(1));c.Vg();return b} +function ZDd(a,b){var c,d,e,f,g,h;if(b){f=b.a.length;c=new vue(f);for(h=(c.b-c.a)*c.c<0?(uue(),tue):new Rue(c);h.Ob();){g=RD(h.Pb(),17);e=xDd(b,g.a);d=new aFd(a);$Dd(d.a,e)}}} +function oEd(a,b){var c,d,e,f,g,h;if(b){f=b.a.length;c=new vue(f);for(h=(c.b-c.a)*c.c<0?(uue(),tue):new Rue(c);h.Ob();){g=RD(h.Pb(),17);e=xDd(b,g.a);d=new LEd(a);NDd(d.a,e)}}} +function ESd(b){var c;if(b!=null&&b.length>0&&ihb(b,b.length-1)==33){try{c=nSd(zhb(b,0,b.length-1));return c.e==null}catch(a){a=zdb(a);if(!ZD(a,33))throw Adb(a)}}return false} +function u0b(a,b,c){var d,e,f;d=Y2b(b);e=i2b(d);f=new R3b;P3b(f,b);switch(c.g){case 1:Q3b(f,spd(vpd(e)));break;case 2:Q3b(f,vpd(e));}pQb(f,(yCc(),ABc),UD(mQb(a,ABc)));return f} +function jdc(a){var b,c;b=RD(hs(new is(Mr(Z2b(a.a).a.Kc(),new ir))),18);c=RD(hs(new is(Mr(a3b(a.a).a.Kc(),new ir))),18);return Heb(TD(mQb(b,(Ywc(),Nwc))))||Heb(TD(mQb(c,Nwc)))} +function Bnc(){Bnc=geb;xnc=new Cnc('ONE_SIDE',0);znc=new Cnc('TWO_SIDES_CORNER',1);Anc=new Cnc('TWO_SIDES_OPPOSING',2);ync=new Cnc('THREE_SIDES',3);wnc=new Cnc('FOUR_SIDES',4)} +function Usc(a,b){var c,d,e,f;f=new bnb;e=0;d=b.Kc();while(d.Ob()){c=sgb(RD(d.Pb(),17).a+e);while(c.a=a.f){break}ZEb(f.c,c)}return f} +function iIc(a,b){var c,d,e,f,g;for(f=new Anb(b.a);f.a0&&Xlc(this,this.c-1,(qpd(),Xod));this.c0&&a[0].length>0&&(this.c=Heb(TD(mQb(Y2b(a[0][0]),(Ywc(),rwc)))));this.a=$C(aY,Nve,2117,a.length,0,2);this.b=$C(dY,Nve,2118,a.length,0,2);this.d=new Ks} +function TOc(a){if(a.c.length==0){return false}if((tFb(0,a.c.length),RD(a.c[0],18)).c.i.k==(r3b(),o3b)){return true}return yDb(GDb(new SDb(null,new Swb(a,16)),new WOc),new YOc)} +function I5c(a,b){var c,d,e,f,g,h,i;h=Q2c(b);f=b.f;i=b.g;g=$wnd.Math.sqrt(f*f+i*i);e=0;for(d=new Anb(h);d.a=0){c=Fdb(a,ixe);d=Mdb(a,ixe)}else{b=Udb(a,1);c=Fdb(b,500000000);d=Mdb(b,500000000);d=Bdb(Sdb(d,1),Cdb(a,1))}return Rdb(Sdb(d,32),Cdb(c,yxe))} +function fTb(a,b,c){var d,e;d=(sFb(b.b!=0),RD(Wub(b,b.a.a),8));switch(c.g){case 0:d.b=0;break;case 2:d.b=a.f;break;case 3:d.a=0;break;default:d.a=a.g;}e=Sub(b,0);cvb(e,d);return b} +function Vpc(a,b,c,d){var e,f,g,h,i;i=a.b;f=b.d;g=f.j;h=$pc(g,i.d[g.g],c);e=$id(ajd(f.n),f.a);switch(f.j.g){case 1:case 3:h.a+=e.a;break;case 2:case 4:h.b+=e.b;}Pub(d,h,d.c.b,d.c)} +function YNc(a,b,c){var d,e,f,g;g=Wmb(a.e,b,0);f=new ZNc;f.b=c;d=new Jkb(a.e,g);while(d.b1;b>>=1){(b&1)!=0&&(d=Wib(d,c));c.d==1?(c=Wib(c,c)):(c=new djb(Tjb(c.a,c.d,$C(kE,Pwe,28,c.d<<1,15,1))))}d=Wib(d,c);return d} +function Hwb(){Hwb=geb;var a,b,c,d;Ewb=$C(iE,vxe,28,25,15,1);Fwb=$C(iE,vxe,28,33,15,1);d=1.52587890625E-5;for(b=32;b>=0;b--){Fwb[b]=d;d*=0.5}c=1;for(a=24;a>=0;a--){Ewb[a]=c;c*=0.5}} +function a5b(a){var b,c;if(Heb(TD(Gxd(a,(yCc(),NAc))))){for(c=new is(Mr(zGd(a).a.Kc(),new ir));gs(c);){b=RD(hs(c),74);if(ozd(b)){if(Heb(TD(Gxd(b,OAc)))){return true}}}}return false} +function Qmc(a,b){var c,d,e;if(Ysb(a.f,b)){b.b=a;d=b.c;Wmb(a.j,d,0)!=-1||Rmb(a.j,d);e=b.d;Wmb(a.j,e,0)!=-1||Rmb(a.j,e);c=b.a.b;if(c.c.length!=0){!a.i&&(a.i=new _mc(a));Wmc(a.i,c)}}} +function Xpc(a){var b,c,d,e,f;c=a.c.d;d=c.j;e=a.d.d;f=e.j;if(d==f){return c.p=0&&lhb(a.substr(b,'GMT'.length),'GMT')){c[0]=b+3;return JA(a,c,d)}if(b>=0&&lhb(a.substr(b,'UTC'.length),'UTC')){c[0]=b+3;return JA(a,c,d)}return JA(a,c,d)} +function Zmc(a,b){var c,d,e,f,g;f=a.g.a;g=a.g.b;for(d=new Anb(a.d);d.ac;f--){a[f]|=b[f-c-1]>>>g;a[f-1]=b[f-c-1]<0&&hib(a.g,b,a.g,b+d,h);g=c.Kc();a.i+=d;for(e=0;e>4&15;f=a[d]&15;g[e++]=oAd[c];g[e++]=oAd[f]}return Ihb(g,0,g.length)}} +function Fhb(a){var b,c;if(a>=txe){b=uxe+(a-txe>>10&1023)&Bwe;c=56320+(a-txe&1023)&Bwe;return String.fromCharCode(b)+(''+String.fromCharCode(c))}else{return String.fromCharCode(a&Bwe)}} +function UMb(a,b){RMb();var c,d,e,f;e=RD(RD(Qc(a.r,b),21),87);if(e.gc()>=2){d=RD(e.Kc().Pb(),117);c=a.u.Hc((Pod(),Kod));f=a.u.Hc(Ood);return !d.a&&!c&&(e.gc()==2||f)}else{return false}} +function v3c(a,b,c,d,e){var f,g,h;f=w3c(a,b,c,d,e);h=false;while(!f){n3c(a,e,true);h=true;f=w3c(a,b,c,d,e)}h&&n3c(a,e,false);g=N2c(e);if(g.c.length!=0){!!a.d&&a.d.Gg(g);v3c(a,e,c,d,g)}} +function ind(){ind=geb;gnd=new jnd(LAe,0);end=new jnd('DIRECTED',1);hnd=new jnd('UNDIRECTED',2);cnd=new jnd('ASSOCIATION',3);fnd=new jnd('GENERALIZATION',4);dnd=new jnd('DEPENDENCY',5)} +function nsd(a,b){var c;if(!MCd(a)){throw Adb(new dgb(sHe))}c=MCd(a);switch(b.g){case 1:return -(a.j+a.f);case 2:return a.i-c.g;case 3:return a.j-c.f;case 4:return -(a.i+a.g);}return 0} +function Jge(a,b,c){var d,e,f;d=b.Lk();f=b.md();e=d.Jk()?fge(a,4,d,f,null,kge(a,d,f,ZD(d,102)&&(RD(d,19).Bb&txe)!=0),true):fge(a,d.tk()?2:1,d,f,d.ik(),-1,true);c?c.nj(e):(c=e);return c} +function lwb(a,b){var c,d;uFb(b);d=a.b.c.length;Rmb(a.b,b);while(d>0){c=d;d=(d-1)/2|0;if(a.a.Ne(Vmb(a.b,d),b)<=0){$mb(a.b,c,b);return true}$mb(a.b,c,Vmb(a.b,d))}$mb(a.b,d,b);return true} +function sKb(a,b,c,d){var e,f;e=0;if(!c){for(f=0;f=h} +function A8c(a){switch(a.g){case 0:return new o8c;case 1:return new u8c;default:throw Adb(new agb('No implementation is available for the width approximator '+(a.f!=null?a.f:''+a.g)));}} +function rDd(a,b,c,d){var e;e=false;if(bE(d)){e=true;sDd(b,c,WD(d))}if(!e){if($D(d)){e=true;rDd(a,b,c,d)}}if(!e){if(ZD(d,242)){e=true;qDd(b,c,RD(d,242))}}if(!e){throw Adb(new Aeb(tIe))}} +function uee(a,b){var c,d,e;c=b.qi(a.a);if(c){e=$Nd((!c.b&&(c.b=new SVd((JTd(),FTd),C8,c)),c.b),rKe);if(e!=null){for(d=1;d<(lke(),hke).length;++d){if(lhb(hke[d],e)){return d}}}}return 0} +function vee(a,b){var c,d,e;c=b.qi(a.a);if(c){e=$Nd((!c.b&&(c.b=new SVd((JTd(),FTd),C8,c)),c.b),rKe);if(e!=null){for(d=1;d<(lke(),ike).length;++d){if(lhb(ike[d],e)){return d}}}}return 0} +function Ve(a,b){var c,d,e,f;uFb(b);f=a.a.gc();if(f0?1:0;while(f.a[e]!=c){f=f.a[e];e=a.a.Ne(c.d,f.d)>0?1:0}f.a[e]=d;d.b=c.b;d.a[0]=c.a[0];d.a[1]=c.a[1];c.a[0]=null;c.a[1]=null} +function zIb(a){var b,c,d,e;b=new bnb;c=$C(xdb,Hye,28,a.a.c.length,16,1);Snb(c,c.length);for(e=new Anb(a.a);e.a0&&O9b((tFb(0,c.c.length),RD(c.c[0],30)),a);c.c.length>1&&O9b(RD(Vmb(c,c.c.length-1),30),a);b.Vg()} +function Sod(a){Pod();var b,c;b=ysb(Lod,cD(WC(D3,1),jwe,279,0,[Nod]));if(dy(Tx(b,a))>1){return false}c=ysb(Kod,cD(WC(D3,1),jwe,279,0,[Jod,Ood]));if(dy(Tx(c,a))>1){return false}return true} +function FBd(a,b){var c;c=Xjb((YSd(),XSd),a);ZD(c,507)?$jb(XSd,a,new B5d(this,b)):$jb(XSd,a,this);BBd(this,b);if(b==(jTd(),iTd)){this.wb=RD(this,2038);RD(b,2040)}else{this.wb=(lTd(),kTd)}} +function Lae(b){var c,d,e;if(b==null){return null}c=null;for(d=0;d=Awe?'error':d>=900?'warn':d>=800?'info':'log');eFb(c,a.a);!!a.b&&fFb(b,c,a.b,'Exception: ',true)} +function mQb(a,b){var c,d;d=(!a.q&&(a.q=new Tsb),Wjb(a.q,b));if(d!=null){return d}c=b.Sg();ZD(c,4)&&(c==null?(!a.q&&(a.q=new Tsb),_jb(a.q,b)):(!a.q&&(a.q=new Tsb),Zjb(a.q,b,c)),a);return c} +function sXb(){sXb=geb;nXb=new tXb('P1_CYCLE_BREAKING',0);oXb=new tXb('P2_LAYERING',1);pXb=new tXb('P3_NODE_ORDERING',2);qXb=new tXb('P4_NODE_PLACEMENT',3);rXb=new tXb('P5_EDGE_ROUTING',4)} +function KZb(a,b){CZb();var c;if(a.c==b.c){if(a.b==b.b||rZb(a.b,b.b)){c=oZb(a.b)?1:-1;if(a.a&&!b.a){return c}else if(!a.a&&b.a){return -c}}return hgb(a.b.g,b.b.g)}else{return Qfb(a.c,b.c)}} +function E3c(a,b){var c,d,e;if(p3c(a,b)){return true}for(d=new Anb(b);d.a=e||b<0)throw Adb(new veb(MIe+b+NIe+e));if(c>=e||c<0)throw Adb(new veb(OIe+c+NIe+e));b!=c?(d=(f=a.Cj(c),a.qj(b,f),f)):(d=a.xj(c));return d} +function Lje(a){var b,c,d;d=a;if(a){b=0;for(c=a.Eh();c;c=c.Eh()){if(++b>wxe){return Lje(c)}d=c;if(c==a){throw Adb(new dgb('There is a cycle in the containment hierarchy of '+a))}}}return d} +function Fe(a){var b,c,d;d=new Jyb(pve,'[',']');for(c=a.Kc();c.Ob();){b=c.Pb();Gyb(d,dE(b)===dE(a)?'(this Collection)':b==null?vve:jeb(b))}return !d.a?d.c:d.e.length==0?d.a.a:d.a.a+(''+d.e)} +function p3c(a,b){var c,d;d=false;if(b.gc()<2){return false}for(c=0;c1&&(a.j.b+=a.e)}else{a.j.a+=c.a;a.j.b=$wnd.Math.max(a.j.b,c.b);a.d.c.length>1&&(a.j.a+=a.e)}} +function Mnc(){Mnc=geb;Jnc=cD(WC(E3,1),NAe,64,0,[(qpd(),Yod),Xod,npd]);Inc=cD(WC(E3,1),NAe,64,0,[Xod,npd,ppd]);Knc=cD(WC(E3,1),NAe,64,0,[npd,ppd,Yod]);Lnc=cD(WC(E3,1),NAe,64,0,[ppd,Yod,Xod])} +function Upc(a,b,c,d){var e,f,g,h,i,j,k;g=a.c.d;h=a.d.d;if(g.j==h.j){return}k=a.b;e=g.j;i=null;while(e!=h.j){i=b==0?tpd(e):rpd(e);f=$pc(e,k.d[e.g],c);j=$pc(i,k.d[i.g],c);Mub(d,$id(f,j));e=i}} +function OJc(a,b,c,d){var e,f,g,h,i;g=hMc(a.a,b,c);h=RD(g.a,17).a;f=RD(g.b,17).a;if(d){i=RD(mQb(b,(Ywc(),Iwc)),10);e=RD(mQb(c,Iwc),10);if(!!i&&!!e){Slc(a.b,i,e);h+=a.b.i;f+=a.b.e}}return h>f} +function OLc(a){var b,c,d,e,f,g,h,i,j;this.a=LLc(a);this.b=new bnb;for(c=a,d=0,e=c.length;damc(a.d).c){a.i+=a.g.c;cmc(a.d)}else if(amc(a.d).c>amc(a.g).c){a.e+=a.d.c;cmc(a.g)}else{a.i+=_lc(a.g);a.e+=_lc(a.d);cmc(a.g);cmc(a.d)}}} +function vTc(a,b,c){var d,e,f,g;f=b.q;g=b.r;new bTc((fTc(),dTc),b,f,1);new bTc(dTc,f,g,1);for(e=new Anb(c);e.ah&&(i=h/d);e>f&&(j=f/e);g=$wnd.Math.min(i,j);a.a+=g*(b.a-a.a);a.b+=g*(b.b-a.b)} +function I8c(a,b,c,d,e){var f,g;g=false;f=RD(Vmb(c.b,0),27);while(V8c(a,b,f,d,e)){g=true;T9c(c,f);if(c.b.c.length==0){break}f=RD(Vmb(c.b,0),27)}c.b.c.length==0&&Fad(c.j,c);g&&gad(b.q);return g} +function Eid(a,b){tid();var c,d,e,f;if(b.b<2){return false}f=Sub(b,0);c=RD(evb(f),8);d=c;while(f.b!=f.d.c){e=RD(evb(f),8);if(Did(a,d,e)){return true}d=e}if(Did(a,d,c)){return true}return false} +function Bxd(a,b,c,d){var e,f;if(c==0){return !a.o&&(a.o=new DVd((pvd(),mvd),X4,a,0)),BVd(a.o,b,d)}return f=RD(vYd((e=RD(Ywd(a,16),29),!e?a.ii():e),c),69),f.wk().Ak(a,Wwd(a),c-AYd(a.ii()),b,d)} +function BBd(a,b){var c;if(b!=a.sb){c=null;!!a.sb&&(c=RD(a.sb,54).Th(a,1,n7,c));!!b&&(c=RD(b,54).Rh(a,1,n7,c));c=hBd(a,b,c);!!c&&c.oj()}else (a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,4,b,b))} +function YDd(a,b){var c,d,e,f;if(b){e=vDd(b,'x');c=new ZEd(a);Hzd(c.a,(uFb(e),e));f=vDd(b,'y');d=new $Ed(a);Izd(d.a,(uFb(f),f))}else{throw Adb(new CDd('All edge sections need an end point.'))}} +function WDd(a,b){var c,d,e,f;if(b){e=vDd(b,'x');c=new WEd(a);Ozd(c.a,(uFb(e),e));f=vDd(b,'y');d=new XEd(a);Pzd(d.a,(uFb(f),f))}else{throw Adb(new CDd('All edge sections need a start point.'))}} +function hBb(a,b){var c,d,e,f,g,h,i;for(d=kBb(a),f=0,h=d.length;f>22-b;e=a.h<>22-b}else if(b<44){c=0;d=a.l<>44-b}else{c=0;d=0;e=a.l<a){throw Adb(new agb('k must be smaller than n'))}else return b==0||b==a?1:a==0?0:Bid(a)/(Bid(b)*Bid(a-b))} +function msd(a,b){var c,d,e,f;c=new zId(a);while(c.g==null&&!c.c?sId(c):c.g==null||c.i!=0&&RD(c.g[c.i-1],51).Ob()){f=RD(tId(c),58);if(ZD(f,167)){d=RD(f,167);for(e=0;e>4];b[c*2+1]=Fqe[f&15]}return Ihb(b,0,b.length)} +function sn(a){fn();var b,c,d;d=a.c.length;switch(d){case 0:return en;case 1:b=RD(Ir(new Anb(a)),44);return xn(b.ld(),b.md());default:c=RD(anb(a,$C(UK,Zve,44,a.c.length,0,1)),173);return new Mx(c);}} +function KWb(a){var b,c,d,e,f,g;b=new wmb;c=new wmb;hmb(b,a);hmb(c,a);while(c.b!=c.c){e=RD(smb(c),36);for(g=new Anb(e.a);g.a0&&uLc(a,c,b);return e}return rLc(a,b,c)} +function $4c(){$4c=geb;R4c=(umd(),Qld);Y4c=fmd;K4c=kld;L4c=nld;M4c=pld;J4c=ild;N4c=sld;Q4c=Lld;H4c=(D4c(),o4c);I4c=p4c;T4c=v4c;W4c=y4c;U4c=w4c;V4c=x4c;O4c=r4c;P4c=t4c;S4c=u4c;X4c=z4c;Z4c=B4c;G4c=n4c} +function P9c(a,b){var c,d,e,f,g;if(a.e<=b){return a.g}if(R9c(a,a.g,b)){return a.g}f=a.r;d=a.g;g=a.r;e=(f-d)/2+d;while(d+11&&(a.e.b+=a.a)}else{a.e.a+=c.a;a.e.b=$wnd.Math.max(a.e.b,c.b);a.d.c.length>1&&(a.e.a+=a.a)}} +function Ipc(a){var b,c,d,e;e=a.i;b=e.b;d=e.j;c=e.g;switch(e.a.g){case 0:c.a=(a.g.b.o.a-d.a)/2;break;case 1:c.a=b.d.n.a+b.d.a.a;break;case 2:c.a=b.d.n.a+b.d.a.a-d.a;break;case 3:c.b=b.d.n.b+b.d.a.b;}} +function oOc(a,b,c){var d,e,f;for(e=new is(Mr(W2b(c).a.Kc(),new ir));gs(e);){d=RD(hs(e),18);if(!(!W0b(d)&&!(!W0b(d)&&d.c.i.c==d.d.i.c))){continue}f=gOc(a,d,c,new VOc);f.c.length>1&&(ZEb(b.c,f),true)}} +function _id(a,b,c,d,e){if(dd&&(a.a=d);a.be&&(a.b=e);return a} +function LFd(a){if(ZD(a,143)){return EFd(RD(a,143))}else if(ZD(a,233)){return FFd(RD(a,233))}else if(ZD(a,23)){return GFd(RD(a,23))}else{throw Adb(new agb(wIe+Fe(new mob(cD(WC(jJ,1),rve,1,5,[a])))))}} +function ujb(a,b,c,d,e){var f,g,h;f=true;for(g=0;g>>e|c[g+d+1]<>>e;++g}return f} +function ZQc(a,b,c,d){var e,f,g;if(b.k==(r3b(),o3b)){for(f=new is(Mr(Z2b(b).a.Kc(),new ir));gs(f);){e=RD(hs(f),18);g=e.c.i.k;if(g==o3b&&a.c.a[e.c.i.c.p]==d&&a.c.a[b.c.p]==c){return true}}}return false} +function CD(a,b){var c,d,e,f;b&=63;c=a.h&exe;if(b<22){f=c>>>b;e=a.m>>b|c<<22-b;d=a.l>>b|a.m<<22-b}else if(b<44){f=0;e=c>>>b-22;d=a.m>>b-22|a.h<<44-b}else{f=0;e=0;d=c>>>b-44}return hD(d&dxe,e&dxe,f&exe)} +function mmc(a,b,c,d){var e;this.b=d;this.e=a==(RKc(),PKc);e=b[c];this.d=YC(xdb,[Nve,Hye],[183,28],16,[e.length,e.length],2);this.a=YC(kE,[Nve,Pwe],[53,28],15,[e.length,e.length],2);this.c=new Ylc(b,c)} +function Rmc(a){var b,c,d;a.k=new Si((qpd(),cD(WC(E3,1),NAe,64,0,[opd,Yod,Xod,npd,ppd])).length,a.j.c.length);for(d=new Anb(a.j);d.a=c){_cc(a,b,d.p);return true}}return false} +function EA(a,b,c,d){var e,f,g,h,i,j;g=c.length;f=0;e=-1;j=Bhb((BFb(b,a.length+1),a.substr(b)),(wvb(),uvb));for(h=0;hf&&whb(j,Bhb(c[h],uvb))){e=h;f=i}}e>=0&&(d[0]=b+f);return e} +function gCd(a){var b;if((a.Db&64)!=0)return Fyd(a);b=new dib(FHe);!a.a||Zhb(Zhb((b.a+=' "',b),a.a),'"');Zhb(Uhb(Zhb(Uhb(Zhb(Uhb(Zhb(Uhb((b.a+=' (',b),a.i),','),a.j),' | '),a.g),','),a.f),')');return b.a} +function xge(a,b,c){var d,e,f,g,h;h=pke(a.e.Dh(),b);e=RD(a.g,124);d=0;for(g=0;gc){return Jb(a,c,'start index')}if(b<0||b>c){return Jb(b,c,'end index')}return hc('end index (%s) must not be less than start index (%s)',cD(WC(jJ,1),rve,1,5,[sgb(b),sgb(a)]))} +function dA(b,c){var d,e,f,g;for(e=0,f=b.length;e0&&aGc(a,f,c))}}b.p=0} +function Ahd(a){var b;this.c=new Yub;this.f=a.e;this.e=a.d;this.i=a.g;this.d=a.c;this.b=a.b;this.k=a.j;this.a=a.a;!a.i?(this.j=(b=RD(mfb(d3),9),new Fsb(b,RD(WEb(b,b.length),9),0))):(this.j=a.i);this.g=a.f} +function Wb(a){var b,c,d,e;b=Thb(Zhb(new dib('Predicates.'),'and'),40);c=true;for(e=new Dkb(a);e.b0?h[g-1]:$C(jR,WAe,10,0,0,1);e=h[g];j=g=0?a.ki(e):Tvd(a,d)}else{throw Adb(new agb(KHe+d.xe()+LHe))}}else{Cvd(a,c,d)}} +function ADd(a){var b,c;c=null;b=false;if(ZD(a,211)){b=true;c=RD(a,211).a}if(!b){if(ZD(a,263)){b=true;c=''+RD(a,263).a}}if(!b){if(ZD(a,493)){b=true;c=''+RD(a,493).a}}if(!b){throw Adb(new Aeb(tIe))}return c} +function gge(a,b,c){var d,e,f,g,h,i;i=pke(a.e.Dh(),b);d=0;h=a.i;e=RD(a.g,124);for(g=0;g=a.d.b.c.length){b=new R4b(a.d);b.p=d.p-1;Rmb(a.d.b,b);c=new R4b(a.d);c.p=d.p;Rmb(a.d.b,c)}g3b(d,RD(Vmb(a.d.b,d.p),30))}} +function DVc(a,b,c){var d,e,f;if(!a.b[b.g]){a.b[b.g]=true;d=c;!d&&(d=new YWc);Mub(d.b,b);for(f=a.a[b.g].Kc();f.Ob();){e=RD(f.Pb(),65);e.b!=b&&DVc(a,e.b,d);e.c!=b&&DVc(a,e.c,d);Mub(d.a,e)}return d}return null} +function iMb(a){switch(a.g){case 0:case 1:case 2:return qpd(),Yod;case 3:case 4:case 5:return qpd(),npd;case 6:case 7:case 8:return qpd(),ppd;case 9:case 10:case 11:return qpd(),Xod;default:return qpd(),opd;}} +function SOc(a,b){var c;if(a.c.length==0){return false}c=zDc((tFb(0,a.c.length),RD(a.c[0],18)).c.i);dOc();if(c==(wDc(),tDc)||c==sDc){return true}return yDb(GDb(new SDb(null,new Swb(a,16)),new $Oc),new aPc(b))} +function KDd(a,b){if(ZD(b,207)){return EDd(a,RD(b,27))}else if(ZD(b,193)){return FDd(a,RD(b,123))}else if(ZD(b,452)){return DDd(a,RD(b,166))}else{throw Adb(new agb(wIe+Fe(new mob(cD(WC(jJ,1),rve,1,5,[b])))))}} +function Ou(a,b,c){var d,e;this.f=a;d=RD(Wjb(a.b,b),260);e=!d?0:d.a;Sb(c,e);if(c>=(e/2|0)){this.e=!d?null:d.c;this.d=e;while(c++0){Lu(this)}}this.b=b;this.a=null} +function iHb(a,b){var c,d;b.a?jHb(a,b):(c=RD(vAb(a.b,b.b),60),!!c&&c==a.a[b.b.f]&&!!c.a&&c.a!=b.b.a&&c.c.Fc(b.b),d=RD(uAb(a.b,b.b),60),!!d&&a.a[d.f]==b.b&&!!d.a&&d.a!=b.b.a&&b.b.c.Fc(d),wAb(a.b,b.b),undefined)} +function wMb(a,b){var c,d;c=RD(Vrb(a.b,b),127);if(RD(RD(Qc(a.r,b),21),87).dc()){c.n.b=0;c.n.c=0;return}c.n.b=a.C.b;c.n.c=a.C.c;a.A.Hc((Qpd(),Ppd))&&BMb(a,b);d=AMb(a,b);BLb(a,b)==(pod(),mod)&&(d+=2*a.w);c.a.a=d} +function FNb(a,b){var c,d;c=RD(Vrb(a.b,b),127);if(RD(RD(Qc(a.r,b),21),87).dc()){c.n.d=0;c.n.a=0;return}c.n.d=a.C.d;c.n.a=a.C.a;a.A.Hc((Qpd(),Ppd))&&JNb(a,b);d=INb(a,b);BLb(a,b)==(pod(),mod)&&(d+=2*a.w);c.a.b=d} +function VQb(a,b){var c,d,e,f;f=new bnb;for(d=new Anb(b);d.ad&&(BFb(b-1,a.length),a.charCodeAt(b-1)<=32)){--b}return d>0||bc.a&&(d.Hc((ukd(),okd))?(e=(b.a-c.a)/2):d.Hc(qkd)&&(e=b.a-c.a));b.b>c.b&&(d.Hc((ukd(),skd))?(f=(b.b-c.b)/2):d.Hc(rkd)&&(f=b.b-c.b));Isd(a,e,f)} +function ABd(a,b,c,d,e,f,g,h,i,j,k,l,m){ZD(a.Cb,90)&&v$d(yYd(RD(a.Cb,90)),4);PAd(a,c);a.f=g;DWd(a,h);FWd(a,i);xWd(a,j);EWd(a,k);aWd(a,l);AWd(a,m);_Vd(a,true);$Vd(a,e);a.Zk(f);YVd(a,b);d!=null&&(a.i=null,zWd(a,d))} +function Jb(a,b,c){if(a<0){return hc(qve,cD(WC(jJ,1),rve,1,5,[c,sgb(a)]))}else if(b<0){throw Adb(new agb(sve+b))}else{return hc('%s (%s) must not be greater than size (%s)',cD(WC(jJ,1),rve,1,5,[c,sgb(a),sgb(b)]))}} +function Xnb(a,b,c,d,e,f){var g,h,i,j;g=d-c;if(g<7){Unb(b,c,d,f);return}i=c+e;h=d+e;j=i+(h-i>>1);Xnb(b,a,i,j,-e,f);Xnb(b,a,j,h,-e,f);if(f.Ne(a[j-1],a[j])<=0){while(c=0?a.bi(f,c):Svd(a,e,c)}else{throw Adb(new agb(KHe+e.xe()+LHe))}}else{Bvd(a,d,e,c)}} +function n3d(a){var b,c;if(a.f){while(a.n>0){b=RD(a.k.Xb(a.n-1),76);c=b.Lk();if(ZD(c,102)&&(RD(c,19).Bb&QHe)!=0&&(!a.e||c.pk()!=C4||c.Lj()!=0)&&b.md()!=null){return true}else{--a.n}}return false}else{return a.n>0}} +function Pje(b){var c,d,e,f;d=RD(b,54)._h();if(d){try{e=null;c=N5d((YSd(),XSd),jSd(kSd(d)));if(c){f=c.ai();!!f&&(e=f.Fl(Chb(d.e)))}if(!!e&&e!=b){return Pje(e)}}catch(a){a=zdb(a);if(!ZD(a,63))throw Adb(a)}}return b} +function P3c(a,b,c){var d,e,f;c.Ug('Remove overlaps',1);c.dh(b,eFe);d=RD(Gxd(b,(u2c(),t2c)),27);a.f=d;a.a=u5c(RD(Gxd(b,($4c(),X4c)),300));e=UD(Gxd(b,(umd(),fmd)));s3c(a,(uFb(e),e));f=Q2c(d);O3c(a,b,f,c);c.dh(b,gFe)} +function Ded(a){var b,c,d;if(Heb(TD(Gxd(a,(umd(),$kd))))){d=new bnb;for(c=new is(Mr(zGd(a).a.Kc(),new ir));gs(c);){b=RD(hs(c),74);ozd(b)&&Heb(TD(Gxd(b,_kd)))&&(ZEb(d.c,b),true)}return d}else{return yob(),yob(),vob}} +function KC(a){if(!a){return cC(),bC}var b=a.valueOf?a.valueOf():a;if(b!==a){var c=GC[typeof b];return c?c(b):NC(typeof b)}else if(a instanceof Array||a instanceof $wnd.Array){return new NB(a)}else{return new vC(a)}} +function IMb(a,b,c){var d,e,f;f=a.o;d=RD(Vrb(a.p,c),252);e=d.i;e.b=ZKb(d);e.a=YKb(d);e.b=$wnd.Math.max(e.b,f.a);e.b>f.a&&!b&&(e.b=f.a);e.c=-(e.b-f.a)/2;switch(c.g){case 1:e.d=-e.a;break;case 3:e.d=f.b;}$Kb(d);_Kb(d)} +function JMb(a,b,c){var d,e,f;f=a.o;d=RD(Vrb(a.p,c),252);e=d.i;e.b=ZKb(d);e.a=YKb(d);e.a=$wnd.Math.max(e.a,f.b);e.a>f.b&&!b&&(e.a=f.b);e.d=-(e.a-f.b)/2;switch(c.g){case 4:e.c=-e.b;break;case 2:e.c=f.a;}$Kb(d);_Kb(d)} +function nkc(a,b){var c,d,e,f,g;if(b.dc()){return}e=RD(b.Xb(0),131);if(b.gc()==1){mkc(a,e,e,1,0,b);return}c=1;while(c0){try{f=Oeb(c,qwe,lve)}catch(a){a=zdb(a);if(ZD(a,130)){e=a;throw Adb(new RSd(e))}else throw Adb(a)}}d=(!b.a&&(b.a=new Zde(b)),b.a);return f=0?RD(QHd(d,f),58):null} +function Ib(a,b){if(a<0){return hc(qve,cD(WC(jJ,1),rve,1,5,['index',sgb(a)]))}else if(b<0){throw Adb(new agb(sve+b))}else{return hc('%s (%s) must be less than size (%s)',cD(WC(jJ,1),rve,1,5,['index',sgb(a),sgb(b)]))}} +function cob(a){var b,c,d,e,f;if(a==null){return vve}f=new Jyb(pve,'[',']');for(c=a,d=0,e=c.length;d=0?a.Lh(c,true,true):Qvd(a,e,true),160));RD(d,220).Zl(b)}else{throw Adb(new agb(KHe+b.xe()+LHe))}} +function Cib(a){var b,c;if(a>-140737488355328&&a<140737488355328){if(a==0){return 0}b=a<0;b&&(a=-a);c=eE($wnd.Math.floor($wnd.Math.log(a)/0.6931471805599453));(!b||a!=$wnd.Math.pow(2,c))&&++c;return c}return Dib(Hdb(a))} +function oTc(a){var b,c,d,e,f,g,h;f=new Iub;for(c=new Anb(a);c.a2&&h.e.b+h.j.b<=2){e=h;d=g}f.a.zc(e,f);e.q=d}return f} +function B5c(a,b,c){c.Ug('Eades radial',1);c.dh(b,gFe);a.d=RD(Gxd(b,(u2c(),t2c)),27);a.c=Kfb(UD(Gxd(b,($4c(),S4c))));a.e=u5c(RD(Gxd(b,X4c),300));a.a=Z3c(RD(Gxd(b,Z4c),434));a.b=k5c(RD(Gxd(b,O4c),354));C5c(a);c.dh(b,gFe)} +function t8c(a,b){b.Ug('Target Width Setter',1);if(Hxd(a,(X7c(),W7c))){Ixd(a,(X6c(),W6c),UD(Gxd(a,W7c)))}else{throw Adb(new Jed('A target width has to be set if the TargetWidthWidthApproximator should be used.'))}b.Vg()} +function _8b(a,b){var c,d,e;d=new j3b(a);kQb(d,b);pQb(d,(Ywc(),gwc),b);pQb(d,(yCc(),BBc),(Bod(),wod));pQb(d,Rzc,(Rjd(),Njd));h3b(d,(r3b(),m3b));c=new R3b;P3b(c,d);Q3b(c,(qpd(),ppd));e=new R3b;P3b(e,d);Q3b(e,Xod);return d} +function ttc(a){switch(a.g){case 0:return new FKc((RKc(),OKc));case 1:return new aKc;case 2:return new FLc;default:throw Adb(new agb('No implementation is available for the crossing minimizer '+(a.f!=null?a.f:''+a.g)));}} +function THc(a,b){var c,d,e,f,g;a.c[b.p]=true;Rmb(a.a,b);for(g=new Anb(b.j);g.a=f){g.$b()}else{e=g.Kc();for(d=0;d0?Hh():g<0&&Rw(a,b,-g);return true}else{return false}} +function YKb(a){var b,c,d,e,f,g,h;h=0;if(a.b==0){g=aLb(a,true);b=0;for(d=g,e=0,f=d.length;e0){h+=c;++b}}b>1&&(h+=a.c*(b-1))}else{h=Vvb(SCb(HDb(CDb(_nb(a.a),new oLb),new qLb)))}return h>0?h+a.n.d+a.n.a:0} +function ZKb(a){var b,c,d,e,f,g,h;h=0;if(a.b==0){h=Vvb(SCb(HDb(CDb(_nb(a.a),new kLb),new mLb)))}else{g=bLb(a,true);b=0;for(d=g,e=0,f=d.length;e0){h+=c;++b}}b>1&&(h+=a.c*(b-1))}return h>0?h+a.n.b+a.n.c:0} +function UOc(a){var b,c;if(a.c.length!=2){throw Adb(new dgb('Order only allowed for two paths.'))}b=(tFb(0,a.c.length),RD(a.c[0],18));c=(tFb(1,a.c.length),RD(a.c[1],18));if(b.d.i!=c.c.i){a.c.length=0;ZEb(a.c,c);ZEb(a.c,b)}} +function O8c(a,b,c){var d;zyd(c,b.g,b.f);Byd(c,b.i,b.j);for(d=0;d<(!b.a&&(b.a=new C5d(J4,b,10,11)),b.a).i;d++){O8c(a,RD(QHd((!b.a&&(b.a=new C5d(J4,b,10,11)),b.a),d),27),RD(QHd((!c.a&&(c.a=new C5d(J4,c,10,11)),c.a),d),27))}} +function DMb(a,b){var c,d,e,f;f=RD(Vrb(a.b,b),127);c=f.a;for(e=RD(RD(Qc(a.r,b),21),87).Kc();e.Ob();){d=RD(e.Pb(),117);!!d.c&&(c.a=$wnd.Math.max(c.a,QKb(d.c)))}if(c.a>0){switch(b.g){case 2:f.n.c=a.s;break;case 4:f.n.b=a.s;}}} +function ETb(a,b){var c,d,e;c=RD(mQb(b,(yVb(),lVb)),17).a-RD(mQb(a,lVb),17).a;if(c==0){d=ojd(ajd(RD(mQb(a,(JVb(),FVb)),8)),RD(mQb(a,GVb),8));e=ojd(ajd(RD(mQb(b,FVb),8)),RD(mQb(b,GVb),8));return Qfb(d.a*d.b,e.a*e.b)}return c} +function JVc(a,b){var c,d,e;c=RD(mQb(b,(h_c(),X$c)),17).a-RD(mQb(a,X$c),17).a;if(c==0){d=ojd(ajd(RD(mQb(a,(q$c(),RZc)),8)),RD(mQb(a,SZc),8));e=ojd(ajd(RD(mQb(b,RZc),8)),RD(mQb(b,SZc),8));return Qfb(d.a*d.b,e.a*e.b)}return c} +function _0b(a){var b,c;c=new bib;c.a+='e_';b=S0b(a);b!=null&&(c.a+=''+b,c);if(!!a.c&&!!a.d){Zhb((c.a+=' ',c),M3b(a.c));Zhb(Yhb((c.a+='[',c),a.c.i),']');Zhb((c.a+=SAe,c),M3b(a.d));Zhb(Yhb((c.a+='[',c),a.d.i),']')}return c.a} +function ZVc(a){switch(a.g){case 0:return new N_c;case 1:return new V_c;case 2:return new x0c;case 3:return new J0c;default:throw Adb(new agb('No implementation is available for the layout phase '+(a.f!=null?a.f:''+a.g)));}} +function qsd(a,b,c,d,e){var f;f=0;switch(e.g){case 1:f=$wnd.Math.max(0,b.b+a.b-(c.b+d));break;case 3:f=$wnd.Math.max(0,-a.b-d);break;case 2:f=$wnd.Math.max(0,-a.a-d);break;case 4:f=$wnd.Math.max(0,b.a+a.a-(c.a+d));}return f} +function MDd(a,b,c){var d,e,f,g,h;if(c){e=c.a.length;d=new vue(e);for(h=(d.b-d.a)*d.c<0?(uue(),tue):new Rue(d);h.Ob();){g=RD(h.Pb(),17);f=xDd(c,g.a);kIe in f.a||lIe in f.a?yEd(a,f,b):EEd(a,f,b);OGd(RD(Wjb(a.b,uDd(f)),74))}}} +function jXd(a){var b,c;switch(a.b){case -1:{return true}case 0:{c=a.t;if(c>1||c==-1){a.b=-1;return true}else{b=WVd(a);if(!!b&&(nke(),b.lk()==aKe)){a.b=-1;return true}else{a.b=1;return false}}}default:case 1:{return false}}} +function Sqe(a,b){var c,d,e,f;Mqe(a);if(a.c!=0||a.a!=123)throw Adb(new Lqe(TId((Hde(),eJe))));f=b==112;d=a.d;c=phb(a.i,125,d);if(c<0)throw Adb(new Lqe(TId((Hde(),fJe))));e=zhb(a.i,d,c);a.d=c+1;return ite(e,f,(a.e&512)==512)} +function YTb(a){var b,c,d,e,f,g,h;d=a.a.c.length;if(d>0){g=a.c.d;h=a.d.d;e=ijd(ojd(new rjd(h.a,h.b),g),1/(d+1));f=new rjd(g.a,g.b);for(c=new Anb(a.a);c.a=0&&f=0?a.Lh(c,true,true):Qvd(a,e,true),160));return RD(d,220).Wl(b)}else{throw Adb(new agb(KHe+b.xe()+NHe))}} +function _ae(){Tae();var a;if(Sae)return RD(N5d((YSd(),XSd),AKe),2038);RRd(UK,new hde);abe();a=RD(ZD(Xjb((YSd(),XSd),AKe),560)?Xjb(XSd,AKe):new $ae,560);Sae=true;Yae(a);Zae(a);Zjb((hTd(),gTd),a,new cbe);$jb(XSd,AKe,a);return a} +function Vfe(a,b){var c,d,e,f;a.j=-1;if(Mvd(a.e)){c=a.i;f=a.i!=0;LHd(a,b);d=new P3d(a.e,3,a.c,null,b,c,f);e=b.zl(a.e,a.c,null);e=Hge(a,b,e);if(!e){qvd(a.e,d)}else{e.nj(d);e.oj()}}else{LHd(a,b);e=b.zl(a.e,a.c,null);!!e&&e.oj()}} +function HA(a,b){var c,d,e;e=0;d=b[0];if(d>=a.length){return -1}c=(BFb(d,a.length),a.charCodeAt(d));while(c>=48&&c<=57){e=e*10+(c-48);++d;if(d>=a.length){break}c=(BFb(d,a.length),a.charCodeAt(d))}d>b[0]?(b[0]=d):(e=-1);return e} +function mPb(a){var b,c,d,e,f;e=RD(a.a,17).a;f=RD(a.b,17).a;c=e;d=f;b=$wnd.Math.max($wnd.Math.abs(e),$wnd.Math.abs(f));if(e<=0&&e==f){c=0;d=f-1}else{if(e==-b&&f!=b){c=f;d=e;f>=0&&++c}else{c=-f;d=e}}return new Ptd(sgb(c),sgb(d))} +function YPb(a,b,c,d){var e,f,g,h,i,j;for(e=0;e=0&&j>=0&&i=a.i)throw Adb(new veb(MIe+b+NIe+a.i));if(c>=a.i)throw Adb(new veb(OIe+c+NIe+a.i));d=a.g[c];if(b!=c){b>16);b=d>>16&16;c=16-b;a=a>>b;d=a-256;b=d>>16&8;c+=b;a<<=b;d=a-qxe;b=d>>16&4;c+=b;a<<=b;d=a-Ove;b=d>>16&2;c+=b;a<<=b;d=a>>14;b=d&~(d>>1);return c+2-b}} +function RSb(a){HSb();var b,c,d,e;GSb=new bnb;FSb=new Tsb;ESb=new bnb;b=(!a.a&&(a.a=new C5d(J4,a,10,11)),a.a);JSb(b);for(e=new dMd(b);e.e!=e.i.gc();){d=RD(bMd(e),27);if(Wmb(GSb,d,0)==-1){c=new bnb;Rmb(ESb,c);KSb(d,c)}}return ESb} +function sTb(a,b,c){var d,e,f,g;a.a=c.b.d;if(ZD(b,326)){e=IGd(RD(b,74),false,false);f=ssd(e);d=new wTb(a);xgb(f,d);lsd(f,e);b.of((umd(),cld))!=null&&xgb(RD(b.of(cld),75),d)}else{g=RD(b,422);g.rh(g.nh()+a.a.a);g.sh(g.oh()+a.a.b)}} +function hWc(a,b){var c,d,e;e=new bnb;for(d=Sub(b.a,0);d.b!=d.d.c;){c=RD(evb(d),65);c.c.g==a.g&&dE(mQb(c.b,(h_c(),f_c)))!==dE(mQb(c.c,f_c))&&!yDb(new SDb(null,new Swb(e,16)),new IWc(c))&&(ZEb(e.c,c),true)}_mb(e,new KWc);return e} +function fUb(a,b,c){var d,e,f,g;if(ZD(b,153)&&ZD(c,153)){f=RD(b,153);g=RD(c,153);return a.a[f.a][g.a]+a.a[g.a][f.a]}else if(ZD(b,250)&&ZD(c,250)){d=RD(b,250);e=RD(c,250);if(d.a==e.a){return RD(mQb(e.a,(yVb(),lVb)),17).a}}return 0} +function q9b(a,b){var c,d,e,f,g,h,i,j;j=Kfb(UD(mQb(b,(yCc(),fCc))));i=a[0].n.a+a[0].o.a+a[0].d.c+j;for(h=1;h=0){return c}h=ejd(ojd(new rjd(g.c+g.b/2,g.d+g.a/2),new rjd(f.c+f.b/2,f.d+f.a/2)));return -(oRb(f,g)-1)*h} +function ysd(a,b,c){var d;FDb(new SDb(null,(!c.a&&(c.a=new C5d(F4,c,6,6)),new Swb(c.a,16))),new Qsd(a,b));FDb(new SDb(null,(!c.n&&(c.n=new C5d(I4,c,1,7)),new Swb(c.n,16))),new Ssd(a,b));d=RD(Gxd(c,(umd(),cld)),75);!!d&&Bjd(d,a,b)} +function Qvd(a,b,c){var d,e,f;f=Eee((lke(),jke),a.Dh(),b);if(f){nke();RD(f,69).xk()||(f=zfe(Qee(jke,f)));e=(d=a.Ih(f),RD(d>=0?a.Lh(d,true,true):Qvd(a,f,true),160));return RD(e,220).Sl(b,c)}else{throw Adb(new agb(KHe+b.xe()+NHe))}} +function WNd(a,b,c,d){var e,f,g,h,i;e=a.d[b];if(e){f=e.g;i=e.i;if(d!=null){for(h=0;h=c){d=b;j=(i.c+i.a)/2;g=j-c;if(i.c<=j-c){e=new BTc(i.c,g);Qmb(a,d++,e)}h=j+c;if(h<=i.a){f=new BTc(h,i.a);wFb(d,a.c.length);XEb(a.c,d,f)}}} +function mZc(a,b,c){var d,e,f,g,h,i;if(!b.dc()){e=new Yub;for(i=b.Kc();i.Ob();){h=RD(i.Pb(),40);Zjb(a.a,sgb(h.g),sgb(c));for(g=(d=Sub((new dXc(h)).a.d,0),new gXc(d));dvb(g.a);){f=RD(evb(g.a),65).c;Pub(e,f,e.c.b,e.c)}}mZc(a,e,c+1)}} +function Ude(a){var b;if(!a.c&&a.g==null){a.d=a.bj(a.f);WGd(a,a.d);b=a.d}else{if(a.g==null){return true}else if(a.i==0){return false}else{b=RD(a.g[a.i-1],51)}}if(b==a.b&&null.Vm>=null.Um()){tId(a);return Ude(a)}else{return b.Ob()}} +function t_b(a){this.a=a;if(a.c.i.k==(r3b(),m3b)){this.c=a.c;this.d=RD(mQb(a.c.i,(Ywc(),hwc)),64)}else if(a.d.i.k==m3b){this.c=a.d;this.d=RD(mQb(a.d.i,(Ywc(),hwc)),64)}else{throw Adb(new agb('Edge '+a+' is not an external edge.'))}} +function O1d(a,b){var c,d,e;e=a.b;a.b=b;(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,3,e,a.b));if(!b){PAd(a,null);Q1d(a,0);P1d(a,null)}else if(b!=a){PAd(a,b.zb);Q1d(a,b.d);c=(d=b.c,d==null?b.zb:d);P1d(a,c==null||lhb(c,b.zb)?null:c)}} +function hj(a,b){var c;this.e=(tm(),Qb(a),tm(),zm(a));this.c=(Qb(b),zm(b));Lb(this.e.Rd().dc()==this.c.Rd().dc());this.d=Uv(this.e);this.b=Uv(this.c);c=YC(jJ,[Nve,rve],[5,1],5,[this.e.Rd().gc(),this.c.Rd().gc()],2);this.a=c;Zi(this)} +function Lz(b){var c=(!Jz&&(Jz=Mz()),Jz);var d=b.replace(/[\x00-\x1f\xad\u0600-\u0603\u06dd\u070f\u17b4\u17b5\u200b-\u200f\u2028-\u202e\u2060-\u2064\u206a-\u206f\ufeff\ufff9-\ufffb"\\]/g,function(a){return Kz(a,c)});return '"'+d+'"'} +function VEb(a,b,c,d,e,f){var g,h,i,j,k;if(e==0){return}if(dE(a)===dE(c)){a=a.slice(b,b+e);b=0}i=c;for(h=b,j=b+e;h=g)throw Adb(new aMd(b,g));e=c[b];if(g==1){d=null}else{d=$C(d6,IJe,424,g-1,0,1);hib(c,0,d,0,b);f=g-b-1;f>0&&hib(c,b+1,d,b,f)}Bde(a,d);Ade(a,b,e);return e} +function l3d(a){var b,c;if(a.f){while(a.n0?(f=vpd(c)):(f=spd(vpd(c)))}Ixd(b,GBc,f)} +function agc(a,b){var c;b.Ug('Partition preprocessing',1);c=RD(zDb(CDb(EDb(CDb(new SDb(null,new Swb(a.a,16)),new egc),new ggc),new igc),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[(xBb(),vBb)]))),15);FDb(c.Oc(),new kgc);b.Vg()} +function Uoc(a,b){var c,d,e,f,g;g=a.j;b.a!=b.b&&_mb(g,new ypc);e=g.c.length/2|0;for(d=0;d0&&uLc(a,c,b);return f}else if(d.a!=null){uLc(a,b,c);return -1}else if(e.a!=null){uLc(a,c,b);return 1}return 0} +function EVc(a,b){var c,d,e,f,g;e=b.b.b;a.a=$C(QK,Ize,15,e,0,1);a.b=$C(xdb,Hye,28,e,16,1);for(g=Sub(b.b,0);g.b!=g.d.c;){f=RD(evb(g),40);a.a[f.g]=new Yub}for(d=Sub(b.a,0);d.b!=d.d.c;){c=RD(evb(d),65);a.a[c.b.g].Fc(c);a.a[c.c.g].Fc(c)}} +function SJd(a,b){var c,d,e,f;if(a.Pj()){c=a.Ej();f=a.Qj();++a.j;a.qj(c,a.Zi(c,b));d=a.Ij(3,null,b,c,f);if(a.Mj()){e=a.Nj(b,null);if(!e){a.Jj(d)}else{e.nj(d);e.oj()}}else{a.Jj(d)}}else{_Id(a,b);if(a.Mj()){e=a.Nj(b,null);!!e&&e.oj()}}} +function oLd(a,b,c){var d,e,f;if(a.Pj()){f=a.Qj();KHd(a,b,c);d=a.Ij(3,null,c,b,f);if(a.Mj()){e=a.Nj(c,null);a.Tj()&&(e=a.Uj(c,e));if(!e){a.Jj(d)}else{e.nj(d);e.oj()}}else{a.Jj(d)}}else{KHd(a,b,c);if(a.Mj()){e=a.Nj(c,null);!!e&&e.oj()}}} +function bge(a,b){var c,d,e,f,g;g=pke(a.e.Dh(),b);e=new YHd;c=RD(a.g,124);for(f=a.i;--f>=0;){d=c[f];g.am(d.Lk())&&WGd(e,d)}!wLd(a,e)&&Mvd(a.e)&&eZd(a,b.Jk()?fge(a,6,b,(yob(),vob),null,-1,false):fge(a,b.tk()?2:1,b,null,null,-1,false))} +function _7b(a,b){var c,d,e,f,g;if(a.a==($uc(),Yuc)){return true}f=b.a.c;c=b.a.c+b.a.b;if(b.j){d=b.A;g=d.c.c.a-d.o.a/2;e=f-(d.n.a+d.o.a);if(e>g){return false}}if(b.q){d=b.C;g=d.c.c.a-d.o.a/2;e=d.n.a-c;if(e>g){return false}}return true} +function bRc(a){WQc();var b,c,d,e,f,g,h;c=new gub;for(e=new Anb(a.e.b);e.a1?(a.e*=Kfb(a.a)):(a.f/=Kfb(a.a));uRb(a);vRb(a);rRb(a);pQb(a.b,(tSb(),lSb),a.g)} +function n9b(a,b,c){var d,e,f,g,h,i;d=0;i=c;if(!b){d=c*(a.c.length-1);i*=-1}for(f=new Anb(a);f.a=0?a.Ah(null):a.Ph().Th(a,-1-b,null,null));a.Bh(RD(e,54),c);!!d&&d.oj();a.vh()&&a.wh()&&c>-1&&qvd(a,new N3d(a,9,c,f,e));return e}}}return f} +function stb(a,b){var c,d,e,f,g;f=a.b.Ce(b);d=(c=a.a.get(f),c==null?$C(jJ,rve,1,0,5,1):c);for(g=0;g>5;if(e>=a.d){return a.e<0}c=a.a[e];b=1<<(b&31);if(a.e<0){d=Uib(a);if(e>16)),15).dd(f);if(h0){!(Dmd(a.a.c)&&b.n.d)&&!(Emd(a.a.c)&&b.n.b)&&(b.g.d+=$wnd.Math.max(0,d/2-0.5));!(Dmd(a.a.c)&&b.n.a)&&!(Emd(a.a.c)&&b.n.c)&&(b.g.a-=d-1)}}} +function c7b(a){var b,c,d,e,f;e=new bnb;f=d7b(a,e);b=RD(mQb(a,(Ywc(),Iwc)),10);if(b){for(d=new Anb(b.j);d.a>b;f=a.m>>b|c<<22-b;e=a.l>>b|a.m<<22-b}else if(b<44){g=d?exe:0;f=c>>b-22;e=a.m>>b-22|c<<44-b}else{g=d?exe:0;f=d?dxe:0;e=c>>b-44}return hD(e&dxe,f&dxe,g&exe)} +function ORb(a){var b,c,d,e,f,g;this.c=new bnb;this.d=a;d=oxe;e=oxe;b=pxe;c=pxe;for(g=Sub(a,0);g.b!=g.d.c;){f=RD(evb(g),8);d=$wnd.Math.min(d,f.a);e=$wnd.Math.min(e,f.b);b=$wnd.Math.max(b,f.a);c=$wnd.Math.max(c,f.b)}this.a=new Uid(d,e,b-d,c-e)} +function Udc(a,b){var c,d,e,f,g,h;for(f=new Anb(a.b);f.a0&&ZD(b,44)){a.a._j();j=RD(b,44);i=j.ld();f=i==null?0:tb(i);g=bOd(a.a,f);c=a.a.d[g];if(c){d=RD(c.g,379);k=c.i;for(h=0;h=2){c=e.Kc();b=UD(c.Pb());while(c.Ob()){f=b;b=UD(c.Pb());d=$wnd.Math.min(d,(uFb(b),b)-(uFb(f),f))}}return d} +function iWc(a,b){var c,d,e;e=new bnb;for(d=Sub(b.a,0);d.b!=d.d.c;){c=RD(evb(d),65);c.b.g==a.g&&!lhb(c.b.c,IEe)&&dE(mQb(c.b,(h_c(),f_c)))!==dE(mQb(c.c,f_c))&&!yDb(new SDb(null,new Swb(e,16)),new OWc(c))&&(ZEb(e.c,c),true)}_mb(e,new QWc);return e} +function $u(a,b){var c,d,e;if(dE(b)===dE(Qb(a))){return true}if(!ZD(b,15)){return false}d=RD(b,15);e=a.gc();if(e!=d.gc()){return false}if(ZD(d,59)){for(c=0;c0&&(e=c);for(g=new Anb(a.f.e);g.a0){b-=1;c-=1}else{if(d>=0&&e<0){b+=1;c+=1}else{if(d>0&&e>=0){b-=1;c+=1}else{b+=1;c-=1}}}}}return new Ptd(sgb(b),sgb(c))} +function nNc(a,b){if(a.cb.c){return 1}else if(a.bb.b){return 1}else if(a.a!=b.a){return tb(a.a)-tb(b.a)}else if(a.d==(sNc(),rNc)&&b.d==qNc){return -1}else if(a.d==qNc&&b.d==rNc){return 1}return 0} +function ARc(a,b){var c,d,e,f,g;f=b.a;f.c.i==b.b?(g=f.d):(g=f.c);f.c.i==b.b?(d=f.c):(d=f.d);e=lQc(a.a,g,d);if(e>0&&e0}else if(e<0&&-e0}return false} +function X9c(a,b,c,d){var e,f,g,h,i,j,k,l;e=(b-a.d)/a.c.c.length;f=0;a.a+=c;a.d=b;for(l=new Anb(a.c);l.a>24}return g} +function Bfb(a){if(a.ze()){var b=a.c;b.Ae()?(a.o='['+b.n):!b.ze()?(a.o='[L'+b.xe()+';'):(a.o='['+b.xe());a.b=b.we()+'[]';a.k=b.ye()+'[]';return}var c=a.j;var d=a.d;d=d.split('/');a.o=Efb('.',[c,Efb('$',d)]);a.b=Efb('.',[c,Efb('.',d)]);a.k=d[d.length-1]} +function hJb(a,b){var c,d,e,f,g;g=null;for(f=new Anb(a.e.a);f.a=0;b-=2){for(c=0;c<=b;c+=2){if(a.b[c]>a.b[c+2]||a.b[c]===a.b[c+2]&&a.b[c+1]>a.b[c+3]){d=a.b[c+2];a.b[c+2]=a.b[c];a.b[c]=d;d=a.b[c+3];a.b[c+3]=a.b[c+1];a.b[c+1]=d}}}a.c=true} +function nKc(a,b){var c,d,e,f,g,h,i,j,k;j=-1;k=0;for(g=a,h=0,i=g.length;h0&&++k}}++j}return k} +function awd(a){var b,c;c=new dib(nfb(a.Rm));c.a+='@';Zhb(c,(b=tb(a)>>>0,b.toString(16)));if(a.Vh()){c.a+=' (eProxyURI: ';Yhb(c,a._h());if(a.Kh()){c.a+=' eClass: ';Yhb(c,a.Kh())}c.a+=')'}else if(a.Kh()){c.a+=' (eClass: ';Yhb(c,a.Kh());c.a+=')'}return c.a} +function KGb(a){var b,c,d,e;if(a.e){throw Adb(new dgb((lfb(lN),lye+lN.k+mye)))}a.d==(Cmd(),Amd)&&JGb(a,ymd);for(c=new Anb(a.a.a);c.a>24}return c} +function cNb(a,b,c){var d,e,f;e=RD(Vrb(a.i,b),314);if(!e){e=new UKb(a.d,b,c);Wrb(a.i,b,e);if(jMb(b)){tKb(a.a,b.c,b.b,e)}else{f=iMb(b);d=RD(Vrb(a.p,f),252);switch(f.g){case 1:case 3:e.j=true;cLb(d,b.b,e);break;case 4:case 2:e.k=true;cLb(d,b.c,e);}}}return e} +function Ndc(a,b){var c,d,e,f,g,h,i,j,k;i=ev(a.c-a.b&a.a.length-1);j=null;k=null;for(f=new Kmb(a);f.a!=f.b;){e=RD(Imb(f),10);c=(h=RD(mQb(e,(Ywc(),vwc)),12),!h?null:h.i);d=(g=RD(mQb(e,wwc),12),!g?null:g.i);if(j!=c||k!=d){Rdc(i,b);j=c;k=d}ZEb(i.c,e)}Rdc(i,b)} +function Rge(a,b,c,d){var e,f,g,h,i,j;h=new YHd;i=pke(a.e.Dh(),b);e=RD(a.g,124);nke();if(RD(b,69).xk()){for(g=0;g=0){return e}else{f=1;for(h=new Anb(b.j);h.a=0){return e}else{f=1;for(h=new Anb(b.j);h.a0&&b.Ne((tFb(e-1,a.c.length),RD(a.c[e-1],10)),f)>0){$mb(a,e,(tFb(e-1,a.c.length),RD(a.c[e-1],10)));--e}tFb(e,a.c.length);a.c[e]=f}c.a=new Tsb;c.b=new Tsb} +function yhd(a,b,c){var d,e,f,g,h,i,j,k;k=(d=RD(b.e&&b.e(),9),new Fsb(d,RD(WEb(d,d.length),9),0));i=vhb(c,'[\\[\\]\\s,]+');for(f=i,g=0,h=f.length;g=0){if(!b){b=new Rhb;d>0&&Nhb(b,(AFb(0,d,a.length),a.substr(0,d)))}b.a+='\\';Jhb(b,c&Bwe)}else !!b&&Jhb(b,c&Bwe)}return b?b.a:a} +function MYb(a){var b,c,d;for(c=new Anb(a.a.a.b);c.a0){!(Dmd(a.a.c)&&b.n.d)&&!(Emd(a.a.c)&&b.n.b)&&(b.g.d-=$wnd.Math.max(0,d/2-0.5));!(Dmd(a.a.c)&&b.n.a)&&!(Emd(a.a.c)&&b.n.c)&&(b.g.a+=$wnd.Math.max(0,d-1))}}} +function Ydc(a,b,c){var d,e;if((a.c-a.b&a.a.length-1)==2){if(b==(qpd(),Yod)||b==Xod){Odc(RD(omb(a),15),(Pnd(),Lnd));Odc(RD(omb(a),15),Mnd)}else{Odc(RD(omb(a),15),(Pnd(),Mnd));Odc(RD(omb(a),15),Lnd)}}else{for(e=new Kmb(a);e.a!=e.b;){d=RD(Imb(e),15);Odc(d,c)}}} +function HGd(a,b){var c,d,e,f,g,h,i;e=cv(new QGd(a));h=new Jkb(e,e.c.length);f=cv(new QGd(b));i=new Jkb(f,f.c.length);g=null;while(h.b>0&&i.b>0){c=(sFb(h.b>0),RD(h.a.Xb(h.c=--h.b),27));d=(sFb(i.b>0),RD(i.a.Xb(i.c=--i.b),27));if(c==d){g=c}else{break}}return g} +function Dmc(a,b,c){var d,e,f,g;if(Hmc(a,b)>Hmc(a,c)){d=b3b(c,(qpd(),Xod));a.d=d.dc()?0:L3b(RD(d.Xb(0),12));g=b3b(b,ppd);a.b=g.dc()?0:L3b(RD(g.Xb(0),12))}else{e=b3b(c,(qpd(),ppd));a.d=e.dc()?0:L3b(RD(e.Xb(0),12));f=b3b(b,Xod);a.b=f.dc()?0:L3b(RD(f.Xb(0),12))}} +function wNb(a,b){var c,d,e,f;c=a.o.a;for(f=RD(RD(Qc(a.r,b),21),87).Kc();f.Ob();){e=RD(f.Pb(),117);e.e.a=c*Kfb(UD(e.b.of(sNb)));e.e.b=(d=e.b,d.pf((umd(),Gld))?d.ag()==(qpd(),Yod)?-d.Mf().b-Kfb(UD(d.of(Gld))):Kfb(UD(d.of(Gld))):d.ag()==(qpd(),Yod)?-d.Mf().b:0)}} +function Mhc(a,b){var c,d,e,f;b.Ug('Self-Loop pre-processing',1);for(d=new Anb(a.a);d.aa.c){break}else if(e.a>=a.s){f<0&&(f=g);h=g}}i=(a.s+a.c)/2;if(f>=0){d=lTc(a,b,f,h);i=yTc((tFb(d,b.c.length),RD(b.c[d],339)));wTc(b,d,c)}return i} +function _Ad(a,b,c){var d,e,f,g,h,i,j;g=(f=new pVd,f);nVd(g,(uFb(b),b));j=(!g.b&&(g.b=new SVd((JTd(),FTd),C8,g)),g.b);for(i=1;i0&&ASb(this,e)}} +function zTb(a,b,c,d,e,f){var g,h,i;if(!e[b.a]){e[b.a]=true;g=d;!g&&(g=new gUb);Rmb(g.e,b);for(i=f[b.a].Kc();i.Ob();){h=RD(i.Pb(),290);if(h.d==c||h.c==c){continue}h.c!=b&&zTb(a,h.c,b,g,e,f);h.d!=b&&zTb(a,h.d,b,g,e,f);Rmb(g.c,h);Tmb(g.d,h.b)}return g}return null} +function v7b(a){var b,c,d,e,f,g,h;b=0;for(e=new Anb(a.e);e.a=2} +function _qc(a,b,c,d,e){var f,g,h,i,j,k;f=a.c.d.j;g=RD(ju(c,0),8);for(k=1;k1){return false}b=ysb(Xnd,cD(WC(A3,1),jwe,95,0,[Wnd,Znd]));if(dy(Tx(b,a))>1){return false}d=ysb(cod,cD(WC(A3,1),jwe,95,0,[bod,aod]));if(dy(Tx(d,a))>1){return false}return true} +function $Uc(a,b,c){var d,e,f;for(f=new Anb(a.t);f.a0){d.b.n-=d.c;d.b.n<=0&&d.b.u>0&&Mub(b,d.b)}}for(e=new Anb(a.i);e.a0){d.a.u-=d.c;d.a.u<=0&&d.a.n>0&&Mub(c,d.a)}}} +function tId(a){var b,c,d,e,f;if(a.g==null){a.d=a.bj(a.f);WGd(a,a.d);if(a.c){f=a.f;return f}}b=RD(a.g[a.i-1],51);e=b.Pb();a.e=b;c=a.bj(e);if(c.Ob()){a.d=c;WGd(a,c)}else{a.d=null;while(!b.Ob()){bD(a.g,--a.i,null);if(a.i==0){break}d=RD(a.g[a.i-1],51);b=d}}return e} +function Rfe(a,b){var c,d,e,f,g,h;d=b;e=d.Lk();if(qke(a.e,e)){if(e.Si()&&cge(a,e,d.md())){return false}}else{h=pke(a.e.Dh(),e);c=RD(a.g,124);for(f=0;f1||c>1){return 2}}if(b+c==1){return 2}return 0} +function Kwb(a,b){var c,d,e,f,g,h;f=a.a*Mxe+a.b*1502;h=a.b*Mxe+11;c=$wnd.Math.floor(h*Nxe);f+=c;h-=c*Oxe;f%=Oxe;a.a=f;a.b=h;if(b<=24){return $wnd.Math.floor(a.a*Ewb[b])}else{e=a.a*(1<=2147483648&&(d-=4294967296);return d}} +function uSc(a,b,c){var d,e,f,g,h,i,j;f=new bnb;j=new Yub;g=new Yub;vSc(a,j,g,b);tSc(a,j,g,b,c);for(i=new Anb(a);i.ad.b.g&&(ZEb(f.c,d),true)}}return f} +function jed(a,b,c){var d,e,f,g,h,i;h=a.c;for(g=(!c.q?(yob(),yob(),wob):c.q).vc().Kc();g.Ob();){f=RD(g.Pb(),44);d=!QDb(CDb(new SDb(null,new Swb(h,16)),new PAb(new xed(b,f)))).Bd((xDb(),wDb));if(d){i=f.md();if(ZD(i,4)){e=FId(i);e!=null&&(i=e)}b.qf(RD(f.ld(),149),i)}}} +function mbd(a,b,c){var d,e;Sed(a.b);Ved(a.b,(gbd(),dbd),(_cd(),$cd));Ved(a.b,ebd,b.g);Ved(a.b,fbd,b.a);a.a=Qed(a.b,b);c.Ug('Compaction by shrinking a tree',a.a.c.length);if(b.i.c.length>1){for(e=new Anb(a.a);e.a=0?a.Lh(d,true,true):Qvd(a,f,true),160));RD(e,220).Xl(b,c)}else{throw Adb(new agb(KHe+b.xe()+LHe))}} +function k2d(a,b){var c,d,e,f,g;if(!b){return null}else{f=ZD(a.Cb,90)||ZD(a.Cb,102);g=!f&&ZD(a.Cb,331);for(d=new dMd((!b.a&&(b.a=new iae(b,o7,b)),b.a));d.e!=d.i.gc();){c=RD(bMd(d),89);e=i2d(c);if(f?ZD(e,90):g?ZD(e,156):!!e){return e}}return f?(JTd(),zTd):(JTd(),wTd)}} +function W8b(a,b){var c,d,e,f;b.Ug('Resize child graph to fit parent.',1);for(d=new Anb(a.b);d.a=2*b&&Rmb(c,new BTc(g[d-1]+b,g[d]-b))}return c} +function dEd(a,b,c){var d,e,f,g,h,j,k,l;if(c){f=c.a.length;d=new vue(f);for(h=(d.b-d.a)*d.c<0?(uue(),tue):new Rue(d);h.Ob();){g=RD(h.Pb(),17);e=xDd(c,g.a);!!e&&(i=null,j=sEd(a,(k=(bvd(),l=new PCd,l),!!b&&NCd(k,b),k),e),jyd(j,zDd(e,uIe)),GEd(e,j),HEd(e,j),CEd(a,e,j))}}} +function sYd(a){var b,c,d,e,f,g;if(!a.j){g=new f1d;b=iYd;f=b.a.zc(a,b);if(f==null){for(d=new dMd(zYd(a));d.e!=d.i.gc();){c=RD(bMd(d),29);e=sYd(c);YGd(g,e);WGd(g,c)}b.a.Bc(a)!=null}VHd(g);a.j=new N$d((RD(QHd(xYd((lTd(),kTd).o),11),19),g.i),g.g);yYd(a).b&=-33}return a.j} +function lne(a){var b,c,d,e;if(a==null){return null}else{d=nue(a,true);e=mLe.length;if(lhb(d.substr(d.length-e,e),mLe)){c=d.length;if(c==4){b=(BFb(0,d.length),d.charCodeAt(0));if(b==43){return Yme}else if(b==45){return Xme}}else if(c==3){return Yme}}return new Ufb(d)}} +function pD(a){var b,c,d;c=a.l;if((c&c-1)!=0){return -1}d=a.m;if((d&d-1)!=0){return -1}b=a.h;if((b&b-1)!=0){return -1}if(b==0&&d==0&&c==0){return -1}if(b==0&&d==0&&c!=0){return ogb(c)}if(b==0&&d!=0&&c==0){return ogb(d)+22}if(b!=0&&d==0&&c==0){return ogb(b)+44}return -1} +function yo(a,b){var c,d,e,f,g;e=b.a&a.f;f=null;for(d=a.b[e];true;d=d.b){if(d==b){!f?(a.b[e]=b.b):(f.b=b.b);break}f=d}g=b.f&a.f;f=null;for(c=a.c[g];true;c=c.d){if(c==b){!f?(a.c[g]=b.d):(f.d=b.d);break}f=c}!b.e?(a.a=b.c):(b.e.c=b.c);!b.c?(a.e=b.e):(b.c.e=b.e);--a.i;++a.g} +function Dt(a,b){var c;b.d?(b.d.b=b.b):(a.a=b.b);b.b?(b.b.d=b.d):(a.e=b.d);if(!b.e&&!b.c){c=RD(Hvb(RD(_jb(a.b,b.a),260)),260);c.a=0;++a.c}else{c=RD(Hvb(RD(Wjb(a.b,b.a),260)),260);--c.a;!b.e?(c.b=RD(Hvb(b.c),511)):(b.e.c=b.c);!b.c?(c.c=RD(Hvb(b.e),511)):(b.c.e=b.e)}--a.d} +function XPb(a){var b,c,d,e,f,g,h,i,j,k;c=a.o;b=a.p;g=lve;e=qwe;h=lve;f=qwe;for(j=0;j0);f.a.Xb(f.c=--f.b);Ikb(f,e);sFb(f.b3&&UA(a,0,b-3)}} +function eXb(a){var b,c,d,e;if(dE(mQb(a,(yCc(),IAc)))===dE((Fnd(),Cnd))){return !a.e&&dE(mQb(a,gAc))!==dE((xvc(),uvc))}d=RD(mQb(a,hAc),299);e=Heb(TD(mQb(a,nAc)))||dE(mQb(a,oAc))===dE((stc(),ptc));b=RD(mQb(a,fAc),17).a;c=a.a.c.length;return !e&&d!=(xvc(),uvc)&&(b==0||b>c)} +function Rnc(a){var b,c;c=0;for(;c0){break}}if(c>0&&c0){break}}if(b>0&&c>16!=6&&!!b){if(Oje(a,b))throw Adb(new agb(UHe+Qzd(a)));d=null;!!a.Cb&&(d=(c=a.Db>>16,c>=0?Czd(a,d):a.Cb.Th(a,-1-c,null,d)));!!b&&(d=Ivd(b,a,6,d));d=Bzd(a,b,d);!!d&&d.oj()}else (a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,6,b,b))} +function pzd(a,b){var c,d;if(b!=a.Cb||a.Db>>16!=3&&!!b){if(Oje(a,b))throw Adb(new agb(UHe+qzd(a)));d=null;!!a.Cb&&(d=(c=a.Db>>16,c>=0?jzd(a,d):a.Cb.Th(a,-1-c,null,d)));!!b&&(d=Ivd(b,a,12,d));d=izd(a,b,d);!!d&&d.oj()}else (a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,3,b,b))} +function NCd(a,b){var c,d;if(b!=a.Cb||a.Db>>16!=9&&!!b){if(Oje(a,b))throw Adb(new agb(UHe+OCd(a)));d=null;!!a.Cb&&(d=(c=a.Db>>16,c>=0?LCd(a,d):a.Cb.Th(a,-1-c,null,d)));!!b&&(d=Ivd(b,a,9,d));d=KCd(a,b,d);!!d&&d.oj()}else (a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,9,b,b))} +function tWd(b){var c,d,e,f,g;e=WVd(b);g=b.j;if(g==null&&!!e){return b.Jk()?null:e.ik()}else if(ZD(e,156)){d=e.jk();if(d){f=d.wi();if(f!=b.i){c=RD(e,156);if(c.nk()){try{b.g=f.ti(c,g)}catch(a){a=zdb(a);if(ZD(a,82)){b.g=null}else throw Adb(a)}}b.i=f}}return b.g}return null} +function nRb(a){var b;b=new bnb;Rmb(b,new TFb(new rjd(a.c,a.d),new rjd(a.c+a.b,a.d)));Rmb(b,new TFb(new rjd(a.c,a.d),new rjd(a.c,a.d+a.a)));Rmb(b,new TFb(new rjd(a.c+a.b,a.d+a.a),new rjd(a.c+a.b,a.d)));Rmb(b,new TFb(new rjd(a.c+a.b,a.d+a.a),new rjd(a.c,a.d+a.a)));return b} +function ic(b){var c,d,e;if(b==null){return vve}try{return jeb(b)}catch(a){a=zdb(a);if(ZD(a,103)){c=a;e=nfb(rb(b))+'@'+(d=(gib(),jFb(b))>>>0,d.toString(16));lBb(pBb(),(SAb(),'Exception during lenientFormat for '+e),c);return '<'+e+' threw '+nfb(c.Rm)+'>'}else throw Adb(a)}} +function mTb(a,b,c){var d,e,f;for(f=b.a.ec().Kc();f.Ob();){e=RD(f.Pb(),74);d=RD(Wjb(a.b,e),272);!d&&(vCd(JGd(e))==vCd(LGd(e))?lTb(a,e,c):JGd(e)==vCd(LGd(e))?Wjb(a.c,e)==null&&Wjb(a.b,LGd(e))!=null&&oTb(a,e,c,false):Wjb(a.d,e)==null&&Wjb(a.b,JGd(e))!=null&&oTb(a,e,c,true))}} +function Pfc(a,b){var c,d,e,f,g,h,i;for(e=a.Kc();e.Ob();){d=RD(e.Pb(),10);h=new R3b;P3b(h,d);Q3b(h,(qpd(),Xod));pQb(h,(Ywc(),Hwc),(Geb(),true));for(g=b.Kc();g.Ob();){f=RD(g.Pb(),10);i=new R3b;P3b(i,f);Q3b(i,ppd);pQb(i,Hwc,true);c=new a1b;pQb(c,Hwc,true);Y0b(c,h);Z0b(c,i)}}} +function Pqc(a,b,c,d){var e,f,g,h;e=Nqc(a,b,c);f=Nqc(a,c,b);g=RD(Wjb(a.c,b),118);h=RD(Wjb(a.c,c),118);if(e1){b=eJb((c=new gJb,++a.b,c),a.d);for(h=Sub(f,0);h.b!=h.d.c;){g=RD(evb(h),125);rIb(uIb(tIb(vIb(sIb(new wIb,1),0),b),g))}}} +function isc(a,b,c){var d,e,f,g,h;c.Ug('Breaking Point Removing',1);a.a=RD(mQb(b,(yCc(),yAc)),223);for(f=new Anb(b.b);f.a>16!=11&&!!b){if(Oje(a,b))throw Adb(new agb(UHe+zCd(a)));d=null;!!a.Cb&&(d=(c=a.Db>>16,c>=0?sCd(a,d):a.Cb.Th(a,-1-c,null,d)));!!b&&(d=Ivd(b,a,10,d));d=rCd(a,b,d);!!d&&d.oj()}else (a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,11,b,b))} +function C0b(a){var b,c,d,e;for(d=new vkb((new mkb(a.b)).a);d.b;){c=tkb(d);e=RD(c.ld(),12);b=RD(c.md(),10);pQb(b,(Ywc(),Awc),e);pQb(e,Iwc,b);pQb(e,nwc,(Geb(),true));Q3b(e,RD(mQb(b,hwc),64));mQb(b,hwc);pQb(e.i,(yCc(),BBc),(Bod(),yod));RD(mQb(Y2b(e.i),kwc),21).Fc((ovc(),kvc))}} +function X7b(a,b,c){var d,e,f,g,h,i;f=0;g=0;if(a.c){for(i=new Anb(a.d.i.j);i.af.a){return -1}else if(e.ai){k=a.d;a.d=$C(D6,KJe,66,2*i+4,0,1);for(f=0;f=9223372036854775807){return MD(),ID}e=false;if(a<0){e=true;a=-a}d=0;if(a>=hxe){d=eE(a/hxe);a-=d*hxe}c=0;if(a>=gxe){c=eE(a/gxe);a-=c*gxe}b=eE(a);f=hD(b,c,d);e&&nD(f);return f} +function KCb(a){var b,c,d,e,f;f=new bnb;Umb(a.b,new SEb(f));a.b.c.length=0;if(f.c.length!=0){b=(tFb(0,f.c.length),RD(f.c[0],82));for(c=1,d=f.c.length;c=-b&&d==b){return new Ptd(sgb(c-1),sgb(d))}return new Ptd(sgb(c),sgb(d-1))} +function lcc(){hcc();return cD(WC(YS,1),jwe,81,0,[nbc,kbc,obc,Ebc,Xbc,Ibc,bcc,Nbc,Vbc,zbc,Rbc,Mbc,Wbc,vbc,dcc,ebc,Qbc,Zbc,Fbc,Ybc,fcc,Tbc,fbc,Ubc,gcc,_bc,ecc,Gbc,sbc,Hbc,Dbc,ccc,ibc,qbc,Kbc,hbc,Lbc,Bbc,wbc,Obc,ybc,lbc,jbc,Cbc,xbc,Pbc,acc,gbc,Sbc,Abc,Jbc,tbc,rbc,$bc,pbc,ubc,mbc])} +function Cmc(a,b,c){a.d=0;a.b=0;b.k==(r3b(),q3b)&&c.k==q3b&&RD(mQb(b,(Ywc(),Awc)),10)==RD(mQb(c,Awc),10)&&(Gmc(b).j==(qpd(),Yod)?Dmc(a,b,c):Dmc(a,c,b));b.k==q3b&&c.k==o3b?Gmc(b).j==(qpd(),Yod)?(a.d=1):(a.b=1):c.k==q3b&&b.k==o3b&&(Gmc(c).j==(qpd(),Yod)?(a.b=1):(a.d=1));Imc(a,b,c)} +function EFd(a){var b,c,d,e,f,g,h,i,j,k,l;l=HFd(a);b=a.a;i=b!=null;i&&sDd(l,'category',a.a);e=cve(new Xkb(a.d));g=!e;if(g){j=new MB;sC(l,'knownOptions',j);c=new MFd(j);xgb(new Xkb(a.d),c)}f=cve(a.g);h=!f;if(h){k=new MB;sC(l,'supportedFeatures',k);d=new OFd(k);xgb(a.g,d)}return l} +function Ly(a){var b,c,d,e,f,g,h,i,j;d=false;b=336;c=0;f=new hq(a.length);for(h=a,i=0,j=h.length;i>16!=7&&!!b){if(Oje(a,b))throw Adb(new agb(UHe+gCd(a)));d=null;!!a.Cb&&(d=(c=a.Db>>16,c>=0?cCd(a,d):a.Cb.Th(a,-1-c,null,d)));!!b&&(d=RD(b,54).Rh(a,1,H4,d));d=bCd(a,b,d);!!d&&d.oj()}else (a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,7,b,b))} +function lVd(a,b){var c,d;if(b!=a.Cb||a.Db>>16!=3&&!!b){if(Oje(a,b))throw Adb(new agb(UHe+oVd(a)));d=null;!!a.Cb&&(d=(c=a.Db>>16,c>=0?iVd(a,d):a.Cb.Th(a,-1-c,null,d)));!!b&&(d=RD(b,54).Rh(a,0,p7,d));d=hVd(a,b,d);!!d&&d.oj()}else (a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,3,b,b))} +function Mjb(a,b){Ljb();var c,d,e,f,g,h,i,j,k;if(b.d>a.d){h=a;a=b;b=h}if(b.d<63){return Qjb(a,b)}g=(a.d&-2)<<4;j=$ib(a,g);k=$ib(b,g);d=Gjb(a,Zib(j,g));e=Gjb(b,Zib(k,g));i=Mjb(j,k);c=Mjb(d,e);f=Mjb(Gjb(j,d),Gjb(e,k));f=Bjb(Bjb(f,i),c);f=Zib(f,g);i=Zib(i,g<<1);return Bjb(Bjb(i,f),c)} +function _Cc(){_Cc=geb;ZCc=new bDc(lEe,0);WCc=new bDc('LONGEST_PATH',1);XCc=new bDc('LONGEST_PATH_SOURCE',2);TCc=new bDc('COFFMAN_GRAHAM',3);VCc=new bDc(BBe,4);$Cc=new bDc('STRETCH_WIDTH',5);YCc=new bDc('MIN_WIDTH',6);SCc=new bDc('BF_MODEL_ORDER',7);UCc=new bDc('DF_MODEL_ORDER',8)} +function AKc(a,b,c){var d,e,f,g,h;g=aMc(a,c);h=$C(jR,WAe,10,b.length,0,1);d=0;for(f=g.Kc();f.Ob();){e=RD(f.Pb(),12);Heb(TD(mQb(e,(Ywc(),nwc))))&&(h[d++]=RD(mQb(e,Iwc),10))}if(d=0;f+=c?1:-1){g=g|b.c.lg(i,f,c,d&&!Heb(TD(mQb(b.j,(Ywc(),jwc))))&&!Heb(TD(mQb(b.j,(Ywc(),Owc)))));g=g|b.q.ug(i,f,c);g=g|CKc(a,i[f],c,d)}Ysb(a.c,b);return g} +function F6b(a,b,c){var d,e,f,g,h,i,j,k,l,m;for(k=u2b(a.j),l=0,m=k.length;l1&&(a.a=true);QQb(RD(c.b,68),$id(ajd(RD(b.b,68).c),ijd(ojd(ajd(RD(c.b,68).a),RD(b.b,68).a),e)));Odd(a,b);Qdd(a,c)}} +function tYb(a){var b,c,d,e,f,g,h;for(f=new Anb(a.a.a);f.a0&&f>0?(g.p=b++):d>0?(g.p=c++):f>0?(g.p=e++):(g.p=c++);}}yob();_mb(a.j,new Lfc)} +function zic(a){var b,c;c=null;b=RD(Vmb(a.g,0),18);do{c=b.d.i;if(nQb(c,(Ywc(),wwc))){return RD(mQb(c,wwc),12).i}if(c.k!=(r3b(),p3b)&&gs(new is(Mr(a3b(c).a.Kc(),new ir)))){b=RD(hs(new is(Mr(a3b(c).a.Kc(),new ir))),18)}else if(c.k!=p3b){return null}}while(!!c&&c.k!=(r3b(),p3b));return c} +function sqc(a,b){var c,d,e,f,g,h,i,j,k;h=b.j;g=b.g;i=RD(Vmb(h,h.c.length-1),113);k=(tFb(0,h.c.length),RD(h.c[0],113));j=oqc(a,g,i,k);for(f=1;fj){i=c;k=e;j=d}}b.a=k;b.c=i} +function fMc(a,b,c){var d,e,f,g,h,i,j;j=new yAb(new TMc(a));for(g=cD(WC(xR,1),XAe,12,0,[b,c]),h=0,i=g.length;hi-a.b&&hi-a.a&&h0){if(f.a){h=f.b.Mf().a;if(c>h){e=(c-h)/2;f.d.b=e;f.d.c=e}}else{f.d.c=a.s+c}}else if(Rod(a.u)){d=wsd(f.b);d.c<0&&(f.d.b=-d.c);d.c+d.b>f.b.Mf().a&&(f.d.c=d.c+d.b-f.b.Mf().a)}}} +function RUc(a,b){var c,d,e,f,g;g=new bnb;c=b;do{f=RD(Wjb(a.b,c),131);f.B=c.c;f.D=c.d;ZEb(g.c,f);c=RD(Wjb(a.k,c),18)}while(c);d=(tFb(0,g.c.length),RD(g.c[0],131));d.j=true;d.A=RD(d.d.a.ec().Kc().Pb(),18).c.i;e=RD(Vmb(g,g.c.length-1),131);e.q=true;e.C=RD(e.d.a.ec().Kc().Pb(),18).d.i;return g} +function pPb(a){var b,c;b=RD(a.a,17).a;c=RD(a.b,17).a;if(b>=0){if(b==c){return new Ptd(sgb(-b-1),sgb(-b-1))}if(b==-c){return new Ptd(sgb(-b),sgb(c+1))}}if($wnd.Math.abs(b)>$wnd.Math.abs(c)){if(b<0){return new Ptd(sgb(-b),sgb(c))}return new Ptd(sgb(-b),sgb(c+1))}return new Ptd(sgb(b+1),sgb(c))} +function H8b(a){var b,c;c=RD(mQb(a,(yCc(),UAc)),171);b=RD(mQb(a,(Ywc(),owc)),311);if(c==(cxc(),$wc)){pQb(a,UAc,bxc);pQb(a,owc,(Gvc(),Fvc))}else if(c==axc){pQb(a,UAc,bxc);pQb(a,owc,(Gvc(),Dvc))}else if(b==(Gvc(),Fvc)){pQb(a,UAc,$wc);pQb(a,owc,Evc)}else if(b==Dvc){pQb(a,UAc,axc);pQb(a,owc,Evc)}} +function dSc(){dSc=geb;bSc=new pSc;ZRc=pfd(new ufd,(sXb(),pXb),(hcc(),Fbc));aSc=nfd(pfd(new ufd,pXb,Tbc),rXb,Sbc);cSc=mfd(mfd(rfd(nfd(pfd(new ufd,nXb,bcc),rXb,acc),qXb),_bc),ccc);$Rc=nfd(pfd(pfd(pfd(new ufd,oXb,Ibc),qXb,Kbc),qXb,Lbc),rXb,Jbc);_Rc=nfd(pfd(pfd(new ufd,qXb,Lbc),qXb,qbc),rXb,pbc)} +function HUc(){HUc=geb;CUc=pfd(nfd(new ufd,(sXb(),rXb),(hcc(),tbc)),pXb,Fbc);GUc=mfd(mfd(rfd(nfd(pfd(new ufd,nXb,bcc),rXb,acc),qXb),_bc),ccc);DUc=nfd(pfd(pfd(pfd(new ufd,oXb,Ibc),qXb,Kbc),qXb,Lbc),rXb,Jbc);FUc=pfd(pfd(new ufd,pXb,Tbc),rXb,Sbc);EUc=nfd(pfd(pfd(new ufd,qXb,Lbc),qXb,qbc),rXb,pbc)} +function eSc(a,b,c,d,e){var f,g;if((!W0b(b)&&b.c.i.c==b.d.i.c||!djd(xjd(cD(WC(l3,1),Nve,8,0,[e.i.n,e.n,e.a])),c))&&!W0b(b)){b.c==e?hu(b.a,0,new sjd(c)):Mub(b.a,new sjd(c));if(d&&!Zsb(a.a,c)){g=RD(mQb(b,(yCc(),RAc)),75);if(!g){g=new Ejd;pQb(b,RAc,g)}f=new sjd(c);Pub(g,f,g.c.b,g.c);Ysb(a.a,f)}}} +function ht(a,b){var c,d,e,f;f=Ydb(Ndb(cwe,qgb(Ydb(Ndb(b==null?0:tb(b),dwe)),15)));c=f&a.b.length-1;e=null;for(d=a.b[c];d;e=d,d=d.a){if(d.d==f&&Hb(d.i,b)){!e?(a.b[c]=d.a):(e.a=d.a);Ts(RD(Hvb(d.c),604),RD(Hvb(d.f),604));Ss(RD(Hvb(d.b),227),RD(Hvb(d.e),227));--a.f;++a.e;return true}}return false} +function dec(a){var b,c;for(c=new is(Mr(Z2b(a).a.Kc(),new ir));gs(c);){b=RD(hs(c),18);if(b.c.i.k!=(r3b(),n3b)){throw Adb(new Jed(nBe+X2b(a)+"' has its layer constraint set to FIRST, but has at least one incoming edge that "+' does not come from a FIRST_SEPARATE node. That must not happen.'))}}} +function Twd(a,b,c){var d,e,f,g,h,i,j;e=ggb(a.Db&254);if(e==0){a.Eb=c}else{if(e==1){h=$C(jJ,rve,1,2,5,1);f=Xwd(a,b);if(f==0){h[0]=c;h[1]=a.Eb}else{h[0]=a.Eb;h[1]=c}}else{h=$C(jJ,rve,1,e+1,5,1);g=SD(a.Eb);for(d=2,i=0,j=0;d<=128;d<<=1){d==b?(h[j++]=c):(a.Db&d)!=0&&(h[j++]=g[i++])}}a.Eb=h}a.Db|=b} +function vQb(a,b,c){var d,e,f,g;this.b=new bnb;e=0;d=0;for(g=new Anb(a);g.a0){f=RD(Vmb(this.b,0),176);e+=f.o;d+=f.p}e*=2;d*=2;b>1?(e=eE($wnd.Math.ceil(e*b))):(d=eE($wnd.Math.ceil(d/b)));this.a=new gQb(e,d)} +function mkc(a,b,c,d,e,f){var g,h,i,j,k,l,m,n,o,p,q,r;k=d;if(b.j&&b.o){n=RD(Wjb(a.f,b.A),60);p=n.d.c+n.d.b;--k}else{p=b.a.c+b.a.b}l=e;if(c.q&&c.o){n=RD(Wjb(a.f,c.C),60);j=n.d.c;++l}else{j=c.a.c}q=j-p;i=$wnd.Math.max(2,l-k);h=q/i;o=p+h;for(m=k;m=0;g+=e?1:-1){h=b[g];i=d==(qpd(),Xod)?e?b3b(h,d):hv(b3b(h,d)):e?hv(b3b(h,d)):b3b(h,d);f&&(a.c[h.p]=i.gc());for(l=i.Kc();l.Ob();){k=RD(l.Pb(),12);a.d[k.p]=j++}Tmb(c,i)}} +function AUc(a,b,c){var d,e,f,g,h,i,j,k;f=Kfb(UD(a.b.Kc().Pb()));j=Kfb(UD(fr(b.b)));d=ijd(ajd(a.a),j-c);e=ijd(ajd(b.a),c-f);k=$id(d,e);ijd(k,1/(j-f));this.a=k;this.b=new bnb;h=true;g=a.b.Kc();g.Pb();while(g.Ob()){i=Kfb(UD(g.Pb()));if(h&&i-c>AEe){this.b.Fc(c);h=false}this.b.Fc(i)}h&&this.b.Fc(c)} +function mJb(a){var b,c,d,e;pJb(a,a.n);if(a.d.c.length>0){Nnb(a.c);while(xJb(a,RD(ynb(new Anb(a.e.a)),125))>5;b&=31;if(d>=a.d){return a.e<0?(Pib(),Jib):(Pib(),Oib)}f=a.d-d;e=$C(kE,Pwe,28,f+1,15,1);ujb(e,f,a.a,d,b);if(a.e<0){for(c=0;c0&&a.a[c]<<32-b!=0){for(c=0;c=0){return false}else{c=Eee((lke(),jke),e,b);if(!c){return true}else{d=c.Ik();return (d>1||d==-1)&&yfe(Qee(jke,c))!=3}}}}else{return false}} +function _4b(a,b,c,d){var e,f,g,h,i;h=AGd(RD(QHd((!b.b&&(b.b=new Yie(E4,b,4,7)),b.b),0),84));i=AGd(RD(QHd((!b.c&&(b.c=new Yie(E4,b,5,8)),b.c),0),84));if(vCd(h)==vCd(i)){return null}if(NGd(i,h)){return null}g=kzd(b);if(g==c){return d}else{f=RD(Wjb(a.a,g),10);if(f){e=f.e;if(e){return e}}}return null} +function uHc(a,b,c){var d,e,f,g,h;c.Ug('Longest path to source layering',1);a.a=b;h=a.a.a;a.b=$C(kE,Pwe,28,h.c.length,15,1);d=0;for(g=new Anb(h);g.a0){c[0]+=a.d;g-=c[0]}if(c[2]>0){c[2]+=a.d;g-=c[2]}f=$wnd.Math.max(0,g);c[1]=$wnd.Math.max(c[1],g);mKb(a,XJb,e.c+d.b+c[0]-(c[1]-g)/2,c);if(b==XJb){a.c.b=f;a.c.c=e.c+d.b+(f-g)/2}} +function D_b(){this.c=$C(iE,vxe,28,(qpd(),cD(WC(E3,1),NAe,64,0,[opd,Yod,Xod,npd,ppd])).length,15,1);this.b=$C(iE,vxe,28,cD(WC(E3,1),NAe,64,0,[opd,Yod,Xod,npd,ppd]).length,15,1);this.a=$C(iE,vxe,28,cD(WC(E3,1),NAe,64,0,[opd,Yod,Xod,npd,ppd]).length,15,1);Lnb(this.c,oxe);Lnb(this.b,pxe);Lnb(this.a,pxe)} +function rte(a,b,c){var d,e,f,g;if(b<=c){e=b;f=c}else{e=c;f=b}d=0;if(a.b==null){a.b=$C(kE,Pwe,28,2,15,1);a.b[0]=e;a.b[1]=f;a.c=true}else{d=a.b.length;if(a.b[d-1]+1==e){a.b[d-1]=f;return}g=$C(kE,Pwe,28,d+2,15,1);hib(a.b,0,g,0,d);a.b=g;a.b[d-1]>=e&&(a.c=false,a.a=false);a.b[d++]=e;a.b[d]=f;a.c||vte(a)}} +function Oqc(a,b,c){var d,e,f,g,h,i,j;j=b.d;a.a=new cnb(j.c.length);a.c=new Tsb;for(h=new Anb(j);h.a=0?a.Lh(j,false,true):Qvd(a,c,false),61));n:for(f=l.Kc();f.Ob();){e=RD(f.Pb(),58);for(k=0;k1){vLd(e,e.i-1)}}return d}} +function Vdc(a,b){var c,d,e,f,g,h,i;c=new wmb;for(f=new Anb(a.b);f.aa.d[g.p]){c+=ZLc(a.b,f);hmb(a.a,sgb(f))}}while(!nmb(a.a)){XLc(a.b,RD(smb(a.a),17).a)}}return c} +function Uec(a){var b,c,d,e,f,g,h,i,j;a.a=new e6b;j=0;e=0;for(d=new Anb(a.i.b);d.ah.d&&(k=h.d+h.a+j)}}c.c.d=k;b.a.zc(c,b);i=$wnd.Math.max(i,c.c.d+c.c.a)}return i} +function ovc(){ovc=geb;fvc=new pvc('COMMENTS',0);hvc=new pvc('EXTERNAL_PORTS',1);ivc=new pvc('HYPEREDGES',2);jvc=new pvc('HYPERNODES',3);kvc=new pvc('NON_FREE_PORTS',4);lvc=new pvc('NORTH_SOUTH_PORTS',5);nvc=new pvc(FBe,6);evc=new pvc('CENTER_LABELS',7);gvc=new pvc('END_LABELS',8);mvc=new pvc('PARTITIONS',9)} +function PA(a,b,c,d,e){if(d<0){d=EA(a,e,cD(WC(qJ,1),Nve,2,6,[Cwe,Dwe,Ewe,Fwe,Gwe,Hwe,Iwe,Jwe,Kwe,Lwe,Mwe,Nwe]),b);d<0&&(d=EA(a,e,cD(WC(qJ,1),Nve,2,6,['Jan','Feb','Mar','Apr',Gwe,'Jun','Jul','Aug','Sep','Oct','Nov','Dec']),b));if(d<0){return false}c.k=d;return true}else if(d>0){c.k=d-1;return true}return false} +function RA(a,b,c,d,e){if(d<0){d=EA(a,e,cD(WC(qJ,1),Nve,2,6,[Cwe,Dwe,Ewe,Fwe,Gwe,Hwe,Iwe,Jwe,Kwe,Lwe,Mwe,Nwe]),b);d<0&&(d=EA(a,e,cD(WC(qJ,1),Nve,2,6,['Jan','Feb','Mar','Apr',Gwe,'Jun','Jul','Aug','Sep','Oct','Nov','Dec']),b));if(d<0){return false}c.k=d;return true}else if(d>0){c.k=d-1;return true}return false} +function TA(a,b,c,d,e,f){var g,h,i,j;h=32;if(d<0){if(b[0]>=a.length){return false}h=ihb(a,b[0]);if(h!=43&&h!=45){return false}++b[0];d=HA(a,b);if(d<0){return false}h==45&&(d=-d)}if(h==32&&b[0]-c==2&&e.b==2){i=new uB;j=i.q.getFullYear()-Owe+Owe-80;g=j%100;f.a=d==g;d+=(j/100|0)*100+(d=0?jjb(a):Xib(jjb(Odb(a))));Kjb[b]=Jdb(Sdb(a,b),0)?jjb(Sdb(a,b)):Xib(jjb(Odb(Sdb(a,b))));a=Ndb(a,5)}for(;b=j&&(i=d)}!!i&&(k=$wnd.Math.max(k,i.a.o.a));if(k>m){l=j;m=k}}return l} +function SNb(a){var b,c,d,e,f,g,h;f=new yAb(RD(Qb(new eOb),50));h=pxe;for(c=new Anb(a.d);c.aFFe?_mb(i,a.b):d<=FFe&&d>GFe?_mb(i,a.d):d<=GFe&&d>HFe?_mb(i,a.c):d<=HFe&&_mb(i,a.a);f=$5c(a,i,f)}return e} +function sTc(a,b,c,d){var e,f,g,h,i,j;e=(d.c+d.a)/2;Xub(b.j);Mub(b.j,e);Xub(c.e);Mub(c.e,e);j=new ATc;for(h=new Anb(a.f);h.a1;if(h){d=new rjd(e,c.b);Mub(b.a,d)}zjd(b.a,cD(WC(l3,1),Nve,8,0,[m,l]))} +function TGc(a,b,c){var d,e;if(b=48;c--){Eqe[c]=c-48<<24>>24}for(d=70;d>=65;d--){Eqe[d]=d-65+10<<24>>24}for(e=102;e>=97;e--){Eqe[e]=e-97+10<<24>>24}for(f=0;f<10;f++)Fqe[f]=48+f&Bwe;for(a=10;a<=15;a++)Fqe[a]=65+a-10&Bwe} +function yYc(a,b){b.Ug('Process graph bounds',1);pQb(a,(q$c(),ZZc),Uvb(TCb(HDb(new SDb(null,new Swb(a.b,16)),new DYc))));pQb(a,_Zc,Uvb(TCb(HDb(new SDb(null,new Swb(a.b,16)),new FYc))));pQb(a,YZc,Uvb(SCb(HDb(new SDb(null,new Swb(a.b,16)),new HYc))));pQb(a,$Zc,Uvb(SCb(HDb(new SDb(null,new Swb(a.b,16)),new JYc))));b.Vg()} +function PWb(a){var b,c,d,e,f;e=RD(mQb(a,(yCc(),lBc)),21);f=RD(mQb(a,oBc),21);c=new rjd(a.f.a+a.d.b+a.d.c,a.f.b+a.d.d+a.d.a);b=new sjd(c);if(e.Hc((Qpd(),Mpd))){d=RD(mQb(a,nBc),8);if(f.Hc((dqd(),Ypd))){d.a<=0&&(d.a=20);d.b<=0&&(d.b=20)}b.a=$wnd.Math.max(c.a,d.a);b.b=$wnd.Math.max(c.b,d.b)}Heb(TD(mQb(a,mBc)))||QWb(a,c,b)} +function lOc(a,b){var c,d,e,f;for(f=b3b(b,(qpd(),npd)).Kc();f.Ob();){d=RD(f.Pb(),12);c=RD(mQb(d,(Ywc(),Iwc)),10);!!c&&rIb(uIb(tIb(vIb(sIb(new wIb,0),0.1),a.i[b.p].d),a.i[c.p].a))}for(e=b3b(b,Yod).Kc();e.Ob();){d=RD(e.Pb(),12);c=RD(mQb(d,(Ywc(),Iwc)),10);!!c&&rIb(uIb(tIb(vIb(sIb(new wIb,0),0.1),a.i[c.p].d),a.i[b.p].a))}} +function oYd(a){var b,c,d,e,f,g;if(!a.c){g=new W$d;b=iYd;f=b.a.zc(a,b);if(f==null){for(d=new dMd(tYd(a));d.e!=d.i.gc();){c=RD(bMd(d),89);e=i2d(c);ZD(e,90)&&YGd(g,oYd(RD(e,29)));WGd(g,c)}b.a.Bc(a)!=null;b.a.gc()==0&&undefined}T$d(g);VHd(g);a.c=new N$d((RD(QHd(xYd((lTd(),kTd).o),15),19),g.i),g.g);yYd(a).b&=-33}return a.c} +function Dre(a){var b;if(a.c!=10)throw Adb(new Lqe(TId((Hde(),VIe))));b=a.a;switch(b){case 110:b=10;break;case 114:b=13;break;case 116:b=9;break;case 92:case 124:case 46:case 94:case 45:case 63:case 42:case 43:case 123:case 125:case 40:case 41:case 91:case 93:break;default:throw Adb(new Lqe(TId((Hde(),xJe))));}return b} +function GD(a){var b,c,d,e,f;if(a.l==0&&a.m==0&&a.h==0){return '0'}if(a.h==fxe&&a.m==0&&a.l==0){return '-9223372036854775808'}if(a.h>>19!=0){return '-'+GD(xD(a))}c=a;d='';while(!(c.l==0&&c.m==0&&c.h==0)){e=fD(ixe);c=iD(c,e,true);b=''+FD(eD);if(!(c.l==0&&c.m==0&&c.h==0)){f=9-b.length;for(;f>0;f--){b='0'+b}}d=b+d}return d} +function tkc(a){var b,c,d,e,f,g,h;b=false;c=0;for(e=new Anb(a.d.b);e.a=a.a){return -1}if(!W9b(b,c)){return -1}if(gr(RD(d.Kb(b),20))){return 1}e=0;for(g=RD(d.Kb(b),20).Kc();g.Ob();){f=RD(g.Pb(),18);i=f.c.i==b?f.d.i:f.c.i;h=X9b(a,i,c,d);if(h==-1){return -1}e=$wnd.Math.max(e,h);if(e>a.c-1){return -1}}return e+1} +function _Gd(a,b){var c,d,e,f,g,h;if(dE(b)===dE(a)){return true}if(!ZD(b,15)){return false}d=RD(b,15);h=a.gc();if(d.gc()!=h){return false}g=d.Kc();if(a.Yi()){for(c=0;c0){a._j();if(b!=null){for(f=0;f>24}case 97:case 98:case 99:case 100:case 101:case 102:{return a-97+10<<24>>24}case 65:case 66:case 67:case 68:case 69:case 70:{return a-65+10<<24>>24}default:{throw Adb(new Vgb('Invalid hexadecimal'))}}} +function iIb(){iIb=geb;hIb=new jIb('SPIRAL',0);cIb=new jIb('LINE_BY_LINE',1);dIb=new jIb('MANHATTAN',2);bIb=new jIb('JITTER',3);fIb=new jIb('QUADRANTS_LINE_BY_LINE',4);gIb=new jIb('QUADRANTS_MANHATTAN',5);eIb=new jIb('QUADRANTS_JITTER',6);aIb=new jIb('COMBINE_LINE_BY_LINE_MANHATTAN',7);_Hb=new jIb('COMBINE_JITTER_MANHATTAN',8)} +function Urc(a,b,c,d){var e,f,g,h,i,j;i=Zrc(a,c);j=Zrc(b,c);e=false;while(!!i&&!!j){if(d||Xrc(i,j,c)){g=Zrc(i,c);h=Zrc(j,c);asc(b);asc(a);f=i.c;Hec(i,false);Hec(j,false);if(c){f3b(b,j.p,f);b.p=j.p;f3b(a,i.p+1,f);a.p=i.p}else{f3b(a,i.p,f);a.p=i.p;f3b(b,j.p+1,f);b.p=j.p}g3b(i,null);g3b(j,null);i=g;j=h;e=true}else{break}}return e} +function aDc(a){switch(a.g){case 0:return new XHc;case 1:return new pHc;case 3:return new GGc;case 4:return new gHc;case 5:return new jIc;case 6:return new IHc;case 2:return new xHc;case 7:return new pGc;case 8:return new YGc;default:throw Adb(new agb('No implementation is available for the layerer '+(a.f!=null?a.f:''+a.g)));}} +function tIc(a,b,c,d){var e,f,g,h,i;e=false;f=false;for(h=new Anb(d.j);h.a=b.length){throw Adb(new veb('Greedy SwitchDecider: Free layer not in graph.'))}this.c=b[a];this.e=new DMc(d);rMc(this.e,this.c,(qpd(),ppd));this.i=new DMc(d);rMc(this.i,this.c,Xod);this.f=new Kmc(this.c);this.a=!f&&e.i&&!e.s&&this.c[0].k==(r3b(),m3b);this.a&&Nmc(this,a,b.length)} +function $Mb(a,b){var c,d,e,f,g,h;f=!a.B.Hc((dqd(),Wpd));g=a.B.Hc(Zpd);a.a=new wKb(g,f,a.c);!!a.n&&C2b(a.a.n,a.n);cLb(a.g,(ZJb(),XJb),a.a);if(!b){d=new dLb(1,f,a.c);d.n.a=a.k;Wrb(a.p,(qpd(),Yod),d);e=new dLb(1,f,a.c);e.n.d=a.k;Wrb(a.p,npd,e);h=new dLb(0,f,a.c);h.n.c=a.k;Wrb(a.p,ppd,h);c=new dLb(0,f,a.c);c.n.b=a.k;Wrb(a.p,Xod,c)}} +function zkc(a){var b,c,d;b=RD(mQb(a.d,(yCc(),yAc)),223);switch(b.g){case 2:c=rkc(a);break;case 3:c=(d=new bnb,FDb(CDb(GDb(EDb(EDb(new SDb(null,new Swb(a.d.b,16)),new wlc),new ylc),new Alc),new Kkc),new Clc(d)),d);break;default:throw Adb(new dgb('Compaction not supported for '+b+' edges.'));}ykc(a,c);xgb(new Xkb(a.g),new ilc(a))} +function qYc(a,b){var c,d,e,f,g,h,i;b.Ug('Process directions',1);c=RD(mQb(a,(h_c(),H$c)),88);if(c!=(Cmd(),xmd)){for(e=Sub(a.b,0);e.b!=e.d.c;){d=RD(evb(e),40);h=RD(mQb(d,(q$c(),o$c)),17).a;i=RD(mQb(d,p$c),17).a;switch(c.g){case 4:i*=-1;break;case 1:f=h;h=i;i=f;break;case 2:g=h;h=-i;i=g;}pQb(d,o$c,sgb(h));pQb(d,p$c,sgb(i))}}b.Vg()} +function led(a,b){var c;c=new qQb;!!b&&kQb(c,RD(Wjb(a.a,H4),96));ZD(b,422)&&kQb(c,RD(Wjb(a.a,L4),96));if(ZD(b,366)){kQb(c,RD(Wjb(a.a,I4),96));return c}ZD(b,84)&&kQb(c,RD(Wjb(a.a,E4),96));if(ZD(b,207)){kQb(c,RD(Wjb(a.a,J4),96));return c}if(ZD(b,193)){kQb(c,RD(Wjb(a.a,K4),96));return c}ZD(b,326)&&kQb(c,RD(Wjb(a.a,G4),96));return c} +function a_b(a){var b,c,d,e,f,g,h,i;i=new m_b;for(h=new Anb(a.a);h.a0&&b=0){return false}else{b.p=c.b;Rmb(c.e,b)}if(e==(r3b(),o3b)||e==q3b){for(g=new Anb(b.j);g.aa.d[h.p]){c+=ZLc(a.b,f);hmb(a.a,sgb(f))}}else{++g}}c+=a.b.d*g;while(!nmb(a.a)){XLc(a.b,RD(smb(a.a),17).a)}}return c} +function pje(a){var b,c,d,e,f,g;f=0;b=WVd(a);!!b.kk()&&(f|=4);(a.Bb&bKe)!=0&&(f|=2);if(ZD(a,102)){c=RD(a,19);e=Z5d(c);(c.Bb&QHe)!=0&&(f|=32);if(e){AYd(uWd(e));f|=8;g=e.t;(g>1||g==-1)&&(f|=16);(e.Bb&QHe)!=0&&(f|=64)}(c.Bb&txe)!=0&&(f|=cKe);f|=gwe}else{if(ZD(b,469)){f|=512}else{d=b.kk();!!d&&(d.i&1)!=0&&(f|=256)}}(a.Bb&512)!=0&&(f|=128);return f} +function vke(a,b){var c;if(a.f==tke){c=yfe(Qee((lke(),jke),b));return a.e?c==4&&b!=(Lle(),Jle)&&b!=(Lle(),Gle)&&b!=(Lle(),Hle)&&b!=(Lle(),Ile):c==2}if(!!a.d&&(a.d.Hc(b)||a.d.Hc(zfe(Qee((lke(),jke),b)))||a.d.Hc(Eee((lke(),jke),a.b,b)))){return true}if(a.f){if(Xee((lke(),a.f),Bfe(Qee(jke,b)))){c=yfe(Qee(jke,b));return a.e?c==4:c==2}}return false} +function oKc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n;m=-1;n=0;for(j=a,k=0,l=j.length;k0&&++n}}}++m}return n} +function S2c(a,b,c,d){var e,f,g,h,i,j,k,l;g=RD(Gxd(c,(umd(),Qld)),8);i=g.a;k=g.b+a;e=$wnd.Math.atan2(k,i);e<0&&(e+=dFe);e+=b;e>dFe&&(e-=dFe);h=RD(Gxd(d,Qld),8);j=h.a;l=h.b+a;f=$wnd.Math.atan2(l,j);f<0&&(f+=dFe);f+=b;f>dFe&&(f-=dFe);return Zy(),bz(1.0E-10),$wnd.Math.abs(e-f)<=1.0E-10||e==f||isNaN(e)&&isNaN(f)?0:ef?1:cz(isNaN(e),isNaN(f))} +function PGb(a){var b,c,d,e,f,g,h;h=new Tsb;for(d=new Anb(a.a.b);d.a=b.o){throw Adb(new web)}i=c>>5;h=c&31;g=Sdb(1,Ydb(Sdb(h,1)));f?(b.n[d][i]=Rdb(b.n[d][i],g)):(b.n[d][i]=Cdb(b.n[d][i],Qdb(g)));g=Sdb(g,1);e?(b.n[d][i]=Rdb(b.n[d][i],g)):(b.n[d][i]=Cdb(b.n[d][i],Qdb(g)))}catch(a){a=zdb(a);if(ZD(a,333)){throw Adb(new veb(fze+b.o+'*'+b.p+gze+c+pve+d+hze))}else throw Adb(a)}} +function eMc(a,b,c,d){var e,f,g,h,i,j,k,l,m;m=new yAb(new PMc(a));for(h=cD(WC(jR,1),WAe,10,0,[b,c]),i=0,j=h.length;i0){d=(!a.n&&(a.n=new C5d(I4,a,1,7)),RD(QHd(a.n,0),135)).a;!d||Zhb(Zhb((b.a+=' "',b),d),'"')}}else{Zhb(Zhb((b.a+=' "',b),c),'"')}Zhb(Uhb(Zhb(Uhb(Zhb(Uhb(Zhb(Uhb((b.a+=' (',b),a.i),','),a.j),' | '),a.g),','),a.f),')');return b.a} +function OCd(a){var b,c,d;if((a.Db&64)!=0)return Fyd(a);b=new dib(HHe);c=a.k;if(!c){!a.n&&(a.n=new C5d(I4,a,1,7));if(a.n.i>0){d=(!a.n&&(a.n=new C5d(I4,a,1,7)),RD(QHd(a.n,0),135)).a;!d||Zhb(Zhb((b.a+=' "',b),d),'"')}}else{Zhb(Zhb((b.a+=' "',b),c),'"')}Zhb(Uhb(Zhb(Uhb(Zhb(Uhb(Zhb(Uhb((b.a+=' (',b),a.i),','),a.j),' | '),a.g),','),a.f),')');return b.a} +function Xnc(a,b){var c,d,e,f,g;b==(TEc(),QEc)&&Eob(RD(Qc(a.a,(Bnc(),xnc)),15));for(e=RD(Qc(a.a,(Bnc(),xnc)),15).Kc();e.Ob();){d=RD(e.Pb(),105);c=RD(Vmb(d.j,0),113).d.j;f=new dnb(d.j);_mb(f,new Boc);switch(b.g){case 2:Pnc(a,f,c,(joc(),hoc),1);break;case 1:case 0:g=Rnc(f);Pnc(a,new Rkb(f,0,g),c,(joc(),hoc),0);Pnc(a,new Rkb(f,g,f.c.length),c,hoc,1);}}} +function sgd(a,b){var c,d,e,f,g,h,i;if(b==null||b.length==0){return null}e=RD(Xjb(a.a,b),143);if(!e){for(d=(h=(new glb(a.b)).a.vc().Kc(),new llb(h));d.a.Ob();){c=(f=RD(d.a.Pb(),44),RD(f.md(),143));g=c.c;i=b.length;if(lhb(g.substr(g.length-i,i),b)&&(b.length==g.length||ihb(g,g.length-b.length-1)==46)){if(e){return null}e=c}}!!e&&$jb(a.a,b,e)}return e} +function HOb(a,b){var c,d,e,f;c=new MOb;d=RD(zDb(GDb(new SDb(null,new Swb(a.f,16)),c),sBb(new _Bb,new bCb,new yCb,new ACb,cD(WC(QL,1),jwe,108,0,[(xBb(),wBb),vBb]))),21);e=d.gc();d=RD(zDb(GDb(new SDb(null,new Swb(b.f,16)),c),sBb(new _Bb,new bCb,new yCb,new ACb,cD(WC(QL,1),jwe,108,0,[wBb,vBb]))),21);f=d.gc();if(ee.p){Q3b(f,npd);if(f.d){h=f.o.b;b=f.a.b;f.a.b=h-b}}else if(f.j==npd&&e.p>a.p){Q3b(f,Yod);if(f.d){h=f.o.b;b=f.a.b;f.a.b=-(h-b)}}break}}return e} +function nTb(a,b,c,d,e){var f,g,h,i,j,k,l;if(!(ZD(b,207)||ZD(b,366)||ZD(b,193))){throw Adb(new agb('Method only works for ElkNode-, ElkLabel and ElkPort-objects.'))}g=a.a/2;i=b.i+d-g;k=b.j+e-g;j=i+b.g+a.a;l=k+b.f+a.a;f=new Ejd;Mub(f,new rjd(i,k));Mub(f,new rjd(i,l));Mub(f,new rjd(j,l));Mub(f,new rjd(j,k));h=new ORb(f);kQb(h,b);c&&Zjb(a.b,b,h);return h} +function w$b(a,b,c){var d,e,f,g,h,i,j,k,l,m;f=new rjd(b,c);for(k=new Anb(a.a);k.a1;if(h){d=new rjd(e,c.b);Mub(b.a,d)}zjd(b.a,cD(WC(l3,1),Nve,8,0,[m,l]))} +function aEc(){aEc=geb;$Dc=new bEc(LAe,0);VDc=new bEc('NIKOLOV',1);YDc=new bEc('NIKOLOV_PIXEL',2);WDc=new bEc('NIKOLOV_IMPROVED',3);XDc=new bEc('NIKOLOV_IMPROVED_PIXEL',4);SDc=new bEc('DUMMYNODE_PERCENTAGE',5);ZDc=new bEc('NODECOUNT_PERCENTAGE',6);_Dc=new bEc('NO_BOUNDARY',7);TDc=new bEc('MODEL_ORDER_LEFT_TO_RIGHT',8);UDc=new bEc('MODEL_ORDER_RIGHT_TO_LEFT',9)} +function use(a){var b,c,d,e,f;d=a.length;b=new Rhb;f=0;while(f=40;g&&wJb(a);nJb(a);mJb(a);c=qJb(a);d=0;while(!!c&&d0&&Mub(a.f,f)}else{a.c[g]-=j+1;a.c[g]<=0&&a.a[g]>0&&Mub(a.e,f)}}}}} +function FVc(a,b,c,d){var e,f,g,h,i,j,k;i=new rjd(c,d);ojd(i,RD(mQb(b,(q$c(),SZc)),8));for(k=Sub(b.b,0);k.b!=k.d.c;){j=RD(evb(k),40);$id(j.e,i);Mub(a.b,j)}for(h=RD(zDb(BDb(new SDb(null,new Swb(b.a,16))),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[(xBb(),vBb)]))),15).Kc();h.Ob();){g=RD(h.Pb(),65);for(f=Sub(g.a,0);f.b!=f.d.c;){e=RD(evb(f),8);e.a+=i.a;e.b+=i.b}Mub(a.a,g)}} +function kWc(a,b){var c,d,e,f;if(0<(ZD(a,16)?RD(a,16).gc():Kr(a.Kc()))){e=b;if(1=0&&if*2){k=new zrd(l);j=urd(g)/trd(g);i=ird(k,b,new z3b,c,d,e,j);$id(hjd(k.e),i);l.c.length=0;f=0;ZEb(l.c,k);ZEb(l.c,g);f=urd(k)*trd(k)+urd(g)*trd(g)}else{ZEb(l.c,g);f+=urd(g)*trd(g)}}return l} +function O9b(a,b){var c,d,e,f,g,h;h=RD(mQb(b,(yCc(),BBc)),101);if(!(h==(Bod(),xod)||h==wod)){return}e=(new rjd(b.f.a+b.d.b+b.d.c,b.f.b+b.d.d+b.d.a)).b;for(g=new Anb(a.a);g.ac?b:c;j<=l;++j){if(j==c){h=d++}else{f=e[j];k=o.am(f.Lk());j==b&&(i=j==l&&!k?d-1:d);k&&++d}}m=RD(uLd(a,b,c),76);h!=i&&eZd(a,new c4d(a.e,7,g,sgb(h),n.md(),i));return m}}}else{return RD(SHd(a,b,c),76)}return RD(uLd(a,b,c),76)} +function ugc(a,b){var c,d,e,f,g,h,i;b.Ug('Port order processing',1);i=RD(mQb(a,(yCc(),HBc)),430);for(d=new Anb(a.b);d.a=0){h=rD(a,g);if(h){j<22?(i.l|=1<>>1;g.m=k>>>1|(l&1)<<21;g.l=m>>>1|(k&1)<<21;--j}c&&nD(i);if(f){if(d){eD=xD(a);e&&(eD=DD(eD,(MD(),KD)))}else{eD=hD(a.l,a.m,a.h)}}return i} +function rIc(a,b){var c,d,e,f,g,h,i,j,k,l;j=a.e[b.c.p][b.p]+1;i=b.c.a.c.length+1;for(h=new Anb(a.a);h.a0&&(BFb(0,a.length),a.charCodeAt(0)==45||(BFb(0,a.length),a.charCodeAt(0)==43))?1:0;for(d=g;dc){throw Adb(new Vgb(nxe+a+'"'))}return h} +function Jqc(a){var b,c,d,e,f,g,h;g=new Yub;for(f=new Anb(a.a);f.a1)&&b==1&&RD(a.a[a.b],10).k==(r3b(),n3b)){Qdc(RD(a.a[a.b],10),(Pnd(),Lnd))}else if(d&&(!c||(a.c-a.b&a.a.length-1)>1)&&b==1&&RD(a.a[a.c-1&a.a.length-1],10).k==(r3b(),n3b)){Qdc(RD(a.a[a.c-1&a.a.length-1],10),(Pnd(),Mnd))}else if((a.c-a.b&a.a.length-1)==2){Qdc(RD(omb(a),10),(Pnd(),Lnd));Qdc(RD(omb(a),10),Mnd)}else{Ndc(a,e)}jmb(a)} +function QVc(a,b,c){var d,e,f,g,h;f=0;for(e=new dMd((!a.a&&(a.a=new C5d(J4,a,10,11)),a.a));e.e!=e.i.gc();){d=RD(bMd(e),27);g='';(!d.n&&(d.n=new C5d(I4,d,1,7)),d.n).i==0||(g=RD(QHd((!d.n&&(d.n=new C5d(I4,d,1,7)),d.n),0),135).a);h=new bXc(f++,b,g);kQb(h,d);pQb(h,(q$c(),h$c),d);h.e.b=d.j+d.f/2;h.f.a=$wnd.Math.max(d.g,1);h.e.a=d.i+d.g/2;h.f.b=$wnd.Math.max(d.f,1);Mub(b.b,h);rtb(c.f,d,h)}} +function L5b(a){var b,c,d,e,f;d=RD(mQb(a,(Ywc(),Awc)),27);f=RD(Gxd(d,(yCc(),lBc)),181).Hc((Qpd(),Ppd));if(!a.e){e=RD(mQb(a,kwc),21);b=new rjd(a.f.a+a.d.b+a.d.c,a.f.b+a.d.d+a.d.a);if(e.Hc((ovc(),hvc))){Ixd(d,BBc,(Bod(),wod));Esd(d,b.a,b.b,false,true)}else{Heb(TD(Gxd(d,mBc)))||Esd(d,b.a,b.b,true,true)}}f?Ixd(d,lBc,xsb(Ppd)):Ixd(d,lBc,(c=RD(mfb(H3),9),new Fsb(c,RD(WEb(c,c.length),9),0)))} +function JA(a,b,c){var d,e,f,g;if(b[0]>=a.length){c.o=0;return true}switch(ihb(a,b[0])){case 43:e=1;break;case 45:e=-1;break;default:c.o=0;return true;}++b[0];f=b[0];g=HA(a,b);if(g==0&&b[0]==f){return false}if(b[0]h){h=e;k.c.length=0}e==h&&Rmb(k,new Ptd(c.c.i,c))}yob();_mb(k,a.c);Qmb(a.b,i.p,k)}}} +function kRc(a,b){var c,d,e,f,g,h,i,j,k;for(g=new Anb(b.b);g.ah){h=e;k.c.length=0}e==h&&Rmb(k,new Ptd(c.d.i,c))}yob();_mb(k,a.c);Qmb(a.f,i.p,k)}}} +function HVc(a,b){var c,d,e,f,g,h,i,j;j=TD(mQb(b,(h_c(),Z$c)));if(j==null||(uFb(j),j)){EVc(a,b);e=new bnb;for(i=Sub(b.b,0);i.b!=i.d.c;){g=RD(evb(i),40);c=DVc(a,g,null);if(c){kQb(c,b);ZEb(e.c,c)}}a.a=null;a.b=null;if(e.c.length>1){for(d=new Anb(e);d.a=0&&h!=c){f=new N3d(a,1,h,g,null);!d?(d=f):d.nj(f)}if(c>=0){f=new N3d(a,1,c,h==c?g:null,b);!d?(d=f):d.nj(f)}}return d} +function jSd(a){var b,c,d;if(a.b==null){d=new Qhb;if(a.i!=null){Nhb(d,a.i);d.a+=':'}if((a.f&256)!=0){if((a.f&256)!=0&&a.a!=null){wSd(a.i)||(d.a+='//',d);Nhb(d,a.a)}if(a.d!=null){d.a+='/';Nhb(d,a.d)}(a.f&16)!=0&&(d.a+='/',d);for(b=0,c=a.j.length;bm){return false}l=(i=S9c(d,m,false),i.a);if(k+h+l<=b.b){Q9c(c,f-c.s);c.c=true;Q9c(d,f-c.s);U9c(d,c.s,c.t+c.d+h);d.k=true;aad(c.q,d);n=true;if(e){Cad(b,d);d.j=b;if(a.c.length>g){Fad((tFb(g,a.c.length),RD(a.c[g],186)),d);(tFb(g,a.c.length),RD(a.c[g],186)).a.c.length==0&&Xmb(a,g)}}}return n} +function Qfc(a,b){var c,d,e,f,g,h;b.Ug('Partition midprocessing',1);e=new Tp;FDb(CDb(new SDb(null,new Swb(a.a,16)),new Ufc),new Wfc(e));if(e.d==0){return}h=RD(zDb(ODb((f=e.i,new SDb(null,(!f?(e.i=new zf(e,e.c)):f).Nc()))),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[(xBb(),vBb)]))),15);d=h.Kc();c=RD(d.Pb(),17);while(d.Ob()){g=RD(d.Pb(),17);Pfc(RD(Qc(e,c),21),RD(Qc(e,g),21));c=g}b.Vg()} +function G_b(a,b,c){var d,e,f,g,h,i,j,k;if(b.p==0){b.p=1;g=c;if(!g){e=new bnb;f=(d=RD(mfb(E3),9),new Fsb(d,RD(WEb(d,d.length),9),0));g=new Ptd(e,f)}RD(g.a,15).Fc(b);b.k==(r3b(),m3b)&&RD(g.b,21).Fc(RD(mQb(b,(Ywc(),hwc)),64));for(i=new Anb(b.j);i.a0){e=RD(a.Ab.g,2033);if(b==null){for(f=0;fc.s&&hg){return qpd(),Xod}break;case 4:case 3:if(k<0){return qpd(),Yod}else if(k+c>f){return qpd(),npd}}i=(j+h/2)/g;d=(k+c/2)/f;return i+d<=1&&i-d<=0?(qpd(),ppd):i+d>=1&&i-d>=0?(qpd(),Xod):d<0.5?(qpd(),Yod):(qpd(),npd)} +function PNc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;c=false;k=Kfb(UD(mQb(b,(yCc(),bCc))));o=pwe*k;for(e=new Anb(b.b);e.ai+o){p=l.g+m.g;m.a=(m.g*m.a+l.g*l.a)/p;m.g=p;l.f=m;c=true}}f=h;l=m}}return c} +function MJb(a,b,c,d,e,f,g){var h,i,j,k,l,m;m=new Tid;for(j=b.Kc();j.Ob();){h=RD(j.Pb(),853);for(l=new Anb(h.Rf());l.a0){if(h.a){j=h.b.Mf().b;if(e>j){if(a.v||h.c.d.c.length==1){g=(e-j)/2;h.d.d=g;h.d.a=g}else{c=RD(Vmb(h.c.d,0),187).Mf().b;d=(c-j)/2;h.d.d=$wnd.Math.max(0,d);h.d.a=e-d-j}}}else{h.d.a=a.t+e}}else if(Rod(a.u)){f=wsd(h.b);f.d<0&&(h.d.d=-f.d);f.d+f.a>h.b.Mf().b&&(h.d.a=f.d+f.a-h.b.Mf().b)}}} +function yVb(){yVb=geb;lVb=new mGd((umd(),Rld),sgb(1));rVb=new mGd(fmd,80);qVb=new mGd($ld,5);ZUb=new mGd(Dkd,Yze);mVb=new mGd(Sld,sgb(1));pVb=new mGd(Vld,(Geb(),true));iVb=new A3b(50);hVb=new mGd(tld,iVb);_Ub=ald;jVb=Hld;$Ub=new mGd(Pkd,false);gVb=sld;eVb=mld;fVb=pld;dVb=kld;cVb=ild;kVb=Lld;bVb=(OUb(),HUb);sVb=MUb;aVb=GUb;nVb=JUb;oVb=LUb;vVb=mmd;xVb=qmd;uVb=lmd;tVb=kmd;wVb=(mqd(),jqd);new mGd(nmd,wVb)} +function VC(a,b){var c;switch(XC(a)){case 6:return bE(b);case 7:return _D(b);case 8:return $D(b);case 3:return Array.isArray(b)&&(c=XC(b),!(c>=14&&c<=16));case 11:return b!=null&&typeof b===kve;case 12:return b!=null&&(typeof b===gve||typeof b==kve);case 0:return QD(b,a.__elementTypeId$);case 2:return cE(b)&&!(b.Tm===keb);case 1:return cE(b)&&!(b.Tm===keb)||QD(b,a.__elementTypeId$);default:return true;}} +function oRb(a,b){var c,d,e,f;d=$wnd.Math.min($wnd.Math.abs(a.c-(b.c+b.b)),$wnd.Math.abs(a.c+a.b-b.c));f=$wnd.Math.min($wnd.Math.abs(a.d-(b.d+b.a)),$wnd.Math.abs(a.d+a.a-b.d));c=$wnd.Math.abs(a.c+a.b/2-(b.c+b.b/2));if(c>a.b/2+b.b/2){return 1}e=$wnd.Math.abs(a.d+a.a/2-(b.d+b.a/2));if(e>a.a/2+b.a/2){return 1}if(c==0&&e==0){return 0}if(c==0){return f/e+1}if(e==0){return d/c+1}return $wnd.Math.min(d/c,f/e)+1} +function oWb(a,b){var c,d,e,f,g,h,i;f=0;h=0;i=0;for(e=new Anb(a.f.e);e.a0&&a.d!=(AWb(),zWb)&&(h+=g*(d.d.a+a.a[b.a][d.a]*(b.d.a-d.d.a)/c));c>0&&a.d!=(AWb(),xWb)&&(i+=g*(d.d.b+a.a[b.a][d.a]*(b.d.b-d.d.b)/c))}switch(a.d.g){case 1:return new rjd(h/f,b.d.b);case 2:return new rjd(b.d.a,i/f);default:return new rjd(h/f,i/f);}} +function xsd(a){var b,c,d,e,f,g;c=(!a.a&&(a.a=new XZd(D4,a,5)),a.a).i+2;g=new cnb(c);Rmb(g,new rjd(a.j,a.k));FDb(new SDb(null,(!a.a&&(a.a=new XZd(D4,a,5)),new Swb(a.a,16))),new Usd(g));Rmb(g,new rjd(a.b,a.c));b=1;while(b0){aHb(i,false,(Cmd(),ymd));aHb(i,true,zmd)}Umb(b.g,new Elc(a,c));Zjb(a.g,b,c)} +function Ugb(){Ugb=geb;var a;Qgb=cD(WC(kE,1),Pwe,28,15,[-1,-1,30,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5]);Rgb=$C(kE,Pwe,28,37,15,1);Sgb=cD(WC(kE,1),Pwe,28,15,[-1,-1,63,40,32,28,25,23,21,20,19,19,18,18,17,17,16,16,16,15,15,15,15,14,14,14,14,14,14,13,13,13,13,13,13,13,13]);Tgb=$C(lE,rxe,28,37,14,1);for(a=2;a<=36;a++){Rgb[a]=eE($wnd.Math.pow(a,Qgb[a]));Tgb[a]=Fdb(Sve,Rgb[a])}} +function tsd(a){var b;if((!a.a&&(a.a=new C5d(F4,a,6,6)),a.a).i!=1){throw Adb(new agb(tHe+(!a.a&&(a.a=new C5d(F4,a,6,6)),a.a).i))}b=new Ejd;!!BGd(RD(QHd((!a.b&&(a.b=new Yie(E4,a,4,7)),a.b),0),84))&&ye(b,usd(a,BGd(RD(QHd((!a.b&&(a.b=new Yie(E4,a,4,7)),a.b),0),84)),false));!!BGd(RD(QHd((!a.c&&(a.c=new Yie(E4,a,5,8)),a.c),0),84))&&ye(b,usd(a,BGd(RD(QHd((!a.c&&(a.c=new Yie(E4,a,5,8)),a.c),0),84)),true));return b} +function zRc(a,b){var c,d,e,f,g;b.d?(e=a.a.c==(wQc(),vQc)?Z2b(b.b):a3b(b.b)):(e=a.a.c==(wQc(),uQc)?Z2b(b.b):a3b(b.b));f=false;for(d=new is(Mr(e.a.Kc(),new ir));gs(d);){c=RD(hs(d),18);g=Heb(a.a.f[a.a.g[b.b.p].p]);if(!g&&!W0b(c)&&c.c.i.c==c.d.i.c){continue}if(Heb(a.a.n[a.a.g[b.b.p].p])||Heb(a.a.n[a.a.g[b.b.p].p])){continue}f=true;if(Zsb(a.b,a.a.g[rRc(c,b.b).p])){b.c=true;b.a=c;return b}}b.c=f;b.a=null;return b} +function QJd(a,b,c){var d,e,f,g,h,i,j;d=c.gc();if(d==0){return false}else{if(a.Pj()){i=a.Qj();ZId(a,b,c);g=d==1?a.Ij(3,null,c.Kc().Pb(),b,i):a.Ij(5,null,c,b,i);if(a.Mj()){h=d<100?null:new gLd(d);f=b+d;for(e=b;e0){for(g=0;g>16==-15&&a.Cb.Yh()&&pKd(new O3d(a.Cb,9,13,c,a.c,fZd(o4d(RD(a.Cb,62)),a)))}else if(ZD(a.Cb,90)){if(a.Db>>16==-23&&a.Cb.Yh()){b=a.c;ZD(b,90)||(b=(JTd(),zTd));ZD(c,90)||(c=(JTd(),zTd));pKd(new O3d(a.Cb,9,10,c,b,fZd(tYd(RD(a.Cb,29)),a)))}}}}return a.c} +function lac(a,b,c){var d,e,f,g,h,i,j,k,l;c.Ug('Hyperedge merging',1);jac(a,b);i=new Jkb(b.b,0);while(i.b0;h=oIb(b,f);c?FIb(h.b,b):FIb(h.g,b);CIb(h).c.length==1&&(Pub(d,h,d.c.b,d.c),true);e=new Ptd(f,b);hmb(a.o,e);Ymb(a.e.a,f)}} +function SQb(a,b){var c,d,e,f,g,h,i;d=$wnd.Math.abs(Oid(a.b).a-Oid(b.b).a);h=$wnd.Math.abs(Oid(a.b).b-Oid(b.b).b);e=0;i=0;c=1;g=1;if(d>a.b.b/2+b.b.b/2){e=$wnd.Math.min($wnd.Math.abs(a.b.c-(b.b.c+b.b.b)),$wnd.Math.abs(a.b.c+a.b.b-b.b.c));c=1-e/d}if(h>a.b.a/2+b.b.a/2){i=$wnd.Math.min($wnd.Math.abs(a.b.d-(b.b.d+b.b.a)),$wnd.Math.abs(a.b.d+a.b.a-b.b.d));g=1-i/h}f=$wnd.Math.min(c,g);return (1-f)*$wnd.Math.sqrt(d*d+h*h)} +function LUc(a){var b,c,d,e;NUc(a,a.e,a.f,(dVc(),bVc),true,a.c,a.i);NUc(a,a.e,a.f,bVc,false,a.c,a.i);NUc(a,a.e,a.f,cVc,true,a.c,a.i);NUc(a,a.e,a.f,cVc,false,a.c,a.i);MUc(a,a.c,a.e,a.f,a.i);d=new Jkb(a.i,0);while(d.b=65;c--){xqe[c]=c-65<<24>>24}for(d=122;d>=97;d--){xqe[d]=d-97+26<<24>>24}for(e=57;e>=48;e--){xqe[e]=e-48+52<<24>>24}xqe[43]=62;xqe[47]=63;for(f=0;f<=25;f++)yqe[f]=65+f&Bwe;for(g=26,i=0;g<=51;++g,i++)yqe[g]=97+i&Bwe;for(a=52,h=0;a<=61;++a,h++)yqe[a]=48+h&Bwe;yqe[62]=43;yqe[63]=47} +function uib(a,b){var c,d,e,f,g,h;e=xib(a);h=xib(b);if(e==h){if(a.e==b.e&&a.a<54&&b.a<54){return a.fb.f?1:0}d=a.e-b.e;c=(a.d>0?a.d:$wnd.Math.floor((a.a-1)*xxe)+1)-(b.d>0?b.d:$wnd.Math.floor((b.a-1)*xxe)+1);if(c>d+1){return e}else if(c0&&(g=Wib(g,Sjb(d)));return Qib(f,g)}}else return ej){m=0;n+=i+b;i=0}w$b(g,m,n);c=$wnd.Math.max(c,m+k.a);i=$wnd.Math.max(i,k.b);m+=k.a+b}return new rjd(c+b,n+i+b)} +function osd(a,b){var c,d,e,f,g,h,i;if(!MCd(a)){throw Adb(new dgb(sHe))}d=MCd(a);f=d.g;e=d.f;if(f<=0&&e<=0){return qpd(),opd}h=a.i;i=a.j;switch(b.g){case 2:case 1:if(h<0){return qpd(),ppd}else if(h+a.g>f){return qpd(),Xod}break;case 4:case 3:if(i<0){return qpd(),Yod}else if(i+a.f>e){return qpd(),npd}}g=(h+a.g/2)/f;c=(i+a.f/2)/e;return g+c<=1&&g-c<=0?(qpd(),ppd):g+c>=1&&g-c>=0?(qpd(),Xod):c<0.5?(qpd(),Yod):(qpd(),npd)} +function Djb(a,b,c,d,e){var f,g;f=Bdb(Cdb(b[0],yxe),Cdb(d[0],yxe));a[0]=Ydb(f);f=Tdb(f,32);if(c>=e){for(g=1;g0){e.b[g++]=0;e.b[g++]=f.b[0]-1}for(b=1;b0){PSc(i,i.d-e.d);e.c==(fTc(),dTc)&&NSc(i,i.a-e.d);i.d<=0&&i.i>0&&(Pub(b,i,b.c.b,b.c),true)}}}for(f=new Anb(a.f);f.a0){QSc(h,h.i-e.d);e.c==(fTc(),dTc)&&OSc(h,h.b-e.d);h.i<=0&&h.d>0&&(Pub(c,h,c.c.b,c.c),true)}}}} +function drd(a,b,c,d,e){var f,g,h,i,j,k,l,m,n;yob();_mb(a,new Mrd);g=gv(a);n=new bnb;m=new bnb;h=null;i=0;while(g.b!=0){f=RD(g.b==0?null:(sFb(g.b!=0),Wub(g,g.a.a)),163);if(!h||urd(h)*trd(h)/21&&(i>urd(h)*trd(h)/2||g.b==0)){l=new zrd(m);k=urd(h)/trd(h);j=ird(l,b,new z3b,c,d,e,k);$id(hjd(l.e),j);h=l;ZEb(n.c,l);i=0;m.c.length=0}}}Tmb(n,m);return n} +function hib(a,b,c,d,e){gib();var f,g,h,i,j,k,l;vFb(a,'src');vFb(c,'dest');l=rb(a);i=rb(c);qFb((l.i&4)!=0,'srcType is not an array');qFb((i.i&4)!=0,'destType is not an array');k=l.c;g=i.c;qFb((k.i&1)!=0?k==g:(g.i&1)==0,"Array types don't match");iib(a,b,c,d,e);if((k.i&1)==0&&l!=i){j=SD(a);f=SD(c);if(dE(a)===dE(c)&&bd;){bD(f,h,j[--b])}}else{for(h=d+e;d0);d.a.Xb(d.c=--d.b);l>m+i&&Ckb(d)}for(g=new Anb(n);g.a0);d.a.Xb(d.c=--d.b)}}}} +function gte(){Vse();var a,b,c,d,e,f;if(Fse)return Fse;a=(++Use,new xte(4));ute(a,hte(WLe,true));wte(a,hte('M',true));wte(a,hte('C',true));f=(++Use,new xte(4));for(d=0;d<11;d++){rte(f,d,d)}b=(++Use,new xte(4));ute(b,hte('M',true));rte(b,4448,4607);rte(b,65438,65439);e=(++Use,new iue(2));hue(e,a);hue(e,Ese);c=(++Use,new iue(2));c.Jm($se(f,hte('L',true)));c.Jm(b);c=(++Use,new Kte(3,c));c=(++Use,new Qte(e,c));Fse=c;return Fse} +function vhb(a,b){var c,d,e,f,g,h,i,j;c=new RegExp(b,'g');i=$C(qJ,Nve,2,0,6,1);d=0;j=a;f=null;while(true){h=c.exec(j);if(h==null||j==''){i[d]=j;break}else{g=h.index;i[d]=(AFb(0,g,j.length),j.substr(0,g));j=zhb(j,g+h[0].length,j.length);c.lastIndex=0;if(f==j){i[d]=(AFb(0,1,j.length),j.substr(0,1));j=(BFb(1,j.length+1),j.substr(1))}f=j;++d}}if(a.length>0){e=i.length;while(e>0&&i[e-1]==''){--e}e0){l-=d[0]+a.c;d[0]+=a.c}d[2]>0&&(l-=d[2]+a.c);d[1]=$wnd.Math.max(d[1],l);dKb(a.a[1],c.c+b.b+d[0]-(d[1]-l)/2,d[1])}for(f=a.a,h=0,j=f.length;h0?(a.n.c.length-1)*a.i:0;for(d=new Anb(a.n);d.a1){for(d=Sub(e,0);d.b!=d.d.c;){c=RD(evb(d),235);f=0;for(i=new Anb(c.e);i.a0){b[0]+=a.c;l-=b[0]}b[2]>0&&(l-=b[2]+a.c);b[1]=$wnd.Math.max(b[1],l);eKb(a.a[1],d.d+c.d+b[0]-(b[1]-l)/2,b[1])}else{o=d.d+c.d;n=d.a-c.d-c.a;for(g=a.a,i=0,k=g.length;i0||$y(e.b.d,a.b.d+a.b.a)==0&&d.b<0||$y(e.b.d+e.b.a,a.b.d)==0&&d.b>0){h=0;break}}else{h=$wnd.Math.min(h,PQb(a,e,d))}h=$wnd.Math.min(h,FQb(a,f,h,d))}return h} +function lsd(a,b){var c,d,e,f,g,h,i;if(a.b<2){throw Adb(new agb('The vector chain must contain at least a source and a target point.'))}e=(sFb(a.b!=0),RD(a.a.a.c,8));Nzd(b,e.a,e.b);i=new mMd((!b.a&&(b.a=new XZd(D4,b,5)),b.a));g=Sub(a,1);while(g.a=0&&f!=c){throw Adb(new agb(LIe))}}e=0;for(i=0;iKfb(pJc(g.g,g.d[0]).a)){sFb(i.b>0);i.a.Xb(i.c=--i.b);Ikb(i,g);e=true}else if(!!h.e&&h.e.gc()>0){f=(!h.e&&(h.e=new bnb),h.e).Mc(b);j=(!h.e&&(h.e=new bnb),h.e).Mc(c);if(f||j){(!h.e&&(h.e=new bnb),h.e).Fc(g);++g.c}}}e||(ZEb(d.c,g),true)} +function H3c(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;l=a.a.i+a.a.g/2;m=a.a.i+a.a.g/2;o=b.i+b.g/2;q=b.j+b.f/2;h=new rjd(o,q);j=RD(Gxd(b,(umd(),Qld)),8);j.a=j.a+l;j.b=j.b+m;f=(h.b-j.b)/(h.a-j.a);d=h.b-f*h.a;p=c.i+c.g/2;r=c.j+c.f/2;i=new rjd(p,r);k=RD(Gxd(c,Qld),8);k.a=k.a+l;k.b=k.b+m;g=(i.b-k.b)/(i.a-k.a);e=i.b-g*i.a;n=(d-e)/(g-f);if(j.a>>0,'0'+b.toString(16));d='\\x'+zhb(c,c.length-2,c.length)}else if(a>=txe){c=(b=a>>>0,'0'+b.toString(16));d='\\v'+zhb(c,c.length-6,c.length)}else d=''+String.fromCharCode(a&Bwe);}return d} +function Ugc(a){var b,c,d;if(Dod(RD(mQb(a,(yCc(),BBc)),101))){for(c=new Anb(a.j);c.a=b.o&&c.f<=b.f||b.a*0.5<=c.f&&b.a*1.5>=c.f){g=RD(Vmb(b.n,b.n.c.length-1),209);if(g.e+g.d+c.g+e<=d&&(f=RD(Vmb(b.n,b.n.c.length-1),209),f.f-a.f+c.f<=a.b||a.a.c.length==1)){K9c(b,c);return true}else if(b.s+c.g<=d&&(b.t+b.d+c.f+e<=a.b||a.a.c.length==1)){Rmb(b.b,c);h=RD(Vmb(b.n,b.n.c.length-1),209);Rmb(b.n,new _9c(b.s,h.f+h.a+b.i,b.i));W9c(RD(Vmb(b.n,b.n.c.length-1),209),c);M9c(b,c);return true}}return false} +function xLd(a,b,c){var d,e,f,g;if(a.Pj()){e=null;f=a.Qj();d=a.Ij(1,g=UHd(a,b,c),c,b,f);if(a.Mj()&&!(a.Yi()&&g!=null?pb(g,c):dE(g)===dE(c))){g!=null&&(e=a.Oj(g,e));e=a.Nj(c,e);a.Tj()&&(e=a.Wj(g,c,e));if(!e){a.Jj(d)}else{e.nj(d);e.oj()}}else{a.Tj()&&(e=a.Wj(g,c,e));if(!e){a.Jj(d)}else{e.nj(d);e.oj()}}return g}else{g=UHd(a,b,c);if(a.Mj()&&!(a.Yi()&&g!=null?pb(g,c):dE(g)===dE(c))){e=null;g!=null&&(e=a.Oj(g,null));e=a.Nj(c,e);!!e&&e.oj()}return g}} +function Rsc(a,b){var c,d,e,f,g;b.Ug('Path-Like Graph Wrapping',1);if(a.b.c.length==0){b.Vg();return}e=new ysc(a);g=(e.i==null&&(e.i=tsc(e,new Asc)),Kfb(e.i)*e.f);c=g/(e.i==null&&(e.i=tsc(e,new Asc)),Kfb(e.i));if(e.b>c){b.Vg();return}switch(RD(mQb(a,(yCc(),rCc)),351).g){case 2:f=new Ksc;break;case 0:f=new zrc;break;default:f=new Nsc;}d=f.og(a,e);if(!f.pg()){switch(RD(mQb(a,xCc),352).g){case 2:d=Wsc(e,d);break;case 1:d=Usc(e,d);}}Qsc(a,e,d);b.Vg()} +function mB(a,b){var c,d,e,f,g,h,i,j;b%=24;if(a.q.getHours()!=b){d=new $wnd.Date(a.q.getTime());d.setDate(d.getDate()+1);h=a.q.getTimezoneOffset()-d.getTimezoneOffset();if(h>0){i=h/60|0;j=h%60;e=a.q.getDate();c=a.q.getHours();c+i>=24&&++e;f=new $wnd.Date(a.q.getFullYear(),a.q.getMonth(),e,b+i,a.q.getMinutes()+j,a.q.getSeconds(),a.q.getMilliseconds());a.q.setTime(f.getTime())}}g=a.q.getTime();a.q.setTime(g+3600000);a.q.getHours()!=b&&a.q.setTime(g)} +function kKc(a,b){var c,d,e,f;Nwb(a.d,a.e);a.c.a.$b();if(Kfb(UD(mQb(b.j,(yCc(),Zzc))))!=0||Kfb(UD(mQb(b.j,Zzc)))!=0){c=Hze;dE(mQb(b.j,cAc))!==dE((kEc(),hEc))&&pQb(b.j,(Ywc(),jwc),(Geb(),true));f=RD(mQb(b.j,gCc),17).a;for(e=0;ee&&++j;Rmb(g,(tFb(h+j,b.c.length),RD(b.c[h+j],17)));i+=(tFb(h+j,b.c.length),RD(b.c[h+j],17)).a-d;++c;while(c=q&&a.e[i.p]>o*a.b||t>=c*q){ZEb(m.c,h);h=new bnb;ye(g,f);f.a.$b();j-=k;n=$wnd.Math.max(n,j*a.b+p);j+=t;s=t;t=0;k=0;p=0}}return new Ptd(n,m)} +function pYd(a){var b,c,d,e,f,g,h;if(!a.d){h=new v_d;b=iYd;f=b.a.zc(a,b);if(f==null){for(d=new dMd(zYd(a));d.e!=d.i.gc();){c=RD(bMd(d),29);YGd(h,pYd(c))}b.a.Bc(a)!=null;b.a.gc()==0&&undefined}g=h.i;for(e=(!a.q&&(a.q=new C5d(s7,a,11,10)),new dMd(a.q));e.e!=e.i.gc();++g){RD(bMd(e),411)}YGd(h,(!a.q&&(a.q=new C5d(s7,a,11,10)),a.q));VHd(h);a.d=new N$d((RD(QHd(xYd((lTd(),kTd).o),9),19),h.i),h.g);a.e=RD(h.g,688);a.e==null&&(a.e=jYd);yYd(a).b&=-17}return a.d} +function kge(a,b,c,d){var e,f,g,h,i,j;j=pke(a.e.Dh(),b);i=0;e=RD(a.g,124);nke();if(RD(b,69).xk()){for(g=0;g1||o==-1){l=RD(p,71);m=RD(k,71);if(l.dc()){m.$b()}else{g=!!Z5d(b);f=0;for(h=a.a?l.Kc():l.Ii();h.Ob();){j=RD(h.Pb(),58);e=RD(cub(a,j),58);if(!e){if(a.b&&!g){m.Gi(f,j);++f}}else{if(g){i=m.dd(e);i==-1?m.Gi(f,e):f!=i&&m.Ui(f,e)}else{m.Gi(f,e)}++f}}}}else{if(p==null){k.Wb(null)}else{e=cub(a,p);e==null?a.b&&!Z5d(b)&&k.Wb(p):k.Wb(e)}}}}} +function V9b(a,b){var c,d,e,f,g,h,i,j;c=new aac;for(e=new is(Mr(Z2b(b).a.Kc(),new ir));gs(e);){d=RD(hs(e),18);if(W0b(d)){continue}h=d.c.i;if(W9b(h,T9b)){j=X9b(a,h,T9b,S9b);if(j==-1){continue}c.b=$wnd.Math.max(c.b,j);!c.a&&(c.a=new bnb);Rmb(c.a,h)}}for(g=new is(Mr(a3b(b).a.Kc(),new ir));gs(g);){f=RD(hs(g),18);if(W0b(f)){continue}i=f.d.i;if(W9b(i,S9b)){j=X9b(a,i,S9b,T9b);if(j==-1){continue}c.d=$wnd.Math.max(c.d,j);!c.c&&(c.c=new bnb);Rmb(c.c,i)}}return c} +function pcc(a,b,c,d){var e,f,g,h,i,j,k;if(c.d.i==b.i){return}e=new j3b(a);h3b(e,(r3b(),o3b));pQb(e,(Ywc(),Awc),c);pQb(e,(yCc(),BBc),(Bod(),wod));ZEb(d.c,e);g=new R3b;P3b(g,e);Q3b(g,(qpd(),ppd));h=new R3b;P3b(h,e);Q3b(h,Xod);k=c.d;Z0b(c,g);f=new a1b;kQb(f,c);pQb(f,RAc,null);Y0b(f,h);Z0b(f,k);j=new Jkb(c.b,0);while(j.b1000000){throw Adb(new teb('power of ten too big'))}if(a<=lve){return Zib(Yib(Jjb[1],b),b)}d=Yib(Jjb[1],lve);e=d;c=Hdb(a-lve);b=eE(a%lve);while(Ddb(c,lve)>0){e=Wib(e,d);c=Vdb(c,lve)}e=Wib(e,Yib(Jjb[1],b));e=Zib(e,lve);c=Hdb(a-lve);while(Ddb(c,lve)>0){e=Zib(e,lve);c=Vdb(c,lve)}e=Zib(e,b);return e} +function s9b(a){var b,c,d,e,f,g,h,i,j,k;for(i=new Anb(a.a);i.aj&&d>j){k=h;j=Kfb(b.p[h.p])+Kfb(b.d[h.p])+h.o.b+h.d.a}else{e=false;c._g()&&c.bh('bk node placement breaks on '+h+' which should have been after '+k);break}}if(!e){break}}c._g()&&c.bh(b+' is feasible: '+e);return e} +function Dfc(a,b,c,d){var e,f,g,h,i,j,k,l,m;f=new j3b(a);h3b(f,(r3b(),q3b));pQb(f,(yCc(),BBc),(Bod(),wod));e=0;if(b){g=new R3b;pQb(g,(Ywc(),Awc),b);pQb(f,Awc,b.i);Q3b(g,(qpd(),ppd));P3b(g,f);m=s2b(b.e);for(j=m,k=0,l=j.length;k0){if(e<0&&k.a){e=i;f=j[0];d=0}if(e>=0){h=k.b;if(i==e){h-=d++;if(h==0){return 0}}if(!MA(b,j,k,h,g)){i=e-1;j[0]=f;continue}}else{e=-1;if(!MA(b,j,k,0,g)){return 0}}}else{e=-1;if(ihb(k.c,0)==32){l=j[0];KA(b,j);if(j[0]>l){continue}}else if(xhb(b,k.c,j[0])){j[0]+=k.c.length;continue}return 0}}if(!CB(g,c)){return 0}return j[0]} +function qWb(a,b,c){var d,e,f,g,h,i,j,k,l,m;k=new pwb(new GWb(c));h=$C(xdb,Hye,28,a.f.e.c.length,16,1);Snb(h,h.length);c[b.a]=0;for(j=new Anb(a.f.e);j.a=0&&!PPb(a,k,l)){--l}e[k]=l}for(n=0;n=0&&!PPb(a,h,o)){--h}f[o]=h}for(i=0;ib[m]&&md[i]&&TPb(a,i,m,false,true)}}} +function hUb(a){var b,c,d,e,f,g,h,i;c=Heb(TD(mQb(a,(yVb(),$Ub))));f=a.a.c.d;h=a.a.d.d;if(c){g=ijd(ojd(new rjd(h.a,h.b),f),0.5);i=ijd(ajd(a.e),0.5);b=ojd($id(new rjd(f.a,f.b),g),i);mjd(a.d,b)}else{e=Kfb(UD(mQb(a.a,qVb)));d=a.d;if(f.a>=h.a){if(f.b>=h.b){d.a=h.a+(f.a-h.a)/2+e;d.b=h.b+(f.b-h.b)/2-e-a.e.b}else{d.a=h.a+(f.a-h.a)/2+e;d.b=f.b+(h.b-f.b)/2+e}}else{if(f.b>=h.b){d.a=f.a+(h.a-f.a)/2+e;d.b=h.b+(f.b-h.b)/2+e}else{d.a=f.a+(h.a-f.a)/2+e;d.b=f.b+(h.b-f.b)/2-e-a.e.b}}}} +function qYd(a){var b,c,d,e,f,g,h,i;if(!a.f){i=new a_d;h=new a_d;b=iYd;g=b.a.zc(a,b);if(g==null){for(f=new dMd(zYd(a));f.e!=f.i.gc();){e=RD(bMd(f),29);YGd(i,qYd(e))}b.a.Bc(a)!=null;b.a.gc()==0&&undefined}for(d=(!a.s&&(a.s=new C5d(y7,a,21,17)),new dMd(a.s));d.e!=d.i.gc();){c=RD(bMd(d),179);ZD(c,102)&&WGd(h,RD(c,19))}VHd(h);a.r=new s_d(a,(RD(QHd(xYd((lTd(),kTd).o),6),19),h.i),h.g);YGd(i,a.r);VHd(i);a.f=new N$d((RD(QHd(xYd(kTd.o),5),19),i.i),i.g);yYd(a).b&=-3}return a.f} +function uSb(a){Cgd(a,new Pfd($fd(Xfd(Zfd(Yfd(new agd,Aze),'ELK DisCo'),'Layouter for arranging unconnected subgraphs. The subgraphs themselves are, by default, not laid out.'),new xSb)));Agd(a,Aze,Bze,iGd(sSb));Agd(a,Aze,Cze,iGd(mSb));Agd(a,Aze,Dze,iGd(hSb));Agd(a,Aze,Eze,iGd(nSb));Agd(a,Aze,Bye,iGd(qSb));Agd(a,Aze,Cye,iGd(pSb));Agd(a,Aze,Aye,iGd(rSb));Agd(a,Aze,Dye,iGd(oSb));Agd(a,Aze,vze,iGd(jSb));Agd(a,Aze,wze,iGd(iSb));Agd(a,Aze,xze,iGd(kSb));Agd(a,Aze,yze,iGd(lSb))} +function qAd(){qAd=geb;oAd=cD(WC(hE,1),zwe,28,15,[48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70]);pAd=new RegExp('[ \t\n\r\f]+');try{nAd=cD(WC(h8,1),rve,2114,0,[new c2d((WA(),YA("yyyy-MM-dd'T'HH:mm:ss'.'SSSZ",_A(($A(),$A(),ZA))))),new c2d(YA("yyyy-MM-dd'T'HH:mm:ss'.'SSS",_A((null,ZA)))),new c2d(YA("yyyy-MM-dd'T'HH:mm:ss",_A((null,ZA)))),new c2d(YA("yyyy-MM-dd'T'HH:mm",_A((null,ZA)))),new c2d(YA('yyyy-MM-dd',_A((null,ZA))))])}catch(a){a=zdb(a);if(!ZD(a,82))throw Adb(a)}} +function uKc(a,b){var c,d,e,f;e=Kwb(a.d,1)!=0;d=mKc(a,b);if(d==0&&Heb(TD(mQb(b.j,(Ywc(),jwc))))){return 0}!Heb(TD(mQb(b.j,(Ywc(),jwc))))&&!Heb(TD(mQb(b.j,Owc)))||dE(mQb(b.j,(yCc(),cAc)))===dE((kEc(),hEc))?b.c.mg(b.e,e):(e=Heb(TD(mQb(b.j,jwc))));DKc(a,b,e,true);Heb(TD(mQb(b.j,Owc)))&&pQb(b.j,Owc,(Geb(),false));if(Heb(TD(mQb(b.j,jwc)))){pQb(b.j,jwc,(Geb(),false));pQb(b.j,Owc,true)}c=mKc(a,b);do{yKc(a);if(c==0){return 0}e=!e;f=c;DKc(a,b,e,false);c=mKc(a,b)}while(f>c);return f} +function vKc(a,b){var c,d,e,f;e=Kwb(a.d,1)!=0;d=lKc(a,b);if(d==0&&Heb(TD(mQb(b.j,(Ywc(),jwc))))){return 0}!Heb(TD(mQb(b.j,(Ywc(),jwc))))&&!Heb(TD(mQb(b.j,Owc)))||dE(mQb(b.j,(yCc(),cAc)))===dE((kEc(),hEc))?b.c.mg(b.e,e):(e=Heb(TD(mQb(b.j,jwc))));DKc(a,b,e,true);Heb(TD(mQb(b.j,Owc)))&&pQb(b.j,Owc,(Geb(),false));if(Heb(TD(mQb(b.j,jwc)))){pQb(b.j,jwc,(Geb(),false));pQb(b.j,Owc,true)}c=lKc(a,b);do{yKc(a);if(c==0){return 0}e=!e;f=c;DKc(a,b,e,false);c=lKc(a,b)}while(f>c);return f} +function Gid(a,b,c,d){var e,f,g,h,i,j,k,l,m;i=ojd(new rjd(c.a,c.b),a);j=i.a*b.b-i.b*b.a;k=b.a*d.b-b.b*d.a;l=(i.a*d.b-i.b*d.a)/k;m=j/k;if(k==0){if(j==0){e=$id(new rjd(c.a,c.b),ijd(new rjd(d.a,d.b),0.5));f=bjd(a,e);g=bjd($id(new rjd(a.a,a.b),b),e);h=$wnd.Math.sqrt(d.a*d.a+d.b*d.b)*0.5;if(f=0&&l<=1&&m>=0&&m<=1?$id(new rjd(a.a,a.b),ijd(new rjd(b.a,b.b),l)):null}} +function QWb(a,b,c){var d,e,f,g,h;d=RD(mQb(a,(yCc(),dAc)),21);c.a>b.a&&(d.Hc((ukd(),okd))?(a.c.a+=(c.a-b.a)/2):d.Hc(qkd)&&(a.c.a+=c.a-b.a));c.b>b.b&&(d.Hc((ukd(),skd))?(a.c.b+=(c.b-b.b)/2):d.Hc(rkd)&&(a.c.b+=c.b-b.b));if(RD(mQb(a,(Ywc(),kwc)),21).Hc((ovc(),hvc))&&(c.a>b.a||c.b>b.b)){for(h=new Anb(a.a);h.ab.a&&(d.Hc((ukd(),okd))?(a.c.a+=(c.a-b.a)/2):d.Hc(qkd)&&(a.c.a+=c.a-b.a));c.b>b.b&&(d.Hc((ukd(),skd))?(a.c.b+=(c.b-b.b)/2):d.Hc(rkd)&&(a.c.b+=c.b-b.b));if(RD(mQb(a,(Ywc(),kwc)),21).Hc((ovc(),hvc))&&(c.a>b.a||c.b>b.b)){for(g=new Anb(a.a);g.a0?a.i:0)>b&&i>0){f=0;g+=i+a.i;e=$wnd.Math.max(e,m);d+=i+a.i;i=0;m=0;if(c){++l;Rmb(a.n,new _9c(a.s,g,a.i))}h=0}m+=j.g+(h>0?a.i:0);i=$wnd.Math.max(i,j.f);c&&W9c(RD(Vmb(a.n,l),209),j);f+=j.g+(h>0?a.i:0);++h}e=$wnd.Math.max(e,m);d+=i;if(c){a.r=e;a.d=d;Ead(a.j)}return new Uid(a.s,a.t,e,d)} +function CRb(a){var b,c,d,e,f,g,h,i,j,k,l,m;a.b=false;l=oxe;i=pxe;m=oxe;j=pxe;for(d=a.e.a.ec().Kc();d.Ob();){c=RD(d.Pb(),272);e=c.a;l=$wnd.Math.min(l,e.c);i=$wnd.Math.max(i,e.c+e.b);m=$wnd.Math.min(m,e.d);j=$wnd.Math.max(j,e.d+e.a);for(g=new Anb(c.c);g.aa.o.a){k=(i-a.o.a)/2;h.b=$wnd.Math.max(h.b,k);h.c=$wnd.Math.max(h.c,k)}} +function RId(a){var b,c,d,e,f,g,h,i;f=new med;ied(f,(hed(),eed));for(d=(e=oC(a,$C(qJ,Nve,2,0,6,1)),new Dkb(new mob((new CC(a,e)).b)));d.bh?1:-1:Ejb(a.a,b.a,f);if(e==-1){l=-i;k=g==i?Hjb(b.a,h,a.a,f):Cjb(b.a,h,a.a,f)}else{l=g;if(g==i){if(e==0){return Pib(),Oib}k=Hjb(a.a,f,b.a,h)}else{k=Cjb(a.a,f,b.a,h)}}j=new cjb(l,k.length,k);Rib(j);return j} +function c5b(a,b){var c,d,e,f;f=Z4b(b);!b.c&&(b.c=new C5d(K4,b,9,9));FDb(new SDb(null,(!b.c&&(b.c=new C5d(K4,b,9,9)),new Swb(b.c,16))),new s5b(f));e=RD(mQb(f,(Ywc(),kwc)),21);Y4b(b,e);if(e.Hc((ovc(),hvc))){for(d=new dMd((!b.c&&(b.c=new C5d(K4,b,9,9)),b.c));d.e!=d.i.gc();){c=RD(bMd(d),123);g5b(a,b,f,c)}}RD(Gxd(b,(yCc(),lBc)),181).gc()!=0&&V4b(b,f);Heb(TD(mQb(f,sBc)))&&e.Fc(mvc);nQb(f,PBc)&&HCc(new RCc(Kfb(UD(mQb(f,PBc)))),f);dE(Gxd(b,IAc))===dE((Fnd(),Cnd))?d5b(a,b,f):b5b(a,b,f);return f} +function Vrc(a){var b,c,d,e,f,g,h,i;for(e=new Anb(a.b);e.a0?zhb(c.a,0,f-1):''}}else{return !c?a:c.a}} +function xic(a,b){var c,d,e,f,g,h,i;b.Ug('Sort By Input Model '+mQb(a,(yCc(),cAc)),1);e=0;for(d=new Anb(a.b);d.a=a.b.length){f[e++]=g.b[d++];f[e++]=g.b[d++]}else if(d>=g.b.length){f[e++]=a.b[c++];f[e++]=a.b[c++]}else if(g.b[d]0?a.i:0)}++b}Ce(a.n,i);a.d=c;a.r=d;a.g=0;a.f=0;a.e=0;a.o=oxe;a.p=oxe;for(f=new Anb(a.b);f.a0){e=(!a.n&&(a.n=new C5d(I4,a,1,7)),RD(QHd(a.n,0),135)).a;!e||Zhb(Zhb((b.a+=' "',b),e),'"')}}else{Zhb(Zhb((b.a+=' "',b),d),'"')}c=(!a.b&&(a.b=new Yie(E4,a,4,7)),!(a.b.i<=1&&(!a.c&&(a.c=new Yie(E4,a,5,8)),a.c.i<=1)));c?(b.a+=' [',b):(b.a+=' ',b);Zhb(b,Eb(new Gb,new dMd(a.b)));c&&(b.a+=']',b);b.a+=SAe;c&&(b.a+='[',b);Zhb(b,Eb(new Gb,new dMd(a.c)));c&&(b.a+=']',b);return b.a} +function odc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D;v=a.c;w=b.c;c=Wmb(v.a,a,0);d=Wmb(w.a,b,0);t=RD(c3b(a,(BEc(),yEc)).Kc().Pb(),12);C=RD(c3b(a,zEc).Kc().Pb(),12);u=RD(c3b(b,yEc).Kc().Pb(),12);D=RD(c3b(b,zEc).Kc().Pb(),12);r=s2b(t.e);A=s2b(C.g);s=s2b(u.e);B=s2b(D.g);f3b(a,d,w);for(g=s,k=0,o=g.length;kk){new bTc((fTc(),eTc),c,b,j-k)}else if(j>0&&k>0){new bTc((fTc(),eTc),b,c,0);new bTc(eTc,c,b,0)}}return g} +function pXc(a,b,c){var d,e,f;a.a=new bnb;for(f=Sub(b.b,0);f.b!=f.d.c;){e=RD(evb(f),40);while(RD(mQb(e,(h_c(),f_c)),17).a>a.a.c.length-1){Rmb(a.a,new Ptd(Hze,KEe))}d=RD(mQb(e,f_c),17).a;if(c==(Cmd(),ymd)||c==zmd){e.e.aKfb(UD(RD(Vmb(a.a,d),42).b))&&Otd(RD(Vmb(a.a,d),42),e.e.a+e.f.a)}else{e.e.bKfb(UD(RD(Vmb(a.a,d),42).b))&&Otd(RD(Vmb(a.a,d),42),e.e.b+e.f.b)}}} +function g2b(a,b,c,d){var e,f,g,h,i,j,k;f=i2b(d);h=Heb(TD(mQb(d,(yCc(),aBc))));if((h||Heb(TD(mQb(a,MAc))))&&!Dod(RD(mQb(a,BBc),101))){e=vpd(f);i=q2b(a,c,c==(BEc(),zEc)?e:spd(e))}else{i=new R3b;P3b(i,a);if(b){k=i.n;k.a=b.a-a.n.a;k.b=b.b-a.n.b;_id(k,0,0,a.o.a,a.o.b);Q3b(i,c2b(i,f))}else{e=vpd(f);Q3b(i,c==(BEc(),zEc)?e:spd(e))}g=RD(mQb(d,(Ywc(),kwc)),21);j=i.j;switch(f.g){case 2:case 1:(j==(qpd(),Yod)||j==npd)&&g.Fc((ovc(),lvc));break;case 4:case 3:(j==(qpd(),Xod)||j==ppd)&&g.Fc((ovc(),lvc));}}return i} +function VXb(a,b){var c,d,e,f,g,h;for(g=new vkb((new mkb(a.f.b)).a);g.b;){f=tkb(g);e=RD(f.ld(),602);if(b==1){if(e.Af()!=(Cmd(),Bmd)&&e.Af()!=xmd){continue}}else{if(e.Af()!=(Cmd(),ymd)&&e.Af()!=zmd){continue}}d=RD(RD(f.md(),42).b,86);h=RD(RD(f.md(),42).a,194);c=h.c;switch(e.Af().g){case 2:d.g.c=a.e.a;d.g.b=$wnd.Math.max(1,d.g.b+c);break;case 1:d.g.c=d.g.c+c;d.g.b=$wnd.Math.max(1,d.g.b-c);break;case 4:d.g.d=a.e.b;d.g.a=$wnd.Math.max(1,d.g.a+c);break;case 3:d.g.d=d.g.d+c;d.g.a=$wnd.Math.max(1,d.g.a-c);}}} +function NNc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;h=$C(kE,Pwe,28,b.b.c.length,15,1);j=$C(hR,jwe,273,b.b.c.length,0,1);i=$C(jR,WAe,10,b.b.c.length,0,1);for(l=a.a,m=0,n=l.length;m0&&!!i[d]&&(o=bFc(a.b,i[d],e));p=$wnd.Math.max(p,e.c.c.b+o)}for(f=new Anb(k.e);f.a1){throw Adb(new agb(gLe))}if(!i){f=oke(b,d.Kc().Pb());g.Fc(f)}}return XGd(a,gge(a,b,c),g)} +function Fge(a,b,c){var d,e,f,g,h,i,j,k;if(qke(a.e,b)){i=(nke(),RD(b,69).xk()?new ole(b,a):new Eke(b,a));bge(i.c,i.b);Ake(i,RD(c,16))}else{k=pke(a.e.Dh(),b);d=RD(a.g,124);for(g=0;g'}i!=null&&(b.a+=''+i,b)}else if(a.e){h=a.e.zb;h!=null&&(b.a+=''+h,b)}else{b.a+='?';if(a.b){b.a+=' super ';r2d(a.b,b)}else{if(a.f){b.a+=' extends ';r2d(a.f,b)}}}} +function Uae(a){a.b=null;a.a=null;a.o=null;a.q=null;a.v=null;a.w=null;a.B=null;a.p=null;a.Q=null;a.R=null;a.S=null;a.T=null;a.U=null;a.V=null;a.W=null;a.bb=null;a.eb=null;a.ab=null;a.H=null;a.db=null;a.c=null;a.d=null;a.f=null;a.n=null;a.r=null;a.s=null;a.u=null;a.G=null;a.J=null;a.e=null;a.j=null;a.i=null;a.g=null;a.k=null;a.t=null;a.F=null;a.I=null;a.L=null;a.M=null;a.O=null;a.P=null;a.$=null;a.N=null;a.Z=null;a.cb=null;a.K=null;a.D=null;a.A=null;a.C=null;a._=null;a.fb=null;a.X=null;a.Y=null;a.gb=false;a.hb=false} +function yib(a){var b,c,d,e;d=Ajb((!a.c&&(a.c=ojb(Hdb(a.f))),a.c),0);if(a.e==0||a.a==0&&a.f!=-1&&a.e<0){return d}b=xib(a)<0?1:0;c=a.e;e=(d.length+1+$wnd.Math.abs(eE(a.e)),new cib);b==1&&(e.a+='-',e);if(a.e>0){c-=d.length-b;if(c>=0){e.a+='0.';for(;c>mib.length;c-=mib.length){$hb(e,mib)}_hb(e,mib,eE(c));Zhb(e,(BFb(b,d.length+1),d.substr(b)))}else{c=b-c;Zhb(e,zhb(d,b,eE(c)));e.a+='.';Zhb(e,yhb(d,eE(c)))}}else{Zhb(e,(BFb(b,d.length+1),d.substr(b)));for(;c<-mib.length;c+=mib.length){$hb(e,mib)}_hb(e,mib,eE(-c))}return e.a} +function BOc(a){var b,c,d,e,f,g,h,i,j;if(a.k!=(r3b(),p3b)){return false}if(a.j.c.length<=1){return false}f=RD(mQb(a,(yCc(),BBc)),101);if(f==(Bod(),wod)){return false}e=(wDc(),(!a.q?(yob(),yob(),wob):a.q)._b(iBc)?(d=RD(mQb(a,iBc),203)):(d=RD(mQb(Y2b(a),jBc),203)),d);if(e==uDc){return false}if(!(e==tDc||e==sDc)){g=Kfb(UD(hFc(a,fCc)));b=RD(mQb(a,eCc),140);!b&&(b=new R2b(g,g,g,g));j=b3b(a,(qpd(),ppd));i=b.d+b.a+(j.gc()-1)*g;if(i>a.o.b){return false}c=b3b(a,Xod);h=b.d+b.a+(c.gc()-1)*g;if(h>a.o.b){return false}}return true} +function VRc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;b.Ug('Orthogonal edge routing',1);j=Kfb(UD(mQb(a,(yCc(),cCc))));c=Kfb(UD(mQb(a,UBc)));d=Kfb(UD(mQb(a,XBc)));m=new TTc(0,c);q=0;g=new Jkb(a.b,0);h=null;k=null;i=null;l=null;do{k=g.b0){n=(o-1)*c;!!h&&(n+=d);!!k&&(n+=d);nb||Heb(TD(Gxd(i,(X7c(),D7c))))){e=0;f+=k.b+c;ZEb(l.c,k);k=new Had(f,c);d=new V9c(0,k.f,k,c);Cad(k,d);e=0}if(d.b.c.length==0||!Heb(TD(Gxd(vCd(i),(X7c(),L7c))))&&(i.f>=d.o&&i.f<=d.f||d.a*0.5<=i.f&&d.a*1.5>=i.f)){K9c(d,i)}else{g=new V9c(d.s+d.r+c,k.f,k,c);Cad(k,g);K9c(g,i)}e=i.i+i.g}ZEb(l.c,k);return l} +function ste(a){var b,c,d,e;if(a.b==null||a.b.length<=2)return;if(a.a)return;b=0;e=0;while(e=a.b[e+1]){e+=2}else if(c0){d=new dnb(RD(Qc(a.a,f),21));yob();_mb(d,new M0b(b));e=new Jkb(f.b,0);while(e.b0&&d>=-6){if(d>=0){aib(f,c-eE(a.e),String.fromCharCode(46))}else{peb(f,b-1,b-1,'0.');aib(f,b+1,Ihb(mib,0,-eE(d)-1))}}else{if(c-b>=1){aib(f,b,String.fromCharCode(46));++c}aib(f,c,String.fromCharCode(69));d>0&&aib(f,++c,String.fromCharCode(43));aib(f,++c,''+Zdb(Hdb(d)))}a.g=f.a;return a.g} +function KNc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A;d=Kfb(UD(mQb(b,(yCc(),hBc))));v=RD(mQb(b,gCc),17).a;m=4;e=3;w=20/v;n=false;i=0;g=lve;do{f=i!=1;l=i!=0;A=0;for(q=a.a,s=0,u=q.length;sv)){i=2;g=lve}else if(i==0){i=1;g=A}else{i=0;g=A}}else{n=A>=g||g-A0?1:cz(isNaN(d),isNaN(0)))>=0^(null,bz(vEe),($wnd.Math.abs(h)<=vEe||h==0||isNaN(h)&&isNaN(0)?0:h<0?-1:h>0?1:cz(isNaN(h),isNaN(0)))>=0)){return $wnd.Math.max(h,d)}bz(vEe);if(($wnd.Math.abs(d)<=vEe||d==0||isNaN(d)&&isNaN(0)?0:d<0?-1:d>0?1:cz(isNaN(d),isNaN(0)))>0){return $wnd.Math.sqrt(h*h+d*d)}return -$wnd.Math.sqrt(h*h+d*d)} +function hue(a,b){var c,d,e,f,g,h;if(!b)return;!a.a&&(a.a=new gyb);if(a.e==2){dyb(a.a,b);return}if(b.e==1){for(e=0;e=txe?Nhb(c,qse(d)):Jhb(c,d&Bwe);g=(++Use,new eue(10,null,0));fyb(a.a,g,h-1)}else{c=(g.Mm().length+f,new Rhb);Nhb(c,g.Mm())}if(b.e==0){d=b.Km();d>=txe?Nhb(c,qse(d)):Jhb(c,d&Bwe)}else{Nhb(c,b.Mm())}RD(g,530).b=c.a} +function Qsc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q;if(c.dc()){return}h=0;m=0;d=c.Kc();o=RD(d.Pb(),17).a;while(h1&&(i=j.Hg(i,a.a,h))}if(i.c.length==1){return RD(Vmb(i,i.c.length-1),238)}if(i.c.length==2){return e8c((tFb(0,i.c.length),RD(i.c[0],238)),(tFb(1,i.c.length),RD(i.c[1],238)),g,f)}return null} +function CZc(a,b,c){var d,e,f,g,h,i,j;c.Ug('Find roots',1);a.a.c.length=0;for(e=Sub(b.b,0);e.b!=e.d.c;){d=RD(evb(e),40);if(d.b.b==0){pQb(d,(q$c(),n$c),(Geb(),true));Rmb(a.a,d)}}switch(a.a.c.length){case 0:f=new bXc(0,b,'DUMMY_ROOT');pQb(f,(q$c(),n$c),(Geb(),true));pQb(f,WZc,true);Mub(b.b,f);break;case 1:break;default:g=new bXc(0,b,IEe);for(i=new Anb(a.a);i.a=$wnd.Math.abs(d.b)){d.b=0;f.d+f.a>g.d&&f.dg.c&&f.c0){b=new zNd(a.i,a.g);c=a.i;f=c<100?null:new gLd(c);if(a.Tj()){for(d=0;d0){h=a.g;j=a.i;OHd(a);f=j<100?null:new gLd(j);for(d=0;d>13|(a.m&15)<<9;e=a.m>>4&8191;f=a.m>>17|(a.h&255)<<5;g=(a.h&1048320)>>8;h=b.l&8191;i=b.l>>13|(b.m&15)<<9;j=b.m>>4&8191;k=b.m>>17|(b.h&255)<<5;l=(b.h&1048320)>>8;B=c*h;C=d*h;D=e*h;F=f*h;G=g*h;if(i!=0){C+=c*i;D+=d*i;F+=e*i;G+=f*i}if(j!=0){D+=c*j;F+=d*j;G+=e*j}if(k!=0){F+=c*k;G+=d*k}l!=0&&(G+=c*l);n=B&dxe;o=(C&511)<<13;m=n+o;q=B>>22;r=C>>9;s=(D&262143)<<4;t=(F&31)<<17;p=q+r+s+t;v=D>>18;w=F>>5;A=(G&4095)<<8;u=v+w+A;p+=m>>22;m&=dxe;u+=p>>22;p&=dxe;u&=exe;return hD(m,p,u)} +function Fac(a){var b,c,d,e,f,g,h;h=RD(Vmb(a.j,0),12);if(h.g.c.length!=0&&h.e.c.length!=0){throw Adb(new dgb('Interactive layout does not support NORTH/SOUTH ports with incoming _and_ outgoing edges.'))}if(h.g.c.length!=0){f=oxe;for(c=new Anb(h.g);c.a4){if(a.fk(b)){if(a.al()){e=RD(b,54);d=e.Eh();i=d==a.e&&(a.ml()?e.yh(e.Fh(),a.il())==a.jl():-1-e.Fh()==a.Lj());if(a.nl()&&!i&&!d&&!!e.Jh()){for(f=0;f0&&aGc(a,h,l)}for(e=new Anb(l);e.aa.d[g.p]){c+=ZLc(a.b,f)*RD(i.b,17).a;hmb(a.a,sgb(f))}}while(!nmb(a.a)){XLc(a.b,RD(smb(a.a),17).a)}}return c} +function x9b(a,b){var c,d,e,f,g,h,i,j,k,l;k=RD(mQb(a,(Ywc(),hwc)),64);d=RD(Vmb(a.j,0),12);k==(qpd(),Yod)?Q3b(d,npd):k==npd&&Q3b(d,Yod);if(RD(mQb(b,(yCc(),lBc)),181).Hc((Qpd(),Ppd))){i=Kfb(UD(mQb(a,_Bc)));j=Kfb(UD(mQb(a,aCc)));g=Kfb(UD(mQb(a,ZBc)));h=RD(mQb(b,EBc),21);if(h.Hc((Pod(),Lod))){c=j;l=a.o.a/2-d.n.a;for(f=new Anb(d.f);f.a0&&(j=a.n.a/f);break;case 2:case 4:e=a.i.o.b;e>0&&(j=a.n.b/e);}pQb(a,(Ywc(),Jwc),j)}i=a.o;g=a.a;if(d){g.a=d.a;g.b=d.b;a.d=true}else if(b!=zod&&b!=Aod&&h!=opd){switch(h.g){case 1:g.a=i.a/2;break;case 2:g.a=i.a;g.b=i.b/2;break;case 3:g.a=i.a/2;g.b=i.b;break;case 4:g.b=i.b/2;}}else{g.a=i.a/2;g.b=i.b/2}} +function VJd(a){var b,c,d,e,f,g,h,i,j,k;if(a.Pj()){k=a.Ej();i=a.Qj();if(k>0){b=new $Hd(a.pj());c=k;f=c<100?null:new gLd(c);aJd(a,c,b.g);e=c==1?a.Ij(4,QHd(b,0),null,0,i):a.Ij(6,b,null,-1,i);if(a.Mj()){for(d=new dMd(b);d.e!=d.i.gc();){f=a.Oj(bMd(d),f)}if(!f){a.Jj(e)}else{f.nj(e);f.oj()}}else{if(!f){a.Jj(e)}else{f.nj(e);f.oj()}}}else{aJd(a,a.Ej(),a.Fj());a.Jj(a.Ij(6,(yob(),vob),null,-1,i))}}else if(a.Mj()){k=a.Ej();if(k>0){h=a.Fj();j=k;aJd(a,k,h);f=j<100?null:new gLd(j);for(d=0;d1&&urd(g)*trd(g)/2>h[0]){f=0;while(fh[f]){++f}o=new Rkb(p,0,f+1);l=new zrd(o);k=urd(g)/trd(g);i=ird(l,b,new z3b,c,d,e,k);$id(hjd(l.e),i);zFb(lwb(m,l),Bxe);n=new Rkb(p,f+1,p.c.length);iwb(m,n);p.c.length=0;j=0;Pnb(h,h.length,0)}else{q=m.b.c.length==0?null:Vmb(m.b,0);q!=null&&owb(m,0);j>0&&(h[j]=h[j-1]);h[j]+=urd(g)*trd(g);++j;ZEb(p.c,g)}}return p} +function _nc(a,b){var c,d,e,f;c=b.b;f=new dnb(c.j);e=0;d=c.j;d.c.length=0;Nnc(RD($i(a.b,(qpd(),Yod),(joc(),ioc)),15),c);e=Onc(f,e,new Hoc,d);Nnc(RD($i(a.b,Yod,hoc),15),c);e=Onc(f,e,new Joc,d);Nnc(RD($i(a.b,Yod,goc),15),c);Nnc(RD($i(a.b,Xod,ioc),15),c);Nnc(RD($i(a.b,Xod,hoc),15),c);e=Onc(f,e,new Loc,d);Nnc(RD($i(a.b,Xod,goc),15),c);Nnc(RD($i(a.b,npd,ioc),15),c);e=Onc(f,e,new Noc,d);Nnc(RD($i(a.b,npd,hoc),15),c);e=Onc(f,e,new Poc,d);Nnc(RD($i(a.b,npd,goc),15),c);Nnc(RD($i(a.b,ppd,ioc),15),c);e=Onc(f,e,new toc,d);Nnc(RD($i(a.b,ppd,hoc),15),c);Nnc(RD($i(a.b,ppd,goc),15),c)} +function jJc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;for(h=new Anb(b);h.a0.5?(r-=g*2*(o-0.5)):o<0.5&&(r+=f*2*(0.5-o));e=h.d.b;rq.a-p-k&&(r=q.a-p-k);h.n.a=b+r}} +function jec(a){var b,c,d,e,f;d=RD(mQb(a,(yCc(),UAc)),171);if(d==(cxc(),$wc)){for(c=new is(Mr(Z2b(a).a.Kc(),new ir));gs(c);){b=RD(hs(c),18);if(!lec(b)){throw Adb(new Jed(nBe+X2b(a)+"' has its layer constraint set to FIRST_SEPARATE, but has at least one incoming edge. "+'FIRST_SEPARATE nodes must not have incoming edges.'))}}}else if(d==axc){for(f=new is(Mr(a3b(a).a.Kc(),new ir));gs(f);){e=RD(hs(f),18);if(!lec(e)){throw Adb(new Jed(nBe+X2b(a)+"' has its layer constraint set to LAST_SEPARATE, but has at least one outgoing edge. "+'LAST_SEPARATE nodes must not have outgoing edges.'))}}}} +function Qed(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;if(a.e&&a.c.c>19!=0){b=xD(b);i=!i}g=pD(b);f=false;e=false;d=false;if(a.h==fxe&&a.m==0&&a.l==0){e=true;f=true;if(g==-1){a=gD((MD(),ID));d=true;i=!i}else{h=BD(a,g);i&&nD(h);c&&(eD=hD(0,0,0));return h}}else if(a.h>>19!=0){f=true;a=xD(a);d=true;i=!i}if(g!=-1){return kD(a,g,i,f,c)}if(uD(a,b)<0){c&&(f?(eD=xD(a)):(eD=hD(a.l,a.m,a.h)));return hD(0,0,0)}return lD(d?a:hD(a.l,a.m,a.h),b,i,f,e,c)} +function Bjb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;g=a.e;i=b.e;if(g==0){return b}if(i==0){return a}f=a.d;h=b.d;if(f+h==2){c=Cdb(a.a[0],yxe);d=Cdb(b.a[0],yxe);if(g==i){k=Bdb(c,d);o=Ydb(k);n=Ydb(Udb(k,32));return n==0?new ajb(g,o):new cjb(g,2,cD(WC(kE,1),Pwe,28,15,[o,n]))}return Pib(),Jdb(g<0?Vdb(d,c):Vdb(c,d),0)?jjb(g<0?Vdb(d,c):Vdb(c,d)):Xib(jjb(Odb(g<0?Vdb(d,c):Vdb(c,d))))}else if(g==i){m=g;l=f>=h?Cjb(a.a,f,b.a,h):Cjb(b.a,h,a.a,f)}else{e=f!=h?f>h?1:-1:Ejb(a.a,b.a,f);if(e==0){return Pib(),Oib}if(e==1){m=g;l=Hjb(a.a,f,b.a,h)}else{m=i;l=Hjb(b.a,h,a.a,f)}}j=new cjb(m,l.length,l);Rib(j);return j} +function KUc(a,b){var c,d,e,f,g,h,i;if(a.g>b.f||b.g>a.f){return}c=0;d=0;for(g=a.w.a.ec().Kc();g.Ob();){e=RD(g.Pb(),12);AVc(xjd(cD(WC(l3,1),Nve,8,0,[e.i.n,e.n,e.a])).b,b.g,b.f)&&++c}for(h=a.r.a.ec().Kc();h.Ob();){e=RD(h.Pb(),12);AVc(xjd(cD(WC(l3,1),Nve,8,0,[e.i.n,e.n,e.a])).b,b.g,b.f)&&--c}for(i=b.w.a.ec().Kc();i.Ob();){e=RD(i.Pb(),12);AVc(xjd(cD(WC(l3,1),Nve,8,0,[e.i.n,e.n,e.a])).b,a.g,a.f)&&++d}for(f=b.r.a.ec().Kc();f.Ob();){e=RD(f.Pb(),12);AVc(xjd(cD(WC(l3,1),Nve,8,0,[e.i.n,e.n,e.a])).b,a.g,a.f)&&--d}if(c=0){return c}switch(yfe(Qee(a,c))){case 2:{if(lhb('',Oee(a,c.qk()).xe())){i=Bfe(Qee(a,c));h=Afe(Qee(a,c));k=Ree(a,b,i,h);if(k){return k}e=Fee(a,b);for(g=0,l=e.gc();g1){throw Adb(new agb(gLe))}k=pke(a.e.Dh(),b);d=RD(a.g,124);for(g=0;g1;for(j=new l4b(m.b);xnb(j.a)||xnb(j.b);){i=RD(xnb(j.a)?ynb(j.a):ynb(j.b),18);l=i.c==m?i.d:i.c;$wnd.Math.abs(xjd(cD(WC(l3,1),Nve,8,0,[l.i.n,l.n,l.a])).b-g.b)>1&&eSc(a,i,g,f,m)}}} +function vUc(a){var b,c,d,e,f,g;e=new Jkb(a.e,0);d=new Jkb(a.a,0);if(a.d){for(c=0;cAEe){f=b;g=0;while($wnd.Math.abs(b-f)0);e.a.Xb(e.c=--e.b);uUc(a,a.b-g,f,d,e);sFb(e.b0);d.a.Xb(d.c=--d.b)}if(!a.d){for(c=0;c0){a.f[k.p]=n/(k.e.c.length+k.g.c.length);a.c=$wnd.Math.min(a.c,a.f[k.p]);a.b=$wnd.Math.max(a.b,a.f[k.p])}else h&&(a.f[k.p]=n)}} +function xne(a){a.b=null;a.bb=null;a.fb=null;a.qb=null;a.a=null;a.c=null;a.d=null;a.e=null;a.f=null;a.n=null;a.M=null;a.L=null;a.Q=null;a.R=null;a.K=null;a.db=null;a.eb=null;a.g=null;a.i=null;a.j=null;a.k=null;a.gb=null;a.o=null;a.p=null;a.q=null;a.r=null;a.$=null;a.ib=null;a.S=null;a.T=null;a.t=null;a.s=null;a.u=null;a.v=null;a.w=null;a.B=null;a.A=null;a.C=null;a.D=null;a.F=null;a.G=null;a.H=null;a.I=null;a.J=null;a.P=null;a.Z=null;a.U=null;a.V=null;a.W=null;a.X=null;a.Y=null;a._=null;a.ab=null;a.cb=null;a.hb=null;a.nb=null;a.lb=null;a.mb=null;a.ob=null;a.pb=null;a.jb=null;a.kb=null;a.N=false;a.O=false} +function C8b(a,b,c){var d,e,f,g;c.Ug('Graph transformation ('+a.a+')',1);g=bv(b.a);for(f=new Anb(b.b);f.a=h.b.c)&&(h.b=b);if(!h.c||b.c<=h.c.c){h.d=h.c;h.c=b}(!h.e||b.d>=h.e.d)&&(h.e=b);(!h.f||b.d<=h.f.d)&&(h.f=b)}d=new PZb((nZb(),jZb));t$b(a,AZb,new mob(cD(WC(wQ,1),rve,382,0,[d])));g=new PZb(mZb);t$b(a,zZb,new mob(cD(WC(wQ,1),rve,382,0,[g])));e=new PZb(kZb);t$b(a,yZb,new mob(cD(WC(wQ,1),rve,382,0,[e])));f=new PZb(lZb);t$b(a,xZb,new mob(cD(WC(wQ,1),rve,382,0,[f])));FZb(d.c,jZb);FZb(e.c,kZb);FZb(f.c,lZb);FZb(g.c,mZb);h.a.c.length=0;Tmb(h.a,d.c);Tmb(h.a,hv(e.c));Tmb(h.a,f.c);Tmb(h.a,hv(g.c));return h} +function n9c(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;b.Ug(bGe,1);n=Kfb(UD(Gxd(a,(X6c(),W6c))));g=Kfb(UD(Gxd(a,(X7c(),Q7c))));h=RD(Gxd(a,N7c),107);Bad((!a.a&&(a.a=new C5d(J4,a,10,11)),a.a));k=U8c((!a.a&&(a.a=new C5d(J4,a,10,11)),a.a),n,g);!a.a&&(a.a=new C5d(J4,a,10,11));for(j=new Anb(k);j.a0){a.a=i+(n-1)*f;b.c.b+=a.a;b.f.b+=a.a}}if(o.a.gc()!=0){m=new TTc(1,f);n=STc(m,b,o,p,b.f.b+i-b.c.b);n>0&&(b.f.b+=i+(n-1)*f)}} +function osc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;k=Kfb(UD(mQb(a,(yCc(),WBc))));d=Kfb(UD(mQb(a,nCc)));m=new dtd;pQb(m,WBc,k+d);j=b;r=j.d;p=j.c.i;s=j.d.i;q=Q4b(p.c);t=Q4b(s.c);e=new bnb;for(l=q;l<=t;l++){h=new j3b(a);h3b(h,(r3b(),o3b));pQb(h,(Ywc(),Awc),j);pQb(h,BBc,(Bod(),wod));pQb(h,YBc,m);n=RD(Vmb(a.b,l),30);l==q?f3b(h,n.a.c.length-c,n):g3b(h,n);u=Kfb(UD(mQb(j,FAc)));if(u<0){u=0;pQb(j,FAc,u)}h.o.b=u;o=$wnd.Math.floor(u/2);g=new R3b;Q3b(g,(qpd(),ppd));P3b(g,h);g.n.b=o;i=new R3b;Q3b(i,Xod);P3b(i,h);i.n.b=o;Z0b(j,g);f=new a1b;kQb(f,j);pQb(f,RAc,null);Y0b(f,i);Z0b(f,r);psc(h,j,f);ZEb(e.c,f);j=f}return e} +function Hec(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;i=RD(e3b(a,(qpd(),ppd)).Kc().Pb(),12).e;n=RD(e3b(a,Xod).Kc().Pb(),12).g;h=i.c.length;t=K3b(RD(Vmb(a.j,0),12));while(h-->0){p=(tFb(0,i.c.length),RD(i.c[0],18));e=(tFb(0,n.c.length),RD(n.c[0],18));s=e.d.e;f=Wmb(s,e,0);$0b(p,e.d,f);Y0b(e,null);Z0b(e,null);o=p.a;b&&Mub(o,new sjd(t));for(d=Sub(e.a,0);d.b!=d.d.c;){c=RD(evb(d),8);Mub(o,new sjd(c))}r=p.b;for(m=new Anb(e.b);m.ag)&&Ysb(a.b,RD(q.b,18))}}++h}f=g}}}} +function zhd(b,c){var d;if(c==null||lhb(c,vve)){return null}if(c.length==0&&b.k!=(kid(),fid)){return null}switch(b.k.g){case 1:return mhb(c,FGe)?(Geb(),Feb):mhb(c,GGe)?(Geb(),Eeb):null;case 2:try{return sgb(Oeb(c,qwe,lve))}catch(a){a=zdb(a);if(ZD(a,130)){return null}else throw Adb(a)}case 4:try{return Neb(c)}catch(a){a=zdb(a);if(ZD(a,130)){return null}else throw Adb(a)}case 3:return c;case 5:uhd(b);return xhd(b,c);case 6:uhd(b);return yhd(b,b.a,c);case 7:try{d=whd(b);d.cg(c);return d}catch(a){a=zdb(a);if(ZD(a,33)){return null}else throw Adb(a)}default:throw Adb(new dgb('Invalid type set for this layout option.'));}} +function JKd(a){var b;switch(a.d){case 1:{if(a.Sj()){return a.o!=-2}break}case 2:{if(a.Sj()){return a.o==-2}break}case 3:case 5:case 4:case 6:case 7:{return a.o>-2}default:{return false}}b=a.Rj();switch(a.p){case 0:return b!=null&&Heb(TD(b))!=Pdb(a.k,0);case 1:return b!=null&&RD(b,222).a!=Ydb(a.k)<<24>>24;case 2:return b!=null&&RD(b,180).a!=(Ydb(a.k)&Bwe);case 6:return b!=null&&Pdb(RD(b,168).a,a.k);case 5:return b!=null&&RD(b,17).a!=Ydb(a.k);case 7:return b!=null&&RD(b,191).a!=Ydb(a.k)<<16>>16;case 3:return b!=null&&Kfb(UD(b))!=a.j;case 4:return b!=null&&RD(b,161).a!=a.j;default:return b==null?a.n!=null:!pb(b,a.n);}} +function N_d(a,b,c){var d,e,f,g;if(a.ol()&&a.nl()){g=O_d(a,RD(c,58));if(dE(g)!==dE(c)){a.xj(b);a.Dj(b,P_d(a,b,g));if(a.al()){f=(e=RD(c,54),a.ml()?a.kl()?e.Th(a.b,Z5d(RD(vYd(Uwd(a.b),a.Lj()),19)).n,RD(vYd(Uwd(a.b),a.Lj()).Hk(),29).kk(),null):e.Th(a.b,BYd(e.Dh(),Z5d(RD(vYd(Uwd(a.b),a.Lj()),19))),null,null):e.Th(a.b,-1-a.Lj(),null,null));!RD(g,54).Ph()&&(f=(d=RD(g,54),a.ml()?a.kl()?d.Rh(a.b,Z5d(RD(vYd(Uwd(a.b),a.Lj()),19)).n,RD(vYd(Uwd(a.b),a.Lj()).Hk(),29).kk(),f):d.Rh(a.b,BYd(d.Dh(),Z5d(RD(vYd(Uwd(a.b),a.Lj()),19))),null,f):d.Rh(a.b,-1-a.Lj(),null,f)));!!f&&f.oj()}Mvd(a.b)&&a.Jj(a.Ij(9,c,g,b,false));return g}}return c} +function iJb(a){var b,c,d,e,f,g,h,i,j,k;d=new bnb;for(g=new Anb(a.e.a);g.a0&&(g=$wnd.Math.max(g,zMb(a.C.b+d.d.b,e)))}else{n=m+k.d.c+a.w+d.d.b;g=$wnd.Math.max(g,(Zy(),bz(Tye),$wnd.Math.abs(l-e)<=Tye||l==e||isNaN(l)&&isNaN(e)?0:n/(e-l)))}k=d;l=e;m=f}if(!!a.C&&a.C.c>0){n=m+a.C.c;j&&(n+=k.d.c);g=$wnd.Math.max(g,(Zy(),bz(Tye),$wnd.Math.abs(l-1)<=Tye||l==1||isNaN(l)&&isNaN(1)?0:n/(1-l)))}c.n.b=0;c.a.a=g} +function ENb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n;c=RD(Vrb(a.b,b),127);i=RD(RD(Qc(a.r,b),21),87);if(i.dc()){c.n.d=0;c.n.a=0;return}j=a.u.Hc((Pod(),Lod));g=0;a.A.Hc((Qpd(),Ppd))&&JNb(a,b);h=i.Kc();k=null;m=0;l=0;while(h.Ob()){d=RD(h.Pb(),117);f=Kfb(UD(d.b.of((tNb(),sNb))));e=d.b.Mf().b;if(!k){!!a.C&&a.C.d>0&&(g=$wnd.Math.max(g,zMb(a.C.d+d.d.d,f)))}else{n=l+k.d.a+a.w+d.d.d;g=$wnd.Math.max(g,(Zy(),bz(Tye),$wnd.Math.abs(m-f)<=Tye||m==f||isNaN(m)&&isNaN(f)?0:n/(f-m)))}k=d;m=f;l=e}if(!!a.C&&a.C.a>0){n=l+a.C.a;j&&(n+=k.d.a);g=$wnd.Math.max(g,(Zy(),bz(Tye),$wnd.Math.abs(m-1)<=Tye||m==1||isNaN(m)&&isNaN(1)?0:n/(1-m)))}c.n.d=0;c.a.b=g} +function L8c(a,b,c,d,e,f,g,h){var i,j,k,l,m,n,o,p,q,r;o=false;j=dad(c.q,b.f+b.b-c.q.f);n=d.f>b.b&&h;r=e-(c.q.e+j-g);l=(i=S9c(d,r,false),i.a);if(n&&l>d.f){return false}if(n){m=0;for(q=new Anb(b.d);q.a=(tFb(f,a.c.length),RD(a.c[f],186)).e;if(!n&&l>b.b&&!k){return false}if(k||n||l<=b.b){if(k&&l>b.b){c.d=l;Q9c(c,P9c(c,l))}else{ead(c.q,j);c.c=true}Q9c(d,e-(c.s+c.r));U9c(d,c.q.e+c.q.d,b.f);Cad(b,d);if(a.c.length>f){Fad((tFb(f,a.c.length),RD(a.c[f],186)),d);(tFb(f,a.c.length),RD(a.c[f],186)).a.c.length==0&&Xmb(a,f)}o=true}return o} +function zJc(a,b,c){var d,e,f,g,h,i;this.g=a;h=b.d.length;i=c.d.length;this.d=$C(jR,WAe,10,h+i,0,1);for(g=0;g0?xJc(this,this.f/this.a):pJc(b.g,b.d[0]).a!=null&&pJc(c.g,c.d[0]).a!=null?xJc(this,(Kfb(pJc(b.g,b.d[0]).a)+Kfb(pJc(c.g,c.d[0]).a))/2):pJc(b.g,b.d[0]).a!=null?xJc(this,pJc(b.g,b.d[0]).a):pJc(c.g,c.d[0]).a!=null&&xJc(this,pJc(c.g,c.d[0]).a)} +function DXb(a,b){var c,d,e,f,g,h,i,j,k,l;a.a=new fYb(wsb(s3));for(d=new Anb(b.a);d.a=1){if(q-g>0&&l>=0){i.n.a+=p;i.n.b+=f*g}else if(q-g<0&&k>=0){i.n.a+=p*q;i.n.b+=f}}}a.o.a=b.a;a.o.b=b.b;pQb(a,(yCc(),lBc),(Qpd(),d=RD(mfb(H3),9),new Fsb(d,RD(WEb(d,d.length),9),0)))} +function ISd(a,b,c,d,e,f){var g;if(!(b==null||!mSd(b,ZRd,$Rd))){throw Adb(new agb('invalid scheme: '+b))}if(!a&&!(c!=null&&qhb(c,Fhb(35))==-1&&c.length>0&&(BFb(0,c.length),c.charCodeAt(0)!=47))){throw Adb(new agb('invalid opaquePart: '+c))}if(a&&!(b!=null&&tpb(eSd,b.toLowerCase()))&&!(c==null||!mSd(c,aSd,bSd))){throw Adb(new agb(NJe+c))}if(a&&b!=null&&tpb(eSd,b.toLowerCase())&&!ESd(c)){throw Adb(new agb(NJe+c))}if(!FSd(d)){throw Adb(new agb('invalid device: '+d))}if(!HSd(e)){g=e==null?'invalid segments: null':'invalid segment: '+tSd(e);throw Adb(new agb(g))}if(!(f==null||qhb(f,Fhb(35))==-1)){throw Adb(new agb('invalid query: '+f))}} +function WHc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;c.Ug('Network simplex layering',1);a.b=b;r=RD(mQb(b,(yCc(),gCc)),17).a*4;q=a.b.a;if(q.c.length<1){c.Vg();return}f=SHc(a,q);p=null;for(e=Sub(f,0);e.b!=e.d.c;){d=RD(evb(e),15);h=r*eE($wnd.Math.sqrt(d.gc()));g=VHc(d);lJb(yJb(AJb(zJb(CJb(g),h),p),true),c.eh(1));m=a.b.b;for(o=new Anb(g.a);o.a1){p=$C(kE,Pwe,28,a.b.b.c.length,15,1);l=0;for(j=new Anb(a.b.b);j.a0){wA(a,c,0);c.a+=String.fromCharCode(d);e=BA(b,f);wA(a,c,e);f+=e-1;continue}if(d==39){if(f+10&&o.a<=0){i.c.length=0;ZEb(i.c,o);break}n=o.i-o.d;if(n>=h){if(n>h){i.c.length=0;h=n}ZEb(i.c,o)}}if(i.c.length!=0){g=RD(Vmb(i,Jwb(e,i.c.length)),118);t.a.Bc(g)!=null;g.g=k++;wSc(g,b,c,d);i.c.length=0}}q=a.c.length+1;for(m=new Anb(a);m.apxe||b.o==CQc&&k=h&&e<=i){if(h<=e&&f<=i){c[k++]=e;c[k++]=f;d+=2}else if(h<=e){c[k++]=e;c[k++]=i;a.b[d]=i+1;g+=2}else if(f<=i){c[k++]=h;c[k++]=f;d+=2}else{c[k++]=h;c[k++]=i;a.b[d]=i+1}}else if(ipwe)&&h<10);BYb(a.c,new bYb);QXb(a);xYb(a.c);AXb(a.f)} +function B9b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;c=RD(mQb(a,(yCc(),BBc)),101);g=a.f;f=a.d;h=g.a+f.b+f.c;i=0-f.d-a.c.b;k=g.b+f.d+f.a-a.c.b;j=new bnb;l=new bnb;for(e=new Anb(b);e.a=2){i=Sub(c,0);g=RD(evb(i),8);h=RD(evb(i),8);while(h.a0&&aHb(j,true,(Cmd(),zmd));h.k==(r3b(),m3b)&&bHb(j);Zjb(a.f,h,b)}}} +function OVc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;e=RD(mQb(a,(q$c(),h$c)),27);j=lve;k=lve;h=qwe;i=qwe;for(t=Sub(a.b,0);t.b!=t.d.c;){r=RD(evb(t),40);n=r.e;o=r.f;j=$wnd.Math.min(j,n.a-o.a/2);k=$wnd.Math.min(k,n.b-o.b/2);h=$wnd.Math.max(h,n.a+o.a/2);i=$wnd.Math.max(i,n.b+o.b/2)}m=RD(Gxd(e,(h_c(),T$c)),107);for(s=Sub(a.b,0);s.b!=s.d.c;){r=RD(evb(s),40);l=mQb(r,h$c);if(ZD(l,207)){f=RD(l,27);Byd(f,r.e.a,r.e.b);zxd(f,r)}}for(q=Sub(a.a,0);q.b!=q.d.c;){p=RD(evb(q),65);d=RD(mQb(p,h$c),74);if(d){b=p.a;c=IGd(d,true,true);lsd(b,c)}}u=h-j+(m.b+m.c);g=i-k+(m.d+m.a);Heb(TD(Gxd(e,(umd(),mld))))||Esd(e,u,g,false,false);Ixd(e,Ikd,u-(m.b+m.c));Ixd(e,Hkd,g-(m.d+m.a))} +function Wec(a,b){var c,d,e,f,g,h,i,j,k,l;i=true;e=0;j=a.g[b.p];k=b.o.b+a.o;c=a.d[b.p][2];$mb(a.b,j,sgb(RD(Vmb(a.b,j),17).a-1+c));$mb(a.c,j,Kfb(UD(Vmb(a.c,j)))-k+c*a.f);++j;if(j>=a.j){++a.j;Rmb(a.b,sgb(1));Rmb(a.c,k)}else{d=a.d[b.p][1];$mb(a.b,j,sgb(RD(Vmb(a.b,j),17).a+1-d));$mb(a.c,j,Kfb(UD(Vmb(a.c,j)))+k-d*a.f)}(a.r==(aEc(),VDc)&&(RD(Vmb(a.b,j),17).a>a.k||RD(Vmb(a.b,j-1),17).a>a.k)||a.r==YDc&&(Kfb(UD(Vmb(a.c,j)))>a.n||Kfb(UD(Vmb(a.c,j-1)))>a.n))&&(i=false);for(g=new is(Mr(Z2b(b).a.Kc(),new ir));gs(g);){f=RD(hs(g),18);h=f.c.i;if(a.g[h.p]==j){l=Wec(a,h);e=e+RD(l.a,17).a;i=i&&Heb(TD(l.b))}}a.g[b.p]=j;e=e+a.d[b.p][0];return new Ptd(sgb(e),(Geb(),i?true:false))} +function cXb(a,b){var c,d,e,f,g;c=Kfb(UD(mQb(b,(yCc(),TBc))));c<2&&pQb(b,TBc,2);d=RD(mQb(b,rAc),88);d==(Cmd(),Amd)&&pQb(b,rAc,i2b(b));e=RD(mQb(b,NBc),17);e.a==0?pQb(b,(Ywc(),Lwc),new Owb):pQb(b,(Ywc(),Lwc),new Pwb(e.a));f=TD(mQb(b,gBc));f==null&&pQb(b,gBc,(Geb(),dE(mQb(b,yAc))===dE((Ymd(),Umd))?true:false));FDb(new SDb(null,new Swb(b.a,16)),new fXb(a));FDb(EDb(new SDb(null,new Swb(b.b,16)),new hXb),new jXb(a));g=new gFc(b);pQb(b,(Ywc(),Qwc),g);Sed(a.a);Ved(a.a,(sXb(),nXb),RD(mQb(b,pAc),188));Ved(a.a,oXb,RD(mQb(b,$Ac),188));Ved(a.a,pXb,RD(mQb(b,oAc),188));Ved(a.a,qXb,RD(mQb(b,kBc),188));Ved(a.a,rXb,KRc(RD(mQb(b,yAc),223)));Ped(a.a,bXb(b));pQb(b,Kwc,Qed(a.a,b))} +function STc(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r;l=new Tsb;g=new bnb;QTc(a,c,a.d.Ag(),g,l);QTc(a,d,a.d.Bg(),g,l);a.b=0.2*(p=RTc(EDb(new SDb(null,new Swb(g,16)),new XTc)),q=RTc(EDb(new SDb(null,new Swb(g,16)),new ZTc)),$wnd.Math.min(p,q));f=0;for(h=0;h=2&&(r=uSc(g,true,m),!a.e&&(a.e=new xTc(a)),tTc(a.e,r,g,a.b),undefined);UTc(g,m);WTc(g);n=-1;for(k=new Anb(g);k.ah} +function Iad(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;j=oxe;k=oxe;h=pxe;i=pxe;for(m=new Anb(b.i);m.a-1){for(e=Sub(h,0);e.b!=e.d.c;){d=RD(evb(e),131);d.v=g}while(h.b!=0){d=RD(ku(h,0),131);for(c=new Anb(d.i);c.a-1){for(f=new Anb(h);f.a0){continue}RSc(i,$wnd.Math.min(i.o,e.o-1));QSc(i,i.i-1);i.i==0&&(ZEb(h.c,i),true)}}}} +function Lid(a,b,c,d,e){var f,g,h,i;i=oxe;g=false;h=Gid(a,ojd(new rjd(b.a,b.b),a),$id(new rjd(c.a,c.b),e),ojd(new rjd(d.a,d.b),c));f=!!h&&!($wnd.Math.abs(h.a-a.a)<=IGe&&$wnd.Math.abs(h.b-a.b)<=IGe||$wnd.Math.abs(h.a-b.a)<=IGe&&$wnd.Math.abs(h.b-b.b)<=IGe);h=Gid(a,ojd(new rjd(b.a,b.b),a),c,e);!!h&&(($wnd.Math.abs(h.a-a.a)<=IGe&&$wnd.Math.abs(h.b-a.b)<=IGe)==($wnd.Math.abs(h.a-b.a)<=IGe&&$wnd.Math.abs(h.b-b.b)<=IGe)||f?(i=$wnd.Math.min(i,ejd(ojd(h,c)))):(g=true));h=Gid(a,ojd(new rjd(b.a,b.b),a),d,e);!!h&&(g||($wnd.Math.abs(h.a-a.a)<=IGe&&$wnd.Math.abs(h.b-a.b)<=IGe)==($wnd.Math.abs(h.a-b.a)<=IGe&&$wnd.Math.abs(h.b-b.b)<=IGe)||f)&&(i=$wnd.Math.min(i,ejd(ojd(h,d))));return i} +function eWb(a){Cgd(a,new Pfd(Wfd($fd(Xfd(Zfd(Yfd(new agd,AAe),BAe),"Minimizes the stress within a layout using stress majorization. Stress exists if the euclidean distance between a pair of nodes doesn't match their graph theoretic distance, that is, the shortest path between the two nodes. The method allows to specify individual edge lengths."),new hWb),Zze)));Agd(a,AAe,dAe,iGd(XVb));Agd(a,AAe,fAe,(Geb(),true));Agd(a,AAe,jAe,iGd($Vb));Agd(a,AAe,CAe,iGd(_Vb));Agd(a,AAe,iAe,iGd(aWb));Agd(a,AAe,kAe,iGd(ZVb));Agd(a,AAe,gAe,iGd(bWb));Agd(a,AAe,lAe,iGd(cWb));Agd(a,AAe,vAe,iGd(WVb));Agd(a,AAe,xAe,iGd(UVb));Agd(a,AAe,yAe,iGd(VVb));Agd(a,AAe,zAe,iGd(YVb));Agd(a,AAe,wAe,iGd(TVb))} +function kJc(a){var b,c,d,e,f,g,h,i;b=null;for(d=new Anb(a);d.a0&&c.c==0){!b&&(b=new bnb);ZEb(b.c,c)}}if(b){while(b.c.length!=0){c=RD(Xmb(b,0),239);if(!!c.b&&c.b.c.length>0){for(f=(!c.b&&(c.b=new bnb),new Anb(c.b));f.aWmb(a,c,0)){return new Ptd(e,c)}}else if(Kfb(pJc(e.g,e.d[0]).a)>Kfb(pJc(c.g,c.d[0]).a)){return new Ptd(e,c)}}}for(h=(!c.e&&(c.e=new bnb),c.e).Kc();h.Ob();){g=RD(h.Pb(),239);i=(!g.b&&(g.b=new bnb),g.b);wFb(0,i.c.length);XEb(i.c,0,c);g.c==i.c.length&&(ZEb(b.c,g),true)}}}return null} +function _Jc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;b.Ug('Interactive crossing minimization',1);g=0;for(f=new Anb(a.b);f.a0){c+=i.n.a+i.o.a/2;++l}for(o=new Anb(i.j);o.a0&&(c/=l);r=$C(iE,vxe,28,d.a.c.length,15,1);h=0;for(j=new Anb(d.a);j.a=h&&e<=i){if(h<=e&&f<=i){d+=2}else if(h<=e){a.b[d]=i+1;g+=2}else if(f<=i){c[k++]=e;c[k++]=h-1;d+=2}else{c[k++]=e;c[k++]=h-1;a.b[d]=i+1;g+=2}}else if(i2){k=new bnb;Tmb(k,new Rkb(r,1,r.b));f=jTb(k,t+a.a);s=new ORb(f);kQb(s,b);ZEb(c.c,s)}else{d?(s=RD(Wjb(a.b,JGd(b)),272)):(s=RD(Wjb(a.b,LGd(b)),272))}i=JGd(b);d&&(i=LGd(b));g=qTb(q,i);j=t+a.a;if(g.a){j+=$wnd.Math.abs(q.b-l.b);p=new rjd(l.a,(l.b+q.b)/2)}else{j+=$wnd.Math.abs(q.a-l.a);p=new rjd((l.a+q.a)/2,l.b)}d?Zjb(a.d,b,new QRb(s,g,p,j)):Zjb(a.c,b,new QRb(s,g,p,j));Zjb(a.b,b,s);o=(!b.n&&(b.n=new C5d(I4,b,1,7)),b.n);for(n=new dMd(o);n.e!=n.i.gc();){m=RD(bMd(n),135);e=nTb(a,m,true,0,0);ZEb(c.c,e)}} +function sMb(a){var b,c,d,e,f,g,h;if(a.A.dc()){return}if(a.A.Hc((Qpd(),Opd))){RD(Vrb(a.b,(qpd(),Yod)),127).k=true;RD(Vrb(a.b,npd),127).k=true;b=a.q!=(Bod(),xod)&&a.q!=wod;QJb(RD(Vrb(a.b,Xod),127),b);QJb(RD(Vrb(a.b,ppd),127),b);QJb(a.g,b);if(a.A.Hc(Ppd)){RD(Vrb(a.b,Yod),127).j=true;RD(Vrb(a.b,npd),127).j=true;RD(Vrb(a.b,Xod),127).k=true;RD(Vrb(a.b,ppd),127).k=true;a.g.k=true}}if(a.A.Hc(Npd)){a.a.j=true;a.a.k=true;a.g.j=true;a.g.k=true;h=a.B.Hc((dqd(),_pd));for(e=nMb(),f=0,g=e.length;f0),RD(k.a.Xb(k.c=--k.b),18));while(f!=d&&k.b>0){a.a[f.p]=true;a.a[d.p]=true;f=(sFb(k.b>0),RD(k.a.Xb(k.c=--k.b),18))}k.b>0&&Ckb(k)}}}}} +function Zyb(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;if(!a.b){return false}g=null;m=null;i=new Fzb(null,null);e=1;i.a[1]=a.b;l=i;while(l.a[e]){j=e;h=m;m=l;l=l.a[e];d=a.a.Ne(b,l.d);e=d<0?0:1;d==0&&(!c.c||Fvb(l.e,c.d))&&(g=l);if(!(!!l&&l.b)&&!Vyb(l.a[e])){if(Vyb(l.a[1-e])){m=m.a[j]=azb(l,e)}else if(!Vyb(l.a[1-e])){n=m.a[1-j];if(n){if(!Vyb(n.a[1-j])&&!Vyb(n.a[j])){m.b=false;n.b=true;l.b=true}else{f=h.a[1]==m?1:0;Vyb(n.a[j])?(h.a[f]=_yb(m,j)):Vyb(n.a[1-j])&&(h.a[f]=azb(m,j));l.b=h.a[f].b=true;h.a[f].a[0].b=false;h.a[f].a[1].b=false}}}}}if(g){c.b=true;c.d=g.e;if(l!=g){k=new Fzb(l.d,l.e);$yb(a,i,g,k);m==g&&(m=k)}m.a[m.a[1]==l?1:0]=l.a[!l.a[0]?1:0];--a.c}a.b=i.a[1];!!a.b&&(a.b.b=false);return c.b} +function Ilc(a){var b,c,d,e,f,g,h,i,j,k,l,m;for(e=new Anb(a.a.a.b);e.a0?(e-=86400000):(e+=86400000);i=new wB(Bdb(Hdb(b.q.getTime()),e))}k=new cib;j=a.a.length;for(f=0;f=97&&d<=122||d>=65&&d<=90){for(g=f+1;g=j){throw Adb(new agb("Missing trailing '"))}g+1=14&&k<=16))){if(b.a._b(d)){!c.a?(c.a=new dib(c.d)):Zhb(c.a,c.b);Whb(c.a,'[...]')}else{h=SD(d);j=new btb(b);Gyb(c,Inb(h,j))}}else ZD(d,183)?Gyb(c,hob(RD(d,183))):ZD(d,195)?Gyb(c,aob(RD(d,195))):ZD(d,201)?Gyb(c,bob(RD(d,201))):ZD(d,2111)?Gyb(c,gob(RD(d,2111))):ZD(d,53)?Gyb(c,eob(RD(d,53))):ZD(d,376)?Gyb(c,fob(RD(d,376))):ZD(d,846)?Gyb(c,dob(RD(d,846))):ZD(d,109)&&Gyb(c,cob(RD(d,109)))}else{Gyb(c,d==null?vve:jeb(d))}}return !c.a?c.c:c.e.length==0?c.a.a:c.a.a+(''+c.e)} +function KXd(a,b){var c,d,e,f;f=a.F;if(b==null){a.F=null;yXd(a,null)}else{a.F=(uFb(b),b);d=qhb(b,Fhb(60));if(d!=-1){e=(AFb(0,d,b.length),b.substr(0,d));qhb(b,Fhb(46))==-1&&!lhb(e,hve)&&!lhb(e,dKe)&&!lhb(e,eKe)&&!lhb(e,fKe)&&!lhb(e,gKe)&&!lhb(e,hKe)&&!lhb(e,iKe)&&!lhb(e,jKe)&&(e=kKe);c=thb(b,Fhb(62));c!=-1&&(e+=''+(BFb(c+1,b.length+1),b.substr(c+1)));yXd(a,e)}else{e=b;if(qhb(b,Fhb(46))==-1){d=qhb(b,Fhb(91));d!=-1&&(e=(AFb(0,d,b.length),b.substr(0,d)));if(!lhb(e,hve)&&!lhb(e,dKe)&&!lhb(e,eKe)&&!lhb(e,fKe)&&!lhb(e,gKe)&&!lhb(e,hKe)&&!lhb(e,iKe)&&!lhb(e,jKe)){e=kKe;d!=-1&&(e+=''+(BFb(d,b.length+1),b.substr(d)))}else{e=b}}yXd(a,e);e==b&&(a.F=a.D)}}(a.Db&4)!=0&&(a.Db&1)==0&&qvd(a,new N3d(a,1,5,f,b))} +function Pvd(b,c){var d,e,f,g,h,i,j,k,l,m;j=c.length-1;i=(BFb(j,c.length),c.charCodeAt(j));if(i==93){h=qhb(c,Fhb(91));if(h>=0){f=Uvd(b,(AFb(1,h,c.length),c.substr(1,h-1)));l=(AFb(h+1,j,c.length),c.substr(h+1,j-(h+1)));return Nvd(b,l,f)}}else{d=-1;_eb==null&&(_eb=new RegExp('\\d'));if(_eb.test(String.fromCharCode(i))){d=uhb(c,Fhb(46),j-1);if(d>=0){e=RD(Fvd(b,Zvd(b,(AFb(1,d,c.length),c.substr(1,d-1))),false),61);k=0;try{k=Oeb((BFb(d+1,c.length+1),c.substr(d+1)),qwe,lve)}catch(a){a=zdb(a);if(ZD(a,130)){g=a;throw Adb(new RSd(g))}else throw Adb(a)}if(k>16==-10){c=RD(a.Cb,292).Yk(b,c)}else if(a.Db>>16==-15){!b&&(b=(JTd(),wTd));!j&&(j=(JTd(),wTd));if(a.Cb.Yh()){i=new P3d(a.Cb,1,13,j,b,fZd(o4d(RD(a.Cb,62)),a),false);!c?(c=i):c.nj(i)}}}else if(ZD(a.Cb,90)){if(a.Db>>16==-23){ZD(b,90)||(b=(JTd(),zTd));ZD(j,90)||(j=(JTd(),zTd));if(a.Cb.Yh()){i=new P3d(a.Cb,1,10,j,b,fZd(tYd(RD(a.Cb,29)),a),false);!c?(c=i):c.nj(i)}}}else if(ZD(a.Cb,457)){h=RD(a.Cb,850);g=(!h.b&&(h.b=new pae(new lae)),h.b);for(f=(d=new vkb((new mkb(g.a)).a),new xae(d));f.a.b;){e=RD(tkb(f.a).ld(),89);c=o2d(e,k2d(e,h),c)}}}return c} +function Y4b(a,b){var c,d,e,f,g,h,i,j,k,l,m;g=Heb(TD(Gxd(a,(yCc(),NAc))));m=RD(Gxd(a,EBc),21);i=false;j=false;l=new dMd((!a.c&&(a.c=new C5d(K4,a,9,9)),a.c));while(l.e!=l.i.gc()&&(!i||!j)){f=RD(bMd(l),123);h=0;for(e=Fl(Al(cD(WC(cJ,1),rve,20,0,[(!f.d&&(f.d=new Yie(G4,f,8,5)),f.d),(!f.e&&(f.e=new Yie(G4,f,7,4)),f.e)])));gs(e);){d=RD(hs(e),74);k=g&&ozd(d)&&Heb(TD(Gxd(d,OAc)));c=cZd((!d.b&&(d.b=new Yie(E4,d,4,7)),d.b),f)?a==vCd(AGd(RD(QHd((!d.c&&(d.c=new Yie(E4,d,5,8)),d.c),0),84))):a==vCd(AGd(RD(QHd((!d.b&&(d.b=new Yie(E4,d,4,7)),d.b),0),84)));if(k||c){++h;if(h>1){break}}}h>0?(i=true):m.Hc((Pod(),Lod))&&(!f.n&&(f.n=new C5d(I4,f,1,7)),f.n).i>0&&(i=true);h>1&&(j=true)}i&&b.Fc((ovc(),hvc));j&&b.Fc((ovc(),ivc))} +function Dsd(a){var b,c,d,e,f,g,h,i,j,k,l,m;m=RD(Gxd(a,(umd(),kld)),21);if(m.dc()){return null}h=0;g=0;if(m.Hc((Qpd(),Opd))){k=RD(Gxd(a,Hld),101);d=2;c=2;e=2;f=2;b=!vCd(a)?RD(Gxd(a,Nkd),88):RD(Gxd(vCd(a),Nkd),88);for(j=new dMd((!a.c&&(a.c=new C5d(K4,a,9,9)),a.c));j.e!=j.i.gc();){i=RD(bMd(j),123);l=RD(Gxd(i,Old),64);if(l==(qpd(),opd)){l=osd(i,b);Ixd(i,Old,l)}if(k==(Bod(),wod)){switch(l.g){case 1:d=$wnd.Math.max(d,i.i+i.g);break;case 2:c=$wnd.Math.max(c,i.j+i.f);break;case 3:e=$wnd.Math.max(e,i.i+i.g);break;case 4:f=$wnd.Math.max(f,i.j+i.f);}}else{switch(l.g){case 1:d+=i.g+2;break;case 2:c+=i.f+2;break;case 3:e+=i.g+2;break;case 4:f+=i.f+2;}}}h=$wnd.Math.max(d,e);g=$wnd.Math.max(c,f)}return Esd(a,h,g,true,true)} +function Rqc(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;s=RD(zDb(PDb(CDb(new SDb(null,new Swb(b.d,16)),new Vqc(c)),new Xqc(c)),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[(xBb(),vBb)]))),15);l=lve;k=qwe;for(i=new Anb(b.b.j);i.a0;if(j){if(j){m=r.p;g?++m:--m;l=RD(Vmb(r.c.a,m),10);d=Z7b(l);n=!(Did(d,w,c[0])||yid(d,w,c[0]))}}else{n=true}}o=false;v=b.D.i;if(!!v&&!!v.c&&h.e){k=g&&v.p>0||!g&&v.p=0){i=null;h=new Jkb(k.a,j+1);while(h.bg?1:cz(isNaN(0),isNaN(g)))<0&&(null,bz(vEe),($wnd.Math.abs(g-1)<=vEe||g==1||isNaN(g)&&isNaN(1)?0:g<1?-1:g>1?1:cz(isNaN(g),isNaN(1)))<0)&&(null,bz(vEe),($wnd.Math.abs(0-h)<=vEe||0==h||isNaN(0)&&isNaN(h)?0:0h?1:cz(isNaN(0),isNaN(h)))<0)&&(null,bz(vEe),($wnd.Math.abs(h-1)<=vEe||h==1||isNaN(h)&&isNaN(1)?0:h<1?-1:h>1?1:cz(isNaN(h),isNaN(1)))<0));return f} +function EXd(b){var c,d,e,f;d=b.D!=null?b.D:b.B;c=qhb(d,Fhb(91));if(c!=-1){e=(AFb(0,c,d.length),d.substr(0,c));f=new Qhb;do f.a+='[';while((c=phb(d,91,++c))!=-1);if(lhb(e,hve))f.a+='Z';else if(lhb(e,dKe))f.a+='B';else if(lhb(e,eKe))f.a+='C';else if(lhb(e,fKe))f.a+='D';else if(lhb(e,gKe))f.a+='F';else if(lhb(e,hKe))f.a+='I';else if(lhb(e,iKe))f.a+='J';else if(lhb(e,jKe))f.a+='S';else{f.a+='L';f.a+=''+e;f.a+=';'}try{return null}catch(a){a=zdb(a);if(!ZD(a,63))throw Adb(a)}}else if(qhb(d,Fhb(46))==-1){if(lhb(d,hve))return xdb;else if(lhb(d,dKe))return gE;else if(lhb(d,eKe))return hE;else if(lhb(d,fKe))return iE;else if(lhb(d,gKe))return jE;else if(lhb(d,hKe))return kE;else if(lhb(d,iKe))return lE;else if(lhb(d,jKe))return wdb}return null} +function pTb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A;a.e=b;h=RSb(b);w=new bnb;for(d=new Anb(h);d.a=0&&p=j.c.c.length?(k=hOc((r3b(),p3b),o3b)):(k=hOc((r3b(),o3b),o3b));k*=2;f=c.a.g;c.a.g=$wnd.Math.max(f,f+(k-f));g=c.b.g;c.b.g=$wnd.Math.max(g,g+(k-g));e=b}}} +function qkc(a){var b,c,d,e;FDb(CDb(new SDb(null,new Swb(a.a.b,16)),new Qkc),new Skc);okc(a);FDb(CDb(new SDb(null,new Swb(a.a.b,16)),new Ukc),new Wkc);if(a.c==(Ymd(),Wmd)){FDb(CDb(EDb(new SDb(null,new Swb(new Xkb(a.f),1)),new clc),new elc),new glc(a));FDb(CDb(GDb(EDb(EDb(new SDb(null,new Swb(a.d.b,16)),new klc),new mlc),new olc),new qlc),new slc(a))}e=new rjd(oxe,oxe);b=new rjd(pxe,pxe);for(d=new Anb(a.a.b);d.a0&&(b.a+=pve,b);Csd(RD(bMd(h),167),b)}b.a+=SAe;i=new mMd((!d.c&&(d.c=new Yie(E4,d,5,8)),d.c));while(i.e!=i.i.gc()){i.e>0&&(b.a+=pve,b);Csd(RD(bMd(i),167),b)}b.a+=')'}}} +function LTb(a,b,c){var d,e,f,g,h,i,j,k;for(i=new dMd((!a.a&&(a.a=new C5d(J4,a,10,11)),a.a));i.e!=i.i.gc();){h=RD(bMd(i),27);for(e=new is(Mr(zGd(h).a.Kc(),new ir));gs(e);){d=RD(hs(e),74);!d.b&&(d.b=new Yie(E4,d,4,7));if(!(d.b.i<=1&&(!d.c&&(d.c=new Yie(E4,d,5,8)),d.c.i<=1))){throw Adb(new Ked('Graph must not contain hyperedges.'))}if(!nzd(d)&&h!=AGd(RD(QHd((!d.c&&(d.c=new Yie(E4,d,5,8)),d.c),0),84))){j=new cUb;kQb(j,d);pQb(j,(JVb(),HVb),d);_Tb(j,RD(Wd(qtb(c.f,h)),153));aUb(j,RD(Wjb(c,AGd(RD(QHd((!d.c&&(d.c=new Yie(E4,d,5,8)),d.c),0),84))),153));Rmb(b.c,j);for(g=new dMd((!d.n&&(d.n=new C5d(I4,d,1,7)),d.n));g.e!=g.i.gc();){f=RD(bMd(g),135);k=new iUb(j,f.a);kQb(k,f);pQb(k,HVb,f);k.e.a=$wnd.Math.max(f.g,1);k.e.b=$wnd.Math.max(f.f,1);hUb(k);Rmb(b.d,k)}}}}} +function Vec(a,b,c){var d,e,f,g,h,i,j,k,l,m;c.Ug('Node promotion heuristic',1);a.i=b;a.r=RD(mQb(b,(yCc(),ZAc)),243);a.r!=(aEc(),TDc)&&a.r!=UDc?Tec(a):Uec(a);k=RD(mQb(a.i,YAc),17).a;f=new nfc;switch(a.r.g){case 2:case 1:Yec(a,f);break;case 3:a.r=_Dc;Yec(a,f);i=0;for(h=new Anb(a.b);h.aa.k){a.r=VDc;Yec(a,f)}break;case 4:a.r=_Dc;Yec(a,f);j=0;for(e=new Anb(a.c);e.aa.n){a.r=YDc;Yec(a,f)}break;case 6:m=eE($wnd.Math.ceil(a.g.length*k/100));Yec(a,new qfc(m));break;case 5:l=eE($wnd.Math.ceil(a.e*k/100));Yec(a,new tfc(l));break;case 8:Sec(a,true);break;case 9:Sec(a,false);break;default:Yec(a,f);}a.r!=TDc&&a.r!=UDc?Zec(a,b):$ec(a,b);c.Vg()} +function $rc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;l=a.b;k=new Jkb(l,0);Ikb(k,new R4b(a));s=false;g=1;while(k.b0){m.d+=k.n.d;m.d+=k.d}if(m.a>0){m.a+=k.n.a;m.a+=k.d}if(m.b>0){m.b+=k.n.b;m.b+=k.d}if(m.c>0){m.c+=k.n.c;m.c+=k.d}return m} +function u9b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o;m=c.d;l=c.c;f=new rjd(c.f.a+c.d.b+c.d.c,c.f.b+c.d.d+c.d.a);g=f.b;for(j=new Anb(a.a);j.a0){a.c[b.c.p][b.p].d+=Kwb(a.i,24)*Nxe*0.07000000029802322-0.03500000014901161;a.c[b.c.p][b.p].a=a.c[b.c.p][b.p].d/a.c[b.c.p][b.p].b}} +function D8b(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;for(o=new Anb(a);o.ad.d;d.d=$wnd.Math.max(d.d,b);if(h&&c){d.d=$wnd.Math.max(d.d,d.a);d.a=d.d+e}break;case 3:c=b>d.a;d.a=$wnd.Math.max(d.a,b);if(h&&c){d.a=$wnd.Math.max(d.a,d.d);d.d=d.a+e}break;case 2:c=b>d.c;d.c=$wnd.Math.max(d.c,b);if(h&&c){d.c=$wnd.Math.max(d.b,d.c);d.b=d.c+e}break;case 4:c=b>d.b;d.b=$wnd.Math.max(d.b,b);if(h&&c){d.b=$wnd.Math.max(d.b,d.c);d.c=d.b+e}}}}} +function pA(a,b){var c,d,e,f,g,h,i,j,k;j='';if(b.length==0){return a.ne(ywe,wwe,-1,-1)}k=Dhb(b);lhb(k.substr(0,3),'at ')&&(k=(BFb(3,k.length+1),k.substr(3)));k=k.replace(/\[.*?\]/g,'');g=k.indexOf('(');if(g==-1){g=k.indexOf('@');if(g==-1){j=k;k=''}else{j=Dhb((BFb(g+1,k.length+1),k.substr(g+1)));k=Dhb((AFb(0,g,k.length),k.substr(0,g)))}}else{c=k.indexOf(')',g);j=(AFb(g+1,c,k.length),k.substr(g+1,c-(g+1)));k=Dhb((AFb(0,g,k.length),k.substr(0,g)))}g=qhb(k,Fhb(46));g!=-1&&(k=(BFb(g+1,k.length+1),k.substr(g+1)));(k.length==0||lhb(k,'Anonymous function'))&&(k=wwe);h=thb(j,Fhb(58));e=uhb(j,Fhb(58),h-1);i=-1;d=-1;f=ywe;if(h!=-1&&e!=-1){f=(AFb(0,e,j.length),j.substr(0,e));i=jA((AFb(e+1,h,j.length),j.substr(e+1,h-(e+1))));d=jA((BFb(h+1,j.length+1),j.substr(h+1)))}return a.ne(f,k,i,d)} +function C6b(a){var b,c,d,e,f,g,h,i,j,k,l;for(j=new Anb(a);j.a0||k.j==ppd&&k.e.c.length-k.g.c.length<0)){b=false;break}for(e=new Anb(k.g);e.a=j&&v>=q){m+=o.n.b+p.n.b+p.a.b-u;++h}}}}if(c){for(g=new Anb(s.e);g.a=j&&v>=q){m+=o.n.b+p.n.b+p.a.b-u;++h}}}}}if(h>0){w+=m/h;++n}}if(n>0){b.a=e*w/n;b.g=n}else{b.a=0;b.g=0}} +function hTb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A;f=a.f.b;m=f.a;k=f.b;o=a.e.g;n=a.e.f;zyd(a.e,f.a,f.b);w=m/o;A=k/n;for(j=new dMd(iyd(a.e));j.e!=j.i.gc();){i=RD(bMd(j),135);Dyd(i,i.i*w);Eyd(i,i.j*A)}for(s=new dMd(wCd(a.e));s.e!=s.i.gc();){r=RD(bMd(s),123);u=r.i;v=r.j;u>0&&Dyd(r,u*w);v>0&&Eyd(r,v*A)}Bvb(a.b,new tTb);b=new bnb;for(h=new vkb((new mkb(a.c)).a);h.b;){g=tkb(h);d=RD(g.ld(),74);c=RD(g.md(),407).a;e=IGd(d,false,false);l=fTb(JGd(d),ssd(e),c);lsd(l,e);t=KGd(d);if(!!t&&Wmb(b,t,0)==-1){ZEb(b.c,t);gTb(t,(sFb(l.b!=0),RD(l.a.a.c,8)),c)}}for(q=new vkb((new mkb(a.d)).a);q.b;){p=tkb(q);d=RD(p.ld(),74);c=RD(p.md(),407).a;e=IGd(d,false,false);l=fTb(LGd(d),Ijd(ssd(e)),c);l=Ijd(l);lsd(l,e);t=MGd(d);if(!!t&&Wmb(b,t,0)==-1){ZEb(b.c,t);gTb(t,(sFb(l.b!=0),RD(l.c.b.c,8)),c)}}} +function GJb(a,b,c,d){var e,f,g,h,i;h=new CLb(b);iNb(h,d);e=true;if(!!a&&a.pf((umd(),Nkd))){f=RD(a.of((umd(),Nkd)),88);e=f==(Cmd(),Amd)||f==ymd||f==zmd}$Mb(h,false);Umb(h.e.Rf(),new dNb(h,false,e));EMb(h,h.f,(ZJb(),WJb),(qpd(),Yod));EMb(h,h.f,YJb,npd);EMb(h,h.g,WJb,ppd);EMb(h,h.g,YJb,Xod);GMb(h,Yod);GMb(h,npd);FMb(h,Xod);FMb(h,ppd);RMb();g=h.A.Hc((Qpd(),Mpd))&&h.B.Hc((dqd(),$pd))?SMb(h):null;!!g&&uKb(h.a,g);XMb(h);xMb(h);GNb(h);sMb(h);gNb(h);yNb(h);oNb(h,Yod);oNb(h,npd);tMb(h);fNb(h);if(!c){return h.o}VMb(h);CNb(h);oNb(h,Xod);oNb(h,ppd);i=h.B.Hc((dqd(),_pd));IMb(h,i,Yod);IMb(h,i,npd);JMb(h,i,Xod);JMb(h,i,ppd);FDb(new SDb(null,new Swb(new glb(h.i),0)),new KMb);FDb(CDb(new SDb(null,ki(h.r).a.oc()),new MMb),new OMb);WMb(h);h.e.Pf(h.o);FDb(new SDb(null,ki(h.r).a.oc()),new YMb);return h.o} +function LYb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;j=oxe;for(d=new Anb(a.a.b);d.a1){n=new xVc(o,t,d);xgb(t,new nVc(a,n));ZEb(g.c,n);for(l=t.a.ec().Kc();l.Ob();){k=RD(l.Pb(),42);Ymb(f,k.b)}}if(h.a.gc()>1){n=new xVc(o,h,d);xgb(h,new pVc(a,n));ZEb(g.c,n);for(l=h.a.ec().Kc();l.Ob();){k=RD(l.Pb(),42);Ymb(f,k.b)}}}} +function p6b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;p=a.n;q=a.o;m=a.d;l=Kfb(UD(hFc(a,(yCc(),QBc))));if(b){k=l*(b.gc()-1);n=0;for(i=b.Kc();i.Ob();){g=RD(i.Pb(),10);k+=g.o.a;n=$wnd.Math.max(n,g.o.b)}r=p.a-(k-q.a)/2;f=p.b-m.d+n;d=q.a/(b.gc()+1);e=d;for(h=b.Kc();h.Ob();){g=RD(h.Pb(),10);g.n.a=r;g.n.b=f-g.o.b;r+=g.o.a+l;j=n6b(g);j.n.a=g.o.a/2-j.a.a;j.n.b=g.o.b;o=RD(mQb(g,(Ywc(),Xvc)),12);if(o.e.c.length+o.g.c.length==1){o.n.a=e-o.a.a;o.n.b=0;P3b(o,a)}e+=d}}if(c){k=l*(c.gc()-1);n=0;for(i=c.Kc();i.Ob();){g=RD(i.Pb(),10);k+=g.o.a;n=$wnd.Math.max(n,g.o.b)}r=p.a-(k-q.a)/2;f=p.b+q.b+m.a-n;d=q.a/(c.gc()+1);e=d;for(h=c.Kc();h.Ob();){g=RD(h.Pb(),10);g.n.a=r;g.n.b=f;r+=g.o.a+l;j=n6b(g);j.n.a=g.o.a/2-j.a.a;j.n.b=0;o=RD(mQb(g,(Ywc(),Xvc)),12);if(o.e.c.length+o.g.c.length==1){o.n.a=e-o.a.a;o.n.b=q.b;P3b(o,a)}e+=d}}} +function Hac(a,b){var c,d,e,f,g,h;if(!RD(mQb(b,(Ywc(),kwc)),21).Hc((ovc(),hvc))){return}for(h=new Anb(b.a);h.a=0&&g0&&(RD(Vrb(a.b,b),127).a.b=c)} +function wcc(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p;m=Kfb(UD(mQb(a,(yCc(),_Bc))));n=Kfb(UD(mQb(a,aCc)));l=Kfb(UD(mQb(a,ZBc)));h=a.o;f=RD(Vmb(a.j,0),12);g=f.n;p=ucc(f,l);if(!p){return}if(b.Hc((Pod(),Lod))){switch(RD(mQb(a,(Ywc(),hwc)),64).g){case 1:p.c=(h.a-p.b)/2-g.a;p.d=n;break;case 3:p.c=(h.a-p.b)/2-g.a;p.d=-n-p.a;break;case 2:if(c&&f.e.c.length==0&&f.g.c.length==0){k=d?p.a:RD(Vmb(f.f,0),72).o.b;p.d=(h.b-k)/2-g.b}else{p.d=h.b+n-g.b}p.c=-m-p.b;break;case 4:if(c&&f.e.c.length==0&&f.g.c.length==0){k=d?p.a:RD(Vmb(f.f,0),72).o.b;p.d=(h.b-k)/2-g.b}else{p.d=h.b+n-g.b}p.c=m;}}else if(b.Hc(Nod)){switch(RD(mQb(a,(Ywc(),hwc)),64).g){case 1:case 3:p.c=g.a+m;break;case 2:case 4:if(c&&!f.c){k=d?p.a:RD(Vmb(f.f,0),72).o.b;p.d=(h.b-k)/2-g.b}else{p.d=g.b+n}}}e=p.d;for(j=new Anb(f.f);j.a=b.length)return {done:true};var a=b[d++];return {value:[a,c.get(a)],done:false}}}};if(!Ftb()){e.prototype.createObject=function(){return {}};e.prototype.get=function(a){return this.obj[':'+a]};e.prototype.set=function(a,b){this.obj[':'+a]=b};e.prototype[Jxe]=function(a){delete this.obj[':'+a]};e.prototype.keys=function(){var a=[];for(var b in this.obj){b.charCodeAt(0)==58&&a.push(b.substring(1))}return a}}return e} +function q$c(){q$c=geb;h$c=new jGd(rAe);new jGd(sAe);new kGd('DEPTH',sgb(0));XZc=new kGd('FAN',sgb(0));VZc=new kGd(QEe,sgb(0));n$c=new kGd('ROOT',(Geb(),false));b$c=new kGd('LEFTNEIGHBOR',null);l$c=new kGd('RIGHTNEIGHBOR',null);c$c=new kGd('LEFTSIBLING',null);m$c=new kGd('RIGHTSIBLING',null);WZc=new kGd('DUMMY',false);new kGd('LEVEL',sgb(0));k$c=new kGd('REMOVABLE_EDGES',new Yub);o$c=new kGd('XCOOR',sgb(0));p$c=new kGd('YCOOR',sgb(0));d$c=new kGd('LEVELHEIGHT',0);f$c=new kGd('LEVELMIN',0);e$c=new kGd('LEVELMAX',0);ZZc=new kGd('GRAPH_XMIN',0);_Zc=new kGd('GRAPH_YMIN',0);YZc=new kGd('GRAPH_XMAX',0);$Zc=new kGd('GRAPH_YMAX',0);UZc=new kGd('COMPACT_LEVEL_ASCENSION',false);TZc=new kGd('COMPACT_CONSTRAINTS',new bnb);a$c=new kGd('ID','');i$c=new kGd('POSITION',sgb(0));j$c=new kGd('PRELIM',0);g$c=new kGd('MODIFIER',0);SZc=new jGd(tAe);RZc=new jGd(uAe)} +function Bqe(a){zqe();var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;if(a==null)return null;l=a.length*8;if(l==0){return ''}h=l%24;n=l/24|0;m=h!=0?n+1:n;f=null;f=$C(hE,zwe,28,m*4,15,1);j=0;k=0;b=0;c=0;d=0;g=0;e=0;for(i=0;i>24;j=(b&3)<<24>>24;o=(b&-128)==0?b>>2<<24>>24:(b>>2^192)<<24>>24;p=(c&-128)==0?c>>4<<24>>24:(c>>4^240)<<24>>24;q=(d&-128)==0?d>>6<<24>>24:(d>>6^252)<<24>>24;f[g++]=yqe[o];f[g++]=yqe[p|j<<4];f[g++]=yqe[k<<2|q];f[g++]=yqe[d&63]}if(h==8){b=a[e];j=(b&3)<<24>>24;o=(b&-128)==0?b>>2<<24>>24:(b>>2^192)<<24>>24;f[g++]=yqe[o];f[g++]=yqe[j<<4];f[g++]=61;f[g++]=61}else if(h==16){b=a[e];c=a[e+1];k=(c&15)<<24>>24;j=(b&3)<<24>>24;o=(b&-128)==0?b>>2<<24>>24:(b>>2^192)<<24>>24;p=(c&-128)==0?c>>4<<24>>24:(c>>4^240)<<24>>24;f[g++]=yqe[o];f[g++]=yqe[p|j<<4];f[g++]=yqe[k<<2];f[g++]=61}return Ihb(f,0,f.length)} +function CB(a,b){var c,d,e,f,g,h,i;a.e==0&&a.p>0&&(a.p=-(a.p-1));a.p>qwe&&tB(b,a.p-Owe);g=b.q.getDate();nB(b,1);a.k>=0&&qB(b,a.k);if(a.c>=0){nB(b,a.c)}else if(a.k>=0){i=new vB(b.q.getFullYear()-Owe,b.q.getMonth(),35);d=35-i.q.getDate();nB(b,$wnd.Math.min(d,g))}else{nB(b,g)}a.f<0&&(a.f=b.q.getHours());a.b>0&&a.f<12&&(a.f+=12);oB(b,a.f==24&&a.g?0:a.f);a.j>=0&&pB(b,a.j);a.n>=0&&rB(b,a.n);a.i>=0&&sB(b,Bdb(Ndb(Fdb(Hdb(b.q.getTime()),Awe),Awe),a.i));if(a.a){e=new uB;tB(e,e.q.getFullYear()-Owe-80);Ldb(Hdb(b.q.getTime()),Hdb(e.q.getTime()))&&tB(b,e.q.getFullYear()-Owe+100)}if(a.d>=0){if(a.c==-1){c=(7+a.d-b.q.getDay())%7;c>3&&(c-=7);h=b.q.getMonth();nB(b,b.q.getDate()+c);b.q.getMonth()!=h&&nB(b,b.q.getDate()+(c>0?-7:7))}else{if(b.q.getDay()!=a.d){return false}}}if(a.o>qwe){f=b.q.getTimezoneOffset();sB(b,Bdb(Hdb(b.q.getTime()),(a.o-f)*60*Awe))}return true} +function J5b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;e=mQb(b,(Ywc(),Awc));if(!ZD(e,207)){return}o=RD(e,27);p=b.e;m=new sjd(b.c);f=b.d;m.a+=f.b;m.b+=f.d;u=RD(Gxd(o,(yCc(),oBc)),181);if(Csb(u,(dqd(),Xpd))){n=RD(Gxd(o,qBc),107);E2b(n,f.a);H2b(n,f.d);F2b(n,f.b);G2b(n,f.c)}c=new bnb;for(k=new Anb(b.a);k.ad.c.length-1){Rmb(d,new Ptd(Hze,KEe))}c=RD(mQb(e,f_c),17).a;if(Dmd(RD(mQb(a,H$c),88))){e.e.aKfb(UD((tFb(c,d.c.length),RD(d.c[c],42)).b))&&Otd((tFb(c,d.c.length),RD(d.c[c],42)),e.e.a+e.f.a)}else{e.e.bKfb(UD((tFb(c,d.c.length),RD(d.c[c],42)).b))&&Otd((tFb(c,d.c.length),RD(d.c[c],42)),e.e.b+e.f.b)}}for(f=Sub(a.b,0);f.b!=f.d.c;){e=RD(evb(f),40);c=RD(mQb(e,(h_c(),f_c)),17).a;pQb(e,(q$c(),f$c),UD((tFb(c,d.c.length),RD(d.c[c],42)).a));pQb(e,e$c,UD((tFb(c,d.c.length),RD(d.c[c],42)).b))}b.Vg()} +function Tec(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;a.o=Kfb(UD(mQb(a.i,(yCc(),bCc))));a.f=Kfb(UD(mQb(a.i,XBc)));a.j=a.i.b.c.length;h=a.j-1;m=0;a.k=0;a.n=0;a.b=dv($C(bJ,Nve,17,a.j,0,1));a.c=dv($C(VI,Nve,345,a.j,7,1));for(g=new Anb(a.i.b);g.a0&&Rmb(a.q,k);Rmb(a.p,k)}b-=d;n=i+b;j+=b*a.f;$mb(a.b,h,sgb(n));$mb(a.c,h,j);a.k=$wnd.Math.max(a.k,n);a.n=$wnd.Math.max(a.n,j);a.e+=b;b+=p}} +function qpd(){qpd=geb;var a;opd=new upd(Sye,0);Yod=new upd(_ye,1);Xod=new upd(aze,2);npd=new upd(bze,3);ppd=new upd(cze,4);bpd=(yob(),new Lqb((a=RD(mfb(E3),9),new Fsb(a,RD(WEb(a,a.length),9),0))));cpd=eq(ysb(Yod,cD(WC(E3,1),NAe,64,0,[])));Zod=eq(ysb(Xod,cD(WC(E3,1),NAe,64,0,[])));kpd=eq(ysb(npd,cD(WC(E3,1),NAe,64,0,[])));mpd=eq(ysb(ppd,cD(WC(E3,1),NAe,64,0,[])));hpd=eq(ysb(Yod,cD(WC(E3,1),NAe,64,0,[npd])));apd=eq(ysb(Xod,cD(WC(E3,1),NAe,64,0,[ppd])));jpd=eq(ysb(Yod,cD(WC(E3,1),NAe,64,0,[ppd])));dpd=eq(ysb(Yod,cD(WC(E3,1),NAe,64,0,[Xod])));lpd=eq(ysb(npd,cD(WC(E3,1),NAe,64,0,[ppd])));$od=eq(ysb(Xod,cD(WC(E3,1),NAe,64,0,[npd])));gpd=eq(ysb(Yod,cD(WC(E3,1),NAe,64,0,[Xod,ppd])));_od=eq(ysb(Xod,cD(WC(E3,1),NAe,64,0,[npd,ppd])));ipd=eq(ysb(Yod,cD(WC(E3,1),NAe,64,0,[npd,ppd])));epd=eq(ysb(Yod,cD(WC(E3,1),NAe,64,0,[Xod,npd])));fpd=eq(ysb(Yod,cD(WC(E3,1),NAe,64,0,[Xod,npd,ppd])))} +function Gfc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A;b.Ug(qBe,1);p=new bnb;w=new bnb;for(j=new Anb(a.b);j.a0&&(t-=n);p2b(g,t);k=0;for(m=new Anb(g.a);m.a0);h.a.Xb(h.c=--h.b)}i=0.4*d*k;!f&&h.b0){j=(BFb(0,c.length),c.charCodeAt(0));if(j!=64){if(j==37){m=c.lastIndexOf('%');k=false;if(m!=0&&(m==n-1||(k=(BFb(m+1,c.length),c.charCodeAt(m+1)==46)))){h=(AFb(1,m,c.length),c.substr(1,m-1));u=lhb('%',h)?null:oSd(h);e=0;if(k){try{e=Oeb((BFb(m+2,c.length+1),c.substr(m+2)),qwe,lve)}catch(a){a=zdb(a);if(ZD(a,130)){i=a;throw Adb(new RSd(i))}else throw Adb(a)}}for(r=P2d(b.Gh());r.Ob();){p=k3d(r);if(ZD(p,519)){f=RD(p,598);t=f.d;if((u==null?t==null:lhb(u,t))&&e--==0){return f}}}return null}}l=c.lastIndexOf('.');o=l==-1?c:(AFb(0,l,c.length),c.substr(0,l));d=0;if(l!=-1){try{d=Oeb((BFb(l+1,c.length+1),c.substr(l+1)),qwe,lve)}catch(a){a=zdb(a);if(ZD(a,130)){o=c}else throw Adb(a)}}o=lhb('%',o)?null:oSd(o);for(q=P2d(b.Gh());q.Ob();){p=k3d(q);if(ZD(p,197)){g=RD(p,197);s=g.xe();if((o==null?s==null:lhb(o,s))&&d--==0){return g}}}return null}}return Pvd(b,c)} +function Hlc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;k=new Tsb;i=new Tp;for(d=new Anb(a.a.a.b);d.ab.d.c){n=a.c[b.a.d];q=a.c[l.a.d];if(n==q){continue}rIb(uIb(tIb(vIb(sIb(new wIb,1),100),n),q))}}}}}}} +function mNb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;m=RD(RD(Qc(a.r,b),21),87);if(b==(qpd(),Xod)||b==ppd){qNb(a,b);return}f=b==Yod?(mOb(),iOb):(mOb(),lOb);u=b==Yod?(vLb(),uLb):(vLb(),sLb);c=RD(Vrb(a.b,b),127);d=c.i;e=d.c+Hid(cD(WC(iE,1),vxe,28,15,[c.n.b,a.C.b,a.k]));r=d.c+d.b-Hid(cD(WC(iE,1),vxe,28,15,[c.n.c,a.C.c,a.k]));g=WNb(_Nb(f),a.t);s=b==Yod?pxe:oxe;for(l=m.Kc();l.Ob();){j=RD(l.Pb(),117);if(!j.c||j.c.d.c.length<=0){continue}q=j.b.Mf();p=j.e;n=j.c;o=n.i;o.b=(i=n.n,n.e.a+i.b+i.c);o.a=(h=n.n,n.e.b+h.d+h.a);Ivb(u,Pye);n.f=u;RKb(n,(EKb(),DKb));o.c=p.a-(o.b-q.a)/2;v=$wnd.Math.min(e,p.a);w=$wnd.Math.max(r,p.a+q.a);o.cw&&(o.c=w-o.b);Rmb(g.d,new sOb(o,UNb(g,o)));s=b==Yod?$wnd.Math.max(s,p.b+j.b.Mf().b):$wnd.Math.min(s,p.b)}s+=b==Yod?a.t:-a.t;t=VNb((g.e=s,g));t>0&&(RD(Vrb(a.b,b),127).a.b=t);for(k=m.Kc();k.Ob();){j=RD(k.Pb(),117);if(!j.c||j.c.d.c.length<=0){continue}o=j.c.i;o.c-=j.e.a;o.d-=j.e.b}} +function JSb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n;b=new Tsb;for(i=new dMd(a);i.e!=i.i.gc();){h=RD(bMd(i),27);c=new _sb;Zjb(FSb,h,c);n=new TSb;e=RD(zDb(new SDb(null,new Twb(new is(Mr(yGd(h).a.Kc(),new ir)))),OBb(n,tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[(xBb(),vBb)])))),85);ISb(c,RD(e.xc((Geb(),true)),16),new VSb);d=RD(zDb(CDb(RD(e.xc(false),15).Lc(),new XSb),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[vBb]))),15);for(g=d.Kc();g.Ob();){f=RD(g.Pb(),74);m=KGd(f);if(m){j=RD(Wd(qtb(b.f,m)),21);if(!j){j=LSb(m);rtb(b.f,m,j)}ye(c,j)}}e=RD(zDb(new SDb(null,new Twb(new is(Mr(zGd(h).a.Kc(),new ir)))),OBb(n,tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[vBb])))),85);ISb(c,RD(e.xc(true),16),new ZSb);d=RD(zDb(CDb(RD(e.xc(false),15).Lc(),new _Sb),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[vBb]))),15);for(l=d.Kc();l.Ob();){k=RD(l.Pb(),74);m=MGd(k);if(m){j=RD(Wd(qtb(b.f,m)),21);if(!j){j=LSb(m);rtb(b.f,m,j)}ye(c,j)}}}} +function zjb(a,b){xjb();var c,d,e,f,g,h,i,j,k,l,m,n,o,p;i=Ddb(a,0)<0;i&&(a=Odb(a));if(Ddb(a,0)==0){switch(b){case 0:return '0';case 1:return zxe;case 2:return '0.00';case 3:return '0.000';case 4:return '0.0000';case 5:return '0.00000';case 6:return '0.000000';default:n=new bib;b<0?(n.a+='0E+',n):(n.a+='0E',n);n.a+=b==qwe?'2147483648':''+-b;return n.a;}}k=18;l=$C(hE,zwe,28,k+1,15,1);c=k;p=a;do{j=p;p=Fdb(p,10);l[--c]=Ydb(Bdb(48,Vdb(j,Ndb(p,10))))&Bwe}while(Ddb(p,0)!=0);e=Vdb(Vdb(Vdb(k,c),b),1);if(b==0){i&&(l[--c]=45);return Ihb(l,c,k-c)}if(b>0&&Ddb(e,-6)>=0){if(Ddb(e,0)>=0){f=c+Ydb(e);for(h=k-1;h>=f;h--){l[h+1]=l[h]}l[++f]=46;i&&(l[--c]=45);return Ihb(l,c,k-c+1)}for(g=2;Ldb(g,Bdb(Odb(e),1));g++){l[--c]=48}l[--c]=46;l[--c]=48;i&&(l[--c]=45);return Ihb(l,c,k-c)}o=c+1;d=k;m=new cib;i&&(m.a+='-',m);if(d-o>=1){Thb(m,l[c]);m.a+='.';m.a+=Ihb(l,c+1,k-c-1)}else{m.a+=Ihb(l,c,k-c)}m.a+='E';Ddb(e,0)>0&&(m.a+='+',m);m.a+=''+Zdb(e);return m.a} +function Esd(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;q=new rjd(a.g,a.f);p=vsd(a);p.a=$wnd.Math.max(p.a,b);p.b=$wnd.Math.max(p.b,c);w=p.a/q.a;k=p.b/q.b;u=p.a-q.a;i=p.b-q.b;if(d){g=!vCd(a)?RD(Gxd(a,(umd(),Nkd)),88):RD(Gxd(vCd(a),(umd(),Nkd)),88);h=dE(Gxd(a,(umd(),Hld)))===dE((Bod(),wod));for(s=new dMd((!a.c&&(a.c=new C5d(K4,a,9,9)),a.c));s.e!=s.i.gc();){r=RD(bMd(s),123);t=RD(Gxd(r,Old),64);if(t==(qpd(),opd)){t=osd(r,g);Ixd(r,Old,t)}switch(t.g){case 1:h||Dyd(r,r.i*w);break;case 2:Dyd(r,r.i+u);h||Eyd(r,r.j*k);break;case 3:h||Dyd(r,r.i*w);Eyd(r,r.j+i);break;case 4:h||Eyd(r,r.j*k);}}}zyd(a,p.a,p.b);if(e){for(m=new dMd((!a.n&&(a.n=new C5d(I4,a,1,7)),a.n));m.e!=m.i.gc();){l=RD(bMd(m),135);n=l.i+l.g/2;o=l.j+l.f/2;v=n/q.a;j=o/q.b;if(v+j>=1){if(v-j>0&&o>=0){Dyd(l,l.i+u);Eyd(l,l.j+i*j)}else if(v-j<0&&n>=0){Dyd(l,l.i+u*v);Eyd(l,l.j+i)}}}}Ixd(a,(umd(),kld),(Qpd(),f=RD(mfb(H3),9),new Fsb(f,RD(WEb(f,f.length),9),0)));return new rjd(w,k)} +function _4c(a){Cgd(a,new Pfd(Wfd($fd(Xfd(Zfd(Yfd(new agd,CFe),'ELK Radial'),'A radial layout provider which is based on the algorithm of Peter Eades published in "Drawing free trees.", published by International Institute for Advanced Study of Social Information Science, Fujitsu Limited in 1991. The radial layouter takes a tree and places the nodes in radial order around the root. The nodes of the same tree level are placed on the same radius.'),new c5c),CFe)));Agd(a,CFe,fEe,iGd(R4c));Agd(a,CFe,_ze,iGd(Y4c));Agd(a,CFe,jAe,iGd(K4c));Agd(a,CFe,CAe,iGd(L4c));Agd(a,CFe,iAe,iGd(M4c));Agd(a,CFe,kAe,iGd(J4c));Agd(a,CFe,gAe,iGd(N4c));Agd(a,CFe,lAe,iGd(Q4c));Agd(a,CFe,tFe,iGd(H4c));Agd(a,CFe,sFe,iGd(I4c));Agd(a,CFe,rFe,iGd(T4c));Agd(a,CFe,xFe,iGd(W4c));Agd(a,CFe,yFe,iGd(U4c));Agd(a,CFe,zFe,iGd(V4c));Agd(a,CFe,wFe,iGd(O4c));Agd(a,CFe,pFe,iGd(P4c));Agd(a,CFe,qFe,iGd(S4c));Agd(a,CFe,uFe,iGd(X4c));Agd(a,CFe,vFe,iGd(Z4c));Agd(a,CFe,oFe,iGd(G4c))} +function Peb(a){var b,c,d,e,f,g,h,i,j,k,l;if(a==null){throw Adb(new Vgb(vve))}j=a;f=a.length;i=false;if(f>0){b=(BFb(0,a.length),a.charCodeAt(0));if(b==45||b==43){a=(BFb(1,a.length+1),a.substr(1));--f;i=b==45}}if(f==0){throw Adb(new Vgb(nxe+j+'"'))}while(a.length>0&&(BFb(0,a.length),a.charCodeAt(0)==48)){a=(BFb(1,a.length+1),a.substr(1));--f}if(f>(Ugb(),Sgb)[10]){throw Adb(new Vgb(nxe+j+'"'))}for(e=0;e0){l=-parseInt((AFb(0,d,a.length),a.substr(0,d)),10);a=(BFb(d,a.length+1),a.substr(d));f-=d;c=false}while(f>=g){d=parseInt((AFb(0,g,a.length),a.substr(0,g)),10);a=(BFb(g,a.length+1),a.substr(g));f-=g;if(c){c=false}else{if(Ddb(l,h)<0){throw Adb(new Vgb(nxe+j+'"'))}l=Ndb(l,k)}l=Vdb(l,d)}if(Ddb(l,0)>0){throw Adb(new Vgb(nxe+j+'"'))}if(!i){l=Odb(l);if(Ddb(l,0)<0){throw Adb(new Vgb(nxe+j+'"'))}}return l} +function oSd(a){gSd();var b,c,d,e,f,g,h,i;if(a==null)return null;e=qhb(a,Fhb(37));if(e<0){return a}else{i=new dib((AFb(0,e,a.length),a.substr(0,e)));b=$C(gE,YHe,28,4,15,1);h=0;d=0;for(g=a.length;ee+2&&zSd((BFb(e+1,a.length),a.charCodeAt(e+1)),XRd,YRd)&&zSd((BFb(e+2,a.length),a.charCodeAt(e+2)),XRd,YRd)){c=DSd((BFb(e+1,a.length),a.charCodeAt(e+1)),(BFb(e+2,a.length),a.charCodeAt(e+2)));e+=2;if(d>0){(c&192)==128?(b[h++]=c<<24>>24):(d=0)}else if(c>=128){if((c&224)==192){b[h++]=c<<24>>24;d=2}else if((c&240)==224){b[h++]=c<<24>>24;d=3}else if((c&248)==240){b[h++]=c<<24>>24;d=4}}if(d>0){if(h==d){switch(h){case 2:{Thb(i,((b[0]&31)<<6|b[1]&63)&Bwe);break}case 3:{Thb(i,((b[0]&15)<<12|(b[1]&63)<<6|b[2]&63)&Bwe);break}}h=0;d=0}}else{for(f=0;f=2){if((!a.a&&(a.a=new C5d(F4,a,6,6)),a.a).i==0){c=(bvd(),e=new Rzd,e);WGd((!a.a&&(a.a=new C5d(F4,a,6,6)),a.a),c)}else if((!a.a&&(a.a=new C5d(F4,a,6,6)),a.a).i>1){m=new mMd((!a.a&&(a.a=new C5d(F4,a,6,6)),a.a));while(m.e!=m.i.gc()){cMd(m)}}lsd(b,RD(QHd((!a.a&&(a.a=new C5d(F4,a,6,6)),a.a),0),166))}if(l){for(d=new dMd((!a.a&&(a.a=new C5d(F4,a,6,6)),a.a));d.e!=d.i.gc();){c=RD(bMd(d),166);for(j=new dMd((!c.a&&(c.a=new XZd(D4,c,5)),c.a));j.e!=j.i.gc();){i=RD(bMd(j),377);h.a=$wnd.Math.max(h.a,i.a);h.b=$wnd.Math.max(h.b,i.b)}}}for(g=new dMd((!a.n&&(a.n=new C5d(I4,a,1,7)),a.n));g.e!=g.i.gc();){f=RD(bMd(g),135);k=RD(Gxd(f,und),8);!!k&&Byd(f,k.a,k.b);if(l){h.a=$wnd.Math.max(h.a,f.i+f.g);h.b=$wnd.Math.max(h.b,f.j+f.f)}}return h} +function MA(a,b,c,d,e){var f,g,h;KA(a,b);g=b[0];f=ihb(c.c,0);h=-1;if(DA(c)){if(d>0){if(g+d>a.length){return false}h=HA((AFb(0,g+d,a.length),a.substr(0,g+d)),b)}else{h=HA(a,b)}}switch(f){case 71:h=EA(a,g,cD(WC(qJ,1),Nve,2,6,[Qwe,Rwe]),b);e.e=h;return true;case 77:return PA(a,b,e,h,g);case 76:return RA(a,b,e,h,g);case 69:return NA(a,b,g,e);case 99:return QA(a,b,g,e);case 97:h=EA(a,g,cD(WC(qJ,1),Nve,2,6,['AM','PM']),b);e.b=h;return true;case 121:return TA(a,b,g,h,c,e);case 100:if(h<=0){return false}e.c=h;return true;case 83:if(h<0){return false}return OA(h,g,b[0],e);case 104:h==12&&(h=0);case 75:case 72:if(h<0){return false}e.f=h;e.g=false;return true;case 107:if(h<0){return false}e.f=h;e.g=true;return true;case 109:if(h<0){return false}e.j=h;return true;case 115:if(h<0){return false}e.n=h;return true;case 90:if(gB[i]&&(q=i);for(l=new Anb(a.a.b);l.a1){e=N8c(b);l=f.g;o=RD(Gxd(b,N7c),107);p=Kfb(UD(Gxd(b,x7c)));(!b.a&&(b.a=new C5d(J4,b,10,11)),b.a).i>1&&Kfb(UD(Gxd(b,(X6c(),T6c))))!=oxe&&(f.c+(o.b+o.c))/(f.b+(o.d+o.a))1&&Kfb(UD(Gxd(b,(X6c(),S6c))))!=oxe&&(f.c+(o.b+o.c))/(f.b+(o.d+o.a))>p&&Ixd(e,(X6c(),W6c),$wnd.Math.max(Kfb(UD(Gxd(b,U6c))),Kfb(UD(Gxd(e,W6c)))-Kfb(UD(Gxd(b,S6c)))));n=new m9c(d,k);i=l9c(n,e,m);j=i.g;if(j>=l&&j==j){for(g=0;g<(!e.a&&(e.a=new C5d(J4,e,10,11)),e.a).i;g++){O8c(a,RD(QHd((!e.a&&(e.a=new C5d(J4,e,10,11)),e.a),g),27),RD(QHd((!b.a&&(b.a=new C5d(J4,b,10,11)),b.a),g),27))}P8c(b,n);jad(f,i.c);iad(f,i.b)}--h}Ixd(b,(X6c(),N6c),f.b);Ixd(b,O6c,f.c);c.Vg()} +function fHc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;b.Ug('Interactive node layering',1);c=new bnb;for(m=new Anb(a.a);m.a=h){sFb(s.b>0);s.a.Xb(s.c=--s.b);break}else if(q.a>i){if(!d){Rmb(q.b,k);q.c=$wnd.Math.min(q.c,i);q.a=$wnd.Math.max(q.a,h);d=q}else{Tmb(d.b,q.b);d.a=$wnd.Math.max(d.a,q.a);Ckb(s)}}}if(!d){d=new jHc;d.c=i;d.a=h;Ikb(s,d);Rmb(d.b,k)}}g=a.b;j=0;for(r=new Anb(c);r.an){if(f){Oub(w,m);Oub(B,sgb(j.b-1))}H=c.b;I+=m+b;m=0;k=$wnd.Math.max(k,c.b+c.c+G)}Dyd(h,H);Eyd(h,I);k=$wnd.Math.max(k,H+G+c.c);m=$wnd.Math.max(m,l);H+=G+b}k=$wnd.Math.max(k,d);F=I+m+c.a;if(FVze;C=$wnd.Math.abs(m.b-o.b)>Vze;(!c&&B&&C||c&&(B||C))&&Mub(q.a,u)}ye(q.a,d);d.b==0?(m=u):(m=(sFb(d.b!=0),RD(d.c.b.c,8)));j0b(n,l,p);if(I0b(e)==A){if(Y2b(A.i)!=e.a){p=new pjd;e2b(p,Y2b(A.i),s)}pQb(q,Wwc,p)}k0b(n,q,s);k.a.zc(n,k)}Y0b(q,v);Z0b(q,A)}for(j=k.a.ec().Kc();j.Ob();){i=RD(j.Pb(),18);Y0b(i,null);Z0b(i,null)}b.Vg()} +function lXc(a,b){var c,d,e,f,g,h,i,j,k,l,m;e=RD(mQb(a,(h_c(),H$c)),88);k=e==(Cmd(),ymd)||e==zmd?xmd:zmd;c=RD(zDb(CDb(new SDb(null,new Swb(a.b,16)),new $Xc),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[(xBb(),vBb)]))),15);i=RD(zDb(GDb(c.Oc(),new aYc(b)),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[vBb]))),15);i.Gc(RD(zDb(GDb(c.Oc(),new cYc(b)),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[vBb]))),16));i.jd(new eYc(k));m=new yAb(new iYc(e));d=new Tsb;for(h=i.Kc();h.Ob();){g=RD(h.Pb(),240);j=RD(g.a,40);if(Heb(TD(g.c))){m.a.zc(j,(Geb(),Eeb))==null;(new zAb(m.a.Zc(j,false))).a.gc()>0&&Zjb(d,j,RD((new zAb(m.a.Zc(j,false))).a.Vc(),40));(new zAb(m.a.ad(j,true))).a.gc()>1&&Zjb(d,nXc(m,j),j)}else{if((new zAb(m.a.Zc(j,false))).a.gc()>0){f=RD((new zAb(m.a.Zc(j,false))).a.Vc(),40);dE(f)===dE(Wd(qtb(d.f,j)))&&RD(mQb(j,(q$c(),TZc)),15).Fc(f)}if((new zAb(m.a.ad(j,true))).a.gc()>1){l=nXc(m,j);dE(Wd(qtb(d.f,l)))===dE(j)&&RD(mQb(l,(q$c(),TZc)),15).Fc(j)}m.a.Bc(j)!=null}}} +function BTb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;if(a.gc()==1){return RD(a.Xb(0),235)}else if(a.gc()<=0){return new gUb}for(e=a.Kc();e.Ob();){c=RD(e.Pb(),235);o=0;k=lve;l=lve;i=qwe;j=qwe;for(n=new Anb(c.e);n.ah){t=0;u+=g+r;g=0}ATb(p,c,t,u);b=$wnd.Math.max(b,t+q.a);g=$wnd.Math.max(g,q.b);t+=q.a+r}return p} +function Aqe(a){zqe();var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;if(a==null)return null;f=Ahb(a);o=Dqe(f);if(o%4!=0){return null}p=o/4|0;if(p==0)return $C(gE,YHe,28,0,15,1);l=null;b=0;c=0;d=0;e=0;g=0;h=0;i=0;j=0;n=0;m=0;k=0;l=$C(gE,YHe,28,p*3,15,1);for(;n>4)<<24>>24;l[m++]=((c&15)<<4|d>>2&15)<<24>>24;l[m++]=(d<<6|e)<<24>>24}if(!Cqe(g=f[k++])||!Cqe(h=f[k++])){return null}b=xqe[g];c=xqe[h];i=f[k++];j=f[k++];if(xqe[i]==-1||xqe[j]==-1){if(i==61&&j==61){if((c&15)!=0)return null;q=$C(gE,YHe,28,n*3+1,15,1);hib(l,0,q,0,n*3);q[m]=(b<<2|c>>4)<<24>>24;return q}else if(i!=61&&j==61){d=xqe[i];if((d&3)!=0)return null;q=$C(gE,YHe,28,n*3+2,15,1);hib(l,0,q,0,n*3);q[m++]=(b<<2|c>>4)<<24>>24;q[m]=((c&15)<<4|d>>2&15)<<24>>24;return q}else{return null}}else{d=xqe[i];e=xqe[j];l[m++]=(b<<2|c>>4)<<24>>24;l[m++]=((c&15)<<4|d>>2&15)<<24>>24;l[m++]=(d<<6|e)<<24>>24}return l} +function wfc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;b.Ug(qBe,1);o=RD(mQb(a,(yCc(),yAc)),223);for(e=new Anb(a.b);e.a=2){p=true;m=new Anb(f.j);c=RD(ynb(m),12);n=null;while(m.a0){d=l.gc();j=eE($wnd.Math.floor((d+1)/2))-1;e=eE($wnd.Math.ceil((d+1)/2))-1;if(b.o==DQc){for(k=e;k>=j;k--){if(b.a[u.p]==u){p=RD(l.Xb(k),42);o=RD(p.a,10);if(!Zsb(c,p.b)&&n>a.b.e[o.p]){b.a[o.p]=u;b.g[u.p]=b.g[o.p];b.a[u.p]=b.g[u.p];b.f[b.g[u.p].p]=(Geb(),Heb(b.f[b.g[u.p].p])&u.k==(r3b(),o3b)?true:false);n=a.b.e[o.p]}}}}else{for(k=j;k<=e;k++){if(b.a[u.p]==u){r=RD(l.Xb(k),42);q=RD(r.a,10);if(!Zsb(c,r.b)&&n0){e=RD(Vmb(q.c.a,w-1),10);g=a.i[e.p];B=$wnd.Math.ceil(bFc(a.n,e,q));f=v.a.e-q.d.d-(g.a.e+e.o.b+e.d.a)-B}j=oxe;if(w0&&A.a.e.e-A.a.a-(A.b.e.e-A.b.a)<0;o=t.a.e.e-t.a.a-(t.b.e.e-t.b.a)<0&&A.a.e.e-A.a.a-(A.b.e.e-A.b.a)>0;n=t.a.e.e+t.b.aA.b.e.e+A.a.a;u=0;!p&&!o&&(m?f+l>0?(u=l):j-d>0&&(u=d):n&&(f+h>0?(u=h):j-s>0&&(u=s)));v.a.e+=u;v.b&&(v.d.e+=u);return false} +function OJb(a,b,c){var d,e,f,g,h,i,j,k,l,m;d=new Uid(b.Lf().a,b.Lf().b,b.Mf().a,b.Mf().b);e=new Tid;if(a.c){for(g=new Anb(b.Rf());g.aj&&(d.a+=Hhb($C(hE,zwe,28,-j,15,1)));d.a+='Is';if(qhb(i,Fhb(32))>=0){for(e=0;e=d.o.b/2}else{s=!l}if(s){r=RD(mQb(d,(Ywc(),Xwc)),15);if(!r){f=new bnb;pQb(d,Xwc,f)}else if(m){f=r}else{e=RD(mQb(d,Vvc),15);if(!e){f=new bnb;pQb(d,Vvc,f)}else{r.gc()<=e.gc()?(f=r):(f=e)}}}else{e=RD(mQb(d,(Ywc(),Vvc)),15);if(!e){f=new bnb;pQb(d,Vvc,f)}else if(l){f=e}else{r=RD(mQb(d,Xwc),15);if(!r){f=new bnb;pQb(d,Xwc,f)}else{e.gc()<=r.gc()?(f=e):(f=r)}}}f.Fc(a);pQb(a,(Ywc(),Xvc),c);if(b.d==c){Z0b(b,null);c.e.c.length+c.g.c.length==0&&P3b(c,null);u6b(c)}else{Y0b(b,null);c.e.c.length+c.g.c.length==0&&P3b(c,null)}Xub(b.a)} +function GHc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I;c.Ug('MinWidth layering',1);n=b.b;A=b.a;I=RD(mQb(b,(yCc(),WAc)),17).a;h=RD(mQb(b,XAc),17).a;a.b=Kfb(UD(mQb(b,TBc)));a.d=oxe;for(u=new Anb(A);u.a0){j=0;!!q&&(j+=h);j+=(C-1)*g;!!t&&(j+=h);B&&!!t&&(j=$wnd.Math.max(j,JUc(t,g,s,A)));if(j=a.a){d=V9b(a,s);k=$wnd.Math.max(k,d.b);u=$wnd.Math.max(u,d.d);Rmb(h,new Ptd(s,d))}}B=new bnb;for(j=0;j0),q.a.Xb(q.c=--q.b),C=new R4b(a.b),Ikb(q,C),sFb(q.b0){m=k<100?null:new gLd(k);j=new $Hd(b);o=j.g;r=$C(kE,Pwe,28,k,15,1);d=0;u=new ZHd(k);for(e=0;e=0;){if(n!=null?pb(n,o[i]):dE(n)===dE(o[i])){if(r.length<=d){q=r;r=$C(kE,Pwe,28,2*r.length,15,1);hib(q,0,r,0,d)}r[d++]=e;WGd(u,o[i]);break v}}n=n;if(dE(n)===dE(h)){break}}}j=u;o=u.g;k=d;if(d>r.length){q=r;r=$C(kE,Pwe,28,d,15,1);hib(q,0,r,0,d)}if(d>0){t=true;for(f=0;f=0;){THd(a,r[g])}if(d!=k){for(e=k;--e>=d;){THd(j,e)}q=r;r=$C(kE,Pwe,28,d,15,1);hib(q,0,r,0,d)}b=j}}}else{b=aHd(a,b);for(e=a.i;--e>=0;){if(b.Hc(a.g[e])){THd(a,e);t=true}}}if(t){if(r!=null){c=b.gc();l=c==1?dZd(a,4,b.Kc().Pb(),null,r[0],p):dZd(a,6,b,r,r[0],p);m=c<100?null:new gLd(c);for(e=b.Kc();e.Ob();){n=e.Pb();m=oge(a,RD(n,76),m)}if(!m){qvd(a.e,l)}else{m.nj(l);m.oj()}}else{m=tLd(b.gc());for(e=b.Kc();e.Ob();){n=e.Pb();m=oge(a,RD(n,76),m)}!!m&&m.oj()}return true}else{return false}} +function i_b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;c=new p_b(b);c.a||b_b(b);j=a_b(b);i=new Tp;q=new D_b;for(p=new Anb(b.a);p.a0||c.o==DQc&&e=c} +function zEd(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G;t=b;s=new Tp;u=new Tp;k=wDd(t,mIe);d=new OEd(a,c,s,u);QDd(d.a,d.b,d.c,d.d,k);i=(A=s.i,!A?(s.i=new zf(s,s.c)):A);for(C=i.Kc();C.Ob();){B=RD(C.Pb(),166);e=RD(Qc(s,B),21);for(p=e.Kc();p.Ob();){o=p.Pb();v=RD(Ao(a.d,o),166);if(v){h=(!B.e&&(B.e=new Yie(F4,B,10,9)),B.e);WGd(h,v)}else{g=zDd(t,uIe);m=AIe+o+BIe+g;n=m+zIe;throw Adb(new CDd(n))}}}j=(w=u.i,!w?(u.i=new zf(u,u.c)):w);for(F=j.Kc();F.Ob();){D=RD(F.Pb(),166);f=RD(Qc(u,D),21);for(r=f.Kc();r.Ob();){q=r.Pb();v=RD(Ao(a.d,q),166);if(v){l=(!D.g&&(D.g=new Yie(F4,D,9,10)),D.g);WGd(l,v)}else{g=zDd(t,uIe);m=AIe+q+BIe+g;n=m+zIe;throw Adb(new CDd(n))}}}!c.b&&(c.b=new Yie(E4,c,4,7));if(c.b.i!=0&&(!c.c&&(c.c=new Yie(E4,c,5,8)),c.c.i!=0)&&(!c.b&&(c.b=new Yie(E4,c,4,7)),c.b.i<=1&&(!c.c&&(c.c=new Yie(E4,c,5,8)),c.c.i<=1))&&(!c.a&&(c.a=new C5d(F4,c,6,6)),c.a).i==1){G=RD(QHd((!c.a&&(c.a=new C5d(F4,c,6,6)),c.a),0),166);if(!Dzd(G)&&!Ezd(G)){Kzd(G,RD(QHd((!c.b&&(c.b=new Yie(E4,c,4,7)),c.b),0),84));Lzd(G,RD(QHd((!c.c&&(c.c=new Yie(E4,c,5,8)),c.c),0),84))}}} +function QNc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D;for(t=a.a,u=0,v=t.length;u0){l=RD(Vmb(m.c.a,g-1),10);B=bFc(a.b,m,l);q=m.n.b-m.d.d-(l.n.b+l.o.b+l.d.a+B)}else{q=m.n.b-m.d.d}j=$wnd.Math.min(q,j);if(g1&&(g=$wnd.Math.min(g,$wnd.Math.abs(RD(ju(h.a,1),8).b-k.b)))}}}}}else{for(p=new Anb(b.j);p.ae){f=m.a-e;g=lve;d.c.length=0;e=m.a}if(m.a>=e){ZEb(d.c,h);h.a.b>1&&(g=$wnd.Math.min(g,$wnd.Math.abs(RD(ju(h.a,h.a.b-2),8).b-m.b)))}}}}}if(d.c.length!=0&&f>b.o.a/2&&g>b.o.b/2){n=new R3b;P3b(n,b);Q3b(n,(qpd(),Yod));n.n.a=b.o.a/2;r=new R3b;P3b(r,b);Q3b(r,npd);r.n.a=b.o.a/2;r.n.b=b.o.b;for(i=new Anb(d);i.a=j.b?Y0b(h,r):Y0b(h,n)}else{j=RD(Vub(h.a),8);q=h.a.b==0?K3b(h.c):RD(Rub(h.a),8);q.b>=j.b?Z0b(h,r):Z0b(h,n)}l=RD(mQb(h,(yCc(),RAc)),75);!!l&&ze(l,j,true)}b.n.a=e-b.o.a/2}} +function E0c(a,b,c){var d,e,f,g,h,i,j,k,l,m;for(h=Sub(a.b,0);h.b!=h.d.c;){g=RD(evb(h),40);if(lhb(g.c,IEe)){continue}j=iWc(g,a);b==(Cmd(),ymd)||b==zmd?_mb(j,new D1c):_mb(j,new H1c);i=j.c.length;for(d=0;d=0?(n=vpd(h)):(n=spd(vpd(h)));a.qf(GBc,n)}j=new pjd;m=false;if(a.pf(zBc)){mjd(j,RD(a.of(zBc),8));m=true}else{ljd(j,g.a/2,g.b/2)}switch(n.g){case 4:pQb(k,UAc,(cxc(),$wc));pQb(k,bwc,(huc(),guc));k.o.b=g.b;p<0&&(k.o.a=-p);Q3b(l,(qpd(),Xod));m||(j.a=g.a);j.a-=g.a;break;case 2:pQb(k,UAc,(cxc(),axc));pQb(k,bwc,(huc(),euc));k.o.b=g.b;p<0&&(k.o.a=-p);Q3b(l,(qpd(),ppd));m||(j.a=0);break;case 1:pQb(k,owc,(Gvc(),Fvc));k.o.a=g.a;p<0&&(k.o.b=-p);Q3b(l,(qpd(),npd));m||(j.b=g.b);j.b-=g.b;break;case 3:pQb(k,owc,(Gvc(),Dvc));k.o.a=g.a;p<0&&(k.o.b=-p);Q3b(l,(qpd(),Yod));m||(j.b=0);}mjd(l.n,j);pQb(k,zBc,j);if(b==vod||b==xod||b==wod){o=0;if(b==vod&&a.pf(CBc)){switch(n.g){case 1:case 2:o=RD(a.of(CBc),17).a;break;case 3:case 4:o=-RD(a.of(CBc),17).a;}}else{switch(n.g){case 4:case 2:o=f.b;b==xod&&(o/=e.b);break;case 1:case 3:o=f.a;b==xod&&(o/=e.a);}}pQb(k,Jwc,o)}pQb(k,hwc,n);return k} +function OId(){MId();function h(f){var g=this;this.dispatch=function(a){var b=a.data;switch(b.cmd){case 'algorithms':var c=PId((yob(),new xpb(new glb(LId.b))));f.postMessage({id:b.id,data:c});break;case 'categories':var d=PId((yob(),new xpb(new glb(LId.c))));f.postMessage({id:b.id,data:d});break;case 'options':var e=PId((yob(),new xpb(new glb(LId.d))));f.postMessage({id:b.id,data:e});break;case 'register':SId(b.algorithms);f.postMessage({id:b.id});break;case 'layout':QId(b.graph,b.layoutOptions||{},b.options||{});f.postMessage({id:b.id,data:b.graph});break;}};this.saveDispatch=function(b){try{g.dispatch(b)}catch(a){f.postMessage({id:b.data.id,error:a})}}} +function j(b){var c=this;this.dispatcher=new h({postMessage:function(a){c.onmessage({data:a})}});this.postMessage=function(a){setTimeout(function(){c.dispatcher.saveDispatch({data:a})},0)}} +if(typeof document===Yxe&&typeof self!==Yxe){var i=new h(self);self.onmessage=i.saveDispatch}else if(typeof module!==Yxe&&module.exports){Object.defineProperty(exports,'__esModule',{value:true});module.exports={'default':j,Worker:j}}} +function i5b(a,b,c){var d,e,f,g,h,i,j,k,l,m;k=new j3b(c);kQb(k,b);pQb(k,(Ywc(),Awc),b);k.o.a=b.g;k.o.b=b.f;k.n.a=b.i;k.n.b=b.j;Rmb(c.a,k);Zjb(a.a,b,k);((!b.a&&(b.a=new C5d(J4,b,10,11)),b.a).i!=0||Heb(TD(Gxd(b,(yCc(),NAc)))))&&pQb(k,Yvc,(Geb(),true));j=RD(mQb(c,kwc),21);l=RD(mQb(k,(yCc(),BBc)),101);l==(Bod(),Aod)?pQb(k,BBc,zod):l!=zod&&j.Fc((ovc(),kvc));m=0;d=RD(mQb(c,rAc),88);for(i=new dMd((!b.c&&(b.c=new C5d(K4,b,9,9)),b.c));i.e!=i.i.gc();){h=RD(bMd(i),123);e=vCd(b);(dE(Gxd(e,cAc))!==dE((kEc(),hEc))||dE(Gxd(e,pAc))===dE((Ptc(),Otc))||dE(Gxd(e,pAc))===dE((Ptc(),Mtc))||Heb(TD(Gxd(e,eAc)))||dE(Gxd(e,Yzc))!==dE((U$b(),T$b))||dE(Gxd(e,ZAc))===dE((aEc(),TDc))||dE(Gxd(e,ZAc))===dE((aEc(),UDc))||dE(Gxd(e,$Ac))===dE((_Cc(),SCc))||dE(Gxd(e,$Ac))===dE((_Cc(),UCc)))&&!Heb(TD(Gxd(b,aAc)))&&Ixd(h,zwc,sgb(m++));Heb(TD(Gxd(h,pBc)))||j5b(a,h,k,j,d,l)}for(g=new dMd((!b.n&&(b.n=new C5d(I4,b,1,7)),b.n));g.e!=g.i.gc();){f=RD(bMd(g),135);!Heb(TD(Gxd(f,pBc)))&&!!f.a&&Rmb(k.b,h5b(f))}Heb(TD(mQb(k,Uzc)))&&j.Fc((ovc(),fvc));if(Heb(TD(mQb(k,MAc)))){j.Fc((ovc(),jvc));j.Fc(ivc);pQb(k,BBc,zod)}return k} +function ird(a,b,c,d,e,f,g){var h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I;p=0;D=0;for(j=new Anb(a.b);j.ap){if(f){Oub(w,n);Oub(B,sgb(k.b-1));Rmb(a.d,o);h.c.length=0}H=c.b;I+=n+b;n=0;l=$wnd.Math.max(l,c.b+c.c+G)}ZEb(h.c,i);xrd(i,H,I);l=$wnd.Math.max(l,H+G+c.c);n=$wnd.Math.max(n,m);H+=G+b;o=i}Tmb(a.a,h);Rmb(a.d,RD(Vmb(h,h.c.length-1),163));l=$wnd.Math.max(l,d);F=I+n+c.a;if(Fe.d.d+e.d.a){k.f.d=true}else{k.f.d=true;k.f.a=true}}}d.b!=d.d.c&&(b=c)}if(k){f=RD(Wjb(a.f,g.d.i),60);if(b.bf.d.d+f.d.a){k.f.d=true}else{k.f.d=true;k.f.a=true}}}}for(h=new is(Mr(Z2b(n).a.Kc(),new ir));gs(h);){g=RD(hs(h),18);if(g.a.b!=0){b=RD(Rub(g.a),8);if(g.d.j==(qpd(),Yod)){q=new Nlc(b,new rjd(b.a,e.d.d),e,g);q.f.a=true;q.a=g.d;ZEb(p.c,q)}if(g.d.j==npd){q=new Nlc(b,new rjd(b.a,e.d.d+e.d.a),e,g);q.f.d=true;q.a=g.d;ZEb(p.c,q)}}}}}return p} +function Nvd(a,b,c){var d,e,f,g,h,i,j,k,l,m;i=new bnb;l=b.length;g=$5d(c);for(j=0;j=o){if(s>o){n.c.length=0;o=s}ZEb(n.c,g)}}if(n.c.length!=0){m=RD(Vmb(n,Jwb(b,n.c.length)),131);F.a.Bc(m)!=null;m.s=p++;$Uc(m,C,w);n.c.length=0}}u=a.c.length+1;for(h=new Anb(a);h.aD.s){Ckb(c);Ymb(D.i,d);if(d.c>0){d.a=D;Rmb(D.t,d);d.b=A;Rmb(A.i,d)}}}}} +function Efc(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F;p=new cnb(b.b);u=new cnb(b.b);m=new cnb(b.b);B=new cnb(b.b);q=new cnb(b.b);for(A=Sub(b,0);A.b!=A.d.c;){v=RD(evb(A),12);for(h=new Anb(v.g);h.a0;r=v.g.c.length>0;j&&r?(ZEb(m.c,v),true):j?(ZEb(p.c,v),true):r&&(ZEb(u.c,v),true)}for(o=new Anb(p);o.as.nh()-j.b&&(m=s.nh()-j.b);n>s.oh()-j.d&&(n=s.oh()-j.d);k0){for(t=Sub(a.f,0);t.b!=t.d.c;){s=RD(evb(t),10);s.p+=m-a.e}WGc(a);Xub(a.f);TGc(a,d,n)}else{Mub(a.f,n);n.p=d;a.e=$wnd.Math.max(a.e,d);for(f=new is(Mr(Z2b(n).a.Kc(),new ir));gs(f);){e=RD(hs(f),18);if(!e.c.i.c&&e.c.i.k==(r3b(),n3b)){Mub(a.f,e.c.i);e.c.i.p=d-1}}a.c=d}}}else{WGc(a);Xub(a.f);d=0;if(gs(new is(Mr(Z2b(n).a.Kc(),new ir)))){m=0;m=UGc(m,n);d=m+2;TGc(a,d,n)}else{Mub(a.f,n);n.p=0;a.e=$wnd.Math.max(a.e,0);a.b=RD(Vmb(a.d.b,0),30);a.c=0}}}}a.f.b==0||WGc(a);a.d.a.c.length=0;r=new bnb;for(j=new Anb(a.d.b);j.a=48&&b<=57){d=b-48;while(e=48&&b<=57){d=d*10+b-48;if(d<0)throw Adb(new Lqe(TId((Hde(),CJe))))}}else{throw Adb(new Lqe(TId((Hde(),yJe))))}c=d;if(b==44){if(e>=a.j){throw Adb(new Lqe(TId((Hde(),AJe))))}else if((b=ihb(a.i,e++))>=48&&b<=57){c=b-48;while(e=48&&b<=57){c=c*10+b-48;if(c<0)throw Adb(new Lqe(TId((Hde(),CJe))))}if(d>c)throw Adb(new Lqe(TId((Hde(),BJe))))}else{c=-1}}if(b!=125)throw Adb(new Lqe(TId((Hde(),zJe))));if(a.bm(e)){f=(Vse(),Vse(),++Use,new Kte(9,f));a.d=e+1}else{f=(Vse(),Vse(),++Use,new Kte(3,f));a.d=e}f.Om(d);f.Nm(c);Mqe(a)}}return f} +function bXb(a){var b,c,d,e,f;c=RD(mQb(a,(Ywc(),kwc)),21);b=vfd(YWb);e=RD(mQb(a,(yCc(),IAc)),346);e==(Fnd(),Cnd)&&ofd(b,ZWb);Heb(TD(mQb(a,GAc)))?pfd(b,(sXb(),nXb),(hcc(),Zbc)):pfd(b,(sXb(),pXb),(hcc(),Zbc));mQb(a,(rid(),qid))!=null&&ofd(b,$Wb);(Heb(TD(mQb(a,PAc)))||Heb(TD(mQb(a,HAc))))&&nfd(b,(sXb(),rXb),(hcc(),lbc));switch(RD(mQb(a,rAc),88).g){case 2:case 3:case 4:nfd(pfd(b,(sXb(),nXb),(hcc(),nbc)),rXb,mbc);}c.Hc((ovc(),fvc))&&nfd(pfd(pfd(b,(sXb(),nXb),(hcc(),kbc)),qXb,ibc),rXb,jbc);dE(mQb(a,ZAc))!==dE((aEc(),$Dc))&&pfd(b,(sXb(),pXb),(hcc(),Rbc));if(c.Hc(mvc)){pfd(b,(sXb(),nXb),(hcc(),Xbc));pfd(b,oXb,Vbc);pfd(b,pXb,Wbc)}dE(mQb(a,Xzc))!==dE(($uc(),Yuc))&&dE(mQb(a,yAc))!==dE((Ymd(),Vmd))&&nfd(b,(sXb(),rXb),(hcc(),Abc));Heb(TD(mQb(a,KAc)))&&pfd(b,(sXb(),pXb),(hcc(),zbc));Heb(TD(mQb(a,nAc)))&&pfd(b,(sXb(),pXb),(hcc(),dcc));if(eXb(a)){dE(mQb(a,IAc))===dE(Cnd)?(d=RD(mQb(a,gAc),299)):(d=RD(mQb(a,hAc),299));f=d==(xvc(),vvc)?(hcc(),Ubc):(hcc(),gcc);pfd(b,(sXb(),qXb),f)}switch(RD(mQb(a,vCc),388).g){case 1:pfd(b,(sXb(),qXb),(hcc(),ecc));break;case 2:nfd(pfd(pfd(b,(sXb(),pXb),(hcc(),ebc)),qXb,fbc),rXb,gbc);}dE(mQb(a,cAc))!==dE((kEc(),hEc))&&pfd(b,(sXb(),pXb),(hcc(),fcc));return b} +function crc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;if(Ujb(a.a,b)){if(Zsb(RD(Wjb(a.a,b),49),c)){return 1}}else{Zjb(a.a,b,new _sb)}if(Ujb(a.a,c)){if(Zsb(RD(Wjb(a.a,c),49),b)){return -1}}else{Zjb(a.a,c,new _sb)}if(Ujb(a.e,b)){if(Zsb(RD(Wjb(a.e,b),49),c)){return -1}}else{Zjb(a.e,b,new _sb)}if(Ujb(a.e,c)){if(Zsb(RD(Wjb(a.a,c),49),b)){return 1}}else{Zjb(a.e,c,new _sb)}if(a.c==(kEc(),iEc)||!nQb(b,(Ywc(),zwc))||!nQb(c,(Ywc(),zwc))){l=null;for(j=new Anb(b.j);j.ag?erc(a,b,c):erc(a,c,b);return eg?1:0}}d=RD(mQb(b,(Ywc(),zwc)),17).a;f=RD(mQb(c,zwc),17).a;d>f?erc(a,b,c):erc(a,c,b);return df?1:0} +function uAd(b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r;if(d==null){return null}if(b.a!=c.jk()){throw Adb(new agb(VHe+c.xe()+WHe))}if(ZD(c,469)){r=z1d(RD(c,685),d);if(!r){throw Adb(new agb(XHe+d+"' is not a valid enumerator of '"+c.xe()+"'"))}return r}switch(Oee((lke(),jke),c).Nl()){case 2:{d=nue(d,false);break}case 3:{d=nue(d,true);break}}e=Oee(jke,c).Jl();if(e){return e.jk().wi().ti(e,d)}n=Oee(jke,c).Ll();if(n){r=new bnb;for(k=xAd(d),l=0,m=k.length;l1){o=new mMd((!a.a&&(a.a=new C5d(F4,a,6,6)),a.a));while(o.e!=o.i.gc()){cMd(o)}}g=RD(QHd((!a.a&&(a.a=new C5d(F4,a,6,6)),a.a),0),166);q=H;H>v+u?(q=v+u):Hw+p?(r=w+p):Iv-u&&qw-p&&rH+G?(B=H+G):vI+A?(C=I+A):wH-G&&BI-A&&Cc&&(m=c-1);n=N+Kwb(b,24)*Nxe*l-l/2;n<0?(n=1):n>d&&(n=d-1);e=(bvd(),i=new Xxd,i);Vxd(e,m);Wxd(e,n);WGd((!g.a&&(g.a=new XZd(D4,g,5)),g.a),e)}} +function Y7c(a){Cgd(a,new Pfd($fd(Xfd(Zfd(Yfd(new agd,$Fe),'ELK Rectangle Packing'),'Algorithm for packing of unconnected boxes, i.e. graphs without edges. The given order of the boxes is always preserved and the main reading direction of the boxes is left to right. The algorithm is divided into two phases. One phase approximates the width in which the rectangles can be placed. The next phase places the rectangles in rows using the previously calculated width as bounding width and bundles rectangles with a similar height in blocks. A compaction step reduces the size of the drawing. Finally, the rectangles are expanded to fill their bounding box and eliminate empty unused spaces.'),new _7c)));Agd(a,$Fe,Dze,1.3);Agd(a,$Fe,hAe,(Geb(),false));Agd(a,$Fe,Eze,O7c);Agd(a,$Fe,_ze,15);Agd(a,$Fe,YDe,iGd(y7c));Agd(a,$Fe,jAe,iGd(F7c));Agd(a,$Fe,CAe,iGd(H7c));Agd(a,$Fe,iAe,iGd(I7c));Agd(a,$Fe,kAe,iGd(E7c));Agd(a,$Fe,gAe,iGd(J7c));Agd(a,$Fe,lAe,iGd(P7c));Agd(a,$Fe,RFe,iGd(U7c));Agd(a,$Fe,SFe,iGd(T7c));Agd(a,$Fe,QFe,iGd(W7c));Agd(a,$Fe,PFe,iGd(V7c));Agd(a,$Fe,TFe,iGd(M7c));Agd(a,$Fe,UFe,iGd(L7c));Agd(a,$Fe,VFe,iGd(K7c));Agd(a,$Fe,WFe,iGd(S7c));Agd(a,$Fe,dAe,iGd(B7c));Agd(a,$Fe,iEe,iGd(C7c));Agd(a,$Fe,NFe,iGd(A7c));Agd(a,$Fe,MFe,iGd(z7c));Agd(a,$Fe,OFe,iGd(D7c));Agd(a,$Fe,LFe,iGd(R7c))} +function Ajb(a,b){xjb();var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H;B=a.e;o=a.d;e=a.a;if(B==0){switch(b){case 0:return '0';case 1:return zxe;case 2:return '0.00';case 3:return '0.000';case 4:return '0.0000';case 5:return '0.00000';case 6:return '0.000000';default:w=new bib;b<0?(w.a+='0E+',w):(w.a+='0E',w);w.a+=-b;return w.a;}}t=o*10+1+7;u=$C(hE,zwe,28,t+1,15,1);c=t;if(o==1){h=e[0];if(h<0){H=Cdb(h,yxe);do{p=H;H=Fdb(H,10);u[--c]=48+Ydb(Vdb(p,Ndb(H,10)))&Bwe}while(Ddb(H,0)!=0)}else{H=h;do{p=H;H=H/10|0;u[--c]=48+(p-H*10)&Bwe}while(H!=0)}}else{D=$C(kE,Pwe,28,o,15,1);G=o;hib(e,0,D,0,G);I:while(true){A=0;for(j=G-1;j>=0;j--){F=Bdb(Sdb(A,32),Cdb(D[j],yxe));r=yjb(F);D[j]=Ydb(r);A=Ydb(Tdb(r,32))}s=Ydb(A);q=c;do{u[--c]=48+s%10&Bwe}while((s=s/10|0)!=0&&c!=0);d=9-q+c;for(i=0;i0;i++){u[--c]=48}l=G-1;for(;D[l]==0;l--){if(l==0){break I}}G=l+1}while(u[c]==48){++c}}n=B<0;g=t-c-b-1;if(b==0){n&&(u[--c]=45);return Ihb(u,c,t-c)}if(b>0&&g>=-6){if(g>=0){k=c+g;for(m=t-1;m>=k;m--){u[m+1]=u[m]}u[++k]=46;n&&(u[--c]=45);return Ihb(u,c,t-c+1)}for(l=2;l<-g+1;l++){u[--c]=48}u[--c]=46;u[--c]=48;n&&(u[--c]=45);return Ihb(u,c,t-c)}C=c+1;f=t;v=new cib;n&&(v.a+='-',v);if(f-C>=1){Thb(v,u[c]);v.a+='.';v.a+=Ihb(u,c+1,t-c-1)}else{v.a+=Ihb(u,c,t-c)}v.a+='E';g>0&&(v.a+='+',v);v.a+=''+g;return v.a} +function Jad(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;a.c=b;a.g=new Tsb;c=(lud(),new zud(a.c));d=new PJb(c);LJb(d);t=WD(Gxd(a.c,(ncd(),gcd)));i=RD(Gxd(a.c,icd),324);v=RD(Gxd(a.c,jcd),437);g=RD(Gxd(a.c,bcd),490);u=RD(Gxd(a.c,hcd),438);a.j=Kfb(UD(Gxd(a.c,kcd)));h=a.a;switch(i.g){case 0:h=a.a;break;case 1:h=a.b;break;case 2:h=a.i;break;case 3:h=a.e;break;case 4:h=a.f;break;default:throw Adb(new agb(eGe+(i.f!=null?i.f:''+i.g)));}a.d=new qbd(h,v,g);pQb(a.d,(OQb(),MQb),TD(Gxd(a.c,dcd)));a.d.c=Heb(TD(Gxd(a.c,ccd)));if(tCd(a.c).i==0){return a.d}for(l=new dMd(tCd(a.c));l.e!=l.i.gc();){k=RD(bMd(l),27);n=k.g/2;m=k.f/2;w=new rjd(k.i+n,k.j+m);while(Ujb(a.g,w)){Zid(w,($wnd.Math.random()-0.5)*Vze,($wnd.Math.random()-0.5)*Vze)}p=RD(Gxd(k,(umd(),eld)),140);q=new TQb(w,new Uid(w.a-n-a.j/2-p.b,w.b-m-a.j/2-p.d,k.g+a.j+(p.b+p.c),k.f+a.j+(p.d+p.a)));Rmb(a.d.i,q);Zjb(a.g,w,new Ptd(q,k))}switch(u.g){case 0:if(t==null){a.d.d=RD(Vmb(a.d.i,0),68)}else{for(s=new Anb(a.d.i);s.a0?G+1:1}for(g=new Anb(w.g);g.a0?G+1:1}}a.c[j]==0?Mub(a.e,p):a.a[j]==0&&Mub(a.f,p);++j}o=-1;n=1;l=new bnb;a.d=RD(mQb(b,(Ywc(),Lwc)),234);while(L>0){while(a.e.b!=0){I=RD(Uub(a.e),10);a.b[I.p]=o--;TFc(a,I);--L}while(a.f.b!=0){J=RD(Uub(a.f),10);a.b[J.p]=n++;TFc(a,J);--L}if(L>0){m=qwe;for(s=new Anb(t);s.a=m){if(u>m){l.c.length=0;m=u}ZEb(l.c,p)}}}k=a.sg(l);a.b[k.p]=n++;TFc(a,k);--L}}H=t.c.length+1;for(j=0;ja.b[K]){X0b(d,true);pQb(b,awc,(Geb(),true))}}}}a.a=null;a.c=null;a.b=null;Xub(a.f);Xub(a.e);c.Vg()} +function usd(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;v=RD(QHd((!a.a&&(a.a=new C5d(F4,a,6,6)),a.a),0),166);k=new Ejd;u=new Tsb;w=xsd(v);rtb(u.f,v,w);m=new Tsb;d=new Yub;for(o=Fl(Al(cD(WC(cJ,1),rve,20,0,[(!b.d&&(b.d=new Yie(G4,b,8,5)),b.d),(!b.e&&(b.e=new Yie(G4,b,7,4)),b.e)])));gs(o);){n=RD(hs(o),74);if((!a.a&&(a.a=new C5d(F4,a,6,6)),a.a).i!=1){throw Adb(new agb(tHe+(!a.a&&(a.a=new C5d(F4,a,6,6)),a.a).i))}if(n!=a){q=RD(QHd((!n.a&&(n.a=new C5d(F4,n,6,6)),n.a),0),166);Pub(d,q,d.c.b,d.c);p=RD(Wd(qtb(u.f,q)),13);if(!p){p=xsd(q);rtb(u.f,q,p)}l=c?ojd(new sjd(RD(Vmb(w,w.c.length-1),8)),RD(Vmb(p,p.c.length-1),8)):ojd(new sjd((tFb(0,w.c.length),RD(w.c[0],8))),(tFb(0,p.c.length),RD(p.c[0],8)));rtb(m.f,q,l)}}if(d.b!=0){r=RD(Vmb(w,c?w.c.length-1:0),8);for(j=1;j1&&(Pub(k,r,k.c.b,k.c),true);gvb(e)}}}r=s}}return k} +function S_c(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D;c.Ug(_Ee,1);D=RD(zDb(CDb(new SDb(null,new Swb(b,16)),new e0c),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[(xBb(),vBb)]))),15);k=RD(zDb(CDb(new SDb(null,new Swb(b,16)),new g0c(b)),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[vBb]))),15);o=RD(zDb(CDb(new SDb(null,new Swb(b,16)),new i0c(b)),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[vBb]))),15);p=$C(Z$,NEe,40,b.gc(),0,1);for(g=0;g=0&&C=0&&!p[n]){p[n]=e;k.gd(h);--h;break}n=C-m;if(n=0&&!p[n]){p[n]=e;k.gd(h);--h;break}}}o.jd(new k0c);for(i=p.length-1;i>=0;i--){if(!p[i]&&!o.dc()){p[i]=RD(o.Xb(0),40);o.gd(0)}}for(j=0;j=0;i--){Mub(c,(tFb(i,g.c.length),RD(g.c[i],8)))}return c} +function l9c(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;t=Kfb(UD(Gxd(b,(X6c(),W6c))));n=Kfb(UD(Gxd(b,U6c)));m=Kfb(UD(Gxd(b,R6c)));Bad((!b.a&&(b.a=new C5d(J4,b,10,11)),b.a));r=U8c((!b.a&&(b.a=new C5d(J4,b,10,11)),b.a),t,a.b);for(q=0;qm&&Fad((tFb(m,b.c.length),RD(b.c[m],186)),k);k=null;while(b.c.length>m&&(tFb(m,b.c.length),RD(b.c[m],186)).a.c.length==0){Ymb(b,(tFb(m,b.c.length),b.c[m]))}}if(!k){--g;continue}if(!Heb(TD(RD(Vmb(k.b,0),27).of((X7c(),D7c))))&&K8c(b,o,f,k,q,c,m,d)){p=true;continue}if(q){n=o.b;l=k.f;if(!Heb(TD(RD(Vmb(k.b,0),27).of(D7c)))&&L8c(b,o,f,k,c,m,d,e)){p=true;if(n=a.j){a.a=-1;a.c=1;return}b=ihb(a.i,a.d++);a.a=b;if(a.b==1){switch(b){case 92:d=10;if(a.d>=a.j)throw Adb(new Lqe(TId((Hde(),VIe))));a.a=ihb(a.i,a.d++);break;case 45:if((a.e&512)==512&&a.d=a.j)break;if(ihb(a.i,a.d)!=63)break;if(++a.d>=a.j)throw Adb(new Lqe(TId((Hde(),WIe))));b=ihb(a.i,a.d++);switch(b){case 58:d=13;break;case 61:d=14;break;case 33:d=15;break;case 91:d=19;break;case 62:d=18;break;case 60:if(a.d>=a.j)throw Adb(new Lqe(TId((Hde(),WIe))));b=ihb(a.i,a.d++);if(b==61){d=16}else if(b==33){d=17}else throw Adb(new Lqe(TId((Hde(),XIe))));break;case 35:while(a.d=a.j)throw Adb(new Lqe(TId((Hde(),VIe))));a.a=ihb(a.i,a.d++);break;default:d=0;}a.c=d} +function oXc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q;c.Ug('Process compaction',1);if(!Heb(TD(mQb(b,(h_c(),F$c))))){return}e=RD(mQb(b,H$c),88);n=Kfb(UD(mQb(b,_$c)));pXc(a,b,e);lXc(b,n/2/2);o=b.b;tvb(o,new EXc(e));for(j=Sub(o,0);j.b!=j.d.c;){i=RD(evb(j),40);if(!Heb(TD(mQb(i,(q$c(),n$c))))){d=mXc(i,e);p=lWc(i,b);l=0;m=0;if(d){q=d.e;switch(e.g){case 2:l=q.a-n-i.f.a;p.e.a-n-i.f.al&&(l=p.e.a+p.f.a+n);m=l+i.f.a;break;case 4:l=q.b-n-i.f.b;p.e.b-n-i.f.bl&&(l=p.e.b+p.f.b+n);m=l+i.f.b;}}else if(p){switch(e.g){case 2:l=p.e.a-n-i.f.a;m=l+i.f.a;break;case 1:l=p.e.a+p.f.a+n;m=l+i.f.a;break;case 4:l=p.e.b-n-i.f.b;m=l+i.f.b;break;case 3:l=p.e.b+p.f.b+n;m=l+i.f.b;}}if(dE(mQb(b,K$c))===dE((LZc(),IZc))){f=l;g=m;h=DDb(CDb(new SDb(null,new Swb(a.a,16)),new IXc(f,g)));if(h.a!=null){e==(Cmd(),ymd)||e==zmd?(i.e.a=l):(i.e.b=l)}else{e==(Cmd(),ymd)||e==Bmd?(h=DDb(CDb(NDb(new SDb(null,new Swb(a.a,16))),new WXc(f)))):(h=DDb(CDb(NDb(new SDb(null,new Swb(a.a,16))),new YXc(f))));h.a!=null&&(e==ymd||e==zmd?(i.e.a=Kfb(UD((sFb(h.a!=null),RD(h.a,42)).a))):(i.e.b=Kfb(UD((sFb(h.a!=null),RD(h.a,42)).a))))}if(h.a!=null){k=Wmb(a.a,(sFb(h.a!=null),h.a),0);if(k>0&&k!=RD(mQb(i,f_c),17).a){pQb(i,UZc,(Geb(),true));pQb(i,f_c,sgb(k))}}}else{e==(Cmd(),ymd)||e==zmd?(i.e.a=l):(i.e.b=l)}}}c.Vg()} +function Fre(a){var b,c,d,e,f,g,h,i,j;a.b=1;Mqe(a);b=null;if(a.c==0&&a.a==94){Mqe(a);b=(Vse(),Vse(),++Use,new xte(4));rte(b,0,MLe);h=(null,++Use,new xte(4))}else{h=(Vse(),Vse(),++Use,new xte(4))}e=true;while((j=a.c)!=1){if(j==0&&a.a==93&&!e){if(b){wte(b,h);h=b}break}c=a.a;d=false;if(j==10){switch(c){case 100:case 68:case 119:case 87:case 115:case 83:ute(h,Ere(c));d=true;break;case 105:case 73:case 99:case 67:c=(ute(h,Ere(c)),-1);c<0&&(d=true);break;case 112:case 80:i=Sqe(a,c);if(!i)throw Adb(new Lqe(TId((Hde(),hJe))));ute(h,i);d=true;break;default:c=Dre(a);}}else if(j==24&&!e){if(b){wte(b,h);h=b}f=Fre(a);wte(h,f);if(a.c!=0||a.a!=93)throw Adb(new Lqe(TId((Hde(),lJe))));break}Mqe(a);if(!d){if(j==0){if(c==91)throw Adb(new Lqe(TId((Hde(),mJe))));if(c==93)throw Adb(new Lqe(TId((Hde(),nJe))));if(c==45&&!e&&a.a!=93)throw Adb(new Lqe(TId((Hde(),oJe))))}if(a.c!=0||a.a!=45||c==45&&e){rte(h,c,c)}else{Mqe(a);if((j=a.c)==1)throw Adb(new Lqe(TId((Hde(),jJe))));if(j==0&&a.a==93){rte(h,c,c);rte(h,45,45)}else if(j==0&&a.a==93||j==24){throw Adb(new Lqe(TId((Hde(),oJe))))}else{g=a.a;if(j==0){if(g==91)throw Adb(new Lqe(TId((Hde(),mJe))));if(g==93)throw Adb(new Lqe(TId((Hde(),nJe))));if(g==45)throw Adb(new Lqe(TId((Hde(),oJe))))}else j==10&&(g=Dre(a));Mqe(a);if(c>g)throw Adb(new Lqe(TId((Hde(),rJe))));rte(h,c,g)}}}e=false}if(a.c==1)throw Adb(new Lqe(TId((Hde(),jJe))));vte(h);ste(h);a.b=0;Mqe(a);return h} +function EGc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;c.Ug('Coffman-Graham Layering',1);if(b.a.c.length==0){c.Vg();return}v=RD(mQb(b,(yCc(),SAc)),17).a;i=0;g=0;for(m=new Anb(b.a);m.a=v||!zGc(r,d))&&(d=BGc(b,k));g3b(r,d);for(f=new is(Mr(Z2b(r).a.Kc(),new ir));gs(f);){e=RD(hs(f),18);if(a.a[e.p]){continue}p=e.c.i;--a.e[p.p];a.e[p.p]==0&&(zFb(lwb(n,p),Bxe),true)}}for(j=k.c.length-1;j>=0;--j){Rmb(b.b,(tFb(j,k.c.length),RD(k.c[j],30)))}b.a.c.length=0;c.Vg()} +function Sec(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;u=false;do{u=false;for(f=b?(new Xkb(a.a.b)).a.gc()-2:1;b?f>=0:f<(new Xkb(a.a.b)).a.gc();f+=b?-1:1){e=_5b(a.a,sgb(f));for(n=0;nRD(mQb(q,zwc),17).a)&&(t=false)}if(!t){continue}i=b?f+1:f-1;h=_5b(a.a,sgb(i));g=false;s=true;d=false;for(k=Sub(h,0);k.b!=k.d.c;){j=RD(evb(k),10);if(nQb(j,zwc)){if(j.p!=l.p){g=g|(b?RD(mQb(j,zwc),17).aRD(mQb(l,zwc),17).a);s=false}}else if(!g&&s){if(j.k==(r3b(),n3b)){d=true;b?(m=RD(hs(new is(Mr(Z2b(j).a.Kc(),new ir))),18).c.i):(m=RD(hs(new is(Mr(a3b(j).a.Kc(),new ir))),18).d.i);if(m==l){b?(c=RD(hs(new is(Mr(a3b(j).a.Kc(),new ir))),18).d.i):(c=RD(hs(new is(Mr(Z2b(j).a.Kc(),new ir))),18).c.i);(b?RD($5b(a.a,c),17).a-RD($5b(a.a,m),17).a:RD($5b(a.a,m),17).a-RD($5b(a.a,c),17).a)<=2&&(s=false)}}}}if(d&&s){b?(c=RD(hs(new is(Mr(a3b(l).a.Kc(),new ir))),18).d.i):(c=RD(hs(new is(Mr(Z2b(l).a.Kc(),new ir))),18).c.i);(b?RD($5b(a.a,c),17).a-RD($5b(a.a,l),17).a:RD($5b(a.a,l),17).a-RD($5b(a.a,c),17).a)<=2&&c.k==(r3b(),p3b)&&(s=false)}if(g||s){p=Xec(a,l,b);while(p.a.gc()!=0){o=RD(p.a.ec().Kc().Pb(),10);p.a.Bc(o)!=null;ye(p,Xec(a,o,b))}--n;u=true}}}}while(u)} +function Xae(a){_Ad(a.c,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'http://www.w3.org/2001/XMLSchema#decimal']));_Ad(a.d,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'http://www.w3.org/2001/XMLSchema#integer']));_Ad(a.e,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'http://www.w3.org/2001/XMLSchema#boolean']));_Ad(a.f,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'EBoolean',GIe,'EBoolean:Object']));_Ad(a.i,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'http://www.w3.org/2001/XMLSchema#byte']));_Ad(a.g,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'http://www.w3.org/2001/XMLSchema#hexBinary']));_Ad(a.j,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'EByte',GIe,'EByte:Object']));_Ad(a.n,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'EChar',GIe,'EChar:Object']));_Ad(a.t,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'http://www.w3.org/2001/XMLSchema#double']));_Ad(a.u,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'EDouble',GIe,'EDouble:Object']));_Ad(a.F,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'http://www.w3.org/2001/XMLSchema#float']));_Ad(a.G,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'EFloat',GIe,'EFloat:Object']));_Ad(a.I,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'http://www.w3.org/2001/XMLSchema#int']));_Ad(a.J,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'EInt',GIe,'EInt:Object']));_Ad(a.N,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'http://www.w3.org/2001/XMLSchema#long']));_Ad(a.O,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'ELong',GIe,'ELong:Object']));_Ad(a.Z,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'http://www.w3.org/2001/XMLSchema#short']));_Ad(a.$,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'EShort',GIe,'EShort:Object']));_Ad(a._,qKe,cD(WC(qJ,1),Nve,2,6,[DKe,'http://www.w3.org/2001/XMLSchema#string']))} +function C0c(a,b,c,d,e,f,g){var h,i,j,k,l,m,n,o;m=RD(d.a,17).a;n=RD(d.b,17).a;l=a.b;o=a.c;h=0;k=0;if(b==(Cmd(),ymd)||b==zmd){k=Uvb(QCb(HDb(GDb(new SDb(null,new Swb(c.b,16)),new b2c),new b1c)));if(l.e.b+l.f.b/2>k){j=++n;h=Kfb(UD(Lvb(JDb(GDb(new SDb(null,new Swb(c.b,16)),new d2c(e,j)),new d1c))))}else{i=++m;h=Kfb(UD(Lvb(KDb(GDb(new SDb(null,new Swb(c.b,16)),new f2c(e,i)),new h1c))))}}else{k=Uvb(QCb(HDb(GDb(new SDb(null,new Swb(c.b,16)),new x1c),new l1c)));if(l.e.a+l.f.a/2>k){j=++n;h=Kfb(UD(Lvb(JDb(GDb(new SDb(null,new Swb(c.b,16)),new z1c(e,j)),new n1c))))}else{i=++m;h=Kfb(UD(Lvb(KDb(GDb(new SDb(null,new Swb(c.b,16)),new B1c(e,i)),new r1c))))}}if(b==ymd){Oub(a.a,new rjd(Kfb(UD(mQb(l,(q$c(),f$c))))-e,h));Oub(a.a,new rjd(o.e.a+o.f.a+e+f,h));Oub(a.a,new rjd(o.e.a+o.f.a+e+f,o.e.b+o.f.b/2));Oub(a.a,new rjd(o.e.a+o.f.a,o.e.b+o.f.b/2))}else if(b==zmd){Oub(a.a,new rjd(Kfb(UD(mQb(l,(q$c(),e$c))))+e,l.e.b+l.f.b/2));Oub(a.a,new rjd(l.e.a+l.f.a+e,h));Oub(a.a,new rjd(o.e.a-e-f,h));Oub(a.a,new rjd(o.e.a-e-f,o.e.b+o.f.b/2));Oub(a.a,new rjd(o.e.a,o.e.b+o.f.b/2))}else if(b==Bmd){Oub(a.a,new rjd(h,Kfb(UD(mQb(l,(q$c(),f$c))))-e));Oub(a.a,new rjd(h,o.e.b+o.f.b+e+f));Oub(a.a,new rjd(o.e.a+o.f.a/2,o.e.b+o.f.b+e+f));Oub(a.a,new rjd(o.e.a+o.f.a/2,o.e.b+o.f.b+e))}else{a.a.b==0||(RD(Rub(a.a),8).b=Kfb(UD(mQb(l,(q$c(),e$c))))+e*RD(g.b,17).a);Oub(a.a,new rjd(h,Kfb(UD(mQb(l,(q$c(),e$c))))+e*RD(g.b,17).a));Oub(a.a,new rjd(h,o.e.b-e*RD(g.a,17).a-f))}return new Ptd(sgb(m),sgb(n))} +function ASd(a){var b,c,d,e,f,g,h,i,j,k,l,m,n;g=true;l=null;d=null;e=null;b=false;n=_Rd;j=null;f=null;h=0;i=sSd(a,h,ZRd,$Rd);if(i=0&&lhb(a.substr(h,'//'.length),'//')){h+=2;i=sSd(a,h,aSd,bSd);d=(AFb(h,i,a.length),a.substr(h,i-h));h=i}else if(l!=null&&(h==a.length||(BFb(h,a.length),a.charCodeAt(h)!=47))){g=false;i=rhb(a,Fhb(35),h);i==-1&&(i=a.length);d=(AFb(h,i,a.length),a.substr(h,i-h));h=i}if(!c&&h0&&ihb(k,k.length-1)==58){e=k;h=i}}if(hqQc(f))&&(l=f)}}!l&&(l=(tFb(0,q.c.length),RD(q.c[0],185)));for(p=new Anb(b.b);p.al){F=0;G+=k+A;k=0}FVc(v,g,F,G);b=$wnd.Math.max(b,F+w.a);k=$wnd.Math.max(k,w.b);F+=w.a+A}u=new Tsb;c=new Tsb;for(C=new Anb(a);C.a=-1900?1:0;c>=4?Zhb(a,cD(WC(qJ,1),Nve,2,6,[Qwe,Rwe])[h]):Zhb(a,cD(WC(qJ,1),Nve,2,6,['BC','AD'])[h]);break;case 121:AA(a,c,d);break;case 77:zA(a,c,d);break;case 107:i=e.q.getHours();i==0?UA(a,24,c):UA(a,i,c);break;case 83:yA(a,c,e);break;case 69:k=d.q.getDay();c==5?Zhb(a,cD(WC(qJ,1),Nve,2,6,['S','M','T','W','T','F','S'])[k]):c==4?Zhb(a,cD(WC(qJ,1),Nve,2,6,[Swe,Twe,Uwe,Vwe,Wwe,Xwe,Ywe])[k]):Zhb(a,cD(WC(qJ,1),Nve,2,6,['Sun','Mon','Tue','Wed','Thu','Fri','Sat'])[k]);break;case 97:e.q.getHours()>=12&&e.q.getHours()<24?Zhb(a,cD(WC(qJ,1),Nve,2,6,['AM','PM'])[1]):Zhb(a,cD(WC(qJ,1),Nve,2,6,['AM','PM'])[0]);break;case 104:l=e.q.getHours()%12;l==0?UA(a,12,c):UA(a,l,c);break;case 75:m=e.q.getHours()%12;UA(a,m,c);break;case 72:n=e.q.getHours();UA(a,n,c);break;case 99:o=d.q.getDay();c==5?Zhb(a,cD(WC(qJ,1),Nve,2,6,['S','M','T','W','T','F','S'])[o]):c==4?Zhb(a,cD(WC(qJ,1),Nve,2,6,[Swe,Twe,Uwe,Vwe,Wwe,Xwe,Ywe])[o]):c==3?Zhb(a,cD(WC(qJ,1),Nve,2,6,['Sun','Mon','Tue','Wed','Thu','Fri','Sat'])[o]):UA(a,o,1);break;case 76:p=d.q.getMonth();c==5?Zhb(a,cD(WC(qJ,1),Nve,2,6,['J','F','M','A','M','J','J','A','S','O','N','D'])[p]):c==4?Zhb(a,cD(WC(qJ,1),Nve,2,6,[Cwe,Dwe,Ewe,Fwe,Gwe,Hwe,Iwe,Jwe,Kwe,Lwe,Mwe,Nwe])[p]):c==3?Zhb(a,cD(WC(qJ,1),Nve,2,6,['Jan','Feb','Mar','Apr',Gwe,'Jun','Jul','Aug','Sep','Oct','Nov','Dec'])[p]):UA(a,p+1,c);break;case 81:q=d.q.getMonth()/3|0;c<4?Zhb(a,cD(WC(qJ,1),Nve,2,6,['Q1','Q2','Q3','Q4'])[q]):Zhb(a,cD(WC(qJ,1),Nve,2,6,['1st quarter','2nd quarter','3rd quarter','4th quarter'])[q]);break;case 100:r=d.q.getDate();UA(a,r,c);break;case 109:j=e.q.getMinutes();UA(a,j,c);break;case 115:g=e.q.getSeconds();UA(a,g,c);break;case 122:c<4?Zhb(a,f.c[0]):Zhb(a,f.c[1]);break;case 118:Zhb(a,f.b);break;case 90:c<3?Zhb(a,cB(f)):c==3?Zhb(a,bB(f)):Zhb(a,eB(f.a));break;default:return false;}return true} +function f5b(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H;X4b(b);i=RD(QHd((!b.b&&(b.b=new Yie(E4,b,4,7)),b.b),0),84);k=RD(QHd((!b.c&&(b.c=new Yie(E4,b,5,8)),b.c),0),84);h=AGd(i);j=AGd(k);g=(!b.a&&(b.a=new C5d(F4,b,6,6)),b.a).i==0?null:RD(QHd((!b.a&&(b.a=new C5d(F4,b,6,6)),b.a),0),166);A=RD(Wjb(a.a,h),10);F=RD(Wjb(a.a,j),10);B=null;G=null;if(ZD(i,193)){w=RD(Wjb(a.a,i),305);if(ZD(w,12)){B=RD(w,12)}else if(ZD(w,10)){A=RD(w,10);B=RD(Vmb(A.j,0),12)}}if(ZD(k,193)){D=RD(Wjb(a.a,k),305);if(ZD(D,12)){G=RD(D,12)}else if(ZD(D,10)){F=RD(D,10);G=RD(Vmb(F.j,0),12)}}if(!A||!F){throw Adb(new Ked('The source or the target of edge '+b+' could not be found. '+'This usually happens when an edge connects a node laid out by ELK Layered to a node in '+'another level of hierarchy laid out by either another instance of ELK Layered or another '+'layout algorithm alltogether. The former can be solved by setting the hierarchyHandling '+'option to INCLUDE_CHILDREN.'))}p=new a1b;kQb(p,b);pQb(p,(Ywc(),Awc),b);pQb(p,(yCc(),RAc),null);n=RD(mQb(d,kwc),21);A==F&&n.Fc((ovc(),nvc));if(!B){v=(BEc(),zEc);C=null;if(!!g&&Dod(RD(mQb(A,BBc),101))){C=new rjd(g.j,g.k);Fsd(C,kzd(b));Gsd(C,c);if(NGd(j,h)){v=yEc;$id(C,A.n)}}B=g2b(A,C,v,d)}if(!G){v=(BEc(),yEc);H=null;if(!!g&&Dod(RD(mQb(F,BBc),101))){H=new rjd(g.b,g.c);Fsd(H,kzd(b));Gsd(H,c)}G=g2b(F,H,v,Y2b(F))}Y0b(p,B);Z0b(p,G);(B.e.c.length>1||B.g.c.length>1||G.e.c.length>1||G.g.c.length>1)&&n.Fc((ovc(),ivc));for(m=new dMd((!b.n&&(b.n=new C5d(I4,b,1,7)),b.n));m.e!=m.i.gc();){l=RD(bMd(m),135);if(!Heb(TD(Gxd(l,pBc)))&&!!l.a){q=h5b(l);Rmb(p.b,q);switch(RD(mQb(q,wAc),278).g){case 1:case 2:n.Fc((ovc(),gvc));break;case 0:n.Fc((ovc(),evc));pQb(q,wAc,(Omd(),Lmd));}}}f=RD(mQb(d,oAc),322);r=RD(mQb(d,kBc),323);e=f==(stc(),ptc)||r==(JDc(),FDc);if(!!g&&(!g.a&&(g.a=new XZd(D4,g,5)),g.a).i!=0&&e){s=ssd(g);o=new Ejd;for(u=Sub(s,0);u.b!=u.d.c;){t=RD(evb(u),8);Mub(o,new sjd(t))}pQb(p,Bwc,o)}return p} +function F0c(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I;C=0;D=0;A=new Tsb;v=RD(Lvb(JDb(GDb(new SDb(null,new Swb(a.b,16)),new v1c),new Z0c)),17).a+1;B=$C(kE,Pwe,28,v,15,1);q=$C(kE,Pwe,28,v,15,1);for(p=0;p1){for(h=G+1;hj.b.e.b*(1-r)+j.c.e.b*r){break}}if(w.gc()>0){H=j.a.b==0?ajd(j.b.e):RD(Rub(j.a),8);t=$id(ajd(RD(w.Xb(w.gc()-1),40).e),RD(w.Xb(w.gc()-1),40).f);m=$id(ajd(RD(w.Xb(0),40).e),RD(w.Xb(0),40).f);if(o>=w.gc()-1&&H.b>t.b&&j.c.e.b>t.b){continue}if(o<=0&&H.bj.b.e.a*(1-r)+j.c.e.a*r){break}}if(w.gc()>0){H=j.a.b==0?ajd(j.b.e):RD(Rub(j.a),8);t=$id(ajd(RD(w.Xb(w.gc()-1),40).e),RD(w.Xb(w.gc()-1),40).f);m=$id(ajd(RD(w.Xb(0),40).e),RD(w.Xb(0),40).f);if(o>=w.gc()-1&&H.a>t.a&&j.c.e.a>t.a){continue}if(o<=0&&H.a=Kfb(UD(mQb(a,(q$c(),$Zc))))&&++D}else{n.f&&n.d.e.a<=Kfb(UD(mQb(a,(q$c(),ZZc))))&&++C;n.g&&n.c.e.a+n.c.f.a>=Kfb(UD(mQb(a,(q$c(),YZc))))&&++D}}}else if(u==0){H0c(j)}else if(u<0){++B[G];++q[I];F=C0c(j,b,a,new Ptd(sgb(C),sgb(D)),c,d,new Ptd(sgb(q[I]),sgb(B[G])));C=RD(F.a,17).a;D=RD(F.b,17).a}}} +function qrc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;d=b;i=c;if(a.b&&d.j==(qpd(),ppd)&&i.j==(qpd(),ppd)){s=d;d=i;i=s}if(Ujb(a.a,d)){if(Zsb(RD(Wjb(a.a,d),49),i)){return 1}}else{Zjb(a.a,d,new _sb)}if(Ujb(a.a,i)){if(Zsb(RD(Wjb(a.a,i),49),d)){return -1}}else{Zjb(a.a,i,new _sb)}if(Ujb(a.d,d)){if(Zsb(RD(Wjb(a.d,d),49),i)){return -1}}else{Zjb(a.d,d,new _sb)}if(Ujb(a.d,i)){if(Zsb(RD(Wjb(a.a,i),49),d)){return 1}}else{Zjb(a.d,i,new _sb)}if(d.j!=i.j){r=yrc(d.j,i.j);r==-1?rrc(a,i,d):rrc(a,d,i);return r}if(d.e.c.length!=0&&i.e.c.length!=0){if(a.b){r=orc(d,i);if(r!=0){r==-1?rrc(a,i,d):r==1&&rrc(a,d,i);return r}}f=RD(Vmb(d.e,0),18).c.i;k=RD(Vmb(i.e,0),18).c.i;if(f==k){e=RD(mQb(RD(Vmb(d.e,0),18),(Ywc(),zwc)),17).a;j=RD(mQb(RD(Vmb(i.e,0),18),zwc),17).a;e>j?rrc(a,d,i):rrc(a,i,d);return ej?1:0}for(o=a.c,p=0,q=o.length;pj?rrc(a,d,i):rrc(a,i,d);return ej?1:0}if(a.b){r=orc(d,i);if(r!=0){r==-1?rrc(a,i,d):r==1&&rrc(a,d,i);return r}}g=0;l=0;nQb(RD(Vmb(d.g,0),18),zwc)&&(g=RD(mQb(RD(Vmb(d.g,0),18),zwc),17).a);nQb(RD(Vmb(i.g,0),18),zwc)&&(l=RD(mQb(RD(Vmb(d.g,0),18),zwc),17).a);if(!!h&&h==m){if(Heb(TD(mQb(RD(Vmb(d.g,0),18),Nwc)))&&!Heb(TD(mQb(RD(Vmb(i.g,0),18),Nwc)))){rrc(a,d,i);return 1}else if(!Heb(TD(mQb(RD(Vmb(d.g,0),18),Nwc)))&&Heb(TD(mQb(RD(Vmb(i.g,0),18),Nwc)))){rrc(a,i,d);return -1}g>l?rrc(a,d,i):rrc(a,i,d);return gl?1:0}if(a.f){a.f._b(h)&&(g=RD(a.f.xc(h),17).a);a.f._b(m)&&(l=RD(a.f.xc(m),17).a)}g>l?rrc(a,d,i):rrc(a,i,d);return gl?1:0}if(d.e.c.length!=0&&i.g.c.length!=0){rrc(a,d,i);return 1}else if(d.g.c.length!=0&&i.e.c.length!=0){rrc(a,i,d);return -1}else if(nQb(d,(Ywc(),zwc))&&nQb(i,zwc)){e=RD(mQb(d,zwc),17).a;j=RD(mQb(i,zwc),17).a;e>j?rrc(a,d,i):rrc(a,i,d);return ej?1:0}else{rrc(a,i,d);return -1}} +function Yae(a){if(a.gb)return;a.gb=true;a.b=jBd(a,0);iBd(a.b,18);oBd(a.b,19);a.a=jBd(a,1);iBd(a.a,1);oBd(a.a,2);oBd(a.a,3);oBd(a.a,4);oBd(a.a,5);a.o=jBd(a,2);iBd(a.o,8);iBd(a.o,9);oBd(a.o,10);oBd(a.o,11);oBd(a.o,12);oBd(a.o,13);oBd(a.o,14);oBd(a.o,15);oBd(a.o,16);oBd(a.o,17);oBd(a.o,18);oBd(a.o,19);oBd(a.o,20);oBd(a.o,21);oBd(a.o,22);oBd(a.o,23);nBd(a.o);nBd(a.o);nBd(a.o);nBd(a.o);nBd(a.o);nBd(a.o);nBd(a.o);nBd(a.o);nBd(a.o);nBd(a.o);a.p=jBd(a,3);iBd(a.p,2);iBd(a.p,3);iBd(a.p,4);iBd(a.p,5);oBd(a.p,6);oBd(a.p,7);nBd(a.p);nBd(a.p);a.q=jBd(a,4);iBd(a.q,8);a.v=jBd(a,5);oBd(a.v,9);nBd(a.v);nBd(a.v);nBd(a.v);a.w=jBd(a,6);iBd(a.w,2);iBd(a.w,3);iBd(a.w,4);oBd(a.w,5);a.B=jBd(a,7);oBd(a.B,1);nBd(a.B);nBd(a.B);nBd(a.B);a.Q=jBd(a,8);oBd(a.Q,0);nBd(a.Q);a.R=jBd(a,9);iBd(a.R,1);a.S=jBd(a,10);nBd(a.S);nBd(a.S);nBd(a.S);nBd(a.S);nBd(a.S);nBd(a.S);nBd(a.S);nBd(a.S);nBd(a.S);nBd(a.S);nBd(a.S);nBd(a.S);nBd(a.S);nBd(a.S);nBd(a.S);a.T=jBd(a,11);oBd(a.T,10);oBd(a.T,11);oBd(a.T,12);oBd(a.T,13);oBd(a.T,14);nBd(a.T);nBd(a.T);a.U=jBd(a,12);iBd(a.U,2);iBd(a.U,3);oBd(a.U,4);oBd(a.U,5);oBd(a.U,6);oBd(a.U,7);nBd(a.U);a.V=jBd(a,13);oBd(a.V,10);a.W=jBd(a,14);iBd(a.W,18);iBd(a.W,19);iBd(a.W,20);oBd(a.W,21);oBd(a.W,22);oBd(a.W,23);a.bb=jBd(a,15);iBd(a.bb,10);iBd(a.bb,11);iBd(a.bb,12);iBd(a.bb,13);iBd(a.bb,14);iBd(a.bb,15);iBd(a.bb,16);oBd(a.bb,17);nBd(a.bb);nBd(a.bb);a.eb=jBd(a,16);iBd(a.eb,2);iBd(a.eb,3);iBd(a.eb,4);iBd(a.eb,5);iBd(a.eb,6);iBd(a.eb,7);oBd(a.eb,8);oBd(a.eb,9);a.ab=jBd(a,17);iBd(a.ab,0);iBd(a.ab,1);a.H=jBd(a,18);oBd(a.H,0);oBd(a.H,1);oBd(a.H,2);oBd(a.H,3);oBd(a.H,4);oBd(a.H,5);nBd(a.H);a.db=jBd(a,19);oBd(a.db,2);a.c=kBd(a,20);a.d=kBd(a,21);a.e=kBd(a,22);a.f=kBd(a,23);a.i=kBd(a,24);a.g=kBd(a,25);a.j=kBd(a,26);a.k=kBd(a,27);a.n=kBd(a,28);a.r=kBd(a,29);a.s=kBd(a,30);a.t=kBd(a,31);a.u=kBd(a,32);a.fb=kBd(a,33);a.A=kBd(a,34);a.C=kBd(a,35);a.D=kBd(a,36);a.F=kBd(a,37);a.G=kBd(a,38);a.I=kBd(a,39);a.J=kBd(a,40);a.L=kBd(a,41);a.M=kBd(a,42);a.N=kBd(a,43);a.O=kBd(a,44);a.P=kBd(a,45);a.X=kBd(a,46);a.Y=kBd(a,47);a.Z=kBd(a,48);a.$=kBd(a,49);a._=kBd(a,50);a.cb=kBd(a,51);a.K=kBd(a,52)} +function d5b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G;g=new Yub;w=RD(mQb(c,(yCc(),rAc)),88);p=0;ye(g,(!b.a&&(b.a=new C5d(J4,b,10,11)),b.a));while(g.b!=0){k=RD(g.b==0?null:(sFb(g.b!=0),Wub(g,g.a.a)),27);j=vCd(k);(dE(Gxd(j,cAc))!==dE((kEc(),hEc))||dE(Gxd(j,pAc))===dE((Ptc(),Otc))||dE(Gxd(j,pAc))===dE((Ptc(),Mtc))||Heb(TD(Gxd(j,eAc)))||dE(Gxd(j,Yzc))!==dE((U$b(),T$b))||dE(Gxd(j,ZAc))===dE((aEc(),TDc))||dE(Gxd(j,ZAc))===dE((aEc(),UDc))||dE(Gxd(j,$Ac))===dE((_Cc(),SCc))||dE(Gxd(j,$Ac))===dE((_Cc(),UCc)))&&!Heb(TD(Gxd(k,aAc)))&&Ixd(k,(Ywc(),zwc),sgb(p++));r=!Heb(TD(Gxd(k,pBc)));if(r){m=(!k.a&&(k.a=new C5d(J4,k,10,11)),k.a).i!=0;o=a5b(k);n=dE(Gxd(k,IAc))===dE((Fnd(),Cnd));G=!Hxd(k,(umd(),Akd))||khb(WD(Gxd(k,Akd)));u=null;if(G&&n&&(m||o)){u=Z4b(k);pQb(u,rAc,w);nQb(u,PBc)&&HCc(new RCc(Kfb(UD(mQb(u,PBc)))),u);if(RD(Gxd(k,lBc),181).gc()!=0){l=u;FDb(new SDb(null,(!k.c&&(k.c=new C5d(K4,k,9,9)),new Swb(k.c,16))),new u5b(l));V4b(k,u)}}A=c;B=RD(Wjb(a.a,vCd(k)),10);!!B&&(A=B.e);t=i5b(a,k,A);if(u){t.e=u;u.e=t;ye(g,(!k.a&&(k.a=new C5d(J4,k,10,11)),k.a))}}}p=0;Pub(g,b,g.c.b,g.c);while(g.b!=0){f=RD(g.b==0?null:(sFb(g.b!=0),Wub(g,g.a.a)),27);for(i=new dMd((!f.b&&(f.b=new C5d(G4,f,12,3)),f.b));i.e!=i.i.gc();){h=RD(bMd(i),74);X4b(h);(dE(Gxd(b,cAc))!==dE((kEc(),hEc))||dE(Gxd(b,pAc))===dE((Ptc(),Otc))||dE(Gxd(b,pAc))===dE((Ptc(),Mtc))||Heb(TD(Gxd(b,eAc)))||dE(Gxd(b,Yzc))!==dE((U$b(),T$b))||dE(Gxd(b,ZAc))===dE((aEc(),TDc))||dE(Gxd(b,ZAc))===dE((aEc(),UDc))||dE(Gxd(b,$Ac))===dE((_Cc(),SCc))||dE(Gxd(b,$Ac))===dE((_Cc(),UCc)))&&Ixd(h,(Ywc(),zwc),sgb(p++));D=AGd(RD(QHd((!h.b&&(h.b=new Yie(E4,h,4,7)),h.b),0),84));F=AGd(RD(QHd((!h.c&&(h.c=new Yie(E4,h,5,8)),h.c),0),84));if(Heb(TD(Gxd(h,pBc)))||Heb(TD(Gxd(D,pBc)))||Heb(TD(Gxd(F,pBc)))){continue}q=ozd(h)&&Heb(TD(Gxd(D,NAc)))&&Heb(TD(Gxd(h,OAc)));v=f;q||NGd(F,D)?(v=D):NGd(D,F)&&(v=F);A=c;B=RD(Wjb(a.a,v),10);!!B&&(A=B.e);s=f5b(a,h,v,A);pQb(s,(Ywc(),Zvc),_4b(a,h,b,c))}n=dE(Gxd(f,IAc))===dE((Fnd(),Cnd));if(n){for(e=new dMd((!f.a&&(f.a=new C5d(J4,f,10,11)),f.a));e.e!=e.i.gc();){d=RD(bMd(e),27);G=!Hxd(d,(umd(),Akd))||khb(WD(Gxd(d,Akd)));C=dE(Gxd(d,IAc))===dE(Cnd);G&&C&&(Pub(g,d,g.c.b,g.c),true)}}}} +function Ywc(){Ywc=geb;var a,b;Awc=new jGd(rAe);Zvc=new jGd('coordinateOrigin');Kwc=new jGd('processors');Yvc=new kGd('compoundNode',(Geb(),false));nwc=new kGd('insideConnections',false);Bwc=new jGd('originalBendpoints');Cwc=new jGd('originalDummyNodePosition');Dwc=new jGd('originalLabelEdge');Mwc=new jGd('representedLabels');cwc=new jGd('endLabels');dwc=new jGd('endLabel.origin');swc=new kGd('labelSide',(Pnd(),Ond));ywc=new kGd('maxEdgeThickness',0);Nwc=new kGd('reversed',false);Lwc=new jGd(sAe);vwc=new kGd('longEdgeSource',null);wwc=new kGd('longEdgeTarget',null);uwc=new kGd('longEdgeHasLabelDummies',false);twc=new kGd('longEdgeBeforeLabelDummy',false);bwc=new kGd('edgeConstraint',(huc(),fuc));pwc=new jGd('inLayerLayoutUnit');owc=new kGd('inLayerConstraint',(Gvc(),Evc));qwc=new kGd('inLayerSuccessorConstraint',new bnb);rwc=new kGd('inLayerSuccessorConstraintBetweenNonDummies',false);Iwc=new jGd('portDummy');$vc=new kGd('crossingHint',sgb(0));kwc=new kGd('graphProperties',(b=RD(mfb(iX),9),new Fsb(b,RD(WEb(b,b.length),9),0)));hwc=new kGd('externalPortSide',(qpd(),opd));iwc=new kGd('externalPortSize',new pjd);fwc=new jGd('externalPortReplacedDummies');gwc=new jGd('externalPortReplacedDummy');ewc=new kGd('externalPortConnections',(a=RD(mfb(E3),9),new Fsb(a,RD(WEb(a,a.length),9),0)));Jwc=new kGd(Xye,0);Uvc=new jGd('barycenterAssociates');Xwc=new jGd('TopSideComments');Vvc=new jGd('BottomSideComments');Xvc=new jGd('CommentConnectionPort');mwc=new kGd('inputCollect',false);Gwc=new kGd('outputCollect',false);awc=new kGd('cyclic',false);_vc=new jGd('crossHierarchyMap');Wwc=new jGd('targetOffset');new kGd('splineLabelSize',new pjd);Qwc=new jGd('spacings');Hwc=new kGd('partitionConstraint',false);Wvc=new jGd('breakingPoint.info');Uwc=new jGd('splines.survivingEdge');Twc=new jGd('splines.route.start');Rwc=new jGd('splines.edgeChain');Fwc=new jGd('originalPortConstraints');Pwc=new jGd('selfLoopHolder');Swc=new jGd('splines.nsPortY');zwc=new jGd('modelOrder');xwc=new jGd('longEdgeTargetNode');jwc=new kGd(GBe,false);Owc=new kGd(GBe,false);lwc=new jGd('layerConstraints.hiddenNodes');Ewc=new jGd('layerConstraints.opposidePort');Vwc=new jGd('targetNode.modelOrder')} +function D0c(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o;for(l=Sub(a.b,0);l.b!=l.d.c;){k=RD(evb(l),40);if(lhb(k.c,IEe)){continue}f=RD(zDb(new SDb(null,new Swb(hWc(k,a),16)),tBb(new ZBb,new XBb,new wCb,cD(WC(QL,1),jwe,108,0,[(xBb(),vBb)]))),15);b==(Cmd(),ymd)||b==zmd?f.jd(new L1c):f.jd(new R1c);o=f.gc();for(e=0;e0){h=RD(Rub(RD(f.Xb(e),65).a),8).a;m=k.e.a+k.f.a/2;i=RD(Rub(RD(f.Xb(e),65).a),8).b;n=k.e.b+k.f.b/2;d>0&&$wnd.Math.abs(i-n)/($wnd.Math.abs(h-m)/40)>50&&(n>i?Oub(RD(f.Xb(e),65).a,new rjd(k.e.a+k.f.a+d/5.3,k.e.b+k.f.b*g-d/2)):Oub(RD(f.Xb(e),65).a,new rjd(k.e.a+k.f.a+d/5.3,k.e.b+k.f.b*g+d/2)))}Oub(RD(f.Xb(e),65).a,new rjd(k.e.a+k.f.a,k.e.b+k.f.b*g))}else if(b==zmd){j=Kfb(UD(mQb(k,(q$c(),f$c))));if(k.e.a-d>j){Oub(RD(f.Xb(e),65).a,new rjd(j-c,k.e.b+k.f.b*g))}else if(RD(f.Xb(e),65).a.b>0){h=RD(Rub(RD(f.Xb(e),65).a),8).a;m=k.e.a+k.f.a/2;i=RD(Rub(RD(f.Xb(e),65).a),8).b;n=k.e.b+k.f.b/2;d>0&&$wnd.Math.abs(i-n)/($wnd.Math.abs(h-m)/40)>50&&(n>i?Oub(RD(f.Xb(e),65).a,new rjd(k.e.a-d/5.3,k.e.b+k.f.b*g-d/2)):Oub(RD(f.Xb(e),65).a,new rjd(k.e.a-d/5.3,k.e.b+k.f.b*g+d/2)))}Oub(RD(f.Xb(e),65).a,new rjd(k.e.a,k.e.b+k.f.b*g))}else if(b==Bmd){j=Kfb(UD(mQb(k,(q$c(),e$c))));if(k.e.b+k.f.b+d0){h=RD(Rub(RD(f.Xb(e),65).a),8).a;m=k.e.a+k.f.a/2;i=RD(Rub(RD(f.Xb(e),65).a),8).b;n=k.e.b+k.f.b/2;d>0&&$wnd.Math.abs(h-m)/($wnd.Math.abs(i-n)/40)>50&&(m>h?Oub(RD(f.Xb(e),65).a,new rjd(k.e.a+k.f.a*g-d/2,k.e.b+d/5.3+k.f.b)):Oub(RD(f.Xb(e),65).a,new rjd(k.e.a+k.f.a*g+d/2,k.e.b+d/5.3+k.f.b)))}Oub(RD(f.Xb(e),65).a,new rjd(k.e.a+k.f.a*g,k.e.b+k.f.b))}else{j=Kfb(UD(mQb(k,(q$c(),f$c))));if(mWc(RD(f.Xb(e),65),a)){Oub(RD(f.Xb(e),65).a,new rjd(k.e.a+k.f.a*g,RD(Rub(RD(f.Xb(e),65).a),8).b))}else if(k.e.b-d>j){Oub(RD(f.Xb(e),65).a,new rjd(k.e.a+k.f.a*g,j-c))}else if(RD(f.Xb(e),65).a.b>0){h=RD(Rub(RD(f.Xb(e),65).a),8).a;m=k.e.a+k.f.a/2;i=RD(Rub(RD(f.Xb(e),65).a),8).b;n=k.e.b+k.f.b/2;d>0&&$wnd.Math.abs(h-m)/($wnd.Math.abs(i-n)/40)>50&&(m>h?Oub(RD(f.Xb(e),65).a,new rjd(k.e.a+k.f.a*g-d/2,k.e.b-d/5.3)):Oub(RD(f.Xb(e),65).a,new rjd(k.e.a+k.f.a*g+d/2,k.e.b-d/5.3)))}Oub(RD(f.Xb(e),65).a,new rjd(k.e.a+k.f.a*g,k.e.b))}}}} +function umd(){umd=geb;var a,b;Akd=new jGd(OGe);Tld=new jGd(PGe);Ckd=(Rjd(),Ljd);Bkd=new lGd(MDe,Ckd);new Xsd;Dkd=new lGd(Dze,null);Ekd=new jGd(QGe);Lkd=(ukd(),ysb(tkd,cD(WC(q3,1),jwe,298,0,[pkd])));Kkd=new lGd(YDe,Lkd);Mkd=new lGd(LDe,(Geb(),false));Okd=(Cmd(),Amd);Nkd=new lGd(PDe,Okd);Tkd=(Ymd(),Xmd);Skd=new lGd(kDe,Tkd);Wkd=new lGd(MGe,false);Ykd=(Fnd(),Dnd);Xkd=new lGd(fDe,Ykd);uld=new A3b(12);tld=new lGd(Eze,uld);ald=new lGd(dAe,false);bld=new lGd(iEe,false);sld=new lGd(gAe,false);Ild=(Bod(),Aod);Hld=new lGd(eAe,Ild);Qld=new jGd(fEe);Rld=new jGd($ze);Sld=new jGd(bAe);Vld=new jGd(cAe);dld=new Ejd;cld=new lGd(ZDe,dld);Jkd=new lGd(aEe,false);Zkd=new lGd(bEe,false);new jGd(RGe);fld=new P2b;eld=new lGd(gEe,fld);rld=new lGd(JDe,false);new Xsd;Uld=new lGd(SGe,1);Ikd=new jGd(TGe);Hkd=new jGd(UGe);mmd=new lGd(mAe,false);new lGd(VGe,true);sgb(0);new lGd(WGe,sgb(100));new lGd(XGe,false);sgb(0);new lGd(YGe,sgb(4000));sgb(0);new lGd(ZGe,sgb(400));new lGd($Ge,false);new lGd(_Ge,false);new lGd(aHe,true);new lGd(bHe,false);Gkd=(Grd(),Frd);Fkd=new lGd(NGe,Gkd);Wld=new lGd(xDe,10);Xld=new lGd(yDe,10);Yld=new lGd(Bze,20);Zld=new lGd(zDe,10);$ld=new lGd(aAe,2);_ld=new lGd(ADe,10);bmd=new lGd(BDe,0);cmd=new lGd(EDe,5);dmd=new lGd(CDe,1);emd=new lGd(DDe,1);fmd=new lGd(_ze,20);gmd=new lGd(FDe,10);jmd=new lGd(GDe,10);amd=new jGd(HDe);imd=new Q2b;hmd=new lGd(hEe,imd);xld=new jGd(eEe);wld=false;vld=new lGd(dEe,wld);hld=new A3b(5);gld=new lGd(QDe,hld);jld=(dod(),b=RD(mfb(A3),9),new Fsb(b,RD(WEb(b,b.length),9),0));ild=new lGd(kAe,jld);Ald=(pod(),mod);zld=new lGd(TDe,Ald);Cld=new jGd(UDe);Dld=new jGd(VDe);Eld=new jGd(WDe);Bld=new jGd(XDe);lld=(a=RD(mfb(H3),9),new Fsb(a,RD(WEb(a,a.length),9),0));kld=new lGd(jAe,lld);qld=xsb((dqd(),Ypd));pld=new lGd(iAe,qld);old=new rjd(0,0);nld=new lGd(CAe,old);mld=new lGd(hAe,false);Rkd=(Omd(),Lmd);Qkd=new lGd($De,Rkd);Pkd=new lGd(fAe,false);new jGd(cHe);sgb(1);new lGd(dHe,null);Fld=new jGd(cEe);Jld=new jGd(_De);Pld=(qpd(),opd);Old=new lGd(KDe,Pld);Gld=new jGd(IDe);Mld=(Pod(),xsb(Nod));Lld=new lGd(lAe,Mld);Kld=new lGd(RDe,false);Nld=new lGd(SDe,true);new Xsd;qmd=new lGd(nAe,1);smd=new lGd(eHe,null);lmd=new lGd(oAe,150);kmd=new lGd(pAe,1.414);nmd=new lGd(qAe,null);omd=new lGd(fHe,1);$kd=new lGd(NDe,false);_kd=new lGd(ODe,false);Ukd=new lGd(Cze,1);Vkd=(ind(),gnd);new lGd(gHe,Vkd);yld=true;rmd=(mqd(),jqd);tmd=jqd;pmd=jqd} +function hcc(){hcc=geb;nbc=new icc('DIRECTION_PREPROCESSOR',0);kbc=new icc('COMMENT_PREPROCESSOR',1);obc=new icc('EDGE_AND_LAYER_CONSTRAINT_EDGE_REVERSER',2);Ebc=new icc('INTERACTIVE_EXTERNAL_PORT_POSITIONER',3);Xbc=new icc('PARTITION_PREPROCESSOR',4);Ibc=new icc('LABEL_DUMMY_INSERTER',5);bcc=new icc('SELF_LOOP_PREPROCESSOR',6);Nbc=new icc('LAYER_CONSTRAINT_PREPROCESSOR',7);Vbc=new icc('PARTITION_MIDPROCESSOR',8);zbc=new icc('HIGH_DEGREE_NODE_LAYER_PROCESSOR',9);Rbc=new icc('NODE_PROMOTION',10);Mbc=new icc('LAYER_CONSTRAINT_POSTPROCESSOR',11);Wbc=new icc('PARTITION_POSTPROCESSOR',12);vbc=new icc('HIERARCHICAL_PORT_CONSTRAINT_PROCESSOR',13);dcc=new icc('SEMI_INTERACTIVE_CROSSMIN_PROCESSOR',14);ebc=new icc('BREAKING_POINT_INSERTER',15);Qbc=new icc('LONG_EDGE_SPLITTER',16);Zbc=new icc('PORT_SIDE_PROCESSOR',17);Fbc=new icc('INVERTED_PORT_PROCESSOR',18);Ybc=new icc('PORT_LIST_SORTER',19);fcc=new icc('SORT_BY_INPUT_ORDER_OF_MODEL',20);Tbc=new icc('NORTH_SOUTH_PORT_PREPROCESSOR',21);fbc=new icc('BREAKING_POINT_PROCESSOR',22);Ubc=new icc(jBe,23);gcc=new icc(kBe,24);_bc=new icc('SELF_LOOP_PORT_RESTORER',25);ecc=new icc('SINGLE_EDGE_GRAPH_WRAPPER',26);Gbc=new icc('IN_LAYER_CONSTRAINT_PROCESSOR',27);sbc=new icc('END_NODE_PORT_LABEL_MANAGEMENT_PROCESSOR',28);Hbc=new icc('LABEL_AND_NODE_SIZE_PROCESSOR',29);Dbc=new icc('INNERMOST_NODE_MARGIN_CALCULATOR',30);ccc=new icc('SELF_LOOP_ROUTER',31);ibc=new icc('COMMENT_NODE_MARGIN_CALCULATOR',32);qbc=new icc('END_LABEL_PREPROCESSOR',33);Kbc=new icc('LABEL_DUMMY_SWITCHER',34);hbc=new icc('CENTER_LABEL_MANAGEMENT_PROCESSOR',35);Lbc=new icc('LABEL_SIDE_SELECTOR',36);Bbc=new icc('HYPEREDGE_DUMMY_MERGER',37);wbc=new icc('HIERARCHICAL_PORT_DUMMY_SIZE_PROCESSOR',38);Obc=new icc('LAYER_SIZE_AND_GRAPH_HEIGHT_CALCULATOR',39);ybc=new icc('HIERARCHICAL_PORT_POSITION_PROCESSOR',40);lbc=new icc('CONSTRAINTS_POSTPROCESSOR',41);jbc=new icc('COMMENT_POSTPROCESSOR',42);Cbc=new icc('HYPERNODE_PROCESSOR',43);xbc=new icc('HIERARCHICAL_PORT_ORTHOGONAL_EDGE_ROUTER',44);Pbc=new icc('LONG_EDGE_JOINER',45);acc=new icc('SELF_LOOP_POSTPROCESSOR',46);gbc=new icc('BREAKING_POINT_REMOVER',47);Sbc=new icc('NORTH_SOUTH_PORT_POSTPROCESSOR',48);Abc=new icc('HORIZONTAL_COMPACTOR',49);Jbc=new icc('LABEL_DUMMY_REMOVER',50);tbc=new icc('FINAL_SPLINE_BENDPOINTS_CALCULATOR',51);rbc=new icc('END_LABEL_SORTER',52);$bc=new icc('REVERSED_EDGE_RESTORER',53);pbc=new icc('END_LABEL_POSTPROCESSOR',54);ubc=new icc('HIERARCHICAL_NODE_RESIZER',55);mbc=new icc('DIRECTION_POSTPROCESSOR',56)} +function Ozc(){Ozc=geb;Uxc=($tc(),Ytc);Txc=new lGd(HBe,Uxc);jyc=new lGd(IBe,(Geb(),false));pyc=(Ovc(),Mvc);oyc=new lGd(JBe,pyc);Hyc=new lGd(KBe,false);Iyc=new lGd(LBe,true);ixc=new lGd(MBe,false);azc=(sEc(),qEc);_yc=new lGd(NBe,azc);sgb(1);izc=new lGd(OBe,sgb(7));jzc=new lGd(PBe,false);kyc=new lGd(QBe,false);Sxc=(Ptc(),Ltc);Rxc=new lGd(RBe,Sxc);Gyc=(_Cc(),ZCc);Fyc=new lGd(SBe,Gyc);wyc=(cxc(),bxc);vyc=new lGd(TBe,wyc);sgb(-1);uyc=new lGd(UBe,null);sgb(-1);xyc=new lGd(VBe,sgb(-1));sgb(-1);yyc=new lGd(WBe,sgb(4));sgb(-1);Ayc=new lGd(XBe,sgb(2));Eyc=(aEc(),$Dc);Dyc=new lGd(YBe,Eyc);sgb(0);Cyc=new lGd(ZBe,sgb(0));syc=new lGd($Be,sgb(lve));Qxc=(stc(),qtc);Pxc=new lGd(_Be,Qxc);yxc=new lGd(aCe,false);Hxc=new lGd(bCe,0.1);Nxc=new lGd(cCe,false);Jxc=new lGd(dCe,null);Kxc=new lGd(eCe,null);sgb(-1);Lxc=new lGd(fCe,null);sgb(-1);Mxc=new lGd(gCe,sgb(-1));sgb(0);zxc=new lGd(hCe,sgb(40));Fxc=(xvc(),wvc);Exc=new lGd(iCe,Fxc);Bxc=uvc;Axc=new lGd(jCe,Bxc);$yc=(JDc(),EDc);Zyc=new lGd(kCe,$yc);Pyc=new jGd(lCe);Kyc=(Cuc(),Auc);Jyc=new lGd(mCe,Kyc);Nyc=(Ouc(),Luc);Myc=new lGd(nCe,Nyc);new Xsd;Syc=new lGd(oCe,0.3);Uyc=new jGd(pCe);Wyc=(wDc(),uDc);Vyc=new lGd(qCe,Wyc);ayc=(KEc(),IEc);_xc=new lGd(rCe,ayc);cyc=(TEc(),SEc);byc=new lGd(sCe,cyc);eyc=(lFc(),kFc);dyc=new lGd(tCe,eyc);gyc=new lGd(uCe,0.2);Zxc=new lGd(vCe,2);ezc=new lGd(wCe,null);gzc=new lGd(xCe,10);fzc=new lGd(yCe,10);hzc=new lGd(zCe,20);sgb(0);bzc=new lGd(ACe,sgb(0));sgb(0);czc=new lGd(BCe,sgb(0));sgb(0);dzc=new lGd(CCe,sgb(0));jxc=new lGd(DCe,false);nxc=($uc(),Yuc);mxc=new lGd(ECe,nxc);lxc=(jtc(),itc);kxc=new lGd(FCe,lxc);myc=new lGd(GCe,false);sgb(0);lyc=new lGd(HCe,sgb(16));sgb(0);nyc=new lGd(ICe,sgb(5));Gzc=(DFc(),BFc);Fzc=new lGd(JCe,Gzc);kzc=new lGd(KCe,10);nzc=new lGd(LCe,1);wzc=(Etc(),Dtc);vzc=new lGd(MCe,wzc);qzc=new jGd(NCe);tzc=sgb(1);sgb(0);szc=new lGd(OCe,tzc);Lzc=(uFc(),rFc);Kzc=new lGd(PCe,Lzc);Hzc=new jGd(QCe);Bzc=new lGd(RCe,true);zzc=new lGd(SCe,2);Dzc=new lGd(TCe,true);Yxc=(tuc(),ruc);Xxc=new lGd(UCe,Yxc);Wxc=(btc(),Zsc);Vxc=new lGd(VCe,Wxc);xxc=(kEc(),hEc);wxc=new lGd(WCe,xxc);vxc=new lGd(XCe,false);uxc=new lGd(YCe,false);pxc=(U$b(),T$b);oxc=new lGd(ZCe,pxc);txc=(lDc(),iDc);sxc=new lGd($Ce,txc);qxc=new lGd(_Ce,0);rxc=new lGd(aDe,0);ryc=Ntc;qyc=ptc;zyc=YCc;Byc=YCc;tyc=TCc;Ixc=(Fnd(),Cnd);Oxc=qtc;Gxc=qtc;Cxc=qtc;Dxc=Cnd;Qyc=HDc;Ryc=EDc;Lyc=EDc;Oyc=EDc;Tyc=GDc;Yyc=HDc;Xyc=HDc;fyc=(Ymd(),Wmd);hyc=Wmd;iyc=kFc;$xc=Vmd;lzc=CFc;mzc=AFc;ozc=CFc;pzc=AFc;xzc=CFc;yzc=AFc;rzc=Ctc;uzc=Dtc;Mzc=CFc;Nzc=AFc;Izc=CFc;Jzc=AFc;Czc=AFc;Azc=AFc;Ezc=AFc} +function iNc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,ab,bb,cb,db,eb,fb,gb,hb,ib,jb,kb,lb;cb=0;for(H=b,K=0,N=H.length;K0&&(a.a[U.p]=cb++)}}hb=0;for(I=c,L=0,O=I.length;L0){U=(sFb(Y.b>0),RD(Y.a.Xb(Y.c=--Y.b),12));X=0;for(h=new Anb(U.e);h.a0){if(U.j==(qpd(),Yod)){a.a[U.p]=hb;++hb}else{a.a[U.p]=hb+P+R;++R}}}hb+=R}W=new Tsb;o=new Iub;for(G=b,J=0,M=G.length;Jj.b&&(j.b=Z)}else if(U.i.c==bb){Zj.c&&(j.c=Z)}}}Wnb(p,0,p.length,null);gb=$C(kE,Pwe,28,p.length,15,1);d=$C(kE,Pwe,28,hb+1,15,1);for(r=0;r0){A%2>0&&(e+=kb[A+1]);A=(A-1)/2|0;++kb[A]}}C=$C(NY,rve,374,p.length*2,0,1);for(u=0;u0&&(ltd(J.f),false)){if(RD(Gxd(r,nmd),280)==jqd){throw Adb(new Jed('Topdown Layout Providers should only be used on parallel nodes.'))}fE(ltd(J.f));null.Um();zyd(r,$wnd.Math.max(r.g,null.Vm),$wnd.Math.max(r.f,null.Vm))}else if(Gxd(r,smd)!=null){h=RD(Gxd(r,smd),347);W=h.Tg(r);zyd(r,$wnd.Math.max(r.g,W.a),$wnd.Math.max(r.f,W.b))}}}O=RD(Gxd(b,tld),107);n=b.g-(O.b+O.c);m=b.f-(O.d+O.a);Z.bh('Available Child Area: ('+n+'|'+m+')');Ixd(b,Dkd,n/m);Ced(b,e,d.eh(M));if(RD(Gxd(b,nmd),280)==lqd){psd(b);zyd(b,O.b+Kfb(UD(Gxd(b,Ikd)))+O.c,O.d+Kfb(UD(Gxd(b,Hkd)))+O.a)}Z.bh('Executed layout algorithm: '+WD(Gxd(b,Akd))+' on node '+b.k);if(RD(Gxd(b,nmd),280)==jqd){if(n<0||m<0){throw Adb(new Jed('The size defined by the parent parallel node is too small for the space provided by the paddings of the child hierarchical node. '+b.k))}Hxd(b,Ikd)||Hxd(b,Hkd)||psd(b);p=Kfb(UD(Gxd(b,Ikd)));o=Kfb(UD(Gxd(b,Hkd)));Z.bh('Desired Child Area: ('+p+'|'+o+')');Q=n/p;R=m/o;P=$wnd.Math.min(Q,$wnd.Math.min(R,Kfb(UD(Gxd(b,omd)))));Ixd(b,qmd,P);Z.bh(b.k+' -- Local Scale Factor (X|Y): ('+Q+'|'+R+')');u=RD(Gxd(b,Kkd),21);f=0;g=0;P'?":lhb(XIe,a)?"'(?<' or '(? toIndex: ',bye=', toIndex: ',cye='Index: ',dye=', Size: ',eye='org.eclipse.elk.alg.common',fye={50:1},gye='org.eclipse.elk.alg.common.compaction',hye='Scanline/EventHandler',iye='org.eclipse.elk.alg.common.compaction.oned',jye='CNode belongs to another CGroup.',kye='ISpacingsHandler/1',lye='The ',mye=' instance has been finished already.',nye='The direction ',oye=' is not supported by the CGraph instance.',pye='OneDimensionalCompactor',qye='OneDimensionalCompactor/lambda$0$Type',rye='Quadruplet',sye='ScanlineConstraintCalculator',tye='ScanlineConstraintCalculator/ConstraintsScanlineHandler',uye='ScanlineConstraintCalculator/ConstraintsScanlineHandler/lambda$0$Type',vye='ScanlineConstraintCalculator/Timestamp',wye='ScanlineConstraintCalculator/lambda$0$Type',xye={178:1,46:1},yye='org.eclipse.elk.alg.common.compaction.options',zye='org.eclipse.elk.core.data',Aye='org.eclipse.elk.polyomino.traversalStrategy',Bye='org.eclipse.elk.polyomino.lowLevelSort',Cye='org.eclipse.elk.polyomino.highLevelSort',Dye='org.eclipse.elk.polyomino.fill',Eye={134:1},Fye='polyomino',Gye='org.eclipse.elk.alg.common.networksimplex',Hye={183:1,3:1,4:1},Iye='org.eclipse.elk.alg.common.nodespacing',Jye='org.eclipse.elk.alg.common.nodespacing.cellsystem',Kye='CENTER',Lye={217:1,336:1},Mye={3:1,4:1,5:1,603:1},Nye='LEFT',Oye='RIGHT',Pye='Vertical alignment cannot be null',Qye='BOTTOM',Rye='org.eclipse.elk.alg.common.nodespacing.internal',Sye='UNDEFINED',Tye=0.01,Uye='org.eclipse.elk.alg.common.nodespacing.internal.algorithm',Vye='LabelPlacer/lambda$0$Type',Wye='LabelPlacer/lambda$1$Type',Xye='portRatioOrPosition',Yye='org.eclipse.elk.alg.common.overlaps',Zye='DOWN',$ye='org.eclipse.elk.alg.common.polyomino',_ye='NORTH',aze='EAST',bze='SOUTH',cze='WEST',dze='org.eclipse.elk.alg.common.polyomino.structures',eze='Direction',fze='Grid is only of size ',gze='. Requested point (',hze=') is out of bounds.',ize=' Given center based coordinates were (',jze='org.eclipse.elk.graph.properties',kze='IPropertyHolder',lze={3:1,96:1,137:1},mze='org.eclipse.elk.alg.common.spore',nze='org.eclipse.elk.alg.common.utils',oze={205:1},pze='org.eclipse.elk.core',qze='Connected Components Compaction',rze='org.eclipse.elk.alg.disco',sze='org.eclipse.elk.alg.disco.graph',tze='org.eclipse.elk.alg.disco.options',uze='CompactionStrategy',vze='org.eclipse.elk.disco.componentCompaction.strategy',wze='org.eclipse.elk.disco.componentCompaction.componentLayoutAlgorithm',xze='org.eclipse.elk.disco.debug.discoGraph',yze='org.eclipse.elk.disco.debug.discoPolys',zze='componentCompaction',Aze='org.eclipse.elk.disco',Bze='org.eclipse.elk.spacing.componentComponent',Cze='org.eclipse.elk.edge.thickness',Dze='org.eclipse.elk.aspectRatio',Eze='org.eclipse.elk.padding',Fze='org.eclipse.elk.alg.disco.transform',Gze=1.5707963267948966,Hze=1.7976931348623157E308,Ize={3:1,4:1,5:1,198:1},Jze={3:1,6:1,4:1,5:1,100:1,115:1},Kze='org.eclipse.elk.alg.force',Lze='ComponentsProcessor',Mze='ComponentsProcessor/1',Nze='ElkGraphImporter/lambda$0$Type',Oze='org.eclipse.elk.alg.force.graph',Pze='Component Layout',Qze='org.eclipse.elk.alg.force.model',Rze='org.eclipse.elk.force.model',Sze='org.eclipse.elk.force.iterations',Tze='org.eclipse.elk.force.repulsivePower',Uze='org.eclipse.elk.force.temperature',Vze=0.001,Wze='org.eclipse.elk.force.repulsion',Xze='org.eclipse.elk.alg.force.options',Yze=1.600000023841858,Zze='org.eclipse.elk.force',$ze='org.eclipse.elk.priority',_ze='org.eclipse.elk.spacing.nodeNode',aAe='org.eclipse.elk.spacing.edgeLabel',bAe='org.eclipse.elk.randomSeed',cAe='org.eclipse.elk.separateConnectedComponents',dAe='org.eclipse.elk.interactive',eAe='org.eclipse.elk.portConstraints',fAe='org.eclipse.elk.edgeLabels.inline',gAe='org.eclipse.elk.omitNodeMicroLayout',hAe='org.eclipse.elk.nodeSize.fixedGraphSize',iAe='org.eclipse.elk.nodeSize.options',jAe='org.eclipse.elk.nodeSize.constraints',kAe='org.eclipse.elk.nodeLabels.placement',lAe='org.eclipse.elk.portLabels.placement',mAe='org.eclipse.elk.topdownLayout',nAe='org.eclipse.elk.topdown.scaleFactor',oAe='org.eclipse.elk.topdown.hierarchicalNodeWidth',pAe='org.eclipse.elk.topdown.hierarchicalNodeAspectRatio',qAe='org.eclipse.elk.topdown.nodeType',rAe='origin',sAe='random',tAe='boundingBox.upLeft',uAe='boundingBox.lowRight',vAe='org.eclipse.elk.stress.fixed',wAe='org.eclipse.elk.stress.desiredEdgeLength',xAe='org.eclipse.elk.stress.dimension',yAe='org.eclipse.elk.stress.epsilon',zAe='org.eclipse.elk.stress.iterationLimit',AAe='org.eclipse.elk.stress',BAe='ELK Stress',CAe='org.eclipse.elk.nodeSize.minimum',DAe='org.eclipse.elk.alg.force.stress',EAe='Layered layout',FAe='org.eclipse.elk.alg.layered',GAe='org.eclipse.elk.alg.layered.compaction.components',HAe='org.eclipse.elk.alg.layered.compaction.oned',IAe='org.eclipse.elk.alg.layered.compaction.oned.algs',JAe='org.eclipse.elk.alg.layered.compaction.recthull',KAe='org.eclipse.elk.alg.layered.components',LAe='NONE',MAe='MODEL_ORDER',NAe={3:1,6:1,4:1,9:1,5:1,126:1},OAe={3:1,6:1,4:1,5:1,150:1,100:1,115:1},PAe='org.eclipse.elk.alg.layered.compound',QAe={47:1},RAe='org.eclipse.elk.alg.layered.graph',SAe=' -> ',TAe='Not supported by LGraph',UAe='Port side is undefined',VAe={3:1,6:1,4:1,5:1,483:1,150:1,100:1,115:1},WAe={3:1,6:1,4:1,5:1,150:1,199:1,210:1,100:1,115:1},XAe={3:1,6:1,4:1,5:1,150:1,2042:1,210:1,100:1,115:1},YAe='([{"\' \t\r\n',ZAe=')]}"\' \t\r\n',$Ae='The given string contains parts that cannot be parsed as numbers.',_Ae='org.eclipse.elk.core.math',aBe={3:1,4:1,140:1,214:1,423:1},bBe={3:1,4:1,107:1,214:1,423:1},cBe='org.eclipse.elk.alg.layered.graph.transform',dBe='ElkGraphImporter',eBe='ElkGraphImporter/lambda$1$Type',fBe='ElkGraphImporter/lambda$2$Type',gBe='ElkGraphImporter/lambda$4$Type',hBe='org.eclipse.elk.alg.layered.intermediate',iBe='Node margin calculation',jBe='ONE_SIDED_GREEDY_SWITCH',kBe='TWO_SIDED_GREEDY_SWITCH',lBe='No implementation is available for the layout processor ',mBe='IntermediateProcessorStrategy',nBe="Node '",oBe='FIRST_SEPARATE',pBe='LAST_SEPARATE',qBe='Odd port side processing',rBe='org.eclipse.elk.alg.layered.intermediate.compaction',sBe='org.eclipse.elk.alg.layered.intermediate.greedyswitch',tBe='org.eclipse.elk.alg.layered.p3order.counting',uBe={230:1},vBe='org.eclipse.elk.alg.layered.intermediate.loops',wBe='org.eclipse.elk.alg.layered.intermediate.loops.ordering',xBe='org.eclipse.elk.alg.layered.intermediate.loops.routing',yBe='org.eclipse.elk.alg.layered.intermediate.preserveorder',zBe='org.eclipse.elk.alg.layered.intermediate.wrapping',ABe='org.eclipse.elk.alg.layered.options',BBe='INTERACTIVE',CBe='GREEDY',DBe='DEPTH_FIRST',EBe='EDGE_LENGTH',FBe='SELF_LOOPS',GBe='firstTryWithInitialOrder',HBe='org.eclipse.elk.layered.directionCongruency',IBe='org.eclipse.elk.layered.feedbackEdges',JBe='org.eclipse.elk.layered.interactiveReferencePoint',KBe='org.eclipse.elk.layered.mergeEdges',LBe='org.eclipse.elk.layered.mergeHierarchyEdges',MBe='org.eclipse.elk.layered.allowNonFlowPortsToSwitchSides',NBe='org.eclipse.elk.layered.portSortingStrategy',OBe='org.eclipse.elk.layered.thoroughness',PBe='org.eclipse.elk.layered.unnecessaryBendpoints',QBe='org.eclipse.elk.layered.generatePositionAndLayerIds',RBe='org.eclipse.elk.layered.cycleBreaking.strategy',SBe='org.eclipse.elk.layered.layering.strategy',TBe='org.eclipse.elk.layered.layering.layerConstraint',UBe='org.eclipse.elk.layered.layering.layerChoiceConstraint',VBe='org.eclipse.elk.layered.layering.layerId',WBe='org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth',XBe='org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor',YBe='org.eclipse.elk.layered.layering.nodePromotion.strategy',ZBe='org.eclipse.elk.layered.layering.nodePromotion.maxIterations',$Be='org.eclipse.elk.layered.layering.coffmanGraham.layerBound',_Be='org.eclipse.elk.layered.crossingMinimization.strategy',aCe='org.eclipse.elk.layered.crossingMinimization.forceNodeModelOrder',bCe='org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness',cCe='org.eclipse.elk.layered.crossingMinimization.semiInteractive',dCe='org.eclipse.elk.layered.crossingMinimization.inLayerPredOf',eCe='org.eclipse.elk.layered.crossingMinimization.inLayerSuccOf',fCe='org.eclipse.elk.layered.crossingMinimization.positionChoiceConstraint',gCe='org.eclipse.elk.layered.crossingMinimization.positionId',hCe='org.eclipse.elk.layered.crossingMinimization.greedySwitch.activationThreshold',iCe='org.eclipse.elk.layered.crossingMinimization.greedySwitch.type',jCe='org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type',kCe='org.eclipse.elk.layered.nodePlacement.strategy',lCe='org.eclipse.elk.layered.nodePlacement.favorStraightEdges',mCe='org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening',nCe='org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment',oCe='org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening',pCe='org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility',qCe='org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default',rCe='org.eclipse.elk.layered.edgeRouting.selfLoopDistribution',sCe='org.eclipse.elk.layered.edgeRouting.selfLoopOrdering',tCe='org.eclipse.elk.layered.edgeRouting.splines.mode',uCe='org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor',vCe='org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth',wCe='org.eclipse.elk.layered.spacing.baseValue',xCe='org.eclipse.elk.layered.spacing.edgeNodeBetweenLayers',yCe='org.eclipse.elk.layered.spacing.edgeEdgeBetweenLayers',zCe='org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers',ACe='org.eclipse.elk.layered.priority.direction',BCe='org.eclipse.elk.layered.priority.shortness',CCe='org.eclipse.elk.layered.priority.straightness',DCe='org.eclipse.elk.layered.compaction.connectedComponents',ECe='org.eclipse.elk.layered.compaction.postCompaction.strategy',FCe='org.eclipse.elk.layered.compaction.postCompaction.constraints',GCe='org.eclipse.elk.layered.highDegreeNodes.treatment',HCe='org.eclipse.elk.layered.highDegreeNodes.threshold',ICe='org.eclipse.elk.layered.highDegreeNodes.treeHeight',JCe='org.eclipse.elk.layered.wrapping.strategy',KCe='org.eclipse.elk.layered.wrapping.additionalEdgeSpacing',LCe='org.eclipse.elk.layered.wrapping.correctionFactor',MCe='org.eclipse.elk.layered.wrapping.cutting.strategy',NCe='org.eclipse.elk.layered.wrapping.cutting.cuts',OCe='org.eclipse.elk.layered.wrapping.cutting.msd.freedom',PCe='org.eclipse.elk.layered.wrapping.validify.strategy',QCe='org.eclipse.elk.layered.wrapping.validify.forbiddenIndices',RCe='org.eclipse.elk.layered.wrapping.multiEdge.improveCuts',SCe='org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty',TCe='org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges',UCe='org.eclipse.elk.layered.edgeLabels.sideSelection',VCe='org.eclipse.elk.layered.edgeLabels.centerLabelPlacementStrategy',WCe='org.eclipse.elk.layered.considerModelOrder.strategy',XCe='org.eclipse.elk.layered.considerModelOrder.portModelOrder',YCe='org.eclipse.elk.layered.considerModelOrder.noModelOrder',ZCe='org.eclipse.elk.layered.considerModelOrder.components',$Ce='org.eclipse.elk.layered.considerModelOrder.longEdgeStrategy',_Ce='org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence',aDe='org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence',bDe='layering',cDe='layering.minWidth',dDe='layering.nodePromotion',eDe='crossingMinimization',fDe='org.eclipse.elk.hierarchyHandling',gDe='crossingMinimization.greedySwitch',hDe='nodePlacement',iDe='nodePlacement.bk',jDe='edgeRouting',kDe='org.eclipse.elk.edgeRouting',lDe='spacing',mDe='priority',nDe='compaction',oDe='compaction.postCompaction',pDe='Specifies whether and how post-process compaction is applied.',qDe='highDegreeNodes',rDe='wrapping',sDe='wrapping.cutting',tDe='wrapping.validify',uDe='wrapping.multiEdge',vDe='edgeLabels',wDe='considerModelOrder',xDe='org.eclipse.elk.spacing.commentComment',yDe='org.eclipse.elk.spacing.commentNode',zDe='org.eclipse.elk.spacing.edgeEdge',ADe='org.eclipse.elk.spacing.edgeNode',BDe='org.eclipse.elk.spacing.labelLabel',CDe='org.eclipse.elk.spacing.labelPortHorizontal',DDe='org.eclipse.elk.spacing.labelPortVertical',EDe='org.eclipse.elk.spacing.labelNode',FDe='org.eclipse.elk.spacing.nodeSelfLoop',GDe='org.eclipse.elk.spacing.portPort',HDe='org.eclipse.elk.spacing.individual',IDe='org.eclipse.elk.port.borderOffset',JDe='org.eclipse.elk.noLayout',KDe='org.eclipse.elk.port.side',LDe='org.eclipse.elk.debugMode',MDe='org.eclipse.elk.alignment',NDe='org.eclipse.elk.insideSelfLoops.activate',ODe='org.eclipse.elk.insideSelfLoops.yo',PDe='org.eclipse.elk.direction',QDe='org.eclipse.elk.nodeLabels.padding',RDe='org.eclipse.elk.portLabels.nextToPortIfPossible',SDe='org.eclipse.elk.portLabels.treatAsGroup',TDe='org.eclipse.elk.portAlignment.default',UDe='org.eclipse.elk.portAlignment.north',VDe='org.eclipse.elk.portAlignment.south',WDe='org.eclipse.elk.portAlignment.west',XDe='org.eclipse.elk.portAlignment.east',YDe='org.eclipse.elk.contentAlignment',ZDe='org.eclipse.elk.junctionPoints',$De='org.eclipse.elk.edgeLabels.placement',_De='org.eclipse.elk.port.index',aEe='org.eclipse.elk.commentBox',bEe='org.eclipse.elk.hypernode',cEe='org.eclipse.elk.port.anchor',dEe='org.eclipse.elk.partitioning.activate',eEe='org.eclipse.elk.partitioning.partition',fEe='org.eclipse.elk.position',gEe='org.eclipse.elk.margins',hEe='org.eclipse.elk.spacing.portsSurrounding',iEe='org.eclipse.elk.interactiveLayout',jEe='org.eclipse.elk.core.util',kEe={3:1,4:1,5:1,601:1},lEe='NETWORK_SIMPLEX',mEe='SIMPLE',nEe={106:1,47:1},oEe='org.eclipse.elk.alg.layered.p1cycles',pEe='org.eclipse.elk.alg.layered.p2layers',qEe={413:1,230:1},rEe={846:1,3:1,4:1},sEe='org.eclipse.elk.alg.layered.p3order',tEe='org.eclipse.elk.alg.layered.p4nodes',uEe={3:1,4:1,5:1,854:1},vEe=1.0E-5,wEe='org.eclipse.elk.alg.layered.p4nodes.bk',xEe='org.eclipse.elk.alg.layered.p5edges',yEe='org.eclipse.elk.alg.layered.p5edges.orthogonal',zEe='org.eclipse.elk.alg.layered.p5edges.orthogonal.direction',AEe=1.0E-6,BEe='org.eclipse.elk.alg.layered.p5edges.splines',CEe=0.09999999999999998,DEe=1.0E-8,EEe=4.71238898038469,FEe=3.141592653589793,GEe='org.eclipse.elk.alg.mrtree',HEe=0.10000000149011612,IEe='SUPER_ROOT',JEe='org.eclipse.elk.alg.mrtree.graph',KEe=-1.7976931348623157E308,LEe='org.eclipse.elk.alg.mrtree.intermediate',MEe='Processor compute fanout',NEe={3:1,6:1,4:1,5:1,534:1,100:1,115:1},OEe='Set neighbors in level',PEe='org.eclipse.elk.alg.mrtree.options',QEe='DESCENDANTS',REe='org.eclipse.elk.mrtree.compaction',SEe='org.eclipse.elk.mrtree.edgeEndTextureLength',TEe='org.eclipse.elk.mrtree.treeLevel',UEe='org.eclipse.elk.mrtree.positionConstraint',VEe='org.eclipse.elk.mrtree.weighting',WEe='org.eclipse.elk.mrtree.edgeRoutingMode',XEe='org.eclipse.elk.mrtree.searchOrder',YEe='Position Constraint',ZEe='org.eclipse.elk.mrtree',$Ee='org.eclipse.elk.tree',_Ee='Processor arrange level',aFe='org.eclipse.elk.alg.mrtree.p2order',bFe='org.eclipse.elk.alg.mrtree.p4route',cFe='org.eclipse.elk.alg.radial',dFe=6.283185307179586,eFe='Before',fFe=4.9E-324,gFe='After',hFe='org.eclipse.elk.alg.radial.intermediate',iFe='COMPACTION',jFe='org.eclipse.elk.alg.radial.intermediate.compaction',kFe={3:1,4:1,5:1,100:1},lFe='org.eclipse.elk.alg.radial.intermediate.optimization',mFe='No implementation is available for the layout option ',nFe='org.eclipse.elk.alg.radial.options',oFe='org.eclipse.elk.radial.centerOnRoot',pFe='org.eclipse.elk.radial.orderId',qFe='org.eclipse.elk.radial.radius',rFe='org.eclipse.elk.radial.rotate',sFe='org.eclipse.elk.radial.compactor',tFe='org.eclipse.elk.radial.compactionStepSize',uFe='org.eclipse.elk.radial.sorter',vFe='org.eclipse.elk.radial.wedgeCriteria',wFe='org.eclipse.elk.radial.optimizationCriteria',xFe='org.eclipse.elk.radial.rotation.targetAngle',yFe='org.eclipse.elk.radial.rotation.computeAdditionalWedgeSpace',zFe='org.eclipse.elk.radial.rotation.outgoingEdgeAngles',AFe='Compaction',BFe='rotation',CFe='org.eclipse.elk.radial',DFe='org.eclipse.elk.alg.radial.p1position.wedge',EFe='org.eclipse.elk.alg.radial.sorting',FFe=5.497787143782138,GFe=3.9269908169872414,HFe=2.356194490192345,IFe='org.eclipse.elk.alg.rectpacking',JFe='org.eclipse.elk.alg.rectpacking.intermediate',KFe='org.eclipse.elk.alg.rectpacking.options',LFe='org.eclipse.elk.rectpacking.trybox',MFe='org.eclipse.elk.rectpacking.currentPosition',NFe='org.eclipse.elk.rectpacking.desiredPosition',OFe='org.eclipse.elk.rectpacking.inNewRow',PFe='org.eclipse.elk.rectpacking.widthApproximation.strategy',QFe='org.eclipse.elk.rectpacking.widthApproximation.targetWidth',RFe='org.eclipse.elk.rectpacking.widthApproximation.optimizationGoal',SFe='org.eclipse.elk.rectpacking.widthApproximation.lastPlaceShift',TFe='org.eclipse.elk.rectpacking.packing.strategy',UFe='org.eclipse.elk.rectpacking.packing.compaction.rowHeightReevaluation',VFe='org.eclipse.elk.rectpacking.packing.compaction.iterations',WFe='org.eclipse.elk.rectpacking.whiteSpaceElimination.strategy',XFe='widthApproximation',YFe='Compaction Strategy',ZFe='packing.compaction',$Fe='org.eclipse.elk.rectpacking',_Fe='org.eclipse.elk.alg.rectpacking.p1widthapproximation',aGe='org.eclipse.elk.alg.rectpacking.p2packing',bGe='No Compaction',cGe='org.eclipse.elk.alg.rectpacking.p3whitespaceelimination',dGe='org.eclipse.elk.alg.rectpacking.util',eGe='No implementation available for ',fGe='org.eclipse.elk.alg.spore',gGe='org.eclipse.elk.alg.spore.options',hGe='org.eclipse.elk.sporeCompaction',iGe='org.eclipse.elk.underlyingLayoutAlgorithm',jGe='org.eclipse.elk.processingOrder.treeConstruction',kGe='org.eclipse.elk.processingOrder.spanningTreeCostFunction',lGe='org.eclipse.elk.processingOrder.preferredRoot',mGe='org.eclipse.elk.processingOrder.rootSelection',nGe='org.eclipse.elk.structure.structureExtractionStrategy',oGe='org.eclipse.elk.compaction.compactionStrategy',pGe='org.eclipse.elk.compaction.orthogonal',qGe='org.eclipse.elk.overlapRemoval.maxIterations',rGe='org.eclipse.elk.overlapRemoval.runScanline',sGe='processingOrder',tGe='overlapRemoval',uGe='org.eclipse.elk.sporeOverlap',vGe='org.eclipse.elk.alg.spore.p1structure',wGe='org.eclipse.elk.alg.spore.p2processingorder',xGe='org.eclipse.elk.alg.spore.p3execution',yGe='Topdown Layout',zGe='Invalid index: ',AGe='org.eclipse.elk.core.alg',BGe={341:1},CGe={295:1},DGe='Make sure its type is registered with the ',EGe=' utility class.',FGe='true',GGe='false',HGe="Couldn't clone property '",IGe=0.05,JGe='org.eclipse.elk.core.options',KGe=1.2999999523162842,LGe='org.eclipse.elk.box',MGe='org.eclipse.elk.expandNodes',NGe='org.eclipse.elk.box.packingMode',OGe='org.eclipse.elk.algorithm',PGe='org.eclipse.elk.resolvedAlgorithm',QGe='org.eclipse.elk.bendPoints',RGe='org.eclipse.elk.labelManager',SGe='org.eclipse.elk.scaleFactor',TGe='org.eclipse.elk.childAreaWidth',UGe='org.eclipse.elk.childAreaHeight',VGe='org.eclipse.elk.animate',WGe='org.eclipse.elk.animTimeFactor',XGe='org.eclipse.elk.layoutAncestors',YGe='org.eclipse.elk.maxAnimTime',ZGe='org.eclipse.elk.minAnimTime',$Ge='org.eclipse.elk.progressBar',_Ge='org.eclipse.elk.validateGraph',aHe='org.eclipse.elk.validateOptions',bHe='org.eclipse.elk.zoomToFit',cHe='org.eclipse.elk.font.name',dHe='org.eclipse.elk.font.size',eHe='org.eclipse.elk.topdown.sizeApproximator',fHe='org.eclipse.elk.topdown.scaleCap',gHe='org.eclipse.elk.edge.type',hHe='partitioning',iHe='nodeLabels',jHe='portAlignment',kHe='nodeSize',lHe='port',mHe='portLabels',nHe='topdown',oHe='insideSelfLoops',pHe='org.eclipse.elk.fixed',qHe='org.eclipse.elk.random',rHe={3:1,34:1,22:1,347:1},sHe='port must have a parent node to calculate the port side',tHe='The edge needs to have exactly one edge section. Found: ',uHe='org.eclipse.elk.core.util.adapters',vHe='org.eclipse.emf.ecore',wHe='org.eclipse.elk.graph',xHe='EMapPropertyHolder',yHe='ElkBendPoint',zHe='ElkGraphElement',AHe='ElkConnectableShape',BHe='ElkEdge',CHe='ElkEdgeSection',DHe='EModelElement',EHe='ENamedElement',FHe='ElkLabel',GHe='ElkNode',HHe='ElkPort',IHe={94:1,93:1},JHe='org.eclipse.emf.common.notify.impl',KHe="The feature '",LHe="' is not a valid changeable feature",MHe='Expecting null',NHe="' is not a valid feature",OHe='The feature ID',PHe=' is not a valid feature ID',QHe=32768,RHe={110:1,94:1,93:1,58:1,54:1,99:1},SHe='org.eclipse.emf.ecore.impl',THe='org.eclipse.elk.graph.impl',UHe='Recursive containment not allowed for ',VHe="The datatype '",WHe="' is not a valid classifier",XHe="The value '",YHe={195:1,3:1,4:1},ZHe="The class '",$He='http://www.eclipse.org/elk/ElkGraph',_He='property',aIe='value',bIe='source',cIe='properties',dIe='identifier',eIe='height',fIe='width',gIe='parent',hIe='text',iIe='children',jIe='hierarchical',kIe='sources',lIe='targets',mIe='sections',nIe='bendPoints',oIe='outgoingShape',pIe='incomingShape',qIe='outgoingSections',rIe='incomingSections',sIe='org.eclipse.emf.common.util',tIe='Severe implementation error in the Json to ElkGraph importer.',uIe='id',vIe='org.eclipse.elk.graph.json',wIe='Unhandled parameter types: ',xIe='startPoint',yIe="An edge must have at least one source and one target (edge id: '",zIe="').",AIe='Referenced edge section does not exist: ',BIe=" (edge id: '",CIe='target',DIe='sourcePoint',EIe='targetPoint',FIe='group',GIe='name',HIe='connectableShape cannot be null',IIe='edge cannot be null',JIe="Passed edge is not 'simple'.",KIe='org.eclipse.elk.graph.util',LIe="The 'no duplicates' constraint is violated",MIe='targetIndex=',NIe=', size=',OIe='sourceIndex=',PIe={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1},QIe={3:1,4:1,20:1,31:1,56:1,16:1,51:1,15:1,59:1,70:1,66:1,61:1,596:1},RIe='logging',SIe='measureExecutionTime',TIe='parser.parse.1',UIe='parser.parse.2',VIe='parser.next.1',WIe='parser.next.2',XIe='parser.next.3',YIe='parser.next.4',ZIe='parser.factor.1',$Ie='parser.factor.2',_Ie='parser.factor.3',aJe='parser.factor.4',bJe='parser.factor.5',cJe='parser.factor.6',dJe='parser.atom.1',eJe='parser.atom.2',fJe='parser.atom.3',gJe='parser.atom.4',hJe='parser.atom.5',iJe='parser.cc.1',jJe='parser.cc.2',kJe='parser.cc.3',lJe='parser.cc.5',mJe='parser.cc.6',nJe='parser.cc.7',oJe='parser.cc.8',pJe='parser.ope.1',qJe='parser.ope.2',rJe='parser.ope.3',sJe='parser.descape.1',tJe='parser.descape.2',uJe='parser.descape.3',vJe='parser.descape.4',wJe='parser.descape.5',xJe='parser.process.1',yJe='parser.quantifier.1',zJe='parser.quantifier.2',AJe='parser.quantifier.3',BJe='parser.quantifier.4',CJe='parser.quantifier.5',DJe='org.eclipse.emf.common.notify',EJe={424:1,686:1},FJe={3:1,4:1,20:1,31:1,56:1,16:1,15:1,70:1,61:1},GJe={378:1,152:1},HJe='index=',IJe={3:1,4:1,5:1,129:1},JJe={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,61:1},KJe={3:1,6:1,4:1,5:1,198:1},LJe={3:1,4:1,5:1,173:1,379:1},MJe=';/?:@&=+$,',NJe='invalid authority: ',OJe='EAnnotation',PJe='ETypedElement',QJe='EStructuralFeature',RJe='EAttribute',SJe='EClassifier',TJe='EEnumLiteral',UJe='EGenericType',VJe='EOperation',WJe='EParameter',XJe='EReference',YJe='ETypeParameter',ZJe='org.eclipse.emf.ecore.util',$Je={79:1},_Je={3:1,20:1,16:1,15:1,61:1,597:1,79:1,71:1,97:1},aKe='org.eclipse.emf.ecore.util.FeatureMap$Entry',bKe=8192,cKe=2048,dKe='byte',eKe='char',fKe='double',gKe='float',hKe='int',iKe='long',jKe='short',kKe='java.lang.Object',lKe={3:1,4:1,5:1,254:1},mKe={3:1,4:1,5:1,688:1},nKe={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1,71:1},oKe={3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1,79:1,71:1,97:1},pKe='mixed',qKe='http:///org/eclipse/emf/ecore/util/ExtendedMetaData',rKe='kind',sKe={3:1,4:1,5:1,689:1},tKe={3:1,4:1,20:1,31:1,56:1,16:1,15:1,70:1,61:1,79:1,71:1,97:1},uKe={20:1,31:1,56:1,16:1,15:1,61:1,71:1},vKe={51:1,128:1,287:1},wKe={76:1,343:1},xKe="The value of type '",yKe="' must be of type '",zKe=1352,AKe='http://www.eclipse.org/emf/2002/Ecore',BKe=-32768,CKe='constraints',DKe='baseType',EKe='getEStructuralFeature',FKe='getFeatureID',GKe='feature',HKe='getOperationID',IKe='operation',JKe='defaultValue',KKe='eTypeParameters',LKe='isInstance',MKe='getEEnumLiteral',NKe='eContainingClass',OKe={57:1},PKe={3:1,4:1,5:1,124:1},QKe='org.eclipse.emf.ecore.resource',RKe={94:1,93:1,599:1,2034:1},SKe='org.eclipse.emf.ecore.resource.impl',TKe='unspecified',UKe='simple',VKe='attribute',WKe='attributeWildcard',XKe='element',YKe='elementWildcard',ZKe='collapse',$Ke='itemType',_Ke='namespace',aLe='##targetNamespace',bLe='whiteSpace',cLe='wildcards',dLe='http://www.eclipse.org/emf/2003/XMLType',eLe='##any',fLe='uninitialized',gLe='The multiplicity constraint is violated',hLe='org.eclipse.emf.ecore.xml.type',iLe='ProcessingInstruction',jLe='SimpleAnyType',kLe='XMLTypeDocumentRoot',lLe='org.eclipse.emf.ecore.xml.type.impl',mLe='INF',nLe='processing',oLe='ENTITIES_._base',pLe='minLength',qLe='ENTITY',rLe='NCName',sLe='IDREFS_._base',tLe='integer',uLe='token',vLe='pattern',wLe='[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*',xLe='\\i\\c*',yLe='[\\i-[:]][\\c-[:]]*',zLe='nonPositiveInteger',ALe='maxInclusive',BLe='NMTOKEN',CLe='NMTOKENS_._base',DLe='nonNegativeInteger',ELe='minInclusive',FLe='normalizedString',GLe='unsignedByte',HLe='unsignedInt',ILe='18446744073709551615',JLe='unsignedShort',KLe='processingInstruction',LLe='org.eclipse.emf.ecore.xml.type.internal',MLe=1114111,NLe='Internal Error: shorthands: \\u',OLe='xml:isDigit',PLe='xml:isWord',QLe='xml:isSpace',RLe='xml:isNameChar',SLe='xml:isInitialNameChar',TLe='09\u0660\u0669\u06F0\u06F9\u0966\u096F\u09E6\u09EF\u0A66\u0A6F\u0AE6\u0AEF\u0B66\u0B6F\u0BE7\u0BEF\u0C66\u0C6F\u0CE6\u0CEF\u0D66\u0D6F\u0E50\u0E59\u0ED0\u0ED9\u0F20\u0F29',ULe='AZaz\xC0\xD6\xD8\xF6\xF8\u0131\u0134\u013E\u0141\u0148\u014A\u017E\u0180\u01C3\u01CD\u01F0\u01F4\u01F5\u01FA\u0217\u0250\u02A8\u02BB\u02C1\u0386\u0386\u0388\u038A\u038C\u038C\u038E\u03A1\u03A3\u03CE\u03D0\u03D6\u03DA\u03DA\u03DC\u03DC\u03DE\u03DE\u03E0\u03E0\u03E2\u03F3\u0401\u040C\u040E\u044F\u0451\u045C\u045E\u0481\u0490\u04C4\u04C7\u04C8\u04CB\u04CC\u04D0\u04EB\u04EE\u04F5\u04F8\u04F9\u0531\u0556\u0559\u0559\u0561\u0586\u05D0\u05EA\u05F0\u05F2\u0621\u063A\u0641\u064A\u0671\u06B7\u06BA\u06BE\u06C0\u06CE\u06D0\u06D3\u06D5\u06D5\u06E5\u06E6\u0905\u0939\u093D\u093D\u0958\u0961\u0985\u098C\u098F\u0990\u0993\u09A8\u09AA\u09B0\u09B2\u09B2\u09B6\u09B9\u09DC\u09DD\u09DF\u09E1\u09F0\u09F1\u0A05\u0A0A\u0A0F\u0A10\u0A13\u0A28\u0A2A\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59\u0A5C\u0A5E\u0A5E\u0A72\u0A74\u0A85\u0A8B\u0A8D\u0A8D\u0A8F\u0A91\u0A93\u0AA8\u0AAA\u0AB0\u0AB2\u0AB3\u0AB5\u0AB9\u0ABD\u0ABD\u0AE0\u0AE0\u0B05\u0B0C\u0B0F\u0B10\u0B13\u0B28\u0B2A\u0B30\u0B32\u0B33\u0B36\u0B39\u0B3D\u0B3D\u0B5C\u0B5D\u0B5F\u0B61\u0B85\u0B8A\u0B8E\u0B90\u0B92\u0B95\u0B99\u0B9A\u0B9C\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8\u0BAA\u0BAE\u0BB5\u0BB7\u0BB9\u0C05\u0C0C\u0C0E\u0C10\u0C12\u0C28\u0C2A\u0C33\u0C35\u0C39\u0C60\u0C61\u0C85\u0C8C\u0C8E\u0C90\u0C92\u0CA8\u0CAA\u0CB3\u0CB5\u0CB9\u0CDE\u0CDE\u0CE0\u0CE1\u0D05\u0D0C\u0D0E\u0D10\u0D12\u0D28\u0D2A\u0D39\u0D60\u0D61\u0E01\u0E2E\u0E30\u0E30\u0E32\u0E33\u0E40\u0E45\u0E81\u0E82\u0E84\u0E84\u0E87\u0E88\u0E8A\u0E8A\u0E8D\u0E8D\u0E94\u0E97\u0E99\u0E9F\u0EA1\u0EA3\u0EA5\u0EA5\u0EA7\u0EA7\u0EAA\u0EAB\u0EAD\u0EAE\u0EB0\u0EB0\u0EB2\u0EB3\u0EBD\u0EBD\u0EC0\u0EC4\u0F40\u0F47\u0F49\u0F69\u10A0\u10C5\u10D0\u10F6\u1100\u1100\u1102\u1103\u1105\u1107\u1109\u1109\u110B\u110C\u110E\u1112\u113C\u113C\u113E\u113E\u1140\u1140\u114C\u114C\u114E\u114E\u1150\u1150\u1154\u1155\u1159\u1159\u115F\u1161\u1163\u1163\u1165\u1165\u1167\u1167\u1169\u1169\u116D\u116E\u1172\u1173\u1175\u1175\u119E\u119E\u11A8\u11A8\u11AB\u11AB\u11AE\u11AF\u11B7\u11B8\u11BA\u11BA\u11BC\u11C2\u11EB\u11EB\u11F0\u11F0\u11F9\u11F9\u1E00\u1E9B\u1EA0\u1EF9\u1F00\u1F15\u1F18\u1F1D\u1F20\u1F45\u1F48\u1F4D\u1F50\u1F57\u1F59\u1F59\u1F5B\u1F5B\u1F5D\u1F5D\u1F5F\u1F7D\u1F80\u1FB4\u1FB6\u1FBC\u1FBE\u1FBE\u1FC2\u1FC4\u1FC6\u1FCC\u1FD0\u1FD3\u1FD6\u1FDB\u1FE0\u1FEC\u1FF2\u1FF4\u1FF6\u1FFC\u2126\u2126\u212A\u212B\u212E\u212E\u2180\u2182\u3007\u3007\u3021\u3029\u3041\u3094\u30A1\u30FA\u3105\u312C\u4E00\u9FA5\uAC00\uD7A3',VLe='Private Use',WLe='ASSIGNED',XLe='\x00\x7F\x80\xFF\u0100\u017F\u0180\u024F\u0250\u02AF\u02B0\u02FF\u0300\u036F\u0370\u03FF\u0400\u04FF\u0530\u058F\u0590\u05FF\u0600\u06FF\u0700\u074F\u0780\u07BF\u0900\u097F\u0980\u09FF\u0A00\u0A7F\u0A80\u0AFF\u0B00\u0B7F\u0B80\u0BFF\u0C00\u0C7F\u0C80\u0CFF\u0D00\u0D7F\u0D80\u0DFF\u0E00\u0E7F\u0E80\u0EFF\u0F00\u0FFF\u1000\u109F\u10A0\u10FF\u1100\u11FF\u1200\u137F\u13A0\u13FF\u1400\u167F\u1680\u169F\u16A0\u16FF\u1780\u17FF\u1800\u18AF\u1E00\u1EFF\u1F00\u1FFF\u2000\u206F\u2070\u209F\u20A0\u20CF\u20D0\u20FF\u2100\u214F\u2150\u218F\u2190\u21FF\u2200\u22FF\u2300\u23FF\u2400\u243F\u2440\u245F\u2460\u24FF\u2500\u257F\u2580\u259F\u25A0\u25FF\u2600\u26FF\u2700\u27BF\u2800\u28FF\u2E80\u2EFF\u2F00\u2FDF\u2FF0\u2FFF\u3000\u303F\u3040\u309F\u30A0\u30FF\u3100\u312F\u3130\u318F\u3190\u319F\u31A0\u31BF\u3200\u32FF\u3300\u33FF\u3400\u4DB5\u4E00\u9FFF\uA000\uA48F\uA490\uA4CF\uAC00\uD7A3\uE000\uF8FF\uF900\uFAFF\uFB00\uFB4F\uFB50\uFDFF\uFE20\uFE2F\uFE30\uFE4F\uFE50\uFE6F\uFE70\uFEFE\uFEFF\uFEFF\uFF00\uFFEF',YLe='UNASSIGNED',ZLe={3:1,122:1},$Le='org.eclipse.emf.ecore.xml.type.util',_Le={3:1,4:1,5:1,381:1},aMe='org.eclipse.xtext.xbase.lib',bMe='Cannot add elements to a Range',cMe='Cannot set elements in a Range',dMe='Cannot remove elements from a Range',eMe='user.agent';var _,eeb,_db,ydb=-1;$wnd.goog=$wnd.goog||{};$wnd.goog.global=$wnd.goog.global||$wnd;eeb={};feb(1,null,{},nb);_.Fb=function ob(a){return mb(this,a)};_.Gb=function qb(){return this.Rm};_.Hb=function sb(){return kFb(this)};_.Ib=function ub(){var a;return nfb(rb(this))+'@'+(a=tb(this)>>>0,a.toString(16))};_.equals=function(a){return this.Fb(a)};_.hashCode=function(){return this.Hb()};_.toString=function(){return this.Ib()};var ND,OD,PD;feb(297,1,{297:1,2124:1},pfb);_.ve=function qfb(a){var b;b=new pfb;b.i=4;a>1?(b.c=xfb(this,a-1)):(b.c=this);return b};_.we=function wfb(){lfb(this);return this.b};_.xe=function yfb(){return nfb(this)};_.ye=function Afb(){return lfb(this),this.k};_.ze=function Cfb(){return (this.i&4)!=0};_.Ae=function Dfb(){return (this.i&1)!=0};_.Ib=function Gfb(){return ofb(this)};_.i=0;var kfb=1;var jJ=sfb(mve,'Object',1);var UI=sfb(mve,'Class',297);feb(2096,1,nve);var oE=sfb(ove,'Optional',2096);feb(1191,2096,nve,xb);_.Fb=function yb(a){return a===this};_.Hb=function zb(){return 2040732332};_.Ib=function Ab(){return 'Optional.absent()'};_.Jb=function Bb(a){Qb(a);return wb(),vb};var vb;var mE=sfb(ove,'Absent',1191);feb(636,1,{},Gb);var nE=sfb(ove,'Joiner',636);var pE=ufb(ove,'Predicate');feb(589,1,{178:1,589:1,3:1,46:1},Yb);_.Mb=function ac(a){return Xb(this,a)};_.Lb=function Zb(a){return Xb(this,a)};_.Fb=function $b(a){var b;if(ZD(a,589)){b=RD(a,589);return Rt(this.a,b.a)}return false};_.Hb=function _b(){return Cob(this.a)+306654252};_.Ib=function bc(){return Wb(this.a)};var qE=sfb(ove,'Predicates/AndPredicate',589);feb(419,2096,{419:1,3:1},cc);_.Fb=function dc(a){var b;if(ZD(a,419)){b=RD(a,419);return pb(this.a,b.a)}return false};_.Hb=function ec(){return 1502476572+tb(this.a)};_.Ib=function fc(){return uve+this.a+')'};_.Jb=function gc(a){return new cc(Rb(a.Kb(this.a),'the Function passed to Optional.transform() must not return null.'))};var rE=sfb(ove,'Present',419);feb(204,1,wve);_.Nb=function kc(a){Ztb(this,a)};_.Qb=function lc(){jc()};var eI=sfb(xve,'UnmodifiableIterator',204);feb(2076,204,yve);_.Qb=function nc(){jc()};_.Rb=function mc(a){throw Adb(new jib)};_.Wb=function oc(a){throw Adb(new jib)};var fI=sfb(xve,'UnmodifiableListIterator',2076);feb(399,2076,yve);_.Ob=function rc(){return this.c0};_.Pb=function tc(){if(this.c>=this.d){throw Adb(new Dvb)}return this.Xb(this.c++)};_.Tb=function uc(){return this.c};_.Ub=function vc(){if(this.c<=0){throw Adb(new Dvb)}return this.Xb(--this.c)};_.Vb=function wc(){return this.c-1};_.c=0;_.d=0;var sE=sfb(xve,'AbstractIndexedListIterator',399);feb(713,204,wve);_.Ob=function Ac(){return xc(this)};_.Pb=function Bc(){return yc(this)};_.e=1;var tE=sfb(xve,'AbstractIterator',713);feb(2084,1,{229:1});_.Zb=function Hc(){var a;return a=this.f,!a?(this.f=this.ac()):a};_.Fb=function Ic(a){return xw(this,a)};_.Hb=function Jc(){return tb(this.Zb())};_.dc=function Kc(){return this.gc()==0};_.ec=function Lc(){return Ec(this)};_.Ib=function Mc(){return jeb(this.Zb())};var YE=sfb(xve,'AbstractMultimap',2084);feb(742,2084,zve);_.$b=function Xc(){Nc(this)};_._b=function Yc(a){return Oc(this,a)};_.ac=function Zc(){return new ne(this,this.c)};_.ic=function $c(a){return this.hc()};_.bc=function _c(){return new zf(this,this.c)};_.jc=function ad(){return this.mc(this.hc())};_.kc=function bd(){return new Hd(this)};_.lc=function cd(){return ek(this.c.vc().Nc(),new hh,64,this.d)};_.cc=function dd(a){return Qc(this,a)};_.fc=function gd(a){return Sc(this,a)};_.gc=function hd(){return this.d};_.mc=function jd(a){return yob(),new xpb(a)};_.nc=function kd(){return new Dd(this)};_.oc=function ld(){return ek(this.c.Cc().Nc(),new Fd,64,this.d)};_.pc=function md(a,b){return new lg(this,a,b,null)};_.d=0;var TE=sfb(xve,'AbstractMapBasedMultimap',742);feb(1696,742,zve);_.hc=function pd(){return new cnb(this.a)};_.jc=function qd(){return yob(),yob(),vob};_.cc=function sd(a){return RD(Qc(this,a),15)};_.fc=function ud(a){return RD(Sc(this,a),15)};_.Zb=function od(){return nd(this)};_.Fb=function rd(a){return xw(this,a)};_.qc=function td(a){return RD(Qc(this,a),15)};_.rc=function vd(a){return RD(Sc(this,a),15)};_.mc=function wd(a){return Hob(RD(a,15))};_.pc=function xd(a,b){return Vc(this,a,RD(b,15),null)};var uE=sfb(xve,'AbstractListMultimap',1696);feb(748,1,Ave);_.Nb=function zd(a){Ztb(this,a)};_.Ob=function Ad(){return this.c.Ob()||this.e.Ob()};_.Pb=function Bd(){var a;if(!this.e.Ob()){a=RD(this.c.Pb(),44);this.b=a.ld();this.a=RD(a.md(),16);this.e=this.a.Kc()}return this.sc(this.b,this.e.Pb())};_.Qb=function Cd(){this.e.Qb();RD(Hvb(this.a),16).dc()&&this.c.Qb();--this.d.d};var CE=sfb(xve,'AbstractMapBasedMultimap/Itr',748);feb(1129,748,Ave,Dd);_.sc=function Ed(a,b){return b};var vE=sfb(xve,'AbstractMapBasedMultimap/1',1129);feb(1130,1,{},Fd);_.Kb=function Gd(a){return RD(a,16).Nc()};var wE=sfb(xve,'AbstractMapBasedMultimap/1methodref$spliterator$Type',1130);feb(1131,748,Ave,Hd);_.sc=function Id(a,b){return new gp(a,b)};var xE=sfb(xve,'AbstractMapBasedMultimap/2',1131);var VK=ufb(Bve,'Map');feb(2065,1,Cve);_.wc=function Td(a){Bvb(this,a)};_.yc=function $d(a,b,c){return Cvb(this,a,b,c)};_.$b=function Od(){this.vc().$b()};_.tc=function Pd(a){return Jd(this,a)};_._b=function Qd(a){return !!Kd(this,a,false)};_.uc=function Rd(a){var b,c,d;for(c=this.vc().Kc();c.Ob();){b=RD(c.Pb(),44);d=b.md();if(dE(a)===dE(d)||a!=null&&pb(a,d)){return true}}return false};_.Fb=function Sd(a){var b,c,d;if(a===this){return true}if(!ZD(a,85)){return false}d=RD(a,85);if(this.gc()!=d.gc()){return false}for(c=d.vc().Kc();c.Ob();){b=RD(c.Pb(),44);if(!this.tc(b)){return false}}return true};_.xc=function Ud(a){return Wd(Kd(this,a,false))};_.Hb=function Xd(){return Bob(this.vc())};_.dc=function Yd(){return this.gc()==0};_.ec=function Zd(){return new Xkb(this)};_.zc=function _d(a,b){throw Adb(new kib('Put not supported on this map'))};_.Ac=function ae(a){Ld(this,a)};_.Bc=function be(a){return Wd(Kd(this,a,true))};_.gc=function ce(){return this.vc().gc()};_.Ib=function de(){return Md(this)};_.Cc=function ee(){return new glb(this)};var KJ=sfb(Bve,'AbstractMap',2065);feb(2085,2065,Cve);_.bc=function ge(){return new rf(this)};_.vc=function he(){return fe(this)};_.ec=function ie(){var a;a=this.g;return !a?(this.g=this.bc()):a};_.Cc=function je(){var a;a=this.i;return !a?(this.i=new nw(this)):a};var uH=sfb(xve,'Maps/ViewCachingAbstractMap',2085);feb(402,2085,Cve,ne);_.xc=function se(a){return ke(this,a)};_.Bc=function ve(a){return le(this,a)};_.$b=function oe(){this.d==this.e.c?this.e.$b():Ar(new mf(this))};_._b=function pe(a){return Wv(this.d,a)};_.Ec=function qe(){return new df(this)};_.Dc=function(){return this.Ec()};_.Fb=function re(a){return this===a||pb(this.d,a)};_.Hb=function te(){return tb(this.d)};_.ec=function ue(){return this.e.ec()};_.gc=function we(){return this.d.gc()};_.Ib=function xe(){return jeb(this.d)};var BE=sfb(xve,'AbstractMapBasedMultimap/AsMap',402);var cJ=ufb(mve,'Iterable');feb(31,1,Dve);_.Jc=function Le(a){xgb(this,a)};_.Lc=function Ne(){return this.Oc()};_.Nc=function Pe(){return new Swb(this,0)};_.Oc=function Qe(){return new SDb(null,this.Nc())};_.Fc=function Ge(a){throw Adb(new kib('Add not supported on this collection'))};_.Gc=function He(a){return ye(this,a)};_.$b=function Ie(){Ae(this)};_.Hc=function Je(a){return ze(this,a,false)};_.Ic=function Ke(a){return Be(this,a)};_.dc=function Me(){return this.gc()==0};_.Mc=function Oe(a){return ze(this,a,true)};_.Pc=function Re(){return De(this)};_.Qc=function Se(a){return Ee(this,a)};_.Ib=function Te(){return Fe(this)};var vJ=sfb(Bve,'AbstractCollection',31);var bL=ufb(Bve,'Set');feb(Eve,31,Fve);_.Nc=function Ye(){return new Swb(this,1)};_.Fb=function We(a){return Ue(this,a)};_.Hb=function Xe(){return Bob(this)};var RJ=sfb(Bve,'AbstractSet',Eve);feb(2068,Eve,Fve);var UH=sfb(xve,'Sets/ImprovedAbstractSet',2068);feb(2069,2068,Fve);_.$b=function $e(){this.Rc().$b()};_.Hc=function _e(a){return Ze(this,a)};_.dc=function af(){return this.Rc().dc()};_.Mc=function bf(a){var b;if(this.Hc(a)&&ZD(a,44)){b=RD(a,44);return this.Rc().ec().Mc(b.ld())}return false};_.gc=function cf(){return this.Rc().gc()};var nH=sfb(xve,'Maps/EntrySet',2069);feb(1127,2069,Fve,df);_.Hc=function ef(a){return Nk(this.a.d.vc(),a)};_.Kc=function ff(){return new mf(this.a)};_.Rc=function gf(){return this.a};_.Mc=function hf(a){var b;if(!Nk(this.a.d.vc(),a)){return false}b=RD(Hvb(RD(a,44)),44);Tc(this.a.e,b.ld());return true};_.Nc=function jf(){return gk(this.a.d.vc().Nc(),new kf(this.a))};var zE=sfb(xve,'AbstractMapBasedMultimap/AsMap/AsMapEntries',1127);feb(1128,1,{},kf);_.Kb=function lf(a){return me(this.a,RD(a,44))};var yE=sfb(xve,'AbstractMapBasedMultimap/AsMap/AsMapEntries/0methodref$wrapEntry$Type',1128);feb(746,1,Ave,mf);_.Nb=function nf(a){Ztb(this,a)};_.Pb=function pf(){var a;return a=RD(this.b.Pb(),44),this.a=RD(a.md(),16),me(this.c,a)};_.Ob=function of(){return this.b.Ob()};_.Qb=function qf(){Vb(!!this.a);this.b.Qb();this.c.e.d-=this.a.gc();this.a.$b();this.a=null};var AE=sfb(xve,'AbstractMapBasedMultimap/AsMap/AsMapIterator',746);feb(542,2068,Fve,rf);_.$b=function sf(){this.b.$b()};_.Hc=function tf(a){return this.b._b(a)};_.Jc=function uf(a){Qb(a);this.b.wc(new lw(a))};_.dc=function vf(){return this.b.dc()};_.Kc=function wf(){return new aw(this.b.vc().Kc())};_.Mc=function xf(a){if(this.b._b(a)){this.b.Bc(a);return true}return false};_.gc=function yf(){return this.b.gc()};var rH=sfb(xve,'Maps/KeySet',542);feb(327,542,Fve,zf);_.$b=function Af(){var a;Ar((a=this.b.vc().Kc(),new Hf(this,a)))};_.Ic=function Bf(a){return this.b.ec().Ic(a)};_.Fb=function Cf(a){return this===a||pb(this.b.ec(),a)};_.Hb=function Df(){return tb(this.b.ec())};_.Kc=function Ef(){var a;return a=this.b.vc().Kc(),new Hf(this,a)};_.Mc=function Ff(a){var b,c;c=0;b=RD(this.b.Bc(a),16);if(b){c=b.gc();b.$b();this.a.d-=c}return c>0};_.Nc=function Gf(){return this.b.ec().Nc()};var EE=sfb(xve,'AbstractMapBasedMultimap/KeySet',327);feb(747,1,Ave,Hf);_.Nb=function If(a){Ztb(this,a)};_.Ob=function Jf(){return this.c.Ob()};_.Pb=function Kf(){this.a=RD(this.c.Pb(),44);return this.a.ld()};_.Qb=function Lf(){var a;Vb(!!this.a);a=RD(this.a.md(),16);this.c.Qb();this.b.a.d-=a.gc();a.$b();this.a=null};var DE=sfb(xve,'AbstractMapBasedMultimap/KeySet/1',747);feb(503,402,{85:1,133:1},Mf);_.bc=function Nf(){return this.Sc()};_.ec=function Qf(){return this.Uc()};_.Sc=function Of(){return new eg(this.c,this.Wc())};_.Tc=function Pf(){return this.Wc().Tc()};_.Uc=function Rf(){var a;return a=this.b,!a?(this.b=this.Sc()):a};_.Vc=function Sf(){return this.Wc().Vc()};_.Wc=function Tf(){return RD(this.d,133)};var IE=sfb(xve,'AbstractMapBasedMultimap/SortedAsMap',503);feb(446,503,Gve,Uf);_.bc=function Wf(){return new gg(this.a,RD(RD(this.d,133),139))};_.Sc=function Xf(){return new gg(this.a,RD(RD(this.d,133),139))};_.ec=function _f(){var a;return a=this.b,RD(!a?(this.b=new gg(this.a,RD(RD(this.d,133),139))):a,277)};_.Uc=function ag(){var a;return a=this.b,RD(!a?(this.b=new gg(this.a,RD(RD(this.d,133),139))):a,277)};_.Wc=function cg(){return RD(RD(this.d,133),139)};_.Xc=function Vf(a){return RD(RD(this.d,133),139).Xc(a)};_.Yc=function Yf(a){return RD(RD(this.d,133),139).Yc(a)};_.Zc=function Zf(a,b){return new Uf(this.a,RD(RD(this.d,133),139).Zc(a,b))};_.$c=function $f(a){return RD(RD(this.d,133),139).$c(a)};_._c=function bg(a){return RD(RD(this.d,133),139)._c(a)};_.ad=function dg(a,b){return new Uf(this.a,RD(RD(this.d,133),139).ad(a,b))};var FE=sfb(xve,'AbstractMapBasedMultimap/NavigableAsMap',446);feb(502,327,Hve,eg);_.Nc=function fg(){return this.b.ec().Nc()};var JE=sfb(xve,'AbstractMapBasedMultimap/SortedKeySet',502);feb(401,502,Ive,gg);var GE=sfb(xve,'AbstractMapBasedMultimap/NavigableKeySet',401);feb(551,31,Dve,lg);_.Fc=function mg(a){var b,c;ig(this);c=this.d.dc();b=this.d.Fc(a);if(b){++this.f.d;c&&hg(this)}return b};_.Gc=function ng(a){var b,c,d;if(a.dc()){return false}d=(ig(this),this.d.gc());b=this.d.Gc(a);if(b){c=this.d.gc();this.f.d+=c-d;d==0&&hg(this)}return b};_.$b=function og(){var a;a=(ig(this),this.d.gc());if(a==0){return}this.d.$b();this.f.d-=a;jg(this)};_.Hc=function pg(a){ig(this);return this.d.Hc(a)};_.Ic=function qg(a){ig(this);return this.d.Ic(a)};_.Fb=function rg(a){if(a===this){return true}ig(this);return pb(this.d,a)};_.Hb=function sg(){ig(this);return tb(this.d)};_.Kc=function tg(){ig(this);return new Og(this)};_.Mc=function ug(a){var b;ig(this);b=this.d.Mc(a);if(b){--this.f.d;jg(this)}return b};_.gc=function vg(){return kg(this)};_.Nc=function wg(){return ig(this),this.d.Nc()};_.Ib=function xg(){ig(this);return jeb(this.d)};var LE=sfb(xve,'AbstractMapBasedMultimap/WrappedCollection',551);var QK=ufb(Bve,'List');feb(744,551,{20:1,31:1,16:1,15:1},yg);_.jd=function Hg(a){tvb(this,a)};_.Nc=function Ig(){return ig(this),this.d.Nc()};_.bd=function zg(a,b){var c;ig(this);c=this.d.dc();RD(this.d,15).bd(a,b);++this.a.d;c&&hg(this)};_.cd=function Ag(a,b){var c,d,e;if(b.dc()){return false}e=(ig(this),this.d.gc());c=RD(this.d,15).cd(a,b);if(c){d=this.d.gc();this.a.d+=d-e;e==0&&hg(this)}return c};_.Xb=function Bg(a){ig(this);return RD(this.d,15).Xb(a)};_.dd=function Cg(a){ig(this);return RD(this.d,15).dd(a)};_.ed=function Dg(){ig(this);return new Ug(this)};_.fd=function Eg(a){ig(this);return new Vg(this,a)};_.gd=function Fg(a){var b;ig(this);b=RD(this.d,15).gd(a);--this.a.d;jg(this);return b};_.hd=function Gg(a,b){ig(this);return RD(this.d,15).hd(a,b)};_.kd=function Jg(a,b){ig(this);return Vc(this.a,this.e,RD(this.d,15).kd(a,b),!this.b?this:this.b)};var NE=sfb(xve,'AbstractMapBasedMultimap/WrappedList',744);feb(1126,744,{20:1,31:1,16:1,15:1,59:1},Kg);var HE=sfb(xve,'AbstractMapBasedMultimap/RandomAccessWrappedList',1126);feb(628,1,Ave,Og);_.Nb=function Qg(a){Ztb(this,a)};_.Ob=function Rg(){Ng(this);return this.b.Ob()};_.Pb=function Sg(){Ng(this);return this.b.Pb()};_.Qb=function Tg(){Mg(this)};var KE=sfb(xve,'AbstractMapBasedMultimap/WrappedCollection/WrappedIterator',628);feb(745,628,Jve,Ug,Vg);_.Qb=function _g(){Mg(this)};_.Rb=function Wg(a){var b;b=kg(this.a)==0;(Ng(this),RD(this.b,128)).Rb(a);++this.a.a.d;b&&hg(this.a)};_.Sb=function Xg(){return (Ng(this),RD(this.b,128)).Sb()};_.Tb=function Yg(){return (Ng(this),RD(this.b,128)).Tb()};_.Ub=function Zg(){return (Ng(this),RD(this.b,128)).Ub()};_.Vb=function $g(){return (Ng(this),RD(this.b,128)).Vb()};_.Wb=function ah(a){(Ng(this),RD(this.b,128)).Wb(a)};var ME=sfb(xve,'AbstractMapBasedMultimap/WrappedList/WrappedListIterator',745);feb(743,551,Hve,bh);_.Nc=function dh(){return ig(this),this.d.Nc()};var QE=sfb(xve,'AbstractMapBasedMultimap/WrappedSortedSet',743);feb(1125,743,Ive,eh);var OE=sfb(xve,'AbstractMapBasedMultimap/WrappedNavigableSet',1125);feb(1124,551,Fve,fh);_.Nc=function gh(){return ig(this),this.d.Nc()};var PE=sfb(xve,'AbstractMapBasedMultimap/WrappedSet',1124);feb(1133,1,{},hh);_.Kb=function ih(a){return fd(RD(a,44))};var RE=sfb(xve,'AbstractMapBasedMultimap/lambda$1$Type',1133);feb(1132,1,{},jh);_.Kb=function kh(a){return new gp(this.a,a)};var SE=sfb(xve,'AbstractMapBasedMultimap/lambda$2$Type',1132);var UK=ufb(Bve,'Map/Entry');feb(358,1,Kve);_.Fb=function lh(a){var b;if(ZD(a,44)){b=RD(a,44);return Hb(this.ld(),b.ld())&&Hb(this.md(),b.md())}return false};_.Hb=function mh(){var a,b;a=this.ld();b=this.md();return (a==null?0:tb(a))^(b==null?0:tb(b))};_.nd=function nh(a){throw Adb(new jib)};_.Ib=function oh(){return this.ld()+'='+this.md()};var UE=sfb(xve,Lve,358);feb(2086,31,Dve);_.$b=function ph(){this.od().$b()};_.Hc=function qh(a){var b;if(ZD(a,44)){b=RD(a,44);return Cc(this.od(),b.ld(),b.md())}return false};_.Mc=function rh(a){var b;if(ZD(a,44)){b=RD(a,44);return Gc(this.od(),b.ld(),b.md())}return false};_.gc=function sh(){return this.od().d};var yH=sfb(xve,'Multimaps/Entries',2086);feb(749,2086,Dve,th);_.Kc=function uh(){return this.a.kc()};_.od=function vh(){return this.a};_.Nc=function wh(){return this.a.lc()};var VE=sfb(xve,'AbstractMultimap/Entries',749);feb(750,749,Fve,xh);_.Nc=function Ah(){return this.a.lc()};_.Fb=function yh(a){return Rx(this,a)};_.Hb=function zh(){return Sx(this)};var WE=sfb(xve,'AbstractMultimap/EntrySet',750);feb(751,31,Dve,Bh);_.$b=function Ch(){this.a.$b()};_.Hc=function Dh(a){return Dc(this.a,a)};_.Kc=function Eh(){return this.a.nc()};_.gc=function Fh(){return this.a.d};_.Nc=function Gh(){return this.a.oc()};var XE=sfb(xve,'AbstractMultimap/Values',751);feb(2087,31,{849:1,20:1,31:1,16:1});_.Jc=function Oh(a){Qb(a);Ih(this).Jc(new lx(a))};_.Nc=function Sh(){var a;return a=Ih(this).Nc(),ek(a,new sx,64|a.yd()&1296,this.a.d)};_.Fc=function Kh(a){Hh();return true};_.Gc=function Lh(a){return Qb(this),Qb(a),ZD(a,552)?nx(RD(a,849)):!a.dc()&&xr(this,a.Kc())};_.Hc=function Mh(a){var b;return b=RD(Xv(nd(this.a),a),16),(!b?0:b.gc())>0};_.Fb=function Nh(a){return ox(this,a)};_.Hb=function Ph(){return tb(Ih(this))};_.dc=function Qh(){return Ih(this).dc()};_.Mc=function Rh(a){return Rw(this,a,1)>0};_.Ib=function Th(){return jeb(Ih(this))};var $E=sfb(xve,'AbstractMultiset',2087);feb(2089,2068,Fve);_.$b=function Uh(){Nc(this.a.a)};_.Hc=function Vh(a){var b,c;if(ZD(a,504)){c=RD(a,425);if(RD(c.a.md(),16).gc()<=0){return false}b=Qw(this.a,c.a.ld());return b==RD(c.a.md(),16).gc()}return false};_.Mc=function Wh(a){var b,c,d,e;if(ZD(a,504)){c=RD(a,425);b=c.a.ld();d=RD(c.a.md(),16).gc();if(d!=0){e=this.a;return qx(e,b,d)}}return false};var IH=sfb(xve,'Multisets/EntrySet',2089);feb(1139,2089,Fve,Xh);_.Kc=function Yh(){return new _w(fe(nd(this.a.a)).Kc())};_.gc=function Zh(){return nd(this.a.a).gc()};var ZE=sfb(xve,'AbstractMultiset/EntrySet',1139);feb(627,742,zve);_.hc=function ai(){return this.pd()};_.jc=function bi(){return this.qd()};_.cc=function ei(a){return this.rd(a)};_.fc=function gi(a){return this.sd(a)};_.Zb=function _h(){var a;return a=this.f,!a?(this.f=this.ac()):a};_.qd=function ci(){return yob(),yob(),xob};_.Fb=function di(a){return xw(this,a)};_.rd=function fi(a){return RD(Qc(this,a),21)};_.sd=function hi(a){return RD(Sc(this,a),21)};_.mc=function ii(a){return yob(),new Lqb(RD(a,21))};_.pc=function ji(a,b){return new fh(this,a,RD(b,21))};var _E=sfb(xve,'AbstractSetMultimap',627);feb(1723,627,zve);_.hc=function mi(){return new yAb(this.b)};_.pd=function ni(){return new yAb(this.b)};_.jc=function oi(){return Zx(new yAb(this.b))};_.qd=function pi(){return Zx(new yAb(this.b))};_.cc=function qi(a){return RD(RD(Qc(this,a),21),87)};_.rd=function ri(a){return RD(RD(Qc(this,a),21),87)};_.fc=function si(a){return RD(RD(Sc(this,a),21),87)};_.sd=function ti(a){return RD(RD(Sc(this,a),21),87)};_.mc=function ui(a){return ZD(a,277)?Zx(RD(a,277)):(yob(),new jrb(RD(a,87)))};_.Zb=function li(){var a;return a=this.f,!a?(this.f=ZD(this.c,139)?new Uf(this,RD(this.c,139)):ZD(this.c,133)?new Mf(this,RD(this.c,133)):new ne(this,this.c)):a};_.pc=function vi(a,b){return ZD(b,277)?new eh(this,a,RD(b,277)):new bh(this,a,RD(b,87))};var bF=sfb(xve,'AbstractSortedSetMultimap',1723);feb(1724,1723,zve);_.Zb=function xi(){var a;return a=this.f,RD(RD(!a?(this.f=ZD(this.c,139)?new Uf(this,RD(this.c,139)):ZD(this.c,133)?new Mf(this,RD(this.c,133)):new ne(this,this.c)):a,133),139)};_.ec=function zi(){var a;return a=this.i,RD(RD(!a?(this.i=ZD(this.c,139)?new gg(this,RD(this.c,139)):ZD(this.c,133)?new eg(this,RD(this.c,133)):new zf(this,this.c)):a,87),277)};_.bc=function yi(){return ZD(this.c,139)?new gg(this,RD(this.c,139)):ZD(this.c,133)?new eg(this,RD(this.c,133)):new zf(this,this.c)};var aF=sfb(xve,'AbstractSortedKeySortedSetMultimap',1724);feb(2109,1,{2046:1});_.Fb=function Ai(a){return Qy(this,a)};_.Hb=function Bi(){var a;return Bob((a=this.g,!a?(this.g=new Di(this)):a))};_.Ib=function Ci(){var a;return Md((a=this.f,!a?(this.f=new Zj(this)):a))};var eF=sfb(xve,'AbstractTable',2109);feb(679,Eve,Fve,Di);_.$b=function Ei(){Xi()};_.Hc=function Fi(a){var b,c;if(ZD(a,479)){b=RD(a,697);c=RD(Xv(bj(this.a),Qm(b.c.e,b.b)),85);return !!c&&Nk(c.vc(),new gp(Qm(b.c.c,b.a),Ui(b.c,b.b,b.a)))}return false};_.Kc=function Gi(){return Vi(this.a)};_.Mc=function Hi(a){var b,c;if(ZD(a,479)){b=RD(a,697);c=RD(Xv(bj(this.a),Qm(b.c.e,b.b)),85);return !!c&&Ok(c.vc(),new gp(Qm(b.c.c,b.a),Ui(b.c,b.b,b.a)))}return false};_.gc=function Ii(){return dj(this.a)};_.Nc=function Ji(){return Wi(this.a)};var cF=sfb(xve,'AbstractTable/CellSet',679);feb(2025,31,Dve,Ki);_.$b=function Li(){Xi()};_.Hc=function Mi(a){return Yi(this.a,a)};_.Kc=function Ni(){return fj(this.a)};_.gc=function Oi(){return dj(this.a)};_.Nc=function Pi(){return gj(this.a)};var dF=sfb(xve,'AbstractTable/Values',2025);feb(1697,1696,zve);var fF=sfb(xve,'ArrayListMultimapGwtSerializationDependencies',1697);feb(520,1697,zve,Ri,Si);_.hc=function Ti(){return new cnb(this.a)};_.a=0;var gF=sfb(xve,'ArrayListMultimap',520);feb(678,2109,{678:1,2046:1,3:1},hj);var sF=sfb(xve,'ArrayTable',678);feb(2021,399,yve,ij);_.Xb=function jj(a){return new pj(this.a,a)};var hF=sfb(xve,'ArrayTable/1',2021);feb(2022,1,{},kj);_.td=function lj(a){return new pj(this.a,a)};var iF=sfb(xve,'ArrayTable/1methodref$getCell$Type',2022);feb(2110,1,{697:1});_.Fb=function mj(a){var b;if(a===this){return true}if(ZD(a,479)){b=RD(a,697);return Hb(Qm(this.c.e,this.b),Qm(b.c.e,b.b))&&Hb(Qm(this.c.c,this.a),Qm(b.c.c,b.a))&&Hb(Ui(this.c,this.b,this.a),Ui(b.c,b.b,b.a))}return false};_.Hb=function nj(){return Tnb(cD(WC(jJ,1),rve,1,5,[Qm(this.c.e,this.b),Qm(this.c.c,this.a),Ui(this.c,this.b,this.a)]))};_.Ib=function oj(){return '('+Qm(this.c.e,this.b)+','+Qm(this.c.c,this.a)+')='+Ui(this.c,this.b,this.a)};var bI=sfb(xve,'Tables/AbstractCell',2110);feb(479,2110,{479:1,697:1},pj);_.a=0;_.b=0;_.d=0;var jF=sfb(xve,'ArrayTable/2',479);feb(2024,1,{},qj);_.td=function rj(a){return _i(this.a,a)};var kF=sfb(xve,'ArrayTable/2methodref$getValue$Type',2024);feb(2023,399,yve,sj);_.Xb=function tj(a){return _i(this.a,a)};var lF=sfb(xve,'ArrayTable/3',2023);feb(2077,2065,Cve);_.$b=function vj(){Ar(this.kc())};_.vc=function wj(){return new gw(this)};_.lc=function xj(){return new Uwb(this.kc(),this.gc())};var pH=sfb(xve,'Maps/IteratorBasedAbstractMap',2077);feb(842,2077,Cve);_.$b=function Bj(){throw Adb(new jib)};_._b=function Cj(a){return En(this.c,a)};_.kc=function Dj(){return new Rj(this,this.c.b.c.gc())};_.lc=function Ej(){return fk(this.c.b.c.gc(),16,new Lj(this))};_.xc=function Fj(a){var b;b=RD(Fn(this.c,a),17);return !b?null:this.vd(b.a)};_.dc=function Gj(){return this.c.b.c.dc()};_.ec=function Hj(){return hn(this.c)};_.zc=function Ij(a,b){var c;c=RD(Fn(this.c,a),17);if(!c){throw Adb(new agb(this.ud()+' '+a+' not in '+hn(this.c)))}return this.wd(c.a,b)};_.Bc=function Jj(a){throw Adb(new jib)};_.gc=function Kj(){return this.c.b.c.gc()};var pF=sfb(xve,'ArrayTable/ArrayMap',842);feb(2020,1,{},Lj);_.td=function Mj(a){return yj(this.a,a)};var mF=sfb(xve,'ArrayTable/ArrayMap/0methodref$getEntry$Type',2020);feb(2018,358,Kve,Nj);_.ld=function Oj(){return zj(this.a,this.b)};_.md=function Pj(){return this.a.vd(this.b)};_.nd=function Qj(a){return this.a.wd(this.b,a)};_.b=0;var nF=sfb(xve,'ArrayTable/ArrayMap/1',2018);feb(2019,399,yve,Rj);_.Xb=function Sj(a){return yj(this.a,a)};var oF=sfb(xve,'ArrayTable/ArrayMap/2',2019);feb(2017,842,Cve,Tj);_.ud=function Uj(){return 'Column'};_.vd=function Vj(a){return Ui(this.b,this.a,a)};_.wd=function Wj(a,b){return cj(this.b,this.a,a,b)};_.a=0;var rF=sfb(xve,'ArrayTable/Row',2017);feb(843,842,Cve,Zj);_.vd=function _j(a){return new Tj(this.a,a)};_.zc=function ak(a,b){return RD(b,85),Xj()};_.wd=function bk(a,b){return RD(b,85),Yj()};_.ud=function $j(){return 'Row'};var qF=sfb(xve,'ArrayTable/RowMap',843);feb(1157,1,Pve,hk);_.Ad=function lk(a){return (this.a.yd()&-262&a)!=0};_.yd=function ik(){return this.a.yd()&-262};_.zd=function jk(){return this.a.zd()};_.Nb=function kk(a){this.a.Nb(new pk(a,this.b))};_.Bd=function mk(a){return this.a.Bd(new nk(a,this.b))};var yF=sfb(xve,'CollectSpliterators/1',1157);feb(1158,1,Qve,nk);_.Cd=function ok(a){this.a.Cd(this.b.Kb(a))};var tF=sfb(xve,'CollectSpliterators/1/lambda$0$Type',1158);feb(1159,1,Qve,pk);_.Cd=function qk(a){this.a.Cd(this.b.Kb(a))};var uF=sfb(xve,'CollectSpliterators/1/lambda$1$Type',1159);feb(1154,1,Pve,rk);_.Ad=function vk(a){return ((16464|this.b)&a)!=0};_.yd=function sk(){return 16464|this.b};_.zd=function tk(){return this.a.zd()};_.Nb=function uk(a){this.a.Qe(new zk(a,this.c))};_.Bd=function wk(a){return this.a.Re(new xk(a,this.c))};_.b=0;var xF=sfb(xve,'CollectSpliterators/1WithCharacteristics',1154);feb(1155,1,Rve,xk);_.Dd=function yk(a){this.a.Cd(this.b.td(a))};var vF=sfb(xve,'CollectSpliterators/1WithCharacteristics/lambda$0$Type',1155);feb(1156,1,Rve,zk);_.Dd=function Ak(a){this.a.Cd(this.b.td(a))};var wF=sfb(xve,'CollectSpliterators/1WithCharacteristics/lambda$1$Type',1156);feb(1150,1,Pve);_.Ad=function Gk(a){return (this.a&a)!=0};_.yd=function Dk(){return this.a};_.zd=function Ek(){!!this.e&&(this.b=Kgb(this.b,this.e.zd()));return Kgb(this.b,0)};_.Nb=function Fk(a){if(this.e){this.e.Nb(a);this.e=null}this.c.Nb(new Kk(this,a));this.b=0};_.Bd=function Hk(a){while(true){if(!!this.e&&this.e.Bd(a)){Pdb(this.b,Sve)&&(this.b=Vdb(this.b,1));return true}else{this.e=null}if(!this.c.Bd(new Ik(this))){return false}}};_.a=0;_.b=0;var CF=sfb(xve,'CollectSpliterators/FlatMapSpliterator',1150);feb(1152,1,Qve,Ik);_.Cd=function Jk(a){Bk(this.a,a)};var zF=sfb(xve,'CollectSpliterators/FlatMapSpliterator/lambda$0$Type',1152);feb(1153,1,Qve,Kk);_.Cd=function Lk(a){Ck(this.a,this.b,a)};var AF=sfb(xve,'CollectSpliterators/FlatMapSpliterator/lambda$1$Type',1153);feb(1151,1150,Pve,Mk);var BF=sfb(xve,'CollectSpliterators/FlatMapSpliteratorOfObject',1151);feb(253,1,Tve);_.Fd=function Sk(a){return this.Ed(RD(a,253))};_.Ed=function Rk(a){var b;if(a==(kl(),jl)){return 1}if(a==(Wk(),Vk)){return -1}b=(ux(),Leb(this.a,a.a));if(b!=0){return b}return ZD(this,526)==ZD(a,526)?0:ZD(this,526)?1:-1};_.Id=function Tk(){return this.a};_.Fb=function Uk(a){return Pk(this,a)};var HF=sfb(xve,'Cut',253);feb(1823,253,Tve,Xk);_.Ed=function Yk(a){return a==this?0:1};_.Gd=function Zk(a){throw Adb(new Ceb)};_.Hd=function $k(a){a.a+='+\u221E)'};_.Id=function _k(){throw Adb(new dgb(Uve))};_.Hb=function al(){return gib(),jFb(this)};_.Jd=function bl(a){return false};_.Ib=function cl(){return '+\u221E'};var Vk;var DF=sfb(xve,'Cut/AboveAll',1823);feb(526,253,{253:1,526:1,3:1,34:1},dl);_.Gd=function el(a){Yhb((a.a+='(',a),this.a)};_.Hd=function fl(a){Thb(Yhb(a,this.a),93)};_.Hb=function gl(){return ~tb(this.a)};_.Jd=function hl(a){return ux(),Leb(this.a,a)<0};_.Ib=function il(){return '/'+this.a+'\\'};var EF=sfb(xve,'Cut/AboveValue',526);feb(1822,253,Tve,ll);_.Ed=function ml(a){return a==this?0:-1};_.Gd=function nl(a){a.a+='(-\u221E'};_.Hd=function ol(a){throw Adb(new Ceb)};_.Id=function pl(){throw Adb(new dgb(Uve))};_.Hb=function ql(){return gib(),jFb(this)};_.Jd=function rl(a){return true};_.Ib=function sl(){return '-\u221E'};var jl;var FF=sfb(xve,'Cut/BelowAll',1822);feb(1824,253,Tve,tl);_.Gd=function ul(a){Yhb((a.a+='[',a),this.a)};_.Hd=function vl(a){Thb(Yhb(a,this.a),41)};_.Hb=function wl(){return tb(this.a)};_.Jd=function xl(a){return ux(),Leb(this.a,a)<=0};_.Ib=function yl(){return '\\'+this.a+'/'};var GF=sfb(xve,'Cut/BelowValue',1824);feb(547,1,Vve);_.Jc=function Bl(a){xgb(this,a)};_.Ib=function Cl(){return Lr(RD(Rb(this,'use Optional.orNull() instead of Optional.or(null)'),20).Kc())};var LF=sfb(xve,'FluentIterable',547);feb(442,547,Vve,Dl);_.Kc=function El(){return new is(Mr(this.a.Kc(),new ir))};var IF=sfb(xve,'FluentIterable/2',442);feb(1059,547,Vve,Gl);_.Kc=function Hl(){return Fl(this)};var KF=sfb(xve,'FluentIterable/3',1059);feb(724,399,yve,Il);_.Xb=function Jl(a){return this.a[a].Kc()};var JF=sfb(xve,'FluentIterable/3/1',724);feb(2070,1,{});_.Ib=function Kl(){return jeb(this.Kd().b)};var SF=sfb(xve,'ForwardingObject',2070);feb(2071,2070,Wve);_.Kd=function Ql(){return this.Ld()};_.Jc=function Rl(a){xgb(this,a)};_.Lc=function Ul(){return this.Oc()};_.Nc=function Xl(){return new Swb(this,0)};_.Oc=function Yl(){return new SDb(null,this.Nc())};_.Fc=function Ll(a){return this.Ld(),qpb()};_.Gc=function Ml(a){return this.Ld(),rpb()};_.$b=function Nl(){this.Ld(),spb()};_.Hc=function Ol(a){return this.Ld().Hc(a)};_.Ic=function Pl(a){return this.Ld().Ic(a)};_.dc=function Sl(){return this.Ld().b.dc()};_.Kc=function Tl(){return this.Ld().Kc()};_.Mc=function Vl(a){return this.Ld(),vpb()};_.gc=function Wl(){return this.Ld().b.gc()};_.Pc=function Zl(){return this.Ld().Pc()};_.Qc=function $l(a){return this.Ld().Qc(a)};var MF=sfb(xve,'ForwardingCollection',2071);feb(2078,31,Xve);_.Kc=function gm(){return this.Od()};_.Fc=function am(a){throw Adb(new jib)};_.Gc=function bm(a){throw Adb(new jib)};_.Md=function cm(){var a;a=this.c;return !a?(this.c=this.Nd()):a};_.$b=function dm(){throw Adb(new jib)};_.Hc=function em(a){return a!=null&&ze(this,a,false)};_.Nd=function fm(){switch(this.gc()){case 0:return tm(),tm(),sm;case 1:return tm(),new Dy(Qb(this.Od().Pb()));default:return new Fx(this,this.Pc());}};_.Mc=function hm(a){throw Adb(new jib)};var lG=sfb(xve,'ImmutableCollection',2078);feb(727,2078,Xve,im);_.Kc=function nm(){return Nr(this.a.Kc())};_.Hc=function jm(a){return a!=null&&this.a.Hc(a)};_.Ic=function km(a){return this.a.Ic(a)};_.dc=function lm(){return this.a.dc()};_.Od=function mm(){return Nr(this.a.Kc())};_.gc=function om(){return this.a.gc()};_.Pc=function pm(){return this.a.Pc()};_.Qc=function qm(a){return this.a.Qc(a)};_.Ib=function rm(){return jeb(this.a)};var NF=sfb(xve,'ForwardingImmutableCollection',727);feb(307,2078,Yve);_.Kc=function Em(){return this.Od()};_.ed=function Fm(){return this.Pd(0)};_.fd=function Hm(a){return this.Pd(a)};_.jd=function Lm(a){tvb(this,a)};_.Nc=function Mm(){return new Swb(this,16)};_.kd=function Om(a,b){return this.Qd(a,b)};_.bd=function wm(a,b){throw Adb(new jib)};_.cd=function xm(a,b){throw Adb(new jib)};_.Md=function ym(){return this};_.Fb=function Am(a){return $u(this,a)};_.Hb=function Bm(){return _u(this)};_.dd=function Cm(a){return a==null?-1:av(this,a)};_.Od=function Dm(){return this.Pd(0)};_.Pd=function Gm(a){return um(this,a)};_.gd=function Jm(a){throw Adb(new jib)};_.hd=function Km(a,b){throw Adb(new jib)};_.Qd=function Nm(a,b){var c;return Pm((c=new pv(this),new Rkb(c,a,b)))};var sm;var qG=sfb(xve,'ImmutableList',307);feb(2105,307,Yve);_.Kc=function Zm(){return Nr(this.Rd().Kc())};_.kd=function an(a,b){return Pm(this.Rd().kd(a,b))};_.Hc=function Rm(a){return a!=null&&this.Rd().Hc(a)};_.Ic=function Sm(a){return this.Rd().Ic(a)};_.Fb=function Tm(a){return pb(this.Rd(),a)};_.Xb=function Um(a){return Qm(this,a)};_.Hb=function Vm(){return tb(this.Rd())};_.dd=function Wm(a){return this.Rd().dd(a)};_.dc=function Xm(){return this.Rd().dc()};_.Od=function Ym(){return Nr(this.Rd().Kc())};_.gc=function $m(){return this.Rd().gc()};_.Qd=function _m(a,b){return Pm(this.Rd().kd(a,b))};_.Pc=function bn(){return this.Rd().Qc($C(jJ,rve,1,this.Rd().gc(),5,1))};_.Qc=function cn(a){return this.Rd().Qc(a)};_.Ib=function dn(){return jeb(this.Rd())};var OF=sfb(xve,'ForwardingImmutableList',2105);feb(729,1,$ve);_.vc=function pn(){return gn(this)};_.wc=function rn(a){Bvb(this,a)};_.ec=function vn(){return hn(this)};_.yc=function wn(a,b,c){return Cvb(this,a,b,c)};_.Cc=function Dn(){return this.Vd()};_.$b=function kn(){throw Adb(new jib)};_._b=function ln(a){return this.xc(a)!=null};_.uc=function mn(a){return this.Vd().Hc(a)};_.Td=function nn(){return new xq(this)};_.Ud=function on(){return new Gq(this)};_.Fb=function qn(a){return Tv(this,a)};_.Hb=function tn(){return gn(this).Hb()};_.dc=function un(){return this.gc()==0};_.zc=function zn(a,b){return jn()};_.Bc=function An(a){throw Adb(new jib)};_.Ib=function Bn(){return Zv(this)};_.Vd=function Cn(){if(this.e){return this.e}return this.e=this.Ud()};_.c=null;_.d=null;_.e=null;var en;var AG=sfb(xve,'ImmutableMap',729);feb(730,729,$ve);_._b=function Hn(a){return En(this,a)};_.uc=function In(a){return pqb(this.b,a)};_.Sd=function Jn(){return go(new Xn(this))};_.Td=function Kn(){return go(sqb(this.b))};_.Ud=function Ln(){return _l(),new im(tqb(this.b))};_.Fb=function Mn(a){return rqb(this.b,a)};_.xc=function Nn(a){return Fn(this,a)};_.Hb=function On(){return tb(this.b.c)};_.dc=function Pn(){return this.b.c.dc()};_.gc=function Qn(){return this.b.c.gc()};_.Ib=function Rn(){return jeb(this.b.c)};var QF=sfb(xve,'ForwardingImmutableMap',730);feb(2072,2071,_ve);_.Kd=function Sn(){return this.Wd()};_.Ld=function Tn(){return this.Wd()};_.Nc=function Wn(){return new Swb(this,1)};_.Fb=function Un(a){return a===this||this.Wd().Fb(a)};_.Hb=function Vn(){return this.Wd().Hb()};var TF=sfb(xve,'ForwardingSet',2072);feb(1085,2072,_ve,Xn);_.Kd=function Zn(){return qqb(this.a.b)};_.Ld=function $n(){return qqb(this.a.b)};_.Hc=function Yn(b){if(ZD(b,44)&&RD(b,44).ld()==null){return false}try{return Pqb(qqb(this.a.b),b)}catch(a){a=zdb(a);if(ZD(a,212)){return false}else throw Adb(a)}};_.Wd=function _n(){return qqb(this.a.b)};_.Qc=function ao(a){var b;b=Qqb(qqb(this.a.b),a);qqb(this.a.b).b.gc()=0?'+':'')+(c/60|0);b=AB($wnd.Math.abs(c)%60);return (Mrb(),Krb)[this.q.getDay()]+' '+Lrb[this.q.getMonth()]+' '+AB(this.q.getDate())+' '+AB(this.q.getHours())+':'+AB(this.q.getMinutes())+':'+AB(this.q.getSeconds())+' GMT'+a+b+' '+this.q.getFullYear()};var qK=sfb(Bve,'Date',206);feb(2015,206,bxe,DB);_.a=false;_.b=0;_.c=0;_.d=0;_.e=0;_.f=0;_.g=false;_.i=0;_.j=0;_.k=0;_.n=0;_.o=0;_.p=0;var xI=sfb('com.google.gwt.i18n.shared.impl','DateRecord',2015);feb(2064,1,{});_.pe=function EB(){return null};_.qe=function FB(){return null};_.re=function GB(){return null};_.se=function HB(){return null};_.te=function IB(){return null};var GI=sfb(cxe,'JSONValue',2064);feb(221,2064,{221:1},MB,NB);_.Fb=function OB(a){if(!ZD(a,221)){return false}return Hz(this.a,RD(a,221).a)};_.oe=function PB(){return TB};_.Hb=function QB(){return Iz(this.a)};_.pe=function RB(){return this};_.Ib=function SB(){var a,b,c;c=new dib('[');for(b=0,a=this.a.length;b0&&(c.a+=',',c);Yhb(c,JB(this,b))}c.a+=']';return c.a};var yI=sfb(cxe,'JSONArray',221);feb(493,2064,{493:1},XB);_.oe=function YB(){return _B};_.qe=function ZB(){return this};_.Ib=function $B(){return Geb(),''+this.a};_.a=false;var UB,VB;var zI=sfb(cxe,'JSONBoolean',493);feb(997,63,swe,aC);var AI=sfb(cxe,'JSONException',997);feb(1036,2064,{},dC);_.oe=function eC(){return gC};_.Ib=function fC(){return vve};var bC;var BI=sfb(cxe,'JSONNull',1036);feb(263,2064,{263:1},hC);_.Fb=function iC(a){if(!ZD(a,263)){return false}return this.a==RD(a,263).a};_.oe=function jC(){return nC};_.Hb=function kC(){return Nfb(this.a)};_.re=function lC(){return this};_.Ib=function mC(){return this.a+''};_.a=0;var CI=sfb(cxe,'JSONNumber',263);feb(190,2064,{190:1},uC,vC);_.Fb=function wC(a){if(!ZD(a,190)){return false}return Hz(this.a,RD(a,190).a)};_.oe=function xC(){return BC};_.Hb=function yC(){return Iz(this.a)};_.se=function zC(){return this};_.Ib=function AC(){var a,b,c,d,e,f,g;g=new dib('{');a=true;f=oC(this,$C(qJ,Nve,2,0,6,1));for(c=f,d=0,e=c.length;d=0?':'+this.c:'')+')'};_.c=0;var mJ=sfb(mve,'StackTraceElement',319);PD={3:1,484:1,34:1,2:1};var qJ=sfb(mve,uwe,2);feb(111,427,{484:1},Qhb,Rhb,Shb);var nJ=sfb(mve,'StringBuffer',111);feb(104,427,{484:1},bib,cib,dib);var oJ=sfb(mve,'StringBuilder',104);feb(702,77,lxe,eib);var pJ=sfb(mve,'StringIndexOutOfBoundsException',702);feb(2145,1,{});var fib;feb(48,63,{3:1,103:1,63:1,82:1,48:1},jib,kib);var sJ=sfb(mve,'UnsupportedOperationException',48);feb(247,242,{3:1,34:1,242:1,247:1},Aib,Bib);_.Fd=function Eib(a){return uib(this,RD(a,247))};_.ue=function Fib(){return Neb(zib(this))};_.Fb=function Gib(a){var b;if(this===a){return true}if(ZD(a,247)){b=RD(a,247);return this.e==b.e&&uib(this,b)==0}return false};_.Hb=function Hib(){var a;if(this.b!=0){return this.b}if(this.a<54){a=Hdb(this.f);this.b=Ydb(Cdb(a,-1));this.b=33*this.b+Ydb(Cdb(Tdb(a,32),-1));this.b=17*this.b+eE(this.e);return this.b}this.b=17*Vib(this.c)+eE(this.e);return this.b};_.Ib=function Iib(){return zib(this)};_.a=0;_.b=0;_.d=0;_.e=0;_.f=0;var lib,mib,nib,oib,pib,qib,rib,sib;var tJ=sfb('java.math','BigDecimal',247);feb(92,242,{3:1,34:1,242:1,92:1},ajb,bjb,cjb,djb,ejb);_.Fd=function gjb(a){return Qib(this,RD(a,92))};_.ue=function hjb(){return Neb(Ajb(this,0))};_.Fb=function ijb(a){return Sib(this,a)};_.Hb=function ljb(){return Vib(this)};_.Ib=function njb(){return Ajb(this,0)};_.b=-2;_.c=0;_.d=0;_.e=0;var Jib,Kib,Lib,Mib,Nib,Oib;var uJ=sfb('java.math','BigInteger',92);var vjb,wjb;var Jjb,Kjb;feb(498,2065,Cve);_.$b=function dkb(){akb(this)};_._b=function ekb(a){return Ujb(this,a)};_.uc=function fkb(a){return Vjb(this,a,this.i)||Vjb(this,a,this.f)};_.vc=function gkb(){return new mkb(this)};_.xc=function hkb(a){return Wjb(this,a)};_.zc=function ikb(a,b){return Zjb(this,a,b)};_.Bc=function jkb(a){return _jb(this,a)};_.gc=function kkb(){return bkb(this)};_.g=0;var yJ=sfb(Bve,'AbstractHashMap',498);feb(267,Eve,Fve,mkb);_.$b=function nkb(){this.a.$b()};_.Hc=function okb(a){return lkb(this,a)};_.Kc=function pkb(){return new vkb(this.a)};_.Mc=function qkb(a){var b;if(lkb(this,a)){b=RD(a,44).ld();this.a.Bc(b);return true}return false};_.gc=function rkb(){return this.a.gc()};var xJ=sfb(Bve,'AbstractHashMap/EntrySet',267);feb(268,1,Ave,vkb);_.Nb=function wkb(a){Ztb(this,a)};_.Pb=function ykb(){return tkb(this)};_.Ob=function xkb(){return this.b};_.Qb=function zkb(){ukb(this)};_.b=false;_.d=0;var wJ=sfb(Bve,'AbstractHashMap/EntrySetIterator',268);feb(426,1,Ave,Dkb);_.Nb=function Ekb(a){Ztb(this,a)};_.Ob=function Fkb(){return Akb(this)};_.Pb=function Gkb(){return Bkb(this)};_.Qb=function Hkb(){Ckb(this)};_.b=0;_.c=-1;var zJ=sfb(Bve,'AbstractList/IteratorImpl',426);feb(98,426,Jve,Jkb);_.Qb=function Pkb(){Ckb(this)};_.Rb=function Kkb(a){Ikb(this,a)};_.Sb=function Lkb(){return this.b>0};_.Tb=function Mkb(){return this.b};_.Ub=function Nkb(){return sFb(this.b>0),this.a.Xb(this.c=--this.b)};_.Vb=function Okb(){return this.b-1};_.Wb=function Qkb(a){yFb(this.c!=-1);this.a.hd(this.c,a)};var AJ=sfb(Bve,'AbstractList/ListIteratorImpl',98);feb(244,56,kwe,Rkb);_.bd=function Skb(a,b){wFb(a,this.b);this.c.bd(this.a+a,b);++this.b};_.Xb=function Tkb(a){tFb(a,this.b);return this.c.Xb(this.a+a)};_.gd=function Ukb(a){var b;tFb(a,this.b);b=this.c.gd(this.a+a);--this.b;return b};_.hd=function Vkb(a,b){tFb(a,this.b);return this.c.hd(this.a+a,b)};_.gc=function Wkb(){return this.b};_.a=0;_.b=0;var BJ=sfb(Bve,'AbstractList/SubList',244);feb(266,Eve,Fve,Xkb);_.$b=function Ykb(){this.a.$b()};_.Hc=function Zkb(a){return this.a._b(a)};_.Kc=function $kb(){var a;return a=this.a.vc().Kc(),new blb(a)};_.Mc=function _kb(a){if(this.a._b(a)){this.a.Bc(a);return true}return false};_.gc=function alb(){return this.a.gc()};var EJ=sfb(Bve,'AbstractMap/1',266);feb(541,1,Ave,blb);_.Nb=function clb(a){Ztb(this,a)};_.Ob=function dlb(){return this.a.Ob()};_.Pb=function elb(){var a;return a=RD(this.a.Pb(),44),a.ld()};_.Qb=function flb(){this.a.Qb()};var DJ=sfb(Bve,'AbstractMap/1/1',541);feb(231,31,Dve,glb);_.$b=function hlb(){this.a.$b()};_.Hc=function ilb(a){return this.a.uc(a)};_.Kc=function jlb(){var a;return a=this.a.vc().Kc(),new llb(a)};_.gc=function klb(){return this.a.gc()};var GJ=sfb(Bve,'AbstractMap/2',231);feb(301,1,Ave,llb);_.Nb=function mlb(a){Ztb(this,a)};_.Ob=function nlb(){return this.a.Ob()};_.Pb=function olb(){var a;return a=RD(this.a.Pb(),44),a.md()};_.Qb=function plb(){this.a.Qb()};var FJ=sfb(Bve,'AbstractMap/2/1',301);feb(494,1,{494:1,44:1});_.Fb=function rlb(a){var b;if(!ZD(a,44)){return false}b=RD(a,44);return Fvb(this.d,b.ld())&&Fvb(this.e,b.md())};_.ld=function slb(){return this.d};_.md=function tlb(){return this.e};_.Hb=function ulb(){return Gvb(this.d)^Gvb(this.e)};_.nd=function vlb(a){return qlb(this,a)};_.Ib=function wlb(){return this.d+'='+this.e};var HJ=sfb(Bve,'AbstractMap/AbstractEntry',494);feb(397,494,{494:1,397:1,44:1},xlb);var IJ=sfb(Bve,'AbstractMap/SimpleEntry',397);feb(2082,1,Axe);_.Fb=function ylb(a){var b;if(!ZD(a,44)){return false}b=RD(a,44);return Fvb(this.ld(),b.ld())&&Fvb(this.md(),b.md())};_.Hb=function zlb(){return Gvb(this.ld())^Gvb(this.md())};_.Ib=function Alb(){return this.ld()+'='+this.md()};var JJ=sfb(Bve,Lve,2082);feb(2090,2065,Gve);_.Xc=function Dlb(a){return Vd(this.Ee(a))};_.tc=function Elb(a){return Blb(this,a)};_._b=function Flb(a){return Clb(this,a)};_.vc=function Glb(){return new Plb(this)};_.Tc=function Hlb(){return Klb(this.Ge())};_.Yc=function Ilb(a){return Vd(this.He(a))};_.xc=function Jlb(a){var b;b=a;return Wd(this.Fe(b))};_.$c=function Llb(a){return Vd(this.Ie(a))};_.ec=function Mlb(){return new Ulb(this)};_.Vc=function Nlb(){return Klb(this.Je())};_._c=function Olb(a){return Vd(this.Ke(a))};var OJ=sfb(Bve,'AbstractNavigableMap',2090);feb(629,Eve,Fve,Plb);_.Hc=function Qlb(a){return ZD(a,44)&&Blb(this.b,RD(a,44))};_.Kc=function Rlb(){return this.b.De()};_.Mc=function Slb(a){var b;if(ZD(a,44)){b=RD(a,44);return this.b.Le(b)}return false};_.gc=function Tlb(){return this.b.gc()};var LJ=sfb(Bve,'AbstractNavigableMap/EntrySet',629);feb(1146,Eve,Ive,Ulb);_.Nc=function $lb(){return new $wb(this)};_.$b=function Vlb(){this.a.$b()};_.Hc=function Wlb(a){return Clb(this.a,a)};_.Kc=function Xlb(){var a;a=this.a.vc().b.De();return new _lb(a)};_.Mc=function Ylb(a){if(Clb(this.a,a)){this.a.Bc(a);return true}return false};_.gc=function Zlb(){return this.a.gc()};var NJ=sfb(Bve,'AbstractNavigableMap/NavigableKeySet',1146);feb(1147,1,Ave,_lb);_.Nb=function amb(a){Ztb(this,a)};_.Ob=function bmb(){return Akb(this.a.a)};_.Pb=function cmb(){var a;a=vzb(this.a);return a.ld()};_.Qb=function dmb(){wzb(this.a)};var MJ=sfb(Bve,'AbstractNavigableMap/NavigableKeySet/1',1147);feb(2103,31,Dve);_.Fc=function emb(a){return zFb(lwb(this,a),Bxe),true};_.Gc=function fmb(a){uFb(a);mFb(a!=this,"Can't add a queue to itself");return ye(this,a)};_.$b=function gmb(){while(mwb(this)!=null);};var PJ=sfb(Bve,'AbstractQueue',2103);feb(310,31,{4:1,20:1,31:1,16:1},wmb,xmb);_.Fc=function ymb(a){return imb(this,a),true};_.$b=function Amb(){jmb(this)};_.Hc=function Bmb(a){return kmb(new Kmb(this),a)};_.dc=function Cmb(){return nmb(this)};_.Kc=function Dmb(){return new Kmb(this)};_.Mc=function Emb(a){return qmb(new Kmb(this),a)};_.gc=function Fmb(){return this.c-this.b&this.a.length-1};_.Nc=function Gmb(){return new Swb(this,272)};_.Qc=function Hmb(a){var b;b=this.c-this.b&this.a.length-1;a.lengthb&&bD(a,b,null);return a};_.b=0;_.c=0;var TJ=sfb(Bve,'ArrayDeque',310);feb(459,1,Ave,Kmb);_.Nb=function Lmb(a){Ztb(this,a)};_.Ob=function Mmb(){return this.a!=this.b};_.Pb=function Nmb(){return Imb(this)};_.Qb=function Omb(){Jmb(this)};_.a=0;_.b=0;_.c=-1;var SJ=sfb(Bve,'ArrayDeque/IteratorImpl',459);feb(13,56,Cxe,bnb,cnb,dnb);_.bd=function enb(a,b){Qmb(this,a,b)};_.Fc=function fnb(a){return Rmb(this,a)};_.cd=function gnb(a,b){return Smb(this,a,b)};_.Gc=function hnb(a){return Tmb(this,a)};_.$b=function inb(){aFb(this.c,0)};_.Hc=function jnb(a){return Wmb(this,a,0)!=-1};_.Jc=function knb(a){Umb(this,a)};_.Xb=function lnb(a){return Vmb(this,a)};_.dd=function mnb(a){return Wmb(this,a,0)};_.dc=function nnb(){return this.c.length==0};_.Kc=function onb(){return new Anb(this)};_.gd=function pnb(a){return Xmb(this,a)};_.Mc=function qnb(a){return Ymb(this,a)};_.ce=function rnb(a,b){Zmb(this,a,b)};_.hd=function snb(a,b){return $mb(this,a,b)};_.gc=function tnb(){return this.c.length};_.jd=function unb(a){_mb(this,a)};_.Pc=function vnb(){return UEb(this.c)};_.Qc=function wnb(a){return anb(this,a)};var VJ=sfb(Bve,'ArrayList',13);feb(7,1,Ave,Anb);_.Nb=function Bnb(a){Ztb(this,a)};_.Ob=function Cnb(){return xnb(this)};_.Pb=function Dnb(){return ynb(this)};_.Qb=function Enb(){znb(this)};_.a=0;_.b=-1;var UJ=sfb(Bve,'ArrayList/1',7);feb(2112,$wnd.Function,{},iob);_.Me=function job(a,b){return Qfb(a,b)};feb(151,56,Dxe,mob);_.Hc=function nob(a){return St(this,a)!=-1};_.Jc=function oob(a){var b,c,d,e;uFb(a);for(c=this.a,d=0,e=c.length;d0){throw Adb(new agb(Sxe+a+' greater than '+this.e))}return this.f.Te()?bzb(this.c,this.b,this.a,a,b):Ryb(this.c,a,b)};_.zc=function Vzb(a,b){if(!Tyb(this.c,this.f,a,this.b,this.a,this.e,this.d)){throw Adb(new agb(a+' outside the range '+this.b+' to '+this.e))}return Wyb(this.c,a,b)};_.Bc=function Wzb(a){var b;b=a;if(!Tyb(this.c,this.f,b,this.b,this.a,this.e,this.d)){return null}return Xyb(this.c,b)};_.Le=function Xzb(a){return Jzb(this,a.ld())&&Yyb(this.c,a)};_.gc=function Yzb(){var a,b,c;this.f.Te()?this.a?(b=Pyb(this.c,this.b,true)):(b=Pyb(this.c,this.b,false)):(b=Nyb(this.c));if(!(!!b&&Jzb(this,b.d)?b:null)){return 0}a=0;for(c=new yzb(this.c,this.f,this.b,this.a,this.e,this.d);Akb(c.a);c.b=RD(Bkb(c.a),44)){++a}return a};_.ad=function Zzb(a,b){if(this.f.Te()&&this.c.a.Ne(a,this.b)<0){throw Adb(new agb(Sxe+a+Txe+this.b))}return this.f.Ue()?bzb(this.c,a,b,this.e,this.d):czb(this.c,a,b)};_.a=false;_.d=false;var BL=sfb(Bve,'TreeMap/SubMap',631);feb(304,22,Uxe,dAb);_.Te=function eAb(){return false};_.Ue=function fAb(){return false};var $zb,_zb,aAb,bAb;var AL=tfb(Bve,'TreeMap/SubMapType',304,WI,hAb,gAb);feb(1143,304,Uxe,iAb);_.Ue=function jAb(){return true};var xL=tfb(Bve,'TreeMap/SubMapType/1',1143,AL,null,null);feb(1144,304,Uxe,kAb);_.Te=function lAb(){return true};_.Ue=function mAb(){return true};var yL=tfb(Bve,'TreeMap/SubMapType/2',1144,AL,null,null);feb(1145,304,Uxe,nAb);_.Te=function oAb(){return true};var zL=tfb(Bve,'TreeMap/SubMapType/3',1145,AL,null,null);var pAb;feb(157,Eve,{3:1,20:1,31:1,16:1,277:1,21:1,87:1,157:1},xAb,yAb,zAb);_.Nc=function GAb(){return new $wb(this)};_.Fc=function AAb(a){return rAb(this,a)};_.$b=function BAb(){this.a.$b()};_.Hc=function CAb(a){return this.a._b(a)};_.Kc=function DAb(){return this.a.ec().Kc()};_.Mc=function EAb(a){return wAb(this,a)};_.gc=function FAb(){return this.a.gc()};var DL=sfb(Bve,'TreeSet',157);feb(1082,1,{},JAb);_.Ve=function KAb(a,b){return HAb(this.a,a,b)};var FL=sfb(Vxe,'BinaryOperator/lambda$0$Type',1082);feb(1083,1,{},LAb);_.Ve=function MAb(a,b){return IAb(this.a,a,b)};var GL=sfb(Vxe,'BinaryOperator/lambda$1$Type',1083);feb(952,1,{},NAb);_.Kb=function OAb(a){return a};var HL=sfb(Vxe,'Function/lambda$0$Type',952);feb(395,1,nwe,PAb);_.Mb=function QAb(a){return !this.a.Mb(a)};var IL=sfb(Vxe,'Predicate/lambda$2$Type',395);feb(581,1,{581:1});var JL=sfb(Wxe,'Handler',581);feb(2107,1,nve);_.xe=function TAb(){return 'DUMMY'};_.Ib=function UAb(){return this.xe()};var RAb;var LL=sfb(Wxe,'Level',2107);feb(1706,2107,nve,VAb);_.xe=function WAb(){return 'INFO'};var KL=sfb(Wxe,'Level/LevelInfo',1706);feb(1843,1,{},$Ab);var XAb;var ML=sfb(Wxe,'LogManager',1843);feb(1896,1,nve,aBb);_.b=null;var NL=sfb(Wxe,'LogRecord',1896);feb(525,1,{525:1},oBb);_.e=false;var bBb=false,cBb=false,dBb=false,eBb=false,fBb=false;var OL=sfb(Wxe,'Logger',525);feb(835,581,{581:1},rBb);var PL=sfb(Wxe,'SimpleConsoleLogHandler',835);feb(108,22,{3:1,34:1,22:1,108:1},yBb);var uBb,vBb,wBb;var QL=tfb(Zxe,'Collector/Characteristics',108,WI,ABb,zBb);var BBb;feb(758,1,{},DBb);var RL=sfb(Zxe,'CollectorImpl',758);feb(1074,1,{},RBb);_.Ve=function SBb(a,b){return Hyb(RD(a,213),RD(b,213))};var SL=sfb(Zxe,'Collectors/10methodref$merge$Type',1074);feb(1075,1,{},TBb);_.Kb=function UBb(a){return Iyb(RD(a,213))};var TL=sfb(Zxe,'Collectors/11methodref$toString$Type',1075);feb(1076,1,{},VBb);_.Kb=function WBb(a){return Geb(),SSb(a)?true:false};var UL=sfb(Zxe,'Collectors/12methodref$test$Type',1076);feb(144,1,{},XBb);_.Yd=function YBb(a,b){RD(a,16).Fc(b)};var VL=sfb(Zxe,'Collectors/20methodref$add$Type',144);feb(146,1,{},ZBb);_.Xe=function $Bb(){return new bnb};var WL=sfb(Zxe,'Collectors/21methodref$ctor$Type',146);feb(359,1,{},_Bb);_.Xe=function aCb(){return new _sb};var XL=sfb(Zxe,'Collectors/23methodref$ctor$Type',359);feb(360,1,{},bCb);_.Yd=function cCb(a,b){Ysb(RD(a,49),b)};var YL=sfb(Zxe,'Collectors/24methodref$add$Type',360);feb(1069,1,{},dCb);_.Ve=function eCb(a,b){return EBb(RD(a,15),RD(b,16))};var ZL=sfb(Zxe,'Collectors/4methodref$addAll$Type',1069);feb(1073,1,{},fCb);_.Yd=function gCb(a,b){Gyb(RD(a,213),RD(b,484))};var $L=sfb(Zxe,'Collectors/9methodref$add$Type',1073);feb(1072,1,{},hCb);_.Xe=function iCb(){return new Jyb(this.a,this.b,this.c)};var _L=sfb(Zxe,'Collectors/lambda$15$Type',1072);feb(1077,1,{},jCb);_.Xe=function kCb(){var a;return a=new gub,dub(a,(Geb(),false),new bnb),dub(a,true,new bnb),a};var aM=sfb(Zxe,'Collectors/lambda$22$Type',1077);feb(1078,1,{},lCb);_.Xe=function mCb(){return cD(WC(jJ,1),rve,1,5,[this.a])};var bM=sfb(Zxe,'Collectors/lambda$25$Type',1078);feb(1079,1,{},nCb);_.Yd=function oCb(a,b){GBb(this.a,SD(a))};var cM=sfb(Zxe,'Collectors/lambda$26$Type',1079);feb(1080,1,{},pCb);_.Ve=function qCb(a,b){return HBb(this.a,SD(a),SD(b))};var dM=sfb(Zxe,'Collectors/lambda$27$Type',1080);feb(1081,1,{},rCb);_.Kb=function sCb(a){return SD(a)[0]};var eM=sfb(Zxe,'Collectors/lambda$28$Type',1081);feb(728,1,{},uCb);_.Ve=function vCb(a,b){return tCb(a,b)};var fM=sfb(Zxe,'Collectors/lambda$4$Type',728);feb(145,1,{},wCb);_.Ve=function xCb(a,b){return JBb(RD(a,16),RD(b,16))};var gM=sfb(Zxe,'Collectors/lambda$42$Type',145);feb(361,1,{},yCb);_.Ve=function zCb(a,b){return KBb(RD(a,49),RD(b,49))};var hM=sfb(Zxe,'Collectors/lambda$50$Type',361);feb(362,1,{},ACb);_.Kb=function BCb(a){return RD(a,49)};var iM=sfb(Zxe,'Collectors/lambda$51$Type',362);feb(1068,1,{},CCb);_.Yd=function DCb(a,b){LBb(this.a,RD(a,85),b)};var jM=sfb(Zxe,'Collectors/lambda$7$Type',1068);feb(1070,1,{},ECb);_.Ve=function FCb(a,b){return NBb(RD(a,85),RD(b,85),new dCb)};var kM=sfb(Zxe,'Collectors/lambda$8$Type',1070);feb(1071,1,{},GCb);_.Kb=function HCb(a){return MBb(this.a,RD(a,85))};var lM=sfb(Zxe,'Collectors/lambda$9$Type',1071);feb(550,1,{});_.$e=function OCb(){ICb(this)};_.d=false;var TM=sfb(Zxe,'TerminatableStream',550);feb(827,550,$xe,WCb);_.$e=function XCb(){ICb(this)};var qM=sfb(Zxe,'DoubleStreamImpl',827);feb(1847,736,Pve,$Cb);_.Re=function aDb(a){return ZCb(this,RD(a,189))};_.a=null;var nM=sfb(Zxe,'DoubleStreamImpl/2',1847);feb(1848,1,Gxe,bDb);_.Pe=function cDb(a){_Cb(this.a,a)};var mM=sfb(Zxe,'DoubleStreamImpl/2/lambda$0$Type',1848);feb(1845,1,Gxe,dDb);_.Pe=function eDb(a){YCb(this.a,a)};var oM=sfb(Zxe,'DoubleStreamImpl/lambda$0$Type',1845);feb(1846,1,Gxe,fDb);_.Pe=function gDb(a){Nrb(this.a,a)};var pM=sfb(Zxe,'DoubleStreamImpl/lambda$2$Type',1846);feb(1397,735,Pve,kDb);_.Re=function lDb(a){return jDb(this,RD(a,202))};_.a=0;_.b=0;_.c=0;var rM=sfb(Zxe,'IntStream/5',1397);feb(806,550,$xe,oDb);_.$e=function pDb(){ICb(this)};_._e=function qDb(){return LCb(this),this.a};var vM=sfb(Zxe,'IntStreamImpl',806);feb(807,550,$xe,rDb);_.$e=function sDb(){ICb(this)};_._e=function tDb(){return LCb(this),Txb(),Sxb};var sM=sfb(Zxe,'IntStreamImpl/Empty',807);feb(1687,1,Rve,uDb);_.Dd=function vDb(a){ktb(this.a,a)};var uM=sfb(Zxe,'IntStreamImpl/lambda$4$Type',1687);var RM=ufb(Zxe,'Stream');feb(26,550,{533:1,687:1,848:1},SDb);_.$e=function TDb(){ICb(this)};var wDb;var QM=sfb(Zxe,'StreamImpl',26);feb(1102,500,Pve,YDb);_.Bd=function ZDb(a){while(WDb(this)){if(this.a.Bd(a)){return true}else{ICb(this.b);this.b=null;this.a=null}}return false};var xM=sfb(Zxe,'StreamImpl/1',1102);feb(1103,1,Qve,$Db);_.Cd=function _Db(a){XDb(this.a,RD(a,848))};var wM=sfb(Zxe,'StreamImpl/1/lambda$0$Type',1103);feb(1104,1,nwe,aEb);_.Mb=function bEb(a){return Ysb(this.a,a)};var yM=sfb(Zxe,'StreamImpl/1methodref$add$Type',1104);feb(1105,500,Pve,cEb);_.Bd=function dEb(a){var b;if(!this.a){b=new bnb;this.b.a.Nb(new eEb(b));yob();_mb(b,this.c);this.a=new Swb(b,16)}return Rwb(this.a,a)};_.a=null;var AM=sfb(Zxe,'StreamImpl/5',1105);feb(1106,1,Qve,eEb);_.Cd=function fEb(a){Rmb(this.a,a)};var zM=sfb(Zxe,'StreamImpl/5/2methodref$add$Type',1106);feb(737,500,Pve,hEb);_.Bd=function iEb(a){this.b=false;while(!this.b&&this.c.Bd(new jEb(this,a)));return this.b};_.b=false;var CM=sfb(Zxe,'StreamImpl/FilterSpliterator',737);feb(1096,1,Qve,jEb);_.Cd=function kEb(a){gEb(this.a,this.b,a)};var BM=sfb(Zxe,'StreamImpl/FilterSpliterator/lambda$0$Type',1096);feb(1091,736,Pve,nEb);_.Re=function oEb(a){return mEb(this,RD(a,189))};var EM=sfb(Zxe,'StreamImpl/MapToDoubleSpliterator',1091);feb(1095,1,Qve,pEb);_.Cd=function qEb(a){lEb(this.a,this.b,a)};var DM=sfb(Zxe,'StreamImpl/MapToDoubleSpliterator/lambda$0$Type',1095);feb(1090,735,Pve,tEb);_.Re=function uEb(a){return sEb(this,RD(a,202))};var GM=sfb(Zxe,'StreamImpl/MapToIntSpliterator',1090);feb(1094,1,Qve,vEb);_.Cd=function wEb(a){rEb(this.a,this.b,a)};var FM=sfb(Zxe,'StreamImpl/MapToIntSpliterator/lambda$0$Type',1094);feb(734,500,Pve,zEb);_.Bd=function AEb(a){return yEb(this,a)};var IM=sfb(Zxe,'StreamImpl/MapToObjSpliterator',734);feb(1093,1,Qve,BEb);_.Cd=function CEb(a){xEb(this.a,this.b,a)};var HM=sfb(Zxe,'StreamImpl/MapToObjSpliterator/lambda$0$Type',1093);feb(1092,500,Pve,DEb);_.Bd=function EEb(a){while(Idb(this.b,0)){if(!this.a.Bd(new FEb)){return false}this.b=Vdb(this.b,1)}return this.a.Bd(a)};_.b=0;var KM=sfb(Zxe,'StreamImpl/SkipSpliterator',1092);feb(1097,1,Qve,FEb);_.Cd=function GEb(a){};var JM=sfb(Zxe,'StreamImpl/SkipSpliterator/lambda$0$Type',1097);feb(626,1,Qve,IEb);_.Cd=function JEb(a){HEb(this,a)};var LM=sfb(Zxe,'StreamImpl/ValueConsumer',626);feb(1098,1,Qve,KEb);_.Cd=function LEb(a){xDb()};var MM=sfb(Zxe,'StreamImpl/lambda$0$Type',1098);feb(1099,1,Qve,MEb);_.Cd=function NEb(a){xDb()};var NM=sfb(Zxe,'StreamImpl/lambda$1$Type',1099);feb(1100,1,{},OEb);_.Ve=function PEb(a,b){return UDb(this.a,a,b)};var OM=sfb(Zxe,'StreamImpl/lambda$4$Type',1100);feb(1101,1,Qve,QEb);_.Cd=function REb(a){VDb(this.b,this.a,a)};var PM=sfb(Zxe,'StreamImpl/lambda$5$Type',1101);feb(1107,1,Qve,SEb);_.Cd=function TEb(a){PCb(this.a,RD(a,380))};var SM=sfb(Zxe,'TerminatableStream/lambda$0$Type',1107);feb(2142,1,{});feb(2014,1,{},gFb);var UM=sfb('javaemul.internal','ConsoleLogger',2014);var iFb=0;feb(2134,1,{});feb(1830,1,Qve,FFb);_.Cd=function GFb(a){RD(a,317)};var VM=sfb(eye,'BowyerWatsonTriangulation/lambda$0$Type',1830);feb(1831,1,Qve,HFb);_.Cd=function IFb(a){ye(this.a,RD(a,317).e)};var WM=sfb(eye,'BowyerWatsonTriangulation/lambda$1$Type',1831);feb(1832,1,Qve,JFb);_.Cd=function KFb(a){RD(a,177)};var XM=sfb(eye,'BowyerWatsonTriangulation/lambda$2$Type',1832);feb(1827,1,fye,NFb);_.Ne=function OFb(a,b){return MFb(this.a,RD(a,177),RD(b,177))};_.Fb=function PFb(a){return this===a};_.Oe=function QFb(){return new Frb(this)};var YM=sfb(eye,'NaiveMinST/lambda$0$Type',1827);feb(449,1,{},SFb);var ZM=sfb(eye,'NodeMicroLayout',449);feb(177,1,{177:1},TFb);_.Fb=function UFb(a){var b;if(ZD(a,177)){b=RD(a,177);return Fvb(this.a,b.a)&&Fvb(this.b,b.b)||Fvb(this.a,b.b)&&Fvb(this.b,b.a)}else{return false}};_.Hb=function VFb(){return Gvb(this.a)+Gvb(this.b)};var $M=sfb(eye,'TEdge',177);feb(317,1,{317:1},XFb);_.Fb=function YFb(a){var b;if(ZD(a,317)){b=RD(a,317);return WFb(this,b.a)&&WFb(this,b.b)&&WFb(this,b.c)}else{return false}};_.Hb=function ZFb(){return Gvb(this.a)+Gvb(this.b)+Gvb(this.c)};var _M=sfb(eye,'TTriangle',317);feb(225,1,{225:1},$Fb);var aN=sfb(eye,'Tree',225);feb(1218,1,{},aGb);var cN=sfb(gye,'Scanline',1218);var bN=ufb(gye,hye);feb(1758,1,{},dGb);var dN=sfb(iye,'CGraph',1758);feb(316,1,{316:1},fGb);_.b=0;_.c=0;_.d=0;_.g=0;_.i=0;_.k=pxe;var fN=sfb(iye,'CGroup',316);feb(830,1,{},jGb);var eN=sfb(iye,'CGroup/CGroupBuilder',830);feb(60,1,{60:1},kGb);_.Ib=function lGb(){var a;if(this.j){return WD(this.j.Kb(this))}return lfb(hN),hN.o+'@'+(a=kFb(this)>>>0,a.toString(16))};_.f=0;_.i=pxe;var hN=sfb(iye,'CNode',60);feb(829,1,{},qGb);var gN=sfb(iye,'CNode/CNodeBuilder',829);var vGb;feb(1590,1,{},xGb);_.ff=function yGb(a,b){return 0};_.gf=function zGb(a,b){return 0};var iN=sfb(iye,kye,1590);feb(1853,1,{},AGb);_.cf=function BGb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;j=oxe;for(d=new Anb(a.a.b);d.ad.d.c||d.d.c==f.d.c&&d.d.b0?a+this.n.d+this.n.a:0};_.kf=function yKb(){var a,b,c,d,e;e=0;if(this.e){this.b?(e=this.b.a):!!this.a[1][1]&&(e=this.a[1][1].kf())}else if(this.g){e=vKb(this,pKb(this,null,true))}else{for(b=(ZJb(),cD(WC(JN,1),jwe,237,0,[WJb,XJb,YJb])),c=0,d=b.length;c0?e+this.n.b+this.n.c:0};_.lf=function zKb(){var a,b,c,d,e;if(this.g){a=pKb(this,null,false);for(c=(ZJb(),cD(WC(JN,1),jwe,237,0,[WJb,XJb,YJb])),d=0,e=c.length;d0){d[0]+=this.d;c-=d[0]}if(d[2]>0){d[2]+=this.d;c-=d[2]}this.c.a=$wnd.Math.max(0,c);this.c.d=b.d+a.d+(this.c.a-c)/2;d[1]=$wnd.Math.max(d[1],c);lKb(this,XJb,b.d+a.d+d[0]-(d[1]-c)/2,d)};_.b=null;_.d=0;_.e=false;_.f=false;_.g=false;var iKb=0,jKb=0;var LN=sfb(Jye,'GridContainerCell',1538);feb(471,22,{3:1,34:1,22:1,471:1},FKb);var BKb,CKb,DKb;var MN=tfb(Jye,'HorizontalLabelAlignment',471,WI,HKb,GKb);var IKb;feb(314,217,{217:1,314:1},TKb,UKb,VKb);_.jf=function WKb(){return PKb(this)};_.kf=function XKb(){return QKb(this)};_.a=0;_.c=false;var NN=sfb(Jye,'LabelCell',314);feb(252,336,{217:1,336:1,252:1},dLb);_.jf=function eLb(){return YKb(this)};_.kf=function fLb(){return ZKb(this)};_.lf=function iLb(){$Kb(this)};_.mf=function jLb(){_Kb(this)};_.b=0;_.c=0;_.d=false;var SN=sfb(Jye,'StripContainerCell',252);feb(1691,1,nwe,kLb);_.Mb=function lLb(a){return gLb(RD(a,217))};var ON=sfb(Jye,'StripContainerCell/lambda$0$Type',1691);feb(1692,1,{},mLb);_.Ye=function nLb(a){return RD(a,217).kf()};var PN=sfb(Jye,'StripContainerCell/lambda$1$Type',1692);feb(1693,1,nwe,oLb);_.Mb=function pLb(a){return hLb(RD(a,217))};var QN=sfb(Jye,'StripContainerCell/lambda$2$Type',1693);feb(1694,1,{},qLb);_.Ye=function rLb(a){return RD(a,217).jf()};var RN=sfb(Jye,'StripContainerCell/lambda$3$Type',1694);feb(472,22,{3:1,34:1,22:1,472:1},wLb);var sLb,tLb,uLb;var TN=tfb(Jye,'VerticalLabelAlignment',472,WI,yLb,xLb);var zLb;feb(800,1,{},CLb);_.c=0;_.d=0;_.k=0;_.s=0;_.t=0;_.v=false;_.w=0;_.D=false;var WN=sfb(Rye,'NodeContext',800);feb(1536,1,fye,FLb);_.Ne=function GLb(a,b){return ELb(RD(a,64),RD(b,64))};_.Fb=function HLb(a){return this===a};_.Oe=function ILb(){return new Frb(this)};var UN=sfb(Rye,'NodeContext/0methodref$comparePortSides$Type',1536);feb(1537,1,fye,JLb);_.Ne=function KLb(a,b){return DLb(RD(a,117),RD(b,117))};_.Fb=function LLb(a){return this===a};_.Oe=function MLb(){return new Frb(this)};var VN=sfb(Rye,'NodeContext/1methodref$comparePortContexts$Type',1537);feb(164,22,{3:1,34:1,22:1,164:1},kMb);var NLb,OLb,PLb,QLb,RLb,SLb,TLb,ULb,VLb,WLb,XLb,YLb,ZLb,$Lb,_Lb,aMb,bMb,cMb,dMb,eMb,fMb,gMb;var XN=tfb(Rye,'NodeLabelLocation',164,WI,nMb,mMb);var oMb;feb(117,1,{117:1},rMb);_.a=false;var YN=sfb(Rye,'PortContext',117);feb(1541,1,Qve,KMb);_.Cd=function LMb(a){NKb(RD(a,314))};var ZN=sfb(Uye,Vye,1541);feb(1542,1,nwe,MMb);_.Mb=function NMb(a){return !!RD(a,117).c};var $N=sfb(Uye,Wye,1542);feb(1543,1,Qve,OMb);_.Cd=function PMb(a){NKb(RD(a,117).c)};var _N=sfb(Uye,'LabelPlacer/lambda$2$Type',1543);var QMb;feb(1540,1,Qve,YMb);_.Cd=function ZMb(a){RMb();qMb(RD(a,117))};var aO=sfb(Uye,'NodeLabelAndSizeUtilities/lambda$0$Type',1540);feb(801,1,Qve,dNb);_.Cd=function eNb(a){bNb(this.b,this.c,this.a,RD(a,187))};_.a=false;_.c=false;var bO=sfb(Uye,'NodeLabelCellCreator/lambda$0$Type',801);feb(1539,1,Qve,kNb);_.Cd=function lNb(a){jNb(this.a,RD(a,187))};var cO=sfb(Uye,'PortContextCreator/lambda$0$Type',1539);var sNb;feb(1902,1,{},MNb);var eO=sfb(Yye,'GreedyRectangleStripOverlapRemover',1902);feb(1903,1,fye,ONb);_.Ne=function PNb(a,b){return NNb(RD(a,226),RD(b,226))};_.Fb=function QNb(a){return this===a};_.Oe=function RNb(){return new Frb(this)};var dO=sfb(Yye,'GreedyRectangleStripOverlapRemover/0methodref$compareByYCoordinate$Type',1903);feb(1849,1,{},YNb);_.a=5;_.e=0;var kO=sfb(Yye,'RectangleStripOverlapRemover',1849);feb(1850,1,fye,aOb);_.Ne=function bOb(a,b){return ZNb(RD(a,226),RD(b,226))};_.Fb=function cOb(a){return this===a};_.Oe=function dOb(){return new Frb(this)};var fO=sfb(Yye,'RectangleStripOverlapRemover/0methodref$compareLeftRectangleBorders$Type',1850);feb(1852,1,fye,eOb);_.Ne=function fOb(a,b){return $Nb(RD(a,226),RD(b,226))};_.Fb=function gOb(a){return this===a};_.Oe=function hOb(){return new Frb(this)};var gO=sfb(Yye,'RectangleStripOverlapRemover/1methodref$compareRightRectangleBorders$Type',1852);feb(417,22,{3:1,34:1,22:1,417:1},nOb);var iOb,jOb,kOb,lOb;var hO=tfb(Yye,'RectangleStripOverlapRemover/OverlapRemovalDirection',417,WI,pOb,oOb);var qOb;feb(226,1,{226:1},sOb);var iO=sfb(Yye,'RectangleStripOverlapRemover/RectangleNode',226);feb(1851,1,Qve,tOb);_.Cd=function uOb(a){TNb(this.a,RD(a,226))};var jO=sfb(Yye,'RectangleStripOverlapRemover/lambda$1$Type',1851);feb(1323,1,fye,xOb);_.Ne=function yOb(a,b){return wOb(RD(a,176),RD(b,176))};_.Fb=function zOb(a){return this===a};_.Oe=function AOb(){return new Frb(this)};var oO=sfb($ye,'PolyominoCompactor/CornerCasesGreaterThanRestComparator',1323);feb(1326,1,{},BOb);_.Kb=function COb(a){return RD(a,334).a};var lO=sfb($ye,'PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$0$Type',1326);feb(1327,1,nwe,DOb);_.Mb=function EOb(a){return RD(a,332).a};var mO=sfb($ye,'PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$1$Type',1327);feb(1328,1,nwe,FOb);_.Mb=function GOb(a){return RD(a,332).a};var nO=sfb($ye,'PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$2$Type',1328);feb(1321,1,fye,IOb);_.Ne=function JOb(a,b){return HOb(RD(a,176),RD(b,176))};_.Fb=function KOb(a){return this===a};_.Oe=function LOb(){return new Frb(this)};var qO=sfb($ye,'PolyominoCompactor/MinNumOfExtensionDirectionsComparator',1321);feb(1324,1,{},MOb);_.Kb=function NOb(a){return RD(a,334).a};var pO=sfb($ye,'PolyominoCompactor/MinNumOfExtensionDirectionsComparator/lambda$0$Type',1324);feb(781,1,fye,POb);_.Ne=function QOb(a,b){return OOb(RD(a,176),RD(b,176))};_.Fb=function ROb(a){return this===a};_.Oe=function SOb(){return new Frb(this)};var rO=sfb($ye,'PolyominoCompactor/MinNumOfExtensionsComparator',781);feb(1319,1,fye,UOb);_.Ne=function VOb(a,b){return TOb(RD(a,330),RD(b,330))};_.Fb=function WOb(a){return this===a};_.Oe=function XOb(){return new Frb(this)};var tO=sfb($ye,'PolyominoCompactor/MinPerimeterComparator',1319);feb(1320,1,fye,ZOb);_.Ne=function $Ob(a,b){return YOb(RD(a,330),RD(b,330))};_.Fb=function _Ob(a){return this===a};_.Oe=function aPb(){return new Frb(this)};var sO=sfb($ye,'PolyominoCompactor/MinPerimeterComparatorWithShape',1320);feb(1322,1,fye,cPb);_.Ne=function dPb(a,b){return bPb(RD(a,176),RD(b,176))};_.Fb=function ePb(a){return this===a};_.Oe=function fPb(){return new Frb(this)};var vO=sfb($ye,'PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator',1322);feb(1325,1,{},gPb);_.Kb=function hPb(a){return RD(a,334).a};var uO=sfb($ye,'PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator/lambda$0$Type',1325);feb(782,1,{},kPb);_.Ve=function lPb(a,b){return jPb(this,RD(a,42),RD(b,176))};var wO=sfb($ye,'SuccessorCombination',782);feb(649,1,{},nPb);_.Ve=function oPb(a,b){var c;return mPb((c=RD(a,42),RD(b,176),c))};var xO=sfb($ye,'SuccessorJitter',649);feb(648,1,{},qPb);_.Ve=function rPb(a,b){var c;return pPb((c=RD(a,42),RD(b,176),c))};var yO=sfb($ye,'SuccessorLineByLine',648);feb(573,1,{},tPb);_.Ve=function uPb(a,b){var c;return sPb((c=RD(a,42),RD(b,176),c))};var zO=sfb($ye,'SuccessorManhattan',573);feb(1344,1,{},wPb);_.Ve=function xPb(a,b){var c;return vPb((c=RD(a,42),RD(b,176),c))};var AO=sfb($ye,'SuccessorMaxNormWindingInMathPosSense',1344);feb(409,1,{},APb);_.Ve=function BPb(a,b){return yPb(this,a,b)};_.c=false;_.d=false;_.e=false;_.f=false;var CO=sfb($ye,'SuccessorQuadrantsGeneric',409);feb(1345,1,{},CPb);_.Kb=function DPb(a){return RD(a,334).a};var BO=sfb($ye,'SuccessorQuadrantsGeneric/lambda$0$Type',1345);feb(332,22,{3:1,34:1,22:1,332:1},JPb);_.a=false;var EPb,FPb,GPb,HPb;var DO=tfb(dze,eze,332,WI,LPb,KPb);var MPb;feb(1317,1,{});_.Ib=function UPb(){var a,b,c,d,e,f;c=' ';a=sgb(0);for(e=0;e=0?'b'+a+'['+bUb(this.a)+']':'b['+bUb(this.a)+']'}return 'b_'+kFb(this)};var rP=sfb(Oze,'FBendpoint',250);feb(290,137,{3:1,290:1,96:1,137:1},cUb);_.Ib=function dUb(){return bUb(this)};var sP=sfb(Oze,'FEdge',290);feb(235,137,{3:1,235:1,96:1,137:1},gUb);var tP=sfb(Oze,'FGraph',235);feb(454,309,{3:1,454:1,309:1,96:1,137:1},iUb);_.Ib=function jUb(){return this.b==null||this.b.length==0?'l['+bUb(this.a)+']':'l_'+this.b};var uP=sfb(Oze,'FLabel',454);feb(153,309,{3:1,153:1,309:1,96:1,137:1},lUb);_.Ib=function mUb(){return kUb(this)};_.a=0;var vP=sfb(Oze,'FNode',153);feb(2100,1,{});_.vf=function rUb(a){nUb(this,a)};_.wf=function sUb(){oUb(this)};_.d=0;var xP=sfb(Qze,'AbstractForceModel',2100);feb(641,2100,{641:1},tUb);_.uf=function vUb(a,b){var c,d,e,f,g;qUb(this.f,a,b);e=ojd(ajd(b.d),a.d);g=$wnd.Math.sqrt(e.a*e.a+e.b*e.b);d=$wnd.Math.max(0,g-ejd(a.e)/2-ejd(b.e)/2);c=fUb(this.e,a,b);c>0?(f=-uUb(d,this.c)*c):(f=yUb(d,this.b)*RD(mQb(a,(yVb(),lVb)),17).a);ijd(e,f/g);return e};_.vf=function wUb(a){nUb(this,a);this.a=RD(mQb(a,(yVb(),aVb)),17).a;this.c=Kfb(UD(mQb(a,rVb)));this.b=Kfb(UD(mQb(a,nVb)))};_.xf=function xUb(a){return a0&&(f-=AUb(d,this.a)*c);ijd(e,f*this.b/g);return e};_.vf=function CUb(a){var b,c,d,e,f,g,h;nUb(this,a);this.b=Kfb(UD(mQb(a,(yVb(),sVb))));this.c=this.b/RD(mQb(a,aVb),17).a;d=a.e.c.length;f=0;e=0;for(h=new Anb(a.e);h.a0};_.a=0;_.b=0;_.c=0;var zP=sfb(Qze,'FruchtermanReingoldModel',642);feb(860,1,Eye,PUb);_.hf=function QUb(a){Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,Rze),''),'Force Model'),'Determines the model for force calculation.'),IUb),(kid(),eid)),BP),xsb((Yhd(),Whd)))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,Sze),''),'Iterations'),'The number of iterations on the force model.'),sgb(300)),gid),bJ),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,Tze),''),'Repulsive Power'),'Determines how many bend points are added to the edge; such bend points are regarded as repelling particles in the force model'),sgb(0)),gid),bJ),xsb(Thd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,Uze),''),'FR Temperature'),'The temperature is used as a scaling factor for particle displacements.'),Vze),did),VI),xsb(Whd))));zgd(a,Uze,Rze,NUb);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,Wze),''),'Eades Repulsion'),"Factor for repulsive forces in Eades' model."),5),did),VI),xsb(Whd))));zgd(a,Wze,Rze,KUb);zVb((new AVb,a))};var GUb,HUb,IUb,JUb,KUb,LUb,MUb,NUb;var AP=sfb(Xze,'ForceMetaDataProvider',860);feb(432,22,{3:1,34:1,22:1,432:1},UUb);var RUb,SUb;var BP=tfb(Xze,'ForceModelStrategy',432,WI,WUb,VUb);var XUb;feb(Awe,1,Eye,AVb);_.hf=function BVb(a){zVb(a)};var ZUb,$Ub,_Ub,aVb,bVb,cVb,dVb,eVb,fVb,gVb,hVb,iVb,jVb,kVb,lVb,mVb,nVb,oVb,pVb,qVb,rVb,sVb,tVb,uVb,vVb,wVb,xVb;var DP=sfb(Xze,'ForceOptions',Awe);feb(1001,1,{},CVb);_.sf=function DVb(){var a;return a=new TTb,a};_.tf=function EVb(a){};var CP=sfb(Xze,'ForceOptions/ForceFactory',1001);var FVb,GVb,HVb,IVb;feb(861,1,Eye,RVb);_.hf=function SVb(a){Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,vAe),''),'Fixed Position'),'Prevent that the node is moved by the layout algorithm.'),(Geb(),false)),(kid(),cid)),QI),xsb((Yhd(),Vhd)))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,wAe),''),'Desired Edge Length'),'Either specified for parent nodes or for individual edges, where the latter takes higher precedence.'),100),did),VI),ysb(Whd,cD(WC(d3,1),jwe,170,0,[Thd])))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,xAe),''),'Layout Dimension'),'Dimensions that are permitted to be altered during layout.'),MVb),eid),JP),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,yAe),''),'Stress Epsilon'),'Termination criterion for the iterative process.'),Vze),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,zAe),''),'Iteration Limit'),"Maximum number of performed iterations. Takes higher precedence than 'epsilon'."),sgb(lve)),gid),bJ),xsb(Whd))));eWb((new fWb,a))};var KVb,LVb,MVb,NVb,OVb,PVb;var EP=sfb(Xze,'StressMetaDataProvider',861);feb(1004,1,Eye,fWb);_.hf=function gWb(a){eWb(a)};var TVb,UVb,VVb,WVb,XVb,YVb,ZVb,$Vb,_Vb,aWb,bWb,cWb;var GP=sfb(Xze,'StressOptions',1004);feb(1005,1,{},hWb);_.sf=function iWb(){var a;return a=new kWb,a};_.tf=function jWb(a){};var FP=sfb(Xze,'StressOptions/StressFactory',1005);feb(1110,205,oze,kWb);_.rf=function lWb(a,b){var c,d,e,f,g;b.Ug(BAe,1);Heb(TD(Gxd(a,(dWb(),XVb))))?Heb(TD(Gxd(a,bWb)))||RFb((c=new SFb((lud(),new zud(a))),c)):QTb(new TTb,a,b.eh(1));e=KTb(a);d=CTb(this.a,e);for(g=d.Kc();g.Ob();){f=RD(g.Pb(),235);if(f.e.c.length<=1){continue}uWb(this.b,f);sWb(this.b);Umb(f.d,new mWb)}e=BTb(d);JTb(e);b.Vg()};var IP=sfb(DAe,'StressLayoutProvider',1110);feb(1111,1,Qve,mWb);_.Cd=function nWb(a){hUb(RD(a,454))};var HP=sfb(DAe,'StressLayoutProvider/lambda$0$Type',1111);feb(1002,1,{},vWb);_.c=0;_.e=0;_.g=0;var LP=sfb(DAe,'StressMajorization',1002);feb(391,22,{3:1,34:1,22:1,391:1},BWb);var xWb,yWb,zWb;var JP=tfb(DAe,'StressMajorization/Dimension',391,WI,DWb,CWb);var EWb;feb(1003,1,fye,GWb);_.Ne=function HWb(a,b){return wWb(this.a,RD(a,153),RD(b,153))};_.Fb=function IWb(a){return this===a};_.Oe=function JWb(){return new Frb(this)};var KP=sfb(DAe,'StressMajorization/lambda$0$Type',1003);feb(1192,1,{},RWb);var OP=sfb(FAe,'ElkLayered',1192);feb(1193,1,Qve,UWb);_.Cd=function VWb(a){SWb(this.a,RD(a,36))};var MP=sfb(FAe,'ElkLayered/lambda$0$Type',1193);feb(1194,1,Qve,WWb);_.Cd=function XWb(a){TWb(this.a,RD(a,36))};var NP=sfb(FAe,'ElkLayered/lambda$1$Type',1194);feb(1281,1,{},dXb);var YWb,ZWb,$Wb;var SP=sfb(FAe,'GraphConfigurator',1281);feb(770,1,Qve,fXb);_.Cd=function gXb(a){aXb(this.a,RD(a,10))};var PP=sfb(FAe,'GraphConfigurator/lambda$0$Type',770);feb(771,1,{},hXb);_.Kb=function iXb(a){return _Wb(),new SDb(null,new Swb(RD(a,30).a,16))};var QP=sfb(FAe,'GraphConfigurator/lambda$1$Type',771);feb(772,1,Qve,jXb);_.Cd=function kXb(a){aXb(this.a,RD(a,10))};var RP=sfb(FAe,'GraphConfigurator/lambda$2$Type',772);feb(1109,205,oze,lXb);_.rf=function mXb(a,b){var c;c=c5b(new k5b,a);dE(Gxd(a,(yCc(),IAc)))===dE((Fnd(),Cnd))?LWb(this.a,c,b):MWb(this.a,c,b);b.$g()||J5b(new N5b,c)};var TP=sfb(FAe,'LayeredLayoutProvider',1109);feb(367,22,{3:1,34:1,22:1,367:1},tXb);var nXb,oXb,pXb,qXb,rXb;var UP=tfb(FAe,'LayeredPhases',367,WI,vXb,uXb);var wXb;feb(1717,1,{},EXb);_.i=0;var yXb;var XP=sfb(GAe,'ComponentsToCGraphTransformer',1717);var jYb;feb(1718,1,{},FXb);_.yf=function GXb(a,b){return $wnd.Math.min(a.a!=null?Kfb(a.a):a.c.i,b.a!=null?Kfb(b.a):b.c.i)};_.zf=function HXb(a,b){return $wnd.Math.min(a.a!=null?Kfb(a.a):a.c.i,b.a!=null?Kfb(b.a):b.c.i)};var VP=sfb(GAe,'ComponentsToCGraphTransformer/1',1718);feb(86,1,{86:1});_.i=0;_.k=true;_.o=pxe;var bQ=sfb(HAe,'CNode',86);feb(470,86,{470:1,86:1},IXb,JXb);_.Ib=function KXb(){return ''};var WP=sfb(GAe,'ComponentsToCGraphTransformer/CRectNode',470);feb(1688,1,{},XXb);var LXb,MXb;var $P=sfb(GAe,'OneDimensionalComponentsCompaction',1688);feb(1689,1,{},$Xb);_.Kb=function _Xb(a){return YXb(RD(a,42))};_.Fb=function aYb(a){return this===a};var YP=sfb(GAe,'OneDimensionalComponentsCompaction/lambda$0$Type',1689);feb(1690,1,{},bYb);_.Kb=function cYb(a){return ZXb(RD(a,42))};_.Fb=function dYb(a){return this===a};var ZP=sfb(GAe,'OneDimensionalComponentsCompaction/lambda$1$Type',1690);feb(1720,1,{},fYb);var _P=sfb(HAe,'CGraph',1720);feb(194,1,{194:1},iYb);_.b=0;_.c=0;_.e=0;_.g=true;_.i=pxe;var aQ=sfb(HAe,'CGroup',194);feb(1719,1,{},lYb);_.yf=function mYb(a,b){return $wnd.Math.max(a.a!=null?Kfb(a.a):a.c.i,b.a!=null?Kfb(b.a):b.c.i)};_.zf=function nYb(a,b){return $wnd.Math.max(a.a!=null?Kfb(a.a):a.c.i,b.a!=null?Kfb(b.a):b.c.i)};var cQ=sfb(HAe,kye,1719);feb(1721,1,{},EYb);_.d=false;var oYb;var eQ=sfb(HAe,pye,1721);feb(1722,1,{},FYb);_.Kb=function GYb(a){return pYb(),Geb(),RD(RD(a,42).a,86).d.e!=0?true:false};_.Fb=function HYb(a){return this===a};var dQ=sfb(HAe,qye,1722);feb(833,1,{},KYb);_.a=false;_.b=false;_.c=false;_.d=false;var fQ=sfb(HAe,rye,833);feb(1898,1,{},QYb);var kQ=sfb(IAe,sye,1898);var wQ=ufb(JAe,hye);feb(1899,1,{382:1},UYb);_.bf=function VYb(a){SYb(this,RD(a,476))};var hQ=sfb(IAe,tye,1899);feb(Owe,1,fye,XYb);_.Ne=function YYb(a,b){return WYb(RD(a,86),RD(b,86))};_.Fb=function ZYb(a){return this===a};_.Oe=function $Yb(){return new Frb(this)};var gQ=sfb(IAe,uye,Owe);feb(476,1,{476:1},_Yb);_.a=false;var iQ=sfb(IAe,vye,476);feb(1901,1,fye,aZb);_.Ne=function bZb(a,b){return RYb(RD(a,476),RD(b,476))};_.Fb=function cZb(a){return this===a};_.Oe=function dZb(){return new Frb(this)};var jQ=sfb(IAe,wye,1901);feb(148,1,{148:1},eZb,fZb);_.Fb=function gZb(a){var b;if(a==null){return false}if(mQ!=rb(a)){return false}b=RD(a,148);return Fvb(this.c,b.c)&&Fvb(this.d,b.d)};_.Hb=function hZb(){return Tnb(cD(WC(jJ,1),rve,1,5,[this.c,this.d]))};_.Ib=function iZb(){return '('+this.c+pve+this.d+(this.a?'cx':'')+this.b+')'};_.a=true;_.c=0;_.d=0;var mQ=sfb(JAe,'Point',148);feb(416,22,{3:1,34:1,22:1,416:1},qZb);var jZb,kZb,lZb,mZb;var lQ=tfb(JAe,'Point/Quadrant',416,WI,uZb,tZb);var vZb;feb(1708,1,{},EZb);_.b=null;_.c=null;_.d=null;_.e=null;_.f=null;var xZb,yZb,zZb,AZb,BZb;var vQ=sfb(JAe,'RectilinearConvexHull',1708);feb(583,1,{382:1},PZb);_.bf=function QZb(a){OZb(this,RD(a,148))};_.b=0;var MZb;var oQ=sfb(JAe,'RectilinearConvexHull/MaximalElementsEventHandler',583);feb(1710,1,fye,SZb);_.Ne=function TZb(a,b){return RZb(UD(a),UD(b))};_.Fb=function UZb(a){return this===a};_.Oe=function VZb(){return new Frb(this)};var nQ=sfb(JAe,'RectilinearConvexHull/MaximalElementsEventHandler/lambda$0$Type',1710);feb(1709,1,{382:1},XZb);_.bf=function YZb(a){WZb(this,RD(a,148))};_.a=0;_.b=null;_.c=null;_.d=null;_.e=null;var pQ=sfb(JAe,'RectilinearConvexHull/RectangleEventHandler',1709);feb(1711,1,fye,ZZb);_.Ne=function $Zb(a,b){return GZb(RD(a,148),RD(b,148))};_.Fb=function _Zb(a){return this===a};_.Oe=function a$b(){return new Frb(this)};var qQ=sfb(JAe,'RectilinearConvexHull/lambda$0$Type',1711);feb(1712,1,fye,b$b);_.Ne=function c$b(a,b){return HZb(RD(a,148),RD(b,148))};_.Fb=function d$b(a){return this===a};_.Oe=function e$b(){return new Frb(this)};var rQ=sfb(JAe,'RectilinearConvexHull/lambda$1$Type',1712);feb(1713,1,fye,f$b);_.Ne=function g$b(a,b){return IZb(RD(a,148),RD(b,148))};_.Fb=function h$b(a){return this===a};_.Oe=function i$b(){return new Frb(this)};var sQ=sfb(JAe,'RectilinearConvexHull/lambda$2$Type',1713);feb(1714,1,fye,j$b);_.Ne=function k$b(a,b){return JZb(RD(a,148),RD(b,148))};_.Fb=function l$b(a){return this===a};_.Oe=function m$b(){return new Frb(this)};var tQ=sfb(JAe,'RectilinearConvexHull/lambda$3$Type',1714);feb(1715,1,fye,n$b);_.Ne=function o$b(a,b){return KZb(RD(a,148),RD(b,148))};_.Fb=function p$b(a){return this===a};_.Oe=function q$b(){return new Frb(this)};var uQ=sfb(JAe,'RectilinearConvexHull/lambda$4$Type',1715);feb(1716,1,{},s$b);var xQ=sfb(JAe,'Scanline',1716);feb(2104,1,{});var yQ=sfb(KAe,'AbstractGraphPlacer',2104);feb(335,1,{335:1},C$b);_.Ff=function D$b(a){if(this.Gf(a)){Rc(this.b,RD(mQb(a,(Ywc(),ewc)),21),a);return true}else{return false}};_.Gf=function E$b(a){var b,c,d,e;b=RD(mQb(a,(Ywc(),ewc)),21);e=RD(Qc(y$b,b),21);for(d=e.Kc();d.Ob();){c=RD(d.Pb(),21);if(!RD(Qc(this.b,c),15).dc()){return false}}return true};var y$b;var BQ=sfb(KAe,'ComponentGroup',335);feb(779,2104,{},J$b);_.Hf=function K$b(a){var b,c;for(c=new Anb(this.a);c.ac){k=0;l+=h+d;h=0}i=f.c;w$b(f,k+i.a,l+i.b);hjd(i);e=$wnd.Math.max(e,k+j.a);h=$wnd.Math.max(h,j.b);k+=j.a+d}b.f.a=e;b.f.b=l+h};_.Jf=function Y_b(a,b){var c,d,e,f,g;if(dE(mQb(b,(yCc(),Yzc)))===dE((U$b(),T$b))){for(d=a.Kc();d.Ob();){c=RD(d.Pb(),36);g=0;for(f=new Anb(c.a);f.ac&&!RD(mQb(f,(Ywc(),ewc)),21).Hc((qpd(),Yod))||!!i&&RD(mQb(i,(Ywc(),ewc)),21).Hc((qpd(),Xod))||RD(mQb(f,(Ywc(),ewc)),21).Hc((qpd(),ppd))){m=l;n+=h+d;h=0}j=f.c;RD(mQb(f,(Ywc(),ewc)),21).Hc((qpd(),Yod))&&(m=e+d);w$b(f,m+j.a,n+j.b);e=$wnd.Math.max(e,m+k.a);RD(mQb(f,ewc),21).Hc(npd)&&(l=$wnd.Math.max(l,m+k.a+d));hjd(j);h=$wnd.Math.max(h,k.b);m+=k.a+d;i=f}b.f.a=e;b.f.b=n+h};_.Jf=function __b(a,b){};var OQ=sfb(KAe,'ModelOrderRowGraphPlacer',1313);feb(1311,1,fye,b0b);_.Ne=function c0b(a,b){return a0b(RD(a,36),RD(b,36))};_.Fb=function d0b(a){return this===a};_.Oe=function e0b(){return new Frb(this)};var PQ=sfb(KAe,'SimpleRowGraphPlacer/1',1311);var f0b;feb(1280,1,xye,l0b);_.Lb=function m0b(a){var b;return b=RD(mQb(RD(a,249).b,(yCc(),RAc)),75),!!b&&b.b!=0};_.Fb=function n0b(a){return this===a};_.Mb=function o0b(a){var b;return b=RD(mQb(RD(a,249).b,(yCc(),RAc)),75),!!b&&b.b!=0};var RQ=sfb(PAe,'CompoundGraphPostprocessor/1',1280);feb(1279,1,QAe,E0b);_.Kf=function F0b(a,b){y0b(this,RD(a,36),b)};var TQ=sfb(PAe,'CompoundGraphPreprocessor',1279);feb(453,1,{453:1},G0b);_.c=false;var SQ=sfb(PAe,'CompoundGraphPreprocessor/ExternalPort',453);feb(249,1,{249:1},J0b);_.Ib=function K0b(){return ps(this.c)+':'+_0b(this.b)};var VQ=sfb(PAe,'CrossHierarchyEdge',249);feb(777,1,fye,M0b);_.Ne=function N0b(a,b){return L0b(this,RD(a,249),RD(b,249))};_.Fb=function O0b(a){return this===a};_.Oe=function Q0b(){return new Frb(this)};var UQ=sfb(PAe,'CrossHierarchyEdgeComparator',777);feb(305,137,{3:1,305:1,96:1,137:1});_.p=0;var dR=sfb(RAe,'LGraphElement',305);feb(18,305,{3:1,18:1,305:1,96:1,137:1},a1b);_.Ib=function b1b(){return _0b(this)};var WQ=sfb(RAe,'LEdge',18);feb(36,305,{3:1,20:1,36:1,305:1,96:1,137:1},d1b);_.Jc=function e1b(a){xgb(this,a)};_.Kc=function f1b(){return new Anb(this.b)};_.Ib=function g1b(){if(this.b.c.length==0){return 'G-unlayered'+Fe(this.a)}else if(this.a.c.length==0){return 'G-layered'+Fe(this.b)}return 'G[layerless'+Fe(this.a)+', layers'+Fe(this.b)+']'};var eR=sfb(RAe,'LGraph',36);var h1b;feb(666,1,{});_.Lf=function j1b(){return this.e.n};_.of=function k1b(a){return mQb(this.e,a)};_.Mf=function l1b(){return this.e.o};_.Nf=function m1b(){return this.e.p};_.pf=function n1b(a){return nQb(this.e,a)};_.Of=function o1b(a){this.e.n.a=a.a;this.e.n.b=a.b};_.Pf=function p1b(a){this.e.o.a=a.a;this.e.o.b=a.b};_.Qf=function q1b(a){this.e.p=a};var XQ=sfb(RAe,'LGraphAdapters/AbstractLShapeAdapter',666);feb(474,1,{853:1},r1b);_.Rf=function s1b(){var a,b;if(!this.b){this.b=ev(this.a.b.c.length);for(b=new Anb(this.a.b);b.a0&&M2b((BFb(c-1,b.length),b.charCodeAt(c-1)),ZAe)){--c}if(g> ',a),M3b(c));Zhb(Yhb((a.a+='[',a),c.i),']')}return a.a};_.c=true;_.d=false;var D3b,E3b,F3b,G3b,H3b,I3b;var xR=sfb(RAe,'LPort',12);feb(408,1,Vve,T3b);_.Jc=function U3b(a){xgb(this,a)};_.Kc=function V3b(){var a;a=new Anb(this.a.e);return new W3b(a)};var mR=sfb(RAe,'LPort/1',408);feb(1309,1,Ave,W3b);_.Nb=function X3b(a){Ztb(this,a)};_.Pb=function Z3b(){return RD(ynb(this.a),18).c};_.Ob=function Y3b(){return xnb(this.a)};_.Qb=function $3b(){znb(this.a)};var lR=sfb(RAe,'LPort/1/1',1309);feb(369,1,Vve,_3b);_.Jc=function a4b(a){xgb(this,a)};_.Kc=function b4b(){var a;return a=new Anb(this.a.g),new c4b(a)};var oR=sfb(RAe,'LPort/2',369);feb(776,1,Ave,c4b);_.Nb=function d4b(a){Ztb(this,a)};_.Pb=function f4b(){return RD(ynb(this.a),18).d};_.Ob=function e4b(){return xnb(this.a)};_.Qb=function g4b(){znb(this.a)};var nR=sfb(RAe,'LPort/2/1',776);feb(1302,1,Vve,h4b);_.Jc=function i4b(a){xgb(this,a)};_.Kc=function j4b(){return new l4b(this)};var qR=sfb(RAe,'LPort/CombineIter',1302);feb(208,1,Ave,l4b);_.Nb=function m4b(a){Ztb(this,a)};_.Qb=function p4b(){$tb()};_.Ob=function n4b(){return k4b(this)};_.Pb=function o4b(){return xnb(this.a)?ynb(this.a):ynb(this.b)};var pR=sfb(RAe,'LPort/CombineIter/1',208);feb(1303,1,xye,r4b);_.Lb=function s4b(a){return q4b(a)};_.Fb=function t4b(a){return this===a};_.Mb=function u4b(a){return J3b(),RD(a,12).g.c.length!=0};var rR=sfb(RAe,'LPort/lambda$0$Type',1303);feb(1304,1,xye,w4b);_.Lb=function x4b(a){return v4b(a)};_.Fb=function y4b(a){return this===a};_.Mb=function z4b(a){return J3b(),RD(a,12).e.c.length!=0};var sR=sfb(RAe,'LPort/lambda$1$Type',1304);feb(1305,1,xye,A4b);_.Lb=function B4b(a){return J3b(),RD(a,12).j==(qpd(),Yod)};_.Fb=function C4b(a){return this===a};_.Mb=function D4b(a){return J3b(),RD(a,12).j==(qpd(),Yod)};var tR=sfb(RAe,'LPort/lambda$2$Type',1305);feb(1306,1,xye,E4b);_.Lb=function F4b(a){return J3b(),RD(a,12).j==(qpd(),Xod)};_.Fb=function G4b(a){return this===a};_.Mb=function H4b(a){return J3b(),RD(a,12).j==(qpd(),Xod)};var uR=sfb(RAe,'LPort/lambda$3$Type',1306);feb(1307,1,xye,I4b);_.Lb=function J4b(a){return J3b(),RD(a,12).j==(qpd(),npd)};_.Fb=function K4b(a){return this===a};_.Mb=function L4b(a){return J3b(),RD(a,12).j==(qpd(),npd)};var vR=sfb(RAe,'LPort/lambda$4$Type',1307);feb(1308,1,xye,M4b);_.Lb=function N4b(a){return J3b(),RD(a,12).j==(qpd(),ppd)};_.Fb=function O4b(a){return this===a};_.Mb=function P4b(a){return J3b(),RD(a,12).j==(qpd(),ppd)};var wR=sfb(RAe,'LPort/lambda$5$Type',1308);feb(30,305,{3:1,20:1,305:1,30:1,96:1,137:1},R4b);_.Jc=function S4b(a){xgb(this,a)};_.Kc=function T4b(){return new Anb(this.a)};_.Ib=function U4b(){return 'L_'+Wmb(this.b.b,this,0)+Fe(this.a)};var zR=sfb(RAe,'Layer',30);feb(1330,1,{},k5b);var JR=sfb(cBe,dBe,1330);feb(1334,1,{},o5b);_.Kb=function p5b(a){return AGd(RD(a,84))};var AR=sfb(cBe,'ElkGraphImporter/0methodref$connectableShapeToNode$Type',1334);feb(1337,1,{},q5b);_.Kb=function r5b(a){return AGd(RD(a,84))};var BR=sfb(cBe,'ElkGraphImporter/1methodref$connectableShapeToNode$Type',1337);feb(1331,1,Qve,s5b);_.Cd=function t5b(a){$4b(this.a,RD(a,123))};var CR=sfb(cBe,Nze,1331);feb(1332,1,Qve,u5b);_.Cd=function v5b(a){$4b(this.a,RD(a,123))};var DR=sfb(cBe,eBe,1332);feb(1333,1,{},w5b);_.Kb=function x5b(a){return new SDb(null,new Swb(mzd(RD(a,74)),16))};var ER=sfb(cBe,fBe,1333);feb(1335,1,nwe,y5b);_.Mb=function z5b(a){return l5b(this.a,RD(a,27))};var FR=sfb(cBe,gBe,1335);feb(1336,1,{},A5b);_.Kb=function B5b(a){return new SDb(null,new Swb(lzd(RD(a,74)),16))};var GR=sfb(cBe,'ElkGraphImporter/lambda$5$Type',1336);feb(1338,1,nwe,C5b);_.Mb=function D5b(a){return m5b(this.a,RD(a,27))};var HR=sfb(cBe,'ElkGraphImporter/lambda$7$Type',1338);feb(1339,1,nwe,E5b);_.Mb=function F5b(a){return n5b(RD(a,74))};var IR=sfb(cBe,'ElkGraphImporter/lambda$8$Type',1339);feb(1297,1,{},N5b);var G5b;var OR=sfb(cBe,'ElkGraphLayoutTransferrer',1297);feb(1298,1,nwe,Q5b);_.Mb=function R5b(a){return O5b(this.a,RD(a,18))};var KR=sfb(cBe,'ElkGraphLayoutTransferrer/lambda$0$Type',1298);feb(1299,1,Qve,S5b);_.Cd=function T5b(a){H5b();Rmb(this.a,RD(a,18))};var LR=sfb(cBe,'ElkGraphLayoutTransferrer/lambda$1$Type',1299);feb(1300,1,nwe,U5b);_.Mb=function V5b(a){return P5b(this.a,RD(a,18))};var MR=sfb(cBe,'ElkGraphLayoutTransferrer/lambda$2$Type',1300);feb(1301,1,Qve,W5b);_.Cd=function X5b(a){H5b();Rmb(this.a,RD(a,18))};var NR=sfb(cBe,'ElkGraphLayoutTransferrer/lambda$3$Type',1301);feb(819,1,{},e6b);var PR=sfb(hBe,'BiLinkedHashMultiMap',819);feb(1550,1,QAe,h6b);_.Kf=function i6b(a,b){f6b(RD(a,36),b)};var SR=sfb(hBe,'CommentNodeMarginCalculator',1550);feb(1551,1,{},j6b);_.Kb=function k6b(a){return new SDb(null,new Swb(RD(a,30).a,16))};var QR=sfb(hBe,'CommentNodeMarginCalculator/lambda$0$Type',1551);feb(1552,1,Qve,l6b);_.Cd=function m6b(a){g6b(RD(a,10))};var RR=sfb(hBe,'CommentNodeMarginCalculator/lambda$1$Type',1552);feb(1553,1,QAe,q6b);_.Kf=function r6b(a,b){o6b(RD(a,36),b)};var TR=sfb(hBe,'CommentPostprocessor',1553);feb(1554,1,QAe,v6b);_.Kf=function w6b(a,b){s6b(RD(a,36),b)};var UR=sfb(hBe,'CommentPreprocessor',1554);feb(1555,1,QAe,y6b);_.Kf=function z6b(a,b){x6b(RD(a,36),b)};var VR=sfb(hBe,'ConstraintsPostprocessor',1555);feb(1556,1,QAe,G6b);_.Kf=function H6b(a,b){E6b(RD(a,36),b)};var WR=sfb(hBe,'EdgeAndLayerConstraintEdgeReverser',1556);feb(1557,1,QAe,K6b);_.Kf=function M6b(a,b){I6b(RD(a,36),b)};var $R=sfb(hBe,'EndLabelPostprocessor',1557);feb(1558,1,{},N6b);_.Kb=function O6b(a){return new SDb(null,new Swb(RD(a,30).a,16))};var XR=sfb(hBe,'EndLabelPostprocessor/lambda$0$Type',1558);feb(1559,1,nwe,P6b);_.Mb=function Q6b(a){return L6b(RD(a,10))};var YR=sfb(hBe,'EndLabelPostprocessor/lambda$1$Type',1559);feb(1560,1,Qve,R6b);_.Cd=function S6b(a){J6b(RD(a,10))};var ZR=sfb(hBe,'EndLabelPostprocessor/lambda$2$Type',1560);feb(1561,1,QAe,b7b);_.Kf=function e7b(a,b){Z6b(RD(a,36),b)};var fS=sfb(hBe,'EndLabelPreprocessor',1561);feb(1562,1,{},f7b);_.Kb=function g7b(a){return new SDb(null,new Swb(RD(a,30).a,16))};var _R=sfb(hBe,'EndLabelPreprocessor/lambda$0$Type',1562);feb(1563,1,Qve,h7b);_.Cd=function i7b(a){V6b(this.a,this.b,this.c,RD(a,10))};_.a=0;_.b=0;_.c=false;var aS=sfb(hBe,'EndLabelPreprocessor/lambda$1$Type',1563);feb(1564,1,nwe,j7b);_.Mb=function k7b(a){return dE(mQb(RD(a,72),(yCc(),wAc)))===dE((Omd(),Nmd))};var bS=sfb(hBe,'EndLabelPreprocessor/lambda$2$Type',1564);feb(1565,1,Qve,l7b);_.Cd=function m7b(a){Mub(this.a,RD(a,72))};var cS=sfb(hBe,'EndLabelPreprocessor/lambda$3$Type',1565);feb(1566,1,nwe,n7b);_.Mb=function o7b(a){return dE(mQb(RD(a,72),(yCc(),wAc)))===dE((Omd(),Mmd))};var dS=sfb(hBe,'EndLabelPreprocessor/lambda$4$Type',1566);feb(1567,1,Qve,p7b);_.Cd=function q7b(a){Mub(this.a,RD(a,72))};var eS=sfb(hBe,'EndLabelPreprocessor/lambda$5$Type',1567);feb(1615,1,QAe,z7b);_.Kf=function A7b(a,b){w7b(RD(a,36),b)};var r7b;var nS=sfb(hBe,'EndLabelSorter',1615);feb(1616,1,fye,C7b);_.Ne=function D7b(a,b){return B7b(RD(a,466),RD(b,466))};_.Fb=function E7b(a){return this===a};_.Oe=function F7b(){return new Frb(this)};var gS=sfb(hBe,'EndLabelSorter/1',1616);feb(466,1,{466:1},G7b);var hS=sfb(hBe,'EndLabelSorter/LabelGroup',466);feb(1617,1,{},H7b);_.Kb=function I7b(a){return s7b(),new SDb(null,new Swb(RD(a,30).a,16))};var iS=sfb(hBe,'EndLabelSorter/lambda$0$Type',1617);feb(1618,1,nwe,J7b);_.Mb=function K7b(a){return s7b(),RD(a,10).k==(r3b(),p3b)};var jS=sfb(hBe,'EndLabelSorter/lambda$1$Type',1618);feb(1619,1,Qve,L7b);_.Cd=function M7b(a){x7b(RD(a,10))};var kS=sfb(hBe,'EndLabelSorter/lambda$2$Type',1619);feb(1620,1,nwe,N7b);_.Mb=function O7b(a){return s7b(),dE(mQb(RD(a,72),(yCc(),wAc)))===dE((Omd(),Mmd))};var lS=sfb(hBe,'EndLabelSorter/lambda$3$Type',1620);feb(1621,1,nwe,P7b);_.Mb=function Q7b(a){return s7b(),dE(mQb(RD(a,72),(yCc(),wAc)))===dE((Omd(),Nmd))};var mS=sfb(hBe,'EndLabelSorter/lambda$4$Type',1621);feb(1568,1,QAe,a8b);_.Kf=function b8b(a,b){$7b(this,RD(a,36))};_.b=0;_.c=0;var uS=sfb(hBe,'FinalSplineBendpointsCalculator',1568);feb(1569,1,{},c8b);_.Kb=function d8b(a){return new SDb(null,new Swb(RD(a,30).a,16))};var oS=sfb(hBe,'FinalSplineBendpointsCalculator/lambda$0$Type',1569);feb(1570,1,{},e8b);_.Kb=function f8b(a){return new SDb(null,new Twb(new is(Mr(a3b(RD(a,10)).a.Kc(),new ir))))};var pS=sfb(hBe,'FinalSplineBendpointsCalculator/lambda$1$Type',1570);feb(1571,1,nwe,g8b);_.Mb=function h8b(a){return !W0b(RD(a,18))};var qS=sfb(hBe,'FinalSplineBendpointsCalculator/lambda$2$Type',1571);feb(1572,1,nwe,i8b);_.Mb=function j8b(a){return nQb(RD(a,18),(Ywc(),Twc))};var rS=sfb(hBe,'FinalSplineBendpointsCalculator/lambda$3$Type',1572);feb(1573,1,Qve,k8b);_.Cd=function l8b(a){T7b(this.a,RD(a,131))};var sS=sfb(hBe,'FinalSplineBendpointsCalculator/lambda$4$Type',1573);feb(1574,1,Qve,m8b);_.Cd=function n8b(a){Eob(RD(a,18).a)};var tS=sfb(hBe,'FinalSplineBendpointsCalculator/lambda$5$Type',1574);feb(803,1,QAe,L8b);_.Kf=function M8b(a,b){C8b(this,RD(a,36),b)};var wS=sfb(hBe,'GraphTransformer',803);feb(517,22,{3:1,34:1,22:1,517:1},Q8b);var N8b,O8b;var vS=tfb(hBe,'GraphTransformer/Mode',517,WI,S8b,R8b);var T8b;feb(1575,1,QAe,Z8b);_.Kf=function $8b(a,b){W8b(RD(a,36),b)};var xS=sfb(hBe,'HierarchicalNodeResizingProcessor',1575);feb(1576,1,QAe,f9b);_.Kf=function g9b(a,b){b9b(RD(a,36),b)};var zS=sfb(hBe,'HierarchicalPortConstraintProcessor',1576);feb(1577,1,fye,i9b);_.Ne=function j9b(a,b){return h9b(RD(a,10),RD(b,10))};_.Fb=function k9b(a){return this===a};_.Oe=function l9b(){return new Frb(this)};var yS=sfb(hBe,'HierarchicalPortConstraintProcessor/NodeComparator',1577);feb(1578,1,QAe,o9b);_.Kf=function p9b(a,b){m9b(RD(a,36),b)};var AS=sfb(hBe,'HierarchicalPortDummySizeProcessor',1578);feb(1579,1,QAe,C9b);_.Kf=function D9b(a,b){v9b(this,RD(a,36),b)};_.a=0;var DS=sfb(hBe,'HierarchicalPortOrthogonalEdgeRouter',1579);feb(1580,1,fye,F9b);_.Ne=function G9b(a,b){return E9b(RD(a,10),RD(b,10))};_.Fb=function H9b(a){return this===a};_.Oe=function I9b(){return new Frb(this)};var BS=sfb(hBe,'HierarchicalPortOrthogonalEdgeRouter/1',1580);feb(1581,1,fye,K9b);_.Ne=function L9b(a,b){return J9b(RD(a,10),RD(b,10))};_.Fb=function M9b(a){return this===a};_.Oe=function N9b(){return new Frb(this)};var CS=sfb(hBe,'HierarchicalPortOrthogonalEdgeRouter/2',1581);feb(1582,1,QAe,Q9b);_.Kf=function R9b(a,b){P9b(RD(a,36),b)};var ES=sfb(hBe,'HierarchicalPortPositionProcessor',1582);feb(1583,1,QAe,$9b);_.Kf=function _9b(a,b){Z9b(this,RD(a,36))};_.a=0;_.c=0;var S9b,T9b;var IS=sfb(hBe,'HighDegreeNodeLayeringProcessor',1583);feb(580,1,{580:1},aac);_.b=-1;_.d=-1;var FS=sfb(hBe,'HighDegreeNodeLayeringProcessor/HighDegreeNodeInformation',580);feb(1584,1,{},bac);_.Kb=function cac(a){return U9b(),Z2b(RD(a,10))};_.Fb=function dac(a){return this===a};var GS=sfb(hBe,'HighDegreeNodeLayeringProcessor/lambda$0$Type',1584);feb(1585,1,{},eac);_.Kb=function fac(a){return U9b(),a3b(RD(a,10))};_.Fb=function gac(a){return this===a};var HS=sfb(hBe,'HighDegreeNodeLayeringProcessor/lambda$1$Type',1585);feb(1591,1,QAe,mac);_.Kf=function nac(a,b){lac(this,RD(a,36),b)};var NS=sfb(hBe,'HyperedgeDummyMerger',1591);feb(804,1,{},oac);_.a=false;_.b=false;_.c=false;var JS=sfb(hBe,'HyperedgeDummyMerger/MergeState',804);feb(1592,1,{},pac);_.Kb=function qac(a){return new SDb(null,new Swb(RD(a,30).a,16))};var KS=sfb(hBe,'HyperedgeDummyMerger/lambda$0$Type',1592);feb(1593,1,{},rac);_.Kb=function sac(a){return new SDb(null,new Swb(RD(a,10).j,16))};var LS=sfb(hBe,'HyperedgeDummyMerger/lambda$1$Type',1593);feb(1594,1,Qve,tac);_.Cd=function uac(a){RD(a,12).p=-1};var MS=sfb(hBe,'HyperedgeDummyMerger/lambda$2$Type',1594);feb(1595,1,QAe,xac);_.Kf=function yac(a,b){wac(RD(a,36),b)};var OS=sfb(hBe,'HypernodesProcessor',1595);feb(1596,1,QAe,Aac);_.Kf=function Bac(a,b){zac(RD(a,36),b)};var PS=sfb(hBe,'InLayerConstraintProcessor',1596);feb(1597,1,QAe,Dac);_.Kf=function Eac(a,b){Cac(RD(a,36),b)};var QS=sfb(hBe,'InnermostNodeMarginCalculator',1597);feb(1598,1,QAe,Iac);_.Kf=function Nac(a,b){Hac(this,RD(a,36))};_.a=pxe;_.b=pxe;_.c=oxe;_.d=oxe;var XS=sfb(hBe,'InteractiveExternalPortPositioner',1598);feb(1599,1,{},Oac);_.Kb=function Pac(a){return RD(a,18).d.i};_.Fb=function Qac(a){return this===a};var RS=sfb(hBe,'InteractiveExternalPortPositioner/lambda$0$Type',1599);feb(1600,1,{},Rac);_.Kb=function Sac(a){return Jac(this.a,UD(a))};_.Fb=function Tac(a){return this===a};var SS=sfb(hBe,'InteractiveExternalPortPositioner/lambda$1$Type',1600);feb(1601,1,{},Uac);_.Kb=function Vac(a){return RD(a,18).c.i};_.Fb=function Wac(a){return this===a};var TS=sfb(hBe,'InteractiveExternalPortPositioner/lambda$2$Type',1601);feb(1602,1,{},Xac);_.Kb=function Yac(a){return Kac(this.a,UD(a))};_.Fb=function Zac(a){return this===a};var US=sfb(hBe,'InteractiveExternalPortPositioner/lambda$3$Type',1602);feb(1603,1,{},$ac);_.Kb=function _ac(a){return Lac(this.a,UD(a))};_.Fb=function abc(a){return this===a};var VS=sfb(hBe,'InteractiveExternalPortPositioner/lambda$4$Type',1603);feb(1604,1,{},bbc);_.Kb=function cbc(a){return Mac(this.a,UD(a))};_.Fb=function dbc(a){return this===a};var WS=sfb(hBe,'InteractiveExternalPortPositioner/lambda$5$Type',1604);feb(81,22,{3:1,34:1,22:1,81:1,196:1},icc);_.dg=function jcc(){switch(this.g){case 15:return new Hrc;case 22:return new bsc;case 47:return new ksc;case 28:case 35:return new Ldc;case 32:return new h6b;case 42:return new q6b;case 1:return new v6b;case 41:return new y6b;case 56:return new L8b((P8b(),O8b));case 0:return new L8b((P8b(),N8b));case 2:return new G6b;case 54:return new K6b;case 33:return new b7b;case 51:return new a8b;case 55:return new Z8b;case 13:return new f9b;case 38:return new o9b;case 44:return new C9b;case 40:return new Q9b;case 9:return new $9b;case 49:return new Yjc;case 37:return new mac;case 43:return new xac;case 27:return new Aac;case 30:return new Dac;case 3:return new Iac;case 18:return new scc;case 29:return new ycc;case 5:return new Lcc;case 50:return new Ucc;case 34:return new pdc;case 36:return new Zdc;case 52:return new z7b;case 11:return new fec;case 7:return new pec;case 39:return new Dec;case 45:return new Gec;case 16:return new Kec;case 10:return new _ec;case 48:return new Bfc;case 21:return new Ifc;case 23:return new FKc((RKc(),PKc));case 8:return new Rfc;case 12:return new Zfc;case 4:return new cgc;case 19:return new xgc;case 17:return new Vgc;case 53:return new Ygc;case 6:return new Nhc;case 25:return new ahc;case 46:return new rhc;case 31:return new Yhc;case 14:return new jic;case 26:return new Ssc;case 20:return new yic;case 24:return new FKc((RKc(),QKc));default:throw Adb(new agb(lBe+(this.f!=null?this.f:''+this.g)));}};var ebc,fbc,gbc,hbc,ibc,jbc,kbc,lbc,mbc,nbc,obc,pbc,qbc,rbc,sbc,tbc,ubc,vbc,wbc,xbc,ybc,zbc,Abc,Bbc,Cbc,Dbc,Ebc,Fbc,Gbc,Hbc,Ibc,Jbc,Kbc,Lbc,Mbc,Nbc,Obc,Pbc,Qbc,Rbc,Sbc,Tbc,Ubc,Vbc,Wbc,Xbc,Ybc,Zbc,$bc,_bc,acc,bcc,ccc,dcc,ecc,fcc,gcc;var YS=tfb(hBe,mBe,81,WI,lcc,kcc);var mcc;feb(1605,1,QAe,scc);_.Kf=function tcc(a,b){qcc(RD(a,36),b)};var ZS=sfb(hBe,'InvertedPortProcessor',1605);feb(1606,1,QAe,ycc);_.Kf=function zcc(a,b){xcc(RD(a,36),b)};var bT=sfb(hBe,'LabelAndNodeSizeProcessor',1606);feb(1607,1,nwe,Acc);_.Mb=function Bcc(a){return RD(a,10).k==(r3b(),p3b)};var $S=sfb(hBe,'LabelAndNodeSizeProcessor/lambda$0$Type',1607);feb(1608,1,nwe,Ccc);_.Mb=function Dcc(a){return RD(a,10).k==(r3b(),m3b)};var _S=sfb(hBe,'LabelAndNodeSizeProcessor/lambda$1$Type',1608);feb(1609,1,Qve,Ecc);_.Cd=function Fcc(a){vcc(this.b,this.a,this.c,RD(a,10))};_.a=false;_.c=false;var aT=sfb(hBe,'LabelAndNodeSizeProcessor/lambda$2$Type',1609);feb(1610,1,QAe,Lcc);_.Kf=function Mcc(a,b){Jcc(RD(a,36),b)};var Gcc;var dT=sfb(hBe,'LabelDummyInserter',1610);feb(1611,1,xye,Ncc);_.Lb=function Occ(a){return dE(mQb(RD(a,72),(yCc(),wAc)))===dE((Omd(),Lmd))};_.Fb=function Pcc(a){return this===a};_.Mb=function Qcc(a){return dE(mQb(RD(a,72),(yCc(),wAc)))===dE((Omd(),Lmd))};var cT=sfb(hBe,'LabelDummyInserter/1',1611);feb(1612,1,QAe,Ucc);_.Kf=function Vcc(a,b){Tcc(RD(a,36),b)};var fT=sfb(hBe,'LabelDummyRemover',1612);feb(1613,1,nwe,Wcc);_.Mb=function Xcc(a){return Heb(TD(mQb(RD(a,72),(yCc(),vAc))))};var eT=sfb(hBe,'LabelDummyRemover/lambda$0$Type',1613);feb(1378,1,QAe,pdc);_.Kf=function tdc(a,b){ldc(this,RD(a,36),b)};_.a=null;var Ycc;var mT=sfb(hBe,'LabelDummySwitcher',1378);feb(293,1,{293:1},xdc);_.c=0;_.d=null;_.f=0;var gT=sfb(hBe,'LabelDummySwitcher/LabelDummyInfo',293);feb(1379,1,{},ydc);_.Kb=function zdc(a){return Zcc(),new SDb(null,new Swb(RD(a,30).a,16))};var hT=sfb(hBe,'LabelDummySwitcher/lambda$0$Type',1379);feb(1380,1,nwe,Adc);_.Mb=function Bdc(a){return Zcc(),RD(a,10).k==(r3b(),n3b)};var iT=sfb(hBe,'LabelDummySwitcher/lambda$1$Type',1380);feb(1381,1,{},Cdc);_.Kb=function Ddc(a){return qdc(this.a,RD(a,10))};var jT=sfb(hBe,'LabelDummySwitcher/lambda$2$Type',1381);feb(1382,1,Qve,Edc);_.Cd=function Fdc(a){rdc(this.a,RD(a,293))};var kT=sfb(hBe,'LabelDummySwitcher/lambda$3$Type',1382);feb(1383,1,fye,Gdc);_.Ne=function Hdc(a,b){return sdc(RD(a,293),RD(b,293))};_.Fb=function Idc(a){return this===a};_.Oe=function Jdc(){return new Frb(this)};var lT=sfb(hBe,'LabelDummySwitcher/lambda$4$Type',1383);feb(802,1,QAe,Ldc);_.Kf=function Mdc(a,b){Kdc(RD(a,36),b)};var nT=sfb(hBe,'LabelManagementProcessor',802);feb(1614,1,QAe,Zdc);_.Kf=function $dc(a,b){Tdc(RD(a,36),b)};var oT=sfb(hBe,'LabelSideSelector',1614);feb(1622,1,QAe,fec);_.Kf=function gec(a,b){bec(RD(a,36),b)};var pT=sfb(hBe,'LayerConstraintPostprocessor',1622);feb(1623,1,QAe,pec);_.Kf=function qec(a,b){nec(RD(a,36),b)};var hec;var rT=sfb(hBe,'LayerConstraintPreprocessor',1623);feb(371,22,{3:1,34:1,22:1,371:1},xec);var rec,sec,tec,uec;var qT=tfb(hBe,'LayerConstraintPreprocessor/HiddenNodeConnections',371,WI,zec,yec);var Aec;feb(1624,1,QAe,Dec);_.Kf=function Eec(a,b){Cec(RD(a,36),b)};var sT=sfb(hBe,'LayerSizeAndGraphHeightCalculator',1624);feb(1625,1,QAe,Gec);_.Kf=function Iec(a,b){Fec(RD(a,36),b)};var tT=sfb(hBe,'LongEdgeJoiner',1625);feb(1626,1,QAe,Kec);_.Kf=function Mec(a,b){Jec(RD(a,36),b)};var uT=sfb(hBe,'LongEdgeSplitter',1626);feb(1627,1,QAe,_ec);_.Kf=function cfc(a,b){Vec(this,RD(a,36),b)};_.e=0;_.f=0;_.j=0;_.k=0;_.n=0;_.o=0;var Pec,Qec;var AT=sfb(hBe,'NodePromotion',1627);feb(1628,1,fye,efc);_.Ne=function ffc(a,b){return dfc(RD(a,10),RD(b,10))};_.Fb=function gfc(a){return this===a};_.Oe=function hfc(){return new Frb(this)};var vT=sfb(hBe,'NodePromotion/1',1628);feb(1629,1,fye,jfc);_.Ne=function kfc(a,b){return ifc(RD(a,10),RD(b,10))};_.Fb=function lfc(a){return this===a};_.Oe=function mfc(){return new Frb(this)};var wT=sfb(hBe,'NodePromotion/2',1629);feb(1630,1,{},nfc);_.Kb=function ofc(a){return RD(a,42),Rec(),Geb(),true};_.Fb=function pfc(a){return this===a};var xT=sfb(hBe,'NodePromotion/lambda$0$Type',1630);feb(1631,1,{},qfc);_.Kb=function rfc(a){return afc(this.a,RD(a,42))};_.Fb=function sfc(a){return this===a};_.a=0;var yT=sfb(hBe,'NodePromotion/lambda$1$Type',1631);feb(1632,1,{},tfc);_.Kb=function ufc(a){return bfc(this.a,RD(a,42))};_.Fb=function vfc(a){return this===a};_.a=0;var zT=sfb(hBe,'NodePromotion/lambda$2$Type',1632);feb(1633,1,QAe,Bfc);_.Kf=function Cfc(a,b){wfc(RD(a,36),b)};var BT=sfb(hBe,'NorthSouthPortPostprocessor',1633);feb(1634,1,QAe,Ifc);_.Kf=function Kfc(a,b){Gfc(RD(a,36),b)};var DT=sfb(hBe,'NorthSouthPortPreprocessor',1634);feb(1635,1,fye,Lfc);_.Ne=function Mfc(a,b){return Jfc(RD(a,12),RD(b,12))};_.Fb=function Nfc(a){return this===a};_.Oe=function Ofc(){return new Frb(this)};var CT=sfb(hBe,'NorthSouthPortPreprocessor/lambda$0$Type',1635);feb(1636,1,QAe,Rfc);_.Kf=function Tfc(a,b){Qfc(RD(a,36),b)};var GT=sfb(hBe,'PartitionMidprocessor',1636);feb(1637,1,nwe,Ufc);_.Mb=function Vfc(a){return nQb(RD(a,10),(yCc(),tBc))};var ET=sfb(hBe,'PartitionMidprocessor/lambda$0$Type',1637);feb(1638,1,Qve,Wfc);_.Cd=function Xfc(a){Sfc(this.a,RD(a,10))};var FT=sfb(hBe,'PartitionMidprocessor/lambda$1$Type',1638);feb(1639,1,QAe,Zfc);_.Kf=function $fc(a,b){Yfc(RD(a,36),b)};var HT=sfb(hBe,'PartitionPostprocessor',1639);feb(1640,1,QAe,cgc);_.Kf=function dgc(a,b){agc(RD(a,36),b)};var MT=sfb(hBe,'PartitionPreprocessor',1640);feb(1641,1,nwe,egc);_.Mb=function fgc(a){return nQb(RD(a,10),(yCc(),tBc))};var IT=sfb(hBe,'PartitionPreprocessor/lambda$0$Type',1641);feb(1642,1,{},ggc);_.Kb=function hgc(a){return new SDb(null,new Twb(new is(Mr(a3b(RD(a,10)).a.Kc(),new ir))))};var JT=sfb(hBe,'PartitionPreprocessor/lambda$1$Type',1642);feb(1643,1,nwe,igc);_.Mb=function jgc(a){return _fc(RD(a,18))};var KT=sfb(hBe,'PartitionPreprocessor/lambda$2$Type',1643);feb(1644,1,Qve,kgc);_.Cd=function lgc(a){bgc(RD(a,18))};var LT=sfb(hBe,'PartitionPreprocessor/lambda$3$Type',1644);feb(1645,1,QAe,xgc);_.Kf=function Bgc(a,b){ugc(RD(a,36),b)};var mgc,ngc,ogc,pgc,qgc,rgc;var ST=sfb(hBe,'PortListSorter',1645);feb(1648,1,fye,Dgc);_.Ne=function Egc(a,b){return ygc(RD(a,12),RD(b,12))};_.Fb=function Fgc(a){return this===a};_.Oe=function Ggc(){return new Frb(this)};var NT=sfb(hBe,'PortListSorter/lambda$0$Type',1648);feb(1650,1,fye,Hgc);_.Ne=function Igc(a,b){return zgc(RD(a,12),RD(b,12))};_.Fb=function Jgc(a){return this===a};_.Oe=function Kgc(){return new Frb(this)};var OT=sfb(hBe,'PortListSorter/lambda$1$Type',1650);feb(1646,1,{},Lgc);_.Kb=function Mgc(a){return sgc(),RD(a,12).e};var PT=sfb(hBe,'PortListSorter/lambda$2$Type',1646);feb(1647,1,{},Ngc);_.Kb=function Ogc(a){return sgc(),RD(a,12).g};var QT=sfb(hBe,'PortListSorter/lambda$3$Type',1647);feb(1649,1,fye,Pgc);_.Ne=function Qgc(a,b){return Agc(RD(a,12),RD(b,12))};_.Fb=function Rgc(a){return this===a};_.Oe=function Sgc(){return new Frb(this)};var RT=sfb(hBe,'PortListSorter/lambda$4$Type',1649);feb(1651,1,QAe,Vgc);_.Kf=function Wgc(a,b){Tgc(RD(a,36),b)};var TT=sfb(hBe,'PortSideProcessor',1651);feb(1652,1,QAe,Ygc);_.Kf=function Zgc(a,b){Xgc(RD(a,36),b)};var UT=sfb(hBe,'ReversedEdgeRestorer',1652);feb(1657,1,QAe,ahc);_.Kf=function bhc(a,b){$gc(this,RD(a,36),b)};var _T=sfb(hBe,'SelfLoopPortRestorer',1657);feb(1658,1,{},chc);_.Kb=function dhc(a){return new SDb(null,new Swb(RD(a,30).a,16))};var VT=sfb(hBe,'SelfLoopPortRestorer/lambda$0$Type',1658);feb(1659,1,nwe,ehc);_.Mb=function fhc(a){return RD(a,10).k==(r3b(),p3b)};var WT=sfb(hBe,'SelfLoopPortRestorer/lambda$1$Type',1659);feb(1660,1,nwe,ghc);_.Mb=function hhc(a){return nQb(RD(a,10),(Ywc(),Pwc))};var XT=sfb(hBe,'SelfLoopPortRestorer/lambda$2$Type',1660);feb(1661,1,{},ihc);_.Kb=function jhc(a){return RD(mQb(RD(a,10),(Ywc(),Pwc)),337)};var YT=sfb(hBe,'SelfLoopPortRestorer/lambda$3$Type',1661);feb(1662,1,Qve,khc);_.Cd=function lhc(a){_gc(this.a,RD(a,337))};var ZT=sfb(hBe,'SelfLoopPortRestorer/lambda$4$Type',1662);feb(805,1,Qve,mhc);_.Cd=function nhc(a){Rmc(RD(a,105))};var $T=sfb(hBe,'SelfLoopPortRestorer/lambda$5$Type',805);feb(1663,1,QAe,rhc);_.Kf=function thc(a,b){ohc(RD(a,36),b)};var iU=sfb(hBe,'SelfLoopPostProcessor',1663);feb(1664,1,{},uhc);_.Kb=function vhc(a){return new SDb(null,new Swb(RD(a,30).a,16))};var aU=sfb(hBe,'SelfLoopPostProcessor/lambda$0$Type',1664);feb(1665,1,nwe,whc);_.Mb=function xhc(a){return RD(a,10).k==(r3b(),p3b)};var bU=sfb(hBe,'SelfLoopPostProcessor/lambda$1$Type',1665);feb(1666,1,nwe,yhc);_.Mb=function zhc(a){return nQb(RD(a,10),(Ywc(),Pwc))};var cU=sfb(hBe,'SelfLoopPostProcessor/lambda$2$Type',1666);feb(1667,1,Qve,Ahc);_.Cd=function Bhc(a){phc(RD(a,10))};var dU=sfb(hBe,'SelfLoopPostProcessor/lambda$3$Type',1667);feb(1668,1,{},Chc);_.Kb=function Dhc(a){return new SDb(null,new Swb(RD(a,105).f,1))};var eU=sfb(hBe,'SelfLoopPostProcessor/lambda$4$Type',1668);feb(1669,1,Qve,Ehc);_.Cd=function Fhc(a){qhc(this.a,RD(a,340))};var fU=sfb(hBe,'SelfLoopPostProcessor/lambda$5$Type',1669);feb(1670,1,nwe,Ghc);_.Mb=function Hhc(a){return !!RD(a,105).i};var gU=sfb(hBe,'SelfLoopPostProcessor/lambda$6$Type',1670);feb(1671,1,Qve,Ihc);_.Cd=function Jhc(a){shc(this.a,RD(a,105))};var hU=sfb(hBe,'SelfLoopPostProcessor/lambda$7$Type',1671);feb(1653,1,QAe,Nhc);_.Kf=function Ohc(a,b){Mhc(RD(a,36),b)};var mU=sfb(hBe,'SelfLoopPreProcessor',1653);feb(1654,1,{},Phc);_.Kb=function Qhc(a){return new SDb(null,new Swb(RD(a,105).f,1))};var jU=sfb(hBe,'SelfLoopPreProcessor/lambda$0$Type',1654);feb(1655,1,{},Rhc);_.Kb=function Shc(a){return RD(a,340).a};var kU=sfb(hBe,'SelfLoopPreProcessor/lambda$1$Type',1655);feb(1656,1,Qve,Thc);_.Cd=function Uhc(a){Lhc(RD(a,18))};var lU=sfb(hBe,'SelfLoopPreProcessor/lambda$2$Type',1656);feb(1672,1,QAe,Yhc);_.Kf=function Zhc(a,b){Whc(this,RD(a,36),b)};var sU=sfb(hBe,'SelfLoopRouter',1672);feb(1673,1,{},$hc);_.Kb=function _hc(a){return new SDb(null,new Swb(RD(a,30).a,16))};var nU=sfb(hBe,'SelfLoopRouter/lambda$0$Type',1673);feb(1674,1,nwe,aic);_.Mb=function bic(a){return RD(a,10).k==(r3b(),p3b)};var oU=sfb(hBe,'SelfLoopRouter/lambda$1$Type',1674);feb(1675,1,nwe,cic);_.Mb=function dic(a){return nQb(RD(a,10),(Ywc(),Pwc))};var pU=sfb(hBe,'SelfLoopRouter/lambda$2$Type',1675);feb(1676,1,{},eic);_.Kb=function fic(a){return RD(mQb(RD(a,10),(Ywc(),Pwc)),337)};var qU=sfb(hBe,'SelfLoopRouter/lambda$3$Type',1676);feb(1677,1,Qve,gic);_.Cd=function hic(a){Vhc(this.a,this.b,RD(a,337))};var rU=sfb(hBe,'SelfLoopRouter/lambda$4$Type',1677);feb(1678,1,QAe,jic);_.Kf=function mic(a,b){iic(RD(a,36),b)};var xU=sfb(hBe,'SemiInteractiveCrossMinProcessor',1678);feb(1679,1,nwe,nic);_.Mb=function oic(a){return RD(a,10).k==(r3b(),p3b)};var tU=sfb(hBe,'SemiInteractiveCrossMinProcessor/lambda$0$Type',1679);feb(1680,1,nwe,pic);_.Mb=function qic(a){return lQb(RD(a,10))._b((yCc(),IBc))};var uU=sfb(hBe,'SemiInteractiveCrossMinProcessor/lambda$1$Type',1680);feb(1681,1,fye,ric);_.Ne=function sic(a,b){return kic(RD(a,10),RD(b,10))};_.Fb=function tic(a){return this===a};_.Oe=function uic(){return new Frb(this)};var vU=sfb(hBe,'SemiInteractiveCrossMinProcessor/lambda$2$Type',1681);feb(1682,1,{},vic);_.Ve=function wic(a,b){return lic(RD(a,10),RD(b,10))};var wU=sfb(hBe,'SemiInteractiveCrossMinProcessor/lambda$3$Type',1682);feb(1684,1,QAe,yic);_.Kf=function Cic(a,b){xic(RD(a,36),b)};var AU=sfb(hBe,'SortByInputModelProcessor',1684);feb(1685,1,nwe,Dic);_.Mb=function Eic(a){return RD(a,12).g.c.length!=0};var yU=sfb(hBe,'SortByInputModelProcessor/lambda$0$Type',1685);feb(1686,1,Qve,Fic);_.Cd=function Gic(a){Aic(this.a,RD(a,12))};var zU=sfb(hBe,'SortByInputModelProcessor/lambda$1$Type',1686);feb(1759,817,{},Pic);_.df=function Qic(a){var b,c,d,e;this.c=a;switch(this.a.g){case 2:b=new bnb;FDb(CDb(new SDb(null,new Swb(this.c.a.b,16)),new Rjc),new Tjc(this,b));eHb(this,new Zic);Umb(b,new bjc);b.c.length=0;FDb(CDb(new SDb(null,new Swb(this.c.a.b,16)),new djc),new fjc(b));eHb(this,new jjc);Umb(b,new njc);b.c.length=0;c=Wvb(TCb(HDb(new SDb(null,new Swb(this.c.a.b,16)),new pjc(this))),new rjc);FDb(new SDb(null,new Swb(this.c.a.a,16)),new vjc(c,b));eHb(this,new zjc);Umb(b,new Djc);b.c.length=0;break;case 3:d=new bnb;eHb(this,new Ric);e=Wvb(TCb(HDb(new SDb(null,new Swb(this.c.a.b,16)),new Vic(this))),new tjc);FDb(CDb(new SDb(null,new Swb(this.c.a.b,16)),new Fjc),new Hjc(e,d));eHb(this,new Ljc);Umb(d,new Pjc);d.c.length=0;break;default:throw Adb(new Ied);}};_.b=0;var ZU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation',1759);feb(1760,1,xye,Ric);_.Lb=function Sic(a){return ZD(RD(a,60).g,154)};_.Fb=function Tic(a){return this===a};_.Mb=function Uic(a){return ZD(RD(a,60).g,154)};var BU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$0$Type',1760);feb(1761,1,{},Vic);_.Ye=function Wic(a){return Jic(this.a,RD(a,60))};var CU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$1$Type',1761);feb(1769,1,owe,Xic);_.de=function Yic(){Iic(this.a,this.b,-1)};_.b=0;var DU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$10$Type',1769);feb(1771,1,xye,Zic);_.Lb=function $ic(a){return ZD(RD(a,60).g,154)};_.Fb=function _ic(a){return this===a};_.Mb=function ajc(a){return ZD(RD(a,60).g,154)};var EU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$11$Type',1771);feb(1772,1,Qve,bjc);_.Cd=function cjc(a){RD(a,380).de()};var FU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$12$Type',1772);feb(1773,1,nwe,djc);_.Mb=function ejc(a){return ZD(RD(a,60).g,10)};var GU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$13$Type',1773);feb(1775,1,Qve,fjc);_.Cd=function gjc(a){Kic(this.a,RD(a,60))};var HU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$14$Type',1775);feb(1774,1,owe,hjc);_.de=function ijc(){Iic(this.b,this.a,-1)};_.a=0;var IU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$15$Type',1774);feb(1776,1,xye,jjc);_.Lb=function kjc(a){return ZD(RD(a,60).g,10)};_.Fb=function ljc(a){return this===a};_.Mb=function mjc(a){return ZD(RD(a,60).g,10)};var JU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$16$Type',1776);feb(1777,1,Qve,njc);_.Cd=function ojc(a){RD(a,380).de()};var KU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$17$Type',1777);feb(1778,1,{},pjc);_.Ye=function qjc(a){return Lic(this.a,RD(a,60))};var LU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$18$Type',1778);feb(1779,1,{},rjc);_.We=function sjc(){return 0};var MU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$19$Type',1779);feb(1762,1,{},tjc);_.We=function ujc(){return 0};var NU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$2$Type',1762);feb(1781,1,Qve,vjc);_.Cd=function wjc(a){Mic(this.a,this.b,RD(a,316))};_.a=0;var OU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$20$Type',1781);feb(1780,1,owe,xjc);_.de=function yjc(){Hic(this.a,this.b,-1)};_.b=0;var PU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$21$Type',1780);feb(1782,1,xye,zjc);_.Lb=function Ajc(a){return RD(a,60),true};_.Fb=function Bjc(a){return this===a};_.Mb=function Cjc(a){return RD(a,60),true};var QU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$22$Type',1782);feb(1783,1,Qve,Djc);_.Cd=function Ejc(a){RD(a,380).de()};var RU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$23$Type',1783);feb(1763,1,nwe,Fjc);_.Mb=function Gjc(a){return ZD(RD(a,60).g,10)};var SU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$3$Type',1763);feb(1765,1,Qve,Hjc);_.Cd=function Ijc(a){Nic(this.a,this.b,RD(a,60))};_.a=0;var TU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$4$Type',1765);feb(1764,1,owe,Jjc);_.de=function Kjc(){Iic(this.b,this.a,-1)};_.a=0;var UU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$5$Type',1764);feb(1766,1,xye,Ljc);_.Lb=function Mjc(a){return RD(a,60),true};_.Fb=function Njc(a){return this===a};_.Mb=function Ojc(a){return RD(a,60),true};var VU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$6$Type',1766);feb(1767,1,Qve,Pjc);_.Cd=function Qjc(a){RD(a,380).de()};var WU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$7$Type',1767);feb(1768,1,nwe,Rjc);_.Mb=function Sjc(a){return ZD(RD(a,60).g,154)};var XU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$8$Type',1768);feb(1770,1,Qve,Tjc);_.Cd=function Ujc(a){Oic(this.a,this.b,RD(a,60))};var YU=sfb(rBe,'EdgeAwareScanlineConstraintCalculation/lambda$9$Type',1770);feb(1586,1,QAe,Yjc);_.Kf=function bkc(a,b){Xjc(this,RD(a,36),b)};var Vjc;var bV=sfb(rBe,'HorizontalGraphCompactor',1586);feb(1587,1,{},ckc);_.ff=function dkc(a,b){var c,d,e;if(_jc(a,b)){return 0}c=Zjc(a);d=Zjc(b);if(!!c&&c.k==(r3b(),m3b)||!!d&&d.k==(r3b(),m3b)){return 0}e=RD(mQb(this.a.a,(Ywc(),Qwc)),312);return ZEc(e,c?c.k:(r3b(),o3b),d?d.k:(r3b(),o3b))};_.gf=function ekc(a,b){var c,d,e;if(_jc(a,b)){return 1}c=Zjc(a);d=Zjc(b);e=RD(mQb(this.a.a,(Ywc(),Qwc)),312);return aFc(e,c?c.k:(r3b(),o3b),d?d.k:(r3b(),o3b))};var $U=sfb(rBe,'HorizontalGraphCompactor/1',1587);feb(1588,1,{},fkc);_.ef=function gkc(a,b){return Wjc(),a.a.i==0};var _U=sfb(rBe,'HorizontalGraphCompactor/lambda$0$Type',1588);feb(1589,1,{},hkc);_.ef=function ikc(a,b){return akc(this.a,a,b)};var aV=sfb(rBe,'HorizontalGraphCompactor/lambda$1$Type',1589);feb(1730,1,{},Ckc);var jkc,kkc;var BV=sfb(rBe,'LGraphToCGraphTransformer',1730);feb(1738,1,nwe,Kkc);_.Mb=function Lkc(a){return a!=null};var cV=sfb(rBe,'LGraphToCGraphTransformer/0methodref$nonNull$Type',1738);feb(1731,1,{},Mkc);_.Kb=function Nkc(a){return lkc(),jeb(mQb(RD(RD(a,60).g,10),(Ywc(),Awc)))};var dV=sfb(rBe,'LGraphToCGraphTransformer/lambda$0$Type',1731);feb(1732,1,{},Okc);_.Kb=function Pkc(a){return lkc(),Mlc(RD(RD(a,60).g,154))};var eV=sfb(rBe,'LGraphToCGraphTransformer/lambda$1$Type',1732);feb(1741,1,nwe,Qkc);_.Mb=function Rkc(a){return lkc(),ZD(RD(a,60).g,10)};var fV=sfb(rBe,'LGraphToCGraphTransformer/lambda$10$Type',1741);feb(1742,1,Qve,Skc);_.Cd=function Tkc(a){Dkc(RD(a,60))};var gV=sfb(rBe,'LGraphToCGraphTransformer/lambda$11$Type',1742);feb(1743,1,nwe,Ukc);_.Mb=function Vkc(a){return lkc(),ZD(RD(a,60).g,154)};var hV=sfb(rBe,'LGraphToCGraphTransformer/lambda$12$Type',1743);feb(1747,1,Qve,Wkc);_.Cd=function Xkc(a){Ekc(RD(a,60))};var iV=sfb(rBe,'LGraphToCGraphTransformer/lambda$13$Type',1747);feb(1744,1,Qve,Ykc);_.Cd=function Zkc(a){Fkc(this.a,RD(a,8))};_.a=0;var jV=sfb(rBe,'LGraphToCGraphTransformer/lambda$14$Type',1744);feb(1745,1,Qve,$kc);_.Cd=function _kc(a){Gkc(this.a,RD(a,116))};_.a=0;var kV=sfb(rBe,'LGraphToCGraphTransformer/lambda$15$Type',1745);feb(1746,1,Qve,alc);_.Cd=function blc(a){Hkc(this.a,RD(a,8))};_.a=0;var lV=sfb(rBe,'LGraphToCGraphTransformer/lambda$16$Type',1746);feb(1748,1,{},clc);_.Kb=function dlc(a){return lkc(),new SDb(null,new Twb(new is(Mr(a3b(RD(a,10)).a.Kc(),new ir))))};var mV=sfb(rBe,'LGraphToCGraphTransformer/lambda$17$Type',1748);feb(1749,1,nwe,elc);_.Mb=function flc(a){return lkc(),W0b(RD(a,18))};var nV=sfb(rBe,'LGraphToCGraphTransformer/lambda$18$Type',1749);feb(1750,1,Qve,glc);_.Cd=function hlc(a){ukc(this.a,RD(a,18))};var oV=sfb(rBe,'LGraphToCGraphTransformer/lambda$19$Type',1750);feb(1734,1,Qve,ilc);_.Cd=function jlc(a){vkc(this.a,RD(a,154))};var pV=sfb(rBe,'LGraphToCGraphTransformer/lambda$2$Type',1734);feb(1751,1,{},klc);_.Kb=function llc(a){return lkc(),new SDb(null,new Swb(RD(a,30).a,16))};var qV=sfb(rBe,'LGraphToCGraphTransformer/lambda$20$Type',1751);feb(1752,1,{},mlc);_.Kb=function nlc(a){return lkc(),new SDb(null,new Twb(new is(Mr(a3b(RD(a,10)).a.Kc(),new ir))))};var rV=sfb(rBe,'LGraphToCGraphTransformer/lambda$21$Type',1752);feb(1753,1,{},olc);_.Kb=function plc(a){return lkc(),RD(mQb(RD(a,18),(Ywc(),Twc)),15)};var sV=sfb(rBe,'LGraphToCGraphTransformer/lambda$22$Type',1753);feb(1754,1,nwe,qlc);_.Mb=function rlc(a){return Ikc(RD(a,15))};var tV=sfb(rBe,'LGraphToCGraphTransformer/lambda$23$Type',1754);feb(1755,1,Qve,slc);_.Cd=function tlc(a){nkc(this.a,RD(a,15))};var uV=sfb(rBe,'LGraphToCGraphTransformer/lambda$24$Type',1755);feb(1733,1,Qve,ulc);_.Cd=function vlc(a){wkc(this.a,this.b,RD(a,154))};var vV=sfb(rBe,'LGraphToCGraphTransformer/lambda$3$Type',1733);feb(1735,1,{},wlc);_.Kb=function xlc(a){return lkc(),new SDb(null,new Swb(RD(a,30).a,16))};var wV=sfb(rBe,'LGraphToCGraphTransformer/lambda$4$Type',1735);feb(1736,1,{},ylc);_.Kb=function zlc(a){return lkc(),new SDb(null,new Twb(new is(Mr(a3b(RD(a,10)).a.Kc(),new ir))))};var xV=sfb(rBe,'LGraphToCGraphTransformer/lambda$5$Type',1736);feb(1737,1,{},Alc);_.Kb=function Blc(a){return lkc(),RD(mQb(RD(a,18),(Ywc(),Twc)),15)};var yV=sfb(rBe,'LGraphToCGraphTransformer/lambda$6$Type',1737);feb(1739,1,Qve,Clc);_.Cd=function Dlc(a){Jkc(this.a,RD(a,15))};var zV=sfb(rBe,'LGraphToCGraphTransformer/lambda$8$Type',1739);feb(1740,1,Qve,Elc);_.Cd=function Flc(a){xkc(this.a,this.b,RD(a,154))};var AV=sfb(rBe,'LGraphToCGraphTransformer/lambda$9$Type',1740);feb(1729,1,{},Jlc);_.cf=function Klc(a){var b,c,d,e,f;this.a=a;this.d=new BIb;this.c=$C(DN,rve,125,this.a.a.a.c.length,0,1);this.b=0;for(c=new Anb(this.a.a.a);c.a=p){Rmb(f,sgb(k));s=$wnd.Math.max(s,t[k-1]-l);h+=o;q+=t[k-1]-q;l=t[k-1];o=i[k]}o=$wnd.Math.max(o,i[k]);++k}h+=o}n=$wnd.Math.min(1/s,1/b.b/h);if(n>d){d=n;c=f}}return c};_.pg=function Psc(){return false};var XW=sfb(zBe,'MSDCutIndexHeuristic',816);feb(1683,1,QAe,Ssc);_.Kf=function Tsc(a,b){Rsc(RD(a,36),b)};var YW=sfb(zBe,'SingleEdgeGraphWrapper',1683);feb(232,22,{3:1,34:1,22:1,232:1},ctc);var Xsc,Ysc,Zsc,$sc,_sc,atc;var ZW=tfb(ABe,'CenterEdgeLabelPlacementStrategy',232,WI,etc,dtc);var ftc;feb(431,22,{3:1,34:1,22:1,431:1},ktc);var htc,itc;var $W=tfb(ABe,'ConstraintCalculationStrategy',431,WI,mtc,ltc);var ntc;feb(322,22,{3:1,34:1,22:1,322:1,188:1,196:1},utc);_.dg=function wtc(){return ttc(this)};_.qg=function vtc(){return ttc(this)};var ptc,qtc,rtc;var _W=tfb(ABe,'CrossingMinimizationStrategy',322,WI,ytc,xtc);var ztc;feb(351,22,{3:1,34:1,22:1,351:1},Ftc);var Btc,Ctc,Dtc;var aX=tfb(ABe,'CuttingStrategy',351,WI,Htc,Gtc);var Itc;feb(348,22,{3:1,34:1,22:1,348:1,188:1,196:1},Rtc);_.dg=function Ttc(){return Qtc(this)};_.qg=function Stc(){return Qtc(this)};var Ktc,Ltc,Mtc,Ntc,Otc;var bX=tfb(ABe,'CycleBreakingStrategy',348,WI,Vtc,Utc);var Wtc;feb(428,22,{3:1,34:1,22:1,428:1},_tc);var Ytc,Ztc;var cX=tfb(ABe,'DirectionCongruency',428,WI,buc,auc);var cuc;feb(460,22,{3:1,34:1,22:1,460:1},iuc);var euc,fuc,guc;var dX=tfb(ABe,'EdgeConstraint',460,WI,kuc,juc);var luc;feb(283,22,{3:1,34:1,22:1,283:1},vuc);var nuc,ouc,puc,quc,ruc,suc;var eX=tfb(ABe,'EdgeLabelSideSelection',283,WI,xuc,wuc);var yuc;feb(488,22,{3:1,34:1,22:1,488:1},Duc);var Auc,Buc;var fX=tfb(ABe,'EdgeStraighteningStrategy',488,WI,Fuc,Euc);var Guc;feb(281,22,{3:1,34:1,22:1,281:1},Puc);var Iuc,Juc,Kuc,Luc,Muc,Nuc;var gX=tfb(ABe,'FixedAlignment',281,WI,Ruc,Quc);var Suc;feb(282,22,{3:1,34:1,22:1,282:1},_uc);var Uuc,Vuc,Wuc,Xuc,Yuc,Zuc;var hX=tfb(ABe,'GraphCompactionStrategy',282,WI,bvc,avc);var cvc;feb(259,22,{3:1,34:1,22:1,259:1},pvc);var evc,fvc,gvc,hvc,ivc,jvc,kvc,lvc,mvc,nvc;var iX=tfb(ABe,'GraphProperties',259,WI,rvc,qvc);var svc;feb(299,22,{3:1,34:1,22:1,299:1},yvc);var uvc,vvc,wvc;var jX=tfb(ABe,'GreedySwitchType',299,WI,Avc,zvc);var Bvc;feb(311,22,{3:1,34:1,22:1,311:1},Hvc);var Dvc,Evc,Fvc;var kX=tfb(ABe,'InLayerConstraint',311,WI,Jvc,Ivc);var Kvc;feb(429,22,{3:1,34:1,22:1,429:1},Pvc);var Mvc,Nvc;var lX=tfb(ABe,'InteractiveReferencePoint',429,WI,Rvc,Qvc);var Svc;var Uvc,Vvc,Wvc,Xvc,Yvc,Zvc,$vc,_vc,awc,bwc,cwc,dwc,ewc,fwc,gwc,hwc,iwc,jwc,kwc,lwc,mwc,nwc,owc,pwc,qwc,rwc,swc,twc,uwc,vwc,wwc,xwc,ywc,zwc,Awc,Bwc,Cwc,Dwc,Ewc,Fwc,Gwc,Hwc,Iwc,Jwc,Kwc,Lwc,Mwc,Nwc,Owc,Pwc,Qwc,Rwc,Swc,Twc,Uwc,Vwc,Wwc,Xwc;feb(171,22,{3:1,34:1,22:1,171:1},dxc);var Zwc,$wc,_wc,axc,bxc;var mX=tfb(ABe,'LayerConstraint',171,WI,fxc,exc);var gxc;feb(859,1,Eye,Pzc);_.hf=function Qzc(a){Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,HBe),''),'Direction Congruency'),'Specifies how drawings of the same graph with different layout directions compare to each other: either a natural reading direction is preserved or the drawings are rotated versions of each other.'),Uxc),(kid(),eid)),cX),xsb((Yhd(),Whd)))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,IBe),''),'Feedback Edges'),'Whether feedback edges should be highlighted by routing around the nodes.'),(Geb(),false)),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,JBe),''),'Interactive Reference Point'),'Determines which point of a node is considered by interactive layout phases.'),pyc),eid),lX),xsb(Whd))));zgd(a,JBe,RBe,ryc);zgd(a,JBe,_Be,qyc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,KBe),''),'Merge Edges'),'Edges that have no ports are merged so they touch the connected nodes at the same points. When this option is disabled, one port is created for each edge directly connected to a node. When it is enabled, all such incoming edges share an input port, and all outgoing edges share an output port.'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,LBe),''),'Merge Hierarchy-Crossing Edges'),'If hierarchical layout is active, hierarchy-crossing edges use as few hierarchical ports as possible. They are broken by the algorithm, with hierarchical ports inserted as required. Usually, one such port is created for each edge at each hierarchy crossing point. With this option set to true, we try to create as few hierarchical ports as possible in the process. In particular, all edges that form a hyperedge can share a port.'),true),cid),QI),xsb(Whd))));Egd(a,new Ahd(Nhd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,MBe),''),'Allow Non-Flow Ports To Switch Sides'),"Specifies whether non-flow ports may switch sides if their node's port constraints are either FIXED_SIDE or FIXED_ORDER. A non-flow port is a port on a side that is not part of the currently configured layout flow. For instance, given a left-to-right layout direction, north and south ports would be considered non-flow ports. Further note that the underlying criterium whether to switch sides or not solely relies on the minimization of edge crossings. Hence, edge length and other aesthetics criteria are not addressed."),false),cid),QI),xsb(Xhd)),cD(WC(qJ,1),Nve,2,6,['org.eclipse.elk.layered.northOrSouthPort']))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,NBe),''),'Port Sorting Strategy'),"Only relevant for nodes with FIXED_SIDE port constraints. Determines the way a node's ports are distributed on the sides of a node if their order is not prescribed. The option is set on parent nodes."),azc),eid),xX),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,OBe),''),'Thoroughness'),'How much effort should be spent to produce a nice layout.'),sgb(7)),gid),bJ),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,PBe),''),'Add Unnecessary Bendpoints'),'Adds bend points even if an edge does not change direction. If true, each long edge dummy will contribute a bend point to its edges and hierarchy-crossing edges will always get a bend point where they cross hierarchy boundaries. By default, bend points are only added where an edge changes direction.'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,QBe),''),'Generate Position and Layer IDs'),'If enabled position id and layer id are generated, which are usually only used internally when setting the interactiveLayout option. This option should be specified on the root node.'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,RBe),'cycleBreaking'),'Cycle Breaking Strategy'),'Strategy for cycle breaking. Cycle breaking looks for cycles in the graph and determines which edges to reverse to break the cycles. Reversed edges will end up pointing to the opposite direction of regular edges (that is, reversed edges will point left if edges usually point right).'),Sxc),eid),bX),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,SBe),bDe),'Node Layering Strategy'),'Strategy for node layering.'),Gyc),eid),rX),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,TBe),bDe),'Layer Constraint'),'Determines a constraint on the placement of the node regarding the layering.'),wyc),eid),mX),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,UBe),bDe),'Layer Choice Constraint'),"Allows to set a constraint regarding the layer placement of a node. Let i be the value of teh constraint. Assumed the drawing has n layers and i < n. If set to i, it expresses that the node should be placed in i-th layer. Should i>=n be true then the node is placed in the last layer of the drawing. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),null),gid),bJ),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,VBe),bDe),'Layer ID'),'Layer identifier that was calculated by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set.'),sgb(-1)),gid),bJ),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,WBe),cDe),'Upper Bound On Width [MinWidth Layerer]'),"Defines a loose upper bound on the width of the MinWidth layerer. If set to '-1' multiple values are tested and the best result is selected."),sgb(4)),gid),bJ),xsb(Whd))));zgd(a,WBe,SBe,zyc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,XBe),cDe),'Upper Layer Estimation Scaling Factor [MinWidth Layerer]'),"Multiplied with Upper Bound On Width for defining an upper bound on the width of layers which haven't been determined yet, but whose maximum width had been (roughly) estimated by the MinWidth algorithm. Compensates for too high estimations. If set to '-1' multiple values are tested and the best result is selected."),sgb(2)),gid),bJ),xsb(Whd))));zgd(a,XBe,SBe,Byc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,YBe),dDe),'Node Promotion Strategy'),'Reduces number of dummy nodes after layering phase (if possible).'),Eyc),eid),vX),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,ZBe),dDe),'Max Node Promotion Iterations'),'Limits the number of iterations for node promotion.'),sgb(0)),gid),bJ),xsb(Whd))));zgd(a,ZBe,YBe,null);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,$Be),'layering.coffmanGraham'),'Layer Bound'),'The maximum number of nodes allowed per layer.'),sgb(lve)),gid),bJ),xsb(Whd))));zgd(a,$Be,SBe,tyc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,_Be),eDe),'Crossing Minimization Strategy'),'Strategy for crossing minimization.'),Qxc),eid),_W),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,aCe),eDe),'Force Node Model Order'),'The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES.'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,bCe),eDe),'Hierarchical Sweepiness'),'How likely it is to use cross-hierarchy (1) vs bottom-up (-1).'),0.1),did),VI),xsb(Whd))));zgd(a,bCe,fDe,Ixc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,cCe),eDe),'Semi-Interactive Crossing Minimization'),"Preserves the order of nodes within a layer but still minimizes crossings between edges connecting long edge dummies. Derives the desired order from positions specified by the 'org.eclipse.elk.position' layout option. Requires a crossing minimization strategy that is able to process 'in-layer' constraints."),false),cid),QI),xsb(Whd))));zgd(a,cCe,_Be,Oxc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,dCe),eDe),'In Layer Predecessor of'),"Allows to set a constraint which specifies of which node the current node is the predecessor. If set to 's' then the node is the predecessor of 's' and is in the same layer"),null),iid),qJ),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,eCe),eDe),'In Layer Successor of'),"Allows to set a constraint which specifies of which node the current node is the successor. If set to 's' then the node is the successor of 's' and is in the same layer"),null),iid),qJ),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,fCe),eDe),'Position Choice Constraint'),"Allows to set a constraint regarding the position placement of a node in a layer. Assumed the layer in which the node placed includes n other nodes and i < n. If set to i, it expresses that the node should be placed at the i-th position. Should i>=n be true then the node is placed at the last position in the layer. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),null),gid),bJ),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,gCe),eDe),'Position ID'),'Position within a layer that was determined by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set.'),sgb(-1)),gid),bJ),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,hCe),gDe),'Greedy Switch Activation Threshold'),"By default it is decided automatically if the greedy switch is activated or not. The decision is based on whether the size of the input graph (without dummy nodes) is smaller than the value of this option. A '0' enforces the activation."),sgb(40)),gid),bJ),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,iCe),gDe),'Greedy Switch Crossing Minimization'),"Greedy Switch strategy for crossing minimization. The greedy switch heuristic is executed after the regular crossing minimization as a post-processor. Note that if 'hierarchyHandling' is set to 'INCLUDE_CHILDREN', the 'greedySwitchHierarchical.type' option must be used."),Fxc),eid),jX),xsb(Whd))));zgd(a,iCe,_Be,Gxc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,jCe),'crossingMinimization.greedySwitchHierarchical'),'Greedy Switch Crossing Minimization (hierarchical)'),"Activates the greedy switch heuristic in case hierarchical layout is used. The differences to the non-hierarchical case (see 'greedySwitch.type') are: 1) greedy switch is inactive by default, 3) only the option value set on the node at which hierarchical layout starts is relevant, and 2) if it's activated by the user, it properly addresses hierarchy-crossing edges."),Bxc),eid),jX),xsb(Whd))));zgd(a,jCe,_Be,Cxc);zgd(a,jCe,fDe,Dxc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,kCe),hDe),'Node Placement Strategy'),'Strategy for node placement.'),$yc),eid),uX),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,lCe),hDe),'Favor Straight Edges Over Balancing'),"Favor straight edges over a balanced node placement. The default behavior is determined automatically based on the used 'edgeRouting'. For an orthogonal style it is set to true, for all other styles to false."),cid),QI),xsb(Whd))));zgd(a,lCe,kCe,Qyc);zgd(a,lCe,kCe,Ryc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,mCe),iDe),'BK Edge Straightening'),"Specifies whether the Brandes Koepf node placer tries to increase the number of straight edges at the expense of diagram size. There is a subtle difference to the 'favorStraightEdges' option, which decides whether a balanced placement of the nodes is desired, or not. In bk terms this means combining the four alignments into a single balanced one, or not. This option on the other hand tries to straighten additional edges during the creation of each of the four alignments."),Kyc),eid),fX),xsb(Whd))));zgd(a,mCe,kCe,Lyc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,nCe),iDe),'BK Fixed Alignment'),'Tells the BK node placer to use a certain alignment (out of its four) instead of the one producing the smallest height, or the combination of all four.'),Nyc),eid),gX),xsb(Whd))));zgd(a,nCe,kCe,Oyc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,oCe),'nodePlacement.linearSegments'),'Linear Segments Deflection Dampening'),'Dampens the movement of nodes to keep the diagram from getting too large.'),0.3),did),VI),xsb(Whd))));zgd(a,oCe,kCe,Tyc);Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,pCe),'nodePlacement.networkSimplex'),'Node Flexibility'),"Aims at shorter and straighter edges. Two configurations are possible: (a) allow ports to move freely on the side they are assigned to (the order is always defined beforehand), (b) additionally allow to enlarge a node wherever it helps. If this option is not configured for a node, the 'nodeFlexibility.default' value is used, which is specified for the node's parent."),eid),tX),xsb(Vhd))));zgd(a,pCe,kCe,Yyc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,qCe),'nodePlacement.networkSimplex.nodeFlexibility'),'Node Flexibility Default'),"Default value of the 'nodeFlexibility' option for the children of a hierarchical node."),Wyc),eid),tX),xsb(Whd))));zgd(a,qCe,kCe,Xyc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,rCe),jDe),'Self-Loop Distribution'),'Alter the distribution of the loops around the node. It only takes effect for PortConstraints.FREE.'),ayc),eid),zX),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,sCe),jDe),'Self-Loop Ordering'),'Alter the ordering of the loops they can either be stacked or sequenced. It only takes effect for PortConstraints.FREE.'),cyc),eid),AX),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,tCe),'edgeRouting.splines'),'Spline Routing Mode'),'Specifies the way control points are assembled for each individual edge. CONSERVATIVE ensures that edges are properly routed around the nodes but feels rather orthogonal at times. SLOPPY uses fewer control points to obtain curvier edge routes but may result in edges overlapping nodes.'),eyc),eid),CX),xsb(Whd))));zgd(a,tCe,kDe,fyc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,uCe),'edgeRouting.splines.sloppy'),'Sloppy Spline Layer Spacing Factor'),'Spacing factor for routing area between layers when using sloppy spline routing.'),0.2),did),VI),xsb(Whd))));zgd(a,uCe,kDe,hyc);zgd(a,uCe,tCe,iyc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,vCe),'edgeRouting.polyline'),'Sloped Edge Zone Width'),'Width of the strip to the left and to the right of each layer where the polyline edge router is allowed to refrain from ensuring that edges are routed horizontally. This prevents awkward bend points for nodes that extent almost to the edge of their layer.'),2),did),VI),xsb(Whd))));zgd(a,vCe,kDe,$xc);Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,wCe),lDe),'Spacing Base Value'),"An optional base value for all other layout options of the 'spacing' group. It can be used to conveniently alter the overall 'spaciousness' of the drawing. Whenever an explicit value is set for the other layout options, this base value will have no effect. The base value is not inherited, i.e. it must be set for each hierarchical node."),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,xCe),lDe),'Edge Node Between Layers Spacing'),"The spacing to be preserved between nodes and edges that are routed next to the node's layer. For the spacing between nodes and edges that cross the node's layer 'spacing.edgeNode' is used."),10),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,yCe),lDe),'Edge Edge Between Layer Spacing'),"Spacing to be preserved between pairs of edges that are routed between the same pair of layers. Note that 'spacing.edgeEdge' is used for the spacing between pairs of edges crossing the same layer."),10),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,zCe),lDe),'Node Node Between Layers Spacing'),"The spacing to be preserved between any pair of nodes of two adjacent layers. Note that 'spacing.nodeNode' is used for the spacing between nodes within the layer itself."),20),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,ACe),mDe),'Direction Priority'),'Defines how important it is to have a certain edge point into the direction of the overall layout. This option is evaluated during the cycle breaking phase.'),sgb(0)),gid),bJ),xsb(Thd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,BCe),mDe),'Shortness Priority'),'Defines how important it is to keep an edge as short as possible. This option is evaluated during the layering phase.'),sgb(0)),gid),bJ),xsb(Thd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,CCe),mDe),'Straightness Priority'),'Defines how important it is to keep an edge straight, i.e. aligned with one of the two axes. This option is evaluated during node placement.'),sgb(0)),gid),bJ),xsb(Thd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,DCe),nDe),qze),'Tries to further compact components (disconnected sub-graphs).'),false),cid),QI),xsb(Whd))));zgd(a,DCe,cAe,true);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,ECe),oDe),'Post Compaction Strategy'),pDe),nxc),eid),hX),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,FCe),oDe),'Post Compaction Constraint Calculation'),pDe),lxc),eid),$W),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,GCe),qDe),'High Degree Node Treatment'),'Makes room around high degree nodes to place leafs and trees.'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,HCe),qDe),'High Degree Node Threshold'),'Whether a node is considered to have a high degree.'),sgb(16)),gid),bJ),xsb(Whd))));zgd(a,HCe,GCe,true);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,ICe),qDe),'High Degree Node Maximum Tree Height'),'Maximum height of a subtree connected to a high degree node to be moved to separate layers.'),sgb(5)),gid),bJ),xsb(Whd))));zgd(a,ICe,GCe,true);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,JCe),rDe),'Graph Wrapping Strategy'),"For certain graphs and certain prescribed drawing areas it may be desirable to split the laid out graph into chunks that are placed side by side. The edges that connect different chunks are 'wrapped' around from the end of one chunk to the start of the other chunk. The points between the chunks are referred to as 'cuts'."),Gzc),eid),EX),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,KCe),rDe),'Additional Wrapped Edges Spacing'),'To visually separate edges that are wrapped from regularly routed edges an additional spacing value can be specified in form of this layout option. The spacing is added to the regular edgeNode spacing.'),10),did),VI),xsb(Whd))));zgd(a,KCe,JCe,lzc);zgd(a,KCe,JCe,mzc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,LCe),rDe),'Correction Factor for Wrapping'),"At times and for certain types of graphs the executed wrapping may produce results that are consistently biased in the same fashion: either wrapping to often or to rarely. This factor can be used to correct the bias. Internally, it is simply multiplied with the 'aspect ratio' layout option."),1),did),VI),xsb(Whd))));zgd(a,LCe,JCe,ozc);zgd(a,LCe,JCe,pzc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,MCe),sDe),'Cutting Strategy'),'The strategy by which the layer indexes are determined at which the layering crumbles into chunks.'),wzc),eid),aX),xsb(Whd))));zgd(a,MCe,JCe,xzc);zgd(a,MCe,JCe,yzc);Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,NCe),sDe),'Manually Specified Cuts'),'Allows the user to specify her own cuts for a certain graph.'),hid),QK),xsb(Whd))));zgd(a,NCe,MCe,rzc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,OCe),'wrapping.cutting.msd'),'MSD Freedom'),'The MSD cutting strategy starts with an initial guess on the number of chunks the graph should be split into. The freedom specifies how much the strategy may deviate from this guess. E.g. if an initial number of 3 is computed, a freedom of 1 allows 2, 3, and 4 cuts.'),tzc),gid),bJ),xsb(Whd))));zgd(a,OCe,MCe,uzc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,PCe),tDe),'Validification Strategy'),'When wrapping graphs, one can specify indices that are not allowed as split points. The validification strategy makes sure every computed split point is allowed.'),Lzc),eid),DX),xsb(Whd))));zgd(a,PCe,JCe,Mzc);zgd(a,PCe,JCe,Nzc);Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,QCe),tDe),'Valid Indices for Wrapping'),null),hid),QK),xsb(Whd))));zgd(a,QCe,JCe,Izc);zgd(a,QCe,JCe,Jzc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,RCe),uDe),'Improve Cuts'),'For general graphs it is important that not too many edges wrap backwards. Thus a compromise between evenly-distributed cuts and the total number of cut edges is sought.'),true),cid),QI),xsb(Whd))));zgd(a,RCe,JCe,Czc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,SCe),uDe),'Distance Penalty When Improving Cuts'),null),2),did),VI),xsb(Whd))));zgd(a,SCe,JCe,Azc);zgd(a,SCe,RCe,true);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,TCe),uDe),'Improve Wrapped Edges'),'The initial wrapping is performed in a very simple way. As a consequence, edges that wrap from one chunk to another may be unnecessarily long. Activating this option tries to shorten such edges.'),true),cid),QI),xsb(Whd))));zgd(a,TCe,JCe,Ezc);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,UCe),vDe),'Edge Label Side Selection'),'Method to decide on edge label sides.'),Yxc),eid),eX),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,VCe),vDe),'Edge Center Label Placement Strategy'),'Determines in which layer center labels of long edges should be placed.'),Wxc),eid),ZW),ysb(Whd,cD(WC(d3,1),jwe,170,0,[Uhd])))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,WCe),wDe),'Consider Model Order'),'Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting.'),xxc),eid),wX),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,XCe),wDe),'Consider Port Order'),'If disabled the port order of output ports is derived from the edge order and input ports are ordered by their incoming connections. If enabled all ports are ordered by the port model order.'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,YCe),wDe),'No Model Order'),'Set on a node to not set a model order for this node even though it is a real node.'),false),cid),QI),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,ZCe),wDe),'Consider Model Order for Components'),'If set to NONE the usual ordering strategy (by cumulative node priority and size of nodes) is used. INSIDE_PORT_SIDES orders the components with external ports only inside the groups with the same port side. FORCE_MODEL_ORDER enforces the mode order on components. This option might produce bad alignments and sub optimal drawings in terms of used area since the ordering should be respected.'),pxc),eid),CQ),xsb(Whd))));zgd(a,ZCe,cAe,null);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,$Ce),wDe),'Long Edge Ordering Strategy'),'Indicates whether long edges are sorted under, over, or equal to nodes that have no connection to a previous layer in a left-to-right or right-to-left layout. Under and over changes to right and left in a vertical layout.'),txc),eid),sX),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,_Ce),wDe),'Crossing Counter Node Order Influence'),'Indicates with what percentage (1 for 100%) violations of the node model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal node order. Defaults to no influence (0).'),0),did),VI),xsb(Whd))));zgd(a,_Ce,WCe,null);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,aDe),wDe),'Crossing Counter Port Order Influence'),'Indicates with what percentage (1 for 100%) violations of the port model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal port order. Defaults to no influence (0).'),0),did),VI),xsb(Whd))));zgd(a,aDe,WCe,null);zCc((new ACc,a))};var ixc,jxc,kxc,lxc,mxc,nxc,oxc,pxc,qxc,rxc,sxc,txc,uxc,vxc,wxc,xxc,yxc,zxc,Axc,Bxc,Cxc,Dxc,Exc,Fxc,Gxc,Hxc,Ixc,Jxc,Kxc,Lxc,Mxc,Nxc,Oxc,Pxc,Qxc,Rxc,Sxc,Txc,Uxc,Vxc,Wxc,Xxc,Yxc,Zxc,$xc,_xc,ayc,byc,cyc,dyc,eyc,fyc,gyc,hyc,iyc,jyc,kyc,lyc,myc,nyc,oyc,pyc,qyc,ryc,syc,tyc,uyc,vyc,wyc,xyc,yyc,zyc,Ayc,Byc,Cyc,Dyc,Eyc,Fyc,Gyc,Hyc,Iyc,Jyc,Kyc,Lyc,Myc,Nyc,Oyc,Pyc,Qyc,Ryc,Syc,Tyc,Uyc,Vyc,Wyc,Xyc,Yyc,Zyc,$yc,_yc,azc,bzc,czc,dzc,ezc,fzc,gzc,hzc,izc,jzc,kzc,lzc,mzc,nzc,ozc,pzc,qzc,rzc,szc,tzc,uzc,vzc,wzc,xzc,yzc,zzc,Azc,Bzc,Czc,Dzc,Ezc,Fzc,Gzc,Hzc,Izc,Jzc,Kzc,Lzc,Mzc,Nzc;var nX=sfb(ABe,'LayeredMetaDataProvider',859);feb(998,1,Eye,ACc);_.hf=function BCc(a){zCc(a)};var Rzc,Szc,Tzc,Uzc,Vzc,Wzc,Xzc,Yzc,Zzc,$zc,_zc,aAc,bAc,cAc,dAc,eAc,fAc,gAc,hAc,iAc,jAc,kAc,lAc,mAc,nAc,oAc,pAc,qAc,rAc,sAc,tAc,uAc,vAc,wAc,xAc,yAc,zAc,AAc,BAc,CAc,DAc,EAc,FAc,GAc,HAc,IAc,JAc,KAc,LAc,MAc,NAc,OAc,PAc,QAc,RAc,SAc,TAc,UAc,VAc,WAc,XAc,YAc,ZAc,$Ac,_Ac,aBc,bBc,cBc,dBc,eBc,fBc,gBc,hBc,iBc,jBc,kBc,lBc,mBc,nBc,oBc,pBc,qBc,rBc,sBc,tBc,uBc,vBc,wBc,xBc,yBc,zBc,ABc,BBc,CBc,DBc,EBc,FBc,GBc,HBc,IBc,JBc,KBc,LBc,MBc,NBc,OBc,PBc,QBc,RBc,SBc,TBc,UBc,VBc,WBc,XBc,YBc,ZBc,$Bc,_Bc,aCc,bCc,cCc,dCc,eCc,fCc,gCc,hCc,iCc,jCc,kCc,lCc,mCc,nCc,oCc,pCc,qCc,rCc,sCc,tCc,uCc,vCc,wCc,xCc;var pX=sfb(ABe,'LayeredOptions',998);feb(999,1,{},CCc);_.sf=function DCc(){var a;return a=new lXb,a};_.tf=function ECc(a){};var oX=sfb(ABe,'LayeredOptions/LayeredFactory',999);feb(1391,1,{});_.a=0;var FCc;var b4=sfb(jEe,'ElkSpacings/AbstractSpacingsBuilder',1391);feb(792,1391,{},RCc);var OCc,PCc;var qX=sfb(ABe,'LayeredSpacings/LayeredSpacingsBuilder',792);feb(265,22,{3:1,34:1,22:1,265:1,188:1,196:1},bDc);_.dg=function dDc(){return aDc(this)};_.qg=function cDc(){return aDc(this)};var SCc,TCc,UCc,VCc,WCc,XCc,YCc,ZCc,$Cc;var rX=tfb(ABe,'LayeringStrategy',265,WI,fDc,eDc);var gDc;feb(390,22,{3:1,34:1,22:1,390:1},nDc);var iDc,jDc,kDc;var sX=tfb(ABe,'LongEdgeOrderingStrategy',390,WI,pDc,oDc);var qDc;feb(203,22,{3:1,34:1,22:1,203:1},yDc);var sDc,tDc,uDc,vDc;var tX=tfb(ABe,'NodeFlexibility',203,WI,BDc,ADc);var CDc;feb(323,22,{3:1,34:1,22:1,323:1,188:1,196:1},LDc);_.dg=function NDc(){return KDc(this)};_.qg=function MDc(){return KDc(this)};var EDc,FDc,GDc,HDc,IDc;var uX=tfb(ABe,'NodePlacementStrategy',323,WI,PDc,ODc);var QDc;feb(243,22,{3:1,34:1,22:1,243:1},bEc);var SDc,TDc,UDc,VDc,WDc,XDc,YDc,ZDc,$Dc,_Dc;var vX=tfb(ABe,'NodePromotionStrategy',243,WI,dEc,cEc);var eEc;feb(284,22,{3:1,34:1,22:1,284:1},lEc);var gEc,hEc,iEc,jEc;var wX=tfb(ABe,'OrderingStrategy',284,WI,nEc,mEc);var oEc;feb(430,22,{3:1,34:1,22:1,430:1},tEc);var qEc,rEc;var xX=tfb(ABe,'PortSortingStrategy',430,WI,vEc,uEc);var wEc;feb(463,22,{3:1,34:1,22:1,463:1},CEc);var yEc,zEc,AEc;var yX=tfb(ABe,'PortType',463,WI,EEc,DEc);var FEc;feb(387,22,{3:1,34:1,22:1,387:1},LEc);var HEc,IEc,JEc;var zX=tfb(ABe,'SelfLoopDistributionStrategy',387,WI,NEc,MEc);var OEc;feb(349,22,{3:1,34:1,22:1,349:1},UEc);var QEc,REc,SEc;var AX=tfb(ABe,'SelfLoopOrderingStrategy',349,WI,WEc,VEc);var XEc;feb(312,1,{312:1},gFc);var BX=sfb(ABe,'Spacings',312);feb(350,22,{3:1,34:1,22:1,350:1},mFc);var iFc,jFc,kFc;var CX=tfb(ABe,'SplineRoutingMode',350,WI,oFc,nFc);var pFc;feb(352,22,{3:1,34:1,22:1,352:1},vFc);var rFc,sFc,tFc;var DX=tfb(ABe,'ValidifyStrategy',352,WI,xFc,wFc);var yFc;feb(388,22,{3:1,34:1,22:1,388:1},EFc);var AFc,BFc,CFc;var EX=tfb(ABe,'WrappingStrategy',388,WI,GFc,FFc);var HFc;feb(1398,1,nEe,NFc);_.rg=function OFc(a){return RD(a,36),JFc};_.Kf=function PFc(a,b){MFc(this,RD(a,36),b)};var JFc;var FX=sfb(oEe,'DepthFirstCycleBreaker',1398);feb(793,1,nEe,UFc);_.rg=function WFc(a){return RD(a,36),QFc};_.Kf=function XFc(a,b){SFc(this,RD(a,36),b)};_.sg=function VFc(a){return RD(Vmb(a,Jwb(this.d,a.c.length)),10)};var QFc;var GX=sfb(oEe,'GreedyCycleBreaker',793);feb(1401,793,nEe,YFc);_.sg=function ZFc(a){var b,c,d,e;e=null;b=lve;for(d=new Anb(a);d.a1){Heb(TD(mQb(Y2b((tFb(0,a.c.length),RD(a.c[0],10))),(yCc(),eAc))))?wLc(a,this.d,RD(this,669)):(yob(),_mb(a,this.d));nJc(this.e,a)}};_.lg=function bJc(a,b,c,d){var e,f,g,h,i,j,k;if(b!=SIc(c,a.length)){f=a[b-(c?1:-1)];sIc(this.f,f,c?(BEc(),zEc):(BEc(),yEc))}e=a[b][0];k=!d||e.k==(r3b(),m3b);j=dv(a[b]);this.vg(j,k,false,c);g=0;for(i=new Anb(j);i.a');a0?(pMc(this.a,a[b-1],a[b]),undefined):!c&&b1){Heb(TD(mQb(Y2b((tFb(0,a.c.length),RD(a.c[0],10))),(yCc(),eAc))))?wLc(a,this.d,this):(yob(),_mb(a,this.d));Heb(TD(mQb(Y2b((tFb(0,a.c.length),RD(a.c[0],10))),eAc)))||nJc(this.e,a)}};var wY=sfb(sEe,'ModelOrderBarycenterHeuristic',669);feb(1866,1,fye,yLc);_.Ne=function zLc(a,b){return tLc(this.a,RD(a,10),RD(b,10))};_.Fb=function ALc(a){return this===a};_.Oe=function BLc(){return new Frb(this)};var vY=sfb(sEe,'ModelOrderBarycenterHeuristic/lambda$0$Type',1866);feb(1423,1,nEe,FLc);_.rg=function GLc(a){var b;return RD(a,36),b=vfd(CLc),pfd(b,(sXb(),pXb),(hcc(),Ybc)),b};_.Kf=function HLc(a,b){ELc((RD(a,36),b))};var CLc;var xY=sfb(sEe,'NoCrossingMinimizer',1423);feb(809,413,qEe,ILc);_.tg=function JLc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;l=this.g;switch(c.g){case 1:{e=0;f=0;for(k=new Anb(a.j);k.a1&&(e.j==(qpd(),Xod)?(this.b[a]=true):e.j==ppd&&a>0&&(this.b[a-1]=true))};_.f=0;var AY=sfb(tBe,'AllCrossingsCounter',1861);feb(595,1,{},_Lc);_.b=0;_.d=0;var BY=sfb(tBe,'BinaryIndexedTree',595);feb(532,1,{},DMc);var bMc,cMc;var LY=sfb(tBe,'CrossingsCounter',532);feb(1950,1,fye,HMc);_.Ne=function IMc(a,b){return wMc(this.a,RD(a,12),RD(b,12))};_.Fb=function JMc(a){return this===a};_.Oe=function KMc(){return new Frb(this)};var CY=sfb(tBe,'CrossingsCounter/lambda$0$Type',1950);feb(1951,1,fye,LMc);_.Ne=function MMc(a,b){return xMc(this.a,RD(a,12),RD(b,12))};_.Fb=function NMc(a){return this===a};_.Oe=function OMc(){return new Frb(this)};var DY=sfb(tBe,'CrossingsCounter/lambda$1$Type',1951);feb(1952,1,fye,PMc);_.Ne=function QMc(a,b){return yMc(this.a,RD(a,12),RD(b,12))};_.Fb=function RMc(a){return this===a};_.Oe=function SMc(){return new Frb(this)};var EY=sfb(tBe,'CrossingsCounter/lambda$2$Type',1952);feb(1953,1,fye,TMc);_.Ne=function UMc(a,b){return zMc(this.a,RD(a,12),RD(b,12))};_.Fb=function VMc(a){return this===a};_.Oe=function WMc(){return new Frb(this)};var FY=sfb(tBe,'CrossingsCounter/lambda$3$Type',1953);feb(1954,1,Qve,XMc);_.Cd=function YMc(a){EMc(this.a,RD(a,12))};var GY=sfb(tBe,'CrossingsCounter/lambda$4$Type',1954);feb(1955,1,nwe,ZMc);_.Mb=function $Mc(a){return FMc(this.a,RD(a,12))};var HY=sfb(tBe,'CrossingsCounter/lambda$5$Type',1955);feb(1956,1,Qve,aNc);_.Cd=function bNc(a){_Mc(this,a)};var IY=sfb(tBe,'CrossingsCounter/lambda$6$Type',1956);feb(1957,1,Qve,cNc);_.Cd=function dNc(a){var b;dMc();hmb(this.b,(b=this.a,RD(a,12),b))};var JY=sfb(tBe,'CrossingsCounter/lambda$7$Type',1957);feb(839,1,xye,eNc);_.Lb=function fNc(a){return dMc(),nQb(RD(a,12),(Ywc(),Iwc))};_.Fb=function gNc(a){return this===a};_.Mb=function hNc(a){return dMc(),nQb(RD(a,12),(Ywc(),Iwc))};var KY=sfb(tBe,'CrossingsCounter/lambda$8$Type',839);feb(1949,1,{},jNc);var PY=sfb(tBe,'HyperedgeCrossingsCounter',1949);feb(478,1,{34:1,478:1},lNc);_.Fd=function mNc(a){return kNc(this,RD(a,478))};_.b=0;_.c=0;_.e=0;_.f=0;var OY=sfb(tBe,'HyperedgeCrossingsCounter/Hyperedge',478);feb(374,1,{34:1,374:1},oNc);_.Fd=function pNc(a){return nNc(this,RD(a,374))};_.b=0;_.c=0;var NY=sfb(tBe,'HyperedgeCrossingsCounter/HyperedgeCorner',374);feb(531,22,{3:1,34:1,22:1,531:1},tNc);var qNc,rNc;var MY=tfb(tBe,'HyperedgeCrossingsCounter/HyperedgeCorner/Type',531,WI,vNc,uNc);var wNc;feb(1425,1,nEe,DNc);_.rg=function ENc(a){return RD(mQb(RD(a,36),(Ywc(),kwc)),21).Hc((ovc(),hvc))?zNc:null};_.Kf=function FNc(a,b){CNc(this,RD(a,36),b)};var zNc;var RY=sfb(tEe,'InteractiveNodePlacer',1425);feb(1426,1,nEe,TNc);_.rg=function UNc(a){return RD(mQb(RD(a,36),(Ywc(),kwc)),21).Hc((ovc(),hvc))?GNc:null};_.Kf=function VNc(a,b){RNc(this,RD(a,36),b)};var GNc,HNc,INc;var TY=sfb(tEe,'LinearSegmentsNodePlacer',1426);feb(261,1,{34:1,261:1},ZNc);_.Fd=function $Nc(a){return WNc(this,RD(a,261))};_.Fb=function _Nc(a){var b;if(ZD(a,261)){b=RD(a,261);return this.b==b.b}return false};_.Hb=function aOc(){return this.b};_.Ib=function bOc(){return 'ls'+Fe(this.e)};_.a=0;_.b=0;_.c=-1;_.d=-1;_.g=0;var SY=sfb(tEe,'LinearSegmentsNodePlacer/LinearSegment',261);feb(1428,1,nEe,yOc);_.rg=function zOc(a){return RD(mQb(RD(a,36),(Ywc(),kwc)),21).Hc((ovc(),hvc))?cOc:null};_.Kf=function HOc(a,b){uOc(this,RD(a,36),b)};_.b=0;_.g=0;var cOc;var DZ=sfb(tEe,'NetworkSimplexPlacer',1428);feb(1447,1,fye,IOc);_.Ne=function JOc(a,b){return hgb(RD(a,17).a,RD(b,17).a)};_.Fb=function KOc(a){return this===a};_.Oe=function LOc(){return new Frb(this)};var UY=sfb(tEe,'NetworkSimplexPlacer/0methodref$compare$Type',1447);feb(1449,1,fye,MOc);_.Ne=function NOc(a,b){return hgb(RD(a,17).a,RD(b,17).a)};_.Fb=function OOc(a){return this===a};_.Oe=function POc(){return new Frb(this)};var VY=sfb(tEe,'NetworkSimplexPlacer/1methodref$compare$Type',1449);feb(655,1,{655:1},QOc);var WY=sfb(tEe,'NetworkSimplexPlacer/EdgeRep',655);feb(412,1,{412:1},ROc);_.b=false;var XY=sfb(tEe,'NetworkSimplexPlacer/NodeRep',412);feb(515,13,{3:1,4:1,20:1,31:1,56:1,13:1,16:1,15:1,59:1,515:1},VOc);var aZ=sfb(tEe,'NetworkSimplexPlacer/Path',515);feb(1429,1,{},WOc);_.Kb=function XOc(a){return RD(a,18).d.i.k};var YY=sfb(tEe,'NetworkSimplexPlacer/Path/lambda$0$Type',1429);feb(1430,1,nwe,YOc);_.Mb=function ZOc(a){return RD(a,273)==(r3b(),o3b)};var ZY=sfb(tEe,'NetworkSimplexPlacer/Path/lambda$1$Type',1430);feb(1431,1,{},$Oc);_.Kb=function _Oc(a){return RD(a,18).d.i};var $Y=sfb(tEe,'NetworkSimplexPlacer/Path/lambda$2$Type',1431);feb(1432,1,nwe,aPc);_.Mb=function bPc(a){return EPc(zDc(RD(a,10)))};var _Y=sfb(tEe,'NetworkSimplexPlacer/Path/lambda$3$Type',1432);feb(1433,1,nwe,cPc);_.Mb=function dPc(a){return DOc(RD(a,12))};var bZ=sfb(tEe,'NetworkSimplexPlacer/lambda$0$Type',1433);feb(1434,1,Qve,ePc);_.Cd=function fPc(a){jOc(this.a,this.b,RD(a,12))};var cZ=sfb(tEe,'NetworkSimplexPlacer/lambda$1$Type',1434);feb(1443,1,Qve,gPc);_.Cd=function hPc(a){kOc(this.a,RD(a,18))};var dZ=sfb(tEe,'NetworkSimplexPlacer/lambda$10$Type',1443);feb(1444,1,{},iPc);_.Kb=function jPc(a){return dOc(),new SDb(null,new Swb(RD(a,30).a,16))};var eZ=sfb(tEe,'NetworkSimplexPlacer/lambda$11$Type',1444);feb(1445,1,Qve,kPc);_.Cd=function lPc(a){lOc(this.a,RD(a,10))};var fZ=sfb(tEe,'NetworkSimplexPlacer/lambda$12$Type',1445);feb(1446,1,{},mPc);_.Kb=function nPc(a){return dOc(),sgb(RD(a,125).e)};var gZ=sfb(tEe,'NetworkSimplexPlacer/lambda$13$Type',1446);feb(1448,1,{},oPc);_.Kb=function pPc(a){return dOc(),sgb(RD(a,125).e)};var hZ=sfb(tEe,'NetworkSimplexPlacer/lambda$15$Type',1448);feb(1450,1,nwe,qPc);_.Mb=function rPc(a){return dOc(),RD(a,412).c.k==(r3b(),p3b)};var iZ=sfb(tEe,'NetworkSimplexPlacer/lambda$17$Type',1450);feb(1451,1,nwe,sPc);_.Mb=function tPc(a){return dOc(),RD(a,412).c.j.c.length>1};var jZ=sfb(tEe,'NetworkSimplexPlacer/lambda$18$Type',1451);feb(1452,1,Qve,uPc);_.Cd=function vPc(a){EOc(this.c,this.b,this.d,this.a,RD(a,412))};_.c=0;_.d=0;var kZ=sfb(tEe,'NetworkSimplexPlacer/lambda$19$Type',1452);feb(1435,1,{},wPc);_.Kb=function xPc(a){return dOc(),new SDb(null,new Swb(RD(a,30).a,16))};var lZ=sfb(tEe,'NetworkSimplexPlacer/lambda$2$Type',1435);feb(1453,1,Qve,yPc);_.Cd=function zPc(a){FOc(this.a,RD(a,12))};_.a=0;var mZ=sfb(tEe,'NetworkSimplexPlacer/lambda$20$Type',1453);feb(1454,1,{},APc);_.Kb=function BPc(a){return dOc(),new SDb(null,new Swb(RD(a,30).a,16))};var nZ=sfb(tEe,'NetworkSimplexPlacer/lambda$21$Type',1454);feb(1455,1,Qve,CPc);_.Cd=function DPc(a){mOc(this.a,RD(a,10))};var oZ=sfb(tEe,'NetworkSimplexPlacer/lambda$22$Type',1455);feb(1456,1,nwe,FPc);_.Mb=function GPc(a){return EPc(a)};var pZ=sfb(tEe,'NetworkSimplexPlacer/lambda$23$Type',1456);feb(1457,1,{},HPc);_.Kb=function IPc(a){return dOc(),new SDb(null,new Swb(RD(a,30).a,16))};var qZ=sfb(tEe,'NetworkSimplexPlacer/lambda$24$Type',1457);feb(1458,1,nwe,JPc);_.Mb=function KPc(a){return nOc(this.a,RD(a,10))};var rZ=sfb(tEe,'NetworkSimplexPlacer/lambda$25$Type',1458);feb(1459,1,Qve,LPc);_.Cd=function MPc(a){oOc(this.a,this.b,RD(a,10))};var sZ=sfb(tEe,'NetworkSimplexPlacer/lambda$26$Type',1459);feb(1460,1,nwe,NPc);_.Mb=function OPc(a){return dOc(),!W0b(RD(a,18))};var tZ=sfb(tEe,'NetworkSimplexPlacer/lambda$27$Type',1460);feb(1461,1,nwe,PPc);_.Mb=function QPc(a){return dOc(),!W0b(RD(a,18))};var uZ=sfb(tEe,'NetworkSimplexPlacer/lambda$28$Type',1461);feb(1462,1,{},RPc);_.Ve=function SPc(a,b){return pOc(this.a,RD(a,30),RD(b,30))};var vZ=sfb(tEe,'NetworkSimplexPlacer/lambda$29$Type',1462);feb(1436,1,{},TPc);_.Kb=function UPc(a){return dOc(),new SDb(null,new Twb(new is(Mr(a3b(RD(a,10)).a.Kc(),new ir))))};var wZ=sfb(tEe,'NetworkSimplexPlacer/lambda$3$Type',1436);feb(1437,1,nwe,VPc);_.Mb=function WPc(a){return dOc(),COc(RD(a,18))};var xZ=sfb(tEe,'NetworkSimplexPlacer/lambda$4$Type',1437);feb(1438,1,Qve,XPc);_.Cd=function YPc(a){vOc(this.a,RD(a,18))};var yZ=sfb(tEe,'NetworkSimplexPlacer/lambda$5$Type',1438);feb(1439,1,{},ZPc);_.Kb=function $Pc(a){return dOc(),new SDb(null,new Swb(RD(a,30).a,16))};var zZ=sfb(tEe,'NetworkSimplexPlacer/lambda$6$Type',1439);feb(1440,1,nwe,_Pc);_.Mb=function aQc(a){return dOc(),RD(a,10).k==(r3b(),p3b)};var AZ=sfb(tEe,'NetworkSimplexPlacer/lambda$7$Type',1440);feb(1441,1,{},bQc);_.Kb=function cQc(a){return dOc(),new SDb(null,new Twb(new is(Mr(W2b(RD(a,10)).a.Kc(),new ir))))};var BZ=sfb(tEe,'NetworkSimplexPlacer/lambda$8$Type',1441);feb(1442,1,nwe,dQc);_.Mb=function eQc(a){return dOc(),V0b(RD(a,18))};var CZ=sfb(tEe,'NetworkSimplexPlacer/lambda$9$Type',1442);feb(1424,1,nEe,iQc);_.rg=function jQc(a){return RD(mQb(RD(a,36),(Ywc(),kwc)),21).Hc((ovc(),hvc))?fQc:null};_.Kf=function kQc(a,b){hQc(RD(a,36),b)};var fQc;var EZ=sfb(tEe,'SimpleNodePlacer',1424);feb(185,1,{185:1},sQc);_.Ib=function tQc(){var a;a='';this.c==(wQc(),vQc)?(a+=Oye):this.c==uQc&&(a+=Nye);this.o==(EQc(),CQc)?(a+=Zye):this.o==DQc?(a+='UP'):(a+='BALANCED');return a};var HZ=sfb(wEe,'BKAlignedLayout',185);feb(523,22,{3:1,34:1,22:1,523:1},xQc);var uQc,vQc;var FZ=tfb(wEe,'BKAlignedLayout/HDirection',523,WI,zQc,yQc);var AQc;feb(522,22,{3:1,34:1,22:1,522:1},FQc);var CQc,DQc;var GZ=tfb(wEe,'BKAlignedLayout/VDirection',522,WI,HQc,GQc);var IQc;feb(1699,1,{},MQc);var IZ=sfb(wEe,'BKAligner',1699);feb(1702,1,{},RQc);var LZ=sfb(wEe,'BKCompactor',1702);feb(663,1,{663:1},SQc);_.a=0;var JZ=sfb(wEe,'BKCompactor/ClassEdge',663);feb(467,1,{467:1},UQc);_.a=null;_.b=0;var KZ=sfb(wEe,'BKCompactor/ClassNode',467);feb(1427,1,nEe,aRc);_.rg=function eRc(a){return RD(mQb(RD(a,36),(Ywc(),kwc)),21).Hc((ovc(),hvc))?VQc:null};_.Kf=function fRc(a,b){_Qc(this,RD(a,36),b)};_.d=false;var VQc;var MZ=sfb(wEe,'BKNodePlacer',1427);feb(1700,1,{},hRc);_.d=0;var OZ=sfb(wEe,'NeighborhoodInformation',1700);feb(1701,1,fye,mRc);_.Ne=function nRc(a,b){return lRc(this,RD(a,42),RD(b,42))};_.Fb=function oRc(a){return this===a};_.Oe=function pRc(){return new Frb(this)};var NZ=sfb(wEe,'NeighborhoodInformation/NeighborComparator',1701);feb(823,1,{});var SZ=sfb(wEe,'ThresholdStrategy',823);feb(1825,823,{},uRc);_.wg=function vRc(a,b,c){return this.a.o==(EQc(),DQc)?oxe:pxe};_.xg=function wRc(){};var PZ=sfb(wEe,'ThresholdStrategy/NullThresholdStrategy',1825);feb(587,1,{587:1},xRc);_.c=false;_.d=false;var QZ=sfb(wEe,'ThresholdStrategy/Postprocessable',587);feb(1826,823,{},BRc);_.wg=function CRc(a,b,c){var d,e,f;e=b==c;d=this.a.a[c.p]==b;if(!(e||d)){return a}f=a;if(this.a.c==(wQc(),vQc)){e&&(f=yRc(this,b,true));!isNaN(f)&&!isFinite(f)&&d&&(f=yRc(this,c,false))}else{e&&(f=yRc(this,b,true));!isNaN(f)&&!isFinite(f)&&d&&(f=yRc(this,c,false))}return f};_.xg=function DRc(){var a,b,c,d,e;while(this.d.b!=0){e=RD(Tub(this.d),587);d=zRc(this,e);if(!d.a){continue}a=d.a;c=Heb(this.a.f[this.a.g[e.b.p].p]);if(!c&&!W0b(a)&&a.c.i.c==a.d.i.c){continue}b=ARc(this,e);b||Eyb(this.e,e)}while(this.e.a.c.length!=0){ARc(this,RD(Dyb(this.e),587))}};var RZ=sfb(wEe,'ThresholdStrategy/SimpleThresholdStrategy',1826);feb(645,1,{645:1,188:1,196:1},HRc);_.dg=function JRc(){return GRc(this)};_.qg=function IRc(){return GRc(this)};var ERc;var TZ=sfb(xEe,'EdgeRouterFactory',645);feb(1485,1,nEe,WRc);_.rg=function XRc(a){return URc(RD(a,36))};_.Kf=function YRc(a,b){VRc(RD(a,36),b)};var LRc,MRc,NRc,ORc,PRc,QRc,RRc,SRc;var UZ=sfb(xEe,'OrthogonalEdgeRouter',1485);feb(1478,1,nEe,lSc);_.rg=function mSc(a){return gSc(RD(a,36))};_.Kf=function nSc(a,b){iSc(this,RD(a,36),b)};var ZRc,$Rc,_Rc,aSc,bSc,cSc;var WZ=sfb(xEe,'PolylineEdgeRouter',1478);feb(1479,1,xye,pSc);_.Lb=function qSc(a){return oSc(RD(a,10))};_.Fb=function rSc(a){return this===a};_.Mb=function sSc(a){return oSc(RD(a,10))};var VZ=sfb(xEe,'PolylineEdgeRouter/1',1479);feb(1872,1,nwe,xSc);_.Mb=function ySc(a){return RD(a,132).c==(fTc(),dTc)};var XZ=sfb(yEe,'HyperEdgeCycleDetector/lambda$0$Type',1872);feb(1873,1,{},zSc);_.Ze=function ASc(a){return RD(a,132).d};var YZ=sfb(yEe,'HyperEdgeCycleDetector/lambda$1$Type',1873);feb(1874,1,nwe,BSc);_.Mb=function CSc(a){return RD(a,132).c==(fTc(),dTc)};var ZZ=sfb(yEe,'HyperEdgeCycleDetector/lambda$2$Type',1874);feb(1875,1,{},DSc);_.Ze=function ESc(a){return RD(a,132).d};var $Z=sfb(yEe,'HyperEdgeCycleDetector/lambda$3$Type',1875);feb(1876,1,{},FSc);_.Ze=function GSc(a){return RD(a,132).d};var _Z=sfb(yEe,'HyperEdgeCycleDetector/lambda$4$Type',1876);feb(1877,1,{},HSc);_.Ze=function ISc(a){return RD(a,132).d};var a$=sfb(yEe,'HyperEdgeCycleDetector/lambda$5$Type',1877);feb(118,1,{34:1,118:1},USc);_.Fd=function VSc(a){return KSc(this,RD(a,118))};_.Fb=function WSc(a){var b;if(ZD(a,118)){b=RD(a,118);return this.g==b.g}return false};_.Hb=function XSc(){return this.g};_.Ib=function ZSc(){var a,b,c,d;a=new dib('{');d=new Anb(this.n);while(d.a'+this.b+' ('+os(this.c)+')'};_.d=0;var c$=sfb(yEe,'HyperEdgeSegmentDependency',132);feb(528,22,{3:1,34:1,22:1,528:1},gTc);var dTc,eTc;var b$=tfb(yEe,'HyperEdgeSegmentDependency/DependencyType',528,WI,iTc,hTc);var jTc;feb(1878,1,{},xTc);var k$=sfb(yEe,'HyperEdgeSegmentSplitter',1878);feb(1879,1,{},ATc);_.a=0;_.b=0;var d$=sfb(yEe,'HyperEdgeSegmentSplitter/AreaRating',1879);feb(339,1,{339:1},BTc);_.a=0;_.b=0;_.c=0;var e$=sfb(yEe,'HyperEdgeSegmentSplitter/FreeArea',339);feb(1880,1,fye,CTc);_.Ne=function DTc(a,b){return zTc(RD(a,118),RD(b,118))};_.Fb=function ETc(a){return this===a};_.Oe=function FTc(){return new Frb(this)};var f$=sfb(yEe,'HyperEdgeSegmentSplitter/lambda$0$Type',1880);feb(1881,1,Qve,GTc);_.Cd=function HTc(a){rTc(this.a,this.d,this.c,this.b,RD(a,118))};_.b=0;var g$=sfb(yEe,'HyperEdgeSegmentSplitter/lambda$1$Type',1881);feb(1882,1,{},ITc);_.Kb=function JTc(a){return new SDb(null,new Swb(RD(a,118).e,16))};var h$=sfb(yEe,'HyperEdgeSegmentSplitter/lambda$2$Type',1882);feb(1883,1,{},KTc);_.Kb=function LTc(a){return new SDb(null,new Swb(RD(a,118).j,16))};var i$=sfb(yEe,'HyperEdgeSegmentSplitter/lambda$3$Type',1883);feb(1884,1,{},MTc);_.Ye=function NTc(a){return Kfb(UD(a))};var j$=sfb(yEe,'HyperEdgeSegmentSplitter/lambda$4$Type',1884);feb(664,1,{},TTc);_.a=0;_.b=0;_.c=0;var o$=sfb(yEe,'OrthogonalRoutingGenerator',664);feb(1703,1,{},XTc);_.Kb=function YTc(a){return new SDb(null,new Swb(RD(a,118).e,16))};var m$=sfb(yEe,'OrthogonalRoutingGenerator/lambda$0$Type',1703);feb(1704,1,{},ZTc);_.Kb=function $Tc(a){return new SDb(null,new Swb(RD(a,118).j,16))};var n$=sfb(yEe,'OrthogonalRoutingGenerator/lambda$1$Type',1704);feb(670,1,{});var p$=sfb(zEe,'BaseRoutingDirectionStrategy',670);feb(1870,670,{},cUc);_.yg=function dUc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p;if(!!a.r&&!a.q){return}k=b+a.o*c;for(j=new Anb(a.n);j.aVze){f=k;e=a;d=new rjd(l,f);Mub(g.a,d);_Tc(this,g,e,d,false);m=a.r;if(m){n=Kfb(UD(ju(m.e,0)));d=new rjd(n,f);Mub(g.a,d);_Tc(this,g,e,d,false);f=b+m.o*c;e=m;d=new rjd(n,f);Mub(g.a,d);_Tc(this,g,e,d,false)}d=new rjd(p,f);Mub(g.a,d);_Tc(this,g,e,d,false)}}}}};_.zg=function eUc(a){return a.i.n.a+a.n.a+a.a.a};_.Ag=function fUc(){return qpd(),npd};_.Bg=function gUc(){return qpd(),Yod};var q$=sfb(zEe,'NorthToSouthRoutingStrategy',1870);feb(1871,670,{},hUc);_.yg=function iUc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p;if(!!a.r&&!a.q){return}k=b-a.o*c;for(j=new Anb(a.n);j.aVze){f=k;e=a;d=new rjd(l,f);Mub(g.a,d);_Tc(this,g,e,d,false);m=a.r;if(m){n=Kfb(UD(ju(m.e,0)));d=new rjd(n,f);Mub(g.a,d);_Tc(this,g,e,d,false);f=b-m.o*c;e=m;d=new rjd(n,f);Mub(g.a,d);_Tc(this,g,e,d,false)}d=new rjd(p,f);Mub(g.a,d);_Tc(this,g,e,d,false)}}}}};_.zg=function jUc(a){return a.i.n.a+a.n.a+a.a.a};_.Ag=function kUc(){return qpd(),Yod};_.Bg=function lUc(){return qpd(),npd};var r$=sfb(zEe,'SouthToNorthRoutingStrategy',1871);feb(1869,670,{},mUc);_.yg=function nUc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p;if(!!a.r&&!a.q){return}k=b+a.o*c;for(j=new Anb(a.n);j.aVze){f=k;e=a;d=new rjd(f,l);Mub(g.a,d);_Tc(this,g,e,d,true);m=a.r;if(m){n=Kfb(UD(ju(m.e,0)));d=new rjd(f,n);Mub(g.a,d);_Tc(this,g,e,d,true);f=b+m.o*c;e=m;d=new rjd(f,n);Mub(g.a,d);_Tc(this,g,e,d,true)}d=new rjd(f,p);Mub(g.a,d);_Tc(this,g,e,d,true)}}}}};_.zg=function oUc(a){return a.i.n.b+a.n.b+a.a.b};_.Ag=function pUc(){return qpd(),Xod};_.Bg=function qUc(){return qpd(),ppd};var s$=sfb(zEe,'WestToEastRoutingStrategy',1869);feb(828,1,{},wUc);_.Ib=function xUc(){return Fe(this.a)};_.b=0;_.c=false;_.d=false;_.f=0;var u$=sfb(BEe,'NubSpline',828);feb(418,1,{418:1},AUc,BUc);var t$=sfb(BEe,'NubSpline/PolarCP',418);feb(1480,1,nEe,VUc);_.rg=function XUc(a){return QUc(RD(a,36))};_.Kf=function YUc(a,b){UUc(this,RD(a,36),b)};var CUc,DUc,EUc,FUc,GUc;var B$=sfb(BEe,'SplineEdgeRouter',1480);feb(274,1,{274:1},_Uc);_.Ib=function aVc(){return this.a+' ->('+this.c+') '+this.b};_.c=0;var v$=sfb(BEe,'SplineEdgeRouter/Dependency',274);feb(465,22,{3:1,34:1,22:1,465:1},eVc);var bVc,cVc;var w$=tfb(BEe,'SplineEdgeRouter/SideToProcess',465,WI,gVc,fVc);var hVc;feb(1481,1,nwe,jVc);_.Mb=function kVc(a){return HUc(),!RD(a,131).o};var x$=sfb(BEe,'SplineEdgeRouter/lambda$0$Type',1481);feb(1482,1,{},lVc);_.Ze=function mVc(a){return HUc(),RD(a,131).v+1};var y$=sfb(BEe,'SplineEdgeRouter/lambda$1$Type',1482);feb(1483,1,Qve,nVc);_.Cd=function oVc(a){SUc(this.a,this.b,RD(a,42))};var z$=sfb(BEe,'SplineEdgeRouter/lambda$2$Type',1483);feb(1484,1,Qve,pVc);_.Cd=function qVc(a){TUc(this.a,this.b,RD(a,42))};var A$=sfb(BEe,'SplineEdgeRouter/lambda$3$Type',1484);feb(131,1,{34:1,131:1},wVc,xVc);_.Fd=function yVc(a){return uVc(this,RD(a,131))};_.b=0;_.e=false;_.f=0;_.g=0;_.j=false;_.k=false;_.n=0;_.o=false;_.p=false;_.q=false;_.s=0;_.u=0;_.v=0;_.F=0;var D$=sfb(BEe,'SplineSegment',131);feb(468,1,{468:1},zVc);_.a=0;_.b=false;_.c=false;_.d=false;_.e=false;_.f=0;var C$=sfb(BEe,'SplineSegment/EdgeInformation',468);feb(1198,1,{},IVc);var F$=sfb(GEe,Lze,1198);feb(1199,1,fye,KVc);_.Ne=function LVc(a,b){return JVc(RD(a,121),RD(b,121))};_.Fb=function MVc(a){return this===a};_.Oe=function NVc(){return new Frb(this)};var E$=sfb(GEe,Mze,1199);feb(1197,1,{},TVc);var G$=sfb(GEe,'MrTree',1197);feb(405,22,{3:1,34:1,22:1,405:1,188:1,196:1},$Vc);_.dg=function aWc(){return ZVc(this)};_.qg=function _Vc(){return ZVc(this)};var UVc,VVc,WVc,XVc;var H$=tfb(GEe,'TreeLayoutPhases',405,WI,cWc,bWc);var dWc;feb(1112,205,oze,fWc);_.rf=function gWc(a,b){var c,d,e,f,g,h,i,j;Heb(TD(Gxd(a,(h_c(),S$c))))||RFb((c=new SFb((lud(),new zud(a))),c));g=b.eh(HEe);g.Ug('build tGraph',1);h=(i=new YWc,kQb(i,a),pQb(i,(q$c(),h$c),a),j=new Tsb,QVc(a,i,j),PVc(a,i,j),i);g.Vg();g=b.eh(HEe);g.Ug('Split graph',1);f=HVc(this.a,h);g.Vg();for(e=new Anb(f);e.a'+aXc(this.c):'e_'+tb(this)};var U$=sfb(JEe,'TEdge',65);feb(121,137,{3:1,121:1,96:1,137:1},YWc);_.Ib=function ZWc(){var a,b,c,d,e;e=null;for(d=Sub(this.b,0);d.b!=d.d.c;){c=RD(evb(d),40);e+=(c.c==null||c.c.length==0?'n_'+c.g:'n_'+c.c)+'\n'}for(b=Sub(this.a,0);b.b!=b.d.c;){a=RD(evb(b),65);e+=(!!a.b&&!!a.c?aXc(a.b)+'->'+aXc(a.c):'e_'+tb(a))+'\n'}return e};var W$=sfb(JEe,'TGraph',121);feb(643,508,{3:1,508:1,643:1,96:1,137:1});var $$=sfb(JEe,'TShape',643);feb(40,643,{3:1,508:1,40:1,643:1,96:1,137:1},bXc);_.Ib=function cXc(){return aXc(this)};var Z$=sfb(JEe,'TNode',40);feb(236,1,Vve,dXc);_.Jc=function eXc(a){xgb(this,a)};_.Kc=function fXc(){var a;return a=Sub(this.a.d,0),new gXc(a)};var Y$=sfb(JEe,'TNode/2',236);feb(329,1,Ave,gXc);_.Nb=function hXc(a){Ztb(this,a)};_.Pb=function jXc(){return RD(evb(this.a),65).c};_.Ob=function iXc(){return dvb(this.a)};_.Qb=function kXc(){gvb(this.a)};var X$=sfb(JEe,'TNode/2/1',329);feb(1923,1,QAe,qXc);_.Kf=function DXc(a,b){oXc(this,RD(a,121),b)};var m_=sfb(LEe,'CompactionProcessor',1923);feb(1924,1,fye,EXc);_.Ne=function FXc(a,b){return rXc(this.a,RD(a,40),RD(b,40))};_.Fb=function GXc(a){return this===a};_.Oe=function HXc(){return new Frb(this)};var _$=sfb(LEe,'CompactionProcessor/lambda$0$Type',1924);feb(1925,1,nwe,IXc);_.Mb=function JXc(a){return sXc(this.b,this.a,RD(a,42))};_.a=0;_.b=0;var a_=sfb(LEe,'CompactionProcessor/lambda$1$Type',1925);feb(1934,1,fye,KXc);_.Ne=function LXc(a,b){return tXc(RD(a,40),RD(b,40))};_.Fb=function MXc(a){return this===a};_.Oe=function NXc(){return new Frb(this)};var b_=sfb(LEe,'CompactionProcessor/lambda$10$Type',1934);feb(1935,1,fye,OXc);_.Ne=function PXc(a,b){return uXc(RD(a,40),RD(b,40))};_.Fb=function QXc(a){return this===a};_.Oe=function RXc(){return new Frb(this)};var c_=sfb(LEe,'CompactionProcessor/lambda$11$Type',1935);feb(1936,1,fye,SXc);_.Ne=function TXc(a,b){return vXc(RD(a,40),RD(b,40))};_.Fb=function UXc(a){return this===a};_.Oe=function VXc(){return new Frb(this)};var d_=sfb(LEe,'CompactionProcessor/lambda$12$Type',1936);feb(1926,1,nwe,WXc);_.Mb=function XXc(a){return wXc(this.a,RD(a,42))};_.a=0;var e_=sfb(LEe,'CompactionProcessor/lambda$2$Type',1926);feb(1927,1,nwe,YXc);_.Mb=function ZXc(a){return xXc(this.a,RD(a,42))};_.a=0;var f_=sfb(LEe,'CompactionProcessor/lambda$3$Type',1927);feb(1928,1,nwe,$Xc);_.Mb=function _Xc(a){return RD(a,40).c.indexOf(IEe)==-1};var g_=sfb(LEe,'CompactionProcessor/lambda$4$Type',1928);feb(1929,1,{},aYc);_.Kb=function bYc(a){return yXc(this.a,RD(a,40))};_.a=0;var h_=sfb(LEe,'CompactionProcessor/lambda$5$Type',1929);feb(1930,1,{},cYc);_.Kb=function dYc(a){return zXc(this.a,RD(a,40))};_.a=0;var i_=sfb(LEe,'CompactionProcessor/lambda$6$Type',1930);feb(1931,1,fye,eYc);_.Ne=function fYc(a,b){return AXc(this.a,RD(a,240),RD(b,240))};_.Fb=function gYc(a){return this===a};_.Oe=function hYc(){return new Frb(this)};var j_=sfb(LEe,'CompactionProcessor/lambda$7$Type',1931);feb(1932,1,fye,iYc);_.Ne=function jYc(a,b){return BXc(this.a,RD(a,40),RD(b,40))};_.Fb=function kYc(a){return this===a};_.Oe=function lYc(){return new Frb(this)};var k_=sfb(LEe,'CompactionProcessor/lambda$8$Type',1932);feb(1933,1,fye,mYc);_.Ne=function nYc(a,b){return CXc(RD(a,40),RD(b,40))};_.Fb=function oYc(a){return this===a};_.Oe=function pYc(){return new Frb(this)};var l_=sfb(LEe,'CompactionProcessor/lambda$9$Type',1933);feb(1921,1,QAe,rYc);_.Kf=function sYc(a,b){qYc(RD(a,121),b)};var n_=sfb(LEe,'DirectionProcessor',1921);feb(1913,1,QAe,vYc);_.Kf=function xYc(a,b){uYc(this,RD(a,121),b)};var o_=sfb(LEe,'FanProcessor',1913);feb(1937,1,QAe,zYc);_.Kf=function CYc(a,b){yYc(RD(a,121),b)};var t_=sfb(LEe,'GraphBoundsProcessor',1937);feb(1938,1,{},DYc);_.Ye=function EYc(a){return RD(a,40).e.a};var p_=sfb(LEe,'GraphBoundsProcessor/lambda$0$Type',1938);feb(1939,1,{},FYc);_.Ye=function GYc(a){return RD(a,40).e.b};var q_=sfb(LEe,'GraphBoundsProcessor/lambda$1$Type',1939);feb(1940,1,{},HYc);_.Ye=function IYc(a){return AYc(RD(a,40))};var r_=sfb(LEe,'GraphBoundsProcessor/lambda$2$Type',1940);feb(1941,1,{},JYc);_.Ye=function KYc(a){return BYc(RD(a,40))};var s_=sfb(LEe,'GraphBoundsProcessor/lambda$3$Type',1941);feb(262,22,{3:1,34:1,22:1,262:1,196:1},XYc);_.dg=function YYc(){switch(this.g){case 0:return new DZc;case 1:return new vYc;case 2:return new nZc;case 3:return new tZc;case 4:return new gZc;case 8:return new cZc;case 5:return new rYc;case 6:return new AZc;case 7:return new qXc;case 9:return new zYc;case 10:return new GZc;default:throw Adb(new agb(lBe+(this.f!=null?this.f:''+this.g)));}};var LYc,MYc,NYc,OYc,PYc,QYc,RYc,SYc,TYc,UYc,VYc;var u_=tfb(LEe,mBe,262,WI,$Yc,ZYc);var _Yc;feb(1920,1,QAe,cZc);_.Kf=function dZc(a,b){bZc(RD(a,121),b)};var v_=sfb(LEe,'LevelCoordinatesProcessor',1920);feb(1918,1,QAe,gZc);_.Kf=function hZc(a,b){eZc(this,RD(a,121),b)};_.a=0;var x_=sfb(LEe,'LevelHeightProcessor',1918);feb(1919,1,Vve,iZc);_.Jc=function jZc(a){xgb(this,a)};_.Kc=function kZc(){return yob(),Qob(),Pob};var w_=sfb(LEe,'LevelHeightProcessor/1',1919);feb(1914,1,QAe,nZc);_.Kf=function oZc(a,b){lZc(this,RD(a,121),b)};var z_=sfb(LEe,'LevelProcessor',1914);feb(1915,1,nwe,pZc);_.Mb=function qZc(a){return Heb(TD(mQb(RD(a,40),(q$c(),n$c))))};var y_=sfb(LEe,'LevelProcessor/lambda$0$Type',1915);feb(1916,1,QAe,tZc);_.Kf=function uZc(a,b){rZc(this,RD(a,121),b)};_.a=0;var B_=sfb(LEe,'NeighborsProcessor',1916);feb(1917,1,Vve,vZc);_.Jc=function wZc(a){xgb(this,a)};_.Kc=function xZc(){return yob(),Qob(),Pob};var A_=sfb(LEe,'NeighborsProcessor/1',1917);feb(1922,1,QAe,AZc);_.Kf=function BZc(a,b){yZc(this,RD(a,121),b)};_.a=0;var C_=sfb(LEe,'NodePositionProcessor',1922);feb(1912,1,QAe,DZc);_.Kf=function EZc(a,b){CZc(this,RD(a,121),b)};var D_=sfb(LEe,'RootProcessor',1912);feb(1942,1,QAe,GZc);_.Kf=function HZc(a,b){FZc(RD(a,121),b)};var E_=sfb(LEe,'Untreeifyer',1942);feb(392,22,{3:1,34:1,22:1,392:1},MZc);var IZc,JZc,KZc;var F_=tfb(PEe,'EdgeRoutingMode',392,WI,OZc,NZc);var PZc;var RZc,SZc,TZc,UZc,VZc,WZc,XZc,YZc,ZZc,$Zc,_Zc,a$c,b$c,c$c,d$c,e$c,f$c,g$c,h$c,i$c,j$c,k$c,l$c,m$c,n$c,o$c,p$c;feb(862,1,Eye,C$c);_.hf=function D$c(a){Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,REe),''),YEe),'Turns on Tree compaction which decreases the size of the whole tree by placing nodes of multiple levels in one large level'),(Geb(),false)),(kid(),cid)),QI),xsb((Yhd(),Whd)))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,SEe),''),'Edge End Texture Length'),'Should be set to the length of the texture at the end of an edge. This value can be used to improve the Edge Routing.'),7),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,TEe),''),'Tree Level'),'The index for the tree level the node is in'),sgb(0)),gid),bJ),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,UEe),''),YEe),'When set to a positive number this option will force the algorithm to place the node to the specified position within the trees layer if weighting is set to constraint'),sgb(-1)),gid),bJ),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,VEe),''),'Weighting of Nodes'),'Which weighting to use when computing a node order.'),A$c),eid),J_),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,WEe),''),'Edge Routing Mode'),'Chooses an Edge Routing algorithm.'),u$c),eid),F_),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,XEe),''),'Search Order'),'Which search order to use when computing a spanning tree.'),x$c),eid),K_),xsb(Whd))));i_c((new j_c,a))};var r$c,s$c,t$c,u$c,v$c,w$c,x$c,y$c,z$c,A$c;var G_=sfb(PEe,'MrTreeMetaDataProvider',862);feb(1006,1,Eye,j_c);_.hf=function k_c(a){i_c(a)};var E$c,F$c,G$c,H$c,I$c,J$c,K$c,L$c,M$c,N$c,O$c,P$c,Q$c,R$c,S$c,T$c,U$c,V$c,W$c,X$c,Y$c,Z$c,$$c,_$c,a_c,b_c,c_c,d_c,e_c,f_c,g_c;var I_=sfb(PEe,'MrTreeOptions',1006);feb(1007,1,{},l_c);_.sf=function m_c(){var a;return a=new fWc,a};_.tf=function n_c(a){};var H_=sfb(PEe,'MrTreeOptions/MrtreeFactory',1007);feb(353,22,{3:1,34:1,22:1,353:1},t_c);var o_c,p_c,q_c,r_c;var J_=tfb(PEe,'OrderWeighting',353,WI,v_c,u_c);var w_c;feb(433,22,{3:1,34:1,22:1,433:1},B_c);var y_c,z_c;var K_=tfb(PEe,'TreeifyingOrder',433,WI,D_c,C_c);var E_c;feb(1486,1,nEe,N_c);_.rg=function O_c(a){return RD(a,121),G_c};_.Kf=function P_c(a,b){M_c(this,RD(a,121),b)};var G_c;var L_=sfb('org.eclipse.elk.alg.mrtree.p1treeify','DFSTreeifyer',1486);feb(1487,1,nEe,V_c);_.rg=function W_c(a){return RD(a,121),Q_c};_.Kf=function $_c(a,b){U_c(this,RD(a,121),b)};var Q_c;var T_=sfb(aFe,'NodeOrderer',1487);feb(1494,1,{},a0c);_.td=function b0c(a){return __c(a)};var M_=sfb(aFe,'NodeOrderer/0methodref$lambda$6$Type',1494);feb(1488,1,nwe,c0c);_.Mb=function d0c(a){return R_c(),Heb(TD(mQb(RD(a,40),(q$c(),n$c))))};var N_=sfb(aFe,'NodeOrderer/lambda$0$Type',1488);feb(1489,1,nwe,e0c);_.Mb=function f0c(a){return R_c(),RD(mQb(RD(a,40),(h_c(),W$c)),17).a<0};var O_=sfb(aFe,'NodeOrderer/lambda$1$Type',1489);feb(1490,1,nwe,g0c);_.Mb=function h0c(a){return X_c(this.a,RD(a,40))};var P_=sfb(aFe,'NodeOrderer/lambda$2$Type',1490);feb(1491,1,nwe,i0c);_.Mb=function j0c(a){return Y_c(this.a,RD(a,40))};var Q_=sfb(aFe,'NodeOrderer/lambda$3$Type',1491);feb(1492,1,fye,k0c);_.Ne=function l0c(a,b){return Z_c(RD(a,40),RD(b,40))};_.Fb=function m0c(a){return this===a};_.Oe=function n0c(){return new Frb(this)};var R_=sfb(aFe,'NodeOrderer/lambda$4$Type',1492);feb(1493,1,nwe,o0c);_.Mb=function p0c(a){return R_c(),RD(mQb(RD(a,40),(q$c(),XZc)),17).a!=0};var S_=sfb(aFe,'NodeOrderer/lambda$5$Type',1493);feb(1495,1,nEe,x0c);_.rg=function y0c(a){return RD(a,121),q0c};_.Kf=function z0c(a,b){v0c(this,RD(a,121),b)};_.b=0;var q0c;var U_=sfb('org.eclipse.elk.alg.mrtree.p3place','NodePlacer',1495);feb(1496,1,nEe,J0c);_.rg=function K0c(a){return RD(a,121),A0c};_.Kf=function Y0c(a,b){I0c(RD(a,121),b)};var A0c;var o0=sfb(bFe,'EdgeRouter',1496);feb(1498,1,fye,Z0c);_.Ne=function $0c(a,b){return hgb(RD(a,17).a,RD(b,17).a)};_.Fb=function _0c(a){return this===a};_.Oe=function a1c(){return new Frb(this)};var V_=sfb(bFe,'EdgeRouter/0methodref$compare$Type',1498);feb(1503,1,{},b1c);_.Ye=function c1c(a){return Kfb(UD(a))};var W_=sfb(bFe,'EdgeRouter/1methodref$doubleValue$Type',1503);feb(1505,1,fye,d1c);_.Ne=function e1c(a,b){return Qfb(Kfb(UD(a)),Kfb(UD(b)))};_.Fb=function f1c(a){return this===a};_.Oe=function g1c(){return new Frb(this)};var X_=sfb(bFe,'EdgeRouter/2methodref$compare$Type',1505);feb(1507,1,fye,h1c);_.Ne=function i1c(a,b){return Qfb(Kfb(UD(a)),Kfb(UD(b)))};_.Fb=function j1c(a){return this===a};_.Oe=function k1c(){return new Frb(this)};var Y_=sfb(bFe,'EdgeRouter/3methodref$compare$Type',1507);feb(1509,1,{},l1c);_.Ye=function m1c(a){return Kfb(UD(a))};var Z_=sfb(bFe,'EdgeRouter/4methodref$doubleValue$Type',1509);feb(1511,1,fye,n1c);_.Ne=function o1c(a,b){return Qfb(Kfb(UD(a)),Kfb(UD(b)))};_.Fb=function p1c(a){return this===a};_.Oe=function q1c(){return new Frb(this)};var $_=sfb(bFe,'EdgeRouter/5methodref$compare$Type',1511);feb(1513,1,fye,r1c);_.Ne=function s1c(a,b){return Qfb(Kfb(UD(a)),Kfb(UD(b)))};_.Fb=function t1c(a){return this===a};_.Oe=function u1c(){return new Frb(this)};var __=sfb(bFe,'EdgeRouter/6methodref$compare$Type',1513);feb(1497,1,{},v1c);_.Kb=function w1c(a){return B0c(),RD(mQb(RD(a,40),(h_c(),f_c)),17)};var a0=sfb(bFe,'EdgeRouter/lambda$0$Type',1497);feb(1508,1,{},x1c);_.Kb=function y1c(a){return L0c(RD(a,40))};var b0=sfb(bFe,'EdgeRouter/lambda$11$Type',1508);feb(1510,1,{},z1c);_.Kb=function A1c(a){return M0c(this.b,this.a,RD(a,40))};_.a=0;_.b=0;var c0=sfb(bFe,'EdgeRouter/lambda$13$Type',1510);feb(1512,1,{},B1c);_.Kb=function C1c(a){return N0c(this.b,this.a,RD(a,40))};_.a=0;_.b=0;var d0=sfb(bFe,'EdgeRouter/lambda$15$Type',1512);feb(1514,1,fye,D1c);_.Ne=function E1c(a,b){return O0c(RD(a,65),RD(b,65))};_.Fb=function F1c(a){return this===a};_.Oe=function G1c(){return new Frb(this)};var e0=sfb(bFe,'EdgeRouter/lambda$17$Type',1514);feb(1515,1,fye,H1c);_.Ne=function I1c(a,b){return P0c(RD(a,65),RD(b,65))};_.Fb=function J1c(a){return this===a};_.Oe=function K1c(){return new Frb(this)};var f0=sfb(bFe,'EdgeRouter/lambda$18$Type',1515);feb(1516,1,fye,L1c);_.Ne=function M1c(a,b){return Q0c(RD(a,65),RD(b,65))};_.Fb=function N1c(a){return this===a};_.Oe=function O1c(){return new Frb(this)};var g0=sfb(bFe,'EdgeRouter/lambda$19$Type',1516);feb(1499,1,nwe,P1c);_.Mb=function Q1c(a){return R0c(this.a,RD(a,40))};_.a=0;var h0=sfb(bFe,'EdgeRouter/lambda$2$Type',1499);feb(1517,1,fye,R1c);_.Ne=function S1c(a,b){return S0c(RD(a,65),RD(b,65))};_.Fb=function T1c(a){return this===a};_.Oe=function U1c(){return new Frb(this)};var i0=sfb(bFe,'EdgeRouter/lambda$20$Type',1517);feb(1500,1,fye,V1c);_.Ne=function W1c(a,b){return T0c(RD(a,40),RD(b,40))};_.Fb=function X1c(a){return this===a};_.Oe=function Y1c(){return new Frb(this)};var j0=sfb(bFe,'EdgeRouter/lambda$3$Type',1500);feb(1501,1,fye,Z1c);_.Ne=function $1c(a,b){return U0c(RD(a,40),RD(b,40))};_.Fb=function _1c(a){return this===a};_.Oe=function a2c(){return new Frb(this)};var k0=sfb(bFe,'EdgeRouter/lambda$4$Type',1501);feb(1502,1,{},b2c);_.Kb=function c2c(a){return V0c(RD(a,40))};var l0=sfb(bFe,'EdgeRouter/lambda$5$Type',1502);feb(1504,1,{},d2c);_.Kb=function e2c(a){return W0c(this.b,this.a,RD(a,40))};_.a=0;_.b=0;var m0=sfb(bFe,'EdgeRouter/lambda$7$Type',1504);feb(1506,1,{},f2c);_.Kb=function g2c(a){return X0c(this.b,this.a,RD(a,40))};_.a=0;_.b=0;var n0=sfb(bFe,'EdgeRouter/lambda$9$Type',1506);feb(675,1,{675:1},i2c);_.e=0;_.f=false;_.g=false;var r0=sfb(bFe,'MultiLevelEdgeNodeNodeGap',675);feb(1943,1,fye,l2c);_.Ne=function m2c(a,b){return j2c(RD(a,240),RD(b,240))};_.Fb=function n2c(a){return this===a};_.Oe=function o2c(){return new Frb(this)};var p0=sfb(bFe,'MultiLevelEdgeNodeNodeGap/lambda$0$Type',1943);feb(1944,1,fye,p2c);_.Ne=function q2c(a,b){return k2c(RD(a,240),RD(b,240))};_.Fb=function r2c(a){return this===a};_.Oe=function s2c(){return new Frb(this)};var q0=sfb(bFe,'MultiLevelEdgeNodeNodeGap/lambda$1$Type',1944);var t2c;feb(501,22,{3:1,34:1,22:1,501:1,188:1,196:1},z2c);_.dg=function B2c(){return y2c(this)};_.qg=function A2c(){return y2c(this)};var v2c,w2c;var s0=tfb(cFe,'RadialLayoutPhases',501,WI,D2c,C2c);var E2c;feb(1113,205,oze,H2c);_.rf=function I2c(a,b){var c,d,e,f,g,h;c=G2c(this,a);b.Ug('Radial layout',c.c.length);Heb(TD(Gxd(a,($4c(),N4c))))||RFb((d=new SFb((lud(),new zud(a))),d));h=K2c(a);Ixd(a,(u2c(),t2c),h);if(!h){throw Adb(new agb('The given graph is not a tree!'))}e=Kfb(UD(Gxd(a,S4c)));e==0&&(e=J2c(a));Ixd(a,S4c,e);for(g=new Anb(G2c(this,a));g.a=3){v=RD(QHd(t,0),27);w=RD(QHd(t,1),27);f=0;while(f+2=v.f+w.f+k||w.f>=u.f+v.f+k){B=true;break}else{++f}}}else{B=true}if(!B){m=t.i;for(h=new dMd(t);h.e!=h.i.gc();){g=RD(bMd(h),27);Ixd(g,(umd(),Rld),sgb(m));--m}crd(a,new Oqd);b.Vg();return}c=(Sed(this.a),Ved(this.a,(f6c(),c6c),RD(Gxd(a,V7c),188)),Ved(this.a,d6c,RD(Gxd(a,M7c),188)),Ved(this.a,e6c,RD(Gxd(a,S7c),188)),Ped(this.a,(D=new ufd,pfd(D,c6c,(z6c(),y6c)),pfd(D,d6c,x6c),Heb(TD(Gxd(a,B7c)))&&pfd(D,c6c,w6c),D)),Qed(this.a,a));j=1/c.c.length;A=0;for(o=new Anb(c);o.a0&&vjd((BFb(c-1,b.length),b.charCodeAt(c-1)),ZAe)){--c}if(e>=c){throw Adb(new agb('The given string does not contain any numbers.'))}f=vhb((AFb(e,c,b.length),b.substr(e,c-e)),',|;|\r|\n');if(f.length!=2){throw Adb(new agb('Exactly two numbers are expected, '+f.length+' were found.'))}try{this.a=Neb(Dhb(f[0]));this.b=Neb(Dhb(f[1]))}catch(a){a=zdb(a);if(ZD(a,130)){d=a;throw Adb(new agb($Ae+d))}else throw Adb(a)}};_.Ib=function yjd(){return '('+this.a+','+this.b+')'};_.a=0;_.b=0;var l3=sfb(_Ae,'KVector',8);feb(75,67,{3:1,4:1,20:1,31:1,56:1,16:1,67:1,15:1,75:1,423:1},Ejd,Fjd,Gjd);_.Pc=function Jjd(){return Djd(this)};_.cg=function Hjd(b){var c,d,e,f,g,h;e=vhb(b,',|;|\\(|\\)|\\[|\\]|\\{|\\}| |\t|\n');Xub(this);try{d=0;g=0;f=0;h=0;while(d0){g%2==0?(f=Neb(e[d])):(h=Neb(e[d]));g>0&&g%2!=0&&Mub(this,new rjd(f,h));++g}++d}}catch(a){a=zdb(a);if(ZD(a,130)){c=a;throw Adb(new agb('The given string does not match the expected format for vectors.'+c))}else throw Adb(a)}};_.Ib=function Kjd(){var a,b,c;a=new dib('(');b=Sub(this,0);while(b.b!=b.d.c){c=RD(evb(b),8);Zhb(a,c.a+','+c.b);b.b!=b.d.c&&(a.a+='; ',a)}return (a.a+=')',a).a};var k3=sfb(_Ae,'KVectorChain',75);feb(255,22,{3:1,34:1,22:1,255:1},Sjd);var Ljd,Mjd,Njd,Ojd,Pjd,Qjd;var n3=tfb(JGe,'Alignment',255,WI,Ujd,Tjd);var Vjd;feb(991,1,Eye,jkd);_.hf=function kkd(a){ikd(a)};var Xjd,Yjd,Zjd,$jd,_jd,akd,bkd,ckd,dkd,ekd,fkd,gkd;var p3=sfb(JGe,'BoxLayouterOptions',991);feb(992,1,{},lkd);_.sf=function mkd(){var a;return a=new jrd,a};_.tf=function nkd(a){};var o3=sfb(JGe,'BoxLayouterOptions/BoxFactory',992);feb(298,22,{3:1,34:1,22:1,298:1},vkd);var okd,pkd,qkd,rkd,skd,tkd;var q3=tfb(JGe,'ContentAlignment',298,WI,xkd,wkd);var ykd;feb(699,1,Eye,vmd);_.hf=function wmd(a){Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,OGe),''),'Layout Algorithm'),'Select a specific layout algorithm.'),(kid(),iid)),qJ),xsb((Yhd(),Whd)))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,PGe),''),'Resolved Layout Algorithm'),'Meta data associated with the selected algorithm.'),hid),D2),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,MDe),''),'Alignment'),'Alignment of the selected node relative to other nodes; the exact meaning depends on the used algorithm.'),Ckd),eid),n3),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,Dze),''),'Aspect Ratio'),'The desired aspect ratio of the drawing, that is the quotient of width by height.'),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,QGe),''),'Bend Points'),"A fixed list of bend points for the edge. This is used by the 'Fixed Layout' algorithm to specify a pre-defined routing for an edge. The vector chain must include the source point, any bend points, and the target point, so it must have at least two points."),hid),k3),xsb(Thd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,YDe),''),'Content Alignment'),'Specifies how the content of a node are aligned. Each node can individually control the alignment of its contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that option.'),Lkd),fid),q3),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,LDe),''),'Debug Mode'),'Whether additional debug information shall be generated.'),(Geb(),false)),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,PDe),''),eze),'Overall direction of edges: horizontal (right / left) or vertical (down / up).'),Okd),eid),s3),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,kDe),''),'Edge Routing'),'What kind of edge routing style should be applied for the content of a parent node. Algorithms may also set this option to single edges in order to mark them as splines. The bend point list of edges with this option set to SPLINES must be interpreted as control points for a piecewise cubic spline.'),Tkd),eid),u3),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,MGe),''),'Expand Nodes'),'If active, nodes are expanded to fill the area of their parent.'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,fDe),''),'Hierarchy Handling'),"Determines whether separate layout runs are triggered for different compound nodes in a hierarchical graph. Setting a node's hierarchy handling to `INCLUDE_CHILDREN` will lay out that node and all of its descendants in a single layout run, until a descendant is encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that setting. Including multiple levels of hierarchy in a single layout run may allow cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` (or not set at all), the default behavior is `SEPARATE_CHILDREN`."),Ykd),eid),y3),ysb(Whd,cD(WC(d3,1),jwe,170,0,[Vhd])))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,Eze),''),'Padding'),"The padding to be left to a parent element's border when placing child elements. This can also serve as an output option of a layout algorithm if node size calculation is setup appropriately."),uld),hid),i3),ysb(Whd,cD(WC(d3,1),jwe,170,0,[Vhd])))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,dAe),''),'Interactive'),'Whether the algorithm should be run in interactive mode for the content of a parent node. What this means exactly depends on how the specific algorithm interprets this option. Usually in the interactive mode algorithms try to modify the current layout as little as possible.'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,iEe),''),'interactive Layout'),'Whether the graph should be changeable interactively and by setting constraints'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,gAe),''),'Omit Node Micro Layout'),"Node micro layout comprises the computation of node dimensions (if requested), the placement of ports and their labels, and the placement of node labels. The functionality is implemented independent of any specific layout algorithm and shouldn't have any negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, this option allows to deactivate the micro layout."),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,eAe),''),'Port Constraints'),'Defines constraints of the position of the ports of a node.'),Ild),eid),C3),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,fEe),''),'Position'),"The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to specify a pre-defined position."),hid),l3),ysb(Vhd,cD(WC(d3,1),jwe,170,0,[Xhd,Uhd])))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,$ze),''),'Priority'),'Defines the priority of an object; its meaning depends on the specific layout algorithm and the context where it is used.'),gid),bJ),ysb(Vhd,cD(WC(d3,1),jwe,170,0,[Thd])))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,bAe),''),'Randomization Seed'),'Seed used for pseudo-random number generators to control the layout algorithm. If the value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time).'),gid),bJ),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,cAe),''),'Separate Connected Components'),'Whether each connected component should be processed separately.'),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,ZDe),''),'Junction Points'),'This option is not used as option, but as output of the layout algorithms. It is attached to edges and determines the points where junction symbols should be drawn in order to represent hyperedges with orthogonal routing. Whether such points are computed depends on the chosen layout algorithm and edge routing style. The points are put into the vector chain with no specific order.'),dld),hid),k3),xsb(Thd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,aEe),''),'Comment Box'),'Whether the node should be regarded as a comment box instead of a regular node. In that case its placement should be similar to how labels are handled. Any edges incident to a comment box specify to which graph elements the comment is related.'),false),cid),QI),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,bEe),''),'Hypernode'),'Whether the node should be handled as a hypernode.'),false),cid),QI),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,RGe),''),'Label Manager'),"Label managers can shorten labels upon a layout algorithm's request."),hid),g3),ysb(Whd,cD(WC(d3,1),jwe,170,0,[Uhd])))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,gEe),''),'Margins'),"Margins define additional space around the actual bounds of a graph element. For instance, ports or labels being placed on the outside of a node's border might introduce such a margin. The margin is used to guarantee non-overlap of other graph elements with those ports or labels."),fld),hid),h3),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,JDe),''),'No Layout'),"No layout is done for the associated element. This is used to mark parts of a diagram to avoid their inclusion in the layout graph, or to mark parts of the layout graph to prevent layout engines from processing them. If you wish to exclude the contents of a compound node from automatic layout, while the node itself is still considered on its own layer, use the 'Fixed Layout' algorithm for that node."),false),cid),QI),ysb(Vhd,cD(WC(d3,1),jwe,170,0,[Thd,Xhd,Uhd])))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,SGe),''),'Scale Factor'),"The scaling factor to be applied to the corresponding node in recursive layout. It causes the corresponding node's size to be adjusted, and its ports and labels to be sized and placed accordingly after the layout of that node has been determined (and before the node itself and its siblings are arranged). The scaling is not reverted afterwards, so the resulting layout graph contains the adjusted size and position data. This option is currently not supported if 'Layout Hierarchy' is set."),1),did),VI),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,TGe),''),'Child Area Width'),'The width of the area occupied by the laid out children of a node.'),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,UGe),''),'Child Area Height'),'The height of the area occupied by the laid out children of a node.'),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,mAe),''),yGe),"Turns topdown layout on and off. If this option is enabled, hierarchical layout will be computed first for the root node and then for its children recursively. Layouts are then scaled down to fit the area provided by their parents. Graphs must follow a certain structure for topdown layout to work properly. {@link TopdownNodeTypes.PARALLEL_NODE} nodes must have children of type {@link TopdownNodeTypes.HIERARCHICAL_NODE} and must define {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} for their children. Furthermore they need to be laid out using an algorithm that is a {@link TopdownLayoutProvider}. Hierarchical nodes can also be parents of other hierarchical nodes and can optionally use a {@link TopdownSizeApproximator} to dynamically set sizes during topdown layout. In this case {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} should be set on the node itself rather than the parent. The values are then used by the size approximator as base values. Hierarchical nodes require the layout option {@link nodeSize.fixedGraphSize} to be true to prevent the algorithm used there from resizing the hierarchical node. This option is not supported if 'Hierarchy Handling' is set to 'INCLUDE_CHILDREN'"),false),cid),QI),xsb(Whd))));zgd(a,mAe,qAe,null);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,VGe),''),'Animate'),'Whether the shift from the old layout to the new computed layout shall be animated.'),true),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,WGe),''),'Animation Time Factor'),"Factor for computation of animation time. The higher the value, the longer the animation time. If the value is 0, the resulting time is always equal to the minimum defined by 'Minimal Animation Time'."),sgb(100)),gid),bJ),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,XGe),''),'Layout Ancestors'),'Whether the hierarchy levels on the path from the selected element to the root of the diagram shall be included in the layout process.'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,YGe),''),'Maximal Animation Time'),'The maximal time for animations, in milliseconds.'),sgb(4000)),gid),bJ),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,ZGe),''),'Minimal Animation Time'),'The minimal time for animations, in milliseconds.'),sgb(400)),gid),bJ),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,$Ge),''),'Progress Bar'),'Whether a progress bar shall be displayed during layout computations.'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,_Ge),''),'Validate Graph'),'Whether the graph shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user.'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,aHe),''),'Validate Options'),'Whether layout options shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user.'),true),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,bHe),''),'Zoom to Fit'),'Whether the zoom level shall be set to view the whole diagram after layout.'),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,NGe),'box'),'Box Layout Mode'),'Configures the packing mode used by the {@link BoxLayoutProvider}. If SIMPLE is not required (neither priorities are used nor the interactive mode), GROUP_DEC can improve the packing and decrease the area. GROUP_MIXED and GROUP_INC may, in very specific scenarios, work better.'),Gkd),eid),R3),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,xDe),lDe),'Comment Comment Spacing'),'Spacing to be preserved between a comment box and other comment boxes connected to the same node. The space left between comment boxes of different nodes is controlled by the node-node spacing.'),10),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,yDe),lDe),'Comment Node Spacing'),'Spacing to be preserved between a node and its connected comment boxes. The space left between a node and the comments of another node is controlled by the node-node spacing.'),10),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,Bze),lDe),'Components Spacing'),"Spacing to be preserved between pairs of connected components. This option is only relevant if 'separateConnectedComponents' is activated."),20),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,zDe),lDe),'Edge Spacing'),'Spacing to be preserved between any two edges. Note that while this can somewhat easily be satisfied for the segments of orthogonally drawn edges, it is harder for general polylines or splines.'),10),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,aAe),lDe),'Edge Label Spacing'),"The minimal distance to be preserved between a label and the edge it is associated with. Note that the placement of a label is influenced by the 'edgelabels.placement' option."),2),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,ADe),lDe),'Edge Node Spacing'),'Spacing to be preserved between nodes and edges.'),10),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,BDe),lDe),'Label Spacing'),'Determines the amount of space to be left between two labels of the same graph element.'),0),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,EDe),lDe),'Label Node Spacing'),"Spacing to be preserved between labels and the border of node they are associated with. Note that the placement of a label is influenced by the 'nodelabels.placement' option."),5),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,CDe),lDe),'Horizontal spacing between Label and Port'),"Horizontal spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,DDe),lDe),'Vertical spacing between Label and Port'),"Vertical spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,_ze),lDe),'Node Spacing'),'The minimal distance to be preserved between each two nodes.'),20),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,FDe),lDe),'Node Self Loop Spacing'),'Spacing to be preserved between a node and its self loops.'),10),did),VI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,GDe),lDe),'Port Spacing'),'Spacing between pairs of ports of the same node.'),10),did),VI),ysb(Whd,cD(WC(d3,1),jwe,170,0,[Vhd])))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,HDe),lDe),'Individual Spacing'),"Allows to specify individual spacing values for graph elements that shall be different from the value specified for the element's parent."),hid),l4),ysb(Vhd,cD(WC(d3,1),jwe,170,0,[Thd,Xhd,Uhd])))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,hEe),lDe),'Additional Port Space'),'Additional space around the sets of ports on each node side. For each side of a node, this option can reserve additional space before and after the ports on each side. For example, a top spacing of 20 makes sure that the first port on the western and eastern side is 20 units away from the northern border.'),imd),hid),h3),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,eEe),hHe),'Layout Partition'),'Partition to which the node belongs. This requires Layout Partitioning to be active. Nodes with lower partition IDs will appear to the left of nodes with higher partition IDs (assuming a left-to-right layout direction).'),gid),bJ),ysb(Whd,cD(WC(d3,1),jwe,170,0,[Vhd])))));zgd(a,eEe,dEe,yld);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,dEe),hHe),'Layout Partitioning'),'Whether to activate partitioned layout. This will allow to group nodes through the Layout Partition option. a pair of nodes with different partition indices is then placed such that the node with lower index is placed to the left of the other node (with left-to-right layout direction). Depending on the layout algorithm, this may only be guaranteed to work if all nodes have a layout partition configured, or at least if edges that cross partitions are not part of a partition-crossing cycle.'),wld),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,QDe),iHe),'Node Label Padding'),'Define padding for node labels that are placed inside of a node.'),hld),hid),i3),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,kAe),iHe),'Node Label Placement'),"Hints for where node labels are to be placed; if empty, the node label's position is not modified."),jld),fid),A3),ysb(Vhd,cD(WC(d3,1),jwe,170,0,[Uhd])))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,TDe),jHe),'Port Alignment'),'Defines the default port distribution for a node. May be overridden for each side individually.'),Ald),eid),B3),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,UDe),jHe),'Port Alignment (North)'),"Defines how ports on the northern side are placed, overriding the node's general port alignment."),eid),B3),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,VDe),jHe),'Port Alignment (South)'),"Defines how ports on the southern side are placed, overriding the node's general port alignment."),eid),B3),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,WDe),jHe),'Port Alignment (West)'),"Defines how ports on the western side are placed, overriding the node's general port alignment."),eid),B3),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,XDe),jHe),'Port Alignment (East)'),"Defines how ports on the eastern side are placed, overriding the node's general port alignment."),eid),B3),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,jAe),kHe),'Node Size Constraints'),"What should be taken into account when calculating a node's size. Empty size constraints specify that a node's size is already fixed and should not be changed."),lld),fid),H3),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,iAe),kHe),'Node Size Options'),'Options modifying the behavior of the size constraints set on a node. Each member of the set specifies something that should be taken into account when calculating node sizes. The empty set corresponds to no further modifications.'),qld),fid),I3),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,CAe),kHe),'Node Size Minimum'),'The minimal size to which a node can be reduced.'),old),hid),l3),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,hAe),kHe),'Fixed Graph Size'),"By default, the fixed layout provider will enlarge a graph until it is large enough to contain its children. If this option is set, it won't do so."),false),cid),QI),xsb(Whd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,$De),vDe),'Edge Label Placement'),'Gives a hint on where to put edge labels.'),Rkd),eid),t3),xsb(Uhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,fAe),vDe),'Inline Edge Labels'),"If true, an edge label is placed directly on its edge. May only apply to center edge labels. This kind of label placement is only advisable if the label's rendering is such that it is not crossed by its edge and thus stays legible."),false),cid),QI),xsb(Uhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,cHe),'font'),'Font Name'),'Font name used for a label.'),iid),qJ),xsb(Uhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,dHe),'font'),'Font Size'),'Font size used for a label.'),gid),bJ),xsb(Uhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,cEe),lHe),'Port Anchor Offset'),'The offset to the port position where connections shall be attached.'),hid),l3),xsb(Xhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,_De),lHe),'Port Index'),"The index of a port in the fixed order around a node. The order is assumed as clockwise, starting with the leftmost port on the top side. This option must be set if 'Port Constraints' is set to FIXED_ORDER and no specific positions are given for the ports. Additionally, the option 'Port Side' must be defined in this case."),gid),bJ),xsb(Xhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,KDe),lHe),'Port Side'),"The side of a node on which a port is situated. This option must be set if 'Port Constraints' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given for the ports."),Pld),eid),E3),xsb(Xhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Khd(Ohd(Lhd(Mhd(new Shd,IDe),lHe),'Port Border Offset'),"The offset of ports on the node border. With a positive offset the port is moved outside of the node, while with a negative offset the port is moved towards the inside. An offset of 0 means that the port is placed directly on the node border, i.e. if the port side is north, the port's south border touches the nodes's north border; if the port side is east, the port's west border touches the nodes's east border; if the port side is south, the port's north border touches the node's south border; if the port side is west, the port's east border touches the node's west border."),did),VI),xsb(Xhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,lAe),mHe),'Port Label Placement'),"Decides on a placement method for port labels; if empty, the node label's position is not modified."),Mld),fid),D3),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,RDe),mHe),'Port Labels Next to Port'),"Use 'portLabels.placement': NEXT_TO_PORT_OF_POSSIBLE."),false),cid),QI),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,SDe),mHe),'Treat Port Labels as Group'),'If this option is true (default), the labels of a port will be treated as a group when it comes to centering them next to their port. If this option is false, only the first label will be centered next to the port, with the others being placed below. This only applies to labels of eastern and western ports and will have no effect if labels are not placed next to their port.'),true),cid),QI),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,nAe),nHe),'Topdown Scale Factor'),"The scaling factor to be applied to the nodes laid out within the node in recursive topdown layout. The difference to 'Scale Factor' is that the node itself is not scaled. This value has to be set on hierarchical nodes."),1),did),VI),xsb(Whd))));zgd(a,nAe,qAe,rmd);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,eHe),nHe),'Topdown Size Approximator'),'The size approximator to be used to set sizes of hierarchical nodes during topdown layout. The default value is null, which results in nodes keeping whatever size is defined for them e.g. through parent parallel node or by manually setting the size.'),null),eid),M3),xsb(Vhd))));zgd(a,eHe,qAe,tmd);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,oAe),nHe),'Topdown Hierarchical Node Width'),'The fixed size of a hierarchical node when using topdown layout. If this value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to the node itself.'),150),did),VI),ysb(Whd,cD(WC(d3,1),jwe,170,0,[Vhd])))));zgd(a,oAe,qAe,null);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,pAe),nHe),'Topdown Hierarchical Node Aspect Ratio'),'The fixed aspect ratio of a hierarchical node when using topdown layout. Default is 1/sqrt(2). If this value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to the node itself.'),1.414),did),VI),ysb(Whd,cD(WC(d3,1),jwe,170,0,[Vhd])))));zgd(a,pAe,qAe,null);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,qAe),nHe),'Topdown Node Type'),'The different node types used for topdown layout. If the node type is set to {@link TopdownNodeTypes.PARALLEL_NODE} the algorithm must be set to a {@link TopdownLayoutProvider} such as {@link TopdownPacking}. The {@link nodeSize.fixedGraphSize} option is technically only required for hierarchical nodes.'),null),eid),J3),xsb(Vhd))));zgd(a,qAe,hAe,null);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,fHe),nHe),'Topdown Scale Cap'),'Determines the upper limit for the topdown scale factor. The default value is 1.0 which ensures that nested children never end up appearing larger than their parents in terms of unit sizes such as the font size. If the limit is larger, nodes will fully utilize the available space, but it is counteriniuitive for inner nodes to have a larger scale than outer nodes.'),1),did),VI),xsb(Whd))));zgd(a,fHe,qAe,pmd);Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,NDe),oHe),'Activate Inside Self Loops'),"Whether this node allows to route self loops inside of it instead of around it. If set to true, this will make the node a compound node if it isn't already, and will require the layout algorithm to support compound nodes with hierarchical ports."),false),cid),QI),xsb(Vhd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,ODe),oHe),'Inside Self Loop'),'Whether a self loop should be routed inside a node instead of around that node.'),false),cid),QI),xsb(Thd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,Cze),'edge'),'Edge Thickness'),'The thickness of an edge. This is a hint on the line width used to draw an edge, possibly requiring more space to be reserved for it.'),1),did),VI),xsb(Thd))));Egd(a,new Ahd(Qhd(Phd(Rhd(Jhd(Khd(Ohd(Lhd(Mhd(new Shd,gHe),'edge'),'Edge Type'),'The type of an edge. This is usually used for UML class diagrams, where associations must be handled differently from generalizations.'),Vkd),eid),v3),xsb(Thd))));Dgd(a,new fgd(mgd(ogd(ngd(new pgd,sxe),'Layered'),'The layer-based method was introduced by Sugiyama, Tagawa and Toda in 1981. It emphasizes the direction of edges by pointing as many edges as possible into the same direction. The nodes are arranged in layers, which are sometimes called "hierarchies", and then reordered such that the number of edge crossings is minimized. Afterwards, concrete coordinates are computed for the nodes and edge bend points.')));Dgd(a,new fgd(mgd(ogd(ngd(new pgd,'org.eclipse.elk.orthogonal'),'Orthogonal'),'Orthogonal methods that follow the "topology-shape-metrics" approach by Batini, Nardelli and Tamassia \'86. The first phase determines the topology of the drawing by applying a planarization technique, which results in a planar representation of the graph. The orthogonal shape is computed in the second phase, which aims at minimizing the number of edge bends, and is called orthogonalization. The third phase leads to concrete coordinates for nodes and edge bend points by applying a compaction method, thus defining the metrics.')));Dgd(a,new fgd(mgd(ogd(ngd(new pgd,Zze),'Force'),'Layout algorithms that follow physical analogies by simulating a system of attractive and repulsive forces. The first successful method of this kind was proposed by Eades in 1984.')));Dgd(a,new fgd(mgd(ogd(ngd(new pgd,'org.eclipse.elk.circle'),'Circle'),'Circular layout algorithms emphasize cycles or biconnected components of a graph by arranging them in circles. This is useful if a drawing is desired where such components are clearly grouped, or where cycles are shown as prominent OPTIONS of the graph.')));Dgd(a,new fgd(mgd(ogd(ngd(new pgd,$Ee),'Tree'),'Specialized layout methods for trees, i.e. acyclic graphs. The regular structure of graphs that have no undirected cycles can be emphasized using an algorithm of this type.')));Dgd(a,new fgd(mgd(ogd(ngd(new pgd,'org.eclipse.elk.planar'),'Planar'),'Algorithms that require a planar or upward planar graph. Most of these algorithms are theoretically interesting, but not practically usable.')));Dgd(a,new fgd(mgd(ogd(ngd(new pgd,CFe),'Radial'),'Radial layout algorithms usually position the nodes of the graph on concentric circles.')));wnd((new xnd,a));ikd((new jkd,a));Gpd((new Hpd,a))};var Akd,Bkd,Ckd,Dkd,Ekd,Fkd,Gkd,Hkd,Ikd,Jkd,Kkd,Lkd,Mkd,Nkd,Okd,Pkd,Qkd,Rkd,Skd,Tkd,Ukd,Vkd,Wkd,Xkd,Ykd,Zkd,$kd,_kd,ald,bld,cld,dld,eld,fld,gld,hld,ild,jld,kld,lld,mld,nld,old,pld,qld,rld,sld,tld,uld,vld,wld,xld,yld,zld,Ald,Bld,Cld,Dld,Eld,Fld,Gld,Hld,Ild,Jld,Kld,Lld,Mld,Nld,Old,Pld,Qld,Rld,Sld,Tld,Uld,Vld,Wld,Xld,Yld,Zld,$ld,_ld,amd,bmd,cmd,dmd,emd,fmd,gmd,hmd,imd,jmd,kmd,lmd,mmd,nmd,omd,pmd,qmd,rmd,smd,tmd;var r3=sfb(JGe,'CoreOptions',699);feb(88,22,{3:1,34:1,22:1,88:1},Gmd);var xmd,ymd,zmd,Amd,Bmd;var s3=tfb(JGe,eze,88,WI,Imd,Hmd);var Jmd;feb(278,22,{3:1,34:1,22:1,278:1},Pmd);var Lmd,Mmd,Nmd;var t3=tfb(JGe,'EdgeLabelPlacement',278,WI,Rmd,Qmd);var Smd;feb(223,22,{3:1,34:1,22:1,223:1},Zmd);var Umd,Vmd,Wmd,Xmd;var u3=tfb(JGe,'EdgeRouting',223,WI,_md,$md);var and;feb(321,22,{3:1,34:1,22:1,321:1},jnd);var cnd,dnd,end,fnd,gnd,hnd;var v3=tfb(JGe,'EdgeType',321,WI,lnd,knd);var mnd;feb(989,1,Eye,xnd);_.hf=function ynd(a){wnd(a)};var ond,pnd,qnd,rnd,snd,tnd,und;var x3=sfb(JGe,'FixedLayouterOptions',989);feb(990,1,{},znd);_.sf=function And(){var a;return a=new btd,a};_.tf=function Bnd(a){};var w3=sfb(JGe,'FixedLayouterOptions/FixedFactory',990);feb(346,22,{3:1,34:1,22:1,346:1},Gnd);var Cnd,Dnd,End;var y3=tfb(JGe,'HierarchyHandling',346,WI,Ind,Hnd);var Jnd;feb(291,22,{3:1,34:1,22:1,291:1},Rnd);var Lnd,Mnd,Nnd,Ond;var z3=tfb(JGe,'LabelSide',291,WI,Tnd,Snd);var Und;feb(95,22,{3:1,34:1,22:1,95:1},eod);var Wnd,Xnd,Ynd,Znd,$nd,_nd,aod,bod,cod;var A3=tfb(JGe,'NodeLabelPlacement',95,WI,hod,god);var iod;feb(256,22,{3:1,34:1,22:1,256:1},qod);var kod,lod,mod,nod,ood;var B3=tfb(JGe,'PortAlignment',256,WI,sod,rod);var tod;feb(101,22,{3:1,34:1,22:1,101:1},Eod);var vod,wod,xod,yod,zod,Aod;var C3=tfb(JGe,'PortConstraints',101,WI,God,Fod);var Hod;feb(279,22,{3:1,34:1,22:1,279:1},Qod);var Jod,Kod,Lod,Mod,Nod,Ood;var D3=tfb(JGe,'PortLabelPlacement',279,WI,Uod,Tod);var Vod;feb(64,22,{3:1,34:1,22:1,64:1},upd);var Xod,Yod,Zod,$od,_od,apd,bpd,cpd,dpd,epd,fpd,gpd,hpd,ipd,jpd,kpd,lpd,mpd,npd,opd,ppd;var E3=tfb(JGe,'PortSide',64,WI,xpd,wpd);var ypd;feb(993,1,Eye,Hpd);_.hf=function Ipd(a){Gpd(a)};var Apd,Bpd,Cpd,Dpd,Epd;var G3=sfb(JGe,'RandomLayouterOptions',993);feb(994,1,{},Jpd);_.sf=function Kpd(){var a;return a=new eud,a};_.tf=function Lpd(a){};var F3=sfb(JGe,'RandomLayouterOptions/RandomFactory',994);feb(386,22,{3:1,34:1,22:1,386:1},Rpd);var Mpd,Npd,Opd,Ppd;var H3=tfb(JGe,'SizeConstraint',386,WI,Tpd,Spd);var Upd;feb(264,22,{3:1,34:1,22:1,264:1},eqd);var Wpd,Xpd,Ypd,Zpd,$pd,_pd,aqd,bqd,cqd;var I3=tfb(JGe,'SizeOptions',264,WI,gqd,fqd);var hqd;feb(280,22,{3:1,34:1,22:1,280:1},nqd);var jqd,kqd,lqd;var J3=tfb(JGe,'TopdownNodeTypes',280,WI,pqd,oqd);var qqd;feb(347,22,rHe);var sqd,tqd;var M3=tfb(JGe,'TopdownSizeApproximator',347,WI,xqd,wqd);feb(987,347,rHe,zqd);_.Tg=function Aqd(a){return yqd(a)};var K3=tfb(JGe,'TopdownSizeApproximator/1',987,M3,null,null);feb(988,347,rHe,Bqd);_.Tg=function Cqd(b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D;c=RD(Gxd(b,(umd(),Tld)),143);A=(bvd(),o=new ACd,o);zxd(A,b);B=new Tsb;for(g=new dMd((!b.a&&(b.a=new C5d(J4,b,10,11)),b.a));g.e!=g.i.gc();){e=RD(bMd(g),27);t=(n=new ACd,n);yCd(t,A);zxd(t,e);D=yqd(e);zyd(t,$wnd.Math.max(e.g,D.a),$wnd.Math.max(e.f,D.b));rtb(B.f,e,t)}for(f=new dMd((!b.a&&(b.a=new C5d(J4,b,10,11)),b.a));f.e!=f.i.gc();){e=RD(bMd(f),27);for(l=new dMd((!e.e&&(e.e=new Yie(G4,e,7,4)),e.e));l.e!=l.i.gc();){k=RD(bMd(l),74);v=RD(Wd(qtb(B.f,e)),27);w=RD(Wjb(B,QHd((!k.c&&(k.c=new Yie(E4,k,5,8)),k.c),0)),27);u=(m=new rzd,m);WGd((!u.b&&(u.b=new Yie(E4,u,4,7)),u.b),v);WGd((!u.c&&(u.c=new Yie(E4,u,5,8)),u.c),w);pzd(u,vCd(v));zxd(u,k)}}q=RD(ltd(c.f),205);try{q.rf(A,new ztd);mtd(c.f,q)}catch(a){a=zdb(a);if(ZD(a,103)){p=a;throw Adb(p)}else throw Adb(a)}Hxd(A,Ikd)||Hxd(A,Hkd)||psd(A);j=Kfb(UD(Gxd(A,Ikd)));i=Kfb(UD(Gxd(A,Hkd)));h=j/i;d=Kfb(UD(Gxd(A,lmd)))*$wnd.Math.sqrt((!A.a&&(A.a=new C5d(J4,A,10,11)),A.a).i);C=RD(Gxd(A,tld),107);s=C.b+C.c+1;r=C.d+C.a+1;return new rjd($wnd.Math.max(s,d),$wnd.Math.max(r,d/h))};var L3=tfb(JGe,'TopdownSizeApproximator/2',988,M3,null,null);var Dqd;feb(344,1,{871:1},Oqd);_.Ug=function Pqd(a,b){return Fqd(this,a,b)};_.Vg=function Qqd(){Hqd(this)};_.Wg=function Rqd(){return this.q};_.Xg=function Sqd(){return !this.f?null:Hob(this.f)};_.Yg=function Tqd(){return Hob(this.a)};_.Zg=function Uqd(){return this.p};_.$g=function Vqd(){return false};_._g=function Wqd(){return this.n};_.ah=function Xqd(){return this.p!=null&&!this.b};_.bh=function Yqd(a){var b;if(this.n){b=a;Rmb(this.f,b)}};_.dh=function Zqd(a,b){var c,d;this.n&&!!a&&Jqd(this,(c=new Zje,d=Rje(c,a),Yje(c),d),(ttd(),qtd))};_.eh=function $qd(a){var b;if(this.b){return null}else{b=Gqd(this,this.g);Mub(this.a,b);b.i=this;this.d=a;return b}};_.fh=function _qd(a){a>0&&!this.b&&Iqd(this,a)};_.b=false;_.c=0;_.d=-1;_.e=null;_.f=null;_.g=-1;_.j=false;_.k=false;_.n=false;_.o=0;_.q=0;_.r=0;var O3=sfb(jEe,'BasicProgressMonitor',344);feb(717,205,oze,jrd);_.rf=function nrd(a,b){crd(a,b)};var V3=sfb(jEe,'BoxLayoutProvider',717);feb(983,1,fye,prd);_.Ne=function qrd(a,b){return ord(this,RD(a,27),RD(b,27))};_.Fb=function rrd(a){return this===a};_.Oe=function srd(){return new Frb(this)};_.a=false;var P3=sfb(jEe,'BoxLayoutProvider/1',983);feb(163,1,{163:1},zrd,Ard);_.Ib=function Brd(){return this.c?zCd(this.c):Fe(this.b)};var Q3=sfb(jEe,'BoxLayoutProvider/Group',163);feb(320,22,{3:1,34:1,22:1,320:1},Hrd);var Crd,Drd,Erd,Frd;var R3=tfb(jEe,'BoxLayoutProvider/PackingMode',320,WI,Jrd,Ird);var Krd;feb(984,1,fye,Mrd);_.Ne=function Nrd(a,b){return krd(RD(a,163),RD(b,163))};_.Fb=function Ord(a){return this===a};_.Oe=function Prd(){return new Frb(this)};var S3=sfb(jEe,'BoxLayoutProvider/lambda$0$Type',984);feb(985,1,fye,Qrd);_.Ne=function Rrd(a,b){return lrd(RD(a,163),RD(b,163))};_.Fb=function Srd(a){return this===a};_.Oe=function Trd(){return new Frb(this)};var T3=sfb(jEe,'BoxLayoutProvider/lambda$1$Type',985);feb(986,1,fye,Urd);_.Ne=function Vrd(a,b){return mrd(RD(a,163),RD(b,163))};_.Fb=function Wrd(a){return this===a};_.Oe=function Xrd(){return new Frb(this)};var U3=sfb(jEe,'BoxLayoutProvider/lambda$2$Type',986);feb(1384,1,{845:1},Yrd);_.Mg=function Zrd(a,b){return GCc(),!ZD(b,167)||ued((hed(),ged,RD(a,167)),b)};var W3=sfb(jEe,'ElkSpacings/AbstractSpacingsBuilder/lambda$0$Type',1384);feb(1385,1,Qve,$rd);_.Cd=function _rd(a){JCc(this.a,RD(a,149))};var X3=sfb(jEe,'ElkSpacings/AbstractSpacingsBuilder/lambda$1$Type',1385);feb(1386,1,Qve,asd);_.Cd=function bsd(a){RD(a,96);GCc()};var Y3=sfb(jEe,'ElkSpacings/AbstractSpacingsBuilder/lambda$2$Type',1386);feb(1390,1,Qve,csd);_.Cd=function dsd(a){KCc(this.a,RD(a,96))};var Z3=sfb(jEe,'ElkSpacings/AbstractSpacingsBuilder/lambda$3$Type',1390);feb(1388,1,nwe,esd);_.Mb=function fsd(a){return LCc(this.a,this.b,RD(a,149))};var $3=sfb(jEe,'ElkSpacings/AbstractSpacingsBuilder/lambda$4$Type',1388);feb(1387,1,nwe,gsd);_.Mb=function hsd(a){return NCc(this.a,this.b,RD(a,845))};var _3=sfb(jEe,'ElkSpacings/AbstractSpacingsBuilder/lambda$5$Type',1387);feb(1389,1,Qve,isd);_.Cd=function jsd(a){MCc(this.a,this.b,RD(a,149))};var a4=sfb(jEe,'ElkSpacings/AbstractSpacingsBuilder/lambda$6$Type',1389);feb(947,1,{},Lsd);_.Kb=function Msd(a){return Ksd(a)};_.Fb=function Nsd(a){return this===a};var c4=sfb(jEe,'ElkUtil/lambda$0$Type',947);feb(948,1,Qve,Osd);_.Cd=function Psd(a){ysd(this.a,this.b,RD(a,74))};_.a=0;_.b=0;var d4=sfb(jEe,'ElkUtil/lambda$1$Type',948);feb(949,1,Qve,Qsd);_.Cd=function Rsd(a){zsd(this.a,this.b,RD(a,166))};_.a=0;_.b=0;var e4=sfb(jEe,'ElkUtil/lambda$2$Type',949);feb(950,1,Qve,Ssd);_.Cd=function Tsd(a){Asd(this.a,this.b,RD(a,135))};_.a=0;_.b=0;var f4=sfb(jEe,'ElkUtil/lambda$3$Type',950);feb(951,1,Qve,Usd);_.Cd=function Vsd(a){Bsd(this.a,RD(a,377))};var g4=sfb(jEe,'ElkUtil/lambda$4$Type',951);feb(325,1,{34:1,325:1},Xsd);_.Fd=function Ysd(a){return Wsd(this,RD(a,242))};_.Fb=function Zsd(a){var b;if(ZD(a,325)){b=RD(a,325);return this.a==b.a}return false};_.Hb=function $sd(){return eE(this.a)};_.Ib=function _sd(){return this.a+' (exclusive)'};_.a=0;var h4=sfb(jEe,'ExclusiveBounds/ExclusiveLowerBound',325);feb(1119,205,oze,btd);_.rf=function ctd(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B;b.Ug('Fixed Layout',1);f=RD(Gxd(a,(umd(),Skd)),223);l=0;m=0;for(s=new dMd((!a.a&&(a.a=new C5d(J4,a,10,11)),a.a));s.e!=s.i.gc();){q=RD(bMd(s),27);B=RD(Gxd(q,(vnd(),und)),8);if(B){Byd(q,B.a,B.b);if(RD(Gxd(q,pnd),181).Hc((Qpd(),Mpd))){n=RD(Gxd(q,rnd),8);n.a>0&&n.b>0&&Esd(q,n.a,n.b,true,true)}}l=$wnd.Math.max(l,q.i+q.g);m=$wnd.Math.max(m,q.j+q.f);for(j=new dMd((!q.n&&(q.n=new C5d(I4,q,1,7)),q.n));j.e!=j.i.gc();){h=RD(bMd(j),135);B=RD(Gxd(h,und),8);!!B&&Byd(h,B.a,B.b);l=$wnd.Math.max(l,q.i+h.i+h.g);m=$wnd.Math.max(m,q.j+h.j+h.f)}for(v=new dMd((!q.c&&(q.c=new C5d(K4,q,9,9)),q.c));v.e!=v.i.gc();){u=RD(bMd(v),123);B=RD(Gxd(u,und),8);!!B&&Byd(u,B.a,B.b);w=q.i+u.i;A=q.j+u.j;l=$wnd.Math.max(l,w+u.g);m=$wnd.Math.max(m,A+u.f);for(i=new dMd((!u.n&&(u.n=new C5d(I4,u,1,7)),u.n));i.e!=i.i.gc();){h=RD(bMd(i),135);B=RD(Gxd(h,und),8);!!B&&Byd(h,B.a,B.b);l=$wnd.Math.max(l,w+h.i+h.g);m=$wnd.Math.max(m,A+h.j+h.f)}}for(e=new is(Mr(zGd(q).a.Kc(),new ir));gs(e);){c=RD(hs(e),74);k=atd(c);l=$wnd.Math.max(l,k.a);m=$wnd.Math.max(m,k.b)}for(d=new is(Mr(yGd(q).a.Kc(),new ir));gs(d);){c=RD(hs(d),74);if(vCd(JGd(c))!=a){k=atd(c);l=$wnd.Math.max(l,k.a);m=$wnd.Math.max(m,k.b)}}}if(f==(Ymd(),Umd)){for(r=new dMd((!a.a&&(a.a=new C5d(J4,a,10,11)),a.a));r.e!=r.i.gc();){q=RD(bMd(r),27);for(d=new is(Mr(zGd(q).a.Kc(),new ir));gs(d);){c=RD(hs(d),74);g=tsd(c);g.b==0?Ixd(c,cld,null):Ixd(c,cld,g)}}}if(!Heb(TD(Gxd(a,(vnd(),qnd))))){t=RD(Gxd(a,snd),107);p=l+t.b+t.c;o=m+t.d+t.a;Esd(a,p,o,true,true)}b.Vg()};var i4=sfb(jEe,'FixedLayoutProvider',1119);feb(385,137,{3:1,423:1,385:1,96:1,137:1},dtd,etd);_.cg=function htd(b){var c,d,e,f,g,h,i,j,k;if(!b){return}try{j=vhb(b,';,;');for(g=j,h=0,i=g.length;h>16&Bwe|b^d<<16};_.Kc=function Ttd(){return new Vtd(this)};_.Ib=function Utd(){return this.a==null&&this.b==null?'pair(null,null)':this.a==null?'pair(null,'+jeb(this.b)+')':this.b==null?'pair('+jeb(this.a)+',null)':'pair('+jeb(this.a)+','+jeb(this.b)+')'};var r4=sfb(jEe,'Pair',42);feb(995,1,Ave,Vtd);_.Nb=function Wtd(a){Ztb(this,a)};_.Ob=function Xtd(){return !this.c&&(!this.b&&this.a.a!=null||this.a.b!=null)};_.Pb=function Ytd(){if(!this.c&&!this.b&&this.a.a!=null){this.b=true;return this.a.a}else if(!this.c&&this.a.b!=null){this.c=true;return this.a.b}throw Adb(new Dvb)};_.Qb=function Ztd(){this.c&&this.a.b!=null?(this.a.b=null):this.b&&this.a.a!=null&&(this.a.a=null);throw Adb(new cgb)};_.b=false;_.c=false;var q4=sfb(jEe,'Pair/1',995);feb(455,1,{455:1},$td);_.Fb=function _td(a){return Fvb(this.a,RD(a,455).a)&&Fvb(this.c,RD(a,455).c)&&Fvb(this.d,RD(a,455).d)&&Fvb(this.b,RD(a,455).b)};_.Hb=function aud(){return Tnb(cD(WC(jJ,1),rve,1,5,[this.a,this.c,this.d,this.b]))};_.Ib=function bud(){return '('+this.a+pve+this.c+pve+this.d+pve+this.b+')'};var s4=sfb(jEe,'Quadruple',455);feb(1108,205,oze,eud);_.rf=function fud(a,b){var c,d,e,f,g;b.Ug('Random Layout',1);if((!a.a&&(a.a=new C5d(J4,a,10,11)),a.a).i==0){b.Vg();return}f=RD(Gxd(a,(Fpd(),Dpd)),17);!!f&&f.a!=0?(e=new Pwb(f.a)):(e=new Owb);c=Mfb(UD(Gxd(a,Apd)));g=Mfb(UD(Gxd(a,Epd)));d=RD(Gxd(a,Bpd),107);dud(a,e,c,g,d);b.Vg()};var t4=sfb(jEe,'RandomLayoutProvider',1108);feb(240,1,{240:1},gud);_.Fb=function hud(a){return Fvb(this.a,RD(a,240).a)&&Fvb(this.b,RD(a,240).b)&&Fvb(this.c,RD(a,240).c)};_.Hb=function iud(){return Tnb(cD(WC(jJ,1),rve,1,5,[this.a,this.b,this.c]))};_.Ib=function jud(){return '('+this.a+pve+this.b+pve+this.c+')'};var u4=sfb(jEe,'Triple',240);var kud;feb(562,1,{});_.Lf=function oud(){return new rjd(this.f.i,this.f.j)};_.of=function pud(a){if(hGd(a,(umd(),Gld))){return Gxd(this.f,mud)}return Gxd(this.f,a)};_.Mf=function qud(){return new rjd(this.f.g,this.f.f)};_.Nf=function rud(){return this.g};_.pf=function sud(a){return Hxd(this.f,a)};_.Of=function tud(a){Dyd(this.f,a.a);Eyd(this.f,a.b)};_.Pf=function uud(a){Cyd(this.f,a.a);Ayd(this.f,a.b)};_.Qf=function vud(a){this.g=a};_.g=0;var mud;var v4=sfb(uHe,'ElkGraphAdapters/AbstractElkGraphElementAdapter',562);feb(563,1,{853:1},wud);_.Rf=function xud(){var a,b;if(!this.b){this.b=fv(iyd(this.a).i);for(b=new dMd(iyd(this.a));b.e!=b.i.gc();){a=RD(bMd(b),135);Rmb(this.b,new Bud(a))}}return this.b};_.b=null;var w4=sfb(uHe,'ElkGraphAdapters/ElkEdgeAdapter',563);feb(289,562,{},zud);_.Sf=function Aud(){return yud(this)};_.a=null;var x4=sfb(uHe,'ElkGraphAdapters/ElkGraphAdapter',289);feb(640,562,{187:1},Bud);var y4=sfb(uHe,'ElkGraphAdapters/ElkLabelAdapter',640);feb(639,562,{695:1},Fud);_.Rf=function Iud(){return Cud(this)};_.Vf=function Jud(){var a;return a=RD(Gxd(this.f,(umd(),eld)),140),!a&&(a=new P2b),a};_.Xf=function Lud(){return Dud(this)};_.Zf=function Nud(a){var b;b=new S2b(a);Ixd(this.f,(umd(),eld),b)};_.$f=function Oud(a){Ixd(this.f,(umd(),tld),new B3b(a))};_.Tf=function Gud(){return this.d};_.Uf=function Hud(){var a,b;if(!this.a){this.a=new bnb;for(b=new is(Mr(yGd(RD(this.f,27)).a.Kc(),new ir));gs(b);){a=RD(hs(b),74);Rmb(this.a,new wud(a))}}return this.a};_.Wf=function Kud(){var a,b;if(!this.c){this.c=new bnb;for(b=new is(Mr(zGd(RD(this.f,27)).a.Kc(),new ir));gs(b);){a=RD(hs(b),74);Rmb(this.c,new wud(a))}}return this.c};_.Yf=function Mud(){return tCd(RD(this.f,27)).i!=0||Heb(TD(RD(this.f,27).of((umd(),$kd))))};_._f=function Pud(){Eud(this,(lud(),kud))};_.a=null;_.b=null;_.c=null;_.d=null;_.e=null;var z4=sfb(uHe,'ElkGraphAdapters/ElkNodeAdapter',639);feb(1284,562,{852:1},Rud);_.Rf=function Tud(){return Qud(this)};_.Uf=function Sud(){var a,b;if(!this.a){this.a=ev(RD(this.f,123).hh().i);for(b=new dMd(RD(this.f,123).hh());b.e!=b.i.gc();){a=RD(bMd(b),74);Rmb(this.a,new wud(a))}}return this.a};_.Wf=function Uud(){var a,b;if(!this.c){this.c=ev(RD(this.f,123).ih().i);for(b=new dMd(RD(this.f,123).ih());b.e!=b.i.gc();){a=RD(bMd(b),74);Rmb(this.c,new wud(a))}}return this.c};_.ag=function Vud(){return RD(RD(this.f,123).of((umd(),Old)),64)};_.bg=function Wud(){var a,b,c,d,e,f,g,h;d=MCd(RD(this.f,123));for(c=new dMd(RD(this.f,123).ih());c.e!=c.i.gc();){a=RD(bMd(c),74);for(h=new dMd((!a.c&&(a.c=new Yie(E4,a,5,8)),a.c));h.e!=h.i.gc();){g=RD(bMd(h),84);if(NGd(AGd(g),d)){return true}else if(AGd(g)==d&&Heb(TD(Gxd(a,(umd(),_kd))))){return true}}}for(b=new dMd(RD(this.f,123).hh());b.e!=b.i.gc();){a=RD(bMd(b),74);for(f=new dMd((!a.b&&(a.b=new Yie(E4,a,4,7)),a.b));f.e!=f.i.gc();){e=RD(bMd(f),84);if(NGd(AGd(e),d)){return true}}}return false};_.a=null;_.b=null;_.c=null;var A4=sfb(uHe,'ElkGraphAdapters/ElkPortAdapter',1284);feb(1285,1,fye,Yud);_.Ne=function Zud(a,b){return Xud(RD(a,123),RD(b,123))};_.Fb=function $ud(a){return this===a};_.Oe=function _ud(){return new Frb(this)};var B4=sfb(uHe,'ElkGraphAdapters/PortComparator',1285);var r7=ufb(vHe,'EObject');var C4=ufb(wHe,xHe);var D4=ufb(wHe,yHe);var H4=ufb(wHe,zHe);var L4=ufb(wHe,'ElkShape');var E4=ufb(wHe,AHe);var G4=ufb(wHe,BHe);var F4=ufb(wHe,CHe);var p7=ufb(vHe,DHe);var n7=ufb(vHe,'EFactory');var avd;var q7=ufb(vHe,EHe);var t7=ufb(vHe,'EPackage');var cvd;var evd,fvd,gvd,hvd,ivd,jvd,kvd,lvd,mvd,nvd,ovd;var I4=ufb(wHe,FHe);var J4=ufb(wHe,GHe);var K4=ufb(wHe,HHe);feb(93,1,IHe);_.th=function rvd(){this.uh();return null};_.uh=function svd(){return null};_.vh=function tvd(){return this.uh(),false};_.wh=function uvd(){return false};_.xh=function vvd(a){qvd(this,a)};var g6=sfb(JHe,'BasicNotifierImpl',93);feb(99,93,RHe);_.Yh=function Dwd(){return Mvd(this)};_.yh=function bwd(a,b){return a};_.zh=function cwd(){throw Adb(new jib)};_.Ah=function dwd(a){var b;return b=Z5d(RD(vYd(this.Dh(),this.Fh()),19)),this.Ph().Th(this,b.n,b.f,a)};_.Bh=function ewd(a,b){throw Adb(new jib)};_.Ch=function fwd(a,b,c){return xvd(this,a,b,c)};_.Dh=function gwd(){var a;if(this.zh()){a=this.zh().Nk();if(a){return a}}return this.ii()};_.Eh=function hwd(){return yvd(this)};_.Fh=function iwd(){throw Adb(new jib)};_.Gh=function kwd(){var a,b;b=this.$h().Ok();!b&&this.zh().Tk(b=(N2d(),a=P$d(rYd(this.Dh())),a==null?M2d:new Q2d(this,a)));return b};_.Hh=function mwd(a,b){return a};_.Ih=function nwd(a){var b;b=a.pk();return !b?BYd(this.Dh(),a):a.Lj()};_.Jh=function owd(){var a;a=this.zh();return !a?null:a.Qk()};_.Kh=function pwd(){return !this.zh()?null:this.zh().Nk()};_.Lh=function qwd(a,b,c){return Dvd(this,a,b,c)};_.Mh=function rwd(a){return Evd(this,a)};_.Nh=function swd(a,b){return Fvd(this,a,b)};_.Oh=function twd(){var a;a=this.zh();return !!a&&a.Rk()};_.Ph=function uwd(){throw Adb(new jib)};_.Qh=function vwd(){return Hvd(this)};_.Rh=function wwd(a,b,c,d){return Ivd(this,a,b,d)};_.Sh=function xwd(a,b,c){var d;return d=RD(vYd(this.Dh(),b),69),d.wk().zk(this,this.hi(),b-this.ji(),a,c)};_.Th=function ywd(a,b,c,d){return Jvd(this,a,b,d)};_.Uh=function zwd(a,b,c){var d;return d=RD(vYd(this.Dh(),b),69),d.wk().Ak(this,this.hi(),b-this.ji(),a,c)};_.Vh=function Awd(){return !!this.zh()&&!!this.zh().Pk()};_.Wh=function Bwd(a){return Kvd(this,a)};_.Xh=function Cwd(a){return Lvd(this,a)};_.Zh=function Ewd(a){return Pvd(this,a)};_.$h=function Fwd(){throw Adb(new jib)};_._h=function Gwd(){return !this.zh()?null:this.zh().Pk()};_.ai=function Hwd(){return Hvd(this)};_.bi=function Iwd(a,b){Wvd(this,a,b)};_.ci=function Jwd(a){this.$h().Sk(a)};_.di=function Kwd(a){this.$h().Vk(a)};_.ei=function Lwd(a){this.$h().Uk(a)};_.fi=function Mwd(a,b){var c,d,e,f;f=this.Jh();if(!!f&&!!a){b=rLd(f.El(),this,b);f.Il(this)}d=this.Ph();if(d){if((jwd(this,this.Ph(),this.Fh()).Bb&txe)!=0){e=d.Qh();!!e&&(!a?e.Hl(this):!f&&e.Il(this))}else{b=(c=this.Fh(),c>=0?this.Ah(b):this.Ph().Th(this,-1-c,null,b));b=this.Ch(null,-1,b)}}this.di(a);return b};_.gi=function Nwd(a){var b,c,d,e,f,g,h,i;c=this.Dh();f=BYd(c,a);b=this.ji();if(f>=b){return RD(a,69).wk().Dk(this,this.hi(),f-b)}else if(f<=-1){g=Eee((lke(),jke),c,a);if(g){nke();RD(g,69).xk()||(g=zfe(Qee(jke,g)));e=(d=this.Ih(g),RD(d>=0?this.Lh(d,true,true):Qvd(this,g,true),160));i=g.Ik();if(i>1||i==-1){return RD(RD(e,220).Sl(a,false),79)}}else{throw Adb(new agb(KHe+a.xe()+NHe))}}else if(a.Jk()){return d=this.Ih(a),RD(d>=0?this.Lh(d,false,true):Qvd(this,a,false),79)}h=new NTd(this,a);return h};_.hi=function Owd(){return Yvd(this)};_.ii=function Pwd(){return (lTd(),kTd).S};_.ji=function Qwd(){return AYd(this.ii())};_.ki=function Rwd(a){$vd(this,a)};_.Ib=function Swd(){return awd(this)};var G7=sfb(SHe,'BasicEObjectImpl',99);var ZSd;feb(119,99,{110:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1});_.li=function _wd(a){var b;b=Vwd(this);return b[a]};_.mi=function axd(a,b){var c;c=Vwd(this);bD(c,a,b)};_.ni=function bxd(a){var b;b=Vwd(this);bD(b,a,null)};_.th=function cxd(){return RD(Ywd(this,4),129)};_.uh=function dxd(){throw Adb(new jib)};_.vh=function exd(){return (this.Db&4)!=0};_.zh=function fxd(){throw Adb(new jib)};_.oi=function gxd(a){$wd(this,2,a)};_.Bh=function hxd(a,b){this.Db=b<<16|this.Db&255;this.oi(a)};_.Dh=function ixd(){return Uwd(this)};_.Fh=function jxd(){return this.Db>>16};_.Gh=function kxd(){var a,b;return N2d(),b=P$d(rYd((a=RD(Ywd(this,16),29),!a?this.ii():a))),b==null?(null,M2d):new Q2d(this,b)};_.wh=function lxd(){return (this.Db&1)==0};_.Jh=function mxd(){return RD(Ywd(this,128),2034)};_.Kh=function nxd(){return RD(Ywd(this,16),29)};_.Oh=function oxd(){return (this.Db&32)!=0};_.Ph=function pxd(){return RD(Ywd(this,2),54)};_.Vh=function qxd(){return (this.Db&64)!=0};_.$h=function rxd(){throw Adb(new jib)};_._h=function sxd(){return RD(Ywd(this,64),288)};_.ci=function txd(a){$wd(this,16,a)};_.di=function uxd(a){$wd(this,128,a)};_.ei=function vxd(a){$wd(this,64,a)};_.hi=function wxd(){return Wwd(this)};_.Db=0;var xab=sfb(SHe,'MinimalEObjectImpl',119);feb(120,119,{110:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1});_.oi=function xxd(a){this.Cb=a};_.Ph=function yxd(){return this.Cb};var wab=sfb(SHe,'MinimalEObjectImpl/Container',120);feb(2083,120,{110:1,342:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1});_.Lh=function Jxd(a,b,c){return Axd(this,a,b,c)};_.Uh=function Kxd(a,b,c){return Bxd(this,a,b,c)};_.Wh=function Lxd(a){return Cxd(this,a)};_.bi=function Mxd(a,b){Dxd(this,a,b)};_.ii=function Nxd(){return pvd(),ovd};_.ki=function Oxd(a){Exd(this,a)};_.nf=function Pxd(){return Fxd(this)};_.gh=function Qxd(){return !this.o&&(this.o=new DVd((pvd(),mvd),X4,this,0)),this.o};_.of=function Rxd(a){return Gxd(this,a)};_.pf=function Sxd(a){return Hxd(this,a)};_.qf=function Txd(a,b){return Ixd(this,a,b)};var M4=sfb(THe,'EMapPropertyHolderImpl',2083);feb(572,120,{110:1,377:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},Xxd);_.Lh=function Yxd(a,b,c){switch(a){case 0:return this.a;case 1:return this.b;}return Dvd(this,a,b,c)};_.Wh=function Zxd(a){switch(a){case 0:return this.a!=0;case 1:return this.b!=0;}return Kvd(this,a)};_.bi=function $xd(a,b){switch(a){case 0:Vxd(this,Kfb(UD(b)));return;case 1:Wxd(this,Kfb(UD(b)));return;}Wvd(this,a,b)};_.ii=function _xd(){return pvd(),evd};_.ki=function ayd(a){switch(a){case 0:Vxd(this,0);return;case 1:Wxd(this,0);return;}$vd(this,a)};_.Ib=function byd(){var a;if((this.Db&64)!=0)return awd(this);a=new Shb(awd(this));a.a+=' (x: ';Khb(a,this.a);a.a+=', y: ';Khb(a,this.b);a.a+=')';return a.a};_.a=0;_.b=0;var N4=sfb(THe,'ElkBendPointImpl',572);feb(739,2083,{110:1,342:1,167:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1});_.Lh=function lyd(a,b,c){return cyd(this,a,b,c)};_.Sh=function myd(a,b,c){return dyd(this,a,b,c)};_.Uh=function nyd(a,b,c){return eyd(this,a,b,c)};_.Wh=function oyd(a){return fyd(this,a)};_.bi=function pyd(a,b){gyd(this,a,b)};_.ii=function qyd(){return pvd(),ivd};_.ki=function ryd(a){hyd(this,a)};_.jh=function syd(){return this.k};_.kh=function tyd(){return iyd(this)};_.Ib=function uyd(){return kyd(this)};_.k=null;var R4=sfb(THe,'ElkGraphElementImpl',739);feb(740,739,{110:1,342:1,167:1,422:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1});_.Lh=function Gyd(a,b,c){return vyd(this,a,b,c)};_.Wh=function Hyd(a){return wyd(this,a)};_.bi=function Iyd(a,b){xyd(this,a,b)};_.ii=function Jyd(){return pvd(),nvd};_.ki=function Kyd(a){yyd(this,a)};_.lh=function Lyd(){return this.f};_.mh=function Myd(){return this.g};_.nh=function Nyd(){return this.i};_.oh=function Oyd(){return this.j};_.ph=function Pyd(a,b){zyd(this,a,b)};_.qh=function Qyd(a,b){Byd(this,a,b)};_.rh=function Ryd(a){Dyd(this,a)};_.sh=function Syd(a){Eyd(this,a)};_.Ib=function Tyd(){return Fyd(this)};_.f=0;_.g=0;_.i=0;_.j=0;var Y4=sfb(THe,'ElkShapeImpl',740);feb(741,740,{110:1,342:1,84:1,167:1,422:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1});_.Lh=function _yd(a,b,c){return Uyd(this,a,b,c)};_.Sh=function azd(a,b,c){return Vyd(this,a,b,c)};_.Uh=function bzd(a,b,c){return Wyd(this,a,b,c)};_.Wh=function czd(a){return Xyd(this,a)};_.bi=function dzd(a,b){Yyd(this,a,b)};_.ii=function ezd(){return pvd(),fvd};_.ki=function fzd(a){Zyd(this,a)};_.hh=function gzd(){return !this.d&&(this.d=new Yie(G4,this,8,5)),this.d};_.ih=function hzd(){return !this.e&&(this.e=new Yie(G4,this,7,4)),this.e};var O4=sfb(THe,'ElkConnectableShapeImpl',741);feb(326,739,{110:1,342:1,74:1,167:1,326:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},rzd);_.Ah=function szd(a){return jzd(this,a)};_.Lh=function tzd(a,b,c){switch(a){case 3:return kzd(this);case 4:return !this.b&&(this.b=new Yie(E4,this,4,7)),this.b;case 5:return !this.c&&(this.c=new Yie(E4,this,5,8)),this.c;case 6:return !this.a&&(this.a=new C5d(F4,this,6,6)),this.a;case 7:return Geb(),!this.b&&(this.b=new Yie(E4,this,4,7)),this.b.i<=1&&(!this.c&&(this.c=new Yie(E4,this,5,8)),this.c.i<=1)?false:true;case 8:return Geb(),nzd(this)?true:false;case 9:return Geb(),ozd(this)?true:false;case 10:return Geb(),!this.b&&(this.b=new Yie(E4,this,4,7)),this.b.i!=0&&(!this.c&&(this.c=new Yie(E4,this,5,8)),this.c.i!=0)?true:false;}return cyd(this,a,b,c)};_.Sh=function uzd(a,b,c){var d;switch(b){case 3:!!this.Cb&&(c=(d=this.Db>>16,d>=0?jzd(this,c):this.Cb.Th(this,-1-d,null,c)));return izd(this,RD(a,27),c);case 4:return !this.b&&(this.b=new Yie(E4,this,4,7)),qLd(this.b,a,c);case 5:return !this.c&&(this.c=new Yie(E4,this,5,8)),qLd(this.c,a,c);case 6:return !this.a&&(this.a=new C5d(F4,this,6,6)),qLd(this.a,a,c);}return dyd(this,a,b,c)};_.Uh=function vzd(a,b,c){switch(b){case 3:return izd(this,null,c);case 4:return !this.b&&(this.b=new Yie(E4,this,4,7)),rLd(this.b,a,c);case 5:return !this.c&&(this.c=new Yie(E4,this,5,8)),rLd(this.c,a,c);case 6:return !this.a&&(this.a=new C5d(F4,this,6,6)),rLd(this.a,a,c);}return eyd(this,a,b,c)};_.Wh=function wzd(a){switch(a){case 3:return !!kzd(this);case 4:return !!this.b&&this.b.i!=0;case 5:return !!this.c&&this.c.i!=0;case 6:return !!this.a&&this.a.i!=0;case 7:return !this.b&&(this.b=new Yie(E4,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new Yie(E4,this,5,8)),this.c.i<=1));case 8:return nzd(this);case 9:return ozd(this);case 10:return !this.b&&(this.b=new Yie(E4,this,4,7)),this.b.i!=0&&(!this.c&&(this.c=new Yie(E4,this,5,8)),this.c.i!=0);}return fyd(this,a)};_.bi=function xzd(a,b){switch(a){case 3:pzd(this,RD(b,27));return;case 4:!this.b&&(this.b=new Yie(E4,this,4,7));sLd(this.b);!this.b&&(this.b=new Yie(E4,this,4,7));YGd(this.b,RD(b,16));return;case 5:!this.c&&(this.c=new Yie(E4,this,5,8));sLd(this.c);!this.c&&(this.c=new Yie(E4,this,5,8));YGd(this.c,RD(b,16));return;case 6:!this.a&&(this.a=new C5d(F4,this,6,6));sLd(this.a);!this.a&&(this.a=new C5d(F4,this,6,6));YGd(this.a,RD(b,16));return;}gyd(this,a,b)};_.ii=function yzd(){return pvd(),gvd};_.ki=function zzd(a){switch(a){case 3:pzd(this,null);return;case 4:!this.b&&(this.b=new Yie(E4,this,4,7));sLd(this.b);return;case 5:!this.c&&(this.c=new Yie(E4,this,5,8));sLd(this.c);return;case 6:!this.a&&(this.a=new C5d(F4,this,6,6));sLd(this.a);return;}hyd(this,a)};_.Ib=function Azd(){return qzd(this)};var P4=sfb(THe,'ElkEdgeImpl',326);feb(452,2083,{110:1,342:1,166:1,452:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},Rzd);_.Ah=function Szd(a){return Czd(this,a)};_.Lh=function Tzd(a,b,c){switch(a){case 1:return this.j;case 2:return this.k;case 3:return this.b;case 4:return this.c;case 5:return !this.a&&(this.a=new XZd(D4,this,5)),this.a;case 6:return Fzd(this);case 7:if(b)return Ezd(this);return this.i;case 8:if(b)return Dzd(this);return this.f;case 9:return !this.g&&(this.g=new Yie(F4,this,9,10)),this.g;case 10:return !this.e&&(this.e=new Yie(F4,this,10,9)),this.e;case 11:return this.d;}return Axd(this,a,b,c)};_.Sh=function Uzd(a,b,c){var d,e,f;switch(b){case 6:!!this.Cb&&(c=(e=this.Db>>16,e>=0?Czd(this,c):this.Cb.Th(this,-1-e,null,c)));return Bzd(this,RD(a,74),c);case 9:return !this.g&&(this.g=new Yie(F4,this,9,10)),qLd(this.g,a,c);case 10:return !this.e&&(this.e=new Yie(F4,this,10,9)),qLd(this.e,a,c);}return f=RD(vYd((d=RD(Ywd(this,16),29),!d?(pvd(),hvd):d),b),69),f.wk().zk(this,Wwd(this),b-AYd((pvd(),hvd)),a,c)};_.Uh=function Vzd(a,b,c){switch(b){case 5:return !this.a&&(this.a=new XZd(D4,this,5)),rLd(this.a,a,c);case 6:return Bzd(this,null,c);case 9:return !this.g&&(this.g=new Yie(F4,this,9,10)),rLd(this.g,a,c);case 10:return !this.e&&(this.e=new Yie(F4,this,10,9)),rLd(this.e,a,c);}return Bxd(this,a,b,c)};_.Wh=function Wzd(a){switch(a){case 1:return this.j!=0;case 2:return this.k!=0;case 3:return this.b!=0;case 4:return this.c!=0;case 5:return !!this.a&&this.a.i!=0;case 6:return !!Fzd(this);case 7:return !!this.i;case 8:return !!this.f;case 9:return !!this.g&&this.g.i!=0;case 10:return !!this.e&&this.e.i!=0;case 11:return this.d!=null;}return Cxd(this,a)};_.bi=function Xzd(a,b){switch(a){case 1:Ozd(this,Kfb(UD(b)));return;case 2:Pzd(this,Kfb(UD(b)));return;case 3:Hzd(this,Kfb(UD(b)));return;case 4:Izd(this,Kfb(UD(b)));return;case 5:!this.a&&(this.a=new XZd(D4,this,5));sLd(this.a);!this.a&&(this.a=new XZd(D4,this,5));YGd(this.a,RD(b,16));return;case 6:Mzd(this,RD(b,74));return;case 7:Lzd(this,RD(b,84));return;case 8:Kzd(this,RD(b,84));return;case 9:!this.g&&(this.g=new Yie(F4,this,9,10));sLd(this.g);!this.g&&(this.g=new Yie(F4,this,9,10));YGd(this.g,RD(b,16));return;case 10:!this.e&&(this.e=new Yie(F4,this,10,9));sLd(this.e);!this.e&&(this.e=new Yie(F4,this,10,9));YGd(this.e,RD(b,16));return;case 11:Jzd(this,WD(b));return;}Dxd(this,a,b)};_.ii=function Yzd(){return pvd(),hvd};_.ki=function Zzd(a){switch(a){case 1:Ozd(this,0);return;case 2:Pzd(this,0);return;case 3:Hzd(this,0);return;case 4:Izd(this,0);return;case 5:!this.a&&(this.a=new XZd(D4,this,5));sLd(this.a);return;case 6:Mzd(this,null);return;case 7:Lzd(this,null);return;case 8:Kzd(this,null);return;case 9:!this.g&&(this.g=new Yie(F4,this,9,10));sLd(this.g);return;case 10:!this.e&&(this.e=new Yie(F4,this,10,9));sLd(this.e);return;case 11:Jzd(this,null);return;}Exd(this,a)};_.Ib=function $zd(){return Qzd(this)};_.b=0;_.c=0;_.d=null;_.j=0;_.k=0;var Q4=sfb(THe,'ElkEdgeSectionImpl',452);feb(158,120,{110:1,94:1,93:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1});_.Lh=function cAd(a,b,c){var d;if(a==0){return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab}return zvd(this,a-AYd(this.ii()),vYd((d=RD(Ywd(this,16),29),!d?this.ii():d),a),b,c)};_.Sh=function dAd(a,b,c){var d,e;if(b==0){return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),qLd(this.Ab,a,c)}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?this.ii():d),b),69),e.wk().zk(this,Wwd(this),b-AYd(this.ii()),a,c)};_.Uh=function eAd(a,b,c){var d,e;if(b==0){return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c)}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?this.ii():d),b),69),e.wk().Ak(this,Wwd(this),b-AYd(this.ii()),a,c)};_.Wh=function fAd(a){var b;if(a==0){return !!this.Ab&&this.Ab.i!=0}return Avd(this,a-AYd(this.ii()),vYd((b=RD(Ywd(this,16),29),!b?this.ii():b),a))};_.Zh=function gAd(a){return _zd(this,a)};_.bi=function hAd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;}Bvd(this,a-AYd(this.ii()),vYd((c=RD(Ywd(this,16),29),!c?this.ii():c),a),b)};_.di=function iAd(a){$wd(this,128,a)};_.ii=function jAd(){return JTd(),xTd};_.ki=function kAd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;}Cvd(this,a-AYd(this.ii()),vYd((b=RD(Ywd(this,16),29),!b?this.ii():b),a))};_.pi=function lAd(){this.Bb|=1};_.qi=function mAd(a){return bAd(this,a)};_.Bb=0;var k8=sfb(SHe,'EModelElementImpl',158);feb(720,158,{110:1,94:1,93:1,480:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1},yAd);_.ri=function zAd(a,b){return tAd(this,a,b)};_.si=function AAd(a){var b,c,d,e,f;if(this.a!=BXd(a)||(a.Bb&256)!=0){throw Adb(new agb(ZHe+a.zb+WHe))}for(d=zYd(a);tYd(d.a).i!=0;){c=RD(N_d(d,0,(b=RD(QHd(tYd(d.a),0),89),f=b.c,ZD(f,90)?RD(f,29):(JTd(),zTd))),29);if(DXd(c)){e=BXd(c).wi().si(c);RD(e,54).ci(a);return e}d=zYd(c)}return (a.D!=null?a.D:a.B)=='java.util.Map$Entry'?new LUd(a):new zUd(a)};_.ti=function BAd(a,b){return uAd(this,a,b)};_.Lh=function CAd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.a;}return zvd(this,a-AYd((JTd(),uTd)),vYd((d=RD(Ywd(this,16),29),!d?uTd:d),a),b,c)};_.Sh=function DAd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),qLd(this.Ab,a,c);case 1:!!this.a&&(c=RD(this.a,54).Th(this,4,t7,c));return rAd(this,RD(a,241),c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),uTd):d),b),69),e.wk().zk(this,Wwd(this),b-AYd((JTd(),uTd)),a,c)};_.Uh=function EAd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c);case 1:return rAd(this,null,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),uTd):d),b),69),e.wk().Ak(this,Wwd(this),b-AYd((JTd(),uTd)),a,c)};_.Wh=function FAd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return !!this.a;}return Avd(this,a-AYd((JTd(),uTd)),vYd((b=RD(Ywd(this,16),29),!b?uTd:b),a))};_.bi=function GAd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:wAd(this,RD(b,241));return;}Bvd(this,a-AYd((JTd(),uTd)),vYd((c=RD(Ywd(this,16),29),!c?uTd:c),a),b)};_.ii=function HAd(){return JTd(),uTd};_.ki=function IAd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:wAd(this,null);return;}Cvd(this,a-AYd((JTd(),uTd)),vYd((b=RD(Ywd(this,16),29),!b?uTd:b),a))};var nAd,oAd,pAd;var i8=sfb(SHe,'EFactoryImpl',720);feb(1037,720,{110:1,2113:1,94:1,93:1,480:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1},KAd);_.ri=function LAd(a,b){switch(a.hk()){case 12:return RD(b,149).Pg();case 13:return jeb(b);default:throw Adb(new agb(VHe+a.xe()+WHe));}};_.si=function MAd(a){var b,c,d,e,f,g,h,i;switch(a.G==-1&&(a.G=(b=BXd(a),b?fZd(b.vi(),a):-1)),a.G){case 4:return f=new hCd,f;case 6:return g=new ACd,g;case 7:return h=new PCd,h;case 8:return d=new rzd,d;case 9:return c=new Xxd,c;case 10:return e=new Rzd,e;case 11:return i=new _Cd,i;default:throw Adb(new agb(ZHe+a.zb+WHe));}};_.ti=function NAd(a,b){switch(a.hk()){case 13:case 12:return null;default:throw Adb(new agb(VHe+a.xe()+WHe));}};var S4=sfb(THe,'ElkGraphFactoryImpl',1037);feb(448,158,{110:1,94:1,93:1,155:1,197:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1});_.Gh=function RAd(){var a,b;b=(a=RD(Ywd(this,16),29),P$d(rYd(!a?this.ii():a)));return b==null?(N2d(),N2d(),M2d):new e3d(this,b)};_.Lh=function SAd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.xe();}return zvd(this,a-AYd(this.ii()),vYd((d=RD(Ywd(this,16),29),!d?this.ii():d),a),b,c)};_.Wh=function TAd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;}return Avd(this,a-AYd(this.ii()),vYd((b=RD(Ywd(this,16),29),!b?this.ii():b),a))};_.bi=function UAd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:this.ui(WD(b));return;}Bvd(this,a-AYd(this.ii()),vYd((c=RD(Ywd(this,16),29),!c?this.ii():c),a),b)};_.ii=function VAd(){return JTd(),yTd};_.ki=function WAd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:this.ui(null);return;}Cvd(this,a-AYd(this.ii()),vYd((b=RD(Ywd(this,16),29),!b?this.ii():b),a))};_.xe=function XAd(){return this.zb};_.ui=function YAd(a){PAd(this,a)};_.Ib=function ZAd(){return QAd(this)};_.zb=null;var o8=sfb(SHe,'ENamedElementImpl',448);feb(184,448,{110:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,54:1,99:1,158:1,184:1,119:1,120:1,690:1},EBd);_.Ah=function GBd(a){return qBd(this,a)};_.Lh=function HBd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.yb;case 3:return this.xb;case 4:return this.sb;case 5:return !this.rb&&(this.rb=new J5d(this,i7,this)),this.rb;case 6:return !this.vb&&(this.vb=new G5d(t7,this,6,7)),this.vb;case 7:if(b)return this.Db>>16==7?RD(this.Cb,241):null;return gBd(this);}return zvd(this,a-AYd((JTd(),CTd)),vYd((d=RD(Ywd(this,16),29),!d?CTd:d),a),b,c)};_.Sh=function IBd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),qLd(this.Ab,a,c);case 4:!!this.sb&&(c=RD(this.sb,54).Th(this,1,n7,c));return hBd(this,RD(a,480),c);case 5:return !this.rb&&(this.rb=new J5d(this,i7,this)),qLd(this.rb,a,c);case 6:return !this.vb&&(this.vb=new G5d(t7,this,6,7)),qLd(this.vb,a,c);case 7:!!this.Cb&&(c=(e=this.Db>>16,e>=0?qBd(this,c):this.Cb.Th(this,-1-e,null,c)));return xvd(this,a,7,c);}return f=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),CTd):d),b),69),f.wk().zk(this,Wwd(this),b-AYd((JTd(),CTd)),a,c)};_.Uh=function JBd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c);case 4:return hBd(this,null,c);case 5:return !this.rb&&(this.rb=new J5d(this,i7,this)),rLd(this.rb,a,c);case 6:return !this.vb&&(this.vb=new G5d(t7,this,6,7)),rLd(this.vb,a,c);case 7:return xvd(this,null,7,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),CTd):d),b),69),e.wk().Ak(this,Wwd(this),b-AYd((JTd(),CTd)),a,c)};_.Wh=function KBd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.yb!=null;case 3:return this.xb!=null;case 4:return !!this.sb;case 5:return !!this.rb&&this.rb.i!=0;case 6:return !!this.vb&&this.vb.i!=0;case 7:return !!gBd(this);}return Avd(this,a-AYd((JTd(),CTd)),vYd((b=RD(Ywd(this,16),29),!b?CTd:b),a))};_.Zh=function LBd(a){var b;b=sBd(this,a);return b?b:_zd(this,a)};_.bi=function MBd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:PAd(this,WD(b));return;case 2:DBd(this,WD(b));return;case 3:CBd(this,WD(b));return;case 4:BBd(this,RD(b,480));return;case 5:!this.rb&&(this.rb=new J5d(this,i7,this));sLd(this.rb);!this.rb&&(this.rb=new J5d(this,i7,this));YGd(this.rb,RD(b,16));return;case 6:!this.vb&&(this.vb=new G5d(t7,this,6,7));sLd(this.vb);!this.vb&&(this.vb=new G5d(t7,this,6,7));YGd(this.vb,RD(b,16));return;}Bvd(this,a-AYd((JTd(),CTd)),vYd((c=RD(Ywd(this,16),29),!c?CTd:c),a),b)};_.ei=function NBd(a){var b,c;if(!!a&&!!this.rb){for(c=new dMd(this.rb);c.e!=c.i.gc();){b=bMd(c);ZD(b,364)&&(RD(b,364).w=null)}}$wd(this,64,a)};_.ii=function OBd(){return JTd(),CTd};_.ki=function PBd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:PAd(this,null);return;case 2:DBd(this,null);return;case 3:CBd(this,null);return;case 4:BBd(this,null);return;case 5:!this.rb&&(this.rb=new J5d(this,i7,this));sLd(this.rb);return;case 6:!this.vb&&(this.vb=new G5d(t7,this,6,7));sLd(this.vb);return;}Cvd(this,a-AYd((JTd(),CTd)),vYd((b=RD(Ywd(this,16),29),!b?CTd:b),a))};_.pi=function QBd(){rBd(this)};_.vi=function RBd(){return !this.rb&&(this.rb=new J5d(this,i7,this)),this.rb};_.wi=function SBd(){return this.sb};_.xi=function TBd(){return this.ub};_.yi=function UBd(){return this.xb};_.zi=function VBd(){return this.yb};_.Ai=function WBd(a){this.ub=a};_.Ib=function XBd(){var a;if((this.Db&64)!=0)return QAd(this);a=new Shb(QAd(this));a.a+=' (nsURI: ';Nhb(a,this.yb);a.a+=', nsPrefix: ';Nhb(a,this.xb);a.a+=')';return a.a};_.xb=null;_.yb=null;var $Ad;var y8=sfb(SHe,'EPackageImpl',184);feb(569,184,{110:1,2115:1,569:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,54:1,99:1,158:1,184:1,119:1,120:1,690:1},_Bd);_.q=false;_.r=false;var YBd=false;var T4=sfb(THe,'ElkGraphPackageImpl',569);feb(366,740,{110:1,342:1,167:1,135:1,422:1,366:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},hCd);_.Ah=function iCd(a){return cCd(this,a)};_.Lh=function jCd(a,b,c){switch(a){case 7:return dCd(this);case 8:return this.a;}return vyd(this,a,b,c)};_.Sh=function kCd(a,b,c){var d;switch(b){case 7:!!this.Cb&&(c=(d=this.Db>>16,d>=0?cCd(this,c):this.Cb.Th(this,-1-d,null,c)));return bCd(this,RD(a,167),c);}return dyd(this,a,b,c)};_.Uh=function lCd(a,b,c){if(b==7){return bCd(this,null,c)}return eyd(this,a,b,c)};_.Wh=function mCd(a){switch(a){case 7:return !!dCd(this);case 8:return !lhb('',this.a);}return wyd(this,a)};_.bi=function nCd(a,b){switch(a){case 7:eCd(this,RD(b,167));return;case 8:fCd(this,WD(b));return;}xyd(this,a,b)};_.ii=function oCd(){return pvd(),jvd};_.ki=function pCd(a){switch(a){case 7:eCd(this,null);return;case 8:fCd(this,'');return;}yyd(this,a)};_.Ib=function qCd(){return gCd(this)};_.a='';var U4=sfb(THe,'ElkLabelImpl',366);feb(207,741,{110:1,342:1,84:1,167:1,27:1,422:1,207:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},ACd);_.Ah=function BCd(a){return sCd(this,a)};_.Lh=function CCd(a,b,c){switch(a){case 9:return !this.c&&(this.c=new C5d(K4,this,9,9)),this.c;case 10:return !this.a&&(this.a=new C5d(J4,this,10,11)),this.a;case 11:return vCd(this);case 12:return !this.b&&(this.b=new C5d(G4,this,12,3)),this.b;case 13:return Geb(),!this.a&&(this.a=new C5d(J4,this,10,11)),this.a.i>0?true:false;}return Uyd(this,a,b,c)};_.Sh=function DCd(a,b,c){var d;switch(b){case 9:return !this.c&&(this.c=new C5d(K4,this,9,9)),qLd(this.c,a,c);case 10:return !this.a&&(this.a=new C5d(J4,this,10,11)),qLd(this.a,a,c);case 11:!!this.Cb&&(c=(d=this.Db>>16,d>=0?sCd(this,c):this.Cb.Th(this,-1-d,null,c)));return rCd(this,RD(a,27),c);case 12:return !this.b&&(this.b=new C5d(G4,this,12,3)),qLd(this.b,a,c);}return Vyd(this,a,b,c)};_.Uh=function ECd(a,b,c){switch(b){case 9:return !this.c&&(this.c=new C5d(K4,this,9,9)),rLd(this.c,a,c);case 10:return !this.a&&(this.a=new C5d(J4,this,10,11)),rLd(this.a,a,c);case 11:return rCd(this,null,c);case 12:return !this.b&&(this.b=new C5d(G4,this,12,3)),rLd(this.b,a,c);}return Wyd(this,a,b,c)};_.Wh=function FCd(a){switch(a){case 9:return !!this.c&&this.c.i!=0;case 10:return !!this.a&&this.a.i!=0;case 11:return !!vCd(this);case 12:return !!this.b&&this.b.i!=0;case 13:return !this.a&&(this.a=new C5d(J4,this,10,11)),this.a.i>0;}return Xyd(this,a)};_.bi=function GCd(a,b){switch(a){case 9:!this.c&&(this.c=new C5d(K4,this,9,9));sLd(this.c);!this.c&&(this.c=new C5d(K4,this,9,9));YGd(this.c,RD(b,16));return;case 10:!this.a&&(this.a=new C5d(J4,this,10,11));sLd(this.a);!this.a&&(this.a=new C5d(J4,this,10,11));YGd(this.a,RD(b,16));return;case 11:yCd(this,RD(b,27));return;case 12:!this.b&&(this.b=new C5d(G4,this,12,3));sLd(this.b);!this.b&&(this.b=new C5d(G4,this,12,3));YGd(this.b,RD(b,16));return;}Yyd(this,a,b)};_.ii=function HCd(){return pvd(),kvd};_.ki=function ICd(a){switch(a){case 9:!this.c&&(this.c=new C5d(K4,this,9,9));sLd(this.c);return;case 10:!this.a&&(this.a=new C5d(J4,this,10,11));sLd(this.a);return;case 11:yCd(this,null);return;case 12:!this.b&&(this.b=new C5d(G4,this,12,3));sLd(this.b);return;}Zyd(this,a)};_.Ib=function JCd(){return zCd(this)};var V4=sfb(THe,'ElkNodeImpl',207);feb(193,741,{110:1,342:1,84:1,167:1,123:1,422:1,193:1,96:1,94:1,93:1,58:1,114:1,54:1,99:1,119:1,120:1},PCd);_.Ah=function QCd(a){return LCd(this,a)};_.Lh=function RCd(a,b,c){if(a==9){return MCd(this)}return Uyd(this,a,b,c)};_.Sh=function SCd(a,b,c){var d;switch(b){case 9:!!this.Cb&&(c=(d=this.Db>>16,d>=0?LCd(this,c):this.Cb.Th(this,-1-d,null,c)));return KCd(this,RD(a,27),c);}return Vyd(this,a,b,c)};_.Uh=function TCd(a,b,c){if(b==9){return KCd(this,null,c)}return Wyd(this,a,b,c)};_.Wh=function UCd(a){if(a==9){return !!MCd(this)}return Xyd(this,a)};_.bi=function VCd(a,b){switch(a){case 9:NCd(this,RD(b,27));return;}Yyd(this,a,b)};_.ii=function WCd(){return pvd(),lvd};_.ki=function XCd(a){switch(a){case 9:NCd(this,null);return;}Zyd(this,a)};_.Ib=function YCd(){return OCd(this)};var W4=sfb(THe,'ElkPortImpl',193);var O6=ufb(sIe,'BasicEMap/Entry');feb(1122,120,{110:1,44:1,94:1,93:1,136:1,58:1,114:1,54:1,99:1,119:1,120:1},_Cd);_.Fb=function fDd(a){return this===a};_.ld=function hDd(){return this.b};_.Hb=function jDd(){return kFb(this)};_.Di=function lDd(a){ZCd(this,RD(a,149))};_.Lh=function aDd(a,b,c){switch(a){case 0:return this.b;case 1:return this.c;}return Dvd(this,a,b,c)};_.Wh=function bDd(a){switch(a){case 0:return !!this.b;case 1:return this.c!=null;}return Kvd(this,a)};_.bi=function cDd(a,b){switch(a){case 0:ZCd(this,RD(b,149));return;case 1:$Cd(this,b);return;}Wvd(this,a,b)};_.ii=function dDd(){return pvd(),mvd};_.ki=function eDd(a){switch(a){case 0:ZCd(this,null);return;case 1:$Cd(this,null);return;}$vd(this,a)};_.Bi=function gDd(){var a;if(this.a==-1){a=this.b;this.a=!a?0:tb(a)}return this.a};_.md=function iDd(){return this.c};_.Ci=function kDd(a){this.a=a};_.nd=function mDd(a){var b;b=this.c;$Cd(this,a);return b};_.Ib=function nDd(){var a;if((this.Db&64)!=0)return awd(this);a=new bib;Zhb(Zhb(Zhb(a,this.b?this.b.Pg():vve),SAe),Ghb(this.c));return a.a};_.a=-1;_.c=null;var X4=sfb(THe,'ElkPropertyToValueMapEntryImpl',1122);feb(996,1,{},BDd);var Z4=sfb(vIe,'JsonAdapter',996);feb(216,63,swe,CDd);var $4=sfb(vIe,'JsonImportException',216);feb(868,1,{},IEd);var O5=sfb(vIe,'JsonImporter',868);feb(903,1,{},JEd);var _4=sfb(vIe,'JsonImporter/lambda$0$Type',903);feb(904,1,{},KEd);var a5=sfb(vIe,'JsonImporter/lambda$1$Type',904);feb(912,1,{},LEd);var b5=sfb(vIe,'JsonImporter/lambda$10$Type',912);feb(914,1,{},MEd);var c5=sfb(vIe,'JsonImporter/lambda$11$Type',914);feb(915,1,{},NEd);var d5=sfb(vIe,'JsonImporter/lambda$12$Type',915);feb(921,1,{},OEd);var e5=sfb(vIe,'JsonImporter/lambda$13$Type',921);feb(920,1,{},PEd);var f5=sfb(vIe,'JsonImporter/lambda$14$Type',920);feb(916,1,{},QEd);var g5=sfb(vIe,'JsonImporter/lambda$15$Type',916);feb(917,1,{},REd);var h5=sfb(vIe,'JsonImporter/lambda$16$Type',917);feb(918,1,{},SEd);var i5=sfb(vIe,'JsonImporter/lambda$17$Type',918);feb(919,1,{},TEd);var j5=sfb(vIe,'JsonImporter/lambda$18$Type',919);feb(924,1,{},UEd);var k5=sfb(vIe,'JsonImporter/lambda$19$Type',924);feb(905,1,{},VEd);var l5=sfb(vIe,'JsonImporter/lambda$2$Type',905);feb(922,1,{},WEd);var m5=sfb(vIe,'JsonImporter/lambda$20$Type',922);feb(923,1,{},XEd);var n5=sfb(vIe,'JsonImporter/lambda$21$Type',923);feb(927,1,{},YEd);var o5=sfb(vIe,'JsonImporter/lambda$22$Type',927);feb(925,1,{},ZEd);var p5=sfb(vIe,'JsonImporter/lambda$23$Type',925);feb(926,1,{},$Ed);var q5=sfb(vIe,'JsonImporter/lambda$24$Type',926);feb(929,1,{},_Ed);var r5=sfb(vIe,'JsonImporter/lambda$25$Type',929);feb(928,1,{},aFd);var s5=sfb(vIe,'JsonImporter/lambda$26$Type',928);feb(930,1,Qve,bFd);_.Cd=function cFd(a){_Dd(this.b,this.a,WD(a))};var t5=sfb(vIe,'JsonImporter/lambda$27$Type',930);feb(931,1,Qve,dFd);_.Cd=function eFd(a){aEd(this.b,this.a,WD(a))};var u5=sfb(vIe,'JsonImporter/lambda$28$Type',931);feb(932,1,{},fFd);var v5=sfb(vIe,'JsonImporter/lambda$29$Type',932);feb(908,1,{},gFd);var w5=sfb(vIe,'JsonImporter/lambda$3$Type',908);feb(933,1,{},hFd);var x5=sfb(vIe,'JsonImporter/lambda$30$Type',933);feb(934,1,{},iFd);var y5=sfb(vIe,'JsonImporter/lambda$31$Type',934);feb(935,1,{},jFd);var z5=sfb(vIe,'JsonImporter/lambda$32$Type',935);feb(936,1,{},kFd);var A5=sfb(vIe,'JsonImporter/lambda$33$Type',936);feb(937,1,{},lFd);var B5=sfb(vIe,'JsonImporter/lambda$34$Type',937);feb(870,1,{},nFd);var C5=sfb(vIe,'JsonImporter/lambda$35$Type',870);feb(941,1,{},pFd);var D5=sfb(vIe,'JsonImporter/lambda$36$Type',941);feb(938,1,Qve,qFd);_.Cd=function rFd(a){jEd(this.a,RD(a,377))};var E5=sfb(vIe,'JsonImporter/lambda$37$Type',938);feb(939,1,Qve,sFd);_.Cd=function tFd(a){kEd(this.a,this.b,RD(a,166))};var F5=sfb(vIe,'JsonImporter/lambda$38$Type',939);feb(940,1,Qve,uFd);_.Cd=function vFd(a){lEd(this.a,this.b,RD(a,166))};var G5=sfb(vIe,'JsonImporter/lambda$39$Type',940);feb(906,1,{},wFd);var H5=sfb(vIe,'JsonImporter/lambda$4$Type',906);feb(942,1,Qve,xFd);_.Cd=function yFd(a){mEd(this.a,RD(a,8))};var I5=sfb(vIe,'JsonImporter/lambda$40$Type',942);feb(907,1,{},zFd);var J5=sfb(vIe,'JsonImporter/lambda$5$Type',907);feb(911,1,{},AFd);var K5=sfb(vIe,'JsonImporter/lambda$6$Type',911);feb(909,1,{},BFd);var L5=sfb(vIe,'JsonImporter/lambda$7$Type',909);feb(910,1,{},CFd);var M5=sfb(vIe,'JsonImporter/lambda$8$Type',910);feb(913,1,{},DFd);var N5=sfb(vIe,'JsonImporter/lambda$9$Type',913);feb(961,1,Qve,MFd);_.Cd=function NFd(a){oDd(this.a,new OC(WD(a)))};var P5=sfb(vIe,'JsonMetaDataConverter/lambda$0$Type',961);feb(962,1,Qve,OFd);_.Cd=function PFd(a){IFd(this.a,RD(a,245))};var Q5=sfb(vIe,'JsonMetaDataConverter/lambda$1$Type',962);feb(963,1,Qve,QFd);_.Cd=function RFd(a){JFd(this.a,RD(a,143))};var R5=sfb(vIe,'JsonMetaDataConverter/lambda$2$Type',963);feb(964,1,Qve,SFd);_.Cd=function TFd(a){KFd(this.a,RD(a,170))};var S5=sfb(vIe,'JsonMetaDataConverter/lambda$3$Type',964);feb(245,22,{3:1,34:1,22:1,245:1},bGd);var UFd,VFd,WFd,XFd,YFd,ZFd,$Fd,_Fd;var T5=tfb(jze,'GraphFeature',245,WI,dGd,cGd);var eGd;feb(11,1,{34:1,149:1},jGd,kGd,lGd,mGd);_.Fd=function nGd(a){return gGd(this,RD(a,149))};_.Fb=function oGd(a){return hGd(this,a)};_.Sg=function pGd(){return iGd(this)};_.Pg=function qGd(){return this.b};_.Hb=function rGd(){return ohb(this.b)};_.Ib=function sGd(){return this.b};var Y5=sfb(jze,'Property',11);feb(671,1,fye,uGd);_.Ne=function vGd(a,b){return tGd(this,RD(a,96),RD(b,96))};_.Fb=function wGd(a){return this===a};_.Oe=function xGd(){return new Frb(this)};var X5=sfb(jze,'PropertyHolderComparator',671);feb(709,1,Ave,QGd);_.Nb=function RGd(a){Ztb(this,a)};_.Pb=function TGd(){return PGd(this)};_.Qb=function UGd(){$tb()};_.Ob=function SGd(){return !!this.a};var Z5=sfb(KIe,'ElkGraphUtil/AncestorIterator',709);var Y6=ufb(sIe,'EList');feb(70,56,{20:1,31:1,56:1,16:1,15:1,70:1,61:1});_.bd=function hHd(a,b){VGd(this,a,b)};_.Fc=function iHd(a){return WGd(this,a)};_.cd=function jHd(a,b){return XGd(this,a,b)};_.Gc=function kHd(a){return YGd(this,a)};_.Ii=function lHd(){return new yMd(this)};_.Ji=function mHd(){return new BMd(this)};_.Ki=function nHd(a){return ZGd(this,a)};_.Li=function oHd(){return true};_.Mi=function pHd(a,b){};_.Ni=function qHd(){};_.Oi=function rHd(a,b){$Gd(this,a,b)};_.Pi=function sHd(a,b,c){};_.Qi=function tHd(a,b){};_.Ri=function uHd(a,b,c){};_.Fb=function vHd(a){return _Gd(this,a)};_.Hb=function wHd(){return cHd(this)};_.Si=function xHd(){return false};_.Kc=function yHd(){return new dMd(this)};_.ed=function zHd(){return new mMd(this)};_.fd=function AHd(a){var b;b=this.gc();if(a<0||a>b)throw Adb(new aMd(a,b));return new nMd(this,a)};_.Ui=function BHd(a,b){this.Ti(a,this.dd(b))};_.Mc=function CHd(a){return dHd(this,a)};_.Wi=function DHd(a,b){return b};_.hd=function EHd(a,b){return eHd(this,a,b)};_.Ib=function FHd(){return fHd(this)};_.Yi=function GHd(){return true};_.Zi=function HHd(a,b){return gHd(this,b)};var u6=sfb(sIe,'AbstractEList',70);feb(66,70,PIe,YHd,ZHd,$Hd);_.Ei=function _Hd(a,b){return IHd(this,a,b)};_.Fi=function aId(a){return JHd(this,a)};_.Gi=function bId(a,b){KHd(this,a,b)};_.Hi=function cId(a){LHd(this,a)};_.$i=function dId(a){return NHd(this,a)};_.$b=function eId(){OHd(this)};_.Hc=function fId(a){return PHd(this,a)};_.Xb=function gId(a){return QHd(this,a)};_._i=function hId(a){var b,c,d;++this.j;c=this.g==null?0:this.g.length;if(a>c){d=this.g;b=c+(c/2|0)+4;b=0){this.gd(b);return true}else{return false}};_.Xi=function LJd(a,b){return this.Dj(a,this.Zi(a,b))};_.gc=function MJd(){return this.Ej()};_.Pc=function NJd(){return this.Fj()};_.Qc=function OJd(a){return this.Gj(a)};_.Ib=function PJd(){return this.Hj()};var R6=sfb(sIe,'DelegatingEList',2093);feb(2094,2093,FJe);_.Ei=function XJd(a,b){return QJd(this,a,b)};_.Fi=function YJd(a){return this.Ei(this.Ej(),a)};_.Gi=function ZJd(a,b){RJd(this,a,b)};_.Hi=function $Jd(a){SJd(this,a)};_.Li=function _Jd(){return !this.Mj()};_.$b=function aKd(){VJd(this)};_.Ij=function bKd(a,b,c,d,e){return new aLd(this,a,b,c,d,e)};_.Jj=function cKd(a){qvd(this.jj(),a)};_.Kj=function dKd(){return null};_.Lj=function eKd(){return -1};_.jj=function fKd(){return null};_.Mj=function gKd(){return false};_.Nj=function hKd(a,b){return b};_.Oj=function iKd(a,b){return b};_.Pj=function jKd(){return false};_.Qj=function kKd(){return !this.Aj()};_.Ti=function lKd(a,b){var c,d;if(this.Pj()){d=this.Qj();c=bJd(this,a,b);this.Jj(this.Ij(7,sgb(b),c,a,d));return c}else{return bJd(this,a,b)}};_.gd=function mKd(a){var b,c,d,e;if(this.Pj()){c=null;d=this.Qj();b=this.Ij(4,e=cJd(this,a),null,a,d);if(this.Mj()&&!!e){c=this.Oj(e,c);if(!c){this.Jj(b)}else{c.nj(b);c.oj()}}else{if(!c){this.Jj(b)}else{c.nj(b);c.oj()}}return e}else{e=cJd(this,a);if(this.Mj()&&!!e){c=this.Oj(e,null);!!c&&c.oj()}return e}};_.Xi=function nKd(a,b){return WJd(this,a,b)};var i6=sfb(JHe,'DelegatingNotifyingListImpl',2094);feb(152,1,GJe);_.nj=function PKd(a){return oKd(this,a)};_.oj=function QKd(){pKd(this)};_.gj=function RKd(){return this.d};_.Kj=function SKd(){return null};_.Rj=function TKd(){return null};_.hj=function UKd(a){return -1};_.ij=function VKd(){return yKd(this)};_.jj=function WKd(){return null};_.kj=function XKd(){return HKd(this)};_.lj=function YKd(){return this.o<0?this.o<-2?-2-this.o-1:-1:this.o};_.Sj=function ZKd(){return false};_.mj=function $Kd(a){var b,c,d,e,f,g,h,i,j,k,l;switch(this.d){case 1:case 2:{e=a.gj();switch(e){case 1:case 2:{f=a.jj();if(dE(f)===dE(this.jj())&&this.hj(null)==a.hj(null)){this.g=a.ij();a.gj()==1&&(this.d=1);return true}}}}case 4:{e=a.gj();switch(e){case 4:{f=a.jj();if(dE(f)===dE(this.jj())&&this.hj(null)==a.hj(null)){j=JKd(this);i=this.o<0?this.o<-2?-2-this.o-1:-1:this.o;g=a.lj();this.d=6;l=new ZHd(2);if(i<=g){WGd(l,this.n);WGd(l,a.kj());this.g=cD(WC(kE,1),Pwe,28,15,[this.o=i,g+1])}else{WGd(l,a.kj());WGd(l,this.n);this.g=cD(WC(kE,1),Pwe,28,15,[this.o=g,i])}this.n=l;j||(this.o=-2-this.o-1);return true}break}}break}case 6:{e=a.gj();switch(e){case 4:{f=a.jj();if(dE(f)===dE(this.jj())&&this.hj(null)==a.hj(null)){j=JKd(this);g=a.lj();k=RD(this.g,53);d=$C(kE,Pwe,28,k.length+1,15,1);b=0;while(b>>0,b.toString(16)));d.a+=' (eventType: ';switch(this.d){case 1:{d.a+='SET';break}case 2:{d.a+='UNSET';break}case 3:{d.a+='ADD';break}case 5:{d.a+='ADD_MANY';break}case 4:{d.a+='REMOVE';break}case 6:{d.a+='REMOVE_MANY';break}case 7:{d.a+='MOVE';break}case 8:{d.a+='REMOVING_ADAPTER';break}case 9:{d.a+='RESOLVE';break}default:{Lhb(d,this.d);break}}IKd(this)&&(d.a+=', touch: true',d);d.a+=', position: ';Lhb(d,this.o<0?this.o<-2?-2-this.o-1:-1:this.o);d.a+=', notifier: ';Mhb(d,this.jj());d.a+=', feature: ';Mhb(d,this.Kj());d.a+=', oldValue: ';Mhb(d,HKd(this));d.a+=', newValue: ';if(this.d==6&&ZD(this.g,53)){c=RD(this.g,53);d.a+='[';for(a=0;a10){if(!this.b||this.c.j!=this.a){this.b=new btb(this);this.a=this.j}return Zsb(this.b,a)}else{return PHd(this,a)}};_.Yi=function _Ld(){return true};_.a=0;var o6=sfb(sIe,'AbstractEList/1',966);feb(302,77,lxe,aMd);var p6=sfb(sIe,'AbstractEList/BasicIndexOutOfBoundsException',302);feb(37,1,Ave,dMd);_.Nb=function gMd(a){Ztb(this,a)};_.Xj=function eMd(){if(this.i.j!=this.f){throw Adb(new Jrb)}};_.Yj=function fMd(){return bMd(this)};_.Ob=function hMd(){return this.e!=this.i.gc()};_.Pb=function iMd(){return this.Yj()};_.Qb=function jMd(){cMd(this)};_.e=0;_.f=0;_.g=-1;var q6=sfb(sIe,'AbstractEList/EIterator',37);feb(286,37,Jve,mMd,nMd);_.Qb=function vMd(){cMd(this)};_.Rb=function oMd(a){kMd(this,a)};_.Zj=function pMd(){var b;try{b=this.d.Xb(--this.e);this.Xj();this.g=this.e;return b}catch(a){a=zdb(a);if(ZD(a,77)){this.Xj();throw Adb(new Dvb)}else throw Adb(a)}};_.$j=function qMd(a){lMd(this,a)};_.Sb=function rMd(){return this.e!=0};_.Tb=function sMd(){return this.e};_.Ub=function tMd(){return this.Zj()};_.Vb=function uMd(){return this.e-1};_.Wb=function wMd(a){this.$j(a)};var r6=sfb(sIe,'AbstractEList/EListIterator',286);feb(355,37,Ave,yMd);_.Yj=function zMd(){return xMd(this)};_.Qb=function AMd(){throw Adb(new jib)};var s6=sfb(sIe,'AbstractEList/NonResolvingEIterator',355);feb(398,286,Jve,BMd,CMd);_.Rb=function DMd(a){throw Adb(new jib)};_.Yj=function EMd(){var b;try{b=this.c.Vi(this.e);this.Xj();this.g=this.e++;return b}catch(a){a=zdb(a);if(ZD(a,77)){this.Xj();throw Adb(new Dvb)}else throw Adb(a)}};_.Zj=function FMd(){var b;try{b=this.c.Vi(--this.e);this.Xj();this.g=this.e;return b}catch(a){a=zdb(a);if(ZD(a,77)){this.Xj();throw Adb(new Dvb)}else throw Adb(a)}};_.Qb=function GMd(){throw Adb(new jib)};_.Wb=function HMd(a){throw Adb(new jib)};var t6=sfb(sIe,'AbstractEList/NonResolvingEListIterator',398);feb(2080,70,JJe);_.Ei=function PMd(a,b){var c,d,e,f,g,h,i,j,k,l,m;e=b.gc();if(e!=0){j=RD(Ywd(this.a,4),129);k=j==null?0:j.length;m=k+e;d=NMd(this,m);l=k-a;l>0&&hib(j,a,d,a+e,l);i=b.Kc();for(g=0;gc)throw Adb(new aMd(a,c));return new wNd(this,a)};_.$b=function WMd(){var a,b;++this.j;a=RD(Ywd(this.a,4),129);b=a==null?0:a.length;Bde(this,null);$Gd(this,b,a)};_.Hc=function XMd(a){var b,c,d,e,f;b=RD(Ywd(this.a,4),129);if(b!=null){if(a!=null){for(d=b,e=0,f=d.length;e=c)throw Adb(new aMd(a,c));return b[a]};_.dd=function ZMd(a){var b,c,d;b=RD(Ywd(this.a,4),129);if(b!=null){if(a!=null){for(c=0,d=b.length;cc)throw Adb(new aMd(a,c));return new oNd(this,a)};_.Ti=function cNd(a,b){var c,d,e;c=MMd(this);e=c==null?0:c.length;if(a>=e)throw Adb(new veb(MIe+a+NIe+e));if(b>=e)throw Adb(new veb(OIe+b+NIe+e));d=c[b];if(a!=b){a0&&hib(a,0,b,0,c);return b};_.Qc=function iNd(a){var b,c,d;b=RD(Ywd(this.a,4),129);d=b==null?0:b.length;if(d>0){if(a.lengthd&&bD(a,d,null);return a};var JMd;var A6=sfb(sIe,'ArrayDelegatingEList',2080);feb(1051,37,Ave,jNd);_.Xj=function kNd(){if(this.b.j!=this.f||dE(RD(Ywd(this.b.a,4),129))!==dE(this.a)){throw Adb(new Jrb)}};_.Qb=function lNd(){cMd(this);this.a=RD(Ywd(this.b.a,4),129)};var w6=sfb(sIe,'ArrayDelegatingEList/EIterator',1051);feb(722,286,Jve,nNd,oNd);_.Xj=function pNd(){if(this.b.j!=this.f||dE(RD(Ywd(this.b.a,4),129))!==dE(this.a)){throw Adb(new Jrb)}};_.$j=function qNd(a){lMd(this,a);this.a=RD(Ywd(this.b.a,4),129)};_.Qb=function rNd(){cMd(this);this.a=RD(Ywd(this.b.a,4),129)};var x6=sfb(sIe,'ArrayDelegatingEList/EListIterator',722);feb(1052,355,Ave,sNd);_.Xj=function tNd(){if(this.b.j!=this.f||dE(RD(Ywd(this.b.a,4),129))!==dE(this.a)){throw Adb(new Jrb)}};var y6=sfb(sIe,'ArrayDelegatingEList/NonResolvingEIterator',1052);feb(723,398,Jve,vNd,wNd);_.Xj=function xNd(){if(this.b.j!=this.f||dE(RD(Ywd(this.b.a,4),129))!==dE(this.a)){throw Adb(new Jrb)}};var z6=sfb(sIe,'ArrayDelegatingEList/NonResolvingEListIterator',723);feb(615,302,lxe,yNd);var B6=sfb(sIe,'BasicEList/BasicIndexOutOfBoundsException',615);feb(710,66,PIe,zNd);_.bd=function ANd(a,b){throw Adb(new jib)};_.Fc=function BNd(a){throw Adb(new jib)};_.cd=function CNd(a,b){throw Adb(new jib)};_.Gc=function DNd(a){throw Adb(new jib)};_.$b=function ENd(){throw Adb(new jib)};_._i=function FNd(a){throw Adb(new jib)};_.Kc=function GNd(){return this.Ii()};_.ed=function HNd(){return this.Ji()};_.fd=function INd(a){return this.Ki(a)};_.Ti=function JNd(a,b){throw Adb(new jib)};_.Ui=function KNd(a,b){throw Adb(new jib)};_.gd=function LNd(a){throw Adb(new jib)};_.Mc=function MNd(a){throw Adb(new jib)};_.hd=function NNd(a,b){throw Adb(new jib)};var C6=sfb(sIe,'BasicEList/UnmodifiableEList',710);feb(721,1,{3:1,20:1,16:1,15:1,61:1,597:1});_.bd=function mOd(a,b){ONd(this,a,RD(b,44))};_.Fc=function nOd(a){return PNd(this,RD(a,44))};_.Jc=function vOd(a){xgb(this,a)};_.Xb=function wOd(a){return RD(QHd(this.c,a),136)};_.Ti=function FOd(a,b){return RD(this.c.Ti(a,b),44)};_.Ui=function GOd(a,b){eOd(this,a,RD(b,44))};_.Lc=function JOd(){return new SDb(null,new Swb(this,16))};_.gd=function KOd(a){return RD(this.c.gd(a),44)};_.hd=function MOd(a,b){return kOd(this,a,RD(b,44))};_.jd=function OOd(a){tvb(this,a)};_.Nc=function POd(){return new Swb(this,16)};_.Oc=function QOd(){return new SDb(null,new Swb(this,16))};_.cd=function oOd(a,b){return this.c.cd(a,b)};_.Gc=function pOd(a){return this.c.Gc(a)};_.$b=function qOd(){this.c.$b()};_.Hc=function rOd(a){return this.c.Hc(a)};_.Ic=function sOd(a){return Be(this.c,a)};_._j=function tOd(){var a,b,c;if(this.d==null){this.d=$C(D6,KJe,66,2*this.f+1,0,1);c=this.e;this.f=0;for(b=this.c.Kc();b.e!=b.i.gc();){a=RD(b.Yj(),136);UNd(this,a)}this.e=c}};_.Fb=function uOd(a){return ZNd(this,a)};_.Hb=function xOd(){return cHd(this.c)};_.dd=function yOd(a){return this.c.dd(a)};_.ak=function zOd(){this.c=new YOd(this)};_.dc=function AOd(){return this.f==0};_.Kc=function BOd(){return this.c.Kc()};_.ed=function COd(){return this.c.ed()};_.fd=function DOd(a){return this.c.fd(a)};_.bk=function EOd(){return dOd(this)};_.ck=function HOd(a,b,c){return new ZPd(a,b,c)};_.dk=function IOd(){return new cPd};_.Mc=function LOd(a){return hOd(this,a)};_.gc=function NOd(){return this.f};_.kd=function ROd(a,b){return new Rkb(this.c,a,b)};_.Pc=function SOd(){return this.c.Pc()};_.Qc=function TOd(a){return this.c.Qc(a)};_.Ib=function UOd(){return fHd(this.c)};_.e=0;_.f=0;var Q6=sfb(sIe,'BasicEMap',721);feb(1046,66,PIe,YOd);_.Mi=function ZOd(a,b){VOd(this,RD(b,136))};_.Pi=function _Od(a,b,c){var d;++(d=this,RD(b,136),d).a.e};_.Qi=function aPd(a,b){WOd(this,RD(b,136))};_.Ri=function bPd(a,b,c){XOd(this,RD(b,136),RD(c,136))};_.Oi=function $Od(a,b){TNd(this.a)};var E6=sfb(sIe,'BasicEMap/1',1046);feb(1047,66,PIe,cPd);_.aj=function dPd(a){return $C(N6,LJe,621,a,0,1)};var F6=sfb(sIe,'BasicEMap/2',1047);feb(1048,Eve,Fve,ePd);_.$b=function fPd(){this.a.c.$b()};_.Hc=function gPd(a){return QNd(this.a,a)};_.Kc=function hPd(){return this.a.f==0?(jQd(),iQd.a):new DPd(this.a)};_.Mc=function iPd(a){var b;b=this.a.f;jOd(this.a,a);return this.a.f!=b};_.gc=function jPd(){return this.a.f};var G6=sfb(sIe,'BasicEMap/3',1048);feb(1049,31,Dve,kPd);_.$b=function lPd(){this.a.c.$b()};_.Hc=function mPd(a){return RNd(this.a,a)};_.Kc=function nPd(){return this.a.f==0?(jQd(),iQd.a):new FPd(this.a)};_.gc=function oPd(){return this.a.f};var H6=sfb(sIe,'BasicEMap/4',1049);feb(1050,Eve,Fve,qPd);_.$b=function rPd(){this.a.c.$b()};_.Hc=function sPd(a){var b,c,d,e,f,g,h,i,j;if(this.a.f>0&&ZD(a,44)){this.a._j();i=RD(a,44);h=i.ld();e=h==null?0:tb(h);f=bOd(this.a,e);b=this.a.d[f];if(b){c=RD(b.g,379);j=b.i;for(g=0;g'+this.c};_.a=0;var N6=sfb(sIe,'BasicEMap/EntryImpl',621);feb(546,1,{},hQd);var P6=sfb(sIe,'BasicEMap/View',546);var iQd;feb(783,1,{});_.Fb=function xQd(a){return Rt((yob(),vob),a)};_.Hb=function yQd(){return Cob((yob(),vob))};_.Ib=function zQd(){return Fe((yob(),vob))};var V6=sfb(sIe,'ECollections/BasicEmptyUnmodifiableEList',783);feb(1348,1,Jve,AQd);_.Nb=function CQd(a){Ztb(this,a)};_.Rb=function BQd(a){throw Adb(new jib)};_.Ob=function DQd(){return false};_.Sb=function EQd(){return false};_.Pb=function FQd(){throw Adb(new Dvb)};_.Tb=function GQd(){return 0};_.Ub=function HQd(){throw Adb(new Dvb)};_.Vb=function IQd(){return -1};_.Qb=function JQd(){throw Adb(new jib)};_.Wb=function KQd(a){throw Adb(new jib)};var U6=sfb(sIe,'ECollections/BasicEmptyUnmodifiableEList/1',1348);feb(1346,783,{20:1,16:1,15:1,61:1},LQd);_.bd=function MQd(a,b){mQd()};_.Fc=function NQd(a){return nQd()};_.cd=function OQd(a,b){return oQd()};_.Gc=function PQd(a){return pQd()};_.$b=function QQd(){qQd()};_.Hc=function RQd(a){return false};_.Ic=function SQd(a){return false};_.Jc=function TQd(a){xgb(this,a)};_.Xb=function UQd(a){return Iob((yob(),vob,a)),null};_.dd=function VQd(a){return -1};_.dc=function WQd(){return true};_.Kc=function XQd(){return this.a};_.ed=function YQd(){return this.a};_.fd=function ZQd(a){return this.a};_.Ti=function $Qd(a,b){return rQd()};_.Ui=function _Qd(a,b){sQd()};_.Lc=function aRd(){return new SDb(null,new Swb(this,16))};_.gd=function bRd(a){return tQd()};_.Mc=function cRd(a){return uQd()};_.hd=function dRd(a,b){return vQd()};_.gc=function eRd(){return 0};_.jd=function fRd(a){tvb(this,a)};_.Nc=function gRd(){return new Swb(this,16)};_.Oc=function hRd(){return new SDb(null,new Swb(this,16))};_.kd=function iRd(a,b){return yob(),new Rkb(vob,a,b)};_.Pc=function jRd(){return De((yob(),vob))};_.Qc=function kRd(a){return yob(),Ee(vob,a)};var W6=sfb(sIe,'ECollections/EmptyUnmodifiableEList',1346);feb(1347,783,{20:1,16:1,15:1,61:1,597:1},lRd);_.bd=function mRd(a,b){mQd()};_.Fc=function nRd(a){return nQd()};_.cd=function oRd(a,b){return oQd()};_.Gc=function pRd(a){return pQd()};_.$b=function qRd(){qQd()};_.Hc=function rRd(a){return false};_.Ic=function sRd(a){return false};_.Jc=function tRd(a){xgb(this,a)};_.Xb=function uRd(a){return Iob((yob(),vob,a)),null};_.dd=function vRd(a){return -1};_.dc=function wRd(){return true};_.Kc=function xRd(){return this.a};_.ed=function yRd(){return this.a};_.fd=function zRd(a){return this.a};_.Ti=function BRd(a,b){return rQd()};_.Ui=function CRd(a,b){sQd()};_.Lc=function DRd(){return new SDb(null,new Swb(this,16))};_.gd=function ERd(a){return tQd()};_.Mc=function FRd(a){return uQd()};_.hd=function GRd(a,b){return vQd()};_.gc=function HRd(){return 0};_.jd=function IRd(a){tvb(this,a)};_.Nc=function JRd(){return new Swb(this,16)};_.Oc=function KRd(){return new SDb(null,new Swb(this,16))};_.kd=function LRd(a,b){return yob(),new Rkb(vob,a,b)};_.Pc=function MRd(){return De((yob(),vob))};_.Qc=function NRd(a){return yob(),Ee(vob,a)};_.bk=function ARd(){return yob(),yob(),wob};var X6=sfb(sIe,'ECollections/EmptyUnmodifiableEMap',1347);var Z6=ufb(sIe,'Enumerator');var ORd;feb(288,1,{288:1},lSd);_.Fb=function pSd(a){var b;if(this===a)return true;if(!ZD(a,288))return false;b=RD(a,288);return this.f==b.f&&rSd(this.i,b.i)&&qSd(this.a,(this.f&256)!=0?(b.f&256)!=0?b.a:null:(b.f&256)!=0?null:b.a)&&qSd(this.d,b.d)&&qSd(this.g,b.g)&&qSd(this.e,b.e)&&iSd(this,b)};_.Hb=function uSd(){return this.f};_.Ib=function CSd(){return jSd(this)};_.f=0;var SRd=0,TRd=0,URd=0,VRd=0,WRd=0,XRd=0,YRd=0,ZRd=0,$Rd=0,_Rd,aSd=0,bSd=0,cSd=0,dSd=0,eSd,fSd;var c7=sfb(sIe,'URI',288);feb(1121,45,Hxe,MSd);_.zc=function NSd(a,b){return RD($jb(this,WD(a),RD(b,288)),288)};var b7=sfb(sIe,'URI/URICache',1121);feb(506,66,PIe,OSd,PSd);_.Si=function QSd(){return true};var d7=sfb(sIe,'UniqueEList',506);feb(590,63,swe,RSd);var e7=sfb(sIe,'WrappedException',590);var f7=ufb(vHe,OJe);var A7=ufb(vHe,PJe);var y7=ufb(vHe,QJe);var g7=ufb(vHe,RJe);var i7=ufb(vHe,SJe);var h7=ufb(vHe,'EClass');var k7=ufb(vHe,'EDataType');var SSd;feb(1233,45,Hxe,VSd);_.xc=function WSd(a){return bE(a)?Xjb(this,a):Wd(qtb(this.f,a))};var j7=sfb(vHe,'EDataType/Internal/ConversionDelegate/Factory/Registry/Impl',1233);var m7=ufb(vHe,'EEnum');var l7=ufb(vHe,TJe);var o7=ufb(vHe,UJe);var s7=ufb(vHe,VJe);var XSd;var u7=ufb(vHe,WJe);var v7=ufb(vHe,XJe);feb(1042,1,{},_Sd);_.Ib=function aTd(){return 'NIL'};var w7=sfb(vHe,'EStructuralFeature/Internal/DynamicValueHolder/1',1042);var bTd;feb(1041,45,Hxe,eTd);_.xc=function fTd(a){return bE(a)?Xjb(this,a):Wd(qtb(this.f,a))};var x7=sfb(vHe,'EStructuralFeature/Internal/SettingDelegate/Factory/Registry/Impl',1041);var z7=ufb(vHe,YJe);var B7=ufb(vHe,'EValidator/PatternMatcher');var gTd;var iTd;var kTd;var mTd,nTd,oTd,pTd,qTd,rTd,sTd,tTd,uTd,vTd,wTd,xTd,yTd,zTd,ATd,BTd,CTd,DTd,ETd,FTd,GTd,HTd,ITd;var Jbb=ufb(ZJe,'FeatureMap/Entry');feb(545,1,{76:1},KTd);_.Lk=function LTd(){return this.a};_.md=function MTd(){return this.b};var C7=sfb(SHe,'BasicEObjectImpl/1',545);feb(1040,1,$Je,NTd);_.Fk=function OTd(a){return Fvd(this.a,this.b,a)};_.Qj=function PTd(){return Lvd(this.a,this.b)};_.Wb=function QTd(a){Xvd(this.a,this.b,a)};_.Gk=function RTd(){_vd(this.a,this.b)};var D7=sfb(SHe,'BasicEObjectImpl/4',1040);feb(2081,1,{114:1});_.Mk=function UTd(a){this.e=a==0?STd:$C(jJ,rve,1,a,5,1)};_.li=function VTd(a){return this.e[a]};_.mi=function WTd(a,b){this.e[a]=b};_.ni=function XTd(a){this.e[a]=null};_.Nk=function YTd(){return this.c};_.Ok=function ZTd(){throw Adb(new jib)};_.Pk=function $Td(){throw Adb(new jib)};_.Qk=function _Td(){return this.d};_.Rk=function aUd(){return this.e!=null};_.Sk=function bUd(a){this.c=a};_.Tk=function cUd(a){throw Adb(new jib)};_.Uk=function dUd(a){throw Adb(new jib)};_.Vk=function eUd(a){this.d=a};var STd;var E7=sfb(SHe,'BasicEObjectImpl/EPropertiesHolderBaseImpl',2081);feb(192,2081,{114:1},fUd);_.Ok=function gUd(){return this.a};_.Pk=function hUd(){return this.b};_.Tk=function iUd(a){this.a=a};_.Uk=function jUd(a){this.b=a};var F7=sfb(SHe,'BasicEObjectImpl/EPropertiesHolderImpl',192);feb(516,99,RHe,kUd);_.uh=function lUd(){return this.f};_.zh=function mUd(){return this.k};_.Bh=function nUd(a,b){this.g=a;this.i=b};_.Dh=function oUd(){return (this.j&2)==0?this.ii():this.$h().Nk()};_.Fh=function pUd(){return this.i};_.wh=function qUd(){return (this.j&1)!=0};_.Ph=function rUd(){return this.g};_.Vh=function sUd(){return (this.j&4)!=0};_.$h=function tUd(){return !this.k&&(this.k=new fUd),this.k};_.ci=function uUd(a){this.$h().Sk(a);a?(this.j|=2):(this.j&=-3)};_.ei=function vUd(a){this.$h().Uk(a);a?(this.j|=4):(this.j&=-5)};_.ii=function wUd(){return (lTd(),kTd).S};_.i=0;_.j=1;var q8=sfb(SHe,'EObjectImpl',516);feb(798,516,{110:1,94:1,93:1,58:1,114:1,54:1,99:1},zUd);_.li=function AUd(a){return this.e[a]};_.mi=function BUd(a,b){this.e[a]=b};_.ni=function CUd(a){this.e[a]=null};_.Dh=function DUd(){return this.d};_.Ih=function EUd(a){return BYd(this.d,a)};_.Kh=function FUd(){return this.d};_.Oh=function GUd(){return this.e!=null};_.$h=function HUd(){!this.k&&(this.k=new VUd);return this.k};_.ci=function IUd(a){this.d=a};_.hi=function JUd(){var a;if(this.e==null){a=AYd(this.d);this.e=a==0?xUd:$C(jJ,rve,1,a,5,1)}return this};_.ji=function KUd(){return 0};var xUd;var J7=sfb(SHe,'DynamicEObjectImpl',798);feb(1522,798,{110:1,44:1,94:1,93:1,136:1,58:1,114:1,54:1,99:1},LUd);_.Fb=function NUd(a){return this===a};_.Hb=function RUd(){return kFb(this)};_.ci=function MUd(a){this.d=a;this.b=wYd(a,'key');this.c=wYd(a,aIe)};_.Bi=function OUd(){var a;if(this.a==-1){a=Gvd(this,this.b);this.a=a==null?0:tb(a)}return this.a};_.ld=function PUd(){return Gvd(this,this.b)};_.md=function QUd(){return Gvd(this,this.c)};_.Ci=function SUd(a){this.a=a};_.Di=function TUd(a){Xvd(this,this.b,a)};_.nd=function UUd(a){var b;b=Gvd(this,this.c);Xvd(this,this.c,a);return b};_.a=0;var H7=sfb(SHe,'DynamicEObjectImpl/BasicEMapEntry',1522);feb(1523,1,{114:1},VUd);_.Mk=function WUd(a){throw Adb(new jib)};_.li=function XUd(a){throw Adb(new jib)};_.mi=function YUd(a,b){throw Adb(new jib)};_.ni=function ZUd(a){throw Adb(new jib)};_.Nk=function $Ud(){throw Adb(new jib)};_.Ok=function _Ud(){return this.a};_.Pk=function aVd(){return this.b};_.Qk=function bVd(){return this.c};_.Rk=function cVd(){throw Adb(new jib)};_.Sk=function dVd(a){throw Adb(new jib)};_.Tk=function eVd(a){this.a=a};_.Uk=function fVd(a){this.b=a};_.Vk=function gVd(a){this.c=a};var I7=sfb(SHe,'DynamicEObjectImpl/DynamicEPropertiesHolderImpl',1523);feb(519,158,{110:1,94:1,93:1,598:1,155:1,58:1,114:1,54:1,99:1,519:1,158:1,119:1,120:1},pVd);_.Ah=function qVd(a){return iVd(this,a)};_.Lh=function rVd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.d;case 2:return c?(!this.b&&(this.b=new SVd((JTd(),FTd),C8,this)),this.b):(!this.b&&(this.b=new SVd((JTd(),FTd),C8,this)),dOd(this.b));case 3:return kVd(this);case 4:return !this.a&&(this.a=new XZd(r7,this,4)),this.a;case 5:return !this.c&&(this.c=new zie(r7,this,5)),this.c;}return zvd(this,a-AYd((JTd(),mTd)),vYd((d=RD(Ywd(this,16),29),!d?mTd:d),a),b,c)};_.Sh=function sVd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),qLd(this.Ab,a,c);case 3:!!this.Cb&&(c=(e=this.Db>>16,e>=0?iVd(this,c):this.Cb.Th(this,-1-e,null,c)));return hVd(this,RD(a,155),c);}return f=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),mTd):d),b),69),f.wk().zk(this,Wwd(this),b-AYd((JTd(),mTd)),a,c)};_.Uh=function tVd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c);case 2:return !this.b&&(this.b=new SVd((JTd(),FTd),C8,this)),BVd(this.b,a,c);case 3:return hVd(this,null,c);case 4:return !this.a&&(this.a=new XZd(r7,this,4)),rLd(this.a,a,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),mTd):d),b),69),e.wk().Ak(this,Wwd(this),b-AYd((JTd(),mTd)),a,c)};_.Wh=function uVd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.d!=null;case 2:return !!this.b&&this.b.f!=0;case 3:return !!kVd(this);case 4:return !!this.a&&this.a.i!=0;case 5:return !!this.c&&this.c.i!=0;}return Avd(this,a-AYd((JTd(),mTd)),vYd((b=RD(Ywd(this,16),29),!b?mTd:b),a))};_.bi=function vVd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:mVd(this,WD(b));return;case 2:!this.b&&(this.b=new SVd((JTd(),FTd),C8,this));CVd(this.b,b);return;case 3:lVd(this,RD(b,155));return;case 4:!this.a&&(this.a=new XZd(r7,this,4));sLd(this.a);!this.a&&(this.a=new XZd(r7,this,4));YGd(this.a,RD(b,16));return;case 5:!this.c&&(this.c=new zie(r7,this,5));sLd(this.c);!this.c&&(this.c=new zie(r7,this,5));YGd(this.c,RD(b,16));return;}Bvd(this,a-AYd((JTd(),mTd)),vYd((c=RD(Ywd(this,16),29),!c?mTd:c),a),b)};_.ii=function wVd(){return JTd(),mTd};_.ki=function xVd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:nVd(this,null);return;case 2:!this.b&&(this.b=new SVd((JTd(),FTd),C8,this));this.b.c.$b();return;case 3:lVd(this,null);return;case 4:!this.a&&(this.a=new XZd(r7,this,4));sLd(this.a);return;case 5:!this.c&&(this.c=new zie(r7,this,5));sLd(this.c);return;}Cvd(this,a-AYd((JTd(),mTd)),vYd((b=RD(Ywd(this,16),29),!b?mTd:b),a))};_.Ib=function yVd(){return oVd(this)};_.d=null;var L7=sfb(SHe,'EAnnotationImpl',519);feb(141,721,_Je,DVd);_.Gi=function EVd(a,b){zVd(this,a,RD(b,44))};_.Wk=function FVd(a,b){return AVd(this,RD(a,44),b)};_.$i=function GVd(a){return RD(RD(this.c,71).$i(a),136)};_.Ii=function HVd(){return RD(this.c,71).Ii()};_.Ji=function IVd(){return RD(this.c,71).Ji()};_.Ki=function JVd(a){return RD(this.c,71).Ki(a)};_.Xk=function KVd(a,b){return BVd(this,a,b)};_.Fk=function LVd(a){return RD(this.c,79).Fk(a)};_.ak=function MVd(){};_.Qj=function NVd(){return RD(this.c,79).Qj()};_.ck=function OVd(a,b,c){var d;d=RD(BXd(this.b).wi().si(this.b),136);d.Ci(a);d.Di(b);d.nd(c);return d};_.dk=function PVd(){return new uje(this)};_.Wb=function QVd(a){CVd(this,a)};_.Gk=function RVd(){RD(this.c,79).Gk()};var Dbb=sfb(ZJe,'EcoreEMap',141);feb(165,141,_Je,SVd);_._j=function TVd(){var a,b,c,d,e,f;if(this.d==null){f=$C(D6,KJe,66,2*this.f+1,0,1);for(c=this.c.Kc();c.e!=c.i.gc();){b=RD(c.Yj(),136);d=b.Bi();e=(d&lve)%f.length;a=f[e];!a&&(a=f[e]=new uje(this));a.Fc(b)}this.d=f}};var K7=sfb(SHe,'EAnnotationImpl/1',165);feb(292,448,{110:1,94:1,93:1,155:1,197:1,58:1,114:1,481:1,54:1,99:1,158:1,292:1,119:1,120:1});_.Lh=function eWd(a,b,c){var d,e;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Geb(),(this.Bb&256)!=0?true:false;case 3:return Geb(),(this.Bb&512)!=0?true:false;case 4:return sgb(this.s);case 5:return sgb(this.t);case 6:return Geb(),this.Jk()?true:false;case 7:return Geb(),e=this.s,e>=1?true:false;case 8:if(b)return WVd(this);return this.r;case 9:return this.q;}return zvd(this,a-AYd(this.ii()),vYd((d=RD(Ywd(this,16),29),!d?this.ii():d),a),b,c)};_.Uh=function fWd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c);case 9:return VVd(this,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?this.ii():d),b),69),e.wk().Ak(this,Wwd(this),b-AYd(this.ii()),a,c)};_.Wh=function gWd(a){var b,c;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return (this.Bb&256)==0;case 3:return (this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return this.Jk();case 7:return c=this.s,c>=1;case 8:return !!this.r&&!this.q.e&&j2d(this.q).i==0;case 9:return !!this.q&&!(!!this.r&&!this.q.e&&j2d(this.q).i==0);}return Avd(this,a-AYd(this.ii()),vYd((b=RD(Ywd(this,16),29),!b?this.ii():b),a))};_.bi=function hWd(a,b){var c,d;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:this.ui(WD(b));return;case 2:_Vd(this,Heb(TD(b)));return;case 3:aWd(this,Heb(TD(b)));return;case 4:$Vd(this,RD(b,17).a);return;case 5:this.Zk(RD(b,17).a);return;case 8:YVd(this,RD(b,142));return;case 9:d=XVd(this,RD(b,89),null);!!d&&d.oj();return;}Bvd(this,a-AYd(this.ii()),vYd((c=RD(Ywd(this,16),29),!c?this.ii():c),a),b)};_.ii=function iWd(){return JTd(),HTd};_.ki=function jWd(a){var b,c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:this.ui(null);return;case 2:_Vd(this,true);return;case 3:aWd(this,true);return;case 4:$Vd(this,0);return;case 5:this.Zk(1);return;case 8:YVd(this,null);return;case 9:c=XVd(this,null,null);!!c&&c.oj();return;}Cvd(this,a-AYd(this.ii()),vYd((b=RD(Ywd(this,16),29),!b?this.ii():b),a))};_.pi=function kWd(){WVd(this);this.Bb|=1};_.Hk=function lWd(){return WVd(this)};_.Ik=function mWd(){return this.t};_.Jk=function nWd(){var a;return a=this.t,a>1||a==-1};_.Si=function oWd(){return (this.Bb&512)!=0};_.Yk=function pWd(a,b){return ZVd(this,a,b)};_.Zk=function qWd(a){bWd(this,a)};_.Ib=function rWd(){return cWd(this)};_.s=0;_.t=1;var A9=sfb(SHe,'ETypedElementImpl',292);feb(462,292,{110:1,94:1,93:1,155:1,197:1,58:1,179:1,69:1,114:1,481:1,54:1,99:1,158:1,462:1,292:1,119:1,120:1,692:1});_.Ah=function IWd(a){return sWd(this,a)};_.Lh=function JWd(a,b,c){var d,e;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Geb(),(this.Bb&256)!=0?true:false;case 3:return Geb(),(this.Bb&512)!=0?true:false;case 4:return sgb(this.s);case 5:return sgb(this.t);case 6:return Geb(),this.Jk()?true:false;case 7:return Geb(),e=this.s,e>=1?true:false;case 8:if(b)return WVd(this);return this.r;case 9:return this.q;case 10:return Geb(),(this.Bb&gwe)!=0?true:false;case 11:return Geb(),(this.Bb&cKe)!=0?true:false;case 12:return Geb(),(this.Bb&qxe)!=0?true:false;case 13:return this.j;case 14:return tWd(this);case 15:return Geb(),(this.Bb&bKe)!=0?true:false;case 16:return Geb(),(this.Bb&Ove)!=0?true:false;case 17:return uWd(this);}return zvd(this,a-AYd(this.ii()),vYd((d=RD(Ywd(this,16),29),!d?this.ii():d),a),b,c)};_.Sh=function KWd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),qLd(this.Ab,a,c);case 17:!!this.Cb&&(c=(e=this.Db>>16,e>=0?sWd(this,c):this.Cb.Th(this,-1-e,null,c)));return xvd(this,a,17,c);}return f=RD(vYd((d=RD(Ywd(this,16),29),!d?this.ii():d),b),69),f.wk().zk(this,Wwd(this),b-AYd(this.ii()),a,c)};_.Uh=function LWd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c);case 9:return VVd(this,c);case 17:return xvd(this,null,17,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?this.ii():d),b),69),e.wk().Ak(this,Wwd(this),b-AYd(this.ii()),a,c)};_.Wh=function MWd(a){var b,c;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return (this.Bb&256)==0;case 3:return (this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return this.Jk();case 7:return c=this.s,c>=1;case 8:return !!this.r&&!this.q.e&&j2d(this.q).i==0;case 9:return !!this.q&&!(!!this.r&&!this.q.e&&j2d(this.q).i==0);case 10:return (this.Bb&gwe)==0;case 11:return (this.Bb&cKe)!=0;case 12:return (this.Bb&qxe)!=0;case 13:return this.j!=null;case 14:return tWd(this)!=null;case 15:return (this.Bb&bKe)!=0;case 16:return (this.Bb&Ove)!=0;case 17:return !!uWd(this);}return Avd(this,a-AYd(this.ii()),vYd((b=RD(Ywd(this,16),29),!b?this.ii():b),a))};_.bi=function NWd(a,b){var c,d;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:CWd(this,WD(b));return;case 2:_Vd(this,Heb(TD(b)));return;case 3:aWd(this,Heb(TD(b)));return;case 4:$Vd(this,RD(b,17).a);return;case 5:this.Zk(RD(b,17).a);return;case 8:YVd(this,RD(b,142));return;case 9:d=XVd(this,RD(b,89),null);!!d&&d.oj();return;case 10:xWd(this,Heb(TD(b)));return;case 11:FWd(this,Heb(TD(b)));return;case 12:DWd(this,Heb(TD(b)));return;case 13:yWd(this,WD(b));return;case 15:EWd(this,Heb(TD(b)));return;case 16:AWd(this,Heb(TD(b)));return;}Bvd(this,a-AYd(this.ii()),vYd((c=RD(Ywd(this,16),29),!c?this.ii():c),a),b)};_.ii=function OWd(){return JTd(),GTd};_.ki=function PWd(a){var b,c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:ZD(this.Cb,90)&&v$d(yYd(RD(this.Cb,90)),4);PAd(this,null);return;case 2:_Vd(this,true);return;case 3:aWd(this,true);return;case 4:$Vd(this,0);return;case 5:this.Zk(1);return;case 8:YVd(this,null);return;case 9:c=XVd(this,null,null);!!c&&c.oj();return;case 10:xWd(this,true);return;case 11:FWd(this,false);return;case 12:DWd(this,false);return;case 13:this.i=null;zWd(this,null);return;case 15:EWd(this,false);return;case 16:AWd(this,false);return;}Cvd(this,a-AYd(this.ii()),vYd((b=RD(Ywd(this,16),29),!b?this.ii():b),a))};_.pi=function QWd(){Afe(Qee((lke(),jke),this));WVd(this);this.Bb|=1};_.pk=function RWd(){return this.f};_.ik=function SWd(){return tWd(this)};_.qk=function TWd(){return uWd(this)};_.uk=function UWd(){return null};_.$k=function VWd(){return this.k};_.Lj=function WWd(){return this.n};_.vk=function XWd(){return vWd(this)};_.wk=function YWd(){var a,b,c,d,e,f,g,h,i;if(!this.p){c=uWd(this);(c.i==null&&rYd(c),c.i).length;d=this.uk();!!d&&AYd(uWd(d));e=WVd(this);g=e.kk();a=!g?null:(g.i&1)!=0?g==xdb?QI:g==kE?bJ:g==jE?ZI:g==iE?VI:g==lE?eJ:g==wdb?lJ:g==gE?RI:SI:g;b=tWd(this);h=e.ik();Mje(this);(this.Bb&Ove)!=0&&(!!(f=Tee((lke(),jke),c))&&f!=this||!!(f=zfe(Qee(jke,this))))?(this.p=new Z6d(this,f)):this.Jk()?this.al()?!d?(this.Bb&bKe)!=0?!a?this.bl()?(this.p=new i7d(42,this)):(this.p=new i7d(0,this)):a==UK?(this.p=new g7d(50,O6,this)):this.bl()?(this.p=new g7d(43,a,this)):(this.p=new g7d(1,a,this)):!a?this.bl()?(this.p=new i7d(44,this)):(this.p=new i7d(2,this)):a==UK?(this.p=new g7d(41,O6,this)):this.bl()?(this.p=new g7d(45,a,this)):(this.p=new g7d(3,a,this)):(this.Bb&bKe)!=0?!a?this.bl()?(this.p=new j7d(46,this,d)):(this.p=new j7d(4,this,d)):this.bl()?(this.p=new h7d(47,a,this,d)):(this.p=new h7d(5,a,this,d)):!a?this.bl()?(this.p=new j7d(48,this,d)):(this.p=new j7d(6,this,d)):this.bl()?(this.p=new h7d(49,a,this,d)):(this.p=new h7d(7,a,this,d)):ZD(e,156)?a==Jbb?(this.p=new i7d(40,this)):(this.Bb&512)!=0?(this.Bb&bKe)!=0?!a?(this.p=new i7d(8,this)):(this.p=new g7d(9,a,this)):!a?(this.p=new i7d(10,this)):(this.p=new g7d(11,a,this)):(this.Bb&bKe)!=0?!a?(this.p=new i7d(12,this)):(this.p=new g7d(13,a,this)):!a?(this.p=new i7d(14,this)):(this.p=new g7d(15,a,this)):!d?this.bl()?(this.Bb&bKe)!=0?!a?(this.p=new i7d(16,this)):(this.p=new g7d(17,a,this)):!a?(this.p=new i7d(18,this)):(this.p=new g7d(19,a,this)):(this.Bb&bKe)!=0?!a?(this.p=new i7d(20,this)):(this.p=new g7d(21,a,this)):!a?(this.p=new i7d(22,this)):(this.p=new g7d(23,a,this)):(i=d.t,i>1||i==-1?this.bl()?(this.Bb&bKe)!=0?!a?(this.p=new j7d(24,this,d)):(this.p=new h7d(25,a,this,d)):!a?(this.p=new j7d(26,this,d)):(this.p=new h7d(27,a,this,d)):(this.Bb&bKe)!=0?!a?(this.p=new j7d(28,this,d)):(this.p=new h7d(29,a,this,d)):!a?(this.p=new j7d(30,this,d)):(this.p=new h7d(31,a,this,d)):this.bl()?(this.Bb&bKe)!=0?!a?(this.p=new j7d(32,this,d)):(this.p=new h7d(33,a,this,d)):!a?(this.p=new j7d(34,this,d)):(this.p=new h7d(35,a,this,d)):(this.Bb&bKe)!=0?!a?(this.p=new j7d(36,this,d)):(this.p=new h7d(37,a,this,d)):!a?(this.p=new j7d(38,this,d)):(this.p=new h7d(39,a,this,d))):this._k()?this.bl()?(this.p=new K7d(RD(e,29),this,d)):(this.p=new C7d(RD(e,29),this,d)):ZD(e,156)?a==Jbb?(this.p=new i7d(40,this)):(this.Bb&bKe)!=0?!a?(this.p=new J8d(RD(e,156),b,h,this)):(this.p=new L8d(b,h,this,(a8d(),g==kE?Y7d:g==xdb?T7d:g==lE?Z7d:g==jE?X7d:g==iE?W7d:g==wdb?_7d:g==gE?U7d:g==hE?V7d:$7d))):!a?(this.p=new C8d(RD(e,156),b,h,this)):(this.p=new E8d(b,h,this,(a8d(),g==kE?Y7d:g==xdb?T7d:g==lE?Z7d:g==jE?X7d:g==iE?W7d:g==wdb?_7d:g==gE?U7d:g==hE?V7d:$7d))):this.al()?!d?(this.Bb&bKe)!=0?this.bl()?(this.p=new d9d(RD(e,29),this)):(this.p=new b9d(RD(e,29),this)):this.bl()?(this.p=new _8d(RD(e,29),this)):(this.p=new Z8d(RD(e,29),this)):(this.Bb&bKe)!=0?this.bl()?(this.p=new l9d(RD(e,29),this,d)):(this.p=new j9d(RD(e,29),this,d)):this.bl()?(this.p=new h9d(RD(e,29),this,d)):(this.p=new f9d(RD(e,29),this,d)):this.bl()?!d?(this.Bb&bKe)!=0?(this.p=new p9d(RD(e,29),this)):(this.p=new n9d(RD(e,29),this)):(this.Bb&bKe)!=0?(this.p=new t9d(RD(e,29),this,d)):(this.p=new r9d(RD(e,29),this,d)):!d?(this.Bb&bKe)!=0?(this.p=new v9d(RD(e,29),this)):(this.p=new N8d(RD(e,29),this)):(this.Bb&bKe)!=0?(this.p=new z9d(RD(e,29),this,d)):(this.p=new x9d(RD(e,29),this,d))}return this.p};_.rk=function ZWd(){return (this.Bb&gwe)!=0};_._k=function $Wd(){return false};_.al=function _Wd(){return false};_.sk=function aXd(){return (this.Bb&Ove)!=0};_.xk=function bXd(){return wWd(this)};_.bl=function cXd(){return false};_.tk=function dXd(){return (this.Bb&bKe)!=0};_.cl=function eXd(a){this.k=a};_.ui=function fXd(a){CWd(this,a)};_.Ib=function gXd(){return GWd(this)};_.e=false;_.n=0;var s9=sfb(SHe,'EStructuralFeatureImpl',462);feb(331,462,{110:1,94:1,93:1,35:1,155:1,197:1,58:1,179:1,69:1,114:1,481:1,54:1,99:1,331:1,158:1,462:1,292:1,119:1,120:1,692:1},mXd);_.Lh=function nXd(a,b,c){var d,e;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Geb(),(this.Bb&256)!=0?true:false;case 3:return Geb(),(this.Bb&512)!=0?true:false;case 4:return sgb(this.s);case 5:return sgb(this.t);case 6:return Geb(),jXd(this)?true:false;case 7:return Geb(),e=this.s,e>=1?true:false;case 8:if(b)return WVd(this);return this.r;case 9:return this.q;case 10:return Geb(),(this.Bb&gwe)!=0?true:false;case 11:return Geb(),(this.Bb&cKe)!=0?true:false;case 12:return Geb(),(this.Bb&qxe)!=0?true:false;case 13:return this.j;case 14:return tWd(this);case 15:return Geb(),(this.Bb&bKe)!=0?true:false;case 16:return Geb(),(this.Bb&Ove)!=0?true:false;case 17:return uWd(this);case 18:return Geb(),(this.Bb&QHe)!=0?true:false;case 19:if(b)return iXd(this);return hXd(this);}return zvd(this,a-AYd((JTd(),nTd)),vYd((d=RD(Ywd(this,16),29),!d?nTd:d),a),b,c)};_.Wh=function oXd(a){var b,c;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return (this.Bb&256)==0;case 3:return (this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return jXd(this);case 7:return c=this.s,c>=1;case 8:return !!this.r&&!this.q.e&&j2d(this.q).i==0;case 9:return !!this.q&&!(!!this.r&&!this.q.e&&j2d(this.q).i==0);case 10:return (this.Bb&gwe)==0;case 11:return (this.Bb&cKe)!=0;case 12:return (this.Bb&qxe)!=0;case 13:return this.j!=null;case 14:return tWd(this)!=null;case 15:return (this.Bb&bKe)!=0;case 16:return (this.Bb&Ove)!=0;case 17:return !!uWd(this);case 18:return (this.Bb&QHe)!=0;case 19:return !!hXd(this);}return Avd(this,a-AYd((JTd(),nTd)),vYd((b=RD(Ywd(this,16),29),!b?nTd:b),a))};_.bi=function pXd(a,b){var c,d;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:CWd(this,WD(b));return;case 2:_Vd(this,Heb(TD(b)));return;case 3:aWd(this,Heb(TD(b)));return;case 4:$Vd(this,RD(b,17).a);return;case 5:lXd(this,RD(b,17).a);return;case 8:YVd(this,RD(b,142));return;case 9:d=XVd(this,RD(b,89),null);!!d&&d.oj();return;case 10:xWd(this,Heb(TD(b)));return;case 11:FWd(this,Heb(TD(b)));return;case 12:DWd(this,Heb(TD(b)));return;case 13:yWd(this,WD(b));return;case 15:EWd(this,Heb(TD(b)));return;case 16:AWd(this,Heb(TD(b)));return;case 18:kXd(this,Heb(TD(b)));return;}Bvd(this,a-AYd((JTd(),nTd)),vYd((c=RD(Ywd(this,16),29),!c?nTd:c),a),b)};_.ii=function qXd(){return JTd(),nTd};_.ki=function rXd(a){var b,c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:ZD(this.Cb,90)&&v$d(yYd(RD(this.Cb,90)),4);PAd(this,null);return;case 2:_Vd(this,true);return;case 3:aWd(this,true);return;case 4:$Vd(this,0);return;case 5:this.b=0;bWd(this,1);return;case 8:YVd(this,null);return;case 9:c=XVd(this,null,null);!!c&&c.oj();return;case 10:xWd(this,true);return;case 11:FWd(this,false);return;case 12:DWd(this,false);return;case 13:this.i=null;zWd(this,null);return;case 15:EWd(this,false);return;case 16:AWd(this,false);return;case 18:kXd(this,false);return;}Cvd(this,a-AYd((JTd(),nTd)),vYd((b=RD(Ywd(this,16),29),!b?nTd:b),a))};_.pi=function sXd(){iXd(this);Afe(Qee((lke(),jke),this));WVd(this);this.Bb|=1};_.Jk=function tXd(){return jXd(this)};_.Yk=function uXd(a,b){this.b=0;this.a=null;return ZVd(this,a,b)};_.Zk=function vXd(a){lXd(this,a)};_.Ib=function wXd(){var a;if((this.Db&64)!=0)return GWd(this);a=new Shb(GWd(this));a.a+=' (iD: ';Ohb(a,(this.Bb&QHe)!=0);a.a+=')';return a.a};_.b=0;var M7=sfb(SHe,'EAttributeImpl',331);feb(364,448,{110:1,94:1,93:1,142:1,155:1,197:1,58:1,114:1,54:1,99:1,364:1,158:1,119:1,120:1,691:1});_.dl=function NXd(a){return a.Dh()==this};_.Ah=function OXd(a){return AXd(this,a)};_.Bh=function PXd(a,b){this.w=null;this.Db=b<<16|this.Db&255;this.Cb=a};_.Lh=function QXd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.D!=null?this.D:this.B;case 3:return DXd(this);case 4:return this.ik();case 5:return this.F;case 6:if(b)return BXd(this);return xXd(this);case 7:return !this.A&&(this.A=new iie(z7,this,7)),this.A;}return zvd(this,a-AYd(this.ii()),vYd((d=RD(Ywd(this,16),29),!d?this.ii():d),a),b,c)};_.Sh=function RXd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),qLd(this.Ab,a,c);case 6:!!this.Cb&&(c=(e=this.Db>>16,e>=0?AXd(this,c):this.Cb.Th(this,-1-e,null,c)));return xvd(this,a,6,c);}return f=RD(vYd((d=RD(Ywd(this,16),29),!d?this.ii():d),b),69),f.wk().zk(this,Wwd(this),b-AYd(this.ii()),a,c)};_.Uh=function SXd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c);case 6:return xvd(this,null,6,c);case 7:return !this.A&&(this.A=new iie(z7,this,7)),rLd(this.A,a,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?this.ii():d),b),69),e.wk().Ak(this,Wwd(this),b-AYd(this.ii()),a,c)};_.Wh=function TXd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.D!=null&&this.D==this.F;case 3:return !!DXd(this);case 4:return this.ik()!=null;case 5:return this.F!=null&&this.F!=this.D&&this.F!=this.B;case 6:return !!xXd(this);case 7:return !!this.A&&this.A.i!=0;}return Avd(this,a-AYd(this.ii()),vYd((b=RD(Ywd(this,16),29),!b?this.ii():b),a))};_.bi=function UXd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:LXd(this,WD(b));return;case 2:IXd(this,WD(b));return;case 5:KXd(this,WD(b));return;case 7:!this.A&&(this.A=new iie(z7,this,7));sLd(this.A);!this.A&&(this.A=new iie(z7,this,7));YGd(this.A,RD(b,16));return;}Bvd(this,a-AYd(this.ii()),vYd((c=RD(Ywd(this,16),29),!c?this.ii():c),a),b)};_.ii=function VXd(){return JTd(),pTd};_.ki=function WXd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:ZD(this.Cb,184)&&(RD(this.Cb,184).tb=null);PAd(this,null);return;case 2:yXd(this,null);zXd(this,this.D);return;case 5:KXd(this,null);return;case 7:!this.A&&(this.A=new iie(z7,this,7));sLd(this.A);return;}Cvd(this,a-AYd(this.ii()),vYd((b=RD(Ywd(this,16),29),!b?this.ii():b),a))};_.hk=function XXd(){var a;return this.G==-1&&(this.G=(a=BXd(this),a?fZd(a.vi(),this):-1)),this.G};_.ik=function YXd(){return null};_.jk=function ZXd(){return BXd(this)};_.el=function $Xd(){return this.v};_.kk=function _Xd(){return DXd(this)};_.lk=function aYd(){return this.D!=null?this.D:this.B};_.mk=function bYd(){return this.F};_.fk=function cYd(a){return FXd(this,a)};_.fl=function dYd(a){this.v=a};_.gl=function eYd(a){GXd(this,a)};_.hl=function fYd(a){this.C=a};_.ui=function gYd(a){LXd(this,a)};_.Ib=function hYd(){return MXd(this)};_.C=null;_.D=null;_.G=-1;var c8=sfb(SHe,'EClassifierImpl',364);feb(90,364,{110:1,94:1,93:1,29:1,142:1,155:1,197:1,58:1,114:1,54:1,99:1,90:1,364:1,158:1,482:1,119:1,120:1,691:1},HYd);_.dl=function IYd(a){return DYd(this,a.Dh())};_.Lh=function JYd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.D!=null?this.D:this.B;case 3:return DXd(this);case 4:return null;case 5:return this.F;case 6:if(b)return BXd(this);return xXd(this);case 7:return !this.A&&(this.A=new iie(z7,this,7)),this.A;case 8:return Geb(),(this.Bb&256)!=0?true:false;case 9:return Geb(),(this.Bb&512)!=0?true:false;case 10:return zYd(this);case 11:return !this.q&&(this.q=new C5d(s7,this,11,10)),this.q;case 12:return mYd(this);case 13:return qYd(this);case 14:return qYd(this),this.r;case 15:return mYd(this),this.k;case 16:return nYd(this);case 17:return pYd(this);case 18:return rYd(this);case 19:return sYd(this);case 20:return mYd(this),this.o;case 21:return !this.s&&(this.s=new C5d(y7,this,21,17)),this.s;case 22:return tYd(this);case 23:return oYd(this);}return zvd(this,a-AYd((JTd(),oTd)),vYd((d=RD(Ywd(this,16),29),!d?oTd:d),a),b,c)};_.Sh=function KYd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),qLd(this.Ab,a,c);case 6:!!this.Cb&&(c=(e=this.Db>>16,e>=0?AXd(this,c):this.Cb.Th(this,-1-e,null,c)));return xvd(this,a,6,c);case 11:return !this.q&&(this.q=new C5d(s7,this,11,10)),qLd(this.q,a,c);case 21:return !this.s&&(this.s=new C5d(y7,this,21,17)),qLd(this.s,a,c);}return f=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),oTd):d),b),69),f.wk().zk(this,Wwd(this),b-AYd((JTd(),oTd)),a,c)};_.Uh=function LYd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c);case 6:return xvd(this,null,6,c);case 7:return !this.A&&(this.A=new iie(z7,this,7)),rLd(this.A,a,c);case 11:return !this.q&&(this.q=new C5d(s7,this,11,10)),rLd(this.q,a,c);case 21:return !this.s&&(this.s=new C5d(y7,this,21,17)),rLd(this.s,a,c);case 22:return rLd(tYd(this),a,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),oTd):d),b),69),e.wk().Ak(this,Wwd(this),b-AYd((JTd(),oTd)),a,c)};_.Wh=function MYd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.D!=null&&this.D==this.F;case 3:return !!DXd(this);case 4:return false;case 5:return this.F!=null&&this.F!=this.D&&this.F!=this.B;case 6:return !!xXd(this);case 7:return !!this.A&&this.A.i!=0;case 8:return (this.Bb&256)!=0;case 9:return (this.Bb&512)!=0;case 10:return !!this.u&&tYd(this.u.a).i!=0&&!(!!this.n&&d$d(this.n));case 11:return !!this.q&&this.q.i!=0;case 12:return mYd(this).i!=0;case 13:return qYd(this).i!=0;case 14:return qYd(this),this.r.i!=0;case 15:return mYd(this),this.k.i!=0;case 16:return nYd(this).i!=0;case 17:return pYd(this).i!=0;case 18:return rYd(this).i!=0;case 19:return sYd(this).i!=0;case 20:return mYd(this),!!this.o;case 21:return !!this.s&&this.s.i!=0;case 22:return !!this.n&&d$d(this.n);case 23:return oYd(this).i!=0;}return Avd(this,a-AYd((JTd(),oTd)),vYd((b=RD(Ywd(this,16),29),!b?oTd:b),a))};_.Zh=function NYd(a){var b;b=this.i==null||!!this.q&&this.q.i!=0?null:wYd(this,a);return b?b:_zd(this,a)};_.bi=function OYd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:LXd(this,WD(b));return;case 2:IXd(this,WD(b));return;case 5:KXd(this,WD(b));return;case 7:!this.A&&(this.A=new iie(z7,this,7));sLd(this.A);!this.A&&(this.A=new iie(z7,this,7));YGd(this.A,RD(b,16));return;case 8:EYd(this,Heb(TD(b)));return;case 9:FYd(this,Heb(TD(b)));return;case 10:VJd(zYd(this));YGd(zYd(this),RD(b,16));return;case 11:!this.q&&(this.q=new C5d(s7,this,11,10));sLd(this.q);!this.q&&(this.q=new C5d(s7,this,11,10));YGd(this.q,RD(b,16));return;case 21:!this.s&&(this.s=new C5d(y7,this,21,17));sLd(this.s);!this.s&&(this.s=new C5d(y7,this,21,17));YGd(this.s,RD(b,16));return;case 22:sLd(tYd(this));YGd(tYd(this),RD(b,16));return;}Bvd(this,a-AYd((JTd(),oTd)),vYd((c=RD(Ywd(this,16),29),!c?oTd:c),a),b)};_.ii=function PYd(){return JTd(),oTd};_.ki=function QYd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:ZD(this.Cb,184)&&(RD(this.Cb,184).tb=null);PAd(this,null);return;case 2:yXd(this,null);zXd(this,this.D);return;case 5:KXd(this,null);return;case 7:!this.A&&(this.A=new iie(z7,this,7));sLd(this.A);return;case 8:EYd(this,false);return;case 9:FYd(this,false);return;case 10:!!this.u&&VJd(this.u);return;case 11:!this.q&&(this.q=new C5d(s7,this,11,10));sLd(this.q);return;case 21:!this.s&&(this.s=new C5d(y7,this,21,17));sLd(this.s);return;case 22:!!this.n&&sLd(this.n);return;}Cvd(this,a-AYd((JTd(),oTd)),vYd((b=RD(Ywd(this,16),29),!b?oTd:b),a))};_.pi=function RYd(){var a,b;mYd(this);qYd(this);nYd(this);pYd(this);rYd(this);sYd(this);oYd(this);OHd(q$d(yYd(this)));if(this.s){for(a=0,b=this.s.i;a=0;--b){QHd(this,b)}}return XHd(this,a)};_.Gk=function NZd(){sLd(this)};_.Zi=function OZd(a,b){return jZd(this,a,b)};var ybb=sfb(ZJe,'EcoreEList',632);feb(505,632,oKe,PZd);_.Li=function QZd(){return false};_.Lj=function RZd(){return this.c};_.Mj=function SZd(){return false};_.ol=function TZd(){return true};_.Si=function UZd(){return true};_.Wi=function VZd(a,b){return b};_.Yi=function WZd(){return false};_.c=0;var ibb=sfb(ZJe,'EObjectEList',505);feb(83,505,oKe,XZd);_.Mj=function YZd(){return true};_.ml=function ZZd(){return false};_.al=function $Zd(){return true};var cbb=sfb(ZJe,'EObjectContainmentEList',83);feb(555,83,oKe,_Zd);_.Ni=function a$d(){this.b=true};_.Qj=function b$d(){return this.b};_.Gk=function c$d(){var a;sLd(this);if(Mvd(this.e)){a=this.b;this.b=false;qvd(this.e,new Q3d(this.e,2,this.c,a,false))}else{this.b=false}};_.b=false;var bbb=sfb(ZJe,'EObjectContainmentEList/Unsettable',555);feb(1161,555,oKe,h$d);_.Ti=function l$d(a,b){var c,d;return c=RD(uLd(this,a,b),89),Mvd(this.e)&&eZd(this,new c4d(this.a,7,(JTd(),qTd),sgb(b),(d=c.c,ZD(d,90)?RD(d,29):zTd),a)),c};_.Uj=function m$d(a,b){return e$d(this,RD(a,89),b)};_.Vj=function n$d(a,b){return f$d(this,RD(a,89),b)};_.Wj=function o$d(a,b,c){return g$d(this,RD(a,89),RD(b,89),c)};_.Ij=function i$d(a,b,c,d,e){switch(a){case 3:{return dZd(this,a,b,c,d,this.i>1)}case 5:{return dZd(this,a,b,c,d,this.i-RD(c,15).gc()>0)}default:{return new P3d(this.e,a,this.c,b,c,d,true)}}};_.Tj=function j$d(){return true};_.Qj=function k$d(){return d$d(this)};_.Gk=function p$d(){sLd(this)};var S7=sfb(SHe,'EClassImpl/1',1161);feb(1175,1174,EJe);_.dj=function t$d(a){var b,c,d,e,f,g,h;c=a.gj();if(c!=8){d=s$d(a);if(d==0){switch(c){case 1:case 9:{h=a.kj();if(h!=null){b=yYd(RD(h,482));!b.c&&(b.c=new X9d);dHd(b.c,a.jj())}g=a.ij();if(g!=null){e=RD(g,482);if((e.Bb&1)==0){b=yYd(e);!b.c&&(b.c=new X9d);WGd(b.c,RD(a.jj(),29))}}break}case 3:{g=a.ij();if(g!=null){e=RD(g,482);if((e.Bb&1)==0){b=yYd(e);!b.c&&(b.c=new X9d);WGd(b.c,RD(a.jj(),29))}}break}case 5:{g=a.ij();if(g!=null){for(f=RD(g,16).Kc();f.Ob();){e=RD(f.Pb(),482);if((e.Bb&1)==0){b=yYd(e);!b.c&&(b.c=new X9d);WGd(b.c,RD(a.jj(),29))}}}break}case 4:{h=a.kj();if(h!=null){e=RD(h,482);if((e.Bb&1)==0){b=yYd(e);!b.c&&(b.c=new X9d);dHd(b.c,a.jj())}}break}case 6:{h=a.kj();if(h!=null){for(f=RD(h,16).Kc();f.Ob();){e=RD(f.Pb(),482);if((e.Bb&1)==0){b=yYd(e);!b.c&&(b.c=new X9d);dHd(b.c,a.jj())}}}break}}}this.ql(d)}};_.ql=function u$d(a){r$d(this,a)};_.b=63;var u9=sfb(SHe,'ESuperAdapter',1175);feb(1176,1175,EJe,w$d);_.ql=function x$d(a){v$d(this,a)};var N7=sfb(SHe,'EClassImpl/10',1176);feb(1165,710,oKe);_.Ei=function y$d(a,b){return IHd(this,a,b)};_.Fi=function z$d(a){return JHd(this,a)};_.Gi=function A$d(a,b){KHd(this,a,b)};_.Hi=function B$d(a){LHd(this,a)};_.$i=function D$d(a){return NHd(this,a)};_.Xi=function L$d(a,b){return UHd(this,a,b)};_.Wk=function C$d(a,b){throw Adb(new jib)};_.Ii=function E$d(){return new yMd(this)};_.Ji=function F$d(){return new BMd(this)};_.Ki=function G$d(a){return ZGd(this,a)};_.Xk=function H$d(a,b){throw Adb(new jib)};_.Fk=function I$d(a){return this};_.Qj=function J$d(){return this.i!=0};_.Wb=function K$d(a){throw Adb(new jib)};_.Gk=function M$d(){throw Adb(new jib)};var xbb=sfb(ZJe,'EcoreEList/UnmodifiableEList',1165);feb(328,1165,oKe,N$d);_.Yi=function O$d(){return false};var wbb=sfb(ZJe,'EcoreEList/UnmodifiableEList/FastCompare',328);feb(1168,328,oKe,R$d);_.dd=function S$d(a){var b,c,d;if(ZD(a,179)){b=RD(a,179);c=b.Lj();if(c!=-1){for(d=this.i;c4){if(this.fk(a)){if(this.al()){d=RD(a,54);c=d.Eh();h=c==this.b&&(this.ml()?d.yh(d.Fh(),RD(vYd(Uwd(this.b),this.Lj()).Hk(),29).kk())==Z5d(RD(vYd(Uwd(this.b),this.Lj()),19)).n:-1-d.Fh()==this.Lj());if(this.nl()&&!h&&!c&&!!d.Jh()){for(e=0;e1||d==-1)}else{return false}};_.ml=function a0d(){var a,b,c;b=vYd(Uwd(this.b),this.Lj());if(ZD(b,102)){a=RD(b,19);c=Z5d(a);return !!c}else{return false}};_.nl=function b0d(){var a,b;b=vYd(Uwd(this.b),this.Lj());if(ZD(b,102)){a=RD(b,19);return (a.Bb&txe)!=0}else{return false}};_.dd=function c0d(a){var b,c,d,e;d=this.zj(a);if(d>=0)return d;if(this.ol()){for(c=0,e=this.Ej();c=0;--a){N_d(this,a,this.xj(a))}}return this.Fj()};_.Qc=function o0d(a){var b;if(this.nl()){for(b=this.Ej()-1;b>=0;--b){N_d(this,b,this.xj(b))}}return this.Gj(a)};_.Gk=function p0d(){VJd(this)};_.Zi=function q0d(a,b){return P_d(this,a,b)};var Pab=sfb(ZJe,'DelegatingEcoreEList',756);feb(1171,756,tKe,w0d);_.qj=function z0d(a,b){r0d(this,a,RD(b,29))};_.rj=function A0d(a){s0d(this,RD(a,29))};_.xj=function G0d(a){var b,c;return b=RD(QHd(tYd(this.a),a),89),c=b.c,ZD(c,90)?RD(c,29):(JTd(),zTd)};_.Cj=function L0d(a){var b,c;return b=RD(vLd(tYd(this.a),a),89),c=b.c,ZD(c,90)?RD(c,29):(JTd(),zTd)};_.Dj=function M0d(a,b){return u0d(this,a,RD(b,29))};_.Li=function x0d(){return false};_.Ij=function y0d(a,b,c,d,e){return null};_.sj=function B0d(){return new c1d(this)};_.tj=function C0d(){sLd(tYd(this.a))};_.uj=function D0d(a){return t0d(this,a)};_.vj=function E0d(a){var b,c;for(c=a.Kc();c.Ob();){b=c.Pb();if(!t0d(this,b)){return false}}return true};_.wj=function F0d(a){var b,c,d;if(ZD(a,15)){d=RD(a,15);if(d.gc()==tYd(this.a).i){for(b=d.Kc(),c=new dMd(this);b.Ob();){if(dE(b.Pb())!==dE(bMd(c))){return false}}return true}}return false};_.yj=function H0d(){var a,b,c,d,e;c=1;for(b=new dMd(tYd(this.a));b.e!=b.i.gc();){a=RD(bMd(b),89);d=(e=a.c,ZD(e,90)?RD(e,29):(JTd(),zTd));c=31*c+(!d?0:kFb(d))}return c};_.zj=function I0d(a){var b,c,d,e;d=0;for(c=new dMd(tYd(this.a));c.e!=c.i.gc();){b=RD(bMd(c),89);if(dE(a)===dE((e=b.c,ZD(e,90)?RD(e,29):(JTd(),zTd)))){return d}++d}return -1};_.Aj=function J0d(){return tYd(this.a).i==0};_.Bj=function K0d(){return null};_.Ej=function N0d(){return tYd(this.a).i};_.Fj=function O0d(){var a,b,c,d,e,f;f=tYd(this.a).i;e=$C(jJ,rve,1,f,5,1);c=0;for(b=new dMd(tYd(this.a));b.e!=b.i.gc();){a=RD(bMd(b),89);e[c++]=(d=a.c,ZD(d,90)?RD(d,29):(JTd(),zTd))}return e};_.Gj=function P0d(a){var b,c,d,e,f,g,h;h=tYd(this.a).i;if(a.lengthh&&bD(a,h,null);d=0;for(c=new dMd(tYd(this.a));c.e!=c.i.gc();){b=RD(bMd(c),89);f=(g=b.c,ZD(g,90)?RD(g,29):(JTd(),zTd));bD(a,d++,f)}return a};_.Hj=function Q0d(){var a,b,c,d,e;e=new Qhb;e.a+='[';a=tYd(this.a);for(b=0,d=tYd(this.a).i;b>16,e>=0?AXd(this,c):this.Cb.Th(this,-1-e,null,c)));return xvd(this,a,6,c);case 9:return !this.a&&(this.a=new C5d(l7,this,9,5)),qLd(this.a,a,c);}return f=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),sTd):d),b),69),f.wk().zk(this,Wwd(this),b-AYd((JTd(),sTd)),a,c)};_.Uh=function D1d(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c);case 6:return xvd(this,null,6,c);case 7:return !this.A&&(this.A=new iie(z7,this,7)),rLd(this.A,a,c);case 9:return !this.a&&(this.a=new C5d(l7,this,9,5)),rLd(this.a,a,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),sTd):d),b),69),e.wk().Ak(this,Wwd(this),b-AYd((JTd(),sTd)),a,c)};_.Wh=function E1d(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.D!=null&&this.D==this.F;case 3:return !!DXd(this);case 4:return !!y1d(this);case 5:return this.F!=null&&this.F!=this.D&&this.F!=this.B;case 6:return !!xXd(this);case 7:return !!this.A&&this.A.i!=0;case 8:return (this.Bb&256)==0;case 9:return !!this.a&&this.a.i!=0;}return Avd(this,a-AYd((JTd(),sTd)),vYd((b=RD(Ywd(this,16),29),!b?sTd:b),a))};_.bi=function F1d(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:LXd(this,WD(b));return;case 2:IXd(this,WD(b));return;case 5:KXd(this,WD(b));return;case 7:!this.A&&(this.A=new iie(z7,this,7));sLd(this.A);!this.A&&(this.A=new iie(z7,this,7));YGd(this.A,RD(b,16));return;case 8:j1d(this,Heb(TD(b)));return;case 9:!this.a&&(this.a=new C5d(l7,this,9,5));sLd(this.a);!this.a&&(this.a=new C5d(l7,this,9,5));YGd(this.a,RD(b,16));return;}Bvd(this,a-AYd((JTd(),sTd)),vYd((c=RD(Ywd(this,16),29),!c?sTd:c),a),b)};_.ii=function G1d(){return JTd(),sTd};_.ki=function H1d(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:ZD(this.Cb,184)&&(RD(this.Cb,184).tb=null);PAd(this,null);return;case 2:yXd(this,null);zXd(this,this.D);return;case 5:KXd(this,null);return;case 7:!this.A&&(this.A=new iie(z7,this,7));sLd(this.A);return;case 8:j1d(this,true);return;case 9:!this.a&&(this.a=new C5d(l7,this,9,5));sLd(this.a);return;}Cvd(this,a-AYd((JTd(),sTd)),vYd((b=RD(Ywd(this,16),29),!b?sTd:b),a))};_.pi=function I1d(){var a,b;if(this.a){for(a=0,b=this.a.i;a>16==5?RD(this.Cb,685):null;}return zvd(this,a-AYd((JTd(),tTd)),vYd((d=RD(Ywd(this,16),29),!d?tTd:d),a),b,c)};_.Sh=function U1d(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),qLd(this.Ab,a,c);case 5:!!this.Cb&&(c=(e=this.Db>>16,e>=0?M1d(this,c):this.Cb.Th(this,-1-e,null,c)));return xvd(this,a,5,c);}return f=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),tTd):d),b),69),f.wk().zk(this,Wwd(this),b-AYd((JTd(),tTd)),a,c)};_.Uh=function V1d(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c);case 5:return xvd(this,null,5,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),tTd):d),b),69),e.wk().Ak(this,Wwd(this),b-AYd((JTd(),tTd)),a,c)};_.Wh=function W1d(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.d!=0;case 3:return !!this.b;case 4:return this.c!=null;case 5:return !!(this.Db>>16==5?RD(this.Cb,685):null);}return Avd(this,a-AYd((JTd(),tTd)),vYd((b=RD(Ywd(this,16),29),!b?tTd:b),a))};_.bi=function X1d(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:PAd(this,WD(b));return;case 2:Q1d(this,RD(b,17).a);return;case 3:O1d(this,RD(b,2039));return;case 4:P1d(this,WD(b));return;}Bvd(this,a-AYd((JTd(),tTd)),vYd((c=RD(Ywd(this,16),29),!c?tTd:c),a),b)};_.ii=function Y1d(){return JTd(),tTd};_.ki=function Z1d(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:PAd(this,null);return;case 2:Q1d(this,0);return;case 3:O1d(this,null);return;case 4:P1d(this,null);return;}Cvd(this,a-AYd((JTd(),tTd)),vYd((b=RD(Ywd(this,16),29),!b?tTd:b),a))};_.Ib=function _1d(){var a;return a=this.c,a==null?this.zb:a};_.b=null;_.c=null;_.d=0;var f8=sfb(SHe,'EEnumLiteralImpl',582);var h8=ufb(SHe,'EFactoryImpl/InternalEDateTimeFormat');feb(499,1,{2114:1},c2d);var g8=sfb(SHe,'EFactoryImpl/1ClientInternalEDateTimeFormat',499);feb(248,120,{110:1,94:1,93:1,89:1,58:1,114:1,54:1,99:1,248:1,119:1,120:1},s2d);_.Ch=function t2d(a,b,c){var d;c=xvd(this,a,b,c);if(!!this.e&&ZD(a,179)){d=k2d(this,this.e);d!=this.c&&(c=o2d(this,d,c))}return c};_.Lh=function u2d(a,b,c){var d;switch(a){case 0:return this.f;case 1:return !this.d&&(this.d=new XZd(o7,this,1)),this.d;case 2:if(b)return i2d(this);return this.c;case 3:return this.b;case 4:return this.e;case 5:if(b)return h2d(this);return this.a;}return zvd(this,a-AYd((JTd(),vTd)),vYd((d=RD(Ywd(this,16),29),!d?vTd:d),a),b,c)};_.Uh=function v2d(a,b,c){var d,e;switch(b){case 0:return g2d(this,null,c);case 1:return !this.d&&(this.d=new XZd(o7,this,1)),rLd(this.d,a,c);case 3:return e2d(this,null,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),vTd):d),b),69),e.wk().Ak(this,Wwd(this),b-AYd((JTd(),vTd)),a,c)};_.Wh=function w2d(a){var b;switch(a){case 0:return !!this.f;case 1:return !!this.d&&this.d.i!=0;case 2:return !!this.c;case 3:return !!this.b;case 4:return !!this.e;case 5:return !!this.a;}return Avd(this,a-AYd((JTd(),vTd)),vYd((b=RD(Ywd(this,16),29),!b?vTd:b),a))};_.bi=function x2d(a,b){var c;switch(a){case 0:q2d(this,RD(b,89));return;case 1:!this.d&&(this.d=new XZd(o7,this,1));sLd(this.d);!this.d&&(this.d=new XZd(o7,this,1));YGd(this.d,RD(b,16));return;case 3:n2d(this,RD(b,89));return;case 4:p2d(this,RD(b,850));return;case 5:l2d(this,RD(b,142));return;}Bvd(this,a-AYd((JTd(),vTd)),vYd((c=RD(Ywd(this,16),29),!c?vTd:c),a),b)};_.ii=function y2d(){return JTd(),vTd};_.ki=function z2d(a){var b;switch(a){case 0:q2d(this,null);return;case 1:!this.d&&(this.d=new XZd(o7,this,1));sLd(this.d);return;case 3:n2d(this,null);return;case 4:p2d(this,null);return;case 5:l2d(this,null);return;}Cvd(this,a-AYd((JTd(),vTd)),vYd((b=RD(Ywd(this,16),29),!b?vTd:b),a))};_.Ib=function A2d(){var a;a=new dib(awd(this));a.a+=' (expression: ';r2d(this,a);a.a+=')';return a.a};var d2d;var j8=sfb(SHe,'EGenericTypeImpl',248);feb(2067,2062,uKe);_.Gi=function C2d(a,b){B2d(this,a,b)};_.Wk=function D2d(a,b){B2d(this,this.gc(),a);return b};_.$i=function E2d(a){return ju(this.pj(),a)};_.Ii=function F2d(){return this.Ji()};_.pj=function G2d(){return new mee(this)};_.Ji=function H2d(){return this.Ki(0)};_.Ki=function I2d(a){return this.pj().fd(a)};_.Xk=function J2d(a,b){ze(this,a,true);return b};_.Ti=function K2d(a,b){var c,d;d=ku(this,b);c=this.fd(a);c.Rb(d);return d};_.Ui=function L2d(a,b){var c;ze(this,b,true);c=this.fd(a);c.Rb(b)};var Gab=sfb(ZJe,'AbstractSequentialInternalEList',2067);feb(496,2067,uKe,Q2d);_.$i=function R2d(a){return ju(this.pj(),a)};_.Ii=function S2d(){if(this.b==null){return j3d(),j3d(),i3d}return this.sl()};_.pj=function T2d(){return new Whe(this.a,this.b)};_.Ji=function U2d(){if(this.b==null){return j3d(),j3d(),i3d}return this.sl()};_.Ki=function V2d(a){var b,c;if(this.b==null){if(a<0||a>1){throw Adb(new veb(HJe+a+', size=0'))}return j3d(),j3d(),i3d}c=this.sl();for(b=0;b0){b=this.c[--this.d];if((!this.e||b.pk()!=C4||b.Lj()!=0)&&(!this.vl()||this.b.Xh(b))){f=this.b.Nh(b,this.ul());this.f=(nke(),RD(b,69).xk());if(this.f||b.Jk()){if(this.ul()){d=RD(f,15);this.k=d}else{d=RD(f,71);this.k=this.j=d}if(ZD(this.k,59)){this.o=this.k.gc();this.n=this.o}else{this.p=!this.j?this.k.fd(this.k.gc()):this.j.Ki(this.k.gc())}if(!this.p?n3d(this):o3d(this,this.p)){e=!this.p?!this.j?this.k.Xb(--this.n):this.j.$i(--this.n):this.p.Ub();if(this.f){a=RD(e,76);a.Lk();c=a.md();this.i=c}else{c=e;this.i=c}this.g=-3;return true}}else if(f!=null){this.k=null;this.p=null;c=f;this.i=c;this.g=-2;return true}}}this.k=null;this.p=null;this.g=-1;return false}else{e=!this.p?!this.j?this.k.Xb(--this.n):this.j.$i(--this.n):this.p.Ub();if(this.f){a=RD(e,76);a.Lk();c=a.md();this.i=c}else{c=e;this.i=c}this.g=-3;return true}}}};_.Pb=function v3d(){return k3d(this)};_.Tb=function w3d(){return this.a};_.Ub=function x3d(){var a;if(this.g<-1||this.Sb()){--this.a;this.g=0;a=this.i;this.Sb();return a}else{throw Adb(new Dvb)}};_.Vb=function y3d(){return this.a-1};_.Qb=function z3d(){throw Adb(new jib)};_.ul=function A3d(){return false};_.Wb=function B3d(a){throw Adb(new jib)};_.vl=function C3d(){return true};_.a=0;_.d=0;_.f=false;_.g=0;_.n=0;_.o=0;var i3d;var Uab=sfb(ZJe,'EContentsEList/FeatureIteratorImpl',287);feb(711,287,vKe,D3d);_.ul=function E3d(){return true};var Vab=sfb(ZJe,'EContentsEList/ResolvingFeatureIteratorImpl',711);feb(1178,711,vKe,F3d);_.vl=function G3d(){return false};var l8=sfb(SHe,'ENamedElementImpl/1/1',1178);feb(1179,287,vKe,H3d);_.vl=function I3d(){return false};var m8=sfb(SHe,'ENamedElementImpl/1/2',1179);feb(39,152,GJe,L3d,M3d,N3d,O3d,P3d,Q3d,R3d,S3d,T3d,U3d,V3d,W3d,X3d,Y3d,Z3d,$3d,_3d,a4d,b4d,c4d,d4d,e4d,f4d,g4d,h4d);_.Kj=function i4d(){return K3d(this)};_.Rj=function j4d(){var a;a=K3d(this);if(a){return a.ik()}return null};_.hj=function k4d(a){this.b==-1&&!!this.a&&(this.b=this.c.Hh(this.a.Lj(),this.a.pk()));return this.c.yh(this.b,a)};_.jj=function l4d(){return this.c};_.Sj=function m4d(){var a;a=K3d(this);if(a){return a.tk()}return false};_.b=-1;var p8=sfb(SHe,'ENotificationImpl',39);feb(411,292,{110:1,94:1,93:1,155:1,197:1,58:1,62:1,114:1,481:1,54:1,99:1,158:1,411:1,292:1,119:1,120:1},q4d);_.Ah=function r4d(a){return n4d(this,a)};_.Lh=function s4d(a,b,c){var d,e,f;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Geb(),(this.Bb&256)!=0?true:false;case 3:return Geb(),(this.Bb&512)!=0?true:false;case 4:return sgb(this.s);case 5:return sgb(this.t);case 6:return Geb(),f=this.t,f>1||f==-1?true:false;case 7:return Geb(),e=this.s,e>=1?true:false;case 8:if(b)return WVd(this);return this.r;case 9:return this.q;case 10:return this.Db>>16==10?RD(this.Cb,29):null;case 11:return !this.d&&(this.d=new iie(z7,this,11)),this.d;case 12:return !this.c&&(this.c=new C5d(u7,this,12,10)),this.c;case 13:return !this.a&&(this.a=new F4d(this,this)),this.a;case 14:return o4d(this);}return zvd(this,a-AYd((JTd(),ATd)),vYd((d=RD(Ywd(this,16),29),!d?ATd:d),a),b,c)};_.Sh=function t4d(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),qLd(this.Ab,a,c);case 10:!!this.Cb&&(c=(e=this.Db>>16,e>=0?n4d(this,c):this.Cb.Th(this,-1-e,null,c)));return xvd(this,a,10,c);case 12:return !this.c&&(this.c=new C5d(u7,this,12,10)),qLd(this.c,a,c);}return f=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),ATd):d),b),69),f.wk().zk(this,Wwd(this),b-AYd((JTd(),ATd)),a,c)};_.Uh=function u4d(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c);case 9:return VVd(this,c);case 10:return xvd(this,null,10,c);case 11:return !this.d&&(this.d=new iie(z7,this,11)),rLd(this.d,a,c);case 12:return !this.c&&(this.c=new C5d(u7,this,12,10)),rLd(this.c,a,c);case 14:return rLd(o4d(this),a,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),ATd):d),b),69),e.wk().Ak(this,Wwd(this),b-AYd((JTd(),ATd)),a,c)};_.Wh=function v4d(a){var b,c,d;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return (this.Bb&256)==0;case 3:return (this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return d=this.t,d>1||d==-1;case 7:return c=this.s,c>=1;case 8:return !!this.r&&!this.q.e&&j2d(this.q).i==0;case 9:return !!this.q&&!(!!this.r&&!this.q.e&&j2d(this.q).i==0);case 10:return !!(this.Db>>16==10?RD(this.Cb,29):null);case 11:return !!this.d&&this.d.i!=0;case 12:return !!this.c&&this.c.i!=0;case 13:return !!this.a&&o4d(this.a.a).i!=0&&!(!!this.b&&o5d(this.b));case 14:return !!this.b&&o5d(this.b);}return Avd(this,a-AYd((JTd(),ATd)),vYd((b=RD(Ywd(this,16),29),!b?ATd:b),a))};_.bi=function w4d(a,b){var c,d;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:PAd(this,WD(b));return;case 2:_Vd(this,Heb(TD(b)));return;case 3:aWd(this,Heb(TD(b)));return;case 4:$Vd(this,RD(b,17).a);return;case 5:bWd(this,RD(b,17).a);return;case 8:YVd(this,RD(b,142));return;case 9:d=XVd(this,RD(b,89),null);!!d&&d.oj();return;case 11:!this.d&&(this.d=new iie(z7,this,11));sLd(this.d);!this.d&&(this.d=new iie(z7,this,11));YGd(this.d,RD(b,16));return;case 12:!this.c&&(this.c=new C5d(u7,this,12,10));sLd(this.c);!this.c&&(this.c=new C5d(u7,this,12,10));YGd(this.c,RD(b,16));return;case 13:!this.a&&(this.a=new F4d(this,this));VJd(this.a);!this.a&&(this.a=new F4d(this,this));YGd(this.a,RD(b,16));return;case 14:sLd(o4d(this));YGd(o4d(this),RD(b,16));return;}Bvd(this,a-AYd((JTd(),ATd)),vYd((c=RD(Ywd(this,16),29),!c?ATd:c),a),b)};_.ii=function x4d(){return JTd(),ATd};_.ki=function y4d(a){var b,c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:PAd(this,null);return;case 2:_Vd(this,true);return;case 3:aWd(this,true);return;case 4:$Vd(this,0);return;case 5:bWd(this,1);return;case 8:YVd(this,null);return;case 9:c=XVd(this,null,null);!!c&&c.oj();return;case 11:!this.d&&(this.d=new iie(z7,this,11));sLd(this.d);return;case 12:!this.c&&(this.c=new C5d(u7,this,12,10));sLd(this.c);return;case 13:!!this.a&&VJd(this.a);return;case 14:!!this.b&&sLd(this.b);return;}Cvd(this,a-AYd((JTd(),ATd)),vYd((b=RD(Ywd(this,16),29),!b?ATd:b),a))};_.pi=function z4d(){var a,b;if(this.c){for(a=0,b=this.c.i;ah&&bD(a,h,null);d=0;for(c=new dMd(o4d(this.a));c.e!=c.i.gc();){b=RD(bMd(c),89);f=(g=b.c,g?g:(JTd(),wTd));bD(a,d++,f)}return a};_.Hj=function Z4d(){var a,b,c,d,e;e=new Qhb;e.a+='[';a=o4d(this.a);for(b=0,d=o4d(this.a).i;b1)}case 5:{return dZd(this,a,b,c,d,this.i-RD(c,15).gc()>0)}default:{return new P3d(this.e,a,this.c,b,c,d,true)}}};_.Tj=function u5d(){return true};_.Qj=function v5d(){return o5d(this)};_.Gk=function A5d(){sLd(this)};var t8=sfb(SHe,'EOperationImpl/2',1377);feb(507,1,{2037:1,507:1},B5d);var v8=sfb(SHe,'EPackageImpl/1',507);feb(14,83,oKe,C5d);_.il=function D5d(){return this.d};_.jl=function E5d(){return this.b};_.ml=function F5d(){return true};_.b=0;var gbb=sfb(ZJe,'EObjectContainmentWithInverseEList',14);feb(365,14,oKe,G5d);_.nl=function H5d(){return true};_.Wi=function I5d(a,b){return gZd(this,a,RD(b,58))};var dbb=sfb(ZJe,'EObjectContainmentWithInverseEList/Resolving',365);feb(308,365,oKe,J5d);_.Ni=function K5d(){this.a.tb=null};var w8=sfb(SHe,'EPackageImpl/2',308);feb(1278,1,{},L5d);var x8=sfb(SHe,'EPackageImpl/3',1278);feb(733,45,Hxe,O5d);_._b=function P5d(a){return bE(a)?Yjb(this,a):!!qtb(this.f,a)};var z8=sfb(SHe,'EPackageRegistryImpl',733);feb(518,292,{110:1,94:1,93:1,155:1,197:1,58:1,2116:1,114:1,481:1,54:1,99:1,158:1,518:1,292:1,119:1,120:1},R5d);_.Ah=function S5d(a){return Q5d(this,a)};_.Lh=function T5d(a,b,c){var d,e,f;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Geb(),(this.Bb&256)!=0?true:false;case 3:return Geb(),(this.Bb&512)!=0?true:false;case 4:return sgb(this.s);case 5:return sgb(this.t);case 6:return Geb(),f=this.t,f>1||f==-1?true:false;case 7:return Geb(),e=this.s,e>=1?true:false;case 8:if(b)return WVd(this);return this.r;case 9:return this.q;case 10:return this.Db>>16==10?RD(this.Cb,62):null;}return zvd(this,a-AYd((JTd(),DTd)),vYd((d=RD(Ywd(this,16),29),!d?DTd:d),a),b,c)};_.Sh=function U5d(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),qLd(this.Ab,a,c);case 10:!!this.Cb&&(c=(e=this.Db>>16,e>=0?Q5d(this,c):this.Cb.Th(this,-1-e,null,c)));return xvd(this,a,10,c);}return f=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),DTd):d),b),69),f.wk().zk(this,Wwd(this),b-AYd((JTd(),DTd)),a,c)};_.Uh=function V5d(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c);case 9:return VVd(this,c);case 10:return xvd(this,null,10,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),DTd):d),b),69),e.wk().Ak(this,Wwd(this),b-AYd((JTd(),DTd)),a,c)};_.Wh=function W5d(a){var b,c,d;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return (this.Bb&256)==0;case 3:return (this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return d=this.t,d>1||d==-1;case 7:return c=this.s,c>=1;case 8:return !!this.r&&!this.q.e&&j2d(this.q).i==0;case 9:return !!this.q&&!(!!this.r&&!this.q.e&&j2d(this.q).i==0);case 10:return !!(this.Db>>16==10?RD(this.Cb,62):null);}return Avd(this,a-AYd((JTd(),DTd)),vYd((b=RD(Ywd(this,16),29),!b?DTd:b),a))};_.ii=function X5d(){return JTd(),DTd};var A8=sfb(SHe,'EParameterImpl',518);feb(102,462,{110:1,94:1,93:1,155:1,197:1,58:1,19:1,179:1,69:1,114:1,481:1,54:1,99:1,158:1,102:1,462:1,292:1,119:1,120:1,692:1},d6d);_.Lh=function e6d(a,b,c){var d,e,f,g;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Geb(),(this.Bb&256)!=0?true:false;case 3:return Geb(),(this.Bb&512)!=0?true:false;case 4:return sgb(this.s);case 5:return sgb(this.t);case 6:return Geb(),g=this.t,g>1||g==-1?true:false;case 7:return Geb(),e=this.s,e>=1?true:false;case 8:if(b)return WVd(this);return this.r;case 9:return this.q;case 10:return Geb(),(this.Bb&gwe)!=0?true:false;case 11:return Geb(),(this.Bb&cKe)!=0?true:false;case 12:return Geb(),(this.Bb&qxe)!=0?true:false;case 13:return this.j;case 14:return tWd(this);case 15:return Geb(),(this.Bb&bKe)!=0?true:false;case 16:return Geb(),(this.Bb&Ove)!=0?true:false;case 17:return uWd(this);case 18:return Geb(),(this.Bb&QHe)!=0?true:false;case 19:return Geb(),f=Z5d(this),!!f&&(f.Bb&QHe)!=0?true:false;case 20:return Geb(),(this.Bb&txe)!=0?true:false;case 21:if(b)return Z5d(this);return this.b;case 22:if(b)return $5d(this);return Y5d(this);case 23:return !this.a&&(this.a=new zie(g7,this,23)),this.a;}return zvd(this,a-AYd((JTd(),ETd)),vYd((d=RD(Ywd(this,16),29),!d?ETd:d),a),b,c)};_.Wh=function f6d(a){var b,c,d,e;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return (this.Bb&256)==0;case 3:return (this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return e=this.t,e>1||e==-1;case 7:return c=this.s,c>=1;case 8:return !!this.r&&!this.q.e&&j2d(this.q).i==0;case 9:return !!this.q&&!(!!this.r&&!this.q.e&&j2d(this.q).i==0);case 10:return (this.Bb&gwe)==0;case 11:return (this.Bb&cKe)!=0;case 12:return (this.Bb&qxe)!=0;case 13:return this.j!=null;case 14:return tWd(this)!=null;case 15:return (this.Bb&bKe)!=0;case 16:return (this.Bb&Ove)!=0;case 17:return !!uWd(this);case 18:return (this.Bb&QHe)!=0;case 19:return d=Z5d(this),!!d&&(d.Bb&QHe)!=0;case 20:return (this.Bb&txe)==0;case 21:return !!this.b;case 22:return !!Y5d(this);case 23:return !!this.a&&this.a.i!=0;}return Avd(this,a-AYd((JTd(),ETd)),vYd((b=RD(Ywd(this,16),29),!b?ETd:b),a))};_.bi=function g6d(a,b){var c,d;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:CWd(this,WD(b));return;case 2:_Vd(this,Heb(TD(b)));return;case 3:aWd(this,Heb(TD(b)));return;case 4:$Vd(this,RD(b,17).a);return;case 5:bWd(this,RD(b,17).a);return;case 8:YVd(this,RD(b,142));return;case 9:d=XVd(this,RD(b,89),null);!!d&&d.oj();return;case 10:xWd(this,Heb(TD(b)));return;case 11:FWd(this,Heb(TD(b)));return;case 12:DWd(this,Heb(TD(b)));return;case 13:yWd(this,WD(b));return;case 15:EWd(this,Heb(TD(b)));return;case 16:AWd(this,Heb(TD(b)));return;case 18:_5d(this,Heb(TD(b)));return;case 20:c6d(this,Heb(TD(b)));return;case 21:b6d(this,RD(b,19));return;case 23:!this.a&&(this.a=new zie(g7,this,23));sLd(this.a);!this.a&&(this.a=new zie(g7,this,23));YGd(this.a,RD(b,16));return;}Bvd(this,a-AYd((JTd(),ETd)),vYd((c=RD(Ywd(this,16),29),!c?ETd:c),a),b)};_.ii=function h6d(){return JTd(),ETd};_.ki=function i6d(a){var b,c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:ZD(this.Cb,90)&&v$d(yYd(RD(this.Cb,90)),4);PAd(this,null);return;case 2:_Vd(this,true);return;case 3:aWd(this,true);return;case 4:$Vd(this,0);return;case 5:bWd(this,1);return;case 8:YVd(this,null);return;case 9:c=XVd(this,null,null);!!c&&c.oj();return;case 10:xWd(this,true);return;case 11:FWd(this,false);return;case 12:DWd(this,false);return;case 13:this.i=null;zWd(this,null);return;case 15:EWd(this,false);return;case 16:AWd(this,false);return;case 18:a6d(this,false);ZD(this.Cb,90)&&v$d(yYd(RD(this.Cb,90)),2);return;case 20:c6d(this,true);return;case 21:b6d(this,null);return;case 23:!this.a&&(this.a=new zie(g7,this,23));sLd(this.a);return;}Cvd(this,a-AYd((JTd(),ETd)),vYd((b=RD(Ywd(this,16),29),!b?ETd:b),a))};_.pi=function j6d(){$5d(this);Afe(Qee((lke(),jke),this));WVd(this);this.Bb|=1};_.uk=function k6d(){return Z5d(this)};_._k=function l6d(){var a;return a=Z5d(this),!!a&&(a.Bb&QHe)!=0};_.al=function m6d(){return (this.Bb&QHe)!=0};_.bl=function n6d(){return (this.Bb&txe)!=0};_.Yk=function o6d(a,b){this.c=null;return ZVd(this,a,b)};_.Ib=function p6d(){var a;if((this.Db&64)!=0)return GWd(this);a=new Shb(GWd(this));a.a+=' (containment: ';Ohb(a,(this.Bb&QHe)!=0);a.a+=', resolveProxies: ';Ohb(a,(this.Bb&txe)!=0);a.a+=')';return a.a};var B8=sfb(SHe,'EReferenceImpl',102);feb(561,120,{110:1,44:1,94:1,93:1,136:1,58:1,114:1,54:1,99:1,561:1,119:1,120:1},v6d);_.Fb=function B6d(a){return this===a};_.ld=function D6d(){return this.b};_.md=function E6d(){return this.c};_.Hb=function F6d(){return kFb(this)};_.Di=function H6d(a){q6d(this,WD(a))};_.nd=function I6d(a){return u6d(this,WD(a))};_.Lh=function w6d(a,b,c){var d;switch(a){case 0:return this.b;case 1:return this.c;}return zvd(this,a-AYd((JTd(),FTd)),vYd((d=RD(Ywd(this,16),29),!d?FTd:d),a),b,c)};_.Wh=function x6d(a){var b;switch(a){case 0:return this.b!=null;case 1:return this.c!=null;}return Avd(this,a-AYd((JTd(),FTd)),vYd((b=RD(Ywd(this,16),29),!b?FTd:b),a))};_.bi=function y6d(a,b){var c;switch(a){case 0:r6d(this,WD(b));return;case 1:t6d(this,WD(b));return;}Bvd(this,a-AYd((JTd(),FTd)),vYd((c=RD(Ywd(this,16),29),!c?FTd:c),a),b)};_.ii=function z6d(){return JTd(),FTd};_.ki=function A6d(a){var b;switch(a){case 0:s6d(this,null);return;case 1:t6d(this,null);return;}Cvd(this,a-AYd((JTd(),FTd)),vYd((b=RD(Ywd(this,16),29),!b?FTd:b),a))};_.Bi=function C6d(){var a;if(this.a==-1){a=this.b;this.a=a==null?0:ohb(a)}return this.a};_.Ci=function G6d(a){this.a=a};_.Ib=function J6d(){var a;if((this.Db&64)!=0)return awd(this);a=new Shb(awd(this));a.a+=' (key: ';Nhb(a,this.b);a.a+=', value: ';Nhb(a,this.c);a.a+=')';return a.a};_.a=-1;_.b=null;_.c=null;var C8=sfb(SHe,'EStringToStringMapEntryImpl',561);var Ibb=ufb(ZJe,'FeatureMap/Entry/Internal');feb(576,1,wKe);_.xl=function M6d(a){return this.yl(RD(a,54))};_.yl=function N6d(a){return this.xl(a)};_.Fb=function O6d(a){var b,c;if(this===a){return true}else if(ZD(a,76)){b=RD(a,76);if(b.Lk()==this.c){c=this.md();return c==null?b.md()==null:pb(c,b.md())}else{return false}}else{return false}};_.Lk=function P6d(){return this.c};_.Hb=function Q6d(){var a;a=this.md();return tb(this.c)^(a==null?0:tb(a))};_.Ib=function R6d(){var a,b;a=this.c;b=BXd(a.qk()).yi();a.xe();return (b!=null&&b.length!=0?b+':'+a.xe():a.xe())+'='+this.md()};var D8=sfb(SHe,'EStructuralFeatureImpl/BasicFeatureMapEntry',576);feb(791,576,wKe,U6d);_.yl=function V6d(a){return new U6d(this.c,a)};_.md=function W6d(){return this.a};_.zl=function X6d(a,b,c){return S6d(this,a,this.a,b,c)};_.Al=function Y6d(a,b,c){return T6d(this,a,this.a,b,c)};var E8=sfb(SHe,'EStructuralFeatureImpl/ContainmentUpdatingFeatureMapEntry',791);feb(1350,1,{},Z6d);_.yk=function $6d(a,b,c,d,e){var f;f=RD(Evd(a,this.b),220);return f.Yl(this.a).Fk(d)};_.zk=function _6d(a,b,c,d,e){var f;f=RD(Evd(a,this.b),220);return f.Pl(this.a,d,e)};_.Ak=function a7d(a,b,c,d,e){var f;f=RD(Evd(a,this.b),220);return f.Ql(this.a,d,e)};_.Bk=function b7d(a,b,c){var d;d=RD(Evd(a,this.b),220);return d.Yl(this.a).Qj()};_.Ck=function c7d(a,b,c,d){var e;e=RD(Evd(a,this.b),220);e.Yl(this.a).Wb(d)};_.Dk=function d7d(a,b,c){return RD(Evd(a,this.b),220).Yl(this.a)};_.Ek=function e7d(a,b,c){var d;d=RD(Evd(a,this.b),220);d.Yl(this.a).Gk()};var F8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateFeatureMapDelegator',1350);feb(91,1,{},g7d,h7d,i7d,j7d);_.yk=function k7d(a,b,c,d,e){var f;f=b.li(c);f==null&&b.mi(c,f=f7d(this,a));if(!e){switch(this.e){case 50:case 41:return RD(f,597).bk();case 40:return RD(f,220).Vl();}}return f};_.zk=function l7d(a,b,c,d,e){var f,g;g=b.li(c);g==null&&b.mi(c,g=f7d(this,a));f=RD(g,71).Wk(d,e);return f};_.Ak=function m7d(a,b,c,d,e){var f;f=b.li(c);f!=null&&(e=RD(f,71).Xk(d,e));return e};_.Bk=function n7d(a,b,c){var d;d=b.li(c);return d!=null&&RD(d,79).Qj()};_.Ck=function o7d(a,b,c,d){var e;e=RD(b.li(c),79);!e&&b.mi(c,e=f7d(this,a));e.Wb(d)};_.Dk=function p7d(a,b,c){var d,e;e=b.li(c);e==null&&b.mi(c,e=f7d(this,a));if(ZD(e,79)){return RD(e,79)}else{d=RD(b.li(c),15);return new I9d(d)}};_.Ek=function q7d(a,b,c){var d;d=RD(b.li(c),79);!d&&b.mi(c,d=f7d(this,a));d.Gk()};_.b=0;_.e=0;var G8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateMany',91);feb(512,1,{});_.zk=function u7d(a,b,c,d,e){throw Adb(new jib)};_.Ak=function v7d(a,b,c,d,e){throw Adb(new jib)};_.Dk=function w7d(a,b,c){return new x7d(this,a,b,c)};var r7d;var n9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingle',512);feb(1367,1,$Je,x7d);_.Fk=function y7d(a){return this.a.yk(this.c,this.d,this.b,a,true)};_.Qj=function z7d(){return this.a.Bk(this.c,this.d,this.b)};_.Wb=function A7d(a){this.a.Ck(this.c,this.d,this.b,a)};_.Gk=function B7d(){this.a.Ek(this.c,this.d,this.b)};_.b=0;var H8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingle/1',1367);feb(784,512,{},C7d);_.yk=function D7d(a,b,c,d,e){return jwd(a,a.Ph(),a.Fh())==this.b?this.bl()&&d?yvd(a):a.Ph():null};_.zk=function E7d(a,b,c,d,e){var f,g;!!a.Ph()&&(e=(f=a.Fh(),f>=0?a.Ah(e):a.Ph().Th(a,-1-f,null,e)));g=BYd(a.Dh(),this.e);return a.Ch(d,g,e)};_.Ak=function F7d(a,b,c,d,e){var f;f=BYd(a.Dh(),this.e);return a.Ch(null,f,e)};_.Bk=function G7d(a,b,c){var d;d=BYd(a.Dh(),this.e);return !!a.Ph()&&a.Fh()==d};_.Ck=function H7d(a,b,c,d){var e,f,g,h,i;if(d!=null&&!FXd(this.a,d)){throw Adb(new Ifb(xKe+(ZD(d,58)?GYd(RD(d,58).Dh()):ofb(rb(d)))+yKe+this.a+"'"))}e=a.Ph();g=BYd(a.Dh(),this.e);if(dE(d)!==dE(e)||a.Fh()!=g&&d!=null){if(Oje(a,RD(d,58)))throw Adb(new agb(UHe+a.Ib()));i=null;!!e&&(i=(f=a.Fh(),f>=0?a.Ah(i):a.Ph().Th(a,-1-f,null,i)));h=RD(d,54);!!h&&(i=h.Rh(a,BYd(h.Dh(),this.b),null,i));i=a.Ch(h,g,i);!!i&&i.oj()}else{a.vh()&&a.wh()&&qvd(a,new N3d(a,1,g,d,d))}};_.Ek=function I7d(a,b,c){var d,e,f,g;d=a.Ph();if(d){g=(e=a.Fh(),e>=0?a.Ah(null):a.Ph().Th(a,-1-e,null,null));f=BYd(a.Dh(),this.e);g=a.Ch(null,f,g);!!g&&g.oj()}else{a.vh()&&a.wh()&&qvd(a,new b4d(a,1,this.e,null,null))}};_.bl=function J7d(){return false};var J8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleContainer',784);feb(1351,784,{},K7d);_.bl=function L7d(){return true};var I8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleContainerResolving',1351);feb(574,512,{});_.yk=function O7d(a,b,c,d,e){var f;return f=b.li(c),f==null?this.b:dE(f)===dE(r7d)?null:f};_.Bk=function P7d(a,b,c){var d;d=b.li(c);return d!=null&&(dE(d)===dE(r7d)||!pb(d,this.b))};_.Ck=function Q7d(a,b,c,d){var e,f;if(a.vh()&&a.wh()){e=(f=b.li(c),f==null?this.b:dE(f)===dE(r7d)?null:f);if(d==null){if(this.c!=null){b.mi(c,null);d=this.b}else this.b!=null?b.mi(c,r7d):b.mi(c,null)}else{this.Bl(d);b.mi(c,d)}qvd(a,this.d.Cl(a,1,this.e,e,d))}else{if(d==null){this.c!=null?b.mi(c,null):this.b!=null?b.mi(c,r7d):b.mi(c,null)}else{this.Bl(d);b.mi(c,d)}}};_.Ek=function R7d(a,b,c){var d,e;if(a.vh()&&a.wh()){d=(e=b.li(c),e==null?this.b:dE(e)===dE(r7d)?null:e);b.ni(c);qvd(a,this.d.Cl(a,1,this.e,d,this.b))}else{b.ni(c)}};_.Bl=function S7d(a){throw Adb(new Hfb)};var Y8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleData',574);feb(zKe,1,{},b8d);_.Cl=function c8d(a,b,c,d,e){return new b4d(a,b,c,d,e)};_.Dl=function d8d(a,b,c,d,e,f){return new d4d(a,b,c,d,e,f)};var T7d,U7d,V7d,W7d,X7d,Y7d,Z7d,$7d,_7d;var S8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator',zKe);feb(1368,zKe,{},e8d);_.Cl=function f8d(a,b,c,d,e){return new g4d(a,b,c,Heb(TD(d)),Heb(TD(e)))};_.Dl=function g8d(a,b,c,d,e,f){return new h4d(a,b,c,Heb(TD(d)),Heb(TD(e)),f)};var K8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/1',1368);feb(1369,zKe,{},h8d);_.Cl=function i8d(a,b,c,d,e){return new R3d(a,b,c,RD(d,222).a,RD(e,222).a)};_.Dl=function j8d(a,b,c,d,e,f){return new S3d(a,b,c,RD(d,222).a,RD(e,222).a,f)};var L8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/2',1369);feb(1370,zKe,{},k8d);_.Cl=function l8d(a,b,c,d,e){return new T3d(a,b,c,RD(d,180).a,RD(e,180).a)};_.Dl=function m8d(a,b,c,d,e,f){return new U3d(a,b,c,RD(d,180).a,RD(e,180).a,f)};var M8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/3',1370);feb(1371,zKe,{},n8d);_.Cl=function o8d(a,b,c,d,e){return new V3d(a,b,c,Kfb(UD(d)),Kfb(UD(e)))};_.Dl=function p8d(a,b,c,d,e,f){return new W3d(a,b,c,Kfb(UD(d)),Kfb(UD(e)),f)};var N8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/4',1371);feb(1372,zKe,{},q8d);_.Cl=function r8d(a,b,c,d,e){return new X3d(a,b,c,RD(d,161).a,RD(e,161).a)};_.Dl=function s8d(a,b,c,d,e,f){return new Y3d(a,b,c,RD(d,161).a,RD(e,161).a,f)};var O8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/5',1372);feb(1373,zKe,{},t8d);_.Cl=function u8d(a,b,c,d,e){return new Z3d(a,b,c,RD(d,17).a,RD(e,17).a)};_.Dl=function v8d(a,b,c,d,e,f){return new $3d(a,b,c,RD(d,17).a,RD(e,17).a,f)};var P8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/6',1373);feb(1374,zKe,{},w8d);_.Cl=function x8d(a,b,c,d,e){return new _3d(a,b,c,RD(d,168).a,RD(e,168).a)};_.Dl=function y8d(a,b,c,d,e,f){return new a4d(a,b,c,RD(d,168).a,RD(e,168).a,f)};var Q8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/7',1374);feb(1375,zKe,{},z8d);_.Cl=function A8d(a,b,c,d,e){return new e4d(a,b,c,RD(d,191).a,RD(e,191).a)};_.Dl=function B8d(a,b,c,d,e,f){return new f4d(a,b,c,RD(d,191).a,RD(e,191).a,f)};var R8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/8',1375);feb(1353,574,{},C8d);_.Bl=function D8d(a){if(!this.a.fk(a)){throw Adb(new Ifb(xKe+rb(a)+yKe+this.a+"'"))}};var T8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleDataDynamic',1353);feb(1354,574,{},E8d);_.Bl=function F8d(a){};var U8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleDataStatic',1354);feb(785,574,{});_.Bk=function G8d(a,b,c){var d;d=b.li(c);return d!=null};_.Ck=function H8d(a,b,c,d){var e,f;if(a.vh()&&a.wh()){e=true;f=b.li(c);if(f==null){e=false;f=this.b}else dE(f)===dE(r7d)&&(f=null);if(d==null){if(this.c!=null){b.mi(c,null);d=this.b}else{b.mi(c,r7d)}}else{this.Bl(d);b.mi(c,d)}qvd(a,this.d.Dl(a,1,this.e,f,d,!e))}else{if(d==null){this.c!=null?b.mi(c,null):b.mi(c,r7d)}else{this.Bl(d);b.mi(c,d)}}};_.Ek=function I8d(a,b,c){var d,e;if(a.vh()&&a.wh()){d=true;e=b.li(c);if(e==null){d=false;e=this.b}else dE(e)===dE(r7d)&&(e=null);b.ni(c);qvd(a,this.d.Dl(a,2,this.e,e,this.b,d))}else{b.ni(c)}};var X8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettable',785);feb(1355,785,{},J8d);_.Bl=function K8d(a){if(!this.a.fk(a)){throw Adb(new Ifb(xKe+rb(a)+yKe+this.a+"'"))}};var V8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableDynamic',1355);feb(1356,785,{},L8d);_.Bl=function M8d(a){};var W8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableStatic',1356);feb(410,512,{},N8d);_.yk=function P8d(a,b,c,d,e){var f,g,h,i,j;j=b.li(c);if(this.tk()&&dE(j)===dE(r7d)){return null}else if(this.bl()&&d&&j!=null){h=RD(j,54);if(h.Vh()){i=Vvd(a,h);if(h!=i){if(!FXd(this.a,i)){throw Adb(new Ifb(xKe+rb(i)+yKe+this.a+"'"))}b.mi(c,j=i);if(this.al()){f=RD(i,54);g=h.Th(a,!this.b?-1-BYd(a.Dh(),this.e):BYd(h.Dh(),this.b),null,null);!f.Ph()&&(g=f.Rh(a,!this.b?-1-BYd(a.Dh(),this.e):BYd(f.Dh(),this.b),null,g));!!g&&g.oj()}a.vh()&&a.wh()&&qvd(a,new b4d(a,9,this.e,h,i))}}return j}else{return j}};_.zk=function Q8d(a,b,c,d,e){var f,g;g=b.li(c);dE(g)===dE(r7d)&&(g=null);b.mi(c,d);if(this.Mj()){if(dE(g)!==dE(d)&&g!=null){f=RD(g,54);e=f.Th(a,BYd(f.Dh(),this.b),null,e)}}else this.al()&&g!=null&&(e=RD(g,54).Th(a,-1-BYd(a.Dh(),this.e),null,e));if(a.vh()&&a.wh()){!e&&(e=new gLd(4));e.nj(new b4d(a,1,this.e,g,d))}return e};_.Ak=function R8d(a,b,c,d,e){var f;f=b.li(c);dE(f)===dE(r7d)&&(f=null);b.ni(c);if(a.vh()&&a.wh()){!e&&(e=new gLd(4));this.tk()?e.nj(new b4d(a,2,this.e,f,null)):e.nj(new b4d(a,1,this.e,f,null))}return e};_.Bk=function S8d(a,b,c){var d;d=b.li(c);return d!=null};_.Ck=function T8d(a,b,c,d){var e,f,g,h,i;if(d!=null&&!FXd(this.a,d)){throw Adb(new Ifb(xKe+(ZD(d,58)?GYd(RD(d,58).Dh()):ofb(rb(d)))+yKe+this.a+"'"))}i=b.li(c);h=i!=null;this.tk()&&dE(i)===dE(r7d)&&(i=null);g=null;if(this.Mj()){if(dE(i)!==dE(d)){if(i!=null){e=RD(i,54);g=e.Th(a,BYd(e.Dh(),this.b),null,g)}if(d!=null){e=RD(d,54);g=e.Rh(a,BYd(e.Dh(),this.b),null,g)}}}else if(this.al()){if(dE(i)!==dE(d)){i!=null&&(g=RD(i,54).Th(a,-1-BYd(a.Dh(),this.e),null,g));d!=null&&(g=RD(d,54).Rh(a,-1-BYd(a.Dh(),this.e),null,g))}}d==null&&this.tk()?b.mi(c,r7d):b.mi(c,d);if(a.vh()&&a.wh()){f=new d4d(a,1,this.e,i,d,this.tk()&&!h);if(!g){qvd(a,f)}else{g.nj(f);g.oj()}}else !!g&&g.oj()};_.Ek=function U8d(a,b,c){var d,e,f,g,h;h=b.li(c);g=h!=null;this.tk()&&dE(h)===dE(r7d)&&(h=null);f=null;if(h!=null){if(this.Mj()){d=RD(h,54);f=d.Th(a,BYd(d.Dh(),this.b),null,f)}else this.al()&&(f=RD(h,54).Th(a,-1-BYd(a.Dh(),this.e),null,f))}b.ni(c);if(a.vh()&&a.wh()){e=new d4d(a,this.tk()?2:1,this.e,h,null,g);if(!f){qvd(a,e)}else{f.nj(e);f.oj()}}else !!f&&f.oj()};_.Mj=function V8d(){return false};_.al=function W8d(){return false};_.bl=function X8d(){return false};_.tk=function Y8d(){return false};var m9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObject',410);feb(575,410,{},Z8d);_.al=function $8d(){return true};var e9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainment',575);feb(1359,575,{},_8d);_.bl=function a9d(){return true};var Z8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentResolving',1359);feb(787,575,{},b9d);_.tk=function c9d(){return true};var _8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettable',787);feb(1361,787,{},d9d);_.bl=function e9d(){return true};var $8=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettableResolving',1361);feb(650,575,{},f9d);_.Mj=function g9d(){return true};var d9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverse',650);feb(1360,650,{},h9d);_.bl=function i9d(){return true};var a9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseResolving',1360);feb(788,650,{},j9d);_.tk=function k9d(){return true};var c9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettable',788);feb(1362,788,{},l9d);_.bl=function m9d(){return true};var b9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettableResolving',1362);feb(651,410,{},n9d);_.bl=function o9d(){return true};var i9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolving',651);feb(1363,651,{},p9d);_.tk=function q9d(){return true};var f9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingUnsettable',1363);feb(789,651,{},r9d);_.Mj=function s9d(){return true};var h9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverse',789);feb(1364,789,{},t9d);_.tk=function u9d(){return true};var g9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverseUnsettable',1364);feb(1357,410,{},v9d);_.tk=function w9d(){return true};var j9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectUnsettable',1357);feb(786,410,{},x9d);_.Mj=function y9d(){return true};var l9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverse',786);feb(1358,786,{},z9d);_.tk=function A9d(){return true};var k9=sfb(SHe,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverseUnsettable',1358);feb(790,576,wKe,D9d);_.yl=function E9d(a){return new D9d(this.a,this.c,a)};_.md=function F9d(){return this.b};_.zl=function G9d(a,b,c){return B9d(this,a,this.b,c)};_.Al=function H9d(a,b,c){return C9d(this,a,this.b,c)};var o9=sfb(SHe,'EStructuralFeatureImpl/InverseUpdatingFeatureMapEntry',790);feb(1365,1,$Je,I9d);_.Fk=function J9d(a){return this.a};_.Qj=function K9d(){return ZD(this.a,97)?RD(this.a,97).Qj():!this.a.dc()};_.Wb=function L9d(a){this.a.$b();this.a.Gc(RD(a,15))};_.Gk=function M9d(){ZD(this.a,97)?RD(this.a,97).Gk():this.a.$b()};var p9=sfb(SHe,'EStructuralFeatureImpl/SettingMany',1365);feb(1366,576,wKe,N9d);_.xl=function O9d(a){return new S9d((nme(),mme),this.b.ri(this.a,a))};_.md=function P9d(){return null};_.zl=function Q9d(a,b,c){return c};_.Al=function R9d(a,b,c){return c};var q9=sfb(SHe,'EStructuralFeatureImpl/SimpleContentFeatureMapEntry',1366);feb(652,576,wKe,S9d);_.xl=function T9d(a){return new S9d(this.c,a)};_.md=function U9d(){return this.a};_.zl=function V9d(a,b,c){return c};_.Al=function W9d(a,b,c){return c};var r9=sfb(SHe,'EStructuralFeatureImpl/SimpleFeatureMapEntry',652);feb(403,506,PIe,X9d);_.aj=function Y9d(a){return $C(h7,rve,29,a,0,1)};_.Yi=function Z9d(){return false};var t9=sfb(SHe,'ESuperAdapter/1',403);feb(457,448,{110:1,94:1,93:1,155:1,197:1,58:1,114:1,850:1,54:1,99:1,158:1,457:1,119:1,120:1},_9d);_.Lh=function aae(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),this.Ab;case 1:return this.zb;case 2:return !this.a&&(this.a=new iae(this,o7,this)),this.a;}return zvd(this,a-AYd((JTd(),ITd)),vYd((d=RD(Ywd(this,16),29),!d?ITd:d),a),b,c)};_.Uh=function bae(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new C5d(f7,this,0,3)),rLd(this.Ab,a,c);case 2:return !this.a&&(this.a=new iae(this,o7,this)),rLd(this.a,a,c);}return e=RD(vYd((d=RD(Ywd(this,16),29),!d?(JTd(),ITd):d),b),69),e.wk().Ak(this,Wwd(this),b-AYd((JTd(),ITd)),a,c)};_.Wh=function cae(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return !!this.a&&this.a.i!=0;}return Avd(this,a-AYd((JTd(),ITd)),vYd((b=RD(Ywd(this,16),29),!b?ITd:b),a))};_.bi=function dae(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);!this.Ab&&(this.Ab=new C5d(f7,this,0,3));YGd(this.Ab,RD(b,16));return;case 1:PAd(this,WD(b));return;case 2:!this.a&&(this.a=new iae(this,o7,this));sLd(this.a);!this.a&&(this.a=new iae(this,o7,this));YGd(this.a,RD(b,16));return;}Bvd(this,a-AYd((JTd(),ITd)),vYd((c=RD(Ywd(this,16),29),!c?ITd:c),a),b)};_.ii=function eae(){return JTd(),ITd};_.ki=function fae(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new C5d(f7,this,0,3));sLd(this.Ab);return;case 1:PAd(this,null);return;case 2:!this.a&&(this.a=new iae(this,o7,this));sLd(this.a);return;}Cvd(this,a-AYd((JTd(),ITd)),vYd((b=RD(Ywd(this,16),29),!b?ITd:b),a))};var z9=sfb(SHe,'ETypeParameterImpl',457);feb(458,83,oKe,iae);_.Nj=function jae(a,b){return gae(this,RD(a,89),b)};_.Oj=function kae(a,b){return hae(this,RD(a,89),b)};var v9=sfb(SHe,'ETypeParameterImpl/1',458);feb(647,45,Hxe,lae);_.ec=function mae(){return new pae(this)};var y9=sfb(SHe,'ETypeParameterImpl/2',647);feb(570,Eve,Fve,pae);_.Fc=function qae(a){return nae(this,RD(a,89))};_.Gc=function rae(a){var b,c,d;d=false;for(c=a.Kc();c.Ob();){b=RD(c.Pb(),89);Zjb(this.a,b,'')==null&&(d=true)}return d};_.$b=function sae(){akb(this.a)};_.Hc=function tae(a){return Ujb(this.a,a)};_.Kc=function uae(){var a;return a=new vkb((new mkb(this.a)).a),new xae(a)};_.Mc=function vae(a){return oae(this,a)};_.gc=function wae(){return bkb(this.a)};var x9=sfb(SHe,'ETypeParameterImpl/2/1',570);feb(571,1,Ave,xae);_.Nb=function yae(a){Ztb(this,a)};_.Pb=function Aae(){return RD(tkb(this.a).ld(),89)};_.Ob=function zae(){return this.a.b};_.Qb=function Bae(){ukb(this.a)};var w9=sfb(SHe,'ETypeParameterImpl/2/1/1',571);feb(1329,45,Hxe,Cae);_._b=function Dae(a){return bE(a)?Yjb(this,a):!!qtb(this.f,a)};_.xc=function Eae(a){var b,c;b=bE(a)?Xjb(this,a):Wd(qtb(this.f,a));if(ZD(b,851)){c=RD(b,851);b=c.Kk();Zjb(this,RD(a,241),b);return b}else return b!=null?b:a==null?(Gie(),Fie):null};var B9=sfb(SHe,'EValidatorRegistryImpl',1329);feb(1349,720,{110:1,94:1,93:1,480:1,155:1,58:1,114:1,2040:1,54:1,99:1,158:1,119:1,120:1},Mae);_.ri=function Nae(a,b){switch(a.hk()){case 21:case 22:case 23:case 24:case 26:case 31:case 32:case 37:case 38:case 39:case 40:case 43:case 44:case 48:case 49:case 20:return b==null?null:jeb(b);case 25:return Gae(b);case 27:return Hae(b);case 28:return Iae(b);case 29:return b==null?null:a2d(nAd[0],RD(b,206));case 41:return b==null?'':nfb(RD(b,297));case 42:return jeb(b);case 50:return WD(b);default:throw Adb(new agb(VHe+a.xe()+WHe));}};_.si=function Oae(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;switch(a.G==-1&&(a.G=(m=BXd(a),m?fZd(m.vi(),a):-1)),a.G){case 0:return c=new mXd,c;case 1:return b=new pVd,b;case 2:return d=new HYd,d;case 4:return e=new k1d,e;case 5:return f=new A1d,f;case 6:return g=new R1d,g;case 7:return h=new yAd,h;case 10:return j=new kUd,j;case 11:return k=new q4d,k;case 12:return l=new EBd,l;case 13:return n=new R5d,n;case 14:return o=new d6d,o;case 17:return p=new v6d,p;case 18:return i=new s2d,i;case 19:return q=new _9d,q;default:throw Adb(new agb(ZHe+a.zb+WHe));}};_.ti=function Pae(a,b){switch(a.hk()){case 20:return b==null?null:new Bib(b);case 21:return b==null?null:new ejb(b);case 23:case 22:return b==null?null:Fae(b);case 26:case 24:return b==null?null:$eb(Oeb(b,-128,127)<<24>>24);case 25:return vAd(b);case 27:return Jae(b);case 28:return Kae(b);case 29:return Lae(b);case 32:case 31:return b==null?null:Neb(b);case 38:case 37:return b==null?null:new Ufb(b);case 40:case 39:return b==null?null:sgb(Oeb(b,qwe,lve));case 41:return null;case 42:return b==null?null:null;case 44:case 43:return b==null?null:Hgb(Peb(b));case 49:case 48:return b==null?null:bhb(Oeb(b,BKe,32767)<<16>>16);case 50:return b;default:throw Adb(new agb(VHe+a.xe()+WHe));}};var C9=sfb(SHe,'EcoreFactoryImpl',1349);feb(560,184,{110:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,2038:1,54:1,99:1,158:1,184:1,560:1,119:1,120:1,690:1},$ae);_.gb=false;_.hb=false;var Rae,Sae=false;var tab=sfb(SHe,'EcorePackageImpl',560);feb(1234,1,{851:1},cbe);_.Kk=function dbe(){return fke(),eke};var N9=sfb(SHe,'EcorePackageImpl/1',1234);feb(1243,1,OKe,ebe);_.fk=function fbe(a){return ZD(a,155)};_.gk=function gbe(a){return $C(p7,rve,155,a,0,1)};var D9=sfb(SHe,'EcorePackageImpl/10',1243);feb(1244,1,OKe,hbe);_.fk=function ibe(a){return ZD(a,197)};_.gk=function jbe(a){return $C(q7,rve,197,a,0,1)};var E9=sfb(SHe,'EcorePackageImpl/11',1244);feb(1245,1,OKe,kbe);_.fk=function lbe(a){return ZD(a,58)};_.gk=function mbe(a){return $C(r7,rve,58,a,0,1)};var F9=sfb(SHe,'EcorePackageImpl/12',1245);feb(1246,1,OKe,nbe);_.fk=function obe(a){return ZD(a,411)};_.gk=function pbe(a){return $C(s7,mKe,62,a,0,1)};var G9=sfb(SHe,'EcorePackageImpl/13',1246);feb(1247,1,OKe,qbe);_.fk=function rbe(a){return ZD(a,241)};_.gk=function sbe(a){return $C(t7,rve,241,a,0,1)};var H9=sfb(SHe,'EcorePackageImpl/14',1247);feb(1248,1,OKe,tbe);_.fk=function ube(a){return ZD(a,518)};_.gk=function vbe(a){return $C(u7,rve,2116,a,0,1)};var I9=sfb(SHe,'EcorePackageImpl/15',1248);feb(1249,1,OKe,wbe);_.fk=function xbe(a){return ZD(a,102)};_.gk=function ybe(a){return $C(v7,lKe,19,a,0,1)};var J9=sfb(SHe,'EcorePackageImpl/16',1249);feb(1250,1,OKe,zbe);_.fk=function Abe(a){return ZD(a,179)};_.gk=function Bbe(a){return $C(y7,lKe,179,a,0,1)};var K9=sfb(SHe,'EcorePackageImpl/17',1250);feb(1251,1,OKe,Cbe);_.fk=function Dbe(a){return ZD(a,481)};_.gk=function Ebe(a){return $C(A7,rve,481,a,0,1)};var L9=sfb(SHe,'EcorePackageImpl/18',1251);feb(1252,1,OKe,Fbe);_.fk=function Gbe(a){return ZD(a,561)};_.gk=function Hbe(a){return $C(C8,LJe,561,a,0,1)};var M9=sfb(SHe,'EcorePackageImpl/19',1252);feb(1235,1,OKe,Ibe);_.fk=function Jbe(a){return ZD(a,331)};_.gk=function Kbe(a){return $C(g7,lKe,35,a,0,1)};var Y9=sfb(SHe,'EcorePackageImpl/2',1235);feb(1253,1,OKe,Lbe);_.fk=function Mbe(a){return ZD(a,248)};_.gk=function Nbe(a){return $C(o7,sKe,89,a,0,1)};var O9=sfb(SHe,'EcorePackageImpl/20',1253);feb(1254,1,OKe,Obe);_.fk=function Pbe(a){return ZD(a,457)};_.gk=function Qbe(a){return $C(z7,rve,850,a,0,1)};var P9=sfb(SHe,'EcorePackageImpl/21',1254);feb(1255,1,OKe,Rbe);_.fk=function Sbe(a){return $D(a)};_.gk=function Tbe(a){return $C(QI,Nve,485,a,8,1)};var Q9=sfb(SHe,'EcorePackageImpl/22',1255);feb(1256,1,OKe,Ube);_.fk=function Vbe(a){return ZD(a,195)};_.gk=function Wbe(a){return $C(gE,Nve,195,a,0,2)};var R9=sfb(SHe,'EcorePackageImpl/23',1256);feb(1257,1,OKe,Xbe);_.fk=function Ybe(a){return ZD(a,222)};_.gk=function Zbe(a){return $C(RI,Nve,222,a,0,1)};var S9=sfb(SHe,'EcorePackageImpl/24',1257);feb(1258,1,OKe,$be);_.fk=function _be(a){return ZD(a,180)};_.gk=function ace(a){return $C(SI,Nve,180,a,0,1)};var T9=sfb(SHe,'EcorePackageImpl/25',1258);feb(1259,1,OKe,bce);_.fk=function cce(a){return ZD(a,206)};_.gk=function dce(a){return $C(qK,Nve,206,a,0,1)};var U9=sfb(SHe,'EcorePackageImpl/26',1259);feb(1260,1,OKe,ece);_.fk=function fce(a){return false};_.gk=function gce(a){return $C(T6,rve,2215,a,0,1)};var V9=sfb(SHe,'EcorePackageImpl/27',1260);feb(1261,1,OKe,hce);_.fk=function ice(a){return _D(a)};_.gk=function jce(a){return $C(VI,Nve,345,a,7,1)};var W9=sfb(SHe,'EcorePackageImpl/28',1261);feb(1262,1,OKe,kce);_.fk=function lce(a){return ZD(a,61)};_.gk=function mce(a){return $C(Y6,Ize,61,a,0,1)};var X9=sfb(SHe,'EcorePackageImpl/29',1262);feb(1236,1,OKe,nce);_.fk=function oce(a){return ZD(a,519)};_.gk=function pce(a){return $C(f7,{3:1,4:1,5:1,2033:1},598,a,0,1)};var hab=sfb(SHe,'EcorePackageImpl/3',1236);feb(1263,1,OKe,qce);_.fk=function rce(a){return ZD(a,582)};_.gk=function sce(a){return $C(Z6,rve,2039,a,0,1)};var Z9=sfb(SHe,'EcorePackageImpl/30',1263);feb(1264,1,OKe,tce);_.fk=function uce(a){return ZD(a,160)};_.gk=function vce(a){return $C(Tbb,Ize,160,a,0,1)};var $9=sfb(SHe,'EcorePackageImpl/31',1264);feb(1265,1,OKe,wce);_.fk=function xce(a){return ZD(a,76)};_.gk=function yce(a){return $C(Jbb,PKe,76,a,0,1)};var _9=sfb(SHe,'EcorePackageImpl/32',1265);feb(1266,1,OKe,zce);_.fk=function Ace(a){return ZD(a,161)};_.gk=function Bce(a){return $C(ZI,Nve,161,a,0,1)};var aab=sfb(SHe,'EcorePackageImpl/33',1266);feb(1267,1,OKe,Cce);_.fk=function Dce(a){return ZD(a,17)};_.gk=function Ece(a){return $C(bJ,Nve,17,a,0,1)};var bab=sfb(SHe,'EcorePackageImpl/34',1267);feb(1268,1,OKe,Fce);_.fk=function Gce(a){return ZD(a,297)};_.gk=function Hce(a){return $C(UI,rve,297,a,0,1)};var cab=sfb(SHe,'EcorePackageImpl/35',1268);feb(1269,1,OKe,Ice);_.fk=function Jce(a){return ZD(a,168)};_.gk=function Kce(a){return $C(eJ,Nve,168,a,0,1)};var dab=sfb(SHe,'EcorePackageImpl/36',1269);feb(1270,1,OKe,Lce);_.fk=function Mce(a){return ZD(a,85)};_.gk=function Nce(a){return $C(VK,rve,85,a,0,1)};var eab=sfb(SHe,'EcorePackageImpl/37',1270);feb(1271,1,OKe,Oce);_.fk=function Pce(a){return ZD(a,599)};_.gk=function Qce(a){return $C(Aab,rve,599,a,0,1)};var fab=sfb(SHe,'EcorePackageImpl/38',1271);feb(1272,1,OKe,Rce);_.fk=function Sce(a){return false};_.gk=function Tce(a){return $C(zab,rve,2216,a,0,1)};var gab=sfb(SHe,'EcorePackageImpl/39',1272);feb(1237,1,OKe,Uce);_.fk=function Vce(a){return ZD(a,90)};_.gk=function Wce(a){return $C(h7,rve,29,a,0,1)};var nab=sfb(SHe,'EcorePackageImpl/4',1237);feb(1273,1,OKe,Xce);_.fk=function Yce(a){return ZD(a,191)};_.gk=function Zce(a){return $C(lJ,Nve,191,a,0,1)};var iab=sfb(SHe,'EcorePackageImpl/40',1273);feb(1274,1,OKe,$ce);_.fk=function _ce(a){return bE(a)};_.gk=function ade(a){return $C(qJ,Nve,2,a,6,1)};var jab=sfb(SHe,'EcorePackageImpl/41',1274);feb(1275,1,OKe,bde);_.fk=function cde(a){return ZD(a,596)};_.gk=function dde(a){return $C(a7,rve,596,a,0,1)};var kab=sfb(SHe,'EcorePackageImpl/42',1275);feb(1276,1,OKe,ede);_.fk=function fde(a){return false};_.gk=function gde(a){return $C($6,Nve,2217,a,0,1)};var lab=sfb(SHe,'EcorePackageImpl/43',1276);feb(1277,1,OKe,hde);_.fk=function ide(a){return ZD(a,44)};_.gk=function jde(a){return $C(UK,Zve,44,a,0,1)};var mab=sfb(SHe,'EcorePackageImpl/44',1277);feb(1238,1,OKe,kde);_.fk=function lde(a){return ZD(a,142)};_.gk=function mde(a){return $C(i7,rve,142,a,0,1)};var oab=sfb(SHe,'EcorePackageImpl/5',1238);feb(1239,1,OKe,nde);_.fk=function ode(a){return ZD(a,156)};_.gk=function pde(a){return $C(k7,rve,156,a,0,1)};var pab=sfb(SHe,'EcorePackageImpl/6',1239);feb(1240,1,OKe,qde);_.fk=function rde(a){return ZD(a,469)};_.gk=function sde(a){return $C(m7,rve,685,a,0,1)};var qab=sfb(SHe,'EcorePackageImpl/7',1240);feb(1241,1,OKe,tde);_.fk=function ude(a){return ZD(a,582)};_.gk=function vde(a){return $C(l7,rve,694,a,0,1)};var rab=sfb(SHe,'EcorePackageImpl/8',1241);feb(1242,1,OKe,wde);_.fk=function xde(a){return ZD(a,480)};_.gk=function yde(a){return $C(n7,rve,480,a,0,1)};var sab=sfb(SHe,'EcorePackageImpl/9',1242);feb(1038,2080,JJe,Cde);_.Mi=function Dde(a,b){zde(this,RD(b,424))};_.Qi=function Ede(a,b){Ade(this,a,RD(b,424))};var vab=sfb(SHe,'MinimalEObjectImpl/1ArrayDelegatingAdapterList',1038);feb(1039,152,GJe,Fde);_.jj=function Gde(){return this.a.a};var uab=sfb(SHe,'MinimalEObjectImpl/1ArrayDelegatingAdapterList/1',1039);feb(1067,1066,{},Ide);var yab=sfb('org.eclipse.emf.ecore.plugin','EcorePlugin',1067);var Aab=ufb(QKe,'Resource');feb(799,1524,RKe);_.Hl=function Mde(a){};_.Il=function Nde(a){};_.El=function Ode(){return !this.a&&(this.a=new Zde(this)),this.a};_.Fl=function Pde(a){var b,c,d,e,f;d=a.length;if(d>0){BFb(0,a.length);if(a.charCodeAt(0)==47){f=new cnb(4);e=1;for(b=1;b0&&(a=(AFb(0,c,a.length),a.substr(0,c)))}}}return Kde(this,a)};_.Gl=function Qde(){return this.c};_.Ib=function Rde(){var a;return nfb(this.Rm)+'@'+(a=tb(this)>>>0,a.toString(16))+" uri='"+this.d+"'"};_.b=false;var Eab=sfb(SKe,'ResourceImpl',799);feb(1525,799,RKe,Sde);var Bab=sfb(SKe,'BinaryResourceImpl',1525);feb(1190,708,QIe);_.bj=function Vde(a){return ZD(a,58)?Tde(this,RD(a,58)):ZD(a,599)?new dMd(RD(a,599).El()):dE(a)===dE(this.f)?RD(a,16).Kc():(jQd(),iQd.a)};_.Ob=function Wde(){return Ude(this)};_.a=false;var Ebb=sfb(ZJe,'EcoreUtil/ContentTreeIterator',1190);feb(1526,1190,QIe,Xde);_.bj=function Yde(a){return dE(a)===dE(this.f)?RD(a,15).Kc():new _je(RD(a,58))};var Cab=sfb(SKe,'ResourceImpl/5',1526);feb(658,2092,nKe,Zde);_.Hc=function $de(a){return this.i<=4?PHd(this,a):ZD(a,54)&&RD(a,54).Jh()==this.a};_.Mi=function _de(a,b){a==this.i-1&&(this.a.b||(this.a.b=true,null))};_.Oi=function aee(a,b){a==0?this.a.b||(this.a.b=true,null):$Gd(this,a,b)};_.Qi=function bee(a,b){};_.Ri=function cee(a,b,c){};_.Lj=function dee(){return 2};_.jj=function eee(){return this.a};_.Mj=function fee(){return true};_.Nj=function gee(a,b){var c;c=RD(a,54);b=c.fi(this.a,b);return b};_.Oj=function hee(a,b){var c;c=RD(a,54);return c.fi(null,b)};_.Pj=function iee(){return false};_.Si=function jee(){return true};_.aj=function kee(a){return $C(r7,rve,58,a,0,1)};_.Yi=function lee(){return false};var Dab=sfb(SKe,'ResourceImpl/ContentsEList',658);feb(970,2062,kwe,mee);_.fd=function nee(a){return this.a.Ki(a)};_.gc=function oee(){return this.a.gc()};var Fab=sfb(ZJe,'AbstractSequentialInternalEList/1',970);var hke,ike,jke,kke;feb(634,1,{},Yee);var pee,qee;var Lab=sfb(ZJe,'BasicExtendedMetaData',634);feb(1181,1,{},afe);_.Jl=function bfe(){return null};_.Kl=function cfe(){this.a==-2&&$ee(this,uee(this.d,this.b));return this.a};_.Ll=function dfe(){return null};_.Ml=function efe(){return yob(),yob(),vob};_.xe=function ffe(){this.c==fLe&&_ee(this,zee(this.d,this.b));return this.c};_.Nl=function gfe(){return 0};_.a=-2;_.c=fLe;var Hab=sfb(ZJe,'BasicExtendedMetaData/EClassExtendedMetaDataImpl',1181);feb(1182,1,{},mfe);_.Jl=function nfe(){this.a==(ree(),pee)&&hfe(this,tee(this.f,this.b));return this.a};_.Kl=function ofe(){return 0};_.Ll=function pfe(){this.c==(ree(),pee)&&ife(this,xee(this.f,this.b));return this.c};_.Ml=function qfe(){!this.d&&jfe(this,yee(this.f,this.b));return this.d};_.xe=function rfe(){this.e==fLe&&kfe(this,zee(this.f,this.b));return this.e};_.Nl=function sfe(){this.g==-2&&lfe(this,Cee(this.f,this.b));return this.g};_.e=fLe;_.g=-2;var Iab=sfb(ZJe,'BasicExtendedMetaData/EDataTypeExtendedMetaDataImpl',1182);feb(1180,1,{},wfe);_.b=false;_.c=false;var Jab=sfb(ZJe,'BasicExtendedMetaData/EPackageExtendedMetaDataImpl',1180);feb(1183,1,{},Jfe);_.c=-2;_.e=fLe;_.f=fLe;var Kab=sfb(ZJe,'BasicExtendedMetaData/EStructuralFeatureExtendedMetaDataImpl',1183);feb(593,632,oKe,Kfe);_.Lj=function Lfe(){return this.c};_.ol=function Mfe(){return false};_.Wi=function Nfe(a,b){return b};_.c=0;var Yab=sfb(ZJe,'EDataTypeEList',593);var Tbb=ufb(ZJe,'FeatureMap');feb(78,593,{3:1,4:1,20:1,31:1,56:1,16:1,15:1,59:1,70:1,66:1,61:1,79:1,160:1,220:1,2036:1,71:1,97:1},Uge);_.bd=function Vge(a,b){Ofe(this,a,RD(b,76))};_.Fc=function Wge(a){return Rfe(this,RD(a,76))};_.Hi=function _ge(a){Wfe(this,RD(a,76))};_.Nj=function khe(a,b){return mge(this,RD(a,76),b)};_.Oj=function lhe(a,b){return oge(this,RD(a,76),b)};_.Ti=function nhe(a,b){return uge(this,a,b)};_.Wi=function phe(a,b){return zge(this,a,RD(b,76))};_.hd=function rhe(a,b){return Cge(this,a,RD(b,76))};_.Uj=function vhe(a,b){return Ige(this,RD(a,76),b)};_.Vj=function whe(a,b){return Kge(this,RD(a,76),b)};_.Wj=function xhe(a,b,c){return Lge(this,RD(a,76),RD(b,76),c)};_.Zi=function zhe(a,b){return Tge(this,a,RD(b,76))};_.Ol=function Xge(a,b){return Qfe(this,a,b)};_.cd=function Yge(a,b){var c,d,e,f,g,h,i,j,k;j=new ZHd(b.gc());for(e=b.Kc();e.Ob();){d=RD(e.Pb(),76);f=d.Lk();if(qke(this.e,f)){(!f.Si()||!cge(this,f,d.md())&&!PHd(j,d))&&WGd(j,d)}else{k=pke(this.e.Dh(),f);c=RD(this.g,124);g=true;for(h=0;h=0){b=a[this.c];if(this.k.am(b.Lk())){this.j=this.f?b:b.md();this.i=-2;return true}}this.i=-1;this.g=-1;return false};var Mab=sfb(ZJe,'BasicFeatureMap/FeatureEIterator',420);feb(676,420,Jve,She);_.ul=function The(){return true};var Nab=sfb(ZJe,'BasicFeatureMap/ResolvingFeatureEIterator',676);feb(968,496,uKe,Uhe);_.pj=function Vhe(){return this};var Rab=sfb(ZJe,'EContentsEList/1',968);feb(969,496,uKe,Whe);_.ul=function Xhe(){return false};var Sab=sfb(ZJe,'EContentsEList/2',969);feb(967,287,vKe,Yhe);_.wl=function Zhe(a){};_.Ob=function $he(){return false};_.Sb=function _he(){return false};var Tab=sfb(ZJe,'EContentsEList/FeatureIteratorImpl/1',967);feb(840,593,oKe,aie);_.Ni=function bie(){this.a=true};_.Qj=function cie(){return this.a};_.Gk=function die(){var a;sLd(this);if(Mvd(this.e)){a=this.a;this.a=false;qvd(this.e,new Q3d(this.e,2,this.c,a,false))}else{this.a=false}};_.a=false;var Xab=sfb(ZJe,'EDataTypeEList/Unsettable',840);feb(1958,593,oKe,eie);_.Si=function fie(){return true};var $ab=sfb(ZJe,'EDataTypeUniqueEList',1958);feb(1959,840,oKe,gie);_.Si=function hie(){return true};var Zab=sfb(ZJe,'EDataTypeUniqueEList/Unsettable',1959);feb(147,83,oKe,iie);_.nl=function jie(){return true};_.Wi=function kie(a,b){return gZd(this,a,RD(b,58))};var _ab=sfb(ZJe,'EObjectContainmentEList/Resolving',147);feb(1184,555,oKe,lie);_.nl=function mie(){return true};_.Wi=function nie(a,b){return gZd(this,a,RD(b,58))};var abb=sfb(ZJe,'EObjectContainmentEList/Unsettable/Resolving',1184);feb(766,14,oKe,oie);_.Ni=function pie(){this.a=true};_.Qj=function qie(){return this.a};_.Gk=function rie(){var a;sLd(this);if(Mvd(this.e)){a=this.a;this.a=false;qvd(this.e,new Q3d(this.e,2,this.c,a,false))}else{this.a=false}};_.a=false;var fbb=sfb(ZJe,'EObjectContainmentWithInverseEList/Unsettable',766);feb(1222,766,oKe,sie);_.nl=function tie(){return true};_.Wi=function uie(a,b){return gZd(this,a,RD(b,58))};var ebb=sfb(ZJe,'EObjectContainmentWithInverseEList/Unsettable/Resolving',1222);feb(757,505,oKe,vie);_.Ni=function wie(){this.a=true};_.Qj=function xie(){return this.a};_.Gk=function yie(){var a;sLd(this);if(Mvd(this.e)){a=this.a;this.a=false;qvd(this.e,new Q3d(this.e,2,this.c,a,false))}else{this.a=false}};_.a=false;var hbb=sfb(ZJe,'EObjectEList/Unsettable',757);feb(338,505,oKe,zie);_.nl=function Aie(){return true};_.Wi=function Bie(a,b){return gZd(this,a,RD(b,58))};var kbb=sfb(ZJe,'EObjectResolvingEList',338);feb(1844,757,oKe,Cie);_.nl=function Die(){return true};_.Wi=function Eie(a,b){return gZd(this,a,RD(b,58))};var jbb=sfb(ZJe,'EObjectResolvingEList/Unsettable',1844);feb(1527,1,{},Hie);var Fie;var lbb=sfb(ZJe,'EObjectValidator',1527);feb(559,505,oKe,Iie);_.il=function Jie(){return this.d};_.jl=function Kie(){return this.b};_.Mj=function Lie(){return true};_.ml=function Mie(){return true};_.b=0;var pbb=sfb(ZJe,'EObjectWithInverseEList',559);feb(1225,559,oKe,Nie);_.ll=function Oie(){return true};var mbb=sfb(ZJe,'EObjectWithInverseEList/ManyInverse',1225);feb(635,559,oKe,Pie);_.Ni=function Qie(){this.a=true};_.Qj=function Rie(){return this.a};_.Gk=function Sie(){var a;sLd(this);if(Mvd(this.e)){a=this.a;this.a=false;qvd(this.e,new Q3d(this.e,2,this.c,a,false))}else{this.a=false}};_.a=false;var obb=sfb(ZJe,'EObjectWithInverseEList/Unsettable',635);feb(1224,635,oKe,Tie);_.ll=function Uie(){return true};var nbb=sfb(ZJe,'EObjectWithInverseEList/Unsettable/ManyInverse',1224);feb(767,559,oKe,Vie);_.nl=function Wie(){return true};_.Wi=function Xie(a,b){return gZd(this,a,RD(b,58))};var tbb=sfb(ZJe,'EObjectWithInverseResolvingEList',767);feb(32,767,oKe,Yie);_.ll=function Zie(){return true};var qbb=sfb(ZJe,'EObjectWithInverseResolvingEList/ManyInverse',32);feb(768,635,oKe,$ie);_.nl=function _ie(){return true};_.Wi=function aje(a,b){return gZd(this,a,RD(b,58))};var sbb=sfb(ZJe,'EObjectWithInverseResolvingEList/Unsettable',768);feb(1223,768,oKe,bje);_.ll=function cje(){return true};var rbb=sfb(ZJe,'EObjectWithInverseResolvingEList/Unsettable/ManyInverse',1223);feb(1185,632,oKe);_.Li=function dje(){return (this.b&1792)==0};_.Ni=function eje(){this.b|=1};_.kl=function fje(){return (this.b&4)!=0};_.Mj=function gje(){return (this.b&40)!=0};_.ll=function hje(){return (this.b&16)!=0};_.ml=function ije(){return (this.b&8)!=0};_.nl=function jje(){return (this.b&cKe)!=0};_.al=function kje(){return (this.b&32)!=0};_.ol=function lje(){return (this.b&gwe)!=0};_.fk=function mje(a){return !this.d?this.Lk().Hk().fk(a):QRd(this.d,a)};_.Qj=function nje(){return (this.b&2)!=0?(this.b&1)!=0:this.i!=0};_.Si=function oje(){return (this.b&128)!=0};_.Gk=function qje(){var a;sLd(this);if((this.b&2)!=0){if(Mvd(this.e)){a=(this.b&1)!=0;this.b&=-2;eZd(this,new Q3d(this.e,2,BYd(this.e.Dh(),this.Lk()),a,false))}else{this.b&=-2}}};_.Yi=function rje(){return (this.b&1536)==0};_.b=0;var vbb=sfb(ZJe,'EcoreEList/Generic',1185);feb(1186,1185,oKe,sje);_.Lk=function tje(){return this.a};var ubb=sfb(ZJe,'EcoreEList/Dynamic',1186);feb(765,66,PIe,uje);_.aj=function vje(a){return IMd(this.a.a,a)};var zbb=sfb(ZJe,'EcoreEMap/1',765);feb(764,83,oKe,wje);_.Mi=function xje(a,b){UNd(this.b,RD(b,136))};_.Oi=function yje(a,b){TNd(this.b)};_.Pi=function zje(a,b,c){var d;++(d=this.b,RD(b,136),d).e};_.Qi=function Aje(a,b){VNd(this.b,RD(b,136))};_.Ri=function Bje(a,b,c){VNd(this.b,RD(c,136));dE(c)===dE(b)&&RD(c,136).Ci(aOd(RD(b,136).ld()));UNd(this.b,RD(b,136))};var Abb=sfb(ZJe,'EcoreEMap/DelegateEObjectContainmentEList',764);feb(1220,141,_Je,Cje);var Cbb=sfb(ZJe,'EcoreEMap/Unsettable',1220);feb(1221,764,oKe,Dje);_.Ni=function Eje(){this.a=true};_.Qj=function Fje(){return this.a};_.Gk=function Gje(){var a;sLd(this);if(Mvd(this.e)){a=this.a;this.a=false;qvd(this.e,new Q3d(this.e,2,this.c,a,false))}else{this.a=false}};_.a=false;var Bbb=sfb(ZJe,'EcoreEMap/Unsettable/UnsettableDelegateEObjectContainmentEList',1221);feb(1189,215,Hxe,Zje);_.a=false;_.b=false;var Fbb=sfb(ZJe,'EcoreUtil/Copier',1189);feb(759,1,Ave,_je);_.Nb=function ake(a){Ztb(this,a)};_.Ob=function bke(){return $je(this)};_.Pb=function cke(){var a;$je(this);a=this.b;this.b=null;return a};_.Qb=function dke(){this.a.Qb()};var Gbb=sfb(ZJe,'EcoreUtil/ProperContentIterator',759);feb(1528,1527,{},gke);var eke;var Hbb=sfb(ZJe,'EcoreValidator',1528);var mke;var Sbb=ufb(ZJe,'FeatureMapUtil/Validator');feb(1295,1,{2041:1},rke);_.am=function ske(a){return true};var Kbb=sfb(ZJe,'FeatureMapUtil/1',1295);feb(773,1,{2041:1},wke);_.am=function xke(a){var b;if(this.c==a)return true;b=TD(Wjb(this.a,a));if(b==null){if(vke(this,a)){yke(this.a,a,(Geb(),Feb));return true}else{yke(this.a,a,(Geb(),Eeb));return false}}else{return b==(Geb(),Feb)}};_.e=false;var tke;var Nbb=sfb(ZJe,'FeatureMapUtil/BasicValidator',773);feb(774,45,Hxe,zke);var Mbb=sfb(ZJe,'FeatureMapUtil/BasicValidator/Cache',774);feb(509,56,{20:1,31:1,56:1,16:1,15:1,61:1,79:1,71:1,97:1},Eke);_.bd=function Fke(a,b){Pfe(this.c,this.b,a,b)};_.Fc=function Gke(a){return Qfe(this.c,this.b,a)};_.cd=function Hke(a,b){return Sfe(this.c,this.b,a,b)};_.Gc=function Ike(a){return Ake(this,a)};_.Gi=function Jke(a,b){Ufe(this.c,this.b,a,b)};_.Wk=function Kke(a,b){return Xfe(this.c,this.b,a,b)};_.$i=function Lke(a){return hge(this.c,this.b,a,false)};_.Ii=function Mke(){return Yfe(this.c,this.b)};_.Ji=function Nke(){return Zfe(this.c,this.b)};_.Ki=function Oke(a){return $fe(this.c,this.b,a)};_.Xk=function Pke(a,b){return Bke(this,a,b)};_.$b=function Qke(){Cke(this)};_.Hc=function Rke(a){return cge(this.c,this.b,a)};_.Ic=function Ske(a){return ege(this.c,this.b,a)};_.Xb=function Tke(a){return hge(this.c,this.b,a,true)};_.Fk=function Uke(a){return this};_.dd=function Vke(a){return jge(this.c,this.b,a)};_.dc=function Wke(){return Dke(this)};_.Qj=function Xke(){return !pge(this.c,this.b)};_.Kc=function Yke(){return qge(this.c,this.b)};_.ed=function Zke(){return sge(this.c,this.b)};_.fd=function $ke(a){return tge(this.c,this.b,a)};_.Ti=function _ke(a,b){return vge(this.c,this.b,a,b)};_.Ui=function ale(a,b){wge(this.c,this.b,a,b)};_.gd=function ble(a){return xge(this.c,this.b,a)};_.Mc=function cle(a){return yge(this.c,this.b,a)};_.hd=function dle(a,b){return Ege(this.c,this.b,a,b)};_.Wb=function ele(a){bge(this.c,this.b);Ake(this,RD(a,15))};_.gc=function fle(){return Nge(this.c,this.b)};_.Pc=function gle(){return Oge(this.c,this.b)};_.Qc=function hle(a){return Qge(this.c,this.b,a)};_.Ib=function ile(){var a,b;b=new Qhb;b.a+='[';for(a=Yfe(this.c,this.b);Bhe(a);){Nhb(b,Ghb(Dhe(a)));Bhe(a)&&(b.a+=pve,b)}b.a+=']';return b.a};_.Gk=function jle(){bge(this.c,this.b)};var Obb=sfb(ZJe,'FeatureMapUtil/FeatureEList',509);feb(644,39,GJe,lle);_.hj=function mle(a){return kle(this,a)};_.mj=function nle(a){var b,c,d,e,f,g,h;switch(this.d){case 1:case 2:{f=a.jj();if(dE(f)===dE(this.c)&&kle(this,null)==a.hj(null)){this.g=a.ij();a.gj()==1&&(this.d=1);return true}break}case 3:{e=a.gj();switch(e){case 3:{f=a.jj();if(dE(f)===dE(this.c)&&kle(this,null)==a.hj(null)){this.d=5;b=new ZHd(2);WGd(b,this.g);WGd(b,a.ij());this.g=b;return true}break}}break}case 5:{e=a.gj();switch(e){case 3:{f=a.jj();if(dE(f)===dE(this.c)&&kle(this,null)==a.hj(null)){c=RD(this.g,16);c.Fc(a.ij());return true}break}}break}case 4:{e=a.gj();switch(e){case 3:{f=a.jj();if(dE(f)===dE(this.c)&&kle(this,null)==a.hj(null)){this.d=1;this.g=a.ij();return true}break}case 4:{f=a.jj();if(dE(f)===dE(this.c)&&kle(this,null)==a.hj(null)){this.d=6;h=new ZHd(2);WGd(h,this.n);WGd(h,a.kj());this.n=h;g=cD(WC(kE,1),Pwe,28,15,[this.o,a.lj()]);this.g=g;return true}break}}break}case 6:{e=a.gj();switch(e){case 4:{f=a.jj();if(dE(f)===dE(this.c)&&kle(this,null)==a.hj(null)){c=RD(this.n,16);c.Fc(a.kj());g=RD(this.g,53);d=$C(kE,Pwe,28,g.length+1,15,1);hib(g,0,d,0,g.length);d[g.length]=a.lj();this.g=d;return true}break}}break}}return false};var Pbb=sfb(ZJe,'FeatureMapUtil/FeatureENotificationImpl',644);feb(564,509,{20:1,31:1,56:1,16:1,15:1,61:1,79:1,160:1,220:1,2036:1,71:1,97:1},ole);_.Ol=function ple(a,b){return Qfe(this.c,a,b)};_.Pl=function qle(a,b,c){return Xfe(this.c,a,b,c)};_.Ql=function rle(a,b,c){return age(this.c,a,b,c)};_.Rl=function sle(){return this};_.Sl=function tle(a,b){return ige(this.c,a,b)};_.Tl=function ule(a){return RD(hge(this.c,this.b,a,false),76).Lk()};_.Ul=function vle(a){return RD(hge(this.c,this.b,a,false),76).md()};_.Vl=function wle(){return this.a};_.Wl=function xle(a){return !pge(this.c,a)};_.Xl=function yle(a,b){Fge(this.c,a,b)};_.Yl=function zle(a){return Gge(this.c,a)};_.Zl=function Ale(a){Sge(this.c,a)};var Qbb=sfb(ZJe,'FeatureMapUtil/FeatureFeatureMap',564);feb(1294,1,$Je,Ble);_.Fk=function Cle(a){return hge(this.b,this.a,-1,a)};_.Qj=function Dle(){return !pge(this.b,this.a)};_.Wb=function Ele(a){Fge(this.b,this.a,a)};_.Gk=function Fle(){bge(this.b,this.a)};var Rbb=sfb(ZJe,'FeatureMapUtil/FeatureValue',1294);var Gle,Hle,Ile,Jle,Kle;var Vbb=ufb(hLe,'AnyType');feb(680,63,swe,Mle);var Wbb=sfb(hLe,'InvalidDatatypeValueException',680);var Xbb=ufb(hLe,iLe);var Ybb=ufb(hLe,jLe);var Zbb=ufb(hLe,kLe);var Nle;var Ple;var Rle,Sle,Tle,Ule,Vle,Wle,Xle,Yle,Zle,$le,_le,ame,bme,cme,dme,eme,fme,gme,hme,ime,jme,kme,lme,mme;feb(844,516,{110:1,94:1,93:1,58:1,54:1,99:1,857:1},ome);_.Lh=function pme(a,b,c){switch(a){case 0:if(c)return !this.c&&(this.c=new Uge(this,0)),this.c;return !this.c&&(this.c=new Uge(this,0)),this.c.b;case 1:if(c)return !this.c&&(this.c=new Uge(this,0)),RD(rge(this.c,(nme(),Sle)),160);return (!this.c&&(this.c=new Uge(this,0)),RD(RD(rge(this.c,(nme(),Sle)),160),220)).Vl();case 2:if(c)return !this.b&&(this.b=new Uge(this,2)),this.b;return !this.b&&(this.b=new Uge(this,2)),this.b.b;}return zvd(this,a-AYd(this.ii()),vYd((this.j&2)==0?this.ii():(!this.k&&(this.k=new fUd),this.k).Nk(),a),b,c)};_.Uh=function qme(a,b,c){var d;switch(b){case 0:return !this.c&&(this.c=new Uge(this,0)),_fe(this.c,a,c);case 1:return (!this.c&&(this.c=new Uge(this,0)),RD(RD(rge(this.c,(nme(),Sle)),160),71)).Xk(a,c);case 2:return !this.b&&(this.b=new Uge(this,2)),_fe(this.b,a,c);}return d=RD(vYd((this.j&2)==0?this.ii():(!this.k&&(this.k=new fUd),this.k).Nk(),b),69),d.wk().Ak(this,Yvd(this),b-AYd(this.ii()),a,c)};_.Wh=function rme(a){switch(a){case 0:return !!this.c&&this.c.i!=0;case 1:return !(!this.c&&(this.c=new Uge(this,0)),RD(rge(this.c,(nme(),Sle)),160)).dc();case 2:return !!this.b&&this.b.i!=0;}return Avd(this,a-AYd(this.ii()),vYd((this.j&2)==0?this.ii():(!this.k&&(this.k=new fUd),this.k).Nk(),a))};_.bi=function sme(a,b){switch(a){case 0:!this.c&&(this.c=new Uge(this,0));Dge(this.c,b);return;case 1:(!this.c&&(this.c=new Uge(this,0)),RD(RD(rge(this.c,(nme(),Sle)),160),220)).Wb(b);return;case 2:!this.b&&(this.b=new Uge(this,2));Dge(this.b,b);return;}Bvd(this,a-AYd(this.ii()),vYd((this.j&2)==0?this.ii():(!this.k&&(this.k=new fUd),this.k).Nk(),a),b)};_.ii=function tme(){return nme(),Rle};_.ki=function ume(a){switch(a){case 0:!this.c&&(this.c=new Uge(this,0));sLd(this.c);return;case 1:(!this.c&&(this.c=new Uge(this,0)),RD(rge(this.c,(nme(),Sle)),160)).$b();return;case 2:!this.b&&(this.b=new Uge(this,2));sLd(this.b);return;}Cvd(this,a-AYd(this.ii()),vYd((this.j&2)==0?this.ii():(!this.k&&(this.k=new fUd),this.k).Nk(),a))};_.Ib=function vme(){var a;if((this.j&4)!=0)return awd(this);a=new Shb(awd(this));a.a+=' (mixed: ';Mhb(a,this.c);a.a+=', anyAttribute: ';Mhb(a,this.b);a.a+=')';return a.a};var $bb=sfb(lLe,'AnyTypeImpl',844);feb(681,516,{110:1,94:1,93:1,58:1,54:1,99:1,2119:1,681:1},yme);_.Lh=function zme(a,b,c){switch(a){case 0:return this.a;case 1:return this.b;}return zvd(this,a-AYd((nme(),cme)),vYd((this.j&2)==0?cme:(!this.k&&(this.k=new fUd),this.k).Nk(),a),b,c)};_.Wh=function Ame(a){switch(a){case 0:return this.a!=null;case 1:return this.b!=null;}return Avd(this,a-AYd((nme(),cme)),vYd((this.j&2)==0?cme:(!this.k&&(this.k=new fUd),this.k).Nk(),a))};_.bi=function Bme(a,b){switch(a){case 0:wme(this,WD(b));return;case 1:xme(this,WD(b));return;}Bvd(this,a-AYd((nme(),cme)),vYd((this.j&2)==0?cme:(!this.k&&(this.k=new fUd),this.k).Nk(),a),b)};_.ii=function Cme(){return nme(),cme};_.ki=function Dme(a){switch(a){case 0:this.a=null;return;case 1:this.b=null;return;}Cvd(this,a-AYd((nme(),cme)),vYd((this.j&2)==0?cme:(!this.k&&(this.k=new fUd),this.k).Nk(),a))};_.Ib=function Eme(){var a;if((this.j&4)!=0)return awd(this);a=new Shb(awd(this));a.a+=' (data: ';Nhb(a,this.a);a.a+=', target: ';Nhb(a,this.b);a.a+=')';return a.a};_.a=null;_.b=null;var _bb=sfb(lLe,'ProcessingInstructionImpl',681);feb(682,844,{110:1,94:1,93:1,58:1,54:1,99:1,857:1,2120:1,682:1},Hme);_.Lh=function Ime(a,b,c){switch(a){case 0:if(c)return !this.c&&(this.c=new Uge(this,0)),this.c;return !this.c&&(this.c=new Uge(this,0)),this.c.b;case 1:if(c)return !this.c&&(this.c=new Uge(this,0)),RD(rge(this.c,(nme(),Sle)),160);return (!this.c&&(this.c=new Uge(this,0)),RD(RD(rge(this.c,(nme(),Sle)),160),220)).Vl();case 2:if(c)return !this.b&&(this.b=new Uge(this,2)),this.b;return !this.b&&(this.b=new Uge(this,2)),this.b.b;case 3:return !this.c&&(this.c=new Uge(this,0)),WD(ige(this.c,(nme(),fme),true));case 4:return Ije(this.a,(!this.c&&(this.c=new Uge(this,0)),WD(ige(this.c,(nme(),fme),true))));case 5:return this.a;}return zvd(this,a-AYd((nme(),eme)),vYd((this.j&2)==0?eme:(!this.k&&(this.k=new fUd),this.k).Nk(),a),b,c)};_.Wh=function Jme(a){switch(a){case 0:return !!this.c&&this.c.i!=0;case 1:return !(!this.c&&(this.c=new Uge(this,0)),RD(rge(this.c,(nme(),Sle)),160)).dc();case 2:return !!this.b&&this.b.i!=0;case 3:return !this.c&&(this.c=new Uge(this,0)),WD(ige(this.c,(nme(),fme),true))!=null;case 4:return Ije(this.a,(!this.c&&(this.c=new Uge(this,0)),WD(ige(this.c,(nme(),fme),true))))!=null;case 5:return !!this.a;}return Avd(this,a-AYd((nme(),eme)),vYd((this.j&2)==0?eme:(!this.k&&(this.k=new fUd),this.k).Nk(),a))};_.bi=function Kme(a,b){switch(a){case 0:!this.c&&(this.c=new Uge(this,0));Dge(this.c,b);return;case 1:(!this.c&&(this.c=new Uge(this,0)),RD(RD(rge(this.c,(nme(),Sle)),160),220)).Wb(b);return;case 2:!this.b&&(this.b=new Uge(this,2));Dge(this.b,b);return;case 3:Gme(this,WD(b));return;case 4:Gme(this,Hje(this.a,b));return;case 5:Fme(this,RD(b,156));return;}Bvd(this,a-AYd((nme(),eme)),vYd((this.j&2)==0?eme:(!this.k&&(this.k=new fUd),this.k).Nk(),a),b)};_.ii=function Lme(){return nme(),eme};_.ki=function Mme(a){switch(a){case 0:!this.c&&(this.c=new Uge(this,0));sLd(this.c);return;case 1:(!this.c&&(this.c=new Uge(this,0)),RD(rge(this.c,(nme(),Sle)),160)).$b();return;case 2:!this.b&&(this.b=new Uge(this,2));sLd(this.b);return;case 3:!this.c&&(this.c=new Uge(this,0));Fge(this.c,(nme(),fme),null);return;case 4:Gme(this,Hje(this.a,null));return;case 5:this.a=null;return;}Cvd(this,a-AYd((nme(),eme)),vYd((this.j&2)==0?eme:(!this.k&&(this.k=new fUd),this.k).Nk(),a))};var acb=sfb(lLe,'SimpleAnyTypeImpl',682);feb(683,516,{110:1,94:1,93:1,58:1,54:1,99:1,2121:1,683:1},Nme);_.Lh=function Ome(a,b,c){switch(a){case 0:if(c)return !this.a&&(this.a=new Uge(this,0)),this.a;return !this.a&&(this.a=new Uge(this,0)),this.a.b;case 1:return c?(!this.b&&(this.b=new DVd((JTd(),FTd),C8,this,1)),this.b):(!this.b&&(this.b=new DVd((JTd(),FTd),C8,this,1)),dOd(this.b));case 2:return c?(!this.c&&(this.c=new DVd((JTd(),FTd),C8,this,2)),this.c):(!this.c&&(this.c=new DVd((JTd(),FTd),C8,this,2)),dOd(this.c));case 3:return !this.a&&(this.a=new Uge(this,0)),rge(this.a,(nme(),ime));case 4:return !this.a&&(this.a=new Uge(this,0)),rge(this.a,(nme(),jme));case 5:return !this.a&&(this.a=new Uge(this,0)),rge(this.a,(nme(),lme));case 6:return !this.a&&(this.a=new Uge(this,0)),rge(this.a,(nme(),mme));}return zvd(this,a-AYd((nme(),hme)),vYd((this.j&2)==0?hme:(!this.k&&(this.k=new fUd),this.k).Nk(),a),b,c)};_.Uh=function Pme(a,b,c){var d;switch(b){case 0:return !this.a&&(this.a=new Uge(this,0)),_fe(this.a,a,c);case 1:return !this.b&&(this.b=new DVd((JTd(),FTd),C8,this,1)),BVd(this.b,a,c);case 2:return !this.c&&(this.c=new DVd((JTd(),FTd),C8,this,2)),BVd(this.c,a,c);case 5:return !this.a&&(this.a=new Uge(this,0)),Bke(rge(this.a,(nme(),lme)),a,c);}return d=RD(vYd((this.j&2)==0?(nme(),hme):(!this.k&&(this.k=new fUd),this.k).Nk(),b),69),d.wk().Ak(this,Yvd(this),b-AYd((nme(),hme)),a,c)};_.Wh=function Qme(a){switch(a){case 0:return !!this.a&&this.a.i!=0;case 1:return !!this.b&&this.b.f!=0;case 2:return !!this.c&&this.c.f!=0;case 3:return !this.a&&(this.a=new Uge(this,0)),!Dke(rge(this.a,(nme(),ime)));case 4:return !this.a&&(this.a=new Uge(this,0)),!Dke(rge(this.a,(nme(),jme)));case 5:return !this.a&&(this.a=new Uge(this,0)),!Dke(rge(this.a,(nme(),lme)));case 6:return !this.a&&(this.a=new Uge(this,0)),!Dke(rge(this.a,(nme(),mme)));}return Avd(this,a-AYd((nme(),hme)),vYd((this.j&2)==0?hme:(!this.k&&(this.k=new fUd),this.k).Nk(),a))};_.bi=function Rme(a,b){switch(a){case 0:!this.a&&(this.a=new Uge(this,0));Dge(this.a,b);return;case 1:!this.b&&(this.b=new DVd((JTd(),FTd),C8,this,1));CVd(this.b,b);return;case 2:!this.c&&(this.c=new DVd((JTd(),FTd),C8,this,2));CVd(this.c,b);return;case 3:!this.a&&(this.a=new Uge(this,0));Cke(rge(this.a,(nme(),ime)));!this.a&&(this.a=new Uge(this,0));Ake(rge(this.a,ime),RD(b,16));return;case 4:!this.a&&(this.a=new Uge(this,0));Cke(rge(this.a,(nme(),jme)));!this.a&&(this.a=new Uge(this,0));Ake(rge(this.a,jme),RD(b,16));return;case 5:!this.a&&(this.a=new Uge(this,0));Cke(rge(this.a,(nme(),lme)));!this.a&&(this.a=new Uge(this,0));Ake(rge(this.a,lme),RD(b,16));return;case 6:!this.a&&(this.a=new Uge(this,0));Cke(rge(this.a,(nme(),mme)));!this.a&&(this.a=new Uge(this,0));Ake(rge(this.a,mme),RD(b,16));return;}Bvd(this,a-AYd((nme(),hme)),vYd((this.j&2)==0?hme:(!this.k&&(this.k=new fUd),this.k).Nk(),a),b)};_.ii=function Sme(){return nme(),hme};_.ki=function Tme(a){switch(a){case 0:!this.a&&(this.a=new Uge(this,0));sLd(this.a);return;case 1:!this.b&&(this.b=new DVd((JTd(),FTd),C8,this,1));this.b.c.$b();return;case 2:!this.c&&(this.c=new DVd((JTd(),FTd),C8,this,2));this.c.c.$b();return;case 3:!this.a&&(this.a=new Uge(this,0));Cke(rge(this.a,(nme(),ime)));return;case 4:!this.a&&(this.a=new Uge(this,0));Cke(rge(this.a,(nme(),jme)));return;case 5:!this.a&&(this.a=new Uge(this,0));Cke(rge(this.a,(nme(),lme)));return;case 6:!this.a&&(this.a=new Uge(this,0));Cke(rge(this.a,(nme(),mme)));return;}Cvd(this,a-AYd((nme(),hme)),vYd((this.j&2)==0?hme:(!this.k&&(this.k=new fUd),this.k).Nk(),a))};_.Ib=function Ume(){var a;if((this.j&4)!=0)return awd(this);a=new Shb(awd(this));a.a+=' (mixed: ';Mhb(a,this.a);a.a+=')';return a.a};var bcb=sfb(lLe,'XMLTypeDocumentRootImpl',683);feb(2028,720,{110:1,94:1,93:1,480:1,155:1,58:1,114:1,54:1,99:1,158:1,119:1,120:1,2122:1},rne);_.ri=function sne(a,b){switch(a.hk()){case 7:case 8:case 9:case 10:case 16:case 22:case 23:case 24:case 25:case 26:case 32:case 33:case 34:case 36:case 37:case 44:case 45:case 50:case 51:case 53:case 55:case 56:case 57:case 58:case 60:case 61:case 4:return b==null?null:jeb(b);case 19:case 28:case 29:case 35:case 38:case 39:case 41:case 46:case 52:case 54:case 5:return WD(b);case 6:return _me(RD(b,195));case 12:case 47:case 49:case 11:return tAd(this,a,b);case 13:return b==null?null:yib(RD(b,247));case 15:case 14:return b==null?null:ane(Kfb(UD(b)));case 17:return bne((nme(),b));case 18:return bne(b);case 21:case 20:return b==null?null:cne(RD(b,161).a);case 27:return dne(RD(b,195));case 30:return ene((nme(),RD(b,15)));case 31:return ene(RD(b,15));case 40:return hne((nme(),b));case 42:return fne((nme(),b));case 43:return fne(b);case 59:case 48:return gne((nme(),b));default:throw Adb(new agb(VHe+a.xe()+WHe));}};_.si=function tne(a){var b,c,d,e,f;switch(a.G==-1&&(a.G=(c=BXd(a),c?fZd(c.vi(),a):-1)),a.G){case 0:return b=new ome,b;case 1:return d=new yme,d;case 2:return e=new Hme,e;case 3:return f=new Nme,f;default:throw Adb(new agb(ZHe+a.zb+WHe));}};_.ti=function une(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;switch(a.hk()){case 5:case 52:case 4:return b;case 6:return ine(b);case 8:case 7:return b==null?null:$me(b);case 9:return b==null?null:$eb(Oeb((d=nue(b,true),d.length>0&&(BFb(0,d.length),d.charCodeAt(0)==43)?(BFb(1,d.length+1),d.substr(1)):d),-128,127)<<24>>24);case 10:return b==null?null:$eb(Oeb((e=nue(b,true),e.length>0&&(BFb(0,e.length),e.charCodeAt(0)==43)?(BFb(1,e.length+1),e.substr(1)):e),-128,127)<<24>>24);case 11:return WD(uAd(this,(nme(),Vle),b));case 12:return WD(uAd(this,(nme(),Wle),b));case 13:return b==null?null:new Bib(nue(b,true));case 15:case 14:return jne(b);case 16:return WD(uAd(this,(nme(),Xle),b));case 17:return kne((nme(),b));case 18:return kne(b);case 28:case 29:case 35:case 38:case 39:case 41:case 54:case 19:return nue(b,true);case 21:case 20:return lne(b);case 22:return WD(uAd(this,(nme(),Yle),b));case 23:return WD(uAd(this,(nme(),Zle),b));case 24:return WD(uAd(this,(nme(),$le),b));case 25:return WD(uAd(this,(nme(),_le),b));case 26:return WD(uAd(this,(nme(),ame),b));case 27:return mne(b);case 30:return nne((nme(),b));case 31:return nne(b);case 32:return b==null?null:sgb(Oeb((k=nue(b,true),k.length>0&&(BFb(0,k.length),k.charCodeAt(0)==43)?(BFb(1,k.length+1),k.substr(1)):k),qwe,lve));case 33:return b==null?null:new ejb((l=nue(b,true),l.length>0&&(BFb(0,l.length),l.charCodeAt(0)==43)?(BFb(1,l.length+1),l.substr(1)):l));case 34:return b==null?null:sgb(Oeb((m=nue(b,true),m.length>0&&(BFb(0,m.length),m.charCodeAt(0)==43)?(BFb(1,m.length+1),m.substr(1)):m),qwe,lve));case 36:return b==null?null:Hgb(Peb((n=nue(b,true),n.length>0&&(BFb(0,n.length),n.charCodeAt(0)==43)?(BFb(1,n.length+1),n.substr(1)):n)));case 37:return b==null?null:Hgb(Peb((o=nue(b,true),o.length>0&&(BFb(0,o.length),o.charCodeAt(0)==43)?(BFb(1,o.length+1),o.substr(1)):o)));case 40:return qne((nme(),b));case 42:return one((nme(),b));case 43:return one(b);case 44:return b==null?null:new ejb((p=nue(b,true),p.length>0&&(BFb(0,p.length),p.charCodeAt(0)==43)?(BFb(1,p.length+1),p.substr(1)):p));case 45:return b==null?null:new ejb((q=nue(b,true),q.length>0&&(BFb(0,q.length),q.charCodeAt(0)==43)?(BFb(1,q.length+1),q.substr(1)):q));case 46:return nue(b,false);case 47:return WD(uAd(this,(nme(),bme),b));case 59:case 48:return pne((nme(),b));case 49:return WD(uAd(this,(nme(),dme),b));case 50:return b==null?null:bhb(Oeb((r=nue(b,true),r.length>0&&(BFb(0,r.length),r.charCodeAt(0)==43)?(BFb(1,r.length+1),r.substr(1)):r),BKe,32767)<<16>>16);case 51:return b==null?null:bhb(Oeb((f=nue(b,true),f.length>0&&(BFb(0,f.length),f.charCodeAt(0)==43)?(BFb(1,f.length+1),f.substr(1)):f),BKe,32767)<<16>>16);case 53:return WD(uAd(this,(nme(),gme),b));case 55:return b==null?null:bhb(Oeb((g=nue(b,true),g.length>0&&(BFb(0,g.length),g.charCodeAt(0)==43)?(BFb(1,g.length+1),g.substr(1)):g),BKe,32767)<<16>>16);case 56:return b==null?null:bhb(Oeb((h=nue(b,true),h.length>0&&(BFb(0,h.length),h.charCodeAt(0)==43)?(BFb(1,h.length+1),h.substr(1)):h),BKe,32767)<<16>>16);case 57:return b==null?null:Hgb(Peb((i=nue(b,true),i.length>0&&(BFb(0,i.length),i.charCodeAt(0)==43)?(BFb(1,i.length+1),i.substr(1)):i)));case 58:return b==null?null:Hgb(Peb((j=nue(b,true),j.length>0&&(BFb(0,j.length),j.charCodeAt(0)==43)?(BFb(1,j.length+1),j.substr(1)):j)));case 60:return b==null?null:sgb(Oeb((c=nue(b,true),c.length>0&&(BFb(0,c.length),c.charCodeAt(0)==43)?(BFb(1,c.length+1),c.substr(1)):c),qwe,lve));case 61:return b==null?null:sgb(Oeb(nue(b,true),qwe,lve));default:throw Adb(new agb(VHe+a.xe()+WHe));}};var Vme,Wme,Xme,Yme;var ccb=sfb(lLe,'XMLTypeFactoryImpl',2028);feb(594,184,{110:1,94:1,93:1,155:1,197:1,58:1,241:1,114:1,54:1,99:1,158:1,184:1,119:1,120:1,690:1,2044:1,594:1},Bne);_.N=false;_.O=false;var wne=false;var bdb=sfb(lLe,'XMLTypePackageImpl',594);feb(1961,1,{851:1},Ene);_.Kk=function Fne(){return rue(),que};var ncb=sfb(lLe,'XMLTypePackageImpl/1',1961);feb(1970,1,OKe,Gne);_.fk=function Hne(a){return bE(a)};_.gk=function Ine(a){return $C(qJ,Nve,2,a,6,1)};var dcb=sfb(lLe,'XMLTypePackageImpl/10',1970);feb(1971,1,OKe,Jne);_.fk=function Kne(a){return bE(a)};_.gk=function Lne(a){return $C(qJ,Nve,2,a,6,1)};var ecb=sfb(lLe,'XMLTypePackageImpl/11',1971);feb(1972,1,OKe,Mne);_.fk=function Nne(a){return bE(a)};_.gk=function One(a){return $C(qJ,Nve,2,a,6,1)};var fcb=sfb(lLe,'XMLTypePackageImpl/12',1972);feb(1973,1,OKe,Pne);_.fk=function Qne(a){return _D(a)};_.gk=function Rne(a){return $C(VI,Nve,345,a,7,1)};var gcb=sfb(lLe,'XMLTypePackageImpl/13',1973);feb(1974,1,OKe,Sne);_.fk=function Tne(a){return bE(a)};_.gk=function Une(a){return $C(qJ,Nve,2,a,6,1)};var hcb=sfb(lLe,'XMLTypePackageImpl/14',1974);feb(1975,1,OKe,Vne);_.fk=function Wne(a){return ZD(a,15)};_.gk=function Xne(a){return $C(QK,Ize,15,a,0,1)};var icb=sfb(lLe,'XMLTypePackageImpl/15',1975);feb(1976,1,OKe,Yne);_.fk=function Zne(a){return ZD(a,15)};_.gk=function $ne(a){return $C(QK,Ize,15,a,0,1)};var jcb=sfb(lLe,'XMLTypePackageImpl/16',1976);feb(1977,1,OKe,_ne);_.fk=function aoe(a){return bE(a)};_.gk=function boe(a){return $C(qJ,Nve,2,a,6,1)};var kcb=sfb(lLe,'XMLTypePackageImpl/17',1977);feb(1978,1,OKe,coe);_.fk=function doe(a){return ZD(a,161)};_.gk=function eoe(a){return $C(ZI,Nve,161,a,0,1)};var lcb=sfb(lLe,'XMLTypePackageImpl/18',1978);feb(1979,1,OKe,foe);_.fk=function goe(a){return bE(a)};_.gk=function hoe(a){return $C(qJ,Nve,2,a,6,1)};var mcb=sfb(lLe,'XMLTypePackageImpl/19',1979);feb(1962,1,OKe,ioe);_.fk=function joe(a){return ZD(a,857)};_.gk=function koe(a){return $C(Vbb,rve,857,a,0,1)};var ycb=sfb(lLe,'XMLTypePackageImpl/2',1962);feb(1980,1,OKe,loe);_.fk=function moe(a){return bE(a)};_.gk=function noe(a){return $C(qJ,Nve,2,a,6,1)};var ocb=sfb(lLe,'XMLTypePackageImpl/20',1980);feb(1981,1,OKe,ooe);_.fk=function poe(a){return bE(a)};_.gk=function qoe(a){return $C(qJ,Nve,2,a,6,1)};var pcb=sfb(lLe,'XMLTypePackageImpl/21',1981);feb(1982,1,OKe,roe);_.fk=function soe(a){return bE(a)};_.gk=function toe(a){return $C(qJ,Nve,2,a,6,1)};var qcb=sfb(lLe,'XMLTypePackageImpl/22',1982);feb(1983,1,OKe,uoe);_.fk=function voe(a){return bE(a)};_.gk=function woe(a){return $C(qJ,Nve,2,a,6,1)};var rcb=sfb(lLe,'XMLTypePackageImpl/23',1983);feb(1984,1,OKe,xoe);_.fk=function yoe(a){return ZD(a,195)};_.gk=function zoe(a){return $C(gE,Nve,195,a,0,2)};var scb=sfb(lLe,'XMLTypePackageImpl/24',1984);feb(1985,1,OKe,Aoe);_.fk=function Boe(a){return bE(a)};_.gk=function Coe(a){return $C(qJ,Nve,2,a,6,1)};var tcb=sfb(lLe,'XMLTypePackageImpl/25',1985);feb(1986,1,OKe,Doe);_.fk=function Eoe(a){return bE(a)};_.gk=function Foe(a){return $C(qJ,Nve,2,a,6,1)};var ucb=sfb(lLe,'XMLTypePackageImpl/26',1986);feb(1987,1,OKe,Goe);_.fk=function Hoe(a){return ZD(a,15)};_.gk=function Ioe(a){return $C(QK,Ize,15,a,0,1)};var vcb=sfb(lLe,'XMLTypePackageImpl/27',1987);feb(1988,1,OKe,Joe);_.fk=function Koe(a){return ZD(a,15)};_.gk=function Loe(a){return $C(QK,Ize,15,a,0,1)};var wcb=sfb(lLe,'XMLTypePackageImpl/28',1988);feb(1989,1,OKe,Moe);_.fk=function Noe(a){return bE(a)};_.gk=function Ooe(a){return $C(qJ,Nve,2,a,6,1)};var xcb=sfb(lLe,'XMLTypePackageImpl/29',1989);feb(1963,1,OKe,Poe);_.fk=function Qoe(a){return ZD(a,681)};_.gk=function Roe(a){return $C(Xbb,rve,2119,a,0,1)};var Jcb=sfb(lLe,'XMLTypePackageImpl/3',1963);feb(1990,1,OKe,Soe);_.fk=function Toe(a){return ZD(a,17)};_.gk=function Uoe(a){return $C(bJ,Nve,17,a,0,1)};var zcb=sfb(lLe,'XMLTypePackageImpl/30',1990);feb(1991,1,OKe,Voe);_.fk=function Woe(a){return bE(a)};_.gk=function Xoe(a){return $C(qJ,Nve,2,a,6,1)};var Acb=sfb(lLe,'XMLTypePackageImpl/31',1991);feb(1992,1,OKe,Yoe);_.fk=function Zoe(a){return ZD(a,168)};_.gk=function $oe(a){return $C(eJ,Nve,168,a,0,1)};var Bcb=sfb(lLe,'XMLTypePackageImpl/32',1992);feb(1993,1,OKe,_oe);_.fk=function ape(a){return bE(a)};_.gk=function bpe(a){return $C(qJ,Nve,2,a,6,1)};var Ccb=sfb(lLe,'XMLTypePackageImpl/33',1993);feb(1994,1,OKe,cpe);_.fk=function dpe(a){return bE(a)};_.gk=function epe(a){return $C(qJ,Nve,2,a,6,1)};var Dcb=sfb(lLe,'XMLTypePackageImpl/34',1994);feb(1995,1,OKe,fpe);_.fk=function gpe(a){return bE(a)};_.gk=function hpe(a){return $C(qJ,Nve,2,a,6,1)};var Ecb=sfb(lLe,'XMLTypePackageImpl/35',1995);feb(1996,1,OKe,ipe);_.fk=function jpe(a){return bE(a)};_.gk=function kpe(a){return $C(qJ,Nve,2,a,6,1)};var Fcb=sfb(lLe,'XMLTypePackageImpl/36',1996);feb(1997,1,OKe,lpe);_.fk=function mpe(a){return ZD(a,15)};_.gk=function npe(a){return $C(QK,Ize,15,a,0,1)};var Gcb=sfb(lLe,'XMLTypePackageImpl/37',1997);feb(1998,1,OKe,ope);_.fk=function ppe(a){return ZD(a,15)};_.gk=function qpe(a){return $C(QK,Ize,15,a,0,1)};var Hcb=sfb(lLe,'XMLTypePackageImpl/38',1998);feb(1999,1,OKe,rpe);_.fk=function spe(a){return bE(a)};_.gk=function tpe(a){return $C(qJ,Nve,2,a,6,1)};var Icb=sfb(lLe,'XMLTypePackageImpl/39',1999);feb(1964,1,OKe,upe);_.fk=function vpe(a){return ZD(a,682)};_.gk=function wpe(a){return $C(Ybb,rve,2120,a,0,1)};var Ucb=sfb(lLe,'XMLTypePackageImpl/4',1964);feb(2000,1,OKe,xpe);_.fk=function ype(a){return bE(a)};_.gk=function zpe(a){return $C(qJ,Nve,2,a,6,1)};var Kcb=sfb(lLe,'XMLTypePackageImpl/40',2000);feb(2001,1,OKe,Ape);_.fk=function Bpe(a){return bE(a)};_.gk=function Cpe(a){return $C(qJ,Nve,2,a,6,1)};var Lcb=sfb(lLe,'XMLTypePackageImpl/41',2001);feb(2002,1,OKe,Dpe);_.fk=function Epe(a){return bE(a)};_.gk=function Fpe(a){return $C(qJ,Nve,2,a,6,1)};var Mcb=sfb(lLe,'XMLTypePackageImpl/42',2002);feb(2003,1,OKe,Gpe);_.fk=function Hpe(a){return bE(a)};_.gk=function Ipe(a){return $C(qJ,Nve,2,a,6,1)};var Ncb=sfb(lLe,'XMLTypePackageImpl/43',2003);feb(2004,1,OKe,Jpe);_.fk=function Kpe(a){return bE(a)};_.gk=function Lpe(a){return $C(qJ,Nve,2,a,6,1)};var Ocb=sfb(lLe,'XMLTypePackageImpl/44',2004);feb(2005,1,OKe,Mpe);_.fk=function Npe(a){return ZD(a,191)};_.gk=function Ope(a){return $C(lJ,Nve,191,a,0,1)};var Pcb=sfb(lLe,'XMLTypePackageImpl/45',2005);feb(2006,1,OKe,Ppe);_.fk=function Qpe(a){return bE(a)};_.gk=function Rpe(a){return $C(qJ,Nve,2,a,6,1)};var Qcb=sfb(lLe,'XMLTypePackageImpl/46',2006);feb(2007,1,OKe,Spe);_.fk=function Tpe(a){return bE(a)};_.gk=function Upe(a){return $C(qJ,Nve,2,a,6,1)};var Rcb=sfb(lLe,'XMLTypePackageImpl/47',2007);feb(2008,1,OKe,Vpe);_.fk=function Wpe(a){return bE(a)};_.gk=function Xpe(a){return $C(qJ,Nve,2,a,6,1)};var Scb=sfb(lLe,'XMLTypePackageImpl/48',2008);feb(2009,1,OKe,Ype);_.fk=function Zpe(a){return ZD(a,191)};_.gk=function $pe(a){return $C(lJ,Nve,191,a,0,1)};var Tcb=sfb(lLe,'XMLTypePackageImpl/49',2009);feb(1965,1,OKe,_pe);_.fk=function aqe(a){return ZD(a,683)};_.gk=function bqe(a){return $C(Zbb,rve,2121,a,0,1)};var Ycb=sfb(lLe,'XMLTypePackageImpl/5',1965);feb(2010,1,OKe,cqe);_.fk=function dqe(a){return ZD(a,168)};_.gk=function eqe(a){return $C(eJ,Nve,168,a,0,1)};var Vcb=sfb(lLe,'XMLTypePackageImpl/50',2010);feb(2011,1,OKe,fqe);_.fk=function gqe(a){return bE(a)};_.gk=function hqe(a){return $C(qJ,Nve,2,a,6,1)};var Wcb=sfb(lLe,'XMLTypePackageImpl/51',2011);feb(2012,1,OKe,iqe);_.fk=function jqe(a){return ZD(a,17)};_.gk=function kqe(a){return $C(bJ,Nve,17,a,0,1)};var Xcb=sfb(lLe,'XMLTypePackageImpl/52',2012);feb(1966,1,OKe,lqe);_.fk=function mqe(a){return bE(a)};_.gk=function nqe(a){return $C(qJ,Nve,2,a,6,1)};var Zcb=sfb(lLe,'XMLTypePackageImpl/6',1966);feb(1967,1,OKe,oqe);_.fk=function pqe(a){return ZD(a,195)};_.gk=function qqe(a){return $C(gE,Nve,195,a,0,2)};var $cb=sfb(lLe,'XMLTypePackageImpl/7',1967);feb(1968,1,OKe,rqe);_.fk=function sqe(a){return $D(a)};_.gk=function tqe(a){return $C(QI,Nve,485,a,8,1)};var _cb=sfb(lLe,'XMLTypePackageImpl/8',1968);feb(1969,1,OKe,uqe);_.fk=function vqe(a){return ZD(a,222)};_.gk=function wqe(a){return $C(RI,Nve,222,a,0,1)};var adb=sfb(lLe,'XMLTypePackageImpl/9',1969);var xqe,yqe;var Eqe,Fqe;var Jqe;feb(55,63,swe,Lqe);var cdb=sfb(LLe,'RegEx/ParseException',55);feb(836,1,{},Tqe);_.bm=function Uqe(a){return ac*16)throw Adb(new Lqe(TId((Hde(),tJe))));c=c*16+e}while(true);if(this.a!=125)throw Adb(new Lqe(TId((Hde(),uJe))));if(c>MLe)throw Adb(new Lqe(TId((Hde(),vJe))));a=c}else{e=0;if(this.c!=0||(e=Xqe(this.a))<0)throw Adb(new Lqe(TId((Hde(),sJe))));c=e;Mqe(this);if(this.c!=0||(e=Xqe(this.a))<0)throw Adb(new Lqe(TId((Hde(),sJe))));c=c*16+e;a=c}break;case 117:d=0;Mqe(this);if(this.c!=0||(d=Xqe(this.a))<0)throw Adb(new Lqe(TId((Hde(),sJe))));b=d;Mqe(this);if(this.c!=0||(d=Xqe(this.a))<0)throw Adb(new Lqe(TId((Hde(),sJe))));b=b*16+d;Mqe(this);if(this.c!=0||(d=Xqe(this.a))<0)throw Adb(new Lqe(TId((Hde(),sJe))));b=b*16+d;Mqe(this);if(this.c!=0||(d=Xqe(this.a))<0)throw Adb(new Lqe(TId((Hde(),sJe))));b=b*16+d;a=b;break;case 118:Mqe(this);if(this.c!=0||(d=Xqe(this.a))<0)throw Adb(new Lqe(TId((Hde(),sJe))));b=d;Mqe(this);if(this.c!=0||(d=Xqe(this.a))<0)throw Adb(new Lqe(TId((Hde(),sJe))));b=b*16+d;Mqe(this);if(this.c!=0||(d=Xqe(this.a))<0)throw Adb(new Lqe(TId((Hde(),sJe))));b=b*16+d;Mqe(this);if(this.c!=0||(d=Xqe(this.a))<0)throw Adb(new Lqe(TId((Hde(),sJe))));b=b*16+d;Mqe(this);if(this.c!=0||(d=Xqe(this.a))<0)throw Adb(new Lqe(TId((Hde(),sJe))));b=b*16+d;Mqe(this);if(this.c!=0||(d=Xqe(this.a))<0)throw Adb(new Lqe(TId((Hde(),sJe))));b=b*16+d;if(b>MLe)throw Adb(new Lqe(TId((Hde(),'parser.descappe.4'))));a=b;break;case 65:case 90:case 122:throw Adb(new Lqe(TId((Hde(),wJe))));}return a};_.dm=function Wqe(a){var b,c;switch(a){case 100:c=(this.e&32)==32?hte('Nd',true):(Vse(),Bse);break;case 68:c=(this.e&32)==32?hte('Nd',false):(Vse(),Ise);break;case 119:c=(this.e&32)==32?hte('IsWord',true):(Vse(),Rse);break;case 87:c=(this.e&32)==32?hte('IsWord',false):(Vse(),Kse);break;case 115:c=(this.e&32)==32?hte('IsSpace',true):(Vse(),Mse);break;case 83:c=(this.e&32)==32?hte('IsSpace',false):(Vse(),Jse);break;default:throw Adb(new yz((b=a,NLe+b.toString(16))));}return c};_.em=function Yqe(a){var b,c,d,e,f,g,h,i,j,k,l,m;this.b=1;Mqe(this);b=null;if(this.c==0&&this.a==94){Mqe(this);if(a){k=(Vse(),Vse(),++Use,new xte(5))}else{b=(Vse(),Vse(),++Use,new xte(4));rte(b,0,MLe);k=(null,++Use,new xte(4))}}else{k=(Vse(),Vse(),++Use,new xte(4))}e=true;while((m=this.c)!=1){if(m==0&&this.a==93&&!e)break;e=false;c=this.a;d=false;if(m==10){switch(c){case 100:case 68:case 119:case 87:case 115:case 83:ute(k,this.dm(c));d=true;break;case 105:case 73:case 99:case 67:c=this.um(k,c);c<0&&(d=true);break;case 112:case 80:l=Sqe(this,c);if(!l)throw Adb(new Lqe(TId((Hde(),hJe))));ute(k,l);d=true;break;default:c=this.cm();}}else if(m==20){g=phb(this.i,58,this.d);if(g<0)throw Adb(new Lqe(TId((Hde(),iJe))));h=true;if(ihb(this.i,this.d)==94){++this.d;h=false}f=zhb(this.i,this.d,g);i=ite(f,h,(this.e&512)==512);if(!i)throw Adb(new Lqe(TId((Hde(),kJe))));ute(k,i);d=true;if(g+1>=this.j||ihb(this.i,g+1)!=93)throw Adb(new Lqe(TId((Hde(),iJe))));this.d=g+2}Mqe(this);if(!d){if(this.c!=0||this.a!=45){rte(k,c,c)}else{Mqe(this);if((m=this.c)==1)throw Adb(new Lqe(TId((Hde(),jJe))));if(m==0&&this.a==93){rte(k,c,c);rte(k,45,45)}else{j=this.a;m==10&&(j=this.cm());Mqe(this);rte(k,c,j)}}}(this.e&gwe)==gwe&&this.c==0&&this.a==44&&Mqe(this)}if(this.c==1)throw Adb(new Lqe(TId((Hde(),jJe))));if(b){wte(b,k);k=b}vte(k);ste(k);this.b=0;Mqe(this);return k};_.fm=function Zqe(){var a,b,c,d;c=this.em(false);while((d=this.c)!=7){a=this.a;if(d==0&&(a==45||a==38)||d==4){Mqe(this);if(this.c!=9)throw Adb(new Lqe(TId((Hde(),pJe))));b=this.em(false);if(d==4)ute(c,b);else if(a==45)wte(c,b);else if(a==38)tte(c,b);else throw Adb(new yz('ASSERT'))}else{throw Adb(new Lqe(TId((Hde(),qJe))))}}Mqe(this);return c};_.gm=function $qe(){var a,b;a=this.a-48;b=(Vse(),Vse(),++Use,new eue(12,null,a));!this.g&&(this.g=new gyb);dyb(this.g,new Bte(a));Mqe(this);return b};_.hm=function _qe(){Mqe(this);return Vse(),Nse};_.im=function are(){Mqe(this);return Vse(),Lse};_.jm=function bre(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.km=function cre(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.lm=function dre(){Mqe(this);return fte()};_.mm=function ere(){Mqe(this);return Vse(),Pse};_.nm=function fre(){Mqe(this);return Vse(),Sse};_.om=function gre(){var a;if(this.d>=this.j||((a=ihb(this.i,this.d++))&65504)!=64)throw Adb(new Lqe(TId((Hde(),dJe))));Mqe(this);return Vse(),Vse(),++Use,new Hte(0,a-64)};_.pm=function hre(){Mqe(this);return gte()};_.qm=function ire(){Mqe(this);return Vse(),Tse};_.rm=function jre(){var a;a=(Vse(),Vse(),++Use,new Hte(0,105));Mqe(this);return a};_.sm=function kre(){Mqe(this);return Vse(),Qse};_.tm=function lre(){Mqe(this);return Vse(),Ose};_.um=function mre(a,b){return this.cm()};_.vm=function nre(){Mqe(this);return Vse(),Gse};_.wm=function ore(){var a,b,c,d,e;if(this.d+1>=this.j)throw Adb(new Lqe(TId((Hde(),aJe))));d=-1;b=null;a=ihb(this.i,this.d);if(49<=a&&a<=57){d=a-48;!this.g&&(this.g=new gyb);dyb(this.g,new Bte(d));++this.d;if(ihb(this.i,this.d)!=41)throw Adb(new Lqe(TId((Hde(),ZIe))));++this.d}else{a==63&&--this.d;Mqe(this);b=Pqe(this);switch(b.e){case 20:case 21:case 22:case 23:break;case 8:if(this.c!=7)throw Adb(new Lqe(TId((Hde(),ZIe))));break;default:throw Adb(new Lqe(TId((Hde(),bJe))));}}Mqe(this);e=Qqe(this);c=null;if(e.e==2){if(e.Pm()!=2)throw Adb(new Lqe(TId((Hde(),cJe))));c=e.Lm(1);e=e.Lm(0)}if(this.c!=7)throw Adb(new Lqe(TId((Hde(),ZIe))));Mqe(this);return Vse(),Vse(),++Use,new Ute(d,b,e,c)};_.xm=function pre(){Mqe(this);return Vse(),Hse};_.ym=function qre(){var a;Mqe(this);a=_se(24,Qqe(this));if(this.c!=7)throw Adb(new Lqe(TId((Hde(),ZIe))));Mqe(this);return a};_.zm=function rre(){var a;Mqe(this);a=_se(20,Qqe(this));if(this.c!=7)throw Adb(new Lqe(TId((Hde(),ZIe))));Mqe(this);return a};_.Am=function sre(){var a;Mqe(this);a=_se(22,Qqe(this));if(this.c!=7)throw Adb(new Lqe(TId((Hde(),ZIe))));Mqe(this);return a};_.Bm=function tre(){var a,b,c,d,e;a=0;c=0;b=-1;while(this.d=this.j)throw Adb(new Lqe(TId((Hde(),$Ie))));if(b==45){++this.d;while(this.d=this.j)throw Adb(new Lqe(TId((Hde(),$Ie))))}if(b==58){++this.d;Mqe(this);d=ate(Qqe(this),a,c);if(this.c!=7)throw Adb(new Lqe(TId((Hde(),ZIe))));Mqe(this)}else if(b==41){++this.d;Mqe(this);d=ate(Qqe(this),a,c)}else throw Adb(new Lqe(TId((Hde(),_Ie))));return d};_.Cm=function ure(){var a;Mqe(this);a=_se(21,Qqe(this));if(this.c!=7)throw Adb(new Lqe(TId((Hde(),ZIe))));Mqe(this);return a};_.Dm=function vre(){var a;Mqe(this);a=_se(23,Qqe(this));if(this.c!=7)throw Adb(new Lqe(TId((Hde(),ZIe))));Mqe(this);return a};_.Em=function wre(){var a,b;Mqe(this);a=this.f++;b=bte(Qqe(this),a);if(this.c!=7)throw Adb(new Lqe(TId((Hde(),ZIe))));Mqe(this);return b};_.Fm=function xre(){var a;Mqe(this);a=bte(Qqe(this),0);if(this.c!=7)throw Adb(new Lqe(TId((Hde(),ZIe))));Mqe(this);return a};_.Gm=function yre(a){Mqe(this);if(this.c==5){Mqe(this);return $se(a,(Vse(),Vse(),++Use,new Kte(9,a)))}else return $se(a,(Vse(),Vse(),++Use,new Kte(3,a)))};_.Hm=function zre(a){var b;Mqe(this);b=(Vse(),Vse(),++Use,new iue(2));if(this.c==5){Mqe(this);hue(b,(null,Ese));hue(b,a)}else{hue(b,a);hue(b,(null,Ese))}return b};_.Im=function Are(a){Mqe(this);if(this.c==5){Mqe(this);return Vse(),Vse(),++Use,new Kte(9,a)}else return Vse(),Vse(),++Use,new Kte(3,a)};_.a=0;_.b=0;_.c=0;_.d=0;_.e=0;_.f=1;_.g=null;_.j=0;var gdb=sfb(LLe,'RegEx/RegexParser',836);feb(1947,836,{},Gre);_.bm=function Hre(a){return false};_.cm=function Ire(){return Dre(this)};_.dm=function Kre(a){return Ere(a)};_.em=function Lre(a){return Fre(this)};_.fm=function Mre(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.gm=function Nre(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.hm=function Ore(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.im=function Pre(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.jm=function Qre(){Mqe(this);return Ere(67)};_.km=function Rre(){Mqe(this);return Ere(73)};_.lm=function Sre(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.mm=function Tre(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.nm=function Ure(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.om=function Vre(){Mqe(this);return Ere(99)};_.pm=function Wre(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.qm=function Xre(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.rm=function Yre(){Mqe(this);return Ere(105)};_.sm=function Zre(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.tm=function $re(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.um=function _re(a,b){return ute(a,Ere(b)),-1};_.vm=function ase(){Mqe(this);return Vse(),Vse(),++Use,new Hte(0,94)};_.wm=function bse(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.xm=function cse(){Mqe(this);return Vse(),Vse(),++Use,new Hte(0,36)};_.ym=function dse(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.zm=function ese(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.Am=function fse(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.Bm=function gse(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.Cm=function hse(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.Dm=function ise(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.Em=function jse(){var a;Mqe(this);a=bte(Qqe(this),0);if(this.c!=7)throw Adb(new Lqe(TId((Hde(),ZIe))));Mqe(this);return a};_.Fm=function kse(){throw Adb(new Lqe(TId((Hde(),xJe))))};_.Gm=function lse(a){Mqe(this);return $se(a,(Vse(),Vse(),++Use,new Kte(3,a)))};_.Hm=function mse(a){var b;Mqe(this);b=(Vse(),Vse(),++Use,new iue(2));hue(b,a);hue(b,(null,Ese));return b};_.Im=function nse(a){Mqe(this);return Vse(),Vse(),++Use,new Kte(3,a)};var Bre=null,Cre=null;var ddb=sfb(LLe,'RegEx/ParserForXMLSchema',1947);feb(122,1,ZLe,Wse);_.Jm=function Xse(a){throw Adb(new yz('Not supported.'))};_.Km=function dte(){return -1};_.Lm=function ete(a){return null};_.Mm=function jte(){return null};_.Nm=function mte(a){};_.Om=function nte(a){};_.Pm=function ote(){return 0};_.Ib=function pte(){return this.Qm(0)};_.Qm=function qte(a){return this.e==11?'.':''};_.e=0;var vse,wse,xse,yse,zse,Ase=null,Bse,Cse=null,Dse,Ese,Fse=null,Gse,Hse,Ise,Jse,Kse,Lse,Mse,Nse,Ose,Pse,Qse,Rse,Sse,Tse,Use=0;var qdb=sfb(LLe,'RegEx/Token',122);feb(138,122,{3:1,138:1,122:1},xte);_.Qm=function Ate(a){var b,c,d;if(this.e==4){if(this==Dse)c='.';else if(this==Bse)c='\\d';else if(this==Rse)c='\\w';else if(this==Mse)c='\\s';else{d=new Qhb;d.a+='[';for(b=0;b0&&(d.a+=',',d);if(this.b[b]===this.b[b+1]){Nhb(d,zte(this.b[b]))}else{Nhb(d,zte(this.b[b]));d.a+='-';Nhb(d,zte(this.b[b+1]))}}d.a+=']';c=d.a}}else{if(this==Ise)c='\\D';else if(this==Kse)c='\\W';else if(this==Jse)c='\\S';else{d=new Qhb;d.a+='[^';for(b=0;b0&&(d.a+=',',d);if(this.b[b]===this.b[b+1]){Nhb(d,zte(this.b[b]))}else{Nhb(d,zte(this.b[b]));d.a+='-';Nhb(d,zte(this.b[b+1]))}}d.a+=']';c=d.a}}return c};_.a=false;_.c=false;var edb=sfb(LLe,'RegEx/RangeToken',138);feb(592,1,{592:1},Bte);_.a=0;var fdb=sfb(LLe,'RegEx/RegexParser/ReferencePosition',592);feb(591,1,{3:1,591:1},Dte);_.Fb=function Ete(a){var b;if(a==null)return false;if(!ZD(a,591))return false;b=RD(a,591);return lhb(this.b,b.b)&&this.a==b.a};_.Hb=function Fte(){return ohb(this.b+'/'+pse(this.a))};_.Ib=function Gte(){return this.c.Qm(this.a)};_.a=0;var hdb=sfb(LLe,'RegEx/RegularExpression',591);feb(228,122,ZLe,Hte);_.Km=function Ite(){return this.a};_.Qm=function Jte(a){var b,c,d;switch(this.e){case 0:switch(this.a){case 124:case 42:case 43:case 63:case 40:case 41:case 46:case 91:case 123:case 92:d='\\'+XD(this.a&Bwe);break;case 12:d='\\f';break;case 10:d='\\n';break;case 13:d='\\r';break;case 9:d='\\t';break;case 27:d='\\e';break;default:if(this.a>=txe){c=(b=this.a>>>0,'0'+b.toString(16));d='\\v'+zhb(c,c.length-6,c.length)}else d=''+XD(this.a&Bwe);}break;case 8:this==Gse||this==Hse?(d=''+XD(this.a&Bwe)):(d='\\'+XD(this.a&Bwe));break;default:d=null;}return d};_.a=0;var idb=sfb(LLe,'RegEx/Token/CharToken',228);feb(318,122,ZLe,Kte);_.Lm=function Lte(a){return this.a};_.Nm=function Mte(a){this.b=a};_.Om=function Nte(a){this.c=a};_.Pm=function Ote(){return 1};_.Qm=function Pte(a){var b;if(this.e==3){if(this.c<0&&this.b<0){b=this.a.Qm(a)+'*'}else if(this.c==this.b){b=this.a.Qm(a)+'{'+this.c+'}'}else if(this.c>=0&&this.b>=0){b=this.a.Qm(a)+'{'+this.c+','+this.b+'}'}else if(this.c>=0&&this.b<0){b=this.a.Qm(a)+'{'+this.c+',}'}else throw Adb(new yz('Token#toString(): CLOSURE '+this.c+pve+this.b))}else{if(this.c<0&&this.b<0){b=this.a.Qm(a)+'*?'}else if(this.c==this.b){b=this.a.Qm(a)+'{'+this.c+'}?'}else if(this.c>=0&&this.b>=0){b=this.a.Qm(a)+'{'+this.c+','+this.b+'}?'}else if(this.c>=0&&this.b<0){b=this.a.Qm(a)+'{'+this.c+',}?'}else throw Adb(new yz('Token#toString(): NONGREEDYCLOSURE '+this.c+pve+this.b))}return b};_.b=0;_.c=0;var jdb=sfb(LLe,'RegEx/Token/ClosureToken',318);feb(837,122,ZLe,Qte);_.Lm=function Rte(a){return a==0?this.a:this.b};_.Pm=function Ste(){return 2};_.Qm=function Tte(a){var b;this.b.e==3&&this.b.Lm(0)==this.a?(b=this.a.Qm(a)+'+'):this.b.e==9&&this.b.Lm(0)==this.a?(b=this.a.Qm(a)+'+?'):(b=this.a.Qm(a)+(''+this.b.Qm(a)));return b};var kdb=sfb(LLe,'RegEx/Token/ConcatToken',837);feb(1945,122,ZLe,Ute);_.Lm=function Vte(a){if(a==0)return this.d;if(a==1)return this.b;throw Adb(new yz('Internal Error: '+a))};_.Pm=function Wte(){return !this.b?1:2};_.Qm=function Xte(a){var b;this.c>0?(b='(?('+this.c+')'):this.a.e==8?(b='(?('+this.a+')'):(b='(?'+this.a);!this.b?(b+=this.d+')'):(b+=this.d+'|'+this.b+')');return b};_.c=0;var ldb=sfb(LLe,'RegEx/Token/ConditionToken',1945);feb(1946,122,ZLe,Yte);_.Lm=function Zte(a){return this.b};_.Pm=function $te(){return 1};_.Qm=function _te(a){return '(?'+(this.a==0?'':pse(this.a))+(this.c==0?'':pse(this.c))+':'+this.b.Qm(a)+')'};_.a=0;_.c=0;var mdb=sfb(LLe,'RegEx/Token/ModifierToken',1946);feb(838,122,ZLe,aue);_.Lm=function bue(a){return this.a};_.Pm=function cue(){return 1};_.Qm=function due(a){var b;b=null;switch(this.e){case 6:this.b==0?(b='(?:'+this.a.Qm(a)+')'):(b='('+this.a.Qm(a)+')');break;case 20:b='(?='+this.a.Qm(a)+')';break;case 21:b='(?!'+this.a.Qm(a)+')';break;case 22:b='(?<='+this.a.Qm(a)+')';break;case 23:b='(?'+this.a.Qm(a)+')';}return b};_.b=0;var ndb=sfb(LLe,'RegEx/Token/ParenToken',838);feb(530,122,{3:1,122:1,530:1},eue);_.Mm=function fue(){return this.b};_.Qm=function gue(a){return this.e==12?'\\'+this.a:tse(this.b)};_.a=0;var odb=sfb(LLe,'RegEx/Token/StringToken',530);feb(477,122,ZLe,iue);_.Jm=function jue(a){hue(this,a)};_.Lm=function kue(a){return RD(eyb(this.a,a),122)};_.Pm=function lue(){return !this.a?0:this.a.a.c.length};_.Qm=function mue(a){var b,c,d,e,f;if(this.e==1){if(this.a.a.c.length==2){b=RD(eyb(this.a,0),122);c=RD(eyb(this.a,1),122);c.e==3&&c.Lm(0)==b?(e=b.Qm(a)+'+'):c.e==9&&c.Lm(0)==b?(e=b.Qm(a)+'+?'):(e=b.Qm(a)+(''+c.Qm(a)))}else{f=new Qhb;for(d=0;d=this.c.b:this.a<=this.c.b};_.Sb=function Vue(){return this.b>0};_.Tb=function Xue(){return this.b};_.Vb=function Zue(){return this.b-1};_.Qb=function $ue(){throw Adb(new kib(dMe))};_.a=0;_.b=0;var udb=sfb(aMe,'ExclusiveRange/RangeIterator',258);var hE=vfb(eKe,'C');var kE=vfb(hKe,'I');var xdb=vfb(hve,'Z');var lE=vfb(iKe,'J');var gE=vfb(dKe,'B');var iE=vfb(fKe,'D');var jE=vfb(gKe,'F');var wdb=vfb(jKe,'S');var g3=ufb('org.eclipse.elk.core.labels','ILabelManager');var T6=ufb(sIe,'DiagnosticChain');var zab=ufb(QKe,'ResourceSet');var $6=sfb(sIe,'InvocationTargetException',null);var fve=(Qz(),Tz);var gwtOnLoad=gwtOnLoad=ceb;aeb(leb);deb('permProps',[[['locale','default'],[eMe,'gecko1_8']],[['locale','default'],[eMe,'safari']]]); +// -------------- RUN GWT INITIALIZATION CODE -------------- +gwtOnLoad(null, 'elk', null); + +}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],3:[function(require,module,exports){ +'use strict'; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +/******************************************************************************* + * Copyright (c) 2021 Kiel University and others. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +var ELK = require('./elk-api.js').default; + +var ELKNode = function (_ELK) { + _inherits(ELKNode, _ELK); + + function ELKNode() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, ELKNode); + + var optionsClone = Object.assign({}, options); + + var workerThreadsExist = false; + try { + require.resolve('web-worker'); + workerThreadsExist = true; + } catch (e) {} + + // user requested a worker + if (options.workerUrl) { + if (workerThreadsExist) { + var Worker = require('web-worker'); + optionsClone.workerFactory = function (url) { + return new Worker(url); + }; + } else { + console.warn('Web worker requested but \'web-worker\' package not installed. \nConsider installing the package or pass your own \'workerFactory\' to ELK\'s constructor.\n... Falling back to non-web worker version.'); + } + } + + // unless no other workerFactory is registered, use the fake worker + if (!optionsClone.workerFactory) { + var _require = require('./elk-worker.min.js'), + _Worker = _require.Worker; + + optionsClone.workerFactory = function (url) { + return new _Worker(url); + }; + } + + return _possibleConstructorReturn(this, (ELKNode.__proto__ || Object.getPrototypeOf(ELKNode)).call(this, optionsClone)); + } + + return ELKNode; +}(ELK); + +Object.defineProperty(module.exports, "__esModule", { + value: true +}); +module.exports = ELKNode; +ELKNode.default = ELKNode; +},{"./elk-api.js":1,"./elk-worker.min.js":2,"web-worker":4}],4:[function(require,module,exports){ +/** + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +module.exports = Worker; +},{}]},{},[3])(3) +}); + + +/***/ }), + +/***/ 40351: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-f47111a7.js + 8 modules +var mermaid_f47111a7 = __webpack_require__(76257); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {Array} items + * Items to add to `list`. + * @returns {Array} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record} */ + const left = maybe || (all[hook] = {}) + /** @type {Record | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array} existing + * @param {Array} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array} */ + let parameters + /** @type {Array} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array} events + * @param {number} eventIndex + * @returns {Record} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record} */ + const gaps = {} + /** @type {Array} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record} */ + const columnStart = {} + /** @type {Array} */ + const resolveAllConstructs = [] + /** @type {Array} */ + let chunks = [] + /** @type {Array} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array} chunks + * @param {Pick} token + * @returns {Array} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * + * b> + * + * + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`` or `b`). + * @param {TokenType} literalType + * Type when enclosed (``). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * . + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * . + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After ` | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | &<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | + * ^^ + * > | + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > |
+ * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after ` | + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > |
+ * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + *

!^a

+ *

!^a

+ * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | ab + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a c + * ^ + * > | a c + * ^ + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * > | a c + * ^ + * > | a &<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after ` | a c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After ` | a &<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a &<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a
c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array} events + * @returns {Array} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract} Parent + * + * @typedef {Omit & {type: 'fragment', children: Array}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array} transforms + * Tree transforms. + * + * @typedef {Partial} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array} stack + * Stack of nodes. + * @property {Array} tokenStack + * Stack of tokens. + * @property {(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(60513); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-6b48ae7d.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.T)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "
"); + } else if (node.type === "strong") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "emphasis") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "paragraph") { + return `

${node.children.map(output).join("")}

`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + " + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_f47111a7.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_f47111a7.M)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 28747: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ insertMarkers$1), +/* harmony export */ b: () => (/* binding */ clear$1), +/* harmony export */ c: () => (/* binding */ createLabel$1), +/* harmony export */ d: () => (/* binding */ clear), +/* harmony export */ e: () => (/* binding */ insertNode), +/* harmony export */ f: () => (/* binding */ insertEdgeLabel), +/* harmony export */ g: () => (/* binding */ getSubGraphTitleMargins), +/* harmony export */ h: () => (/* binding */ insertEdge), +/* harmony export */ i: () => (/* binding */ intersectRect$1), +/* harmony export */ j: () => (/* binding */ positionEdgeLabel), +/* harmony export */ k: () => (/* binding */ getLineFunctionsWithOffset), +/* harmony export */ l: () => (/* binding */ labelHelper), +/* harmony export */ m: () => (/* binding */ addEdgeMarkers), +/* harmony export */ p: () => (/* binding */ positionNode), +/* harmony export */ s: () => (/* binding */ setNodeElem), +/* harmony export */ u: () => (/* binding */ updateNodeBounds) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(40351); + + + +const insertMarkers = (elem, markerArray, type, id) => { + markerArray.forEach((markerName) => { + markers[markerName](elem, type, id); + }); +}; +const extension = (elem, type, id) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Making markers for ", id); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); +}; +const composition = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const aggregation = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const dependency = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 6).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const lollipop = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopEnd").attr("class", "marker lollipop " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); +}; +const point = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 6).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 4.5).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const circle$1 = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const cross = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); +}; +const barb = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const markers = { + extension, + composition, + aggregation, + dependency, + lollipop, + point, + circle: circle$1, + cross, + barb +}; +const insertMarkers$1 = insertMarkers; +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlLabel(node) { + const fo = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + '" + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "inline-block"); + div.style("white-space", "nowrap"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + return fo.node(); +} +const createLabel = (_vertexText, style, isTitle, isNode) => { + let vertexText = _vertexText || ""; + if (typeof vertexText === "object") { + vertexText = vertexText[0]; + } + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + vertexText = vertexText.replace(/\\n|\n/g, "
"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("vertexText" + vertexText); + const node = { + isNode, + label: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(vertexText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + let vertexNode = addHtmlLabel(node); + return vertexNode; + } else { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", style.replace("color:", "fill:")); + let rows = []; + if (typeof vertexText === "string") { + rows = vertexText.split(/\\n|\n|/gi); + } else if (Array.isArray(vertexText)) { + rows = vertexText; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + if (isTitle) { + tspan.setAttribute("class", "title-row"); + } else { + tspan.setAttribute("class", "row"); + } + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; + } +}; +const createLabel$1 = createLabel; +const labelHelper = async (parent, node, _classes, isNode) => { + let classes; + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + if (!_classes) { + classes = "node default"; + } else { + classes = _classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle); + let labelText; + if (node.labelText === void 0) { + labelText = ""; + } else { + labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0]; + } + const textNode = label.node(); + let text; + if (node.labelType === "markdown") { + text = (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__.a)(label, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(labelText), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()), { + useHtmlLabels, + width: node.width || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.wrappingWidth, + classes: "markdown-node-label" + }); + } else { + text = textNode.appendChild( + createLabel$1( + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(labelText), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()), + node.labelStyle, + false, + isNode + ) + ); + } + let bbox = text.getBBox(); + const halfPadding = node.padding / 2; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text); + const images = div.getElementsByTagName("img"); + if (images) { + const noImgText = labelText.replace(/]*>/g, "").trim() === ""; + await Promise.all( + [...images].map( + (img) => new Promise((res) => { + function setupImage() { + img.style.display = "flex"; + img.style.flexDirection = "column"; + if (noImgText) { + const bodyFontSize = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize ? (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize : window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + const width = parseInt(bodyFontSize, 10) * enlargingFactor + "px"; + img.style.minWidth = width; + img.style.maxWidth = width; + } else { + img.style.width = "100%"; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener("error", setupImage); + img.addEventListener("load", setupImage); + }) + ) + ); + } + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (useHtmlLabels) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } else { + label.attr("transform", "translate(0, " + -bbox.height / 2 + ")"); + } + if (node.centerLabel) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } + label.insert("rect", ":first-child"); + return { shapeSvg, bbox, halfPadding, label }; +}; +const updateNodeBounds = (node, element) => { + const bbox = element.node().getBBox(); + node.width = bbox.width; + node.height = bbox.height; +}; +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +function intersectNode(node, point2) { + return node.intersect(point2); +} +function intersectEllipse(node, rx, ry, point2) { + var cx = node.x; + var cy = node.y; + var px = cx - point2.x; + var py = cy - point2.y; + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + var dx = Math.abs(rx * ry * px / det); + if (point2.x < cx) { + dx = -dx; + } + var dy = Math.abs(rx * ry * py / det); + if (point2.y < cy) { + dy = -dy; + } + return { x: cx + dx, y: cy + dy }; +} +function intersectCircle(node, rx, point2) { + return intersectEllipse(node, rx, rx, point2); +} +function intersectLine(p1, p2, q1, q2) { + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return; + } + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return; + } + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return; + } + offset = Math.abs(denom / 2); + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + return { x, y }; +} +function sameSign(r1, r2) { + return r1 * r2 > 0; +} +function intersectPolygon(node, polyPoints, point2) { + var x1 = node.x; + var y1 = node.y; + var intersections = []; + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + if (typeof polyPoints.forEach === "function") { + polyPoints.forEach(function(entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + } else { + minX = Math.min(minX, polyPoints.x); + minY = Math.min(minY, polyPoints.y); + } + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect2 = intersectLine( + node, + point2, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect2) { + intersections.push(intersect2); + } + } + if (!intersections.length) { + return node; + } + if (intersections.length > 1) { + intersections.sort(function(p, q) { + var pdx = p.x - point2.x; + var pdy = p.y - point2.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + var qdx = q.x - point2.x; + var qdy = q.y - point2.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} +const intersectRect = (node, point2) => { + var x = node.x; + var y = node.y; + var dx = point2.x - x; + var dy = point2.y - y; + var w = node.width / 2; + var h = node.height / 2; + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : h * dx / dy; + sy = h; + } else { + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : w * dy / dx; + } + return { x: x + sx, y: y + sy }; +}; +const intersectRect$1 = intersectRect; +const intersect = { + node: intersectNode, + circle: intersectCircle, + ellipse: intersectEllipse, + polygon: intersectPolygon, + rect: intersectRect$1 +}; +const note = async (parent, node) => { + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels; + if (!useHtmlLabels) { + node.centerLabel = true; + } + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Classes = ", node.classes); + const rect2 = shapeSvg.insert("rect", ":first-child"); + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const note$1 = note; +const expandAndDeduplicateDirections = (directions) => { + const uniqueDirections = /* @__PURE__ */ new Set(); + for (const direction of directions) { + switch (direction) { + case "x": + uniqueDirections.add("right"); + uniqueDirections.add("left"); + break; + case "y": + uniqueDirections.add("up"); + uniqueDirections.add("down"); + break; + default: + uniqueDirections.add(direction); + break; + } + } + return uniqueDirections; +}; +const getArrowPoints = (duplicatedDirections, bbox, node) => { + const directions = expandAndDeduplicateDirections(duplicatedDirections); + const f = 2; + const height = bbox.height + 2 * node.padding; + const midpoint = height / f; + const width = bbox.width + 2 * midpoint + node.padding; + const padding = node.padding / 2; + if (directions.has("right") && directions.has("left") && directions.has("up") && directions.has("down")) { + return [ + // Bottom + { x: 0, y: 0 }, + { x: midpoint, y: 0 }, + { x: width / 2, y: 2 * padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: 0 }, + // Right + { x: width, y: -height / 3 }, + { x: width + 2 * padding, y: -height / 2 }, + { x: width, y: -2 * height / 3 }, + { x: width, y: -height }, + // Top + { x: width - midpoint, y: -height }, + { x: width / 2, y: -height - 2 * padding }, + { x: midpoint, y: -height }, + // Left + { x: 0, y: -height }, + { x: 0, y: -2 * height / 3 }, + { x: -2 * padding, y: -height / 2 }, + { x: 0, y: -height / 3 } + ]; + } + if (directions.has("right") && directions.has("left") && directions.has("up")) { + return [ + { x: midpoint, y: 0 }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("right") && directions.has("left") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: midpoint, y: -height }, + { x: width - midpoint, y: -height }, + { x: width, y: 0 } + ]; + } + if (directions.has("right") && directions.has("up") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: width, y: -midpoint }, + { x: width, y: -height + midpoint }, + { x: 0, y: -height } + ]; + } + if (directions.has("left") && directions.has("up") && directions.has("down")) { + return [ + { x: width, y: 0 }, + { x: 0, y: -midpoint }, + { x: 0, y: -height + midpoint }, + { x: width, y: -height } + ]; + } + if (directions.has("right") && directions.has("left")) { + return [ + { x: midpoint, y: 0 }, + { x: midpoint, y: -padding }, + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: width - midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("up") && directions.has("down")) { + return [ + // Bottom center + { x: width / 2, y: 0 }, + // Left pont of bottom arrow + { x: 0, y: -padding }, + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: 0, y: -height + padding }, + // Top of arrow + { x: width / 2, y: -height }, + { x: width, y: -height + padding }, + // Top of right vertical bar + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding }, + { x: width, y: -padding } + ]; + } + if (directions.has("right") && directions.has("up")) { + return [ + { x: 0, y: 0 }, + { x: width, y: -midpoint }, + { x: 0, y: -height } + ]; + } + if (directions.has("right") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: width, y: 0 }, + { x: 0, y: -height } + ]; + } + if (directions.has("left") && directions.has("up")) { + return [ + { x: width, y: 0 }, + { x: 0, y: -midpoint }, + { x: width, y: -height } + ]; + } + if (directions.has("left") && directions.has("down")) { + return [ + { x: width, y: 0 }, + { x: 0, y: 0 }, + { x: width, y: -height } + ]; + } + if (directions.has("right")) { + return [ + { x: midpoint, y: -padding }, + { x: midpoint, y: -padding }, + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: width - midpoint, y: -height + padding }, + // top left corner of arrow + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding } + ]; + } + if (directions.has("left")) { + return [ + { x: midpoint, y: 0 }, + { x: midpoint, y: -padding }, + // Two points, the right corners + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("up")) { + return [ + // Bottom center + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: 0, y: -height + padding }, + // Top of arrow + { x: width / 2, y: -height }, + { x: width, y: -height + padding }, + // Top of right vertical bar + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding } + ]; + } + if (directions.has("down")) { + return [ + // Bottom center + { x: width / 2, y: 0 }, + // Left pont of bottom arrow + { x: 0, y: -padding }, + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding }, + { x: width, y: -padding } + ]; + } + return [{ x: 0, y: 0 }]; +}; +const formatClass = (str) => { + if (str) { + return " " + str; + } + return ""; +}; +const getClassesFromNode = (node, otherClasses) => { + return `${otherClasses ? otherClasses : "node default"}${formatClass(node.classes)} ${formatClass( + node.class + )}`; +}; +const question = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const s = w + h; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Question main (Circle)"); + const questionElem = insertPolygonShape(shapeSvg, s, s, points); + questionElem.attr("style", node.style); + updateNodeBounds(node, questionElem); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("Intersect called"); + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const choice = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const s = 28; + const points = [ + { x: 0, y: s / 2 }, + { x: s / 2, y: 0 }, + { x: 0, y: -s / 2 }, + { x: -s / 2, y: 0 } + ]; + const choice2 = shapeSvg.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ); + choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28); + node.width = 28; + node.height = 28; + node.intersect = function(point2) { + return intersect.circle(node, 14, point2); + }; + return shapeSvg; +}; +const hexagon = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const f = 4; + const h = bbox.height + node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const hex = insertPolygonShape(shapeSvg, w, h, points); + hex.attr("style", node.style); + updateNodeBounds(node, hex); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const block_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true); + const f = 2; + const h = bbox.height + 2 * node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = getArrowPoints(node.directions, bbox, node); + const blockArrow = insertPolygonShape(shapeSvg, w, h, points); + blockArrow.attr("style", node.style); + updateNodeBounds(node, blockArrow); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_left_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + node.width = w + h; + node.height = h; + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_right = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_left = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const inv_trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_right_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const cylinder = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry + node.padding; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const el = shapeSvg.attr("label-offset-y", ry).insert("path", ":first-child").attr("style", node.style).attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + updateNodeBounds(node, el); + node.intersect = function(point2) { + const pos = intersect.rect(node, point2); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point2.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +}; +const rect = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes + " " + node.class, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding; + const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding; + rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const composite = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding; + const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding; + rect2.attr("class", "basic cluster composite label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const labelRect = async (parent, node) => { + const { shapeSvg } = await labelHelper(parent, node, "label", true); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Classes = ", node.class); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = 0; + const totalHeight = 0; + rect2.attr("width", totalWidth).attr("height", totalHeight); + shapeSvg.attr("class", "label edgeLabel"); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) { + const strokeDashArray = []; + const addBorder = (length) => { + strokeDashArray.push(length, 0); + }; + const skipBorder = (length) => { + strokeDashArray.push(0, length); + }; + if (borders.includes("t")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add top border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("r")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add right border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + if (borders.includes("b")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add bottom border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("l")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add left border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + rect2.attr("stroke-dasharray", strokeDashArray.join(" ")); +} +const rectWithTitle = (parent, node) => { + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const innerLine = shapeSvg.insert("line"); + const label = shapeSvg.insert("g").attr("class", "label"); + const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText; + let title = ""; + if (typeof text2 === "object") { + title = text2[0]; + } else { + title = text2; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Label text abc79", title, text2, typeof text2 === "object"); + const text = label.node().appendChild(createLabel$1(title, node.labelStyle, true, true)); + let bbox = { width: 0, height: 0 }; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Text 2", text2); + const textRows = text2.slice(1, text2.length); + let titleBox = text.getBBox(); + const descr = label.node().appendChild( + createLabel$1(textRows.join ? textRows.join("
") : textRows, node.labelStyle, true, true) + ); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = descr.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(descr); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const halfPadding = node.padding / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(descr).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")" + ); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)" + ); + bbox = label.node().getBBox(); + label.attr( + "transform", + "translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")" + ); + rect2.attr("class", "outer title-state").attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + innerLine.attr("class", "divider").attr("x1", -bbox.width / 2 - halfPadding).attr("x2", bbox.width / 2 + halfPadding).attr("y1", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr("y2", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const stadium = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const h = bbox.height + node.padding; + const w = bbox.width + h / 4 + node.padding; + const rect2 = shapeSvg.insert("rect", ":first-child").attr("style", node.style).attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const circle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle main"); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle intersect", node, bbox.width / 2 + halfPadding, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding, point2); + }; + return shapeSvg; +}; +const doublecircle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const gap = 5; + const circleGroup = shapeSvg.insert("g", ":first-child"); + const outerCircle = circleGroup.insert("circle"); + const innerCircle = circleGroup.insert("circle"); + circleGroup.attr("class", node.class); + outerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding + gap).attr("width", bbox.width + node.padding + gap * 2).attr("height", bbox.height + node.padding + gap * 2); + innerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle main"); + updateNodeBounds(node, outerCircle); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point2); + }; + return shapeSvg; +}; +const subroutine = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const start = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const forkJoin = (parent, node, dir) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + let width = 70; + let height = 10; + if (dir === "LR") { + width = 10; + height = 70; + } + const shape = shapeSvg.append("rect").attr("x", -1 * width / 2).attr("y", -1 * height / 2).attr("width", width).attr("height", height).attr("class", "fork-join"); + updateNodeBounds(node, shape); + node.height = node.height + node.padding / 2; + node.width = node.width + node.padding / 2; + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const end = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const innerCircle = shapeSvg.insert("circle", ":first-child"); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const class_box = (parent, node) => { + const halfPadding = node.padding / 2; + const rowPadding = 4; + const lineHeight = 8; + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const topLine = shapeSvg.insert("line"); + const bottomLine = shapeSvg.insert("line"); + let maxWidth = 0; + let maxHeight = rowPadding; + const labelContainer = shapeSvg.insert("g").attr("class", "label"); + let verticalPos = 0; + const hasInterface = node.classData.annotations && node.classData.annotations[0]; + const interfaceLabelText = node.classData.annotations[0] ? "«" + node.classData.annotations[0] + "»" : ""; + const interfaceLabel = labelContainer.node().appendChild(createLabel$1(interfaceLabelText, node.labelStyle, true, true)); + let interfaceBBox = interfaceLabel.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = interfaceLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(interfaceLabel); + interfaceBBox = div.getBoundingClientRect(); + dv.attr("width", interfaceBBox.width); + dv.attr("height", interfaceBBox.height); + } + if (node.classData.annotations[0]) { + maxHeight += interfaceBBox.height + rowPadding; + maxWidth += interfaceBBox.width; + } + let classTitleString = node.classData.label; + if (node.classData.type !== void 0 && node.classData.type !== "") { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + classTitleString += "<" + node.classData.type + ">"; + } else { + classTitleString += "<" + node.classData.type + ">"; + } + } + const classTitleLabel = labelContainer.node().appendChild(createLabel$1(classTitleString, node.labelStyle, true, true)); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel).attr("class", "classTitle"); + let classTitleBBox = classTitleLabel.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = classTitleLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel); + classTitleBBox = div.getBoundingClientRect(); + dv.attr("width", classTitleBBox.width); + dv.attr("height", classTitleBBox.height); + } + maxHeight += classTitleBBox.height + rowPadding; + if (classTitleBBox.width > maxWidth) { + maxWidth = classTitleBBox.width; + } + const classAttributes = []; + node.classData.members.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let parsedText = parsedInfo.displayText; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + parsedText = parsedText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + parsedText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classAttributes.push(lbl); + }); + maxHeight += lineHeight; + const classMethods = []; + node.classData.methods.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let displayText = parsedInfo.displayText; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + displayText = displayText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + displayText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classMethods.push(lbl); + }); + maxHeight += lineHeight; + if (hasInterface) { + let diffX2 = (maxWidth - interfaceBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(interfaceLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")" + ); + verticalPos = interfaceBBox.height + rowPadding; + } + let diffX = (maxWidth - classTitleBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + verticalPos += classTitleBBox.height + rowPadding; + topLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classAttributes.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + verticalPos += lineHeight; + bottomLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classMethods.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + rect2.attr("style", node.style).attr("class", "outer title-state").attr("x", -maxWidth / 2 - halfPadding).attr("y", -(maxHeight / 2) - halfPadding).attr("width", maxWidth + node.padding).attr("height", maxHeight + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const shapes = { + rhombus: question, + composite, + question, + rect, + labelRect, + rectWithTitle, + choice, + circle, + doublecircle, + stadium, + hexagon, + block_arrow, + rect_left_inv_arrow, + lean_right, + lean_left, + trapezoid, + inv_trapezoid, + rect_right_inv_arrow, + cylinder, + start, + end, + note: note$1, + subroutine, + fork: forkJoin, + join: forkJoin, + class_box +}; +let nodeElems = {}; +const insertNode = async (elem, node, dir) => { + let newEl; + let el; + if (node.link) { + let target; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel === "sandbox") { + target = "_top"; + } else if (node.linkTarget) { + target = node.linkTarget || "_blank"; + } + newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target); + el = await shapes[node.shape](newEl, node, dir); + } else { + el = await shapes[node.shape](elem, node, dir); + newEl = el; + } + if (node.tooltip) { + el.attr("title", node.tooltip); + } + if (node.class) { + el.attr("class", "node default " + node.class); + } + newEl.attr("data-node", "true"); + newEl.attr("data-id", node.id); + nodeElems[node.id] = newEl; + if (node.haveCallback) { + nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable"); + } + return newEl; +}; +const setNodeElem = (elem, node) => { + nodeElems[node.id] = elem; +}; +const clear$1 = () => { + nodeElems = {}; +}; +const positionNode = (node) => { + const el = nodeElems[node.id]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace( + "Transforming node", + node.diff, + node, + "translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")" + ); + const padding = 8; + const diff = node.diff || 0; + if (node.clusterNode) { + el.attr( + "transform", + "translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")" + ); + } else { + el.attr("transform", "translate(" + node.x + ", " + node.y + ")"); + } + return diff; +}; +const getSubGraphTitleMargins = ({ + flowchart +}) => { + var _a, _b; + const subGraphTitleTopMargin = ((_a = flowchart == null ? void 0 : flowchart.subGraphTitleMargin) == null ? void 0 : _a.top) ?? 0; + const subGraphTitleBottomMargin = ((_b = flowchart == null ? void 0 : flowchart.subGraphTitleMargin) == null ? void 0 : _b.bottom) ?? 0; + const subGraphTitleTotalMargin = subGraphTitleTopMargin + subGraphTitleBottomMargin; + return { + subGraphTitleTopMargin, + subGraphTitleBottomMargin, + subGraphTitleTotalMargin + }; +}; +const markerOffsets = { + aggregation: 18, + extension: 18, + composition: 18, + dependency: 6, + lollipop: 13.5, + arrow_point: 5.3 +}; +function calculateDeltaAndAngle(point1, point2) { + if (point1 === void 0 || point2 === void 0) { + return { angle: 0, deltaX: 0, deltaY: 0 }; + } + point1 = pointTransformer(point1); + point2 = pointTransformer(point2); + const [x1, y1] = [point1.x, point1.y]; + const [x2, y2] = [point2.x, point2.y]; + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY }; +} +const pointTransformer = (data) => { + if (Array.isArray(data)) { + return { x: data[0], y: data[1] }; + } + return data; +}; +const getLineFunctionsWithOffset = (edge) => { + return { + x: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaX } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } + return pointTransformer(d).x + offset; + }, + y: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaY } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } + return pointTransformer(d).y + offset; + } + }; +}; +const addEdgeMarkers = (svgPath, edge, url, id, diagramType) => { + if (edge.arrowTypeStart) { + addEdgeMarker(svgPath, "start", edge.arrowTypeStart, url, id, diagramType); + } + if (edge.arrowTypeEnd) { + addEdgeMarker(svgPath, "end", edge.arrowTypeEnd, url, id, diagramType); + } +}; +const arrowTypesMap = { + arrow_cross: "cross", + arrow_point: "point", + arrow_barb: "barb", + arrow_circle: "circle", + aggregation: "aggregation", + extension: "extension", + composition: "composition", + dependency: "dependency", + lollipop: "lollipop" +}; +const addEdgeMarker = (svgPath, position, arrowType, url, id, diagramType) => { + const endMarkerType = arrowTypesMap[arrowType]; + if (!endMarkerType) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown arrow type: ${arrowType}`); + return; + } + const suffix = position === "start" ? "Start" : "End"; + svgPath.attr(`marker-${position}`, `url(${url}#${id}_${diagramType}-${endMarkerType}${suffix})`); +}; +let edgeLabels = {}; +let terminalLabels = {}; +const clear = () => { + edgeLabels = {}; + terminalLabels = {}; +}; +const insertEdgeLabel = (elem, edge) => { + const useHtmlLabels = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + const labelElement = edge.labelType === "markdown" ? (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__.a)(elem, edge.label, { + style: edge.labelStyle, + useHtmlLabels, + addSvgBackground: true + }) : createLabel$1(edge.label, edge.labelStyle); + const edgeLabel = elem.insert("g").attr("class", "edgeLabel"); + const label = edgeLabel.insert("g").attr("class", "label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + if (useHtmlLabels) { + const div = labelElement.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(labelElement); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + edgeLabels[edge.id] = edgeLabel; + edge.width = bbox.width; + edge.height = bbox.height; + let fo; + if (edge.startLabelLeft) { + const startLabelElement = createLabel$1(edge.startLabelLeft, edge.labelStyle); + const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startLeft = startEdgeLabelLeft; + setTerminalWidth(fo, edge.startLabelLeft); + } + if (edge.startLabelRight) { + const startLabelElement = createLabel$1(edge.startLabelRight, edge.labelStyle); + const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelRight.insert("g").attr("class", "inner"); + fo = startEdgeLabelRight.node().appendChild(startLabelElement); + inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startRight = startEdgeLabelRight; + setTerminalWidth(fo, edge.startLabelRight); + } + if (edge.endLabelLeft) { + const endLabelElement = createLabel$1(edge.endLabelLeft, edge.labelStyle); + const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelLeft.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endLeft = endEdgeLabelLeft; + setTerminalWidth(fo, edge.endLabelLeft); + } + if (edge.endLabelRight) { + const endLabelElement = createLabel$1(edge.endLabelRight, edge.labelStyle); + const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelRight.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelRight.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endRight = endEdgeLabelRight; + setTerminalWidth(fo, edge.endLabelRight); + } + return labelElement; +}; +function setTerminalWidth(fo, value) { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels && fo) { + fo.style.width = value.length * 9 + "px"; + fo.style.height = "12px"; + } +} +const positionEdgeLabel = (edge, paths) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("Moving label abc88 ", edge.id, edge.label, edgeLabels[edge.id], paths); + let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig); + if (edge.label) { + const el = edgeLabels[edge.id]; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcLabelPosition(path); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug( + "Moving label " + edge.label + " from (", + x, + ",", + y, + ") to (", + pos.x, + ",", + pos.y, + ") abc88" + ); + if (paths.updatedPath) { + x = pos.x; + y = pos.y; + } + } + el.attr("transform", `translate(${x}, ${y + subGraphTitleTotalMargin / 2})`); + } + if (edge.startLabelLeft) { + const el = terminalLabels[edge.id].startLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.startLabelRight) { + const el = terminalLabels[edge.id].startRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition( + edge.arrowTypeStart ? 10 : 0, + "start_right", + path + ); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.endLabelLeft) { + const el = terminalLabels[edge.id].endLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.endLabelRight) { + const el = terminalLabels[edge.id].endRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } +}; +const outsideNode = (node, point2) => { + const x = node.x; + const y = node.y; + const dx = Math.abs(point2.x - x); + const dy = Math.abs(point2.y - y); + const w = node.width / 2; + const h = node.height / 2; + if (dx >= w || dy >= h) { + return true; + } + return false; +}; +const intersection = (node, outsidePoint, insidePoint) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`intersection calc abc89: + outsidePoint: ${JSON.stringify(outsidePoint)} + insidePoint : ${JSON.stringify(insidePoint)} + node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`); + const x = node.x; + const y = node.y; + const dx = Math.abs(x - insidePoint.x); + const w = node.width / 2; + let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; + const h = node.height / 2; + const Q = Math.abs(outsidePoint.y - insidePoint.y); + const R = Math.abs(outsidePoint.x - insidePoint.x); + if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { + let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y; + r = R * q / Q; + const res = { + x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r, + y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q + }; + if (r === 0) { + res.x = outsidePoint.x; + res.y = outsidePoint.y; + } + if (R === 0) { + res.x = outsidePoint.x; + } + if (Q === 0) { + res.y = outsidePoint.y; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res); + return res; + } else { + if (insidePoint.x < outsidePoint.x) { + r = outsidePoint.x - w - x; + } else { + r = x - w - outsidePoint.x; + } + let q = Q * r / R; + let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r; + let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y }); + if (r === 0) { + _x = outsidePoint.x; + _y = outsidePoint.y; + } + if (R === 0) { + _x = outsidePoint.x; + } + if (Q === 0) { + _y = outsidePoint.y; + } + return { x: _x, y: _y }; + } +}; +const cutPathAtIntersect = (_points, boundaryNode) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("abc88 cutPathAtIntersect", _points, boundaryNode); + let points = []; + let lastPointOutside = _points[0]; + let isInside = false; + _points.forEach((point2) => { + if (!outsideNode(boundaryNode, point2) && !isInside) { + const inter = intersection(boundaryNode, lastPointOutside, point2); + let pointPresent = false; + points.forEach((p) => { + pointPresent = pointPresent || p.x === inter.x && p.y === inter.y; + }); + if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { + points.push(inter); + } + isInside = true; + } else { + lastPointOutside = point2; + if (!isInside) { + points.push(point2); + } + } + }); + return points; +}; +const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph, id) { + let points = edge.points; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("abc88 InsertEdge: edge=", edge, "e=", e); + let pointsHasChanged = false; + const tail = graph.node(e.v); + var head = graph.node(e.w); + if ((head == null ? void 0 : head.intersect) && (tail == null ? void 0 : tail.intersect)) { + points = points.slice(1, edge.points.length - 1); + points.unshift(tail.intersect(points[0])); + points.push(head.intersect(points[points.length - 1])); + } + if (edge.toCluster) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("to cluster abc88", clusterDb[edge.toCluster]); + points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); + pointsHasChanged = true; + } + if (edge.fromCluster) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("from cluster abc88", clusterDb[edge.fromCluster]); + points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse(); + pointsHasChanged = true; + } + const lineData = points.filter((p) => !Number.isNaN(p.y)); + let curve = d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .qrM; + if (edge.curve && (diagramType === "graph" || diagramType === "flowchart")) { + curve = edge.curve; + } + const { x, y } = getLineFunctionsWithOffset(edge); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .n8j)().x(x).y(y).curve(curve); + let strokeClasses; + switch (edge.thickness) { + case "normal": + strokeClasses = "edge-thickness-normal"; + break; + case "thick": + strokeClasses = "edge-thickness-thick"; + break; + case "invisible": + strokeClasses = "edge-thickness-thick"; + break; + default: + strokeClasses = ""; + } + switch (edge.pattern) { + case "solid": + strokeClasses += " edge-pattern-solid"; + break; + case "dotted": + strokeClasses += " edge-pattern-dotted"; + break; + case "dashed": + strokeClasses += " edge-pattern-dashed"; + break; + } + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style); + let url = ""; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.arrowMarkerAbsolute || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + addEdgeMarkers(svgPath, edge, url, id, diagramType); + let paths = {}; + if (pointsHasChanged) { + paths.updatedPath = points; + } + paths.originalPath = edge.points; + return paths; +}; + + + +/***/ }), + +/***/ 66216: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ f: () => (/* binding */ flowDb), +/* harmony export */ p: () => (/* binding */ parser$1) +/* harmony export */ }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 4], $V1 = [1, 3], $V2 = [1, 5], $V3 = [1, 8, 9, 10, 11, 27, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $V4 = [2, 2], $V5 = [1, 13], $V6 = [1, 14], $V7 = [1, 15], $V8 = [1, 16], $V9 = [1, 23], $Va = [1, 25], $Vb = [1, 26], $Vc = [1, 27], $Vd = [1, 49], $Ve = [1, 48], $Vf = [1, 29], $Vg = [1, 30], $Vh = [1, 31], $Vi = [1, 32], $Vj = [1, 33], $Vk = [1, 44], $Vl = [1, 46], $Vm = [1, 42], $Vn = [1, 47], $Vo = [1, 43], $Vp = [1, 50], $Vq = [1, 45], $Vr = [1, 51], $Vs = [1, 52], $Vt = [1, 34], $Vu = [1, 35], $Vv = [1, 36], $Vw = [1, 37], $Vx = [1, 57], $Vy = [1, 8, 9, 10, 11, 27, 32, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $Vz = [1, 61], $VA = [1, 60], $VB = [1, 62], $VC = [8, 9, 11, 73, 75], $VD = [1, 88], $VE = [1, 93], $VF = [1, 92], $VG = [1, 89], $VH = [1, 85], $VI = [1, 91], $VJ = [1, 87], $VK = [1, 94], $VL = [1, 90], $VM = [1, 95], $VN = [1, 86], $VO = [8, 9, 10, 11, 73, 75], $VP = [8, 9, 10, 11, 44, 73, 75], $VQ = [8, 9, 10, 11, 29, 42, 44, 46, 48, 50, 52, 54, 56, 58, 61, 63, 65, 66, 68, 73, 75, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VR = [8, 9, 11, 42, 58, 73, 75, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VS = [42, 58, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VT = [1, 121], $VU = [1, 120], $VV = [1, 128], $VW = [1, 142], $VX = [1, 143], $VY = [1, 144], $VZ = [1, 145], $V_ = [1, 130], $V$ = [1, 132], $V01 = [1, 136], $V11 = [1, 137], $V21 = [1, 138], $V31 = [1, 139], $V41 = [1, 140], $V51 = [1, 141], $V61 = [1, 146], $V71 = [1, 147], $V81 = [1, 126], $V91 = [1, 127], $Va1 = [1, 134], $Vb1 = [1, 129], $Vc1 = [1, 133], $Vd1 = [1, 131], $Ve1 = [8, 9, 10, 11, 27, 32, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $Vf1 = [1, 149], $Vg1 = [8, 9, 11], $Vh1 = [8, 9, 10, 11, 14, 42, 58, 86, 102, 103, 106, 108, 111, 112, 113], $Vi1 = [1, 169], $Vj1 = [1, 165], $Vk1 = [1, 166], $Vl1 = [1, 170], $Vm1 = [1, 167], $Vn1 = [1, 168], $Vo1 = [75, 113, 116], $Vp1 = [8, 9, 10, 11, 12, 14, 27, 29, 32, 42, 58, 73, 81, 82, 83, 84, 85, 86, 87, 102, 106, 108, 111, 112, 113], $Vq1 = [10, 103], $Vr1 = [31, 47, 49, 51, 53, 55, 60, 62, 64, 65, 67, 69, 113, 114, 115], $Vs1 = [1, 235], $Vt1 = [1, 233], $Vu1 = [1, 237], $Vv1 = [1, 231], $Vw1 = [1, 232], $Vx1 = [1, 234], $Vy1 = [1, 236], $Vz1 = [1, 238], $VA1 = [1, 255], $VB1 = [8, 9, 11, 103], $VC1 = [8, 9, 10, 11, 58, 81, 102, 103, 106, 107, 108, 109]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "graphConfig": 4, "document": 5, "line": 6, "statement": 7, "SEMI": 8, "NEWLINE": 9, "SPACE": 10, "EOF": 11, "GRAPH": 12, "NODIR": 13, "DIR": 14, "FirstStmtSeparator": 15, "ending": 16, "endToken": 17, "spaceList": 18, "spaceListNewline": 19, "vertexStatement": 20, "separator": 21, "styleStatement": 22, "linkStyleStatement": 23, "classDefStatement": 24, "classStatement": 25, "clickStatement": 26, "subgraph": 27, "textNoTags": 28, "SQS": 29, "text": 30, "SQE": 31, "end": 32, "direction": 33, "acc_title": 34, "acc_title_value": 35, "acc_descr": 36, "acc_descr_value": 37, "acc_descr_multiline_value": 38, "link": 39, "node": 40, "styledVertex": 41, "AMP": 42, "vertex": 43, "STYLE_SEPARATOR": 44, "idString": 45, "DOUBLECIRCLESTART": 46, "DOUBLECIRCLEEND": 47, "PS": 48, "PE": 49, "(-": 50, "-)": 51, "STADIUMSTART": 52, "STADIUMEND": 53, "SUBROUTINESTART": 54, "SUBROUTINEEND": 55, "VERTEX_WITH_PROPS_START": 56, "NODE_STRING[field]": 57, "COLON": 58, "NODE_STRING[value]": 59, "PIPE": 60, "CYLINDERSTART": 61, "CYLINDEREND": 62, "DIAMOND_START": 63, "DIAMOND_STOP": 64, "TAGEND": 65, "TRAPSTART": 66, "TRAPEND": 67, "INVTRAPSTART": 68, "INVTRAPEND": 69, "linkStatement": 70, "arrowText": 71, "TESTSTR": 72, "START_LINK": 73, "edgeText": 74, "LINK": 75, "edgeTextToken": 76, "STR": 77, "MD_STR": 78, "textToken": 79, "keywords": 80, "STYLE": 81, "LINKSTYLE": 82, "CLASSDEF": 83, "CLASS": 84, "CLICK": 85, "DOWN": 86, "UP": 87, "textNoTagsToken": 88, "stylesOpt": 89, "idString[vertex]": 90, "idString[class]": 91, "CALLBACKNAME": 92, "CALLBACKARGS": 93, "HREF": 94, "LINK_TARGET": 95, "STR[link]": 96, "STR[tooltip]": 97, "alphaNum": 98, "DEFAULT": 99, "numList": 100, "INTERPOLATE": 101, "NUM": 102, "COMMA": 103, "style": 104, "styleComponent": 105, "NODE_STRING": 106, "UNIT": 107, "BRKT": 108, "PCT": 109, "idStringToken": 110, "MINUS": 111, "MULT": 112, "UNICODE_TEXT": 113, "TEXT": 114, "TAGSTART": 115, "EDGE_TEXT": 116, "alphaNumToken": 117, "direction_tb": 118, "direction_bt": 119, "direction_rl": 120, "direction_lr": 121, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 8: "SEMI", 9: "NEWLINE", 10: "SPACE", 11: "EOF", 12: "GRAPH", 13: "NODIR", 14: "DIR", 27: "subgraph", 29: "SQS", 31: "SQE", 32: "end", 34: "acc_title", 35: "acc_title_value", 36: "acc_descr", 37: "acc_descr_value", 38: "acc_descr_multiline_value", 42: "AMP", 44: "STYLE_SEPARATOR", 46: "DOUBLECIRCLESTART", 47: "DOUBLECIRCLEEND", 48: "PS", 49: "PE", 50: "(-", 51: "-)", 52: "STADIUMSTART", 53: "STADIUMEND", 54: "SUBROUTINESTART", 55: "SUBROUTINEEND", 56: "VERTEX_WITH_PROPS_START", 57: "NODE_STRING[field]", 58: "COLON", 59: "NODE_STRING[value]", 60: "PIPE", 61: "CYLINDERSTART", 62: "CYLINDEREND", 63: "DIAMOND_START", 64: "DIAMOND_STOP", 65: "TAGEND", 66: "TRAPSTART", 67: "TRAPEND", 68: "INVTRAPSTART", 69: "INVTRAPEND", 72: "TESTSTR", 73: "START_LINK", 75: "LINK", 77: "STR", 78: "MD_STR", 81: "STYLE", 82: "LINKSTYLE", 83: "CLASSDEF", 84: "CLASS", 85: "CLICK", 86: "DOWN", 87: "UP", 90: "idString[vertex]", 91: "idString[class]", 92: "CALLBACKNAME", 93: "CALLBACKARGS", 94: "HREF", 95: "LINK_TARGET", 96: "STR[link]", 97: "STR[tooltip]", 99: "DEFAULT", 101: "INTERPOLATE", 102: "NUM", 103: "COMMA", 106: "NODE_STRING", 107: "UNIT", 108: "BRKT", 109: "PCT", 111: "MINUS", 112: "MULT", 113: "UNICODE_TEXT", 114: "TEXT", 115: "TAGSTART", 116: "EDGE_TEXT", 118: "direction_tb", 119: "direction_bt", 120: "direction_rl", 121: "direction_lr" }, + productions_: [0, [3, 2], [5, 0], [5, 2], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [4, 2], [4, 2], [4, 2], [4, 3], [16, 2], [16, 1], [17, 1], [17, 1], [17, 1], [15, 1], [15, 1], [15, 2], [19, 2], [19, 2], [19, 1], [19, 1], [18, 2], [18, 1], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 9], [7, 6], [7, 4], [7, 1], [7, 2], [7, 2], [7, 1], [21, 1], [21, 1], [21, 1], [20, 3], [20, 4], [20, 2], [20, 1], [40, 1], [40, 5], [41, 1], [41, 3], [43, 4], [43, 4], [43, 6], [43, 4], [43, 4], [43, 4], [43, 8], [43, 4], [43, 4], [43, 4], [43, 6], [43, 4], [43, 4], [43, 4], [43, 4], [43, 4], [43, 1], [39, 2], [39, 3], [39, 3], [39, 1], [39, 3], [74, 1], [74, 2], [74, 1], [74, 1], [70, 1], [71, 3], [30, 1], [30, 2], [30, 1], [30, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [28, 1], [28, 2], [28, 1], [28, 1], [24, 5], [25, 5], [26, 2], [26, 4], [26, 3], [26, 5], [26, 3], [26, 5], [26, 5], [26, 7], [26, 2], [26, 4], [26, 2], [26, 4], [26, 4], [26, 6], [22, 5], [23, 5], [23, 5], [23, 9], [23, 9], [23, 7], [23, 7], [100, 1], [100, 3], [89, 1], [89, 3], [104, 1], [104, 2], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [79, 1], [79, 1], [79, 1], [79, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [76, 1], [76, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [45, 1], [45, 2], [98, 1], [98, 2], [33, 1], [33, 1], [33, 1], [33, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 2: + this.$ = []; + break; + case 3: + if (!Array.isArray($$[$0]) || $$[$0].length > 0) { + $$[$0 - 1].push($$[$0]); + } + this.$ = $$[$0 - 1]; + break; + case 4: + case 176: + this.$ = $$[$0]; + break; + case 11: + yy.setDirection("TB"); + this.$ = "TB"; + break; + case 12: + yy.setDirection($$[$0 - 1]); + this.$ = $$[$0 - 1]; + break; + case 27: + this.$ = $$[$0 - 1].nodes; + break; + case 28: + case 29: + case 30: + case 31: + case 32: + this.$ = []; + break; + case 33: + this.$ = yy.addSubGraph($$[$0 - 6], $$[$0 - 1], $$[$0 - 4]); + break; + case 34: + this.$ = yy.addSubGraph($$[$0 - 3], $$[$0 - 1], $$[$0 - 3]); + break; + case 35: + this.$ = yy.addSubGraph(void 0, $$[$0 - 1], void 0); + break; + case 37: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 38: + case 39: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 43: + yy.addLink($$[$0 - 2].stmt, $$[$0], $$[$0 - 1]); + this.$ = { stmt: $$[$0], nodes: $$[$0].concat($$[$0 - 2].nodes) }; + break; + case 44: + yy.addLink($$[$0 - 3].stmt, $$[$0 - 1], $$[$0 - 2]); + this.$ = { stmt: $$[$0 - 1], nodes: $$[$0 - 1].concat($$[$0 - 3].nodes) }; + break; + case 45: + this.$ = { stmt: $$[$0 - 1], nodes: $$[$0 - 1] }; + break; + case 46: + this.$ = { stmt: $$[$0], nodes: $$[$0] }; + break; + case 47: + this.$ = [$$[$0]]; + break; + case 48: + this.$ = $$[$0 - 4].concat($$[$0]); + break; + case 49: + this.$ = $$[$0]; + break; + case 50: + this.$ = $$[$0 - 2]; + yy.setClass($$[$0 - 2], $$[$0]); + break; + case 51: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "square"); + break; + case 52: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "doublecircle"); + break; + case 53: + this.$ = $$[$0 - 5]; + yy.addVertex($$[$0 - 5], $$[$0 - 2], "circle"); + break; + case 54: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "ellipse"); + break; + case 55: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "stadium"); + break; + case 56: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "subroutine"); + break; + case 57: + this.$ = $$[$0 - 7]; + yy.addVertex($$[$0 - 7], $$[$0 - 1], "rect", void 0, void 0, void 0, Object.fromEntries([[$$[$0 - 5], $$[$0 - 3]]])); + break; + case 58: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "cylinder"); + break; + case 59: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "round"); + break; + case 60: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "diamond"); + break; + case 61: + this.$ = $$[$0 - 5]; + yy.addVertex($$[$0 - 5], $$[$0 - 2], "hexagon"); + break; + case 62: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "odd"); + break; + case 63: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "trapezoid"); + break; + case 64: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "inv_trapezoid"); + break; + case 65: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "lean_right"); + break; + case 66: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "lean_left"); + break; + case 67: + this.$ = $$[$0]; + yy.addVertex($$[$0]); + break; + case 68: + $$[$0 - 1].text = $$[$0]; + this.$ = $$[$0 - 1]; + break; + case 69: + case 70: + $$[$0 - 2].text = $$[$0 - 1]; + this.$ = $$[$0 - 2]; + break; + case 71: + this.$ = $$[$0]; + break; + case 72: + var inf = yy.destructLink($$[$0], $$[$0 - 2]); + this.$ = { "type": inf.type, "stroke": inf.stroke, "length": inf.length, "text": $$[$0 - 1] }; + break; + case 73: + this.$ = { text: $$[$0], type: "text" }; + break; + case 74: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 75: + this.$ = { text: $$[$0], type: "string" }; + break; + case 76: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 77: + var inf = yy.destructLink($$[$0]); + this.$ = { "type": inf.type, "stroke": inf.stroke, "length": inf.length }; + break; + case 78: + this.$ = $$[$0 - 1]; + break; + case 79: + this.$ = { text: $$[$0], type: "text" }; + break; + case 80: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 81: + this.$ = { text: $$[$0], type: "string" }; + break; + case 82: + case 97: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 94: + this.$ = { text: $$[$0], type: "text" }; + break; + case 95: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 96: + this.$ = { text: $$[$0], type: "text" }; + break; + case 98: + this.$ = $$[$0 - 4]; + yy.addClass($$[$0 - 2], $$[$0]); + break; + case 99: + this.$ = $$[$0 - 4]; + yy.setClass($$[$0 - 2], $$[$0]); + break; + case 100: + case 108: + this.$ = $$[$0 - 1]; + yy.setClickEvent($$[$0 - 1], $$[$0]); + break; + case 101: + case 109: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 102: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 103: + this.$ = $$[$0 - 4]; + yy.setClickEvent($$[$0 - 4], $$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 4], $$[$0]); + break; + case 104: + this.$ = $$[$0 - 2]; + yy.setLink($$[$0 - 2], $$[$0]); + break; + case 105: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 4], $$[$0 - 2]); + yy.setTooltip($$[$0 - 4], $$[$0]); + break; + case 106: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 4], $$[$0 - 2], $$[$0]); + break; + case 107: + this.$ = $$[$0 - 6]; + yy.setLink($$[$0 - 6], $$[$0 - 4], $$[$0]); + yy.setTooltip($$[$0 - 6], $$[$0 - 2]); + break; + case 110: + this.$ = $$[$0 - 1]; + yy.setLink($$[$0 - 1], $$[$0]); + break; + case 111: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 112: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 3], $$[$0 - 2], $$[$0]); + break; + case 113: + this.$ = $$[$0 - 5]; + yy.setLink($$[$0 - 5], $$[$0 - 4], $$[$0]); + yy.setTooltip($$[$0 - 5], $$[$0 - 2]); + break; + case 114: + this.$ = $$[$0 - 4]; + yy.addVertex($$[$0 - 2], void 0, void 0, $$[$0]); + break; + case 115: + this.$ = $$[$0 - 4]; + yy.updateLink([$$[$0 - 2]], $$[$0]); + break; + case 116: + this.$ = $$[$0 - 4]; + yy.updateLink($$[$0 - 2], $$[$0]); + break; + case 117: + this.$ = $$[$0 - 8]; + yy.updateLinkInterpolate([$$[$0 - 6]], $$[$0 - 2]); + yy.updateLink([$$[$0 - 6]], $$[$0]); + break; + case 118: + this.$ = $$[$0 - 8]; + yy.updateLinkInterpolate($$[$0 - 6], $$[$0 - 2]); + yy.updateLink($$[$0 - 6], $$[$0]); + break; + case 119: + this.$ = $$[$0 - 6]; + yy.updateLinkInterpolate([$$[$0 - 4]], $$[$0]); + break; + case 120: + this.$ = $$[$0 - 6]; + yy.updateLinkInterpolate($$[$0 - 4], $$[$0]); + break; + case 121: + case 123: + this.$ = [$$[$0]]; + break; + case 122: + case 124: + $$[$0 - 2].push($$[$0]); + this.$ = $$[$0 - 2]; + break; + case 126: + this.$ = $$[$0 - 1] + $$[$0]; + break; + case 174: + this.$ = $$[$0]; + break; + case 175: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + case 177: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + case 178: + this.$ = { stmt: "dir", value: "TB" }; + break; + case 179: + this.$ = { stmt: "dir", value: "BT" }; + break; + case 180: + this.$ = { stmt: "dir", value: "RL" }; + break; + case 181: + this.$ = { stmt: "dir", value: "LR" }; + break; + } + }, + table: [{ 3: 1, 4: 2, 9: $V0, 10: $V1, 12: $V2 }, { 1: [3] }, o($V3, $V4, { 5: 6 }), { 4: 7, 9: $V0, 10: $V1, 12: $V2 }, { 4: 8, 9: $V0, 10: $V1, 12: $V2 }, { 13: [1, 9], 14: [1, 10] }, { 1: [2, 1], 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, o($V3, [2, 9]), o($V3, [2, 10]), o($V3, [2, 11]), { 8: [1, 54], 9: [1, 55], 10: $Vx, 15: 53, 18: 56 }, o($Vy, [2, 3]), o($Vy, [2, 4]), o($Vy, [2, 5]), o($Vy, [2, 6]), o($Vy, [2, 7]), o($Vy, [2, 8]), { 8: $Vz, 9: $VA, 11: $VB, 21: 58, 39: 59, 70: 63, 73: [1, 64], 75: [1, 65] }, { 8: $Vz, 9: $VA, 11: $VB, 21: 66 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 67 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 68 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 69 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 70 }, { 8: $Vz, 9: $VA, 10: [1, 71], 11: $VB, 21: 72 }, o($Vy, [2, 36]), { 35: [1, 73] }, { 37: [1, 74] }, o($Vy, [2, 39]), o($VC, [2, 46], { 18: 75, 10: $Vx }), { 10: [1, 76] }, { 10: [1, 77] }, { 10: [1, 78] }, { 10: [1, 79] }, { 14: $VD, 42: $VE, 58: $VF, 77: [1, 83], 86: $VG, 92: [1, 80], 94: [1, 81], 98: 82, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, o($Vy, [2, 178]), o($Vy, [2, 179]), o($Vy, [2, 180]), o($Vy, [2, 181]), o($VO, [2, 47]), o($VO, [2, 49], { 44: [1, 96] }), o($VP, [2, 67], { 110: 109, 29: [1, 97], 42: $Vd, 46: [1, 98], 48: [1, 99], 50: [1, 100], 52: [1, 101], 54: [1, 102], 56: [1, 103], 58: $Ve, 61: [1, 104], 63: [1, 105], 65: [1, 106], 66: [1, 107], 68: [1, 108], 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), o($VQ, [2, 174]), o($VQ, [2, 135]), o($VQ, [2, 136]), o($VQ, [2, 137]), o($VQ, [2, 138]), o($VQ, [2, 139]), o($VQ, [2, 140]), o($VQ, [2, 141]), o($VQ, [2, 142]), o($VQ, [2, 143]), o($VQ, [2, 144]), o($VQ, [2, 145]), o($V3, [2, 12]), o($V3, [2, 18]), o($V3, [2, 19]), { 9: [1, 110] }, o($VR, [2, 26], { 18: 111, 10: $Vx }), o($Vy, [2, 27]), { 40: 112, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vy, [2, 40]), o($Vy, [2, 41]), o($Vy, [2, 42]), o($VS, [2, 71], { 71: 113, 60: [1, 115], 72: [1, 114] }), { 74: 116, 76: 117, 77: [1, 118], 78: [1, 119], 113: $VT, 116: $VU }, o([42, 58, 60, 72, 86, 99, 102, 103, 106, 108, 111, 112, 113], [2, 77]), o($Vy, [2, 28]), o($Vy, [2, 29]), o($Vy, [2, 30]), o($Vy, [2, 31]), o($Vy, [2, 32]), { 10: $VV, 12: $VW, 14: $VX, 27: $VY, 28: 122, 32: $VZ, 42: $V_, 58: $V$, 73: $V01, 77: [1, 124], 78: [1, 125], 80: 135, 81: $V11, 82: $V21, 83: $V31, 84: $V41, 85: $V51, 86: $V61, 87: $V71, 88: 123, 102: $V81, 106: $V91, 108: $Va1, 111: $Vb1, 112: $Vc1, 113: $Vd1 }, o($Ve1, $V4, { 5: 148 }), o($Vy, [2, 37]), o($Vy, [2, 38]), o($VC, [2, 45], { 42: $Vf1 }), { 42: $Vd, 45: 150, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 99: [1, 151], 100: 152, 102: [1, 153] }, { 42: $Vd, 45: 154, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 42: $Vd, 45: 155, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vg1, [2, 100], { 10: [1, 156], 93: [1, 157] }), { 77: [1, 158] }, o($Vg1, [2, 108], { 117: 160, 10: [1, 159], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 110], { 10: [1, 161] }), o($Vh1, [2, 176]), o($Vh1, [2, 163]), o($Vh1, [2, 164]), o($Vh1, [2, 165]), o($Vh1, [2, 166]), o($Vh1, [2, 167]), o($Vh1, [2, 168]), o($Vh1, [2, 169]), o($Vh1, [2, 170]), o($Vh1, [2, 171]), o($Vh1, [2, 172]), o($Vh1, [2, 173]), { 42: $Vd, 45: 162, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 30: 163, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 171, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 173, 48: [1, 172], 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 174, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 175, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 176, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 106: [1, 177] }, { 30: 178, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 179, 63: [1, 180], 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 181, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 182, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 183, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VQ, [2, 175]), o($V3, [2, 20]), o($VR, [2, 25]), o($VC, [2, 43], { 18: 184, 10: $Vx }), o($VS, [2, 68], { 10: [1, 185] }), { 10: [1, 186] }, { 30: 187, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 75: [1, 188], 76: 189, 113: $VT, 116: $VU }, o($Vo1, [2, 73]), o($Vo1, [2, 75]), o($Vo1, [2, 76]), o($Vo1, [2, 161]), o($Vo1, [2, 162]), { 8: $Vz, 9: $VA, 10: $VV, 11: $VB, 12: $VW, 14: $VX, 21: 191, 27: $VY, 29: [1, 190], 32: $VZ, 42: $V_, 58: $V$, 73: $V01, 80: 135, 81: $V11, 82: $V21, 83: $V31, 84: $V41, 85: $V51, 86: $V61, 87: $V71, 88: 192, 102: $V81, 106: $V91, 108: $Va1, 111: $Vb1, 112: $Vc1, 113: $Vd1 }, o($Vp1, [2, 94]), o($Vp1, [2, 96]), o($Vp1, [2, 97]), o($Vp1, [2, 150]), o($Vp1, [2, 151]), o($Vp1, [2, 152]), o($Vp1, [2, 153]), o($Vp1, [2, 154]), o($Vp1, [2, 155]), o($Vp1, [2, 156]), o($Vp1, [2, 157]), o($Vp1, [2, 158]), o($Vp1, [2, 159]), o($Vp1, [2, 160]), o($Vp1, [2, 83]), o($Vp1, [2, 84]), o($Vp1, [2, 85]), o($Vp1, [2, 86]), o($Vp1, [2, 87]), o($Vp1, [2, 88]), o($Vp1, [2, 89]), o($Vp1, [2, 90]), o($Vp1, [2, 91]), o($Vp1, [2, 92]), o($Vp1, [2, 93]), { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 193], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, { 10: $Vx, 18: 194 }, { 10: [1, 195], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: [1, 196] }, { 10: [1, 197], 103: [1, 198] }, o($Vq1, [2, 121]), { 10: [1, 199], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: [1, 200], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 77: [1, 201] }, o($Vg1, [2, 102], { 10: [1, 202] }), o($Vg1, [2, 104], { 10: [1, 203] }), { 77: [1, 204] }, o($Vh1, [2, 177]), { 77: [1, 205], 95: [1, 206] }, o($VO, [2, 50], { 110: 109, 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), { 31: [1, 207], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($Vr1, [2, 79]), o($Vr1, [2, 81]), o($Vr1, [2, 82]), o($Vr1, [2, 146]), o($Vr1, [2, 147]), o($Vr1, [2, 148]), o($Vr1, [2, 149]), { 47: [1, 209], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 210, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 49: [1, 211], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 51: [1, 212], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 53: [1, 213], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 55: [1, 214], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 58: [1, 215] }, { 62: [1, 216], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 64: [1, 217], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 218, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 31: [1, 219], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 65: $Vi1, 67: [1, 220], 69: [1, 221], 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 65: $Vi1, 67: [1, 223], 69: [1, 222], 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VC, [2, 44], { 42: $Vf1 }), o($VS, [2, 70]), o($VS, [2, 69]), { 60: [1, 224], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VS, [2, 72]), o($Vo1, [2, 74]), { 30: 225, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($Ve1, $V4, { 5: 226 }), o($Vp1, [2, 95]), o($Vy, [2, 35]), { 41: 227, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 228, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 239, 101: [1, 240], 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 241, 101: [1, 242], 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 102: [1, 243] }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 244, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 42: $Vd, 45: 245, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vg1, [2, 101]), { 77: [1, 246] }, { 77: [1, 247], 95: [1, 248] }, o($Vg1, [2, 109]), o($Vg1, [2, 111], { 10: [1, 249] }), o($Vg1, [2, 112]), o($VP, [2, 51]), o($Vr1, [2, 80]), o($VP, [2, 52]), { 49: [1, 250], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 59]), o($VP, [2, 54]), o($VP, [2, 55]), o($VP, [2, 56]), { 106: [1, 251] }, o($VP, [2, 58]), o($VP, [2, 60]), { 64: [1, 252], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 62]), o($VP, [2, 63]), o($VP, [2, 65]), o($VP, [2, 64]), o($VP, [2, 66]), o([10, 42, 58, 86, 99, 102, 103, 106, 108, 111, 112, 113], [2, 78]), { 31: [1, 253], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 254], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, o($VO, [2, 48]), o($Vg1, [2, 114], { 103: $VA1 }), o($VB1, [2, 123], { 105: 256, 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }), o($VC1, [2, 125]), o($VC1, [2, 127]), o($VC1, [2, 128]), o($VC1, [2, 129]), o($VC1, [2, 130]), o($VC1, [2, 131]), o($VC1, [2, 132]), o($VC1, [2, 133]), o($VC1, [2, 134]), o($Vg1, [2, 115], { 103: $VA1 }), { 10: [1, 257] }, o($Vg1, [2, 116], { 103: $VA1 }), { 10: [1, 258] }, o($Vq1, [2, 122]), o($Vg1, [2, 98], { 103: $VA1 }), o($Vg1, [2, 99], { 110: 109, 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), o($Vg1, [2, 103]), o($Vg1, [2, 105], { 10: [1, 259] }), o($Vg1, [2, 106]), { 95: [1, 260] }, { 49: [1, 261] }, { 60: [1, 262] }, { 64: [1, 263] }, { 8: $Vz, 9: $VA, 11: $VB, 21: 264 }, o($Vy, [2, 34]), { 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 104: 265, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, o($VC1, [2, 126]), { 14: $VD, 42: $VE, 58: $VF, 86: $VG, 98: 266, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, { 14: $VD, 42: $VE, 58: $VF, 86: $VG, 98: 267, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, { 95: [1, 268] }, o($Vg1, [2, 113]), o($VP, [2, 53]), { 30: 269, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 61]), o($Ve1, $V4, { 5: 270 }), o($VB1, [2, 124], { 105: 256, 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }), o($Vg1, [2, 119], { 117: 160, 10: [1, 271], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 120], { 117: 160, 10: [1, 272], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 107]), { 31: [1, 273], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 274], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 275, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 276, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, o($VP, [2, 57]), o($Vy, [2, 33]), o($Vg1, [2, 117], { 103: $VA1 }), o($Vg1, [2, 118], { 103: $VA1 })], + defaultActions: {}, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex2() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex2(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex2() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.begin("acc_title"); + return 34; + case 1: + this.popState(); + return "acc_title_value"; + case 2: + this.begin("acc_descr"); + return 36; + case 3: + this.popState(); + return "acc_descr_value"; + case 4: + this.begin("acc_descr_multiline"); + break; + case 5: + this.popState(); + break; + case 6: + return "acc_descr_multiline_value"; + case 7: + this.begin("callbackname"); + break; + case 8: + this.popState(); + break; + case 9: + this.popState(); + this.begin("callbackargs"); + break; + case 10: + return 92; + case 11: + this.popState(); + break; + case 12: + return 93; + case 13: + return "MD_STR"; + case 14: + this.popState(); + break; + case 15: + this.begin("md_string"); + break; + case 16: + return "STR"; + case 17: + this.popState(); + break; + case 18: + this.pushState("string"); + break; + case 19: + return 81; + case 20: + return 99; + case 21: + return 82; + case 22: + return 101; + case 23: + return 83; + case 24: + return 84; + case 25: + return 94; + case 26: + this.begin("click"); + break; + case 27: + this.popState(); + break; + case 28: + return 85; + case 29: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 30: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 31: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 32: + return 27; + case 33: + return 32; + case 34: + return 95; + case 35: + return 95; + case 36: + return 95; + case 37: + return 95; + case 38: + this.popState(); + return 13; + case 39: + this.popState(); + return 14; + case 40: + this.popState(); + return 14; + case 41: + this.popState(); + return 14; + case 42: + this.popState(); + return 14; + case 43: + this.popState(); + return 14; + case 44: + this.popState(); + return 14; + case 45: + this.popState(); + return 14; + case 46: + this.popState(); + return 14; + case 47: + this.popState(); + return 14; + case 48: + this.popState(); + return 14; + case 49: + return 118; + case 50: + return 119; + case 51: + return 120; + case 52: + return 121; + case 53: + return 102; + case 54: + return 108; + case 55: + return 44; + case 56: + return 58; + case 57: + return 42; + case 58: + return 8; + case 59: + return 103; + case 60: + return 112; + case 61: + this.popState(); + return 75; + case 62: + this.pushState("edgeText"); + return 73; + case 63: + return 116; + case 64: + this.popState(); + return 75; + case 65: + this.pushState("thickEdgeText"); + return 73; + case 66: + return 116; + case 67: + this.popState(); + return 75; + case 68: + this.pushState("dottedEdgeText"); + return 73; + case 69: + return 116; + case 70: + return 75; + case 71: + this.popState(); + return 51; + case 72: + return "TEXT"; + case 73: + this.pushState("ellipseText"); + return 50; + case 74: + this.popState(); + return 53; + case 75: + this.pushState("text"); + return 52; + case 76: + this.popState(); + return 55; + case 77: + this.pushState("text"); + return 54; + case 78: + return 56; + case 79: + this.pushState("text"); + return 65; + case 80: + this.popState(); + return 62; + case 81: + this.pushState("text"); + return 61; + case 82: + this.popState(); + return 47; + case 83: + this.pushState("text"); + return 46; + case 84: + this.popState(); + return 67; + case 85: + this.popState(); + return 69; + case 86: + return 114; + case 87: + this.pushState("trapText"); + return 66; + case 88: + this.pushState("trapText"); + return 68; + case 89: + return 115; + case 90: + return 65; + case 91: + return 87; + case 92: + return "SEP"; + case 93: + return 86; + case 94: + return 112; + case 95: + return 108; + case 96: + return 42; + case 97: + return 106; + case 98: + return 111; + case 99: + return 113; + case 100: + this.popState(); + return 60; + case 101: + this.pushState("text"); + return 60; + case 102: + this.popState(); + return 49; + case 103: + this.pushState("text"); + return 48; + case 104: + this.popState(); + return 31; + case 105: + this.pushState("text"); + return 29; + case 106: + this.popState(); + return 64; + case 107: + this.pushState("text"); + return 63; + case 108: + return "TEXT"; + case 109: + return "QUOTE"; + case 110: + return 9; + case 111: + return 10; + case 112: + return 11; + } + }, + rules: [/^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:call[\s]+)/, /^(?:\([\s]*\))/, /^(?:\()/, /^(?:[^(]*)/, /^(?:\))/, /^(?:[^)]*)/, /^(?:[^`"]+)/, /^(?:[`]["])/, /^(?:["][`])/, /^(?:[^"]+)/, /^(?:["])/, /^(?:["])/, /^(?:style\b)/, /^(?:default\b)/, /^(?:linkStyle\b)/, /^(?:interpolate\b)/, /^(?:classDef\b)/, /^(?:class\b)/, /^(?:href[\s])/, /^(?:click[\s]+)/, /^(?:[\s\n])/, /^(?:[^\s\n]*)/, /^(?:flowchart-elk\b)/, /^(?:graph\b)/, /^(?:flowchart\b)/, /^(?:subgraph\b)/, /^(?:end\b\s*)/, /^(?:_self\b)/, /^(?:_blank\b)/, /^(?:_parent\b)/, /^(?:_top\b)/, /^(?:(\r?\n)*\s*\n)/, /^(?:\s*LR\b)/, /^(?:\s*RL\b)/, /^(?:\s*TB\b)/, /^(?:\s*BT\b)/, /^(?:\s*TD\b)/, /^(?:\s*BR\b)/, /^(?:\s*<)/, /^(?:\s*>)/, /^(?:\s*\^)/, /^(?:\s*v\b)/, /^(?:.*direction\s+TB[^\n]*)/, /^(?:.*direction\s+BT[^\n]*)/, /^(?:.*direction\s+RL[^\n]*)/, /^(?:.*direction\s+LR[^\n]*)/, /^(?:[0-9]+)/, /^(?:#)/, /^(?::::)/, /^(?::)/, /^(?:&)/, /^(?:;)/, /^(?:,)/, /^(?:\*)/, /^(?:\s*[xo<]?--+[-xo>]\s*)/, /^(?:\s*[xo<]?--\s*)/, /^(?:[^-]|-(?!-)+)/, /^(?:\s*[xo<]?==+[=xo>]\s*)/, /^(?:\s*[xo<]?==\s*)/, /^(?:[^=]|=(?!))/, /^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/, /^(?:\s*[xo<]?-\.\s*)/, /^(?:[^\.]|\.(?!))/, /^(?:\s*~~[\~]+\s*)/, /^(?:[-/\)][\)])/, /^(?:[^\(\)\[\]\{\}]|!\)+)/, /^(?:\(-)/, /^(?:\]\))/, /^(?:\(\[)/, /^(?:\]\])/, /^(?:\[\[)/, /^(?:\[\|)/, /^(?:>)/, /^(?:\)\])/, /^(?:\[\()/, /^(?:\)\)\))/, /^(?:\(\(\()/, /^(?:[\\(?=\])][\]])/, /^(?:\/(?=\])\])/, /^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/, /^(?:\[\/)/, /^(?:\[\\)/, /^(?:<)/, /^(?:>)/, /^(?:\^)/, /^(?:\\\|)/, /^(?:v\b)/, /^(?:\*)/, /^(?:#)/, /^(?:&)/, /^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/, /^(?:-)/, /^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/, /^(?:\|)/, /^(?:\|)/, /^(?:\))/, /^(?:\()/, /^(?:\])/, /^(?:\[)/, /^(?:(\}))/, /^(?:\{)/, /^(?:[^\[\]\(\)\{\}\|\"]+)/, /^(?:")/, /^(?:(\r?\n)+)/, /^(?:\s)/, /^(?:$)/], + conditions: { "callbackargs": { "rules": [11, 12, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "callbackname": { "rules": [8, 9, 10, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "href": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "click": { "rules": [15, 18, 27, 28, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "dottedEdgeText": { "rules": [15, 18, 67, 69, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "thickEdgeText": { "rules": [15, 18, 64, 66, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "edgeText": { "rules": [15, 18, 61, 63, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "trapText": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 84, 85, 86, 87, 88, 101, 103, 105, 107], "inclusive": false }, "ellipseText": { "rules": [15, 18, 70, 71, 72, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "text": { "rules": [15, 18, 70, 73, 74, 75, 76, 77, 80, 81, 82, 83, 87, 88, 100, 101, 102, 103, 104, 105, 106, 107, 108], "inclusive": false }, "vertex": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "dir": { "rules": [15, 18, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_descr_multiline": { "rules": [5, 6, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_descr": { "rules": [3, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_title": { "rules": [1, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "md_string": { "rules": [13, 14, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "string": { "rules": [15, 16, 17, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "INITIAL": { "rules": [0, 2, 4, 7, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 67, 68, 70, 73, 75, 77, 78, 79, 81, 83, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 101, 103, 105, 107, 109, 110, 111, 112], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const MERMAID_DOM_ID_PREFIX = "flowchart-"; +let vertexCounter = 0; +let config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); +let vertices = {}; +let edges = []; +let classes = {}; +let subGraphs = []; +let subGraphLookup = {}; +let tooltips = {}; +let subCount = 0; +let firstGraphFlag = true; +let direction; +let version; +let funs = []; +const sanitizeText = (txt) => _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(txt, config); +const lookUpDomId = function(id) { + const vertexKeys = Object.keys(vertices); + for (const vertexKey of vertexKeys) { + if (vertices[vertexKey].id === id) { + return vertices[vertexKey].domId; + } + } + return id; +}; +const addVertex = function(_id, textObj, type, style, classes2, dir, props = {}) { + let txt; + let id = _id; + if (id === void 0) { + return; + } + if (id.trim().length === 0) { + return; + } + if (vertices[id] === void 0) { + vertices[id] = { + id, + labelType: "text", + domId: MERMAID_DOM_ID_PREFIX + id + "-" + vertexCounter, + styles: [], + classes: [] + }; + } + vertexCounter++; + if (textObj !== void 0) { + config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + txt = sanitizeText(textObj.text.trim()); + vertices[id].labelType = textObj.type; + if (txt[0] === '"' && txt[txt.length - 1] === '"') { + txt = txt.substring(1, txt.length - 1); + } + vertices[id].text = txt; + } else { + if (vertices[id].text === void 0) { + vertices[id].text = _id; + } + } + if (type !== void 0) { + vertices[id].type = type; + } + if (style !== void 0 && style !== null) { + style.forEach(function(s) { + vertices[id].styles.push(s); + }); + } + if (classes2 !== void 0 && classes2 !== null) { + classes2.forEach(function(s) { + vertices[id].classes.push(s); + }); + } + if (dir !== void 0) { + vertices[id].dir = dir; + } + if (vertices[id].props === void 0) { + vertices[id].props = props; + } else if (props !== void 0) { + Object.assign(vertices[id].props, props); + } +}; +const addSingleLink = function(_start, _end, type) { + let start = _start; + let end = _end; + const edge = { start, end, type: void 0, text: "", labelType: "text" }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc78 Got edge...", edge); + const linkTextObj = type.text; + if (linkTextObj !== void 0) { + edge.text = sanitizeText(linkTextObj.text.trim()); + if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') { + edge.text = edge.text.substring(1, edge.text.length - 1); + } + edge.labelType = linkTextObj.type; + } + if (type !== void 0) { + edge.type = type.type; + edge.stroke = type.stroke; + edge.length = type.length; + } + if ((edge == null ? void 0 : edge.length) > 10) { + edge.length = 10; + } + if (edges.length < (config.maxEdges ?? 500)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc78 pushing edge..."); + edges.push(edge); + } else { + throw new Error( + `Edge limit exceeded. ${edges.length} edges found, but the limit is ${config.maxEdges}. + +Initialize mermaid with maxEdges set to a higher number to allow more edges. +You cannot set this config via configuration inside the diagram as it is a secure config. +You have to call mermaid.initialize.` + ); + } +}; +const addLink = function(_start, _end, type) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("addLink (abc78)", _start, _end, type); + let i, j; + for (i = 0; i < _start.length; i++) { + for (j = 0; j < _end.length; j++) { + addSingleLink(_start[i], _end[j], type); + } + } +}; +const updateLinkInterpolate = function(positions, interp) { + positions.forEach(function(pos) { + if (pos === "default") { + edges.defaultInterpolate = interp; + } else { + edges[pos].interpolate = interp; + } + }); +}; +const updateLink = function(positions, style) { + positions.forEach(function(pos) { + if (pos >= edges.length) { + throw new Error( + `The index ${pos} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${edges.length - 1}. (Help: Ensure that the index is within the range of existing edges.)` + ); + } + if (pos === "default") { + edges.defaultStyle = style; + } else { + if (_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.isSubstringInArray("fill", style) === -1) { + style.push("fill:none"); + } + edges[pos].style = style; + } + }); +}; +const addClass = function(ids, style) { + ids.split(",").forEach(function(id) { + if (classes[id] === void 0) { + classes[id] = { id, styles: [], textStyles: [] }; + } + if (style !== void 0 && style !== null) { + style.forEach(function(s) { + if (s.match("color")) { + const newStyle = s.replace("fill", "bgFill").replace("color", "fill"); + classes[id].textStyles.push(newStyle); + } + classes[id].styles.push(s); + }); + } + }); +}; +const setDirection = function(dir) { + direction = dir; + if (direction.match(/.*/)) { + direction = "LR"; + } + if (direction.match(/.*v/)) { + direction = "TB"; + } + if (direction === "TD") { + direction = "TB"; + } +}; +const setClass = function(ids, className) { + ids.split(",").forEach(function(_id) { + let id = _id; + if (vertices[id] !== void 0) { + vertices[id].classes.push(className); + } + if (subGraphLookup[id] !== void 0) { + subGraphLookup[id].classes.push(className); + } + }); +}; +const setTooltip = function(ids, tooltip) { + ids.split(",").forEach(function(id) { + if (tooltip !== void 0) { + tooltips[version === "gen-1" ? lookUpDomId(id) : id] = sanitizeText(tooltip); + } + }); +}; +const setClickFun = function(id, functionName, functionArgs) { + let domId = lookUpDomId(id); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel !== "loose") { + return; + } + if (functionName === void 0) { + return; + } + let argList = []; + if (typeof functionArgs === "string") { + argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); + for (let i = 0; i < argList.length; i++) { + let item = argList[i].trim(); + if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') { + item = item.substr(1, item.length - 2); + } + argList[i] = item; + } + } + if (argList.length === 0) { + argList.push(id); + } + if (vertices[id] !== void 0) { + vertices[id].haveCallback = true; + funs.push(function() { + const elem = document.querySelector(`[id="${domId}"]`); + if (elem !== null) { + elem.addEventListener( + "click", + function() { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.runFunc(functionName, ...argList); + }, + false + ); + } + }); + } +}; +const setLink = function(ids, linkStr, target) { + ids.split(",").forEach(function(id) { + if (vertices[id] !== void 0) { + vertices[id].link = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.formatUrl(linkStr, config); + vertices[id].linkTarget = target; + } + }); + setClass(ids, "clickable"); +}; +const getTooltip = function(id) { + if (tooltips.hasOwnProperty(id)) { + return tooltips[id]; + } + return void 0; +}; +const setClickEvent = function(ids, functionName, functionArgs) { + ids.split(",").forEach(function(id) { + setClickFun(id, functionName, functionArgs); + }); + setClass(ids, "clickable"); +}; +const bindFunctions = function(element) { + funs.forEach(function(fun) { + fun(element); + }); +}; +const getDirection = function() { + return direction.trim(); +}; +const getVertices = function() { + return vertices; +}; +const getEdges = function() { + return edges; +}; +const getClasses = function() { + return classes; +}; +const setupToolTips = function(element) { + let tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(".mermaidTooltip"); + if ((tooltipElem._groups || tooltipElem)[0][0] === null) { + tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body").append("div").attr("class", "mermaidTooltip").style("opacity", 0); + } + const svg = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(element).select("svg"); + const nodes = svg.selectAll("g.node"); + nodes.on("mouseover", function() { + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(this); + const title = el.attr("title"); + if (title === null) { + return; + } + const rect = this.getBoundingClientRect(); + tooltipElem.transition().duration(200).style("opacity", ".9"); + tooltipElem.text(el.attr("title")).style("left", window.scrollX + rect.left + (rect.right - rect.left) / 2 + "px").style("top", window.scrollY + rect.bottom + "px"); + tooltipElem.html(tooltipElem.html().replace(/<br\/>/g, "
")); + el.classed("hover", true); + }).on("mouseout", function() { + tooltipElem.transition().duration(500).style("opacity", 0); + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(this); + el.classed("hover", false); + }); +}; +funs.push(setupToolTips); +const clear = function(ver = "gen-1") { + vertices = {}; + classes = {}; + edges = []; + funs = [setupToolTips]; + subGraphs = []; + subGraphLookup = {}; + subCount = 0; + tooltips = {}; + firstGraphFlag = true; + version = ver; + config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.v)(); +}; +const setGen = (ver) => { + version = ver || "gen-2"; +}; +const defaultStyle = function() { + return "fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"; +}; +const addSubGraph = function(_id, list, _title) { + let id = _id.text.trim(); + let title = _title.text; + if (_id === _title && _title.text.match(/\s/)) { + id = void 0; + } + function uniq(a) { + const prims = { boolean: {}, number: {}, string: {} }; + const objs = []; + let dir2; + const nodeList2 = a.filter(function(item) { + const type = typeof item; + if (item.stmt && item.stmt === "dir") { + dir2 = item.value; + return false; + } + if (item.trim() === "") { + return false; + } + if (type in prims) { + return prims[type].hasOwnProperty(item) ? false : prims[type][item] = true; + } else { + return objs.includes(item) ? false : objs.push(item); + } + }); + return { nodeList: nodeList2, dir: dir2 }; + } + let nodeList = []; + const { nodeList: nl, dir } = uniq(nodeList.concat.apply(nodeList, list)); + nodeList = nl; + if (version === "gen-1") { + for (let i = 0; i < nodeList.length; i++) { + nodeList[i] = lookUpDomId(nodeList[i]); + } + } + id = id || "subGraph" + subCount; + title = title || ""; + title = sanitizeText(title); + subCount = subCount + 1; + const subGraph = { + id, + nodes: nodeList, + title: title.trim(), + classes: [], + dir, + labelType: _title.type + }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Adding", subGraph.id, subGraph.nodes, subGraph.dir); + subGraph.nodes = makeUniq(subGraph, subGraphs).nodes; + subGraphs.push(subGraph); + subGraphLookup[id] = subGraph; + return id; +}; +const getPosForId = function(id) { + for (const [i, subGraph] of subGraphs.entries()) { + if (subGraph.id === id) { + return i; + } + } + return -1; +}; +let secCount = -1; +const posCrossRef = []; +const indexNodes2 = function(id, pos) { + const nodes = subGraphs[pos].nodes; + secCount = secCount + 1; + if (secCount > 2e3) { + return; + } + posCrossRef[secCount] = pos; + if (subGraphs[pos].id === id) { + return { + result: true, + count: 0 + }; + } + let count = 0; + let posCount = 1; + while (count < nodes.length) { + const childPos = getPosForId(nodes[count]); + if (childPos >= 0) { + const res = indexNodes2(id, childPos); + if (res.result) { + return { + result: true, + count: posCount + res.count + }; + } else { + posCount = posCount + res.count; + } + } + count = count + 1; + } + return { + result: false, + count: posCount + }; +}; +const getDepthFirstPos = function(pos) { + return posCrossRef[pos]; +}; +const indexNodes = function() { + secCount = -1; + if (subGraphs.length > 0) { + indexNodes2("none", subGraphs.length - 1); + } +}; +const getSubGraphs = function() { + return subGraphs; +}; +const firstGraph = () => { + if (firstGraphFlag) { + firstGraphFlag = false; + return true; + } + return false; +}; +const destructStartLink = (_str) => { + let str = _str.trim(); + let type = "arrow_open"; + switch (str[0]) { + case "<": + type = "arrow_point"; + str = str.slice(1); + break; + case "x": + type = "arrow_cross"; + str = str.slice(1); + break; + case "o": + type = "arrow_circle"; + str = str.slice(1); + break; + } + let stroke = "normal"; + if (str.includes("=")) { + stroke = "thick"; + } + if (str.includes(".")) { + stroke = "dotted"; + } + return { type, stroke }; +}; +const countChar = (char, str) => { + const length = str.length; + let count = 0; + for (let i = 0; i < length; ++i) { + if (str[i] === char) { + ++count; + } + } + return count; +}; +const destructEndLink = (_str) => { + const str = _str.trim(); + let line = str.slice(0, -1); + let type = "arrow_open"; + switch (str.slice(-1)) { + case "x": + type = "arrow_cross"; + if (str[0] === "x") { + type = "double_" + type; + line = line.slice(1); + } + break; + case ">": + type = "arrow_point"; + if (str[0] === "<") { + type = "double_" + type; + line = line.slice(1); + } + break; + case "o": + type = "arrow_circle"; + if (str[0] === "o") { + type = "double_" + type; + line = line.slice(1); + } + break; + } + let stroke = "normal"; + let length = line.length - 1; + if (line[0] === "=") { + stroke = "thick"; + } + if (line[0] === "~") { + stroke = "invisible"; + } + let dots = countChar(".", line); + if (dots) { + stroke = "dotted"; + length = dots; + } + return { type, stroke, length }; +}; +const destructLink = (_str, _startStr) => { + const info = destructEndLink(_str); + let startInfo; + if (_startStr) { + startInfo = destructStartLink(_startStr); + if (startInfo.stroke !== info.stroke) { + return { type: "INVALID", stroke: "INVALID" }; + } + if (startInfo.type === "arrow_open") { + startInfo.type = info.type; + } else { + if (startInfo.type !== info.type) { + return { type: "INVALID", stroke: "INVALID" }; + } + startInfo.type = "double_" + startInfo.type; + } + if (startInfo.type === "double_arrow") { + startInfo.type = "double_arrow_point"; + } + startInfo.length = info.length; + return startInfo; + } + return info; +}; +const exists = (allSgs, _id) => { + let res = false; + allSgs.forEach((sg) => { + const pos = sg.nodes.indexOf(_id); + if (pos >= 0) { + res = true; + } + }); + return res; +}; +const makeUniq = (sg, allSubgraphs) => { + const res = []; + sg.nodes.forEach((_id, pos) => { + if (!exists(allSubgraphs, _id)) { + res.push(sg.nodes[pos]); + } + }); + return { nodes: res }; +}; +const lex = { + firstGraph +}; +const flowDb = { + defaultConfig: () => _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.K.flowchart, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.g, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.a, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.b, + addVertex, + lookUpDomId, + addLink, + updateLinkInterpolate, + updateLink, + addClass, + setDirection, + setClass, + setTooltip, + getTooltip, + setClickEvent, + setLink, + bindFunctions, + getDirection, + getVertices, + getEdges, + getClasses, + clear, + setGen, + defaultStyle, + addSubGraph, + getDepthFirstPos, + indexNodes, + getSubGraphs, + destructLink, + lex, + exists, + makeUniq, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.t +}; +const db = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + addClass, + addLink, + addSingleLink, + addSubGraph, + addVertex, + bindFunctions, + clear, + default: flowDb, + defaultStyle, + destructLink, + firstGraph, + getClasses, + getDepthFirstPos, + getDirection, + getEdges, + getSubGraphs, + getTooltip, + getVertices, + indexNodes, + lex, + lookUpDomId, + setClass, + setClickEvent, + setDirection, + setGen, + setLink, + updateLink, + updateLinkInterpolate +}, Symbol.toStringTag, { value: "Module" })); + + + +/***/ }), + +/***/ 22235: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _flowDb_4b19a42f_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(66216); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(28747); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(76257); +/* harmony import */ var elkjs_lib_elk_bundled_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62954); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(99418); + + + + + + + + + + + + + + + + +const findCommonAncestor = (id1, id2, treeData) => { + const { parentById } = treeData; + const visited = /* @__PURE__ */ new Set(); + let currentId = id1; + while (currentId) { + visited.add(currentId); + if (currentId === id2) { + return currentId; + } + currentId = parentById[currentId]; + } + currentId = id2; + while (currentId) { + if (visited.has(currentId)) { + return currentId; + } + currentId = parentById[currentId]; + } + return "root"; +}; +const elk = new elkjs_lib_elk_bundled_js__WEBPACK_IMPORTED_MODULE_1__(); +let portPos = {}; +const conf = {}; +let nodeDb = {}; +const addVertices = async function(vert, svgId, root, doc, diagObj, parentLookupDb, graph) { + const svg = root.select(`[id="${svgId}"]`); + const nodes = svg.insert("g").attr("class", "nodes"); + const keys = Object.keys(vert); + await Promise.all( + keys.map(async function(id) { + const vertex = vert[id]; + let classStr = "default"; + if (vertex.classes.length > 0) { + classStr = vertex.classes.join(" "); + } + classStr = classStr + " flowchart-label"; + const styles2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.k)(vertex.styles); + let vertexText = vertex.text !== void 0 ? vertex.text : vertex.id; + const labelData = { width: 0, height: 0 }; + const ports = [ + { + id: vertex.id + "-west", + layoutOptions: { + "port.side": "WEST" + } + }, + { + id: vertex.id + "-east", + layoutOptions: { + "port.side": "EAST" + } + }, + { + id: vertex.id + "-south", + layoutOptions: { + "port.side": "SOUTH" + } + }, + { + id: vertex.id + "-north", + layoutOptions: { + "port.side": "NORTH" + } + } + ]; + let radius = 0; + let _shape = ""; + let layoutOptions = {}; + switch (vertex.type) { + case "round": + radius = 5; + _shape = "rect"; + break; + case "square": + _shape = "rect"; + break; + case "diamond": + _shape = "question"; + layoutOptions = { + portConstraints: "FIXED_SIDE" + }; + break; + case "hexagon": + _shape = "hexagon"; + break; + case "odd": + _shape = "rect_left_inv_arrow"; + break; + case "lean_right": + _shape = "lean_right"; + break; + case "lean_left": + _shape = "lean_left"; + break; + case "trapezoid": + _shape = "trapezoid"; + break; + case "inv_trapezoid": + _shape = "inv_trapezoid"; + break; + case "odd_right": + _shape = "rect_left_inv_arrow"; + break; + case "circle": + _shape = "circle"; + break; + case "ellipse": + _shape = "ellipse"; + break; + case "stadium": + _shape = "stadium"; + break; + case "subroutine": + _shape = "subroutine"; + break; + case "cylinder": + _shape = "cylinder"; + break; + case "group": + _shape = "rect"; + break; + case "doublecircle": + _shape = "doublecircle"; + break; + default: + _shape = "rect"; + } + const node = { + labelStyle: styles2.labelStyle, + shape: _shape, + labelText: vertexText, + labelType: vertex.labelType, + rx: radius, + ry: radius, + class: classStr, + style: styles2.style, + id: vertex.id, + link: vertex.link, + linkTarget: vertex.linkTarget, + tooltip: diagObj.db.getTooltip(vertex.id) || "", + domId: diagObj.db.lookUpDomId(vertex.id), + haveCallback: vertex.haveCallback, + width: vertex.type === "group" ? 500 : void 0, + dir: vertex.dir, + type: vertex.type, + props: vertex.props, + padding: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.F)().flowchart.padding + }; + let boundingBox; + let nodeEl; + if (node.type !== "group") { + nodeEl = await (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.e)(nodes, node, vertex.dir); + boundingBox = nodeEl.node().getBBox(); + } else { + doc.createElementNS("http://www.w3.org/2000/svg", "text"); + const { shapeSvg, bbox } = await (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.l)(nodes, node, void 0, true); + labelData.width = bbox.width; + labelData.wrappingWidth = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.F)().flowchart.wrappingWidth; + labelData.height = bbox.height; + labelData.labelNode = shapeSvg.node(); + node.labelData = labelData; + } + const data = { + id: vertex.id, + ports: vertex.type === "diamond" ? ports : [], + // labelStyle: styles.labelStyle, + // shape: _shape, + layoutOptions, + labelText: vertexText, + labelData, + // labels: [{ text: vertexText }], + // rx: radius, + // ry: radius, + // class: classStr, + // style: styles.style, + // link: vertex.link, + // linkTarget: vertex.linkTarget, + // tooltip: diagObj.db.getTooltip(vertex.id) || '', + domId: diagObj.db.lookUpDomId(vertex.id), + // haveCallback: vertex.haveCallback, + width: boundingBox == null ? void 0 : boundingBox.width, + height: boundingBox == null ? void 0 : boundingBox.height, + // dir: vertex.dir, + type: vertex.type, + // props: vertex.props, + // padding: getConfig().flowchart.padding, + // boundingBox, + el: nodeEl, + parent: parentLookupDb.parentById[vertex.id] + }; + nodeDb[node.id] = data; + }) + ); + return graph; +}; +const getNextPosition = (position, edgeDirection, graphDirection) => { + const portPos2 = { + TB: { + in: { + north: "north" + }, + out: { + south: "west", + west: "east", + east: "south" + } + }, + LR: { + in: { + west: "west" + }, + out: { + east: "south", + south: "north", + north: "east" + } + }, + RL: { + in: { + east: "east" + }, + out: { + west: "north", + north: "south", + south: "west" + } + }, + BT: { + in: { + south: "south" + }, + out: { + north: "east", + east: "west", + west: "north" + } + } + }; + portPos2.TD = portPos2.TB; + return portPos2[graphDirection][edgeDirection][position]; +}; +const getNextPort = (node, edgeDirection, graphDirection) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("getNextPort", { node, edgeDirection, graphDirection }); + if (!portPos[node]) { + switch (graphDirection) { + case "TB": + case "TD": + portPos[node] = { + inPosition: "north", + outPosition: "south" + }; + break; + case "BT": + portPos[node] = { + inPosition: "south", + outPosition: "north" + }; + break; + case "RL": + portPos[node] = { + inPosition: "east", + outPosition: "west" + }; + break; + case "LR": + portPos[node] = { + inPosition: "west", + outPosition: "east" + }; + break; + } + } + const result = edgeDirection === "in" ? portPos[node].inPosition : portPos[node].outPosition; + if (edgeDirection === "in") { + portPos[node].inPosition = getNextPosition( + portPos[node].inPosition, + edgeDirection, + graphDirection + ); + } else { + portPos[node].outPosition = getNextPosition( + portPos[node].outPosition, + edgeDirection, + graphDirection + ); + } + return result; +}; +const getEdgeStartEndPoint = (edge, dir) => { + let source = edge.start; + let target = edge.end; + const sourceId = source; + const targetId = target; + const startNode = nodeDb[source]; + const endNode = nodeDb[target]; + if (!startNode || !endNode) { + return { source, target }; + } + if (startNode.type === "diamond") { + source = `${source}-${getNextPort(source, "out", dir)}`; + } + if (endNode.type === "diamond") { + target = `${target}-${getNextPort(target, "in", dir)}`; + } + return { source, target, sourceId, targetId }; +}; +const addEdges = function(edges, diagObj, graph, svg) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("abc78 edges = ", edges); + const labelsEl = svg.insert("g").attr("class", "edgeLabels"); + let linkIdCnt = {}; + let dir = diagObj.db.getDirection(); + let defaultStyle; + let defaultLabelStyle; + if (edges.defaultStyle !== void 0) { + const defaultStyles = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.k)(edges.defaultStyle); + defaultStyle = defaultStyles.style; + defaultLabelStyle = defaultStyles.labelStyle; + } + edges.forEach(function(edge) { + const linkIdBase = "L-" + edge.start + "-" + edge.end; + if (linkIdCnt[linkIdBase] === void 0) { + linkIdCnt[linkIdBase] = 0; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); + } else { + linkIdCnt[linkIdBase]++; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); + } + let linkId = linkIdBase + "-" + linkIdCnt[linkIdBase]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("abc78 new link id to be used is", linkIdBase, linkId, linkIdCnt[linkIdBase]); + const linkNameStart = "LS-" + edge.start; + const linkNameEnd = "LE-" + edge.end; + const edgeData = { style: "", labelStyle: "" }; + edgeData.minlen = edge.length || 1; + if (edge.type === "arrow_open") { + edgeData.arrowhead = "none"; + } else { + edgeData.arrowhead = "normal"; + } + edgeData.arrowTypeStart = "arrow_open"; + edgeData.arrowTypeEnd = "arrow_open"; + switch (edge.type) { + case "double_arrow_cross": + edgeData.arrowTypeStart = "arrow_cross"; + case "arrow_cross": + edgeData.arrowTypeEnd = "arrow_cross"; + break; + case "double_arrow_point": + edgeData.arrowTypeStart = "arrow_point"; + case "arrow_point": + edgeData.arrowTypeEnd = "arrow_point"; + break; + case "double_arrow_circle": + edgeData.arrowTypeStart = "arrow_circle"; + case "arrow_circle": + edgeData.arrowTypeEnd = "arrow_circle"; + break; + } + let style = ""; + let labelStyle = ""; + switch (edge.stroke) { + case "normal": + style = "fill:none;"; + if (defaultStyle !== void 0) { + style = defaultStyle; + } + if (defaultLabelStyle !== void 0) { + labelStyle = defaultLabelStyle; + } + edgeData.thickness = "normal"; + edgeData.pattern = "solid"; + break; + case "dotted": + edgeData.thickness = "normal"; + edgeData.pattern = "dotted"; + edgeData.style = "fill:none;stroke-width:2px;stroke-dasharray:3;"; + break; + case "thick": + edgeData.thickness = "thick"; + edgeData.pattern = "solid"; + edgeData.style = "stroke-width: 3.5px;fill:none;"; + break; + } + if (edge.style !== void 0) { + const styles2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.k)(edge.style); + style = styles2.style; + labelStyle = styles2.labelStyle; + } + edgeData.style = edgeData.style += style; + edgeData.labelStyle = edgeData.labelStyle += labelStyle; + if (edge.interpolate !== void 0) { + edgeData.curve = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.n)(edge.interpolate, d3__WEBPACK_IMPORTED_MODULE_0__/* .curveLinear */ .lUB); + } else if (edges.defaultInterpolate !== void 0) { + edgeData.curve = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.n)(edges.defaultInterpolate, d3__WEBPACK_IMPORTED_MODULE_0__/* .curveLinear */ .lUB); + } else { + edgeData.curve = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.n)(conf.curve, d3__WEBPACK_IMPORTED_MODULE_0__/* .curveLinear */ .lUB); + } + if (edge.text === void 0) { + if (edge.style !== void 0) { + edgeData.arrowheadStyle = "fill: #333"; + } + } else { + edgeData.arrowheadStyle = "fill: #333"; + edgeData.labelpos = "c"; + } + edgeData.labelType = edge.labelType; + edgeData.label = edge.text.replace(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.e.lineBreakRegex, "\n"); + if (edge.style === void 0) { + edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none;"; + } + edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:"); + edgeData.id = linkId; + edgeData.classes = "flowchart-link " + linkNameStart + " " + linkNameEnd; + const labelEl = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.f)(labelsEl, edgeData); + const { source, target, sourceId, targetId } = getEdgeStartEndPoint(edge, dir); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.debug("abc78 source and target", source, target); + graph.edges.push({ + id: "e" + edge.start + edge.end, + sources: [source], + targets: [target], + sourceId, + targetId, + labelEl, + labels: [ + { + width: edgeData.width, + height: edgeData.height, + orgWidth: edgeData.width, + orgHeight: edgeData.height, + text: edgeData.label, + layoutOptions: { + "edgeLabels.inline": "true", + "edgeLabels.placement": "CENTER" + } + } + ], + edgeData + }); + }); + return graph; +}; +const addMarkersToEdge = function(svgPath, edgeData, diagramType, arrowMarkerAbsolute, id) { + let url = ""; + if (arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.m)(svgPath, edgeData, url, id, diagramType); +}; +const getClasses = function(text, diagObj) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("Extracting classes"); + return diagObj.db.getClasses(); +}; +const addSubGraphs = function(db2) { + const parentLookupDb = { parentById: {}, childrenById: {} }; + const subgraphs = db2.getSubGraphs(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("Subgraphs - ", subgraphs); + subgraphs.forEach(function(subgraph) { + subgraph.nodes.forEach(function(node) { + parentLookupDb.parentById[node] = subgraph.id; + if (parentLookupDb.childrenById[subgraph.id] === void 0) { + parentLookupDb.childrenById[subgraph.id] = []; + } + parentLookupDb.childrenById[subgraph.id].push(node); + }); + }); + subgraphs.forEach(function(subgraph) { + ({ id: subgraph.id }); + if (parentLookupDb.parentById[subgraph.id] !== void 0) { + parentLookupDb.parentById[subgraph.id]; + } + }); + return parentLookupDb; +}; +const calcOffset = function(src, dest, parentLookupDb) { + const ancestor = findCommonAncestor(src, dest, parentLookupDb); + if (ancestor === void 0 || ancestor === "root") { + return { x: 0, y: 0 }; + } + const ancestorOffset = nodeDb[ancestor].offset; + return { x: ancestorOffset.posX, y: ancestorOffset.posY }; +}; +const insertEdge = function(edgesEl, edge, edgeData, diagObj, parentLookupDb, id) { + const offset = calcOffset(edge.sourceId, edge.targetId, parentLookupDb); + const src = edge.sections[0].startPoint; + const dest = edge.sections[0].endPoint; + const segments = edge.sections[0].bendPoints ? edge.sections[0].bendPoints : []; + const segPoints = segments.map((segment) => [segment.x + offset.x, segment.y + offset.y]); + const points = [ + [src.x + offset.x, src.y + offset.y], + ...segPoints, + [dest.x + offset.x, dest.y + offset.y] + ]; + const { x, y } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.k)(edge.edgeData); + const curve = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .n8j)().x(x).y(y).curve(d3__WEBPACK_IMPORTED_MODULE_0__/* .curveLinear */ .lUB); + const edgePath = edgesEl.insert("path").attr("d", curve(points)).attr("class", "path " + edgeData.classes).attr("fill", "none"); + const edgeG = edgesEl.insert("g").attr("class", "edgeLabel"); + const edgeWithLabel = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(edgeG.node().appendChild(edge.labelEl)); + const box = edgeWithLabel.node().firstChild.getBoundingClientRect(); + edgeWithLabel.attr("width", box.width); + edgeWithLabel.attr("height", box.height); + edgeG.attr( + "transform", + `translate(${edge.labels[0].x + offset.x}, ${edge.labels[0].y + offset.y})` + ); + addMarkersToEdge(edgePath, edgeData, diagObj.type, diagObj.arrowMarkerAbsolute, id); +}; +const insertChildren = (nodeArray, parentLookupDb) => { + nodeArray.forEach((node) => { + if (!node.children) { + node.children = []; + } + const childIds = parentLookupDb.childrenById[node.id]; + if (childIds) { + childIds.forEach((childId) => { + node.children.push(nodeDb[childId]); + }); + } + insertChildren(node.children, parentLookupDb); + }); +}; +const draw = async function(text, id, _version, diagObj) { + var _a; + diagObj.db.clear(); + nodeDb = {}; + portPos = {}; + diagObj.db.setGen("gen-2"); + diagObj.parser.parse(text); + const renderEl = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body").append("div").attr("style", "height:400px").attr("id", "cy"); + let graph = { + id: "root", + layoutOptions: { + "elk.hierarchyHandling": "INCLUDE_CHILDREN", + "org.eclipse.elk.padding": "[top=100, left=100, bottom=110, right=110]", + "elk.layered.spacing.edgeNodeBetweenLayers": "30", + // 'elk.layered.mergeEdges': 'true', + "elk.direction": "DOWN" + // 'elk.ports.sameLayerEdges': true, + // 'nodePlacement.strategy': 'SIMPLE', + }, + children: [], + edges: [] + }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("Drawing flowchart using v3 renderer", elk); + let dir = diagObj.db.getDirection(); + switch (dir) { + case "BT": + graph.layoutOptions["elk.direction"] = "UP"; + break; + case "TB": + graph.layoutOptions["elk.direction"] = "DOWN"; + break; + case "LR": + graph.layoutOptions["elk.direction"] = "RIGHT"; + break; + case "RL": + graph.layoutOptions["elk.direction"] = "LEFT"; + break; + } + const { securityLevel, flowchart: conf2 } = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.F)(); + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + const svg = root.select(`[id="${id}"]`); + const markers = ["point", "circle", "cross"]; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.a)(svg, markers, diagObj.type, id); + const vert = diagObj.db.getVertices(); + let subG; + const subGraphs = diagObj.db.getSubGraphs(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("Subgraphs - ", subGraphs); + for (let i = subGraphs.length - 1; i >= 0; i--) { + subG = subGraphs[i]; + diagObj.db.addVertex( + subG.id, + { text: subG.title, type: subG.labelType }, + "group", + void 0, + subG.classes, + subG.dir + ); + } + const subGraphsEl = svg.insert("g").attr("class", "subgraphs"); + const parentLookupDb = addSubGraphs(diagObj.db); + graph = await addVertices(vert, id, root, doc, diagObj, parentLookupDb, graph); + const edgesEl = svg.insert("g").attr("class", "edges edgePath"); + const edges = diagObj.db.getEdges(); + graph = addEdges(edges, diagObj, graph, svg); + const nodes = Object.keys(nodeDb); + nodes.forEach((nodeId) => { + const node = nodeDb[nodeId]; + if (!node.parent) { + graph.children.push(node); + } + if (parentLookupDb.childrenById[nodeId] !== void 0) { + node.labels = [ + { + text: node.labelText, + layoutOptions: { + "nodeLabels.placement": "[H_CENTER, V_TOP, INSIDE]" + }, + width: node.labelData.width, + height: node.labelData.height + // width: 100, + // height: 100, + } + ]; + delete node.x; + delete node.y; + delete node.width; + delete node.height; + } + }); + insertChildren(graph.children, parentLookupDb); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("after layout", JSON.stringify(graph, null, 2)); + const g = await elk.layout(graph); + drawNodes(0, 0, g.children, svg, subGraphsEl, diagObj, 0); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("after layout", g); + (_a = g.edges) == null ? void 0 : _a.map((edge) => { + insertEdge(edgesEl, edge, edge.edgeData, diagObj, parentLookupDb, id); + }); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.o)({}, svg, conf2.diagramPadding, conf2.useMaxWidth); + renderEl.remove(); +}; +const drawNodes = (relX, relY, nodeArray, svg, subgraphsEl, diagObj, depth) => { + nodeArray.forEach(function(node) { + if (node) { + nodeDb[node.id].offset = { + posX: node.x + relX, + posY: node.y + relY, + x: relX, + y: relY, + depth, + width: node.width, + height: node.height + }; + if (node.type === "group") { + const subgraphEl = subgraphsEl.insert("g").attr("class", "subgraph"); + subgraphEl.insert("rect").attr("class", "subgraph subgraph-lvl-" + depth % 5 + " node").attr("x", node.x + relX).attr("y", node.y + relY).attr("width", node.width).attr("height", node.height); + const label = subgraphEl.insert("g").attr("class", "label"); + const labelCentering = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.F)().flowchart.htmlLabels ? node.labelData.width / 2 : 0; + label.attr( + "transform", + `translate(${node.labels[0].x + relX + node.x + labelCentering}, ${node.labels[0].y + relY + node.y + 3})` + ); + label.node().appendChild(node.labelData.labelNode); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("Id (UGH)= ", node.type, node.labels); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.info("Id (UGH)= ", node.id); + node.el.attr( + "transform", + `translate(${node.x + relX + node.width / 2}, ${node.y + relY + node.height / 2})` + ); + } + } + }); + nodeArray.forEach(function(node) { + if (node && node.type === "group") { + drawNodes(relX + node.x, relY + node.y, node.children, svg, subgraphsEl, diagObj, depth + 1); + } + }); +}; +const renderer = { + getClasses, + draw +}; +const genSections = (options) => { + let sections = ""; + for (let i = 0; i < 5; i++) { + sections += ` + .subgraph-lvl-${i} { + fill: ${options[`surface${i}`]}; + stroke: ${options[`surfacePeer${i}`]}; + } + `; + } + return sections; +}; +const getStyles = (options) => `.label { + font-family: ${options.fontFamily}; + color: ${options.nodeTextColor || options.textColor}; + } + .cluster-label text { + fill: ${options.titleColor}; + } + .cluster-label span { + color: ${options.titleColor}; + } + + .label text,span { + fill: ${options.nodeTextColor || options.textColor}; + color: ${options.nodeTextColor || options.textColor}; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${options.arrowheadColor}; + } + + .edgePath .path { + stroke: ${options.lineColor}; + stroke-width: 2.0px; + } + + .flowchart-link { + stroke: ${options.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${options.edgeLabelBackground}; + rect { + opacity: 0.85; + background-color: ${options.edgeLabelBackground}; + fill: ${options.edgeLabelBackground}; + } + text-align: center; + } + + .cluster rect { + fill: ${options.clusterBkg}; + stroke: ${options.clusterBorder}; + stroke-width: 1px; + } + + .cluster text { + fill: ${options.titleColor}; + } + + .cluster span { + color: ${options.titleColor}; + } + /* .cluster div { + color: ${options.titleColor}; + } */ + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${options.fontFamily}; + font-size: 12px; + background: ${options.tertiaryColor}; + border: 1px solid ${options.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } + .subgraph { + stroke-width:2; + rx:3; + } + // .subgraph-lvl-1 { + // fill:#ccc; + // // stroke:black; + // } + + .flowchart-label text { + text-anchor: middle; + } + + ${genSections(options)} +`; +const styles = getStyles; +const diagram = { + db: _flowDb_4b19a42f_js__WEBPACK_IMPORTED_MODULE_7__.d, + renderer, + parser: _flowDb_4b19a42f_js__WEBPACK_IMPORTED_MODULE_7__.p, + styles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/23cd166f.73436cd0.js b/assets/js/23cd166f.73436cd0.js new file mode 100644 index 0000000000..eaec8f0a25 --- /dev/null +++ b/assets/js/23cd166f.73436cd0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1822],{95439:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var s=n(74848),r=n(28453);const c={},o="Create a new cluster",a={id:"container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster",title:"Create a new cluster",description:"On the management server (login with make ssh), create a directory (below the home of",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc/usage",slug:"/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Usage",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/"},next:{title:"Managing many clusters",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters"}},i={},l=[];function d(e){const t={code:"code",h1:"h1",p:"p",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"create-a-new-cluster",children:"Create a new cluster"}),"\n",(0,s.jsxs)(t.p,{children:["On the management server (login with ",(0,s.jsx)(t.code,{children:"make ssh"}),"), create a directory (below the home of\nthe standard ubuntu user) with the name of your cluster. Copy over ",(0,s.jsx)(t.code,{children:"clusterctl.yaml"})," from\n",(0,s.jsx)(t.code,{children:"~/cluster-defaults/"})," and edit it according to your needs. You can also copy over other\nfiles from ",(0,s.jsx)(t.code,{children:"~/cluster-defaults/"})," and adjust them, but this is only needed in exceptional\ncases.\nNow run ",(0,s.jsx)(t.code,{children:"create_cluster.sh "})]}),"\n",(0,s.jsxs)(t.p,{children:["This will copy all missing defaults from ",(0,s.jsx)(t.code,{children:"~/cluster-defaults/"})," into the directory with your\ncluster name and then ask cluster-api to create the cluster. The scripts also take\ncare of security groups, anti-affinity, node image registration (if needed) and\nof deploying CCM, CNI, CSI as well as optional services such as metrics or nginx-ingress\ncontroller."]}),"\n",(0,s.jsxs)(t.p,{children:["You can access the new cluster with ",(0,s.jsx)(t.code,{children:"kubectl --context clustername-admin@cluster"}),"\nor ",(0,s.jsx)(t.code,{children:"KUBECONFIG=~/clustername/clustername.yaml kubectl"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The management cluster is in context ",(0,s.jsx)(t.code,{children:"kind-kind"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["Note that you can always change ",(0,s.jsx)(t.code,{children:"clusterctl.yaml"})," and re-run ",(0,s.jsx)(t.code,{children:"create_cluster.sh"}),". The script is idempotent and running\nit multiple times with the unchanged input file will result in no changes to the cluster."]})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},c=s.createContext(r);function o(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/23d0e2bb.f150b016.js b/assets/js/23d0e2bb.f150b016.js new file mode 100644 index 0000000000..9bdcad82c4 --- /dev/null +++ b/assets/js/23d0e2bb.f150b016.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6323],{17202:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>d,metadata:()=>c,toc:()=>o});var n=s(74848),r=s(28453);const d={},a="scs-0114: Volume Type Standard",c={id:"iaas/scs-0114",title:"scs-0114: Volume Type Standard",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/iaas/scs-0114.md",sourceDirName:"iaas",slug:"/iaas/scs-0114",permalink:"/standards/iaas/scs-0114",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Security Groups Decision Record",permalink:"/standards/scs-0113-v1-security-groups-decision-record"},next:{title:"Volume Type Standard",permalink:"/standards/scs-0114-v1-volume-type-standard"}},i={},o=[];function l(e){const t={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"scs-0114-volume-type-standard",children:"scs-0114: Volume Type Standard"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0114-v1-volume-type-standard",children:"scs-0114-v1"})}),(0,n.jsx)(t.td,{children:"Standard"}),(0,n.jsx)(t.td,{children:"Draft"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>c});var n=s(96540);const r={},d=n.createContext(r);function a(e){const t=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(d.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/23e62f09.feb0beea.js b/assets/js/23e62f09.feb0beea.js new file mode 100644 index 0000000000..526f67a41d --- /dev/null +++ b/assets/js/23e62f09.feb0beea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8966],{9324:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var s=n(74848),i=n(28453);const r={},d="scs-0300: Requirements for SSO identity federation",a={id:"iam/scs-0300",title:"scs-0300: Requirements for SSO identity federation",description:"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign",source:"@site/standards/iam/scs-0300.md",sourceDirName:"iam",slug:"/iam/scs-0300",permalink:"/standards/iam/scs-0300",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"IAM Standards",permalink:"/standards/iam/"},next:{title:"Requirements for SSO identity federation",permalink:"/standards/scs-0300-v1-requirements-for-sso-identity-federation"}},o={},c=[];function l(e){const t={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"scs-0300-requirements-for-sso-identity-federation",children:"scs-0300: Requirements for SSO identity federation"}),"\n",(0,s.jsx)(t.p,{children:"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign\nCloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed\nexternally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard\nfocuses on delegating authentication to external identity providers and mapping users to roles within SCS for\nauthorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity\nProvider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible."}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Version"}),(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"State"}),(0,s.jsx)(t.th,{children:"stabilized"}),(0,s.jsx)(t.th,{children:"deprecated"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/standards/scs-0300-v1-requirements-for-sso-identity-federation",children:"scs-0300-v1"})}),(0,s.jsx)(t.td,{children:"Decision Record"}),(0,s.jsx)(t.td,{children:"Stable"}),(0,s.jsx)(t.td,{children:"2023-06-21"}),(0,s.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>d,x:()=>a});var s=n(96540);const i={},r=s.createContext(i);function d(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/247783bb.1565db2f.js b/assets/js/247783bb.1565db2f.js new file mode 100644 index 0000000000..0283de1fad --- /dev/null +++ b/assets/js/247783bb.1565db2f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5548],{61966:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/25cf6706.68184cdc.js b/assets/js/25cf6706.68184cdc.js new file mode 100644 index 0000000000..dd2c6ee97e --- /dev/null +++ b/assets/js/25cf6706.68184cdc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7104],{33166:(t,e,i)=>{i.r(e),i.d(e,{assets:()=>r,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var a=i(74848),n=i(28453);const o={sidebar_label:"Octavia"},c="Octavia",s={id:"iaas/guides/configuration-guide/openstack/octavia",title:"Octavia",description:"* Octavia admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/octavia.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/octavia",permalink:"/docs/iaas/guides/configuration-guide/openstack/octavia",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/octavia.md",tags:[],version:"current",frontMatter:{sidebar_label:"Octavia"},sidebar:"docs",previous:{title:"Nova",permalink:"/docs/iaas/guides/configuration-guide/openstack/nova"},next:{title:"Placement",permalink:"/docs/iaas/guides/configuration-guide/openstack/placement"}},r={},d=[];function u(t){const e={a:"a",h1:"h1",li:"li",ul:"ul",...(0,n.R)(),...t.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.h1,{id:"octavia",children:"Octavia"}),"\n",(0,a.jsxs)(e.ul,{children:["\n",(0,a.jsx)(e.li,{children:(0,a.jsx)(e.a,{href:"https://docs.openstack.org/octavia/latest/admin/index.html",children:"Octavia admin guide"})}),"\n",(0,a.jsx)(e.li,{children:(0,a.jsx)(e.a,{href:"https://docs.openstack.org/octavia/latest/configuration/index.html",children:"Octavia configuration guide"})}),"\n",(0,a.jsx)(e.li,{children:(0,a.jsx)(e.a,{href:"https://docs.openstack.org/octavia/latest/configuration/configref.html",children:"Octavia configuration reference"})}),"\n"]})]})}function l(t={}){const{wrapper:e}={...(0,n.R)(),...t.components};return e?(0,a.jsx)(e,{...t,children:(0,a.jsx)(u,{...t})}):u(t)}},28453:(t,e,i)=>{i.d(e,{R:()=>c,x:()=>s});var a=i(96540);const n={},o=a.createContext(n);function c(t){const e=a.useContext(o);return a.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(n):t.components||n:c(t.components),a.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/26bc5a46.0e03375d.js b/assets/js/26bc5a46.0e03375d.js new file mode 100644 index 0000000000..beccfbcef3 --- /dev/null +++ b/assets/js/26bc5a46.0e03375d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2914],{28114:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>l,frontMatter:()=>o,metadata:()=>c,toc:()=>i});var a=r(74848),t=r(28453);const o={sidebar_label:"Docker",sidebar_position:20},s="Docker",c={id:"iaas/guides/upgrade-guide/docker",title:"Docker",description:"The Docker version used is defined via the parameter docker_version in the file",source:"@site/docs/02-iaas/guides/upgrade-guide/docker.md",sourceDirName:"02-iaas/guides/upgrade-guide",slug:"/iaas/guides/upgrade-guide/docker",permalink:"/docs/iaas/guides/upgrade-guide/docker",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/docker.md",tags:[],version:"current",sidebarPosition:20,frontMatter:{sidebar_label:"Docker",sidebar_position:20},sidebar:"docs",previous:{title:"Ceph",permalink:"/docs/iaas/guides/upgrade-guide/ceph"},next:{title:"Infrastructure",permalink:"/docs/iaas/guides/upgrade-guide/infrastructure"}},d={},i=[{value:"Restart behaviour",id:"restart-behaviour",level:2}];function u(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h1,{id:"docker",children:"Docker"}),"\n",(0,a.jsxs)(n.p,{children:["The Docker version used is defined via the parameter ",(0,a.jsx)(n.code,{children:"docker_version"})," in the file\n",(0,a.jsx)(n.code,{children:"environments/configuration.yml"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"docker_version: '5:20.10.24'\n"})}),"\n",(0,a.jsxs)(n.p,{children:["All installable versions can be displayed with ",(0,a.jsx)(n.code,{children:"apt-cache madison docker-ce"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"$ apt-cache madison docker-ce\n docker-ce | 5:24.0.6-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:24.0.5-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:24.0.4-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:24.0.3-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:24.0.2-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:24.0.1-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:24.0.0-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.6-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.5-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.4-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.3-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.2-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.1-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:23.0.0-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.24~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.23~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.22~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.21~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.20~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.19~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.18~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.17~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.16~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.15~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.14~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n docker-ce | 5:20.10.13~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages\n"})}),"\n",(0,a.jsxs)(n.p,{children:["If, for example, you want to change the Docker version from ",(0,a.jsx)(n.code,{children:"20.10.24"})," to ",(0,a.jsx)(n.code,{children:"24.0.6"}),", ",(0,a.jsx)(n.code,{children:"docker_version"})," in\n",(0,a.jsx)(n.code,{children:"environments/configuration.yml"})," is changed accordingly. The ",(0,a.jsx)(n.code,{children:"5:"})," prefix is placed in front of the version. Commit and push the changes to your configuration repository afterwards."]}),"\n",(0,a.jsx)(n.p,{children:"The upgrade of Docker is then done with the OSISM CLI. Docker on the manager itself is updated differently.\nThis does not work on the manager itself because the Docker service may be started during the upgrade and\nindividual containers may be started as a result. This would interrupt the run of the role itself."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply docker -l 'docker:!manager'\n"})}),"\n",(0,a.jsxs)(n.p,{children:["By default, ",(0,a.jsx)(n.code,{children:"serial"})," is set to ",(0,a.jsx)(n.code,{children:"1"})," so that the the hosts are upgrade one after the other.\nTo adjust this, either use the ",(0,a.jsx)(n.code,{children:"osism_serial"})," dictionary in the ",(0,a.jsx)(n.code,{children:"environments/configuration.yml"})," file\nto change the value in ",(0,a.jsx)(n.code,{children:"docker"})," or append ",(0,a.jsx)(n.code,{children:"-e serial=10%"})," to upgrade, for example, 10%\nwith each iteration."]}),"\n",(0,a.jsx)(n.p,{children:"Please note that it is not a good idea to upgrade more than one Docker service at a time.\nThis can lead to anomalies, especially on storage nodes and control nodes. It is recommended\nnot to change the default of 1."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"osism_serial:\n docker: 10%\n"})}),"\n",(0,a.jsxs)(n.p,{children:["On the manager itself, the ",(0,a.jsx)(n.code,{children:"run.sh"})," script in the manager environment of the configuration must\ncurrently be used to upgrade the Docker service. In a future release a dedicated ",(0,a.jsx)(n.code,{children:"osism update docker"}),"\ncommand will be available for this purpose."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"cd /opt/configuration/environments/manager\nANSIBLE_ASK_VAULT_PASS=True ./run.sh docker\n"})}),"\n",(0,a.jsx)(n.h2,{id:"restart-behaviour",children:"Restart behaviour"}),"\n",(0,a.jsxs)(n.p,{children:["When upgrading, the Docker service is restarted. As a result, it can come to a restart of the\nrunning containers. This can lead to interruptions in individual services. A change in\n",(0,a.jsx)(n.code,{children:"/etc/docker/daemon.json"})," due to a new configuration parameter etc. can also result in a\nrequired restart."]}),"\n",(0,a.jsxs)(n.p,{children:["Whether the containers are restarted when the Docker Service is restarted depends on whether the\n",(0,a.jsx)(n.a,{href:"https://docs.docker.com/config/containers/live-restore/",children:"Live Restore feature"})," is used.\nThis can be configured via the parameter ",(0,a.jsx)(n.code,{children:"docker_live_restore"}),". Live restore is enabled by default."]}),"\n",(0,a.jsxs)(n.p,{children:["It is important to set the ",(0,a.jsx)(n.code,{children:"docker_live_restore"})," parameter explicitly as a string. This means\n",(0,a.jsx)(n.code,{children:'docker_live_restore: "false"'})," or ",(0,a.jsx)(n.code,{children:'docker_live_restore: "true"'}),"."]}),"\n",(0,a.jsx)(n.p,{children:"But even if the Live Restore feature is enabled, certain upgrades will cause running containers\nto be restarted:"}),"\n",(0,a.jsxs)(n.blockquote,{children:["\n",(0,a.jsxs)(n.p,{children:["Live restore allows you to keep containers running across Docker daemon updates, but is only\nsupported when installing patch releases (",(0,a.jsx)(n.code,{children:"YY.MM.x"}),"), not for major (",(0,a.jsx)(n.code,{children:"YY.MM"}),") daemon upgrades."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"There are two ways to prevent a restart of the Docker service during an upgrade."}),"\n",(0,a.jsx)(n.p,{children:"If the restart behaviour of the Docker service is changed, always make sure to restart the\nDocker service manually afterwards (e.g. by a system reboot)."}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["A host group can be defined via the parameter ",(0,a.jsx)(n.code,{children:"docker_ignore_restart_groupname"}),". The\nrestart of the Docker service is not triggered for all hosts in this group. By default,\n",(0,a.jsx)(n.code,{children:"docker_ignore_restart_groupname"})," is set to ",(0,a.jsx)(n.code,{children:"manager"}),". The parameter is best set in the\n",(0,a.jsx)(n.code,{children:"environments/configuration.yml"})," file when making an adjustment. For example, to prevent\nthe restart on all hosts, ",(0,a.jsx)(n.code,{children:"docker_ignore_restart_groupname"})," is set to ",(0,a.jsx)(n.code,{children:"generic"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"docker_ignore_restart_groupname: generic\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["With the parameter ",(0,a.jsx)(n.code,{children:"docker_allow_restart"}),", the restart of the Docker service can be\nprevented. By default, ",(0,a.jsx)(n.code,{children:"docker_allow_restart"})," is set to ",(0,a.jsx)(n.code,{children:"true"}),". It is recommended to set\nthis parameter only at runtime. Otherwise, the best place for the parameter is the\n",(0,a.jsx)(n.code,{children:"environments/configuration.yml"})," file."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"osism apply docker -e docker_allow_restart=false\n"})}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>s,x:()=>c});var a=r(96540);const t={},o=a.createContext(t);function s(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/26dd306b.b508ea24.js b/assets/js/26dd306b.b508ea24.js new file mode 100644 index 0000000000..04ca6e7895 --- /dev/null +++ b/assets/js/26dd306b.b508ea24.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2342],{31219:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>l,frontMatter:()=>n,metadata:()=>d,toc:()=>u});var i=s(74848),o=s(28453);const n={sidebar_label:"Other Guides",sidebar_position:60},r="Other Guides",d={id:"iaas/guides/other-guides/index",title:"Other Guides",description:"",source:"@site/docs/02-iaas/guides/other-guides/index.md",sourceDirName:"02-iaas/guides/other-guides",slug:"/iaas/guides/other-guides/",permalink:"/docs/iaas/guides/other-guides/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/index.md",tags:[],version:"current",sidebarPosition:60,frontMatter:{sidebar_label:"Other Guides",sidebar_position:60},sidebar:"docs",previous:{title:"User Data Backups",permalink:"/docs/iaas/guides/user-guide/user-data-backups"},next:{title:"Cloud in a Box Guide",permalink:"/docs/iaas/guides/other-guides/cloud-in-a-box"}},a={},u=[];function c(e){const t={h1:"h1",...(0,o.R)(),...e.components};return(0,i.jsx)(t.h1,{id:"other-guides",children:"Other Guides"})}function l(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>d});var i=s(96540);const o={},n=i.createContext(o);function r(e){const t=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2746.313ca11d.js b/assets/js/2746.313ca11d.js new file mode 100644 index 0000000000..cb09ce5c73 --- /dev/null +++ b/assets/js/2746.313ca11d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2746],{14075:(e,t,n)=>{n.d(t,{M:()=>d});var r=n(69592),i=n(50053),a=n(74722);n(73046);function d(e){var t={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:o(e),edges:l(e)};return r.A(e.graph())||(t.value=i.A(e.graph())),t}function o(e){return a.A(e.nodes(),(function(t){var n=e.node(t),i=e.parent(t),a={v:t};return r.A(n)||(a.value=n),r.A(i)||(a.parent=i),a}))}function l(e){return a.A(e.edges(),(function(t){var n=e.edge(t),i={v:t.v,w:t.w};return r.A(t.name)||(i.name=t.name),r.A(n)||(i.value=n),i}))}},50053:(e,t,n)=>{n.d(t,{A:()=>i});var r=n(91641);const i=function(e){return(0,r.A)(e,4)}},92746:(e,t,n)=>{n.d(t,{r:()=>E});var r=n(21176),i=n(14075),a=n(28747),d=n(76257),o=n(697),l=n(45829),s=n(26312);let c={},h={},g={};const f=(e,t)=>(d.l.trace("In isDescendant",t," ",e," = ",h[t].includes(e)),!!h[t].includes(e)),u=(e,t,n,r)=>{d.l.warn("Copying children of ",e,"root",r,"data",t.node(e),r);const i=t.children(e)||[];e!==r&&i.push(e),d.l.warn("Copying (nodes) clusterId",e,"nodes",i),i.forEach((i=>{if(t.children(i).length>0)u(i,t,n,r);else{const a=t.node(i);d.l.info("cp ",i," to ",r," with parent ",e),n.setNode(i,a),r!==t.parent(i)&&(d.l.warn("Setting parent",i,t.parent(i)),n.setParent(i,t.parent(i))),e!==r&&i!==e?(d.l.debug("Setting parent",i,e),n.setParent(i,e)):(d.l.info("In copy ",e,"root",r,"data",t.node(e),r),d.l.debug("Not Setting parent for node=",i,"cluster!==rootId",e!==r,"node!==clusterId",i!==e));const o=t.edges(i);d.l.debug("Copying Edges",o),o.forEach((i=>{d.l.info("Edge",i);const a=t.edge(i.v,i.w,i.name);d.l.info("Edge data",a,r);try{((e,t)=>(d.l.info("Descendants of ",t," is ",h[t]),d.l.info("Edge is ",e),e.v!==t&&e.w!==t&&(h[t]?h[t].includes(e.v)||f(e.v,t)||f(e.w,t)||h[t].includes(e.w):(d.l.debug("Tilt, ",t,",not in descendants"),!1))))(i,r)?(d.l.info("Copying as ",i.v,i.w,a,i.name),n.setEdge(i.v,i.w,a,i.name),d.l.info("newGraph edges ",n.edges(),n.edge(n.edges()[0]))):d.l.info("Skipping copy of edge ",i.v,"--\x3e",i.w," rootId: ",r," clusterId:",e)}catch(o){d.l.error(o)}}))}d.l.debug("Removing node",i),t.removeNode(i)}))},w=(e,t)=>{const n=t.children(e);let r=[...n];for(const i of n)g[i]=e,r=[...r,...w(i,t)];return r},p=(e,t)=>{d.l.trace("Searching",e);const n=t.children(e);if(d.l.trace("Searching children of id ",e,n),n.length<1)return d.l.trace("This is a valid node",e),e;for(const r of n){const n=p(r,t);if(n)return d.l.trace("Found replacement for",e," => ",n),n}},v=e=>c[e]&&c[e].externalConnections&&c[e]?c[e].id:e,y=(e,t)=>{if(d.l.warn("extractor - ",t,i.M(e),e.children("D")),t>10)return void d.l.error("Bailing out");let n=e.nodes(),r=!1;for(const i of n){const t=e.children(i);r=r||t.length>0}if(r){d.l.debug("Nodes = ",n,t);for(const r of n)if(d.l.debug("Extracting node",r,c,c[r]&&!c[r].externalConnections,!e.parent(r),e.node(r),e.children("D")," Depth ",t),c[r])if(!c[r].externalConnections&&e.children(r)&&e.children(r).length>0){d.l.warn("Cluster without external connections, without a parent and with children",r,t);let n="TB"===e.graph().rankdir?"LR":"TB";c[r]&&c[r].clusterData&&c[r].clusterData.dir&&(n=c[r].clusterData.dir,d.l.warn("Fixing dir",c[r].clusterData.dir,n));const a=new o.T({multigraph:!0,compound:!0}).setGraph({rankdir:n,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));d.l.warn("Old graph before copy",i.M(e)),u(r,e,a,r),e.setNode(r,{clusterNode:!0,id:r,clusterData:c[r].clusterData,labelText:c[r].labelText,graph:a}),d.l.warn("New graph after copy node: (",r,")",i.M(a)),d.l.debug("Old graph after copy",i.M(e))}else d.l.warn("Cluster ** ",r," **not meeting the criteria !externalConnections:",!c[r].externalConnections," no parent: ",!e.parent(r)," children ",e.children(r)&&e.children(r).length>0,e.children("D"),t),d.l.debug(c);else d.l.debug("Not a cluster",r,t);n=e.nodes(),d.l.warn("New list of nodes",n);for(const r of n){const n=e.node(r);d.l.warn(" Now next level",r,n),n.clusterNode&&y(n.graph,t+1)}}else d.l.debug("Done, no node has children",e.nodes())},x=(e,t)=>{if(0===t.length)return[];let n=Object.assign(t);return t.forEach((t=>{const r=e.children(t),i=x(e,r);n=[...n,...i]})),n},m={rect:(e,t)=>{d.l.info("Creating subgraph rect for ",t.id,t);const n=(0,d.c)(),r=e.insert("g").attr("class","cluster"+(t.class?" "+t.class:"")).attr("id",t.id),i=r.insert("rect",":first-child"),o=(0,d.m)(n.flowchart.htmlLabels),c=r.insert("g").attr("class","cluster-label"),h="markdown"===t.labelType?(0,l.a)(c,t.labelText,{style:t.labelStyle,useHtmlLabels:o}):c.node().appendChild((0,a.c)(t.labelText,t.labelStyle,void 0,!0));let g=h.getBBox();if((0,d.m)(n.flowchart.htmlLabels)){const e=h.children[0],t=(0,s.Ltv)(h);g=e.getBoundingClientRect(),t.attr("width",g.width),t.attr("height",g.height)}const f=0*t.padding,u=f/2,w=t.width<=g.width+f?g.width+f:t.width;t.width<=g.width+f?t.diff=(g.width-t.width)/2-t.padding/2:t.diff=-t.padding/2,d.l.trace("Data ",t,JSON.stringify(t)),i.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-w/2).attr("y",t.y-t.height/2-u).attr("width",w).attr("height",t.height+f);const{subGraphTitleTopMargin:p}=(0,a.g)(n);o?c.attr("transform",`translate(${t.x-g.width/2}, ${t.y-t.height/2+p})`):c.attr("transform",`translate(${t.x}, ${t.y-t.height/2+p})`);const v=i.node().getBBox();return t.width=v.width,t.height=v.height,t.intersect=function(e){return(0,a.i)(t,e)},r},roundedWithTitle:(e,t)=>{const n=(0,d.c)(),r=e.insert("g").attr("class",t.classes).attr("id",t.id),i=r.insert("rect",":first-child"),o=r.insert("g").attr("class","cluster-label"),l=r.append("rect"),c=o.node().appendChild((0,a.c)(t.labelText,t.labelStyle,void 0,!0));let h=c.getBBox();if((0,d.m)(n.flowchart.htmlLabels)){const e=c.children[0],t=(0,s.Ltv)(c);h=e.getBoundingClientRect(),t.attr("width",h.width),t.attr("height",h.height)}h=c.getBBox();const g=0*t.padding,f=g/2,u=t.width<=h.width+t.padding?h.width+t.padding:t.width;t.width<=h.width+t.padding?t.diff=(h.width+0*t.padding-t.width)/2:t.diff=-t.padding/2,i.attr("class","outer").attr("x",t.x-u/2-f).attr("y",t.y-t.height/2-f).attr("width",u+g).attr("height",t.height+g),l.attr("class","inner").attr("x",t.x-u/2-f).attr("y",t.y-t.height/2-f+h.height-1).attr("width",u+g).attr("height",t.height+g-h.height-3);const{subGraphTitleTopMargin:w}=(0,a.g)(n);o.attr("transform",`translate(${t.x-h.width/2}, ${t.y-t.height/2-t.padding/3+((0,d.m)(n.flowchart.htmlLabels)?5:3)+w})`);const p=i.node().getBBox();return t.height=p.height,t.intersect=function(e){return(0,a.i)(t,e)},r},noteGroup:(e,t)=>{const n=e.insert("g").attr("class","note-cluster").attr("id",t.id),r=n.insert("rect",":first-child"),i=0*t.padding,d=i/2;r.attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-t.width/2-d).attr("y",t.y-t.height/2-d).attr("width",t.width+i).attr("height",t.height+i).attr("fill","none");const o=r.node().getBBox();return t.width=o.width,t.height=o.height,t.intersect=function(e){return(0,a.i)(t,e)},n},divider:(e,t)=>{const n=e.insert("g").attr("class",t.classes).attr("id",t.id),r=n.insert("rect",":first-child"),i=0*t.padding,d=i/2;r.attr("class","divider").attr("x",t.x-t.width/2-d).attr("y",t.y-t.height/2).attr("width",t.width+i).attr("height",t.height+i);const o=r.node().getBBox();return t.width=o.width,t.height=o.height,t.diff=-t.padding/2,t.intersect=function(e){return(0,a.i)(t,e)},n}};let b={};const C=async(e,t,n,o,l,s)=>{d.l.info("Graph in recursive render: XXX",i.M(t),l);const h=t.graph().rankdir;d.l.trace("Dir in recursive render - dir:",h);const g=e.insert("g").attr("class","root");t.nodes()?d.l.info("Recursive render XXX",t.nodes()):d.l.info("No nodes found for",t),t.edges().length>0&&d.l.trace("Recursive edges",t.edge(t.edges()[0]));const f=g.insert("g").attr("class","clusters"),u=g.insert("g").attr("class","edgePaths"),w=g.insert("g").attr("class","edgeLabels"),v=g.insert("g").attr("class","nodes");await Promise.all(t.nodes().map((async function(e){const r=t.node(e);if(void 0!==l){const n=JSON.parse(JSON.stringify(l.clusterData));d.l.info("Setting data for cluster XXX (",e,") ",n,l),t.setNode(l.id,n),t.parent(e)||(d.l.trace("Setting parent",e,l.id),t.setParent(e,l.id,n))}if(d.l.info("(Insert) Node XXX"+e+": "+JSON.stringify(t.node(e))),r&&r.clusterNode){d.l.info("Cluster identified",e,r.width,t.node(e));const i=await C(v,r.graph,n,o,t.node(e),s),l=i.elem;(0,a.u)(r,l),r.diff=i.diff||0,d.l.info("Node bounds (abc123)",e,r,r.width,r.x,r.y),(0,a.s)(l,r),d.l.warn("Recursive render complete ",l,r)}else t.children(e).length>0?(d.l.info("Cluster - the non recursive path XXX",e,r.id,r,t),d.l.info(p(r.id,t)),c[r.id]={id:p(r.id,t),node:r}):(d.l.info("Node - the non recursive path",e,r.id,r),await(0,a.e)(v,t.node(e),h))}))),t.edges().forEach((function(e){const n=t.edge(e.v,e.w,e.name);d.l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e)),d.l.info("Edge "+e.v+" -> "+e.w+": ",e," ",JSON.stringify(t.edge(e))),d.l.info("Fix",c,"ids:",e.v,e.w,"Translating: ",c[e.v],c[e.w]),(0,a.f)(w,n)})),t.edges().forEach((function(e){d.l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e))})),d.l.info("#############################################"),d.l.info("### Layout ###"),d.l.info("#############################################"),d.l.info(t),(0,r.Zp)(t),d.l.info("Graph after layout:",i.M(t));let y=0;const{subGraphTitleTotalMargin:E}=(0,a.g)(s);return(e=>x(e,e.children()))(t).forEach((function(e){const n=t.node(e);d.l.info("Position "+e+": "+JSON.stringify(t.node(e))),d.l.info("Position "+e+": ("+n.x,","+n.y,") width: ",n.width," height: ",n.height),n&&n.clusterNode?(n.y+=E,(0,a.p)(n)):t.children(e).length>0?(n.height+=E,((e,t)=>{d.l.trace("Inserting cluster");const n=t.shape||"rect";b[t.id]=m[n](e,t)})(f,n),c[n.id].node=n):(n.y+=E/2,(0,a.p)(n))})),t.edges().forEach((function(e){const r=t.edge(e);d.l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(r),r),r.points.forEach((e=>e.y+=E/2));const i=(0,a.h)(u,e,r,c,n,t,o);(0,a.j)(r,i)})),t.nodes().forEach((function(e){const n=t.node(e);d.l.info(e,n.type,n.diff),"group"===n.type&&(y=n.diff)})),{elem:g,diff:y}},E=async(e,t,n,r,o)=>{(0,a.a)(e,n,r,o),(0,a.b)(),(0,a.d)(),b={},h={},g={},c={},d.l.warn("Graph at first:",JSON.stringify(i.M(t))),((e,t)=>{if(!e||t>10)d.l.debug("Opting out, no graph ");else{d.l.debug("Opting in, graph "),e.nodes().forEach((function(t){e.children(t).length>0&&(d.l.warn("Cluster identified",t," Replacement id in edges: ",p(t,e)),h[t]=w(t,e),c[t]={id:p(t,e),clusterData:e.node(t)})})),e.nodes().forEach((function(t){const n=e.children(t),r=e.edges();n.length>0?(d.l.debug("Cluster identified",t,h),r.forEach((e=>{e.v!==t&&e.w!==t&&f(e.v,t)^f(e.w,t)&&(d.l.warn("Edge: ",e," leaves cluster ",t),d.l.warn("Descendants of XXX ",t,": ",h[t]),c[t].externalConnections=!0)}))):d.l.debug("Not a cluster ",t,h)}));for(let t of Object.keys(c)){const n=c[t].id,r=e.parent(n);r!==t&&c[r]&&!c[r].externalConnections&&(c[t].id=r)}e.edges().forEach((function(t){const n=e.edge(t);d.l.warn("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(t)),d.l.warn("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(e.edge(t)));let r=t.v,i=t.w;if(d.l.warn("Fix XXX",c,"ids:",t.v,t.w,"Translating: ",c[t.v]," --- ",c[t.w]),c[t.v]&&c[t.w]&&c[t.v]===c[t.w]){d.l.warn("Fixing and trixing link to self - removing XXX",t.v,t.w,t.name),d.l.warn("Fixing and trixing - removing XXX",t.v,t.w,t.name),r=v(t.v),i=v(t.w),e.removeEdge(t.v,t.w,t.name);const a=t.w+"---"+t.v;e.setNode(a,{domId:a,id:a,labelStyle:"",labelText:n.label,padding:0,shape:"labelRect",style:""});const o=structuredClone(n),l=structuredClone(n);o.label="",o.arrowTypeEnd="none",l.label="",o.fromCluster=t.v,l.toCluster=t.v,e.setEdge(r,a,o,t.name+"-cyclic-special"),e.setEdge(a,i,l,t.name+"-cyclic-special")}else if(c[t.v]||c[t.w]){if(d.l.warn("Fixing and trixing - removing XXX",t.v,t.w,t.name),r=v(t.v),i=v(t.w),e.removeEdge(t.v,t.w,t.name),r!==t.v){const i=e.parent(r);c[i].externalConnections=!0,n.fromCluster=t.v}if(i!==t.w){const r=e.parent(i);c[r].externalConnections=!0,n.toCluster=t.w}d.l.warn("Fix Replacing with XXX",r,i,t.name),e.setEdge(r,i,n,t.name)}})),d.l.warn("Adjusted Graph",i.M(e)),y(e,0),d.l.trace(c)}})(t),d.l.warn("Graph after:",JSON.stringify(i.M(t)));const l=(0,d.c)();await C(e,t,r,o,void 0,l)}}}]); \ No newline at end of file diff --git a/assets/js/27f24dfd.dd03ec43.js b/assets/js/27f24dfd.dd03ec43.js new file mode 100644 index 0000000000..4e78f9d178 --- /dev/null +++ b/assets/js/27f24dfd.dd03ec43.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4132],{12053:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var s=n(74848),i=n(28453);const o={title:"Kubernetes Node Distribution and Availability",type:"Standard",status:"Stable",stabilized_at:new Date("2024-02-08T00:00:00.000Z"),track:"KaaS"},r=void 0,a={id:"scs-0214-v1-k8s-node-distribution",title:"Kubernetes Node Distribution and Availability",description:"Introduction",source:"@site/standards/scs-0214-v1-k8s-node-distribution.md",sourceDirName:".",slug:"/scs-0214-v1-k8s-node-distribution",permalink:"/standards/scs-0214-v1-k8s-node-distribution",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Kubernetes Node Distribution and Availability",type:"Standard",status:"Stable",stabilized_at:"2024-02-08T00:00:00.000Z",track:"KaaS"},sidebar:"standards",previous:{title:"scs-0214: Kubernetes Node Distribution and Availability",permalink:"/standards/kaas/scs-0214"},next:{title:"scs-0215: Robustness features for Kubernetes clusters",permalink:"/standards/kaas/scs-0215"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Glossary",id:"glossary",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Decision",id:"decision",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(t.p,{children:"A Kubernetes instance is provided as a cluster, which consists of a set of machines,\nso-called nodes. A cluster is composed of a control plane and at least one worker node.\nThe control plane manages the worker nodes and therefore the pods in the cluster by making\ndecisions about scheduling, event detection and rights management. Inside the control plane,\nmultiple components exist, which can be duplicated and distributed over multiple nodes\ninside the cluster. Typically, no user workloads are run on these nodes in order to\nseparate the controller component from user workloads, which could pose a security risk."}),"\n",(0,s.jsx)(t.h3,{id:"glossary",children:"Glossary"}),"\n",(0,s.jsx)(t.p,{children:"The following terms are used throughout this document:"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Term"}),(0,s.jsx)(t.th,{children:"Meaning"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Worker"}),(0,s.jsx)(t.td,{children:"Virtual or bare-metal machine, which hosts workloads of customers"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Control Plane"}),(0,s.jsx)(t.td,{children:"Virtual or bare-metal machine, which hosts the container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Machine"}),(0,s.jsx)(t.td,{children:"Virtual or bare-metal entity with computational capabilities"})]})]})]}),"\n",(0,s.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(t.p,{children:'In normal day-to-day operation, it is not unusual for some operational failures, either\ndue to wear and tear of hardware, software misconfigurations, external problems or\nuser errors. Whichever was the source of such an outage, it always means down-time for\noperations and users and possible even data loss.\nTherefore, a Kubernetes cluster in a productive environment should be distributed over\nmultiple "failure zones" in order to provide fault-tolerance and high availability.\nThis is especially important for the control plane of the cluster, since it contains the\nstate of the whole cluster. A failure of this component could mean an unrecoverable failure\nof the whole cluster.'}),"\n",(0,s.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,s.jsxs)(t.p,{children:["Most design considerations of this standard follow the previously written Decision Record\n",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0213-v1-k8s-nodes-anti-affinity.md",children:"Kubernetes Nodes Anti Affinity"})," as well as the Kubernetes documents about\n",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/",children:"High Availability"})," and ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/best-practices/cluster-large/",children:"Best practices for large clusters"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"SCS wishes to prefer distributed, highly-available systems due to their obvious advantages\nlike fault-tolerance and data redundancy. But it also understands the costs and overhead\nfor the providers associated with this effort, since the infrastructure needs to have\nhardware which will just be used to provide fail-over safety or duplication."}),"\n",(0,s.jsxs)(t.p,{children:["The document ",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/best-practices/cluster-large/",children:"Best practices for large clusters"})," describes the concept of a failure zone.\nThis term isn't defined any further, but can in this context be described as a number of\nphysical (computing) machines in such a vicinity to each other (either through physical\nor logical interconnection in some way), that specific problems inside this zone would put\nall these machines at risk of failure/shutdown. It is therefore necessary for important\ndata or services to not be present just on one failure zone.\nHow such a failure zone should be defined is dependent on the risk model of the service/data\nand its owner as well as the capabilities of the provider. Zones could be set from things\nlike single machines or racks up to whole datacenters or even regions, which could be\ncoupled by things like electrical grids. They're therefore purely logical entities, which\nshouldn't be defined further in this document."]}),"\n",(0,s.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsx)(t.p,{children:"This standard formulates the requirement for the distribution of Kubernetes nodes in order\nto provide a fault-tolerant and available Kubernetes cluster infrastructure.\nSince some providers only have small environments to work with and therefore couldn't\ncomply with this standard, it will be treated as a RECOMMENDED standard, where providers\ncan OPT OUT."}),"\n",(0,s.jsx)(t.p,{children:"If the standard is used by a provider, the following decisions are binding and valid:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"The control plane nodes MUST be distributed over multiple physical machines. Kubernetes\nprovides best-practices on this topic, which are also RECOMMENDED by SCS."}),"\n",(0,s.jsx)(t.li,{children:'At least one control plane instance MUST be run in each "failure zone", more are\nRECOMMENDED in each "failure zone" to provide fault-tolerance for each zone.'}),"\n",(0,s.jsx)(t.li,{children:'Worker nodes are RECOMMENDED to be distributed over multiple zones. This policy makes\nit OPTIONAL to provide a worker node in each "failure zone", meaning that worker nodes\ncan also be scaled vertically first before scaling horizontally.'}),"\n",(0,s.jsx)(t.li,{children:'Worker node distribution MUST be indicated to the user through some kind of labeling\nin order to enable (anti)-affinity for workloads over "failure zones".'}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The script ",(0,s.jsx)(t.code,{children:"k8s-node-distribution-check.py"})," checks the nodes available with a user-provided\nkubeconfig file. It then determines based on the labels ",(0,s.jsx)(t.code,{children:"kubernetes.io/hostname"}),", ",(0,s.jsx)(t.code,{children:"topology.kubernetes.io/zone"}),",\n",(0,s.jsx)(t.code,{children:"topology.kubernetes.io/region"})," and ",(0,s.jsx)(t.code,{children:"node-role.kubernetes.io/control-plane"}),", if a distribution\nof the available nodes is present. If this isn't the case, the script produces an error.\nIf also produces warnings and informational outputs, if e.g. labels don't seem to be set."]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var s=n(96540);const i={},o=s.createContext(i);function r(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/287cd167.bcb88876.js b/assets/js/287cd167.bcb88876.js new file mode 100644 index 0000000000..51627c2d64 --- /dev/null +++ b/assets/js/287cd167.bcb88876.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3043],{29239:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>u});var c=s(74848),n=s(28453);const o={},r="Quickstart",a={id:"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart",title:"Quickstart",description:"This document has been moved.",source:"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart.md",sourceDirName:"03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs",slug:"/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart",permalink:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Overview",permalink:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview"},next:{title:"Controllers",permalink:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers"}},i={},u=[];function p(t){const e={a:"a",h1:"h1",p:"p",...(0,n.R)(),...t.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.h1,{id:"quickstart",children:"Quickstart"}),"\n",(0,c.jsx)(e.p,{children:"This document has been moved."}),"\n",(0,c.jsxs)(e.p,{children:["You can find the current version of the quickstart guide ",(0,c.jsx)(e.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks/blob/main/providers/openstack/README.md",children:"here"}),"."]})]})}function d(t={}){const{wrapper:e}={...(0,n.R)(),...t.components};return e?(0,c.jsx)(e,{...t,children:(0,c.jsx)(p,{...t})}):p(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>r,x:()=>a});var c=s(96540);const n={},o=c.createContext(n);function r(t){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(n):t.components||n:r(t.components),c.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/2886628e.9895b216.js b/assets/js/2886628e.9895b216.js new file mode 100644 index 0000000000..4c53a094d6 --- /dev/null +++ b/assets/js/2886628e.9895b216.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7778],{88309:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>a});var n=o(74848),r=o(28453);const s={},i="Branch Protection Rules",c={id:"tools/github/branchprotection",title:"Branch Protection Rules",description:"To protect our source code from unwanted changes, we enforce the following branch protection rules for all repositories within our GitHub organization:",source:"@site/community/tools/github/branchprotection.md",sourceDirName:"tools/github",slug:"/tools/github/branchprotection",permalink:"/community/tools/github/branchprotection",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Zuul",permalink:"/community/tools/zuul"},next:{title:"Developer Certificate of Origin + Licenses",permalink:"/community/tools/github/dco-and-licenses"}},l={},a=[];function u(e){const t={a:"a",code:"code",h1:"h1",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"branch-protection-rules",children:"Branch Protection Rules"}),"\n",(0,n.jsxs)(t.p,{children:["To protect our source code from unwanted changes, we enforce the following branch protection rules for all repositories within our ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack",children:"GitHub organization"}),":"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Require a pull request before merging into our default branch ",(0,n.jsx)(t.code,{children:"main"}),".","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Require at least one approval before pull requests can be merged."}),"\n",(0,n.jsx)(t.li,{children:"Dismiss stale pull request approvals when new commits are pushed"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["Require status checks to pass before merging","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Require branches to be up to date before merging"}),"\n",(0,n.jsxs)(t.li,{children:["Status checks that are required:","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"/community/tools/github/dco-and-licenses",children:"DCO"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.li,{children:"Do not allow bypassing the above settings"}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["The branch protection rules are rolled out by our ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/github-manager",children:(0,n.jsx)(t.code,{children:"github-manager"})})," to ensure that all repositories use a consistent set of rules. Should you intend to propose changes to the above rules, please open a pull request against ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/github-manager/blob/main/orgs/SovereignCloudStack/data.yaml",children:(0,n.jsx)(t.code,{children:"orgs/SovereignCloudStack/data.yaml"})}),"."]}),"\n",(0,n.jsx)(t.p,{children:"Some repositories however do allow that the above rules are bypassed by the organization's owners, especially repositories that are used for public resources such as the website or the weekly digest."})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,o)=>{o.d(t,{R:()=>i,x:()=>c});var n=o(96540);const r={},s=n.createContext(r);function i(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/28d842ee.2fe1a43e.js b/assets/js/28d842ee.2fe1a43e.js new file mode 100644 index 0000000000..e1d0941054 --- /dev/null +++ b/assets/js/28d842ee.2fe1a43e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3405],{4368:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var t=n(74848),s=n(28453);const o={title:"SONiC Support in SCS",type:"Decision Record",status:"Draft",track:"Global",description:"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.\n"},r=void 0,a={id:"scs-0112-v1-sonic",title:"SONiC Support in SCS",description:"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.\n",source:"@site/standards/scs-0112-v1-sonic.md",sourceDirName:".",slug:"/scs-0112-v1-sonic",permalink:"/standards/scs-0112-v1-sonic",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SONiC Support in SCS",type:"Decision Record",status:"Draft",track:"Global",description:"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.\n"},sidebar:"standards",previous:{title:"scs-0112: SONiC Support in SCS",permalink:"/standards/global/scs-0112"},next:{title:"IaaS Standards",permalink:"/standards/iaas/"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"SONiC as a network OS where dynamic network configuration in Openstack is required",id:"sonic-as-a-network-os-where-dynamic-network-configuration-in-openstack-is-required",level:3},{value:"Automation and tooling for SONiC",id:"automation-and-tooling-for-sonic",level:3},{value:"OVN for SONiC",id:"ovn-for-sonic",level:3},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Option 1: SCS distribution of SONiC",id:"option-1-scs-distribution-of-sonic",level:4},{value:"Option 2: SCS will support SONiC but will not change it",id:"option-2-scs-will-support-sonic-but-will-not-change-it",level:4},{value:"Option 3: SCS develops SCS-specific modules as add-on for any SONiC (Community or Enterprise)",id:"option-3-scs-develops-scs-specific-modules-as-add-on-for-any-sonic-community-or-enterprise",level:4},{value:"Option 4: SCS does not adopt SONiC at all",id:"option-4-scs-does-not-adopt-sonic-at-all",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"State of SONiC community?",id:"state-of-sonic-community",level:3},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2}];function c(e){const i={a:"a",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsxs)(i.p,{children:["SONiC support in ",(0,t.jsx)(i.a,{href:"https://scs.community",children:"SCS"})," was considered within the context of ",(0,t.jsx)(i.a,{href:"https://scs.community/tenders/lot4",children:"VP04 Networking"}),", sub-lot 1 SDN scalability. Different challenges and approaches to SDN scalability have been explored and more specifically those who require support in the underlay network. Using SONiC in the underlay can have benefits for SCS users by using a standardized OS for network devices and also having a clear path for network scalability when using SONiC. For this to work, we have to define how SONiC is used and supported architecturally in SCS. This document outlines the architectural decisions in regards to SONiC support and integration in SCS."]}),"\n",(0,t.jsx)(i.h2,{id:"motivation",children:"Motivation"}),"\n",(0,t.jsx)(i.p,{children:"In respect to SDN scalability improvements in Openstack and SCS, there are several ways SONiC can be leveraged."}),"\n",(0,t.jsx)(i.h3,{id:"sonic-as-a-network-os-where-dynamic-network-configuration-in-openstack-is-required",children:"SONiC as a network OS where dynamic network configuration in Openstack is required"}),"\n",(0,t.jsx)(i.p,{children:"In many network designs for Openstack, configuration of the actual network hardware by Openstack Neutron service is required. The following network designs apply:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:["\n",(0,t.jsx)(i.p,{children:"VLANs. Uisng VLANs to segment tenant networks requires the network switch to be configured. This can be manual or dynamic configuration via the ML2 Neutron driver."}),"\n"]}),"\n",(0,t.jsxs)(i.li,{children:["\n",(0,t.jsx)(i.p,{children:"EVPN/VXLAN on the switch. In this use case, SONiC runs on leaf switches. Leafs terminate VXLAN endpoints and run BGP/EVPN for the control plane. Again, the ML2 Neutron driver is used to dynamically configure the network switch. The link between the switch and the service is regular VLAN."}),"\n"]}),"\n",(0,t.jsxs)(i.li,{children:["\n",(0,t.jsx)(i.p,{children:"VXLAN on servers and switches. This is a hybrid use case, where most of the SDN is pushed to the server, but the network is still involved where support for bare metal hosts is needed."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(i.h3,{id:"automation-and-tooling-for-sonic",children:"Automation and tooling for SONiC"}),"\n",(0,t.jsx)(i.p,{children:"There is no tooling in SCS or Openstack communities to facilitate the rollout and configuration of enterprise scale SONiC deployments. Netbox and OSISM can be integrated, so that Netbox becomes the source of truth for network configuration and OSISM supports the initial rollout and configuration for the switches."}),"\n",(0,t.jsx)(i.h3,{id:"ovn-for-sonic",children:"OVN for SONiC"}),"\n",(0,t.jsx)(i.p,{children:"OVN and OVS are extensively leveraged in Neutron to SDN. In large scale deployments, OVN can become a bottleneck by exhausting resources on network nodes. SONiC can host the OVN control plane as a module (container) and spare the resources in network nodes. There is however a potential other bottleneck on SONiC hardware, as OVN control plane can be resource intensive. This is a potential area for further investigation."}),"\n",(0,t.jsx)(i.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,t.jsx)(i.p,{children:"There are different ways SONiC support can be implemented in SCS, very similar to existing approaches with Linux."}),"\n",(0,t.jsx)(i.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,t.jsx)(i.h4,{id:"option-1-scs-distribution-of-sonic",children:"Option 1: SCS distribution of SONiC"}),"\n",(0,t.jsx)(i.p,{children:"With this approach, SCS will create it's own distribution of SONiC, similar to what Debian or Arch are for Linux. This distribution will be based on the SONiC community distribution, but will have SCS specific modules, which will be developed and maintained by SCS. SCS will contribute its code to dedicated SCS repositories and build its own SONiC images. The code can eventually be pushed upstream, but not as top priority. This approach will allow SCS to have a clear path for SONiC support and integration in SCS, but will also require SCS to maintain a distribution of SONiC, which is a significant effort. Upstream/downstream changes will have to be managed and maintained. However the advantage is that SCS will have full control over the distribution and can make changes as needed. Users will have to use the SCS distribution of SONiC, which will be based on the community distribution. If users already deploy community or enterprise SONiC, a migration path to SCS SONiC will be needed."}),"\n",(0,t.jsx)(i.h4,{id:"option-2-scs-will-support-sonic-but-will-not-change-it",children:"Option 2: SCS will support SONiC but will not change it"}),"\n",(0,t.jsx)(i.p,{children:"SCS supports enterprise ans community versions of SONiC but will not develop its own code for it. This will significantly limit the ability to develop new features for SDN, because all changes will be done in the tooling around SONiC and not in the OS itself. The advantages are that SCS will still improve SONiC support and will have minimal effort for this. The downside is that some features like OVN control plane for SONiC will not be possible."}),"\n",(0,t.jsx)(i.h4,{id:"option-3-scs-develops-scs-specific-modules-as-add-on-for-any-sonic-community-or-enterprise",children:"Option 3: SCS develops SCS-specific modules as add-on for any SONiC (Community or Enterprise)"}),"\n",(0,t.jsx)(i.p,{children:"In option 3, SCS will change SONiC by releasing its own modules for it. Those module can be provided as add-ons and installed on top of any version, community or enterprise. While compatability between the modules the SONiC releases will need to be maintained, there will be much broader support for SONiC and users will be able to pick and chose distributions based on their existing relationships and experience and use SCS independent of this. In cases where SCS provides contributions to core SONiC, those can be made in upstream Community repositories, so that the whole community including the propriatory vendors can adopt them eventually."}),"\n",(0,t.jsx)(i.h4,{id:"option-4-scs-does-not-adopt-sonic-at-all",children:"Option 4: SCS does not adopt SONiC at all"}),"\n",(0,t.jsx)(i.p,{children:"This option entails no dedicated effort on SCS's part in supporting SONiC network equipement for it's users and software stack. Users can still use SONiC from what is available by other projects or if they invest the effort themselves. This has several disadvantages:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"SCS is not contributing to the SONiC community"}),"\n",(0,t.jsx)(i.li,{children:"the value for SCS by users who already use or plan to invest in SONiC is diminished"}),"\n",(0,t.jsx)(i.li,{children:"users have less incentive to use community SONiC and switch to Enterprise SONiC"}),"\n",(0,t.jsx)(i.li,{children:"SCS will not be able to leverage SONiC for SDN scalability improvements"}),"\n"]}),"\n",(0,t.jsx)(i.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,t.jsx)(i.h3,{id:"state-of-sonic-community",children:"State of SONiC community?"}),"\n",(0,t.jsx)(i.p,{children:(0,t.jsx)(i.strong,{children:"community version: mature or not?"})}),"\n",(0,t.jsx)(i.p,{children:'Commits: between 40-52 per month. Contributors to master: 10-20. Mailing list: 6 lists, about 10-30 messages/month for list. Community version supports 25 hardware vendors. Requires significant time and resource investment and "Explorer\'s mindset".'}),"\n",(0,t.jsx)(i.p,{children:(0,t.jsx)(i.strong,{children:"enterprise version: mature or not?"})}),"\n",(0,t.jsx)(i.p,{children:"Multiple vendor distributions. Expensive in general"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"release schedule - how often are features and bugfixes released?"}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"New tags appears on different periods, once 2 times per month, other 3 months between releases."}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"adoption penetration - how many vendors use it? What type of venders (big, medium and large)?"}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"Good initial adoption: Microsoft, Target. Adoption requires time and money"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"Is SONiC being overtaken by alternatives: SmartNICs and DPUs? How relevant is it still and will be in the coming years?"}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"Actually not, because of different use cases."}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"Sustainability of community SONIC for 2025+"}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"The SONiC community is healthy and growing, however progress is slower due to factors like investment of resources. The barrier of entry is much higher than other similar OSS projects."}),"\n",(0,t.jsx)(i.h2,{id:"decision",children:"Decision"}),"\n",(0,t.jsx)(i.p,{children:"IaaS team recommends to use Option 3: SCS develops SCS-specific modules as add-on for any SONiC (Community or Enterprise). It has the best tradeoff between time and resource investment and benefits for the community. Adopting this strategy would allow SCS to be agile and quickly adopt SONiC, by providing users with clear path while allowing the freedom to chose different hardware and software vendors. SCS code can be packaged independently of each SONiC distribution and installed as add-on. Also SCS contributions to core SONiC will be done directly upstream, so that the whole community can benefit from them."}),"\n",(0,t.jsx)(i.p,{children:"Work on hardware support in SONiC should be raised in upstream and SCS shouldn't make significant investments in this area."}),"\n",(0,t.jsx)(i.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"https://input.scs.community/VP04-issues-455-research-SDN-scalability",children:"Research SDN scalability"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"https://input.scs.community/SCS-DR-SONIC-usage",children:"Results SONIC Usage in SCS"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"https://input.scs.community/oW_plPZ6RkuXs3k9mrRDdw#",children:"SONiC Community research"})}),"\n"]})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>r,x:()=>a});var t=n(96540);const s={},o=t.createContext(s);function r(e){const i=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(o.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/29331985.aac2af9c.js b/assets/js/29331985.aac2af9c.js new file mode 100644 index 0000000000..ed2ebe65f4 --- /dev/null +++ b/assets/js/29331985.aac2af9c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1349],{47946:e=>{e.exports=JSON.parse('{"title":"IaaS Layer","slug":"/category/iaas-layer","permalink":"/docs/category/iaas-layer","navigation":{"previous":{"title":"Introduction","permalink":"/docs/"},"next":{"title":"Concept Guide","permalink":"/docs/iaas/guides/concept-guide/"}}}')}}]); \ No newline at end of file diff --git a/assets/js/29c2cfba.867c3231.js b/assets/js/29c2cfba.867c3231.js new file mode 100644 index 0000000000..c92de2ef3c --- /dev/null +++ b/assets/js/29c2cfba.867c3231.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8547],{6361:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var i=n(74848),o=n(28453);const r={},a="Documentation Files Structure",s={id:"contribute/doc-files-structure-guide",title:"Documentation Files Structure",description:"Structure Best Practice",source:"@site/community/contribute/doc-files-structure-guide.md",sourceDirName:"contribute",slug:"/contribute/doc-files-structure-guide",permalink:"/community/contribute/doc-files-structure-guide",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Adding Docs Guide",permalink:"/community/contribute/adding-docs-guide"},next:{title:"Documentation workflow explanation",permalink:"/community/contribute/docs-workflow-explanation"}},l={},c=[{value:"Structure Best Practice",id:"structure-best-practice",level:2},{value:"Overview - mandatory",id:"overview---mandatory",level:3},{value:"Requirements - mandatory",id:"requirements---mandatory",level:3},{value:"Quickstart - optional. If it is possible, then mandatory",id:"quickstart---optional-if-it-is-possible-then-mandatory",level:3},{value:"Getting Started - mandatory",id:"getting-started---mandatory",level:3},{value:"Configuration \u2013 mandatory",id:"configuration--mandatory",level:3},{value:"Contribute \u2013 mandatory",id:"contribute--mandatory",level:3},{value:"FAQ`s \u2013 optional",id:"faqs--optional",level:3}];function d(t){const e={h1:"h1",h2:"h2",h3:"h3",li:"li",ul:"ul",...(0,o.R)(),...t.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h1,{id:"documentation-files-structure",children:"Documentation Files Structure"}),"\n",(0,i.jsx)(e.h2,{id:"structure-best-practice",children:"Structure Best Practice"}),"\n",(0,i.jsx)(e.h3,{id:"overview---mandatory",children:"Overview - mandatory"}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:"What is it and for what do I need this? What benefits does it have for users?"}),"\n",(0,i.jsx)(e.li,{children:"What organization/company does this belong to? (Link to company/organization)"}),"\n",(0,i.jsx)(e.li,{children:"Where am I \u2013 as module \u2013 within the bigger context of SCS?"}),"\n"]}),"\n",(0,i.jsx)(e.h3,{id:"requirements---mandatory",children:"Requirements - mandatory"}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:"What minimal requirements do i need to quickstart?"}),"\n"]}),"\n",(0,i.jsx)(e.h3,{id:"quickstart---optional-if-it-is-possible-then-mandatory",children:"Quickstart - optional. If it is possible, then mandatory"}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:"Link to requirements"}),"\n",(0,i.jsx)(e.li,{children:"What is the aim of this quickstart guide?"}),"\n",(0,i.jsx)(e.li,{children:"Caution: only for testing, not for production"}),"\n",(0,i.jsx)(e.li,{children:"Rule: one line per command for easy copy&paste and one line for description where possible"}),"\n",(0,i.jsx)(e.li,{children:"Rule: only one working path for installation!"}),"\n"]}),"\n",(0,i.jsx)(e.h3,{id:"getting-started---mandatory",children:"Getting Started - mandatory"}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:"Aim is a production ready installation"}),"\n"]}),"\n",(0,i.jsx)(e.h3,{id:"configuration--mandatory",children:"Configuration \u2013 mandatory"}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:"Showing all possible config options"}),"\n"]}),"\n",(0,i.jsx)(e.h3,{id:"contribute--mandatory",children:"Contribute \u2013 mandatory"}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:"Description for how can i contribute with Link to Github repository"}),"\n"]}),"\n",(0,i.jsx)(e.h3,{id:"faqs--optional",children:"FAQ`s \u2013 optional"}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:"Roadmap - optional"}),"\n"]})]})}function u(t={}){const{wrapper:e}={...(0,o.R)(),...t.components};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(d,{...t})}):d(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>a,x:()=>s});var i=n(96540);const o={},r=i.createContext(o);function a(t){const e=i.useContext(r);return i.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(o):t.components||o:a(t.components),i.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/2abb9c6f.1841fc9f.js b/assets/js/2abb9c6f.1841fc9f.js new file mode 100644 index 0000000000..e818218242 --- /dev/null +++ b/assets/js/2abb9c6f.1841fc9f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6372],{12629:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>i,toc:()=>u});var o=t(74848),s=t(28453);const c={},a="Prometheus & Grafana",i={id:"iaas/guides/concept-guide/components/prometheus",title:"Prometheus & Grafana",description:"Lifecycle Management of Prometheus in OSISM",source:"@site/docs/02-iaas/guides/concept-guide/components/prometheus.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/prometheus",permalink:"/docs/iaas/guides/concept-guide/components/prometheus",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/prometheus.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"OpenStack",permalink:"/docs/iaas/guides/concept-guide/components/openstack"},next:{title:"Proxmox VE",permalink:"/docs/iaas/guides/concept-guide/components/proxmox"}},r={},u=[{value:"Lifecycle Management of Prometheus in OSISM",id:"lifecycle-management-of-prometheus-in-osism",level:2},{value:"Lifecycle Management of Grafana in OSISM",id:"lifecycle-management-of-grafana-in-osism",level:2}];function m(e){const n={h1:"h1",h2:"h2",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"prometheus--grafana",children:"Prometheus & Grafana"}),"\n",(0,o.jsx)(n.h2,{id:"lifecycle-management-of-prometheus-in-osism",children:"Lifecycle Management of Prometheus in OSISM"}),"\n",(0,o.jsx)(n.h2,{id:"lifecycle-management-of-grafana-in-osism",children:"Lifecycle Management of Grafana in OSISM"})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(m,{...e})}):m(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var o=t(96540);const s={},c=o.createContext(s);function a(e){const n=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),o.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2cc9d448.d52aa333.js b/assets/js/2cc9d448.d52aa333.js new file mode 100644 index 0000000000..229a57e756 --- /dev/null +++ b/assets/js/2cc9d448.d52aa333.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3574],{3389:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var i=n(74848),t=n(28453);const a={},r="Release Notes for SCS Release 6",o={id:"releases/Release6",title:"Release Notes for SCS Release 6",description:"SCS Release 6 has been published on 2024-03-20.",source:"@site/docs/06-releases/Release6.md",sourceDirName:"06-releases",slug:"/releases/Release6",permalink:"/docs/releases/Release6",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release6.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Release Notes for SCS Release 5",permalink:"/docs/releases/Release5"},next:{title:"Frequently Asked Questions",permalink:"/docs/faq/"}},l={},c=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"IaaS",id:"iaas",level:3},{value:"KaaS",id:"kaas",level:3},{value:"Operations",id:"operations",level:3},{value:"Observability",id:"observability",level:4},{value:"Zuul",id:"zuul",level:4},{value:"IAM",id:"iam",level:3},{value:"New Features (Highlights)",id:"new-features-highlights",level:2},{value:"Operator focused improvements",id:"operator-focused-improvements",level:3},{value:"OpenStack Health Monitor",id:"openstack-health-monitor",level:4},{value:"SCS Developer focused improvements (testbed and k8s cluster management)",id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",level:3},{value:"KaaS",id:"kaas-1",level:4},{value:"Preview: Domain Manager Persona",id:"preview-domain-manager-persona",level:3},{value:"Preview: Central API",id:"preview-central-api",level:3},{value:"Preview: Keycloak Home-IdP-discovery",id:"preview-keycloak-home-idp-discovery",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Security assessment for IaaS",id:"security-assessment-for-iaas",level:3},{value:"Resolved Issues",id:"resolved-issues",level:2},{value:"Preview: proper scope filtering for domain list API",id:"preview-proper-scope-filtering-for-domain-list-api",level:3},{value:"Documentation",id:"documentation",level:2},{value:"Highlighted blog posts",id:"highlighted-blog-posts",level:3},{value:"IAM",id:"iam-1",level:3},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R6",id:"list-of-known-issues--restrictions-in-r6",level:2},{value:"IaaS",id:"iaas-1",level:3},{value:"Loadbalancer service (octavia)",id:"loadbalancer-service-octavia",level:4},{value:"KaaS",id:"kaas-2",level:3},{value:"IAM",id:"iam-2",level:3},{value:"Contributing",id:"contributing",level:2},{value:"Thanks",id:"thanks",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h1,{id:"release-notes-for-scs-release-6",children:"Release Notes for SCS Release 6"}),"\n",(0,i.jsx)(s.p,{children:"SCS Release 6 has been published on 2024-03-20."}),"\n",(0,i.jsx)(s.h2,{id:"scope",children:"Scope"}),"\n",(0,i.jsxs)(s.p,{children:["Just as our previous release, Release 6 has been developed alongside a set of ",(0,i.jsx)(s.a,{href:"https://scs.community/2023/12/29/scs-r6-enables/",children:"associated outcomes"}),".\nOverall with Release 6 it becomes apparent that SCS is efficient to operate."]}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"SCS is standardized"}),"\n",(0,i.jsx)(s.li,{children:"SCS is understandable"}),"\n",(0,i.jsx)(s.li,{children:"SCS enables"}),"\n",(0,i.jsx)(s.li,{children:"SCS is transparent"}),"\n",(0,i.jsx)(s.li,{children:"SCS is continuously built and tested"}),"\n",(0,i.jsx)(s.li,{children:"SCS is opinionated"}),"\n",(0,i.jsx)(s.li,{children:"SCS charters new territory"}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,i.jsx)(s.h3,{id:"iaas",children:"IaaS"}),"\n",(0,i.jsxs)(s.p,{children:["The IaaS reference implementation is based on ",(0,i.jsx)(s.a,{href:"https://osism.tech/docs/release-notes/osism-7",children:"OSISM 7.0.0"}),"\nand delivers the following components:"]}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://releases.openstack.org/bobcat/highlights.html",children:"OpenStack 2023.2 (Bobcat)"})}),"\n",(0,i.jsxs)(s.li,{children:["Default Ceph version is ",(0,i.jsx)(s.a,{href:"https://docs.ceph.com/en/reef/releases/quincy/#v17-2-5-quincy",children:"Ceph Quincy"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://docs.ceph.com/en/latest/releases/reef/",children:"Ceph Reef"})," is included as a technical preview"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://www.openvswitch.org",children:"OVS"})," and ",(0,i.jsx)(s.a,{href:"https://www.ovn.org/en/",children:"OVN"})," have been updated and switched to LTS versions","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://mail.openvswitch.org/pipermail/ovs-announce/2024-February/000343.html",children:"OVS 3.3.0"})}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://mail.openvswitch.org/pipermail/ovs-announce/2024-March/000344.html",children:"OVN 24.03.1"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"kaas",children:"KaaS"}),"\n",(0,i.jsx)(s.p,{children:"On the KaaS level, the development of the Cluster Stacks as KaaS V2 has reached a state where the approach is finally usable. With Cluster Stacks it is possible to bundle all components of Kubernetes clusters, i.e. node images, Kubernetes configuration, and cluster addons (core applications necessary to use a Kubernetes cluster) together and use the bundles to create and update clusters with one simple command."}),"\n",(0,i.jsx)(s.p,{children:"One bundle, a Cluster Stack, can be tested extensively and is only released if both creating and upgrading clusters works smoothly. Users of these Cluster Stacks profit from the Cluster Stack Operator that works alongside with Cluster API to create and update ready-to-use clusters easily."}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"k8s-cluster-api-provider"})," (KaaS v1)","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Moved to OpenTofu"}),"\n",(0,i.jsx)(s.li,{children:"Migrated to ClusterClass (last not least to ease the migration to Cluster Stacks)"}),"\n",(0,i.jsx)(s.li,{children:"HTTP_Proxy configurable"}),"\n",(0,i.jsx)(s.li,{children:"OVN LB"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks",children:"Cluster Stacks"})," (KaaS v2)","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"First Cluster Stacks for OpenStack build"}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/",children:"Cluster Stack Operator"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"core component to manage Cluster Stack releases"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-provider-openstack",children:"Cluster Stack Provider OpenStack"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"manages node image release for OpenStack"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/csctl",children:"csctl"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"builds Cluster Stacks assets"}),"\n",(0,i.jsx)(s.li,{children:"builds node images"}),"\n",(0,i.jsx)(s.li,{children:"tests Cluster Stacks"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"operations",children:"Operations"}),"\n",(0,i.jsx)(s.h4,{id:"observability",children:"Observability"}),"\n",(0,i.jsxs)(s.p,{children:["The ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-observability",children:"Observability stack reference implementation"})," is based on ",(0,i.jsx)(s.a,{href:"https://github.com/dNationCloud/kubernetes-monitoring-stack",children:"dNation Kubernetes monitoring stack v3.5.0"}),"\nand delivers the following components:"]}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Monitoring of ",(0,i.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/monitoring/docs/overview",children:"infrastructure services"})," such as Kubernetes clusters, physical or virtual machines, and infrastructure endpoints"]}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/monitoring/docs/zuul",children:"Zuul CI monitoring"})}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/monitoring/docs/alertmanager",children:"Matrix chat notifications"})}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/monitoring/docs/oauth",children:"OAUTH authentication"})}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/components/monitoring/docs/iaas",children:"IaaS monitoring"})," is included as a technical preview"]}),"\n"]}),"\n",(0,i.jsx)(s.h4,{id:"zuul",children:"Zuul"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Created a development deployment for advancement testing."}),"\n",(0,i.jsx)(s.li,{children:"Simplified the installation requirements."}),"\n",(0,i.jsx)(s.li,{children:"Updated the Zuul repository's README file to include complete installation instructions for Terraform an Ansible."}),"\n",(0,i.jsx)(s.li,{children:"Added the clouds data into the ansible vault."}),"\n",(0,i.jsx)(s.li,{children:"Created an independent ansible Zuul role."}),"\n",(0,i.jsx)(s.li,{children:"Moved the custom Zuul tasks from the playbook and incorporated them into the role."}),"\n",(0,i.jsx)(s.li,{children:"Moved the custom Zuul variables from the playbook into the role's variables."}),"\n",(0,i.jsx)(s.li,{children:"Included the installation of Letsencrypt which adds certificates as part of the installation."}),"\n",(0,i.jsx)(s.li,{children:"Added a volume on the VM for the MariaDB instance to use for continuity."}),"\n",(0,i.jsx)(s.li,{children:"Added volumes on the VM for Zookeeper to use for the data snapshots and datalog."}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"iam",children:"IAM"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Updated Keycloak image to 23.0.6."}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://registry.scs.community/harbor/projects/22/repositories/scs-keycloak/artifacts-tab",children:"Custom SCS-Keycloak image"})," now includes the ",(0,i.jsx)(s.a,{href:"https://github.com/sventorben/keycloak-home-idp-discovery",children:"Home-IdP-discovery"})," plugin."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"new-features-highlights",children:"New Features (Highlights)"}),"\n",(0,i.jsx)(s.h3,{id:"operator-focused-improvements",children:"Operator focused improvements"}),"\n",(0,i.jsxs)(s.p,{children:["A Kubernetes engine, via ",(0,i.jsx)(s.a,{href:"https://k3s.io",children:"k3s"}),", has been introduced to the control plane of the IaaS reference\nimplementation."]}),"\n",(0,i.jsxs)(s.p,{children:[(0,i.jsx)(s.code,{children:"osism"})," now deploys Keycloak to k3s via ",(0,i.jsx)(s.a,{href:"https://github.com/codecentric/helm-charts/blob/master/charts/keycloakx/README.md",children:"codecentric/keycloakx"})," helm chart and ",(0,i.jsx)(s.a,{href:"https://github.com/cloudnative-pg/charts",children:"CloudNativePG"})," operator."]}),"\n",(0,i.jsxs)(s.p,{children:["Rotation of the Octavia Amphora images has been added to the ",(0,i.jsx)(s.code,{children:"osism"})," command. ",(0,i.jsx)(s.code,{children:"osism manage image octavia"})," will rotate\nthe image, which is rebuilt on a daily basis."]}),"\n",(0,i.jsx)(s.h4,{id:"openstack-health-monitor",children:"OpenStack Health Monitor"}),"\n",(0,i.jsxs)(s.p,{children:["A new monitoring stack will replace the old\n",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/",children:"openstack-health-monitor"}),".\nNevertheless, it is currently still in heavy use and has thus seen a few improvements\nresponding to challenges observed in real-life clouds:"]}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["A new ",(0,i.jsx)(s.a,{href:"https://docs.scs.community/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install",children:"installation guide"})]}),"\n",(0,i.jsx)(s.li,{children:"Robustness against leaking volumes even with overloaded cinder API"}),"\n",(0,i.jsx)(s.li,{children:"Robustness against leaking ports from OVN LB health-monitor"}),"\n",(0,i.jsx)(s.li,{children:"Robustness against leftover keypairs"}),"\n",(0,i.jsx)(s.li,{children:"Avoid some followup errors when VM creation failed"}),"\n",(0,i.jsxs)(s.li,{children:["Add logic to startup os-health-mon in tmux windows via ",(0,i.jsx)(s.code,{children:"systemctl --user"})]}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",children:"SCS Developer focused improvements (testbed and k8s cluster management)"}),"\n",(0,i.jsx)(s.h4,{id:"kaas-1",children:"KaaS"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Every component of Cluster Stacks brings a Tilt environment for local test and development"}),"\n",(0,i.jsx)(s.li,{children:"With csctl Cluster Stacks assets can be created and tested locally without uploading to GitHub"}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"preview-domain-manager-persona",children:"Preview: Domain Manager Persona"}),"\n",(0,i.jsxs)(s.p,{children:["A Domain Manager role has been established in a ",(0,i.jsx)(s.a,{href:"https://docs.scs.community/standards/scs-0302-v1-domain-manager-role",children:"standard draft in SCS"})," aiming to allow self-service capabilities for customers at the identity API.\nWork is in progress to ",(0,i.jsx)(s.a,{href:"https://bugs.launchpad.net/keystone/+bug/2045974",children:"contribute this functionality to OpenStack Keystone"})," and the corresponding ",(0,i.jsx)(s.a,{href:"https://review.opendev.org/c/openstack/keystone-specs/+/903172",children:"upstream spec"})," is currently under review.\nThe feature is expected to be available in the next SCS release."]}),"\n",(0,i.jsx)(s.h3,{id:"preview-central-api",children:"Preview: Central API"}),"\n",(0,i.jsxs)(s.p,{children:['To improve the experience of SCS cloud customers, the idea of a "Central API" was discussed. Such API should enable customers to manage various "as-a-Service" resources. For example: OpenStack instances as well as Kubernetes clusters as well as Keycloak OAuth2 clients.\nRead about the trade-offs and ideas in the ',(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/central-api",children:"central-api repository"})," and feel free to test out the ",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/central-api/blob/0422e8ca24667b04b7364ffa461f85c3de51a50a/poc-setup.md",children:"POC"}),"."]}),"\n",(0,i.jsx)(s.h3,{id:"preview-keycloak-home-idp-discovery",children:"Preview: Keycloak Home-IdP-discovery"}),"\n",(0,i.jsxs)(s.p,{children:["To improve flexibility of onboarding new customer domains via IdP federation, SCS now deploys Keycloak with the ",(0,i.jsx)(s.a,{href:"https://github.com/sventorben/keycloak-home-idp-discovery",children:"Home-IdP-discovery"}),' plugin. The idea is, that Keystone federates out to a single Keycloak "proxy" realm (called ',(0,i.jsx)(s.code,{children:"osism"}),' in the testbed) and using the plugin, Keycloak can identify the user specific realm from an email-format login-ID. Operators can create dedicated realms for each customer and Keycloak uses internal federation to redirect from the "proxy" realm to the specific customer realm. In the customer ream they can configure IdP federation (OpenID-Connect or SAML) to their own IAM solution. The ',(0,i.jsx)(s.a,{href:"https://docs.scs.community/docs/iam",children:"IAM section"})," of the SCS documentation shall be extended to detail the configuration. SCS is working upstream to contribute required enhancements in the\nmapping of users, groups and roles from OpenID-Connect token claims to the OpenStack Keystone access management."]}),"\n",(0,i.jsx)(s.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["For the IaaS reference implementation, please refer to the ",(0,i.jsx)(s.a,{href:"https://osism.tech/docs/release-notes/osism-7#upgrade-notes",children:"OSISM 7.0.0 Upgrade Notes"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"removals",children:"Removals"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Please check the removals for OSISM in the ",(0,i.jsx)(s.a,{href:"https://osism.tech/docs/release-notes/osism-7#removals--deprecations",children:"upstream removal notices"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsx)(s.p,{children:"KaaSv1 is still provided with R6, but we do not intend to include it in R7 again.\nWe want to rather focus on the feature completeness of the much more future-proof\ncluster-stacks."}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["In upstream OSISM the role for deploying the Tang service (",(0,i.jsx)(s.code,{children:"osism.services.tang"}),") has been deprecated.\nWe would like to encourage active contributions in this area via the deprecation, since this piece of\ncode is currently not actively maintained nor -- to our knowledge -- actively used."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,i.jsx)(s.p,{children:"During the R6 development cycle a few security issues were reported and we issued security\nadvisories and addressed them via maintenance updates. All of these issues are also fixed\nin the upcoming R6 release. These include:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["A ",(0,i.jsx)(s.a,{href:"https://scs.community/de/security/2024/02/20/cve-2023-3966/",children:"OvS vulnerability with crafted Geneve packets and HW acceleration"})]}),"\n",(0,i.jsxs)(s.li,{children:["A ",(0,i.jsx)(s.a,{href:"https://scs.community/de/security/2024/03/15/cve-2024-2182/",children:"OVN vulnerability against specific BFD packets"})]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:"Other security topics were covered in our community blog as well:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://scs.community/2024/01/03/intel-amd-cpu-vulns/",children:"Delving into the Technical Depths of Intel-SA-00950 and AMD Cachewarp Vulnerabilities"})}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"security-assessment-for-iaas",children:"Security assessment for IaaS"}),"\n",(0,i.jsx)(s.p,{children:"We invested in a range of penetration tests of the IaaS layer which resulted in valuable insight in possible improvements (e.g. applying hardening measures):"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"External pentesting of components (scanning, blackbox testing)"}),"\n",(0,i.jsx)(s.li,{children:"Internal pentesting of components with privileged and unprivileged system users (scanning from inside the cluster)"}),"\n",(0,i.jsx)(s.li,{children:"Scanning and pentesting the environment from a customer workload machine"}),"\n"]}),"\n",(0,i.jsxs)(s.p,{children:["The vision of SCS is to have continuous security assurance by adding security checks and pentesting tooling\nto our CI pipelines; this is currently in implementation. Next step will then be to also cover other parts\n(beyond the IaaS layer) of our stack with manual and then\n",(0,i.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/security-infra-scan-pipeline",children:"automated penetration testing"}),"."]}),"\n",(0,i.jsx)(s.h2,{id:"resolved-issues",children:"Resolved Issues"}),"\n",(0,i.jsx)(s.h3,{id:"preview-proper-scope-filtering-for-domain-list-api",children:"Preview: proper scope filtering for domain list API"}),"\n",(0,i.jsxs)(s.p,{children:["A fix to a bug where listing domains via Keystone API would return domains not intended to be visible to the requesting entity was ",(0,i.jsx)(s.a,{href:"https://bugs.launchpad.net/keystone/+bug/2041611",children:"contributed and merged upstream"}),".\nThe fix is expected to be available by the next SCS release."]}),"\n",(0,i.jsx)(s.h2,{id:"documentation",children:"Documentation"}),"\n",(0,i.jsxs)(s.p,{children:["The ",(0,i.jsx)(s.a,{href:"https://docs.scs.commnutiy/",children:"docs page"})," has come a long way in the last 6 months.\nIt pulls in a lot more content from the various projects and structures it in a much\nmore accessible way. Look at the ",(0,i.jsx)(s.a,{href:"https://docs.scs.community/standards",children:"standards"})," pages\nthere to get an impression."]}),"\n",(0,i.jsx)(s.h3,{id:"highlighted-blog-posts",children:"Highlighted blog posts"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Oct'23: ",(0,i.jsx)(s.a,{href:"https://scs.community/2023/10/19/progress-openstack-cli-with-federation/",children:"Progress: OpenStack API access with OpenID Connect in Sovereign Cloud Stack"})]}),"\n",(0,i.jsxs)(s.li,{children:["Nov'23: ",(0,i.jsx)(s.a,{href:"https://scs.community/tech/2023/11/21/confidential-computing-in-digital-sovereign-environments/",children:"Confidential Computing in digital sovereign environments"})]}),"\n",(0,i.jsxs)(s.li,{children:["Dec'23: ",(0,i.jsx)(s.a,{href:"https://scs.community/tech/2023/12/06/mvp-monitoring/",children:"SCS observability and monitoring - An opinionated proposal"})]}),"\n",(0,i.jsxs)(s.li,{children:["Dec'23: ",(0,i.jsx)(s.a,{href:"https://scs.community/2023/12/23/clusterstacks/",children:"Cluster Stacks"})]}),"\n",(0,i.jsxs)(s.li,{children:["Feb'24: ",(0,i.jsx)(s.a,{href:"https://scs.community/2024/02/09/sdn-scalability/",children:"SDN scalability improvements"})]}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"iam-1",children:"IAM"}),"\n",(0,i.jsxs)(s.p,{children:["The documentation now contains an ",(0,i.jsx)(s.a,{href:"https://docs.scs.community/docs/iam",children:"IAM overview document"})," which explains current\nlimitations for the dynamic mapping of user roles and shall be extended to explain configuration options for Operators."]}),"\n",(0,i.jsx)(s.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,i.jsxs)(s.p,{children:["The standards have evolved, increasing the amount of guarantees that software developers\nand operators have for workloads that work across SCS-compatible clouds.\nThe ",(0,i.jsx)(s.a,{href:"https://docs.scs.community/standards/scs-compatible-iaas",children:"SCS-compatible IaaS-v4"}),"\nhas seen improvements and better test coverage; the OSISM IaaS reference implementation\nfulfills all of these standards in the default configuration."]}),"\n",(0,i.jsxs)(s.p,{children:["For the Kubernetes layer, we have our first set of standards almost finalized.\nSome of the standards for ",(0,i.jsx)(s.a,{href:"https://docs.scs.community/standards/scs-compatible-kaas",children:"SCS-compatible KaaS-v1"}),"\nare unfortunately hard to test, so we are working on adding some more tests before\nwe cut it in stone. We aim for both KaaSv1 and v2 to fulfill the standards.\n(Future standards will likely not be fulfilled by KaaSv1 as it's being deprecated.)"]}),"\n",(0,i.jsx)(s.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,i.jsxs)(s.p,{children:["A number of repositories follow OSISM's example and use the ",(0,i.jsx)(s.code,{children:"7.0.0"})," or ",(0,i.jsx)(s.code,{children:"v7.0.0"})," tag\nto denote SCS Release 6."]}),"\n",(0,i.jsx)(s.h2,{id:"list-of-known-issues--restrictions-in-r6",children:"List of known issues & restrictions in R6"}),"\n",(0,i.jsx)(s.h3,{id:"iaas-1",children:"IaaS"}),"\n",(0,i.jsx)(s.h4,{id:"loadbalancer-service-octavia",children:"Loadbalancer service (octavia)"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Creating loadbalancers in Cloud-in-a-Box installations fails with the\nerror message that the VIP subnet does not exist. ",(0,i.jsx)(s.a,{href:"https://github.com/osism/issues/issues/890",children:"OSISM #890"})]}),"\n",(0,i.jsxs)(s.li,{children:["When using ",(0,i.jsx)(s.code,{children:"--provider ovn"})," with a loadbalancer health-monitor, we leak ports ",(0,i.jsx)(s.code,{children:"ovn-lb-hm-$SUBNETID"})," in all\nbut the VIP subnet, if we clean up the LB members before the health-monitor. This is tracked as\n",(0,i.jsx)(s.a,{href:"https://github.com/osism/issues/issues/921",children:"OSISM issue #921"}),". Deleting the health-monitor before the\nmembers or using ",(0,i.jsx)(s.code,{children:"openstack loadbalancer delete --cascade"})," avoids this issue."]}),"\n",(0,i.jsxs)(s.li,{children:["With amphora loadbalancers, we can end up in situations that LB deletion does no longer work due to\na failover or a failed creation of the vrrp port. This is tracked in\n",(0,i.jsx)(s.a,{href:"https://github.com/osism/issues/issues/925",children:"OSISM issue #925"}),". An upstream fix exists and a backport\nis already underway."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:"We expect to resolve these issues with a maintenance update."}),"\n",(0,i.jsx)(s.h3,{id:"kaas-2",children:"KaaS"}),"\n",(0,i.jsx)(s.p,{children:"Some features of KaaS v1 are not available yet in KaaS v2 because they are WIP in upstream CAPO.\nThis includes the creation of some of the optional components such as e.g. the deployment\nof ingress service, cert-manager, flux, harbor. More importantly, we do not yet have the\nhandling of restrictive security groups implemented nor the ability to avoid OpenStack\nscheduling more than one control plane node on the same host (hypervisor)."}),"\n",(0,i.jsx)(s.p,{children:"For this reason, we are including KaaS v1 (k8s-cluster-api-provider) in the R6 release,\nso existing users can upgrade to the latest upstream code and continuing using it as\na maintained solution while they evaluate the migration to KaaS v2 (cluster-stacks)."}),"\n",(0,i.jsx)(s.p,{children:"We will address most of the gaps during the next release cycle."}),"\n",(0,i.jsx)(s.p,{children:"KaaS v1 should not be used for new deployments; we intend to remove it with the next\nrelease (R7)."}),"\n",(0,i.jsx)(s.h3,{id:"iam-2",children:"IAM"}),"\n",(0,i.jsx)(s.p,{children:"Since Keycloak is a Java application it requires importing certificates into its certificate store.\nAs the Keycloak pod in k3s now runs the service as non-root user, it gets more challenging to import\ncustom certificates from arbitrary customers for IdP federation. In case this topic is interesting for\nspecific deployments, the SCS project team would like to hear from users and discuss how to best\nexpose such a capability."}),"\n",(0,i.jsx)(s.h2,{id:"contributing",children:"Contributing"}),"\n",(0,i.jsxs)(s.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,i.jsx)(s.a,{href:"https://scs.community/contribute/",children:"How to contribute page"}),"."]}),"\n",(0,i.jsx)(s.h2,{id:"thanks",children:"Thanks"}),"\n",(0,i.jsx)(s.p,{children:"We have had considerable help from many partners and upstream projects during\nthe R6 development cycle. We continue to be grateful for the generous support\nfrom providers that support with infrastructure that we can use for testing and\ndevelopment. plusserver has been particularly generous and also helped us\nfinding a few issues during the pre-release phase by upgrading test\nenvironments and testing them."})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>o});var i=n(96540);const t={},a=i.createContext(t);function r(e){const s=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2ce1dccd.a0c204ee.js b/assets/js/2ce1dccd.a0c204ee.js new file mode 100644 index 0000000000..5584d2c0dd --- /dev/null +++ b/assets/js/2ce1dccd.a0c204ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1026],{48143:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>t,metadata:()=>o,toc:()=>d});var s=i(74848),a=i(28453);const t={sidebar_label:"Image Manager",sidebar_position:50},r="Image Manager",o={id:"iaas/components/image-manager/index",title:"Image Manager",description:"The OpenStack Image Manager is a tool for managing all",source:"@site/docs/02-iaas/components/image-manager/index.md",sourceDirName:"02-iaas/components/image-manager",slug:"/iaas/components/image-manager/",permalink:"/docs/iaas/components/image-manager/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/image-manager/index.md",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"Image Manager",sidebar_position:50},sidebar:"docs",previous:{title:"Components",permalink:"/docs/category/components"},next:{title:"Automated updates",permalink:"/docs/iaas/components/image-manager/update"}},l={},d=[{value:"Requirements",id:"requirements",level:2},{value:"OpenStack Image Service (Glance)",id:"openstack-image-service-glance",level:3},{value:"Object storage backend",id:"object-storage-backend",level:3},{value:"Getting started",id:"getting-started",level:2},{value:"Image definitions",id:"image-definitions",level:2},{value:"SCS image standard",id:"scs-image-standard",level:3},{value:"Image with regular rebuilds",id:"image-with-regular-rebuilds",level:3},{value:"Image without regular rebuild",id:"image-without-regular-rebuild",level:3},{value:"Other properties",id:"other-properties",level:3},{value:"Image properties",id:"image-properties",level:4},{value:"Image tags",id:"image-tags",level:4},{value:"image status",id:"image-status",level:4},{value:"Image visibility",id:"image-visibility",level:4},{value:"Usage",id:"usage",level:2},{value:"Mirroring images",id:"mirroring-images",level:3},{value:"Updating images",id:"updating-images",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"image-manager",children:"Image Manager"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://pypi.org/project/openstack-image-manager/",children:"OpenStack Image Manager"})," is a tool for managing all\nimages on an OpenStack environment"]}),"\n",(0,s.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,s.jsx)(n.p,{children:"This information is only relevant for the operator of an OpenStack environment. You can skip this section if\nyou want to use OpenStack Image Manager as a normal user and you are not an operator of an openStack environment."}),"\n",(0,s.jsx)(n.h3,{id:"openstack-image-service-glance",children:"OpenStack Image Service (Glance)"}),"\n",(0,s.jsx)(n.p,{children:"The OpenStack Image Service (Glance) is required to upload and discover data assets that are used by other\nservices."}),"\n",(0,s.jsx)(n.p,{children:"Since this script stores many images in a single project, the Glance quota must be set accordingly high or to unlimited."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[DEFAULT]\nuser_storage_quota = 1TB\n"})}),"\n",(0,s.jsxs)(n.p,{children:["With most storage backends it makes sense to convert the imported images directly to RAW. So it is required for using Ceph and it's\nfeatures too. Recited from the Ceph documentation ",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rbd/qemu-rbd/",children:"QEMU and block devices"})," and\n",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rbd/rbd-openstack/",children:"Block devices and OpenStack"}),"."]}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsx)(n.p,{children:"The raw data format is really the only sensible format option to use with RBD. Technically, you could use other QEMU-supported formats\n(such as qcow2 or vmdk), but doing so would add additional overhead, and would also render the volume unsafe for virtual machine live\nmigration when caching (see below) is enabled."}),(0,s.jsx)(n.p,{children:"Important Ceph doesn't support QCOW2 for hosting a virtual machine disk. Thus if you want to boot virtual machines in Ceph (ephemeral\nbackend or boot from volume), the Glance image format must be RAW."}),(0,s.jsxs)(n.p,{children:["See the ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/glance/latest/configuration/sample-configuration.html",children:"OpenStack Glance documentation"}),"\nfor more details."]})]}),"\n",(0,s.jsx)(n.p,{children:"This requires the following parameter for the image import workflow."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"[taskflow_executor]\nconversion_format = raw\n\n[image_import_opts]\nimage_import_plugins = ['image_decompression', 'image_conversion']\n\n[image_conversion]\noutput_format = raw\n"})}),"\n",(0,s.jsx)(n.h3,{id:"object-storage-backend",children:"Object storage backend"}),"\n",(0,s.jsx)(n.p,{children:"If the mirror functionality is used, an object storage backend is required. The use of the mirror functionality\nis optional and is not used by default."}),"\n",(0,s.jsx)(n.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,s.jsxs)(n.p,{children:["This ",(0,s.jsx)(n.strong,{children:"Getting started"})," will upload a private image to your OpenStack environment with\nthe help of the OpenStack Image Manager."]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Install the ",(0,s.jsx)(n.a,{href:"https://pypi.org/project/openstack-image-manager/",children:"openstack-image-manager"})," package with\n",(0,s.jsx)(n.a,{href:"https://pypi.org/project/pip/",children:"pip"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"pip3 install openstack-image-manager\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The installation can also be done via ",(0,s.jsx)(n.a,{href:"https://pypi.org/project/pipenv/",children:"pipenv"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"Pipefile"})," file is created with this content. The ",(0,s.jsx)(n.a,{href:"https://pypi.org/project/openstack-image-manager/#history",children:"latest version of openstack-image-manager"}),"\nis used."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:'[[source]]\nurl = "https://pypi.org/simple"\nverify_ssl = true\nname = "pypi"\n\n[packages]\nopenstack-image-manager = "==0.20240403.0"\n\n[dev-packages]\n\n[requires]\npython_version = "3.10"\n'})}),"\n",(0,s.jsx)(n.p,{children:"The dependencies are then installed and the shell is prepared for use:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"pipenv install\npipenv shell\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Create a image definition in the file ",(0,s.jsx)(n.code,{children:"getting-started.yml"})," in the local directory ",(0,s.jsx)(n.code,{children:"images"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'---\nimages:\n - name: MyCirros\n format: qcow2\n login: cirros\n password: gocubsgo\n min_disk: 1\n min_ram: 32\n status: active\n visibility: private\n multi: false\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_rng_model: virtio\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n os_distro: cirros\n replace_frequency: never\n uuid_validity: none\n provided_until: none\n tags: []\n versions:\n - version: "0.6.0"\n url: https://github.com/cirros-dev/cirros/releases/download/0.6.0/cirros-0.6.0-x86_64-disk.img\n checksum: "sha256:94e1e2c94dbbae7d4bdc38e68590a1daf73c9de2d03dd693857b4b0a042548e8"\n build_date: 2022-09-28\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run the OpenStack Image Manager. It is assumed that a profile with the name ",(0,s.jsx)(n.code,{children:"openstack"})," exists in the\n",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/python-openstackclient/latest/configuration/index.html#configuration-files",children:"clouds.yaml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'openstack-image-manager --cloud openstack --filter ".*Cirr.*" --images images/\n'})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"image-definitions",children:"Image definitions"}),"\n",(0,s.jsxs)(n.p,{children:["The configuration consists of different parameter settings, such as values for\nminimum RAM or the visibility of the image. Have a look at the examples below\nfor all parameters. After a change to the configuration, validate it with\n",(0,s.jsx)(n.code,{children:"tox -- --dry-run"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"scs-image-standard",children:"SCS image standard"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The value of ",(0,s.jsx)(n.code,{children:"login"})," is stored as ",(0,s.jsx)(n.code,{children:"image_original_user"})," in the metadata of an image."]}),"\n",(0,s.jsxs)(n.li,{children:["If ",(0,s.jsx)(n.code,{children:"image_description"})," is not set as meta information, ",(0,s.jsx)(n.code,{children:"image_description"})," is set to the name of the image."]}),"\n",(0,s.jsxs)(n.li,{children:["The value of ",(0,s.jsx)(n.code,{children:"build_date"})," of a specific version of an image is stored as ",(0,s.jsx)(n.code,{children:"image_build_date"})," in the metadata of an image."]}),"\n",(0,s.jsxs)(n.li,{children:["The value of ",(0,s.jsx)(n.code,{children:"url"})," of a specific version of an image is stored as ",(0,s.jsx)(n.code,{children:"image_source"})," in the metadata of an image."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"image-with-regular-rebuilds",children:"Image with regular rebuilds"}),"\n",(0,s.jsx)(n.p,{children:"This type of image definition is used for images that are rebuilt at regular\nintervals. For example, this is the case for the daily builds of the Ubuntu\nimages."}),"\n",(0,s.jsxs)(n.p,{children:["The attribute ",(0,s.jsx)(n.code,{children:"multi: true"})," is set."]}),"\n",(0,s.jsxs)(n.p,{children:["With this type of image definition, the version of the distribution (or product,\nwhatever is contained in the image) used is already in the name of the image\ndefinition. The ",(0,s.jsx)(n.code,{children:"version"})," properties from the definition's ",(0,s.jsx)(n.code,{children:"versions"})," list\nare appended only to older iterations of the image as timestamp suffixes\nin parentheses upon each rotation (except for the latest entry)."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"images:\n - name: Ubuntu 24.04\n format: qcow2\n login: ubuntu\n min_disk: 8\n min_ram: 512\n status: active\n visibility: public\n multi: true\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n os_distro: ubuntu\n os_version: '24.04'\n tags: []\n versions:\n - version: '20240416'\n url: https://cloud-images.ubuntu.com/noble/20240416/noble-server-cloudimg-amd64.img\n - version: '20240422'\n url: https://cloud-images.ubuntu.com/noble/20240422/noble-server-cloudimg-amd64.img\n"})}),"\n",(0,s.jsx)(n.p,{children:"This configuration creates the following images:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.strong,{children:"Ubuntu 24.04 (20240416)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.strong,{children:"Ubuntu 24.04"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"If a newer build is added, the following rotation takes place:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Ubuntu 24.04 (20240416)"})," does not change"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Ubuntu 24.04"})," becomes ",(0,s.jsx)(n.strong,{children:"Ubuntu 24.04 (20240422)"})]}),"\n",(0,s.jsxs)(n.li,{children:["the new image becomes ",(0,s.jsx)(n.strong,{children:"Ubuntu 24.04"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["By default the last three images will be visible. When a fourth image is added, the visibility of\nthe last image in the list is changed to ",(0,s.jsx)(n.code,{children:"community"})," and the image can be deleted in the future."]}),"\n",(0,s.jsx)(n.h3,{id:"image-without-regular-rebuild",children:"Image without regular rebuild"}),"\n",(0,s.jsx)(n.p,{children:"This type of image definition is used for images that are not rebuilt. For example,\nthis is the case for the flatcar images. For each release of Flatcar there is exactly\none image which will not be rebuilt in the future."}),"\n",(0,s.jsxs)(n.p,{children:["The attribute ",(0,s.jsx)(n.code,{children:"multi: false"})," is set."]}),"\n",(0,s.jsxs)(n.p,{children:["With this type of image definition, the version of the distribution (or product,\nwhatever is contained in the image) used is not in the name of the image definition.\nInstead, the ",(0,s.jsx)(n.code,{children:"version"})," properties from the image definition's ",(0,s.jsx)(n.code,{children:"versions"})," list\nare appended as static version suffixes to the images' names."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"images:\n - name: RancherOS\n format: qcow2\n login: rancher\n min_disk: 8\n min_ram: 2048\n status: active\n visibility: public\n multi: false\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n tags: []\n versions:\n - version: '1.3.0'\n url: https://github.com/rancher/os/releases/download/v1.3.0/rancheros-openstack.img\n - version: '1.4.0'\n url: https://github.com/rancher/os/releases/download/v1.4.0/rancheros-openstack.img\n - version: '1.4.1'\n url: https://github.com/rancher/os/releases/download/v1.4.1/rancheros-openstack.img\n"})}),"\n",(0,s.jsx)(n.p,{children:"This configuration creates the following images:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.strong,{children:"RancherOS 1.3.0"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.strong,{children:"RancherOS 1.4.0"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.strong,{children:"RancherOS 1.4.1"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["If a new version is added, no rotation takes place. The new version is added\nas ",(0,s.jsx)(n.strong,{children:"RancherOS x.y.z"}),". Here also the visibility of older images is not changed."]}),"\n",(0,s.jsx)(n.h3,{id:"other-properties",children:"Other properties"}),"\n",(0,s.jsx)(n.h4,{id:"image-properties",children:"Image properties"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Removal of properties is not yet possible"}),"\n",(0,s.jsx)(n.li,{children:"URL, name and format can not be changed"}),"\n",(0,s.jsxs)(n.li,{children:["Any keys can be added to ",(0,s.jsx)(n.code,{children:"meta"}),", these will be added to the image"]}),"\n",(0,s.jsxs)(n.li,{children:["Existing keys in ",(0,s.jsx)(n.code,{children:"meta"})," can be changed, the same applies to ",(0,s.jsx)(n.code,{children:"min_disk"}),"\nand ",(0,s.jsx)(n.code,{children:"min_ram"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"image-tags",children:"Image tags"}),"\n",(0,s.jsx)(n.h4,{id:"image-status",children:"image status"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["deactivation: change ",(0,s.jsx)(n.code,{children:"status"})," to ",(0,s.jsx)(n.code,{children:"deactivated"})]}),"\n",(0,s.jsxs)(n.li,{children:["reactivation: change ",(0,s.jsx)(n.code,{children:"status"})," to ",(0,s.jsx)(n.code,{children:"active"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"image-visibility",children:"Image visibility"}),"\n",(0,s.jsxs)(n.p,{children:["A full documentation about the visibility of images can be found in the ",(0,s.jsx)(n.strong,{children:"Image visibility"})," section in the\n",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/api-ref/image/v2/index.html#general-information",children:"OpenStack Image Service API Documentation"}),"."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["public: set ",(0,s.jsx)(n.code,{children:"visibility"})," to ",(0,s.jsx)(n.code,{children:"public"})]}),"\n",(0,s.jsxs)(n.li,{children:["community: set ",(0,s.jsx)(n.code,{children:"visibility"})," to ",(0,s.jsx)(n.code,{children:"community"})]}),"\n",(0,s.jsxs)(n.li,{children:["shared: set ",(0,s.jsx)(n.code,{children:"visibility"})," to ",(0,s.jsx)(n.code,{children:"shared"})]}),"\n",(0,s.jsxs)(n.li,{children:["private: set ",(0,s.jsx)(n.code,{children:"visibility"})," to ",(0,s.jsx)(n.code,{children:"private"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,s.jsx)(n.h3,{id:"mirroring-images",children:"Mirroring images"}),"\n",(0,s.jsx)(n.p,{children:"Since the upstreams often only keep their images for a short time, we mirror most of the images on REGIO.cloud.\nThis makes us independent of the availability of the images in the individual upstreams."}),"\n",(0,s.jsx)(n.h3,{id:"updating-images",children:"Updating images"}),"\n",(0,s.jsxs)(n.p,{children:["Some of the images are automatically updated by a ",(0,s.jsx)(n.a,{href:"update",children:"CI job"}),". The latest available build at the time of the CI job execution is mirrored and\nmade available as the current version."]}),"\n",(0,s.jsx)(n.p,{children:"Currently, the following images are updated once a week (every Sunday at 0 am):"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Almalinux"}),"\n",(0,s.jsx)(n.li,{children:"CentOS"}),"\n",(0,s.jsx)(n.li,{children:"Debian"}),"\n",(0,s.jsx)(n.li,{children:"Rockylinux"}),"\n",(0,s.jsx)(n.li,{children:"Ubuntu"}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>o});var s=i(96540);const a={},t=s.createContext(a);function r(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2d071e49.d7c0dd51.js b/assets/js/2d071e49.d7c0dd51.js new file mode 100644 index 0000000000..518a500577 --- /dev/null +++ b/assets/js/2d071e49.d7c0dd51.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[953],{16539:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var a=t(74848),s=t(28453);const i={},r="KaaS monitoring (experimental)",o={id:"operating-scs/components/monitoring/docs/kaas",title:"KaaS monitoring (experimental)",description:"This component is marked as experimental, and it is not part of the reference SCS installation available",source:"@site/docs/04-operating-scs/components/monitoring/docs/kaas.md",sourceDirName:"04-operating-scs/components/monitoring/docs",slug:"/operating-scs/components/monitoring/docs/kaas",permalink:"/docs/operating-scs/components/monitoring/docs/kaas",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/kaas.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"IaaS monitoring (experimental)",permalink:"/docs/operating-scs/components/monitoring/docs/iaas"},next:{title:"Zuul monitoring",permalink:"/docs/operating-scs/components/monitoring/docs/zuul"}},c={},l=[{value:"Enable KaaS layer monitoring",id:"enable-kaas-layer-monitoring",level:2},{value:"KaaS metric importer",id:"kaas-metric-importer",level:2},{value:"KaaS mock service",id:"kaas-mock-service",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h1,{id:"kaas-monitoring-experimental",children:"KaaS monitoring (experimental)"}),"\n",(0,a.jsxs)(n.p,{children:["This component is marked as experimental, and it is not part of the reference SCS installation available\nat ",(0,a.jsx)(n.a,{href:"https://monitoring.scs.community",children:"https://monitoring.scs.community"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"enable-kaas-layer-monitoring",children:"Enable KaaS layer monitoring"}),"\n",(0,a.jsx)(n.p,{children:"TODO: Provide clear instructions on how to enable KaaS layer monitoring."}),"\n",(0,a.jsxs)(n.p,{children:["Please check out the ",(0,a.jsx)(n.code,{children:"mvp-0"})," tag and find the related comments on what needs to be done in the monitoring\nvalues to enable KaaS monitoring in your Observer cluster."]}),"\n",(0,a.jsx)(n.h2,{id:"kaas-metric-importer",children:"KaaS metric importer"}),"\n",(0,a.jsx)(n.p,{children:"To test the Monitoring of the KaaS layer use case, deploy the Kaas-metric-importer\ninto the Observer cluster."}),"\n",(0,a.jsx)(n.p,{children:"The Kaas-metric-importer is a simple service through which the KaaS software registers\nand unregisters newly created or deleted KaaS clusters in the Observer monitoring.\nThis functionality enables the Observer monitoring to differentiate between KaaS clusters deleted intentionally\nand those that have stopped writing metrics to the Observer monitoring for any reason."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f kaas/kaas-metric-importer.yaml\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The Kaas-metric-importer uses an image built from ",(0,a.jsx)(n.a,{href:"https://github.com/m3dbx/prometheus_remote_client_golang",children:"https://github.com/m3dbx/prometheus_remote_client_golang"}),".\nIt has mounted configmap and based on configmap keys it pushes custom metric ",(0,a.jsx)(n.code,{children:"kaas"}),"\nwith label ",(0,a.jsx)(n.code,{children:"cluster"})," and value ",(0,a.jsx)(n.code,{children:"1"})," into the thanos receiver."]}),"\n",(0,a.jsx)(n.p,{children:"Example of configmap:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'data:\n workload-cluster: ""\n'})}),"\n",(0,a.jsxs)(n.p,{children:["It pushes metric e.g. ",(0,a.jsx)(n.code,{children:'kaas{cluster="workload-cluster"} 1'})," to the Observer.\nIt is important to keep the configmap up-to-date with your KaaS offering. This is automated e.g.\nin the KaaS mock service below."]}),"\n",(0,a.jsx)(n.h2,{id:"kaas-mock-service",children:"KaaS mock service"}),"\n",(0,a.jsx)(n.p,{children:"To evaluate the Monitoring of the KaaS layer use case and view actual metrics in your\nObserver monitoring cluster, you can launch the KaaS mock service."}),"\n",(0,a.jsxs)(n.p,{children:["Put your Observer monitoring cluster kubeconfig into the ",(0,a.jsx)(n.code,{children:"./kaas/manifests/"})," directory and name\nit ",(0,a.jsx)(n.code,{children:"observer-kubeconfig.yaml"})," (or adjust kaas service ",(0,a.jsx)(n.code,{children:"./kaas/app/config.py"})," accordingly)."]}),"\n",(0,a.jsx)(n.p,{children:"If you're utilizing the KinD Observer deployment outlined in this tutorial, collect the kubeconfig using the following command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kind get kubeconfig --name observer > ./kaas/manifests/observer-kubeconfig.yaml\n"})}),"\n",(0,a.jsxs)(n.p,{children:["All KaaS mock service dependencies can be installed via the corresponding ",(0,a.jsx)(n.code,{children:"./kaas/requirements.txt"})," file.\nInstalling them into a Python virtualenv is recommended."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd kaas\npython3 -m venv .venv # Optional\nsource .venv/bin/activate # Optional\n# Install kaas dependencies\npip install -r requirements.txt\n\n# Launch the KaaS mock service\nmake kaas\n"})}),"\n",(0,a.jsx)(n.p,{children:"At this point, you should have the ability to access the KaaS mock service Swagger UI:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"http://127.0.0.1:8080/kaas\n"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Create KaaS cluster through Swagger UI: ",(0,a.jsx)(n.a,{href:"http://127.0.0.1:8080/kaas#/Clusters/create_cluster_api_clusters__post",children:"Create Cluster"})," or\ncall directly the KaaS service API via some client, e.g.:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'curl -X POST -H "Content-Type: application/json" http://127.0.0.1:8080/api/clusters/ -d \'{"name": "kaas"}\'\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Navigate to the ",(0,a.jsx)(n.a,{href:"http://localhost:30000/d/kaas-monitoring/kaas-monitoring",children:"KaaS Monitoring dashboard"}),"\nin the Observer monitoring. After a few minutes (approximately 4), your KaaS cluster should become visible.\nClick on the cluster box to dive into KaaS cluster dashboards at a more detailed level.\nRepeat the process to explore further and gain deeper insights."]}),"\n",(0,a.jsx)(n.p,{children:"Note: The disk utilization expression for the Docker environment has not been adjusted,\nso you will encounter non-realistic numbers in the nodes/disk sections. However,\nthe other sections should accurately reflect the reality."}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Retrieve a list of all KaaS clusters and check their status. Swagger UI: ",(0,a.jsx)(n.a,{href:"http://127.0.0.1:8080/kaas#/Clusters/get_clusters_api_clusters__get",children:"Get List of Clusters"})," or\ncall directly the KaaS service API via some client, e.g.:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"curl -s -X GET -H 'accept: application/json' http://127.0.0.1:8080/api/clusters/\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Get Kaas Cluster kubeconfig by its name through Swagger UI: ",(0,a.jsx)(n.a,{href:"http://127.0.0.1:8080/kaas#/Clusters/get_kubeconfig_api_clusters__name__get",children:"Get Cluster kubeconfig"})," or\ncall directly the KaaS service API via some client and save it, e.g.:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"curl -s -X GET -H 'accept: application/json' http://127.0.0.1:8080/api/clusters/kaas > kaas-kube\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:"Now, you have the opportunity to play with your KaaS cluster and experiment with triggering\nmonitoring alerts by initiating actions like destroying certain components \ud83d\ude0e."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"kubectl --kubeconfig kaas-kube get po -A\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:["Finally, delete your KaaS cluster by its name through Swagger UI: ",(0,a.jsx)(n.a,{href:"http://127.0.0.1:8080/kaas#/Clusters/delete_cluster_api_clusters__delete",children:"Delete Cluster"})," or\ncall directly the KaaS service API via some client and save it, e.g.:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"curl -X DELETE http://127.0.0.1:8080/api/clusters/?name=kaas\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2d3bf848.b2f53ccd.js b/assets/js/2d3bf848.b2f53ccd.js new file mode 100644 index 0000000000..b574512b47 --- /dev/null +++ b/assets/js/2d3bf848.b2f53ccd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1468],{71761:t=>{t.exports=JSON.parse('{"title":"Contribute to Docs","slug":"/category/contribute-to-docs","permalink":"/community/category/contribute-to-docs","navigation":{"previous":{"title":"Getting Started with Wavestack","permalink":"/community/cloud-resources/wavestack"},"next":{"title":"Adding Docs Guide","permalink":"/community/contribute/adding-docs-guide"}}}')}}]); \ No newline at end of file diff --git a/assets/js/2ee7a08a.d998810b.js b/assets/js/2ee7a08a.d998810b.js new file mode 100644 index 0000000000..8861da3e10 --- /dev/null +++ b/assets/js/2ee7a08a.d998810b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5658],{87815:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var s=n(74848),i=n(28453);const a={},r="Cluster API",o={id:"iaas/guides/concept-guide/components/clusterapi",title:"Cluster API",description:"Kubernetes as a Service (KaaS) is a cloud service model that simplifies the deployment,",source:"@site/docs/02-iaas/guides/concept-guide/components/clusterapi.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/clusterapi",permalink:"/docs/iaas/guides/concept-guide/components/clusterapi",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/clusterapi.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Ceph",permalink:"/docs/iaas/guides/concept-guide/components/ceph"},next:{title:"Gardener",permalink:"/docs/iaas/guides/concept-guide/components/gardener"}},c={},l=[{value:"Lifecycle Management of Cluster API in OSISM",id:"lifecycle-management-of-cluster-api-in-osism",level:2},{value:"Cluster API with OpenStack Magnum",id:"cluster-api-with-openstack-magnum",level:3},{value:"Cluster API with SCS Cluster Stacks",id:"cluster-api-with-scs-cluster-stacks",level:3}];function u(e){const t={h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"cluster-api",children:"Cluster API"}),"\n",(0,s.jsx)(t.p,{children:"Kubernetes as a Service (KaaS) is a cloud service model that simplifies the deployment,\nmanagement and scaling of Kubernetes clusters. By abstracting the underlying infrastructure,\nKaaS allows organisations to focus on developing and deploying applications without the\ncomplexities of cluster management. One of the most powerful tools for implementing KaaS\nis the Cluster API, an official Kubernetes project that provides declarative APIs and tools\nfor managing the lifecycle of Kubernetes clusters."}),"\n",(0,s.jsx)(t.p,{children:"Key benefits of Cluster API include:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Declarative Cluster Management: Cluster API allows users to define the desired state of\nclusters using YAML manifests. This declarative approach simplifies the process of creating,\nupdating, and deleting clusters, making it easier to automate and version control cluster\nconfigurations."}),"\n",(0,s.jsx)(t.li,{children:"Infrastructure Abstraction: Cluster API abstracts the underlying infrastructure, enabling\nthe deployment of Kubernetes clusters across various environments, including public clouds\n(AWS, Azure, GCP), private clouds (OpenStack), and on-premises data centers. This abstraction\nensures that the same API can be used regardless of the infrastructure provider."}),"\n",(0,s.jsx)(t.li,{children:"Consistent Lifecycle Management: Cluster API standardizes the lifecycle management of\nKubernetes clusters, including provisioning, scaling, upgrading, and deletion. This consistency\nreduces operational overhead and ensures that clusters are managed uniformly across different\nenvironments."}),"\n",(0,s.jsx)(t.li,{children:"Extensibility and Customization: Cluster API\u2019s modular architecture allows for extensibility\nthrough the use of custom resource definitions (CRDs) and controllers. Organizations can tailor\nthe API to meet specific requirements, such as integrating with existing CI/CD pipelines or\nadding custom operational logic."}),"\n",(0,s.jsx)(t.li,{children:"Improved Operational Efficiency: By leveraging Cluster API, organizations can automate repetitive\ntasks, reduce human error, and ensure that clusters are configured according to best practices.\nThis automation leads to increased operational efficiency and faster delivery of applications."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"By using Kubernetes as a Service with Cluster API, organisations can achieve a highly automated,\nscalable and consistent approach to managing Kubernetes clusters across different environments.\nThis allows them to focus more on application development, and less on the operational\ncomplexities of managing Kubernetes infrastructure."}),"\n",(0,s.jsx)(t.h2,{id:"lifecycle-management-of-cluster-api-in-osism",children:"Lifecycle Management of Cluster API in OSISM"}),"\n",(0,s.jsx)(t.h3,{id:"cluster-api-with-openstack-magnum",children:"Cluster API with OpenStack Magnum"}),"\n",(0,s.jsx)(t.h3,{id:"cluster-api-with-scs-cluster-stacks",children:"Cluster API with SCS Cluster Stacks"})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const i={},a=s.createContext(i);function r(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/306a8c6c.152a5819.js b/assets/js/306a8c6c.152a5819.js new file mode 100644 index 0000000000..47aa3e98b9 --- /dev/null +++ b/assets/js/306a8c6c.152a5819.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3867],{8482:e=>{e.exports=JSON.parse('{"pluginId":"community","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"community":[{"type":"link","label":"Overview","href":"/community/","docId":"index","unlisted":false},{"type":"link","label":"Mission Statement","href":"/community/mission-statement","docId":"mission-statement","unlisted":false},{"type":"category","label":"Collaboration","items":[{"type":"link","label":"Team Iaas","href":"/community/collaboration/team-iaas","docId":"collaboration/team-iaas","unlisted":false},{"type":"link","label":"Team IAM","href":"/community/collaboration/team-iam","docId":"collaboration/team-iam","unlisted":false},{"type":"link","label":"Team Container","href":"/community/collaboration/team-container","docId":"collaboration/team-container","unlisted":false},{"type":"link","label":"Team Ops","href":"/community/collaboration/team-ops","docId":"collaboration/team-ops","unlisted":false},{"type":"link","label":"SIG Central API","href":"/community/collaboration/sig-central-api","docId":"collaboration/sig-central-api","unlisted":false},{"type":"link","label":"SIG Community","href":"/community/collaboration/sig-community","docId":"collaboration/sig-community","unlisted":false},{"type":"link","label":"SIG Documentation","href":"/community/collaboration/sig-documentation","docId":"collaboration/sig-documentation","unlisted":false},{"type":"link","label":"SIG Monitoring","href":"/community/collaboration/sig-monitoring","docId":"collaboration/sig-monitoring","unlisted":false},{"type":"link","label":"SIG Standardization","href":"/community/collaboration/sig-standardization","docId":"collaboration/sig-standardization","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/community/collaboration/"},{"type":"category","label":"Tools","items":[{"type":"link","label":"Jitsi","href":"/community/tools/jitsi","docId":"tools/jitsi","unlisted":false},{"type":"link","label":"Matrix","href":"/community/tools/matrix","docId":"tools/matrix","unlisted":false},{"type":"link","label":"Mailing Lists","href":"/community/tools/mailinglists","docId":"tools/mailinglists","unlisted":false},{"type":"link","label":"Nextcloud","href":"/community/tools/nextcloud","docId":"tools/nextcloud","unlisted":false},{"type":"link","label":"Zuul","href":"/community/tools/zuul","docId":"tools/zuul","unlisted":false},{"type":"category","label":"GitHub","items":[{"type":"link","label":"Branch Protection Rules","href":"/community/tools/github/branchprotection","docId":"tools/github/branchprotection","unlisted":false},{"type":"link","label":"Developer Certificate of Origin + Licenses","href":"/community/tools/github/dco-and-licenses","docId":"tools/github/dco-and-licenses","unlisted":false},{"type":"link","label":"Tips and Tricks","href":"/community/tools/github/tips-and-tricks","docId":"tools/github/tips-and-tricks","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Cloud Resources","items":[{"type":"link","label":"Test and development cloud resources","href":"/community/cloud-resources/","docId":"cloud-resources/cloud-resources","unlisted":false},{"type":"link","label":"Getting Started with OpenStack","href":"/community/cloud-resources/getting-started-openstack","docId":"cloud-resources/getting-started-openstack","unlisted":false},{"type":"link","label":"Getting Started Gaia-X Demonstrator @ plusserver","href":"/community/cloud-resources/plusserver-gx-scs","docId":"cloud-resources/plusserver-gx-scs","unlisted":false},{"type":"link","label":"Getting Started with Wavestack","href":"/community/cloud-resources/wavestack","docId":"cloud-resources/wavestack","unlisted":false}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true,"href":"/community/category/tools"},{"type":"category","label":"Contribute to Docs","items":[{"type":"link","label":"Adding Docs Guide","href":"/community/contribute/adding-docs-guide","docId":"contribute/adding-docs-guide","unlisted":false},{"type":"link","label":"Documentation Files Structure","href":"/community/contribute/doc-files-structure-guide","docId":"contribute/doc-files-structure-guide","unlisted":false},{"type":"link","label":"Documentation workflow explanation","href":"/community/contribute/docs-workflow-explanation","docId":"contribute/docs-workflow-explanation","unlisted":false},{"type":"link","label":"Linting Guide","href":"/community/contribute/linting-guide","docId":"contribute/linting-guide","unlisted":false},{"type":"link","label":"Installation","href":"/community/contribute/local-docusaurus-development-guide","docId":"contribute/local-docusaurus-development-guide","unlisted":false},{"type":"link","label":"Styleguide","href":"/community/contribute/styleguide","docId":"contribute/styleguide","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/community/category/contribute-to-docs"}]},"docs":{"central-services/plusserver-gx-scs":{"id":"central-services/plusserver-gx-scs","title":"Central services","description":"This document gives an overview of what SCS central services are deployed and who is responsible for them in plusserver gx-scs infrastructure."},"cloud-resources/cloud-resources":{"id":"cloud-resources/cloud-resources","title":"Test and development cloud resources","description":"This document gives an overview of the test and development cloud resources currently provided by our partners.","sidebar":"community"},"cloud-resources/getting-started-openstack":{"id":"cloud-resources/getting-started-openstack","title":"Getting Started with OpenStack","description":"Getting Started with OpenStack CLI","sidebar":"community"},"cloud-resources/plusserver-gx-scs":{"id":"cloud-resources/plusserver-gx-scs","title":"Getting Started Gaia-X Demonstrator @ plusserver","description":"Getting Started for the Gaia-X Demonstrator @ plusserver","sidebar":"community"},"cloud-resources/wavestack":{"id":"cloud-resources/wavestack","title":"Getting Started with Wavestack","description":"Getting Started with Wavestack","sidebar":"community"},"collaboration/index":{"id":"collaboration/index","title":"Collaboration","description":"We\u2019re an open community","sidebar":"community"},"collaboration/sig-central-api":{"id":"collaboration/sig-central-api","title":"SIG Central API","description":"For defining a Common and Central interface for the Customers of SCS cloud to manage the Infrastructure cloud resources open stack and Kubernetes and identity and Access management.","sidebar":"community"},"collaboration/sig-community":{"id":"collaboration/sig-community","title":"SIG Community","description":"In this meeting, we come together to shape our community strategy and coordinate collaborative efforts within our community. Our goal is to cultivate an open and welcoming community where we can share the message of SCS. We plan engaging community events, strive to make this open-source community even more inclusive, and aim to keep it informative, inspiring, and captivating. We warmly invite you to join us in our mission and become a part of this exciting journey!","sidebar":"community"},"collaboration/sig-documentation":{"id":"collaboration/sig-documentation","title":"SIG Documentation","description":"We curate and enhance the SCS Documentation, focusing on refining its information architecture for optimal usability. Our objective is to facilitate straightforward contributions from community developers and to provide operators with a clear, quick reference guide that accelerates the initiation of an SCS deployment.","sidebar":"community"},"collaboration/sig-monitoring":{"id":"collaboration/sig-monitoring","title":"SIG Monitoring","description":"The Special Interest Group (SIG) Monitoring meets on a fortnightly base (alternating with the audit log WG) to discuss the monitoring needs of SCS Operators, Users and Integrators. Together we shape how monitoring and observability within the SCS landscape looks like.","sidebar":"community"},"collaboration/sig-standardization":{"id":"collaboration/sig-standardization","title":"SIG Standardization","description":"In this Special Interest Group, we discuss and align our activities and approach to standardization and certification. That is to say, we devise and refine the relevant concepts and processes; we work on a roadmap for new certificate versions; and we align on which standards are desireable for each certificate subject. We then work with the teams to align on existing or new standards.","sidebar":"community"},"collaboration/team-container":{"id":"collaboration/team-container","title":"Team Container","description":"The Team Container deals with all topics around Containers and Kubernetes.","sidebar":"community"},"collaboration/team-iaas":{"id":"collaboration/team-iaas","title":"Team Iaas","description":"We build the reference implementation of the IaaS parts of SCS that informs and adheres to the SCS IaaS standards.","sidebar":"community"},"collaboration/team-iam":{"id":"collaboration/team-iam","title":"Team IAM","description":"The Team IAM deals with topics around Identity and Access Management.","sidebar":"community"},"collaboration/team-ops":{"id":"collaboration/team-ops","title":"Team Ops","description":"We build tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.","sidebar":"community"},"contribute/adding-docs-guide":{"id":"contribute/adding-docs-guide","title":"Adding Docs Guide","description":"In this Guide you will learn how to integrate your documentation to the SCS documentation, which you will find on docs.scs.community.","sidebar":"community"},"contribute/doc-files-structure-guide":{"id":"contribute/doc-files-structure-guide","title":"Documentation Files Structure","description":"Structure Best Practice","sidebar":"community"},"contribute/docs-workflow-explanation":{"id":"contribute/docs-workflow-explanation","title":"Documentation workflow explanation","description":"The aim within this documentation is to have a good developer experience and a low entry barrier to start with SCS. For this to achieve we think all docs that define the SCS stack and have been developed by the SCS community should be within this documentation framework.","sidebar":"community"},"contribute/linting-guide":{"id":"contribute/linting-guide","title":"Linting Guide","description":"In order to have a clean content repository regarding all markdown files we enforce linting on:","sidebar":"community"},"contribute/local-docusaurus-development-guide":{"id":"contribute/local-docusaurus-development-guide","title":"Installation","description":"This Guide shows you how to setup docusaurus on your local machine to run this docs in your local development enviroment.","sidebar":"community"},"contribute/styleguide":{"id":"contribute/styleguide","title":"Styleguide","description":"Admonitions","sidebar":"community"},"contribute/styleguides/ansible_styleguide":{"id":"contribute/styleguides/ansible_styleguide","title":"Ansible Style Guide","description":"We use nearly all default rules of ansible lint. A listing of all these rules can be found in the Ansible Lint documentation:"},"hackathons/checklist":{"id":"hackathons/checklist","title":"Hackathon planning checklist","description":"This checklist is designed to simplify the planning of hackathons and meetups. All items are suggestions and optionally adaptable"},"index":{"id":"index","title":"Overview","description":"Welcome to our SCS Community","sidebar":"community"},"license-considerations":{"id":"license-considerations","title":"License considerations for SCS","description":"As Sovereign Cloud Stack (SCS), our mission is to provide Operators"},"mission-statement":{"id":"mission-statement","title":"Mission Statement","description":"Sovereign Cloud Stack (SCS) offers more than just a software stack \u2014 it\'s the embodiment of a collaborative open-source spirit, united by the aim of achieving digital sovereignty. At the heart of this initiative is a foundational pillar: the community.","sidebar":"community"},"tools/github/branchprotection":{"id":"tools/github/branchprotection","title":"Branch Protection Rules","description":"To protect our source code from unwanted changes, we enforce the following branch protection rules for all repositories within our GitHub organization:","sidebar":"community"},"tools/github/dco-and-licenses":{"id":"tools/github/dco-and-licenses","title":"Developer Certificate of Origin + Licenses","description":"The Developer Certificate of Origin (DCO) is a lightweight way for contributors","sidebar":"community"},"tools/github/tips-and-tricks":{"id":"tools/github/tips-and-tricks","title":"Tips and Tricks","description":"Octo Reminder - your friendly assistant","sidebar":"community"},"tools/jitsi":{"id":"tools/jitsi","title":"Jitsi","description":"We use a self-hosted Jitsi Meet instance for video conferencing.","sidebar":"community"},"tools/mailinglists":{"id":"tools/mailinglists","title":"Mailing Lists","description":"We have an announcements mailing list there announce@lists.scs.community and you","sidebar":"community"},"tools/matrix":{"id":"tools/matrix","title":"Matrix","description":"We have created an open community space on the Matrix federation. Feel free to join the several channels and start chatting with our community. A good starting point is entering the General & Announcements and the Tech channel.","sidebar":"community"},"tools/nextcloud":{"id":"tools/nextcloud","title":"Nextcloud","description":"We have a Nextcloud","sidebar":"community"},"tools/zuul":{"id":"tools/zuul","title":"Zuul","description":"Zuul CI/CD pipelines and project gating","sidebar":"community"}}}')}}]); \ No newline at end of file diff --git a/assets/js/307.a785f6d3.js b/assets/js/307.a785f6d3.js new file mode 100644 index 0000000000..308773d8b4 --- /dev/null +++ b/assets/js/307.a785f6d3.js @@ -0,0 +1,10065 @@ +"use strict"; +exports.id = 307; +exports.ids = [307]; +exports.modules = { + +/***/ 21176: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Zp: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(5664); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(74722); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(91395); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(697); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.A(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.A( + map/* default */.A(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.A(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.A(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.T(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.A(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.A(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.A(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.A(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.A(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.A('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.A(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.A(g.outEdges(v), function (e) { + if (has/* default */.A(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.A(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.A(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(98879); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(81942); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(23068); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.A)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(52528); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.A)(iteratee, 3); + + (0,_baseForOwn/* default */.A)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.A)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(41917); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.A.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.A(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.T().setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.T({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.A(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.A(range/* default */.A(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.A(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.A(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.A(layers, function (vs, i) { + if (isUndefined/* default */.A(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.A(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.A(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.A(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.A(children, dfs); + } + + if (has/* default */.A(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.A(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.A(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, reverseYOne); + if (has/* default */.A(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, swapXYOne); + if (has/* default */.A(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.A(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.A)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.A(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.A(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.A(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.T({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.A(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.A(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.A(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.A)(collection)) { + var iteratee = (0,_baseIteratee/* default */.A)(predicate, 3); + collection = (0,keys/* default */.A)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.A)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.A)(array, (0,_baseIteratee/* default */.A)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(69471); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(88496); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.A)(value) && (0,isObjectLike/* default */.A)(value) && (0,_baseGetTag/* default */.A)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.A)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.A)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.A)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.A)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.A(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.A(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.A(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.A(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.A(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.A(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.A(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.A(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(73046); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.A(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.A(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.A(tree.neighbors(v), function (w) { + if (!has/* default */.A(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.A(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.A(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.A(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.A(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.A(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.A(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.A(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.A(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.A( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(91641); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.A)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.A(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.T({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.A(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.A(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.A(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.A('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.A); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(52568); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.A)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.A)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + if ((0,isArray/* default */.A)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.A)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.A]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.A)(iteratees, (0,_baseUnary/* default */.A)(_baseIteratee/* default */.A)); + + var result = (0,_baseMap/* default */.A)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.A)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.A)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.A)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.A)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.A(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.A( + map/* default */.A(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.A(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.A(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.A( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.A(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.A(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.A(range/* default */.A(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.A(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.A(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.A(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.A(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.A( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.A(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.A(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.A(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.A(entryV) && !isUndefined/* default */.A(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.A(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.A(uEntry.barycenter) || + isUndefined/* default */.A(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.A(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.A(entry.out, handleOut(entry)); + } + + return map/* default */.A( + filter/* default */.A(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.A(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.A(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.A(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.A(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.A(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.A(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.A(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.A([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.A(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.A(entries, function (entry) { + entry.vs = flatten/* default */.A( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.A(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.A(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.A(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.A(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.T(); + forEach/* default */.A(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.A(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.A(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.A(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(99922); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(4574); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee), keysIn/* default */.A); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.A(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.A(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.A(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.A(range/* default */.A(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.A(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.A(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.A(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.A(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.A(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.A(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.T(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.A(layering, function (layer) { + var u; + forEach/* default */.A(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.A(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.A(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.A(['u', 'd'], function (vert) { + forEach/* default */.A(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.A(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.A(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.A(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.A(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.A(layering).reverse(); + forEach/* default */.A(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.A(adjustedLayering, function (inner) { + return values/* default */.A(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.A(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.A(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.A(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.A(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.A(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.A(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.A(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.T({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.A({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.A(graph, graphAttrs)) + ); + + forEach/* default */.A(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.A(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.A({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.A(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.A(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.A(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.A(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.A(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.A(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.A(layers, function (layer) { + var orderShift = 0; + forEach/* default */.A(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.A(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.A(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.A(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 73046: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + T: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(89610); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(66401); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.A)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(39857); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.A && (1 / (0,_setToArray/* default */.A)(new _Set/* default */.A([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.A(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.A)(set); + } + isCommon = false; + includes = _cacheHas/* default */.A; + seen = new _SetCache/* default */.A; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(53533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.A)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.A)(arrays, 1, isArrayLikeObject/* default */.A, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.A(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.A(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.A(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.A(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.A(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.A(this._nodes); + } + sources() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.A(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.A(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.A(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.A(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.A(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.A(keys/* default */.A(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.A(keys/* default */.A(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.A(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.A(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.A(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.A(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.A(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.A(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.A(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.A(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.A(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.A(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.A(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.A(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.A(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.A(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.A(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.A(inV); + if (!u) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.A(outV); + if (!w) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.A(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 697: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ T: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.T) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 62062: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(29471); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.A; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 72641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 2634: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 45572: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 76912: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 91641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(72641); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(22031); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keys/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keysIn/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(80154); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(39759); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(14792); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.A)(source, (0,_getSymbols/* default */.A)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(15647); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(13153); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.A : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.A)(result, (0,_getSymbols/* default */.A)(object)); + object = (0,_getPrototype/* default */.A)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.A)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(33831); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.A)(object, keysIn/* default */.A, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(90565); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.A)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(1801); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.A)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.A)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(18598); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(64841); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.A)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.A)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.A)(value)) { + return value; + } + var isArr = (0,isArray/* default */.A)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.A)(value, result); + } + } else { + var tag = (0,_getTag/* default */.A)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.A)(value)) { + return (0,_cloneBuffer/* default */.A)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.A)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.A); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.A) + : (isFlat ? keysIn/* default */.A : keys/* default */.A); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.A)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.A)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 6240: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.A)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.A); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 25707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 13588: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(52274); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.A ? _Symbol/* default */.A.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.A)(value) || (0,isArguments/* default */.A)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.A)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 79841: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4574); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 66318: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 33831: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76912); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 49574: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.A : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.A)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(43988); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(66984); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.A(object), new _Uint8Array/* default */.A(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.A)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.A); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.A)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.A)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(33858); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.A)(object), + othIsArr = (0,isArray/* default */.A)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.A)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.A)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.A)(object)) { + if (!(0,isBuffer/* default */.A)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.A); + return (objIsArr || (0,isTypedArray/* default */.A)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.A); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.A); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.A)(value) && !(0,isObjectLike/* default */.A)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.A; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.A)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.A)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.A)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.A)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.A)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.A)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.A)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.A)(path) ? (0,_baseProperty/* default */.A)((0,_toKey/* default */.A)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.A; + } + if (typeof value == 'object') { + return (0,isArray/* default */.A)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 52568: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6240); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 70805: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 64099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 99922: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(29008); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 7819: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(46632); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.A)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(28894); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.A)(value)) { + return value; + } + return (0,_isKey/* default */.A)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.A)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 19042: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33831); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14792); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 14792: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2634); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13153); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 85054: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(52274); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(92049); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25353); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5254); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 86586: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(61882); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 29959: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 30901: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61882); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 23068: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(24326); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66984); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6832); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55615); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 11662: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(2634); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.A)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.A)(collection) ? _arrayFilter/* default */.A : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.A)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 34098: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13588); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 8058: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72641); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6240); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99922); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 48585: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 39188: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 61882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(88496); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(53098); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 69592: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 27422: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(83607); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69471); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 74722: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(45572); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49574); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(52568); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 81942: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(7819); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(25353); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.A)(object)) { + return object; + } + path = (0,_castPath/* default */.A)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.A)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.A)(objValue) + ? objValue + : ((0,_isIndex/* default */.A)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.A)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.A)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.A)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.A)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(76875); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(67525); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.A)((0,_overRest/* default */.A)(func, undefined, flatten/* default */.A), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 91395: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.A)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.A)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.A)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.A)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 89463: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.A)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.A)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.A); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 13153: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 74342: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.A)(value)) { + return NAN; + } + if ((0,isObject/* default */.A)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.A)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 28894: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.A)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.A)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.A)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 5664: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28894); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 38207: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.A)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.A)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 39688: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(21176); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(697); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(99418); + + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 3], $V1 = [1, 4], $V2 = [1, 5], $V3 = [1, 6], $V4 = [5, 6, 8, 9, 11, 13, 31, 32, 33, 34, 35, 36, 44, 62, 63], $V5 = [1, 18], $V6 = [2, 7], $V7 = [1, 22], $V8 = [1, 23], $V9 = [1, 24], $Va = [1, 25], $Vb = [1, 26], $Vc = [1, 27], $Vd = [1, 20], $Ve = [1, 28], $Vf = [1, 29], $Vg = [62, 63], $Vh = [5, 8, 9, 11, 13, 31, 32, 33, 34, 35, 36, 44, 51, 53, 62, 63], $Vi = [1, 47], $Vj = [1, 48], $Vk = [1, 49], $Vl = [1, 50], $Vm = [1, 51], $Vn = [1, 52], $Vo = [1, 53], $Vp = [53, 54], $Vq = [1, 64], $Vr = [1, 60], $Vs = [1, 61], $Vt = [1, 62], $Vu = [1, 63], $Vv = [1, 65], $Vw = [1, 69], $Vx = [1, 70], $Vy = [1, 67], $Vz = [1, 68], $VA = [5, 8, 9, 11, 13, 31, 32, 33, 34, 35, 36, 44, 62, 63]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "directive": 4, "NEWLINE": 5, "RD": 6, "diagram": 7, "EOF": 8, "acc_title": 9, "acc_title_value": 10, "acc_descr": 11, "acc_descr_value": 12, "acc_descr_multiline_value": 13, "requirementDef": 14, "elementDef": 15, "relationshipDef": 16, "requirementType": 17, "requirementName": 18, "STRUCT_START": 19, "requirementBody": 20, "ID": 21, "COLONSEP": 22, "id": 23, "TEXT": 24, "text": 25, "RISK": 26, "riskLevel": 27, "VERIFYMTHD": 28, "verifyType": 29, "STRUCT_STOP": 30, "REQUIREMENT": 31, "FUNCTIONAL_REQUIREMENT": 32, "INTERFACE_REQUIREMENT": 33, "PERFORMANCE_REQUIREMENT": 34, "PHYSICAL_REQUIREMENT": 35, "DESIGN_CONSTRAINT": 36, "LOW_RISK": 37, "MED_RISK": 38, "HIGH_RISK": 39, "VERIFY_ANALYSIS": 40, "VERIFY_DEMONSTRATION": 41, "VERIFY_INSPECTION": 42, "VERIFY_TEST": 43, "ELEMENT": 44, "elementName": 45, "elementBody": 46, "TYPE": 47, "type": 48, "DOCREF": 49, "ref": 50, "END_ARROW_L": 51, "relationship": 52, "LINE": 53, "END_ARROW_R": 54, "CONTAINS": 55, "COPIES": 56, "DERIVES": 57, "SATISFIES": 58, "VERIFIES": 59, "REFINES": 60, "TRACES": 61, "unqString": 62, "qString": 63, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 5: "NEWLINE", 6: "RD", 8: "EOF", 9: "acc_title", 10: "acc_title_value", 11: "acc_descr", 12: "acc_descr_value", 13: "acc_descr_multiline_value", 19: "STRUCT_START", 21: "ID", 22: "COLONSEP", 24: "TEXT", 26: "RISK", 28: "VERIFYMTHD", 30: "STRUCT_STOP", 31: "REQUIREMENT", 32: "FUNCTIONAL_REQUIREMENT", 33: "INTERFACE_REQUIREMENT", 34: "PERFORMANCE_REQUIREMENT", 35: "PHYSICAL_REQUIREMENT", 36: "DESIGN_CONSTRAINT", 37: "LOW_RISK", 38: "MED_RISK", 39: "HIGH_RISK", 40: "VERIFY_ANALYSIS", 41: "VERIFY_DEMONSTRATION", 42: "VERIFY_INSPECTION", 43: "VERIFY_TEST", 44: "ELEMENT", 47: "TYPE", 49: "DOCREF", 51: "END_ARROW_L", 53: "LINE", 54: "END_ARROW_R", 55: "CONTAINS", 56: "COPIES", 57: "DERIVES", 58: "SATISFIES", 59: "VERIFIES", 60: "REFINES", 61: "TRACES", 62: "unqString", 63: "qString" }, + productions_: [0, [3, 3], [3, 2], [3, 4], [4, 2], [4, 2], [4, 1], [7, 0], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [14, 5], [20, 5], [20, 5], [20, 5], [20, 5], [20, 2], [20, 1], [17, 1], [17, 1], [17, 1], [17, 1], [17, 1], [17, 1], [27, 1], [27, 1], [27, 1], [29, 1], [29, 1], [29, 1], [29, 1], [15, 5], [46, 5], [46, 5], [46, 2], [46, 1], [16, 5], [16, 5], [52, 1], [52, 1], [52, 1], [52, 1], [52, 1], [52, 1], [52, 1], [18, 1], [18, 1], [23, 1], [23, 1], [25, 1], [25, 1], [45, 1], [45, 1], [48, 1], [48, 1], [50, 1], [50, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 4: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 5: + case 6: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 7: + this.$ = []; + break; + case 13: + yy.addRequirement($$[$0 - 3], $$[$0 - 4]); + break; + case 14: + yy.setNewReqId($$[$0 - 2]); + break; + case 15: + yy.setNewReqText($$[$0 - 2]); + break; + case 16: + yy.setNewReqRisk($$[$0 - 2]); + break; + case 17: + yy.setNewReqVerifyMethod($$[$0 - 2]); + break; + case 20: + this.$ = yy.RequirementType.REQUIREMENT; + break; + case 21: + this.$ = yy.RequirementType.FUNCTIONAL_REQUIREMENT; + break; + case 22: + this.$ = yy.RequirementType.INTERFACE_REQUIREMENT; + break; + case 23: + this.$ = yy.RequirementType.PERFORMANCE_REQUIREMENT; + break; + case 24: + this.$ = yy.RequirementType.PHYSICAL_REQUIREMENT; + break; + case 25: + this.$ = yy.RequirementType.DESIGN_CONSTRAINT; + break; + case 26: + this.$ = yy.RiskLevel.LOW_RISK; + break; + case 27: + this.$ = yy.RiskLevel.MED_RISK; + break; + case 28: + this.$ = yy.RiskLevel.HIGH_RISK; + break; + case 29: + this.$ = yy.VerifyType.VERIFY_ANALYSIS; + break; + case 30: + this.$ = yy.VerifyType.VERIFY_DEMONSTRATION; + break; + case 31: + this.$ = yy.VerifyType.VERIFY_INSPECTION; + break; + case 32: + this.$ = yy.VerifyType.VERIFY_TEST; + break; + case 33: + yy.addElement($$[$0 - 3]); + break; + case 34: + yy.setNewElementType($$[$0 - 2]); + break; + case 35: + yy.setNewElementDocRef($$[$0 - 2]); + break; + case 38: + yy.addRelationship($$[$0 - 2], $$[$0], $$[$0 - 4]); + break; + case 39: + yy.addRelationship($$[$0 - 2], $$[$0 - 4], $$[$0]); + break; + case 40: + this.$ = yy.Relationships.CONTAINS; + break; + case 41: + this.$ = yy.Relationships.COPIES; + break; + case 42: + this.$ = yy.Relationships.DERIVES; + break; + case 43: + this.$ = yy.Relationships.SATISFIES; + break; + case 44: + this.$ = yy.Relationships.VERIFIES; + break; + case 45: + this.$ = yy.Relationships.REFINES; + break; + case 46: + this.$ = yy.Relationships.TRACES; + break; + } + }, + table: [{ 3: 1, 4: 2, 6: $V0, 9: $V1, 11: $V2, 13: $V3 }, { 1: [3] }, { 3: 8, 4: 2, 5: [1, 7], 6: $V0, 9: $V1, 11: $V2, 13: $V3 }, { 5: [1, 9] }, { 10: [1, 10] }, { 12: [1, 11] }, o($V4, [2, 6]), { 3: 12, 4: 2, 6: $V0, 9: $V1, 11: $V2, 13: $V3 }, { 1: [2, 2] }, { 4: 17, 5: $V5, 7: 13, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, o($V4, [2, 4]), o($V4, [2, 5]), { 1: [2, 1] }, { 8: [1, 30] }, { 4: 17, 5: $V5, 7: 31, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 4: 17, 5: $V5, 7: 32, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 4: 17, 5: $V5, 7: 33, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 4: 17, 5: $V5, 7: 34, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 4: 17, 5: $V5, 7: 35, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 18: 36, 62: [1, 37], 63: [1, 38] }, { 45: 39, 62: [1, 40], 63: [1, 41] }, { 51: [1, 42], 53: [1, 43] }, o($Vg, [2, 20]), o($Vg, [2, 21]), o($Vg, [2, 22]), o($Vg, [2, 23]), o($Vg, [2, 24]), o($Vg, [2, 25]), o($Vh, [2, 49]), o($Vh, [2, 50]), { 1: [2, 3] }, { 8: [2, 8] }, { 8: [2, 9] }, { 8: [2, 10] }, { 8: [2, 11] }, { 8: [2, 12] }, { 19: [1, 44] }, { 19: [2, 47] }, { 19: [2, 48] }, { 19: [1, 45] }, { 19: [2, 53] }, { 19: [2, 54] }, { 52: 46, 55: $Vi, 56: $Vj, 57: $Vk, 58: $Vl, 59: $Vm, 60: $Vn, 61: $Vo }, { 52: 54, 55: $Vi, 56: $Vj, 57: $Vk, 58: $Vl, 59: $Vm, 60: $Vn, 61: $Vo }, { 5: [1, 55] }, { 5: [1, 56] }, { 53: [1, 57] }, o($Vp, [2, 40]), o($Vp, [2, 41]), o($Vp, [2, 42]), o($Vp, [2, 43]), o($Vp, [2, 44]), o($Vp, [2, 45]), o($Vp, [2, 46]), { 54: [1, 58] }, { 5: $Vq, 20: 59, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vw, 30: $Vx, 46: 66, 47: $Vy, 49: $Vz }, { 23: 71, 62: $Ve, 63: $Vf }, { 23: 72, 62: $Ve, 63: $Vf }, o($VA, [2, 13]), { 22: [1, 73] }, { 22: [1, 74] }, { 22: [1, 75] }, { 22: [1, 76] }, { 5: $Vq, 20: 77, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, o($VA, [2, 19]), o($VA, [2, 33]), { 22: [1, 78] }, { 22: [1, 79] }, { 5: $Vw, 30: $Vx, 46: 80, 47: $Vy, 49: $Vz }, o($VA, [2, 37]), o($VA, [2, 38]), o($VA, [2, 39]), { 23: 81, 62: $Ve, 63: $Vf }, { 25: 82, 62: [1, 83], 63: [1, 84] }, { 27: 85, 37: [1, 86], 38: [1, 87], 39: [1, 88] }, { 29: 89, 40: [1, 90], 41: [1, 91], 42: [1, 92], 43: [1, 93] }, o($VA, [2, 18]), { 48: 94, 62: [1, 95], 63: [1, 96] }, { 50: 97, 62: [1, 98], 63: [1, 99] }, o($VA, [2, 36]), { 5: [1, 100] }, { 5: [1, 101] }, { 5: [2, 51] }, { 5: [2, 52] }, { 5: [1, 102] }, { 5: [2, 26] }, { 5: [2, 27] }, { 5: [2, 28] }, { 5: [1, 103] }, { 5: [2, 29] }, { 5: [2, 30] }, { 5: [2, 31] }, { 5: [2, 32] }, { 5: [1, 104] }, { 5: [2, 55] }, { 5: [2, 56] }, { 5: [1, 105] }, { 5: [2, 57] }, { 5: [2, 58] }, { 5: $Vq, 20: 106, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vq, 20: 107, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vq, 20: 108, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vq, 20: 109, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vw, 30: $Vx, 46: 110, 47: $Vy, 49: $Vz }, { 5: $Vw, 30: $Vx, 46: 111, 47: $Vy, 49: $Vz }, o($VA, [2, 14]), o($VA, [2, 15]), o($VA, [2, 16]), o($VA, [2, 17]), o($VA, [2, 34]), o($VA, [2, 35])], + defaultActions: { 8: [2, 2], 12: [2, 1], 30: [2, 3], 31: [2, 8], 32: [2, 9], 33: [2, 10], 34: [2, 11], 35: [2, 12], 37: [2, 47], 38: [2, 48], 40: [2, 53], 41: [2, 54], 83: [2, 51], 84: [2, 52], 86: [2, 26], 87: [2, 27], 88: [2, 28], 90: [2, 29], 91: [2, 30], 92: [2, 31], 93: [2, 32], 95: [2, 55], 96: [2, 56], 98: [2, 57], 99: [2, 58] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return "title"; + case 1: + this.begin("acc_title"); + return 9; + case 2: + this.popState(); + return "acc_title_value"; + case 3: + this.begin("acc_descr"); + return 11; + case 4: + this.popState(); + return "acc_descr_value"; + case 5: + this.begin("acc_descr_multiline"); + break; + case 6: + this.popState(); + break; + case 7: + return "acc_descr_multiline_value"; + case 8: + return 5; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + return 8; + case 13: + return 6; + case 14: + return 19; + case 15: + return 30; + case 16: + return 22; + case 17: + return 21; + case 18: + return 24; + case 19: + return 26; + case 20: + return 28; + case 21: + return 31; + case 22: + return 32; + case 23: + return 33; + case 24: + return 34; + case 25: + return 35; + case 26: + return 36; + case 27: + return 37; + case 28: + return 38; + case 29: + return 39; + case 30: + return 40; + case 31: + return 41; + case 32: + return 42; + case 33: + return 43; + case 34: + return 44; + case 35: + return 55; + case 36: + return 56; + case 37: + return 57; + case 38: + return 58; + case 39: + return 59; + case 40: + return 60; + case 41: + return 61; + case 42: + return 47; + case 43: + return 49; + case 44: + return 51; + case 45: + return 54; + case 46: + return 53; + case 47: + this.begin("string"); + break; + case 48: + this.popState(); + break; + case 49: + return "qString"; + case 50: + yy_.yytext = yy_.yytext.trim(); + return 62; + } + }, + rules: [/^(?:title\s[^#\n;]+)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:(\r?\n)+)/i, /^(?:\s+)/i, /^(?:#[^\n]*)/i, /^(?:%[^\n]*)/i, /^(?:$)/i, /^(?:requirementDiagram\b)/i, /^(?:\{)/i, /^(?:\})/i, /^(?::)/i, /^(?:id\b)/i, /^(?:text\b)/i, /^(?:risk\b)/i, /^(?:verifyMethod\b)/i, /^(?:requirement\b)/i, /^(?:functionalRequirement\b)/i, /^(?:interfaceRequirement\b)/i, /^(?:performanceRequirement\b)/i, /^(?:physicalRequirement\b)/i, /^(?:designConstraint\b)/i, /^(?:low\b)/i, /^(?:medium\b)/i, /^(?:high\b)/i, /^(?:analysis\b)/i, /^(?:demonstration\b)/i, /^(?:inspection\b)/i, /^(?:test\b)/i, /^(?:element\b)/i, /^(?:contains\b)/i, /^(?:copies\b)/i, /^(?:derives\b)/i, /^(?:satisfies\b)/i, /^(?:verifies\b)/i, /^(?:refines\b)/i, /^(?:traces\b)/i, /^(?:type\b)/i, /^(?:docref\b)/i, /^(?:<-)/i, /^(?:->)/i, /^(?:-)/i, /^(?:["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:[\w][^\r\n\{\<\>\-\=]*)/i], + conditions: { "acc_descr_multiline": { "rules": [6, 7], "inclusive": false }, "acc_descr": { "rules": [4], "inclusive": false }, "acc_title": { "rules": [2], "inclusive": false }, "unqString": { "rules": [], "inclusive": false }, "token": { "rules": [], "inclusive": false }, "string": { "rules": [48, 49], "inclusive": false }, "INITIAL": { "rules": [0, 1, 3, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 50], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let relations = []; +let latestRequirement = {}; +let requirements = {}; +let latestElement = {}; +let elements = {}; +const RequirementType = { + REQUIREMENT: "Requirement", + FUNCTIONAL_REQUIREMENT: "Functional Requirement", + INTERFACE_REQUIREMENT: "Interface Requirement", + PERFORMANCE_REQUIREMENT: "Performance Requirement", + PHYSICAL_REQUIREMENT: "Physical Requirement", + DESIGN_CONSTRAINT: "Design Constraint" +}; +const RiskLevel = { + LOW_RISK: "Low", + MED_RISK: "Medium", + HIGH_RISK: "High" +}; +const VerifyType = { + VERIFY_ANALYSIS: "Analysis", + VERIFY_DEMONSTRATION: "Demonstration", + VERIFY_INSPECTION: "Inspection", + VERIFY_TEST: "Test" +}; +const Relationships = { + CONTAINS: "contains", + COPIES: "copies", + DERIVES: "derives", + SATISFIES: "satisfies", + VERIFIES: "verifies", + REFINES: "refines", + TRACES: "traces" +}; +const addRequirement = (name, type) => { + if (requirements[name] === void 0) { + requirements[name] = { + name, + type, + id: latestRequirement.id, + text: latestRequirement.text, + risk: latestRequirement.risk, + verifyMethod: latestRequirement.verifyMethod + }; + } + latestRequirement = {}; + return requirements[name]; +}; +const getRequirements = () => requirements; +const setNewReqId = (id) => { + if (latestRequirement !== void 0) { + latestRequirement.id = id; + } +}; +const setNewReqText = (text) => { + if (latestRequirement !== void 0) { + latestRequirement.text = text; + } +}; +const setNewReqRisk = (risk) => { + if (latestRequirement !== void 0) { + latestRequirement.risk = risk; + } +}; +const setNewReqVerifyMethod = (verifyMethod) => { + if (latestRequirement !== void 0) { + latestRequirement.verifyMethod = verifyMethod; + } +}; +const addElement = (name) => { + if (elements[name] === void 0) { + elements[name] = { + name, + type: latestElement.type, + docRef: latestElement.docRef + }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Added new requirement: ", name); + } + latestElement = {}; + return elements[name]; +}; +const getElements = () => elements; +const setNewElementType = (type) => { + if (latestElement !== void 0) { + latestElement.type = type; + } +}; +const setNewElementDocRef = (docRef) => { + if (latestElement !== void 0) { + latestElement.docRef = docRef; + } +}; +const addRelationship = (type, src, dst) => { + relations.push({ + type, + src, + dst + }); +}; +const getRelationships = () => relations; +const clear = () => { + relations = []; + latestRequirement = {}; + requirements = {}; + latestElement = {}; + elements = {}; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.v)(); +}; +const db = { + RequirementType, + RiskLevel, + VerifyType, + Relationships, + getConfig: () => (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().req, + addRequirement, + getRequirements, + setNewReqId, + setNewReqText, + setNewReqRisk, + setNewReqVerifyMethod, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.g, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.b, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.a, + addElement, + getElements, + setNewElementType, + setNewElementDocRef, + addRelationship, + getRelationships, + clear +}; +const getStyles = (options) => ` + + marker { + fill: ${options.relationColor}; + stroke: ${options.relationColor}; + } + + marker.cross { + stroke: ${options.lineColor}; + } + + svg { + font-family: ${options.fontFamily}; + font-size: ${options.fontSize}; + } + + .reqBox { + fill: ${options.requirementBackground}; + fill-opacity: 1.0; + stroke: ${options.requirementBorderColor}; + stroke-width: ${options.requirementBorderSize}; + } + + .reqTitle, .reqLabel{ + fill: ${options.requirementTextColor}; + } + .reqLabelBox { + fill: ${options.relationLabelBackground}; + fill-opacity: 1.0; + } + + .req-title-line { + stroke: ${options.requirementBorderColor}; + stroke-width: ${options.requirementBorderSize}; + } + .relationshipLine { + stroke: ${options.relationColor}; + stroke-width: 1; + } + .relationshipLabel { + fill: ${options.relationLabelColor}; + } + +`; +const styles = getStyles; +const ReqMarkers = { + CONTAINS: "contains", + ARROW: "arrow" +}; +const insertLineEndings = (parentNode, conf2) => { + let containsNode = parentNode.append("defs").append("marker").attr("id", ReqMarkers.CONTAINS + "_line_ending").attr("refX", 0).attr("refY", conf2.line_height / 2).attr("markerWidth", conf2.line_height).attr("markerHeight", conf2.line_height).attr("orient", "auto").append("g"); + containsNode.append("circle").attr("cx", conf2.line_height / 2).attr("cy", conf2.line_height / 2).attr("r", conf2.line_height / 2).attr("fill", "none"); + containsNode.append("line").attr("x1", 0).attr("x2", conf2.line_height).attr("y1", conf2.line_height / 2).attr("y2", conf2.line_height / 2).attr("stroke-width", 1); + containsNode.append("line").attr("y1", 0).attr("y2", conf2.line_height).attr("x1", conf2.line_height / 2).attr("x2", conf2.line_height / 2).attr("stroke-width", 1); + parentNode.append("defs").append("marker").attr("id", ReqMarkers.ARROW + "_line_ending").attr("refX", conf2.line_height).attr("refY", 0.5 * conf2.line_height).attr("markerWidth", conf2.line_height).attr("markerHeight", conf2.line_height).attr("orient", "auto").append("path").attr( + "d", + `M0,0 + L${conf2.line_height},${conf2.line_height / 2} + M${conf2.line_height},${conf2.line_height / 2} + L0,${conf2.line_height}` + ).attr("stroke-width", 1); +}; +const markers = { + ReqMarkers, + insertLineEndings +}; +let conf = {}; +let relCnt = 0; +const newRectNode = (parentNode, id) => { + return parentNode.insert("rect", "#" + id).attr("class", "req reqBox").attr("x", 0).attr("y", 0).attr("width", conf.rect_min_width + "px").attr("height", conf.rect_min_height + "px"); +}; +const newTitleNode = (parentNode, id, txts) => { + let x = conf.rect_min_width / 2; + let title = parentNode.append("text").attr("class", "req reqLabel reqTitle").attr("id", id).attr("x", x).attr("y", conf.rect_padding).attr("dominant-baseline", "hanging"); + let i = 0; + txts.forEach((textStr) => { + if (i == 0) { + title.append("tspan").attr("text-anchor", "middle").attr("x", conf.rect_min_width / 2).attr("dy", 0).text(textStr); + } else { + title.append("tspan").attr("text-anchor", "middle").attr("x", conf.rect_min_width / 2).attr("dy", conf.line_height * 0.75).text(textStr); + } + i++; + }); + let yPadding = 1.5 * conf.rect_padding; + let linePadding = i * conf.line_height * 0.75; + let totalY = yPadding + linePadding; + parentNode.append("line").attr("class", "req-title-line").attr("x1", "0").attr("x2", conf.rect_min_width).attr("y1", totalY).attr("y2", totalY); + return { + titleNode: title, + y: totalY + }; +}; +const newBodyNode = (parentNode, id, txts, yStart) => { + let body = parentNode.append("text").attr("class", "req reqLabel").attr("id", id).attr("x", conf.rect_padding).attr("y", yStart).attr("dominant-baseline", "hanging"); + let currentRow = 0; + const charLimit = 30; + let wrappedTxts = []; + txts.forEach((textStr) => { + let currentTextLen = textStr.length; + while (currentTextLen > charLimit && currentRow < 3) { + let firstPart = textStr.substring(0, charLimit); + textStr = textStr.substring(charLimit, textStr.length); + currentTextLen = textStr.length; + wrappedTxts[wrappedTxts.length] = firstPart; + currentRow++; + } + if (currentRow == 3) { + let lastStr = wrappedTxts[wrappedTxts.length - 1]; + wrappedTxts[wrappedTxts.length - 1] = lastStr.substring(0, lastStr.length - 4) + "..."; + } else { + wrappedTxts[wrappedTxts.length] = textStr; + } + currentRow = 0; + }); + wrappedTxts.forEach((textStr) => { + body.append("tspan").attr("x", conf.rect_padding).attr("dy", conf.line_height).text(textStr); + }); + return body; +}; +const addEdgeLabel = (parentNode, svgPath, conf2, txt) => { + const len = svgPath.node().getTotalLength(); + const labelPoint = svgPath.node().getPointAtLength(len * 0.5); + const labelId = "rel" + relCnt; + relCnt++; + const labelNode = parentNode.append("text").attr("class", "req relationshipLabel").attr("id", labelId).attr("x", labelPoint.x).attr("y", labelPoint.y).attr("text-anchor", "middle").attr("dominant-baseline", "middle").text(txt); + const labelBBox = labelNode.node().getBBox(); + parentNode.insert("rect", "#" + labelId).attr("class", "req reqLabelBox").attr("x", labelPoint.x - labelBBox.width / 2).attr("y", labelPoint.y - labelBBox.height / 2).attr("width", labelBBox.width).attr("height", labelBBox.height).attr("fill", "white").attr("fill-opacity", "85%"); +}; +const drawRelationshipFromLayout = function(svg, rel, g, insert, diagObj) { + const edge = g.edge(elementString(rel.src), elementString(rel.dst)); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .n8j)().x(function(d) { + return d.x; + }).y(function(d) { + return d.y; + }); + const svgPath = svg.insert("path", "#" + insert).attr("class", "er relationshipLine").attr("d", lineFunction(edge.points)).attr("fill", "none"); + if (rel.type == diagObj.db.Relationships.CONTAINS) { + svgPath.attr( + "marker-start", + "url(" + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.e.getUrl(conf.arrowMarkerAbsolute) + "#" + rel.type + "_line_ending)" + ); + } else { + svgPath.attr("stroke-dasharray", "10,7"); + svgPath.attr( + "marker-end", + "url(" + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.e.getUrl(conf.arrowMarkerAbsolute) + "#" + markers.ReqMarkers.ARROW + "_line_ending)" + ); + } + addEdgeLabel(svg, svgPath, conf, `<<${rel.type}>>`); + return; +}; +const drawReqs = (reqs, graph, svgNode) => { + Object.keys(reqs).forEach((reqName) => { + let req = reqs[reqName]; + reqName = elementString(reqName); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Added new requirement: ", reqName); + const groupNode = svgNode.append("g").attr("id", reqName); + const textId = "req-" + reqName; + const rectNode = newRectNode(groupNode, textId); + let titleNodeInfo = newTitleNode(groupNode, reqName + "_title", [ + `<<${req.type}>>`, + `${req.name}` + ]); + newBodyNode( + groupNode, + reqName + "_body", + [ + `Id: ${req.id}`, + `Text: ${req.text}`, + `Risk: ${req.risk}`, + `Verification: ${req.verifyMethod}` + ], + titleNodeInfo.y + ); + const rectBBox = rectNode.node().getBBox(); + graph.setNode(reqName, { + width: rectBBox.width, + height: rectBBox.height, + shape: "rect", + id: reqName + }); + }); +}; +const drawElements = (els, graph, svgNode) => { + Object.keys(els).forEach((elName) => { + let el = els[elName]; + const id = elementString(elName); + const groupNode = svgNode.append("g").attr("id", id); + const textId = "element-" + id; + const rectNode = newRectNode(groupNode, textId); + let titleNodeInfo = newTitleNode(groupNode, textId + "_title", [`<>`, `${elName}`]); + newBodyNode( + groupNode, + textId + "_body", + [`Type: ${el.type || "Not Specified"}`, `Doc Ref: ${el.docRef || "None"}`], + titleNodeInfo.y + ); + const rectBBox = rectNode.node().getBBox(); + graph.setNode(id, { + width: rectBBox.width, + height: rectBBox.height, + shape: "rect", + id + }); + }); +}; +const addRelationships = (relationships, g) => { + relationships.forEach(function(r) { + let src = elementString(r.src); + let dst = elementString(r.dst); + g.setEdge(src, dst, { relationship: r }); + }); + return relationships; +}; +const adjustEntities = function(svgNode, graph) { + graph.nodes().forEach(function(v) { + if (v !== void 0 && graph.node(v) !== void 0) { + svgNode.select("#" + v); + svgNode.select("#" + v).attr( + "transform", + "translate(" + (graph.node(v).x - graph.node(v).width / 2) + "," + (graph.node(v).y - graph.node(v).height / 2) + " )" + ); + } + }); + return; +}; +const elementString = (str) => { + return str.replace(/\s/g, "").replace(/\./g, "_"); +}; +const draw = (text, id, _version, diagObj) => { + conf = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().requirement; + const securityLevel = conf.securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body"); + const svg = root.select(`[id='${id}']`); + markers.insertLineEndings(svg, conf); + const g = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .T({ + multigraph: false, + compound: false, + directed: true + }).setGraph({ + rankdir: conf.layoutDirection, + marginx: 20, + marginy: 20, + nodesep: 100, + edgesep: 100, + ranksep: 100 + }).setDefaultEdgeLabel(function() { + return {}; + }); + let requirements2 = diagObj.db.getRequirements(); + let elements2 = diagObj.db.getElements(); + let relationships = diagObj.db.getRelationships(); + drawReqs(requirements2, g, svg); + drawElements(elements2, g, svg); + addRelationships(relationships, g); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_1__/* .layout */ .Zp)(g); + adjustEntities(svg, g); + relationships.forEach(function(rel) { + drawRelationshipFromLayout(svg, rel, g, id, diagObj); + }); + const padding = conf.rect_padding; + const svgBounds = svg.node().getBBox(); + const width = svgBounds.width + padding * 2; + const height = svgBounds.height + padding * 2; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.i)(svg, height, width, conf.useMaxWidth); + svg.attr("viewBox", `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`); +}; +const renderer = { + draw +}; +const diagram = { + parser: parser$1, + db, + renderer, + styles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/3132.9308a2c3.js b/assets/js/3132.9308a2c3.js new file mode 100644 index 0000000000..15258a8989 --- /dev/null +++ b/assets/js/3132.9308a2c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3132],{70751:(t,e,a)=>{a.d(e,{diagram:()=>y});var r=a(27308),i=a(26312),n=a(21176),d=a(697),o=a(76257);a(74353),a(16750),a(42838);let s=0;const l=function(t){let e=t.id;return t.type&&(e+="<"+(0,o.x)(t.type)+">"),e},p=function(t,e,a,r){const{displayText:i,cssStyle:n}=e.getDisplayDetails(),d=t.append("tspan").attr("x",r.padding).text(i);""!==n&&d.attr("style",e.cssStyle),a||d.attr("dy",r.textHeight)},c=function(t,e,a,r){o.l.debug("Rendering class ",e,a);const i=e.id,n={id:i,label:e.id,width:0,height:0},d=t.append("g").attr("id",r.db.lookUpDomId(i)).attr("class","classGroup");let s;s=e.link?d.append("svg:a").attr("xlink:href",e.link).attr("target",e.linkTarget).append("text").attr("y",a.textHeight+a.padding).attr("x",0):d.append("text").attr("y",a.textHeight+a.padding).attr("x",0);let c=!0;e.annotations.forEach((function(t){const e=s.append("tspan").text("\xab"+t+"\xbb");c||e.attr("dy",a.textHeight),c=!1}));let g=l(e);const h=s.append("tspan").text(g).attr("class","title");c||h.attr("dy",a.textHeight);const f=s.node().getBBox().height;let x,u,y;if(e.members.length>0){x=d.append("line").attr("x1",0).attr("y1",a.padding+f+a.dividerMargin/2).attr("y2",a.padding+f+a.dividerMargin/2);const t=d.append("text").attr("x",a.padding).attr("y",f+a.dividerMargin+a.textHeight).attr("fill","white").attr("class","classText");c=!0,e.members.forEach((function(e){p(t,e,c,a),c=!1})),u=t.node().getBBox()}if(e.methods.length>0){y=d.append("line").attr("x1",0).attr("y1",a.padding+f+a.dividerMargin+u.height).attr("y2",a.padding+f+a.dividerMargin+u.height);const t=d.append("text").attr("x",a.padding).attr("y",f+2*a.dividerMargin+u.height+a.textHeight).attr("fill","white").attr("class","classText");c=!0,e.methods.forEach((function(e){p(t,e,c,a),c=!1}))}const b=d.node().getBBox();var m=" ";e.cssClasses.length>0&&(m+=e.cssClasses.join(" "));const k=d.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",b.width+2*a.padding).attr("height",b.height+a.padding+.5*a.dividerMargin).attr("class",m).node().getBBox().width;return s.node().childNodes.forEach((function(t){t.setAttribute("x",(k-t.getBBox().width)/2)})),e.tooltip&&s.insert("title").text(e.tooltip),x&&x.attr("x2",k),y&&y.attr("x2",k),n.width=k,n.height=b.height+a.padding+.5*a.dividerMargin,n},g=function(t,e,a,r,n){const d=function(t){switch(t){case n.db.relationType.AGGREGATION:return"aggregation";case n.db.relationType.EXTENSION:return"extension";case n.db.relationType.COMPOSITION:return"composition";case n.db.relationType.DEPENDENCY:return"dependency";case n.db.relationType.LOLLIPOP:return"lollipop"}};e.points=e.points.filter((t=>!Number.isNaN(t.y)));const l=e.points,p=(0,i.n8j)().x((function(t){return t.x})).y((function(t){return t.y})).curve(i.qrM),c=t.append("path").attr("d",p(l)).attr("id","edge"+s).attr("class","relation");let g,h,f="";r.arrowMarkerAbsolute&&(f=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,f=f.replace(/\(/g,"\\("),f=f.replace(/\)/g,"\\)")),1==a.relation.lineType&&c.attr("class","relation dashed-line"),10==a.relation.lineType&&c.attr("class","relation dotted-line"),"none"!==a.relation.type1&&c.attr("marker-start","url("+f+"#"+d(a.relation.type1)+"Start)"),"none"!==a.relation.type2&&c.attr("marker-end","url("+f+"#"+d(a.relation.type2)+"End)");const x=e.points.length;let u,y,b,m,k=o.u.calcLabelPosition(e.points);if(g=k.x,h=k.y,x%2!=0&&x>1){let t=o.u.calcCardinalityPosition("none"!==a.relation.type1,e.points,e.points[0]),r=o.u.calcCardinalityPosition("none"!==a.relation.type2,e.points,e.points[x-1]);o.l.debug("cardinality_1_point "+JSON.stringify(t)),o.l.debug("cardinality_2_point "+JSON.stringify(r)),u=t.x,y=t.y,b=r.x,m=r.y}if(void 0!==a.title){const e=t.append("g").attr("class","classLabel"),i=e.append("text").attr("class","label").attr("x",g).attr("y",h).attr("fill","red").attr("text-anchor","middle").text(a.title);window.label=i;const n=i.node().getBBox();e.insert("rect",":first-child").attr("class","box").attr("x",n.x-r.padding/2).attr("y",n.y-r.padding/2).attr("width",n.width+r.padding).attr("height",n.height+r.padding)}if(o.l.info("Rendering relation "+JSON.stringify(a)),void 0!==a.relationTitle1&&"none"!==a.relationTitle1){t.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",u).attr("y",y).attr("fill","black").attr("font-size","6").text(a.relationTitle1)}if(void 0!==a.relationTitle2&&"none"!==a.relationTitle2){t.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",b).attr("y",m).attr("fill","black").attr("font-size","6").text(a.relationTitle2)}s++},h=function(t,e,a,r){o.l.debug("Rendering note ",e,a);const i=e.id,n={id:i,text:e.text,width:0,height:0},d=t.append("g").attr("id",i).attr("class","classGroup");let s=d.append("text").attr("y",a.textHeight+a.padding).attr("x",0);const l=JSON.parse(`"${e.text}"`).split("\n");l.forEach((function(t){o.l.debug(`Adding line: ${t}`),s.append("tspan").text(t).attr("class","title").attr("dy",a.textHeight)}));const p=d.node().getBBox(),c=d.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",p.width+2*a.padding).attr("height",p.height+l.length*a.textHeight+a.padding+.5*a.dividerMargin).node().getBBox().width;return s.node().childNodes.forEach((function(t){t.setAttribute("x",(c-t.getBBox().width)/2)})),n.width=c,n.height=p.height+l.length*a.textHeight+a.padding+.5*a.dividerMargin,n};let f={};const x=function(t){const e=Object.entries(f).find((e=>e[1].label===t));if(e)return e[0]},u={draw:function(t,e,a,r){const s=(0,o.c)().class;f={},o.l.info("Rendering diagram "+t);const l=(0,o.c)().securityLevel;let p;"sandbox"===l&&(p=(0,i.Ltv)("#i"+e));const u="sandbox"===l?(0,i.Ltv)(p.nodes()[0].contentDocument.body):(0,i.Ltv)("body"),y=u.select(`[id='${e}']`);var b;(b=y).append("defs").append("marker").attr("id","extensionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),b.append("defs").append("marker").attr("id","extensionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z"),b.append("defs").append("marker").attr("id","compositionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","compositionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","aggregationStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","aggregationEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","dependencyStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z");const m=new d.T({multigraph:!0});m.setGraph({isMultiGraph:!0}),m.setDefaultEdgeLabel((function(){return{}}));const k=r.db.getClasses(),w=Object.keys(k);for(const i of w){const t=k[i],e=c(y,t,s,r);f[e.id]=e,m.setNode(e.id,e),o.l.info("Org height: "+e.height)}r.db.getRelations().forEach((function(t){o.l.info("tjoho"+x(t.id1)+x(t.id2)+JSON.stringify(t)),m.setEdge(x(t.id1),x(t.id2),{relation:t},t.title||"DEFAULT")}));r.db.getNotes().forEach((function(t){o.l.debug(`Adding note: ${JSON.stringify(t)}`);const e=h(y,t,s,r);f[e.id]=e,m.setNode(e.id,e),t.class&&t.class in k&&m.setEdge(t.id,x(t.class),{relation:{id1:t.id,id2:t.class,relation:{type1:"none",type2:"none",lineType:10}}},"DEFAULT")})),(0,n.Zp)(m),m.nodes().forEach((function(t){void 0!==t&&void 0!==m.node(t)&&(o.l.debug("Node "+t+": "+JSON.stringify(m.node(t))),u.select("#"+(r.db.lookUpDomId(t)||t)).attr("transform","translate("+(m.node(t).x-m.node(t).width/2)+","+(m.node(t).y-m.node(t).height/2)+" )"))})),m.edges().forEach((function(t){void 0!==t&&void 0!==m.edge(t)&&(o.l.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(m.edge(t))),g(y,m.edge(t),m.edge(t).relation,s,r))}));const L=y.node().getBBox(),v=L.width+40,E=L.height+40;(0,o.i)(y,E,v,s.useMaxWidth);const M=`${L.x-20} ${L.y-20} ${v} ${E}`;o.l.debug(`viewBox ${M}`),y.attr("viewBox",M)}},y={parser:r.p,db:r.d,renderer:u,styles:r.s,init:t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute,r.d.clear()}}}}]); \ No newline at end of file diff --git a/assets/js/317.2b0480fc.js b/assets/js/317.2b0480fc.js new file mode 100644 index 0000000000..bed66a796b --- /dev/null +++ b/assets/js/317.2b0480fc.js @@ -0,0 +1,26805 @@ +"use strict"; +exports.id = 317; +exports.ids = [317]; +exports.modules = { + +/***/ 10646: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ H: () => (/* binding */ addHtmlLabel) +/* harmony export */ }); +/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(82933); + + + + +function addHtmlLabel(root, node) { + var fo = root.append('foreignObject').attr('width', '100000'); + + var div = fo.append('xhtml:div'); + div.attr('xmlns', 'http://www.w3.org/1999/xhtml'); + + var label = node.label; + switch (typeof label) { + case 'function': + div.insert(label); + break; + case 'object': + // Currently we assume this is a DOM object. + div.insert(function () { + return label; + }); + break; + default: + div.html(label); + } + + _util_js__WEBPACK_IMPORTED_MODULE_0__/* .applyStyle */ .AV(div, node.labelStyle); + div.style('display', 'inline-block'); + // Fix for firefox + div.style('white-space', 'nowrap'); + + var client = div.node().getBoundingClientRect(); + fo.attr('width', client.width).attr('height', client.height); + + return fo; +} + + +/***/ }), + +/***/ 82933: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ AV: () => (/* binding */ applyStyle), +/* harmony export */ De: () => (/* binding */ isSubgraph), +/* harmony export */ c$: () => (/* binding */ applyTransition), +/* harmony export */ gh: () => (/* binding */ edgeToId), +/* harmony export */ nh: () => (/* binding */ applyClass) +/* harmony export */ }); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(34963); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(89610); + + +// Public utility functions + + +/* + * Returns true if the specified node in the graph is a subgraph node. A + * subgraph node is one that contains other nodes. + */ +function isSubgraph(g, v) { + return !!g.children(v).length; +} + +function edgeToId(e) { + return escapeId(e.v) + ':' + escapeId(e.w) + ':' + escapeId(e.name); +} + +var ID_DELIM = /:/g; +function escapeId(str) { + return str ? String(str).replace(ID_DELIM, '\\:') : ''; +} + +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr('style', styleFn); + } +} + +function applyClass(dom, classFn, otherClasses) { + if (classFn) { + dom.attr('class', classFn).attr('class', otherClasses + ' ' + dom.attr('class')); + } +} + +function applyTransition(selection, g) { + var graph = g.graph(); + + if (lodash_es__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A(graph)) { + var transition = graph.transition; + if (lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(transition)) { + return transition(selection); + } + } + + return selection; +} + + +/***/ }), + +/***/ 21176: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Zp: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(5664); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(74722); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(91395); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(697); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.A(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.A( + map/* default */.A(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.A(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.A(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.T(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.A(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.A(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.A(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.A(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.A(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.A('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.A(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.A(g.outEdges(v), function (e) { + if (has/* default */.A(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.A(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.A(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(98879); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(81942); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(23068); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.A)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(52528); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.A)(iteratee, 3); + + (0,_baseForOwn/* default */.A)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.A)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(41917); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.A.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.A(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.T().setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.T({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.A(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.A(range/* default */.A(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.A(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.A(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.A(layers, function (vs, i) { + if (isUndefined/* default */.A(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.A(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.A(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.A(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.A(children, dfs); + } + + if (has/* default */.A(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.A(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.A(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, reverseYOne); + if (has/* default */.A(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, swapXYOne); + if (has/* default */.A(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.A(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.A)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.A(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.A(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.A(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.T({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.A(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.A(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.A(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.A)(collection)) { + var iteratee = (0,_baseIteratee/* default */.A)(predicate, 3); + collection = (0,keys/* default */.A)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.A)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.A)(array, (0,_baseIteratee/* default */.A)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(69471); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(88496); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.A)(value) && (0,isObjectLike/* default */.A)(value) && (0,_baseGetTag/* default */.A)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.A)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.A)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.A)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.A)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.A(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.A(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.A(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.A(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.A(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.A(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.A(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.A(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(73046); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.A(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.A(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.A(tree.neighbors(v), function (w) { + if (!has/* default */.A(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.A(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.A(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.A(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.A(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.A(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.A(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.A(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.A(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.A( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(91641); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.A)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.A(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.T({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.A(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.A(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.A(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.A('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.A); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(52568); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.A)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.A)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + if ((0,isArray/* default */.A)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.A)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.A]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.A)(iteratees, (0,_baseUnary/* default */.A)(_baseIteratee/* default */.A)); + + var result = (0,_baseMap/* default */.A)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.A)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.A)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.A)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.A)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.A(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.A( + map/* default */.A(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.A(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.A(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.A( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.A(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.A(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.A(range/* default */.A(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.A(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.A(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.A(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.A(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.A( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.A(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.A(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.A(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.A(entryV) && !isUndefined/* default */.A(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.A(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.A(uEntry.barycenter) || + isUndefined/* default */.A(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.A(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.A(entry.out, handleOut(entry)); + } + + return map/* default */.A( + filter/* default */.A(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.A(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.A(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.A(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.A(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.A(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.A(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.A(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.A([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.A(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.A(entries, function (entry) { + entry.vs = flatten/* default */.A( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.A(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.A(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.A(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.A(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.T(); + forEach/* default */.A(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.A(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.A(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.A(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(99922); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(4574); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee), keysIn/* default */.A); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.A(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.A(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.A(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.A(range/* default */.A(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.A(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.A(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.A(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.A(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.A(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.A(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.T(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.A(layering, function (layer) { + var u; + forEach/* default */.A(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.A(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.A(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.A(['u', 'd'], function (vert) { + forEach/* default */.A(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.A(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.A(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.A(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.A(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.A(layering).reverse(); + forEach/* default */.A(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.A(adjustedLayering, function (inner) { + return values/* default */.A(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.A(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.A(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.A(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.A(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.A(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.A(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.A(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.T({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.A({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.A(graph, graphAttrs)) + ); + + forEach/* default */.A(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.A(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.A({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.A(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.A(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.A(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.A(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.A(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.A(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.A(layers, function (layer) { + var orderShift = 0; + forEach/* default */.A(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.A(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.A(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.A(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 73046: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + T: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(89610); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(66401); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.A)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(39857); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.A && (1 / (0,_setToArray/* default */.A)(new _Set/* default */.A([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.A(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.A)(set); + } + isCommon = false; + includes = _cacheHas/* default */.A; + seen = new _SetCache/* default */.A; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(53533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.A)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.A)(arrays, 1, isArrayLikeObject/* default */.A, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.A(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.A(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.A(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.A(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.A(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.A(this._nodes); + } + sources() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.A(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.A(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.A(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.A(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.A(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.A(keys/* default */.A(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.A(keys/* default */.A(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.A(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.A(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.A(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.A(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.A(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.A(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.A(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.A(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.A(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.A(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.A(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.A(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.A(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.A(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.A(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.A(inV); + if (!u) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.A(outV); + if (!w) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.A(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 697: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ T: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.T) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 14075: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ M: () => (/* binding */ write) +/* harmony export */ }); +/* unused harmony export read */ +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69592); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(50053); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74722); +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); + + + + + +function write(g) { + var json = { + options: { + directed: g.isDirected(), + multigraph: g.isMultigraph(), + compound: g.isCompound(), + }, + nodes: writeNodes(g), + edges: writeEdges(g), + }; + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(g.graph())) { + json.value = lodash_es__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A(g.graph()); + } + return json; +} + +function writeNodes(g) { + return lodash_es__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A(g.nodes(), function (v) { + var nodeValue = g.node(v); + var parent = g.parent(v); + var node = { v: v }; + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(nodeValue)) { + node.value = nodeValue; + } + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(parent)) { + node.parent = parent; + } + return node; + }); +} + +function writeEdges(g) { + return lodash_es__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A(g.edges(), function (e) { + var edgeValue = g.edge(e); + var edge = { v: e.v, w: e.w }; + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(e.name)) { + edge.name = e.name; + } + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(edgeValue)) { + edge.value = edgeValue; + } + return edge; + }); +} + +function read(json) { + var g = new Graph(json.options).setGraph(json.value); + _.each(json.nodes, function (entry) { + g.setNode(entry.v, entry.value); + if (entry.parent) { + g.setParent(entry.v, entry.parent); + } + }); + _.each(json.edges, function (entry) { + g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value); + }); + return g; +} + + +/***/ }), + +/***/ 75937: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _utils_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(72453); +/* harmony import */ var _color_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74886); +/* IMPORT */ + + +/* MAIN */ +const channel = (color, channel) => { + return _utils_index_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A.lang.round(_color_index_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A.parse(color)[channel]); +}; +/* EXPORT */ +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (channel); + + +/***/ }), + +/***/ 62062: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(29471); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.A; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 72641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 2634: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 45572: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 76912: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 91641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(72641); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(22031); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keys/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keysIn/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(80154); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(39759); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(14792); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.A)(source, (0,_getSymbols/* default */.A)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(15647); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(13153); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.A : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.A)(result, (0,_getSymbols/* default */.A)(object)); + object = (0,_getPrototype/* default */.A)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.A)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(33831); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.A)(object, keysIn/* default */.A, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(90565); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.A)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(1801); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.A)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.A)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(18598); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(64841); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.A)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.A)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.A)(value)) { + return value; + } + var isArr = (0,isArray/* default */.A)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.A)(value, result); + } + } else { + var tag = (0,_getTag/* default */.A)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.A)(value)) { + return (0,_cloneBuffer/* default */.A)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.A)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.A); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.A) + : (isFlat ? keysIn/* default */.A : keys/* default */.A); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.A)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.A)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 6240: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.A)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.A); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 25707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 13588: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(52274); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.A ? _Symbol/* default */.A.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.A)(value) || (0,isArguments/* default */.A)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.A)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 79841: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4574); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 66318: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 33831: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76912); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 49574: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.A : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.A)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(43988); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(66984); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.A(object), new _Uint8Array/* default */.A(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.A)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.A); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.A)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.A)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(33858); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.A)(object), + othIsArr = (0,isArray/* default */.A)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.A)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.A)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.A)(object)) { + if (!(0,isBuffer/* default */.A)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.A); + return (objIsArr || (0,isTypedArray/* default */.A)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.A); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.A); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.A)(value) && !(0,isObjectLike/* default */.A)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.A; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.A)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.A)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.A)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.A)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.A)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.A)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.A)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.A)(path) ? (0,_baseProperty/* default */.A)((0,_toKey/* default */.A)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.A; + } + if (typeof value == 'object') { + return (0,isArray/* default */.A)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 52568: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6240); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 70805: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 64099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 99922: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(29008); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 7819: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(46632); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.A)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(28894); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.A)(value)) { + return value; + } + return (0,_isKey/* default */.A)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.A)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 19042: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33831); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14792); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 14792: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2634); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13153); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 85054: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(52274); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(92049); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25353); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5254); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 86586: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(61882); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 29959: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 30901: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61882); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 50053: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseClone_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(91641); + + +/** Used to compose bitmasks for cloning. */ +var CLONE_SYMBOLS_FLAG = 4; + +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return (0,_baseClone_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value, CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (clone); + + +/***/ }), + +/***/ 23068: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(24326); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66984); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6832); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55615); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 11662: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(2634); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.A)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.A)(collection) ? _arrayFilter/* default */.A : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.A)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 34098: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13588); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 8058: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72641); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6240); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99922); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 48585: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 39188: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 61882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(88496); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(53098); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 69592: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 27422: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(83607); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69471); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 74722: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(45572); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49574); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(52568); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 81942: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(7819); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(25353); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.A)(object)) { + return object; + } + path = (0,_castPath/* default */.A)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.A)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.A)(objValue) + ? objValue + : ((0,_isIndex/* default */.A)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.A)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.A)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.A)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.A)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(76875); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(67525); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.A)((0,_overRest/* default */.A)(func, undefined, flatten/* default */.A), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 91395: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.A)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.A)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.A)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.A)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 89463: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.A)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.A)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.A); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 13153: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 74342: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.A)(value)) { + return NAN; + } + if ((0,isObject/* default */.A)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.A)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 28894: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.A)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.A)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.A)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 5664: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28894); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 38207: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.A)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.A)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 40351: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-f47111a7.js + 8 modules +var mermaid_f47111a7 = __webpack_require__(76257); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {Array} items + * Items to add to `list`. + * @returns {Array} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record} */ + const left = maybe || (all[hook] = {}) + /** @type {Record | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array} existing + * @param {Array} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array} */ + let parameters + /** @type {Array} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array} events + * @param {number} eventIndex + * @returns {Record} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record} */ + const gaps = {} + /** @type {Array} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record} */ + const columnStart = {} + /** @type {Array} */ + const resolveAllConstructs = [] + /** @type {Array} */ + let chunks = [] + /** @type {Array} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array} chunks + * @param {Pick} token + * @returns {Array} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * + * b> + * + * + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`` or `b`). + * @param {TokenType} literalType + * Type when enclosed (``). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * . + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * . + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After ` | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | &<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | + * ^^ + * > | + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > |
+ * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after ` | + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > |
+ * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + *

!^a

+ *

!^a

+ * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | ab + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a c + * ^ + * > | a c + * ^ + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * > | a c + * ^ + * > | a &<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after ` | a c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After ` | a &<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a &<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a
c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array} events + * @returns {Array} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract} Parent + * + * @typedef {Omit & {type: 'fragment', children: Array}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array} transforms + * Tree transforms. + * + * @typedef {Partial} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array} stack + * Stack of nodes. + * @property {Array} tokenStack + * Stack of tokens. + * @property {(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(60513); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-6b48ae7d.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.T)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "
"); + } else if (node.type === "strong") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "emphasis") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "paragraph") { + return `

${node.children.map(output).join("")}

`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + " + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_f47111a7.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_f47111a7.M)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 28747: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ insertMarkers$1), +/* harmony export */ b: () => (/* binding */ clear$1), +/* harmony export */ c: () => (/* binding */ createLabel$1), +/* harmony export */ d: () => (/* binding */ clear), +/* harmony export */ e: () => (/* binding */ insertNode), +/* harmony export */ f: () => (/* binding */ insertEdgeLabel), +/* harmony export */ g: () => (/* binding */ getSubGraphTitleMargins), +/* harmony export */ h: () => (/* binding */ insertEdge), +/* harmony export */ i: () => (/* binding */ intersectRect$1), +/* harmony export */ j: () => (/* binding */ positionEdgeLabel), +/* harmony export */ k: () => (/* binding */ getLineFunctionsWithOffset), +/* harmony export */ l: () => (/* binding */ labelHelper), +/* harmony export */ m: () => (/* binding */ addEdgeMarkers), +/* harmony export */ p: () => (/* binding */ positionNode), +/* harmony export */ s: () => (/* binding */ setNodeElem), +/* harmony export */ u: () => (/* binding */ updateNodeBounds) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(40351); + + + +const insertMarkers = (elem, markerArray, type, id) => { + markerArray.forEach((markerName) => { + markers[markerName](elem, type, id); + }); +}; +const extension = (elem, type, id) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Making markers for ", id); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); +}; +const composition = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const aggregation = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const dependency = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 6).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const lollipop = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopEnd").attr("class", "marker lollipop " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); +}; +const point = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 6).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 4.5).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const circle$1 = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const cross = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); +}; +const barb = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const markers = { + extension, + composition, + aggregation, + dependency, + lollipop, + point, + circle: circle$1, + cross, + barb +}; +const insertMarkers$1 = insertMarkers; +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlLabel(node) { + const fo = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + '" + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "inline-block"); + div.style("white-space", "nowrap"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + return fo.node(); +} +const createLabel = (_vertexText, style, isTitle, isNode) => { + let vertexText = _vertexText || ""; + if (typeof vertexText === "object") { + vertexText = vertexText[0]; + } + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + vertexText = vertexText.replace(/\\n|\n/g, "
"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("vertexText" + vertexText); + const node = { + isNode, + label: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(vertexText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + let vertexNode = addHtmlLabel(node); + return vertexNode; + } else { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", style.replace("color:", "fill:")); + let rows = []; + if (typeof vertexText === "string") { + rows = vertexText.split(/\\n|\n|/gi); + } else if (Array.isArray(vertexText)) { + rows = vertexText; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + if (isTitle) { + tspan.setAttribute("class", "title-row"); + } else { + tspan.setAttribute("class", "row"); + } + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; + } +}; +const createLabel$1 = createLabel; +const labelHelper = async (parent, node, _classes, isNode) => { + let classes; + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + if (!_classes) { + classes = "node default"; + } else { + classes = _classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle); + let labelText; + if (node.labelText === void 0) { + labelText = ""; + } else { + labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0]; + } + const textNode = label.node(); + let text; + if (node.labelType === "markdown") { + text = (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__.a)(label, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(labelText), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()), { + useHtmlLabels, + width: node.width || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.wrappingWidth, + classes: "markdown-node-label" + }); + } else { + text = textNode.appendChild( + createLabel$1( + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(labelText), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()), + node.labelStyle, + false, + isNode + ) + ); + } + let bbox = text.getBBox(); + const halfPadding = node.padding / 2; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text); + const images = div.getElementsByTagName("img"); + if (images) { + const noImgText = labelText.replace(/]*>/g, "").trim() === ""; + await Promise.all( + [...images].map( + (img) => new Promise((res) => { + function setupImage() { + img.style.display = "flex"; + img.style.flexDirection = "column"; + if (noImgText) { + const bodyFontSize = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize ? (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize : window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + const width = parseInt(bodyFontSize, 10) * enlargingFactor + "px"; + img.style.minWidth = width; + img.style.maxWidth = width; + } else { + img.style.width = "100%"; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener("error", setupImage); + img.addEventListener("load", setupImage); + }) + ) + ); + } + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (useHtmlLabels) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } else { + label.attr("transform", "translate(0, " + -bbox.height / 2 + ")"); + } + if (node.centerLabel) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } + label.insert("rect", ":first-child"); + return { shapeSvg, bbox, halfPadding, label }; +}; +const updateNodeBounds = (node, element) => { + const bbox = element.node().getBBox(); + node.width = bbox.width; + node.height = bbox.height; +}; +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +function intersectNode(node, point2) { + return node.intersect(point2); +} +function intersectEllipse(node, rx, ry, point2) { + var cx = node.x; + var cy = node.y; + var px = cx - point2.x; + var py = cy - point2.y; + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + var dx = Math.abs(rx * ry * px / det); + if (point2.x < cx) { + dx = -dx; + } + var dy = Math.abs(rx * ry * py / det); + if (point2.y < cy) { + dy = -dy; + } + return { x: cx + dx, y: cy + dy }; +} +function intersectCircle(node, rx, point2) { + return intersectEllipse(node, rx, rx, point2); +} +function intersectLine(p1, p2, q1, q2) { + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return; + } + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return; + } + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return; + } + offset = Math.abs(denom / 2); + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + return { x, y }; +} +function sameSign(r1, r2) { + return r1 * r2 > 0; +} +function intersectPolygon(node, polyPoints, point2) { + var x1 = node.x; + var y1 = node.y; + var intersections = []; + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + if (typeof polyPoints.forEach === "function") { + polyPoints.forEach(function(entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + } else { + minX = Math.min(minX, polyPoints.x); + minY = Math.min(minY, polyPoints.y); + } + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect2 = intersectLine( + node, + point2, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect2) { + intersections.push(intersect2); + } + } + if (!intersections.length) { + return node; + } + if (intersections.length > 1) { + intersections.sort(function(p, q) { + var pdx = p.x - point2.x; + var pdy = p.y - point2.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + var qdx = q.x - point2.x; + var qdy = q.y - point2.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} +const intersectRect = (node, point2) => { + var x = node.x; + var y = node.y; + var dx = point2.x - x; + var dy = point2.y - y; + var w = node.width / 2; + var h = node.height / 2; + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : h * dx / dy; + sy = h; + } else { + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : w * dy / dx; + } + return { x: x + sx, y: y + sy }; +}; +const intersectRect$1 = intersectRect; +const intersect = { + node: intersectNode, + circle: intersectCircle, + ellipse: intersectEllipse, + polygon: intersectPolygon, + rect: intersectRect$1 +}; +const note = async (parent, node) => { + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels; + if (!useHtmlLabels) { + node.centerLabel = true; + } + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Classes = ", node.classes); + const rect2 = shapeSvg.insert("rect", ":first-child"); + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const note$1 = note; +const expandAndDeduplicateDirections = (directions) => { + const uniqueDirections = /* @__PURE__ */ new Set(); + for (const direction of directions) { + switch (direction) { + case "x": + uniqueDirections.add("right"); + uniqueDirections.add("left"); + break; + case "y": + uniqueDirections.add("up"); + uniqueDirections.add("down"); + break; + default: + uniqueDirections.add(direction); + break; + } + } + return uniqueDirections; +}; +const getArrowPoints = (duplicatedDirections, bbox, node) => { + const directions = expandAndDeduplicateDirections(duplicatedDirections); + const f = 2; + const height = bbox.height + 2 * node.padding; + const midpoint = height / f; + const width = bbox.width + 2 * midpoint + node.padding; + const padding = node.padding / 2; + if (directions.has("right") && directions.has("left") && directions.has("up") && directions.has("down")) { + return [ + // Bottom + { x: 0, y: 0 }, + { x: midpoint, y: 0 }, + { x: width / 2, y: 2 * padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: 0 }, + // Right + { x: width, y: -height / 3 }, + { x: width + 2 * padding, y: -height / 2 }, + { x: width, y: -2 * height / 3 }, + { x: width, y: -height }, + // Top + { x: width - midpoint, y: -height }, + { x: width / 2, y: -height - 2 * padding }, + { x: midpoint, y: -height }, + // Left + { x: 0, y: -height }, + { x: 0, y: -2 * height / 3 }, + { x: -2 * padding, y: -height / 2 }, + { x: 0, y: -height / 3 } + ]; + } + if (directions.has("right") && directions.has("left") && directions.has("up")) { + return [ + { x: midpoint, y: 0 }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("right") && directions.has("left") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: midpoint, y: -height }, + { x: width - midpoint, y: -height }, + { x: width, y: 0 } + ]; + } + if (directions.has("right") && directions.has("up") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: width, y: -midpoint }, + { x: width, y: -height + midpoint }, + { x: 0, y: -height } + ]; + } + if (directions.has("left") && directions.has("up") && directions.has("down")) { + return [ + { x: width, y: 0 }, + { x: 0, y: -midpoint }, + { x: 0, y: -height + midpoint }, + { x: width, y: -height } + ]; + } + if (directions.has("right") && directions.has("left")) { + return [ + { x: midpoint, y: 0 }, + { x: midpoint, y: -padding }, + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: width - midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("up") && directions.has("down")) { + return [ + // Bottom center + { x: width / 2, y: 0 }, + // Left pont of bottom arrow + { x: 0, y: -padding }, + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: 0, y: -height + padding }, + // Top of arrow + { x: width / 2, y: -height }, + { x: width, y: -height + padding }, + // Top of right vertical bar + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding }, + { x: width, y: -padding } + ]; + } + if (directions.has("right") && directions.has("up")) { + return [ + { x: 0, y: 0 }, + { x: width, y: -midpoint }, + { x: 0, y: -height } + ]; + } + if (directions.has("right") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: width, y: 0 }, + { x: 0, y: -height } + ]; + } + if (directions.has("left") && directions.has("up")) { + return [ + { x: width, y: 0 }, + { x: 0, y: -midpoint }, + { x: width, y: -height } + ]; + } + if (directions.has("left") && directions.has("down")) { + return [ + { x: width, y: 0 }, + { x: 0, y: 0 }, + { x: width, y: -height } + ]; + } + if (directions.has("right")) { + return [ + { x: midpoint, y: -padding }, + { x: midpoint, y: -padding }, + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: width - midpoint, y: -height + padding }, + // top left corner of arrow + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding } + ]; + } + if (directions.has("left")) { + return [ + { x: midpoint, y: 0 }, + { x: midpoint, y: -padding }, + // Two points, the right corners + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("up")) { + return [ + // Bottom center + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: 0, y: -height + padding }, + // Top of arrow + { x: width / 2, y: -height }, + { x: width, y: -height + padding }, + // Top of right vertical bar + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding } + ]; + } + if (directions.has("down")) { + return [ + // Bottom center + { x: width / 2, y: 0 }, + // Left pont of bottom arrow + { x: 0, y: -padding }, + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding }, + { x: width, y: -padding } + ]; + } + return [{ x: 0, y: 0 }]; +}; +const formatClass = (str) => { + if (str) { + return " " + str; + } + return ""; +}; +const getClassesFromNode = (node, otherClasses) => { + return `${otherClasses ? otherClasses : "node default"}${formatClass(node.classes)} ${formatClass( + node.class + )}`; +}; +const question = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const s = w + h; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Question main (Circle)"); + const questionElem = insertPolygonShape(shapeSvg, s, s, points); + questionElem.attr("style", node.style); + updateNodeBounds(node, questionElem); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("Intersect called"); + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const choice = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const s = 28; + const points = [ + { x: 0, y: s / 2 }, + { x: s / 2, y: 0 }, + { x: 0, y: -s / 2 }, + { x: -s / 2, y: 0 } + ]; + const choice2 = shapeSvg.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ); + choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28); + node.width = 28; + node.height = 28; + node.intersect = function(point2) { + return intersect.circle(node, 14, point2); + }; + return shapeSvg; +}; +const hexagon = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const f = 4; + const h = bbox.height + node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const hex = insertPolygonShape(shapeSvg, w, h, points); + hex.attr("style", node.style); + updateNodeBounds(node, hex); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const block_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true); + const f = 2; + const h = bbox.height + 2 * node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = getArrowPoints(node.directions, bbox, node); + const blockArrow = insertPolygonShape(shapeSvg, w, h, points); + blockArrow.attr("style", node.style); + updateNodeBounds(node, blockArrow); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_left_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + node.width = w + h; + node.height = h; + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_right = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_left = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const inv_trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_right_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const cylinder = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry + node.padding; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const el = shapeSvg.attr("label-offset-y", ry).insert("path", ":first-child").attr("style", node.style).attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + updateNodeBounds(node, el); + node.intersect = function(point2) { + const pos = intersect.rect(node, point2); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point2.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +}; +const rect = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes + " " + node.class, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding; + const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding; + rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const composite = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding; + const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding; + rect2.attr("class", "basic cluster composite label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const labelRect = async (parent, node) => { + const { shapeSvg } = await labelHelper(parent, node, "label", true); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Classes = ", node.class); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = 0; + const totalHeight = 0; + rect2.attr("width", totalWidth).attr("height", totalHeight); + shapeSvg.attr("class", "label edgeLabel"); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) { + const strokeDashArray = []; + const addBorder = (length) => { + strokeDashArray.push(length, 0); + }; + const skipBorder = (length) => { + strokeDashArray.push(0, length); + }; + if (borders.includes("t")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add top border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("r")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add right border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + if (borders.includes("b")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add bottom border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("l")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add left border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + rect2.attr("stroke-dasharray", strokeDashArray.join(" ")); +} +const rectWithTitle = (parent, node) => { + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const innerLine = shapeSvg.insert("line"); + const label = shapeSvg.insert("g").attr("class", "label"); + const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText; + let title = ""; + if (typeof text2 === "object") { + title = text2[0]; + } else { + title = text2; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Label text abc79", title, text2, typeof text2 === "object"); + const text = label.node().appendChild(createLabel$1(title, node.labelStyle, true, true)); + let bbox = { width: 0, height: 0 }; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Text 2", text2); + const textRows = text2.slice(1, text2.length); + let titleBox = text.getBBox(); + const descr = label.node().appendChild( + createLabel$1(textRows.join ? textRows.join("
") : textRows, node.labelStyle, true, true) + ); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = descr.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(descr); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const halfPadding = node.padding / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(descr).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")" + ); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)" + ); + bbox = label.node().getBBox(); + label.attr( + "transform", + "translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")" + ); + rect2.attr("class", "outer title-state").attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + innerLine.attr("class", "divider").attr("x1", -bbox.width / 2 - halfPadding).attr("x2", bbox.width / 2 + halfPadding).attr("y1", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr("y2", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const stadium = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const h = bbox.height + node.padding; + const w = bbox.width + h / 4 + node.padding; + const rect2 = shapeSvg.insert("rect", ":first-child").attr("style", node.style).attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const circle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle main"); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle intersect", node, bbox.width / 2 + halfPadding, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding, point2); + }; + return shapeSvg; +}; +const doublecircle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const gap = 5; + const circleGroup = shapeSvg.insert("g", ":first-child"); + const outerCircle = circleGroup.insert("circle"); + const innerCircle = circleGroup.insert("circle"); + circleGroup.attr("class", node.class); + outerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding + gap).attr("width", bbox.width + node.padding + gap * 2).attr("height", bbox.height + node.padding + gap * 2); + innerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle main"); + updateNodeBounds(node, outerCircle); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point2); + }; + return shapeSvg; +}; +const subroutine = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const start = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const forkJoin = (parent, node, dir) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + let width = 70; + let height = 10; + if (dir === "LR") { + width = 10; + height = 70; + } + const shape = shapeSvg.append("rect").attr("x", -1 * width / 2).attr("y", -1 * height / 2).attr("width", width).attr("height", height).attr("class", "fork-join"); + updateNodeBounds(node, shape); + node.height = node.height + node.padding / 2; + node.width = node.width + node.padding / 2; + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const end = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const innerCircle = shapeSvg.insert("circle", ":first-child"); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const class_box = (parent, node) => { + const halfPadding = node.padding / 2; + const rowPadding = 4; + const lineHeight = 8; + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const topLine = shapeSvg.insert("line"); + const bottomLine = shapeSvg.insert("line"); + let maxWidth = 0; + let maxHeight = rowPadding; + const labelContainer = shapeSvg.insert("g").attr("class", "label"); + let verticalPos = 0; + const hasInterface = node.classData.annotations && node.classData.annotations[0]; + const interfaceLabelText = node.classData.annotations[0] ? "«" + node.classData.annotations[0] + "»" : ""; + const interfaceLabel = labelContainer.node().appendChild(createLabel$1(interfaceLabelText, node.labelStyle, true, true)); + let interfaceBBox = interfaceLabel.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = interfaceLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(interfaceLabel); + interfaceBBox = div.getBoundingClientRect(); + dv.attr("width", interfaceBBox.width); + dv.attr("height", interfaceBBox.height); + } + if (node.classData.annotations[0]) { + maxHeight += interfaceBBox.height + rowPadding; + maxWidth += interfaceBBox.width; + } + let classTitleString = node.classData.label; + if (node.classData.type !== void 0 && node.classData.type !== "") { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + classTitleString += "<" + node.classData.type + ">"; + } else { + classTitleString += "<" + node.classData.type + ">"; + } + } + const classTitleLabel = labelContainer.node().appendChild(createLabel$1(classTitleString, node.labelStyle, true, true)); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel).attr("class", "classTitle"); + let classTitleBBox = classTitleLabel.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = classTitleLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel); + classTitleBBox = div.getBoundingClientRect(); + dv.attr("width", classTitleBBox.width); + dv.attr("height", classTitleBBox.height); + } + maxHeight += classTitleBBox.height + rowPadding; + if (classTitleBBox.width > maxWidth) { + maxWidth = classTitleBBox.width; + } + const classAttributes = []; + node.classData.members.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let parsedText = parsedInfo.displayText; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + parsedText = parsedText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + parsedText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classAttributes.push(lbl); + }); + maxHeight += lineHeight; + const classMethods = []; + node.classData.methods.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let displayText = parsedInfo.displayText; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + displayText = displayText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + displayText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classMethods.push(lbl); + }); + maxHeight += lineHeight; + if (hasInterface) { + let diffX2 = (maxWidth - interfaceBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(interfaceLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")" + ); + verticalPos = interfaceBBox.height + rowPadding; + } + let diffX = (maxWidth - classTitleBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + verticalPos += classTitleBBox.height + rowPadding; + topLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classAttributes.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + verticalPos += lineHeight; + bottomLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classMethods.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + rect2.attr("style", node.style).attr("class", "outer title-state").attr("x", -maxWidth / 2 - halfPadding).attr("y", -(maxHeight / 2) - halfPadding).attr("width", maxWidth + node.padding).attr("height", maxHeight + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const shapes = { + rhombus: question, + composite, + question, + rect, + labelRect, + rectWithTitle, + choice, + circle, + doublecircle, + stadium, + hexagon, + block_arrow, + rect_left_inv_arrow, + lean_right, + lean_left, + trapezoid, + inv_trapezoid, + rect_right_inv_arrow, + cylinder, + start, + end, + note: note$1, + subroutine, + fork: forkJoin, + join: forkJoin, + class_box +}; +let nodeElems = {}; +const insertNode = async (elem, node, dir) => { + let newEl; + let el; + if (node.link) { + let target; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel === "sandbox") { + target = "_top"; + } else if (node.linkTarget) { + target = node.linkTarget || "_blank"; + } + newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target); + el = await shapes[node.shape](newEl, node, dir); + } else { + el = await shapes[node.shape](elem, node, dir); + newEl = el; + } + if (node.tooltip) { + el.attr("title", node.tooltip); + } + if (node.class) { + el.attr("class", "node default " + node.class); + } + newEl.attr("data-node", "true"); + newEl.attr("data-id", node.id); + nodeElems[node.id] = newEl; + if (node.haveCallback) { + nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable"); + } + return newEl; +}; +const setNodeElem = (elem, node) => { + nodeElems[node.id] = elem; +}; +const clear$1 = () => { + nodeElems = {}; +}; +const positionNode = (node) => { + const el = nodeElems[node.id]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace( + "Transforming node", + node.diff, + node, + "translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")" + ); + const padding = 8; + const diff = node.diff || 0; + if (node.clusterNode) { + el.attr( + "transform", + "translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")" + ); + } else { + el.attr("transform", "translate(" + node.x + ", " + node.y + ")"); + } + return diff; +}; +const getSubGraphTitleMargins = ({ + flowchart +}) => { + var _a, _b; + const subGraphTitleTopMargin = ((_a = flowchart == null ? void 0 : flowchart.subGraphTitleMargin) == null ? void 0 : _a.top) ?? 0; + const subGraphTitleBottomMargin = ((_b = flowchart == null ? void 0 : flowchart.subGraphTitleMargin) == null ? void 0 : _b.bottom) ?? 0; + const subGraphTitleTotalMargin = subGraphTitleTopMargin + subGraphTitleBottomMargin; + return { + subGraphTitleTopMargin, + subGraphTitleBottomMargin, + subGraphTitleTotalMargin + }; +}; +const markerOffsets = { + aggregation: 18, + extension: 18, + composition: 18, + dependency: 6, + lollipop: 13.5, + arrow_point: 5.3 +}; +function calculateDeltaAndAngle(point1, point2) { + if (point1 === void 0 || point2 === void 0) { + return { angle: 0, deltaX: 0, deltaY: 0 }; + } + point1 = pointTransformer(point1); + point2 = pointTransformer(point2); + const [x1, y1] = [point1.x, point1.y]; + const [x2, y2] = [point2.x, point2.y]; + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY }; +} +const pointTransformer = (data) => { + if (Array.isArray(data)) { + return { x: data[0], y: data[1] }; + } + return data; +}; +const getLineFunctionsWithOffset = (edge) => { + return { + x: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaX } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } + return pointTransformer(d).x + offset; + }, + y: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaY } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } + return pointTransformer(d).y + offset; + } + }; +}; +const addEdgeMarkers = (svgPath, edge, url, id, diagramType) => { + if (edge.arrowTypeStart) { + addEdgeMarker(svgPath, "start", edge.arrowTypeStart, url, id, diagramType); + } + if (edge.arrowTypeEnd) { + addEdgeMarker(svgPath, "end", edge.arrowTypeEnd, url, id, diagramType); + } +}; +const arrowTypesMap = { + arrow_cross: "cross", + arrow_point: "point", + arrow_barb: "barb", + arrow_circle: "circle", + aggregation: "aggregation", + extension: "extension", + composition: "composition", + dependency: "dependency", + lollipop: "lollipop" +}; +const addEdgeMarker = (svgPath, position, arrowType, url, id, diagramType) => { + const endMarkerType = arrowTypesMap[arrowType]; + if (!endMarkerType) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown arrow type: ${arrowType}`); + return; + } + const suffix = position === "start" ? "Start" : "End"; + svgPath.attr(`marker-${position}`, `url(${url}#${id}_${diagramType}-${endMarkerType}${suffix})`); +}; +let edgeLabels = {}; +let terminalLabels = {}; +const clear = () => { + edgeLabels = {}; + terminalLabels = {}; +}; +const insertEdgeLabel = (elem, edge) => { + const useHtmlLabels = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + const labelElement = edge.labelType === "markdown" ? (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__.a)(elem, edge.label, { + style: edge.labelStyle, + useHtmlLabels, + addSvgBackground: true + }) : createLabel$1(edge.label, edge.labelStyle); + const edgeLabel = elem.insert("g").attr("class", "edgeLabel"); + const label = edgeLabel.insert("g").attr("class", "label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + if (useHtmlLabels) { + const div = labelElement.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(labelElement); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + edgeLabels[edge.id] = edgeLabel; + edge.width = bbox.width; + edge.height = bbox.height; + let fo; + if (edge.startLabelLeft) { + const startLabelElement = createLabel$1(edge.startLabelLeft, edge.labelStyle); + const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startLeft = startEdgeLabelLeft; + setTerminalWidth(fo, edge.startLabelLeft); + } + if (edge.startLabelRight) { + const startLabelElement = createLabel$1(edge.startLabelRight, edge.labelStyle); + const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelRight.insert("g").attr("class", "inner"); + fo = startEdgeLabelRight.node().appendChild(startLabelElement); + inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startRight = startEdgeLabelRight; + setTerminalWidth(fo, edge.startLabelRight); + } + if (edge.endLabelLeft) { + const endLabelElement = createLabel$1(edge.endLabelLeft, edge.labelStyle); + const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelLeft.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endLeft = endEdgeLabelLeft; + setTerminalWidth(fo, edge.endLabelLeft); + } + if (edge.endLabelRight) { + const endLabelElement = createLabel$1(edge.endLabelRight, edge.labelStyle); + const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelRight.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelRight.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endRight = endEdgeLabelRight; + setTerminalWidth(fo, edge.endLabelRight); + } + return labelElement; +}; +function setTerminalWidth(fo, value) { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels && fo) { + fo.style.width = value.length * 9 + "px"; + fo.style.height = "12px"; + } +} +const positionEdgeLabel = (edge, paths) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("Moving label abc88 ", edge.id, edge.label, edgeLabels[edge.id], paths); + let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig); + if (edge.label) { + const el = edgeLabels[edge.id]; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcLabelPosition(path); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug( + "Moving label " + edge.label + " from (", + x, + ",", + y, + ") to (", + pos.x, + ",", + pos.y, + ") abc88" + ); + if (paths.updatedPath) { + x = pos.x; + y = pos.y; + } + } + el.attr("transform", `translate(${x}, ${y + subGraphTitleTotalMargin / 2})`); + } + if (edge.startLabelLeft) { + const el = terminalLabels[edge.id].startLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.startLabelRight) { + const el = terminalLabels[edge.id].startRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition( + edge.arrowTypeStart ? 10 : 0, + "start_right", + path + ); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.endLabelLeft) { + const el = terminalLabels[edge.id].endLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.endLabelRight) { + const el = terminalLabels[edge.id].endRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } +}; +const outsideNode = (node, point2) => { + const x = node.x; + const y = node.y; + const dx = Math.abs(point2.x - x); + const dy = Math.abs(point2.y - y); + const w = node.width / 2; + const h = node.height / 2; + if (dx >= w || dy >= h) { + return true; + } + return false; +}; +const intersection = (node, outsidePoint, insidePoint) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`intersection calc abc89: + outsidePoint: ${JSON.stringify(outsidePoint)} + insidePoint : ${JSON.stringify(insidePoint)} + node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`); + const x = node.x; + const y = node.y; + const dx = Math.abs(x - insidePoint.x); + const w = node.width / 2; + let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; + const h = node.height / 2; + const Q = Math.abs(outsidePoint.y - insidePoint.y); + const R = Math.abs(outsidePoint.x - insidePoint.x); + if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { + let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y; + r = R * q / Q; + const res = { + x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r, + y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q + }; + if (r === 0) { + res.x = outsidePoint.x; + res.y = outsidePoint.y; + } + if (R === 0) { + res.x = outsidePoint.x; + } + if (Q === 0) { + res.y = outsidePoint.y; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res); + return res; + } else { + if (insidePoint.x < outsidePoint.x) { + r = outsidePoint.x - w - x; + } else { + r = x - w - outsidePoint.x; + } + let q = Q * r / R; + let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r; + let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y }); + if (r === 0) { + _x = outsidePoint.x; + _y = outsidePoint.y; + } + if (R === 0) { + _x = outsidePoint.x; + } + if (Q === 0) { + _y = outsidePoint.y; + } + return { x: _x, y: _y }; + } +}; +const cutPathAtIntersect = (_points, boundaryNode) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("abc88 cutPathAtIntersect", _points, boundaryNode); + let points = []; + let lastPointOutside = _points[0]; + let isInside = false; + _points.forEach((point2) => { + if (!outsideNode(boundaryNode, point2) && !isInside) { + const inter = intersection(boundaryNode, lastPointOutside, point2); + let pointPresent = false; + points.forEach((p) => { + pointPresent = pointPresent || p.x === inter.x && p.y === inter.y; + }); + if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { + points.push(inter); + } + isInside = true; + } else { + lastPointOutside = point2; + if (!isInside) { + points.push(point2); + } + } + }); + return points; +}; +const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph, id) { + let points = edge.points; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("abc88 InsertEdge: edge=", edge, "e=", e); + let pointsHasChanged = false; + const tail = graph.node(e.v); + var head = graph.node(e.w); + if ((head == null ? void 0 : head.intersect) && (tail == null ? void 0 : tail.intersect)) { + points = points.slice(1, edge.points.length - 1); + points.unshift(tail.intersect(points[0])); + points.push(head.intersect(points[points.length - 1])); + } + if (edge.toCluster) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("to cluster abc88", clusterDb[edge.toCluster]); + points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); + pointsHasChanged = true; + } + if (edge.fromCluster) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("from cluster abc88", clusterDb[edge.fromCluster]); + points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse(); + pointsHasChanged = true; + } + const lineData = points.filter((p) => !Number.isNaN(p.y)); + let curve = d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .qrM; + if (edge.curve && (diagramType === "graph" || diagramType === "flowchart")) { + curve = edge.curve; + } + const { x, y } = getLineFunctionsWithOffset(edge); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .n8j)().x(x).y(y).curve(curve); + let strokeClasses; + switch (edge.thickness) { + case "normal": + strokeClasses = "edge-thickness-normal"; + break; + case "thick": + strokeClasses = "edge-thickness-thick"; + break; + case "invisible": + strokeClasses = "edge-thickness-thick"; + break; + default: + strokeClasses = ""; + } + switch (edge.pattern) { + case "solid": + strokeClasses += " edge-pattern-solid"; + break; + case "dotted": + strokeClasses += " edge-pattern-dotted"; + break; + case "dashed": + strokeClasses += " edge-pattern-dashed"; + break; + } + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style); + let url = ""; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.arrowMarkerAbsolute || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + addEdgeMarkers(svgPath, edge, url, id, diagramType); + let paths = {}; + if (pointsHasChanged) { + paths.updatedPath = points; + } + paths.originalPath = edge.points; + return paths; +}; + + + +/***/ }), + +/***/ 66216: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ f: () => (/* binding */ flowDb), +/* harmony export */ p: () => (/* binding */ parser$1) +/* harmony export */ }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 4], $V1 = [1, 3], $V2 = [1, 5], $V3 = [1, 8, 9, 10, 11, 27, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $V4 = [2, 2], $V5 = [1, 13], $V6 = [1, 14], $V7 = [1, 15], $V8 = [1, 16], $V9 = [1, 23], $Va = [1, 25], $Vb = [1, 26], $Vc = [1, 27], $Vd = [1, 49], $Ve = [1, 48], $Vf = [1, 29], $Vg = [1, 30], $Vh = [1, 31], $Vi = [1, 32], $Vj = [1, 33], $Vk = [1, 44], $Vl = [1, 46], $Vm = [1, 42], $Vn = [1, 47], $Vo = [1, 43], $Vp = [1, 50], $Vq = [1, 45], $Vr = [1, 51], $Vs = [1, 52], $Vt = [1, 34], $Vu = [1, 35], $Vv = [1, 36], $Vw = [1, 37], $Vx = [1, 57], $Vy = [1, 8, 9, 10, 11, 27, 32, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $Vz = [1, 61], $VA = [1, 60], $VB = [1, 62], $VC = [8, 9, 11, 73, 75], $VD = [1, 88], $VE = [1, 93], $VF = [1, 92], $VG = [1, 89], $VH = [1, 85], $VI = [1, 91], $VJ = [1, 87], $VK = [1, 94], $VL = [1, 90], $VM = [1, 95], $VN = [1, 86], $VO = [8, 9, 10, 11, 73, 75], $VP = [8, 9, 10, 11, 44, 73, 75], $VQ = [8, 9, 10, 11, 29, 42, 44, 46, 48, 50, 52, 54, 56, 58, 61, 63, 65, 66, 68, 73, 75, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VR = [8, 9, 11, 42, 58, 73, 75, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VS = [42, 58, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VT = [1, 121], $VU = [1, 120], $VV = [1, 128], $VW = [1, 142], $VX = [1, 143], $VY = [1, 144], $VZ = [1, 145], $V_ = [1, 130], $V$ = [1, 132], $V01 = [1, 136], $V11 = [1, 137], $V21 = [1, 138], $V31 = [1, 139], $V41 = [1, 140], $V51 = [1, 141], $V61 = [1, 146], $V71 = [1, 147], $V81 = [1, 126], $V91 = [1, 127], $Va1 = [1, 134], $Vb1 = [1, 129], $Vc1 = [1, 133], $Vd1 = [1, 131], $Ve1 = [8, 9, 10, 11, 27, 32, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $Vf1 = [1, 149], $Vg1 = [8, 9, 11], $Vh1 = [8, 9, 10, 11, 14, 42, 58, 86, 102, 103, 106, 108, 111, 112, 113], $Vi1 = [1, 169], $Vj1 = [1, 165], $Vk1 = [1, 166], $Vl1 = [1, 170], $Vm1 = [1, 167], $Vn1 = [1, 168], $Vo1 = [75, 113, 116], $Vp1 = [8, 9, 10, 11, 12, 14, 27, 29, 32, 42, 58, 73, 81, 82, 83, 84, 85, 86, 87, 102, 106, 108, 111, 112, 113], $Vq1 = [10, 103], $Vr1 = [31, 47, 49, 51, 53, 55, 60, 62, 64, 65, 67, 69, 113, 114, 115], $Vs1 = [1, 235], $Vt1 = [1, 233], $Vu1 = [1, 237], $Vv1 = [1, 231], $Vw1 = [1, 232], $Vx1 = [1, 234], $Vy1 = [1, 236], $Vz1 = [1, 238], $VA1 = [1, 255], $VB1 = [8, 9, 11, 103], $VC1 = [8, 9, 10, 11, 58, 81, 102, 103, 106, 107, 108, 109]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "graphConfig": 4, "document": 5, "line": 6, "statement": 7, "SEMI": 8, "NEWLINE": 9, "SPACE": 10, "EOF": 11, "GRAPH": 12, "NODIR": 13, "DIR": 14, "FirstStmtSeparator": 15, "ending": 16, "endToken": 17, "spaceList": 18, "spaceListNewline": 19, "vertexStatement": 20, "separator": 21, "styleStatement": 22, "linkStyleStatement": 23, "classDefStatement": 24, "classStatement": 25, "clickStatement": 26, "subgraph": 27, "textNoTags": 28, "SQS": 29, "text": 30, "SQE": 31, "end": 32, "direction": 33, "acc_title": 34, "acc_title_value": 35, "acc_descr": 36, "acc_descr_value": 37, "acc_descr_multiline_value": 38, "link": 39, "node": 40, "styledVertex": 41, "AMP": 42, "vertex": 43, "STYLE_SEPARATOR": 44, "idString": 45, "DOUBLECIRCLESTART": 46, "DOUBLECIRCLEEND": 47, "PS": 48, "PE": 49, "(-": 50, "-)": 51, "STADIUMSTART": 52, "STADIUMEND": 53, "SUBROUTINESTART": 54, "SUBROUTINEEND": 55, "VERTEX_WITH_PROPS_START": 56, "NODE_STRING[field]": 57, "COLON": 58, "NODE_STRING[value]": 59, "PIPE": 60, "CYLINDERSTART": 61, "CYLINDEREND": 62, "DIAMOND_START": 63, "DIAMOND_STOP": 64, "TAGEND": 65, "TRAPSTART": 66, "TRAPEND": 67, "INVTRAPSTART": 68, "INVTRAPEND": 69, "linkStatement": 70, "arrowText": 71, "TESTSTR": 72, "START_LINK": 73, "edgeText": 74, "LINK": 75, "edgeTextToken": 76, "STR": 77, "MD_STR": 78, "textToken": 79, "keywords": 80, "STYLE": 81, "LINKSTYLE": 82, "CLASSDEF": 83, "CLASS": 84, "CLICK": 85, "DOWN": 86, "UP": 87, "textNoTagsToken": 88, "stylesOpt": 89, "idString[vertex]": 90, "idString[class]": 91, "CALLBACKNAME": 92, "CALLBACKARGS": 93, "HREF": 94, "LINK_TARGET": 95, "STR[link]": 96, "STR[tooltip]": 97, "alphaNum": 98, "DEFAULT": 99, "numList": 100, "INTERPOLATE": 101, "NUM": 102, "COMMA": 103, "style": 104, "styleComponent": 105, "NODE_STRING": 106, "UNIT": 107, "BRKT": 108, "PCT": 109, "idStringToken": 110, "MINUS": 111, "MULT": 112, "UNICODE_TEXT": 113, "TEXT": 114, "TAGSTART": 115, "EDGE_TEXT": 116, "alphaNumToken": 117, "direction_tb": 118, "direction_bt": 119, "direction_rl": 120, "direction_lr": 121, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 8: "SEMI", 9: "NEWLINE", 10: "SPACE", 11: "EOF", 12: "GRAPH", 13: "NODIR", 14: "DIR", 27: "subgraph", 29: "SQS", 31: "SQE", 32: "end", 34: "acc_title", 35: "acc_title_value", 36: "acc_descr", 37: "acc_descr_value", 38: "acc_descr_multiline_value", 42: "AMP", 44: "STYLE_SEPARATOR", 46: "DOUBLECIRCLESTART", 47: "DOUBLECIRCLEEND", 48: "PS", 49: "PE", 50: "(-", 51: "-)", 52: "STADIUMSTART", 53: "STADIUMEND", 54: "SUBROUTINESTART", 55: "SUBROUTINEEND", 56: "VERTEX_WITH_PROPS_START", 57: "NODE_STRING[field]", 58: "COLON", 59: "NODE_STRING[value]", 60: "PIPE", 61: "CYLINDERSTART", 62: "CYLINDEREND", 63: "DIAMOND_START", 64: "DIAMOND_STOP", 65: "TAGEND", 66: "TRAPSTART", 67: "TRAPEND", 68: "INVTRAPSTART", 69: "INVTRAPEND", 72: "TESTSTR", 73: "START_LINK", 75: "LINK", 77: "STR", 78: "MD_STR", 81: "STYLE", 82: "LINKSTYLE", 83: "CLASSDEF", 84: "CLASS", 85: "CLICK", 86: "DOWN", 87: "UP", 90: "idString[vertex]", 91: "idString[class]", 92: "CALLBACKNAME", 93: "CALLBACKARGS", 94: "HREF", 95: "LINK_TARGET", 96: "STR[link]", 97: "STR[tooltip]", 99: "DEFAULT", 101: "INTERPOLATE", 102: "NUM", 103: "COMMA", 106: "NODE_STRING", 107: "UNIT", 108: "BRKT", 109: "PCT", 111: "MINUS", 112: "MULT", 113: "UNICODE_TEXT", 114: "TEXT", 115: "TAGSTART", 116: "EDGE_TEXT", 118: "direction_tb", 119: "direction_bt", 120: "direction_rl", 121: "direction_lr" }, + productions_: [0, [3, 2], [5, 0], [5, 2], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [4, 2], [4, 2], [4, 2], [4, 3], [16, 2], [16, 1], [17, 1], [17, 1], [17, 1], [15, 1], [15, 1], [15, 2], [19, 2], [19, 2], [19, 1], [19, 1], [18, 2], [18, 1], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 9], [7, 6], [7, 4], [7, 1], [7, 2], [7, 2], [7, 1], [21, 1], [21, 1], [21, 1], [20, 3], [20, 4], [20, 2], [20, 1], [40, 1], [40, 5], [41, 1], [41, 3], [43, 4], [43, 4], [43, 6], [43, 4], [43, 4], [43, 4], [43, 8], [43, 4], [43, 4], [43, 4], [43, 6], [43, 4], [43, 4], [43, 4], [43, 4], [43, 4], [43, 1], [39, 2], [39, 3], [39, 3], [39, 1], [39, 3], [74, 1], [74, 2], [74, 1], [74, 1], [70, 1], [71, 3], [30, 1], [30, 2], [30, 1], [30, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [28, 1], [28, 2], [28, 1], [28, 1], [24, 5], [25, 5], [26, 2], [26, 4], [26, 3], [26, 5], [26, 3], [26, 5], [26, 5], [26, 7], [26, 2], [26, 4], [26, 2], [26, 4], [26, 4], [26, 6], [22, 5], [23, 5], [23, 5], [23, 9], [23, 9], [23, 7], [23, 7], [100, 1], [100, 3], [89, 1], [89, 3], [104, 1], [104, 2], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [79, 1], [79, 1], [79, 1], [79, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [76, 1], [76, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [45, 1], [45, 2], [98, 1], [98, 2], [33, 1], [33, 1], [33, 1], [33, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 2: + this.$ = []; + break; + case 3: + if (!Array.isArray($$[$0]) || $$[$0].length > 0) { + $$[$0 - 1].push($$[$0]); + } + this.$ = $$[$0 - 1]; + break; + case 4: + case 176: + this.$ = $$[$0]; + break; + case 11: + yy.setDirection("TB"); + this.$ = "TB"; + break; + case 12: + yy.setDirection($$[$0 - 1]); + this.$ = $$[$0 - 1]; + break; + case 27: + this.$ = $$[$0 - 1].nodes; + break; + case 28: + case 29: + case 30: + case 31: + case 32: + this.$ = []; + break; + case 33: + this.$ = yy.addSubGraph($$[$0 - 6], $$[$0 - 1], $$[$0 - 4]); + break; + case 34: + this.$ = yy.addSubGraph($$[$0 - 3], $$[$0 - 1], $$[$0 - 3]); + break; + case 35: + this.$ = yy.addSubGraph(void 0, $$[$0 - 1], void 0); + break; + case 37: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 38: + case 39: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 43: + yy.addLink($$[$0 - 2].stmt, $$[$0], $$[$0 - 1]); + this.$ = { stmt: $$[$0], nodes: $$[$0].concat($$[$0 - 2].nodes) }; + break; + case 44: + yy.addLink($$[$0 - 3].stmt, $$[$0 - 1], $$[$0 - 2]); + this.$ = { stmt: $$[$0 - 1], nodes: $$[$0 - 1].concat($$[$0 - 3].nodes) }; + break; + case 45: + this.$ = { stmt: $$[$0 - 1], nodes: $$[$0 - 1] }; + break; + case 46: + this.$ = { stmt: $$[$0], nodes: $$[$0] }; + break; + case 47: + this.$ = [$$[$0]]; + break; + case 48: + this.$ = $$[$0 - 4].concat($$[$0]); + break; + case 49: + this.$ = $$[$0]; + break; + case 50: + this.$ = $$[$0 - 2]; + yy.setClass($$[$0 - 2], $$[$0]); + break; + case 51: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "square"); + break; + case 52: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "doublecircle"); + break; + case 53: + this.$ = $$[$0 - 5]; + yy.addVertex($$[$0 - 5], $$[$0 - 2], "circle"); + break; + case 54: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "ellipse"); + break; + case 55: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "stadium"); + break; + case 56: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "subroutine"); + break; + case 57: + this.$ = $$[$0 - 7]; + yy.addVertex($$[$0 - 7], $$[$0 - 1], "rect", void 0, void 0, void 0, Object.fromEntries([[$$[$0 - 5], $$[$0 - 3]]])); + break; + case 58: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "cylinder"); + break; + case 59: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "round"); + break; + case 60: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "diamond"); + break; + case 61: + this.$ = $$[$0 - 5]; + yy.addVertex($$[$0 - 5], $$[$0 - 2], "hexagon"); + break; + case 62: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "odd"); + break; + case 63: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "trapezoid"); + break; + case 64: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "inv_trapezoid"); + break; + case 65: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "lean_right"); + break; + case 66: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "lean_left"); + break; + case 67: + this.$ = $$[$0]; + yy.addVertex($$[$0]); + break; + case 68: + $$[$0 - 1].text = $$[$0]; + this.$ = $$[$0 - 1]; + break; + case 69: + case 70: + $$[$0 - 2].text = $$[$0 - 1]; + this.$ = $$[$0 - 2]; + break; + case 71: + this.$ = $$[$0]; + break; + case 72: + var inf = yy.destructLink($$[$0], $$[$0 - 2]); + this.$ = { "type": inf.type, "stroke": inf.stroke, "length": inf.length, "text": $$[$0 - 1] }; + break; + case 73: + this.$ = { text: $$[$0], type: "text" }; + break; + case 74: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 75: + this.$ = { text: $$[$0], type: "string" }; + break; + case 76: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 77: + var inf = yy.destructLink($$[$0]); + this.$ = { "type": inf.type, "stroke": inf.stroke, "length": inf.length }; + break; + case 78: + this.$ = $$[$0 - 1]; + break; + case 79: + this.$ = { text: $$[$0], type: "text" }; + break; + case 80: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 81: + this.$ = { text: $$[$0], type: "string" }; + break; + case 82: + case 97: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 94: + this.$ = { text: $$[$0], type: "text" }; + break; + case 95: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 96: + this.$ = { text: $$[$0], type: "text" }; + break; + case 98: + this.$ = $$[$0 - 4]; + yy.addClass($$[$0 - 2], $$[$0]); + break; + case 99: + this.$ = $$[$0 - 4]; + yy.setClass($$[$0 - 2], $$[$0]); + break; + case 100: + case 108: + this.$ = $$[$0 - 1]; + yy.setClickEvent($$[$0 - 1], $$[$0]); + break; + case 101: + case 109: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 102: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 103: + this.$ = $$[$0 - 4]; + yy.setClickEvent($$[$0 - 4], $$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 4], $$[$0]); + break; + case 104: + this.$ = $$[$0 - 2]; + yy.setLink($$[$0 - 2], $$[$0]); + break; + case 105: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 4], $$[$0 - 2]); + yy.setTooltip($$[$0 - 4], $$[$0]); + break; + case 106: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 4], $$[$0 - 2], $$[$0]); + break; + case 107: + this.$ = $$[$0 - 6]; + yy.setLink($$[$0 - 6], $$[$0 - 4], $$[$0]); + yy.setTooltip($$[$0 - 6], $$[$0 - 2]); + break; + case 110: + this.$ = $$[$0 - 1]; + yy.setLink($$[$0 - 1], $$[$0]); + break; + case 111: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 112: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 3], $$[$0 - 2], $$[$0]); + break; + case 113: + this.$ = $$[$0 - 5]; + yy.setLink($$[$0 - 5], $$[$0 - 4], $$[$0]); + yy.setTooltip($$[$0 - 5], $$[$0 - 2]); + break; + case 114: + this.$ = $$[$0 - 4]; + yy.addVertex($$[$0 - 2], void 0, void 0, $$[$0]); + break; + case 115: + this.$ = $$[$0 - 4]; + yy.updateLink([$$[$0 - 2]], $$[$0]); + break; + case 116: + this.$ = $$[$0 - 4]; + yy.updateLink($$[$0 - 2], $$[$0]); + break; + case 117: + this.$ = $$[$0 - 8]; + yy.updateLinkInterpolate([$$[$0 - 6]], $$[$0 - 2]); + yy.updateLink([$$[$0 - 6]], $$[$0]); + break; + case 118: + this.$ = $$[$0 - 8]; + yy.updateLinkInterpolate($$[$0 - 6], $$[$0 - 2]); + yy.updateLink($$[$0 - 6], $$[$0]); + break; + case 119: + this.$ = $$[$0 - 6]; + yy.updateLinkInterpolate([$$[$0 - 4]], $$[$0]); + break; + case 120: + this.$ = $$[$0 - 6]; + yy.updateLinkInterpolate($$[$0 - 4], $$[$0]); + break; + case 121: + case 123: + this.$ = [$$[$0]]; + break; + case 122: + case 124: + $$[$0 - 2].push($$[$0]); + this.$ = $$[$0 - 2]; + break; + case 126: + this.$ = $$[$0 - 1] + $$[$0]; + break; + case 174: + this.$ = $$[$0]; + break; + case 175: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + case 177: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + case 178: + this.$ = { stmt: "dir", value: "TB" }; + break; + case 179: + this.$ = { stmt: "dir", value: "BT" }; + break; + case 180: + this.$ = { stmt: "dir", value: "RL" }; + break; + case 181: + this.$ = { stmt: "dir", value: "LR" }; + break; + } + }, + table: [{ 3: 1, 4: 2, 9: $V0, 10: $V1, 12: $V2 }, { 1: [3] }, o($V3, $V4, { 5: 6 }), { 4: 7, 9: $V0, 10: $V1, 12: $V2 }, { 4: 8, 9: $V0, 10: $V1, 12: $V2 }, { 13: [1, 9], 14: [1, 10] }, { 1: [2, 1], 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, o($V3, [2, 9]), o($V3, [2, 10]), o($V3, [2, 11]), { 8: [1, 54], 9: [1, 55], 10: $Vx, 15: 53, 18: 56 }, o($Vy, [2, 3]), o($Vy, [2, 4]), o($Vy, [2, 5]), o($Vy, [2, 6]), o($Vy, [2, 7]), o($Vy, [2, 8]), { 8: $Vz, 9: $VA, 11: $VB, 21: 58, 39: 59, 70: 63, 73: [1, 64], 75: [1, 65] }, { 8: $Vz, 9: $VA, 11: $VB, 21: 66 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 67 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 68 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 69 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 70 }, { 8: $Vz, 9: $VA, 10: [1, 71], 11: $VB, 21: 72 }, o($Vy, [2, 36]), { 35: [1, 73] }, { 37: [1, 74] }, o($Vy, [2, 39]), o($VC, [2, 46], { 18: 75, 10: $Vx }), { 10: [1, 76] }, { 10: [1, 77] }, { 10: [1, 78] }, { 10: [1, 79] }, { 14: $VD, 42: $VE, 58: $VF, 77: [1, 83], 86: $VG, 92: [1, 80], 94: [1, 81], 98: 82, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, o($Vy, [2, 178]), o($Vy, [2, 179]), o($Vy, [2, 180]), o($Vy, [2, 181]), o($VO, [2, 47]), o($VO, [2, 49], { 44: [1, 96] }), o($VP, [2, 67], { 110: 109, 29: [1, 97], 42: $Vd, 46: [1, 98], 48: [1, 99], 50: [1, 100], 52: [1, 101], 54: [1, 102], 56: [1, 103], 58: $Ve, 61: [1, 104], 63: [1, 105], 65: [1, 106], 66: [1, 107], 68: [1, 108], 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), o($VQ, [2, 174]), o($VQ, [2, 135]), o($VQ, [2, 136]), o($VQ, [2, 137]), o($VQ, [2, 138]), o($VQ, [2, 139]), o($VQ, [2, 140]), o($VQ, [2, 141]), o($VQ, [2, 142]), o($VQ, [2, 143]), o($VQ, [2, 144]), o($VQ, [2, 145]), o($V3, [2, 12]), o($V3, [2, 18]), o($V3, [2, 19]), { 9: [1, 110] }, o($VR, [2, 26], { 18: 111, 10: $Vx }), o($Vy, [2, 27]), { 40: 112, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vy, [2, 40]), o($Vy, [2, 41]), o($Vy, [2, 42]), o($VS, [2, 71], { 71: 113, 60: [1, 115], 72: [1, 114] }), { 74: 116, 76: 117, 77: [1, 118], 78: [1, 119], 113: $VT, 116: $VU }, o([42, 58, 60, 72, 86, 99, 102, 103, 106, 108, 111, 112, 113], [2, 77]), o($Vy, [2, 28]), o($Vy, [2, 29]), o($Vy, [2, 30]), o($Vy, [2, 31]), o($Vy, [2, 32]), { 10: $VV, 12: $VW, 14: $VX, 27: $VY, 28: 122, 32: $VZ, 42: $V_, 58: $V$, 73: $V01, 77: [1, 124], 78: [1, 125], 80: 135, 81: $V11, 82: $V21, 83: $V31, 84: $V41, 85: $V51, 86: $V61, 87: $V71, 88: 123, 102: $V81, 106: $V91, 108: $Va1, 111: $Vb1, 112: $Vc1, 113: $Vd1 }, o($Ve1, $V4, { 5: 148 }), o($Vy, [2, 37]), o($Vy, [2, 38]), o($VC, [2, 45], { 42: $Vf1 }), { 42: $Vd, 45: 150, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 99: [1, 151], 100: 152, 102: [1, 153] }, { 42: $Vd, 45: 154, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 42: $Vd, 45: 155, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vg1, [2, 100], { 10: [1, 156], 93: [1, 157] }), { 77: [1, 158] }, o($Vg1, [2, 108], { 117: 160, 10: [1, 159], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 110], { 10: [1, 161] }), o($Vh1, [2, 176]), o($Vh1, [2, 163]), o($Vh1, [2, 164]), o($Vh1, [2, 165]), o($Vh1, [2, 166]), o($Vh1, [2, 167]), o($Vh1, [2, 168]), o($Vh1, [2, 169]), o($Vh1, [2, 170]), o($Vh1, [2, 171]), o($Vh1, [2, 172]), o($Vh1, [2, 173]), { 42: $Vd, 45: 162, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 30: 163, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 171, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 173, 48: [1, 172], 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 174, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 175, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 176, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 106: [1, 177] }, { 30: 178, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 179, 63: [1, 180], 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 181, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 182, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 183, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VQ, [2, 175]), o($V3, [2, 20]), o($VR, [2, 25]), o($VC, [2, 43], { 18: 184, 10: $Vx }), o($VS, [2, 68], { 10: [1, 185] }), { 10: [1, 186] }, { 30: 187, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 75: [1, 188], 76: 189, 113: $VT, 116: $VU }, o($Vo1, [2, 73]), o($Vo1, [2, 75]), o($Vo1, [2, 76]), o($Vo1, [2, 161]), o($Vo1, [2, 162]), { 8: $Vz, 9: $VA, 10: $VV, 11: $VB, 12: $VW, 14: $VX, 21: 191, 27: $VY, 29: [1, 190], 32: $VZ, 42: $V_, 58: $V$, 73: $V01, 80: 135, 81: $V11, 82: $V21, 83: $V31, 84: $V41, 85: $V51, 86: $V61, 87: $V71, 88: 192, 102: $V81, 106: $V91, 108: $Va1, 111: $Vb1, 112: $Vc1, 113: $Vd1 }, o($Vp1, [2, 94]), o($Vp1, [2, 96]), o($Vp1, [2, 97]), o($Vp1, [2, 150]), o($Vp1, [2, 151]), o($Vp1, [2, 152]), o($Vp1, [2, 153]), o($Vp1, [2, 154]), o($Vp1, [2, 155]), o($Vp1, [2, 156]), o($Vp1, [2, 157]), o($Vp1, [2, 158]), o($Vp1, [2, 159]), o($Vp1, [2, 160]), o($Vp1, [2, 83]), o($Vp1, [2, 84]), o($Vp1, [2, 85]), o($Vp1, [2, 86]), o($Vp1, [2, 87]), o($Vp1, [2, 88]), o($Vp1, [2, 89]), o($Vp1, [2, 90]), o($Vp1, [2, 91]), o($Vp1, [2, 92]), o($Vp1, [2, 93]), { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 193], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, { 10: $Vx, 18: 194 }, { 10: [1, 195], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: [1, 196] }, { 10: [1, 197], 103: [1, 198] }, o($Vq1, [2, 121]), { 10: [1, 199], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: [1, 200], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 77: [1, 201] }, o($Vg1, [2, 102], { 10: [1, 202] }), o($Vg1, [2, 104], { 10: [1, 203] }), { 77: [1, 204] }, o($Vh1, [2, 177]), { 77: [1, 205], 95: [1, 206] }, o($VO, [2, 50], { 110: 109, 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), { 31: [1, 207], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($Vr1, [2, 79]), o($Vr1, [2, 81]), o($Vr1, [2, 82]), o($Vr1, [2, 146]), o($Vr1, [2, 147]), o($Vr1, [2, 148]), o($Vr1, [2, 149]), { 47: [1, 209], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 210, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 49: [1, 211], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 51: [1, 212], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 53: [1, 213], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 55: [1, 214], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 58: [1, 215] }, { 62: [1, 216], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 64: [1, 217], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 218, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 31: [1, 219], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 65: $Vi1, 67: [1, 220], 69: [1, 221], 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 65: $Vi1, 67: [1, 223], 69: [1, 222], 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VC, [2, 44], { 42: $Vf1 }), o($VS, [2, 70]), o($VS, [2, 69]), { 60: [1, 224], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VS, [2, 72]), o($Vo1, [2, 74]), { 30: 225, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($Ve1, $V4, { 5: 226 }), o($Vp1, [2, 95]), o($Vy, [2, 35]), { 41: 227, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 228, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 239, 101: [1, 240], 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 241, 101: [1, 242], 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 102: [1, 243] }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 244, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 42: $Vd, 45: 245, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vg1, [2, 101]), { 77: [1, 246] }, { 77: [1, 247], 95: [1, 248] }, o($Vg1, [2, 109]), o($Vg1, [2, 111], { 10: [1, 249] }), o($Vg1, [2, 112]), o($VP, [2, 51]), o($Vr1, [2, 80]), o($VP, [2, 52]), { 49: [1, 250], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 59]), o($VP, [2, 54]), o($VP, [2, 55]), o($VP, [2, 56]), { 106: [1, 251] }, o($VP, [2, 58]), o($VP, [2, 60]), { 64: [1, 252], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 62]), o($VP, [2, 63]), o($VP, [2, 65]), o($VP, [2, 64]), o($VP, [2, 66]), o([10, 42, 58, 86, 99, 102, 103, 106, 108, 111, 112, 113], [2, 78]), { 31: [1, 253], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 254], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, o($VO, [2, 48]), o($Vg1, [2, 114], { 103: $VA1 }), o($VB1, [2, 123], { 105: 256, 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }), o($VC1, [2, 125]), o($VC1, [2, 127]), o($VC1, [2, 128]), o($VC1, [2, 129]), o($VC1, [2, 130]), o($VC1, [2, 131]), o($VC1, [2, 132]), o($VC1, [2, 133]), o($VC1, [2, 134]), o($Vg1, [2, 115], { 103: $VA1 }), { 10: [1, 257] }, o($Vg1, [2, 116], { 103: $VA1 }), { 10: [1, 258] }, o($Vq1, [2, 122]), o($Vg1, [2, 98], { 103: $VA1 }), o($Vg1, [2, 99], { 110: 109, 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), o($Vg1, [2, 103]), o($Vg1, [2, 105], { 10: [1, 259] }), o($Vg1, [2, 106]), { 95: [1, 260] }, { 49: [1, 261] }, { 60: [1, 262] }, { 64: [1, 263] }, { 8: $Vz, 9: $VA, 11: $VB, 21: 264 }, o($Vy, [2, 34]), { 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 104: 265, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, o($VC1, [2, 126]), { 14: $VD, 42: $VE, 58: $VF, 86: $VG, 98: 266, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, { 14: $VD, 42: $VE, 58: $VF, 86: $VG, 98: 267, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, { 95: [1, 268] }, o($Vg1, [2, 113]), o($VP, [2, 53]), { 30: 269, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 61]), o($Ve1, $V4, { 5: 270 }), o($VB1, [2, 124], { 105: 256, 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }), o($Vg1, [2, 119], { 117: 160, 10: [1, 271], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 120], { 117: 160, 10: [1, 272], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 107]), { 31: [1, 273], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 274], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 275, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 276, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, o($VP, [2, 57]), o($Vy, [2, 33]), o($Vg1, [2, 117], { 103: $VA1 }), o($Vg1, [2, 118], { 103: $VA1 })], + defaultActions: {}, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex2() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex2(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex2() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.begin("acc_title"); + return 34; + case 1: + this.popState(); + return "acc_title_value"; + case 2: + this.begin("acc_descr"); + return 36; + case 3: + this.popState(); + return "acc_descr_value"; + case 4: + this.begin("acc_descr_multiline"); + break; + case 5: + this.popState(); + break; + case 6: + return "acc_descr_multiline_value"; + case 7: + this.begin("callbackname"); + break; + case 8: + this.popState(); + break; + case 9: + this.popState(); + this.begin("callbackargs"); + break; + case 10: + return 92; + case 11: + this.popState(); + break; + case 12: + return 93; + case 13: + return "MD_STR"; + case 14: + this.popState(); + break; + case 15: + this.begin("md_string"); + break; + case 16: + return "STR"; + case 17: + this.popState(); + break; + case 18: + this.pushState("string"); + break; + case 19: + return 81; + case 20: + return 99; + case 21: + return 82; + case 22: + return 101; + case 23: + return 83; + case 24: + return 84; + case 25: + return 94; + case 26: + this.begin("click"); + break; + case 27: + this.popState(); + break; + case 28: + return 85; + case 29: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 30: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 31: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 32: + return 27; + case 33: + return 32; + case 34: + return 95; + case 35: + return 95; + case 36: + return 95; + case 37: + return 95; + case 38: + this.popState(); + return 13; + case 39: + this.popState(); + return 14; + case 40: + this.popState(); + return 14; + case 41: + this.popState(); + return 14; + case 42: + this.popState(); + return 14; + case 43: + this.popState(); + return 14; + case 44: + this.popState(); + return 14; + case 45: + this.popState(); + return 14; + case 46: + this.popState(); + return 14; + case 47: + this.popState(); + return 14; + case 48: + this.popState(); + return 14; + case 49: + return 118; + case 50: + return 119; + case 51: + return 120; + case 52: + return 121; + case 53: + return 102; + case 54: + return 108; + case 55: + return 44; + case 56: + return 58; + case 57: + return 42; + case 58: + return 8; + case 59: + return 103; + case 60: + return 112; + case 61: + this.popState(); + return 75; + case 62: + this.pushState("edgeText"); + return 73; + case 63: + return 116; + case 64: + this.popState(); + return 75; + case 65: + this.pushState("thickEdgeText"); + return 73; + case 66: + return 116; + case 67: + this.popState(); + return 75; + case 68: + this.pushState("dottedEdgeText"); + return 73; + case 69: + return 116; + case 70: + return 75; + case 71: + this.popState(); + return 51; + case 72: + return "TEXT"; + case 73: + this.pushState("ellipseText"); + return 50; + case 74: + this.popState(); + return 53; + case 75: + this.pushState("text"); + return 52; + case 76: + this.popState(); + return 55; + case 77: + this.pushState("text"); + return 54; + case 78: + return 56; + case 79: + this.pushState("text"); + return 65; + case 80: + this.popState(); + return 62; + case 81: + this.pushState("text"); + return 61; + case 82: + this.popState(); + return 47; + case 83: + this.pushState("text"); + return 46; + case 84: + this.popState(); + return 67; + case 85: + this.popState(); + return 69; + case 86: + return 114; + case 87: + this.pushState("trapText"); + return 66; + case 88: + this.pushState("trapText"); + return 68; + case 89: + return 115; + case 90: + return 65; + case 91: + return 87; + case 92: + return "SEP"; + case 93: + return 86; + case 94: + return 112; + case 95: + return 108; + case 96: + return 42; + case 97: + return 106; + case 98: + return 111; + case 99: + return 113; + case 100: + this.popState(); + return 60; + case 101: + this.pushState("text"); + return 60; + case 102: + this.popState(); + return 49; + case 103: + this.pushState("text"); + return 48; + case 104: + this.popState(); + return 31; + case 105: + this.pushState("text"); + return 29; + case 106: + this.popState(); + return 64; + case 107: + this.pushState("text"); + return 63; + case 108: + return "TEXT"; + case 109: + return "QUOTE"; + case 110: + return 9; + case 111: + return 10; + case 112: + return 11; + } + }, + rules: [/^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:call[\s]+)/, /^(?:\([\s]*\))/, /^(?:\()/, /^(?:[^(]*)/, /^(?:\))/, /^(?:[^)]*)/, /^(?:[^`"]+)/, /^(?:[`]["])/, /^(?:["][`])/, /^(?:[^"]+)/, /^(?:["])/, /^(?:["])/, /^(?:style\b)/, /^(?:default\b)/, /^(?:linkStyle\b)/, /^(?:interpolate\b)/, /^(?:classDef\b)/, /^(?:class\b)/, /^(?:href[\s])/, /^(?:click[\s]+)/, /^(?:[\s\n])/, /^(?:[^\s\n]*)/, /^(?:flowchart-elk\b)/, /^(?:graph\b)/, /^(?:flowchart\b)/, /^(?:subgraph\b)/, /^(?:end\b\s*)/, /^(?:_self\b)/, /^(?:_blank\b)/, /^(?:_parent\b)/, /^(?:_top\b)/, /^(?:(\r?\n)*\s*\n)/, /^(?:\s*LR\b)/, /^(?:\s*RL\b)/, /^(?:\s*TB\b)/, /^(?:\s*BT\b)/, /^(?:\s*TD\b)/, /^(?:\s*BR\b)/, /^(?:\s*<)/, /^(?:\s*>)/, /^(?:\s*\^)/, /^(?:\s*v\b)/, /^(?:.*direction\s+TB[^\n]*)/, /^(?:.*direction\s+BT[^\n]*)/, /^(?:.*direction\s+RL[^\n]*)/, /^(?:.*direction\s+LR[^\n]*)/, /^(?:[0-9]+)/, /^(?:#)/, /^(?::::)/, /^(?::)/, /^(?:&)/, /^(?:;)/, /^(?:,)/, /^(?:\*)/, /^(?:\s*[xo<]?--+[-xo>]\s*)/, /^(?:\s*[xo<]?--\s*)/, /^(?:[^-]|-(?!-)+)/, /^(?:\s*[xo<]?==+[=xo>]\s*)/, /^(?:\s*[xo<]?==\s*)/, /^(?:[^=]|=(?!))/, /^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/, /^(?:\s*[xo<]?-\.\s*)/, /^(?:[^\.]|\.(?!))/, /^(?:\s*~~[\~]+\s*)/, /^(?:[-/\)][\)])/, /^(?:[^\(\)\[\]\{\}]|!\)+)/, /^(?:\(-)/, /^(?:\]\))/, /^(?:\(\[)/, /^(?:\]\])/, /^(?:\[\[)/, /^(?:\[\|)/, /^(?:>)/, /^(?:\)\])/, /^(?:\[\()/, /^(?:\)\)\))/, /^(?:\(\(\()/, /^(?:[\\(?=\])][\]])/, /^(?:\/(?=\])\])/, /^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/, /^(?:\[\/)/, /^(?:\[\\)/, /^(?:<)/, /^(?:>)/, /^(?:\^)/, /^(?:\\\|)/, /^(?:v\b)/, /^(?:\*)/, /^(?:#)/, /^(?:&)/, /^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/, /^(?:-)/, /^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/, /^(?:\|)/, /^(?:\|)/, /^(?:\))/, /^(?:\()/, /^(?:\])/, /^(?:\[)/, /^(?:(\}))/, /^(?:\{)/, /^(?:[^\[\]\(\)\{\}\|\"]+)/, /^(?:")/, /^(?:(\r?\n)+)/, /^(?:\s)/, /^(?:$)/], + conditions: { "callbackargs": { "rules": [11, 12, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "callbackname": { "rules": [8, 9, 10, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "href": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "click": { "rules": [15, 18, 27, 28, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "dottedEdgeText": { "rules": [15, 18, 67, 69, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "thickEdgeText": { "rules": [15, 18, 64, 66, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "edgeText": { "rules": [15, 18, 61, 63, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "trapText": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 84, 85, 86, 87, 88, 101, 103, 105, 107], "inclusive": false }, "ellipseText": { "rules": [15, 18, 70, 71, 72, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "text": { "rules": [15, 18, 70, 73, 74, 75, 76, 77, 80, 81, 82, 83, 87, 88, 100, 101, 102, 103, 104, 105, 106, 107, 108], "inclusive": false }, "vertex": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "dir": { "rules": [15, 18, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_descr_multiline": { "rules": [5, 6, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_descr": { "rules": [3, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_title": { "rules": [1, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "md_string": { "rules": [13, 14, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "string": { "rules": [15, 16, 17, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "INITIAL": { "rules": [0, 2, 4, 7, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 67, 68, 70, 73, 75, 77, 78, 79, 81, 83, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 101, 103, 105, 107, 109, 110, 111, 112], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const MERMAID_DOM_ID_PREFIX = "flowchart-"; +let vertexCounter = 0; +let config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); +let vertices = {}; +let edges = []; +let classes = {}; +let subGraphs = []; +let subGraphLookup = {}; +let tooltips = {}; +let subCount = 0; +let firstGraphFlag = true; +let direction; +let version; +let funs = []; +const sanitizeText = (txt) => _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(txt, config); +const lookUpDomId = function(id) { + const vertexKeys = Object.keys(vertices); + for (const vertexKey of vertexKeys) { + if (vertices[vertexKey].id === id) { + return vertices[vertexKey].domId; + } + } + return id; +}; +const addVertex = function(_id, textObj, type, style, classes2, dir, props = {}) { + let txt; + let id = _id; + if (id === void 0) { + return; + } + if (id.trim().length === 0) { + return; + } + if (vertices[id] === void 0) { + vertices[id] = { + id, + labelType: "text", + domId: MERMAID_DOM_ID_PREFIX + id + "-" + vertexCounter, + styles: [], + classes: [] + }; + } + vertexCounter++; + if (textObj !== void 0) { + config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + txt = sanitizeText(textObj.text.trim()); + vertices[id].labelType = textObj.type; + if (txt[0] === '"' && txt[txt.length - 1] === '"') { + txt = txt.substring(1, txt.length - 1); + } + vertices[id].text = txt; + } else { + if (vertices[id].text === void 0) { + vertices[id].text = _id; + } + } + if (type !== void 0) { + vertices[id].type = type; + } + if (style !== void 0 && style !== null) { + style.forEach(function(s) { + vertices[id].styles.push(s); + }); + } + if (classes2 !== void 0 && classes2 !== null) { + classes2.forEach(function(s) { + vertices[id].classes.push(s); + }); + } + if (dir !== void 0) { + vertices[id].dir = dir; + } + if (vertices[id].props === void 0) { + vertices[id].props = props; + } else if (props !== void 0) { + Object.assign(vertices[id].props, props); + } +}; +const addSingleLink = function(_start, _end, type) { + let start = _start; + let end = _end; + const edge = { start, end, type: void 0, text: "", labelType: "text" }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc78 Got edge...", edge); + const linkTextObj = type.text; + if (linkTextObj !== void 0) { + edge.text = sanitizeText(linkTextObj.text.trim()); + if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') { + edge.text = edge.text.substring(1, edge.text.length - 1); + } + edge.labelType = linkTextObj.type; + } + if (type !== void 0) { + edge.type = type.type; + edge.stroke = type.stroke; + edge.length = type.length; + } + if ((edge == null ? void 0 : edge.length) > 10) { + edge.length = 10; + } + if (edges.length < (config.maxEdges ?? 500)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc78 pushing edge..."); + edges.push(edge); + } else { + throw new Error( + `Edge limit exceeded. ${edges.length} edges found, but the limit is ${config.maxEdges}. + +Initialize mermaid with maxEdges set to a higher number to allow more edges. +You cannot set this config via configuration inside the diagram as it is a secure config. +You have to call mermaid.initialize.` + ); + } +}; +const addLink = function(_start, _end, type) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("addLink (abc78)", _start, _end, type); + let i, j; + for (i = 0; i < _start.length; i++) { + for (j = 0; j < _end.length; j++) { + addSingleLink(_start[i], _end[j], type); + } + } +}; +const updateLinkInterpolate = function(positions, interp) { + positions.forEach(function(pos) { + if (pos === "default") { + edges.defaultInterpolate = interp; + } else { + edges[pos].interpolate = interp; + } + }); +}; +const updateLink = function(positions, style) { + positions.forEach(function(pos) { + if (pos >= edges.length) { + throw new Error( + `The index ${pos} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${edges.length - 1}. (Help: Ensure that the index is within the range of existing edges.)` + ); + } + if (pos === "default") { + edges.defaultStyle = style; + } else { + if (_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.isSubstringInArray("fill", style) === -1) { + style.push("fill:none"); + } + edges[pos].style = style; + } + }); +}; +const addClass = function(ids, style) { + ids.split(",").forEach(function(id) { + if (classes[id] === void 0) { + classes[id] = { id, styles: [], textStyles: [] }; + } + if (style !== void 0 && style !== null) { + style.forEach(function(s) { + if (s.match("color")) { + const newStyle = s.replace("fill", "bgFill").replace("color", "fill"); + classes[id].textStyles.push(newStyle); + } + classes[id].styles.push(s); + }); + } + }); +}; +const setDirection = function(dir) { + direction = dir; + if (direction.match(/.*/)) { + direction = "LR"; + } + if (direction.match(/.*v/)) { + direction = "TB"; + } + if (direction === "TD") { + direction = "TB"; + } +}; +const setClass = function(ids, className) { + ids.split(",").forEach(function(_id) { + let id = _id; + if (vertices[id] !== void 0) { + vertices[id].classes.push(className); + } + if (subGraphLookup[id] !== void 0) { + subGraphLookup[id].classes.push(className); + } + }); +}; +const setTooltip = function(ids, tooltip) { + ids.split(",").forEach(function(id) { + if (tooltip !== void 0) { + tooltips[version === "gen-1" ? lookUpDomId(id) : id] = sanitizeText(tooltip); + } + }); +}; +const setClickFun = function(id, functionName, functionArgs) { + let domId = lookUpDomId(id); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel !== "loose") { + return; + } + if (functionName === void 0) { + return; + } + let argList = []; + if (typeof functionArgs === "string") { + argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); + for (let i = 0; i < argList.length; i++) { + let item = argList[i].trim(); + if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') { + item = item.substr(1, item.length - 2); + } + argList[i] = item; + } + } + if (argList.length === 0) { + argList.push(id); + } + if (vertices[id] !== void 0) { + vertices[id].haveCallback = true; + funs.push(function() { + const elem = document.querySelector(`[id="${domId}"]`); + if (elem !== null) { + elem.addEventListener( + "click", + function() { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.runFunc(functionName, ...argList); + }, + false + ); + } + }); + } +}; +const setLink = function(ids, linkStr, target) { + ids.split(",").forEach(function(id) { + if (vertices[id] !== void 0) { + vertices[id].link = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.formatUrl(linkStr, config); + vertices[id].linkTarget = target; + } + }); + setClass(ids, "clickable"); +}; +const getTooltip = function(id) { + if (tooltips.hasOwnProperty(id)) { + return tooltips[id]; + } + return void 0; +}; +const setClickEvent = function(ids, functionName, functionArgs) { + ids.split(",").forEach(function(id) { + setClickFun(id, functionName, functionArgs); + }); + setClass(ids, "clickable"); +}; +const bindFunctions = function(element) { + funs.forEach(function(fun) { + fun(element); + }); +}; +const getDirection = function() { + return direction.trim(); +}; +const getVertices = function() { + return vertices; +}; +const getEdges = function() { + return edges; +}; +const getClasses = function() { + return classes; +}; +const setupToolTips = function(element) { + let tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(".mermaidTooltip"); + if ((tooltipElem._groups || tooltipElem)[0][0] === null) { + tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body").append("div").attr("class", "mermaidTooltip").style("opacity", 0); + } + const svg = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(element).select("svg"); + const nodes = svg.selectAll("g.node"); + nodes.on("mouseover", function() { + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(this); + const title = el.attr("title"); + if (title === null) { + return; + } + const rect = this.getBoundingClientRect(); + tooltipElem.transition().duration(200).style("opacity", ".9"); + tooltipElem.text(el.attr("title")).style("left", window.scrollX + rect.left + (rect.right - rect.left) / 2 + "px").style("top", window.scrollY + rect.bottom + "px"); + tooltipElem.html(tooltipElem.html().replace(/<br\/>/g, "
")); + el.classed("hover", true); + }).on("mouseout", function() { + tooltipElem.transition().duration(500).style("opacity", 0); + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(this); + el.classed("hover", false); + }); +}; +funs.push(setupToolTips); +const clear = function(ver = "gen-1") { + vertices = {}; + classes = {}; + edges = []; + funs = [setupToolTips]; + subGraphs = []; + subGraphLookup = {}; + subCount = 0; + tooltips = {}; + firstGraphFlag = true; + version = ver; + config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.v)(); +}; +const setGen = (ver) => { + version = ver || "gen-2"; +}; +const defaultStyle = function() { + return "fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"; +}; +const addSubGraph = function(_id, list, _title) { + let id = _id.text.trim(); + let title = _title.text; + if (_id === _title && _title.text.match(/\s/)) { + id = void 0; + } + function uniq(a) { + const prims = { boolean: {}, number: {}, string: {} }; + const objs = []; + let dir2; + const nodeList2 = a.filter(function(item) { + const type = typeof item; + if (item.stmt && item.stmt === "dir") { + dir2 = item.value; + return false; + } + if (item.trim() === "") { + return false; + } + if (type in prims) { + return prims[type].hasOwnProperty(item) ? false : prims[type][item] = true; + } else { + return objs.includes(item) ? false : objs.push(item); + } + }); + return { nodeList: nodeList2, dir: dir2 }; + } + let nodeList = []; + const { nodeList: nl, dir } = uniq(nodeList.concat.apply(nodeList, list)); + nodeList = nl; + if (version === "gen-1") { + for (let i = 0; i < nodeList.length; i++) { + nodeList[i] = lookUpDomId(nodeList[i]); + } + } + id = id || "subGraph" + subCount; + title = title || ""; + title = sanitizeText(title); + subCount = subCount + 1; + const subGraph = { + id, + nodes: nodeList, + title: title.trim(), + classes: [], + dir, + labelType: _title.type + }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Adding", subGraph.id, subGraph.nodes, subGraph.dir); + subGraph.nodes = makeUniq(subGraph, subGraphs).nodes; + subGraphs.push(subGraph); + subGraphLookup[id] = subGraph; + return id; +}; +const getPosForId = function(id) { + for (const [i, subGraph] of subGraphs.entries()) { + if (subGraph.id === id) { + return i; + } + } + return -1; +}; +let secCount = -1; +const posCrossRef = []; +const indexNodes2 = function(id, pos) { + const nodes = subGraphs[pos].nodes; + secCount = secCount + 1; + if (secCount > 2e3) { + return; + } + posCrossRef[secCount] = pos; + if (subGraphs[pos].id === id) { + return { + result: true, + count: 0 + }; + } + let count = 0; + let posCount = 1; + while (count < nodes.length) { + const childPos = getPosForId(nodes[count]); + if (childPos >= 0) { + const res = indexNodes2(id, childPos); + if (res.result) { + return { + result: true, + count: posCount + res.count + }; + } else { + posCount = posCount + res.count; + } + } + count = count + 1; + } + return { + result: false, + count: posCount + }; +}; +const getDepthFirstPos = function(pos) { + return posCrossRef[pos]; +}; +const indexNodes = function() { + secCount = -1; + if (subGraphs.length > 0) { + indexNodes2("none", subGraphs.length - 1); + } +}; +const getSubGraphs = function() { + return subGraphs; +}; +const firstGraph = () => { + if (firstGraphFlag) { + firstGraphFlag = false; + return true; + } + return false; +}; +const destructStartLink = (_str) => { + let str = _str.trim(); + let type = "arrow_open"; + switch (str[0]) { + case "<": + type = "arrow_point"; + str = str.slice(1); + break; + case "x": + type = "arrow_cross"; + str = str.slice(1); + break; + case "o": + type = "arrow_circle"; + str = str.slice(1); + break; + } + let stroke = "normal"; + if (str.includes("=")) { + stroke = "thick"; + } + if (str.includes(".")) { + stroke = "dotted"; + } + return { type, stroke }; +}; +const countChar = (char, str) => { + const length = str.length; + let count = 0; + for (let i = 0; i < length; ++i) { + if (str[i] === char) { + ++count; + } + } + return count; +}; +const destructEndLink = (_str) => { + const str = _str.trim(); + let line = str.slice(0, -1); + let type = "arrow_open"; + switch (str.slice(-1)) { + case "x": + type = "arrow_cross"; + if (str[0] === "x") { + type = "double_" + type; + line = line.slice(1); + } + break; + case ">": + type = "arrow_point"; + if (str[0] === "<") { + type = "double_" + type; + line = line.slice(1); + } + break; + case "o": + type = "arrow_circle"; + if (str[0] === "o") { + type = "double_" + type; + line = line.slice(1); + } + break; + } + let stroke = "normal"; + let length = line.length - 1; + if (line[0] === "=") { + stroke = "thick"; + } + if (line[0] === "~") { + stroke = "invisible"; + } + let dots = countChar(".", line); + if (dots) { + stroke = "dotted"; + length = dots; + } + return { type, stroke, length }; +}; +const destructLink = (_str, _startStr) => { + const info = destructEndLink(_str); + let startInfo; + if (_startStr) { + startInfo = destructStartLink(_startStr); + if (startInfo.stroke !== info.stroke) { + return { type: "INVALID", stroke: "INVALID" }; + } + if (startInfo.type === "arrow_open") { + startInfo.type = info.type; + } else { + if (startInfo.type !== info.type) { + return { type: "INVALID", stroke: "INVALID" }; + } + startInfo.type = "double_" + startInfo.type; + } + if (startInfo.type === "double_arrow") { + startInfo.type = "double_arrow_point"; + } + startInfo.length = info.length; + return startInfo; + } + return info; +}; +const exists = (allSgs, _id) => { + let res = false; + allSgs.forEach((sg) => { + const pos = sg.nodes.indexOf(_id); + if (pos >= 0) { + res = true; + } + }); + return res; +}; +const makeUniq = (sg, allSubgraphs) => { + const res = []; + sg.nodes.forEach((_id, pos) => { + if (!exists(allSubgraphs, _id)) { + res.push(sg.nodes[pos]); + } + }); + return { nodes: res }; +}; +const lex = { + firstGraph +}; +const flowDb = { + defaultConfig: () => _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.K.flowchart, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.g, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.a, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.b, + addVertex, + lookUpDomId, + addLink, + updateLinkInterpolate, + updateLink, + addClass, + setDirection, + setClass, + setTooltip, + getTooltip, + setClickEvent, + setLink, + bindFunctions, + getDirection, + getVertices, + getEdges, + getClasses, + clear, + setGen, + defaultStyle, + addSubGraph, + getDepthFirstPos, + indexNodes, + getSubGraphs, + destructLink, + lex, + exists, + makeUniq, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.t +}; +const db = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + addClass, + addLink, + addSingleLink, + addSubGraph, + addVertex, + bindFunctions, + clear, + default: flowDb, + defaultStyle, + destructLink, + firstGraph, + getClasses, + getDepthFirstPos, + getDirection, + getEdges, + getSubGraphs, + getTooltip, + getVertices, + indexNodes, + lex, + lookUpDomId, + setClass, + setClickEvent, + setDirection, + setGen, + setLink, + updateLink, + updateLinkInterpolate +}, Symbol.toStringTag, { value: "Module" })); + + + +/***/ }), + +/***/ 62317: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _flowDb_4b19a42f_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(66216); +/* harmony import */ var _styles_3ed67cfa_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(98696); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(697); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21176); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(14075); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(99418); + + + + + + + + + + + + + + + + + + + + + +const diagram = { + parser: _flowDb_4b19a42f_js__WEBPACK_IMPORTED_MODULE_7__.p, + db: _flowDb_4b19a42f_js__WEBPACK_IMPORTED_MODULE_7__.f, + renderer: _styles_3ed67cfa_js__WEBPACK_IMPORTED_MODULE_8__.f, + styles: _styles_3ed67cfa_js__WEBPACK_IMPORTED_MODULE_8__.a, + init: (cnf) => { + if (!cnf.flowchart) { + cnf.flowchart = {}; + } + cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_9__.p)({ flowchart: { arrowMarkerAbsolute: cnf.arrowMarkerAbsolute } }); + _styles_3ed67cfa_js__WEBPACK_IMPORTED_MODULE_8__.f.setConf(cnf.flowchart); + _flowDb_4b19a42f_js__WEBPACK_IMPORTED_MODULE_7__.f.clear(); + _flowDb_4b19a42f_js__WEBPACK_IMPORTED_MODULE_7__.f.setGen("gen-2"); + } +}; + + + +/***/ }), + +/***/ 92746: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ r: () => (/* binding */ render) +/* harmony export */ }); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(21176); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14075); +/* harmony import */ var _edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(28747); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(76257); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(697); +/* harmony import */ var _createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(40351); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(26312); + + + + + + + +let clusterDb = {}; +let descendants = {}; +let parents = {}; +const clear$1 = () => { + descendants = {}; + parents = {}; + clusterDb = {}; +}; +const isDescendant = (id, ancestorId) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("In isDescendant", ancestorId, " ", id, " = ", descendants[ancestorId].includes(id)); + if (descendants[ancestorId].includes(id)) { + return true; + } + return false; +}; +const edgeInCluster = (edge, clusterId) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Descendants of ", clusterId, " is ", descendants[clusterId]); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge is ", edge); + if (edge.v === clusterId) { + return false; + } + if (edge.w === clusterId) { + return false; + } + if (!descendants[clusterId]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Tilt, ", clusterId, ",not in descendants"); + return false; + } + return descendants[clusterId].includes(edge.v) || isDescendant(edge.v, clusterId) || isDescendant(edge.w, clusterId) || descendants[clusterId].includes(edge.w); +}; +const copy = (clusterId, graph, newGraph, rootId) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Copying children of ", + clusterId, + "root", + rootId, + "data", + graph.node(clusterId), + rootId + ); + const nodes = graph.children(clusterId) || []; + if (clusterId !== rootId) { + nodes.push(clusterId); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Copying (nodes) clusterId", clusterId, "nodes", nodes); + nodes.forEach((node) => { + if (graph.children(node).length > 0) { + copy(node, graph, newGraph, rootId); + } else { + const data = graph.node(node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("cp ", node, " to ", rootId, " with parent ", clusterId); + newGraph.setNode(node, data); + if (rootId !== graph.parent(node)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Setting parent", node, graph.parent(node)); + newGraph.setParent(node, graph.parent(node)); + } + if (clusterId !== rootId && node !== clusterId) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Setting parent", node, clusterId); + newGraph.setParent(node, clusterId); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("In copy ", clusterId, "root", rootId, "data", graph.node(clusterId), rootId); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Not Setting parent for node=", + node, + "cluster!==rootId", + clusterId !== rootId, + "node!==clusterId", + node !== clusterId + ); + } + const edges = graph.edges(node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Copying Edges", edges); + edges.forEach((edge) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge", edge); + const data2 = graph.edge(edge.v, edge.w, edge.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge data", data2, rootId); + try { + if (edgeInCluster(edge, rootId)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Copying as ", edge.v, edge.w, data2, edge.name); + newGraph.setEdge(edge.v, edge.w, data2, edge.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("newGraph edges ", newGraph.edges(), newGraph.edge(newGraph.edges()[0])); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Skipping copy of edge ", + edge.v, + "-->", + edge.w, + " rootId: ", + rootId, + " clusterId:", + clusterId + ); + } + } catch (e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error(e); + } + }); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Removing node", node); + graph.removeNode(node); + }); +}; +const extractDescendants = (id, graph) => { + const children = graph.children(id); + let res = [...children]; + for (const child of children) { + parents[child] = id; + res = [...res, ...extractDescendants(child, graph)]; + } + return res; +}; +const findNonClusterChild = (id, graph) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching", id); + const children = graph.children(id); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching children of id ", id, children); + if (children.length < 1) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("This is a valid node", id); + return id; + } + for (const child of children) { + const _id = findNonClusterChild(child, graph); + if (_id) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Found replacement for", id, " => ", _id); + return _id; + } + } +}; +const getAnchorId = (id) => { + if (!clusterDb[id]) { + return id; + } + if (!clusterDb[id].externalConnections) { + return id; + } + if (clusterDb[id]) { + return clusterDb[id].id; + } + return id; +}; +const adjustClustersAndEdges = (graph, depth) => { + if (!graph || depth > 10) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting out, no graph "); + return; + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting in, graph "); + } + graph.nodes().forEach(function(id) { + const children = graph.children(id); + if (children.length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster identified", + id, + " Replacement id in edges: ", + findNonClusterChild(id, graph) + ); + descendants[id] = extractDescendants(id, graph); + clusterDb[id] = { id: findNonClusterChild(id, graph), clusterData: graph.node(id) }; + } + }); + graph.nodes().forEach(function(id) { + const children = graph.children(id); + const edges = graph.edges(); + if (children.length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Cluster identified", id, descendants); + edges.forEach((edge) => { + if (edge.v !== id && edge.w !== id) { + const d1 = isDescendant(edge.v, id); + const d2 = isDescendant(edge.w, id); + if (d1 ^ d2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge: ", edge, " leaves cluster ", id); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Descendants of XXX ", id, ": ", descendants[id]); + clusterDb[id].externalConnections = true; + } + } + }); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster ", id, descendants); + } + }); + for (let id of Object.keys(clusterDb)) { + const nonClusterChild = clusterDb[id].id; + const parent = graph.parent(nonClusterChild); + if (parent !== id && clusterDb[parent] && !clusterDb[parent].externalConnections) { + clusterDb[id].id = parent; + } + } + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(graph.edge(e))); + let v = e.v; + let w = e.w; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Fix XXX", + clusterDb, + "ids:", + e.v, + e.w, + "Translating: ", + clusterDb[e.v], + " --- ", + clusterDb[e.w] + ); + if (clusterDb[e.v] && clusterDb[e.w] && clusterDb[e.v] === clusterDb[e.w]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing link to self - removing XXX", e.v, e.w, e.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + const specialId = e.w + "---" + e.v; + graph.setNode(specialId, { + domId: specialId, + id: specialId, + labelStyle: "", + labelText: edge.label, + padding: 0, + shape: "labelRect", + style: "" + }); + const edge1 = structuredClone(edge); + const edge2 = structuredClone(edge); + edge1.label = ""; + edge1.arrowTypeEnd = "none"; + edge2.label = ""; + edge1.fromCluster = e.v; + edge2.toCluster = e.v; + graph.setEdge(v, specialId, edge1, e.name + "-cyclic-special"); + graph.setEdge(specialId, w, edge2, e.name + "-cyclic-special"); + } else if (clusterDb[e.v] || clusterDb[e.w]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + if (v !== e.v) { + const parent = graph.parent(v); + clusterDb[parent].externalConnections = true; + edge.fromCluster = e.v; + } + if (w !== e.w) { + const parent = graph.parent(w); + clusterDb[parent].externalConnections = true; + edge.toCluster = e.w; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fix Replacing with XXX", v, w, e.name); + graph.setEdge(v, w, edge, e.name); + } + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Adjusted Graph", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + extractor(graph, 0); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace(clusterDb); +}; +const extractor = (graph, depth) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("extractor - ", depth, dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph), graph.children("D")); + if (depth > 10) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error("Bailing out"); + return; + } + let nodes = graph.nodes(); + let hasChildren = false; + for (const node of nodes) { + const children = graph.children(node); + hasChildren = hasChildren || children.length > 0; + } + if (!hasChildren) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Done, no node has children", graph.nodes()); + return; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Nodes = ", nodes, depth); + for (const node of nodes) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Extracting node", + node, + clusterDb, + clusterDb[node] && !clusterDb[node].externalConnections, + !graph.parent(node), + graph.node(node), + graph.children("D"), + " Depth ", + depth + ); + if (!clusterDb[node]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster", node, depth); + } else if (!clusterDb[node].externalConnections && // !graph.parent(node) && + graph.children(node) && graph.children(node).length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster without external connections, without a parent and with children", + node, + depth + ); + const graphSettings = graph.graph(); + let dir = graphSettings.rankdir === "TB" ? "LR" : "TB"; + if (clusterDb[node] && clusterDb[node].clusterData && clusterDb[node].clusterData.dir) { + dir = clusterDb[node].clusterData.dir; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing dir", clusterDb[node].clusterData.dir, dir); + } + const clusterGraph = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .T({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + // Todo: set proper spacing + nodesep: 50, + ranksep: 50, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Old graph before copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + copy(node, graph, clusterGraph, node); + graph.setNode(node, { + clusterNode: true, + id: node, + clusterData: clusterDb[node].clusterData, + labelText: clusterDb[node].labelText, + graph: clusterGraph + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New graph after copy node: (", node, ")", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(clusterGraph)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Old graph after copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster ** ", + node, + " **not meeting the criteria !externalConnections:", + !clusterDb[node].externalConnections, + " no parent: ", + !graph.parent(node), + " children ", + graph.children(node) && graph.children(node).length > 0, + graph.children("D"), + depth + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(clusterDb); + } + } + nodes = graph.nodes(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New list of nodes", nodes); + for (const node of nodes) { + const data = graph.node(node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn(" Now next level", node, data); + if (data.clusterNode) { + extractor(data.graph, depth + 1); + } + } +}; +const sorter = (graph, nodes) => { + if (nodes.length === 0) { + return []; + } + let result = Object.assign(nodes); + nodes.forEach((node) => { + const children = graph.children(node); + const sorted = sorter(graph, children); + result = [...result, ...sorted]; + }); + return result; +}; +const sortNodesByHierarchy = (graph) => sorter(graph, graph.children()); +const rect = (parent, node) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Creating subgraph rect for ", node.id, node); + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const shapeSvg = parent.insert("g").attr("class", "cluster" + (node.class ? " " + node.class : "")).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const useHtmlLabels = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const text = node.labelType === "markdown" ? (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_5__.a)(label, node.labelText, { style: node.labelStyle, useHtmlLabels }) : label.node().appendChild((0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width; + if (node.width <= bbox.width + padding) { + node.diff = (bbox.width - node.width) / 2 - node.padding / 2; + } else { + node.diff = -node.padding / 2; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Data ", node, JSON.stringify(node)); + rect2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - width / 2).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width).attr("height", node.height + padding); + const { subGraphTitleTopMargin } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.g)(siteConfig); + if (useHtmlLabels) { + label.attr( + "transform", + // This puts the label on top of the box instead of inside it + `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 + subGraphTitleTopMargin})` + ); + } else { + label.attr( + "transform", + // This puts the label on top of the box instead of inside it + `translate(${node.x}, ${node.y - node.height / 2 + subGraphTitleTopMargin})` + ); + } + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const noteGroup = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "note-cluster").attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", node.width + padding).attr("height", node.height + padding).attr("fill", "none"); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const roundedWithTitle = (parent, node) => { + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const innerRect = shapeSvg.append("rect"); + const text = label.node().appendChild((0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + bbox = text.getBBox(); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width; + if (node.width <= bbox.width + node.padding) { + node.diff = (bbox.width + node.padding * 0 - node.width) / 2; + } else { + node.diff = -node.padding / 2; + } + rect2.attr("class", "outer").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width + padding).attr("height", node.height + padding); + innerRect.attr("class", "inner").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding + bbox.height - 1).attr("width", width + padding).attr("height", node.height + padding - bbox.height - 3); + const { subGraphTitleTopMargin } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.g)(siteConfig); + label.attr( + "transform", + `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 - node.padding / 3 + ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels) ? 5 : 3) + subGraphTitleTopMargin})` + ); + const rectBox = rect2.node().getBBox(); + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const divider = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("class", "divider").attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2).attr("width", node.width + padding).attr("height", node.height + padding); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.diff = -node.padding / 2; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const shapes = { rect, roundedWithTitle, noteGroup, divider }; +let clusterElems = {}; +const insertCluster = (elem, node) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Inserting cluster"); + const shape = node.shape || "rect"; + clusterElems[node.id] = shapes[shape](elem, node); +}; +const clear = () => { + clusterElems = {}; +}; +const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, siteConfig) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph in recursive render: XXX", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph), parentCluster); + const dir = graph.graph().rankdir; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Dir in recursive render - dir:", dir); + const elem = _elem.insert("g").attr("class", "root"); + if (!graph.nodes()) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("No nodes found for", graph); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Recursive render XXX", graph.nodes()); + } + if (graph.edges().length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Recursive edges", graph.edge(graph.edges()[0])); + } + const clusters = elem.insert("g").attr("class", "clusters"); + const edgePaths = elem.insert("g").attr("class", "edgePaths"); + const edgeLabels = elem.insert("g").attr("class", "edgeLabels"); + const nodes = elem.insert("g").attr("class", "nodes"); + await Promise.all( + graph.nodes().map(async function(v) { + const node = graph.node(v); + if (parentCluster !== void 0) { + const data = JSON.parse(JSON.stringify(parentCluster.clusterData)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Setting data for cluster XXX (", v, ") ", data, parentCluster); + graph.setNode(parentCluster.id, data); + if (!graph.parent(v)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Setting parent", v, parentCluster.id); + graph.setParent(v, parentCluster.id, data); + } + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("(Insert) Node XXX" + v + ": " + JSON.stringify(graph.node(v))); + if (node && node.clusterNode) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster identified", v, node.width, graph.node(v)); + const o = await recursiveRender( + nodes, + node.graph, + diagramType, + id, + graph.node(v), + siteConfig + ); + const newEl = o.elem; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.u)(node, newEl); + node.diff = o.diff || 0; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node bounds (abc123)", v, node, node.width, node.x, node.y); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.s)(newEl, node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Recursive render complete ", newEl, node); + } else { + if (graph.children(v).length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster - the non recursive path XXX", v, node.id, node, graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info(findNonClusterChild(node.id, graph)); + clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node }; + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node - the non recursive path", v, node.id, node); + await (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.e)(nodes, graph.node(v), dir); + } + } + }) + ); + graph.edges().forEach(function(e) { + const edge = graph.edge(e.v, e.w, e.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": ", e, " ", JSON.stringify(graph.edge(e))); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Fix", clusterDb, "ids:", e.v, e.w, "Translating: ", clusterDb[e.v], clusterDb[e.w]); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.f)(edgeLabels, edge); + }); + graph.edges().forEach(function(e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("### Layout ###"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info(graph); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__/* .layout */ .Zp)(graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph after layout:", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + let diff = 0; + const { subGraphTitleTotalMargin } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.g)(siteConfig); + sortNodesByHierarchy(graph).forEach(function(v) { + const node = graph.node(v); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Position " + v + ": " + JSON.stringify(graph.node(v))); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Position " + v + ": (" + node.x, + "," + node.y, + ") width: ", + node.width, + " height: ", + node.height + ); + if (node && node.clusterNode) { + node.y += subGraphTitleTotalMargin; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } else { + if (graph.children(v).length > 0) { + node.height += subGraphTitleTotalMargin; + insertCluster(clusters, node); + clusterDb[node.id].node = node; + } else { + node.y += subGraphTitleTotalMargin / 2; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } + } + }); + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(edge), edge); + edge.points.forEach((point) => point.y += subGraphTitleTotalMargin / 2); + const paths = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.h)(edgePaths, e, edge, clusterDb, diagramType, graph, id); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.j)(edge, paths); + }); + graph.nodes().forEach(function(v) { + const n = graph.node(v); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info(v, n.type, n.diff); + if (n.type === "group") { + diff = n.diff; + } + }); + return { elem, diff }; +}; +const render = async (elem, graph, markers, diagramType, id) => { + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.a)(elem, markers, diagramType, id); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.b)(); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.d)(); + clear(); + clear$1(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph at first:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph))); + adjustClustersAndEdges(graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph after:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph))); + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + await recursiveRender(elem, graph, diagramType, id, void 0, siteConfig); +}; + + + +/***/ }), + +/***/ 98696: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ flowStyles), +/* harmony export */ f: () => (/* binding */ flowRendererV2) +/* harmony export */ }); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(697); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(26312); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(76257); +/* harmony import */ var _index_fc10efb0_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(92746); +/* harmony import */ var dagre_d3_es_src_dagre_js_label_add_html_label_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(10646); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(75937); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(25582); + + + + + + +const conf = {}; +const setConf = function(cnf) { + const keys = Object.keys(cnf); + for (const key of keys) { + conf[key] = cnf[key]; + } +}; +const addVertices = async function(vert, g, svgId, root, doc, diagObj) { + const svg = root.select(`[id="${svgId}"]`); + const keys = Object.keys(vert); + for (const id of keys) { + const vertex = vert[id]; + let classStr = "default"; + if (vertex.classes.length > 0) { + classStr = vertex.classes.join(" "); + } + classStr = classStr + " flowchart-label"; + const styles = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.k)(vertex.styles); + let vertexText = vertex.text !== void 0 ? vertex.text : vertex.id; + let vertexNode; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("vertex", vertex, vertex.labelType); + if (vertex.labelType === "markdown") { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("vertex", vertex, vertex.labelType); + } else { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.c)().flowchart.htmlLabels)) { + const node = { + label: vertexText + }; + vertexNode = (0,dagre_d3_es_src_dagre_js_label_add_html_label_js__WEBPACK_IMPORTED_MODULE_3__/* .addHtmlLabel */ .H)(svg, node).node(); + vertexNode.parentNode.removeChild(vertexNode); + } else { + const svgLabel = doc.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", styles.labelStyle.replace("color:", "fill:")); + const rows = vertexText.split(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.e.lineBreakRegex); + for (const row of rows) { + const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "1"); + tspan.textContent = row; + svgLabel.appendChild(tspan); + } + vertexNode = svgLabel; + } + } + let radius = 0; + let _shape = ""; + switch (vertex.type) { + case "round": + radius = 5; + _shape = "rect"; + break; + case "square": + _shape = "rect"; + break; + case "diamond": + _shape = "question"; + break; + case "hexagon": + _shape = "hexagon"; + break; + case "odd": + _shape = "rect_left_inv_arrow"; + break; + case "lean_right": + _shape = "lean_right"; + break; + case "lean_left": + _shape = "lean_left"; + break; + case "trapezoid": + _shape = "trapezoid"; + break; + case "inv_trapezoid": + _shape = "inv_trapezoid"; + break; + case "odd_right": + _shape = "rect_left_inv_arrow"; + break; + case "circle": + _shape = "circle"; + break; + case "ellipse": + _shape = "ellipse"; + break; + case "stadium": + _shape = "stadium"; + break; + case "subroutine": + _shape = "subroutine"; + break; + case "cylinder": + _shape = "cylinder"; + break; + case "group": + _shape = "rect"; + break; + case "doublecircle": + _shape = "doublecircle"; + break; + default: + _shape = "rect"; + } + const labelText = await (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.r)(vertexText, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.c)()); + g.setNode(vertex.id, { + labelStyle: styles.labelStyle, + shape: _shape, + labelText, + labelType: vertex.labelType, + rx: radius, + ry: radius, + class: classStr, + style: styles.style, + id: vertex.id, + link: vertex.link, + linkTarget: vertex.linkTarget, + tooltip: diagObj.db.getTooltip(vertex.id) || "", + domId: diagObj.db.lookUpDomId(vertex.id), + haveCallback: vertex.haveCallback, + width: vertex.type === "group" ? 500 : void 0, + dir: vertex.dir, + type: vertex.type, + props: vertex.props, + padding: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.c)().flowchart.padding + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("setNode", { + labelStyle: styles.labelStyle, + labelType: vertex.labelType, + shape: _shape, + labelText, + rx: radius, + ry: radius, + class: classStr, + style: styles.style, + id: vertex.id, + domId: diagObj.db.lookUpDomId(vertex.id), + width: vertex.type === "group" ? 500 : void 0, + type: vertex.type, + dir: vertex.dir, + props: vertex.props, + padding: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.c)().flowchart.padding + }); + } +}; +const addEdges = async function(edges, g, diagObj) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("abc78 edges = ", edges); + let cnt = 0; + let linkIdCnt = {}; + let defaultStyle; + let defaultLabelStyle; + if (edges.defaultStyle !== void 0) { + const defaultStyles = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.k)(edges.defaultStyle); + defaultStyle = defaultStyles.style; + defaultLabelStyle = defaultStyles.labelStyle; + } + for (const edge of edges) { + cnt++; + const linkIdBase = "L-" + edge.start + "-" + edge.end; + if (linkIdCnt[linkIdBase] === void 0) { + linkIdCnt[linkIdBase] = 0; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); + } else { + linkIdCnt[linkIdBase]++; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); + } + let linkId = linkIdBase + "-" + linkIdCnt[linkIdBase]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("abc78 new link id to be used is", linkIdBase, linkId, linkIdCnt[linkIdBase]); + const linkNameStart = "LS-" + edge.start; + const linkNameEnd = "LE-" + edge.end; + const edgeData = { style: "", labelStyle: "" }; + edgeData.minlen = edge.length || 1; + if (edge.type === "arrow_open") { + edgeData.arrowhead = "none"; + } else { + edgeData.arrowhead = "normal"; + } + edgeData.arrowTypeStart = "arrow_open"; + edgeData.arrowTypeEnd = "arrow_open"; + switch (edge.type) { + case "double_arrow_cross": + edgeData.arrowTypeStart = "arrow_cross"; + case "arrow_cross": + edgeData.arrowTypeEnd = "arrow_cross"; + break; + case "double_arrow_point": + edgeData.arrowTypeStart = "arrow_point"; + case "arrow_point": + edgeData.arrowTypeEnd = "arrow_point"; + break; + case "double_arrow_circle": + edgeData.arrowTypeStart = "arrow_circle"; + case "arrow_circle": + edgeData.arrowTypeEnd = "arrow_circle"; + break; + } + let style = ""; + let labelStyle = ""; + switch (edge.stroke) { + case "normal": + style = "fill:none;"; + if (defaultStyle !== void 0) { + style = defaultStyle; + } + if (defaultLabelStyle !== void 0) { + labelStyle = defaultLabelStyle; + } + edgeData.thickness = "normal"; + edgeData.pattern = "solid"; + break; + case "dotted": + edgeData.thickness = "normal"; + edgeData.pattern = "dotted"; + edgeData.style = "fill:none;stroke-width:2px;stroke-dasharray:3;"; + break; + case "thick": + edgeData.thickness = "thick"; + edgeData.pattern = "solid"; + edgeData.style = "stroke-width: 3.5px;fill:none;"; + break; + case "invisible": + edgeData.thickness = "invisible"; + edgeData.pattern = "solid"; + edgeData.style = "stroke-width: 0;fill:none;"; + break; + } + if (edge.style !== void 0) { + const styles = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.k)(edge.style); + style = styles.style; + labelStyle = styles.labelStyle; + } + edgeData.style = edgeData.style += style; + edgeData.labelStyle = edgeData.labelStyle += labelStyle; + if (edge.interpolate !== void 0) { + edgeData.curve = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.n)(edge.interpolate, d3__WEBPACK_IMPORTED_MODULE_1__/* .curveLinear */ .lUB); + } else if (edges.defaultInterpolate !== void 0) { + edgeData.curve = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.n)(edges.defaultInterpolate, d3__WEBPACK_IMPORTED_MODULE_1__/* .curveLinear */ .lUB); + } else { + edgeData.curve = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.n)(conf.curve, d3__WEBPACK_IMPORTED_MODULE_1__/* .curveLinear */ .lUB); + } + if (edge.text === void 0) { + if (edge.style !== void 0) { + edgeData.arrowheadStyle = "fill: #333"; + } + } else { + edgeData.arrowheadStyle = "fill: #333"; + edgeData.labelpos = "c"; + } + edgeData.labelType = edge.labelType; + edgeData.label = await (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.r)(edge.text.replace(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.e.lineBreakRegex, "\n"), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.c)()); + if (edge.style === void 0) { + edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none;"; + } + edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:"); + edgeData.id = linkId; + edgeData.classes = "flowchart-link " + linkNameStart + " " + linkNameEnd; + g.setEdge(edge.start, edge.end, edgeData, cnt); + } +}; +const getClasses = function(text, diagObj) { + return diagObj.db.getClasses(); +}; +const draw = async function(text, id, _version, diagObj) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("Drawing flowchart"); + let dir = diagObj.db.getDirection(); + if (dir === void 0) { + dir = "TD"; + } + const { securityLevel, flowchart: conf2 } = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.c)(); + const nodeSpacing = conf2.nodeSpacing || 50; + const rankSpacing = conf2.rankSpacing || 50; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + const g = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_0__/* .Graph */ .T({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + nodesep: nodeSpacing, + ranksep: rankSpacing, + marginx: 0, + marginy: 0 + }).setDefaultEdgeLabel(function() { + return {}; + }); + let subG; + const subGraphs = diagObj.db.getSubGraphs(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("Subgraphs - ", subGraphs); + for (let i2 = subGraphs.length - 1; i2 >= 0; i2--) { + subG = subGraphs[i2]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("Subgraph - ", subG); + diagObj.db.addVertex( + subG.id, + { text: subG.title, type: subG.labelType }, + "group", + void 0, + subG.classes, + subG.dir + ); + } + const vert = diagObj.db.getVertices(); + const edges = diagObj.db.getEdges(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("Edges", edges); + let i = 0; + for (i = subGraphs.length - 1; i >= 0; i--) { + subG = subGraphs[i]; + (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .selectAll */ .Ubm)("cluster").append("text"); + for (let j = 0; j < subG.nodes.length; j++) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.l.info("Setting up subgraphs", subG.nodes[j], subG.id); + g.setParent(subG.nodes[j], subG.id); + } + } + await addVertices(vert, g, id, root, doc, diagObj); + await addEdges(edges, g); + const svg = root.select(`[id="${id}"]`); + const element = root.select("#" + id + " g"); + await (0,_index_fc10efb0_js__WEBPACK_IMPORTED_MODULE_4__.r)(element, g, ["point", "circle", "cross"], "flowchart", id); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.u.insertTitle(svg, "flowchartTitleText", conf2.titleTopMargin, diagObj.db.getDiagramTitle()); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_2__.o)(g, svg, conf2.diagramPadding, conf2.useMaxWidth); + diagObj.db.indexNodes("subGraph" + i); + if (!conf2.htmlLabels) { + const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); + for (const label of labels) { + const dim = label.getBBox(); + const rect = doc.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.setAttribute("rx", 0); + rect.setAttribute("ry", 0); + rect.setAttribute("width", dim.width); + rect.setAttribute("height", dim.height); + label.insertBefore(rect, label.firstChild); + } + } + const keys = Object.keys(vert); + keys.forEach(function(key) { + const vertex = vert[key]; + if (vertex.link) { + const node = (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)("#" + id + ' [id="' + key + '"]'); + if (node) { + const link = doc.createElementNS("http://www.w3.org/2000/svg", "a"); + link.setAttributeNS("http://www.w3.org/2000/svg", "class", vertex.classes.join(" ")); + link.setAttributeNS("http://www.w3.org/2000/svg", "href", vertex.link); + link.setAttributeNS("http://www.w3.org/2000/svg", "rel", "noopener"); + if (securityLevel === "sandbox") { + link.setAttributeNS("http://www.w3.org/2000/svg", "target", "_top"); + } else if (vertex.linkTarget) { + link.setAttributeNS("http://www.w3.org/2000/svg", "target", vertex.linkTarget); + } + const linkNode = node.insert(function() { + return link; + }, ":first-child"); + const shape = node.select(".label-container"); + if (shape) { + linkNode.append(function() { + return shape.node(); + }); + } + const label = node.select(".label"); + if (label) { + linkNode.append(function() { + return label.node(); + }); + } + } + } + }); +}; +const flowRendererV2 = { + setConf, + addVertices, + addEdges, + getClasses, + draw +}; +const fade = (color, opacity) => { + const channel = khroma__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A; + const r = channel(color, "r"); + const g = channel(color, "g"); + const b = channel(color, "b"); + return khroma__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A(r, g, b, opacity); +}; +const getStyles = (options) => `.label { + font-family: ${options.fontFamily}; + color: ${options.nodeTextColor || options.textColor}; + } + .cluster-label text { + fill: ${options.titleColor}; + } + .cluster-label span,p { + color: ${options.titleColor}; + } + + .label text,span,p { + fill: ${options.nodeTextColor || options.textColor}; + color: ${options.nodeTextColor || options.textColor}; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + .flowchart-label text { + text-anchor: middle; + } + // .flowchart-label .text-outer-tspan { + // text-anchor: middle; + // } + // .flowchart-label .text-inner-tspan { + // text-anchor: start; + // } + + .node .katex path { + fill: #000; + stroke: #000; + stroke-width: 1px; + } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${options.arrowheadColor}; + } + + .edgePath .path { + stroke: ${options.lineColor}; + stroke-width: 2.0px; + } + + .flowchart-link { + stroke: ${options.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${options.edgeLabelBackground}; + rect { + opacity: 0.5; + background-color: ${options.edgeLabelBackground}; + fill: ${options.edgeLabelBackground}; + } + text-align: center; + } + + /* For html labels only */ + .labelBkg { + background-color: ${fade(options.edgeLabelBackground, 0.5)}; + // background-color: + } + + .cluster rect { + fill: ${options.clusterBkg}; + stroke: ${options.clusterBorder}; + stroke-width: 1px; + } + + .cluster text { + fill: ${options.titleColor}; + } + + .cluster span,p { + color: ${options.titleColor}; + } + /* .cluster div { + color: ${options.titleColor}; + } */ + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${options.fontFamily}; + font-size: 12px; + background: ${options.tertiaryColor}; + border: 1px solid ${options.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } +`; +const flowStyles = getStyles; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/320ccb30.348a2cf8.js b/assets/js/320ccb30.348a2cf8.js new file mode 100644 index 0000000000..d9abf48c27 --- /dev/null +++ b/assets/js/320ccb30.348a2cf8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7677],{60032:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var s=t(74848),o=t(28453);const i={},r="OAUTH",c={id:"operating-scs/components/monitoring/docs/oauth",title:"OAUTH",description:"We set up oauth2 with GitHub provider for the https//kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/.",source:"@site/docs/04-operating-scs/components/monitoring/docs/oauth.md",sourceDirName:"04-operating-scs/components/monitoring/docs",slug:"/operating-scs/components/monitoring/docs/oauth",permalink:"/docs/operating-scs/components/monitoring/docs/oauth",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/oauth.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Alertmanager notifications in Matrix chat",permalink:"/docs/operating-scs/components/monitoring/docs/alertmanager"},next:{title:"Traces",permalink:"/docs/operating-scs/components/monitoring/docs/tracing"}},a={},l=[];function d(e){const n={a:"a",code:"code",h1:"h1",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"oauth",children:"OAUTH"}),"\n",(0,s.jsxs)(n.p,{children:["We set up oauth2 with GitHub provider for the ",(0,s.jsx)(n.a,{href:"https://monitoring.scs.community",children:"https://monitoring.scs.community"})," according to the ",(0,s.jsx)(n.a,{href:"https://kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/",children:"https://kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["To use it, inspect ",(0,s.jsx)(n.code,{children:"oauth/oauth2-proxy.yaml"})," and modify it according to your needs.\nYou want to change at least these:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"OAUTH2_PROXY_CLIENT_ID"}),"\n",(0,s.jsx)(n.li,{children:"OAUTH2_PROXY_CLIENT_SECRET"}),"\n",(0,s.jsx)(n.li,{children:"OAUTH2_PROXY_COOKIE_SECRET"}),"\n",(0,s.jsx)(n.li,{children:"ingress host"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Then deploy oauth2-proxy as follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f oauth/oauth2-proxy.yaml\n"})}),"\n",(0,s.jsx)(n.p,{children:"We set up OAuth authentication for these components:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Thanos Query","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"it is exposed via ingress on monitoring.scs.community/thanos"}),"\n",(0,s.jsxs)(n.li,{children:["modified with ",(0,s.jsx)(n.code,{children:"--web.external-prefix=thanos"})," extra flag","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"ruler query endpoint and grafana datasource url need to be modified"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Alertmanager","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"it is exposed via ingress on monitoring.scs.community/alertmanager"}),"\n",(0,s.jsxs)(n.li,{children:["modified with ",(0,s.jsx)(n.code,{children:"routePrefix: /alertmanager"})," alertmanagerSpec","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"ruler alertmanager url needs to be modified"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["You have to also uncomment a related sections in ",(0,s.jsx)(n.code,{children:"values-observer.yaml"})," for exposing\nthe components via ingress.\nThe sections related to OAUTH in the ",(0,s.jsx)(n.code,{children:"values-observer-scs.yaml"})," values file are already uncommented."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>c});var s=t(96540);const o={},i=s.createContext(o);function r(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/32227eef.33868d63.js b/assets/js/32227eef.33868d63.js new file mode 100644 index 0000000000..4e622c982b --- /dev/null +++ b/assets/js/32227eef.33868d63.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3429],{40710:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>o});var t=n(74848),s=n(28453);const r={title:"Sovereign Cloud Standards YAML",type:"Procedural",status:"Draft",track:"Global",description:"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,\ncategorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning\nin a machine-readable YAML format for clarity, traceability, and tool integration.\n"},a=void 0,d={id:"scs-0003-v1-sovereign-cloud-standards-yaml",title:"Sovereign Cloud Standards YAML",description:"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,\ncategorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning\nin a machine-readable YAML format for clarity, traceability, and tool integration.\n",source:"@site/standards/scs-0003-v1-sovereign-cloud-standards-yaml.md",sourceDirName:".",slug:"/scs-0003-v1-sovereign-cloud-standards-yaml",permalink:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Sovereign Cloud Standards YAML",type:"Procedural",status:"Draft",track:"Global",description:"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,\ncategorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning\nin a machine-readable YAML format for clarity, traceability, and tool integration.\n"},sidebar:"standards",previous:{title:"scs-0003: Sovereign Cloud Standards YAML",permalink:"/standards/global/scs-0003"},next:{title:"scs-0004: Regulations for achieving SCS-compatible certification",permalink:"/standards/global/scs-0004"}},c={},o=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Overview of mandatory SCS standards",id:"overview-of-mandatory-scs-standards",level:3},{value:"Lifecycle of certificate scopes",id:"lifecycle-of-certificate-scopes",level:3},{value:"Machine-readability for further processing",id:"machine-readability-for-further-processing",level:3},{value:"SCS Certification YAML",id:"scs-certification-yaml",level:2},{value:"Prerequisite descriptor",id:"prerequisite-descriptor",level:3},{value:"Version descriptor",id:"version-descriptor",level:3},{value:"Standard descriptor",id:"standard-descriptor",level:3},{value:"Check descriptor",id:"check-descriptor",level:3},{value:"Automated check",id:"automated-check",level:4},{value:"Manual check",id:"manual-check",level:4},{value:"Basic Example",id:"basic-example",level:3},{value:"Process",id:"process",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"File format",id:"file-format",level:3},{value:"Dependency graph for certifications",id:"dependency-graph-for-certifications",level:3},{value:"Tooling",id:"tooling",level:2},{value:"Open Questions",id:"open-questions",level:2},{value:"Acknowledgements",id:"acknowledgements",level:2}];function l(e){const i={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsxs)(i.p,{children:["The ",(0,t.jsx)(i.a,{href:"https://scs.community",children:"Sovereign Cloud Stack (SCS)"})," provides standards for a range of cloud infrastructure types.\nIt strives for interoperable and sovereign cloud offerings which can be deployed and used by a wide range of organizations and individuals."]}),"\n",(0,t.jsx)(i.p,{children:"SCS plans to offer six kinds of certificates with varying scope. These scopes can be sorted into two dimensions:"}),"\n",(0,t.jsxs)(i.ol,{children:["\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.em,{children:"certification level"}),", of which there are three:","\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"SCS-compatible"}),"\n",(0,t.jsx)(i.li,{children:"SCS-open"}),"\n",(0,t.jsx)(i.li,{children:"SCS-sovereign"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.em,{children:"cloud layer"}),", of which there are two:","\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"infastructure as a service (IaaS)"}),"\n",(0,t.jsx)(i.li,{children:"Kubernetes as a service (KaaS)"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(i.p,{children:["So, for instance, a certificate can have the scope ",(0,t.jsx)(i.em,{children:"SCS-compatible IaaS"})," or ",(0,t.jsx)(i.em,{children:"SCS-sovereign KaaS"}),".\nNote that we don't currently have separate certification layers for Operations and IAM.\nWe expect that tests for these aspects will exist, but be incorporated into the IaaS\nand KaaS layers."]}),"\n",(0,t.jsxs)(i.p,{children:['Each certificate scope amounts to a set of standards that have to be fulfilled by the cloud service in question in order for a certificate to be issued.\nIn addition, a certificate with a certain scope may only be issued if some other certificate is already held.\nCase in point: the certification levels are meant to be seen as a progression, where the upper levels build on the lower ones, and\nthe certificate for "SCS-open IaaS" will only be issued if a certificate for "SCS-compatible IaaS" is already held.\nWe say that the latter certificate is a ',(0,t.jsx)(i.em,{children:"prerequisite"})," of the former."]}),"\n",(0,t.jsx)(i.p,{children:"Naturally, as the state of the art progresses, so do our certificates. We keep track of the changes by means of versioning.\nThat is to say that each certificate scope can come in several versions, each one of them having its distinct timespan when it is in effect.\nFor instance, we might have"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"SCS-compatible IaaS v1, effective 2021-01-01 through 2023-10-31"}),"\n",(0,t.jsx)(i.li,{children:"SCS-compatible IaaS v2, effective 2023-03-23 through 2023-11-30"}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"and so on (but usually, we aim to keep at most two versions in effect, with an overlap of 4 to 6 weeks)."}),"\n",(0,t.jsx)(i.p,{children:"This decision record describes two main points:"}),"\n",(0,t.jsxs)(i.ol,{children:["\n",(0,t.jsx)(i.li,{children:"How we denote our certificate scopes by means of a YAML file."}),"\n",(0,t.jsx)(i.li,{children:"Our process for constructing and progressing the certificate scopes."}),"\n"]}),"\n",(0,t.jsx)(i.h2,{id:"motivation",children:"Motivation"}),"\n",(0,t.jsx)(i.p,{children:"This decision record establishes a mechanism (by means of the YAML file) with the following three main objectives:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"to provide an overview of the mandatory standards for the different SCS certificate scopes"}),"\n",(0,t.jsx)(i.li,{children:"to make the lifecycle of certificate scopes traceable"}),"\n",(0,t.jsx)(i.li,{children:"to provide a machine-readable document for further processing (e.g. for a compliance tool suite or continuous integration)."}),"\n"]}),"\n",(0,t.jsx)(i.h3,{id:"overview-of-mandatory-scs-standards",children:"Overview of mandatory SCS standards"}),"\n",(0,t.jsx)(i.p,{children:"Digging through a repository of draft, stable, replaced and rejected standards becomes increasingly challenging with a growing number\ndocuments and decision records. A central document that lists all mandatory standards to acquire a certificate with a certain scope can\nresolve this issue. It provides clarity for providers as well as users and helps to understand the value\nproposition of SCS."}),"\n",(0,t.jsx)(i.h3,{id:"lifecycle-of-certificate-scopes",children:"Lifecycle of certificate scopes"}),"\n",(0,t.jsx)(i.p,{children:"Standards and therefore certifications will evolve over time. To provide transparency and traceability for the lifecycle of SCS certificate\nscopes, the whole history of our certifications should be recorded. Pre-notification of changes to our certificate scopes allows\nusers to adapt their environments or deployment automation to the new standards in advance."}),"\n",(0,t.jsx)(i.h3,{id:"machine-readability-for-further-processing",children:"Machine-readability for further processing"}),"\n",(0,t.jsx)(i.p,{children:"By providing a machine-readable document, we can generate web-friendly overviews of our certificate scopes as well as create a tool suite\nthat checks environments against all described standards."}),"\n",(0,t.jsx)(i.h2,{id:"scs-certification-yaml",children:"SCS Certification YAML"}),"\n",(0,t.jsxs)(i.p,{children:["Each certificate scope is recorded in a dedicated YAML file, e.g. ",(0,t.jsx)(i.code,{children:"scs-open-kaas.yaml"}),"."]}),"\n",(0,t.jsxs)(i.p,{children:["The certification YAML ",(0,t.jsx)(i.em,{children:"MUST"})," contain the following keys:"]}),"\n",(0,t.jsxs)(i.table,{children:[(0,t.jsx)(i.thead,{children:(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.th,{children:"Key"}),(0,t.jsx)(i.th,{children:"Type"}),(0,t.jsx)(i.th,{children:"Description"}),(0,t.jsx)(i.th,{children:"Example"})]})}),(0,t.jsxs)(i.tbody,{children:[(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"name"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsx)(i.td,{children:"Full name of this certificate scope"}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:"SCS Open KaaS"})})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"url"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsx)(i.td,{children:"Valid URL to the latest raw version of this document"}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/scs-open-kaas.yaml"})})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"versions"})}),(0,t.jsx)(i.td,{children:"Array of maps"}),(0,t.jsx)(i.td,{children:"List of version descriptors (described below)"}),(0,t.jsx)(i.td,{children:"(see below)"})]})]})]}),"\n",(0,t.jsxs)(i.p,{children:["The certification YAML ",(0,t.jsx)(i.em,{children:"MAY"})," contain the following keys:"]}),"\n",(0,t.jsxs)(i.table,{children:[(0,t.jsx)(i.thead,{children:(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.th,{children:"Key"}),(0,t.jsx)(i.th,{children:"Type"}),(0,t.jsx)(i.th,{children:"Description"})]})}),(0,t.jsxs)(i.tbody,{children:[(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"prerequisite"})}),(0,t.jsx)(i.td,{children:"Map"}),(0,t.jsx)(i.td,{children:"Descriptor for the prerequisite certificate scope (see below)"})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"variables"})}),(0,t.jsx)(i.td,{children:"Array of String"}),(0,t.jsx)(i.td,{children:"Lists variables that may occur in check tool descriptors"})]})]})]}),"\n",(0,t.jsx)(i.p,{children:"The main check tool will expect an assignment for these variables (which is specific to the subject under test), and every occurrence of the variable in the check tool descriptor will be substituted accordingly."}),"\n",(0,t.jsx)(i.h3,{id:"prerequisite-descriptor",children:"Prerequisite descriptor"}),"\n",(0,t.jsx)(i.p,{children:"A certificate within a certain level (above SCS-compatible) can only be granted if a valid corresponding certificate of the level below is presented,\nwhere corresponding means: of the same layer. The latter certificate is said to be a prerequisite for the former."}),"\n",(0,t.jsx)(i.p,{children:"We implement this logic by allowing for the designation of a certificate scope as a prerequisite;\nthen a certificate of that prerequisite scope has to be presented before the certificate of the scope in question can be granted."}),"\n",(0,t.jsxs)(i.table,{children:[(0,t.jsx)(i.thead,{children:(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.th,{children:"Key"}),(0,t.jsx)(i.th,{children:"Type"}),(0,t.jsx)(i.th,{children:"Description"}),(0,t.jsx)(i.th,{children:"Example"})]})}),(0,t.jsxs)(i.tbody,{children:[(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"name"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsx)(i.td,{children:"Full name of the certificate scope"}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:"SCS Compatible IaaS"})})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"url"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsx)(i.td,{children:"Valid URL to the latest raw version of the certificate scope"}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:(0,t.jsx)(i.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/scs-compatible-iaas.yaml",children:"scs-compatible-iaas.yaml"})})})]})]})]}),"\n",(0,t.jsx)(i.h3,{id:"version-descriptor",children:"Version descriptor"}),"\n",(0,t.jsxs)(i.table,{children:[(0,t.jsx)(i.thead,{children:(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.th,{children:"Key"}),(0,t.jsx)(i.th,{children:"Type"}),(0,t.jsx)(i.th,{children:"Description"}),(0,t.jsx)(i.th,{children:"Example"})]})}),(0,t.jsxs)(i.tbody,{children:[(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"version"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsx)(i.td,{children:"Mandatory: Version of the particular list of standards"}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:"v3"})})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"standards"})}),(0,t.jsx)(i.td,{children:"Array of maps"}),(0,t.jsx)(i.td,{children:"Mandatory: List of standard descriptors for this particular layer"}),(0,t.jsx)(i.td,{})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"stabilized_at"})}),(0,t.jsx)(i.td,{children:"Date"}),(0,t.jsx)(i.td,{children:"ISO formatted date indicating the date after this version is considered stable."}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:"2022-11-09"})})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"deprecated_at"})}),(0,t.jsx)(i.td,{children:"Date"}),(0,t.jsx)(i.td,{children:"ISO formatted date indicating the date on which this version is expired."}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:"2023-04-09"})})]})]})]}),"\n",(0,t.jsxs)(i.p,{children:["Once a version has a ",(0,t.jsx)(i.code,{children:"stabilized_at"})," field, this field may not be changed. The same holds true for the ",(0,t.jsx)(i.code,{children:"deprecated_at"})," field."]}),"\n",(0,t.jsxs)(i.p,{children:["Note that at any point in time, all versions that are older (",(0,t.jsx)(i.code,{children:"stabilized_at"})," is at or before this point)\ncan be certified against, unless the version is already deprecated (the point is after ",(0,t.jsx)(i.code,{children:"deprecated_at"}),").\nThis means that more than one version may be allowable at a certain point in time. Tooling should default\nto use the newest allowable version (the one with the most recent ",(0,t.jsx)(i.code,{children:"stabilized_at"})," date) then."]}),"\n",(0,t.jsx)(i.p,{children:"Note: We intend to keep only one version in effect, except for a grace period of 4 to 6 weeks, when two versions\nare effective at the same time."}),"\n",(0,t.jsx)(i.h3,{id:"standard-descriptor",children:"Standard descriptor"}),"\n",(0,t.jsx)(i.p,{children:"Every list of standards consists of several standards that \u2013 altogether \u2013 define the particular layer standard in the given version."}),"\n",(0,t.jsxs)(i.table,{children:[(0,t.jsx)(i.thead,{children:(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.th,{children:"Key"}),(0,t.jsx)(i.th,{children:"Type"}),(0,t.jsx)(i.th,{children:"Description"}),(0,t.jsx)(i.th,{children:"Example"})]})}),(0,t.jsxs)(i.tbody,{children:[(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"name"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsx)(i.td,{children:"Full name of the particular standard"}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:"Flavor naming"})})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"url"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsx)(i.td,{children:"Valid URL to the latest raw version of the particular standard"}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:(0,t.jsx)(i.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Standards/scs-0100-v2-flavor-naming.md",children:"Flavor naming"})})})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"condition"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsxs)(i.td,{children:["State of the particular standard, currently either ",(0,t.jsx)(i.code,{children:"mandatory"})," or ",(0,t.jsx)(i.code,{children:"optional"}),", default is ",(0,t.jsx)(i.code,{children:"mandatory"})]}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:"mandatory"})})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"checks"})}),(0,t.jsx)(i.td,{children:"Array"}),(0,t.jsx)(i.td,{children:"List of all checks that must pass; each entry being a check descriptor"}),(0,t.jsx)(i.td,{})]})]})]}),"\n",(0,t.jsx)(i.h3,{id:"check-descriptor",children:"Check descriptor"}),"\n",(0,t.jsx)(i.p,{children:"The following fields are valid for every check descriptor:"}),"\n",(0,t.jsxs)(i.table,{children:[(0,t.jsx)(i.thead,{children:(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.th,{children:"Key"}),(0,t.jsx)(i.th,{children:"Type"}),(0,t.jsx)(i.th,{children:"Description"}),(0,t.jsx)(i.th,{children:"Example"})]})}),(0,t.jsxs)(i.tbody,{children:[(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"id"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsx)(i.td,{children:"Identifier for this check (immutable and unique within this version of the certificate scope)"}),(0,t.jsx)(i.td,{children:"image-md-check"})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"condition"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsxs)(i.td,{children:[(0,t.jsx)(i.em,{children:"Optionally"})," overrides the per-standard condition (",(0,t.jsx)(i.code,{children:"mandatory"})," or ",(0,t.jsx)(i.code,{children:"optional"}),")"]}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:"optional"})})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"lifetime"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsxs)(i.td,{children:["One of: ",(0,t.jsx)(i.code,{children:"day"})," (",(0,t.jsx)(i.em,{children:"default"}),"), ",(0,t.jsx)(i.code,{children:"week"}),", ",(0,t.jsx)(i.code,{children:"month"}),", ",(0,t.jsx)(i.code,{children:"quarter"}),"; the test result is valid until the end of the next period"]}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:"week"})})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"section"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsxs)(i.td,{children:[(0,t.jsx)(i.em,{children:"Optional"})," what section to associate this check with (sections can be checked in isolation); default: equal to lifetime"]}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:"flavor-name syntax"})})]})]})]}),"\n",(0,t.jsx)(i.p,{children:"Additional fields are valid depending on whether the check is automated or manual."}),"\n",(0,t.jsx)(i.h4,{id:"automated-check",children:"Automated check"}),"\n",(0,t.jsxs)(i.table,{children:[(0,t.jsx)(i.thead,{children:(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.th,{children:"Key"}),(0,t.jsx)(i.th,{children:"Type"}),(0,t.jsx)(i.th,{children:"Description"}),(0,t.jsx)(i.th,{children:"Example"})]})}),(0,t.jsxs)(i.tbody,{children:[(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"executable"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsx)(i.td,{children:"Valid local filename (relative to the path of scs-compliance-check.py) of a script that verifies compliance with the particular standard"}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.em,{children:"image-md-check.py"})})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"env"})}),(0,t.jsx)(i.td,{children:"Map"}),(0,t.jsxs)(i.td,{children:[(0,t.jsx)(i.em,{children:"Optional"})," key-value map of environment variables (values may use variables)"]}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"OS_CLOUD: {os_cloud}"})})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"args"})}),(0,t.jsx)(i.td,{children:"String"}),(0,t.jsxs)(i.td,{children:[(0,t.jsx)(i.em,{children:"Optional"})," command-line arguments to be passed to the ",(0,t.jsx)(i.code,{children:"check_tool"})," (may use variables)"]}),(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"-v -k {kubeconfig}"})})]})]})]}),"\n",(0,t.jsxs)(i.p,{children:["As mentioned, variables may be used within ",(0,t.jsx)(i.code,{children:"env"})," and ",(0,t.jsx)(i.code,{children:"args"}),"; they are enclosed in single braces, like so: ",(0,t.jsx)(i.code,{children:"{var}"}),".\nIf a brace is desired, it needs to be doubled: ",(0,t.jsx)(i.code,{children:"{{"})," will be turned into ",(0,t.jsx)(i.code,{children:"{"}),". When the main check tool is run,\neach occurrence of a variable will be substituted for according to the variable assignment for the subject under test."]}),"\n",(0,t.jsxs)(i.p,{children:[(0,t.jsx)(i.em,{children:"Note"}),": the ",(0,t.jsx)(i.code,{children:"executable"})," could in principle also be given via a URL; however, this is not yet supported due to security considerations."]}),"\n",(0,t.jsx)(i.h4,{id:"manual-check",children:"Manual check"}),"\n",(0,t.jsx)(i.p,{children:"TBD"}),"\n",(0,t.jsx)(i.h3,{id:"basic-example",children:"Basic Example"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{className:"language-yaml",children:'name: SCS Open IaaS\nurl: https://raw.githubusercontent.com/SovereignCloudStack/Docs/main/Certification/scs-open-iaas.yaml\nprerequisite:\n name: SCS Compatible IaaS\n url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/scs-compatible-iaas.yaml\nvariables:\n - os_cloud\nversions:\n - version: v5 # This version is in a draft state and work in progress\n # No stabilized_at: date set yet\n standards:\n - name: Flavor naming\n url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Standards/scs-0100-v2-flavor-naming.md\n condition: mandatory # is default and can be left out\n checks:\n - executable: flavor-name-check.py\n env:\n OS_CLOUD: "{os_cloud}"\n id: flavor-name-check\n lifetime: day\n - name: Image metadata\n url: https://raw.githubusercontent.com/SovereignCloudStack/Docs/main/Standards/SCS-0004-v1-image-metadata.md\n condition: mandatory\n checks:\n - executable: image-md-check.py\n args: -c {os_cloud} -v\n id: image-md-check\n lifetime: day\n - executable: image-md-check2.py\n condition: optional\n id: image-md-check-2\n lifetime: day\n - version: v4 # This is the upcoming version with a given target date. No further changes should be done to this set of standards\n stabilized_at: 2022-04-01\n standards:\n - name: ....\n\n - version: v3 # This is the stable set of standards that is currently active\n stabilized_at: 2021-10-01\n deprecated_at: 2022-11-08\n standards:\n - name: ....\n\n - version: v2 # This set of standards is obsolete and has been replaced by v3\n stabilized_at: 2021-07-01\n deprecated_at: 2021-11-01\n standards:\n - name: ....\n'})}),"\n",(0,t.jsx)(i.h2,{id:"process",children:"Process"}),"\n",(0,t.jsx)(i.p,{children:"The lifecycle any version of any certificate scope goes through the following phases:\nDraft, Stable, and Deprecated."}),"\n",(0,t.jsx)(i.mermaid,{value:"graph TD\n B[Draft] --\x3e|Pull Request| D[Stable]\n D --\x3e|Pull Request| F[Deprecated]"}),"\n",(0,t.jsx)(i.p,{children:"Note that one pull request can affect multiple versions, but each pull request has to affect\nat most one layer."}),"\n",(0,t.jsx)(i.p,{children:"Each pull request is to be voted upon in the corresponding team meeting. The vote has to be\non the pull request only, i.e., it may not affect any other pull request or issue, and it\nmust be announced 14 days in advance via the corresponding mailing list."}),"\n",(0,t.jsx)(i.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,t.jsx)(i.h3,{id:"file-format",children:"File format"}),"\n",(0,t.jsx)(i.p,{children:"In order to have a document that can be processed by a wide range of tools, we need to opt for a simple but yet well supported format.\nYAML offers readability for humans as well as good support by many frameworks. Since YAML is heavily used in the cloud and container\ndomain, the choice is obvious."}),"\n",(0,t.jsx)(i.h3,{id:"dependency-graph-for-certifications",children:"Dependency graph for certifications"}),"\n",(0,t.jsx)(i.p,{children:"This standard only allows exactly one depending certification, otherwise we would need to use a list of mappings. Since this is\nin accordance to the current plan of the SIG Standardization & Certification, we can safely ignore multiple dependency of\ncertification for now."}),"\n",(0,t.jsx)(i.h2,{id:"tooling",children:"Tooling"}),"\n",(0,t.jsxs)(i.p,{children:["The SCS repository Docs has a tool ",(0,t.jsx)(i.code,{children:"scs-compliance-check.py"})," in the ",(0,t.jsx)(i.code,{children:"Tests"})," directory\nwhich parses the SCS Certification YAML and then runs the tests referenced there, returning the results\nof the tests."]}),"\n",(0,t.jsx)(i.h2,{id:"open-questions",children:"Open Questions"}),"\n",(0,t.jsx)(i.h2,{id:"acknowledgements",children:"Acknowledgements"}),"\n",(0,t.jsxs)(i.p,{children:["This document is heavily inspired by the ",(0,t.jsx)(i.a,{href:"https://yml.publiccode.tools/",children:"publiccode.yml standard"}),", as published by the ",(0,t.jsx)(i.a,{href:"https://publiccode.net/",children:"Foundation for Public Code"}),"."]})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>a,x:()=>d});var t=n(96540);const s={},r=t.createContext(s);function a(e){const i=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function d(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/327.4e111aeb.js b/assets/js/327.4e111aeb.js new file mode 100644 index 0000000000..c9bf17d59c --- /dev/null +++ b/assets/js/327.4e111aeb.js @@ -0,0 +1,1323 @@ +"use strict"; +exports.id = 327; +exports.ids = [327]; +exports.modules = { + +/***/ 30708: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(58886); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99418); + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [6, 8, 10, 11, 12, 14, 16, 17, 18], $V1 = [1, 9], $V2 = [1, 10], $V3 = [1, 11], $V4 = [1, 12], $V5 = [1, 13], $V6 = [1, 14]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "journey": 4, "document": 5, "EOF": 6, "line": 7, "SPACE": 8, "statement": 9, "NEWLINE": 10, "title": 11, "acc_title": 12, "acc_title_value": 13, "acc_descr": 14, "acc_descr_value": 15, "acc_descr_multiline_value": 16, "section": 17, "taskName": 18, "taskData": 19, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "journey", 6: "EOF", 8: "SPACE", 10: "NEWLINE", 11: "title", 12: "acc_title", 13: "acc_title_value", 14: "acc_descr", 15: "acc_descr_value", 16: "acc_descr_multiline_value", 17: "section", 18: "taskName", 19: "taskData" }, + productions_: [0, [3, 3], [5, 0], [5, 2], [7, 2], [7, 1], [7, 1], [7, 1], [9, 1], [9, 2], [9, 2], [9, 1], [9, 1], [9, 2]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 1: + return $$[$0 - 1]; + case 2: + this.$ = []; + break; + case 3: + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + break; + case 4: + case 5: + this.$ = $$[$0]; + break; + case 6: + case 7: + this.$ = []; + break; + case 8: + yy.setDiagramTitle($$[$0].substr(6)); + this.$ = $$[$0].substr(6); + break; + case 9: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 10: + case 11: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 12: + yy.addSection($$[$0].substr(8)); + this.$ = $$[$0].substr(8); + break; + case 13: + yy.addTask($$[$0 - 1], $$[$0]); + this.$ = "task"; + break; + } + }, + table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: [1, 6], 9: 7, 10: [1, 8], 11: $V1, 12: $V2, 14: $V3, 16: $V4, 17: $V5, 18: $V6 }, o($V0, [2, 7], { 1: [2, 1] }), o($V0, [2, 3]), { 9: 15, 11: $V1, 12: $V2, 14: $V3, 16: $V4, 17: $V5, 18: $V6 }, o($V0, [2, 5]), o($V0, [2, 6]), o($V0, [2, 8]), { 13: [1, 16] }, { 15: [1, 17] }, o($V0, [2, 11]), o($V0, [2, 12]), { 19: [1, 18] }, o($V0, [2, 4]), o($V0, [2, 9]), o($V0, [2, 10]), o($V0, [2, 13])], + defaultActions: {}, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + break; + case 1: + break; + case 2: + return 10; + case 3: + break; + case 4: + break; + case 5: + return 4; + case 6: + return 11; + case 7: + this.begin("acc_title"); + return 12; + case 8: + this.popState(); + return "acc_title_value"; + case 9: + this.begin("acc_descr"); + return 14; + case 10: + this.popState(); + return "acc_descr_value"; + case 11: + this.begin("acc_descr_multiline"); + break; + case 12: + this.popState(); + break; + case 13: + return "acc_descr_multiline_value"; + case 14: + return 17; + case 15: + return 18; + case 16: + return 19; + case 17: + return ":"; + case 18: + return 6; + case 19: + return "INVALID"; + } + }, + rules: [/^(?:%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[\n]+)/i, /^(?:\s+)/i, /^(?:#[^\n]*)/i, /^(?:journey\b)/i, /^(?:title\s[^#\n;]+)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:section\s[^#:\n;]+)/i, /^(?:[^#:\n;]+)/i, /^(?::[^#\n;]+)/i, /^(?::)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "acc_descr_multiline": { "rules": [12, 13], "inclusive": false }, "acc_descr": { "rules": [10], "inclusive": false }, "acc_title": { "rules": [8], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 18, 19], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let currentSection = ""; +const sections = []; +const tasks = []; +const rawTasks = []; +const clear = function() { + sections.length = 0; + tasks.length = 0; + currentSection = ""; + rawTasks.length = 0; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.v)(); +}; +const addSection = function(txt) { + currentSection = txt; + sections.push(txt); +}; +const getSections = function() { + return sections; +}; +const getTasks = function() { + let allItemsProcessed = compileTasks(); + const maxDepth = 100; + let iterationCount = 0; + while (!allItemsProcessed && iterationCount < maxDepth) { + allItemsProcessed = compileTasks(); + iterationCount++; + } + tasks.push(...rawTasks); + return tasks; +}; +const updateActors = function() { + const tempActors = []; + tasks.forEach((task) => { + if (task.people) { + tempActors.push(...task.people); + } + }); + const unique = new Set(tempActors); + return [...unique].sort(); +}; +const addTask = function(descr, taskData) { + const pieces = taskData.substr(1).split(":"); + let score = 0; + let peeps = []; + if (pieces.length === 1) { + score = Number(pieces[0]); + peeps = []; + } else { + score = Number(pieces[0]); + peeps = pieces[1].split(","); + } + const peopleList = peeps.map((s) => s.trim()); + const rawTask = { + section: currentSection, + type: currentSection, + people: peopleList, + task: descr, + score + }; + rawTasks.push(rawTask); +}; +const addTaskOrg = function(descr) { + const newTask = { + section: currentSection, + type: currentSection, + description: descr, + task: descr, + classes: [] + }; + tasks.push(newTask); +}; +const compileTasks = function() { + const compileTask = function(pos) { + return rawTasks[pos].processed; + }; + let allProcessed = true; + for (const [i, rawTask] of rawTasks.entries()) { + compileTask(i); + allProcessed = allProcessed && rawTask.processed; + } + return allProcessed; +}; +const getActors = function() { + return updateActors(); +}; +const db = { + getConfig: () => (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().journey, + clear, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.t, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.g, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.b, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.a, + addSection, + getSections, + getTasks, + addTask, + addTaskOrg, + getActors +}; +const getStyles = (options) => `.label { + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + color: ${options.textColor}; + } + .mouth { + stroke: #666; + } + + line { + stroke: ${options.textColor} + } + + .legend { + fill: ${options.textColor}; + } + + .label text { + fill: #333; + } + .label { + color: ${options.textColor} + } + + .face { + ${options.faceColor ? `fill: ${options.faceColor}` : "fill: #FFF8DC"}; + stroke: #999; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${options.arrowheadColor}; + } + + .edgePath .path { + stroke: ${options.lineColor}; + stroke-width: 1.5px; + } + + .flowchart-link { + stroke: ${options.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${options.edgeLabelBackground}; + rect { + opacity: 0.5; + } + text-align: center; + } + + .cluster rect { + } + + .cluster text { + fill: ${options.titleColor}; + } + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + font-size: 12px; + background: ${options.tertiaryColor}; + border: 1px solid ${options.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .task-type-0, .section-type-0 { + ${options.fillType0 ? `fill: ${options.fillType0}` : ""}; + } + .task-type-1, .section-type-1 { + ${options.fillType0 ? `fill: ${options.fillType1}` : ""}; + } + .task-type-2, .section-type-2 { + ${options.fillType0 ? `fill: ${options.fillType2}` : ""}; + } + .task-type-3, .section-type-3 { + ${options.fillType0 ? `fill: ${options.fillType3}` : ""}; + } + .task-type-4, .section-type-4 { + ${options.fillType0 ? `fill: ${options.fillType4}` : ""}; + } + .task-type-5, .section-type-5 { + ${options.fillType0 ? `fill: ${options.fillType5}` : ""}; + } + .task-type-6, .section-type-6 { + ${options.fillType0 ? `fill: ${options.fillType6}` : ""}; + } + .task-type-7, .section-type-7 { + ${options.fillType0 ? `fill: ${options.fillType7}` : ""}; + } + + .actor-0 { + ${options.actor0 ? `fill: ${options.actor0}` : ""}; + } + .actor-1 { + ${options.actor1 ? `fill: ${options.actor1}` : ""}; + } + .actor-2 { + ${options.actor2 ? `fill: ${options.actor2}` : ""}; + } + .actor-3 { + ${options.actor3 ? `fill: ${options.actor3}` : ""}; + } + .actor-4 { + ${options.actor4 ? `fill: ${options.actor4}` : ""}; + } + .actor-5 { + ${options.actor5 ? `fill: ${options.actor5}` : ""}; + } +`; +const styles = getStyles; +const drawRect = function(elem, rectData) { + return (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.d)(elem, rectData); +}; +const drawFace = function(element, faceData) { + const radius = 15; + const circleElement = element.append("circle").attr("cx", faceData.cx).attr("cy", faceData.cy).attr("class", "face").attr("r", radius).attr("stroke-width", 2).attr("overflow", "visible"); + const face = element.append("g"); + face.append("circle").attr("cx", faceData.cx - radius / 3).attr("cy", faceData.cy - radius / 3).attr("r", 1.5).attr("stroke-width", 2).attr("fill", "#666").attr("stroke", "#666"); + face.append("circle").attr("cx", faceData.cx + radius / 3).attr("cy", faceData.cy - radius / 3).attr("r", 1.5).attr("stroke-width", 2).attr("fill", "#666").attr("stroke", "#666"); + function smile(face2) { + const arc$1 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .arc */ .JLW)().startAngle(Math.PI / 2).endAngle(3 * (Math.PI / 2)).innerRadius(radius / 2).outerRadius(radius / 2.2); + face2.append("path").attr("class", "mouth").attr("d", arc$1).attr("transform", "translate(" + faceData.cx + "," + (faceData.cy + 2) + ")"); + } + function sad(face2) { + const arc$1 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .arc */ .JLW)().startAngle(3 * Math.PI / 2).endAngle(5 * (Math.PI / 2)).innerRadius(radius / 2).outerRadius(radius / 2.2); + face2.append("path").attr("class", "mouth").attr("d", arc$1).attr("transform", "translate(" + faceData.cx + "," + (faceData.cy + 7) + ")"); + } + function ambivalent(face2) { + face2.append("line").attr("class", "mouth").attr("stroke", 2).attr("x1", faceData.cx - 5).attr("y1", faceData.cy + 7).attr("x2", faceData.cx + 5).attr("y2", faceData.cy + 7).attr("class", "mouth").attr("stroke-width", "1px").attr("stroke", "#666"); + } + if (faceData.score > 3) { + smile(face); + } else if (faceData.score < 3) { + sad(face); + } else { + ambivalent(face); + } + return circleElement; +}; +const drawCircle = function(element, circleData) { + const circleElement = element.append("circle"); + circleElement.attr("cx", circleData.cx); + circleElement.attr("cy", circleData.cy); + circleElement.attr("class", "actor-" + circleData.pos); + circleElement.attr("fill", circleData.fill); + circleElement.attr("stroke", circleData.stroke); + circleElement.attr("r", circleData.r); + if (circleElement.class !== void 0) { + circleElement.attr("class", circleElement.class); + } + if (circleData.title !== void 0) { + circleElement.append("title").text(circleData.title); + } + return circleElement; +}; +const drawText = function(elem, textData) { + return (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.f)(elem, textData); +}; +const drawLabel = function(elem, txtObject) { + function genPoints(x, y, width, height, cut) { + return x + "," + y + " " + (x + width) + "," + y + " " + (x + width) + "," + (y + height - cut) + " " + (x + width - cut * 1.2) + "," + (y + height) + " " + x + "," + (y + height); + } + const polygon = elem.append("polygon"); + polygon.attr("points", genPoints(txtObject.x, txtObject.y, 50, 20, 7)); + polygon.attr("class", "labelBox"); + txtObject.y = txtObject.y + txtObject.labelMargin; + txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin; + drawText(elem, txtObject); +}; +const drawSection = function(elem, section, conf2) { + const g = elem.append("g"); + const rect = (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + rect.x = section.x; + rect.y = section.y; + rect.fill = section.fill; + rect.width = conf2.width * section.taskCount + // width of the tasks + conf2.diagramMarginX * (section.taskCount - 1); + rect.height = conf2.height; + rect.class = "journey-section section-type-" + section.num; + rect.rx = 3; + rect.ry = 3; + drawRect(g, rect); + _drawTextCandidateFunc(conf2)( + section.text, + g, + rect.x, + rect.y, + rect.width, + rect.height, + { class: "journey-section section-type-" + section.num }, + conf2, + section.colour + ); +}; +let taskCount = -1; +const drawTask = function(elem, task, conf2) { + const center = task.x + conf2.width / 2; + const g = elem.append("g"); + taskCount++; + const maxHeight = 300 + 5 * 30; + g.append("line").attr("id", "task" + taskCount).attr("x1", center).attr("y1", task.y).attr("x2", center).attr("y2", maxHeight).attr("class", "task-line").attr("stroke-width", "1px").attr("stroke-dasharray", "4 2").attr("stroke", "#666"); + drawFace(g, { + cx: center, + cy: 300 + (5 - task.score) * 30, + score: task.score + }); + const rect = (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + rect.x = task.x; + rect.y = task.y; + rect.fill = task.fill; + rect.width = conf2.width; + rect.height = conf2.height; + rect.class = "task task-type-" + task.num; + rect.rx = 3; + rect.ry = 3; + drawRect(g, rect); + let xPos = task.x + 14; + task.people.forEach((person) => { + const colour = task.actors[person].color; + const circle = { + cx: xPos, + cy: task.y, + r: 7, + fill: colour, + stroke: "#000", + title: person, + pos: task.actors[person].position + }; + drawCircle(g, circle); + xPos += 10; + }); + _drawTextCandidateFunc(conf2)( + task.task, + g, + rect.x, + rect.y, + rect.width, + rect.height, + { class: "task" }, + conf2, + task.colour + ); +}; +const drawBackgroundRect = function(elem, bounds2) { + (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.a)(elem, bounds2); +}; +const _drawTextCandidateFunc = function() { + function byText(content, g, x, y, width, height, textAttrs, colour) { + const text = g.append("text").attr("x", x + width / 2).attr("y", y + height / 2 + 5).style("font-color", colour).style("text-anchor", "middle").text(content); + _setTextAttrs(text, textAttrs); + } + function byTspan(content, g, x, y, width, height, textAttrs, conf2, colour) { + const { taskFontSize, taskFontFamily } = conf2; + const lines = content.split(//gi); + for (let i = 0; i < lines.length; i++) { + const dy = i * taskFontSize - taskFontSize * (lines.length - 1) / 2; + const text = g.append("text").attr("x", x + width / 2).attr("y", y).attr("fill", colour).style("text-anchor", "middle").style("font-size", taskFontSize).style("font-family", taskFontFamily); + text.append("tspan").attr("x", x + width / 2).attr("dy", dy).text(lines[i]); + text.attr("y", y + height / 2).attr("dominant-baseline", "central").attr("alignment-baseline", "central"); + _setTextAttrs(text, textAttrs); + } + } + function byFo(content, g, x, y, width, height, textAttrs, conf2) { + const body = g.append("switch"); + const f = body.append("foreignObject").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("position", "fixed"); + const text = f.append("xhtml:div").style("display", "table").style("height", "100%").style("width", "100%"); + text.append("div").attr("class", "label").style("display", "table-cell").style("text-align", "center").style("vertical-align", "middle").text(content); + byTspan(content, body, x, y, width, height, textAttrs, conf2); + _setTextAttrs(text, textAttrs); + } + function _setTextAttrs(toText, fromTextAttrsDict) { + for (const key in fromTextAttrsDict) { + if (key in fromTextAttrsDict) { + toText.attr(key, fromTextAttrsDict[key]); + } + } + } + return function(conf2) { + return conf2.textPlacement === "fo" ? byFo : conf2.textPlacement === "old" ? byText : byTspan; + }; +}(); +const initGraphics = function(graphics) { + graphics.append("defs").append("marker").attr("id", "arrowhead").attr("refX", 5).attr("refY", 2).attr("markerWidth", 6).attr("markerHeight", 4).attr("orient", "auto").append("path").attr("d", "M 0,0 V 4 L6,2 Z"); +}; +const svgDraw = { + drawRect, + drawCircle, + drawSection, + drawText, + drawLabel, + drawTask, + drawBackgroundRect, + initGraphics +}; +const setConf = function(cnf) { + const keys = Object.keys(cnf); + keys.forEach(function(key) { + conf[key] = cnf[key]; + }); +}; +const actors = {}; +function drawActorLegend(diagram2) { + const conf2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().journey; + let yPos = 60; + Object.keys(actors).forEach((person) => { + const colour = actors[person].color; + const circleData = { + cx: 20, + cy: yPos, + r: 7, + fill: colour, + stroke: "#000", + pos: actors[person].position + }; + svgDraw.drawCircle(diagram2, circleData); + const labelData = { + x: 40, + y: yPos + 7, + fill: "#666", + text: person, + textMargin: conf2.boxTextMargin | 5 + }; + svgDraw.drawText(diagram2, labelData); + yPos += 20; + }); +} +const conf = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().journey; +const LEFT_MARGIN = conf.leftMargin; +const draw = function(text, id, version, diagObj) { + const conf2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().journey; + const securityLevel = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body"); + bounds.init(); + const diagram2 = root.select("#" + id); + svgDraw.initGraphics(diagram2); + const tasks2 = diagObj.db.getTasks(); + const title = diagObj.db.getDiagramTitle(); + const actorNames = diagObj.db.getActors(); + for (const member in actors) { + delete actors[member]; + } + let actorPos = 0; + actorNames.forEach((actorName) => { + actors[actorName] = { + color: conf2.actorColours[actorPos % conf2.actorColours.length], + position: actorPos + }; + actorPos++; + }); + drawActorLegend(diagram2); + bounds.insert(0, 0, LEFT_MARGIN, Object.keys(actors).length * 50); + drawTasks(diagram2, tasks2, 0); + const box = bounds.getBounds(); + if (title) { + diagram2.append("text").text(title).attr("x", LEFT_MARGIN).attr("font-size", "4ex").attr("font-weight", "bold").attr("y", 25); + } + const height = box.stopy - box.starty + 2 * conf2.diagramMarginY; + const width = LEFT_MARGIN + box.stopx + 2 * conf2.diagramMarginX; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.i)(diagram2, height, width, conf2.useMaxWidth); + diagram2.append("line").attr("x1", LEFT_MARGIN).attr("y1", conf2.height * 4).attr("x2", width - LEFT_MARGIN - 4).attr("y2", conf2.height * 4).attr("stroke-width", 4).attr("stroke", "black").attr("marker-end", "url(#arrowhead)"); + const extraVertForTitle = title ? 70 : 0; + diagram2.attr("viewBox", `${box.startx} -25 ${width} ${height + extraVertForTitle}`); + diagram2.attr("preserveAspectRatio", "xMinYMin meet"); + diagram2.attr("height", height + extraVertForTitle + 25); +}; +const bounds = { + data: { + startx: void 0, + stopx: void 0, + starty: void 0, + stopy: void 0 + }, + verticalPos: 0, + sequenceItems: [], + init: function() { + this.sequenceItems = []; + this.data = { + startx: void 0, + stopx: void 0, + starty: void 0, + stopy: void 0 + }; + this.verticalPos = 0; + }, + updateVal: function(obj, key, val, fun) { + if (obj[key] === void 0) { + obj[key] = val; + } else { + obj[key] = fun(val, obj[key]); + } + }, + updateBounds: function(startx, starty, stopx, stopy) { + const conf2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().journey; + const _self = this; + let cnt = 0; + function updateFn(type) { + return function updateItemBounds(item) { + cnt++; + const n = _self.sequenceItems.length - cnt + 1; + _self.updateVal(item, "starty", starty - n * conf2.boxMargin, Math.min); + _self.updateVal(item, "stopy", stopy + n * conf2.boxMargin, Math.max); + _self.updateVal(bounds.data, "startx", startx - n * conf2.boxMargin, Math.min); + _self.updateVal(bounds.data, "stopx", stopx + n * conf2.boxMargin, Math.max); + if (!(type === "activation")) { + _self.updateVal(item, "startx", startx - n * conf2.boxMargin, Math.min); + _self.updateVal(item, "stopx", stopx + n * conf2.boxMargin, Math.max); + _self.updateVal(bounds.data, "starty", starty - n * conf2.boxMargin, Math.min); + _self.updateVal(bounds.data, "stopy", stopy + n * conf2.boxMargin, Math.max); + } + }; + } + this.sequenceItems.forEach(updateFn()); + }, + insert: function(startx, starty, stopx, stopy) { + const _startx = Math.min(startx, stopx); + const _stopx = Math.max(startx, stopx); + const _starty = Math.min(starty, stopy); + const _stopy = Math.max(starty, stopy); + this.updateVal(bounds.data, "startx", _startx, Math.min); + this.updateVal(bounds.data, "starty", _starty, Math.min); + this.updateVal(bounds.data, "stopx", _stopx, Math.max); + this.updateVal(bounds.data, "stopy", _stopy, Math.max); + this.updateBounds(_startx, _starty, _stopx, _stopy); + }, + bumpVerticalPos: function(bump) { + this.verticalPos = this.verticalPos + bump; + this.data.stopy = this.verticalPos; + }, + getVerticalPos: function() { + return this.verticalPos; + }, + getBounds: function() { + return this.data; + } +}; +const fills = conf.sectionFills; +const textColours = conf.sectionColours; +const drawTasks = function(diagram2, tasks2, verticalPos) { + const conf2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().journey; + let lastSection = ""; + const sectionVHeight = conf2.height * 2 + conf2.diagramMarginY; + const taskPos = verticalPos + sectionVHeight; + let sectionNumber = 0; + let fill = "#CCC"; + let colour = "black"; + let num = 0; + for (const [i, task] of tasks2.entries()) { + if (lastSection !== task.section) { + fill = fills[sectionNumber % fills.length]; + num = sectionNumber % fills.length; + colour = textColours[sectionNumber % textColours.length]; + let taskInSectionCount = 0; + const currentSection2 = task.section; + for (let taskIndex = i; taskIndex < tasks2.length; taskIndex++) { + if (tasks2[taskIndex].section == currentSection2) { + taskInSectionCount = taskInSectionCount + 1; + } else { + break; + } + } + const section = { + x: i * conf2.taskMargin + i * conf2.width + LEFT_MARGIN, + y: 50, + text: task.section, + fill, + num, + colour, + taskCount: taskInSectionCount + }; + svgDraw.drawSection(diagram2, section, conf2); + lastSection = task.section; + sectionNumber++; + } + const taskActors = task.people.reduce((acc, actorName) => { + if (actors[actorName]) { + acc[actorName] = actors[actorName]; + } + return acc; + }, {}); + task.x = i * conf2.taskMargin + i * conf2.width + LEFT_MARGIN; + task.y = taskPos; + task.width = conf2.diagramMarginX; + task.height = conf2.diagramMarginY; + task.colour = colour; + task.fill = fill; + task.num = num; + task.actors = taskActors; + svgDraw.drawTask(diagram2, task, conf2); + bounds.insert(task.x, task.y, task.x + task.width + conf2.taskMargin, 300 + 5 * 30); + } +}; +const renderer = { + setConf, + draw +}; +const diagram = { + parser: parser$1, + db, + renderer, + styles, + init: (cnf) => { + renderer.setConf(cnf.journey); + db.clear(); + } +}; + + + +/***/ }), + +/***/ 58886: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ drawBackgroundRect), +/* harmony export */ b: () => (/* binding */ drawEmbeddedImage), +/* harmony export */ c: () => (/* binding */ drawImage), +/* harmony export */ d: () => (/* binding */ drawRect), +/* harmony export */ e: () => (/* binding */ getTextObj), +/* harmony export */ f: () => (/* binding */ drawText), +/* harmony export */ g: () => (/* binding */ getNoteRect) +/* harmony export */ }); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(16750); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); + + +const drawRect = (element, rectData) => { + const rectElement = element.append("rect"); + rectElement.attr("x", rectData.x); + rectElement.attr("y", rectData.y); + rectElement.attr("fill", rectData.fill); + rectElement.attr("stroke", rectData.stroke); + rectElement.attr("width", rectData.width); + rectElement.attr("height", rectData.height); + if (rectData.name) { + rectElement.attr("name", rectData.name); + } + rectData.rx !== void 0 && rectElement.attr("rx", rectData.rx); + rectData.ry !== void 0 && rectElement.attr("ry", rectData.ry); + if (rectData.attrs !== void 0) { + for (const attrKey in rectData.attrs) { + rectElement.attr(attrKey, rectData.attrs[attrKey]); + } + } + rectData.class !== void 0 && rectElement.attr("class", rectData.class); + return rectElement; +}; +const drawBackgroundRect = (element, bounds) => { + const rectData = { + x: bounds.startx, + y: bounds.starty, + width: bounds.stopx - bounds.startx, + height: bounds.stopy - bounds.starty, + fill: bounds.fill, + stroke: bounds.stroke, + class: "rect" + }; + const rectElement = drawRect(element, rectData); + rectElement.lower(); +}; +const drawText = (element, textData) => { + const nText = textData.text.replace(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.J, " "); + const textElem = element.append("text"); + textElem.attr("x", textData.x); + textElem.attr("y", textData.y); + textElem.attr("class", "legend"); + textElem.style("text-anchor", textData.anchor); + textData.class !== void 0 && textElem.attr("class", textData.class); + const tspan = textElem.append("tspan"); + tspan.attr("x", textData.x + textData.textMargin * 2); + tspan.text(nText); + return textElem; +}; +const drawImage = (elem, x, y, link) => { + const imageElement = elem.append("image"); + imageElement.attr("x", x); + imageElement.attr("y", y); + const sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Jf)(link); + imageElement.attr("xlink:href", sanitizedLink); +}; +const drawEmbeddedImage = (element, x, y, link) => { + const imageElement = element.append("use"); + imageElement.attr("x", x); + imageElement.attr("y", y); + const sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Jf)(link); + imageElement.attr("xlink:href", `#${sanitizedLink}`); +}; +const getNoteRect = () => { + const noteRectData = { + x: 0, + y: 0, + width: 100, + height: 100, + fill: "#EDF2AE", + stroke: "#666", + anchor: "start", + rx: 0, + ry: 0 + }; + return noteRectData; +}; +const getTextObj = () => { + const testObject = { + x: 0, + y: 0, + width: 100, + height: 100, + "text-anchor": "start", + style: "#666", + textMargin: 0, + rx: 0, + ry: 0, + tspan: true + }; + return testObject; +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/32dcd940.0e700c54.js b/assets/js/32dcd940.0e700c54.js new file mode 100644 index 0000000000..d19f46f6c9 --- /dev/null +++ b/assets/js/32dcd940.0e700c54.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[86],{57446:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>u,frontMatter:()=>c,metadata:()=>s,toc:()=>l});var i=t(74848),a=t(28453);const c={sidebar_label:"Placement"},o="Placement",s={id:"iaas/guides/configuration-guide/openstack/placement",title:"Placement",description:"* Placement admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/placement.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/placement",permalink:"/docs/iaas/guides/configuration-guide/openstack/placement",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/placement.md",tags:[],version:"current",frontMatter:{sidebar_label:"Placement"},sidebar:"docs",previous:{title:"Octavia",permalink:"/docs/iaas/guides/configuration-guide/openstack/octavia"},next:{title:"Skyline",permalink:"/docs/iaas/guides/configuration-guide/openstack/skyline"}},r={},l=[];function d(e){const n={a:"a",h1:"h1",li:"li",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"placement",children:"Placement"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/placement/latest/admin/index.html",children:"Placement admin guide"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/placement/latest/configuration/index.html",children:"Placement configuration guide"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/placement/latest/configuration/config.html",children:"Placement configuration reference"})}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>s});var i=t(96540);const a={},c=i.createContext(a);function o(e){const n=i.useContext(c);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),i.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/343a1afc.2754cdd5.js b/assets/js/343a1afc.2754cdd5.js new file mode 100644 index 0000000000..4ec06c70a5 --- /dev/null +++ b/assets/js/343a1afc.2754cdd5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8965],{46486:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var o=t(74848),s=t(28453);const r={},i="Overview",c={id:"operating-scs/logging/index",title:"Overview",description:"TODO",source:"@site/docs/04-operating-scs/06-logging/index.md",sourceDirName:"04-operating-scs/06-logging",slug:"/operating-scs/logging/",permalink:"/docs/operating-scs/logging/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/06-logging/index.md",tags:[],version:"current",frontMatter:{}},a={},d=[];function g(e){const n={h1:"h1",p:"p",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"overview",children:"Overview"}),"\n",(0,o.jsx)(n.p,{children:"TODO"})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(g,{...e})}):g(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>c});var o=t(96540);const s={},r=o.createContext(s);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3498.52731744.js b/assets/js/3498.52731744.js new file mode 100644 index 0000000000..4ecf781378 --- /dev/null +++ b/assets/js/3498.52731744.js @@ -0,0 +1,2 @@ +/*! For license information please see 3498.52731744.js.LICENSE.txt */ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3498],{16750:(t,e)=>{"use strict";e.Jf=e.dz=void 0;var i=/^([^\w]*)(javascript|data|vbscript)/im,r=/&#(\w+)(^\w|;)?/g,n=/&(newline|tab);/gi,o=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,a=/^.+(:|:)/gim,s=[".","/"];e.dz="about:blank",e.Jf=function(t){if(!t)return e.dz;var l,c=(l=t,l.replace(o,"").replace(r,(function(t,e){return String.fromCharCode(e)}))).replace(n,"").replace(o,"").trim();if(!c)return e.dz;if(function(t){return s.indexOf(t[0])>-1}(c))return c;var h=c.match(a);if(!h)return c;var u=h[0];return i.test(u)?e.dz:c}},27293:(t,e,i)=>{"use strict";i.d(e,{A:()=>F});var r=i(96540),n=i(74848);function o(t){const{mdxAdmonitionTitle:e,rest:i}=function(t){const e=r.Children.toArray(t),i=e.find((t=>r.isValidElement(t)&&"mdxAdmonitionTitle"===t.type)),o=e.filter((t=>t!==i)),a=i?.props.children;return{mdxAdmonitionTitle:a,rest:o.length>0?(0,n.jsx)(n.Fragment,{children:o}):null}}(t.children),o=t.title??e;return{...t,...o&&{title:o},children:i}}var a=i(18215),s=i(21312),l=i(17559);const c={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function h(t){let{type:e,className:i,children:r}=t;return(0,n.jsx)("div",{className:(0,a.A)(l.G.common.admonition,l.G.common.admonitionType(e),c.admonition,i),children:r})}function u(t){let{icon:e,title:i}=t;return(0,n.jsxs)("div",{className:c.admonitionHeading,children:[(0,n.jsx)("span",{className:c.admonitionIcon,children:e}),i]})}function d(t){let{children:e}=t;return e?(0,n.jsx)("div",{className:c.admonitionContent,children:e}):null}function f(t){const{type:e,icon:i,title:r,children:o,className:a}=t;return(0,n.jsxs)(h,{type:e,className:a,children:[(0,n.jsx)(u,{title:r,icon:i}),(0,n.jsx)(d,{children:o})]})}function p(t){return(0,n.jsx)("svg",{viewBox:"0 0 14 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const g={icon:(0,n.jsx)(p,{}),title:(0,n.jsx)(s.A,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function m(t){return(0,n.jsx)(f,{...g,...t,className:(0,a.A)("alert alert--secondary",t.className),children:t.children})}function y(t){return(0,n.jsx)("svg",{viewBox:"0 0 12 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const x={icon:(0,n.jsx)(y,{}),title:(0,n.jsx)(s.A,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function C(t){return(0,n.jsx)(f,{...x,...t,className:(0,a.A)("alert alert--success",t.className),children:t.children})}function b(t){return(0,n.jsx)("svg",{viewBox:"0 0 14 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const _={icon:(0,n.jsx)(b,{}),title:(0,n.jsx)(s.A,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function v(t){return(0,n.jsx)(f,{..._,...t,className:(0,a.A)("alert alert--info",t.className),children:t.children})}function k(t){return(0,n.jsx)("svg",{viewBox:"0 0 16 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const T={icon:(0,n.jsx)(k,{}),title:(0,n.jsx)(s.A,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function A(t){return(0,n.jsx)("svg",{viewBox:"0 0 12 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const w={icon:(0,n.jsx)(A,{}),title:(0,n.jsx)(s.A,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const S={icon:(0,n.jsx)(k,{}),title:(0,n.jsx)(s.A,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const B={...{note:m,tip:C,info:v,warning:function(t){return(0,n.jsx)(f,{...T,...t,className:(0,a.A)("alert alert--warning",t.className),children:t.children})},danger:function(t){return(0,n.jsx)(f,{...w,...t,className:(0,a.A)("alert alert--danger",t.className),children:t.children})}},...{secondary:t=>(0,n.jsx)(m,{title:"secondary",...t}),important:t=>(0,n.jsx)(v,{title:"important",...t}),success:t=>(0,n.jsx)(C,{title:"success",...t}),caution:function(t){return(0,n.jsx)(f,{...S,...t,className:(0,a.A)("alert alert--warning",t.className),children:t.children})}}};function F(t){const e=o(t),i=(r=e.type,B[r]||(console.warn(`No admonition component found for admonition type "${r}". Using Info as fallback.`),B.info));var r;return(0,n.jsx)(i,{...e})}},4336:(t,e,i)=>{"use strict";i.d(e,{A:()=>m});i(96540);var r=i(18215),n=i(21312),o=i(17559),a=i(28774);const s={iconEdit:"iconEdit_Z9Sw"};var l=i(74848);function c(t){let{className:e,...i}=t;return(0,l.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,r.A)(s.iconEdit,e),"aria-hidden":"true",...i,children:(0,l.jsx)("g",{children:(0,l.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function h(t){let{editUrl:e}=t;return(0,l.jsxs)(a.A,{to:e,className:o.G.common.editThisPage,children:[(0,l.jsx)(c,{}),(0,l.jsx)(n.A,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}var u=i(36266);function d(t){let{lastUpdatedAt:e}=t;const i=new Date(e),r=(0,u.i)({day:"numeric",month:"short",year:"numeric",timeZone:"UTC"}).format(i);return(0,l.jsx)(n.A,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,l.jsx)("b",{children:(0,l.jsx)("time",{dateTime:i.toISOString(),itemProp:"dateModified",children:r})})},children:" on {date}"})}function f(t){let{lastUpdatedBy:e}=t;return(0,l.jsx)(n.A,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,l.jsx)("b",{children:e})},children:" by {user}"})}function p(t){let{lastUpdatedAt:e,lastUpdatedBy:i}=t;return(0,l.jsxs)("span",{className:o.G.common.lastUpdated,children:[(0,l.jsx)(n.A,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:e?(0,l.jsx)(d,{lastUpdatedAt:e}):"",byUser:i?(0,l.jsx)(f,{lastUpdatedBy:i}):""},children:"Last updated{atDate}{byUser}"}),!1]})}const g={lastUpdated:"lastUpdated_JAkA"};function m(t){let{className:e,editUrl:i,lastUpdatedAt:n,lastUpdatedBy:o}=t;return(0,l.jsxs)("div",{className:(0,r.A)("row",e),children:[(0,l.jsx)("div",{className:"col",children:i&&(0,l.jsx)(h,{editUrl:i})}),(0,l.jsx)("div",{className:(0,r.A)("col",g.lastUpdated),children:(n||o)&&(0,l.jsx)(p,{lastUpdatedAt:n,lastUpdatedBy:o})})]})}},11544:(t,e,i)=>{"use strict";i.d(e,{A:()=>yt});var r=i(96540),n=i(28453),o=i(5260),a=i(92303),s=i(18215),l=i(95293),c=i(6342);function h(){const{prism:t}=(0,c.p)(),{colorMode:e}=(0,l.G)(),i=t.theme,r=t.darkTheme||i;return"dark"===e?r:i}var u=i(17559),d=i(18426),f=i.n(d);const p=/title=(?["'])(?.*?)\1/,g=/\{(?<range>[\d,-]+)\}/,m={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},y={...m,lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""},vb:{start:"['\u2018\u2019]",end:""},vbnet:{start:"(?:_\\s*)?['\u2018\u2019]",end:""},rem:{start:"[Rr][Ee][Mm]\\b",end:""},f90:{start:"!",end:""},ml:{start:"\\(\\*",end:"\\*\\)"},cobol:{start:"\\*>",end:""}},x=Object.keys(m);function C(t,e){const i=t.map((t=>{const{start:i,end:r}=y[t];return`(?:${i}\\s*(${e.flatMap((t=>[t.line,t.block?.start,t.block?.end].filter(Boolean))).join("|")})\\s*${r})`})).join("|");return new RegExp(`^\\s*(?:${i})\\s*$`)}function b(t,e){let i=t.replace(/\n$/,"");const{language:r,magicComments:n,metastring:o}=e;if(o&&g.test(o)){const t=o.match(g).groups.range;if(0===n.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${o}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const e=n[0].className,r=f()(t).filter((t=>t>0)).map((t=>[t-1,[e]]));return{lineClassNames:Object.fromEntries(r),code:i}}if(void 0===r)return{lineClassNames:{},code:i};const a=function(t,e){switch(t){case"js":case"javascript":case"ts":case"typescript":return C(["js","jsBlock"],e);case"jsx":case"tsx":return C(["js","jsBlock","jsx"],e);case"html":return C(["js","jsBlock","html"],e);case"python":case"py":case"bash":return C(["bash"],e);case"markdown":case"md":return C(["html","jsx","bash"],e);case"tex":case"latex":case"matlab":return C(["tex"],e);case"lua":case"haskell":case"sql":return C(["lua"],e);case"wasm":return C(["wasm"],e);case"vb":case"vba":case"visual-basic":return C(["vb","rem"],e);case"vbnet":return C(["vbnet","rem"],e);case"batch":return C(["rem"],e);case"basic":return C(["rem","f90"],e);case"fsharp":return C(["js","ml"],e);case"ocaml":case"sml":return C(["ml"],e);case"fortran":return C(["f90"],e);case"cobol":return C(["cobol"],e);default:return C(x,e)}}(r,n),s=i.split("\n"),l=Object.fromEntries(n.map((t=>[t.className,{start:0,range:""}]))),c=Object.fromEntries(n.filter((t=>t.line)).map((t=>{let{className:e,line:i}=t;return[i,e]}))),h=Object.fromEntries(n.filter((t=>t.block)).map((t=>{let{className:e,block:i}=t;return[i.start,e]}))),u=Object.fromEntries(n.filter((t=>t.block)).map((t=>{let{className:e,block:i}=t;return[i.end,e]})));for(let f=0;f<s.length;){const t=s[f].match(a);if(!t){f+=1;continue}const e=t.slice(1).find((t=>void 0!==t));c[e]?l[c[e]].range+=`${f},`:h[e]?l[h[e]].start=f:u[e]&&(l[u[e]].range+=`${l[u[e]].start}-${f-1},`),s.splice(f,1)}i=s.join("\n");const d={};return Object.entries(l).forEach((t=>{let[e,{range:i}]=t;f()(i).forEach((t=>{d[t]??=[],d[t].push(e)}))})),{lineClassNames:d,code:i}}const _={codeBlockContainer:"codeBlockContainer_Ckt0"};var v=i(74848);function k(t){let{as:e,...i}=t;const r=function(t){const e={color:"--prism-color",backgroundColor:"--prism-background-color"},i={};return Object.entries(t.plain).forEach((t=>{let[r,n]=t;const o=e[r];o&&"string"==typeof n&&(i[o]=n)})),i}(h());return(0,v.jsx)(e,{...i,style:r,className:(0,s.A)(i.className,_.codeBlockContainer,u.G.common.codeBlock)})}const T={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function A(t){let{children:e,className:i}=t;return(0,v.jsx)(k,{as:"pre",tabIndex:0,className:(0,s.A)(T.codeBlockStandalone,"thin-scrollbar",i),children:(0,v.jsx)("code",{className:T.codeBlockLines,children:e})})}var w=i(89532);const S={attributes:!0,characterData:!0,childList:!0,subtree:!0};function B(t,e){const[i,n]=(0,r.useState)(),o=(0,r.useCallback)((()=>{n(t.current?.closest("[role=tabpanel][hidden]"))}),[t,n]);(0,r.useEffect)((()=>{o()}),[o]),function(t,e,i){void 0===i&&(i=S);const n=(0,w._q)(e),o=(0,w.Be)(i);(0,r.useEffect)((()=>{const e=new MutationObserver(n);return t&&e.observe(t,o),()=>e.disconnect()}),[t,n,o])}(i,(t=>{t.forEach((t=>{"attributes"===t.type&&"hidden"===t.attributeName&&(e(),o())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}var F=i(78181);const L={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function M(t){let{line:e,classNames:i,showLineNumbers:r,getLineProps:n,getTokenProps:o}=t;1===e.length&&"\n"===e[0].content&&(e[0].content="");const a=n({line:e,className:(0,s.A)(i,r&&L.codeLine)}),l=e.map(((t,e)=>(0,v.jsx)("span",{...o({token:t,key:e})},e)));return(0,v.jsxs)("span",{...a,children:[r?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)("span",{className:L.codeLineNumber}),(0,v.jsx)("span",{className:L.codeLineContent,children:l})]}):l,(0,v.jsx)("br",{})]})}var E=i(21312);function N(t){return(0,v.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,v.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function O(t){return(0,v.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,v.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const j={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function I(t){let{code:e,className:i}=t;const[n,o]=(0,r.useState)(!1),a=(0,r.useRef)(void 0),l=(0,r.useCallback)((()=>{!function(t,e){let{target:i=document.body}=void 0===e?{}:e;if("string"!=typeof t)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof t}\`.`);const r=document.createElement("textarea"),n=document.activeElement;r.value=t,r.setAttribute("readonly",""),r.style.contain="strict",r.style.position="absolute",r.style.left="-9999px",r.style.fontSize="12pt";const o=document.getSelection(),a=o.rangeCount>0&&o.getRangeAt(0);i.append(r),r.select(),r.selectionStart=0,r.selectionEnd=t.length;let s=!1;try{s=document.execCommand("copy")}catch{}r.remove(),a&&(o.removeAllRanges(),o.addRange(a)),n&&n.focus()}(e),o(!0),a.current=window.setTimeout((()=>{o(!1)}),1e3)}),[e]);return(0,r.useEffect)((()=>()=>window.clearTimeout(a.current)),[]),(0,v.jsx)("button",{type:"button","aria-label":n?(0,E.T)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,E.T)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,E.T)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,s.A)("clean-btn",i,j.copyButton,n&&j.copyButtonCopied),onClick:l,children:(0,v.jsxs)("span",{className:j.copyButtonIcons,"aria-hidden":"true",children:[(0,v.jsx)(N,{className:j.copyButtonIcon}),(0,v.jsx)(O,{className:j.copyButtonSuccessIcon})]})})}function D(t){return(0,v.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,v.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const q={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function $(t){let{className:e,onClick:i,isEnabled:r}=t;const n=(0,E.T)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,v.jsx)("button",{type:"button",onClick:i,className:(0,s.A)("clean-btn",e,r&&q.wordWrapButtonEnabled),"aria-label":n,title:n,children:(0,v.jsx)(D,{className:q.wordWrapButtonIcon,"aria-hidden":"true"})})}function z(t){let{children:e,className:i="",metastring:n,title:o,showLineNumbers:a,language:l}=t;const{prism:{defaultLanguage:u,magicComments:d}}=(0,c.p)(),f=function(t){return t?.toLowerCase()}(l??function(t){const e=t.split(" ").find((t=>t.startsWith("language-")));return e?.replace(/language-/,"")}(i)??u),g=h(),m=function(){const[t,e]=(0,r.useState)(!1),[i,n]=(0,r.useState)(!1),o=(0,r.useRef)(null),a=(0,r.useCallback)((()=>{const i=o.current.querySelector("code");t?i.removeAttribute("style"):(i.style.whiteSpace="pre-wrap",i.style.overflowWrap="anywhere"),e((t=>!t))}),[o,t]),s=(0,r.useCallback)((()=>{const{scrollWidth:t,clientWidth:e}=o.current,i=t>e||o.current.querySelector("code").hasAttribute("style");n(i)}),[o]);return B(o,s),(0,r.useEffect)((()=>{s()}),[t,s]),(0,r.useEffect)((()=>(window.addEventListener("resize",s,{passive:!0}),()=>{window.removeEventListener("resize",s)})),[s]),{codeBlockRef:o,isEnabled:t,isCodeScrollable:i,toggle:a}}(),y=function(t){return t?.match(p)?.groups.title??""}(n)||o,{lineClassNames:x,code:C}=b(e,{metastring:n,language:f,magicComments:d}),_=a??function(t){return Boolean(t?.includes("showLineNumbers"))}(n);return(0,v.jsxs)(k,{as:"div",className:(0,s.A)(i,f&&!i.includes(`language-${f}`)&&`language-${f}`),children:[y&&(0,v.jsx)("div",{className:T.codeBlockTitle,children:y}),(0,v.jsxs)("div",{className:T.codeBlockContent,children:[(0,v.jsx)(F.f4,{theme:g,code:C,language:f??"text",children:t=>{let{className:e,style:i,tokens:r,getLineProps:n,getTokenProps:o}=t;return(0,v.jsx)("pre",{tabIndex:0,ref:m.codeBlockRef,className:(0,s.A)(e,T.codeBlock,"thin-scrollbar"),style:i,children:(0,v.jsx)("code",{className:(0,s.A)(T.codeBlockLines,_&&T.codeBlockLinesWithNumbering),children:r.map(((t,e)=>(0,v.jsx)(M,{line:t,getLineProps:n,getTokenProps:o,classNames:x[e],showLineNumbers:_},e)))})})}}),(0,v.jsxs)("div",{className:T.buttonGroup,children:[(m.isEnabled||m.isCodeScrollable)&&(0,v.jsx)($,{className:T.codeButton,onClick:()=>m.toggle(),isEnabled:m.isEnabled}),(0,v.jsx)(I,{className:T.codeButton,code:C})]})]})]})}function P(t){let{children:e,...i}=t;const n=(0,a.A)(),o=function(t){return r.Children.toArray(t).some((t=>(0,r.isValidElement)(t)))?t:Array.isArray(t)?t.join(""):t}(e),s="string"==typeof o?z:A;return(0,v.jsx)(s,{...i,children:o},String(n))}function R(t){return(0,v.jsx)("code",{...t})}var W=i(28774);var U=i(15066),H=i(63427),Y=i(41422);const V={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function G(t){return!!t&&("SUMMARY"===t.tagName||G(t.parentElement))}function X(t,e){return!!t&&(t===e||X(t.parentElement,e))}function Z(t){let{summary:e,children:i,...n}=t;(0,H.A)().collectAnchor(n.id);const o=(0,a.A)(),s=(0,r.useRef)(null),{collapsed:l,setCollapsed:c}=(0,Y.u)({initialState:!n.open}),[h,u]=(0,r.useState)(n.open),d=r.isValidElement(e)?e:(0,v.jsx)("summary",{children:e??"Details"});return(0,v.jsxs)("details",{...n,ref:s,open:h,"data-collapsed":l,className:(0,U.A)(V.details,o&&V.isBrowser,n.className),onMouseDown:t=>{G(t.target)&&t.detail>1&&t.preventDefault()},onClick:t=>{t.stopPropagation();const e=t.target;G(e)&&X(e,s.current)&&(t.preventDefault(),l?(c(!1),u(!0)):c(!0))},children:[d,(0,v.jsx)(Y.N,{lazy:!1,collapsed:l,disableSSRStyle:!0,onCollapseTransitionEnd:t=>{c(t),u(!t)},children:(0,v.jsx)("div",{className:V.collapsibleContent,children:i})})]})}const J={details:"details_b_Ee"},Q="alert alert--info";function K(t){let{...e}=t;return(0,v.jsx)(Z,{...e,className:(0,s.A)(Q,J.details,e.className)})}function tt(t){const e=r.Children.toArray(t.children),i=e.find((t=>r.isValidElement(t)&&"summary"===t.type)),n=(0,v.jsx)(v.Fragment,{children:e.filter((t=>t!==i))});return(0,v.jsx)(K,{...t,summary:i,children:n})}var et=i(51107);function it(t){return(0,v.jsx)(et.A,{...t})}const rt={containsTaskList:"containsTaskList_mC6p"};function nt(t){if(void 0!==t)return(0,s.A)(t,t?.includes("contains-task-list")&&rt.containsTaskList)}const ot={img:"img_ev3q"};var at=i(27293),st=i(67489),lt=i(12181),ct=i(76257);const ht="docusaurus-mermaid-container";function ut(){const{colorMode:t}=(0,l.G)(),e=(0,c.p)().mermaid,i=e.theme[t],{options:n}=e;return(0,r.useMemo)((()=>({startOnLoad:!1,...n,theme:i})),[i,n])}function dt(t){let{text:e,config:i}=t;const[n,o]=(0,r.useState)(null),a=(0,r.useRef)(`mermaid-svg-${Math.round(1e7*Math.random())}`).current,s=ut(),l=i??s;return(0,r.useEffect)((()=>{(async function(t){let{id:e,text:i,config:r}=t;ct.N.mermaidAPI.initialize(r);try{return await ct.N.render(e,i)}catch(n){throw document.querySelector(`#d${e}`)?.remove(),n}})({id:a,text:e,config:l}).then(o).catch((t=>{o((()=>{throw t}))}))}),[a,e,l]),n}const ft={container:"container_lyt7"};function pt(t){let{renderResult:e}=t;const i=(0,r.useRef)(null);return(0,r.useEffect)((()=>{const t=i.current;e.bindFunctions?.(t)}),[e]),(0,v.jsx)("div",{ref:i,className:`${ht} ${ft.container}`,dangerouslySetInnerHTML:{__html:e.svg}})}function gt(t){let{value:e}=t;const i=dt({text:e});return null===i?null:(0,v.jsx)(pt,{renderResult:i})}const mt={Head:o.A,details:tt,Details:tt,code:function(t){return function(t){return void 0!==t.children&&r.Children.toArray(t.children).every((t=>"string"==typeof t&&!t.includes("\n")))}(t)?(0,v.jsx)(R,{...t}):(0,v.jsx)(P,{...t})},a:function(t){return(0,v.jsx)(W.A,{...t})},pre:function(t){return(0,v.jsx)(v.Fragment,{children:t.children})},ul:function(t){return(0,v.jsx)("ul",{...t,className:nt(t.className)})},li:function(t){return(0,H.A)().collectAnchor(t.id),(0,v.jsx)("li",{...t})},img:function(t){return(0,v.jsx)("img",{decoding:"async",loading:"lazy",...t,className:(e=t.className,(0,s.A)(e,ot.img))});var e},h1:t=>(0,v.jsx)(it,{as:"h1",...t}),h2:t=>(0,v.jsx)(it,{as:"h2",...t}),h3:t=>(0,v.jsx)(it,{as:"h3",...t}),h4:t=>(0,v.jsx)(it,{as:"h4",...t}),h5:t=>(0,v.jsx)(it,{as:"h5",...t}),h6:t=>(0,v.jsx)(it,{as:"h6",...t}),admonition:at.A,mermaid:function(t){return(0,v.jsx)(st.A,{fallback:t=>(0,v.jsx)(lt.MN,{...t}),children:(0,v.jsx)(gt,{...t})})}};function yt(t){let{children:e}=t;return(0,v.jsx)(n.x,{components:mt,children:e})}},39022:(t,e,i)=>{"use strict";i.d(e,{A:()=>a});i(96540);var r=i(18215),n=i(28774),o=i(74848);function a(t){const{permalink:e,title:i,subLabel:a,isNext:s}=t;return(0,o.jsxs)(n.A,{className:(0,r.A)("pagination-nav__link",s?"pagination-nav__link--next":"pagination-nav__link--prev"),to:e,children:[a&&(0,o.jsx)("div",{className:"pagination-nav__sublabel",children:a}),(0,o.jsx)("div",{className:"pagination-nav__label",children:i})]})}},56133:(t,e,i)=>{"use strict";i.d(e,{A:()=>s});i(96540);var r=i(18215),n=i(28774);const o={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var a=i(74848);function s(t){let{permalink:e,label:i,count:s}=t;return(0,a.jsxs)(n.A,{href:e,className:(0,r.A)(o.tag,s?o.tagWithCount:o.tagRegular),children:[i,s&&(0,a.jsx)("span",{children:s})]})}},62053:(t,e,i)=>{"use strict";i.d(e,{A:()=>l});i(96540);var r=i(18215),n=i(21312),o=i(56133);const a={tags:"tags_jXut",tag:"tag_QGVx"};var s=i(74848);function l(t){let{tags:e}=t;return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("b",{children:(0,s.jsx)(n.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,s.jsx)("ul",{className:(0,r.A)(a.tags,"padding--none","margin-left--sm"),children:e.map((t=>{let{label:e,permalink:i}=t;return(0,s.jsx)("li",{className:a.tag,children:(0,s.jsx)(o.A,{label:e,permalink:i})},i)}))})]})}},36266:(t,e,i)=>{"use strict";i.d(e,{i:()=>n});var r=i(44586);function n(t){void 0===t&&(t={});const{i18n:{currentLocale:e}}=(0,r.A)(),i=function(){const{i18n:{currentLocale:t,localeConfigs:e}}=(0,r.A)();return e[t].calendar}();return new Intl.DateTimeFormat(e,{calendar:i,...t})}},74353:function(t){t.exports=function(){"use strict";var t=1e3,e=6e4,i=36e5,r="millisecond",n="second",o="minute",a="hour",s="day",l="week",c="month",h="quarter",u="year",d="date",f="Invalid Date",p=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,g=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,m={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],i=t%100;return"["+t+(e[(i-20)%10]||e[i]||e[0])+"]"}},y=function(t,e,i){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(i)+t},x={s:y,z:function(t){var e=-t.utcOffset(),i=Math.abs(e),r=Math.floor(i/60),n=i%60;return(e<=0?"+":"-")+y(r,2,"0")+":"+y(n,2,"0")},m:function t(e,i){if(e.date()<i.date())return-t(i,e);var r=12*(i.year()-e.year())+(i.month()-e.month()),n=e.clone().add(r,c),o=i-n<0,a=e.clone().add(r+(o?-1:1),c);return+(-(r+(i-n)/(o?n-a:a-n))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return{M:c,y:u,w:l,d:s,D:d,h:a,m:o,s:n,ms:r,Q:h}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},C="en",b={};b[C]=m;var _="$isDayjsObject",v=function(t){return t instanceof w||!(!t||!t[_])},k=function t(e,i,r){var n;if(!e)return C;if("string"==typeof e){var o=e.toLowerCase();b[o]&&(n=o),i&&(b[o]=i,n=o);var a=e.split("-");if(!n&&a.length>1)return t(a[0])}else{var s=e.name;b[s]=e,n=s}return!r&&n&&(C=n),n||!r&&C},T=function(t,e){if(v(t))return t.clone();var i="object"==typeof e?e:{};return i.date=t,i.args=arguments,new w(i)},A=x;A.l=k,A.i=v,A.w=function(t,e){return T(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var w=function(){function m(t){this.$L=k(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[_]=!0}var y=m.prototype;return y.parse=function(t){this.$d=function(t){var e=t.date,i=t.utc;if(null===e)return new Date(NaN);if(A.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(p);if(r){var n=r[2]-1||0,o=(r[7]||"0").substring(0,3);return i?new Date(Date.UTC(r[1],n,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)):new Date(r[1],n,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)}}return new Date(e)}(t),this.init()},y.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},y.$utils=function(){return A},y.isValid=function(){return!(this.$d.toString()===f)},y.isSame=function(t,e){var i=T(t);return this.startOf(e)<=i&&i<=this.endOf(e)},y.isAfter=function(t,e){return T(t)<this.startOf(e)},y.isBefore=function(t,e){return this.endOf(e)<T(t)},y.$g=function(t,e,i){return A.u(t)?this[e]:this.set(i,t)},y.unix=function(){return Math.floor(this.valueOf()/1e3)},y.valueOf=function(){return this.$d.getTime()},y.startOf=function(t,e){var i=this,r=!!A.u(e)||e,h=A.p(t),f=function(t,e){var n=A.w(i.$u?Date.UTC(i.$y,e,t):new Date(i.$y,e,t),i);return r?n:n.endOf(s)},p=function(t,e){return A.w(i.toDate()[t].apply(i.toDate("s"),(r?[0,0,0,0]:[23,59,59,999]).slice(e)),i)},g=this.$W,m=this.$M,y=this.$D,x="set"+(this.$u?"UTC":"");switch(h){case u:return r?f(1,0):f(31,11);case c:return r?f(1,m):f(0,m+1);case l:var C=this.$locale().weekStart||0,b=(g<C?g+7:g)-C;return f(r?y-b:y+(6-b),m);case s:case d:return p(x+"Hours",0);case a:return p(x+"Minutes",1);case o:return p(x+"Seconds",2);case n:return p(x+"Milliseconds",3);default:return this.clone()}},y.endOf=function(t){return this.startOf(t,!1)},y.$set=function(t,e){var i,l=A.p(t),h="set"+(this.$u?"UTC":""),f=(i={},i[s]=h+"Date",i[d]=h+"Date",i[c]=h+"Month",i[u]=h+"FullYear",i[a]=h+"Hours",i[o]=h+"Minutes",i[n]=h+"Seconds",i[r]=h+"Milliseconds",i)[l],p=l===s?this.$D+(e-this.$W):e;if(l===c||l===u){var g=this.clone().set(d,1);g.$d[f](p),g.init(),this.$d=g.set(d,Math.min(this.$D,g.daysInMonth())).$d}else f&&this.$d[f](p);return this.init(),this},y.set=function(t,e){return this.clone().$set(t,e)},y.get=function(t){return this[A.p(t)]()},y.add=function(r,h){var d,f=this;r=Number(r);var p=A.p(h),g=function(t){var e=T(f);return A.w(e.date(e.date()+Math.round(t*r)),f)};if(p===c)return this.set(c,this.$M+r);if(p===u)return this.set(u,this.$y+r);if(p===s)return g(1);if(p===l)return g(7);var m=(d={},d[o]=e,d[a]=i,d[n]=t,d)[p]||1,y=this.$d.getTime()+r*m;return A.w(y,this)},y.subtract=function(t,e){return this.add(-1*t,e)},y.format=function(t){var e=this,i=this.$locale();if(!this.isValid())return i.invalidDate||f;var r=t||"YYYY-MM-DDTHH:mm:ssZ",n=A.z(this),o=this.$H,a=this.$m,s=this.$M,l=i.weekdays,c=i.months,h=i.meridiem,u=function(t,i,n,o){return t&&(t[i]||t(e,r))||n[i].slice(0,o)},d=function(t){return A.s(o%12||12,t,"0")},p=h||function(t,e,i){var r=t<12?"AM":"PM";return i?r.toLowerCase():r};return r.replace(g,(function(t,r){return r||function(t){switch(t){case"YY":return String(e.$y).slice(-2);case"YYYY":return A.s(e.$y,4,"0");case"M":return s+1;case"MM":return A.s(s+1,2,"0");case"MMM":return u(i.monthsShort,s,c,3);case"MMMM":return u(c,s);case"D":return e.$D;case"DD":return A.s(e.$D,2,"0");case"d":return String(e.$W);case"dd":return u(i.weekdaysMin,e.$W,l,2);case"ddd":return u(i.weekdaysShort,e.$W,l,3);case"dddd":return l[e.$W];case"H":return String(o);case"HH":return A.s(o,2,"0");case"h":return d(1);case"hh":return d(2);case"a":return p(o,a,!0);case"A":return p(o,a,!1);case"m":return String(a);case"mm":return A.s(a,2,"0");case"s":return String(e.$s);case"ss":return A.s(e.$s,2,"0");case"SSS":return A.s(e.$ms,3,"0");case"Z":return n}return null}(t)||n.replace(":","")}))},y.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},y.diff=function(r,d,f){var p,g=this,m=A.p(d),y=T(r),x=(y.utcOffset()-this.utcOffset())*e,C=this-y,b=function(){return A.m(g,y)};switch(m){case u:p=b()/12;break;case c:p=b();break;case h:p=b()/3;break;case l:p=(C-x)/6048e5;break;case s:p=(C-x)/864e5;break;case a:p=C/i;break;case o:p=C/e;break;case n:p=C/t;break;default:p=C}return f?p:A.a(p)},y.daysInMonth=function(){return this.endOf(c).$D},y.$locale=function(){return b[this.$L]},y.locale=function(t,e){if(!t)return this.$L;var i=this.clone(),r=k(t,e,!0);return r&&(i.$L=r),i},y.clone=function(){return A.w(this.$d,this)},y.toDate=function(){return new Date(this.valueOf())},y.toJSON=function(){return this.isValid()?this.toISOString():null},y.toISOString=function(){return this.$d.toISOString()},y.toString=function(){return this.$d.toUTCString()},m}(),S=w.prototype;return T.prototype=S,[["$ms",r],["$s",n],["$m",o],["$H",a],["$W",s],["$M",c],["$y",u],["$D",d]].forEach((function(t){S[t[1]]=function(e){return this.$g(e,t[0],t[1])}})),T.extend=function(t,e){return t.$i||(t(e,w,T),t.$i=!0),T},T.locale=k,T.isDayjs=v,T.unix=function(t){return T(1e3*t)},T.en=b[C],T.Ls=b,T.p={},T}()},42838:function(t){t.exports=function(){"use strict";const{entries:t,setPrototypeOf:e,isFrozen:i,getPrototypeOf:r,getOwnPropertyDescriptor:n}=Object;let{freeze:o,seal:a,create:s}=Object,{apply:l,construct:c}="undefined"!=typeof Reflect&&Reflect;o||(o=function(t){return t}),a||(a=function(t){return t}),l||(l=function(t,e,i){return t.apply(e,i)}),c||(c=function(t,e){return new t(...e)});const h=v(Array.prototype.forEach),u=v(Array.prototype.pop),d=v(Array.prototype.push),f=v(String.prototype.toLowerCase),p=v(String.prototype.toString),g=v(String.prototype.match),m=v(String.prototype.replace),y=v(String.prototype.indexOf),x=v(String.prototype.trim),C=v(Object.prototype.hasOwnProperty),b=v(RegExp.prototype.test),_=k(TypeError);function v(t){return function(e){for(var i=arguments.length,r=new Array(i>1?i-1:0),n=1;n<i;n++)r[n-1]=arguments[n];return l(t,e,r)}}function k(t){return function(){for(var e=arguments.length,i=new Array(e),r=0;r<e;r++)i[r]=arguments[r];return c(t,i)}}function T(t,r){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:f;e&&e(t,null);let o=r.length;for(;o--;){let e=r[o];if("string"==typeof e){const t=n(e);t!==e&&(i(r)||(r[o]=t),e=t)}t[e]=!0}return t}function A(t){for(let e=0;e<t.length;e++)C(t,e)||(t[e]=null);return t}function w(e){const i=s(null);for(const[r,n]of t(e))C(e,r)&&(Array.isArray(n)?i[r]=A(n):n&&"object"==typeof n&&n.constructor===Object?i[r]=w(n):i[r]=n);return i}function S(t,e){for(;null!==t;){const i=n(t,e);if(i){if(i.get)return v(i.get);if("function"==typeof i.value)return v(i.value)}t=r(t)}function i(){return null}return i}const B=o(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),F=o(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),L=o(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),M=o(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),E=o(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),N=o(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),O=o(["#text"]),j=o(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","xmlns","slot"]),I=o(["accent-height","accumulate","additive","alignment-baseline","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),D=o(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),q=o(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),$=a(/\{\{[\w\W]*|[\w\W]*\}\}/gm),z=a(/<%[\w\W]*|[\w\W]*%>/gm),P=a(/\${[\w\W]*}/gm),R=a(/^data-[\-\w.\u00B7-\uFFFF]/),W=a(/^aria-[\-\w]+$/),U=a(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),H=a(/^(?:\w+script|data):/i),Y=a(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),V=a(/^html$/i),G=a(/^[a-z][.\w]*(-[.\w]+)+$/i);var X=Object.freeze({__proto__:null,MUSTACHE_EXPR:$,ERB_EXPR:z,TMPLIT_EXPR:P,DATA_ATTR:R,ARIA_ATTR:W,IS_ALLOWED_URI:U,IS_SCRIPT_OR_DATA:H,ATTR_WHITESPACE:Y,DOCTYPE_NAME:V,CUSTOM_ELEMENT:G});const Z=function(){return"undefined"==typeof window?null:window},J=function(t,e){if("object"!=typeof t||"function"!=typeof t.createPolicy)return null;let i=null;const r="data-tt-policy-suffix";e&&e.hasAttribute(r)&&(i=e.getAttribute(r));const n="dompurify"+(i?"#"+i:"");try{return t.createPolicy(n,{createHTML:t=>t,createScriptURL:t=>t})}catch(o){return console.warn("TrustedTypes policy "+n+" could not be created."),null}};function Q(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Z();const i=t=>Q(t);if(i.version="3.0.11",i.removed=[],!e||!e.document||9!==e.document.nodeType)return i.isSupported=!1,i;let{document:r}=e;const n=r,a=n.currentScript,{DocumentFragment:l,HTMLTemplateElement:c,Node:v,Element:k,NodeFilter:A,NamedNodeMap:$=e.NamedNodeMap||e.MozNamedAttrMap,HTMLFormElement:z,DOMParser:P,trustedTypes:R}=e,W=k.prototype,H=S(W,"cloneNode"),Y=S(W,"nextSibling"),G=S(W,"childNodes"),K=S(W,"parentNode");if("function"==typeof c){const t=r.createElement("template");t.content&&t.content.ownerDocument&&(r=t.content.ownerDocument)}let tt,et="";const{implementation:it,createNodeIterator:rt,createDocumentFragment:nt,getElementsByTagName:ot}=r,{importNode:at}=n;let st={};i.isSupported="function"==typeof t&&"function"==typeof K&&it&&void 0!==it.createHTMLDocument;const{MUSTACHE_EXPR:lt,ERB_EXPR:ct,TMPLIT_EXPR:ht,DATA_ATTR:ut,ARIA_ATTR:dt,IS_SCRIPT_OR_DATA:ft,ATTR_WHITESPACE:pt,CUSTOM_ELEMENT:gt}=X;let{IS_ALLOWED_URI:mt}=X,yt=null;const xt=T({},[...B,...F,...L,...E,...O]);let Ct=null;const bt=T({},[...j,...I,...D,...q]);let _t=Object.seal(s(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),vt=null,kt=null,Tt=!0,At=!0,wt=!1,St=!0,Bt=!1,Ft=!1,Lt=!1,Mt=!1,Et=!1,Nt=!1,Ot=!1,jt=!0,It=!1;const Dt="user-content-";let qt=!0,$t=!1,zt={},Pt=null;const Rt=T({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let Wt=null;const Ut=T({},["audio","video","img","source","image","track"]);let Ht=null;const Yt=T({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Vt="http://www.w3.org/1998/Math/MathML",Gt="http://www.w3.org/2000/svg",Xt="http://www.w3.org/1999/xhtml";let Zt=Xt,Jt=!1,Qt=null;const Kt=T({},[Vt,Gt,Xt],p);let te=null;const ee=["application/xhtml+xml","text/html"],ie="text/html";let re=null,ne=null;const oe=r.createElement("form"),ae=function(t){return t instanceof RegExp||t instanceof Function},se=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!ne||ne!==t){if(t&&"object"==typeof t||(t={}),t=w(t),te=-1===ee.indexOf(t.PARSER_MEDIA_TYPE)?ie:t.PARSER_MEDIA_TYPE,re="application/xhtml+xml"===te?p:f,yt=C(t,"ALLOWED_TAGS")?T({},t.ALLOWED_TAGS,re):xt,Ct=C(t,"ALLOWED_ATTR")?T({},t.ALLOWED_ATTR,re):bt,Qt=C(t,"ALLOWED_NAMESPACES")?T({},t.ALLOWED_NAMESPACES,p):Kt,Ht=C(t,"ADD_URI_SAFE_ATTR")?T(w(Yt),t.ADD_URI_SAFE_ATTR,re):Yt,Wt=C(t,"ADD_DATA_URI_TAGS")?T(w(Ut),t.ADD_DATA_URI_TAGS,re):Ut,Pt=C(t,"FORBID_CONTENTS")?T({},t.FORBID_CONTENTS,re):Rt,vt=C(t,"FORBID_TAGS")?T({},t.FORBID_TAGS,re):{},kt=C(t,"FORBID_ATTR")?T({},t.FORBID_ATTR,re):{},zt=!!C(t,"USE_PROFILES")&&t.USE_PROFILES,Tt=!1!==t.ALLOW_ARIA_ATTR,At=!1!==t.ALLOW_DATA_ATTR,wt=t.ALLOW_UNKNOWN_PROTOCOLS||!1,St=!1!==t.ALLOW_SELF_CLOSE_IN_ATTR,Bt=t.SAFE_FOR_TEMPLATES||!1,Ft=t.WHOLE_DOCUMENT||!1,Et=t.RETURN_DOM||!1,Nt=t.RETURN_DOM_FRAGMENT||!1,Ot=t.RETURN_TRUSTED_TYPE||!1,Mt=t.FORCE_BODY||!1,jt=!1!==t.SANITIZE_DOM,It=t.SANITIZE_NAMED_PROPS||!1,qt=!1!==t.KEEP_CONTENT,$t=t.IN_PLACE||!1,mt=t.ALLOWED_URI_REGEXP||U,Zt=t.NAMESPACE||Xt,_t=t.CUSTOM_ELEMENT_HANDLING||{},t.CUSTOM_ELEMENT_HANDLING&&ae(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(_t.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&ae(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(_t.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(_t.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Bt&&(At=!1),Nt&&(Et=!0),zt&&(yt=T({},O),Ct=[],!0===zt.html&&(T(yt,B),T(Ct,j)),!0===zt.svg&&(T(yt,F),T(Ct,I),T(Ct,q)),!0===zt.svgFilters&&(T(yt,L),T(Ct,I),T(Ct,q)),!0===zt.mathMl&&(T(yt,E),T(Ct,D),T(Ct,q))),t.ADD_TAGS&&(yt===xt&&(yt=w(yt)),T(yt,t.ADD_TAGS,re)),t.ADD_ATTR&&(Ct===bt&&(Ct=w(Ct)),T(Ct,t.ADD_ATTR,re)),t.ADD_URI_SAFE_ATTR&&T(Ht,t.ADD_URI_SAFE_ATTR,re),t.FORBID_CONTENTS&&(Pt===Rt&&(Pt=w(Pt)),T(Pt,t.FORBID_CONTENTS,re)),qt&&(yt["#text"]=!0),Ft&&T(yt,["html","head","body"]),yt.table&&(T(yt,["tbody"]),delete vt.tbody),t.TRUSTED_TYPES_POLICY){if("function"!=typeof t.TRUSTED_TYPES_POLICY.createHTML)throw _('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof t.TRUSTED_TYPES_POLICY.createScriptURL)throw _('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');tt=t.TRUSTED_TYPES_POLICY,et=tt.createHTML("")}else void 0===tt&&(tt=J(R,a)),null!==tt&&"string"==typeof et&&(et=tt.createHTML(""));o&&o(t),ne=t}},le=T({},["mi","mo","mn","ms","mtext"]),ce=T({},["foreignobject","desc","title","annotation-xml"]),he=T({},["title","style","font","a","script"]),ue=T({},[...F,...L,...M]),de=T({},[...E,...N]),fe=function(t){let e=K(t);e&&e.tagName||(e={namespaceURI:Zt,tagName:"template"});const i=f(t.tagName),r=f(e.tagName);return!!Qt[t.namespaceURI]&&(t.namespaceURI===Gt?e.namespaceURI===Xt?"svg"===i:e.namespaceURI===Vt?"svg"===i&&("annotation-xml"===r||le[r]):Boolean(ue[i]):t.namespaceURI===Vt?e.namespaceURI===Xt?"math"===i:e.namespaceURI===Gt?"math"===i&&ce[r]:Boolean(de[i]):t.namespaceURI===Xt?!(e.namespaceURI===Gt&&!ce[r])&&!(e.namespaceURI===Vt&&!le[r])&&!de[i]&&(he[i]||!ue[i]):!("application/xhtml+xml"!==te||!Qt[t.namespaceURI]))},pe=function(t){d(i.removed,{element:t});try{t.parentNode.removeChild(t)}catch(e){t.remove()}},ge=function(t,e){try{d(i.removed,{attribute:e.getAttributeNode(t),from:e})}catch(r){d(i.removed,{attribute:null,from:e})}if(e.removeAttribute(t),"is"===t&&!Ct[t])if(Et||Nt)try{pe(e)}catch(r){}else try{e.setAttribute(t,"")}catch(r){}},me=function(t){let e=null,i=null;if(Mt)t="<remove></remove>"+t;else{const e=g(t,/^[\r\n\t ]+/);i=e&&e[0]}"application/xhtml+xml"===te&&Zt===Xt&&(t='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+t+"</body></html>");const n=tt?tt.createHTML(t):t;if(Zt===Xt)try{e=(new P).parseFromString(n,te)}catch(a){}if(!e||!e.documentElement){e=it.createDocument(Zt,"template",null);try{e.documentElement.innerHTML=Jt?et:n}catch(a){}}const o=e.body||e.documentElement;return t&&i&&o.insertBefore(r.createTextNode(i),o.childNodes[0]||null),Zt===Xt?ot.call(e,Ft?"html":"body")[0]:Ft?e.documentElement:o},ye=function(t){return rt.call(t.ownerDocument||t,t,A.SHOW_ELEMENT|A.SHOW_COMMENT|A.SHOW_TEXT|A.SHOW_PROCESSING_INSTRUCTION|A.SHOW_CDATA_SECTION,null)},xe=function(t){return t instanceof z&&("string"!=typeof t.nodeName||"string"!=typeof t.textContent||"function"!=typeof t.removeChild||!(t.attributes instanceof $)||"function"!=typeof t.removeAttribute||"function"!=typeof t.setAttribute||"string"!=typeof t.namespaceURI||"function"!=typeof t.insertBefore||"function"!=typeof t.hasChildNodes)},Ce=function(t){return"function"==typeof v&&t instanceof v},be=function(t,e,r){st[t]&&h(st[t],(t=>{t.call(i,e,r,ne)}))},_e=function(t){let e=null;if(be("beforeSanitizeElements",t,null),xe(t))return pe(t),!0;const r=re(t.nodeName);if(be("uponSanitizeElement",t,{tagName:r,allowedTags:yt}),t.hasChildNodes()&&!Ce(t.firstElementChild)&&b(/<[/\w]/g,t.innerHTML)&&b(/<[/\w]/g,t.textContent))return pe(t),!0;if(7===t.nodeType)return pe(t),!0;if(!yt[r]||vt[r]){if(!vt[r]&&ke(r)){if(_t.tagNameCheck instanceof RegExp&&b(_t.tagNameCheck,r))return!1;if(_t.tagNameCheck instanceof Function&&_t.tagNameCheck(r))return!1}if(qt&&!Pt[r]){const e=K(t)||t.parentNode,i=G(t)||t.childNodes;if(i&&e)for(let r=i.length-1;r>=0;--r)e.insertBefore(H(i[r],!0),Y(t))}return pe(t),!0}return t instanceof k&&!fe(t)?(pe(t),!0):"noscript"!==r&&"noembed"!==r&&"noframes"!==r||!b(/<\/no(script|embed|frames)/i,t.innerHTML)?(Bt&&3===t.nodeType&&(e=t.textContent,h([lt,ct,ht],(t=>{e=m(e,t," ")})),t.textContent!==e&&(d(i.removed,{element:t.cloneNode()}),t.textContent=e)),be("afterSanitizeElements",t,null),!1):(pe(t),!0)},ve=function(t,e,i){if(jt&&("id"===e||"name"===e)&&(i in r||i in oe))return!1;if(At&&!kt[e]&&b(ut,e));else if(Tt&&b(dt,e));else if(!Ct[e]||kt[e]){if(!(ke(t)&&(_t.tagNameCheck instanceof RegExp&&b(_t.tagNameCheck,t)||_t.tagNameCheck instanceof Function&&_t.tagNameCheck(t))&&(_t.attributeNameCheck instanceof RegExp&&b(_t.attributeNameCheck,e)||_t.attributeNameCheck instanceof Function&&_t.attributeNameCheck(e))||"is"===e&&_t.allowCustomizedBuiltInElements&&(_t.tagNameCheck instanceof RegExp&&b(_t.tagNameCheck,i)||_t.tagNameCheck instanceof Function&&_t.tagNameCheck(i))))return!1}else if(Ht[e]);else if(b(mt,m(i,pt,"")));else if("src"!==e&&"xlink:href"!==e&&"href"!==e||"script"===t||0!==y(i,"data:")||!Wt[t])if(wt&&!b(ft,m(i,pt,"")));else if(i)return!1;return!0},ke=function(t){return"annotation-xml"!==t&&g(t,gt)},Te=function(t){be("beforeSanitizeAttributes",t,null);const{attributes:e}=t;if(!e)return;const r={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Ct};let n=e.length;for(;n--;){const a=e[n],{name:s,namespaceURI:l,value:c}=a,d=re(s);let f="value"===s?c:x(c);if(r.attrName=d,r.attrValue=f,r.keepAttr=!0,r.forceKeepAttr=void 0,be("uponSanitizeAttribute",t,r),f=r.attrValue,r.forceKeepAttr)continue;if(ge(s,t),!r.keepAttr)continue;if(!St&&b(/\/>/i,f)){ge(s,t);continue}Bt&&h([lt,ct,ht],(t=>{f=m(f,t," ")}));const p=re(t.nodeName);if(ve(p,d,f)){if(!It||"id"!==d&&"name"!==d||(ge(s,t),f=Dt+f),tt&&"object"==typeof R&&"function"==typeof R.getAttributeType)if(l);else switch(R.getAttributeType(p,d)){case"TrustedHTML":f=tt.createHTML(f);break;case"TrustedScriptURL":f=tt.createScriptURL(f)}try{l?t.setAttributeNS(l,s,f):t.setAttribute(s,f),u(i.removed)}catch(o){}}}be("afterSanitizeAttributes",t,null)},Ae=function t(e){let i=null;const r=ye(e);for(be("beforeSanitizeShadowDOM",e,null);i=r.nextNode();)be("uponSanitizeShadowNode",i,null),_e(i)||(i.content instanceof l&&t(i.content),Te(i));be("afterSanitizeShadowDOM",e,null)};return i.sanitize=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=null,o=null,a=null,s=null;if(Jt=!t,Jt&&(t="\x3c!--\x3e"),"string"!=typeof t&&!Ce(t)){if("function"!=typeof t.toString)throw _("toString is not a function");if("string"!=typeof(t=t.toString()))throw _("dirty is not a string, aborting")}if(!i.isSupported)return t;if(Lt||se(e),i.removed=[],"string"==typeof t&&($t=!1),$t){if(t.nodeName){const e=re(t.nodeName);if(!yt[e]||vt[e])throw _("root node is forbidden and cannot be sanitized in-place")}}else if(t instanceof v)r=me("\x3c!----\x3e"),o=r.ownerDocument.importNode(t,!0),1===o.nodeType&&"BODY"===o.nodeName||"HTML"===o.nodeName?r=o:r.appendChild(o);else{if(!Et&&!Bt&&!Ft&&-1===t.indexOf("<"))return tt&&Ot?tt.createHTML(t):t;if(r=me(t),!r)return Et?null:Ot?et:""}r&&Mt&&pe(r.firstChild);const c=ye($t?t:r);for(;a=c.nextNode();)_e(a)||(a.content instanceof l&&Ae(a.content),Te(a));if($t)return t;if(Et){if(Nt)for(s=nt.call(r.ownerDocument);r.firstChild;)s.appendChild(r.firstChild);else s=r;return(Ct.shadowroot||Ct.shadowrootmode)&&(s=at.call(n,s,!0)),s}let u=Ft?r.outerHTML:r.innerHTML;return Ft&&yt["!doctype"]&&r.ownerDocument&&r.ownerDocument.doctype&&r.ownerDocument.doctype.name&&b(V,r.ownerDocument.doctype.name)&&(u="<!DOCTYPE "+r.ownerDocument.doctype.name+">\n"+u),Bt&&h([lt,ct,ht],(t=>{u=m(u,t," ")})),tt&&Ot?tt.createHTML(u):u},i.setConfig=function(){se(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),Lt=!0},i.clearConfig=function(){ne=null,Lt=!1},i.isValidAttribute=function(t,e,i){ne||se({});const r=re(t),n=re(e);return ve(r,n,i)},i.addHook=function(t,e){"function"==typeof e&&(st[t]=st[t]||[],d(st[t],e))},i.removeHook=function(t){if(st[t])return u(st[t])},i.removeHooks=function(t){st[t]&&(st[t]=[])},i.removeAllHooks=function(){st={}},i}return Q()}()},18426:(t,e)=>{function i(t){let e,i=[];for(let r of t.split(",").map((t=>t.trim())))if(/^-?\d+$/.test(r))i.push(parseInt(r,10));else if(e=r.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[t,r,n,o]=e;if(r&&o){r=parseInt(r),o=parseInt(o);const t=r<o?1:-1;"-"!==n&&".."!==n&&"\u2025"!==n||(o+=t);for(let e=r;e!==o;e+=t)i.push(e)}}return i}e.default=i,t.exports=i},60513:(t,e,i)=>{"use strict";function r(t){for(var e=[],i=1;i<arguments.length;i++)e[i-1]=arguments[i];var r=Array.from("string"==typeof t?[t]:t);r[r.length-1]=r[r.length-1].replace(/\r?\n([\t ]*)$/,"");var n=r.reduce((function(t,e){var i=e.match(/\n([\t ]+|(?!\s).)/g);return i?t.concat(i.map((function(t){var e,i;return null!==(i=null===(e=t.match(/[\t ]/g))||void 0===e?void 0:e.length)&&void 0!==i?i:0}))):t}),[]);if(n.length){var o=new RegExp("\n[\t ]{"+Math.min.apply(Math,n)+"}","g");r=r.map((function(t){return t.replace(o,"\n")}))}r[0]=r[0].replace(/^\r?\n/,"");var a=r[0];return e.forEach((function(t,e){var i=a.match(/(?:^|\n)( *)$/),n=i?i[1]:"",o=t;"string"==typeof t&&t.includes("\n")&&(o=String(t).split("\n").map((function(t,e){return 0===e?t:""+n+t})).join("\n")),a+=o+r[e+1]})),a}i.d(e,{T:()=>r})},28453:(t,e,i)=>{"use strict";i.d(e,{R:()=>a,x:()=>s});var r=i(96540);const n={},o=r.createContext(n);function a(t){const e=r.useContext(o);return r.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(n):t.components||n:a(t.components),r.createElement(o.Provider,{value:e},t.children)}},26312:(t,e,i)=>{"use strict";function r(t,e){let i;if(void 0===e)for(const r of t)null!=r&&(i<r||void 0===i&&r>=r)&&(i=r);else{let r=-1;for(let n of t)null!=(n=e(n,++r,t))&&(i<n||void 0===i&&n>=n)&&(i=n)}return i}function n(t,e){let i;if(void 0===e)for(const r of t)null!=r&&(i>r||void 0===i&&r>=r)&&(i=r);else{let r=-1;for(let n of t)null!=(n=e(n,++r,t))&&(i>n||void 0===i&&n>=n)&&(i=n)}return i}function o(t){return t}i.d(e,{JLW:()=>cs,l78:()=>x,tlR:()=>y,qrM:()=>vs,Yu4:()=>Ts,IA3:()=>ws,Wi0:()=>Bs,PGM:()=>Fs,OEq:()=>Ms,y8u:()=>Os,olC:()=>Is,IrU:()=>qs,oDi:()=>Ps,Q7f:()=>Ws,cVp:()=>Hs,lUB:()=>ds,Lx9:()=>Vs,nVG:()=>el,uxU:()=>il,Xf2:()=>ol,GZz:()=>sl,UPb:()=>cl,dyv:()=>ll,bEH:()=>pr,n8j:()=>gs,T9B:()=>r,jkA:()=>n,rLf:()=>xs,WH:()=>kr,m4Y:()=>mn,UMr:()=>vr,w7C:()=>Na,zt:()=>Oa,Ltv:()=>ja,Ubm:()=>Ia,JWy:()=>Vi,UAC:()=>Nn,DCK:()=>uo,TUC:()=>Rn,Agd:()=>Mn,t6C:()=>Sn,wXd:()=>Fn,ABi:()=>qn,Ui6:()=>Qn,rGn:()=>Wn,ucG:()=>Bn,YPH:()=>Dn,Mol:()=>Pn,PGu:()=>$n,GuW:()=>zn});var a=1,s=2,l=3,c=4,h=1e-6;function u(t){return"translate("+t+",0)"}function d(t){return"translate(0,"+t+")"}function f(t){return e=>+t(e)}function p(t,e){return e=Math.max(0,t.bandwidth()-2*e)/2,t.round()&&(e=Math.round(e)),i=>+t(i)+e}function g(){return!this.__axis}function m(t,e){var i=[],r=null,n=null,m=6,y=6,x=3,C="undefined"!=typeof window&&window.devicePixelRatio>1?0:.5,b=t===a||t===c?-1:1,_=t===c||t===s?"x":"y",v=t===a||t===l?u:d;function k(u){var d=null==r?e.ticks?e.ticks.apply(e,i):e.domain():r,k=null==n?e.tickFormat?e.tickFormat.apply(e,i):o:n,T=Math.max(m,0)+x,A=e.range(),w=+A[0]+C,S=+A[A.length-1]+C,B=(e.bandwidth?p:f)(e.copy(),C),F=u.selection?u.selection():u,L=F.selectAll(".domain").data([null]),M=F.selectAll(".tick").data(d,e).order(),E=M.exit(),N=M.enter().append("g").attr("class","tick"),O=M.select("line"),j=M.select("text");L=L.merge(L.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),M=M.merge(N),O=O.merge(N.append("line").attr("stroke","currentColor").attr(_+"2",b*m)),j=j.merge(N.append("text").attr("fill","currentColor").attr(_,b*T).attr("dy",t===a?"0em":t===l?"0.71em":"0.32em")),u!==F&&(L=L.transition(u),M=M.transition(u),O=O.transition(u),j=j.transition(u),E=E.transition(u).attr("opacity",h).attr("transform",(function(t){return isFinite(t=B(t))?v(t+C):this.getAttribute("transform")})),N.attr("opacity",h).attr("transform",(function(t){var e=this.parentNode.__axis;return v((e&&isFinite(e=e(t))?e:B(t))+C)}))),E.remove(),L.attr("d",t===c||t===s?y?"M"+b*y+","+w+"H"+C+"V"+S+"H"+b*y:"M"+C+","+w+"V"+S:y?"M"+w+","+b*y+"V"+C+"H"+S+"V"+b*y:"M"+w+","+C+"H"+S),M.attr("opacity",1).attr("transform",(function(t){return v(B(t)+C)})),O.attr(_+"2",b*m),j.attr(_,b*T).text(k),F.filter(g).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===s?"start":t===c?"end":"middle"),F.each((function(){this.__axis=B}))}return k.scale=function(t){return arguments.length?(e=t,k):e},k.ticks=function(){return i=Array.from(arguments),k},k.tickArguments=function(t){return arguments.length?(i=null==t?[]:Array.from(t),k):i.slice()},k.tickValues=function(t){return arguments.length?(r=null==t?null:Array.from(t),k):r&&r.slice()},k.tickFormat=function(t){return arguments.length?(n=t,k):n},k.tickSize=function(t){return arguments.length?(m=y=+t,k):m},k.tickSizeInner=function(t){return arguments.length?(m=+t,k):m},k.tickSizeOuter=function(t){return arguments.length?(y=+t,k):y},k.tickPadding=function(t){return arguments.length?(x=+t,k):x},k.offset=function(t){return arguments.length?(C=+t,k):C},k}function y(t){return m(a,t)}function x(t){return m(l,t)}function C(){}function b(t){return null==t?C:function(){return this.querySelector(t)}}function _(t){return null==t?[]:Array.isArray(t)?t:Array.from(t)}function v(){return[]}function k(t){return null==t?v:function(){return this.querySelectorAll(t)}}function T(t){return function(){return this.matches(t)}}function A(t){return function(e){return e.matches(t)}}var w=Array.prototype.find;function S(){return this.firstElementChild}var B=Array.prototype.filter;function F(){return Array.from(this.children)}function L(t){return new Array(t.length)}function M(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}function E(t,e,i,r,n,o){for(var a,s=0,l=e.length,c=o.length;s<c;++s)(a=e[s])?(a.__data__=o[s],r[s]=a):i[s]=new M(t,o[s]);for(;s<l;++s)(a=e[s])&&(n[s]=a)}function N(t,e,i,r,n,o,a){var s,l,c,h=new Map,u=e.length,d=o.length,f=new Array(u);for(s=0;s<u;++s)(l=e[s])&&(f[s]=c=a.call(l,l.__data__,s,e)+"",h.has(c)?n[s]=l:h.set(c,l));for(s=0;s<d;++s)c=a.call(t,o[s],s,o)+"",(l=h.get(c))?(r[s]=l,l.__data__=o[s],h.delete(c)):i[s]=new M(t,o[s]);for(s=0;s<u;++s)(l=e[s])&&h.get(f[s])===l&&(n[s]=l)}function O(t){return t.__data__}function j(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function I(t,e){return t<e?-1:t>e?1:t>=e?0:NaN}M.prototype={constructor:M,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var D="http://www.w3.org/1999/xhtml";const q={svg:"http://www.w3.org/2000/svg",xhtml:D,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function $(t){var e=t+="",i=e.indexOf(":");return i>=0&&"xmlns"!==(e=t.slice(0,i))&&(t=t.slice(i+1)),q.hasOwnProperty(e)?{space:q[e],local:t}:t}function z(t){return function(){this.removeAttribute(t)}}function P(t){return function(){this.removeAttributeNS(t.space,t.local)}}function R(t,e){return function(){this.setAttribute(t,e)}}function W(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function U(t,e){return function(){var i=e.apply(this,arguments);null==i?this.removeAttribute(t):this.setAttribute(t,i)}}function H(t,e){return function(){var i=e.apply(this,arguments);null==i?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,i)}}function Y(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function V(t){return function(){this.style.removeProperty(t)}}function G(t,e,i){return function(){this.style.setProperty(t,e,i)}}function X(t,e,i){return function(){var r=e.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,i)}}function Z(t,e){return t.style.getPropertyValue(e)||Y(t).getComputedStyle(t,null).getPropertyValue(e)}function J(t){return function(){delete this[t]}}function Q(t,e){return function(){this[t]=e}}function K(t,e){return function(){var i=e.apply(this,arguments);null==i?delete this[t]:this[t]=i}}function tt(t){return t.trim().split(/^|\s+/)}function et(t){return t.classList||new it(t)}function it(t){this._node=t,this._names=tt(t.getAttribute("class")||"")}function rt(t,e){for(var i=et(t),r=-1,n=e.length;++r<n;)i.add(e[r])}function nt(t,e){for(var i=et(t),r=-1,n=e.length;++r<n;)i.remove(e[r])}function ot(t){return function(){rt(this,t)}}function at(t){return function(){nt(this,t)}}function st(t,e){return function(){(e.apply(this,arguments)?rt:nt)(this,t)}}function lt(){this.textContent=""}function ct(t){return function(){this.textContent=t}}function ht(t){return function(){var e=t.apply(this,arguments);this.textContent=null==e?"":e}}function ut(){this.innerHTML=""}function dt(t){return function(){this.innerHTML=t}}function ft(t){return function(){var e=t.apply(this,arguments);this.innerHTML=null==e?"":e}}function pt(){this.nextSibling&&this.parentNode.appendChild(this)}function gt(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function mt(t){return function(){var e=this.ownerDocument,i=this.namespaceURI;return i===D&&e.documentElement.namespaceURI===D?e.createElement(t):e.createElementNS(i,t)}}function yt(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function xt(t){var e=$(t);return(e.local?yt:mt)(e)}function Ct(){return null}function bt(){var t=this.parentNode;t&&t.removeChild(this)}function _t(){var t=this.cloneNode(!1),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function vt(){var t=this.cloneNode(!0),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function kt(t){return function(){var e=this.__on;if(e){for(var i,r=0,n=-1,o=e.length;r<o;++r)i=e[r],t.type&&i.type!==t.type||i.name!==t.name?e[++n]=i:this.removeEventListener(i.type,i.listener,i.options);++n?e.length=n:delete this.__on}}}function Tt(t,e,i){return function(){var r,n=this.__on,o=function(t){return function(e){t.call(this,e,this.__data__)}}(e);if(n)for(var a=0,s=n.length;a<s;++a)if((r=n[a]).type===t.type&&r.name===t.name)return this.removeEventListener(r.type,r.listener,r.options),this.addEventListener(r.type,r.listener=o,r.options=i),void(r.value=e);this.addEventListener(t.type,o,i),r={type:t.type,name:t.name,value:e,listener:o,options:i},n?n.push(r):this.__on=[r]}}function At(t,e,i){var r=Y(t),n=r.CustomEvent;"function"==typeof n?n=new n(e,i):(n=r.document.createEvent("Event"),i?(n.initEvent(e,i.bubbles,i.cancelable),n.detail=i.detail):n.initEvent(e,!1,!1)),t.dispatchEvent(n)}function wt(t,e){return function(){return At(this,t,e)}}function St(t,e){return function(){return At(this,t,e.apply(this,arguments))}}it.prototype={add:function(t){this._names.indexOf(t)<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var e=this._names.indexOf(t);e>=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var Bt=[null];function Ft(t,e){this._groups=t,this._parents=e}function Lt(){return new Ft([[document.documentElement]],Bt)}Ft.prototype=Lt.prototype={constructor:Ft,select:function(t){"function"!=typeof t&&(t=b(t));for(var e=this._groups,i=e.length,r=new Array(i),n=0;n<i;++n)for(var o,a,s=e[n],l=s.length,c=r[n]=new Array(l),h=0;h<l;++h)(o=s[h])&&(a=t.call(o,o.__data__,h,s))&&("__data__"in o&&(a.__data__=o.__data__),c[h]=a);return new Ft(r,this._parents)},selectAll:function(t){t="function"==typeof t?function(t){return function(){return _(t.apply(this,arguments))}}(t):k(t);for(var e=this._groups,i=e.length,r=[],n=[],o=0;o<i;++o)for(var a,s=e[o],l=s.length,c=0;c<l;++c)(a=s[c])&&(r.push(t.call(a,a.__data__,c,s)),n.push(a));return new Ft(r,n)},selectChild:function(t){return this.select(null==t?S:function(t){return function(){return w.call(this.children,t)}}("function"==typeof t?t:A(t)))},selectChildren:function(t){return this.selectAll(null==t?F:function(t){return function(){return B.call(this.children,t)}}("function"==typeof t?t:A(t)))},filter:function(t){"function"!=typeof t&&(t=T(t));for(var e=this._groups,i=e.length,r=new Array(i),n=0;n<i;++n)for(var o,a=e[n],s=a.length,l=r[n]=[],c=0;c<s;++c)(o=a[c])&&t.call(o,o.__data__,c,a)&&l.push(o);return new Ft(r,this._parents)},data:function(t,e){if(!arguments.length)return Array.from(this,O);var i,r=e?N:E,n=this._parents,o=this._groups;"function"!=typeof t&&(i=t,t=function(){return i});for(var a=o.length,s=new Array(a),l=new Array(a),c=new Array(a),h=0;h<a;++h){var u=n[h],d=o[h],f=d.length,p=j(t.call(u,u&&u.__data__,h,n)),g=p.length,m=l[h]=new Array(g),y=s[h]=new Array(g);r(u,d,m,y,c[h]=new Array(f),p,e);for(var x,C,b=0,_=0;b<g;++b)if(x=m[b]){for(b>=_&&(_=b+1);!(C=y[_])&&++_<g;);x._next=C||null}}return(s=new Ft(s,n))._enter=l,s._exit=c,s},enter:function(){return new Ft(this._enter||this._groups.map(L),this._parents)},exit:function(){return new Ft(this._exit||this._groups.map(L),this._parents)},join:function(t,e,i){var r=this.enter(),n=this,o=this.exit();return"function"==typeof t?(r=t(r))&&(r=r.selection()):r=r.append(t+""),null!=e&&(n=e(n))&&(n=n.selection()),null==i?o.remove():i(o),r&&n?r.merge(n).order():n},merge:function(t){for(var e=t.selection?t.selection():t,i=this._groups,r=e._groups,n=i.length,o=r.length,a=Math.min(n,o),s=new Array(n),l=0;l<a;++l)for(var c,h=i[l],u=r[l],d=h.length,f=s[l]=new Array(d),p=0;p<d;++p)(c=h[p]||u[p])&&(f[p]=c);for(;l<n;++l)s[l]=i[l];return new Ft(s,this._parents)},selection:function(){return this},order:function(){for(var t=this._groups,e=-1,i=t.length;++e<i;)for(var r,n=t[e],o=n.length-1,a=n[o];--o>=0;)(r=n[o])&&(a&&4^r.compareDocumentPosition(a)&&a.parentNode.insertBefore(r,a),a=r);return this},sort:function(t){function e(e,i){return e&&i?t(e.__data__,i.__data__):!e-!i}t||(t=I);for(var i=this._groups,r=i.length,n=new Array(r),o=0;o<r;++o){for(var a,s=i[o],l=s.length,c=n[o]=new Array(l),h=0;h<l;++h)(a=s[h])&&(c[h]=a);c.sort(e)}return new Ft(n,this._parents).order()},call:function(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this},nodes:function(){return Array.from(this)},node:function(){for(var t=this._groups,e=0,i=t.length;e<i;++e)for(var r=t[e],n=0,o=r.length;n<o;++n){var a=r[n];if(a)return a}return null},size:function(){let t=0;for(const e of this)++t;return t},empty:function(){return!this.node()},each:function(t){for(var e=this._groups,i=0,r=e.length;i<r;++i)for(var n,o=e[i],a=0,s=o.length;a<s;++a)(n=o[a])&&t.call(n,n.__data__,a,o);return this},attr:function(t,e){var i=$(t);if(arguments.length<2){var r=this.node();return i.local?r.getAttributeNS(i.space,i.local):r.getAttribute(i)}return this.each((null==e?i.local?P:z:"function"==typeof e?i.local?H:U:i.local?W:R)(i,e))},style:function(t,e,i){return arguments.length>1?this.each((null==e?V:"function"==typeof e?X:G)(t,e,null==i?"":i)):Z(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?J:"function"==typeof e?K:Q)(t,e)):this.node()[t]},classed:function(t,e){var i=tt(t+"");if(arguments.length<2){for(var r=et(this.node()),n=-1,o=i.length;++n<o;)if(!r.contains(i[n]))return!1;return!0}return this.each(("function"==typeof e?st:e?ot:at)(i,e))},text:function(t){return arguments.length?this.each(null==t?lt:("function"==typeof t?ht:ct)(t)):this.node().textContent},html:function(t){return arguments.length?this.each(null==t?ut:("function"==typeof t?ft:dt)(t)):this.node().innerHTML},raise:function(){return this.each(pt)},lower:function(){return this.each(gt)},append:function(t){var e="function"==typeof t?t:xt(t);return this.select((function(){return this.appendChild(e.apply(this,arguments))}))},insert:function(t,e){var i="function"==typeof t?t:xt(t),r=null==e?Ct:"function"==typeof e?e:b(e);return this.select((function(){return this.insertBefore(i.apply(this,arguments),r.apply(this,arguments)||null)}))},remove:function(){return this.each(bt)},clone:function(t){return this.select(t?vt:_t)},datum:function(t){return arguments.length?this.property("__data__",t):this.node().__data__},on:function(t,e,i){var r,n,o=function(t){return t.trim().split(/^|\s+/).map((function(t){var e="",i=t.indexOf(".");return i>=0&&(e=t.slice(i+1),t=t.slice(0,i)),{type:t,name:e}}))}(t+""),a=o.length;if(!(arguments.length<2)){for(s=e?Tt:kt,r=0;r<a;++r)this.each(s(o[r],e,i));return this}var s=this.node().__on;if(s)for(var l,c=0,h=s.length;c<h;++c)for(r=0,l=s[c];r<a;++r)if((n=o[r]).type===l.type&&n.name===l.name)return l.value},dispatch:function(t,e){return this.each(("function"==typeof e?St:wt)(t,e))},[Symbol.iterator]:function*(){for(var t=this._groups,e=0,i=t.length;e<i;++e)for(var r,n=t[e],o=0,a=n.length;o<a;++o)(r=n[o])&&(yield r)}};const Mt=Lt;var Et={value:()=>{}};function Nt(){for(var t,e=0,i=arguments.length,r={};e<i;++e){if(!(t=arguments[e]+"")||t in r||/[\s.]/.test(t))throw new Error("illegal type: "+t);r[t]=[]}return new Ot(r)}function Ot(t){this._=t}function jt(t,e){for(var i,r=0,n=t.length;r<n;++r)if((i=t[r]).name===e)return i.value}function It(t,e,i){for(var r=0,n=t.length;r<n;++r)if(t[r].name===e){t[r]=Et,t=t.slice(0,r).concat(t.slice(r+1));break}return null!=i&&t.push({name:e,value:i}),t}Ot.prototype=Nt.prototype={constructor:Ot,on:function(t,e){var i,r,n=this._,o=(r=n,(t+"").trim().split(/^|\s+/).map((function(t){var e="",i=t.indexOf(".");if(i>=0&&(e=t.slice(i+1),t=t.slice(0,i)),t&&!r.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:e}}))),a=-1,s=o.length;if(!(arguments.length<2)){if(null!=e&&"function"!=typeof e)throw new Error("invalid callback: "+e);for(;++a<s;)if(i=(t=o[a]).type)n[i]=It(n[i],t.name,e);else if(null==e)for(i in n)n[i]=It(n[i],t.name,null);return this}for(;++a<s;)if((i=(t=o[a]).type)&&(i=jt(n[i],t.name)))return i},copy:function(){var t={},e=this._;for(var i in e)t[i]=e[i].slice();return new Ot(t)},call:function(t,e){if((i=arguments.length-2)>0)for(var i,r,n=new Array(i),o=0;o<i;++o)n[o]=arguments[o+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(o=0,i=(r=this._[t]).length;o<i;++o)r[o].value.apply(e,n)},apply:function(t,e,i){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var r=this._[t],n=0,o=r.length;n<o;++n)r[n].value.apply(e,i)}};const Dt=Nt;var qt,$t,zt=0,Pt=0,Rt=0,Wt=1e3,Ut=0,Ht=0,Yt=0,Vt="object"==typeof performance&&performance.now?performance:Date,Gt="object"==typeof window&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function Xt(){return Ht||(Gt(Zt),Ht=Vt.now()+Yt)}function Zt(){Ht=0}function Jt(){this._call=this._time=this._next=null}function Qt(t,e,i){var r=new Jt;return r.restart(t,e,i),r}function Kt(){Ht=(Ut=Vt.now())+Yt,zt=Pt=0;try{!function(){Xt(),++zt;for(var t,e=qt;e;)(t=Ht-e._time)>=0&&e._call.call(void 0,t),e=e._next;--zt}()}finally{zt=0,function(){var t,e,i=qt,r=1/0;for(;i;)i._call?(r>i._time&&(r=i._time),t=i,i=i._next):(e=i._next,i._next=null,i=t?t._next=e:qt=e);$t=t,ee(r)}(),Ht=0}}function te(){var t=Vt.now(),e=t-Ut;e>Wt&&(Yt-=e,Ut=t)}function ee(t){zt||(Pt&&(Pt=clearTimeout(Pt)),t-Ht>24?(t<1/0&&(Pt=setTimeout(Kt,t-Vt.now()-Yt)),Rt&&(Rt=clearInterval(Rt))):(Rt||(Ut=Vt.now(),Rt=setInterval(te,Wt)),zt=1,Gt(Kt)))}function ie(t,e,i){var r=new Jt;return e=null==e?0:+e,r.restart((i=>{r.stop(),t(i+e)}),e,i),r}Jt.prototype=Qt.prototype={constructor:Jt,restart:function(t,e,i){if("function"!=typeof t)throw new TypeError("callback is not a function");i=(null==i?Xt():+i)+(null==e?0:+e),this._next||$t===this||($t?$t._next=this:qt=this,$t=this),this._call=t,this._time=i,ee()},stop:function(){this._call&&(this._call=null,this._time=1/0,ee())}};var re=Dt("start","end","cancel","interrupt"),ne=[],oe=0,ae=1,se=2,le=3,ce=4,he=5,ue=6;function de(t,e,i,r,n,o){var a=t.__transition;if(a){if(i in a)return}else t.__transition={};!function(t,e,i){var r,n=t.__transition;function o(t){i.state=ae,i.timer.restart(a,i.delay,i.time),i.delay<=t&&a(t-i.delay)}function a(o){var c,h,u,d;if(i.state!==ae)return l();for(c in n)if((d=n[c]).name===i.name){if(d.state===le)return ie(a);d.state===ce?(d.state=ue,d.timer.stop(),d.on.call("interrupt",t,t.__data__,d.index,d.group),delete n[c]):+c<e&&(d.state=ue,d.timer.stop(),d.on.call("cancel",t,t.__data__,d.index,d.group),delete n[c])}if(ie((function(){i.state===le&&(i.state=ce,i.timer.restart(s,i.delay,i.time),s(o))})),i.state=se,i.on.call("start",t,t.__data__,i.index,i.group),i.state===se){for(i.state=le,r=new Array(u=i.tween.length),c=0,h=-1;c<u;++c)(d=i.tween[c].value.call(t,t.__data__,i.index,i.group))&&(r[++h]=d);r.length=h+1}}function s(e){for(var n=e<i.duration?i.ease.call(null,e/i.duration):(i.timer.restart(l),i.state=he,1),o=-1,a=r.length;++o<a;)r[o].call(t,n);i.state===he&&(i.on.call("end",t,t.__data__,i.index,i.group),l())}function l(){for(var r in i.state=ue,i.timer.stop(),delete n[e],n)return;delete t.__transition}n[e]=i,i.timer=Qt(o,0,i.time)}(t,i,{name:e,index:r,group:n,on:re,tween:ne,time:o.time,delay:o.delay,duration:o.duration,ease:o.ease,timer:null,state:oe})}function fe(t,e){var i=ge(t,e);if(i.state>oe)throw new Error("too late; already scheduled");return i}function pe(t,e){var i=ge(t,e);if(i.state>le)throw new Error("too late; already running");return i}function ge(t,e){var i=t.__transition;if(!i||!(i=i[e]))throw new Error("transition not found");return i}function me(t,e){return t=+t,e=+e,function(i){return t*(1-i)+e*i}}var ye,xe=180/Math.PI,Ce={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function be(t,e,i,r,n,o){var a,s,l;return(a=Math.sqrt(t*t+e*e))&&(t/=a,e/=a),(l=t*i+e*r)&&(i-=t*l,r-=e*l),(s=Math.sqrt(i*i+r*r))&&(i/=s,r/=s,l/=s),t*r<e*i&&(t=-t,e=-e,l=-l,a=-a),{translateX:n,translateY:o,rotate:Math.atan2(e,t)*xe,skewX:Math.atan(l)*xe,scaleX:a,scaleY:s}}function _e(t,e,i,r){function n(t){return t.length?t.pop()+" ":""}return function(o,a){var s=[],l=[];return o=t(o),a=t(a),function(t,r,n,o,a,s){if(t!==n||r!==o){var l=a.push("translate(",null,e,null,i);s.push({i:l-4,x:me(t,n)},{i:l-2,x:me(r,o)})}else(n||o)&&a.push("translate("+n+e+o+i)}(o.translateX,o.translateY,a.translateX,a.translateY,s,l),function(t,e,i,o){t!==e?(t-e>180?e+=360:e-t>180&&(t+=360),o.push({i:i.push(n(i)+"rotate(",null,r)-2,x:me(t,e)})):e&&i.push(n(i)+"rotate("+e+r)}(o.rotate,a.rotate,s,l),function(t,e,i,o){t!==e?o.push({i:i.push(n(i)+"skewX(",null,r)-2,x:me(t,e)}):e&&i.push(n(i)+"skewX("+e+r)}(o.skewX,a.skewX,s,l),function(t,e,i,r,o,a){if(t!==i||e!==r){var s=o.push(n(o)+"scale(",null,",",null,")");a.push({i:s-4,x:me(t,i)},{i:s-2,x:me(e,r)})}else 1===i&&1===r||o.push(n(o)+"scale("+i+","+r+")")}(o.scaleX,o.scaleY,a.scaleX,a.scaleY,s,l),o=a=null,function(t){for(var e,i=-1,r=l.length;++i<r;)s[(e=l[i]).i]=e.x(t);return s.join("")}}}var ve=_e((function(t){const e=new("function"==typeof DOMMatrix?DOMMatrix:WebKitCSSMatrix)(t+"");return e.isIdentity?Ce:be(e.a,e.b,e.c,e.d,e.e,e.f)}),"px, ","px)","deg)"),ke=_e((function(t){return null==t?Ce:(ye||(ye=document.createElementNS("http://www.w3.org/2000/svg","g")),ye.setAttribute("transform",t),(t=ye.transform.baseVal.consolidate())?be((t=t.matrix).a,t.b,t.c,t.d,t.e,t.f):Ce)}),", ",")",")");function Te(t,e){var i,r;return function(){var n=pe(this,t),o=n.tween;if(o!==i)for(var a=0,s=(r=i=o).length;a<s;++a)if(r[a].name===e){(r=r.slice()).splice(a,1);break}n.tween=r}}function Ae(t,e,i){var r,n;if("function"!=typeof i)throw new Error;return function(){var o=pe(this,t),a=o.tween;if(a!==r){n=(r=a).slice();for(var s={name:e,value:i},l=0,c=n.length;l<c;++l)if(n[l].name===e){n[l]=s;break}l===c&&n.push(s)}o.tween=n}}function we(t,e,i){var r=t._id;return t.each((function(){var t=pe(this,r);(t.value||(t.value={}))[e]=i.apply(this,arguments)})),function(t){return ge(t,r).value[e]}}function Se(t,e,i){t.prototype=e.prototype=i,i.constructor=t}function Be(t,e){var i=Object.create(t.prototype);for(var r in e)i[r]=e[r];return i}function Fe(){}var Le=.7,Me=1/Le,Ee="\\s*([+-]?\\d+)\\s*",Ne="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",Oe="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",je=/^#([0-9a-f]{3,8})$/,Ie=new RegExp(`^rgb\\(${Ee},${Ee},${Ee}\\)$`),De=new RegExp(`^rgb\\(${Oe},${Oe},${Oe}\\)$`),qe=new RegExp(`^rgba\\(${Ee},${Ee},${Ee},${Ne}\\)$`),$e=new RegExp(`^rgba\\(${Oe},${Oe},${Oe},${Ne}\\)$`),ze=new RegExp(`^hsl\\(${Ne},${Oe},${Oe}\\)$`),Pe=new RegExp(`^hsla\\(${Ne},${Oe},${Oe},${Ne}\\)$`),Re={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};function We(){return this.rgb().formatHex()}function Ue(){return this.rgb().formatRgb()}function He(t){var e,i;return t=(t+"").trim().toLowerCase(),(e=je.exec(t))?(i=e[1].length,e=parseInt(e[1],16),6===i?Ye(e):3===i?new Ze(e>>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===i?Ve(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===i?Ve(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=Ie.exec(t))?new Ze(e[1],e[2],e[3],1):(e=De.exec(t))?new Ze(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=qe.exec(t))?Ve(e[1],e[2],e[3],e[4]):(e=$e.exec(t))?Ve(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=ze.exec(t))?ii(e[1],e[2]/100,e[3]/100,1):(e=Pe.exec(t))?ii(e[1],e[2]/100,e[3]/100,e[4]):Re.hasOwnProperty(t)?Ye(Re[t]):"transparent"===t?new Ze(NaN,NaN,NaN,0):null}function Ye(t){return new Ze(t>>16&255,t>>8&255,255&t,1)}function Ve(t,e,i,r){return r<=0&&(t=e=i=NaN),new Ze(t,e,i,r)}function Ge(t){return t instanceof Fe||(t=He(t)),t?new Ze((t=t.rgb()).r,t.g,t.b,t.opacity):new Ze}function Xe(t,e,i,r){return 1===arguments.length?Ge(t):new Ze(t,e,i,null==r?1:r)}function Ze(t,e,i,r){this.r=+t,this.g=+e,this.b=+i,this.opacity=+r}function Je(){return`#${ei(this.r)}${ei(this.g)}${ei(this.b)}`}function Qe(){const t=Ke(this.opacity);return`${1===t?"rgb(":"rgba("}${ti(this.r)}, ${ti(this.g)}, ${ti(this.b)}${1===t?")":`, ${t})`}`}function Ke(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function ti(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function ei(t){return((t=ti(t))<16?"0":"")+t.toString(16)}function ii(t,e,i,r){return r<=0?t=e=i=NaN:i<=0||i>=1?t=e=NaN:e<=0&&(t=NaN),new ni(t,e,i,r)}function ri(t){if(t instanceof ni)return new ni(t.h,t.s,t.l,t.opacity);if(t instanceof Fe||(t=He(t)),!t)return new ni;if(t instanceof ni)return t;var e=(t=t.rgb()).r/255,i=t.g/255,r=t.b/255,n=Math.min(e,i,r),o=Math.max(e,i,r),a=NaN,s=o-n,l=(o+n)/2;return s?(a=e===o?(i-r)/s+6*(i<r):i===o?(r-e)/s+2:(e-i)/s+4,s/=l<.5?o+n:2-o-n,a*=60):s=l>0&&l<1?0:a,new ni(a,s,l,t.opacity)}function ni(t,e,i,r){this.h=+t,this.s=+e,this.l=+i,this.opacity=+r}function oi(t){return(t=(t||0)%360)<0?t+360:t}function ai(t){return Math.max(0,Math.min(1,t||0))}function si(t,e,i){return 255*(t<60?e+(i-e)*t/60:t<180?i:t<240?e+(i-e)*(240-t)/60:e)}function li(t,e,i,r,n){var o=t*t,a=o*t;return((1-3*t+3*o-a)*e+(4-6*o+3*a)*i+(1+3*t+3*o-3*a)*r+a*n)/6}Se(Fe,He,{copy(t){return Object.assign(new this.constructor,this,t)},displayable(){return this.rgb().displayable()},hex:We,formatHex:We,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return ri(this).formatHsl()},formatRgb:Ue,toString:Ue}),Se(Ze,Xe,Be(Fe,{brighter(t){return t=null==t?Me:Math.pow(Me,t),new Ze(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=null==t?Le:Math.pow(Le,t),new Ze(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Ze(ti(this.r),ti(this.g),ti(this.b),Ke(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Je,formatHex:Je,formatHex8:function(){return`#${ei(this.r)}${ei(this.g)}${ei(this.b)}${ei(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Qe,toString:Qe})),Se(ni,(function(t,e,i,r){return 1===arguments.length?ri(t):new ni(t,e,i,null==r?1:r)}),Be(Fe,{brighter(t){return t=null==t?Me:Math.pow(Me,t),new ni(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=null==t?Le:Math.pow(Le,t),new ni(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,i=this.l,r=i+(i<.5?i:1-i)*e,n=2*i-r;return new Ze(si(t>=240?t-240:t+120,n,r),si(t,n,r),si(t<120?t+240:t-120,n,r),this.opacity)},clamp(){return new ni(oi(this.h),ai(this.s),ai(this.l),Ke(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=Ke(this.opacity);return`${1===t?"hsl(":"hsla("}${oi(this.h)}, ${100*ai(this.s)}%, ${100*ai(this.l)}%${1===t?")":`, ${t})`}`}}));const ci=t=>()=>t;function hi(t,e){return function(i){return t+i*e}}function ui(t){return 1==(t=+t)?di:function(e,i){return i-e?function(t,e,i){return t=Math.pow(t,i),e=Math.pow(e,i)-t,i=1/i,function(r){return Math.pow(t+r*e,i)}}(e,i,t):ci(isNaN(e)?i:e)}}function di(t,e){var i=e-t;return i?hi(t,i):ci(isNaN(t)?e:t)}const fi=function t(e){var i=ui(e);function r(t,e){var r=i((t=Xe(t)).r,(e=Xe(e)).r),n=i(t.g,e.g),o=i(t.b,e.b),a=di(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=n(e),t.b=o(e),t.opacity=a(e),t+""}}return r.gamma=t,r}(1);function pi(t){return function(e){var i,r,n=e.length,o=new Array(n),a=new Array(n),s=new Array(n);for(i=0;i<n;++i)r=Xe(e[i]),o[i]=r.r||0,a[i]=r.g||0,s[i]=r.b||0;return o=t(o),a=t(a),s=t(s),r.opacity=1,function(t){return r.r=o(t),r.g=a(t),r.b=s(t),r+""}}}pi((function(t){var e=t.length-1;return function(i){var r=i<=0?i=0:i>=1?(i=1,e-1):Math.floor(i*e),n=t[r],o=t[r+1],a=r>0?t[r-1]:2*n-o,s=r<e-1?t[r+2]:2*o-n;return li((i-r/e)*e,a,n,o,s)}})),pi((function(t){var e=t.length;return function(i){var r=Math.floor(((i%=1)<0?++i:i)*e),n=t[(r+e-1)%e],o=t[r%e],a=t[(r+1)%e],s=t[(r+2)%e];return li((i-r/e)*e,n,o,a,s)}}));var gi=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,mi=new RegExp(gi.source,"g");function yi(t,e){var i,r,n,o=gi.lastIndex=mi.lastIndex=0,a=-1,s=[],l=[];for(t+="",e+="";(i=gi.exec(t))&&(r=mi.exec(e));)(n=r.index)>o&&(n=e.slice(o,n),s[a]?s[a]+=n:s[++a]=n),(i=i[0])===(r=r[0])?s[a]?s[a]+=r:s[++a]=r:(s[++a]=null,l.push({i:a,x:me(i,r)})),o=mi.lastIndex;return o<e.length&&(n=e.slice(o),s[a]?s[a]+=n:s[++a]=n),s.length<2?l[0]?function(t){return function(e){return t(e)+""}}(l[0].x):function(t){return function(){return t}}(e):(e=l.length,function(t){for(var i,r=0;r<e;++r)s[(i=l[r]).i]=i.x(t);return s.join("")})}function xi(t,e){var i;return("number"==typeof e?me:e instanceof He?fi:(i=He(e))?(e=i,fi):yi)(t,e)}function Ci(t){return function(){this.removeAttribute(t)}}function bi(t){return function(){this.removeAttributeNS(t.space,t.local)}}function _i(t,e,i){var r,n,o=i+"";return function(){var a=this.getAttribute(t);return a===o?null:a===r?n:n=e(r=a,i)}}function vi(t,e,i){var r,n,o=i+"";return function(){var a=this.getAttributeNS(t.space,t.local);return a===o?null:a===r?n:n=e(r=a,i)}}function ki(t,e,i){var r,n,o;return function(){var a,s,l=i(this);if(null!=l)return(a=this.getAttribute(t))===(s=l+"")?null:a===r&&s===n?o:(n=s,o=e(r=a,l));this.removeAttribute(t)}}function Ti(t,e,i){var r,n,o;return function(){var a,s,l=i(this);if(null!=l)return(a=this.getAttributeNS(t.space,t.local))===(s=l+"")?null:a===r&&s===n?o:(n=s,o=e(r=a,l));this.removeAttributeNS(t.space,t.local)}}function Ai(t,e){var i,r;function n(){var n=e.apply(this,arguments);return n!==r&&(i=(r=n)&&function(t,e){return function(i){this.setAttributeNS(t.space,t.local,e.call(this,i))}}(t,n)),i}return n._value=e,n}function wi(t,e){var i,r;function n(){var n=e.apply(this,arguments);return n!==r&&(i=(r=n)&&function(t,e){return function(i){this.setAttribute(t,e.call(this,i))}}(t,n)),i}return n._value=e,n}function Si(t,e){return function(){fe(this,t).delay=+e.apply(this,arguments)}}function Bi(t,e){return e=+e,function(){fe(this,t).delay=e}}function Fi(t,e){return function(){pe(this,t).duration=+e.apply(this,arguments)}}function Li(t,e){return e=+e,function(){pe(this,t).duration=e}}var Mi=Mt.prototype.constructor;function Ei(t){return function(){this.style.removeProperty(t)}}var Ni=0;function Oi(t,e,i,r){this._groups=t,this._parents=e,this._name=i,this._id=r}function ji(){return++Ni}var Ii=Mt.prototype;Oi.prototype=function(t){return Mt().transition(t)}.prototype={constructor:Oi,select:function(t){var e=this._name,i=this._id;"function"!=typeof t&&(t=b(t));for(var r=this._groups,n=r.length,o=new Array(n),a=0;a<n;++a)for(var s,l,c=r[a],h=c.length,u=o[a]=new Array(h),d=0;d<h;++d)(s=c[d])&&(l=t.call(s,s.__data__,d,c))&&("__data__"in s&&(l.__data__=s.__data__),u[d]=l,de(u[d],e,i,d,u,ge(s,i)));return new Oi(o,this._parents,e,i)},selectAll:function(t){var e=this._name,i=this._id;"function"!=typeof t&&(t=k(t));for(var r=this._groups,n=r.length,o=[],a=[],s=0;s<n;++s)for(var l,c=r[s],h=c.length,u=0;u<h;++u)if(l=c[u]){for(var d,f=t.call(l,l.__data__,u,c),p=ge(l,i),g=0,m=f.length;g<m;++g)(d=f[g])&&de(d,e,i,g,f,p);o.push(f),a.push(l)}return new Oi(o,a,e,i)},selectChild:Ii.selectChild,selectChildren:Ii.selectChildren,filter:function(t){"function"!=typeof t&&(t=T(t));for(var e=this._groups,i=e.length,r=new Array(i),n=0;n<i;++n)for(var o,a=e[n],s=a.length,l=r[n]=[],c=0;c<s;++c)(o=a[c])&&t.call(o,o.__data__,c,a)&&l.push(o);return new Oi(r,this._parents,this._name,this._id)},merge:function(t){if(t._id!==this._id)throw new Error;for(var e=this._groups,i=t._groups,r=e.length,n=i.length,o=Math.min(r,n),a=new Array(r),s=0;s<o;++s)for(var l,c=e[s],h=i[s],u=c.length,d=a[s]=new Array(u),f=0;f<u;++f)(l=c[f]||h[f])&&(d[f]=l);for(;s<r;++s)a[s]=e[s];return new Oi(a,this._parents,this._name,this._id)},selection:function(){return new Mi(this._groups,this._parents)},transition:function(){for(var t=this._name,e=this._id,i=ji(),r=this._groups,n=r.length,o=0;o<n;++o)for(var a,s=r[o],l=s.length,c=0;c<l;++c)if(a=s[c]){var h=ge(a,e);de(a,t,i,c,s,{time:h.time+h.delay+h.duration,delay:0,duration:h.duration,ease:h.ease})}return new Oi(r,this._parents,t,i)},call:Ii.call,nodes:Ii.nodes,node:Ii.node,size:Ii.size,empty:Ii.empty,each:Ii.each,on:function(t,e){var i=this._id;return arguments.length<2?ge(this.node(),i).on.on(t):this.each(function(t,e,i){var r,n,o=function(t){return(t+"").trim().split(/^|\s+/).every((function(t){var e=t.indexOf(".");return e>=0&&(t=t.slice(0,e)),!t||"start"===t}))}(e)?fe:pe;return function(){var a=o(this,t),s=a.on;s!==r&&(n=(r=s).copy()).on(e,i),a.on=n}}(i,t,e))},attr:function(t,e){var i=$(t),r="transform"===i?ke:xi;return this.attrTween(t,"function"==typeof e?(i.local?Ti:ki)(i,r,we(this,"attr."+t,e)):null==e?(i.local?bi:Ci)(i):(i.local?vi:_i)(i,r,e))},attrTween:function(t,e){var i="attr."+t;if(arguments.length<2)return(i=this.tween(i))&&i._value;if(null==e)return this.tween(i,null);if("function"!=typeof e)throw new Error;var r=$(t);return this.tween(i,(r.local?Ai:wi)(r,e))},style:function(t,e,i){var r="transform"==(t+="")?ve:xi;return null==e?this.styleTween(t,function(t,e){var i,r,n;return function(){var o=Z(this,t),a=(this.style.removeProperty(t),Z(this,t));return o===a?null:o===i&&a===r?n:n=e(i=o,r=a)}}(t,r)).on("end.style."+t,Ei(t)):"function"==typeof e?this.styleTween(t,function(t,e,i){var r,n,o;return function(){var a=Z(this,t),s=i(this),l=s+"";return null==s&&(this.style.removeProperty(t),l=s=Z(this,t)),a===l?null:a===r&&l===n?o:(n=l,o=e(r=a,s))}}(t,r,we(this,"style."+t,e))).each(function(t,e){var i,r,n,o,a="style."+e,s="end."+a;return function(){var l=pe(this,t),c=l.on,h=null==l.value[a]?o||(o=Ei(e)):void 0;c===i&&n===h||(r=(i=c).copy()).on(s,n=h),l.on=r}}(this._id,t)):this.styleTween(t,function(t,e,i){var r,n,o=i+"";return function(){var a=Z(this,t);return a===o?null:a===r?n:n=e(r=a,i)}}(t,r,e),i).on("end.style."+t,null)},styleTween:function(t,e,i){var r="style."+(t+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==e)return this.tween(r,null);if("function"!=typeof e)throw new Error;return this.tween(r,function(t,e,i){var r,n;function o(){var o=e.apply(this,arguments);return o!==n&&(r=(n=o)&&function(t,e,i){return function(r){this.style.setProperty(t,e.call(this,r),i)}}(t,o,i)),r}return o._value=e,o}(t,e,null==i?"":i))},text:function(t){return this.tween("text","function"==typeof t?function(t){return function(){var e=t(this);this.textContent=null==e?"":e}}(we(this,"text",t)):function(t){return function(){this.textContent=t}}(null==t?"":t+""))},textTween:function(t){var e="text";if(arguments.length<1)return(e=this.tween(e))&&e._value;if(null==t)return this.tween(e,null);if("function"!=typeof t)throw new Error;return this.tween(e,function(t){var e,i;function r(){var r=t.apply(this,arguments);return r!==i&&(e=(i=r)&&function(t){return function(e){this.textContent=t.call(this,e)}}(r)),e}return r._value=t,r}(t))},remove:function(){return this.on("end.remove",function(t){return function(){var e=this.parentNode;for(var i in this.__transition)if(+i!==t)return;e&&e.removeChild(this)}}(this._id))},tween:function(t,e){var i=this._id;if(t+="",arguments.length<2){for(var r,n=ge(this.node(),i).tween,o=0,a=n.length;o<a;++o)if((r=n[o]).name===t)return r.value;return null}return this.each((null==e?Te:Ae)(i,t,e))},delay:function(t){var e=this._id;return arguments.length?this.each(("function"==typeof t?Si:Bi)(e,t)):ge(this.node(),e).delay},duration:function(t){var e=this._id;return arguments.length?this.each(("function"==typeof t?Fi:Li)(e,t)):ge(this.node(),e).duration},ease:function(t){var e=this._id;return arguments.length?this.each(function(t,e){if("function"!=typeof e)throw new Error;return function(){pe(this,t).ease=e}}(e,t)):ge(this.node(),e).ease},easeVarying:function(t){if("function"!=typeof t)throw new Error;return this.each(function(t,e){return function(){var i=e.apply(this,arguments);if("function"!=typeof i)throw new Error;pe(this,t).ease=i}}(this._id,t))},end:function(){var t,e,i=this,r=i._id,n=i.size();return new Promise((function(o,a){var s={value:a},l={value:function(){0==--n&&o()}};i.each((function(){var i=pe(this,r),n=i.on;n!==t&&((e=(t=n).copy())._.cancel.push(s),e._.interrupt.push(s),e._.end.push(l)),i.on=e})),0===n&&o()}))},[Symbol.iterator]:Ii[Symbol.iterator]};var Di={time:null,delay:0,duration:250,ease:function(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}};function qi(t,e){for(var i;!(i=t.__transition)||!(i=i[e]);)if(!(t=t.parentNode))throw new Error(`transition ${e} not found`);return i}Mt.prototype.interrupt=function(t){return this.each((function(){!function(t,e){var i,r,n,o=t.__transition,a=!0;if(o){for(n in e=null==e?null:e+"",o)(i=o[n]).name===e?(r=i.state>se&&i.state<he,i.state=ue,i.timer.stop(),i.on.call(r?"interrupt":"cancel",t,t.__data__,i.index,i.group),delete o[n]):a=!1;a&&delete t.__transition}}(this,t)}))},Mt.prototype.transition=function(t){var e,i;t instanceof Oi?(e=t._id,t=t._name):(e=ji(),(i=Di).time=Xt(),t=null==t?null:t+"");for(var r=this._groups,n=r.length,o=0;o<n;++o)for(var a,s=r[o],l=s.length,c=0;c<l;++c)(a=s[c])&&de(a,t,e,c,s,i||qi(a,e));return new Oi(r,this._parents,t,e)};const{abs:$i,max:zi,min:Pi}=Math;function Ri(t){return[+t[0],+t[1]]}function Wi(t){return[Ri(t[0]),Ri(t[1])]}["w","e"].map(Ui),["n","s"].map(Ui),["n","w","e","s","nw","ne","sw","se"].map(Ui);function Ui(t){return{type:t}}function Hi(t){if(!t.ok)throw new Error(t.status+" "+t.statusText);return t.text()}function Yi(t){return(e,i)=>function(t,e){return fetch(t,e).then(Hi)}(e,i).then((e=>(new DOMParser).parseFromString(e,t)))}Yi("application/xml");Yi("text/html");var Vi=Yi("image/svg+xml");const Gi=Math.PI/180,Xi=180/Math.PI,Zi=.96422,Ji=1,Qi=.82521,Ki=4/29,tr=6/29,er=3*tr*tr,ir=tr*tr*tr;function rr(t){if(t instanceof nr)return new nr(t.l,t.a,t.b,t.opacity);if(t instanceof ur)return dr(t);t instanceof Ze||(t=Ge(t));var e,i,r=lr(t.r),n=lr(t.g),o=lr(t.b),a=or((.2225045*r+.7168786*n+.0606169*o)/Ji);return r===n&&n===o?e=i=a:(e=or((.4360747*r+.3850649*n+.1430804*o)/Zi),i=or((.0139322*r+.0971045*n+.7141733*o)/Qi)),new nr(116*a-16,500*(e-a),200*(a-i),t.opacity)}function nr(t,e,i,r){this.l=+t,this.a=+e,this.b=+i,this.opacity=+r}function or(t){return t>ir?Math.pow(t,1/3):t/er+Ki}function ar(t){return t>tr?t*t*t:er*(t-Ki)}function sr(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function lr(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function cr(t){if(t instanceof ur)return new ur(t.h,t.c,t.l,t.opacity);if(t instanceof nr||(t=rr(t)),0===t.a&&0===t.b)return new ur(NaN,0<t.l&&t.l<100?0:NaN,t.l,t.opacity);var e=Math.atan2(t.b,t.a)*Xi;return new ur(e<0?e+360:e,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}function hr(t,e,i,r){return 1===arguments.length?cr(t):new ur(t,e,i,null==r?1:r)}function ur(t,e,i,r){this.h=+t,this.c=+e,this.l=+i,this.opacity=+r}function dr(t){if(isNaN(t.h))return new nr(t.l,0,0,t.opacity);var e=t.h*Gi;return new nr(t.l,Math.cos(e)*t.c,Math.sin(e)*t.c,t.opacity)}function fr(t){return function(e,i){var r=t((e=hr(e)).h,(i=hr(i)).h),n=di(e.c,i.c),o=di(e.l,i.l),a=di(e.opacity,i.opacity);return function(t){return e.h=r(t),e.c=n(t),e.l=o(t),e.opacity=a(t),e+""}}}Se(nr,(function(t,e,i,r){return 1===arguments.length?rr(t):new nr(t,e,i,null==r?1:r)}),Be(Fe,{brighter(t){return new nr(this.l+18*(null==t?1:t),this.a,this.b,this.opacity)},darker(t){return new nr(this.l-18*(null==t?1:t),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,i=isNaN(this.b)?t:t-this.b/200;return new Ze(sr(3.1338561*(e=Zi*ar(e))-1.6168667*(t=Ji*ar(t))-.4906146*(i=Qi*ar(i))),sr(-.9787684*e+1.9161415*t+.033454*i),sr(.0719453*e-.2289914*t+1.4052427*i),this.opacity)}})),Se(ur,hr,Be(Fe,{brighter(t){return new ur(this.h,this.c,this.l+18*(null==t?1:t),this.opacity)},darker(t){return new ur(this.h,this.c,this.l-18*(null==t?1:t),this.opacity)},rgb(){return dr(this).rgb()}}));const pr=fr((function(t,e){var i=e-t;return i?hi(t,i>180||i<-180?i-360*Math.round(i/360):i):ci(isNaN(t)?e:t)}));fr(di);function gr(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t)}return this}class mr extends Map{constructor(t,e=br){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:e}}),null!=t)for(const[i,r]of t)this.set(i,r)}get(t){return super.get(yr(this,t))}has(t){return super.has(yr(this,t))}set(t,e){return super.set(xr(this,t),e)}delete(t){return super.delete(Cr(this,t))}}Set;function yr({_intern:t,_key:e},i){const r=e(i);return t.has(r)?t.get(r):i}function xr({_intern:t,_key:e},i){const r=e(i);return t.has(r)?t.get(r):(t.set(r,i),i)}function Cr({_intern:t,_key:e},i){const r=e(i);return t.has(r)&&(i=t.get(r),t.delete(r)),i}function br(t){return null!==t&&"object"==typeof t?t.valueOf():t}const _r=Symbol("implicit");function vr(){var t=new mr,e=[],i=[],r=_r;function n(n){let o=t.get(n);if(void 0===o){if(r!==_r)return r;t.set(n,o=e.push(n)-1)}return i[o%i.length]}return n.domain=function(i){if(!arguments.length)return e.slice();e=[],t=new mr;for(const r of i)t.has(r)||t.set(r,e.push(r)-1);return n},n.range=function(t){return arguments.length?(i=Array.from(t),n):i.slice()},n.unknown=function(t){return arguments.length?(r=t,n):r},n.copy=function(){return vr(e,i).unknown(r)},gr.apply(n,arguments),n}function kr(){var t,e,i=vr().unknown(void 0),r=i.domain,n=i.range,o=0,a=1,s=!1,l=0,c=0,h=.5;function u(){var i=r().length,u=a<o,d=u?a:o,f=u?o:a;t=(f-d)/Math.max(1,i-l+2*c),s&&(t=Math.floor(t)),d+=(f-d-t*(i-l))*h,e=t*(1-l),s&&(d=Math.round(d),e=Math.round(e));var p=function(t,e,i){t=+t,e=+e,i=(n=arguments.length)<2?(e=t,t=0,1):n<3?1:+i;for(var r=-1,n=0|Math.max(0,Math.ceil((e-t)/i)),o=new Array(n);++r<n;)o[r]=t+r*i;return o}(i).map((function(e){return d+t*e}));return n(u?p.reverse():p)}return delete i.unknown,i.domain=function(t){return arguments.length?(r(t),u()):r()},i.range=function(t){return arguments.length?([o,a]=t,o=+o,a=+a,u()):[o,a]},i.rangeRound=function(t){return[o,a]=t,o=+o,a=+a,s=!0,u()},i.bandwidth=function(){return e},i.step=function(){return t},i.round=function(t){return arguments.length?(s=!!t,u()):s},i.padding=function(t){return arguments.length?(l=Math.min(1,c=+t),u()):l},i.paddingInner=function(t){return arguments.length?(l=Math.min(1,t),u()):l},i.paddingOuter=function(t){return arguments.length?(c=+t,u()):c},i.align=function(t){return arguments.length?(h=Math.max(0,Math.min(1,t)),u()):h},i.copy=function(){return kr(r(),[o,a]).round(s).paddingInner(l).paddingOuter(c).align(h)},gr.apply(u(),arguments)}const Tr=Math.sqrt(50),Ar=Math.sqrt(10),wr=Math.sqrt(2);function Sr(t,e,i){const r=(e-t)/Math.max(0,i),n=Math.floor(Math.log10(r)),o=r/Math.pow(10,n),a=o>=Tr?10:o>=Ar?5:o>=wr?2:1;let s,l,c;return n<0?(c=Math.pow(10,-n)/a,s=Math.round(t*c),l=Math.round(e*c),s/c<t&&++s,l/c>e&&--l,c=-c):(c=Math.pow(10,n)*a,s=Math.round(t/c),l=Math.round(e/c),s*c<t&&++s,l*c>e&&--l),l<s&&.5<=i&&i<2?Sr(t,e,2*i):[s,l,c]}function Br(t,e,i){return Sr(t=+t,e=+e,i=+i)[2]}function Fr(t,e,i){i=+i;const r=(e=+e)<(t=+t),n=r?Br(e,t,i):Br(t,e,i);return(r?-1:1)*(n<0?1/-n:n)}function Lr(t,e){return null==t||null==e?NaN:t<e?-1:t>e?1:t>=e?0:NaN}function Mr(t,e){return null==t||null==e?NaN:e<t?-1:e>t?1:e>=t?0:NaN}function Er(t){let e,i,r;function n(t,r,n=0,o=t.length){if(n<o){if(0!==e(r,r))return o;do{const e=n+o>>>1;i(t[e],r)<0?n=e+1:o=e}while(n<o)}return n}return 2!==t.length?(e=Lr,i=(e,i)=>Lr(t(e),i),r=(e,i)=>t(e)-i):(e=t===Lr||t===Mr?t:Nr,i=t,r=t),{left:n,center:function(t,e,i=0,o=t.length){const a=n(t,e,i,o-1);return a>i&&r(t[a-1],e)>-r(t[a],e)?a-1:a},right:function(t,r,n=0,o=t.length){if(n<o){if(0!==e(r,r))return o;do{const e=n+o>>>1;i(t[e],r)<=0?n=e+1:o=e}while(n<o)}return n}}}function Nr(){return 0}const Or=Er(Lr),jr=Or.right,Ir=(Or.left,Er((function(t){return null===t?NaN:+t})).center,jr);function Dr(t,e){var i,r=e?e.length:0,n=t?Math.min(r,t.length):0,o=new Array(n),a=new Array(r);for(i=0;i<n;++i)o[i]=Pr(t[i],e[i]);for(;i<r;++i)a[i]=e[i];return function(t){for(i=0;i<n;++i)a[i]=o[i](t);return a}}function qr(t,e){var i=new Date;return t=+t,e=+e,function(r){return i.setTime(t*(1-r)+e*r),i}}function $r(t,e){var i,r={},n={};for(i in null!==t&&"object"==typeof t||(t={}),null!==e&&"object"==typeof e||(e={}),e)i in t?r[i]=Pr(t[i],e[i]):n[i]=e[i];return function(t){for(i in r)n[i]=r[i](t);return n}}function zr(t,e){e||(e=[]);var i,r=t?Math.min(e.length,t.length):0,n=e.slice();return function(o){for(i=0;i<r;++i)n[i]=t[i]*(1-o)+e[i]*o;return n}}function Pr(t,e){var i,r,n=typeof e;return null==e||"boolean"===n?ci(e):("number"===n?me:"string"===n?(i=He(e))?(e=i,fi):yi:e instanceof He?fi:e instanceof Date?qr:(r=e,!ArrayBuffer.isView(r)||r instanceof DataView?Array.isArray(e)?Dr:"function"!=typeof e.valueOf&&"function"!=typeof e.toString||isNaN(e)?$r:me:zr))(t,e)}function Rr(t,e){return t=+t,e=+e,function(i){return Math.round(t*(1-i)+e*i)}}function Wr(t){return+t}var Ur=[0,1];function Hr(t){return t}function Yr(t,e){return(e-=t=+t)?function(i){return(i-t)/e}:(i=isNaN(e)?NaN:.5,function(){return i});var i}function Vr(t,e,i){var r=t[0],n=t[1],o=e[0],a=e[1];return n<r?(r=Yr(n,r),o=i(a,o)):(r=Yr(r,n),o=i(o,a)),function(t){return o(r(t))}}function Gr(t,e,i){var r=Math.min(t.length,e.length)-1,n=new Array(r),o=new Array(r),a=-1;for(t[r]<t[0]&&(t=t.slice().reverse(),e=e.slice().reverse());++a<r;)n[a]=Yr(t[a],t[a+1]),o[a]=i(e[a],e[a+1]);return function(e){var i=Ir(t,e,1,r)-1;return o[i](n[i](e))}}function Xr(t,e){return e.domain(t.domain()).range(t.range()).interpolate(t.interpolate()).clamp(t.clamp()).unknown(t.unknown())}function Zr(){var t,e,i,r,n,o,a=Ur,s=Ur,l=Pr,c=Hr;function h(){var t,e,i,l=Math.min(a.length,s.length);return c!==Hr&&(t=a[0],e=a[l-1],t>e&&(i=t,t=e,e=i),c=function(i){return Math.max(t,Math.min(e,i))}),r=l>2?Gr:Vr,n=o=null,u}function u(e){return null==e||isNaN(e=+e)?i:(n||(n=r(a.map(t),s,l)))(t(c(e)))}return u.invert=function(i){return c(e((o||(o=r(s,a.map(t),me)))(i)))},u.domain=function(t){return arguments.length?(a=Array.from(t,Wr),h()):a.slice()},u.range=function(t){return arguments.length?(s=Array.from(t),h()):s.slice()},u.rangeRound=function(t){return s=Array.from(t),l=Rr,h()},u.clamp=function(t){return arguments.length?(c=!!t||Hr,h()):c!==Hr},u.interpolate=function(t){return arguments.length?(l=t,h()):l},u.unknown=function(t){return arguments.length?(i=t,u):i},function(i,r){return t=i,e=r,h()}}function Jr(){return Zr()(Hr,Hr)}var Qr,Kr=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function tn(t){if(!(e=Kr.exec(t)))throw new Error("invalid format: "+t);var e;return new en({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function en(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function rn(t,e){if((i=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var i,r=t.slice(0,i);return[r.length>1?r[0]+r.slice(2):r,+t.slice(i+1)]}function nn(t){return(t=rn(Math.abs(t)))?t[1]:NaN}function on(t,e){var i=rn(t,e);if(!i)return t+"";var r=i[0],n=i[1];return n<0?"0."+new Array(-n).join("0")+r:r.length>n+1?r.slice(0,n+1)+"."+r.slice(n+1):r+new Array(n-r.length+2).join("0")}tn.prototype=en.prototype,en.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const an={"%":(t,e)=>(100*t).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:function(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)},e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>on(100*t,e),r:on,s:function(t,e){var i=rn(t,e);if(!i)return t+"";var r=i[0],n=i[1],o=n-(Qr=3*Math.max(-8,Math.min(8,Math.floor(n/3))))+1,a=r.length;return o===a?r:o>a?r+new Array(o-a+1).join("0"):o>0?r.slice(0,o)+"."+r.slice(o):"0."+new Array(1-o).join("0")+rn(t,Math.max(0,e+o-1))[0]},X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function sn(t){return t}var ln,cn,hn,un=Array.prototype.map,dn=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"];function fn(t){var e,i,r=void 0===t.grouping||void 0===t.thousands?sn:(e=un.call(t.grouping,Number),i=t.thousands+"",function(t,r){for(var n=t.length,o=[],a=0,s=e[0],l=0;n>0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),o.push(t.substring(n-=s,n+s)),!((l+=s+1)>r));)s=e[a=(a+1)%e.length];return o.reverse().join(i)}),n=void 0===t.currency?"":t.currency[0]+"",o=void 0===t.currency?"":t.currency[1]+"",a=void 0===t.decimal?".":t.decimal+"",s=void 0===t.numerals?sn:function(t){return function(e){return e.replace(/[0-9]/g,(function(e){return t[+e]}))}}(un.call(t.numerals,String)),l=void 0===t.percent?"%":t.percent+"",c=void 0===t.minus?"\u2212":t.minus+"",h=void 0===t.nan?"NaN":t.nan+"";function u(t){var e=(t=tn(t)).fill,i=t.align,u=t.sign,d=t.symbol,f=t.zero,p=t.width,g=t.comma,m=t.precision,y=t.trim,x=t.type;"n"===x?(g=!0,x="g"):an[x]||(void 0===m&&(m=12),y=!0,x="g"),(f||"0"===e&&"="===i)&&(f=!0,e="0",i="=");var C="$"===d?n:"#"===d&&/[boxX]/.test(x)?"0"+x.toLowerCase():"",b="$"===d?o:/[%p]/.test(x)?l:"",_=an[x],v=/[defgprs%]/.test(x);function k(t){var n,o,l,d=C,k=b;if("c"===x)k=_(t)+k,t="";else{var T=(t=+t)<0||1/t<0;if(t=isNaN(t)?h:_(Math.abs(t),m),y&&(t=function(t){t:for(var e,i=t.length,r=1,n=-1;r<i;++r)switch(t[r]){case".":n=e=r;break;case"0":0===n&&(n=r),e=r;break;default:if(!+t[r])break t;n>0&&(n=0)}return n>0?t.slice(0,n)+t.slice(e+1):t}(t)),T&&0==+t&&"+"!==u&&(T=!1),d=(T?"("===u?u:c:"-"===u||"("===u?"":u)+d,k=("s"===x?dn[8+Qr/3]:"")+k+(T&&"("===u?")":""),v)for(n=-1,o=t.length;++n<o;)if(48>(l=t.charCodeAt(n))||l>57){k=(46===l?a+t.slice(n+1):t.slice(n))+k,t=t.slice(0,n);break}}g&&!f&&(t=r(t,1/0));var A=d.length+t.length+k.length,w=A<p?new Array(p-A+1).join(e):"";switch(g&&f&&(t=r(w+t,w.length?p-k.length:1/0),w=""),i){case"<":t=d+t+k+w;break;case"=":t=d+w+t+k;break;case"^":t=w.slice(0,A=w.length>>1)+d+t+k+w.slice(A);break;default:t=w+d+t+k}return s(t)}return m=void 0===m?6:/[gprs]/.test(x)?Math.max(1,Math.min(21,m)):Math.max(0,Math.min(20,m)),k.toString=function(){return t+""},k}return{format:u,formatPrefix:function(t,e){var i=u(((t=tn(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor(nn(e)/3))),n=Math.pow(10,-r),o=dn[8+r/3];return function(t){return i(n*t)+o}}}}function pn(t,e,i,r){var n,o=Fr(t,e,i);switch((r=tn(null==r?",f":r)).type){case"s":var a=Math.max(Math.abs(t),Math.abs(e));return null!=r.precision||isNaN(n=function(t,e){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(nn(e)/3)))-nn(Math.abs(t)))}(o,a))||(r.precision=n),hn(r,a);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(n=function(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,nn(e)-nn(t))+1}(o,Math.max(Math.abs(t),Math.abs(e))))||(r.precision=n-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(n=function(t){return Math.max(0,-nn(Math.abs(t)))}(o))||(r.precision=n-2*("%"===r.type))}return cn(r)}function gn(t){var e=t.domain;return t.ticks=function(t){var i=e();return function(t,e,i){if(!((i=+i)>0))return[];if((t=+t)==(e=+e))return[t];const r=e<t,[n,o,a]=r?Sr(e,t,i):Sr(t,e,i);if(!(o>=n))return[];const s=o-n+1,l=new Array(s);if(r)if(a<0)for(let c=0;c<s;++c)l[c]=(o-c)/-a;else for(let c=0;c<s;++c)l[c]=(o-c)*a;else if(a<0)for(let c=0;c<s;++c)l[c]=(n+c)/-a;else for(let c=0;c<s;++c)l[c]=(n+c)*a;return l}(i[0],i[i.length-1],null==t?10:t)},t.tickFormat=function(t,i){var r=e();return pn(r[0],r[r.length-1],null==t?10:t,i)},t.nice=function(i){null==i&&(i=10);var r,n,o=e(),a=0,s=o.length-1,l=o[a],c=o[s],h=10;for(c<l&&(n=l,l=c,c=n,n=a,a=s,s=n);h-- >0;){if((n=Br(l,c,i))===r)return o[a]=l,o[s]=c,e(o);if(n>0)l=Math.floor(l/n)*n,c=Math.ceil(c/n)*n;else{if(!(n<0))break;l=Math.ceil(l*n)/n,c=Math.floor(c*n)/n}r=n}return t},t}function mn(){var t=Jr();return t.copy=function(){return Xr(t,mn())},gr.apply(t,arguments),gn(t)}ln=fn({thousands:",",grouping:[3],currency:["$",""]}),cn=ln.format,hn=ln.formatPrefix;const yn=1e3,xn=6e4,Cn=36e5,bn=864e5,_n=6048e5,vn=2592e6,kn=31536e6,Tn=new Date,An=new Date;function wn(t,e,i,r){function n(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return n.floor=e=>(t(e=new Date(+e)),e),n.ceil=i=>(t(i=new Date(i-1)),e(i,1),t(i),i),n.round=t=>{const e=n(t),i=n.ceil(t);return t-e<i-t?e:i},n.offset=(t,i)=>(e(t=new Date(+t),null==i?1:Math.floor(i)),t),n.range=(i,r,o)=>{const a=[];if(i=n.ceil(i),o=null==o?1:Math.floor(o),!(i<r&&o>0))return a;let s;do{a.push(s=new Date(+i)),e(i,o),t(i)}while(s<i&&i<r);return a},n.filter=i=>wn((e=>{if(e>=e)for(;t(e),!i(e);)e.setTime(e-1)}),((t,r)=>{if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!i(t););else for(;--r>=0;)for(;e(t,1),!i(t););})),i&&(n.count=(e,r)=>(Tn.setTime(+e),An.setTime(+r),t(Tn),t(An),Math.floor(i(Tn,An))),n.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?n.filter(r?e=>r(e)%t==0:e=>n.count(0,e)%t==0):n:null)),n}const Sn=wn((()=>{}),((t,e)=>{t.setTime(+t+e)}),((t,e)=>e-t));Sn.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?wn((e=>{e.setTime(Math.floor(e/t)*t)}),((e,i)=>{e.setTime(+e+i*t)}),((e,i)=>(i-e)/t)):Sn:null);Sn.range;const Bn=wn((t=>{t.setTime(t-t.getMilliseconds())}),((t,e)=>{t.setTime(+t+e*yn)}),((t,e)=>(e-t)/yn),(t=>t.getUTCSeconds())),Fn=(Bn.range,wn((t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*yn)}),((t,e)=>{t.setTime(+t+e*xn)}),((t,e)=>(e-t)/xn),(t=>t.getMinutes()))),Ln=(Fn.range,wn((t=>{t.setUTCSeconds(0,0)}),((t,e)=>{t.setTime(+t+e*xn)}),((t,e)=>(e-t)/xn),(t=>t.getUTCMinutes()))),Mn=(Ln.range,wn((t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*yn-t.getMinutes()*xn)}),((t,e)=>{t.setTime(+t+e*Cn)}),((t,e)=>(e-t)/Cn),(t=>t.getHours()))),En=(Mn.range,wn((t=>{t.setUTCMinutes(0,0,0)}),((t,e)=>{t.setTime(+t+e*Cn)}),((t,e)=>(e-t)/Cn),(t=>t.getUTCHours()))),Nn=(En.range,wn((t=>t.setHours(0,0,0,0)),((t,e)=>t.setDate(t.getDate()+e)),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*xn)/bn),(t=>t.getDate()-1))),On=(Nn.range,wn((t=>{t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+e)}),((t,e)=>(e-t)/bn),(t=>t.getUTCDate()-1))),jn=(On.range,wn((t=>{t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+e)}),((t,e)=>(e-t)/bn),(t=>Math.floor(t/bn))));jn.range;function In(t){return wn((e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),((t,e)=>{t.setDate(t.getDate()+7*e)}),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*xn)/_n))}const Dn=In(0),qn=In(1),$n=In(2),zn=In(3),Pn=In(4),Rn=In(5),Wn=In(6);Dn.range,qn.range,$n.range,zn.range,Pn.range,Rn.range,Wn.range;function Un(t){return wn((e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+7*e)}),((t,e)=>(e-t)/_n))}const Hn=Un(0),Yn=Un(1),Vn=Un(2),Gn=Un(3),Xn=Un(4),Zn=Un(5),Jn=Un(6),Qn=(Hn.range,Yn.range,Vn.range,Gn.range,Xn.range,Zn.range,Jn.range,wn((t=>{t.setDate(1),t.setHours(0,0,0,0)}),((t,e)=>{t.setMonth(t.getMonth()+e)}),((t,e)=>e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())),(t=>t.getMonth()))),Kn=(Qn.range,wn((t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)}),((t,e)=>e.getUTCMonth()-t.getUTCMonth()+12*(e.getUTCFullYear()-t.getUTCFullYear())),(t=>t.getUTCMonth()))),to=(Kn.range,wn((t=>{t.setMonth(0,1),t.setHours(0,0,0,0)}),((t,e)=>{t.setFullYear(t.getFullYear()+e)}),((t,e)=>e.getFullYear()-t.getFullYear()),(t=>t.getFullYear())));to.every=t=>isFinite(t=Math.floor(t))&&t>0?wn((e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),((e,i)=>{e.setFullYear(e.getFullYear()+i*t)})):null;to.range;const eo=wn((t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)}),((t,e)=>e.getUTCFullYear()-t.getUTCFullYear()),(t=>t.getUTCFullYear()));eo.every=t=>isFinite(t=Math.floor(t))&&t>0?wn((e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),((e,i)=>{e.setUTCFullYear(e.getUTCFullYear()+i*t)})):null;eo.range;function io(t,e,i,r,n,o){const a=[[Bn,1,yn],[Bn,5,5e3],[Bn,15,15e3],[Bn,30,3e4],[o,1,xn],[o,5,3e5],[o,15,9e5],[o,30,18e5],[n,1,Cn],[n,3,108e5],[n,6,216e5],[n,12,432e5],[r,1,bn],[r,2,1728e5],[i,1,_n],[e,1,vn],[e,3,7776e6],[t,1,kn]];function s(e,i,r){const n=Math.abs(i-e)/r,o=Er((([,,t])=>t)).right(a,n);if(o===a.length)return t.every(Fr(e/kn,i/kn,r));if(0===o)return Sn.every(Math.max(Fr(e,i,r),1));const[s,l]=a[n/a[o-1][2]<a[o][2]/n?o-1:o];return s.every(l)}return[function(t,e,i){const r=e<t;r&&([t,e]=[e,t]);const n=i&&"function"==typeof i.range?i:s(t,e,i),o=n?n.range(t,+e+1):[];return r?o.reverse():o},s]}const[ro,no]=io(eo,Kn,Hn,jn,En,Ln),[oo,ao]=io(to,Qn,Dn,Nn,Mn,Fn);function so(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function lo(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function co(t,e,i){return{y:t,m:e,d:i,H:0,M:0,S:0,L:0}}var ho,uo,fo={"-":"",_:" ",0:"0"},po=/^\s*\d+/,go=/^%/,mo=/[\\^$*+?|[\]().{}]/g;function yo(t,e,i){var r=t<0?"-":"",n=(r?-t:t)+"",o=n.length;return r+(o<i?new Array(i-o+1).join(e)+n:n)}function xo(t){return t.replace(mo,"\\$&")}function Co(t){return new RegExp("^(?:"+t.map(xo).join("|")+")","i")}function bo(t){return new Map(t.map(((t,e)=>[t.toLowerCase(),e])))}function _o(t,e,i){var r=po.exec(e.slice(i,i+1));return r?(t.w=+r[0],i+r[0].length):-1}function vo(t,e,i){var r=po.exec(e.slice(i,i+1));return r?(t.u=+r[0],i+r[0].length):-1}function ko(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.U=+r[0],i+r[0].length):-1}function To(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.V=+r[0],i+r[0].length):-1}function Ao(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.W=+r[0],i+r[0].length):-1}function wo(t,e,i){var r=po.exec(e.slice(i,i+4));return r?(t.y=+r[0],i+r[0].length):-1}function So(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),i+r[0].length):-1}function Bo(t,e,i){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(i,i+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),i+r[0].length):-1}function Fo(t,e,i){var r=po.exec(e.slice(i,i+1));return r?(t.q=3*r[0]-3,i+r[0].length):-1}function Lo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.m=r[0]-1,i+r[0].length):-1}function Mo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.d=+r[0],i+r[0].length):-1}function Eo(t,e,i){var r=po.exec(e.slice(i,i+3));return r?(t.m=0,t.d=+r[0],i+r[0].length):-1}function No(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.H=+r[0],i+r[0].length):-1}function Oo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.M=+r[0],i+r[0].length):-1}function jo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.S=+r[0],i+r[0].length):-1}function Io(t,e,i){var r=po.exec(e.slice(i,i+3));return r?(t.L=+r[0],i+r[0].length):-1}function Do(t,e,i){var r=po.exec(e.slice(i,i+6));return r?(t.L=Math.floor(r[0]/1e3),i+r[0].length):-1}function qo(t,e,i){var r=go.exec(e.slice(i,i+1));return r?i+r[0].length:-1}function $o(t,e,i){var r=po.exec(e.slice(i));return r?(t.Q=+r[0],i+r[0].length):-1}function zo(t,e,i){var r=po.exec(e.slice(i));return r?(t.s=+r[0],i+r[0].length):-1}function Po(t,e){return yo(t.getDate(),e,2)}function Ro(t,e){return yo(t.getHours(),e,2)}function Wo(t,e){return yo(t.getHours()%12||12,e,2)}function Uo(t,e){return yo(1+Nn.count(to(t),t),e,3)}function Ho(t,e){return yo(t.getMilliseconds(),e,3)}function Yo(t,e){return Ho(t,e)+"000"}function Vo(t,e){return yo(t.getMonth()+1,e,2)}function Go(t,e){return yo(t.getMinutes(),e,2)}function Xo(t,e){return yo(t.getSeconds(),e,2)}function Zo(t){var e=t.getDay();return 0===e?7:e}function Jo(t,e){return yo(Dn.count(to(t)-1,t),e,2)}function Qo(t){var e=t.getDay();return e>=4||0===e?Pn(t):Pn.ceil(t)}function Ko(t,e){return t=Qo(t),yo(Pn.count(to(t),t)+(4===to(t).getDay()),e,2)}function ta(t){return t.getDay()}function ea(t,e){return yo(qn.count(to(t)-1,t),e,2)}function ia(t,e){return yo(t.getFullYear()%100,e,2)}function ra(t,e){return yo((t=Qo(t)).getFullYear()%100,e,2)}function na(t,e){return yo(t.getFullYear()%1e4,e,4)}function oa(t,e){var i=t.getDay();return yo((t=i>=4||0===i?Pn(t):Pn.ceil(t)).getFullYear()%1e4,e,4)}function aa(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+yo(e/60|0,"0",2)+yo(e%60,"0",2)}function sa(t,e){return yo(t.getUTCDate(),e,2)}function la(t,e){return yo(t.getUTCHours(),e,2)}function ca(t,e){return yo(t.getUTCHours()%12||12,e,2)}function ha(t,e){return yo(1+On.count(eo(t),t),e,3)}function ua(t,e){return yo(t.getUTCMilliseconds(),e,3)}function da(t,e){return ua(t,e)+"000"}function fa(t,e){return yo(t.getUTCMonth()+1,e,2)}function pa(t,e){return yo(t.getUTCMinutes(),e,2)}function ga(t,e){return yo(t.getUTCSeconds(),e,2)}function ma(t){var e=t.getUTCDay();return 0===e?7:e}function ya(t,e){return yo(Hn.count(eo(t)-1,t),e,2)}function xa(t){var e=t.getUTCDay();return e>=4||0===e?Xn(t):Xn.ceil(t)}function Ca(t,e){return t=xa(t),yo(Xn.count(eo(t),t)+(4===eo(t).getUTCDay()),e,2)}function ba(t){return t.getUTCDay()}function _a(t,e){return yo(Yn.count(eo(t)-1,t),e,2)}function va(t,e){return yo(t.getUTCFullYear()%100,e,2)}function ka(t,e){return yo((t=xa(t)).getUTCFullYear()%100,e,2)}function Ta(t,e){return yo(t.getUTCFullYear()%1e4,e,4)}function Aa(t,e){var i=t.getUTCDay();return yo((t=i>=4||0===i?Xn(t):Xn.ceil(t)).getUTCFullYear()%1e4,e,4)}function wa(){return"+0000"}function Sa(){return"%"}function Ba(t){return+t}function Fa(t){return Math.floor(+t/1e3)}function La(t){return new Date(t)}function Ma(t){return t instanceof Date?+t:+new Date(+t)}function Ea(t,e,i,r,n,o,a,s,l,c){var h=Jr(),u=h.invert,d=h.domain,f=c(".%L"),p=c(":%S"),g=c("%I:%M"),m=c("%I %p"),y=c("%a %d"),x=c("%b %d"),C=c("%B"),b=c("%Y");function _(t){return(l(t)<t?f:s(t)<t?p:a(t)<t?g:o(t)<t?m:r(t)<t?n(t)<t?y:x:i(t)<t?C:b)(t)}return h.invert=function(t){return new Date(u(t))},h.domain=function(t){return arguments.length?d(Array.from(t,Ma)):d().map(La)},h.ticks=function(e){var i=d();return t(i[0],i[i.length-1],null==e?10:e)},h.tickFormat=function(t,e){return null==e?_:c(e)},h.nice=function(t){var i=d();return t&&"function"==typeof t.range||(t=e(i[0],i[i.length-1],null==t?10:t)),t?d(function(t,e){var i,r=0,n=(t=t.slice()).length-1,o=t[r],a=t[n];return a<o&&(i=r,r=n,n=i,i=o,o=a,a=i),t[r]=e.floor(o),t[n]=e.ceil(a),t}(i,t)):h},h.copy=function(){return Xr(h,Ea(t,e,i,r,n,o,a,s,l,c))},h}function Na(){return gr.apply(Ea(oo,ao,to,Qn,Dn,Nn,Mn,Fn,Bn,uo).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)}!function(t){ho=function(t){var e=t.dateTime,i=t.date,r=t.time,n=t.periods,o=t.days,a=t.shortDays,s=t.months,l=t.shortMonths,c=Co(n),h=bo(n),u=Co(o),d=bo(o),f=Co(a),p=bo(a),g=Co(s),m=bo(s),y=Co(l),x=bo(l),C={a:function(t){return a[t.getDay()]},A:function(t){return o[t.getDay()]},b:function(t){return l[t.getMonth()]},B:function(t){return s[t.getMonth()]},c:null,d:Po,e:Po,f:Yo,g:ra,G:oa,H:Ro,I:Wo,j:Uo,L:Ho,m:Vo,M:Go,p:function(t){return n[+(t.getHours()>=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:Ba,s:Fa,S:Xo,u:Zo,U:Jo,V:Ko,w:ta,W:ea,x:null,X:null,y:ia,Y:na,Z:aa,"%":Sa},b={a:function(t){return a[t.getUTCDay()]},A:function(t){return o[t.getUTCDay()]},b:function(t){return l[t.getUTCMonth()]},B:function(t){return s[t.getUTCMonth()]},c:null,d:sa,e:sa,f:da,g:ka,G:Aa,H:la,I:ca,j:ha,L:ua,m:fa,M:pa,p:function(t){return n[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:Ba,s:Fa,S:ga,u:ma,U:ya,V:Ca,w:ba,W:_a,x:null,X:null,y:va,Y:Ta,Z:wa,"%":Sa},_={a:function(t,e,i){var r=f.exec(e.slice(i));return r?(t.w=p.get(r[0].toLowerCase()),i+r[0].length):-1},A:function(t,e,i){var r=u.exec(e.slice(i));return r?(t.w=d.get(r[0].toLowerCase()),i+r[0].length):-1},b:function(t,e,i){var r=y.exec(e.slice(i));return r?(t.m=x.get(r[0].toLowerCase()),i+r[0].length):-1},B:function(t,e,i){var r=g.exec(e.slice(i));return r?(t.m=m.get(r[0].toLowerCase()),i+r[0].length):-1},c:function(t,i,r){return T(t,e,i,r)},d:Mo,e:Mo,f:Do,g:So,G:wo,H:No,I:No,j:Eo,L:Io,m:Lo,M:Oo,p:function(t,e,i){var r=c.exec(e.slice(i));return r?(t.p=h.get(r[0].toLowerCase()),i+r[0].length):-1},q:Fo,Q:$o,s:zo,S:jo,u:vo,U:ko,V:To,w:_o,W:Ao,x:function(t,e,r){return T(t,i,e,r)},X:function(t,e,i){return T(t,r,e,i)},y:So,Y:wo,Z:Bo,"%":qo};function v(t,e){return function(i){var r,n,o,a=[],s=-1,l=0,c=t.length;for(i instanceof Date||(i=new Date(+i));++s<c;)37===t.charCodeAt(s)&&(a.push(t.slice(l,s)),null!=(n=fo[r=t.charAt(++s)])?r=t.charAt(++s):n="e"===r?" ":"0",(o=e[r])&&(r=o(i,n)),a.push(r),l=s+1);return a.push(t.slice(l,s)),a.join("")}}function k(t,e){return function(i){var r,n,o=co(1900,void 0,1);if(T(o,t,i+="",0)!=i.length)return null;if("Q"in o)return new Date(o.Q);if("s"in o)return new Date(1e3*o.s+("L"in o?o.L:0));if(e&&!("Z"in o)&&(o.Z=0),"p"in o&&(o.H=o.H%12+12*o.p),void 0===o.m&&(o.m="q"in o?o.q:0),"V"in o){if(o.V<1||o.V>53)return null;"w"in o||(o.w=1),"Z"in o?(n=(r=lo(co(o.y,0,1))).getUTCDay(),r=n>4||0===n?Yn.ceil(r):Yn(r),r=On.offset(r,7*(o.V-1)),o.y=r.getUTCFullYear(),o.m=r.getUTCMonth(),o.d=r.getUTCDate()+(o.w+6)%7):(n=(r=so(co(o.y,0,1))).getDay(),r=n>4||0===n?qn.ceil(r):qn(r),r=Nn.offset(r,7*(o.V-1)),o.y=r.getFullYear(),o.m=r.getMonth(),o.d=r.getDate()+(o.w+6)%7)}else("W"in o||"U"in o)&&("w"in o||(o.w="u"in o?o.u%7:"W"in o?1:0),n="Z"in o?lo(co(o.y,0,1)).getUTCDay():so(co(o.y,0,1)).getDay(),o.m=0,o.d="W"in o?(o.w+6)%7+7*o.W-(n+5)%7:o.w+7*o.U-(n+6)%7);return"Z"in o?(o.H+=o.Z/100|0,o.M+=o.Z%100,lo(o)):so(o)}}function T(t,e,i,r){for(var n,o,a=0,s=e.length,l=i.length;a<s;){if(r>=l)return-1;if(37===(n=e.charCodeAt(a++))){if(n=e.charAt(a++),!(o=_[n in fo?e.charAt(a++):n])||(r=o(t,i,r))<0)return-1}else if(n!=i.charCodeAt(r++))return-1}return r}return C.x=v(i,C),C.X=v(r,C),C.c=v(e,C),b.x=v(i,b),b.X=v(r,b),b.c=v(e,b),{format:function(t){var e=v(t+="",C);return e.toString=function(){return t},e},parse:function(t){var e=k(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=v(t+="",b);return e.toString=function(){return t},e},utcParse:function(t){var e=k(t+="",!0);return e.toString=function(){return t},e}}}(t),uo=ho.format,ho.parse,ho.utcFormat,ho.utcParse}({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});const Oa=function(t){for(var e=t.length/6|0,i=new Array(e),r=0;r<e;)i[r]="#"+t.slice(6*r,6*++r);return i}("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab");function ja(t){return"string"==typeof t?new Ft([[document.querySelector(t)]],[document.documentElement]):new Ft([[t]],Bt)}function Ia(t){return"string"==typeof t?new Ft([document.querySelectorAll(t)],[document.documentElement]):new Ft([_(t)],Bt)}function Da(t){return function(){return t}}const qa=Math.abs,$a=Math.atan2,za=Math.cos,Pa=Math.max,Ra=Math.min,Wa=Math.sin,Ua=Math.sqrt,Ha=1e-12,Ya=Math.PI,Va=Ya/2,Ga=2*Ya;function Xa(t){return t>=1?Va:t<=-1?-Va:Math.asin(t)}const Za=Math.PI,Ja=2*Za,Qa=1e-6,Ka=Ja-Qa;function ts(t){this._+=t[0];for(let e=1,i=t.length;e<i;++e)this._+=arguments[e]+t[e]}class es{constructor(t){this._x0=this._y0=this._x1=this._y1=null,this._="",this._append=null==t?ts:function(t){let e=Math.floor(t);if(!(e>=0))throw new Error(`invalid digits: ${t}`);if(e>15)return ts;const i=10**e;return function(t){this._+=t[0];for(let e=1,r=t.length;e<r;++e)this._+=Math.round(arguments[e]*i)/i+t[e]}}(t)}moveTo(t,e){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}`}closePath(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._append`Z`)}lineTo(t,e){this._append`L${this._x1=+t},${this._y1=+e}`}quadraticCurveTo(t,e,i,r){this._append`Q${+t},${+e},${this._x1=+i},${this._y1=+r}`}bezierCurveTo(t,e,i,r,n,o){this._append`C${+t},${+e},${+i},${+r},${this._x1=+n},${this._y1=+o}`}arcTo(t,e,i,r,n){if(t=+t,e=+e,i=+i,r=+r,(n=+n)<0)throw new Error(`negative radius: ${n}`);let o=this._x1,a=this._y1,s=i-t,l=r-e,c=o-t,h=a-e,u=c*c+h*h;if(null===this._x1)this._append`M${this._x1=t},${this._y1=e}`;else if(u>Qa)if(Math.abs(h*s-l*c)>Qa&&n){let d=i-o,f=r-a,p=s*s+l*l,g=d*d+f*f,m=Math.sqrt(p),y=Math.sqrt(u),x=n*Math.tan((Za-Math.acos((p+u-g)/(2*m*y)))/2),C=x/y,b=x/m;Math.abs(C-1)>Qa&&this._append`L${t+C*c},${e+C*h}`,this._append`A${n},${n},0,0,${+(h*d>c*f)},${this._x1=t+b*s},${this._y1=e+b*l}`}else this._append`L${this._x1=t},${this._y1=e}`;else;}arc(t,e,i,r,n,o){if(t=+t,e=+e,o=!!o,(i=+i)<0)throw new Error(`negative radius: ${i}`);let a=i*Math.cos(r),s=i*Math.sin(r),l=t+a,c=e+s,h=1^o,u=o?r-n:n-r;null===this._x1?this._append`M${l},${c}`:(Math.abs(this._x1-l)>Qa||Math.abs(this._y1-c)>Qa)&&this._append`L${l},${c}`,i&&(u<0&&(u=u%Ja+Ja),u>Ka?this._append`A${i},${i},0,1,${h},${t-a},${e-s}A${i},${i},0,1,${h},${this._x1=l},${this._y1=c}`:u>Qa&&this._append`A${i},${i},0,${+(u>=Za)},${h},${this._x1=t+i*Math.cos(n)},${this._y1=e+i*Math.sin(n)}`)}rect(t,e,i,r){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}h${i=+i}v${+r}h${-i}Z`}toString(){return this._}}function is(t){let e=3;return t.digits=function(i){if(!arguments.length)return e;if(null==i)e=null;else{const t=Math.floor(i);if(!(t>=0))throw new RangeError(`invalid digits: ${i}`);e=t}return t},()=>new es(e)}function rs(t){return t.innerRadius}function ns(t){return t.outerRadius}function os(t){return t.startAngle}function as(t){return t.endAngle}function ss(t){return t&&t.padAngle}function ls(t,e,i,r,n,o,a){var s=t-i,l=e-r,c=(a?o:-o)/Ua(s*s+l*l),h=c*l,u=-c*s,d=t+h,f=e+u,p=i+h,g=r+u,m=(d+p)/2,y=(f+g)/2,x=p-d,C=g-f,b=x*x+C*C,_=n-o,v=d*g-p*f,k=(C<0?-1:1)*Ua(Pa(0,_*_*b-v*v)),T=(v*C-x*k)/b,A=(-v*x-C*k)/b,w=(v*C+x*k)/b,S=(-v*x+C*k)/b,B=T-m,F=A-y,L=w-m,M=S-y;return B*B+F*F>L*L+M*M&&(T=w,A=S),{cx:T,cy:A,x01:-h,y01:-u,x11:T*(n/_-1),y11:A*(n/_-1)}}function cs(){var t=rs,e=ns,i=Da(0),r=null,n=os,o=as,a=ss,s=null,l=is(c);function c(){var c,h,u,d=+t.apply(this,arguments),f=+e.apply(this,arguments),p=n.apply(this,arguments)-Va,g=o.apply(this,arguments)-Va,m=qa(g-p),y=g>p;if(s||(s=c=l()),f<d&&(h=f,f=d,d=h),f>Ha)if(m>Ga-Ha)s.moveTo(f*za(p),f*Wa(p)),s.arc(0,0,f,p,g,!y),d>Ha&&(s.moveTo(d*za(g),d*Wa(g)),s.arc(0,0,d,g,p,y));else{var x,C,b=p,_=g,v=p,k=g,T=m,A=m,w=a.apply(this,arguments)/2,S=w>Ha&&(r?+r.apply(this,arguments):Ua(d*d+f*f)),B=Ra(qa(f-d)/2,+i.apply(this,arguments)),F=B,L=B;if(S>Ha){var M=Xa(S/d*Wa(w)),E=Xa(S/f*Wa(w));(T-=2*M)>Ha?(v+=M*=y?1:-1,k-=M):(T=0,v=k=(p+g)/2),(A-=2*E)>Ha?(b+=E*=y?1:-1,_-=E):(A=0,b=_=(p+g)/2)}var N=f*za(b),O=f*Wa(b),j=d*za(k),I=d*Wa(k);if(B>Ha){var D,q=f*za(_),$=f*Wa(_),z=d*za(v),P=d*Wa(v);if(m<Ya)if(D=function(t,e,i,r,n,o,a,s){var l=i-t,c=r-e,h=a-n,u=s-o,d=u*l-h*c;if(!(d*d<Ha))return[t+(d=(h*(e-o)-u*(t-n))/d)*l,e+d*c]}(N,O,z,P,q,$,j,I)){var R=N-D[0],W=O-D[1],U=q-D[0],H=$-D[1],Y=1/Wa(((u=(R*U+W*H)/(Ua(R*R+W*W)*Ua(U*U+H*H)))>1?0:u<-1?Ya:Math.acos(u))/2),V=Ua(D[0]*D[0]+D[1]*D[1]);F=Ra(B,(d-V)/(Y-1)),L=Ra(B,(f-V)/(Y+1))}else F=L=0}A>Ha?L>Ha?(x=ls(z,P,N,O,f,L,y),C=ls(q,$,j,I,f,L,y),s.moveTo(x.cx+x.x01,x.cy+x.y01),L<B?s.arc(x.cx,x.cy,L,$a(x.y01,x.x01),$a(C.y01,C.x01),!y):(s.arc(x.cx,x.cy,L,$a(x.y01,x.x01),$a(x.y11,x.x11),!y),s.arc(0,0,f,$a(x.cy+x.y11,x.cx+x.x11),$a(C.cy+C.y11,C.cx+C.x11),!y),s.arc(C.cx,C.cy,L,$a(C.y11,C.x11),$a(C.y01,C.x01),!y))):(s.moveTo(N,O),s.arc(0,0,f,b,_,!y)):s.moveTo(N,O),d>Ha&&T>Ha?F>Ha?(x=ls(j,I,q,$,d,-F,y),C=ls(N,O,z,P,d,-F,y),s.lineTo(x.cx+x.x01,x.cy+x.y01),F<B?s.arc(x.cx,x.cy,F,$a(x.y01,x.x01),$a(C.y01,C.x01),!y):(s.arc(x.cx,x.cy,F,$a(x.y01,x.x01),$a(x.y11,x.x11),!y),s.arc(0,0,d,$a(x.cy+x.y11,x.cx+x.x11),$a(C.cy+C.y11,C.cx+C.x11),y),s.arc(C.cx,C.cy,F,$a(C.y11,C.x11),$a(C.y01,C.x01),!y))):s.arc(0,0,d,k,v,y):s.lineTo(j,I)}else s.moveTo(0,0);if(s.closePath(),c)return s=null,c+""||null}return c.centroid=function(){var i=(+t.apply(this,arguments)+ +e.apply(this,arguments))/2,r=(+n.apply(this,arguments)+ +o.apply(this,arguments))/2-Ya/2;return[za(r)*i,Wa(r)*i]},c.innerRadius=function(e){return arguments.length?(t="function"==typeof e?e:Da(+e),c):t},c.outerRadius=function(t){return arguments.length?(e="function"==typeof t?t:Da(+t),c):e},c.cornerRadius=function(t){return arguments.length?(i="function"==typeof t?t:Da(+t),c):i},c.padRadius=function(t){return arguments.length?(r=null==t?null:"function"==typeof t?t:Da(+t),c):r},c.startAngle=function(t){return arguments.length?(n="function"==typeof t?t:Da(+t),c):n},c.endAngle=function(t){return arguments.length?(o="function"==typeof t?t:Da(+t),c):o},c.padAngle=function(t){return arguments.length?(a="function"==typeof t?t:Da(+t),c):a},c.context=function(t){return arguments.length?(s=null==t?null:t,c):s},c}es.prototype;Array.prototype.slice;function hs(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function us(t){this._context=t}function ds(t){return new us(t)}function fs(t){return t[0]}function ps(t){return t[1]}function gs(t,e){var i=Da(!0),r=null,n=ds,o=null,a=is(s);function s(s){var l,c,h,u=(s=hs(s)).length,d=!1;for(null==r&&(o=n(h=a())),l=0;l<=u;++l)!(l<u&&i(c=s[l],l,s))===d&&((d=!d)?o.lineStart():o.lineEnd()),d&&o.point(+t(c,l,s),+e(c,l,s));if(h)return o=null,h+""||null}return t="function"==typeof t?t:void 0===t?fs:Da(t),e="function"==typeof e?e:void 0===e?ps:Da(e),s.x=function(e){return arguments.length?(t="function"==typeof e?e:Da(+e),s):t},s.y=function(t){return arguments.length?(e="function"==typeof t?t:Da(+t),s):e},s.defined=function(t){return arguments.length?(i="function"==typeof t?t:Da(!!t),s):i},s.curve=function(t){return arguments.length?(n=t,null!=r&&(o=n(r)),s):n},s.context=function(t){return arguments.length?(null==t?r=o=null:o=n(r=t),s):r},s}function ms(t,e){return e<t?-1:e>t?1:e>=t?0:NaN}function ys(t){return t}function xs(){var t=ys,e=ms,i=null,r=Da(0),n=Da(Ga),o=Da(0);function a(a){var s,l,c,h,u,d=(a=hs(a)).length,f=0,p=new Array(d),g=new Array(d),m=+r.apply(this,arguments),y=Math.min(Ga,Math.max(-Ga,n.apply(this,arguments)-m)),x=Math.min(Math.abs(y)/d,o.apply(this,arguments)),C=x*(y<0?-1:1);for(s=0;s<d;++s)(u=g[p[s]=s]=+t(a[s],s,a))>0&&(f+=u);for(null!=e?p.sort((function(t,i){return e(g[t],g[i])})):null!=i&&p.sort((function(t,e){return i(a[t],a[e])})),s=0,c=f?(y-d*C)/f:0;s<d;++s,m=h)l=p[s],h=m+((u=g[l])>0?u*c:0)+C,g[l]={data:a[l],index:s,value:u,startAngle:m,endAngle:h,padAngle:x};return g}return a.value=function(e){return arguments.length?(t="function"==typeof e?e:Da(+e),a):t},a.sortValues=function(t){return arguments.length?(e=t,i=null,a):e},a.sort=function(t){return arguments.length?(i=t,e=null,a):i},a.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:Da(+t),a):r},a.endAngle=function(t){return arguments.length?(n="function"==typeof t?t:Da(+t),a):n},a.padAngle=function(t){return arguments.length?(o="function"==typeof t?t:Da(+t),a):o},a}function Cs(){}function bs(t,e,i){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+i)/6)}function _s(t){this._context=t}function vs(t){return new _s(t)}function ks(t){this._context=t}function Ts(t){return new ks(t)}function As(t){this._context=t}function ws(t){return new As(t)}us.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._context.lineTo(t,e)}}},_s.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:bs(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:bs(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},ks.prototype={areaStart:Cs,areaEnd:Cs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:bs(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},As.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var i=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(i,r):this._context.moveTo(i,r);break;case 3:this._point=4;default:bs(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};class Ss{constructor(t,e){this._context=t,this._x=e}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line}point(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._x?this._context.bezierCurveTo(this._x0=(this._x0+t)/2,this._y0,this._x0,e,t,e):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+e)/2,t,this._y0,t,e)}this._x0=t,this._y0=e}}function Bs(t){return new Ss(t,!0)}function Fs(t){return new Ss(t,!1)}function Ls(t,e){this._basis=new _s(t),this._beta=e}Ls.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,i=t.length-1;if(i>0)for(var r,n=t[0],o=e[0],a=t[i]-n,s=e[i]-o,l=-1;++l<=i;)r=l/i,this._basis.point(this._beta*t[l]+(1-this._beta)*(n+r*a),this._beta*e[l]+(1-this._beta)*(o+r*s));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};const Ms=function t(e){function i(t){return 1===e?new _s(t):new Ls(t,e)}return i.beta=function(e){return t(+e)},i}(.85);function Es(t,e,i){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-i),t._x2,t._y2)}function Ns(t,e){this._context=t,this._k=(1-e)/6}Ns.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Es(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:Es(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Os=function t(e){function i(t){return new Ns(t,e)}return i.tension=function(e){return t(+e)},i}(0);function js(t,e){this._context=t,this._k=(1-e)/6}js.prototype={areaStart:Cs,areaEnd:Cs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Es(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Is=function t(e){function i(t){return new js(t,e)}return i.tension=function(e){return t(+e)},i}(0);function Ds(t,e){this._context=t,this._k=(1-e)/6}Ds.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Es(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const qs=function t(e){function i(t){return new Ds(t,e)}return i.tension=function(e){return t(+e)},i}(0);function $s(t,e,i){var r=t._x1,n=t._y1,o=t._x2,a=t._y2;if(t._l01_a>Ha){var s=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,l=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*s-t._x0*t._l12_2a+t._x2*t._l01_2a)/l,n=(n*s-t._y0*t._l12_2a+t._y2*t._l01_2a)/l}if(t._l23_a>Ha){var c=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,h=3*t._l23_a*(t._l23_a+t._l12_a);o=(o*c+t._x1*t._l23_2a-e*t._l12_2a)/h,a=(a*c+t._y1*t._l23_2a-i*t._l12_2a)/h}t._context.bezierCurveTo(r,n,o,a,t._x2,t._y2)}function zs(t,e){this._context=t,this._alpha=e}zs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var i=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:$s(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Ps=function t(e){function i(t){return e?new zs(t,e):new Ns(t,0)}return i.alpha=function(e){return t(+e)},i}(.5);function Rs(t,e){this._context=t,this._alpha=e}Rs.prototype={areaStart:Cs,areaEnd:Cs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){if(t=+t,e=+e,this._point){var i=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:$s(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Ws=function t(e){function i(t){return e?new Rs(t,e):new js(t,0)}return i.alpha=function(e){return t(+e)},i}(.5);function Us(t,e){this._context=t,this._alpha=e}Us.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var i=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:$s(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Hs=function t(e){function i(t){return e?new Us(t,e):new Ds(t,0)}return i.alpha=function(e){return t(+e)},i}(.5);function Ys(t){this._context=t}function Vs(t){return new Ys(t)}function Gs(t){return t<0?-1:1}function Xs(t,e,i){var r=t._x1-t._x0,n=e-t._x1,o=(t._y1-t._y0)/(r||n<0&&-0),a=(i-t._y1)/(n||r<0&&-0),s=(o*n+a*r)/(r+n);return(Gs(o)+Gs(a))*Math.min(Math.abs(o),Math.abs(a),.5*Math.abs(s))||0}function Zs(t,e){var i=t._x1-t._x0;return i?(3*(t._y1-t._y0)/i-e)/2:e}function Js(t,e,i){var r=t._x0,n=t._y0,o=t._x1,a=t._y1,s=(o-r)/3;t._context.bezierCurveTo(r+s,n+s*e,o-s,a-s*i,o,a)}function Qs(t){this._context=t}function Ks(t){this._context=new tl(t)}function tl(t){this._context=t}function el(t){return new Qs(t)}function il(t){return new Ks(t)}function rl(t){this._context=t}function nl(t){var e,i,r=t.length-1,n=new Array(r),o=new Array(r),a=new Array(r);for(n[0]=0,o[0]=2,a[0]=t[0]+2*t[1],e=1;e<r-1;++e)n[e]=1,o[e]=4,a[e]=4*t[e]+2*t[e+1];for(n[r-1]=2,o[r-1]=7,a[r-1]=8*t[r-1]+t[r],e=1;e<r;++e)i=n[e]/o[e-1],o[e]-=i,a[e]-=i*a[e-1];for(n[r-1]=a[r-1]/o[r-1],e=r-2;e>=0;--e)n[e]=(a[e]-n[e+1])/o[e];for(o[r-1]=(t[r]+n[r-1])/2,e=0;e<r-1;++e)o[e]=2*t[e+1]-n[e+1];return[n,o]}function ol(t){return new rl(t)}function al(t,e){this._context=t,this._t=e}function sl(t){return new al(t,.5)}function ll(t){return new al(t,0)}function cl(t){return new al(t,1)}function hl(t,e,i){this.k=t,this.x=e,this.y=i}Ys.prototype={areaStart:Cs,areaEnd:Cs,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}},Qs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:Js(this,this._t0,Zs(this,this._t0))}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){var i=NaN;if(e=+e,(t=+t)!==this._x1||e!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,Js(this,Zs(this,i=Xs(this,t,e)),i);break;default:Js(this,this._t0,i=Xs(this,t,e))}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=i}}},(Ks.prototype=Object.create(Qs.prototype)).point=function(t,e){Qs.prototype.point.call(this,e,t)},tl.prototype={moveTo:function(t,e){this._context.moveTo(e,t)},closePath:function(){this._context.closePath()},lineTo:function(t,e){this._context.lineTo(e,t)},bezierCurveTo:function(t,e,i,r,n,o){this._context.bezierCurveTo(e,t,r,i,o,n)}},rl.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,e=this._y,i=t.length;if(i)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),2===i)this._context.lineTo(t[1],e[1]);else for(var r=nl(t),n=nl(e),o=0,a=1;a<i;++o,++a)this._context.bezierCurveTo(r[0][o],n[0][o],r[1][o],n[1][o],t[a],e[a]);(this._line||0!==this._line&&1===i)&&this._context.closePath(),this._line=1-this._line,this._x=this._y=null},point:function(t,e){this._x.push(+t),this._y.push(+e)}},al.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=this._y=NaN,this._point=0},lineEnd:function(){0<this._t&&this._t<1&&2===this._point&&this._context.lineTo(this._x,this._y),(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line>=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var i=this._x*(1-this._t)+t*this._t;this._context.lineTo(i,this._y),this._context.lineTo(i,e)}}this._x=t,this._y=e}},hl.prototype={constructor:hl,scale:function(t){return 1===t?this:new hl(this.k*t,this.x,this.y)},translate:function(t,e){return 0===t&0===e?this:new hl(this.k,this.x+this.k*t,this.y+this.k*e)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};new hl(1,0,0);hl.prototype},93539:(t,e,i)=>{"use strict";i.d(e,{A:()=>a});var r=i(72453),n=i(63122);const o=class{constructor(){this.type=n.Z.ALL}get(){return this.type}set(t){if(this.type&&this.type!==t)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=t}reset(){this.type=n.Z.ALL}is(t){return this.type===t}};const a=new class{constructor(t,e){this.color=e,this.changed=!1,this.data=t,this.type=new o}set(t,e){return this.color=e,this.changed=!1,this.data=t,this.type.type=n.Z.ALL,this}_ensureHSL(){const t=this.data,{h:e,s:i,l:n}=t;void 0===e&&(t.h=r.A.channel.rgb2hsl(t,"h")),void 0===i&&(t.s=r.A.channel.rgb2hsl(t,"s")),void 0===n&&(t.l=r.A.channel.rgb2hsl(t,"l"))}_ensureRGB(){const t=this.data,{r:e,g:i,b:n}=t;void 0===e&&(t.r=r.A.channel.hsl2rgb(t,"r")),void 0===i&&(t.g=r.A.channel.hsl2rgb(t,"g")),void 0===n&&(t.b=r.A.channel.hsl2rgb(t,"b"))}get r(){const t=this.data,e=t.r;return this.type.is(n.Z.HSL)||void 0===e?(this._ensureHSL(),r.A.channel.hsl2rgb(t,"r")):e}get g(){const t=this.data,e=t.g;return this.type.is(n.Z.HSL)||void 0===e?(this._ensureHSL(),r.A.channel.hsl2rgb(t,"g")):e}get b(){const t=this.data,e=t.b;return this.type.is(n.Z.HSL)||void 0===e?(this._ensureHSL(),r.A.channel.hsl2rgb(t,"b")):e}get h(){const t=this.data,e=t.h;return this.type.is(n.Z.RGB)||void 0===e?(this._ensureRGB(),r.A.channel.rgb2hsl(t,"h")):e}get s(){const t=this.data,e=t.s;return this.type.is(n.Z.RGB)||void 0===e?(this._ensureRGB(),r.A.channel.rgb2hsl(t,"s")):e}get l(){const t=this.data,e=t.l;return this.type.is(n.Z.RGB)||void 0===e?(this._ensureRGB(),r.A.channel.rgb2hsl(t,"l")):e}get a(){return this.data.a}set r(t){this.type.set(n.Z.RGB),this.changed=!0,this.data.r=t}set g(t){this.type.set(n.Z.RGB),this.changed=!0,this.data.g=t}set b(t){this.type.set(n.Z.RGB),this.changed=!0,this.data.b=t}set h(t){this.type.set(n.Z.HSL),this.changed=!0,this.data.h=t}set s(t){this.type.set(n.Z.HSL),this.changed=!0,this.data.s=t}set l(t){this.type.set(n.Z.HSL),this.changed=!0,this.data.l=t}set a(t){this.changed=!0,this.data.a=t}}({r:0,g:0,b:0,a:0},"transparent")},74886:(t,e,i)=>{"use strict";i.d(e,{A:()=>g});var r=i(93539),n=i(63122);const o={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:t=>{if(35!==t.charCodeAt(0))return;const e=t.match(o.re);if(!e)return;const i=e[1],n=parseInt(i,16),a=i.length,s=a%4==0,l=a>4,c=l?1:17,h=l?8:4,u=s?0:-1,d=l?255:15;return r.A.set({r:(n>>h*(u+3)&d)*c,g:(n>>h*(u+2)&d)*c,b:(n>>h*(u+1)&d)*c,a:s?(n&d)*c/255:1},t)},stringify:t=>{const{r:e,g:i,b:r,a:o}=t;return o<1?`#${n.Y[Math.round(e)]}${n.Y[Math.round(i)]}${n.Y[Math.round(r)]}${n.Y[Math.round(255*o)]}`:`#${n.Y[Math.round(e)]}${n.Y[Math.round(i)]}${n.Y[Math.round(r)]}`}},a=o;var s=i(72453);const l={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:t=>{const e=t.match(l.hueRe);if(e){const[,t,i]=e;switch(i){case"grad":return s.A.channel.clamp.h(.9*parseFloat(t));case"rad":return s.A.channel.clamp.h(180*parseFloat(t)/Math.PI);case"turn":return s.A.channel.clamp.h(360*parseFloat(t))}}return s.A.channel.clamp.h(parseFloat(t))},parse:t=>{const e=t.charCodeAt(0);if(104!==e&&72!==e)return;const i=t.match(l.re);if(!i)return;const[,n,o,a,c,h]=i;return r.A.set({h:l._hue2deg(n),s:s.A.channel.clamp.s(parseFloat(o)),l:s.A.channel.clamp.l(parseFloat(a)),a:c?s.A.channel.clamp.a(h?parseFloat(c)/100:parseFloat(c)):1},t)},stringify:t=>{const{h:e,s:i,l:r,a:n}=t;return n<1?`hsla(${s.A.lang.round(e)}, ${s.A.lang.round(i)}%, ${s.A.lang.round(r)}%, ${n})`:`hsl(${s.A.lang.round(e)}, ${s.A.lang.round(i)}%, ${s.A.lang.round(r)}%)`}},c=l,h={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:t=>{t=t.toLowerCase();const e=h.colors[t];if(e)return a.parse(e)},stringify:t=>{const e=a.stringify(t);for(const i in h.colors)if(h.colors[i]===e)return i}},u=h,d={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:t=>{const e=t.charCodeAt(0);if(114!==e&&82!==e)return;const i=t.match(d.re);if(!i)return;const[,n,o,a,l,c,h,u,f]=i;return r.A.set({r:s.A.channel.clamp.r(o?2.55*parseFloat(n):parseFloat(n)),g:s.A.channel.clamp.g(l?2.55*parseFloat(a):parseFloat(a)),b:s.A.channel.clamp.b(h?2.55*parseFloat(c):parseFloat(c)),a:u?s.A.channel.clamp.a(f?parseFloat(u)/100:parseFloat(u)):1},t)},stringify:t=>{const{r:e,g:i,b:r,a:n}=t;return n<1?`rgba(${s.A.lang.round(e)}, ${s.A.lang.round(i)}, ${s.A.lang.round(r)}, ${s.A.lang.round(n)})`:`rgb(${s.A.lang.round(e)}, ${s.A.lang.round(i)}, ${s.A.lang.round(r)})`}},f=d,p={format:{keyword:h,hex:a,rgb:d,rgba:d,hsl:l,hsla:l},parse:t=>{if("string"!=typeof t)return t;const e=a.parse(t)||f.parse(t)||c.parse(t)||u.parse(t);if(e)return e;throw new Error(`Unsupported color format: "${t}"`)},stringify:t=>!t.changed&&t.color?t.color:t.type.is(n.Z.HSL)||void 0===t.data.r?c.stringify(t):t.a<1||!Number.isInteger(t.r)||!Number.isInteger(t.g)||!Number.isInteger(t.b)?f.stringify(t):a.stringify(t)},g=p},63122:(t,e,i)=>{"use strict";i.d(e,{Y:()=>n,Z:()=>o});var r=i(72453);const n={};for(let a=0;a<=255;a++)n[a]=r.A.unit.dec2hex(a);const o={ALL:0,RGB:1,HSL:2}},95635:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(72453),n=i(74886);const o=(t,e,i)=>{const o=n.A.parse(t),a=o[e],s=r.A.channel.clamp[e](a+i);return a!==s&&(o[e]=s),n.A.stringify(o)}},8232:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(72453),n=i(74886);const o=(t,e)=>{const i=n.A.parse(t);for(const n in e)i[n]=r.A.channel.clamp[n](e[n]);return n.A.stringify(i)}},75263:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=i(95635);const n=(t,e)=>(0,r.A)(t,"l",-e)},3219:(t,e,i)=>{"use strict";i.d(e,{A:()=>s});var r=i(72453),n=i(74886);const o=t=>{const{r:e,g:i,b:o}=n.A.parse(t),a=.2126*r.A.channel.toLinear(e)+.7152*r.A.channel.toLinear(i)+.0722*r.A.channel.toLinear(o);return r.A.lang.round(a)},a=t=>o(t)>=.5,s=t=>!a(t)},78041:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=i(95635);const n=(t,e)=>(0,r.A)(t,"l",e)},25582:(t,e,i)=>{"use strict";i.d(e,{A:()=>s});var r=i(72453),n=i(93539),o=i(74886),a=i(8232);const s=(t,e,i=0,s=1)=>{if("number"!=typeof t)return(0,a.A)(t,{a:e});const l=n.A.set({r:r.A.channel.clamp.r(t),g:r.A.channel.clamp.g(e),b:r.A.channel.clamp.b(i),a:r.A.channel.clamp.a(s)});return o.A.stringify(l)}},72453:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});const r={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:t=>t>=255?255:t<0?0:t,g:t=>t>=255?255:t<0?0:t,b:t=>t>=255?255:t<0?0:t,h:t=>t%360,s:t=>t>=100?100:t<0?0:t,l:t=>t>=100?100:t<0?0:t,a:t=>t>=1?1:t<0?0:t},toLinear:t=>{const e=t/255;return t>.03928?Math.pow((e+.055)/1.055,2.4):e/12.92},hue2rgb:(t,e,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t),hsl2rgb:({h:t,s:e,l:i},n)=>{if(!e)return 2.55*i;t/=360,e/=100;const o=(i/=100)<.5?i*(1+e):i+e-i*e,a=2*i-o;switch(n){case"r":return 255*r.hue2rgb(a,o,t+1/3);case"g":return 255*r.hue2rgb(a,o,t);case"b":return 255*r.hue2rgb(a,o,t-1/3)}},rgb2hsl:({r:t,g:e,b:i},r)=>{t/=255,e/=255,i/=255;const n=Math.max(t,e,i),o=Math.min(t,e,i),a=(n+o)/2;if("l"===r)return 100*a;if(n===o)return 0;const s=n-o;if("s"===r)return 100*(a>.5?s/(2-n-o):s/(n+o));switch(n){case t:return 60*((e-i)/s+(e<i?6:0));case e:return 60*((i-t)/s+2);case i:return 60*((t-e)/s+4);default:return-1}}},n={channel:r,lang:{clamp:(t,e,i)=>e>i?Math.min(e,Math.max(i,t)):Math.min(i,Math.max(e,t)),round:t=>Math.round(1e10*t)/1e10},unit:{dec2hex:t=>{const e=Math.round(t).toString(16);return e.length>1?e:`0${e}`}}}},80127:(t,e,i)=>{"use strict";i.d(e,{A:()=>d});const r=function(){this.__data__=[],this.size=0};var n=i(66984);const o=function(t,e){for(var i=t.length;i--;)if((0,n.A)(t[i][0],e))return i;return-1};var a=Array.prototype.splice;const s=function(t){var e=this.__data__,i=o(e,t);return!(i<0)&&(i==e.length-1?e.pop():a.call(e,i,1),--this.size,!0)};const l=function(t){var e=this.__data__,i=o(e,t);return i<0?void 0:e[i][1]};const c=function(t){return o(this.__data__,t)>-1};const h=function(t,e){var i=this.__data__,r=o(i,t);return r<0?(++this.size,i.push([t,e])):i[r][1]=e,this};function u(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e<i;){var r=t[e];this.set(r[0],r[1])}}u.prototype.clear=r,u.prototype.delete=s,u.prototype.get=l,u.prototype.has=c,u.prototype.set=h;const d=u},68335:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(18744),n=i(41917);const o=(0,r.A)(n.A,"Map")},29471:(t,e,i)=>{"use strict";i.d(e,{A:()=>k});const r=(0,i(18744).A)(Object,"create");const n=function(){this.__data__=r?r(null):{},this.size=0};const o=function(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e};var a=Object.prototype.hasOwnProperty;const s=function(t){var e=this.__data__;if(r){var i=e[t];return"__lodash_hash_undefined__"===i?void 0:i}return a.call(e,t)?e[t]:void 0};var l=Object.prototype.hasOwnProperty;const c=function(t){var e=this.__data__;return r?void 0!==e[t]:l.call(e,t)};const h=function(t,e){var i=this.__data__;return this.size+=this.has(t)?0:1,i[t]=r&&void 0===e?"__lodash_hash_undefined__":e,this};function u(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e<i;){var r=t[e];this.set(r[0],r[1])}}u.prototype.clear=n,u.prototype.delete=o,u.prototype.get=s,u.prototype.has=c,u.prototype.set=h;const d=u;var f=i(80127),p=i(68335);const g=function(){this.size=0,this.__data__={hash:new d,map:new(p.A||f.A),string:new d}};const m=function(t){var e=typeof t;return"string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t};const y=function(t,e){var i=t.__data__;return m(e)?i["string"==typeof e?"string":"hash"]:i.map};const x=function(t){var e=y(this,t).delete(t);return this.size-=e?1:0,e};const C=function(t){return y(this,t).get(t)};const b=function(t){return y(this,t).has(t)};const _=function(t,e){var i=y(this,t),r=i.size;return i.set(t,e),this.size+=i.size==r?0:1,this};function v(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e<i;){var r=t[e];this.set(r[0],r[1])}}v.prototype.clear=g,v.prototype.delete=x,v.prototype.get=C,v.prototype.has=b,v.prototype.set=_;const k=v},39857:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(18744),n=i(41917);const o=(0,r.A)(n.A,"Set")},11754:(t,e,i)=>{"use strict";i.d(e,{A:()=>d});var r=i(80127);const n=function(){this.__data__=new r.A,this.size=0};const o=function(t){var e=this.__data__,i=e.delete(t);return this.size=e.size,i};const a=function(t){return this.__data__.get(t)};const s=function(t){return this.__data__.has(t)};var l=i(68335),c=i(29471);const h=function(t,e){var i=this.__data__;if(i instanceof r.A){var n=i.__data__;if(!l.A||n.length<199)return n.push([t,e]),this.size=++i.size,this;i=this.__data__=new c.A(n)}return i.set(t,e),this.size=i.size,this};function u(t){var e=this.__data__=new r.A(t);this.size=e.size}u.prototype.clear=n,u.prototype.delete=o,u.prototype.get=a,u.prototype.has=s,u.prototype.set=h;const d=u},241:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=i(41917).A.Symbol},43988:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=i(41917).A.Uint8Array},83607:(t,e,i)=>{"use strict";i.d(e,{A:()=>h});const r=function(t,e){for(var i=-1,r=Array(t);++i<t;)r[i]=e(i);return r};var n=i(52274),o=i(92049),a=i(99912),s=i(25353),l=i(33858),c=Object.prototype.hasOwnProperty;const h=function(t,e){var i=(0,o.A)(t),h=!i&&(0,n.A)(t),u=!i&&!h&&(0,a.A)(t),d=!i&&!h&&!u&&(0,l.A)(t),f=i||h||u||d,p=f?r(t.length,String):[],g=p.length;for(var m in t)!e&&!c.call(t,m)||f&&("length"==m||u&&("offset"==m||"parent"==m)||d&&("buffer"==m||"byteLength"==m||"byteOffset"==m)||(0,s.A)(m,g))||p.push(m);return p}},52851:(t,e,i)=>{"use strict";i.d(e,{A:()=>a});var r=i(52528),n=i(66984),o=Object.prototype.hasOwnProperty;const a=function(t,e,i){var a=t[e];o.call(t,e)&&(0,n.A)(a,i)&&(void 0!==i||e in t)||(0,r.A)(t,e,i)}},52528:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=i(84171);const n=function(t,e,i){"__proto__"==e&&r.A?(0,r.A)(t,e,{configurable:!0,enumerable:!0,value:i,writable:!0}):t[e]=i}},4574:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){return function(e,i,r){for(var n=-1,o=Object(e),a=r(e),s=a.length;s--;){var l=a[t?s:++n];if(!1===i(o[l],l,o))break}return e}}()},88496:(t,e,i)=>{"use strict";i.d(e,{A:()=>d});var r=i(241),n=Object.prototype,o=n.hasOwnProperty,a=n.toString,s=r.A?r.A.toStringTag:void 0;const l=function(t){var e=o.call(t,s),i=t[s];try{t[s]=void 0;var r=!0}catch(l){}var n=a.call(t);return r&&(e?t[s]=i:delete t[s]),n};var c=Object.prototype.toString;const h=function(t){return c.call(t)};var u=r.A?r.A.toStringTag:void 0;const d=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":u&&u in Object(t)?l(t):h(t)}},69471:(t,e,i)=>{"use strict";i.d(e,{A:()=>a});var r=i(97271);const n=(0,i(40367).A)(Object.keys,Object);var o=Object.prototype.hasOwnProperty;const a=function(t){if(!(0,r.A)(t))return n(t);var e=[];for(var i in Object(t))o.call(t,i)&&"constructor"!=i&&e.push(i);return e}},24326:(t,e,i)=>{"use strict";i.d(e,{A:()=>a});var r=i(29008),n=i(76875),o=i(67525);const a=function(t,e){return(0,o.A)((0,n.A)(t,e,r.A),t+"")}},52789:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){return function(e){return t(e)}}},90565:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=i(43988);const n=function(t){var e=new t.constructor(t.byteLength);return new r.A(e).set(new r.A(t)),e}},80154:(t,e,i)=>{"use strict";i.d(e,{A:()=>l});var r=i(41917),n="object"==typeof exports&&exports&&!exports.nodeType&&exports,o=n&&"object"==typeof module&&module&&!module.nodeType&&module,a=o&&o.exports===n?r.A.Buffer:void 0,s=a?a.allocUnsafe:void 0;const l=function(t,e){if(e)return t.slice();var i=t.length,r=s?s(i):new t.constructor(i);return t.copy(r),r}},1801:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=i(90565);const n=function(t,e){var i=e?(0,r.A)(t.buffer):t.buffer;return new t.constructor(i,t.byteOffset,t.length)}},39759:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t,e){var i=-1,r=t.length;for(e||(e=Array(r));++i<r;)e[i]=t[i];return e}},22031:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(52851),n=i(52528);const o=function(t,e,i,o){var a=!i;i||(i={});for(var s=-1,l=e.length;++s<l;){var c=e[s],h=o?o(i[c],t[c],c,i,t):void 0;void 0===h&&(h=t[c]),a?(0,n.A)(i,c,h):(0,r.A)(i,c,h)}return i}},84171:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=i(18744);const n=function(){try{var t=(0,r.A)(Object,"defineProperty");return t({},"",{}),t}catch(e){}}()},72136:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r="object"==typeof global&&global&&global.Object===Object&&global},18744:(t,e,i)=>{"use strict";i.d(e,{A:()=>x});var r=i(89610);const n=i(41917).A["__core-js_shared__"];var o,a=(o=/[^.]+$/.exec(n&&n.keys&&n.keys.IE_PROTO||""))?"Symbol(src)_1."+o:"";const s=function(t){return!!a&&a in t};var l=i(23149),c=i(81121),h=/^\[object .+?Constructor\]$/,u=Function.prototype,d=Object.prototype,f=u.toString,p=d.hasOwnProperty,g=RegExp("^"+f.call(p).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");const m=function(t){return!(!(0,l.A)(t)||s(t))&&((0,r.A)(t)?g:h).test((0,c.A)(t))};const y=function(t,e){return null==t?void 0:t[e]};const x=function(t,e){var i=y(t,e);return m(i)?i:void 0}},15647:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=(0,i(40367).A)(Object.getPrototypeOf,Object)},9779:(t,e,i)=>{"use strict";i.d(e,{A:()=>k});var r=i(18744),n=i(41917);const o=(0,r.A)(n.A,"DataView");var a=i(68335);const s=(0,r.A)(n.A,"Promise");var l=i(39857);const c=(0,r.A)(n.A,"WeakMap");var h=i(88496),u=i(81121),d="[object Map]",f="[object Promise]",p="[object Set]",g="[object WeakMap]",m="[object DataView]",y=(0,u.A)(o),x=(0,u.A)(a.A),C=(0,u.A)(s),b=(0,u.A)(l.A),_=(0,u.A)(c),v=h.A;(o&&v(new o(new ArrayBuffer(1)))!=m||a.A&&v(new a.A)!=d||s&&v(s.resolve())!=f||l.A&&v(new l.A)!=p||c&&v(new c)!=g)&&(v=function(t){var e=(0,h.A)(t),i="[object Object]"==e?t.constructor:void 0,r=i?(0,u.A)(i):"";if(r)switch(r){case y:return m;case x:return d;case C:return f;case b:return p;case _:return g}return e});const k=v},18598:(t,e,i)=>{"use strict";i.d(e,{A:()=>l});var r=i(23149),n=Object.create;const o=function(){function t(){}return function(e){if(!(0,r.A)(e))return{};if(n)return n(e);t.prototype=e;var i=new t;return t.prototype=void 0,i}}();var a=i(15647),s=i(97271);const l=function(t){return"function"!=typeof t.constructor||(0,s.A)(t)?{}:o((0,a.A)(t))}},25353:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=/^(?:0|[1-9]\d*)$/;const n=function(t,e){var i=typeof t;return!!(e=null==e?9007199254740991:e)&&("number"==i||"symbol"!=i&&r.test(t))&&t>-1&&t%1==0&&t<e}},6832:(t,e,i)=>{"use strict";i.d(e,{A:()=>s});var r=i(66984),n=i(38446),o=i(25353),a=i(23149);const s=function(t,e,i){if(!(0,a.A)(i))return!1;var s=typeof e;return!!("number"==s?(0,n.A)(i)&&(0,o.A)(e,i.length):"string"==s&&e in i)&&(0,r.A)(i[e],t)}},97271:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=Object.prototype;const n=function(t){var e=t&&t.constructor;return t===("function"==typeof e&&e.prototype||r)}},64841:(t,e,i)=>{"use strict";i.d(e,{A:()=>s});var r=i(72136),n="object"==typeof exports&&exports&&!exports.nodeType&&exports,o=n&&"object"==typeof module&&module&&!module.nodeType&&module,a=o&&o.exports===n&&r.A.process;const s=function(){try{var t=o&&o.require&&o.require("util").types;return t||a&&a.binding&&a.binding("util")}catch(e){}}()},40367:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t,e){return function(i){return t(e(i))}}},76875:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});const r=function(t,e,i){switch(i.length){case 0:return t.call(e);case 1:return t.call(e,i[0]);case 2:return t.call(e,i[0],i[1]);case 3:return t.call(e,i[0],i[1],i[2])}return t.apply(e,i)};var n=Math.max;const o=function(t,e,i){return e=n(void 0===e?t.length-1:e,0),function(){for(var o=arguments,a=-1,s=n(o.length-e,0),l=Array(s);++a<s;)l[a]=o[e+a];a=-1;for(var c=Array(e+1);++a<e;)c[a]=o[a];return c[e]=i(l),r(t,this,c)}}},41917:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(72136),n="object"==typeof self&&self&&self.Object===Object&&self;const o=r.A||n||Function("return this")()},67525:(t,e,i)=>{"use strict";i.d(e,{A:()=>l});var r=i(39142),n=i(84171),o=i(29008);const a=n.A?function(t,e){return(0,n.A)(t,"toString",{configurable:!0,enumerable:!1,value:(0,r.A)(e),writable:!0})}:o.A;var s=Date.now;const l=function(t){var e=0,i=0;return function(){var r=s(),n=16-(r-i);if(i=r,n>0){if(++e>=800)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}(a)},81121:(t,e,i)=>{"use strict";i.d(e,{A:()=>n});var r=Function.prototype.toString;const n=function(t){if(null!=t){try{return r.call(t)}catch(e){}try{return t+""}catch(e){}}return""}},39142:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){return function(){return t}}},66984:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t,e){return t===e||t!=t&&e!=e}},29008:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){return t}},52274:(t,e,i)=>{"use strict";i.d(e,{A:()=>c});var r=i(88496),n=i(53098);const o=function(t){return(0,n.A)(t)&&"[object Arguments]"==(0,r.A)(t)};var a=Object.prototype,s=a.hasOwnProperty,l=a.propertyIsEnumerable;const c=o(function(){return arguments}())?o:function(t){return(0,n.A)(t)&&s.call(t,"callee")&&!l.call(t,"callee")}},92049:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=Array.isArray},38446:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(89610),n=i(5254);const o=function(t){return null!=t&&(0,n.A)(t.length)&&!(0,r.A)(t)}},53533:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(38446),n=i(53098);const o=function(t){return(0,n.A)(t)&&(0,r.A)(t)}},99912:(t,e,i)=>{"use strict";i.d(e,{A:()=>l});var r=i(41917);const n=function(){return!1};var o="object"==typeof exports&&exports&&!exports.nodeType&&exports,a=o&&"object"==typeof module&&module&&!module.nodeType&&module,s=a&&a.exports===o?r.A.Buffer:void 0;const l=(s?s.isBuffer:void 0)||n},66401:(t,e,i)=>{"use strict";i.d(e,{A:()=>d});var r=i(69471),n=i(9779),o=i(52274),a=i(92049),s=i(38446),l=i(99912),c=i(97271),h=i(33858),u=Object.prototype.hasOwnProperty;const d=function(t){if(null==t)return!0;if((0,s.A)(t)&&((0,a.A)(t)||"string"==typeof t||"function"==typeof t.splice||(0,l.A)(t)||(0,h.A)(t)||(0,o.A)(t)))return!t.length;var e=(0,n.A)(t);if("[object Map]"==e||"[object Set]"==e)return!t.size;if((0,c.A)(t))return!(0,r.A)(t).length;for(var i in t)if(u.call(t,i))return!1;return!0}},89610:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(88496),n=i(23149);const o=function(t){if(!(0,n.A)(t))return!1;var e=(0,r.A)(t);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e}},5254:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=9007199254740991}},23149:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},53098:(t,e,i)=>{"use strict";i.d(e,{A:()=>r});const r=function(t){return null!=t&&"object"==typeof t}},34963:(t,e,i)=>{"use strict";i.d(e,{A:()=>u});var r=i(88496),n=i(15647),o=i(53098),a=Function.prototype,s=Object.prototype,l=a.toString,c=s.hasOwnProperty,h=l.call(Object);const u=function(t){if(!(0,o.A)(t)||"[object Object]"!=(0,r.A)(t))return!1;var e=(0,n.A)(t);if(null===e)return!0;var i=c.call(e,"constructor")&&e.constructor;return"function"==typeof i&&i instanceof i&&l.call(i)==h}},33858:(t,e,i)=>{"use strict";i.d(e,{A:()=>u});var r=i(88496),n=i(5254),o=i(53098),a={};a["[object Float32Array]"]=a["[object Float64Array]"]=a["[object Int8Array]"]=a["[object Int16Array]"]=a["[object Int32Array]"]=a["[object Uint8Array]"]=a["[object Uint8ClampedArray]"]=a["[object Uint16Array]"]=a["[object Uint32Array]"]=!0,a["[object Arguments]"]=a["[object Array]"]=a["[object ArrayBuffer]"]=a["[object Boolean]"]=a["[object DataView]"]=a["[object Date]"]=a["[object Error]"]=a["[object Function]"]=a["[object Map]"]=a["[object Number]"]=a["[object Object]"]=a["[object RegExp]"]=a["[object Set]"]=a["[object String]"]=a["[object WeakMap]"]=!1;const s=function(t){return(0,o.A)(t)&&(0,n.A)(t.length)&&!!a[(0,r.A)(t)]};var l=i(52789),c=i(64841),h=c.A&&c.A.isTypedArray;const u=h?(0,l.A)(h):s},55615:(t,e,i)=>{"use strict";i.d(e,{A:()=>h});var r=i(83607),n=i(23149),o=i(97271);const a=function(t){var e=[];if(null!=t)for(var i in Object(t))e.push(i);return e};var s=Object.prototype.hasOwnProperty;const l=function(t){if(!(0,n.A)(t))return a(t);var e=(0,o.A)(t),i=[];for(var r in t)("constructor"!=r||!e&&s.call(t,r))&&i.push(r);return i};var c=i(38446);const h=function(t){return(0,c.A)(t)?(0,r.A)(t,!0):l(t)}},46632:(t,e,i)=>{"use strict";i.d(e,{A:()=>o});var r=i(29471);function n(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new TypeError("Expected a function");var i=function(){var r=arguments,n=e?e.apply(this,r):r[0],o=i.cache;if(o.has(n))return o.get(n);var a=t.apply(this,r);return i.cache=o.set(n,a)||o,a};return i.cache=new(n.Cache||r.A),i}n.Cache=r.A;const o=n},98879:(t,e,i)=>{"use strict";i.d(e,{A:()=>B});var r=i(11754),n=i(52528),o=i(66984);const a=function(t,e,i){(void 0!==i&&!(0,o.A)(t[e],i)||void 0===i&&!(e in t))&&(0,n.A)(t,e,i)};var s=i(4574),l=i(80154),c=i(1801),h=i(39759),u=i(18598),d=i(52274),f=i(92049),p=i(53533),g=i(99912),m=i(89610),y=i(23149),x=i(34963),C=i(33858);const b=function(t,e){if(("constructor"!==e||"function"!=typeof t[e])&&"__proto__"!=e)return t[e]};var _=i(22031),v=i(55615);const k=function(t){return(0,_.A)(t,(0,v.A)(t))};const T=function(t,e,i,r,n,o,s){var _=b(t,i),v=b(e,i),T=s.get(v);if(T)a(t,i,T);else{var A=o?o(_,v,i+"",t,e,s):void 0,w=void 0===A;if(w){var S=(0,f.A)(v),B=!S&&(0,g.A)(v),F=!S&&!B&&(0,C.A)(v);A=v,S||B||F?(0,f.A)(_)?A=_:(0,p.A)(_)?A=(0,h.A)(_):B?(w=!1,A=(0,l.A)(v,!0)):F?(w=!1,A=(0,c.A)(v,!0)):A=[]:(0,x.A)(v)||(0,d.A)(v)?(A=_,(0,d.A)(_)?A=k(_):(0,y.A)(_)&&!(0,m.A)(_)||(A=(0,u.A)(v))):w=!1}w&&(s.set(v,A),n(A,v,r,o,s),s.delete(v)),a(t,i,A)}};const A=function t(e,i,n,o,l){e!==i&&(0,s.A)(i,(function(s,c){if(l||(l=new r.A),(0,y.A)(s))T(e,i,c,n,t,o,l);else{var h=o?o(b(e,c),s,c+"",e,i,l):void 0;void 0===h&&(h=s),a(e,c,h)}}),v.A)};var w=i(24326),S=i(6832);const B=function(t){return(0,w.A)((function(e,i){var r=-1,n=i.length,o=n>1?i[n-1]:void 0,a=n>2?i[2]:void 0;for(o=t.length>3&&"function"==typeof o?(n--,o):void 0,a&&(0,S.A)(i[0],i[1],a)&&(o=n<3?void 0:o,n=1),e=Object(e);++r<n;){var s=i[r];s&&t(e,s,r,o)}return e}))}((function(t,e,i){A(t,e,i)}))},76257:(t,e,i)=>{"use strict";i.d(e,{A:()=>Hi,B:()=>Rt,C:()=>ve,D:()=>_e,E:()=>Ot,F:()=>Oe,G:()=>Tt,H:()=>At,I:()=>ue,J:()=>ht,K:()=>qi,L:()=>Ni,M:()=>Te,N:()=>co,Z:()=>ee,a:()=>Li,b:()=>Fi,c:()=>Ii,d:()=>pt,e:()=>St,f:()=>te,g:()=>Bi,h:()=>ye,i:()=>xi,j:()=>me,k:()=>ce,l:()=>st,m:()=>yt,n:()=>oe,o:()=>Ci,p:()=>Di,q:()=>Mi,r:()=>wt,s:()=>Si,t:()=>Ei,u:()=>ke,v:()=>wi,w:()=>pe,x:()=>xt,y:()=>de,z:()=>zi});var r=i(60513),n=i(74353),o=i(16750),a=i(26312),s=i(42838),l=i(74886),c=i(8232);const h=(t,e)=>{const i=l.A.parse(t),r={};for(const n in e)e[n]&&(r[n]=i[n]+e[n]);return(0,c.A)(t,r)};var u=i(25582);const d=(t,e,i=50)=>{const{r:r,g:n,b:o,a:a}=l.A.parse(t),{r:s,g:c,b:h,a:d}=l.A.parse(e),f=i/100,p=2*f-1,g=a-d,m=((p*g==-1?p:(p+g)/(1+p*g))+1)/2,y=1-m,x=r*m+s*y,C=n*m+c*y,b=o*m+h*y,_=a*f+d*(1-f);return(0,u.A)(x,C,b,_)},f=(t,e=100)=>{const i=l.A.parse(t);return i.r=255-i.r,i.g=255-i.g,i.b=255-i.b,d(i,t,e)};var p=i(75263),g=i(78041),m=i(3219),y=i(46632),x=i(98879),C="comm",b="rule",_="decl",v=Math.abs,k=String.fromCharCode;Object.assign;function T(t){return t.trim()}function A(t,e,i){return t.replace(e,i)}function w(t,e,i){return t.indexOf(e,i)}function S(t,e){return 0|t.charCodeAt(e)}function B(t,e,i){return t.slice(e,i)}function F(t){return t.length}function L(t,e){return e.push(t),t}function M(t,e){for(var i="",r=0;r<t.length;r++)i+=e(t[r],r,t,e)||"";return i}function E(t,e,i,r){switch(t.type){case"@layer":if(t.children.length)break;case"@import":case _:return t.return=t.return||t.value;case C:return"";case"@keyframes":return t.return=t.value+"{"+M(t.children,r)+"}";case b:if(!F(t.value=t.props.join(",")))return""}return F(i=M(t.children,r))?t.return=t.value+"{"+i+"}":""}var N=1,O=1,j=0,I=0,D=0,q="";function $(t,e,i,r,n,o,a,s){return{value:t,root:e,parent:i,type:r,props:n,children:o,line:N,column:O,length:a,return:"",siblings:s}}function z(){return D=I>0?S(q,--I):0,O--,10===D&&(O=1,N--),D}function P(){return D=I<j?S(q,I++):0,O++,10===D&&(O=1,N++),D}function R(){return S(q,I)}function W(){return I}function U(t,e){return B(q,t,e)}function H(t){switch(t){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}function Y(t){return N=O=1,j=F(q=t),I=0,[]}function V(t){return q="",t}function G(t){return T(U(I-1,J(91===t?t+2:40===t?t+1:t)))}function X(t){for(;(D=R())&&D<33;)P();return H(t)>2||H(D)>3?"":" "}function Z(t,e){for(;--e&&P()&&!(D<48||D>102||D>57&&D<65||D>70&&D<97););return U(t,W()+(e<6&&32==R()&&32==P()))}function J(t){for(;P();)switch(D){case t:return I;case 34:case 39:34!==t&&39!==t&&J(D);break;case 40:41===t&&J(t);break;case 92:P()}return I}function Q(t,e){for(;P()&&t+D!==57&&(t+D!==84||47!==R()););return"/*"+U(e,I-1)+"*"+k(47===t?t:P())}function K(t){for(;!H(R());)P();return U(t,I)}function tt(t){return V(et("",null,null,null,[""],t=Y(t),0,[0],t))}function et(t,e,i,r,n,o,a,s,l){for(var c=0,h=0,u=a,d=0,f=0,p=0,g=1,m=1,y=1,x=0,C="",b=n,_=o,T=r,B=C;m;)switch(p=x,x=P()){case 40:if(108!=p&&58==S(B,u-1)){-1!=w(B+=A(G(x),"&","&\f"),"&\f",v(c?s[c-1]:0))&&(y=-1);break}case 34:case 39:case 91:B+=G(x);break;case 9:case 10:case 13:case 32:B+=X(p);break;case 92:B+=Z(W()-1,7);continue;case 47:switch(R()){case 42:case 47:L(rt(Q(P(),W()),e,i,l),l);break;default:B+="/"}break;case 123*g:s[c++]=F(B)*y;case 125*g:case 59:case 0:switch(x){case 0:case 125:m=0;case 59+h:-1==y&&(B=A(B,/\f/g,"")),f>0&&F(B)-u&&L(f>32?nt(B+";",r,i,u-1,l):nt(A(B," ","")+";",r,i,u-2,l),l);break;case 59:B+=";";default:if(L(T=it(B,e,i,c,h,n,s,C,b=[],_=[],u,o),o),123===x)if(0===h)et(B,e,T,T,b,o,u,s,_);else switch(99===d&&110===S(B,3)?100:d){case 100:case 108:case 109:case 115:et(t,T,T,r&&L(it(t,T,T,0,0,n,s,C,n,b=[],u,_),_),n,_,u,s,r?b:_);break;default:et(B,T,T,T,[""],_,0,s,_)}}c=h=f=0,g=y=1,C=B="",u=a;break;case 58:u=1+F(B),f=p;default:if(g<1)if(123==x)--g;else if(125==x&&0==g++&&125==z())continue;switch(B+=k(x),x*g){case 38:y=h>0?1:(B+="\f",-1);break;case 44:s[c++]=(F(B)-1)*y,y=1;break;case 64:45===R()&&(B+=G(P())),d=R(),h=u=F(C=B+=K(W())),x++;break;case 45:45===p&&2==F(B)&&(g=0)}}return o}function it(t,e,i,r,n,o,a,s,l,c,h,u){for(var d=n-1,f=0===n?o:[""],p=function(t){return t.length}(f),g=0,m=0,y=0;g<r;++g)for(var x=0,C=B(t,d+1,d=v(m=a[g])),_=t;x<p;++x)(_=T(m>0?f[x]+" "+C:A(C,/&\f/g,f[x])))&&(l[y++]=_);return $(t,e,i,0===n?b:s,l,c,h,u)}function rt(t,e,i,r){return $(t,e,i,C,k(D),B(t,2,-2),0,r)}function nt(t,e,i,r,n){return $(t,e,i,_,B(t,0,r),B(t,r+1,-1),r,n)}var ot=i(66401);const at={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},st={trace:(...t)=>{},debug:(...t)=>{},info:(...t)=>{},warn:(...t)=>{},error:(...t)=>{},fatal:(...t)=>{}},lt=function(t="fatal"){let e=at.fatal;"string"==typeof t?(t=t.toLowerCase())in at&&(e=at[t]):"number"==typeof t&&(e=t),st.trace=()=>{},st.debug=()=>{},st.info=()=>{},st.warn=()=>{},st.error=()=>{},st.fatal=()=>{},e<=at.fatal&&(st.fatal=console.error?console.error.bind(console,ct("FATAL"),"color: orange"):console.log.bind(console,"\x1b[35m",ct("FATAL"))),e<=at.error&&(st.error=console.error?console.error.bind(console,ct("ERROR"),"color: orange"):console.log.bind(console,"\x1b[31m",ct("ERROR"))),e<=at.warn&&(st.warn=console.warn?console.warn.bind(console,ct("WARN"),"color: orange"):console.log.bind(console,"\x1b[33m",ct("WARN"))),e<=at.info&&(st.info=console.info?console.info.bind(console,ct("INFO"),"color: lightblue"):console.log.bind(console,"\x1b[34m",ct("INFO"))),e<=at.debug&&(st.debug=console.debug?console.debug.bind(console,ct("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",ct("DEBUG"))),e<=at.trace&&(st.trace=console.debug?console.debug.bind(console,ct("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",ct("TRACE")))},ct=t=>`%c${n().format("ss.SSS")} : ${t} : `,ht=/<br\s*\/?>/gi,ut=(()=>{let t=!1;return()=>{t||(!function(){const t="data-temp-href-target";s.addHook("beforeSanitizeAttributes",(e=>{"A"===e.tagName&&e.hasAttribute("target")&&e.setAttribute(t,e.getAttribute("target")||"")})),s.addHook("afterSanitizeAttributes",(e=>{"A"===e.tagName&&e.hasAttribute(t)&&(e.setAttribute("target",e.getAttribute(t)||""),e.removeAttribute(t),"_blank"===e.getAttribute("target")&&e.setAttribute("rel","noopener"))}))}(),t=!0)}})();const dt=t=>{ut();return s.sanitize(t)},ft=(t,e)=>{var i;if(!1!==(null==(i=e.flowchart)?void 0:i.htmlLabels)){const i=e.securityLevel;"antiscript"===i||"strict"===i?t=dt(t):"loose"!==i&&(t=(t=(t=mt(t)).replace(/</g,"<").replace(/>/g,">")).replace(/=/g,"="),t=gt(t))}return t},pt=(t,e)=>t?t=e.dompurifyConfig?s.sanitize(ft(t,e),e.dompurifyConfig).toString():s.sanitize(ft(t,e),{FORBID_TAGS:["style"]}).toString():t,gt=t=>t.replace(/#br#/g,"<br/>"),mt=t=>t.replace(ht,"#br#"),yt=t=>!1!==t&&!["false","null","0"].includes(String(t).trim().toLowerCase()),xt=function(t){const e=t.split(/(,)/),i=[];for(let r=0;r<e.length;r++){let t=e[r];if(","===t&&r>0&&r+1<e.length){const n=e[r-1],o=e[r+1];bt(n,o)&&(t=n+","+o,r++,i.pop())}i.push(_t(t))}return i.join("")},Ct=(t,e)=>Math.max(0,t.split(e).length-1),bt=(t,e)=>{const i=Ct(t,"~"),r=Ct(e,"~");return 1===i&&1===r},_t=t=>{const e=Ct(t,"~");let i=!1;if(e<=1)return t;e%2!=0&&t.startsWith("~")&&(t=t.substring(1),i=!0);const r=[...t];let n=r.indexOf("~"),o=r.lastIndexOf("~");for(;-1!==n&&-1!==o&&n!==o;)r[n]="<",r[o]=">",n=r.indexOf("~"),o=r.lastIndexOf("~");return i&&r.unshift("~"),r.join("")},vt=()=>void 0!==window.MathMLElement,kt=/\$\$(.*)\$\$/g,Tt=t=>{var e;return((null==(e=t.match(kt))?void 0:e.length)??0)>0},At=async(t,e)=>{t=await wt(t,e);const i=document.createElement("div");i.innerHTML=t,i.id="katex-temp",i.style.visibility="hidden",i.style.position="absolute",i.style.top="0";const r=document.querySelector("body");null==r||r.insertAdjacentElement("beforeend",i);const n={width:i.clientWidth,height:i.clientHeight};return i.remove(),n},wt=async(t,e)=>{if(!Tt(t))return t;if(!vt()&&!e.legacyMathML)return t.replace(kt,"MathML is unsupported in this environment.");const{default:r}=await i.e(2130).then(i.bind(i,22130));return t.split(ht).map((t=>Tt(t)?`\n <div style="display: flex; align-items: center; justify-content: center; white-space: nowrap;">\n ${t}\n </div>\n `:`<div>${t}</div>`)).join("").replace(kt,((t,e)=>r.renderToString(e,{throwOnError:!0,displayMode:!0,output:vt()?"mathml":"htmlAndMathml"}).replace(/\n/g," ").replace(/<annotation.*<\/annotation>/g,"")))},St={getRows:t=>{if(!t)return[""];return mt(t).replace(/\\n/g,"#br#").split("#br#")},sanitizeText:pt,sanitizeTextOrArray:(t,e)=>"string"==typeof t?pt(t,e):t.flat().map((t=>pt(t,e))),hasBreaks:t=>ht.test(t),splitBreaks:t=>t.split(ht),lineBreakRegex:ht,removeScript:dt,getUrl:t=>{let e="";return t&&(e=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,e=e.replaceAll(/\(/g,"\\("),e=e.replaceAll(/\)/g,"\\)")),e},evaluate:yt,getMax:function(...t){const e=t.filter((t=>!isNaN(t)));return Math.max(...e)},getMin:function(...t){const e=t.filter((t=>!isNaN(t)));return Math.min(...e)}},Bt=(t,e)=>h(t,e?{s:-40,l:10}:{s:-40,l:-10}),Ft="#ffffff",Lt="#f2f2f2";let Mt=class{constructor(){this.background="#f4f4f4",this.primaryColor="#fff4dd",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px"}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||h(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||h(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||Bt(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||Bt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||Bt(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||Bt(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||f(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||f(this.tertiaryColor),this.lineColor=this.lineColor||f(this.background),this.arrowheadColor=this.arrowheadColor||f(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?(0,p.A)(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||"grey",this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||(0,p.A)(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||f(this.lineColor),this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||(0,g.A)(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||this.tertiaryColor,this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||h(this.primaryColor,{h:30}),this.cScale4=this.cScale4||h(this.primaryColor,{h:60}),this.cScale5=this.cScale5||h(this.primaryColor,{h:90}),this.cScale6=this.cScale6||h(this.primaryColor,{h:120}),this.cScale7=this.cScale7||h(this.primaryColor,{h:150}),this.cScale8=this.cScale8||h(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||h(this.primaryColor,{h:270}),this.cScale10=this.cScale10||h(this.primaryColor,{h:300}),this.cScale11=this.cScale11||h(this.primaryColor,{h:330}),this.darkMode)for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScale"+h]=(0,p.A)(this["cScale"+h],75);else for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScale"+h]=(0,p.A)(this["cScale"+h],25);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleInv"+h]=this["cScaleInv"+h]||f(this["cScale"+h]);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this.darkMode?this["cScalePeer"+h]=this["cScalePeer"+h]||(0,g.A)(this["cScale"+h],10):this["cScalePeer"+h]=this["cScalePeer"+h]||(0,p.A)(this["cScale"+h],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleLabel"+h]=this["cScaleLabel"+h]||this.scaleLabelColor;const d=this.darkMode?-4:-1;for(let f=0;f<5;f++)this["surface"+f]=this["surface"+f]||h(this.mainBkg,{h:180,s:-15,l:d*(5+3*f)}),this["surfacePeer"+f]=this["surfacePeer"+f]||h(this.mainBkg,{h:180,s:-15,l:d*(8+3*f)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||this.primaryColor,this.fillType1=this.fillType1||this.secondaryColor,this.fillType2=this.fillType2||h(this.primaryColor,{h:64}),this.fillType3=this.fillType3||h(this.secondaryColor,{h:64}),this.fillType4=this.fillType4||h(this.primaryColor,{h:-64}),this.fillType5=this.fillType5||h(this.secondaryColor,{h:-64}),this.fillType6=this.fillType6||h(this.primaryColor,{h:128}),this.fillType7=this.fillType7||h(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||h(this.primaryColor,{l:-10}),this.pie5=this.pie5||h(this.secondaryColor,{l:-10}),this.pie6=this.pie6||h(this.tertiaryColor,{l:-10}),this.pie7=this.pie7||h(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||h(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||h(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||h(this.primaryColor,{h:60,l:-20}),this.pie11=this.pie11||h(this.primaryColor,{h:-60,l:-20}),this.pie12=this.pie12||h(this.primaryColor,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.A)(this.quadrant1Fill)?(0,g.A)(this.quadrant1Fill):(0,p.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?(0,p.A)(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||h(this.primaryColor,{h:-30}),this.git4=this.git4||h(this.primaryColor,{h:-60}),this.git5=this.git5||h(this.primaryColor,{h:-90}),this.git6=this.git6||h(this.primaryColor,{h:60}),this.git7=this.git7||h(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,g.A)(this.git0,25),this.git1=(0,g.A)(this.git1,25),this.git2=(0,g.A)(this.git2,25),this.git3=(0,g.A)(this.git3,25),this.git4=(0,g.A)(this.git4,25),this.git5=(0,g.A)(this.git5,25),this.git6=(0,g.A)(this.git6,25),this.git7=(0,g.A)(this.git7,25)):(this.git0=(0,p.A)(this.git0,25),this.git1=(0,p.A)(this.git1,25),this.git2=(0,p.A)(this.git2,25),this.git3=(0,p.A)(this.git3,25),this.git4=(0,p.A)(this.git4,25),this.git5=(0,p.A)(this.git5,25),this.git6=(0,p.A)(this.git6,25),this.git7=(0,p.A)(this.git7,25)),this.gitInv0=this.gitInv0||f(this.git0),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||Ft,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Lt}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};let Et=class{constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=(0,g.A)(this.primaryColor,16),this.tertiaryColor=h(this.primaryColor,{h:-160}),this.primaryBorderColor=f(this.background),this.secondaryBorderColor=Bt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Bt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.tertiaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=(0,g.A)(f("#323D47"),10),this.lineColor="calculated",this.border1="#81B1DB",this.border2=(0,u.A)(255,255,255,.25),this.arrowheadColor="calculated",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#F9FFFE",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="calculated",this.activationBkgColor="calculated",this.sequenceNumberColor="black",this.sectionBkgColor=(0,p.A)("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.excludeBkgColor=(0,p.A)(this.sectionBkgColor,10),this.taskBorderColor=(0,u.A)(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=(0,u.A)(255,255,255,50),this.activeTaskBkgColor="#81B1DB",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="grey",this.critBorderColor="#E83737",this.critBkgColor="#E83737",this.taskTextDarkColor="calculated",this.todayLineColor="#DB5757",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd"}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;this.secondBkg=(0,g.A)(this.mainBkg,16),this.lineColor=this.mainContrastColor,this.arrowheadColor=this.mainContrastColor,this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.edgeLabelBackground=(0,g.A)(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.mainContrastColor,this.signalColor=this.mainContrastColor,this.signalTextColor=this.mainContrastColor,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.mainContrastColor,this.loopTextColor=this.mainContrastColor,this.noteBorderColor=this.secondaryBorderColor,this.noteBkgColor=this.secondBkg,this.noteTextColor=this.secondaryTextColor,this.activationBorderColor=this.border1,this.activationBkgColor=this.secondBkg,this.altSectionBkgColor=this.background,this.taskBkgColor=(0,g.A)(this.mainBkg,23),this.taskTextColor=this.darkTextColor,this.taskTextLightColor=this.mainContrastColor,this.taskTextOutsideColor=this.taskTextLightColor,this.gridColor=this.mainContrastColor,this.doneTaskBkgColor=this.mainContrastColor,this.taskTextDarkColor=this.darkTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#555",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#f4f4f4",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=h(this.primaryColor,{h:64}),this.fillType3=h(this.secondaryColor,{h:64}),this.fillType4=h(this.primaryColor,{h:-64}),this.fillType5=h(this.secondaryColor,{h:-64}),this.fillType6=h(this.primaryColor,{h:128}),this.fillType7=h(this.secondaryColor,{h:128}),this.cScale1=this.cScale1||"#0b0000",this.cScale2=this.cScale2||"#4d1037",this.cScale3=this.cScale3||"#3f5258",this.cScale4=this.cScale4||"#4f2f1b",this.cScale5=this.cScale5||"#6e0a0a",this.cScale6=this.cScale6||"#3b0048",this.cScale7=this.cScale7||"#995a01",this.cScale8=this.cScale8||"#154706",this.cScale9=this.cScale9||"#161722",this.cScale10=this.cScale10||"#00296f",this.cScale11=this.cScale11||"#01629c",this.cScale12=this.cScale12||"#010029",this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||h(this.primaryColor,{h:30}),this.cScale4=this.cScale4||h(this.primaryColor,{h:60}),this.cScale5=this.cScale5||h(this.primaryColor,{h:90}),this.cScale6=this.cScale6||h(this.primaryColor,{h:120}),this.cScale7=this.cScale7||h(this.primaryColor,{h:150}),this.cScale8=this.cScale8||h(this.primaryColor,{h:210}),this.cScale9=this.cScale9||h(this.primaryColor,{h:270}),this.cScale10=this.cScale10||h(this.primaryColor,{h:300}),this.cScale11=this.cScale11||h(this.primaryColor,{h:330});for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleInv"+h]=this["cScaleInv"+h]||f(this["cScale"+h]);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScalePeer"+h]=this["cScalePeer"+h]||(0,g.A)(this["cScale"+h],10);for(let d=0;d<5;d++)this["surface"+d]=this["surface"+d]||h(this.mainBkg,{h:30,s:-30,l:-(4*d-10)}),this["surfacePeer"+d]=this["surfacePeer"+d]||h(this.mainBkg,{h:30,s:-30,l:-(4*d-7)});this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleLabel"+h]=this["cScaleLabel"+h]||this.scaleLabelColor;for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["pie"+h]=this["cScale"+h];this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.A)(this.quadrant1Fill)?(0,g.A)(this.quadrant1Fill):(0,p.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#3498db,#2ecc71,#e74c3c,#f1c40f,#bdc3c7,#ffffff,#34495e,#9b59b6,#1abc9c,#e67e22"},this.classText=this.primaryTextColor,this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?(0,p.A)(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=(0,g.A)(this.secondaryColor,20),this.git1=(0,g.A)(this.pie2||this.secondaryColor,20),this.git2=(0,g.A)(this.pie3||this.tertiaryColor,20),this.git3=(0,g.A)(this.pie4||h(this.primaryColor,{h:-30}),20),this.git4=(0,g.A)(this.pie5||h(this.primaryColor,{h:-60}),20),this.git5=(0,g.A)(this.pie6||h(this.primaryColor,{h:-90}),10),this.git6=(0,g.A)(this.pie7||h(this.primaryColor,{h:60}),10),this.git7=(0,g.A)(this.pie8||h(this.primaryColor,{h:120}),20),this.gitInv0=this.gitInv0||f(this.git0),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||f(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||f(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||(0,g.A)(this.background,12),this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||(0,g.A)(this.background,2)}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};let Nt=class{constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=h(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=h(this.primaryColor,{h:-160}),this.primaryBorderColor=Bt(this.primaryColor,this.darkMode),this.secondaryBorderColor=Bt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Bt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.tertiaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.background="white",this.mainBkg="#ECECFF",this.secondBkg="#ffffde",this.lineColor="#333333",this.border1="#9370DB",this.border2="#aaaa33",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#e8e8e8",this.textColor="#333",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="grey",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="calculated",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="calculated",this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor="calculated",this.taskTextOutsideColor=this.taskTextDarkColor,this.taskTextClickableColor="calculated",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBorderColor="calculated",this.critBkgColor="calculated",this.todayLineColor="calculated",this.sectionBkgColor=(0,u.A)(102,102,255,.49),this.altSectionBkgColor="white",this.sectionBkgColor2="#fff400",this.taskBorderColor="#534fbc",this.taskBkgColor="#8a90dd",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="#534fbc",this.activeTaskBkgColor="#bfc7ff",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.updateColors()}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||h(this.primaryColor,{h:30}),this.cScale4=this.cScale4||h(this.primaryColor,{h:60}),this.cScale5=this.cScale5||h(this.primaryColor,{h:90}),this.cScale6=this.cScale6||h(this.primaryColor,{h:120}),this.cScale7=this.cScale7||h(this.primaryColor,{h:150}),this.cScale8=this.cScale8||h(this.primaryColor,{h:210}),this.cScale9=this.cScale9||h(this.primaryColor,{h:270}),this.cScale10=this.cScale10||h(this.primaryColor,{h:300}),this.cScale11=this.cScale11||h(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||(0,p.A)(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||(0,p.A)(this.tertiaryColor,40);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScale"+h]=(0,p.A)(this["cScale"+h],10),this["cScalePeer"+h]=this["cScalePeer"+h]||(0,p.A)(this["cScale"+h],25);for(let d=0;d<this.THEME_COLOR_LIMIT;d++)this["cScaleInv"+d]=this["cScaleInv"+d]||h(this["cScale"+d],{h:180});for(let d=0;d<5;d++)this["surface"+d]=this["surface"+d]||h(this.mainBkg,{h:30,l:-(5+5*d)}),this["surfacePeer"+d]=this["surfacePeer"+d]||h(this.mainBkg,{h:30,l:-(7+5*d)});if(this.scaleLabelColor="calculated"!==this.scaleLabelColor&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor,"calculated"!==this.labelTextColor){this.cScaleLabel0=this.cScaleLabel0||f(this.labelTextColor),this.cScaleLabel3=this.cScaleLabel3||f(this.labelTextColor);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.labelTextColor}this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.textColor,this.edgeLabelBackground=this.labelBackground,this.actorBorder=(0,g.A)(this.border1,23),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.signalColor=this.textColor,this.signalTextColor=this.textColor,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=h(this.primaryColor,{h:64}),this.fillType3=h(this.secondaryColor,{h:64}),this.fillType4=h(this.primaryColor,{h:-64}),this.fillType5=h(this.secondaryColor,{h:-64}),this.fillType6=h(this.primaryColor,{h:128}),this.fillType7=h(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||h(this.tertiaryColor,{l:-40}),this.pie4=this.pie4||h(this.primaryColor,{l:-10}),this.pie5=this.pie5||h(this.secondaryColor,{l:-30}),this.pie6=this.pie6||h(this.tertiaryColor,{l:-20}),this.pie7=this.pie7||h(this.primaryColor,{h:60,l:-20}),this.pie8=this.pie8||h(this.primaryColor,{h:-60,l:-40}),this.pie9=this.pie9||h(this.primaryColor,{h:120,l:-40}),this.pie10=this.pie10||h(this.primaryColor,{h:60,l:-40}),this.pie11=this.pie11||h(this.primaryColor,{h:-90,l:-40}),this.pie12=this.pie12||h(this.primaryColor,{h:120,l:-30}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.A)(this.quadrant1Fill)?(0,g.A)(this.quadrant1Fill):(0,p.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#ECECFF,#8493A6,#FFC3A0,#DCDDE1,#B8E994,#D1A36F,#C3CDE6,#FFB6C1,#496078,#F8F3E3"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.labelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||h(this.primaryColor,{h:-30}),this.git4=this.git4||h(this.primaryColor,{h:-60}),this.git5=this.git5||h(this.primaryColor,{h:-90}),this.git6=this.git6||h(this.primaryColor,{h:60}),this.git7=this.git7||h(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,g.A)(this.git0,25),this.git1=(0,g.A)(this.git1,25),this.git2=(0,g.A)(this.git2,25),this.git3=(0,g.A)(this.git3,25),this.git4=(0,g.A)(this.git4,25),this.git5=(0,g.A)(this.git5,25),this.git6=(0,g.A)(this.git6,25),this.git7=(0,g.A)(this.git7,25)):(this.git0=(0,p.A)(this.git0,25),this.git1=(0,p.A)(this.git1,25),this.git2=(0,p.A)(this.git2,25),this.git3=(0,p.A)(this.git3,25),this.git4=(0,p.A)(this.git4,25),this.git5=(0,p.A)(this.git5,25),this.git6=(0,p.A)(this.git6,25),this.git7=(0,p.A)(this.git7,25)),this.gitInv0=this.gitInv0||(0,p.A)(f(this.git0),25),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||f(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||f(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||Ft,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Lt}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};const Ot=t=>{const e=new Nt;return e.calculate(t),e};let jt=class{constructor(){this.background="#f4f4f4",this.primaryColor="#cde498",this.secondaryColor="#cdffb2",this.background="white",this.mainBkg="#cde498",this.secondBkg="#cdffb2",this.lineColor="green",this.border1="#13540c",this.border2="#6eaa49",this.arrowheadColor="green",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.tertiaryColor=(0,g.A)("#cde498",10),this.primaryBorderColor=Bt(this.primaryColor,this.darkMode),this.secondaryBorderColor=Bt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Bt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.primaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#333",this.edgeLabelBackground="#e8e8e8",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="grey",this.signalColor="#333",this.signalTextColor="#333",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="#326932",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="#6eaa49",this.altSectionBkgColor="white",this.sectionBkgColor2="#6eaa49",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="#487e3a",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;this.actorBorder=(0,p.A)(this.mainBkg,20),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||h(this.primaryColor,{h:30}),this.cScale4=this.cScale4||h(this.primaryColor,{h:60}),this.cScale5=this.cScale5||h(this.primaryColor,{h:90}),this.cScale6=this.cScale6||h(this.primaryColor,{h:120}),this.cScale7=this.cScale7||h(this.primaryColor,{h:150}),this.cScale8=this.cScale8||h(this.primaryColor,{h:210}),this.cScale9=this.cScale9||h(this.primaryColor,{h:270}),this.cScale10=this.cScale10||h(this.primaryColor,{h:300}),this.cScale11=this.cScale11||h(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||(0,p.A)(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||(0,p.A)(this.tertiaryColor,40);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScale"+h]=(0,p.A)(this["cScale"+h],10),this["cScalePeer"+h]=this["cScalePeer"+h]||(0,p.A)(this["cScale"+h],25);for(let d=0;d<this.THEME_COLOR_LIMIT;d++)this["cScaleInv"+d]=this["cScaleInv"+d]||h(this["cScale"+d],{h:180});this.scaleLabelColor="calculated"!==this.scaleLabelColor&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor;for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleLabel"+h]=this["cScaleLabel"+h]||this.scaleLabelColor;for(let d=0;d<5;d++)this["surface"+d]=this["surface"+d]||h(this.mainBkg,{h:30,s:-30,l:-(5+5*d)}),this["surfacePeer"+d]=this["surfacePeer"+d]||h(this.mainBkg,{h:30,s:-30,l:-(8+5*d)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.taskBorderColor=this.border1,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=h(this.primaryColor,{h:64}),this.fillType3=h(this.secondaryColor,{h:64}),this.fillType4=h(this.primaryColor,{h:-64}),this.fillType5=h(this.secondaryColor,{h:-64}),this.fillType6=h(this.primaryColor,{h:128}),this.fillType7=h(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||h(this.primaryColor,{l:-30}),this.pie5=this.pie5||h(this.secondaryColor,{l:-30}),this.pie6=this.pie6||h(this.tertiaryColor,{h:40,l:-40}),this.pie7=this.pie7||h(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||h(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||h(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||h(this.primaryColor,{h:60,l:-50}),this.pie11=this.pie11||h(this.primaryColor,{h:-60,l:-50}),this.pie12=this.pie12||h(this.primaryColor,{h:120,l:-50}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.A)(this.quadrant1Fill)?(0,g.A)(this.quadrant1Fill):(0,p.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#CDE498,#FF6B6B,#A0D2DB,#D7BDE2,#F0F0F0,#FFC3A0,#7FD8BE,#FF9A8B,#FAF3E0,#FFF176"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||h(this.primaryColor,{h:-30}),this.git4=this.git4||h(this.primaryColor,{h:-60}),this.git5=this.git5||h(this.primaryColor,{h:-90}),this.git6=this.git6||h(this.primaryColor,{h:60}),this.git7=this.git7||h(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,g.A)(this.git0,25),this.git1=(0,g.A)(this.git1,25),this.git2=(0,g.A)(this.git2,25),this.git3=(0,g.A)(this.git3,25),this.git4=(0,g.A)(this.git4,25),this.git5=(0,g.A)(this.git5,25),this.git6=(0,g.A)(this.git6,25),this.git7=(0,g.A)(this.git7,25)):(this.git0=(0,p.A)(this.git0,25),this.git1=(0,p.A)(this.git1,25),this.git2=(0,p.A)(this.git2,25),this.git3=(0,p.A)(this.git3,25),this.git4=(0,p.A)(this.git4,25),this.git5=(0,p.A)(this.git5,25),this.git6=(0,p.A)(this.git6,25),this.git7=(0,p.A)(this.git7,25)),this.gitInv0=this.gitInv0||f(this.git0),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||f(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||f(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||Ft,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Lt}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};class It{constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=(0,g.A)(this.contrast,55),this.background="#ffffff",this.tertiaryColor=h(this.primaryColor,{h:-160}),this.primaryBorderColor=Bt(this.primaryColor,this.darkMode),this.secondaryBorderColor=Bt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Bt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.tertiaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.mainBkg="#eee",this.secondBkg="calculated",this.lineColor="#666",this.border1="#999",this.border2="calculated",this.note="#ffa",this.text="#333",this.critical="#d42",this.done="#bbb",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="white",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="calculated",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="white",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBkgColor="calculated",this.critBorderColor="calculated",this.todayLineColor="calculated",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;this.secondBkg=(0,g.A)(this.contrast,55),this.border2=this.contrast,this.actorBorder=(0,g.A)(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.lineColor,this.signalColor=this.text,this.signalTextColor=this.text,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.text,this.loopTextColor=this.text,this.noteBorderColor="#999",this.noteBkgColor="#666",this.noteTextColor="#fff",this.cScale0=this.cScale0||"#555",this.cScale1=this.cScale1||"#F4F4F4",this.cScale2=this.cScale2||"#555",this.cScale3=this.cScale3||"#BBB",this.cScale4=this.cScale4||"#777",this.cScale5=this.cScale5||"#999",this.cScale6=this.cScale6||"#DDD",this.cScale7=this.cScale7||"#FFF",this.cScale8=this.cScale8||"#DDD",this.cScale9=this.cScale9||"#BBB",this.cScale10=this.cScale10||"#999",this.cScale11=this.cScale11||"#777";for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleInv"+h]=this["cScaleInv"+h]||f(this["cScale"+h]);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this.darkMode?this["cScalePeer"+h]=this["cScalePeer"+h]||(0,g.A)(this["cScale"+h],10):this["cScalePeer"+h]=this["cScalePeer"+h]||(0,p.A)(this["cScale"+h],10);this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor),this.cScaleLabel0=this.cScaleLabel0||this.cScale1,this.cScaleLabel2=this.cScaleLabel2||this.cScale1;for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleLabel"+h]=this["cScaleLabel"+h]||this.scaleLabelColor;for(let d=0;d<5;d++)this["surface"+d]=this["surface"+d]||h(this.mainBkg,{l:-(5+5*d)}),this["surfacePeer"+d]=this["surfacePeer"+d]||h(this.mainBkg,{l:-(8+5*d)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.text,this.sectionBkgColor=(0,g.A)(this.contrast,30),this.sectionBkgColor2=(0,g.A)(this.contrast,30),this.taskBorderColor=(0,p.A)(this.contrast,10),this.taskBkgColor=this.contrast,this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor=this.text,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.gridColor=(0,g.A)(this.border1,30),this.doneTaskBkgColor=this.done,this.doneTaskBorderColor=this.lineColor,this.critBkgColor=this.critical,this.critBorderColor=(0,p.A)(this.critBkgColor,10),this.todayLineColor=this.critBkgColor,this.transitionColor=this.transitionColor||"#000",this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f4f4f4",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.stateBorder=this.stateBorder||"#000",this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#222",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=h(this.primaryColor,{h:64}),this.fillType3=h(this.secondaryColor,{h:64}),this.fillType4=h(this.primaryColor,{h:-64}),this.fillType5=h(this.secondaryColor,{h:-64}),this.fillType6=h(this.primaryColor,{h:128}),this.fillType7=h(this.secondaryColor,{h:128});for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["pie"+h]=this["cScale"+h];this.pie12=this.pie0,this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.A)(this.quadrant1Fill)?(0,g.A)(this.quadrant1Fill):(0,p.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#EEE,#6BB8E4,#8ACB88,#C7ACD6,#E8DCC2,#FFB2A8,#FFF380,#7E8D91,#FFD8B1,#FAF3E0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=(0,p.A)(this.pie1,25)||this.primaryColor,this.git1=this.pie2||this.secondaryColor,this.git2=this.pie3||this.tertiaryColor,this.git3=this.pie4||h(this.primaryColor,{h:-30}),this.git4=this.pie5||h(this.primaryColor,{h:-60}),this.git5=this.pie6||h(this.primaryColor,{h:-90}),this.git6=this.pie7||h(this.primaryColor,{h:60}),this.git7=this.pie8||h(this.primaryColor,{h:120}),this.gitInv0=this.gitInv0||f(this.git0),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.branchLabelColor=this.branchLabelColor||this.labelTextColor,this.gitBranchLabel0=this.branchLabelColor,this.gitBranchLabel1="white",this.gitBranchLabel2=this.branchLabelColor,this.gitBranchLabel3="white",this.gitBranchLabel4=this.branchLabelColor,this.gitBranchLabel5=this.branchLabelColor,this.gitBranchLabel6=this.branchLabelColor,this.gitBranchLabel7=this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||Ft,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Lt}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}}const Dt={base:{getThemeVariables:t=>{const e=new Mt;return e.calculate(t),e}},dark:{getThemeVariables:t=>{const e=new Et;return e.calculate(t),e}},default:{getThemeVariables:Ot},forest:{getThemeVariables:t=>{const e=new jt;return e.calculate(t),e}},neutral:{getThemeVariables:t=>{const e=new It;return e.calculate(t),e}}},qt={flowchart:{useMaxWidth:!0,titleTopMargin:25,subGraphTitleMargin:{top:0,bottom:0},diagramPadding:8,htmlLabels:!0,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,defaultRenderer:"dagre-wrapper",wrappingWidth:200},sequence:{useMaxWidth:!0,hideUnusedParticipants:!1,activationWidth:10,diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",mirrorActors:!0,forceMenus:!1,bottomMarginAdj:1,rightAngles:!1,showSequenceNumbers:!1,actorFontSize:14,actorFontFamily:'"Open Sans", sans-serif',actorFontWeight:400,noteFontSize:14,noteFontFamily:'"trebuchet ms", verdana, arial, sans-serif',noteFontWeight:400,noteAlign:"center",messageFontSize:16,messageFontFamily:'"trebuchet ms", verdana, arial, sans-serif',messageFontWeight:400,wrap:!1,wrapPadding:10,labelBoxWidth:50,labelBoxHeight:20},gantt:{useMaxWidth:!0,titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,axisFormat:"%Y-%m-%d",topAxis:!1,displayMode:"",weekday:"sunday"},journey:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"]},class:{useMaxWidth:!0,titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,defaultRenderer:"dagre-wrapper",htmlLabels:!1},state:{useMaxWidth:!0,titleTopMargin:25,dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,defaultRenderer:"dagre-wrapper"},er:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,stroke:"gray",fill:"honeydew",fontSize:12},pie:{useMaxWidth:!0,textPosition:.75},quadrantChart:{useMaxWidth:!0,chartWidth:500,chartHeight:500,titleFontSize:20,titlePadding:10,quadrantPadding:5,xAxisLabelPadding:5,yAxisLabelPadding:5,xAxisLabelFontSize:16,yAxisLabelFontSize:16,quadrantLabelFontSize:16,quadrantTextTopPadding:5,pointTextPadding:5,pointLabelFontSize:12,pointRadius:5,xAxisPosition:"top",yAxisPosition:"left",quadrantInternalBorderStrokeWidth:1,quadrantExternalBorderStrokeWidth:2},xyChart:{useMaxWidth:!0,width:700,height:500,titleFontSize:20,titlePadding:10,showTitle:!0,xAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},yAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},chartOrientation:"vertical",plotReservedSpacePercent:50},requirement:{useMaxWidth:!0,rect_fill:"#f9f9f9",text_color:"#333",rect_border_size:"0.5px",rect_border_color:"#bbb",rect_min_width:200,rect_min_height:200,fontSize:14,rect_padding:10,line_height:20},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200},timeline:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],disableMulticolor:!1},gitGraph:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0,parallelCommits:!1,arrowMarkerAbsolute:!1},c4:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,c4ShapeInRow:4,nextLinePaddingX:0,c4BoundaryInRow:2,personFontSize:14,personFontFamily:'"Open Sans", sans-serif',personFontWeight:"normal",external_personFontSize:14,external_personFontFamily:'"Open Sans", sans-serif',external_personFontWeight:"normal",systemFontSize:14,systemFontFamily:'"Open Sans", sans-serif',systemFontWeight:"normal",external_systemFontSize:14,external_systemFontFamily:'"Open Sans", sans-serif',external_systemFontWeight:"normal",system_dbFontSize:14,system_dbFontFamily:'"Open Sans", sans-serif',system_dbFontWeight:"normal",external_system_dbFontSize:14,external_system_dbFontFamily:'"Open Sans", sans-serif',external_system_dbFontWeight:"normal",system_queueFontSize:14,system_queueFontFamily:'"Open Sans", sans-serif',system_queueFontWeight:"normal",external_system_queueFontSize:14,external_system_queueFontFamily:'"Open Sans", sans-serif',external_system_queueFontWeight:"normal",boundaryFontSize:14,boundaryFontFamily:'"Open Sans", sans-serif',boundaryFontWeight:"normal",messageFontSize:12,messageFontFamily:'"Open Sans", sans-serif',messageFontWeight:"normal",containerFontSize:14,containerFontFamily:'"Open Sans", sans-serif',containerFontWeight:"normal",external_containerFontSize:14,external_containerFontFamily:'"Open Sans", sans-serif',external_containerFontWeight:"normal",container_dbFontSize:14,container_dbFontFamily:'"Open Sans", sans-serif',container_dbFontWeight:"normal",external_container_dbFontSize:14,external_container_dbFontFamily:'"Open Sans", sans-serif',external_container_dbFontWeight:"normal",container_queueFontSize:14,container_queueFontFamily:'"Open Sans", sans-serif',container_queueFontWeight:"normal",external_container_queueFontSize:14,external_container_queueFontFamily:'"Open Sans", sans-serif',external_container_queueFontWeight:"normal",componentFontSize:14,componentFontFamily:'"Open Sans", sans-serif',componentFontWeight:"normal",external_componentFontSize:14,external_componentFontFamily:'"Open Sans", sans-serif',external_componentFontWeight:"normal",component_dbFontSize:14,component_dbFontFamily:'"Open Sans", sans-serif',component_dbFontWeight:"normal",external_component_dbFontSize:14,external_component_dbFontFamily:'"Open Sans", sans-serif',external_component_dbFontWeight:"normal",component_queueFontSize:14,component_queueFontFamily:'"Open Sans", sans-serif',component_queueFontWeight:"normal",external_component_queueFontSize:14,external_component_queueFontFamily:'"Open Sans", sans-serif',external_component_queueFontWeight:"normal",wrap:!0,wrapPadding:10,person_bg_color:"#08427B",person_border_color:"#073B6F",external_person_bg_color:"#686868",external_person_border_color:"#8A8A8A",system_bg_color:"#1168BD",system_border_color:"#3C7FC0",system_db_bg_color:"#1168BD",system_db_border_color:"#3C7FC0",system_queue_bg_color:"#1168BD",system_queue_border_color:"#3C7FC0",external_system_bg_color:"#999999",external_system_border_color:"#8A8A8A",external_system_db_bg_color:"#999999",external_system_db_border_color:"#8A8A8A",external_system_queue_bg_color:"#999999",external_system_queue_border_color:"#8A8A8A",container_bg_color:"#438DD5",container_border_color:"#3C7FC0",container_db_bg_color:"#438DD5",container_db_border_color:"#3C7FC0",container_queue_bg_color:"#438DD5",container_queue_border_color:"#3C7FC0",external_container_bg_color:"#B3B3B3",external_container_border_color:"#A6A6A6",external_container_db_bg_color:"#B3B3B3",external_container_db_border_color:"#A6A6A6",external_container_queue_bg_color:"#B3B3B3",external_container_queue_border_color:"#A6A6A6",component_bg_color:"#85BBF0",component_border_color:"#78A8D8",component_db_bg_color:"#85BBF0",component_db_border_color:"#78A8D8",component_queue_bg_color:"#85BBF0",component_queue_border_color:"#78A8D8",external_component_bg_color:"#CCCCCC",external_component_border_color:"#BFBFBF",external_component_db_bg_color:"#CCCCCC",external_component_db_border_color:"#BFBFBF",external_component_queue_bg_color:"#CCCCCC",external_component_queue_border_color:"#BFBFBF"},sankey:{useMaxWidth:!0,width:600,height:400,linkColor:"gradient",nodeAlignment:"justify",showValues:!0,prefix:"",suffix:""},block:{useMaxWidth:!0,padding:8},theme:"default",maxTextSize:5e4,maxEdges:500,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize","maxEdges"],legacyMathML:!1,deterministicIds:!1,fontSize:16},$t={...qt,deterministicIDSeed:void 0,themeCSS:void 0,themeVariables:Dt.default.getThemeVariables(),sequence:{...qt.sequence,messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},noteFont:function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}},actorFont:function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}}},gantt:{...qt.gantt,tickInterval:void 0,useWidth:void 0},c4:{...qt.c4,useWidth:void 0,personFont:function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}},external_personFont:function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}},systemFont:function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}},external_systemFont:function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}},system_dbFont:function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}},external_system_dbFont:function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}},system_queueFont:function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}},external_system_queueFont:function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}},containerFont:function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}},external_containerFont:function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}},container_dbFont:function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}},external_container_dbFont:function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}},container_queueFont:function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}},external_container_queueFont:function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}},componentFont:function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}},external_componentFont:function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}},component_dbFont:function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}},external_component_dbFont:function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}},component_queueFont:function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}},external_component_queueFont:function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}},boundaryFont:function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}},messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}}},pie:{...qt.pie,useWidth:984},xyChart:{...qt.xyChart,useWidth:void 0},requirement:{...qt.requirement,useWidth:void 0},gitGraph:{...qt.gitGraph,useMaxWidth:!1},sankey:{...qt.sankey,useMaxWidth:!1}},zt=(t,e="")=>Object.keys(t).reduce(((i,r)=>Array.isArray(t[r])?i:"object"==typeof t[r]&&null!==t[r]?[...i,e+r,...zt(t[r],"")]:[...i,e+r]),[]),Pt=new Set(zt($t,"")),Rt=$t,Wt=t=>{if(st.debug("sanitizeDirective called with",t),"object"==typeof t&&null!=t)if(Array.isArray(t))t.forEach((t=>Wt(t)));else{for(const e of Object.keys(t)){if(st.debug("Checking key",e),e.startsWith("__")||e.includes("proto")||e.includes("constr")||!Pt.has(e)||null==t[e]){st.debug("sanitize deleting key: ",e),delete t[e];continue}if("object"==typeof t[e]){st.debug("sanitizing object",e),Wt(t[e]);continue}const i=["themeCSS","fontFamily","altFontFamily"];for(const r of i)e.includes(r)&&(st.debug("sanitizing css option",e),t[e]=Ut(t[e]))}if(t.themeVariables)for(const e of Object.keys(t.themeVariables)){const i=t.themeVariables[e];(null==i?void 0:i.match)&&!i.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[e]="")}st.debug("After sanitization",t)}},Ut=t=>{let e=0,i=0;for(const r of t){if(e<i)return"{ /* ERROR: Unbalanced CSS */ }";"{"===r?e++:"}"===r&&i++}return e!==i?"{ /* ERROR: Unbalanced CSS */ }":t},Ht=/^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s,Yt=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,Vt=/\s*%%.*\n/gm;class Gt extends Error{constructor(t){super(t),this.name="UnknownDiagramError"}}const Xt={},Zt=function(t,e){t=t.replace(Ht,"").replace(Yt,"").replace(Vt,"\n");for(const[i,{detector:r}]of Object.entries(Xt)){if(r(t,e))return i}throw new Gt(`No diagram type detected matching given configuration for text: ${t}`)},Jt=(...t)=>{for(const{id:e,detector:i,loader:r}of t)Qt(e,i,r)},Qt=(t,e,i)=>{Xt[t]?st.error(`Detector with key ${t} already exists`):Xt[t]={detector:e,loader:i},st.debug(`Detector with key ${t} added${i?" with loader":""}`)},Kt=(t,e,{depth:i=2,clobber:r=!1}={})=>{const n={depth:i,clobber:r};return Array.isArray(e)&&!Array.isArray(t)?(e.forEach((e=>Kt(t,e,n))),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach((e=>{t.includes(e)||t.push(e)})),t):void 0===t||i<=0?null!=t&&"object"==typeof t&&"object"==typeof e?Object.assign(t,e):e:(void 0!==e&&"object"==typeof t&&"object"==typeof e&&Object.keys(e).forEach((n=>{"object"!=typeof e[n]||void 0!==t[n]&&"object"!=typeof t[n]?(r||"object"!=typeof t[n]&&"object"!=typeof e[n])&&(t[n]=e[n]):(void 0===t[n]&&(t[n]=Array.isArray(e[n])?[]:{}),t[n]=Kt(t[n],e[n],{depth:i-1,clobber:r}))})),t)},te=Kt,ee="\u200b",ie={curveBasis:a.qrM,curveBasisClosed:a.Yu4,curveBasisOpen:a.IA3,curveBumpX:a.Wi0,curveBumpY:a.PGM,curveBundle:a.OEq,curveCardinalClosed:a.olC,curveCardinalOpen:a.IrU,curveCardinal:a.y8u,curveCatmullRomClosed:a.Q7f,curveCatmullRomOpen:a.cVp,curveCatmullRom:a.oDi,curveLinear:a.lUB,curveLinearClosed:a.Lx9,curveMonotoneX:a.nVG,curveMonotoneY:a.uxU,curveNatural:a.Xf2,curveStep:a.GZz,curveStepAfter:a.UPb,curveStepBefore:a.dyv},re=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,ne=function(t,e=null){try{const i=new RegExp(`[%]{2}(?![{]${re.source})(?=[}][%]{2}).*\n`,"ig");let r;t=t.trim().replace(i,"").replace(/'/gm,'"'),st.debug(`Detecting diagram directive${null!==e?" type:"+e:""} based on the text:${t}`);const n=[];for(;null!==(r=Yt.exec(t));)if(r.index===Yt.lastIndex&&Yt.lastIndex++,r&&!e||e&&r[1]&&r[1].match(e)||e&&r[2]&&r[2].match(e)){const t=r[1]?r[1]:r[2],e=r[3]?r[3].trim():r[4]?JSON.parse(r[4].trim()):null;n.push({type:t,args:e})}return 0===n.length?{type:t,args:null}:1===n.length?n[0]:n}catch(i){return st.error(`ERROR: ${i.message} - Unable to parse directive type: '${e}' based on the text: '${t}'`),{type:void 0,args:null}}};function oe(t,e){if(!t)return e;const i=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return ie[i]??e}function ae(t,e){return t&&e?Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)):0}const se=(t,e=2)=>{const i=Math.pow(10,e);return Math.round(t*i)/i},le=(t,e)=>{let i,r=e;for(const n of t){if(i){const t=ae(n,i);if(t<r)r-=t;else{const e=r/t;if(e<=0)return i;if(e>=1)return{x:n.x,y:n.y};if(e>0&&e<1)return{x:se((1-e)*i.x+e*n.x,5),y:se((1-e)*i.y+e*n.y,5)}}}i=n}throw new Error("Could not find a suitable point for the given distance")};function ce(t){let e="",i="";for(const r of t)void 0!==r&&(r.startsWith("color:")||r.startsWith("text-align:")?i=i+r+";":e=e+r+";");return{style:e,labelStyle:i}}let he=0;const ue=()=>(he++,"id-"+Math.random().toString(36).substr(2,12)+"-"+he);const de=t=>function(t){let e="";const i="0123456789abcdef";for(let r=0;r<t;r++)e+=i.charAt(Math.floor(16*Math.random()));return e}(t.length),fe=function(t,e){const i=e.text.replace(St.lineBreakRegex," "),[,r]=_e(e.fontSize),n=t.append("text");n.attr("x",e.x),n.attr("y",e.y),n.style("text-anchor",e.anchor),n.style("font-family",e.fontFamily),n.style("font-size",r),n.style("font-weight",e.fontWeight),n.attr("fill",e.fill),void 0!==e.class&&n.attr("class",e.class);const o=n.append("tspan");return o.attr("x",e.x+2*e.textMargin),o.attr("fill",e.fill),o.text(i),n},pe=(0,y.A)(((t,e,i)=>{if(!t)return t;if(i=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"<br/>"},i),St.lineBreakRegex.test(t))return t;const r=t.split(" "),n=[];let o="";return r.forEach(((t,a)=>{const s=ye(`${t} `,i),l=ye(o,i);if(s>e){const{hyphenatedStrings:r,remainingWord:a}=ge(t,e,"-",i);n.push(o,...r),o=a}else l+s>=e?(n.push(o),o=t):o=[o,t].filter(Boolean).join(" ");a+1===r.length&&n.push(o)})),n.filter((t=>""!==t)).join(i.joinWith)}),((t,e,i)=>`${t}${e}${i.fontSize}${i.fontWeight}${i.fontFamily}${i.joinWith}`)),ge=(0,y.A)(((t,e,i="-",r)=>{r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},r);const n=[...t],o=[];let a="";return n.forEach(((t,s)=>{const l=`${a}${t}`;if(ye(l,r)>=e){const t=s+1,e=n.length===t,r=`${l}${i}`;o.push(e?l:r),a=""}else a=l})),{hyphenatedStrings:o,remainingWord:a}}),((t,e,i="-",r)=>`${t}${e}${i}${r.fontSize}${r.fontWeight}${r.fontFamily}`));function me(t,e){return xe(t,e).height}function ye(t,e){return xe(t,e).width}const xe=(0,y.A)(((t,e)=>{const{fontSize:i=12,fontFamily:r="Arial",fontWeight:n=400}=e;if(!t)return{width:0,height:0};const[,o]=_e(i),s=["sans-serif",r],l=t.split(St.lineBreakRegex),c=[],h=(0,a.Ltv)("body");if(!h.remove)return{width:0,height:0,lineHeight:0};const u=h.append("svg");for(const a of s){let t=0;const e={width:0,height:0,lineHeight:0};for(const i of l){const r={x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0,text:""};r.text=i||ee;const s=fe(u,r).style("font-size",o).style("font-weight",n).style("font-family",a),l=(s._groups||s)[0][0].getBBox();if(0===l.width&&0===l.height)throw new Error("svg element not in render tree");e.width=Math.round(Math.max(e.width,l.width)),t=Math.round(l.height),e.height+=t,e.lineHeight=Math.round(Math.max(e.lineHeight,t))}c.push(e)}u.remove();return c[isNaN(c[1].height)||isNaN(c[1].width)||isNaN(c[1].lineHeight)||c[0].height>c[1].height&&c[0].width>c[1].width&&c[0].lineHeight>c[1].lineHeight?0:1]}),((t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`));let Ce;function be(t){return"str"in t}const _e=t=>{if("number"==typeof t)return[t,t+"px"];const e=parseInt(t??"",10);return Number.isNaN(e)?[void 0,void 0]:t===String(e)?[e,t+"px"]:[e,t]};function ve(t,e){return(0,x.A)({},t,e)}const ke={assignWithDepth:te,wrapLabel:pe,calculateTextHeight:me,calculateTextWidth:ye,calculateTextDimensions:xe,cleanAndMerge:ve,detectInit:function(t,e){const i=ne(t,/(?:init\b)|(?:initialize\b)/);let r={};if(Array.isArray(i)){const t=i.map((t=>t.args));Wt(t),r=te(r,[...t])}else r=i.args;if(!r)return;let n=Zt(t,e);const o="config";return void 0!==r[o]&&("flowchart-v2"===n&&(n="flowchart"),r[n]=r[o],delete r[o]),r},detectDirective:ne,isSubstringInArray:function(t,e){for(const[i,r]of e.entries())if(r.match(t))return i;return-1},interpolateToCurve:oe,calcLabelPosition:function(t){return 1===t.length?t[0]:function(t){let e,i=0;return t.forEach((t=>{i+=ae(t,e),e=t})),le(t,i/2)}(t)},calcCardinalityPosition:(t,e,i)=>{st.info(`our points ${JSON.stringify(e)}`),e[0]!==i&&(e=e.reverse());const r=le(e,25),n=t?10:5,o=Math.atan2(e[0].y-r.y,e[0].x-r.x),a={x:0,y:0};return a.x=Math.sin(o)*n+(e[0].x+r.x)/2,a.y=-Math.cos(o)*n+(e[0].y+r.y)/2,a},calcTerminalLabelPosition:function(t,e,i){const r=structuredClone(i);st.info("our points",r),"start_left"!==e&&"start_right"!==e&&r.reverse();const n=le(r,25+t),o=10+.5*t,a=Math.atan2(r[0].y-n.y,r[0].x-n.x),s={x:0,y:0};return"start_left"===e?(s.x=Math.sin(a+Math.PI)*o+(r[0].x+n.x)/2,s.y=-Math.cos(a+Math.PI)*o+(r[0].y+n.y)/2):"end_right"===e?(s.x=Math.sin(a-Math.PI)*o+(r[0].x+n.x)/2-5,s.y=-Math.cos(a-Math.PI)*o+(r[0].y+n.y)/2-5):"end_left"===e?(s.x=Math.sin(a)*o+(r[0].x+n.x)/2-5,s.y=-Math.cos(a)*o+(r[0].y+n.y)/2-5):(s.x=Math.sin(a)*o+(r[0].x+n.x)/2,s.y=-Math.cos(a)*o+(r[0].y+n.y)/2),s},formatUrl:function(t,e){const i=t.trim();if(i)return"loose"!==e.securityLevel?(0,o.Jf)(i):i},getStylesFromArray:ce,generateId:ue,random:de,runFunc:(t,...e)=>{const i=t.split("."),r=i.length-1,n=i[r];let o=window;for(let a=0;a<r;a++)if(o=o[i[a]],!o)return void st.error(`Function name: ${t} not found in window`);o[n](...e)},entityDecode:function(t){return Ce=Ce||document.createElement("div"),t=escape(t).replace(/%26/g,"&").replace(/%23/g,"#").replace(/%3B/g,";"),Ce.innerHTML=t,unescape(Ce.textContent)},insertTitle:(t,e,i,r)=>{var n;if(!r)return;const o=null==(n=t.node())?void 0:n.getBBox();o&&t.append("text").text(r).attr("x",o.x+o.width/2).attr("y",-i).attr("class",e)},parseFontSize:_e,InitIDGenerator:class{constructor(t=!1,e){this.count=0,this.count=e?e.length:0,this.next=t?()=>this.count++:()=>Date.now()}}},Te=function(t){return t.replace(/\ufb02\xb0\xb0/g,"&#").replace(/\ufb02\xb0/g,"&").replace(/\xb6\xdf/g,";")},Ae="10.9.0",we=Object.freeze(Rt);let Se,Be=te({},we),Fe=[],Le=te({},we);const Me=(t,e)=>{let i=te({},t),r={};for(const n of e)je(n),r=te(r,n);if(i=te(i,r),r.theme&&r.theme in Dt){const t=te({},Se),e=te(t.themeVariables||{},r.themeVariables);i.theme&&i.theme in Dt&&(i.themeVariables=Dt[i.theme].getThemeVariables(e))}return Le=i,ze(Le),Le},Ee=()=>te({},Be),Ne=t=>(ze(t),te(Le,t),Oe()),Oe=()=>te({},Le),je=t=>{t&&(["secure",...Be.secure??[]].forEach((e=>{Object.hasOwn(t,e)&&(st.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])})),Object.keys(t).forEach((e=>{e.startsWith("__")&&delete t[e]})),Object.keys(t).forEach((e=>{"string"==typeof t[e]&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],"object"==typeof t[e]&&je(t[e])})))},Ie=t=>{Wt(t),!t.fontFamily||t.themeVariables&&t.themeVariables.fontFamily||(t.themeVariables={fontFamily:t.fontFamily}),Fe.push(t),Me(Be,Fe)},De=(t=Be)=>{Fe=[],Me(t,Fe)},qe={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead."},$e={},ze=t=>{var e;t&&((t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&&($e[e="LAZY_LOAD_DEPRECATED"]||(st.warn(qe[e]),$e[e]=!0)))},Pe={id:"c4",detector:t=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(t),loader:async()=>{const{diagram:t}=await i.e(3863).then(i.bind(i,83863));return{id:"c4",diagram:t}}},Re="flowchart",We={id:Re,detector:(t,e)=>{var i,r;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer)&&"elk"!==(null==(r=null==e?void 0:e.flowchart)?void 0:r.defaultRenderer)&&/^\s*graph/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(1169),i.e(5829),i.e(1176),i.e(8747),i.e(2746),i.e(6216),i.e(7121)]).then(i.bind(i,29502));return{id:Re,diagram:t}}},Ue="flowchart-v2",He={id:Ue,detector:(t,e)=>{var i,r,n;return"dagre-d3"!==(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer)&&"elk"!==(null==(r=null==e?void 0:e.flowchart)?void 0:r.defaultRenderer)&&(!(!/^\s*graph/.test(t)||"dagre-wrapper"!==(null==(n=null==e?void 0:e.flowchart)?void 0:n.defaultRenderer))||/^\s*flowchart/.test(t))},loader:async()=>{const{diagram:t}=await Promise.all([i.e(1169),i.e(5829),i.e(1176),i.e(8747),i.e(2746),i.e(6216),i.e(2317)]).then(i.bind(i,62317));return{id:Ue,diagram:t}}},Ye={id:"er",detector:t=>/^\s*erDiagram/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(1169),i.e(1176),i.e(8159)]).then(i.bind(i,58159));return{id:"er",diagram:t}}},Ve="gitGraph",Ge={id:Ve,detector:t=>/^\s*gitGraph/.test(t),loader:async()=>{const{diagram:t}=await i.e(6506).then(i.bind(i,66506));return{id:Ve,diagram:t}}},Xe="gantt",Ze={id:Xe,detector:t=>/^\s*gantt/.test(t),loader:async()=>{const{diagram:t}=await i.e(1555).then(i.bind(i,71555));return{id:Xe,diagram:t}}},Je="info",Qe={id:Je,detector:t=>/^\s*info/.test(t),loader:async()=>{const{diagram:t}=await i.e(9469).then(i.bind(i,59469));return{id:Je,diagram:t}}},Ke={id:"pie",detector:t=>/^\s*pie/.test(t),loader:async()=>{const{diagram:t}=await i.e(8444).then(i.bind(i,36063));return{id:"pie",diagram:t}}},ti="quadrantChart",ei={id:ti,detector:t=>/^\s*quadrantChart/.test(t),loader:async()=>{const{diagram:t}=await i.e(7200).then(i.bind(i,57200));return{id:ti,diagram:t}}},ii="xychart",ri={id:ii,detector:t=>/^\s*xychart-beta/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(5829),i.e(8947)]).then(i.bind(i,18947));return{id:ii,diagram:t}}},ni="requirement",oi={id:ni,detector:t=>/^\s*requirement(Diagram)?/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(1169),i.e(1176),i.e(9688)]).then(i.bind(i,39688));return{id:ni,diagram:t}}},ai="sequence",si={id:ai,detector:t=>/^\s*sequenceDiagram/.test(t),loader:async()=>{const{diagram:t}=await i.e(7211).then(i.bind(i,77211));return{id:ai,diagram:t}}},li="class",ci={id:li,detector:(t,e)=>{var i;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.class)?void 0:i.defaultRenderer)&&/^\s*classDiagram/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(1169),i.e(1176),i.e(7308),i.e(3132)]).then(i.bind(i,70751));return{id:li,diagram:t}}},hi="classDiagram",ui={id:hi,detector:(t,e)=>{var i;return!(!/^\s*classDiagram/.test(t)||"dagre-wrapper"!==(null==(i=null==e?void 0:e.class)?void 0:i.defaultRenderer))||/^\s*classDiagram-v2/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(1169),i.e(5829),i.e(1176),i.e(8747),i.e(2746),i.e(7308),i.e(4)]).then(i.bind(i,4));return{id:hi,diagram:t}}},di="state",fi={id:di,detector:(t,e)=>{var i;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.state)?void 0:i.defaultRenderer)&&/^\s*stateDiagram/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(1169),i.e(1176),i.e(6292),i.e(8609)]).then(i.bind(i,58609));return{id:di,diagram:t}}},pi="stateDiagram",gi={id:pi,detector:(t,e)=>{var i;return!!/^\s*stateDiagram-v2/.test(t)||!(!/^\s*stateDiagram/.test(t)||"dagre-wrapper"!==(null==(i=null==e?void 0:e.state)?void 0:i.defaultRenderer))},loader:async()=>{const{diagram:t}=await Promise.all([i.e(1169),i.e(5829),i.e(1176),i.e(8747),i.e(2746),i.e(6292),i.e(5688)]).then(i.bind(i,45688));return{id:pi,diagram:t}}},mi="journey",yi={id:mi,detector:t=>/^\s*journey/.test(t),loader:async()=>{const{diagram:t}=await i.e(8327).then(i.bind(i,30708));return{id:mi,diagram:t}}},xi=function(t,e,i,r){const n=function(t,e,i){let r=new Map;return i?(r.set("width","100%"),r.set("style",`max-width: ${e}px;`)):(r.set("height",t),r.set("width",e)),r}(e,i,r);!function(t,e){for(let i of e)t.attr(i[0],i[1])}(t,n)},Ci=function(t,e,i,r){const n=e.node().getBBox(),o=n.width,a=n.height;st.info(`SVG bounds: ${o}x${a}`,n);let s=0,l=0;st.info(`Graph bounds: ${s}x${l}`,t),s=o+2*i,l=a+2*i,st.info(`Calculated bounds: ${s}x${l}`),xi(e,l,s,r);const c=`${n.x-i} ${n.y-i} ${n.width+2*i} ${n.height+2*i}`;e.attr("viewBox",c)},bi={},_i=(t,e,i)=>{let r="";return t in bi&&bi[t]?r=bi[t](i):st.warn(`No theme found for ${t}`),` & {\n font-family: ${i.fontFamily};\n font-size: ${i.fontSize};\n fill: ${i.textColor}\n }\n\n /* Classes common for multiple diagrams */\n\n & .error-icon {\n fill: ${i.errorBkgColor};\n }\n & .error-text {\n fill: ${i.errorTextColor};\n stroke: ${i.errorTextColor};\n }\n\n & .edge-thickness-normal {\n stroke-width: 2px;\n }\n & .edge-thickness-thick {\n stroke-width: 3.5px\n }\n & .edge-pattern-solid {\n stroke-dasharray: 0;\n }\n\n & .edge-pattern-dashed{\n stroke-dasharray: 3;\n }\n .edge-pattern-dotted {\n stroke-dasharray: 2;\n }\n\n & .marker {\n fill: ${i.lineColor};\n stroke: ${i.lineColor};\n }\n & .marker.cross {\n stroke: ${i.lineColor};\n }\n\n & svg {\n font-family: ${i.fontFamily};\n font-size: ${i.fontSize};\n }\n\n ${r}\n\n ${e}\n`};let vi="",ki="",Ti="";const Ai=t=>pt(t,Oe()),wi=()=>{vi="",Ti="",ki=""},Si=t=>{vi=Ai(t).replace(/^\s+/g,"")},Bi=()=>vi,Fi=t=>{Ti=Ai(t).replace(/\n\s+/g,"\n")},Li=()=>Ti,Mi=t=>{ki=Ai(t)},Ei=()=>ki,Ni=Object.freeze(Object.defineProperty({__proto__:null,clear:wi,getAccDescription:Li,getAccTitle:Bi,getDiagramTitle:Ei,setAccDescription:Fi,setAccTitle:Si,setDiagramTitle:Mi},Symbol.toStringTag,{value:"Module"})),Oi=st,ji=lt,Ii=Oe,Di=Ne,qi=we,$i=t=>pt(t,Ii()),zi=Ci,Pi={},Ri=(t,e,i)=>{var r,n,o;if(Pi[t])throw new Error(`Diagram ${t} already registered.`);Pi[t]=e,i&&Qt(t,i),n=t,void 0!==(o=e.styles)&&(bi[n]=o),null==(r=e.injectUtils)||r.call(e,Oi,ji,Ii,$i,zi,Ni,(()=>{}))},Wi=t=>{if(t in Pi)return Pi[t];throw new Ui(t)};class Ui extends Error{constructor(t){super(`Diagram ${t} not found.`)}}const Hi=t=>{var e;const{securityLevel:i}=Ii();let r=(0,a.Ltv)("body");if("sandbox"===i){const i=(null==(e=(0,a.Ltv)(`#i${t}`).node())?void 0:e.contentDocument)??document;r=(0,a.Ltv)(i.body)}return r.select(`#${t}`)},Yi={draw:(t,e,i)=>{st.debug("rendering svg for syntax error\n");const r=Hi(e),n=r.append("g");r.attr("viewBox","0 0 2412 512"),xi(r,100,512,!0),n.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),n.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),n.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),n.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),n.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),n.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),n.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),n.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${i}`)}},Vi=Yi,Gi={db:{},renderer:Yi,parser:{parser:{yy:{}},parse:()=>{}}},Xi="flowchart-elk",Zi={id:Xi,detector:(t,e)=>{var i;return!!(/^\s*flowchart-elk/.test(t)||/^\s*flowchart|graph/.test(t)&&"elk"===(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer))},loader:async()=>{const{diagram:t}=await Promise.all([i.e(5829),i.e(8747),i.e(6216),i.e(2235)]).then(i.bind(i,22235));return{id:Xi,diagram:t}}},Ji="timeline",Qi={id:Ji,detector:t=>/^\s*timeline/.test(t),loader:async()=>{const{diagram:t}=await i.e(5642).then(i.bind(i,45642));return{id:Ji,diagram:t}}},Ki="mindmap",tr={id:Ki,detector:t=>/^\s*mindmap/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(5829),i.e(3771)]).then(i.bind(i,93771));return{id:Ki,diagram:t}}},er="sankey",ir={id:er,detector:t=>/^\s*sankey-beta/.test(t),loader:async()=>{const{diagram:t}=await i.e(7440).then(i.bind(i,7440));return{id:er,diagram:t}}},rr="block",nr={id:rr,detector:t=>/^\s*block-beta/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(1169),i.e(5829),i.e(8747),i.e(7147)]).then(i.bind(i,87147));return{id:rr,diagram:t}}};let or=!1;const ar=()=>{or||(or=!0,Ri("error",Gi,(t=>"error"===t.toLowerCase().trim())),Ri("---",{db:{clear:()=>{}},styles:{},renderer:{draw:()=>{}},parser:{parser:{yy:{}},parse:()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")}},init:()=>null},(t=>t.toLowerCase().trimStart().startsWith("---"))),Jt(Pe,ui,ci,Ye,Ze,Qe,Ke,oi,si,Zi,He,We,tr,Qi,Ge,gi,fi,yi,ei,ir,ri,nr))};class sr{constructor(t,e={}){this.text=t,this.metadata=e,this.type="graph",this.text=function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/classDef.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/#\w+;/g,(function(t){const e=t.substring(1,t.length-1);return/^\+?\d+$/.test(e)?"\ufb02\xb0\xb0"+e+"\xb6\xdf":"\ufb02\xb0"+e+"\xb6\xdf"})),e}(t),this.text+="\n";const i=Oe();try{this.type=Zt(t,i)}catch(n){this.type="error",this.detectError=n}const r=Wi(this.type);st.debug("Type "+this.type),this.db=r.db,this.renderer=r.renderer,this.parser=r.parser,this.parser.parser.yy=this.db,this.init=r.init,this.parse()}parse(){var t,e,i,r,n;if(this.detectError)throw this.detectError;null==(e=(t=this.db).clear)||e.call(t);const o=Oe();null==(i=this.init)||i.call(this,o),this.metadata.title&&(null==(n=(r=this.db).setDiagramTitle)||n.call(r,this.metadata.title)),this.parser.parse(this.text)}async render(t,e){await this.renderer.draw(this.text,t,e,this)}getParser(){return this.parser}getType(){return this.type}}const lr=async(t,e={})=>{const i=Zt(t,Oe());try{Wi(i)}catch(r){const t=Xt[i].loader;if(!t)throw new Gt(`Diagram ${i} not found.`);const{id:e,diagram:n}=await t();Ri(e,n)}return new sr(t,e)};let cr=[];const hr="graphics-document document";const ur=t=>t.replace(/^\s*%%(?!{)[^\n]+\n?/gm,"").trimStart();function dr(t){return null==t}var fr={isNothing:dr,isObject:function(t){return"object"==typeof t&&null!==t},toArray:function(t){return Array.isArray(t)?t:dr(t)?[]:[t]},repeat:function(t,e){var i,r="";for(i=0;i<e;i+=1)r+=t;return r},isNegativeZero:function(t){return 0===t&&Number.NEGATIVE_INFINITY===1/t},extend:function(t,e){var i,r,n,o;if(e)for(i=0,r=(o=Object.keys(e)).length;i<r;i+=1)t[n=o[i]]=e[n];return t}};function pr(t,e){var i="",r=t.reason||"(unknown reason)";return t.mark?(t.mark.name&&(i+='in "'+t.mark.name+'" '),i+="("+(t.mark.line+1)+":"+(t.mark.column+1)+")",!e&&t.mark.snippet&&(i+="\n\n"+t.mark.snippet),r+" "+i):r}function gr(t,e){Error.call(this),this.name="YAMLException",this.reason=t,this.mark=e,this.message=pr(this,!1),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||""}gr.prototype=Object.create(Error.prototype),gr.prototype.constructor=gr,gr.prototype.toString=function(t){return this.name+": "+pr(this,t)};var mr=gr;function yr(t,e,i,r,n){var o="",a="",s=Math.floor(n/2)-1;return r-e>s&&(e=r-s+(o=" ... ").length),i-r>s&&(i=r+s-(a=" ...").length),{str:o+t.slice(e,i).replace(/\t/g,"\u2192")+a,pos:r-e+o.length}}function xr(t,e){return fr.repeat(" ",e-t.length)+t}var Cr=function(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),"number"!=typeof e.indent&&(e.indent=1),"number"!=typeof e.linesBefore&&(e.linesBefore=3),"number"!=typeof e.linesAfter&&(e.linesAfter=2);for(var i,r=/\r?\n|\r|\0/g,n=[0],o=[],a=-1;i=r.exec(t.buffer);)o.push(i.index),n.push(i.index+i[0].length),t.position<=i.index&&a<0&&(a=n.length-2);a<0&&(a=n.length-1);var s,l,c="",h=Math.min(t.line+e.linesAfter,o.length).toString().length,u=e.maxLength-(e.indent+h+3);for(s=1;s<=e.linesBefore&&!(a-s<0);s++)l=yr(t.buffer,n[a-s],o[a-s],t.position-(n[a]-n[a-s]),u),c=fr.repeat(" ",e.indent)+xr((t.line-s+1).toString(),h)+" | "+l.str+"\n"+c;for(l=yr(t.buffer,n[a],o[a],t.position,u),c+=fr.repeat(" ",e.indent)+xr((t.line+1).toString(),h)+" | "+l.str+"\n",c+=fr.repeat("-",e.indent+h+3+l.pos)+"^\n",s=1;s<=e.linesAfter&&!(a+s>=o.length);s++)l=yr(t.buffer,n[a+s],o[a+s],t.position-(n[a]-n[a+s]),u),c+=fr.repeat(" ",e.indent)+xr((t.line+s+1).toString(),h)+" | "+l.str+"\n";return c.replace(/\n$/,"")},br=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],_r=["scalar","sequence","mapping"];var vr=function(t,e){var i,r;if(e=e||{},Object.keys(e).forEach((function(e){if(-1===br.indexOf(e))throw new mr('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')})),this.options=e,this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.representName=e.representName||null,this.defaultStyle=e.defaultStyle||null,this.multi=e.multi||!1,this.styleAliases=(i=e.styleAliases||null,r={},null!==i&&Object.keys(i).forEach((function(t){i[t].forEach((function(e){r[String(e)]=t}))})),r),-1===_r.indexOf(this.kind))throw new mr('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')};function kr(t,e){var i=[];return t[e].forEach((function(t){var e=i.length;i.forEach((function(i,r){i.tag===t.tag&&i.kind===t.kind&&i.multi===t.multi&&(e=r)})),i[e]=t})),i}function Tr(t){return this.extend(t)}Tr.prototype.extend=function(t){var e=[],i=[];if(t instanceof vr)i.push(t);else if(Array.isArray(t))i=i.concat(t);else{if(!t||!Array.isArray(t.implicit)&&!Array.isArray(t.explicit))throw new mr("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");t.implicit&&(e=e.concat(t.implicit)),t.explicit&&(i=i.concat(t.explicit))}e.forEach((function(t){if(!(t instanceof vr))throw new mr("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(t.loadKind&&"scalar"!==t.loadKind)throw new mr("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(t.multi)throw new mr("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")})),i.forEach((function(t){if(!(t instanceof vr))throw new mr("Specified list of YAML types (or a single Type object) contains a non-Type object.")}));var r=Object.create(Tr.prototype);return r.implicit=(this.implicit||[]).concat(e),r.explicit=(this.explicit||[]).concat(i),r.compiledImplicit=kr(r,"implicit"),r.compiledExplicit=kr(r,"explicit"),r.compiledTypeMap=function(){var t,e,i={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}};function r(t){t.multi?(i.multi[t.kind].push(t),i.multi.fallback.push(t)):i[t.kind][t.tag]=i.fallback[t.tag]=t}for(t=0,e=arguments.length;t<e;t+=1)arguments[t].forEach(r);return i}(r.compiledImplicit,r.compiledExplicit),r};var Ar=new Tr({explicit:[new vr("tag:yaml.org,2002:str",{kind:"scalar",construct:function(t){return null!==t?t:""}}),new vr("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(t){return null!==t?t:[]}}),new vr("tag:yaml.org,2002:map",{kind:"mapping",construct:function(t){return null!==t?t:{}}})]});var wr=new vr("tag:yaml.org,2002:null",{kind:"scalar",resolve:function(t){if(null===t)return!0;var e=t.length;return 1===e&&"~"===t||4===e&&("null"===t||"Null"===t||"NULL"===t)},construct:function(){return null},predicate:function(t){return null===t},represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"},empty:function(){return""}},defaultStyle:"lowercase"});var Sr=new vr("tag:yaml.org,2002:bool",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e=t.length;return 4===e&&("true"===t||"True"===t||"TRUE"===t)||5===e&&("false"===t||"False"===t||"FALSE"===t)},construct:function(t){return"true"===t||"True"===t||"TRUE"===t},predicate:function(t){return"[object Boolean]"===Object.prototype.toString.call(t)},represent:{lowercase:function(t){return t?"true":"false"},uppercase:function(t){return t?"TRUE":"FALSE"},camelcase:function(t){return t?"True":"False"}},defaultStyle:"lowercase"});function Br(t){return 48<=t&&t<=55}function Fr(t){return 48<=t&&t<=57}var Lr=new vr("tag:yaml.org,2002:int",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e,i,r=t.length,n=0,o=!1;if(!r)return!1;if("-"!==(e=t[n])&&"+"!==e||(e=t[++n]),"0"===e){if(n+1===r)return!0;if("b"===(e=t[++n])){for(n++;n<r;n++)if("_"!==(e=t[n])){if("0"!==e&&"1"!==e)return!1;o=!0}return o&&"_"!==e}if("x"===e){for(n++;n<r;n++)if("_"!==(e=t[n])){if(!(48<=(i=t.charCodeAt(n))&&i<=57||65<=i&&i<=70||97<=i&&i<=102))return!1;o=!0}return o&&"_"!==e}if("o"===e){for(n++;n<r;n++)if("_"!==(e=t[n])){if(!Br(t.charCodeAt(n)))return!1;o=!0}return o&&"_"!==e}}if("_"===e)return!1;for(;n<r;n++)if("_"!==(e=t[n])){if(!Fr(t.charCodeAt(n)))return!1;o=!0}return!(!o||"_"===e)},construct:function(t){var e,i=t,r=1;if(-1!==i.indexOf("_")&&(i=i.replace(/_/g,"")),"-"!==(e=i[0])&&"+"!==e||("-"===e&&(r=-1),e=(i=i.slice(1))[0]),"0"===i)return 0;if("0"===e){if("b"===i[1])return r*parseInt(i.slice(2),2);if("x"===i[1])return r*parseInt(i.slice(2),16);if("o"===i[1])return r*parseInt(i.slice(2),8)}return r*parseInt(i,10)},predicate:function(t){return"[object Number]"===Object.prototype.toString.call(t)&&t%1==0&&!fr.isNegativeZero(t)},represent:{binary:function(t){return t>=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},octal:function(t){return t>=0?"0o"+t.toString(8):"-0o"+t.toString(8).slice(1)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),Mr=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");var Er=/^[-+]?[0-9]+e/;var Nr=new vr("tag:yaml.org,2002:float",{kind:"scalar",resolve:function(t){return null!==t&&!(!Mr.test(t)||"_"===t[t.length-1])},construct:function(t){var e,i;return i="-"===(e=t.replace(/_/g,"").toLowerCase())[0]?-1:1,"+-".indexOf(e[0])>=0&&(e=e.slice(1)),".inf"===e?1===i?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:i*parseFloat(e,10)},predicate:function(t){return"[object Number]"===Object.prototype.toString.call(t)&&(t%1!=0||fr.isNegativeZero(t))},represent:function(t,e){var i;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(fr.isNegativeZero(t))return"-0.0";return i=t.toString(10),Er.test(i)?i.replace("e",".e"):i},defaultStyle:"lowercase"}),Or=Ar.extend({implicit:[wr,Sr,Lr,Nr]}),jr=Or,Ir=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),Dr=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");var qr=new vr("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:function(t){return null!==t&&(null!==Ir.exec(t)||null!==Dr.exec(t))},construct:function(t){var e,i,r,n,o,a,s,l,c=0,h=null;if(null===(e=Ir.exec(t))&&(e=Dr.exec(t)),null===e)throw new Error("Date resolve error");if(i=+e[1],r=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(i,r,n));if(o=+e[4],a=+e[5],s=+e[6],e[7]){for(c=e[7].slice(0,3);c.length<3;)c+="0";c=+c}return e[9]&&(h=6e4*(60*+e[10]+ +(e[11]||0)),"-"===e[9]&&(h=-h)),l=new Date(Date.UTC(i,r,n,o,a,s,c)),h&&l.setTime(l.getTime()-h),l},instanceOf:Date,represent:function(t){return t.toISOString()}});var $r=new vr("tag:yaml.org,2002:merge",{kind:"scalar",resolve:function(t){return"<<"===t||null===t}}),zr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";var Pr=new vr("tag:yaml.org,2002:binary",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e,i,r=0,n=t.length,o=zr;for(i=0;i<n;i++)if(!((e=o.indexOf(t.charAt(i)))>64)){if(e<0)return!1;r+=6}return r%8==0},construct:function(t){var e,i,r=t.replace(/[\r\n=]/g,""),n=r.length,o=zr,a=0,s=[];for(e=0;e<n;e++)e%4==0&&e&&(s.push(a>>16&255),s.push(a>>8&255),s.push(255&a)),a=a<<6|o.indexOf(r.charAt(e));return 0===(i=n%4*6)?(s.push(a>>16&255),s.push(a>>8&255),s.push(255&a)):18===i?(s.push(a>>10&255),s.push(a>>2&255)):12===i&&s.push(a>>4&255),new Uint8Array(s)},predicate:function(t){return"[object Uint8Array]"===Object.prototype.toString.call(t)},represent:function(t){var e,i,r="",n=0,o=t.length,a=zr;for(e=0;e<o;e++)e%3==0&&e&&(r+=a[n>>18&63],r+=a[n>>12&63],r+=a[n>>6&63],r+=a[63&n]),n=(n<<8)+t[e];return 0===(i=o%3)?(r+=a[n>>18&63],r+=a[n>>12&63],r+=a[n>>6&63],r+=a[63&n]):2===i?(r+=a[n>>10&63],r+=a[n>>4&63],r+=a[n<<2&63],r+=a[64]):1===i&&(r+=a[n>>2&63],r+=a[n<<4&63],r+=a[64],r+=a[64]),r}}),Rr=Object.prototype.hasOwnProperty,Wr=Object.prototype.toString;var Ur=new vr("tag:yaml.org,2002:omap",{kind:"sequence",resolve:function(t){if(null===t)return!0;var e,i,r,n,o,a=[],s=t;for(e=0,i=s.length;e<i;e+=1){if(r=s[e],o=!1,"[object Object]"!==Wr.call(r))return!1;for(n in r)if(Rr.call(r,n)){if(o)return!1;o=!0}if(!o)return!1;if(-1!==a.indexOf(n))return!1;a.push(n)}return!0},construct:function(t){return null!==t?t:[]}}),Hr=Object.prototype.toString;var Yr=new vr("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:function(t){if(null===t)return!0;var e,i,r,n,o,a=t;for(o=new Array(a.length),e=0,i=a.length;e<i;e+=1){if(r=a[e],"[object Object]"!==Hr.call(r))return!1;if(1!==(n=Object.keys(r)).length)return!1;o[e]=[n[0],r[n[0]]]}return!0},construct:function(t){if(null===t)return[];var e,i,r,n,o,a=t;for(o=new Array(a.length),e=0,i=a.length;e<i;e+=1)r=a[e],n=Object.keys(r),o[e]=[n[0],r[n[0]]];return o}}),Vr=Object.prototype.hasOwnProperty;var Gr=new vr("tag:yaml.org,2002:set",{kind:"mapping",resolve:function(t){if(null===t)return!0;var e,i=t;for(e in i)if(Vr.call(i,e)&&null!==i[e])return!1;return!0},construct:function(t){return null!==t?t:{}}}),Xr=jr.extend({implicit:[qr,$r],explicit:[Pr,Ur,Yr,Gr]}),Zr=Object.prototype.hasOwnProperty,Jr=1,Qr=2,Kr=3,tn=4,en=1,rn=2,nn=3,on=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,an=/[\x85\u2028\u2029]/,sn=/[,\[\]\{\}]/,ln=/^(?:!|!!|![a-z\-]+!)$/i,cn=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function hn(t){return Object.prototype.toString.call(t)}function un(t){return 10===t||13===t}function dn(t){return 9===t||32===t}function fn(t){return 9===t||32===t||10===t||13===t}function pn(t){return 44===t||91===t||93===t||123===t||125===t}function gn(t){var e;return 48<=t&&t<=57?t-48:97<=(e=32|t)&&e<=102?e-97+10:-1}function mn(t){return 48===t?"\0":97===t?"\x07":98===t?"\b":116===t||9===t?"\t":110===t?"\n":118===t?"\v":102===t?"\f":114===t?"\r":101===t?"\x1b":32===t?" ":34===t?'"':47===t?"/":92===t?"\\":78===t?"\x85":95===t?"\xa0":76===t?"\u2028":80===t?"\u2029":""}function yn(t){return t<=65535?String.fromCharCode(t):String.fromCharCode(55296+(t-65536>>10),56320+(t-65536&1023))}for(var xn=new Array(256),Cn=new Array(256),bn=0;bn<256;bn++)xn[bn]=mn(bn)?1:0,Cn[bn]=mn(bn);function _n(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||Xr,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function vn(t,e){var i={name:t.filename,buffer:t.input.slice(0,-1),position:t.position,line:t.line,column:t.position-t.lineStart};return i.snippet=Cr(i),new mr(e,i)}function kn(t,e){throw vn(t,e)}function Tn(t,e){t.onWarning&&t.onWarning.call(null,vn(t,e))}var An={YAML:function(t,e,i){var r,n,o;null!==t.version&&kn(t,"duplication of %YAML directive"),1!==i.length&&kn(t,"YAML directive accepts exactly one argument"),null===(r=/^([0-9]+)\.([0-9]+)$/.exec(i[0]))&&kn(t,"ill-formed argument of the YAML directive"),n=parseInt(r[1],10),o=parseInt(r[2],10),1!==n&&kn(t,"unacceptable YAML version of the document"),t.version=i[0],t.checkLineBreaks=o<2,1!==o&&2!==o&&Tn(t,"unsupported YAML version of the document")},TAG:function(t,e,i){var r,n;2!==i.length&&kn(t,"TAG directive accepts exactly two arguments"),r=i[0],n=i[1],ln.test(r)||kn(t,"ill-formed tag handle (first argument) of the TAG directive"),Zr.call(t.tagMap,r)&&kn(t,'there is a previously declared suffix for "'+r+'" tag handle'),cn.test(n)||kn(t,"ill-formed tag prefix (second argument) of the TAG directive");try{n=decodeURIComponent(n)}catch(o){kn(t,"tag prefix is malformed: "+n)}t.tagMap[r]=n}};function wn(t,e,i,r){var n,o,a,s;if(e<i){if(s=t.input.slice(e,i),r)for(n=0,o=s.length;n<o;n+=1)9===(a=s.charCodeAt(n))||32<=a&&a<=1114111||kn(t,"expected valid JSON character");else on.test(s)&&kn(t,"the stream contains non-printable characters");t.result+=s}}function Sn(t,e,i,r){var n,o,a,s;for(fr.isObject(i)||kn(t,"cannot merge mappings; the provided source object is unacceptable"),a=0,s=(n=Object.keys(i)).length;a<s;a+=1)o=n[a],Zr.call(e,o)||(e[o]=i[o],r[o]=!0)}function Bn(t,e,i,r,n,o,a,s,l){var c,h;if(Array.isArray(n))for(c=0,h=(n=Array.prototype.slice.call(n)).length;c<h;c+=1)Array.isArray(n[c])&&kn(t,"nested arrays are not supported inside keys"),"object"==typeof n&&"[object Object]"===hn(n[c])&&(n[c]="[object Object]");if("object"==typeof n&&"[object Object]"===hn(n)&&(n="[object Object]"),n=String(n),null===e&&(e={}),"tag:yaml.org,2002:merge"===r)if(Array.isArray(o))for(c=0,h=o.length;c<h;c+=1)Sn(t,e,o[c],i);else Sn(t,e,o,i);else t.json||Zr.call(i,n)||!Zr.call(e,n)||(t.line=a||t.line,t.lineStart=s||t.lineStart,t.position=l||t.position,kn(t,"duplicated mapping key")),"__proto__"===n?Object.defineProperty(e,n,{configurable:!0,enumerable:!0,writable:!0,value:o}):e[n]=o,delete i[n];return e}function Fn(t){var e;10===(e=t.input.charCodeAt(t.position))?t.position++:13===e?(t.position++,10===t.input.charCodeAt(t.position)&&t.position++):kn(t,"a line break is expected"),t.line+=1,t.lineStart=t.position,t.firstTabInLine=-1}function Ln(t,e,i){for(var r=0,n=t.input.charCodeAt(t.position);0!==n;){for(;dn(n);)9===n&&-1===t.firstTabInLine&&(t.firstTabInLine=t.position),n=t.input.charCodeAt(++t.position);if(e&&35===n)do{n=t.input.charCodeAt(++t.position)}while(10!==n&&13!==n&&0!==n);if(!un(n))break;for(Fn(t),n=t.input.charCodeAt(t.position),r++,t.lineIndent=0;32===n;)t.lineIndent++,n=t.input.charCodeAt(++t.position)}return-1!==i&&0!==r&&t.lineIndent<i&&Tn(t,"deficient indentation"),r}function Mn(t){var e,i=t.position;return!(45!==(e=t.input.charCodeAt(i))&&46!==e||e!==t.input.charCodeAt(i+1)||e!==t.input.charCodeAt(i+2)||(i+=3,0!==(e=t.input.charCodeAt(i))&&!fn(e)))}function En(t,e){1===e?t.result+=" ":e>1&&(t.result+=fr.repeat("\n",e-1))}function Nn(t,e){var i,r,n=t.tag,o=t.anchor,a=[],s=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=a),r=t.input.charCodeAt(t.position);0!==r&&(-1!==t.firstTabInLine&&(t.position=t.firstTabInLine,kn(t,"tab characters must not be used in indentation")),45===r)&&fn(t.input.charCodeAt(t.position+1));)if(s=!0,t.position++,Ln(t,!0,-1)&&t.lineIndent<=e)a.push(null),r=t.input.charCodeAt(t.position);else if(i=t.line,In(t,e,Kr,!1,!0),a.push(t.result),Ln(t,!0,-1),r=t.input.charCodeAt(t.position),(t.line===i||t.lineIndent>e)&&0!==r)kn(t,"bad indentation of a sequence entry");else if(t.lineIndent<e)break;return!!s&&(t.tag=n,t.anchor=o,t.kind="sequence",t.result=a,!0)}function On(t){var e,i,r,n,o=!1,a=!1;if(33!==(n=t.input.charCodeAt(t.position)))return!1;if(null!==t.tag&&kn(t,"duplication of a tag property"),60===(n=t.input.charCodeAt(++t.position))?(o=!0,n=t.input.charCodeAt(++t.position)):33===n?(a=!0,i="!!",n=t.input.charCodeAt(++t.position)):i="!",e=t.position,o){do{n=t.input.charCodeAt(++t.position)}while(0!==n&&62!==n);t.position<t.length?(r=t.input.slice(e,t.position),n=t.input.charCodeAt(++t.position)):kn(t,"unexpected end of the stream within a verbatim tag")}else{for(;0!==n&&!fn(n);)33===n&&(a?kn(t,"tag suffix cannot contain exclamation marks"):(i=t.input.slice(e-1,t.position+1),ln.test(i)||kn(t,"named tag handle cannot contain such characters"),a=!0,e=t.position+1)),n=t.input.charCodeAt(++t.position);r=t.input.slice(e,t.position),sn.test(r)&&kn(t,"tag suffix cannot contain flow indicator characters")}r&&!cn.test(r)&&kn(t,"tag name cannot contain such characters: "+r);try{r=decodeURIComponent(r)}catch(s){kn(t,"tag name is malformed: "+r)}return o?t.tag=r:Zr.call(t.tagMap,i)?t.tag=t.tagMap[i]+r:"!"===i?t.tag="!"+r:"!!"===i?t.tag="tag:yaml.org,2002:"+r:kn(t,'undeclared tag handle "'+i+'"'),!0}function jn(t){var e,i;if(38!==(i=t.input.charCodeAt(t.position)))return!1;for(null!==t.anchor&&kn(t,"duplication of an anchor property"),i=t.input.charCodeAt(++t.position),e=t.position;0!==i&&!fn(i)&&!pn(i);)i=t.input.charCodeAt(++t.position);return t.position===e&&kn(t,"name of an anchor node must contain at least one character"),t.anchor=t.input.slice(e,t.position),!0}function In(t,e,i,r,n){var o,a,s,l,c,h,u,d,f,p=1,g=!1,m=!1;if(null!==t.listener&&t.listener("open",t),t.tag=null,t.anchor=null,t.kind=null,t.result=null,o=a=s=tn===i||Kr===i,r&&Ln(t,!0,-1)&&(g=!0,t.lineIndent>e?p=1:t.lineIndent===e?p=0:t.lineIndent<e&&(p=-1)),1===p)for(;On(t)||jn(t);)Ln(t,!0,-1)?(g=!0,s=o,t.lineIndent>e?p=1:t.lineIndent===e?p=0:t.lineIndent<e&&(p=-1)):s=!1;if(s&&(s=g||n),1!==p&&tn!==i||(d=Jr===i||Qr===i?e:e+1,f=t.position-t.lineStart,1===p?s&&(Nn(t,f)||function(t,e,i){var r,n,o,a,s,l,c,h=t.tag,u=t.anchor,d={},f=Object.create(null),p=null,g=null,m=null,y=!1,x=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=d),c=t.input.charCodeAt(t.position);0!==c;){if(y||-1===t.firstTabInLine||(t.position=t.firstTabInLine,kn(t,"tab characters must not be used in indentation")),r=t.input.charCodeAt(t.position+1),o=t.line,63!==c&&58!==c||!fn(r)){if(a=t.line,s=t.lineStart,l=t.position,!In(t,i,Qr,!1,!0))break;if(t.line===o){for(c=t.input.charCodeAt(t.position);dn(c);)c=t.input.charCodeAt(++t.position);if(58===c)fn(c=t.input.charCodeAt(++t.position))||kn(t,"a whitespace character is expected after the key-value separator within a block mapping"),y&&(Bn(t,d,f,p,g,null,a,s,l),p=g=m=null),x=!0,y=!1,n=!1,p=t.tag,g=t.result;else{if(!x)return t.tag=h,t.anchor=u,!0;kn(t,"can not read an implicit mapping pair; a colon is missed")}}else{if(!x)return t.tag=h,t.anchor=u,!0;kn(t,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===c?(y&&(Bn(t,d,f,p,g,null,a,s,l),p=g=m=null),x=!0,y=!0,n=!0):y?(y=!1,n=!0):kn(t,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),t.position+=1,c=r;if((t.line===o||t.lineIndent>e)&&(y&&(a=t.line,s=t.lineStart,l=t.position),In(t,e,tn,!0,n)&&(y?g=t.result:m=t.result),y||(Bn(t,d,f,p,g,m,a,s,l),p=g=m=null),Ln(t,!0,-1),c=t.input.charCodeAt(t.position)),(t.line===o||t.lineIndent>e)&&0!==c)kn(t,"bad indentation of a mapping entry");else if(t.lineIndent<e)break}return y&&Bn(t,d,f,p,g,null,a,s,l),x&&(t.tag=h,t.anchor=u,t.kind="mapping",t.result=d),x}(t,f,d))||function(t,e){var i,r,n,o,a,s,l,c,h,u,d,f,p=!0,g=t.tag,m=t.anchor,y=Object.create(null);if(91===(f=t.input.charCodeAt(t.position)))a=93,c=!1,o=[];else{if(123!==f)return!1;a=125,c=!0,o={}}for(null!==t.anchor&&(t.anchorMap[t.anchor]=o),f=t.input.charCodeAt(++t.position);0!==f;){if(Ln(t,!0,e),(f=t.input.charCodeAt(t.position))===a)return t.position++,t.tag=g,t.anchor=m,t.kind=c?"mapping":"sequence",t.result=o,!0;p?44===f&&kn(t,"expected the node content, but found ','"):kn(t,"missed comma between flow collection entries"),d=null,s=l=!1,63===f&&fn(t.input.charCodeAt(t.position+1))&&(s=l=!0,t.position++,Ln(t,!0,e)),i=t.line,r=t.lineStart,n=t.position,In(t,e,Jr,!1,!0),u=t.tag,h=t.result,Ln(t,!0,e),f=t.input.charCodeAt(t.position),!l&&t.line!==i||58!==f||(s=!0,f=t.input.charCodeAt(++t.position),Ln(t,!0,e),In(t,e,Jr,!1,!0),d=t.result),c?Bn(t,o,y,u,h,d,i,r,n):s?o.push(Bn(t,null,y,u,h,d,i,r,n)):o.push(h),Ln(t,!0,e),44===(f=t.input.charCodeAt(t.position))?(p=!0,f=t.input.charCodeAt(++t.position)):p=!1}kn(t,"unexpected end of the stream within a flow collection")}(t,d)?m=!0:(a&&function(t,e){var i,r,n,o,a,s=en,l=!1,c=!1,h=e,u=0,d=!1;if(124===(o=t.input.charCodeAt(t.position)))r=!1;else{if(62!==o)return!1;r=!0}for(t.kind="scalar",t.result="";0!==o;)if(43===(o=t.input.charCodeAt(++t.position))||45===o)en===s?s=43===o?nn:rn:kn(t,"repeat of a chomping mode identifier");else{if(!((n=48<=(a=o)&&a<=57?a-48:-1)>=0))break;0===n?kn(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):c?kn(t,"repeat of an indentation width identifier"):(h=e+n-1,c=!0)}if(dn(o)){do{o=t.input.charCodeAt(++t.position)}while(dn(o));if(35===o)do{o=t.input.charCodeAt(++t.position)}while(!un(o)&&0!==o)}for(;0!==o;){for(Fn(t),t.lineIndent=0,o=t.input.charCodeAt(t.position);(!c||t.lineIndent<h)&&32===o;)t.lineIndent++,o=t.input.charCodeAt(++t.position);if(!c&&t.lineIndent>h&&(h=t.lineIndent),un(o))u++;else{if(t.lineIndent<h){s===nn?t.result+=fr.repeat("\n",l?1+u:u):s===en&&l&&(t.result+="\n");break}for(r?dn(o)?(d=!0,t.result+=fr.repeat("\n",l?1+u:u)):d?(d=!1,t.result+=fr.repeat("\n",u+1)):0===u?l&&(t.result+=" "):t.result+=fr.repeat("\n",u):t.result+=fr.repeat("\n",l?1+u:u),l=!0,c=!0,u=0,i=t.position;!un(o)&&0!==o;)o=t.input.charCodeAt(++t.position);wn(t,i,t.position,!1)}}return!0}(t,d)||function(t,e){var i,r,n;if(39!==(i=t.input.charCodeAt(t.position)))return!1;for(t.kind="scalar",t.result="",t.position++,r=n=t.position;0!==(i=t.input.charCodeAt(t.position));)if(39===i){if(wn(t,r,t.position,!0),39!==(i=t.input.charCodeAt(++t.position)))return!0;r=t.position,t.position++,n=t.position}else un(i)?(wn(t,r,n,!0),En(t,Ln(t,!1,e)),r=n=t.position):t.position===t.lineStart&&Mn(t)?kn(t,"unexpected end of the document within a single quoted scalar"):(t.position++,n=t.position);kn(t,"unexpected end of the stream within a single quoted scalar")}(t,d)||function(t,e){var i,r,n,o,a,s,l;if(34!==(s=t.input.charCodeAt(t.position)))return!1;for(t.kind="scalar",t.result="",t.position++,i=r=t.position;0!==(s=t.input.charCodeAt(t.position));){if(34===s)return wn(t,i,t.position,!0),t.position++,!0;if(92===s){if(wn(t,i,t.position,!0),un(s=t.input.charCodeAt(++t.position)))Ln(t,!1,e);else if(s<256&&xn[s])t.result+=Cn[s],t.position++;else if((a=120===(l=s)?2:117===l?4:85===l?8:0)>0){for(n=a,o=0;n>0;n--)(a=gn(s=t.input.charCodeAt(++t.position)))>=0?o=(o<<4)+a:kn(t,"expected hexadecimal character");t.result+=yn(o),t.position++}else kn(t,"unknown escape sequence");i=r=t.position}else un(s)?(wn(t,i,r,!0),En(t,Ln(t,!1,e)),i=r=t.position):t.position===t.lineStart&&Mn(t)?kn(t,"unexpected end of the document within a double quoted scalar"):(t.position++,r=t.position)}kn(t,"unexpected end of the stream within a double quoted scalar")}(t,d)?m=!0:!function(t){var e,i,r;if(42!==(r=t.input.charCodeAt(t.position)))return!1;for(r=t.input.charCodeAt(++t.position),e=t.position;0!==r&&!fn(r)&&!pn(r);)r=t.input.charCodeAt(++t.position);return t.position===e&&kn(t,"name of an alias node must contain at least one character"),i=t.input.slice(e,t.position),Zr.call(t.anchorMap,i)||kn(t,'unidentified alias "'+i+'"'),t.result=t.anchorMap[i],Ln(t,!0,-1),!0}(t)?function(t,e,i){var r,n,o,a,s,l,c,h,u=t.kind,d=t.result;if(fn(h=t.input.charCodeAt(t.position))||pn(h)||35===h||38===h||42===h||33===h||124===h||62===h||39===h||34===h||37===h||64===h||96===h)return!1;if((63===h||45===h)&&(fn(r=t.input.charCodeAt(t.position+1))||i&&pn(r)))return!1;for(t.kind="scalar",t.result="",n=o=t.position,a=!1;0!==h;){if(58===h){if(fn(r=t.input.charCodeAt(t.position+1))||i&&pn(r))break}else if(35===h){if(fn(t.input.charCodeAt(t.position-1)))break}else{if(t.position===t.lineStart&&Mn(t)||i&&pn(h))break;if(un(h)){if(s=t.line,l=t.lineStart,c=t.lineIndent,Ln(t,!1,-1),t.lineIndent>=e){a=!0,h=t.input.charCodeAt(t.position);continue}t.position=o,t.line=s,t.lineStart=l,t.lineIndent=c;break}}a&&(wn(t,n,o,!1),En(t,t.line-s),n=o=t.position,a=!1),dn(h)||(o=t.position+1),h=t.input.charCodeAt(++t.position)}return wn(t,n,o,!1),!!t.result||(t.kind=u,t.result=d,!1)}(t,d,Jr===i)&&(m=!0,null===t.tag&&(t.tag="?")):(m=!0,null===t.tag&&null===t.anchor||kn(t,"alias node should not have any properties")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===p&&(m=s&&Nn(t,f))),null===t.tag)null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);else if("?"===t.tag){for(null!==t.result&&"scalar"!==t.kind&&kn(t,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+t.kind+'"'),l=0,c=t.implicitTypes.length;l<c;l+=1)if((u=t.implicitTypes[l]).resolve(t.result)){t.result=u.construct(t.result),t.tag=u.tag,null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);break}}else if("!"!==t.tag){if(Zr.call(t.typeMap[t.kind||"fallback"],t.tag))u=t.typeMap[t.kind||"fallback"][t.tag];else for(u=null,l=0,c=(h=t.typeMap.multi[t.kind||"fallback"]).length;l<c;l+=1)if(t.tag.slice(0,h[l].tag.length)===h[l].tag){u=h[l];break}u||kn(t,"unknown tag !<"+t.tag+">"),null!==t.result&&u.kind!==t.kind&&kn(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+u.kind+'", not "'+t.kind+'"'),u.resolve(t.result,t.tag)?(t.result=u.construct(t.result,t.tag),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):kn(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")}return null!==t.listener&&t.listener("close",t),null!==t.tag||null!==t.anchor||m}function Dn(t){var e,i,r,n,o=t.position,a=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap=Object.create(null),t.anchorMap=Object.create(null);0!==(n=t.input.charCodeAt(t.position))&&(Ln(t,!0,-1),n=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==n));){for(a=!0,n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!fn(n);)n=t.input.charCodeAt(++t.position);for(r=[],(i=t.input.slice(e,t.position)).length<1&&kn(t,"directive name must not be less than one character in length");0!==n;){for(;dn(n);)n=t.input.charCodeAt(++t.position);if(35===n){do{n=t.input.charCodeAt(++t.position)}while(0!==n&&!un(n));break}if(un(n))break;for(e=t.position;0!==n&&!fn(n);)n=t.input.charCodeAt(++t.position);r.push(t.input.slice(e,t.position))}0!==n&&Fn(t),Zr.call(An,i)?An[i](t,i,r):Tn(t,'unknown document directive "'+i+'"')}Ln(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,Ln(t,!0,-1)):a&&kn(t,"directives end mark is expected"),In(t,t.lineIndent-1,tn,!1,!0),Ln(t,!0,-1),t.checkLineBreaks&&an.test(t.input.slice(o,t.position))&&Tn(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&Mn(t)?46===t.input.charCodeAt(t.position)&&(t.position+=3,Ln(t,!0,-1)):t.position<t.length-1&&kn(t,"end of the stream or a document separator is expected")}function qn(t,e){e=e||{},0!==(t=String(t)).length&&(10!==t.charCodeAt(t.length-1)&&13!==t.charCodeAt(t.length-1)&&(t+="\n"),65279===t.charCodeAt(0)&&(t=t.slice(1)));var i=new _n(t,e),r=t.indexOf("\0");for(-1!==r&&(i.position=r,kn(i,"null byte is not allowed in input")),i.input+="\0";32===i.input.charCodeAt(i.position);)i.lineIndent+=1,i.position+=1;for(;i.position<i.length-1;)Dn(i);return i.documents}var $n=Or,zn={loadAll:function(t,e,i){null!==e&&"object"==typeof e&&void 0===i&&(i=e,e=null);var r=qn(t,i);if("function"!=typeof e)return r;for(var n=0,o=r.length;n<o;n+=1)e(r[n])},load:function(t,e){var i=qn(t,e);if(0!==i.length){if(1===i.length)return i[0];throw new mr("expected a single document in the stream, but found more")}}}.load;const Pn=t=>t.replace(/\r\n?/g,"\n").replace(/<(\w+)([^>]*)>/g,((t,e,i)=>"<"+e+i.replace(/="([^"]*)"/g,"='$1'")+">")),Rn=t=>{const{text:e,metadata:i}=function(t){const e=t.match(Ht);if(!e)return{text:t,metadata:{}};let i=zn(e[1],{schema:$n})??{};i="object"!=typeof i||Array.isArray(i)?{}:i;const r={};return i.displayMode&&(r.displayMode=i.displayMode.toString()),i.title&&(r.title=i.title.toString()),i.config&&(r.config=i.config),{text:t.slice(e[0].length),metadata:r}}(t),{displayMode:r,title:n,config:o={}}=i;return r&&(o.gantt||(o.gantt={}),o.gantt.displayMode=r),{title:n,config:o,text:e}},Wn=t=>{const e=ke.detectInit(t)??{},i=ke.detectDirective(t,"wrap");return Array.isArray(i)?e.wrap=i.some((({type:t})=>{})):"wrap"===(null==i?void 0:i.type)&&(e.wrap=!0),{text:(r=t,r.replace(Yt,"")),directive:e};var r};function Un(t){const e=Pn(t),i=Rn(e),r=Wn(i.text),n=ve(i.config,r.directive);return{code:t=ur(r.text),title:i.title,config:n}}const Hn=["foreignobject"],Yn=["dominant-baseline"];function Vn(t){const e=Un(t);return De(),Ie(e.config??{}),e}const Gn=(t,e,i=[])=>`\n.${t} ${e} { ${i.join(" !important; ")} !important; }`,Xn=(t,e,i,r)=>{const n=((t,e={})=>{var i;let r="";if(void 0!==t.themeCSS&&(r+=`\n${t.themeCSS}`),void 0!==t.fontFamily&&(r+=`\n:root { --mermaid-font-family: ${t.fontFamily}}`),void 0!==t.altFontFamily&&(r+=`\n:root { --mermaid-alt-font-family: ${t.altFontFamily}}`),!(0,ot.A)(e)){const n=t.htmlLabels||(null==(i=t.flowchart)?void 0:i.htmlLabels)?["> *","span"]:["rect","polygon","ellipse","circle","path"];for(const t in e){const i=e[t];(0,ot.A)(i.styles)||n.forEach((t=>{r+=Gn(i.id,t,i.styles)})),(0,ot.A)(i.textStyles)||(r+=Gn(i.id,"tspan",i.textStyles))}}return r})(t,i);return M(tt(`${r}{${_i(e,n,t.themeVariables)}}`),E)},Zn=(t,e,i,r,n)=>{const o=t.append("div");o.attr("id",i),r&&o.attr("style",r);const a=o.append("svg").attr("id",e).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg");return n&&a.attr("xmlns:xlink",n),a.append("g"),t};function Jn(t,e){return t.append("iframe").attr("id",e).attr("style","width: 100%; height: 100%;").attr("sandbox","")}const Qn=(t,e={})=>{const{code:i}=Un(t);return lr(i,e)};const Kn=Object.freeze({render:async function(t,e,i){var r,n,o,l,c,h;ar();const u=Vn(e);e=u.code;const d=Oe();st.debug(d),e.length>((null==d?void 0:d.maxTextSize)??5e4)&&(e="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa");const f="#"+t,p="i"+t,g="#"+p,m="d"+t,y="#"+m;let x=(0,a.Ltv)("body");const C="sandbox"===d.securityLevel,b="loose"===d.securityLevel,_=d.fontFamily;if(void 0!==i){if(i&&(i.innerHTML=""),C){const t=Jn((0,a.Ltv)(i),p);x=(0,a.Ltv)(t.nodes()[0].contentDocument.body),x.node().style.margin=0}else x=(0,a.Ltv)(i);Zn(x,t,m,`font-family: ${_}`,"http://www.w3.org/1999/xlink")}else{if(((t,e,i,r)=>{var n,o,a;null==(n=t.getElementById(e))||n.remove(),null==(o=t.getElementById(i))||o.remove(),null==(a=t.getElementById(r))||a.remove()})(document,t,m,p),C){const t=Jn((0,a.Ltv)("body"),p);x=(0,a.Ltv)(t.nodes()[0].contentDocument.body),x.node().style.margin=0}else x=(0,a.Ltv)("body");Zn(x,t,m)}let v,k;try{v=await Qn(e,{title:u.title})}catch(O){v=new sr("error"),k=O}const T=x.select(y).node(),A=v.type,w=T.firstChild,S=w.firstChild,B=null==(n=(r=v.renderer).getClasses)?void 0:n.call(r,e,v),F=Xn(d,A,B,f),L=document.createElement("style");L.innerHTML=F,w.insertBefore(L,S);try{await v.renderer.draw(e,t,Ae,v)}catch(j){throw Vi.draw(e,t,Ae),j}!function(t,e,i,r){(function(t,e){t.attr("role",hr),""!==e&&t.attr("aria-roledescription",e)})(e,t),function(t,e,i,r){if(void 0!==t.insert){if(i){const e=`chart-desc-${r}`;t.attr("aria-describedby",e),t.insert("desc",":first-child").attr("id",e).text(i)}if(e){const i=`chart-title-${r}`;t.attr("aria-labelledby",i),t.insert("title",":first-child").attr("id",i).text(e)}}}(e,i,r,e.attr("id"))}(A,x.select(`${y} svg`),null==(l=(o=v.db).getAccTitle)?void 0:l.call(o),null==(h=(c=v.db).getAccDescription)?void 0:h.call(c)),x.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns","http://www.w3.org/1999/xhtml");let M=x.select(y).node().innerHTML;if(st.debug("config.arrowMarkerAbsolute",d.arrowMarkerAbsolute),M=((t="",e,i)=>{let r=t;return i||e||(r=r.replace(/marker-end="url\([\d+./:=?A-Za-z-]*?#/g,'marker-end="url(#')),r=Te(r),r=r.replace(/<br>/g,"<br/>"),r})(M,C,yt(d.arrowMarkerAbsolute)),C){M=((t="",e)=>{var i,r;return`<iframe style="width:100%;height:${(null==(r=null==(i=null==e?void 0:e.viewBox)?void 0:i.baseVal)?void 0:r.height)?e.viewBox.baseVal.height+"px":"100%"};border:0;margin:0;" src="data:text/html;base64,${btoa('<body style="margin:0">'+t+"</body>")}" sandbox="allow-top-navigation-by-user-activation allow-popups">\n The "iframe" tag is not supported by your browser.\n</iframe>`})(M,x.select(y+" svg").node())}else b||(M=s.sanitize(M,{ADD_TAGS:Hn,ADD_ATTR:Yn}));if(cr.forEach((t=>{t()})),cr=[],k)throw k;const E=C?g:y,N=(0,a.Ltv)(E).node();return N&&"remove"in N&&N.remove(),{svg:M,bindFunctions:v.db.bindFunctions}},parse:async function(t,e){ar(),t=Vn(t).code;try{await Qn(t)}catch(i){if(null==e?void 0:e.suppressErrors)return!1;throw i}return!0},getDiagramFromText:Qn,initialize:function(t={}){var e;(null==t?void 0:t.fontFamily)&&!(null==(e=t.themeVariables)?void 0:e.fontFamily)&&(t.themeVariables||(t.themeVariables={}),t.themeVariables.fontFamily=t.fontFamily),Se=te({},t),(null==t?void 0:t.theme)&&t.theme in Dt?t.themeVariables=Dt[t.theme].getThemeVariables(t.themeVariables):t&&(t.themeVariables=Dt.default.getThemeVariables(t.themeVariables));const i="object"==typeof t?(t=>(Be=te({},we),Be=te(Be,t),t.theme&&Dt[t.theme]&&(Be.themeVariables=Dt[t.theme].getThemeVariables(t.themeVariables)),Me(Be,Fe),Be))(t):Ee();lt(i.logLevel),ar()},getConfig:Oe,setConfig:Ne,getSiteConfig:Ee,updateSiteConfig:t=>(Be=te(Be,t),Me(Be,Fe),Be),reset:()=>{De()},globalReset:()=>{De(we)},defaultConfig:we});lt(Oe().logLevel),De(Oe());const to=(t,e,i)=>{st.warn(t),be(t)?(i&&i(t.str,t.hash),e.push({...t,message:t.str,error:t})):(i&&i(t),t instanceof Error&&e.push({str:t.message,message:t.message,hash:t.name,error:t}))},eo=async function(t={querySelector:".mermaid"}){try{await io(t)}catch(e){if(be(e)&&st.error(e.str),co.parseError&&co.parseError(e),!t.suppressErrors)throw st.error("Use the suppressErrors option to suppress these errors"),e}},io=async function({postRenderCallback:t,querySelector:e,nodes:i}={querySelector:".mermaid"}){const n=Kn.getConfig();let o;if(st.debug((t?"":"No ")+"Callback function found"),i)o=i;else{if(!e)throw new Error("Nodes and querySelector are both undefined");o=document.querySelectorAll(e)}st.debug(`Found ${o.length} diagrams`),void 0!==(null==n?void 0:n.startOnLoad)&&(st.debug("Start On Load: "+(null==n?void 0:n.startOnLoad)),Kn.updateSiteConfig({startOnLoad:null==n?void 0:n.startOnLoad}));const a=new ke.InitIDGenerator(n.deterministicIds,n.deterministicIDSeed);let s;const l=[];for(const h of Array.from(o)){if(st.info("Rendering diagram: "+h.id),h.getAttribute("data-processed"))continue;h.setAttribute("data-processed","true");const e=`mermaid-${a.next()}`;s=h.innerHTML,s=(0,r.T)(ke.entityDecode(s)).trim().replace(/<br\s*\/?>/gi,"<br/>");const i=ke.detectInit(s);i&&st.debug("Detected early reinit: ",i);try{const{svg:i,bindFunctions:r}=await lo(e,s,h);h.innerHTML=i,t&&await t(e),r&&r(h)}catch(c){to(c,l,co.parseError)}}if(l.length>0)throw l[0]},ro=function(t){Kn.initialize(t)},no=function(){if(co.startOnLoad){const{startOnLoad:t}=Kn.getConfig();t&&co.run().catch((t=>st.error("Mermaid failed to initialize",t)))}};"undefined"!=typeof document&&window.addEventListener("load",no,!1);const oo=[];let ao=!1;const so=async()=>{if(!ao){for(ao=!0;oo.length>0;){const e=oo.shift();if(e)try{await e()}catch(t){st.error("Error executing queue",t)}}ao=!1}},lo=(t,e,i)=>new Promise(((r,n)=>{oo.push((()=>new Promise(((o,a)=>{Kn.render(t,e,i).then((t=>{o(t),r(t)}),(t=>{var e;st.error("Error parsing",t),null==(e=co.parseError)||e.call(co,t),a(t),n(t)}))})))),so().catch(n)})),co={startOnLoad:!0,mermaidAPI:Kn,parse:async(t,e)=>new Promise(((i,r)=>{oo.push((()=>new Promise(((n,o)=>{Kn.parse(t,e).then((t=>{n(t),i(t)}),(t=>{var e;st.error("Error parsing",t),null==(e=co.parseError)||e.call(co,t),o(t),r(t)}))})))),so().catch(r)})),render:lo,init:async function(t,e,i){st.warn("mermaid.init is deprecated. Please use run instead."),t&&ro(t);const r={postRenderCallback:i,querySelector:".mermaid"};"string"==typeof e?r.querySelector=e:e&&(e instanceof HTMLElement?r.nodes=[e]:r.nodes=e),await eo(r)},run:eo,registerExternalDiagrams:async(t,{lazyLoad:e=!0}={})=>{Jt(...t),!1===e&&await(async()=>{st.debug("Loading registered diagrams");const t=(await Promise.allSettled(Object.entries(Xt).map((async([t,{detector:e,loader:i}])=>{if(i)try{Wi(t)}catch(r){try{const{diagram:t,id:r}=await i();Ri(r,t,e)}catch(n){throw st.error(`Failed to load external diagram with key ${t}. Removing from detectors.`),delete Xt[t],n}}})))).filter((t=>"rejected"===t.status));if(t.length>0){st.error(`Failed to load ${t.length} external diagrams`);for(const e of t)st.error(e);throw new Error(`Failed to load ${t.length} external diagrams`)}})()},initialize:ro,parseError:void 0,contentLoaded:no,setParseErrorHandler:function(t){co.parseError=t},detectType:Zt}}}]); \ No newline at end of file diff --git a/assets/js/3498.52731744.js.LICENSE.txt b/assets/js/3498.52731744.js.LICENSE.txt new file mode 100644 index 0000000000..4298ea11b4 --- /dev/null +++ b/assets/js/3498.52731744.js.LICENSE.txt @@ -0,0 +1,9 @@ +/*! + * Wait for document loaded before starting the execution + */ + +/*! @license DOMPurify 3.0.11 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.11/LICENSE */ + +/*! Check if previously processed */ + +/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ diff --git a/assets/js/34c3e4b2.940ac935.js b/assets/js/34c3e4b2.940ac935.js new file mode 100644 index 0000000000..8727abfa08 --- /dev/null +++ b/assets/js/34c3e4b2.940ac935.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[163],{10929:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>d,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>o});var r=s(74848),n=s(28453);const a={},d="scs-0115: Default Rules for Security Groups",c={id:"iaas/scs-0115",title:"scs-0115: Default Rules for Security Groups",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/iaas/scs-0115.md",sourceDirName:"iaas",slug:"/iaas/scs-0115",permalink:"/standards/iaas/scs-0115",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Volume Type Standard",permalink:"/standards/scs-0114-v1-volume-type-standard"},next:{title:"Default Rules for Security Groups",permalink:"/standards/scs-0115-v1-default-rules-for-security-groups"}},i={},o=[];function l(e){const t={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"scs-0115-default-rules-for-security-groups",children:"scs-0115: Default Rules for Security Groups"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0115-v1-default-rules-for-security-groups",children:"scs-0115-v1"})}),(0,r.jsx)(t.td,{children:"Standard"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function u(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>c});var r=s(96540);const n={},a=r.createContext(n);function d(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:d(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/35b359a4.3bb7526f.js b/assets/js/35b359a4.3bb7526f.js new file mode 100644 index 0000000000..df0d5139bd --- /dev/null +++ b/assets/js/35b359a4.3bb7526f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7683],{94564:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>d,metadata:()=>o,toc:()=>h});var n=s(74848),l=s(28453),i=s(11470),r=s(19365);const d={sidebar_label:"Testbed Guide"},c="Testbed",o={id:"iaas/guides/other-guides/testbed",title:"Testbed",description:"With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack",source:"@site/docs/02-iaas/guides/other-guides/testbed.mdx",sourceDirName:"02-iaas/guides/other-guides",slug:"/iaas/guides/other-guides/testbed",permalink:"/docs/iaas/guides/other-guides/testbed",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/testbed.mdx",tags:[],version:"current",frontMatter:{sidebar_label:"Testbed Guide"},sidebar:"docs",previous:{title:"Style Guide",permalink:"/docs/iaas/guides/other-guides/style-guide"},next:{title:"Components",permalink:"/docs/category/components"}},a={},h=[{value:"Requirements",id:"requirements",level:2},{value:"Cloud access",id:"cloud-access",level:3},{value:"Cloud resources",id:"cloud-resources",level:3},{value:"Software",id:"software",level:3},{value:"Deployment",id:"deployment",level:2},{value:"Usage",id:"usage",level:2},{value:"Custom CA",id:"custom-ca",level:3},{value:"VPN access",id:"vpn-access",level:3},{value:"Wireguard",id:"wireguard",level:4},{value:"sshuttle",id:"sshuttle",level:4},{value:"Static entries in <code>/etc/hosts</code>",id:"static-entries-in-etchosts",level:3},{value:"Webinterfaces",id:"webinterfaces",level:3},{value:"Authentication with OIDC",id:"authentication-with-oidc",level:3},{value:"OpenStack web dashboard (Horizon) login via OIDC",id:"openstack-web-dashboard-horizon-login-via-oidc",level:4},{value:"OpenStack web dashboard (Horizon) logout",id:"openstack-web-dashboard-horizon-logout",level:4},{value:"Usage of the OpenStack CLI",id:"usage-of-the-openstack-cli",level:4},{value:"OpenStack CLI operations with OpenID Connect password",id:"openstack-cli-operations-with-openid-connect-password",level:4},{value:"OpenStack CLI token issue with OpenID Connect",id:"openstack-cli-token-issue-with-openid-connect",level:4},{value:"Advanced Usage",id:"advanced-usage",level:2},{value:"External API",id:"external-api",level:3},{value:"Change versions",id:"change-versions",level:3},{value:"Deploy services",id:"deploy-services",level:3},{value:"Upgrade services",id:"upgrade-services",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Ansible errors",id:"ansible-errors",level:3},{value:"Unsupported locale setting",id:"unsupported-locale-setting",level:3},{value:"Appendix",id:"appendix",level:2},{value:"Configuration",id:"configuration",level:3},{value:"Variables",id:"variables",level:4},{value:"Overrides",id:"overrides",level:4},{value:"Customisations",id:"customisations",level:4},{value:"Notes",id:"notes",level:3},{value:"Supported releases",id:"supported-releases",level:3},{value:"Included services",id:"included-services",level:3},{value:"Infrastructure",id:"infrastructure",level:4},{value:"OpenStack",id:"openstack",level:4},{value:"Makefile reference",id:"makefile-reference",level:3},{value:"CI jobs",id:"ci-jobs",level:3}];function x(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,l.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"testbed",children:"Testbed"}),"\n",(0,n.jsxs)(t.p,{children:["With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack\ndeployment on an existing OpenStack environment such as Cleura or ",(0,n.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["OSISM is the reference implementation for the Infrastructure as a Service (IaaS) layer in the\n",(0,n.jsx)(t.a,{href:"https://scs.community",children:"Sovereign Cloud Stack"})," (SCS) project. The OSISM Testbed is therefore\nused in the SCS project to test and work on the Instrastructure as a Service layer."]}),"\n",(0,n.jsx)(t.p,{children:"The OSISM Testbed is intended as a playground. Further services and integration will\nbe added over time. A increasing number of best practices and experiences from the productive\ndeployments will be included here in the future. It will become more production-like\nover time. However, at no point does it claim to represent a production setup exactly."}),"\n",(0,n.jsx)(t.h2,{id:"requirements",children:"Requirements"}),"\n",(0,n.jsx)(t.h3,{id:"cloud-access",children:"Cloud access"}),"\n",(0,n.jsx)(t.p,{children:"The usual prerequisite is to have an account on one of the supported OpenStack cloud providers.\nAs the OSISM Testbed also virtualizes systems itself, the OpenStack cluster should provide\nthe capabilities for nested virtualization."}),"\n",(0,n.jsx)(t.p,{children:"It is not part of this guide to describe the registration with the individual cloud\nproviders. Please contact the respective cloud provider for this."}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Product"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Provider"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Profile name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Cleura"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Cleura"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"cleura"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Fuga Cloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"FUGA"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"fuga"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HuaweiCloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HuaweiCloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"huaweicloud"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OVH"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OVH"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"ovh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OpenTelekomCloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"T-Systems"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"otc"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"pluscloud open"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"plusserver"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"pluscloudopen"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"pluscloud SCS Test"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"plusserver"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"gx-scs"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"REGIO.cloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OSISM"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"regiocloud"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"REGIO.cloud"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OSISM"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"regio-fast"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"boot from NVMe SSD backed volumes"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Wavestack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"noris network"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"wavestack"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsxs)(t.p,{children:["For each cloud provider listed in the table, a predefined profile is available in the\n",(0,n.jsx)(t.code,{children:"terraform/environments"})," directory. This profile contains the name of the public\nnetwork, which flavors to use, etc."]}),"\n",(0,n.jsxs)(t.p,{children:["Here is an example from the profile for ",(0,n.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-text",children:'flavor_manager = "SCS-4V-16-50"\nflavor_node = "SCS-8V-32-50"\nvolume_type = "ssd"\nimage = "Ubuntu 22.04"\nimage_node = "Ubuntu 22.04"\npublic = "public"\navailability_zone = "nova"\nvolume_availability_zone = "nova"\nnetwork_availability_zone = "nova"\n'})}),"\n",(0,n.jsx)(t.h3,{id:"cloud-resources",children:"Cloud resources"}),"\n",(0,n.jsx)(t.p,{children:"The OSISM Testbed requires at least the following project quota when using the default flavors:"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Quantity"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Resource"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"4"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Instances"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"28 VCPUs + 112 GByte RAM (3 modes, 1 manager)"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"9"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Volumes"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"90 GByte volume storage"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Floating IP"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Keypair"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"3"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Security group"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"16"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Security group rules"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Network"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Subetwork"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"6"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Ports"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"1"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Router"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"software",children:"Software"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"make"})," must be installed on the system"]}),"\n",(0,n.jsxs)(t.li,{children:["Wireguard or ",(0,n.jsx)(t.code,{children:"sshuttle"})," must be installed on your system for VPN access"]}),"\n",(0,n.jsxs)(t.li,{children:["Python must be installed, the Python version used must be at least 3.10, otherwise\nthe current Ansible release cannot be used (details in the\n",(0,n.jsx)(t.a,{href:"https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix",children:"Ansible support matrix"}),")"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"python3-venv"})," must be installed for managing Python dependencies like Ansible"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"deployment",children:"Deployment"}),"\n",(0,n.jsx)(t.p,{children:"This section describes step by step how to deploy the OSISM Testbed."}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Request access from the administrator of the respective cloud or get access to an OpenStack cloud."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["Clone the ",(0,n.jsx)(t.a,{href:"https://github.com/osism/testbed",children:"osism/testbed"})," repository."]}),"\n",(0,n.jsx)(t.p,{children:"The repository can also be cloned to any other location."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"mkdir -p ~/src/github.com/osism\ngit clone https://github.com/osism/testbed ~/src/github.com/osism/testbed\ncd ~/src/github.com/osism/testbed\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Configure your cloud access profile"}),"\n",(0,n.jsxs)(t.p,{children:["The access data for the cloud provider used is stored in ",(0,n.jsx)(t.code,{children:"terraform/clouds.yaml"})," and (optionally)\nin ",(0,n.jsx)(t.code,{children:"terraform/secure.yaml"})," (same structure, if you want to store credentials on a separate place)."]}),"\n",(0,n.jsxs)(t.p,{children:["In file ",(0,n.jsx)(t.a,{href:"https://github.com/osism/testbed/blob/main/terraform/clouds.yaml.sample",children:"terraform/clouds.yaml.sample"}),"\nyou will find examples of typical setups. Settings that are identical for all users of a cloud can be defined\ncentrally via the profiles of the file\n",(0,n.jsx)(t.a,{href:"https://github.com/osism/testbed/blob/main/terraform/clouds-public.yaml",children:"terraform/clouds-public.yaml"}),".\nYou can reference these settings by using the ",(0,n.jsx)(t.code,{children:"profile"})," parameter in cloud-specific\ndefinition in ",(0,n.jsx)(t.code,{children:"terraform/clouds.yaml"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["The user specific settings of the ",(0,n.jsx)(t.code,{children:"clouds.yaml"})," file are provided by the cloud provider. Please check the\ndocumentation of the cloud provider you are using or their support for details."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"})," is used as an example here. The cloud name in ",(0,n.jsx)(t.code,{children:"clouds.yaml"}),"\nand the environment name (value of ",(0,n.jsx)(t.code,{children:"ENVIRONMENT"}),") are ",(0,n.jsx)(t.code,{children:"regiocloud"})," in this case. It is important that\nthe name of the cloud in ",(0,n.jsx)(t.code,{children:"clouds.yaml"})," matches the name of the environment to be used. The names must\nbe identical. It is currently not possible to name the cloud ",(0,n.jsx)(t.code,{children:"regiocloud-123"})," in ",(0,n.jsx)(t.code,{children:"clouds.yaml"})," if the\nenvironment is ",(0,n.jsx)(t.code,{children:"regiocloud"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["If another cloud is used, replace ",(0,n.jsx)(t.code,{children:"regiocloud"})," with the respective profile name ",(0,n.jsx)(t.a,{href:"#cloud-access",children:"from the table above"}),"."]}),"\n",(0,n.jsxs)(i.A,{children:[(0,n.jsxs)(r.A,{value:"testbed-cloud-access-with-app-credentials",label:"Application Credentials",children:[(0,n.jsxs)(t.p,{children:["The use of application credentials is preferred. This way it is not necessary to store\ndetails like username, project name or sensitive information like the password in the\n",(0,n.jsx)(t.code,{children:"clouds.yaml"})," file."]}),(0,n.jsxs)(t.p,{children:["The application credentials can be found in Horizon under ",(0,n.jsx)(t.strong,{children:"Identity"}),". Use ",(0,n.jsx)(t.code,{children:"OSISM Testbed"})," as\nname and click ",(0,n.jsx)(t.code,{children:"Create Application Credential"}),"."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/clouds.yaml"',children:'clouds:\n regiocloud:\n profile: regiocloud\n auth:\n application_credential_id: ID\n application_credential_secret: SECRET\n auth_type: "v3applicationcredential"\n'})}),(0,n.jsxs)(t.p,{children:["If you want to make use of ",(0,n.jsx)(t.code,{children:"terraform/secure.yaml"})," add your application credential secret there\ninstead of ",(0,n.jsx)(t.code,{children:"terraform/clouds.yaml"}),"."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/secure.yaml"',children:"clouds:\n regiocloud:\n auth:\n application_credential_secret: SECRET\n"})})]}),(0,n.jsxs)(r.A,{value:"testbed-cloud-access-with-username-password",label:"Username/Password",children:[(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/clouds.yaml"',children:"clouds:\n regiocloud:\n profile: regiocloud\n auth:\n project_name: PROJECT\n username: USERNAME\n project_domain_name: DOMAIN\n user_domain_name: DOMAIN\n"})}),(0,n.jsxs)(t.p,{children:["If you want to make use of ",(0,n.jsx)(t.code,{children:"terraform/secure.yaml"})," add your password there instead of ",(0,n.jsx)(t.code,{children:"terraform/clouds.yaml"}),"."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",metastring:'title="terraform/secure.yaml"',children:"clouds:\n regiocloud:\n auth:\n password: PASSWORD\n"})})]})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Prepare the deployment."}),"\n",(0,n.jsxs)(t.p,{children:["The versions of Ansible and ",(0,n.jsx)(t.a,{href:"https://opentofu.org",children:"OpenTofu"})," are managed\nautomatically and necessary dependencies are cloned."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make prepare\n"})}),"\n",(0,n.jsxs)(t.p,{children:["If any error occurs during preparation and you want to run the preparation\nagain, it is important to run ",(0,n.jsx)(t.code,{children:"make wipe-local-install"})," first. Otherwise the\npreparation will not be redone completely and necessary parts will be missing\nlater on."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Create the infrastructure with OpenTofu."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud create\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Deploy the OSISM manager and bootstrap all nodes."}),"\n",(0,n.jsxs)(i.A,{children:[(0,n.jsx)(r.A,{value:"testbed-deploy-latst",label:"Deploy latest manager version",children:(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud manager\n"})})}),(0,n.jsx)(r.A,{value:"testbed-deploy-stable",label:"Deploy a stable manager version",children:(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud VERSION_MANAGER=7.0.3 manager\n"})})})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"After the bootstrap, you can log in to the manager via SSH."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud login\n"})}),"\n",(0,n.jsx)(t.p,{children:"Yo can log in to the nodes of the cluster via the manager."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"osism console testbed-node-0\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Deploy all services."}),"\n",(0,n.jsxs)(i.A,{children:[(0,n.jsxs)(r.A,{value:"testbed-deploy-multi-steps",label:"Deployment in single steps",children:[(0,n.jsxs)(t.p,{children:["It is also possible to deploy the services step by step on the\nmanager. To do this, first log in to the manager with ",(0,n.jsx)(t.code,{children:"make ENVIRONMENT=regiocloud login"}),"\nand then execute the deploy scripts one after the other. It is recommended to do this\nwithin a screen session."]}),(0,n.jsx)(t.p,{children:"Deploying the services takes some time and depends on how much bandwidth is available,\nhow the instances are equipped, etc. 90-120 minutes is not unusual when Ceph and OpenStack\nare fully deployed."}),(0,n.jsxs)(t.p,{children:["To speed up the Ansible playbooks, ",(0,n.jsx)(t.a,{href:"https://ara.recordsansible.org",children:"ARA"})," can be disabled. This\nis done by executing ",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/disable-ara.sh"}),". Run this script ",(0,n.jsx)(t.strong,{children:"before"})," the deployment scripts.\nAfterwards no more logs are available in the ARA web\ninterface. To re-enable ARA use ",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/enable-ara.sh"}),"."]}),(0,n.jsxs)(t.p,{children:["There is also the option of pre-population of images with ",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/pull-images.sh"}),"\nso that deployments do not have to be lengthy. Run this script ",(0,n.jsx)(t.strong,{children:"before"})," the deployment scripts."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"/opt/configuration/scripts/deploy/001-helper-services.sh\n/opt/configuration/scripts/deploy/005-kubernetes.sh\n/opt/configuration/scripts/deploy/100-ceph-services-basic.sh\n/opt/configuration/scripts/deploy/200-infrastructure-services-basic.sh\n/opt/configuration/scripts/deploy/300-openstack-services-basic.sh\n/opt/configuration/scripts/deploy/400-monitoring-services.sh\n"})}),(0,n.jsxs)(t.p,{children:["Prepare OpenStack resources like public network, flavors and images by running\n",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/bootstrap.sh"}),". Run this script ",(0,n.jsx)(t.strong,{children:"after"})," the deployment scripts."]}),(0,n.jsxs)(t.admonition,{type:"info",children:[(0,n.jsxs)(t.p,{children:["If you only want to deploy the monitoring services with ",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/400-monitoring-services.sh"}),",\na few dependencies must be deployed first. You can then use the monitoring services without having to install a\ncomplete OpenStack & Ceph environment."]}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"osism apply common\nosism apply loadbalancer\nosism apply opensearch\nosism apply mariadb\n"})})]})]}),(0,n.jsxs)(r.A,{value:"testbed-deploy-single-step",label:"Deployment of all services",children:[(0,n.jsx)(t.p,{children:"In this single step deployment, Ceph, OpenStack and all necessary\ninfrastructure services (MariaDB, RabbitMQ, ...) are deployed.\nDepending on the cloud, the deployment will take some time. Up to two hours is not unusual."}),(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud deploy\n"})})]})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["If you want to verify the deployment with ",(0,n.jsx)(t.a,{href:"https://opendev.org/openinfra/refstack",children:"refstack"})," run\n",(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/check.sh"}),". This step will take some time and is optional."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"The machine images required for the use of Kubernetes Cluster API and the amphora driver of OpenStack Octavia\nservice are not provided by default to save resources on the OSISM Testbed and improve deployment time.\nThese can be provisioned if required."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"/opt/configuration/scripts/bootstrap/301-openstack-octavia-amhpora-image.sh\n/opt/configuration/scripts/bootstrap/302-openstack-k8s-clusterapi-images.sh\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"If you want you can create a test project with a test user after login. It also\ncreates an instance with a volume attached to a network with a router. This step is optional."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"osism apply --environment openstack test\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"When the OSISM Testbed is no longer needed, it can be deleted."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"make ENVIRONMENT=regiocloud clean\n"})}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"usage",children:"Usage"}),"\n",(0,n.jsx)(t.p,{children:"Deployment must be completed at this point."}),"\n",(0,n.jsx)(t.h3,{id:"custom-ca",children:"Custom CA"}),"\n",(0,n.jsxs)(t.p,{children:["The OSISM Testbed deployment currently uses hostnames in the domain ",(0,n.jsx)(t.code,{children:"testbed.osism.xyz"}),". This is a real domain\nand we provide the DNS records matching the addresses used in the OSISM Testbed, so that once you connect to your testbed via a direct\nlink or Wireguard, you can access hosts and servers by their hostname (e.g. ",(0,n.jsx)(t.code,{children:"ssh testbed-manager.testbed.osism.xyz"}),")."]}),"\n",(0,n.jsxs)(t.p,{children:["We also provide a wildcard TLS certificate signed by a custom CA for ",(0,n.jsx)(t.code,{children:"testbed.osism.xyz"})," and ",(0,n.jsx)(t.code,{children:"*.testbed.osism.xyz"}),".\nThis CA is always used for each testbed. The CA is not regenerated and it is not planned to change this for the next 10 years."]}),"\n",(0,n.jsxs)(t.p,{children:["In order for these certificates to be recognized locally as valid, the CA\n",(0,n.jsx)(t.a,{href:"https://raw.githubusercontent.com/osism/testbed/main/environments/kolla/certificates/ca/testbed.crt",children:"environments/kolla/certificates/ca/testbed.crt"}),"\nmust be imported locally."]}),"\n",(0,n.jsx)(t.h3,{id:"vpn-access",children:"VPN access"}),"\n",(0,n.jsx)(t.h4,{id:"wireguard",children:"Wireguard"}),"\n",(0,n.jsxs)(t.p,{children:["Install wireguard on your workstation, if you have not done this before. For instructions how to do\nit on your workstation, please have a look on the documentation of your used distribution. The\nwireguard documentation you will find ",(0,n.jsx)(t.a,{href:"https://www.wireguard.com",children:"here"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"Start the wireguard tunnel.\n(Press CTRL+c to keep the tunnel running forever. The make target also launches a browser tab with references to all services)"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"make vpn-wireguard ENVIRONMENT=regiocloud\n"})}),"\n",(0,n.jsx)(t.p,{children:"If you want to connect to the OSISM Testbed from multiple clients, change the client IP\naddress in the downloaded configuration file to be different on each client."}),"\n",(0,n.jsxs)(t.p,{children:["If you only want to download the Wireguard configuration, you can use the ",(0,n.jsx)(t.code,{children:"vpn-wireguard-config"}),"\ntarget. The configuration is then available in the file ",(0,n.jsx)(t.code,{children:"wg-testbed-regiocloud.conf"}),", for example."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"make vpn-wireguard-config ENVIRONMENT=regiocloud\n"})}),"\n",(0,n.jsx)(t.h4,{id:"sshuttle",children:"sshuttle"}),"\n",(0,n.jsxs)(t.p,{children:["If you do not want to use Wireguard you can also work with ",(0,n.jsx)(t.a,{href:"https://github.com/sshuttle/sshuttle",children:"sshuttle"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"make vpn-sshuttle ENVIRONMENT=regiocloud\nkillall sshuttle\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"static-entries-in-etchosts",children:["Static entries in ",(0,n.jsx)(t.code,{children:"/etc/hosts"})]}),"\n",(0,n.jsxs)(t.p,{children:["If you are unable to access the following domains, you can customize your local ",(0,n.jsx)(t.code,{children:"/etc/hosts"}),"\nwith the following static entries. This may be necessary, for example, if you use Pi-hole and\nall DNS entries from a public DNS with a non-public IP address are filtered."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"# OSISM Testbed hosts\n192.168.16.5 ara.testbed.osism.xyz ara\n192.168.16.5 cgit.testbed.osism.xyz cgit\n192.168.16.5 flower.testbed.osism.xyz flower\n192.168.16.5 homer.testbed.osism.xyz homer\n192.168.16.5 netbox.testbed.osism.xyz netbox\n192.168.16.5 testbed-manager.testbed.osism.xyz testbed-manager\n192.168.16.5 nexus.testbed.osism.xyz nexus\n192.168.16.5 phpmyadmin.testbed.osism.xyz phpmyadmin\n192.168.16.9 api-int.testbed.osism.xyz api-int\n192.168.16.10 testbed-node-0.testbed.osism.xyz testbed-node-0\n192.168.16.11 testbed-node-1.testbed.osism.xyz testbed-node-1\n192.168.16.12 testbed-node-2.testbed.osism.xyz testbed-node-2\n192.168.16.13 testbed-node-3.testbed.osism.xyz testbed-node-3\n192.168.16.14 testbed-node-4.testbed.osism.xyz testbed-node-4\n192.168.16.15 testbed-node-5.testbed.osism.xyz testbed-node-5\n192.168.16.16 testbed-node-6.testbed.osism.xyz testbed-node-6\n192.168.16.17 testbed-node-7.testbed.osism.xyz testbed-node-7\n192.168.16.18 testbed-node-8.testbed.osism.xyz testbed-node-8\n192.168.16.19 testbed-node-9.testbed.osism.xyz testbed-node-9\n192.168.16.100 keycloak.testbed.osism.xyz keycloak\n192.168.16.254 api.testbed.osism.xyz api\n"})}),"\n",(0,n.jsx)(t.h3,{id:"webinterfaces",children:"Webinterfaces"}),"\n",(0,n.jsxs)(t.p,{children:["All SSL enabled services within the OSISM Testbed use certs which are signed by the self-signed\n",(0,n.jsx)(t.a,{href:"https://raw.githubusercontent.com/osism/testbed/main/environments/kolla/certificates/ca/testbed.crt",children:"OSISM Testbed CA"}),"\n(Download the file and import it as certification authority to your browser)."]}),"\n",(0,n.jsx)(t.p,{children:"If you want to access the services please choose the URL from the following table."}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"URL"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Username"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Password"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"ARA"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://ara.testbed.osism.xyz",children:"https://ara.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"ara"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Ceph"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:8140",children:"https://api-int.testbed.osism.xyz:8140"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Flower"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://flower.testbed.osism.xyz",children:"https://flower.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Grafana"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:3000",children:"https://api-int.testbed.osism.xyz:3000"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HAProxy (testbed-node-0)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"http://testbed-node-0.testbed.osism.xyz:1984",children:"http://testbed-node-0.testbed.osism.xyz:1984"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HAProxy (testbed-node-1)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"http://testbed-node-1.testbed.osism.xyz:1984",children:"http://testbed-node-1.testbed.osism.xyz:1984"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"HAProxy (testbed-node-2)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"http://testbed-node-2.testbed.osism.xyz:1984",children:"http://testbed-node-2.testbed.osism.xyz:1984"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Homer"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://homer.testbed.osism.xyz",children:"https://homer.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Horizon (via Keycloak)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api.testbed.osism.xyz",children:"https://api.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"alice"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Horizon (via Keystone)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api.testbed.osism.xyz",children:"https://api.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"domain: default"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Horizon (via Keystone)"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api.testbed.osism.xyz",children:"https://api.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"test"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"test"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"domain: test"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Keycloak"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz/auth",children:"https://keycloak.testbed.osism.xyz/auth"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Netbox"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://netbox.testbed.osism.xyz",children:"https://netbox.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Netdata"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"http://testbed-manager.testbed.osism.xyz:19999",children:"http://testbed-manager.testbed.osism.xyz:19999"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Nexus"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://nexus.testbed.osism.xyz",children:"https://nexus.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"OpenSearch Dashboards"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api.testbed.osism.xyz:5601",children:"https://api.testbed.osism.xyz:5601"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"opensearch"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Prometheus"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:9091",children:"https://api-int.testbed.osism.xyz:9091"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"admin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"RabbitMQ"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://api-int.testbed.osism.xyz:15672",children:"https://api-int.testbed.osism.xyz:15672"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"phpMyAdmin"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.a,{href:"https://phpmyadmin.testbed.osism.xyz",children:"https://phpmyadmin.testbed.osism.xyz"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"root"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"password"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"authentication-with-oidc",children:"Authentication with OIDC"}),"\n",(0,n.jsx)(t.p,{children:"Authentication with OpenID Connect (OIDC) is possible via Keycloak, which is automatically configured for the OIDC mechanism."}),"\n",(0,n.jsx)(t.h4,{id:"openstack-web-dashboard-horizon-login-via-oidc",children:"OpenStack web dashboard (Horizon) login via OIDC"}),"\n",(0,n.jsxs)(t.p,{children:["For logging in via OIDC, open your browser at OpenStack Dashboard Login Page, select ",(0,n.jsx)(t.strong,{children:"Authenticate via Keycloak"}),", after being\nredirected to the Keycloak login page, perform the login with the credentials ",(0,n.jsx)(t.strong,{children:"alice"})," and ",(0,n.jsx)(t.strong,{children:"password"}),".\nAfter that you will be redirected back to the Horizon dashboard, where you will be logged in with the user ",(0,n.jsx)(t.strong,{children:"alice"}),"."]}),"\n",(0,n.jsx)(t.h4,{id:"openstack-web-dashboard-horizon-logout",children:"OpenStack web dashboard (Horizon) logout"}),"\n",(0,n.jsxs)(t.p,{children:["Keep in mind, that clicking ",(0,n.jsx)(t.strong,{children:"Sign Out"})," on the Horizon dashboard currently doesn't revoke your OIDC token, and any consequent\nattempt to ",(0,n.jsx)(t.strong,{children:"Authenticate via Keycloak"})," will succeed without providing the credentials."]}),"\n",(0,n.jsx)(t.p,{children:"The expiration time of the Single Sign On tokens can be controlled on multiple levels in Keycloak."}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["On realm level under ",(0,n.jsx)(t.em,{children:"Realm Settings"})," > ",(0,n.jsx)(t.em,{children:"Tokens"}),".\nAssuming the ",(0,n.jsx)(t.em,{children:"keycloak_realm"})," ansible variable is the default ",(0,n.jsx)(t.em,{children:"osism"}),", and keycloak is listening on\n",(0,n.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz",children:"keycloak.testbed.osism.xyz"}),", then the configuration form is available\n",(0,n.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz/auth/admin/master/console/#/realms/osism/token-settings",children:"here"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["Detailed information is available in the Keycloak Server Administrator Documentation\n",(0,n.jsx)(t.a,{href:"https://www.keycloak.org/docs/latest/server_admin/#_timeouts",children:"Session and Token Timeouts"})," section."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["In a realm down on the ",(0,n.jsx)(t.a,{href:"https://keycloak.testbed.osism.xyz/auth/admin/master/console/#/realms/osism/clients",children:"client level"}),"\nselect the client (keystone), and under ",(0,n.jsx)(t.em,{children:"Settings"})," > ",(0,n.jsx)(t.em,{children:"Advanced Settings"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["It is recommended to keep the ",(0,n.jsx)(t.em,{children:"Access Token Lifespan"})," on a relatively low value, with the trend of blocking third party\ncookies. For further information see the Keycloak documentation's ",(0,n.jsx)(t.a,{href:"https://www.keycloak.org/docs/latest/securing_apps/#browsers-with-blocked-third-party-cookies",children:"Browsers with Blocked Third-Party Cookies"})," section."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h4,{id:"usage-of-the-openstack-cli",children:"Usage of the OpenStack CLI"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.code,{children:"environments/openstack"})," folder contains the needed files for the openstack client:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"cd environments/openstack\nexport OS_CLOUD=<the cloud environment> # i.e. admin\nopenstack floating ip list\n"})}),"\n",(0,n.jsx)(t.h4,{id:"openstack-cli-operations-with-openid-connect-password",children:"OpenStack CLI operations with OpenID Connect password"}),"\n",(0,n.jsxs)(t.p,{children:["Using the OpenStack cli is also possible via OIDC, assuming you provisioned the user ",(0,n.jsx)(t.strong,{children:"alice"})," with password ",(0,n.jsx)(t.strong,{children:"password"}),",\nthen you can perform a simple ",(0,n.jsx)(t.code,{children:"project list"})," operation like this:"]}),"\n",(0,n.jsx)(t.p,{children:'See chapter "Usage the OpenStack CLI" for basic openstack usage.'}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"openstack \\\n --os-cacert /etc/ssl/certs/ca-certificates.crt \\\n --os-auth-url https://api.testbed.osism.xyz:5000/v3 \\\n --os-auth-type v3oidcpassword \\\n --os-client-id keystone \\\n --os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \\\n --os-username alice \\\n --os-password password \\\n --os-identity-provider keycloak \\\n --os-protocol openid \\\n --os-identity-api-version 3 \\\n --os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \\\nproject list\n"})}),"\n",(0,n.jsx)(t.h4,{id:"openstack-cli-token-issue-with-openid-connect",children:"OpenStack CLI token issue with OpenID Connect"}),"\n",(0,n.jsxs)(t.p,{children:["It is also possible to exchange your username/password to a token, for further use with the cli.\nThe ",(0,n.jsx)(t.code,{children:"token issue"})," subcommand returns an SQL table, in which the ",(0,n.jsx)(t.code,{children:"id"})," column's ",(0,n.jsx)(t.code,{children:"value"})," field contains the token:"]}),"\n",(0,n.jsx)(t.p,{children:'See chapter "Usage the OpenStack CLI" for basic openstack usage.'}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:'openstack \\\n --os-cacert /etc/ssl/certs/ca-certificates.crt \\\n --os-auth-url https://api.testbed.osism.xyz:5000/v3 \\\n --os-auth-type v3oidcpassword \\\n --os-client-id keystone \\\n --os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \\\n --os-username alice \\\n --os-password password \\\n --os-identity-provider keycloak \\\n --os-protocol openid \\\n --os-identity-api-version 3 \\\n --os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \\\n --os-openid-scope "openid profile email" \\\ntoken issue \\\n -c id\n -f value\n'})}),"\n",(0,n.jsx)(t.p,{children:"An example token is like:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"gAAAAABhC98gL8nsQWknro3JWDXWLFCG3CDr3Mi9OIlvVAZMjy2mNgYtlXv_0yAIy-\nnSlLAaLIGhht17-mwf8uclKgRuNVsYLSmgUpB163l89-ch2w2_OFe9zNSQNWf4qfd8\nCl7E7XvvUoFr1N8Gh09vaYLvRvYgCGV05xBUSs76qCHa0qElPUsk56s5ft4ALrSrzD\n4cEQRVb5PXNjywdZk9_gtJziz31A7sD4LPIy82O5N9NryDoDw\n"})}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"TODO: OpenStack CLI operations with token"}),"\n",(0,n.jsx)(t.li,{children:"TODO: OpenStack CLI token revoke"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"advanced-usage",children:"Advanced Usage"}),"\n",(0,n.jsx)(t.h3,{id:"external-api",children:"External API"}),"\n",(0,n.jsxs)(t.p,{children:["It is possible to provide the OpenStack APIs and the OpenStack Dashboard via the manager's public IP address.\nThis is not enabled by default, with the exception of the OTC profile. To provide the OpenStack APIs and the\nOpenStack dashboard via the public IP address of the manager, the following changes are necessary in the\n",(0,n.jsx)(t.code,{children:"terraform/environments/regiocloud.tfvars"})," file. If a cloud other than the REGIO.cloud is used, the profile\nof the other cloud is changed accordingly."]}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["Add the customisation ",(0,n.jsx)(t.code,{children:"external_api"}),". This customisation makes sure that the required security group rules\nare created for the various OpenStack APIs and the OpenStack dashboard."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"# customisation:external_api\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["Set parameter ",(0,n.jsx)(t.code,{children:"external_api"})," to ",(0,n.jsx)(t.code,{children:"true"}),". This makes sure that all necessary changes are made in the configuration\nrepository when the Manager service is deployed. It is correct that this is added as a comment."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"external_api = true\n"})}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["After the deployment of the Manager service and the OpenStack services, the OpenStack APIs and the OpenStack\ndashboard can be reached via a DNS name. The service ",(0,n.jsx)(t.a,{href:"https://traefik.me",children:"traefik.me"})," is used for the DNS record.\nRun the following two commands on the manager node to get the DNS record."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:'$ source /opt/manager-vars.sh\n$ echo "api-${MANAGER_PUBLIC_IP_ADDRESS//./-}.traefik.me"\napi-80-158-46-219.traefik.me\n'})}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"change-versions",children:"Change versions"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["Go to ",(0,n.jsx)(t.code,{children:"/opt/configuration"})," on ",(0,n.jsx)(t.code,{children:"testbed-manager"})]}),"\n",(0,n.jsxs)(t.li,{children:["Run ",(0,n.jsx)(t.code,{children:"./scripts/set-openstack-version.sh 2023.2"})," to set the OpenStack version to ",(0,n.jsx)(t.code,{children:"2023.2"})]}),"\n",(0,n.jsxs)(t.li,{children:["Run ",(0,n.jsx)(t.code,{children:"./scripts/set-ceph-version.sh reef"})," to set the Ceph version to ",(0,n.jsx)(t.code,{children:"reef"})]}),"\n",(0,n.jsxs)(t.li,{children:["Run ",(0,n.jsx)(t.code,{children:"osism update manager"})," to update the Manager service"]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"deploy-services",children:"Deploy services"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Script"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/000-manager-service.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/001-helper-services.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/100-ceph-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/200-infrastructure-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/210-infrastructure-services-extended.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/300-openstack-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/310-openstack-services-extended.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/320-openstack-services-baremetal.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/330-openstack-services-additional.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/deploy/400-monitoring-services.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"upgrade-services",children:"Upgrade services"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Script"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/100-ceph-services.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/200-infrastructure-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/300-openstack-services-basic.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/310-openstack-services-extended.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/320-openstack-services-baremetal.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"/opt/configuration/scripts/upgrade/330-openstack-services-additional.sh"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,n.jsx)(t.h3,{id:"ansible-errors",children:"Ansible errors"}),"\n",(0,n.jsxs)(t.p,{children:["Ansible errors that have something to do with undefined variables (e.g. ",(0,n.jsx)(t.code,{children:"AnsibleUndefined"}),") are most likely due to cached\nfacts that are no longer valid. The facts can be updated by running ",(0,n.jsx)(t.code,{children:"osism apply facts"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"unsupported-locale-setting",children:"Unsupported locale setting"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",children:"$ make prepare\nansible-playbook -i localhost, ansible/check-local-versions.yml\nERROR: Ansible could not initialize the preferred locale: unsupported locale setting\nmake: *** [prepare] Error 1\n"})}),"\n",(0,n.jsxs)(t.p,{children:["To solve the problem you have to modify the ",(0,n.jsx)(t.code,{children:"Makefile"}),". Change the 1st line as follows."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"export LC_ALL=en_US.UTF-8\n"})}),"\n",(0,n.jsxs)(t.p,{children:["To find out the locale used on the system ",(0,n.jsx)(t.code,{children:"printenv"})," can be used."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:'$ printenv | grep -i lang|locale\nLANG="en_US.UTF-8"\nLC_COLLATE="en_US.UTF-8"\nLC_CTYPE="UTF-8"\nLC_MESSAGES="en_US.UTF-8"\nLC_MONETARY="en_US.UTF-8"\nLC_NUMERIC="en_US.UTF-8"\nLC_TIME="en_US.UTF-8"\nLC_ALL=\n'})}),"\n",(0,n.jsx)(t.h2,{id:"appendix",children:"Appendix"}),"\n",(0,n.jsx)(t.h3,{id:"configuration",children:"Configuration"}),"\n",(0,n.jsx)(t.p,{children:"This section describes how to configure and customise the OSISM Testbed."}),"\n",(0,n.jsx)(t.h4,{id:"variables",children:"Variables"}),"\n",(0,n.jsxs)(t.p,{children:["The defaults for the OpenTofu variables are intended for ",(0,n.jsx)(t.a,{href:"https://regio.digital",children:"REGIO.cloud"}),"."]}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Variable"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Default"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"availability_zone"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nova"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"ceph_version"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"quincy"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"cloud_provider"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"regiocloud"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"configuration_version"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"main"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"deploy_monitoring"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"false"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"dns_nameservers"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:'["8.8.8.8", "9.9.9.9"]'})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"enable_config_drive"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"true"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"external_api"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"false"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"flavor_manager"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"SCS-4V-16-50"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"flavor_node"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"SCS-8V-32-50"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"image"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"Ubuntu 22.04"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Only Ubuntu 22.04 is currently supported"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"image_node"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"Ubuntu 22.04"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"Only Ubuntu 22.04 is currently supported"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"keypair"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"testbed"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"manager_version"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"latest"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"network_availability_zone"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nova"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"number_of_nodes"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"3"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"number_of_volumes"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"3"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"openstack_version"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"2023.2"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"prefix"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"testbed"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"public"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"external"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"refstack"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"false"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"volume_availability_zone"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nova"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"volume_size_base"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"30"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"volume_size_storage"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"10"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"volume_type"}),(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"__DEFAULT__"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h4,{id:"overrides",children:"Overrides"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"manager_boot_from_image"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"manager_boot_from_volume"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"neutron_availability_zone_hints_network"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"neutron_availability_zone_hints_router"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"neutron_router_enable_snat"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nodes_boot_from_image"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nodes_boot_from_volume"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"nodes_use_ephemeral_storage"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h4,{id:"customisations",children:"Customisations"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"access_floatingip"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"access_ipv4"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"access_ipv6"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"default"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"external_api"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:(0,n.jsx)(t.code,{children:"neutron_floatingip"})}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"notes",children:"Notes"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"The configuration is intentionally kept quite static. Please create no PRs to make the configuration more flexible/dynamic."}),"\n",(0,n.jsx)(t.li,{children:"The OSISM documentation uses hostnames, examples, addresses etc. from OSISM Testbed."}),"\n",(0,n.jsxs)(t.li,{children:["The third volume (",(0,n.jsx)(t.code,{children:"/dev/sdd"}),") is not enabled for Ceph by default. This is to test the scaling of Ceph."]}),"\n",(0,n.jsx)(t.li,{children:"The manager is used as pull through cache for Docker images and Ubuntu packages. This reduces the amount of traffic consumed."}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"supported-releases",children:"Supported releases"}),"\n",(0,n.jsx)(t.p,{children:"The following stable Ceph and OpenStack releases are supported."}),"\n",(0,n.jsxs)(t.p,{children:["The deployment of Ceph is based on ",(0,n.jsx)(t.a,{href:"https://docs.ceph.com/ceph-ansible/",children:"ceph-ansible"}),"."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Ceph Quincy (",(0,n.jsx)(t.strong,{children:"default"}),")"]}),"\n",(0,n.jsx)(t.li,{children:"Ceph Reef"}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["The deployment of OpenStack is based on ",(0,n.jsx)(t.a,{href:"https://docs.openstack.org/kolla-ansible/latest/",children:"kolla-ansible"}),"."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"OpenStack 2023.1"}),"\n",(0,n.jsxs)(t.li,{children:["OpenStack 2023.2 (",(0,n.jsx)(t.strong,{children:"default"}),")"]}),"\n",(0,n.jsx)(t.li,{children:"OpenStack 2024.1"}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["The deployment of Kubernetes is based on ",(0,n.jsx)(t.a,{href:"https://github.com/techno-tim/k3s-ansible",children:"k3s-ansible"}),"."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Kubernetes v1.29 (",(0,n.jsx)(t.strong,{children:"default"}),")"]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"included-services",children:"Included services"}),"\n",(0,n.jsx)(t.p,{children:"The following services can currently be used with the OSISM Testbed without further adjustments."}),"\n",(0,n.jsx)(t.h4,{id:"infrastructure",children:"Infrastructure"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Ceph"}),"\n",(0,n.jsx)(t.li,{children:"Cluster API Management Cluster"}),"\n",(0,n.jsx)(t.li,{children:"Fluentd"}),"\n",(0,n.jsx)(t.li,{children:"Gnocchi"}),"\n",(0,n.jsx)(t.li,{children:"Grafana"}),"\n",(0,n.jsx)(t.li,{children:"Haproxy"}),"\n",(0,n.jsx)(t.li,{children:"Influxdb"}),"\n",(0,n.jsx)(t.li,{children:"Keepalived"}),"\n",(0,n.jsx)(t.li,{children:"Keycloak"}),"\n",(0,n.jsx)(t.li,{children:"Kubernetes"}),"\n",(0,n.jsx)(t.li,{children:"Mariadb"}),"\n",(0,n.jsx)(t.li,{children:"Memcached"}),"\n",(0,n.jsx)(t.li,{children:"Netbox"}),"\n",(0,n.jsx)(t.li,{children:"Netdata"}),"\n",(0,n.jsx)(t.li,{children:"Opensearch"}),"\n",(0,n.jsx)(t.li,{children:"Openvswitch"}),"\n",(0,n.jsx)(t.li,{children:"Patchman"}),"\n",(0,n.jsx)(t.li,{children:"Prometheus exporters"}),"\n",(0,n.jsx)(t.li,{children:"Rabbitmq"}),"\n",(0,n.jsx)(t.li,{children:"Redis"}),"\n"]}),"\n",(0,n.jsx)(t.h4,{id:"openstack",children:"OpenStack"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Barbican"}),"\n",(0,n.jsx)(t.li,{children:"Ceilometer"}),"\n",(0,n.jsx)(t.li,{children:"Cinder"}),"\n",(0,n.jsx)(t.li,{children:"Designate"}),"\n",(0,n.jsx)(t.li,{children:"Glance"}),"\n",(0,n.jsx)(t.li,{children:"Heat"}),"\n",(0,n.jsx)(t.li,{children:"Horizon"}),"\n",(0,n.jsx)(t.li,{children:"Ironic"}),"\n",(0,n.jsx)(t.li,{children:"Keystone"}),"\n",(0,n.jsx)(t.li,{children:"Magnum"}),"\n",(0,n.jsx)(t.li,{children:"Manila"}),"\n",(0,n.jsx)(t.li,{children:"Neutron"}),"\n",(0,n.jsx)(t.li,{children:"Nova (with Libvirt/KVM)"}),"\n",(0,n.jsx)(t.li,{children:"Octavia"}),"\n",(0,n.jsx)(t.li,{children:"Senlin"}),"\n",(0,n.jsx)(t.li,{children:"Skyline"}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"makefile-reference",children:"Makefile reference"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"$ make help\n\nUsage:\n make <target>\n help Display this help.\n clean Destroy infrastructure with OpenTofu.\n wipe-local-install Wipe the software dependencies in `venv`.\n create Create required infrastructure with OpenTofu.\n login Log in on the manager.\n vpn-wireguard Establish a wireguard vpn tunnel.\n vpn-sshuttle Establish a sshuttle vpn tunnel.\n bootstrap Bootstrap everything.\n manager Deploy only the manager service.\n identity Deploy only identity services.\n ceph Deploy only ceph services.\n deploy Deploy everything and then check it.\n prepare Run local preperations.\n deps Install software preconditions to `venv`.\n\n$ make <TAB> <TAB>\n"})}),"\n",(0,n.jsx)(t.h3,{id:"ci-jobs",children:"CI jobs"}),"\n",(0,n.jsxs)(t.p,{children:["You can inspect the ",(0,n.jsx)(t.a,{href:"https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Ftestbed&skip=0",children:"results of the daily zuul jobs"}),"."]}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Name"}),(0,n.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-deploy"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-deploy-ceph"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-deploy-stable"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-update-stable"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-upgrade"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-upgrade-ceph"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{style:{textAlign:"left"},children:"testbed-upgrade-stable"}),(0,n.jsx)(t.td,{style:{textAlign:"left"}})]})]})]})]})}function u(e={}){const{wrapper:t}={...(0,l.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(x,{...e})}):x(e)}},19365:(e,t,s)=>{s.d(t,{A:()=>r});s(96540);var n=s(18215);const l={tabItem:"tabItem_Ymn6"};var i=s(74848);function r(e){let{children:t,hidden:s,className:r}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,n.A)(l.tabItem,r),hidden:s,children:t})}},11470:(e,t,s)=>{s.d(t,{A:()=>v});var n=s(96540),l=s(18215),i=s(23104),r=s(56347),d=s(205),c=s(57485),o=s(31682),a=s(89466);function h(e){return n.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,n.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function x(e){const{values:t,children:s}=e;return(0,n.useMemo)((()=>{const e=t??function(e){return h(e).map((e=>{let{props:{value:t,label:s,attributes:n,default:l}}=e;return{value:t,label:s,attributes:n,default:l}}))}(s);return function(e){const t=(0,o.X)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[t,s])}function u(e){let{value:t,tabValues:s}=e;return s.some((e=>e.value===t))}function j(e){let{queryString:t=!1,groupId:s}=e;const l=(0,r.W6)(),i=function(e){let{queryString:t=!1,groupId:s}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!s)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return s??null}({queryString:t,groupId:s});return[(0,c.aZ)(i),(0,n.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(l.location.search);t.set(i,e),l.replace({...l.location,search:t.toString()})}),[i,l])]}function p(e){const{defaultValue:t,queryString:s=!1,groupId:l}=e,i=x(e),[r,c]=(0,n.useState)((()=>function(e){let{defaultValue:t,tabValues:s}=e;if(0===s.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(t){if(!u({value:t,tabValues:s}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${s.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=s.find((e=>e.default))??s[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:i}))),[o,h]=j({queryString:s,groupId:l}),[p,f]=function(e){let{groupId:t}=e;const s=function(e){return e?`docusaurus.tab.${e}`:null}(t),[l,i]=(0,a.Dv)(s);return[l,(0,n.useCallback)((e=>{s&&i.set(e)}),[s,i])]}({groupId:l}),g=(()=>{const e=o??p;return u({value:e,tabValues:i})?e:null})();(0,d.A)((()=>{g&&c(g)}),[g]);return{selectedValue:r,selectValue:(0,n.useCallback)((e=>{if(!u({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);c(e),h(e),f(e)}),[h,f,i]),tabValues:i}}var f=s(92303);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var y=s(74848);function m(e){let{className:t,block:s,selectedValue:n,selectValue:r,tabValues:d}=e;const c=[],{blockElementScrollPositionUntilNextRender:o}=(0,i.a_)(),a=e=>{const t=e.currentTarget,s=c.indexOf(t),l=d[s].value;l!==n&&(o(t),r(l))},h=e=>{let t=null;switch(e.key){case"Enter":a(e);break;case"ArrowRight":{const s=c.indexOf(e.currentTarget)+1;t=c[s]??c[0];break}case"ArrowLeft":{const s=c.indexOf(e.currentTarget)-1;t=c[s]??c[c.length-1];break}}t?.focus()};return(0,y.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.A)("tabs",{"tabs--block":s},t),children:d.map((e=>{let{value:t,label:s,attributes:i}=e;return(0,y.jsx)("li",{role:"tab",tabIndex:n===t?0:-1,"aria-selected":n===t,ref:e=>c.push(e),onKeyDown:h,onClick:a,...i,className:(0,l.A)("tabs__item",g.tabItem,i?.className,{"tabs__item--active":n===t}),children:s??t},t)}))})}function b(e){let{lazy:t,children:s,selectedValue:l}=e;const i=(Array.isArray(s)?s:[s]).filter(Boolean);if(t){const e=i.find((e=>e.props.value===l));return e?(0,n.cloneElement)(e,{className:"margin-top--md"}):null}return(0,y.jsx)("div",{className:"margin-top--md",children:i.map(((e,t)=>(0,n.cloneElement)(e,{key:t,hidden:e.props.value!==l})))})}function A(e){const t=p(e);return(0,y.jsxs)("div",{className:(0,l.A)("tabs-container",g.tabList),children:[(0,y.jsx)(m,{...e,...t}),(0,y.jsx)(b,{...e,...t})]})}function v(e){const t=(0,f.A)();return(0,y.jsx)(A,{...e,children:h(e.children)},String(t))}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>d});var n=s(96540);const l={},i=n.createContext(l);function r(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:r(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/35fbae7a.f798cb6d.js b/assets/js/35fbae7a.f798cb6d.js new file mode 100644 index 0000000000..cb7a312f90 --- /dev/null +++ b/assets/js/35fbae7a.f798cb6d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1617],{82547:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=s(74848),n=s(28453);const i={title:"Getting Started Gaia-X Demonstrator @ plusserver",version:new Date("2022-12-22T00:00:00.000Z"),author:"Ralf Heiringhoff, Mathias Fechner"},o=void 0,c={id:"cloud-resources/plusserver-gx-scs",title:"Getting Started Gaia-X Demonstrator @ plusserver",description:"Getting Started for the Gaia-X Demonstrator @ plusserver",source:"@site/community/cloud-resources/plusserver-gx-scs.md",sourceDirName:"cloud-resources",slug:"/cloud-resources/plusserver-gx-scs",permalink:"/community/cloud-resources/plusserver-gx-scs",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Getting Started Gaia-X Demonstrator @ plusserver",version:"2022-12-22T00:00:00.000Z",author:"Ralf Heiringhoff, Mathias Fechner"},sidebar:"community",previous:{title:"Getting Started with OpenStack",permalink:"/community/cloud-resources/getting-started-openstack"},next:{title:"Getting Started with Wavestack",permalink:"/community/cloud-resources/wavestack"}},a={},l=[{value:"Getting Started for the Gaia-X Demonstrator @ plusserver",id:"getting-started-for-the-gaia-x-demonstrator--plusserver",level:2},{value:"URLs for access",id:"urls-for-access",level:2},{value:"Authentication (UI)",id:"authentication-ui",level:2},{value:"Getting Started with OpenStack",id:"getting-started-with-openstack",level:2}];function u(e){const t={a:"a",code:"code",h2:"h2",li:"li",p:"p",ul:"ul",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h2,{id:"getting-started-for-the-gaia-x-demonstrator--plusserver",children:"Getting Started for the Gaia-X Demonstrator @ plusserver"}),"\n",(0,r.jsx)(t.h2,{id:"urls-for-access",children:"URLs for access"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["UI (Horizon): ",(0,r.jsx)(t.a,{href:"https://ui.gx-scs.sovereignit.cloud/",children:"https://ui.gx-scs.sovereignit.cloud/"})]}),"\n",(0,r.jsxs)(t.li,{children:["API auth url (Keystone): ",(0,r.jsx)(t.a,{href:"https://api.gx-scs.sovereignit.cloud:5000",children:"https://api.gx-scs.sovereignit.cloud:5000"})]}),"\n",(0,r.jsxs)(t.li,{children:["Object Storage endpoint (S3/SWIFT): ",(0,r.jsx)(t.a,{href:"https://api.gx-scs.sovereignit.cloud:8080",children:"https://api.gx-scs.sovereignit.cloud:8080"})]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"authentication-ui",children:"Authentication (UI)"}),"\n",(0,r.jsx)(t.p,{children:"For your login you will need:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Username (",(0,r.jsx)(t.code,{children:"u500924-<$github-handle>"}),")"]}),"\n",(0,r.jsx)(t.li,{children:"Password"}),"\n",(0,r.jsxs)(t.li,{children:["Domain (",(0,r.jsx)(t.code,{children:"d500924"}),")"]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"getting-started-with-openstack",children:"Getting Started with OpenStack"}),"\n",(0,r.jsxs)(t.p,{children:["See ",(0,r.jsx)(t.a,{href:"/community/cloud-resources/getting-started-openstack",children:"Getting Started with OpenStack"})]})]})}function d(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>c});var r=s(96540);const n={},i=r.createContext(n);function o(e){const t=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/36c47bdd.ae03502f.js b/assets/js/36c47bdd.ae03502f.js new file mode 100644 index 0000000000..d4ec3410de --- /dev/null +++ b/assets/js/36c47bdd.ae03502f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9766],{83554:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var o=n(74848),a=n(28453);const r={},i="Team Ops",s={id:"collaboration/team-ops",title:"Team Ops",description:"We build tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.",source:"@site/community/collaboration/team-ops.md",sourceDirName:"collaboration",slug:"/collaboration/team-ops",permalink:"/community/collaboration/team-ops",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Team Container",permalink:"/community/collaboration/team-container"},next:{title:"SIG Central API",permalink:"/community/collaboration/sig-central-api"}},c={},l=[];function u(t){const e={h1:"h1",p:"p",...(0,a.R)(),...t.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(e.h1,{id:"team-ops",children:"Team Ops"}),"\n",(0,o.jsx)(e.p,{children:"We build tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud."})]})}function m(t={}){const{wrapper:e}={...(0,a.R)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>i,x:()=>s});var o=n(96540);const a={},r=o.createContext(a);function i(t){const e=o.useContext(r);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(a):t.components||a:i(t.components),o.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/36f749d2.74efae0f.js b/assets/js/36f749d2.74efae0f.js new file mode 100644 index 0000000000..ee4f5d4f3a --- /dev/null +++ b/assets/js/36f749d2.74efae0f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4602],{99819:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>p,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var s=n(74848),o=n(28453);const r={},i="Overview",c={id:"operating-scs/audits/index",title:"Overview",description:"TODO",source:"@site/docs/04-operating-scs/04-audits/index.md",sourceDirName:"04-operating-scs/04-audits",slug:"/operating-scs/audits/",permalink:"/docs/operating-scs/audits/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/04-audits/index.md",tags:[],version:"current",frontMatter:{}},a={},d=[];function u(e){const t={h1:"h1",p:"p",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"overview",children:"Overview"}),"\n",(0,s.jsx)(t.p,{children:"TODO"})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var s=n(96540);const o={},r=s.createContext(o);function i(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3771.46254ee5.js b/assets/js/3771.46254ee5.js new file mode 100644 index 0000000000..0992050349 --- /dev/null +++ b/assets/js/3771.46254ee5.js @@ -0,0 +1,2 @@ +/*! For license information please see 3771.46254ee5.js.LICENSE.txt */ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3771],{87799:function(e,t,n){var r;r=function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=7)}([function(t,n){t.exports=e},function(e,t,n){"use strict";var r=n(0).FDLayoutConstants;function i(){}for(var a in r)i[a]=r[a];i.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,i.DEFAULT_RADIAL_SEPARATION=r.DEFAULT_EDGE_LENGTH,i.DEFAULT_COMPONENT_SEPERATION=60,i.TILE=!0,i.TILING_PADDING_VERTICAL=10,i.TILING_PADDING_HORIZONTAL=10,i.TREE_REDUCTION_ON_INCREMENTAL=!1,e.exports=i},function(e,t,n){"use strict";var r=n(0).FDLayoutEdge;function i(e,t,n){r.call(this,e,t,n)}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];e.exports=i},function(e,t,n){"use strict";var r=n(0).LGraph;function i(e,t,n){r.call(this,e,t,n)}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];e.exports=i},function(e,t,n){"use strict";var r=n(0).LGraphManager;function i(e){r.call(this,e)}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];e.exports=i},function(e,t,n){"use strict";var r=n(0).FDLayoutNode,i=n(0).IMath;function a(e,t,n,i){r.call(this,e,t,n,i)}for(var o in a.prototype=Object.create(r.prototype),r)a[o]=r[o];a.prototype.move=function(){var e=this.graphManager.getLayout();this.displacementX=e.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY=e.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren,Math.abs(this.displacementX)>e.coolingFactor*e.maxNodeDisplacement&&(this.displacementX=e.coolingFactor*e.maxNodeDisplacement*i.sign(this.displacementX)),Math.abs(this.displacementY)>e.coolingFactor*e.maxNodeDisplacement&&(this.displacementY=e.coolingFactor*e.maxNodeDisplacement*i.sign(this.displacementY)),null==this.child||0==this.child.getNodes().length?this.moveBy(this.displacementX,this.displacementY):this.propogateDisplacementToChildren(this.displacementX,this.displacementY),e.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},a.prototype.propogateDisplacementToChildren=function(e,t){for(var n,r=this.getChild().getNodes(),i=0;i<r.length;i++)null==(n=r[i]).getChild()?(n.moveBy(e,t),n.displacementX+=e,n.displacementY+=t):n.propogateDisplacementToChildren(e,t)},a.prototype.setPred1=function(e){this.pred1=e},a.prototype.getPred1=function(){return pred1},a.prototype.getPred2=function(){return pred2},a.prototype.setNext=function(e){this.next=e},a.prototype.getNext=function(){return next},a.prototype.setProcessed=function(e){this.processed=e},a.prototype.isProcessed=function(){return processed},e.exports=a},function(e,t,n){"use strict";var r=n(0).FDLayout,i=n(4),a=n(3),o=n(5),s=n(2),l=n(1),u=n(0).FDLayoutConstants,c=n(0).LayoutConstants,h=n(0).Point,d=n(0).PointD,p=n(0).Layout,g=n(0).Integer,f=n(0).IGeometry,v=n(0).LGraph,y=n(0).Transform;function m(){r.call(this),this.toBeTiled={}}for(var b in m.prototype=Object.create(r.prototype),r)m[b]=r[b];m.prototype.newGraphManager=function(){var e=new i(this);return this.graphManager=e,e},m.prototype.newGraph=function(e){return new a(null,this.graphManager,e)},m.prototype.newNode=function(e){return new o(this.graphManager,e)},m.prototype.newEdge=function(e){return new s(null,null,e)},m.prototype.initParameters=function(){r.prototype.initParameters.call(this,arguments),this.isSubLayout||(l.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=l.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=l.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.springConstant=u.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=u.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=u.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=u.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=u.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=u.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1,this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/u.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=u.CONVERGENCE_CHECK_PERIOD/this.maxIterations,this.coolingAdjuster=1)},m.prototype.layout=function(){return c.DEFAULT_CREATE_BENDS_AS_NEEDED&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},m.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental)l.TREE_REDUCTION_ON_INCREMENTAL&&(this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation(),t=new Set(this.getAllNodes()),n=this.nodesWithGravity.filter((function(e){return t.has(e)})),this.graphManager.setAllNodesToApplyGravitation(n));else{var e=this.getFlatForest();if(e.length>0)this.positionNodesRadially(e);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var t=new Set(this.getAllNodes()),n=this.nodesWithGravity.filter((function(e){return t.has(e)}));this.graphManager.setAllNodesToApplyGravitation(n),this.positionNodesRandomly()}}return this.initSpringEmbedder(),this.runSpringEmbedder(),!0},m.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}if(this.totalIterations%u.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged()){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}this.coolingCycle++,0==this.layoutQuality?this.coolingAdjuster=this.coolingCycle:1==this.layoutQuality&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var e=new Set(this.getAllNodes()),t=this.nodesWithGravity.filter((function(t){return e.has(t)}));this.graphManager.setAllNodesToApplyGravitation(t),this.graphManager.updateBounds(),this.updateGrid(),this.coolingFactor=u.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),this.coolingFactor=u.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var n=!this.isTreeGrowing&&!this.isGrowthFinished,r=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(n,r),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},m.prototype.getPositionsData=function(){for(var e=this.graphManager.getAllNodes(),t={},n=0;n<e.length;n++){var r=e[n].rect,i=e[n].id;t[i]={id:i,x:r.getCenterX(),y:r.getCenterY(),w:r.width,h:r.height}}return t},m.prototype.runSpringEmbedder=function(){this.initialAnimationPeriod=25,this.animationPeriod=this.initialAnimationPeriod;var e=!1;if("during"===u.ANIMATE)this.emit("layoutstarted");else{for(;!e;)e=this.tick();this.graphManager.updateBounds()}},m.prototype.calculateNodesToApplyGravitationTo=function(){var e,t,n=[],r=this.graphManager.getGraphs(),i=r.length;for(t=0;t<i;t++)(e=r[t]).updateConnected(),e.isConnected||(n=n.concat(e.getNodes()));return n},m.prototype.createBendpoints=function(){var e=[];e=e.concat(this.graphManager.getAllEdges());var t,n=new Set;for(t=0;t<e.length;t++){var r=e[t];if(!n.has(r)){var i=r.getSource(),a=r.getTarget();if(i==a)r.getBendpoints().push(new d),r.getBendpoints().push(new d),this.createDummyNodesForBendpoints(r),n.add(r);else{var o=[];if(o=(o=o.concat(i.getEdgeListToNode(a))).concat(a.getEdgeListToNode(i)),!n.has(o[0])){var s;if(o.length>1)for(s=0;s<o.length;s++){var l=o[s];l.getBendpoints().push(new d),this.createDummyNodesForBendpoints(l)}o.forEach((function(e){n.add(e)}))}}}if(n.size==e.length)break}},m.prototype.positionNodesRadially=function(e){for(var t=new h(0,0),n=Math.ceil(Math.sqrt(e.length)),r=0,i=0,a=0,o=new d(0,0),s=0;s<e.length;s++){s%n==0&&(a=0,i=r,0!=s&&(i+=l.DEFAULT_COMPONENT_SEPERATION),r=0);var u=e[s],g=p.findCenterOfTree(u);t.x=a,t.y=i,(o=m.radialLayout(u,g,t)).y>r&&(r=Math.floor(o.y)),a=Math.floor(o.x+l.DEFAULT_COMPONENT_SEPERATION)}this.transform(new d(c.WORLD_CENTER_X-o.x/2,c.WORLD_CENTER_Y-o.y/2))},m.radialLayout=function(e,t,n){var r=Math.max(this.maxDiagonalInTree(e),l.DEFAULT_RADIAL_SEPARATION);m.branchRadialLayout(t,null,0,359,0,r);var i=v.calculateBounds(e),a=new y;a.setDeviceOrgX(i.getMinX()),a.setDeviceOrgY(i.getMinY()),a.setWorldOrgX(n.x),a.setWorldOrgY(n.y);for(var o=0;o<e.length;o++)e[o].transform(a);var s=new d(i.getMaxX(),i.getMaxY());return a.inverseTransformPoint(s)},m.branchRadialLayout=function(e,t,n,r,i,a){var o=(r-n+1)/2;o<0&&(o+=180);var s=(o+n)%360*f.TWO_PI/360,l=(Math.cos(s),i*Math.cos(s)),u=i*Math.sin(s);e.setCenter(l,u);var c=[],h=(c=c.concat(e.getEdges())).length;null!=t&&h--;for(var d,p=0,g=c.length,v=e.getEdgesBetween(t);v.length>1;){var y=v[0];v.splice(0,1);var b=c.indexOf(y);b>=0&&c.splice(b,1),g--,h--}d=null!=t?(c.indexOf(v[0])+1)%g:0;for(var x=Math.abs(r-n)/h,w=d;p!=h;w=++w%g){var E=c[w].getOtherEnd(e);if(E!=t){var _=(n+p*x)%360,T=(_+x)%360;m.branchRadialLayout(E,e,_,T,i+a,a),p++}}},m.maxDiagonalInTree=function(e){for(var t=g.MIN_VALUE,n=0;n<e.length;n++){var r=e[n].getDiagonal();r>t&&(t=r)}return t},m.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},m.prototype.groupZeroDegreeMembers=function(){var e=this,t={};this.memberGroups={},this.idToDummyNode={};for(var n=[],r=this.graphManager.getAllNodes(),i=0;i<r.length;i++){var a=(s=r[i]).getParent();0!==this.getNodeDegreeWithChildren(s)||null!=a.id&&this.getToBeTiled(a)||n.push(s)}for(i=0;i<n.length;i++){var s,l=(s=n[i]).getParent().id;void 0===t[l]&&(t[l]=[]),t[l]=t[l].concat(s)}Object.keys(t).forEach((function(n){if(t[n].length>1){var r="DummyCompound_"+n;e.memberGroups[r]=t[n];var i=t[n][0].getParent(),a=new o(e.graphManager);a.id=r,a.paddingLeft=i.paddingLeft||0,a.paddingRight=i.paddingRight||0,a.paddingBottom=i.paddingBottom||0,a.paddingTop=i.paddingTop||0,e.idToDummyNode[r]=a;var s=e.getGraphManager().add(e.newGraph(),a),l=i.getChild();l.add(a);for(var u=0;u<t[n].length;u++){var c=t[n][u];l.remove(c),s.add(c)}}}))},m.prototype.clearCompounds=function(){var e={},t={};this.performDFSOnCompounds();for(var n=0;n<this.compoundOrder.length;n++)t[this.compoundOrder[n].id]=this.compoundOrder[n],e[this.compoundOrder[n].id]=[].concat(this.compoundOrder[n].getChild().getNodes()),this.graphManager.remove(this.compoundOrder[n].getChild()),this.compoundOrder[n].child=null;this.graphManager.resetAllNodes(),this.tileCompoundMembers(e,t)},m.prototype.clearZeroDegreeMembers=function(){var e=this,t=this.tiledZeroDegreePack=[];Object.keys(this.memberGroups).forEach((function(n){var r=e.idToDummyNode[n];t[n]=e.tileNodes(e.memberGroups[n],r.paddingLeft+r.paddingRight),r.rect.width=t[n].width,r.rect.height=t[n].height}))},m.prototype.repopulateCompounds=function(){for(var e=this.compoundOrder.length-1;e>=0;e--){var t=this.compoundOrder[e],n=t.id,r=t.paddingLeft,i=t.paddingTop;this.adjustLocations(this.tiledMemberPack[n],t.rect.x,t.rect.y,r,i)}},m.prototype.repopulateZeroDegreeMembers=function(){var e=this,t=this.tiledZeroDegreePack;Object.keys(t).forEach((function(n){var r=e.idToDummyNode[n],i=r.paddingLeft,a=r.paddingTop;e.adjustLocations(t[n],r.rect.x,r.rect.y,i,a)}))},m.prototype.getToBeTiled=function(e){var t=e.id;if(null!=this.toBeTiled[t])return this.toBeTiled[t];var n=e.getChild();if(null==n)return this.toBeTiled[t]=!1,!1;for(var r=n.getNodes(),i=0;i<r.length;i++){var a=r[i];if(this.getNodeDegree(a)>0)return this.toBeTiled[t]=!1,!1;if(null!=a.getChild()){if(!this.getToBeTiled(a))return this.toBeTiled[t]=!1,!1}else this.toBeTiled[a.id]=!1}return this.toBeTiled[t]=!0,!0},m.prototype.getNodeDegree=function(e){e.id;for(var t=e.getEdges(),n=0,r=0;r<t.length;r++){var i=t[r];i.getSource().id!==i.getTarget().id&&(n+=1)}return n},m.prototype.getNodeDegreeWithChildren=function(e){var t=this.getNodeDegree(e);if(null==e.getChild())return t;for(var n=e.getChild().getNodes(),r=0;r<n.length;r++){var i=n[r];t+=this.getNodeDegreeWithChildren(i)}return t},m.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},m.prototype.fillCompexOrderByDFS=function(e){for(var t=0;t<e.length;t++){var n=e[t];null!=n.getChild()&&this.fillCompexOrderByDFS(n.getChild().getNodes()),this.getToBeTiled(n)&&this.compoundOrder.push(n)}},m.prototype.adjustLocations=function(e,t,n,r,i){n+=i;for(var a=t+=r,o=0;o<e.rows.length;o++){var s=e.rows[o];t=a;for(var l=0,u=0;u<s.length;u++){var c=s[u];c.rect.x=t,c.rect.y=n,t+=c.rect.width+e.horizontalPadding,c.rect.height>l&&(l=c.rect.height)}n+=l+e.verticalPadding}},m.prototype.tileCompoundMembers=function(e,t){var n=this;this.tiledMemberPack=[],Object.keys(e).forEach((function(r){var i=t[r];n.tiledMemberPack[r]=n.tileNodes(e[r],i.paddingLeft+i.paddingRight),i.rect.width=n.tiledMemberPack[r].width,i.rect.height=n.tiledMemberPack[r].height}))},m.prototype.tileNodes=function(e,t){var n={rows:[],rowWidth:[],rowHeight:[],width:0,height:t,verticalPadding:l.TILING_PADDING_VERTICAL,horizontalPadding:l.TILING_PADDING_HORIZONTAL};e.sort((function(e,t){return e.rect.width*e.rect.height>t.rect.width*t.rect.height?-1:e.rect.width*e.rect.height<t.rect.width*t.rect.height?1:0}));for(var r=0;r<e.length;r++){var i=e[r];0==n.rows.length?this.insertNodeToRow(n,i,0,t):this.canAddHorizontal(n,i.rect.width,i.rect.height)?this.insertNodeToRow(n,i,this.getShortestRowIndex(n),t):this.insertNodeToRow(n,i,n.rows.length,t),this.shiftToLastRow(n)}return n},m.prototype.insertNodeToRow=function(e,t,n,r){var i=r;n==e.rows.length&&(e.rows.push([]),e.rowWidth.push(i),e.rowHeight.push(0));var a=e.rowWidth[n]+t.rect.width;e.rows[n].length>0&&(a+=e.horizontalPadding),e.rowWidth[n]=a,e.width<a&&(e.width=a);var o=t.rect.height;n>0&&(o+=e.verticalPadding);var s=0;o>e.rowHeight[n]&&(s=e.rowHeight[n],e.rowHeight[n]=o,s=e.rowHeight[n]-s),e.height+=s,e.rows[n].push(t)},m.prototype.getShortestRowIndex=function(e){for(var t=-1,n=Number.MAX_VALUE,r=0;r<e.rows.length;r++)e.rowWidth[r]<n&&(t=r,n=e.rowWidth[r]);return t},m.prototype.getLongestRowIndex=function(e){for(var t=-1,n=Number.MIN_VALUE,r=0;r<e.rows.length;r++)e.rowWidth[r]>n&&(t=r,n=e.rowWidth[r]);return t},m.prototype.canAddHorizontal=function(e,t,n){var r=this.getShortestRowIndex(e);if(r<0)return!0;var i=e.rowWidth[r];if(i+e.horizontalPadding+t<=e.width)return!0;var a,o,s=0;return e.rowHeight[r]<n&&r>0&&(s=n+e.verticalPadding-e.rowHeight[r]),a=e.width-i>=t+e.horizontalPadding?(e.height+s)/(i+t+e.horizontalPadding):(e.height+s)/e.width,s=n+e.verticalPadding,(o=e.width<t?(e.height+s)/t:(e.height+s)/e.width)<1&&(o=1/o),a<1&&(a=1/a),a<o},m.prototype.shiftToLastRow=function(e){var t=this.getLongestRowIndex(e),n=e.rowWidth.length-1,r=e.rows[t],i=r[r.length-1],a=i.width+e.horizontalPadding;if(e.width-e.rowWidth[n]>a&&t!=n){r.splice(-1,1),e.rows[n].push(i),e.rowWidth[t]=e.rowWidth[t]-a,e.rowWidth[n]=e.rowWidth[n]+a,e.width=e.rowWidth[instance.getLongestRowIndex(e)];for(var o=Number.MIN_VALUE,s=0;s<r.length;s++)r[s].height>o&&(o=r[s].height);t>0&&(o+=e.verticalPadding);var l=e.rowHeight[t]+e.rowHeight[n];e.rowHeight[t]=o,e.rowHeight[n]<i.height+e.verticalPadding&&(e.rowHeight[n]=i.height+e.verticalPadding);var u=e.rowHeight[t]+e.rowHeight[n];e.height+=u-l,this.shiftToLastRow(e)}},m.prototype.tilingPreLayout=function(){l.TILE&&(this.groupZeroDegreeMembers(),this.clearCompounds(),this.clearZeroDegreeMembers())},m.prototype.tilingPostLayout=function(){l.TILE&&(this.repopulateZeroDegreeMembers(),this.repopulateCompounds())},m.prototype.reduceTrees=function(){for(var e,t=[],n=!0;n;){var r=this.graphManager.getAllNodes(),i=[];n=!1;for(var a=0;a<r.length;a++)1!=(e=r[a]).getEdges().length||e.getEdges()[0].isInterGraph||null!=e.getChild()||(i.push([e,e.getEdges()[0],e.getOwner()]),n=!0);if(1==n){for(var o=[],s=0;s<i.length;s++)1==i[s][0].getEdges().length&&(o.push(i[s]),i[s][0].getOwner().remove(i[s][0]));t.push(o),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()}}this.prunedNodesAll=t},m.prototype.growTree=function(e){for(var t,n=e[e.length-1],r=0;r<n.length;r++)t=n[r],this.findPlaceforPrunedNode(t),t[2].add(t[0]),t[2].add(t[1],t[1].source,t[1].target);e.splice(e.length-1,1),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()},m.prototype.findPlaceforPrunedNode=function(e){var t,n,r=e[0],i=(n=r==e[1].source?e[1].target:e[1].source).startX,a=n.finishX,o=n.startY,s=n.finishY,l=[0,0,0,0];if(o>0)for(var c=i;c<=a;c++)l[0]+=this.grid[c][o-1].length+this.grid[c][o].length-1;if(a<this.grid.length-1)for(c=o;c<=s;c++)l[1]+=this.grid[a+1][c].length+this.grid[a][c].length-1;if(s<this.grid[0].length-1)for(c=i;c<=a;c++)l[2]+=this.grid[c][s+1].length+this.grid[c][s].length-1;if(i>0)for(c=o;c<=s;c++)l[3]+=this.grid[i-1][c].length+this.grid[i][c].length-1;for(var h,d,p=g.MAX_VALUE,f=0;f<l.length;f++)l[f]<p?(p=l[f],h=1,d=f):l[f]==p&&h++;if(3==h&&0==p)0==l[0]&&0==l[1]&&0==l[2]?t=1:0==l[0]&&0==l[1]&&0==l[3]?t=0:0==l[0]&&0==l[2]&&0==l[3]?t=3:0==l[1]&&0==l[2]&&0==l[3]&&(t=2);else if(2==h&&0==p){var v=Math.floor(2*Math.random());t=0==l[0]&&0==l[1]?0==v?0:1:0==l[0]&&0==l[2]?0==v?0:2:0==l[0]&&0==l[3]?0==v?0:3:0==l[1]&&0==l[2]?0==v?1:2:0==l[1]&&0==l[3]?0==v?1:3:0==v?2:3}else t=4==h&&0==p?v=Math.floor(4*Math.random()):d;0==t?r.setCenter(n.getCenterX(),n.getCenterY()-n.getHeight()/2-u.DEFAULT_EDGE_LENGTH-r.getHeight()/2):1==t?r.setCenter(n.getCenterX()+n.getWidth()/2+u.DEFAULT_EDGE_LENGTH+r.getWidth()/2,n.getCenterY()):2==t?r.setCenter(n.getCenterX(),n.getCenterY()+n.getHeight()/2+u.DEFAULT_EDGE_LENGTH+r.getHeight()/2):r.setCenter(n.getCenterX()-n.getWidth()/2-u.DEFAULT_EDGE_LENGTH-r.getWidth()/2,n.getCenterY())},e.exports=m},function(e,t,n){"use strict";var r={};r.layoutBase=n(0),r.CoSEConstants=n(1),r.CoSEEdge=n(2),r.CoSEGraph=n(3),r.CoSEGraphManager=n(4),r.CoSELayout=n(6),r.CoSENode=n(5),e.exports=r}])},e.exports=r(n(23143))},43457:function(e,t,n){var r;r=function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(t,n){t.exports=e},function(e,t,n){"use strict";var r=n(0).layoutBase.LayoutConstants,i=n(0).layoutBase.FDLayoutConstants,a=n(0).CoSEConstants,o=n(0).CoSELayout,s=n(0).CoSENode,l=n(0).layoutBase.PointD,u=n(0).layoutBase.DimensionD,c={ready:function(){},stop:function(){},quality:"default",nodeDimensionsIncludeLabels:!1,refresh:30,fit:!0,padding:10,randomize:!0,nodeRepulsion:4500,idealEdgeLength:50,edgeElasticity:.45,nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,animate:"end",animationDuration:500,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.5};function h(e){this.options=function(e,t){var n={};for(var r in e)n[r]=e[r];for(var r in t)n[r]=t[r];return n}(c,e),d(this.options)}var d=function(e){null!=e.nodeRepulsion&&(a.DEFAULT_REPULSION_STRENGTH=i.DEFAULT_REPULSION_STRENGTH=e.nodeRepulsion),null!=e.idealEdgeLength&&(a.DEFAULT_EDGE_LENGTH=i.DEFAULT_EDGE_LENGTH=e.idealEdgeLength),null!=e.edgeElasticity&&(a.DEFAULT_SPRING_STRENGTH=i.DEFAULT_SPRING_STRENGTH=e.edgeElasticity),null!=e.nestingFactor&&(a.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=e.nestingFactor),null!=e.gravity&&(a.DEFAULT_GRAVITY_STRENGTH=i.DEFAULT_GRAVITY_STRENGTH=e.gravity),null!=e.numIter&&(a.MAX_ITERATIONS=i.MAX_ITERATIONS=e.numIter),null!=e.gravityRange&&(a.DEFAULT_GRAVITY_RANGE_FACTOR=i.DEFAULT_GRAVITY_RANGE_FACTOR=e.gravityRange),null!=e.gravityCompound&&(a.DEFAULT_COMPOUND_GRAVITY_STRENGTH=i.DEFAULT_COMPOUND_GRAVITY_STRENGTH=e.gravityCompound),null!=e.gravityRangeCompound&&(a.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=e.gravityRangeCompound),null!=e.initialEnergyOnIncremental&&(a.DEFAULT_COOLING_FACTOR_INCREMENTAL=i.DEFAULT_COOLING_FACTOR_INCREMENTAL=e.initialEnergyOnIncremental),"draft"==e.quality?r.QUALITY=0:"proof"==e.quality?r.QUALITY=2:r.QUALITY=1,a.NODE_DIMENSIONS_INCLUDE_LABELS=i.NODE_DIMENSIONS_INCLUDE_LABELS=r.NODE_DIMENSIONS_INCLUDE_LABELS=e.nodeDimensionsIncludeLabels,a.DEFAULT_INCREMENTAL=i.DEFAULT_INCREMENTAL=r.DEFAULT_INCREMENTAL=!e.randomize,a.ANIMATE=i.ANIMATE=r.ANIMATE=e.animate,a.TILE=e.tile,a.TILING_PADDING_VERTICAL="function"==typeof e.tilingPaddingVertical?e.tilingPaddingVertical.call():e.tilingPaddingVertical,a.TILING_PADDING_HORIZONTAL="function"==typeof e.tilingPaddingHorizontal?e.tilingPaddingHorizontal.call():e.tilingPaddingHorizontal};h.prototype.run=function(){var e,t,n=this.options,r=(this.idToLNode={},this.layout=new o),i=this;i.stopped=!1,this.cy=this.options.cy,this.cy.trigger({type:"layoutstart",layout:this});var a=r.newGraphManager();this.gm=a;var s=this.options.eles.nodes(),l=this.options.eles.edges();this.root=a.addRoot(),this.processChildrenList(this.root,this.getTopMostNodes(s),r);for(var u=0;u<l.length;u++){var c=l[u],h=this.idToLNode[c.data("source")],d=this.idToLNode[c.data("target")];h!==d&&0==h.getEdgesBetween(d).length&&(a.add(r.newEdge(),h,d).id=c.id())}var p=function(e,t){"number"==typeof e&&(e=t);var n=e.data("id"),r=i.idToLNode[n];return{x:r.getRect().getCenterX(),y:r.getRect().getCenterY()}},g=function a(){for(var o,s=function(){n.fit&&n.cy.fit(n.eles,n.padding),e||(e=!0,i.cy.one("layoutready",n.ready),i.cy.trigger({type:"layoutready",layout:i}))},l=i.options.refresh,u=0;u<l&&!o;u++)o=i.stopped||i.layout.tick();if(o)return r.checkLayoutSuccess()&&!r.isSubLayout&&r.doPostLayout(),r.tilingPostLayout&&r.tilingPostLayout(),r.isLayoutFinished=!0,i.options.eles.nodes().positions(p),s(),i.cy.one("layoutstop",i.options.stop),i.cy.trigger({type:"layoutstop",layout:i}),t&&cancelAnimationFrame(t),void(e=!1);var c=i.layout.getPositionsData();n.eles.nodes().positions((function(e,t){if("number"==typeof e&&(e=t),!e.isParent()){for(var n=e.id(),r=c[n],i=e;null==r&&(r=c[i.data("parent")]||c["DummyCompound_"+i.data("parent")],c[n]=r,null!=(i=i.parent()[0])););return null!=r?{x:r.x,y:r.y}:{x:e.position("x"),y:e.position("y")}}})),s(),t=requestAnimationFrame(a)};return r.addListener("layoutstarted",(function(){"during"===i.options.animate&&(t=requestAnimationFrame(g))})),r.runLayout(),"during"!==this.options.animate&&(i.options.eles.nodes().not(":parent").layoutPositions(i,i.options,p),e=!1),this},h.prototype.getTopMostNodes=function(e){for(var t={},n=0;n<e.length;n++)t[e[n].id()]=!0;var r=e.filter((function(e,n){"number"==typeof e&&(e=n);for(var r=e.parent()[0];null!=r;){if(t[r.id()])return!1;r=r.parent()[0]}return!0}));return r},h.prototype.processChildrenList=function(e,t,n){for(var r=t.length,i=0;i<r;i++){var a,o,c=t[i],h=c.children(),d=c.layoutDimensions({nodeDimensionsIncludeLabels:this.options.nodeDimensionsIncludeLabels});if((a=null!=c.outerWidth()&&null!=c.outerHeight()?e.add(new s(n.graphManager,new l(c.position("x")-d.w/2,c.position("y")-d.h/2),new u(parseFloat(d.w),parseFloat(d.h)))):e.add(new s(this.graphManager))).id=c.data("id"),a.paddingLeft=parseInt(c.css("padding")),a.paddingTop=parseInt(c.css("padding")),a.paddingRight=parseInt(c.css("padding")),a.paddingBottom=parseInt(c.css("padding")),this.options.nodeDimensionsIncludeLabels&&c.isParent()){var p=c.boundingBox({includeLabels:!0,includeNodes:!1}).w,g=c.boundingBox({includeLabels:!0,includeNodes:!1}).h,f=c.css("text-halign");a.labelWidth=p,a.labelHeight=g,a.labelPos=f}this.idToLNode[c.data("id")]=a,isNaN(a.rect.x)&&(a.rect.x=0),isNaN(a.rect.y)&&(a.rect.y=0),null!=h&&h.length>0&&(o=n.getGraphManager().add(n.newGraph(),a),this.processChildrenList(o,h,n))}},h.prototype.stop=function(){return this.stopped=!0,this};var p=function(e){e("layout","cose-bilkent",h)};"undefined"!=typeof cytoscape&&p(cytoscape),e.exports=p}])},e.exports=r(n(87799))},44726:(e,t,n)=>{"use strict";var r=n(38221),i=n(65731),a=n(58156),o=n(63560),s=n(42072);function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=l(r),c=l(i),h=l(a),d=l(o),p=l(s);function g(e){return g="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},g(e)}function f(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function v(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function y(e,t,n){return t&&v(e.prototype,t),n&&v(e,n),Object.defineProperty(e,"prototype",{writable:!1}),e}function m(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function b(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var r,i,a=[],o=!0,s=!1;try{for(n=n.call(e);!(o=(r=n.next()).done)&&(a.push(r.value),!t||a.length!==t);o=!0);}catch(l){s=!0,i=l}finally{try{o||null==n.return||n.return()}finally{if(s)throw i}}return a}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return x(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return x(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function x(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var w="undefined"==typeof window?null:window,E=w?w.navigator:null;w&&w.document;var _=g(""),T=g({}),D=g((function(){})),C="undefined"==typeof HTMLElement?"undefined":g(HTMLElement),N=function(e){return e&&e.instanceString&&L(e.instanceString)?e.instanceString():null},A=function(e){return null!=e&&g(e)==_},L=function(e){return null!=e&&g(e)===D},k=function(e){return!O(e)&&(Array.isArray?Array.isArray(e):null!=e&&e instanceof Array)},S=function(e){return null!=e&&g(e)===T&&!k(e)&&e.constructor===Object},I=function(e){return null!=e&&g(e)===g(1)&&!isNaN(e)},M=function(e){return"undefined"===C?void 0:null!=e&&e instanceof HTMLElement},O=function(e){return P(e)||R(e)},P=function(e){return"collection"===N(e)&&e._private.single},R=function(e){return"collection"===N(e)&&!e._private.single},B=function(e){return"core"===N(e)},F=function(e){return"stylesheet"===N(e)},z=function(e){return null==e||!(""!==e&&!e.match(/^\s+$/))},G=function(e){return function(e){return null!=e&&g(e)===T}(e)&&L(e.then)},Y=function(e,t){t||(t=function(){if(1===arguments.length)return arguments[0];if(0===arguments.length)return"undefined";for(var e=[],t=0;t<arguments.length;t++)e.push(arguments[t]);return e.join("$")});var n=function n(){var r,i=arguments,a=t.apply(this,i),o=n.cache;return(r=o[a])||(r=o[a]=e.apply(this,i)),r};return n.cache={},n},X=Y((function(e){return e.replace(/([A-Z])/g,(function(e){return"-"+e.toLowerCase()}))})),V=Y((function(e){return e.replace(/(-\w)/g,(function(e){return e[1].toUpperCase()}))})),U=Y((function(e,t){return e+t[0].toUpperCase()+t.substring(1)}),(function(e,t){return e+"$"+t})),j=function(e){return z(e)?e:e.charAt(0).toUpperCase()+e.substring(1)},q="(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))",H="rgb[a]?\\(("+q+"[%]?)\\s*,\\s*("+q+"[%]?)\\s*,\\s*("+q+"[%]?)(?:\\s*,\\s*("+q+"))?\\)",W="rgb[a]?\\((?:"+q+"[%]?)\\s*,\\s*(?:"+q+"[%]?)\\s*,\\s*(?:"+q+"[%]?)(?:\\s*,\\s*(?:"+q+"))?\\)",$="hsl[a]?\\(("+q+")\\s*,\\s*("+q+"[%])\\s*,\\s*("+q+"[%])(?:\\s*,\\s*("+q+"))?\\)",K="hsl[a]?\\((?:"+q+")\\s*,\\s*(?:"+q+"[%])\\s*,\\s*(?:"+q+"[%])(?:\\s*,\\s*(?:"+q+"))?\\)",Z=function(e,t){return e<t?-1:e>t?1:0},Q=null!=Object.assign?Object.assign.bind(Object):function(e){for(var t=arguments,n=1;n<t.length;n++){var r=t[n];if(null!=r)for(var i=Object.keys(r),a=0;a<i.length;a++){var o=i[a];e[o]=r[o]}}return e},J=function(e){return(k(e)?e:null)||function(e){return ee[e.toLowerCase()]}(e)||function(e){if((4===e.length||7===e.length)&&"#"===e[0]){var t,n,r,i=16;return 4===e.length?(t=parseInt(e[1]+e[1],i),n=parseInt(e[2]+e[2],i),r=parseInt(e[3]+e[3],i)):(t=parseInt(e[1]+e[2],i),n=parseInt(e[3]+e[4],i),r=parseInt(e[5]+e[6],i)),[t,n,r]}}(e)||function(e){var t,n=new RegExp("^"+H+"$").exec(e);if(n){t=[];for(var r=[],i=1;i<=3;i++){var a=n[i];if("%"===a[a.length-1]&&(r[i]=!0),a=parseFloat(a),r[i]&&(a=a/100*255),a<0||a>255)return;t.push(Math.floor(a))}var o=r[1]||r[2]||r[3],s=r[1]&&r[2]&&r[3];if(o&&!s)return;var l=n[4];if(void 0!==l){if((l=parseFloat(l))<0||l>1)return;t.push(l)}}return t}(e)||function(e){var t,n,r,i,a,o,s,l;function u(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var c=new RegExp("^"+$+"$").exec(e);if(c){if((n=parseInt(c[1]))<0?n=(360- -1*n%360)%360:n>360&&(n%=360),n/=360,(r=parseFloat(c[2]))<0||r>100)return;if(r/=100,(i=parseFloat(c[3]))<0||i>100)return;if(i/=100,void 0!==(a=c[4])&&((a=parseFloat(a))<0||a>1))return;if(0===r)o=s=l=Math.round(255*i);else{var h=i<.5?i*(1+r):i+r-i*r,d=2*i-h;o=Math.round(255*u(d,h,n+1/3)),s=Math.round(255*u(d,h,n)),l=Math.round(255*u(d,h,n-1/3))}t=[o,s,l,a]}return t}(e)},ee={transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},te=function(e){for(var t=e.map,n=e.keys,r=n.length,i=0;i<r;i++){var a=n[i];if(S(a))throw Error("Tried to set map with object key");i<n.length-1?(null==t[a]&&(t[a]={}),t=t[a]):t[a]=e.value}},ne=function(e){for(var t=e.map,n=e.keys,r=n.length,i=0;i<r;i++){var a=n[i];if(S(a))throw Error("Tried to get map with object key");if(null==(t=t[a]))return t}return t},re=w?w.performance:null,ie=re&&re.now?function(){return re.now()}:function(){return Date.now()},ae=function(){if(w){if(w.requestAnimationFrame)return function(e){w.requestAnimationFrame(e)};if(w.mozRequestAnimationFrame)return function(e){w.mozRequestAnimationFrame(e)};if(w.webkitRequestAnimationFrame)return function(e){w.webkitRequestAnimationFrame(e)};if(w.msRequestAnimationFrame)return function(e){w.msRequestAnimationFrame(e)}}return function(e){e&&setTimeout((function(){e(ie())}),1e3/60)}}(),oe=function(e){return ae(e)},se=ie,le=9261,ue=5381,ce=function(e){for(var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:le;!(t=e.next()).done;)n=65599*n+t.value|0;return n},he=function(e){return 65599*(arguments.length>1&&void 0!==arguments[1]?arguments[1]:le)+e|0},de=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:ue;return(t<<5)+t+e|0},pe=function(e){return 2097152*e[0]+e[1]},ge=function(e,t){return[he(e[0],t[0]),de(e[1],t[1])]},fe=function(e,t){var n={value:0,done:!1},r=0,i=e.length;return ce({next:function(){return r<i?n.value=e.charCodeAt(r++):n.done=!0,n}},t)},ve=function(){return ye(arguments)},ye=function(e){for(var t,n=0;n<e.length;n++){var r=e[n];t=0===n?fe(r):fe(r,t)}return t},me=!0,be=null!=console.warn,xe=null!=console.trace,we=Number.MAX_SAFE_INTEGER||9007199254740991,Ee=function(){return!0},_e=function(){return!1},Te=function(){return 0},De=function(){},Ce=function(e){throw new Error(e)},Ne=function(e){if(void 0===e)return me;me=!!e},Ae=function(e){Ne()&&(be?console.warn(e):(console.log(e),xe&&console.trace()))},Le=function(e){return null==e?e:k(e)?e.slice():S(e)?function(e){return Q({},e)}(e):e},ke=function(e,t){for(t=e="";e++<36;t+=51*e&52?(15^e?8^Math.random()*(20^e?16:4):4).toString(16):"-");return t},Se={},Ie=function(){return Se},Me=function(e){var t=Object.keys(e);return function(n){for(var r={},i=0;i<t.length;i++){var a=t[i],o=null==n?void 0:n[a];r[a]=void 0===o?e[a]:o}return r}},Oe=function(e,t,n){for(var r=e.length-1;r>=0&&(e[r]!==t||(e.splice(r,1),!n));r--);},Pe=function(e){e.splice(0,e.length)},Re=function(e,t,n){return n&&(t=U(n,t)),e[t]},Be=function(e,t,n,r){n&&(t=U(n,t)),e[t]=r},Fe="undefined"!=typeof Map?Map:function(){function e(){f(this,e),this._obj={}}return y(e,[{key:"set",value:function(e,t){return this._obj[e]=t,this}},{key:"delete",value:function(e){return this._obj[e]=void 0,this}},{key:"clear",value:function(){this._obj={}}},{key:"has",value:function(e){return void 0!==this._obj[e]}},{key:"get",value:function(e){return this._obj[e]}}]),e}(),ze=function(){function e(t){if(f(this,e),this._obj=Object.create(null),this.size=0,null!=t){var n;n=null!=t.instanceString&&t.instanceString()===this.instanceString()?t.toArray():t;for(var r=0;r<n.length;r++)this.add(n[r])}}return y(e,[{key:"instanceString",value:function(){return"set"}},{key:"add",value:function(e){var t=this._obj;1!==t[e]&&(t[e]=1,this.size++)}},{key:"delete",value:function(e){var t=this._obj;1===t[e]&&(t[e]=0,this.size--)}},{key:"clear",value:function(){this._obj=Object.create(null)}},{key:"has",value:function(e){return 1===this._obj[e]}},{key:"toArray",value:function(){var e=this;return Object.keys(this._obj).filter((function(t){return e.has(t)}))}},{key:"forEach",value:function(e,t){return this.toArray().forEach(e,t)}}]),e}(),Ge="undefined"!==("undefined"==typeof Set?"undefined":g(Set))?Set:ze,Ye=function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(void 0!==e&&void 0!==t&&B(e)){var r=t.group;if(null==r&&(r=t.data&&null!=t.data.source&&null!=t.data.target?"edges":"nodes"),"nodes"===r||"edges"===r){this.length=1,this[0]=this;var i=this._private={cy:e,single:!0,data:t.data||{},position:t.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:r,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!t.selected,selectable:void 0===t.selectable||!!t.selectable,locked:!!t.locked,grabbed:!1,grabbable:void 0===t.grabbable||!!t.grabbable,pannable:void 0===t.pannable?"edges"===r:!!t.pannable,active:!1,classes:new Ge,animation:{current:[],queue:[]},rscratch:{},scratch:t.scratch||{},edges:[],children:[],parent:t.parent&&t.parent.isNode()?t.parent:null,traversalCache:{},backgrounding:!1,bbCache:null,bbCacheShift:{x:0,y:0},bodyBounds:null,overlayBounds:null,labelBounds:{all:null,source:null,target:null,main:null},arrowBounds:{source:null,target:null,"mid-source":null,"mid-target":null}};if(null==i.position.x&&(i.position.x=0),null==i.position.y&&(i.position.y=0),t.renderedPosition){var a=t.renderedPosition,o=e.pan(),s=e.zoom();i.position={x:(a.x-o.x)/s,y:(a.y-o.y)/s}}var l=[];k(t.classes)?l=t.classes:A(t.classes)&&(l=t.classes.split(/\s+/));for(var u=0,c=l.length;u<c;u++){var h=l[u];h&&""!==h&&i.classes.add(h)}this.createEmitter();var d=t.style||t.css;d&&(Ae("Setting a `style` bypass at element creation should be done only when absolutely necessary. Try to use the stylesheet instead."),this.style(d)),(void 0===n||n)&&this.restore()}else Ce("An element must be of type `nodes` or `edges`; you specified `"+r+"`")}else Ce("An element must have a core reference and parameters set")},Xe=function(e){return e={bfs:e.bfs||!e.dfs,dfs:e.dfs||!e.bfs},function(t,n,r){var i;S(t)&&!O(t)&&(t=(i=t).roots||i.root,n=i.visit,r=i.directed),r=2!==arguments.length||L(n)?r:n,n=L(n)?n:function(){};for(var a,o=this._private.cy,s=t=A(t)?this.filter(t):t,l=[],u=[],c={},h={},d={},p=0,g=this.byGroup(),f=g.nodes,v=g.edges,y=0;y<s.length;y++){var m=s[y],b=m.id();m.isNode()&&(l.unshift(m),e.bfs&&(d[b]=!0,u.push(m)),h[b]=0)}for(var x=function(){var t=e.bfs?l.shift():l.pop(),i=t.id();if(e.dfs){if(d[i])return"continue";d[i]=!0,u.push(t)}var o,s=h[i],g=c[i],y=null!=g?g.source():null,m=null!=g?g.target():null,b=null==g?void 0:t.same(y)?m[0]:y[0];if(!0===(o=n(t,g,b,p++,s)))return a=t,"break";if(!1===o)return"break";for(var x=t.connectedEdges().filter((function(e){return(!r||e.source().same(t))&&v.has(e)})),w=0;w<x.length;w++){var E=x[w],_=E.connectedNodes().filter((function(e){return!e.same(t)&&f.has(e)})),T=_.id();0===_.length||d[T]||(_=_[0],l.push(_),e.bfs&&(d[T]=!0,u.push(_)),c[T]=E,h[T]=h[i]+1)}};0!==l.length;){var w=x();if("continue"!==w&&"break"===w)break}for(var E=o.collection(),_=0;_<u.length;_++){var T=u[_],D=c[T.id()];null!=D&&E.push(D),E.push(T)}return{path:o.collection(E),found:o.collection(a)}}},Ve={breadthFirstSearch:Xe({bfs:!0}),depthFirstSearch:Xe({dfs:!0})};Ve.bfs=Ve.breadthFirstSearch,Ve.dfs=Ve.depthFirstSearch;var Ue=Me({root:null,weight:function(e){return 1},directed:!1}),je={dijkstra:function(e){if(!S(e)){var t=arguments;e={root:t[0],weight:t[1],directed:t[2]}}var n=Ue(e),r=n.root,i=n.weight,a=n.directed,o=this,s=i,l=A(r)?this.filter(r)[0]:r[0],u={},h={},d={},p=this.byGroup(),g=p.nodes,f=p.edges;f.unmergeBy((function(e){return e.isLoop()}));for(var v=function(e){return u[e.id()]},y=function(e,t){u[e.id()]=t,m.updateItem(e)},m=new c.default((function(e,t){return v(e)-v(t)})),b=0;b<g.length;b++){var x=g[b];u[x.id()]=x.same(l)?0:1/0,m.push(x)}for(var w=function(e,t){for(var n,r=(a?e.edgesTo(t):e.edgesWith(t)).intersect(f),i=1/0,o=0;o<r.length;o++){var l=r[o],u=s(l);(u<i||!n)&&(i=u,n=l)}return{edge:n,dist:i}};m.size()>0;){var E=m.pop(),_=v(E),T=E.id();if(d[T]=_,_!==1/0)for(var D=E.neighborhood().intersect(g),C=0;C<D.length;C++){var N=D[C],L=N.id(),k=w(E,N),I=_+k.dist;I<v(N)&&(y(N,I),h[L]={node:E,edge:k.edge})}}return{distanceTo:function(e){var t=A(e)?g.filter(e)[0]:e[0];return d[t.id()]},pathTo:function(e){var t=A(e)?g.filter(e)[0]:e[0],n=[],r=t,i=r.id();if(t.length>0)for(n.unshift(t);h[i];){var a=h[i];n.unshift(a.edge),n.unshift(a.node),i=(r=a.node).id()}return o.spawn(n)}}}},qe={kruskal:function(e){e=e||function(e){return 1};for(var t=this.byGroup(),n=t.nodes,r=t.edges,i=n.length,a=new Array(i),o=n,s=function(e){for(var t=0;t<a.length;t++){if(a[t].has(e))return t}},l=0;l<i;l++)a[l]=this.spawn(n[l]);for(var u=r.sort((function(t,n){return e(t)-e(n)})),c=0;c<u.length;c++){var h=u[c],d=h.source()[0],p=h.target()[0],g=s(d),f=s(p),v=a[g],y=a[f];g!==f&&(o.merge(h),v.merge(y),a.splice(f,1))}return o}},He=Me({root:null,goal:null,weight:function(e){return 1},heuristic:function(e){return 0},directed:!1}),We={aStar:function(e){var t=this.cy(),n=He(e),r=n.root,i=n.goal,a=n.heuristic,o=n.directed,s=n.weight;r=t.collection(r)[0],i=t.collection(i)[0];var l,u,h=r.id(),d=i.id(),p={},g={},f={},v=new c.default((function(e,t){return g[e.id()]-g[t.id()]})),y=new Ge,m={},b={},x=function(e,t){v.push(e),y.add(t)};x(r,h),p[h]=0,g[h]=a(r);for(var w,E=0;v.size()>0;){if(l=v.pop(),u=l.id(),y.delete(u),E++,u===d){for(var _=[],T=i,D=d,C=b[D];_.unshift(T),null!=C&&_.unshift(C),null!=(T=m[D]);)C=b[D=T.id()];return{found:!0,distance:p[u],path:this.spawn(_),steps:E}}f[u]=!0;for(var N=l._private.edges,A=0;A<N.length;A++){var L=N[A];if(this.hasElementWithId(L.id())&&(!o||L.data("source")===u)){var k=L.source(),S=L.target(),I=k.id()!==u?k:S,M=I.id();if(this.hasElementWithId(M)&&!f[M]){var O=p[u]+s(L);w=M,y.has(w)?O<p[M]&&(p[M]=O,g[M]=O+a(I),m[M]=l,b[M]=L):(p[M]=O,g[M]=O+a(I),x(I,M),m[M]=l,b[M]=L)}}}}return{found:!1,distance:void 0,path:void 0,steps:E}}},$e=Me({weight:function(e){return 1},directed:!1}),Ke={floydWarshall:function(e){for(var t=this.cy(),n=$e(e),r=n.weight,i=n.directed,a=r,o=this.byGroup(),s=o.nodes,l=o.edges,u=s.length,c=u*u,h=function(e){return s.indexOf(e)},d=function(e){return s[e]},p=new Array(c),g=0;g<c;g++){var f=g%u,v=(g-f)/u;p[g]=v===f?0:1/0}for(var y=new Array(c),m=new Array(c),b=0;b<l.length;b++){var x=l[b],w=x.source()[0],E=x.target()[0];if(w!==E){var _=h(w),T=h(E),D=_*u+T,C=a(x);if(p[D]>C&&(p[D]=C,y[D]=T,m[D]=x),!i){var N=T*u+_;!i&&p[N]>C&&(p[N]=C,y[N]=_,m[N]=x)}}}for(var L=0;L<u;L++)for(var k=0;k<u;k++)for(var S=k*u+L,I=0;I<u;I++){var M=k*u+I,O=L*u+I;p[S]+p[O]<p[M]&&(p[M]=p[S]+p[O],y[M]=y[S])}var P=function(e){return h(function(e){return(A(e)?t.filter(e):e)[0]}(e))},R={distance:function(e,t){var n=P(e),r=P(t);return p[n*u+r]},path:function(e,n){var r=P(e),i=P(n),a=d(r);if(r===i)return a.collection();if(null==y[r*u+i])return t.collection();var o,s=t.collection(),l=r;for(s.merge(a);r!==i;)l=r,r=y[r*u+i],o=m[l*u+r],s.merge(o),s.merge(d(r));return s}};return R}},Ze=Me({weight:function(e){return 1},directed:!1,root:null}),Qe={bellmanFord:function(e){var t=this,n=Ze(e),r=n.weight,i=n.directed,a=n.root,o=r,s=this,l=this.cy(),u=this.byGroup(),c=u.edges,h=u.nodes,d=h.length,p=new Fe,g=!1,f=[];a=l.collection(a)[0],c.unmergeBy((function(e){return e.isLoop()}));for(var v=c.length,y=function(e){var t=p.get(e.id());return t||(t={},p.set(e.id(),t)),t},m=function(e){return(A(e)?l.$(e):e)[0]},b=0;b<d;b++){var x=h[b],w=y(x);x.same(a)?w.dist=0:w.dist=1/0,w.pred=null,w.edge=null}for(var E=!1,_=function(e,t,n,r,i,a){var o=r.dist+a;o<i.dist&&!n.same(r.edge)&&(i.dist=o,i.pred=e,i.edge=n,E=!0)},T=1;T<d;T++){E=!1;for(var D=0;D<v;D++){var C=c[D],N=C.source(),L=C.target(),k=o(C),S=y(N),I=y(L);_(N,0,C,S,I,k),i||_(L,0,C,I,S,k)}if(!E)break}if(E)for(var M=[],O=0;O<v;O++){var P=c[O],R=P.source(),B=P.target(),F=o(P),z=y(R).dist,G=y(B).dist;if(z+F<G||!i&&G+F<z){if(g||(Ae("Graph contains a negative weight cycle for Bellman-Ford"),g=!0),!1===e.findNegativeWeightCycles)break;var Y=[];z+F<G&&Y.push(R),!i&&G+F<z&&Y.push(B);for(var X=Y.length,V=0;V<X;V++){var U=Y[V],j=[U];j.push(y(U).edge);for(var q=y(U).pred;-1===j.indexOf(q);)j.push(q),j.push(y(q).edge),q=y(q).pred;for(var H=(j=j.slice(j.indexOf(q)))[0].id(),W=0,$=2;$<j.length;$+=2)j[$].id()<H&&(H=j[$].id(),W=$);(j=j.slice(W).concat(j.slice(0,W))).push(j[0]);var K=j.map((function(e){return e.id()})).join(",");-1===M.indexOf(K)&&(f.push(s.spawn(j)),M.push(K))}}}return{distanceTo:function(e){return y(m(e)).dist},pathTo:function(e){for(var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:a,r=[],i=m(e);;){if(null==i)return t.spawn();var o=y(i),l=o.edge,u=o.pred;if(r.unshift(i[0]),i.same(n)&&r.length>0)break;null!=l&&r.unshift(l),i=u}return s.spawn(r)},hasNegativeWeightCycle:g,negativeWeightCycles:f}}},Je=Math.sqrt(2),et=function(e,t,n){0===n.length&&Ce("Karger-Stein must be run on a connected (sub)graph");for(var r=n[e],i=r[1],a=r[2],o=t[i],s=t[a],l=n,u=l.length-1;u>=0;u--){var c=l[u],h=c[1],d=c[2];(t[h]===o&&t[d]===s||t[h]===s&&t[d]===o)&&l.splice(u,1)}for(var p=0;p<l.length;p++){var g=l[p];g[1]===s?(l[p]=g.slice(),l[p][1]=o):g[2]===s&&(l[p]=g.slice(),l[p][2]=o)}for(var f=0;f<t.length;f++)t[f]===s&&(t[f]=o);return l},tt=function(e,t,n,r){for(;n>r;){var i=Math.floor(Math.random()*t.length);t=et(i,e,t),n--}return t},nt={kargerStein:function(){var e=this,t=this.byGroup(),n=t.nodes,r=t.edges;r.unmergeBy((function(e){return e.isLoop()}));var i=n.length,a=r.length,o=Math.ceil(Math.pow(Math.log(i)/Math.LN2,2)),s=Math.floor(i/Je);if(!(i<2)){for(var l=[],u=0;u<a;u++){var c=r[u];l.push([u,n.indexOf(c.source()),n.indexOf(c.target())])}for(var h=1/0,d=[],p=new Array(i),g=new Array(i),f=new Array(i),v=function(e,t){for(var n=0;n<i;n++)t[n]=e[n]},y=0;y<=o;y++){for(var m=0;m<i;m++)g[m]=m;var b=tt(g,l.slice(),i,s),x=b.slice();v(g,f);var w=tt(g,b,s,2),E=tt(f,x,s,2);w.length<=E.length&&w.length<h?(h=w.length,d=w,v(g,p)):E.length<=w.length&&E.length<h&&(h=E.length,d=E,v(f,p))}for(var _=this.spawn(d.map((function(e){return r[e[0]]}))),T=this.spawn(),D=this.spawn(),C=p[0],N=0;N<p.length;N++){var A=p[N],L=n[N];A===C?T.merge(L):D.merge(L)}var k=function(t){var n=e.spawn();return t.forEach((function(t){n.merge(t),t.connectedEdges().forEach((function(t){e.contains(t)&&!_.contains(t)&&n.merge(t)}))})),n},S=[k(T),k(D)];return{cut:_,components:S,partition1:T,partition2:D}}Ce("At least 2 nodes are required for Karger-Stein algorithm")}},rt=function(e,t,n){return{x:e.x*t+n.x,y:e.y*t+n.y}},it=function(e,t,n){return{x:(e.x-n.x)/t,y:(e.y-n.y)/t}},at=function(e){return{x:e[0],y:e[1]}},ot=function(e,t){return Math.atan2(t,e)-Math.PI/2},st=Math.log2||function(e){return Math.log(e)/Math.log(2)},lt=function(e){return e>0?1:e<0?-1:0},ut=function(e,t){return Math.sqrt(ct(e,t))},ct=function(e,t){var n=t.x-e.x,r=t.y-e.y;return n*n+r*r},ht=function(e){for(var t=e.length,n=0,r=0;r<t;r++)n+=e[r];for(var i=0;i<t;i++)e[i]=e[i]/n;return e},dt=function(e,t,n,r){return(1-r)*(1-r)*e+2*(1-r)*r*t+r*r*n},pt=function(e,t,n,r){return{x:dt(e.x,t.x,n.x,r),y:dt(e.y,t.y,n.y,r)}},gt=function(e,t,n){return Math.max(e,Math.min(n,t))},ft=function(e){if(null==e)return{x1:1/0,y1:1/0,x2:-1/0,y2:-1/0,w:0,h:0};if(null!=e.x1&&null!=e.y1){if(null!=e.x2&&null!=e.y2&&e.x2>=e.x1&&e.y2>=e.y1)return{x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,w:e.x2-e.x1,h:e.y2-e.y1};if(null!=e.w&&null!=e.h&&e.w>=0&&e.h>=0)return{x1:e.x1,y1:e.y1,x2:e.x1+e.w,y2:e.y1+e.h,w:e.w,h:e.h}}},vt=function(e,t){e.x1=Math.min(e.x1,t.x1),e.x2=Math.max(e.x2,t.x2),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,t.y1),e.y2=Math.max(e.y2,t.y2),e.h=e.y2-e.y1},yt=function(e,t,n){e.x1=Math.min(e.x1,t),e.x2=Math.max(e.x2,t),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,n),e.y2=Math.max(e.y2,n),e.h=e.y2-e.y1},mt=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e.x1-=t,e.x2+=t,e.y1-=t,e.y2+=t,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},bt=function(e){var t,n,r,i,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[0];if(1===a.length)t=n=r=i=a[0];else if(2===a.length)t=r=a[0],i=n=a[1];else if(4===a.length){var o=b(a,4);t=o[0],n=o[1],r=o[2],i=o[3]}return e.x1-=i,e.x2+=n,e.y1-=t,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},xt=function(e,t){e.x1=t.x1,e.y1=t.y1,e.x2=t.x2,e.y2=t.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},wt=function(e,t){return!(e.x1>t.x2)&&(!(t.x1>e.x2)&&(!(e.x2<t.x1)&&(!(t.x2<e.x1)&&(!(e.y2<t.y1)&&(!(t.y2<e.y1)&&(!(e.y1>t.y2)&&!(t.y1>e.y2)))))))},Et=function(e,t,n){return e.x1<=t&&t<=e.x2&&e.y1<=n&&n<=e.y2},_t=function(e,t){return Et(e,t.x1,t.y1)&&Et(e,t.x2,t.y2)},Tt=function(e,t,n,r,i,a,o){var s,l=Xt(i,a),u=i/2,c=a/2,h=r-c-o;if((s=Rt(e,t,n,r,n-u+l-o,h,n+u-l+o,h,!1)).length>0)return s;var d=n+u+o;if((s=Rt(e,t,n,r,d,r-c+l-o,d,r+c-l+o,!1)).length>0)return s;var p=r+c+o;if((s=Rt(e,t,n,r,n-u+l-o,p,n+u-l+o,p,!1)).length>0)return s;var g,f=n-u-o;if((s=Rt(e,t,n,r,f,r-c+l-o,f,r+c-l+o,!1)).length>0)return s;var v=n-u+l,y=r-c+l;if((g=Ot(e,t,n,r,v,y,l+o)).length>0&&g[0]<=v&&g[1]<=y)return[g[0],g[1]];var m=n+u-l,b=r-c+l;if((g=Ot(e,t,n,r,m,b,l+o)).length>0&&g[0]>=m&&g[1]<=b)return[g[0],g[1]];var x=n+u-l,w=r+c-l;if((g=Ot(e,t,n,r,x,w,l+o)).length>0&&g[0]>=x&&g[1]>=w)return[g[0],g[1]];var E=n-u+l,_=r+c-l;return(g=Ot(e,t,n,r,E,_,l+o)).length>0&&g[0]<=E&&g[1]>=_?[g[0],g[1]]:[]},Dt=function(e,t,n,r,i,a,o){var s=o,l=Math.min(n,i),u=Math.max(n,i),c=Math.min(r,a),h=Math.max(r,a);return l-s<=e&&e<=u+s&&c-s<=t&&t<=h+s},Ct=function(e,t,n,r,i,a,o,s,l){var u=Math.min(n,o,i)-l,c=Math.max(n,o,i)+l,h=Math.min(r,s,a)-l,d=Math.max(r,s,a)+l;return!(e<u||e>c||t<h||t>d)},Nt=function(e,t,n,r,i,a,o,s){var l=[];!function(e,t,n,r,i){var a,o,s,l,u,c,h,d;0===e&&(e=1e-5),s=-27*(r/=e)+(t/=e)*(9*(n/=e)-t*t*2),a=(o=(3*n-t*t)/9)*o*o+(s/=54)*s,i[1]=0,h=t/3,a>0?(u=(u=s+Math.sqrt(a))<0?-Math.pow(-u,1/3):Math.pow(u,1/3),c=(c=s-Math.sqrt(a))<0?-Math.pow(-c,1/3):Math.pow(c,1/3),i[0]=-h+u+c,h+=(u+c)/2,i[4]=i[2]=-h,h=Math.sqrt(3)*(-c+u)/2,i[3]=h,i[5]=-h):(i[5]=i[3]=0,0===a?(d=s<0?-Math.pow(-s,1/3):Math.pow(s,1/3),i[0]=2*d-h,i[4]=i[2]=-(d+h)):(l=(o=-o)*o*o,l=Math.acos(s/Math.sqrt(l)),d=2*Math.sqrt(o),i[0]=-h+d*Math.cos(l/3),i[2]=-h+d*Math.cos((l+2*Math.PI)/3),i[4]=-h+d*Math.cos((l+4*Math.PI)/3)))}(1*n*n-4*n*i+2*n*o+4*i*i-4*i*o+o*o+r*r-4*r*a+2*r*s+4*a*a-4*a*s+s*s,9*n*i-3*n*n-3*n*o-6*i*i+3*i*o+9*r*a-3*r*r-3*r*s-6*a*a+3*a*s,3*n*n-6*n*i+n*o-n*e+2*i*i+2*i*e-o*e+3*r*r-6*r*a+r*s-r*t+2*a*a+2*a*t-s*t,1*n*i-n*n+n*e-i*e+r*a-r*r+r*t-a*t,l);for(var u=[],c=0;c<6;c+=2)Math.abs(l[c+1])<1e-7&&l[c]>=0&&l[c]<=1&&u.push(l[c]);u.push(1),u.push(0);for(var h,d,p,g=-1,f=0;f<u.length;f++)h=Math.pow(1-u[f],2)*n+2*(1-u[f])*u[f]*i+u[f]*u[f]*o,d=Math.pow(1-u[f],2)*r+2*(1-u[f])*u[f]*a+u[f]*u[f]*s,p=Math.pow(h-e,2)+Math.pow(d-t,2),g>=0?p<g&&(g=p):g=p;return g},At=function(e,t,n,r,i,a){var o=[e-n,t-r],s=[i-n,a-r],l=s[0]*s[0]+s[1]*s[1],u=o[0]*o[0]+o[1]*o[1],c=o[0]*s[0]+o[1]*s[1],h=c*c/l;return c<0?u:h>l?(e-i)*(e-i)+(t-a)*(t-a):u-h},Lt=function(e,t,n){for(var r,i,a,o,s=0,l=0;l<n.length/2;l++)if(r=n[2*l],i=n[2*l+1],l+1<n.length/2?(a=n[2*(l+1)],o=n[2*(l+1)+1]):(a=n[2*(l+1-n.length/2)],o=n[2*(l+1-n.length/2)+1]),r==e&&a==e);else{if(!(r>=e&&e>=a||r<=e&&e<=a))continue;(e-r)/(a-r)*(o-i)+i>t&&s++}return s%2!=0},kt=function(e,t,n,r,i,a,o,s,l){var u,c=new Array(n.length);null!=s[0]?(u=Math.atan(s[1]/s[0]),s[0]<0?u+=Math.PI/2:u=-u-Math.PI/2):u=s;for(var h,d=Math.cos(-u),p=Math.sin(-u),g=0;g<c.length/2;g++)c[2*g]=a/2*(n[2*g]*d-n[2*g+1]*p),c[2*g+1]=o/2*(n[2*g+1]*d+n[2*g]*p),c[2*g]+=r,c[2*g+1]+=i;if(l>0){var f=It(c,-l);h=St(f)}else h=c;return Lt(e,t,h)},St=function(e){for(var t,n,r,i,a,o,s,l,u=new Array(e.length/2),c=0;c<e.length/4;c++){t=e[4*c],n=e[4*c+1],r=e[4*c+2],i=e[4*c+3],c<e.length/4-1?(a=e[4*(c+1)],o=e[4*(c+1)+1],s=e[4*(c+1)+2],l=e[4*(c+1)+3]):(a=e[0],o=e[1],s=e[2],l=e[3]);var h=Rt(t,n,r,i,a,o,s,l,!0);u[2*c]=h[0],u[2*c+1]=h[1]}return u},It=function(e,t){for(var n,r,i,a,o=new Array(2*e.length),s=0;s<e.length/2;s++){n=e[2*s],r=e[2*s+1],s<e.length/2-1?(i=e[2*(s+1)],a=e[2*(s+1)+1]):(i=e[0],a=e[1]);var l=a-r,u=-(i-n),c=Math.sqrt(l*l+u*u),h=l/c,d=u/c;o[4*s]=n+h*t,o[4*s+1]=r+d*t,o[4*s+2]=i+h*t,o[4*s+3]=a+d*t}return o},Mt=function(e,t,n,r,i,a,o){return e-=i,t-=a,(e/=n/2+o)*e+(t/=r/2+o)*t<=1},Ot=function(e,t,n,r,i,a,o){var s=[n-e,r-t],l=[e-i,t-a],u=s[0]*s[0]+s[1]*s[1],c=2*(l[0]*s[0]+l[1]*s[1]),h=c*c-4*u*(l[0]*l[0]+l[1]*l[1]-o*o);if(h<0)return[];var d=(-c+Math.sqrt(h))/(2*u),p=(-c-Math.sqrt(h))/(2*u),g=Math.min(d,p),f=Math.max(d,p),v=[];if(g>=0&&g<=1&&v.push(g),f>=0&&f<=1&&v.push(f),0===v.length)return[];var y=v[0]*s[0]+e,m=v[0]*s[1]+t;return v.length>1?v[0]==v[1]?[y,m]:[y,m,v[1]*s[0]+e,v[1]*s[1]+t]:[y,m]},Pt=function(e,t,n){return t<=e&&e<=n||n<=e&&e<=t?e:e<=t&&t<=n||n<=t&&t<=e?t:n},Rt=function(e,t,n,r,i,a,o,s,l){var u=e-i,c=n-e,h=o-i,d=t-a,p=r-t,g=s-a,f=h*d-g*u,v=c*d-p*u,y=g*c-h*p;if(0!==y){var m=f/y,b=v/y,x=-.001;return x<=m&&m<=1.001&&x<=b&&b<=1.001||l?[e+m*c,t+m*p]:[]}return 0===f||0===v?Pt(e,n,o)===o?[o,s]:Pt(e,n,i)===i?[i,a]:Pt(i,o,n)===n?[n,r]:[]:[]},Bt=function(e,t,n,r,i,a,o,s){var l,u,c,h,d,p,g=[],f=new Array(n.length),v=!0;if(null==a&&(v=!1),v){for(var y=0;y<f.length/2;y++)f[2*y]=n[2*y]*a+r,f[2*y+1]=n[2*y+1]*o+i;if(s>0){var m=It(f,-s);u=St(m)}else u=f}else u=n;for(var b=0;b<u.length/2;b++)c=u[2*b],h=u[2*b+1],b<u.length/2-1?(d=u[2*(b+1)],p=u[2*(b+1)+1]):(d=u[0],p=u[1]),0!==(l=Rt(e,t,r,i,c,h,d,p)).length&&g.push(l[0],l[1]);return g},Ft=function(e,t,n){var r=[e[0]-t[0],e[1]-t[1]],i=Math.sqrt(r[0]*r[0]+r[1]*r[1]),a=(i-n)/i;return a<0&&(a=1e-5),[t[0]+a*r[0],t[1]+a*r[1]]},zt=function(e,t){var n=Yt(e,t);return n=Gt(n)},Gt=function(e){for(var t,n,r=e.length/2,i=1/0,a=1/0,o=-1/0,s=-1/0,l=0;l<r;l++)t=e[2*l],n=e[2*l+1],i=Math.min(i,t),o=Math.max(o,t),a=Math.min(a,n),s=Math.max(s,n);for(var u=2/(o-i),c=2/(s-a),h=0;h<r;h++)t=e[2*h]=e[2*h]*u,n=e[2*h+1]=e[2*h+1]*c,i=Math.min(i,t),o=Math.max(o,t),a=Math.min(a,n),s=Math.max(s,n);if(a<-1)for(var d=0;d<r;d++)n=e[2*d+1]=e[2*d+1]+(-1-a);return e},Yt=function(e,t){var n=1/e*2*Math.PI,r=e%2==0?Math.PI/2+n/2:Math.PI/2;r+=t;for(var i,a=new Array(2*e),o=0;o<e;o++)i=o*n+r,a[2*o]=Math.cos(i),a[2*o+1]=Math.sin(-i);return a},Xt=function(e,t){return Math.min(e/4,t/4,8)},Vt=function(e,t){return Math.min(e/10,t/10,8)},Ut=function(e,t){return{heightOffset:Math.min(15,.05*t),widthOffset:Math.min(100,.25*e),ctrlPtOffsetPct:.05}},jt=Me({dampingFactor:.8,precision:1e-6,iterations:200,weight:function(e){return 1}}),qt={pageRank:function(e){for(var t=jt(e),n=t.dampingFactor,r=t.precision,i=t.iterations,a=t.weight,o=this._private.cy,s=this.byGroup(),l=s.nodes,u=s.edges,c=l.length,h=c*c,d=u.length,p=new Array(h),g=new Array(c),f=(1-n)/c,v=0;v<c;v++){for(var y=0;y<c;y++){p[v*c+y]=0}g[v]=0}for(var m=0;m<d;m++){var b=u[m],x=b.data("source"),w=b.data("target");if(x!==w){var E=l.indexOfId(x),_=l.indexOfId(w),T=a(b);p[_*c+E]+=T,g[E]+=T}}for(var D=1/c+f,C=0;C<c;C++)if(0===g[C])for(var N=0;N<c;N++){p[N*c+C]=D}else for(var A=0;A<c;A++){var L=A*c+C;p[L]=p[L]/g[C]+f}for(var k,S=new Array(c),I=new Array(c),M=0;M<c;M++)S[M]=1;for(var O=0;O<i;O++){for(var P=0;P<c;P++)I[P]=0;for(var R=0;R<c;R++)for(var B=0;B<c;B++){var F=R*c+B;I[R]+=p[F]*S[B]}ht(I),k=S,S=I,I=k;for(var z=0,G=0;G<c;G++){var Y=k[G]-S[G];z+=Y*Y}if(z<r)break}return{rank:function(e){return e=o.collection(e)[0],S[l.indexOf(e)]}}}},Ht=Me({root:null,weight:function(e){return 1},directed:!1,alpha:0}),Wt={degreeCentralityNormalized:function(e){e=Ht(e);var t=this.cy(),n=this.nodes(),r=n.length;if(e.directed){for(var i={},a={},o=0,s=0,l=0;l<r;l++){var u=n[l],c=u.id();e.root=u;var h=this.degreeCentrality(e);o<h.indegree&&(o=h.indegree),s<h.outdegree&&(s=h.outdegree),i[c]=h.indegree,a[c]=h.outdegree}return{indegree:function(e){return 0==o?0:(A(e)&&(e=t.filter(e)),i[e.id()]/o)},outdegree:function(e){return 0===s?0:(A(e)&&(e=t.filter(e)),a[e.id()]/s)}}}for(var d={},p=0,g=0;g<r;g++){var f=n[g];e.root=f;var v=this.degreeCentrality(e);p<v.degree&&(p=v.degree),d[f.id()]=v.degree}return{degree:function(e){return 0===p?0:(A(e)&&(e=t.filter(e)),d[e.id()]/p)}}},degreeCentrality:function(e){e=Ht(e);var t=this.cy(),n=this,r=e,i=r.root,a=r.weight,o=r.directed,s=r.alpha;if(i=t.collection(i)[0],o){for(var l=i.connectedEdges(),u=l.filter((function(e){return e.target().same(i)&&n.has(e)})),c=l.filter((function(e){return e.source().same(i)&&n.has(e)})),h=u.length,d=c.length,p=0,g=0,f=0;f<u.length;f++)p+=a(u[f]);for(var v=0;v<c.length;v++)g+=a(c[v]);return{indegree:Math.pow(h,1-s)*Math.pow(p,s),outdegree:Math.pow(d,1-s)*Math.pow(g,s)}}for(var y=i.connectedEdges().intersection(n),m=y.length,b=0,x=0;x<y.length;x++)b+=a(y[x]);return{degree:Math.pow(m,1-s)*Math.pow(b,s)}}};Wt.dc=Wt.degreeCentrality,Wt.dcn=Wt.degreeCentralityNormalised=Wt.degreeCentralityNormalized;var $t=Me({harmonic:!0,weight:function(){return 1},directed:!1,root:null}),Kt={closenessCentralityNormalized:function(e){for(var t=$t(e),n=t.harmonic,r=t.weight,i=t.directed,a=this.cy(),o={},s=0,l=this.nodes(),u=this.floydWarshall({weight:r,directed:i}),c=0;c<l.length;c++){for(var h=0,d=l[c],p=0;p<l.length;p++)if(c!==p){var g=u.distance(d,l[p]);h+=n?1/g:g}n||(h=1/h),s<h&&(s=h),o[d.id()]=h}return{closeness:function(e){return 0==s?0:(e=A(e)?a.filter(e)[0].id():e.id(),o[e]/s)}}},closenessCentrality:function(e){var t=$t(e),n=t.root,r=t.weight,i=t.directed,a=t.harmonic;n=this.filter(n)[0];for(var o=this.dijkstra({root:n,weight:r,directed:i}),s=0,l=this.nodes(),u=0;u<l.length;u++){var c=l[u];if(!c.same(n)){var h=o.distanceTo(c);s+=a?1/h:h}}return a?s:1/s}};Kt.cc=Kt.closenessCentrality,Kt.ccn=Kt.closenessCentralityNormalised=Kt.closenessCentralityNormalized;var Zt=Me({weight:null,directed:!1}),Qt={betweennessCentrality:function(e){for(var t=Zt(e),n=t.directed,r=t.weight,i=null!=r,a=this.cy(),o=this.nodes(),s={},l={},u=0,h=function(e,t){l[e]=t,t>u&&(u=t)},d=function(e){return l[e]},p=0;p<o.length;p++){var g=o[p],f=g.id();s[f]=n?g.outgoers().nodes():g.openNeighborhood().nodes(),h(f,0)}for(var v=function(e){for(var t=o[e].id(),n=[],l={},u={},p={},g=new c.default((function(e,t){return p[e]-p[t]})),f=0;f<o.length;f++){var v=o[f].id();l[v]=[],u[v]=0,p[v]=1/0}for(u[t]=1,p[t]=0,g.push(t);!g.empty();){var y=g.pop();if(n.push(y),i)for(var m=0;m<s[y].length;m++){var b=s[y][m],x=a.getElementById(y),w=void 0;w=x.edgesTo(b).length>0?x.edgesTo(b)[0]:b.edgesTo(x)[0];var E=r(w);b=b.id(),p[b]>p[y]+E&&(p[b]=p[y]+E,g.nodes.indexOf(b)<0?g.push(b):g.updateItem(b),u[b]=0,l[b]=[]),p[b]==p[y]+E&&(u[b]=u[b]+u[y],l[b].push(y))}else for(var _=0;_<s[y].length;_++){var T=s[y][_].id();p[T]==1/0&&(g.push(T),p[T]=p[y]+1),p[T]==p[y]+1&&(u[T]=u[T]+u[y],l[T].push(y))}}for(var D={},C=0;C<o.length;C++)D[o[C].id()]=0;for(;n.length>0;){for(var N=n.pop(),A=0;A<l[N].length;A++){var L=l[N][A];D[L]=D[L]+u[L]/u[N]*(1+D[N])}N!=o[e].id()&&h(N,d(N)+D[N])}},y=0;y<o.length;y++)v(y);var m={betweenness:function(e){var t=a.collection(e).id();return d(t)},betweennessNormalized:function(e){if(0==u)return 0;var t=a.collection(e).id();return d(t)/u}};return m.betweennessNormalised=m.betweennessNormalized,m}};Qt.bc=Qt.betweennessCentrality;var Jt=Me({expandFactor:2,inflateFactor:2,multFactor:1,maxIterations:20,attributes:[function(e){return 1}]}),en=function(e,t){for(var n=0,r=0;r<t.length;r++)n+=t[r](e);return n},tn=function(e,t){for(var n,r=0;r<t;r++){n=0;for(var i=0;i<t;i++)n+=e[i*t+r];for(var a=0;a<t;a++)e[a*t+r]=e[a*t+r]/n}},nn=function(e,t,n){for(var r=new Array(n*n),i=0;i<n;i++){for(var a=0;a<n;a++)r[i*n+a]=0;for(var o=0;o<n;o++)for(var s=0;s<n;s++)r[i*n+s]+=e[i*n+o]*t[o*n+s]}return r},rn=function(e,t,n){for(var r=e.slice(0),i=1;i<n;i++)e=nn(e,r,t);return e},an=function(e,t,n){for(var r=new Array(t*t),i=0;i<t*t;i++)r[i]=Math.pow(e[i],n);return tn(r,t),r},on=function(e,t,n,r){for(var i=0;i<n;i++){if(Math.round(e[i]*Math.pow(10,r))/Math.pow(10,r)!==Math.round(t[i]*Math.pow(10,r))/Math.pow(10,r))return!1}return!0},sn=function(e,t){for(var n=0;n<e.length;n++)if(!t[n]||e[n].id()!==t[n].id())return!1;return!0},ln=function(e){for(var t=this.nodes(),n=this.edges(),r=this.cy(),i=function(e){return Jt(e)}(e),a={},o=0;o<t.length;o++)a[t[o].id()]=o;for(var s,l=t.length,u=l*l,c=new Array(u),h=0;h<u;h++)c[h]=0;for(var d=0;d<n.length;d++){var p=n[d],g=a[p.source().id()],f=a[p.target().id()],v=en(p,i.attributes);c[g*l+f]+=v,c[f*l+g]+=v}!function(e,t,n){for(var r=0;r<t;r++)e[r*t+r]=n}(c,l,i.multFactor),tn(c,l);for(var y=!0,m=0;y&&m<i.maxIterations;)y=!1,s=rn(c,l,i.expandFactor),c=an(s,l,i.inflateFactor),on(c,s,u,4)||(y=!0),m++;var b=function(e,t,n,r){for(var i=[],a=0;a<t;a++){for(var o=[],s=0;s<t;s++)Math.round(1e3*e[a*t+s])/1e3>0&&o.push(n[s]);0!==o.length&&i.push(r.collection(o))}return i}(c,l,t,r);return b=function(e){for(var t=0;t<e.length;t++)for(var n=0;n<e.length;n++)t!=n&&sn(e[t],e[n])&&e.splice(n,1);return e}(b),b},un={markovClustering:ln,mcl:ln},cn=function(e){return e},hn=function(e,t){return Math.abs(t-e)},dn=function(e,t,n){return e+hn(t,n)},pn=function(e,t,n){return e+Math.pow(n-t,2)},gn=function(e){return Math.sqrt(e)},fn=function(e,t,n){return Math.max(e,hn(t,n))},vn=function(e,t,n,r,i){for(var a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:cn,o=r,s=0;s<e;s++)o=i(o,t(s),n(s));return a(o)},yn={euclidean:function(e,t,n){return e>=2?vn(e,t,n,0,pn,gn):vn(e,t,n,0,dn)},squaredEuclidean:function(e,t,n){return vn(e,t,n,0,pn)},manhattan:function(e,t,n){return vn(e,t,n,0,dn)},max:function(e,t,n){return vn(e,t,n,-1/0,fn)}};function mn(e,t,n,r,i,a){var o;return o=L(e)?e:yn[e]||yn.euclidean,0===t&&L(e)?o(i,a):o(t,n,r,i,a)}yn["squared-euclidean"]=yn.squaredEuclidean,yn.squaredeuclidean=yn.squaredEuclidean;var bn=Me({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),xn=function(e){return bn(e)},wn=function(e,t,n,r,i){var a="kMedoids"!==i?function(e){return n[e]}:function(e){return r[e](n)},o=n,s=t;return mn(e,r.length,a,(function(e){return r[e](t)}),o,s)},En=function(e,t,n){for(var r=n.length,i=new Array(r),a=new Array(r),o=new Array(t),s=null,l=0;l<r;l++)i[l]=e.min(n[l]).value,a[l]=e.max(n[l]).value;for(var u=0;u<t;u++){s=[];for(var c=0;c<r;c++)s[c]=Math.random()*(a[c]-i[c])+i[c];o[u]=s}return o},_n=function(e,t,n,r,i){for(var a=1/0,o=0,s=0;s<t.length;s++){var l=wn(n,e,t[s],r,i);l<a&&(a=l,o=s)}return o},Tn=function(e,t,n){for(var r=[],i=null,a=0;a<t.length;a++)n[(i=t[a]).id()]===e&&r.push(i);return r},Dn=function(e,t,n){for(var r=0;r<e.length;r++)for(var i=0;i<e[r].length;i++){if(Math.abs(e[r][i]-t[r][i])>n)return!1}return!0},Cn=function(e,t,n){for(var r=0;r<n;r++)if(e===t[r])return!0;return!1},Nn=function(e,t){var n=new Array(t);if(e.length<50)for(var r=0;r<t;r++){for(var i=e[Math.floor(Math.random()*e.length)];Cn(i,n,r);)i=e[Math.floor(Math.random()*e.length)];n[r]=i}else for(var a=0;a<t;a++)n[a]=e[Math.floor(Math.random()*e.length)];return n},An=function(e,t,n){for(var r=0,i=0;i<t.length;i++)r+=wn("manhattan",t[i],e,n,"kMedoids");return r},Ln=function(e,t,n,r,i){for(var a,o,s=0;s<t.length;s++)for(var l=0;l<e.length;l++)r[s][l]=Math.pow(n[s][l],i.m);for(var u=0;u<e.length;u++)for(var c=0;c<i.attributes.length;c++){a=0,o=0;for(var h=0;h<t.length;h++)a+=r[h][u]*i.attributes[c](t[h]),o+=r[h][u];e[u][c]=a/o}},kn=function(e,t,n,r,i){for(var a=0;a<e.length;a++)t[a]=e[a].slice();for(var o,s,l,u=2/(i.m-1),c=0;c<n.length;c++)for(var h=0;h<r.length;h++){o=0;for(var d=0;d<n.length;d++)s=wn(i.distance,r[h],n[c],i.attributes,"cmeans"),l=wn(i.distance,r[h],n[d],i.attributes,"cmeans"),o+=Math.pow(s/l,u);e[h][c]=1/o}},Sn=function(e){var t,n,r,i,a,o=this.cy(),s=this.nodes(),l=xn(e);i=new Array(s.length);for(var u=0;u<s.length;u++)i[u]=new Array(l.k);r=new Array(s.length);for(var c=0;c<s.length;c++)r[c]=new Array(l.k);for(var h=0;h<s.length;h++){for(var d=0,p=0;p<l.k;p++)r[h][p]=Math.random(),d+=r[h][p];for(var g=0;g<l.k;g++)r[h][g]=r[h][g]/d}n=new Array(l.k);for(var f=0;f<l.k;f++)n[f]=new Array(l.attributes.length);a=new Array(s.length);for(var v=0;v<s.length;v++)a[v]=new Array(l.k);for(var y=!0,m=0;y&&m<l.maxIterations;)y=!1,Ln(n,s,r,a,l),kn(r,i,n,s,l),Dn(r,i,l.sensitivityThreshold)||(y=!0),m++;return t=function(e,t,n,r){for(var i,a,o=new Array(n.k),s=0;s<o.length;s++)o[s]=[];for(var l=0;l<t.length;l++){i=-1/0,a=-1;for(var u=0;u<t[0].length;u++)t[l][u]>i&&(i=t[l][u],a=u);o[a].push(e[l])}for(var c=0;c<o.length;c++)o[c]=r.collection(o[c]);return o}(s,r,l,o),{clusters:t,degreeOfMembership:r}},In={kMeans:function(e){var t,n=this.cy(),r=this.nodes(),i=null,a=xn(e),o=new Array(a.k),s={};a.testMode?"number"==typeof a.testCentroids?(a.testCentroids,t=En(r,a.k,a.attributes)):t="object"===g(a.testCentroids)?a.testCentroids:En(r,a.k,a.attributes):t=En(r,a.k,a.attributes);for(var l,u,c,h=!0,d=0;h&&d<a.maxIterations;){for(var p=0;p<r.length;p++)s[(i=r[p]).id()]=_n(i,t,a.distance,a.attributes,"kMeans");h=!1;for(var f=0;f<a.k;f++){var v=Tn(f,r,s);if(0!==v.length){for(var y=a.attributes.length,m=t[f],b=new Array(y),x=new Array(y),w=0;w<y;w++){x[w]=0;for(var E=0;E<v.length;E++)i=v[E],x[w]+=a.attributes[w](i);b[w]=x[w]/v.length,l=b[w],u=m[w],c=a.sensitivityThreshold,Math.abs(u-l)<=c||(h=!0)}t[f]=b,o[f]=n.collection(v)}}d++}return o},kMedoids:function(e){var t,n,r=this.cy(),i=this.nodes(),a=null,o=xn(e),s=new Array(o.k),l={},u=new Array(o.k);o.testMode?"number"==typeof o.testCentroids||(t="object"===g(o.testCentroids)?o.testCentroids:Nn(i,o.k)):t=Nn(i,o.k);for(var c=!0,h=0;c&&h<o.maxIterations;){for(var d=0;d<i.length;d++)l[(a=i[d]).id()]=_n(a,t,o.distance,o.attributes,"kMedoids");c=!1;for(var p=0;p<t.length;p++){var f=Tn(p,i,l);if(0!==f.length){u[p]=An(t[p],f,o.attributes);for(var v=0;v<f.length;v++)(n=An(f[v],f,o.attributes))<u[p]&&(u[p]=n,t[p]=f[v],c=!0);s[p]=r.collection(f)}}h++}return s},fuzzyCMeans:Sn,fcm:Sn},Mn=Me({distance:"euclidean",linkage:"min",mode:"threshold",threshold:1/0,addDendrogram:!1,dendrogramDepth:0,attributes:[]}),On={single:"min",complete:"max"},Pn=function(e,t,n,r,i){for(var a,o=0,s=1/0,l=i.attributes,u=function(e,t){return mn(i.distance,l.length,(function(t){return l[t](e)}),(function(e){return l[e](t)}),e,t)},c=0;c<e.length;c++){var h=e[c].key,d=n[h][r[h]];d<s&&(o=h,s=d)}if("threshold"===i.mode&&s>=i.threshold||"dendrogram"===i.mode&&1===e.length)return!1;var p,g=t[o],f=t[r[o]];p="dendrogram"===i.mode?{left:g,right:f,key:g.key}:{value:g.value.concat(f.value),key:g.key},e[g.index]=p,e.splice(f.index,1),t[g.key]=p;for(var v=0;v<e.length;v++){var y=e[v];g.key===y.key?a=1/0:"min"===i.linkage?(a=n[g.key][y.key],n[g.key][y.key]>n[f.key][y.key]&&(a=n[f.key][y.key])):"max"===i.linkage?(a=n[g.key][y.key],n[g.key][y.key]<n[f.key][y.key]&&(a=n[f.key][y.key])):a="mean"===i.linkage?(n[g.key][y.key]*g.size+n[f.key][y.key]*f.size)/(g.size+f.size):"dendrogram"===i.mode?u(y.value,g.value):u(y.value[0],g.value[0]),n[g.key][y.key]=n[y.key][g.key]=a}for(var m=0;m<e.length;m++){var b=e[m].key;if(r[b]===g.key||r[b]===f.key){for(var x=b,w=0;w<e.length;w++){var E=e[w].key;n[b][E]<n[b][x]&&(x=E)}r[b]=x}e[m].index=m}return g.key=f.key=g.index=f.index=null,!0},Rn=function e(t,n,r){t&&(t.value?n.push(t.value):(t.left&&e(t.left,n),t.right&&e(t.right,n)))},Bn=function e(t,n){if(!t)return"";if(t.left&&t.right){var r=e(t.left,n),i=e(t.right,n),a=n.add({group:"nodes",data:{id:r+","+i}});return n.add({group:"edges",data:{source:r,target:a.id()}}),n.add({group:"edges",data:{source:i,target:a.id()}}),a.id()}return t.value?t.value.id():void 0},Fn=function e(t,n,r){if(!t)return[];var i=[],a=[],o=[];return 0===n?(t.left&&Rn(t.left,i),t.right&&Rn(t.right,a),o=i.concat(a),[r.collection(o)]):1===n?t.value?[r.collection(t.value)]:(t.left&&Rn(t.left,i),t.right&&Rn(t.right,a),[r.collection(i),r.collection(a)]):t.value?[r.collection(t.value)]:(t.left&&(i=e(t.left,n-1,r)),t.right&&(a=e(t.right,n-1,r)),i.concat(a))},zn=function(e){for(var t=this.cy(),n=this.nodes(),r=function(e){var t=Mn(e),n=On[t.linkage];return null!=n&&(t.linkage=n),t}(e),i=r.attributes,a=function(e,t){return mn(r.distance,i.length,(function(t){return i[t](e)}),(function(e){return i[e](t)}),e,t)},o=[],s=[],l=[],u=[],c=0;c<n.length;c++){var h={value:"dendrogram"===r.mode?n[c]:[n[c]],key:c,index:c};o[c]=h,u[c]=h,s[c]=[],l[c]=0}for(var d=0;d<o.length;d++)for(var p=0;p<=d;p++){var g=void 0;g="dendrogram"===r.mode?d===p?1/0:a(o[d].value,o[p].value):d===p?1/0:a(o[d].value[0],o[p].value[0]),s[d][p]=g,s[p][d]=g,g<s[d][l[d]]&&(l[d]=p)}for(var f,v=Pn(o,u,s,l,r);v;)v=Pn(o,u,s,l,r);return"dendrogram"===r.mode?(f=Fn(o[0],r.dendrogramDepth,t),r.addDendrogram&&Bn(o[0],t)):(f=new Array(o.length),o.forEach((function(e,n){e.key=e.index=null,f[n]=t.collection(e.value)}))),f},Gn={hierarchicalClustering:zn,hca:zn},Yn=Me({distance:"euclidean",preference:"median",damping:.8,maxIterations:1e3,minIterations:100,attributes:[]}),Xn=function(e,t,n,r){var i=function(e,t){return r[t](e)};return-mn(e,r.length,(function(e){return i(t,e)}),(function(e){return i(n,e)}),t,n)},Vn=function(e,t){var n=null;return n="median"===t?function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];arguments.length>3&&void 0!==arguments[3]&&!arguments[3]?(n<e.length&&e.splice(n,e.length-n),t>0&&e.splice(0,t)):e=e.slice(t,n);for(var a=0,o=e.length-1;o>=0;o--){var s=e[o];i?isFinite(s)||(e[o]=-1/0,a++):e.splice(o,1)}r&&e.sort((function(e,t){return e-t}));var l=e.length,u=Math.floor(l/2);return l%2!=0?e[u+1+a]:(e[u-1+a]+e[u+a])/2}(e):"mean"===t?function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=0,i=0,a=t;a<n;a++){var o=e[a];isFinite(o)&&(r+=o,i++)}return r/i}(e):"min"===t?function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=1/0,i=t;i<n;i++){var a=e[i];isFinite(a)&&(r=Math.min(a,r))}return r}(e):"max"===t?function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=-1/0,i=t;i<n;i++){var a=e[i];isFinite(a)&&(r=Math.max(a,r))}return r}(e):t,n},Un=function(e,t,n){for(var r=[],i=0;i<e;i++){for(var a=-1,o=-1/0,s=0;s<n.length;s++){var l=n[s];t[i*e+l]>o&&(a=l,o=t[i*e+l])}a>0&&r.push(a)}for(var u=0;u<n.length;u++)r[n[u]]=n[u];return r},jn=function(e){for(var t,n,r,i,a,o,s=this.cy(),l=this.nodes(),u=function(e){var t=e.damping,n=e.preference;.5<=t&&t<1||Ce("Damping must range on [0.5, 1). Got: ".concat(t));var r=["median","mean","min","max"];return r.some((function(e){return e===n}))||I(n)||Ce("Preference must be one of [".concat(r.map((function(e){return"'".concat(e,"'")})).join(", "),"] or a number. Got: ").concat(n)),Yn(e)}(e),c={},h=0;h<l.length;h++)c[l[h].id()]=h;n=(t=l.length)*t,r=new Array(n);for(var d=0;d<n;d++)r[d]=-1/0;for(var p=0;p<t;p++)for(var g=0;g<t;g++)p!==g&&(r[p*t+g]=Xn(u.distance,l[p],l[g],u.attributes));i=Vn(r,u.preference);for(var f=0;f<t;f++)r[f*t+f]=i;a=new Array(n);for(var v=0;v<n;v++)a[v]=0;o=new Array(n);for(var y=0;y<n;y++)o[y]=0;for(var m=new Array(t),b=new Array(t),x=new Array(t),w=0;w<t;w++)m[w]=0,b[w]=0,x[w]=0;for(var E,_=new Array(t*u.minIterations),T=0;T<_.length;T++)_[T]=0;for(E=0;E<u.maxIterations;E++){for(var D=0;D<t;D++){for(var C=-1/0,N=-1/0,A=-1,L=0,k=0;k<t;k++)m[k]=a[D*t+k],(L=o[D*t+k]+r[D*t+k])>=C?(N=C,C=L,A=k):L>N&&(N=L);for(var S=0;S<t;S++)a[D*t+S]=(1-u.damping)*(r[D*t+S]-C)+u.damping*m[S];a[D*t+A]=(1-u.damping)*(r[D*t+A]-N)+u.damping*m[A]}for(var M=0;M<t;M++){for(var O=0,P=0;P<t;P++)m[P]=o[P*t+M],b[P]=Math.max(0,a[P*t+M]),O+=b[P];O-=b[M],b[M]=a[M*t+M],O+=b[M];for(var R=0;R<t;R++)o[R*t+M]=(1-u.damping)*Math.min(0,O-b[R])+u.damping*m[R];o[M*t+M]=(1-u.damping)*(O-b[M])+u.damping*m[M]}for(var B=0,F=0;F<t;F++){var z=o[F*t+F]+a[F*t+F]>0?1:0;_[E%u.minIterations*t+F]=z,B+=z}if(B>0&&(E>=u.minIterations-1||E==u.maxIterations-1)){for(var G=0,Y=0;Y<t;Y++){x[Y]=0;for(var X=0;X<u.minIterations;X++)x[Y]+=_[X*t+Y];0!==x[Y]&&x[Y]!==u.minIterations||G++}if(G===t)break}}for(var V=function(e,t,n){for(var r=[],i=0;i<e;i++)t[i*e+i]+n[i*e+i]>0&&r.push(i);return r}(t,a,o),U=function(e,t,n){for(var r=Un(e,t,n),i=0;i<n.length;i++){for(var a=[],o=0;o<r.length;o++)r[o]===n[i]&&a.push(o);for(var s=-1,l=-1/0,u=0;u<a.length;u++){for(var c=0,h=0;h<a.length;h++)c+=t[a[h]*e+a[u]];c>l&&(s=u,l=c)}n[i]=a[s]}return Un(e,t,n)}(t,r,V),j={},q=0;q<V.length;q++)j[V[q]]=[];for(var H=0;H<l.length;H++){var W=U[c[l[H].id()]];null!=W&&j[W].push(l[H])}for(var $=new Array(V.length),K=0;K<V.length;K++)$[K]=s.collection(j[V[K]]);return $},qn={affinityPropagation:jn,ap:jn},Hn=Me({root:void 0,directed:!1}),Wn=function(){var e=this,t={},n=0,r=0,i=[],a=[],o={},s=function s(l,u,c){l===c&&(r+=1),t[u]={id:n,low:n++,cutVertex:!1};var h,d,p,g,f=e.getElementById(u).connectedEdges().intersection(e);0===f.size()?i.push(e.spawn(e.getElementById(u))):f.forEach((function(n){h=n.source().id(),d=n.target().id(),(p=h===u?d:h)!==c&&(g=n.id(),o[g]||(o[g]=!0,a.push({x:u,y:p,edge:n})),p in t?t[u].low=Math.min(t[u].low,t[p].id):(s(l,p,u),t[u].low=Math.min(t[u].low,t[p].low),t[u].id<=t[p].low&&(t[u].cutVertex=!0,function(n,r){for(var o=a.length-1,s=[],l=e.spawn();a[o].x!=n||a[o].y!=r;)s.push(a.pop().edge),o--;s.push(a.pop().edge),s.forEach((function(n){var r=n.connectedNodes().intersection(e);l.merge(n),r.forEach((function(n){var r=n.id(),i=n.connectedEdges().intersection(e);l.merge(n),t[r].cutVertex?l.merge(i.filter((function(e){return e.isLoop()}))):l.merge(i)}))})),i.push(l)}(u,p))))}))};e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||(r=0,s(n,n),t[n].cutVertex=r>1)}}));var l=Object.keys(t).filter((function(e){return t[e].cutVertex})).map((function(t){return e.getElementById(t)}));return{cut:e.spawn(l),components:i}},$n=function(){var e=this,t={},n=0,r=[],i=[],a=e.spawn(e),o=function o(s){if(i.push(s),t[s]={index:n,low:n++,explored:!1},e.getElementById(s).connectedEdges().intersection(e).forEach((function(e){var n=e.target().id();n!==s&&(n in t||o(n),t[n].explored||(t[s].low=Math.min(t[s].low,t[n].low)))})),t[s].index===t[s].low){for(var l=e.spawn();;){var u=i.pop();if(l.merge(e.getElementById(u)),t[u].low=t[s].index,t[u].explored=!0,u===s)break}var c=l.edgesWith(l),h=l.merge(c);r.push(h),a=a.difference(h)}};return e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||o(n)}})),{cut:a,components:r}},Kn={};[Ve,je,qe,We,Ke,Qe,nt,qt,Wt,Kt,Qt,un,In,Gn,qn,{hierholzer:function(e){if(!S(e)){var t=arguments;e={root:t[0],directed:t[1]}}var n,r,i,a=Hn(e),o=a.root,s=a.directed,l=this,u=!1;o&&(i=A(o)?this.filter(o)[0].id():o[0].id());var c={},h={};s?l.forEach((function(e){var t=e.id();if(e.isNode()){var i=e.indegree(!0),a=e.outdegree(!0),o=i-a,s=a-i;1==o?n?u=!0:n=t:1==s?r?u=!0:r=t:(s>1||o>1)&&(u=!0),c[t]=[],e.outgoers().forEach((function(e){e.isEdge()&&c[t].push(e.id())}))}else h[t]=[void 0,e.target().id()]})):l.forEach((function(e){var t=e.id();e.isNode()?(e.degree(!0)%2&&(n?r?u=!0:r=t:n=t),c[t]=[],e.connectedEdges().forEach((function(e){return c[t].push(e.id())}))):h[t]=[e.source().id(),e.target().id()]}));var d={found:!1,trail:void 0};if(u)return d;if(r&&n)if(s){if(i&&r!=i)return d;i=r}else{if(i&&r!=i&&n!=i)return d;i||(i=r)}else i||(i=l[0].id());var p=function(e){for(var t,n,r,i=e,a=[e];c[i].length;)t=c[i].shift(),n=h[t][0],i!=(r=h[t][1])?(c[r]=c[r].filter((function(e){return e!=t})),i=r):s||i==n||(c[n]=c[n].filter((function(e){return e!=t})),i=n),a.unshift(t),a.unshift(i);return a},g=[],f=[];for(f=p(i);1!=f.length;)0==c[f[0]].length?(g.unshift(l.getElementById(f.shift())),g.unshift(l.getElementById(f.shift()))):f=p(f.shift()).concat(f);for(var v in g.unshift(l.getElementById(f.shift())),c)if(c[v].length)return d;return d.found=!0,d.trail=this.spawn(g,!0),d}},{hopcroftTarjanBiconnected:Wn,htbc:Wn,htb:Wn,hopcroftTarjanBiconnectedComponents:Wn},{tarjanStronglyConnected:$n,tsc:$n,tscc:$n,tarjanStronglyConnectedComponents:$n}].forEach((function(e){Q(Kn,e)}));var Zn=function e(t){if(!(this instanceof e))return new e(t);this.id="Thenable/1.0.7",this.state=0,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},"function"==typeof t&&t.call(this,this.fulfill.bind(this),this.reject.bind(this))};Zn.prototype={fulfill:function(e){return Qn(this,1,"fulfillValue",e)},reject:function(e){return Qn(this,2,"rejectReason",e)},then:function(e,t){var n=this,r=new Zn;return n.onFulfilled.push(tr(e,r,"fulfill")),n.onRejected.push(tr(t,r,"reject")),Jn(n),r.proxy}};var Qn=function(e,t,n,r){return 0===e.state&&(e.state=t,e[n]=r,Jn(e)),e},Jn=function(e){1===e.state?er(e,"onFulfilled",e.fulfillValue):2===e.state&&er(e,"onRejected",e.rejectReason)},er=function(e,t,n){if(0!==e[t].length){var r=e[t];e[t]=[];var i=function(){for(var e=0;e<r.length;e++)r[e](n)};"function"==typeof setImmediate?setImmediate(i):setTimeout(i,0)}},tr=function(e,t,n){return function(r){if("function"!=typeof e)t[n].call(t,r);else{var i;try{i=e(r)}catch(a){return void t.reject(a)}nr(t,i)}}},nr=function e(t,n){if(t!==n&&t.proxy!==n){var r;if("object"===g(n)&&null!==n||"function"==typeof n)try{r=n.then}catch(a){return void t.reject(a)}if("function"!=typeof r)t.fulfill(n);else{var i=!1;try{r.call(n,(function(r){i||(i=!0,r===n?t.reject(new TypeError("circular thenable chain")):e(t,r))}),(function(e){i||(i=!0,t.reject(e))}))}catch(a){i||t.reject(a)}}}else t.reject(new TypeError("cannot resolve promise with itself"))};Zn.all=function(e){return new Zn((function(t,n){for(var r=new Array(e.length),i=0,a=function(n,a){r[n]=a,++i===e.length&&t(r)},o=0;o<e.length;o++)!function(t){var r=e[t];null!=r&&null!=r.then?r.then((function(e){a(t,e)}),(function(e){n(e)})):a(t,r)}(o)}))},Zn.resolve=function(e){return new Zn((function(t,n){t(e)}))},Zn.reject=function(e){return new Zn((function(t,n){n(e)}))};var rr="undefined"!=typeof Promise?Promise:Zn,ir=function(e,t,n){var r=B(e),i=!r,a=this._private=Q({duration:1e3},t,n);if(a.target=e,a.style=a.style||a.css,a.started=!1,a.playing=!1,a.hooked=!1,a.applying=!1,a.progress=0,a.completes=[],a.frames=[],a.complete&&L(a.complete)&&a.completes.push(a.complete),i){var o=e.position();a.startPosition=a.startPosition||{x:o.x,y:o.y},a.startStyle=a.startStyle||e.cy().style().getAnimationStartStyle(e,a.style)}if(r){var s=e.pan();a.startPan={x:s.x,y:s.y},a.startZoom=e.zoom()}this.length=1,this[0]=this},ar=ir.prototype;Q(ar,{instanceString:function(){return"animation"},hook:function(){var e=this._private;if(!e.hooked){var t=e.target._private.animation;(e.queue?t.queue:t.current).push(this),O(e.target)&&e.target.cy().addToAnimationPool(e.target),e.hooked=!0}return this},play:function(){var e=this._private;return 1===e.progress&&(e.progress=0),e.playing=!0,e.started=!1,e.stopped=!1,this.hook(),this},playing:function(){return this._private.playing},apply:function(){var e=this._private;return e.applying=!0,e.started=!1,e.stopped=!1,this.hook(),this},applying:function(){return this._private.applying},pause:function(){var e=this._private;return e.playing=!1,e.started=!1,this},stop:function(){var e=this._private;return e.playing=!1,e.started=!1,e.stopped=!0,this},rewind:function(){return this.progress(0)},fastforward:function(){return this.progress(1)},time:function(e){var t=this._private;return void 0===e?t.progress*t.duration:this.progress(e/t.duration)},progress:function(e){var t=this._private,n=t.playing;return void 0===e?t.progress:(n&&this.pause(),t.progress=e,t.started=!1,n&&this.play(),this)},completed:function(){return 1===this._private.progress},reverse:function(){var e=this._private,t=e.playing;t&&this.pause(),e.progress=1-e.progress,e.started=!1;var n=function(t,n){var r=e[t];null!=r&&(e[t]=e[n],e[n]=r)};if(n("zoom","startZoom"),n("pan","startPan"),n("position","startPosition"),e.style)for(var r=0;r<e.style.length;r++){var i=e.style[r],a=i.name,o=e.startStyle[a];e.startStyle[a]=i,e.style[r]=o}return t&&this.play(),this},promise:function(e){var t,n=this._private;if("frame"===e)t=n.frames;else t=n.completes;return new rr((function(e,n){t.push((function(){e()}))}))}}),ar.complete=ar.completed,ar.run=ar.play,ar.running=ar.playing;var or={animated:function(){return function(){var e=this,t=void 0!==e.length?e:[e];if(!(this._private.cy||this).styleEnabled())return!1;var n=t[0];return n?n._private.animation.current.length>0:void 0}},clearQueue:function(){return function(){var e=this,t=void 0!==e.length?e:[e];if(!(this._private.cy||this).styleEnabled())return this;for(var n=0;n<t.length;n++){t[n]._private.animation.queue=[]}return this}},delay:function(){return function(e,t){return(this._private.cy||this).styleEnabled()?this.animate({delay:e,duration:e,complete:t}):this}},delayAnimation:function(){return function(e,t){return(this._private.cy||this).styleEnabled()?this.animation({delay:e,duration:e,complete:t}):this}},animation:function(){return function(e,t){var n=this,r=void 0!==n.length,i=r?n:[n],a=this._private.cy||this,o=!r,s=!o;if(!a.styleEnabled())return this;var l=a.style();if(e=Q({},e,t),0===Object.keys(e).length)return new ir(i[0],e);switch(void 0===e.duration&&(e.duration=400),e.duration){case"slow":e.duration=600;break;case"fast":e.duration=200}if(s&&(e.style=l.getPropsList(e.style||e.css),e.css=void 0),s&&null!=e.renderedPosition){var u=e.renderedPosition,c=a.pan(),h=a.zoom();e.position=it(u,h,c)}if(o&&null!=e.panBy){var d=e.panBy,p=a.pan();e.pan={x:p.x+d.x,y:p.y+d.y}}var g=e.center||e.centre;if(o&&null!=g){var f=a.getCenterPan(g.eles,e.zoom);null!=f&&(e.pan=f)}if(o&&null!=e.fit){var v=e.fit,y=a.getFitViewport(v.eles||v.boundingBox,v.padding);null!=y&&(e.pan=y.pan,e.zoom=y.zoom)}if(o&&S(e.zoom)){var m=a.getZoomedViewport(e.zoom);null!=m?(m.zoomed&&(e.zoom=m.zoom),m.panned&&(e.pan=m.pan)):e.zoom=null}return new ir(i[0],e)}},animate:function(){return function(e,t){var n=this,r=void 0!==n.length?n:[n];if(!(this._private.cy||this).styleEnabled())return this;t&&(e=Q({},e,t));for(var i=0;i<r.length;i++){var a=r[i],o=a.animated()&&(void 0===e.queue||e.queue);a.animation(e,o?{queue:!0}:void 0).play()}return this}},stop:function(){return function(e,t){var n=this,r=void 0!==n.length?n:[n],i=this._private.cy||this;if(!i.styleEnabled())return this;for(var a=0;a<r.length;a++){for(var o=r[a]._private,s=o.animation.current,l=0;l<s.length;l++){var u=s[l]._private;t&&(u.duration=0)}e&&(o.animation.queue=[]),t||(o.animation.current=[])}return i.notify("draw"),this}}},sr={data:function(e){return e=Q({},{field:"data",bindingEvent:"data",allowBinding:!1,allowSetting:!1,allowGetting:!1,settingEvent:"data",settingTriggersEvent:!1,triggerFnName:"trigger",immutableKeys:{},updateStyle:!1,beforeGet:function(e){},beforeSet:function(e,t){},onSet:function(e){},canSet:function(e){return!0}},e),function(t,n){var r=e,i=this,a=void 0!==i.length,o=a?i:[i],s=a?i[0]:i;if(A(t)){var l,u=-1!==t.indexOf(".")&&p.default(t);if(r.allowGetting&&void 0===n)return s&&(r.beforeGet(s),l=u&&void 0===s._private[r.field][t]?h.default(s._private[r.field],u):s._private[r.field][t]),l;if(r.allowSetting&&void 0!==n&&!r.immutableKeys[t]){var c=m({},t,n);r.beforeSet(i,c);for(var g=0,f=o.length;g<f;g++){var v=o[g];r.canSet(v)&&(u&&void 0===s._private[r.field][t]?d.default(v._private[r.field],u,n):v._private[r.field][t]=n)}r.updateStyle&&i.updateStyle(),r.onSet(i),r.settingTriggersEvent&&i[r.triggerFnName](r.settingEvent)}}else if(r.allowSetting&&S(t)){var y,b,x=t,w=Object.keys(x);r.beforeSet(i,x);for(var E=0;E<w.length;E++){if(b=x[y=w[E]],!r.immutableKeys[y])for(var _=0;_<o.length;_++){var T=o[_];r.canSet(T)&&(T._private[r.field][y]=b)}}r.updateStyle&&i.updateStyle(),r.onSet(i),r.settingTriggersEvent&&i[r.triggerFnName](r.settingEvent)}else if(r.allowBinding&&L(t)){var D=t;i.on(r.bindingEvent,D)}else if(r.allowGetting&&void 0===t){var C;return s&&(r.beforeGet(s),C=s._private[r.field]),C}return i}},removeData:function(e){return e=Q({},{field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!1,immutableKeys:{}},e),function(t){var n=e,r=this,i=void 0!==r.length?r:[r];if(A(t)){for(var a=t.split(/\s+/),o=a.length,s=0;s<o;s++){var l=a[s];if(!z(l))if(!n.immutableKeys[l])for(var u=0,c=i.length;u<c;u++)i[u]._private[n.field][l]=void 0}n.triggerEvent&&r[n.triggerFnName](n.event)}else if(void 0===t){for(var h=0,d=i.length;h<d;h++)for(var p=i[h]._private[n.field],g=Object.keys(p),f=0;f<g.length;f++){var v=g[f];!n.immutableKeys[v]&&(p[v]=void 0)}n.triggerEvent&&r[n.triggerFnName](n.event)}return r}}},lr={eventAliasesOn:function(e){var t=e;t.addListener=t.listen=t.bind=t.on,t.unlisten=t.unbind=t.off=t.removeListener,t.trigger=t.emit,t.pon=t.promiseOn=function(e,t){var n=this,r=Array.prototype.slice.call(arguments,0);return new rr((function(e,t){var i=r.concat([function(t){n.off.apply(n,a),e(t)}]),a=i.concat([]);n.on.apply(n,i)}))}}},ur={};[or,sr,lr].forEach((function(e){Q(ur,e)}));var cr={animate:ur.animate(),animation:ur.animation(),animated:ur.animated(),clearQueue:ur.clearQueue(),delay:ur.delay(),delayAnimation:ur.delayAnimation(),stop:ur.stop()},hr={classes:function(e){var t=this;if(void 0===e){var n=[];return t[0]._private.classes.forEach((function(e){return n.push(e)})),n}k(e)||(e=(e||"").match(/\S+/g)||[]);for(var r=[],i=new Ge(e),a=0;a<t.length;a++){for(var o=t[a],s=o._private,l=s.classes,u=!1,c=0;c<e.length;c++){var h=e[c];if(!l.has(h)){u=!0;break}}u||(u=l.size!==e.length),u&&(s.classes=i,r.push(o))}return r.length>0&&this.spawn(r).updateStyle().emit("class"),t},addClass:function(e){return this.toggleClass(e,!0)},hasClass:function(e){var t=this[0];return null!=t&&t._private.classes.has(e)},toggleClass:function(e,t){k(e)||(e=e.match(/\S+/g)||[]);for(var n=this,r=void 0===t,i=[],a=0,o=n.length;a<o;a++)for(var s=n[a],l=s._private.classes,u=!1,c=0;c<e.length;c++){var h=e[c],d=l.has(h),p=!1;t||r&&!d?(l.add(h),p=!0):(!t||r&&d)&&(l.delete(h),p=!0),!u&&p&&(i.push(s),u=!0)}return i.length>0&&this.spawn(i).updateStyle().emit("class"),n},removeClass:function(e){return this.toggleClass(e,!1)},flashClass:function(e,t){var n=this;if(null==t)t=250;else if(0===t)return n;return n.addClass(e),setTimeout((function(){n.removeClass(e)}),t),n}};hr.className=hr.classNames=hr.classes;var dr={metaChar:"[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",comparatorOp:"=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",boolOp:"\\?|\\!|\\^",string:"\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*'",number:q,meta:"degree|indegree|outdegree",separator:"\\s*,\\s*",descendant:"\\s+",child:"\\s+>\\s+",subject:"\\$",group:"node|edge|\\*",directedEdge:"\\s+->\\s+",undirectedEdge:"\\s+<->\\s+"};dr.variable="(?:[\\w-.]|(?:\\\\"+dr.metaChar+"))+",dr.className="(?:[\\w-]|(?:\\\\"+dr.metaChar+"))+",dr.value=dr.string+"|"+dr.number,dr.id=dr.variable,function(){var e,t,n;for(e=dr.comparatorOp.split("|"),n=0;n<e.length;n++)t=e[n],dr.comparatorOp+="|@"+t;for(e=dr.comparatorOp.split("|"),n=0;n<e.length;n++)(t=e[n]).indexOf("!")>=0||"="!==t&&(dr.comparatorOp+="|\\!"+t)}();var pr=0,gr=1,fr=2,vr=3,yr=4,mr=5,br=6,xr=7,wr=8,Er=9,_r=10,Tr=11,Dr=12,Cr=13,Nr=14,Ar=15,Lr=16,kr=17,Sr=18,Ir=19,Mr=20,Or=[{selector:":selected",matches:function(e){return e.selected()}},{selector:":unselected",matches:function(e){return!e.selected()}},{selector:":selectable",matches:function(e){return e.selectable()}},{selector:":unselectable",matches:function(e){return!e.selectable()}},{selector:":locked",matches:function(e){return e.locked()}},{selector:":unlocked",matches:function(e){return!e.locked()}},{selector:":visible",matches:function(e){return e.visible()}},{selector:":hidden",matches:function(e){return!e.visible()}},{selector:":transparent",matches:function(e){return e.transparent()}},{selector:":grabbed",matches:function(e){return e.grabbed()}},{selector:":free",matches:function(e){return!e.grabbed()}},{selector:":removed",matches:function(e){return e.removed()}},{selector:":inside",matches:function(e){return!e.removed()}},{selector:":grabbable",matches:function(e){return e.grabbable()}},{selector:":ungrabbable",matches:function(e){return!e.grabbable()}},{selector:":animated",matches:function(e){return e.animated()}},{selector:":unanimated",matches:function(e){return!e.animated()}},{selector:":parent",matches:function(e){return e.isParent()}},{selector:":childless",matches:function(e){return e.isChildless()}},{selector:":child",matches:function(e){return e.isChild()}},{selector:":orphan",matches:function(e){return e.isOrphan()}},{selector:":nonorphan",matches:function(e){return e.isChild()}},{selector:":compound",matches:function(e){return e.isNode()?e.isParent():e.source().isParent()||e.target().isParent()}},{selector:":loop",matches:function(e){return e.isLoop()}},{selector:":simple",matches:function(e){return e.isSimple()}},{selector:":active",matches:function(e){return e.active()}},{selector:":inactive",matches:function(e){return!e.active()}},{selector:":backgrounding",matches:function(e){return e.backgrounding()}},{selector:":nonbackgrounding",matches:function(e){return!e.backgrounding()}}].sort((function(e,t){return function(e,t){return-1*Z(e,t)}(e.selector,t.selector)})),Pr=function(){for(var e,t={},n=0;n<Or.length;n++)t[(e=Or[n]).selector]=e.matches;return t}(),Rr="("+Or.map((function(e){return e.selector})).join("|")+")",Br=function(e){return e.replace(new RegExp("\\\\("+dr.metaChar+")","g"),(function(e,t){return t}))},Fr=function(e,t,n){e[e.length-1]=n},zr=[{name:"group",query:!0,regex:"("+dr.group+")",populate:function(e,t,n){var r=b(n,1)[0];t.checks.push({type:pr,value:"*"===r?r:r+"s"})}},{name:"state",query:!0,regex:Rr,populate:function(e,t,n){var r=b(n,1)[0];t.checks.push({type:xr,value:r})}},{name:"id",query:!0,regex:"\\#("+dr.id+")",populate:function(e,t,n){var r=b(n,1)[0];t.checks.push({type:wr,value:Br(r)})}},{name:"className",query:!0,regex:"\\.("+dr.className+")",populate:function(e,t,n){var r=b(n,1)[0];t.checks.push({type:Er,value:Br(r)})}},{name:"dataExists",query:!0,regex:"\\[\\s*("+dr.variable+")\\s*\\]",populate:function(e,t,n){var r=b(n,1)[0];t.checks.push({type:yr,field:Br(r)})}},{name:"dataCompare",query:!0,regex:"\\[\\s*("+dr.variable+")\\s*("+dr.comparatorOp+")\\s*("+dr.value+")\\s*\\]",populate:function(e,t,n){var r=b(n,3),i=r[0],a=r[1],o=r[2];o=null!=new RegExp("^"+dr.string+"$").exec(o)?o.substring(1,o.length-1):parseFloat(o),t.checks.push({type:vr,field:Br(i),operator:a,value:o})}},{name:"dataBool",query:!0,regex:"\\[\\s*("+dr.boolOp+")\\s*("+dr.variable+")\\s*\\]",populate:function(e,t,n){var r=b(n,2),i=r[0],a=r[1];t.checks.push({type:mr,field:Br(a),operator:i})}},{name:"metaCompare",query:!0,regex:"\\[\\[\\s*("+dr.meta+")\\s*("+dr.comparatorOp+")\\s*("+dr.number+")\\s*\\]\\]",populate:function(e,t,n){var r=b(n,3),i=r[0],a=r[1],o=r[2];t.checks.push({type:br,field:Br(i),operator:a,value:parseFloat(o)})}},{name:"nextQuery",separator:!0,regex:dr.separator,populate:function(e,t){var n=e.currentSubject,r=e.edgeCount,i=e.compoundCount,a=e[e.length-1];return null!=n&&(a.subject=n,e.currentSubject=null),a.edgeCount=r,a.compoundCount=i,e.edgeCount=0,e.compoundCount=0,e[e.length++]={checks:[]}}},{name:"directedEdge",separator:!0,regex:dr.directedEdge,populate:function(e,t){if(null==e.currentSubject){var n={checks:[]},r=t,i={checks:[]};return n.checks.push({type:Tr,source:r,target:i}),Fr(e,0,n),e.edgeCount++,i}var a={checks:[]},o=t,s={checks:[]};return a.checks.push({type:Dr,source:o,target:s}),Fr(e,0,a),e.edgeCount++,s}},{name:"undirectedEdge",separator:!0,regex:dr.undirectedEdge,populate:function(e,t){if(null==e.currentSubject){var n={checks:[]},r=t,i={checks:[]};return n.checks.push({type:_r,nodes:[r,i]}),Fr(e,0,n),e.edgeCount++,i}var a={checks:[]},o=t,s={checks:[]};return a.checks.push({type:Nr,node:o,neighbor:s}),Fr(e,0,a),s}},{name:"child",separator:!0,regex:dr.child,populate:function(e,t){if(null==e.currentSubject){var n={checks:[]},r={checks:[]},i=e[e.length-1];return n.checks.push({type:Ar,parent:i,child:r}),Fr(e,0,n),e.compoundCount++,r}if(e.currentSubject===t){var a={checks:[]},o=e[e.length-1],s={checks:[]},l={checks:[]},u={checks:[]},c={checks:[]};return a.checks.push({type:Ir,left:o,right:s,subject:l}),l.checks=t.checks,t.checks=[{type:Mr}],c.checks.push({type:Mr}),s.checks.push({type:kr,parent:c,child:u}),Fr(e,0,a),e.currentSubject=l,e.compoundCount++,u}var h={checks:[]},d={checks:[]},p=[{type:kr,parent:h,child:d}];return h.checks=t.checks,t.checks=p,e.compoundCount++,d}},{name:"descendant",separator:!0,regex:dr.descendant,populate:function(e,t){if(null==e.currentSubject){var n={checks:[]},r={checks:[]},i=e[e.length-1];return n.checks.push({type:Lr,ancestor:i,descendant:r}),Fr(e,0,n),e.compoundCount++,r}if(e.currentSubject===t){var a={checks:[]},o=e[e.length-1],s={checks:[]},l={checks:[]},u={checks:[]},c={checks:[]};return a.checks.push({type:Ir,left:o,right:s,subject:l}),l.checks=t.checks,t.checks=[{type:Mr}],c.checks.push({type:Mr}),s.checks.push({type:Sr,ancestor:c,descendant:u}),Fr(e,0,a),e.currentSubject=l,e.compoundCount++,u}var h={checks:[]},d={checks:[]},p=[{type:Sr,ancestor:h,descendant:d}];return h.checks=t.checks,t.checks=p,e.compoundCount++,d}},{name:"subject",modifier:!0,regex:dr.subject,populate:function(e,t){if(null!=e.currentSubject&&e.currentSubject!==t)return Ae("Redefinition of subject in selector `"+e.toString()+"`"),!1;e.currentSubject=t;var n=e[e.length-1].checks[0],r=null==n?null:n.type;r===Tr?n.type=Cr:r===_r&&(n.type=Nr,n.node=n.nodes[1],n.neighbor=n.nodes[0],n.nodes=null)}}];zr.forEach((function(e){return e.regexObj=new RegExp("^"+e.regex)}));var Gr=function(e){for(var t,n,r,i=0;i<zr.length;i++){var a=zr[i],o=a.name,s=e.match(a.regexObj);if(null!=s){n=s,t=a,r=o;var l=s[0];e=e.substring(l.length);break}}return{expr:t,match:n,name:r,remaining:e}},Yr={parse:function(e){var t=this,n=t.inputText=e,r=t[0]={checks:[]};for(t.length=1,n=function(e){var t=e.match(/^\s+/);if(t){var n=t[0];e=e.substring(n.length)}return e}(n);;){var i=Gr(n);if(null==i.expr)return Ae("The selector `"+e+"`is invalid"),!1;var a=i.match.slice(1),o=i.expr.populate(t,r,a);if(!1===o)return!1;if(null!=o&&(r=o),(n=i.remaining).match(/^\s*$/))break}var s=t[t.length-1];null!=t.currentSubject&&(s.subject=t.currentSubject),s.edgeCount=t.edgeCount,s.compoundCount=t.compoundCount;for(var l=0;l<t.length;l++){var u=t[l];if(u.compoundCount>0&&u.edgeCount>0)return Ae("The selector `"+e+"` is invalid because it uses both a compound selector and an edge selector"),!1;if(u.edgeCount>1)return Ae("The selector `"+e+"` is invalid because it uses multiple edge selectors"),!1;1===u.edgeCount&&Ae("The selector `"+e+"` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.")}return!0},toString:function(){if(null!=this.toStringCache)return this.toStringCache;for(var e=function(e){return null==e?"":e},t=function(t){return A(t)?'"'+t+'"':e(t)},n=function(e){return" "+e+" "},r=function(r,a){var o=r.type,s=r.value;switch(o){case pr:var l=e(s);return l.substring(0,l.length-1);case vr:var u=r.field,c=r.operator;return"["+u+n(e(c))+t(s)+"]";case mr:var h=r.operator,d=r.field;return"["+e(h)+d+"]";case yr:return"["+r.field+"]";case br:var p=r.operator;return"[["+r.field+n(e(p))+t(s)+"]]";case xr:return s;case wr:return"#"+s;case Er:return"."+s;case kr:case Ar:return i(r.parent,a)+n(">")+i(r.child,a);case Sr:case Lr:return i(r.ancestor,a)+" "+i(r.descendant,a);case Ir:var g=i(r.left,a),f=i(r.subject,a),v=i(r.right,a);return g+(g.length>0?" ":"")+f+v;case Mr:return""}},i=function(e,t){return e.checks.reduce((function(n,i,a){return n+(t===e&&0===a?"$":"")+r(i,t)}),"")},a="",o=0;o<this.length;o++){var s=this[o];a+=i(s,s.subject),this.length>1&&o<this.length-1&&(a+=", ")}return this.toStringCache=a,a}},Xr=function(e,t,n){var r,i,a,o=A(e),s=I(e),l=A(n),u=!1,c=!1,h=!1;switch(t.indexOf("!")>=0&&(t=t.replace("!",""),c=!0),t.indexOf("@")>=0&&(t=t.replace("@",""),u=!0),(o||l||u)&&(i=o||s?""+e:"",a=""+n),u&&(e=i=i.toLowerCase(),n=a=a.toLowerCase()),t){case"*=":r=i.indexOf(a)>=0;break;case"$=":r=i.indexOf(a,i.length-a.length)>=0;break;case"^=":r=0===i.indexOf(a);break;case"=":r=e===n;break;case">":h=!0,r=e>n;break;case">=":h=!0,r=e>=n;break;case"<":h=!0,r=e<n;break;case"<=":h=!0,r=e<=n;break;default:r=!1}return!c||null==e&&h||(r=!r),r},Vr=function(e,t){return e.data(t)},Ur=[],jr=function(e,t){return e.checks.every((function(e){return Ur[e.type](e,t)}))};Ur[pr]=function(e,t){var n=e.value;return"*"===n||n===t.group()},Ur[xr]=function(e,t){return function(e,t){return Pr[e](t)}(e.value,t)},Ur[wr]=function(e,t){var n=e.value;return t.id()===n},Ur[Er]=function(e,t){var n=e.value;return t.hasClass(n)},Ur[br]=function(e,t){var n=e.field,r=e.operator,i=e.value;return Xr(function(e,t){return e[t]()}(t,n),r,i)},Ur[vr]=function(e,t){var n=e.field,r=e.operator,i=e.value;return Xr(Vr(t,n),r,i)},Ur[mr]=function(e,t){var n=e.field,r=e.operator;return function(e,t){switch(t){case"?":return!!e;case"!":return!e;case"^":return void 0===e}}(Vr(t,n),r)},Ur[yr]=function(e,t){var n=e.field;return e.operator,void 0!==Vr(t,n)},Ur[_r]=function(e,t){var n=e.nodes[0],r=e.nodes[1],i=t.source(),a=t.target();return jr(n,i)&&jr(r,a)||jr(r,i)&&jr(n,a)},Ur[Nr]=function(e,t){return jr(e.node,t)&&t.neighborhood().some((function(t){return t.isNode()&&jr(e.neighbor,t)}))},Ur[Tr]=function(e,t){return jr(e.source,t.source())&&jr(e.target,t.target())},Ur[Dr]=function(e,t){return jr(e.source,t)&&t.outgoers().some((function(t){return t.isNode()&&jr(e.target,t)}))},Ur[Cr]=function(e,t){return jr(e.target,t)&&t.incomers().some((function(t){return t.isNode()&&jr(e.source,t)}))},Ur[Ar]=function(e,t){return jr(e.child,t)&&jr(e.parent,t.parent())},Ur[kr]=function(e,t){return jr(e.parent,t)&&t.children().some((function(t){return jr(e.child,t)}))},Ur[Lr]=function(e,t){return jr(e.descendant,t)&&t.ancestors().some((function(t){return jr(e.ancestor,t)}))},Ur[Sr]=function(e,t){return jr(e.ancestor,t)&&t.descendants().some((function(t){return jr(e.descendant,t)}))},Ur[Ir]=function(e,t){return jr(e.subject,t)&&jr(e.left,t)&&jr(e.right,t)},Ur[Mr]=function(){return!0},Ur[gr]=function(e,t){return e.value.has(t)},Ur[fr]=function(e,t){return(0,e.value)(t)};var qr={matches:function(e){for(var t=0;t<this.length;t++){var n=this[t];if(jr(n,e))return!0}return!1},filter:function(e){var t=this;if(1===t.length&&1===t[0].checks.length&&t[0].checks[0].type===wr)return e.getElementById(t[0].checks[0].value).collection();var n=function(e){for(var n=0;n<t.length;n++){var r=t[n];if(jr(r,e))return!0}return!1};return null==t.text()&&(n=function(){return!0}),e.filter(n)}},Hr=function(e){this.inputText=e,this.currentSubject=null,this.compoundCount=0,this.edgeCount=0,this.length=0,null==e||A(e)&&e.match(/^\s*$/)||(O(e)?this.addQuery({checks:[{type:gr,value:e.collection()}]}):L(e)?this.addQuery({checks:[{type:fr,value:e}]}):A(e)?this.parse(e)||(this.invalid=!0):Ce("A selector must be created from a string; found "))},Wr=Hr.prototype;[Yr,qr].forEach((function(e){return Q(Wr,e)})),Wr.text=function(){return this.inputText},Wr.size=function(){return this.length},Wr.eq=function(e){return this[e]},Wr.sameText=function(e){return!this.invalid&&!e.invalid&&this.text()===e.text()},Wr.addQuery=function(e){this[this.length++]=e},Wr.selector=Wr.toString;var $r={allAre:function(e){var t=new Hr(e);return this.every((function(e){return t.matches(e)}))},is:function(e){var t=new Hr(e);return this.some((function(e){return t.matches(e)}))},some:function(e,t){for(var n=0;n<this.length;n++){if(t?e.apply(t,[this[n],n,this]):e(this[n],n,this))return!0}return!1},every:function(e,t){for(var n=0;n<this.length;n++){if(!(t?e.apply(t,[this[n],n,this]):e(this[n],n,this)))return!1}return!0},same:function(e){if(this===e)return!0;e=this.cy().collection(e);var t=this.length;return t===e.length&&(1===t?this[0]===e[0]:this.every((function(t){return e.hasElementWithId(t.id())})))},anySame:function(e){return e=this.cy().collection(e),this.some((function(t){return e.hasElementWithId(t.id())}))},allAreNeighbors:function(e){e=this.cy().collection(e);var t=this.neighborhood();return e.every((function(e){return t.hasElementWithId(e.id())}))},contains:function(e){e=this.cy().collection(e);var t=this;return e.every((function(e){return t.hasElementWithId(e.id())}))}};$r.allAreNeighbours=$r.allAreNeighbors,$r.has=$r.contains,$r.equal=$r.equals=$r.same;var Kr,Zr,Qr=function(e,t){return function(n,r,i,a){var o,s=n,l=this;if(null==s?o="":O(s)&&1===s.length&&(o=s.id()),1===l.length&&o){var u=l[0]._private,c=u.traversalCache=u.traversalCache||{},h=c[t]=c[t]||[],d=fe(o),p=h[d];return p||(h[d]=e.call(l,n,r,i,a))}return e.call(l,n,r,i,a)}},Jr={parent:function(e){var t=[];if(1===this.length){var n=this[0]._private.parent;if(n)return n}for(var r=0;r<this.length;r++){var i=this[r]._private.parent;i&&t.push(i)}return this.spawn(t,!0).filter(e)},parents:function(e){for(var t=[],n=this.parent();n.nonempty();){for(var r=0;r<n.length;r++){var i=n[r];t.push(i)}n=n.parent()}return this.spawn(t,!0).filter(e)},commonAncestors:function(e){for(var t,n=0;n<this.length;n++){var r=this[n].parents();t=(t=t||r).intersect(r)}return t.filter(e)},orphans:function(e){return this.stdFilter((function(e){return e.isOrphan()})).filter(e)},nonorphans:function(e){return this.stdFilter((function(e){return e.isChild()})).filter(e)},children:Qr((function(e){for(var t=[],n=0;n<this.length;n++)for(var r=this[n]._private.children,i=0;i<r.length;i++)t.push(r[i]);return this.spawn(t,!0).filter(e)}),"children"),siblings:function(e){return this.parent().children().not(this).filter(e)},isParent:function(){var e=this[0];if(e)return e.isNode()&&0!==e._private.children.length},isChildless:function(){var e=this[0];if(e)return e.isNode()&&0===e._private.children.length},isChild:function(){var e=this[0];if(e)return e.isNode()&&null!=e._private.parent},isOrphan:function(){var e=this[0];if(e)return e.isNode()&&null==e._private.parent},descendants:function(e){var t=[];return function e(n){for(var r=0;r<n.length;r++){var i=n[r];t.push(i),i.children().nonempty()&&e(i.children())}}(this.children()),this.spawn(t,!0).filter(e)}};function ei(e,t,n,r){for(var i=[],a=new Ge,o=e.cy().hasCompoundNodes(),s=0;s<e.length;s++){var l=e[s];n?i.push(l):o&&r(i,a,l)}for(;i.length>0;){var u=i.shift();t(u),a.add(u.id()),o&&r(i,a,u)}return e}function ti(e,t,n){if(n.isParent())for(var r=n._private.children,i=0;i<r.length;i++){var a=r[i];t.has(a.id())||e.push(a)}}function ni(e,t,n){if(n.isChild()){var r=n._private.parent;t.has(r.id())||e.push(r)}}function ri(e,t,n){ni(e,t,n),ti(e,t,n)}Jr.forEachDown=function(e){return ei(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],ti)},Jr.forEachUp=function(e){return ei(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],ni)},Jr.forEachUpAndDown=function(e){return ei(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],ri)},Jr.ancestors=Jr.parents,(Kr=Zr={data:ur.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),removeData:ur.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),scratch:ur.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:ur.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),rscratch:ur.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:ur.removeData({field:"rscratch",triggerEvent:!1}),id:function(){var e=this[0];if(e)return e._private.data.id}}).attr=Kr.data,Kr.removeAttr=Kr.removeData;var ii,ai,oi=Zr,si={};function li(e){return function(t){var n=this;if(void 0===t&&(t=!0),0!==n.length&&n.isNode()&&!n.removed()){for(var r=0,i=n[0],a=i._private.edges,o=0;o<a.length;o++){var s=a[o];!t&&s.isLoop()||(r+=e(i,s))}return r}}}function ui(e,t){return function(n){for(var r,i=this.nodes(),a=0;a<i.length;a++){var o=i[a][e](n);void 0===o||void 0!==r&&!t(o,r)||(r=o)}return r}}Q(si,{degree:li((function(e,t){return t.source().same(t.target())?2:1})),indegree:li((function(e,t){return t.target().same(e)?1:0})),outdegree:li((function(e,t){return t.source().same(e)?1:0}))}),Q(si,{minDegree:ui("degree",(function(e,t){return e<t})),maxDegree:ui("degree",(function(e,t){return e>t})),minIndegree:ui("indegree",(function(e,t){return e<t})),maxIndegree:ui("indegree",(function(e,t){return e>t})),minOutdegree:ui("outdegree",(function(e,t){return e<t})),maxOutdegree:ui("outdegree",(function(e,t){return e>t}))}),Q(si,{totalDegree:function(e){for(var t=0,n=this.nodes(),r=0;r<n.length;r++)t+=n[r].degree(e);return t}});var ci=function(e,t,n){for(var r=0;r<e.length;r++){var i=e[r];if(!i.locked()){var a=i._private.position,o={x:null!=t.x?t.x-a.x:0,y:null!=t.y?t.y-a.y:0};!i.isParent()||0===o.x&&0===o.y||i.children().shift(o,n),i.dirtyBoundingBoxCache()}}},hi={field:"position",bindingEvent:"position",allowBinding:!0,allowSetting:!0,settingEvent:"position",settingTriggersEvent:!0,triggerFnName:"emitAndNotify",allowGetting:!0,validKeys:["x","y"],beforeGet:function(e){e.updateCompoundBounds()},beforeSet:function(e,t){ci(e,t,!1)},onSet:function(e){e.dirtyCompoundBoundsCache()},canSet:function(e){return!e.locked()}};ii=ai={position:ur.data(hi),silentPosition:ur.data(Q({},hi,{allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!1,beforeSet:function(e,t){ci(e,t,!0)},onSet:function(e){e.dirtyCompoundBoundsCache()}})),positions:function(e,t){if(S(e))t?this.silentPosition(e):this.position(e);else if(L(e)){var n=e,r=this.cy();r.startBatch();for(var i=0;i<this.length;i++){var a,o=this[i];(a=n(o,i))&&(t?o.silentPosition(a):o.position(a))}r.endBatch()}return this},silentPositions:function(e){return this.positions(e,!0)},shift:function(e,t,n){var r;if(S(e)?(r={x:I(e.x)?e.x:0,y:I(e.y)?e.y:0},n=t):A(e)&&I(t)&&((r={x:0,y:0})[e]=t),null!=r){var i=this.cy();i.startBatch();for(var a=0;a<this.length;a++){var o=this[a];if(!(i.hasCompoundNodes()&&o.isChild()&&o.ancestors().anySame(this))){var s=o.position(),l={x:s.x+r.x,y:s.y+r.y};n?o.silentPosition(l):o.position(l)}}i.endBatch()}return this},silentShift:function(e,t){return S(e)?this.shift(e,!0):A(e)&&I(t)&&this.shift(e,t,!0),this},renderedPosition:function(e,t){var n=this[0],r=this.cy(),i=r.zoom(),a=r.pan(),o=S(e)?e:void 0,s=void 0!==o||void 0!==t&&A(e);if(n&&n.isNode()){if(!s){var l=n.position();return o=rt(l,i,a),void 0===e?o:o[e]}for(var u=0;u<this.length;u++){var c=this[u];void 0!==t?c.position(e,(t-a[e])/i):void 0!==o&&c.position(it(o,i,a))}}else if(!s)return;return this},relativePosition:function(e,t){var n=this[0],r=this.cy(),i=S(e)?e:void 0,a=void 0!==i||void 0!==t&&A(e),o=r.hasCompoundNodes();if(n&&n.isNode()){if(!a){var s=n.position(),l=o?n.parent():null,u=l&&l.length>0,c=u;u&&(l=l[0]);var h=c?l.position():{x:0,y:0};return i={x:s.x-h.x,y:s.y-h.y},void 0===e?i:i[e]}for(var d=0;d<this.length;d++){var p=this[d],g=o?p.parent():null,f=g&&g.length>0,v=f;f&&(g=g[0]);var y=v?g.position():{x:0,y:0};void 0!==t?p.position(e,t+y[e]):void 0!==i&&p.position({x:i.x+y.x,y:i.y+y.y})}}else if(!a)return;return this}},ii.modelPosition=ii.point=ii.position,ii.modelPositions=ii.points=ii.positions,ii.renderedPoint=ii.renderedPosition,ii.relativePoint=ii.relativePosition;var di,pi,gi=ai;di=pi={},pi.renderedBoundingBox=function(e){var t=this.boundingBox(e),n=this.cy(),r=n.zoom(),i=n.pan(),a=t.x1*r+i.x,o=t.x2*r+i.x,s=t.y1*r+i.y,l=t.y2*r+i.y;return{x1:a,x2:o,y1:s,y2:l,w:o-a,h:l-s}},pi.dirtyCompoundBoundsCache=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();return t.styleEnabled()&&t.hasCompoundNodes()?(this.forEachUp((function(t){if(t.isParent()){var n=t._private;n.compoundBoundsClean=!1,n.bbCache=null,e||t.emitAndNotify("bounds")}})),this):this},pi.updateCompoundBounds=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();if(!t.styleEnabled()||!t.hasCompoundNodes())return this;if(!e&&t.batching())return this;function n(e){if(e.isParent()){var t=e._private,n=e.children(),r="include"===e.pstyle("compound-sizing-wrt-labels").value,i={width:{val:e.pstyle("min-width").pfValue,left:e.pstyle("min-width-bias-left"),right:e.pstyle("min-width-bias-right")},height:{val:e.pstyle("min-height").pfValue,top:e.pstyle("min-height-bias-top"),bottom:e.pstyle("min-height-bias-bottom")}},a=n.boundingBox({includeLabels:r,includeOverlays:!1,useCache:!1}),o=t.position;0!==a.w&&0!==a.h||((a={w:e.pstyle("width").pfValue,h:e.pstyle("height").pfValue}).x1=o.x-a.w/2,a.x2=o.x+a.w/2,a.y1=o.y-a.h/2,a.y2=o.y+a.h/2);var s=i.width.left.value;"px"===i.width.left.units&&i.width.val>0&&(s=100*s/i.width.val);var l=i.width.right.value;"px"===i.width.right.units&&i.width.val>0&&(l=100*l/i.width.val);var u=i.height.top.value;"px"===i.height.top.units&&i.height.val>0&&(u=100*u/i.height.val);var c=i.height.bottom.value;"px"===i.height.bottom.units&&i.height.val>0&&(c=100*c/i.height.val);var h=y(i.width.val-a.w,s,l),d=h.biasDiff,p=h.biasComplementDiff,g=y(i.height.val-a.h,u,c),f=g.biasDiff,v=g.biasComplementDiff;t.autoPadding=function(e,t,n,r){if("%"!==n.units)return"px"===n.units?n.pfValue:0;switch(r){case"width":return e>0?n.pfValue*e:0;case"height":return t>0?n.pfValue*t:0;case"average":return e>0&&t>0?n.pfValue*(e+t)/2:0;case"min":return e>0&&t>0?e>t?n.pfValue*t:n.pfValue*e:0;case"max":return e>0&&t>0?e>t?n.pfValue*e:n.pfValue*t:0;default:return 0}}(a.w,a.h,e.pstyle("padding"),e.pstyle("padding-relative-to").value),t.autoWidth=Math.max(a.w,i.width.val),o.x=(-d+a.x1+a.x2+p)/2,t.autoHeight=Math.max(a.h,i.height.val),o.y=(-f+a.y1+a.y2+v)/2}function y(e,t,n){var r=0,i=0,a=t+n;return e>0&&a>0&&(r=t/a*e,i=n/a*e),{biasDiff:r,biasComplementDiff:i}}}for(var r=0;r<this.length;r++){var i=this[r],a=i._private;a.compoundBoundsClean&&!e||(n(i),t.batching()||(a.compoundBoundsClean=!0))}return this};var fi=function(e){return e===1/0||e===-1/0?0:e},vi=function(e,t,n,r,i){r-t!=0&&i-n!=0&&null!=t&&null!=n&&null!=r&&null!=i&&(e.x1=t<e.x1?t:e.x1,e.x2=r>e.x2?r:e.x2,e.y1=n<e.y1?n:e.y1,e.y2=i>e.y2?i:e.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1)},yi=function(e,t){return null==t?e:vi(e,t.x1,t.y1,t.x2,t.y2)},mi=function(e,t,n){return Re(e,t,n)},bi=function(e,t,n){if(!t.cy().headless()){var r,i,a=t._private,o=a.rstyle,s=o.arrowWidth/2;if("none"!==t.pstyle(n+"-arrow-shape").value){"source"===n?(r=o.srcX,i=o.srcY):"target"===n?(r=o.tgtX,i=o.tgtY):(r=o.midX,i=o.midY);var l=a.arrowBounds=a.arrowBounds||{},u=l[n]=l[n]||{};u.x1=r-s,u.y1=i-s,u.x2=r+s,u.y2=i+s,u.w=u.x2-u.x1,u.h=u.y2-u.y1,mt(u,1),vi(e,u.x1,u.y1,u.x2,u.y2)}}},xi=function(e,t,n){if(!t.cy().headless()){var r;r=n?n+"-":"";var i=t._private,a=i.rstyle;if(t.pstyle(r+"label").strValue){var o,s,l,u,c=t.pstyle("text-halign"),h=t.pstyle("text-valign"),d=mi(a,"labelWidth",n),p=mi(a,"labelHeight",n),g=mi(a,"labelX",n),f=mi(a,"labelY",n),v=t.pstyle(r+"text-margin-x").pfValue,y=t.pstyle(r+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle(r+"text-rotation"),x=t.pstyle("text-outline-width").pfValue,w=t.pstyle("text-border-width").pfValue/2,E=t.pstyle("text-background-padding").pfValue,_=p,T=d,D=T/2,C=_/2;if(m)o=g-D,s=g+D,l=f-C,u=f+C;else{switch(c.value){case"left":o=g-T,s=g;break;case"center":o=g-D,s=g+D;break;case"right":o=g,s=g+T}switch(h.value){case"top":l=f-_,u=f;break;case"center":l=f-C,u=f+C;break;case"bottom":l=f,u=f+_}}o+=v-Math.max(x,w)-E-2,s+=v+Math.max(x,w)+E+2,l+=y-Math.max(x,w)-E-2,u+=y+Math.max(x,w)+E+2;var N=n||"main",A=i.labelBounds,L=A[N]=A[N]||{};L.x1=o,L.y1=l,L.x2=s,L.y2=u,L.w=s-o,L.h=u-l;var k=m&&"autorotate"===b.strValue,S=null!=b.pfValue&&0!==b.pfValue;if(k||S){var I=k?mi(i.rstyle,"labelAngle",n):b.pfValue,M=Math.cos(I),O=Math.sin(I),P=(o+s)/2,R=(l+u)/2;if(!m){switch(c.value){case"left":P=s;break;case"right":P=o}switch(h.value){case"top":R=u;break;case"bottom":R=l}}var B=function(e,t){return{x:(e-=P)*M-(t-=R)*O+P,y:e*O+t*M+R}},F=B(o,l),z=B(o,u),G=B(s,l),Y=B(s,u);o=Math.min(F.x,z.x,G.x,Y.x),s=Math.max(F.x,z.x,G.x,Y.x),l=Math.min(F.y,z.y,G.y,Y.y),u=Math.max(F.y,z.y,G.y,Y.y)}var X=N+"Rot",V=A[X]=A[X]||{};V.x1=o,V.y1=l,V.x2=s,V.y2=u,V.w=s-o,V.h=u-l,vi(e,o,l,s,u),vi(i.labelBounds.all,o,l,s,u)}return e}},wi=function(e,t){var n,r,i,a,o,s,l,u=e._private.cy,c=u.styleEnabled(),h=u.headless(),d=ft(),p=e._private,g=e.isNode(),f=e.isEdge(),v=p.rstyle,y=g&&c?e.pstyle("bounds-expansion").pfValue:[0],m=function(e){return"none"!==e.pstyle("display").value},b=!c||m(e)&&(!f||m(e.source())&&m(e.target()));if(b){var x=0;c&&t.includeOverlays&&0!==e.pstyle("overlay-opacity").value&&(x=e.pstyle("overlay-padding").value);var w=0;c&&t.includeUnderlays&&0!==e.pstyle("underlay-opacity").value&&(w=e.pstyle("underlay-padding").value);var E=Math.max(x,w),_=0;if(c&&(_=e.pstyle("width").pfValue/2),g&&t.includeNodes){var T=e.position();o=T.x,s=T.y;var D=e.outerWidth()/2,C=e.outerHeight()/2;vi(d,n=o-D,i=s-C,r=o+D,a=s+C),c&&t.includeOutlines&&function(e,t){if(!t.cy().headless()){var n,r,i,a=t.pstyle("outline-opacity").value,o=t.pstyle("outline-width").value;if(a>0&&o>0){var s=t.pstyle("outline-offset").value,l=t.pstyle("shape").value,u=o+s,c=(e.w+2*u)/e.w,h=(e.h+2*u)/e.h,d=0;["diamond","pentagon","round-triangle"].includes(l)?(c=(e.w+2.4*u)/e.w,d=-u/3.6):["concave-hexagon","rhomboid","right-rhomboid"].includes(l)?c=(e.w+2.4*u)/e.w:"star"===l?(c=(e.w+2.8*u)/e.w,h=(e.h+2.6*u)/e.h,d=-u/3.8):"triangle"===l?(c=(e.w+2.8*u)/e.w,h=(e.h+2.4*u)/e.h,d=-u/1.4):"vee"===l&&(c=(e.w+4.4*u)/e.w,h=(e.h+3.8*u)/e.h,d=.5*-u);var p=e.h*h-e.h,g=e.w*c-e.w;if(bt(e,[Math.ceil(p/2),Math.ceil(g/2)]),0!==d){var f=(r=0,i=d,{x1:(n=e).x1+r,x2:n.x2+r,y1:n.y1+i,y2:n.y2+i,w:n.w,h:n.h});vt(e,f)}}}}(d,e)}else if(f&&t.includeEdges)if(c&&!h){var N=e.pstyle("curve-style").strValue;if(n=Math.min(v.srcX,v.midX,v.tgtX),r=Math.max(v.srcX,v.midX,v.tgtX),i=Math.min(v.srcY,v.midY,v.tgtY),a=Math.max(v.srcY,v.midY,v.tgtY),vi(d,n-=_,i-=_,r+=_,a+=_),"haystack"===N){var A=v.haystackPts;if(A&&2===A.length){if(n=A[0].x,i=A[0].y,n>(r=A[1].x)){var L=n;n=r,r=L}if(i>(a=A[1].y)){var k=i;i=a,a=k}vi(d,n-_,i-_,r+_,a+_)}}else if("bezier"===N||"unbundled-bezier"===N||"segments"===N||"taxi"===N){var S;switch(N){case"bezier":case"unbundled-bezier":S=v.bezierPts;break;case"segments":case"taxi":S=v.linePts}if(null!=S)for(var I=0;I<S.length;I++){var M=S[I];n=M.x-_,r=M.x+_,i=M.y-_,a=M.y+_,vi(d,n,i,r,a)}}}else{var O=e.source().position(),P=e.target().position();if((n=O.x)>(r=P.x)){var R=n;n=r,r=R}if((i=O.y)>(a=P.y)){var B=i;i=a,a=B}vi(d,n-=_,i-=_,r+=_,a+=_)}if(c&&t.includeEdges&&f&&(bi(d,e,"mid-source"),bi(d,e,"mid-target"),bi(d,e,"source"),bi(d,e,"target")),c)if("yes"===e.pstyle("ghost").value){var F=e.pstyle("ghost-offset-x").pfValue,z=e.pstyle("ghost-offset-y").pfValue;vi(d,d.x1+F,d.y1+z,d.x2+F,d.y2+z)}var G=p.bodyBounds=p.bodyBounds||{};xt(G,d),bt(G,y),mt(G,1),c&&(n=d.x1,r=d.x2,i=d.y1,a=d.y2,vi(d,n-E,i-E,r+E,a+E));var Y=p.overlayBounds=p.overlayBounds||{};xt(Y,d),bt(Y,y),mt(Y,1);var X=p.labelBounds=p.labelBounds||{};null!=X.all?((l=X.all).x1=1/0,l.y1=1/0,l.x2=-1/0,l.y2=-1/0,l.w=0,l.h=0):X.all=ft(),c&&t.includeLabels&&(t.includeMainLabels&&xi(d,e,null),f&&(t.includeSourceLabels&&xi(d,e,"source"),t.includeTargetLabels&&xi(d,e,"target")))}return d.x1=fi(d.x1),d.y1=fi(d.y1),d.x2=fi(d.x2),d.y2=fi(d.y2),d.w=fi(d.x2-d.x1),d.h=fi(d.y2-d.y1),d.w>0&&d.h>0&&b&&(bt(d,y),mt(d,1)),d},Ei=function(e){var t=0,n=function(e){return(e?1:0)<<t++},r=0;return r+=n(e.incudeNodes),r+=n(e.includeEdges),r+=n(e.includeLabels),r+=n(e.includeMainLabels),r+=n(e.includeSourceLabels),r+=n(e.includeTargetLabels),r+=n(e.includeOverlays),r+=n(e.includeOutlines)},_i=function(e){if(e.isEdge()){var t=e.source().position(),n=e.target().position(),r=function(e){return Math.round(e)};return function(e,t){var n={value:0,done:!1},r=0,i=e.length;return ce({next:function(){return r<i?n.value=e[r++]:n.done=!0,n}},t)}([r(t.x),r(t.y),r(n.x),r(n.y)])}return 0},Ti=function(e,t){var n,r=e._private,i=e.isEdge(),a=(null==t?Ci:Ei(t))===Ci,o=_i(e),s=r.bbCachePosKey===o,l=t.useCache&&s,u=function(e){return null==e._private.bbCache||e._private.styleDirty};if(!l||u(e)||i&&u(e.source())||u(e.target())?(s||e.recalculateRenderedStyle(l),n=wi(e,Di),r.bbCache=n,r.bbCachePosKey=o):n=r.bbCache,!a){var c=e.isNode();n=ft(),(t.includeNodes&&c||t.includeEdges&&!c)&&(t.includeOverlays?yi(n,r.overlayBounds):yi(n,r.bodyBounds)),t.includeLabels&&(t.includeMainLabels&&(!i||t.includeSourceLabels&&t.includeTargetLabels)?yi(n,r.labelBounds.all):(t.includeMainLabels&&yi(n,r.labelBounds.mainRot),t.includeSourceLabels&&yi(n,r.labelBounds.sourceRot),t.includeTargetLabels&&yi(n,r.labelBounds.targetRot))),n.w=n.x2-n.x1,n.h=n.y2-n.y1}return n},Di={includeNodes:!0,includeEdges:!0,includeLabels:!0,includeMainLabels:!0,includeSourceLabels:!0,includeTargetLabels:!0,includeOverlays:!0,includeUnderlays:!0,includeOutlines:!0,useCache:!0},Ci=Ei(Di),Ni=Me(Di);pi.boundingBox=function(e){var t;if(1!==this.length||null==this[0]._private.bbCache||this[0]._private.styleDirty||void 0!==e&&void 0!==e.useCache&&!0!==e.useCache){t=ft();var n=Ni(e=e||Di),r=this;if(r.cy().styleEnabled())for(var i=0;i<r.length;i++){var a=r[i],o=a._private,s=_i(a),l=o.bbCachePosKey===s,u=n.useCache&&l&&!o.styleDirty;a.recalculateRenderedStyle(u)}this.updateCompoundBounds(!e.useCache);for(var c=0;c<r.length;c++){var h=r[c];yi(t,Ti(h,n))}}else e=void 0===e?Di:Ni(e),t=Ti(this[0],e);return t.x1=fi(t.x1),t.y1=fi(t.y1),t.x2=fi(t.x2),t.y2=fi(t.y2),t.w=fi(t.x2-t.x1),t.h=fi(t.y2-t.y1),t},pi.dirtyBoundingBoxCache=function(){for(var e=0;e<this.length;e++){var t=this[e]._private;t.bbCache=null,t.bbCachePosKey=null,t.bodyBounds=null,t.overlayBounds=null,t.labelBounds.all=null,t.labelBounds.source=null,t.labelBounds.target=null,t.labelBounds.main=null,t.labelBounds.sourceRot=null,t.labelBounds.targetRot=null,t.labelBounds.mainRot=null,t.arrowBounds.source=null,t.arrowBounds.target=null,t.arrowBounds["mid-source"]=null,t.arrowBounds["mid-target"]=null}return this.emitAndNotify("bounds"),this},pi.boundingBoxAt=function(e){var t=this.nodes(),n=this.cy(),r=n.hasCompoundNodes(),i=n.collection();if(r&&(i=t.filter((function(e){return e.isParent()})),t=t.not(i)),S(e)){var a=e;e=function(){return a}}n.startBatch(),t.forEach((function(t,n){return t._private.bbAtOldPos=e(t,n)})).silentPositions(e),r&&(i.dirtyCompoundBoundsCache(),i.dirtyBoundingBoxCache(),i.updateCompoundBounds(!0));var o=function(e){return{x1:e.x1,x2:e.x2,w:e.w,y1:e.y1,y2:e.y2,h:e.h}}(this.boundingBox({useCache:!1}));return t.silentPositions((function(e){return e._private.bbAtOldPos})),r&&(i.dirtyCompoundBoundsCache(),i.dirtyBoundingBoxCache(),i.updateCompoundBounds(!0)),n.endBatch(),o},di.boundingbox=di.bb=di.boundingBox,di.renderedBoundingbox=di.renderedBoundingBox;var Ai,Li,ki=pi;Ai=Li={};var Si=function(e){e.uppercaseName=j(e.name),e.autoName="auto"+e.uppercaseName,e.labelName="label"+e.uppercaseName,e.outerName="outer"+e.uppercaseName,e.uppercaseOuterName=j(e.outerName),Ai[e.name]=function(){var t=this[0],n=t._private,r=n.cy._private.styleEnabled;if(t){if(r){if(t.isParent())return t.updateCompoundBounds(),n[e.autoName]||0;var i=t.pstyle(e.name);return"label"===i.strValue?(t.recalculateRenderedStyle(),n.rstyle[e.labelName]||0):i.pfValue}return 1}},Ai["outer"+e.uppercaseName]=function(){var t=this[0],n=t._private.cy._private.styleEnabled;if(t)return n?t[e.name]()+t.pstyle("border-width").pfValue+2*t.padding():1},Ai["rendered"+e.uppercaseName]=function(){var t=this[0];if(t)return t[e.name]()*this.cy().zoom()},Ai["rendered"+e.uppercaseOuterName]=function(){var t=this[0];if(t)return t[e.outerName]()*this.cy().zoom()}};Si({name:"width"}),Si({name:"height"}),Li.padding=function(){var e=this[0],t=e._private;return e.isParent()?(e.updateCompoundBounds(),void 0!==t.autoPadding?t.autoPadding:e.pstyle("padding").pfValue):e.pstyle("padding").pfValue},Li.paddedHeight=function(){var e=this[0];return e.height()+2*e.padding()},Li.paddedWidth=function(){var e=this[0];return e.width()+2*e.padding()};var Ii=Li,Mi={controlPoints:{get:function(e){return e.renderer().getControlPoints(e)},mult:!0},segmentPoints:{get:function(e){return e.renderer().getSegmentPoints(e)},mult:!0},sourceEndpoint:{get:function(e){return e.renderer().getSourceEndpoint(e)}},targetEndpoint:{get:function(e){return e.renderer().getTargetEndpoint(e)}},midpoint:{get:function(e){return e.renderer().getEdgeMidpoint(e)}}},Oi=Object.keys(Mi).reduce((function(e,t){var n=Mi[t],r=function(e){return"rendered"+e[0].toUpperCase()+e.substr(1)}(t);return e[t]=function(){return function(e,t){if(e.isEdge())return t(e)}(this,n.get)},n.mult?e[r]=function(){return function(e,t){if(e.isEdge()){var n=e.cy(),r=n.pan(),i=n.zoom();return t(e).map((function(e){return rt(e,i,r)}))}}(this,n.get)}:e[r]=function(){return function(e,t){if(e.isEdge()){var n=e.cy();return rt(t(e),n.zoom(),n.pan())}}(this,n.get)},e}),{}),Pi=Q({},gi,ki,Ii,Oi),Ri=function(e,t){this.recycle(e,t)};function Bi(){return!1}function Fi(){return!0}Ri.prototype={instanceString:function(){return"event"},recycle:function(e,t){if(this.isImmediatePropagationStopped=this.isPropagationStopped=this.isDefaultPrevented=Bi,null!=e&&e.preventDefault?(this.type=e.type,this.isDefaultPrevented=e.defaultPrevented?Fi:Bi):null!=e&&e.type?t=e:this.type=e,null!=t&&(this.originalEvent=t.originalEvent,this.type=null!=t.type?t.type:this.type,this.cy=t.cy,this.target=t.target,this.position=t.position,this.renderedPosition=t.renderedPosition,this.namespace=t.namespace,this.layout=t.layout),null!=this.cy&&null!=this.position&&null==this.renderedPosition){var n=this.position,r=this.cy.zoom(),i=this.cy.pan();this.renderedPosition={x:n.x*r+i.x,y:n.y*r+i.y}}this.timeStamp=e&&e.timeStamp||Date.now()},preventDefault:function(){this.isDefaultPrevented=Fi;var e=this.originalEvent;e&&e.preventDefault&&e.preventDefault()},stopPropagation:function(){this.isPropagationStopped=Fi;var e=this.originalEvent;e&&e.stopPropagation&&e.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Fi,this.stopPropagation()},isDefaultPrevented:Bi,isPropagationStopped:Bi,isImmediatePropagationStopped:Bi};var zi=/^([^.]+)(\.(?:[^.]+))?$/,Gi={qualifierCompare:function(e,t){return e===t},eventMatches:function(){return!0},addEventFields:function(){},callbackContext:function(e){return e},beforeEmit:function(){},afterEmit:function(){},bubble:function(){return!1},parent:function(){return null},context:null},Yi=Object.keys(Gi),Xi={};function Vi(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Xi,t=arguments.length>1?arguments[1]:void 0,n=0;n<Yi.length;n++){var r=Yi[n];this[r]=e[r]||Gi[r]}this.context=t||this.context,this.listeners=[],this.emitting=0}var Ui=Vi.prototype,ji=function(e,t,n,r,i,a,o){L(r)&&(i=r,r=null),o&&(a=null==a?o:Q({},a,o));for(var s=k(n)?n:n.split(/\s+/),l=0;l<s.length;l++){var u=s[l];if(!z(u)){var c=u.match(zi);if(c)if(!1===t(e,u,c[1],c[2]?c[2]:null,r,i,a))break}}},qi=function(e,t){return e.addEventFields(e.context,t),new Ri(t.type,t)},Hi=function(e,t,n){if("event"!==N(n))if(S(n))t(e,qi(e,n));else for(var r=k(n)?n:n.split(/\s+/),i=0;i<r.length;i++){var a=r[i];if(!z(a)){var o=a.match(zi);if(o){var s=o[1],l=o[2]?o[2]:null;t(e,qi(e,{type:s,namespace:l,target:e.context}))}}}else t(e,n)};Ui.on=Ui.addListener=function(e,t,n,r,i){return ji(this,(function(e,t,n,r,i,a,o){L(a)&&e.listeners.push({event:t,callback:a,type:n,namespace:r,qualifier:i,conf:o})}),e,t,n,r,i),this},Ui.one=function(e,t,n,r){return this.on(e,t,n,r,{one:!0})},Ui.removeListener=Ui.off=function(e,t,n,r){var i=this;0!==this.emitting&&(this.listeners=this.listeners.slice());for(var a=this.listeners,o=function(o){var s=a[o];ji(i,(function(t,n,r,i,l,u){if((s.type===r||"*"===e)&&(!i&&".*"!==s.namespace||s.namespace===i)&&(!l||t.qualifierCompare(s.qualifier,l))&&(!u||s.callback===u))return a.splice(o,1),!1}),e,t,n,r)},s=a.length-1;s>=0;s--)o(s);return this},Ui.removeAllListeners=function(){return this.removeListener("*")},Ui.emit=Ui.trigger=function(e,t,n){var r=this.listeners,i=r.length;return this.emitting++,k(t)||(t=[t]),Hi(this,(function(e,a){null!=n&&(r=[{event:a.event,type:a.type,namespace:a.namespace,callback:n}],i=r.length);for(var o=function(n){var i=r[n];if(i.type===a.type&&(!i.namespace||i.namespace===a.namespace||".*"===i.namespace)&&e.eventMatches(e.context,i,a)){var o=[a];null!=t&&function(e,t){for(var n=0;n<t.length;n++){var r=t[n];e.push(r)}}(o,t),e.beforeEmit(e.context,i,a),i.conf&&i.conf.one&&(e.listeners=e.listeners.filter((function(e){return e!==i})));var s=e.callbackContext(e.context,i,a),l=i.callback.apply(s,o);e.afterEmit(e.context,i,a),!1===l&&(a.stopPropagation(),a.preventDefault())}},s=0;s<i;s++)o(s);e.bubble(e.context)&&!a.isPropagationStopped()&&e.parent(e.context).emit(a,t)}),e),this.emitting--,this};var Wi={qualifierCompare:function(e,t){return null==e||null==t?null==e&&null==t:e.sameText(t)},eventMatches:function(e,t,n){var r=t.qualifier;return null==r||e!==n.target&&P(n.target)&&r.matches(n.target)},addEventFields:function(e,t){t.cy=e.cy(),t.target=e},callbackContext:function(e,t,n){return null!=t.qualifier?n.target:e},beforeEmit:function(e,t){t.conf&&t.conf.once&&t.conf.onceCollection.removeListener(t.event,t.qualifier,t.callback)},bubble:function(){return!0},parent:function(e){return e.isChild()?e.parent():e.cy()}},$i=function(e){return A(e)?new Hr(e):e},Ki={createEmitter:function(){for(var e=0;e<this.length;e++){var t=this[e],n=t._private;n.emitter||(n.emitter=new Vi(Wi,t))}return this},emitter:function(){return this._private.emitter},on:function(e,t,n){for(var r=$i(t),i=0;i<this.length;i++){this[i].emitter().on(e,r,n)}return this},removeListener:function(e,t,n){for(var r=$i(t),i=0;i<this.length;i++){this[i].emitter().removeListener(e,r,n)}return this},removeAllListeners:function(){for(var e=0;e<this.length;e++){this[e].emitter().removeAllListeners()}return this},one:function(e,t,n){for(var r=$i(t),i=0;i<this.length;i++){this[i].emitter().one(e,r,n)}return this},once:function(e,t,n){for(var r=$i(t),i=0;i<this.length;i++){this[i].emitter().on(e,r,n,{once:!0,onceCollection:this})}},emit:function(e,t){for(var n=0;n<this.length;n++){this[n].emitter().emit(e,t)}return this},emitAndNotify:function(e,t){if(0!==this.length)return this.cy().notify(e,this),this.emit(e,t),this}};ur.eventAliasesOn(Ki);var Zi={nodes:function(e){return this.filter((function(e){return e.isNode()})).filter(e)},edges:function(e){return this.filter((function(e){return e.isEdge()})).filter(e)},byGroup:function(){for(var e=this.spawn(),t=this.spawn(),n=0;n<this.length;n++){var r=this[n];r.isNode()?e.push(r):t.push(r)}return{nodes:e,edges:t}},filter:function(e,t){if(void 0===e)return this;if(A(e)||O(e))return new Hr(e).filter(this);if(L(e)){for(var n=this.spawn(),r=this,i=0;i<r.length;i++){var a=r[i];(t?e.apply(t,[a,i,r]):e(a,i,r))&&n.push(a)}return n}return this.spawn()},not:function(e){if(e){A(e)&&(e=this.filter(e));for(var t=this.spawn(),n=0;n<this.length;n++){var r=this[n];e.has(r)||t.push(r)}return t}return this},absoluteComplement:function(){return this.cy().mutableElements().not(this)},intersect:function(e){if(A(e)){var t=e;return this.filter(t)}for(var n=this.spawn(),r=e,i=this.length<e.length,a=i?this:r,o=i?r:this,s=0;s<a.length;s++){var l=a[s];o.has(l)&&n.push(l)}return n},xor:function(e){var t=this._private.cy;A(e)&&(e=t.$(e));var n=this.spawn(),r=e,i=function(e,t){for(var r=0;r<e.length;r++){var i=e[r],a=i._private.data.id;t.hasElementWithId(a)||n.push(i)}};return i(this,r),i(r,this),n},diff:function(e){var t=this._private.cy;A(e)&&(e=t.$(e));var n=this.spawn(),r=this.spawn(),i=this.spawn(),a=e,o=function(e,t,n){for(var r=0;r<e.length;r++){var a=e[r],o=a._private.data.id;t.hasElementWithId(o)?i.merge(a):n.push(a)}};return o(this,a,n),o(a,this,r),{left:n,right:r,both:i}},add:function(e){var t=this._private.cy;if(!e)return this;if(A(e)){var n=e;e=t.mutableElements().filter(n)}for(var r=this.spawnSelf(),i=0;i<e.length;i++){var a=e[i],o=!this.has(a);o&&r.push(a)}return r},merge:function(e){var t=this._private,n=t.cy;if(!e)return this;if(e&&A(e)){var r=e;e=n.mutableElements().filter(r)}for(var i=t.map,a=0;a<e.length;a++){var o=e[a],s=o._private.data.id;if(!i.has(s)){var l=this.length++;this[l]=o,i.set(s,{ele:o,index:l})}}return this},unmergeAt:function(e){var t=this[e].id(),n=this._private.map;this[e]=void 0,n.delete(t);var r=e===this.length-1;if(this.length>1&&!r){var i=this.length-1,a=this[i],o=a._private.data.id;this[i]=void 0,this[e]=a,n.set(o,{ele:a,index:e})}return this.length--,this},unmergeOne:function(e){e=e[0];var t=this._private,n=e._private.data.id,r=t.map.get(n);if(!r)return this;var i=r.index;return this.unmergeAt(i),this},unmerge:function(e){var t=this._private.cy;if(!e)return this;if(e&&A(e)){var n=e;e=t.mutableElements().filter(n)}for(var r=0;r<e.length;r++)this.unmergeOne(e[r]);return this},unmergeBy:function(e){for(var t=this.length-1;t>=0;t--){e(this[t])&&this.unmergeAt(t)}return this},map:function(e,t){for(var n=[],r=this,i=0;i<r.length;i++){var a=r[i],o=t?e.apply(t,[a,i,r]):e(a,i,r);n.push(o)}return n},reduce:function(e,t){for(var n=t,r=this,i=0;i<r.length;i++)n=e(n,r[i],i,r);return n},max:function(e,t){for(var n,r=-1/0,i=this,a=0;a<i.length;a++){var o=i[a],s=t?e.apply(t,[o,a,i]):e(o,a,i);s>r&&(r=s,n=o)}return{value:r,ele:n}},min:function(e,t){for(var n,r=1/0,i=this,a=0;a<i.length;a++){var o=i[a],s=t?e.apply(t,[o,a,i]):e(o,a,i);s<r&&(r=s,n=o)}return{value:r,ele:n}}},Qi=Zi;Qi.u=Qi["|"]=Qi["+"]=Qi.union=Qi.or=Qi.add,Qi["\\"]=Qi["!"]=Qi["-"]=Qi.difference=Qi.relativeComplement=Qi.subtract=Qi.not,Qi.n=Qi["&"]=Qi["."]=Qi.and=Qi.intersection=Qi.intersect,Qi["^"]=Qi["(+)"]=Qi["(-)"]=Qi.symmetricDifference=Qi.symdiff=Qi.xor,Qi.fnFilter=Qi.filterFn=Qi.stdFilter=Qi.filter,Qi.complement=Qi.abscomp=Qi.absoluteComplement;var Ji=function(e,t){var n=e.cy().hasCompoundNodes();function r(e){var t=e.pstyle("z-compound-depth");return"auto"===t.value?n?e.zDepth():0:"bottom"===t.value?-1:"top"===t.value?we:0}var i=r(e)-r(t);if(0!==i)return i;function a(e){return"auto"===e.pstyle("z-index-compare").value&&e.isNode()?1:0}var o=a(e)-a(t);if(0!==o)return o;var s=e.pstyle("z-index").value-t.pstyle("z-index").value;return 0!==s?s:e.poolIndex()-t.poolIndex()},ea={forEach:function(e,t){if(L(e))for(var n=this.length,r=0;r<n;r++){var i=this[r];if(!1===(t?e.apply(t,[i,r,this]):e(i,r,this)))break}return this},toArray:function(){for(var e=[],t=0;t<this.length;t++)e.push(this[t]);return e},slice:function(e,t){var n=[],r=this.length;null==t&&(t=r),null==e&&(e=0),e<0&&(e=r+e),t<0&&(t=r+t);for(var i=e;i>=0&&i<t&&i<r;i++)n.push(this[i]);return this.spawn(n)},size:function(){return this.length},eq:function(e){return this[e]||this.spawn()},first:function(){return this[0]||this.spawn()},last:function(){return this[this.length-1]||this.spawn()},empty:function(){return 0===this.length},nonempty:function(){return!this.empty()},sort:function(e){if(!L(e))return this;var t=this.toArray().sort(e);return this.spawn(t)},sortByZIndex:function(){return this.sort(Ji)},zDepth:function(){var e=this[0];if(e){var t=e._private;if("nodes"===t.group){var n=t.data.parent?e.parents().size():0;return e.isParent()?n:we-1}var r=t.source,i=t.target,a=r.zDepth(),o=i.zDepth();return Math.max(a,o,0)}}};ea.each=ea.forEach;var ta;ta="undefined",("undefined"==typeof Symbol?"undefined":g(Symbol))!=ta&&g(Symbol.iterator)!=ta&&(ea[Symbol.iterator]=function(){var e=this,t={value:void 0,done:!1},n=0,r=this.length;return m({next:function(){return n<r?t.value=e[n++]:(t.value=void 0,t.done=!0),t}},Symbol.iterator,(function(){return this}))});var na=Me({nodeDimensionsIncludeLabels:!1}),ra={layoutDimensions:function(e){var t;if(e=na(e),this.takesUpSpace())if(e.nodeDimensionsIncludeLabels){var n=this.boundingBox();t={w:n.w,h:n.h}}else t={w:this.outerWidth(),h:this.outerHeight()};else t={w:0,h:0};return 0!==t.w&&0!==t.h||(t.w=t.h=1),t},layoutPositions:function(e,t,n){var r=this.nodes().filter((function(e){return!e.isParent()})),i=this.cy(),a=t.eles,o=function(e){return e.id()},s=Y(n,o);e.emit({type:"layoutstart",layout:e}),e.animations=[];var l=t.spacingFactor&&1!==t.spacingFactor,u=function(){if(!l)return null;for(var e=ft(),t=0;t<r.length;t++){var n=r[t],i=s(n,t);yt(e,i.x,i.y)}return e}(),c=Y((function(e,n){var r=s(e,n);l&&(r=function(e,t,n){var r=t.x1+t.w/2,i=t.y1+t.h/2;return{x:r+(n.x-r)*e,y:i+(n.y-i)*e}}(Math.abs(t.spacingFactor),u,r));return null!=t.transform&&(r=t.transform(e,r)),r}),o);if(t.animate){for(var h=0;h<r.length;h++){var d=r[h],p=c(d,h);if(null==t.animateFilter||t.animateFilter(d,h)){var g=d.animation({position:p,duration:t.animationDuration,easing:t.animationEasing});e.animations.push(g)}else d.position(p)}if(t.fit){var f=i.animation({fit:{boundingBox:a.boundingBoxAt(c),padding:t.padding},duration:t.animationDuration,easing:t.animationEasing});e.animations.push(f)}else if(void 0!==t.zoom&&void 0!==t.pan){var v=i.animation({zoom:t.zoom,pan:t.pan,duration:t.animationDuration,easing:t.animationEasing});e.animations.push(v)}e.animations.forEach((function(e){return e.play()})),e.one("layoutready",t.ready),e.emit({type:"layoutready",layout:e}),rr.all(e.animations.map((function(e){return e.promise()}))).then((function(){e.one("layoutstop",t.stop),e.emit({type:"layoutstop",layout:e})}))}else r.positions(c),t.fit&&i.fit(t.eles,t.padding),null!=t.zoom&&i.zoom(t.zoom),t.pan&&i.pan(t.pan),e.one("layoutready",t.ready),e.emit({type:"layoutready",layout:e}),e.one("layoutstop",t.stop),e.emit({type:"layoutstop",layout:e});return this},layout:function(e){return this.cy().makeLayout(Q({},e,{eles:this}))}};function ia(e,t,n){var r,i=n._private,a=i.styleCache=i.styleCache||[];return null!=(r=a[e])?r:r=a[e]=t(n)}function aa(e,t){return e=fe(e),function(n){return ia(e,t,n)}}function oa(e,t){e=fe(e);var n=function(e){return t.call(e)};return function(){var t=this[0];if(t)return ia(e,n,t)}}ra.createLayout=ra.makeLayout=ra.layout;var sa={recalculateRenderedStyle:function(e){var t=this.cy(),n=t.renderer(),r=t.styleEnabled();return n&&r&&n.recalculateRenderedStyle(this,e),this},dirtyStyleCache:function(){var e,t=this.cy(),n=function(e){return e._private.styleCache=null};t.hasCompoundNodes()?((e=this.spawnSelf().merge(this.descendants()).merge(this.parents())).merge(e.connectedEdges()),e.forEach(n)):this.forEach((function(e){n(e),e.connectedEdges().forEach(n)}));return this},updateStyle:function(e){var t=this._private.cy;if(!t.styleEnabled())return this;if(t.batching())return t._private.batchStyleEles.merge(this),this;var n=this;e=!(!e&&void 0!==e),t.hasCompoundNodes()&&(n=this.spawnSelf().merge(this.descendants()).merge(this.parents()));var r=n;return e?r.emitAndNotify("style"):r.emit("style"),n.forEach((function(e){return e._private.styleDirty=!0})),this},cleanStyle:function(){var e=this.cy();if(e.styleEnabled())for(var t=0;t<this.length;t++){var n=this[t];n._private.styleDirty&&(n._private.styleDirty=!1,e.style().apply(n))}},parsedStyle:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this[0],r=n.cy();if(r.styleEnabled()&&n){this.cleanStyle();var i=n._private.style[e];return null!=i?i:t?r.style().getDefaultProperty(e):null}},numericStyle:function(e){var t=this[0];if(t.cy().styleEnabled()&&t){var n=t.pstyle(e);return void 0!==n.pfValue?n.pfValue:n.value}},numericStyleUnits:function(e){var t=this[0];if(t.cy().styleEnabled())return t?t.pstyle(e).units:void 0},renderedStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=this[0];return n?t.style().getRenderedStyle(n,e):void 0},style:function(e,t){var n=this.cy();if(!n.styleEnabled())return this;var r=!1,i=n.style();if(S(e)){var a=e;i.applyBypass(this,a,r),this.emitAndNotify("style")}else if(A(e)){if(void 0===t){var o=this[0];return o?i.getStylePropertyValue(o,e):void 0}i.applyBypass(this,e,t,r),this.emitAndNotify("style")}else if(void 0===e){var s=this[0];return s?i.getRawStyle(s):void 0}return this},removeStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=!1,r=t.style(),i=this;if(void 0===e)for(var a=0;a<i.length;a++){var o=i[a];r.removeAllBypasses(o,n)}else{e=e.split(/\s+/);for(var s=0;s<i.length;s++){var l=i[s];r.removeBypasses(l,e,n)}}return this.emitAndNotify("style"),this},show:function(){return this.css("display","element"),this},hide:function(){return this.css("display","none"),this},effectiveOpacity:function(){var e=this.cy();if(!e.styleEnabled())return 1;var t=e.hasCompoundNodes(),n=this[0];if(n){var r=n._private,i=n.pstyle("opacity").value;if(!t)return i;var a=r.data.parent?n.parents():null;if(a)for(var o=0;o<a.length;o++){i*=a[o].pstyle("opacity").value}return i}},transparent:function(){if(!this.cy().styleEnabled())return!1;var e=this[0],t=e.cy().hasCompoundNodes();return e?t?0===e.effectiveOpacity():0===e.pstyle("opacity").value:void 0},backgrounding:function(){return!!this.cy().styleEnabled()&&!!this[0]._private.backgrounding}};function la(e,t){var n=e._private.data.parent?e.parents():null;if(n)for(var r=0;r<n.length;r++){if(!t(n[r]))return!1}return!0}function ua(e){var t=e.ok,n=e.edgeOkViaNode||e.ok,r=e.parentOk||e.ok;return function(){var e=this.cy();if(!e.styleEnabled())return!0;var i=this[0],a=e.hasCompoundNodes();if(i){var o=i._private;if(!t(i))return!1;if(i.isNode())return!a||la(i,r);var s=o.source,l=o.target;return n(s)&&(!a||la(s,n))&&(s===l||n(l)&&(!a||la(l,n)))}}}var ca=aa("eleTakesUpSpace",(function(e){return"element"===e.pstyle("display").value&&0!==e.width()&&(!e.isNode()||0!==e.height())}));sa.takesUpSpace=oa("takesUpSpace",ua({ok:ca}));var ha=aa("eleInteractive",(function(e){return"yes"===e.pstyle("events").value&&"visible"===e.pstyle("visibility").value&&ca(e)})),da=aa("parentInteractive",(function(e){return"visible"===e.pstyle("visibility").value&&ca(e)}));sa.interactive=oa("interactive",ua({ok:ha,parentOk:da,edgeOkViaNode:ca})),sa.noninteractive=function(){var e=this[0];if(e)return!e.interactive()};var pa=aa("eleVisible",(function(e){return"visible"===e.pstyle("visibility").value&&0!==e.pstyle("opacity").pfValue&&ca(e)})),ga=ca;sa.visible=oa("visible",ua({ok:pa,edgeOkViaNode:ga})),sa.hidden=function(){var e=this[0];if(e)return!e.visible()},sa.isBundledBezier=oa("isBundledBezier",(function(){return!!this.cy().styleEnabled()&&(!this.removed()&&"bezier"===this.pstyle("curve-style").value&&this.takesUpSpace())})),sa.bypass=sa.css=sa.style,sa.renderedCss=sa.renderedStyle,sa.removeBypass=sa.removeCss=sa.removeStyle,sa.pstyle=sa.parsedStyle;var fa={};function va(e){return function(){var t=arguments,n=[];if(2===t.length){var r=t[0],i=t[1];this.on(e.event,r,i)}else if(1===t.length&&L(t[0])){var a=t[0];this.on(e.event,a)}else if(0===t.length||1===t.length&&k(t[0])){for(var o=1===t.length?t[0]:null,s=0;s<this.length;s++){var l=this[s],u=!e.ableField||l._private[e.ableField],c=l._private[e.field]!=e.value;if(e.overrideAble){var h=e.overrideAble(l);if(void 0!==h&&(u=h,!h))return this}u&&(l._private[e.field]=e.value,c&&n.push(l))}var d=this.spawn(n);d.updateStyle(),d.emit(e.event),o&&d.emit(o)}return this}}function ya(e){fa[e.field]=function(){var t=this[0];if(t){if(e.overrideField){var n=e.overrideField(t);if(void 0!==n)return n}return t._private[e.field]}},fa[e.on]=va({event:e.on,field:e.field,ableField:e.ableField,overrideAble:e.overrideAble,value:!0}),fa[e.off]=va({event:e.off,field:e.field,ableField:e.ableField,overrideAble:e.overrideAble,value:!1})}ya({field:"locked",overrideField:function(e){return!!e.cy().autolock()||void 0},on:"lock",off:"unlock"}),ya({field:"grabbable",overrideField:function(e){return!e.cy().autoungrabify()&&!e.pannable()&&void 0},on:"grabify",off:"ungrabify"}),ya({field:"selected",ableField:"selectable",overrideAble:function(e){return!e.cy().autounselectify()&&void 0},on:"select",off:"unselect"}),ya({field:"selectable",overrideField:function(e){return!e.cy().autounselectify()&&void 0},on:"selectify",off:"unselectify"}),fa.deselect=fa.unselect,fa.grabbed=function(){var e=this[0];if(e)return e._private.grabbed},ya({field:"active",on:"activate",off:"unactivate"}),ya({field:"pannable",on:"panify",off:"unpanify"}),fa.inactive=function(){var e=this[0];if(e)return!e._private.active};var ma={},ba=function(e){return function(t){for(var n=[],r=0;r<this.length;r++){var i=this[r];if(i.isNode()){for(var a=!1,o=i.connectedEdges(),s=0;s<o.length;s++){var l=o[s],u=l.source(),c=l.target();if(e.noIncomingEdges&&c===i&&u!==i||e.noOutgoingEdges&&u===i&&c!==i){a=!0;break}}a||n.push(i)}}return this.spawn(n,!0).filter(t)}},xa=function(e){return function(t){for(var n=[],r=0;r<this.length;r++){var i=this[r];if(i.isNode())for(var a=i.connectedEdges(),o=0;o<a.length;o++){var s=a[o],l=s.source(),u=s.target();e.outgoing&&l===i?(n.push(s),n.push(u)):e.incoming&&u===i&&(n.push(s),n.push(l))}}return this.spawn(n,!0).filter(t)}},wa=function(e){return function(t){for(var n=this,r=[],i={};;){var a=e.outgoing?n.outgoers():n.incomers();if(0===a.length)break;for(var o=!1,s=0;s<a.length;s++){var l=a[s],u=l.id();i[u]||(i[u]=!0,r.push(l),o=!0)}if(!o)break;n=a}return this.spawn(r,!0).filter(t)}};function Ea(e){return function(t){for(var n=[],r=0;r<this.length;r++){var i=this[r]._private[e.attr];i&&n.push(i)}return this.spawn(n,!0).filter(t)}}function _a(e){return function(t){var n=[],r=this._private.cy,i=e||{};A(t)&&(t=r.$(t));for(var a=0;a<t.length;a++)for(var o=t[a]._private.edges,s=0;s<o.length;s++){var l=o[s],u=l._private.data,c=this.hasElementWithId(u.source)&&t.hasElementWithId(u.target),h=t.hasElementWithId(u.source)&&this.hasElementWithId(u.target);if(c||h){if(i.thisIsSrc||i.thisIsTgt){if(i.thisIsSrc&&!c)continue;if(i.thisIsTgt&&!h)continue}n.push(l)}}return this.spawn(n,!0)}}function Ta(e){return e=Q({},{codirected:!1},e),function(t){for(var n=[],r=this.edges(),i=e,a=0;a<r.length;a++)for(var o=r[a]._private,s=o.source,l=s._private.data.id,u=o.data.target,c=s._private.edges,h=0;h<c.length;h++){var d=c[h],p=d._private.data,g=p.target,f=p.source,v=g===u&&f===l,y=l===g&&u===f;(i.codirected&&v||!i.codirected&&(v||y))&&n.push(d)}return this.spawn(n,!0).filter(t)}}ma.clearTraversalCache=function(){for(var e=0;e<this.length;e++)this[e]._private.traversalCache=null},Q(ma,{roots:ba({noIncomingEdges:!0}),leaves:ba({noOutgoingEdges:!0}),outgoers:Qr(xa({outgoing:!0}),"outgoers"),successors:wa({outgoing:!0}),incomers:Qr(xa({incoming:!0}),"incomers"),predecessors:wa({incoming:!0})}),Q(ma,{neighborhood:Qr((function(e){for(var t=[],n=this.nodes(),r=0;r<n.length;r++)for(var i=n[r],a=i.connectedEdges(),o=0;o<a.length;o++){var s=a[o],l=s.source(),u=s.target(),c=i===l?u:l;c.length>0&&t.push(c[0]),t.push(s[0])}return this.spawn(t,!0).filter(e)}),"neighborhood"),closedNeighborhood:function(e){return this.neighborhood().add(this).filter(e)},openNeighborhood:function(e){return this.neighborhood(e)}}),ma.neighbourhood=ma.neighborhood,ma.closedNeighbourhood=ma.closedNeighborhood,ma.openNeighbourhood=ma.openNeighborhood,Q(ma,{source:Qr((function(e){var t,n=this[0];return n&&(t=n._private.source||n.cy().collection()),t&&e?t.filter(e):t}),"source"),target:Qr((function(e){var t,n=this[0];return n&&(t=n._private.target||n.cy().collection()),t&&e?t.filter(e):t}),"target"),sources:Ea({attr:"source"}),targets:Ea({attr:"target"})}),Q(ma,{edgesWith:Qr(_a(),"edgesWith"),edgesTo:Qr(_a({thisIsSrc:!0}),"edgesTo")}),Q(ma,{connectedEdges:Qr((function(e){for(var t=[],n=0;n<this.length;n++){var r=this[n];if(r.isNode())for(var i=r._private.edges,a=0;a<i.length;a++){var o=i[a];t.push(o)}}return this.spawn(t,!0).filter(e)}),"connectedEdges"),connectedNodes:Qr((function(e){for(var t=[],n=0;n<this.length;n++){var r=this[n];r.isEdge()&&(t.push(r.source()[0]),t.push(r.target()[0]))}return this.spawn(t,!0).filter(e)}),"connectedNodes"),parallelEdges:Qr(Ta(),"parallelEdges"),codirectedEdges:Qr(Ta({codirected:!0}),"codirectedEdges")}),Q(ma,{components:function(e){var t=this,n=t.cy(),r=n.collection(),i=null==e?t.nodes():e.nodes(),a=[];null!=e&&i.empty()&&(i=e.sources());var o=function(e,t){r.merge(e),i.unmerge(e),t.merge(e)};if(i.empty())return t.spawn();var s=function(){var e=n.collection();a.push(e);var r=i[0];o(r,e),t.bfs({directed:!1,roots:r,visit:function(t){return o(t,e)}}),e.forEach((function(n){n.connectedEdges().forEach((function(n){t.has(n)&&e.has(n.source())&&e.has(n.target())&&e.merge(n)}))}))};do{s()}while(i.length>0);return a},component:function(){var e=this[0];return e.cy().mutableElements().components(e)[0]}}),ma.componentsOf=ma.components;var Da=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(void 0!==e){var i=new Fe,a=!1;if(t){if(t.length>0&&S(t[0])&&!P(t[0])){a=!0;for(var o=[],s=new Ge,l=0,u=t.length;l<u;l++){var c=t[l];null==c.data&&(c.data={});var h=c.data;if(null==h.id)h.id=ke();else if(e.hasElementWithId(h.id)||s.has(h.id))continue;var d=new Ye(e,c,!1);o.push(d),s.add(h.id)}t=o}}else t=[];this.length=0;for(var p=0,g=t.length;p<g;p++){var f=t[p][0];if(null!=f){var v=f._private.data.id;n&&i.has(v)||(n&&i.set(v,{index:this.length,ele:f}),this[this.length]=f,this.length++)}}this._private={eles:this,cy:e,get map(){return null==this.lazyMap&&this.rebuildMap(),this.lazyMap},set map(e){this.lazyMap=e},rebuildMap:function(){for(var e=this.lazyMap=new Fe,t=this.eles,n=0;n<t.length;n++){var r=t[n];e.set(r.id(),{index:n,ele:r})}}},n&&(this._private.map=i),a&&!r&&this.restore()}else Ce("A collection must have a reference to the core")},Ca=Ye.prototype=Da.prototype=Object.create(Array.prototype);Ca.instanceString=function(){return"collection"},Ca.spawn=function(e,t){return new Da(this.cy(),e,t)},Ca.spawnSelf=function(){return this.spawn(this)},Ca.cy=function(){return this._private.cy},Ca.renderer=function(){return this._private.cy.renderer()},Ca.element=function(){return this[0]},Ca.collection=function(){return R(this)?this:new Da(this._private.cy,[this])},Ca.unique=function(){return new Da(this._private.cy,this,!0)},Ca.hasElementWithId=function(e){return e=""+e,this._private.map.has(e)},Ca.getElementById=function(e){e=""+e;var t=this._private.cy,n=this._private.map.get(e);return n?n.ele:new Da(t)},Ca.$id=Ca.getElementById,Ca.poolIndex=function(){var e=this._private.cy._private.elements,t=this[0]._private.data.id;return e._private.map.get(t).index},Ca.indexOf=function(e){var t=e[0]._private.data.id;return this._private.map.get(t).index},Ca.indexOfId=function(e){return e=""+e,this._private.map.get(e).index},Ca.json=function(e){var t=this.element(),n=this.cy();if(null==t&&e)return this;if(null!=t){var r=t._private;if(S(e)){if(n.startBatch(),e.data){t.data(e.data);var i=r.data;if(t.isEdge()){var a=!1,o={},s=e.data.source,l=e.data.target;null!=s&&s!=i.source&&(o.source=""+s,a=!0),null!=l&&l!=i.target&&(o.target=""+l,a=!0),a&&(t=t.move(o))}else{var u="parent"in e.data,c=e.data.parent;!u||null==c&&null==i.parent||c==i.parent||(void 0===c&&(c=null),null!=c&&(c=""+c),t=t.move({parent:c}))}}e.position&&t.position(e.position);var h=function(n,i,a){var o=e[n];null!=o&&o!==r[n]&&(o?t[i]():t[a]())};return h("removed","remove","restore"),h("selected","select","unselect"),h("selectable","selectify","unselectify"),h("locked","lock","unlock"),h("grabbable","grabify","ungrabify"),h("pannable","panify","unpanify"),null!=e.classes&&t.classes(e.classes),n.endBatch(),this}if(void 0===e){var d={data:Le(r.data),position:Le(r.position),group:r.group,removed:r.removed,selected:r.selected,selectable:r.selectable,locked:r.locked,grabbable:r.grabbable,pannable:r.pannable,classes:null};d.classes="";var p=0;return r.classes.forEach((function(e){return d.classes+=0==p++?e:" "+e})),d}}},Ca.jsons=function(){for(var e=[],t=0;t<this.length;t++){var n=this[t].json();e.push(n)}return e},Ca.clone=function(){for(var e=this.cy(),t=[],n=0;n<this.length;n++){var r=this[n].json(),i=new Ye(e,r,!1);t.push(i)}return new Da(e,t)},Ca.copy=Ca.clone,Ca.restore=function(){for(var e,t,n=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=this,a=i.cy(),o=a._private,s=[],l=[],u=0,c=i.length;u<c;u++){var h=i[u];r&&!h.removed()||(h.isNode()?s.push(h):l.push(h))}e=s.concat(l);var d=function(){e.splice(t,1),t--};for(t=0;t<e.length;t++){var p=e[t],g=p._private,f=g.data;if(p.clearTraversalCache(),r||g.removed)if(void 0===f.id)f.id=ke();else if(I(f.id))f.id=""+f.id;else{if(z(f.id)||!A(f.id)){Ce("Can not create element with invalid string ID `"+f.id+"`"),d();continue}if(a.hasElementWithId(f.id)){Ce("Can not create second element with ID `"+f.id+"`"),d();continue}}else;var v=f.id;if(p.isNode()){var y=g.position;null==y.x&&(y.x=0),null==y.y&&(y.y=0)}if(p.isEdge()){for(var m=p,b=["source","target"],x=b.length,w=!1,E=0;E<x;E++){var _=b[E],T=f[_];I(T)&&(T=f[_]=""+f[_]),null==T||""===T?(Ce("Can not create edge `"+v+"` with unspecified "+_),w=!0):a.hasElementWithId(T)||(Ce("Can not create edge `"+v+"` with nonexistant "+_+" `"+T+"`"),w=!0)}if(w){d();continue}var D=a.getElementById(f.source),C=a.getElementById(f.target);D.same(C)?D._private.edges.push(m):(D._private.edges.push(m),C._private.edges.push(m)),m._private.source=D,m._private.target=C}g.map=new Fe,g.map.set(v,{ele:p,index:0}),g.removed=!1,r&&a.addToPool(p)}for(var N=0;N<s.length;N++){var L=s[N],k=L._private.data;I(k.parent)&&(k.parent=""+k.parent);var S=k.parent;if(null!=S||L._private.parent){var M=L._private.parent?a.collection().merge(L._private.parent):a.getElementById(S);if(M.empty())k.parent=void 0;else if(M[0].removed())Ae("Node added with missing parent, reference to parent removed"),k.parent=void 0,L._private.parent=null;else{for(var O=!1,P=M;!P.empty();){if(L.same(P)){O=!0,k.parent=void 0;break}P=P.parent()}O||(M[0]._private.children.push(L),L._private.parent=M[0],o.hasCompoundNodes=!0)}}}if(e.length>0){for(var R=e.length===i.length?i:new Da(a,e),B=0;B<R.length;B++){var F=R[B];F.isNode()||(F.parallelEdges().clearTraversalCache(),F.source().clearTraversalCache(),F.target().clearTraversalCache())}(o.hasCompoundNodes?a.collection().merge(R).merge(R.connectedNodes()).merge(R.parent()):R).dirtyCompoundBoundsCache().dirtyBoundingBoxCache().updateStyle(n),n?R.emitAndNotify("add"):r&&R.emit("add")}return i},Ca.removed=function(){var e=this[0];return e&&e._private.removed},Ca.inside=function(){var e=this[0];return e&&!e._private.removed},Ca.remove=function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this,r=[],i={},a=n._private.cy;function o(e){var n=i[e.id()];t&&e.removed()||n||(i[e.id()]=!0,e.isNode()?(r.push(e),function(e){for(var t=e._private.edges,n=0;n<t.length;n++)o(t[n])}(e),function(e){for(var t=e._private.children,n=0;n<t.length;n++)o(t[n])}(e)):r.unshift(e))}for(var s=0,l=n.length;s<l;s++){o(n[s])}function u(e,t){var n=e._private.edges;Oe(n,t),e.clearTraversalCache()}function c(e){e.clearTraversalCache()}var h=[];function d(e,t){t=t[0];var n=(e=e[0])._private.children,r=e.id();Oe(n,t),t._private.parent=null,h.ids[r]||(h.ids[r]=!0,h.push(e))}h.ids={},n.dirtyCompoundBoundsCache(),t&&a.removeFromPool(r);for(var p=0;p<r.length;p++){var g=r[p];if(g.isEdge()){var f=g.source()[0],v=g.target()[0];u(f,g),u(v,g);for(var y=g.parallelEdges(),m=0;m<y.length;m++){var b=y[m];c(b),b.isBundledBezier()&&b.dirtyBoundingBoxCache()}}else{var x=g.parent();0!==x.length&&d(x,g)}t&&(g._private.removed=!0)}var w=a._private.elements;a._private.hasCompoundNodes=!1;for(var E=0;E<w.length;E++){if(w[E].isParent()){a._private.hasCompoundNodes=!0;break}}var _=new Da(this.cy(),r);_.size()>0&&(e?_.emitAndNotify("remove"):t&&_.emit("remove"));for(var T=0;T<h.length;T++){var D=h[T];t&&D.removed()||D.updateStyle()}return _},Ca.move=function(e){var t=this._private.cy,n=this,r=!1,i=!1,a=function(e){return null==e?e:""+e};if(void 0!==e.source||void 0!==e.target){var o=a(e.source),s=a(e.target),l=null!=o&&t.hasElementWithId(o),u=null!=s&&t.hasElementWithId(s);(l||u)&&(t.batch((function(){n.remove(r,i),n.emitAndNotify("moveout");for(var e=0;e<n.length;e++){var t=n[e],a=t._private.data;t.isEdge()&&(l&&(a.source=o),u&&(a.target=s))}n.restore(r,i)})),n.emitAndNotify("move"))}else if(void 0!==e.parent){var c=a(e.parent);if(null===c||t.hasElementWithId(c)){var h=null===c?void 0:c;t.batch((function(){var e=n.remove(r,i);e.emitAndNotify("moveout");for(var t=0;t<n.length;t++){var a=n[t],o=a._private.data;a.isNode()&&(o.parent=h)}e.restore(r,i)})),n.emitAndNotify("move")}}return this},[Kn,cr,hr,$r,Jr,oi,si,Pi,Ki,Zi,{isNode:function(){return"nodes"===this.group()},isEdge:function(){return"edges"===this.group()},isLoop:function(){return this.isEdge()&&this.source()[0]===this.target()[0]},isSimple:function(){return this.isEdge()&&this.source()[0]!==this.target()[0]},group:function(){var e=this[0];if(e)return e._private.group}},ea,ra,sa,fa,ma].forEach((function(e){Q(Ca,e)}));var Na={add:function(e){var t,n=this;if(O(e)){var r=e;if(r._private.cy===n)t=r.restore();else{for(var i=[],a=0;a<r.length;a++){var o=r[a];i.push(o.json())}t=new Da(n,i)}}else if(k(e)){t=new Da(n,e)}else if(S(e)&&(k(e.nodes)||k(e.edges))){for(var s=e,l=[],u=["nodes","edges"],c=0,h=u.length;c<h;c++){var d=u[c],p=s[d];if(k(p))for(var g=0,f=p.length;g<f;g++){var v=Q({group:d},p[g]);l.push(v)}}t=new Da(n,l)}else{t=new Ye(n,e).collection()}return t},remove:function(e){if(O(e));else if(A(e)){var t=e;e=this.$(t)}return e.remove()}};function Aa(e,t,n,r){var i=4,a=1e-7,o=10,s=11,l=1/(s-1),u="undefined"!=typeof Float32Array;if(4!==arguments.length)return!1;for(var c=0;c<4;++c)if("number"!=typeof arguments[c]||isNaN(arguments[c])||!isFinite(arguments[c]))return!1;e=Math.min(e,1),n=Math.min(n,1),e=Math.max(e,0),n=Math.max(n,0);var h=u?new Float32Array(s):new Array(s);function d(e,t){return 1-3*t+3*e}function p(e,t){return 3*t-6*e}function g(e){return 3*e}function f(e,t,n){return((d(t,n)*e+p(t,n))*e+g(t))*e}function v(e,t,n){return 3*d(t,n)*e*e+2*p(t,n)*e+g(t)}function y(t){for(var r=0,u=1,c=s-1;u!==c&&h[u]<=t;++u)r+=l;--u;var d=r+(t-h[u])/(h[u+1]-h[u])*l,p=v(d,e,n);return p>=.001?function(t,r){for(var a=0;a<i;++a){var o=v(r,e,n);if(0===o)return r;r-=(f(r,e,n)-t)/o}return r}(t,d):0===p?d:function(t,r,i){var s,l,u=0;do{(s=f(l=r+(i-r)/2,e,n)-t)>0?i=l:r=l}while(Math.abs(s)>a&&++u<o);return l}(t,r,r+l)}var m=!1;function b(){m=!0,e===t&&n===r||function(){for(var t=0;t<s;++t)h[t]=f(t*l,e,n)}()}var x=function(i){return m||b(),e===t&&n===r?i:0===i?0:1===i?1:f(y(i),t,r)};x.getControlPoints=function(){return[{x:e,y:t},{x:n,y:r}]};var w="generateBezier("+[e,t,n,r]+")";return x.toString=function(){return w},x}var La=function(){function e(e){return-e.tension*e.x-e.friction*e.v}function t(t,n,r){var i={x:t.x+r.dx*n,v:t.v+r.dv*n,tension:t.tension,friction:t.friction};return{dx:i.v,dv:e(i)}}function n(n,r){var i={dx:n.v,dv:e(n)},a=t(n,.5*r,i),o=t(n,.5*r,a),s=t(n,r,o),l=1/6*(i.dx+2*(a.dx+o.dx)+s.dx),u=1/6*(i.dv+2*(a.dv+o.dv)+s.dv);return n.x=n.x+l*r,n.v=n.v+u*r,n}return function e(t,r,i){var a,o,s,l={x:-1,v:0,tension:null,friction:null},u=[0],c=0,h=1e-4;for(t=parseFloat(t)||500,r=parseFloat(r)||20,i=i||null,l.tension=t,l.friction=r,o=(a=null!==i)?(c=e(t,r))/i*.016:.016;s=n(s||l,o),u.push(1+s.x),c+=16,Math.abs(s.x)>h&&Math.abs(s.v)>h;);return a?function(e){return u[e*(u.length-1)|0]}:c}}(),ka=function(e,t,n,r){var i=Aa(e,t,n,r);return function(e,t,n){return e+(t-e)*i(n)}},Sa={linear:function(e,t,n){return e+(t-e)*n},ease:ka(.25,.1,.25,1),"ease-in":ka(.42,0,1,1),"ease-out":ka(0,0,.58,1),"ease-in-out":ka(.42,0,.58,1),"ease-in-sine":ka(.47,0,.745,.715),"ease-out-sine":ka(.39,.575,.565,1),"ease-in-out-sine":ka(.445,.05,.55,.95),"ease-in-quad":ka(.55,.085,.68,.53),"ease-out-quad":ka(.25,.46,.45,.94),"ease-in-out-quad":ka(.455,.03,.515,.955),"ease-in-cubic":ka(.55,.055,.675,.19),"ease-out-cubic":ka(.215,.61,.355,1),"ease-in-out-cubic":ka(.645,.045,.355,1),"ease-in-quart":ka(.895,.03,.685,.22),"ease-out-quart":ka(.165,.84,.44,1),"ease-in-out-quart":ka(.77,0,.175,1),"ease-in-quint":ka(.755,.05,.855,.06),"ease-out-quint":ka(.23,1,.32,1),"ease-in-out-quint":ka(.86,0,.07,1),"ease-in-expo":ka(.95,.05,.795,.035),"ease-out-expo":ka(.19,1,.22,1),"ease-in-out-expo":ka(1,0,0,1),"ease-in-circ":ka(.6,.04,.98,.335),"ease-out-circ":ka(.075,.82,.165,1),"ease-in-out-circ":ka(.785,.135,.15,.86),spring:function(e,t,n){if(0===n)return Sa.linear;var r=La(e,t,n);return function(e,t,n){return e+(t-e)*r(n)}},"cubic-bezier":ka};function Ia(e,t,n,r,i){if(1===r)return n;if(t===n)return n;var a=i(t,n,r);return null==e||((e.roundValue||e.color)&&(a=Math.round(a)),void 0!==e.min&&(a=Math.max(a,e.min)),void 0!==e.max&&(a=Math.min(a,e.max))),a}function Ma(e,t){return null!=e.pfValue||null!=e.value?null==e.pfValue||null!=t&&"%"===t.type.units?e.value:e.pfValue:e}function Oa(e,t,n,r,i){var a=null!=i?i.type:null;n<0?n=0:n>1&&(n=1);var o=Ma(e,i),s=Ma(t,i);if(I(o)&&I(s))return Ia(a,o,s,n,r);if(k(o)&&k(s)){for(var l=[],u=0;u<s.length;u++){var c=o[u],h=s[u];if(null!=c&&null!=h){var d=Ia(a,c,h,n,r);l.push(d)}else l.push(h)}return l}}function Pa(e,t,n,r){var i=!r,a=e._private,o=t._private,s=o.easing,l=o.startTime,u=(r?e:e.cy()).style();if(!o.easingImpl)if(null==s)o.easingImpl=Sa.linear;else{var c,h,d;if(A(s))c=u.parse("transition-timing-function",s).value;else c=s;A(c)?(h=c,d=[]):(h=c[1],d=c.slice(2).map((function(e){return+e}))),d.length>0?("spring"===h&&d.push(o.duration),o.easingImpl=Sa[h].apply(null,d)):o.easingImpl=Sa[h]}var p,g=o.easingImpl;if(p=0===o.duration?1:(n-l)/o.duration,o.applying&&(p=o.progress),p<0?p=0:p>1&&(p=1),null==o.delay){var f=o.startPosition,v=o.position;if(v&&i&&!e.locked()){var y={};Ra(f.x,v.x)&&(y.x=Oa(f.x,v.x,p,g)),Ra(f.y,v.y)&&(y.y=Oa(f.y,v.y,p,g)),e.position(y)}var m=o.startPan,b=o.pan,x=a.pan,w=null!=b&&r;w&&(Ra(m.x,b.x)&&(x.x=Oa(m.x,b.x,p,g)),Ra(m.y,b.y)&&(x.y=Oa(m.y,b.y,p,g)),e.emit("pan"));var E=o.startZoom,_=o.zoom,T=null!=_&&r;T&&(Ra(E,_)&&(a.zoom=gt(a.minZoom,Oa(E,_,p,g),a.maxZoom)),e.emit("zoom")),(w||T)&&e.emit("viewport");var D=o.style;if(D&&D.length>0&&i){for(var C=0;C<D.length;C++){var N=D[C],L=N.name,k=N,S=o.startStyle[L],I=Oa(S,k,p,g,u.properties[S.name]);u.overrideBypass(e,L,I)}e.emit("style")}}return o.progress=p,p}function Ra(e,t){return null!=e&&null!=t&&(!(!I(e)||!I(t))||!(!e||!t))}function Ba(e,t,n,r){var i=t._private;i.started=!0,i.startTime=n-i.progress*i.duration}function Fa(e,t){var n=t._private.aniEles,r=[];function i(t,n){var i=t._private,a=i.animation.current,o=i.animation.queue,s=!1;if(0===a.length){var l=o.shift();l&&a.push(l)}for(var u=function(e){for(var t=e.length-1;t>=0;t--){(0,e[t])()}e.splice(0,e.length)},c=a.length-1;c>=0;c--){var h=a[c],d=h._private;d.stopped?(a.splice(c,1),d.hooked=!1,d.playing=!1,d.started=!1,u(d.frames)):(d.playing||d.applying)&&(d.playing&&d.applying&&(d.applying=!1),d.started||Ba(0,h,e),Pa(t,h,e,n),d.applying&&(d.applying=!1),u(d.frames),null!=d.step&&d.step(e),h.completed()&&(a.splice(c,1),d.hooked=!1,d.playing=!1,d.started=!1,u(d.completes)),s=!0)}return n||0!==a.length||0!==o.length||r.push(t),s}for(var a=!1,o=0;o<n.length;o++){var s=i(n[o]);a=a||s}var l=i(t,!0);(a||l)&&(n.length>0?t.notify("draw",n):t.notify("draw")),n.unmerge(r),t.emit("step")}var za={animate:ur.animate(),animation:ur.animation(),animated:ur.animated(),clearQueue:ur.clearQueue(),delay:ur.delay(),delayAnimation:ur.delayAnimation(),stop:ur.stop(),addToAnimationPool:function(e){this.styleEnabled()&&this._private.aniEles.merge(e)},stopAnimationLoop:function(){this._private.animationsRunning=!1},startAnimationLoop:function(){var e=this;if(e._private.animationsRunning=!0,e.styleEnabled()){var t=e.renderer();t&&t.beforeRender?t.beforeRender((function(t,n){Fa(n,e)}),t.beforeRenderPriorities.animations):function t(){e._private.animationsRunning&&oe((function(n){Fa(n,e),t()}))}()}}},Ga={qualifierCompare:function(e,t){return null==e||null==t?null==e&&null==t:e.sameText(t)},eventMatches:function(e,t,n){var r=t.qualifier;return null==r||e!==n.target&&P(n.target)&&r.matches(n.target)},addEventFields:function(e,t){t.cy=e,t.target=e},callbackContext:function(e,t,n){return null!=t.qualifier?n.target:e}},Ya=function(e){return A(e)?new Hr(e):e},Xa={createEmitter:function(){var e=this._private;return e.emitter||(e.emitter=new Vi(Ga,this)),this},emitter:function(){return this._private.emitter},on:function(e,t,n){return this.emitter().on(e,Ya(t),n),this},removeListener:function(e,t,n){return this.emitter().removeListener(e,Ya(t),n),this},removeAllListeners:function(){return this.emitter().removeAllListeners(),this},one:function(e,t,n){return this.emitter().one(e,Ya(t),n),this},once:function(e,t,n){return this.emitter().one(e,Ya(t),n),this},emit:function(e,t){return this.emitter().emit(e,t),this},emitAndNotify:function(e,t){return this.emit(e),this.notify(e,t),this}};ur.eventAliasesOn(Xa);var Va={png:function(e){return e=e||{},this._private.renderer.png(e)},jpg:function(e){var t=this._private.renderer;return(e=e||{}).bg=e.bg||"#fff",t.jpg(e)}};Va.jpeg=Va.jpg;var Ua={layout:function(e){var t=this;if(null!=e)if(null!=e.name){var n=e.name,r=t.extension("layout",n);if(null!=r){var i;i=A(e.eles)?t.$(e.eles):null!=e.eles?e.eles:t.$();var a=new r(Q({},e,{cy:t,eles:i}));return a}Ce("No such layout `"+n+"` found. Did you forget to import it and `cytoscape.use()` it?")}else Ce("A `name` must be specified to make a layout");else Ce("Layout options must be specified to make a layout")}};Ua.createLayout=Ua.makeLayout=Ua.layout;var ja={notify:function(e,t){var n=this._private;if(this.batching()){n.batchNotifications=n.batchNotifications||{};var r=n.batchNotifications[e]=n.batchNotifications[e]||this.collection();null!=t&&r.merge(t)}else if(n.notificationsEnabled){var i=this.renderer();!this.destroyed()&&i&&i.notify(e,t)}},notifications:function(e){var t=this._private;return void 0===e?t.notificationsEnabled:(t.notificationsEnabled=!!e,this)},noNotifications:function(e){this.notifications(!1),e(),this.notifications(!0)},batching:function(){return this._private.batchCount>0},startBatch:function(){var e=this._private;return null==e.batchCount&&(e.batchCount=0),0===e.batchCount&&(e.batchStyleEles=this.collection(),e.batchNotifications={}),e.batchCount++,this},endBatch:function(){var e=this._private;if(0===e.batchCount)return this;if(e.batchCount--,0===e.batchCount){e.batchStyleEles.updateStyle();var t=this.renderer();Object.keys(e.batchNotifications).forEach((function(n){var r=e.batchNotifications[n];r.empty()?t.notify(n):t.notify(n,r)}))}return this},batch:function(e){return this.startBatch(),e(),this.endBatch(),this},batchData:function(e){var t=this;return this.batch((function(){for(var n=Object.keys(e),r=0;r<n.length;r++){var i=n[r],a=e[i];t.getElementById(i).data(a)}}))}},qa=Me({hideEdgesOnViewport:!1,textureOnViewport:!1,motionBlur:!1,motionBlurOpacity:.05,pixelRatio:void 0,desktopTapThreshold:4,touchTapThreshold:8,wheelSensitivity:1,debug:!1,showFps:!1}),Ha={renderTo:function(e,t,n,r){return this._private.renderer.renderTo(e,t,n,r),this},renderer:function(){return this._private.renderer},forceRender:function(){return this.notify("draw"),this},resize:function(){return this.invalidateSize(),this.emitAndNotify("resize"),this},initRenderer:function(e){var t=this,n=t.extension("renderer",e.name);if(null!=n){void 0!==e.wheelSensitivity&&Ae("You have set a custom wheel sensitivity. This will make your app zoom unnaturally when using mainstream mice. You should change this value from the default only if you can guarantee that all your users will use the same hardware and OS configuration as your current machine.");var r=qa(e);r.cy=t,t._private.renderer=new n(r),this.notify("init")}else Ce("Can not initialise: No such renderer `".concat(e.name,"` found. Did you forget to import it and `cytoscape.use()` it?"))},destroyRenderer:function(){var e=this;e.notify("destroy");var t=e.container();if(t)for(t._cyreg=null;t.childNodes.length>0;)t.removeChild(t.childNodes[0]);e._private.renderer=null,e.mutableElements().forEach((function(e){var t=e._private;t.rscratch={},t.rstyle={},t.animation.current=[],t.animation.queue=[]}))},onRender:function(e){return this.on("render",e)},offRender:function(e){return this.off("render",e)}};Ha.invalidateDimensions=Ha.resize;var Wa={collection:function(e,t){return A(e)?this.$(e):O(e)?e.collection():k(e)?(t||(t={}),new Da(this,e,t.unique,t.removed)):new Da(this)},nodes:function(e){var t=this.$((function(e){return e.isNode()}));return e?t.filter(e):t},edges:function(e){var t=this.$((function(e){return e.isEdge()}));return e?t.filter(e):t},$:function(e){var t=this._private.elements;return e?t.filter(e):t.spawnSelf()},mutableElements:function(){return this._private.elements}};Wa.elements=Wa.filter=Wa.$;var $a={},Ka="t";$a.apply=function(e){for(var t=this,n=t._private.cy.collection(),r=0;r<e.length;r++){var i=e[r],a=t.getContextMeta(i);if(!a.empty){var o=t.getContextStyle(a),s=t.applyContextStyle(a,o,i);i._private.appliedInitStyle?t.updateTransitions(i,s.diffProps):i._private.appliedInitStyle=!0,t.updateStyleHints(i)&&n.push(i)}}return n},$a.getPropertiesDiff=function(e,t){var n=this,r=n._private.propDiffs=n._private.propDiffs||{},i=e+"-"+t,a=r[i];if(a)return a;for(var o=[],s={},l=0;l<n.length;l++){var u=n[l],c=e[l]===Ka,h=t[l]===Ka,d=c!==h,p=u.mappedProperties.length>0;if(d||h&&p){var g=void 0;d&&p||d?g=u.properties:p&&(g=u.mappedProperties);for(var f=0;f<g.length;f++){for(var v=g[f],y=v.name,m=!1,b=l+1;b<n.length;b++){var x=n[b];if(t[b]===Ka&&(m=null!=x.properties[v.name]))break}s[y]||m||(s[y]=!0,o.push(y))}}}return r[i]=o,o},$a.getContextMeta=function(e){for(var t,n=this,r="",i=e._private.styleCxtKey||"",a=0;a<n.length;a++){var o=n[a];r+=o.selector&&o.selector.matches(e)?Ka:"f"}return t=n.getPropertiesDiff(i,r),e._private.styleCxtKey=r,{key:r,diffPropNames:t,empty:0===t.length}},$a.getContextStyle=function(e){var t=e.key,n=this._private.contextStyles=this._private.contextStyles||{};if(n[t])return n[t];for(var r={_private:{key:t}},i=0;i<this.length;i++){var a=this[i];if(t[i]===Ka)for(var o=0;o<a.properties.length;o++){var s=a.properties[o];r[s.name]=s}}return n[t]=r,r},$a.applyContextStyle=function(e,t,n){for(var r=e.diffPropNames,i={},a=this.types,o=0;o<r.length;o++){var s=r[o],l=t[s],u=n.pstyle(s);if(!l){if(!u)continue;l=u.bypass?{name:s,deleteBypassed:!0}:{name:s,delete:!0}}if(u!==l){if(l.mapped===a.fn&&null!=u&&null!=u.mapping&&u.mapping.value===l.value){var c=u.mapping;if((c.fnValue=l.value(n))===c.prevFnValue)continue}var h=i[s]={prev:u};this.applyParsedProperty(n,l),h.next=n.pstyle(s),h.next&&h.next.bypass&&(h.next=h.next.bypassed)}}return{diffProps:i}},$a.updateStyleHints=function(e){var t=e._private,n=this,r=n.propertyGroupNames,i=n.propertyGroupKeys,a=function(e,t,r){return n.getPropertiesHash(e,t,r)},o=t.styleKey;if(e.removed())return!1;var s="nodes"===t.group,l=e._private.style;r=Object.keys(l);for(var u=0;u<i.length;u++){var c=i[u];t.styleKeys[c]=[le,ue]}for(var h,d=function(e,n){return t.styleKeys[n][0]=he(e,t.styleKeys[n][0])},p=function(e,n){return t.styleKeys[n][1]=de(e,t.styleKeys[n][1])},g=function(e,t){d(e,t),p(e,t)},f=function(e,t){for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);d(r,t),p(r,t)}},v=0;v<r.length;v++){var y=r[v],m=l[y];if(null!=m){var b=this.properties[y],x=b.type,w=b.groupKey,E=void 0;null!=b.hashOverride?E=b.hashOverride(e,m):null!=m.pfValue&&(E=m.pfValue);var _=null==b.enums?m.value:null,T=null!=E,D=T||null!=_,C=m.units;if(x.number&&D&&!x.multiple)g(-128<(h=T?E:_)&&h<128&&Math.floor(h)!==h?2e9-(1024*h|0):h,w),T||null==C||f(C,w);else f(m.strValue,w)}}for(var N,A,L=[le,ue],k=0;k<i.length;k++){var S=i[k],I=t.styleKeys[S];L[0]=he(I[0],L[0]),L[1]=de(I[1],L[1])}t.styleKey=(N=L[0],A=L[1],2097152*N+A);var M=t.styleKeys;t.labelDimsKey=pe(M.labelDimensions);var O=a(e,["label"],M.labelDimensions);if(t.labelKey=pe(O),t.labelStyleKey=pe(ge(M.commonLabel,O)),!s){var P=a(e,["source-label"],M.labelDimensions);t.sourceLabelKey=pe(P),t.sourceLabelStyleKey=pe(ge(M.commonLabel,P));var R=a(e,["target-label"],M.labelDimensions);t.targetLabelKey=pe(R),t.targetLabelStyleKey=pe(ge(M.commonLabel,R))}if(s){var B=t.styleKeys,F=B.nodeBody,z=B.nodeBorder,G=B.nodeOutline,Y=B.backgroundImage,X=B.compound,V=B.pie,U=[F,z,G,Y,X,V].filter((function(e){return null!=e})).reduce(ge,[le,ue]);t.nodeKey=pe(U),t.hasPie=null!=V&&V[0]!==le&&V[1]!==ue}return o!==t.styleKey},$a.clearStyleHints=function(e){var t=e._private;t.styleCxtKey="",t.styleKeys={},t.styleKey=null,t.labelKey=null,t.labelStyleKey=null,t.sourceLabelKey=null,t.sourceLabelStyleKey=null,t.targetLabelKey=null,t.targetLabelStyleKey=null,t.nodeKey=null,t.hasPie=null},$a.applyParsedProperty=function(e,t){var n,r=this,i=t,a=e._private.style,o=r.types,s=r.properties[i.name].type,l=i.bypass,u=a[i.name],c=u&&u.bypass,h=e._private,d="mapping",p=function(e){return null==e?null:null!=e.pfValue?e.pfValue:e.value},g=function(){var t=p(u),n=p(i);r.checkTriggers(e,i.name,t,n)};if("curve-style"===t.name&&e.isEdge()&&("bezier"!==t.value&&e.isLoop()||"haystack"===t.value&&(e.source().isParent()||e.target().isParent()))&&(i=t=this.parse(t.name,"bezier",l)),i.delete)return a[i.name]=void 0,g(),!0;if(i.deleteBypassed)return u?!!u.bypass&&(u.bypassed=void 0,g(),!0):(g(),!0);if(i.deleteBypass)return u?!!u.bypass&&(a[i.name]=u.bypassed,g(),!0):(g(),!0);var f=function(){Ae("Do not assign mappings to elements without corresponding data (i.e. ele `"+e.id()+"` has no mapping for property `"+i.name+"` with data field `"+i.field+"`); try a `["+i.field+"]` selector to limit scope to elements with `"+i.field+"` defined")};switch(i.mapped){case o.mapData:for(var v,y=i.field.split("."),m=h.data,b=0;b<y.length&&m;b++){m=m[y[b]]}if(null==m)return f(),!1;if(!I(m))return Ae("Do not use continuous mappers without specifying numeric data (i.e. `"+i.field+": "+m+"` for `"+e.id()+"` is non-numeric)"),!1;var x=i.fieldMax-i.fieldMin;if((v=0===x?0:(m-i.fieldMin)/x)<0?v=0:v>1&&(v=1),s.color){var w=i.valueMin[0],E=i.valueMax[0],_=i.valueMin[1],T=i.valueMax[1],D=i.valueMin[2],C=i.valueMax[2],N=null==i.valueMin[3]?1:i.valueMin[3],A=null==i.valueMax[3]?1:i.valueMax[3],L=[Math.round(w+(E-w)*v),Math.round(_+(T-_)*v),Math.round(D+(C-D)*v),Math.round(N+(A-N)*v)];n={bypass:i.bypass,name:i.name,value:L,strValue:"rgb("+L[0]+", "+L[1]+", "+L[2]+")"}}else{if(!s.number)return!1;var k=i.valueMin+(i.valueMax-i.valueMin)*v;n=this.parse(i.name,k,i.bypass,d)}if(!n)return f(),!1;n.mapping=i,i=n;break;case o.data:for(var S=i.field.split("."),M=h.data,O=0;O<S.length&&M;O++){M=M[S[O]]}if(null!=M&&(n=this.parse(i.name,M,i.bypass,d)),!n)return f(),!1;n.mapping=i,i=n;break;case o.fn:var P=i.value,R=null!=i.fnValue?i.fnValue:P(e);if(i.prevFnValue=R,null==R)return Ae("Custom function mappers may not return null (i.e. `"+i.name+"` for ele `"+e.id()+"` is null)"),!1;if(!(n=this.parse(i.name,R,i.bypass,d)))return Ae("Custom function mappers may not return invalid values for the property type (i.e. `"+i.name+"` for ele `"+e.id()+"` is invalid)"),!1;n.mapping=Le(i),i=n;break;case void 0:break;default:return!1}return l?(i.bypassed=c?u.bypassed:u,a[i.name]=i):c?u.bypassed=i:a[i.name]=i,g(),!0},$a.cleanElements=function(e,t){for(var n=0;n<e.length;n++){var r=e[n];if(this.clearStyleHints(r),r.dirtyCompoundBoundsCache(),r.dirtyBoundingBoxCache(),t)for(var i=r._private.style,a=Object.keys(i),o=0;o<a.length;o++){var s=a[o],l=i[s];null!=l&&(l.bypass?l.bypassed=null:i[s]=null)}else r._private.style={}}},$a.update=function(){this._private.cy.mutableElements().updateStyle()},$a.updateTransitions=function(e,t){var n=this,r=e._private,i=e.pstyle("transition-property").value,a=e.pstyle("transition-duration").pfValue,o=e.pstyle("transition-delay").pfValue;if(i.length>0&&a>0){for(var s={},l=!1,u=0;u<i.length;u++){var c=i[u],h=e.pstyle(c),d=t[c];if(d){var p=d.prev,g=null!=d.next?d.next:h,f=!1,v=void 0,y=1e-6;p&&(I(p.pfValue)&&I(g.pfValue)?(f=g.pfValue-p.pfValue,v=p.pfValue+y*f):I(p.value)&&I(g.value)?(f=g.value-p.value,v=p.value+y*f):k(p.value)&&k(g.value)&&(f=p.value[0]!==g.value[0]||p.value[1]!==g.value[1]||p.value[2]!==g.value[2],v=p.strValue),f&&(s[c]=g.strValue,this.applyBypass(e,c,v),l=!0))}}if(!l)return;r.transitioning=!0,new rr((function(t){o>0?e.delayAnimation(o).play().promise().then(t):t()})).then((function(){return e.animation({style:s,duration:a,easing:e.pstyle("transition-timing-function").value,queue:!1}).play().promise()})).then((function(){n.removeBypasses(e,i),e.emitAndNotify("style"),r.transitioning=!1}))}else r.transitioning&&(this.removeBypasses(e,i),e.emitAndNotify("style"),r.transitioning=!1)},$a.checkTrigger=function(e,t,n,r,i,a){var o=this.properties[t],s=i(o);null!=s&&s(n,r)&&a(o)},$a.checkZOrderTrigger=function(e,t,n,r){var i=this;this.checkTrigger(e,t,n,r,(function(e){return e.triggersZOrder}),(function(){i._private.cy.notify("zorder",e)}))},$a.checkBoundsTrigger=function(e,t,n,r){this.checkTrigger(e,t,n,r,(function(e){return e.triggersBounds}),(function(i){e.dirtyCompoundBoundsCache(),e.dirtyBoundingBoxCache(),!i.triggersBoundsOfParallelBeziers||"curve-style"!==t||"bezier"!==n&&"bezier"!==r||e.parallelEdges().forEach((function(e){e.isBundledBezier()&&e.dirtyBoundingBoxCache()})),!i.triggersBoundsOfConnectedEdges||"display"!==t||"none"!==n&&"none"!==r||e.connectedEdges().forEach((function(e){e.dirtyBoundingBoxCache()}))}))},$a.checkTriggers=function(e,t,n,r){e.dirtyStyleCache(),this.checkZOrderTrigger(e,t,n,r),this.checkBoundsTrigger(e,t,n,r)};var Za={applyBypass:function(e,t,n,r){var i=[];if("*"===t||"**"===t){if(void 0!==n)for(var a=0;a<this.properties.length;a++){var o=this.properties[a].name,s=this.parse(o,n,!0);s&&i.push(s)}}else if(A(t)){var l=this.parse(t,n,!0);l&&i.push(l)}else{if(!S(t))return!1;var u=t;r=n;for(var c=Object.keys(u),h=0;h<c.length;h++){var d=c[h],p=u[d];if(void 0===p&&(p=u[V(d)]),void 0!==p){var g=this.parse(d,p,!0);g&&i.push(g)}}}if(0===i.length)return!1;for(var f=!1,v=0;v<e.length;v++){for(var y=e[v],m={},b=void 0,x=0;x<i.length;x++){var w=i[x];if(r){var E=y.pstyle(w.name);b=m[w.name]={prev:E}}f=this.applyParsedProperty(y,Le(w))||f,r&&(b.next=y.pstyle(w.name))}f&&this.updateStyleHints(y),r&&this.updateTransitions(y,m,true)}return f},overrideBypass:function(e,t,n){t=X(t);for(var r=0;r<e.length;r++){var i=e[r],a=i._private.style[t],o=this.properties[t].type,s=o.color,l=o.mutiple,u=a?null!=a.pfValue?a.pfValue:a.value:null;a&&a.bypass?(a.value=n,null!=a.pfValue&&(a.pfValue=n),a.strValue=s?"rgb("+n.join(",")+")":l?n.join(" "):""+n,this.updateStyleHints(i)):this.applyBypass(i,t,n),this.checkTriggers(i,t,u,n)}},removeAllBypasses:function(e,t){return this.removeBypasses(e,this.propertyNames,t)},removeBypasses:function(e,t,n){for(var r=0;r<e.length;r++){for(var i=e[r],a={},o=0;o<t.length;o++){var s=t[o],l=this.properties[s],u=i.pstyle(l.name);if(u&&u.bypass){var c=this.parse(s,"",!0),h=a[l.name]={prev:u};this.applyParsedProperty(i,c),h.next=i.pstyle(l.name)}}this.updateStyleHints(i),n&&this.updateTransitions(i,a,true)}}},Qa={getEmSizeInPixels:function(){var e=this.containerCss("font-size");return null!=e?parseFloat(e):1},containerCss:function(e){var t=this._private.cy,n=t.container(),r=t.window();if(r&&n&&r.getComputedStyle)return r.getComputedStyle(n).getPropertyValue(e)}},Ja={getRenderedStyle:function(e,t){return t?this.getStylePropertyValue(e,t,!0):this.getRawStyle(e,!0)},getRawStyle:function(e,t){var n=this;if(e=e[0]){for(var r={},i=0;i<n.properties.length;i++){var a=n.properties[i],o=n.getStylePropertyValue(e,a.name,t);null!=o&&(r[a.name]=o,r[V(a.name)]=o)}return r}},getIndexedStyle:function(e,t,n,r){var i=e.pstyle(t)[n][r];return null!=i?i:e.cy().style().getDefaultProperty(t)[n][0]},getStylePropertyValue:function(e,t,n){if(e=e[0]){var r=this.properties[t];r.alias&&(r=r.pointsTo);var i=r.type,a=e.pstyle(r.name);if(a){var o=a.value,s=a.units,l=a.strValue;if(n&&i.number&&null!=o&&I(o)){var u=e.cy().zoom(),c=function(e){return e*u},h=function(e,t){return c(e)+t},d=k(o);return(d?s.every((function(e){return null!=e})):null!=s)?d?o.map((function(e,t){return h(e,s[t])})).join(" "):h(o,s):d?o.map((function(e){return A(e)?e:""+c(e)})).join(" "):""+c(o)}if(null!=l)return l}return null}},getAnimationStartStyle:function(e,t){for(var n={},r=0;r<t.length;r++){var i=t[r].name,a=e.pstyle(i);void 0!==a&&(a=S(a)?this.parse(i,a.strValue):this.parse(i,a)),a&&(n[i]=a)}return n},getPropsList:function(e){var t=[],n=e,r=this.properties;if(n)for(var i=Object.keys(n),a=0;a<i.length;a++){var o=i[a],s=n[o],l=r[o]||r[X(o)],u=this.parse(l.name,s);u&&t.push(u)}return t},getNonDefaultPropertiesHash:function(e,t,n){var r,i,a,o,s,l,u=n.slice();for(s=0;s<t.length;s++)if(r=t[s],null!=(i=e.pstyle(r,!1)))if(null!=i.pfValue)u[0]=he(o,u[0]),u[1]=de(o,u[1]);else for(a=i.strValue,l=0;l<a.length;l++)o=a.charCodeAt(l),u[0]=he(o,u[0]),u[1]=de(o,u[1]);return u}};Ja.getPropertiesHash=Ja.getNonDefaultPropertiesHash;var eo={appendFromJson:function(e){for(var t=this,n=0;n<e.length;n++){var r=e[n],i=r.selector,a=r.style||r.css,o=Object.keys(a);t.selector(i);for(var s=0;s<o.length;s++){var l=o[s],u=a[l];t.css(l,u)}}return t},fromJson:function(e){var t=this;return t.resetToDefault(),t.appendFromJson(e),t},json:function(){for(var e=[],t=this.defaultLength;t<this.length;t++){for(var n=this[t],r=n.selector,i=n.properties,a={},o=0;o<i.length;o++){var s=i[o];a[s.name]=s.strValue}e.push({selector:r?r.toString():"core",style:a})}return e}},to={appendFromString:function(e){var t,n,r,i=this,a=""+e;function o(){a=a.length>t.length?a.substr(t.length):""}function s(){n=n.length>r.length?n.substr(r.length):""}for(a=a.replace(/[/][*](\s|.)+?[*][/]/g,"");;){if(a.match(/^\s*$/))break;var l=a.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!l){Ae("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+a);break}t=l[0];var u=l[1];if("core"!==u)if(new Hr(u).invalid){Ae("Skipping parsing of block: Invalid selector found in string stylesheet: "+u),o();continue}var c=l[2],h=!1;n=c;for(var d=[];;){if(n.match(/^\s*$/))break;var p=n.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);if(!p){Ae("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+c),h=!0;break}r=p[0];var g=p[1],f=p[2];if(this.properties[g])i.parse(g,f)?(d.push({name:g,val:f}),s()):(Ae("Skipping property: Invalid property definition in: "+r),s());else Ae("Skipping property: Invalid property name in: "+r),s()}if(h){o();break}i.selector(u);for(var v=0;v<d.length;v++){var y=d[v];i.css(y.name,y.val)}o()}return i},fromString:function(e){var t=this;return t.resetToDefault(),t.appendFromString(e),t}},no={};!function(){var e=q,t=W,n=K,r=function(e){return"^"+e+"\\s*\\(\\s*([\\w\\.]+)\\s*\\)$"},i=function(r){var i=e+"|\\w+|"+t+"|"+n+"|\\#[0-9a-fA-F]{3}|\\#[0-9a-fA-F]{6}";return"^"+r+"\\s*\\(([\\w\\.]+)\\s*\\,\\s*("+e+")\\s*\\,\\s*("+e+")\\s*,\\s*("+i+")\\s*\\,\\s*("+i+")\\)$"},a=["^url\\s*\\(\\s*['\"]?(.+?)['\"]?\\s*\\)$","^(none)$","^(.+)$"];no.types={time:{number:!0,min:0,units:"s|ms",implicitUnits:"ms"},percent:{number:!0,min:0,max:100,units:"%",implicitUnits:"%"},percentages:{number:!0,min:0,max:100,units:"%",implicitUnits:"%",multiple:!0},zeroOneNumber:{number:!0,min:0,max:1,unitless:!0},zeroOneNumbers:{number:!0,min:0,max:1,unitless:!0,multiple:!0},nOneOneNumber:{number:!0,min:-1,max:1,unitless:!0},nonNegativeInt:{number:!0,min:0,integer:!0,unitless:!0},nonNegativeNumber:{number:!0,min:0,unitless:!0},position:{enums:["parent","origin"]},nodeSize:{number:!0,min:0,enums:["label"]},number:{number:!0,unitless:!0},numbers:{number:!0,unitless:!0,multiple:!0},positiveNumber:{number:!0,unitless:!0,min:0,strictMin:!0},size:{number:!0,min:0},bidirectionalSize:{number:!0},bidirectionalSizeMaybePercent:{number:!0,allowPercent:!0},bidirectionalSizes:{number:!0,multiple:!0},sizeMaybePercent:{number:!0,min:0,allowPercent:!0},axisDirection:{enums:["horizontal","leftward","rightward","vertical","upward","downward","auto"]},paddingRelativeTo:{enums:["width","height","average","min","max"]},bgWH:{number:!0,min:0,allowPercent:!0,enums:["auto"],multiple:!0},bgPos:{number:!0,allowPercent:!0,multiple:!0},bgRelativeTo:{enums:["inner","include-padding"],multiple:!0},bgRepeat:{enums:["repeat","repeat-x","repeat-y","no-repeat"],multiple:!0},bgFit:{enums:["none","contain","cover"],multiple:!0},bgCrossOrigin:{enums:["anonymous","use-credentials","null"],multiple:!0},bgClip:{enums:["none","node"],multiple:!0},bgContainment:{enums:["inside","over"],multiple:!0},color:{color:!0},colors:{color:!0,multiple:!0},fill:{enums:["solid","linear-gradient","radial-gradient"]},bool:{enums:["yes","no"]},bools:{enums:["yes","no"],multiple:!0},lineStyle:{enums:["solid","dotted","dashed"]},lineCap:{enums:["butt","round","square"]},borderStyle:{enums:["solid","dotted","dashed","double"]},curveStyle:{enums:["bezier","unbundled-bezier","haystack","segments","straight","straight-triangle","taxi"]},fontFamily:{regex:'^([\\w- \\"]+(?:\\s*,\\s*[\\w- \\"]+)*)$'},fontStyle:{enums:["italic","normal","oblique"]},fontWeight:{enums:["normal","bold","bolder","lighter","100","200","300","400","500","600","800","900",100,200,300,400,500,600,700,800,900]},textDecoration:{enums:["none","underline","overline","line-through"]},textTransform:{enums:["none","uppercase","lowercase"]},textWrap:{enums:["none","wrap","ellipsis"]},textOverflowWrap:{enums:["whitespace","anywhere"]},textBackgroundShape:{enums:["rectangle","roundrectangle","round-rectangle"]},nodeShape:{enums:["rectangle","roundrectangle","round-rectangle","cutrectangle","cut-rectangle","bottomroundrectangle","bottom-round-rectangle","barrel","ellipse","triangle","round-triangle","square","pentagon","round-pentagon","hexagon","round-hexagon","concavehexagon","concave-hexagon","heptagon","round-heptagon","octagon","round-octagon","tag","round-tag","star","diamond","round-diamond","vee","rhomboid","right-rhomboid","polygon"]},overlayShape:{enums:["roundrectangle","round-rectangle","ellipse"]},compoundIncludeLabels:{enums:["include","exclude"]},arrowShape:{enums:["tee","triangle","triangle-tee","circle-triangle","triangle-cross","triangle-backcurve","vee","square","circle","diamond","chevron","none"]},arrowFill:{enums:["filled","hollow"]},arrowWidth:{number:!0,units:"%|px|em",implicitUnits:"px",enums:["match-line"]},display:{enums:["element","none"]},visibility:{enums:["hidden","visible"]},zCompoundDepth:{enums:["bottom","orphan","auto","top"]},zIndexCompare:{enums:["auto","manual"]},valign:{enums:["top","center","bottom"]},halign:{enums:["left","center","right"]},justification:{enums:["left","center","right","auto"]},text:{string:!0},data:{mapping:!0,regex:r("data")},layoutData:{mapping:!0,regex:r("layoutData")},scratch:{mapping:!0,regex:r("scratch")},mapData:{mapping:!0,regex:i("mapData")},mapLayoutData:{mapping:!0,regex:i("mapLayoutData")},mapScratch:{mapping:!0,regex:i("mapScratch")},fn:{mapping:!0,fn:!0},url:{regexes:a,singleRegexMatchValue:!0},urls:{regexes:a,singleRegexMatchValue:!0,multiple:!0},propList:{propList:!0},angle:{number:!0,units:"deg|rad",implicitUnits:"rad"},textRotation:{number:!0,units:"deg|rad",implicitUnits:"rad",enums:["none","autorotate"]},polygonPointList:{number:!0,multiple:!0,evenMultiple:!0,min:-1,max:1,unitless:!0},edgeDistances:{enums:["intersection","node-position","endpoints"]},edgeEndpoint:{number:!0,multiple:!0,units:"%|px|em|deg|rad",implicitUnits:"px",enums:["inside-to-node","outside-to-node","outside-to-node-or-label","outside-to-line","outside-to-line-or-label"],singleEnum:!0,validate:function(e,t){switch(e.length){case 2:return"deg"!==t[0]&&"rad"!==t[0]&&"deg"!==t[1]&&"rad"!==t[1];case 1:return A(e[0])||"deg"===t[0]||"rad"===t[0];default:return!1}}},easing:{regexes:["^(spring)\\s*\\(\\s*("+e+")\\s*,\\s*("+e+")\\s*\\)$","^(cubic-bezier)\\s*\\(\\s*("+e+")\\s*,\\s*("+e+")\\s*,\\s*("+e+")\\s*,\\s*("+e+")\\s*\\)$"],enums:["linear","ease","ease-in","ease-out","ease-in-out","ease-in-sine","ease-out-sine","ease-in-out-sine","ease-in-quad","ease-out-quad","ease-in-out-quad","ease-in-cubic","ease-out-cubic","ease-in-out-cubic","ease-in-quart","ease-out-quart","ease-in-out-quart","ease-in-quint","ease-out-quint","ease-in-out-quint","ease-in-expo","ease-out-expo","ease-in-out-expo","ease-in-circ","ease-out-circ","ease-in-out-circ"]},gradientDirection:{enums:["to-bottom","to-top","to-left","to-right","to-bottom-right","to-bottom-left","to-top-right","to-top-left","to-right-bottom","to-left-bottom","to-right-top","to-left-top"]},boundsExpansion:{number:!0,multiple:!0,min:0,validate:function(e){var t=e.length;return 1===t||2===t||4===t}}};var o={zeroNonZero:function(e,t){return(null==e||null==t)&&e!==t||(0==e&&0!=t||0!=e&&0==t)},any:function(e,t){return e!=t},emptyNonEmpty:function(e,t){var n=z(e),r=z(t);return n&&!r||!n&&r}},s=no.types,l=[{name:"label",type:s.text,triggersBounds:o.any,triggersZOrder:o.emptyNonEmpty},{name:"text-rotation",type:s.textRotation,triggersBounds:o.any},{name:"text-margin-x",type:s.bidirectionalSize,triggersBounds:o.any},{name:"text-margin-y",type:s.bidirectionalSize,triggersBounds:o.any}],u=[{name:"source-label",type:s.text,triggersBounds:o.any},{name:"source-text-rotation",type:s.textRotation,triggersBounds:o.any},{name:"source-text-margin-x",type:s.bidirectionalSize,triggersBounds:o.any},{name:"source-text-margin-y",type:s.bidirectionalSize,triggersBounds:o.any},{name:"source-text-offset",type:s.size,triggersBounds:o.any}],c=[{name:"target-label",type:s.text,triggersBounds:o.any},{name:"target-text-rotation",type:s.textRotation,triggersBounds:o.any},{name:"target-text-margin-x",type:s.bidirectionalSize,triggersBounds:o.any},{name:"target-text-margin-y",type:s.bidirectionalSize,triggersBounds:o.any},{name:"target-text-offset",type:s.size,triggersBounds:o.any}],h=[{name:"font-family",type:s.fontFamily,triggersBounds:o.any},{name:"font-style",type:s.fontStyle,triggersBounds:o.any},{name:"font-weight",type:s.fontWeight,triggersBounds:o.any},{name:"font-size",type:s.size,triggersBounds:o.any},{name:"text-transform",type:s.textTransform,triggersBounds:o.any},{name:"text-wrap",type:s.textWrap,triggersBounds:o.any},{name:"text-overflow-wrap",type:s.textOverflowWrap,triggersBounds:o.any},{name:"text-max-width",type:s.size,triggersBounds:o.any},{name:"text-outline-width",type:s.size,triggersBounds:o.any},{name:"line-height",type:s.positiveNumber,triggersBounds:o.any}],d=[{name:"text-valign",type:s.valign,triggersBounds:o.any},{name:"text-halign",type:s.halign,triggersBounds:o.any},{name:"color",type:s.color},{name:"text-outline-color",type:s.color},{name:"text-outline-opacity",type:s.zeroOneNumber},{name:"text-background-color",type:s.color},{name:"text-background-opacity",type:s.zeroOneNumber},{name:"text-background-padding",type:s.size,triggersBounds:o.any},{name:"text-border-opacity",type:s.zeroOneNumber},{name:"text-border-color",type:s.color},{name:"text-border-width",type:s.size,triggersBounds:o.any},{name:"text-border-style",type:s.borderStyle,triggersBounds:o.any},{name:"text-background-shape",type:s.textBackgroundShape,triggersBounds:o.any},{name:"text-justification",type:s.justification}],p=[{name:"events",type:s.bool,triggersZOrder:o.any},{name:"text-events",type:s.bool,triggersZOrder:o.any}],g=[{name:"display",type:s.display,triggersZOrder:o.any,triggersBounds:o.any,triggersBoundsOfConnectedEdges:!0},{name:"visibility",type:s.visibility,triggersZOrder:o.any},{name:"opacity",type:s.zeroOneNumber,triggersZOrder:o.zeroNonZero},{name:"text-opacity",type:s.zeroOneNumber},{name:"min-zoomed-font-size",type:s.size},{name:"z-compound-depth",type:s.zCompoundDepth,triggersZOrder:o.any},{name:"z-index-compare",type:s.zIndexCompare,triggersZOrder:o.any},{name:"z-index",type:s.number,triggersZOrder:o.any}],f=[{name:"overlay-padding",type:s.size,triggersBounds:o.any},{name:"overlay-color",type:s.color},{name:"overlay-opacity",type:s.zeroOneNumber,triggersBounds:o.zeroNonZero},{name:"overlay-shape",type:s.overlayShape,triggersBounds:o.any}],v=[{name:"underlay-padding",type:s.size,triggersBounds:o.any},{name:"underlay-color",type:s.color},{name:"underlay-opacity",type:s.zeroOneNumber,triggersBounds:o.zeroNonZero},{name:"underlay-shape",type:s.overlayShape,triggersBounds:o.any}],y=[{name:"transition-property",type:s.propList},{name:"transition-duration",type:s.time},{name:"transition-delay",type:s.time},{name:"transition-timing-function",type:s.easing}],m=function(e,t){return"label"===t.value?-e.poolIndex():t.pfValue},b=[{name:"height",type:s.nodeSize,triggersBounds:o.any,hashOverride:m},{name:"width",type:s.nodeSize,triggersBounds:o.any,hashOverride:m},{name:"shape",type:s.nodeShape,triggersBounds:o.any},{name:"shape-polygon-points",type:s.polygonPointList,triggersBounds:o.any},{name:"background-color",type:s.color},{name:"background-fill",type:s.fill},{name:"background-opacity",type:s.zeroOneNumber},{name:"background-blacken",type:s.nOneOneNumber},{name:"background-gradient-stop-colors",type:s.colors},{name:"background-gradient-stop-positions",type:s.percentages},{name:"background-gradient-direction",type:s.gradientDirection},{name:"padding",type:s.sizeMaybePercent,triggersBounds:o.any},{name:"padding-relative-to",type:s.paddingRelativeTo,triggersBounds:o.any},{name:"bounds-expansion",type:s.boundsExpansion,triggersBounds:o.any}],x=[{name:"border-color",type:s.color},{name:"border-opacity",type:s.zeroOneNumber},{name:"border-width",type:s.size,triggersBounds:o.any},{name:"border-style",type:s.borderStyle}],w=[{name:"outline-color",type:s.color},{name:"outline-opacity",type:s.zeroOneNumber},{name:"outline-width",type:s.size,triggersBounds:o.any},{name:"outline-style",type:s.borderStyle},{name:"outline-offset",type:s.size,triggersBounds:o.any}],E=[{name:"background-image",type:s.urls},{name:"background-image-crossorigin",type:s.bgCrossOrigin},{name:"background-image-opacity",type:s.zeroOneNumbers},{name:"background-image-containment",type:s.bgContainment},{name:"background-image-smoothing",type:s.bools},{name:"background-position-x",type:s.bgPos},{name:"background-position-y",type:s.bgPos},{name:"background-width-relative-to",type:s.bgRelativeTo},{name:"background-height-relative-to",type:s.bgRelativeTo},{name:"background-repeat",type:s.bgRepeat},{name:"background-fit",type:s.bgFit},{name:"background-clip",type:s.bgClip},{name:"background-width",type:s.bgWH},{name:"background-height",type:s.bgWH},{name:"background-offset-x",type:s.bgPos},{name:"background-offset-y",type:s.bgPos}],_=[{name:"position",type:s.position,triggersBounds:o.any},{name:"compound-sizing-wrt-labels",type:s.compoundIncludeLabels,triggersBounds:o.any},{name:"min-width",type:s.size,triggersBounds:o.any},{name:"min-width-bias-left",type:s.sizeMaybePercent,triggersBounds:o.any},{name:"min-width-bias-right",type:s.sizeMaybePercent,triggersBounds:o.any},{name:"min-height",type:s.size,triggersBounds:o.any},{name:"min-height-bias-top",type:s.sizeMaybePercent,triggersBounds:o.any},{name:"min-height-bias-bottom",type:s.sizeMaybePercent,triggersBounds:o.any}],T=[{name:"line-style",type:s.lineStyle},{name:"line-color",type:s.color},{name:"line-fill",type:s.fill},{name:"line-cap",type:s.lineCap},{name:"line-opacity",type:s.zeroOneNumber},{name:"line-dash-pattern",type:s.numbers},{name:"line-dash-offset",type:s.number},{name:"line-gradient-stop-colors",type:s.colors},{name:"line-gradient-stop-positions",type:s.percentages},{name:"curve-style",type:s.curveStyle,triggersBounds:o.any,triggersBoundsOfParallelBeziers:!0},{name:"haystack-radius",type:s.zeroOneNumber,triggersBounds:o.any},{name:"source-endpoint",type:s.edgeEndpoint,triggersBounds:o.any},{name:"target-endpoint",type:s.edgeEndpoint,triggersBounds:o.any},{name:"control-point-step-size",type:s.size,triggersBounds:o.any},{name:"control-point-distances",type:s.bidirectionalSizes,triggersBounds:o.any},{name:"control-point-weights",type:s.numbers,triggersBounds:o.any},{name:"segment-distances",type:s.bidirectionalSizes,triggersBounds:o.any},{name:"segment-weights",type:s.numbers,triggersBounds:o.any},{name:"taxi-turn",type:s.bidirectionalSizeMaybePercent,triggersBounds:o.any},{name:"taxi-turn-min-distance",type:s.size,triggersBounds:o.any},{name:"taxi-direction",type:s.axisDirection,triggersBounds:o.any},{name:"edge-distances",type:s.edgeDistances,triggersBounds:o.any},{name:"arrow-scale",type:s.positiveNumber,triggersBounds:o.any},{name:"loop-direction",type:s.angle,triggersBounds:o.any},{name:"loop-sweep",type:s.angle,triggersBounds:o.any},{name:"source-distance-from-node",type:s.size,triggersBounds:o.any},{name:"target-distance-from-node",type:s.size,triggersBounds:o.any}],D=[{name:"ghost",type:s.bool,triggersBounds:o.any},{name:"ghost-offset-x",type:s.bidirectionalSize,triggersBounds:o.any},{name:"ghost-offset-y",type:s.bidirectionalSize,triggersBounds:o.any},{name:"ghost-opacity",type:s.zeroOneNumber}],C=[{name:"selection-box-color",type:s.color},{name:"selection-box-opacity",type:s.zeroOneNumber},{name:"selection-box-border-color",type:s.color},{name:"selection-box-border-width",type:s.size},{name:"active-bg-color",type:s.color},{name:"active-bg-opacity",type:s.zeroOneNumber},{name:"active-bg-size",type:s.size},{name:"outside-texture-bg-color",type:s.color},{name:"outside-texture-bg-opacity",type:s.zeroOneNumber}],N=[];no.pieBackgroundN=16,N.push({name:"pie-size",type:s.sizeMaybePercent});for(var L=1;L<=no.pieBackgroundN;L++)N.push({name:"pie-"+L+"-background-color",type:s.color}),N.push({name:"pie-"+L+"-background-size",type:s.percent}),N.push({name:"pie-"+L+"-background-opacity",type:s.zeroOneNumber});var k=[],S=no.arrowPrefixes=["source","mid-source","target","mid-target"];[{name:"arrow-shape",type:s.arrowShape,triggersBounds:o.any},{name:"arrow-color",type:s.color},{name:"arrow-fill",type:s.arrowFill},{name:"arrow-width",type:s.arrowWidth}].forEach((function(e){S.forEach((function(t){var n=t+"-"+e.name,r=e.type,i=e.triggersBounds;k.push({name:n,type:r,triggersBounds:i})}))}),{});var I=no.properties=[].concat(p,y,g,f,v,D,d,h,l,u,c,b,x,w,E,N,_,T,k,C),M=no.propertyGroups={behavior:p,transition:y,visibility:g,overlay:f,underlay:v,ghost:D,commonLabel:d,labelDimensions:h,mainLabel:l,sourceLabel:u,targetLabel:c,nodeBody:b,nodeBorder:x,nodeOutline:w,backgroundImage:E,pie:N,compound:_,edgeLine:T,edgeArrow:k,core:C},O=no.propertyGroupNames={};(no.propertyGroupKeys=Object.keys(M)).forEach((function(e){O[e]=M[e].map((function(e){return e.name})),M[e].forEach((function(t){return t.groupKey=e}))}));var P=no.aliases=[{name:"content",pointsTo:"label"},{name:"control-point-distance",pointsTo:"control-point-distances"},{name:"control-point-weight",pointsTo:"control-point-weights"},{name:"edge-text-rotation",pointsTo:"text-rotation"},{name:"padding-left",pointsTo:"padding"},{name:"padding-right",pointsTo:"padding"},{name:"padding-top",pointsTo:"padding"},{name:"padding-bottom",pointsTo:"padding"}];no.propertyNames=I.map((function(e){return e.name}));for(var R=0;R<I.length;R++){var B=I[R];I[B.name]=B}for(var F=0;F<P.length;F++){var G=P[F],Y=I[G.pointsTo],X={name:G.name,alias:!0,pointsTo:Y};I.push(X),I[G.name]=X}}(),no.getDefaultProperty=function(e){return this.getDefaultProperties()[e]},no.getDefaultProperties=function(){var e=this._private;if(null!=e.defaultProperties)return e.defaultProperties;for(var t=Q({"selection-box-color":"#ddd","selection-box-opacity":.65,"selection-box-border-color":"#aaa","selection-box-border-width":1,"active-bg-color":"black","active-bg-opacity":.15,"active-bg-size":30,"outside-texture-bg-color":"#000","outside-texture-bg-opacity":.125,events:"yes","text-events":"no","text-valign":"top","text-halign":"center","text-justification":"auto","line-height":1,color:"#000","text-outline-color":"#000","text-outline-width":0,"text-outline-opacity":1,"text-opacity":1,"text-decoration":"none","text-transform":"none","text-wrap":"none","text-overflow-wrap":"whitespace","text-max-width":9999,"text-background-color":"#000","text-background-opacity":0,"text-background-shape":"rectangle","text-background-padding":0,"text-border-opacity":0,"text-border-width":0,"text-border-style":"solid","text-border-color":"#000","font-family":"Helvetica Neue, Helvetica, sans-serif","font-style":"normal","font-weight":"normal","font-size":16,"min-zoomed-font-size":0,"text-rotation":"none","source-text-rotation":"none","target-text-rotation":"none",visibility:"visible",display:"element",opacity:1,"z-compound-depth":"auto","z-index-compare":"auto","z-index":0,label:"","text-margin-x":0,"text-margin-y":0,"source-label":"","source-text-offset":0,"source-text-margin-x":0,"source-text-margin-y":0,"target-label":"","target-text-offset":0,"target-text-margin-x":0,"target-text-margin-y":0,"overlay-opacity":0,"overlay-color":"#000","overlay-padding":10,"overlay-shape":"round-rectangle","underlay-opacity":0,"underlay-color":"#000","underlay-padding":10,"underlay-shape":"round-rectangle","transition-property":"none","transition-duration":0,"transition-delay":0,"transition-timing-function":"linear","background-blacken":0,"background-color":"#999","background-fill":"solid","background-opacity":1,"background-image":"none","background-image-crossorigin":"anonymous","background-image-opacity":1,"background-image-containment":"inside","background-image-smoothing":"yes","background-position-x":"50%","background-position-y":"50%","background-offset-x":0,"background-offset-y":0,"background-width-relative-to":"include-padding","background-height-relative-to":"include-padding","background-repeat":"no-repeat","background-fit":"none","background-clip":"node","background-width":"auto","background-height":"auto","border-color":"#000","border-opacity":1,"border-width":0,"border-style":"solid","outline-color":"#999","outline-opacity":1,"outline-width":0,"outline-offset":0,"outline-style":"solid",height:30,width:30,shape:"ellipse","shape-polygon-points":"-1, -1, 1, -1, 1, 1, -1, 1","bounds-expansion":0,"background-gradient-direction":"to-bottom","background-gradient-stop-colors":"#999","background-gradient-stop-positions":"0%",ghost:"no","ghost-offset-y":0,"ghost-offset-x":0,"ghost-opacity":0,padding:0,"padding-relative-to":"width",position:"origin","compound-sizing-wrt-labels":"include","min-width":0,"min-width-bias-left":0,"min-width-bias-right":0,"min-height":0,"min-height-bias-top":0,"min-height-bias-bottom":0},{"pie-size":"100%"},[{name:"pie-{{i}}-background-color",value:"black"},{name:"pie-{{i}}-background-size",value:"0%"},{name:"pie-{{i}}-background-opacity",value:1}].reduce((function(e,t){for(var n=1;n<=no.pieBackgroundN;n++){var r=t.name.replace("{{i}}",n),i=t.value;e[r]=i}return e}),{}),{"line-style":"solid","line-color":"#999","line-fill":"solid","line-cap":"butt","line-opacity":1,"line-gradient-stop-colors":"#999","line-gradient-stop-positions":"0%","control-point-step-size":40,"control-point-weights":.5,"segment-weights":.5,"segment-distances":20,"taxi-turn":"50%","taxi-turn-min-distance":10,"taxi-direction":"auto","edge-distances":"intersection","curve-style":"haystack","haystack-radius":0,"arrow-scale":1,"loop-direction":"-45deg","loop-sweep":"-90deg","source-distance-from-node":0,"target-distance-from-node":0,"source-endpoint":"outside-to-node","target-endpoint":"outside-to-node","line-dash-pattern":[6,3],"line-dash-offset":0},[{name:"arrow-shape",value:"none"},{name:"arrow-color",value:"#999"},{name:"arrow-fill",value:"filled"},{name:"arrow-width",value:1}].reduce((function(e,t){return no.arrowPrefixes.forEach((function(n){var r=n+"-"+t.name,i=t.value;e[r]=i})),e}),{})),n={},r=0;r<this.properties.length;r++){var i=this.properties[r];if(!i.pointsTo){var a=i.name,o=t[a],s=this.parse(a,o);n[a]=s}}return e.defaultProperties=n,e.defaultProperties},no.addDefaultStylesheet=function(){this.selector(":parent").css({shape:"rectangle",padding:10,"background-color":"#eee","border-color":"#ccc","border-width":1}).selector("edge").css({width:3}).selector(":loop").css({"curve-style":"bezier"}).selector("edge:compound").css({"curve-style":"bezier","source-endpoint":"outside-to-line","target-endpoint":"outside-to-line"}).selector(":selected").css({"background-color":"#0169D9","line-color":"#0169D9","source-arrow-color":"#0169D9","target-arrow-color":"#0169D9","mid-source-arrow-color":"#0169D9","mid-target-arrow-color":"#0169D9"}).selector(":parent:selected").css({"background-color":"#CCE1F9","border-color":"#aec8e5"}).selector(":active").css({"overlay-color":"black","overlay-padding":10,"overlay-opacity":.25}),this.defaultLength=this.length};var ro={parse:function(e,t,n,r){var i=this;if(L(t))return i.parseImplWarn(e,t,n,r);var a,o=ve(e,""+t,n?"t":"f","mapping"===r||!0===r||!1===r||null==r?"dontcare":r),s=i.propCache=i.propCache||[];return(a=s[o])||(a=s[o]=i.parseImplWarn(e,t,n,r)),(n||"mapping"===r)&&(a=Le(a))&&(a.value=Le(a.value)),a},parseImplWarn:function(e,t,n,r){var i=this.parseImpl(e,t,n,r);return i||null==t||Ae("The style property `".concat(e,": ").concat(t,"` is invalid")),!i||"width"!==i.name&&"height"!==i.name||"label"!==t||Ae("The style value of `label` is deprecated for `"+i.name+"`"),i}};ro.parseImpl=function(e,t,n,r){var i=this;e=X(e);var a=i.properties[e],o=t,s=i.types;if(!a)return null;if(void 0===t)return null;a.alias&&(a=a.pointsTo,e=a.name);var l=A(t);l&&(t=t.trim());var u,c,h=a.type;if(!h)return null;if(n&&(""===t||null===t))return{name:e,value:t,bypass:!0,deleteBypass:!0};if(L(t))return{name:e,value:t,strValue:"fn",mapped:s.fn,bypass:n};if(!l||r||t.length<7||"a"!==t[1]);else{if(t.length>=7&&"d"===t[0]&&(u=new RegExp(s.data.regex).exec(t))){if(n)return!1;var d=s.data;return{name:e,value:u,strValue:""+t,mapped:d,field:u[1],bypass:n}}if(t.length>=10&&"m"===t[0]&&(c=new RegExp(s.mapData.regex).exec(t))){if(n)return!1;if(h.multiple)return!1;var p=s.mapData;if(!h.color&&!h.number)return!1;var g=this.parse(e,c[4]);if(!g||g.mapped)return!1;var f=this.parse(e,c[5]);if(!f||f.mapped)return!1;if(g.pfValue===f.pfValue||g.strValue===f.strValue)return Ae("`"+e+": "+t+"` is not a valid mapper because the output range is zero; converting to `"+e+": "+g.strValue+"`"),this.parse(e,g.strValue);if(h.color){var v=g.value,y=f.value;if(!(v[0]!==y[0]||v[1]!==y[1]||v[2]!==y[2]||v[3]!==y[3]&&(null!=v[3]&&1!==v[3]||null!=y[3]&&1!==y[3])))return!1}return{name:e,value:c,strValue:""+t,mapped:p,field:c[1],fieldMin:parseFloat(c[2]),fieldMax:parseFloat(c[3]),valueMin:g.value,valueMax:f.value,bypass:n}}}if(h.multiple&&"multiple"!==r){var m;if(m=l?t.split(/\s+/):k(t)?t:[t],h.evenMultiple&&m.length%2!=0)return null;for(var b=[],x=[],w=[],E="",_=!1,T=0;T<m.length;T++){var D=i.parse(e,m[T],n,"multiple");_=_||A(D.value),b.push(D.value),w.push(null!=D.pfValue?D.pfValue:D.value),x.push(D.units),E+=(T>0?" ":"")+D.strValue}return h.validate&&!h.validate(b,x)?null:h.singleEnum&&_?1===b.length&&A(b[0])?{name:e,value:b[0],strValue:b[0],bypass:n}:null:{name:e,value:b,pfValue:w,strValue:E,bypass:n,units:x}}var C,N,S=function(){for(var r=0;r<h.enums.length;r++){if(h.enums[r]===t)return{name:e,value:t,strValue:""+t,bypass:n}}return null};if(h.number){var M,O="px";if(h.units&&(M=h.units),h.implicitUnits&&(O=h.implicitUnits),!h.unitless)if(l){var P="px|em"+(h.allowPercent?"|\\%":"");M&&(P=M);var R=t.match("^("+q+")("+P+")?$");R&&(t=R[1],M=R[2]||O)}else M&&!h.implicitUnits||(M=O);if(t=parseFloat(t),isNaN(t)&&void 0===h.enums)return null;if(isNaN(t)&&void 0!==h.enums)return t=o,S();if(h.integer&&(!I(N=t)||Math.floor(N)!==N))return null;if(void 0!==h.min&&(t<h.min||h.strictMin&&t===h.min)||void 0!==h.max&&(t>h.max||h.strictMax&&t===h.max))return null;var B={name:e,value:t,strValue:""+t+(M||""),units:M,bypass:n};return h.unitless||"px"!==M&&"em"!==M?B.pfValue=t:B.pfValue="px"!==M&&M?this.getEmSizeInPixels()*t:t,"ms"!==M&&"s"!==M||(B.pfValue="ms"===M?t:1e3*t),"deg"!==M&&"rad"!==M||(B.pfValue="rad"===M?t:(C=t,Math.PI*C/180)),"%"===M&&(B.pfValue=t/100),B}if(h.propList){var F=[],z=""+t;if("none"===z);else{for(var G=z.split(/\s*,\s*|\s+/),Y=0;Y<G.length;Y++){var V=G[Y].trim();i.properties[V]?F.push(V):Ae("`"+V+"` is not a valid property name")}if(0===F.length)return null}return{name:e,value:F,strValue:0===F.length?"none":F.join(" "),bypass:n}}if(h.color){var U=J(t);return U?{name:e,value:U,pfValue:U,strValue:"rgb("+U[0]+","+U[1]+","+U[2]+")",bypass:n}:null}if(h.regex||h.regexes){if(h.enums){var j=S();if(j)return j}for(var H=h.regexes?h.regexes:[h.regex],W=0;W<H.length;W++){var $=new RegExp(H[W]).exec(t);if($)return{name:e,value:h.singleRegexMatchValue?$[1]:$,strValue:""+t,bypass:n}}return null}return h.string?{name:e,value:""+t,strValue:""+t,bypass:n}:h.enums?S():null};var io=function e(t){if(!(this instanceof e))return new e(t);B(t)?(this._private={cy:t,coreStyle:{}},this.length=0,this.resetToDefault()):Ce("A style must have a core reference")},ao=io.prototype;ao.instanceString=function(){return"style"},ao.clear=function(){for(var e=this._private,t=e.cy.elements(),n=0;n<this.length;n++)this[n]=void 0;return this.length=0,e.contextStyles={},e.propDiffs={},this.cleanElements(t,!0),t.forEach((function(e){var t=e[0]._private;t.styleDirty=!0,t.appliedInitStyle=!1})),this},ao.resetToDefault=function(){return this.clear(),this.addDefaultStylesheet(),this},ao.core=function(e){return this._private.coreStyle[e]||this.getDefaultProperty(e)},ao.selector=function(e){var t="core"===e?null:new Hr(e),n=this.length++;return this[n]={selector:t,properties:[],mappedProperties:[],index:n},this},ao.css=function(){var e=arguments;if(1===e.length)for(var t=e[0],n=0;n<this.properties.length;n++){var r=this.properties[n],i=t[r.name];void 0===i&&(i=t[V(r.name)]),void 0!==i&&this.cssRule(r.name,i)}else 2===e.length&&this.cssRule(e[0],e[1]);return this},ao.style=ao.css,ao.cssRule=function(e,t){var n=this.parse(e,t);if(n){var r=this.length-1;this[r].properties.push(n),this[r].properties[n.name]=n,n.name.match(/pie-(\d+)-background-size/)&&n.value&&(this._private.hasPie=!0),n.mapped&&this[r].mappedProperties.push(n),!this[r].selector&&(this._private.coreStyle[n.name]=n)}return this},ao.append=function(e){return F(e)?e.appendToStyle(this):k(e)?this.appendFromJson(e):A(e)&&this.appendFromString(e),this},io.fromJson=function(e,t){var n=new io(e);return n.fromJson(t),n},io.fromString=function(e,t){return new io(e).fromString(t)},[$a,Za,Qa,Ja,eo,to,no,ro].forEach((function(e){Q(ao,e)})),io.types=ao.types,io.properties=ao.properties,io.propertyGroups=ao.propertyGroups,io.propertyGroupNames=ao.propertyGroupNames,io.propertyGroupKeys=ao.propertyGroupKeys;var oo={style:function(e){e&&this.setStyle(e).update();return this._private.style},setStyle:function(e){var t=this._private;return F(e)?t.style=e.generateStyle(this):k(e)?t.style=io.fromJson(this,e):A(e)?t.style=io.fromString(this,e):t.style=io(this),t.style},updateStyle:function(){this.mutableElements().updateStyle()}},so={autolock:function(e){return void 0===e?this._private.autolock:(this._private.autolock=!!e,this)},autoungrabify:function(e){return void 0===e?this._private.autoungrabify:(this._private.autoungrabify=!!e,this)},autounselectify:function(e){return void 0===e?this._private.autounselectify:(this._private.autounselectify=!!e,this)},selectionType:function(e){var t=this._private;return null==t.selectionType&&(t.selectionType="single"),void 0===e?t.selectionType:("additive"!==e&&"single"!==e||(t.selectionType=e),this)},panningEnabled:function(e){return void 0===e?this._private.panningEnabled:(this._private.panningEnabled=!!e,this)},userPanningEnabled:function(e){return void 0===e?this._private.userPanningEnabled:(this._private.userPanningEnabled=!!e,this)},zoomingEnabled:function(e){return void 0===e?this._private.zoomingEnabled:(this._private.zoomingEnabled=!!e,this)},userZoomingEnabled:function(e){return void 0===e?this._private.userZoomingEnabled:(this._private.userZoomingEnabled=!!e,this)},boxSelectionEnabled:function(e){return void 0===e?this._private.boxSelectionEnabled:(this._private.boxSelectionEnabled=!!e,this)},pan:function(){var e,t,n,r,i,a=arguments,o=this._private.pan;switch(a.length){case 0:return o;case 1:if(A(a[0]))return o[e=a[0]];if(S(a[0])){if(!this._private.panningEnabled)return this;r=(n=a[0]).x,i=n.y,I(r)&&(o.x=r),I(i)&&(o.y=i),this.emit("pan viewport")}break;case 2:if(!this._private.panningEnabled)return this;t=a[1],"x"!==(e=a[0])&&"y"!==e||!I(t)||(o[e]=t),this.emit("pan viewport")}return this.notify("viewport"),this},panBy:function(e,t){var n,r,i,a,o,s=arguments,l=this._private.pan;if(!this._private.panningEnabled)return this;switch(s.length){case 1:S(e)&&(a=(i=s[0]).x,o=i.y,I(a)&&(l.x+=a),I(o)&&(l.y+=o),this.emit("pan viewport"));break;case 2:r=t,"x"!==(n=e)&&"y"!==n||!I(r)||(l[n]+=r),this.emit("pan viewport")}return this.notify("viewport"),this},fit:function(e,t){var n=this.getFitViewport(e,t);if(n){var r=this._private;r.zoom=n.zoom,r.pan=n.pan,this.emit("pan zoom viewport"),this.notify("viewport")}return this},getFitViewport:function(e,t){if(I(e)&&void 0===t&&(t=e,e=void 0),this._private.panningEnabled&&this._private.zoomingEnabled){var n,r;if(A(e)){var i=e;e=this.$(i)}else if(S(r=e)&&I(r.x1)&&I(r.x2)&&I(r.y1)&&I(r.y2)){var a=e;(n={x1:a.x1,y1:a.y1,x2:a.x2,y2:a.y2}).w=n.x2-n.x1,n.h=n.y2-n.y1}else O(e)||(e=this.mutableElements());if(!O(e)||!e.empty()){n=n||e.boundingBox();var o,s=this.width(),l=this.height();if(t=I(t)?t:0,!isNaN(s)&&!isNaN(l)&&s>0&&l>0&&!isNaN(n.w)&&!isNaN(n.h)&&n.w>0&&n.h>0)return{zoom:o=(o=(o=Math.min((s-2*t)/n.w,(l-2*t)/n.h))>this._private.maxZoom?this._private.maxZoom:o)<this._private.minZoom?this._private.minZoom:o,pan:{x:(s-o*(n.x1+n.x2))/2,y:(l-o*(n.y1+n.y2))/2}}}}},zoomRange:function(e,t){var n=this._private;if(null==t){var r=e;e=r.min,t=r.max}return I(e)&&I(t)&&e<=t?(n.minZoom=e,n.maxZoom=t):I(e)&&void 0===t&&e<=n.maxZoom?n.minZoom=e:I(t)&&void 0===e&&t>=n.minZoom&&(n.maxZoom=t),this},minZoom:function(e){return void 0===e?this._private.minZoom:this.zoomRange({min:e})},maxZoom:function(e){return void 0===e?this._private.maxZoom:this.zoomRange({max:e})},getZoomedViewport:function(e){var t,n,r=this._private,i=r.pan,a=r.zoom,o=!1;if(r.zoomingEnabled||(o=!0),I(e)?n=e:S(e)&&(n=e.level,null!=e.position?t=rt(e.position,a,i):null!=e.renderedPosition&&(t=e.renderedPosition),null==t||r.panningEnabled||(o=!0)),n=(n=n>r.maxZoom?r.maxZoom:n)<r.minZoom?r.minZoom:n,o||!I(n)||n===a||null!=t&&(!I(t.x)||!I(t.y)))return null;if(null!=t){var s=i,l=a,u=n;return{zoomed:!0,panned:!0,zoom:u,pan:{x:-u/l*(t.x-s.x)+t.x,y:-u/l*(t.y-s.y)+t.y}}}return{zoomed:!0,panned:!1,zoom:n,pan:i}},zoom:function(e){if(void 0===e)return this._private.zoom;var t=this.getZoomedViewport(e),n=this._private;return null!=t&&t.zoomed?(n.zoom=t.zoom,t.panned&&(n.pan.x=t.pan.x,n.pan.y=t.pan.y),this.emit("zoom"+(t.panned?" pan":"")+" viewport"),this.notify("viewport"),this):this},viewport:function(e){var t=this._private,n=!0,r=!0,i=[],a=!1,o=!1;if(!e)return this;if(I(e.zoom)||(n=!1),S(e.pan)||(r=!1),!n&&!r)return this;if(n){var s=e.zoom;s<t.minZoom||s>t.maxZoom||!t.zoomingEnabled?a=!0:(t.zoom=s,i.push("zoom"))}if(r&&(!a||!e.cancelOnFailedZoom)&&t.panningEnabled){var l=e.pan;I(l.x)&&(t.pan.x=l.x,o=!1),I(l.y)&&(t.pan.y=l.y,o=!1),o||i.push("pan")}return i.length>0&&(i.push("viewport"),this.emit(i.join(" ")),this.notify("viewport")),this},center:function(e){var t=this.getCenterPan(e);return t&&(this._private.pan=t,this.emit("pan viewport"),this.notify("viewport")),this},getCenterPan:function(e,t){if(this._private.panningEnabled){if(A(e)){var n=e;e=this.mutableElements().filter(n)}else O(e)||(e=this.mutableElements());if(0!==e.length){var r=e.boundingBox(),i=this.width(),a=this.height();return{x:(i-(t=void 0===t?this._private.zoom:t)*(r.x1+r.x2))/2,y:(a-t*(r.y1+r.y2))/2}}}},reset:function(){return this._private.panningEnabled&&this._private.zoomingEnabled?(this.viewport({pan:{x:0,y:0},zoom:1}),this):this},invalidateSize:function(){this._private.sizeCache=null},size:function(){var e,t,n=this._private,r=n.container,i=this;return n.sizeCache=n.sizeCache||(r?(e=i.window().getComputedStyle(r),t=function(t){return parseFloat(e.getPropertyValue(t))},{width:r.clientWidth-t("padding-left")-t("padding-right"),height:r.clientHeight-t("padding-top")-t("padding-bottom")}):{width:1,height:1})},width:function(){return this.size().width},height:function(){return this.size().height},extent:function(){var e=this._private.pan,t=this._private.zoom,n=this.renderedExtent(),r={x1:(n.x1-e.x)/t,x2:(n.x2-e.x)/t,y1:(n.y1-e.y)/t,y2:(n.y2-e.y)/t};return r.w=r.x2-r.x1,r.h=r.y2-r.y1,r},renderedExtent:function(){var e=this.width(),t=this.height();return{x1:0,y1:0,x2:e,y2:t,w:e,h:t}},multiClickDebounceTime:function(e){return e?(this._private.multiClickDebounceTime=e,this):this._private.multiClickDebounceTime}};so.centre=so.center,so.autolockNodes=so.autolock,so.autoungrabifyNodes=so.autoungrabify;var lo={data:ur.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeData:ur.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),scratch:ur.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:ur.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0})};lo.attr=lo.data,lo.removeAttr=lo.removeData;var uo=function(e){var t=this,n=(e=Q({},e)).container;n&&!M(n)&&M(n[0])&&(n=n[0]);var r=n?n._cyreg:null;(r=r||{})&&r.cy&&(r.cy.destroy(),r={});var i=r.readies=r.readies||[];n&&(n._cyreg=r),r.cy=t;var a=void 0!==w&&void 0!==n&&!e.headless,o=e;o.layout=Q({name:a?"grid":"null"},o.layout),o.renderer=Q({name:a?"canvas":"null"},o.renderer);var s=function(e,t,n){return void 0!==t?t:void 0!==n?n:e},l=this._private={container:n,ready:!1,options:o,elements:new Da(this),listeners:[],aniEles:new Da(this),data:o.data||{},scratch:{},layout:null,renderer:null,destroyed:!1,notificationsEnabled:!0,minZoom:1e-50,maxZoom:1e50,zoomingEnabled:s(!0,o.zoomingEnabled),userZoomingEnabled:s(!0,o.userZoomingEnabled),panningEnabled:s(!0,o.panningEnabled),userPanningEnabled:s(!0,o.userPanningEnabled),boxSelectionEnabled:s(!0,o.boxSelectionEnabled),autolock:s(!1,o.autolock,o.autolockNodes),autoungrabify:s(!1,o.autoungrabify,o.autoungrabifyNodes),autounselectify:s(!1,o.autounselectify),styleEnabled:void 0===o.styleEnabled?a:o.styleEnabled,zoom:I(o.zoom)?o.zoom:1,pan:{x:S(o.pan)&&I(o.pan.x)?o.pan.x:0,y:S(o.pan)&&I(o.pan.y)?o.pan.y:0},animation:{current:[],queue:[]},hasCompoundNodes:!1,multiClickDebounceTime:s(250,o.multiClickDebounceTime)};this.createEmitter(),this.selectionType(o.selectionType),this.zoomRange({min:o.minZoom,max:o.maxZoom});l.styleEnabled&&t.setStyle([]);var u=Q({},o,o.renderer);t.initRenderer(u);!function(e,t){if(e.some(G))return rr.all(e).then(t);t(e)}([o.style,o.elements],(function(e){var n=e[0],a=e[1];l.styleEnabled&&t.style().append(n),function(e,n,r){t.notifications(!1);var i=t.mutableElements();i.length>0&&i.remove(),null!=e&&(S(e)||k(e))&&t.add(e),t.one("layoutready",(function(e){t.notifications(!0),t.emit(e),t.one("load",n),t.emitAndNotify("load")})).one("layoutstop",(function(){t.one("done",r),t.emit("done")}));var a=Q({},t._private.options.layout);a.eles=t.elements(),t.layout(a).run()}(a,(function(){t.startAnimationLoop(),l.ready=!0,L(o.ready)&&t.on("ready",o.ready);for(var e=0;e<i.length;e++){var n=i[e];t.on("ready",n)}r&&(r.readies=[]),t.emit("ready")}),o.done)}))},co=uo.prototype;Q(co,{instanceString:function(){return"core"},isReady:function(){return this._private.ready},destroyed:function(){return this._private.destroyed},ready:function(e){return this.isReady()?this.emitter().emit("ready",[],e):this.on("ready",e),this},destroy:function(){var e=this;if(!e.destroyed())return e.stopAnimationLoop(),e.destroyRenderer(),this.emit("destroy"),e._private.destroyed=!0,e},hasElementWithId:function(e){return this._private.elements.hasElementWithId(e)},getElementById:function(e){return this._private.elements.getElementById(e)},hasCompoundNodes:function(){return this._private.hasCompoundNodes},headless:function(){return this._private.renderer.isHeadless()},styleEnabled:function(){return this._private.styleEnabled},addToPool:function(e){return this._private.elements.merge(e),this},removeFromPool:function(e){return this._private.elements.unmerge(e),this},container:function(){return this._private.container||null},window:function(){if(null==this._private.container)return w;var e=this._private.container.ownerDocument;return void 0===e||null==e?w:e.defaultView||w},mount:function(e){if(null!=e){var t=this,n=t._private,r=n.options;return!M(e)&&M(e[0])&&(e=e[0]),t.stopAnimationLoop(),t.destroyRenderer(),n.container=e,n.styleEnabled=!0,t.invalidateSize(),t.initRenderer(Q({},r,r.renderer,{name:"null"===r.renderer.name?"canvas":r.renderer.name})),t.startAnimationLoop(),t.style(r.style),t.emit("mount"),t}},unmount:function(){var e=this;return e.stopAnimationLoop(),e.destroyRenderer(),e.initRenderer({name:"null"}),e.emit("unmount"),e},options:function(){return Le(this._private.options)},json:function(e){var t=this,n=t._private,r=t.mutableElements();if(S(e)){if(t.startBatch(),e.elements){var i={},a=function(e,n){for(var r=[],a=[],o=0;o<e.length;o++){var s=e[o];if(s.data.id){var l=""+s.data.id,u=t.getElementById(l);i[l]=!0,0!==u.length?a.push({ele:u,json:s}):n?(s.group=n,r.push(s)):r.push(s)}else Ae("cy.json() cannot handle elements without an ID attribute")}t.add(r);for(var c=0;c<a.length;c++){var h=a[c],d=h.ele,p=h.json;d.json(p)}};if(k(e.elements))a(e.elements);else for(var o=["nodes","edges"],s=0;s<o.length;s++){var l=o[s],u=e.elements[l];k(u)&&a(u,l)}var c=t.collection();r.filter((function(e){return!i[e.id()]})).forEach((function(e){e.isParent()?c.merge(e):e.remove()})),c.forEach((function(e){return e.children().move({parent:null})})),c.forEach((function(e){return function(e){return t.getElementById(e.id())}(e).remove()}))}e.style&&t.style(e.style),null!=e.zoom&&e.zoom!==n.zoom&&t.zoom(e.zoom),e.pan&&(e.pan.x===n.pan.x&&e.pan.y===n.pan.y||t.pan(e.pan)),e.data&&t.data(e.data);for(var h=["minZoom","maxZoom","zoomingEnabled","userZoomingEnabled","panningEnabled","userPanningEnabled","boxSelectionEnabled","autolock","autoungrabify","autounselectify","multiClickDebounceTime"],d=0;d<h.length;d++){var p=h[d];null!=e[p]&&t[p](e[p])}return t.endBatch(),this}var g={};!!e?g.elements=this.elements().map((function(e){return e.json()})):(g.elements={},r.forEach((function(e){var t=e.group();g.elements[t]||(g.elements[t]=[]),g.elements[t].push(e.json())}))),this._private.styleEnabled&&(g.style=t.style().json()),g.data=Le(t.data());var f=n.options;return g.zoomingEnabled=n.zoomingEnabled,g.userZoomingEnabled=n.userZoomingEnabled,g.zoom=n.zoom,g.minZoom=n.minZoom,g.maxZoom=n.maxZoom,g.panningEnabled=n.panningEnabled,g.userPanningEnabled=n.userPanningEnabled,g.pan=Le(n.pan),g.boxSelectionEnabled=n.boxSelectionEnabled,g.renderer=Le(f.renderer),g.hideEdgesOnViewport=f.hideEdgesOnViewport,g.textureOnViewport=f.textureOnViewport,g.wheelSensitivity=f.wheelSensitivity,g.motionBlur=f.motionBlur,g.multiClickDebounceTime=f.multiClickDebounceTime,g}}),co.$id=co.getElementById,[Na,za,Xa,Va,Ua,ja,Ha,Wa,oo,so,lo].forEach((function(e){Q(co,e)}));var ho={fit:!0,directed:!1,padding:30,circle:!1,grid:!1,spacingFactor:1.75,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,roots:void 0,depthSort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}},po={maximal:!1,acyclic:!1},go=function(e){return e.scratch("breadthfirst")},fo=function(e,t){return e.scratch("breadthfirst",t)};function vo(e){this.options=Q({},ho,po,e)}vo.prototype.run=function(){var e,t=this.options,n=t,r=t.cy,i=n.eles,a=i.nodes().filter((function(e){return!e.isParent()})),o=i,s=n.directed,l=n.acyclic||n.maximal||n.maximalAdjustments>0,u=ft(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()});if(O(n.roots))e=n.roots;else if(k(n.roots)){for(var c=[],h=0;h<n.roots.length;h++){var d=n.roots[h],p=r.getElementById(d);c.push(p)}e=r.collection(c)}else if(A(n.roots))e=r.$(n.roots);else if(s)e=a.roots();else{var g=i.components();e=r.collection();for(var f=function(t){var n=g[t],r=n.maxDegree(!1),i=n.filter((function(e){return e.degree(!1)===r}));e=e.add(i)},v=0;v<g.length;v++)f(v)}var y=[],m={},b=function(e,t){null==y[t]&&(y[t]=[]);var n=y[t].length;y[t].push(e),fo(e,{index:n,depth:t})};o.bfs({roots:e,directed:n.directed,visit:function(e,t,n,r,i){var a=e[0],o=a.id();b(a,i),m[o]=!0}});for(var x=[],w=0;w<a.length;w++){var E=a[w];m[E.id()]||x.push(E)}var _=function(e){for(var t=y[e],n=0;n<t.length;n++){var r=t[n];null!=r?fo(r,{depth:e,index:n}):(t.splice(n,1),n--)}},T=function(){for(var e=0;e<y.length;e++)_(e)},D=function(e,t){for(var r=go(e),a=e.incomers().filter((function(e){return e.isNode()&&i.has(e)})),o=-1,s=e.id(),l=0;l<a.length;l++){var u=a[l],c=go(u);o=Math.max(o,c.depth)}if(r.depth<=o){if(!n.acyclic&&t[s])return null;var h=o+1;return function(e,t){var n=go(e),r=n.depth,i=n.index;y[r][i]=null,b(e,t)}(e,h),t[s]=h,!0}return!1};if(s&&l){var C=[],N={},L=function(e){return C.push(e)};for(a.forEach((function(e){return C.push(e)}));C.length>0;){var S=C.shift(),I=D(S,N);if(I)S.outgoers().filter((function(e){return e.isNode()&&i.has(e)})).forEach(L);else if(null===I){Ae("Detected double maximal shift for node `"+S.id()+"`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.");break}}}T();var M=0;if(n.avoidOverlap)for(var P=0;P<a.length;P++){var R=a[P].layoutDimensions(n),B=R.w,F=R.h;M=Math.max(M,B,F)}var z={},G=function(e){if(z[e.id()])return z[e.id()];for(var t=go(e).depth,n=e.neighborhood(),r=0,i=0,o=0;o<n.length;o++){var s=n[o];if(!s.isEdge()&&!s.isParent()&&a.has(s)){var l=go(s);if(null!=l){var u=l.index,c=l.depth;if(null!=u&&null!=c){var h=y[c].length;c<t&&(r+=u/h,i++)}}}}return r/=i=Math.max(1,i),0===i&&(r=0),z[e.id()]=r,r},Y=function(e,t){var n=G(e)-G(t);return 0===n?Z(e.id(),t.id()):n};void 0!==n.depthSort&&(Y=n.depthSort);for(var X=0;X<y.length;X++)y[X].sort(Y),_(X);for(var V=[],U=0;U<x.length;U++)V.push(x[U]);y.unshift(V),T();for(var j=0,q=0;q<y.length;q++)j=Math.max(y[q].length,j);var H=u.x1+u.w/2,W=u.x1+u.h/2,$=y.reduce((function(e,t){return Math.max(e,t.length)}),0);return i.nodes().layoutPositions(this,n,(function(e){var t=go(e),r=t.depth,i=t.index,a=y[r].length,o=Math.max(u.w/((n.grid?$:a)+1),M),s=Math.max(u.h/(y.length+1),M),l=Math.min(u.w/2/y.length,u.h/2/y.length);if(l=Math.max(l,M),n.circle){var c=l*r+l-(y.length>0&&y[0].length<=3?l/2:0),h=2*Math.PI/y[r].length*i;return 0===r&&1===y[0].length&&(c=1),{x:H+c*Math.cos(h),y:W+c*Math.sin(h)}}return{x:H+(i+1-(a+1)/2)*o,y:(r+1)*s}})),this};var yo={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,radius:void 0,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function mo(e){this.options=Q({},yo,e)}mo.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,i=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,a=r.nodes().not(":parent");t.sort&&(a=a.sort(t.sort));for(var o,s=ft(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()}),l=s.x1+s.w/2,u=s.y1+s.h/2,c=(void 0===t.sweep?2*Math.PI-2*Math.PI/a.length:t.sweep)/Math.max(1,a.length-1),h=0,d=0;d<a.length;d++){var p=a[d].layoutDimensions(t),g=p.w,f=p.h;h=Math.max(h,g,f)}if(o=I(t.radius)?t.radius:a.length<=1?0:Math.min(s.h,s.w)/2-h,a.length>1&&t.avoidOverlap){h*=1.75;var v=Math.cos(c)-Math.cos(0),y=Math.sin(c)-Math.sin(0),m=Math.sqrt(h*h/(v*v+y*y));o=Math.max(m,o)}return r.nodes().layoutPositions(this,t,(function(e,n){var r=t.startAngle+n*c*(i?1:-1),a=o*Math.cos(r),s=o*Math.sin(r);return{x:l+a,y:u+s}})),this};var bo,xo={fit:!0,padding:30,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,equidistant:!1,minNodeSpacing:10,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,height:void 0,width:void 0,spacingFactor:void 0,concentric:function(e){return e.degree()},levelWidth:function(e){return e.maxDegree()/4},animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function wo(e){this.options=Q({},xo,e)}wo.prototype.run=function(){for(var e=this.options,t=e,n=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,r=e.cy,i=t.eles,a=i.nodes().not(":parent"),o=ft(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()}),s=o.x1+o.w/2,l=o.y1+o.h/2,u=[],c=0,h=0;h<a.length;h++){var d,p=a[h];d=t.concentric(p),u.push({value:d,node:p}),p._private.scratch.concentric=d}a.updateStyle();for(var g=0;g<a.length;g++){var f=a[g].layoutDimensions(t);c=Math.max(c,f.w,f.h)}u.sort((function(e,t){return t.value-e.value}));for(var v=t.levelWidth(a),y=[[]],m=y[0],b=0;b<u.length;b++){var x=u[b];if(m.length>0)Math.abs(m[0].value-x.value)>=v&&(m=[],y.push(m));m.push(x)}var w=c+t.minNodeSpacing;if(!t.avoidOverlap){var E=y.length>0&&y[0].length>1,_=(Math.min(o.w,o.h)/2-w)/(y.length+E?1:0);w=Math.min(w,_)}for(var T=0,D=0;D<y.length;D++){var C=y[D],N=void 0===t.sweep?2*Math.PI-2*Math.PI/C.length:t.sweep,A=C.dTheta=N/Math.max(1,C.length-1);if(C.length>1&&t.avoidOverlap){var L=Math.cos(A)-Math.cos(0),k=Math.sin(A)-Math.sin(0),S=Math.sqrt(w*w/(L*L+k*k));T=Math.max(S,T)}C.r=T,T+=w}if(t.equidistant){for(var I=0,M=0,O=0;O<y.length;O++){var P=y[O].r-M;I=Math.max(I,P)}M=0;for(var R=0;R<y.length;R++){var B=y[R];0===R&&(M=B.r),B.r=M,M+=I}}for(var F={},z=0;z<y.length;z++)for(var G=y[z],Y=G.dTheta,X=G.r,V=0;V<G.length;V++){var U=G[V],j=t.startAngle+(n?1:-1)*Y*V,q={x:s+X*Math.cos(j),y:l+X*Math.sin(j)};F[U.node.id()]=q}return i.nodes().layoutPositions(this,t,(function(e){var t=e.id();return F[t]})),this};var Eo={ready:function(){},stop:function(){},animate:!0,animationEasing:void 0,animationDuration:void 0,animateFilter:function(e,t){return!0},animationThreshold:250,refresh:20,fit:!0,padding:30,boundingBox:void 0,nodeDimensionsIncludeLabels:!1,randomize:!1,componentSpacing:40,nodeRepulsion:function(e){return 2048},nodeOverlap:4,idealEdgeLength:function(e){return 32},edgeElasticity:function(e){return 32},nestingFactor:1.2,gravity:1,numIter:1e3,initialTemp:1e3,coolingFactor:.99,minTemp:1};function _o(e){this.options=Q({},Eo,e),this.options.layout=this;var t=this.options.eles.nodes(),n=this.options.eles.edges().filter((function(e){var n=e.source().data("id"),r=e.target().data("id"),i=t.some((function(e){return e.data("id")===n})),a=t.some((function(e){return e.data("id")===r}));return!i||!a}));this.options.eles=this.options.eles.not(n)}_o.prototype.run=function(){var e=this.options,t=e.cy,n=this;n.stopped=!1,!0!==e.animate&&!1!==e.animate||n.emit({type:"layoutstart",layout:n}),bo=!0===e.debug;var r=To(t,n,e);bo&&undefined(r),e.randomize&&No(r);var i=se(),a=function(){Lo(r,t,e),!0===e.fit&&t.fit(e.padding)},o=function(t){return!(n.stopped||t>=e.numIter)&&(ko(r,e),r.temperature=r.temperature*e.coolingFactor,!(r.temperature<e.minTemp))},s=function(){if(!0===e.animate||!1===e.animate)a(),n.one("layoutstop",e.stop),n.emit({type:"layoutstop",layout:n});else{var t=e.eles.nodes(),i=Ao(r,e,t);t.layoutPositions(n,e,i)}},l=0,u=!0;if(!0===e.animate){!function t(){for(var n=0;u&&n<e.refresh;)u=o(l),l++,n++;u?(se()-i>=e.animationThreshold&&a(),oe(t)):(Xo(r,e),s())}()}else{for(;u;)u=o(l),l++;Xo(r,e),s()}return this},_o.prototype.stop=function(){return this.stopped=!0,this.thread&&this.thread.stop(),this.emit("layoutstop"),this},_o.prototype.destroy=function(){return this.thread&&this.thread.stop(),this};var To=function(e,t,n){for(var r=n.eles.edges(),i=n.eles.nodes(),a=ft(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:e.width(),h:e.height()}),o={isCompound:e.hasCompoundNodes(),layoutNodes:[],idToIndex:{},nodeSize:i.size(),graphSet:[],indexToGraph:[],layoutEdges:[],edgeSize:r.size(),temperature:n.initialTemp,clientWidth:a.w,clientHeight:a.h,boundingBox:a},s=n.eles.components(),l={},u=0;u<s.length;u++)for(var c=s[u],h=0;h<c.length;h++){l[c[h].id()]=u}for(u=0;u<o.nodeSize;u++){var d=(y=i[u]).layoutDimensions(n);(O={}).isLocked=y.locked(),O.id=y.data("id"),O.parentId=y.data("parent"),O.cmptId=l[y.id()],O.children=[],O.positionX=y.position("x"),O.positionY=y.position("y"),O.offsetX=0,O.offsetY=0,O.height=d.w,O.width=d.h,O.maxX=O.positionX+O.width/2,O.minX=O.positionX-O.width/2,O.maxY=O.positionY+O.height/2,O.minY=O.positionY-O.height/2,O.padLeft=parseFloat(y.style("padding")),O.padRight=parseFloat(y.style("padding")),O.padTop=parseFloat(y.style("padding")),O.padBottom=parseFloat(y.style("padding")),O.nodeRepulsion=L(n.nodeRepulsion)?n.nodeRepulsion(y):n.nodeRepulsion,o.layoutNodes.push(O),o.idToIndex[O.id]=u}var p=[],g=0,f=-1,v=[];for(u=0;u<o.nodeSize;u++){var y,m=(y=o.layoutNodes[u]).parentId;null!=m?o.layoutNodes[o.idToIndex[m]].children.push(y.id):(p[++f]=y.id,v.push(y.id))}for(o.graphSet.push(v);g<=f;){var b=p[g++],x=o.idToIndex[b],w=o.layoutNodes[x].children;if(w.length>0){o.graphSet.push(w);for(u=0;u<w.length;u++)p[++f]=w[u]}}for(u=0;u<o.graphSet.length;u++){var E=o.graphSet[u];for(h=0;h<E.length;h++){var _=o.idToIndex[E[h]];o.indexToGraph[_]=u}}for(u=0;u<o.edgeSize;u++){var T=r[u],D={};D.id=T.data("id"),D.sourceId=T.data("source"),D.targetId=T.data("target");var C=L(n.idealEdgeLength)?n.idealEdgeLength(T):n.idealEdgeLength,N=L(n.edgeElasticity)?n.edgeElasticity(T):n.edgeElasticity,A=o.idToIndex[D.sourceId],k=o.idToIndex[D.targetId];if(o.indexToGraph[A]!=o.indexToGraph[k]){for(var S=Do(D.sourceId,D.targetId,o),I=o.graphSet[S],M=0,O=o.layoutNodes[A];-1===I.indexOf(O.id);)O=o.layoutNodes[o.idToIndex[O.parentId]],M++;for(O=o.layoutNodes[k];-1===I.indexOf(O.id);)O=o.layoutNodes[o.idToIndex[O.parentId]],M++;C*=M*n.nestingFactor}D.idealLength=C,D.elasticity=N,o.layoutEdges.push(D)}return o},Do=function(e,t,n){var r=Co(e,t,0,n);return 2>r.count?0:r.graph},Co=function e(t,n,r,i){var a=i.graphSet[r];if(-1<a.indexOf(t)&&-1<a.indexOf(n))return{count:2,graph:r};for(var o=0,s=0;s<a.length;s++){var l=a[s],u=i.idToIndex[l],c=i.layoutNodes[u].children;if(0!==c.length){var h=e(t,n,i.indexToGraph[i.idToIndex[c[0]]],i);if(0!==h.count){if(1!==h.count)return h;if(2===++o)break}}}return{count:o,graph:r}},No=function(e,t){for(var n=e.clientWidth,r=e.clientHeight,i=0;i<e.nodeSize;i++){var a=e.layoutNodes[i];0!==a.children.length||a.isLocked||(a.positionX=Math.random()*n,a.positionY=Math.random()*r)}},Ao=function(e,t,n){var r=e.boundingBox,i={x1:1/0,x2:-1/0,y1:1/0,y2:-1/0};return t.boundingBox&&(n.forEach((function(t){var n=e.layoutNodes[e.idToIndex[t.data("id")]];i.x1=Math.min(i.x1,n.positionX),i.x2=Math.max(i.x2,n.positionX),i.y1=Math.min(i.y1,n.positionY),i.y2=Math.max(i.y2,n.positionY)})),i.w=i.x2-i.x1,i.h=i.y2-i.y1),function(n,a){var o=e.layoutNodes[e.idToIndex[n.data("id")]];if(t.boundingBox){var s=(o.positionX-i.x1)/i.w,l=(o.positionY-i.y1)/i.h;return{x:r.x1+s*r.w,y:r.y1+l*r.h}}return{x:o.positionX,y:o.positionY}}},Lo=function(e,t,n){var r=n.layout,i=n.eles.nodes(),a=Ao(e,n,i);i.positions(a),!0!==e.ready&&(e.ready=!0,r.one("layoutready",n.ready),r.emit({type:"layoutready",layout:this}))},ko=function(e,t,n){So(e,t),Ro(e),Bo(e,t),Fo(e),zo(e)},So=function(e,t){for(var n=0;n<e.graphSet.length;n++)for(var r=e.graphSet[n],i=r.length,a=0;a<i;a++)for(var o=e.layoutNodes[e.idToIndex[r[a]]],s=a+1;s<i;s++){var l=e.layoutNodes[e.idToIndex[r[s]]];Mo(o,l,e,t)}},Io=function(e){return-e+2*e*Math.random()},Mo=function(e,t,n,r){if(e.cmptId===t.cmptId||n.isCompound){var i=t.positionX-e.positionX,a=t.positionY-e.positionY;0===i&&0===a&&(i=Io(1),a=Io(1));var o=Oo(e,t,i,a);if(o>0)var s=(u=r.nodeOverlap*o)*i/(f=Math.sqrt(i*i+a*a)),l=u*a/f;else{var u,c=Po(e,i,a),h=Po(t,-1*i,-1*a),d=h.x-c.x,p=h.y-c.y,g=d*d+p*p,f=Math.sqrt(g);s=(u=(e.nodeRepulsion+t.nodeRepulsion)/g)*d/f,l=u*p/f}e.isLocked||(e.offsetX-=s,e.offsetY-=l),t.isLocked||(t.offsetX+=s,t.offsetY+=l)}},Oo=function(e,t,n,r){if(n>0)var i=e.maxX-t.minX;else i=t.maxX-e.minX;if(r>0)var a=e.maxY-t.minY;else a=t.maxY-e.minY;return i>=0&&a>=0?Math.sqrt(i*i+a*a):0},Po=function(e,t,n){var r=e.positionX,i=e.positionY,a=e.height||1,o=e.width||1,s=n/t,l=a/o,u={};return 0===t&&0<n||0===t&&0>n?(u.x=r,u.y=i+a/2,u):0<t&&-1*l<=s&&s<=l?(u.x=r+o/2,u.y=i+o*n/2/t,u):0>t&&-1*l<=s&&s<=l?(u.x=r-o/2,u.y=i-o*n/2/t,u):0<n&&(s<=-1*l||s>=l)?(u.x=r+a*t/2/n,u.y=i+a/2,u):0>n&&(s<=-1*l||s>=l)?(u.x=r-a*t/2/n,u.y=i-a/2,u):u},Ro=function(e,t){for(var n=0;n<e.edgeSize;n++){var r=e.layoutEdges[n],i=e.idToIndex[r.sourceId],a=e.layoutNodes[i],o=e.idToIndex[r.targetId],s=e.layoutNodes[o],l=s.positionX-a.positionX,u=s.positionY-a.positionY;if(0!==l||0!==u){var c=Po(a,l,u),h=Po(s,-1*l,-1*u),d=h.x-c.x,p=h.y-c.y,g=Math.sqrt(d*d+p*p),f=Math.pow(r.idealLength-g,2)/r.elasticity;if(0!==g)var v=f*d/g,y=f*p/g;else v=0,y=0;a.isLocked||(a.offsetX+=v,a.offsetY+=y),s.isLocked||(s.offsetX-=v,s.offsetY-=y)}}},Bo=function(e,t){if(0!==t.gravity)for(var n=0;n<e.graphSet.length;n++){var r=e.graphSet[n],i=r.length;if(0===n)var a=e.clientHeight/2,o=e.clientWidth/2;else{var s=e.layoutNodes[e.idToIndex[r[0]]],l=e.layoutNodes[e.idToIndex[s.parentId]];a=l.positionX,o=l.positionY}for(var u=0;u<i;u++){var c=e.layoutNodes[e.idToIndex[r[u]]];if(!c.isLocked){var h=a-c.positionX,d=o-c.positionY,p=Math.sqrt(h*h+d*d);if(p>1){var g=t.gravity*h/p,f=t.gravity*d/p;c.offsetX+=g,c.offsetY+=f}}}}},Fo=function(e,t){var n=[],r=0,i=-1;for(n.push.apply(n,e.graphSet[0]),i+=e.graphSet[0].length;r<=i;){var a=n[r++],o=e.idToIndex[a],s=e.layoutNodes[o],l=s.children;if(0<l.length&&!s.isLocked){for(var u=s.offsetX,c=s.offsetY,h=0;h<l.length;h++){var d=e.layoutNodes[e.idToIndex[l[h]]];d.offsetX+=u,d.offsetY+=c,n[++i]=l[h]}s.offsetX=0,s.offsetY=0}}},zo=function(e,t){for(var n=0;n<e.nodeSize;n++){0<(i=e.layoutNodes[n]).children.length&&(i.maxX=void 0,i.minX=void 0,i.maxY=void 0,i.minY=void 0)}for(n=0;n<e.nodeSize;n++){if(!(0<(i=e.layoutNodes[n]).children.length||i.isLocked)){var r=Go(i.offsetX,i.offsetY,e.temperature);i.positionX+=r.x,i.positionY+=r.y,i.offsetX=0,i.offsetY=0,i.minX=i.positionX-i.width,i.maxX=i.positionX+i.width,i.minY=i.positionY-i.height,i.maxY=i.positionY+i.height,Yo(i,e)}}for(n=0;n<e.nodeSize;n++){var i;0<(i=e.layoutNodes[n]).children.length&&!i.isLocked&&(i.positionX=(i.maxX+i.minX)/2,i.positionY=(i.maxY+i.minY)/2,i.width=i.maxX-i.minX,i.height=i.maxY-i.minY)}},Go=function(e,t,n){var r=Math.sqrt(e*e+t*t);if(r>n)var i={x:n*e/r,y:n*t/r};else i={x:e,y:t};return i},Yo=function e(t,n){var r=t.parentId;if(null!=r){var i=n.layoutNodes[n.idToIndex[r]],a=!1;return(null==i.maxX||t.maxX+i.padRight>i.maxX)&&(i.maxX=t.maxX+i.padRight,a=!0),(null==i.minX||t.minX-i.padLeft<i.minX)&&(i.minX=t.minX-i.padLeft,a=!0),(null==i.maxY||t.maxY+i.padBottom>i.maxY)&&(i.maxY=t.maxY+i.padBottom,a=!0),(null==i.minY||t.minY-i.padTop<i.minY)&&(i.minY=t.minY-i.padTop,a=!0),a?e(i,n):void 0}},Xo=function(e,t){for(var n=e.layoutNodes,r=[],i=0;i<n.length;i++){var a=n[i],o=a.cmptId;(r[o]=r[o]||[]).push(a)}var s=0;for(i=0;i<r.length;i++){if(f=r[i]){f.x1=1/0,f.x2=-1/0,f.y1=1/0,f.y2=-1/0;for(var l=0;l<f.length;l++){var u=f[l];f.x1=Math.min(f.x1,u.positionX-u.width/2),f.x2=Math.max(f.x2,u.positionX+u.width/2),f.y1=Math.min(f.y1,u.positionY-u.height/2),f.y2=Math.max(f.y2,u.positionY+u.height/2)}f.w=f.x2-f.x1,f.h=f.y2-f.y1,s+=f.w*f.h}}r.sort((function(e,t){return t.w*t.h-e.w*e.h}));var c=0,h=0,d=0,p=0,g=Math.sqrt(s)*e.clientWidth/e.clientHeight;for(i=0;i<r.length;i++){var f;if(f=r[i]){for(l=0;l<f.length;l++){(u=f[l]).isLocked||(u.positionX+=c-f.x1,u.positionY+=h-f.y1)}c+=f.w+t.componentSpacing,d+=f.w+t.componentSpacing,p=Math.max(p,f.h),d>g&&(h+=p+t.componentSpacing,c=0,d=0,p=0)}}},Vo={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,avoidOverlapPadding:10,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,condense:!1,rows:void 0,cols:void 0,position:function(e){},sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Uo(e){this.options=Q({},Vo,e)}Uo.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,i=r.nodes().not(":parent");t.sort&&(i=i.sort(t.sort));var a=ft(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()});if(0===a.h||0===a.w)r.nodes().layoutPositions(this,t,(function(e){return{x:a.x1,y:a.y1}}));else{var o=i.size(),s=Math.sqrt(o*a.h/a.w),l=Math.round(s),u=Math.round(a.w/a.h*s),c=function(e){if(null==e)return Math.min(l,u);Math.min(l,u)==l?l=e:u=e},h=function(e){if(null==e)return Math.max(l,u);Math.max(l,u)==l?l=e:u=e},d=t.rows,p=null!=t.cols?t.cols:t.columns;if(null!=d&&null!=p)l=d,u=p;else if(null!=d&&null==p)l=d,u=Math.ceil(o/l);else if(null==d&&null!=p)u=p,l=Math.ceil(o/u);else if(u*l>o){var g=c(),f=h();(g-1)*f>=o?c(g-1):(f-1)*g>=o&&h(f-1)}else for(;u*l<o;){var v=c(),y=h();(y+1)*v>=o?h(y+1):c(v+1)}var m=a.w/u,b=a.h/l;if(t.condense&&(m=0,b=0),t.avoidOverlap)for(var x=0;x<i.length;x++){var w=i[x],E=w._private.position;null!=E.x&&null!=E.y||(E.x=0,E.y=0);var _=w.layoutDimensions(t),T=t.avoidOverlapPadding,D=_.w+T,C=_.h+T;m=Math.max(m,D),b=Math.max(b,C)}for(var N={},A=function(e,t){return!!N["c-"+e+"-"+t]},L=function(e,t){N["c-"+e+"-"+t]=!0},k=0,S=0,I=function(){++S>=u&&(S=0,k++)},M={},O=0;O<i.length;O++){var P=i[O],R=t.position(P);if(R&&(void 0!==R.row||void 0!==R.col)){var B={row:R.row,col:R.col};if(void 0===B.col)for(B.col=0;A(B.row,B.col);)B.col++;else if(void 0===B.row)for(B.row=0;A(B.row,B.col);)B.row++;M[P.id()]=B,L(B.row,B.col)}}i.layoutPositions(this,t,(function(e,t){var n,r;if(e.locked()||e.isParent())return!1;var i=M[e.id()];if(i)n=i.col*m+m/2+a.x1,r=i.row*b+b/2+a.y1;else{for(;A(k,S);)I();n=S*m+m/2+a.x1,r=k*b+b/2+a.y1,L(k,S),I()}return{x:n,y:r}}))}return this};var jo={ready:function(){},stop:function(){}};function qo(e){this.options=Q({},jo,e)}qo.prototype.run=function(){var e=this.options,t=e.eles,n=this;return e.cy,n.emit("layoutstart"),t.nodes().positions((function(){return{x:0,y:0}})),n.one("layoutready",e.ready),n.emit("layoutready"),n.one("layoutstop",e.stop),n.emit("layoutstop"),this},qo.prototype.stop=function(){return this};var Ho={positions:void 0,zoom:void 0,pan:void 0,fit:!0,padding:30,spacingFactor:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Wo(e){this.options=Q({},Ho,e)}Wo.prototype.run=function(){var e=this.options,t=e.eles.nodes(),n=L(e.positions);return t.layoutPositions(this,e,(function(t,r){var i=function(t){if(null==e.positions)return function(e){return{x:e.x,y:e.y}}(t.position());if(n)return e.positions(t);var r=e.positions[t._private.data.id];return null==r?null:r}(t);return!t.locked()&&null!=i&&i})),this};var $o={fit:!0,padding:30,boundingBox:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Ko(e){this.options=Q({},$o,e)}Ko.prototype.run=function(){var e=this.options,t=e.cy,n=e.eles,r=ft(e.boundingBox?e.boundingBox:{x1:0,y1:0,w:t.width(),h:t.height()});return n.nodes().layoutPositions(this,e,(function(e,t){return{x:r.x1+Math.round(Math.random()*r.w),y:r.y1+Math.round(Math.random()*r.h)}})),this};var Zo=[{name:"breadthfirst",impl:vo},{name:"circle",impl:mo},{name:"concentric",impl:wo},{name:"cose",impl:_o},{name:"grid",impl:Uo},{name:"null",impl:qo},{name:"preset",impl:Wo},{name:"random",impl:Ko}];function Qo(e){this.options=e,this.notifications=0}var Jo=function(){},es=function(){throw new Error("A headless instance can not render images")};Qo.prototype={recalculateRenderedStyle:Jo,notify:function(){this.notifications++},init:Jo,isHeadless:function(){return!0},png:es,jpg:es};var ts={arrowShapeWidth:.3,registerArrowShapes:function(){var e=this.arrowShapes={},t=this,n=function(e,t,n,r,i,a,o){var s=i.x-n/2-o,l=i.x+n/2+o,u=i.y-n/2-o,c=i.y+n/2+o;return s<=e&&e<=l&&u<=t&&t<=c},r=function(e,t,n,r,i){var a=e*Math.cos(r)-t*Math.sin(r),o=(e*Math.sin(r)+t*Math.cos(r))*n;return{x:a*n+i.x,y:o+i.y}},i=function(e,t,n,i){for(var a=[],o=0;o<e.length;o+=2){var s=e[o],l=e[o+1];a.push(r(s,l,t,n,i))}return a},a=function(e){for(var t=[],n=0;n<e.length;n++){var r=e[n];t.push(r.x,r.y)}return t},o=function(e){return e.pstyle("width").pfValue*e.pstyle("arrow-scale").pfValue*2},s=function(r,s){A(s)&&(s=e[s]),e[r]=Q({name:r,points:[-.15,-.3,.15,-.3,.15,.3,-.15,.3],collide:function(e,t,n,r,o,s){var l=a(i(this.points,n+2*s,r,o));return Lt(e,t,l)},roughCollide:n,draw:function(e,n,r,a){var o=i(this.points,n,r,a);t.arrowShapeImpl("polygon")(e,o)},spacing:function(e){return 0},gap:o},s)};s("none",{collide:_e,roughCollide:_e,draw:De,spacing:Te,gap:Te}),s("triangle",{points:[-.15,-.3,0,0,.15,-.3]}),s("arrow","triangle"),s("triangle-backcurve",{points:e.triangle.points,controlPoint:[0,-.15],roughCollide:n,draw:function(e,n,a,o,s){var l=i(this.points,n,a,o),u=this.controlPoint,c=r(u[0],u[1],n,a,o);t.arrowShapeImpl(this.name)(e,l,c)},gap:function(e){return.8*o(e)}}),s("triangle-tee",{points:[0,0,.15,-.3,-.15,-.3,0,0],pointsTee:[-.15,-.4,-.15,-.5,.15,-.5,.15,-.4],collide:function(e,t,n,r,o,s,l){var u=a(i(this.points,n+2*l,r,o)),c=a(i(this.pointsTee,n+2*l,r,o));return Lt(e,t,u)||Lt(e,t,c)},draw:function(e,n,r,a,o){var s=i(this.points,n,r,a),l=i(this.pointsTee,n,r,a);t.arrowShapeImpl(this.name)(e,s,l)}}),s("circle-triangle",{radius:.15,pointsTr:[0,-.15,.15,-.45,-.15,-.45,0,-.15],collide:function(e,t,n,r,o,s,l){var u=o,c=Math.pow(u.x-e,2)+Math.pow(u.y-t,2)<=Math.pow((n+2*l)*this.radius,2),h=a(i(this.points,n+2*l,r,o));return Lt(e,t,h)||c},draw:function(e,n,r,a,o){var s=i(this.pointsTr,n,r,a);t.arrowShapeImpl(this.name)(e,s,a.x,a.y,this.radius*n)},spacing:function(e){return t.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.radius}}),s("triangle-cross",{points:[0,0,.15,-.3,-.15,-.3,0,0],baseCrossLinePts:[-.15,-.4,-.15,-.4,.15,-.4,.15,-.4],crossLinePts:function(e,t){var n=this.baseCrossLinePts.slice(),r=t/e;return n[3]=n[3]-r,n[5]=n[5]-r,n},collide:function(e,t,n,r,o,s,l){var u=a(i(this.points,n+2*l,r,o)),c=a(i(this.crossLinePts(n,s),n+2*l,r,o));return Lt(e,t,u)||Lt(e,t,c)},draw:function(e,n,r,a,o){var s=i(this.points,n,r,a),l=i(this.crossLinePts(n,o),n,r,a);t.arrowShapeImpl(this.name)(e,s,l)}}),s("vee",{points:[-.15,-.3,0,0,.15,-.3,0,-.15],gap:function(e){return.525*o(e)}}),s("circle",{radius:.15,collide:function(e,t,n,r,i,a,o){var s=i;return Math.pow(s.x-e,2)+Math.pow(s.y-t,2)<=Math.pow((n+2*o)*this.radius,2)},draw:function(e,n,r,i,a){t.arrowShapeImpl(this.name)(e,i.x,i.y,this.radius*n)},spacing:function(e){return t.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.radius}}),s("tee",{points:[-.15,0,-.15,-.1,.15,-.1,.15,0],spacing:function(e){return 1},gap:function(e){return 1}}),s("square",{points:[-.15,0,.15,0,.15,-.3,-.15,-.3]}),s("diamond",{points:[-.15,-.15,0,-.3,.15,-.15,0,0],gap:function(e){return e.pstyle("width").pfValue*e.pstyle("arrow-scale").value}}),s("chevron",{points:[0,0,-.15,-.15,-.1,-.2,0,-.1,.1,-.2,.15,-.15],gap:function(e){return.95*e.pstyle("width").pfValue*e.pstyle("arrow-scale").value}})}},ns={projectIntoViewport:function(e,t){var n=this.cy,r=this.findContainerClientCoords(),i=r[0],a=r[1],o=r[4],s=n.pan(),l=n.zoom();return[((e-i)/o-s.x)/l,((t-a)/o-s.y)/l]},findContainerClientCoords:function(){if(this.containerBB)return this.containerBB;var e=this.container,t=e.getBoundingClientRect(),n=this.cy.window().getComputedStyle(e),r=function(e){return parseFloat(n.getPropertyValue(e))},i=r("padding-left"),a=r("padding-right"),o=r("padding-top"),s=r("padding-bottom"),l=r("border-left-width"),u=r("border-right-width"),c=r("border-top-width"),h=(r("border-bottom-width"),e.clientWidth),d=e.clientHeight,p=i+a,g=o+s,f=l+u,v=t.width/(h+f),y=h-p,m=d-g,b=t.left+i+l,x=t.top+o+c;return this.containerBB=[b,x,y,m,v]},invalidateContainerClientCoordsCache:function(){this.containerBB=null},findNearestElement:function(e,t,n,r){return this.findNearestElements(e,t,n,r)[0]},findNearestElements:function(e,t,n,r){var i,a,o=this,s=this,l=s.getCachedZSortedEles(),u=[],c=s.cy.zoom(),h=s.cy.hasCompoundNodes(),d=(r?24:8)/c,p=(r?8:2)/c,g=(r?8:2)/c,f=1/0;function v(e,t){if(e.isNode()){if(a)return;a=e,u.push(e)}if(e.isEdge()&&(null==t||t<f))if(i){if(i.pstyle("z-compound-depth").value===e.pstyle("z-compound-depth").value&&i.pstyle("z-compound-depth").value===e.pstyle("z-compound-depth").value)for(var n=0;n<u.length;n++)if(u[n].isEdge()){u[n]=e,i=e,f=null!=t?t:f;break}}else u.push(e),i=e,f=null!=t?t:f}function y(n){var r=n.outerWidth()+2*p,i=n.outerHeight()+2*p,a=r/2,l=i/2,u=n.position();if(u.x-a<=e&&e<=u.x+a&&u.y-l<=t&&t<=u.y+l&&s.nodeShapes[o.getNodeShape(n)].checkPoint(e,t,0,r,i,u.x,u.y))return v(n,0),!0}function m(n){var r,i=n._private,a=i.rscratch,l=n.pstyle("width").pfValue,c=n.pstyle("arrow-scale").value,p=l/2+d,g=p*p,f=2*p,m=i.source,b=i.target;if("segments"===a.edgeType||"straight"===a.edgeType||"haystack"===a.edgeType){for(var x=a.allpts,w=0;w+3<x.length;w+=2)if(Dt(e,t,x[w],x[w+1],x[w+2],x[w+3],f)&&g>(r=At(e,t,x[w],x[w+1],x[w+2],x[w+3])))return v(n,r),!0}else if("bezier"===a.edgeType||"multibezier"===a.edgeType||"self"===a.edgeType||"compound"===a.edgeType)for(x=a.allpts,w=0;w+5<a.allpts.length;w+=4)if(Ct(e,t,x[w],x[w+1],x[w+2],x[w+3],x[w+4],x[w+5],f)&&g>(r=Nt(e,t,x[w],x[w+1],x[w+2],x[w+3],x[w+4],x[w+5])))return v(n,r),!0;m=m||i.source,b=b||i.target;var E=o.getArrowWidth(l,c),_=[{name:"source",x:a.arrowStartX,y:a.arrowStartY,angle:a.srcArrowAngle},{name:"target",x:a.arrowEndX,y:a.arrowEndY,angle:a.tgtArrowAngle},{name:"mid-source",x:a.midX,y:a.midY,angle:a.midsrcArrowAngle},{name:"mid-target",x:a.midX,y:a.midY,angle:a.midtgtArrowAngle}];for(w=0;w<_.length;w++){var T=_[w],D=s.arrowShapes[n.pstyle(T.name+"-arrow-shape").value],C=n.pstyle("width").pfValue;if(D.roughCollide(e,t,E,T.angle,{x:T.x,y:T.y},C,d)&&D.collide(e,t,E,T.angle,{x:T.x,y:T.y},C,d))return v(n),!0}h&&u.length>0&&(y(m),y(b))}function b(e,t,n){return Re(e,t,n)}function x(n,r){var i,a=n._private,o=g;i=r?r+"-":"",n.boundingBox();var s=a.labelBounds[r||"main"],l=n.pstyle(i+"label").value;if("yes"===n.pstyle("text-events").strValue&&l){var u=b(a.rscratch,"labelX",r),c=b(a.rscratch,"labelY",r),h=b(a.rscratch,"labelAngle",r),d=n.pstyle(i+"text-margin-x").pfValue,p=n.pstyle(i+"text-margin-y").pfValue,f=s.x1-o-d,y=s.x2+o-d,m=s.y1-o-p,x=s.y2+o-p;if(h){var w=Math.cos(h),E=Math.sin(h),_=function(e,t){return{x:(e-=u)*w-(t-=c)*E+u,y:e*E+t*w+c}},T=_(f,m),D=_(f,x),C=_(y,m),N=_(y,x),A=[T.x+d,T.y+p,C.x+d,C.y+p,N.x+d,N.y+p,D.x+d,D.y+p];if(Lt(e,t,A))return v(n),!0}else if(Et(s,e,t))return v(n),!0}}n&&(l=l.interactive);for(var w=l.length-1;w>=0;w--){var E=l[w];E.isNode()?y(E)||x(E):m(E)||x(E)||x(E,"source")||x(E,"target")}return u},getAllInBox:function(e,t,n,r){for(var i,a,o=this.getCachedZSortedEles().interactive,s=[],l=Math.min(e,n),u=Math.max(e,n),c=Math.min(t,r),h=Math.max(t,r),d=ft({x1:e=l,y1:t=c,x2:n=u,y2:r=h}),p=0;p<o.length;p++){var g=o[p];if(g.isNode()){var f=g,v=f.boundingBox({includeNodes:!0,includeEdges:!1,includeLabels:!1});wt(d,v)&&!_t(v,d)&&s.push(f)}else{var y=g,m=y._private,b=m.rscratch;if(null!=b.startX&&null!=b.startY&&!Et(d,b.startX,b.startY))continue;if(null!=b.endX&&null!=b.endY&&!Et(d,b.endX,b.endY))continue;if("bezier"===b.edgeType||"multibezier"===b.edgeType||"self"===b.edgeType||"compound"===b.edgeType||"segments"===b.edgeType||"haystack"===b.edgeType){for(var x=m.rstyle.bezierPts||m.rstyle.linePts||m.rstyle.haystackPts,w=!0,E=0;E<x.length;E++)if(i=d,a=x[E],!Et(i,a.x,a.y)){w=!1;break}w&&s.push(y)}else"haystack"!==b.edgeType&&"straight"!==b.edgeType||s.push(y)}}return s}},rs={calculateArrowAngles:function(e){var t,n,r,i,a,o,s=e._private.rscratch,l="haystack"===s.edgeType,u="bezier"===s.edgeType,c="multibezier"===s.edgeType,h="segments"===s.edgeType,d="compound"===s.edgeType,p="self"===s.edgeType;if(l?(r=s.haystackPts[0],i=s.haystackPts[1],a=s.haystackPts[2],o=s.haystackPts[3]):(r=s.arrowStartX,i=s.arrowStartY,a=s.arrowEndX,o=s.arrowEndY),f=s.midX,v=s.midY,h)t=r-s.segpts[0],n=i-s.segpts[1];else if(c||d||p||u){var g=s.allpts;t=r-dt(g[0],g[2],g[4],.1),n=i-dt(g[1],g[3],g[5],.1)}else t=r-f,n=i-v;s.srcArrowAngle=ot(t,n);var f=s.midX,v=s.midY;if(l&&(f=(r+a)/2,v=(i+o)/2),t=a-r,n=o-i,h)if((g=s.allpts).length/2%2==0){var y=(m=g.length/2)-2;t=g[m]-g[y],n=g[m+1]-g[y+1]}else{y=(m=g.length/2-1)-2;var m,b=m+2;t=g[m]-g[y],n=g[m+1]-g[y+1]}else if(c||d||p){var x,w,E,_,g=s.allpts;if(s.ctrlpts.length/2%2==0){var T=(D=(C=g.length/2-1)+2)+2;x=dt(g[C],g[D],g[T],0),w=dt(g[C+1],g[D+1],g[T+1],0),E=dt(g[C],g[D],g[T],1e-4),_=dt(g[C+1],g[D+1],g[T+1],1e-4)}else{var D,C;T=(D=g.length/2-1)+2;x=dt(g[C=D-2],g[D],g[T],.4999),w=dt(g[C+1],g[D+1],g[T+1],.4999),E=dt(g[C],g[D],g[T],.5),_=dt(g[C+1],g[D+1],g[T+1],.5)}t=E-x,n=_-w}(s.midtgtArrowAngle=ot(t,n),s.midDispX=t,s.midDispY=n,t*=-1,n*=-1,h)&&((g=s.allpts).length/2%2==0||(t=-(g[b=(m=g.length/2-1)+2]-g[m]),n=-(g[b+1]-g[m+1])));if(s.midsrcArrowAngle=ot(t,n),h)t=a-s.segpts[s.segpts.length-2],n=o-s.segpts[s.segpts.length-1];else if(c||d||p||u){var N=(g=s.allpts).length;t=a-dt(g[N-6],g[N-4],g[N-2],.9),n=o-dt(g[N-5],g[N-3],g[N-1],.9)}else t=a-f,n=o-v;s.tgtArrowAngle=ot(t,n)}};rs.getArrowWidth=rs.getArrowHeight=function(e,t){var n=this.arrowWidthCache=this.arrowWidthCache||{},r=n[e+", "+t];return r||(r=Math.max(Math.pow(13.37*e,.9),29)*t,n[e+", "+t]=r,r)};var is={};function as(e){var t=[];if(null!=e){for(var n=0;n<e.length;n+=2){var r=e[n],i=e[n+1];t.push({x:r,y:i})}return t}}is.findMidptPtsEtc=function(e,t){var n,r=t.posPts,i=t.intersectionPts,a=t.vectorNormInverse,o=e.pstyle("source-endpoint"),s=e.pstyle("target-endpoint"),l=null!=o.units&&null!=s.units;switch(e.pstyle("edge-distances").value){case"node-position":n=r;break;case"intersection":n=i;break;case"endpoints":if(l){var u=b(this.manualEndptToPx(e.source()[0],o),2),c=u[0],h=u[1],d=b(this.manualEndptToPx(e.target()[0],s),2),p=d[0],g=d[1],f={x1:c,y1:h,x2:p,y2:g};a=function(e,t,n,r){var i=r-t,a=n-e,o=Math.sqrt(a*a+i*i);return{x:-i/o,y:a/o}}(c,h,p,g),n=f}else Ae("Edge ".concat(e.id()," has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint. Falling back on edge-distances:intersection (default).")),n=i}return{midptPts:n,vectorNormInverse:a}},is.findHaystackPoints=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=n._private,i=r.rscratch;if(!i.haystack){var a=2*Math.random()*Math.PI;i.source={x:Math.cos(a),y:Math.sin(a)},a=2*Math.random()*Math.PI,i.target={x:Math.cos(a),y:Math.sin(a)}}var o=r.source,s=r.target,l=o.position(),u=s.position(),c=o.width(),h=s.width(),d=o.height(),p=s.height(),g=n.pstyle("haystack-radius").value/2;i.haystackPts=i.allpts=[i.source.x*c*g+l.x,i.source.y*d*g+l.y,i.target.x*h*g+u.x,i.target.y*p*g+u.y],i.midX=(i.allpts[0]+i.allpts[2])/2,i.midY=(i.allpts[1]+i.allpts[3])/2,i.edgeType="haystack",i.haystack=!0,this.storeEdgeProjections(n),this.calculateArrowAngles(n),this.recalculateEdgeLabelProjections(n),this.calculateLabelAngles(n)}},is.findSegmentsPoints=function(e,t){var n=e._private.rscratch,r=e.pstyle("segment-weights"),i=e.pstyle("segment-distances"),a=Math.min(r.pfValue.length,i.pfValue.length);n.edgeType="segments",n.segpts=[];for(var o=0;o<a;o++){var s=r.pfValue[o],l=i.pfValue[o],u=1-s,c=s,h=this.findMidptPtsEtc(e,t),d=h.midptPts,p=h.vectorNormInverse,g={x:d.x1*u+d.x2*c,y:d.y1*u+d.y2*c};n.segpts.push(g.x+p.x*l,g.y+p.y*l)}},is.findLoopPoints=function(e,t,n,r){var i=e._private.rscratch,a=t.dirCounts,o=t.srcPos,s=e.pstyle("control-point-distances"),l=s?s.pfValue[0]:void 0,u=e.pstyle("loop-direction").pfValue,c=e.pstyle("loop-sweep").pfValue,h=e.pstyle("control-point-step-size").pfValue;i.edgeType="self";var d=n,p=h;r&&(d=0,p=l);var g=u-Math.PI/2,f=g-c/2,v=g+c/2,y=String(u+"_"+c);d=void 0===a[y]?a[y]=0:++a[y],i.ctrlpts=[o.x+1.4*Math.cos(f)*p*(d/3+1),o.y+1.4*Math.sin(f)*p*(d/3+1),o.x+1.4*Math.cos(v)*p*(d/3+1),o.y+1.4*Math.sin(v)*p*(d/3+1)]},is.findCompoundLoopPoints=function(e,t,n,r){var i=e._private.rscratch;i.edgeType="compound";var a=t.srcPos,o=t.tgtPos,s=t.srcW,l=t.srcH,u=t.tgtW,c=t.tgtH,h=e.pstyle("control-point-step-size").pfValue,d=e.pstyle("control-point-distances"),p=d?d.pfValue[0]:void 0,g=n,f=h;r&&(g=0,f=p);var v={x:a.x-s/2,y:a.y-l/2},y={x:o.x-u/2,y:o.y-c/2},m={x:Math.min(v.x,y.x),y:Math.min(v.y,y.y)},b=Math.max(.5,Math.log(.01*s)),x=Math.max(.5,Math.log(.01*u));i.ctrlpts=[m.x,m.y-(1+Math.pow(50,1.12)/100)*f*(g/3+1)*b,m.x-(1+Math.pow(50,1.12)/100)*f*(g/3+1)*x,m.y]},is.findStraightEdgePoints=function(e){e._private.rscratch.edgeType="straight"},is.findBezierPoints=function(e,t,n,r,i){var a=e._private.rscratch,o=e.pstyle("control-point-step-size").pfValue,s=e.pstyle("control-point-distances"),l=e.pstyle("control-point-weights"),u=s&&l?Math.min(s.value.length,l.value.length):1,c=s?s.pfValue[0]:void 0,h=l.value[0],d=r;a.edgeType=d?"multibezier":"bezier",a.ctrlpts=[];for(var p=0;p<u;p++){var g=(.5-t.eles.length/2+n)*o*(i?-1:1),f=void 0,v=lt(g);d&&(c=s?s.pfValue[p]:o,h=l.value[p]);var y=void 0!==(f=r?c:void 0!==c?v*c:void 0)?f:g,m=1-h,b=h,x=this.findMidptPtsEtc(e,t),w=x.midptPts,E=x.vectorNormInverse,_={x:w.x1*m+w.x2*b,y:w.y1*m+w.y2*b};a.ctrlpts.push(_.x+E.x*y,_.y+E.y*y)}},is.findTaxiPoints=function(e,t){var n=e._private.rscratch;n.edgeType="segments";var r="vertical",i="horizontal",a="leftward",o="rightward",s="downward",l="upward",u=t.posPts,c=t.srcW,h=t.srcH,d=t.tgtW,p=t.tgtH,g="node-position"!==e.pstyle("edge-distances").value,f=e.pstyle("taxi-direction").value,v=f,y=e.pstyle("taxi-turn"),m="%"===y.units,b=y.pfValue,x=b<0,w=e.pstyle("taxi-turn-min-distance").pfValue,E=g?(c+d)/2:0,_=g?(h+p)/2:0,T=u.x2-u.x1,D=u.y2-u.y1,C=function(e,t){return e>0?Math.max(e-t,0):Math.min(e+t,0)},N=C(T,E),A=C(D,_),L=!1;"auto"===v?f=Math.abs(N)>Math.abs(A)?i:r:v===l||v===s?(f=r,L=!0):v!==a&&v!==o||(f=i,L=!0);var k,S=f===r,I=S?A:N,M=S?D:T,O=lt(M),P=!1;(L&&(m||x)||!(v===s&&M<0||v===l&&M>0||v===a&&M>0||v===o&&M<0)||(I=(O*=-1)*Math.abs(I),P=!0),m)?k=(b<0?1+b:b)*I:k=(b<0?I:0)+b*O;var R=function(e){return Math.abs(e)<w||Math.abs(e)>=Math.abs(I)},B=R(k),F=R(Math.abs(I)-Math.abs(k));if((B||F)&&!P)if(S){var z=Math.abs(M)<=h/2,G=Math.abs(T)<=d/2;if(z){var Y=(u.x1+u.x2)/2,X=u.y1,V=u.y2;n.segpts=[Y,X,Y,V]}else if(G){var U=(u.y1+u.y2)/2,j=u.x1,q=u.x2;n.segpts=[j,U,q,U]}else n.segpts=[u.x1,u.y2]}else{var H=Math.abs(M)<=c/2,W=Math.abs(D)<=p/2;if(H){var $=(u.y1+u.y2)/2,K=u.x1,Z=u.x2;n.segpts=[K,$,Z,$]}else if(W){var Q=(u.x1+u.x2)/2,J=u.y1,ee=u.y2;n.segpts=[Q,J,Q,ee]}else n.segpts=[u.x2,u.y1]}else if(S){var te=u.y1+k+(g?h/2*O:0),ne=u.x1,re=u.x2;n.segpts=[ne,te,re,te]}else{var ie=u.x1+k+(g?c/2*O:0),ae=u.y1,oe=u.y2;n.segpts=[ie,ae,ie,oe]}},is.tryToCorrectInvalidPoints=function(e,t){var n=e._private.rscratch;if("bezier"===n.edgeType){var r=t.srcPos,i=t.tgtPos,a=t.srcW,o=t.srcH,s=t.tgtW,l=t.tgtH,u=t.srcShape,c=t.tgtShape,h=!I(n.startX)||!I(n.startY),d=!I(n.arrowStartX)||!I(n.arrowStartY),p=!I(n.endX)||!I(n.endY),g=!I(n.arrowEndX)||!I(n.arrowEndY),f=3*(this.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.arrowShapeWidth),v=ut({x:n.ctrlpts[0],y:n.ctrlpts[1]},{x:n.startX,y:n.startY}),y=v<f,m=ut({x:n.ctrlpts[0],y:n.ctrlpts[1]},{x:n.endX,y:n.endY}),b=m<f,x=!1;if(h||d||y){x=!0;var w={x:n.ctrlpts[0]-r.x,y:n.ctrlpts[1]-r.y},E=Math.sqrt(w.x*w.x+w.y*w.y),_={x:w.x/E,y:w.y/E},T=Math.max(a,o),D={x:n.ctrlpts[0]+2*_.x*T,y:n.ctrlpts[1]+2*_.y*T},C=u.intersectLine(r.x,r.y,a,o,D.x,D.y,0);y?(n.ctrlpts[0]=n.ctrlpts[0]+_.x*(f-v),n.ctrlpts[1]=n.ctrlpts[1]+_.y*(f-v)):(n.ctrlpts[0]=C[0]+_.x*f,n.ctrlpts[1]=C[1]+_.y*f)}if(p||g||b){x=!0;var N={x:n.ctrlpts[0]-i.x,y:n.ctrlpts[1]-i.y},A=Math.sqrt(N.x*N.x+N.y*N.y),L={x:N.x/A,y:N.y/A},k=Math.max(a,o),S={x:n.ctrlpts[0]+2*L.x*k,y:n.ctrlpts[1]+2*L.y*k},M=c.intersectLine(i.x,i.y,s,l,S.x,S.y,0);b?(n.ctrlpts[0]=n.ctrlpts[0]+L.x*(f-m),n.ctrlpts[1]=n.ctrlpts[1]+L.y*(f-m)):(n.ctrlpts[0]=M[0]+L.x*f,n.ctrlpts[1]=M[1]+L.y*f)}x&&this.findEndpoints(e)}},is.storeAllpts=function(e){var t=e._private.rscratch;if("multibezier"===t.edgeType||"bezier"===t.edgeType||"self"===t.edgeType||"compound"===t.edgeType){t.allpts=[],t.allpts.push(t.startX,t.startY);for(var n=0;n+1<t.ctrlpts.length;n+=2)t.allpts.push(t.ctrlpts[n],t.ctrlpts[n+1]),n+3<t.ctrlpts.length&&t.allpts.push((t.ctrlpts[n]+t.ctrlpts[n+2])/2,(t.ctrlpts[n+1]+t.ctrlpts[n+3])/2);var r;t.allpts.push(t.endX,t.endY),t.ctrlpts.length/2%2==0?(r=t.allpts.length/2-1,t.midX=t.allpts[r],t.midY=t.allpts[r+1]):(r=t.allpts.length/2-3,.5,t.midX=dt(t.allpts[r],t.allpts[r+2],t.allpts[r+4],.5),t.midY=dt(t.allpts[r+1],t.allpts[r+3],t.allpts[r+5],.5))}else if("straight"===t.edgeType)t.allpts=[t.startX,t.startY,t.endX,t.endY],t.midX=(t.startX+t.endX+t.arrowStartX+t.arrowEndX)/4,t.midY=(t.startY+t.endY+t.arrowStartY+t.arrowEndY)/4;else if("segments"===t.edgeType)if(t.allpts=[],t.allpts.push(t.startX,t.startY),t.allpts.push.apply(t.allpts,t.segpts),t.allpts.push(t.endX,t.endY),t.segpts.length%4==0){var i=t.segpts.length/2,a=i-2;t.midX=(t.segpts[a]+t.segpts[i])/2,t.midY=(t.segpts[a+1]+t.segpts[i+1])/2}else{var o=t.segpts.length/2-1;t.midX=t.segpts[o],t.midY=t.segpts[o+1]}},is.checkForInvalidEdgeWarning=function(e){var t=e[0]._private.rscratch;t.nodesOverlap||I(t.startX)&&I(t.startY)&&I(t.endX)&&I(t.endY)?t.loggedErr=!1:t.loggedErr||(t.loggedErr=!0,Ae("Edge `"+e.id()+"` has invalid endpoints and so it is impossible to draw. Adjust your edge style (e.g. control points) accordingly or use an alternative edge type. This is expected behaviour when the source node and the target node overlap."))},is.findEdgeControlPoints=function(e){var t=this;if(e&&0!==e.length){for(var n=this,r=n.cy.hasCompoundNodes(),i={map:new Fe,get:function(e){var t=this.map.get(e[0]);return null!=t?t.get(e[1]):null},set:function(e,t){var n=this.map.get(e[0]);null==n&&(n=new Fe,this.map.set(e[0],n)),n.set(e[1],t)}},a=[],o=[],s=0;s<e.length;s++){var l=e[s],u=l._private,c=l.pstyle("curve-style").value;if(!l.removed()&&l.takesUpSpace())if("haystack"!==c){var h="unbundled-bezier"===c||"segments"===c||"straight"===c||"straight-triangle"===c||"taxi"===c,d="unbundled-bezier"===c||"bezier"===c,p=u.source,g=u.target,f=[p.poolIndex(),g.poolIndex()].sort(),v=i.get(f);null==v&&(v={eles:[]},i.set(f,v),a.push(f)),v.eles.push(l),h&&(v.hasUnbundled=!0),d&&(v.hasBezier=!0)}else o.push(l)}for(var y=function(e){var o=a[e],s=i.get(o),l=void 0;if(!s.hasUnbundled){var u=s.eles[0].parallelEdges().filter((function(e){return e.isBundledBezier()}));Pe(s.eles),u.forEach((function(e){return s.eles.push(e)})),s.eles.sort((function(e,t){return e.poolIndex()-t.poolIndex()}))}var c=s.eles[0],h=c.source(),d=c.target();if(h.poolIndex()>d.poolIndex()){var p=h;h=d,d=p}var g=s.srcPos=h.position(),f=s.tgtPos=d.position(),v=s.srcW=h.outerWidth(),y=s.srcH=h.outerHeight(),m=s.tgtW=d.outerWidth(),b=s.tgtH=d.outerHeight(),x=s.srcShape=n.nodeShapes[t.getNodeShape(h)],w=s.tgtShape=n.nodeShapes[t.getNodeShape(d)];s.dirCounts={north:0,west:0,south:0,east:0,northwest:0,southwest:0,northeast:0,southeast:0};for(var E=0;E<s.eles.length;E++){var _=s.eles[E],T=_[0]._private.rscratch,D=_.pstyle("curve-style").value,C="unbundled-bezier"===D||"segments"===D||"taxi"===D,N=!h.same(_.source());if(!s.calculatedIntersection&&h!==d&&(s.hasBezier||s.hasUnbundled)){s.calculatedIntersection=!0;var A=x.intersectLine(g.x,g.y,v,y,f.x,f.y,0),L=s.srcIntn=A,k=w.intersectLine(f.x,f.y,m,b,g.x,g.y,0),S=s.tgtIntn=k,M=s.intersectionPts={x1:A[0],x2:k[0],y1:A[1],y2:k[1]},O=s.posPts={x1:g.x,x2:f.x,y1:g.y,y2:f.y},P=k[1]-A[1],R=k[0]-A[0],B=Math.sqrt(R*R+P*P),F=s.vector={x:R,y:P},z=s.vectorNorm={x:F.x/B,y:F.y/B},G={x:-z.y,y:z.x};s.nodesOverlap=!I(B)||w.checkPoint(A[0],A[1],0,m,b,f.x,f.y)||x.checkPoint(k[0],k[1],0,v,y,g.x,g.y),s.vectorNormInverse=G,l={nodesOverlap:s.nodesOverlap,dirCounts:s.dirCounts,calculatedIntersection:!0,hasBezier:s.hasBezier,hasUnbundled:s.hasUnbundled,eles:s.eles,srcPos:f,tgtPos:g,srcW:m,srcH:b,tgtW:v,tgtH:y,srcIntn:S,tgtIntn:L,srcShape:w,tgtShape:x,posPts:{x1:O.x2,y1:O.y2,x2:O.x1,y2:O.y1},intersectionPts:{x1:M.x2,y1:M.y2,x2:M.x1,y2:M.y1},vector:{x:-F.x,y:-F.y},vectorNorm:{x:-z.x,y:-z.y},vectorNormInverse:{x:-G.x,y:-G.y}}}var Y=N?l:s;T.nodesOverlap=Y.nodesOverlap,T.srcIntn=Y.srcIntn,T.tgtIntn=Y.tgtIntn,r&&(h.isParent()||h.isChild()||d.isParent()||d.isChild())&&(h.parents().anySame(d)||d.parents().anySame(h)||h.same(d)&&h.isParent())?t.findCompoundLoopPoints(_,Y,E,C):h===d?t.findLoopPoints(_,Y,E,C):"segments"===D?t.findSegmentsPoints(_,Y):"taxi"===D?t.findTaxiPoints(_,Y):"straight"===D||!C&&s.eles.length%2==1&&E===Math.floor(s.eles.length/2)?t.findStraightEdgePoints(_):t.findBezierPoints(_,Y,E,C,N),t.findEndpoints(_),t.tryToCorrectInvalidPoints(_,Y),t.checkForInvalidEdgeWarning(_),t.storeAllpts(_),t.storeEdgeProjections(_),t.calculateArrowAngles(_),t.recalculateEdgeLabelProjections(_),t.calculateLabelAngles(_)}},m=0;m<a.length;m++)y(m);this.findHaystackPoints(o)}},is.getSegmentPoints=function(e){var t=e[0]._private.rscratch;if("segments"===t.edgeType)return this.recalculateRenderedStyle(e),as(t.segpts)},is.getControlPoints=function(e){var t=e[0]._private.rscratch,n=t.edgeType;if("bezier"===n||"multibezier"===n||"self"===n||"compound"===n)return this.recalculateRenderedStyle(e),as(t.ctrlpts)},is.getEdgeMidpoint=function(e){var t=e[0]._private.rscratch;return this.recalculateRenderedStyle(e),{x:t.midX,y:t.midY}};var os={manualEndptToPx:function(e,t){var n=e.position(),r=e.outerWidth(),i=e.outerHeight();if(2===t.value.length){var a=[t.pfValue[0],t.pfValue[1]];return"%"===t.units[0]&&(a[0]=a[0]*r),"%"===t.units[1]&&(a[1]=a[1]*i),a[0]+=n.x,a[1]+=n.y,a}var o=t.pfValue[0];o=-Math.PI/2+o;var s=2*Math.max(r,i),l=[n.x+Math.cos(o)*s,n.y+Math.sin(o)*s];return this.nodeShapes[this.getNodeShape(e)].intersectLine(n.x,n.y,r,i,l[0],l[1],0)},findEndpoints:function(e){var t,n,r,i,a,o=this,s=e.source()[0],l=e.target()[0],u=s.position(),c=l.position(),h=e.pstyle("target-arrow-shape").value,d=e.pstyle("source-arrow-shape").value,p=e.pstyle("target-distance-from-node").pfValue,g=e.pstyle("source-distance-from-node").pfValue,f=e.pstyle("curve-style").value,v=e._private.rscratch,y=v.edgeType,m="self"===y||"compound"===y,b="bezier"===y||"multibezier"===y||m,x="bezier"!==y,w="straight"===y||"segments"===y,E="segments"===y,_=b||x||w,T=m||"taxi"===f,D=e.pstyle("source-endpoint"),C=T?"outside-to-node":D.value,N=e.pstyle("target-endpoint"),A=T?"outside-to-node":N.value;if(v.srcManEndpt=D,v.tgtManEndpt=N,b){var L=[v.ctrlpts[0],v.ctrlpts[1]];n=x?[v.ctrlpts[v.ctrlpts.length-2],v.ctrlpts[v.ctrlpts.length-1]]:L,r=L}else if(w){var k=E?v.segpts.slice(0,2):[c.x,c.y];n=E?v.segpts.slice(v.segpts.length-2):[u.x,u.y],r=k}if("inside-to-node"===A)t=[c.x,c.y];else if(N.units)t=this.manualEndptToPx(l,N);else if("outside-to-line"===A)t=v.tgtIntn;else if("outside-to-node"===A||"outside-to-node-or-label"===A?i=n:"outside-to-line"!==A&&"outside-to-line-or-label"!==A||(i=[u.x,u.y]),t=o.nodeShapes[this.getNodeShape(l)].intersectLine(c.x,c.y,l.outerWidth(),l.outerHeight(),i[0],i[1],0),"outside-to-node-or-label"===A||"outside-to-line-or-label"===A){var S=l._private.rscratch,M=S.labelWidth,O=S.labelHeight,P=S.labelX,R=S.labelY,B=M/2,F=O/2,z=l.pstyle("text-valign").value;"top"===z?R-=F:"bottom"===z&&(R+=F);var G=l.pstyle("text-halign").value;"left"===G?P-=B:"right"===G&&(P+=B);var Y=Bt(i[0],i[1],[P-B,R-F,P+B,R-F,P+B,R+F,P-B,R+F],c.x,c.y);if(Y.length>0){var X=u,V=ct(X,at(t)),U=ct(X,at(Y)),j=V;if(U<V&&(t=Y,j=U),Y.length>2)ct(X,{x:Y[2],y:Y[3]})<j&&(t=[Y[2],Y[3]])}}var q=Ft(t,n,o.arrowShapes[h].spacing(e)+p),H=Ft(t,n,o.arrowShapes[h].gap(e)+p);if(v.endX=H[0],v.endY=H[1],v.arrowEndX=q[0],v.arrowEndY=q[1],"inside-to-node"===C)t=[u.x,u.y];else if(D.units)t=this.manualEndptToPx(s,D);else if("outside-to-line"===C)t=v.srcIntn;else if("outside-to-node"===C||"outside-to-node-or-label"===C?a=r:"outside-to-line"!==C&&"outside-to-line-or-label"!==C||(a=[c.x,c.y]),t=o.nodeShapes[this.getNodeShape(s)].intersectLine(u.x,u.y,s.outerWidth(),s.outerHeight(),a[0],a[1],0),"outside-to-node-or-label"===C||"outside-to-line-or-label"===C){var W=s._private.rscratch,$=W.labelWidth,K=W.labelHeight,Z=W.labelX,Q=W.labelY,J=$/2,ee=K/2,te=s.pstyle("text-valign").value;"top"===te?Q-=ee:"bottom"===te&&(Q+=ee);var ne=s.pstyle("text-halign").value;"left"===ne?Z-=J:"right"===ne&&(Z+=J);var re=Bt(a[0],a[1],[Z-J,Q-ee,Z+J,Q-ee,Z+J,Q+ee,Z-J,Q+ee],u.x,u.y);if(re.length>0){var ie=c,ae=ct(ie,at(t)),oe=ct(ie,at(re)),se=ae;if(oe<ae&&(t=[re[0],re[1]],se=oe),re.length>2)ct(ie,{x:re[2],y:re[3]})<se&&(t=[re[2],re[3]])}}var le=Ft(t,r,o.arrowShapes[d].spacing(e)+g),ue=Ft(t,r,o.arrowShapes[d].gap(e)+g);v.startX=ue[0],v.startY=ue[1],v.arrowStartX=le[0],v.arrowStartY=le[1],_&&(I(v.startX)&&I(v.startY)&&I(v.endX)&&I(v.endY)?v.badLine=!1:v.badLine=!0)},getSourceEndpoint:function(e){var t=e[0]._private.rscratch;return this.recalculateRenderedStyle(e),"haystack"===t.edgeType?{x:t.haystackPts[0],y:t.haystackPts[1]}:{x:t.arrowStartX,y:t.arrowStartY}},getTargetEndpoint:function(e){var t=e[0]._private.rscratch;return this.recalculateRenderedStyle(e),"haystack"===t.edgeType?{x:t.haystackPts[2],y:t.haystackPts[3]}:{x:t.arrowEndX,y:t.arrowEndY}}},ss={};function ls(e,t,n){for(var r=function(e,t,n,r){return dt(e,t,n,r)},i=t._private.rstyle.bezierPts,a=0;a<e.bezierProjPcts.length;a++){var o=e.bezierProjPcts[a];i.push({x:r(n[0],n[2],n[4],o),y:r(n[1],n[3],n[5],o)})}}ss.storeEdgeProjections=function(e){var t=e._private,n=t.rscratch,r=n.edgeType;if(t.rstyle.bezierPts=null,t.rstyle.linePts=null,t.rstyle.haystackPts=null,"multibezier"===r||"bezier"===r||"self"===r||"compound"===r){t.rstyle.bezierPts=[];for(var i=0;i+5<n.allpts.length;i+=4)ls(this,e,n.allpts.slice(i,i+6))}else if("segments"===r){var a=t.rstyle.linePts=[];for(i=0;i+1<n.allpts.length;i+=2)a.push({x:n.allpts[i],y:n.allpts[i+1]})}else if("haystack"===r){var o=n.haystackPts;t.rstyle.haystackPts=[{x:o[0],y:o[1]},{x:o[2],y:o[3]}]}t.rstyle.arrowWidth=this.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.arrowShapeWidth},ss.recalculateEdgeProjections=function(e){this.findEdgeControlPoints(e)};var us={recalculateNodeLabelProjection:function(e){var t=e.pstyle("label").strValue;if(!z(t)){var n,r,i=e._private,a=e.width(),o=e.height(),s=e.padding(),l=e.position(),u=e.pstyle("text-halign").strValue,c=e.pstyle("text-valign").strValue,h=i.rscratch,d=i.rstyle;switch(u){case"left":n=l.x-a/2-s;break;case"right":n=l.x+a/2+s;break;default:n=l.x}switch(c){case"top":r=l.y-o/2-s;break;case"bottom":r=l.y+o/2+s;break;default:r=l.y}h.labelX=n,h.labelY=r,d.labelX=n,d.labelY=r,this.calculateLabelAngles(e),this.applyLabelDimensions(e)}}},cs=function(e,t){var n=Math.atan(t/e);return 0===e&&n<0&&(n*=-1),n},hs=function(e,t){var n=t.x-e.x,r=t.y-e.y;return cs(n,r)};us.recalculateEdgeLabelProjections=function(e){var t,n=e._private,r=n.rscratch,i=this,a={mid:e.pstyle("label").strValue,source:e.pstyle("source-label").strValue,target:e.pstyle("target-label").strValue};if(a.mid||a.source||a.target){t={x:r.midX,y:r.midY};var o=function(e,t,r){Be(n.rscratch,e,t,r),Be(n.rstyle,e,t,r)};o("labelX",null,t.x),o("labelY",null,t.y);var s=cs(r.midDispX,r.midDispY);o("labelAutoAngle",null,s);var l=function e(){if(e.cache)return e.cache;for(var t=[],a=0;a+5<r.allpts.length;a+=4){var o={x:r.allpts[a],y:r.allpts[a+1]},s={x:r.allpts[a+2],y:r.allpts[a+3]},l={x:r.allpts[a+4],y:r.allpts[a+5]};t.push({p0:o,p1:s,p2:l,startDist:0,length:0,segments:[]})}var u=n.rstyle.bezierPts,c=i.bezierProjPcts.length;function h(e,t,n,r,i){var a=ut(t,n),o=e.segments[e.segments.length-1],s={p0:t,p1:n,t0:r,t1:i,startDist:o?o.startDist+o.length:0,length:a};e.segments.push(s),e.length+=a}for(var d=0;d<t.length;d++){var p=t[d],g=t[d-1];g&&(p.startDist=g.startDist+g.length),h(p,p.p0,u[d*c],0,i.bezierProjPcts[0]);for(var f=0;f<c-1;f++)h(p,u[d*c+f],u[d*c+f+1],i.bezierProjPcts[f],i.bezierProjPcts[f+1]);h(p,u[d*c+c-1],p.p2,i.bezierProjPcts[c-1],1)}return e.cache=t},u=function(n){var i,s="source"===n;if(a[n]){var u=e.pstyle(n+"-text-offset").pfValue;switch(r.edgeType){case"self":case"compound":case"bezier":case"multibezier":for(var c,h=l(),d=0,p=0,g=0;g<h.length;g++){for(var f=h[s?g:h.length-1-g],v=0;v<f.segments.length;v++){var y=f.segments[s?v:f.segments.length-1-v],m=g===h.length-1&&v===f.segments.length-1;if(d=p,(p+=y.length)>=u||m){c={cp:f,segment:y};break}}if(c)break}var b=c.cp,x=c.segment,w=(u-d)/x.length,E=x.t1-x.t0,_=s?x.t0+E*w:x.t1-E*w;_=gt(0,_,1),t=pt(b.p0,b.p1,b.p2,_),i=function(e,t,n,r){var i=gt(0,r-.001,1),a=gt(0,r+.001,1),o=pt(e,t,n,i),s=pt(e,t,n,a);return hs(o,s)}(b.p0,b.p1,b.p2,_);break;case"straight":case"segments":case"haystack":for(var T,D,C,N,A=0,L=r.allpts.length,k=0;k+3<L&&(s?(C={x:r.allpts[k],y:r.allpts[k+1]},N={x:r.allpts[k+2],y:r.allpts[k+3]}):(C={x:r.allpts[L-2-k],y:r.allpts[L-1-k]},N={x:r.allpts[L-4-k],y:r.allpts[L-3-k]}),D=A,!((A+=T=ut(C,N))>=u));k+=2);var S=(u-D)/T;S=gt(0,S,1),t=function(e,t,n,r){var i=t.x-e.x,a=t.y-e.y,o=ut(e,t),s=i/o,l=a/o;return n=null==n?0:n,r=null!=r?r:n*o,{x:e.x+s*r,y:e.y+l*r}}(C,N,S),i=hs(C,N)}o("labelX",n,t.x),o("labelY",n,t.y),o("labelAutoAngle",n,i)}};u("source"),u("target"),this.applyLabelDimensions(e)}},us.applyLabelDimensions=function(e){this.applyPrefixedLabelDimensions(e),e.isEdge()&&(this.applyPrefixedLabelDimensions(e,"source"),this.applyPrefixedLabelDimensions(e,"target"))},us.applyPrefixedLabelDimensions=function(e,t){var n=e._private,r=this.getLabelText(e,t),i=this.calculateLabelDimensions(e,r),a=e.pstyle("line-height").pfValue,o=e.pstyle("text-wrap").strValue,s=Re(n.rscratch,"labelWrapCachedLines",t)||[],l="wrap"!==o?1:Math.max(s.length,1),u=i.height/l,c=u*a,h=i.width,d=i.height+(l-1)*(a-1)*u;Be(n.rstyle,"labelWidth",t,h),Be(n.rscratch,"labelWidth",t,h),Be(n.rstyle,"labelHeight",t,d),Be(n.rscratch,"labelHeight",t,d),Be(n.rscratch,"labelLineHeight",t,c)},us.getLabelText=function(e,t){var n=e._private,r=t?t+"-":"",i=e.pstyle(r+"label").strValue,a=e.pstyle("text-transform").value,o=function(e,r){return r?(Be(n.rscratch,e,t,r),r):Re(n.rscratch,e,t)};if(!i)return"";"none"==a||("uppercase"==a?i=i.toUpperCase():"lowercase"==a&&(i=i.toLowerCase()));var s=e.pstyle("text-wrap").value;if("wrap"===s){var l=o("labelKey");if(null!=l&&o("labelWrapKey")===l)return o("labelWrapCachedText");for(var u=i.split("\n"),c=e.pstyle("text-max-width").pfValue,h="anywhere"===e.pstyle("text-overflow-wrap").value,d=[],p=/[\s\u200b]+/,g=h?"":" ",f=0;f<u.length;f++){var v=u[f],y=this.calculateLabelDimensions(e,v).width;if(h){var m=v.split("").join("\u200b");v=m}if(y>c){for(var b=v.split(p),x="",w=0;w<b.length;w++){var E=b[w],_=0===x.length?E:x+g+E;this.calculateLabelDimensions(e,_).width<=c?x+=E+g:(x&&d.push(x),x=E+g)}x.match(/^[\s\u200b]+$/)||d.push(x)}else d.push(v)}o("labelWrapCachedLines",d),i=o("labelWrapCachedText",d.join("\n")),o("labelWrapKey",l)}else if("ellipsis"===s){var T=e.pstyle("text-max-width").pfValue,D="",C=!1;if(this.calculateLabelDimensions(e,i).width<T)return i;for(var N=0;N<i.length;N++){if(this.calculateLabelDimensions(e,D+i[N]+"\u2026").width>T)break;D+=i[N],N===i.length-1&&(C=!0)}return C||(D+="\u2026"),D}return i},us.getLabelJustification=function(e){var t=e.pstyle("text-justification").strValue,n=e.pstyle("text-halign").strValue;if("auto"!==t)return t;if(!e.isNode())return"center";switch(n){case"left":return"right";case"right":return"left";default:return"center"}},us.calculateLabelDimensions=function(e,t){var n=fe(t,e._private.labelDimsKey),r=this.labelDimCache||(this.labelDimCache=[]),i=r[n];if(null!=i)return i;var a=e.pstyle("font-style").strValue,o=e.pstyle("font-size").pfValue,s=e.pstyle("font-family").strValue,l=e.pstyle("font-weight").strValue,u=this.labelCalcCanvas,c=this.labelCalcCanvasContext;if(!u){u=this.labelCalcCanvas=document.createElement("canvas"),c=this.labelCalcCanvasContext=u.getContext("2d");var h=u.style;h.position="absolute",h.left="-9999px",h.top="-9999px",h.zIndex="-1",h.visibility="hidden",h.pointerEvents="none"}c.font="".concat(a," ").concat(l," ").concat(o,"px ").concat(s);for(var d=0,p=0,g=t.split("\n"),f=0;f<g.length;f++){var v=g[f],y=c.measureText(v),m=Math.ceil(y.width),b=o;d=Math.max(m,d),p+=b}return d+=0,p+=0,r[n]={width:d,height:p}},us.calculateLabelAngle=function(e,t){var n=e._private.rscratch,r=e.isEdge(),i=t?t+"-":"",a=e.pstyle(i+"text-rotation"),o=a.strValue;return"none"===o?0:r&&"autorotate"===o?n.labelAutoAngle:"autorotate"===o?0:a.pfValue},us.calculateLabelAngles=function(e){var t=this,n=e.isEdge(),r=e._private.rscratch;r.labelAngle=t.calculateLabelAngle(e),n&&(r.sourceLabelAngle=t.calculateLabelAngle(e,"source"),r.targetLabelAngle=t.calculateLabelAngle(e,"target"))};var ds={},ps=!1;ds.getNodeShape=function(e){var t=e.pstyle("shape").value;if("cutrectangle"===t&&(e.width()<28||e.height()<28))return ps||(Ae("The `cutrectangle` node shape can not be used at small sizes so `rectangle` is used instead"),ps=!0),"rectangle";if(e.isParent())return"rectangle"===t||"roundrectangle"===t||"round-rectangle"===t||"cutrectangle"===t||"cut-rectangle"===t||"barrel"===t?t:"rectangle";if("polygon"===t){var n=e.pstyle("shape-polygon-points").value;return this.nodeShapes.makePolygon(n).name}return t};var gs={registerCalculationListeners:function(){var e=this.cy,t=e.collection(),n=this,r=function(e){var n=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(t.merge(e),n)for(var r=0;r<e.length;r++){var i=e[r]._private.rstyle;i.clean=!1,i.cleanConnected=!1}};n.binder(e).on("bounds.* dirty.*",(function(e){var t=e.target;r(t)})).on("style.* background.*",(function(e){var t=e.target;r(t,!1)}));var i=function(i){if(i){var a=n.onUpdateEleCalcsFns;t.cleanStyle();for(var o=0;o<t.length;o++){var s=t[o],l=s._private.rstyle;s.isNode()&&!l.cleanConnected&&(r(s.connectedEdges()),l.cleanConnected=!0)}if(a)for(var u=0;u<a.length;u++){(0,a[u])(i,t)}n.recalculateRenderedStyle(t),t=e.collection()}};n.flushRenderedStyleQueue=function(){i(!0)},n.beforeRender(i,n.beforeRenderPriorities.eleCalcs)},onUpdateEleCalcs:function(e){(this.onUpdateEleCalcsFns=this.onUpdateEleCalcsFns||[]).push(e)},recalculateRenderedStyle:function(e,t){var n=function(e){return e._private.rstyle.cleanConnected},r=[],i=[];if(!this.destroyed){void 0===t&&(t=!0);for(var a=0;a<e.length;a++){var o=e[a],s=o._private,l=s.rstyle;!o.isEdge()||n(o.source())&&n(o.target())||(l.clean=!1),t&&l.clean||o.removed()||"none"!==o.pstyle("display").value&&("nodes"===s.group?i.push(o):r.push(o),l.clean=!0)}for(var u=0;u<i.length;u++){var c=i[u],h=c._private.rstyle,d=c.position();this.recalculateNodeLabelProjection(c),h.nodeX=d.x,h.nodeY=d.y,h.nodeW=c.pstyle("width").pfValue,h.nodeH=c.pstyle("height").pfValue}this.recalculateEdgeProjections(r);for(var p=0;p<r.length;p++){var g=r[p]._private,f=g.rstyle,v=g.rscratch;f.srcX=v.arrowStartX,f.srcY=v.arrowStartY,f.tgtX=v.arrowEndX,f.tgtY=v.arrowEndY,f.midX=v.midX,f.midY=v.midY,f.labelAngle=v.labelAngle,f.sourceLabelAngle=v.sourceLabelAngle,f.targetLabelAngle=v.targetLabelAngle}}}},fs={updateCachedGrabbedEles:function(){var e=this.cachedZSortedEles;if(e){e.drag=[],e.nondrag=[];for(var t=[],n=0;n<e.length;n++){var r=(i=e[n])._private.rscratch;i.grabbed()&&!i.isParent()?t.push(i):r.inDragLayer?e.drag.push(i):e.nondrag.push(i)}for(n=0;n<t.length;n++){var i=t[n];e.drag.push(i)}}},invalidateCachedZSortedEles:function(){this.cachedZSortedEles=null},getCachedZSortedEles:function(e){if(e||!this.cachedZSortedEles){var t=this.cy.mutableElements().toArray();t.sort(Ji),t.interactive=t.filter((function(e){return e.interactive()})),this.cachedZSortedEles=t,this.updateCachedGrabbedEles()}else t=this.cachedZSortedEles;return t}},vs={};[ns,rs,is,os,ss,us,ds,gs,fs].forEach((function(e){Q(vs,e)}));var ys={getCachedImage:function(e,t,n){var r=this.imageCache=this.imageCache||{},i=r[e];if(i)return i.image.complete||i.image.addEventListener("load",n),i.image;var a=(i=r[e]=r[e]||{}).image=new Image;a.addEventListener("load",n),a.addEventListener("error",(function(){a.error=!0}));var o="data:";return e.substring(0,5).toLowerCase()===o||(t="null"===t?null:t,a.crossOrigin=t),a.src=e,a}},ms={registerBinding:function(e,t,n,r){var i=Array.prototype.slice.apply(arguments,[1]),a=this.binder(e);return a.on.apply(a,i)}};ms.binder=function(e){var t,n=this,r=n.cy.window(),i=e===r||e===r.document||e===r.document.body||(t=e,"undefined"!=typeof HTMLElement&&t instanceof HTMLElement);if(null==n.supportsPassiveEvents){var a=!1;try{var o=Object.defineProperty({},"passive",{get:function(){return a=!0,!0}});r.addEventListener("test",null,o)}catch(l){}n.supportsPassiveEvents=a}var s=function(t,r,a){var o=Array.prototype.slice.call(arguments);return i&&n.supportsPassiveEvents&&(o[2]={capture:null!=a&&a,passive:!1,once:!1}),n.bindings.push({target:e,args:o}),(e.addEventListener||e.on).apply(e,o),this};return{on:s,addEventListener:s,addListener:s,bind:s}},ms.nodeIsDraggable=function(e){return e&&e.isNode()&&!e.locked()&&e.grabbable()},ms.nodeIsGrabbable=function(e){return this.nodeIsDraggable(e)&&e.interactive()},ms.load=function(){var e=this,t=e.cy.window(),n=function(e){return e.selected()},r=function(t,n,r,i){null==t&&(t=e.cy);for(var a=0;a<n.length;a++){var o=n[a];t.emit({originalEvent:r,type:o,position:i})}},i=function(e){return e.shiftKey||e.metaKey||e.ctrlKey},a=function(t,n){var r=!0;if(e.cy.hasCompoundNodes()&&t&&t.pannable())for(var i=0;n&&i<n.length;i++){if((t=n[i]).isNode()&&t.isParent()&&!t.pannable()){r=!1;break}}else r=!0;return r},o=function(e){e[0]._private.rscratch.inDragLayer=!0},s=function(e){e[0]._private.rscratch.isGrabTarget=!0},l=function(e,t){var n=t.addToList;n.has(e)||!e.grabbable()||e.locked()||(n.merge(e),function(e){e[0]._private.grabbed=!0}(e))},c=function(t,n){n=n||{};var r=t.cy().hasCompoundNodes();n.inDragLayer&&(t.forEach(o),t.neighborhood().stdFilter((function(e){return!r||e.isEdge()})).forEach(o)),n.addToList&&t.forEach((function(e){l(e,n)})),function(e,t){if(e.cy().hasCompoundNodes()&&(null!=t.inDragLayer||null!=t.addToList)){var n=e.descendants();t.inDragLayer&&(n.forEach(o),n.connectedEdges().forEach(o)),t.addToList&&l(n,t)}}(t,n),p(t,{inDragLayer:n.inDragLayer}),e.updateCachedGrabbedEles()},h=c,d=function(t){t&&(e.getCachedZSortedEles().forEach((function(e){!function(e){e[0]._private.grabbed=!1}(e),function(e){e[0]._private.rscratch.inDragLayer=!1}(e),function(e){e[0]._private.rscratch.isGrabTarget=!1}(e)})),e.updateCachedGrabbedEles())},p=function(e,t){if((null!=t.inDragLayer||null!=t.addToList)&&e.cy().hasCompoundNodes()){var n=e.ancestors().orphans();if(!n.same(e)){var r=n.descendants().spawnSelf().merge(n).unmerge(e).unmerge(e.descendants()),i=r.connectedEdges();t.inDragLayer&&(i.forEach(o),r.forEach(o)),t.addToList&&r.forEach((function(e){l(e,t)}))}}},g=function(){null!=document.activeElement&&null!=document.activeElement.blur&&document.activeElement.blur()},f="undefined"!=typeof MutationObserver,v="undefined"!=typeof ResizeObserver;f?(e.removeObserver=new MutationObserver((function(t){for(var n=0;n<t.length;n++){var r=t[n].removedNodes;if(r)for(var i=0;i<r.length;i++){if(r[i]===e.container){e.destroy();break}}}})),e.container.parentNode&&e.removeObserver.observe(e.container.parentNode,{childList:!0})):e.registerBinding(e.container,"DOMNodeRemoved",(function(t){e.destroy()}));var y=u.default((function(){e.cy.resize()}),100);f&&(e.styleObserver=new MutationObserver(y),e.styleObserver.observe(e.container,{attributes:!0})),e.registerBinding(t,"resize",y),v&&(e.resizeObserver=new ResizeObserver(y),e.resizeObserver.observe(e.container));var m=function(){e.invalidateContainerClientCoordsCache()};!function(e,t){for(;null!=e;)t(e),e=e.parentNode}(e.container,(function(t){e.registerBinding(t,"transitionend",m),e.registerBinding(t,"animationend",m),e.registerBinding(t,"scroll",m)})),e.registerBinding(e.container,"contextmenu",(function(e){e.preventDefault()}));var b,x,w,E=function(t){for(var n=e.findContainerClientCoords(),r=n[0],i=n[1],a=n[2],o=n[3],s=t.touches?t.touches:[t],l=!1,u=0;u<s.length;u++){var c=s[u];if(r<=c.clientX&&c.clientX<=r+a&&i<=c.clientY&&c.clientY<=i+o){l=!0;break}}if(!l)return!1;for(var h=e.container,d=t.target.parentNode,p=!1;d;){if(d===h){p=!0;break}d=d.parentNode}return!!p};e.registerBinding(e.container,"mousedown",(function(t){if(E(t)){t.preventDefault(),g(),e.hoverData.capture=!0,e.hoverData.which=t.which;var n=e.cy,i=[t.clientX,t.clientY],a=e.projectIntoViewport(i[0],i[1]),o=e.selection,l=e.findNearestElements(a[0],a[1],!0,!1),u=l[0],d=e.dragData.possibleDragElements;e.hoverData.mdownPos=a,e.hoverData.mdownGPos=i;if(3==t.which){e.hoverData.cxtStarted=!0;var p={originalEvent:t,type:"cxttapstart",position:{x:a[0],y:a[1]}};u?(u.activate(),u.emit(p),e.hoverData.down=u):n.emit(p),e.hoverData.downTime=(new Date).getTime(),e.hoverData.cxtDragged=!1}else if(1==t.which){if(u&&u.activate(),null!=u&&e.nodeIsGrabbable(u)){var f=function(e){return{originalEvent:t,type:e,position:{x:a[0],y:a[1]}}};if(s(u),u.selected()){d=e.dragData.possibleDragElements=n.collection();var v=n.$((function(t){return t.isNode()&&t.selected()&&e.nodeIsGrabbable(t)}));c(v,{addToList:d}),u.emit(f("grabon")),v.forEach((function(e){e.emit(f("grab"))}))}else d=e.dragData.possibleDragElements=n.collection(),h(u,{addToList:d}),u.emit(f("grabon")).emit(f("grab"));e.redrawHint("eles",!0),e.redrawHint("drag",!0)}e.hoverData.down=u,e.hoverData.downs=l,e.hoverData.downTime=(new Date).getTime(),r(u,["mousedown","tapstart","vmousedown"],t,{x:a[0],y:a[1]}),null==u?(o[4]=1,e.data.bgActivePosistion={x:a[0],y:a[1]},e.redrawHint("select",!0),e.redraw()):u.pannable()&&(o[4]=1),e.hoverData.tapholdCancelled=!1,clearTimeout(e.hoverData.tapholdTimeout),e.hoverData.tapholdTimeout=setTimeout((function(){if(!e.hoverData.tapholdCancelled){var r=e.hoverData.down;r?r.emit({originalEvent:t,type:"taphold",position:{x:a[0],y:a[1]}}):n.emit({originalEvent:t,type:"taphold",position:{x:a[0],y:a[1]}})}}),e.tapholdDuration)}o[0]=o[2]=a[0],o[1]=o[3]=a[1]}}),!1),e.registerBinding(t,"mousemove",(function(t){if(e.hoverData.capture||E(t)){var n=!1,o=e.cy,s=o.zoom(),l=[t.clientX,t.clientY],u=e.projectIntoViewport(l[0],l[1]),h=e.hoverData.mdownPos,p=e.hoverData.mdownGPos,g=e.selection,f=null;e.hoverData.draggingEles||e.hoverData.dragging||e.hoverData.selecting||(f=e.findNearestElement(u[0],u[1],!0,!1));var v,y=e.hoverData.last,m=e.hoverData.down,b=[u[0]-g[2],u[1]-g[3]],x=e.dragData.possibleDragElements;if(p){var w=l[0]-p[0],_=w*w,T=l[1]-p[1],D=_+T*T;e.hoverData.isOverThresholdDrag=v=D>=e.desktopTapThreshold2}var C=i(t);v&&(e.hoverData.tapholdCancelled=!0);n=!0,r(f,["mousemove","vmousemove","tapdrag"],t,{x:u[0],y:u[1]});var N=function(){e.data.bgActivePosistion=void 0,e.hoverData.selecting||o.emit({originalEvent:t,type:"boxstart",position:{x:u[0],y:u[1]}}),g[4]=1,e.hoverData.selecting=!0,e.redrawHint("select",!0),e.redraw()};if(3===e.hoverData.which){if(v){var A={originalEvent:t,type:"cxtdrag",position:{x:u[0],y:u[1]}};m?m.emit(A):o.emit(A),e.hoverData.cxtDragged=!0,e.hoverData.cxtOver&&f===e.hoverData.cxtOver||(e.hoverData.cxtOver&&e.hoverData.cxtOver.emit({originalEvent:t,type:"cxtdragout",position:{x:u[0],y:u[1]}}),e.hoverData.cxtOver=f,f&&f.emit({originalEvent:t,type:"cxtdragover",position:{x:u[0],y:u[1]}}))}}else if(e.hoverData.dragging){if(n=!0,o.panningEnabled()&&o.userPanningEnabled()){var L;if(e.hoverData.justStartedPan){var k=e.hoverData.mdownPos;L={x:(u[0]-k[0])*s,y:(u[1]-k[1])*s},e.hoverData.justStartedPan=!1}else L={x:b[0]*s,y:b[1]*s};o.panBy(L),o.emit("dragpan"),e.hoverData.dragged=!0}u=e.projectIntoViewport(t.clientX,t.clientY)}else if(1!=g[4]||null!=m&&!m.pannable()){if(m&&m.pannable()&&m.active()&&m.unactivate(),m&&m.grabbed()||f==y||(y&&r(y,["mouseout","tapdragout"],t,{x:u[0],y:u[1]}),f&&r(f,["mouseover","tapdragover"],t,{x:u[0],y:u[1]}),e.hoverData.last=f),m)if(v){if(o.boxSelectionEnabled()&&C)m&&m.grabbed()&&(d(x),m.emit("freeon"),x.emit("free"),e.dragData.didDrag&&(m.emit("dragfreeon"),x.emit("dragfree"))),N();else if(m&&m.grabbed()&&e.nodeIsDraggable(m)){var S=!e.dragData.didDrag;S&&e.redrawHint("eles",!0),e.dragData.didDrag=!0,e.hoverData.draggingEles||c(x,{inDragLayer:!0});var M={x:0,y:0};if(I(b[0])&&I(b[1])&&(M.x+=b[0],M.y+=b[1],S)){var O=e.hoverData.dragDelta;O&&I(O[0])&&I(O[1])&&(M.x+=O[0],M.y+=O[1])}e.hoverData.draggingEles=!0,x.silentShift(M).emit("position drag"),e.redrawHint("drag",!0),e.redraw()}}else!function(){var t=e.hoverData.dragDelta=e.hoverData.dragDelta||[];0===t.length?(t.push(b[0]),t.push(b[1])):(t[0]+=b[0],t[1]+=b[1])}();n=!0}else if(v){if(e.hoverData.dragging||!o.boxSelectionEnabled()||!C&&o.panningEnabled()&&o.userPanningEnabled()){if(!e.hoverData.selecting&&o.panningEnabled()&&o.userPanningEnabled()){a(m,e.hoverData.downs)&&(e.hoverData.dragging=!0,e.hoverData.justStartedPan=!0,g[4]=0,e.data.bgActivePosistion=at(h),e.redrawHint("select",!0),e.redraw())}}else N();m&&m.pannable()&&m.active()&&m.unactivate()}return g[2]=u[0],g[3]=u[1],n?(t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),!1):void 0}}),!1),e.registerBinding(t,"mouseup",(function(t){if(e.hoverData.capture){e.hoverData.capture=!1;var a=e.cy,o=e.projectIntoViewport(t.clientX,t.clientY),s=e.selection,l=e.findNearestElement(o[0],o[1],!0,!1),u=e.dragData.possibleDragElements,c=e.hoverData.down,h=i(t);if(e.data.bgActivePosistion&&(e.redrawHint("select",!0),e.redraw()),e.hoverData.tapholdCancelled=!0,e.data.bgActivePosistion=void 0,c&&c.unactivate(),3===e.hoverData.which){var p={originalEvent:t,type:"cxttapend",position:{x:o[0],y:o[1]}};if(c?c.emit(p):a.emit(p),!e.hoverData.cxtDragged){var g={originalEvent:t,type:"cxttap",position:{x:o[0],y:o[1]}};c?c.emit(g):a.emit(g)}e.hoverData.cxtDragged=!1,e.hoverData.which=null}else if(1===e.hoverData.which){if(r(l,["mouseup","tapend","vmouseup"],t,{x:o[0],y:o[1]}),e.dragData.didDrag||e.hoverData.dragged||e.hoverData.selecting||e.hoverData.isOverThresholdDrag||(r(c,["click","tap","vclick"],t,{x:o[0],y:o[1]}),x=!1,t.timeStamp-w<=a.multiClickDebounceTime()?(b&&clearTimeout(b),x=!0,w=null,r(c,["dblclick","dbltap","vdblclick"],t,{x:o[0],y:o[1]})):(b=setTimeout((function(){x||r(c,["oneclick","onetap","voneclick"],t,{x:o[0],y:o[1]})}),a.multiClickDebounceTime()),w=t.timeStamp)),null!=c||e.dragData.didDrag||e.hoverData.selecting||e.hoverData.dragged||i(t)||(a.$(n).unselect(["tapunselect"]),u.length>0&&e.redrawHint("eles",!0),e.dragData.possibleDragElements=u=a.collection()),l!=c||e.dragData.didDrag||e.hoverData.selecting||null!=l&&l._private.selectable&&(e.hoverData.dragging||("additive"===a.selectionType()||h?l.selected()?l.unselect(["tapunselect"]):l.select(["tapselect"]):h||(a.$(n).unmerge(l).unselect(["tapunselect"]),l.select(["tapselect"]))),e.redrawHint("eles",!0)),e.hoverData.selecting){var f=a.collection(e.getAllInBox(s[0],s[1],s[2],s[3]));e.redrawHint("select",!0),f.length>0&&e.redrawHint("eles",!0),a.emit({type:"boxend",originalEvent:t,position:{x:o[0],y:o[1]}});var v=function(e){return e.selectable()&&!e.selected()};"additive"===a.selectionType()||h||a.$(n).unmerge(f).unselect(),f.emit("box").stdFilter(v).select().emit("boxselect"),e.redraw()}if(e.hoverData.dragging&&(e.hoverData.dragging=!1,e.redrawHint("select",!0),e.redrawHint("eles",!0),e.redraw()),!s[4]){e.redrawHint("drag",!0),e.redrawHint("eles",!0);var y=c&&c.grabbed();d(u),y&&(c.emit("freeon"),u.emit("free"),e.dragData.didDrag&&(c.emit("dragfreeon"),u.emit("dragfree")))}}s[4]=0,e.hoverData.down=null,e.hoverData.cxtStarted=!1,e.hoverData.draggingEles=!1,e.hoverData.selecting=!1,e.hoverData.isOverThresholdDrag=!1,e.dragData.didDrag=!1,e.hoverData.dragged=!1,e.hoverData.dragDelta=[],e.hoverData.mdownPos=null,e.hoverData.mdownGPos=null}}),!1);var _,T,D,C,N,A,L,k,S,M,O,P,R,B=function(t){if(!e.scrollingPage){var n=e.cy,r=n.zoom(),i=n.pan(),a=e.projectIntoViewport(t.clientX,t.clientY),o=[a[0]*r+i.x,a[1]*r+i.y];if(e.hoverData.draggingEles||e.hoverData.dragging||e.hoverData.cxtStarted||0!==e.selection[4])t.preventDefault();else if(n.panningEnabled()&&n.userPanningEnabled()&&n.zoomingEnabled()&&n.userZoomingEnabled()){var s;t.preventDefault(),e.data.wheelZooming=!0,clearTimeout(e.data.wheelTimeout),e.data.wheelTimeout=setTimeout((function(){e.data.wheelZooming=!1,e.redrawHint("eles",!0),e.redraw()}),150),s=null!=t.deltaY?t.deltaY/-250:null!=t.wheelDeltaY?t.wheelDeltaY/1e3:t.wheelDelta/1e3,s*=e.wheelSensitivity,1===t.deltaMode&&(s*=33);var l=n.zoom()*Math.pow(10,s);"gesturechange"===t.type&&(l=e.gestureStartZoom*t.scale),n.zoom({level:l,renderedPosition:{x:o[0],y:o[1]}}),n.emit("gesturechange"===t.type?"pinchzoom":"scrollzoom")}}};e.registerBinding(e.container,"wheel",B,!0),e.registerBinding(t,"scroll",(function(t){e.scrollingPage=!0,clearTimeout(e.scrollingPageTimeout),e.scrollingPageTimeout=setTimeout((function(){e.scrollingPage=!1}),250)}),!0),e.registerBinding(e.container,"gesturestart",(function(t){e.gestureStartZoom=e.cy.zoom(),e.hasTouchStarted||t.preventDefault()}),!0),e.registerBinding(e.container,"gesturechange",(function(t){e.hasTouchStarted||B(t)}),!0),e.registerBinding(e.container,"mouseout",(function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseout",position:{x:n[0],y:n[1]}})}),!1),e.registerBinding(e.container,"mouseover",(function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseover",position:{x:n[0],y:n[1]}})}),!1);var F,z,G,Y,X,V,U,j=function(e,t,n,r){return Math.sqrt((n-e)*(n-e)+(r-t)*(r-t))},q=function(e,t,n,r){return(n-e)*(n-e)+(r-t)*(r-t)};if(e.registerBinding(e.container,"touchstart",F=function(t){if(e.hasTouchStarted=!0,E(t)){g(),e.touchData.capture=!0,e.data.bgActivePosistion=void 0;var n=e.cy,i=e.touchData.now,a=e.touchData.earlier;if(t.touches[0]){var o=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);i[0]=o[0],i[1]=o[1]}if(t.touches[1]){o=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);i[2]=o[0],i[3]=o[1]}if(t.touches[2]){o=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);i[4]=o[0],i[5]=o[1]}if(t.touches[1]){e.touchData.singleTouchMoved=!0,d(e.dragData.touchDragEles);var l=e.findContainerClientCoords();S=l[0],M=l[1],O=l[2],P=l[3],_=t.touches[0].clientX-S,T=t.touches[0].clientY-M,D=t.touches[1].clientX-S,C=t.touches[1].clientY-M,R=0<=_&&_<=O&&0<=D&&D<=O&&0<=T&&T<=P&&0<=C&&C<=P;var u=n.pan(),p=n.zoom();N=j(_,T,D,C),A=q(_,T,D,C),k=[((L=[(_+D)/2,(T+C)/2])[0]-u.x)/p,(L[1]-u.y)/p];if(A<4e4&&!t.touches[2]){var f=e.findNearestElement(i[0],i[1],!0,!0),v=e.findNearestElement(i[2],i[3],!0,!0);return f&&f.isNode()?(f.activate().emit({originalEvent:t,type:"cxttapstart",position:{x:i[0],y:i[1]}}),e.touchData.start=f):v&&v.isNode()?(v.activate().emit({originalEvent:t,type:"cxttapstart",position:{x:i[0],y:i[1]}}),e.touchData.start=v):n.emit({originalEvent:t,type:"cxttapstart",position:{x:i[0],y:i[1]}}),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!0,e.touchData.cxtDragged=!1,e.data.bgActivePosistion=void 0,void e.redraw()}}if(t.touches[2])n.boxSelectionEnabled()&&t.preventDefault();else if(t.touches[1]);else if(t.touches[0]){var y=e.findNearestElements(i[0],i[1],!0,!0),m=y[0];if(null!=m&&(m.activate(),e.touchData.start=m,e.touchData.starts=y,e.nodeIsGrabbable(m))){var b=e.dragData.touchDragEles=n.collection(),x=null;e.redrawHint("eles",!0),e.redrawHint("drag",!0),m.selected()?(x=n.$((function(t){return t.selected()&&e.nodeIsGrabbable(t)})),c(x,{addToList:b})):h(m,{addToList:b}),s(m);var w=function(e){return{originalEvent:t,type:e,position:{x:i[0],y:i[1]}}};m.emit(w("grabon")),x?x.forEach((function(e){e.emit(w("grab"))})):m.emit(w("grab"))}r(m,["touchstart","tapstart","vmousedown"],t,{x:i[0],y:i[1]}),null==m&&(e.data.bgActivePosistion={x:o[0],y:o[1]},e.redrawHint("select",!0),e.redraw()),e.touchData.singleTouchMoved=!1,e.touchData.singleTouchStartTime=+new Date,clearTimeout(e.touchData.tapholdTimeout),e.touchData.tapholdTimeout=setTimeout((function(){!1!==e.touchData.singleTouchMoved||e.pinching||e.touchData.selecting||r(e.touchData.start,["taphold"],t,{x:i[0],y:i[1]})}),e.tapholdDuration)}if(t.touches.length>=1){for(var I=e.touchData.startPosition=[null,null,null,null,null,null],B=0;B<i.length;B++)I[B]=a[B]=i[B];var F=t.touches[0];e.touchData.startGPosition=[F.clientX,F.clientY]}}},!1),e.registerBinding(window,"touchmove",z=function(t){var n=e.touchData.capture;if(n||E(t)){var i=e.selection,o=e.cy,s=e.touchData.now,l=e.touchData.earlier,u=o.zoom();if(t.touches[0]){var h=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);s[0]=h[0],s[1]=h[1]}if(t.touches[1]){h=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);s[2]=h[0],s[3]=h[1]}if(t.touches[2]){h=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);s[4]=h[0],s[5]=h[1]}var p,g=e.touchData.startGPosition;if(n&&t.touches[0]&&g){for(var f=[],v=0;v<s.length;v++)f[v]=s[v]-l[v];var y=t.touches[0].clientX-g[0],m=y*y,b=t.touches[0].clientY-g[1];p=m+b*b>=e.touchTapThreshold2}if(n&&e.touchData.cxt){t.preventDefault();var x=t.touches[0].clientX-S,w=t.touches[0].clientY-M,L=t.touches[1].clientX-S,O=t.touches[1].clientY-M,P=q(x,w,L,O);if(P/A>=2.25||P>=22500){e.touchData.cxt=!1,e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var B={originalEvent:t,type:"cxttapend",position:{x:s[0],y:s[1]}};e.touchData.start?(e.touchData.start.unactivate().emit(B),e.touchData.start=null):o.emit(B)}}if(n&&e.touchData.cxt){B={originalEvent:t,type:"cxtdrag",position:{x:s[0],y:s[1]}};e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.touchData.start?e.touchData.start.emit(B):o.emit(B),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxtDragged=!0;var F=e.findNearestElement(s[0],s[1],!0,!0);e.touchData.cxtOver&&F===e.touchData.cxtOver||(e.touchData.cxtOver&&e.touchData.cxtOver.emit({originalEvent:t,type:"cxtdragout",position:{x:s[0],y:s[1]}}),e.touchData.cxtOver=F,F&&F.emit({originalEvent:t,type:"cxtdragover",position:{x:s[0],y:s[1]}}))}else if(n&&t.touches[2]&&o.boxSelectionEnabled())t.preventDefault(),e.data.bgActivePosistion=void 0,this.lastThreeTouch=+new Date,e.touchData.selecting||o.emit({originalEvent:t,type:"boxstart",position:{x:s[0],y:s[1]}}),e.touchData.selecting=!0,e.touchData.didSelect=!0,i[4]=1,i&&0!==i.length&&void 0!==i[0]?(i[2]=(s[0]+s[2]+s[4])/3,i[3]=(s[1]+s[3]+s[5])/3):(i[0]=(s[0]+s[2]+s[4])/3,i[1]=(s[1]+s[3]+s[5])/3,i[2]=(s[0]+s[2]+s[4])/3+1,i[3]=(s[1]+s[3]+s[5])/3+1),e.redrawHint("select",!0),e.redraw();else if(n&&t.touches[1]&&!e.touchData.didSelect&&o.zoomingEnabled()&&o.panningEnabled()&&o.userZoomingEnabled()&&o.userPanningEnabled()){if(t.preventDefault(),e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),ee=e.dragData.touchDragEles){e.redrawHint("drag",!0);for(var z=0;z<ee.length;z++){var G=ee[z]._private;G.grabbed=!1,G.rscratch.inDragLayer=!1}}var Y=e.touchData.start,X=(x=t.touches[0].clientX-S,w=t.touches[0].clientY-M,L=t.touches[1].clientX-S,O=t.touches[1].clientY-M,j(x,w,L,O)),V=X/N;if(R){var U=(x-_+(L-D))/2,H=(w-T+(O-C))/2,W=o.zoom(),$=W*V,K=o.pan(),Z=k[0]*W+K.x,Q=k[1]*W+K.y,J={x:-$/W*(Z-K.x-U)+Z,y:-$/W*(Q-K.y-H)+Q};if(Y&&Y.active()){var ee=e.dragData.touchDragEles;d(ee),e.redrawHint("drag",!0),e.redrawHint("eles",!0),Y.unactivate().emit("freeon"),ee.emit("free"),e.dragData.didDrag&&(Y.emit("dragfreeon"),ee.emit("dragfree"))}o.viewport({zoom:$,pan:J,cancelOnFailedZoom:!0}),o.emit("pinchzoom"),N=X,_=x,T=w,D=L,C=O,e.pinching=!0}if(t.touches[0]){h=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);s[0]=h[0],s[1]=h[1]}if(t.touches[1]){h=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);s[2]=h[0],s[3]=h[1]}if(t.touches[2]){h=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);s[4]=h[0],s[5]=h[1]}}else if(t.touches[0]&&!e.touchData.didSelect){var te=e.touchData.start,ne=e.touchData.last;if(e.hoverData.draggingEles||e.swipePanning||(F=e.findNearestElement(s[0],s[1],!0,!0)),n&&null!=te&&t.preventDefault(),n&&null!=te&&e.nodeIsDraggable(te))if(p){ee=e.dragData.touchDragEles;var re=!e.dragData.didDrag;re&&c(ee,{inDragLayer:!0}),e.dragData.didDrag=!0;var ie={x:0,y:0};if(I(f[0])&&I(f[1]))if(ie.x+=f[0],ie.y+=f[1],re)e.redrawHint("eles",!0),(ae=e.touchData.dragDelta)&&I(ae[0])&&I(ae[1])&&(ie.x+=ae[0],ie.y+=ae[1]);e.hoverData.draggingEles=!0,ee.silentShift(ie).emit("position drag"),e.redrawHint("drag",!0),e.touchData.startPosition[0]==l[0]&&e.touchData.startPosition[1]==l[1]&&e.redrawHint("eles",!0),e.redraw()}else{var ae;0===(ae=e.touchData.dragDelta=e.touchData.dragDelta||[]).length?(ae.push(f[0]),ae.push(f[1])):(ae[0]+=f[0],ae[1]+=f[1])}if(r(te||F,["touchmove","tapdrag","vmousemove"],t,{x:s[0],y:s[1]}),te&&te.grabbed()||F==ne||(ne&&ne.emit({originalEvent:t,type:"tapdragout",position:{x:s[0],y:s[1]}}),F&&F.emit({originalEvent:t,type:"tapdragover",position:{x:s[0],y:s[1]}})),e.touchData.last=F,n)for(z=0;z<s.length;z++)s[z]&&e.touchData.startPosition[z]&&p&&(e.touchData.singleTouchMoved=!0);if(n&&(null==te||te.pannable())&&o.panningEnabled()&&o.userPanningEnabled()){a(te,e.touchData.starts)&&(t.preventDefault(),e.data.bgActivePosistion||(e.data.bgActivePosistion=at(e.touchData.startPosition)),e.swipePanning?(o.panBy({x:f[0]*u,y:f[1]*u}),o.emit("dragpan")):p&&(e.swipePanning=!0,o.panBy({x:y*u,y:b*u}),o.emit("dragpan"),te&&(te.unactivate(),e.redrawHint("select",!0),e.touchData.start=null)));h=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);s[0]=h[0],s[1]=h[1]}}for(v=0;v<s.length;v++)l[v]=s[v];n&&t.touches.length>0&&!e.hoverData.draggingEles&&!e.swipePanning&&null!=e.data.bgActivePosistion&&(e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.redraw())}},!1),e.registerBinding(t,"touchcancel",G=function(t){var n=e.touchData.start;e.touchData.capture=!1,n&&n.unactivate()}),e.registerBinding(t,"touchend",Y=function(t){var i=e.touchData.start;if(e.touchData.capture){0===t.touches.length&&(e.touchData.capture=!1),t.preventDefault();var a=e.selection;e.swipePanning=!1,e.hoverData.draggingEles=!1;var o,s=e.cy,l=s.zoom(),u=e.touchData.now,c=e.touchData.earlier;if(t.touches[0]){var h=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);u[0]=h[0],u[1]=h[1]}if(t.touches[1]){h=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);u[2]=h[0],u[3]=h[1]}if(t.touches[2]){h=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);u[4]=h[0],u[5]=h[1]}if(i&&i.unactivate(),e.touchData.cxt){if(o={originalEvent:t,type:"cxttapend",position:{x:u[0],y:u[1]}},i?i.emit(o):s.emit(o),!e.touchData.cxtDragged){var p={originalEvent:t,type:"cxttap",position:{x:u[0],y:u[1]}};i?i.emit(p):s.emit(p)}return e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!1,e.touchData.start=null,void e.redraw()}if(!t.touches[2]&&s.boxSelectionEnabled()&&e.touchData.selecting){e.touchData.selecting=!1;var g=s.collection(e.getAllInBox(a[0],a[1],a[2],a[3]));a[0]=void 0,a[1]=void 0,a[2]=void 0,a[3]=void 0,a[4]=0,e.redrawHint("select",!0),s.emit({type:"boxend",originalEvent:t,position:{x:u[0],y:u[1]}});g.emit("box").stdFilter((function(e){return e.selectable()&&!e.selected()})).select().emit("boxselect"),g.nonempty()&&e.redrawHint("eles",!0),e.redraw()}if(null!=i&&i.unactivate(),t.touches[2])e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);else if(t.touches[1]);else if(t.touches[0]);else if(!t.touches[0]){e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var f=e.dragData.touchDragEles;if(null!=i){var v=i._private.grabbed;d(f),e.redrawHint("drag",!0),e.redrawHint("eles",!0),v&&(i.emit("freeon"),f.emit("free"),e.dragData.didDrag&&(i.emit("dragfreeon"),f.emit("dragfree"))),r(i,["touchend","tapend","vmouseup","tapdragout"],t,{x:u[0],y:u[1]}),i.unactivate(),e.touchData.start=null}else{var y=e.findNearestElement(u[0],u[1],!0,!0);r(y,["touchend","tapend","vmouseup","tapdragout"],t,{x:u[0],y:u[1]})}var m=e.touchData.startPosition[0]-u[0],b=m*m,x=e.touchData.startPosition[1]-u[1],w=(b+x*x)*l*l;e.touchData.singleTouchMoved||(i||s.$(":selected").unselect(["tapunselect"]),r(i,["tap","vclick"],t,{x:u[0],y:u[1]}),X=!1,t.timeStamp-U<=s.multiClickDebounceTime()?(V&&clearTimeout(V),X=!0,U=null,r(i,["dbltap","vdblclick"],t,{x:u[0],y:u[1]})):(V=setTimeout((function(){X||r(i,["onetap","voneclick"],t,{x:u[0],y:u[1]})}),s.multiClickDebounceTime()),U=t.timeStamp)),null!=i&&!e.dragData.didDrag&&i._private.selectable&&w<e.touchTapThreshold2&&!e.pinching&&("single"===s.selectionType()?(s.$(n).unmerge(i).unselect(["tapunselect"]),i.select(["tapselect"])):i.selected()?i.unselect(["tapunselect"]):i.select(["tapselect"]),e.redrawHint("eles",!0)),e.touchData.singleTouchMoved=!0}for(var E=0;E<u.length;E++)c[E]=u[E];e.dragData.didDrag=!1,0===t.touches.length&&(e.touchData.dragDelta=[],e.touchData.startPosition=[null,null,null,null,null,null],e.touchData.startGPosition=null,e.touchData.didSelect=!1),t.touches.length<2&&(1===t.touches.length&&(e.touchData.startGPosition=[t.touches[0].clientX,t.touches[0].clientY]),e.pinching=!1,e.redrawHint("eles",!0),e.redraw())}},!1),"undefined"==typeof TouchEvent){var H=[],W=function(e){return{clientX:e.clientX,clientY:e.clientY,force:1,identifier:e.pointerId,pageX:e.pageX,pageY:e.pageY,radiusX:e.width/2,radiusY:e.height/2,screenX:e.screenX,screenY:e.screenY,target:e.target}},$=function(e){H.push(function(e){return{event:e,touch:W(e)}}(e))},K=function(e){for(var t=0;t<H.length;t++){if(H[t].event.pointerId===e.pointerId)return void H.splice(t,1)}},Z=function(e){e.touches=H.map((function(e){return e.touch}))},Q=function(e){return"mouse"===e.pointerType||4===e.pointerType};e.registerBinding(e.container,"pointerdown",(function(e){Q(e)||(e.preventDefault(),$(e),Z(e),F(e))})),e.registerBinding(e.container,"pointerup",(function(e){Q(e)||(K(e),Z(e),Y(e))})),e.registerBinding(e.container,"pointercancel",(function(e){Q(e)||(K(e),Z(e),G())})),e.registerBinding(e.container,"pointermove",(function(e){Q(e)||(e.preventDefault(),function(e){var t=H.filter((function(t){return t.event.pointerId===e.pointerId}))[0];t.event=e,t.touch=W(e)}(e),Z(e),z(e))}))}};var bs={generatePolygon:function(e,t){return this.nodeShapes[e]={renderer:this,name:e,points:t,draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl("polygon",e,t,n,r,i,this.points)},intersectLine:function(e,t,n,r,i,a,o){return Bt(i,a,this.points,e,t,n/2,r/2,o)},checkPoint:function(e,t,n,r,i,a,o){return kt(e,t,this.points,a,o,r,i,[0,-1],n)}}}};bs.generateEllipse=function(){return this.nodeShapes.ellipse={renderer:this,name:"ellipse",draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},intersectLine:function(e,t,n,r,i,a,o){return function(e,t,n,r,i,a){var o=n-e,s=r-t;o/=i,s/=a;var l=Math.sqrt(o*o+s*s),u=l-1;if(u<0)return[];var c=u/l;return[(n-e)*c+e,(r-t)*c+t]}(i,a,e,t,n/2+o,r/2+o)},checkPoint:function(e,t,n,r,i,a,o){return Mt(e,t,r,i,a,o,n)}}},bs.generateRoundPolygon=function(e,t){for(var n=new Array(2*t.length),r=0;r<t.length/2;r++){var i=2*r,a=void 0;a=r<t.length/2-1?2*(r+1):0,n[4*r]=t[i],n[4*r+1]=t[i+1];var o=t[a]-t[i],s=t[a+1]-t[i+1],l=Math.sqrt(o*o+s*s);n[4*r+2]=o/l,n[4*r+3]=s/l}return this.nodeShapes[e]={renderer:this,name:e,points:n,draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl("round-polygon",e,t,n,r,i,this.points)},intersectLine:function(e,t,n,r,i,a,o){return function(e,t,n,r,i,a,o,s){for(var l,u=[],c=new Array(n.length),h=a/2,d=o/2,p=Vt(a,o),g=0;g<n.length/4;g++){var f,v=void 0;v=0===g?n.length-2:4*g-2,f=4*g+2;var y=r+h*n[4*g],m=i+d*n[4*g+1],b=-n[v]*n[f]-n[v+1]*n[f+1],x=p/Math.tan(Math.acos(b)/2),w=y-x*n[v],E=m-x*n[v+1],_=y+x*n[f],T=m+x*n[f+1];0===g?(c[n.length-2]=w,c[n.length-1]=E):(c[4*g-2]=w,c[4*g-1]=E),c[4*g]=_,c[4*g+1]=T;var D=n[v+1],C=-n[v];D*n[f]+C*n[f+1]<0&&(D*=-1,C*=-1),0!==(l=Ot(e,t,r,i,w+D*p,E+C*p,p)).length&&u.push(l[0],l[1])}for(var N=0;N<c.length/4;N++)0!==(l=Rt(e,t,r,i,c[4*N],c[4*N+1],c[4*N+2],c[4*N+3],!1)).length&&u.push(l[0],l[1]);if(u.length>2){for(var A=[u[0],u[1]],L=Math.pow(A[0]-e,2)+Math.pow(A[1]-t,2),k=1;k<u.length/2;k++){var S=Math.pow(u[2*k]-e,2)+Math.pow(u[2*k+1]-t,2);S<=L&&(A[0]=u[2*k],A[1]=u[2*k+1],L=S)}return A}return u}(i,a,this.points,e,t,n,r)},checkPoint:function(e,t,n,r,i,a,o){return function(e,t,n,r,i,a,o){for(var s=new Array(n.length),l=a/2,u=o/2,c=Vt(a,o),h=c*c,d=0;d<n.length/4;d++){var p,g=void 0;g=0===d?n.length-2:4*d-2,p=4*d+2;var f=r+l*n[4*d],v=i+u*n[4*d+1],y=-n[g]*n[p]-n[g+1]*n[p+1],m=c/Math.tan(Math.acos(y)/2),b=f-m*n[g],x=v-m*n[g+1],w=f+m*n[p],E=v+m*n[p+1];s[4*d]=b,s[4*d+1]=x,s[4*d+2]=w,s[4*d+3]=E;var _=n[g+1],T=-n[g];_*n[p]+T*n[p+1]<0&&(_*=-1,T*=-1);var D=b+_*c,C=x+T*c;if(Math.pow(D-e,2)+Math.pow(C-t,2)<=h)return!0}return Lt(e,t,s)}(e,t,this.points,a,o,r,i)}}},bs.generateRoundRectangle=function(){return this.nodeShapes["round-rectangle"]=this.nodeShapes.roundrectangle={renderer:this,name:"round-rectangle",points:zt(4,0),draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},intersectLine:function(e,t,n,r,i,a,o){return Tt(i,a,e,t,n,r,o)},checkPoint:function(e,t,n,r,i,a,o){var s=Xt(r,i),l=2*s;return!!kt(e,t,this.points,a,o,r,i-l,[0,-1],n)||(!!kt(e,t,this.points,a,o,r-l,i,[0,-1],n)||(!!Mt(e,t,l,l,a-r/2+s,o-i/2+s,n)||(!!Mt(e,t,l,l,a+r/2-s,o-i/2+s,n)||(!!Mt(e,t,l,l,a+r/2-s,o+i/2-s,n)||!!Mt(e,t,l,l,a-r/2+s,o+i/2-s,n)))))}}},bs.generateCutRectangle=function(){return this.nodeShapes["cut-rectangle"]=this.nodeShapes.cutrectangle={renderer:this,name:"cut-rectangle",cornerLength:8,points:zt(4,0),draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},generateCutTrianglePts:function(e,t,n,r){var i=this.cornerLength,a=t/2,o=e/2,s=n-o,l=n+o,u=r-a,c=r+a;return{topLeft:[s,u+i,s+i,u,s+i,u+i],topRight:[l-i,u,l,u+i,l-i,u+i],bottomRight:[l,c-i,l-i,c,l-i,c-i],bottomLeft:[s+i,c,s,c-i,s+i,c-i]}},intersectLine:function(e,t,n,r,i,a,o){var s=this.generateCutTrianglePts(n+2*o,r+2*o,e,t),l=[].concat.apply([],[s.topLeft.splice(0,4),s.topRight.splice(0,4),s.bottomRight.splice(0,4),s.bottomLeft.splice(0,4)]);return Bt(i,a,l,e,t)},checkPoint:function(e,t,n,r,i,a,o){if(kt(e,t,this.points,a,o,r,i-2*this.cornerLength,[0,-1],n))return!0;if(kt(e,t,this.points,a,o,r-2*this.cornerLength,i,[0,-1],n))return!0;var s=this.generateCutTrianglePts(r,i,a,o);return Lt(e,t,s.topLeft)||Lt(e,t,s.topRight)||Lt(e,t,s.bottomRight)||Lt(e,t,s.bottomLeft)}}},bs.generateBarrel=function(){return this.nodeShapes.barrel={renderer:this,name:"barrel",points:zt(4,0),draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},intersectLine:function(e,t,n,r,i,a,o){var s=this.generateBarrelBezierPts(n+2*o,r+2*o,e,t),l=function(e){var t=pt({x:e[0],y:e[1]},{x:e[2],y:e[3]},{x:e[4],y:e[5]},.15),n=pt({x:e[0],y:e[1]},{x:e[2],y:e[3]},{x:e[4],y:e[5]},.5),r=pt({x:e[0],y:e[1]},{x:e[2],y:e[3]},{x:e[4],y:e[5]},.85);return[e[0],e[1],t.x,t.y,n.x,n.y,r.x,r.y,e[4],e[5]]},u=[].concat(l(s.topLeft),l(s.topRight),l(s.bottomRight),l(s.bottomLeft));return Bt(i,a,u,e,t)},generateBarrelBezierPts:function(e,t,n,r){var i=t/2,a=e/2,o=n-a,s=n+a,l=r-i,u=r+i,c=Ut(e,t),h=c.heightOffset,d=c.widthOffset,p=c.ctrlPtOffsetPct*e,g={topLeft:[o,l+h,o+p,l,o+d,l],topRight:[s-d,l,s-p,l,s,l+h],bottomRight:[s,u-h,s-p,u,s-d,u],bottomLeft:[o+d,u,o+p,u,o,u-h]};return g.topLeft.isTop=!0,g.topRight.isTop=!0,g.bottomLeft.isBottom=!0,g.bottomRight.isBottom=!0,g},checkPoint:function(e,t,n,r,i,a,o){var s=Ut(r,i),l=s.heightOffset,u=s.widthOffset;if(kt(e,t,this.points,a,o,r,i-2*l,[0,-1],n))return!0;if(kt(e,t,this.points,a,o,r-2*u,i,[0,-1],n))return!0;for(var c=this.generateBarrelBezierPts(r,i,a,o),h=function(e,t,n){var r,i,a=n[4],o=n[2],s=n[0],l=n[5],u=n[1],c=Math.min(a,s),h=Math.max(a,s),d=Math.min(l,u),p=Math.max(l,u);if(c<=e&&e<=h&&d<=t&&t<=p){var g=[(r=a)-2*(i=o)+s,2*(i-r),r],f=function(e,t,n,r){var i=t*t-4*e*(n-=r);if(i<0)return[];var a=Math.sqrt(i),o=2*e;return[(-t+a)/o,(-t-a)/o]}(g[0],g[1],g[2],e).filter((function(e){return 0<=e&&e<=1}));if(f.length>0)return f[0]}return null},d=Object.keys(c),p=0;p<d.length;p++){var g=c[d[p]],f=h(e,t,g);if(null!=f){var v=g[5],y=g[3],m=g[1],b=dt(v,y,m,f);if(g.isTop&&b<=t)return!0;if(g.isBottom&&t<=b)return!0}}return!1}}},bs.generateBottomRoundrectangle=function(){return this.nodeShapes["bottom-round-rectangle"]=this.nodeShapes.bottomroundrectangle={renderer:this,name:"bottom-round-rectangle",points:zt(4,0),draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},intersectLine:function(e,t,n,r,i,a,o){var s=t-(r/2+o),l=Rt(i,a,e,t,e-(n/2+o),s,e+(n/2+o),s,!1);return l.length>0?l:Tt(i,a,e,t,n,r,o)},checkPoint:function(e,t,n,r,i,a,o){var s=Xt(r,i),l=2*s;if(kt(e,t,this.points,a,o,r,i-l,[0,-1],n))return!0;if(kt(e,t,this.points,a,o,r-l,i,[0,-1],n))return!0;var u=r/2+2*n,c=i/2+2*n;return!!Lt(e,t,[a-u,o-c,a-u,o,a+u,o,a+u,o-c])||(!!Mt(e,t,l,l,a+r/2-s,o+i/2-s,n)||!!Mt(e,t,l,l,a-r/2+s,o+i/2-s,n))}}},bs.registerNodeShapes=function(){var e=this.nodeShapes={},t=this;this.generateEllipse(),this.generatePolygon("triangle",zt(3,0)),this.generateRoundPolygon("round-triangle",zt(3,0)),this.generatePolygon("rectangle",zt(4,0)),e.square=e.rectangle,this.generateRoundRectangle(),this.generateCutRectangle(),this.generateBarrel(),this.generateBottomRoundrectangle();var n=[0,1,1,0,0,-1,-1,0];this.generatePolygon("diamond",n),this.generateRoundPolygon("round-diamond",n),this.generatePolygon("pentagon",zt(5,0)),this.generateRoundPolygon("round-pentagon",zt(5,0)),this.generatePolygon("hexagon",zt(6,0)),this.generateRoundPolygon("round-hexagon",zt(6,0)),this.generatePolygon("heptagon",zt(7,0)),this.generateRoundPolygon("round-heptagon",zt(7,0)),this.generatePolygon("octagon",zt(8,0)),this.generateRoundPolygon("round-octagon",zt(8,0));var r=new Array(20),i=Yt(5,0),a=Yt(5,Math.PI/5),o=.5*(3-Math.sqrt(5));o*=1.57;for(var s=0;s<a.length/2;s++)a[2*s]*=o,a[2*s+1]*=o;for(s=0;s<5;s++)r[4*s]=i[2*s],r[4*s+1]=i[2*s+1],r[4*s+2]=a[2*s],r[4*s+3]=a[2*s+1];r=Gt(r),this.generatePolygon("star",r),this.generatePolygon("vee",[-1,-1,0,-.333,1,-1,0,1]),this.generatePolygon("rhomboid",[-1,-1,.333,-1,1,1,-.333,1]),this.generatePolygon("right-rhomboid",[-.333,-1,1,-1,.333,1,-1,1]),this.nodeShapes.concavehexagon=this.generatePolygon("concave-hexagon",[-1,-.95,-.75,0,-1,.95,1,.95,.75,0,1,-.95]);var l=[-1,-1,.25,-1,1,0,.25,1,-1,1];this.generatePolygon("tag",l),this.generateRoundPolygon("round-tag",l),e.makePolygon=function(e){var n,r="polygon-"+e.join("$");return(n=this[r])?n:t.generatePolygon(r,e)}};var xs={timeToRender:function(){return this.redrawTotalTime/this.redrawCount},redraw:function(e){e=e||Ie();var t=this;void 0===t.averageRedrawTime&&(t.averageRedrawTime=0),void 0===t.lastRedrawTime&&(t.lastRedrawTime=0),void 0===t.lastDrawTime&&(t.lastDrawTime=0),t.requestedFrame=!0,t.renderOptions=e},beforeRender:function(e,t){if(!this.destroyed){null==t&&Ce("Priority is not optional for beforeRender");var n=this.beforeRenderCallbacks;n.push({fn:e,priority:t}),n.sort((function(e,t){return t.priority-e.priority}))}}},ws=function(e,t,n){for(var r=e.beforeRenderCallbacks,i=0;i<r.length;i++)r[i].fn(t,n)};xs.startRenderLoop=function(){var e=this,t=e.cy;if(!e.renderLoopStarted){e.renderLoopStarted=!0;oe((function n(r){if(!e.destroyed){if(t.batching());else if(e.requestedFrame&&!e.skipFrame){ws(e,!0,r);var i=se();e.render(e.renderOptions);var a=e.lastDrawTime=se();void 0===e.averageRedrawTime&&(e.averageRedrawTime=a-i),void 0===e.redrawCount&&(e.redrawCount=0),e.redrawCount++,void 0===e.redrawTotalTime&&(e.redrawTotalTime=0);var o=a-i;e.redrawTotalTime+=o,e.lastRedrawTime=o,e.averageRedrawTime=e.averageRedrawTime/2+o/2,e.requestedFrame=!1}else ws(e,!1,r);e.skipFrame=!1,oe(n)}}))}};var Es=function(e){this.init(e)},_s=Es.prototype;_s.clientFunctions=["redrawHint","render","renderTo","matchCanvasSize","nodeShapeImpl","arrowShapeImpl"],_s.init=function(e){var t=this;t.options=e,t.cy=e.cy;var n=t.container=e.cy.container(),r=t.cy.window();if(r){var i=r.document,a=i.head,o="__________cytoscape_stylesheet",s="__________cytoscape_container",l=null!=i.getElementById(o);if(n.className.indexOf(s)<0&&(n.className=(n.className||"")+" "+s),!l){var u=i.createElement("style");u.id=o,u.textContent="."+s+" { position: relative; }",a.insertBefore(u,a.children[0])}"static"===r.getComputedStyle(n).getPropertyValue("position")&&Ae("A Cytoscape container has style position:static and so can not use UI extensions properly")}t.selection=[void 0,void 0,void 0,void 0,0],t.bezierProjPcts=[.05,.225,.4,.5,.6,.775,.95],t.hoverData={down:null,last:null,downTime:null,triggerMode:null,dragging:!1,initialPan:[null,null],capture:!1},t.dragData={possibleDragElements:[]},t.touchData={start:null,capture:!1,startPosition:[null,null,null,null,null,null],singleTouchStartTime:null,singleTouchMoved:!0,now:[null,null,null,null,null,null],earlier:[null,null,null,null,null,null]},t.redraws=0,t.showFps=e.showFps,t.debug=e.debug,t.hideEdgesOnViewport=e.hideEdgesOnViewport,t.textureOnViewport=e.textureOnViewport,t.wheelSensitivity=e.wheelSensitivity,t.motionBlurEnabled=e.motionBlur,t.forcedPixelRatio=I(e.pixelRatio)?e.pixelRatio:null,t.motionBlur=e.motionBlur,t.motionBlurOpacity=e.motionBlurOpacity,t.motionBlurTransparency=1-t.motionBlurOpacity,t.motionBlurPxRatio=1,t.mbPxRBlurry=1,t.minMbLowQualFrames=4,t.fullQualityMb=!1,t.clearedForMotionBlur=[],t.desktopTapThreshold=e.desktopTapThreshold,t.desktopTapThreshold2=e.desktopTapThreshold*e.desktopTapThreshold,t.touchTapThreshold=e.touchTapThreshold,t.touchTapThreshold2=e.touchTapThreshold*e.touchTapThreshold,t.tapholdDuration=500,t.bindings=[],t.beforeRenderCallbacks=[],t.beforeRenderPriorities={animations:400,eleCalcs:300,eleTxrDeq:200,lyrTxrDeq:150,lyrTxrSkip:100},t.registerNodeShapes(),t.registerArrowShapes(),t.registerCalculationListeners()},_s.notify=function(e,t){var n=this,r=n.cy;this.destroyed||("init"!==e?"destroy"!==e?(("add"===e||"remove"===e||"move"===e&&r.hasCompoundNodes()||"load"===e||"zorder"===e||"mount"===e)&&n.invalidateCachedZSortedEles(),"viewport"===e&&n.redrawHint("select",!0),"load"!==e&&"resize"!==e&&"mount"!==e||(n.invalidateContainerClientCoordsCache(),n.matchCanvasSize(n.container)),n.redrawHint("eles",!0),n.redrawHint("drag",!0),this.startRenderLoop(),this.redraw()):n.destroy():n.load())},_s.destroy=function(){var e=this;e.destroyed=!0,e.cy.stopAnimationLoop();for(var t=0;t<e.bindings.length;t++){var n=e.bindings[t],r=n.target;(r.off||r.removeEventListener).apply(r,n.args)}if(e.bindings=[],e.beforeRenderCallbacks=[],e.onUpdateEleCalcsFns=[],e.removeObserver&&e.removeObserver.disconnect(),e.styleObserver&&e.styleObserver.disconnect(),e.resizeObserver&&e.resizeObserver.disconnect(),e.labelCalcDiv)try{document.body.removeChild(e.labelCalcDiv)}catch(i){}},_s.isHeadless=function(){return!1},[ts,vs,ys,ms,bs,xs].forEach((function(e){Q(_s,e)}));var Ts=1e3/60,Ds=function(e){return function(){var t=this,n=this.renderer;if(!t.dequeueingSetup){t.dequeueingSetup=!0;var r=u.default((function(){n.redrawHint("eles",!0),n.redrawHint("drag",!0),n.redraw()}),e.deqRedrawThreshold),i=e.priority||De;n.beforeRender((function(i,a){var o=se(),s=n.averageRedrawTime,l=n.lastRedrawTime,u=[],c=n.cy.extent(),h=n.getPixelRatio();for(i||n.flushRenderedStyleQueue();;){var d=se(),p=d-o,g=d-a;if(l<Ts){var f=Ts-(i?s:0);if(g>=e.deqFastCost*f)break}else if(i){if(p>=e.deqCost*l||p>=e.deqAvgCost*s)break}else if(g>=e.deqNoDrawCost*Ts)break;var v=e.deq(t,h,c);if(!(v.length>0))break;for(var y=0;y<v.length;y++)u.push(v[y])}u.length>0&&(e.onDeqd(t,u),!i&&e.shouldRedraw(t,u,h,c)&&r())}),i(t))}}},Cs=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:_e;f(this,e),this.idsByKey=new Fe,this.keyForId=new Fe,this.cachesByLvl=new Fe,this.lvls=[],this.getKey=t,this.doesEleInvalidateKey=n}return y(e,[{key:"getIdsFor",value:function(e){null==e&&Ce("Can not get id list for null key");var t=this.idsByKey,n=this.idsByKey.get(e);return n||(n=new Ge,t.set(e,n)),n}},{key:"addIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).add(t)}},{key:"deleteIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).delete(t)}},{key:"getNumberOfIdsForKey",value:function(e){return null==e?0:this.getIdsFor(e).size}},{key:"updateKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t),r=this.getKey(e);this.deleteIdForKey(n,t),this.addIdForKey(r,t),this.keyForId.set(t,r)}},{key:"deleteKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteIdForKey(n,t),this.keyForId.delete(t)}},{key:"keyHasChangedFor",value:function(e){var t=e.id();return this.keyForId.get(t)!==this.getKey(e)}},{key:"isInvalid",value:function(e){return this.keyHasChangedFor(e)||this.doesEleInvalidateKey(e)}},{key:"getCachesAt",value:function(e){var t=this.cachesByLvl,n=this.lvls,r=t.get(e);return r||(r=new Fe,t.set(e,r),n.push(e)),r}},{key:"getCache",value:function(e,t){return this.getCachesAt(t).get(e)}},{key:"get",value:function(e,t){var n=this.getKey(e),r=this.getCache(n,t);return null!=r&&this.updateKeyMappingFor(e),r}},{key:"getForCachedKey",value:function(e,t){var n=this.keyForId.get(e.id());return this.getCache(n,t)}},{key:"hasCache",value:function(e,t){return this.getCachesAt(t).has(e)}},{key:"has",value:function(e,t){var n=this.getKey(e);return this.hasCache(n,t)}},{key:"setCache",value:function(e,t,n){n.key=e,this.getCachesAt(t).set(e,n)}},{key:"set",value:function(e,t,n){var r=this.getKey(e);this.setCache(r,t,n),this.updateKeyMappingFor(e)}},{key:"deleteCache",value:function(e,t){this.getCachesAt(t).delete(e)}},{key:"delete",value:function(e,t){var n=this.getKey(e);this.deleteCache(n,t)}},{key:"invalidateKey",value:function(e){var t=this;this.lvls.forEach((function(n){return t.deleteCache(e,n)}))}},{key:"invalidate",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteKeyMappingFor(e);var r=this.doesEleInvalidateKey(e);return r&&this.invalidateKey(n),r||0===this.getNumberOfIdsForKey(n)}}]),e}(),Ns={dequeue:"dequeue",downscale:"downscale",highQuality:"highQuality"},As=Me({getKey:null,doesEleInvalidateKey:_e,drawElement:null,getBoundingBox:null,getRotationPoint:null,getRotationOffset:null,isVisible:Ee,allowEdgeTxrCaching:!0,allowParentTxrCaching:!0}),Ls=function(e,t){var n=this;n.renderer=e,n.onDequeues=[];var r=As(t);Q(n,r),n.lookup=new Cs(r.getKey,r.doesEleInvalidateKey),n.setupDequeueing()},ks=Ls.prototype;ks.reasons=Ns,ks.getTextureQueue=function(e){var t=this;return t.eleImgCaches=t.eleImgCaches||{},t.eleImgCaches[e]=t.eleImgCaches[e]||[]},ks.getRetiredTextureQueue=function(e){var t=this.eleImgCaches.retired=this.eleImgCaches.retired||{};return t[e]=t[e]||[]},ks.getElementQueue=function(){return this.eleCacheQueue=this.eleCacheQueue||new c.default((function(e,t){return t.reqs-e.reqs}))},ks.getElementKeyToQueue=function(){return this.eleKeyToCacheQueue=this.eleKeyToCacheQueue||{}},ks.getElement=function(e,t,n,r,i){var a=this,o=this.renderer,s=o.cy.zoom(),l=this.lookup;if(!t||0===t.w||0===t.h||isNaN(t.w)||isNaN(t.h)||!e.visible()||e.removed())return null;if(!a.allowEdgeTxrCaching&&e.isEdge()||!a.allowParentTxrCaching&&e.isParent())return null;if(null==r&&(r=Math.ceil(st(s*n))),r<-4)r=-4;else if(s>=7.99||r>3)return null;var u=Math.pow(2,r),c=t.h*u,h=t.w*u,d=o.eleTextBiggerThanMin(e,u);if(!this.isVisible(e,d))return null;var p,g=l.get(e,r);if(g&&g.invalidated&&(g.invalidated=!1,g.texture.invalidatedWidth-=g.width),g)return g;if(p=c<=25?25:c<=50?50:50*Math.ceil(c/50),c>1024||h>1024)return null;var f=a.getTextureQueue(p),v=f[f.length-2],y=function(){return a.recycleTexture(p,h)||a.addTexture(p,h)};v||(v=f[f.length-1]),v||(v=y()),v.width-v.usedWidth<h&&(v=y());for(var m,b=function(e){return e&&e.scaledLabelShown===d},x=i&&i===Ns.dequeue,w=i&&i===Ns.highQuality,E=i&&i===Ns.downscale,_=r+1;_<=3;_++){var T=l.get(e,_);if(T){m=T;break}}var D=m&&m.level===r+1?m:null,C=function(){v.context.drawImage(D.texture.canvas,D.x,0,D.width,D.height,v.usedWidth,0,h,c)};if(v.context.setTransform(1,0,0,1,0,0),v.context.clearRect(v.usedWidth,0,h,p),b(D))C();else if(b(m)){if(!w)return a.queueElement(e,m.level-1),m;for(var N=m.level;N>r;N--)D=a.getElement(e,t,n,N,Ns.downscale);C()}else{var A;if(!x&&!w&&!E)for(var L=r-1;L>=-4;L--){var k=l.get(e,L);if(k){A=k;break}}if(b(A))return a.queueElement(e,r),A;v.context.translate(v.usedWidth,0),v.context.scale(u,u),this.drawElement(v.context,e,t,d,!1),v.context.scale(1/u,1/u),v.context.translate(-v.usedWidth,0)}return g={x:v.usedWidth,texture:v,level:r,scale:u,width:h,height:c,scaledLabelShown:d},v.usedWidth+=Math.ceil(h+8),v.eleCaches.push(g),l.set(e,r,g),a.checkTextureFullness(v),g},ks.invalidateElements=function(e){for(var t=0;t<e.length;t++)this.invalidateElement(e[t])},ks.invalidateElement=function(e){var t=this,n=t.lookup,r=[];if(n.isInvalid(e)){for(var i=-4;i<=3;i++){var a=n.getForCachedKey(e,i);a&&r.push(a)}if(n.invalidate(e))for(var o=0;o<r.length;o++){var s=r[o],l=s.texture;l.invalidatedWidth+=s.width,s.invalidated=!0,t.checkTextureUtility(l)}t.removeFromQueue(e)}},ks.checkTextureUtility=function(e){e.invalidatedWidth>=.2*e.width&&this.retireTexture(e)},ks.checkTextureFullness=function(e){var t=this.getTextureQueue(e.height);e.usedWidth/e.width>.8&&e.fullnessChecks>=10?Oe(t,e):e.fullnessChecks++},ks.retireTexture=function(e){var t=e.height,n=this.getTextureQueue(t),r=this.lookup;Oe(n,e),e.retired=!0;for(var i=e.eleCaches,a=0;a<i.length;a++){var o=i[a];r.deleteCache(o.key,o.level)}Pe(i),this.getRetiredTextureQueue(t).push(e)},ks.addTexture=function(e,t){var n={};return this.getTextureQueue(e).push(n),n.eleCaches=[],n.height=e,n.width=Math.max(1024,t),n.usedWidth=0,n.invalidatedWidth=0,n.fullnessChecks=0,n.canvas=this.renderer.makeOffscreenCanvas(n.width,n.height),n.context=n.canvas.getContext("2d"),n},ks.recycleTexture=function(e,t){for(var n=this.getTextureQueue(e),r=this.getRetiredTextureQueue(e),i=0;i<r.length;i++){var a=r[i];if(a.width>=t)return a.retired=!1,a.usedWidth=0,a.invalidatedWidth=0,a.fullnessChecks=0,Pe(a.eleCaches),a.context.setTransform(1,0,0,1,0,0),a.context.clearRect(0,0,a.width,a.height),Oe(r,a),n.push(a),a}},ks.queueElement=function(e,t){var n=this.getElementQueue(),r=this.getElementKeyToQueue(),i=this.getKey(e),a=r[i];if(a)a.level=Math.max(a.level,t),a.eles.merge(e),a.reqs++,n.updateItem(a);else{var o={eles:e.spawn().merge(e),level:t,reqs:1,key:i};n.push(o),r[i]=o}},ks.dequeue=function(e){for(var t=this,n=t.getElementQueue(),r=t.getElementKeyToQueue(),i=[],a=t.lookup,o=0;o<1&&n.size()>0;o++){var s=n.pop(),l=s.key,u=s.eles[0],c=a.hasCache(u,s.level);if(r[l]=null,!c){i.push(s);var h=t.getBoundingBox(u);t.getElement(u,h,e,s.level,Ns.dequeue)}}return i},ks.removeFromQueue=function(e){var t=this.getElementQueue(),n=this.getElementKeyToQueue(),r=this.getKey(e),i=n[r];null!=i&&(1===i.eles.length?(i.reqs=we,t.updateItem(i),t.pop(),n[r]=null):i.eles.unmerge(e))},ks.onDequeue=function(e){this.onDequeues.push(e)},ks.offDequeue=function(e){Oe(this.onDequeues,e)},ks.setupDequeueing=Ds({deqRedrawThreshold:100,deqCost:.15,deqAvgCost:.1,deqNoDrawCost:.9,deqFastCost:.9,deq:function(e,t,n){return e.dequeue(t,n)},onDeqd:function(e,t){for(var n=0;n<e.onDequeues.length;n++){(0,e.onDequeues[n])(t)}},shouldRedraw:function(e,t,n,r){for(var i=0;i<t.length;i++)for(var a=t[i].eles,o=0;o<a.length;o++){var s=a[o].boundingBox();if(wt(s,r))return!0}return!1},priority:function(e){return e.renderer.beforeRenderPriorities.eleTxrDeq}});var Ss=function(e){var t=this,n=t.renderer=e,r=n.cy;t.layersByLevel={},t.firstGet=!0,t.lastInvalidationTime=se()-500,t.skipping=!1,t.eleTxrDeqs=r.collection(),t.scheduleElementRefinement=u.default((function(){t.refineElementTextures(t.eleTxrDeqs),t.eleTxrDeqs.unmerge(t.eleTxrDeqs)}),50),n.beforeRender((function(e,n){n-t.lastInvalidationTime<=250?t.skipping=!0:t.skipping=!1}),n.beforeRenderPriorities.lyrTxrSkip);t.layersQueue=new c.default((function(e,t){return t.reqs-e.reqs})),t.setupDequeueing()},Is=Ss.prototype,Ms=0,Os=Math.pow(2,53)-1;Is.makeLayer=function(e,t){var n=Math.pow(2,t),r=Math.ceil(e.w*n),i=Math.ceil(e.h*n),a=this.renderer.makeOffscreenCanvas(r,i),o={id:Ms=++Ms%Os,bb:e,level:t,width:r,height:i,canvas:a,context:a.getContext("2d"),eles:[],elesQueue:[],reqs:0},s=o.context,l=-o.bb.x1,u=-o.bb.y1;return s.scale(n,n),s.translate(l,u),o},Is.getLayers=function(e,t,n){var r=this,i=r.renderer.cy.zoom(),a=r.firstGet;if(r.firstGet=!1,null==n)if((n=Math.ceil(st(i*t)))<-4)n=-4;else if(i>=3.99||n>2)return null;r.validateLayersElesOrdering(n,e);var o,s,l=r.layersByLevel,u=Math.pow(2,n),c=l[n]=l[n]||[];if(r.levelIsComplete(n,e))return c;!function(){var t=function(t){if(r.validateLayersElesOrdering(t,e),r.levelIsComplete(t,e))return s=l[t],!0},i=function(e){if(!s)for(var r=n+e;-4<=r&&r<=2&&!t(r);r+=e);};i(1),i(-1);for(var a=c.length-1;a>=0;a--){var o=c[a];o.invalid&&Oe(c,o)}}();var h=function(t){var i=(t=t||{}).after;if(function(){if(!o){o=ft();for(var t=0;t<e.length;t++)vt(o,e[t].boundingBox())}}(),o.w*u*(o.h*u)>16e6)return null;var a=r.makeLayer(o,n);if(null!=i){var s=c.indexOf(i)+1;c.splice(s,0,a)}else(void 0===t.insert||t.insert)&&c.unshift(a);return a};if(r.skipping&&!a)return null;for(var d=null,p=e.length/1,g=!a,f=0;f<e.length;f++){var v=e[f],y=v._private.rscratch,m=y.imgLayerCaches=y.imgLayerCaches||{},b=m[n];if(b)d=b;else{if((!d||d.eles.length>=p||!_t(d.bb,v.boundingBox()))&&!(d=h({insert:!0,after:d})))return null;s||g?r.queueLayer(d,v):r.drawEleInLayer(d,v,n,t),d.eles.push(v),m[n]=d}}return s||(g?null:c)},Is.getEleLevelForLayerLevel=function(e,t){return e},Is.drawEleInLayer=function(e,t,n,r){var i=this.renderer,a=e.context,o=t.boundingBox();0!==o.w&&0!==o.h&&t.visible()&&(n=this.getEleLevelForLayerLevel(n,r),i.setImgSmoothing(a,!1),i.drawCachedElement(a,t,null,null,n,true),i.setImgSmoothing(a,!0))},Is.levelIsComplete=function(e,t){var n=this.layersByLevel[e];if(!n||0===n.length)return!1;for(var r=0,i=0;i<n.length;i++){var a=n[i];if(a.reqs>0)return!1;if(a.invalid)return!1;r+=a.eles.length}return r===t.length},Is.validateLayersElesOrdering=function(e,t){var n=this.layersByLevel[e];if(n)for(var r=0;r<n.length;r++){for(var i=n[r],a=-1,o=0;o<t.length;o++)if(i.eles[0]===t[o]){a=o;break}if(a<0)this.invalidateLayer(i);else{var s=a;for(o=0;o<i.eles.length;o++)if(i.eles[o]!==t[s+o]){this.invalidateLayer(i);break}}}},Is.updateElementsInLayers=function(e,t){for(var n=P(e[0]),r=0;r<e.length;r++)for(var i=n?null:e[r],a=n?e[r]:e[r].ele,o=a._private.rscratch,s=o.imgLayerCaches=o.imgLayerCaches||{},l=-4;l<=2;l++){var u=s[l];u&&(i&&this.getEleLevelForLayerLevel(u.level)!==i.level||t(u,a,i))}},Is.haveLayers=function(){for(var e=!1,t=-4;t<=2;t++){var n=this.layersByLevel[t];if(n&&n.length>0){e=!0;break}}return e},Is.invalidateElements=function(e){var t=this;0!==e.length&&(t.lastInvalidationTime=se(),0!==e.length&&t.haveLayers()&&t.updateElementsInLayers(e,(function(e,n,r){t.invalidateLayer(e)})))},Is.invalidateLayer=function(e){if(this.lastInvalidationTime=se(),!e.invalid){var t=e.level,n=e.eles,r=this.layersByLevel[t];Oe(r,e),e.elesQueue=[],e.invalid=!0,e.replacement&&(e.replacement.invalid=!0);for(var i=0;i<n.length;i++){var a=n[i]._private.rscratch.imgLayerCaches;a&&(a[t]=null)}}},Is.refineElementTextures=function(e){var t=this;t.updateElementsInLayers(e,(function(e,n,r){var i=e.replacement;if(i||((i=e.replacement=t.makeLayer(e.bb,e.level)).replaces=e,i.eles=e.eles),!i.reqs)for(var a=0;a<i.eles.length;a++)t.queueLayer(i,i.eles[a])}))},Is.enqueueElementRefinement=function(e){this.eleTxrDeqs.merge(e),this.scheduleElementRefinement()},Is.queueLayer=function(e,t){var n=this.layersQueue,r=e.elesQueue,i=r.hasId=r.hasId||{};if(!e.replacement){if(t){if(i[t.id()])return;r.push(t),i[t.id()]=!0}e.reqs?(e.reqs++,n.updateItem(e)):(e.reqs=1,n.push(e))}},Is.dequeue=function(e){for(var t=this,n=t.layersQueue,r=[],i=0;i<1&&0!==n.size();){var a=n.peek();if(a.replacement)n.pop();else if(a.replaces&&a!==a.replaces.replacement)n.pop();else if(a.invalid)n.pop();else{var o=a.elesQueue.shift();o&&(t.drawEleInLayer(a,o,a.level,e),i++),0===r.length&&r.push(!0),0===a.elesQueue.length&&(n.pop(),a.reqs=0,a.replaces&&t.applyLayerReplacement(a),t.requestRedraw())}}return r},Is.applyLayerReplacement=function(e){var t=this.layersByLevel[e.level],n=e.replaces,r=t.indexOf(n);if(!(r<0||n.invalid)){t[r]=e;for(var i=0;i<e.eles.length;i++){var a=e.eles[i]._private,o=a.imgLayerCaches=a.imgLayerCaches||{};o&&(o[e.level]=e)}this.requestRedraw()}},Is.requestRedraw=u.default((function(){var e=this.renderer;e.redrawHint("eles",!0),e.redrawHint("drag",!0),e.redraw()}),100),Is.setupDequeueing=Ds({deqRedrawThreshold:50,deqCost:.15,deqAvgCost:.1,deqNoDrawCost:.9,deqFastCost:.9,deq:function(e,t){return e.dequeue(t)},onDeqd:De,shouldRedraw:Ee,priority:function(e){return e.renderer.beforeRenderPriorities.lyrTxrDeq}});var Ps,Rs={};function Bs(e,t){for(var n=0;n<t.length;n++){var r=t[n];e.lineTo(r.x,r.y)}}function Fs(e,t,n){for(var r,i=0;i<t.length;i++){var a=t[i];0===i&&(r=a),e.lineTo(a.x,a.y)}e.quadraticCurveTo(n.x,n.y,r.x,r.y)}function zs(e,t,n){e.beginPath&&e.beginPath();for(var r=t,i=0;i<r.length;i++){var a=r[i];e.lineTo(a.x,a.y)}var o=n,s=n[0];e.moveTo(s.x,s.y);for(i=1;i<o.length;i++){a=o[i];e.lineTo(a.x,a.y)}e.closePath&&e.closePath()}function Gs(e,t,n,r,i){e.beginPath&&e.beginPath(),e.arc(n,r,i,0,2*Math.PI,!1);var a=t,o=a[0];e.moveTo(o.x,o.y);for(var s=0;s<a.length;s++){var l=a[s];e.lineTo(l.x,l.y)}e.closePath&&e.closePath()}function Ys(e,t,n,r){e.arc(t,n,r,0,2*Math.PI,!1)}Rs.arrowShapeImpl=function(e){return(Ps||(Ps={polygon:Bs,"triangle-backcurve":Fs,"triangle-tee":zs,"circle-triangle":Gs,"triangle-cross":zs,circle:Ys}))[e]};var Xs={drawElement:function(e,t,n,r,i,a){t.isNode()?this.drawNode(e,t,n,r,i,a):this.drawEdge(e,t,n,r,i,a)},drawElementOverlay:function(e,t){t.isNode()?this.drawNodeOverlay(e,t):this.drawEdgeOverlay(e,t)},drawElementUnderlay:function(e,t){t.isNode()?this.drawNodeUnderlay(e,t):this.drawEdgeUnderlay(e,t)},drawCachedElementPortion:function(e,t,n,r,i,a,o,s){var l=this,u=n.getBoundingBox(t);if(0!==u.w&&0!==u.h){var c=n.getElement(t,u,r,i,a);if(null!=c){var h=s(l,t);if(0===h)return;var d,p,g,f,v,y,m=o(l,t),b=u.x1,x=u.y1,w=u.w,E=u.h;if(0!==m){var _=n.getRotationPoint(t);g=_.x,f=_.y,e.translate(g,f),e.rotate(m),(v=l.getImgSmoothing(e))||l.setImgSmoothing(e,!0);var T=n.getRotationOffset(t);d=T.x,p=T.y}else d=b,p=x;1!==h&&(y=e.globalAlpha,e.globalAlpha=y*h),e.drawImage(c.texture.canvas,c.x,0,c.width,c.height,d,p,w,E),1!==h&&(e.globalAlpha=y),0!==m&&(e.rotate(-m),e.translate(-g,-f),v||l.setImgSmoothing(e,!1))}else n.drawElement(e,t)}}},Vs=function(){return 0},Us=function(e,t){return e.getTextAngle(t,null)},js=function(e,t){return e.getTextAngle(t,"source")},qs=function(e,t){return e.getTextAngle(t,"target")},Hs=function(e,t){return t.effectiveOpacity()},Ws=function(e,t){return t.pstyle("text-opacity").pfValue*t.effectiveOpacity()};Xs.drawCachedElement=function(e,t,n,r,i,a){var o=this,s=o.data,l=s.eleTxrCache,u=s.lblTxrCache,c=s.slbTxrCache,h=s.tlbTxrCache,d=t.boundingBox(),p=!0===a?l.reasons.highQuality:null;if(0!==d.w&&0!==d.h&&t.visible()&&(!r||wt(d,r))){var g=t.isEdge(),f=t.element()._private.rscratch.badLine;o.drawElementUnderlay(e,t),o.drawCachedElementPortion(e,t,l,n,i,p,Vs,Hs),g&&f||o.drawCachedElementPortion(e,t,u,n,i,p,Us,Ws),g&&!f&&(o.drawCachedElementPortion(e,t,c,n,i,p,js,Ws),o.drawCachedElementPortion(e,t,h,n,i,p,qs,Ws)),o.drawElementOverlay(e,t)}},Xs.drawElements=function(e,t){for(var n=0;n<t.length;n++){var r=t[n];this.drawElement(e,r)}},Xs.drawCachedElements=function(e,t,n,r){for(var i=0;i<t.length;i++){var a=t[i];this.drawCachedElement(e,a,n,r)}},Xs.drawCachedNodes=function(e,t,n,r){for(var i=0;i<t.length;i++){var a=t[i];a.isNode()&&this.drawCachedElement(e,a,n,r)}},Xs.drawLayeredElements=function(e,t,n,r){var i=this.data.lyrTxrCache.getLayers(t,n);if(i)for(var a=0;a<i.length;a++){var o=i[a],s=o.bb;0!==s.w&&0!==s.h&&e.drawImage(o.canvas,s.x1,s.y1,s.w,s.h)}else this.drawCachedElements(e,t,n,r)};var $s={drawEdge:function(e,t,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],i=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],o=this,s=t._private.rscratch;if((!a||t.visible())&&!s.badLine&&null!=s.allpts&&!isNaN(s.allpts[0])){var l;n&&(l=n,e.translate(-l.x1,-l.y1));var u=a?t.pstyle("opacity").value:1,c=a?t.pstyle("line-opacity").value:1,h=t.pstyle("curve-style").value,d=t.pstyle("line-style").value,p=t.pstyle("width").pfValue,g=t.pstyle("line-cap").value,f=u*c,v=u*c,y=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:f;"straight-triangle"===h?(o.eleStrokeStyle(e,t,n),o.drawEdgeTrianglePath(t,e,s.allpts)):(e.lineWidth=p,e.lineCap=g,o.eleStrokeStyle(e,t,n),o.drawEdgePath(t,e,s.allpts,d),e.lineCap="butt")},m=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:v;o.drawArrowheads(e,t,n)};if(e.lineJoin="round","yes"===t.pstyle("ghost").value){var b=t.pstyle("ghost-offset-x").pfValue,x=t.pstyle("ghost-offset-y").pfValue,w=t.pstyle("ghost-opacity").value,E=f*w;e.translate(b,x),y(E),m(E),e.translate(-b,-x)}i&&o.drawEdgeUnderlay(e,t),y(),m(),i&&o.drawEdgeOverlay(e,t),o.drawElementText(e,t,null,r),n&&e.translate(l.x1,l.y1)}}},Ks=function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(t,n){if(n.visible()){var r=n.pstyle("".concat(e,"-opacity")).value;if(0!==r){var i=this,a=i.usePaths(),o=n._private.rscratch,s=2*n.pstyle("".concat(e,"-padding")).pfValue,l=n.pstyle("".concat(e,"-color")).value;t.lineWidth=s,"self"!==o.edgeType||a?t.lineCap="round":t.lineCap="butt",i.colorStrokeStyle(t,l[0],l[1],l[2],r),i.drawEdgePath(n,t,o.allpts,"solid")}}}};$s.drawEdgeOverlay=Ks("overlay"),$s.drawEdgeUnderlay=Ks("underlay"),$s.drawEdgePath=function(e,t,n,r){var i,a=e._private.rscratch,o=t,s=!1,l=this.usePaths(),u=e.pstyle("line-dash-pattern").pfValue,c=e.pstyle("line-dash-offset").pfValue;if(l){var h=n.join("$");a.pathCacheKey&&a.pathCacheKey===h?(i=t=a.pathCache,s=!0):(i=t=new Path2D,a.pathCacheKey=h,a.pathCache=i)}if(o.setLineDash)switch(r){case"dotted":o.setLineDash([1,1]);break;case"dashed":o.setLineDash(u),o.lineDashOffset=c;break;case"solid":o.setLineDash([])}if(!s&&!a.badLine)switch(t.beginPath&&t.beginPath(),t.moveTo(n[0],n[1]),a.edgeType){case"bezier":case"self":case"compound":case"multibezier":for(var d=2;d+3<n.length;d+=4)t.quadraticCurveTo(n[d],n[d+1],n[d+2],n[d+3]);break;case"straight":case"segments":case"haystack":for(var p=2;p+1<n.length;p+=2)t.lineTo(n[p],n[p+1])}t=o,l?t.stroke(i):t.stroke(),t.setLineDash&&t.setLineDash([])},$s.drawEdgeTrianglePath=function(e,t,n){t.fillStyle=t.strokeStyle;for(var r=e.pstyle("width").pfValue,i=0;i+1<n.length;i+=2){var a=[n[i+2]-n[i],n[i+3]-n[i+1]],o=Math.sqrt(a[0]*a[0]+a[1]*a[1]),s=[a[1]/o,-a[0]/o],l=[s[0]*r/2,s[1]*r/2];t.beginPath(),t.moveTo(n[i]-l[0],n[i+1]-l[1]),t.lineTo(n[i]+l[0],n[i+1]+l[1]),t.lineTo(n[i+2],n[i+3]),t.closePath(),t.fill()}},$s.drawArrowheads=function(e,t,n){var r=t._private.rscratch,i="haystack"===r.edgeType;i||this.drawArrowhead(e,t,"source",r.arrowStartX,r.arrowStartY,r.srcArrowAngle,n),this.drawArrowhead(e,t,"mid-target",r.midX,r.midY,r.midtgtArrowAngle,n),this.drawArrowhead(e,t,"mid-source",r.midX,r.midY,r.midsrcArrowAngle,n),i||this.drawArrowhead(e,t,"target",r.arrowEndX,r.arrowEndY,r.tgtArrowAngle,n)},$s.drawArrowhead=function(e,t,n,r,i,a,o){if(!(isNaN(r)||null==r||isNaN(i)||null==i||isNaN(a)||null==a)){var s=this,l=t.pstyle(n+"-arrow-shape").value;if("none"!==l){var u="hollow"===t.pstyle(n+"-arrow-fill").value?"both":"filled",c=t.pstyle(n+"-arrow-fill").value,h=t.pstyle("width").pfValue,d=t.pstyle(n+"-arrow-width"),p="match-line"===d.value?h:d.pfValue;"%"===d.units&&(p*=h);var g=t.pstyle("opacity").value;void 0===o&&(o=g);var f=e.globalCompositeOperation;1===o&&"hollow"!==c||(e.globalCompositeOperation="destination-out",s.colorFillStyle(e,255,255,255,1),s.colorStrokeStyle(e,255,255,255,1),s.drawArrowShape(t,e,u,h,l,p,r,i,a),e.globalCompositeOperation=f);var v=t.pstyle(n+"-arrow-color").value;s.colorFillStyle(e,v[0],v[1],v[2],o),s.colorStrokeStyle(e,v[0],v[1],v[2],o),s.drawArrowShape(t,e,c,h,l,p,r,i,a)}}},$s.drawArrowShape=function(e,t,n,r,i,a,o,s,l){var u,c=this,h=this.usePaths()&&"triangle-cross"!==i,d=!1,p=t,g={x:o,y:s},f=e.pstyle("arrow-scale").value,v=this.getArrowWidth(r,f),y=c.arrowShapes[i];if(h){var m=c.arrowPathCache=c.arrowPathCache||[],b=fe(i),x=m[b];null!=x?(u=t=x,d=!0):(u=t=new Path2D,m[b]=u)}d||(t.beginPath&&t.beginPath(),h?y.draw(t,1,0,{x:0,y:0},1):y.draw(t,v,l,g,r),t.closePath&&t.closePath()),t=p,h&&(t.translate(o,s),t.rotate(l),t.scale(v,v)),"filled"!==n&&"both"!==n||(h?t.fill(u):t.fill()),"hollow"!==n&&"both"!==n||(t.lineWidth=a/(h?v:1),t.lineJoin="miter",h?t.stroke(u):t.stroke()),h&&(t.scale(1/v,1/v),t.rotate(-l),t.translate(-o,-s))};var Zs={safeDrawImage:function(e,t,n,r,i,a,o,s,l,u){if(!(i<=0||a<=0||l<=0||u<=0))try{e.drawImage(t,n,r,i,a,o,s,l,u)}catch(c){Ae(c)}},drawInscribedImage:function(e,t,n,r,i){var a=this,o=n.position(),s=o.x,l=o.y,u=n.cy().style(),c=u.getIndexedStyle.bind(u),h=c(n,"background-fit","value",r),d=c(n,"background-repeat","value",r),p=n.width(),g=n.height(),f=2*n.padding(),v=p+("inner"===c(n,"background-width-relative-to","value",r)?0:f),y=g+("inner"===c(n,"background-height-relative-to","value",r)?0:f),m=n._private.rscratch,b="node"===c(n,"background-clip","value",r),x=c(n,"background-image-opacity","value",r)*i,w=c(n,"background-image-smoothing","value",r),E=t.width||t.cachedW,_=t.height||t.cachedH;null!=E&&null!=_||(document.body.appendChild(t),E=t.cachedW=t.width||t.offsetWidth,_=t.cachedH=t.height||t.offsetHeight,document.body.removeChild(t));var T=E,D=_;if("auto"!==c(n,"background-width","value",r)&&(T="%"===c(n,"background-width","units",r)?c(n,"background-width","pfValue",r)*v:c(n,"background-width","pfValue",r)),"auto"!==c(n,"background-height","value",r)&&(D="%"===c(n,"background-height","units",r)?c(n,"background-height","pfValue",r)*y:c(n,"background-height","pfValue",r)),0!==T&&0!==D){if("contain"===h)T*=C=Math.min(v/T,y/D),D*=C;else if("cover"===h){var C;T*=C=Math.max(v/T,y/D),D*=C}var N=s-v/2,A=c(n,"background-position-x","units",r),L=c(n,"background-position-x","pfValue",r);N+="%"===A?(v-T)*L:L;var k=c(n,"background-offset-x","units",r),S=c(n,"background-offset-x","pfValue",r);N+="%"===k?(v-T)*S:S;var I=l-y/2,M=c(n,"background-position-y","units",r),O=c(n,"background-position-y","pfValue",r);I+="%"===M?(y-D)*O:O;var P=c(n,"background-offset-y","units",r),R=c(n,"background-offset-y","pfValue",r);I+="%"===P?(y-D)*R:R,m.pathCache&&(N-=s,I-=l,s=0,l=0);var B=e.globalAlpha;e.globalAlpha=x;var F=a.getImgSmoothing(e),z=!1;if("no"===w&&F?(a.setImgSmoothing(e,!1),z=!0):"yes"!==w||F||(a.setImgSmoothing(e,!0),z=!0),"no-repeat"===d)b&&(e.save(),m.pathCache?e.clip(m.pathCache):(a.nodeShapes[a.getNodeShape(n)].draw(e,s,l,v,y),e.clip())),a.safeDrawImage(e,t,0,0,E,_,N,I,T,D),b&&e.restore();else{var G=e.createPattern(t,d);e.fillStyle=G,a.nodeShapes[a.getNodeShape(n)].draw(e,s,l,v,y),e.translate(N,I),e.fill(),e.translate(-N,-I)}e.globalAlpha=B,z&&a.setImgSmoothing(e,F)}}},Qs={};function Js(e,t,n,r,i){var a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:5,o=arguments.length>6?arguments[6]:void 0;e.beginPath(),e.moveTo(t+a,n),e.lineTo(t+r-a,n),e.quadraticCurveTo(t+r,n,t+r,n+a),e.lineTo(t+r,n+i-a),e.quadraticCurveTo(t+r,n+i,t+r-a,n+i),e.lineTo(t+a,n+i),e.quadraticCurveTo(t,n+i,t,n+i-a),e.lineTo(t,n+a),e.quadraticCurveTo(t,n,t+a,n),e.closePath(),o?e.stroke():e.fill()}Qs.eleTextBiggerThanMin=function(e,t){if(!t){var n=e.cy().zoom(),r=this.getPixelRatio(),i=Math.ceil(st(n*r));t=Math.pow(2,i)}return!(e.pstyle("font-size").pfValue*t<e.pstyle("min-zoomed-font-size").pfValue)},Qs.drawElementText=function(e,t,n,r,i){var a=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],o=this;if(null==r){if(a&&!o.eleTextBiggerThanMin(t))return}else if(!1===r)return;if(t.isNode()){var s=t.pstyle("label");if(!s||!s.value)return;var l=o.getLabelJustification(t);e.textAlign=l,e.textBaseline="bottom"}else{var u=t.element()._private.rscratch.badLine,c=t.pstyle("label"),h=t.pstyle("source-label"),d=t.pstyle("target-label");if(u||(!c||!c.value)&&(!h||!h.value)&&(!d||!d.value))return;e.textAlign="center",e.textBaseline="bottom"}var p,g=!n;n&&(p=n,e.translate(-p.x1,-p.y1)),null==i?(o.drawText(e,t,null,g,a),t.isEdge()&&(o.drawText(e,t,"source",g,a),o.drawText(e,t,"target",g,a))):o.drawText(e,t,i,g,a),n&&e.translate(p.x1,p.y1)},Qs.getFontCache=function(e){var t;this.fontCaches=this.fontCaches||[];for(var n=0;n<this.fontCaches.length;n++)if((t=this.fontCaches[n]).context===e)return t;return t={context:e},this.fontCaches.push(t),t},Qs.setupTextStyle=function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],r=t.pstyle("font-style").strValue,i=t.pstyle("font-size").pfValue+"px",a=t.pstyle("font-family").strValue,o=t.pstyle("font-weight").strValue,s=n?t.effectiveOpacity()*t.pstyle("text-opacity").value:1,l=t.pstyle("text-outline-opacity").value*s,u=t.pstyle("color").value,c=t.pstyle("text-outline-color").value;e.font=r+" "+o+" "+i+" "+a,e.lineJoin="round",this.colorFillStyle(e,u[0],u[1],u[2],s),this.colorStrokeStyle(e,c[0],c[1],c[2],l)},Qs.getTextAngle=function(e,t){var n=e._private.rscratch,r=t?t+"-":"",i=e.pstyle(r+"text-rotation"),a=Re(n,"labelAngle",t);return"autorotate"===i.strValue?e.isEdge()?a:0:"none"===i.strValue?0:i.pfValue},Qs.drawText=function(e,t,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],i=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=t._private.rscratch,o=i?t.effectiveOpacity():1;if(!i||0!==o&&0!==t.pstyle("text-opacity").value){"main"===n&&(n=null);var s,l,u=Re(a,"labelX",n),c=Re(a,"labelY",n),h=this.getLabelText(t,n);if(null!=h&&""!==h&&!isNaN(u)&&!isNaN(c)){this.setupTextStyle(e,t,i);var d,p=n?n+"-":"",g=Re(a,"labelWidth",n),f=Re(a,"labelHeight",n),v=t.pstyle(p+"text-margin-x").pfValue,y=t.pstyle(p+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle("text-halign").value,x=t.pstyle("text-valign").value;switch(m&&(b="center",x="center"),u+=v,c+=y,0!==(d=r?this.getTextAngle(t,n):0)&&(s=u,l=c,e.translate(s,l),e.rotate(d),u=0,c=0),x){case"top":break;case"center":c+=f/2;break;case"bottom":c+=f}var w=t.pstyle("text-background-opacity").value,E=t.pstyle("text-border-opacity").value,_=t.pstyle("text-border-width").pfValue,T=t.pstyle("text-background-padding").pfValue,D=0===t.pstyle("text-background-shape").strValue.indexOf("round");if(w>0||_>0&&E>0){var C=u-T;switch(b){case"left":C-=g;break;case"center":C-=g/2}var N=c-f-T,A=g+2*T,L=f+2*T;if(w>0){var k=e.fillStyle,S=t.pstyle("text-background-color").value;e.fillStyle="rgba("+S[0]+","+S[1]+","+S[2]+","+w*o+")",D?Js(e,C,N,A,L,2):e.fillRect(C,N,A,L),e.fillStyle=k}if(_>0&&E>0){var I=e.strokeStyle,M=e.lineWidth,O=t.pstyle("text-border-color").value,P=t.pstyle("text-border-style").value;if(e.strokeStyle="rgba("+O[0]+","+O[1]+","+O[2]+","+E*o+")",e.lineWidth=_,e.setLineDash)switch(P){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"double":e.lineWidth=_/4,e.setLineDash([]);break;case"solid":e.setLineDash([])}if(D?Js(e,C,N,A,L,2,"stroke"):e.strokeRect(C,N,A,L),"double"===P){var R=_/2;D?Js(e,C+R,N+R,A-2*R,L-2*R,2,"stroke"):e.strokeRect(C+R,N+R,A-2*R,L-2*R)}e.setLineDash&&e.setLineDash([]),e.lineWidth=M,e.strokeStyle=I}}var B=2*t.pstyle("text-outline-width").pfValue;if(B>0&&(e.lineWidth=B),"wrap"===t.pstyle("text-wrap").value){var F=Re(a,"labelWrapCachedLines",n),z=Re(a,"labelLineHeight",n),G=g/2,Y=this.getLabelJustification(t);switch("auto"===Y||("left"===b?"left"===Y?u+=-g:"center"===Y&&(u+=-G):"center"===b?"left"===Y?u+=-G:"right"===Y&&(u+=G):"right"===b&&("center"===Y?u+=G:"right"===Y&&(u+=g))),x){case"top":case"center":case"bottom":c-=(F.length-1)*z}for(var X=0;X<F.length;X++)B>0&&e.strokeText(F[X],u,c),e.fillText(F[X],u,c),c+=z}else B>0&&e.strokeText(h,u,c),e.fillText(h,u,c);0!==d&&(e.rotate(-d),e.translate(-s,-l))}}};var el={drawNode:function(e,t,n){var r,i,a=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],o=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],s=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],l=this,u=t._private,c=u.rscratch,h=t.position();if(I(h.x)&&I(h.y)&&(!s||t.visible())){var d,p,g=s?t.effectiveOpacity():1,f=l.usePaths(),v=!1,y=t.padding();r=t.width()+2*y,i=t.height()+2*y,n&&(p=n,e.translate(-p.x1,-p.y1));for(var m=t.pstyle("background-image").value,b=new Array(m.length),x=new Array(m.length),w=0,E=0;E<m.length;E++){var _=m[E];if(b[E]=null!=_&&"none"!==_){var T=t.cy().style().getIndexedStyle(t,"background-image-crossorigin","value",E);w++,x[E]=l.getCachedImage(_,T,(function(){u.backgroundTimestamp=Date.now(),t.emitAndNotify("background")}))}}var D=t.pstyle("background-blacken").value,C=t.pstyle("border-width").pfValue,N=t.pstyle("background-opacity").value*g,A=t.pstyle("border-color").value,L=t.pstyle("border-style").value,k=t.pstyle("border-opacity").value*g,S=t.pstyle("outline-width").pfValue,M=t.pstyle("outline-color").value,O=t.pstyle("outline-style").value,P=t.pstyle("outline-opacity").value*g,R=t.pstyle("outline-offset").value;e.lineJoin="miter";var B=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:N;l.eleFillStyle(e,t,n)},F=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:k;l.colorStrokeStyle(e,A[0],A[1],A[2],t)},z=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:P;l.colorStrokeStyle(e,M[0],M[1],M[2],t)},G=function(e,t,n,r){var i,a=l.nodePathCache=l.nodePathCache||[],o=ve("polygon"===n?n+","+r.join(","):n,""+t,""+e),s=a[o],u=!1;return null!=s?(i=s,u=!0,c.pathCache=i):(i=new Path2D,a[o]=c.pathCache=i),{path:i,cacheHit:u}},Y=t.pstyle("shape").strValue,X=t.pstyle("shape-polygon-points").pfValue;if(f){e.translate(h.x,h.y);var V=G(r,i,Y,X);d=V.path,v=V.cacheHit}var U=function(){if(!v){var n=h;f&&(n={x:0,y:0}),l.nodeShapes[l.getNodeShape(t)].draw(d||e,n.x,n.y,r,i)}f?e.fill(d):e.fill()},j=function(){for(var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:g,r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=u.backgrounding,a=0,o=0;o<x.length;o++){var s=t.cy().style().getIndexedStyle(t,"background-image-containment","value",o);r&&"over"===s||!r&&"inside"===s?a++:b[o]&&x[o].complete&&!x[o].error&&(a++,l.drawInscribedImage(e,x[o],t,o,n))}u.backgrounding=!(a===w),i!==u.backgrounding&&t.updateStyle(!1)},q=function(){var n=arguments.length>0&&void 0!==arguments[0]&&arguments[0],a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:g;l.hasPie(t)&&(l.drawPie(e,t,a),n&&(f||l.nodeShapes[l.getNodeShape(t)].draw(e,h.x,h.y,r,i)))},H=function(){var t=(D>0?D:-D)*(arguments.length>0&&void 0!==arguments[0]?arguments[0]:g),n=D>0?0:255;0!==D&&(l.colorFillStyle(e,n,n,n,t),f?e.fill(d):e.fill())},W=function(){if(C>0){if(e.lineWidth=C,e.lineCap="butt",e.setLineDash)switch(L){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"solid":case"double":e.setLineDash([])}if(f?e.stroke(d):e.stroke(),"double"===L){e.lineWidth=C/3;var t=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",f?e.stroke(d):e.stroke(),e.globalCompositeOperation=t}e.setLineDash&&e.setLineDash([])}},$=function(){if(S>0){if(e.lineWidth=S,e.lineCap="butt",e.setLineDash)switch(O){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"solid":case"double":e.setLineDash([])}var n=h;f&&(n={x:0,y:0});var a,o=l.getNodeShape(t),s=(r+C+(S+R))/r,u=(i+C+(S+R))/i,c=r*s,d=i*u,p=l.nodeShapes[o].points;if(f)a=G(c,d,o,p).path;if("ellipse"===o)l.drawEllipsePath(a||e,n.x,n.y,c,d);else if(["round-diamond","round-heptagon","round-hexagon","round-octagon","round-pentagon","round-polygon","round-triangle","round-tag"].includes(o)){var g=0,v=0,y=0;"round-diamond"===o?g=1.4*(C+R+S):"round-heptagon"===o?(g=1.075*(C+R+S),y=-(C/2+R+S)/35):"round-hexagon"===o?g=1.12*(C+R+S):"round-pentagon"===o?(g=1.13*(C+R+S),y=-(C/2+R+S)/15):"round-tag"===o?(g=1.12*(C+R+S),v=.07*(C/2+S+R)):"round-triangle"===o&&(g=(C+R+S)*(Math.PI/2),y=-(C+R/2+S)/Math.PI),0!==g&&(s=(r+g)/r,u=(i+g)/i),l.drawRoundPolygonPath(a||e,n.x+v,n.y+y,r*s,i*u,p)}else if(["roundrectangle","round-rectangle"].includes(o))l.drawRoundRectanglePath(a||e,n.x,n.y,c,d);else if(["cutrectangle","cut-rectangle"].includes(o))l.drawCutRectanglePath(a||e,n.x,n.y,c,d);else if(["bottomroundrectangle","bottom-round-rectangle"].includes(o))l.drawBottomRoundRectanglePath(a||e,n.x,n.y,c,d);else if("barrel"===o)l.drawBarrelPath(a||e,n.x,n.y,c,d);else if(o.startsWith("polygon")||["rhomboid","right-rhomboid","round-tag","tag","vee"].includes(o)){p=St(It(p,(C+S+R)/r)),l.drawPolygonPath(a||e,n.x,n.y,r,i,p)}else{p=St(It(p,-((C+S+R)/r))),l.drawPolygonPath(a||e,n.x,n.y,r,i,p)}if(f?e.stroke(a):e.stroke(),"double"===O){e.lineWidth=C/3;var m=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",f?e.stroke(a):e.stroke(),e.globalCompositeOperation=m}e.setLineDash&&e.setLineDash([])}};if("yes"===t.pstyle("ghost").value){var K=t.pstyle("ghost-offset-x").pfValue,Z=t.pstyle("ghost-offset-y").pfValue,Q=t.pstyle("ghost-opacity").value,J=Q*g;e.translate(K,Z),z(),$(),B(Q*N),U(),j(J,!0),F(Q*k),W(),q(0!==D||0!==C),j(J,!1),H(J),e.translate(-K,-Z)}f&&e.translate(-h.x,-h.y),o&&l.drawNodeUnderlay(e,t,h,r,i),f&&e.translate(h.x,h.y),z(),$(),B(),U(),j(g,!0),F(),W(),q(0!==D||0!==C),j(g,!1),H(),f&&e.translate(-h.x,-h.y),l.drawElementText(e,t,null,a),o&&l.drawNodeOverlay(e,t,h,r,i),n&&e.translate(p.x1,p.y1)}}},tl=function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(t,n,r,i,a){if(n.visible()){var o=n.pstyle("".concat(e,"-padding")).pfValue,s=n.pstyle("".concat(e,"-opacity")).value,l=n.pstyle("".concat(e,"-color")).value,u=n.pstyle("".concat(e,"-shape")).value;if(s>0){if(r=r||n.position(),null==i||null==a){var c=n.padding();i=n.width()+2*c,a=n.height()+2*c}this.colorFillStyle(t,l[0],l[1],l[2],s),this.nodeShapes[u].draw(t,r.x,r.y,i+2*o,a+2*o),t.fill()}}}};el.drawNodeOverlay=tl("overlay"),el.drawNodeUnderlay=tl("underlay"),el.hasPie=function(e){return(e=e[0])._private.hasPie},el.drawPie=function(e,t,n,r){t=t[0],r=r||t.position();var i=t.cy().style(),a=t.pstyle("pie-size"),o=r.x,s=r.y,l=t.width(),u=t.height(),c=Math.min(l,u)/2,h=0;this.usePaths()&&(o=0,s=0),"%"===a.units?c*=a.pfValue:void 0!==a.pfValue&&(c=a.pfValue/2);for(var d=1;d<=i.pieBackgroundN;d++){var p=t.pstyle("pie-"+d+"-background-size").value,g=t.pstyle("pie-"+d+"-background-color").value,f=t.pstyle("pie-"+d+"-background-opacity").value*n,v=p/100;v+h>1&&(v=1-h);var y=1.5*Math.PI+2*Math.PI*h,m=y+2*Math.PI*v;0===p||h>=1||h+v>1||(e.beginPath(),e.moveTo(o,s),e.arc(o,s,c,y,m),e.closePath(),this.colorFillStyle(e,g[0],g[1],g[2],f),e.fill(),h+=v)}};var nl={};nl.getPixelRatio=function(){var e=this.data.contexts[0];if(null!=this.forcedPixelRatio)return this.forcedPixelRatio;var t=e.backingStorePixelRatio||e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1;return(window.devicePixelRatio||1)/t},nl.paintCache=function(e){for(var t,n=this.paintCaches=this.paintCaches||[],r=!0,i=0;i<n.length;i++)if((t=n[i]).context===e){r=!1;break}return r&&(t={context:e},n.push(t)),t},nl.createGradientStyleFor=function(e,t,n,r,i){var a,o=this.usePaths(),s=n.pstyle(t+"-gradient-stop-colors").value,l=n.pstyle(t+"-gradient-stop-positions").pfValue;if("radial-gradient"===r)if(n.isEdge()){var u=n.sourceEndpoint(),c=n.targetEndpoint(),h=n.midpoint(),d=ut(u,h),p=ut(c,h);a=e.createRadialGradient(h.x,h.y,0,h.x,h.y,Math.max(d,p))}else{var g=o?{x:0,y:0}:n.position(),f=n.paddedWidth(),v=n.paddedHeight();a=e.createRadialGradient(g.x,g.y,0,g.x,g.y,Math.max(f,v))}else if(n.isEdge()){var y=n.sourceEndpoint(),m=n.targetEndpoint();a=e.createLinearGradient(y.x,y.y,m.x,m.y)}else{var b=o?{x:0,y:0}:n.position(),x=n.paddedWidth()/2,w=n.paddedHeight()/2;switch(n.pstyle("background-gradient-direction").value){case"to-bottom":a=e.createLinearGradient(b.x,b.y-w,b.x,b.y+w);break;case"to-top":a=e.createLinearGradient(b.x,b.y+w,b.x,b.y-w);break;case"to-left":a=e.createLinearGradient(b.x+x,b.y,b.x-x,b.y);break;case"to-right":a=e.createLinearGradient(b.x-x,b.y,b.x+x,b.y);break;case"to-bottom-right":case"to-right-bottom":a=e.createLinearGradient(b.x-x,b.y-w,b.x+x,b.y+w);break;case"to-top-right":case"to-right-top":a=e.createLinearGradient(b.x-x,b.y+w,b.x+x,b.y-w);break;case"to-bottom-left":case"to-left-bottom":a=e.createLinearGradient(b.x+x,b.y-w,b.x-x,b.y+w);break;case"to-top-left":case"to-left-top":a=e.createLinearGradient(b.x+x,b.y+w,b.x-x,b.y-w)}}if(!a)return null;for(var E=l.length===s.length,_=s.length,T=0;T<_;T++)a.addColorStop(E?l[T]:T/(_-1),"rgba("+s[T][0]+","+s[T][1]+","+s[T][2]+","+i+")");return a},nl.gradientFillStyle=function(e,t,n,r){var i=this.createGradientStyleFor(e,"background",t,n,r);if(!i)return null;e.fillStyle=i},nl.colorFillStyle=function(e,t,n,r,i){e.fillStyle="rgba("+t+","+n+","+r+","+i+")"},nl.eleFillStyle=function(e,t,n){var r=t.pstyle("background-fill").value;if("linear-gradient"===r||"radial-gradient"===r)this.gradientFillStyle(e,t,r,n);else{var i=t.pstyle("background-color").value;this.colorFillStyle(e,i[0],i[1],i[2],n)}},nl.gradientStrokeStyle=function(e,t,n,r){var i=this.createGradientStyleFor(e,"line",t,n,r);if(!i)return null;e.strokeStyle=i},nl.colorStrokeStyle=function(e,t,n,r,i){e.strokeStyle="rgba("+t+","+n+","+r+","+i+")"},nl.eleStrokeStyle=function(e,t,n){var r=t.pstyle("line-fill").value;if("linear-gradient"===r||"radial-gradient"===r)this.gradientStrokeStyle(e,t,r,n);else{var i=t.pstyle("line-color").value;this.colorStrokeStyle(e,i[0],i[1],i[2],n)}},nl.matchCanvasSize=function(e){var t=this,n=t.data,r=t.findContainerClientCoords(),i=r[2],a=r[3],o=t.getPixelRatio(),s=t.motionBlurPxRatio;e!==t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_NODE]&&e!==t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_DRAG]||(o=s);var l,u=i*o,c=a*o;if(u!==t.canvasWidth||c!==t.canvasHeight){t.fontCaches=null;var h=n.canvasContainer;h.style.width=i+"px",h.style.height=a+"px";for(var d=0;d<t.CANVAS_LAYERS;d++)(l=n.canvases[d]).width=u,l.height=c,l.style.width=i+"px",l.style.height=a+"px";for(d=0;d<t.BUFFER_COUNT;d++)(l=n.bufferCanvases[d]).width=u,l.height=c,l.style.width=i+"px",l.style.height=a+"px";t.textureMult=1,o<=1&&(l=n.bufferCanvases[t.TEXTURE_BUFFER],t.textureMult=2,l.width=u*t.textureMult,l.height=c*t.textureMult),t.canvasWidth=u,t.canvasHeight=c}},nl.renderTo=function(e,t,n,r){this.render({forcedContext:e,forcedZoom:t,forcedPan:n,drawAllLayers:!0,forcedPxRatio:r})},nl.render=function(e){var t=(e=e||Ie()).forcedContext,n=e.drawAllLayers,r=e.drawOnlyNodeLayer,i=e.forcedZoom,a=e.forcedPan,o=this,s=void 0===e.forcedPxRatio?this.getPixelRatio():e.forcedPxRatio,l=o.cy,u=o.data,c=u.canvasNeedsRedraw,h=o.textureOnViewport&&!t&&(o.pinching||o.hoverData.dragging||o.swipePanning||o.data.wheelZooming),d=void 0!==e.motionBlur?e.motionBlur:o.motionBlur,p=o.motionBlurPxRatio,g=l.hasCompoundNodes(),f=o.hoverData.draggingEles,v=!(!o.hoverData.selecting&&!o.touchData.selecting),y=d=d&&!t&&o.motionBlurEnabled&&!v;t||(o.prevPxRatio!==s&&(o.invalidateContainerClientCoordsCache(),o.matchCanvasSize(o.container),o.redrawHint("eles",!0),o.redrawHint("drag",!0)),o.prevPxRatio=s),!t&&o.motionBlurTimeout&&clearTimeout(o.motionBlurTimeout),d&&(null==o.mbFrames&&(o.mbFrames=0),o.mbFrames++,o.mbFrames<3&&(y=!1),o.mbFrames>o.minMbLowQualFrames&&(o.motionBlurPxRatio=o.mbPxRBlurry)),o.clearingMotionBlur&&(o.motionBlurPxRatio=1),o.textureDrawLastFrame&&!h&&(c[o.NODE]=!0,c[o.SELECT_BOX]=!0);var m=l.style(),b=l.zoom(),x=void 0!==i?i:b,w=l.pan(),E={x:w.x,y:w.y},_={zoom:b,pan:{x:w.x,y:w.y}},T=o.prevViewport;void 0===T||_.zoom!==T.zoom||_.pan.x!==T.pan.x||_.pan.y!==T.pan.y||f&&!g||(o.motionBlurPxRatio=1),a&&(E=a),x*=s,E.x*=s,E.y*=s;var D=o.getCachedZSortedEles();function C(e,t,n,r,i){var a=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",o.colorFillStyle(e,255,255,255,o.motionBlurTransparency),e.fillRect(t,n,r,i),e.globalCompositeOperation=a}function N(e,r){var s,l,c,h;o.clearingMotionBlur||e!==u.bufferContexts[o.MOTIONBLUR_BUFFER_NODE]&&e!==u.bufferContexts[o.MOTIONBLUR_BUFFER_DRAG]?(s=E,l=x,c=o.canvasWidth,h=o.canvasHeight):(s={x:w.x*p,y:w.y*p},l=b*p,c=o.canvasWidth*p,h=o.canvasHeight*p),e.setTransform(1,0,0,1,0,0),"motionBlur"===r?C(e,0,0,c,h):t||void 0!==r&&!r||e.clearRect(0,0,c,h),n||(e.translate(s.x,s.y),e.scale(l,l)),a&&e.translate(a.x,a.y),i&&e.scale(i,i)}if(h||(o.textureDrawLastFrame=!1),h){if(o.textureDrawLastFrame=!0,!o.textureCache){o.textureCache={},o.textureCache.bb=l.mutableElements().boundingBox(),o.textureCache.texture=o.data.bufferCanvases[o.TEXTURE_BUFFER];var A=o.data.bufferContexts[o.TEXTURE_BUFFER];A.setTransform(1,0,0,1,0,0),A.clearRect(0,0,o.canvasWidth*o.textureMult,o.canvasHeight*o.textureMult),o.render({forcedContext:A,drawOnlyNodeLayer:!0,forcedPxRatio:s*o.textureMult}),(_=o.textureCache.viewport={zoom:l.zoom(),pan:l.pan(),width:o.canvasWidth,height:o.canvasHeight}).mpan={x:(0-_.pan.x)/_.zoom,y:(0-_.pan.y)/_.zoom}}c[o.DRAG]=!1,c[o.NODE]=!1;var L=u.contexts[o.NODE],k=o.textureCache.texture;_=o.textureCache.viewport;L.setTransform(1,0,0,1,0,0),d?C(L,0,0,_.width,_.height):L.clearRect(0,0,_.width,_.height);var S=m.core("outside-texture-bg-color").value,I=m.core("outside-texture-bg-opacity").value;o.colorFillStyle(L,S[0],S[1],S[2],I),L.fillRect(0,0,_.width,_.height);b=l.zoom();N(L,!1),L.clearRect(_.mpan.x,_.mpan.y,_.width/_.zoom/s,_.height/_.zoom/s),L.drawImage(k,_.mpan.x,_.mpan.y,_.width/_.zoom/s,_.height/_.zoom/s)}else o.textureOnViewport&&!t&&(o.textureCache=null);var M=l.extent(),O=o.pinching||o.hoverData.dragging||o.swipePanning||o.data.wheelZooming||o.hoverData.draggingEles||o.cy.animated(),P=o.hideEdgesOnViewport&&O,R=[];if(R[o.NODE]=!c[o.NODE]&&d&&!o.clearedForMotionBlur[o.NODE]||o.clearingMotionBlur,R[o.NODE]&&(o.clearedForMotionBlur[o.NODE]=!0),R[o.DRAG]=!c[o.DRAG]&&d&&!o.clearedForMotionBlur[o.DRAG]||o.clearingMotionBlur,R[o.DRAG]&&(o.clearedForMotionBlur[o.DRAG]=!0),c[o.NODE]||n||r||R[o.NODE]){var B=d&&!R[o.NODE]&&1!==p;N(L=t||(B?o.data.bufferContexts[o.MOTIONBLUR_BUFFER_NODE]:u.contexts[o.NODE]),d&&!B?"motionBlur":void 0),P?o.drawCachedNodes(L,D.nondrag,s,M):o.drawLayeredElements(L,D.nondrag,s,M),o.debug&&o.drawDebugPoints(L,D.nondrag),n||d||(c[o.NODE]=!1)}if(!r&&(c[o.DRAG]||n||R[o.DRAG])){B=d&&!R[o.DRAG]&&1!==p;N(L=t||(B?o.data.bufferContexts[o.MOTIONBLUR_BUFFER_DRAG]:u.contexts[o.DRAG]),d&&!B?"motionBlur":void 0),P?o.drawCachedNodes(L,D.drag,s,M):o.drawCachedElements(L,D.drag,s,M),o.debug&&o.drawDebugPoints(L,D.drag),n||d||(c[o.DRAG]=!1)}if(o.showFps||!r&&c[o.SELECT_BOX]&&!n){if(N(L=t||u.contexts[o.SELECT_BOX]),1==o.selection[4]&&(o.hoverData.selecting||o.touchData.selecting)){b=o.cy.zoom();var F=m.core("selection-box-border-width").value/b;L.lineWidth=F,L.fillStyle="rgba("+m.core("selection-box-color").value[0]+","+m.core("selection-box-color").value[1]+","+m.core("selection-box-color").value[2]+","+m.core("selection-box-opacity").value+")",L.fillRect(o.selection[0],o.selection[1],o.selection[2]-o.selection[0],o.selection[3]-o.selection[1]),F>0&&(L.strokeStyle="rgba("+m.core("selection-box-border-color").value[0]+","+m.core("selection-box-border-color").value[1]+","+m.core("selection-box-border-color").value[2]+","+m.core("selection-box-opacity").value+")",L.strokeRect(o.selection[0],o.selection[1],o.selection[2]-o.selection[0],o.selection[3]-o.selection[1]))}if(u.bgActivePosistion&&!o.hoverData.selecting){b=o.cy.zoom();var z=u.bgActivePosistion;L.fillStyle="rgba("+m.core("active-bg-color").value[0]+","+m.core("active-bg-color").value[1]+","+m.core("active-bg-color").value[2]+","+m.core("active-bg-opacity").value+")",L.beginPath(),L.arc(z.x,z.y,m.core("active-bg-size").pfValue/b,0,2*Math.PI),L.fill()}var G=o.lastRedrawTime;if(o.showFps&&G){G=Math.round(G);var Y=Math.round(1e3/G);L.setTransform(1,0,0,1,0,0),L.fillStyle="rgba(255, 0, 0, 0.75)",L.strokeStyle="rgba(255, 0, 0, 0.75)",L.lineWidth=1,L.fillText("1 frame = "+G+" ms = "+Y+" fps",0,20);L.strokeRect(0,30,250,20),L.fillRect(0,30,250*Math.min(Y/60,1),20)}n||(c[o.SELECT_BOX]=!1)}if(d&&1!==p){var X=u.contexts[o.NODE],V=o.data.bufferCanvases[o.MOTIONBLUR_BUFFER_NODE],U=u.contexts[o.DRAG],j=o.data.bufferCanvases[o.MOTIONBLUR_BUFFER_DRAG],q=function(e,t,n){e.setTransform(1,0,0,1,0,0),n||!y?e.clearRect(0,0,o.canvasWidth,o.canvasHeight):C(e,0,0,o.canvasWidth,o.canvasHeight);var r=p;e.drawImage(t,0,0,o.canvasWidth*r,o.canvasHeight*r,0,0,o.canvasWidth,o.canvasHeight)};(c[o.NODE]||R[o.NODE])&&(q(X,V,R[o.NODE]),c[o.NODE]=!1),(c[o.DRAG]||R[o.DRAG])&&(q(U,j,R[o.DRAG]),c[o.DRAG]=!1)}o.prevViewport=_,o.clearingMotionBlur&&(o.clearingMotionBlur=!1,o.motionBlurCleared=!0,o.motionBlur=!0),d&&(o.motionBlurTimeout=setTimeout((function(){o.motionBlurTimeout=null,o.clearedForMotionBlur[o.NODE]=!1,o.clearedForMotionBlur[o.DRAG]=!1,o.motionBlur=!1,o.clearingMotionBlur=!h,o.mbFrames=0,c[o.NODE]=!0,c[o.DRAG]=!0,o.redraw()}),100)),t||l.emit("render")};for(var rl={drawPolygonPath:function(e,t,n,r,i,a){var o=r/2,s=i/2;e.beginPath&&e.beginPath(),e.moveTo(t+o*a[0],n+s*a[1]);for(var l=1;l<a.length/2;l++)e.lineTo(t+o*a[2*l],n+s*a[2*l+1]);e.closePath()},drawRoundPolygonPath:function(e,t,n,r,i,a){var o=r/2,s=i/2,l=Vt(r,i);e.beginPath&&e.beginPath();for(var u=0;u<a.length/4;u++){var c,h=void 0;h=0===u?a.length-2:4*u-2,c=4*u+2;var d=t+o*a[4*u],p=n+s*a[4*u+1],g=-a[h]*a[c]-a[h+1]*a[c+1],f=l/Math.tan(Math.acos(g)/2),v=d-f*a[h],y=p-f*a[h+1],m=d+f*a[c],b=p+f*a[c+1];0===u?e.moveTo(v,y):e.lineTo(v,y),e.arcTo(d,p,m,b,l)}e.closePath()},drawRoundRectanglePath:function(e,t,n,r,i){var a=r/2,o=i/2,s=Xt(r,i);e.beginPath&&e.beginPath(),e.moveTo(t,n-o),e.arcTo(t+a,n-o,t+a,n,s),e.arcTo(t+a,n+o,t,n+o,s),e.arcTo(t-a,n+o,t-a,n,s),e.arcTo(t-a,n-o,t,n-o,s),e.lineTo(t,n-o),e.closePath()},drawBottomRoundRectanglePath:function(e,t,n,r,i){var a=r/2,o=i/2,s=Xt(r,i);e.beginPath&&e.beginPath(),e.moveTo(t,n-o),e.lineTo(t+a,n-o),e.lineTo(t+a,n),e.arcTo(t+a,n+o,t,n+o,s),e.arcTo(t-a,n+o,t-a,n,s),e.lineTo(t-a,n-o),e.lineTo(t,n-o),e.closePath()},drawCutRectanglePath:function(e,t,n,r,i){var a=r/2,o=i/2;e.beginPath&&e.beginPath(),e.moveTo(t-a+8,n-o),e.lineTo(t+a-8,n-o),e.lineTo(t+a,n-o+8),e.lineTo(t+a,n+o-8),e.lineTo(t+a-8,n+o),e.lineTo(t-a+8,n+o),e.lineTo(t-a,n+o-8),e.lineTo(t-a,n-o+8),e.closePath()},drawBarrelPath:function(e,t,n,r,i){var a=r/2,o=i/2,s=t-a,l=t+a,u=n-o,c=n+o,h=Ut(r,i),d=h.widthOffset,p=h.heightOffset,g=h.ctrlPtOffsetPct*d;e.beginPath&&e.beginPath(),e.moveTo(s,u+p),e.lineTo(s,c-p),e.quadraticCurveTo(s+g,c,s+d,c),e.lineTo(l-d,c),e.quadraticCurveTo(l-g,c,l,c-p),e.lineTo(l,u+p),e.quadraticCurveTo(l-g,u,l-d,u),e.lineTo(s+d,u),e.quadraticCurveTo(s+g,u,s,u+p),e.closePath()}},il=Math.sin(0),al=Math.cos(0),ol={},sl={},ll=Math.PI/40,ul=0*Math.PI;ul<2*Math.PI;ul+=ll)ol[ul]=Math.sin(ul),sl[ul]=Math.cos(ul);rl.drawEllipsePath=function(e,t,n,r,i){if(e.beginPath&&e.beginPath(),e.ellipse)e.ellipse(t,n,r/2,i/2,0,0,2*Math.PI);else for(var a,o,s=r/2,l=i/2,u=0*Math.PI;u<2*Math.PI;u+=ll)a=t-s*ol[u]*il+s*sl[u]*al,o=n+l*sl[u]*il+l*ol[u]*al,0===u?e.moveTo(a,o):e.lineTo(a,o);e.closePath()};var cl={};function hl(e){var t=e.indexOf(",");return e.substr(t+1)}function dl(e,t,n){var r=function(){return t.toDataURL(n,e.quality)};switch(e.output){case"blob-promise":return new rr((function(r,i){try{t.toBlob((function(e){null!=e?r(e):i(new Error("`canvas.toBlob()` sent a null value in its callback"))}),n,e.quality)}catch(a){i(a)}}));case"blob":return function(e,t){for(var n=atob(e),r=new ArrayBuffer(n.length),i=new Uint8Array(r),a=0;a<n.length;a++)i[a]=n.charCodeAt(a);return new Blob([r],{type:t})}(hl(r()),n);case"base64":return hl(r());default:return r()}}cl.createBuffer=function(e,t){var n=document.createElement("canvas");return n.width=e,n.height=t,[n,n.getContext("2d")]},cl.bufferCanvasImage=function(e){var t=this.cy,n=t.mutableElements().boundingBox(),r=this.findContainerClientCoords(),i=e.full?Math.ceil(n.w):r[2],a=e.full?Math.ceil(n.h):r[3],o=I(e.maxWidth)||I(e.maxHeight),s=this.getPixelRatio(),l=1;if(void 0!==e.scale)i*=e.scale,a*=e.scale,l=e.scale;else if(o){var u=1/0,c=1/0;I(e.maxWidth)&&(u=l*e.maxWidth/i),I(e.maxHeight)&&(c=l*e.maxHeight/a),i*=l=Math.min(u,c),a*=l}o||(i*=s,a*=s,l*=s);var h=document.createElement("canvas");h.width=i,h.height=a,h.style.width=i+"px",h.style.height=a+"px";var d=h.getContext("2d");if(i>0&&a>0){d.clearRect(0,0,i,a),d.globalCompositeOperation="source-over";var p=this.getCachedZSortedEles();if(e.full)d.translate(-n.x1*l,-n.y1*l),d.scale(l,l),this.drawElements(d,p),d.scale(1/l,1/l),d.translate(n.x1*l,n.y1*l);else{var g=t.pan(),f={x:g.x*l,y:g.y*l};l*=t.zoom(),d.translate(f.x,f.y),d.scale(l,l),this.drawElements(d,p),d.scale(1/l,1/l),d.translate(-f.x,-f.y)}e.bg&&(d.globalCompositeOperation="destination-over",d.fillStyle=e.bg,d.rect(0,0,i,a),d.fill())}return h},cl.png=function(e){return dl(e,this.bufferCanvasImage(e),"image/png")},cl.jpg=function(e){return dl(e,this.bufferCanvasImage(e),"image/jpeg")};var pl={nodeShapeImpl:function(e,t,n,r,i,a,o){switch(e){case"ellipse":return this.drawEllipsePath(t,n,r,i,a);case"polygon":return this.drawPolygonPath(t,n,r,i,a,o);case"round-polygon":return this.drawRoundPolygonPath(t,n,r,i,a,o);case"roundrectangle":case"round-rectangle":return this.drawRoundRectanglePath(t,n,r,i,a);case"cutrectangle":case"cut-rectangle":return this.drawCutRectanglePath(t,n,r,i,a);case"bottomroundrectangle":case"bottom-round-rectangle":return this.drawBottomRoundRectanglePath(t,n,r,i,a);case"barrel":return this.drawBarrelPath(t,n,r,i,a)}}},gl=vl,fl=vl.prototype;function vl(e){var t=this;t.data={canvases:new Array(fl.CANVAS_LAYERS),contexts:new Array(fl.CANVAS_LAYERS),canvasNeedsRedraw:new Array(fl.CANVAS_LAYERS),bufferCanvases:new Array(fl.BUFFER_COUNT),bufferContexts:new Array(fl.CANVAS_LAYERS)};var n="-webkit-tap-highlight-color",r="rgba(0,0,0,0)";t.data.canvasContainer=document.createElement("div");var i=t.data.canvasContainer.style;t.data.canvasContainer.style[n]=r,i.position="relative",i.zIndex="0",i.overflow="hidden";var a=e.cy.container();a.appendChild(t.data.canvasContainer),a.style[n]=r;var o={"-webkit-user-select":"none","-moz-user-select":"-moz-none","user-select":"none","-webkit-tap-highlight-color":"rgba(0,0,0,0)","outline-style":"none"};E&&E.userAgent.match(/msie|trident|edge/i)&&(o["-ms-touch-action"]="none",o["touch-action"]="none");for(var s=0;s<fl.CANVAS_LAYERS;s++){var l=t.data.canvases[s]=document.createElement("canvas");t.data.contexts[s]=l.getContext("2d"),Object.keys(o).forEach((function(e){l.style[e]=o[e]})),l.style.position="absolute",l.setAttribute("data-id","layer"+s),l.style.zIndex=String(fl.CANVAS_LAYERS-s),t.data.canvasContainer.appendChild(l),t.data.canvasNeedsRedraw[s]=!1}t.data.topCanvas=t.data.canvases[0],t.data.canvases[fl.NODE].setAttribute("data-id","layer"+fl.NODE+"-node"),t.data.canvases[fl.SELECT_BOX].setAttribute("data-id","layer"+fl.SELECT_BOX+"-selectbox"),t.data.canvases[fl.DRAG].setAttribute("data-id","layer"+fl.DRAG+"-drag");for(s=0;s<fl.BUFFER_COUNT;s++)t.data.bufferCanvases[s]=document.createElement("canvas"),t.data.bufferContexts[s]=t.data.bufferCanvases[s].getContext("2d"),t.data.bufferCanvases[s].style.position="absolute",t.data.bufferCanvases[s].setAttribute("data-id","buffer"+s),t.data.bufferCanvases[s].style.zIndex=String(-s-1),t.data.bufferCanvases[s].style.visibility="hidden";t.pathsEnabled=!0;var u=ft(),c=function(e){return{x:-e.w/2,y:-e.h/2}},h=function(e){return e.boundingBox(),e[0]._private.bodyBounds},d=function(e){return e.boundingBox(),e[0]._private.labelBounds.main||u},p=function(e){return e.boundingBox(),e[0]._private.labelBounds.source||u},g=function(e){return e.boundingBox(),e[0]._private.labelBounds.target||u},f=function(e,t){return t},v=function(e,t,n){var r=e?e+"-":"";return{x:t.x+n.pstyle(r+"text-margin-x").pfValue,y:t.y+n.pstyle(r+"text-margin-y").pfValue}},y=function(e,t,n){var r=e[0]._private.rscratch;return{x:r[t],y:r[n]}},m=t.data.eleTxrCache=new Ls(t,{getKey:function(e){return e[0]._private.nodeKey},doesEleInvalidateKey:function(e){var t=e[0]._private;return!(t.oldBackgroundTimestamp===t.backgroundTimestamp)},drawElement:function(e,n,r,i,a){return t.drawElement(e,n,r,!1,!1,a)},getBoundingBox:h,getRotationPoint:function(e){return{x:((t=h(e)).x1+t.x2)/2,y:(t.y1+t.y2)/2};var t},getRotationOffset:function(e){return c(h(e))},allowEdgeTxrCaching:!1,allowParentTxrCaching:!1}),b=t.data.lblTxrCache=new Ls(t,{getKey:function(e){return e[0]._private.labelStyleKey},drawElement:function(e,n,r,i,a){return t.drawElementText(e,n,r,i,"main",a)},getBoundingBox:d,getRotationPoint:function(e){return v("",y(e,"labelX","labelY"),e)},getRotationOffset:function(e){var t=d(e),n=c(d(e));if(e.isNode()){switch(e.pstyle("text-halign").value){case"left":n.x=-t.w;break;case"right":n.x=0}switch(e.pstyle("text-valign").value){case"top":n.y=-t.h;break;case"bottom":n.y=0}}return n},isVisible:f}),x=t.data.slbTxrCache=new Ls(t,{getKey:function(e){return e[0]._private.sourceLabelStyleKey},drawElement:function(e,n,r,i,a){return t.drawElementText(e,n,r,i,"source",a)},getBoundingBox:p,getRotationPoint:function(e){return v("source",y(e,"sourceLabelX","sourceLabelY"),e)},getRotationOffset:function(e){return c(p(e))},isVisible:f}),w=t.data.tlbTxrCache=new Ls(t,{getKey:function(e){return e[0]._private.targetLabelStyleKey},drawElement:function(e,n,r,i,a){return t.drawElementText(e,n,r,i,"target",a)},getBoundingBox:g,getRotationPoint:function(e){return v("target",y(e,"targetLabelX","targetLabelY"),e)},getRotationOffset:function(e){return c(g(e))},isVisible:f}),_=t.data.lyrTxrCache=new Ss(t);t.onUpdateEleCalcs((function(e,t){m.invalidateElements(t),b.invalidateElements(t),x.invalidateElements(t),w.invalidateElements(t),_.invalidateElements(t);for(var n=0;n<t.length;n++){var r=t[n]._private;r.oldBackgroundTimestamp=r.backgroundTimestamp}}));var T=function(e){for(var t=0;t<e.length;t++)_.enqueueElementRefinement(e[t].ele)};m.onDequeue(T),b.onDequeue(T),x.onDequeue(T),w.onDequeue(T)}fl.CANVAS_LAYERS=3,fl.SELECT_BOX=0,fl.DRAG=1,fl.NODE=2,fl.BUFFER_COUNT=3,fl.TEXTURE_BUFFER=0,fl.MOTIONBLUR_BUFFER_NODE=1,fl.MOTIONBLUR_BUFFER_DRAG=2,fl.redrawHint=function(e,t){var n=this;switch(e){case"eles":n.data.canvasNeedsRedraw[fl.NODE]=t;break;case"drag":n.data.canvasNeedsRedraw[fl.DRAG]=t;break;case"select":n.data.canvasNeedsRedraw[fl.SELECT_BOX]=t}};var yl="undefined"!=typeof Path2D;fl.path2dEnabled=function(e){if(void 0===e)return this.pathsEnabled;this.pathsEnabled=!!e},fl.usePaths=function(){return yl&&this.pathsEnabled},fl.setImgSmoothing=function(e,t){null!=e.imageSmoothingEnabled?e.imageSmoothingEnabled=t:(e.webkitImageSmoothingEnabled=t,e.mozImageSmoothingEnabled=t,e.msImageSmoothingEnabled=t)},fl.getImgSmoothing=function(e){return null!=e.imageSmoothingEnabled?e.imageSmoothingEnabled:e.webkitImageSmoothingEnabled||e.mozImageSmoothingEnabled||e.msImageSmoothingEnabled},fl.makeOffscreenCanvas=function(e,t){var n;return"undefined"!==("undefined"==typeof OffscreenCanvas?"undefined":g(OffscreenCanvas))?n=new OffscreenCanvas(e,t):((n=document.createElement("canvas")).width=e,n.height=t),n},[Rs,Xs,$s,Zs,Qs,el,nl,rl,cl,pl].forEach((function(e){Q(fl,e)}));var ml=[{type:"layout",extensions:Zo},{type:"renderer",extensions:[{name:"null",impl:Qo},{name:"base",impl:Es},{name:"canvas",impl:gl}]}],bl={},xl={};function wl(e,t,n){var r=n,i=function(n){Ae("Can not register `"+t+"` for `"+e+"` since `"+n+"` already exists in the prototype and can not be overridden")};if("core"===e){if(uo.prototype[t])return i(t);uo.prototype[t]=n}else if("collection"===e){if(Da.prototype[t])return i(t);Da.prototype[t]=n}else if("layout"===e){for(var a=function(e){this.options=e,n.call(this,e),S(this._private)||(this._private={}),this._private.cy=e.cy,this._private.listeners=[],this.createEmitter()},o=a.prototype=Object.create(n.prototype),s=[],l=0;l<s.length;l++){var u=s[l];o[u]=o[u]||function(){return this}}o.start&&!o.run?o.run=function(){return this.start(),this}:!o.start&&o.run&&(o.start=function(){return this.run(),this});var c=n.prototype.stop;o.stop=function(){var e=this.options;if(e&&e.animate){var t=this.animations;if(t)for(var n=0;n<t.length;n++)t[n].stop()}return c?c.call(this):this.emit("layoutstop"),this},o.destroy||(o.destroy=function(){return this}),o.cy=function(){return this._private.cy};var h=function(e){return e._private.cy},d={addEventFields:function(e,t){t.layout=e,t.cy=h(e),t.target=e},bubble:function(){return!0},parent:function(e){return h(e)}};Q(o,{createEmitter:function(){return this._private.emitter=new Vi(d,this),this},emitter:function(){return this._private.emitter},on:function(e,t){return this.emitter().on(e,t),this},one:function(e,t){return this.emitter().one(e,t),this},once:function(e,t){return this.emitter().one(e,t),this},removeListener:function(e,t){return this.emitter().removeListener(e,t),this},removeAllListeners:function(){return this.emitter().removeAllListeners(),this},emit:function(e,t){return this.emitter().emit(e,t),this}}),ur.eventAliasesOn(o),r=a}else if("renderer"===e&&"null"!==t&&"base"!==t){var p=El("renderer","base"),g=p.prototype,f=n,v=n.prototype,y=function(){p.apply(this,arguments),f.apply(this,arguments)},m=y.prototype;for(var b in g){var x=g[b];if(null!=v[b])return i(b);m[b]=x}for(var w in v)m[w]=v[w];g.clientFunctions.forEach((function(e){m[e]=m[e]||function(){Ce("Renderer does not implement `renderer."+e+"()` on its prototype")}})),r=y}else if("__proto__"===e||"constructor"===e||"prototype"===e)return Ce(e+" is an illegal type to be registered, possibly lead to prototype pollutions");return te({map:bl,keys:[e,t],value:r})}function El(e,t){return ne({map:bl,keys:[e,t]})}function _l(e,t,n,r,i){return te({map:xl,keys:[e,t,n,r],value:i})}function Tl(e,t,n,r){return ne({map:xl,keys:[e,t,n,r]})}var Dl=function(){return 2===arguments.length?El.apply(null,arguments):3===arguments.length?wl.apply(null,arguments):4===arguments.length?Tl.apply(null,arguments):5===arguments.length?_l.apply(null,arguments):void Ce("Invalid extension access syntax")};uo.prototype.extension=Dl,ml.forEach((function(e){e.extensions.forEach((function(t){wl(e.type,t.name,t.impl)}))}));var Cl=function e(){if(!(this instanceof e))return new e;this.length=0},Nl=Cl.prototype;Nl.instanceString=function(){return"stylesheet"},Nl.selector=function(e){return this[this.length++]={selector:e,properties:[]},this},Nl.css=function(e,t){var n=this.length-1;if(A(e))this[n].properties.push({name:e,value:t});else if(S(e))for(var r=e,i=Object.keys(r),a=0;a<i.length;a++){var o=i[a],s=r[o];if(null!=s){var l=io.properties[o]||io.properties[V(o)];if(null!=l){var u=l.name,c=s;this[n].properties.push({name:u,value:c})}}}return this},Nl.style=Nl.css,Nl.generateStyle=function(e){var t=new io(e);return this.appendToStyle(t)},Nl.appendToStyle=function(e){for(var t=0;t<this.length;t++){var n=this[t],r=n.selector,i=n.properties;e.selector(r);for(var a=0;a<i.length;a++){var o=i[a];e.css(o.name,o.value)}}return e};var Al=function(e){return void 0===e&&(e={}),S(e)?new uo(e):A(e)?Dl.apply(Dl,arguments):void 0};Al.use=function(e){var t=Array.prototype.slice.call(arguments,1);return t.unshift(Al),e.apply(null,t),this},Al.warnings=function(e){return Ne(e)},Al.version="3.28.1",Al.stylesheet=Al.Stylesheet=Cl,e.exports=Al},65731:(e,t,n)=>{e.exports=n(34297)},34297:function(e,t){var n,r,i;(function(){var a,o,s,l,u,c,h,d,p,g,f,v,y,m,b;s=Math.floor,g=Math.min,o=function(e,t){return e<t?-1:e>t?1:0},p=function(e,t,n,r,i){var a;if(null==n&&(n=0),null==i&&(i=o),n<0)throw new Error("lo must be non-negative");for(null==r&&(r=e.length);n<r;)i(t,e[a=s((n+r)/2)])<0?r=a:n=a+1;return[].splice.apply(e,[n,n-n].concat(t)),t},c=function(e,t,n){return null==n&&(n=o),e.push(t),m(e,0,e.length-1,n)},u=function(e,t){var n,r;return null==t&&(t=o),n=e.pop(),e.length?(r=e[0],e[0]=n,b(e,0,t)):r=n,r},d=function(e,t,n){var r;return null==n&&(n=o),r=e[0],e[0]=t,b(e,0,n),r},h=function(e,t,n){var r;return null==n&&(n=o),e.length&&n(e[0],t)<0&&(t=(r=[e[0],t])[0],e[0]=r[1],b(e,0,n)),t},l=function(e,t){var n,r,i,a,l,u;for(null==t&&(t=o),a=function(){u=[];for(var t=0,n=s(e.length/2);0<=n?t<n:t>n;0<=n?t++:t--)u.push(t);return u}.apply(this).reverse(),l=[],r=0,i=a.length;r<i;r++)n=a[r],l.push(b(e,n,t));return l},y=function(e,t,n){var r;if(null==n&&(n=o),-1!==(r=e.indexOf(t)))return m(e,0,r,n),b(e,r,n)},f=function(e,t,n){var r,i,a,s,u;if(null==n&&(n=o),!(i=e.slice(0,t)).length)return i;for(l(i,n),a=0,s=(u=e.slice(t)).length;a<s;a++)r=u[a],h(i,r,n);return i.sort(n).reverse()},v=function(e,t,n){var r,i,a,s,c,h,d,f,v;if(null==n&&(n=o),10*t<=e.length){if(!(a=e.slice(0,t).sort(n)).length)return a;for(i=a[a.length-1],s=0,h=(d=e.slice(t)).length;s<h;s++)n(r=d[s],i)<0&&(p(a,r,0,null,n),a.pop(),i=a[a.length-1]);return a}for(l(e,n),v=[],c=0,f=g(t,e.length);0<=f?c<f:c>f;0<=f?++c:--c)v.push(u(e,n));return v},m=function(e,t,n,r){var i,a,s;for(null==r&&(r=o),i=e[n];n>t&&r(i,a=e[s=n-1>>1])<0;)e[n]=a,n=s;return e[n]=i},b=function(e,t,n){var r,i,a,s,l;for(null==n&&(n=o),i=e.length,l=t,a=e[t],r=2*t+1;r<i;)(s=r+1)<i&&!(n(e[r],e[s])<0)&&(r=s),e[t]=e[r],r=2*(t=r)+1;return e[t]=a,m(e,l,t,n)},a=function(){function e(e){this.cmp=null!=e?e:o,this.nodes=[]}return e.push=c,e.pop=u,e.replace=d,e.pushpop=h,e.heapify=l,e.updateItem=y,e.nlargest=f,e.nsmallest=v,e.prototype.push=function(e){return c(this.nodes,e,this.cmp)},e.prototype.pop=function(){return u(this.nodes,this.cmp)},e.prototype.peek=function(){return this.nodes[0]},e.prototype.contains=function(e){return-1!==this.nodes.indexOf(e)},e.prototype.replace=function(e){return d(this.nodes,e,this.cmp)},e.prototype.pushpop=function(e){return h(this.nodes,e,this.cmp)},e.prototype.heapify=function(){return l(this.nodes,this.cmp)},e.prototype.updateItem=function(e){return y(this.nodes,e,this.cmp)},e.prototype.clear=function(){return this.nodes=[]},e.prototype.empty=function(){return 0===this.nodes.length},e.prototype.size=function(){return this.nodes.length},e.prototype.clone=function(){var t;return(t=new e).nodes=this.nodes.slice(0),t},e.prototype.toArray=function(){return this.nodes.slice(0)},e.prototype.insert=e.prototype.push,e.prototype.top=e.prototype.peek,e.prototype.front=e.prototype.peek,e.prototype.has=e.prototype.contains,e.prototype.copy=e.prototype.clone,e}(),r=[],void 0===(i="function"==typeof(n=function(){return a})?n.apply(t,r):n)||(e.exports=i)}).call(this)},23143:function(e){var t;t=function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=26)}([function(e,t,n){"use strict";function r(){}r.QUALITY=1,r.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,r.DEFAULT_INCREMENTAL=!1,r.DEFAULT_ANIMATION_ON_LAYOUT=!0,r.DEFAULT_ANIMATION_DURING_LAYOUT=!1,r.DEFAULT_ANIMATION_PERIOD=50,r.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,r.DEFAULT_GRAPH_MARGIN=15,r.NODE_DIMENSIONS_INCLUDE_LABELS=!1,r.SIMPLE_NODE_SIZE=40,r.SIMPLE_NODE_HALF_SIZE=r.SIMPLE_NODE_SIZE/2,r.EMPTY_COMPOUND_NODE_SIZE=40,r.MIN_EDGE_LENGTH=1,r.WORLD_BOUNDARY=1e6,r.INITIAL_WORLD_BOUNDARY=r.WORLD_BOUNDARY/1e3,r.WORLD_CENTER_X=1200,r.WORLD_CENTER_Y=900,e.exports=r},function(e,t,n){"use strict";var r=n(2),i=n(8),a=n(9);function o(e,t,n){r.call(this,n),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=n,this.bendpoints=[],this.source=e,this.target=t}for(var s in o.prototype=Object.create(r.prototype),r)o[s]=r[s];o.prototype.getSource=function(){return this.source},o.prototype.getTarget=function(){return this.target},o.prototype.isInterGraph=function(){return this.isInterGraph},o.prototype.getLength=function(){return this.length},o.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},o.prototype.getBendpoints=function(){return this.bendpoints},o.prototype.getLca=function(){return this.lca},o.prototype.getSourceInLca=function(){return this.sourceInLca},o.prototype.getTargetInLca=function(){return this.targetInLca},o.prototype.getOtherEnd=function(e){if(this.source===e)return this.target;if(this.target===e)return this.source;throw"Node is not incident with this edge"},o.prototype.getOtherEndInGraph=function(e,t){for(var n=this.getOtherEnd(e),r=t.getGraphManager().getRoot();;){if(n.getOwner()==t)return n;if(n.getOwner()==r)break;n=n.getOwner().getParent()}return null},o.prototype.updateLength=function(){var e=new Array(4);this.isOverlapingSourceAndTarget=i.getIntersection(this.target.getRect(),this.source.getRect(),e),this.isOverlapingSourceAndTarget||(this.lengthX=e[0]-e[2],this.lengthY=e[1]-e[3],Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},o.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},e.exports=o},function(e,t,n){"use strict";e.exports=function(e){this.vGraphObject=e}},function(e,t,n){"use strict";var r=n(2),i=n(10),a=n(13),o=n(0),s=n(16),l=n(4);function u(e,t,n,o){null==n&&null==o&&(o=t),r.call(this,o),null!=e.graphManager&&(e=e.graphManager),this.estimatedSize=i.MIN_VALUE,this.inclusionTreeDepth=i.MAX_VALUE,this.vGraphObject=o,this.edges=[],this.graphManager=e,this.rect=null!=n&&null!=t?new a(t.x,t.y,n.width,n.height):new a}for(var c in u.prototype=Object.create(r.prototype),r)u[c]=r[c];u.prototype.getEdges=function(){return this.edges},u.prototype.getChild=function(){return this.child},u.prototype.getOwner=function(){return this.owner},u.prototype.getWidth=function(){return this.rect.width},u.prototype.setWidth=function(e){this.rect.width=e},u.prototype.getHeight=function(){return this.rect.height},u.prototype.setHeight=function(e){this.rect.height=e},u.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},u.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},u.prototype.getCenter=function(){return new l(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},u.prototype.getLocation=function(){return new l(this.rect.x,this.rect.y)},u.prototype.getRect=function(){return this.rect},u.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},u.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},u.prototype.setRect=function(e,t){this.rect.x=e.x,this.rect.y=e.y,this.rect.width=t.width,this.rect.height=t.height},u.prototype.setCenter=function(e,t){this.rect.x=e-this.rect.width/2,this.rect.y=t-this.rect.height/2},u.prototype.setLocation=function(e,t){this.rect.x=e,this.rect.y=t},u.prototype.moveBy=function(e,t){this.rect.x+=e,this.rect.y+=t},u.prototype.getEdgeListToNode=function(e){var t=[],n=this;return n.edges.forEach((function(r){if(r.target==e){if(r.source!=n)throw"Incorrect edge source!";t.push(r)}})),t},u.prototype.getEdgesBetween=function(e){var t=[],n=this;return n.edges.forEach((function(r){if(r.source!=n&&r.target!=n)throw"Incorrect edge source and/or target";r.target!=e&&r.source!=e||t.push(r)})),t},u.prototype.getNeighborsList=function(){var e=new Set,t=this;return t.edges.forEach((function(n){if(n.source==t)e.add(n.target);else{if(n.target!=t)throw"Incorrect incidency!";e.add(n.source)}})),e},u.prototype.withChildren=function(){var e=new Set;if(e.add(this),null!=this.child)for(var t=this.child.getNodes(),n=0;n<t.length;n++)t[n].withChildren().forEach((function(t){e.add(t)}));return e},u.prototype.getNoOfChildren=function(){var e=0;if(null==this.child)e=1;else for(var t=this.child.getNodes(),n=0;n<t.length;n++)e+=t[n].getNoOfChildren();return 0==e&&(e=1),e},u.prototype.getEstimatedSize=function(){if(this.estimatedSize==i.MIN_VALUE)throw"assert failed";return this.estimatedSize},u.prototype.calcEstimatedSize=function(){return null==this.child?this.estimatedSize=(this.rect.width+this.rect.height)/2:(this.estimatedSize=this.child.calcEstimatedSize(),this.rect.width=this.estimatedSize,this.rect.height=this.estimatedSize,this.estimatedSize)},u.prototype.scatter=function(){var e,t,n=-o.INITIAL_WORLD_BOUNDARY,r=o.INITIAL_WORLD_BOUNDARY;e=o.WORLD_CENTER_X+s.nextDouble()*(r-n)+n;var i=-o.INITIAL_WORLD_BOUNDARY,a=o.INITIAL_WORLD_BOUNDARY;t=o.WORLD_CENTER_Y+s.nextDouble()*(a-i)+i,this.rect.x=e,this.rect.y=t},u.prototype.updateBounds=function(){if(null==this.getChild())throw"assert failed";if(0!=this.getChild().getNodes().length){var e=this.getChild();if(e.updateBounds(!0),this.rect.x=e.getLeft(),this.rect.y=e.getTop(),this.setWidth(e.getRight()-e.getLeft()),this.setHeight(e.getBottom()-e.getTop()),o.NODE_DIMENSIONS_INCLUDE_LABELS){var t=e.getRight()-e.getLeft(),n=e.getBottom()-e.getTop();this.labelWidth>t&&(this.rect.x-=(this.labelWidth-t)/2,this.setWidth(this.labelWidth)),this.labelHeight>n&&("center"==this.labelPos?this.rect.y-=(this.labelHeight-n)/2:"top"==this.labelPos&&(this.rect.y-=this.labelHeight-n),this.setHeight(this.labelHeight))}}},u.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==i.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},u.prototype.transform=function(e){var t=this.rect.x;t>o.WORLD_BOUNDARY?t=o.WORLD_BOUNDARY:t<-o.WORLD_BOUNDARY&&(t=-o.WORLD_BOUNDARY);var n=this.rect.y;n>o.WORLD_BOUNDARY?n=o.WORLD_BOUNDARY:n<-o.WORLD_BOUNDARY&&(n=-o.WORLD_BOUNDARY);var r=new l(t,n),i=e.inverseTransformPoint(r);this.setLocation(i.x,i.y)},u.prototype.getLeft=function(){return this.rect.x},u.prototype.getRight=function(){return this.rect.x+this.rect.width},u.prototype.getTop=function(){return this.rect.y},u.prototype.getBottom=function(){return this.rect.y+this.rect.height},u.prototype.getParent=function(){return null==this.owner?null:this.owner.getParent()},e.exports=u},function(e,t,n){"use strict";function r(e,t){null==e&&null==t?(this.x=0,this.y=0):(this.x=e,this.y=t)}r.prototype.getX=function(){return this.x},r.prototype.getY=function(){return this.y},r.prototype.setX=function(e){this.x=e},r.prototype.setY=function(e){this.y=e},r.prototype.getDifference=function(e){return new DimensionD(this.x-e.x,this.y-e.y)},r.prototype.getCopy=function(){return new r(this.x,this.y)},r.prototype.translate=function(e){return this.x+=e.width,this.y+=e.height,this},e.exports=r},function(e,t,n){"use strict";var r=n(2),i=n(10),a=n(0),o=n(6),s=n(3),l=n(1),u=n(13),c=n(12),h=n(11);function d(e,t,n){r.call(this,n),this.estimatedSize=i.MIN_VALUE,this.margin=a.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=e,null!=t&&t instanceof o?this.graphManager=t:null!=t&&t instanceof Layout&&(this.graphManager=t.graphManager)}for(var p in d.prototype=Object.create(r.prototype),r)d[p]=r[p];d.prototype.getNodes=function(){return this.nodes},d.prototype.getEdges=function(){return this.edges},d.prototype.getGraphManager=function(){return this.graphManager},d.prototype.getParent=function(){return this.parent},d.prototype.getLeft=function(){return this.left},d.prototype.getRight=function(){return this.right},d.prototype.getTop=function(){return this.top},d.prototype.getBottom=function(){return this.bottom},d.prototype.isConnected=function(){return this.isConnected},d.prototype.add=function(e,t,n){if(null==t&&null==n){var r=e;if(null==this.graphManager)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(r)>-1)throw"Node already in graph!";return r.owner=this,this.getNodes().push(r),r}var i=e;if(!(this.getNodes().indexOf(t)>-1&&this.getNodes().indexOf(n)>-1))throw"Source or target not in graph!";if(t.owner!=n.owner||t.owner!=this)throw"Both owners must be this graph!";return t.owner!=n.owner?null:(i.source=t,i.target=n,i.isInterGraph=!1,this.getEdges().push(i),t.edges.push(i),n!=t&&n.edges.push(i),i)},d.prototype.remove=function(e){var t=e;if(e instanceof s){if(null==t)throw"Node is null!";if(null==t.owner||t.owner!=this)throw"Owner graph is invalid!";if(null==this.graphManager)throw"Owner graph manager is invalid!";for(var n=t.edges.slice(),r=n.length,i=0;i<r;i++)(a=n[i]).isInterGraph?this.graphManager.remove(a):a.source.owner.remove(a);if(-1==(o=this.nodes.indexOf(t)))throw"Node not in owner node list!";this.nodes.splice(o,1)}else if(e instanceof l){var a;if(null==(a=e))throw"Edge is null!";if(null==a.source||null==a.target)throw"Source and/or target is null!";if(null==a.source.owner||null==a.target.owner||a.source.owner!=this||a.target.owner!=this)throw"Source and/or target owner is invalid!";var o,u=a.source.edges.indexOf(a),c=a.target.edges.indexOf(a);if(!(u>-1&&c>-1))throw"Source and/or target doesn't know this edge!";if(a.source.edges.splice(u,1),a.target!=a.source&&a.target.edges.splice(c,1),-1==(o=a.source.owner.getEdges().indexOf(a)))throw"Not in owner's edge list!";a.source.owner.getEdges().splice(o,1)}},d.prototype.updateLeftTop=function(){for(var e,t,n,r=i.MAX_VALUE,a=i.MAX_VALUE,o=this.getNodes(),s=o.length,l=0;l<s;l++){var u=o[l];r>(e=u.getTop())&&(r=e),a>(t=u.getLeft())&&(a=t)}return r==i.MAX_VALUE?null:(n=null!=o[0].getParent().paddingLeft?o[0].getParent().paddingLeft:this.margin,this.left=a-n,this.top=r-n,new c(this.left,this.top))},d.prototype.updateBounds=function(e){for(var t,n,r,a,o,s=i.MAX_VALUE,l=-i.MAX_VALUE,c=i.MAX_VALUE,h=-i.MAX_VALUE,d=this.nodes,p=d.length,g=0;g<p;g++){var f=d[g];e&&null!=f.child&&f.updateBounds(),s>(t=f.getLeft())&&(s=t),l<(n=f.getRight())&&(l=n),c>(r=f.getTop())&&(c=r),h<(a=f.getBottom())&&(h=a)}var v=new u(s,c,l-s,h-c);s==i.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),o=null!=d[0].getParent().paddingLeft?d[0].getParent().paddingLeft:this.margin,this.left=v.x-o,this.right=v.x+v.width+o,this.top=v.y-o,this.bottom=v.y+v.height+o},d.calculateBounds=function(e){for(var t,n,r,a,o=i.MAX_VALUE,s=-i.MAX_VALUE,l=i.MAX_VALUE,c=-i.MAX_VALUE,h=e.length,d=0;d<h;d++){var p=e[d];o>(t=p.getLeft())&&(o=t),s<(n=p.getRight())&&(s=n),l>(r=p.getTop())&&(l=r),c<(a=p.getBottom())&&(c=a)}return new u(o,l,s-o,c-l)},d.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},d.prototype.getEstimatedSize=function(){if(this.estimatedSize==i.MIN_VALUE)throw"assert failed";return this.estimatedSize},d.prototype.calcEstimatedSize=function(){for(var e=0,t=this.nodes,n=t.length,r=0;r<n;r++)e+=t[r].calcEstimatedSize();return this.estimatedSize=0==e?a.EMPTY_COMPOUND_NODE_SIZE:e/Math.sqrt(this.nodes.length),this.estimatedSize},d.prototype.updateConnected=function(){var e=this;if(0!=this.nodes.length){var t,n,r=new h,i=new Set,a=this.nodes[0];for(a.withChildren().forEach((function(e){r.push(e),i.add(e)}));0!==r.length;)for(var o=(t=(a=r.shift()).getEdges()).length,s=0;s<o;s++)null==(n=t[s].getOtherEndInGraph(a,this))||i.has(n)||n.withChildren().forEach((function(e){r.push(e),i.add(e)}));if(this.isConnected=!1,i.size>=this.nodes.length){var l=0;i.forEach((function(t){t.owner==e&&l++})),l==this.nodes.length&&(this.isConnected=!0)}}else this.isConnected=!0},e.exports=d},function(e,t,n){"use strict";var r,i=n(1);function a(e){r=n(5),this.layout=e,this.graphs=[],this.edges=[]}a.prototype.addRoot=function(){var e=this.layout.newGraph(),t=this.layout.newNode(null),n=this.add(e,t);return this.setRootGraph(n),this.rootGraph},a.prototype.add=function(e,t,n,r,i){if(null==n&&null==r&&null==i){if(null==e)throw"Graph is null!";if(null==t)throw"Parent node is null!";if(this.graphs.indexOf(e)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(e),null!=e.parent)throw"Already has a parent!";if(null!=t.child)throw"Already has a child!";return e.parent=t,t.child=e,e}i=n,n=e;var a=(r=t).getOwner(),o=i.getOwner();if(null==a||a.getGraphManager()!=this)throw"Source not in this graph mgr!";if(null==o||o.getGraphManager()!=this)throw"Target not in this graph mgr!";if(a==o)return n.isInterGraph=!1,a.add(n,r,i);if(n.isInterGraph=!0,n.source=r,n.target=i,this.edges.indexOf(n)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(n),null==n.source||null==n.target)throw"Edge source and/or target is null!";if(-1!=n.source.edges.indexOf(n)||-1!=n.target.edges.indexOf(n))throw"Edge already in source and/or target incidency list!";return n.source.edges.push(n),n.target.edges.push(n),n},a.prototype.remove=function(e){if(e instanceof r){var t=e;if(t.getGraphManager()!=this)throw"Graph not in this graph mgr";if(t!=this.rootGraph&&(null==t.parent||t.parent.graphManager!=this))throw"Invalid parent node!";for(var n,a=[],o=(a=a.concat(t.getEdges())).length,s=0;s<o;s++)n=a[s],t.remove(n);var l,u=[];for(o=(u=u.concat(t.getNodes())).length,s=0;s<o;s++)l=u[s],t.remove(l);t==this.rootGraph&&this.setRootGraph(null);var c=this.graphs.indexOf(t);this.graphs.splice(c,1),t.parent=null}else if(e instanceof i){if(null==(n=e))throw"Edge is null!";if(!n.isInterGraph)throw"Not an inter-graph edge!";if(null==n.source||null==n.target)throw"Source and/or target is null!";if(-1==n.source.edges.indexOf(n)||-1==n.target.edges.indexOf(n))throw"Source and/or target doesn't know this edge!";if(c=n.source.edges.indexOf(n),n.source.edges.splice(c,1),c=n.target.edges.indexOf(n),n.target.edges.splice(c,1),null==n.source.owner||null==n.source.owner.getGraphManager())throw"Edge owner graph or owner graph manager is null!";if(-1==n.source.owner.getGraphManager().edges.indexOf(n))throw"Not in owner graph manager's edge list!";c=n.source.owner.getGraphManager().edges.indexOf(n),n.source.owner.getGraphManager().edges.splice(c,1)}},a.prototype.updateBounds=function(){this.rootGraph.updateBounds(!0)},a.prototype.getGraphs=function(){return this.graphs},a.prototype.getAllNodes=function(){if(null==this.allNodes){for(var e=[],t=this.getGraphs(),n=t.length,r=0;r<n;r++)e=e.concat(t[r].getNodes());this.allNodes=e}return this.allNodes},a.prototype.resetAllNodes=function(){this.allNodes=null},a.prototype.resetAllEdges=function(){this.allEdges=null},a.prototype.resetAllNodesToApplyGravitation=function(){this.allNodesToApplyGravitation=null},a.prototype.getAllEdges=function(){if(null==this.allEdges){for(var e=[],t=this.getGraphs(),n=(t.length,0);n<t.length;n++)e=e.concat(t[n].getEdges());e=e.concat(this.edges),this.allEdges=e}return this.allEdges},a.prototype.getAllNodesToApplyGravitation=function(){return this.allNodesToApplyGravitation},a.prototype.setAllNodesToApplyGravitation=function(e){if(null!=this.allNodesToApplyGravitation)throw"assert failed";this.allNodesToApplyGravitation=e},a.prototype.getRoot=function(){return this.rootGraph},a.prototype.setRootGraph=function(e){if(e.getGraphManager()!=this)throw"Root not in this graph mgr!";this.rootGraph=e,null==e.parent&&(e.parent=this.layout.newNode("Root node"))},a.prototype.getLayout=function(){return this.layout},a.prototype.isOneAncestorOfOther=function(e,t){if(null==e||null==t)throw"assert failed";if(e==t)return!0;for(var n,r=e.getOwner();null!=(n=r.getParent());){if(n==t)return!0;if(null==(r=n.getOwner()))break}for(r=t.getOwner();null!=(n=r.getParent());){if(n==e)return!0;if(null==(r=n.getOwner()))break}return!1},a.prototype.calcLowestCommonAncestors=function(){for(var e,t,n,r,i,a=this.getAllEdges(),o=a.length,s=0;s<o;s++)if(t=(e=a[s]).source,n=e.target,e.lca=null,e.sourceInLca=t,e.targetInLca=n,t!=n){for(r=t.getOwner();null==e.lca;){for(e.targetInLca=n,i=n.getOwner();null==e.lca;){if(i==r){e.lca=i;break}if(i==this.rootGraph)break;if(null!=e.lca)throw"assert failed";e.targetInLca=i.getParent(),i=e.targetInLca.getOwner()}if(r==this.rootGraph)break;null==e.lca&&(e.sourceInLca=r.getParent(),r=e.sourceInLca.getOwner())}if(null==e.lca)throw"assert failed"}else e.lca=t.getOwner()},a.prototype.calcLowestCommonAncestor=function(e,t){if(e==t)return e.getOwner();for(var n=e.getOwner();null!=n;){for(var r=t.getOwner();null!=r;){if(r==n)return r;r=r.getParent().getOwner()}n=n.getParent().getOwner()}return n},a.prototype.calcInclusionTreeDepths=function(e,t){var n;null==e&&null==t&&(e=this.rootGraph,t=1);for(var r=e.getNodes(),i=r.length,a=0;a<i;a++)(n=r[a]).inclusionTreeDepth=t,null!=n.child&&this.calcInclusionTreeDepths(n.child,t+1)},a.prototype.includesInvalidEdge=function(){for(var e,t=this.edges.length,n=0;n<t;n++)if(e=this.edges[n],this.isOneAncestorOfOther(e.source,e.target))return!0;return!1},e.exports=a},function(e,t,n){"use strict";var r=n(0);function i(){}for(var a in r)i[a]=r[a];i.MAX_ITERATIONS=2500,i.DEFAULT_EDGE_LENGTH=50,i.DEFAULT_SPRING_STRENGTH=.45,i.DEFAULT_REPULSION_STRENGTH=4500,i.DEFAULT_GRAVITY_STRENGTH=.4,i.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,i.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,i.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,i.COOLING_ADAPTATION_FACTOR=.33,i.ADAPTATION_LOWER_NODE_LIMIT=1e3,i.ADAPTATION_UPPER_NODE_LIMIT=5e3,i.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,i.MAX_NODE_DISPLACEMENT=3*i.MAX_NODE_DISPLACEMENT_INCREMENTAL,i.MIN_REPULSION_DIST=i.DEFAULT_EDGE_LENGTH/10,i.CONVERGENCE_CHECK_PERIOD=100,i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,i.MIN_EDGE_LENGTH=1,i.GRID_CALCULATION_CHECK_PERIOD=10,e.exports=i},function(e,t,n){"use strict";var r=n(12);function i(){}i.calcSeparationAmount=function(e,t,n,r){if(!e.intersects(t))throw"assert failed";var i=new Array(2);this.decideDirectionsForOverlappingNodes(e,t,i),n[0]=Math.min(e.getRight(),t.getRight())-Math.max(e.x,t.x),n[1]=Math.min(e.getBottom(),t.getBottom())-Math.max(e.y,t.y),e.getX()<=t.getX()&&e.getRight()>=t.getRight()?n[0]+=Math.min(t.getX()-e.getX(),e.getRight()-t.getRight()):t.getX()<=e.getX()&&t.getRight()>=e.getRight()&&(n[0]+=Math.min(e.getX()-t.getX(),t.getRight()-e.getRight())),e.getY()<=t.getY()&&e.getBottom()>=t.getBottom()?n[1]+=Math.min(t.getY()-e.getY(),e.getBottom()-t.getBottom()):t.getY()<=e.getY()&&t.getBottom()>=e.getBottom()&&(n[1]+=Math.min(e.getY()-t.getY(),t.getBottom()-e.getBottom()));var a=Math.abs((t.getCenterY()-e.getCenterY())/(t.getCenterX()-e.getCenterX()));t.getCenterY()===e.getCenterY()&&t.getCenterX()===e.getCenterX()&&(a=1);var o=a*n[0],s=n[1]/a;n[0]<s?s=n[0]:o=n[1],n[0]=-1*i[0]*(s/2+r),n[1]=-1*i[1]*(o/2+r)},i.decideDirectionsForOverlappingNodes=function(e,t,n){e.getCenterX()<t.getCenterX()?n[0]=-1:n[0]=1,e.getCenterY()<t.getCenterY()?n[1]=-1:n[1]=1},i.getIntersection2=function(e,t,n){var r=e.getCenterX(),i=e.getCenterY(),a=t.getCenterX(),o=t.getCenterY();if(e.intersects(t))return n[0]=r,n[1]=i,n[2]=a,n[3]=o,!0;var s=e.getX(),l=e.getY(),u=e.getRight(),c=e.getX(),h=e.getBottom(),d=e.getRight(),p=e.getWidthHalf(),g=e.getHeightHalf(),f=t.getX(),v=t.getY(),y=t.getRight(),m=t.getX(),b=t.getBottom(),x=t.getRight(),w=t.getWidthHalf(),E=t.getHeightHalf(),_=!1,T=!1;if(r===a){if(i>o)return n[0]=r,n[1]=l,n[2]=a,n[3]=b,!1;if(i<o)return n[0]=r,n[1]=h,n[2]=a,n[3]=v,!1}else if(i===o){if(r>a)return n[0]=s,n[1]=i,n[2]=y,n[3]=o,!1;if(r<a)return n[0]=u,n[1]=i,n[2]=f,n[3]=o,!1}else{var D=e.height/e.width,C=t.height/t.width,N=(o-i)/(a-r),A=void 0,L=void 0,k=void 0,S=void 0,I=void 0,M=void 0;if(-D===N?r>a?(n[0]=c,n[1]=h,_=!0):(n[0]=u,n[1]=l,_=!0):D===N&&(r>a?(n[0]=s,n[1]=l,_=!0):(n[0]=d,n[1]=h,_=!0)),-C===N?a>r?(n[2]=m,n[3]=b,T=!0):(n[2]=y,n[3]=v,T=!0):C===N&&(a>r?(n[2]=f,n[3]=v,T=!0):(n[2]=x,n[3]=b,T=!0)),_&&T)return!1;if(r>a?i>o?(A=this.getCardinalDirection(D,N,4),L=this.getCardinalDirection(C,N,2)):(A=this.getCardinalDirection(-D,N,3),L=this.getCardinalDirection(-C,N,1)):i>o?(A=this.getCardinalDirection(-D,N,1),L=this.getCardinalDirection(-C,N,3)):(A=this.getCardinalDirection(D,N,2),L=this.getCardinalDirection(C,N,4)),!_)switch(A){case 1:S=l,k=r+-g/N,n[0]=k,n[1]=S;break;case 2:k=d,S=i+p*N,n[0]=k,n[1]=S;break;case 3:S=h,k=r+g/N,n[0]=k,n[1]=S;break;case 4:k=c,S=i+-p*N,n[0]=k,n[1]=S}if(!T)switch(L){case 1:M=v,I=a+-E/N,n[2]=I,n[3]=M;break;case 2:I=x,M=o+w*N,n[2]=I,n[3]=M;break;case 3:M=b,I=a+E/N,n[2]=I,n[3]=M;break;case 4:I=m,M=o+-w*N,n[2]=I,n[3]=M}}return!1},i.getCardinalDirection=function(e,t,n){return e>t?n:1+n%4},i.getIntersection=function(e,t,n,i){if(null==i)return this.getIntersection2(e,t,n);var a,o,s,l,u,c,h,d=e.x,p=e.y,g=t.x,f=t.y,v=n.x,y=n.y,m=i.x,b=i.y;return 0==(h=(a=f-p)*(l=v-m)-(o=b-y)*(s=d-g))?null:new r((s*(c=m*y-v*b)-l*(u=g*p-d*f))/h,(o*u-a*c)/h)},i.angleOfVector=function(e,t,n,r){var i=void 0;return e!==n?(i=Math.atan((r-t)/(n-e)),n<e?i+=Math.PI:r<t&&(i+=this.TWO_PI)):i=r<t?this.ONE_AND_HALF_PI:this.HALF_PI,i},i.doIntersect=function(e,t,n,r){var i=e.x,a=e.y,o=t.x,s=t.y,l=n.x,u=n.y,c=r.x,h=r.y,d=(o-i)*(h-u)-(c-l)*(s-a);if(0===d)return!1;var p=((h-u)*(c-i)+(l-c)*(h-a))/d,g=((a-s)*(c-i)+(o-i)*(h-a))/d;return 0<p&&p<1&&0<g&&g<1},i.HALF_PI=.5*Math.PI,i.ONE_AND_HALF_PI=1.5*Math.PI,i.TWO_PI=2*Math.PI,i.THREE_PI=3*Math.PI,e.exports=i},function(e,t,n){"use strict";function r(){}r.sign=function(e){return e>0?1:e<0?-1:0},r.floor=function(e){return e<0?Math.ceil(e):Math.floor(e)},r.ceil=function(e){return e<0?Math.floor(e):Math.ceil(e)},e.exports=r},function(e,t,n){"use strict";function r(){}r.MAX_VALUE=2147483647,r.MIN_VALUE=-2147483648,e.exports=r},function(e,t,n){"use strict";var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=function(e){return{value:e,next:null,prev:null}},a=function(e,t,n,r){return null!==e?e.next=t:r.head=t,null!==n?n.prev=t:r.tail=t,t.prev=e,t.next=n,r.length++,t},o=function(e,t){var n=e.prev,r=e.next;return null!==n?n.next=r:t.head=r,null!==r?r.prev=n:t.tail=n,e.prev=e.next=null,t.length--,e},s=function(){function e(t){var n=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.length=0,this.head=null,this.tail=null,null!=t&&t.forEach((function(e){return n.push(e)}))}return r(e,[{key:"size",value:function(){return this.length}},{key:"insertBefore",value:function(e,t){return a(t.prev,i(e),t,this)}},{key:"insertAfter",value:function(e,t){return a(t,i(e),t.next,this)}},{key:"insertNodeBefore",value:function(e,t){return a(t.prev,e,t,this)}},{key:"insertNodeAfter",value:function(e,t){return a(t,e,t.next,this)}},{key:"push",value:function(e){return a(this.tail,i(e),null,this)}},{key:"unshift",value:function(e){return a(null,i(e),this.head,this)}},{key:"remove",value:function(e){return o(e,this)}},{key:"pop",value:function(){return o(this.tail,this).value}},{key:"popNode",value:function(){return o(this.tail,this)}},{key:"shift",value:function(){return o(this.head,this).value}},{key:"shiftNode",value:function(){return o(this.head,this)}},{key:"get_object_at",value:function(e){if(e<=this.length()){for(var t=1,n=this.head;t<e;)n=n.next,t++;return n.value}}},{key:"set_object_at",value:function(e,t){if(e<=this.length()){for(var n=1,r=this.head;n<e;)r=r.next,n++;r.value=t}}}]),e}();e.exports=s},function(e,t,n){"use strict";function r(e,t,n){this.x=null,this.y=null,null==e&&null==t&&null==n?(this.x=0,this.y=0):"number"==typeof e&&"number"==typeof t&&null==n?(this.x=e,this.y=t):"Point"==e.constructor.name&&null==t&&null==n&&(n=e,this.x=n.x,this.y=n.y)}r.prototype.getX=function(){return this.x},r.prototype.getY=function(){return this.y},r.prototype.getLocation=function(){return new r(this.x,this.y)},r.prototype.setLocation=function(e,t,n){"Point"==e.constructor.name&&null==t&&null==n?(n=e,this.setLocation(n.x,n.y)):"number"==typeof e&&"number"==typeof t&&null==n&&(parseInt(e)==e&&parseInt(t)==t?this.move(e,t):(this.x=Math.floor(e+.5),this.y=Math.floor(t+.5)))},r.prototype.move=function(e,t){this.x=e,this.y=t},r.prototype.translate=function(e,t){this.x+=e,this.y+=t},r.prototype.equals=function(e){if("Point"==e.constructor.name){var t=e;return this.x==t.x&&this.y==t.y}return this==e},r.prototype.toString=function(){return(new r).constructor.name+"[x="+this.x+",y="+this.y+"]"},e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){this.x=0,this.y=0,this.width=0,this.height=0,null!=e&&null!=t&&null!=n&&null!=r&&(this.x=e,this.y=t,this.width=n,this.height=r)}r.prototype.getX=function(){return this.x},r.prototype.setX=function(e){this.x=e},r.prototype.getY=function(){return this.y},r.prototype.setY=function(e){this.y=e},r.prototype.getWidth=function(){return this.width},r.prototype.setWidth=function(e){this.width=e},r.prototype.getHeight=function(){return this.height},r.prototype.setHeight=function(e){this.height=e},r.prototype.getRight=function(){return this.x+this.width},r.prototype.getBottom=function(){return this.y+this.height},r.prototype.intersects=function(e){return!(this.getRight()<e.x||this.getBottom()<e.y||e.getRight()<this.x||e.getBottom()<this.y)},r.prototype.getCenterX=function(){return this.x+this.width/2},r.prototype.getMinX=function(){return this.getX()},r.prototype.getMaxX=function(){return this.getX()+this.width},r.prototype.getCenterY=function(){return this.y+this.height/2},r.prototype.getMinY=function(){return this.getY()},r.prototype.getMaxY=function(){return this.getY()+this.height},r.prototype.getWidthHalf=function(){return this.width/2},r.prototype.getHeightHalf=function(){return this.height/2},e.exports=r},function(e,t,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function i(){}i.lastID=0,i.createID=function(e){return i.isPrimitive(e)?e:(null!=e.uniqueID||(e.uniqueID=i.getString(),i.lastID++),e.uniqueID)},i.getString=function(e){return null==e&&(e=i.lastID),"Object#"+e},i.isPrimitive=function(e){var t=void 0===e?"undefined":r(e);return null==e||"object"!=t&&"function"!=t},e.exports=i},function(e,t,n){"use strict";function r(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}var i=n(0),a=n(6),o=n(3),s=n(1),l=n(5),u=n(4),c=n(17),h=n(27);function d(e){h.call(this),this.layoutQuality=i.QUALITY,this.createBendsAsNeeded=i.DEFAULT_CREATE_BENDS_AS_NEEDED,this.incremental=i.DEFAULT_INCREMENTAL,this.animationOnLayout=i.DEFAULT_ANIMATION_ON_LAYOUT,this.animationDuringLayout=i.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=i.DEFAULT_ANIMATION_PERIOD,this.uniformLeafNodeSizes=i.DEFAULT_UNIFORM_LEAF_NODE_SIZES,this.edgeToDummyNodes=new Map,this.graphManager=new a(this),this.isLayoutFinished=!1,this.isSubLayout=!1,this.isRemoteUse=!1,null!=e&&(this.isRemoteUse=e)}d.RANDOM_SEED=1,d.prototype=Object.create(h.prototype),d.prototype.getGraphManager=function(){return this.graphManager},d.prototype.getAllNodes=function(){return this.graphManager.getAllNodes()},d.prototype.getAllEdges=function(){return this.graphManager.getAllEdges()},d.prototype.getAllNodesToApplyGravitation=function(){return this.graphManager.getAllNodesToApplyGravitation()},d.prototype.newGraphManager=function(){var e=new a(this);return this.graphManager=e,e},d.prototype.newGraph=function(e){return new l(null,this.graphManager,e)},d.prototype.newNode=function(e){return new o(this.graphManager,e)},d.prototype.newEdge=function(e){return new s(null,null,e)},d.prototype.checkLayoutSuccess=function(){return null==this.graphManager.getRoot()||0==this.graphManager.getRoot().getNodes().length||this.graphManager.includesInvalidEdge()},d.prototype.runLayout=function(){var e;return this.isLayoutFinished=!1,this.tilingPreLayout&&this.tilingPreLayout(),this.initParameters(),e=!this.checkLayoutSuccess()&&this.layout(),"during"!==i.ANIMATE&&(e&&(this.isSubLayout||this.doPostLayout()),this.tilingPostLayout&&this.tilingPostLayout(),this.isLayoutFinished=!0,e)},d.prototype.doPostLayout=function(){this.incremental||this.transform(),this.update()},d.prototype.update2=function(){if(this.createBendsAsNeeded&&(this.createBendpointsFromDummyNodes(),this.graphManager.resetAllEdges()),!this.isRemoteUse){for(var e=this.graphManager.getAllEdges(),t=0;t<e.length;t++)e[t];var n=this.graphManager.getRoot().getNodes();for(t=0;t<n.length;t++)n[t];this.update(this.graphManager.getRoot())}},d.prototype.update=function(e){if(null==e)this.update2();else if(e instanceof o){var t=e;if(null!=t.getChild())for(var n=t.getChild().getNodes(),r=0;r<n.length;r++)update(n[r]);null!=t.vGraphObject&&t.vGraphObject.update(t)}else if(e instanceof s){var i=e;null!=i.vGraphObject&&i.vGraphObject.update(i)}else if(e instanceof l){var a=e;null!=a.vGraphObject&&a.vGraphObject.update(a)}},d.prototype.initParameters=function(){this.isSubLayout||(this.layoutQuality=i.QUALITY,this.animationDuringLayout=i.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=i.DEFAULT_ANIMATION_PERIOD,this.animationOnLayout=i.DEFAULT_ANIMATION_ON_LAYOUT,this.incremental=i.DEFAULT_INCREMENTAL,this.createBendsAsNeeded=i.DEFAULT_CREATE_BENDS_AS_NEEDED,this.uniformLeafNodeSizes=i.DEFAULT_UNIFORM_LEAF_NODE_SIZES),this.animationDuringLayout&&(this.animationOnLayout=!1)},d.prototype.transform=function(e){if(null==e)this.transform(new u(0,0));else{var t=new c,n=this.graphManager.getRoot().updateLeftTop();if(null!=n){t.setWorldOrgX(e.x),t.setWorldOrgY(e.y),t.setDeviceOrgX(n.x),t.setDeviceOrgY(n.y);for(var r=this.getAllNodes(),i=0;i<r.length;i++)r[i].transform(t)}}},d.prototype.positionNodesRandomly=function(e){if(null==e)this.positionNodesRandomly(this.getGraphManager().getRoot()),this.getGraphManager().getRoot().updateBounds(!0);else for(var t,n,r=e.getNodes(),i=0;i<r.length;i++)null==(n=(t=r[i]).getChild())||0==n.getNodes().length?t.scatter():(this.positionNodesRandomly(n),t.updateBounds())},d.prototype.getFlatForest=function(){for(var e=[],t=!0,n=this.graphManager.getRoot().getNodes(),i=!0,a=0;a<n.length;a++)null!=n[a].getChild()&&(i=!1);if(!i)return e;var o=new Set,s=[],l=new Map,u=[];for(u=u.concat(n);u.length>0&&t;){for(s.push(u[0]);s.length>0&&t;){var c=s[0];s.splice(0,1),o.add(c);var h=c.getEdges();for(a=0;a<h.length;a++){var d=h[a].getOtherEnd(c);if(l.get(c)!=d){if(o.has(d)){t=!1;break}s.push(d),l.set(d,c)}}}if(t){var p=[].concat(r(o));for(e.push(p),a=0;a<p.length;a++){var g=p[a],f=u.indexOf(g);f>-1&&u.splice(f,1)}o=new Set,l=new Map}else e=[]}return e},d.prototype.createDummyNodesForBendpoints=function(e){for(var t=[],n=e.source,r=this.graphManager.calcLowestCommonAncestor(e.source,e.target),i=0;i<e.bendpoints.length;i++){var a=this.newNode(null);a.setRect(new Point(0,0),new Dimension(1,1)),r.add(a);var o=this.newEdge(null);this.graphManager.add(o,n,a),t.add(a),n=a}return o=this.newEdge(null),this.graphManager.add(o,n,e.target),this.edgeToDummyNodes.set(e,t),e.isInterGraph()?this.graphManager.remove(e):r.remove(e),t},d.prototype.createBendpointsFromDummyNodes=function(){var e=[];e=e.concat(this.graphManager.getAllEdges()),e=[].concat(r(this.edgeToDummyNodes.keys())).concat(e);for(var t=0;t<e.length;t++){var n=e[t];if(n.bendpoints.length>0){for(var i=this.edgeToDummyNodes.get(n),a=0;a<i.length;a++){var o=i[a],s=new u(o.getCenterX(),o.getCenterY()),l=n.bendpoints.get(a);l.x=s.x,l.y=s.y,o.getOwner().remove(o)}this.graphManager.add(n,n.source,n.target)}}},d.transform=function(e,t,n,r){if(null!=n&&null!=r){var i=t;return e<=50?i-=(t-t/n)/50*(50-e):i+=(t*r-t)/50*(e-50),i}var a,o;return e<=50?(a=9*t/500,o=t/10):(a=9*t/50,o=-8*t),a*e+o},d.findCenterOfTree=function(e){var t=[];t=t.concat(e);var n=[],r=new Map,i=!1,a=null;1!=t.length&&2!=t.length||(i=!0,a=t[0]);for(var o=0;o<t.length;o++){var s=(c=t[o]).getNeighborsList().size;r.set(c,c.getNeighborsList().size),1==s&&n.push(c)}var l=[];for(l=l.concat(n);!i;){var u=[];for(u=u.concat(l),l=[],o=0;o<t.length;o++){var c=t[o],h=t.indexOf(c);h>=0&&t.splice(h,1),c.getNeighborsList().forEach((function(e){if(n.indexOf(e)<0){var t=r.get(e)-1;1==t&&l.push(e),r.set(e,t)}}))}n=n.concat(l),1!=t.length&&2!=t.length||(i=!0,a=t[0])}return a},d.prototype.setGraphManager=function(e){this.graphManager=e},e.exports=d},function(e,t,n){"use strict";function r(){}r.seed=1,r.x=0,r.nextDouble=function(){return r.x=1e4*Math.sin(r.seed++),r.x-Math.floor(r.x)},e.exports=r},function(e,t,n){"use strict";var r=n(4);function i(e,t){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}i.prototype.getWorldOrgX=function(){return this.lworldOrgX},i.prototype.setWorldOrgX=function(e){this.lworldOrgX=e},i.prototype.getWorldOrgY=function(){return this.lworldOrgY},i.prototype.setWorldOrgY=function(e){this.lworldOrgY=e},i.prototype.getWorldExtX=function(){return this.lworldExtX},i.prototype.setWorldExtX=function(e){this.lworldExtX=e},i.prototype.getWorldExtY=function(){return this.lworldExtY},i.prototype.setWorldExtY=function(e){this.lworldExtY=e},i.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},i.prototype.setDeviceOrgX=function(e){this.ldeviceOrgX=e},i.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},i.prototype.setDeviceOrgY=function(e){this.ldeviceOrgY=e},i.prototype.getDeviceExtX=function(){return this.ldeviceExtX},i.prototype.setDeviceExtX=function(e){this.ldeviceExtX=e},i.prototype.getDeviceExtY=function(){return this.ldeviceExtY},i.prototype.setDeviceExtY=function(e){this.ldeviceExtY=e},i.prototype.transformX=function(e){var t=0,n=this.lworldExtX;return 0!=n&&(t=this.ldeviceOrgX+(e-this.lworldOrgX)*this.ldeviceExtX/n),t},i.prototype.transformY=function(e){var t=0,n=this.lworldExtY;return 0!=n&&(t=this.ldeviceOrgY+(e-this.lworldOrgY)*this.ldeviceExtY/n),t},i.prototype.inverseTransformX=function(e){var t=0,n=this.ldeviceExtX;return 0!=n&&(t=this.lworldOrgX+(e-this.ldeviceOrgX)*this.lworldExtX/n),t},i.prototype.inverseTransformY=function(e){var t=0,n=this.ldeviceExtY;return 0!=n&&(t=this.lworldOrgY+(e-this.ldeviceOrgY)*this.lworldExtY/n),t},i.prototype.inverseTransformPoint=function(e){return new r(this.inverseTransformX(e.x),this.inverseTransformY(e.y))},e.exports=i},function(e,t,n){"use strict";var r=n(15),i=n(7),a=n(0),o=n(8),s=n(9);function l(){r.call(this),this.useSmartIdealEdgeLengthCalculation=i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.idealEdgeLength=i.DEFAULT_EDGE_LENGTH,this.springConstant=i.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=i.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=i.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=i.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=i.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*i.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=i.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=i.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=i.MAX_ITERATIONS}for(var u in l.prototype=Object.create(r.prototype),r)l[u]=r[u];l.prototype.initParameters=function(){r.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},l.prototype.calcIdealEdgeLengths=function(){for(var e,t,n,r,o,s,l=this.getGraphManager().getAllEdges(),u=0;u<l.length;u++)(e=l[u]).idealLength=this.idealEdgeLength,e.isInterGraph&&(n=e.getSource(),r=e.getTarget(),o=e.getSourceInLca().getEstimatedSize(),s=e.getTargetInLca().getEstimatedSize(),this.useSmartIdealEdgeLengthCalculation&&(e.idealLength+=o+s-2*a.SIMPLE_NODE_SIZE),t=e.getLca().getInclusionTreeDepth(),e.idealLength+=i.DEFAULT_EDGE_LENGTH*i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR*(n.getInclusionTreeDepth()+r.getInclusionTreeDepth()-2*t))},l.prototype.initSpringEmbedder=function(){var e=this.getAllNodes().length;this.incremental?(e>i.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*i.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(e-i.ADAPTATION_LOWER_NODE_LIMIT)/(i.ADAPTATION_UPPER_NODE_LIMIT-i.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-i.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=i.MAX_NODE_DISPLACEMENT_INCREMENTAL):(e>i.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(i.COOLING_ADAPTATION_FACTOR,1-(e-i.ADAPTATION_LOWER_NODE_LIMIT)/(i.ADAPTATION_UPPER_NODE_LIMIT-i.ADAPTATION_LOWER_NODE_LIMIT)*(1-i.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=i.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(5*this.getAllNodes().length,this.maxIterations),this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},l.prototype.calcSpringForces=function(){for(var e,t=this.getAllEdges(),n=0;n<t.length;n++)e=t[n],this.calcSpringForce(e,e.idealLength)},l.prototype.calcRepulsionForces=function(){var e,t,n,r,a,o=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],s=arguments.length>1&&void 0!==arguments[1]&&arguments[1],l=this.getAllNodes();if(this.useFRGridVariant)for(this.totalIterations%i.GRID_CALCULATION_CHECK_PERIOD==1&&o&&this.updateGrid(),a=new Set,e=0;e<l.length;e++)n=l[e],this.calculateRepulsionForceOfANode(n,a,o,s),a.add(n);else for(e=0;e<l.length;e++)for(n=l[e],t=e+1;t<l.length;t++)r=l[t],n.getOwner()==r.getOwner()&&this.calcRepulsionForce(n,r)},l.prototype.calcGravitationalForces=function(){for(var e,t=this.getAllNodesToApplyGravitation(),n=0;n<t.length;n++)e=t[n],this.calcGravitationalForce(e)},l.prototype.moveNodes=function(){for(var e=this.getAllNodes(),t=0;t<e.length;t++)e[t].move()},l.prototype.calcSpringForce=function(e,t){var n,r,i,a,o=e.getSource(),s=e.getTarget();if(this.uniformLeafNodeSizes&&null==o.getChild()&&null==s.getChild())e.updateLengthSimple();else if(e.updateLength(),e.isOverlapingSourceAndTarget)return;0!=(n=e.getLength())&&(i=(r=this.springConstant*(n-t))*(e.lengthX/n),a=r*(e.lengthY/n),o.springForceX+=i,o.springForceY+=a,s.springForceX-=i,s.springForceY-=a)},l.prototype.calcRepulsionForce=function(e,t){var n,r,a,l,u,c,h,d=e.getRect(),p=t.getRect(),g=new Array(2),f=new Array(4);if(d.intersects(p)){o.calcSeparationAmount(d,p,g,i.DEFAULT_EDGE_LENGTH/2),c=2*g[0],h=2*g[1];var v=e.noOfChildren*t.noOfChildren/(e.noOfChildren+t.noOfChildren);e.repulsionForceX-=v*c,e.repulsionForceY-=v*h,t.repulsionForceX+=v*c,t.repulsionForceY+=v*h}else this.uniformLeafNodeSizes&&null==e.getChild()&&null==t.getChild()?(n=p.getCenterX()-d.getCenterX(),r=p.getCenterY()-d.getCenterY()):(o.getIntersection(d,p,f),n=f[2]-f[0],r=f[3]-f[1]),Math.abs(n)<i.MIN_REPULSION_DIST&&(n=s.sign(n)*i.MIN_REPULSION_DIST),Math.abs(r)<i.MIN_REPULSION_DIST&&(r=s.sign(r)*i.MIN_REPULSION_DIST),a=n*n+r*r,l=Math.sqrt(a),c=(u=this.repulsionConstant*e.noOfChildren*t.noOfChildren/a)*n/l,h=u*r/l,e.repulsionForceX-=c,e.repulsionForceY-=h,t.repulsionForceX+=c,t.repulsionForceY+=h},l.prototype.calcGravitationalForce=function(e){var t,n,r,i,a,o,s,l;n=((t=e.getOwner()).getRight()+t.getLeft())/2,r=(t.getTop()+t.getBottom())/2,i=e.getCenterX()-n,a=e.getCenterY()-r,o=Math.abs(i)+e.getWidth()/2,s=Math.abs(a)+e.getHeight()/2,e.getOwner()==this.graphManager.getRoot()?(o>(l=t.getEstimatedSize()*this.gravityRangeFactor)||s>l)&&(e.gravitationForceX=-this.gravityConstant*i,e.gravitationForceY=-this.gravityConstant*a):(o>(l=t.getEstimatedSize()*this.compoundGravityRangeFactor)||s>l)&&(e.gravitationForceX=-this.gravityConstant*i*this.compoundGravityConstant,e.gravitationForceY=-this.gravityConstant*a*this.compoundGravityConstant)},l.prototype.isConverged=function(){var e,t=!1;return this.totalIterations>this.maxIterations/3&&(t=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),e=this.totalDisplacement<this.totalDisplacementThreshold,this.oldTotalDisplacement=this.totalDisplacement,e||t},l.prototype.animate=function(){this.animationDuringLayout&&!this.isSubLayout&&(this.notAnimatedIterations==this.animationPeriod?(this.update(),this.notAnimatedIterations=0):this.notAnimatedIterations++)},l.prototype.calcNoOfChildrenForAllNodes=function(){for(var e,t=this.graphManager.getAllNodes(),n=0;n<t.length;n++)(e=t[n]).noOfChildren=e.getNoOfChildren()},l.prototype.calcGrid=function(e){var t,n;t=parseInt(Math.ceil((e.getRight()-e.getLeft())/this.repulsionRange)),n=parseInt(Math.ceil((e.getBottom()-e.getTop())/this.repulsionRange));for(var r=new Array(t),i=0;i<t;i++)r[i]=new Array(n);for(i=0;i<t;i++)for(var a=0;a<n;a++)r[i][a]=new Array;return r},l.prototype.addNodeToGrid=function(e,t,n){var r,i,a,o;r=parseInt(Math.floor((e.getRect().x-t)/this.repulsionRange)),i=parseInt(Math.floor((e.getRect().width+e.getRect().x-t)/this.repulsionRange)),a=parseInt(Math.floor((e.getRect().y-n)/this.repulsionRange)),o=parseInt(Math.floor((e.getRect().height+e.getRect().y-n)/this.repulsionRange));for(var s=r;s<=i;s++)for(var l=a;l<=o;l++)this.grid[s][l].push(e),e.setGridCoordinates(r,i,a,o)},l.prototype.updateGrid=function(){var e,t,n=this.getAllNodes();for(this.grid=this.calcGrid(this.graphManager.getRoot()),e=0;e<n.length;e++)t=n[e],this.addNodeToGrid(t,this.graphManager.getRoot().getLeft(),this.graphManager.getRoot().getTop())},l.prototype.calculateRepulsionForceOfANode=function(e,t,n,r){if(this.totalIterations%i.GRID_CALCULATION_CHECK_PERIOD==1&&n||r){var a,o=new Set;e.surrounding=new Array;for(var s=this.grid,l=e.startX-1;l<e.finishX+2;l++)for(var u=e.startY-1;u<e.finishY+2;u++)if(!(l<0||u<0||l>=s.length||u>=s[0].length))for(var c=0;c<s[l][u].length;c++)if(a=s[l][u][c],e.getOwner()==a.getOwner()&&e!=a&&!t.has(a)&&!o.has(a)){var h=Math.abs(e.getCenterX()-a.getCenterX())-(e.getWidth()/2+a.getWidth()/2),d=Math.abs(e.getCenterY()-a.getCenterY())-(e.getHeight()/2+a.getHeight()/2);h<=this.repulsionRange&&d<=this.repulsionRange&&o.add(a)}e.surrounding=[].concat(function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}(o))}for(l=0;l<e.surrounding.length;l++)this.calcRepulsionForce(e,e.surrounding[l])},l.prototype.calcRepulsionRange=function(){return 0},e.exports=l},function(e,t,n){"use strict";var r=n(1),i=n(7);function a(e,t,n){r.call(this,e,t,n),this.idealLength=i.DEFAULT_EDGE_LENGTH}for(var o in a.prototype=Object.create(r.prototype),r)a[o]=r[o];e.exports=a},function(e,t,n){"use strict";var r=n(3);function i(e,t,n,i){r.call(this,e,t,n,i),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0,this.startX=0,this.finishX=0,this.startY=0,this.finishY=0,this.surrounding=[]}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];i.prototype.setGridCoordinates=function(e,t,n,r){this.startX=e,this.finishX=t,this.startY=n,this.finishY=r},e.exports=i},function(e,t,n){"use strict";function r(e,t){this.width=0,this.height=0,null!==e&&null!==t&&(this.height=t,this.width=e)}r.prototype.getWidth=function(){return this.width},r.prototype.setWidth=function(e){this.width=e},r.prototype.getHeight=function(){return this.height},r.prototype.setHeight=function(e){this.height=e},e.exports=r},function(e,t,n){"use strict";var r=n(14);function i(){this.map={},this.keys=[]}i.prototype.put=function(e,t){var n=r.createID(e);this.contains(n)||(this.map[n]=t,this.keys.push(e))},i.prototype.contains=function(e){return r.createID(e),null!=this.map[e]},i.prototype.get=function(e){var t=r.createID(e);return this.map[t]},i.prototype.keySet=function(){return this.keys},e.exports=i},function(e,t,n){"use strict";var r=n(14);function i(){this.set={}}i.prototype.add=function(e){var t=r.createID(e);this.contains(t)||(this.set[t]=e)},i.prototype.remove=function(e){delete this.set[r.createID(e)]},i.prototype.clear=function(){this.set={}},i.prototype.contains=function(e){return this.set[r.createID(e)]==e},i.prototype.isEmpty=function(){return 0===this.size()},i.prototype.size=function(){return Object.keys(this.set).length},i.prototype.addAllTo=function(e){for(var t=Object.keys(this.set),n=t.length,r=0;r<n;r++)e.push(this.set[t[r]])},i.prototype.size=function(){return Object.keys(this.set).length},i.prototype.addAll=function(e){for(var t=e.length,n=0;n<t;n++){var r=e[n];this.add(r)}},e.exports=i},function(e,t,n){"use strict";var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=n(11),a=function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),null===n&&void 0===n||(this.compareFunction=this._defaultCompareFunction);var r=void 0;r=t instanceof i?t.size():t.length,this._quicksort(t,0,r-1)}return r(e,[{key:"_quicksort",value:function(e,t,n){if(t<n){var r=this._partition(e,t,n);this._quicksort(e,t,r),this._quicksort(e,r+1,n)}}},{key:"_partition",value:function(e,t,n){for(var r=this._get(e,t),i=t,a=n;;){for(;this.compareFunction(r,this._get(e,a));)a--;for(;this.compareFunction(this._get(e,i),r);)i++;if(!(i<a))return a;this._swap(e,i,a),i++,a--}}},{key:"_get",value:function(e,t){return e instanceof i?e.get_object_at(t):e[t]}},{key:"_set",value:function(e,t,n){e instanceof i?e.set_object_at(t,n):e[t]=n}},{key:"_swap",value:function(e,t,n){var r=this._get(e,t);this._set(e,t,this._get(e,n)),this._set(e,n,r)}},{key:"_defaultCompareFunction",value:function(e,t){return t>e}}]),e}();e.exports=a},function(e,t,n){"use strict";var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=function(){function e(t,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:-1,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.sequence1=t,this.sequence2=n,this.match_score=r,this.mismatch_penalty=i,this.gap_penalty=a,this.iMax=t.length+1,this.jMax=n.length+1,this.grid=new Array(this.iMax);for(var o=0;o<this.iMax;o++){this.grid[o]=new Array(this.jMax);for(var s=0;s<this.jMax;s++)this.grid[o][s]=0}this.tracebackGrid=new Array(this.iMax);for(var l=0;l<this.iMax;l++){this.tracebackGrid[l]=new Array(this.jMax);for(var u=0;u<this.jMax;u++)this.tracebackGrid[l][u]=[null,null,null]}this.alignments=[],this.score=-1,this.computeGrids()}return r(e,[{key:"getScore",value:function(){return this.score}},{key:"getAlignments",value:function(){return this.alignments}},{key:"computeGrids",value:function(){for(var e=1;e<this.jMax;e++)this.grid[0][e]=this.grid[0][e-1]+this.gap_penalty,this.tracebackGrid[0][e]=[!1,!1,!0];for(var t=1;t<this.iMax;t++)this.grid[t][0]=this.grid[t-1][0]+this.gap_penalty,this.tracebackGrid[t][0]=[!1,!0,!1];for(var n=1;n<this.iMax;n++)for(var r=1;r<this.jMax;r++){var i=[this.sequence1[n-1]===this.sequence2[r-1]?this.grid[n-1][r-1]+this.match_score:this.grid[n-1][r-1]+this.mismatch_penalty,this.grid[n-1][r]+this.gap_penalty,this.grid[n][r-1]+this.gap_penalty],a=this.arrayAllMaxIndexes(i);this.grid[n][r]=i[a[0]],this.tracebackGrid[n][r]=[a.includes(0),a.includes(1),a.includes(2)]}this.score=this.grid[this.iMax-1][this.jMax-1]}},{key:"alignmentTraceback",value:function(){var e=[];for(e.push({pos:[this.sequence1.length,this.sequence2.length],seq1:"",seq2:""});e[0];){var t=e[0],n=this.tracebackGrid[t.pos[0]][t.pos[1]];n[0]&&e.push({pos:[t.pos[0]-1,t.pos[1]-1],seq1:this.sequence1[t.pos[0]-1]+t.seq1,seq2:this.sequence2[t.pos[1]-1]+t.seq2}),n[1]&&e.push({pos:[t.pos[0]-1,t.pos[1]],seq1:this.sequence1[t.pos[0]-1]+t.seq1,seq2:"-"+t.seq2}),n[2]&&e.push({pos:[t.pos[0],t.pos[1]-1],seq1:"-"+t.seq1,seq2:this.sequence2[t.pos[1]-1]+t.seq2}),0===t.pos[0]&&0===t.pos[1]&&this.alignments.push({sequence1:t.seq1,sequence2:t.seq2}),e.shift()}return this.alignments}},{key:"getAllIndexes",value:function(e,t){for(var n=[],r=-1;-1!==(r=e.indexOf(t,r+1));)n.push(r);return n}},{key:"arrayAllMaxIndexes",value:function(e){return this.getAllIndexes(e,Math.max.apply(null,e))}}]),e}();e.exports=i},function(e,t,n){"use strict";var r=function(){};r.FDLayout=n(18),r.FDLayoutConstants=n(7),r.FDLayoutEdge=n(19),r.FDLayoutNode=n(20),r.DimensionD=n(21),r.HashMap=n(22),r.HashSet=n(23),r.IGeometry=n(8),r.IMath=n(9),r.Integer=n(10),r.Point=n(12),r.PointD=n(4),r.RandomSeed=n(16),r.RectangleD=n(13),r.Transform=n(17),r.UniqueIDGeneretor=n(14),r.Quicksort=n(24),r.LinkedList=n(11),r.LGraphObject=n(2),r.LGraph=n(5),r.LEdge=n(1),r.LGraphManager=n(6),r.LNode=n(3),r.Layout=n(15),r.LayoutConstants=n(0),r.NeedlemanWunsch=n(25),e.exports=r},function(e,t,n){"use strict";function r(){this.listeners=[]}var i=r.prototype;i.addListener=function(e,t){this.listeners.push({event:e,callback:t})},i.removeListener=function(e,t){for(var n=this.listeners.length;n>=0;n--){var r=this.listeners[n];r.event===e&&r.callback===t&&this.listeners.splice(n,1)}},i.emit=function(e,t){for(var n=0;n<this.listeners.length;n++){var r=this.listeners[n];e===r.event&&r.callback(t)}},e.exports=r}])},e.exports=t()},21549:(e,t,n)=>{var r=n(22032),i=n(63862),a=n(66721),o=n(12749),s=n(35749);function l(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}l.prototype.clear=r,l.prototype.delete=i,l.prototype.get=a,l.prototype.has=o,l.prototype.set=s,e.exports=l},80079:(e,t,n)=>{var r=n(63702),i=n(70080),a=n(24739),o=n(48655),s=n(31175);function l(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}l.prototype.clear=r,l.prototype.delete=i,l.prototype.get=a,l.prototype.has=o,l.prototype.set=s,e.exports=l},68223:(e,t,n)=>{var r=n(56110)(n(9325),"Map");e.exports=r},53661:(e,t,n)=>{var r=n(63040),i=n(17670),a=n(90289),o=n(4509),s=n(72949);function l(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}l.prototype.clear=r,l.prototype.delete=i,l.prototype.get=a,l.prototype.has=o,l.prototype.set=s,e.exports=l},51873:(e,t,n)=>{var r=n(9325).Symbol;e.exports=r},34932:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length,i=Array(r);++n<r;)i[n]=t(e[n],n,e);return i}},16547:(e,t,n)=>{var r=n(43360),i=n(75288),a=Object.prototype.hasOwnProperty;e.exports=function(e,t,n){var o=e[t];a.call(e,t)&&i(o,n)&&(void 0!==n||t in e)||r(e,t,n)}},26025:(e,t,n)=>{var r=n(75288);e.exports=function(e,t){for(var n=e.length;n--;)if(r(e[n][0],t))return n;return-1}},43360:(e,t,n)=>{var r=n(93243);e.exports=function(e,t,n){"__proto__"==t&&r?r(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0}):e[t]=n}},47422:(e,t,n)=>{var r=n(31769),i=n(77797);e.exports=function(e,t){for(var n=0,a=(t=r(t,e)).length;null!=e&&n<a;)e=e[i(t[n++])];return n&&n==a?e:void 0}},72552:(e,t,n)=>{var r=n(51873),i=n(659),a=n(59350),o=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":o&&o in Object(e)?i(e):a(e)}},45083:(e,t,n)=>{var r=n(1882),i=n(87296),a=n(23805),o=n(47473),s=/^\[object .+?Constructor\]$/,l=Function.prototype,u=Object.prototype,c=l.toString,h=u.hasOwnProperty,d=RegExp("^"+c.call(h).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");e.exports=function(e){return!(!a(e)||i(e))&&(r(e)?d:s).test(o(e))}},73170:(e,t,n)=>{var r=n(16547),i=n(31769),a=n(30361),o=n(23805),s=n(77797);e.exports=function(e,t,n,l){if(!o(e))return e;for(var u=-1,c=(t=i(t,e)).length,h=c-1,d=e;null!=d&&++u<c;){var p=s(t[u]),g=n;if("__proto__"===p||"constructor"===p||"prototype"===p)return e;if(u!=h){var f=d[p];void 0===(g=l?l(f,p,d):void 0)&&(g=o(f)?f:a(t[u+1])?[]:{})}r(d,p,g),d=d[p]}return e}},77556:(e,t,n)=>{var r=n(51873),i=n(34932),a=n(56449),o=n(44394),s=r?r.prototype:void 0,l=s?s.toString:void 0;e.exports=function e(t){if("string"==typeof t)return t;if(a(t))return i(t,e)+"";if(o(t))return l?l.call(t):"";var n=t+"";return"0"==n&&1/t==-1/0?"-0":n}},54128:(e,t,n)=>{var r=n(31800),i=/^\s+/;e.exports=function(e){return e?e.slice(0,r(e)+1).replace(i,""):e}},31769:(e,t,n)=>{var r=n(56449),i=n(28586),a=n(61802),o=n(13222);e.exports=function(e,t){return r(e)?e:i(e,t)?[e]:a(o(e))}},23007:e=>{e.exports=function(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n<r;)t[n]=e[n];return t}},55481:(e,t,n)=>{var r=n(9325)["__core-js_shared__"];e.exports=r},93243:(e,t,n)=>{var r=n(56110),i=function(){try{var e=r(Object,"defineProperty");return e({},"",{}),e}catch(t){}}();e.exports=i},34840:(e,t,n)=>{var r="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g;e.exports=r},12651:(e,t,n)=>{var r=n(74218);e.exports=function(e,t){var n=e.__data__;return r(t)?n["string"==typeof t?"string":"hash"]:n.map}},56110:(e,t,n)=>{var r=n(45083),i=n(10392);e.exports=function(e,t){var n=i(e,t);return r(n)?n:void 0}},659:(e,t,n)=>{var r=n(51873),i=Object.prototype,a=i.hasOwnProperty,o=i.toString,s=r?r.toStringTag:void 0;e.exports=function(e){var t=a.call(e,s),n=e[s];try{e[s]=void 0;var r=!0}catch(l){}var i=o.call(e);return r&&(t?e[s]=n:delete e[s]),i}},10392:e=>{e.exports=function(e,t){return null==e?void 0:e[t]}},22032:(e,t,n)=>{var r=n(81042);e.exports=function(){this.__data__=r?r(null):{},this.size=0}},63862:e=>{e.exports=function(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}},66721:(e,t,n)=>{var r=n(81042),i=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;if(r){var n=t[e];return"__lodash_hash_undefined__"===n?void 0:n}return i.call(t,e)?t[e]:void 0}},12749:(e,t,n)=>{var r=n(81042),i=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;return r?void 0!==t[e]:i.call(t,e)}},35749:(e,t,n)=>{var r=n(81042);e.exports=function(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=r&&void 0===t?"__lodash_hash_undefined__":t,this}},30361:e=>{var t=/^(?:0|[1-9]\d*)$/;e.exports=function(e,n){var r=typeof e;return!!(n=null==n?9007199254740991:n)&&("number"==r||"symbol"!=r&&t.test(e))&&e>-1&&e%1==0&&e<n}},28586:(e,t,n)=>{var r=n(56449),i=n(44394),a=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,o=/^\w*$/;e.exports=function(e,t){if(r(e))return!1;var n=typeof e;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=e&&!i(e))||(o.test(e)||!a.test(e)||null!=t&&e in Object(t))}},74218:e=>{e.exports=function(e){var t=typeof e;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==e:null===e}},87296:(e,t,n)=>{var r,i=n(55481),a=(r=/[^.]+$/.exec(i&&i.keys&&i.keys.IE_PROTO||""))?"Symbol(src)_1."+r:"";e.exports=function(e){return!!a&&a in e}},63702:e=>{e.exports=function(){this.__data__=[],this.size=0}},70080:(e,t,n)=>{var r=n(26025),i=Array.prototype.splice;e.exports=function(e){var t=this.__data__,n=r(t,e);return!(n<0)&&(n==t.length-1?t.pop():i.call(t,n,1),--this.size,!0)}},24739:(e,t,n)=>{var r=n(26025);e.exports=function(e){var t=this.__data__,n=r(t,e);return n<0?void 0:t[n][1]}},48655:(e,t,n)=>{var r=n(26025);e.exports=function(e){return r(this.__data__,e)>-1}},31175:(e,t,n)=>{var r=n(26025);e.exports=function(e,t){var n=this.__data__,i=r(n,e);return i<0?(++this.size,n.push([e,t])):n[i][1]=t,this}},63040:(e,t,n)=>{var r=n(21549),i=n(80079),a=n(68223);e.exports=function(){this.size=0,this.__data__={hash:new r,map:new(a||i),string:new r}}},17670:(e,t,n)=>{var r=n(12651);e.exports=function(e){var t=r(this,e).delete(e);return this.size-=t?1:0,t}},90289:(e,t,n)=>{var r=n(12651);e.exports=function(e){return r(this,e).get(e)}},4509:(e,t,n)=>{var r=n(12651);e.exports=function(e){return r(this,e).has(e)}},72949:(e,t,n)=>{var r=n(12651);e.exports=function(e,t){var n=r(this,e),i=n.size;return n.set(e,t),this.size+=n.size==i?0:1,this}},62224:(e,t,n)=>{var r=n(50104);e.exports=function(e){var t=r(e,(function(e){return 500===n.size&&n.clear(),e})),n=t.cache;return t}},81042:(e,t,n)=>{var r=n(56110)(Object,"create");e.exports=r},59350:e=>{var t=Object.prototype.toString;e.exports=function(e){return t.call(e)}},9325:(e,t,n)=>{var r=n(34840),i="object"==typeof self&&self&&self.Object===Object&&self,a=r||i||Function("return this")();e.exports=a},61802:(e,t,n)=>{var r=n(62224),i=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,a=/\\(\\)?/g,o=r((function(e){var t=[];return 46===e.charCodeAt(0)&&t.push(""),e.replace(i,(function(e,n,r,i){t.push(r?i.replace(a,"$1"):n||e)})),t}));e.exports=o},77797:(e,t,n)=>{var r=n(44394);e.exports=function(e){if("string"==typeof e||r(e))return e;var t=e+"";return"0"==t&&1/e==-1/0?"-0":t}},47473:e=>{var t=Function.prototype.toString;e.exports=function(e){if(null!=e){try{return t.call(e)}catch(n){}try{return e+""}catch(n){}}return""}},31800:e=>{var t=/\s/;e.exports=function(e){for(var n=e.length;n--&&t.test(e.charAt(n)););return n}},38221:(e,t,n)=>{var r=n(23805),i=n(10124),a=n(99374),o=Math.max,s=Math.min;e.exports=function(e,t,n){var l,u,c,h,d,p,g=0,f=!1,v=!1,y=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function m(t){var n=l,r=u;return l=u=void 0,g=t,h=e.apply(r,n)}function b(e){var n=e-p;return void 0===p||n>=t||n<0||v&&e-g>=c}function x(){var e=i();if(b(e))return w(e);d=setTimeout(x,function(e){var n=t-(e-p);return v?s(n,c-(e-g)):n}(e))}function w(e){return d=void 0,y&&l?m(e):(l=u=void 0,h)}function E(){var e=i(),n=b(e);if(l=arguments,u=this,p=e,n){if(void 0===d)return function(e){return g=e,d=setTimeout(x,t),f?m(e):h}(p);if(v)return clearTimeout(d),d=setTimeout(x,t),m(p)}return void 0===d&&(d=setTimeout(x,t)),h}return t=a(t)||0,r(n)&&(f=!!n.leading,c=(v="maxWait"in n)?o(a(n.maxWait)||0,t):c,y="trailing"in n?!!n.trailing:y),E.cancel=function(){void 0!==d&&clearTimeout(d),g=0,l=p=u=d=void 0},E.flush=function(){return void 0===d?h:w(i())},E}},75288:e=>{e.exports=function(e,t){return e===t||e!=e&&t!=t}},58156:(e,t,n)=>{var r=n(47422);e.exports=function(e,t,n){var i=null==e?void 0:r(e,t);return void 0===i?n:i}},56449:e=>{var t=Array.isArray;e.exports=t},1882:(e,t,n)=>{var r=n(72552),i=n(23805);e.exports=function(e){if(!i(e))return!1;var t=r(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t}},23805:e=>{e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},40346:e=>{e.exports=function(e){return null!=e&&"object"==typeof e}},44394:(e,t,n)=>{var r=n(72552),i=n(40346);e.exports=function(e){return"symbol"==typeof e||i(e)&&"[object Symbol]"==r(e)}},50104:(e,t,n)=>{var r=n(53661);function i(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new TypeError("Expected a function");var n=function(){var r=arguments,i=t?t.apply(this,r):r[0],a=n.cache;if(a.has(i))return a.get(i);var o=e.apply(this,r);return n.cache=a.set(i,o)||a,o};return n.cache=new(i.Cache||r),n}i.Cache=r,e.exports=i},10124:(e,t,n)=>{var r=n(9325);e.exports=function(){return r.Date.now()}},63560:(e,t,n)=>{var r=n(73170);e.exports=function(e,t,n){return null==e?e:r(e,t,n)}},99374:(e,t,n)=>{var r=n(54128),i=n(23805),a=n(44394),o=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,l=/^0o[0-7]+$/i,u=parseInt;e.exports=function(e){if("number"==typeof e)return e;if(a(e))return NaN;if(i(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=i(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=r(e);var n=s.test(e);return n||l.test(e)?u(e.slice(2),n?2:8):o.test(e)?NaN:+e}},42072:(e,t,n)=>{var r=n(34932),i=n(23007),a=n(56449),o=n(44394),s=n(61802),l=n(77797),u=n(13222);e.exports=function(e){return a(e)?r(e,l):o(e)?[e]:i(s(u(e)))}},13222:(e,t,n)=>{var r=n(77556);e.exports=function(e){return null==e?"":r(e)}},93771:(e,t,n)=>{"use strict";n.d(t,{diagram:()=>w});var r=n(76257),i=n(44726),a=n(43457),o=n(26312),s=n(45829),l=n(3219),u=n(78041),c=n(75263),h=(n(74353),n(16750),n(42838),function(){var e=function(e,t,n,r){for(n=n||{},r=e.length;r--;n[e[r]]=t);return n},t=[1,4],n=[1,13],r=[1,12],i=[1,15],a=[1,16],o=[1,20],s=[1,19],l=[6,7,8],u=[1,26],c=[1,24],h=[1,25],d=[6,7,11],p=[1,6,13,15,16,19,22],g=[1,33],f=[1,34],v=[1,6,7,11,13,15,16,19,22],y={trace:function(){},yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,MINDMAP:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,ICON:15,CLASS:16,nodeWithId:17,nodeWithoutId:18,NODE_DSTART:19,NODE_DESCR:20,NODE_DEND:21,NODE_ID:22,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"MINDMAP",11:"EOF",13:"SPACELIST",15:"ICON",16:"CLASS",19:"NODE_DSTART",20:"NODE_DESCR",21:"NODE_DEND",22:"NODE_ID"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,2],[12,2],[12,2],[12,1],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[18,3],[17,1],[17,4]],performAction:function(e,t,n,r,i,a,o){var s=a.length-1;switch(i){case 6:case 7:return r;case 8:r.getLogger().trace("Stop NL ");break;case 9:r.getLogger().trace("Stop EOF ");break;case 11:r.getLogger().trace("Stop NL2 ");break;case 12:r.getLogger().trace("Stop EOF2 ");break;case 15:r.getLogger().info("Node: ",a[s].id),r.addNode(a[s-1].length,a[s].id,a[s].descr,a[s].type);break;case 16:r.getLogger().trace("Icon: ",a[s]),r.decorateNode({icon:a[s]});break;case 17:case 21:r.decorateNode({class:a[s]});break;case 18:r.getLogger().trace("SPACELIST");break;case 19:r.getLogger().trace("Node: ",a[s].id),r.addNode(0,a[s].id,a[s].descr,a[s].type);break;case 20:r.decorateNode({icon:a[s]});break;case 25:r.getLogger().trace("node found ..",a[s-2]),this.$={id:a[s-1],descr:a[s-1],type:r.getType(a[s-2],a[s])};break;case 26:this.$={id:a[s],descr:a[s],type:r.nodeType.DEFAULT};break;case 27:r.getLogger().trace("node found ..",a[s-3]),this.$={id:a[s-3],descr:a[s-1],type:r.getType(a[s-2],a[s])}}},table:[{3:1,4:2,5:3,6:[1,5],8:t},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:t},{6:n,7:[1,10],9:9,12:11,13:r,14:14,15:i,16:a,17:17,18:18,19:o,22:s},e(l,[2,3]),{1:[2,2]},e(l,[2,4]),e(l,[2,5]),{1:[2,6],6:n,12:21,13:r,14:14,15:i,16:a,17:17,18:18,19:o,22:s},{6:n,9:22,12:11,13:r,14:14,15:i,16:a,17:17,18:18,19:o,22:s},{6:u,7:c,10:23,11:h},e(d,[2,22],{17:17,18:18,14:27,15:[1,28],16:[1,29],19:o,22:s}),e(d,[2,18]),e(d,[2,19]),e(d,[2,20]),e(d,[2,21]),e(d,[2,23]),e(d,[2,24]),e(d,[2,26],{19:[1,30]}),{20:[1,31]},{6:u,7:c,10:32,11:h},{1:[2,7],6:n,12:21,13:r,14:14,15:i,16:a,17:17,18:18,19:o,22:s},e(p,[2,14],{7:g,11:f}),e(v,[2,8]),e(v,[2,9]),e(v,[2,10]),e(d,[2,15]),e(d,[2,16]),e(d,[2,17]),{20:[1,35]},{21:[1,36]},e(p,[2,13],{7:g,11:f}),e(v,[2,11]),e(v,[2,12]),{21:[1,37]},e(d,[2,25]),e(d,[2,27])],defaultActions:{2:[2,1],6:[2,2]},parseError:function(e,t){if(!t.recoverable){var n=new Error(e);throw n.hash=t,n}this.trace(e)},parse:function(e){var t=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",l=0,u=0,c=a.slice.call(arguments,1),h=Object.create(this.lexer),d={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(d.yy[p]=this.yy[p]);h.setInput(e,d.yy),d.yy.lexer=h,d.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var g=h.yylloc;a.push(g);var f=h.options&&h.options.ranges;"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var v,y,m,b,x,w,E,_,T,D={};;){if(y=n[n.length-1],this.defaultActions[y]?m=this.defaultActions[y]:(null==v&&(T=void 0,"number"!=typeof(T=r.pop()||h.lex()||1)&&(T instanceof Array&&(T=(r=T).pop()),T=t.symbols_[T]||T),v=T),m=o[y]&&o[y][v]),void 0===m||!m.length||!m[0]){var C="";for(x in _=[],o[y])this.terminals_[x]&&x>2&&_.push("'"+this.terminals_[x]+"'");C=h.showPosition?"Parse error on line "+(l+1)+":\n"+h.showPosition()+"\nExpecting "+_.join(", ")+", got '"+(this.terminals_[v]||v)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==v?"end of input":"'"+(this.terminals_[v]||v)+"'"),this.parseError(C,{text:h.match,token:this.terminals_[v]||v,line:h.yylineno,loc:g,expected:_})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+y+", token: "+v);switch(m[0]){case 1:n.push(v),i.push(h.yytext),a.push(h.yylloc),n.push(m[1]),v=null,u=h.yyleng,s=h.yytext,l=h.yylineno,g=h.yylloc;break;case 2:if(w=this.productions_[m[1]][1],D.$=i[i.length-w],D._$={first_line:a[a.length-(w||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(w||1)].first_column,last_column:a[a.length-1].last_column},f&&(D._$.range=[a[a.length-(w||1)].range[0],a[a.length-1].range[1]]),void 0!==(b=this.performAction.apply(D,[s,u,l,d.yy,m[1],i,a].concat(c))))return b;w&&(n=n.slice(0,-1*w*2),i=i.slice(0,-1*w),a=a.slice(0,-1*w)),n.push(this.productions_[m[1]][0]),i.push(D.$),a.push(D._$),E=o[n[n.length-2]][n[n.length-1]],n.push(E);break;case 3:return!0}}return!0}},m={EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,n=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],n=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var e,t,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;a<i.length;a++)if((n=this._input.match(this.rules[i[a]]))&&(!t||n[0].length>t[0].length)){if(t=n,r=a,this.options.backtrack_lexer){if(!1!==(e=this.test_match(n,i[a])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,i[r]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(e,t,n,r){switch(n){case 0:return e.getLogger().trace("Found comment",t.yytext),6;case 1:return 8;case 2:this.begin("CLASS");break;case 3:return this.popState(),16;case 4:case 23:case 26:this.popState();break;case 5:e.getLogger().trace("Begin icon"),this.begin("ICON");break;case 6:return e.getLogger().trace("SPACELINE"),6;case 7:return 7;case 8:return 15;case 9:e.getLogger().trace("end icon"),this.popState();break;case 10:return e.getLogger().trace("Exploding node"),this.begin("NODE"),19;case 11:return e.getLogger().trace("Cloud"),this.begin("NODE"),19;case 12:return e.getLogger().trace("Explosion Bang"),this.begin("NODE"),19;case 13:return e.getLogger().trace("Cloud Bang"),this.begin("NODE"),19;case 14:case 15:case 16:case 17:return this.begin("NODE"),19;case 18:return 13;case 19:return 22;case 20:return 11;case 21:this.begin("NSTR2");break;case 22:return"NODE_DESCR";case 24:e.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 25:return e.getLogger().trace("description:",t.yytext),"NODE_DESCR";case 27:return this.popState(),e.getLogger().trace("node end ))"),"NODE_DEND";case 28:return this.popState(),e.getLogger().trace("node end )"),"NODE_DEND";case 29:return this.popState(),e.getLogger().trace("node end ...",t.yytext),"NODE_DEND";case 30:case 33:case 34:return this.popState(),e.getLogger().trace("node end (("),"NODE_DEND";case 31:case 32:return this.popState(),e.getLogger().trace("node end (-"),"NODE_DEND";case 35:case 36:return e.getLogger().trace("Long description:",t.yytext),20}},rules:[/^(?:\s*%%.*)/i,/^(?:mindmap\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{CLASS:{rules:[3,4],inclusive:!1},ICON:{rules:[8,9],inclusive:!1},NSTR2:{rules:[22,23],inclusive:!1},NSTR:{rules:[25,26],inclusive:!1},NODE:{rules:[21,24,27,28,29,30,31,32,33,34,35,36],inclusive:!1},INITIAL:{rules:[0,1,2,5,6,7,10,11,12,13,14,15,16,17,18,19,20],inclusive:!0}}};function b(){this.yy={}}return y.lexer=m,b.prototype=y,y.Parser=b,new b}());h.parser=h;const d=h;let p=[],g=0,f={};const v={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},y={clear:()=>{p=[],g=0,f={}},addNode:(e,t,n,i)=>{var a,o;r.l.info("addNode",e,t,n,i);const s=(0,r.c)();let l=(null==(a=s.mindmap)?void 0:a.padding)??r.B.mindmap.padding;switch(i){case v.ROUNDED_RECT:case v.RECT:case v.HEXAGON:l*=2}const u={id:g++,nodeId:(0,r.d)(t,s),level:e,descr:(0,r.d)(n,s),type:i,children:[],width:(null==(o=s.mindmap)?void 0:o.maxNodeWidth)??r.B.mindmap.maxNodeWidth,padding:l},c=function(e){for(let t=p.length-1;t>=0;t--)if(p[t].level<e)return p[t];return null}(e);if(c)c.children.push(u),p.push(u);else{if(0!==p.length)throw new Error('There can be only one root. No parent could be found for ("'+u.descr+'")');p.push(u)}},getMindmap:()=>p.length>0?p[0]:null,nodeType:v,getType:(e,t)=>{switch(r.l.debug("In get type",e,t),e){case"[":return v.RECT;case"(":return")"===t?v.ROUNDED_RECT:v.CLOUD;case"((":return v.CIRCLE;case")":return v.CLOUD;case"))":return v.BANG;case"{{":return v.HEXAGON;default:return v.DEFAULT}},setElementForId:(e,t)=>{f[e]=t},decorateNode:e=>{if(!e)return;const t=(0,r.c)(),n=p[p.length-1];e.icon&&(n.icon=(0,r.d)(e.icon,t)),e.class&&(n.class=(0,r.d)(e.class,t))},type2Str:e=>{switch(e){case v.DEFAULT:return"no-border";case v.RECT:return"rect";case v.ROUNDED_RECT:return"rounded-rect";case v.CIRCLE:return"circle";case v.CLOUD:return"cloud";case v.BANG:return"bang";case v.HEXAGON:return"hexgon";default:return"no-border"}},getLogger:()=>r.l,getElementById:e=>f[e]};function m(e,t,n,i,a){!function(e,t,n,i,a){const o=a.htmlLabels,l=i%11,u=t.append("g");n.section=l;let c="section-"+l;l<0&&(c+=" section-root"),u.attr("class",(n.class?n.class+" ":"")+"mindmap-node "+c);const h=u.append("g"),d=u.append("g"),p=n.descr.replace(/(<br\/*>)/g,"\n");(0,s.a)(d,p,{useHtmlLabels:o,width:n.width,classes:"mindmap-node-label"}),o||d.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle");const g=d.node().getBBox(),[f]=(0,r.D)(a.fontSize);if(n.height=g.height+1.1*f*.5+n.padding,n.width=g.width+2*n.padding,n.icon)if(n.type===e.nodeType.CIRCLE)n.height+=50,n.width+=50,u.append("foreignObject").attr("height","50px").attr("width",n.width).attr("style","text-align: center;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+l+" "+n.icon),d.attr("transform","translate("+n.width/2+", "+(n.height/2-1.5*n.padding)+")");else{n.width+=50;const e=n.height;n.height=Math.max(e,60);const t=Math.abs(n.height-e);u.append("foreignObject").attr("width","60px").attr("height",n.height).attr("style","text-align: center;margin-top:"+t/2+"px;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+l+" "+n.icon),d.attr("transform","translate("+(25+n.width/2)+", "+(t/2+n.padding/2)+")")}else if(o){const e=(n.width-g.width)/2,t=(n.height-g.height)/2;d.attr("transform","translate("+e+", "+t+")")}else{const e=n.width/2,t=n.padding/2;d.attr("transform","translate("+e+", "+t+")")}switch(n.type){case e.nodeType.DEFAULT:!function(e,t,n,r){t.append("path").attr("id","node-"+n.id).attr("class","node-bkg node-"+e.type2Str(n.type)).attr("d",`M0 ${n.height-5} v${10-n.height} q0,-5 5,-5 h${n.width-10} q5,0 5,5 v${n.height-5} H0 Z`),t.append("line").attr("class","node-line-"+r).attr("x1",0).attr("y1",n.height).attr("x2",n.width).attr("y2",n.height)}(e,h,n,l);break;case e.nodeType.ROUNDED_RECT:!function(e,t,n){t.append("rect").attr("id","node-"+n.id).attr("class","node-bkg node-"+e.type2Str(n.type)).attr("height",n.height).attr("rx",n.padding).attr("ry",n.padding).attr("width",n.width)}(e,h,n);break;case e.nodeType.RECT:!function(e,t,n){t.append("rect").attr("id","node-"+n.id).attr("class","node-bkg node-"+e.type2Str(n.type)).attr("height",n.height).attr("width",n.width)}(e,h,n);break;case e.nodeType.CIRCLE:h.attr("transform","translate("+n.width/2+", "+ +n.height/2+")"),function(e,t,n){t.append("circle").attr("id","node-"+n.id).attr("class","node-bkg node-"+e.type2Str(n.type)).attr("r",n.width/2)}(e,h,n);break;case e.nodeType.CLOUD:!function(e,t,n){const r=n.width,i=n.height,a=.15*r,o=.25*r,s=.35*r,l=.2*r;t.append("path").attr("id","node-"+n.id).attr("class","node-bkg node-"+e.type2Str(n.type)).attr("d",`M0 0 a${a},${a} 0 0,1 ${.25*r},${-1*r*.1}\n a${s},${s} 1 0,1 ${.4*r},${-1*r*.1}\n a${o},${o} 1 0,1 ${.35*r},${1*r*.2}\n\n a${a},${a} 1 0,1 ${.15*r},${1*i*.35}\n a${l},${l} 1 0,1 ${-1*r*.15},${1*i*.65}\n\n a${o},${a} 1 0,1 ${-1*r*.25},${.15*r}\n a${s},${s} 1 0,1 ${-1*r*.5},0\n a${a},${a} 1 0,1 ${-1*r*.25},${-1*r*.15}\n\n a${a},${a} 1 0,1 ${-1*r*.1},${-1*i*.35}\n a${l},${l} 1 0,1 ${.1*r},${-1*i*.65}\n\n H0 V0 Z`)}(e,h,n);break;case e.nodeType.BANG:!function(e,t,n){const r=n.width,i=n.height,a=.15*r;t.append("path").attr("id","node-"+n.id).attr("class","node-bkg node-"+e.type2Str(n.type)).attr("d",`M0 0 a${a},${a} 1 0,0 ${.25*r},${-1*i*.1}\n a${a},${a} 1 0,0 ${.25*r},0\n a${a},${a} 1 0,0 ${.25*r},0\n a${a},${a} 1 0,0 ${.25*r},${1*i*.1}\n\n a${a},${a} 1 0,0 ${.15*r},${1*i*.33}\n a${.8*a},${.8*a} 1 0,0 0,${1*i*.34}\n a${a},${a} 1 0,0 ${-1*r*.15},${1*i*.33}\n\n a${a},${a} 1 0,0 ${-1*r*.25},${.15*i}\n a${a},${a} 1 0,0 ${-1*r*.25},0\n a${a},${a} 1 0,0 ${-1*r*.25},0\n a${a},${a} 1 0,0 ${-1*r*.25},${-1*i*.15}\n\n a${a},${a} 1 0,0 ${-1*r*.1},${-1*i*.33}\n a${.8*a},${.8*a} 1 0,0 0,${-1*i*.34}\n a${a},${a} 1 0,0 ${.1*r},${-1*i*.33}\n\n H0 V0 Z`)}(e,h,n);break;case e.nodeType.HEXAGON:!function(e,t,n){const r=n.height,i=r/4,a=n.width-n.padding+2*i;!function(e,t,n,r,i){e.insert("polygon",":first-child").attr("points",r.map((function(e){return e.x+","+e.y})).join(" ")).attr("transform","translate("+(i.width-t)/2+", "+n+")")}(t,a,r,[{x:i,y:0},{x:a-i,y:0},{x:a,y:-r/2},{x:a-i,y:-r},{x:i,y:-r},{x:0,y:-r/2}],n)}(0,h,n)}e.setElementForId(n.id,u),n.height}(e,t,n,i,a),n.children&&n.children.forEach(((n,r)=>{m(e,t,n,i<0?r:i,a)}))}function b(e,t,n,r){t.add({group:"nodes",data:{id:e.id.toString(),labelText:e.descr,height:e.height,width:e.width,level:r,nodeId:e.id,padding:e.padding,type:e.type},position:{x:e.x,y:e.y}}),e.children&&e.children.forEach((i=>{b(i,t,n,r+1),t.add({group:"edges",data:{id:`${e.id}_${i.id}`,source:e.id,target:i.id,depth:r,section:i.section}})}))}function x(e,t){return new Promise((n=>{const a=(0,o.Ltv)("body").append("div").attr("id","cy").attr("style","display:none"),s=i({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"bezier"}}]});a.remove(),b(e,s,t,0),s.nodes().forEach((function(e){e.layoutDimensions=()=>{const t=e.data();return{w:t.width,h:t.height}}})),s.layout({name:"cose-bilkent",quality:"proof",styleEnabled:!1,animate:!1}).run(),s.ready((e=>{r.l.info("Ready",e),n(s)}))}))}i.use(a);const w={db:y,renderer:{draw:async(e,t,n,i)=>{var a,o;r.l.debug("Rendering mindmap diagram\n"+e);const s=i.db,l=s.getMindmap();if(!l)return;const u=(0,r.c)();u.htmlLabels=!1;const c=(0,r.A)(t),h=c.append("g");h.attr("class","mindmap-edges");const d=c.append("g");d.attr("class","mindmap-nodes"),m(s,d,l,-1,u);const p=await x(l,u);!function(e,t){t.edges().map(((t,n)=>{const i=t.data();if(t[0]._private.bodyBounds){const a=t[0]._private.rscratch;r.l.trace("Edge: ",n,i),e.insert("path").attr("d",`M ${a.startX},${a.startY} L ${a.midX},${a.midY} L${a.endX},${a.endY} `).attr("class","edge section-edge-"+i.section+" edge-depth-"+i.depth)}}))}(h,p),function(e,t){t.nodes().map(((t,n)=>{const i=t.data();i.x=t.position().x,i.y=t.position().y,function(e,t){const n=e.getElementById(t.id),r=t.x||0,i=t.y||0;n.attr("transform","translate("+r+","+i+")")}(e,i);const a=e.getElementById(i.nodeId);r.l.info("Id:",n,"Position: (",t.position().x,", ",t.position().y,")",i),a.attr("transform",`translate(${t.position().x-i.width/2}, ${t.position().y-i.height/2})`),a.attr("attr",`apa-${n})`)}))}(s,p),(0,r.o)(void 0,c,(null==(a=u.mindmap)?void 0:a.padding)??r.B.mindmap.padding,(null==(o=u.mindmap)?void 0:o.useMaxWidth)??r.B.mindmap.useMaxWidth)}},parser:d,styles:e=>`\n .edge {\n stroke-width: 3;\n }\n ${(e=>{let t="";for(let n=0;n<e.THEME_COLOR_LIMIT;n++)e["lineColor"+n]=e["lineColor"+n]||e["cScaleInv"+n],(0,l.A)(e["lineColor"+n])?e["lineColor"+n]=(0,u.A)(e["lineColor"+n],20):e["lineColor"+n]=(0,c.A)(e["lineColor"+n],20);for(let n=0;n<e.THEME_COLOR_LIMIT;n++){const r=""+(17-3*n);t+=`\n .section-${n-1} rect, .section-${n-1} path, .section-${n-1} circle, .section-${n-1} polygon, .section-${n-1} path {\n fill: ${e["cScale"+n]};\n }\n .section-${n-1} text {\n fill: ${e["cScaleLabel"+n]};\n }\n .node-icon-${n-1} {\n font-size: 40px;\n color: ${e["cScaleLabel"+n]};\n }\n .section-edge-${n-1}{\n stroke: ${e["cScale"+n]};\n }\n .edge-depth-${n-1}{\n stroke-width: ${r};\n }\n .section-${n-1} line {\n stroke: ${e["cScaleInv"+n]} ;\n stroke-width: 3;\n }\n\n .disabled, .disabled circle, .disabled text {\n fill: lightgray;\n }\n .disabled text {\n fill: #efefef;\n }\n `}return t})(e)}\n .section-root rect, .section-root path, .section-root circle, .section-root polygon {\n fill: ${e.git0};\n }\n .section-root text {\n fill: ${e.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .mindmap-node-label {\n dy: 1em;\n alignment-baseline: middle;\n text-anchor: middle;\n dominant-baseline: middle;\n text-align: center;\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/3771.46254ee5.js.LICENSE.txt b/assets/js/3771.46254ee5.js.LICENSE.txt new file mode 100644 index 0000000000..a9f6f12447 --- /dev/null +++ b/assets/js/3771.46254ee5.js.LICENSE.txt @@ -0,0 +1,9 @@ +/*! +Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable +Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com) +Licensed under The MIT License (http://opensource.org/licenses/MIT) +*/ + +/*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */ + +/*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */ diff --git a/assets/js/37a5cb6b.472dae82.js b/assets/js/37a5cb6b.472dae82.js new file mode 100644 index 0000000000..1d9166f17f --- /dev/null +++ b/assets/js/37a5cb6b.472dae82.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1384],{72444:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>o});var n=s(74848),c=s(28453);const i={},r="scs-0402: Status page OpenAPI decision",a={id:"ops/scs-0402",title:"scs-0402: Status page OpenAPI decision",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/ops/scs-0402.md",sourceDirName:"ops",slug:"/ops/scs-0402",permalink:"/standards/ops/scs-0402",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Status page reference implementation decision",permalink:"/standards/scs-0401-v1-status-page-reference-implementation-decision"},next:{title:"Status page OpenAPI decision",permalink:"/standards/scs-0402-v1-status-page-openapi-spec-decision"}},d={},o=[];function p(e){const t={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"scs-0402-status-page-openapi-decision",children:"scs-0402: Status page OpenAPI decision"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0402-v1-status-page-openapi-spec-decision",children:"scs-0402-v1"})}),(0,n.jsx)(t.td,{children:"Decision Record"}),(0,n.jsx)(t.td,{children:"Draft"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function l(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>a});var n=s(96540);const c={},i=n.createContext(c);function r(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3863.e17ac104.js b/assets/js/3863.e17ac104.js new file mode 100644 index 0000000000..b7bc13438e --- /dev/null +++ b/assets/js/3863.e17ac104.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3863],{83863:(t,e,n)=>{n.d(e,{diagram:()=>nt});var a=n(76257),i=n(26312),s=n(58886),r=n(16750),l=(n(74353),n(42838),function(){var t=function(t,e,n,a){for(n=n||{},a=t.length;a--;n[t[a]]=e);return n},e=[1,24],n=[1,25],a=[1,26],i=[1,27],s=[1,28],r=[1,63],l=[1,64],o=[1,65],h=[1,66],d=[1,67],u=[1,68],p=[1,69],y=[1,29],f=[1,30],b=[1,31],g=[1,32],x=[1,33],_=[1,34],m=[1,35],E=[1,36],A=[1,37],S=[1,38],C=[1,39],k=[1,40],O=[1,41],v=[1,42],T=[1,43],w=[1,44],R=[1,45],D=[1,46],N=[1,47],P=[1,48],M=[1,50],j=[1,51],B=[1,52],L=[1,53],Y=[1,54],I=[1,55],U=[1,56],F=[1,57],X=[1,58],z=[1,59],W=[1,60],Q=[14,42],$=[14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],q=[12,14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],V=[1,82],G=[1,83],H=[1,84],K=[1,85],J=[12,14,42],Z=[12,14,33,42],tt=[12,14,33,42,76,77,79,80],et=[12,33],nt=[34,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],at={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,direction_tb:6,direction_bt:7,direction_rl:8,direction_lr:9,graphConfig:10,C4_CONTEXT:11,NEWLINE:12,statements:13,EOF:14,C4_CONTAINER:15,C4_COMPONENT:16,C4_DYNAMIC:17,C4_DEPLOYMENT:18,otherStatements:19,diagramStatements:20,otherStatement:21,title:22,accDescription:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,boundaryStatement:29,boundaryStartStatement:30,boundaryStopStatement:31,boundaryStart:32,LBRACE:33,ENTERPRISE_BOUNDARY:34,attributes:35,SYSTEM_BOUNDARY:36,BOUNDARY:37,CONTAINER_BOUNDARY:38,NODE:39,NODE_L:40,NODE_R:41,RBRACE:42,diagramStatement:43,PERSON:44,PERSON_EXT:45,SYSTEM:46,SYSTEM_DB:47,SYSTEM_QUEUE:48,SYSTEM_EXT:49,SYSTEM_EXT_DB:50,SYSTEM_EXT_QUEUE:51,CONTAINER:52,CONTAINER_DB:53,CONTAINER_QUEUE:54,CONTAINER_EXT:55,CONTAINER_EXT_DB:56,CONTAINER_EXT_QUEUE:57,COMPONENT:58,COMPONENT_DB:59,COMPONENT_QUEUE:60,COMPONENT_EXT:61,COMPONENT_EXT_DB:62,COMPONENT_EXT_QUEUE:63,REL:64,BIREL:65,REL_U:66,REL_D:67,REL_L:68,REL_R:69,REL_B:70,REL_INDEX:71,UPDATE_EL_STYLE:72,UPDATE_REL_STYLE:73,UPDATE_LAYOUT_CONFIG:74,attribute:75,STR:76,STR_KEY:77,STR_VALUE:78,ATTRIBUTE:79,ATTRIBUTE_EMPTY:80,$accept:0,$end:1},terminals_:{2:"error",6:"direction_tb",7:"direction_bt",8:"direction_rl",9:"direction_lr",11:"C4_CONTEXT",12:"NEWLINE",14:"EOF",15:"C4_CONTAINER",16:"C4_COMPONENT",17:"C4_DYNAMIC",18:"C4_DEPLOYMENT",22:"title",23:"accDescription",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"LBRACE",34:"ENTERPRISE_BOUNDARY",36:"SYSTEM_BOUNDARY",37:"BOUNDARY",38:"CONTAINER_BOUNDARY",39:"NODE",40:"NODE_L",41:"NODE_R",42:"RBRACE",44:"PERSON",45:"PERSON_EXT",46:"SYSTEM",47:"SYSTEM_DB",48:"SYSTEM_QUEUE",49:"SYSTEM_EXT",50:"SYSTEM_EXT_DB",51:"SYSTEM_EXT_QUEUE",52:"CONTAINER",53:"CONTAINER_DB",54:"CONTAINER_QUEUE",55:"CONTAINER_EXT",56:"CONTAINER_EXT_DB",57:"CONTAINER_EXT_QUEUE",58:"COMPONENT",59:"COMPONENT_DB",60:"COMPONENT_QUEUE",61:"COMPONENT_EXT",62:"COMPONENT_EXT_DB",63:"COMPONENT_EXT_QUEUE",64:"REL",65:"BIREL",66:"REL_U",67:"REL_D",68:"REL_L",69:"REL_R",70:"REL_B",71:"REL_INDEX",72:"UPDATE_EL_STYLE",73:"UPDATE_REL_STYLE",74:"UPDATE_LAYOUT_CONFIG",76:"STR",77:"STR_KEY",78:"STR_VALUE",79:"ATTRIBUTE",80:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[5,1],[5,1],[5,1],[5,1],[4,1],[10,4],[10,4],[10,4],[10,4],[10,4],[13,1],[13,1],[13,2],[19,1],[19,2],[19,3],[21,1],[21,1],[21,2],[21,2],[21,1],[29,3],[30,3],[30,3],[30,4],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[31,1],[20,1],[20,2],[20,3],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,1],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[35,1],[35,2],[75,1],[75,2],[75,1],[75,1]],performAction:function(t,e,n,a,i,s,r){var l=s.length-1;switch(i){case 3:a.setDirection("TB");break;case 4:a.setDirection("BT");break;case 5:a.setDirection("RL");break;case 6:a.setDirection("LR");break;case 8:case 9:case 10:case 11:case 12:a.setC4Type(s[l-3]);break;case 19:a.setTitle(s[l].substring(6)),this.$=s[l].substring(6);break;case 20:a.setAccDescription(s[l].substring(15)),this.$=s[l].substring(15);break;case 21:this.$=s[l].trim(),a.setTitle(this.$);break;case 22:case 23:this.$=s[l].trim(),a.setAccDescription(this.$);break;case 28:case 29:s[l].splice(2,0,"ENTERPRISE"),a.addPersonOrSystemBoundary(...s[l]),this.$=s[l];break;case 30:a.addPersonOrSystemBoundary(...s[l]),this.$=s[l];break;case 31:s[l].splice(2,0,"CONTAINER"),a.addContainerBoundary(...s[l]),this.$=s[l];break;case 32:a.addDeploymentNode("node",...s[l]),this.$=s[l];break;case 33:a.addDeploymentNode("nodeL",...s[l]),this.$=s[l];break;case 34:a.addDeploymentNode("nodeR",...s[l]),this.$=s[l];break;case 35:a.popBoundaryParseStack();break;case 39:a.addPersonOrSystem("person",...s[l]),this.$=s[l];break;case 40:a.addPersonOrSystem("external_person",...s[l]),this.$=s[l];break;case 41:a.addPersonOrSystem("system",...s[l]),this.$=s[l];break;case 42:a.addPersonOrSystem("system_db",...s[l]),this.$=s[l];break;case 43:a.addPersonOrSystem("system_queue",...s[l]),this.$=s[l];break;case 44:a.addPersonOrSystem("external_system",...s[l]),this.$=s[l];break;case 45:a.addPersonOrSystem("external_system_db",...s[l]),this.$=s[l];break;case 46:a.addPersonOrSystem("external_system_queue",...s[l]),this.$=s[l];break;case 47:a.addContainer("container",...s[l]),this.$=s[l];break;case 48:a.addContainer("container_db",...s[l]),this.$=s[l];break;case 49:a.addContainer("container_queue",...s[l]),this.$=s[l];break;case 50:a.addContainer("external_container",...s[l]),this.$=s[l];break;case 51:a.addContainer("external_container_db",...s[l]),this.$=s[l];break;case 52:a.addContainer("external_container_queue",...s[l]),this.$=s[l];break;case 53:a.addComponent("component",...s[l]),this.$=s[l];break;case 54:a.addComponent("component_db",...s[l]),this.$=s[l];break;case 55:a.addComponent("component_queue",...s[l]),this.$=s[l];break;case 56:a.addComponent("external_component",...s[l]),this.$=s[l];break;case 57:a.addComponent("external_component_db",...s[l]),this.$=s[l];break;case 58:a.addComponent("external_component_queue",...s[l]),this.$=s[l];break;case 60:a.addRel("rel",...s[l]),this.$=s[l];break;case 61:a.addRel("birel",...s[l]),this.$=s[l];break;case 62:a.addRel("rel_u",...s[l]),this.$=s[l];break;case 63:a.addRel("rel_d",...s[l]),this.$=s[l];break;case 64:a.addRel("rel_l",...s[l]),this.$=s[l];break;case 65:a.addRel("rel_r",...s[l]),this.$=s[l];break;case 66:a.addRel("rel_b",...s[l]),this.$=s[l];break;case 67:s[l].splice(0,1),a.addRel("rel",...s[l]),this.$=s[l];break;case 68:a.updateElStyle("update_el_style",...s[l]),this.$=s[l];break;case 69:a.updateRelStyle("update_rel_style",...s[l]),this.$=s[l];break;case 70:a.updateLayoutConfig("update_layout_config",...s[l]),this.$=s[l];break;case 71:this.$=[s[l]];break;case 72:s[l].unshift(s[l-1]),this.$=s[l];break;case 73:case 75:this.$=s[l].trim();break;case 74:let t={};t[s[l-1].trim()]=s[l].trim(),this.$=t;break;case 76:this.$=""}},table:[{3:1,4:2,5:3,6:[1,5],7:[1,6],8:[1,7],9:[1,8],10:4,11:[1,9],15:[1,10],16:[1,11],17:[1,12],18:[1,13]},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,7]},{1:[2,3]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{12:[1,14]},{12:[1,15]},{12:[1,16]},{12:[1,17]},{12:[1,18]},{13:19,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W},{13:70,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W},{13:71,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W},{13:72,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W},{13:73,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W},{14:[1,74]},t(Q,[2,13],{43:23,29:49,30:61,32:62,20:75,34:r,36:l,37:o,38:h,39:d,40:u,41:p,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W}),t(Q,[2,14]),t($,[2,16],{12:[1,76]}),t(Q,[2,36],{12:[1,77]}),t(q,[2,19]),t(q,[2,20]),{25:[1,78]},{27:[1,79]},t(q,[2,23]),{35:80,75:81,76:V,77:G,79:H,80:K},{35:86,75:81,76:V,77:G,79:H,80:K},{35:87,75:81,76:V,77:G,79:H,80:K},{35:88,75:81,76:V,77:G,79:H,80:K},{35:89,75:81,76:V,77:G,79:H,80:K},{35:90,75:81,76:V,77:G,79:H,80:K},{35:91,75:81,76:V,77:G,79:H,80:K},{35:92,75:81,76:V,77:G,79:H,80:K},{35:93,75:81,76:V,77:G,79:H,80:K},{35:94,75:81,76:V,77:G,79:H,80:K},{35:95,75:81,76:V,77:G,79:H,80:K},{35:96,75:81,76:V,77:G,79:H,80:K},{35:97,75:81,76:V,77:G,79:H,80:K},{35:98,75:81,76:V,77:G,79:H,80:K},{35:99,75:81,76:V,77:G,79:H,80:K},{35:100,75:81,76:V,77:G,79:H,80:K},{35:101,75:81,76:V,77:G,79:H,80:K},{35:102,75:81,76:V,77:G,79:H,80:K},{35:103,75:81,76:V,77:G,79:H,80:K},{35:104,75:81,76:V,77:G,79:H,80:K},t(J,[2,59]),{35:105,75:81,76:V,77:G,79:H,80:K},{35:106,75:81,76:V,77:G,79:H,80:K},{35:107,75:81,76:V,77:G,79:H,80:K},{35:108,75:81,76:V,77:G,79:H,80:K},{35:109,75:81,76:V,77:G,79:H,80:K},{35:110,75:81,76:V,77:G,79:H,80:K},{35:111,75:81,76:V,77:G,79:H,80:K},{35:112,75:81,76:V,77:G,79:H,80:K},{35:113,75:81,76:V,77:G,79:H,80:K},{35:114,75:81,76:V,77:G,79:H,80:K},{35:115,75:81,76:V,77:G,79:H,80:K},{20:116,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W},{12:[1,118],33:[1,117]},{35:119,75:81,76:V,77:G,79:H,80:K},{35:120,75:81,76:V,77:G,79:H,80:K},{35:121,75:81,76:V,77:G,79:H,80:K},{35:122,75:81,76:V,77:G,79:H,80:K},{35:123,75:81,76:V,77:G,79:H,80:K},{35:124,75:81,76:V,77:G,79:H,80:K},{35:125,75:81,76:V,77:G,79:H,80:K},{14:[1,126]},{14:[1,127]},{14:[1,128]},{14:[1,129]},{1:[2,8]},t(Q,[2,15]),t($,[2,17],{21:22,19:130,22:e,23:n,24:a,26:i,28:s}),t(Q,[2,37],{19:20,20:21,21:22,43:23,29:49,30:61,32:62,13:131,22:e,23:n,24:a,26:i,28:s,34:r,36:l,37:o,38:h,39:d,40:u,41:p,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:L,68:Y,69:I,70:U,71:F,72:X,73:z,74:W}),t(q,[2,21]),t(q,[2,22]),t(J,[2,39]),t(Z,[2,71],{75:81,35:132,76:V,77:G,79:H,80:K}),t(tt,[2,73]),{78:[1,133]},t(tt,[2,75]),t(tt,[2,76]),t(J,[2,40]),t(J,[2,41]),t(J,[2,42]),t(J,[2,43]),t(J,[2,44]),t(J,[2,45]),t(J,[2,46]),t(J,[2,47]),t(J,[2,48]),t(J,[2,49]),t(J,[2,50]),t(J,[2,51]),t(J,[2,52]),t(J,[2,53]),t(J,[2,54]),t(J,[2,55]),t(J,[2,56]),t(J,[2,57]),t(J,[2,58]),t(J,[2,60]),t(J,[2,61]),t(J,[2,62]),t(J,[2,63]),t(J,[2,64]),t(J,[2,65]),t(J,[2,66]),t(J,[2,67]),t(J,[2,68]),t(J,[2,69]),t(J,[2,70]),{31:134,42:[1,135]},{12:[1,136]},{33:[1,137]},t(et,[2,28]),t(et,[2,29]),t(et,[2,30]),t(et,[2,31]),t(et,[2,32]),t(et,[2,33]),t(et,[2,34]),{1:[2,9]},{1:[2,10]},{1:[2,11]},{1:[2,12]},t($,[2,18]),t(Q,[2,38]),t(Z,[2,72]),t(tt,[2,74]),t(J,[2,24]),t(J,[2,35]),t(nt,[2,25]),t(nt,[2,26],{12:[1,138]}),t(nt,[2,27])],defaultActions:{2:[2,1],3:[2,2],4:[2,7],5:[2,3],6:[2,4],7:[2,5],8:[2,6],74:[2,8],126:[2,9],127:[2,10],128:[2,11],129:[2,12]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],a=[],i=[null],s=[],r=this.table,l="",o=0,c=0,h=s.slice.call(arguments,1),d=Object.create(this.lexer),u={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(u.yy[p]=this.yy[p]);d.setInput(t,u.yy),u.yy.lexer=d,u.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var y=d.yylloc;s.push(y);var f=d.options&&d.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var b,g,x,_,m,E,A,S,C,k={};;){if(g=n[n.length-1],this.defaultActions[g]?x=this.defaultActions[g]:(null==b&&(C=void 0,"number"!=typeof(C=a.pop()||d.lex()||1)&&(C instanceof Array&&(C=(a=C).pop()),C=e.symbols_[C]||C),b=C),x=r[g]&&r[g][b]),void 0===x||!x.length||!x[0]){var O="";for(m in S=[],r[g])this.terminals_[m]&&m>2&&S.push("'"+this.terminals_[m]+"'");O=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+S.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(O,{text:d.match,token:this.terminals_[b]||b,line:d.yylineno,loc:y,expected:S})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+b);switch(x[0]){case 1:n.push(b),i.push(d.yytext),s.push(d.yylloc),n.push(x[1]),b=null,c=d.yyleng,l=d.yytext,o=d.yylineno,y=d.yylloc;break;case 2:if(E=this.productions_[x[1]][1],k.$=i[i.length-E],k._$={first_line:s[s.length-(E||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(E||1)].first_column,last_column:s[s.length-1].last_column},f&&(k._$.range=[s[s.length-(E||1)].range[0],s[s.length-1].range[1]]),void 0!==(_=this.performAction.apply(k,[l,c,o,u.yy,x[1],i,s].concat(h))))return _;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),s=s.slice(0,-1*E)),n.push(this.productions_[x[1]][0]),i.push(k.$),s.push(k._$),A=r[n[n.length-2]][n[n.length-1]],n.push(A);break;case 3:return!0}}return!0}},it={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var a=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===a.length?this.yylloc.first_column:0)+a[a.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,a,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var s in i)this[s]=i[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),s=0;s<i.length;s++)if((n=this._input.match(this.rules[i[s]]))&&(!e||n[0].length>e[0].length)){if(e=n,a=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,a){switch(n){case 0:return 6;case 1:return 7;case 2:return 8;case 3:return 9;case 4:return 22;case 5:return 23;case 6:return this.begin("acc_title"),24;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),26;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 73:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:case 16:case 70:break;case 14:c;break;case 15:return 12;case 17:return 11;case 18:return 15;case 19:return 16;case 20:return 17;case 21:return 18;case 22:return this.begin("person_ext"),45;case 23:return this.begin("person"),44;case 24:return this.begin("system_ext_queue"),51;case 25:return this.begin("system_ext_db"),50;case 26:return this.begin("system_ext"),49;case 27:return this.begin("system_queue"),48;case 28:return this.begin("system_db"),47;case 29:return this.begin("system"),46;case 30:return this.begin("boundary"),37;case 31:return this.begin("enterprise_boundary"),34;case 32:return this.begin("system_boundary"),36;case 33:return this.begin("container_ext_queue"),57;case 34:return this.begin("container_ext_db"),56;case 35:return this.begin("container_ext"),55;case 36:return this.begin("container_queue"),54;case 37:return this.begin("container_db"),53;case 38:return this.begin("container"),52;case 39:return this.begin("container_boundary"),38;case 40:return this.begin("component_ext_queue"),63;case 41:return this.begin("component_ext_db"),62;case 42:return this.begin("component_ext"),61;case 43:return this.begin("component_queue"),60;case 44:return this.begin("component_db"),59;case 45:return this.begin("component"),58;case 46:case 47:return this.begin("node"),39;case 48:return this.begin("node_l"),40;case 49:return this.begin("node_r"),41;case 50:return this.begin("rel"),64;case 51:return this.begin("birel"),65;case 52:case 53:return this.begin("rel_u"),66;case 54:case 55:return this.begin("rel_d"),67;case 56:case 57:return this.begin("rel_l"),68;case 58:case 59:return this.begin("rel_r"),69;case 60:return this.begin("rel_b"),70;case 61:return this.begin("rel_index"),71;case 62:return this.begin("update_el_style"),72;case 63:return this.begin("update_rel_style"),73;case 64:return this.begin("update_layout_config"),74;case 65:return"EOF_IN_STRUCT";case 66:return this.begin("attribute"),"ATTRIBUTE_EMPTY";case 67:this.begin("attribute");break;case 68:case 79:this.popState(),this.popState();break;case 69:case 71:return 80;case 72:this.begin("string");break;case 74:case 80:return"STR";case 75:this.begin("string_kv");break;case 76:return this.begin("string_kv_key"),"STR_KEY";case 77:this.popState(),this.begin("string_kv_value");break;case 78:return"STR_VALUE";case 81:return"LBRACE";case 82:return"RBRACE";case 83:return"SPACE";case 84:return"EOL";case 85:return 14}},rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:title\s[^#\n;]+)/,/^(?:accDescription\s[^#\n;]+)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:C4Context\b)/,/^(?:C4Container\b)/,/^(?:C4Component\b)/,/^(?:C4Dynamic\b)/,/^(?:C4Deployment\b)/,/^(?:Person_Ext\b)/,/^(?:Person\b)/,/^(?:SystemQueue_Ext\b)/,/^(?:SystemDb_Ext\b)/,/^(?:System_Ext\b)/,/^(?:SystemQueue\b)/,/^(?:SystemDb\b)/,/^(?:System\b)/,/^(?:Boundary\b)/,/^(?:Enterprise_Boundary\b)/,/^(?:System_Boundary\b)/,/^(?:ContainerQueue_Ext\b)/,/^(?:ContainerDb_Ext\b)/,/^(?:Container_Ext\b)/,/^(?:ContainerQueue\b)/,/^(?:ContainerDb\b)/,/^(?:Container\b)/,/^(?:Container_Boundary\b)/,/^(?:ComponentQueue_Ext\b)/,/^(?:ComponentDb_Ext\b)/,/^(?:Component_Ext\b)/,/^(?:ComponentQueue\b)/,/^(?:ComponentDb\b)/,/^(?:Component\b)/,/^(?:Deployment_Node\b)/,/^(?:Node\b)/,/^(?:Node_L\b)/,/^(?:Node_R\b)/,/^(?:Rel\b)/,/^(?:BiRel\b)/,/^(?:Rel_Up\b)/,/^(?:Rel_U\b)/,/^(?:Rel_Down\b)/,/^(?:Rel_D\b)/,/^(?:Rel_Left\b)/,/^(?:Rel_L\b)/,/^(?:Rel_Right\b)/,/^(?:Rel_R\b)/,/^(?:Rel_Back\b)/,/^(?:RelIndex\b)/,/^(?:UpdateElementStyle\b)/,/^(?:UpdateRelStyle\b)/,/^(?:UpdateLayoutConfig\b)/,/^(?:$)/,/^(?:[(][ ]*[,])/,/^(?:[(])/,/^(?:[)])/,/^(?:,,)/,/^(?:,)/,/^(?:[ ]*["]["])/,/^(?:[ ]*["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[ ]*[\$])/,/^(?:[^=]*)/,/^(?:[=][ ]*["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:[^,]+)/,/^(?:\{)/,/^(?:\})/,/^(?:[\s]+)/,/^(?:[\n\r]+)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},string_kv_value:{rules:[78,79],inclusive:!1},string_kv_key:{rules:[77],inclusive:!1},string_kv:{rules:[76],inclusive:!1},string:{rules:[73,74],inclusive:!1},attribute:{rules:[68,69,70,71,72,75,80],inclusive:!1},update_layout_config:{rules:[65,66,67,68],inclusive:!1},update_rel_style:{rules:[65,66,67,68],inclusive:!1},update_el_style:{rules:[65,66,67,68],inclusive:!1},rel_b:{rules:[65,66,67,68],inclusive:!1},rel_r:{rules:[65,66,67,68],inclusive:!1},rel_l:{rules:[65,66,67,68],inclusive:!1},rel_d:{rules:[65,66,67,68],inclusive:!1},rel_u:{rules:[65,66,67,68],inclusive:!1},rel_bi:{rules:[],inclusive:!1},rel:{rules:[65,66,67,68],inclusive:!1},node_r:{rules:[65,66,67,68],inclusive:!1},node_l:{rules:[65,66,67,68],inclusive:!1},node:{rules:[65,66,67,68],inclusive:!1},index:{rules:[],inclusive:!1},rel_index:{rules:[65,66,67,68],inclusive:!1},component_ext_queue:{rules:[],inclusive:!1},component_ext_db:{rules:[65,66,67,68],inclusive:!1},component_ext:{rules:[65,66,67,68],inclusive:!1},component_queue:{rules:[65,66,67,68],inclusive:!1},component_db:{rules:[65,66,67,68],inclusive:!1},component:{rules:[65,66,67,68],inclusive:!1},container_boundary:{rules:[65,66,67,68],inclusive:!1},container_ext_queue:{rules:[65,66,67,68],inclusive:!1},container_ext_db:{rules:[65,66,67,68],inclusive:!1},container_ext:{rules:[65,66,67,68],inclusive:!1},container_queue:{rules:[65,66,67,68],inclusive:!1},container_db:{rules:[65,66,67,68],inclusive:!1},container:{rules:[65,66,67,68],inclusive:!1},birel:{rules:[65,66,67,68],inclusive:!1},system_boundary:{rules:[65,66,67,68],inclusive:!1},enterprise_boundary:{rules:[65,66,67,68],inclusive:!1},boundary:{rules:[65,66,67,68],inclusive:!1},system_ext_queue:{rules:[65,66,67,68],inclusive:!1},system_ext_db:{rules:[65,66,67,68],inclusive:!1},system_ext:{rules:[65,66,67,68],inclusive:!1},system_queue:{rules:[65,66,67,68],inclusive:!1},system_db:{rules:[65,66,67,68],inclusive:!1},system:{rules:[65,66,67,68],inclusive:!1},person_ext:{rules:[65,66,67,68],inclusive:!1},person:{rules:[65,66,67,68],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,81,82,83,84,85],inclusive:!0}}};function st(){this.yy={}}return at.lexer=it,st.prototype=at,at.Parser=st,new st}());l.parser=l;const o=l;let h=[],d=[""],u="global",p="",y=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],f=[],b="",g=!1,x=4,_=2;var m;const E=function(t){return null==t?h:h.filter((e=>e.parentBoundary===t))},A=function(t){return null==t?y:y.filter((e=>e.parentBoundary===t))},S=function(){return g},C={addPersonOrSystem:function(t,e,n,a,i,s,r){if(null===e||null===n)return;let l={};const o=h.find((t=>t.alias===e));if(o&&e===o.alias?l=o:(l.alias=e,h.push(l)),l.label=null==n?{text:""}:{text:n},null==a)l.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]={text:e}}else l.descr={text:a};if("object"==typeof i){let[t,e]=Object.entries(i)[0];l[t]=e}else l.sprite=i;if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=e}else l.tags=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=e}else l.link=r;l.typeC4Shape={text:t},l.parentBoundary=u,l.wrap=S()},addPersonOrSystemBoundary:function(t,e,n,a,i){if(null===t||null===e)return;let s={};const r=y.find((e=>e.alias===t));if(r&&t===r.alias?s=r:(s.alias=t,y.push(s)),s.label=null==e?{text:""}:{text:e},null==n)s.type={text:"system"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];s[t]={text:e}}else s.type={text:n};if("object"==typeof a){let[t,e]=Object.entries(a)[0];s[t]=e}else s.tags=a;if("object"==typeof i){let[t,e]=Object.entries(i)[0];s[t]=e}else s.link=i;s.parentBoundary=u,s.wrap=S(),p=u,u=t,d.push(p)},addContainer:function(t,e,n,a,i,s,r,l){if(null===e||null===n)return;let o={};const c=h.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,h.push(o)),o.label=null==n?{text:""}:{text:n},null==a)o.techn={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.techn={text:a};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.sprite=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=S(),o.typeC4Shape={text:t},o.parentBoundary=u},addContainerBoundary:function(t,e,n,a,i){if(null===t||null===e)return;let s={};const r=y.find((e=>e.alias===t));if(r&&t===r.alias?s=r:(s.alias=t,y.push(s)),s.label=null==e?{text:""}:{text:e},null==n)s.type={text:"container"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];s[t]={text:e}}else s.type={text:n};if("object"==typeof a){let[t,e]=Object.entries(a)[0];s[t]=e}else s.tags=a;if("object"==typeof i){let[t,e]=Object.entries(i)[0];s[t]=e}else s.link=i;s.parentBoundary=u,s.wrap=S(),p=u,u=t,d.push(p)},addComponent:function(t,e,n,a,i,s,r,l){if(null===e||null===n)return;let o={};const c=h.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,h.push(o)),o.label=null==n?{text:""}:{text:n},null==a)o.techn={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.techn={text:a};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.sprite=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=S(),o.typeC4Shape={text:t},o.parentBoundary=u},addDeploymentNode:function(t,e,n,a,i,s,r,l){if(null===e||null===n)return;let o={};const c=y.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,y.push(o)),o.label=null==n?{text:""}:{text:n},null==a)o.type={text:"node"};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.type={text:a};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.nodeType=t,o.parentBoundary=u,o.wrap=S(),p=u,u=e,d.push(p)},popBoundaryParseStack:function(){u=p,d.pop(),p=d.pop(),d.push(p)},addRel:function(t,e,n,a,i,s,r,l,o){if(null==t||null==e||null==n||null==a)return;let c={};const h=f.find((t=>t.from===e&&t.to===n));if(h?c=h:f.push(c),c.type=t,c.from=e,c.to=n,c.label={text:a},null==i)c.techn={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];c[t]={text:e}}else c.techn={text:i};if(null==s)c.descr={text:""};else if("object"==typeof s){let[t,e]=Object.entries(s)[0];c[t]={text:e}}else c.descr={text:s};if("object"==typeof r){let[t,e]=Object.entries(r)[0];c[t]=e}else c.sprite=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];c[t]=e}else c.tags=l;if("object"==typeof o){let[t,e]=Object.entries(o)[0];c[t]=e}else c.link=o;c.wrap=S()},updateElStyle:function(t,e,n,a,i,s,r,l,o,c,d){let u=h.find((t=>t.alias===e));if(void 0!==u||(u=y.find((t=>t.alias===e)),void 0!==u)){if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];u[t]=e}else u.bgColor=n;if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];u[t]=e}else u.fontColor=a;if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];u[t]=e}else u.borderColor=i;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];u[t]=e}else u.shadowing=s;if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];u[t]=e}else u.shape=r;if(null!=l)if("object"==typeof l){let[t,e]=Object.entries(l)[0];u[t]=e}else u.sprite=l;if(null!=o)if("object"==typeof o){let[t,e]=Object.entries(o)[0];u[t]=e}else u.techn=o;if(null!=c)if("object"==typeof c){let[t,e]=Object.entries(c)[0];u[t]=e}else u.legendText=c;if(null!=d)if("object"==typeof d){let[t,e]=Object.entries(d)[0];u[t]=e}else u.legendSprite=d}},updateRelStyle:function(t,e,n,a,i,s,r){const l=f.find((t=>t.from===e&&t.to===n));if(void 0!==l){if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]=e}else l.textColor=a;if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];l[t]=e}else l.lineColor=i;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=parseInt(e)}else l.offsetX=parseInt(s);if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=parseInt(e)}else l.offsetY=parseInt(r)}},updateLayoutConfig:function(t,e,n){let a=x,i=_;if("object"==typeof e){const t=Object.values(e)[0];a=parseInt(t)}else a=parseInt(e);if("object"==typeof n){const t=Object.values(n)[0];i=parseInt(t)}else i=parseInt(n);a>=1&&(x=a),i>=1&&(_=i)},autoWrap:S,setWrap:function(t){g=t},getC4ShapeArray:E,getC4Shape:function(t){return h.find((e=>e.alias===t))},getC4ShapeKeys:function(t){return Object.keys(E(t))},getBoundaries:A,getBoundarys:A,getCurrentBoundaryParse:function(){return u},getParentBoundaryParse:function(){return p},getRels:function(){return f},getTitle:function(){return b},getC4Type:function(){return m},getC4ShapeInRow:function(){return x},getC4BoundaryInRow:function(){return _},setAccTitle:a.s,getAccTitle:a.g,getAccDescription:a.a,setAccDescription:a.b,getConfig:()=>(0,a.c)().c4,clear:function(){h=[],y=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],p="",u="global",d=[""],f=[],d=[""],b="",g=!1,x=4,_=2},LINETYPE:{SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25},ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},setTitle:function(t){let e=(0,a.d)(t,(0,a.c)());b=e},setC4Type:function(t){let e=(0,a.d)(t,(0,a.c)());m=e}},k=function(t,e){return(0,s.d)(t,e)},O=function(t,e,n,a,i,s){const l=t.append("image");l.attr("width",e),l.attr("height",n),l.attr("x",a),l.attr("y",i);let o=s.startsWith("data:image/png;base64")?s:(0,r.Jf)(s);l.attr("xlink:href",o)},v=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),T=function(){function t(t,e,n,a,s,r,l){i(e.append("text").attr("x",n+s/2).attr("y",a+r/2+5).style("text-anchor","middle").text(t),l)}function e(t,e,n,s,r,l,o,c){const{fontSize:h,fontFamily:d,fontWeight:u}=c,p=t.split(a.e.lineBreakRegex);for(let a=0;a<p.length;a++){const t=a*h-h*(p.length-1)/2,l=e.append("text").attr("x",n+r/2).attr("y",s).style("text-anchor","middle").attr("dominant-baseline","middle").style("font-size",h).style("font-weight",u).style("font-family",d);l.append("tspan").attr("dy",t).text(p[a]).attr("alignment-baseline","mathematical"),i(l,o)}}function n(t,n,a,s,r,l,o,c){const h=n.append("switch"),d=h.append("foreignObject").attr("x",a).attr("y",s).attr("width",r).attr("height",l).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");d.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,a,s,r,0,o,c),i(d,o)}function i(t,e){for(const n in e)e.hasOwnProperty(n)&&t.attr(n,e[n])}return function(a){return"fo"===a.textPlacement?n:"old"===a.textPlacement?t:e}}(),w=function(t,e,n){const a=t.append("g");let i=e.bgColor?e.bgColor:"none",s=e.borderColor?e.borderColor:"#444444",r=e.fontColor?e.fontColor:"black",l={"stroke-width":1,"stroke-dasharray":"7.0,7.0"};e.nodeType&&(l={"stroke-width":1});let o={x:e.x,y:e.y,fill:i,stroke:s,width:e.width,height:e.height,rx:2.5,ry:2.5,attrs:l};k(a,o);let c=n.boundaryFont();c.fontWeight="bold",c.fontSize=c.fontSize+2,c.fontColor=r,T(n)(e.label.text,a,e.x,e.y+e.label.Y,e.width,e.height,{fill:"#444444"},c),e.type&&""!==e.type.text&&(c=n.boundaryFont(),c.fontColor=r,T(n)(e.type.text,a,e.x,e.y+e.type.Y,e.width,e.height,{fill:"#444444"},c)),e.descr&&""!==e.descr.text&&(c=n.boundaryFont(),c.fontSize=c.fontSize-2,c.fontColor=r,T(n)(e.descr.text,a,e.x,e.y+e.descr.Y,e.width,e.height,{fill:"#444444"},c))},R=function(t,e,n){var a;let i=e.bgColor?e.bgColor:n[e.typeC4Shape.text+"_bg_color"],r=e.borderColor?e.borderColor:n[e.typeC4Shape.text+"_border_color"],l=e.fontColor?e.fontColor:"#FFFFFF",o="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";switch(e.typeC4Shape.text){case"person":o="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";break;case"external_person":o="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAB6ElEQVR4Xu2YLY+EMBCG9+dWr0aj0Wg0Go1Go0+j8Xdv2uTCvv1gpt0ebHKPuhDaeW4605Z9mJvx4AdXUyTUdd08z+u6flmWZRnHsWkafk9DptAwDPu+f0eAYtu2PEaGWuj5fCIZrBAC2eLBAnRCsEkkxmeaJp7iDJ2QMDdHsLg8SxKFEJaAo8lAXnmuOFIhTMpxxKATebo4UiFknuNo4OniSIXQyRxEA3YsnjGCVEjVXD7yLUAqxBGUyPv/Y4W2beMgGuS7kVQIBycH0fD+oi5pezQETxdHKmQKGk1eQEYldK+jw5GxPfZ9z7Mk0Qnhf1W1m3w//EUn5BDmSZsbR44QQLBEqrBHqOrmSKaQAxdnLArCrxZcM7A7ZKs4ioRq8LFC+NpC3WCBJsvpVw5edm9iEXFuyNfxXAgSwfrFQ1c0iNda8AdejvUgnktOtJQQxmcfFzGglc5WVCj7oDgFqU18boeFSs52CUh8LE8BIVQDT1ABrB0HtgSEYlX5doJnCwv9TXocKCaKbnwhdDKPq4lf3SwU3HLq4V/+WYhHVMa/3b4IlfyikAduCkcBc7mQ3/z/Qq/cTuikhkzB12Ae/mcJC9U+Vo8Ej1gWAtgbeGgFsAMHr50BIWOLCbezvhpBFUdY6EJuJ/QDW0XoMX60zZ0AAAAASUVORK5CYII="}const c=t.append("g");c.attr("class","person-man");const h=(0,s.g)();switch(e.typeC4Shape.text){case"person":case"external_person":case"system":case"external_system":case"container":case"external_container":case"component":case"external_component":h.x=e.x,h.y=e.y,h.fill=i,h.width=e.width,h.height=e.height,h.stroke=r,h.rx=2.5,h.ry=2.5,h.attrs={"stroke-width":.5},k(c,h);break;case"system_db":case"external_system_db":case"container_db":case"external_container_db":case"component_db":case"external_component_db":c.append("path").attr("fill",i).attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc0,-10 half,-10 half,-10c0,0 half,0 half,10l0,heightc0,10 -half,10 -half,10c0,0 -half,0 -half,-10l0,-height".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2).replaceAll("height",e.height)),c.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc0,10 half,10 half,10c0,0 half,0 half,-10".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2));break;case"system_queue":case"external_system_queue":case"container_queue":case"external_container_queue":case"component_queue":case"external_component_queue":c.append("path").attr("fill",i).attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startylwidth,0c5,0 5,half 5,halfc0,0 0,half -5,halfl-width,0c-5,0 -5,-half -5,-halfc0,0 0,-half 5,-half".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("width",e.width).replaceAll("half",e.height/2)),c.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc-5,0 -5,half -5,halfc0,half 5,half 5,half".replaceAll("startx",e.x+e.width).replaceAll("starty",e.y).replaceAll("half",e.height/2))}let d=v(n,e.typeC4Shape.text);switch(c.append("text").attr("fill",l).attr("font-family",d.fontFamily).attr("font-size",d.fontSize-2).attr("font-style","italic").attr("lengthAdjust","spacing").attr("textLength",e.typeC4Shape.width).attr("x",e.x+e.width/2-e.typeC4Shape.width/2).attr("y",e.y+e.typeC4Shape.Y).text("<<"+e.typeC4Shape.text+">>"),e.typeC4Shape.text){case"person":case"external_person":O(c,48,48,e.x+e.width/2-24,e.y+e.image.Y,o)}let u=n[e.typeC4Shape.text+"Font"]();return u.fontWeight="bold",u.fontSize=u.fontSize+2,u.fontColor=l,T(n)(e.label.text,c,e.x,e.y+e.label.Y,e.width,e.height,{fill:l},u),u=n[e.typeC4Shape.text+"Font"](),u.fontColor=l,e.techn&&""!==(null==(a=e.techn)?void 0:a.text)?T(n)(e.techn.text,c,e.x,e.y+e.techn.Y,e.width,e.height,{fill:l,"font-style":"italic"},u):e.type&&""!==e.type.text&&T(n)(e.type.text,c,e.x,e.y+e.type.Y,e.width,e.height,{fill:l,"font-style":"italic"},u),e.descr&&""!==e.descr.text&&(u=n.personFont(),u.fontColor=l,T(n)(e.descr.text,c,e.x,e.y+e.descr.Y,e.width,e.height,{fill:l},u)),e.height},D=(t,e,n)=>{const a=t.append("g");let i=0;for(let s of e){let t=s.textColor?s.textColor:"#444444",e=s.lineColor?s.lineColor:"#444444",r=s.offsetX?parseInt(s.offsetX):0,l=s.offsetY?parseInt(s.offsetY):0,o="";if(0===i){let t=a.append("line");t.attr("x1",s.startPoint.x),t.attr("y1",s.startPoint.y),t.attr("x2",s.endPoint.x),t.attr("y2",s.endPoint.y),t.attr("stroke-width","1"),t.attr("stroke",e),t.style("fill","none"),"rel_b"!==s.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==s.type&&"rel_b"!==s.type||t.attr("marker-start","url("+o+"#arrowend)"),i=-1}else{let t=a.append("path");t.attr("fill","none").attr("stroke-width","1").attr("stroke",e).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",s.startPoint.x).replaceAll("starty",s.startPoint.y).replaceAll("controlx",s.startPoint.x+(s.endPoint.x-s.startPoint.x)/2-(s.endPoint.x-s.startPoint.x)/4).replaceAll("controly",s.startPoint.y+(s.endPoint.y-s.startPoint.y)/2).replaceAll("stopx",s.endPoint.x).replaceAll("stopy",s.endPoint.y)),"rel_b"!==s.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==s.type&&"rel_b"!==s.type||t.attr("marker-start","url("+o+"#arrowend)")}let c=n.messageFont();T(n)(s.label.text,a,Math.min(s.startPoint.x,s.endPoint.x)+Math.abs(s.endPoint.x-s.startPoint.x)/2+r,Math.min(s.startPoint.y,s.endPoint.y)+Math.abs(s.endPoint.y-s.startPoint.y)/2+l,s.label.width,s.label.height,{fill:t},c),s.techn&&""!==s.techn.text&&(c=n.messageFont(),T(n)("["+s.techn.text+"]",a,Math.min(s.startPoint.x,s.endPoint.x)+Math.abs(s.endPoint.x-s.startPoint.x)/2+r,Math.min(s.startPoint.y,s.endPoint.y)+Math.abs(s.endPoint.y-s.startPoint.y)/2+n.messageFontSize+5+l,Math.max(s.label.width,s.techn.width),s.techn.height,{fill:t,"font-style":"italic"},c))}},N=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},P=function(t){t.append("defs").append("marker").attr("id","arrowend").attr("refX",1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z")},M=function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},j=function(t){const e=t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);e.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),e.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")},B=function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},L=function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},Y=function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")};let I=0,U=0,F=4,X=2;l.yy=C;let z={};class W{constructor(t){this.name="",this.data={},this.data.startx=void 0,this.data.stopx=void 0,this.data.starty=void 0,this.data.stopy=void 0,this.data.widthLimit=void 0,this.nextData={},this.nextData.startx=void 0,this.nextData.stopx=void 0,this.nextData.starty=void 0,this.nextData.stopy=void 0,this.nextData.cnt=0,Q(t.db.getConfig())}setData(t,e,n,a){this.nextData.startx=this.data.startx=t,this.nextData.stopx=this.data.stopx=e,this.nextData.starty=this.data.starty=n,this.nextData.stopy=this.data.stopy=a}updateVal(t,e,n,a){void 0===t[e]?t[e]=n:t[e]=a(n,t[e])}insert(t){this.nextData.cnt=this.nextData.cnt+1;let e=this.nextData.startx===this.nextData.stopx?this.nextData.stopx+t.margin:this.nextData.stopx+2*t.margin,n=e+t.width,a=this.nextData.starty+2*t.margin,i=a+t.height;(e>=this.data.widthLimit||n>=this.data.widthLimit||this.nextData.cnt>F)&&(e=this.nextData.startx+t.margin+z.nextLinePaddingX,a=this.nextData.stopy+2*t.margin,this.nextData.stopx=n=e+t.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=i=a+t.height,this.nextData.cnt=1),t.x=e,t.y=a,this.updateVal(this.data,"startx",e,Math.min),this.updateVal(this.data,"starty",a,Math.min),this.updateVal(this.data,"stopx",n,Math.max),this.updateVal(this.data,"stopy",i,Math.max),this.updateVal(this.nextData,"startx",e,Math.min),this.updateVal(this.nextData,"starty",a,Math.min),this.updateVal(this.nextData,"stopx",n,Math.max),this.updateVal(this.nextData,"stopy",i,Math.max)}init(t){this.name="",this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,widthLimit:void 0},this.nextData={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,cnt:0},Q(t.db.getConfig())}bumpLastMargin(t){this.data.stopx+=t,this.data.stopy+=t}}const Q=function(t){(0,a.f)(z,t),t.fontFamily&&(z.personFontFamily=z.systemFontFamily=z.messageFontFamily=t.fontFamily),t.fontSize&&(z.personFontSize=z.systemFontSize=z.messageFontSize=t.fontSize),t.fontWeight&&(z.personFontWeight=z.systemFontWeight=z.messageFontWeight=t.fontWeight)},$=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),q=t=>({fontFamily:t.boundaryFontFamily,fontSize:t.boundaryFontSize,fontWeight:t.boundaryFontWeight});function V(t,e,n,i,s){if(!e[t].width)if(n)e[t].text=(0,a.w)(e[t].text,s,i),e[t].textLines=e[t].text.split(a.e.lineBreakRegex).length,e[t].width=s,e[t].height=(0,a.j)(e[t].text,i);else{let n=e[t].text.split(a.e.lineBreakRegex);e[t].textLines=n.length;let s=0;e[t].height=0,e[t].width=0;for(const r of n)e[t].width=Math.max((0,a.h)(r,i),e[t].width),s=(0,a.j)(r,i),e[t].height=e[t].height+s}}const G=function(t,e,n){e.x=n.data.startx,e.y=n.data.starty,e.width=n.data.stopx-n.data.startx,e.height=n.data.stopy-n.data.starty,e.label.y=z.c4ShapeMargin-35;let i=e.wrap&&z.wrap,s=q(z);s.fontSize=s.fontSize+2,s.fontWeight="bold",V("label",e,i,s,(0,a.h)(e.label.text,s)),w(t,e,z)},H=function(t,e,n,i){let s=0;for(const r of i){s=0;const i=n[r];let l=$(z,i.typeC4Shape.text);switch(l.fontSize=l.fontSize-2,i.typeC4Shape.width=(0,a.h)("\xab"+i.typeC4Shape.text+"\xbb",l),i.typeC4Shape.height=l.fontSize+2,i.typeC4Shape.Y=z.c4ShapePadding,s=i.typeC4Shape.Y+i.typeC4Shape.height-4,i.image={width:0,height:0,Y:0},i.typeC4Shape.text){case"person":case"external_person":i.image.width=48,i.image.height=48,i.image.Y=s,s=i.image.Y+i.image.height}i.sprite&&(i.image.width=48,i.image.height=48,i.image.Y=s,s=i.image.Y+i.image.height);let o=i.wrap&&z.wrap,c=z.width-2*z.c4ShapePadding,h=$(z,i.typeC4Shape.text);if(h.fontSize=h.fontSize+2,h.fontWeight="bold",V("label",i,o,h,c),i.label.Y=s+8,s=i.label.Y+i.label.height,i.type&&""!==i.type.text){i.type.text="["+i.type.text+"]",V("type",i,o,$(z,i.typeC4Shape.text),c),i.type.Y=s+5,s=i.type.Y+i.type.height}else if(i.techn&&""!==i.techn.text){i.techn.text="["+i.techn.text+"]",V("techn",i,o,$(z,i.techn.text),c),i.techn.Y=s+5,s=i.techn.Y+i.techn.height}let d=s,u=i.label.width;if(i.descr&&""!==i.descr.text){V("descr",i,o,$(z,i.typeC4Shape.text),c),i.descr.Y=s+20,s=i.descr.Y+i.descr.height,u=Math.max(i.label.width,i.descr.width),d=s-5*i.descr.textLines}u+=z.c4ShapePadding,i.width=Math.max(i.width||z.width,u,z.width),i.height=Math.max(i.height||z.height,d,z.height),i.margin=i.margin||z.c4ShapeMargin,t.insert(i),R(e,i,z)}t.bumpLastMargin(z.c4ShapeMargin)};class K{constructor(t,e){this.x=t,this.y=e}}let J=function(t,e){let n=t.x,a=t.y,i=e.x,s=e.y,r=n+t.width/2,l=a+t.height/2,o=Math.abs(n-i),c=Math.abs(a-s),h=c/o,d=t.height/t.width,u=null;return a==s&&n<i?u=new K(n+t.width,l):a==s&&n>i?u=new K(n,l):n==i&&a<s?u=new K(r,a+t.height):n==i&&a>s&&(u=new K(r,a)),n>i&&a<s?u=d>=h?new K(n,l+h*t.width/2):new K(r-o/c*t.height/2,a+t.height):n<i&&a<s?u=d>=h?new K(n+t.width,l+h*t.width/2):new K(r+o/c*t.height/2,a+t.height):n<i&&a>s?u=d>=h?new K(n+t.width,l-h*t.width/2):new K(r+t.height/2*o/c,a):n>i&&a>s&&(u=d>=h?new K(n,l-t.width/2*h):new K(r-t.height/2*o/c,a)),u},Z=function(t,e){let n={x:0,y:0};n.x=e.x+e.width/2,n.y=e.y+e.height/2;let a=J(t,n);return n.x=t.x+t.width/2,n.y=t.y+t.height/2,{startPoint:a,endPoint:J(e,n)}};function tt(t,e,n,a,i){let s=new W(i);s.data.widthLimit=n.data.widthLimit/Math.min(X,a.length);for(let[r,l]of a.entries()){let a=0;l.image={width:0,height:0,Y:0},l.sprite&&(l.image.width=48,l.image.height=48,l.image.Y=a,a=l.image.Y+l.image.height);let o=l.wrap&&z.wrap,c=q(z);if(c.fontSize=c.fontSize+2,c.fontWeight="bold",V("label",l,o,c,s.data.widthLimit),l.label.Y=a+8,a=l.label.Y+l.label.height,l.type&&""!==l.type.text){l.type.text="["+l.type.text+"]",V("type",l,o,q(z),s.data.widthLimit),l.type.Y=a+5,a=l.type.Y+l.type.height}if(l.descr&&""!==l.descr.text){let t=q(z);t.fontSize=t.fontSize-2,V("descr",l,o,t,s.data.widthLimit),l.descr.Y=a+20,a=l.descr.Y+l.descr.height}if(0==r||r%X==0){let t=n.data.startx+z.diagramMarginX,e=n.data.stopy+z.diagramMarginY+a;s.setData(t,t,e,e)}else{let t=s.data.stopx!==s.data.startx?s.data.stopx+z.diagramMarginX:s.data.startx,e=s.data.starty;s.setData(t,t,e,e)}s.name=l.alias;let h=i.db.getC4ShapeArray(l.alias),d=i.db.getC4ShapeKeys(l.alias);d.length>0&&H(s,t,h,d),e=l.alias;let u=i.db.getBoundarys(e);u.length>0&&tt(t,e,s,u,i),"global"!==l.alias&&G(t,l,s),n.data.stopy=Math.max(s.data.stopy+z.c4ShapeMargin,n.data.stopy),n.data.stopx=Math.max(s.data.stopx+z.c4ShapeMargin,n.data.stopx),I=Math.max(I,n.data.stopx),U=Math.max(U,n.data.stopy)}}const et={drawPersonOrSystemArray:H,drawBoundary:G,setConf:Q,draw:function(t,e,n,s){z=(0,a.c)().c4;const r=(0,a.c)().securityLevel;let l;"sandbox"===r&&(l=(0,i.Ltv)("#i"+e));const o="sandbox"===r?(0,i.Ltv)(l.nodes()[0].contentDocument.body):(0,i.Ltv)("body");let c=s.db;s.db.setWrap(z.wrap),F=c.getC4ShapeInRow(),X=c.getC4BoundaryInRow(),a.l.debug(`C:${JSON.stringify(z,null,2)}`);const h="sandbox"===r?o.select(`[id="${e}"]`):(0,i.Ltv)(`[id="${e}"]`);L(h),B(h),Y(h);let d=new W(s);d.setData(z.diagramMarginX,z.diagramMarginX,z.diagramMarginY,z.diagramMarginY),d.data.widthLimit=screen.availWidth,I=z.diagramMarginX,U=z.diagramMarginY;const u=s.db.getTitle();tt(h,"",d,s.db.getBoundarys(""),s),N(h),P(h),j(h),M(h),function(t,e,n,i){let s=0;for(let l of e){s+=1;let t=l.wrap&&z.wrap,e={fontFamily:(r=z).messageFontFamily,fontSize:r.messageFontSize,fontWeight:r.messageFontWeight};"C4Dynamic"===i.db.getC4Type()&&(l.label.text=s+": "+l.label.text);let o=(0,a.h)(l.label.text,e);V("label",l,t,e,o),l.techn&&""!==l.techn.text&&(o=(0,a.h)(l.techn.text,e),V("techn",l,t,e,o)),l.descr&&""!==l.descr.text&&(o=(0,a.h)(l.descr.text,e),V("descr",l,t,e,o));let c=n(l.from),h=n(l.to),d=Z(c,h);l.startPoint=d.startPoint,l.endPoint=d.endPoint}var r;D(t,e,z)}(h,s.db.getRels(),s.db.getC4Shape,s),d.data.stopx=I,d.data.stopy=U;const p=d.data;let y=p.stopy-p.starty+2*z.diagramMarginY;const f=p.stopx-p.startx+2*z.diagramMarginX;u&&h.append("text").text(u).attr("x",(p.stopx-p.startx)/2-4*z.diagramMarginX).attr("y",p.starty+z.diagramMarginY),(0,a.i)(h,y,f,z.useMaxWidth);const b=u?60:0;h.attr("viewBox",p.startx-z.diagramMarginX+" -"+(z.diagramMarginY+b)+" "+f+" "+(y+b)),a.l.debug("models:",p)}},nt={parser:o,db:C,renderer:et,styles:t=>`.person {\n stroke: ${t.personBorder};\n fill: ${t.personBkg};\n }\n`,init:({c4:t,wrap:e})=>{et.setConf(t),C.setWrap(e)}}},58886:(t,e,n)=>{n.d(e,{a:()=>r,b:()=>c,c:()=>o,d:()=>s,e:()=>d,f:()=>l,g:()=>h});var a=n(16750),i=n(76257);const s=(t,e)=>{const n=t.append("rect");if(n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),e.name&&n.attr("name",e.name),void 0!==e.rx&&n.attr("rx",e.rx),void 0!==e.ry&&n.attr("ry",e.ry),void 0!==e.attrs)for(const a in e.attrs)n.attr(a,e.attrs[a]);return void 0!==e.class&&n.attr("class",e.class),n},r=(t,e)=>{const n={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};s(t,n).lower()},l=(t,e)=>{const n=e.text.replace(i.J," "),a=t.append("text");a.attr("x",e.x),a.attr("y",e.y),a.attr("class","legend"),a.style("text-anchor",e.anchor),void 0!==e.class&&a.attr("class",e.class);const s=a.append("tspan");return s.attr("x",e.x+2*e.textMargin),s.text(n),a},o=(t,e,n,i)=>{const s=t.append("image");s.attr("x",e),s.attr("y",n);const r=(0,a.Jf)(i);s.attr("xlink:href",r)},c=(t,e,n,i)=>{const s=t.append("use");s.attr("x",e),s.attr("y",n);const r=(0,a.Jf)(i);s.attr("xlink:href",`#${r}`)},h=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),d=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})}}]); \ No newline at end of file diff --git a/assets/js/38b583d2.7eb273cc.js b/assets/js/38b583d2.7eb273cc.js new file mode 100644 index 0000000000..1bb69b0b01 --- /dev/null +++ b/assets/js/38b583d2.7eb273cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3012],{50510:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"SCS k8s-cluster-api-provider upgrade guide",version:new Date("2023-09-07T00:00:00.000Z"),authors:"Kurt Garloff, Roman Hros, Matej Feder",state:"Draft (v0.7)"},l=void 0,o={id:"container/components/k8s-cluster-api-provider/doc/Upgrade-Guide",title:"SCS k8s-cluster-api-provider upgrade guide",description:"SCS k8s-cluster-api-provider upgrade guide",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/Upgrade-Guide.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc",slug:"/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/Upgrade-Guide.md",tags:[],version:"current",frontMatter:{title:"SCS k8s-cluster-api-provider upgrade guide",version:"2023-09-07T00:00:00.000Z",authors:"Kurt Garloff, Roman Hros, Matej Feder",state:"Draft (v0.7)"},sidebar:"docs",previous:{title:"Ingress with externalTrafficPolicy: local",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal"},next:{title:"Continuous integration",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration"}},a={},c=[{value:"SCS k8s-cluster-api-provider upgrade guide",id:"scs-k8s-cluster-api-provider-upgrade-guide",level:2},{value:"Management host (cluster) vs. Workload clusters",id:"management-host-cluster-vs-workload-clusters",level:2},{value:"Updating the management host",id:"updating-the-management-host",level:2},{value:"In-place upgrade",id:"in-place-upgrade",level:3},{value:"Operating system",id:"operating-system",level:4},{value:"k8s-cluster-api-provider git",id:"k8s-cluster-api-provider-git",level:4},{value:"Updating cluster-API and openstack cluster-API provider",id:"updating-cluster-api-and-openstack-cluster-api-provider",level:4},{value:"New templates",id:"new-templates",level:4},{value:"R2 to R3",id:"r2-to-r3",level:5},{value:"R3 to R4",id:"r3-to-r4",level:5},{value:"R4 to R5",id:"r4-to-r5",level:5},{value:"R5 to R6",id:"r5-to-r6",level:5},{value:"New defaults",id:"new-defaults",level:4},{value:"The clusterctl move approach",id:"the-clusterctl-move-approach",level:3},{value:"Updating workload clusters",id:"updating-workload-clusters",level:2},{value:"k8s version upgrade",id:"k8s-version-upgrade",level:3},{value:"On R2 clusters",id:"on-r2-clusters",level:4},{value:"On R3 and R4 clusters",id:"on-r3-and-r4-clusters",level:4},{value:"On R5 clusters",id:"on-r5-clusters",level:4},{value:"On R6 clusters",id:"on-r6-clusters",level:4},{value:"New versions for mandatory components",id:"new-versions-for-mandatory-components",level:3},{value:"New versions for optional components",id:"new-versions-for-optional-components",level:3},{value:"etcd leader changes",id:"etcd-leader-changes",level:3}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"scs-k8s-cluster-api-provider-upgrade-guide",children:"SCS k8s-cluster-api-provider upgrade guide"}),"\n",(0,t.jsx)(n.p,{children:"This document explains the steps to upgrade the SCS Kubernetes cluster-API\nbased cluster management solution as follows:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"from the R2 (2022-03) to the R3 (2022-09) state"}),"\n",(0,t.jsx)(n.li,{children:"from the R3 (2022-09) to the R4 (2023-03) state"}),"\n",(0,t.jsx)(n.li,{children:"from the R4 (2023-03) to the R5 (2023-09) state"}),"\n",(0,t.jsx)(n.li,{children:"from the R5 (2023-09) to the R6 (2024-03) state"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The document explains how the management cluster and the workload clusters can be\nupgraded without disruption. It is highly recommended to do a step-by-step upgrade\nacross major releases i.e. upgrade from R2 to R3 and then to R4 in the case of\nupgrade from the R2 to the R4. Upgrades across major releases without step-by-step\nprocess is not recommended and could lead to undocumented issues."}),"\n",(0,t.jsx)(n.p,{children:"The various steps are not very complicated, but there are numerous steps to\ntake, and it is advisable that cluster operators get some experience with\nthis kind of cluster management before applying this to customer clusters\nthat carry important workloads."}),"\n",(0,t.jsx)(n.p,{children:"Note that while the detailed steps are tested and targeted to an R2 -> R3 move,\nR3 -> R4 move, R4 -> R5 move or R5 -> R6 move, many of the steps are a generic approach that will apply also for other\nupgrades, so expect a lot of similar steps when moving beyond R6."}),"\n",(0,t.jsxs)(n.p,{children:["Upgrades from cluster management prior to R2 are difficult; many changes before\nR2 assumed that you would redeploy the management cluster. Redeploying the\nmanagement cluster can of course always be done, but it's typically disruptive\nto your workload clusters, unless you move your cluster management state into\na new management cluster with ",(0,t.jsx)(n.code,{children:"clusterctl move"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"management-host-cluster-vs-workload-clusters",children:"Management host (cluster) vs. Workload clusters"}),"\n",(0,t.jsxs)(n.p,{children:["When you initially deployed the SCS k8s-cluster-api-provider, you created a\nVM with a ",(0,t.jsx)(n.a,{href:"https://kind.sigs.k8s.io/",children:"kind"})," cluster inside and a number of\ntemplates, scripts and binaries that are then used to do the cluster management.\nThis is your management host (or more precisely your single-host management\ncluster). Currently, all cluster management including upgrading etc. is done\nby connecting to this host via ssh and performing commands there. (You don't\nneed root privileges to do cluster management there, the normal ubuntu user\nrights are sufficient; there are obviously host management tasks such as\ninstalling package updates that do require root power and the user has the\nsudo rights to do so.)"]}),"\n",(0,t.jsxs)(n.p,{children:["When you create the management host, you have the option to create your\nfirst workload cluster. This cluster is no different from other workload\nclusters that you create by calling commands on the management host, so you\ncan manage it there. (The default name of this cluster is typically\n",(0,t.jsx)(n.code,{children:"testcluster"}),", though that can be changed since a while, #264)."]}),"\n",(0,t.jsxs)(n.p,{children:["On the management host, you have the openstack and kubernetes tools\ninstalled and configured, so you can nicely manage all aspects of your\nCaaS setups as well as the underlying IaaS. The kubectl configuration\nis in ",(0,t.jsx)(n.code,{children:"~/.kube/config"})," while you will find the OpenStack configuration\nin ",(0,t.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"}),". These files are automatically\nmanaged; you can add entries to the files though, and they should\npersist."]}),"\n",(0,t.jsx)(n.h2,{id:"updating-the-management-host",children:"Updating the management host"}),"\n",(0,t.jsx)(n.p,{children:"There are two different possibilities to upgrade the management host."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"You do a component-wise in-place upgrade of it."}),"\n",(0,t.jsxs)(n.li,{children:["You deploy a new management host and ",(0,t.jsx)(n.code,{children:"clusterctl move"})," the resources\nover to it from the old one. (Note: Config state in ",(0,t.jsx)(n.code,{children:"~/CLUSTER_NAME/"}),")"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"TODO: Advice when to do what, risks, limitations"}),"\n",(0,t.jsx)(n.h3,{id:"in-place-upgrade",children:"In-place upgrade"}),"\n",(0,t.jsx)(n.h4,{id:"operating-system",children:"Operating system"}),"\n",(0,t.jsxs)(n.p,{children:["You should keep the host up-to-date with respect to normal operating system\nupgrades, so perform your normal ",(0,t.jsx)(n.code,{children:"sudo apt-get update && sudo apt-get upgrade"}),".\n",(0,t.jsx)(n.code,{children:"kubectl"}),", ",(0,t.jsx)(n.code,{children:"kustomize"}),", ",(0,t.jsx)(n.code,{children:"yq"}),", ",(0,t.jsx)(n.code,{children:"lxd"})," and a few other tools are installed as\nsnaps, so you may want to upgrade these as well: ",(0,t.jsx)(n.code,{children:"sudo snap refresh"}),".\nFrom R5 ",(0,t.jsx)(n.code,{children:"sudo apt-get install -y jq"})," is also required as this is used by the diskless flavors feature, #424.\nDefault operating system image was changed from Ubuntu 20.04 to Ubuntu 22.04 in R4."]}),"\n",(0,t.jsx)(n.h4,{id:"k8s-cluster-api-provider-git",children:"k8s-cluster-api-provider git"}),"\n",(0,t.jsxs)(n.p,{children:["The automation is deployed on the management host by cloning ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"the relevant\ngit repository"}),".\ninto the ",(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider"})," directory. Note that the checked out\nbranch will be the one that has been used when creating the management host,\nand you might want to change branches from ",(0,t.jsx)(n.code,{children:"maintained/v3.x"})," to ",(0,t.jsx)(n.code,{children:"maintained/v4.x"}),"\nin case of R2 to R3 upgrade, ",(0,t.jsx)(n.code,{children:"maintained/v5.x"})," for R3 to R4 upgrade, ",(0,t.jsx)(n.code,{children:"maintained/v6.x"}),"\nfor R4 to R5 upgrade or ",(0,t.jsx)(n.code,{children:"maintained/v7.x"})," for R5 to R6 upgrade.\nUse ",(0,t.jsx)(n.code,{children:"git branch -rl"})," to see available branches in the k8s-cluster-api-provider\nrepository."]}),"\n",(0,t.jsxs)(n.p,{children:["You can update the scripts and templates by checking out the relevant branch\n",(0,t.jsx)(n.code,{children:"main"}),", ",(0,t.jsx)(n.code,{children:"maintained/v4.x"}),", ",(0,t.jsx)(n.code,{children:"maintained/v5.x"}),", ",(0,t.jsx)(n.code,{children:"maintained/v6.x"})," or ",(0,t.jsx)(n.code,{children:"maintained/v7.x"}),"\nand using a ",(0,t.jsx)(n.code,{children:"git pull"})," to ensure the latest content is retrieved.\nOnce you do that, the cluster-management scripts will be up-to-date.\n(The ",(0,t.jsx)(n.code,{children:"~/bin"})," directory in your search ",(0,t.jsx)(n.code,{children:"PATH"})," is symlinked to the check-ed out scripts.)"]}),"\n",(0,t.jsx)(n.p,{children:"Note however that the binaries and used templates are NOT automatically updated.\nThis should not normally result in problems -- when new features are introduced\nin the management scripts, they ensure to continue to support older templates."}),"\n",(0,t.jsx)(n.h4,{id:"updating-cluster-api-and-openstack-cluster-api-provider",children:"Updating cluster-API and openstack cluster-API provider"}),"\n",(0,t.jsxs)(n.p,{children:["To get the latest version of cluster-API, you can download a new clusterctl\nbinary from ",(0,t.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api/releases",children:"https://github.com/kubernetes-sigs/cluster-api/releases"}),",\nmake it executable ",(0,t.jsx)(n.code,{children:"chmod +x clusterctl"})," and install it to ",(0,t.jsx)(n.code,{children:"/usr/local/bin/"}),",\npossibly saving the old binary by renaming it. ",(0,t.jsx)(n.code,{children:"clusterctl version"})," should now\ndisplay the current version number (v1.6.2 at the time of this writing)."]}),"\n",(0,t.jsxs)(n.p,{children:["You can now issue the command ",(0,t.jsx)(n.code,{children:"clusterctl upgrade plan"})," and clusterctl will\nlist the components in your (kind) management cluster that can be upgraded.\nHere's an example output:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ubuntu@capi-old-mgmtcluster:~ [0]$ clusterctl upgrade plan\nChecking cert-manager version...\nCert-Manager is already up to date\n\nChecking new release availability...\n\nLatest release available for the v1beta1 API Version of Cluster API (contract):\n\nNAME NAMESPACE TYPE CURRENT VERSION NEXT VERSION\nbootstrap-kubeadm capi-kubeadm-bootstrap-system BootstrapProvider v1.5.1 v1.6.2\ncontrol-plane-kubeadm capi-kubeadm-control-plane-system ControlPlaneProvider v1.5.1 v1.6.2\ncluster-api capi-system CoreProvider v1.5.1 v1.6.2\ninfrastructure-openstack capo-system InfrastructureProvider v0.7.3 v0.9.0\n\nYou can now apply the upgrade by executing the following command:\n\nclusterctl upgrade apply --contract v1beta1\n"})}),"\n",(0,t.jsx)(n.p,{children:"You can then upgrade the components:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"export CLUSTER_TOPOLOGY=true"})," - this is needed from R5 to R6 upgrade due to ClusterClass feature #600"]}),"\n",(0,t.jsxs)(n.li,{children:["Upgrade components","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You can do them one-by-one, e.g.:","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"clusterctl upgrade apply --infrastructure capo-system/openstack:v0.9.0 --core capi-system/cluster-api:v1.6.2 -b capi-kubeadm-bootstrap-system/kubeadm:v1.6.2 -c capi-kubeadm-control-plane-system/kubeadm:v1.6.2\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Or simply do ",(0,t.jsx)(n.code,{children:"clusterctl upgrade apply --contract v1beta1"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"new-templates",children:"New templates"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"cluster-template.yaml"})," template used for the workload clusters is located in\n",(0,t.jsx)(n.code,{children:"~/k8s-cluster-api-provider/terraform/files/template/"})," and copied from there into\n",(0,t.jsx)(n.code,{children:"~/cluster-defaults/"}),". Then workload clusters are created, they will also have a\ncopy of it in ",(0,t.jsx)(n.code,{children:"~/${CLUSTER_NAME}/"}),". If you have not changed it manually, you can\ncopy it over the old templates. (Consider backing up the old one though.)"]}),"\n",(0,t.jsxs)(n.p,{children:["The next ",(0,t.jsx)(n.code,{children:"create_cluster.sh <CLUSTER_NAME>"})," run will then use the new template.\nNote that ",(0,t.jsx)(n.code,{children:"create_cluster.sh"})," is idempotent -- it will not perform any changes\non the cluster unless you have changed its configuration by tweaking\n",(0,t.jsx)(n.code,{children:"cluster-template.yaml"})," (which you almost never do!) or ",(0,t.jsx)(n.code,{children:"clusterctl.yaml"}),"\n(which you do often)."]}),"\n",(0,t.jsx)(n.p,{children:"The other template file that changed -- however, some opentofu logic is used to\nprefill it with values. So you can't copy it from git."}),"\n",(0,t.jsx)(n.h5,{id:"r2-to-r3",children:"R2 to R3"}),"\n",(0,t.jsxs)(n.p,{children:["For going from R2 to R3, there is just one real change that you want\nto apply: Add the variables ",(0,t.jsx)(n.code,{children:"CONTROL_PLANE_MACHINE_GEN: genc01"})," and\n",(0,t.jsx)(n.code,{children:"WORKER_MACHINE_GEN: genw01"})," to it. If you have copied over the new\n",(0,t.jsx)(n.code,{children:"cluster-template.yaml"})," as described above, then you're done. Otherwise\nyou can use the script ",(0,t.jsx)(n.code,{children:"update-R2-R3.sh <CLUSTER_NAME>"}),"\nto tweak both ",(0,t.jsx)(n.code,{children:"clusterctl.yaml"})," and ",(0,t.jsx)(n.code,{children:"cluster-template.yaml"})," for the\nrelevant cluster. (You can use ",(0,t.jsx)(n.code,{children:"cluster-defaults"})," to change the templates\nin ",(0,t.jsx)(n.code,{children:"~/cluster-defaults/"})," which get used when creating new clusters.)"]}),"\n",(0,t.jsx)(n.h5,{id:"r3-to-r4",children:"R3 to R4"}),"\n",(0,t.jsxs)(n.p,{children:["In the R3 to R4, CALICO_VERSION was moved from ",(0,t.jsx)(n.code,{children:".capi-settings"})," to ",(0,t.jsx)(n.code,{children:"clusterctl.yaml"}),". So\nbefore upgrading workload clusters, you must add it also to the ",(0,t.jsx)(n.code,{children:"~/${CLUSTER_NAME}/clusterctl.yaml"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'echo "CALICO_VERSION: v3.25.0" >> ~/cluster-defaults/clusterctl.yaml\necho "CALICO_VERSION: v3.25.0" >> ~/testcluster/clusterctl.yaml\n'})}),"\n",(0,t.jsxs)(n.p,{children:["In the R3 to R4 upgrade process, ",(0,t.jsx)(n.code,{children:"cluster-template.yaml"})," changed etcd defrag process in the\nkubeadm control-planes and also security group names by adding ",(0,t.jsx)(n.code,{children:"${PREFIX}-"})," to them, so it\nhas to be changed also in openstack project e.g. (",(0,t.jsx)(n.em,{children:"PREFIX=capi"}),"):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"openstack security group set --name capi-allow-ssh allow-ssh\nopenstack security group set --name capi-allow-icmp allow-icmp\n"})}),"\n",(0,t.jsxs)(n.p,{children:["We changed immutable fields in the Cluster API templates, so before running\n",(0,t.jsx)(n.code,{children:"create_cluster.sh"})," to upgrade existing workload cluster the ",(0,t.jsx)(n.code,{children:"CONTROL_PLANE_MACHINE_GEN"}),"\nand ",(0,t.jsx)(n.code,{children:"WORKER_MACHINE_GEN"})," needs to be incremented in cluster specific ",(0,t.jsx)(n.code,{children:"clusterctl.yaml"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["In the R3 to R4 process, also ",(0,t.jsx)(n.code,{children:"cloud.conf"})," added ",(0,t.jsx)(n.code,{children:"enable-ingress-hostname=true"})," to the\nLoadBalancer section. It is due to ",(0,t.jsx)(n.code,{children:"NGINX_INGRESS_PROXY"})," defaulting to true now. So if\nyou want to use, or you are already using this proxy functionality we recommend you to\nadd this line to your ",(0,t.jsx)(n.code,{children:"cloud.conf"}),", e.g.:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'echo "enable-ingress-hostname=true" >> ~/cluster-defaults/cloud.conf\necho "enable-ingress-hostname=true" >> ~/testcluster/cloud.conf\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Then, before upgrading workload cluster by ",(0,t.jsx)(n.code,{children:"create_cluster.sh"}),",\nyou should delete cloud-config secret in the kube-system namespace, so it can be recreated. E.g.:\n",(0,t.jsx)(n.code,{children:"kubectl delete secret cloud-config -n kube-system --kubeconfig=testcluster/testcluster.yaml"})]}),"\n",(0,t.jsx)(n.p,{children:"Also, the default nginx-ingress version has changed, so we recommend before upgrading cluster\nto delete ingress-nginx jobs, so new job with new image can be created in the update process."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl delete job ingress-nginx-admission-create -n ingress-nginx --kubeconfig=testcluster/testcluster.yaml\nkubectl delete job ingress-nginx-admission-patch -n ingress-nginx --kubeconfig=testcluster/testcluster.yaml\n"})}),"\n",(0,t.jsx)(n.h5,{id:"r4-to-r5",children:"R4 to R5"}),"\n",(0,t.jsxs)(n.p,{children:["In R4 to R5, the ",(0,t.jsx)(n.code,{children:"cluster-template.yaml"})," and ",(0,t.jsx)(n.code,{children:"clusterctl.yaml"})," changed (see release notes).\nYou can use script ",(0,t.jsx)(n.code,{children:"update-R4-to-R5.sh"})," to update the cluster's ",(0,t.jsx)(n.code,{children:"cluster-template.yaml"})," and ",(0,t.jsx)(n.code,{children:"clusterctl.yaml"})," from\nR4 to R5. This script could update an existing Kubernetes cluster configuration files\nas well as ",(0,t.jsx)(n.code,{children:"cluster-defaults"})," files that could be used for spawning new R5 clusters."]}),"\n",(0,t.jsx)(n.p,{children:"If you want to update an existing cluster configuration files from R4 to R5, just use script as follows:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"update-R4-to-R5.sh <CLUSTER_NAME>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["After you executed the above you will find that e.g. Calico version has been bumped from\nv3.25.0 to v3.26.1. Note that some software versions are not configurable and are not\ndirectly mentioned in the cluster configuration files, but they are hardcoded\nin R5 scripts (e.g. ingress nginx controller, metrics server), see ",(0,t.jsx)(n.a,{href:"#new-defaults",children:"new-defaults"})," section.\nNote that the Kubernetes version was not updated as well the default CNI is not the Cilium yet.\nThis two R5 features are out of scope this script when it is applied on the existing cluster\nconfiguration files as this features require advanced action such as CNI migration\nand step-by-step Kubernetes upgrade of +2 minor releases."]}),"\n",(0,t.jsxs)(n.p,{children:["If you want to update ",(0,t.jsx)(n.code,{children:"cluster-defaults"})," configuration files from R4 to R5, just use script as follows:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"update-R4-to-R5.sh cluster-defaults\n"})}),"\n",(0,t.jsx)(n.p,{children:"The above action updates a cluster-defaults configuration file, which is almost similar\nto updating an existing cluster configuration file described above. The distinction lies\nin the fact that both the Kubernetes version and the default CNI are also updated, specifically\nto Kubernetes version v1.27.5 and Cilium as a default CNI."}),"\n",(0,t.jsx)(n.h5,{id:"r5-to-r6",children:"R5 to R6"}),"\n",(0,t.jsxs)(n.p,{children:["In R5 to R6, the ",(0,t.jsx)(n.code,{children:"cluster-template.yaml"})," and ",(0,t.jsx)(n.code,{children:"clusterctl.yaml"})," changed (see release notes).\nYou can use script ",(0,t.jsx)(n.code,{children:"update-R5-to-R6.sh"})," to update the cluster's ",(0,t.jsx)(n.code,{children:"cluster-template.yaml"})," and ",(0,t.jsx)(n.code,{children:"clusterctl.yaml"})," from\nR5 to R6. This script could update an existing Kubernetes cluster configuration files\nas well as ",(0,t.jsx)(n.code,{children:"cluster-defaults"})," files that could be used for spawning new R6 clusters."]}),"\n",(0,t.jsx)(n.p,{children:"If you want to update an existing cluster configuration files from R5 to R6, just use script as follows:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"update-R5-to-R6.sh <CLUSTER_NAME>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["After you executed the above you will find that e.g. Calico version has been bumped from\nv3.26.1 to v3.27.2 or Kubernetes version bumped from v1.27.5 to v1.28.7.\nNote that some software versions are not configurable and are not directly mentioned\nin the cluster configuration files, but they are hardcoded\nin R6 scripts (e.g. ingress nginx controller, metrics server, cilium), see ",(0,t.jsx)(n.a,{href:"#new-defaults",children:"new-defaults"})," section."]}),"\n",(0,t.jsxs)(n.p,{children:["If you want to update ",(0,t.jsx)(n.code,{children:"cluster-defaults"})," configuration files from R5 to R6, just use script as follows:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"update-R5-to-R6.sh cluster-defaults\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you are curious: In R2, doing rolling upgrades of k8s versions required\nedits in ",(0,t.jsx)(n.code,{children:"cluster-template.yaml"})," -- this is no longer the case in R3, R4, R5 and R6.\nJust increase the generation counter for node and control plane nodes if you\nupgrade k8s versions -- or otherwise change the worker or control plane\nnode specs, such as e.g. using a different flavor."]}),"\n",(0,t.jsx)(n.h4,{id:"new-defaults",children:"New defaults"}),"\n",(0,t.jsxs)(n.p,{children:["You deploy a CNI (calico or cilium), the OpenStack Cloud Controller\nManager (OCCM), the cinder CSI driver to clusters; optionally also a\nmetrics server (default is true), a nginx ingress controller (also\ndefaulting to true), the flux2 controller, the cert-manager.\nSome of these tools come with binaries that you can use for management\npurposes and which get installed on the management host in ",(0,t.jsx)(n.code,{children:"/usr/local/bin/"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The scripts that deploy these components into your workload clusters\ndownload the manifests into ",(0,t.jsx)(n.code,{children:"~/kubernetes-manifests.d/"})," with a version\nspecific name. If you request a new version, a new download will happen;\nalready existing versions will not be re-downloaded."]}),"\n",(0,t.jsxs)(n.p,{children:["Most binaries in ",(0,t.jsx)(n.code,{children:"/usr/local/bin/"})," are not stored under a version-specific\nname. You need to rename them to case a re-download of a newer version.\n(The reason for not having version specific names is that this would\nbreak scripts from users that assume the unversioned names; the good\nnews is that most of these binaries have no trouble managing somewhat\nolder deployments, so you can typically work with the latest binary\ntool even if you have a variety of versions deployed into various\nclusters.)"]}),"\n",(0,t.jsx)(n.p,{children:"The defaults have changed as follows:"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{}),(0,t.jsx)(n.th,{children:"R2"}),(0,t.jsx)(n.th,{children:"R3"}),(0,t.jsx)(n.th,{children:"R4"}),(0,t.jsx)(n.th,{children:"R5"}),(0,t.jsx)(n.th,{children:"R6"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"kind"}),(0,t.jsx)(n.td,{children:"v0.14.0"}),(0,t.jsx)(n.td,{children:"v0.14.0"}),(0,t.jsx)(n.td,{children:"v0.17.0"}),(0,t.jsx)(n.td,{children:"v0.20.0"}),(0,t.jsx)(n.td,{children:"v0.20.0"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"capi"}),(0,t.jsx)(n.td,{children:"v1.0.5"}),(0,t.jsx)(n.td,{children:"v1.2.2"}),(0,t.jsx)(n.td,{children:"v1.3.5"}),(0,t.jsx)(n.td,{children:"v1.5.1"}),(0,t.jsx)(n.td,{children:"v1.6.2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"capo"}),(0,t.jsx)(n.td,{children:"v0.5.3"}),(0,t.jsx)(n.td,{children:"v0.6.3"}),(0,t.jsx)(n.td,{children:"v0.7.1"}),(0,t.jsx)(n.td,{children:"v0.7.3"}),(0,t.jsx)(n.td,{children:"v0.9.0"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"helm"}),(0,t.jsx)(n.td,{children:"v3.8.1"}),(0,t.jsx)(n.td,{children:"v3.9.4"}),(0,t.jsx)(n.td,{children:"v3.11.1"}),(0,t.jsx)(n.td,{children:"v3.12.3"}),(0,t.jsx)(n.td,{children:"v3.14.1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"sonobuoy"}),(0,t.jsx)(n.td,{children:"v0.56.2"}),(0,t.jsx)(n.td,{children:"v0.56.10"}),(0,t.jsx)(n.td,{children:"v0.56.16"}),(0,t.jsx)(n.td,{children:"v0.56.17"}),(0,t.jsx)(n.td,{children:"v0.57.1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"k9s"}),(0,t.jsx)(n.td,{children:"unversioned"}),(0,t.jsx)(n.td,{children:"unversioned"}),(0,t.jsx)(n.td,{children:"unversioned"}),(0,t.jsx)(n.td,{children:"v0.27.4"}),(0,t.jsx)(n.td,{children:"v0.31.9"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"calico"}),(0,t.jsx)(n.td,{children:"v3.22.1"}),(0,t.jsx)(n.td,{children:"v3.24.1"}),(0,t.jsx)(n.td,{children:"v3.25.0"}),(0,t.jsx)(n.td,{children:"v3.26.1"}),(0,t.jsx)(n.td,{children:"v3.27.2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"calico CLI"}),(0,t.jsx)(n.td,{children:"v3.22.1"}),(0,t.jsx)(n.td,{children:"v3.24.1"}),(0,t.jsx)(n.td,{children:"v3.25.0"}),(0,t.jsx)(n.td,{children:"v3.26.1"}),(0,t.jsx)(n.td,{children:"v3.27.2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"cilium"}),(0,t.jsx)(n.td,{children:"unversioned"}),(0,t.jsx)(n.td,{children:"unversioned"}),(0,t.jsx)(n.td,{children:"v1.13.0"}),(0,t.jsx)(n.td,{children:"v1.14.1"}),(0,t.jsx)(n.td,{children:"v1.15.1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"cilium CLI"}),(0,t.jsx)(n.td,{children:"unversioned"}),(0,t.jsx)(n.td,{children:"unversioned"}),(0,t.jsx)(n.td,{children:"v0.13.1"}),(0,t.jsx)(n.td,{children:"v0.15.7"}),(0,t.jsx)(n.td,{children:"v0.15.23"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"hubble CLI"}),(0,t.jsx)(n.td,{children:"unversioned"}),(0,t.jsx)(n.td,{children:"unversioned"}),(0,t.jsx)(n.td,{children:"v0.11.2"}),(0,t.jsx)(n.td,{children:"v0.12.0"}),(0,t.jsx)(n.td,{children:"v0.13.0"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"nginx-ingress"}),(0,t.jsx)(n.td,{children:"v1.1.2"}),(0,t.jsx)(n.td,{children:"v1.3.0"}),(0,t.jsx)(n.td,{children:"v1.6.4"}),(0,t.jsx)(n.td,{children:"v1.8.1"}),(0,t.jsx)(n.td,{children:"v1.9.6"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"flux2"}),(0,t.jsx)(n.td,{children:"unversioned"}),(0,t.jsx)(n.td,{children:"unversioned"}),(0,t.jsx)(n.td,{children:"v0.40.2"}),(0,t.jsx)(n.td,{children:"v2.1.0"}),(0,t.jsx)(n.td,{children:"v2.2.3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"cert-manager"}),(0,t.jsx)(n.td,{children:"v1.7.1"}),(0,t.jsx)(n.td,{children:"v1.9.1"}),(0,t.jsx)(n.td,{children:"v1.11.0"}),(0,t.jsx)(n.td,{children:"v1.12.4"}),(0,t.jsx)(n.td,{children:"v1.14.2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"metrics-server"}),(0,t.jsx)(n.td,{children:"v0.6.1"}),(0,t.jsx)(n.td,{children:"v0.6.1"}),(0,t.jsx)(n.td,{children:"v0.6.1"}),(0,t.jsx)(n.td,{children:"v0.6.4"}),(0,t.jsx)(n.td,{children:"v0.7.0"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"kubectx"}),(0,t.jsx)(n.td,{}),(0,t.jsx)(n.td,{}),(0,t.jsx)(n.td,{}),(0,t.jsx)(n.td,{}),(0,t.jsx)(n.td,{children:"v0.9.5"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"kube-ps1"}),(0,t.jsx)(n.td,{}),(0,t.jsx)(n.td,{}),(0,t.jsx)(n.td,{}),(0,t.jsx)(n.td,{}),(0,t.jsx)(n.td,{children:"v0.8.0"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"the-clusterctl-move-approach",children:"The clusterctl move approach"}),"\n",(0,t.jsx)(n.p,{children:"To be written"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Create new management host in same project -- avoid name conflicts\nwith different prefix, to be tweaked later. Avoid testcluster creation"}),"\n",(0,t.jsx)(n.li,{children:"Ensure it's up and running ..."}),"\n",(0,t.jsx)(n.li,{children:"Tweak prefix"}),"\n",(0,t.jsx)(n.li,{children:"Copy over configs (and a bit of state though that's uncritical) by using\nthe directories"}),"\n",(0,t.jsx)(n.li,{children:"Copy over the openstack credentials clouds.yaml and the kubectl config"}),"\n",(0,t.jsx)(n.li,{children:"clusterctl move"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"updating-workload-clusters",children:"Updating workload clusters"}),"\n",(0,t.jsx)(n.h3,{id:"k8s-version-upgrade",children:"k8s version upgrade"}),"\n",(0,t.jsx)(n.h4,{id:"on-r2-clusters",children:"On R2 clusters"}),"\n",(0,t.jsxs)(n.p,{children:["The old way: Editing cluster-template.yaml. Or better use the\n",(0,t.jsx)(n.code,{children:"update-R2-to-R3.sh"})," script to convert first."]}),"\n",(0,t.jsx)(n.h4,{id:"on-r3-and-r4-clusters",children:"On R3 and R4 clusters"}),"\n",(0,t.jsxs)(n.p,{children:["Edit ",(0,t.jsx)(n.code,{children:"~/<CLUSTER_NAME>/clusterctl.yaml"})," and put the wanted version into the\nfields ",(0,t.jsx)(n.code,{children:"KUBERNETES_VERSION"})," and ",(0,t.jsx)(n.code,{children:"OPENSTACK_IMAGE_NAME"}),". The node image will\nbe downloaded from ",(0,t.jsx)(n.a,{href:"https://minio.services.osism.tech/openstack-k8s-capi-images",children:"https://minio.services.osism.tech/openstack-k8s-capi-images"}),"\nand registered if needed. (If you have updated the k8s-cluster-api-provider repo,\nyou can use a version v1.NN.x, where you fill in NN with the wanted k8s version,\nbut leave a literal ",(0,t.jsx)(n.code,{children:".x"})," which will get translated to the newest tested version.)"]}),"\n",(0,t.jsxs)(n.p,{children:["In the same file, increase the generation counters for ",(0,t.jsx)(n.code,{children:"CONTROL_PLANE_MACHINE_GEN"}),"\nand ",(0,t.jsx)(n.code,{children:"WORKER_MACHINE_GEN"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Now do the normal ",(0,t.jsx)(n.code,{children:"create_cluster.sh <CLUSTER_NAME>"})," and watch cluster-api\nreplace your worker nodes and doing a rolling upgrade of your control plane.\nIf you used a 3-node (or 5 or higher) control plane node setup, you will have\nuninterrupted access not just to your workloads but also the workload's cluster\ncontrol plane. Use ",(0,t.jsx)(n.code,{children:"clusterctl describe cluster <CLUSTER_NAME>"})," or simply\n",(0,t.jsx)(n.code,{children:"kubectl --context <CLUSTER_NAME>-admin@<CLUSTER_NAME> get nodes -o wide"}),"\nto watch the progress of this."]}),"\n",(0,t.jsx)(n.h4,{id:"on-r5-clusters",children:"On R5 clusters"}),"\n",(0,t.jsx)(n.p,{children:"If you decide to migrate your existing Kubernetes cluster from R4 to R5 be aware of the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"R5 features such as per cluster namespaces and Cilium as a default CNI are supported\nonly on new clusters and will not be migrated on the existing clusters"}),"\n",(0,t.jsxs)(n.li,{children:["R4 default Kubernetes version v1.25.6 can not be directly migrated to the R5 default\nKubernetes version v1.27.5, because +2 minor Kubernetes version upgrade is ",(0,t.jsx)(n.a,{href:"https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/operate-cluster.html?highlight=upgrade%20cluster#upgrade-a-cluster",children:"not allowed"}),".\nSee further migration steps below if you want to upgrade also Kubernetes version to R5"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Follow the below steps if you want to migrate an existing cluster from R4 to R5:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Access your management node"}),"\n",(0,t.jsxs)(n.li,{children:["Checkout R5 branch","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd k8s-cluster-api-provider\ngit pull\ngit checkout maintained/v6.x\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Backup an existing cluster configuration files (recommended)","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd ..\ncp -R <CLUSTER_NAME> <CLUSTER_NAME>-backup\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Update an existing cluster configuration files from R4 to R5","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"update-R4-to-R5.sh <CLUSTER_NAME>\n"})}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:"Validate updated cluster configuration files. You will find that e.g. Calico version\nhas been bumped from v3.25.0 to v3.26.1. Note that some software versions are not configurable\nand are not directly mentioned in the cluster configuration files, but they are hardcoded\nin R5 scripts (e.g. ingress nginx controller, metrics server). Hence, read carefully the\nR5 release notes too. Also see that Kubernetes version was not updated, and it is still v1.25.6."}),"\n",(0,t.jsxs)(n.li,{children:["Update an existing cluster (except Kubernetes version)","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"create_cluster.sh <CLUSTER_NAME>\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Update cluster-API and openstack cluster-API provider, see ",(0,t.jsx)(n.a,{href:"#updating-cluster-api-and-openstack-cluster-api-provider",children:"related"})," section for details","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"clusterctl upgrade plan\nclusterctl upgrade apply --contract v1beta1\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Bump Kubernetes version +1 minor release (to v1.26.8) and increase the generation counter for node and control plane nodes","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sed -i 's/^KUBERNETES_VERSION: v1.25.6/KUBERNETES_VERSION: v1.26.8/' <CLUSTER_NAME>/clusterctl.yaml\nsed -i 's/^OPENSTACK_IMAGE_NAME: ubuntu-capi-image-v1.25.6/OPENSTACK_IMAGE_NAME: ubuntu-capi-image-v1.26.8/' <CLUSTER_NAME>/clusterctl.yaml\nsed -r 's/(^CONTROL_PLANE_MACHINE_GEN: genc)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i <CLUSTER_NAME>/clusterctl.yaml\nsed -r 's/(^WORKER_MACHINE_GEN: genw)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i <CLUSTER_NAME>/clusterctl.yaml\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Update an existing cluster Kubernetes version to v1.26.8","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"create_cluster.sh <CLUSTER_NAME>\n"})}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:"Bump Kubernetes version to R5 v1.27.5 and increase the generation counter for node and control plane nodes"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sed -i 's/^KUBERNETES_VERSION: v1.26.8/KUBERNETES_VERSION: v1.27.5/' <CLUSTER_NAME>/clusterctl.yaml\nsed -i 's/^OPENSTACK_IMAGE_NAME: ubuntu-capi-image-v1.26.8/OPENSTACK_IMAGE_NAME: ubuntu-capi-image-v1.27.5/' <CLUSTER_NAME>/clusterctl.yaml\nsed -r 's/(^CONTROL_PLANE_MACHINE_GEN: genc)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i <CLUSTER_NAME>/clusterctl.yaml\nsed -r 's/(^WORKER_MACHINE_GEN: genw)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i <CLUSTER_NAME>/clusterctl.yaml\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"11",children:["\n",(0,t.jsxs)(n.li,{children:["Update an existing cluster to the R5 Kubernetes version v1.27.5","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"create_cluster.sh <CLUSTER_NAME>\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"on-r6-clusters",children:"On R6 clusters"}),"\n",(0,t.jsx)(n.p,{children:"If you decide to migrate your existing Kubernetes cluster from R5 to R6 be aware of the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Kubernetes version will be upgraded from v1.27.5 to v1.28.7"}),"\n",(0,t.jsx)(n.li,{children:"You have to migrate from Cluster based templates to ClusterClass based templates"}),"\n",(0,t.jsxs)(n.li,{children:["Upgrade of cilium needs to be done manually (for clusters with ",(0,t.jsx)(n.code,{children:"USE_CILIUM: true"}),")"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Follow the below steps if you want to migrate an existing cluster from R5 to R6:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Access your management node"}),"\n",(0,t.jsxs)(n.li,{children:["Checkout R6 branch","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd k8s-cluster-api-provider\ngit pull\ngit checkout maintained/v7.x\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Backup an existing cluster configuration files (recommended)","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd ..\ncp -R <CLUSTER_NAME> <CLUSTER_NAME>-backup\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Update an existing cluster configuration files from R5 to R6","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"update-R5-to-R6.sh <CLUSTER_NAME>\n"})}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:"Validate updated cluster configuration files. You will find that e.g. Calico version\nhas been bumped from v3.26.1 to v3.27.2 or Kubernetes version bumped from v1.27.5 to v1.28.7.\nNote that some software versions are not configurable and are not directly mentioned in the\ncluster configuration files, but they are hardcoded in R6 scripts (e.g. ingress nginx controller,\nmetrics server, cilium). Hence, read carefully the R6 release notes too."}),"\n",(0,t.jsxs)(n.li,{children:["Update cluster-API and openstack cluster-API provider, see ",(0,t.jsx)(n.a,{href:"#updating-cluster-api-and-openstack-cluster-api-provider",children:"related"})," section for details","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"clusterctl upgrade plan\nexport CLUSTER_TOPOLOGY=true\nclusterctl upgrade apply --contract v1beta1\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Migrate to ClusterClass","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"migrate-to-cluster-class.sh <CLUSTER_NAME>\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Increase the generation counter for worker and control plane nodes","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sed -r 's/(^CONTROL_PLANE_MACHINE_GEN: genc)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i <CLUSTER_NAME>/clusterctl.yaml\nsed -r 's/(^WORKER_MACHINE_GEN: genw)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i <CLUSTER_NAME>/clusterctl.yaml\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Update an existing cluster to the R6","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"create_cluster.sh <CLUSTER_NAME>\n"})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["Note: You will probably experience a double rollout of nodes because\nthe k8s version and templates are changed concurrently here.\nSee ",(0,t.jsx)(n.a,{href:"https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/operate-cluster#effects-of-concurrent-changes",children:"https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/operate-cluster#effects-of-concurrent-changes"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Upgrade cilium (for clusters with ",(0,t.jsx)(n.code,{children:"USE_CILIUM: true"}),")","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"KUBECONFIG=<CLUSTER_NAME>/<CLUSTER_NAME>.yaml bash -c 'helm get values cilium -n kube-system -o yaml | cilium upgrade --version v1.15.1 -f -'\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"new-versions-for-mandatory-components",children:"New versions for mandatory components"}),"\n",(0,t.jsx)(n.p,{children:"OCCM, CNI (calico/cilium), CSI"}),"\n",(0,t.jsx)(n.h3,{id:"new-versions-for-optional-components",children:"New versions for optional components"}),"\n",(0,t.jsx)(n.p,{children:"nginx, metrics server, cert-manager, flux"}),"\n",(0,t.jsx)(n.h3,{id:"etcd-leader-changes",children:"etcd leader changes"}),"\n",(0,t.jsx)(n.p,{children:"While testing clusters with >= 3 control nodes, we have observed occasional transient\nerror messages that reported an etcd leader change preventing a command from succeeding.\nThis could result in a dozen of random failed tests in a sonobuoy conformance run.\n(Retrying the commands would let them succeed.)"}),"\n",(0,t.jsx)(n.p,{children:"Too frequent etcd leader changes are detrimental to your control plane performance and\ncan lead to transient failures. They are a sign that the infrastructure supporting your\ncluster is introducing too high latencies."}),"\n",(0,t.jsx)(n.p,{children:"We recommend to deploy the control nodes (which run etcd) on instances with local SSD\nstorage (which we reflect in the default flavor name) and recommend using flavors with\ndedicated cores and that your network does not introduce latencies by significant packet drop."}),"\n",(0,t.jsxs)(n.p,{children:["We now always use slower heartbeat (250ms) and increase CPU and IO priority which used to be\ncontrolled by ",(0,t.jsx)(n.code,{children:"ETCD_PRIO_BOOST"}),". This is safe."]}),"\n",(0,t.jsxs)(n.p,{children:["If you build multi-controller clusters and can not use a flavor with low latency local storage\n(ideally SSD), you can also work around this with ",(0,t.jsx)(n.code,{children:"ETCD_UNSAFE_FS"}),". ",(0,t.jsx)(n.code,{children:"ETCD_UNSAFE_FS"})," is using\n",(0,t.jsx)(n.code,{children:"barrier=0"})," mount option, which violates filesystem ordering guarantees.\nThis works around storage latencies, but introduces the risk of inconsistent\nfilesystem state and inconsistent etcd data in case of an unclean shutdown.\nYou may be able to live with this risk in a multi-controller etcd setup.\nIf you don't have flavors that fulfill the requirements (low-latency\nstorage attached), your choice is between a single-controller cluster\n(without ",(0,t.jsx)(n.code,{children:"ETCD_UNSAFE_FS"}),") and a multi-controller cluster with\n",(0,t.jsx)(n.code,{children:"ETCD_UNSAFE_FS"}),". Neither option is perfect, but we deem the\nmulti-controller cluster preferable in such a scenario."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>o});var t=s(96540);const r={},i=t.createContext(r);function l(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/38c9ef35.3cdf3303.js b/assets/js/38c9ef35.3cdf3303.js new file mode 100644 index 0000000000..555cb68447 --- /dev/null +++ b/assets/js/38c9ef35.3cdf3303.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3131],{44945:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var n=t(74848),d=t(28453);const r={},a="Global Standards",c={id:"global/index",title:"Global Standards",description:"This track encompasses the foundational standards that guide the overall structure, documentation, and general topics related to the Sovereign Cloud Stack. It serves as the core framework, ensuring consistency, clarity, and comprehensibility across all aspects of the cloud stack, fostering an environment where information is easily accessible and understood.",source:"@site/standards/global/index.md",sourceDirName:"global",slug:"/global/",permalink:"/standards/global/",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Overview",permalink:"/standards/standards/overview"},next:{title:"scs-0001: Sovereign Cloud Standards",permalink:"/standards/global/scs-0001"}},i={},l=[];function o(e){const s={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"global-standards",children:"Global Standards"}),"\n",(0,n.jsx)(s.p,{children:"This track encompasses the foundational standards that guide the overall structure, documentation, and general topics related to the Sovereign Cloud Stack. It serves as the core framework, ensuring consistency, clarity, and comprehensibility across all aspects of the cloud stack, fostering an environment where information is easily accessible and understood."}),"\n",(0,n.jsx)(s.p,{children:"*Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective)."}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Standard"}),(0,n.jsx)(s.th,{children:"Description"}),(0,n.jsx)(s.th,{children:"Draft"}),(0,n.jsx)(s.th,{children:"Stable*"}),(0,n.jsx)(s.th,{children:"Effective"}),(0,n.jsx)(s.th,{children:"Deprecated*"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/global/scs-0001",children:"scs-0001"})}),(0,n.jsx)(s.td,{children:"Sovereign Cloud Standards"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0001-v1-sovereign-cloud-standards",children:"v1"})}),(0,n.jsx)(s.td,{children:"-"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/global/scs-0002",children:"scs-0002"})}),(0,n.jsx)(s.td,{children:"Standards, Docs and Organisation"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0002-v2-standards-docs-org",children:"v2"})}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0002-v1-standards-docs-org",children:"v1"})}),(0,n.jsx)(s.td,{children:"-"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/global/scs-0003",children:"scs-0003"})}),(0,n.jsx)(s.td,{children:"Sovereign Cloud Standards YAML"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",children:"v1"})}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/global/scs-0004",children:"scs-0004"})}),(0,n.jsx)(s.td,{children:"Regulations for achieving SCS-compatible certification"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0004-v1-achieving-certification",children:"v1"})}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/global/scs-0112",children:"scs-0112"})}),(0,n.jsx)(s.td,{children:"SONiC Support in SCS"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0112-v1-sonic",children:"v1"})}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]})]})]})]})}function h(e={}){const{wrapper:s}={...(0,d.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(o,{...e})}):o(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>a,x:()=>c});var n=t(96540);const d={},r=n.createContext(d);function a(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:a(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3a1d878d.8acba785.js b/assets/js/3a1d878d.8acba785.js new file mode 100644 index 0000000000..c1146b5d98 --- /dev/null +++ b/assets/js/3a1d878d.8acba785.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8031],{81813:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>l,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var o=t(74848),s=t(28453);const a={},c="OpenStack",i={id:"iaas/guides/concept-guide/components/openstack",title:"OpenStack",description:"Lifecycle Management of OpenStack in OSISM",source:"@site/docs/02-iaas/guides/concept-guide/components/openstack.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/openstack",permalink:"/docs/iaas/guides/concept-guide/components/openstack",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/openstack.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Netdata",permalink:"/docs/iaas/guides/concept-guide/components/netdata"},next:{title:"Prometheus & Grafana",permalink:"/docs/iaas/guides/concept-guide/components/prometheus"}},r={},p=[{value:"Lifecycle Management of OpenStack in OSISM",id:"lifecycle-management-of-openstack-in-osism",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",p:"p",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"openstack",children:"OpenStack"}),"\n",(0,o.jsx)(n.h2,{id:"lifecycle-management-of-openstack-in-osism",children:"Lifecycle Management of OpenStack in OSISM"}),"\n",(0,o.jsxs)(n.p,{children:["The open source project Kolla from the ",(0,o.jsx)(n.a,{href:"https://openinfra.dev",children:"OpenInfra Foundation"})," is\nused in OSISM for the life cycle management of OpenStack. Kolla\u2019s mission is to provide\nproduction-ready containers and deployment tools for operating OpenStack clouds. Kolla has\nbeen actively developed by a very diverse team for 10 years and is one of the most common\n(if not the most common) life cycle management tool for OpenStack."]}),"\n",(0,o.jsxs)(n.p,{children:["The container images provided by Kolla are not only used by Kolla itself. They are also used\nin TripleO, the basis for the now discontinued\n",(0,o.jsx)(n.a,{href:"https://www.redhat.com/en/technologies/linux-platforms/openstack-platform",children:"RedHat OpenStack Platform"}),",\nand the ",(0,o.jsx)(n.a,{href:"https://github.com/openstack-k8s-operators",children:"OpenStack Kubernetes Operators"}),",\nthe basis for the new\n",(0,o.jsx)(n.a,{href:"https://www.redhat.com/en/blog/red-hat-openstack-services-openshift-next-generation-red-hat-openstack-platform",children:"OpenStack Services on OpenShift from Redhat"}),"."]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var o=t(96540);const s={},a=o.createContext(s);function c(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3ad2c61e.4f252055.js b/assets/js/3ad2c61e.4f252055.js new file mode 100644 index 0000000000..62225ede3a --- /dev/null +++ b/assets/js/3ad2c61e.4f252055.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8384],{56313:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var t=i(74848),s=i(28453);const o={},a="Ceph",c={id:"iaas/guides/concept-guide/components/ceph",title:"Ceph",description:"Ceph is an Open Source software defined storage platform designed to provide highly scalable",source:"@site/docs/02-iaas/guides/concept-guide/components/ceph.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/ceph",permalink:"/docs/iaas/guides/concept-guide/components/ceph",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/ceph.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Components",permalink:"/docs/iaas/guides/concept-guide/components/"},next:{title:"Cluster API",permalink:"/docs/iaas/guides/concept-guide/components/clusterapi"}},r={},l=[{value:"Lifecycle Management of Ceph in OSISM",id:"lifecycle-management-of-ceph-in-osism",level:2}];function d(e){const n={h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"ceph",children:"Ceph"}),"\n",(0,t.jsx)(n.p,{children:"Ceph is an Open Source software defined storage platform designed to provide highly scalable\nobject, block and file-based storage in a unified system. Designed for flexibility,\nCeph integrates seamlessly with cloud infrastructures like OpenStack and supports\ndiverse workloads with robust, self-healing and self-managing capabilities."}),"\n",(0,t.jsx)(n.p,{children:"Key benefits of Ceph include:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Scalability: Ceph is designed to scale from terabytes to exabytes, easily meeting\nthe needs of small businesses to large enterprises."}),"\n",(0,t.jsx)(n.li,{children:"Resilience: With built-in redundancy and data replication, Ceph ensures data\nintegrity and availability even in the face of hardware failures."}),"\n",(0,t.jsx)(n.li,{children:"High performance: Using a distributed architecture, Ceph delivers high throughput\nand low latency, making it ideal for high-demand workloads."}),"\n",(0,t.jsx)(n.li,{children:"Cost-effective: As open source, Ceph eliminates licensing costs and its ability to\nrun on commodity hardware reduces CapEx."}),"\n",(0,t.jsx)(n.li,{children:"Versatility: Ceph supports a variety of storage types - object, block and file -\non a single platform, simplifying storage management and reducing operational complexity."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"lifecycle-management-of-ceph-in-osism",children:"Lifecycle Management of Ceph in OSISM"})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>c});var t=i(96540);const s={},o=t.createContext(s);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3bf9fbe6.456b5e1f.js b/assets/js/3bf9fbe6.456b5e1f.js new file mode 100644 index 0000000000..52ccc0f38d --- /dev/null +++ b/assets/js/3bf9fbe6.456b5e1f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3942],{9281:e=>{e.exports=JSON.parse('{"title":"Releases","slug":"/category/releases","permalink":"/docs/category/releases","navigation":{"previous":{"title":"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)","permalink":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations"},"next":{"title":"Release Notes for SCS Release 0","permalink":"/docs/releases/Release0"}}}')}}]); \ No newline at end of file diff --git a/assets/js/3d19221e.ca825484.js b/assets/js/3d19221e.ca825484.js new file mode 100644 index 0000000000..0167742257 --- /dev/null +++ b/assets/js/3d19221e.ca825484.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3714],{70499:(s,n,o)=>{o.r(n),o.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>a});var e=o(74848),t=o(28453);const i={sidebar_label:"Commons",sidebar_position:50},c="Commons",r={id:"iaas/guides/configuration-guide/commons/index",title:"Commons",description:"This section contains the documentation of the Ansible collection osism.commons.",source:"@site/docs/02-iaas/guides/configuration-guide/commons/index.md",sourceDirName:"02-iaas/guides/configuration-guide/commons",slug:"/iaas/guides/configuration-guide/commons/",permalink:"/docs/iaas/guides/configuration-guide/commons/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/index.md",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"Commons",sidebar_position:50},sidebar:"docs",previous:{title:"Skyline",permalink:"/docs/iaas/guides/configuration-guide/openstack/skyline"},next:{title:"Certificates",permalink:"/docs/iaas/guides/configuration-guide/commons/certificates"}},d={},a=[];function m(s){const n={a:"a",h1:"h1",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...s.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(n.h1,{id:"commons",children:"Commons"}),"\n",(0,e.jsxs)(n.p,{children:["This section contains the documentation of the Ansible collection ",(0,e.jsx)(n.a,{href:"https://github.com/osism/ansible-collection-commons",children:"osism.commons"}),"."]}),"\n",(0,e.jsxs)(n.table,{children:[(0,e.jsx)(n.thead,{children:(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.th,{children:(0,e.jsx)(n.strong,{children:"Role"})}),(0,e.jsx)(n.th,{children:(0,e.jsx)(n.strong,{children:"Description"})})]})}),(0,e.jsxs)(n.tbody,{children:[(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:"osism.commons.network"}),(0,e.jsx)(n.td,{})]}),(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:"osism.commons.packages"}),(0,e.jsx)(n.td,{})]}),(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:"osism.commons.services"}),(0,e.jsx)(n.td,{})]}),(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:"osism.commons.sshconfig"}),(0,e.jsx)(n.td,{})]}),(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:"osism.commons.timezone"}),(0,e.jsx)(n.td,{})]})]})]})]})}function l(s={}){const{wrapper:n}={...(0,t.R)(),...s.components};return n?(0,e.jsx)(n,{...s,children:(0,e.jsx)(m,{...s})}):m(s)}},28453:(s,n,o)=>{o.d(n,{R:()=>c,x:()=>r});var e=o(96540);const t={},i=e.createContext(t);function c(s){const n=e.useContext(i);return e.useMemo((function(){return"function"==typeof s?s(n):{...n,...s}}),[n,s])}function r(s){let n;return n=s.disableParentContext?"function"==typeof s.components?s.components(t):s.components||t:c(s.components),e.createElement(i.Provider,{value:n},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/3d23a943.69553362.js b/assets/js/3d23a943.69553362.js new file mode 100644 index 0000000000..cc92c03363 --- /dev/null +++ b/assets/js/3d23a943.69553362.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1014],{60343:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var i=n(74848),s=n(28453);const r={title:"Kubernetes cluster baseline security",type:"Standard",status:"Draft",track:"KaaS"},o=void 0,a={id:"scs-0217-v1-baseline-cluster-security",title:"Kubernetes cluster baseline security",description:"Introduction",source:"@site/standards/scs-0217-v1-baseline-cluster-security.md",sourceDirName:".",slug:"/scs-0217-v1-baseline-cluster-security",permalink:"/standards/scs-0217-v1-baseline-cluster-security",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Kubernetes cluster baseline security",type:"Standard",status:"Draft",track:"KaaS"},sidebar:"standards",previous:{title:"scs-0217: Kubernetes cluster baseline security",permalink:"/standards/kaas/scs-0217"},next:{title:"scs-0218: Container registry for SCS standard implementation",permalink:"/standards/kaas/scs-0218"}},c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"External CA",id:"external-ca",level:3},{value:"Protected Kubernetes endpoints",id:"protected-kubernetes-endpoints",level:3},{value:"TLS for all internal/API traffic",id:"tls-for-all-internalapi-traffic",level:4},{value:"Authentication and Authorization",id:"authentication-and-authorization",level:4},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function d(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"Due to the regular changes and updates, there are always new security features to deploy and use in Kubernetes.\nNevertheless, a provider (or even a customer) needs to take action in order to achieve a\nhardened, secure cluster due to the myriad of configurations possible. This is especially\nthe case since Kubernetes ships with insecure features and configurations out of the box,\nwhich will need to be mitigated by an administrator with the proper knowledge.\nHardened, secure Kubernetes clusters are desirable regardless of the possible threat model,\nsince higher security doesn't necessarily mean higher complexity in this case."}),"\n",(0,i.jsx)(t.h2,{id:"terminology",children:"Terminology"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Term"}),(0,i.jsx)(t.th,{children:"Meaning"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"TLS"}),(0,i.jsx)(t.td,{children:"Transport Layer Security"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"CA"}),(0,i.jsx)(t.td,{children:"Certificate Authority"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"CSR"}),(0,i.jsx)(t.td,{children:"Certificate Signing Request"})]})]})]}),"\n",(0,i.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:"Kubernetes clusters are highly configurable, which also gives rise to different security\nproblems, if the configuration isn't done properly.\nThese security risks can potentially be exposed in many different parts of a cluster, e.g.\ndifferent APIs, authorization and authentication procedures or even Pod privilege mechanisms.\nIn order to mitigate these problems, different steps and mechanisms could be used to increase\nthe security of a Kubernetes setup."}),"\n",(0,i.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsx)(t.h3,{id:"external-ca",children:"External CA"}),"\n",(0,i.jsx)(t.p,{children:"Kubernetes provides an API to provision TLS certificates that can be signed by a CA.\nThis CA can be controlled by the cluster provider, which enables much more tight control\nover the clusters communication and therefore also better controllable security."}),"\n",(0,i.jsx)(t.p,{children:"In order to do this, the CA certificate bundle needs to be added to the trusted certificates\nof the server.\nTo provide a certificate, the following steps need to be undertaken:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Create a CSR"}),"\n",(0,i.jsx)(t.li,{children:"Send the CSR manifest to the k8s API"}),"\n",(0,i.jsx)(t.li,{children:"Approve the CSR"}),"\n",(0,i.jsx)(t.li,{children:"Sign CSR with your CA"}),"\n",(0,i.jsx)(t.li,{children:"Upload the signed certificate to the server"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"This certificate could now be used by a user in a pod in order to provide a trusted certificate."}),"\n",(0,i.jsxs)(t.p,{children:["It is also possible for the Kubernetes controller manager to provide the signing functionality.\nTo enable this, ",(0,i.jsx)(t.code,{children:"--cluster-signing-cert-file"})," and ",(0,i.jsx)(t.code,{children:"--cluster-signing-key-file"})," need to be set with\na reference to the CA keypair, which was used in the previous example to sign a CSR."]}),"\n",(0,i.jsx)(t.h3,{id:"protected-kubernetes-endpoints",children:"Protected Kubernetes endpoints"}),"\n",(0,i.jsx)(t.p,{children:"In order to secure a Kubernetes cluster, the protection of endpoints is important.\nTo do this, different approaches can be taken."}),"\n",(0,i.jsx)(t.h4,{id:"tls-for-all-internalapi-traffic",children:"TLS for all internal/API traffic"}),"\n",(0,i.jsx)(t.p,{children:"It is already expected by Kubernetes that all API communication internally is encrypted with TLS.\nNevertheless, some endpoints of internal components could be/will be exposed without the necessary\nencryption, which could lead to weak points in the system.\nA list of the default service endpoints can be seen in the following table"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Protocol"}),(0,i.jsx)(t.th,{children:"Port Range"}),(0,i.jsx)(t.th,{children:"Purpose"}),(0,i.jsx)(t.th,{children:"Notes"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"6443*"}),(0,i.jsx)(t.td,{children:"Kubernetes API Server"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"2379-2380"}),(0,i.jsx)(t.td,{children:"etcd server client API"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"10250"}),(0,i.jsx)(t.td,{children:"Kubelet API"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"10251/10259"}),(0,i.jsx)(t.td,{children:"kube-scheduler"}),(0,i.jsx)(t.td,{children:"10251 could be insecure before 1.13, after that only the secure port 10259 is available"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"10252/10257"}),(0,i.jsx)(t.td,{children:"kube-controller-manager"}),(0,i.jsx)(t.td,{children:"10252 could be insecure before 1.13, after that only the secure port 10257 is available"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"TCP"}),(0,i.jsx)(t.td,{children:"30000-32767"}),(0,i.jsx)(t.td,{children:"NodePort Services"}),(0,i.jsx)(t.td,{children:"Service endpoints, could be HTTP"})]})]})]}),"\n",(0,i.jsxs)(t.p,{children:["The usage of ",(0,i.jsx)(t.code,{children:"readOnlyPort"})," (enabling a read-only Kubelet API port on 10255) by design neither provides authentication nor authorization. Its usage is strongly discouraged!"]}),"\n",(0,i.jsx)(t.h4,{id:"authentication-and-authorization",children:"Authentication and Authorization"}),"\n",(0,i.jsx)(t.p,{children:"All API clients should authenticate and authorize in order to be able to access an API or even\nspecific functions of this API. This is the case for users as well as internal components."}),"\n",(0,i.jsx)(t.p,{children:"Most internal clients (like proxies or nodes) are typically authenticated via service accounts or\nx509 certificates, which will normally be created automatically during the setup of a cluster.\nExternal users can authenticate via an access pattern of choice, which is typically decided by\nthe cluster provider."}),"\n",(0,i.jsx)(t.p,{children:"Authorization is (normally) done by the Role-Based Access Control (RBAC), which matches a request\nby a user with a set of permissions, also called a role. Kubernetes deploys some roles out-of-the-box;\nadditional roles need to be carefully checked, since some permissions for specific resources allow\nmodification of other resources."}),"\n",(0,i.jsx)(t.p,{children:"This whole process is especially important for the Kubelet, which allows anonymous requests in its\ndefault configuration. This is obviously a security risk, since everybody with access to its endpoint\ncould manipulate resources that are managed with the Kubelet."}),"\n",(0,i.jsxs)(t.p,{children:["To disable anonymous requests, the Kubelet should be started with ",(0,i.jsx)(t.code,{children:"--anonymous-auth=false"}),".\nAuthentication can be provided either through x509 client certificates or API bearer tokens.\nHow to set up both approaches can be found in the ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/",children:"Kubelet Authentication and Authorization"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["Kubelet authorization is set to ",(0,i.jsx)(t.code,{children:"AlwaysAllow"})," as a default mode. This can be quite problematic,\nsince all authenticated users can do all actions. To mitigate this, it is possible to delegate\nauthorization to the API server by:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["enabling the ",(0,i.jsx)(t.code,{children:"authorization.k8s.io/v1beta1"})," API group"]}),"\n",(0,i.jsxs)(t.li,{children:["starting the Kubelet with the ",(0,i.jsx)(t.code,{children:"--authorization-mode=Webhook"})," and the ",(0,i.jsx)(t.code,{children:"--kubeconfig"})," flags"]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["After that, the Kubelet calls the ",(0,i.jsx)(t.code,{children:"SubjectAccessReview"})," API in order to determine the authorization of a request."]}),"\n",(0,i.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(t.p,{children:"This standard tries to increase security for a Kubernetes cluster in order to provide a\nsolid baseline setup with regard to security. For this to work, multiple measures need to be undertaken."}),"\n",(0,i.jsx)(t.p,{children:"A self-controlled CA SHOULD be used in order to be in control of the TLS certificates, which\nenables operators to provide and revoke certificates according to their own requirements."}),"\n",(0,i.jsx)(t.p,{children:"All internal endpoints found in the section [TLS for all internal/API traffic] MUST be\nencrypted with TLS in order to secure internal traffic."}),"\n",(0,i.jsx)(t.p,{children:"The Kubernetes API (kubeAPI) MUST be secured by authenticating and authorizing the users\ntrying to access its endpoints. How a user is authenticated is up to the provider of the\ncluster and/or the wishes of the customer. Authorization MUST be done by providing fine-grained RBAC.\nThe authentication and authorization steps MUST also be applied to the Kubelet, which in its default configuration\ndoesn't enable them. A way to do this can be found in the section [Authentication and Authorization]."}),"\n",(0,i.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/",children:"Managing TLS in a cluster"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/securing-a-cluster/",children:"Securing a cluster"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/security/controlling-access/",children:"Controlling access"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/security/security-checklist/",children:"Kubernetes Security Checklist"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/",children:"Kubelet Authentication and Authorization"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/access-authn-authz/authentication/",children:"Authentication"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://cheatsheetseries.owasp.org/cheatsheets/Kubernetes_Security_Cheat_Sheet.html",children:"OWASP Kubernetes Security Cheat Sheet"})}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,i.jsx)(t.p,{children:"Conformance Tests will be written in another issue"})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var i=n(96540);const s={},r=i.createContext(s);function o(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3d9e0922.7b202a02.js b/assets/js/3d9e0922.7b202a02.js new file mode 100644 index 0000000000..18457f739e --- /dev/null +++ b/assets/js/3d9e0922.7b202a02.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2069],{74463:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>l,frontMatter:()=>a,metadata:()=>d,toc:()=>o});var n=s(74848),r=s(28453);const a={},c="scs-0410: Gnocchi as database for metering",d={id:"ops/scs-0410",title:"scs-0410: Gnocchi as database for metering",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/ops/scs-0410.md",sourceDirName:"ops",slug:"/ops/scs-0410",permalink:"/standards/ops/scs-0410",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Architecture for the Cloud Service provider Observability System for the KaaS Layer",permalink:"/standards/scs-0403-v1-csp-kaas-observability-stack"},next:{title:"Gnocchi as database for metering",permalink:"/standards/scs-0410-v1-gnocchi-as-metering-database"}},i={},o=[];function h(e){const t={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"scs-0410-gnocchi-as-database-for-metering",children:"scs-0410: Gnocchi as database for metering"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0410-v1-gnocchi-as-metering-database",children:"scs-0410-v1"})}),(0,n.jsx)(t.td,{children:"Decision Record"}),(0,n.jsx)(t.td,{children:"Draft"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>d});var n=s(96540);const r={},a=n.createContext(r);function c(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3e493f26.445fd139.js b/assets/js/3e493f26.445fd139.js new file mode 100644 index 0000000000..8af202f835 --- /dev/null +++ b/assets/js/3e493f26.445fd139.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6029],{36278:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>s,metadata:()=>i,toc:()=>u});var o=n(74848),r=n(28453);const s={},c="Network",i={id:"iaas/overview/network",title:"Network",description:"TODO",source:"@site/docs/02-iaas/overview/network.md",sourceDirName:"02-iaas/overview",slug:"/iaas/overview/network",permalink:"/docs/iaas/overview/network",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/overview/network.md",tags:[],version:"current",frontMatter:{}},a={},u=[];function d(e){const t={h1:"h1",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"network",children:"Network"}),"\n",(0,o.jsx)(t.p,{children:"TODO"})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var o=n(96540);const r={},s=o.createContext(r);function c(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3f3928dc.cf5405a4.js b/assets/js/3f3928dc.cf5405a4.js new file mode 100644 index 0000000000..70a3a73017 --- /dev/null +++ b/assets/js/3f3928dc.cf5405a4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3213],{44428:(s,e,d)=>{d.r(e),d.d(e,{assets:()=>c,contentTitle:()=>a,default:()=>x,frontMatter:()=>t,metadata:()=>i,toc:()=>l});var r=d(74848),n=d(28453);const t={},a="IaaS Standards",i={id:"iaas/index",title:"IaaS Standards",description:"The IaaS Layer Standards track focuses on the protocols, guidelines, and specifications that govern the infrastructure as a service layer. This encompasses standards for virtual machines, storage, networking, and other foundational resources, ensuring seamless, efficient, and secure operation, interoperability, and management of the underlying cloud infrastructure.",source:"@site/standards/iaas/index.md",sourceDirName:"iaas",slug:"/iaas/",permalink:"/standards/iaas/",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"SONiC Support in SCS",permalink:"/standards/scs-0112-v1-sonic"},next:{title:"scs-0100: SCS Flavor Naming Standard",permalink:"/standards/iaas/scs-0100"}},c={},l=[];function h(s){const e={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...s.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.h1,{id:"iaas-standards",children:"IaaS Standards"}),"\n",(0,r.jsx)(e.p,{children:"The IaaS Layer Standards track focuses on the protocols, guidelines, and specifications that govern the infrastructure as a service layer. This encompasses standards for virtual machines, storage, networking, and other foundational resources, ensuring seamless, efficient, and secure operation, interoperability, and management of the underlying cloud infrastructure."}),"\n",(0,r.jsx)(e.p,{children:"*Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective)."}),"\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Standard"}),(0,r.jsx)(e.th,{children:"Description"}),(0,r.jsx)(e.th,{children:"Draft"}),(0,r.jsx)(e.th,{children:"Stable*"}),(0,r.jsx)(e.th,{children:"Effective"}),(0,r.jsx)(e.th,{children:"Deprecated*"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/iaas/scs-0100",children:"scs-0100"})}),(0,r.jsx)(e.td,{children:"SCS Flavor Naming Standard"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"v3"})}),(0,r.jsxs)(e.td,{children:[(0,r.jsx)(e.a,{href:"/standards/scs-0100-v1-flavor-naming",children:"v1"}),", ",(0,r.jsx)(e.a,{href:"/standards/scs-0100-v2-flavor-naming",children:"v2"})]})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{children:"Supplement: Implementation and Testing Notes"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0100-w1-flavor-naming-implementation-testing",children:"w1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/iaas/scs-0101",children:"scs-0101"})}),(0,r.jsx)(e.td,{children:"SCS Entropy"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0101-v1-entropy",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{}),(0,r.jsx)(e.td,{children:"Supplement: Implementation and Testing Notes"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0101-w1-entropy-implementation-testing",children:"w1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/iaas/scs-0102",children:"scs-0102"})}),(0,r.jsx)(e.td,{children:"SCS Image Metadata Standard"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0102-v1-image-metadata",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/iaas/scs-0103",children:"scs-0103"})}),(0,r.jsx)(e.td,{children:"SCS Standard Flavors and Properties"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0103-v1-standard-flavors",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/iaas/scs-0104",children:"scs-0104"})}),(0,r.jsx)(e.td,{children:"SCS Standard Images"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0104-v1-standard-images",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/iaas/scs-0110",children:"scs-0110"})}),(0,r.jsx)(e.td,{children:"SSD Flavors"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0110-v1-ssd-flavors",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/iaas/scs-0111",children:"scs-0111"})}),(0,r.jsx)(e.td,{children:"Decisions for the Volume Type Standard"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0111-v1-volume-type-decisions",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/iaas/scs-0113",children:"scs-0113"})}),(0,r.jsx)(e.td,{children:"Security Groups Decision Record"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0113-v1-security-groups-decision-record",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/iaas/scs-0114",children:"scs-0114"})}),(0,r.jsx)(e.td,{children:"Volume Type Standard"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0114-v1-volume-type-standard",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/iaas/scs-0115",children:"scs-0115"})}),(0,r.jsx)(e.td,{children:"Default Rules for Security Groups"}),(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0115-v1-default-rules-for-security-groups",children:"v1"})}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]})]})]})]})}function x(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,r.jsx)(e,{...s,children:(0,r.jsx)(h,{...s})}):h(s)}},28453:(s,e,d)=>{d.d(e,{R:()=>a,x:()=>i});var r=d(96540);const n={},t=r.createContext(n);function a(s){const e=r.useContext(t);return r.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function i(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:a(s.components),r.createElement(t.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/3ff13a62.f29e7019.js b/assets/js/3ff13a62.f29e7019.js new file mode 100644 index 0000000000..75f2c57cea --- /dev/null +++ b/assets/js/3ff13a62.f29e7019.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5743],{24712:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var r=t(74848),i=t(28453);const a={},o="Container Layer Introduction",s={id:"container/index",title:"Container Layer Introduction",description:"The container layer within the Sovereign Cloud Stack (SCS) offers a robust solution for managing container workloads on a Kubernetes infrastructure. It facilitates the on-demand creation and scaling of Kubernetes clusters, catering to various needs across development, testing, deployment, and operation of services and applications. While the container layer is versatile for a range of use cases, the most common ones include:",source:"@site/docs/03-container/index.md",sourceDirName:"03-container",slug:"/container/",permalink:"/docs/container/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/index.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Flavor Manager",permalink:"/docs/iaas/components/flavor-manager"},next:{title:"Components",permalink:"/docs/category/components-1"}},l={},c=[{value:"Target groups",id:"target-groups",level:2},{value:"What is it not",id:"what-is-it-not",level:2},{value:"Prerequisites and Requirements",id:"prerequisites-and-requirements",level:3},{value:"Features",id:"features",level:3},{value:"Limitations",id:"limitations",level:3},{value:"Current state and future Outlook",id:"current-state-and-future-outlook",level:3}];function d(e){const n={h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"container-layer-introduction",children:"Container Layer Introduction"}),"\n",(0,r.jsx)(n.p,{children:"The container layer within the Sovereign Cloud Stack (SCS) offers a robust solution for managing container workloads on a Kubernetes infrastructure. It facilitates the on-demand creation and scaling of Kubernetes clusters, catering to various needs across development, testing, deployment, and operation of services and applications. While the container layer is versatile for a range of use cases, the most common ones include:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Self-Service: Here, entities can empower their development teams with the autonomy to spawn and manage their clusters on demand, fostering a more agile and responsive development environment."}),"\n",(0,r.jsx)(n.li,{children:"KaaS (Kubernetes as a Service): In this model, an SCS Cloud provider can offer their customers a managed Kubernetes service, abstracting much of the underlying operational complexity from their customers."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"target-groups",children:"Target groups"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"DevOps/SysOps Teams: They are the primary beneficiaries as the container layer promotes flexible, on-demand operations helpful for continuous development, testing, deployment, and service management."}),"\n",(0,r.jsx)(n.li,{children:"Cloud Service Providers: By delivering a standardized container orchestration platform, they can provide more reliable and robust services to their customers, enhancing their product portfolio."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"what-is-it-not",children:"What is it not"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The container layer is not an alternative to Infrastructure as a Service (IaaS) but rather an extension that allows for more streamlined operation and management of containerized applications."}),"\n",(0,r.jsx)(n.li,{children:"Although the container layer doesn't directly support Serverless Containers or Functions as a Service, these can be run on a Kubernetes cluster. However, as of now, the SCS container layer doesn't offer specialized tools for these use cases."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"prerequisites-and-requirements",children:"Prerequisites and Requirements"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Knowledge: Familiarity with Kubernetes, container orchestration, and basic cloud infrastructure principles is pivotal."}),"\n",(0,r.jsx)(n.li,{children:"Software: The core software component is the K8s Cluster API Provider, crafted to function optimally on OpenStack environments. Although designed to run on the SCS IaaS layer, with minor configuration adjustments, it can operate on any OpenStack environment."}),"\n",(0,r.jsx)(n.li,{children:"Hardware: Virtualization-enabled hardware capable of running OpenStack is essential if hosting the IaaS layer independently. For further details, refer to the IaaS layer documentation."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"features",children:"Features"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Automated Cluster Management: The K8s Cluster API Provider automates the process of creating, scaling, managing and updating Kubernetes clusters, thus significantly reducing the operational overhead."}),"\n",(0,r.jsx)(n.li,{children:"Standardized Operations: Upholding SCS standards across various clusters ensures operational consistency and reliability."}),"\n",(0,r.jsx)(n.li,{children:"Integration with OpenStack: The K8s Cluster API Provider is tailored to work seamlessly with SCS IaaS (OpenStack), thus offering a unified platform for managing both containers and the underlying infrastructure."}),"\n",(0,r.jsx)(n.li,{children:"Container Registry Integration: The container layer has an integrated container registry, facilitating easy management and deployment of container images."}),"\n",(0,r.jsx)(n.li,{children:"Certificate Managment: The kubernetes clusters can optionaly include a certbot allowing for ease of deployment of public facing services out of the box."}),"\n",(0,r.jsx)(n.li,{children:"Preconfigured ingress: Certificate Management: Optional inclusion of Certbot in Kubernetes clusters facilitates straightforward deployment of publicly accessible services.\nPreconfigured Ingress: Kubernetes clusters come with a preconfigured Nginx ingress, designed with OpenStack in mind, providing a ready-to-use ingress solution with enhancements like out-of-the-box client source IP visibility."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"limitations",children:"Limitations"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"OpenStack Dependency: The current design primarily supports OpenStack environments, which could be a limitation for other infrastructure setups."}),"\n",(0,r.jsx)(n.li,{children:"Serverless/Functions as a Service Support: Lack of direct support for serverless containers and Functions as a Service (FaaS) might require additional tools or platforms."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"current-state-and-future-outlook",children:"Current state and future Outlook"}),"\n",(0,r.jsx)(n.p,{children:"The container layer has matured with multiple cloud providers now offering Kubernetes as a Service using this layer to manage a multitude of clusters. It follows a half-yearly release schedule to ensure security and up-to-date Kubernetes clusters, alongside providing backports for significant features into older versions."}),"\n",(0,r.jsx)(n.p,{children:"Looking ahead, a new version based on ClusterStacks is in the pipeline, currently in its Alpha state. This upcoming release aims to be backward compatible, facilitating smooth migration from existing setups, and further extending the capabilities of the SCS container layer."})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>s});var r=t(96540);const i={},a=r.createContext(i);function o(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4.61d292cf.js b/assets/js/4.61d292cf.js new file mode 100644 index 0000000000..c1fd497565 --- /dev/null +++ b/assets/js/4.61d292cf.js @@ -0,0 +1,26180 @@ +"use strict"; +exports.id = 4; +exports.ids = [4]; +exports.modules = { + +/***/ 21176: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Zp: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(5664); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(74722); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(91395); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(697); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.A(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.A( + map/* default */.A(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.A(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.A(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.T(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.A(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.A(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.A(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.A(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.A(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.A('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.A(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.A(g.outEdges(v), function (e) { + if (has/* default */.A(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.A(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.A(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(98879); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(81942); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(23068); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.A)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(52528); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.A)(iteratee, 3); + + (0,_baseForOwn/* default */.A)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.A)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(41917); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.A.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.A(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.T().setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.T({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.A(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.A(range/* default */.A(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.A(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.A(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.A(layers, function (vs, i) { + if (isUndefined/* default */.A(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.A(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.A(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.A(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.A(children, dfs); + } + + if (has/* default */.A(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.A(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.A(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, reverseYOne); + if (has/* default */.A(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, swapXYOne); + if (has/* default */.A(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.A(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.A)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.A(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.A(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.A(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.T({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.A(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.A(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.A(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.A)(collection)) { + var iteratee = (0,_baseIteratee/* default */.A)(predicate, 3); + collection = (0,keys/* default */.A)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.A)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.A)(array, (0,_baseIteratee/* default */.A)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(69471); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(88496); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.A)(value) && (0,isObjectLike/* default */.A)(value) && (0,_baseGetTag/* default */.A)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.A)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.A)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.A)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.A)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.A(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.A(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.A(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.A(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.A(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.A(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.A(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.A(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(73046); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.A(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.A(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.A(tree.neighbors(v), function (w) { + if (!has/* default */.A(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.A(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.A(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.A(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.A(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.A(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.A(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.A(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.A(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.A( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(91641); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.A)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.A(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.T({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.A(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.A(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.A(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.A('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.A); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(52568); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.A)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.A)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + if ((0,isArray/* default */.A)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.A)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.A]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.A)(iteratees, (0,_baseUnary/* default */.A)(_baseIteratee/* default */.A)); + + var result = (0,_baseMap/* default */.A)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.A)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.A)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.A)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.A)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.A(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.A( + map/* default */.A(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.A(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.A(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.A( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.A(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.A(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.A(range/* default */.A(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.A(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.A(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.A(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.A(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.A( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.A(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.A(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.A(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.A(entryV) && !isUndefined/* default */.A(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.A(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.A(uEntry.barycenter) || + isUndefined/* default */.A(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.A(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.A(entry.out, handleOut(entry)); + } + + return map/* default */.A( + filter/* default */.A(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.A(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.A(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.A(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.A(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.A(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.A(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.A(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.A([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.A(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.A(entries, function (entry) { + entry.vs = flatten/* default */.A( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.A(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.A(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.A(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.A(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.T(); + forEach/* default */.A(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.A(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.A(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.A(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(99922); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(4574); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee), keysIn/* default */.A); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.A(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.A(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.A(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.A(range/* default */.A(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.A(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.A(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.A(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.A(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.A(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.A(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.T(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.A(layering, function (layer) { + var u; + forEach/* default */.A(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.A(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.A(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.A(['u', 'd'], function (vert) { + forEach/* default */.A(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.A(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.A(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.A(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.A(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.A(layering).reverse(); + forEach/* default */.A(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.A(adjustedLayering, function (inner) { + return values/* default */.A(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.A(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.A(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.A(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.A(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.A(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.A(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.A(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.T({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.A({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.A(graph, graphAttrs)) + ); + + forEach/* default */.A(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.A(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.A({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.A(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.A(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.A(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.A(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.A(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.A(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.A(layers, function (layer) { + var orderShift = 0; + forEach/* default */.A(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.A(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.A(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.A(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 73046: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + T: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(89610); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(66401); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.A)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(39857); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.A && (1 / (0,_setToArray/* default */.A)(new _Set/* default */.A([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.A(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.A)(set); + } + isCommon = false; + includes = _cacheHas/* default */.A; + seen = new _SetCache/* default */.A; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(53533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.A)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.A)(arrays, 1, isArrayLikeObject/* default */.A, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.A(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.A(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.A(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.A(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.A(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.A(this._nodes); + } + sources() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.A(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.A(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.A(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.A(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.A(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.A(keys/* default */.A(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.A(keys/* default */.A(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.A(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.A(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.A(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.A(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.A(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.A(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.A(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.A(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.A(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.A(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.A(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.A(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.A(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.A(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.A(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.A(inV); + if (!u) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.A(outV); + if (!w) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.A(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 697: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ T: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.T) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 14075: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ M: () => (/* binding */ write) +/* harmony export */ }); +/* unused harmony export read */ +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69592); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(50053); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74722); +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); + + + + + +function write(g) { + var json = { + options: { + directed: g.isDirected(), + multigraph: g.isMultigraph(), + compound: g.isCompound(), + }, + nodes: writeNodes(g), + edges: writeEdges(g), + }; + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(g.graph())) { + json.value = lodash_es__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A(g.graph()); + } + return json; +} + +function writeNodes(g) { + return lodash_es__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A(g.nodes(), function (v) { + var nodeValue = g.node(v); + var parent = g.parent(v); + var node = { v: v }; + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(nodeValue)) { + node.value = nodeValue; + } + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(parent)) { + node.parent = parent; + } + return node; + }); +} + +function writeEdges(g) { + return lodash_es__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A(g.edges(), function (e) { + var edgeValue = g.edge(e); + var edge = { v: e.v, w: e.w }; + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(e.name)) { + edge.name = e.name; + } + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(edgeValue)) { + edge.value = edgeValue; + } + return edge; + }); +} + +function read(json) { + var g = new Graph(json.options).setGraph(json.value); + _.each(json.nodes, function (entry) { + g.setNode(entry.v, entry.value); + if (entry.parent) { + g.setParent(entry.v, entry.parent); + } + }); + _.each(json.edges, function (entry) { + g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value); + }); + return g; +} + + +/***/ }), + +/***/ 62062: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(29471); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.A; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 72641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 2634: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 45572: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 76912: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 91641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(72641); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(22031); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keys/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keysIn/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(80154); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(39759); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(14792); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.A)(source, (0,_getSymbols/* default */.A)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(15647); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(13153); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.A : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.A)(result, (0,_getSymbols/* default */.A)(object)); + object = (0,_getPrototype/* default */.A)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.A)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(33831); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.A)(object, keysIn/* default */.A, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(90565); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.A)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(1801); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.A)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.A)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(18598); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(64841); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.A)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.A)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.A)(value)) { + return value; + } + var isArr = (0,isArray/* default */.A)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.A)(value, result); + } + } else { + var tag = (0,_getTag/* default */.A)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.A)(value)) { + return (0,_cloneBuffer/* default */.A)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.A)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.A); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.A) + : (isFlat ? keysIn/* default */.A : keys/* default */.A); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.A)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.A)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 6240: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.A)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.A); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 25707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 13588: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(52274); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.A ? _Symbol/* default */.A.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.A)(value) || (0,isArguments/* default */.A)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.A)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 79841: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4574); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 66318: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 33831: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76912); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 49574: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.A : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.A)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(43988); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(66984); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.A(object), new _Uint8Array/* default */.A(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.A)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.A); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.A)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.A)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(33858); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.A)(object), + othIsArr = (0,isArray/* default */.A)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.A)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.A)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.A)(object)) { + if (!(0,isBuffer/* default */.A)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.A); + return (objIsArr || (0,isTypedArray/* default */.A)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.A); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.A); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.A)(value) && !(0,isObjectLike/* default */.A)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.A; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.A)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.A)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.A)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.A)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.A)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.A)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.A)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.A)(path) ? (0,_baseProperty/* default */.A)((0,_toKey/* default */.A)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.A; + } + if (typeof value == 'object') { + return (0,isArray/* default */.A)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 52568: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6240); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 70805: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 64099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 99922: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(29008); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 7819: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(46632); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.A)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(28894); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.A)(value)) { + return value; + } + return (0,_isKey/* default */.A)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.A)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 19042: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33831); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14792); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 14792: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2634); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13153); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 85054: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(52274); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(92049); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25353); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5254); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 86586: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(61882); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 29959: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 30901: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61882); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 50053: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseClone_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(91641); + + +/** Used to compose bitmasks for cloning. */ +var CLONE_SYMBOLS_FLAG = 4; + +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return (0,_baseClone_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value, CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (clone); + + +/***/ }), + +/***/ 23068: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(24326); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66984); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6832); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55615); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 11662: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(2634); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.A)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.A)(collection) ? _arrayFilter/* default */.A : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.A)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 34098: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13588); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 8058: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72641); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6240); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99922); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 48585: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 39188: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 61882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(88496); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(53098); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 69592: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 27422: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(83607); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69471); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 74722: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(45572); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49574); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(52568); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 81942: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(7819); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(25353); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.A)(object)) { + return object; + } + path = (0,_castPath/* default */.A)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.A)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.A)(objValue) + ? objValue + : ((0,_isIndex/* default */.A)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.A)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.A)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.A)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.A)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(76875); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(67525); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.A)((0,_overRest/* default */.A)(func, undefined, flatten/* default */.A), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 91395: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.A)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.A)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.A)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.A)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 89463: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.A)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.A)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.A); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 13153: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 74342: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.A)(value)) { + return NAN; + } + if ((0,isObject/* default */.A)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.A)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 28894: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.A)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.A)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.A)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 5664: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28894); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 38207: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.A)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.A)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 4: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _styles_991ebdfc_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(27308); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(697); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(76257); +/* harmony import */ var _index_fc10efb0_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(92746); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(99418); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(21176); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(14075); + + + + + + + + + + + + + + + + + + + +const sanitizeText = (txt) => _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.e.sanitizeText(txt, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)()); +let conf = { + dividerMargin: 10, + padding: 5, + textHeight: 10, + curve: void 0 +}; +const addNamespaces = function(namespaces, g, _id, diagObj) { + const keys = Object.keys(namespaces); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.info("keys:", keys); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.info(namespaces); + keys.forEach(function(id) { + var _a, _b; + const vertex = namespaces[id]; + const shape = "rect"; + const node = { + shape, + id: vertex.id, + domId: vertex.domId, + labelText: sanitizeText(vertex.id), + labelStyle: "", + style: "fill: none; stroke: black", + // TODO V10: Flowchart ? Keeping flowchart for backwards compatibility. Remove in next major release + padding: ((_a = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().flowchart) == null ? void 0 : _a.padding) ?? ((_b = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().class) == null ? void 0 : _b.padding) + }; + g.setNode(vertex.id, node); + addClasses(vertex.classes, g, _id, diagObj, vertex.id); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.info("setNode", node); + }); +}; +const addClasses = function(classes, g, _id, diagObj, parent) { + const keys = Object.keys(classes); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.info("keys:", keys); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.info(classes); + keys.filter((id) => classes[id].parent == parent).forEach(function(id) { + var _a, _b; + const vertex = classes[id]; + const cssClassStr = vertex.cssClasses.join(" "); + const styles2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.k)(vertex.styles); + const vertexText = vertex.label ?? vertex.id; + const radius = 0; + const shape = "class_box"; + const node = { + labelStyle: styles2.labelStyle, + shape, + labelText: sanitizeText(vertexText), + classData: vertex, + rx: radius, + ry: radius, + class: cssClassStr, + style: styles2.style, + id: vertex.id, + domId: vertex.domId, + tooltip: diagObj.db.getTooltip(vertex.id, parent) || "", + haveCallback: vertex.haveCallback, + link: vertex.link, + width: vertex.type === "group" ? 500 : void 0, + type: vertex.type, + // TODO V10: Flowchart ? Keeping flowchart for backwards compatibility. Remove in next major release + padding: ((_a = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().flowchart) == null ? void 0 : _a.padding) ?? ((_b = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().class) == null ? void 0 : _b.padding) + }; + g.setNode(vertex.id, node); + if (parent) { + g.setParent(vertex.id, parent); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.info("setNode", node); + }); +}; +const addNotes = function(notes, g, startEdgeId, classes) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.info(notes); + notes.forEach(function(note, i) { + var _a, _b; + const vertex = note; + const cssNoteStr = ""; + const styles2 = { labelStyle: "", style: "" }; + const vertexText = vertex.text; + const radius = 0; + const shape = "note"; + const node = { + labelStyle: styles2.labelStyle, + shape, + labelText: sanitizeText(vertexText), + noteData: vertex, + rx: radius, + ry: radius, + class: cssNoteStr, + style: styles2.style, + id: vertex.id, + domId: vertex.id, + tooltip: "", + type: "note", + // TODO V10: Flowchart ? Keeping flowchart for backwards compatibility. Remove in next major release + padding: ((_a = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().flowchart) == null ? void 0 : _a.padding) ?? ((_b = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().class) == null ? void 0 : _b.padding) + }; + g.setNode(vertex.id, node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.info("setNode", node); + if (!vertex.class || !(vertex.class in classes)) { + return; + } + const edgeId = startEdgeId + i; + const edgeData = { + id: `edgeNote${edgeId}`, + //Set relationship style and line type + classes: "relation", + pattern: "dotted", + // Set link type for rendering + arrowhead: "none", + //Set edge extra labels + startLabelRight: "", + endLabelLeft: "", + //Set relation arrow types + arrowTypeStart: "none", + arrowTypeEnd: "none", + style: "fill:none", + labelStyle: "", + curve: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.n)(conf.curve, d3__WEBPACK_IMPORTED_MODULE_0__/* .curveLinear */ .lUB) + }; + g.setEdge(vertex.id, vertex.class, edgeData, edgeId); + }); +}; +const addRelations = function(relations, g) { + const conf2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().flowchart; + let cnt = 0; + relations.forEach(function(edge) { + var _a; + cnt++; + const edgeData = { + //Set relationship style and line type + classes: "relation", + pattern: edge.relation.lineType == 1 ? "dashed" : "solid", + id: `id_${edge.id1}_${edge.id2}_${cnt}`, + // Set link type for rendering + arrowhead: edge.type === "arrow_open" ? "none" : "normal", + //Set edge extra labels + startLabelRight: edge.relationTitle1 === "none" ? "" : edge.relationTitle1, + endLabelLeft: edge.relationTitle2 === "none" ? "" : edge.relationTitle2, + //Set relation arrow types + arrowTypeStart: getArrowMarker(edge.relation.type1), + arrowTypeEnd: getArrowMarker(edge.relation.type2), + style: "fill:none", + labelStyle: "", + curve: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.n)(conf2 == null ? void 0 : conf2.curve, d3__WEBPACK_IMPORTED_MODULE_0__/* .curveLinear */ .lUB) + }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.info(edgeData, edge); + if (edge.style !== void 0) { + const styles2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.k)(edge.style); + edgeData.style = styles2.style; + edgeData.labelStyle = styles2.labelStyle; + } + edge.text = edge.title; + if (edge.text === void 0) { + if (edge.style !== void 0) { + edgeData.arrowheadStyle = "fill: #333"; + } + } else { + edgeData.arrowheadStyle = "fill: #333"; + edgeData.labelpos = "c"; + if (((_a = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().flowchart) == null ? void 0 : _a.htmlLabels) ?? (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().htmlLabels) { + edgeData.labelType = "html"; + edgeData.label = '<span class="edgeLabel">' + edge.text + "</span>"; + } else { + edgeData.labelType = "text"; + edgeData.label = edge.text.replace(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.e.lineBreakRegex, "\n"); + if (edge.style === void 0) { + edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none"; + } + edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:"); + } + } + g.setEdge(edge.id1, edge.id2, edgeData, cnt); + }); +}; +const setConf = function(cnf) { + conf = { + ...conf, + ...cnf + }; +}; +const draw = async function(text, id, _version, diagObj) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.info("Drawing class - ", id); + const conf2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().flowchart ?? (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().class; + const securityLevel = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().securityLevel; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.info("config:", conf2); + const nodeSpacing = (conf2 == null ? void 0 : conf2.nodeSpacing) ?? 50; + const rankSpacing = (conf2 == null ? void 0 : conf2.rankSpacing) ?? 50; + const g = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_1__/* .Graph */ .T({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: diagObj.db.getDirection(), + nodesep: nodeSpacing, + ranksep: rankSpacing, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + const namespaces = diagObj.db.getNamespaces(); + const classes = diagObj.db.getClasses(); + const relations = diagObj.db.getRelations(); + const notes = diagObj.db.getNotes(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.info(relations); + addNamespaces(namespaces, g, id, diagObj); + addClasses(classes, g, id, diagObj); + addRelations(relations, g); + addNotes(notes, g, relations.length + 1, classes); + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body"); + const svg = root.select(`[id="${id}"]`); + const element = root.select("#" + id + " g"); + await (0,_index_fc10efb0_js__WEBPACK_IMPORTED_MODULE_8__.r)( + element, + g, + ["aggregation", "extension", "composition", "dependency", "lollipop"], + "classDiagram", + id + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.u.insertTitle(svg, "classTitleText", (conf2 == null ? void 0 : conf2.titleTopMargin) ?? 5, diagObj.db.getDiagramTitle()); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.o)(g, svg, conf2 == null ? void 0 : conf2.diagramPadding, conf2 == null ? void 0 : conf2.useMaxWidth); + if (!(conf2 == null ? void 0 : conf2.htmlLabels)) { + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); + for (const label of labels) { + const dim = label.getBBox(); + const rect = doc.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.setAttribute("rx", 0); + rect.setAttribute("ry", 0); + rect.setAttribute("width", dim.width); + rect.setAttribute("height", dim.height); + label.insertBefore(rect, label.firstChild); + } + } +}; +function getArrowMarker(type) { + let marker; + switch (type) { + case 0: + marker = "aggregation"; + break; + case 1: + marker = "extension"; + break; + case 2: + marker = "composition"; + break; + case 3: + marker = "dependency"; + break; + case 4: + marker = "lollipop"; + break; + default: + marker = "none"; + } + return marker; +} +const renderer = { + setConf, + draw +}; +const diagram = { + parser: _styles_991ebdfc_js__WEBPACK_IMPORTED_MODULE_9__.p, + db: _styles_991ebdfc_js__WEBPACK_IMPORTED_MODULE_9__.d, + renderer, + styles: _styles_991ebdfc_js__WEBPACK_IMPORTED_MODULE_9__.s, + init: (cnf) => { + if (!cnf.class) { + cnf.class = {}; + } + cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + _styles_991ebdfc_js__WEBPACK_IMPORTED_MODULE_9__.d.clear(); + } +}; + + + +/***/ }), + +/***/ 40351: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-f47111a7.js + 8 modules +var mermaid_f47111a7 = __webpack_require__(76257); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array<unknown>} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array<string>} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array<T>} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array<unknown>} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {Array<T>} items + * Items to add to `list`. + * @returns {Array<T>} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array<Extension>} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record<string, unknown>} */ + const left = maybe || (all[hook] = {}) + /** @type {Record<string, unknown> | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array<unknown>} existing + * @param {Array<unknown>} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array<unknown>} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array<HtmlExtension>} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array<StackItem>} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array<Event>} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record<string, number>} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array<Event>} */ + let parameters + /** @type {Array<Event>} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array<Event>} events + * @param {number} eventIndex + * @returns {Record<string, number>} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array<number>} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record<string, number>} */ + const gaps = {} + /** @type {Array<Chunk>} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array<Event>} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array<Event>} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array<Resolver>} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit<Point, '_bufferIndex' | '_index'> | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record<string, number>} */ + const columnStart = {} + /** @type {Array<Construct>} */ + const resolveAllConstructs = [] + /** @type {Array<Chunk>} */ + let chunks = [] + /** @type {Array<Token>} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array<Construct> | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array<Construct>} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array<Construct>} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array<Chunk>} chunks + * @param {Pick<Token, 'end' | 'start'>} token + * @returns {Array<Chunk>} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array<Chunk>} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array<Chunk>} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array<string>} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * <a> + * <a\>b> + * <a b> + * <a)> + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`<a>` or `b`). + * @param {TokenType} literalType + * Type when enclosed (`<a>`). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | <aa> + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | <a\*a> + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | <x /> + * ^ + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<!-`, inside a comment, at another `-`. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<![`, inside CDATA, expecting `CDATA[`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | </x> + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | <ab> + * ^^ + * > | </ab> + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > | <div/> + * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | <x/> + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | <a /> + * ^ + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * > | <a > + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | <a b> + * ^ + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | <a b=c> + * ^ + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | <a b="c"> + * ^ + * > | <a b='c'> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | <x> + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | <x> + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after `</`, in a raw tag name. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | <!--> + * ^ + * > | <?> + * ^ + * > | <!q> + * ^ + * > | <!--ab--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > | <div> + * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record<string, string>} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array<Event>} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + * <p>!<a href=\"b\">^a</a></p> + * <p>!<a href=\"c\">^a</a></p> + * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array<Event>} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | a<user.name@ex-ample.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code> | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a <b> c + * ^ + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * > | a <![CDATA[>&<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after `<!-`, at another `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After `<![`, in CDATA, expecting `CDATA[`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a <!b> c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After `</x`, in a tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After `<x`, in opening tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a <!--a + * ^ + * | b--> + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array<Chunk>} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array<Chunk>} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array<Event>} events + * @returns {Array<Event>} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract<Node, UnistParent>} Parent + * + * @typedef {Omit<UnistParent, 'type' | 'children'> & {type: 'fragment', children: Array<PhrasingContent>}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record<string, Handle>} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array<string>} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array<Transform>} transforms + * Tree transforms. + * + * @typedef {Partial<Config>} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array<Node | Fragment>} stack + * Stack of nodes. + * @property {Array<TokenTuple>} tokenStack + * Stack of tokens. + * @property {<Key extends keyof CompileData>(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {<Key extends keyof CompileData>(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {<Kind extends Node>(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array<Extension | Array<Extension>> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array<Event>} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit<CompileContext, 'sliceSerialize'>} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array<number>} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array<Event>} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array<StaticPhrasingContent>} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array<Extension | Array<Extension>>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(60513); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-6b48ae7d.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.T)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "<br/>"); + } else if (node.type === "strong") { + return `<strong>${node.children.map(output).join("")}</strong>`; + } else if (node.type === "emphasis") { + return `<em>${node.children.map(output).join("")}</em>`; + } else if (node.type === "paragraph") { + return `<p>${node.children.map(output).join("")}</p>`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + <span class="${labelClass} ${classes}" ` + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_f47111a7.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_f47111a7.M)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `<i class='${s.replace(":", " ")}'></i>` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 28747: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ insertMarkers$1), +/* harmony export */ b: () => (/* binding */ clear$1), +/* harmony export */ c: () => (/* binding */ createLabel$1), +/* harmony export */ d: () => (/* binding */ clear), +/* harmony export */ e: () => (/* binding */ insertNode), +/* harmony export */ f: () => (/* binding */ insertEdgeLabel), +/* harmony export */ g: () => (/* binding */ getSubGraphTitleMargins), +/* harmony export */ h: () => (/* binding */ insertEdge), +/* harmony export */ i: () => (/* binding */ intersectRect$1), +/* harmony export */ j: () => (/* binding */ positionEdgeLabel), +/* harmony export */ k: () => (/* binding */ getLineFunctionsWithOffset), +/* harmony export */ l: () => (/* binding */ labelHelper), +/* harmony export */ m: () => (/* binding */ addEdgeMarkers), +/* harmony export */ p: () => (/* binding */ positionNode), +/* harmony export */ s: () => (/* binding */ setNodeElem), +/* harmony export */ u: () => (/* binding */ updateNodeBounds) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(40351); + + + +const insertMarkers = (elem, markerArray, type, id) => { + markerArray.forEach((markerName) => { + markers[markerName](elem, type, id); + }); +}; +const extension = (elem, type, id) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Making markers for ", id); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); +}; +const composition = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const aggregation = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const dependency = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 6).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const lollipop = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopEnd").attr("class", "marker lollipop " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); +}; +const point = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 6).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 4.5).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const circle$1 = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const cross = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); +}; +const barb = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const markers = { + extension, + composition, + aggregation, + dependency, + lollipop, + point, + circle: circle$1, + cross, + barb +}; +const insertMarkers$1 = insertMarkers; +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlLabel(node) { + const fo = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + '<span class="' + labelClass + '" ' + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>" + ); + applyStyle(div, node.labelStyle); + div.style("display", "inline-block"); + div.style("white-space", "nowrap"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + return fo.node(); +} +const createLabel = (_vertexText, style, isTitle, isNode) => { + let vertexText = _vertexText || ""; + if (typeof vertexText === "object") { + vertexText = vertexText[0]; + } + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + vertexText = vertexText.replace(/\\n|\n/g, "<br />"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("vertexText" + vertexText); + const node = { + isNode, + label: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(vertexText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `<i class='${s.replace(":", " ")}'></i>` + ), + labelStyle: style.replace("fill:", "color:") + }; + let vertexNode = addHtmlLabel(node); + return vertexNode; + } else { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", style.replace("color:", "fill:")); + let rows = []; + if (typeof vertexText === "string") { + rows = vertexText.split(/\\n|\n|<br\s*\/?>/gi); + } else if (Array.isArray(vertexText)) { + rows = vertexText; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + if (isTitle) { + tspan.setAttribute("class", "title-row"); + } else { + tspan.setAttribute("class", "row"); + } + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; + } +}; +const createLabel$1 = createLabel; +const labelHelper = async (parent, node, _classes, isNode) => { + let classes; + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + if (!_classes) { + classes = "node default"; + } else { + classes = _classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle); + let labelText; + if (node.labelText === void 0) { + labelText = ""; + } else { + labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0]; + } + const textNode = label.node(); + let text; + if (node.labelType === "markdown") { + text = (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__.a)(label, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(labelText), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()), { + useHtmlLabels, + width: node.width || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.wrappingWidth, + classes: "markdown-node-label" + }); + } else { + text = textNode.appendChild( + createLabel$1( + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(labelText), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()), + node.labelStyle, + false, + isNode + ) + ); + } + let bbox = text.getBBox(); + const halfPadding = node.padding / 2; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text); + const images = div.getElementsByTagName("img"); + if (images) { + const noImgText = labelText.replace(/<img[^>]*>/g, "").trim() === ""; + await Promise.all( + [...images].map( + (img) => new Promise((res) => { + function setupImage() { + img.style.display = "flex"; + img.style.flexDirection = "column"; + if (noImgText) { + const bodyFontSize = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize ? (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize : window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + const width = parseInt(bodyFontSize, 10) * enlargingFactor + "px"; + img.style.minWidth = width; + img.style.maxWidth = width; + } else { + img.style.width = "100%"; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener("error", setupImage); + img.addEventListener("load", setupImage); + }) + ) + ); + } + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (useHtmlLabels) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } else { + label.attr("transform", "translate(0, " + -bbox.height / 2 + ")"); + } + if (node.centerLabel) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } + label.insert("rect", ":first-child"); + return { shapeSvg, bbox, halfPadding, label }; +}; +const updateNodeBounds = (node, element) => { + const bbox = element.node().getBBox(); + node.width = bbox.width; + node.height = bbox.height; +}; +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +function intersectNode(node, point2) { + return node.intersect(point2); +} +function intersectEllipse(node, rx, ry, point2) { + var cx = node.x; + var cy = node.y; + var px = cx - point2.x; + var py = cy - point2.y; + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + var dx = Math.abs(rx * ry * px / det); + if (point2.x < cx) { + dx = -dx; + } + var dy = Math.abs(rx * ry * py / det); + if (point2.y < cy) { + dy = -dy; + } + return { x: cx + dx, y: cy + dy }; +} +function intersectCircle(node, rx, point2) { + return intersectEllipse(node, rx, rx, point2); +} +function intersectLine(p1, p2, q1, q2) { + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return; + } + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return; + } + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return; + } + offset = Math.abs(denom / 2); + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + return { x, y }; +} +function sameSign(r1, r2) { + return r1 * r2 > 0; +} +function intersectPolygon(node, polyPoints, point2) { + var x1 = node.x; + var y1 = node.y; + var intersections = []; + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + if (typeof polyPoints.forEach === "function") { + polyPoints.forEach(function(entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + } else { + minX = Math.min(minX, polyPoints.x); + minY = Math.min(minY, polyPoints.y); + } + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect2 = intersectLine( + node, + point2, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect2) { + intersections.push(intersect2); + } + } + if (!intersections.length) { + return node; + } + if (intersections.length > 1) { + intersections.sort(function(p, q) { + var pdx = p.x - point2.x; + var pdy = p.y - point2.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + var qdx = q.x - point2.x; + var qdy = q.y - point2.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} +const intersectRect = (node, point2) => { + var x = node.x; + var y = node.y; + var dx = point2.x - x; + var dy = point2.y - y; + var w = node.width / 2; + var h = node.height / 2; + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : h * dx / dy; + sy = h; + } else { + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : w * dy / dx; + } + return { x: x + sx, y: y + sy }; +}; +const intersectRect$1 = intersectRect; +const intersect = { + node: intersectNode, + circle: intersectCircle, + ellipse: intersectEllipse, + polygon: intersectPolygon, + rect: intersectRect$1 +}; +const note = async (parent, node) => { + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels; + if (!useHtmlLabels) { + node.centerLabel = true; + } + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Classes = ", node.classes); + const rect2 = shapeSvg.insert("rect", ":first-child"); + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const note$1 = note; +const expandAndDeduplicateDirections = (directions) => { + const uniqueDirections = /* @__PURE__ */ new Set(); + for (const direction of directions) { + switch (direction) { + case "x": + uniqueDirections.add("right"); + uniqueDirections.add("left"); + break; + case "y": + uniqueDirections.add("up"); + uniqueDirections.add("down"); + break; + default: + uniqueDirections.add(direction); + break; + } + } + return uniqueDirections; +}; +const getArrowPoints = (duplicatedDirections, bbox, node) => { + const directions = expandAndDeduplicateDirections(duplicatedDirections); + const f = 2; + const height = bbox.height + 2 * node.padding; + const midpoint = height / f; + const width = bbox.width + 2 * midpoint + node.padding; + const padding = node.padding / 2; + if (directions.has("right") && directions.has("left") && directions.has("up") && directions.has("down")) { + return [ + // Bottom + { x: 0, y: 0 }, + { x: midpoint, y: 0 }, + { x: width / 2, y: 2 * padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: 0 }, + // Right + { x: width, y: -height / 3 }, + { x: width + 2 * padding, y: -height / 2 }, + { x: width, y: -2 * height / 3 }, + { x: width, y: -height }, + // Top + { x: width - midpoint, y: -height }, + { x: width / 2, y: -height - 2 * padding }, + { x: midpoint, y: -height }, + // Left + { x: 0, y: -height }, + { x: 0, y: -2 * height / 3 }, + { x: -2 * padding, y: -height / 2 }, + { x: 0, y: -height / 3 } + ]; + } + if (directions.has("right") && directions.has("left") && directions.has("up")) { + return [ + { x: midpoint, y: 0 }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("right") && directions.has("left") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: midpoint, y: -height }, + { x: width - midpoint, y: -height }, + { x: width, y: 0 } + ]; + } + if (directions.has("right") && directions.has("up") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: width, y: -midpoint }, + { x: width, y: -height + midpoint }, + { x: 0, y: -height } + ]; + } + if (directions.has("left") && directions.has("up") && directions.has("down")) { + return [ + { x: width, y: 0 }, + { x: 0, y: -midpoint }, + { x: 0, y: -height + midpoint }, + { x: width, y: -height } + ]; + } + if (directions.has("right") && directions.has("left")) { + return [ + { x: midpoint, y: 0 }, + { x: midpoint, y: -padding }, + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: width - midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("up") && directions.has("down")) { + return [ + // Bottom center + { x: width / 2, y: 0 }, + // Left pont of bottom arrow + { x: 0, y: -padding }, + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: 0, y: -height + padding }, + // Top of arrow + { x: width / 2, y: -height }, + { x: width, y: -height + padding }, + // Top of right vertical bar + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding }, + { x: width, y: -padding } + ]; + } + if (directions.has("right") && directions.has("up")) { + return [ + { x: 0, y: 0 }, + { x: width, y: -midpoint }, + { x: 0, y: -height } + ]; + } + if (directions.has("right") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: width, y: 0 }, + { x: 0, y: -height } + ]; + } + if (directions.has("left") && directions.has("up")) { + return [ + { x: width, y: 0 }, + { x: 0, y: -midpoint }, + { x: width, y: -height } + ]; + } + if (directions.has("left") && directions.has("down")) { + return [ + { x: width, y: 0 }, + { x: 0, y: 0 }, + { x: width, y: -height } + ]; + } + if (directions.has("right")) { + return [ + { x: midpoint, y: -padding }, + { x: midpoint, y: -padding }, + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: width - midpoint, y: -height + padding }, + // top left corner of arrow + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding } + ]; + } + if (directions.has("left")) { + return [ + { x: midpoint, y: 0 }, + { x: midpoint, y: -padding }, + // Two points, the right corners + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("up")) { + return [ + // Bottom center + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: 0, y: -height + padding }, + // Top of arrow + { x: width / 2, y: -height }, + { x: width, y: -height + padding }, + // Top of right vertical bar + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding } + ]; + } + if (directions.has("down")) { + return [ + // Bottom center + { x: width / 2, y: 0 }, + // Left pont of bottom arrow + { x: 0, y: -padding }, + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding }, + { x: width, y: -padding } + ]; + } + return [{ x: 0, y: 0 }]; +}; +const formatClass = (str) => { + if (str) { + return " " + str; + } + return ""; +}; +const getClassesFromNode = (node, otherClasses) => { + return `${otherClasses ? otherClasses : "node default"}${formatClass(node.classes)} ${formatClass( + node.class + )}`; +}; +const question = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const s = w + h; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Question main (Circle)"); + const questionElem = insertPolygonShape(shapeSvg, s, s, points); + questionElem.attr("style", node.style); + updateNodeBounds(node, questionElem); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("Intersect called"); + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const choice = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const s = 28; + const points = [ + { x: 0, y: s / 2 }, + { x: s / 2, y: 0 }, + { x: 0, y: -s / 2 }, + { x: -s / 2, y: 0 } + ]; + const choice2 = shapeSvg.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ); + choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28); + node.width = 28; + node.height = 28; + node.intersect = function(point2) { + return intersect.circle(node, 14, point2); + }; + return shapeSvg; +}; +const hexagon = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const f = 4; + const h = bbox.height + node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const hex = insertPolygonShape(shapeSvg, w, h, points); + hex.attr("style", node.style); + updateNodeBounds(node, hex); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const block_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true); + const f = 2; + const h = bbox.height + 2 * node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = getArrowPoints(node.directions, bbox, node); + const blockArrow = insertPolygonShape(shapeSvg, w, h, points); + blockArrow.attr("style", node.style); + updateNodeBounds(node, blockArrow); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_left_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + node.width = w + h; + node.height = h; + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_right = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_left = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const inv_trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_right_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const cylinder = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry + node.padding; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const el = shapeSvg.attr("label-offset-y", ry).insert("path", ":first-child").attr("style", node.style).attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + updateNodeBounds(node, el); + node.intersect = function(point2) { + const pos = intersect.rect(node, point2); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point2.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +}; +const rect = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes + " " + node.class, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding; + const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding; + rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const composite = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding; + const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding; + rect2.attr("class", "basic cluster composite label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const labelRect = async (parent, node) => { + const { shapeSvg } = await labelHelper(parent, node, "label", true); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Classes = ", node.class); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = 0; + const totalHeight = 0; + rect2.attr("width", totalWidth).attr("height", totalHeight); + shapeSvg.attr("class", "label edgeLabel"); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) { + const strokeDashArray = []; + const addBorder = (length) => { + strokeDashArray.push(length, 0); + }; + const skipBorder = (length) => { + strokeDashArray.push(0, length); + }; + if (borders.includes("t")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add top border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("r")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add right border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + if (borders.includes("b")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add bottom border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("l")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add left border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + rect2.attr("stroke-dasharray", strokeDashArray.join(" ")); +} +const rectWithTitle = (parent, node) => { + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const innerLine = shapeSvg.insert("line"); + const label = shapeSvg.insert("g").attr("class", "label"); + const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText; + let title = ""; + if (typeof text2 === "object") { + title = text2[0]; + } else { + title = text2; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Label text abc79", title, text2, typeof text2 === "object"); + const text = label.node().appendChild(createLabel$1(title, node.labelStyle, true, true)); + let bbox = { width: 0, height: 0 }; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Text 2", text2); + const textRows = text2.slice(1, text2.length); + let titleBox = text.getBBox(); + const descr = label.node().appendChild( + createLabel$1(textRows.join ? textRows.join("<br/>") : textRows, node.labelStyle, true, true) + ); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = descr.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(descr); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const halfPadding = node.padding / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(descr).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")" + ); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)" + ); + bbox = label.node().getBBox(); + label.attr( + "transform", + "translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")" + ); + rect2.attr("class", "outer title-state").attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + innerLine.attr("class", "divider").attr("x1", -bbox.width / 2 - halfPadding).attr("x2", bbox.width / 2 + halfPadding).attr("y1", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr("y2", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const stadium = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const h = bbox.height + node.padding; + const w = bbox.width + h / 4 + node.padding; + const rect2 = shapeSvg.insert("rect", ":first-child").attr("style", node.style).attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const circle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle main"); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle intersect", node, bbox.width / 2 + halfPadding, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding, point2); + }; + return shapeSvg; +}; +const doublecircle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const gap = 5; + const circleGroup = shapeSvg.insert("g", ":first-child"); + const outerCircle = circleGroup.insert("circle"); + const innerCircle = circleGroup.insert("circle"); + circleGroup.attr("class", node.class); + outerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding + gap).attr("width", bbox.width + node.padding + gap * 2).attr("height", bbox.height + node.padding + gap * 2); + innerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle main"); + updateNodeBounds(node, outerCircle); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point2); + }; + return shapeSvg; +}; +const subroutine = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const start = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const forkJoin = (parent, node, dir) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + let width = 70; + let height = 10; + if (dir === "LR") { + width = 10; + height = 70; + } + const shape = shapeSvg.append("rect").attr("x", -1 * width / 2).attr("y", -1 * height / 2).attr("width", width).attr("height", height).attr("class", "fork-join"); + updateNodeBounds(node, shape); + node.height = node.height + node.padding / 2; + node.width = node.width + node.padding / 2; + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const end = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const innerCircle = shapeSvg.insert("circle", ":first-child"); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const class_box = (parent, node) => { + const halfPadding = node.padding / 2; + const rowPadding = 4; + const lineHeight = 8; + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const topLine = shapeSvg.insert("line"); + const bottomLine = shapeSvg.insert("line"); + let maxWidth = 0; + let maxHeight = rowPadding; + const labelContainer = shapeSvg.insert("g").attr("class", "label"); + let verticalPos = 0; + const hasInterface = node.classData.annotations && node.classData.annotations[0]; + const interfaceLabelText = node.classData.annotations[0] ? "«" + node.classData.annotations[0] + "»" : ""; + const interfaceLabel = labelContainer.node().appendChild(createLabel$1(interfaceLabelText, node.labelStyle, true, true)); + let interfaceBBox = interfaceLabel.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = interfaceLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(interfaceLabel); + interfaceBBox = div.getBoundingClientRect(); + dv.attr("width", interfaceBBox.width); + dv.attr("height", interfaceBBox.height); + } + if (node.classData.annotations[0]) { + maxHeight += interfaceBBox.height + rowPadding; + maxWidth += interfaceBBox.width; + } + let classTitleString = node.classData.label; + if (node.classData.type !== void 0 && node.classData.type !== "") { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + classTitleString += "<" + node.classData.type + ">"; + } else { + classTitleString += "<" + node.classData.type + ">"; + } + } + const classTitleLabel = labelContainer.node().appendChild(createLabel$1(classTitleString, node.labelStyle, true, true)); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel).attr("class", "classTitle"); + let classTitleBBox = classTitleLabel.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = classTitleLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel); + classTitleBBox = div.getBoundingClientRect(); + dv.attr("width", classTitleBBox.width); + dv.attr("height", classTitleBBox.height); + } + maxHeight += classTitleBBox.height + rowPadding; + if (classTitleBBox.width > maxWidth) { + maxWidth = classTitleBBox.width; + } + const classAttributes = []; + node.classData.members.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let parsedText = parsedInfo.displayText; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + parsedText = parsedText.replace(/</g, "<").replace(/>/g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + parsedText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classAttributes.push(lbl); + }); + maxHeight += lineHeight; + const classMethods = []; + node.classData.methods.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let displayText = parsedInfo.displayText; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + displayText = displayText.replace(/</g, "<").replace(/>/g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + displayText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classMethods.push(lbl); + }); + maxHeight += lineHeight; + if (hasInterface) { + let diffX2 = (maxWidth - interfaceBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(interfaceLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")" + ); + verticalPos = interfaceBBox.height + rowPadding; + } + let diffX = (maxWidth - classTitleBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + verticalPos += classTitleBBox.height + rowPadding; + topLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classAttributes.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + verticalPos += lineHeight; + bottomLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classMethods.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + rect2.attr("style", node.style).attr("class", "outer title-state").attr("x", -maxWidth / 2 - halfPadding).attr("y", -(maxHeight / 2) - halfPadding).attr("width", maxWidth + node.padding).attr("height", maxHeight + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const shapes = { + rhombus: question, + composite, + question, + rect, + labelRect, + rectWithTitle, + choice, + circle, + doublecircle, + stadium, + hexagon, + block_arrow, + rect_left_inv_arrow, + lean_right, + lean_left, + trapezoid, + inv_trapezoid, + rect_right_inv_arrow, + cylinder, + start, + end, + note: note$1, + subroutine, + fork: forkJoin, + join: forkJoin, + class_box +}; +let nodeElems = {}; +const insertNode = async (elem, node, dir) => { + let newEl; + let el; + if (node.link) { + let target; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel === "sandbox") { + target = "_top"; + } else if (node.linkTarget) { + target = node.linkTarget || "_blank"; + } + newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target); + el = await shapes[node.shape](newEl, node, dir); + } else { + el = await shapes[node.shape](elem, node, dir); + newEl = el; + } + if (node.tooltip) { + el.attr("title", node.tooltip); + } + if (node.class) { + el.attr("class", "node default " + node.class); + } + newEl.attr("data-node", "true"); + newEl.attr("data-id", node.id); + nodeElems[node.id] = newEl; + if (node.haveCallback) { + nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable"); + } + return newEl; +}; +const setNodeElem = (elem, node) => { + nodeElems[node.id] = elem; +}; +const clear$1 = () => { + nodeElems = {}; +}; +const positionNode = (node) => { + const el = nodeElems[node.id]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace( + "Transforming node", + node.diff, + node, + "translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")" + ); + const padding = 8; + const diff = node.diff || 0; + if (node.clusterNode) { + el.attr( + "transform", + "translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")" + ); + } else { + el.attr("transform", "translate(" + node.x + ", " + node.y + ")"); + } + return diff; +}; +const getSubGraphTitleMargins = ({ + flowchart +}) => { + var _a, _b; + const subGraphTitleTopMargin = ((_a = flowchart == null ? void 0 : flowchart.subGraphTitleMargin) == null ? void 0 : _a.top) ?? 0; + const subGraphTitleBottomMargin = ((_b = flowchart == null ? void 0 : flowchart.subGraphTitleMargin) == null ? void 0 : _b.bottom) ?? 0; + const subGraphTitleTotalMargin = subGraphTitleTopMargin + subGraphTitleBottomMargin; + return { + subGraphTitleTopMargin, + subGraphTitleBottomMargin, + subGraphTitleTotalMargin + }; +}; +const markerOffsets = { + aggregation: 18, + extension: 18, + composition: 18, + dependency: 6, + lollipop: 13.5, + arrow_point: 5.3 +}; +function calculateDeltaAndAngle(point1, point2) { + if (point1 === void 0 || point2 === void 0) { + return { angle: 0, deltaX: 0, deltaY: 0 }; + } + point1 = pointTransformer(point1); + point2 = pointTransformer(point2); + const [x1, y1] = [point1.x, point1.y]; + const [x2, y2] = [point2.x, point2.y]; + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY }; +} +const pointTransformer = (data) => { + if (Array.isArray(data)) { + return { x: data[0], y: data[1] }; + } + return data; +}; +const getLineFunctionsWithOffset = (edge) => { + return { + x: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaX } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } + return pointTransformer(d).x + offset; + }, + y: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaY } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } + return pointTransformer(d).y + offset; + } + }; +}; +const addEdgeMarkers = (svgPath, edge, url, id, diagramType) => { + if (edge.arrowTypeStart) { + addEdgeMarker(svgPath, "start", edge.arrowTypeStart, url, id, diagramType); + } + if (edge.arrowTypeEnd) { + addEdgeMarker(svgPath, "end", edge.arrowTypeEnd, url, id, diagramType); + } +}; +const arrowTypesMap = { + arrow_cross: "cross", + arrow_point: "point", + arrow_barb: "barb", + arrow_circle: "circle", + aggregation: "aggregation", + extension: "extension", + composition: "composition", + dependency: "dependency", + lollipop: "lollipop" +}; +const addEdgeMarker = (svgPath, position, arrowType, url, id, diagramType) => { + const endMarkerType = arrowTypesMap[arrowType]; + if (!endMarkerType) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown arrow type: ${arrowType}`); + return; + } + const suffix = position === "start" ? "Start" : "End"; + svgPath.attr(`marker-${position}`, `url(${url}#${id}_${diagramType}-${endMarkerType}${suffix})`); +}; +let edgeLabels = {}; +let terminalLabels = {}; +const clear = () => { + edgeLabels = {}; + terminalLabels = {}; +}; +const insertEdgeLabel = (elem, edge) => { + const useHtmlLabels = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + const labelElement = edge.labelType === "markdown" ? (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__.a)(elem, edge.label, { + style: edge.labelStyle, + useHtmlLabels, + addSvgBackground: true + }) : createLabel$1(edge.label, edge.labelStyle); + const edgeLabel = elem.insert("g").attr("class", "edgeLabel"); + const label = edgeLabel.insert("g").attr("class", "label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + if (useHtmlLabels) { + const div = labelElement.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(labelElement); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + edgeLabels[edge.id] = edgeLabel; + edge.width = bbox.width; + edge.height = bbox.height; + let fo; + if (edge.startLabelLeft) { + const startLabelElement = createLabel$1(edge.startLabelLeft, edge.labelStyle); + const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startLeft = startEdgeLabelLeft; + setTerminalWidth(fo, edge.startLabelLeft); + } + if (edge.startLabelRight) { + const startLabelElement = createLabel$1(edge.startLabelRight, edge.labelStyle); + const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelRight.insert("g").attr("class", "inner"); + fo = startEdgeLabelRight.node().appendChild(startLabelElement); + inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startRight = startEdgeLabelRight; + setTerminalWidth(fo, edge.startLabelRight); + } + if (edge.endLabelLeft) { + const endLabelElement = createLabel$1(edge.endLabelLeft, edge.labelStyle); + const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelLeft.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endLeft = endEdgeLabelLeft; + setTerminalWidth(fo, edge.endLabelLeft); + } + if (edge.endLabelRight) { + const endLabelElement = createLabel$1(edge.endLabelRight, edge.labelStyle); + const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelRight.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelRight.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endRight = endEdgeLabelRight; + setTerminalWidth(fo, edge.endLabelRight); + } + return labelElement; +}; +function setTerminalWidth(fo, value) { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels && fo) { + fo.style.width = value.length * 9 + "px"; + fo.style.height = "12px"; + } +} +const positionEdgeLabel = (edge, paths) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("Moving label abc88 ", edge.id, edge.label, edgeLabels[edge.id], paths); + let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig); + if (edge.label) { + const el = edgeLabels[edge.id]; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcLabelPosition(path); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug( + "Moving label " + edge.label + " from (", + x, + ",", + y, + ") to (", + pos.x, + ",", + pos.y, + ") abc88" + ); + if (paths.updatedPath) { + x = pos.x; + y = pos.y; + } + } + el.attr("transform", `translate(${x}, ${y + subGraphTitleTotalMargin / 2})`); + } + if (edge.startLabelLeft) { + const el = terminalLabels[edge.id].startLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.startLabelRight) { + const el = terminalLabels[edge.id].startRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition( + edge.arrowTypeStart ? 10 : 0, + "start_right", + path + ); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.endLabelLeft) { + const el = terminalLabels[edge.id].endLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.endLabelRight) { + const el = terminalLabels[edge.id].endRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } +}; +const outsideNode = (node, point2) => { + const x = node.x; + const y = node.y; + const dx = Math.abs(point2.x - x); + const dy = Math.abs(point2.y - y); + const w = node.width / 2; + const h = node.height / 2; + if (dx >= w || dy >= h) { + return true; + } + return false; +}; +const intersection = (node, outsidePoint, insidePoint) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`intersection calc abc89: + outsidePoint: ${JSON.stringify(outsidePoint)} + insidePoint : ${JSON.stringify(insidePoint)} + node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`); + const x = node.x; + const y = node.y; + const dx = Math.abs(x - insidePoint.x); + const w = node.width / 2; + let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; + const h = node.height / 2; + const Q = Math.abs(outsidePoint.y - insidePoint.y); + const R = Math.abs(outsidePoint.x - insidePoint.x); + if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { + let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y; + r = R * q / Q; + const res = { + x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r, + y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q + }; + if (r === 0) { + res.x = outsidePoint.x; + res.y = outsidePoint.y; + } + if (R === 0) { + res.x = outsidePoint.x; + } + if (Q === 0) { + res.y = outsidePoint.y; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res); + return res; + } else { + if (insidePoint.x < outsidePoint.x) { + r = outsidePoint.x - w - x; + } else { + r = x - w - outsidePoint.x; + } + let q = Q * r / R; + let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r; + let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y }); + if (r === 0) { + _x = outsidePoint.x; + _y = outsidePoint.y; + } + if (R === 0) { + _x = outsidePoint.x; + } + if (Q === 0) { + _y = outsidePoint.y; + } + return { x: _x, y: _y }; + } +}; +const cutPathAtIntersect = (_points, boundaryNode) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("abc88 cutPathAtIntersect", _points, boundaryNode); + let points = []; + let lastPointOutside = _points[0]; + let isInside = false; + _points.forEach((point2) => { + if (!outsideNode(boundaryNode, point2) && !isInside) { + const inter = intersection(boundaryNode, lastPointOutside, point2); + let pointPresent = false; + points.forEach((p) => { + pointPresent = pointPresent || p.x === inter.x && p.y === inter.y; + }); + if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { + points.push(inter); + } + isInside = true; + } else { + lastPointOutside = point2; + if (!isInside) { + points.push(point2); + } + } + }); + return points; +}; +const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph, id) { + let points = edge.points; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("abc88 InsertEdge: edge=", edge, "e=", e); + let pointsHasChanged = false; + const tail = graph.node(e.v); + var head = graph.node(e.w); + if ((head == null ? void 0 : head.intersect) && (tail == null ? void 0 : tail.intersect)) { + points = points.slice(1, edge.points.length - 1); + points.unshift(tail.intersect(points[0])); + points.push(head.intersect(points[points.length - 1])); + } + if (edge.toCluster) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("to cluster abc88", clusterDb[edge.toCluster]); + points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); + pointsHasChanged = true; + } + if (edge.fromCluster) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("from cluster abc88", clusterDb[edge.fromCluster]); + points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse(); + pointsHasChanged = true; + } + const lineData = points.filter((p) => !Number.isNaN(p.y)); + let curve = d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .qrM; + if (edge.curve && (diagramType === "graph" || diagramType === "flowchart")) { + curve = edge.curve; + } + const { x, y } = getLineFunctionsWithOffset(edge); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .n8j)().x(x).y(y).curve(curve); + let strokeClasses; + switch (edge.thickness) { + case "normal": + strokeClasses = "edge-thickness-normal"; + break; + case "thick": + strokeClasses = "edge-thickness-thick"; + break; + case "invisible": + strokeClasses = "edge-thickness-thick"; + break; + default: + strokeClasses = ""; + } + switch (edge.pattern) { + case "solid": + strokeClasses += " edge-pattern-solid"; + break; + case "dotted": + strokeClasses += " edge-pattern-dotted"; + break; + case "dashed": + strokeClasses += " edge-pattern-dashed"; + break; + } + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style); + let url = ""; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.arrowMarkerAbsolute || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + addEdgeMarkers(svgPath, edge, url, id, diagramType); + let paths = {}; + if (pointsHasChanged) { + paths.updatedPath = points; + } + paths.originalPath = edge.points; + return paths; +}; + + + +/***/ }), + +/***/ 92746: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ r: () => (/* binding */ render) +/* harmony export */ }); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(21176); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14075); +/* harmony import */ var _edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(28747); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(76257); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(697); +/* harmony import */ var _createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(40351); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(26312); + + + + + + + +let clusterDb = {}; +let descendants = {}; +let parents = {}; +const clear$1 = () => { + descendants = {}; + parents = {}; + clusterDb = {}; +}; +const isDescendant = (id, ancestorId) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("In isDescendant", ancestorId, " ", id, " = ", descendants[ancestorId].includes(id)); + if (descendants[ancestorId].includes(id)) { + return true; + } + return false; +}; +const edgeInCluster = (edge, clusterId) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Descendants of ", clusterId, " is ", descendants[clusterId]); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge is ", edge); + if (edge.v === clusterId) { + return false; + } + if (edge.w === clusterId) { + return false; + } + if (!descendants[clusterId]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Tilt, ", clusterId, ",not in descendants"); + return false; + } + return descendants[clusterId].includes(edge.v) || isDescendant(edge.v, clusterId) || isDescendant(edge.w, clusterId) || descendants[clusterId].includes(edge.w); +}; +const copy = (clusterId, graph, newGraph, rootId) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Copying children of ", + clusterId, + "root", + rootId, + "data", + graph.node(clusterId), + rootId + ); + const nodes = graph.children(clusterId) || []; + if (clusterId !== rootId) { + nodes.push(clusterId); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Copying (nodes) clusterId", clusterId, "nodes", nodes); + nodes.forEach((node) => { + if (graph.children(node).length > 0) { + copy(node, graph, newGraph, rootId); + } else { + const data = graph.node(node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("cp ", node, " to ", rootId, " with parent ", clusterId); + newGraph.setNode(node, data); + if (rootId !== graph.parent(node)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Setting parent", node, graph.parent(node)); + newGraph.setParent(node, graph.parent(node)); + } + if (clusterId !== rootId && node !== clusterId) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Setting parent", node, clusterId); + newGraph.setParent(node, clusterId); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("In copy ", clusterId, "root", rootId, "data", graph.node(clusterId), rootId); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Not Setting parent for node=", + node, + "cluster!==rootId", + clusterId !== rootId, + "node!==clusterId", + node !== clusterId + ); + } + const edges = graph.edges(node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Copying Edges", edges); + edges.forEach((edge) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge", edge); + const data2 = graph.edge(edge.v, edge.w, edge.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge data", data2, rootId); + try { + if (edgeInCluster(edge, rootId)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Copying as ", edge.v, edge.w, data2, edge.name); + newGraph.setEdge(edge.v, edge.w, data2, edge.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("newGraph edges ", newGraph.edges(), newGraph.edge(newGraph.edges()[0])); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Skipping copy of edge ", + edge.v, + "-->", + edge.w, + " rootId: ", + rootId, + " clusterId:", + clusterId + ); + } + } catch (e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error(e); + } + }); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Removing node", node); + graph.removeNode(node); + }); +}; +const extractDescendants = (id, graph) => { + const children = graph.children(id); + let res = [...children]; + for (const child of children) { + parents[child] = id; + res = [...res, ...extractDescendants(child, graph)]; + } + return res; +}; +const findNonClusterChild = (id, graph) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching", id); + const children = graph.children(id); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching children of id ", id, children); + if (children.length < 1) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("This is a valid node", id); + return id; + } + for (const child of children) { + const _id = findNonClusterChild(child, graph); + if (_id) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Found replacement for", id, " => ", _id); + return _id; + } + } +}; +const getAnchorId = (id) => { + if (!clusterDb[id]) { + return id; + } + if (!clusterDb[id].externalConnections) { + return id; + } + if (clusterDb[id]) { + return clusterDb[id].id; + } + return id; +}; +const adjustClustersAndEdges = (graph, depth) => { + if (!graph || depth > 10) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting out, no graph "); + return; + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting in, graph "); + } + graph.nodes().forEach(function(id) { + const children = graph.children(id); + if (children.length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster identified", + id, + " Replacement id in edges: ", + findNonClusterChild(id, graph) + ); + descendants[id] = extractDescendants(id, graph); + clusterDb[id] = { id: findNonClusterChild(id, graph), clusterData: graph.node(id) }; + } + }); + graph.nodes().forEach(function(id) { + const children = graph.children(id); + const edges = graph.edges(); + if (children.length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Cluster identified", id, descendants); + edges.forEach((edge) => { + if (edge.v !== id && edge.w !== id) { + const d1 = isDescendant(edge.v, id); + const d2 = isDescendant(edge.w, id); + if (d1 ^ d2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge: ", edge, " leaves cluster ", id); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Descendants of XXX ", id, ": ", descendants[id]); + clusterDb[id].externalConnections = true; + } + } + }); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster ", id, descendants); + } + }); + for (let id of Object.keys(clusterDb)) { + const nonClusterChild = clusterDb[id].id; + const parent = graph.parent(nonClusterChild); + if (parent !== id && clusterDb[parent] && !clusterDb[parent].externalConnections) { + clusterDb[id].id = parent; + } + } + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(graph.edge(e))); + let v = e.v; + let w = e.w; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Fix XXX", + clusterDb, + "ids:", + e.v, + e.w, + "Translating: ", + clusterDb[e.v], + " --- ", + clusterDb[e.w] + ); + if (clusterDb[e.v] && clusterDb[e.w] && clusterDb[e.v] === clusterDb[e.w]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing link to self - removing XXX", e.v, e.w, e.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + const specialId = e.w + "---" + e.v; + graph.setNode(specialId, { + domId: specialId, + id: specialId, + labelStyle: "", + labelText: edge.label, + padding: 0, + shape: "labelRect", + style: "" + }); + const edge1 = structuredClone(edge); + const edge2 = structuredClone(edge); + edge1.label = ""; + edge1.arrowTypeEnd = "none"; + edge2.label = ""; + edge1.fromCluster = e.v; + edge2.toCluster = e.v; + graph.setEdge(v, specialId, edge1, e.name + "-cyclic-special"); + graph.setEdge(specialId, w, edge2, e.name + "-cyclic-special"); + } else if (clusterDb[e.v] || clusterDb[e.w]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + if (v !== e.v) { + const parent = graph.parent(v); + clusterDb[parent].externalConnections = true; + edge.fromCluster = e.v; + } + if (w !== e.w) { + const parent = graph.parent(w); + clusterDb[parent].externalConnections = true; + edge.toCluster = e.w; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fix Replacing with XXX", v, w, e.name); + graph.setEdge(v, w, edge, e.name); + } + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Adjusted Graph", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + extractor(graph, 0); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace(clusterDb); +}; +const extractor = (graph, depth) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("extractor - ", depth, dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph), graph.children("D")); + if (depth > 10) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error("Bailing out"); + return; + } + let nodes = graph.nodes(); + let hasChildren = false; + for (const node of nodes) { + const children = graph.children(node); + hasChildren = hasChildren || children.length > 0; + } + if (!hasChildren) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Done, no node has children", graph.nodes()); + return; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Nodes = ", nodes, depth); + for (const node of nodes) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Extracting node", + node, + clusterDb, + clusterDb[node] && !clusterDb[node].externalConnections, + !graph.parent(node), + graph.node(node), + graph.children("D"), + " Depth ", + depth + ); + if (!clusterDb[node]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster", node, depth); + } else if (!clusterDb[node].externalConnections && // !graph.parent(node) && + graph.children(node) && graph.children(node).length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster without external connections, without a parent and with children", + node, + depth + ); + const graphSettings = graph.graph(); + let dir = graphSettings.rankdir === "TB" ? "LR" : "TB"; + if (clusterDb[node] && clusterDb[node].clusterData && clusterDb[node].clusterData.dir) { + dir = clusterDb[node].clusterData.dir; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing dir", clusterDb[node].clusterData.dir, dir); + } + const clusterGraph = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .T({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + // Todo: set proper spacing + nodesep: 50, + ranksep: 50, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Old graph before copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + copy(node, graph, clusterGraph, node); + graph.setNode(node, { + clusterNode: true, + id: node, + clusterData: clusterDb[node].clusterData, + labelText: clusterDb[node].labelText, + graph: clusterGraph + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New graph after copy node: (", node, ")", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(clusterGraph)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Old graph after copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster ** ", + node, + " **not meeting the criteria !externalConnections:", + !clusterDb[node].externalConnections, + " no parent: ", + !graph.parent(node), + " children ", + graph.children(node) && graph.children(node).length > 0, + graph.children("D"), + depth + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(clusterDb); + } + } + nodes = graph.nodes(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New list of nodes", nodes); + for (const node of nodes) { + const data = graph.node(node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn(" Now next level", node, data); + if (data.clusterNode) { + extractor(data.graph, depth + 1); + } + } +}; +const sorter = (graph, nodes) => { + if (nodes.length === 0) { + return []; + } + let result = Object.assign(nodes); + nodes.forEach((node) => { + const children = graph.children(node); + const sorted = sorter(graph, children); + result = [...result, ...sorted]; + }); + return result; +}; +const sortNodesByHierarchy = (graph) => sorter(graph, graph.children()); +const rect = (parent, node) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Creating subgraph rect for ", node.id, node); + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const shapeSvg = parent.insert("g").attr("class", "cluster" + (node.class ? " " + node.class : "")).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const useHtmlLabels = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const text = node.labelType === "markdown" ? (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_5__.a)(label, node.labelText, { style: node.labelStyle, useHtmlLabels }) : label.node().appendChild((0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width; + if (node.width <= bbox.width + padding) { + node.diff = (bbox.width - node.width) / 2 - node.padding / 2; + } else { + node.diff = -node.padding / 2; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Data ", node, JSON.stringify(node)); + rect2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - width / 2).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width).attr("height", node.height + padding); + const { subGraphTitleTopMargin } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.g)(siteConfig); + if (useHtmlLabels) { + label.attr( + "transform", + // This puts the label on top of the box instead of inside it + `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 + subGraphTitleTopMargin})` + ); + } else { + label.attr( + "transform", + // This puts the label on top of the box instead of inside it + `translate(${node.x}, ${node.y - node.height / 2 + subGraphTitleTopMargin})` + ); + } + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const noteGroup = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "note-cluster").attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", node.width + padding).attr("height", node.height + padding).attr("fill", "none"); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const roundedWithTitle = (parent, node) => { + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const innerRect = shapeSvg.append("rect"); + const text = label.node().appendChild((0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + bbox = text.getBBox(); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width; + if (node.width <= bbox.width + node.padding) { + node.diff = (bbox.width + node.padding * 0 - node.width) / 2; + } else { + node.diff = -node.padding / 2; + } + rect2.attr("class", "outer").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width + padding).attr("height", node.height + padding); + innerRect.attr("class", "inner").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding + bbox.height - 1).attr("width", width + padding).attr("height", node.height + padding - bbox.height - 3); + const { subGraphTitleTopMargin } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.g)(siteConfig); + label.attr( + "transform", + `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 - node.padding / 3 + ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels) ? 5 : 3) + subGraphTitleTopMargin})` + ); + const rectBox = rect2.node().getBBox(); + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const divider = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("class", "divider").attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2).attr("width", node.width + padding).attr("height", node.height + padding); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.diff = -node.padding / 2; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const shapes = { rect, roundedWithTitle, noteGroup, divider }; +let clusterElems = {}; +const insertCluster = (elem, node) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Inserting cluster"); + const shape = node.shape || "rect"; + clusterElems[node.id] = shapes[shape](elem, node); +}; +const clear = () => { + clusterElems = {}; +}; +const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, siteConfig) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph in recursive render: XXX", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph), parentCluster); + const dir = graph.graph().rankdir; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Dir in recursive render - dir:", dir); + const elem = _elem.insert("g").attr("class", "root"); + if (!graph.nodes()) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("No nodes found for", graph); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Recursive render XXX", graph.nodes()); + } + if (graph.edges().length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Recursive edges", graph.edge(graph.edges()[0])); + } + const clusters = elem.insert("g").attr("class", "clusters"); + const edgePaths = elem.insert("g").attr("class", "edgePaths"); + const edgeLabels = elem.insert("g").attr("class", "edgeLabels"); + const nodes = elem.insert("g").attr("class", "nodes"); + await Promise.all( + graph.nodes().map(async function(v) { + const node = graph.node(v); + if (parentCluster !== void 0) { + const data = JSON.parse(JSON.stringify(parentCluster.clusterData)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Setting data for cluster XXX (", v, ") ", data, parentCluster); + graph.setNode(parentCluster.id, data); + if (!graph.parent(v)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Setting parent", v, parentCluster.id); + graph.setParent(v, parentCluster.id, data); + } + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("(Insert) Node XXX" + v + ": " + JSON.stringify(graph.node(v))); + if (node && node.clusterNode) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster identified", v, node.width, graph.node(v)); + const o = await recursiveRender( + nodes, + node.graph, + diagramType, + id, + graph.node(v), + siteConfig + ); + const newEl = o.elem; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.u)(node, newEl); + node.diff = o.diff || 0; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node bounds (abc123)", v, node, node.width, node.x, node.y); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.s)(newEl, node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Recursive render complete ", newEl, node); + } else { + if (graph.children(v).length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster - the non recursive path XXX", v, node.id, node, graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info(findNonClusterChild(node.id, graph)); + clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node }; + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node - the non recursive path", v, node.id, node); + await (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.e)(nodes, graph.node(v), dir); + } + } + }) + ); + graph.edges().forEach(function(e) { + const edge = graph.edge(e.v, e.w, e.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": ", e, " ", JSON.stringify(graph.edge(e))); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Fix", clusterDb, "ids:", e.v, e.w, "Translating: ", clusterDb[e.v], clusterDb[e.w]); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.f)(edgeLabels, edge); + }); + graph.edges().forEach(function(e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("### Layout ###"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info(graph); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__/* .layout */ .Zp)(graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph after layout:", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + let diff = 0; + const { subGraphTitleTotalMargin } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.g)(siteConfig); + sortNodesByHierarchy(graph).forEach(function(v) { + const node = graph.node(v); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Position " + v + ": " + JSON.stringify(graph.node(v))); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Position " + v + ": (" + node.x, + "," + node.y, + ") width: ", + node.width, + " height: ", + node.height + ); + if (node && node.clusterNode) { + node.y += subGraphTitleTotalMargin; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } else { + if (graph.children(v).length > 0) { + node.height += subGraphTitleTotalMargin; + insertCluster(clusters, node); + clusterDb[node.id].node = node; + } else { + node.y += subGraphTitleTotalMargin / 2; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } + } + }); + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(edge), edge); + edge.points.forEach((point) => point.y += subGraphTitleTotalMargin / 2); + const paths = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.h)(edgePaths, e, edge, clusterDb, diagramType, graph, id); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.j)(edge, paths); + }); + graph.nodes().forEach(function(v) { + const n = graph.node(v); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info(v, n.type, n.diff); + if (n.type === "group") { + diff = n.diff; + } + }); + return { elem, diff }; +}; +const render = async (elem, graph, markers, diagramType, id) => { + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.a)(elem, markers, diagramType, id); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.b)(); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.d)(); + clear(); + clear$1(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph at first:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph))); + adjustClustersAndEdges(graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph after:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph))); + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + await recursiveRender(elem, graph, diagramType, id, void 0, siteConfig); +}; + + + +/***/ }), + +/***/ 27308: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ p: () => (/* binding */ parser$1), +/* harmony export */ s: () => (/* binding */ styles) +/* harmony export */ }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 17], $V1 = [1, 18], $V2 = [1, 19], $V3 = [1, 39], $V4 = [1, 40], $V5 = [1, 25], $V6 = [1, 23], $V7 = [1, 24], $V8 = [1, 31], $V9 = [1, 32], $Va = [1, 33], $Vb = [1, 34], $Vc = [1, 35], $Vd = [1, 36], $Ve = [1, 26], $Vf = [1, 27], $Vg = [1, 28], $Vh = [1, 29], $Vi = [1, 43], $Vj = [1, 30], $Vk = [1, 42], $Vl = [1, 44], $Vm = [1, 41], $Vn = [1, 45], $Vo = [1, 9], $Vp = [1, 8, 9], $Vq = [1, 56], $Vr = [1, 57], $Vs = [1, 58], $Vt = [1, 59], $Vu = [1, 60], $Vv = [1, 61], $Vw = [1, 62], $Vx = [1, 8, 9, 39], $Vy = [1, 74], $Vz = [1, 8, 9, 12, 13, 21, 37, 39, 42, 59, 60, 61, 62, 63, 64, 65, 70, 72], $VA = [1, 8, 9, 12, 13, 19, 21, 37, 39, 42, 46, 59, 60, 61, 62, 63, 64, 65, 70, 72, 74, 80, 95, 97, 98], $VB = [13, 74, 80, 95, 97, 98], $VC = [13, 64, 65, 74, 80, 95, 97, 98], $VD = [13, 59, 60, 61, 62, 63, 74, 80, 95, 97, 98], $VE = [1, 93], $VF = [1, 110], $VG = [1, 108], $VH = [1, 102], $VI = [1, 103], $VJ = [1, 104], $VK = [1, 105], $VL = [1, 106], $VM = [1, 107], $VN = [1, 109], $VO = [1, 8, 9, 37, 39, 42], $VP = [1, 8, 9, 21], $VQ = [1, 8, 9, 78], $VR = [1, 8, 9, 21, 73, 74, 78, 80, 81, 82, 83, 84, 85]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "mermaidDoc": 4, "statements": 5, "graphConfig": 6, "CLASS_DIAGRAM": 7, "NEWLINE": 8, "EOF": 9, "statement": 10, "classLabel": 11, "SQS": 12, "STR": 13, "SQE": 14, "namespaceName": 15, "alphaNumToken": 16, "className": 17, "classLiteralName": 18, "GENERICTYPE": 19, "relationStatement": 20, "LABEL": 21, "namespaceStatement": 22, "classStatement": 23, "memberStatement": 24, "annotationStatement": 25, "clickStatement": 26, "styleStatement": 27, "cssClassStatement": 28, "noteStatement": 29, "direction": 30, "acc_title": 31, "acc_title_value": 32, "acc_descr": 33, "acc_descr_value": 34, "acc_descr_multiline_value": 35, "namespaceIdentifier": 36, "STRUCT_START": 37, "classStatements": 38, "STRUCT_STOP": 39, "NAMESPACE": 40, "classIdentifier": 41, "STYLE_SEPARATOR": 42, "members": 43, "CLASS": 44, "ANNOTATION_START": 45, "ANNOTATION_END": 46, "MEMBER": 47, "SEPARATOR": 48, "relation": 49, "NOTE_FOR": 50, "noteText": 51, "NOTE": 52, "direction_tb": 53, "direction_bt": 54, "direction_rl": 55, "direction_lr": 56, "relationType": 57, "lineType": 58, "AGGREGATION": 59, "EXTENSION": 60, "COMPOSITION": 61, "DEPENDENCY": 62, "LOLLIPOP": 63, "LINE": 64, "DOTTED_LINE": 65, "CALLBACK": 66, "LINK": 67, "LINK_TARGET": 68, "CLICK": 69, "CALLBACK_NAME": 70, "CALLBACK_ARGS": 71, "HREF": 72, "STYLE": 73, "ALPHA": 74, "stylesOpt": 75, "CSSCLASS": 76, "style": 77, "COMMA": 78, "styleComponent": 79, "NUM": 80, "COLON": 81, "UNIT": 82, "SPACE": 83, "BRKT": 84, "PCT": 85, "commentToken": 86, "textToken": 87, "graphCodeTokens": 88, "textNoTagsToken": 89, "TAGSTART": 90, "TAGEND": 91, "==": 92, "--": 93, "DEFAULT": 94, "MINUS": 95, "keywords": 96, "UNICODE_TEXT": 97, "BQUOTE_STR": 98, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 7: "CLASS_DIAGRAM", 8: "NEWLINE", 9: "EOF", 12: "SQS", 13: "STR", 14: "SQE", 19: "GENERICTYPE", 21: "LABEL", 31: "acc_title", 32: "acc_title_value", 33: "acc_descr", 34: "acc_descr_value", 35: "acc_descr_multiline_value", 37: "STRUCT_START", 39: "STRUCT_STOP", 40: "NAMESPACE", 42: "STYLE_SEPARATOR", 44: "CLASS", 45: "ANNOTATION_START", 46: "ANNOTATION_END", 47: "MEMBER", 48: "SEPARATOR", 50: "NOTE_FOR", 52: "NOTE", 53: "direction_tb", 54: "direction_bt", 55: "direction_rl", 56: "direction_lr", 59: "AGGREGATION", 60: "EXTENSION", 61: "COMPOSITION", 62: "DEPENDENCY", 63: "LOLLIPOP", 64: "LINE", 65: "DOTTED_LINE", 66: "CALLBACK", 67: "LINK", 68: "LINK_TARGET", 69: "CLICK", 70: "CALLBACK_NAME", 71: "CALLBACK_ARGS", 72: "HREF", 73: "STYLE", 74: "ALPHA", 76: "CSSCLASS", 78: "COMMA", 80: "NUM", 81: "COLON", 82: "UNIT", 83: "SPACE", 84: "BRKT", 85: "PCT", 88: "graphCodeTokens", 90: "TAGSTART", 91: "TAGEND", 92: "==", 93: "--", 94: "DEFAULT", 95: "MINUS", 96: "keywords", 97: "UNICODE_TEXT", 98: "BQUOTE_STR" }, + productions_: [0, [3, 1], [3, 1], [4, 1], [6, 4], [5, 1], [5, 2], [5, 3], [11, 3], [15, 1], [15, 2], [17, 1], [17, 1], [17, 2], [17, 2], [17, 2], [10, 1], [10, 2], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 2], [10, 2], [10, 1], [22, 4], [22, 5], [36, 2], [38, 1], [38, 2], [38, 3], [23, 1], [23, 3], [23, 4], [23, 6], [41, 2], [41, 3], [25, 4], [43, 1], [43, 2], [24, 1], [24, 2], [24, 1], [24, 1], [20, 3], [20, 4], [20, 4], [20, 5], [29, 3], [29, 2], [30, 1], [30, 1], [30, 1], [30, 1], [49, 3], [49, 2], [49, 2], [49, 1], [57, 1], [57, 1], [57, 1], [57, 1], [57, 1], [58, 1], [58, 1], [26, 3], [26, 4], [26, 3], [26, 4], [26, 4], [26, 5], [26, 3], [26, 4], [26, 4], [26, 5], [26, 4], [26, 5], [26, 5], [26, 6], [27, 3], [28, 3], [75, 1], [75, 3], [77, 1], [77, 2], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [86, 1], [86, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [89, 1], [89, 1], [89, 1], [89, 1], [16, 1], [16, 1], [16, 1], [16, 1], [18, 1], [51, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 8: + this.$ = $$[$0 - 1]; + break; + case 9: + case 11: + case 12: + this.$ = $$[$0]; + break; + case 10: + case 13: + this.$ = $$[$0 - 1] + $$[$0]; + break; + case 14: + case 15: + this.$ = $$[$0 - 1] + "~" + $$[$0] + "~"; + break; + case 16: + yy.addRelation($$[$0]); + break; + case 17: + $$[$0 - 1].title = yy.cleanupLabel($$[$0]); + yy.addRelation($$[$0 - 1]); + break; + case 27: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 28: + case 29: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 30: + yy.addClassesToNamespace($$[$0 - 3], $$[$0 - 1]); + break; + case 31: + yy.addClassesToNamespace($$[$0 - 4], $$[$0 - 1]); + break; + case 32: + this.$ = $$[$0]; + yy.addNamespace($$[$0]); + break; + case 33: + this.$ = [$$[$0]]; + break; + case 34: + this.$ = [$$[$0 - 1]]; + break; + case 35: + $$[$0].unshift($$[$0 - 2]); + this.$ = $$[$0]; + break; + case 37: + yy.setCssClass($$[$0 - 2], $$[$0]); + break; + case 38: + yy.addMembers($$[$0 - 3], $$[$0 - 1]); + break; + case 39: + yy.setCssClass($$[$0 - 5], $$[$0 - 3]); + yy.addMembers($$[$0 - 5], $$[$0 - 1]); + break; + case 40: + this.$ = $$[$0]; + yy.addClass($$[$0]); + break; + case 41: + this.$ = $$[$0 - 1]; + yy.addClass($$[$0 - 1]); + yy.setClassLabel($$[$0 - 1], $$[$0]); + break; + case 42: + yy.addAnnotation($$[$0], $$[$0 - 2]); + break; + case 43: + this.$ = [$$[$0]]; + break; + case 44: + $$[$0].push($$[$0 - 1]); + this.$ = $$[$0]; + break; + case 45: + break; + case 46: + yy.addMember($$[$0 - 1], yy.cleanupLabel($$[$0])); + break; + case 47: + break; + case 48: + break; + case 49: + this.$ = { "id1": $$[$0 - 2], "id2": $$[$0], relation: $$[$0 - 1], relationTitle1: "none", relationTitle2: "none" }; + break; + case 50: + this.$ = { id1: $$[$0 - 3], id2: $$[$0], relation: $$[$0 - 1], relationTitle1: $$[$0 - 2], relationTitle2: "none" }; + break; + case 51: + this.$ = { id1: $$[$0 - 3], id2: $$[$0], relation: $$[$0 - 2], relationTitle1: "none", relationTitle2: $$[$0 - 1] }; + break; + case 52: + this.$ = { id1: $$[$0 - 4], id2: $$[$0], relation: $$[$0 - 2], relationTitle1: $$[$0 - 3], relationTitle2: $$[$0 - 1] }; + break; + case 53: + yy.addNote($$[$0], $$[$0 - 1]); + break; + case 54: + yy.addNote($$[$0]); + break; + case 55: + yy.setDirection("TB"); + break; + case 56: + yy.setDirection("BT"); + break; + case 57: + yy.setDirection("RL"); + break; + case 58: + yy.setDirection("LR"); + break; + case 59: + this.$ = { type1: $$[$0 - 2], type2: $$[$0], lineType: $$[$0 - 1] }; + break; + case 60: + this.$ = { type1: "none", type2: $$[$0], lineType: $$[$0 - 1] }; + break; + case 61: + this.$ = { type1: $$[$0 - 1], type2: "none", lineType: $$[$0] }; + break; + case 62: + this.$ = { type1: "none", type2: "none", lineType: $$[$0] }; + break; + case 63: + this.$ = yy.relationType.AGGREGATION; + break; + case 64: + this.$ = yy.relationType.EXTENSION; + break; + case 65: + this.$ = yy.relationType.COMPOSITION; + break; + case 66: + this.$ = yy.relationType.DEPENDENCY; + break; + case 67: + this.$ = yy.relationType.LOLLIPOP; + break; + case 68: + this.$ = yy.lineType.LINE; + break; + case 69: + this.$ = yy.lineType.DOTTED_LINE; + break; + case 70: + case 76: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 1], $$[$0]); + break; + case 71: + case 77: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1]); + yy.setTooltip($$[$0 - 2], $$[$0]); + break; + case 72: + this.$ = $$[$0 - 2]; + yy.setLink($$[$0 - 1], $$[$0]); + break; + case 73: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 74: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 2], $$[$0 - 1]); + yy.setTooltip($$[$0 - 2], $$[$0]); + break; + case 75: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 3], $$[$0 - 2], $$[$0]); + yy.setTooltip($$[$0 - 3], $$[$0 - 1]); + break; + case 78: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 79: + this.$ = $$[$0 - 4]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 2], $$[$0 - 1]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 80: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 2], $$[$0]); + break; + case 81: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 3], $$[$0 - 1], $$[$0]); + break; + case 82: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 3], $$[$0 - 1]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 83: + this.$ = $$[$0 - 5]; + yy.setLink($$[$0 - 4], $$[$0 - 2], $$[$0]); + yy.setTooltip($$[$0 - 4], $$[$0 - 1]); + break; + case 84: + this.$ = $$[$0 - 2]; + yy.setCssStyle($$[$0 - 1], $$[$0]); + break; + case 85: + yy.setCssClass($$[$0 - 1], $$[$0]); + break; + case 86: + this.$ = [$$[$0]]; + break; + case 87: + $$[$0 - 2].push($$[$0]); + this.$ = $$[$0 - 2]; + break; + case 89: + this.$ = $$[$0 - 1] + $$[$0]; + break; + } + }, + table: [{ 3: 1, 4: 2, 5: 3, 6: 4, 7: [1, 6], 10: 5, 16: 37, 17: 20, 18: 38, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: 16, 31: $V0, 33: $V1, 35: $V2, 36: 21, 40: $V3, 41: 22, 44: $V4, 45: $V5, 47: $V6, 48: $V7, 50: $V8, 52: $V9, 53: $Va, 54: $Vb, 55: $Vc, 56: $Vd, 66: $Ve, 67: $Vf, 69: $Vg, 73: $Vh, 74: $Vi, 76: $Vj, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 1: [3] }, { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3] }, o($Vo, [2, 5], { 8: [1, 46] }), { 8: [1, 47] }, o($Vp, [2, 16], { 21: [1, 48] }), o($Vp, [2, 18]), o($Vp, [2, 19]), o($Vp, [2, 20]), o($Vp, [2, 21]), o($Vp, [2, 22]), o($Vp, [2, 23]), o($Vp, [2, 24]), o($Vp, [2, 25]), o($Vp, [2, 26]), { 32: [1, 49] }, { 34: [1, 50] }, o($Vp, [2, 29]), o($Vp, [2, 45], { 49: 51, 57: 54, 58: 55, 13: [1, 52], 21: [1, 53], 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu, 64: $Vv, 65: $Vw }), { 37: [1, 63] }, o($Vx, [2, 36], { 37: [1, 65], 42: [1, 64] }), o($Vp, [2, 47]), o($Vp, [2, 48]), { 16: 66, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm }, { 16: 37, 17: 67, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 16: 37, 17: 68, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 16: 37, 17: 69, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 74: [1, 70] }, { 13: [1, 71] }, { 16: 37, 17: 72, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 13: $Vy, 51: 73 }, o($Vp, [2, 55]), o($Vp, [2, 56]), o($Vp, [2, 57]), o($Vp, [2, 58]), o($Vz, [2, 11], { 16: 37, 18: 38, 17: 75, 19: [1, 76], 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }), o($Vz, [2, 12], { 19: [1, 77] }), { 15: 78, 16: 79, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm }, { 16: 37, 17: 80, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($VA, [2, 112]), o($VA, [2, 113]), o($VA, [2, 114]), o($VA, [2, 115]), o([1, 8, 9, 12, 13, 19, 21, 37, 39, 42, 59, 60, 61, 62, 63, 64, 65, 70, 72], [2, 116]), o($Vo, [2, 6], { 10: 5, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: 16, 17: 20, 36: 21, 41: 22, 16: 37, 18: 38, 5: 81, 31: $V0, 33: $V1, 35: $V2, 40: $V3, 44: $V4, 45: $V5, 47: $V6, 48: $V7, 50: $V8, 52: $V9, 53: $Va, 54: $Vb, 55: $Vc, 56: $Vd, 66: $Ve, 67: $Vf, 69: $Vg, 73: $Vh, 74: $Vi, 76: $Vj, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }), { 5: 82, 10: 5, 16: 37, 17: 20, 18: 38, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: 16, 31: $V0, 33: $V1, 35: $V2, 36: 21, 40: $V3, 41: 22, 44: $V4, 45: $V5, 47: $V6, 48: $V7, 50: $V8, 52: $V9, 53: $Va, 54: $Vb, 55: $Vc, 56: $Vd, 66: $Ve, 67: $Vf, 69: $Vg, 73: $Vh, 74: $Vi, 76: $Vj, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($Vp, [2, 17]), o($Vp, [2, 27]), o($Vp, [2, 28]), { 13: [1, 84], 16: 37, 17: 83, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 49: 85, 57: 54, 58: 55, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu, 64: $Vv, 65: $Vw }, o($Vp, [2, 46]), { 58: 86, 64: $Vv, 65: $Vw }, o($VB, [2, 62], { 57: 87, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu }), o($VC, [2, 63]), o($VC, [2, 64]), o($VC, [2, 65]), o($VC, [2, 66]), o($VC, [2, 67]), o($VD, [2, 68]), o($VD, [2, 69]), { 8: [1, 89], 23: 90, 38: 88, 41: 22, 44: $V4 }, { 16: 91, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm }, { 43: 92, 47: $VE }, { 46: [1, 94] }, { 13: [1, 95] }, { 13: [1, 96] }, { 70: [1, 97], 72: [1, 98] }, { 21: $VF, 73: $VG, 74: $VH, 75: 99, 77: 100, 79: 101, 80: $VI, 81: $VJ, 82: $VK, 83: $VL, 84: $VM, 85: $VN }, { 74: [1, 111] }, { 13: $Vy, 51: 112 }, o($Vp, [2, 54]), o($Vp, [2, 117]), o($Vz, [2, 13]), o($Vz, [2, 14]), o($Vz, [2, 15]), { 37: [2, 32] }, { 15: 113, 16: 79, 37: [2, 9], 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm }, o($VO, [2, 40], { 11: 114, 12: [1, 115] }), o($Vo, [2, 7]), { 9: [1, 116] }, o($VP, [2, 49]), { 16: 37, 17: 117, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 13: [1, 119], 16: 37, 17: 118, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($VB, [2, 61], { 57: 120, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu }), o($VB, [2, 60]), { 39: [1, 121] }, { 23: 90, 38: 122, 41: 22, 44: $V4 }, { 8: [1, 123], 39: [2, 33] }, o($Vx, [2, 37], { 37: [1, 124] }), { 39: [1, 125] }, { 39: [2, 43], 43: 126, 47: $VE }, { 16: 37, 17: 127, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($Vp, [2, 70], { 13: [1, 128] }), o($Vp, [2, 72], { 13: [1, 130], 68: [1, 129] }), o($Vp, [2, 76], { 13: [1, 131], 71: [1, 132] }), { 13: [1, 133] }, o($Vp, [2, 84], { 78: [1, 134] }), o($VQ, [2, 86], { 79: 135, 21: $VF, 73: $VG, 74: $VH, 80: $VI, 81: $VJ, 82: $VK, 83: $VL, 84: $VM, 85: $VN }), o($VR, [2, 88]), o($VR, [2, 90]), o($VR, [2, 91]), o($VR, [2, 92]), o($VR, [2, 93]), o($VR, [2, 94]), o($VR, [2, 95]), o($VR, [2, 96]), o($VR, [2, 97]), o($VR, [2, 98]), o($Vp, [2, 85]), o($Vp, [2, 53]), { 37: [2, 10] }, o($VO, [2, 41]), { 13: [1, 136] }, { 1: [2, 4] }, o($VP, [2, 51]), o($VP, [2, 50]), { 16: 37, 17: 137, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($VB, [2, 59]), o($Vp, [2, 30]), { 39: [1, 138] }, { 23: 90, 38: 139, 39: [2, 34], 41: 22, 44: $V4 }, { 43: 140, 47: $VE }, o($Vx, [2, 38]), { 39: [2, 44] }, o($Vp, [2, 42]), o($Vp, [2, 71]), o($Vp, [2, 73]), o($Vp, [2, 74], { 68: [1, 141] }), o($Vp, [2, 77]), o($Vp, [2, 78], { 13: [1, 142] }), o($Vp, [2, 80], { 13: [1, 144], 68: [1, 143] }), { 21: $VF, 73: $VG, 74: $VH, 77: 145, 79: 101, 80: $VI, 81: $VJ, 82: $VK, 83: $VL, 84: $VM, 85: $VN }, o($VR, [2, 89]), { 14: [1, 146] }, o($VP, [2, 52]), o($Vp, [2, 31]), { 39: [2, 35] }, { 39: [1, 147] }, o($Vp, [2, 75]), o($Vp, [2, 79]), o($Vp, [2, 81]), o($Vp, [2, 82], { 68: [1, 148] }), o($VQ, [2, 87], { 79: 135, 21: $VF, 73: $VG, 74: $VH, 80: $VI, 81: $VJ, 82: $VK, 83: $VL, 84: $VM, 85: $VN }), o($VO, [2, 8]), o($Vx, [2, 39]), o($Vp, [2, 83])], + defaultActions: { 2: [2, 1], 3: [2, 2], 4: [2, 3], 78: [2, 32], 113: [2, 10], 116: [2, 4], 126: [2, 44], 139: [2, 35] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 53; + case 1: + return 54; + case 2: + return 55; + case 3: + return 56; + case 4: + break; + case 5: + break; + case 6: + this.begin("acc_title"); + return 31; + case 7: + this.popState(); + return "acc_title_value"; + case 8: + this.begin("acc_descr"); + return 33; + case 9: + this.popState(); + return "acc_descr_value"; + case 10: + this.begin("acc_descr_multiline"); + break; + case 11: + this.popState(); + break; + case 12: + return "acc_descr_multiline_value"; + case 13: + return 8; + case 14: + break; + case 15: + return 7; + case 16: + return 7; + case 17: + return "EDGE_STATE"; + case 18: + this.begin("callback_name"); + break; + case 19: + this.popState(); + break; + case 20: + this.popState(); + this.begin("callback_args"); + break; + case 21: + return 70; + case 22: + this.popState(); + break; + case 23: + return 71; + case 24: + this.popState(); + break; + case 25: + return "STR"; + case 26: + this.begin("string"); + break; + case 27: + return 73; + case 28: + this.begin("namespace"); + return 40; + case 29: + this.popState(); + return 8; + case 30: + break; + case 31: + this.begin("namespace-body"); + return 37; + case 32: + this.popState(); + return 39; + case 33: + return "EOF_IN_STRUCT"; + case 34: + return 8; + case 35: + break; + case 36: + return "EDGE_STATE"; + case 37: + this.begin("class"); + return 44; + case 38: + this.popState(); + return 8; + case 39: + break; + case 40: + this.popState(); + this.popState(); + return 39; + case 41: + this.begin("class-body"); + return 37; + case 42: + this.popState(); + return 39; + case 43: + return "EOF_IN_STRUCT"; + case 44: + return "EDGE_STATE"; + case 45: + return "OPEN_IN_STRUCT"; + case 46: + break; + case 47: + return "MEMBER"; + case 48: + return 76; + case 49: + return 66; + case 50: + return 67; + case 51: + return 69; + case 52: + return 50; + case 53: + return 52; + case 54: + return 45; + case 55: + return 46; + case 56: + return 72; + case 57: + this.popState(); + break; + case 58: + return "GENERICTYPE"; + case 59: + this.begin("generic"); + break; + case 60: + this.popState(); + break; + case 61: + return "BQUOTE_STR"; + case 62: + this.begin("bqstring"); + break; + case 63: + return 68; + case 64: + return 68; + case 65: + return 68; + case 66: + return 68; + case 67: + return 60; + case 68: + return 60; + case 69: + return 62; + case 70: + return 62; + case 71: + return 61; + case 72: + return 59; + case 73: + return 63; + case 74: + return 64; + case 75: + return 65; + case 76: + return 21; + case 77: + return 42; + case 78: + return 95; + case 79: + return "DOT"; + case 80: + return "PLUS"; + case 81: + return 81; + case 82: + return 78; + case 83: + return 84; + case 84: + return 84; + case 85: + return 85; + case 86: + return "EQUALS"; + case 87: + return "EQUALS"; + case 88: + return 74; + case 89: + return 12; + case 90: + return 14; + case 91: + return "PUNCTUATION"; + case 92: + return 80; + case 93: + return 97; + case 94: + return 83; + case 95: + return 83; + case 96: + return 9; + } + }, + rules: [/^(?:.*direction\s+TB[^\n]*)/, /^(?:.*direction\s+BT[^\n]*)/, /^(?:.*direction\s+RL[^\n]*)/, /^(?:.*direction\s+LR[^\n]*)/, /^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/, /^(?:%%[^\n]*(\r?\n)*)/, /^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:classDiagram-v2\b)/, /^(?:classDiagram\b)/, /^(?:\[\*\])/, /^(?:call[\s]+)/, /^(?:\([\s]*\))/, /^(?:\()/, /^(?:[^(]*)/, /^(?:\))/, /^(?:[^)]*)/, /^(?:["])/, /^(?:[^"]*)/, /^(?:["])/, /^(?:style\b)/, /^(?:namespace\b)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:[{])/, /^(?:[}])/, /^(?:$)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:\[\*\])/, /^(?:class\b)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:[}])/, /^(?:[{])/, /^(?:[}])/, /^(?:$)/, /^(?:\[\*\])/, /^(?:[{])/, /^(?:[\n])/, /^(?:[^{}\n]*)/, /^(?:cssClass\b)/, /^(?:callback\b)/, /^(?:link\b)/, /^(?:click\b)/, /^(?:note for\b)/, /^(?:note\b)/, /^(?:<<)/, /^(?:>>)/, /^(?:href\b)/, /^(?:[~])/, /^(?:[^~]*)/, /^(?:~)/, /^(?:[`])/, /^(?:[^`]+)/, /^(?:[`])/, /^(?:_self\b)/, /^(?:_blank\b)/, /^(?:_parent\b)/, /^(?:_top\b)/, /^(?:\s*<\|)/, /^(?:\s*\|>)/, /^(?:\s*>)/, /^(?:\s*<)/, /^(?:\s*\*)/, /^(?:\s*o\b)/, /^(?:\s*\(\))/, /^(?:--)/, /^(?:\.\.)/, /^(?::{1}[^:\n;]+)/, /^(?::{3})/, /^(?:-)/, /^(?:\.)/, /^(?:\+)/, /^(?::)/, /^(?:,)/, /^(?:#)/, /^(?:#)/, /^(?:%)/, /^(?:=)/, /^(?:=)/, /^(?:\w+)/, /^(?:\[)/, /^(?:\])/, /^(?:[!"#$%&'*+,-.`?\\/])/, /^(?:[0-9]+)/, /^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/, /^(?:\s)/, /^(?:\s)/, /^(?:$)/], + conditions: { "namespace-body": { "rules": [26, 32, 33, 34, 35, 36, 37, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "namespace": { "rules": [26, 28, 29, 30, 31, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "class-body": { "rules": [26, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "class": { "rules": [26, 38, 39, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "acc_descr_multiline": { "rules": [11, 12, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "acc_descr": { "rules": [9, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "acc_title": { "rules": [7, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "callback_args": { "rules": [22, 23, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "callback_name": { "rules": [19, 20, 21, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "href": { "rules": [26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "struct": { "rules": [26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "generic": { "rules": [26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "bqstring": { "rules": [26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "string": { "rules": [24, 25, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 8, 10, 13, 14, 15, 16, 17, 18, 26, 27, 28, 37, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const visibilityValues = ["#", "+", "~", "-", ""]; +class ClassMember { + constructor(input, memberType) { + this.memberType = memberType; + this.visibility = ""; + this.classifier = ""; + const sanitizedInput = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)(input, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + this.parseMember(sanitizedInput); + } + getDisplayDetails() { + let displayText = this.visibility + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.x)(this.id); + if (this.memberType === "method") { + displayText += `(${(0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.x)(this.parameters.trim())})`; + if (this.returnType) { + displayText += " : " + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.x)(this.returnType); + } + } + displayText = displayText.trim(); + const cssStyle = this.parseClassifier(); + return { + displayText, + cssStyle + }; + } + parseMember(input) { + let potentialClassifier = ""; + if (this.memberType === "method") { + const methodRegEx = /([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/; + const match = input.match(methodRegEx); + if (match) { + const detectedVisibility = match[1] ? match[1].trim() : ""; + if (visibilityValues.includes(detectedVisibility)) { + this.visibility = detectedVisibility; + } + this.id = match[2].trim(); + this.parameters = match[3] ? match[3].trim() : ""; + potentialClassifier = match[4] ? match[4].trim() : ""; + this.returnType = match[5] ? match[5].trim() : ""; + if (potentialClassifier === "") { + const lastChar = this.returnType.substring(this.returnType.length - 1); + if (lastChar.match(/[$*]/)) { + potentialClassifier = lastChar; + this.returnType = this.returnType.substring(0, this.returnType.length - 1); + } + } + } + } else { + const length = input.length; + const firstChar = input.substring(0, 1); + const lastChar = input.substring(length - 1); + if (visibilityValues.includes(firstChar)) { + this.visibility = firstChar; + } + if (lastChar.match(/[$*]/)) { + potentialClassifier = lastChar; + } + this.id = input.substring( + this.visibility === "" ? 0 : 1, + potentialClassifier === "" ? length : length - 1 + ); + } + this.classifier = potentialClassifier; + } + parseClassifier() { + switch (this.classifier) { + case "*": + return "font-style:italic;"; + case "$": + return "text-decoration:underline;"; + default: + return ""; + } + } +} +const MERMAID_DOM_ID_PREFIX = "classId-"; +let relations = []; +let classes = {}; +let notes = []; +let classCounter = 0; +let namespaces = {}; +let namespaceCounter = 0; +let functions = []; +const sanitizeText = (txt) => _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(txt, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); +const splitClassNameAndType = function(_id) { + const id = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + let genericType = ""; + let className = id; + if (id.indexOf("~") > 0) { + const split = id.split("~"); + className = sanitizeText(split[0]); + genericType = sanitizeText(split[1]); + } + return { className, type: genericType }; +}; +const setClassLabel = function(_id, label) { + const id = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + if (label) { + label = sanitizeText(label); + } + const { className } = splitClassNameAndType(id); + classes[className].label = label; +}; +const addClass = function(_id) { + const id = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + const { className, type } = splitClassNameAndType(id); + if (Object.hasOwn(classes, className)) { + return; + } + const name = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(className, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + classes[name] = { + id: name, + type, + label: name, + cssClasses: [], + methods: [], + members: [], + annotations: [], + styles: [], + domId: MERMAID_DOM_ID_PREFIX + name + "-" + classCounter + }; + classCounter++; +}; +const lookUpDomId = function(_id) { + const id = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + if (id in classes) { + return classes[id].domId; + } + throw new Error("Class not found: " + id); +}; +const clear = function() { + relations = []; + classes = {}; + notes = []; + functions = []; + functions.push(setupToolTips); + namespaces = {}; + namespaceCounter = 0; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.v)(); +}; +const getClass = function(id) { + return classes[id]; +}; +const getClasses = function() { + return classes; +}; +const getRelations = function() { + return relations; +}; +const getNotes = function() { + return notes; +}; +const addRelation = function(relation) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("Adding relation: " + JSON.stringify(relation)); + addClass(relation.id1); + addClass(relation.id2); + relation.id1 = splitClassNameAndType(relation.id1).className; + relation.id2 = splitClassNameAndType(relation.id2).className; + relation.relationTitle1 = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(relation.relationTitle1.trim(), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + relation.relationTitle2 = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(relation.relationTitle2.trim(), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + relations.push(relation); +}; +const addAnnotation = function(className, annotation) { + const validatedClassName = splitClassNameAndType(className).className; + classes[validatedClassName].annotations.push(annotation); +}; +const addMember = function(className, member) { + addClass(className); + const validatedClassName = splitClassNameAndType(className).className; + const theClass = classes[validatedClassName]; + if (typeof member === "string") { + const memberString = member.trim(); + if (memberString.startsWith("<<") && memberString.endsWith(">>")) { + theClass.annotations.push(sanitizeText(memberString.substring(2, memberString.length - 2))); + } else if (memberString.indexOf(")") > 0) { + theClass.methods.push(new ClassMember(memberString, "method")); + } else if (memberString) { + theClass.members.push(new ClassMember(memberString, "attribute")); + } + } +}; +const addMembers = function(className, members) { + if (Array.isArray(members)) { + members.reverse(); + members.forEach((member) => addMember(className, member)); + } +}; +const addNote = function(text, className) { + const note = { + id: `note${notes.length}`, + class: className, + text + }; + notes.push(note); +}; +const cleanupLabel = function(label) { + if (label.startsWith(":")) { + label = label.substring(1); + } + return sanitizeText(label.trim()); +}; +const setCssClass = function(ids, className) { + ids.split(",").forEach(function(_id) { + let id = _id; + if (_id[0].match(/\d/)) { + id = MERMAID_DOM_ID_PREFIX + id; + } + if (classes[id] !== void 0) { + classes[id].cssClasses.push(className); + } + }); +}; +const setTooltip = function(ids, tooltip) { + ids.split(",").forEach(function(id) { + if (tooltip !== void 0) { + classes[id].tooltip = sanitizeText(tooltip); + } + }); +}; +const getTooltip = function(id, namespace) { + if (namespace) { + return namespaces[namespace].classes[id].tooltip; + } + return classes[id].tooltip; +}; +const setLink = function(ids, linkStr, target) { + const config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + ids.split(",").forEach(function(_id) { + let id = _id; + if (_id[0].match(/\d/)) { + id = MERMAID_DOM_ID_PREFIX + id; + } + if (classes[id] !== void 0) { + classes[id].link = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.formatUrl(linkStr, config); + if (config.securityLevel === "sandbox") { + classes[id].linkTarget = "_top"; + } else if (typeof target === "string") { + classes[id].linkTarget = sanitizeText(target); + } else { + classes[id].linkTarget = "_blank"; + } + } + }); + setCssClass(ids, "clickable"); +}; +const setClickEvent = function(ids, functionName, functionArgs) { + ids.split(",").forEach(function(id) { + setClickFunc(id, functionName, functionArgs); + classes[id].haveCallback = true; + }); + setCssClass(ids, "clickable"); +}; +const setClickFunc = function(_domId, functionName, functionArgs) { + const domId = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_domId, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + const config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + if (config.securityLevel !== "loose") { + return; + } + if (functionName === void 0) { + return; + } + const id = domId; + if (classes[id] !== void 0) { + const elemId = lookUpDomId(id); + let argList = []; + if (typeof functionArgs === "string") { + argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); + for (let i = 0; i < argList.length; i++) { + let item = argList[i].trim(); + if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') { + item = item.substr(1, item.length - 2); + } + argList[i] = item; + } + } + if (argList.length === 0) { + argList.push(elemId); + } + functions.push(function() { + const elem = document.querySelector(`[id="${elemId}"]`); + if (elem !== null) { + elem.addEventListener( + "click", + function() { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.runFunc(functionName, ...argList); + }, + false + ); + } + }); + } +}; +const bindFunctions = function(element) { + functions.forEach(function(fun) { + fun(element); + }); +}; +const lineType = { + LINE: 0, + DOTTED_LINE: 1 +}; +const relationType = { + AGGREGATION: 0, + EXTENSION: 1, + COMPOSITION: 2, + DEPENDENCY: 3, + LOLLIPOP: 4 +}; +const setupToolTips = function(element) { + let tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(".mermaidTooltip"); + if ((tooltipElem._groups || tooltipElem)[0][0] === null) { + tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body").append("div").attr("class", "mermaidTooltip").style("opacity", 0); + } + const svg = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(element).select("svg"); + const nodes = svg.selectAll("g.node"); + nodes.on("mouseover", function() { + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(this); + const title = el.attr("title"); + if (title === null) { + return; + } + const rect = this.getBoundingClientRect(); + tooltipElem.transition().duration(200).style("opacity", ".9"); + tooltipElem.text(el.attr("title")).style("left", window.scrollX + rect.left + (rect.right - rect.left) / 2 + "px").style("top", window.scrollY + rect.top - 14 + document.body.scrollTop + "px"); + tooltipElem.html(tooltipElem.html().replace(/<br\/>/g, "<br/>")); + el.classed("hover", true); + }).on("mouseout", function() { + tooltipElem.transition().duration(500).style("opacity", 0); + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(this); + el.classed("hover", false); + }); +}; +functions.push(setupToolTips); +let direction = "TB"; +const getDirection = () => direction; +const setDirection = (dir) => { + direction = dir; +}; +const addNamespace = function(id) { + if (namespaces[id] !== void 0) { + return; + } + namespaces[id] = { + id, + classes: {}, + children: {}, + domId: MERMAID_DOM_ID_PREFIX + id + "-" + namespaceCounter + }; + namespaceCounter++; +}; +const getNamespace = function(name) { + return namespaces[name]; +}; +const getNamespaces = function() { + return namespaces; +}; +const addClassesToNamespace = function(id, classNames) { + if (namespaces[id] === void 0) { + return; + } + for (const name of classNames) { + const { className } = splitClassNameAndType(name); + classes[className].parent = id; + namespaces[id].classes[className] = classes[className]; + } +}; +const setCssStyle = function(id, styles2) { + const thisClass = classes[id]; + if (!styles2 || !thisClass) { + return; + } + for (const s of styles2) { + if (s.includes(",")) { + thisClass.styles.push(...s.split(",")); + } else { + thisClass.styles.push(s); + } + } +}; +const db = { + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.g, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.a, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.b, + getConfig: () => (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().class, + addClass, + bindFunctions, + clear, + getClass, + getClasses, + getNotes, + addAnnotation, + addNote, + getRelations, + addRelation, + getDirection, + setDirection, + addMember, + addMembers, + cleanupLabel, + lineType, + relationType, + setClickEvent, + setCssClass, + setLink, + getTooltip, + setTooltip, + lookUpDomId, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.t, + setClassLabel, + addNamespace, + addClassesToNamespace, + getNamespace, + getNamespaces, + setCssStyle +}; +const getStyles = (options) => `g.classGroup text { + fill: ${options.nodeBorder || options.classText}; + stroke: none; + font-family: ${options.fontFamily}; + font-size: 10px; + + .title { + font-weight: bolder; + } + +} + +.nodeLabel, .edgeLabel { + color: ${options.classText}; +} +.edgeLabel .label rect { + fill: ${options.mainBkg}; +} +.label text { + fill: ${options.classText}; +} +.edgeLabel .label span { + background: ${options.mainBkg}; +} + +.classTitle { + font-weight: bolder; +} +.node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + + +.divider { + stroke: ${options.nodeBorder}; + stroke-width: 1; +} + +g.clickable { + cursor: pointer; +} + +g.classGroup rect { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; +} + +g.classGroup line { + stroke: ${options.nodeBorder}; + stroke-width: 1; +} + +.classLabel .box { + stroke: none; + stroke-width: 0; + fill: ${options.mainBkg}; + opacity: 0.5; +} + +.classLabel .label { + fill: ${options.nodeBorder}; + font-size: 10px; +} + +.relation { + stroke: ${options.lineColor}; + stroke-width: 1; + fill: none; +} + +.dashed-line{ + stroke-dasharray: 3; +} + +.dotted-line{ + stroke-dasharray: 1 2; +} + +#compositionStart, .composition { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#compositionEnd, .composition { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#dependencyStart, .dependency { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#dependencyStart, .dependency { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#extensionStart, .extension { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#extensionEnd, .extension { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#aggregationStart, .aggregation { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#aggregationEnd, .aggregation { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#lollipopStart, .lollipop { + fill: ${options.mainBkg} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#lollipopEnd, .lollipop { + fill: ${options.mainBkg} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +.edgeTerminals { + font-size: 11px; + line-height: initial; +} + +.classTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; +} +`; +const styles = getStyles; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/4.b946d741.js b/assets/js/4.b946d741.js new file mode 100644 index 0000000000..5ec8085bcf --- /dev/null +++ b/assets/js/4.b946d741.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4],{4:(e,t,l)=>{l.d(t,{diagram:()=>f});var n=l(27308),a=l(26312),o=l(697),i=l(76257),s=l(92746);l(74353),l(16750),l(42838),l(21176),l(14075);const d=e=>i.e.sanitizeText(e,(0,i.c)());let r={dividerMargin:10,padding:5,textHeight:10,curve:void 0};const c=function(e,t,l,n,a){const o=Object.keys(e);i.l.info("keys:",o),i.l.info(e),o.filter((t=>e[t].parent==a)).forEach((function(l){var o,s;const r=e[l],c=r.cssClasses.join(" "),p=(0,i.k)(r.styles),b=r.label??r.id,f={labelStyle:p.labelStyle,shape:"class_box",labelText:d(b),classData:r,rx:0,ry:0,class:c,style:p.style,id:r.id,domId:r.domId,tooltip:n.db.getTooltip(r.id,a)||"",haveCallback:r.haveCallback,link:r.link,width:"group"===r.type?500:void 0,type:r.type,padding:(null==(o=(0,i.c)().flowchart)?void 0:o.padding)??(null==(s=(0,i.c)().class)?void 0:s.padding)};t.setNode(r.id,f),a&&t.setParent(r.id,a),i.l.info("setNode",f)}))};function p(e){let t;switch(e){case 0:t="aggregation";break;case 1:t="extension";break;case 2:t="composition";break;case 3:t="dependency";break;case 4:t="lollipop";break;default:t="none"}return t}const b={setConf:function(e){r={...r,...e}},draw:async function(e,t,l,n){i.l.info("Drawing class - ",t);const b=(0,i.c)().flowchart??(0,i.c)().class,f=(0,i.c)().securityLevel;i.l.info("config:",b);const y=(null==b?void 0:b.nodeSpacing)??50,u=(null==b?void 0:b.rankSpacing)??50,g=new o.T({multigraph:!0,compound:!0}).setGraph({rankdir:n.db.getDirection(),nodesep:y,ranksep:u,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}})),h=n.db.getNamespaces(),v=n.db.getClasses(),w=n.db.getRelations(),k=n.db.getNotes();let x;i.l.info(w),function(e,t,l,n){const a=Object.keys(e);i.l.info("keys:",a),i.l.info(e),a.forEach((function(a){var o,s;const r=e[a],p={shape:"rect",id:r.id,domId:r.domId,labelText:d(r.id),labelStyle:"",style:"fill: none; stroke: black",padding:(null==(o=(0,i.c)().flowchart)?void 0:o.padding)??(null==(s=(0,i.c)().class)?void 0:s.padding)};t.setNode(r.id,p),c(r.classes,t,l,n,r.id),i.l.info("setNode",p)}))}(h,g,t,n),c(v,g,t,n),function(e,t){const l=(0,i.c)().flowchart;let n=0;e.forEach((function(e){var o;n++;const s={classes:"relation",pattern:1==e.relation.lineType?"dashed":"solid",id:`id_${e.id1}_${e.id2}_${n}`,arrowhead:"arrow_open"===e.type?"none":"normal",startLabelRight:"none"===e.relationTitle1?"":e.relationTitle1,endLabelLeft:"none"===e.relationTitle2?"":e.relationTitle2,arrowTypeStart:p(e.relation.type1),arrowTypeEnd:p(e.relation.type2),style:"fill:none",labelStyle:"",curve:(0,i.n)(null==l?void 0:l.curve,a.lUB)};if(i.l.info(s,e),void 0!==e.style){const t=(0,i.k)(e.style);s.style=t.style,s.labelStyle=t.labelStyle}e.text=e.title,void 0===e.text?void 0!==e.style&&(s.arrowheadStyle="fill: #333"):(s.arrowheadStyle="fill: #333",s.labelpos="c",(null==(o=(0,i.c)().flowchart)?void 0:o.htmlLabels)??(0,i.c)().htmlLabels?(s.labelType="html",s.label='<span class="edgeLabel">'+e.text+"</span>"):(s.labelType="text",s.label=e.text.replace(i.e.lineBreakRegex,"\n"),void 0===e.style&&(s.style=s.style||"stroke: #333; stroke-width: 1.5px;fill:none"),s.labelStyle=s.labelStyle.replace("color:","fill:"))),t.setEdge(e.id1,e.id2,s,n)}))}(w,g),function(e,t,l,n){i.l.info(e),e.forEach((function(e,o){var s,c;const p=e,b="",f="",y=p.text,u={labelStyle:b,shape:"note",labelText:d(y),noteData:p,rx:0,ry:0,class:"",style:f,id:p.id,domId:p.id,tooltip:"",type:"note",padding:(null==(s=(0,i.c)().flowchart)?void 0:s.padding)??(null==(c=(0,i.c)().class)?void 0:c.padding)};if(t.setNode(p.id,u),i.l.info("setNode",u),!p.class||!(p.class in n))return;const g=l+o,h={id:`edgeNote${g}`,classes:"relation",pattern:"dotted",arrowhead:"none",startLabelRight:"",endLabelLeft:"",arrowTypeStart:"none",arrowTypeEnd:"none",style:"fill:none",labelStyle:"",curve:(0,i.n)(r.curve,a.lUB)};t.setEdge(p.id,p.class,h,g)}))}(k,g,w.length+1,v),"sandbox"===f&&(x=(0,a.Ltv)("#i"+t));const m="sandbox"===f?(0,a.Ltv)(x.nodes()[0].contentDocument.body):(0,a.Ltv)("body"),T=m.select(`[id="${t}"]`),S=m.select("#"+t+" g");if(await(0,s.r)(S,g,["aggregation","extension","composition","dependency","lollipop"],"classDiagram",t),i.u.insertTitle(T,"classTitleText",(null==b?void 0:b.titleTopMargin)??5,n.db.getDiagramTitle()),(0,i.o)(g,T,null==b?void 0:b.diagramPadding,null==b?void 0:b.useMaxWidth),!(null==b?void 0:b.htmlLabels)){const e="sandbox"===f?x.nodes()[0].contentDocument:document,l=e.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const t of l){const l=t.getBBox(),n=e.createElementNS("http://www.w3.org/2000/svg","rect");n.setAttribute("rx",0),n.setAttribute("ry",0),n.setAttribute("width",l.width),n.setAttribute("height",l.height),t.insertBefore(n,t.firstChild)}}}},f={parser:n.p,db:n.d,renderer:b,styles:n.s,init:e=>{e.class||(e.class={}),e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute,n.d.clear()}}}}]); \ No newline at end of file diff --git a/assets/js/40d9468c.b9fc055a.js b/assets/js/40d9468c.b9fc055a.js new file mode 100644 index 0000000000..1f8a2503a5 --- /dev/null +++ b/assets/js/40d9468c.b9fc055a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[783],{63435:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>n,metadata:()=>r,toc:()=>a});var i=t(74848),l=t(28453);const n={sidebar_label:"Developer Guide"},o="Developer Guide",r={id:"iaas/guides/other-guides/developer-guide/index",title:"Developer Guide",description:"How to add a new service",source:"@site/docs/02-iaas/guides/other-guides/developer-guide/index.md",sourceDirName:"02-iaas/guides/other-guides/developer-guide",slug:"/iaas/guides/other-guides/developer-guide/",permalink:"/docs/iaas/guides/other-guides/developer-guide/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/developer-guide/index.md",tags:[],version:"current",frontMatter:{sidebar_label:"Developer Guide"},sidebar:"docs",previous:{title:"Contributor Guide",permalink:"/docs/iaas/guides/other-guides/contributor-guide"},next:{title:"Releases",permalink:"/docs/iaas/guides/other-guides/developer-guide/releases"}},d={},a=[{value:"How to add a new service",id:"how-to-add-a-new-service",level:2},{value:"How to add a new container image",id:"how-to-add-a-new-container-image",level:2},{value:"How service deployment works",id:"how-service-deployment-works",level:2},{value:"Docker",id:"docker",level:3},{value:"Kubernetes",id:"kubernetes",level:3}];function c(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,l.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h1,{id:"developer-guide",children:"Developer Guide"}),"\n",(0,i.jsx)(s.h2,{id:"how-to-add-a-new-service",children:"How to add a new service"}),"\n",(0,i.jsxs)(s.p,{children:["If you want to add a new service to OSISM, this is done via an Ansible role and (most often)\na container image. The following steps are necessary and are demonstrated using the example\nof ",(0,i.jsx)(s.code,{children:"osism.services.cgit"}),"."]}),"\n",(0,i.jsxs)(s.table,{children:[(0,i.jsx)(s.thead,{children:(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.th,{style:{textAlign:"left"},children:"Description"}),(0,i.jsx)(s.th,{style:{textAlign:"left"},children:"Example"})]})}),(0,i.jsxs)(s.tbody,{children:[(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{style:{textAlign:"left"},children:"Add the Ansible role in one of the Ansible collection repositories"}),(0,i.jsx)(s.td,{style:{textAlign:"left"},children:(0,i.jsx)(s.a,{href:"https://github.com/osism/ansible-collection-services/pull/578/files",children:"https://github.com/osism/ansible-collection-services/pull/578/files"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{style:{textAlign:"left"},children:"Add the Ansible playbook"}),(0,i.jsx)(s.td,{style:{textAlign:"left"},children:(0,i.jsx)(s.a,{href:"https://github.com/osism/ansible-playbooks/pull/215/files",children:"https://github.com/osism/ansible-playbooks/pull/215/files"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{style:{textAlign:"left"},children:"Add the Ansible inventory group"}),(0,i.jsx)(s.td,{style:{textAlign:"left"},children:(0,i.jsx)(s.a,{href:"https://github.com/osism/cfg-generics/pull/225/files",children:"https://github.com/osism/cfg-generics/pull/225/files"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{style:{textAlign:"left"},children:"Add the used container image(s) to the release repository"}),(0,i.jsx)(s.td,{style:{textAlign:"left"},children:(0,i.jsx)(s.a,{href:"https://github.com/osism/release/pull/278/files",children:"https://github.com/osism/release/pull/278/files"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{style:{textAlign:"left"},children:"Add the container images(s) to osism-ansible container image"}),(0,i.jsx)(s.td,{style:{textAlign:"left"},children:(0,i.jsx)(s.a,{href:"https://github.com/osism/container-image-osism-ansible/pull/215/files",children:"https://github.com/osism/container-image-osism-ansible/pull/215/files"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{style:{textAlign:"left"},children:"Add the container image registry/registries and host(s) to the defaults repository"}),(0,i.jsx)(s.td,{style:{textAlign:"left"},children:(0,i.jsx)(s.a,{href:"https://github.com/osism/defaults/pull/54/files",children:"https://github.com/osism/defaults/pull/54/files"})})]}),(0,i.jsxs)(s.tr,{children:[(0,i.jsx)(s.td,{style:{textAlign:"left"},children:"Add a sample deployment to the testbed"}),(0,i.jsx)(s.td,{style:{textAlign:"left"},children:(0,i.jsx)(s.a,{href:"https://github.com/osism/testbed/pull/1043/files",children:"https://github.com/osism/testbed/pull/1043/files"})})]})]})]}),"\n",(0,i.jsx)(s.h2,{id:"how-to-add-a-new-container-image",children:"How to add a new container image"}),"\n",(0,i.jsxs)(s.p,{children:["If required, add a new container image in the ",(0,i.jsx)(s.a,{href:"https://github.com/osism/container-images",children:"osism/container-images"}),"\nrepository. The example here is from the ",(0,i.jsx)(s.code,{children:"osism.services.keycloak"})," role: ",(0,i.jsx)(s.a,{href:"https://github.com/osism/container-images/pull/34/files",children:"https://github.com/osism/container-images/pull/34/files"}),"."]}),"\n",(0,i.jsx)(s.p,{children:"Whenever possible, upstream container images should be used. If only minor customizations are necessary,\nalways work with overlay container images based on upstream container images."}),"\n",(0,i.jsx)(s.h2,{id:"how-service-deployment-works",children:"How service deployment works"}),"\n",(0,i.jsx)(s.h3,{id:"docker",children:"Docker"}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{alt:"Service deployment with Docker",src:t(44601).A+"",width:"281",height:"892"})}),"\n",(0,i.jsx)(s.h3,{id:"kubernetes",children:"Kubernetes"}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{alt:"Service deployment with Kubernetes",src:t(31469).A+"",width:"281",height:"902"})})]})}function h(e={}){const{wrapper:s}={...(0,l.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},44601:(e,s,t)=>{t.d(s,{A:()=>i});const i=t.p+"assets/images/service-with-docker.drawio-21d9ff770c727c43ab477f857b5017e2.png"},31469:(e,s,t)=>{t.d(s,{A:()=>i});const i=t.p+"assets/images/service-with-kubernetes.drawio-9500d1fb61ca22792d8277f9f06e58ce.png"},28453:(e,s,t)=>{t.d(s,{R:()=>o,x:()=>r});var i=t(96540);const l={},n=i.createContext(l);function o(e){const s=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function r(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:o(e.components),i.createElement(n.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4129286c.fcb59d86.js b/assets/js/4129286c.fcb59d86.js new file mode 100644 index 0000000000..4f149c6292 --- /dev/null +++ b/assets/js/4129286c.fcb59d86.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9730],{81142:s=>{s.exports=JSON.parse('{"name":"@easyops-cn/docusaurus-search-local","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/41ab9761.3c032c6d.js b/assets/js/41ab9761.3c032c6d.js new file mode 100644 index 0000000000..90f3ed202e --- /dev/null +++ b/assets/js/41ab9761.3c032c6d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5676],{579:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>s,default:()=>_,frontMatter:()=>d,metadata:()=>l,toc:()=>r});var a=t(74848),i=t(28453);const d={title:"Metering Configuration",type:null,status:"Draft",track:"Global"},s=void 0,l={id:"operating-scs/metering/meter_configuration",title:"Metering Configuration",description:"The Metrics and events we want to use in the metering process can be defined in two ways. The first one is to allow ceilometer to poll distinct metrics and events.",source:"@site/docs/04-operating-scs/07-metering/meter_configuration.md",sourceDirName:"04-operating-scs/07-metering",slug:"/operating-scs/metering/meter_configuration",permalink:"/docs/operating-scs/metering/meter_configuration",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/07-metering/meter_configuration.md",tags:[],version:"current",frontMatter:{title:"Metering Configuration",type:null,status:"Draft",track:"Global"},sidebar:"docs",previous:{title:"Metering",permalink:"/docs/category/metering"},next:{title:"Introduction on Identity Management and Federation in SCS",permalink:"/docs/iam/"}},o={},r=[{value:"1. ceilometer metering configuration",id:"1-ceilometer-metering-configuration",level:2},{value:"1.1 polling.yaml",id:"11-pollingyaml",level:3},{value:"1.2 event_definitions.yaml",id:"12-event_definitionsyaml",level:3},{value:"1.3 event_pipeline.yaml",id:"13-event_pipelineyaml",level:3},{value:"1.4 pipeline.yaml",id:"14-pipelineyaml",level:3}];function p(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.p,{children:"The Metrics and events we want to use in the metering process can be defined in two ways. The first one is to allow ceilometer to poll distinct metrics and events.\nThis can be achived by setting up ceilometers config files."}),"\n",(0,a.jsx)(n.h2,{id:"1-ceilometer-metering-configuration",children:"1. ceilometer metering configuration"}),"\n",(0,a.jsx)(n.p,{children:"there is the polling.yaml file that describes what metrics to poll and when. It allows to create multiple sources for the ceilometer pipeline with different metrics and intervals."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://docs.openstack.org/ceilometer/latest/admin/telemetry-data-collection.html#polling",children:"ceilometer polling"}),"\n",(0,a.jsx)(n.a,{href:"https://docs.openstack.org/ceilometer/latest/admin/telemetry-measurements.html#telemetry-bare-metal-service",children:"ceilometer polling metrics"})]}),"\n",(0,a.jsx)(n.h3,{id:"11-pollingyaml",children:"1.1 polling.yaml"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"---\nsources:\n - name: billing_source # 'source name'\n interval: 300 # 'how often the samples should be generated'\n meters:\n - \"volume.size\" # 'meter filter'\n # - \"*\" # 'using all pollsters\n"})}),"\n",(0,a.jsx)(n.p,{children:"in the event_definitions file all data structure of events are defined. If a message with a distinct event_type appears, the Fields and values from the message are matched with the Event-object."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://docs.openstack.org/ceilometer/latest/admin/telemetry-events.html",children:"ceilometer events"}),"\n",(0,a.jsx)(n.a,{href:"https://github.com/openstack/ceilometer/blob/master/ceilometer/pipeline/data/event_definitions.yaml",children:"ceilometer event_definitions"})]}),"\n",(0,a.jsx)(n.h3,{id:"12-event_definitionsyaml",children:"1.2 event_definitions.yaml"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'---\n- event_type: "compute.instance.*"\n traits: &instance_traits\n tenant_id:\n fields: payload.tenant_id\n user_id:\n fields: payload.user_id\n instance_id:\n fields: payload.instance_id\n display_name:\n fields: payload.display_name\n resource_id:\n fields: payload.instance_id\n cell_name:\n fields: payload.cell_name\n host:\n fields: publisher_id.`split(., 1, 1)`\n service:\n fields: publisher_id.`split(., 0, -1)`\n memory_mb:\n type: int\n fields: payload.memory_mb\n disk_gb:\n type: int\n fields: payload.disk_gb\n root_gb:\n type: int\n fields: payload.root_gb\n ephemeral_gb:\n type: int\n fields: payload.ephemeral_gb\n vcpus:\n type: int\n fields: payload.vcpus\n instance_type_id:\n fields: payload.instance_type_id\n instance_type:\n fields: payload.instance_type\n state:\n fields: payload.state\n os_architecture:\n fields: payload.image_meta.\'org.openstack__1__architecture\'\n os_version:\n fields: payload.image_meta.\'org.openstack__1__os_version\'\n os_distro:\n fields: payload.image_meta.\'org.openstack__1__os_distro\'\n launched_at:\n type: datetime\n fields: payload.launched_at\n deleted_at:\n type: datetime\n fields: payload.deleted_at\n- event_type: compute.instance.create.end\n traits:\n <<: *instance_traits\n availability_zone:\n fields: payload.availability_zone\n- event_type: compute.instance.update\n traits:\n <<: *instance_traits\n old_state:\n fields: payload.old_state\n- event_type: compute.instance.exists\n traits:\n <<: *instance_traits\n audit_period_beginning:\n type: datetime\n fields: payload.audit_period_beginning\n audit_period_ending:\n type: datetime\n fields: payload.audit_period_ending\n- event_type:\n [\n "volume.exists",\n "volume.retype",\n "volume.create.*",\n "volume.delete.*",\n "volume.resize.*",\n "volume.attach.*",\n "volume.detach.*",\n "volume.update.*",\n "snapshot.exists",\n "snapshot.create.*",\n "snapshot.delete.*",\n "snapshot.update.*",\n "volume.transfer.accept.end",\n "snapshot.transfer.accept.end",\n ]\n traits: &cinder_traits\n user_id:\n fields: payload.user_id\n project_id:\n fields: payload.tenant_id\n availability_zone:\n fields: payload.availability_zone\n display_name:\n fields: payload.display_name\n replication_status:\n fields: payload.replication_status\n status:\n fields: payload.status\n created_at:\n type: datetime\n fields: payload.created_at\n image_id:\n fields: payload.glance_metadata[?key=image_id].value\n instance_id:\n fields: payload.volume_attachment[0].server_id\n- event_type:\n [\n "volume.transfer.*",\n "volume.exists",\n "volume.retype",\n "volume.create.*",\n "volume.delete.*",\n "volume.resize.*",\n "volume.attach.*",\n "volume.detach.*",\n "volume.update.*",\n "snapshot.transfer.accept.end",\n ]\n traits:\n <<: *cinder_traits\n resource_id:\n fields: payload.volume_id\n host:\n fields: payload.host\n size:\n type: int\n fields: payload.size\n type:\n fields: payload.volume_type\n replication_status:\n fields: payload.replication_status\n- event_type: ["snapshot.transfer.accept.end"]\n traits:\n <<: *cinder_traits\n resource_id:\n fields: payload.snapshot_id\n project_id:\n fields: payload.tenant_id\n- event_type:\n ["share.create.*", "share.delete.*", "share.extend.*", "share.shrink.*"]\n traits: &share_traits\n share_id:\n fields: payload.share_id\n user_id:\n fields: payload.user_id\n project_id:\n fields: payload.tenant_id\n snapshot_id:\n fields: payload.snapshot_id\n availability_zone:\n fields: payload.availability_zone\n status:\n fields: payload.status\n created_at:\n type: datetime\n fields: payload.created_at\n share_group_id:\n fields: payload.share_group_id\n size:\n type: int\n fields: payload.size\n name:\n fields: payload.name\n proto:\n fields: payload.proto\n is_public:\n fields: payload.is_public\n description:\n fields: payload.description\n host:\n fields: payload.host\n- event_type:\n [\n "snapshot.exists",\n "snapshot.create.*",\n "snapshot.delete.*",\n "snapshot.update.*",\n ]\n traits:\n <<: *cinder_traits\n resource_id:\n fields: payload.snapshot_id\n volume_id:\n fields: payload.volume_id\n- event_type: ["image_volume_cache.*"]\n traits:\n image_id:\n fields: payload.image_id\n host:\n fields: payload.host\n- event_type: ["image.create", "image.update", "image.upload", "image.delete"]\n traits: &glance_crud\n project_id:\n fields: payload.owner\n resource_id:\n fields: payload.id\n name:\n fields: payload.name\n status:\n fields: payload.status\n created_at:\n type: datetime\n fields: payload.created_at\n user_id:\n fields: payload.owner\n deleted_at:\n type: datetime\n fields: payload.deleted_at\n size:\n type: int\n fields: payload.size\n- event_type: image.send\n traits: &glance_send\n receiver_project:\n fields: payload.receiver_tenant_id\n receiver_user:\n fields: payload.receiver_user_id\n user_id:\n fields: payload.owner_id\n image_id:\n fields: payload.image_id\n destination_ip:\n fields: payload.destination_ip\n bytes_sent:\n type: int\n fields: payload.bytes_sent\n- event_type: orchestration.stack.*\n traits: &orchestration_crud\n project_id:\n fields: payload.tenant_id\n user_id:\n fields: ["ctxt.trustor_user_id", "ctxt.user_id"]\n resource_id:\n fields: payload.stack_identity\n name:\n fields: payload.name\n- event_type: sahara.cluster.*\n traits: &sahara_crud\n project_id:\n fields: payload.project_id\n user_id:\n fields: ctxt.user_id\n resource_id:\n fields: payload.cluster_id\n name:\n fields: payload.name\n- event_type: sahara.cluster.health\n traits: &sahara_health\n <<: *sahara_crud\n verification_id:\n fields: payload.verification_id\n health_check_status:\n fields: payload.health_check_status\n health_check_name:\n fields: payload.health_check_name\n health_check_description:\n fields: payload.health_check_description\n created_at:\n type: datetime\n fields: payload.created_at\n updated_at:\n type: datetime\n fields: payload.updated_at\n- event_type:\n [\n "identity.user.*",\n "identity.project.*",\n "identity.group.*",\n "identity.role.*",\n "identity.OS-TRUST:trust.*",\n "identity.region.*",\n "identity.service.*",\n "identity.endpoint.*",\n "identity.policy.*",\n ]\n traits: &identity_crud\n resource_id:\n fields: payload.resource_info\n initiator_id:\n fields: payload.initiator.id\n project_id:\n fields: payload.initiator.project_id\n domain_id:\n fields: payload.initiator.domain_id\n- event_type: identity.role_assignment.*\n traits: &identity_role_assignment\n role:\n fields: payload.role\n group:\n fields: payload.group\n domain:\n fields: payload.domain\n user:\n fields: payload.user\n project:\n fields: payload.project\n- event_type: identity.authenticate\n traits: &identity_authenticate\n typeURI:\n fields: payload.typeURI\n id:\n fields: payload.id\n action:\n fields: payload.action\n eventType:\n fields: payload.eventType\n eventTime:\n type: datetime\n fields: payload.eventTime\n outcome:\n fields: payload.outcome\n initiator_typeURI:\n fields: payload.initiator.typeURI\n initiator_id:\n fields: payload.initiator.id\n initiator_name:\n fields: payload.initiator.name\n initiator_host_agent:\n fields: payload.initiator.host.agent\n initiator_host_addr:\n fields: payload.initiator.host.address\n target_typeURI:\n fields: payload.target.typeURI\n target_id:\n fields: payload.target.id\n observer_typeURI:\n fields: payload.observer.typeURI\n observer_id:\n fields: payload.observer.id\n- event_type: objectstore.http.request\n traits: &objectstore_request\n typeURI:\n fields: payload.typeURI\n id:\n fields: payload.id\n action:\n fields: payload.action\n eventType:\n fields: payload.eventType\n eventTime:\n type: datetime\n fields: payload.eventTime\n outcome:\n fields: payload.outcome\n initiator_typeURI:\n fields: payload.initiator.typeURI\n initiator_id:\n fields: payload.initiator.id\n initiator_project_id:\n fields: payload.initiator.project_id\n target_typeURI:\n fields: payload.target.typeURI\n target_id:\n fields: payload.target.id\n target_action:\n fields: payload.target.action\n target_metadata_path:\n fields: payload.target.metadata.path\n target_metadata_version:\n fields: payload.target.metadata.version\n target_metadata_container:\n fields: payload.target.metadata.container\n target_metadata_object:\n fields: payload.target.metadata.object\n observer_id:\n fields: payload.observer.id\n- event_type:\n [\n "network.*",\n "subnet.*",\n "port.*",\n "router.*",\n "floatingip.*",\n "firewall.*",\n "firewall_policy.*",\n "firewall_rule.*",\n "vpnservice.*",\n "ipsecpolicy.*",\n "ikepolicy.*",\n "ipsec_site_connection.*",\n ]\n traits: &network_traits\n user_id:\n fields: ctxt.user_id\n project_id:\n fields: ctxt.tenant_id\n- event_type: network.*\n traits:\n <<: *network_traits\n name:\n fields: payload.network.name\n resource_id:\n fields: ["payload.network.id", "payload.id"]\n- event_type: subnet.*\n traits:\n <<: *network_traits\n name:\n fields: payload.subnet.name\n resource_id:\n fields: ["payload.subnet.id", "payload.id"]\n- event_type: port.*\n traits:\n <<: *network_traits\n name:\n fields: payload.port.name\n resource_id:\n fields: ["payload.port.id", "payload.id"]\n- event_type: router.*\n traits:\n <<: *network_traits\n name:\n fields: payload.router.name\n resource_id:\n fields: ["payload.router.id", "payload.id"]\n- event_type: floatingip.*\n traits:\n <<: *network_traits\n resource_id:\n fields: ["payload.floatingip.id", "payload.id"]\n- event_type: firewall.*\n traits:\n <<: *network_traits\n name:\n fields: payload.firewall.name\n resource_id:\n fields: ["payload.firewall.id", "payload.id"]\n- event_type: firewall_policy.*\n traits:\n <<: *network_traits\n name:\n fields: payload.firewall_policy.name\n resource_id:\n fields: ["payload.firewall_policy.id", "payload.id"]\n- event_type: firewall_rule.*\n traits:\n <<: *network_traits\n name:\n fields: payload.firewall_rule.name\n resource_id:\n fields: ["payload.firewall_rule.id", "payload.id"]\n- event_type: vpnservice.*\n traits:\n <<: *network_traits\n name:\n fields: payload.vpnservice.name\n resource_id:\n fields: ["payload.vpnservice.id", "payload.id"]\n- event_type: ipsecpolicy.*\n traits:\n <<: *network_traits\n name:\n fields: payload.ipsecpolicy.name\n resource_id:\n fields: ["payload.ipsecpolicy.id", "payload.id"]\n- event_type: ikepolicy.*\n traits:\n <<: *network_traits\n name:\n fields: payload.ikepolicy.name\n resource_id:\n fields: ["payload.ikepolicy.id", "payload.id"]\n- event_type: ipsec_site_connection.*\n traits:\n <<: *network_traits\n resource_id:\n fields: ["payload.ipsec_site_connection.id", "payload.id"]\n- event_type: "*http.*"\n traits: &http_audit\n project_id:\n fields: payload.initiator.project_id\n user_id:\n fields: payload.initiator.id\n typeURI:\n fields: payload.typeURI\n eventType:\n fields: payload.eventType\n action:\n fields: payload.action\n outcome:\n fields: payload.outcome\n id:\n fields: payload.id\n eventTime:\n type: datetime\n fields: payload.eventTime\n requestPath:\n fields: payload.requestPath\n observer_id:\n fields: payload.observer.id\n target_id:\n fields: payload.target.id\n target_typeURI:\n fields: payload.target.typeURI\n target_name:\n fields: payload.target.name\n initiator_typeURI:\n fields: payload.initiator.typeURI\n initiator_id:\n fields: payload.initiator.id\n initiator_name:\n fields: payload.initiator.name\n initiator_host_address:\n fields: payload.initiator.host.address\n- event_type: "*http.response"\n traits:\n <<: *http_audit\n reason_code:\n fields: payload.reason.reasonCode\n- event_type: ["dns.domain.create", "dns.domain.update", "dns.domain.delete"]\n traits: &dns_domain_traits\n status:\n fields: payload.status\n retry:\n fields: payload.retry\n description:\n fields: payload.description\n expire:\n fields: payload.expire\n email:\n fields: payload.email\n ttl:\n fields: payload.ttl\n action:\n fields: payload.action\n name:\n fields: payload.name\n resource_id:\n fields: payload.id\n created_at:\n type: datetime\n fields: payload.created_at\n updated_at:\n type: datetime\n fields: payload.updated_at\n version:\n fields: payload.version\n parent_domain_id:\n fields: parent_domain_id\n serial:\n fields: payload.serial\n- event_type: dns.domain.exists\n traits:\n <<: *dns_domain_traits\n audit_period_beginning:\n type: datetime\n fields: payload.audit_period_beginning\n audit_period_ending:\n type: datetime\n fields: payload.audit_period_ending\n- event_type: trove.*\n traits: &trove_base_traits\n instance_type:\n fields: payload.instance_type\n user_id:\n fields: payload.user_id\n resource_id:\n fields: payload.instance_id\n instance_type_id:\n fields: payload.instance_type_id\n launched_at:\n type: datetime\n fields: payload.launched_at\n instance_name:\n fields: payload.instance_name\n state:\n fields: payload.state\n nova_instance_id:\n fields: payload.nova_instance_id\n service_id:\n fields: payload.service_id\n created_at:\n type: datetime\n fields: payload.created_at\n region:\n fields: payload.region\n- event_type:\n [\n "trove.instance.create",\n "trove.instance.modify_volume",\n "trove.instance.modify_flavor",\n "trove.instance.delete",\n ]\n traits: &trove_common_traits\n name:\n fields: payload.name\n availability_zone:\n fields: payload.availability_zone\n instance_size:\n type: int\n fields: payload.instance_size\n volume_size:\n type: int\n fields: payload.volume_size\n nova_volume_id:\n fields: payload.nova_volume_id\n- event_type: trove.instance.create\n traits:\n <<: [*trove_base_traits, *trove_common_traits]\n- event_type: trove.instance.modify_volume\n traits:\n <<: [*trove_base_traits, *trove_common_traits]\n old_volume_size:\n type: int\n fields: payload.old_volume_size\n modify_at:\n type: datetime\n fields: payload.modify_at\n- event_type: trove.instance.modify_flavor\n traits:\n <<: [*trove_base_traits, *trove_common_traits]\n old_instance_size:\n type: int\n fields: payload.old_instance_size\n modify_at:\n type: datetime\n fields: payload.modify_at\n- event_type: trove.instance.delete\n traits:\n <<: [*trove_base_traits, *trove_common_traits]\n deleted_at:\n type: datetime\n fields: payload.deleted_at\n- event_type: trove.instance.exists\n traits:\n <<: *trove_base_traits\n display_name:\n fields: payload.display_name\n audit_period_beginning:\n type: datetime\n fields: payload.audit_period_beginning\n audit_period_ending:\n type: datetime\n fields: payload.audit_period_ending\n- event_type: profiler.*\n traits:\n project:\n fields: payload.project\n service:\n fields: payload.service\n name:\n fields: payload.name\n base_id:\n fields: payload.base_id\n trace_id:\n fields: payload.trace_id\n parent_id:\n fields: payload.parent_id\n timestamp:\n type: datetime\n fields: payload.timestamp\n host:\n fields: payload.info.host\n path:\n fields: payload.info.request.path\n query:\n fields: payload.info.request.query\n method:\n fields: payload.info.request.method\n scheme:\n fields: payload.info.request.scheme\n db.statement:\n fields: payload.info.db.statement\n db.params:\n fields: payload.info.db.params\n- event_type: "magnum.cluster.*"\n traits: &magnum_cluster_crud\n id:\n fields: payload.id\n typeURI:\n fields: payload.typeURI\n eventType:\n fields: payload.eventType\n eventTime:\n type: datetime\n fields: payload.eventTime\n action:\n fields: payload.action\n outcome:\n fields: payload.outcome\n initiator_id:\n fields: payload.initiator.id\n initiator_typeURI:\n fields: payload.initiator.typeURI\n initiator_name:\n fields: payload.initiator.name\n initiator_host_agent:\n fields: payload.initiator.host.agent\n initiator_host_address:\n fields: payload.initiator.host.address\n target_id:\n fields: payload.target.id\n target_typeURI:\n fields: payload.target.typeURI\n observer_id:\n fields: payload.observer.id\n observer_typeURI:\n fields: payload.observer.typeURI\n- event_type: "alarm.*"\n traits:\n id:\n fields: payload.alarm_id\n user_id:\n fields: payload.user_id\n project_id:\n fields: payload.project_id\n on_behalf_of:\n fields: payload.on_behalf_of\n severity:\n fields: payload.severity\n detail:\n fields: payload.detail\n type:\n fields: payload.type\n'})}),"\n",(0,a.jsx)(n.p,{children:"The event_pipeline can be used to filter events and pipeline them to different publishers.\nthe notifier publisher is the message queue broadcasster (RabbitMQ)."}),"\n",(0,a.jsx)(n.h3,{id:"13-event_pipelineyaml",children:"1.3 event_pipeline.yaml"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"---\nsources:\n - name: event_source # 'source name'\n events:\n - \"*\" # 'event filter'\n sinks:\n - event_sink # 'sink name'\nsinks:\n - name: event_sink # 'sink name'\n publishers: # 'list of publishers'\n - notifier://\n - http://localhost:8088/post_json\n"})}),"\n",(0,a.jsx)(n.p,{children:"The pipeline.yaml can be used to filter and pipeline all metrics and events since events send via the notifier also appears in the meters and send them to different publishers."}),"\n",(0,a.jsx)(n.p,{children:"In our case we want to push to the metering api."}),"\n",(0,a.jsx)(n.h3,{id:"14-pipelineyaml",children:"1.4 pipeline.yaml"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'---\nsources:\n - name: meter_source\n meters:\n - "*"\n sinks:\n - meter_sink\nsinks:\n - name: meter_sink\n publishers:\n - gnocchi://?archive_policy=ceilometer-low&filter_project=service\n - http://localhost:8088/post_json\n'})})]})}function _(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(p,{...e})}):p(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>l});var a=t(96540);const i={},d=a.createContext(i);function s(e){const n=a.useContext(d);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),a.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/420452be.5b959566.js b/assets/js/420452be.5b959566.js new file mode 100644 index 0000000000..da3d358292 --- /dev/null +++ b/assets/js/420452be.5b959566.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1911],{24449:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>a,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var i=n(74848),r=n(28453);const o={},a="Matrix",s={id:"tools/matrix",title:"Matrix",description:"We have created an open community space on the Matrix federation. Feel free to join the several channels and start chatting with our community. A good starting point is entering the General & Announcements and the Tech channel.",source:"@site/community/tools/matrix.md",sourceDirName:"tools",slug:"/tools/matrix",permalink:"/community/tools/matrix",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Jitsi",permalink:"/community/tools/jitsi"},next:{title:"Mailing Lists",permalink:"/community/tools/mailinglists"}},c={},l=[{value:"Client and Registration",id:"client-and-registration",level:2}];function h(t){const e={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",...(0,r.R)(),...t.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h1,{id:"matrix",children:"Matrix"}),"\n",(0,i.jsxs)(e.p,{children:["We have created an ",(0,i.jsx)(e.a,{href:"https://matrix.to/#/!TiDqlLmEUaXqTemaLc:matrix.org?via=matrix.org",children:"open community space on the Matrix federation"}),". Feel free to join the several channels and start chatting with our community. A good starting point is entering the ",(0,i.jsx)(e.a,{href:"https://matrix.to/#/#scs-general:matrix.org",children:"General & Announcements"})," and the ",(0,i.jsx)(e.a,{href:"https://matrix.to/#/#scs-tech:matrix.org",children:"Tech"})," channel."]}),"\n",(0,i.jsx)(e.h2,{id:"client-and-registration",children:"Client and Registration"}),"\n",(0,i.jsxs)(e.p,{children:["To connect to the Matrix federation, you will need an account on a federated homeserver and a client. The easiest way to join us is register on the popular ",(0,i.jsx)(e.code,{children:"matrix.org"})," homeserver via the Element web client: ",(0,i.jsx)(e.a,{href:"https://app.element.io/#/register%5D",children:"https://app.element.io/#/register"}),". A list of curated Matrix clients is collected on the official Matrix website: ",(0,i.jsx)(e.a,{href:"https://matrix.org/clients/",children:"https://matrix.org/clients/"})]})]})}function m(t={}){const{wrapper:e}={...(0,r.R)(),...t.components};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(h,{...t})}):h(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>a,x:()=>s});var i=n(96540);const r={},o=i.createContext(r);function a(t){const e=i.useContext(o);return i.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:a(t.components),i.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/42088e64.c457a555.js b/assets/js/42088e64.c457a555.js new file mode 100644 index 0000000000..d43fc70cbf --- /dev/null +++ b/assets/js/42088e64.c457a555.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[282],{40831:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var o=t(74848),s=t(28453);const a={},r="Multi-AZ and multi-cloud environments",i={id:"container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments",title:"Multi-AZ and multi-cloud environments",description:"The provided cluster-template.yaml assumes that all control nodes on one hand and all worker nodes on the other are",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc/usage",slug:"/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Cluster Management on the capi management node",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node"},next:{title:"Testing",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/testing"}},c={},l=[];function d(e){const n={code:"code",h1:"h1",p:"p",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"multi-az-and-multi-cloud-environments",children:"Multi-AZ and multi-cloud environments"}),"\n",(0,o.jsxs)(n.p,{children:["The provided ",(0,o.jsx)(n.code,{children:"cluster-template.yaml"})," assumes that all control nodes on one hand and all worker nodes on the other are\nequal. They are in the same cloud within the same availability zone, using the same flavor. cluster API allows k8s\nclusters to have varying flavors, span availability zones and even clouds. For this, you can create an advanced\ncluster-template with more different machine descriptions and potentially several secrets. Depending on your changes,\nthe logic in ",(0,o.jsx)(n.code,{children:"create_cluster.sh"})," might also need enhancements to handle this. Extending this is not hard and we're happy\nto hear from your use cases and take patches."]}),"\n",(0,o.jsx)(n.p,{children:"However, we are currently investigating to use helm templating for anything beyond the simple use cases instead, see\nnext chapter."})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var o=t(96540);const s={},a=o.createContext(s);function r(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/421b5e65.1d4e25e2.js b/assets/js/421b5e65.1d4e25e2.js new file mode 100644 index 0000000000..b27f808f54 --- /dev/null +++ b/assets/js/421b5e65.1d4e25e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9305],{21723:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var o=t(74848),r=t(28453);const a={},i="Ingress with externalTrafficPolicy: local",s={id:"container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal",title:"Ingress with externalTrafficPolicy: local",description:"Setting up the nginx ingress controller from the upstream deployment templates",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc",slug:"/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Maintenance and Troubleshooting Guide for SCS k8s-cluster-api-provider",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting"},next:{title:"SCS k8s-cluster-api-provider upgrade guide",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide"}},c={},l=[];function d(e){const n={a:"a",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(n.h1,{id:"ingress-with-externaltrafficpolicy-local",children:["Ingress with ",(0,o.jsx)(n.code,{children:"externalTrafficPolicy: local"})]}),"\n",(0,o.jsxs)(n.p,{children:["Setting up the nginx ingress controller from the upstream deployment templates\nusing the ",(0,o.jsx)(n.code,{children:"externalTrafficPolicy: local"})," setting and -- without any special\ntreatment -- results in a service that is only partially working: Only requests\nthat the LoadBalancer happens to route at the node where the nginx container is\nrunning get a response."]}),"\n",(0,o.jsxs)(n.p,{children:["nginx could just use the ",(0,o.jsx)(n.code,{children:"cluster"})," setting instead and kube-proxy would forward\nthe network packets. There are two reasons for nginx not to do that"]}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Having a load-balancer balance the traffic to a node that is not active just\nto have kube-proxy forward it to the active node does not make much sense.\nIt creates an unnecessary hop and makes the LoadBalancer pretty useless."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Packets forwarded by kube-proxy do not carry the original client IP, so any\nsource IP dependant handling in nginx (filtering, QoS, ...) will not be\npossible."}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h1,{id:"getting-it-to-work-for-managed-ingress",children:"Getting it to work for managed ingress"}),"\n",(0,o.jsx)(n.p,{children:"There does not seem to be a standard mechanism where k8s tells the LoadBalancer (LB)\nwhich backend members are active, but the load-balancer can find this out by using\na health-monitor that probes for the availability of the service and then takes\nthe inactive nodes out of the rotation. Should the container be rescheduled on\nsome other node, the health-monitor will adapt within a few seconds."}),"\n",(0,o.jsx)(n.p,{children:"Since SCS R2, the deployed nginx-ingress deployment is patched to carry a service\nannotation (a behavior specifically needed by OpenStack) that enables the health-monitor for the LB in\nfront of the ingress. This results in traffic to flow."}),"\n",(0,o.jsxs)(n.p,{children:["This covers the nginx ingress controller that is deployed by setting\n",(0,o.jsx)(n.code,{children:"DEPLOY_NGINX_INGRESS: true"})," with the ",(0,o.jsx)(n.code,{children:"create_cluster.sh"})," or ",(0,o.jsx)(n.code,{children:"apply_nginx_ingress.sh"}),'.\nThat the ingress we call the "managed ingress".']}),"\n",(0,o.jsx)(n.p,{children:"For the ingress service to see the client IPs, more is needed. The Octavia LB\nas well as the nginx service both support the proxy protocol, which can be used to\ncommunicate the real client IP. We had plumbing included which we disabled by\ndefault prior to releasing R2, because it broke the access to ingress from\nsoftware that runs inside the cluster."}),"\n",(0,o.jsxs)(n.p,{children:["A workaround for this has been implemented, so the default is\n",(0,o.jsx)(n.code,{children:"NGINX_USE_PROXY: true"})," as of R4. So the managed nginx ingress service\ndoes work reliably and gets the client IPs."]}),"\n",(0,o.jsx)(n.h1,{id:"getting-it-to-work-in-general",children:"Getting it to work in general"}),"\n",(0,o.jsxs)(n.p,{children:["Users that deploy their own nginx or other services with ",(0,o.jsx)(n.code,{children:"externalTrafficPolicy: local"}),"\nwon't be helped by the annotations done by the SCS cluster management. They will\nhave to do similar custom patching or revert to a ",(0,o.jsx)(n.code,{children:"cluster"})," policy and forego the\nvisibility on real client IPs."]}),"\n",(0,o.jsx)(n.p,{children:"A generic solution to this would be a different kind of LB that does work at the\nnetworking layer 3 (routing), so the (TCP) connections are not terminated at the\nLB and then data being forwarded on a new connection to the backend member, but\nthe routing would create a direct connection. Google (with Direct Server Return, DSR)\nand Azure support such LB modes."}),"\n",(0,o.jsx)(n.p,{children:"As it turns out, on OpenStack clouds that use OVN as networking (SDN) layer, the OVN\nloadbalancer does almost deliver what's needed."}),"\n",(0,o.jsx)(n.h1,{id:"ovn-provider-loadbalancer",children:"OVN provider LoadBalancer"}),"\n",(0,o.jsx)(n.p,{children:"The OVN provider for the load-balancer does create direct flows to the chosen backend\nmember, so no proxy protocol (or similar hacks) are needed to make the backend service\nsee the client IPs. This has been validated (and can even be monitored by openstack-health-monitor)\non SCS clouds that use OVN."}),"\n",(0,o.jsxs)(n.p,{children:["A health-monitor is still needed to ensure that only active members receive requests.\nHealth monitors for the ovn provider are only supported on OpenStack Wallaby and later.\nSee also occm ",(0,o.jsx)(n.a,{href:"https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/openstack-cloud-controller-manager/using-openstack-cloud-controller-manager.md",children:"docs"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["OVN LoadBalancer can be enabled by setting ",(0,o.jsx)(n.code,{children:'use_ovn_lb_provider = "true"'})," or ",(0,o.jsx)(n.code,{children:'use_ovn_lb_provider = "auto"'}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Note that the ",(0,o.jsx)(n.code,{children:"use_ovn_lb_provider"})," does not affect the LB in front of the kube API.\nThat one is created by capo and requires other settings. Also note that it would\nnot yet support the ",(0,o.jsx)(n.a,{href:"https://docs.openstack.org/octavia/latest/user/feature-classification/index.html#operation_allowed_cidr",children:"CIDR filtering"}),"\nwith ",(0,o.jsx)(n.code,{children:"restrict_kubeapi"})," setting."]}),"\n",(0,o.jsx)(n.h1,{id:"disabled-health-monitor-by-default",children:"Disabled health-monitor by default"}),"\n",(0,o.jsxs)(n.p,{children:["We could enable a health-monitor by default for load-balancers created from OCCM\nin the k8s clusters. This would make services with ",(0,o.jsx)(n.code,{children:"externalTrafficPolicy: local"}),"\nwork, as the traffic would be routed exclusively to active members. But the\nother goal would not be achieved: Getting the real client IPs.\nWe decided against turning on the health-monitor by default, as this might result\nin the wrong impression that ",(0,o.jsx)(n.code,{children:"local"})," fully works. Rather break and then have users take\na decision to go for ",(0,o.jsx)(n.code,{children:"cluster"}),", to enable health-monitoring to get it half-working\nor to do health-monitoring plus some extra plumbing for proxy protocol (or similar)\nto get all aspects working."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>s});var o=t(96540);const r={},a=o.createContext(r);function i(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/422fff4b.628ec50d.js b/assets/js/422fff4b.628ec50d.js new file mode 100644 index 0000000000..8ed0ada613 --- /dev/null +++ b/assets/js/422fff4b.628ec50d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6227],{60993:(s,e,t)=>{t.r(e),t.d(e,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>o});var n=t(74848),r=t(28453);const c={},d="scs-0210: SCS K8S Version Policy",i={id:"kaas/scs-0210",title:"scs-0210: SCS K8S Version Policy",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/kaas/scs-0210.md",sourceDirName:"kaas",slug:"/kaas/scs-0210",permalink:"/standards/kaas/scs-0210",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Using Sonobuoy for KaaS conformance tests",permalink:"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests"},next:{title:"SCS K8S Version Policy for new Kubernetes versions",permalink:"/standards/scs-0210-v1-k8s-new-version-policy"}},a={},o=[];function l(s){const e={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"scs-0210-scs-k8s-version-policy",children:"scs-0210: SCS K8S Version Policy"}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:"Version"}),(0,n.jsx)(e.th,{children:"Type"}),(0,n.jsx)(e.th,{children:"State"}),(0,n.jsx)(e.th,{children:"stabilized"}),(0,n.jsx)(e.th,{children:"deprecated"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0210-v1-k8s-new-version-policy",children:"scs-0210-v1"})}),(0,n.jsx)(e.td,{children:"Standard"}),(0,n.jsx)(e.td,{children:"Deprecated"}),(0,n.jsx)(e.td,{children:"2023-02-07"}),(0,n.jsx)(e.td,{children:"2024-02-08"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0210-v2-k8s-version-policy",children:"scs-0210-v2"})}),(0,n.jsx)(e.td,{children:"Standard"}),(0,n.jsx)(e.td,{children:"Stable"}),(0,n.jsx)(e.td,{children:"2024-02-08"}),(0,n.jsx)(e.td,{children:"-"})]})]})]})]})}function h(s={}){const{wrapper:e}={...(0,r.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(l,{...s})}):l(s)}},28453:(s,e,t)=>{t.d(e,{R:()=>d,x:()=>i});var n=t(96540);const r={},c=n.createContext(r);function d(s){const e=n.useContext(c);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function i(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(r):s.components||r:d(s.components),n.createElement(c.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/42b29c77.5eb8c03c.js b/assets/js/42b29c77.5eb8c03c.js new file mode 100644 index 0000000000..9f03e1ec15 --- /dev/null +++ b/assets/js/42b29c77.5eb8c03c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8767],{87855:(t,s,e)=>{e.r(s),e.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var n=e(74848),i=e(28453);const r={},c="scs-0112: SONiC Support in SCS",o={id:"global/scs-0112",title:"scs-0112: SONiC Support in SCS",description:"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.",source:"@site/standards/global/scs-0112.md",sourceDirName:"global",slug:"/global/scs-0112",permalink:"/standards/global/scs-0112",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Regulations for achieving SCS-compatible certification",permalink:"/standards/scs-0004-v1-achieving-certification"},next:{title:"SONiC Support in SCS",permalink:"/standards/scs-0112-v1-sonic"}},a={},d=[];function l(t){const s={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"scs-0112-sonic-support-in-scs",children:"scs-0112: SONiC Support in SCS"}),"\n",(0,n.jsx)(s.p,{children:"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration."}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Version"}),(0,n.jsx)(s.th,{children:"Type"}),(0,n.jsx)(s.th,{children:"State"}),(0,n.jsx)(s.th,{children:"stabilized"}),(0,n.jsx)(s.th,{children:"deprecated"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0112-v1-sonic",children:"scs-0112-v1"})}),(0,n.jsx)(s.td,{children:"Decision Record"}),(0,n.jsx)(s.td,{children:"Draft"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]})})]})]})}function h(t={}){const{wrapper:s}={...(0,i.R)(),...t.components};return s?(0,n.jsx)(s,{...t,children:(0,n.jsx)(l,{...t})}):l(t)}},28453:(t,s,e)=>{e.d(s,{R:()=>c,x:()=>o});var n=e(96540);const i={},r=n.createContext(i);function c(t){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof t?t(s):{...s,...t}}),[s,t])}function o(t){let s;return s=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:c(t.components),n.createElement(r.Provider,{value:s},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/431e6cfe.c63ebe0e.js b/assets/js/431e6cfe.c63ebe0e.js new file mode 100644 index 0000000000..6a4e20c118 --- /dev/null +++ b/assets/js/431e6cfe.c63ebe0e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2932],{89027:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>c,toc:()=>a});var t=s(74848),i=s(28453);const r={},o="Continuous integration",c={id:"container/components/k8s-cluster-api-provider/doc/continuous-integration",title:"Continuous integration",description:"Project k8s-cluster-api-provider uses SCS Zuul CI platform to",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/continuous-integration.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc",slug:"/container/components/k8s-cluster-api-provider/doc/continuous-integration",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/continuous-integration.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"SCS k8s-cluster-api-provider upgrade guide",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide"},next:{title:"Roadmap",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/roadmap"}},l={},a=[{value:"Configuration",id:"configuration",level:2},{value:"Pipelines",id:"pipelines",level:2},{value:"Jobs",id:"jobs",level:2},{value:"Secrets",id:"secrets",level:3},{value:"Job customization",id:"job-customization",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"continuous-integration",children:"Continuous integration"}),"\n",(0,t.jsxs)(n.p,{children:["Project k8s-cluster-api-provider uses ",(0,t.jsx)(n.a,{href:"https://zuul.scs.community",children:"SCS Zuul"})," CI platform to\ndrive its continuous integration tests. The project is registered under the ",(0,t.jsx)(n.a,{href:"https://zuul.scs.community/t/SCS/projects",children:"SCS tenant"}),"\nand therefore is able to use a set of pre-defined pipelines, jobs, and ansible roles that\nSCS Zuul instance defines and imports. If you want to explore currently available SCS pipelines,\nvisit the ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-config",children:"SCS zuul-config"})," project.\nIf you want to see the full list of jobs that are available, visit the ",(0,t.jsx)(n.a,{href:"https://zuul.scs.community/t/SCS/jobs",children:"SCS Zuul UI"}),".\nAnd if you are looking for some handy ansible role that SCS Zuul imports, visit they ",(0,t.jsx)(n.a,{href:"https://opendev.org/zuul/zuul-jobs/src/branch/master/roles",children:"source"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Refer to SCS ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/pull/54",children:"Zuul users guide"})," and/or\n",(0,t.jsx)(n.a,{href:"https://zuul-ci.org/docs/",children:"Zuul docs"})," for further details on how to define and use Zuul\nCI/CD pipelines and jobs."]}),"\n",(0,t.jsxs)(n.p,{children:["Note (for geeks): If you are interested in Zuul CI platform and want to deploy your own development instance of it,\nthen read the official ",(0,t.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/tutorials/quick-start.html",children:"quick-start"})," manual\nor visit ",(0,t.jsx)(n.a,{href:"https://github.com/matofederorg/zuul-config",children:"this"})," tutorial which aims a connection\nof Zuul CI platform with a GitHub organization."]}),"\n",(0,t.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,t.jsxs)(n.p,{children:["SCS Zuul automatically recognizes ",(0,t.jsx)(n.code,{children:".zuul.yaml"})," configuration file that is located in the\nk8s-cluster-api-provider's root. This file informs Zuul about the project's ",(0,t.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/project.html#attr-project.default-branch",children:"default-branch"})," and\npreferred ",(0,t.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/project.html#attr-project.merge-mode",children:"merge-mode"}),".\nIt also references ",(0,t.jsx)(n.a,{href:"https://github.com/matofederorg/zuul-config",children:"SCS Zuul pipelines"})," and\ntheir jobs used by the k8s-cluster-api-provider project. Then, jobs link Ansible playbooks that contain\ntasks for actual CI testing."]}),"\n",(0,t.jsx)(n.p,{children:"See relevant CI configuration files:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-text",children:"\u251c\u2500\u2500 .zuul.yaml\n\u251c\u2500\u2500 playbooks\n\u2502 \u251c\u2500\u2500 cleanup.yaml\n\u2502 \u251c\u2500\u2500 dependencies.yaml\n\u2502 \u251c\u2500\u2500 e2e.yaml\n\u2502 \u251c\u2500\u2500 templates\n\u2502 \u2502 \u2514\u2500\u2500 environment.tfvars.j2\n"})}),"\n",(0,t.jsx)(n.h2,{id:"pipelines",children:"Pipelines"}),"\n",(0,t.jsxs)(n.p,{children:["This section describes an ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-config/blob/main/zuul.d/gh_pipelines.yaml",children:"SCS Zuul pipelines"})," that are used by the k8s-cluster-api-provider project."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"e2e-test"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["It is triggered by the ",(0,t.jsx)(n.code,{children:"e2e-test"})," label in the opened PR"]}),"\n",(0,t.jsxs)(n.li,{children:["It executes ",(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-conformance"})," job"]}),"\n",(0,t.jsxs)(n.li,{children:["It applies the PR label ",(0,t.jsx)(n.code,{children:"successful-e2e-test"})," and leaves an informative PR comment when the ",(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-conformance"})," job succeeded"]}),"\n",(0,t.jsxs)(n.li,{children:["It applies the PR label ",(0,t.jsx)(n.code,{children:"failed-e2e-test"})," and leaves an informative PR comment when the ",(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-conformance"})," job failed"]}),"\n",(0,t.jsxs)(n.li,{children:["It applies the PR label ",(0,t.jsx)(n.code,{children:"cancelled-e2e-test"})," and leaves an informative PR comment when the ",(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-conformance"})," job is canceled"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"unlabel-on-update-e2e-test"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["It is triggered by the PR update only when PR contains the ",(0,t.jsx)(n.code,{children:"successful-e2e-test"})," label"]}),"\n",(0,t.jsx)(n.li,{children:"It ensures that any PR update invalidates a previous successful e2e test"}),"\n",(0,t.jsxs)(n.li,{children:["It removes ",(0,t.jsx)(n.code,{children:"successful-e2e-test"})," label from the PR"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"e2e-quick-test"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["It is triggered by the ",(0,t.jsx)(n.code,{children:"e2e-quick-test"})," label in the opened PR"]}),"\n",(0,t.jsxs)(n.li,{children:["It executes ",(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-quick"})," job"]}),"\n",(0,t.jsxs)(n.li,{children:["It applies the PR label ",(0,t.jsx)(n.code,{children:"successful-e2e-quick-test"})," and leaves an informative PR comment when the ",(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-quick"})," job succeeded"]}),"\n",(0,t.jsxs)(n.li,{children:["It applies the PR label ",(0,t.jsx)(n.code,{children:"failed-e2e-quick-test"})," and leaves an informative PR comment when the ",(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-quick"})," job failed"]}),"\n",(0,t.jsxs)(n.li,{children:["It applies the PR label ",(0,t.jsx)(n.code,{children:"cancelled-e2e-quick-test"})," and leaves an informative PR comment when the ",(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-quick"})," job is canceled"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"unlabel-on-update-e2e-quick-test"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["It is triggered by the PR update only when PR contains the ",(0,t.jsx)(n.code,{children:"successful-e2e-quick-test"})," label"]}),"\n",(0,t.jsx)(n.li,{children:"It ensures that any PR update invalidates a previous successful e2e test"}),"\n",(0,t.jsxs)(n.li,{children:["It removes ",(0,t.jsx)(n.code,{children:"successful-e2e-quick-test"})," label from the PR"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"periodic-daily"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"This pipeline runs jobs daily at 3AM"}),"\n",(0,t.jsxs)(n.li,{children:["It executes ",(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-conformance"})," job"]}),"\n",(0,t.jsxs)(n.li,{children:["The job overrides the ",(0,t.jsx)(n.code,{children:"git_reference"})," variable to ensure that the e2e conformance testing is executed on a specific tag"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"jobs",children:"Jobs"}),"\n",(0,t.jsx)(n.p,{children:"This section describes Zuul jobs defined within the k8s-cluster-api-provider project and linked in the above pipelines."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-conformance"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"It runs a sonobuoy conformance test against Kubernetes cluster spawned by k8s-cluster-api-provider scripts"}),"\n",(0,t.jsxs)(n.li,{children:["This job is a child job of ",(0,t.jsx)(n.code,{children:"openstack-access-base"})," that ensures OpenStack credentials\navailability in Zuul worker node. Parent job also defines a Zuul semaphore ",(0,t.jsx)(n.code,{children:"semaphore-openstack-access"}),",\nthat ensures that a maximum of three ",(0,t.jsx)(n.code,{children:"openstack-access-base"})," jobs (or their children) can run at a time"]}),"\n",(0,t.jsxs)(n.li,{children:["See a high level ",(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-conformance"})," job steps:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Pre-run playbook ",(0,t.jsx)(n.code,{children:"dependencies.yaml"})," installs project prerequisites, e.g. opentofu, yq, etc."]}),"\n",(0,t.jsxs)(n.li,{children:["Main playbook ",(0,t.jsx)(n.code,{children:"e2e.yaml"})," spawns a k8s cluster, runs sonobuoy conformance test, and cleans created infrastructure, all by k8s-cluster-api-provider scripts"]}),"\n",(0,t.jsxs)(n.li,{children:["Cleanup-run playbook ",(0,t.jsx)(n.code,{children:"cleanup.yaml"})," runs ",(0,t.jsx)(n.code,{children:"ospurge"}),", cleanup created application credentials and keypair to ensure that multiple e2e runs do not interfere"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-quick"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"It runs a sonobuoy quick test against Kubernetes cluster spawned by k8s-cluster-api-provider scripts"}),"\n",(0,t.jsxs)(n.li,{children:["This job is a child job of ",(0,t.jsx)(n.code,{children:"openstack-access-base"})," that ensures OpenStack credentials\navailability in Zuul worker node. Parent job also defines a Zuul semaphore ",(0,t.jsx)(n.code,{children:"semaphore-openstack-access"}),",\nthat ensures that a maximum of three ",(0,t.jsx)(n.code,{children:"openstack-access-base"})," jobs (or their children) can run at a time"]}),"\n",(0,t.jsxs)(n.li,{children:["See a high level ",(0,t.jsx)(n.code,{children:"k8s-cluster-api-provider-e2e-quick"})," job steps:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Pre-run playbook ",(0,t.jsx)(n.code,{children:"dependencies.yaml"})," installs project prerequisites, e.g. opentofu, yq, etc."]}),"\n",(0,t.jsxs)(n.li,{children:["Main playbook ",(0,t.jsx)(n.code,{children:"e2e.yaml"})," spawns a k8s cluster, runs sonobuoy quick test, and cleans created infrastructure, all by k8s-cluster-api-provider scripts"]}),"\n",(0,t.jsxs)(n.li,{children:["Cleanup-run playbook ",(0,t.jsx)(n.code,{children:"cleanup.yaml"})," runs ",(0,t.jsx)(n.code,{children:"ospurge"}),", cleanup created application credentials and keypair to ensure that multiple e2e runs do not interfere"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"secrets",children:"Secrets"}),"\n",(0,t.jsxs)(n.p,{children:["The parent job ",(0,t.jsx)(n.code,{children:"openstack-access-base"}),", from which e2e jobs inherit, defines secret variable ",(0,t.jsx)(n.code,{children:"openstack-application-credential"}),".\nThis secret is stored directly in the ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-config/blob/main/zuul.d/secrets.yaml",children:"SCS/zuul-config repository"})," in an encrypted form.\nIt contains OpenStack application credentials to access the OpenStack project dedicated for CI testing."]}),"\n",(0,t.jsxs)(n.p,{children:["This secret is encrypted by the SCS/zuul-config repository RSA key that has been generated by SCS Zuul instance.\nSo only SCS Zuul instance is able to decrypt it (read the ",(0,t.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/project-config.html#encryption",children:"docs"}),")."]}),"\n",(0,t.jsx)(n.p,{children:"If you want to re-generate the mentioned secret or add another one using SCS/zuul-config repository RSA key, follow the below instructions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Install zuul-client"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install zuul-client\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'Encrypt "super-secret" string by the SCS/zuul-config repository public key from SCS Zuul'}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'echo -n "super-secret" | \\\n zuul-client --zuul-url https://zuul.scs.community encrypt \\\n --tenant SCS \\\n --project github.com/SovereignCloudStack/zuul-config\n'})}),"\n",(0,t.jsx)(n.h3,{id:"job-customization",children:"Job customization"}),"\n",(0,t.jsxs)(n.p,{children:["In some cases you may want to change your ",(0,t.jsx)(n.code,{children:"environment.tfvars"})," file before running the e2e test without changing\nthe ",(0,t.jsx)(n.code,{children:"environment.tfvars"})," file in the repository. For example, you may want to change the ",(0,t.jsx)(n.code,{children:"image"})," variable to test a different\nsystem image without altering the default image used by the project."]}),"\n",(0,t.jsx)(n.p,{children:"To do so, you can in the body of the PR add the following text:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-text",children:' ```ZUUL_CONFIG\n image = "Ubuntu 20.04"\n'})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"\n### FAQ\n\n#### How do developers/reviewers should proceed if they want to CI test this project?\n\nA developer initiates a PR as usual. If a reviewer deems that the PR requires e2e testing,\nthey can apply a specific label to the PR.\nCurrently, the following labels could be applied:\n\n- `e2e-test` (for comprehensive e2e testing, including k8s cluster creation, execution of sonobuoy conformance tests, and cluster deletion)\n- `e2e-quick-test` (for expedited e2e testing, involving k8s cluster creation, quick sonobuoy tests, and cluster deletion)\n\nAfter the e2e test has completed, the reviewer can examine the test results and respond\naccordingly, such as approving the PR if everything appears to be in order or requesting changes.\nSonobuoy test results, along with a link to the e2e logs, are conveyed back to the PR via a comment.\nAdditionally, the PR is labeled appropriately based on the overall e2e test result, using labels like\n`successful-e2e-test`, `successful-e2e-quick-test`, `failed-e2e-test`, or `failed-e2e-quick-test`.\n\n#### Why do we use PR `label` as an e2e pipeline trigger instead of e.g. PR `comment`?\n\nWe consider PR labels to be a more secure pipeline trigger compared to, for example, PR comments.\nPR labels can only be applied by developers with [triage](https://docs.github.com/en/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization#permissions-for-each-role) repository access or higher.\nIn contrast, PR comments can be added by anyone with a GitHub account.\n\nMembers of the SCS GitHub organization are automatically granted 'write' access to SCS repositories.\nConsequently, the PR label mechanism ensures that only SCS organization members can trigger e2e pipelines.\n\n#### How do we ensure that any PR update invalidates a previous successful e2e test?\n\nIn fact, two mechanisms ensure the invalidation of a previously successful test when a PR is updated.\n\nFirstly, the pipelines `unlabel-on-update-<e2e-test-name>` remove the `successful-<e2e-test-name>` label\nfrom the PR when it's updated after a successful e2e test has finished.\nIf an e2e test is in progress and the PR is updated, the currently running e2e test is\ncanceled, the `successful-<e2e-test-name>` label is removed (if it exists), and the\n`cancelled-<e2e-test-name>` label is applied along with an informative PR comment to\ninform the reviewer about the situation.\n"})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var t=s(96540);const i={},r=t.createContext(i);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/437bedbc.8d085187.js b/assets/js/437bedbc.8d085187.js new file mode 100644 index 0000000000..64ee747812 --- /dev/null +++ b/assets/js/437bedbc.8d085187.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9745],{35959:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var t=n(74848),i=n(28453);const r={},o="Release Notes for SCS Release 4",a={id:"releases/Release4",title:"Release Notes for SCS Release 4",description:"(Release Date: 2023-03-22)",source:"@site/docs/06-releases/Release4.md",sourceDirName:"06-releases",slug:"/releases/Release4",permalink:"/docs/releases/Release4",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release4.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Release Notes for SCS Release 3",permalink:"/docs/releases/Release3"},next:{title:"Release Notes for SCS Release 5",permalink:"/docs/releases/Release5"}},l={},d=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"New Features (Highlights)",id:"new-features-highlights",level:2},{value:"Operator focused improvements",id:"operator-focused-improvements",level:3},{value:"SCS Developer focused improvements (testbed and k8s cluster management)",id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Deprecations via OSISM",id:"deprecations-via-osism",level:3},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Resolved Issues",id:"resolved-issues",level:2},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R4",id:"list-of-known-issues--restrictions-in-r4",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Thanks",id:"thanks",level:2}];function c(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h1,{id:"release-notes-for-scs-release-4",children:"Release Notes for SCS Release 4"}),"\n",(0,t.jsx)(s.p,{children:"(Release Date: 2023-03-22)"}),"\n",(0,t.jsx)(s.h2,{id:"scope",children:"Scope"}),"\n",(0,t.jsx)(s.p,{children:"Release 4 has been developed alongside a set of associated outcomes. These outcomes are comprised of:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"SCS is standardized"}),"\n",(0,t.jsx)(s.li,{children:"SCS is federated"}),"\n",(0,t.jsx)(s.li,{children:"SCS is continuously built and tested"}),"\n",(0,t.jsx)(s.li,{children:"SCS is understandable"}),"\n",(0,t.jsx)(s.li,{children:"SCS enables Operators with an excellent toolbox"}),"\n"]}),"\n",(0,t.jsx)(s.p,{children:"The SCS project is completely developed in the open, based on the principles of the four opens. Due to this a lot of our work can be tracked and used continuously without waiting for the half-year releases. Especially, but not limited to, this includes our efforts in regards to documentation and our standards."}),"\n",(0,t.jsxs)(s.p,{children:["One of the major highlights that happened in the R4 development cycle is our work on assuring ",(0,t.jsx)(s.em,{children:"SCS is understandable"}),".\nBe sure to look at ",(0,t.jsx)(s.a,{href:"https://docs.scs.community",children:"our new documentation entry point"}),".\nWe have created a ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/contribute/adding-docs-guide.md",children:"systematic approach"})," to structure documentation which already has been implemented for the ",(0,t.jsx)(s.a,{href:"https://docs.scs.community/docs/category/openstack-image-manager/",children:"OpenStack Image Manager"}),",\nthe ",(0,t.jsx)(s.a,{href:"https://docs.scs.community/docs/category/osism-testbed/",children:"OSISM testbed"})," and the ",(0,t.jsx)(s.a,{href:"https://docs.scs.community/docs/category/k8s-cluster-api-provider/",children:"K8s Cluster API Provider"}),". More will follow in a continuous manner."]}),"\n",(0,t.jsxs)(s.p,{children:["Our community has created a growing amount of ",(0,t.jsx)(s.a,{href:"https://scs.community/blog/",children:"blog articles"})," which also help to understand the SCS project, its community and the technology that is worked on."]}),"\n",(0,t.jsx)(s.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://releases.openstack.org/zed/highlights.html",children:"OpenStack Zed release"})}),"\n",(0,t.jsx)(s.li,{children:"Ceph Quincy is available, the default release of Ceph is still Pacific."}),"\n",(0,t.jsxs)(s.li,{children:["The base infrastructure is provided by\n",(0,t.jsx)(s.a,{href:"https://release.osism.tech/notes/5.0.0.html",children:"OSISM 5.0.0"}),"\nwhich in turn builds on top of kolla and kolla-ansible."]}),"\n",(0,t.jsxs)(s.li,{children:["With ",(0,t.jsx)(s.a,{href:"https://github.com/osism/cloud-in-a-box",children:"Cloud-in-a-Box"})," there is an easy way to get SCS up and running on a single hardware node as a test environment. There are two blog posts (",(0,t.jsx)(s.a,{href:"https://scs.community/2023/03/15/ciab/",children:"part 1"})," and ",(0,t.jsx)(s.a,{href:"https://scs.community/2023/03/15/ciab-2/",children:"part2"}),") covering it."]}),"\n",(0,t.jsx)(s.li,{children:"For new deployments of the IaaS reference implementation Ubuntu 22.04 is recommended while existing installations can be upgraded to R4 while staying on Ubuntu 20.04. With Release 5, upgrading to Ubuntu 22.04 will be required."}),"\n",(0,t.jsxs)(s.li,{children:["With ",(0,t.jsx)(s.a,{href:"https://github.com/osism/node-image",children:"osism/node-image"})," an iso image for much easier bootstrapping of new OSISM environments is available now"]}),"\n",(0,t.jsxs)(s.li,{children:["The software for our ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"Kubernetes Cluster-API reference implementation"})," has been updated and highlights are covered in own ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R4.md",children:"release notes"}),"."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"new-features-highlights",children:"New Features (Highlights)"}),"\n",(0,t.jsx)(s.h3,{id:"operator-focused-improvements",children:"Operator focused improvements"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/osism/openstack-image-manager",children:"Openstack Image Manager"})," has seen many improvements and is the reference command to assure the images available comply with the ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Drafts/Image-Properties-Spec.md",children:"SCS Image Standard"})]}),"\n",(0,t.jsxs)(s.li,{children:["For Ceph, special playbooks were added to validate the deployment status of the OSD, MON and MGR services in OSISM. The commands for use are ",(0,t.jsx)(s.code,{children:"osism validate ceph-osds"}),", ",(0,t.jsx)(s.code,{children:"osism validate ceph-mons"}),", and ",(0,t.jsx)(s.code,{children:"osism validate ceph-mgrs"}),"."]}),"\n",(0,t.jsx)(s.li,{children:"OVN has been updated to version 22.09."}),"\n",(0,t.jsx)(s.li,{children:"OVS has been updated to version 3.0.1."}),"\n",(0,t.jsxs)(s.li,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/osism/testbed",children:"testbed"})," uses per default a proxy for container pulling. This will allow for airgapped installations out of the box. Please note: a full airgap support (with local mirrors, etc.) will follow in a future release."]}),"\n",(0,t.jsxs)(s.li,{children:["The efforts to create a well-maintained status page with well-defined interfaces resulted in an OpenAPI specification (within its own ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi",children:"repository"}),") which is intended to be implementable by multiple implementations."]}),"\n",(0,t.jsxs)(s.li,{children:["The dashboard of the ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/",children:"OpenStack Health Monitor"})," is in use by the SCS operators and has proven helpful a number of times in detecting and addressing issues. That said, it only received a few fixes and minor enhancements, as we plan to replace it with a more generic and more maintainable solution soon."]}),"\n",(0,t.jsx)(s.li,{children:"The k8s clusters built with our k8s-capi implementation now allow controlling the versions of more components; the latest tested and stable versions are used by default (if enabled). The latest version for the cilium CNI for example allows testing the upcoming k8s gateway API."}),"\n",(0,t.jsx)(s.li,{children:"The k8s cluster now allows filtering access to the kubernetes API by IP ranges."}),"\n",(0,t.jsx)(s.li,{children:"The k8s clusters now have the proxy protocol enabled with the nginx-ingress controller, so client IPs are visible; the previous issue that blocked internal access could be worked around."}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",children:"SCS Developer focused improvements (testbed and k8s cluster management)"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["The testbed has been significantly simplified for new operators and developers and a ",(0,t.jsx)(s.a,{href:"https://docs.osism.tech/testbed/quickstart.html",children:"Quick Start"})," guide has been added."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["For the IaaS reference implementation, please refer to the ",(0,t.jsx)(s.a,{href:"https://release.osism.tech/notes/5.0.0.html#upgrade-notes",children:"OSISM 5.0.0 Upgrade Notes"}),"."]}),"\n",(0,t.jsxs)(s.li,{children:["The k8s Cluster Management solution has an enhanced ",(0,t.jsx)(s.a,{href:"https://docs.scs.community/docs/k8s-cluster-api-provider/doc/Upgrade-Guide",children:"upgrade guide"})," that covers the upgrade of clusters as well as the upgrade of the cluster management server."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"removals",children:"Removals"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"The ospurge wrapper script has been removed from the osism.services.openstackclient role. The ospurge project is no longer compatible with the current OpenStack SDK. The command openstack project purge can be used as an alternative."}),"\n",(0,t.jsx)(s.li,{children:"The docker-compose package is uninstalled by the osism.commons.docker_compose role. The Compose v2 plugin for Docker is now used instead of the old standalone docker-compose CLI. A dummy script has been added to /usr/local/bin which displays a corresponding message when using docker-compose."}),"\n",(0,t.jsxs)(s.li,{children:["Further removals from the IaaS reference implementation, please refer to the ",(0,t.jsx)(s.a,{href:"https://release.osism.tech/notes/5.0.0.html#removals",children:"OSISM 5.0.0 Removals Section"}),"."]}),"\n",(0,t.jsxs)(s.li,{children:["The k8s cluster parameter ",(0,t.jsx)(s.code,{children:"ETCD_PRIO_BOOST"})," that was already unused has been removed as announced with R3."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,t.jsx)(s.h3,{id:"deprecations-via-osism",children:"Deprecations via OSISM"}),"\n",(0,t.jsxs)(s.p,{children:["For these please also refer to the ",(0,t.jsx)(s.a,{href:"https://release.osism.tech/notes/5.0.0.html#deprecations",children:"upstream deprecation notices"})]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"The role osism.services.bird is deprecated. In future, FRRouting (osism.services.frr) will be used."}),"\n",(0,t.jsx)(s.li,{children:"The role osism.services.minikube is deprecated. In future osism.services.k8s will be used."}),"\n",(0,t.jsx)(s.li,{children:"Heat is deprecated in favor of more generic Infrastructure as Code tools like Terraform as of now and will be removed in the future (exact removal date is not yet known)"}),"\n",(0,t.jsx)(s.li,{children:"Swift (currently available as Technical Preview) will be removed in favor of Ceph RGW"}),"\n",(0,t.jsx)(s.li,{children:"Trove (currently available as Technical Preview) will be removed in favor of Kubernetes database operators"}),"\n",(0,t.jsxs)(s.li,{children:["Skydive (currently available as Technical Preview) will be removed in the future, the project is not maintained anymore, last commit is 8th Jan 2022: ",(0,t.jsx)(s.a,{href:"https://review.opendev.org/c/openstack/kolla/+/869191",children:"https://review.opendev.org/c/openstack/kolla/+/869191"})]}),"\n",(0,t.jsxs)(s.li,{children:["The login to a registry with the ",(0,t.jsx)(s.code,{children:"osism.services.docker"})," role is deprecated in favor of the new ",(0,t.jsx)(s.code,{children:"osism.commons.docker_login"})," role."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,t.jsx)(s.p,{children:"Throughout the Release 4 development cycle, the SCS project issued two security advisories for upstream components:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["In November 2022 an advisory regarding ",(0,t.jsx)(s.a,{href:"https://www.openssl.org/news/secadv/20221101.txt",children:"CVE-2022-3602 and CVE-2022-3786"})," in OpenSSL was issued.\nOur ",(0,t.jsx)(s.a,{href:"https://scs.community/security/2022/11/01/advisory-spookyssl/",children:"advisory"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["In February 2023 an advisory regarding ",(0,t.jsx)(s.a,{href:"https://cve.report/CVE-2022-47951",children:"CVE 2022-47951"})," in OpenStack components nova and glance was published.\nOur ",(0,t.jsx)(s.a,{href:"https://scs.community/security/2023/01/24/cve-2022-47951/",children:"advisory"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.p,{children:"Fixes were delivered via maintenance updates to existing R3 deployments, but of course also included in the main development branch that became R4."}),"\n",(0,t.jsx)(s.h2,{id:"resolved-issues",children:"Resolved Issues"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["Breakage with old kustomize syntax has been addressed.(",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/issues/328",children:"k8s-capi/#328"}),")"]}),"\n",(0,t.jsxs)(s.li,{children:["The move of k8s container images from k8s.gcr.io to registry.k8s.io needed adjustments.(",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/issues/321",children:"k8s-capi/#321"}),")"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,t.jsxs)(s.p,{children:["The last months saw intense work in the standardization area. The process how standards are created has been documented.\nThe standards are collected in its own ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards",children:"standards"}),' repository.\nA machine readable file lists the required (and optional) standards that apply to "SCS-compatible" conformance at\nthe IaaS and the Container (KaaS) layer. The referenced executables are used by the compliance checking framework\nto test existing implementations for compliance. To run the checker, the tester needs access to the infrastructure\nunder test (normal user privileges are sufficient) and standard openstack and kubernetes client tools -- or just\nuse the docker container that is provided.']}),"\n",(0,t.jsxs)(s.p,{children:["The public clouds based on the SCS reference implementation from plusserver and Noris/Wavecon are tested automatically\nfrom us and the live result is visible in ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards",children:"standards page"}),".\nWe will enhance the standardization and test coverage significantly in the next months and we hope to list a number\nof more clouds there soon."]}),"\n",(0,t.jsx)(s.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,t.jsxs)(s.p,{children:["The code in OSISM and a number of SCS repositories will receive the ",(0,t.jsx)(s.code,{children:"v5.0.0"})," tag; some repositories use\n",(0,t.jsx)(s.code,{children:"maintained/v5.0.x"})," and ",(0,t.jsx)(s.code,{children:"maintained/v5.x"})," branches for providing code that only gets bug- and security fixes (5.0.x)\nor only those plus selected, backwards-compatible enhancements (5.x)."]}),"\n",(0,t.jsx)(s.h2,{id:"list-of-known-issues--restrictions-in-r4",children:"List of known issues & restrictions in R4"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"The k8s cluster-API code does not work well with OpenStack API endpoints that require trusting a custom CA."}),"\n",(0,t.jsxs)(s.li,{children:["The OpenStack component Horizon has two issues when working with Swift endpoints. One issue is a ",(0,t.jsx)(s.a,{href:"https://bugs.launchpad.net/horizon/+bug/1993005",children:"known bug"})," when uploading objects to Swift endpoints. A workaround will be released shortly after R4. The ",(0,t.jsx)(s.a,{href:"https://github.com/osism/issues/issues/488",children:"second issue"})," is that existing Swift containers can not be set to public."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"contributing",children:"Contributing"}),"\n",(0,t.jsxs)(s.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,t.jsx)(s.a,{href:"https://scs.community/contribute/",children:"How to contribute page"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"thanks",children:"Thanks"}),"\n",(0,t.jsx)(s.p,{children:"The work for R4 has been done by many contributors from our community.\nThe special thanks goes out to our contributors who participate in our community\non a very regular base - without these the various team calls and events like\nthe hackathons would be much less successful and fun."}),"\n",(0,t.jsx)(s.p,{children:"Of course we are leveraging a huge amount of open source technology that has been\ncreated by our friends in other communities, many of which are part of the\nCNCF, Linux Foudation, OIF, and others. We participate and contribute where\nwe can and definitely want to acknowledge the great work that we build upon."})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var t=n(96540);const i={},r=t.createContext(i);function o(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/440.c71a4efe.js b/assets/js/440.c71a4efe.js new file mode 100644 index 0000000000..a9056dd3a6 --- /dev/null +++ b/assets/js/440.c71a4efe.js @@ -0,0 +1,1410 @@ +"use strict"; +exports.id = 440; +exports.ids = [440]; +exports.modules = { + +/***/ 7440: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + diagram: () => (/* binding */ diagram) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-f47111a7.js + 8 modules +var mermaid_f47111a7 = __webpack_require__(76257); +// EXTERNAL MODULE: ./node_modules/d3/src/index.js + 197 modules +var src = __webpack_require__(26312); +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-array/src/min.js +function min(values, valueof) { + let min; + if (valueof === undefined) { + for (const value of values) { + if (value != null + && (min > value || (min === undefined && value >= value))) { + min = value; + } + } + } else { + let index = -1; + for (let value of values) { + if ((value = valueof(value, ++index, values)) != null + && (min > value || (min === undefined && value >= value))) { + min = value; + } + } + } + return min; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/src/align.js + + +function targetDepth(d) { + return d.target.depth; +} + +function left(node) { + return node.depth; +} + +function right(node, n) { + return n - 1 - node.height; +} + +function justify(node, n) { + return node.sourceLinks.length ? node.depth : n - 1; +} + +function center(node) { + return node.targetLinks.length ? node.depth + : node.sourceLinks.length ? min(node.sourceLinks, targetDepth) - 1 + : 0; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-array/src/sum.js +function sum(values, valueof) { + let sum = 0; + if (valueof === undefined) { + for (let value of values) { + if (value = +value) { + sum += value; + } + } + } else { + let index = -1; + for (let value of values) { + if (value = +valueof(value, ++index, values)) { + sum += value; + } + } + } + return sum; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-array/src/max.js +function max(values, valueof) { + let max; + if (valueof === undefined) { + for (const value of values) { + if (value != null + && (max < value || (max === undefined && value >= value))) { + max = value; + } + } + } else { + let index = -1; + for (let value of values) { + if ((value = valueof(value, ++index, values)) != null + && (max < value || (max === undefined && value >= value))) { + max = value; + } + } + } + return max; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/src/constant.js +function constant(x) { + return function() { + return x; + }; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/src/sankey.js + + + + +function ascendingSourceBreadth(a, b) { + return ascendingBreadth(a.source, b.source) || a.index - b.index; +} + +function ascendingTargetBreadth(a, b) { + return ascendingBreadth(a.target, b.target) || a.index - b.index; +} + +function ascendingBreadth(a, b) { + return a.y0 - b.y0; +} + +function value(d) { + return d.value; +} + +function defaultId(d) { + return d.index; +} + +function defaultNodes(graph) { + return graph.nodes; +} + +function defaultLinks(graph) { + return graph.links; +} + +function find(nodeById, id) { + const node = nodeById.get(id); + if (!node) throw new Error("missing: " + id); + return node; +} + +function computeLinkBreadths({nodes}) { + for (const node of nodes) { + let y0 = node.y0; + let y1 = y0; + for (const link of node.sourceLinks) { + link.y0 = y0 + link.width / 2; + y0 += link.width; + } + for (const link of node.targetLinks) { + link.y1 = y1 + link.width / 2; + y1 += link.width; + } + } +} + +function Sankey() { + let x0 = 0, y0 = 0, x1 = 1, y1 = 1; // extent + let dx = 24; // nodeWidth + let dy = 8, py; // nodePadding + let id = defaultId; + let align = justify; + let sort; + let linkSort; + let nodes = defaultNodes; + let links = defaultLinks; + let iterations = 6; + + function sankey() { + const graph = {nodes: nodes.apply(null, arguments), links: links.apply(null, arguments)}; + computeNodeLinks(graph); + computeNodeValues(graph); + computeNodeDepths(graph); + computeNodeHeights(graph); + computeNodeBreadths(graph); + computeLinkBreadths(graph); + return graph; + } + + sankey.update = function(graph) { + computeLinkBreadths(graph); + return graph; + }; + + sankey.nodeId = function(_) { + return arguments.length ? (id = typeof _ === "function" ? _ : constant(_), sankey) : id; + }; + + sankey.nodeAlign = function(_) { + return arguments.length ? (align = typeof _ === "function" ? _ : constant(_), sankey) : align; + }; + + sankey.nodeSort = function(_) { + return arguments.length ? (sort = _, sankey) : sort; + }; + + sankey.nodeWidth = function(_) { + return arguments.length ? (dx = +_, sankey) : dx; + }; + + sankey.nodePadding = function(_) { + return arguments.length ? (dy = py = +_, sankey) : dy; + }; + + sankey.nodes = function(_) { + return arguments.length ? (nodes = typeof _ === "function" ? _ : constant(_), sankey) : nodes; + }; + + sankey.links = function(_) { + return arguments.length ? (links = typeof _ === "function" ? _ : constant(_), sankey) : links; + }; + + sankey.linkSort = function(_) { + return arguments.length ? (linkSort = _, sankey) : linkSort; + }; + + sankey.size = function(_) { + return arguments.length ? (x0 = y0 = 0, x1 = +_[0], y1 = +_[1], sankey) : [x1 - x0, y1 - y0]; + }; + + sankey.extent = function(_) { + return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], sankey) : [[x0, y0], [x1, y1]]; + }; + + sankey.iterations = function(_) { + return arguments.length ? (iterations = +_, sankey) : iterations; + }; + + function computeNodeLinks({nodes, links}) { + for (const [i, node] of nodes.entries()) { + node.index = i; + node.sourceLinks = []; + node.targetLinks = []; + } + const nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d])); + for (const [i, link] of links.entries()) { + link.index = i; + let {source, target} = link; + if (typeof source !== "object") source = link.source = find(nodeById, source); + if (typeof target !== "object") target = link.target = find(nodeById, target); + source.sourceLinks.push(link); + target.targetLinks.push(link); + } + if (linkSort != null) { + for (const {sourceLinks, targetLinks} of nodes) { + sourceLinks.sort(linkSort); + targetLinks.sort(linkSort); + } + } + } + + function computeNodeValues({nodes}) { + for (const node of nodes) { + node.value = node.fixedValue === undefined + ? Math.max(sum(node.sourceLinks, value), sum(node.targetLinks, value)) + : node.fixedValue; + } + } + + function computeNodeDepths({nodes}) { + const n = nodes.length; + let current = new Set(nodes); + let next = new Set; + let x = 0; + while (current.size) { + for (const node of current) { + node.depth = x; + for (const {target} of node.sourceLinks) { + next.add(target); + } + } + if (++x > n) throw new Error("circular link"); + current = next; + next = new Set; + } + } + + function computeNodeHeights({nodes}) { + const n = nodes.length; + let current = new Set(nodes); + let next = new Set; + let x = 0; + while (current.size) { + for (const node of current) { + node.height = x; + for (const {source} of node.targetLinks) { + next.add(source); + } + } + if (++x > n) throw new Error("circular link"); + current = next; + next = new Set; + } + } + + function computeNodeLayers({nodes}) { + const x = max(nodes, d => d.depth) + 1; + const kx = (x1 - x0 - dx) / (x - 1); + const columns = new Array(x); + for (const node of nodes) { + const i = Math.max(0, Math.min(x - 1, Math.floor(align.call(null, node, x)))); + node.layer = i; + node.x0 = x0 + i * kx; + node.x1 = node.x0 + dx; + if (columns[i]) columns[i].push(node); + else columns[i] = [node]; + } + if (sort) for (const column of columns) { + column.sort(sort); + } + return columns; + } + + function initializeNodeBreadths(columns) { + const ky = min(columns, c => (y1 - y0 - (c.length - 1) * py) / sum(c, value)); + for (const nodes of columns) { + let y = y0; + for (const node of nodes) { + node.y0 = y; + node.y1 = y + node.value * ky; + y = node.y1 + py; + for (const link of node.sourceLinks) { + link.width = link.value * ky; + } + } + y = (y1 - y + py) / (nodes.length + 1); + for (let i = 0; i < nodes.length; ++i) { + const node = nodes[i]; + node.y0 += y * (i + 1); + node.y1 += y * (i + 1); + } + reorderLinks(nodes); + } + } + + function computeNodeBreadths(graph) { + const columns = computeNodeLayers(graph); + py = Math.min(dy, (y1 - y0) / (max(columns, c => c.length) - 1)); + initializeNodeBreadths(columns); + for (let i = 0; i < iterations; ++i) { + const alpha = Math.pow(0.99, i); + const beta = Math.max(1 - alpha, (i + 1) / iterations); + relaxRightToLeft(columns, alpha, beta); + relaxLeftToRight(columns, alpha, beta); + } + } + + // Reposition each node based on its incoming (target) links. + function relaxLeftToRight(columns, alpha, beta) { + for (let i = 1, n = columns.length; i < n; ++i) { + const column = columns[i]; + for (const target of column) { + let y = 0; + let w = 0; + for (const {source, value} of target.targetLinks) { + let v = value * (target.layer - source.layer); + y += targetTop(source, target) * v; + w += v; + } + if (!(w > 0)) continue; + let dy = (y / w - target.y0) * alpha; + target.y0 += dy; + target.y1 += dy; + reorderNodeLinks(target); + } + if (sort === undefined) column.sort(ascendingBreadth); + resolveCollisions(column, beta); + } + } + + // Reposition each node based on its outgoing (source) links. + function relaxRightToLeft(columns, alpha, beta) { + for (let n = columns.length, i = n - 2; i >= 0; --i) { + const column = columns[i]; + for (const source of column) { + let y = 0; + let w = 0; + for (const {target, value} of source.sourceLinks) { + let v = value * (target.layer - source.layer); + y += sourceTop(source, target) * v; + w += v; + } + if (!(w > 0)) continue; + let dy = (y / w - source.y0) * alpha; + source.y0 += dy; + source.y1 += dy; + reorderNodeLinks(source); + } + if (sort === undefined) column.sort(ascendingBreadth); + resolveCollisions(column, beta); + } + } + + function resolveCollisions(nodes, alpha) { + const i = nodes.length >> 1; + const subject = nodes[i]; + resolveCollisionsBottomToTop(nodes, subject.y0 - py, i - 1, alpha); + resolveCollisionsTopToBottom(nodes, subject.y1 + py, i + 1, alpha); + resolveCollisionsBottomToTop(nodes, y1, nodes.length - 1, alpha); + resolveCollisionsTopToBottom(nodes, y0, 0, alpha); + } + + // Push any overlapping nodes down. + function resolveCollisionsTopToBottom(nodes, y, i, alpha) { + for (; i < nodes.length; ++i) { + const node = nodes[i]; + const dy = (y - node.y0) * alpha; + if (dy > 1e-6) node.y0 += dy, node.y1 += dy; + y = node.y1 + py; + } + } + + // Push any overlapping nodes up. + function resolveCollisionsBottomToTop(nodes, y, i, alpha) { + for (; i >= 0; --i) { + const node = nodes[i]; + const dy = (node.y1 - y) * alpha; + if (dy > 1e-6) node.y0 -= dy, node.y1 -= dy; + y = node.y0 - py; + } + } + + function reorderNodeLinks({sourceLinks, targetLinks}) { + if (linkSort === undefined) { + for (const {source: {sourceLinks}} of targetLinks) { + sourceLinks.sort(ascendingTargetBreadth); + } + for (const {target: {targetLinks}} of sourceLinks) { + targetLinks.sort(ascendingSourceBreadth); + } + } + } + + function reorderLinks(nodes) { + if (linkSort === undefined) { + for (const {sourceLinks, targetLinks} of nodes) { + sourceLinks.sort(ascendingTargetBreadth); + targetLinks.sort(ascendingSourceBreadth); + } + } + } + + // Returns the target.y0 that would produce an ideal link from source to target. + function targetTop(source, target) { + let y = source.y0 - (source.sourceLinks.length - 1) * py / 2; + for (const {target: node, width} of source.sourceLinks) { + if (node === target) break; + y += width + py; + } + for (const {source: node, width} of target.targetLinks) { + if (node === source) break; + y -= width; + } + return y; + } + + // Returns the source.y0 that would produce an ideal link from source to target. + function sourceTop(source, target) { + let y = target.y0 - (target.targetLinks.length - 1) * py / 2; + for (const {source: node, width} of target.targetLinks) { + if (node === source) break; + y += width + py; + } + for (const {target: node, width} of source.sourceLinks) { + if (node === target) break; + y -= width; + } + return y; + } + + return sankey; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-path/src/path.js +var pi = Math.PI, + tau = 2 * pi, + epsilon = 1e-6, + tauEpsilon = tau - epsilon; + +function Path() { + this._x0 = this._y0 = // start of current subpath + this._x1 = this._y1 = null; // end of current subpath + this._ = ""; +} + +function path() { + return new Path; +} + +Path.prototype = path.prototype = { + constructor: Path, + moveTo: function(x, y) { + this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y); + }, + closePath: function() { + if (this._x1 !== null) { + this._x1 = this._x0, this._y1 = this._y0; + this._ += "Z"; + } + }, + lineTo: function(x, y) { + this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y); + }, + quadraticCurveTo: function(x1, y1, x, y) { + this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y); + }, + bezierCurveTo: function(x1, y1, x2, y2, x, y) { + this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y); + }, + arcTo: function(x1, y1, x2, y2, r) { + x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r; + var x0 = this._x1, + y0 = this._y1, + x21 = x2 - x1, + y21 = y2 - y1, + x01 = x0 - x1, + y01 = y0 - y1, + l01_2 = x01 * x01 + y01 * y01; + + // Is the radius negative? Error. + if (r < 0) throw new Error("negative radius: " + r); + + // Is this path empty? Move to (x1,y1). + if (this._x1 === null) { + this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1); + } + + // Or, is (x1,y1) coincident with (x0,y0)? Do nothing. + else if (!(l01_2 > epsilon)); + + // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? + // Equivalently, is (x1,y1) coincident with (x2,y2)? + // Or, is the radius zero? Line to (x1,y1). + else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) { + this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1); + } + + // Otherwise, draw an arc! + else { + var x20 = x2 - x0, + y20 = y2 - y0, + l21_2 = x21 * x21 + y21 * y21, + l20_2 = x20 * x20 + y20 * y20, + l21 = Math.sqrt(l21_2), + l01 = Math.sqrt(l01_2), + l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), + t01 = l / l01, + t21 = l / l21; + + // If the start tangent is not coincident with (x0,y0), line to. + if (Math.abs(t01 - 1) > epsilon) { + this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01); + } + + this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21); + } + }, + arc: function(x, y, r, a0, a1, ccw) { + x = +x, y = +y, r = +r, ccw = !!ccw; + var dx = r * Math.cos(a0), + dy = r * Math.sin(a0), + x0 = x + dx, + y0 = y + dy, + cw = 1 ^ ccw, + da = ccw ? a0 - a1 : a1 - a0; + + // Is the radius negative? Error. + if (r < 0) throw new Error("negative radius: " + r); + + // Is this path empty? Move to (x0,y0). + if (this._x1 === null) { + this._ += "M" + x0 + "," + y0; + } + + // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0). + else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) { + this._ += "L" + x0 + "," + y0; + } + + // Is this arc empty? We’re done. + if (!r) return; + + // Does the angle go the wrong way? Flip the direction. + if (da < 0) da = da % tau + tau; + + // Is this a complete circle? Draw two arcs to complete the circle. + if (da > tauEpsilon) { + this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0); + } + + // Is this arc non-empty? Draw an arc! + else if (da > epsilon) { + this._ += "A" + r + "," + r + ",0," + (+(da >= pi)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1)); + } + }, + rect: function(x, y, w, h) { + this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z"; + }, + toString: function() { + return this._; + } +}; + +/* harmony default export */ const src_path = (path); + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-shape/src/array.js +var slice = Array.prototype.slice; + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-shape/src/constant.js +/* harmony default export */ function src_constant(x) { + return function constant() { + return x; + }; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-shape/src/point.js +function point_x(p) { + return p[0]; +} + +function point_y(p) { + return p[1]; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-shape/src/link/index.js + + + + + + +function linkSource(d) { + return d.source; +} + +function linkTarget(d) { + return d.target; +} + +function link_link(curve) { + var source = linkSource, + target = linkTarget, + x = point_x, + y = point_y, + context = null; + + function link() { + var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv); + if (!context) context = buffer = src_path(); + curve(context, +x.apply(this, (argv[0] = s, argv)), +y.apply(this, argv), +x.apply(this, (argv[0] = t, argv)), +y.apply(this, argv)); + if (buffer) return context = null, buffer + "" || null; + } + + link.source = function(_) { + return arguments.length ? (source = _, link) : source; + }; + + link.target = function(_) { + return arguments.length ? (target = _, link) : target; + }; + + link.x = function(_) { + return arguments.length ? (x = typeof _ === "function" ? _ : src_constant(+_), link) : x; + }; + + link.y = function(_) { + return arguments.length ? (y = typeof _ === "function" ? _ : src_constant(+_), link) : y; + }; + + link.context = function(_) { + return arguments.length ? ((context = _ == null ? null : _), link) : context; + }; + + return link; +} + +function curveHorizontal(context, x0, y0, x1, y1) { + context.moveTo(x0, y0); + context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1); +} + +function curveVertical(context, x0, y0, x1, y1) { + context.moveTo(x0, y0); + context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1); +} + +function curveRadial(context, x0, y0, x1, y1) { + var p0 = pointRadial(x0, y0), + p1 = pointRadial(x0, y0 = (y0 + y1) / 2), + p2 = pointRadial(x1, y0), + p3 = pointRadial(x1, y1); + context.moveTo(p0[0], p0[1]); + context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]); +} + +function linkHorizontal() { + return link_link(curveHorizontal); +} + +function linkVertical() { + return link_link(curveVertical); +} + +function linkRadial() { + var l = link_link(curveRadial); + l.angle = l.x, delete l.x; + l.radius = l.y, delete l.y; + return l; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/src/sankeyLinkHorizontal.js + + +function horizontalSource(d) { + return [d.source.x1, d.y0]; +} + +function horizontalTarget(d) { + return [d.target.x0, d.y1]; +} + +/* harmony default export */ function sankeyLinkHorizontal() { + return linkHorizontal() + .source(horizontalSource) + .target(horizontalTarget); +} + +// EXTERNAL MODULE: ./node_modules/dayjs/dayjs.min.js +var dayjs_min = __webpack_require__(74353); +// EXTERNAL MODULE: ./node_modules/@braintree/sanitize-url/dist/index.js +var dist = __webpack_require__(16750); +// EXTERNAL MODULE: ./node_modules/dompurify/dist/purify.es.mjs +var purify_es = __webpack_require__(99418); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/sankeyDiagram-97764748.js + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 9], $V1 = [1, 10], $V2 = [1, 5, 10, 12]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "SANKEY": 4, "NEWLINE": 5, "csv": 6, "opt_eof": 7, "record": 8, "csv_tail": 9, "EOF": 10, "field[source]": 11, "COMMA": 12, "field[target]": 13, "field[value]": 14, "field": 15, "escaped": 16, "non_escaped": 17, "DQUOTE": 18, "ESCAPED_TEXT": 19, "NON_ESCAPED_TEXT": 20, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "SANKEY", 5: "NEWLINE", 10: "EOF", 11: "field[source]", 12: "COMMA", 13: "field[target]", 14: "field[value]", 18: "DQUOTE", 19: "ESCAPED_TEXT", 20: "NON_ESCAPED_TEXT" }, + productions_: [0, [3, 4], [6, 2], [9, 2], [9, 0], [7, 1], [7, 0], [8, 5], [15, 1], [15, 1], [16, 3], [17, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 7: + const source = yy.findOrCreateNode($$[$0 - 4].trim().replaceAll('""', '"')); + const target = yy.findOrCreateNode($$[$0 - 2].trim().replaceAll('""', '"')); + const value = parseFloat($$[$0].trim()); + yy.addLink(source, target, value); + break; + case 8: + case 9: + case 11: + this.$ = $$[$0]; + break; + case 10: + this.$ = $$[$0 - 1]; + break; + } + }, + table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, { 5: [1, 3] }, { 6: 4, 8: 5, 15: 6, 16: 7, 17: 8, 18: $V0, 20: $V1 }, { 1: [2, 6], 7: 11, 10: [1, 12] }, o($V1, [2, 4], { 9: 13, 5: [1, 14] }), { 12: [1, 15] }, o($V2, [2, 8]), o($V2, [2, 9]), { 19: [1, 16] }, o($V2, [2, 11]), { 1: [2, 1] }, { 1: [2, 5] }, o($V1, [2, 2]), { 6: 17, 8: 5, 15: 6, 16: 7, 17: 8, 18: $V0, 20: $V1 }, { 15: 18, 16: 7, 17: 8, 18: $V0, 20: $V1 }, { 18: [1, 19] }, o($V1, [2, 3]), { 12: [1, 20] }, o($V2, [2, 10]), { 15: 21, 16: 7, 17: 8, 18: $V0, 20: $V1 }, o([1, 5, 10], [2, 7])], + defaultActions: { 11: [2, 1], 12: [2, 5] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.pushState("csv"); + return 4; + case 1: + return 10; + case 2: + return 5; + case 3: + return 12; + case 4: + this.pushState("escaped_text"); + return 18; + case 5: + return 20; + case 6: + this.popState("escaped_text"); + return 18; + case 7: + return 19; + } + }, + rules: [/^(?:sankey-beta\b)/i, /^(?:$)/i, /^(?:((\u000D\u000A)|(\u000A)))/i, /^(?:(\u002C))/i, /^(?:(\u0022))/i, /^(?:([\u0020-\u0021\u0023-\u002B\u002D-\u007E])*)/i, /^(?:(\u0022)(?!(\u0022)))/i, /^(?:(([\u0020-\u0021\u0023-\u002B\u002D-\u007E])|(\u002C)|(\u000D)|(\u000A)|(\u0022)(\u0022))*)/i], + conditions: { "csv": { "rules": [1, 2, 3, 4, 5, 6, 7], "inclusive": false }, "escaped_text": { "rules": [6, 7], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let links = []; +let nodes = []; +let nodesMap = {}; +const clear = () => { + links = []; + nodes = []; + nodesMap = {}; + (0,mermaid_f47111a7.v)(); +}; +class SankeyLink { + constructor(source, target, value = 0) { + this.source = source; + this.target = target; + this.value = value; + } +} +const addLink = (source, target, value) => { + links.push(new SankeyLink(source, target, value)); +}; +class SankeyNode { + constructor(ID) { + this.ID = ID; + } +} +const findOrCreateNode = (ID) => { + ID = mermaid_f47111a7.e.sanitizeText(ID, (0,mermaid_f47111a7.c)()); + if (!nodesMap[ID]) { + nodesMap[ID] = new SankeyNode(ID); + nodes.push(nodesMap[ID]); + } + return nodesMap[ID]; +}; +const getNodes = () => nodes; +const getLinks = () => links; +const getGraph = () => ({ + nodes: nodes.map((node) => ({ id: node.ID })), + links: links.map((link) => ({ + source: link.source.ID, + target: link.target.ID, + value: link.value + })) +}); +const db = { + nodesMap, + getConfig: () => (0,mermaid_f47111a7.c)().sankey, + getNodes, + getLinks, + getGraph, + addLink, + findOrCreateNode, + getAccTitle: mermaid_f47111a7.g, + setAccTitle: mermaid_f47111a7.s, + getAccDescription: mermaid_f47111a7.a, + setAccDescription: mermaid_f47111a7.b, + getDiagramTitle: mermaid_f47111a7.t, + setDiagramTitle: mermaid_f47111a7.q, + clear +}; +const _Uid = class _Uid2 { + static next(name) { + return new _Uid2(name + ++_Uid2.count); + } + constructor(id) { + this.id = id; + this.href = `#${id}`; + } + toString() { + return "url(" + this.href + ")"; + } +}; +_Uid.count = 0; +let Uid = _Uid; +const alignmentsMap = { + left: left, + right: right, + center: center, + justify: justify +}; +const draw = function(text, id, _version, diagObj) { + const { securityLevel, sankey: conf } = (0,mermaid_f47111a7.c)(); + const defaultSankeyConfig = mermaid_f47111a7.K.sankey; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,src/* select */.Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,src/* select */.Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,src/* select */.Ltv)("body"); + const svg = securityLevel === "sandbox" ? root.select(`[id="${id}"]`) : (0,src/* select */.Ltv)(`[id="${id}"]`); + const width = (conf == null ? void 0 : conf.width) ?? defaultSankeyConfig.width; + const height = (conf == null ? void 0 : conf.height) ?? defaultSankeyConfig.width; + const useMaxWidth = (conf == null ? void 0 : conf.useMaxWidth) ?? defaultSankeyConfig.useMaxWidth; + const nodeAlignment = (conf == null ? void 0 : conf.nodeAlignment) ?? defaultSankeyConfig.nodeAlignment; + const prefix = (conf == null ? void 0 : conf.prefix) ?? defaultSankeyConfig.prefix; + const suffix = (conf == null ? void 0 : conf.suffix) ?? defaultSankeyConfig.suffix; + const showValues = (conf == null ? void 0 : conf.showValues) ?? defaultSankeyConfig.showValues; + const graph = diagObj.db.getGraph(); + const nodeAlign = alignmentsMap[nodeAlignment]; + const nodeWidth = 10; + const sankey$1 = Sankey().nodeId((d) => d.id).nodeWidth(nodeWidth).nodePadding(10 + (showValues ? 15 : 0)).nodeAlign(nodeAlign).extent([ + [0, 0], + [width, height] + ]); + sankey$1(graph); + const colorScheme = (0,src/* scaleOrdinal */.UMr)(src/* schemeTableau10 */.zt); + svg.append("g").attr("class", "nodes").selectAll(".node").data(graph.nodes).join("g").attr("class", "node").attr("id", (d) => (d.uid = Uid.next("node-")).id).attr("transform", function(d) { + return "translate(" + d.x0 + "," + d.y0 + ")"; + }).attr("x", (d) => d.x0).attr("y", (d) => d.y0).append("rect").attr("height", (d) => { + return d.y1 - d.y0; + }).attr("width", (d) => d.x1 - d.x0).attr("fill", (d) => colorScheme(d.id)); + const getText = ({ id: id2, value }) => { + if (!showValues) { + return id2; + } + return `${id2} +${prefix}${Math.round(value * 100) / 100}${suffix}`; + }; + svg.append("g").attr("class", "node-labels").attr("font-family", "sans-serif").attr("font-size", 14).selectAll("text").data(graph.nodes).join("text").attr("x", (d) => d.x0 < width / 2 ? d.x1 + 6 : d.x0 - 6).attr("y", (d) => (d.y1 + d.y0) / 2).attr("dy", `${showValues ? "0" : "0.35"}em`).attr("text-anchor", (d) => d.x0 < width / 2 ? "start" : "end").text(getText); + const link = svg.append("g").attr("class", "links").attr("fill", "none").attr("stroke-opacity", 0.5).selectAll(".link").data(graph.links).join("g").attr("class", "link").style("mix-blend-mode", "multiply"); + const linkColor = (conf == null ? void 0 : conf.linkColor) || "gradient"; + if (linkColor === "gradient") { + const gradient = link.append("linearGradient").attr("id", (d) => (d.uid = Uid.next("linearGradient-")).id).attr("gradientUnits", "userSpaceOnUse").attr("x1", (d) => d.source.x1).attr("x2", (d) => d.target.x0); + gradient.append("stop").attr("offset", "0%").attr("stop-color", (d) => colorScheme(d.source.id)); + gradient.append("stop").attr("offset", "100%").attr("stop-color", (d) => colorScheme(d.target.id)); + } + let coloring; + switch (linkColor) { + case "gradient": + coloring = (d) => d.uid; + break; + case "source": + coloring = (d) => colorScheme(d.source.id); + break; + case "target": + coloring = (d) => colorScheme(d.target.id); + break; + default: + coloring = linkColor; + } + link.append("path").attr("d", sankeyLinkHorizontal()).attr("stroke", coloring).attr("stroke-width", (d) => Math.max(1, d.width)); + (0,mermaid_f47111a7.o)(void 0, svg, 0, useMaxWidth); +}; +const renderer = { + draw +}; +const prepareTextForParsing = (text) => { + const textToParse = text.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g, "").replaceAll(/([\n\r])+/g, "\n").trim(); + return textToParse; +}; +const originalParse = parser$1.parse.bind(parser$1); +parser$1.parse = (text) => originalParse(prepareTextForParsing(text)); +const diagram = { + parser: parser$1, + db, + renderer +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/441ae8e9.22b363c5.js b/assets/js/441ae8e9.22b363c5.js new file mode 100644 index 0000000000..8536415276 --- /dev/null +++ b/assets/js/441ae8e9.22b363c5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2692],{32335:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var s=t(74848),r=t(28453);const a={title:"Maintenance and Troubleshooting Guide for SCS k8s-cluster-api-provider",version:new Date("2023-03-16T00:00:00.000Z"),authors:"Kurt Garloff, Mathias Fechner, Andrej Friesen, Matej Feder",state:"Draft (v0.3)"},o="Maintenance and Troubleshooting Guide for SCS k8s-cluster-api-provider",c={id:"container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting",title:"Maintenance and Troubleshooting Guide for SCS k8s-cluster-api-provider",description:"Client Certificates in Kubernetes expire after one year",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc",slug:"/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting.md",tags:[],version:"current",frontMatter:{title:"Maintenance and Troubleshooting Guide for SCS k8s-cluster-api-provider",version:"2023-03-16T00:00:00.000Z",authors:"Kurt Garloff, Mathias Fechner, Andrej Friesen, Matej Feder",state:"Draft (v0.3)"},sidebar:"docs",previous:{title:"Configuration",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/configuration"},next:{title:"Ingress with externalTrafficPolicy: local",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal"}},i={},l=[{value:"Client Certificates in Kubernetes expire after one year",id:"client-certificates-in-kubernetes-expire-after-one-year",level:2},{value:"Certificate Authority expires",id:"certificate-authority-expires",level:2},{value:"Failed cluster deployment debugging",id:"failed-cluster-deployment-debugging",level:2},{value:"Cluster state",id:"cluster-state",level:2},{value:"Etcd maintenance",id:"etcd-maintenance",level:2},{value:"Defragmentation and backup",id:"defragmentation-and-backup",level:3}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"maintenance-and-troubleshooting-guide-for-scs-k8s-cluster-api-provider",children:"Maintenance and Troubleshooting Guide for SCS k8s-cluster-api-provider"}),"\n",(0,s.jsx)(n.h2,{id:"client-certificates-in-kubernetes-expire-after-one-year",children:"Client Certificates in Kubernetes expire after one year"}),"\n",(0,s.jsxs)(n.p,{children:["What does a provider need to do in order to ",(0,s.jsx)(n.strong,{children:"NOT"})," run into a certificate issue?"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Update the cluster at least once a year to rotate certificates automatically"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#automatic-certificate-renewal",children:"Automatic certificate renewal for cluster upgrades"})}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["kubeadm renews all the certificates during control plane\n",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/",children:"upgrade"}),".\nThis feature is designed for addressing the simplest use cases; if you don't have specific\nrequirements on certificate renewal and perform Kubernetes version upgrades regularly\n(less than 1 year in between each upgrade), kubeadm will take care of keeping your\ncluster up to date and reasonably secure."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Renew all certificates with ",(0,s.jsx)(n.code,{children:"kubeadm certs renew all"})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"You only need to do this when you don't upgrade your cluster"}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-certs/#cmd-certs-renew",children:"kubeadm certs renew"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"certificate-authority-expires",children:"Certificate Authority expires"}),"\n",(0,s.jsx)(n.p,{children:"Another problem is that the CA might expire as well (normally after 10 years)"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"kubeadm"})," does not have any tooling for this at the time of writing"]}),"\n",(0,s.jsxs)(n.li,{children:["There is documentation for\n",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/tls/manual-rotation-of-ca-certificates/",children:"Manual Rotation of CA Certifcates"})]}),"\n",(0,s.jsxs)(n.li,{children:["On the management node, there is a ",(0,s.jsx)(n.code,{children:"signer.sh"})," that can be used to sign server certificates\nafter checking that they belong to the server."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"failed-cluster-deployment-debugging",children:"Failed cluster deployment debugging"}),"\n",(0,s.jsxs)(n.p,{children:["NOTE: The following ",(0,s.jsx)(n.code,{children:"kubectl"})," and ",(0,s.jsx)(n.code,{children:"clusterctl"})," commands should be executed against\nthe management Kubernetes cluster API. Keep in mind that these tools and the\n",(0,s.jsx)(n.code,{children:"kubeconfig"})," to access the management Kubernetes cluster are available in the management\nhost, hence it is convenient to execute the following commands from the management host."]}),"\n",(0,s.jsx)(n.p,{children:"Ask Kubernetes what went wrong:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl describe cluster <CLUSTER_NAME>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The status and the events may give you a clue what happened. The healthy cluster should\nbe in the phase: ",(0,s.jsx)(n.code,{children:"Provisioned"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ kubectl describe cluster <CLUSTER_NAME> | yq .Status.Phase\nProvisioned\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You can also have a look at the ",(0,s.jsx)(n.code,{children:"openstackcluster"})," object and see OpenStack related\nstatuses and events. The healthy cluster should be ready:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ kubectl describe openstackcluster <CLUSTER_NAME> | yq .Status.Ready\ntrue\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Note that you can instead execute ",(0,s.jsx)(n.code,{children:"kubectl get cluster <CLUSTER_NAME> -ojsonpath='{ .status.phase }'"}),"\nand ",(0,s.jsx)(n.code,{children:"kubectl get openstackcluster <CLUSTER_NAME> -ojsonpath='{ .status.ready }'"}),"\nif you don't have ",(0,s.jsx)(n.code,{children:"yq"})," at hand."]}),"\n",(0,s.jsxs)(n.p,{children:["A handy command for cluster health investigation is ",(0,s.jsx)(n.code,{children:"clusterctl describe cluster <CLUSTER_NAME>"}),".\nThis prints infrastructure/control plane/workers readiness status and other relevant\ninformation like a failure reason. The healthy cluster output is similar to this:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ clusterctl describe cluster <CLUSTER_NAME>\nNAME READY SEVERITY REASON SINCE MESSAGE\nCluster/testcluster True 21m\n\u251c\u2500ClusterInfrastructure - OpenStackCluster/testcluster\n\u251c\u2500ControlPlane - KubeadmControlPlane/testcluster-control-plane True 23m\n\u2502 \u2514\u25003 Machines... True 21m See testcluster-control-plane-5ftjs, testcluster-control-plane-62cdj, ...\n\n\u2514\u2500Workers\n \u2514\u2500MachineDeployment/capi-testcluster-md-0-no1 True 22m\n \u2514\u25003 Machines... True 21m See capi-testcluster-md-0-no1-84dd86f598-bhxfd, capi-testcluster-md-0-no1-84dd86f598-f6pnl, ...\n"})}),"\n",(0,s.jsx)(n.p,{children:"The logs of the capi pod and especially the capo pod are a good source of information.\nTo find out in which condition the deployment status is, you can use the following way:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl logs -n capo-system -l control-plane=capo-controller-manager -c manager\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Successful cluster creation will log ",(0,s.jsx)(n.code,{children:"Reconciled Machine create successfully"})," for\nsuccessfully created nodes."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl logs -n capi-system -l control-plane=controller-manager -c manager\n"})}),"\n",(0,s.jsxs)(n.p,{children:["In some cases could be a good idea to go through the official [capi]\n(",(0,s.jsx)(n.a,{href:"https://cluster-api.sigs.k8s.io/user/troubleshooting.html",children:"https://cluster-api.sigs.k8s.io/user/troubleshooting.html"}),") and ",(0,s.jsx)(n.a,{href:"https://cluster-api-openstack.sigs.k8s.io/topics/troubleshooting.html",children:"capo"}),"\ntroubleshooting guides or check whether you hit some known bug already reported in\n",(0,s.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api/issues?q=is%3Aissue+is%3Aopen+label%3Akind%2Fbug",children:"capi"}),"\nor ",(0,s.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api-provider-openstack/issues?q=is%3Aissue+is%3Aopen+label%3Akind%2Fbug",children:"capo"})," projects."]}),"\n",(0,s.jsx)(n.p,{children:"You can also check the OpenStack layer. A cluster deployment should result in a\nrouter,a network, a subnet, a loadbalancer (in front of kubeapi) and a number of servers (VMs)\nfor the control-plane and worker nodes. Have you run out of quota?"}),"\n",(0,s.jsx)(n.h2,{id:"cluster-state",children:"Cluster state"}),"\n",(0,s.jsxs)(n.p,{children:["Have a look at the pods that run:\n",(0,s.jsx)(n.code,{children:"kubectl --context=<CLUSTER_NAME>-admin@<CLUSTER_NAME> get pods -A"})]}),"\n",(0,s.jsxs)(n.p,{children:["or have a look at the nodes:\n",(0,s.jsx)(n.code,{children:"kubectl --context=<CLUSTER_NAME>-admin@<CLUSTER_NAME> get nodes -o wide"})]}),"\n",(0,s.jsxs)(n.p,{children:["If you fall into some Kubernetes specific issues after a successful cluster\ncreation, go through the official ",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/debug/debug-cluster/",children:"Kubernetes"}),"\ntroubleshooting guide."]}),"\n",(0,s.jsx)(n.h2,{id:"etcd-maintenance",children:"Etcd maintenance"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://etcd.io/",children:"Etcd"})," is a highly-available key value store used as Kubernetes'\nbacking store for all cluster data. This section contains etcd related maintenance\nnotes from SCS k8s-cluster-api-provider project perspective."]}),"\n",(0,s.jsxs)(n.p,{children:["For further information about etcd maintenance visit an official ",(0,s.jsx)(n.a,{href:"https://etcd.io/docs/v3.5/op-guide/maintenance/",children:"etcd maintenance guide"}),"\nand/or ",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/",children:"Kubernetes etcd operating guide"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"defragmentation-and-backup",children:"Defragmentation and backup"}),"\n",(0,s.jsxs)(n.p,{children:["Etcd storage can become fragmented over time, for this, we have included a\nmaintenance script that regularly defragments and then also backups the database.\nThe script, called ",(0,s.jsx)(n.code,{children:"etcd-defrag.sh"})," is located in each control plane node's ",(0,s.jsx)(n.code,{children:"/root"}),"\ndirectory . It is executed through the systemd service unit file ",(0,s.jsx)(n.code,{children:"etcd-defrag.service"}),"\nand scheduled to run each day at 02:30:00 using the ",(0,s.jsx)(n.code,{children:"etcd-defrag.timer"})," systemd timer."]}),"\n",(0,s.jsxs)(n.p,{children:["The defragmentation strategy is inspired by the ",(0,s.jsx)(n.a,{href:"https://github.com/ugur99/etcd-defrag-cronjob/",children:"etcd-defrag-cronjob"})," and\n",(0,s.jsx)(n.a,{href:"https://docs.openshift.com/container-platform/4.9/scalability_and_performance/recommended-host-practices.html#automatic-defrag-etcd-data_recommended-host-practices",children:"practices recommended"})," by the OpenShift project.\nNote that the proposed strategy could be changed in a future version based on results from\nrelated ",(0,s.jsx)(n.a,{href:"https://github.com/etcd-io/etcd/issues/15477",children:"upstream issue #15477"})," which wants to define\nan official solution on how to defragment etcd cluster."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"etcd-defrag.sh"})," script checks multiple conditions before the actual defragmentation as\nfollows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The script should not be executed on non leader etcd member"}),"\n",(0,s.jsx)(n.li,{children:"The script should not be executed on etcd cluster with some unhealthy member"}),"\n",(0,s.jsx)(n.li,{children:"The script should not be executed on single member etcd cluster"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"These pre-flight checks should ensure, that the defragmentation does not cause temporary\netcd cluster failures and/or unwanted etcd leader changes. They also prevent executing\nthe script on a single control-plane node cluster. Single-node etcd clusters are not\nmade for long-term operation. As a workaround, however, you can scale up to three\ncontrol-plane nodes overnight from time to time."}),"\n",(0,s.jsx)(n.p,{children:"After all pre-flight checks passed the etcd cluster defragmentation is performed as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Defragment the non leader etcd members first"}),"\n",(0,s.jsx)(n.li,{children:"Change the leadership to the randomly selected and defragmentation completed etcd member"}),"\n",(0,s.jsx)(n.li,{children:"Defragment the local (ex-leader) etcd member"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["At the end of the defragmentation script, the local (ex-leader) etcd member is backed up\nand trimmed. Backup is saved and then compressed in the control plane ",(0,s.jsx)(n.code,{children:"/root"})," directory.\nYou can find it here: ",(0,s.jsx)(n.code,{children:"/root/etcd-backup.xz"}),". File system trim is performed by the ",(0,s.jsx)(n.code,{children:"fstrim"}),"\ncommand that discards unused blocks on a filesystem which could increase write performance\non the long run and also release unused storage. Cluster admins are not supposed to log\nin to the cluster nodes (neither control plane nor workers) and thus won't access or use\nthese backup files. The local backups on these nodes however can prove useful however\nin a disaster recovery scenario."]}),"\n",(0,s.jsx)(n.p,{children:"All mentioned pre-flight checks could be skipped by the optional arguments that force\ndefragmentation despite potential failures. Optional arguments are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"--force-single"})," (allows to execute defragmentation on single member etcd cluster)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"--force-unhealthy"})," (allows to execute defragmentation on unhealthy etcd member)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"--force-nonleader"})," (allows to execute defragmentation on non leader etcd member)"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"We do not recommend to log in to the cluster nodes let alone executing manual\ndefragmentation"})," using the optional arguments above. If you are aware of potential\nissues, you can access the control plane node and execute the defragmentation script\nmanually as follows:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"/root/etcd-defrag.sh [--force-single] [--force-unhealthy] [--force-nonleader]\n"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const r={},a=s.createContext(r);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/441bd449.a4f3568e.js b/assets/js/441bd449.a4f3568e.js new file mode 100644 index 0000000000..479d16427e --- /dev/null +++ b/assets/js/441bd449.a4f3568e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9851],{57660:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>c,contentTitle:()=>d,default:()=>l,frontMatter:()=>t,metadata:()=>i,toc:()=>h});var n=o(74848),r=o(28453);const t={sidebar_label:"Ceph"},d="Ceph",i={id:"iaas/guides/troubleshooting-guide/ceph",title:"Ceph",description:"Where to find docs",source:"@site/docs/02-iaas/guides/troubleshooting-guide/ceph.md",sourceDirName:"02-iaas/guides/troubleshooting-guide",slug:"/iaas/guides/troubleshooting-guide/ceph",permalink:"/docs/iaas/guides/troubleshooting-guide/ceph",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/troubleshooting-guide/ceph.md",tags:[],version:"current",frontMatter:{sidebar_label:"Ceph"},sidebar:"docs",previous:{title:"OpenStack",permalink:"/docs/iaas/guides/troubleshooting-guide/openstack"},next:{title:"Guides",permalink:"/docs/iaas/guides/"}},c={},h=[{value:"Where to find docs",id:"where-to-find-docs",level:2},{value:"Critical medium error",id:"critical-medium-error",level:2}];function a(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"ceph",children:"Ceph"}),"\n",(0,n.jsx)(s.h2,{id:"where-to-find-docs",children:"Where to find docs"}),"\n",(0,n.jsxs)(s.p,{children:["The official Ceph documentation is located on ",(0,n.jsx)(s.a,{href:"https://docs.ceph.com/en/latest/rados/troubleshooting/",children:"https://docs.ceph.com/en/latest/rados/troubleshooting/"})]}),"\n",(0,n.jsxs)(s.p,{children:["It is ",(0,n.jsx)(s.strong,{children:"strongly advised"})," to use the documentation for the version being used."]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["Pacific - ",(0,n.jsx)(s.a,{href:"https://docs.ceph.com/en/pacific/rados/troubleshooting/",children:"https://docs.ceph.com/en/pacific/rados/troubleshooting/"})]}),"\n",(0,n.jsxs)(s.li,{children:["Quincy - ",(0,n.jsx)(s.a,{href:"https://docs.ceph.com/en/quincy/rados/troubleshooting/",children:"https://docs.ceph.com/en/quincy/rados/troubleshooting/"})]}),"\n",(0,n.jsxs)(s.li,{children:["Reef - ",(0,n.jsx)(s.a,{href:"https://docs.ceph.com/en/reef/rados/troubleshooting/",children:"https://docs.ceph.com/en/reef/rados/troubleshooting/"})]}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"critical-medium-error",children:"Critical medium error"}),"\n",(0,n.jsxs)(s.p,{children:["The block device ",(0,n.jsx)(s.code,{children:"sdf"})," has errors. You can see this in the kernel ring buffer, for example."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"$ sudo dmesg\n[...]\n[14062414.575715] sd 14:0:5:0: [sdf] tag#2120 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=1s\n[14062414.575722] sd 14:0:5:0: [sdf] tag#2120 Sense Key : Medium Error [current] [descriptor]\n[14062414.575725] sd 14:0:5:0: [sdf] tag#2120 Add. Sense: Unrecovered read error\n[14062414.575728] sd 14:0:5:0: [sdf] tag#2120 CDB: Read(16) 88 00 00 00 00 01 09 7c d9 50 00 00 00 80 00 00\n[14062414.575730] critical medium error, dev sdf, sector 4454144360 op 0x0:(READ) flags 0x0 phys_seg 13 prio class 2\n"})}),"\n",(0,n.jsx)(s.p,{children:"It may also be displayed in the health details of Ceph."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"$ ceph -s\n[...]\n health: HEALTH_WARN\n Too many repaired reads on 1 OSDs\n[...]\n\n$ ceph health detail\nHEALTH_WARN Too many repaired reads on 1 OSDs\n[WRN] OSD_TOO_MANY_REPAIRS: Too many repaired reads on 1 OSDs\n osd.17 had 13 reads repaire\n"})}),"\n",(0,n.jsxs)(s.p,{children:["In this case the block device ",(0,n.jsx)(s.code,{children:"sdf"})," is in the storage node ",(0,n.jsx)(s.code,{children:"sto1001"}),". The OSD assigned\nto this block device can be determined."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"$ ceph device ls | grep 'sto1001:sdf'\nSEAGATE_ST16000NM004J_ZR604ZDZ0000C210PWE9 sto1001:sdf osd.17\n"})}),"\n",(0,n.jsx)(s.p,{children:"If you only know the OSD ID, you can also determine the associated block device and the storage node."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"$ ceph device ls | grep osd.17\n[...]\nSEAGATE_ST16000NM004J_ZR604ZDZ0000C210PWE9 sto1001:sdf osd.17\n"})}),"\n",(0,n.jsx)(s.p,{children:"The broken OSD can be removed from the Ceph cluster. The Ceph cluster is then rebalanced.\nThis can take some time and cause a high level of activity on the Ceph cluster."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"$ ceph osd out osd.17\nmarked out osd.17.\n"})}),"\n",(0,n.jsx)(s.p,{children:"On the storage node disable the OSD service for the OSD."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"$ sudo systemctl stop ceph-osd@17.service\n"})})]})}function l(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(a,{...e})}):a(e)}},28453:(e,s,o)=>{o.d(s,{R:()=>d,x:()=>i});var n=o(96540);const r={},t=n.createContext(r);function d(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4468ebd1.a0f8510c.js b/assets/js/4468ebd1.a0f8510c.js new file mode 100644 index 0000000000..8a53282352 --- /dev/null +++ b/assets/js/4468ebd1.a0f8510c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8805],{45378:(t,e,o)=>{o.r(e),o.d(e,{assets:()=>u,contentTitle:()=>r,default:()=>m,frontMatter:()=>n,metadata:()=>c,toc:()=>l});var s=o(74848),i=o(28453);const n={slug:"first-blog-post",title:"First Blog Post",authors:"itrich",tags:["community","howto"]},r=void 0,c={permalink:"/blog/first-blog-post",editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/blog/2022-10-28-first-blog-post.md",source:"@site/blog/2022-10-28-first-blog-post.md",title:"First Blog Post",description:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet",date:"2022-10-28T00:00:00.000Z",tags:[{label:"community",permalink:"/blog/tags/community"},{label:"howto",permalink:"/blog/tags/howto"}],readingTime:.12,hasTruncateMarker:!1,authors:[{name:"Eduard Itrich",title:"Community Manager @ SCS",url:"https://github.com/itrich",imageURL:"https://github.com/itrich.png",key:"itrich"}],frontMatter:{slug:"first-blog-post",title:"First Blog Post",authors:"itrich",tags:["community","howto"]},unlisted:!1},u={authorsImageUrls:[void 0]},l=[];function a(t){const e={p:"p",...(0,i.R)(),...t.components};return(0,s.jsx)(e.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"})}function m(t={}){const{wrapper:e}={...(0,i.R)(),...t.components};return e?(0,s.jsx)(e,{...t,children:(0,s.jsx)(a,{...t})}):a(t)}},28453:(t,e,o)=>{o.d(e,{R:()=>r,x:()=>c});var s=o(96540);const i={},n=s.createContext(i);function r(t){const e=s.useContext(n);return s.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:r(t.components),s.createElement(n.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/452be0ad.f9df0f84.js b/assets/js/452be0ad.f9df0f84.js new file mode 100644 index 0000000000..006bb73070 --- /dev/null +++ b/assets/js/452be0ad.f9df0f84.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5546],{15225:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>u});var n=s(74848),o=s(28453);const c={},r="Overview",a={id:"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview",title:"Overview",description:"The Cluster Stack Provider OpenStack (CSPO) works with the Cluster Stack Operator (CSO) and Cluster Stacks, enabling the creation of Kubernetes clusters in a Cluster-API-native (CAPI) fashion.",source:"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview.md",sourceDirName:"03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs",slug:"/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview",permalink:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Cluster Stacks",permalink:"/docs/category/cluster-stacks"},next:{title:"Quickstart",permalink:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart"}},i={},u=[];function l(e){const t={a:"a",h1:"h1",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"overview",children:"Overview"}),"\n",(0,n.jsx)(t.p,{children:"The Cluster Stack Provider OpenStack (CSPO) works with the Cluster Stack Operator (CSO) and Cluster Stacks, enabling the creation of Kubernetes clusters in a Cluster-API-native (CAPI) fashion."}),"\n",(0,n.jsx)(t.p,{children:"The primary goal of the CSPO is to facilitate the import of node images in a manner specific to OpenStack. These images are then used to create Kubernetes workload clusters on top of the OpenStack infrastructure."}),"\n",(0,n.jsxs)(t.p,{children:["To gain a comprehensive understanding of the entire concept, we recommend familiarizing yourself with the fundamental ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/blob/main/docs/concept.md",children:"concepts"})," and ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/blob/main/docs/architecture/overview.md",children:"architecture"})," outlined in ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/blob/main/README.md",children:"CSO"})," and ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks/blob/main/README.md",children:"Cluster Stacks"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>a});var n=s(96540);const o={},c=n.createContext(o);function r(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/45bfeaeb.6bb0f898.js b/assets/js/45bfeaeb.6bb0f898.js new file mode 100644 index 0000000000..f10ba73350 --- /dev/null +++ b/assets/js/45bfeaeb.6bb0f898.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4257],{49648:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>d,frontMatter:()=>l,metadata:()=>u,toc:()=>a});var t=o(74848),i=o(28453);const l={},s="Zuul",u={id:"tools/zuul",title:"Zuul",description:"Zuul CI/CD pipelines and project gating",source:"@site/community/tools/zuul.md",sourceDirName:"tools",slug:"/tools/zuul",permalink:"/community/tools/zuul",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Nextcloud",permalink:"/community/tools/nextcloud"},next:{title:"Branch Protection Rules",permalink:"/community/tools/github/branchprotection"}},r={},a=[{value:"Zuul CI/CD pipelines and project gating",id:"zuul-cicd-pipelines-and-project-gating",level:2},{value:"How to make a repo use Zuul",id:"how-to-make-a-repo-use-zuul",level:3},{value:"General information about Zuul",id:"general-information-about-zuul",level:3}];function c(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"zuul",children:"Zuul"}),"\n",(0,t.jsx)(n.h2,{id:"zuul-cicd-pipelines-and-project-gating",children:"Zuul CI/CD pipelines and project gating"}),"\n",(0,t.jsx)(n.p,{children:"Since we are expecting a lot of pipelines beeing created and used GitHub actions won't keep up\nwell. We also expect cross-repository and even cross-project dependencies. Therefore we decided to\nuse Zuul as our main pipeline solution."}),"\n",(0,t.jsx)(n.h3,{id:"how-to-make-a-repo-use-zuul",children:"How to make a repo use Zuul"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Make Zuul aware of your repository in this ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul_deployment",children:"repo"})]}),"\n",(0,t.jsxs)(n.li,{children:["Create a file ",(0,t.jsx)(n.em,{children:".zuul.yaml"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["An example can be found ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-sandbox/blob/main/.zuul.yaml",children:"here"})]}),"\n",(0,t.jsxs)(n.li,{children:["You can have a job section containing ",(0,t.jsx)(n.em,{children:"self-defined"})," jobs which you need to write on your own"]}),"\n",(0,t.jsxs)(n.li,{children:["You have to have a project section containing","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"the default-branch name"}),"\n",(0,t.jsx)(n.li,{children:"the merge-mode which should be used to auto-merge"}),"\n",(0,t.jsx)(n.li,{children:"the jobs to run in each pipeline (gh_check, gh_gate, gh_post, gh_tag)"}),"\n",(0,t.jsxs)(n.li,{children:["these pipelines are triggered by events which can be looked up ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul_config/blob/main/zuul.d/gh_pipelines.yaml",children:"here"})]}),"\n",(0,t.jsxs)(n.li,{children:["some default jobs can be found ",(0,t.jsx)(n.a,{href:"https://opendev.org/zuul/zuul-jobs/src/branch/master/playbooks",children:"here"})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["If you have ",(0,t.jsx)(n.em,{children:"self-defined"})," jobs, you need to create a folder ",(0,t.jsx)(n.em,{children:".playbooks"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"this folder containers ansible playbooks which will be triggered"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"general-information-about-zuul",children:"General information about Zuul"}),"\n",(0,t.jsx)(n.p,{children:"Zuul does not take anything for granted. If you need to have something installed,\nyou should install it via ansible. Our test-machines are basically pimped\ndocker-containers, so we might run into issues some time. But for now, things work pretty good."})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>u});var t=o(96540);const i={},l=t.createContext(i);function s(e){const n=t.useContext(l);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function u(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/45f4377b.45d54f9b.js b/assets/js/45f4377b.45d54f9b.js new file mode 100644 index 0000000000..fc7f012a3c --- /dev/null +++ b/assets/js/45f4377b.45d54f9b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1346],{94312:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var o=n(74848),t=n(28453);const s={sidebar_label:"Seed",sidebar_position:10},r="Seed",a={id:"iaas/guides/deploy-guide/seed",title:"Seed",description:"The prerequisite for the deployment of a cluster is a configuration repository.",source:"@site/docs/02-iaas/guides/deploy-guide/seed.md",sourceDirName:"02-iaas/guides/deploy-guide",slug:"/iaas/guides/deploy-guide/seed",permalink:"/docs/iaas/guides/deploy-guide/seed",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/seed.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Seed",sidebar_position:10},sidebar:"docs",previous:{title:"Deploy Guide",permalink:"/docs/iaas/guides/deploy-guide/"},next:{title:"Manager",permalink:"/docs/iaas/guides/deploy-guide/manager"}},d={},c=[{value:"Install required packages",id:"install-required-packages",level:2},{value:"Get a copy of the configuration repository",id:"get-a-copy-of-the-configuration-repository",level:2}];function l(e){const i={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(i.h1,{id:"seed",children:"Seed"}),"\n",(0,o.jsx)(i.admonition,{type:"info",children:(0,o.jsxs)(i.p,{children:["The prerequisite for the deployment of a cluster is a configuration repository.\nWhat a configuration repository is and how it is created is described in the\n",(0,o.jsx)(i.a,{href:"../configuration-guide/configuration-repository#creating-a-new-configuration-repository",children:"Configuration Guide"}),"."]})}),"\n",(0,o.jsx)(i.p,{children:"The seed node is used once for the initial bootstrap of the manager node. The seed node can\nalso be used to initially create and prepare the configuration repository. The seed node is\nnot the manager node itself. It is sufficient to use the local workstation. It doesn't have\nto be a dedicated system. The seed node is no longer needed in the further process. The seed\nnode must be able to reach the manager node via SSH. It is important for the further process\nthat no packages are installed manually on the manager. Especially not Docker."}),"\n",(0,o.jsx)(i.p,{children:"The use of Linux on the seed node is recommended. Other operating systems should also\nwork without problems. It is assumed in this documentation that Ubuntu 22.04 is used on\nthe seed node."}),"\n",(0,o.jsx)(i.h2,{id:"install-required-packages",children:"Install required packages"}),"\n",(0,o.jsx)(i.pre,{children:(0,o.jsx)(i.code,{children:"sudo apt-get install git python3-pip python3-virtualenv sshpass\n"})}),"\n",(0,o.jsx)(i.h2,{id:"get-a-copy-of-the-configuration-repository",children:"Get a copy of the configuration repository"}),"\n",(0,o.jsxs)(i.p,{children:["Each environment managed with OSISM is based on a configuration repository. This was\npreviously created with Cookiecutter and the ",(0,o.jsx)(i.a,{href:"https://github.com/osism/cfg-cookiecutter",children:"osism/cfg-cookiecutter"}),"\nrepository."]}),"\n",(0,o.jsxs)(i.p,{children:["The creation of the configuration repository is covered in chapter\n",(0,o.jsx)(i.a,{href:"../configuration-guide/configuration-repository#creating-a-new-configuration-repository",children:"Creation of a configuration repository"}),"\nof the ",(0,o.jsx)(i.a,{href:"../configuration-guide",children:"Configuration Guide"}),"."]}),"\n",(0,o.jsx)(i.p,{children:"A configuration repository is stored on a Git server (e.g. GitHub, Gitlab, ...). The\nconfiguration repository is individual for each environment and is therefore not provided\nby us."}),"\n",(0,o.jsxs)(i.p,{children:["The configuration repository to be used must be available on the seed node. In the following\nexample, replace ",(0,o.jsx)(i.code,{children:"YOUR_ORG"})," and ",(0,o.jsx)(i.code,{children:"YOUR_NEW_CONFIGURATION_REPOSITORY"})," accordingly."]}),"\n",(0,o.jsx)(i.pre,{children:(0,o.jsx)(i.code,{children:"git clone ssh://git@github.com:YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY.git\n"})}),"\n",(0,o.jsx)(i.p,{children:"Examples:"}),"\n",(0,o.jsxs)(i.ul,{children:["\n",(0,o.jsxs)(i.li,{children:["The repository is located in the ",(0,o.jsx)(i.code,{children:"regiocloud"})," organisation on GitHub, has the name\nconfiguration and can be accessed via SSH: ",(0,o.jsx)(i.code,{children:"ssh://git@github.com:regiocloud/configuration.git"})]}),"\n",(0,o.jsxs)(i.li,{children:["The repository is located in the ",(0,o.jsx)(i.code,{children:"regiocloud"})," organisation on Gitlab, has the name configuration\nand can be accessed via SSH: ",(0,o.jsx)(i.code,{children:"ssh://git@gitlab.com:regiocloud/configuration.git"})]}),"\n",(0,o.jsxs)(i.li,{children:["The repository is located in the ",(0,o.jsx)(i.code,{children:"regiocloud"})," organisation on an internal Gitlab, has the name\nconfiguration and can be accessed via SSH: ",(0,o.jsx)(i.code,{children:"ssh://git@git.services.osism.tech:regiocloud/configuration.git"})]}),"\n"]}),"\n",(0,o.jsx)(i.p,{children:"If necessary, the configuration SSH key can be used for the initial transfer of the repository."}),"\n",(0,o.jsxs)(i.p,{children:["For this, the following content is added in ",(0,o.jsx)(i.code,{children:"~/.ssh/config"})," and the SSH privte key is stored in\n",(0,o.jsx)(i.code,{children:"~/.ssh/id_rsa.configuration"}),"."]}),"\n",(0,o.jsx)(i.pre,{children:(0,o.jsx)(i.code,{children:"Host github.com\n HostName github.com\n User git\n Port 22\n IdentityFile ~/.ssh/id_rsa.configuration\n"})})]})}function h(e={}){const{wrapper:i}={...(0,t.R)(),...e.components};return i?(0,o.jsx)(i,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>r,x:()=>a});var o=n(96540);const t={},s=o.createContext(t);function r(e){const i=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),o.createElement(s.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/469.1eaab61c.js b/assets/js/469.1eaab61c.js new file mode 100644 index 0000000000..00425c6c92 --- /dev/null +++ b/assets/js/469.1eaab61c.js @@ -0,0 +1,540 @@ +"use strict"; +exports.id = 469; +exports.ids = [469]; +exports.modules = { + +/***/ 59469: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(76257); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16750); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(26312); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99418); + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [6, 9, 10]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "info": 4, "document": 5, "EOF": 6, "line": 7, "statement": 8, "NL": 9, "showInfo": 10, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "info", 6: "EOF", 9: "NL", 10: "showInfo" }, + productions_: [0, [3, 3], [5, 0], [5, 2], [7, 1], [7, 1], [8, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + $$.length - 1; + switch (yystate) { + case 1: + return yy; + case 4: + break; + case 6: + yy.setInfo(true); + break; + } + }, + table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: 6, 9: [1, 7], 10: [1, 8] }, { 1: [2, 1] }, o($V0, [2, 3]), o($V0, [2, 4]), o($V0, [2, 5]), o($V0, [2, 6])], + defaultActions: { 4: [2, 1] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 4; + case 1: + return 9; + case 2: + return "space"; + case 3: + return 10; + case 4: + return 6; + case 5: + return "TXT"; + } + }, + rules: [/^(?:info\b)/i, /^(?:[\s\n\r]+)/i, /^(?:[\s]+)/i, /^(?:showInfo\b)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "INITIAL": { "rules": [0, 1, 2, 3, 4, 5], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const DEFAULT_INFO_DB = { + info: false +}; +let info = DEFAULT_INFO_DB.info; +const setInfo = (toggle) => { + info = toggle; +}; +const getInfo = () => info; +const clear = () => { + info = DEFAULT_INFO_DB.info; +}; +const db = { + clear, + setInfo, + getInfo +}; +const draw = (text, id, version) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("rendering info diagram\n" + text); + const svg = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.A)(id); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.i)(svg, 100, 400, true); + const group = svg.append("g"); + group.append("text").attr("x", 100).attr("y", 40).attr("class", "version").attr("font-size", 32).style("text-anchor", "middle").text(`v${version}`); +}; +const renderer = { draw }; +const diagram = { + parser: parser$1, + db, + renderer +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/477ed06d.ed5b7321.js b/assets/js/477ed06d.ed5b7321.js new file mode 100644 index 0000000000..4f14a9fc4b --- /dev/null +++ b/assets/js/477ed06d.ed5b7321.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3502],{64804:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var s=n(74848),r=n(28453);const i={},a="scs-0101: SCS Entropy",d={id:"iaas/scs-0101",title:"scs-0101: SCS Entropy",description:"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations",source:"@site/standards/iaas/scs-0101.md",sourceDirName:"iaas",slug:"/iaas/scs-0101",permalink:"/standards/iaas/scs-0101",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"SCS Flavor Naming Standard: Implementation and Testing Notes",permalink:"/standards/scs-0100-w1-flavor-naming-implementation-testing"},next:{title:"SCS Entropy",permalink:"/standards/scs-0101-v1-entropy"}},o={},c=[{value:"Supplement: Implementation and Testing Notes",id:"supplement-implementation-and-testing-notes",level:2}];function l(e){const t={a:"a",h1:"h1",h2:"h2",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"scs-0101-scs-entropy",children:"scs-0101: SCS Entropy"}),"\n",(0,s.jsx)(t.p,{children:"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations\nsuch as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and\nactivating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy\naccessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into\nvirtual instances and ensures the availability and quality of entropy in virtual environments, promoting system\nsecurity and efficiency."}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Version"}),(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"State"}),(0,s.jsx)(t.th,{children:"stabilized"}),(0,s.jsx)(t.th,{children:"deprecated"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/standards/scs-0101-v1-entropy",children:"scs-0101-v1"})}),(0,s.jsx)(t.td,{children:"Standard"}),(0,s.jsx)(t.td,{children:"Stable"}),(0,s.jsx)(t.td,{children:"2024-02-08"}),(0,s.jsx)(t.td,{children:"-"})]})})]}),"\n",(0,s.jsx)(t.h2,{id:"supplement-implementation-and-testing-notes",children:"Supplement: Implementation and Testing Notes"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Version"}),(0,s.jsx)(t.th,{children:"State"}),(0,s.jsx)(t.th,{children:"stabilized"}),(0,s.jsx)(t.th,{children:"deprecated"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/standards/scs-0101-w1-entropy-implementation-testing",children:"w1"})}),(0,s.jsx)(t.td,{children:"Proposal"}),(0,s.jsx)(t.td,{children:"-"}),(0,s.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>d});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/489.79124cfe.js b/assets/js/489.79124cfe.js new file mode 100644 index 0000000000..85f9e9c887 --- /dev/null +++ b/assets/js/489.79124cfe.js @@ -0,0 +1,2 @@ +/*! For license information please see 489.79124cfe.js.LICENSE.txt */ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[489],{90489:(t,e,n)=>{"use strict";t.exports=n(810)},2542:(t,e,n)=>{"use strict";var i=n(46573),s={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none",opacity:"1"},input:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},inputWithNoHint:{position:"relative",verticalAlign:"top"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"},suggestions:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"},ltr:{left:"0",right:"auto"},rtl:{left:"auto",right:"0"},defaultClasses:{root:"algolia-autocomplete",prefix:"aa",noPrefix:!1,dropdownMenu:"dropdown-menu",input:"input",hint:"hint",suggestions:"suggestions",suggestion:"suggestion",cursor:"cursor",dataset:"dataset",empty:"empty"},appendTo:{wrapper:{position:"absolute",zIndex:"100",display:"none"},input:{},inputWithNoHint:{},dropdown:{display:"block"}}};i.isMsie()&&i.mixin(s.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),i.isMsie()&&i.isMsie()<=7&&i.mixin(s.input,{marginTop:"-1px"}),t.exports=s},10897:(t,e,n)=>{"use strict";var i="aaDataset",s="aaValue",r="aaDatum",o=n(46573),a=n(61348),u=n(99272),c=n(2542),l=n(84436);function h(t){var e;(t=t||{}).templates=t.templates||{},t.source||o.error("missing source"),t.name&&(e=t.name,!/^[_a-zA-Z0-9-]+$/.test(e))&&o.error("invalid dataset name: "+t.name),this.query=null,this._isEmpty=!0,this.highlight=!!t.highlight,this.name=void 0===t.name||null===t.name?o.getUniqueId():t.name,this.source=t.source,this.displayFn=function(t){return t=t||"value",o.isFunction(t)?t:e;function e(e){return e[t]}}(t.display||t.displayKey),this.debounce=t.debounce,this.cache=!1!==t.cache,this.templates=function(t,e){return{empty:t.empty&&o.templatify(t.empty),header:t.header&&o.templatify(t.header),footer:t.footer&&o.templatify(t.footer),suggestion:t.suggestion||n};function n(t){return"<p>"+e(t)+"</p>"}}(t.templates,this.displayFn),this.css=o.mixin({},c,t.appendTo?c.appendTo:{}),this.cssClasses=t.cssClasses=o.mixin({},c.defaultClasses,t.cssClasses||{}),this.cssClasses.prefix=t.cssClasses.formattedPrefix||o.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix);var n=o.className(this.cssClasses.prefix,this.cssClasses.dataset);this.$el=t.$menu&&t.$menu.find(n+"-"+this.name).length>0?a.element(t.$menu.find(n+"-"+this.name)[0]):a.element(u.dataset.replace("%CLASS%",this.name).replace("%PREFIX%",this.cssClasses.prefix).replace("%DATASET%",this.cssClasses.dataset)),this.$menu=t.$menu,this.clearCachedSuggestions()}h.extractDatasetName=function(t){return a.element(t).data(i)},h.extractValue=function(t){return a.element(t).data(s)},h.extractDatum=function(t){var e=a.element(t).data(r);return"string"==typeof e&&(e=JSON.parse(e)),e},o.mixin(h.prototype,l,{_render:function(t,e){if(this.$el){var n,c=this,l=[].slice.call(arguments,2);if(this.$el.empty(),n=e&&e.length,this._isEmpty=!n,!n&&this.templates.empty)this.$el.html(function(){var e=[].slice.call(arguments,0);return e=[{query:t,isEmpty:!0}].concat(e),c.templates.empty.apply(this,e)}.apply(this,l)).prepend(c.templates.header?h.apply(this,l):null).append(c.templates.footer?p.apply(this,l):null);else if(n)this.$el.html(function(){var t,n,l=[].slice.call(arguments,0),h=this,p=u.suggestions.replace("%PREFIX%",this.cssClasses.prefix).replace("%SUGGESTIONS%",this.cssClasses.suggestions);return t=a.element(p).css(this.css.suggestions),n=o.map(e,f),t.append.apply(t,n),t;function f(t){var e,n=u.suggestion.replace("%PREFIX%",h.cssClasses.prefix).replace("%SUGGESTION%",h.cssClasses.suggestion);return(e=a.element(n).attr({role:"option",id:["option",Math.floor(1e8*Math.random())].join("-")}).append(c.templates.suggestion.apply(this,[t].concat(l)))).data(i,c.name),e.data(s,c.displayFn(t)||void 0),e.data(r,JSON.stringify(t)),e.children().each((function(){a.element(this).css(h.css.suggestionChild)})),e}}.apply(this,l)).prepend(c.templates.header?h.apply(this,l):null).append(c.templates.footer?p.apply(this,l):null);else if(e&&!Array.isArray(e))throw new TypeError("suggestions must be an array");this.$menu&&this.$menu.addClass(this.cssClasses.prefix+(n?"with":"without")+"-"+this.name).removeClass(this.cssClasses.prefix+(n?"without":"with")+"-"+this.name),this.trigger("rendered",t)}function h(){var e=[].slice.call(arguments,0);return e=[{query:t,isEmpty:!n}].concat(e),c.templates.header.apply(this,e)}function p(){var e=[].slice.call(arguments,0);return e=[{query:t,isEmpty:!n}].concat(e),c.templates.footer.apply(this,e)}},getRoot:function(){return this.$el},update:function(t){function e(e){if(!this.canceled&&t===this.query){var n=[].slice.call(arguments,1);this.cacheSuggestions(t,e,n),this._render.apply(this,[t,e].concat(n))}}if(this.query=t,this.canceled=!1,this.shouldFetchFromCache(t))e.apply(this,[this.cachedSuggestions].concat(this.cachedRenderExtraArgs));else{var n=this,i=function(){n.canceled||n.source(t,e.bind(n))};if(this.debounce){clearTimeout(this.debounceTimeout),this.debounceTimeout=setTimeout((function(){n.debounceTimeout=null,i()}),this.debounce)}else i()}},cacheSuggestions:function(t,e,n){this.cachedQuery=t,this.cachedSuggestions=e,this.cachedRenderExtraArgs=n},shouldFetchFromCache:function(t){return this.cache&&this.cachedQuery===t&&this.cachedSuggestions&&this.cachedSuggestions.length},clearCachedSuggestions:function(){delete this.cachedQuery,delete this.cachedSuggestions,delete this.cachedRenderExtraArgs},cancel:function(){this.canceled=!0},clear:function(){this.$el&&(this.cancel(),this.$el.empty(),this.trigger("rendered",""))},isEmpty:function(){return this._isEmpty},destroy:function(){this.clearCachedSuggestions(),this.$el=null}}),t.exports=h},21540:(t,e,n)=>{"use strict";var i=n(46573),s=n(61348),r=n(84436),o=n(10897),a=n(2542);function u(t){var e,n,r,o=this;(t=t||{}).menu||i.error("menu is required"),i.isArray(t.datasets)||i.isObject(t.datasets)||i.error("1 or more datasets required"),t.datasets||i.error("datasets is required"),this.isOpen=!1,this.isEmpty=!0,this.minLength=t.minLength||0,this.templates={},this.appendTo=t.appendTo||!1,this.css=i.mixin({},a,t.appendTo?a.appendTo:{}),this.cssClasses=t.cssClasses=i.mixin({},a.defaultClasses,t.cssClasses||{}),this.cssClasses.prefix=t.cssClasses.formattedPrefix||i.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix),e=i.bind(this._onSuggestionClick,this),n=i.bind(this._onSuggestionMouseEnter,this),r=i.bind(this._onSuggestionMouseLeave,this);var c=i.className(this.cssClasses.prefix,this.cssClasses.suggestion);this.$menu=s.element(t.menu).on("mouseenter.aa",c,n).on("mouseleave.aa",c,r).on("click.aa",c,e),this.$container=t.appendTo?t.wrapper:this.$menu,t.templates&&t.templates.header&&(this.templates.header=i.templatify(t.templates.header),this.$menu.prepend(this.templates.header())),t.templates&&t.templates.empty&&(this.templates.empty=i.templatify(t.templates.empty),this.$empty=s.element('<div class="'+i.className(this.cssClasses.prefix,this.cssClasses.empty,!0)+'"></div>'),this.$menu.append(this.$empty),this.$empty.hide()),this.datasets=i.map(t.datasets,(function(e){return function(t,e,n){return new u.Dataset(i.mixin({$menu:t,cssClasses:n},e))}(o.$menu,e,t.cssClasses)})),i.each(this.datasets,(function(t){var e=t.getRoot();e&&0===e.parent().length&&o.$menu.append(e),t.onSync("rendered",o._onRendered,o)})),t.templates&&t.templates.footer&&(this.templates.footer=i.templatify(t.templates.footer),this.$menu.append(this.templates.footer()));var l=this;s.element(window).resize((function(){l._redraw()}))}i.mixin(u.prototype,r,{_onSuggestionClick:function(t){this.trigger("suggestionClicked",s.element(t.currentTarget))},_onSuggestionMouseEnter:function(t){var e=s.element(t.currentTarget);if(!e.hasClass(i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0))){this._removeCursor();var n=this;setTimeout((function(){n._setCursor(e,!1)}),0)}},_onSuggestionMouseLeave:function(t){if(t.relatedTarget&&s.element(t.relatedTarget).closest("."+i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0)).length>0)return;this._removeCursor(),this.trigger("cursorRemoved")},_onRendered:function(t,e){if(this.isEmpty=i.every(this.datasets,(function(t){return t.isEmpty()})),this.isEmpty)if(e.length>=this.minLength&&this.trigger("empty"),this.$empty)if(e.length<this.minLength)this._hide();else{var n=this.templates.empty({query:this.datasets[0]&&this.datasets[0].query});this.$empty.html(n),this.$empty.show(),this._show()}else i.any(this.datasets,(function(t){return t.templates&&t.templates.empty}))?e.length<this.minLength?this._hide():this._show():this._hide();else this.isOpen&&(this.$empty&&(this.$empty.empty(),this.$empty.hide()),e.length>=this.minLength?this._show():this._hide());this.trigger("datasetRendered")},_hide:function(){this.$container.hide()},_show:function(){this.$container.css("display","block"),this._redraw(),this.trigger("shown")},_redraw:function(){this.isOpen&&this.appendTo&&this.trigger("redrawn")},_getSuggestions:function(){return this.$menu.find(i.className(this.cssClasses.prefix,this.cssClasses.suggestion))},_getCursor:function(){return this.$menu.find(i.className(this.cssClasses.prefix,this.cssClasses.cursor)).first()},_setCursor:function(t,e){t.first().addClass(i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0)).attr("aria-selected","true"),this.trigger("cursorMoved",e)},_removeCursor:function(){this._getCursor().removeClass(i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0)).removeAttr("aria-selected")},_moveCursor:function(t){var e,n,i,s;this.isOpen&&(n=this._getCursor(),e=this._getSuggestions(),this._removeCursor(),-1!==(i=((i=e.index(n)+t)+1)%(e.length+1)-1)?(i<-1&&(i=e.length-1),this._setCursor(s=e.eq(i),!0),this._ensureVisible(s)):this.trigger("cursorRemoved"))},_ensureVisible:function(t){var e,n,i,s;n=(e=t.position().top)+t.height()+parseInt(t.css("margin-top"),10)+parseInt(t.css("margin-bottom"),10),i=this.$menu.scrollTop(),s=this.$menu.height()+parseInt(this.$menu.css("padding-top"),10)+parseInt(this.$menu.css("padding-bottom"),10),e<0?this.$menu.scrollTop(i+e):s<n&&this.$menu.scrollTop(i+(n-s))},close:function(){this.isOpen&&(this.isOpen=!1,this._removeCursor(),this._hide(),this.trigger("closed"))},open:function(){this.isOpen||(this.isOpen=!0,this.isEmpty||this._show(),this.trigger("opened"))},setLanguageDirection:function(t){this.$menu.css("ltr"===t?this.css.ltr:this.css.rtl)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(1)},getDatumForSuggestion:function(t){var e=null;return t.length&&(e={raw:o.extractDatum(t),value:o.extractValue(t),datasetName:o.extractDatasetName(t)}),e},getCurrentCursor:function(){return this._getCursor().first()},getDatumForCursor:function(){return this.getDatumForSuggestion(this._getCursor().first())},getDatumForTopSuggestion:function(){return this.getDatumForSuggestion(this._getSuggestions().first())},cursorTopSuggestion:function(){this._setCursor(this._getSuggestions().first(),!1)},update:function(t){i.each(this.datasets,(function(e){e.update(t)}))},empty:function(){i.each(this.datasets,(function(t){t.clear()})),this.isEmpty=!0},isVisible:function(){return this.isOpen&&!this.isEmpty},destroy:function(){this.$menu.off(".aa"),this.$menu=null,i.each(this.datasets,(function(t){t.destroy()}))}}),u.Dataset=o,t.exports=u},52324:(t,e,n)=>{"use strict";var i=n(46573),s=n(61348);function r(t){t&&t.el||i.error("EventBus initialized without el"),this.$el=s.element(t.el)}i.mixin(r.prototype,{trigger:function(t,e,n,s){var r=i.Event("autocomplete:"+t);return this.$el.trigger(r,[e,n,s]),r}}),t.exports=r},84436:(t,e,n)=>{"use strict";var i=n(90874),s=/\s+/;function r(t,e,n,i){var r;if(!n)return this;for(e=e.split(s),n=i?function(t,e){return t.bind?t.bind(e):function(){t.apply(e,[].slice.call(arguments,0))}}(n,i):n,this._callbacks=this._callbacks||{};r=e.shift();)this._callbacks[r]=this._callbacks[r]||{sync:[],async:[]},this._callbacks[r][t].push(n);return this}function o(t,e,n){return function(){for(var i,s=0,r=t.length;!i&&s<r;s+=1)i=!1===t[s].apply(e,n);return!i}}t.exports={onSync:function(t,e,n){return r.call(this,"sync",t,e,n)},onAsync:function(t,e,n){return r.call(this,"async",t,e,n)},off:function(t){var e;if(!this._callbacks)return this;t=t.split(s);for(;e=t.shift();)delete this._callbacks[e];return this},trigger:function(t){var e,n,r,a,u;if(!this._callbacks)return this;t=t.split(s),r=[].slice.call(arguments,1);for(;(e=t.shift())&&(n=this._callbacks[e]);)a=o(n.sync,this,[e].concat(r)),u=o(n.async,this,[e].concat(r)),a()&&i(u);return this}}},99272:t=>{"use strict";t.exports={wrapper:'<span class="%ROOT%"></span>',dropdown:'<span class="%PREFIX%%DROPDOWN_MENU%"></span>',dataset:'<div class="%PREFIX%%DATASET%-%CLASS%"></div>',suggestions:'<span class="%PREFIX%%SUGGESTIONS%"></span>',suggestion:'<div class="%PREFIX%%SUGGESTION%"></div>'}},49629:(t,e,n)=>{"use strict";var i;i={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"};var s=n(46573),r=n(61348),o=n(84436);function a(t){var e,n,o,a,u,c=this;(t=t||{}).input||s.error("input is missing"),e=s.bind(this._onBlur,this),n=s.bind(this._onFocus,this),o=s.bind(this._onKeydown,this),a=s.bind(this._onInput,this),this.$hint=r.element(t.hint),this.$input=r.element(t.input).on("blur.aa",e).on("focus.aa",n).on("keydown.aa",o),0===this.$hint.length&&(this.setHint=this.getHint=this.clearHint=this.clearHintIfInvalid=s.noop),s.isMsie()?this.$input.on("keydown.aa keypress.aa cut.aa paste.aa",(function(t){i[t.which||t.keyCode]||s.defer(s.bind(c._onInput,c,t))})):this.$input.on("input.aa",a),this.query=this.$input.val(),this.$overflowHelper=(u=this.$input,r.element('<pre aria-hidden="true"></pre>').css({position:"absolute",visibility:"hidden",whiteSpace:"pre",fontFamily:u.css("font-family"),fontSize:u.css("font-size"),fontStyle:u.css("font-style"),fontVariant:u.css("font-variant"),fontWeight:u.css("font-weight"),wordSpacing:u.css("word-spacing"),letterSpacing:u.css("letter-spacing"),textIndent:u.css("text-indent"),textRendering:u.css("text-rendering"),textTransform:u.css("text-transform")}).insertAfter(u))}function u(t){return t.altKey||t.ctrlKey||t.metaKey||t.shiftKey}a.normalizeQuery=function(t){return(t||"").replace(/^\s*/g,"").replace(/\s{2,}/g," ")},s.mixin(a.prototype,o,{_onBlur:function(){this.resetInputValue(),this.$input.removeAttr("aria-activedescendant"),this.trigger("blurred")},_onFocus:function(){this.trigger("focused")},_onKeydown:function(t){var e=i[t.which||t.keyCode];this._managePreventDefault(e,t),e&&this._shouldTrigger(e,t)&&this.trigger(e+"Keyed",t)},_onInput:function(){this._checkInputValue()},_managePreventDefault:function(t,e){var n,i,s;switch(t){case"tab":i=this.getHint(),s=this.getInputValue(),n=i&&i!==s&&!u(e);break;case"up":case"down":n=!u(e);break;default:n=!1}n&&e.preventDefault()},_shouldTrigger:function(t,e){var n;if("tab"===t)n=!u(e);else n=!0;return n},_checkInputValue:function(){var t,e,n,i,s;t=this.getInputValue(),i=t,s=this.query,n=!(!(e=a.normalizeQuery(i)===a.normalizeQuery(s))||!this.query)&&this.query.length!==t.length,this.query=t,e?n&&this.trigger("whitespaceChanged",this.query):this.trigger("queryChanged",this.query)},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return this.query},setQuery:function(t){this.query=t},getInputValue:function(){return this.$input.val()},setInputValue:function(t,e){void 0===t&&(t=this.query),this.$input.val(t),e?this.clearHint():this._checkInputValue()},expand:function(){this.$input.attr("aria-expanded","true")},collapse:function(){this.$input.attr("aria-expanded","false")},setActiveDescendant:function(t){this.$input.attr("aria-activedescendant",t)},removeActiveDescendant:function(){this.$input.removeAttr("aria-activedescendant")},resetInputValue:function(){this.setInputValue(this.query,!0)},getHint:function(){return this.$hint.val()},setHint:function(t){this.$hint.val(t)},clearHint:function(){this.setHint("")},clearHintIfInvalid:function(){var t,e,n;n=(t=this.getInputValue())!==(e=this.getHint())&&0===e.indexOf(t),""!==t&&n&&!this.hasOverflow()||this.clearHint()},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},hasOverflow:function(){var t=this.$input.width()-2;return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>=t},isCursorAtEnd:function(){var t,e,n;return t=this.$input.val().length,e=this.$input[0].selectionStart,s.isNumber(e)?e===t:!document.selection||((n=document.selection.createRange()).moveStart("character",-t),t===n.text.length)},destroy:function(){this.$hint.off(".aa"),this.$input.off(".aa"),this.$hint=this.$input=this.$overflowHelper=null}}),t.exports=a},37360:(t,e,n)=>{"use strict";var i="aaAttrs",s=n(46573),r=n(61348),o=n(52324),a=n(49629),u=n(21540),c=n(99272),l=n(2542);function h(t){var e,n;if((t=t||{}).input||s.error("missing input"),this.isActivated=!1,this.debug=!!t.debug,this.autoselect=!!t.autoselect,this.autoselectOnBlur=!!t.autoselectOnBlur,this.openOnFocus=!!t.openOnFocus,this.minLength=s.isNumber(t.minLength)?t.minLength:1,this.autoWidth=void 0===t.autoWidth||!!t.autoWidth,this.clearOnSelected=!!t.clearOnSelected,this.tabAutocomplete=void 0===t.tabAutocomplete||!!t.tabAutocomplete,t.hint=!!t.hint,t.hint&&t.appendTo)throw new Error("[autocomplete.js] hint and appendTo options can't be used at the same time");this.css=t.css=s.mixin({},l,t.appendTo?l.appendTo:{}),this.cssClasses=t.cssClasses=s.mixin({},l.defaultClasses,t.cssClasses||{}),this.cssClasses.prefix=t.cssClasses.formattedPrefix=s.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix),this.listboxId=t.listboxId=[this.cssClasses.root,"listbox",s.getUniqueId()].join("-");var a=function(t){var e,n,o,a;e=r.element(t.input),n=r.element(c.wrapper.replace("%ROOT%",t.cssClasses.root)).css(t.css.wrapper),t.appendTo||"block"!==e.css("display")||"table"!==e.parent().css("display")||n.css("display","table-cell");var u=c.dropdown.replace("%PREFIX%",t.cssClasses.prefix).replace("%DROPDOWN_MENU%",t.cssClasses.dropdownMenu);o=r.element(u).css(t.css.dropdown).attr({role:"listbox",id:t.listboxId}),t.templates&&t.templates.dropdownMenu&&o.html(s.templatify(t.templates.dropdownMenu)());a=e.clone().css(t.css.hint).css(function(t){return{backgroundAttachment:t.css("background-attachment"),backgroundClip:t.css("background-clip"),backgroundColor:t.css("background-color"),backgroundImage:t.css("background-image"),backgroundOrigin:t.css("background-origin"),backgroundPosition:t.css("background-position"),backgroundRepeat:t.css("background-repeat"),backgroundSize:t.css("background-size")}}(e)),a.val("").addClass(s.className(t.cssClasses.prefix,t.cssClasses.hint,!0)).removeAttr("id name placeholder required").prop("readonly",!0).attr({"aria-hidden":"true",autocomplete:"off",spellcheck:"false",tabindex:-1}),a.removeData&&a.removeData();e.data(i,{"aria-autocomplete":e.attr("aria-autocomplete"),"aria-expanded":e.attr("aria-expanded"),"aria-owns":e.attr("aria-owns"),autocomplete:e.attr("autocomplete"),dir:e.attr("dir"),role:e.attr("role"),spellcheck:e.attr("spellcheck"),style:e.attr("style"),type:e.attr("type")}),e.addClass(s.className(t.cssClasses.prefix,t.cssClasses.input,!0)).attr({autocomplete:"off",spellcheck:!1,role:"combobox","aria-autocomplete":t.datasets&&t.datasets[0]&&t.datasets[0].displayKey?"both":"list","aria-expanded":"false","aria-label":t.ariaLabel,"aria-owns":t.listboxId}).css(t.hint?t.css.input:t.css.inputWithNoHint);try{e.attr("dir")||e.attr("dir","auto")}catch(l){}return n=t.appendTo?n.appendTo(r.element(t.appendTo).eq(0)).eq(0):e.wrap(n).parent(),n.prepend(t.hint?a:null).append(o),{wrapper:n,input:e,hint:a,menu:o}}(t);this.$node=a.wrapper;var u=this.$input=a.input;e=a.menu,n=a.hint,t.dropdownMenuContainer&&r.element(t.dropdownMenuContainer).css("position","relative").append(e.css("top","0")),u.on("blur.aa",(function(t){var n=document.activeElement;s.isMsie()&&(e[0]===n||e[0].contains(n))&&(t.preventDefault(),t.stopImmediatePropagation(),s.defer((function(){u.focus()})))})),e.on("mousedown.aa",(function(t){t.preventDefault()})),this.eventBus=t.eventBus||new o({el:u}),this.dropdown=new h.Dropdown({appendTo:t.appendTo,wrapper:this.$node,menu:e,datasets:t.datasets,templates:t.templates,cssClasses:t.cssClasses,minLength:this.minLength}).onSync("suggestionClicked",this._onSuggestionClicked,this).onSync("cursorMoved",this._onCursorMoved,this).onSync("cursorRemoved",this._onCursorRemoved,this).onSync("opened",this._onOpened,this).onSync("closed",this._onClosed,this).onSync("shown",this._onShown,this).onSync("empty",this._onEmpty,this).onSync("redrawn",this._onRedrawn,this).onAsync("datasetRendered",this._onDatasetRendered,this),this.input=new h.Input({input:u,hint:n}).onSync("focused",this._onFocused,this).onSync("blurred",this._onBlurred,this).onSync("enterKeyed",this._onEnterKeyed,this).onSync("tabKeyed",this._onTabKeyed,this).onSync("escKeyed",this._onEscKeyed,this).onSync("upKeyed",this._onUpKeyed,this).onSync("downKeyed",this._onDownKeyed,this).onSync("leftKeyed",this._onLeftKeyed,this).onSync("rightKeyed",this._onRightKeyed,this).onSync("queryChanged",this._onQueryChanged,this).onSync("whitespaceChanged",this._onWhitespaceChanged,this),this._bindKeyboardShortcuts(t),this._setLanguageDirection()}s.mixin(h.prototype,{_bindKeyboardShortcuts:function(t){if(t.keyboardShortcuts){var e=this.$input,n=[];s.each(t.keyboardShortcuts,(function(t){"string"==typeof t&&(t=t.toUpperCase().charCodeAt(0)),n.push(t)})),r.element(document).keydown((function(t){var i=t.target||t.srcElement,s=i.tagName;if(!i.isContentEditable&&"INPUT"!==s&&"SELECT"!==s&&"TEXTAREA"!==s){var r=t.which||t.keyCode;-1!==n.indexOf(r)&&(e.focus(),t.stopPropagation(),t.preventDefault())}}))}},_onSuggestionClicked:function(t,e){var n;(n=this.dropdown.getDatumForSuggestion(e))&&this._select(n,{selectionMethod:"click"})},_onCursorMoved:function(t,e){var n=this.dropdown.getDatumForCursor(),i=this.dropdown.getCurrentCursor().attr("id");this.input.setActiveDescendant(i),n&&(e&&this.input.setInputValue(n.value,!0),this.eventBus.trigger("cursorchanged",n.raw,n.datasetName))},_onCursorRemoved:function(){this.input.resetInputValue(),this._updateHint(),this.eventBus.trigger("cursorremoved")},_onDatasetRendered:function(){this._updateHint(),this.eventBus.trigger("updated")},_onOpened:function(){this._updateHint(),this.input.expand(),this.eventBus.trigger("opened")},_onEmpty:function(){this.eventBus.trigger("empty")},_onRedrawn:function(){this.$node.css("top","0px"),this.$node.css("left","0px");var t=this.$input[0].getBoundingClientRect();this.autoWidth&&this.$node.css("width",t.width+"px");var e=this.$node[0].getBoundingClientRect(),n=t.bottom-e.top;this.$node.css("top",n+"px");var i=t.left-e.left;this.$node.css("left",i+"px"),this.eventBus.trigger("redrawn")},_onShown:function(){this.eventBus.trigger("shown"),this.autoselect&&this.dropdown.cursorTopSuggestion()},_onClosed:function(){this.input.clearHint(),this.input.removeActiveDescendant(),this.input.collapse(),this.eventBus.trigger("closed")},_onFocused:function(){if(this.isActivated=!0,this.openOnFocus){var t=this.input.getQuery();t.length>=this.minLength?this.dropdown.update(t):this.dropdown.empty(),this.dropdown.open()}},_onBlurred:function(){var t,e;t=this.dropdown.getDatumForCursor(),e=this.dropdown.getDatumForTopSuggestion();var n={selectionMethod:"blur"};this.debug||(this.autoselectOnBlur&&t?this._select(t,n):this.autoselectOnBlur&&e?this._select(e,n):(this.isActivated=!1,this.dropdown.empty(),this.dropdown.close()))},_onEnterKeyed:function(t,e){var n,i;n=this.dropdown.getDatumForCursor(),i=this.dropdown.getDatumForTopSuggestion();var s={selectionMethod:"enterKey"};n?(this._select(n,s),e.preventDefault()):this.autoselect&&i&&(this._select(i,s),e.preventDefault())},_onTabKeyed:function(t,e){if(this.tabAutocomplete){var n;(n=this.dropdown.getDatumForCursor())?(this._select(n,{selectionMethod:"tabKey"}),e.preventDefault()):this._autocomplete(!0)}else this.dropdown.close()},_onEscKeyed:function(){this.dropdown.close(),this.input.resetInputValue()},_onUpKeyed:function(){var t=this.input.getQuery();this.dropdown.isEmpty&&t.length>=this.minLength?this.dropdown.update(t):this.dropdown.moveCursorUp(),this.dropdown.open()},_onDownKeyed:function(){var t=this.input.getQuery();this.dropdown.isEmpty&&t.length>=this.minLength?this.dropdown.update(t):this.dropdown.moveCursorDown(),this.dropdown.open()},_onLeftKeyed:function(){"rtl"===this.dir&&this._autocomplete()},_onRightKeyed:function(){"ltr"===this.dir&&this._autocomplete()},_onQueryChanged:function(t,e){this.input.clearHintIfInvalid(),e.length>=this.minLength?this.dropdown.update(e):this.dropdown.empty(),this.dropdown.open(),this._setLanguageDirection()},_onWhitespaceChanged:function(){this._updateHint(),this.dropdown.open()},_setLanguageDirection:function(){var t=this.input.getLanguageDirection();this.dir!==t&&(this.dir=t,this.$node.css("direction",t),this.dropdown.setLanguageDirection(t))},_updateHint:function(){var t,e,n,i,r;(t=this.dropdown.getDatumForTopSuggestion())&&this.dropdown.isVisible()&&!this.input.hasOverflow()?(e=this.input.getInputValue(),n=a.normalizeQuery(e),i=s.escapeRegExChars(n),(r=new RegExp("^(?:"+i+")(.+$)","i").exec(t.value))?this.input.setHint(e+r[1]):this.input.clearHint()):this.input.clearHint()},_autocomplete:function(t){var e,n,i,s;e=this.input.getHint(),n=this.input.getQuery(),i=t||this.input.isCursorAtEnd(),e&&n!==e&&i&&((s=this.dropdown.getDatumForTopSuggestion())&&this.input.setInputValue(s.value),this.eventBus.trigger("autocompleted",s.raw,s.datasetName))},_select:function(t,e){void 0!==t.value&&this.input.setQuery(t.value),this.clearOnSelected?this.setVal(""):this.input.setInputValue(t.value,!0),this._setLanguageDirection(),!1===this.eventBus.trigger("selected",t.raw,t.datasetName,e).isDefaultPrevented()&&(this.dropdown.close(),s.defer(s.bind(this.dropdown.empty,this.dropdown)))},open:function(){if(!this.isActivated){var t=this.input.getInputValue();t.length>=this.minLength?this.dropdown.update(t):this.dropdown.empty()}this.dropdown.open()},close:function(){this.dropdown.close()},setVal:function(t){t=s.toStr(t),this.isActivated?this.input.setInputValue(t):(this.input.setQuery(t),this.input.setInputValue(t,!0)),this._setLanguageDirection()},getVal:function(){return this.input.getQuery()},destroy:function(){this.input.destroy(),this.dropdown.destroy(),function(t,e){var n=t.find(s.className(e.prefix,e.input));s.each(n.data(i),(function(t,e){void 0===t?n.removeAttr(e):n.attr(e,t)})),n.detach().removeClass(s.className(e.prefix,e.input,!0)).insertAfter(t),n.removeData&&n.removeData(i);t.remove()}(this.$node,this.cssClasses),this.$node=null},getWrapper:function(){return this.dropdown.$container[0]}}),h.Dropdown=u,h.Input=a,h.sources=n(36353),t.exports=h},61348:t=>{"use strict";t.exports={element:null}},19715:t=>{"use strict";t.exports=function(t){var e=t.match(/Algolia for JavaScript \((\d+\.)(\d+\.)(\d+)\)/)||t.match(/Algolia for vanilla JavaScript (\d+\.)(\d+\.)(\d+)/);if(e)return[e[1],e[2],e[3]]}},46573:(t,e,n)=>{"use strict";var i,s=n(68937),r=n(61348);function o(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}t.exports={isArray:null,isFunction:null,isObject:null,bind:null,each:null,map:null,mixin:null,isMsie:function(t){if(void 0===t&&(t=navigator.userAgent),/(msie|trident)/i.test(t)){var e=t.match(/(msie |rv:)(\d+(.\d+)?)/i);if(e)return e[2]}return!1},escapeRegExChars:function(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isNumber:function(t){return"number"==typeof t},toStr:function(t){return null==t?"":t+""},cloneDeep:function(t){var e=this.mixin({},t),n=this;return this.each(e,(function(t,i){t&&(n.isArray(t)?e[i]=[].concat(t):n.isObject(t)&&(e[i]=n.cloneDeep(t)))})),e},error:function(t){throw new Error(t)},every:function(t,e){var n=!0;return t?(this.each(t,(function(i,s){n&&(n=e.call(null,i,s,t)&&n)})),!!n):n},any:function(t,e){var n=!1;return t?(this.each(t,(function(i,s){if(e.call(null,i,s,t))return n=!0,!1})),n):n},getUniqueId:(i=0,function(){return i++}),templatify:function(t){if(this.isFunction(t))return t;var e=r.element(t);return"SCRIPT"===e.prop("tagName")?function(){return e.text()}:function(){return String(t)}},defer:function(t){setTimeout(t,0)},noop:function(){},formatPrefix:function(t,e){return e?"":t+"-"},className:function(t,e,n){return n?t+e:"."+s(t+e,{isIdentifier:!0})},escapeHighlightedString:function(t,e,n){e=e||"<em>";var i=document.createElement("div");i.appendChild(document.createTextNode(e)),n=n||"</em>";var s=document.createElement("div");s.appendChild(document.createTextNode(n));var r=document.createElement("div");return r.appendChild(document.createTextNode(t)),r.innerHTML.replace(RegExp(o(i.innerHTML),"g"),e).replace(RegExp(o(s.innerHTML),"g"),n)}}},16903:(t,e,n)=>{"use strict";var i=n(46573),s=n(92281),r=n(19715);var o,a,u=(o=[],a=window.Promise.resolve(),function(t,e){return function(n,s){(function(t,e){return window.Promise.resolve().then((function(){return o.length&&(a=t.search(o),o=[]),a})).then((function(t){if(t)return t.results[e]}))})(t.as,o.push({indexName:t.indexName,query:n,params:e})-1).then((function(t){t&&s(t.hits,t)})).catch((function(t){i.error(t.message)}))}});t.exports=function(t,e){var n=r(t.as._ua);if(n&&n[0]>=3&&n[1]>20){var i="autocomplete.js "+s;-1===t.as._ua.indexOf(i)&&(t.as._ua+="; "+i)}return u(t,e)}},36353:(t,e,n)=>{"use strict";t.exports={hits:n(16903),popularIn:n(46839)}},46839:(t,e,n)=>{"use strict";var i=n(46573),s=n(92281),r=n(19715);t.exports=function(t,e,n,o){var a=r(t.as._ua);if(a&&a[0]>=3&&a[1]>20&&((e=e||{}).additionalUA="autocomplete.js "+s),!n.source)return i.error("Missing 'source' key");var u=i.isFunction(n.source)?n.source:function(t){return t[n.source]};if(!n.index)return i.error("Missing 'index' key");var c=n.index;return o=o||{},function(a,l){t.search(a,e,(function(t,a){if(t)i.error(t.message);else{if(a.hits.length>0){var h=a.hits[0],p=i.mixin({hitsPerPage:0},n);delete p.source,delete p.index;var f=r(c.as._ua);return f&&f[0]>=3&&f[1]>20&&(e.additionalUA="autocomplete.js "+s),void c.search(u(h),p,(function(t,e){if(t)i.error(t.message);else{var n=[];if(o.includeAll){var s=o.allTitle||"All departments";n.push(i.mixin({facet:{value:s,count:e.nbHits}},i.cloneDeep(h)))}i.each(e.facets,(function(t,e){i.each(t,(function(t,s){n.push(i.mixin({facet:{facet:e,value:s,count:t}},i.cloneDeep(h)))}))}));for(var r=1;r<a.hits.length;++r)n.push(a.hits[r]);l(n,a)}}))}l([])}}))}}},810:(t,e,n)=>{"use strict";var i=n(59539);n(61348).element=i;var s=n(46573);s.isArray=i.isArray,s.isFunction=i.isFunction,s.isObject=i.isPlainObject,s.bind=i.proxy,s.each=function(t,e){i.each(t,(function(t,n){return e(n,t)}))},s.map=i.map,s.mixin=i.extend,s.Event=i.Event;var r="aaAutocomplete",o=n(37360),a=n(52324);function u(t,e,n,u){n=s.isArray(n)?n:[].slice.call(arguments,2);var c=i(t).each((function(t,s){var c=i(s),l=new a({el:c}),h=u||new o({input:c,eventBus:l,dropdownMenuContainer:e.dropdownMenuContainer,hint:void 0===e.hint||!!e.hint,minLength:e.minLength,autoselect:e.autoselect,autoselectOnBlur:e.autoselectOnBlur,tabAutocomplete:e.tabAutocomplete,openOnFocus:e.openOnFocus,templates:e.templates,debug:e.debug,clearOnSelected:e.clearOnSelected,cssClasses:e.cssClasses,datasets:n,keyboardShortcuts:e.keyboardShortcuts,appendTo:e.appendTo,autoWidth:e.autoWidth,ariaLabel:e.ariaLabel||s.getAttribute("aria-label")});c.data(r,h)}));return c.autocomplete={},s.each(["open","close","getVal","setVal","destroy","getWrapper"],(function(t){c.autocomplete[t]=function(){var e,n=arguments;return c.each((function(s,o){var a=i(o).data(r);e=a[t].apply(a,n)})),e}})),c}u.sources=o.sources,u.escapeHighlightedString=s.escapeHighlightedString;var c="autocomplete"in window,l=window.autocomplete;u.noConflict=function(){return c?window.autocomplete=l:delete window.autocomplete,u},t.exports=u},92281:t=>{t.exports="0.38.1"},59539:t=>{var e;e=window,t.exports=function(t){var e,n,i=function(){var e,n,i,s,r,o,a=[],u=a.concat,c=a.filter,l=a.slice,h=t.document,p={},f={},d={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},g=/^\s*<(\w+|!)[^>]*>/,m=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,y=/^(?:body|html)$/i,w=/([A-Z])/g,b=["val","css","html","text","data","width","height","offset"],C=["after","prepend","before","append"],x=h.createElement("table"),_=h.createElement("tr"),S={tr:h.createElement("tbody"),tbody:x,thead:x,tfoot:x,td:_,th:_,"*":h.createElement("div")},E=/complete|loaded|interactive/,A=/^[\w-]*$/,$={},T=$.toString,O={},D=h.createElement("div"),N={tabindex:"tabIndex",readonly:"readOnly",for:"htmlFor",class:"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},k=Array.isArray||function(t){return t instanceof Array};function I(t){return null==t?String(t):$[T.call(t)]||"object"}function P(t){return"function"==I(t)}function L(t){return null!=t&&t==t.window}function M(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE}function F(t){return"object"==I(t)}function R(t){return F(t)&&!L(t)&&Object.getPrototypeOf(t)==Object.prototype}function q(t){var e=!!t&&"length"in t&&t.length,n=i.type(t);return"function"!=n&&!L(t)&&("array"==n||0===e||"number"==typeof e&&e>0&&e-1 in t)}function V(t){return c.call(t,(function(t){return null!=t}))}function H(t){return t.length>0?i.fn.concat.apply([],t):t}function B(t){return t.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function K(t){return t in f?f[t]:f[t]=new RegExp("(^|\\s)"+t+"(\\s|$)")}function j(t,e){return"number"!=typeof e||d[B(t)]?e:e+"px"}function z(t){var e,n;return p[t]||(e=h.createElement(t),h.body.appendChild(e),n=getComputedStyle(e,"").getPropertyValue("display"),e.parentNode.removeChild(e),"none"==n&&(n="block"),p[t]=n),p[t]}function U(t){return"children"in t?l.call(t.children):i.map(t.childNodes,(function(t){if(1==t.nodeType)return t}))}function Q(t,e){var n,i=t?t.length:0;for(n=0;n<i;n++)this[n]=t[n];this.length=i,this.selector=e||""}function W(t,i,s){for(n in i)s&&(R(i[n])||k(i[n]))?(R(i[n])&&!R(t[n])&&(t[n]={}),k(i[n])&&!k(t[n])&&(t[n]=[]),W(t[n],i[n],s)):i[n]!==e&&(t[n]=i[n])}function Z(t,e){return null==e?i(t):i(t).filter(e)}function X(t,e,n,i){return P(e)?e.call(t,n,i):e}function G(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function J(t,n){var i=t.className||"",s=i&&i.baseVal!==e;if(n===e)return s?i.baseVal:i;s?i.baseVal=n:t.className=n}function Y(t){try{return t?"true"==t||"false"!=t&&("null"==t?null:+t+""==t?+t:/^[\[\{]/.test(t)?i.parseJSON(t):t):t}catch(e){return t}}function tt(t,e){e(t);for(var n=0,i=t.childNodes.length;n<i;n++)tt(t.childNodes[n],e)}return O.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var n=t.matches||t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var i,s=t.parentNode,r=!s;return r&&(s=D).appendChild(t),i=~O.qsa(s,e).indexOf(t),r&&D.removeChild(t),i},r=function(t){return t.replace(/-+(.)?/g,(function(t,e){return e?e.toUpperCase():""}))},o=function(t){return c.call(t,(function(e,n){return t.indexOf(e)==n}))},O.fragment=function(t,n,s){var r,o,a;return m.test(t)&&(r=i(h.createElement(RegExp.$1))),r||(t.replace&&(t=t.replace(v,"<$1></$2>")),n===e&&(n=g.test(t)&&RegExp.$1),n in S||(n="*"),(a=S[n]).innerHTML=""+t,r=i.each(l.call(a.childNodes),(function(){a.removeChild(this)}))),R(s)&&(o=i(r),i.each(s,(function(t,e){b.indexOf(t)>-1?o[t](e):o.attr(t,e)}))),r},O.Z=function(t,e){return new Q(t,e)},O.isZ=function(t){return t instanceof O.Z},O.init=function(t,n){var s;if(!t)return O.Z();if("string"==typeof t)if("<"==(t=t.trim())[0]&&g.test(t))s=O.fragment(t,RegExp.$1,n),t=null;else{if(n!==e)return i(n).find(t);s=O.qsa(h,t)}else{if(P(t))return i(h).ready(t);if(O.isZ(t))return t;if(k(t))s=V(t);else if(F(t))s=[t],t=null;else if(g.test(t))s=O.fragment(t.trim(),RegExp.$1,n),t=null;else{if(n!==e)return i(n).find(t);s=O.qsa(h,t)}}return O.Z(s,t)},(i=function(t,e){return O.init(t,e)}).extend=function(t){var e,n=l.call(arguments,1);return"boolean"==typeof t&&(e=t,t=n.shift()),n.forEach((function(n){W(t,n,e)})),t},O.qsa=function(t,e){var n,i="#"==e[0],s=!i&&"."==e[0],r=i||s?e.slice(1):e,o=A.test(r);return t.getElementById&&o&&i?(n=t.getElementById(r))?[n]:[]:1!==t.nodeType&&9!==t.nodeType&&11!==t.nodeType?[]:l.call(o&&!i&&t.getElementsByClassName?s?t.getElementsByClassName(r):t.getElementsByTagName(e):t.querySelectorAll(e))},i.contains=h.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},i.type=I,i.isFunction=P,i.isWindow=L,i.isArray=k,i.isPlainObject=R,i.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},i.isNumeric=function(t){var e=Number(t),n=typeof t;return null!=t&&"boolean"!=n&&("string"!=n||t.length)&&!isNaN(e)&&isFinite(e)||!1},i.inArray=function(t,e,n){return a.indexOf.call(e,t,n)},i.camelCase=r,i.trim=function(t){return null==t?"":String.prototype.trim.call(t)},i.uuid=0,i.support={},i.expr={},i.noop=function(){},i.map=function(t,e){var n,i,s,r=[];if(q(t))for(i=0;i<t.length;i++)null!=(n=e(t[i],i))&&r.push(n);else for(s in t)null!=(n=e(t[s],s))&&r.push(n);return H(r)},i.each=function(t,e){var n,i;if(q(t)){for(n=0;n<t.length;n++)if(!1===e.call(t[n],n,t[n]))return t}else for(i in t)if(!1===e.call(t[i],i,t[i]))return t;return t},i.grep=function(t,e){return c.call(t,e)},t.JSON&&(i.parseJSON=JSON.parse),i.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),(function(t,e){$["[object "+e+"]"]=e.toLowerCase()})),i.fn={constructor:O.Z,length:0,forEach:a.forEach,reduce:a.reduce,push:a.push,sort:a.sort,splice:a.splice,indexOf:a.indexOf,concat:function(){var t,e,n=[];for(t=0;t<arguments.length;t++)e=arguments[t],n[t]=O.isZ(e)?e.toArray():e;return u.apply(O.isZ(this)?this.toArray():this,n)},map:function(t){return i(i.map(this,(function(e,n){return t.call(e,n,e)})))},slice:function(){return i(l.apply(this,arguments))},ready:function(t){return E.test(h.readyState)&&h.body?t(i):h.addEventListener("DOMContentLoaded",(function(){t(i)}),!1),this},get:function(t){return t===e?l.call(this):this[t>=0?t:t+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each((function(){null!=this.parentNode&&this.parentNode.removeChild(this)}))},each:function(t){return a.every.call(this,(function(e,n){return!1!==t.call(e,n,e)})),this},filter:function(t){return P(t)?this.not(this.not(t)):i(c.call(this,(function(e){return O.matches(e,t)})))},add:function(t,e){return i(o(this.concat(i(t,e))))},is:function(t){return this.length>0&&O.matches(this[0],t)},not:function(t){var n=[];if(P(t)&&t.call!==e)this.each((function(e){t.call(this,e)||n.push(this)}));else{var s="string"==typeof t?this.filter(t):q(t)&&P(t.item)?l.call(t):i(t);this.forEach((function(t){s.indexOf(t)<0&&n.push(t)}))}return i(n)},has:function(t){return this.filter((function(){return F(t)?i.contains(this,t):i(this).find(t).size()}))},eq:function(t){return-1===t?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!F(t)?t:i(t)},last:function(){var t=this[this.length-1];return t&&!F(t)?t:i(t)},find:function(t){var e=this;return t?"object"==typeof t?i(t).filter((function(){var t=this;return a.some.call(e,(function(e){return i.contains(e,t)}))})):1==this.length?i(O.qsa(this[0],t)):this.map((function(){return O.qsa(this,t)})):i()},closest:function(t,e){var n=[],s="object"==typeof t&&i(t);return this.each((function(i,r){for(;r&&!(s?s.indexOf(r)>=0:O.matches(r,t));)r=r!==e&&!M(r)&&r.parentNode;r&&n.indexOf(r)<0&&n.push(r)})),i(n)},parents:function(t){for(var e=[],n=this;n.length>0;)n=i.map(n,(function(t){if((t=t.parentNode)&&!M(t)&&e.indexOf(t)<0)return e.push(t),t}));return Z(e,t)},parent:function(t){return Z(o(this.pluck("parentNode")),t)},children:function(t){return Z(this.map((function(){return U(this)})),t)},contents:function(){return this.map((function(){return this.contentDocument||l.call(this.childNodes)}))},siblings:function(t){return Z(this.map((function(t,e){return c.call(U(e.parentNode),(function(t){return t!==e}))})),t)},empty:function(){return this.each((function(){this.innerHTML=""}))},pluck:function(t){return i.map(this,(function(e){return e[t]}))},show:function(){return this.each((function(){"none"==this.style.display&&(this.style.display=""),"none"==getComputedStyle(this,"").getPropertyValue("display")&&(this.style.display=z(this.nodeName))}))},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var e=P(t);if(this[0]&&!e)var n=i(t).get(0),s=n.parentNode||this.length>1;return this.each((function(r){i(this).wrapAll(e?t.call(this,r):s?n.cloneNode(!0):n)}))},wrapAll:function(t){if(this[0]){var e;for(i(this[0]).before(t=i(t));(e=t.children()).length;)t=e.first();i(t).append(this)}return this},wrapInner:function(t){var e=P(t);return this.each((function(n){var s=i(this),r=s.contents(),o=e?t.call(this,n):t;r.length?r.wrapAll(o):s.append(o)}))},unwrap:function(){return this.parent().each((function(){i(this).replaceWith(i(this).children())})),this},clone:function(){return this.map((function(){return this.cloneNode(!0)}))},hide:function(){return this.css("display","none")},toggle:function(t){return this.each((function(){var n=i(this);(t===e?"none"==n.css("display"):t)?n.show():n.hide()}))},prev:function(t){return i(this.pluck("previousElementSibling")).filter(t||"*")},next:function(t){return i(this.pluck("nextElementSibling")).filter(t||"*")},html:function(t){return 0 in arguments?this.each((function(e){var n=this.innerHTML;i(this).empty().append(X(this,t,e,n))})):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each((function(e){var n=X(this,t,e,this.textContent);this.textContent=null==n?"":""+n})):0 in this?this.pluck("textContent").join(""):null},attr:function(t,i){var s;return"string"!=typeof t||1 in arguments?this.each((function(e){if(1===this.nodeType)if(F(t))for(n in t)G(this,n,t[n]);else G(this,t,X(this,i,e,this.getAttribute(t)))})):0 in this&&1==this[0].nodeType&&null!=(s=this[0].getAttribute(t))?s:e},removeAttr:function(t){return this.each((function(){1===this.nodeType&&t.split(" ").forEach((function(t){G(this,t)}),this)}))},prop:function(t,e){return t=N[t]||t,1 in arguments?this.each((function(n){this[t]=X(this,e,n,this[t])})):this[0]&&this[0][t]},removeProp:function(t){return t=N[t]||t,this.each((function(){delete this[t]}))},data:function(t,n){var i="data-"+t.replace(w,"-$1").toLowerCase(),s=1 in arguments?this.attr(i,n):this.attr(i);return null!==s?Y(s):e},val:function(t){return 0 in arguments?(null==t&&(t=""),this.each((function(e){this.value=X(this,t,e,this.value)}))):this[0]&&(this[0].multiple?i(this[0]).find("option").filter((function(){return this.selected})).pluck("value"):this[0].value)},offset:function(e){if(e)return this.each((function(t){var n=i(this),s=X(this,e,t,n.offset()),r=n.offsetParent().offset(),o={top:s.top-r.top,left:s.left-r.left};"static"==n.css("position")&&(o.position="relative"),n.css(o)}));if(!this.length)return null;if(h.documentElement!==this[0]&&!i.contains(h.documentElement,this[0]))return{top:0,left:0};var n=this[0].getBoundingClientRect();return{left:n.left+t.pageXOffset,top:n.top+t.pageYOffset,width:Math.round(n.width),height:Math.round(n.height)}},css:function(t,e){if(arguments.length<2){var s=this[0];if("string"==typeof t){if(!s)return;return s.style[r(t)]||getComputedStyle(s,"").getPropertyValue(t)}if(k(t)){if(!s)return;var o={},a=getComputedStyle(s,"");return i.each(t,(function(t,e){o[e]=s.style[r(e)]||a.getPropertyValue(e)})),o}}var u="";if("string"==I(t))e||0===e?u=B(t)+":"+j(t,e):this.each((function(){this.style.removeProperty(B(t))}));else for(n in t)t[n]||0===t[n]?u+=B(n)+":"+j(n,t[n])+";":this.each((function(){this.style.removeProperty(B(n))}));return this.each((function(){this.style.cssText+=";"+u}))},index:function(t){return t?this.indexOf(i(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return!!t&&a.some.call(this,(function(t){return this.test(J(t))}),K(t))},addClass:function(t){return t?this.each((function(e){if("className"in this){s=[];var n=J(this);X(this,t,e,n).split(/\s+/g).forEach((function(t){i(this).hasClass(t)||s.push(t)}),this),s.length&&J(this,n+(n?" ":"")+s.join(" "))}})):this},removeClass:function(t){return this.each((function(n){if("className"in this){if(t===e)return J(this,"");s=J(this),X(this,t,n,s).split(/\s+/g).forEach((function(t){s=s.replace(K(t)," ")})),J(this,s.trim())}}))},toggleClass:function(t,n){return t?this.each((function(s){var r=i(this);X(this,t,s,J(this)).split(/\s+/g).forEach((function(t){(n===e?!r.hasClass(t):n)?r.addClass(t):r.removeClass(t)}))})):this},scrollTop:function(t){if(this.length){var n="scrollTop"in this[0];return t===e?n?this[0].scrollTop:this[0].pageYOffset:this.each(n?function(){this.scrollTop=t}:function(){this.scrollTo(this.scrollX,t)})}},scrollLeft:function(t){if(this.length){var n="scrollLeft"in this[0];return t===e?n?this[0].scrollLeft:this[0].pageXOffset:this.each(n?function(){this.scrollLeft=t}:function(){this.scrollTo(t,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),n=this.offset(),s=y.test(e[0].nodeName)?{top:0,left:0}:e.offset();return n.top-=parseFloat(i(t).css("margin-top"))||0,n.left-=parseFloat(i(t).css("margin-left"))||0,s.top+=parseFloat(i(e[0]).css("border-top-width"))||0,s.left+=parseFloat(i(e[0]).css("border-left-width"))||0,{top:n.top-s.top,left:n.left-s.left}}},offsetParent:function(){return this.map((function(){for(var t=this.offsetParent||h.body;t&&!y.test(t.nodeName)&&"static"==i(t).css("position");)t=t.offsetParent;return t}))}},i.fn.detach=i.fn.remove,["width","height"].forEach((function(t){var n=t.replace(/./,(function(t){return t[0].toUpperCase()}));i.fn[t]=function(s){var r,o=this[0];return s===e?L(o)?o["inner"+n]:M(o)?o.documentElement["scroll"+n]:(r=this.offset())&&r[t]:this.each((function(e){(o=i(this)).css(t,X(this,s,e,o[t]()))}))}})),C.forEach((function(n,s){var r=s%2;i.fn[n]=function(){var n,o,a=i.map(arguments,(function(t){var s=[];return"array"==(n=I(t))?(t.forEach((function(t){return t.nodeType!==e?s.push(t):i.zepto.isZ(t)?s=s.concat(t.get()):void(s=s.concat(O.fragment(t)))})),s):"object"==n||null==t?t:O.fragment(t)})),u=this.length>1;return a.length<1?this:this.each((function(e,n){o=r?n:n.parentNode,n=0==s?n.nextSibling:1==s?n.firstChild:2==s?n:null;var c=i.contains(h.documentElement,o);a.forEach((function(e){if(u)e=e.cloneNode(!0);else if(!o)return i(e).remove();o.insertBefore(e,n),c&&tt(e,(function(e){if(!(null==e.nodeName||"SCRIPT"!==e.nodeName.toUpperCase()||e.type&&"text/javascript"!==e.type||e.src)){var n=e.ownerDocument?e.ownerDocument.defaultView:t;n.eval.call(n,e.innerHTML)}}))}))}))},i.fn[r?n+"To":"insert"+(s?"Before":"After")]=function(t){return i(t)[n](this),this}})),O.Z.prototype=Q.prototype=i.fn,O.uniq=o,O.deserializeValue=Y,i.zepto=O,i}();return function(e){var n,i=1,s=Array.prototype.slice,r=e.isFunction,o=function(t){return"string"==typeof t},a={},u={},c="onfocusin"in t,l={focus:"focusin",blur:"focusout"},h={mouseenter:"mouseover",mouseleave:"mouseout"};function p(t){return t._zid||(t._zid=i++)}function f(t,e,n,i){if((e=d(e)).ns)var s=g(e.ns);return(a[p(t)]||[]).filter((function(t){return t&&(!e.e||t.e==e.e)&&(!e.ns||s.test(t.ns))&&(!n||p(t.fn)===p(n))&&(!i||t.sel==i)}))}function d(t){var e=(""+t).split(".");return{e:e[0],ns:e.slice(1).sort().join(" ")}}function g(t){return new RegExp("(?:^| )"+t.replace(" "," .* ?")+"(?: |$)")}function m(t,e){return t.del&&!c&&t.e in l||!!e}function v(t){return h[t]||c&&l[t]||t}function y(t,i,s,r,o,u,c){var l=p(t),f=a[l]||(a[l]=[]);i.split(/\s/).forEach((function(i){if("ready"==i)return e(document).ready(s);var a=d(i);a.fn=s,a.sel=o,a.e in h&&(s=function(t){var n=t.relatedTarget;if(!n||n!==this&&!e.contains(this,n))return a.fn.apply(this,arguments)}),a.del=u;var l=u||s;a.proxy=function(e){if(!(e=S(e)).isImmediatePropagationStopped()){try{var i=Object.getOwnPropertyDescriptor(e,"data");i&&!i.writable||(e.data=r)}catch(e){}var s=l.apply(t,e._args==n?[e]:[e].concat(e._args));return!1===s&&(e.preventDefault(),e.stopPropagation()),s}},a.i=f.length,f.push(a),"addEventListener"in t&&t.addEventListener(v(a.e),a.proxy,m(a,c))}))}function w(t,e,n,i,s){var r=p(t);(e||"").split(/\s/).forEach((function(e){f(t,e,n,i).forEach((function(e){delete a[r][e.i],"removeEventListener"in t&&t.removeEventListener(v(e.e),e.proxy,m(e,s))}))}))}u.click=u.mousedown=u.mouseup=u.mousemove="MouseEvents",e.event={add:y,remove:w},e.proxy=function(t,n){var i=2 in arguments&&s.call(arguments,2);if(r(t)){var a=function(){return t.apply(n,i?i.concat(s.call(arguments)):arguments)};return a._zid=p(t),a}if(o(n))return i?(i.unshift(t[n],t),e.proxy.apply(null,i)):e.proxy(t[n],t);throw new TypeError("expected function")},e.fn.bind=function(t,e,n){return this.on(t,e,n)},e.fn.unbind=function(t,e){return this.off(t,e)},e.fn.one=function(t,e,n,i){return this.on(t,e,n,i,1)};var b=function(){return!0},C=function(){return!1},x=/^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/,_={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};function S(t,i){if(i||!t.isDefaultPrevented){i||(i=t),e.each(_,(function(e,n){var s=i[e];t[e]=function(){return this[n]=b,s&&s.apply(i,arguments)},t[n]=C}));try{t.timeStamp||(t.timeStamp=Date.now())}catch(s){}(i.defaultPrevented!==n?i.defaultPrevented:"returnValue"in i?!1===i.returnValue:i.getPreventDefault&&i.getPreventDefault())&&(t.isDefaultPrevented=b)}return t}function E(t){var e,i={originalEvent:t};for(e in t)x.test(e)||t[e]===n||(i[e]=t[e]);return S(i,t)}e.fn.delegate=function(t,e,n){return this.on(e,t,n)},e.fn.undelegate=function(t,e,n){return this.off(e,t,n)},e.fn.live=function(t,n){return e(document.body).delegate(this.selector,t,n),this},e.fn.die=function(t,n){return e(document.body).undelegate(this.selector,t,n),this},e.fn.on=function(t,i,a,u,c){var l,h,p=this;return t&&!o(t)?(e.each(t,(function(t,e){p.on(t,i,a,e,c)})),p):(o(i)||r(u)||!1===u||(u=a,a=i,i=n),u!==n&&!1!==a||(u=a,a=n),!1===u&&(u=C),p.each((function(n,r){c&&(l=function(t){return w(r,t.type,u),u.apply(this,arguments)}),i&&(h=function(t){var n,o=e(t.target).closest(i,r).get(0);if(o&&o!==r)return n=e.extend(E(t),{currentTarget:o,liveFired:r}),(l||u).apply(o,[n].concat(s.call(arguments,1)))}),y(r,t,u,a,i,h||l)})))},e.fn.off=function(t,i,s){var a=this;return t&&!o(t)?(e.each(t,(function(t,e){a.off(t,i,e)})),a):(o(i)||r(s)||!1===s||(s=i,i=n),!1===s&&(s=C),a.each((function(){w(this,t,s,i)})))},e.fn.trigger=function(t,n){return(t=o(t)||e.isPlainObject(t)?e.Event(t):S(t))._args=n,this.each((function(){t.type in l&&"function"==typeof this[t.type]?this[t.type]():"dispatchEvent"in this?this.dispatchEvent(t):e(this).triggerHandler(t,n)}))},e.fn.triggerHandler=function(t,n){var i,s;return this.each((function(r,a){(i=E(o(t)?e.Event(t):t))._args=n,i.target=a,e.each(f(a,t.type||t),(function(t,e){if(s=e.proxy(i),i.isImmediatePropagationStopped())return!1}))})),s},"focusin focusout focus blur load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach((function(t){e.fn[t]=function(e){return 0 in arguments?this.bind(t,e):this.trigger(t)}})),e.Event=function(t,e){o(t)||(t=(e=t).type);var n=document.createEvent(u[t]||"Events"),i=!0;if(e)for(var s in e)"bubbles"==s?i=!!e[s]:n[s]=e[s];return n.initEvent(t,i,!0),S(n)}}(i),n=[],i.fn.remove=function(){return this.each((function(){this.parentNode&&("IMG"===this.tagName&&(n.push(this),this.src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=",e&&clearTimeout(e),e=setTimeout((function(){n=[]}),6e4)),this.parentNode.removeChild(this))}))},function(t){var e={},n=t.fn.data,i=t.camelCase,s=t.expando="Zepto"+ +new Date,r=[];function o(r,o){var u=r[s],c=u&&e[u];if(void 0===o)return c||a(r);if(c){if(o in c)return c[o];var l=i(o);if(l in c)return c[l]}return n.call(t(r),o)}function a(n,r,o){var a=n[s]||(n[s]=++t.uuid),c=e[a]||(e[a]=u(n));return void 0!==r&&(c[i(r)]=o),c}function u(e){var n={};return t.each(e.attributes||r,(function(e,s){0==s.name.indexOf("data-")&&(n[i(s.name.replace("data-",""))]=t.zepto.deserializeValue(s.value))})),n}t.fn.data=function(e,n){return void 0===n?t.isPlainObject(e)?this.each((function(n,i){t.each(e,(function(t,e){a(i,t,e)}))})):0 in this?o(this[0],e):void 0:this.each((function(){a(this,e,n)}))},t.data=function(e,n,i){return t(e).data(n,i)},t.hasData=function(n){var i=n[s],r=i&&e[i];return!!r&&!t.isEmptyObject(r)},t.fn.removeData=function(n){return"string"==typeof n&&(n=n.split(/\s+/)),this.each((function(){var r=this[s],o=r&&e[r];o&&t.each(n||o,(function(t){delete o[n?i(this):t]}))}))},["remove","empty"].forEach((function(e){var n=t.fn[e];t.fn[e]=function(){var t=this.find("*");return"remove"===e&&(t=t.add(this)),t.removeData(),n.call(this)}}))}(i),i}(e)},68937:t=>{"use strict";var e={}.hasOwnProperty,n=/[ -,\.\/:-@\[-\^`\{-~]/,i=/[ -,\.\/:-@\[\]\^`\{-~]/,s=/(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g,r=function t(r,o){"single"!=(o=function(t,n){if(!t)return n;var i={};for(var s in n)i[s]=e.call(t,s)?t[s]:n[s];return i}(o,t.options)).quotes&&"double"!=o.quotes&&(o.quotes="single");for(var a="double"==o.quotes?'"':"'",u=o.isIdentifier,c=r.charAt(0),l="",h=0,p=r.length;h<p;){var f=r.charAt(h++),d=f.charCodeAt(),g=void 0;if(d<32||d>126){if(d>=55296&&d<=56319&&h<p){var m=r.charCodeAt(h++);56320==(64512&m)?d=((1023&d)<<10)+(1023&m)+65536:h--}g="\\"+d.toString(16).toUpperCase()+" "}else g=o.escapeEverything?n.test(f)?"\\"+f:"\\"+d.toString(16).toUpperCase()+" ":/[\t\n\f\r\x0B]/.test(f)?"\\"+d.toString(16).toUpperCase()+" ":"\\"==f||!u&&('"'==f&&a==f||"'"==f&&a==f)||u&&i.test(f)?"\\"+f:f;l+=g}return u&&(/^-[-\d]/.test(l)?l="\\-"+l.slice(1):/\d/.test(c)&&(l="\\3"+c+" "+l.slice(1))),l=l.replace(s,(function(t,e,n){return e&&e.length%2?t:(e||"")+n})),!u&&o.wrap?a+l+a:l};r.options={escapeEverything:!1,isIdentifier:!1,quotes:"single",wrap:!1},r.version="3.0.0",t.exports=r},90874:(t,e,n)=>{"use strict";var i,s,r,o=[n(45741),n(91856),n(41015),n(16486),n(45723),n(26345)],a=-1,u=[],c=!1;function l(){i&&s&&(i=!1,s.length?u=s.concat(u):a=-1,u.length&&h())}function h(){if(!i){c=!1,i=!0;for(var t=u.length,e=setTimeout(l);t;){for(s=u,u=[];s&&++a<t;)s[a].run();a=-1,t=u.length}s=null,a=-1,i=!1,clearTimeout(e)}}for(var p=-1,f=o.length;++p<f;)if(o[p]&&o[p].test&&o[p].test()){r=o[p].install(h);break}function d(t,e){this.fun=t,this.array=e}d.prototype.run=function(){var t=this.fun,e=this.array;switch(e.length){case 0:return t();case 1:return t(e[0]);case 2:return t(e[0],e[1]);case 3:return t(e[0],e[1],e[2]);default:return t.apply(null,e)}},t.exports=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];u.push(new d(t,e)),c||i||(c=!0,r())}},16486:(t,e,n)=>{"use strict";e.test=function(){return!n.g.setImmediate&&void 0!==n.g.MessageChannel},e.install=function(t){var e=new n.g.MessageChannel;return e.port1.onmessage=t,function(){e.port2.postMessage(0)}}},41015:(t,e,n)=>{"use strict";var i=n.g.MutationObserver||n.g.WebKitMutationObserver;e.test=function(){return i},e.install=function(t){var e=0,s=new i(t),r=n.g.document.createTextNode("");return s.observe(r,{characterData:!0}),function(){r.data=e=++e%2}}},91856:(t,e,n)=>{"use strict";e.test=function(){return"function"==typeof n.g.queueMicrotask},e.install=function(t){return function(){n.g.queueMicrotask(t)}}},45723:(t,e,n)=>{"use strict";e.test=function(){return"document"in n.g&&"onreadystatechange"in n.g.document.createElement("script")},e.install=function(t){return function(){var e=n.g.document.createElement("script");return e.onreadystatechange=function(){t(),e.onreadystatechange=null,e.parentNode.removeChild(e),e=null},n.g.document.documentElement.appendChild(e),t}}},26345:(t,e)=>{"use strict";e.test=function(){return!0},e.install=function(t){return function(){setTimeout(t,0)}}}}]); \ No newline at end of file diff --git a/assets/js/489.79124cfe.js.LICENSE.txt b/assets/js/489.79124cfe.js.LICENSE.txt new file mode 100644 index 0000000000..4f7ccd8a76 --- /dev/null +++ b/assets/js/489.79124cfe.js.LICENSE.txt @@ -0,0 +1 @@ +/*! https://mths.be/cssesc v3.0.0 by @mathias */ diff --git a/assets/js/49993131.9f0a6e53.js b/assets/js/49993131.9f0a6e53.js new file mode 100644 index 0000000000..cb9e78562b --- /dev/null +++ b/assets/js/49993131.9f0a6e53.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8460],{3681:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var t=s(74848),i=s(28453);const r={sidebar_label:"Releases",sidebar_position:10},o="Releases",a={id:"iaas/guides/other-guides/developer-guide/releases",title:"Releases",description:"How we handle releases",source:"@site/docs/02-iaas/guides/other-guides/developer-guide/releases.md",sourceDirName:"02-iaas/guides/other-guides/developer-guide",slug:"/iaas/guides/other-guides/developer-guide/releases",permalink:"/docs/iaas/guides/other-guides/developer-guide/releases",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/developer-guide/releases.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Releases",sidebar_position:10},sidebar:"docs",previous:{title:"Developer Guide",permalink:"/docs/iaas/guides/other-guides/developer-guide/"},next:{title:"Scripts",permalink:"/docs/iaas/guides/other-guides/developer-guide/scripts"}},l={},d=[{value:"How we handle releases",id:"how-we-handle-releases",level:2},{value:"How to make a release",id:"how-to-make-a-release",level:2},{value:"Stable release",id:"stable-release",level:3},{value:"How we write release notes",id:"how-we-write-release-notes",level:2},{value:"Installation",id:"installation",level:3},{value:"Usage",id:"usage",level:3},{value:"Example",id:"example",level:3},{value:"Repositories without release notes",id:"repositories-without-release-notes",level:3}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"releases",children:"Releases"}),"\n",(0,t.jsx)(n.h2,{id:"how-we-handle-releases",children:"How we handle releases"}),"\n",(0,t.jsx)(n.p,{children:"Currently we do a major release every 6 months. Minor releases we do when\nneeded and about every 2 weeks."}),"\n",(0,t.jsx)(n.p,{children:"In a minor release, only updates, bug fixes, etc. take place. There are also\nno major upgrades of included components such as OpenStack, Keycloak or Ceph\nin a minor release."}),"\n",(0,t.jsx)(n.p,{children:"It is possible to jump from any minor version within a major version to higher\nminor versions without any intervention."}),"\n",(0,t.jsx)(n.p,{children:"Deprecations, removals, etc. take place in a major release. New mandatory\nfeatures are also added in a major release. Upgrades of the included components\ncan also take place during a major release (e.g. OpenStack Xena -> OpenStack Yoga)."}),"\n",(0,t.jsx)(n.p,{children:"It is possible to jump from the previous major version to the next major version.\nIt may be that manual intervention is necessary. For example, configuration\nparameters may need to be added or services that no longer exist may need to be\nremoved."}),"\n",(0,t.jsx)(n.h2,{id:"how-to-make-a-release",children:"How to make a release"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["On all repositories that are used, check that the versions to be used have an\nappropriate version tag (e.g. ",(0,t.jsx)(n.code,{children:"v0.20230308.0"}),")."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism/ansible-collection-commons\nosism/ansible-collection-services\nosism/ansible-collection-validations\nosism/ansible-defaults\nosism/ansible-playbooks\nosism/ansible-playbooks-manager\nosism/cf-generics\nosism/kolla-operations\nosism/python-osism\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Copy the ",(0,t.jsx)(n.code,{children:"latest"})," directory. The release to be created is used as the new name."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"latest -> 6.0.0b\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Remove all ",(0,t.jsx)(n.code,{children:"# renovate"})," lines from the ",(0,t.jsx)(n.code,{children:"base.yml"})," file."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Remove all Ceph and OpenStack releases that should not be part of the pre-release.\nThere is only one OpenStack version and one Ceph version per (pre-)release."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Ensure that the symlinks ",(0,t.jsx)(n.code,{children:"openstack.yml"})," and ",(0,t.jsx)(n.code,{children:"ceph.yml"})," point to the releases\nto be used in this pre-release."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"base.yml\nceph-pacific.yml\nceph.yml -> ceph-pacific.yml\nopenstack-zed.yml\nopenstack.yml -> openstack-zed.yml\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Run ",(0,t.jsx)(n.code,{children:"src/prepare-release.py"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"RELEASE=6.0.0b python3 src/prepare-release.py\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Do the steps from the ",(0,t.jsx)(n.code,{children:"Stable release"})," starting from the 4th step."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"stable-release",children:"Stable release"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Copy the directory of the last pre-release or the previous stable release.\nThe release to be created is used as the new name."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"5.0.0a -> 5.0.0b\n5.0.0b -> 5.0.0\n5.0.0 -> 5.1.0\n5.1.0 -> 5.2.0\n5.2.0 -> 5.3.0\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Change all necessary versions in the YAML files within the new directory.\nIn any case, the version of the pre-release or the version of the stable\nrelease must be replaced by the release to be created."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"The release to be created is submitted as a pull request as usual and then\nmerged."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Add a tag with the name of the new release to the listed repositories."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism/container-image-ceph-ansible\nosism/container-image-inventory-reconciler\nosism/container-image-osism-ansible\nosism/container-images-kolla\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["After completing the creation of the images in repository ",(0,t.jsx)(n.code,{children:"container-images-kolla"}),",\nthe file ",(0,t.jsx)(n.code,{children:"images.yml"})," must be added to repository ",(0,t.jsx)(n.code,{children:"osism/sbom"})," as\n",(0,t.jsx)(n.code,{children:"5.0.0/openstack.yml"})," (instead of ",(0,t.jsx)(n.code,{children:"5.0.0"}),", the corresponding release is used).\nThe file is available as a build artefact of the ",(0,t.jsx)(n.code,{children:"Release container images"})," action\non the created tag."]}),"\n",(0,t.jsxs)(n.p,{children:["Before the file is added, it is enhanced with the checksums of the images. The script\nis available in the ",(0,t.jsx)(n.code,{children:"osism/sbom"})," repository."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"VERSION=5.0.0 python3 scripts/add-image-checksum.py\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["If ",(0,t.jsx)(n.code,{children:"5.0.0/openstack.yml"})," is present in ",(0,t.jsx)(n.code,{children:"osism/sbom"}),", repository\n",(0,t.jsx)(n.code,{children:"osism/container-image-kolla-ansible"})," can be tagged like the other\nrepositories before."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Add the created SPDX files from the listed repositories to the ",(0,t.jsx)(n.code,{children:"osism/sbom"})," repository.\nThe file are available as build artefacts of the ",(0,t.jsx)(n.code,{children:"Build container image"})," action\non the created tags."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism/container-image-ceph-ansible\nosism/container-image-kolla-ansible\nosism/container-image-osism-ansible\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Add and run temporary CI jobs in ",(0,t.jsx)(n.code,{children:"osism/testbed"})," that uses the pre-release."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'- job:\n name: testbed-deploy-stable-next\n parent: testbed-deploy\n vars:\n manager_version: "5.0.0a"\n refstack: true\n nodeset: testbed-orchestrator\n\n- job:\n name: testbed-upgrade-stable-next\n parent: testbed-deploy\n vars:\n manager_version: "4.2.0"\n manager_version_next: "5.0.0a"\n nodeset: testbed-orchestrator\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Test. Test. Test."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Prepare a PR to change the stable version to the new stable version in the following Zuul jobs\nin the ",(0,t.jsx)(n.code,{children:"osism/testbed"})," repository. All tests there must pass successfully before the tag is\nset on this repository in the next step. The temporary CI jobs (step 8) are removed again with\nthis PR."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"testbed-deploy-stable\ntestbed-update-stable\ntestbed-update-stable\ntestbed-upgrade-stable\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Add a new release notes file to ",(0,t.jsx)(n.code,{children:"doc/sorce/notes"}),". Generate the versions table with the\nhelp of the ",(0,t.jsx)(n.code,{children:"release-table.py"})," script in the ",(0,t.jsx)(n.code,{children:"osism/sbom"})," repository."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["After all known issues are documented, a corresponding tag, e.g. ",(0,t.jsx)(n.code,{children:"5.0.0"}),", is set on the\n",(0,t.jsx)(n.a,{href:"https://github.com/osism/release/releases",children:"osism/release"})," repository."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Create a ",(0,t.jsx)(n.a,{href:"https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository",children:"GitHub release"})," with the new tag on the\n",(0,t.jsx)(n.a,{href:"https://github.com/osism/release/releases",children:"osism/release"})," repository. The release is\nnow public available."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["As the last of the release process, the previously prepared PR is merged on the\n",(0,t.jsx)(n.code,{children:"osism/testbed"})," repository to change the stable version."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"how-we-write-release-notes",children:"How we write release notes"}),"\n",(0,t.jsxs)(n.p,{children:["We use ",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/reno/latest/",children:"Reno"})," to manage the release notes."]}),"\n",(0,t.jsx)(n.h3,{id:"installation",children:"Installation"}),"\n",(0,t.jsxs)(n.p,{children:["Reno is provided as a ",(0,t.jsx)(n.a,{href:"https://pypi.org/project/reno/",children:"Python package"})," and can be installed with pip."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"pip3 install reno\n"})}),"\n",(0,t.jsx)(n.h3,{id:"usage",children:"Usage"}),"\n",(0,t.jsxs)(n.p,{children:["For each change in a repository, a release note is created with Reno.\nSomething meaningful is used as the name for the note. For example, if the\nrequirements file for Ansible is removed, ",(0,t.jsx)(n.code,{children:"remove-ansible-requirements"})," is a good name."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ reno new remove-ansible-requirements\nno configuration file in: ./releasenotes/config.yaml, ./reno.yaml\nCreated new notes file in releasenotes/notes/remove-ansible-requirements-6c6eba43f616bc6b.yaml\n"})}),"\n",(0,t.jsx)(n.p,{children:"The created file contains prepared entries for several categories. It is described briefly\nin each instance which contents belong in which category. What is not needed is deleted."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"prelude: >\n Replace this text with content to appear at the top of the section for this\n release. All of the prelude content is merged together and then rendered\n separately from the items listed in other parts of the file, so the text\n needs to be worded so that both the prelude and the other items make sense\n when read independently. This may mean repeating some details. Not every\n release note requires a prelude. Usually only notes describing major\n features or adding release theme details should have a prelude.\nfeatures:\n - |\n List new features here, or remove this section. All of the list items in\n this section are combined when the release notes are rendered, so the text\n needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\nissues:\n - |\n List known issues here, or remove this section. All of the list items in\n this section are combined when the release notes are rendered, so the text\n needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\nupgrade:\n - |\n List upgrade notes here, or remove this section. All of the list items in\n this section are combined when the release notes are rendered, so the text\n needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\ndeprecations:\n - |\n List deprecations notes here, or remove this section. All of the list\n items in this section are combined when the release notes are rendered, so\n the text needs to be worded so that it does not depend on any information\n only available in another section, such as the prelude. This may mean\n repeating some details.\ncritical:\n - |\n Add critical notes here, or remove this section. All of the list items in\n this section are combined when the release notes are rendered, so the text\n needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\nsecurity:\n - |\n Add security notes here, or remove this section. All of the list items in\n this section are combined when the release notes are rendered, so the text\n needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\nfixes:\n - |\n Add normal bug fixes here, or remove this section. All of the list items\n in this section are combined when the release notes are rendered, so the\n text needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\nother:\n - |\n Add other notes here, or remove this section. All of the list items in\n this section are combined when the release notes are rendered, so the text\n needs to be worded so that it does not depend on any information only\n available in another section, such as the prelude. This may mean repeating\n some details.\n"})}),"\n",(0,t.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,t.jsxs)(n.p,{children:["Here is an example of a ",(0,t.jsx)(n.a,{href:"https://github.com/osism/cfg-generics/commit/e2f04a9f4a51eb058446d7a8ab6835df53989099",children:"commit from the osism/cfg-generics repository"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"---\nfeatures:\n - |\n The `requirements.yml` has been removed. The version will be set in the `run.sh`\n script for the seed process in the future exactly as later in the update process\n via the parameters `ANSIBLE_COLLECTION_SERVICES_VERSION` and\n `ANSIBLE_PLAYBOOKS_MANAGER_VERSION`.\nupgrade:\n - |\n In existing configuration repositories, the `environments/manager/requirements.yml`\n file can be removed after the generics have been synced.\n"})}),"\n",(0,t.jsx)(n.h3,{id:"repositories-without-release-notes",children:"Repositories without release notes"}),"\n",(0,t.jsx)(n.p,{children:"We do not create release notes in the following repositories:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"osism/github-manager"}),"\n",(0,t.jsx)(n.li,{children:"osism/osism.github.io"}),"\n",(0,t.jsx)(n.li,{children:"osism/release"}),"\n"]})]})}function c(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const i={},r=t.createContext(i);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/49bc3785.f3702487.js b/assets/js/49bc3785.f3702487.js new file mode 100644 index 0000000000..83836a80cc --- /dev/null +++ b/assets/js/49bc3785.f3702487.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8592],{47221:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>r,contentTitle:()=>d,default:()=>x,frontMatter:()=>n,metadata:()=>c,toc:()=>h});var l=i(74848),t=i(28453);const n={},d="Hackathon planning checklist",c={id:"hackathons/checklist",title:"Hackathon planning checklist",description:"This checklist is designed to simplify the planning of hackathons and meetups. All items are suggestions and optionally adaptable",source:"@site/community/hackathons/checklist.md",sourceDirName:"hackathons",slug:"/hackathons/checklist",permalink:"/community/hackathons/checklist",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{}},r={},h=[{value:"Checklist 6 months before Hackathon",id:"checklist-6-months-before-hackathon",level:2},{value:"Checklist advertising",id:"checklist-advertising",level:2},{value:"Checklist 5 months before Hackathon",id:"checklist-5-months-before-hackathon",level:2},{value:"Checklist hotel",id:"checklist-hotel",level:2},{value:"Iportant things",id:"iportant-things",level:3},{value:"Nice-to-have things",id:"nice-to-have-things",level:3},{value:"Checklist 4 months before Hackathon",id:"checklist-4-months-before-hackathon",level:2},{value:"Checklist for evening before location",id:"checklist-for-evening-before-location",level:2},{value:"Checklist rooms 1",id:"checklist-rooms-1",level:2},{value:"Checklist merch (examples)",id:"checklist-merch-examples",level:2},{value:"Checklist 3 months before Hackathon",id:"checklist-3-months-before-hackathon",level:2},{value:"Checklist evening event",id:"checklist-evening-event",level:2},{value:"Checklist 2 months before Hackathon",id:"checklist-2-months-before-hackathon",level:2},{value:"Snacks checklist",id:"snacks-checklist",level:2},{value:"Breakfast examples",id:"breakfast-examples",level:3},{value:"Snack exemples",id:"snack-exemples",level:3},{value:"Vegan snack examples",id:"vegan-snack-examples",level:3},{value:"Checklist rooms 2",id:"checklist-rooms-2",level:2},{value:"Checklist 1 month before Hackathon",id:"checklist-1-month-before-hackathon",level:2},{value:"Checklist 1 week before Hackathon",id:"checklist-1-week-before-hackathon",level:2},{value:"Checklist one day before Hackathon",id:"checklist-one-day-before-hackathon",level:2},{value:"Checklist Hackathon Day X",id:"checklist-hackathon-day-x",level:2},{value:"Checklist after Hackathon",id:"checklist-after-hackathon",level:2}];function a(e){const s={h1:"h1",h2:"h2",h3:"h3",input:"input",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.h1,{id:"hackathon-planning-checklist",children:"Hackathon planning checklist"}),"\n",(0,l.jsx)(s.p,{children:"This checklist is designed to simplify the planning of hackathons and meetups. All items are suggestions and optionally adaptable\nto the situation."}),"\n",(0,l.jsx)(s.h2,{id:"checklist-6-months-before-hackathon",children:"Checklist 6 months before Hackathon"}),"\n",(0,l.jsxs)(s.table,{children:[(0,l.jsx)(s.thead,{children:(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.th,{}),(0,l.jsx)(s.th,{children:"Date"}),(0,l.jsx)(s.th,{children:"Task"})]})}),(0,l.jsxs)(s.tbody,{children:[(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Clarify sponsorship"})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Clarify who is responsible for planning. Contact persons of the companies involved. These should then also be present at the hackathon."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Set a specific date."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Clarify responsibilities."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"First advertising in form of advertising in meetings, LinkedIn post, mailing list or similar."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Clarify which advertising measures are required (see checklist advertising)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Determine venue."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Set the theme for the hackathon and apply it to the design."})]})]})]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-advertising",children:"Checklist advertising"}),"\n",(0,l.jsxs)(s.table,{children:[(0,l.jsx)(s.thead,{children:(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.th,{}),(0,l.jsx)(s.th,{children:"Topic"}),(0,l.jsx)(s.th,{children:"Task"})]})}),(0,l.jsxs)(s.tbody,{children:[(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{children:"Social Media"}),(0,l.jsx)(s.td,{children:"Create content plan."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Which accounts/people/companies have to be mentioned as well."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Which persons must agree to a publication."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Should hashtags be used, if yes which ones."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{children:"Newsletter"}),(0,l.jsx)(s.td,{children:"Create content plan with possible content and frequency."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{children:"Website"}),(0,l.jsx)(s.td,{children:"Content plan: Blogposts."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Info landing page."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Registration page."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Special newsletter or just regular."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{children:"Other placements"}),(0,l.jsx)(s.td,{children:"Spread the word in meetings or at other events."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{children:"Media"}),(0,l.jsx)(s.td,{children:"Should be changeable, specify target audience, language, sources."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{children:"Media suggestions"}),(0,l.jsx)(s.td,{children:"Video, images, PDF, texts, merch, graphics. Everything should be planned in advance precisely date, type, releases, scope, size, etc."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{children:"Graphics"}),(0,l.jsx)(s.td,{children:"Set design motto."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{children:"Key metrics"}),(0,l.jsx)(s.td,{children:"Should the success be tracked by key metrics, if so which ones."})]})]})]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-5-months-before-hackathon",children:"Checklist 5 months before Hackathon"}),"\n",(0,l.jsxs)(s.table,{children:[(0,l.jsx)(s.thead,{children:(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.th,{}),(0,l.jsx)(s.th,{children:"Date"}),(0,l.jsx)(s.th,{children:"Task"})]})}),(0,l.jsxs)(s.tbody,{children:[(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Clarify if extra merch is desired and start looking for vendors. Order samples."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Discuss concrete advertising measures."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Check hotels (see checklist hotel)."})]})]})]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-hotel",children:"Checklist hotel"}),"\n",(0,l.jsx)(s.h3,{id:"iportant-things",children:"Iportant things"}),"\n",(0,l.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Availabilities in the period."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Way from the hotel to the hackathon."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Parking at the hotel."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Way from train station to hotel."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Checkin / Checkout times."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Check barrier-free accessibility."]}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"nice-to-have-things",children:"Nice-to-have things"}),"\n",(0,l.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Bar in the hotel, for relaxed sitting together in the evening."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Clarify whether employees from on site are also allowed in the bar."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Clarify whether reservations must be made in the bar, if so, reserve for the evening before."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Possibility of contingent reservation."]}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-4-months-before-hackathon",children:"Checklist 4 months before Hackathon"}),"\n",(0,l.jsxs)(s.table,{children:[(0,l.jsx)(s.thead,{children:(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.th,{}),(0,l.jsx)(s.th,{children:"Date"}),(0,l.jsx)(s.th,{children:"Task"})]})}),(0,l.jsxs)(s.tbody,{children:[(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Determine hotel final and make recommendation. Possibly reserve contingent if the hotel offers it."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Find the location for the evening before (see checklist for evening before location)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Start organizing venue. (See checklist rooms 1)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Roughly plan evening event (consider volume level and space available)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Promotional drumbeat. Social media, website, meetings, newsletter."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Order special merch."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Organize merch in general (see merch checklist)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Start collecting statements that need to be sent around. (Privacy statements, photo statements, data center statements, security statements)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Rough sequence of events to be able to plan more precisely at a later date."})]})]})]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-for-evening-before-location",children:"Checklist for evening before location"}),"\n",(0,l.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Volume level."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Consider food possibilities."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Enough space."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Availability."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","If intermediate change from A to B, then plan and include firmly in the plan."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","If it is necessary to choose two locations because of food, drink, coziness, distance to the hotel: plan both, ask for and book them."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Ask for flexibility in the reservation. If more people come as registered."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Plan times."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Price / performance ratio should fit."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Way from the hotel to the evening before location."]}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-rooms-1",children:"Checklist rooms 1"}),"\n",(0,l.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Space available (Enough space available for: Work area, meet-up area, no-photo area, break room, restrooms?)."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Provisional room plan."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","How long are the rooms available?"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Are there any legal/corporate issues to consider?"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Do declarations need to be signed to enter the premises?"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","List what hackathon relevant equipment is on site and if anything needs to be organized. For example, screens, whiteboards, power sockets if necessary,\ntables, chairs, wi-fi, etc."]}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-merch-examples",children:"Checklist merch (examples)"}),"\n",(0,l.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Ballpens"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Lanyards"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Notepads"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Stickers"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","ID card / name badge covers"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Name badges"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Snacks"]}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-3-months-before-hackathon",children:"Checklist 3 months before Hackathon"}),"\n",(0,l.jsxs)(s.table,{children:[(0,l.jsx)(s.thead,{children:(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.th,{}),(0,l.jsx)(s.th,{children:"Date"}),(0,l.jsx)(s.th,{children:"Task"})]})}),(0,l.jsxs)(s.tbody,{children:[(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Required declarations (photo/video usage rights, data center, premises, etc.) are available as a form. Have a look if you can have"})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"them confirmed with the registration. Otherwise as a circular email to all who register with the registration confirmation. Well"})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"visible. For the photo/video declaration: Give the option of refusing and explain the variant with the no-photo dot."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Promote again: Website, social media, newsletter, meetings, circular email, etc...."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Make reservations for pre-evening event."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Plan evening event and reserve location / tables (see checklist evening event)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Create a provisional schedule."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Eventually invite people separately. (Special guests)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Schedule start time and arrival time. Allow enough time for everyone to arrive."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Set presentation time and end time."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Define arrival time evening event. Leave enough time to change, but also do not define too long."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Schedule a fixed cleanup time."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Plan break time."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Activate login page."})]})]})]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-evening-event",children:"Checklist evening event"}),"\n",(0,l.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Volume level (It should be possible to have relaxed conversations)"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Available space"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Price / performance ratio should be suitable"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Check availabilities"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Snacks should be possible"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Request flexibility with reservation (number of participants)"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Actions would be a nice-to-have, everyone has been sitting and working all day, so it's good to have a change."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Way from the hotel to the evening location."]}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-2-months-before-hackathon",children:"Checklist 2 months before Hackathon"}),"\n",(0,l.jsxs)(s.table,{children:[(0,l.jsx)(s.thead,{children:(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.th,{}),(0,l.jsx)(s.th,{children:"Date"}),(0,l.jsx)(s.th,{children:"Task"})]})}),(0,l.jsxs)(s.tbody,{children:[(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Start collecting goals and topics."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Work out goals and topics yourself."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Check results from the checklist rooms 1 again."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Go through checklist rooms 2."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Advertising (social media, mailing list, website, blog post, newsletter, room plan video, etc)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Go through checklists again in general, was anything forgotten?"})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Plan food for the break."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Plan snacks / breakfast (See snacks checklist)."})]})]})]}),"\n",(0,l.jsx)(s.h2,{id:"snacks-checklist",children:"Snacks checklist"}),"\n",(0,l.jsx)(s.h3,{id:"breakfast-examples",children:"Breakfast examples"}),"\n",(0,l.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Sandwiches (rolls)"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Pretzel sandwiches"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Sandwiches (toast)"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Cocktail tomatoes"]}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"snack-exemples",children:"Snack exemples"}),"\n",(0,l.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ",'"Kinder Schokobons"']}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ",'"Kinder Schokoriegel"']}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ",'"Kinder Duplo"']}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Hanuta"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Gummy bears"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Apples"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Bananas"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Nuts"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Grapes"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Dried fruits"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Salted sticks"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Salted pretzels"]}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"vegan-snack-examples",children:"Vegan snack examples"}),"\n",(0,l.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ",'"Katjes Fruchtgummi"']}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ",'"Katjes Lakritz"']}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-rooms-2",children:"Checklist rooms 2"}),"\n",(0,l.jsxs)(s.ul,{className:"contains-task-list",children:["\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Create a room plan for publication. In it, work areas, break areas, no-photo area, meet-up places should be clearly\nvisible. Gladly also again as a video."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","If necessary route map."]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Is wifi available without any problems?"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Where will drinks be located?"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Where to set up snacks?"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Where the food for the break?"]}),"\n",(0,l.jsxs)(s.li,{className:"task-list-item",children:[(0,l.jsx)(s.input,{type:"checkbox",disabled:!0})," ","Are there enough plates, cups, glasses, cutlery, napkins, and bowls for snacks?"]}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-1-month-before-hackathon",children:"Checklist 1 month before Hackathon"}),"\n",(0,l.jsxs)(s.table,{children:[(0,l.jsx)(s.thead,{children:(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.th,{}),(0,l.jsx)(s.th,{children:"Date"}),(0,l.jsx)(s.th,{children:"Task"})]})}),(0,l.jsxs)(s.tbody,{children:[(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Fix and publish the agenda."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Check the declarations once again, has every declaration been send, have any answered yet?"})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Check reservations, expand if necessary."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Check whether all possible special features have been observed (location etc)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Pre-order food for in-between meals and for the lunch break."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Plan drinks, type and quantity (don't forget coffee, tea, milk, sugar)."})]})]})]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-1-week-before-hackathon",children:"Checklist 1 week before Hackathon"}),"\n",(0,l.jsxs)(s.table,{children:[(0,l.jsx)(s.thead,{children:(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.th,{}),(0,l.jsx)(s.th,{children:"Date"}),(0,l.jsx)(s.th,{children:"Task"})]})}),(0,l.jsxs)(s.tbody,{children:[(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Print statements and forms."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Advertise again."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Make a list for the snacks (See for inspiration checklist snacks)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Pre-order the food, if necessary, check whether the quantity still fits with the registrations."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Depending on expand. Firmly plan transport / pickup / delivery."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Create a room plan with the topics, where, when, what takes place."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Organize drinks."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Determine the time when the helpers / organizers meet."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"If necessary create / organize lists and visitor cards."})]})]})]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-one-day-before-hackathon",children:"Checklist one day before Hackathon"}),"\n",(0,l.jsxs)(s.table,{children:[(0,l.jsx)(s.thead,{children:(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.th,{}),(0,l.jsx)(s.th,{children:"Date"}),(0,l.jsx)(s.th,{children:"Task"})]})}),(0,l.jsxs)(s.tbody,{children:[(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Buy snacks."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Contact food supplier again if the delivery date is suitable."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Check technology for functionality."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Send around the room plan with the topics by email."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Prepare rooms if necessary / possible."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Put drinks in the refrigerator."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Provide coffee machine."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Provide dishes."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Label rooms."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Check visitor cards and lists for completeness."})]})]})]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-hackathon-day-x",children:"Checklist Hackathon Day X"}),"\n",(0,l.jsxs)(s.table,{children:[(0,l.jsx)(s.thead,{children:(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.th,{}),(0,l.jsx)(s.th,{children:"Time"}),(0,l.jsx)(s.th,{children:"Task"})]})}),(0,l.jsxs)(s.tbody,{children:[(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Place snacks on the tables in small bowls or similar."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Distribute merchandise."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Have declarations and forms ready for late deciders."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Have lists and visitor cards ready if necessary."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Check drinks in an interval."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Make coffee if necessary."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Provide tea, coffee, milk, sugar."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Provide breakfast / snacks."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Pick up lunch."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:'Lunch "build up"'})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Cleanup"})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Keep an eye on the process (keep times a little bit)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"See if everyone feels picked up, no one is bored."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Makes Photos."})]})]})]}),"\n",(0,l.jsx)(s.h2,{id:"checklist-after-hackathon",children:"Checklist after Hackathon"}),"\n",(0,l.jsxs)(s.table,{children:[(0,l.jsx)(s.thead,{children:(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.th,{}),(0,l.jsx)(s.th,{children:"Date"}),(0,l.jsx)(s.th,{children:"Task"})]})}),(0,l.jsxs)(s.tbody,{children:[(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Collect photos and provide them in a link for review and approval."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Create and send feedback sheet."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Create Blog Post Article."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Eventually create retro video."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Create social media posts. (After all approvals)."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Prepare debriefing."})]}),(0,l.jsxs)(s.tr,{children:[(0,l.jsx)(s.td,{children:(0,l.jsx)("ul",{children:(0,l.jsx)("li",{children:"- [ ] "})})}),(0,l.jsx)(s.td,{}),(0,l.jsx)(s.td,{children:"Summarize and process feedback."})]})]})]})]})}function x(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,l.jsx)(s,{...e,children:(0,l.jsx)(a,{...e})}):a(e)}},28453:(e,s,i)=>{i.d(s,{R:()=>d,x:()=>c});var l=i(96540);const t={},n=l.createContext(t);function d(e){const s=l.useContext(n);return l.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),l.createElement(n.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4a61a7c1.9963015b.js b/assets/js/4a61a7c1.9963015b.js new file mode 100644 index 0000000000..e7266040a2 --- /dev/null +++ b/assets/js/4a61a7c1.9963015b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3705],{83252:(s,t,e)=>{e.r(t),e.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>i});var n=e(74848),o=e(28453);const r={},a="scs-0200: Using Sonobuoy for KaaS conformance tests",c={id:"kaas/scs-0200",title:"scs-0200: Using Sonobuoy for KaaS conformance tests",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/kaas/scs-0200.md",sourceDirName:"kaas",slug:"/kaas/scs-0200",permalink:"/standards/kaas/scs-0200",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"KaaS Standards",permalink:"/standards/kaas/"},next:{title:"Using Sonobuoy for KaaS conformance tests",permalink:"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests"}},d={},i=[];function l(s){const t={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"scs-0200-using-sonobuoy-for-kaas-conformance-tests",children:"scs-0200: Using Sonobuoy for KaaS conformance tests"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests",children:"scs-0200-v1"})}),(0,n.jsx)(t.td,{children:"Decision Record"}),(0,n.jsx)(t.td,{children:"Draft"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function h(s={}){const{wrapper:t}={...(0,o.R)(),...s.components};return t?(0,n.jsx)(t,{...s,children:(0,n.jsx)(l,{...s})}):l(s)}},28453:(s,t,e)=>{e.d(t,{R:()=>a,x:()=>c});var n=e(96540);const o={},r=n.createContext(o);function a(s){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof s?s(t):{...t,...s}}),[t,s])}function c(s){let t;return t=s.disableParentContext?"function"==typeof s.components?s.components(o):s.components||o:a(s.components),n.createElement(r.Provider,{value:t},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/4b015924.270c4b17.js b/assets/js/4b015924.270c4b17.js new file mode 100644 index 0000000000..443d42b4cb --- /dev/null +++ b/assets/js/4b015924.270c4b17.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2076],{76480:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>o,metadata:()=>d,toc:()=>l});var i=s(74848),t=s(28453);const o={sidebar_label:"Network",sidebar_position:15},r="Network",d={id:"iaas/guides/deploy-guide/services/network",title:"Network",description:"1. Open vSwitch (OVS)",source:"@site/docs/02-iaas/guides/deploy-guide/services/network.md",sourceDirName:"02-iaas/guides/deploy-guide/services",slug:"/iaas/guides/deploy-guide/services/network",permalink:"/docs/iaas/guides/deploy-guide/services/network",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/network.md",tags:[],version:"current",sidebarPosition:15,frontMatter:{sidebar_label:"Network",sidebar_position:15},sidebar:"docs",previous:{title:"Kubernetes",permalink:"/docs/iaas/guides/deploy-guide/services/kubernetes"},next:{title:"Logging & Monitoring",permalink:"/docs/iaas/guides/deploy-guide/services/logging-monitoring"}},c={},l=[];function a(e){const n={code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"network",children:"Network"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Open vSwitch (OVS)"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull openvswitch\nosism apply openvswitch\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Open Virtual Network (OVN)"}),"\n",(0,i.jsxs)(n.p,{children:["In ",(0,i.jsx)(n.code,{children:"environments/kolla/configuration.yml"})," the parameter ",(0,i.jsx)(n.code,{children:"neutron_plugin_agent"})," is set to\n",(0,i.jsx)(n.code,{children:"ovn"})," if OVN is used as a network plugin. The parameter is set to ",(0,i.jsx)(n.code,{children:"ovn"})," by default in the\nCookiecutter."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'# neutron\nneutron_plugin_agent: "ovn"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Otherwise the network plugin is set to ",(0,i.jsx)(n.code,{children:"openvswitch"}),".\nIf the ",(0,i.jsx)(n.code,{children:"neutron_plugin_agent"})," is set to ",(0,i.jsx)(n.code,{children:"openvswitch"}),", this step does not need to be done."]}),"\n",(0,i.jsx)(n.p,{children:"Before the deployment of OVN, the deployment of Open vSwitch must already have been done."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull ovn\nosism apply ovn\n"})}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>d});var i=s(96540);const t={},o=i.createContext(t);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4d571bd0.7f888589.js b/assets/js/4d571bd0.7f888589.js new file mode 100644 index 0000000000..7acc4a5436 --- /dev/null +++ b/assets/js/4d571bd0.7f888589.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9226],{54209:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>r});var t=o(74848),i=o(28453);const a={sidebar_label:"Aodh"},s="Aodh",d={id:"iaas/guides/configuration-guide/openstack/aodh",title:"Aodh",description:"* Aodh admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/aodh.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/aodh",permalink:"/docs/iaas/guides/configuration-guide/openstack/aodh",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/aodh.md",tags:[],version:"current",frontMatter:{sidebar_label:"Aodh"},sidebar:"docs",previous:{title:"OpenStack",permalink:"/docs/iaas/guides/configuration-guide/openstack/"},next:{title:"Barbican",permalink:"/docs/iaas/guides/configuration-guide/openstack/barbican"}},c={},r=[];function u(e){const n={a:"a",h1:"h1",li:"li",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"aodh",children:"Aodh"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/aodh/latest/admin/index.html",children:"Aodh admin guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/aodh/latest/configuration/index.html",children:"Aodh configuration guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/aodh/latest/configuration/aodh-config-options.html",children:"Aodh configuration reference"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>d});var t=o(96540);const i={},a=t.createContext(i);function s(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4e607b99.52488ba2.js b/assets/js/4e607b99.52488ba2.js new file mode 100644 index 0000000000..728b083253 --- /dev/null +++ b/assets/js/4e607b99.52488ba2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2441],{59669:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var o=n(74848),i=n(28453);const s={},r="Jitsi",a={id:"tools/jitsi",title:"Jitsi",description:"We use a self-hosted Jitsi Meet instance for video conferencing.",source:"@site/community/tools/jitsi.md",sourceDirName:"tools",slug:"/tools/jitsi",permalink:"/community/tools/jitsi",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Tools",permalink:"/community/category/tools"},next:{title:"Matrix",permalink:"/community/tools/matrix"}},c={},l=[{value:"Usage",id:"usage",level:2}];function h(e){const t={a:"a",h1:"h1",h2:"h2",p:"p",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"jitsi",children:"Jitsi"}),"\n",(0,o.jsxs)(t.p,{children:["We use a self-hosted ",(0,o.jsx)(t.a,{href:"https://jitsi.org",children:"Jitsi Meet"})," instance for video conferencing.\nThanks go to Cleura for providing the server for it."]}),"\n",(0,o.jsxs)(t.p,{children:["The server uses an automated deployment based on the\n",(0,o.jsx)(t.a,{href:"https://github.com/garloff/heat-docker-jitsi-meet",children:"heat-docker-jitsi-meet"})," project."]}),"\n",(0,o.jsx)(t.p,{children:"Configuration is such everyone who knows the room can connect, unless the moderator\nsets a password/PIN. Opening a new room requires authentication. (Contact Kurt if\nyou need a password.)"}),"\n",(0,o.jsx)(t.p,{children:"Links to the meeting room (as well as dial-in information) are in the appointments\nin the public calendar."}),"\n",(0,o.jsx)(t.h2,{id:"usage",children:"Usage"}),"\n",(0,o.jsx)(t.p,{children:"Connect with a desktop browser (Chrome/Chromium or other blink based browser\nrecommended due to superior WebRTC implementation with SimulCast/SVC for VP8/VP9 --\nSafari & Firefox work, but cause higher data traffic). For mobile devices use\nthe Jitsi Meet App."}),"\n",(0,o.jsx)(t.p,{children:"Use the little arrows in the control bar at the bottom to select speaker, microphone\nand camera in case you lack audio/video. Occasionally, you can not hear all but\none participant; in this case reconnecting typically helps."}),"\n",(0,o.jsx)(t.p,{children:"We have an asterisk connected to some conference rooms to provide dial-in capabilities\nfor folks that lack internet connectivity (but have a working phone connection)."})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var o=n(96540);const i={},s=o.createContext(i);function r(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4e6fa974.c357784d.js b/assets/js/4e6fa974.c357784d.js new file mode 100644 index 0000000000..6ed9b99c10 --- /dev/null +++ b/assets/js/4e6fa974.c357784d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[557],{36848:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>t,toc:()=>l});var a=i(74848),r=i(28453);const o={title:"Domain Manager configuration for Keystone",type:"Standard",status:"Draft",track:"IAM"},s=void 0,t={id:"scs-0302-v1-domain-manager-role",title:"Domain Manager configuration for Keystone",description:"Introduction",source:"@site/standards/scs-0302-v1-domain-manager-role.md",sourceDirName:".",slug:"/scs-0302-v1-domain-manager-role",permalink:"/standards/scs-0302-v1-domain-manager-role",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Domain Manager configuration for Keystone",type:"Standard",status:"Draft",track:"IAM"},sidebar:"standards",previous:{title:"scs-0302: Domain Manager configuration for Keystone",permalink:"/standards/iam/scs-0302"},next:{title:"Ops Standards",permalink:"/standards/ops/"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Glossary",id:"glossary",level:3},{value:"Impact",id:"impact",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Desired Workflow",id:"desired-workflow",level:3},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Re-using the existing <code>admin</code> role",id:"re-using-the-existing-admin-role",level:4},{value:"Introducing a new persona and role with API policy changes",id:"introducing-a-new-persona-and-role-with-api-policy-changes",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"Limitations",id:"limitations",level:3},{value:"Decision",id:"decision",level:2},{value:"Policy adjustments",id:"policy-adjustments",level:3},{value:"Specifying manageable roles via "<code>is_domain_managed_role</code>"",id:"specifying-manageable-roles-via-is_domain_managed_role",level:4},{value:"Example: permitting multiple roles",id:"example-permitting-multiple-roles",level:5},{value:"Related Documents",id:"related-documents",level:2},{value:""admin"-ness not properly scoped",id:"admin-ness-not-properly-scoped",level:3},{value:"Consistent and Secure Default RBAC",id:"consistent-and-secure-default-rbac",level:3},{value:"Conformance Tests",id:"conformance-tests",level:2},{value:"Appendix",id:"appendix",level:2},{value:"Decision Record",id:"decision-record",level:3},{value:"Change the naming of the Domain Manager role to align with upstream",id:"change-the-naming-of-the-domain-manager-role-to-align-with-upstream",level:4},{value:"Allow flexibility for the roles a Domain Manager can assign/revoke within domain",id:"allow-flexibility-for-the-roles-a-domain-manager-can-assignrevoke-within-domain",level:4},{value:"Extend domain management functionality to Keystone groups",id:"extend-domain-management-functionality-to-keystone-groups",level:4},{value:"Change the naming of the Domain Manager role",id:"change-the-naming-of-the-domain-manager-role",level:4}];function c(e){const n={a:"a",blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,a.jsxs)(n.p,{children:["SCS Clouds should provide a way to grant Domain Manager rights to SCS Customers which provides IAM self-service capabilities within an OpenStack domain.\nThis is not properly implemented in the default OpenStack configuration and requires specific adjustments to the Keystone identity management configuration.\nTo avoid conflict with the unscoped ",(0,a.jsx)(n.code,{children:"admin"}),' role in OpenStack we want to refer to this new persona as "Domain Manager", introducing the ',(0,a.jsx)(n.code,{children:"manager"})," role in the API for domains."]}),"\n",(0,a.jsx)(n.h3,{id:"glossary",children:"Glossary"}),"\n",(0,a.jsx)(n.p,{children:"The following special terms are used throughout this standard document:"}),"\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Term"}),(0,a.jsx)(n.th,{children:"Meaning"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"RBAC"}),(0,a.jsxs)(n.td,{children:["Role-Based Access Control",(0,a.jsx)(n.sup,{children:(0,a.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})," established by OpenStack Keystone"]})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"project"}),(0,a.jsx)(n.td,{children:"OpenStack project as per Keystone RBAC"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"user"}),(0,a.jsx)(n.td,{children:"OpenStack user as per Keystone RBAC"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"group"}),(0,a.jsx)(n.td,{children:"OpenStack group as per Keystone RBAC"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"role"}),(0,a.jsx)(n.td,{children:"OpenStack role as per Keystone RBAC"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"domain"}),(0,a.jsx)(n.td,{children:"OpenStack domain as per Keystone RBAC"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"IAM"}),(0,a.jsx)(n.td,{children:"identity and access management"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"persona"}),(0,a.jsx)(n.td,{children:"Abstract and conceptual role of a user in terms of IAM"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"IAM resources"}),(0,a.jsx)(n.td,{children:"projects, users, groups, roles, domains as managed by OpenStack Keystone"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"CSP"}),(0,a.jsx)(n.td,{children:"Cloud Service Provider, provider managing the OpenStack infrastructure"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"cloud admin"}),(0,a.jsxs)(n.td,{children:["OpenStack user belonging to the CSP that possesses the ",(0,a.jsx)(n.code,{children:"admin"})," role"]})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"impact",children:"Impact"}),"\n",(0,a.jsx)(n.p,{children:"Applying this standard modifies the API policy configuration of Keystone and introduces a new persona to Keystone to enable IAM self-service for customers within a domain.\nOnce assigned, this persona allows special Domain Manager users within a domain to manage users, project, groups and role assignments as part of the IAM self-service."}),"\n",(0,a.jsx)(n.p,{children:"However, the configuration change introduced by this standard does not automatically assign the Domain Manager persona to any users per default.\nAssigning the new persona and granting customers the resulting self-service capabilities is a deliberate action to be taken by the CSP on a per-tenant (i.e. per domain) basis."}),"\n",(0,a.jsx)(n.p,{children:"Omitting the provisioning of any Domain Manager users (i.e. not assigning the new persona to any user) will result in an OpenStack cloud that behaves identically to a configuration without the standard applied, making the actual usage of the functionality a CSP's choice and entirely optional."}),"\n",(0,a.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,a.jsxs)(n.p,{children:["In the default configuration of Keystone, only users with the ",(0,a.jsx)(n.code,{children:"admin"})," role may manage the IAM resources such as projects, groups and users and their relation through role assignments.\nThe ",(0,a.jsx)(n.code,{children:"admin"})," role in OpenStack Keystone is not properly scoped when assigned within a domain or project only as due to hard-coded architectural limitations in OpenStack, a user with the ",(0,a.jsx)(n.code,{children:"admin"})," role may escalate their privileges outside of their assigned project or domain boundaries.\nThus, it is not possible to properly give customers a self-service functionality in regards to project, group and user management with the default configuration."]}),"\n",(0,a.jsxs)(n.p,{children:["To address this, this standard defines a new Domain Manager persona implemented using a domain-scoped ",(0,a.jsx)(n.code,{children:"manager"})," role in conjunction with appropriate Keystone API policy adjustments to establish a standardized extension to the default Keystone configuration allowing for IAM self-service capabilities for customers within domains."]}),"\n",(0,a.jsx)(n.h3,{id:"desired-workflow",children:"Desired Workflow"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"The cloud admin deploys the Domain Manager policy configuration for Keystone as per this standard if it is not already applied."}),"\n",(0,a.jsx)(n.li,{children:"The cloud admin creates the desired domains for the customers for which IAM self-service capabilities are desired."}),"\n",(0,a.jsxs)(n.li,{children:["The cloud admin creates one or more users within each of the applicable domains and assigns the ",(0,a.jsx)(n.code,{children:"manager"})," role for a certain domain to them. These users represent the Domain Managers of the corresponding domain."]}),"\n",(0,a.jsx)(n.li,{children:"The customer uses the Domain Manager users to manage (create, update, delete) users, projects, groups and corresponding role assignments within their domain."}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"the Domain Manager persona MUST support managing projects, groups and users within a specific domain"}),"\n",(0,a.jsx)(n.li,{children:"the Domain Manager persona MUST be properly scoped to a domain, it MUST NOT gain access to resources outside of its owning domain"}),"\n",(0,a.jsx)(n.li,{children:"the Domain Manager persona MUST NOT be able to manipulate existing roles or create new roles"}),"\n",(0,a.jsx)(n.li,{children:"the Domain Manager persona MUST only be able to assign specific non-administrative* roles to their managed users where the applicable roles are defined by the CSP"}),"\n",(0,a.jsx)(n.li,{children:"Domain Managers MUST NOT be able to abuse the role assignment functionalities to escalate their own privileges or those of other users beyond the roles defined by the CSP"}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:['* "non-administrative" in this context means this excludes the role "',(0,a.jsx)(n.code,{children:"admin"}),'" and any comparable role that grants permissions beyond domain and tenant scope.\nSince the "',(0,a.jsx)(n.code,{children:"manager"}),'" role as defined in this standard is domain-scoped for a Domain Manager, it does not count as administrative.']}),"\n",(0,a.jsx)(n.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,a.jsxs)(n.h4,{id:"re-using-the-existing-admin-role",children:["Re-using the existing ",(0,a.jsx)(n.code,{children:"admin"})," role"]}),"\n",(0,a.jsxs)(n.p,{children:["As role assignments can be scoped to project, groups and domains the most obvious option would be to assign the existing ",(0,a.jsx)(n.code,{children:"admin"})," role to users representing Domain Managers in a scoped fashion."]}),"\n",(0,a.jsxs)(n.p,{children:["However, due to architectural limitations",(0,a.jsx)(n.sup,{children:(0,a.jsx)(n.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," of the existing OpenStack implementation of roles, the ",(0,a.jsx)(n.code,{children:"admin"})," role has a special meaning reaching beyond the RBAC checks done by Keystone and other OpenStack components.\nThis results in special permissions being granted to users possessing the role which ignore the project or domain scope of the role assignment.\nThis poses severe security risks as the proper scoping of the ",(0,a.jsx)(n.code,{children:"admin"})," role is impossible.\n",(0,a.jsx)(n.strong,{children:"Due to this, this approach was discarded early."})]}),"\n",(0,a.jsxs)(n.p,{children:["Upstream (OpenStack) is in the process of addressing this across the services but it has not been fully implemented yet, especially for domains",(0,a.jsx)(n.sup,{children:(0,a.jsx)(n.a,{href:"#user-content-fn-3",id:"user-content-fnref-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),"."]}),"\n",(0,a.jsx)(n.h4,{id:"introducing-a-new-persona-and-role-with-api-policy-changes",children:"Introducing a new persona and role with API policy changes"}),"\n",(0,a.jsxs)(n.p,{children:["OpenStack Keystone allows for new roles to be created via its API by administrative users.\nAdditionally, each OpenStack API's RBAC can be adjusted through an API policy file (",(0,a.jsx)(n.code,{children:"policy.yaml"}),") through olso-policy",(0,a.jsx)(n.sup,{children:(0,a.jsx)(n.a,{href:"#user-content-fn-4",id:"user-content-fnref-4","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"4"})}),", Keystone included.\nThe possibility of managing users, projects, role assignments and so on is regulated through Keystone's RBAC configured by its API policy file."]}),"\n",(0,a.jsx)(n.p,{children:"This means that by creating a new role and extending Keystone's API policy configuration a new Domain Manager persona can be established that is limited to a specific subset of the Keystone API to be used to manage users, projects and role assignments within a domain."}),"\n",(0,a.jsx)(n.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,a.jsx)(n.h3,{id:"limitations",children:"Limitations"}),"\n",(0,a.jsx)(n.p,{children:"The approach described in this standard imposes the following limitations:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:['as a result of the "',(0,a.jsx)(n.code,{children:"identity:list_domains"}),'" rule (see below), Domain Managers are able to see all domains',(0,a.jsx)(n.sup,{children:(0,a.jsx)(n.a,{href:"#user-content-fn-5",id:"user-content-fnref-5","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"5"})}),' via "',(0,a.jsx)(n.code,{children:"openstack domain list"}),'" and can inspect the metadata of other domains with "',(0,a.jsx)(n.code,{children:"openstack domain show"}),'"']}),"\n",(0,a.jsxs)(n.li,{children:['as a result of the "',(0,a.jsx)(n.code,{children:"identity:list_roles"}),'" rule (see below), Domain Managers are able to see all roles via "',(0,a.jsx)(n.code,{children:"openstack role list"}),'" and can inspect the metadata of other roles with "',(0,a.jsx)(n.code,{children:"openstack role show"}),'"']}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"As a result of points 1 and 2, metadata of all domains and roles will be exposed to all Domain Managers!"})}),"\n",(0,a.jsxs)(n.p,{children:["If a CSP deems either of these points critical, they may abstain from granting the ",(0,a.jsx)(n.code,{children:'"manager"'})," role to any user in a domain scope, effectively disabling the Domain Manager functionality. See ",(0,a.jsx)(n.a,{href:"#impact",children:"Impact"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,a.jsxs)(n.p,{children:['A role named "',(0,a.jsx)(n.code,{children:"manager"}),'" is to be created via the Keystone API and the policy adjustments quoted below are to be applied.']}),"\n",(0,a.jsx)(n.h3,{id:"policy-adjustments",children:"Policy adjustments"}),"\n",(0,a.jsx)(n.p,{children:"The following policy has to be applied to Keystone in a verbatim fashion.\nThe only parts of the policy definitions that may be changed are:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:['The "',(0,a.jsx)(n.code,{children:"base_*"}),'" definitions to align them to the correct OpenStack defaults matching the OpenStack release of the environment in case those differ from this template.']}),"\n",(0,a.jsxs)(n.li,{children:['The "',(0,a.jsx)(n.code,{children:"is_domain_managed_role"}),'" definition (see next section below).']}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'# SCS Domain Manager policy configuration\n\n# Section A: OpenStack base definitons\n# The entries beginning with "base_<rule>" should be exact copies of the\n# default "identity:<rule>" definitions for the target OpenStack release.\n# They will be extended upon for the manager role below this section.\n"base_get_domain": "(role:reader and system_scope:all) or token.domain.id:%(target.domain.id)s or token.project.domain.id:%(target.domain.id)s"\n"base_list_domains": "(role:reader and system_scope:all)"\n"base_list_roles": "(role:reader and system_scope:all)"\n"base_get_role": "(role:reader and system_scope:all)"\n"base_list_users": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"\n"base_get_user": "(role:reader and system_scope:all) or (role:reader and token.domain.id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"\n"base_create_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"\n"base_update_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"\n"base_delete_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"\n"base_list_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"\n"base_get_project": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.project.domain_id)s) or project_id:%(target.project.id)s"\n"base_create_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"\n"base_update_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"\n"base_delete_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"\n"base_list_user_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"\n"base_check_grant": "(role:reader and system_scope:all) or ((role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"\n"base_list_grants": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)"\n"base_create_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"\n"base_revoke_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"\n"base_list_role_assignments": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"\n"base_list_groups": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"\n"base_get_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"\n"base_create_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"\n"base_update_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"\n"base_delete_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"\n"base_list_groups_for_user": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(user_id)s"\n"base_list_users_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"\n"base_remove_user_from_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"\n"base_check_user_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"\n"base_add_user_to_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"\n\n# Section B: Domain Manager Extensions\n\n# classify domain managers with a special role\n"is_domain_manager": "role:manager"\n\n# specify a rule that whitelists roles which domain admins are permitted\n# to assign and revoke within their domain\n"is_domain_managed_role": "\'member\':%(target.role.name)s or \'load-balancer_member\':%(target.role.name)s"\n\n# allow domain admins to retrieve their own domain (does not need changes)\n"identity:get_domain": "rule:base_get_domain or rule:admin_required"\n\n# list_domains is needed for GET /v3/domains?name=... requests\n# this is mandatory for things like\n# `create user --domain $DOMAIN_NAME $USER_NAME` to correctly discover\n# domains by name\n"identity:list_domains": "rule:is_domain_manager or rule:base_list_domains or rule:admin_required"\n\n# list_roles is needed for GET /v3/roles?name=... requests\n# this is mandatory for things like `role add ... $ROLE_NAME`` to correctly\n# discover roles by name\n"identity:list_roles": "rule:is_domain_manager or rule:base_list_roles or rule:admin_required"\n\n# get_role is needed for GET /v3/roles/{role_id} requests\n# this is mandatory for the OpenStack SDK to properly process role assignments\n# which are issued by role id instead of name\n"identity:get_role": "(rule:is_domain_manager and rule:is_domain_managed_role) or rule:base_get_role or rule:admin_required"\n\n# allow domain admins to manage users within their domain\n"identity:list_users": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_users or rule:admin_required"\n"identity:get_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_get_user or rule:admin_required"\n"identity:create_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_create_user or rule:admin_required"\n"identity:update_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_update_user or rule:admin_required"\n"identity:delete_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_delete_user or rule:admin_required"\n\n# allow domain admins to manage projects within their domain\n"identity:list_projects": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_projects or rule:admin_required"\n"identity:get_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_get_project or rule:admin_required"\n"identity:create_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_create_project or rule:admin_required"\n"identity:update_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_update_project or rule:admin_required"\n"identity:delete_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_delete_project or rule:admin_required"\n"identity:list_user_projects": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_user_projects or rule:admin_required"\n\n# allow domain managers to manage role assignments within their domain\n# (restricted to specific roles by the \'is_domain_managed_role\' rule)\n#\n# project-level role assignment to user within domain\n"is_domain_user_project_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s"\n# project-level role assignment to group within domain\n"is_domain_group_project_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.project.domain_id)s"\n# domain-level role assignment to group\n"is_domain_level_group_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.domain.id)s"\n# domain-level role assignment to user\n"is_domain_level_user_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.domain.id)s"\n"domain_manager_grant": "rule:is_domain_manager and (rule:is_domain_user_project_grant or rule:is_domain_group_project_grant or rule:is_domain_level_group_grant or rule:is_domain_level_user_grant)"\n"identity:check_grant": "rule:domain_manager_grant or rule:base_check_grant or rule:admin_required"\n"identity:list_grants": "rule:domain_manager_grant or rule:base_list_grants or rule:admin_required"\n"identity:create_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_create_grant or rule:admin_required"\n"identity:revoke_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_revoke_grant or rule:admin_required"\n"identity:list_role_assignments": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_role_assignments or rule:admin_required"\n\n\n# allow domain managers to manage groups within their domain\n"identity:list_groups": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_list_groups or rule:admin_required"\n"identity:get_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_get_group or rule:admin_required"\n"identity:create_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_create_group or rule:admin_required"\n"identity:update_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_update_group or rule:admin_required"\n"identity:delete_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_delete_group or rule:admin_required"\n"identity:list_groups_for_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_groups_for_user or rule:admin_required"\n"identity:list_users_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_list_users_in_group or rule:admin_required"\n"identity:remove_user_from_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_remove_user_from_group or rule:admin_required"\n"identity:check_user_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_check_user_in_group or rule:admin_required"\n"identity:add_user_to_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_add_user_to_group or rule:admin_required"\n'})}),"\n",(0,a.jsxs)(n.p,{children:['Note that the policy file begins with a list of "',(0,a.jsx)(n.code,{children:"base_*"}),'" rule definitions ("Section A").\nThese mirror the default policies of recent OpenStack releases.\nThey are used as a basis for the domain-manager-specific changes which are implemented in "Section B" where they are referenced to via "',(0,a.jsx)(n.code,{children:"or rule:base_*"}),'" accordingly.\nThe section of "',(0,a.jsx)(n.code,{children:"base_*"}),'" rules is meant for easy maintenance/update of default rules while keeping the domain-manager-specific rules separate.']}),"\n",(0,a.jsxs)(n.blockquote,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Note:"}),'\nThe "',(0,a.jsx)(n.code,{children:"or rule:admin_required"}),'" appendix to the rule defintions in "Section B" is included for backwards compatibility with environments not yet fully configured for the new secure RBAC standard',(0,a.jsx)(n.sup,{children:(0,a.jsx)(n.a,{href:"#user-content-fn-6",id:"user-content-fnref-6","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"6"})}),"."]}),"\n"]}),"\n",(0,a.jsxs)(n.h4,{id:"specifying-manageable-roles-via-is_domain_managed_role",children:['Specifying manageable roles via "',(0,a.jsx)(n.code,{children:"is_domain_managed_role"}),'"']}),"\n",(0,a.jsxs)(n.p,{children:['The "',(0,a.jsx)(n.code,{children:"is_domain_managed_role"}),'" rule of the above policy template may be adjusted according to the requirements of the CSP and infrastructure architecture to specify different or multiple roles as manageable by Domain Managers as long as the policy rule adheres to the following:']}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:['the "',(0,a.jsx)(n.code,{children:"is_domain_managed_role"}),'" rule MUST NOT contain the "',(0,a.jsx)(n.code,{children:"admin"}),'" role, neither directly nor transitively']}),"\n",(0,a.jsxs)(n.li,{children:['the "',(0,a.jsx)(n.code,{children:"is_domain_managed_role"}),'" rule MUST define all applicable roles directly, it MUST NOT contain a "',(0,a.jsx)(n.code,{children:"rule:"}),'" reference within itself']}),"\n"]}),"\n",(0,a.jsx)(n.h5,{id:"example-permitting-multiple-roles",children:"Example: permitting multiple roles"}),"\n",(0,a.jsxs)(n.p,{children:['The following example permits the "',(0,a.jsx)(n.code,{children:"reader"}),'" role to be assigned/revoked by a Domain Manager in addition to the default "',(0,a.jsx)(n.code,{children:"member"}),'" and "',(0,a.jsx)(n.code,{children:"load-balancer_member"}),'" roles.\nFurther roles can be appended using the logical ',(0,a.jsx)(n.code,{children:"or"})," directive."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"\"is_domain_managed_role\": \"'member':%(target.role.name)s or 'load-balancer_member':%(target.role.name)s or 'reader':%(target.role.name)s\"\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsxs)(n.strong,{children:["Note regarding the ",(0,a.jsx)(n.code,{children:"manager"})," role"]})}),"\n",(0,a.jsxs)(n.p,{children:['When adjusting the "',(0,a.jsx)(n.code,{children:"is_domain_managed_role"}),'" rule a CSP might opt to also include the "',(0,a.jsx)(n.code,{children:"manager"}),'" role itself in the manageable roles, resulting in Domain Managers being able to propagate the Domain Manager capabilities to other users within their domain.\nThis increases the self-service capabilities of the customer but introduces risks of Domain Managers also being able to revoke this role from themselves or each other (within their domain) in an unintended fashion.']}),"\n",(0,a.jsxs)(n.p,{children:['CSPs have to carefully evaluate whether Domain Manager designation authority should reside solely on their side or be part of the customer self-service scope and decide about adding "',(0,a.jsx)(n.code,{children:"'manager':%(target.role.name)s"}),'" to the rule accordingly.']}),"\n",(0,a.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,a.jsx)(n.h3,{id:"admin-ness-not-properly-scoped",children:'"admin"-ness not properly scoped'}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Description:"})," Upstream bug report about the underlying architectural issue of the ",(0,a.jsx)(n.code,{children:"admin"})," role not being properly scoped and giving system-level admin permissions regardless of whether the ",(0,a.jsx)(n.code,{children:"admin"})," role assignment was scoped to project or domain level.\nThis is the main reason for the ",(0,a.jsx)(n.code,{children:"admin"})," role being inappropriate to implement Domain Managers."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Link:"})," ",(0,a.jsx)(n.a,{href:"https://bugs.launchpad.net/keystone/+bug/968696",children:'Launchpad bug: "admin"-ness not properly scoped'})]}),"\n",(0,a.jsx)(n.h3,{id:"consistent-and-secure-default-rbac",children:"Consistent and Secure Default RBAC"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Description:"})," Upstream rework of the default role definitions and hierarchy across all OpenStack services.\nAims to introduce support for a scoped ",(0,a.jsx)(n.code,{children:"manager"})," role by 2024 but only focuses on project-level scoping for this role so far, not domain-level."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Link:"})," ",(0,a.jsx)(n.a,{href:"https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html",children:"OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC"})]}),"\n",(0,a.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,a.jsxs)(n.p,{children:["There is a test suite in ",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iam/domain-manager/domain-manager-check.py",children:(0,a.jsx)(n.code,{children:"domain-manager-check.py"})}),".\nThe test suite connects to the OpenStack API using two sample domains and corresponding Domain Manager accounts.\nIt verifies the compliance to the standard and the proper domain-scoping as defined by the Keystone policy.\nPlease consult the associated ",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iam/domain-manager/README.md",children:"README.md"})," for detailed setup and testing instructions."]}),"\n",(0,a.jsx)(n.h2,{id:"appendix",children:"Appendix"}),"\n",(0,a.jsx)(n.h3,{id:"decision-record",children:"Decision Record"}),"\n",(0,a.jsx)(n.h4,{id:"change-the-naming-of-the-domain-manager-role-to-align-with-upstream",children:"Change the naming of the Domain Manager role to align with upstream"}),"\n",(0,a.jsx)(n.p,{children:"Decision Date: 2024-03-13"}),"\n",(0,a.jsx)(n.p,{children:"Decision Maker: Team IaaS"}),"\n",(0,a.jsx)(n.p,{children:"Decision:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:'the Domain Manager role should be named "manager" not "domain-manager"'}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Rationale:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:'upstream (OpenStack) will introduce a "manager" role with the upcoming RBAC rework'}),"\n",(0,a.jsx)(n.li,{children:'the "manager" role is intended to grant managing capabilities bound to the scope it is assigned for, e.g. projects; it would make sense to also integrate the Domain Manager approach here'}),"\n",(0,a.jsx)(n.li,{children:'during the process of contributing the Domain Manager functionality upstream we were asked to use the already defined "manager" role instead of introducing a new role; so the rename would then also be in line with the upstream contribution'}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Links / Comments / References:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/minutes/blob/main/iaas/20240313.md#domain-manager-rolepersona-markus-hentsch",children:"Team IaaS meeting protocol entry"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://review.opendev.org/c/openstack/keystone-specs/+/903172/2/specs/keystone/2023.1/domain-manager-role.rst#20",children:'request from upstream to re-use existing "manager" role'})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"allow-flexibility-for-the-roles-a-domain-manager-can-assignrevoke-within-domain",children:"Allow flexibility for the roles a Domain Manager can assign/revoke within domain"}),"\n",(0,a.jsx)(n.p,{children:"Decision Date: 2023-09-27"}),"\n",(0,a.jsx)(n.p,{children:"Decision Maker: Team IaaS, Team IAM"}),"\n",(0,a.jsx)(n.p,{children:"Decision:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:'the standard should not strictly limit the roles a Domain Manager can assign/revoke to/from other users within a domain to the "member" role'}),"\n",(0,a.jsx)(n.li,{children:"the standard should allow CSPs to define one or more roles for Domain Managers to manage"}),"\n",(0,a.jsx)(n.li,{children:"whether or not this includes the Domain Manager role itself is not to be predefined by the standard and should be up to the CSP to decide instead"}),"\n",(0,a.jsx)(n.li,{children:'the standard should only strictly prohibit adding the "admin" role to the list of roles manageable by Domain Managers'}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Rationale:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"the available and configured roles might differ between CSPs and infrastructures"}),"\n",(0,a.jsx)(n.li,{children:"the Domain Manager standard should be flexible enough to adapt to different environments while still offering the intended functionality"}),"\n",(0,a.jsx)(n.li,{children:"there might be a tradeoff between self-service flexibility desired by customers and the security regulation a CSP wants to impose, thus allowing or prohibiting the designation of Domain Managers by customers themselves should be up to the CSP to decide"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Links / Comments / References:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://input.scs.community/2023-scs-team-iaas?view#Domain-Manager-Standard-markus-hentsch",children:"Team IaaS meeting protocol entry"})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"extend-domain-management-functionality-to-keystone-groups",children:"Extend domain management functionality to Keystone groups"}),"\n",(0,a.jsx)(n.p,{children:"Decision Date: 2023-08-04"}),"\n",(0,a.jsx)(n.p,{children:"Decision Maker: SIG IAM"}),"\n",(0,a.jsx)(n.p,{children:"Decision:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"the Domain Manager Standard configuration should cover the groups functionality of Keystone, allowing domain manager to manage groups in domains"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Rationale:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"the groups functionality is a desired IAM feature for customers"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Links / Comments / References:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://input.scs.community/2023-scs-sig-iam#Domain-Admin-rights-for-SCS-IaaS-Customers-184",children:"SIG IAM meeting protocol entry"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/issues/issues/383",children:"action item issue"})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"change-the-naming-of-the-domain-manager-role",children:"Change the naming of the Domain Manager role"}),"\n",(0,a.jsx)(n.p,{children:"Decision Date: 2023-08-04"}),"\n",(0,a.jsx)(n.p,{children:"Decision Maker: SIG IAM"}),"\n",(0,a.jsx)(n.p,{children:"Decision:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:'the Domain Manager role should be named "domain-manager" not "domain-admin".'}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Rationale:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["avoid confusion with the unscoped admin role and to be inline with the upstream plan: ",(0,a.jsx)(n.a,{href:"https://specs.openstack.org/openstack/keystone-specs/specs/keystone/2023.1/default-service-role.html",children:"Default Service Role - Identity Specs"})]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Links / Comments / References:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://input.scs.community/2023-scs-sig-iam#Domain-Admin-rights-for-SCS-IaaS-Customers-184",children:"SIG IAM meeting protocol entry"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/issues/issues/184#issuecomment-1670985934",children:"issue commment about decision"})}),"\n"]}),"\n","\n",(0,a.jsxs)(n.section,{"data-footnotes":!0,className:"footnotes",children:[(0,a.jsx)(n.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{id:"user-content-fn-1",children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://static.opendev.org/docs/patrole/latest/rbac-overview.html",children:"OpenStack Documentation: Role-Based Access Control Overview"})," ",(0,a.jsx)(n.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{id:"user-content-fn-2",children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://bugs.launchpad.net/keystone/+bug/968696",children:'Launchpad bug: "admin"-ness not properly scoped'})," ",(0,a.jsx)(n.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{id:"user-content-fn-3",children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://docs.openstack.org/keystone/latest/contributor/services.html#domain-scope",children:"OpenStack Documentation: Keystone for Other Services - Domain Scope"})," ",(0,a.jsx)(n.a,{href:"#user-content-fnref-3","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{id:"user-content-fn-4",children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://docs.openstack.org/oslo.policy/latest/admin/index.html",children:"OpenStack Documentation: Administering Applications that use oslo.policy"})," ",(0,a.jsx)(n.a,{href:"#user-content-fnref-4","data-footnote-backref":"","aria-label":"Back to reference 4",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{id:"user-content-fn-5",children:["\n",(0,a.jsxs)(n.p,{children:["see the ",(0,a.jsx)(n.a,{href:"https://bugs.launchpad.net/keystone/+bug/2041611",children:"corresponding Launchpad bug at Keystone"})," ",(0,a.jsx)(n.a,{href:"#user-content-fnref-5","data-footnote-backref":"","aria-label":"Back to reference 5",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{id:"user-content-fn-6",children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://governance.openstack.org/tc/goals/selected/consistent-and-secure-rbac.html",children:"OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC"})," ",(0,a.jsx)(n.a,{href:"#user-content-fnref-6","data-footnote-backref":"","aria-label":"Back to reference 6",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function m(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>s,x:()=>t});var a=i(96540);const r={},o=a.createContext(r);function s(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4edc808e.11fb0f02.js b/assets/js/4edc808e.11fb0f02.js new file mode 100644 index 0000000000..c4a4afa1aa --- /dev/null +++ b/assets/js/4edc808e.11fb0f02.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[308],{92842:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var s=n(74848),i=n(28453),o=n(54368);const a={title:"Introduction",sidebar_position:1},r=void 0,l={id:"index",title:"Introduction",description:"About",source:"@site/docs/index.mdx",sourceDirName:".",slug:"/",permalink:"/docs/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/index.mdx",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Introduction",sidebar_position:1},sidebar:"docs",next:{title:"IaaS Layer",permalink:"/docs/category/iaas-layer"}},c={},d=[{value:"About",id:"about",level:2},{value:"Architectural Overview",id:"architectural-overview",level:2},{value:"Use Cases and Deployment Examples",id:"use-cases-and-deployment-examples",level:2},{value:"IaaS Layer",id:"iaas-layer",level:3},{value:"Quick Start with Cloud-In-A-Box",id:"quick-start-with-cloud-in-a-box",level:4},{value:"Reference Implementation Testbed",id:"reference-implementation-testbed",level:4},{value:"Container Layer",id:"container-layer",level:3},{value:"K8s Cluster API Provider",id:"k8s-cluster-api-provider",level:4},{value:"Cluster Stacks",id:"cluster-stacks",level:4},{value:"Public SCS Clouds in production",id:"public-scs-clouds-in-production",level:3},{value:"Development of SCS",id:"development-of-scs",level:3},{value:"Issues and Bugs",id:"issues-and-bugs",level:3},{value:"Contribute and Connect",id:"contribute-and-connect",level:3},{value:"Releases and Roadmap",id:"releases-and-roadmap",level:3},{value:"Standards, Conformity and Certification",id:"standards-conformity-and-certification",level:2}];function h(e){const t={a:"a",br:"br",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"about",children:"About"}),"\n",(0,s.jsx)(t.p,{children:"The Sovereign Cloud Stack combines the best of Cloud Computing in one unified standard.\nSCS is built, backed, and operated by an active open-source community worldwide."}),"\n",(0,s.jsx)(t.h2,{id:"architectural-overview",children:"Architectural Overview"}),"\n",(0,s.jsx)(o.A,{jsonFilePath:"data/architecturalOverviewData.json"}),"\n",(0,s.jsx)(t.h2,{id:"use-cases-and-deployment-examples",children:"Use Cases and Deployment Examples"}),"\n",(0,s.jsx)(t.h3,{id:"iaas-layer",children:"IaaS Layer"}),"\n",(0,s.jsx)(t.h4,{id:"quick-start-with-cloud-in-a-box",children:"Quick Start with Cloud-In-A-Box"}),"\n",(0,s.jsxs)(t.p,{children:["The fastest way to get in touch with SCS is to deploy a SCS cloud virtually. The Cloud-In-A-Box was built explicitly for this scenario. Check it out ",(0,s.jsx)(t.a,{href:"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box",children:"here"})]}),"\n",(0,s.jsx)(t.h4,{id:"reference-implementation-testbed",children:"Reference Implementation Testbed"}),"\n",(0,s.jsxs)(t.p,{children:["This means that you set up an SCS test installation including all the infrastructure\npieces such as database, message queueing, ceph, monitoring and logging, IAM, the\n",(0,s.jsx)(t.a,{href:"https://openstack.org/",children:"OpenStack"})," core services, and (soon) the Container layer\non top of an existing IaaS platform."]}),"\n",(0,s.jsxs)(t.p,{children:["The SCS IaaS reference implementation is based on ",(0,s.jsx)(t.a,{href:"https://osism.tech/",children:"OSISM"}),". Read on the\n",(0,s.jsx)(t.a,{href:"https://docs.osism.de/testbed/",children:"OSISM testbed docs"})," to learn how to get the\ntestbed running. Please read carefully through the\n",(0,s.jsx)(t.a,{href:"https://docs.osism.de/testbed/deployment.html",children:"deployment"})," section of the\nmanual."]}),"\n",(0,s.jsx)(t.h3,{id:"container-layer",children:"Container Layer"}),"\n",(0,s.jsx)(t.h4,{id:"k8s-cluster-api-provider",children:"K8s Cluster API Provider"}),"\n",(0,s.jsxs)(t.p,{children:["You can easily deploy the container layer on top of the testbed (or a production\nSCS cloud) checking out the code from\n",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/",children:"k8s-cluster-api-provider"}),"."]}),"\n",(0,s.jsx)(t.h4,{id:"cluster-stacks",children:"Cluster Stacks"}),"\n",(0,s.jsxs)(t.p,{children:["With the Cluster Stacks, in the V2 KaaS reference implementation, we provide an opinionated optimized configuration of Kubernetes clusters. Through better packaging, integrated testing, and bundled configuration, SCS-based Kubernetes clusters provide easier individualization.",(0,s.jsx)(t.br,{}),"\n","Throughout the R6 development cycle Cluster Stacks are taken from a technical preview to be ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/issues/milestone/8",children:"functional and available on top of the IaaS reference implementation"})," as well to replace the V1 KaaS reference implementation ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/",children:"k8s-cluster-api-provider"}),".",(0,s.jsx)(t.br,{}),"\n","The Cluster Stacks can already be tried with the ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks-demo",children:"demo"})," repository. Although this is based on the not-production-ready Docker provider, the usage is the same for every provider."]}),"\n",(0,s.jsx)(t.h3,{id:"public-scs-clouds-in-production",children:"Public SCS Clouds in production"}),"\n",(0,s.jsxs)(t.p,{children:["Find the current list of scs compatible clouds ",(0,s.jsx)(t.a,{href:"https://docs.scs.community/standards/certification/overview#compliant-cloud-environments",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"development-of-scs",children:"Development of SCS"}),"\n",(0,s.jsx)(t.p,{children:"While the SCS project tracks the efforts across the released epics and user stories, the work on the code, whenever possible, happens upstream. As such, these repositories are usually not found in the SCS GitHub organization. SCS works directly in the following upstream projects:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"CNCF projects,"}),"\n",(0,s.jsx)(t.li,{children:"OpenStack,"}),"\n",(0,s.jsx)(t.li,{children:"kolla-ansible,"}),"\n",(0,s.jsx)(t.li,{children:"OSISM and others."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["All code not pushed upstream can be found in the ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack",children:"SCS Github organization"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"issues-and-bugs",children:"Issues and Bugs"}),"\n",(0,s.jsxs)(t.p,{children:["If you can identify the affected component, raise the issue against the relevant repository in the SovereignCloudStack or OSISM space. Otherwise, you can use the ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/issues",children:"issues repository"}),". We appreciate PRs as well as issues; please don't forget to sign off your contributions see ",(0,s.jsx)(t.a,{href:"https://docs.scs.community/community",children:"contributor guide"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"contribute-and-connect",children:"Contribute and Connect"}),"\n",(0,s.jsxs)(t.p,{children:["Please see the ",(0,s.jsx)(t.a,{href:"https://docs.scs.community/community",children:"SCS contributor guide"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"releases-and-roadmap",children:"Releases and Roadmap"}),"\n",(0,s.jsxs)(t.p,{children:["See our Release Notes ",(0,s.jsx)(t.a,{href:"https://docs.scs.community/docs/category/releases",children:"here"})]}),"\n",(0,s.jsx)(t.h2,{id:"standards-conformity-and-certification",children:"Standards, Conformity and Certification"}),"\n",(0,s.jsxs)(t.p,{children:["How to get compliant? What do I need to be compliant? What are the benefits? What does it involve? What to expect in the future? Learn more in the ",(0,s.jsx)(t.a,{href:"https://docs.scs.community/standards",children:"standards section"}),"."]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},54368:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var s=n(89839);const i="gradient_pRJN",o="border_XcL8",a="bottom_ufNC";var r=n(44586),l=n(74848);const c=e=>{const{topLayers:t}=e,n=(0,r.A)().globalData["global-data-plugin"].default.architecturalOverviewData;return n?(0,l.jsxs)("div",{className:`${i} ${o} row`,children:[!t&&(0,l.jsx)("div",{style:{display:"flex",margin:" 10px 0 4px 12px"},children:(0,l.jsx)("h5",{style:{marginBottom:0},children:"SCS Component Map"})}),(0,l.jsxs)("div",{style:{display:"flex",flexWrap:"wrap"},children:[(0,l.jsx)("div",{style:{padding:"8px 8px 8px 8px",margin:"0 0 0 0"},className:`${a} col col--3`,children:n.ops.map(((e,n)=>(0,l.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components},n)))}),(0,l.jsxs)("div",{className:"col col--6",style:{padding:"8px 8px 8px 8px",margin:"0 0 0 0"},children:[n.container.map(((e,i)=>(0,l.jsx)("div",{style:{marginBottom:e===n.container[0]?"8px":"0"},children:(0,l.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components})},i))),n.iaas.map(((e,n)=>(0,l.jsx)("div",{children:(0,l.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components})},n)))]}),(0,l.jsx)("div",{className:"col col--3",style:{padding:"8px 8px 8px 8px",margin:"0 0 0 0"},children:n.iam.map(((e,n)=>(0,l.jsx)(s.A,{small:!t,style:t&&{height:"100%"},title:e.title,body:t&&e.body,buttonText:t&&e.buttonText,url:e.url,components:!t&&e.components},n)))})]})]}):(0,l.jsx)("div",{children:"No data available."})}},89839:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);const s="contentCard_uSpk",i="layerComponent_syzR",o="layerComponentWip_fSEJ";var a=n(28774),r=n(56347),l=n(74848);const c=e=>{const{title:t,body:n,url:c,buttonText:d,style:h,small:u,components:p}=e,m=(0,r.zy)();return(0,l.jsxs)("div",{style:h,className:`${s} card`,children:[(0,l.jsx)("div",{className:"card__header",children:u?(0,l.jsx)("h5",{style:{marginLeft:"-6px"},children:t}):(0,l.jsx)("h3",{children:t})}),(0,l.jsx)("div",{className:"card__body",children:(0,l.jsx)("p",{children:n})}),(0,l.jsx)("div",{style:{display:"flex",flexWrap:"wrap"},children:p&&p.map(((e,t)=>(0,l.jsx)(a.A,{to:e.url,children:(0,l.jsx)("div",{style:m.pathname==e.url?{color:"blue",backgroundColor:"#0066ff44"}:{},className:"true"==e.stable?i:o,children:e.title})},t)))}),d&&(0,l.jsx)("div",{className:"card__footer",children:(0,l.jsx)(a.A,{className:"button button--secondary button--md",to:c,children:d})})]})}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var s=n(96540);const i={},o=s.createContext(i);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4f363fd8.020c221f.js b/assets/js/4f363fd8.020c221f.js new file mode 100644 index 0000000000..946a9490e9 --- /dev/null +++ b/assets/js/4f363fd8.020c221f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4605],{18312:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>l,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var t=r(74848),i=r(28453);const s={sidebar_label:"Cinder"},o="Cinder",c={id:"iaas/guides/configuration-guide/openstack/cinder",title:"Cinder",description:"* Cinder admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/cinder.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/cinder",permalink:"/docs/iaas/guides/configuration-guide/openstack/cinder",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/cinder.md",tags:[],version:"current",frontMatter:{sidebar_label:"Cinder"},sidebar:"docs",previous:{title:"Ceilometer",permalink:"/docs/iaas/guides/configuration-guide/openstack/ceilometer"},next:{title:"Designate",permalink:"/docs/iaas/guides/configuration-guide/openstack/designate"}},a={},d=[{value:"Pure Storage FlashArray",id:"pure-storage-flasharray",level:2}];function u(e){const n={a:"a",h1:"h1",h2:"h2",li:"li",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"cinder",children:"Cinder"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/cinder/latest/admin/index.html",children:"Cinder admin guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/cinder/latest/configuration/index.html",children:"Cinder configuration guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/cinder/latest/configuration/block-storage/samples/cinder.conf.html",children:"Cinder configuration reference"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"pure-storage-flasharray",children:"Pure Storage FlashArray"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://support.purestorage.com/bundle/m_openstack/page/Solutions/topics/concept/c_openstack_02.html",children:"https://support.purestorage.com/bundle/m_openstack/page/Solutions/topics/concept/c_openstack_02.html"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://support-be.purestorage.com/bundle/m_openstack/page/Solutions/OpenStack/OpenStack_Reference/library/resources/Pure_Storage_OpenStack_2023.2_Bobcat_Cinder_Driver_Best_Practices.pdf",children:"Pure Storage OpenStack (2023.2) Cinder Driver Best Practices"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/openstack/cinder/blob/master/cinder/volume/drivers/pure.py",children:"https://github.com/openstack/cinder/blob/master/cinder/volume/drivers/pure.py"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/cinder/latest/configuration/block-storage/drivers/pure-storage-driver.html",children:"https://docs.openstack.org/cinder/latest/configuration/block-storage/drivers/pure-storage-driver.html"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>c});var t=r(96540);const i={},s=t.createContext(i);function o(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/502adbf6.6527a76e.js b/assets/js/502adbf6.6527a76e.js new file mode 100644 index 0000000000..1b1a8d2619 --- /dev/null +++ b/assets/js/502adbf6.6527a76e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8561],{56306:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>r,contentTitle:()=>t,default:()=>c,frontMatter:()=>o,metadata:()=>a,toc:()=>u});var s=n(74848),d=n(28453);const o={sidebar_label:"Guides",sidebar_position:50},t="Guides",a={id:"iaas/guides/index",title:"Guides",description:"* The Concept Guide explains which components and modules make up OSISM. It also",source:"@site/docs/02-iaas/guides/index.md",sourceDirName:"02-iaas/guides",slug:"/iaas/guides/",permalink:"/docs/iaas/guides/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/index.md",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"Guides",sidebar_position:50},sidebar:"docs",previous:{title:"Ceph",permalink:"/docs/iaas/guides/troubleshooting-guide/ceph"},next:{title:"User Guide",permalink:"/docs/iaas/guides/user-guide/"}},r={},u=[];function l(e){const i={a:"a",h1:"h1",li:"li",ul:"ul",...(0,d.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h1,{id:"guides",children:"Guides"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["The ",(0,s.jsx)(i.a,{href:"./concept-guide/",children:"Concept Guide"})," explains which components and modules make up OSISM. It also\nexplains the use cases."]}),"\n",(0,s.jsxs)(i.li,{children:["The ",(0,s.jsx)(i.a,{href:"./deploy-guide/",children:"Deploy Guide"})," explains how the nodes of a cluster are created and bootstrapped.\nIt also explains how the individual modules can be deployed."]}),"\n",(0,s.jsxs)(i.li,{children:["The ",(0,s.jsx)(i.a,{href:"./upgrade-guide/",children:"Upgrade Guide"})," explains how the individual modules can be upgraded."]}),"\n",(0,s.jsxs)(i.li,{children:["The ",(0,s.jsx)(i.a,{href:"./configuration-guide/",children:"Configuration Guide"})," explains how the individual modules can be\nconfigured."]}),"\n",(0,s.jsxs)(i.li,{children:["The ",(0,s.jsx)(i.a,{href:"./operations-guide/",children:"Operations Guide"})," explains how individual tasks can be done in\nday-to-day business in a running cluster."]}),"\n",(0,s.jsxs)(i.li,{children:["The ",(0,s.jsx)(i.a,{href:"./troubleshooting-guide/",children:"Troubleshooting Guide"})," explains how to resolve problems.\nIt is an extension of the Operations Guide."]}),"\n",(0,s.jsxs)(i.li,{children:["The ",(0,s.jsx)(i.a,{href:"./user-guide/",children:"User Guide"})," is intended for users of the individual components. It contains\nbest practices, as well as other information."]}),"\n"]})]})}function c(e={}){const{wrapper:i}={...(0,d.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>t,x:()=>a});var s=n(96540);const d={},o=s.createContext(d);function t(e){const i=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:t(e.components),s.createElement(o.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/506.080976e4.js b/assets/js/506.080976e4.js new file mode 100644 index 0000000000..014e754959 --- /dev/null +++ b/assets/js/506.080976e4.js @@ -0,0 +1,1820 @@ +"use strict"; +exports.id = 506; +exports.ids = [506]; +exports.modules = { + +/***/ 66506: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99418); + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 3], $V1 = [1, 6], $V2 = [1, 4], $V3 = [1, 5], $V4 = [2, 5], $V5 = [1, 12], $V6 = [5, 7, 13, 19, 21, 23, 24, 26, 28, 31, 37, 40, 47], $V7 = [7, 13, 19, 21, 23, 24, 26, 28, 31, 37, 40], $V8 = [7, 12, 13, 19, 21, 23, 24, 26, 28, 31, 37, 40], $V9 = [7, 13, 47], $Va = [1, 42], $Vb = [1, 41], $Vc = [7, 13, 29, 32, 35, 38, 47], $Vd = [1, 55], $Ve = [1, 56], $Vf = [1, 57], $Vg = [7, 13, 32, 35, 42, 47]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "eol": 4, "GG": 5, "document": 6, "EOF": 7, ":": 8, "DIR": 9, "options": 10, "body": 11, "OPT": 12, "NL": 13, "line": 14, "statement": 15, "commitStatement": 16, "mergeStatement": 17, "cherryPickStatement": 18, "acc_title": 19, "acc_title_value": 20, "acc_descr": 21, "acc_descr_value": 22, "acc_descr_multiline_value": 23, "section": 24, "branchStatement": 25, "CHECKOUT": 26, "ref": 27, "BRANCH": 28, "ORDER": 29, "NUM": 30, "CHERRY_PICK": 31, "COMMIT_ID": 32, "STR": 33, "PARENT_COMMIT": 34, "COMMIT_TAG": 35, "EMPTYSTR": 36, "MERGE": 37, "COMMIT_TYPE": 38, "commitType": 39, "COMMIT": 40, "commit_arg": 41, "COMMIT_MSG": 42, "NORMAL": 43, "REVERSE": 44, "HIGHLIGHT": 45, "ID": 46, ";": 47, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 5: "GG", 7: "EOF", 8: ":", 9: "DIR", 12: "OPT", 13: "NL", 19: "acc_title", 20: "acc_title_value", 21: "acc_descr", 22: "acc_descr_value", 23: "acc_descr_multiline_value", 24: "section", 26: "CHECKOUT", 28: "BRANCH", 29: "ORDER", 30: "NUM", 31: "CHERRY_PICK", 32: "COMMIT_ID", 33: "STR", 34: "PARENT_COMMIT", 35: "COMMIT_TAG", 36: "EMPTYSTR", 37: "MERGE", 38: "COMMIT_TYPE", 40: "COMMIT", 42: "COMMIT_MSG", 43: "NORMAL", 44: "REVERSE", 45: "HIGHLIGHT", 46: "ID", 47: ";" }, + productions_: [0, [3, 2], [3, 3], [3, 4], [3, 5], [6, 0], [6, 2], [10, 2], [10, 1], [11, 0], [11, 2], [14, 2], [14, 1], [15, 1], [15, 1], [15, 1], [15, 2], [15, 2], [15, 1], [15, 1], [15, 1], [15, 2], [25, 2], [25, 4], [18, 3], [18, 5], [18, 5], [18, 7], [18, 7], [18, 5], [18, 5], [18, 5], [18, 7], [18, 7], [18, 7], [18, 7], [17, 2], [17, 4], [17, 4], [17, 4], [17, 6], [17, 6], [17, 6], [17, 6], [17, 6], [17, 6], [17, 8], [17, 8], [17, 8], [17, 8], [17, 8], [17, 8], [16, 2], [16, 3], [16, 3], [16, 5], [16, 5], [16, 3], [16, 5], [16, 5], [16, 5], [16, 5], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 3], [16, 5], [16, 5], [16, 5], [16, 5], [16, 5], [16, 5], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [41, 0], [41, 1], [39, 1], [39, 1], [39, 1], [27, 1], [27, 1], [4, 1], [4, 1], [4, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 2: + return $$[$0]; + case 3: + return $$[$0 - 1]; + case 4: + yy.setDirection($$[$0 - 3]); + return $$[$0 - 1]; + case 6: + yy.setOptions($$[$0 - 1]); + this.$ = $$[$0]; + break; + case 7: + $$[$0 - 1] += $$[$0]; + this.$ = $$[$0 - 1]; + break; + case 9: + this.$ = []; + break; + case 10: + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + break; + case 11: + this.$ = $$[$0 - 1]; + break; + case 16: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 17: + case 18: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 19: + yy.addSection($$[$0].substr(8)); + this.$ = $$[$0].substr(8); + break; + case 21: + yy.checkout($$[$0]); + break; + case 22: + yy.branch($$[$0]); + break; + case 23: + yy.branch($$[$0 - 2], $$[$0]); + break; + case 24: + yy.cherryPick($$[$0], "", void 0); + break; + case 25: + yy.cherryPick($$[$0 - 2], "", void 0, $$[$0]); + break; + case 26: + yy.cherryPick($$[$0 - 2], "", $$[$0]); + break; + case 27: + yy.cherryPick($$[$0 - 4], "", $$[$0], $$[$0 - 2]); + break; + case 28: + yy.cherryPick($$[$0 - 4], "", $$[$0 - 2], $$[$0]); + break; + case 29: + yy.cherryPick($$[$0], "", $$[$0 - 2]); + break; + case 30: + yy.cherryPick($$[$0], "", ""); + break; + case 31: + yy.cherryPick($$[$0 - 2], "", ""); + break; + case 32: + yy.cherryPick($$[$0 - 4], "", "", $$[$0 - 2]); + break; + case 33: + yy.cherryPick($$[$0 - 4], "", "", $$[$0]); + break; + case 34: + yy.cherryPick($$[$0 - 2], "", $$[$0 - 4], $$[$0]); + break; + case 35: + yy.cherryPick($$[$0 - 2], "", "", $$[$0]); + break; + case 36: + yy.merge($$[$0], "", "", ""); + break; + case 37: + yy.merge($$[$0 - 2], $$[$0], "", ""); + break; + case 38: + yy.merge($$[$0 - 2], "", $$[$0], ""); + break; + case 39: + yy.merge($$[$0 - 2], "", "", $$[$0]); + break; + case 40: + yy.merge($$[$0 - 4], $$[$0], "", $$[$0 - 2]); + break; + case 41: + yy.merge($$[$0 - 4], "", $$[$0], $$[$0 - 2]); + break; + case 42: + yy.merge($$[$0 - 4], "", $$[$0 - 2], $$[$0]); + break; + case 43: + yy.merge($$[$0 - 4], $$[$0 - 2], $$[$0], ""); + break; + case 44: + yy.merge($$[$0 - 4], $$[$0 - 2], "", $$[$0]); + break; + case 45: + yy.merge($$[$0 - 4], $$[$0], $$[$0 - 2], ""); + break; + case 46: + yy.merge($$[$0 - 6], $$[$0 - 4], $$[$0 - 2], $$[$0]); + break; + case 47: + yy.merge($$[$0 - 6], $$[$0], $$[$0 - 4], $$[$0 - 2]); + break; + case 48: + yy.merge($$[$0 - 6], $$[$0 - 4], $$[$0], $$[$0 - 2]); + break; + case 49: + yy.merge($$[$0 - 6], $$[$0 - 2], $$[$0 - 4], $$[$0]); + break; + case 50: + yy.merge($$[$0 - 6], $$[$0], $$[$0 - 2], $$[$0 - 4]); + break; + case 51: + yy.merge($$[$0 - 6], $$[$0 - 2], $$[$0], $$[$0 - 4]); + break; + case 52: + yy.commit($$[$0]); + break; + case 53: + yy.commit("", "", yy.commitType.NORMAL, $$[$0]); + break; + case 54: + yy.commit("", "", $$[$0], ""); + break; + case 55: + yy.commit("", "", $$[$0], $$[$0 - 2]); + break; + case 56: + yy.commit("", "", $$[$0 - 2], $$[$0]); + break; + case 57: + yy.commit("", $$[$0], yy.commitType.NORMAL, ""); + break; + case 58: + yy.commit("", $$[$0 - 2], yy.commitType.NORMAL, $$[$0]); + break; + case 59: + yy.commit("", $$[$0], yy.commitType.NORMAL, $$[$0 - 2]); + break; + case 60: + yy.commit("", $$[$0 - 2], $$[$0], ""); + break; + case 61: + yy.commit("", $$[$0], $$[$0 - 2], ""); + break; + case 62: + yy.commit("", $$[$0 - 4], $$[$0 - 2], $$[$0]); + break; + case 63: + yy.commit("", $$[$0 - 4], $$[$0], $$[$0 - 2]); + break; + case 64: + yy.commit("", $$[$0 - 2], $$[$0 - 4], $$[$0]); + break; + case 65: + yy.commit("", $$[$0], $$[$0 - 4], $$[$0 - 2]); + break; + case 66: + yy.commit("", $$[$0], $$[$0 - 2], $$[$0 - 4]); + break; + case 67: + yy.commit("", $$[$0 - 2], $$[$0], $$[$0 - 4]); + break; + case 68: + yy.commit($$[$0], "", yy.commitType.NORMAL, ""); + break; + case 69: + yy.commit($$[$0], "", yy.commitType.NORMAL, $$[$0 - 2]); + break; + case 70: + yy.commit($$[$0 - 2], "", yy.commitType.NORMAL, $$[$0]); + break; + case 71: + yy.commit($$[$0 - 2], "", $$[$0], ""); + break; + case 72: + yy.commit($$[$0], "", $$[$0 - 2], ""); + break; + case 73: + yy.commit($$[$0], $$[$0 - 2], yy.commitType.NORMAL, ""); + break; + case 74: + yy.commit($$[$0 - 2], $$[$0], yy.commitType.NORMAL, ""); + break; + case 75: + yy.commit($$[$0 - 4], "", $$[$0 - 2], $$[$0]); + break; + case 76: + yy.commit($$[$0 - 4], "", $$[$0], $$[$0 - 2]); + break; + case 77: + yy.commit($$[$0 - 2], "", $$[$0 - 4], $$[$0]); + break; + case 78: + yy.commit($$[$0], "", $$[$0 - 4], $$[$0 - 2]); + break; + case 79: + yy.commit($$[$0], "", $$[$0 - 2], $$[$0 - 4]); + break; + case 80: + yy.commit($$[$0 - 2], "", $$[$0], $$[$0 - 4]); + break; + case 81: + yy.commit($$[$0 - 4], $$[$0], $$[$0 - 2], ""); + break; + case 82: + yy.commit($$[$0 - 4], $$[$0 - 2], $$[$0], ""); + break; + case 83: + yy.commit($$[$0 - 2], $$[$0], $$[$0 - 4], ""); + break; + case 84: + yy.commit($$[$0], $$[$0 - 2], $$[$0 - 4], ""); + break; + case 85: + yy.commit($$[$0], $$[$0 - 4], $$[$0 - 2], ""); + break; + case 86: + yy.commit($$[$0 - 2], $$[$0 - 4], $$[$0], ""); + break; + case 87: + yy.commit($$[$0 - 4], $$[$0], yy.commitType.NORMAL, $$[$0 - 2]); + break; + case 88: + yy.commit($$[$0 - 4], $$[$0 - 2], yy.commitType.NORMAL, $$[$0]); + break; + case 89: + yy.commit($$[$0 - 2], $$[$0], yy.commitType.NORMAL, $$[$0 - 4]); + break; + case 90: + yy.commit($$[$0], $$[$0 - 2], yy.commitType.NORMAL, $$[$0 - 4]); + break; + case 91: + yy.commit($$[$0], $$[$0 - 4], yy.commitType.NORMAL, $$[$0 - 2]); + break; + case 92: + yy.commit($$[$0 - 2], $$[$0 - 4], yy.commitType.NORMAL, $$[$0]); + break; + case 93: + yy.commit($$[$0 - 6], $$[$0 - 4], $$[$0 - 2], $$[$0]); + break; + case 94: + yy.commit($$[$0 - 6], $$[$0 - 4], $$[$0], $$[$0 - 2]); + break; + case 95: + yy.commit($$[$0 - 6], $$[$0 - 2], $$[$0 - 4], $$[$0]); + break; + case 96: + yy.commit($$[$0 - 6], $$[$0], $$[$0 - 4], $$[$0 - 2]); + break; + case 97: + yy.commit($$[$0 - 6], $$[$0 - 2], $$[$0], $$[$0 - 4]); + break; + case 98: + yy.commit($$[$0 - 6], $$[$0], $$[$0 - 2], $$[$0 - 4]); + break; + case 99: + yy.commit($$[$0 - 4], $$[$0 - 6], $$[$0 - 2], $$[$0]); + break; + case 100: + yy.commit($$[$0 - 4], $$[$0 - 6], $$[$0], $$[$0 - 2]); + break; + case 101: + yy.commit($$[$0 - 2], $$[$0 - 6], $$[$0 - 4], $$[$0]); + break; + case 102: + yy.commit($$[$0], $$[$0 - 6], $$[$0 - 4], $$[$0 - 2]); + break; + case 103: + yy.commit($$[$0 - 2], $$[$0 - 6], $$[$0], $$[$0 - 4]); + break; + case 104: + yy.commit($$[$0], $$[$0 - 6], $$[$0 - 2], $$[$0 - 4]); + break; + case 105: + yy.commit($$[$0], $$[$0 - 4], $$[$0 - 2], $$[$0 - 6]); + break; + case 106: + yy.commit($$[$0 - 2], $$[$0 - 4], $$[$0], $$[$0 - 6]); + break; + case 107: + yy.commit($$[$0], $$[$0 - 2], $$[$0 - 4], $$[$0 - 6]); + break; + case 108: + yy.commit($$[$0 - 2], $$[$0], $$[$0 - 4], $$[$0 - 6]); + break; + case 109: + yy.commit($$[$0 - 4], $$[$0 - 2], $$[$0], $$[$0 - 6]); + break; + case 110: + yy.commit($$[$0 - 4], $$[$0], $$[$0 - 2], $$[$0 - 6]); + break; + case 111: + yy.commit($$[$0 - 2], $$[$0 - 4], $$[$0 - 6], $$[$0]); + break; + case 112: + yy.commit($$[$0], $$[$0 - 4], $$[$0 - 6], $$[$0 - 2]); + break; + case 113: + yy.commit($$[$0 - 2], $$[$0], $$[$0 - 6], $$[$0 - 4]); + break; + case 114: + yy.commit($$[$0], $$[$0 - 2], $$[$0 - 6], $$[$0 - 4]); + break; + case 115: + yy.commit($$[$0 - 4], $$[$0 - 2], $$[$0 - 6], $$[$0]); + break; + case 116: + yy.commit($$[$0 - 4], $$[$0], $$[$0 - 6], $$[$0 - 2]); + break; + case 117: + this.$ = ""; + break; + case 118: + this.$ = $$[$0]; + break; + case 119: + this.$ = yy.commitType.NORMAL; + break; + case 120: + this.$ = yy.commitType.REVERSE; + break; + case 121: + this.$ = yy.commitType.HIGHLIGHT; + break; + } + }, + table: [{ 3: 1, 4: 2, 5: $V0, 7: $V1, 13: $V2, 47: $V3 }, { 1: [3] }, { 3: 7, 4: 2, 5: $V0, 7: $V1, 13: $V2, 47: $V3 }, { 6: 8, 7: $V4, 8: [1, 9], 9: [1, 10], 10: 11, 13: $V5 }, o($V6, [2, 124]), o($V6, [2, 125]), o($V6, [2, 126]), { 1: [2, 1] }, { 7: [1, 13] }, { 6: 14, 7: $V4, 10: 11, 13: $V5 }, { 8: [1, 15] }, o($V7, [2, 9], { 11: 16, 12: [1, 17] }), o($V8, [2, 8]), { 1: [2, 2] }, { 7: [1, 18] }, { 6: 19, 7: $V4, 10: 11, 13: $V5 }, { 7: [2, 6], 13: [1, 22], 14: 20, 15: 21, 16: 23, 17: 24, 18: 25, 19: [1, 26], 21: [1, 27], 23: [1, 28], 24: [1, 29], 25: 30, 26: [1, 31], 28: [1, 35], 31: [1, 34], 37: [1, 33], 40: [1, 32] }, o($V8, [2, 7]), { 1: [2, 3] }, { 7: [1, 36] }, o($V7, [2, 10]), { 4: 37, 7: $V1, 13: $V2, 47: $V3 }, o($V7, [2, 12]), o($V9, [2, 13]), o($V9, [2, 14]), o($V9, [2, 15]), { 20: [1, 38] }, { 22: [1, 39] }, o($V9, [2, 18]), o($V9, [2, 19]), o($V9, [2, 20]), { 27: 40, 33: $Va, 46: $Vb }, o($V9, [2, 117], { 41: 43, 32: [1, 46], 33: [1, 48], 35: [1, 44], 38: [1, 45], 42: [1, 47] }), { 27: 49, 33: $Va, 46: $Vb }, { 32: [1, 50], 35: [1, 51] }, { 27: 52, 33: $Va, 46: $Vb }, { 1: [2, 4] }, o($V7, [2, 11]), o($V9, [2, 16]), o($V9, [2, 17]), o($V9, [2, 21]), o($Vc, [2, 122]), o($Vc, [2, 123]), o($V9, [2, 52]), { 33: [1, 53] }, { 39: 54, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 58] }, { 33: [1, 59] }, o($V9, [2, 118]), o($V9, [2, 36], { 32: [1, 60], 35: [1, 62], 38: [1, 61] }), { 33: [1, 63] }, { 33: [1, 64], 36: [1, 65] }, o($V9, [2, 22], { 29: [1, 66] }), o($V9, [2, 53], { 32: [1, 68], 38: [1, 67], 42: [1, 69] }), o($V9, [2, 54], { 32: [1, 71], 35: [1, 70], 42: [1, 72] }), o($Vg, [2, 119]), o($Vg, [2, 120]), o($Vg, [2, 121]), o($V9, [2, 57], { 35: [1, 73], 38: [1, 74], 42: [1, 75] }), o($V9, [2, 68], { 32: [1, 78], 35: [1, 76], 38: [1, 77] }), { 33: [1, 79] }, { 39: 80, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 81] }, o($V9, [2, 24], { 34: [1, 82], 35: [1, 83] }), { 32: [1, 84] }, { 32: [1, 85] }, { 30: [1, 86] }, { 39: 87, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 88] }, { 33: [1, 89] }, { 33: [1, 90] }, { 33: [1, 91] }, { 33: [1, 92] }, { 33: [1, 93] }, { 39: 94, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 95] }, { 33: [1, 96] }, { 39: 97, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 98] }, o($V9, [2, 37], { 35: [1, 100], 38: [1, 99] }), o($V9, [2, 38], { 32: [1, 102], 35: [1, 101] }), o($V9, [2, 39], { 32: [1, 103], 38: [1, 104] }), { 33: [1, 105] }, { 33: [1, 106], 36: [1, 107] }, { 33: [1, 108] }, { 33: [1, 109] }, o($V9, [2, 23]), o($V9, [2, 55], { 32: [1, 110], 42: [1, 111] }), o($V9, [2, 59], { 38: [1, 112], 42: [1, 113] }), o($V9, [2, 69], { 32: [1, 115], 38: [1, 114] }), o($V9, [2, 56], { 32: [1, 116], 42: [1, 117] }), o($V9, [2, 61], { 35: [1, 118], 42: [1, 119] }), o($V9, [2, 72], { 32: [1, 121], 35: [1, 120] }), o($V9, [2, 58], { 38: [1, 122], 42: [1, 123] }), o($V9, [2, 60], { 35: [1, 124], 42: [1, 125] }), o($V9, [2, 73], { 35: [1, 127], 38: [1, 126] }), o($V9, [2, 70], { 32: [1, 129], 38: [1, 128] }), o($V9, [2, 71], { 32: [1, 131], 35: [1, 130] }), o($V9, [2, 74], { 35: [1, 133], 38: [1, 132] }), { 39: 134, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 135] }, { 33: [1, 136] }, { 33: [1, 137] }, { 33: [1, 138] }, { 39: 139, 43: $Vd, 44: $Ve, 45: $Vf }, o($V9, [2, 25], { 35: [1, 140] }), o($V9, [2, 26], { 34: [1, 141] }), o($V9, [2, 31], { 34: [1, 142] }), o($V9, [2, 29], { 34: [1, 143] }), o($V9, [2, 30], { 34: [1, 144] }), { 33: [1, 145] }, { 33: [1, 146] }, { 39: 147, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 148] }, { 39: 149, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 150] }, { 33: [1, 151] }, { 33: [1, 152] }, { 33: [1, 153] }, { 33: [1, 154] }, { 33: [1, 155] }, { 33: [1, 156] }, { 39: 157, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 158] }, { 33: [1, 159] }, { 33: [1, 160] }, { 39: 161, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 162] }, { 39: 163, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 164] }, { 33: [1, 165] }, { 33: [1, 166] }, { 39: 167, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 168] }, o($V9, [2, 43], { 35: [1, 169] }), o($V9, [2, 44], { 38: [1, 170] }), o($V9, [2, 42], { 32: [1, 171] }), o($V9, [2, 45], { 35: [1, 172] }), o($V9, [2, 40], { 38: [1, 173] }), o($V9, [2, 41], { 32: [1, 174] }), { 33: [1, 175], 36: [1, 176] }, { 33: [1, 177] }, { 33: [1, 178] }, { 33: [1, 179] }, { 33: [1, 180] }, o($V9, [2, 66], { 42: [1, 181] }), o($V9, [2, 79], { 32: [1, 182] }), o($V9, [2, 67], { 42: [1, 183] }), o($V9, [2, 90], { 38: [1, 184] }), o($V9, [2, 80], { 32: [1, 185] }), o($V9, [2, 89], { 38: [1, 186] }), o($V9, [2, 65], { 42: [1, 187] }), o($V9, [2, 78], { 32: [1, 188] }), o($V9, [2, 64], { 42: [1, 189] }), o($V9, [2, 84], { 35: [1, 190] }), o($V9, [2, 77], { 32: [1, 191] }), o($V9, [2, 83], { 35: [1, 192] }), o($V9, [2, 63], { 42: [1, 193] }), o($V9, [2, 91], { 38: [1, 194] }), o($V9, [2, 62], { 42: [1, 195] }), o($V9, [2, 85], { 35: [1, 196] }), o($V9, [2, 86], { 35: [1, 197] }), o($V9, [2, 92], { 38: [1, 198] }), o($V9, [2, 76], { 32: [1, 199] }), o($V9, [2, 87], { 38: [1, 200] }), o($V9, [2, 75], { 32: [1, 201] }), o($V9, [2, 81], { 35: [1, 202] }), o($V9, [2, 82], { 35: [1, 203] }), o($V9, [2, 88], { 38: [1, 204] }), { 33: [1, 205] }, { 39: 206, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 207] }, { 33: [1, 208] }, { 39: 209, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 210] }, o($V9, [2, 27]), o($V9, [2, 32]), o($V9, [2, 28]), o($V9, [2, 33]), o($V9, [2, 34]), o($V9, [2, 35]), { 33: [1, 211] }, { 33: [1, 212] }, { 33: [1, 213] }, { 39: 214, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 215] }, { 39: 216, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 217] }, { 33: [1, 218] }, { 33: [1, 219] }, { 33: [1, 220] }, { 33: [1, 221] }, { 33: [1, 222] }, { 33: [1, 223] }, { 39: 224, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 225] }, { 33: [1, 226] }, { 33: [1, 227] }, { 39: 228, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 229] }, { 39: 230, 43: $Vd, 44: $Ve, 45: $Vf }, { 33: [1, 231] }, { 33: [1, 232] }, { 33: [1, 233] }, { 39: 234, 43: $Vd, 44: $Ve, 45: $Vf }, o($V9, [2, 46]), o($V9, [2, 48]), o($V9, [2, 47]), o($V9, [2, 49]), o($V9, [2, 51]), o($V9, [2, 50]), o($V9, [2, 107]), o($V9, [2, 108]), o($V9, [2, 105]), o($V9, [2, 106]), o($V9, [2, 110]), o($V9, [2, 109]), o($V9, [2, 114]), o($V9, [2, 113]), o($V9, [2, 112]), o($V9, [2, 111]), o($V9, [2, 116]), o($V9, [2, 115]), o($V9, [2, 104]), o($V9, [2, 103]), o($V9, [2, 102]), o($V9, [2, 101]), o($V9, [2, 99]), o($V9, [2, 100]), o($V9, [2, 98]), o($V9, [2, 97]), o($V9, [2, 96]), o($V9, [2, 95]), o($V9, [2, 93]), o($V9, [2, 94])], + defaultActions: { 7: [2, 1], 13: [2, 2], 18: [2, 3], 36: [2, 4] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.begin("acc_title"); + return 19; + case 1: + this.popState(); + return "acc_title_value"; + case 2: + this.begin("acc_descr"); + return 21; + case 3: + this.popState(); + return "acc_descr_value"; + case 4: + this.begin("acc_descr_multiline"); + break; + case 5: + this.popState(); + break; + case 6: + return "acc_descr_multiline_value"; + case 7: + return 13; + case 8: + break; + case 9: + break; + case 10: + return 5; + case 11: + return 40; + case 12: + return 32; + case 13: + return 38; + case 14: + return 42; + case 15: + return 43; + case 16: + return 44; + case 17: + return 45; + case 18: + return 35; + case 19: + return 28; + case 20: + return 29; + case 21: + return 37; + case 22: + return 31; + case 23: + return 34; + case 24: + return 26; + case 25: + return 9; + case 26: + return 9; + case 27: + return 8; + case 28: + return "CARET"; + case 29: + this.begin("options"); + break; + case 30: + this.popState(); + break; + case 31: + return 12; + case 32: + return 36; + case 33: + this.begin("string"); + break; + case 34: + this.popState(); + break; + case 35: + return 33; + case 36: + return 30; + case 37: + return 46; + case 38: + return 7; + } + }, + rules: [/^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:(\r?\n)+)/i, /^(?:#[^\n]*)/i, /^(?:%[^\n]*)/i, /^(?:gitGraph\b)/i, /^(?:commit(?=\s|$))/i, /^(?:id:)/i, /^(?:type:)/i, /^(?:msg:)/i, /^(?:NORMAL\b)/i, /^(?:REVERSE\b)/i, /^(?:HIGHLIGHT\b)/i, /^(?:tag:)/i, /^(?:branch(?=\s|$))/i, /^(?:order:)/i, /^(?:merge(?=\s|$))/i, /^(?:cherry-pick(?=\s|$))/i, /^(?:parent:)/i, /^(?:checkout(?=\s|$))/i, /^(?:LR\b)/i, /^(?:TB\b)/i, /^(?::)/i, /^(?:\^)/i, /^(?:options\r?\n)/i, /^(?:[ \r\n\t]+end\b)/i, /^(?:[\s\S]+(?=[ \r\n\t]+end))/i, /^(?:["]["])/i, /^(?:["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:[0-9]+(?=\s|$))/i, /^(?:\w([-\./\w]*[-\w])?)/i, /^(?:$)/i, /^(?:\s+)/i], + conditions: { "acc_descr_multiline": { "rules": [5, 6], "inclusive": false }, "acc_descr": { "rules": [3], "inclusive": false }, "acc_title": { "rules": [1], "inclusive": false }, "options": { "rules": [30, 31], "inclusive": false }, "string": { "rules": [34, 35], "inclusive": false }, "INITIAL": { "rules": [0, 2, 4, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 36, 37, 38, 39], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const gitGraphParser = parser; +let mainBranchName = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph.mainBranchName; +let mainBranchOrder = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph.mainBranchOrder; +let commits = {}; +let head = null; +let branchesConfig = {}; +branchesConfig[mainBranchName] = { name: mainBranchName, order: mainBranchOrder }; +let branches = {}; +branches[mainBranchName] = head; +let curBranch = mainBranchName; +let direction = "LR"; +let seq = 0; +function getId() { + return (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.y)({ length: 7 }); +} +function uniqBy(list, fn) { + const recordMap = /* @__PURE__ */ Object.create(null); + return list.reduce((out, item) => { + const key = fn(item); + if (!recordMap[key]) { + recordMap[key] = true; + out.push(item); + } + return out; + }, []); +} +const setDirection = function(dir2) { + direction = dir2; +}; +let options = {}; +const setOptions = function(rawOptString) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("options str", rawOptString); + rawOptString = rawOptString && rawOptString.trim(); + rawOptString = rawOptString || "{}"; + try { + options = JSON.parse(rawOptString); + } catch (e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error("error while parsing gitGraph options", e.message); + } +}; +const getOptions = function() { + return options; +}; +const commit = function(msg, id, type, tag) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Entering commit:", msg, id, type, tag); + id = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(id, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + msg = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(msg, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + tag = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(tag, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + const commit2 = { + id: id ? id : seq + "-" + getId(), + message: msg, + seq: seq++, + type: type ? type : commitType$1.NORMAL, + tag: tag ? tag : "", + parents: head == null ? [] : [head.id], + branch: curBranch + }; + head = commit2; + commits[commit2.id] = commit2; + branches[curBranch] = commit2.id; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("in pushCommit " + commit2.id); +}; +const branch = function(name, order) { + name = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(name, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + if (branches[name] === void 0) { + branches[name] = head != null ? head.id : null; + branchesConfig[name] = { name, order: order ? parseInt(order, 10) : null }; + checkout(name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("in createBranch"); + } else { + let error = new Error( + 'Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout ' + name + '")' + ); + error.hash = { + text: "branch " + name, + token: "branch " + name, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ['"checkout ' + name + '"'] + }; + throw error; + } +}; +const merge = function(otherBranch, custom_id, override_type, custom_tag) { + otherBranch = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(otherBranch, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + custom_id = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(custom_id, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + const currentCommit = commits[branches[curBranch]]; + const otherCommit = commits[branches[otherBranch]]; + if (curBranch === otherBranch) { + let error = new Error('Incorrect usage of "merge". Cannot merge a branch to itself'); + error.hash = { + text: "merge " + otherBranch, + token: "merge " + otherBranch, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["branch abc"] + }; + throw error; + } else if (currentCommit === void 0 || !currentCommit) { + let error = new Error( + 'Incorrect usage of "merge". Current branch (' + curBranch + ")has no commits" + ); + error.hash = { + text: "merge " + otherBranch, + token: "merge " + otherBranch, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["commit"] + }; + throw error; + } else if (branches[otherBranch] === void 0) { + let error = new Error( + 'Incorrect usage of "merge". Branch to be merged (' + otherBranch + ") does not exist" + ); + error.hash = { + text: "merge " + otherBranch, + token: "merge " + otherBranch, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["branch " + otherBranch] + }; + throw error; + } else if (otherCommit === void 0 || !otherCommit) { + let error = new Error( + 'Incorrect usage of "merge". Branch to be merged (' + otherBranch + ") has no commits" + ); + error.hash = { + text: "merge " + otherBranch, + token: "merge " + otherBranch, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ['"commit"'] + }; + throw error; + } else if (currentCommit === otherCommit) { + let error = new Error('Incorrect usage of "merge". Both branches have same head'); + error.hash = { + text: "merge " + otherBranch, + token: "merge " + otherBranch, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["branch abc"] + }; + throw error; + } else if (custom_id && commits[custom_id] !== void 0) { + let error = new Error( + 'Incorrect usage of "merge". Commit with id:' + custom_id + " already exists, use different custom Id" + ); + error.hash = { + text: "merge " + otherBranch + custom_id + override_type + custom_tag, + token: "merge " + otherBranch + custom_id + override_type + custom_tag, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: [ + "merge " + otherBranch + " " + custom_id + "_UNIQUE " + override_type + " " + custom_tag + ] + }; + throw error; + } + const commit2 = { + id: custom_id ? custom_id : seq + "-" + getId(), + message: "merged branch " + otherBranch + " into " + curBranch, + seq: seq++, + parents: [head == null ? null : head.id, branches[otherBranch]], + branch: curBranch, + type: commitType$1.MERGE, + customType: override_type, + customId: custom_id ? true : false, + tag: custom_tag ? custom_tag : "" + }; + head = commit2; + commits[commit2.id] = commit2; + branches[curBranch] = commit2.id; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(branches); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("in mergeBranch"); +}; +const cherryPick = function(sourceId, targetId, tag, parentCommitId) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Entering cherryPick:", sourceId, targetId, tag); + sourceId = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(sourceId, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + targetId = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(targetId, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + tag = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(tag, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + parentCommitId = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(parentCommitId, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + if (!sourceId || commits[sourceId] === void 0) { + let error = new Error( + 'Incorrect usage of "cherryPick". Source commit id should exist and provided' + ); + error.hash = { + text: "cherryPick " + sourceId + " " + targetId, + token: "cherryPick " + sourceId + " " + targetId, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["cherry-pick abc"] + }; + throw error; + } + let sourceCommit = commits[sourceId]; + let sourceCommitBranch = sourceCommit.branch; + if (parentCommitId && !(Array.isArray(sourceCommit.parents) && sourceCommit.parents.includes(parentCommitId))) { + let error = new Error( + "Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit." + ); + throw error; + } + if (sourceCommit.type === commitType$1.MERGE && !parentCommitId) { + let error = new Error( + "Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified." + ); + throw error; + } + if (!targetId || commits[targetId] === void 0) { + if (sourceCommitBranch === curBranch) { + let error = new Error( + 'Incorrect usage of "cherryPick". Source commit is already on current branch' + ); + error.hash = { + text: "cherryPick " + sourceId + " " + targetId, + token: "cherryPick " + sourceId + " " + targetId, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["cherry-pick abc"] + }; + throw error; + } + const currentCommit = commits[branches[curBranch]]; + if (currentCommit === void 0 || !currentCommit) { + let error = new Error( + 'Incorrect usage of "cherry-pick". Current branch (' + curBranch + ")has no commits" + ); + error.hash = { + text: "cherryPick " + sourceId + " " + targetId, + token: "cherryPick " + sourceId + " " + targetId, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["cherry-pick abc"] + }; + throw error; + } + const commit2 = { + id: seq + "-" + getId(), + message: "cherry-picked " + sourceCommit + " into " + curBranch, + seq: seq++, + parents: [head == null ? null : head.id, sourceCommit.id], + branch: curBranch, + type: commitType$1.CHERRY_PICK, + tag: tag ?? `cherry-pick:${sourceCommit.id}${sourceCommit.type === commitType$1.MERGE ? `|parent:${parentCommitId}` : ""}` + }; + head = commit2; + commits[commit2.id] = commit2; + branches[curBranch] = commit2.id; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(branches); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("in cherryPick"); + } +}; +const checkout = function(branch2) { + branch2 = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(branch2, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + if (branches[branch2] === void 0) { + let error = new Error( + 'Trying to checkout branch which is not yet created. (Help try using "branch ' + branch2 + '")' + ); + error.hash = { + text: "checkout " + branch2, + token: "checkout " + branch2, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ['"branch ' + branch2 + '"'] + }; + throw error; + } else { + curBranch = branch2; + const id = branches[curBranch]; + head = commits[id]; + } +}; +function upsert(arr, key, newVal) { + const index = arr.indexOf(key); + if (index === -1) { + arr.push(newVal); + } else { + arr.splice(index, 1, newVal); + } +} +function prettyPrintCommitHistory(commitArr) { + const commit2 = commitArr.reduce((out, commit3) => { + if (out.seq > commit3.seq) { + return out; + } + return commit3; + }, commitArr[0]); + let line = ""; + commitArr.forEach(function(c) { + if (c === commit2) { + line += " *"; + } else { + line += " |"; + } + }); + const label = [line, commit2.id, commit2.seq]; + for (let branch2 in branches) { + if (branches[branch2] === commit2.id) { + label.push(branch2); + } + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(label.join(" ")); + if (commit2.parents && commit2.parents.length == 2) { + const newCommit = commits[commit2.parents[0]]; + upsert(commitArr, commit2, newCommit); + commitArr.push(commits[commit2.parents[1]]); + } else if (commit2.parents.length == 0) { + return; + } else { + const nextCommit = commits[commit2.parents]; + upsert(commitArr, commit2, nextCommit); + } + commitArr = uniqBy(commitArr, (c) => c.id); + prettyPrintCommitHistory(commitArr); +} +const prettyPrint = function() { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(commits); + const node = getCommitsArray()[0]; + prettyPrintCommitHistory([node]); +}; +const clear$1 = function() { + commits = {}; + head = null; + let mainBranch = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph.mainBranchName; + let mainBranchOrder2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph.mainBranchOrder; + branches = {}; + branches[mainBranch] = null; + branchesConfig = {}; + branchesConfig[mainBranch] = { name: mainBranch, order: mainBranchOrder2 }; + curBranch = mainBranch; + seq = 0; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.v)(); +}; +const getBranchesAsObjArray = function() { + const branchesArray = Object.values(branchesConfig).map((branchConfig, i) => { + if (branchConfig.order !== null) { + return branchConfig; + } + return { + ...branchConfig, + order: parseFloat(`0.${i}`, 10) + }; + }).sort((a, b) => a.order - b.order).map(({ name }) => ({ name })); + return branchesArray; +}; +const getBranches = function() { + return branches; +}; +const getCommits = function() { + return commits; +}; +const getCommitsArray = function() { + const commitArr = Object.keys(commits).map(function(key) { + return commits[key]; + }); + commitArr.forEach(function(o) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(o.id); + }); + commitArr.sort((a, b) => a.seq - b.seq); + return commitArr; +}; +const getCurrentBranch = function() { + return curBranch; +}; +const getDirection = function() { + return direction; +}; +const getHead = function() { + return head; +}; +const commitType$1 = { + NORMAL: 0, + REVERSE: 1, + HIGHLIGHT: 2, + MERGE: 3, + CHERRY_PICK: 4 +}; +const gitGraphDb = { + getConfig: () => (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph, + setDirection, + setOptions, + getOptions, + commit, + branch, + merge, + cherryPick, + checkout, + //reset, + prettyPrint, + clear: clear$1, + getBranchesAsObjArray, + getBranches, + getCommits, + getCommitsArray, + getCurrentBranch, + getDirection, + getHead, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.g, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.a, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.b, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.t, + commitType: commitType$1 +}; +let allCommitsDict = {}; +const commitType = { + NORMAL: 0, + REVERSE: 1, + HIGHLIGHT: 2, + MERGE: 3, + CHERRY_PICK: 4 +}; +const THEME_COLOR_LIMIT = 8; +let branchPos = {}; +let commitPos = {}; +let lanes = []; +let maxPos = 0; +let dir = "LR"; +const clear = () => { + branchPos = {}; + commitPos = {}; + allCommitsDict = {}; + maxPos = 0; + lanes = []; + dir = "LR"; +}; +const drawText = (txt) => { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + let rows = []; + if (typeof txt === "string") { + rows = txt.split(/\\n|\n|<br\s*\/?>/gi); + } else if (Array.isArray(txt)) { + rows = txt; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + tspan.setAttribute("class", "row"); + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; +}; +const findClosestParent = (parents) => { + let closestParent = ""; + let maxPosition = 0; + parents.forEach((parent) => { + const parentPosition = dir === "TB" ? commitPos[parent].y : commitPos[parent].x; + if (parentPosition >= maxPosition) { + closestParent = parent; + maxPosition = parentPosition; + } + }); + return closestParent || void 0; +}; +const drawCommits = (svg, commits2, modifyGraph) => { + const gitGraphConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph; + const gBullets = svg.append("g").attr("class", "commit-bullets"); + const gLabels = svg.append("g").attr("class", "commit-labels"); + let pos = 0; + if (dir === "TB") { + pos = 30; + } + const keys = Object.keys(commits2); + const sortedKeys = keys.sort((a, b) => { + return commits2[a].seq - commits2[b].seq; + }); + const isParallelCommits = gitGraphConfig.parallelCommits; + const layoutOffset = 10; + const commitStep = 40; + sortedKeys.forEach((key) => { + const commit2 = commits2[key]; + if (isParallelCommits) { + if (commit2.parents.length) { + const closestParent = findClosestParent(commit2.parents); + pos = dir === "TB" ? commitPos[closestParent].y + commitStep : commitPos[closestParent].x + commitStep; + } else { + pos = 0; + if (dir === "TB") { + pos = 30; + } + } + } + const posWithOffset = pos + layoutOffset; + const y = dir === "TB" ? posWithOffset : branchPos[commit2.branch].pos; + const x = dir === "TB" ? branchPos[commit2.branch].pos : posWithOffset; + if (modifyGraph) { + let typeClass; + let commitSymbolType = commit2.customType !== void 0 && commit2.customType !== "" ? commit2.customType : commit2.type; + switch (commitSymbolType) { + case commitType.NORMAL: + typeClass = "commit-normal"; + break; + case commitType.REVERSE: + typeClass = "commit-reverse"; + break; + case commitType.HIGHLIGHT: + typeClass = "commit-highlight"; + break; + case commitType.MERGE: + typeClass = "commit-merge"; + break; + case commitType.CHERRY_PICK: + typeClass = "commit-cherry-pick"; + break; + default: + typeClass = "commit-normal"; + } + if (commitSymbolType === commitType.HIGHLIGHT) { + const circle = gBullets.append("rect"); + circle.attr("x", x - 10); + circle.attr("y", y - 10); + circle.attr("height", 20); + circle.attr("width", 20); + circle.attr( + "class", + `commit ${commit2.id} commit-highlight${branchPos[commit2.branch].index % THEME_COLOR_LIMIT} ${typeClass}-outer` + ); + gBullets.append("rect").attr("x", x - 6).attr("y", y - 6).attr("height", 12).attr("width", 12).attr( + "class", + `commit ${commit2.id} commit${branchPos[commit2.branch].index % THEME_COLOR_LIMIT} ${typeClass}-inner` + ); + } else if (commitSymbolType === commitType.CHERRY_PICK) { + gBullets.append("circle").attr("cx", x).attr("cy", y).attr("r", 10).attr("class", `commit ${commit2.id} ${typeClass}`); + gBullets.append("circle").attr("cx", x - 3).attr("cy", y + 2).attr("r", 2.75).attr("fill", "#fff").attr("class", `commit ${commit2.id} ${typeClass}`); + gBullets.append("circle").attr("cx", x + 3).attr("cy", y + 2).attr("r", 2.75).attr("fill", "#fff").attr("class", `commit ${commit2.id} ${typeClass}`); + gBullets.append("line").attr("x1", x + 3).attr("y1", y + 1).attr("x2", x).attr("y2", y - 5).attr("stroke", "#fff").attr("class", `commit ${commit2.id} ${typeClass}`); + gBullets.append("line").attr("x1", x - 3).attr("y1", y + 1).attr("x2", x).attr("y2", y - 5).attr("stroke", "#fff").attr("class", `commit ${commit2.id} ${typeClass}`); + } else { + const circle = gBullets.append("circle"); + circle.attr("cx", x); + circle.attr("cy", y); + circle.attr("r", commit2.type === commitType.MERGE ? 9 : 10); + circle.attr( + "class", + `commit ${commit2.id} commit${branchPos[commit2.branch].index % THEME_COLOR_LIMIT}` + ); + if (commitSymbolType === commitType.MERGE) { + const circle2 = gBullets.append("circle"); + circle2.attr("cx", x); + circle2.attr("cy", y); + circle2.attr("r", 6); + circle2.attr( + "class", + `commit ${typeClass} ${commit2.id} commit${branchPos[commit2.branch].index % THEME_COLOR_LIMIT}` + ); + } + if (commitSymbolType === commitType.REVERSE) { + const cross = gBullets.append("path"); + cross.attr("d", `M ${x - 5},${y - 5}L${x + 5},${y + 5}M${x - 5},${y + 5}L${x + 5},${y - 5}`).attr( + "class", + `commit ${typeClass} ${commit2.id} commit${branchPos[commit2.branch].index % THEME_COLOR_LIMIT}` + ); + } + } + } + if (dir === "TB") { + commitPos[commit2.id] = { x, y: posWithOffset }; + } else { + commitPos[commit2.id] = { x: posWithOffset, y }; + } + if (modifyGraph) { + const px = 4; + const py = 2; + if (commit2.type !== commitType.CHERRY_PICK && (commit2.customId && commit2.type === commitType.MERGE || commit2.type !== commitType.MERGE) && gitGraphConfig.showCommitLabel) { + const wrapper = gLabels.append("g"); + const labelBkg = wrapper.insert("rect").attr("class", "commit-label-bkg"); + const text = wrapper.append("text").attr("x", pos).attr("y", y + 25).attr("class", "commit-label").text(commit2.id); + let bbox = text.node().getBBox(); + labelBkg.attr("x", posWithOffset - bbox.width / 2 - py).attr("y", y + 13.5).attr("width", bbox.width + 2 * py).attr("height", bbox.height + 2 * py); + if (dir === "TB") { + labelBkg.attr("x", x - (bbox.width + 4 * px + 5)).attr("y", y - 12); + text.attr("x", x - (bbox.width + 4 * px)).attr("y", y + bbox.height - 12); + } + if (dir !== "TB") { + text.attr("x", posWithOffset - bbox.width / 2); + } + if (gitGraphConfig.rotateCommitLabel) { + if (dir === "TB") { + text.attr("transform", "rotate(-45, " + x + ", " + y + ")"); + labelBkg.attr("transform", "rotate(-45, " + x + ", " + y + ")"); + } else { + let r_x = -7.5 - (bbox.width + 10) / 25 * 9.5; + let r_y = 10 + bbox.width / 25 * 8.5; + wrapper.attr( + "transform", + "translate(" + r_x + ", " + r_y + ") rotate(-45, " + pos + ", " + y + ")" + ); + } + } + } + if (commit2.tag) { + const rect = gLabels.insert("polygon"); + const hole = gLabels.append("circle"); + const tag = gLabels.append("text").attr("y", y - 16).attr("class", "tag-label").text(commit2.tag); + let tagBbox = tag.node().getBBox(); + tag.attr("x", posWithOffset - tagBbox.width / 2); + const h2 = tagBbox.height / 2; + const ly = y - 19.2; + rect.attr("class", "tag-label-bkg").attr( + "points", + ` + ${pos - tagBbox.width / 2 - px / 2},${ly + py} + ${pos - tagBbox.width / 2 - px / 2},${ly - py} + ${posWithOffset - tagBbox.width / 2 - px},${ly - h2 - py} + ${posWithOffset + tagBbox.width / 2 + px},${ly - h2 - py} + ${posWithOffset + tagBbox.width / 2 + px},${ly + h2 + py} + ${posWithOffset - tagBbox.width / 2 - px},${ly + h2 + py}` + ); + hole.attr("cx", pos - tagBbox.width / 2 + px / 2).attr("cy", ly).attr("r", 1.5).attr("class", "tag-hole"); + if (dir === "TB") { + rect.attr("class", "tag-label-bkg").attr( + "points", + ` + ${x},${pos + py} + ${x},${pos - py} + ${x + layoutOffset},${pos - h2 - py} + ${x + layoutOffset + tagBbox.width + px},${pos - h2 - py} + ${x + layoutOffset + tagBbox.width + px},${pos + h2 + py} + ${x + layoutOffset},${pos + h2 + py}` + ).attr("transform", "translate(12,12) rotate(45, " + x + "," + pos + ")"); + hole.attr("cx", x + px / 2).attr("cy", pos).attr("transform", "translate(12,12) rotate(45, " + x + "," + pos + ")"); + tag.attr("x", x + 5).attr("y", pos + 3).attr("transform", "translate(14,14) rotate(45, " + x + "," + pos + ")"); + } + } + } + pos += commitStep + layoutOffset; + if (pos > maxPos) { + maxPos = pos; + } + }); +}; +const shouldRerouteArrow = (commitA, commitB, p1, p2, allCommits) => { + const commitBIsFurthest = dir === "TB" ? p1.x < p2.x : p1.y < p2.y; + const branchToGetCurve = commitBIsFurthest ? commitB.branch : commitA.branch; + const isOnBranchToGetCurve = (x) => x.branch === branchToGetCurve; + const isBetweenCommits = (x) => x.seq > commitA.seq && x.seq < commitB.seq; + return Object.values(allCommits).some((commitX) => { + return isBetweenCommits(commitX) && isOnBranchToGetCurve(commitX); + }); +}; +const findLane = (y1, y2, depth = 0) => { + const candidate = y1 + Math.abs(y1 - y2) / 2; + if (depth > 5) { + return candidate; + } + let ok = lanes.every((lane) => Math.abs(lane - candidate) >= 10); + if (ok) { + lanes.push(candidate); + return candidate; + } + const diff = Math.abs(y1 - y2); + return findLane(y1, y2 - diff / 5, depth + 1); +}; +const drawArrow = (svg, commitA, commitB, allCommits) => { + const p1 = commitPos[commitA.id]; + const p2 = commitPos[commitB.id]; + const arrowNeedsRerouting = shouldRerouteArrow(commitA, commitB, p1, p2, allCommits); + let arc = ""; + let arc2 = ""; + let radius = 0; + let offset = 0; + let colorClassNum = branchPos[commitB.branch].index; + if (commitB.type === commitType.MERGE && commitA.id !== commitB.parents[0]) { + colorClassNum = branchPos[commitA.branch].index; + } + let lineDef; + if (arrowNeedsRerouting) { + arc = "A 10 10, 0, 0, 0,"; + arc2 = "A 10 10, 0, 0, 1,"; + radius = 10; + offset = 10; + const lineY = p1.y < p2.y ? findLane(p1.y, p2.y) : findLane(p2.y, p1.y); + const lineX = p1.x < p2.x ? findLane(p1.x, p2.x) : findLane(p2.x, p1.x); + if (dir === "TB") { + if (p1.x < p2.x) { + lineDef = `M ${p1.x} ${p1.y} L ${lineX - radius} ${p1.y} ${arc2} ${lineX} ${p1.y + offset} L ${lineX} ${p2.y - radius} ${arc} ${lineX + offset} ${p2.y} L ${p2.x} ${p2.y}`; + } else { + colorClassNum = branchPos[commitA.branch].index; + lineDef = `M ${p1.x} ${p1.y} L ${lineX + radius} ${p1.y} ${arc} ${lineX} ${p1.y + offset} L ${lineX} ${p2.y - radius} ${arc2} ${lineX - offset} ${p2.y} L ${p2.x} ${p2.y}`; + } + } else { + if (p1.y < p2.y) { + lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${lineY - radius} ${arc} ${p1.x + offset} ${lineY} L ${p2.x - radius} ${lineY} ${arc2} ${p2.x} ${lineY + offset} L ${p2.x} ${p2.y}`; + } else { + colorClassNum = branchPos[commitA.branch].index; + lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${lineY + radius} ${arc2} ${p1.x + offset} ${lineY} L ${p2.x - radius} ${lineY} ${arc} ${p2.x} ${lineY - offset} L ${p2.x} ${p2.y}`; + } + } + } else { + arc = "A 20 20, 0, 0, 0,"; + arc2 = "A 20 20, 0, 0, 1,"; + radius = 20; + offset = 20; + if (dir === "TB") { + if (p1.x < p2.x) { + if (commitB.type === commitType.MERGE && commitA.id !== commitB.parents[0]) { + lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y - radius} ${arc} ${p1.x + offset} ${p2.y} L ${p2.x} ${p2.y}`; + } else { + lineDef = `M ${p1.x} ${p1.y} L ${p2.x - radius} ${p1.y} ${arc2} ${p2.x} ${p1.y + offset} L ${p2.x} ${p2.y}`; + } + } + if (p1.x > p2.x) { + arc = "A 20 20, 0, 0, 0,"; + arc2 = "A 20 20, 0, 0, 1,"; + radius = 20; + offset = 20; + if (commitB.type === commitType.MERGE && commitA.id !== commitB.parents[0]) { + lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y - radius} ${arc2} ${p1.x - offset} ${p2.y} L ${p2.x} ${p2.y}`; + } else { + lineDef = `M ${p1.x} ${p1.y} L ${p2.x + radius} ${p1.y} ${arc} ${p2.x} ${p1.y + offset} L ${p2.x} ${p2.y}`; + } + } + if (p1.x === p2.x) { + lineDef = `M ${p1.x} ${p1.y} L ${p2.x} ${p2.y}`; + } + } else { + if (p1.y < p2.y) { + if (commitB.type === commitType.MERGE && commitA.id !== commitB.parents[0]) { + lineDef = `M ${p1.x} ${p1.y} L ${p2.x - radius} ${p1.y} ${arc2} ${p2.x} ${p1.y + offset} L ${p2.x} ${p2.y}`; + } else { + lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y - radius} ${arc} ${p1.x + offset} ${p2.y} L ${p2.x} ${p2.y}`; + } + } + if (p1.y > p2.y) { + if (commitB.type === commitType.MERGE && commitA.id !== commitB.parents[0]) { + lineDef = `M ${p1.x} ${p1.y} L ${p2.x - radius} ${p1.y} ${arc} ${p2.x} ${p1.y - offset} L ${p2.x} ${p2.y}`; + } else { + lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y + radius} ${arc2} ${p1.x + offset} ${p2.y} L ${p2.x} ${p2.y}`; + } + } + if (p1.y === p2.y) { + lineDef = `M ${p1.x} ${p1.y} L ${p2.x} ${p2.y}`; + } + } + } + svg.append("path").attr("d", lineDef).attr("class", "arrow arrow" + colorClassNum % THEME_COLOR_LIMIT); +}; +const drawArrows = (svg, commits2) => { + const gArrows = svg.append("g").attr("class", "commit-arrows"); + Object.keys(commits2).forEach((key) => { + const commit2 = commits2[key]; + if (commit2.parents && commit2.parents.length > 0) { + commit2.parents.forEach((parent) => { + drawArrow(gArrows, commits2[parent], commit2, commits2); + }); + } + }); +}; +const drawBranches = (svg, branches2) => { + const gitGraphConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph; + const g = svg.append("g"); + branches2.forEach((branch2, index) => { + const adjustIndexForTheme = index % THEME_COLOR_LIMIT; + const pos = branchPos[branch2.name].pos; + const line = g.append("line"); + line.attr("x1", 0); + line.attr("y1", pos); + line.attr("x2", maxPos); + line.attr("y2", pos); + line.attr("class", "branch branch" + adjustIndexForTheme); + if (dir === "TB") { + line.attr("y1", 30); + line.attr("x1", pos); + line.attr("y2", maxPos); + line.attr("x2", pos); + } + lanes.push(pos); + let name = branch2.name; + const labelElement = drawText(name); + const bkg = g.insert("rect"); + const branchLabel = g.insert("g").attr("class", "branchLabel"); + const label = branchLabel.insert("g").attr("class", "label branch-label" + adjustIndexForTheme); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + bkg.attr("class", "branchLabelBkg label" + adjustIndexForTheme).attr("rx", 4).attr("ry", 4).attr("x", -bbox.width - 4 - (gitGraphConfig.rotateCommitLabel === true ? 30 : 0)).attr("y", -bbox.height / 2 + 8).attr("width", bbox.width + 18).attr("height", bbox.height + 4); + label.attr( + "transform", + "translate(" + (-bbox.width - 14 - (gitGraphConfig.rotateCommitLabel === true ? 30 : 0)) + ", " + (pos - bbox.height / 2 - 1) + ")" + ); + if (dir === "TB") { + bkg.attr("x", pos - bbox.width / 2 - 10).attr("y", 0); + label.attr("transform", "translate(" + (pos - bbox.width / 2 - 5) + ", 0)"); + } + if (dir !== "TB") { + bkg.attr("transform", "translate(-19, " + (pos - bbox.height / 2) + ")"); + } + }); +}; +const draw = function(txt, id, ver, diagObj) { + clear(); + const conf = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const gitGraphConfig = conf.gitGraph; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("in gitgraph renderer", txt + "\n", "id:", id, ver); + allCommitsDict = diagObj.db.getCommits(); + const branches2 = diagObj.db.getBranchesAsObjArray(); + dir = diagObj.db.getDirection(); + const diagram2 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(`[id="${id}"]`); + let pos = 0; + branches2.forEach((branch2, index) => { + const labelElement = drawText(branch2.name); + const g = diagram2.append("g"); + const branchLabel = g.insert("g").attr("class", "branchLabel"); + const label = branchLabel.insert("g").attr("class", "label branch-label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + branchPos[branch2.name] = { pos, index }; + pos += 50 + (gitGraphConfig.rotateCommitLabel ? 40 : 0) + (dir === "TB" ? bbox.width / 2 : 0); + label.remove(); + branchLabel.remove(); + g.remove(); + }); + drawCommits(diagram2, allCommitsDict, false); + if (gitGraphConfig.showBranches) { + drawBranches(diagram2, branches2); + } + drawArrows(diagram2, allCommitsDict); + drawCommits(diagram2, allCommitsDict, true); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.u.insertTitle( + diagram2, + "gitTitleText", + gitGraphConfig.titleTopMargin, + diagObj.db.getDiagramTitle() + ); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.z)( + void 0, + diagram2, + gitGraphConfig.diagramPadding, + gitGraphConfig.useMaxWidth ?? conf.useMaxWidth + ); +}; +const gitGraphRenderer = { + draw +}; +const getStyles = (options2) => ` + .commit-id, + .commit-msg, + .branch-label { + fill: lightgrey; + color: lightgrey; + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + } + ${[0, 1, 2, 3, 4, 5, 6, 7].map( + (i) => ` + .branch-label${i} { fill: ${options2["gitBranchLabel" + i]}; } + .commit${i} { stroke: ${options2["git" + i]}; fill: ${options2["git" + i]}; } + .commit-highlight${i} { stroke: ${options2["gitInv" + i]}; fill: ${options2["gitInv" + i]}; } + .label${i} { fill: ${options2["git" + i]}; } + .arrow${i} { stroke: ${options2["git" + i]}; } + ` +).join("\n")} + + .branch { + stroke-width: 1; + stroke: ${options2.lineColor}; + stroke-dasharray: 2; + } + .commit-label { font-size: ${options2.commitLabelFontSize}; fill: ${options2.commitLabelColor};} + .commit-label-bkg { font-size: ${options2.commitLabelFontSize}; fill: ${options2.commitLabelBackground}; opacity: 0.5; } + .tag-label { font-size: ${options2.tagLabelFontSize}; fill: ${options2.tagLabelColor};} + .tag-label-bkg { fill: ${options2.tagLabelBackground}; stroke: ${options2.tagLabelBorder}; } + .tag-hole { fill: ${options2.textColor}; } + + .commit-merge { + stroke: ${options2.primaryColor}; + fill: ${options2.primaryColor}; + } + .commit-reverse { + stroke: ${options2.primaryColor}; + fill: ${options2.primaryColor}; + stroke-width: 3; + } + .commit-highlight-outer { + } + .commit-highlight-inner { + stroke: ${options2.primaryColor}; + fill: ${options2.primaryColor}; + } + + .arrow { stroke-width: 8; stroke-linecap: round; fill: none} + .gitTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options2.textColor}; + } +`; +const gitGraphStyles = getStyles; +const diagram = { + parser: gitGraphParser, + db: gitGraphDb, + renderer: gitGraphRenderer, + styles: gitGraphStyles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/50963409.9df6f406.js b/assets/js/50963409.9df6f406.js new file mode 100644 index 0000000000..2b0bbaa503 --- /dev/null +++ b/assets/js/50963409.9df6f406.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8169],{18131:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>c,toc:()=>a});var s=n(74848),o=n(28453);const r={},i="Testing",c={id:"container/components/k8s-cluster-api-provider/doc/usage/testing",title:"Testing",description:"To test the created k8s cluster, there are several tools available.",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/testing.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc/usage",slug:"/container/components/k8s-cluster-api-provider/doc/usage/testing",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/testing",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/usage/testing.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Multi-AZ and multi-cloud environments",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments"},next:{title:"Container registry configuration",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration"}},l={},a=[];function d(e){const t={a:"a",code:"code",h1:"h1",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"testing",children:"Testing"}),"\n",(0,s.jsxs)(t.p,{children:["To test the created k8s cluster, there are several tools available.\nApply all commands to the testcluster context (by passing the appropriate\n",(0,s.jsx)(t.code,{children:"--context"})," setting to ",(0,s.jsx)(t.code,{children:"kubectl"})," or by using the right ",(0,s.jsx)(t.code,{children:"KUBECONFIG"}),"\nfile)."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Looking at all pods (",(0,s.jsx)(t.code,{children:"kubectl get pods -A"}),") to see that they all come\nup (and don't suffer excessive restarts) is a good first check.\nLook at the pod logs to investigate any failures."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["You can create a very simple deployment with the provided ",(0,s.jsx)(t.code,{children:"kuard.yaml"}),', which is\nan example taken from the O\'Reilly book from B. Burns, J. Beda, K. Hightower:\n"Kubernetes Up & Running" enhanced to also use a persistent volume.']}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["You can deploy ",(0,s.jsx)(t.a,{href:"https://github.com/GoogleCloudPlatform/microservices-demo",children:"Google's demo microservice application"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"sonobuoy"})," runs a subset of the k8s tests, providing a simple way to\nfilter the >5000 existing test cases to only run the CNCF conformance\ntests or to restrict testing to non-disruptive tests. The ",(0,s.jsx)(t.code,{children:"sonobuoy.sh"})," wrapper\nhelps with calling it. There are also ",(0,s.jsx)(t.code,{children:"Makefile"})," targets ",(0,s.jsx)(t.code,{children:"check-*"})," that\ncall various ",(0,s.jsx)(t.a,{href:"https://sonobuoy.io",children:"sonobuoy"})," test sets.\nThis is how we call sonobuoy for our CI tests."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["You can use ",(0,s.jsx)(t.code,{children:"cilium connectivity test"})," to check whether your cilium\nCNI is working properly. You might need to enable hubble to get\na fully successful result."]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var s=n(96540);const o={},r=s.createContext(o);function i(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5199876b.3805c215.js b/assets/js/5199876b.3805c215.js new file mode 100644 index 0000000000..471d19dfbd --- /dev/null +++ b/assets/js/5199876b.3805c215.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3008],{82756:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>r,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>d,toc:()=>c});var t=n(74848),i=n(28453);const o={sidebar_label:"Get"},a="Get",d={id:"iaas/guides/operations-guide/manager/get",title:"Get",description:"A get command is available in the OSISM CLI. This allows to gather specific information.",source:"@site/docs/02-iaas/guides/operations-guide/manager/get.md",sourceDirName:"02-iaas/guides/operations-guide/manager",slug:"/iaas/guides/operations-guide/manager/get",permalink:"/docs/iaas/guides/operations-guide/manager/get",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/manager/get.md",tags:[],version:"current",frontMatter:{sidebar_label:"Get"},sidebar:"docs",previous:{title:"Console",permalink:"/docs/iaas/guides/operations-guide/manager/console"},next:{title:"Logging",permalink:"/docs/iaas/guides/operations-guide/manager/log"}},r={},c=[{value:"Hosts",id:"hosts",level:2},{value:"Host variables",id:"host-variables",level:2},{value:"Host facts",id:"host-facts",level:2}];function l(e){const s={code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h1,{id:"get",children:"Get"}),"\n",(0,t.jsxs)(s.p,{children:["A ",(0,t.jsx)(s.code,{children:"get"})," command is available in the OSISM CLI. This allows to gather specific information."]}),"\n",(0,t.jsx)(s.h2,{id:"hosts",children:"Hosts"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"Get all hosts defined in the inventory"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"$ osism get hosts\n+-----------------------------------+\n| Host |\n|-----------------------------------|\n| testbed-manager.testbed.osism.xyz |\n| testbed-node-0.testbed.osism.xyz |\n| testbed-node-1.testbed.osism.xyz |\n| testbed-node-2.testbed.osism.xyz |\n+-----------------------------------+\n"})}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"Get all hosts defined in the inventory that are member of a specific inventory group"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"$ osism get hosts -l manager\n+-----------------------------------+\n| Host |\n|-----------------------------------|\n| testbed-manager.testbed.osism.xyz |\n+-----------------------------------+\n\n$ osism get hosts -l control\n+----------------------------------+\n| Host |\n|----------------------------------|\n| testbed-node-0.testbed.osism.xyz |\n| testbed-node-1.testbed.osism.xyz |\n| testbed-node-2.testbed.osism.xyz |\n+----------------------------------+\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"host-variables",children:"Host variables"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"Get all host vars of a specific node"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"osism get hostvars testbed-manager.testbed.osism.xyz\n"})}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"Get a specific host var of a specific node"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"$ osism get hostvars testbed-manager.testbed.osism.xyz ansible_host\n+-----------------------------------+--------------+----------------+\n| Host | Variable | Value |\n+===================================+==============+================+\n| testbed-manager.testbed.osism.xyz | ansible_host | '192.168.16.5' |\n+-----------------------------------+--------------+----------------+\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"host-facts",children:"Host facts"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"Get all facts of a specific node"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"osism get facts testbed-manager.testbed.osism.xyz\n"})}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"Get a specific fact of a specific node"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"$ osism get facts testbed-manager.testbed.osism.xyz ansible_architecture\n+-----------------------------------+----------------------+----------+\n| Host | Fact | Value |\n+===================================+======================+==========+\n| testbed-manager.testbed.osism.xyz | ansible_architecture | 'x86_64' |\n+-----------------------------------+----------------------+----------+\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>d});var t=n(96540);const i={},o=t.createContext(i);function a(e){const s=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/526992cf.7b421abc.js b/assets/js/526992cf.7b421abc.js new file mode 100644 index 0000000000..433e3d065d --- /dev/null +++ b/assets/js/526992cf.7b421abc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1475],{38249:(e,s,d)=>{d.r(s),d.d(s,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>o});var n=d(74848),r=d(28453);const t={title:"SCS Standard Flavors and Properties",type:"Standard",status:"Stable",stabilized_at:new Date("2024-02-08T00:00:00.000Z"),track:"IaaS",description:"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack\nenvironments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific\nconfigurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs:name-vN, scs:cpu-type,\nand scs:diskN-type to detail the flavor's specifications. This standard facilitates guaranteed availability and\nconsistency of flavors, simplifying the deployment process for DevOps teams.\n"},i=void 0,c={id:"scs-0103-v1-standard-flavors",title:"SCS Standard Flavors and Properties",description:"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack\nenvironments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific\nconfigurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs:name-vN, scs:cpu-type,\nand scs:diskN-type to detail the flavor's specifications. This standard facilitates guaranteed availability and\nconsistency of flavors, simplifying the deployment process for DevOps teams.\n",source:"@site/standards/scs-0103-v1-standard-flavors.md",sourceDirName:".",slug:"/scs-0103-v1-standard-flavors",permalink:"/standards/scs-0103-v1-standard-flavors",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS Standard Flavors and Properties",type:"Standard",status:"Stable",stabilized_at:"2024-02-08T00:00:00.000Z",track:"IaaS",description:"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack\nenvironments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific\nconfigurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs:name-vN, scs:cpu-type,\nand scs:diskN-type to detail the flavor's specifications. This standard facilitates guaranteed availability and\nconsistency of flavors, simplifying the deployment process for DevOps teams.\n"},sidebar:"standards",previous:{title:"scs-0103: SCS Standard Flavors and Properties",permalink:"/standards/iaas/scs-0103"},next:{title:"scs-0104: SCS Standard Images",permalink:"/standards/iaas/scs-0104"}},a={},o=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Properties (extra specs)",id:"properties-extra-specs",level:2},{value:"Standard SCS flavors",id:"standard-scs-flavors",level:2},{value:"Mandatory",id:"mandatory",level:3},{value:"Recommended",id:"recommended",level:3},{value:"Guarantees and properties",id:"guarantees-and-properties",level:3},{value:"Remarks",id:"remarks",level:3},{value:"Conformance Tests",id:"conformance-tests",level:2},{value:"Operational tooling",id:"operational-tooling",level:2},{value:"Previous standard versions",id:"previous-standard-versions",level:2}];function l(e){const s={a:"a",code:"code",div:"div",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsx)(s.h2,{id:"motivation",children:"Motivation"}),"\n",(0,n.jsx)(s.p,{children:"In OpenStack environments there is a need to define different flavors for instances.\nThe flavors are pre-defined by the operator, the customer can not change these.\nOpenStack providers thus typically offer a large selection of flavors."}),"\n",(0,n.jsxs)(s.p,{children:["While flavors can be discovered (",(0,n.jsx)(s.code,{children:"openstack flavor list"}),"), it is helpful for users (DevOps teams),\nto have a guaranteed set of flavors available on all SCS clouds, so these need not be discovered."]}),"\n",(0,n.jsx)(s.h2,{id:"properties-extra-specs",children:"Properties (extra specs)"}),"\n",(0,n.jsx)(s.p,{children:"The following extra specs are recognized, together with the respective semantics:"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"scs:name-vN=NAME"})," (where ",(0,n.jsx)(s.code,{children:"N"})," is ",(0,n.jsx)(s.code,{children:"1"})," or ",(0,n.jsx)(s.code,{children:"2"}),", and ",(0,n.jsx)(s.code,{children:"NAME"}),' is some string) means that the\nflavor is one of the\nstandard SCS flavors, and the requirements of Section "Standard SCS flavors" below apply.']}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"scs:cpu-type=shared-core"})," means that ",(0,n.jsx)(s.em,{children:"at least 20% of a core in >99% of the time"}),",\nmeasured over the course of one month (1% is 7,2 h/month). The ",(0,n.jsx)(s.code,{children:"cpu-type=shared-core"}),"\ncorresponds to the ",(0,n.jsx)(s.code,{children:"V"})," cpu modifier in the ",(0,n.jsx)(s.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"flavor-naming spec"}),",\nother options are ",(0,n.jsx)(s.code,{children:"crowded-core"})," (",(0,n.jsx)(s.code,{children:"L"}),"), ",(0,n.jsx)(s.code,{children:"dedicated-thread"})," (",(0,n.jsx)(s.code,{children:"T"}),") and ",(0,n.jsx)(s.code,{children:"dedicated-core"})," (",(0,n.jsx)(s.code,{children:"C"}),")."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"scs:diskN-type=ssd"})," (where ",(0,n.jsx)(s.code,{children:"N"})," is a nonnegative integer, usually ",(0,n.jsx)(s.code,{children:"0"}),") means that the\nroot disk ",(0,n.jsx)(s.code,{children:"N"})," must support 1000 ",(0,n.jsx)(s.em,{children:"sequential"})," IOPS per VM and it must be equipped with\npower-loss protection; see ",(0,n.jsx)(s.a,{href:"/standards/scs-0110-v1-ssd-flavors",children:"scs-0110-v1-ssd-flavors"}),".\nThe ",(0,n.jsx)(s.code,{children:"disk"}),"N",(0,n.jsx)(s.code,{children:"-type=ssd"})," setting corresponds to the ",(0,n.jsx)(s.code,{children:"s"})," disk modifier, other options\nare ",(0,n.jsx)(s.code,{children:"nvme"})," (",(0,n.jsx)(s.code,{children:"p"}),"), ",(0,n.jsx)(s.code,{children:"hdd"})," (",(0,n.jsx)(s.code,{children:"h"}),") and ",(0,n.jsx)(s.code,{children:"network"})," (",(0,n.jsx)(s.code,{children:"n"}),"). Only flavors without disk and\nthose with ",(0,n.jsx)(s.code,{children:"diskN-type=network"})," can be expected to support live-migration."]}),"\n"]}),"\n",(0,n.jsx)(s.p,{children:"Whenever ANY of these are present on ANY flavor, the corresponding semantics must be satisfied."}),"\n",(0,n.jsx)(s.h2,{id:"standard-scs-flavors",children:"Standard SCS flavors"}),"\n",(0,n.jsx)(s.p,{children:"Following are flavors that must exist on standard SCS clouds (x86-64).\nNote that this statement does not preclude the existence of additional flavors."}),"\n",(0,n.jsx)(s.h3,{id:"mandatory",children:"Mandatory"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Recommended name"}),(0,n.jsx)(s.th,{children:"vCPUs"}),(0,n.jsx)(s.th,{children:"vCPU type"}),(0,n.jsx)(s.th,{children:"RAM [GiB]"}),(0,n.jsx)(s.th,{children:"Root disk [GB]"}),(0,n.jsx)(s.th,{children:"Disk type"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-1V-4"}),(0,n.jsx)(s.td,{children:"1"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-2V-8"}),(0,n.jsx)(s.td,{children:"2"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"8"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-4V-16"}),(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"16"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-4V-16-100s"}),(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"16"}),(0,n.jsx)(s.td,{children:"100"}),(0,n.jsx)(s.td,{children:"ssd"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-8V-32"}),(0,n.jsx)(s.td,{children:"8"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"32"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-1V-2"}),(0,n.jsx)(s.td,{children:"1"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"2"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-2V-4"}),(0,n.jsx)(s.td,{children:"2"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-2V-4-20s"}),(0,n.jsx)(s.td,{children:"2"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{children:"20"}),(0,n.jsx)(s.td,{children:"ssd"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-4V-8"}),(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"8"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-8V-16"}),(0,n.jsx)(s.td,{children:"8"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"16"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-16V-32"}),(0,n.jsx)(s.td,{children:"16"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"32"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-1V-8"}),(0,n.jsx)(s.td,{children:"1"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"8"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-2V-16"}),(0,n.jsx)(s.td,{children:"2"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"16"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-4V-32"}),(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"32"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-1L-1"}),(0,n.jsx)(s.td,{children:"1"}),(0,n.jsx)(s.td,{children:"crowded-core"}),(0,n.jsx)(s.td,{children:"1"}),(0,n.jsx)(s.td,{}),(0,n.jsx)(s.td,{})]})]})]}),"\n",(0,n.jsx)(s.h3,{id:"recommended",children:"Recommended"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Recommended name"}),(0,n.jsx)(s.th,{children:"vCPUs"}),(0,n.jsx)(s.th,{children:"vCPU type"}),(0,n.jsx)(s.th,{children:"RAM [GiB]"}),(0,n.jsx)(s.th,{children:"Root disk [GB]"}),(0,n.jsx)(s.th,{children:"Disk type"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-1V-4-10"}),(0,n.jsx)(s.td,{children:"1"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{children:"10"}),(0,n.jsx)(s.td,{children:"(any)"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-2V-8-20"}),(0,n.jsx)(s.td,{children:"2"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"8"}),(0,n.jsx)(s.td,{children:"20"}),(0,n.jsx)(s.td,{children:"(any)"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-4V-16-50"}),(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"16"}),(0,n.jsx)(s.td,{children:"50"}),(0,n.jsx)(s.td,{children:"(any)"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-8V-32-100"}),(0,n.jsx)(s.td,{children:"8"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"32"}),(0,n.jsx)(s.td,{children:"100"}),(0,n.jsx)(s.td,{children:"(any)"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-1V-2-5"}),(0,n.jsx)(s.td,{children:"1"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"2"}),(0,n.jsx)(s.td,{children:"5"}),(0,n.jsx)(s.td,{children:"(any)"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-2V-4-10"}),(0,n.jsx)(s.td,{children:"2"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{children:"10"}),(0,n.jsx)(s.td,{children:"(any)"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-4V-8-20"}),(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"8"}),(0,n.jsx)(s.td,{children:"20"}),(0,n.jsx)(s.td,{children:"(any)"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-8V-16-50"}),(0,n.jsx)(s.td,{children:"8"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"16"}),(0,n.jsx)(s.td,{children:"50"}),(0,n.jsx)(s.td,{children:"(any)"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-16V-32-100"}),(0,n.jsx)(s.td,{children:"16"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"32"}),(0,n.jsx)(s.td,{children:"100"}),(0,n.jsx)(s.td,{children:"(any)"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-1V-8-20"}),(0,n.jsx)(s.td,{children:"1"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"8"}),(0,n.jsx)(s.td,{children:"20"}),(0,n.jsx)(s.td,{children:"(any)"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-2V-16-50"}),(0,n.jsx)(s.td,{children:"2"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"16"}),(0,n.jsx)(s.td,{children:"50"}),(0,n.jsx)(s.td,{children:"(any)"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-4V-32-100"}),(0,n.jsx)(s.td,{children:"4"}),(0,n.jsx)(s.td,{children:"shared-core"}),(0,n.jsx)(s.td,{children:"32"}),(0,n.jsx)(s.td,{children:"100"}),(0,n.jsx)(s.td,{children:"(any)"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"SCS-1L-1-5"}),(0,n.jsx)(s.td,{children:"1"}),(0,n.jsx)(s.td,{children:"crowded-core"}),(0,n.jsx)(s.td,{children:"1"}),(0,n.jsx)(s.td,{children:"5"}),(0,n.jsx)(s.td,{children:"(any)"})]})]})]}),"\n",(0,n.jsx)(s.h3,{id:"guarantees-and-properties",children:"Guarantees and properties"}),"\n",(0,n.jsx)(s.p,{children:"The figures given in the table (number of CPUs, amount of RAM, root disk size) must match\nprecisely the corresponding figures in the flavor."}),"\n",(0,n.jsxs)(s.p,{children:["In addition, the following properties must be set (in the ",(0,n.jsx)(s.code,{children:"extra_specs"}),"):"]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"scs:name-v1"})," to the recommended name, but with each dash AFTER the first one replaced by a colon,"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"scs:name-v2"})," to the recommended name,"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"scs:cpu-type"})," to ",(0,n.jsx)(s.code,{children:"shared-core"})," or ",(0,n.jsx)(s.code,{children:"crowded-core"}),", reflecting the vCPU type,"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"scs:disk0-type"})," not set if no disk is provided, otherwise set to ",(0,n.jsx)(s.code,{children:"ssd"})," or some other\nvalue, reflecting the disk type."]}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"remarks",children:"Remarks"}),"\n",(0,n.jsxs)(s.p,{children:["We expect the most used vCPU",(0,n.jsx)(s.div,{children:"GiB"})," ratio to be 1:4."]}),"\n",(0,n.jsxs)(s.p,{children:["Note that all vCPUs of SCS standard flavors are oversubscribed \u2014 the smallest ",(0,n.jsx)(s.code,{children:"1L-1"}),"\nflavor allows for heavy oversubscription (note the ",(0,n.jsx)(s.code,{children:"L"}),"), and thus can be offered very\ncheaply \u2014 imagine jump hosts ..."]}),"\n",(0,n.jsx)(s.p,{children:"The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM\ncompute hosts) to offer all flavors."}),"\n",(0,n.jsx)(s.p,{children:"Except for the two flavors with SSD root volume, disks types are not specified\n(and expected to be network disks (Ceph/Cinder) or local SATA/SAS disks typically)."}),"\n",(0,n.jsxs)(s.p,{children:["We only included a limited variation of disk sizes \u2014 this reflects that\nfor the standard networked cinder\ndisks, you can pass ",(0,n.jsx)(s.code,{children:"block_device_mapping_v2"})," on server (VM) creation to\nallocate a boot disk of any size you desire. We have scaled the few\nrecommended disk sizes with the amount of RAM. For each flavor there is\nalso one ",(0,n.jsx)(s.em,{children:"without"})," a pre-attached disk \u2014 these are meant to be used\nto boot from a volume (either created beforehand or allocated on-the-fly\nwith ",(0,n.jsx)(s.code,{children:"block_device_mapping_v2"}),", e.g.\n",(0,n.jsx)(s.code,{children:"openstack server create --flavor SCS-1V-2 --block-device-mapping sda=IMGUUID:image:12:true"}),"\nto create a bootable 12G cinder volume from image ",(0,n.jsx)(s.code,{children:"IMGUUID"})," that gets tied to the VM\ninstance life cycle.)"]}),"\n",(0,n.jsx)(s.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,n.jsxs)(s.p,{children:["The script ",(0,n.jsx)(s.code,{children:"flavors-openstack.py"})," will read the lists of mandatory and recommended flavors\nfrom a yaml file provided as command-line argument, connect to an OpenStack installation,\nand check whether the flavors are present and their extra specs are correct. Missing\nflavors will be reported on various logging channels: error for mandatory, info for\nrecommended flavors. Incorrect extra specs will be reported as error in any case.\nThe return code will be non-zero if the test could not be performed or if any error was\nreported."]}),"\n",(0,n.jsx)(s.h2,{id:"operational-tooling",children:"Operational tooling"}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.a,{href:"https://github.com/osism/openstack-flavor-manager",children:"openstack-flavor-manager"})," is able to\ncreate all standard, mandatory SCS flavors for you. It takes input that can be generated by\n",(0,n.jsx)(s.code,{children:"flavor-manager-input.py"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"previous-standard-versions",children:"Previous standard versions"}),"\n",(0,n.jsxs)(s.p,{children:["The list of standard flavors used to be part of the flavor naming standard up until\n",(0,n.jsx)(s.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"version 3"}),". The following changes have been made to\nthe list in comparison with said standard:"]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:"the flavor names have been turned into recommendations, and"}),"\n",(0,n.jsx)(s.li,{children:"the properties have been introduced in order to help discoverability."}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["Note that the flavors with fixed size root disks have all moved to Recommended\nwith ",(0,n.jsx)(s.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"scs-0100-v3"}),".\nThis means that they are not a certification requirement any longer,\nbut we still recommend implementing these for backwards compatibility reasons.\nAlso in that standard, two flavors with SSD+ root disks have been added, as defined in\n",(0,n.jsx)(s.a,{href:"/standards/scs-0110-v1-ssd-flavors",children:"scs-0110-v1-ssd-flavors.md"})]})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,s,d)=>{d.d(s,{R:()=>i,x:()=>c});var n=d(96540);const r={},t=n.createContext(r);function i(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/52ac6bcf.23b059f0.js b/assets/js/52ac6bcf.23b059f0.js new file mode 100644 index 0000000000..b3147ed60b --- /dev/null +++ b/assets/js/52ac6bcf.23b059f0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7813],{70884:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>o});var n=s(74848),r=s(28453);const i={},d="scs-0213: Kubernetes Nodes Anti Affinity",a={id:"kaas/scs-0213",title:"scs-0213: Kubernetes Nodes Anti Affinity",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/kaas/scs-0213.md",sourceDirName:"kaas",slug:"/kaas/scs-0213",permalink:"/standards/kaas/scs-0213",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Requirements for container registries",permalink:"/standards/scs-0212-v1-requirements-for-container-registries"},next:{title:"Kubernetes Nodes Anti Affinity",permalink:"/standards/scs-0213-v1-k8s-nodes-anti-affinity"}},c={},o=[];function l(e){const t={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"scs-0213-kubernetes-nodes-anti-affinity",children:"scs-0213: Kubernetes Nodes Anti Affinity"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0213-v1-k8s-nodes-anti-affinity",children:"scs-0213-v1"})}),(0,n.jsx)(t.td,{children:"Decision Record"}),(0,n.jsx)(t.td,{children:"Draft"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>a});var n=s(96540);const r={},i=n.createContext(r);function d(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/52e3f5ca.f927ba35.js b/assets/js/52e3f5ca.f927ba35.js new file mode 100644 index 0000000000..4578c269fc --- /dev/null +++ b/assets/js/52e3f5ca.f927ba35.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7157],{91177:s=>{s.exports=JSON.parse('{"pluginId":"standards","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"standards":[{"type":"link","label":"Introduction","href":"/standards/","docId":"index","unlisted":false},{"type":"category","label":"Certification","items":[{"type":"category","label":"Scopes and Versions","items":[{"type":"link","label":"SCS Compatible IaaS","href":"/standards/scs-compatible-iaas","docId":"scs-compatible-iaas","unlisted":false},{"type":"link","label":"SCS Compatible KaaS","href":"/standards/scs-compatible-kaas","docId":"scs-compatible-kaas","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/certification/scopes-versions"}],"collapsed":true,"collapsible":true,"href":"/standards/certification/overview"},{"type":"category","label":"Standards","items":[{"type":"category","label":"Global","items":[{"type":"category","label":"scs-0001","items":[{"type":"link","label":"V1","href":"/standards/scs-0001-v1-sovereign-cloud-standards","docId":"scs-0001-v1-sovereign-cloud-standards","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/global/scs-0001"},{"type":"category","label":"scs-0002","items":[{"type":"link","label":"V1","href":"/standards/scs-0002-v1-standards-docs-org","docId":"scs-0002-v1-standards-docs-org","unlisted":false},{"type":"link","label":"V2","href":"/standards/scs-0002-v2-standards-docs-org","docId":"scs-0002-v2-standards-docs-org","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/global/scs-0002"},{"type":"category","label":"scs-0003","items":[{"type":"link","label":"V1","href":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","docId":"scs-0003-v1-sovereign-cloud-standards-yaml","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/global/scs-0003"},{"type":"category","label":"scs-0004","items":[{"type":"link","label":"V1","href":"/standards/scs-0004-v1-achieving-certification","docId":"scs-0004-v1-achieving-certification","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/global/scs-0004"},{"type":"category","label":"scs-0112","items":[{"type":"link","label":"V1","href":"/standards/scs-0112-v1-sonic","docId":"scs-0112-v1-sonic","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/global/scs-0112"}],"collapsed":true,"collapsible":true,"href":"/standards/global/"},{"type":"category","label":"IaaS","items":[{"type":"category","label":"scs-0100","items":[{"type":"link","label":"V1","href":"/standards/scs-0100-v1-flavor-naming","docId":"scs-0100-v1-flavor-naming","unlisted":false},{"type":"link","label":"V2","href":"/standards/scs-0100-v2-flavor-naming","docId":"scs-0100-v2-flavor-naming","unlisted":false},{"type":"link","label":"V3","href":"/standards/scs-0100-v3-flavor-naming","docId":"scs-0100-v3-flavor-naming","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0100-w1-flavor-naming-implementation-testing","docId":"scs-0100-w1-flavor-naming-implementation-testing","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0100"},{"type":"category","label":"scs-0101","items":[{"type":"link","label":"V1","href":"/standards/scs-0101-v1-entropy","docId":"scs-0101-v1-entropy","unlisted":false},{"type":"link","label":"W1","href":"/standards/scs-0101-w1-entropy-implementation-testing","docId":"scs-0101-w1-entropy-implementation-testing","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0101"},{"type":"category","label":"scs-0102","items":[{"type":"link","label":"V1","href":"/standards/scs-0102-v1-image-metadata","docId":"scs-0102-v1-image-metadata","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0102"},{"type":"category","label":"scs-0103","items":[{"type":"link","label":"V1","href":"/standards/scs-0103-v1-standard-flavors","docId":"scs-0103-v1-standard-flavors","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0103"},{"type":"category","label":"scs-0104","items":[{"type":"link","label":"V1","href":"/standards/scs-0104-v1-standard-images","docId":"scs-0104-v1-standard-images","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0104"},{"type":"category","label":"scs-0110","items":[{"type":"link","label":"V1","href":"/standards/scs-0110-v1-ssd-flavors","docId":"scs-0110-v1-ssd-flavors","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0110"},{"type":"category","label":"scs-0111","items":[{"type":"link","label":"V1","href":"/standards/scs-0111-v1-volume-type-decisions","docId":"scs-0111-v1-volume-type-decisions","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0111"},{"type":"category","label":"scs-0113","items":[{"type":"link","label":"V1","href":"/standards/scs-0113-v1-security-groups-decision-record","docId":"scs-0113-v1-security-groups-decision-record","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0113"},{"type":"category","label":"scs-0114","items":[{"type":"link","label":"V1","href":"/standards/scs-0114-v1-volume-type-standard","docId":"scs-0114-v1-volume-type-standard","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0114"},{"type":"category","label":"scs-0115","items":[{"type":"link","label":"V1","href":"/standards/scs-0115-v1-default-rules-for-security-groups","docId":"scs-0115-v1-default-rules-for-security-groups","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/scs-0115"}],"collapsed":true,"collapsible":true,"href":"/standards/iaas/"},{"type":"category","label":"KaaS","items":[{"type":"category","label":"scs-0200","items":[{"type":"link","label":"V1","href":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","docId":"scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0200"},{"type":"category","label":"scs-0210","items":[{"type":"link","label":"V1","href":"/standards/scs-0210-v1-k8s-new-version-policy","docId":"scs-0210-v1-k8s-new-version-policy","unlisted":false},{"type":"link","label":"V2","href":"/standards/scs-0210-v2-k8s-version-policy","docId":"scs-0210-v2-k8s-version-policy","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0210"},{"type":"category","label":"scs-0211","items":[{"type":"link","label":"V1","href":"/standards/scs-0211-v1-kaas-default-storage-class","docId":"scs-0211-v1-kaas-default-storage-class","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0211"},{"type":"category","label":"scs-0212","items":[{"type":"link","label":"V1","href":"/standards/scs-0212-v1-requirements-for-container-registries","docId":"scs-0212-v1-requirements-for-container-registries","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0212"},{"type":"category","label":"scs-0213","items":[{"type":"link","label":"V1","href":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","docId":"scs-0213-v1-k8s-nodes-anti-affinity","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0213"},{"type":"category","label":"scs-0214","items":[{"type":"link","label":"V1","href":"/standards/scs-0214-v1-k8s-node-distribution","docId":"scs-0214-v1-k8s-node-distribution","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0214"},{"type":"category","label":"scs-0215","items":[{"type":"link","label":"V1","href":"/standards/scs-0215-v1-robustness-features","docId":"scs-0215-v1-robustness-features","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0215"},{"type":"category","label":"scs-0216","items":[{"type":"link","label":"V1","href":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","docId":"scs-0216-v1-requirements-for-testing-cluster-stacks","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0216"},{"type":"category","label":"scs-0217","items":[{"type":"link","label":"V1","href":"/standards/scs-0217-v1-baseline-cluster-security","docId":"scs-0217-v1-baseline-cluster-security","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0217"},{"type":"category","label":"scs-0218","items":[{"type":"link","label":"V1","href":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","docId":"scs-0218-v1-container-registry-for-scs-standard-implementation","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/scs-0218"}],"collapsed":true,"collapsible":true,"href":"/standards/kaas/"},{"type":"category","label":"IAM","items":[{"type":"category","label":"scs-0300","items":[{"type":"link","label":"V1","href":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","docId":"scs-0300-v1-requirements-for-sso-identity-federation","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iam/scs-0300"},{"type":"category","label":"scs-0301","items":[{"type":"link","label":"V1","href":"/standards/scs-0301-v1-naming-conventions","docId":"scs-0301-v1-naming-conventions","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iam/scs-0301"},{"type":"category","label":"scs-0302","items":[{"type":"link","label":"V1","href":"/standards/scs-0302-v1-domain-manager-role","docId":"scs-0302-v1-domain-manager-role","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/iam/scs-0302"}],"collapsed":true,"collapsible":true,"href":"/standards/iam/"},{"type":"category","label":"Ops","items":[{"type":"category","label":"scs-0400","items":[{"type":"link","label":"V1","href":"/standards/scs-0400-v1-status-page-create-decision","docId":"scs-0400-v1-status-page-create-decision","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0400"},{"type":"category","label":"scs-0401","items":[{"type":"link","label":"V1","href":"/standards/scs-0401-v1-status-page-reference-implementation-decision","docId":"scs-0401-v1-status-page-reference-implementation-decision","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0401"},{"type":"category","label":"scs-0402","items":[{"type":"link","label":"V1","href":"/standards/scs-0402-v1-status-page-openapi-spec-decision","docId":"scs-0402-v1-status-page-openapi-spec-decision","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0402"},{"type":"category","label":"scs-0403","items":[{"type":"link","label":"V1","href":"/standards/scs-0403-v1-csp-kaas-observability-stack","docId":"scs-0403-v1-csp-kaas-observability-stack","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0403"},{"type":"category","label":"scs-0410","items":[{"type":"link","label":"V1","href":"/standards/scs-0410-v1-gnocchi-as-metering-database","docId":"scs-0410-v1-gnocchi-as-metering-database","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0410"},{"type":"category","label":"scs-0411","items":[{"type":"link","label":"V1","href":"/standards/scs-0411-v1-publishing_method_for_metering_data","docId":"scs-0411-v1-publishing_method_for_metering_data","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0411"},{"type":"category","label":"scs-0412","items":[{"type":"link","label":"V1","href":"/standards/scs-0412-v1-metering-json","docId":"scs-0412-v1-metering-json","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/standards/ops/scs-0412"}],"collapsed":true,"collapsible":true,"href":"/standards/ops/"}],"collapsed":true,"collapsible":true,"href":"/standards/standards/overview"}]},"docs":{"certification/overview":{"id":"certification/overview","title":"overview","description":"SCS certificates come with various scopes. See Scopes and Versions for details.","sidebar":"standards"},"certification/scopes-versions":{"id":"certification/scopes-versions","title":"Scopes and versions","description":"SCS provides a certification framework consisting of six different kinds of certificates of varying scope.","sidebar":"standards"},"global/index":{"id":"global/index","title":"Global Standards","description":"This track encompasses the foundational standards that guide the overall structure, documentation, and general topics related to the Sovereign Cloud Stack. It serves as the core framework, ensuring consistency, clarity, and comprehensibility across all aspects of the cloud stack, fostering an environment where information is easily accessible and understood.","sidebar":"standards"},"global/scs-0001":{"id":"global/scs-0001","title":"scs-0001: Sovereign Cloud Standards","description":"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision","sidebar":"standards"},"global/scs-0002":{"id":"global/scs-0002","title":"scs-0002: Standards, Docs and Organisation","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"global/scs-0003":{"id":"global/scs-0003","title":"scs-0003: Sovereign Cloud Standards YAML","description":"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,","sidebar":"standards"},"global/scs-0004":{"id":"global/scs-0004","title":"scs-0004: Regulations for achieving SCS-compatible certification","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"global/scs-0112":{"id":"global/scs-0112","title":"scs-0112: SONiC Support in SCS","description":"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.","sidebar":"standards"},"iaas/index":{"id":"iaas/index","title":"IaaS Standards","description":"The IaaS Layer Standards track focuses on the protocols, guidelines, and specifications that govern the infrastructure as a service layer. This encompasses standards for virtual machines, storage, networking, and other foundational resources, ensuring seamless, efficient, and secure operation, interoperability, and management of the underlying cloud infrastructure.","sidebar":"standards"},"iaas/scs-0100":{"id":"iaas/scs-0100","title":"scs-0100: SCS Flavor Naming Standard","description":"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack","sidebar":"standards"},"iaas/scs-0101":{"id":"iaas/scs-0101","title":"scs-0101: SCS Entropy","description":"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations","sidebar":"standards"},"iaas/scs-0102":{"id":"iaas/scs-0102","title":"scs-0102: SCS Image Metadata Standard","description":"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating","sidebar":"standards"},"iaas/scs-0103":{"id":"iaas/scs-0103","title":"scs-0103: SCS Standard Flavors and Properties","description":"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack","sidebar":"standards"},"iaas/scs-0104":{"id":"iaas/scs-0104","title":"scs-0104: SCS Standard Images","description":"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,","sidebar":"standards"},"iaas/scs-0110":{"id":"iaas/scs-0110","title":"scs-0110: SSD Flavors","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0111":{"id":"iaas/scs-0111","title":"scs-0111: Decisions for the Volume Type Standard","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0113":{"id":"iaas/scs-0113","title":"scs-0113: Security Groups Decision Record","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0114":{"id":"iaas/scs-0114","title":"scs-0114: Volume Type Standard","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iaas/scs-0115":{"id":"iaas/scs-0115","title":"scs-0115: Default Rules for Security Groups","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iam/index":{"id":"iam/index","title":"IAM Standards","description":"This track revolves around Identity and Access Management (IAM) standards, providing guidelines for ensuring secure and efficient user authentication, authorization, and administration. It addresses issues related to user identity, permissions, roles, and policies, aiming to safeguard and streamline access to cloud resources and services.","sidebar":"standards"},"iam/scs-0300":{"id":"iam/scs-0300","title":"scs-0300: Requirements for SSO identity federation","description":"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign","sidebar":"standards"},"iam/scs-0301":{"id":"iam/scs-0301","title":"scs-0301: Naming for domains/groups/roles/project when onboarding new customers","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"iam/scs-0302":{"id":"iam/scs-0302","title":"scs-0302: Domain Manager configuration for Keystone","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"index":{"id":"index","title":"Introduction","description":"The Sovereign Cloud Stack (SCS) is a community-driven project that curates a set of standards\u2014including both existing standards, such as the OpenInfra interoperability guides or the CNCF Kubernetes conformance, and newly created ones\u2014to enable and ensure compatibility, openness, and sovereignty of cloud services across a wide range of providers, particularly small and medium businesses.","sidebar":"standards"},"kaas/index":{"id":"kaas/index","title":"KaaS Standards","description":"Standards in this track are concerned with Kubernetes as a Service layer, outlining norms and best practices for deploying, managing, and operating Kubernetes clusters. These standards aim to ensure that the orchestration of containers is streamlined, secure, and compatible across various cloud environments and platforms.","sidebar":"standards"},"kaas/scs-0200":{"id":"kaas/scs-0200","title":"scs-0200: Using Sonobuoy for KaaS conformance tests","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0210":{"id":"kaas/scs-0210","title":"scs-0210: SCS K8S Version Policy","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0211":{"id":"kaas/scs-0211","title":"scs-0211: SCS KaaS default storage class","description":"The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).","sidebar":"standards"},"kaas/scs-0212":{"id":"kaas/scs-0212","title":"scs-0212: Requirements for container registries","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0213":{"id":"kaas/scs-0213","title":"scs-0213: Kubernetes Nodes Anti Affinity","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0214":{"id":"kaas/scs-0214","title":"scs-0214: Kubernetes Node Distribution and Availability","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0215":{"id":"kaas/scs-0215","title":"scs-0215: Robustness features for Kubernetes clusters","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0216":{"id":"kaas/scs-0216","title":"scs-0216: Requirements for testing cluster-stacks","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0217":{"id":"kaas/scs-0217","title":"scs-0217: Kubernetes cluster baseline security","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"kaas/scs-0218":{"id":"kaas/scs-0218","title":"scs-0218: Container registry for SCS standard implementation","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/index":{"id":"ops/index","title":"Ops Standards","description":"Operational Tooling Standards cover the protocols and guidelines associated with tools and utilities used for monitoring, management, and maintenance of the cloud environment. This includes standards for status pages, alerts, logs, and other operational tools, aiming to optimize the reliability, performance, and security of cloud services and resources.","sidebar":"standards"},"ops/scs-0400":{"id":"ops/scs-0400","title":"scs-0400: Status Page create decision","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/scs-0401":{"id":"ops/scs-0401","title":"scs-0401: Status page reference implementation decision","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/scs-0402":{"id":"ops/scs-0402","title":"scs-0402: Status page OpenAPI decision","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/scs-0403":{"id":"ops/scs-0403","title":"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/scs-0410":{"id":"ops/scs-0410","title":"scs-0410: Gnocchi as database for metering","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/scs-0411":{"id":"ops/scs-0411","title":"scs-0411: Push-based approach for providing usage data","description":"| Version | Type | State | stabilized | deprecated |","sidebar":"standards"},"ops/scs-0412":{"id":"ops/scs-0412","title":"scs-0412: Exposition of IaaS metering data as JSON","description":"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format","sidebar":"standards"},"scs-0001-v1-sovereign-cloud-standards":{"id":"scs-0001-v1-sovereign-cloud-standards","title":"Sovereign Cloud Standards","description":"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision\\nrecords within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in\\nthe development and maintenance of interoperable and transparent cloud infrastructure standards.\\n","sidebar":"standards"},"scs-0002-v1-standards-docs-org":{"id":"scs-0002-v1-standards-docs-org","title":"Standards, Docs and Organisation","description":"Introduction","sidebar":"standards"},"scs-0002-v2-standards-docs-org":{"id":"scs-0002-v2-standards-docs-org","title":"SCS Documentation structure","description":"SCS-0002 outlines the standardized structure and maintenance processes for easily accessible and\\ncomprehensible content of the SCS project.\\n","sidebar":"standards"},"scs-0003-v1-sovereign-cloud-standards-yaml":{"id":"scs-0003-v1-sovereign-cloud-standards-yaml","title":"Sovereign Cloud Standards YAML","description":"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,\\ncategorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning\\nin a machine-readable YAML format for clarity, traceability, and tool integration.\\n","sidebar":"standards"},"scs-0004-v1-achieving-certification":{"id":"scs-0004-v1-achieving-certification","title":"Regulations for achieving SCS-compatible certification","description":"Introduction","sidebar":"standards"},"scs-0100-v1-flavor-naming":{"id":"scs-0100-v1-flavor-naming","title":"SCS Flavor Naming Standard","description":"Introduction","sidebar":"standards"},"scs-0100-v2-flavor-naming":{"id":"scs-0100-v2-flavor-naming","title":"SCS Flavor Naming Standard","description":"Introduction","sidebar":"standards"},"scs-0100-v3-flavor-naming":{"id":"scs-0100-v3-flavor-naming","title":"SCS Flavor Naming Standard","description":"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack\\nenvironments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM,\\nand Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for\\nusability and portability across all SCS flavors.\\n","sidebar":"standards"},"scs-0100-w1-flavor-naming-implementation-testing":{"id":"scs-0100-w1-flavor-naming-implementation-testing","title":"SCS Flavor Naming Standard: Implementation and Testing Notes","description":"Introduction","sidebar":"standards"},"scs-0101-v1-entropy":{"id":"scs-0101-v1-entropy","title":"SCS Entropy","description":"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations\\nsuch as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and\\nactivating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy\\naccessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into\\nvirtual instances and ensures the availability and quality of entropy in virtual environments, promoting system\\nsecurity and efficiency.\\n","sidebar":"standards"},"scs-0101-w1-entropy-implementation-testing":{"id":"scs-0101-w1-entropy-implementation-testing","title":"SCS Entropy: Implementation and Testing Notes","description":"Implementation","sidebar":"standards"},"scs-0102-v1-image-metadata":{"id":"scs-0102-v1-image-metadata","title":"SCS Image Metadata Standard","description":"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating\\nsystem images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements,\\nimage handling protocols including updating and origin, and licensing/support details. These guidelines ensure\\nthat users can understand, access, and utilize OS images effectively, with clear information on features, updates,\\nand licensing provided through well-defined metadata properties.\\n","sidebar":"standards"},"scs-0103-v1-standard-flavors":{"id":"scs-0103-v1-standard-flavors","title":"SCS Standard Flavors and Properties","description":"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack\\nenvironments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific\\nconfigurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs:name-vN, scs:cpu-type,\\nand scs:diskN-type to detail the flavor\'s specifications. This standard facilitates guaranteed availability and\\nconsistency of flavors, simplifying the deployment process for DevOps teams.\\n","sidebar":"standards"},"scs-0104-v1-standard-images":{"id":"scs-0104-v1-standard-images","title":"SCS Standard Images","description":"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,\\nspecifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined\\ndeployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard\'s\\nmachine-readable document facilitates automated processing for compliance and integration purposes, promoting\\nconsistency and reliability in cloud environments.\\n","sidebar":"standards"},"scs-0110-v1-ssd-flavors":{"id":"scs-0110-v1-ssd-flavors","title":"SSD Flavors","description":"Introduction","sidebar":"standards"},"scs-0111-v1-volume-type-decisions":{"id":"scs-0111-v1-volume-type-decisions","title":"Decisions for the Volume Type Standard","description":"Introduction","sidebar":"standards"},"scs-0112-v1-sonic":{"id":"scs-0112-v1-sonic","title":"SONiC Support in SCS","description":"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.\\n","sidebar":"standards"},"scs-0113-v1-security-groups-decision-record":{"id":"scs-0113-v1-security-groups-decision-record","title":"Security Groups Decision Record","description":"Introduction","sidebar":"standards"},"scs-0114-v1-volume-type-standard":{"id":"scs-0114-v1-volume-type-standard","title":"Volume Type Standard","description":"Introduction","sidebar":"standards"},"scs-0115-v1-default-rules-for-security-groups":{"id":"scs-0115-v1-default-rules-for-security-groups","title":"Default Rules for Security Groups","description":"Introduction","sidebar":"standards"},"scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests":{"id":"scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","title":"Using Sonobuoy for KaaS conformance tests","description":"Motivation","sidebar":"standards"},"scs-0210-v1-k8s-new-version-policy":{"id":"scs-0210-v1-k8s-new-version-policy","title":"SCS K8S Version Policy for new Kubernetes versions","description":"The SCS-0210 standard outlines the expected pace at which providers should adopt new Kubernetes versions, aiming\\nfor alignment with the rapid development cycle of Kubernetes. Providers must offer the latest minor version within\\nfour months of its release and the newest patch version within a week, ensuring users have timely access to security\\nupdates, bug fixes, and features. The standard emphasizes the need for expedited updates for critical CVEs and\\nexpects providers to thoroughly test new versions before deployment.\\n","sidebar":"standards"},"scs-0210-v2-k8s-version-policy":{"id":"scs-0210-v2-k8s-version-policy","title":"SCS K8S Version Policy","description":"Introduction","sidebar":"standards"},"scs-0211-v1-kaas-default-storage-class":{"id":"scs-0211-v1-kaas-default-storage-class","title":"SCS KaaS default storage class","description":"The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).\\nThe standard ensures that the default StorageClass, identified by the \\"storageclass.kubernetes.io/is-default-class\\"\\nannotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or\\nhost hardware failures.\\n","sidebar":"standards"},"scs-0212-v1-requirements-for-container-registries":{"id":"scs-0212-v1-requirements-for-container-registries","title":"Requirements for container registries","description":"Introduction","sidebar":"standards"},"scs-0213-v1-k8s-nodes-anti-affinity":{"id":"scs-0213-v1-k8s-nodes-anti-affinity","title":"Kubernetes Nodes Anti Affinity","description":"Introduction","sidebar":"standards"},"scs-0214-v1-k8s-node-distribution":{"id":"scs-0214-v1-k8s-node-distribution","title":"Kubernetes Node Distribution and Availability","description":"Introduction","sidebar":"standards"},"scs-0215-v1-robustness-features":{"id":"scs-0215-v1-robustness-features","title":"Robustness features for Kubernetes clusters","description":"Introduction","sidebar":"standards"},"scs-0216-v1-requirements-for-testing-cluster-stacks":{"id":"scs-0216-v1-requirements-for-testing-cluster-stacks","title":"Requirements for testing cluster-stacks","description":"Introduction","sidebar":"standards"},"scs-0217-v1-baseline-cluster-security":{"id":"scs-0217-v1-baseline-cluster-security","title":"Kubernetes cluster baseline security","description":"Introduction","sidebar":"standards"},"scs-0218-v1-container-registry-for-scs-standard-implementation":{"id":"scs-0218-v1-container-registry-for-scs-standard-implementation","title":"Container registry for SCS standard implementation","description":"Introduction","sidebar":"standards"},"scs-0300-v1-requirements-for-sso-identity-federation":{"id":"scs-0300-v1-requirements-for-sso-identity-federation","title":"Requirements for SSO identity federation","description":"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign\\nCloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed\\nexternally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard\\nfocuses on delegating authentication to external identity providers and mapping users to roles within SCS for\\nauthorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity\\nProvider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible.\\n","sidebar":"standards"},"scs-0301-v1-naming-conventions":{"id":"scs-0301-v1-naming-conventions","title":"Naming for domains/groups/roles/project when onboarding new customers","description":"\x3c!---","sidebar":"standards"},"scs-0302-v1-domain-manager-role":{"id":"scs-0302-v1-domain-manager-role","title":"Domain Manager configuration for Keystone","description":"Introduction","sidebar":"standards"},"scs-0400-v1-status-page-create-decision":{"id":"scs-0400-v1-status-page-create-decision","title":"Status Page create decision","description":"Introduction","sidebar":"standards"},"scs-0401-v1-status-page-reference-implementation-decision":{"id":"scs-0401-v1-status-page-reference-implementation-decision","title":"Status page reference implementation decision","description":"Introduction","sidebar":"standards"},"scs-0402-v1-status-page-openapi-spec-decision":{"id":"scs-0402-v1-status-page-openapi-spec-decision","title":"Status page OpenAPI decision","description":"Introduction","sidebar":"standards"},"scs-0403-v1-csp-kaas-observability-stack":{"id":"scs-0403-v1-csp-kaas-observability-stack","title":"Architecture for the Cloud Service provider Observability System for the KaaS Layer","description":"Introduction","sidebar":"standards"},"scs-0410-v1-gnocchi-as-metering-database":{"id":"scs-0410-v1-gnocchi-as-metering-database","title":"Gnocchi as database for metering","description":"for more info. --\x3e","sidebar":"standards"},"scs-0411-v1-publishing_method_for_metering_data":{"id":"scs-0411-v1-publishing_method_for_metering_data","title":"Push-based approach for providing usage data","description":"for more info. --\x3e","sidebar":"standards"},"scs-0412-v1-metering-json":{"id":"scs-0412-v1-metering-json","title":"Exposition of IaaS metering data as JSON","description":"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format\\nwithin the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with\\ntheir existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format\\nprovided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation\\nlayers and implementation components.\\n","sidebar":"standards"},"scs-compatible-iaas":{"id":"scs-compatible-iaas","title":"SCS Compatible IaaS","description":"Note that the state Stable is shown here if stabilized at is in the future, whereas Effective is shown here if stabilized at is in the past and deprecated at is unset or in the future.","sidebar":"standards"},"scs-compatible-kaas":{"id":"scs-compatible-kaas","title":"SCS Compatible KaaS","description":"Note that the state Stable is shown here if stabilized at is in the future, whereas Effective is shown here if stabilized at is in the past and deprecated at is unset or in the future.","sidebar":"standards"},"scs-XXXX-vN-decision-record-template":{"id":"scs-XXXX-vN-decision-record-template","title":"_Descriptive title_","description":"\x3c!---"},"scs-XXXX-vN-standard-template":{"id":"scs-XXXX-vN-standard-template","title":"_Descriptive title_","description":"\x3c!---"},"standards/overview":{"id":"standards/overview","title":"Overview","description":"Standards are the core deliverable of SCS. By standardizing the open source software components of a cloud computing stack, their versions, how they are to be configured, deployed and utilized, SCS guarantees the reproducibility of a certain behavior of this technology.","sidebar":"standards"}}}')}}]); \ No newline at end of file diff --git a/assets/js/5309.a831c364.js b/assets/js/5309.a831c364.js new file mode 100644 index 0000000000..1bb3898bd4 --- /dev/null +++ b/assets/js/5309.a831c364.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5309],{26535:(e,t,s)=>{s.d(t,{A:()=>p});var a=s(96540),r=s(18215),n=s(72415),l=s(24581),i=s(28774),o=s(21312),c=s(56347),m=s(99169);function d(e){const{pathname:t}=(0,c.zy)();return(0,a.useMemo)((()=>e.filter((e=>function(e,t){return!(e.unlisted&&!(0,m.ys)(e.permalink,t))}(e,t)))),[e,t])}const u={sidebar:"sidebar_re4s",sidebarItemTitle:"sidebarItemTitle_pO2u",sidebarItemList:"sidebarItemList_Yudw",sidebarItem:"sidebarItem__DBe",sidebarItemLink:"sidebarItemLink_mo7H",sidebarItemLinkActive:"sidebarItemLinkActive_I1ZP"};var h=s(74848);function g(e){let{sidebar:t}=e;const s=d(t.items);return(0,h.jsx)("aside",{className:"col col--3",children:(0,h.jsxs)("nav",{className:(0,r.A)(u.sidebar,"thin-scrollbar"),"aria-label":(0,o.T)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"}),children:[(0,h.jsx)("div",{className:(0,r.A)(u.sidebarItemTitle,"margin-bottom--md"),children:t.title}),(0,h.jsx)("ul",{className:(0,r.A)(u.sidebarItemList,"clean-list"),children:s.map((e=>(0,h.jsx)("li",{className:u.sidebarItem,children:(0,h.jsx)(i.A,{isNavLink:!0,to:e.permalink,className:u.sidebarItemLink,activeClassName:u.sidebarItemLinkActive,children:e.title})},e.permalink)))})]})})}var x=s(75600);function f(e){let{sidebar:t}=e;const s=d(t.items);return(0,h.jsx)("ul",{className:"menu__list",children:s.map((e=>(0,h.jsx)("li",{className:"menu__list-item",children:(0,h.jsx)(i.A,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active",children:e.title})},e.permalink)))})}function j(e){return(0,h.jsx)(x.GX,{component:f,props:e})}function b(e){let{sidebar:t}=e;const s=(0,l.l)();return t?.items.length?"mobile"===s?(0,h.jsx)(j,{sidebar:t}):(0,h.jsx)(g,{sidebar:t}):null}function p(e){const{sidebar:t,toc:s,children:a,...l}=e,i=t&&t.items.length>0;return(0,h.jsx)(n.A,{...l,children:(0,h.jsx)("div",{className:"container margin-vert--lg",children:(0,h.jsxs)("div",{className:"row",children:[(0,h.jsx)(b,{sidebar:t}),(0,h.jsx)("main",{className:(0,r.A)("col",{"col--7":i,"col--9 col--offset-1":!i}),children:a}),s&&(0,h.jsx)("div",{className:"col col--2",children:s})]})})})}},24651:(e,t,s)=>{s.d(t,{A:()=>M});s(96540);var a=s(18215),r=s(7131),n=s(74848);function l(e){let{children:t,className:s}=e;return(0,n.jsx)("article",{className:s,children:t})}var i=s(28774);const o={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:s,isBlogPostPage:l}=(0,r.e)(),{permalink:c,title:m}=s,d=l?"h1":"h2";return(0,n.jsx)(d,{className:(0,a.A)(o.title,t),children:l?m:(0,n.jsx)(i.A,{to:c,children:m})})}var m=s(21312),d=s(53465),u=s(36266);const h={container:"container_mt6G"};function g(e){let{readingTime:t}=e;const s=function(){const{selectMessage:e}=(0,d.W)();return t=>{const s=Math.ceil(t);return e(s,(0,m.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:s}))}}();return(0,n.jsx)(n.Fragment,{children:s(t)})}function x(e){let{date:t,formattedDate:s}=e;return(0,n.jsx)("time",{dateTime:t,children:s})}function f(){return(0,n.jsx)(n.Fragment,{children:" \xb7 "})}function j(e){let{className:t}=e;const{metadata:s}=(0,r.e)(),{date:l,readingTime:i}=s,o=(0,u.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,n.jsxs)("div",{className:(0,a.A)(h.container,"margin-vert--md",t),children:[(0,n.jsx)(x,{date:l,formattedDate:(c=l,o.format(new Date(c)))}),void 0!==i&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(f,{}),(0,n.jsx)(g,{readingTime:i})]})]});var c}function b(e){return e.href?(0,n.jsx)(i.A,{...e}):(0,n.jsx)(n.Fragment,{children:e.children})}function p(e){let{author:t,className:s}=e;const{name:r,title:l,url:i,imageURL:o,email:c}=t,m=i||c&&`mailto:${c}`||void 0;return(0,n.jsxs)("div",{className:(0,a.A)("avatar margin-bottom--sm",s),children:[o&&(0,n.jsx)(b,{href:m,className:"avatar__photo-link",children:(0,n.jsx)("img",{className:"avatar__photo",src:o,alt:r})}),r&&(0,n.jsxs)("div",{className:"avatar__intro",children:[(0,n.jsx)("div",{className:"avatar__name",children:(0,n.jsx)(b,{href:m,children:(0,n.jsx)("span",{children:r})})}),l&&(0,n.jsx)("small",{className:"avatar__subtitle",children:l})]})]})}const v={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function A(e){let{className:t}=e;const{metadata:{authors:s},assets:l}=(0,r.e)();if(0===s.length)return null;const i=s.every((e=>{let{name:t}=e;return!t}));return(0,n.jsx)("div",{className:(0,a.A)("margin-top--md margin-bottom--sm",i?v.imageOnlyAuthorRow:"row",t),children:s.map(((e,t)=>(0,n.jsx)("div",{className:(0,a.A)(!i&&"col col--6",i?v.imageOnlyAuthorCol:v.authorCol),children:(0,n.jsx)(p,{author:{...e,imageURL:l.authorsImageUrls[t]??e.imageURL}})},t)))})}function N(){return(0,n.jsxs)("header",{children:[(0,n.jsx)(c,{}),(0,n.jsx)(j,{}),(0,n.jsx)(A,{})]})}var _=s(70440),k=s(11544);function P(e){let{children:t,className:s}=e;const{isBlogPostPage:l}=(0,r.e)();return(0,n.jsx)("div",{id:l?_.blogPostContainerID:void 0,className:(0,a.A)("markdown",s),children:(0,n.jsx)(k.A,{children:t})})}var w=s(17559),I=s(4336),T=s(62053);function y(){return(0,n.jsx)("b",{children:(0,n.jsx)(m.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read More"})})}function L(e){const{blogPostTitle:t,...s}=e;return(0,n.jsx)(i.A,{"aria-label":(0,m.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...s,children:(0,n.jsx)(y,{})})}function C(){const{metadata:e,isBlogPostPage:t}=(0,r.e)(),{tags:s,title:l,editUrl:i,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:m}=e,d=!t&&o,u=s.length>0;if(!(u||d||i))return null;if(t){const e=!!(i||m||c);return(0,n.jsxs)("footer",{className:"docusaurus-mt-lg",children:[u&&(0,n.jsx)("div",{className:(0,a.A)("row","margin-top--sm",w.G.blog.blogFooterEditMetaRow),children:(0,n.jsx)("div",{className:"col",children:(0,n.jsx)(T.A,{tags:s})})}),e&&(0,n.jsx)(I.A,{className:(0,a.A)("margin-top--sm",w.G.blog.blogFooterEditMetaRow),editUrl:i,lastUpdatedAt:m,lastUpdatedBy:c})]})}return(0,n.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[u&&(0,n.jsx)("div",{className:(0,a.A)("col",{"col--9":d}),children:(0,n.jsx)(T.A,{tags:s})}),d&&(0,n.jsx)("div",{className:(0,a.A)("col text--right",{"col--3":u}),children:(0,n.jsx)(L,{blogPostTitle:l,to:e.permalink})})]})}function M(e){let{children:t,className:s}=e;const i=function(){const{isBlogPostPage:e}=(0,r.e)();return e?void 0:"margin-bottom--xl"}();return(0,n.jsxs)(l,{className:(0,a.A)(i,s),children:[(0,n.jsx)(N,{}),(0,n.jsx)(P,{children:t}),(0,n.jsx)(C,{})]})}},7131:(e,t,s)=>{s.d(t,{e:()=>o,i:()=>i});var a=s(96540),r=s(89532),n=s(74848);const l=a.createContext(null);function i(e){let{children:t,content:s,isBlogPostPage:r=!1}=e;const i=function(e){let{content:t,isBlogPostPage:s}=e;return(0,a.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:s})),[t,s])}({content:s,isBlogPostPage:r});return(0,n.jsx)(l.Provider,{value:i,children:t})}function o(){const e=(0,a.useContext)(l);if(null===e)throw new r.dV("BlogPostProvider");return e}},53465:(e,t,s)=>{s.d(t,{W:()=>c});var a=s(96540),r=s(44586);const n=["zero","one","two","few","many","other"];function l(e){return n.filter((t=>e.includes(t)))}const i={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,r.A)();return(0,a.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:l(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),i}}),[e])}function c(){const e=o();return{selectMessage:(t,s)=>function(e,t,s){const a=e.split("|");if(1===a.length)return a[0];a.length>s.pluralForms.length&&console.error(`For locale=${s.locale}, a maximum of ${s.pluralForms.length} plural forms are expected (${s.pluralForms.join(",")}), but the message contains ${a.length}: ${e}`);const r=s.select(t),n=s.pluralForms.indexOf(r);return a[Math.min(n,a.length-1)]}(s,t,e)}}}}]); \ No newline at end of file diff --git a/assets/js/53596370.541b1a61.js b/assets/js/53596370.541b1a61.js new file mode 100644 index 0000000000..aee92de40a --- /dev/null +++ b/assets/js/53596370.541b1a61.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1421],{25552:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>l,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var o=s(74848),t=s(28453);const i={},l='"Levels of consensus"',c={id:"operating-scs/components/status-page/docs/levels_of_consensus",title:'"Levels of consensus"',description:"When implementing any system to be used by a group of potential users, there will be varying use cases and opinions about API's, programming languages, persistence models, authentication, authorization, deployment options and so on.",source:"@site/docs/04-operating-scs/components/status-page/docs/levels_of_consensus.md",sourceDirName:"04-operating-scs/components/status-page/docs",slug:"/operating-scs/components/status-page/docs/levels_of_consensus",permalink:"/docs/operating-scs/components/status-page/docs/levels_of_consensus",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page/docs/levels_of_consensus.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Components",permalink:"/docs/operating-scs/components/status-page/docs/components"},next:{title:"Monitoring",permalink:"/docs/category/monitoring"}},r={},a=[];function d(e){const n={h1:"h1",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"levels-of-consensus",children:'"Levels of consensus"'}),"\n",(0,o.jsx)(n.p,{children:"When implementing any system to be used by a group of potential users, there will be varying use cases and opinions about API's, programming languages, persistence models, authentication, authorization, deployment options and so on.\nHence, building a complete one-fits-all solution is difficult, but (while offering a pretty un-opinionated reference implementation) even finding consensus on a few basic concepts may make adaptation and integration of different solutions possible."}),"\n",(0,o.jsx)(n.p,{children:'The "levels" of consensus could be split into:'}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Consensus on..."})}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Resource Definition"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:'"What is an incident?"'}),"\n",(0,o.jsx)(n.li,{children:"Core REST API Spec"}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"General Architecture"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:'"Monolithic Web App or multiple components?"'}),"\n",(0,o.jsx)(n.li,{children:'"Use static password file or rely on OIDC provider?"'}),"\n",(0,o.jsxs)(n.li,{children:["(If any:) Interfaces between components:","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"AuthN mechanisms"}),"\n",(0,o.jsx)(n.li,{children:"AuthZ decisions"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Implementation of core component(s)"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:'"Use reference implementation components?"'}),"\n",(0,o.jsx)(n.li,{children:'"Go vs. JavaScript?"'}),"\n",(0,o.jsx)(n.li,{children:'"Postgres vs. MySQL?"'}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Choice of all used components"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:'"Policy: Istio vs. traefik?"'}),"\n",(0,o.jsx)(n.li,{children:'"Deployment: Helm vs. ansible?"'}),"\n",(0,o.jsx)(n.li,{children:'"dex vs. keycloak vs. zitadel?"'}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"Every user of the Status Page (API) should be able to either make full use of the full reference implementation, building little to none on their own; Or just pick core concepts/API's/automation and build partial compatibility."}),"\n",(0,o.jsx)(n.p,{children:'E.g. while the value on agreeing on every aspect would bring the most value, this most likely is not likely to happen, but adopting only the "Resource Definition", should ideally bring value already.'})]})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>c});var o=s(96540);const t={},i=o.createContext(t);function l(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/53f25e30.9e4b9bb0.js b/assets/js/53f25e30.9e4b9bb0.js new file mode 100644 index 0000000000..604813fdc0 --- /dev/null +++ b/assets/js/53f25e30.9e4b9bb0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[332],{19995:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>u});var o=t(74848),s=t(28453);const r={},c="Infrastructure service endpoints",i={id:"operating-scs/components/monitoring/docs/infrastructure_services",title:"Infrastructure service endpoints",description:"This page contains instructions on how to enable probing of infrastructure service endpoints using blackbox exporter.",source:"@site/docs/04-operating-scs/components/monitoring/docs/infrastructure_services.md",sourceDirName:"04-operating-scs/components/monitoring/docs",slug:"/operating-scs/components/monitoring/docs/infrastructure_services",permalink:"/docs/operating-scs/components/monitoring/docs/infrastructure_services",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/infrastructure_services.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"K3s support",permalink:"/docs/operating-scs/components/monitoring/docs/k3s"},next:{title:"IaaS monitoring (experimental)",permalink:"/docs/operating-scs/components/monitoring/docs/iaas"}},a={},u=[];function p(e){const n={a:"a",code:"code",h1:"h1",p:"p",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"infrastructure-service-endpoints",children:"Infrastructure service endpoints"}),"\n",(0,o.jsxs)(n.p,{children:["This page contains instructions on how to enable probing of infrastructure service endpoints using ",(0,o.jsx)(n.a,{href:"https://github.com/prometheus/blackbox_exporter",children:"blackbox exporter"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"Infrastructure service endpoints can be probed using protocols such as HTTP, HTTPS, DNS, TCP, ICMP, and gRPC."}),"\n",(0,o.jsxs)(n.p,{children:["Blackbox exporter is a component of the ",(0,o.jsx)(n.a,{href:"https://github.com/dNationCloud/kubernetes-monitoring-stack",children:"monitoring stack"}),".\nTherefore, it can be deployed into the Observer cluster and configured simply by using the Helm chart values."]}),"\n",(0,o.jsxs)(n.p,{children:["To enable probing of infrastructure service endpoints with blackbox exporter, locate and uncomment the related section in ",(0,o.jsx)(n.code,{children:"values-observer.yaml"}),".\nThe sections related to blackbox exporter in the ",(0,o.jsx)(n.code,{children:"values-observer-scs.yaml"})," values file are already uncommented."]})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var o=t(96540);const s={},r=o.createContext(s);function c(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5447d460.0014e23d.js b/assets/js/5447d460.0014e23d.js new file mode 100644 index 0000000000..0b368bcf67 --- /dev/null +++ b/assets/js/5447d460.0014e23d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3881],{29181:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>r,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var i=n(74848),t=n(28453);const o={},r="Scopes and versions",c={id:"certification/scopes-versions",title:"Scopes and versions",description:"SCS provides a certification framework consisting of six different kinds of certificates of varying scope.",source:"@site/standards/certification/scopes-versions.md",sourceDirName:"certification",slug:"/certification/scopes-versions",permalink:"/standards/certification/scopes-versions",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"overview",permalink:"/standards/certification/overview"},next:{title:"SCS Compatible IaaS",permalink:"/standards/scs-compatible-iaas"}},a={},d=[];function l(e){const s={em:"em",h1:"h1",img:"img",li:"li",ol:"ol",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h1,{id:"scopes-and-versions",children:"Scopes and versions"}),"\n",(0,i.jsx)(s.p,{children:"SCS provides a certification framework consisting of six different kinds of certificates of varying scope.\nThese scopes can be sorted into two dimensions:"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.em,{children:"certification level"}),", of which there are three:","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"SCS-compatible"}),"\n",(0,i.jsx)(s.li,{children:"SCS-open"}),"\n",(0,i.jsx)(s.li,{children:"SCS-sovereign"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.em,{children:"cloud layer"}),", of which there are two:","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"infastructure as a service (IaaS)"}),"\n",(0,i.jsx)(s.li,{children:"Kubernetes as a service (KaaS)"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.p,{children:["So, for instance, a certificate can have the scope ",(0,i.jsx)(s.em,{children:"SCS-compatible IaaS"})," or ",(0,i.jsx)(s.em,{children:"SCS-sovereign KaaS"}),"."]}),"\n",(0,i.jsx)(s.p,{children:"Each scope corresponds to a set of standards. As these standards progress, so do the scopes, and we keep track of this by versioning. Each version undergoes a lifecycle of Draft, Stable, and Deprecated, and we aim to keep at most one version stable at the same time, with the exception of a transition period of 4 to 6 weeks."}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{alt:"Alt text",src:n(39479).A+"",width:"2728",height:"742"})})]})}function p(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},39479:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/image-123702bb74539962d7c6839715583f29.png"},28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>c});var i=n(96540);const t={},o=i.createContext(t);function r(e){const s=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/555.3fbe9c09.js b/assets/js/555.3fbe9c09.js new file mode 100644 index 0000000000..fca2589572 --- /dev/null +++ b/assets/js/555.3fbe9c09.js @@ -0,0 +1,2105 @@ +exports.id = 555; +exports.ids = [555]; +exports.modules = { + +/***/ 97375: +/***/ (function(module) { + +!function(e,t){ true?module.exports=t():0}(this,(function(){"use strict";return function(e,t){var r=t.prototype,n=r.format;r.format=function(e){var t=this,r=this.$locale();if(!this.isValid())return n.bind(this)(e);var s=this.$utils(),a=(e||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,(function(e){switch(e){case"Q":return Math.ceil((t.$M+1)/3);case"Do":return r.ordinal(t.$D);case"gggg":return t.weekYear();case"GGGG":return t.isoWeekYear();case"wo":return r.ordinal(t.week(),"W");case"w":case"ww":return s.s(t.week(),"w"===e?1:2,"0");case"W":case"WW":return s.s(t.isoWeek(),"W"===e?1:2,"0");case"k":case"kk":return s.s(String(0===t.$H?24:t.$H),"k"===e?1:2,"0");case"X":return Math.floor(t.$d.getTime()/1e3);case"x":return t.$d.getTime();case"z":return"["+t.offsetName()+"]";case"zzz":return"["+t.offsetName("long")+"]";default:return e}}));return n.bind(this)(a)}}})); + +/***/ }), + +/***/ 90445: +/***/ (function(module) { + +!function(e,t){ true?module.exports=t():0}(this,(function(){"use strict";var e={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},t=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,n=/\d\d/,r=/\d\d?/,i=/\d*[^-_:/,()\s\d]+/,o={},s=function(e){return(e=+e)+(e>68?1900:2e3)};var a=function(e){return function(t){this[e]=+t}},f=[/[+-]\d\d:?(\d\d)?|Z/,function(e){(this.zone||(this.zone={})).offset=function(e){if(!e)return 0;if("Z"===e)return 0;var t=e.match(/([+-]|\d\d)/g),n=60*t[1]+(+t[2]||0);return 0===n?0:"+"===t[0]?-n:n}(e)}],h=function(e){var t=o[e];return t&&(t.indexOf?t:t.s.concat(t.f))},u=function(e,t){var n,r=o.meridiem;if(r){for(var i=1;i<=24;i+=1)if(e.indexOf(r(i,0,t))>-1){n=i>12;break}}else n=e===(t?"pm":"PM");return n},d={A:[i,function(e){this.afternoon=u(e,!1)}],a:[i,function(e){this.afternoon=u(e,!0)}],S:[/\d/,function(e){this.milliseconds=100*+e}],SS:[n,function(e){this.milliseconds=10*+e}],SSS:[/\d{3}/,function(e){this.milliseconds=+e}],s:[r,a("seconds")],ss:[r,a("seconds")],m:[r,a("minutes")],mm:[r,a("minutes")],H:[r,a("hours")],h:[r,a("hours")],HH:[r,a("hours")],hh:[r,a("hours")],D:[r,a("day")],DD:[n,a("day")],Do:[i,function(e){var t=o.ordinal,n=e.match(/\d+/);if(this.day=n[0],t)for(var r=1;r<=31;r+=1)t(r).replace(/\[|\]/g,"")===e&&(this.day=r)}],M:[r,a("month")],MM:[n,a("month")],MMM:[i,function(e){var t=h("months"),n=(h("monthsShort")||t.map((function(e){return e.slice(0,3)}))).indexOf(e)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[i,function(e){var t=h("months").indexOf(e)+1;if(t<1)throw new Error;this.month=t%12||t}],Y:[/[+-]?\d+/,a("year")],YY:[n,function(e){this.year=s(e)}],YYYY:[/\d{4}/,a("year")],Z:f,ZZ:f};function c(n){var r,i;r=n,i=o&&o.formats;for(var s=(n=r.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(t,n,r){var o=r&&r.toUpperCase();return n||i[r]||e[r]||i[o].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(e,t,n){return t||n.slice(1)}))}))).match(t),a=s.length,f=0;f<a;f+=1){var h=s[f],u=d[h],c=u&&u[0],l=u&&u[1];s[f]=l?{regex:c,parser:l}:h.replace(/^\[|\]$/g,"")}return function(e){for(var t={},n=0,r=0;n<a;n+=1){var i=s[n];if("string"==typeof i)r+=i.length;else{var o=i.regex,f=i.parser,h=e.slice(r),u=o.exec(h)[0];f.call(t,u),e=e.replace(u,"")}}return function(e){var t=e.afternoon;if(void 0!==t){var n=e.hours;t?n<12&&(e.hours+=12):12===n&&(e.hours=0),delete e.afternoon}}(t),t}}return function(e,t,n){n.p.customParseFormat=!0,e&&e.parseTwoDigitYear&&(s=e.parseTwoDigitYear);var r=t.prototype,i=r.parse;r.parse=function(e){var t=e.date,r=e.utc,s=e.args;this.$u=r;var a=s[1];if("string"==typeof a){var f=!0===s[2],h=!0===s[3],u=f||h,d=s[2];h&&(d=s[2]),o=this.$locale(),!f&&d&&(o=n.Ls[d]),this.$d=function(e,t,n){try{if(["x","X"].indexOf(t)>-1)return new Date(("X"===t?1e3:1)*e);var r=c(t)(e),i=r.year,o=r.month,s=r.day,a=r.hours,f=r.minutes,h=r.seconds,u=r.milliseconds,d=r.zone,l=new Date,m=s||(i||o?1:l.getDate()),M=i||l.getFullYear(),Y=0;i&&!o||(Y=o>0?o-1:l.getMonth());var p=a||0,v=f||0,D=h||0,g=u||0;return d?new Date(Date.UTC(M,Y,m,p,v,D,g+60*d.offset*1e3)):n?new Date(Date.UTC(M,Y,m,p,v,D,g)):new Date(M,Y,m,p,v,D,g)}catch(e){return new Date("")}}(t,a,r),this.init(),d&&!0!==d&&(this.$L=this.locale(d).$L),u&&t!=this.format(a)&&(this.$d=new Date("")),o={}}else if(a instanceof Array)for(var l=a.length,m=1;m<=l;m+=1){s[1]=a[m-1];var M=n.apply(this,s);if(M.isValid()){this.$d=M.$d,this.$L=M.$L,this.init();break}m===l&&(this.$d=new Date(""))}else i.call(this,e)}}})); + +/***/ }), + +/***/ 68313: +/***/ (function(module) { + +!function(e,t){ true?module.exports=t():0}(this,(function(){"use strict";var e="day";return function(t,i,s){var a=function(t){return t.add(4-t.isoWeekday(),e)},d=i.prototype;d.isoWeekYear=function(){return a(this).year()},d.isoWeek=function(t){if(!this.$utils().u(t))return this.add(7*(t-this.isoWeek()),e);var i,d,n,o,r=a(this),u=(i=this.isoWeekYear(),d=this.$u,n=(d?s.utc:s)().year(i).startOf("year"),o=4-n.isoWeekday(),n.isoWeekday()>4&&(o+=7),n.add(o,e));return r.diff(u,"week")+1},d.isoWeekday=function(e){return this.$utils().u(e)?this.day()||7:this.day(this.day()%7?e:e-7)};var n=d.startOf;d.startOf=function(e,t){var i=this.$utils(),s=!!i.u(t)||t;return"isoweek"===i.p(e)?s?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):n.bind(this)(e,t)}}})); + +/***/ }), + +/***/ 71555: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(16750); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74353); +/* harmony import */ var dayjs_plugin_isoWeek_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(68313); +/* harmony import */ var dayjs_plugin_customParseFormat_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(90445); +/* harmony import */ var dayjs_plugin_advancedFormat_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(97375); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(26312); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(99418); + + + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [6, 8, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 32, 33, 35, 37], $V1 = [1, 25], $V2 = [1, 26], $V3 = [1, 27], $V4 = [1, 28], $V5 = [1, 29], $V6 = [1, 30], $V7 = [1, 31], $V8 = [1, 9], $V9 = [1, 10], $Va = [1, 11], $Vb = [1, 12], $Vc = [1, 13], $Vd = [1, 14], $Ve = [1, 15], $Vf = [1, 16], $Vg = [1, 18], $Vh = [1, 19], $Vi = [1, 20], $Vj = [1, 21], $Vk = [1, 22], $Vl = [1, 24], $Vm = [1, 32]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "gantt": 4, "document": 5, "EOF": 6, "line": 7, "SPACE": 8, "statement": 9, "NL": 10, "weekday": 11, "weekday_monday": 12, "weekday_tuesday": 13, "weekday_wednesday": 14, "weekday_thursday": 15, "weekday_friday": 16, "weekday_saturday": 17, "weekday_sunday": 18, "dateFormat": 19, "inclusiveEndDates": 20, "topAxis": 21, "axisFormat": 22, "tickInterval": 23, "excludes": 24, "includes": 25, "todayMarker": 26, "title": 27, "acc_title": 28, "acc_title_value": 29, "acc_descr": 30, "acc_descr_value": 31, "acc_descr_multiline_value": 32, "section": 33, "clickStatement": 34, "taskTxt": 35, "taskData": 36, "click": 37, "callbackname": 38, "callbackargs": 39, "href": 40, "clickStatementDebug": 41, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "gantt", 6: "EOF", 8: "SPACE", 10: "NL", 12: "weekday_monday", 13: "weekday_tuesday", 14: "weekday_wednesday", 15: "weekday_thursday", 16: "weekday_friday", 17: "weekday_saturday", 18: "weekday_sunday", 19: "dateFormat", 20: "inclusiveEndDates", 21: "topAxis", 22: "axisFormat", 23: "tickInterval", 24: "excludes", 25: "includes", 26: "todayMarker", 27: "title", 28: "acc_title", 29: "acc_title_value", 30: "acc_descr", 31: "acc_descr_value", 32: "acc_descr_multiline_value", 33: "section", 35: "taskTxt", 36: "taskData", 37: "click", 38: "callbackname", 39: "callbackargs", 40: "href" }, + productions_: [0, [3, 3], [5, 0], [5, 2], [7, 2], [7, 1], [7, 1], [7, 1], [11, 1], [11, 1], [11, 1], [11, 1], [11, 1], [11, 1], [11, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 2], [9, 2], [9, 1], [9, 1], [9, 1], [9, 2], [34, 2], [34, 3], [34, 3], [34, 4], [34, 3], [34, 4], [34, 2], [41, 2], [41, 3], [41, 3], [41, 4], [41, 3], [41, 4], [41, 2]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 1: + return $$[$0 - 1]; + case 2: + this.$ = []; + break; + case 3: + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + break; + case 4: + case 5: + this.$ = $$[$0]; + break; + case 6: + case 7: + this.$ = []; + break; + case 8: + yy.setWeekday("monday"); + break; + case 9: + yy.setWeekday("tuesday"); + break; + case 10: + yy.setWeekday("wednesday"); + break; + case 11: + yy.setWeekday("thursday"); + break; + case 12: + yy.setWeekday("friday"); + break; + case 13: + yy.setWeekday("saturday"); + break; + case 14: + yy.setWeekday("sunday"); + break; + case 15: + yy.setDateFormat($$[$0].substr(11)); + this.$ = $$[$0].substr(11); + break; + case 16: + yy.enableInclusiveEndDates(); + this.$ = $$[$0].substr(18); + break; + case 17: + yy.TopAxis(); + this.$ = $$[$0].substr(8); + break; + case 18: + yy.setAxisFormat($$[$0].substr(11)); + this.$ = $$[$0].substr(11); + break; + case 19: + yy.setTickInterval($$[$0].substr(13)); + this.$ = $$[$0].substr(13); + break; + case 20: + yy.setExcludes($$[$0].substr(9)); + this.$ = $$[$0].substr(9); + break; + case 21: + yy.setIncludes($$[$0].substr(9)); + this.$ = $$[$0].substr(9); + break; + case 22: + yy.setTodayMarker($$[$0].substr(12)); + this.$ = $$[$0].substr(12); + break; + case 24: + yy.setDiagramTitle($$[$0].substr(6)); + this.$ = $$[$0].substr(6); + break; + case 25: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 26: + case 27: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 28: + yy.addSection($$[$0].substr(8)); + this.$ = $$[$0].substr(8); + break; + case 30: + yy.addTask($$[$0 - 1], $$[$0]); + this.$ = "task"; + break; + case 31: + this.$ = $$[$0 - 1]; + yy.setClickEvent($$[$0 - 1], $$[$0], null); + break; + case 32: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 33: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], null); + yy.setLink($$[$0 - 2], $$[$0]); + break; + case 34: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 2], $$[$0 - 1]); + yy.setLink($$[$0 - 3], $$[$0]); + break; + case 35: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 2], $$[$0], null); + yy.setLink($$[$0 - 2], $$[$0 - 1]); + break; + case 36: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 1], $$[$0]); + yy.setLink($$[$0 - 3], $$[$0 - 2]); + break; + case 37: + this.$ = $$[$0 - 1]; + yy.setLink($$[$0 - 1], $$[$0]); + break; + case 38: + case 44: + this.$ = $$[$0 - 1] + " " + $$[$0]; + break; + case 39: + case 40: + case 42: + this.$ = $$[$0 - 2] + " " + $$[$0 - 1] + " " + $$[$0]; + break; + case 41: + case 43: + this.$ = $$[$0 - 3] + " " + $$[$0 - 2] + " " + $$[$0 - 1] + " " + $$[$0]; + break; + } + }, + table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: [1, 6], 9: 7, 10: [1, 8], 11: 17, 12: $V1, 13: $V2, 14: $V3, 15: $V4, 16: $V5, 17: $V6, 18: $V7, 19: $V8, 20: $V9, 21: $Va, 22: $Vb, 23: $Vc, 24: $Vd, 25: $Ve, 26: $Vf, 27: $Vg, 28: $Vh, 30: $Vi, 32: $Vj, 33: $Vk, 34: 23, 35: $Vl, 37: $Vm }, o($V0, [2, 7], { 1: [2, 1] }), o($V0, [2, 3]), { 9: 33, 11: 17, 12: $V1, 13: $V2, 14: $V3, 15: $V4, 16: $V5, 17: $V6, 18: $V7, 19: $V8, 20: $V9, 21: $Va, 22: $Vb, 23: $Vc, 24: $Vd, 25: $Ve, 26: $Vf, 27: $Vg, 28: $Vh, 30: $Vi, 32: $Vj, 33: $Vk, 34: 23, 35: $Vl, 37: $Vm }, o($V0, [2, 5]), o($V0, [2, 6]), o($V0, [2, 15]), o($V0, [2, 16]), o($V0, [2, 17]), o($V0, [2, 18]), o($V0, [2, 19]), o($V0, [2, 20]), o($V0, [2, 21]), o($V0, [2, 22]), o($V0, [2, 23]), o($V0, [2, 24]), { 29: [1, 34] }, { 31: [1, 35] }, o($V0, [2, 27]), o($V0, [2, 28]), o($V0, [2, 29]), { 36: [1, 36] }, o($V0, [2, 8]), o($V0, [2, 9]), o($V0, [2, 10]), o($V0, [2, 11]), o($V0, [2, 12]), o($V0, [2, 13]), o($V0, [2, 14]), { 38: [1, 37], 40: [1, 38] }, o($V0, [2, 4]), o($V0, [2, 25]), o($V0, [2, 26]), o($V0, [2, 30]), o($V0, [2, 31], { 39: [1, 39], 40: [1, 40] }), o($V0, [2, 37], { 38: [1, 41] }), o($V0, [2, 32], { 40: [1, 42] }), o($V0, [2, 33]), o($V0, [2, 35], { 39: [1, 43] }), o($V0, [2, 34]), o($V0, [2, 36])], + defaultActions: {}, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.begin("open_directive"); + return "open_directive"; + case 1: + this.begin("acc_title"); + return 28; + case 2: + this.popState(); + return "acc_title_value"; + case 3: + this.begin("acc_descr"); + return 30; + case 4: + this.popState(); + return "acc_descr_value"; + case 5: + this.begin("acc_descr_multiline"); + break; + case 6: + this.popState(); + break; + case 7: + return "acc_descr_multiline_value"; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + return 10; + case 12: + break; + case 13: + break; + case 14: + this.begin("href"); + break; + case 15: + this.popState(); + break; + case 16: + return 40; + case 17: + this.begin("callbackname"); + break; + case 18: + this.popState(); + break; + case 19: + this.popState(); + this.begin("callbackargs"); + break; + case 20: + return 38; + case 21: + this.popState(); + break; + case 22: + return 39; + case 23: + this.begin("click"); + break; + case 24: + this.popState(); + break; + case 25: + return 37; + case 26: + return 4; + case 27: + return 19; + case 28: + return 20; + case 29: + return 21; + case 30: + return 22; + case 31: + return 23; + case 32: + return 25; + case 33: + return 24; + case 34: + return 26; + case 35: + return 12; + case 36: + return 13; + case 37: + return 14; + case 38: + return 15; + case 39: + return 16; + case 40: + return 17; + case 41: + return 18; + case 42: + return "date"; + case 43: + return 27; + case 44: + return "accDescription"; + case 45: + return 33; + case 46: + return 35; + case 47: + return 36; + case 48: + return ":"; + case 49: + return 6; + case 50: + return "INVALID"; + } + }, + rules: [/^(?:%%\{)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:%%(?!\{)*[^\n]*)/i, /^(?:[^\}]%%*[^\n]*)/i, /^(?:%%*[^\n]*[\n]*)/i, /^(?:[\n]+)/i, /^(?:\s+)/i, /^(?:%[^\n]*)/i, /^(?:href[\s]+["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:call[\s]+)/i, /^(?:\([\s]*\))/i, /^(?:\()/i, /^(?:[^(]*)/i, /^(?:\))/i, /^(?:[^)]*)/i, /^(?:click[\s]+)/i, /^(?:[\s\n])/i, /^(?:[^\s\n]*)/i, /^(?:gantt\b)/i, /^(?:dateFormat\s[^#\n;]+)/i, /^(?:inclusiveEndDates\b)/i, /^(?:topAxis\b)/i, /^(?:axisFormat\s[^#\n;]+)/i, /^(?:tickInterval\s[^#\n;]+)/i, /^(?:includes\s[^#\n;]+)/i, /^(?:excludes\s[^#\n;]+)/i, /^(?:todayMarker\s[^\n;]+)/i, /^(?:weekday\s+monday\b)/i, /^(?:weekday\s+tuesday\b)/i, /^(?:weekday\s+wednesday\b)/i, /^(?:weekday\s+thursday\b)/i, /^(?:weekday\s+friday\b)/i, /^(?:weekday\s+saturday\b)/i, /^(?:weekday\s+sunday\b)/i, /^(?:\d\d\d\d-\d\d-\d\d\b)/i, /^(?:title\s[^\n]+)/i, /^(?:accDescription\s[^#\n;]+)/i, /^(?:section\s[^\n]+)/i, /^(?:[^:\n]+)/i, /^(?::[^#\n;]+)/i, /^(?::)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "acc_descr_multiline": { "rules": [6, 7], "inclusive": false }, "acc_descr": { "rules": [4], "inclusive": false }, "acc_title": { "rules": [2], "inclusive": false }, "callbackargs": { "rules": [21, 22], "inclusive": false }, "callbackname": { "rules": [18, 19, 20], "inclusive": false }, "href": { "rules": [15, 16], "inclusive": false }, "click": { "rules": [24, 25], "inclusive": false }, "INITIAL": { "rules": [0, 1, 3, 5, 8, 9, 10, 11, 12, 13, 14, 17, 23, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const ganttParser = parser; +dayjs__WEBPACK_IMPORTED_MODULE_1__.extend(dayjs_plugin_isoWeek_js__WEBPACK_IMPORTED_MODULE_2__); +dayjs__WEBPACK_IMPORTED_MODULE_1__.extend(dayjs_plugin_customParseFormat_js__WEBPACK_IMPORTED_MODULE_3__); +dayjs__WEBPACK_IMPORTED_MODULE_1__.extend(dayjs_plugin_advancedFormat_js__WEBPACK_IMPORTED_MODULE_4__); +let dateFormat = ""; +let axisFormat = ""; +let tickInterval = void 0; +let todayMarker = ""; +let includes = []; +let excludes = []; +let links = {}; +let sections = []; +let tasks = []; +let currentSection = ""; +let displayMode = ""; +const tags = ["active", "done", "crit", "milestone"]; +let funs = []; +let inclusiveEndDates = false; +let topAxis = false; +let weekday = "sunday"; +let lastOrder = 0; +const clear = function() { + sections = []; + tasks = []; + currentSection = ""; + funs = []; + taskCnt = 0; + lastTask = void 0; + lastTaskID = void 0; + rawTasks = []; + dateFormat = ""; + axisFormat = ""; + displayMode = ""; + tickInterval = void 0; + todayMarker = ""; + includes = []; + excludes = []; + inclusiveEndDates = false; + topAxis = false; + lastOrder = 0; + links = {}; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.v)(); + weekday = "sunday"; +}; +const setAxisFormat = function(txt) { + axisFormat = txt; +}; +const getAxisFormat = function() { + return axisFormat; +}; +const setTickInterval = function(txt) { + tickInterval = txt; +}; +const getTickInterval = function() { + return tickInterval; +}; +const setTodayMarker = function(txt) { + todayMarker = txt; +}; +const getTodayMarker = function() { + return todayMarker; +}; +const setDateFormat = function(txt) { + dateFormat = txt; +}; +const enableInclusiveEndDates = function() { + inclusiveEndDates = true; +}; +const endDatesAreInclusive = function() { + return inclusiveEndDates; +}; +const enableTopAxis = function() { + topAxis = true; +}; +const topAxisEnabled = function() { + return topAxis; +}; +const setDisplayMode = function(txt) { + displayMode = txt; +}; +const getDisplayMode = function() { + return displayMode; +}; +const getDateFormat = function() { + return dateFormat; +}; +const setIncludes = function(txt) { + includes = txt.toLowerCase().split(/[\s,]+/); +}; +const getIncludes = function() { + return includes; +}; +const setExcludes = function(txt) { + excludes = txt.toLowerCase().split(/[\s,]+/); +}; +const getExcludes = function() { + return excludes; +}; +const getLinks = function() { + return links; +}; +const addSection = function(txt) { + currentSection = txt; + sections.push(txt); +}; +const getSections = function() { + return sections; +}; +const getTasks = function() { + let allItemsProcessed = compileTasks(); + const maxDepth = 10; + let iterationCount = 0; + while (!allItemsProcessed && iterationCount < maxDepth) { + allItemsProcessed = compileTasks(); + iterationCount++; + } + tasks = rawTasks; + return tasks; +}; +const isInvalidDate = function(date, dateFormat2, excludes2, includes2) { + if (includes2.includes(date.format(dateFormat2.trim()))) { + return false; + } + if (date.isoWeekday() >= 6 && excludes2.includes("weekends")) { + return true; + } + if (excludes2.includes(date.format("dddd").toLowerCase())) { + return true; + } + return excludes2.includes(date.format(dateFormat2.trim())); +}; +const setWeekday = function(txt) { + weekday = txt; +}; +const getWeekday = function() { + return weekday; +}; +const checkTaskDates = function(task, dateFormat2, excludes2, includes2) { + if (!excludes2.length || task.manualEndTime) { + return; + } + let startTime; + if (task.startTime instanceof Date) { + startTime = dayjs__WEBPACK_IMPORTED_MODULE_1__(task.startTime); + } else { + startTime = dayjs__WEBPACK_IMPORTED_MODULE_1__(task.startTime, dateFormat2, true); + } + startTime = startTime.add(1, "d"); + let originalEndTime; + if (task.endTime instanceof Date) { + originalEndTime = dayjs__WEBPACK_IMPORTED_MODULE_1__(task.endTime); + } else { + originalEndTime = dayjs__WEBPACK_IMPORTED_MODULE_1__(task.endTime, dateFormat2, true); + } + const [fixedEndTime, renderEndTime] = fixTaskDates( + startTime, + originalEndTime, + dateFormat2, + excludes2, + includes2 + ); + task.endTime = fixedEndTime.toDate(); + task.renderEndTime = renderEndTime; +}; +const fixTaskDates = function(startTime, endTime, dateFormat2, excludes2, includes2) { + let invalid = false; + let renderEndTime = null; + while (startTime <= endTime) { + if (!invalid) { + renderEndTime = endTime.toDate(); + } + invalid = isInvalidDate(startTime, dateFormat2, excludes2, includes2); + if (invalid) { + endTime = endTime.add(1, "d"); + } + startTime = startTime.add(1, "d"); + } + return [endTime, renderEndTime]; +}; +const getStartDate = function(prevTime, dateFormat2, str) { + str = str.trim(); + const afterRePattern = /^after\s+(?<ids>[\d\w- ]+)/; + const afterStatement = afterRePattern.exec(str); + if (afterStatement !== null) { + let latestTask = null; + for (const id of afterStatement.groups.ids.split(" ")) { + let task = findTaskById(id); + if (task !== void 0 && (!latestTask || task.endTime > latestTask.endTime)) { + latestTask = task; + } + } + if (latestTask) { + return latestTask.endTime; + } + const today = /* @__PURE__ */ new Date(); + today.setHours(0, 0, 0, 0); + return today; + } + let mDate = dayjs__WEBPACK_IMPORTED_MODULE_1__(str, dateFormat2.trim(), true); + if (mDate.isValid()) { + return mDate.toDate(); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.debug("Invalid date:" + str); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.debug("With date format:" + dateFormat2.trim()); + const d = new Date(str); + if (d === void 0 || isNaN(d.getTime()) || // WebKit browsers can mis-parse invalid dates to be ridiculously + // huge numbers, e.g. new Date('202304') gets parsed as January 1, 202304. + // This can cause virtually infinite loops while rendering, so for the + // purposes of Gantt charts we'll just treat any date beyond 10,000 AD/BC as + // invalid. + d.getFullYear() < -1e4 || d.getFullYear() > 1e4) { + throw new Error("Invalid date:" + str); + } + return d; + } +}; +const parseDuration = function(str) { + const statement = /^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(str.trim()); + if (statement !== null) { + return [Number.parseFloat(statement[1]), statement[2]]; + } + return [NaN, "ms"]; +}; +const getEndDate = function(prevTime, dateFormat2, str, inclusive = false) { + str = str.trim(); + const untilRePattern = /^until\s+(?<ids>[\d\w- ]+)/; + const untilStatement = untilRePattern.exec(str); + if (untilStatement !== null) { + let earliestTask = null; + for (const id of untilStatement.groups.ids.split(" ")) { + let task = findTaskById(id); + if (task !== void 0 && (!earliestTask || task.startTime < earliestTask.startTime)) { + earliestTask = task; + } + } + if (earliestTask) { + return earliestTask.startTime; + } + const today = /* @__PURE__ */ new Date(); + today.setHours(0, 0, 0, 0); + return today; + } + let parsedDate = dayjs__WEBPACK_IMPORTED_MODULE_1__(str, dateFormat2.trim(), true); + if (parsedDate.isValid()) { + if (inclusive) { + parsedDate = parsedDate.add(1, "d"); + } + return parsedDate.toDate(); + } + let endTime = dayjs__WEBPACK_IMPORTED_MODULE_1__(prevTime); + const [durationValue, durationUnit] = parseDuration(str); + if (!Number.isNaN(durationValue)) { + const newEndTime = endTime.add(durationValue, durationUnit); + if (newEndTime.isValid()) { + endTime = newEndTime; + } + } + return endTime.toDate(); +}; +let taskCnt = 0; +const parseId = function(idStr) { + if (idStr === void 0) { + taskCnt = taskCnt + 1; + return "task" + taskCnt; + } + return idStr; +}; +const compileData = function(prevTask, dataStr) { + let ds; + if (dataStr.substr(0, 1) === ":") { + ds = dataStr.substr(1, dataStr.length); + } else { + ds = dataStr; + } + const data = ds.split(","); + const task = {}; + getTaskTags(data, task, tags); + for (let i = 0; i < data.length; i++) { + data[i] = data[i].trim(); + } + let endTimeData = ""; + switch (data.length) { + case 1: + task.id = parseId(); + task.startTime = prevTask.endTime; + endTimeData = data[0]; + break; + case 2: + task.id = parseId(); + task.startTime = getStartDate(void 0, dateFormat, data[0]); + endTimeData = data[1]; + break; + case 3: + task.id = parseId(data[0]); + task.startTime = getStartDate(void 0, dateFormat, data[1]); + endTimeData = data[2]; + break; + } + if (endTimeData) { + task.endTime = getEndDate(task.startTime, dateFormat, endTimeData, inclusiveEndDates); + task.manualEndTime = dayjs__WEBPACK_IMPORTED_MODULE_1__(endTimeData, "YYYY-MM-DD", true).isValid(); + checkTaskDates(task, dateFormat, excludes, includes); + } + return task; +}; +const parseData = function(prevTaskId, dataStr) { + let ds; + if (dataStr.substr(0, 1) === ":") { + ds = dataStr.substr(1, dataStr.length); + } else { + ds = dataStr; + } + const data = ds.split(","); + const task = {}; + getTaskTags(data, task, tags); + for (let i = 0; i < data.length; i++) { + data[i] = data[i].trim(); + } + switch (data.length) { + case 1: + task.id = parseId(); + task.startTime = { + type: "prevTaskEnd", + id: prevTaskId + }; + task.endTime = { + data: data[0] + }; + break; + case 2: + task.id = parseId(); + task.startTime = { + type: "getStartDate", + startData: data[0] + }; + task.endTime = { + data: data[1] + }; + break; + case 3: + task.id = parseId(data[0]); + task.startTime = { + type: "getStartDate", + startData: data[1] + }; + task.endTime = { + data: data[2] + }; + break; + } + return task; +}; +let lastTask; +let lastTaskID; +let rawTasks = []; +const taskDb = {}; +const addTask = function(descr, data) { + const rawTask = { + section: currentSection, + type: currentSection, + processed: false, + manualEndTime: false, + renderEndTime: null, + raw: { data }, + task: descr, + classes: [] + }; + const taskInfo = parseData(lastTaskID, data); + rawTask.raw.startTime = taskInfo.startTime; + rawTask.raw.endTime = taskInfo.endTime; + rawTask.id = taskInfo.id; + rawTask.prevTaskId = lastTaskID; + rawTask.active = taskInfo.active; + rawTask.done = taskInfo.done; + rawTask.crit = taskInfo.crit; + rawTask.milestone = taskInfo.milestone; + rawTask.order = lastOrder; + lastOrder++; + const pos = rawTasks.push(rawTask); + lastTaskID = rawTask.id; + taskDb[rawTask.id] = pos - 1; +}; +const findTaskById = function(id) { + const pos = taskDb[id]; + return rawTasks[pos]; +}; +const addTaskOrg = function(descr, data) { + const newTask = { + section: currentSection, + type: currentSection, + description: descr, + task: descr, + classes: [] + }; + const taskInfo = compileData(lastTask, data); + newTask.startTime = taskInfo.startTime; + newTask.endTime = taskInfo.endTime; + newTask.id = taskInfo.id; + newTask.active = taskInfo.active; + newTask.done = taskInfo.done; + newTask.crit = taskInfo.crit; + newTask.milestone = taskInfo.milestone; + lastTask = newTask; + tasks.push(newTask); +}; +const compileTasks = function() { + const compileTask = function(pos) { + const task = rawTasks[pos]; + let startTime = ""; + switch (rawTasks[pos].raw.startTime.type) { + case "prevTaskEnd": { + const prevTask = findTaskById(task.prevTaskId); + task.startTime = prevTask.endTime; + break; + } + case "getStartDate": + startTime = getStartDate(void 0, dateFormat, rawTasks[pos].raw.startTime.startData); + if (startTime) { + rawTasks[pos].startTime = startTime; + } + break; + } + if (rawTasks[pos].startTime) { + rawTasks[pos].endTime = getEndDate( + rawTasks[pos].startTime, + dateFormat, + rawTasks[pos].raw.endTime.data, + inclusiveEndDates + ); + if (rawTasks[pos].endTime) { + rawTasks[pos].processed = true; + rawTasks[pos].manualEndTime = dayjs__WEBPACK_IMPORTED_MODULE_1__( + rawTasks[pos].raw.endTime.data, + "YYYY-MM-DD", + true + ).isValid(); + checkTaskDates(rawTasks[pos], dateFormat, excludes, includes); + } + } + return rawTasks[pos].processed; + }; + let allProcessed = true; + for (const [i, rawTask] of rawTasks.entries()) { + compileTask(i); + allProcessed = allProcessed && rawTask.processed; + } + return allProcessed; +}; +const setLink = function(ids, _linkStr) { + let linkStr = _linkStr; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().securityLevel !== "loose") { + linkStr = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Jf)(_linkStr); + } + ids.split(",").forEach(function(id) { + let rawTask = findTaskById(id); + if (rawTask !== void 0) { + pushFun(id, () => { + window.open(linkStr, "_self"); + }); + links[id] = linkStr; + } + }); + setClass(ids, "clickable"); +}; +const setClass = function(ids, className) { + ids.split(",").forEach(function(id) { + let rawTask = findTaskById(id); + if (rawTask !== void 0) { + rawTask.classes.push(className); + } + }); +}; +const setClickFun = function(id, functionName, functionArgs) { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().securityLevel !== "loose") { + return; + } + if (functionName === void 0) { + return; + } + let argList = []; + if (typeof functionArgs === "string") { + argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); + for (let i = 0; i < argList.length; i++) { + let item = argList[i].trim(); + if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') { + item = item.substr(1, item.length - 2); + } + argList[i] = item; + } + } + if (argList.length === 0) { + argList.push(id); + } + let rawTask = findTaskById(id); + if (rawTask !== void 0) { + pushFun(id, () => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.u.runFunc(functionName, ...argList); + }); + } +}; +const pushFun = function(id, callbackFunction) { + funs.push( + function() { + const elem = document.querySelector(`[id="${id}"]`); + if (elem !== null) { + elem.addEventListener("click", function() { + callbackFunction(); + }); + } + }, + function() { + const elem = document.querySelector(`[id="${id}-text"]`); + if (elem !== null) { + elem.addEventListener("click", function() { + callbackFunction(); + }); + } + } + ); +}; +const setClickEvent = function(ids, functionName, functionArgs) { + ids.split(",").forEach(function(id) { + setClickFun(id, functionName, functionArgs); + }); + setClass(ids, "clickable"); +}; +const bindFunctions = function(element) { + funs.forEach(function(fun) { + fun(element); + }); +}; +const ganttDb = { + getConfig: () => (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().gantt, + clear, + setDateFormat, + getDateFormat, + enableInclusiveEndDates, + endDatesAreInclusive, + enableTopAxis, + topAxisEnabled, + setAxisFormat, + getAxisFormat, + setTickInterval, + getTickInterval, + setTodayMarker, + getTodayMarker, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.g, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.t, + setDisplayMode, + getDisplayMode, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.b, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.a, + addSection, + getSections, + getTasks, + addTask, + findTaskById, + addTaskOrg, + setIncludes, + getIncludes, + setExcludes, + getExcludes, + setClickEvent, + setLink, + getLinks, + bindFunctions, + parseDuration, + isInvalidDate, + setWeekday, + getWeekday +}; +function getTaskTags(data, task, tags2) { + let matchFound = true; + while (matchFound) { + matchFound = false; + tags2.forEach(function(t) { + const pattern = "^\\s*" + t + "\\s*$"; + const regex = new RegExp(pattern); + if (data[0].match(regex)) { + task[t] = true; + data.shift(1); + matchFound = true; + } + }); + } +} +const setConf = function() { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.debug("Something is calling, setConf, remove the call"); +}; +const mapWeekdayToTimeFunction = { + monday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMonday */ .ABi, + tuesday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeTuesday */ .PGu, + wednesday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeWednesday */ .GuW, + thursday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeThursday */ .Mol, + friday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeFriday */ .TUC, + saturday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeSaturday */ .rGn, + sunday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeSunday */ .YPH +}; +const getMaxIntersections = (tasks2, orderOffset) => { + let timeline = [...tasks2].map(() => -Infinity); + let sorted = [...tasks2].sort((a, b) => a.startTime - b.startTime || a.order - b.order); + let maxIntersections = 0; + for (const element of sorted) { + for (let j = 0; j < timeline.length; j++) { + if (element.startTime >= timeline[j]) { + timeline[j] = element.endTime; + element.order = j + orderOffset; + if (j > maxIntersections) { + maxIntersections = j; + } + break; + } + } + } + return maxIntersections; +}; +let w; +const draw = function(text, id, version, diagObj) { + const conf = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().gantt; + const securityLevel = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .select */ .Ltv)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + const elem = doc.getElementById(id); + w = elem.parentElement.offsetWidth; + if (w === void 0) { + w = 1200; + } + if (conf.useWidth !== void 0) { + w = conf.useWidth; + } + const taskArray = diagObj.db.getTasks(); + let categories = []; + for (const element of taskArray) { + categories.push(element.type); + } + categories = checkUnique(categories); + const categoryHeights = {}; + let h = 2 * conf.topPadding; + if (diagObj.db.getDisplayMode() === "compact" || conf.displayMode === "compact") { + const categoryElements = {}; + for (const element of taskArray) { + if (categoryElements[element.section] === void 0) { + categoryElements[element.section] = [element]; + } else { + categoryElements[element.section].push(element); + } + } + let intersections = 0; + for (const category of Object.keys(categoryElements)) { + const categoryHeight = getMaxIntersections(categoryElements[category], intersections) + 1; + intersections += categoryHeight; + h += categoryHeight * (conf.barHeight + conf.barGap); + categoryHeights[category] = categoryHeight; + } + } else { + h += taskArray.length * (conf.barHeight + conf.barGap); + for (const category of categories) { + categoryHeights[category] = taskArray.filter((task) => task.type === category).length; + } + } + elem.setAttribute("viewBox", "0 0 " + w + " " + h); + const svg = root.select(`[id="${id}"]`); + const timeScale = (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .scaleTime */ .w7C)().domain([ + (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .min */ .jkA)(taskArray, function(d) { + return d.startTime; + }), + (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .max */ .T9B)(taskArray, function(d) { + return d.endTime; + }) + ]).rangeRound([0, w - conf.leftPadding - conf.rightPadding]); + function taskCompare(a, b) { + const taskA = a.startTime; + const taskB = b.startTime; + let result = 0; + if (taskA > taskB) { + result = 1; + } else if (taskA < taskB) { + result = -1; + } + return result; + } + taskArray.sort(taskCompare); + makeGantt(taskArray, w, h); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.i)(svg, h, w, conf.useMaxWidth); + svg.append("text").text(diagObj.db.getDiagramTitle()).attr("x", w / 2).attr("y", conf.titleTopMargin).attr("class", "titleText"); + function makeGantt(tasks2, pageWidth, pageHeight) { + const barHeight = conf.barHeight; + const gap = barHeight + conf.barGap; + const topPadding = conf.topPadding; + const leftPadding = conf.leftPadding; + const colorScale = (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .scaleLinear */ .m4Y)().domain([0, categories.length]).range(["#00B9FA", "#F95002"]).interpolate(d3__WEBPACK_IMPORTED_MODULE_5__/* .interpolateHcl */ .bEH); + drawExcludeDays( + gap, + topPadding, + leftPadding, + pageWidth, + pageHeight, + tasks2, + diagObj.db.getExcludes(), + diagObj.db.getIncludes() + ); + makeGrid(leftPadding, topPadding, pageWidth, pageHeight); + drawRects(tasks2, gap, topPadding, leftPadding, barHeight, colorScale, pageWidth); + vertLabels(gap, topPadding); + drawToday(leftPadding, topPadding, pageWidth, pageHeight); + } + function drawRects(theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w2) { + const uniqueTaskOrderIds = [...new Set(theArray.map((item) => item.order))]; + const uniqueTasks = uniqueTaskOrderIds.map((id2) => theArray.find((item) => item.order === id2)); + svg.append("g").selectAll("rect").data(uniqueTasks).enter().append("rect").attr("x", 0).attr("y", function(d, i) { + i = d.order; + return i * theGap + theTopPad - 2; + }).attr("width", function() { + return w2 - conf.rightPadding / 2; + }).attr("height", theGap).attr("class", function(d) { + for (const [i, category] of categories.entries()) { + if (d.type === category) { + return "section section" + i % conf.numberSectionStyles; + } + } + return "section section0"; + }); + const rectangles = svg.append("g").selectAll("rect").data(theArray).enter(); + const links2 = diagObj.db.getLinks(); + rectangles.append("rect").attr("id", function(d) { + return d.id; + }).attr("rx", 3).attr("ry", 3).attr("x", function(d) { + if (d.milestone) { + return timeScale(d.startTime) + theSidePad + 0.5 * (timeScale(d.endTime) - timeScale(d.startTime)) - 0.5 * theBarHeight; + } + return timeScale(d.startTime) + theSidePad; + }).attr("y", function(d, i) { + i = d.order; + return i * theGap + theTopPad; + }).attr("width", function(d) { + if (d.milestone) { + return theBarHeight; + } + return timeScale(d.renderEndTime || d.endTime) - timeScale(d.startTime); + }).attr("height", theBarHeight).attr("transform-origin", function(d, i) { + i = d.order; + return (timeScale(d.startTime) + theSidePad + 0.5 * (timeScale(d.endTime) - timeScale(d.startTime))).toString() + "px " + (i * theGap + theTopPad + 0.5 * theBarHeight).toString() + "px"; + }).attr("class", function(d) { + const res = "task"; + let classStr = ""; + if (d.classes.length > 0) { + classStr = d.classes.join(" "); + } + let secNum = 0; + for (const [i, category] of categories.entries()) { + if (d.type === category) { + secNum = i % conf.numberSectionStyles; + } + } + let taskClass = ""; + if (d.active) { + if (d.crit) { + taskClass += " activeCrit"; + } else { + taskClass = " active"; + } + } else if (d.done) { + if (d.crit) { + taskClass = " doneCrit"; + } else { + taskClass = " done"; + } + } else { + if (d.crit) { + taskClass += " crit"; + } + } + if (taskClass.length === 0) { + taskClass = " task"; + } + if (d.milestone) { + taskClass = " milestone " + taskClass; + } + taskClass += secNum; + taskClass += " " + classStr; + return res + taskClass; + }); + rectangles.append("text").attr("id", function(d) { + return d.id + "-text"; + }).text(function(d) { + return d.task; + }).attr("font-size", conf.fontSize).attr("x", function(d) { + let startX = timeScale(d.startTime); + let endX = timeScale(d.renderEndTime || d.endTime); + if (d.milestone) { + startX += 0.5 * (timeScale(d.endTime) - timeScale(d.startTime)) - 0.5 * theBarHeight; + } + if (d.milestone) { + endX = startX + theBarHeight; + } + const textWidth = this.getBBox().width; + if (textWidth > endX - startX) { + if (endX + textWidth + 1.5 * conf.leftPadding > w2) { + return startX + theSidePad - 5; + } else { + return endX + theSidePad + 5; + } + } else { + return (endX - startX) / 2 + startX + theSidePad; + } + }).attr("y", function(d, i) { + i = d.order; + return i * theGap + conf.barHeight / 2 + (conf.fontSize / 2 - 2) + theTopPad; + }).attr("text-height", theBarHeight).attr("class", function(d) { + const startX = timeScale(d.startTime); + let endX = timeScale(d.endTime); + if (d.milestone) { + endX = startX + theBarHeight; + } + const textWidth = this.getBBox().width; + let classStr = ""; + if (d.classes.length > 0) { + classStr = d.classes.join(" "); + } + let secNum = 0; + for (const [i, category] of categories.entries()) { + if (d.type === category) { + secNum = i % conf.numberSectionStyles; + } + } + let taskType = ""; + if (d.active) { + if (d.crit) { + taskType = "activeCritText" + secNum; + } else { + taskType = "activeText" + secNum; + } + } + if (d.done) { + if (d.crit) { + taskType = taskType + " doneCritText" + secNum; + } else { + taskType = taskType + " doneText" + secNum; + } + } else { + if (d.crit) { + taskType = taskType + " critText" + secNum; + } + } + if (d.milestone) { + taskType += " milestoneText"; + } + if (textWidth > endX - startX) { + if (endX + textWidth + 1.5 * conf.leftPadding > w2) { + return classStr + " taskTextOutsideLeft taskTextOutside" + secNum + " " + taskType; + } else { + return classStr + " taskTextOutsideRight taskTextOutside" + secNum + " " + taskType + " width-" + textWidth; + } + } else { + return classStr + " taskText taskText" + secNum + " " + taskType + " width-" + textWidth; + } + }); + const securityLevel2 = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.c)().securityLevel; + if (securityLevel2 === "sandbox") { + let sandboxElement2; + sandboxElement2 = (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .select */ .Ltv)("#i" + id); + const doc2 = sandboxElement2.nodes()[0].contentDocument; + rectangles.filter(function(d) { + return links2[d.id] !== void 0; + }).each(function(o) { + var taskRect = doc2.querySelector("#" + o.id); + var taskText = doc2.querySelector("#" + o.id + "-text"); + const oldParent = taskRect.parentNode; + var Link = doc2.createElement("a"); + Link.setAttribute("xlink:href", links2[o.id]); + Link.setAttribute("target", "_top"); + oldParent.appendChild(Link); + Link.appendChild(taskRect); + Link.appendChild(taskText); + }); + } + } + function drawExcludeDays(theGap, theTopPad, theSidePad, w2, h2, tasks2, excludes2, includes2) { + if (excludes2.length === 0 && includes2.length === 0) { + return; + } + let minTime; + let maxTime; + for (const { startTime, endTime } of tasks2) { + if (minTime === void 0 || startTime < minTime) { + minTime = startTime; + } + if (maxTime === void 0 || endTime > maxTime) { + maxTime = endTime; + } + } + if (!minTime || !maxTime) { + return; + } + if (dayjs__WEBPACK_IMPORTED_MODULE_1__(maxTime).diff(dayjs__WEBPACK_IMPORTED_MODULE_1__(minTime), "year") > 5) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.l.warn( + "The difference between the min and max time is more than 5 years. This will cause performance issues. Skipping drawing exclude days." + ); + return; + } + const dateFormat2 = diagObj.db.getDateFormat(); + const excludeRanges = []; + let range = null; + let d = dayjs__WEBPACK_IMPORTED_MODULE_1__(minTime); + while (d.valueOf() <= maxTime) { + if (diagObj.db.isInvalidDate(d, dateFormat2, excludes2, includes2)) { + if (!range) { + range = { + start: d, + end: d + }; + } else { + range.end = d; + } + } else { + if (range) { + excludeRanges.push(range); + range = null; + } + } + d = d.add(1, "d"); + } + const rectangles = svg.append("g").selectAll("rect").data(excludeRanges).enter(); + rectangles.append("rect").attr("id", function(d2) { + return "exclude-" + d2.start.format("YYYY-MM-DD"); + }).attr("x", function(d2) { + return timeScale(d2.start) + theSidePad; + }).attr("y", conf.gridLineStartPadding).attr("width", function(d2) { + const renderEnd = d2.end.add(1, "day"); + return timeScale(renderEnd) - timeScale(d2.start); + }).attr("height", h2 - theTopPad - conf.gridLineStartPadding).attr("transform-origin", function(d2, i) { + return (timeScale(d2.start) + theSidePad + 0.5 * (timeScale(d2.end) - timeScale(d2.start))).toString() + "px " + (i * theGap + 0.5 * h2).toString() + "px"; + }).attr("class", "exclude-range"); + } + function makeGrid(theSidePad, theTopPad, w2, h2) { + let bottomXAxis = (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .axisBottom */ .l78)(timeScale).tickSize(-h2 + theTopPad + conf.gridLineStartPadding).tickFormat((0,d3__WEBPACK_IMPORTED_MODULE_5__/* .timeFormat */ .DCK)(diagObj.db.getAxisFormat() || conf.axisFormat || "%Y-%m-%d")); + const reTickInterval = /^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/; + const resultTickInterval = reTickInterval.exec( + diagObj.db.getTickInterval() || conf.tickInterval + ); + if (resultTickInterval !== null) { + const every = resultTickInterval[1]; + const interval = resultTickInterval[2]; + const weekday2 = diagObj.db.getWeekday() || conf.weekday; + switch (interval) { + case "millisecond": + bottomXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMillisecond */ .t6C.every(every)); + break; + case "second": + bottomXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeSecond */ .ucG.every(every)); + break; + case "minute": + bottomXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMinute */ .wXd.every(every)); + break; + case "hour": + bottomXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeHour */ .Agd.every(every)); + break; + case "day": + bottomXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeDay */ .UAC.every(every)); + break; + case "week": + bottomXAxis.ticks(mapWeekdayToTimeFunction[weekday2].every(every)); + break; + case "month": + bottomXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMonth */ .Ui6.every(every)); + break; + } + } + svg.append("g").attr("class", "grid").attr("transform", "translate(" + theSidePad + ", " + (h2 - 50) + ")").call(bottomXAxis).selectAll("text").style("text-anchor", "middle").attr("fill", "#000").attr("stroke", "none").attr("font-size", 10).attr("dy", "1em"); + if (diagObj.db.topAxisEnabled() || conf.topAxis) { + let topXAxis = (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .axisTop */ .tlR)(timeScale).tickSize(-h2 + theTopPad + conf.gridLineStartPadding).tickFormat((0,d3__WEBPACK_IMPORTED_MODULE_5__/* .timeFormat */ .DCK)(diagObj.db.getAxisFormat() || conf.axisFormat || "%Y-%m-%d")); + if (resultTickInterval !== null) { + const every = resultTickInterval[1]; + const interval = resultTickInterval[2]; + const weekday2 = diagObj.db.getWeekday() || conf.weekday; + switch (interval) { + case "millisecond": + topXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMillisecond */ .t6C.every(every)); + break; + case "second": + topXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeSecond */ .ucG.every(every)); + break; + case "minute": + topXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMinute */ .wXd.every(every)); + break; + case "hour": + topXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeHour */ .Agd.every(every)); + break; + case "day": + topXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeDay */ .UAC.every(every)); + break; + case "week": + topXAxis.ticks(mapWeekdayToTimeFunction[weekday2].every(every)); + break; + case "month": + topXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMonth */ .Ui6.every(every)); + break; + } + } + svg.append("g").attr("class", "grid").attr("transform", "translate(" + theSidePad + ", " + theTopPad + ")").call(topXAxis).selectAll("text").style("text-anchor", "middle").attr("fill", "#000").attr("stroke", "none").attr("font-size", 10); + } + } + function vertLabels(theGap, theTopPad) { + let prevGap = 0; + const numOccurrences = Object.keys(categoryHeights).map((d) => [d, categoryHeights[d]]); + svg.append("g").selectAll("text").data(numOccurrences).enter().append(function(d) { + const rows = d[0].split(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_7__.e.lineBreakRegex); + const dy = -(rows.length - 1) / 2; + const svgLabel = doc.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("dy", dy + "em"); + for (const [j, row] of rows.entries()) { + const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttribute("alignment-baseline", "central"); + tspan.setAttribute("x", "10"); + if (j > 0) { + tspan.setAttribute("dy", "1em"); + } + tspan.textContent = row; + svgLabel.appendChild(tspan); + } + return svgLabel; + }).attr("x", 10).attr("y", function(d, i) { + if (i > 0) { + for (let j = 0; j < i; j++) { + prevGap += numOccurrences[i - 1][1]; + return d[1] * theGap / 2 + prevGap * theGap + theTopPad; + } + } else { + return d[1] * theGap / 2 + theTopPad; + } + }).attr("font-size", conf.sectionFontSize).attr("class", function(d) { + for (const [i, category] of categories.entries()) { + if (d[0] === category) { + return "sectionTitle sectionTitle" + i % conf.numberSectionStyles; + } + } + return "sectionTitle"; + }); + } + function drawToday(theSidePad, theTopPad, w2, h2) { + const todayMarker2 = diagObj.db.getTodayMarker(); + if (todayMarker2 === "off") { + return; + } + const todayG = svg.append("g").attr("class", "today"); + const today = /* @__PURE__ */ new Date(); + const todayLine = todayG.append("line"); + todayLine.attr("x1", timeScale(today) + theSidePad).attr("x2", timeScale(today) + theSidePad).attr("y1", conf.titleTopMargin).attr("y2", h2 - conf.titleTopMargin).attr("class", "today"); + if (todayMarker2 !== "") { + todayLine.attr("style", todayMarker2.replace(/,/g, ";")); + } + } + function checkUnique(arr) { + const hash = {}; + const result = []; + for (let i = 0, l = arr.length; i < l; ++i) { + if (!Object.prototype.hasOwnProperty.call(hash, arr[i])) { + hash[arr[i]] = true; + result.push(arr[i]); + } + } + return result; + } +}; +const ganttRenderer = { + setConf, + draw +}; +const getStyles = (options) => ` + .mermaid-main-font { + font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif); + } + + .exclude-range { + fill: ${options.excludeBkgColor}; + } + + .section { + stroke: none; + opacity: 0.2; + } + + .section0 { + fill: ${options.sectionBkgColor}; + } + + .section2 { + fill: ${options.sectionBkgColor2}; + } + + .section1, + .section3 { + fill: ${options.altSectionBkgColor}; + opacity: 0.2; + } + + .sectionTitle0 { + fill: ${options.titleColor}; + } + + .sectionTitle1 { + fill: ${options.titleColor}; + } + + .sectionTitle2 { + fill: ${options.titleColor}; + } + + .sectionTitle3 { + fill: ${options.titleColor}; + } + + .sectionTitle { + text-anchor: start; + font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif); + } + + + /* Grid and axis */ + + .grid .tick { + stroke: ${options.gridColor}; + opacity: 0.8; + shape-rendering: crispEdges; + } + + .grid .tick text { + font-family: ${options.fontFamily}; + fill: ${options.textColor}; + } + + .grid path { + stroke-width: 0; + } + + + /* Today line */ + + .today { + fill: none; + stroke: ${options.todayLineColor}; + stroke-width: 2px; + } + + + /* Task styling */ + + /* Default task */ + + .task { + stroke-width: 2; + } + + .taskText { + text-anchor: middle; + font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif); + } + + .taskTextOutsideRight { + fill: ${options.taskTextDarkColor}; + text-anchor: start; + font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif); + } + + .taskTextOutsideLeft { + fill: ${options.taskTextDarkColor}; + text-anchor: end; + } + + + /* Special case clickable */ + + .task.clickable { + cursor: pointer; + } + + .taskText.clickable { + cursor: pointer; + fill: ${options.taskTextClickableColor} !important; + font-weight: bold; + } + + .taskTextOutsideLeft.clickable { + cursor: pointer; + fill: ${options.taskTextClickableColor} !important; + font-weight: bold; + } + + .taskTextOutsideRight.clickable { + cursor: pointer; + fill: ${options.taskTextClickableColor} !important; + font-weight: bold; + } + + + /* Specific task settings for the sections*/ + + .taskText0, + .taskText1, + .taskText2, + .taskText3 { + fill: ${options.taskTextColor}; + } + + .task0, + .task1, + .task2, + .task3 { + fill: ${options.taskBkgColor}; + stroke: ${options.taskBorderColor}; + } + + .taskTextOutside0, + .taskTextOutside2 + { + fill: ${options.taskTextOutsideColor}; + } + + .taskTextOutside1, + .taskTextOutside3 { + fill: ${options.taskTextOutsideColor}; + } + + + /* Active task */ + + .active0, + .active1, + .active2, + .active3 { + fill: ${options.activeTaskBkgColor}; + stroke: ${options.activeTaskBorderColor}; + } + + .activeText0, + .activeText1, + .activeText2, + .activeText3 { + fill: ${options.taskTextDarkColor} !important; + } + + + /* Completed task */ + + .done0, + .done1, + .done2, + .done3 { + stroke: ${options.doneTaskBorderColor}; + fill: ${options.doneTaskBkgColor}; + stroke-width: 2; + } + + .doneText0, + .doneText1, + .doneText2, + .doneText3 { + fill: ${options.taskTextDarkColor} !important; + } + + + /* Tasks on the critical line */ + + .crit0, + .crit1, + .crit2, + .crit3 { + stroke: ${options.critBorderColor}; + fill: ${options.critBkgColor}; + stroke-width: 2; + } + + .activeCrit0, + .activeCrit1, + .activeCrit2, + .activeCrit3 { + stroke: ${options.critBorderColor}; + fill: ${options.activeTaskBkgColor}; + stroke-width: 2; + } + + .doneCrit0, + .doneCrit1, + .doneCrit2, + .doneCrit3 { + stroke: ${options.critBorderColor}; + fill: ${options.doneTaskBkgColor}; + stroke-width: 2; + cursor: pointer; + shape-rendering: crispEdges; + } + + .milestone { + transform: rotate(45deg) scale(0.8,0.8); + } + + .milestoneText { + font-style: italic; + } + .doneCritText0, + .doneCritText1, + .doneCritText2, + .doneCritText3 { + fill: ${options.taskTextDarkColor} !important; + } + + .activeCritText0, + .activeCritText1, + .activeCritText2, + .activeCritText3 { + fill: ${options.taskTextDarkColor} !important; + } + + .titleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.titleColor || options.textColor}; + font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif); + } +`; +const ganttStyles = getStyles; +const diagram = { + parser: ganttParser, + db: ganttDb, + renderer: ganttRenderer, + styles: ganttStyles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/5565c8ed.630ca6bf.js b/assets/js/5565c8ed.630ca6bf.js new file mode 100644 index 0000000000..4f737d34c0 --- /dev/null +++ b/assets/js/5565c8ed.630ca6bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2016],{51152:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>u,contentTitle:()=>d,default:()=>r,frontMatter:()=>t,metadata:()=>a,toc:()=>c});var s=n(74848),i=n(28453);const t={sidebar_label:"Cloud in a Box"},d="Cloud in a Box",a={id:"iaas/guides/deploy-guide/examples/cloud-in-a-box",title:"Cloud in a Box",description:"This section has moved. You can now find the content in the",source:"@site/docs/02-iaas/guides/deploy-guide/examples/cloud-in-a-box.md",sourceDirName:"02-iaas/guides/deploy-guide/examples",slug:"/iaas/guides/deploy-guide/examples/cloud-in-a-box",permalink:"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/examples/cloud-in-a-box.md",tags:[],version:"current",frontMatter:{sidebar_label:"Cloud in a Box"},sidebar:"docs",previous:{title:"Examples",permalink:"/docs/iaas/guides/deploy-guide/examples/"},next:{title:"Testbed",permalink:"/docs/iaas/guides/deploy-guide/examples/testbed"}},u={},c=[];function l(e){const o={a:"a",h1:"h1",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o.h1,{id:"cloud-in-a-box",children:"Cloud in a Box"}),"\n",(0,s.jsxs)(o.p,{children:["This section has moved. You can now find the content in the\n",(0,s.jsx)(o.a,{href:"../../other-guides",children:"Other Guides"})," as\n",(0,s.jsx)(o.a,{href:"../../other-guides/cloud-in-a-box",children:"Cloud in a Box Guide"}),"."]})]})}function r(e={}){const{wrapper:o}={...(0,i.R)(),...e.components};return o?(0,s.jsx)(o,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,o,n)=>{n.d(o,{R:()=>d,x:()=>a});var s=n(96540);const i={},t=s.createContext(i);function d(e){const o=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function a(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),s.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/55e21dcd.beb09bec.js b/assets/js/55e21dcd.beb09bec.js new file mode 100644 index 0000000000..6d8d88520c --- /dev/null +++ b/assets/js/55e21dcd.beb09bec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1810],{60941:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>g,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var o=t(74848),s=t(28453);const a={},i="Traces",r={id:"operating-scs/components/monitoring/docs/tracing",title:"Traces",description:"This page contains a guide on how to enable traces in Thanos. Traces are not enabled by default.",source:"@site/docs/04-operating-scs/components/monitoring/docs/tracing.md",sourceDirName:"04-operating-scs/components/monitoring/docs",slug:"/operating-scs/components/monitoring/docs/tracing",permalink:"/docs/operating-scs/components/monitoring/docs/tracing",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/tracing.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"OAUTH",permalink:"/docs/operating-scs/components/monitoring/docs/oauth"},next:{title:"Tuning",permalink:"/docs/operating-scs/components/monitoring/docs/tuning"}},c={},l=[{value:"Example",id:"example",level:2},{value:"Usage",id:"usage",level:2}];function d(e){const n={code:"code",h1:"h1",h2:"h2",img:"img",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"traces",children:"Traces"}),"\n",(0,o.jsx)(n.p,{children:"This page contains a guide on how to enable traces in Thanos. Traces are not enabled by default."}),"\n",(0,o.jsxs)(n.p,{children:["Thanos supports different tracing backends that implements ",(0,o.jsx)(n.code,{children:"opentracing.Tracer"})," interface.\nAll clients could be configured by ",(0,o.jsx)(n.code,{children:"--tracing.config-file"})," parameter to reference to the configuration file or by ",(0,o.jsx)(n.code,{children:"--tracing.config"}),"\nparameter to put yaml config directly. Recommended way is to pass configuration directly as it gives an explicit static view of\nconfiguration for each component, and it also saves you the fuss of creating and managing additional files."]}),"\n",(0,o.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,o.jsx)(n.p,{children:"Here is the example of the configuration how to enable jaeger in Thanos. This configuration can be applied for multiple components e.g. query-frontend, query or thanos-sidecar."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'thanos:\n queryFrontend:\n extraFlags:\n - |-\n --tracing.config="config":\n "sampler_param": 2\n "sampler_type": "ratelimiting"\n "service_name": "thanos-query-frontend"\n "agent_host": "jaeger-agent.<namespace>.svc"\n "agent_port": 5775\n "type": "JAEGER"\n'})}),"\n",(0,o.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,o.jsxs)(n.p,{children:["Once tracing is enabled, Thanos will generate traces for all gRPC and HTTP APIs thanks to generic \u201cmiddlewares\u201d.\nSome more interesting to observe APIs like query or query_range have more low-level spans with focused metadata showing\nlatency for important functionalities. For example, Jaeger view of query_range HTTP API call might look as follows:\n",(0,o.jsx)(n.img,{alt:"Jaeger-example",src:t(62122).A+"",width:"1843",height:"903"})]})]})}function g(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},62122:(e,n,t)=>{t.d(n,{A:()=>o});const o=t.p+"assets/images/jaeger-91a4b48820447709f604d72c396cacf8.png"},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var o=t(96540);const s={},a=o.createContext(s);function i(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5642.33e06e4a.js b/assets/js/5642.33e06e4a.js new file mode 100644 index 0000000000..a1dae5615f --- /dev/null +++ b/assets/js/5642.33e06e4a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5642],{45642:(t,e,n)=>{n.d(e,{diagram:()=>O});var i=n(76257),s=n(26312),r=n(3219),a=n(78041),o=n(75263),l=(n(74353),n(16750),n(42838),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[6,8,10,11,12,14,16,17,20,21],n=[1,9],i=[1,10],s=[1,11],r=[1,12],a=[1,13],o=[1,16],l=[1,17],c={trace:function(){},yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,period_statement:18,event_statement:19,period:20,event:21,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",20:"period",21:"event"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[18,1],[19,1]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.getCommonDb().setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 9:this.$=r[o].trim(),i.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=r[o].trim(),i.getCommonDb().setAccDescription(this.$);break;case 12:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 15:i.addTask(r[o],0,""),this.$=r[o];break;case 16:i.addEvent(r[o].substr(2)),this.$=r[o]}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:n,12:i,14:s,16:r,17:a,18:14,19:15,20:o,21:l},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:18,11:n,12:i,14:s,16:r,17:a,18:14,19:15,20:o,21:l},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,19]},{15:[1,20]},t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),t(e,[2,4]),t(e,[2,9]),t(e,[2,10])],defaultActions:{},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,o="",l=0,c=0,h=r.slice.call(arguments,1),d=Object.create(this.lexer),u={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(u.yy[p]=this.yy[p]);d.setInput(t,u.yy),u.yy.lexer=d,u.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var y=d.yylloc;r.push(y);var g=d.options&&d.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,m,_,b,x,k,v,w,S,$={};;){if(m=n[n.length-1],this.defaultActions[m]?_=this.defaultActions[m]:(null==f&&(S=void 0,"number"!=typeof(S=i.pop()||d.lex()||1)&&(S instanceof Array&&(S=(i=S).pop()),S=e.symbols_[S]||S),f=S),_=a[m]&&a[m][f]),void 0===_||!_.length||!_[0]){var E="";for(x in w=[],a[m])this.terminals_[x]&&x>2&&w.push("'"+this.terminals_[x]+"'");E=d.showPosition?"Parse error on line "+(l+1)+":\n"+d.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(E,{text:d.match,token:this.terminals_[f]||f,line:d.yylineno,loc:y,expected:w})}if(_[0]instanceof Array&&_.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+f);switch(_[0]){case 1:n.push(f),s.push(d.yytext),r.push(d.yylloc),n.push(_[1]),f=null,c=d.yyleng,o=d.yytext,l=d.yylineno,y=d.yylloc;break;case 2:if(k=this.productions_[_[1]][1],$.$=s[s.length-k],$._$={first_line:r[r.length-(k||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(k||1)].first_column,last_column:r[r.length-1].last_column},g&&($._$.range=[r[r.length-(k||1)].range[0],r[r.length-1].range[1]]),void 0!==(b=this.performAction.apply($,[o,c,l,u.yy,_[1],s,r].concat(h))))return b;k&&(n=n.slice(0,-1*k*2),s=s.slice(0,-1*k),r=r.slice(0,-1*k)),n.push(this.productions_[_[1]][0]),s.push($.$),r.push($._$),v=a[n[n.length-2]][n[n.length-1]],n.push(v);break;case 3:return!0}}return!0}},h={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:case 1:case 3:case 4:break;case 2:return 10;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),14;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 21;case 16:return 20;case 17:return 6;case 18:return"INVALID"}},rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:timeline\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?::\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18],inclusive:!0}}};function d(){this.yy={}}return c.lexer=h,d.prototype=c,c.Parser=d,new d}());l.parser=l;const c=l;let h="",d=0;const u=[],p=[],y=[],g=()=>i.L,f=function(){u.length=0,p.length=0,h="",y.length=0,(0,i.v)()},m=function(t){h=t,u.push(t)},_=function(){return u},b=function(){let t=w();let e=0;for(;!t&&e<100;)t=w(),e++;return p.push(...y),p},x=function(t,e,n){const i={id:d++,section:h,type:h,task:t,score:e||0,events:n?[n]:[]};y.push(i)},k=function(t){y.find((t=>t.id===d-1)).events.push(t)},v=function(t){const e={section:h,type:h,description:t,task:t,classes:[]};p.push(e)},w=function(){let t=!0;for(const[e,n]of y.entries())y[e].processed,t=t&&n.processed;return t},S={clear:f,getCommonDb:g,addSection:m,getSections:_,getTasks:b,addTask:x,addTaskOrg:v,addEvent:k},$=Object.freeze(Object.defineProperty({__proto__:null,addEvent:k,addSection:m,addTask:x,addTaskOrg:v,clear:f,default:S,getCommonDb:g,getSections:_,getTasks:b},Symbol.toStringTag,{value:"Module"}));!function(){function t(t,e,n,s,r,a,o,l){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",l).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,l,c){const{taskFontSize:h,taskFontFamily:d}=l,u=t.split(/<br\s*\/?>/gi);for(let p=0;p<u.length;p++){const t=p*h-h*(u.length-1)/2,l=e.append("text").attr("x",n+r/2).attr("y",s).attr("fill",c).style("text-anchor","middle").style("font-size",h).style("font-family",d);l.append("tspan").attr("x",n+r/2).attr("dy",t).text(u[p]),l.attr("y",s+a/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(l,o)}}function n(t,n,s,r,a,o,l,c){const h=n.append("switch"),d=h.append("foreignObject").attr("x",s).attr("y",r).attr("width",a).attr("height",o).attr("position","fixed").append("xhtml:div").style("display","table").style("height","100%").style("width","100%");d.append("div").attr("class","label").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,s,r,a,o,l,c),i(d,l)}function i(t,e){for(const n in e)n in e&&t.attr(n,e[n])}}();function E(t,e){t.each((function(){var t,n=(0,s.Ltv)(this),i=n.text().split(/(\s+|<br>)/).reverse(),r=[],a=n.attr("y"),o=parseFloat(n.attr("dy")),l=n.text(null).append("tspan").attr("x",0).attr("y",a).attr("dy",o+"em");for(let s=0;s<i.length;s++)t=i[i.length-1-s],r.push(t),l.text(r.join(" ").trim()),(l.node().getComputedTextLength()>e||"<br>"===t)&&(r.pop(),l.text(r.join(" ").trim()),r="<br>"===t?[""]:[t],l=n.append("tspan").attr("x",0).attr("y",a).attr("dy","1.1em").text(t))}))}const I=function(t,e,n){t.append("path").attr("id","node-"+e.id).attr("class","node-bkg node-"+e.type).attr("d",`M0 ${e.height-5} v${10-e.height} q0,-5 5,-5 h${e.width-10} q5,0 5,5 v${e.height-5} H0 Z`),t.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",e.height).attr("x2",e.width).attr("y2",e.height)},L=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},T=function(t,e,n,i){const s=n%12-1,r=t.append("g");e.section=s,r.attr("class",(e.class?e.class+" ":"")+"timeline-node section-"+s);const a=r.append("g"),o=r.append("g"),l=o.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(E,e.width).node().getBBox(),c=i.fontSize&&i.fontSize.replace?i.fontSize.replace("px",""):i.fontSize;return e.height=l.height+1.1*c*.5+e.padding,e.height=Math.max(e.height,e.maxHeight),e.width=e.width+2*e.padding,o.attr("transform","translate("+e.width/2+", "+e.padding/2+")"),I(a,e,s),e},A=function(t,e,n){const i=t.append("g"),s=i.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(E,e.width).node().getBBox(),r=n.fontSize&&n.fontSize.replace?n.fontSize.replace("px",""):n.fontSize;return i.remove(),s.height+1.1*r*.5+e.padding},C=function(t,e,n,s,r,a,o,l,c,h,d){var u;for(const p of e){const e={descr:p.task,section:n,number:n,width:150,padding:20,maxHeight:a};i.l.debug("taskNode",e);const l=t.append("g").attr("class","taskWrapper"),y=T(l,e,n,o).height;if(i.l.debug("taskHeight after draw",y),l.attr("transform",`translate(${s}, ${r})`),a=Math.max(a,y),p.events){const e=t.append("g").attr("class","lineWrapper");let i=a;r+=100,i+=M(t,p.events,n,s,r,o),r-=100,e.append("line").attr("x1",s+95).attr("y1",r+a).attr("x2",s+95).attr("y2",r+a+(d?a:h)+c+120).attr("stroke-width",2).attr("stroke","black").attr("marker-end","url(#arrowhead)").attr("stroke-dasharray","5,5")}s+=200,d&&!(null==(u=o.timeline)?void 0:u.disableMulticolor)&&n++}r-=10},M=function(t,e,n,s,r,a){let o=0;const l=r;r+=100;for(const c of e){const e={descr:c,section:n,number:n,width:150,padding:20,maxHeight:50};i.l.debug("eventNode",e);const l=t.append("g").attr("class","eventWrapper"),h=T(l,e,n,a).height;o+=h,l.attr("transform",`translate(${s}, ${r})`),r=r+10+h}return r=l,o},O={db:$,renderer:{setConf:()=>{},draw:function(t,e,n,r){var a,o;const l=(0,i.c)(),c=l.leftMargin??50;i.l.debug("timeline",r.db);const h=l.securityLevel;let d;"sandbox"===h&&(d=(0,s.Ltv)("#i"+e));const u=("sandbox"===h?(0,s.Ltv)(d.nodes()[0].contentDocument.body):(0,s.Ltv)("body")).select("#"+e);u.append("g");const p=r.db.getTasks(),y=r.db.getCommonDb().getDiagramTitle();i.l.debug("task",p),L(u);const g=r.db.getSections();i.l.debug("sections",g);let f=0,m=0,_=0,b=0,x=50+c,k=50;b=50;let v=0,w=!0;g.forEach((function(t){const e=A(u,{number:v,descr:t,section:v,width:150,padding:20,maxHeight:f},l);i.l.debug("sectionHeight before draw",e),f=Math.max(f,e+20)}));let S=0,$=0;i.l.debug("tasks.length",p.length);for(const[s,I]of p.entries()){const t={number:s,descr:I,section:I.section,width:150,padding:20,maxHeight:m},e=A(u,t,l);i.l.debug("taskHeight before draw",e),m=Math.max(m,e+20),S=Math.max(S,I.events.length);let n=0;for(let i=0;i<I.events.length;i++){const t={descr:I.events[i],section:I.section,number:I.section,width:150,padding:20,maxHeight:50};n+=A(u,t,l)}$=Math.max($,n)}i.l.debug("maxSectionHeight before draw",f),i.l.debug("maxTaskHeight before draw",m),g&&g.length>0?g.forEach((t=>{const e=p.filter((e=>e.section===t)),n={number:v,descr:t,section:v,width:200*Math.max(e.length,1)-50,padding:20,maxHeight:f};i.l.debug("sectionNode",n);const s=u.append("g"),r=T(s,n,v,l);i.l.debug("sectionNode output",r),s.attr("transform",`translate(${x}, 50)`),k+=f+50,e.length>0&&C(u,e,v,x,k,m,l,S,$,f,!1),x+=200*Math.max(e.length,1),k=50,v++})):(w=!1,C(u,p,v,x,k,m,l,S,$,f,!0));const E=u.node().getBBox();i.l.debug("bounds",E),y&&u.append("text").text(y).attr("x",E.width/2-c).attr("font-size","4ex").attr("font-weight","bold").attr("y",20),_=w?f+m+150:m+100;u.append("g").attr("class","lineWrapper").append("line").attr("x1",c).attr("y1",_).attr("x2",E.width+3*c).attr("y2",_).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)"),(0,i.o)(void 0,u,(null==(a=l.timeline)?void 0:a.padding)??50,(null==(o=l.timeline)?void 0:o.useMaxWidth)??!1)}},parser:c,styles:t=>`\n .edge {\n stroke-width: 3;\n }\n ${(t=>{let e="";for(let n=0;n<t.THEME_COLOR_LIMIT;n++)t["lineColor"+n]=t["lineColor"+n]||t["cScaleInv"+n],(0,r.A)(t["lineColor"+n])?t["lineColor"+n]=(0,a.A)(t["lineColor"+n],20):t["lineColor"+n]=(0,o.A)(t["lineColor"+n],20);for(let n=0;n<t.THEME_COLOR_LIMIT;n++){const i=""+(17-3*n);e+=`\n .section-${n-1} rect, .section-${n-1} path, .section-${n-1} circle, .section-${n-1} path {\n fill: ${t["cScale"+n]};\n }\n .section-${n-1} text {\n fill: ${t["cScaleLabel"+n]};\n }\n .node-icon-${n-1} {\n font-size: 40px;\n color: ${t["cScaleLabel"+n]};\n }\n .section-edge-${n-1}{\n stroke: ${t["cScale"+n]};\n }\n .edge-depth-${n-1}{\n stroke-width: ${i};\n }\n .section-${n-1} line {\n stroke: ${t["cScaleInv"+n]} ;\n stroke-width: 3;\n }\n\n .lineWrapper line{\n stroke: ${t["cScaleLabel"+n]} ;\n }\n\n .disabled, .disabled circle, .disabled text {\n fill: lightgray;\n }\n .disabled text {\n fill: #efefef;\n }\n `}return e})(t)}\n .section-root rect, .section-root path, .section-root circle {\n fill: ${t.git0};\n }\n .section-root text {\n fill: ${t.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .eventWrapper {\n filter: brightness(120%);\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/564eabfd.0c7dcb95.js b/assets/js/564eabfd.0c7dcb95.js new file mode 100644 index 0000000000..bd0901e885 --- /dev/null +++ b/assets/js/564eabfd.0c7dcb95.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8752],{94181:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>d});var s=r(74848),a=r(28453);const t={},o="Harbor",i={id:"container/components/k8s-cluster-api-provider/doc/usage/harbor",title:"Harbor",description:"Project k8s-harbor is used for the SCS Harbor",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/harbor.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc/usage",slug:"/container/components/k8s-cluster-api-provider/doc/usage/harbor",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/usage/harbor.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Gateway-API",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api"},next:{title:"Migration to ClusterClass",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class"}},c={},d=[{value:"Default deployment",id:"default-deployment",level:2},{value:"Configuration options",id:"configuration-options",level:2},{value:"Persistence",id:"persistence",level:3},{value:"Ingress and TLS",id:"ingress-and-tls",level:3}];function l(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"harbor",children:"Harbor"}),"\n",(0,s.jsxs)(n.p,{children:["Project ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-harbor",children:"k8s-harbor"})," is used for the SCS Harbor\ncontainer registry deployment ",(0,s.jsx)(n.a,{href:"https://registry.scs.community/",children:"https://registry.scs.community/"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["With this project, it is possible to deploy Harbor in a similar way into the workload cluster.\nIf you want to deploy Harbor, set opentofu variable ",(0,s.jsx)(n.code,{children:"deploy_harbor = true"}),". It will deploy\nHarbor with ",(0,s.jsx)(n.a,{href:"#default-deployment",children:"default options"}),". The recommended approach is to\nset up also ",(0,s.jsx)(n.a,{href:"#persistence",children:"persistence"})," and ",(0,s.jsx)(n.a,{href:"#ingress-and-tls",children:"ingress with tls"}),"."]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["It automatically deploys flux as k8s-harbor requirement.\nIt also expects that the Swift object store is available in the targeting OpenStack project. S3 credentials\n(",(0,s.jsx)(n.code,{children:"openstack ec2 credentials create"}),") are created and saved into ",(0,s.jsx)(n.em,{children:"~/$CLUSTER_NAME/deployed-manifests.d/harbor/.ec2"}),".\nBucket (",(0,s.jsx)(n.code,{children:'openstack container create "$PREFIX-$CLUSTER_NAME-harbor-registry"'}),") for storing container images\nis also automatically created in the openstack Swift object store."]}),"\n"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Warning: Swift container and ec2 credentials are not removed when the workload cluster is deleted."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"default-deployment",children:"Default deployment"}),"\n",(0,s.jsx)(n.p,{children:"By default, Harbor will be deployed with these options:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-terraform",children:'harbor_config = {\n domain_name: "",\n issuer_email: "",\n persistence: false,\n database_size: "1Gi",\n redis_size: "1Gi",\n trivy_size: "5Gi"\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"These options are templated to the mgmt server and used as environment variables\nduring the creation of the workload cluster:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ cat ~/cluster-defaults/harbor-settings\nDEPLOY_HARBOR=true\nHARBOR_DATABASE_SIZE=1Gi\nHARBOR_DOMAIN_NAME=\nHARBOR_ISSUER_EMAIL=\nHARBOR_PERSISTENCE=false\nHARBOR_REDIS_SIZE=1Gi\nHARBOR_TRIVY_SIZE=5G\n"})}),"\n",(0,s.jsx)(n.p,{children:"When the Harbor is deployed, you can check the status, e.g. by:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ flux get helmrelease -n default\nNAME REVISION SUSPENDED READY MESSAGE \nharbor 1.12.4 False True Release reconciliation succeeded\n"})}),"\n",(0,s.jsxs)(n.p,{children:["or you can simply check if pods are running by ",(0,s.jsx)(n.code,{children:"kubectl get pods"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Harbor components are deployed as deployments and statefulsets:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ kubectl get deploy,sts\nNAME READY UP-TO-DATE AVAILABLE AGE\ndeployment.apps/harbor-core 2/2 2 2 11m\ndeployment.apps/harbor-exporter 1/1 1 1 11m\ndeployment.apps/harbor-jobservice 2/2 2 2 11m\ndeployment.apps/harbor-nginx 1/1 1 1 11m\ndeployment.apps/harbor-portal 2/2 2 2 11m\ndeployment.apps/harbor-registry 2/2 2 2 11m\n\nNAME READY AGE\nstatefulset.apps/harbor-database 1/1 11m\nstatefulset.apps/harbor-redis 1/1 11m\nstatefulset.apps/harbor-trivy 2/2 11m\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Default options deploy Harbor as clusterIP service without pvc persistence for database, redis and trivy.\nSee ",(0,s.jsx)(n.code,{children:"terraform/files/kubernetes-manifests.d/harbor/envs/clusterIP/"})," for further details.\nYou can access it via the k8s service ",(0,s.jsx)(n.code,{children:"harbor"}),", for example, ",(0,s.jsx)(n.em,{children:"port-forward"})," it and access it at ",(0,s.jsx)(n.a,{href:"http://localhost:8080",children:"http://localhost:8080"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ kubectl get svc harbor -o wide\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR\nharbor ClusterIP 10.109.57.148 <none> 80/TCP 11m app=harbor,component=nginx,release=harbor\n$ kubectl port-forward svc/harbor 8080:80\nForwarding from 127.0.0.1:8080 -> 8080\nForwarding from [::1]:8080 -> 8080\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Admin username is ",(0,s.jsx)(n.code,{children:"admin"})," and password can be obtained from the secret by:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl get secret harbor-secrets -o jsonpath='{.data.values\\.yaml}' | base64 -d | yq .harborAdminPassword\n"})}),"\n",(0,s.jsx)(n.h2,{id:"configuration-options",children:"Configuration options"}),"\n",(0,s.jsx)(n.h3,{id:"persistence",children:"Persistence"}),"\n",(0,s.jsxs)(n.p,{children:["By default, ",(0,s.jsx)(n.code,{children:"persistence"})," is set to ",(0,s.jsx)(n.code,{children:"false"}),".\nWhen persistence is set to ",(0,s.jsx)(n.code,{children:"true"}),", i.e. ",(0,s.jsx)(n.code,{children:"harbor_config = {persistence: true}"}),",\nHarbor components (database, redis, trivy) are deployed with PVCs:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ kubectl get pvc\nNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE\ndata-harbor-redis-0 Bound pvc-982221c1-64cb-4d3e-a77d-1db5b4429a69 1Gi RWO cinder-default 6m12s\ndata-harbor-trivy-0 Bound pvc-8a2ad60c-c7bf-40e1-8593-0d00b3d40b4f 5Gi RWO cinder-default 6m12s\ndata-harbor-trivy-1 Bound pvc-734f9b6a-9cee-40e4-9e1c-b959d9f7b7cf 5Gi RWO cinder-default 5m11s\ndatabase-data-harbor-database-0 Bound pvc-c5c3a7e6-a99a-4f16-a5cc-792e9b3665d8 1Gi RWO cinder-default 6m12s\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The size of PVCs can be configured by ",(0,s.jsx)(n.code,{children:'harbor_config = {<component>_size: "size"}'}),".\nTrivy has 2 replicas, i.e. 2 PVCs will be created."]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["When persistence is set to ",(0,s.jsx)(n.code,{children:"true"}),", ",(0,s.jsx)(n.em,{children:"Cinder CSI"})," is automatically deployed."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"ingress-and-tls",children:"Ingress and TLS"}),"\n",(0,s.jsxs)(n.p,{children:["If you want to deploy ingress in front of Harbor and secure it with SSL/TLS certificate, set the ",(0,s.jsx)(n.code,{children:"domain_name"})," option.\nRelevant files which will be deployed are located in ",(0,s.jsx)(n.code,{children:"terraform/files/kubernetes-manifests.d/harbor/envs/ingress/"}),"."]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["When ",(0,s.jsx)(n.code,{children:"domain_name"})," is set, ",(0,s.jsx)(n.code,{children:"cert-manager"})," and ",(0,s.jsx)(n.code,{children:"ingress-nginx"})," are automatically deployed."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["So, instead of default ",(0,s.jsx)(n.em,{children:"harbor"})," clusterIP service and ",(0,s.jsx)(n.em,{children:"harbor-nginx"})," deployment, ",(0,s.jsx)(n.code,{children:"harbor-ingress"})," will be deployed:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ kubectl get ing harbor-ingress\nNAME CLASS HOSTS ADDRESS PORTS AGE\nharbor-ingress nginx harbor.example.com 213.131.230.203.nip.io 80, 443 13m\n"})}),"\n",(0,s.jsxs)(n.p,{children:["There will be also an additional cert-manager ",(0,s.jsx)(n.em,{children:"issuer"})," ",(0,s.jsx)(n.code,{children:"letsencrypt"})," deployed:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ kubectl get issuers -o wide\nNAME READY STATUS AGE\nletsencrypt True The ACME account was registered with the ACME server 13m\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This ACME issuer has an optional email field, which can be set by ",(0,s.jsx)(n.code,{children:"issuer_email"})," option.\nThis is recommended option because it will be used to contact you in case of issues with your account or certificates,\nincluding expiry notification emails."]}),"\n",(0,s.jsx)(n.p,{children:"Then, the settings can look like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-terraform",children:'harbor_config = {\n domain_name: "harbor.example.com",\n issuer_email: "email@example.com",\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["After the deployment, there is one mandatory step to set up proper TLS communication with this Harbor instance.\n",(0,s.jsx)(n.code,{children:"harbor-ingress"})," has special annotation ",(0,s.jsx)(n.code,{children:"cert-manager.io/issuer: letsencrypt"})," which instructs cert-manager\nto create a certificate object:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ kubectl get cert -o wide\nNAME READY SECRET ISSUER STATUS AGE\nharbor-crt False harbor-crt letsencrypt Issuing certificate as Secret does not exist 13m\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The certificate is not ready, because it uses Let\u2019s Encrypt standard ACME HTTP-01 challenge.\nIn this challenge, you need to take the IP address of the ingress load balancer and create a DNS record\nfor your ",(0,s.jsx)(n.code,{children:"domain_name"}),". You can get an IP address (don't look on ",(0,s.jsx)(n.em,{children:"nip.io"})," suffix) e.g. by this command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'$ kubectl -n ingress-nginx get svc ingress-nginx-controller -o jsonpath=\'{.status.loadBalancer.ingress}\'\n[{"hostname":"213.131.230.203.nip.io"}]\n'})}),"\n",(0,s.jsxs)(n.p,{children:["And after a while, your cert is ready, and you can access harbor at ",(0,s.jsx)(n.a,{href:"https://harbor.example.com/",children:"https://harbor.example.com/"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ kubectl get cert -o wide\nNAME READY SECRET ISSUER STATUS AGE\nharbor-crt True harbor-crt letsencrypt Certificate is up to date and has not expired 18m\n"})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>i});var s=r(96540);const a={},t=s.createContext(a);function o(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5688.e3378d6d.js b/assets/js/5688.e3378d6d.js new file mode 100644 index 0000000000..502122fe7c --- /dev/null +++ b/assets/js/5688.e3378d6d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5688],{45688:(e,t,s)=>{s.d(t,{diagram:()=>V});var o=s(26292),i=s(697),a=s(26312),r=s(76257),n=s(92746);s(74353),s(16750),s(42838),s(21176),s(14075);const d="rect",c="rectWithTitle",l="statediagram",p=`${l}-state`,b="transition",g=`${b} note-edge`,h=`${l}-note`,u=`${l}-cluster`,y=`${l}-cluster-alt`,f="parent",w="note",x="----",$=`${x}${w}`,m=`${x}${f}`,T="fill:none",S="fill: #333",k="text",v="normal";let D={},A=0;function B(e="",t=0,s="",o=x){return`state-${e}${null!==s&&s.length>0?`${o}${s}`:""}-${t}`}const L=(e,t,s,i,a,n)=>{const l=s.id,b=null==(x=i[l])?"":x.classes?x.classes.join(" "):"";var x;if("root"!==l){let t=d;!0===s.start&&(t="start"),!1===s.start&&(t="end"),s.type!==o.D&&(t=s.type),D[l]||(D[l]={id:l,shape:t,description:r.e.sanitizeText(l,(0,r.c)()),classes:`${b} ${p}`});const i=D[l];s.description&&(Array.isArray(i.description)?(i.shape=c,i.description.push(s.description)):i.description.length>0?(i.shape=c,i.description===l?i.description=[s.description]:i.description=[i.description,s.description]):(i.shape=d,i.description=s.description),i.description=r.e.sanitizeTextOrArray(i.description,(0,r.c)())),1===i.description.length&&i.shape===c&&(i.shape=d),!i.type&&s.doc&&(r.l.info("Setting cluster for ",l,E(s)),i.type="group",i.dir=E(s),i.shape=s.type===o.a?"divider":"roundedWithTitle",i.classes=i.classes+" "+u+" "+(n?y:""));const a={labelStyle:"",shape:i.shape,labelText:i.description,classes:i.classes,style:"",id:l,dir:i.dir,domId:B(l,A),type:i.type,padding:15,centerLabel:!0};if(s.note){const t={labelStyle:"",shape:"note",labelText:s.note.text,classes:h,style:"",id:l+$+"-"+A,domId:B(l,A,w),type:i.type,padding:15},o={labelStyle:"",shape:"noteGroup",labelText:s.note.text,classes:i.classes,style:"",id:l+m,domId:B(l,A,f),type:"group",padding:0};A++;const r=l+m;e.setNode(r,o),e.setNode(t.id,t),e.setNode(l,a),e.setParent(l,r),e.setParent(t.id,r);let n=l,d=t.id;"left of"===s.note.position&&(n=t.id,d=l),e.setEdge(n,d,{arrowhead:"none",arrowType:"",style:T,labelStyle:"",classes:g,arrowheadStyle:S,labelpos:"c",labelType:k,thickness:v})}else e.setNode(l,a)}t&&"root"!==t.id&&(r.l.trace("Setting node ",l," to be child of its parent ",t.id),e.setParent(l,t.id)),s.doc&&(r.l.trace("Adding nodes children "),C(e,s,s.doc,i,a,!n))},C=(e,t,s,i,a,n)=>{r.l.trace("items",s),s.forEach((s=>{switch(s.stmt){case o.b:case o.D:L(e,t,s,i,a,n);break;case o.S:{L(e,t,s.state1,i,a,n),L(e,t,s.state2,i,a,n);const o={id:"edge"+A,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:T,labelStyle:"",label:r.e.sanitizeText(s.description,(0,r.c)()),arrowheadStyle:S,labelpos:"c",labelType:k,thickness:v,classes:b};e.setEdge(s.state1.id,s.state2.id,o,A),A++}}}))},E=(e,t=o.c)=>{let s=t;if(e.doc)for(let o=0;o<e.doc.length;o++){const t=e.doc[o];"dir"===t.stmt&&(s=t.value)}return s},R={setConf:function(e){const t=Object.keys(e);for(const s of t)e[s]},getClasses:function(e,t){return t.db.extract(t.db.getRootDocV2()),t.db.getClasses()},draw:async function(e,t,s,o){r.l.info("Drawing state diagram (v2)",t),D={},o.db.getDirection();const{securityLevel:c,state:p}=(0,r.c)(),b=p.nodeSpacing||50,g=p.rankSpacing||50;r.l.info(o.db.getRootDocV2()),o.db.extract(o.db.getRootDocV2()),r.l.info(o.db.getRootDocV2());const h=o.db.getStates(),u=new i.T({multigraph:!0,compound:!0}).setGraph({rankdir:E(o.db.getRootDocV2()),nodesep:b,ranksep:g,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));let y;L(u,void 0,o.db.getRootDocV2(),h,o.db,!0),"sandbox"===c&&(y=(0,a.Ltv)("#i"+t));const f="sandbox"===c?(0,a.Ltv)(y.nodes()[0].contentDocument.body):(0,a.Ltv)("body"),w=f.select(`[id="${t}"]`),x=f.select("#"+t+" g");await(0,n.r)(x,u,["barb"],l,t);r.u.insertTitle(w,"statediagramTitleText",p.titleTopMargin,o.db.getDiagramTitle());const $=w.node().getBBox(),m=$.width+16,T=$.height+16;w.attr("class",l);const S=w.node().getBBox();(0,r.i)(w,T,m,p.useMaxWidth);const k=`${S.x-8} ${S.y-8} ${m} ${T}`;r.l.debug(`viewBox ${k}`),w.attr("viewBox",k);const v=document.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const i of v){const e=i.getBBox(),t=document.createElementNS("http://www.w3.org/2000/svg",d);t.setAttribute("rx",0),t.setAttribute("ry",0),t.setAttribute("width",e.width),t.setAttribute("height",e.height),i.insertBefore(t,i.firstChild)}}},V={parser:o.p,db:o.d,renderer:R,styles:o.s,init:e=>{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute,o.d.clear()}}}}]); \ No newline at end of file diff --git a/assets/js/5741.7580ffe7.js b/assets/js/5741.7580ffe7.js new file mode 100644 index 0000000000..8ea713391e --- /dev/null +++ b/assets/js/5741.7580ffe7.js @@ -0,0 +1 @@ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5741],{45741:()=>{}}]); \ No newline at end of file diff --git a/assets/js/57b63ae3.4f733c75.js b/assets/js/57b63ae3.4f733c75.js new file mode 100644 index 0000000000..e808ec72aa --- /dev/null +++ b/assets/js/57b63ae3.4f733c75.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9539],{53467:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>m,frontMatter:()=>o,metadata:()=>c,toc:()=>u});var t=r(74848),a=r(28453),s=r(11470),i=r(19365);const o={sidebar_label:"Manager",sidebar_position:15},l="Manager",c={id:"iaas/guides/configuration-guide/manager",title:"Manager",description:"Stable release",source:"@site/docs/02-iaas/guides/configuration-guide/manager.mdx",sourceDirName:"02-iaas/guides/configuration-guide",slug:"/iaas/guides/configuration-guide/manager",permalink:"/docs/iaas/guides/configuration-guide/manager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/manager.mdx",tags:[],version:"current",sidebarPosition:15,frontMatter:{sidebar_label:"Manager",sidebar_position:15},sidebar:"docs",previous:{title:"Inventory",permalink:"/docs/iaas/guides/configuration-guide/inventory"},next:{title:"Network",permalink:"/docs/iaas/guides/configuration-guide/network"}},d={},u=[{value:"Stable release",id:"stable-release",level:2},{value:"OpenSearch integration",id:"opensearch-integration",level:2},{value:"OpenStack broker integration",id:"openstack-broker-integration",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"manager",children:"Manager"}),"\n",(0,t.jsx)(n.h2,{id:"stable-release",children:"Stable release"}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsxs)(n.p,{children:["Always read the ",(0,t.jsx)(n.a,{href:"https://osism.tech/docs/release-notes/",children:"release notes"})," first to learn what has changed and what\nadjustments are necessary. Read the release notes even if you are only updating from e.g. 7.0.2 to 7.0.5."]})}),"\n",(0,t.jsx)(n.p,{children:"In the example, OSISM release 7.0.5 is used."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Set the new manager version in the configuration repository."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'MANAGER_VERSION=7.0.5\nsed -i -e "s/manager_version: .*/manager_version: ${MANAGER_VERSION}/g" environments/manager/configuration.yml\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["If ",(0,t.jsx)(n.code,{children:"openstack_version"})," or ",(0,t.jsx)(n.code,{children:"ceph_version"})," are set in ",(0,t.jsx)(n.code,{children:"environments/manager/configuration.yml"}),"\n(or anywhere else), they must be removed. If these are set, the stable release is not used for\nthese components."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Sync the image versions in the configuration repository."}),"\n",(0,t.jsxs)(s.A,{children:[(0,t.jsx)(i.A,{value:"osism-7",label:"OSISM >= 7.0.0",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"make sync\n"})})}),(0,t.jsxs)(i.A,{value:"osism-6",label:"OSISM < 7.0.0",children:[(0,t.jsxs)(n.p,{children:["If Gilt is not installed via the ",(0,t.jsx)(n.code,{children:"requirements.txt"})," of the manager environment it is\nimportant to use a version smaller v2. The v2 of Gilt is not yet usable."]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"gilt overlay # you have to do this 2x, this is not a copy & paste error\ngilt overlay\n"})}),(0,t.jsxs)(n.p,{children:["Optionally, this is normally not necessary, it is possible to reference a specific tag of the\n",(0,t.jsx)(n.a,{href:"https://github.com/osism/cfg-generics",children:"osism/cfg-generics"})," repository. To do this, first\ncheck which version of osism/cfg-generics is used in a particular release. The version is\ndefined in ",(0,t.jsx)(n.code,{children:"generics_version"})," in the ",(0,t.jsx)(n.code,{children:"base.yml"})," file in the ",(0,t.jsx)(n.code,{children:"osism/release"})," repository. For OSISM 6.0.0,\nfor example, this is version ",(0,t.jsx)(n.a,{href:"https://github.com/osism/release/blob/main/6.0.0/base.yml#L6",children:"v0.20230919.0"}),".\nThis version is then added to the file ",(0,t.jsx)(n.code,{children:"gilt.yml"})," in the configuration repository instead of\n",(0,t.jsx)(n.code,{children:"main"})," at ",(0,t.jsx)(n.code,{children:"version"}),". This change must be made again after each execution of ",(0,t.jsx)(n.code,{children:"gilt overlay"})," as\nit is overwritten by the call of ",(0,t.jsx)(n.code,{children:"gilt overlay"}),". This cannot be realized differently in the\ncurrent implementation of ",(0,t.jsx)(n.a,{href:"https://github.com/retr0h/gilt",children:"Gilt"}),"."]})]})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Commit and push changes in the configuration repository. Since everyone here has their own\nworkflows for changes to the configuration repository, only a generic example for Git."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'git commit -a -s -m "manager: use OSISM version 7.0.5"\ngit push\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["The upgrade is described in the ",(0,t.jsx)(n.a,{href:"../upgrade-guide/manager",children:"Manager Upgrade Guide"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"opensearch-integration",children:"OpenSearch integration"}),"\n",(0,t.jsxs)(n.p,{children:["With the command ",(0,t.jsx)(n.code,{children:"osism log opensearch"})," it is possible to send SQL queries\nto the OpenSearch service. For the command to be functional, the OpenSearch\nintegration must be activated in the manager environment and the OpenSearch\naddress and port must be set."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/configuration.yml"',children:"manager_opensearch_enable: true\nmanager_opensearch_address: api-int.testbed.osism.xyz\nmanager_opensearch_port: 9200\nmanager_opensearch_protocol: https\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The integration can also be enabled later. ",(0,t.jsx)(n.code,{children:"osism update manager"})," is then\nexecuted after the configuration has been changed."]}),"\n",(0,t.jsx)(n.h2,{id:"openstack-broker-integration",children:"OpenStack broker integration"}),"\n",(0,t.jsxs)(n.p,{children:["If the Baremetal Service Integration in OSISM is used, the OpenStack Broker integration is\nrequired. The integration itself is activated by setting the parameter ",(0,t.jsx)(n.code,{children:"enable_listener"})," to ",(0,t.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The hosts in the ",(0,t.jsx)(n.code,{children:"manager_listener_broker_hosts"})," list are the control nodes of OpenStack.\nThe user is set via ",(0,t.jsx)(n.code,{children:"manager_listener_broker_username"}),". On OpenStack's RabbitMQ broker, the user ",(0,t.jsx)(n.code,{children:"openstack"}),"\nis present by default."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/configuration.yml"',children:'enable_listener: true\nmanager_listener_broker_hosts:\n - 192.168.16.10\n - 192.168.16.11\n - 192.168.16.12\nmanager_listener_broker_username: openstack\nmanager_listener_broker_uri: "{% for host in manager_listener_broker_hosts %}amqp://{{ manager_listener_broker_username }}:{{ manager_listener_broker_password }}@{{ host }}:5672/{% if not loop.last %};{% endif %}{% endfor %}"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The password used when using the ",(0,t.jsx)(n.code,{children:"openstack"})," user is ",(0,t.jsx)(n.code,{children:"rabbitmq_password"})," from ",(0,t.jsx)(n.code,{children:"environments/kolla/secrets.yml"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/secrets.yml"',children:"manager_listener_broker_password: RABBITMQ_PASSWORD\n"})})]})}function m(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},19365:(e,n,r)=>{r.d(n,{A:()=>i});r(96540);var t=r(18215);const a={tabItem:"tabItem_Ymn6"};var s=r(74848);function i(e){let{children:n,hidden:r,className:i}=e;return(0,s.jsx)("div",{role:"tabpanel",className:(0,t.A)(a.tabItem,i),hidden:r,children:n})}},11470:(e,n,r)=>{r.d(n,{A:()=>_});var t=r(96540),a=r(18215),s=r(23104),i=r(56347),o=r(205),l=r(57485),c=r(31682),d=r(89466);function u(e){return t.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,t.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:n,children:r}=e;return(0,t.useMemo)((()=>{const e=n??function(e){return u(e).map((e=>{let{props:{value:n,label:r,attributes:t,default:a}}=e;return{value:n,label:r,attributes:t,default:a}}))}(r);return function(e){const n=(0,c.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,r])}function m(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function g(e){let{queryString:n=!1,groupId:r}=e;const a=(0,i.W6)(),s=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,l.aZ)(s),(0,t.useCallback)((e=>{if(!s)return;const n=new URLSearchParams(a.location.search);n.set(s,e),a.replace({...a.location,search:n.toString()})}),[s,a])]}function p(e){const{defaultValue:n,queryString:r=!1,groupId:a}=e,s=h(e),[i,l]=(0,t.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!m({value:n,tabValues:r}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const t=r.find((e=>e.default))??r[0];if(!t)throw new Error("Unexpected error: 0 tabValues");return t.value}({defaultValue:n,tabValues:s}))),[c,u]=g({queryString:r,groupId:a}),[p,f]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,s]=(0,d.Dv)(r);return[a,(0,t.useCallback)((e=>{r&&s.set(e)}),[r,s])]}({groupId:a}),b=(()=>{const e=c??p;return m({value:e,tabValues:s})?e:null})();(0,o.A)((()=>{b&&l(b)}),[b]);return{selectedValue:i,selectValue:(0,t.useCallback)((e=>{if(!m({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),f(e)}),[u,f,s]),tabValues:s}}var f=r(92303);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=r(74848);function v(e){let{className:n,block:r,selectedValue:t,selectValue:i,tabValues:o}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.a_)(),d=e=>{const n=e.currentTarget,r=l.indexOf(n),a=o[r].value;a!==t&&(c(n),i(a))},u=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;n=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;n=l[r]??l[l.length-1];break}}n?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.A)("tabs",{"tabs--block":r},n),children:o.map((e=>{let{value:n,label:r,attributes:s}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:t===n?0:-1,"aria-selected":t===n,ref:e=>l.push(e),onKeyDown:u,onClick:d,...s,className:(0,a.A)("tabs__item",b.tabItem,s?.className,{"tabs__item--active":t===n}),children:r??n},n)}))})}function j(e){let{lazy:n,children:r,selectedValue:a}=e;const s=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=s.find((e=>e.props.value===a));return e?(0,t.cloneElement)(e,{className:"margin-top--md"}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:s.map(((e,n)=>(0,t.cloneElement)(e,{key:n,hidden:e.props.value!==a})))})}function y(e){const n=p(e);return(0,x.jsxs)("div",{className:(0,a.A)("tabs-container",b.tabList),children:[(0,x.jsx)(v,{...e,...n}),(0,x.jsx)(j,{...e,...n})]})}function _(e){const n=(0,f.A)();return(0,x.jsx)(y,{...e,children:u(e.children)},String(n))}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>o});var t=r(96540);const a={},s=t.createContext(a);function i(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5829.bd6e68ee.js b/assets/js/5829.bd6e68ee.js new file mode 100644 index 0000000000..fe6e9f1639 --- /dev/null +++ b/assets/js/5829.bd6e68ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5829],{45829:(e,n,t)=>{t.d(n,{a:()=>dn,c:()=>an});var r={};t.r(r),t.d(r,{attentionMarkers:()=>je,contentInitial:()=>Be,disable:()=>He,document:()=>De,flow:()=>Me,flowInitial:()=>_e,insideSpan:()=>Oe,string:()=>Le,text:()=>Pe});var i=t(76257);const u={};function o(e,n,t){if(function(e){return Boolean(e&&"object"==typeof e)}(e)){if("value"in e)return"html"!==e.type||t?e.value:"";if(n&&"alt"in e&&e.alt)return e.alt;if("children"in e)return c(e.children,n,t)}return Array.isArray(e)?c(e,n,t):""}function c(e,n,t){const r=[];let i=-1;for(;++i<e.length;)r[i]=o(e[i],n,t);return r.join("")}function s(e,n,t,r){const i=e.length;let u,o=0;if(n=n<0?-n>i?0:i+n:n>i?i:n,t=t>0?t:0,r.length<1e4)u=Array.from(r),u.unshift(n,t),e.splice(...u);else for(t&&e.splice(n,t);o<r.length;)u=r.slice(o,o+1e4),u.unshift(n,0),e.splice(...u),o+=1e4,n+=1e4}function l(e,n){return e.length>0?(s(e,e.length,0,n),e):n}const a={}.hasOwnProperty;function f(e,n){let t;for(t in n){const r=(a.call(e,t)?e[t]:void 0)||(e[t]={}),i=n[t];let u;if(i)for(u in i){a.call(r,u)||(r[u]=[]);const e=i[u];d(r[u],Array.isArray(e)?e:e?[e]:[])}}}function d(e,n){let t=-1;const r=[];for(;++t<n.length;)("after"===n[t].add?e:r).push(n[t]);s(e,0,0,r)}const h=A(/[A-Za-z]/),p=A(/[\dA-Za-z]/),m=A(/[#-'*+\--9=?A-Z^-~]/);function g(e){return null!==e&&(e<32||127===e)}const x=A(/\d/),k=A(/[\dA-Fa-f]/),y=A(/[!-/:-@[-`{-~]/);function F(e){return null!==e&&e<-2}function v(e){return null!==e&&(e<0||32===e)}function b(e){return-2===e||-1===e||32===e}const S=A(/[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/),E=A(/\s/);function A(e){return function(n){return null!==n&&e.test(String.fromCharCode(n))}}function I(e,n,t,r){const i=r?r-1:Number.POSITIVE_INFINITY;let u=0;return function(r){if(b(r))return e.enter(t),o(r);return n(r)};function o(r){return b(r)&&u++<i?(e.consume(r),o):(e.exit(t),n(r))}}const w={tokenize:function(e){const n=e.attempt(this.parser.constructs.contentInitial,(function(t){if(null===t)return void e.consume(t);return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),I(e,n,"linePrefix")}),(function(n){return e.enter("paragraph"),r(n)}));let t;return n;function r(n){const r=e.enter("chunkText",{contentType:"text",previous:t});return t&&(t.next=r),t=r,i(n)}function i(n){return null===n?(e.exit("chunkText"),e.exit("paragraph"),void e.consume(n)):F(n)?(e.consume(n),e.exit("chunkText"),r):(e.consume(n),i)}}};const C={tokenize:function(e){const n=this,t=[];let r,i,u,o=0;return c;function c(r){if(o<t.length){const i=t[o];return n.containerState=i[1],e.attempt(i[0].continuation,l,a)(r)}return a(r)}function l(e){if(o++,n.containerState._closeFlow){n.containerState._closeFlow=void 0,r&&y();const t=n.events.length;let i,u=t;for(;u--;)if("exit"===n.events[u][0]&&"chunkFlow"===n.events[u][1].type){i=n.events[u][1].end;break}k(o);let c=t;for(;c<n.events.length;)n.events[c][1].end=Object.assign({},i),c++;return s(n.events,u+1,0,n.events.slice(t)),n.events.length=c,a(e)}return c(e)}function a(i){if(o===t.length){if(!r)return h(i);if(r.currentConstruct&&r.currentConstruct.concrete)return m(i);n.interrupt=Boolean(r.currentConstruct&&!r._gfmTableDynamicInterruptHack)}return n.containerState={},e.check(T,f,d)(i)}function f(e){return r&&y(),k(o),h(e)}function d(e){return n.parser.lazy[n.now().line]=o!==t.length,u=n.now().offset,m(e)}function h(t){return n.containerState={},e.attempt(T,p,m)(t)}function p(e){return o++,t.push([n.currentConstruct,n.containerState]),h(e)}function m(t){return null===t?(r&&y(),k(0),void e.consume(t)):(r=r||n.parser.flow(n.now()),e.enter("chunkFlow",{contentType:"flow",previous:i,_tokenizer:r}),g(t))}function g(t){return null===t?(x(e.exit("chunkFlow"),!0),k(0),void e.consume(t)):F(t)?(e.consume(t),x(e.exit("chunkFlow")),o=0,n.interrupt=void 0,c):(e.consume(t),g)}function x(e,t){const c=n.sliceStream(e);if(t&&c.push(null),e.previous=i,i&&(i.next=e),i=e,r.defineSkip(e.start),r.write(c),n.parser.lazy[e.start.line]){let e=r.events.length;for(;e--;)if(r.events[e][1].start.offset<u&&(!r.events[e][1].end||r.events[e][1].end.offset>u))return;const t=n.events.length;let i,c,l=t;for(;l--;)if("exit"===n.events[l][0]&&"chunkFlow"===n.events[l][1].type){if(i){c=n.events[l][1].end;break}i=!0}for(k(o),e=t;e<n.events.length;)n.events[e][1].end=Object.assign({},c),e++;s(n.events,l+1,0,n.events.slice(t)),n.events.length=e}}function k(r){let i=t.length;for(;i-- >r;){const r=t[i];n.containerState=r[1],r[0].exit.call(n,e)}t.length=r}function y(){r.write([null]),i=void 0,r=void 0,n.containerState._closeFlow=void 0}}},T={tokenize:function(e,n,t){return I(e,e.attempt(this.parser.constructs.document,n,t),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}};const z={tokenize:function(e,n,t){return function(n){return b(n)?I(e,r,"linePrefix")(n):r(n)};function r(e){return null===e||F(e)?n(e):t(e)}},partial:!0};function D(e){const n={};let t,r,i,u,o,c,l,a=-1;for(;++a<e.length;){for(;a in n;)a=n[a];if(t=e[a],a&&"chunkFlow"===t[1].type&&"listItemPrefix"===e[a-1][1].type&&(c=t[1]._tokenizer.events,i=0,i<c.length&&"lineEndingBlank"===c[i][1].type&&(i+=2),i<c.length&&"content"===c[i][1].type))for(;++i<c.length&&"content"!==c[i][1].type;)"chunkText"===c[i][1].type&&(c[i][1]._isInFirstContentOfListItem=!0,i++);if("enter"===t[0])t[1].contentType&&(Object.assign(n,B(e,a)),a=n[a],l=!0);else if(t[1]._container){for(i=a,r=void 0;i--&&(u=e[i],"lineEnding"===u[1].type||"lineEndingBlank"===u[1].type);)"enter"===u[0]&&(r&&(e[r][1].type="lineEndingBlank"),u[1].type="lineEnding",r=i);r&&(t[1].end=Object.assign({},e[r][1].start),o=e.slice(r,a),o.unshift(t),s(e,r,a-r+1,o))}}return!l}function B(e,n){const t=e[n][1],r=e[n][2];let i=n-1;const u=[],o=t._tokenizer||r.parser[t.contentType](t.start),c=o.events,l=[],a={};let f,d,h=-1,p=t,m=0,g=0;const x=[g];for(;p;){for(;e[++i][1]!==p;);u.push(i),p._tokenizer||(f=r.sliceStream(p),p.next||f.push(null),d&&o.defineSkip(p.start),p._isInFirstContentOfListItem&&(o._gfmTasklistFirstContentOfListItem=!0),o.write(f),p._isInFirstContentOfListItem&&(o._gfmTasklistFirstContentOfListItem=void 0)),d=p,p=p.next}for(p=t;++h<c.length;)"exit"===c[h][0]&&"enter"===c[h-1][0]&&c[h][1].type===c[h-1][1].type&&c[h][1].start.line!==c[h][1].end.line&&(g=h+1,x.push(g),p._tokenizer=void 0,p.previous=void 0,p=p.next);for(o.events=[],p?(p._tokenizer=void 0,p.previous=void 0):x.pop(),h=x.length;h--;){const n=c.slice(x[h],x[h+1]),t=u.pop();l.unshift([t,t+n.length-1]),s(e,t,2,n)}for(h=-1;++h<l.length;)a[m+l[h][0]]=m+l[h][1],m+=l[h][1]-l[h][0]-1;return a}const _={tokenize:function(e,n){let t;return function(n){return e.enter("content"),t=e.enter("chunkContent",{contentType:"content"}),r(n)};function r(n){return null===n?i(n):F(n)?e.check(M,u,i)(n):(e.consume(n),r)}function i(t){return e.exit("chunkContent"),e.exit("content"),n(t)}function u(n){return e.consume(n),e.exit("chunkContent"),t.next=e.enter("chunkContent",{contentType:"content",previous:t}),t=t.next,r}},resolve:function(e){return D(e),e}},M={tokenize:function(e,n,t){const r=this;return function(n){return e.exit("chunkContent"),e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),I(e,i,"linePrefix")};function i(i){if(null===i||F(i))return t(i);const u=r.events[r.events.length-1];return!r.parser.constructs.disable.null.includes("codeIndented")&&u&&"linePrefix"===u[1].type&&u[2].sliceSerialize(u[1],!0).length>=4?n(i):e.interrupt(r.parser.constructs.flow,t,n)(i)}},partial:!0};const L={tokenize:function(e){const n=this,t=e.attempt(z,(function(r){if(null===r)return void e.consume(r);return e.enter("lineEndingBlank"),e.consume(r),e.exit("lineEndingBlank"),n.currentConstruct=void 0,t}),e.attempt(this.parser.constructs.flowInitial,r,I(e,e.attempt(this.parser.constructs.flow,r,e.attempt(_,r)),"linePrefix")));return t;function r(r){if(null!==r)return e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),n.currentConstruct=void 0,t;e.consume(r)}}};const P={resolveAll:R()},O=H("string"),j=H("text");function H(e){return{tokenize:function(n){const t=this,r=this.parser.constructs[e],i=n.attempt(r,u,o);return u;function u(e){return s(e)?i(e):o(e)}function o(e){if(null!==e)return n.enter("data"),n.consume(e),c;n.consume(e)}function c(e){return s(e)?(n.exit("data"),i(e)):(n.consume(e),c)}function s(e){if(null===e)return!0;const n=r[e];let i=-1;if(n)for(;++i<n.length;){const e=n[i];if(!e.previous||e.previous.call(t,t.previous))return!0}return!1}},resolveAll:R("text"===e?q:void 0)}}function R(e){return function(n,t){let r,i=-1;for(;++i<=n.length;)void 0===r?n[i]&&"data"===n[i][1].type&&(r=i,i++):n[i]&&"data"===n[i][1].type||(i!==r+2&&(n[r][1].end=n[i-1][1].end,n.splice(r+2,i-r-2),i=r+2),r=void 0);return e?e(n,t):n}}function q(e,n){let t=0;for(;++t<=e.length;)if((t===e.length||"lineEnding"===e[t][1].type)&&"data"===e[t-1][1].type){const r=e[t-1][1],i=n.sliceStream(r);let u,o=i.length,c=-1,s=0;for(;o--;){const e=i[o];if("string"==typeof e){for(c=e.length;32===e.charCodeAt(c-1);)s++,c--;if(c)break;c=-1}else if(-2===e)u=!0,s++;else if(-1!==e){o++;break}}if(s){const i={type:t===e.length||u||s<2?"lineSuffix":"hardBreakTrailing",start:{line:r.end.line,column:r.end.column-s,offset:r.end.offset-s,_index:r.start._index+o,_bufferIndex:o?c:r.start._bufferIndex+c},end:Object.assign({},r.end)};r.end=Object.assign({},i.start),r.start.offset===r.end.offset?Object.assign(r,i):(e.splice(t,0,["enter",i,n],["exit",i,n]),t+=2)}t++}return e}function V(e,n,t){const r=[];let i=-1;for(;++i<e.length;){const u=e[i].resolveAll;u&&!r.includes(u)&&(n=u(n,t),r.push(u))}return n}function Q(e,n,t){let r=Object.assign(t?Object.assign({},t):{line:1,column:1,offset:0},{_index:0,_bufferIndex:-1});const i={},u=[];let o=[],c=[],a=!0;const f={consume:function(e){F(e)?(r.line++,r.column=1,r.offset+=-3===e?2:1,S()):-1!==e&&(r.column++,r.offset++);r._bufferIndex<0?r._index++:(r._bufferIndex++,r._bufferIndex===o[r._index].length&&(r._bufferIndex=-1,r._index++));d.previous=e,a=!0},enter:function(e,n){const t=n||{};return t.type=e,t.start=g(),d.events.push(["enter",t,d]),c.push(t),t},exit:function(e){const n=c.pop();return n.end=g(),d.events.push(["exit",n,d]),n},attempt:v((function(e,n){b(e,n.from)})),check:v(y),interrupt:v(y,{interrupt:!0})},d={previous:null,code:null,containerState:{},events:[],parser:e,sliceStream:m,sliceSerialize:function(e,n){return function(e,n){let t=-1;const r=[];let i;for(;++t<e.length;){const u=e[t];let o;if("string"==typeof u)o=u;else switch(u){case-5:o="\r";break;case-4:o="\n";break;case-3:o="\r\n";break;case-2:o=n?" ":"\t";break;case-1:if(!n&&i)continue;o=" ";break;default:o=String.fromCharCode(u)}i=-2===u,r.push(o)}return r.join("")}(m(e),n)},now:g,defineSkip:function(e){i[e.line]=e.column,S()},write:function(e){if(o=l(o,e),x(),null!==o[o.length-1])return[];return b(n,0),d.events=V(u,d.events,d),d.events}};let h,p=n.tokenize.call(d,f);return n.resolveAll&&u.push(n),d;function m(e){return function(e,n){const t=n.start._index,r=n.start._bufferIndex,i=n.end._index,u=n.end._bufferIndex;let o;if(t===i)o=[e[t].slice(r,u)];else{if(o=e.slice(t,i),r>-1){const e=o[0];"string"==typeof e?o[0]=e.slice(r):o.shift()}u>0&&o.push(e[i].slice(0,u))}return o}(o,e)}function g(){const{line:e,column:n,offset:t,_index:i,_bufferIndex:u}=r;return{line:e,column:n,offset:t,_index:i,_bufferIndex:u}}function x(){let e;for(;r._index<o.length;){const n=o[r._index];if("string"==typeof n)for(e=r._index,r._bufferIndex<0&&(r._bufferIndex=0);r._index===e&&r._bufferIndex<n.length;)k(n.charCodeAt(r._bufferIndex));else k(n)}}function k(e){a=void 0,h=e,p=p(e)}function y(e,n){n.restore()}function v(e,n){return function(t,i,u){let o,s,l,h;return Array.isArray(t)?p(t):"tokenize"in t?p([t]):function(e){return n;function n(n){const t=null!==n&&e[n],r=null!==n&&e.null;return p([...Array.isArray(t)?t:t?[t]:[],...Array.isArray(r)?r:r?[r]:[]])(n)}}(t);function p(e){return o=e,s=0,0===e.length?u:m(e[s])}function m(e){return function(t){h=function(){const e=g(),n=d.previous,t=d.currentConstruct,i=d.events.length,u=Array.from(c);return{restore:o,from:i};function o(){r=e,d.previous=n,d.currentConstruct=t,d.events.length=i,c=u,S()}}(),l=e,e.partial||(d.currentConstruct=e);if(e.name&&d.parser.constructs.disable.null.includes(e.name))return k(t);return e.tokenize.call(n?Object.assign(Object.create(d),n):d,f,x,k)(t)}}function x(n){return a=!0,e(l,h),i}function k(e){return a=!0,h.restore(),++s<o.length?m(o[s]):u}}}function b(e,n){e.resolveAll&&!u.includes(e)&&u.push(e),e.resolve&&s(d.events,n,d.events.length-n,e.resolve(d.events.slice(n),d)),e.resolveTo&&(d.events=e.resolveTo(d.events,d))}function S(){r.line in i&&r.column<2&&(r.column=i[r.line],r.offset+=i[r.line]-1)}}const N={name:"thematicBreak",tokenize:function(e,n,t){let r,i=0;return function(n){return e.enter("thematicBreak"),function(e){return r=e,u(e)}(n)};function u(u){return u===r?(e.enter("thematicBreakSequence"),o(u)):i>=3&&(null===u||F(u))?(e.exit("thematicBreak"),n(u)):t(u)}function o(n){return n===r?(e.consume(n),i++,o):(e.exit("thematicBreakSequence"),b(n)?I(e,u,"whitespace")(n):u(n))}}};const U={name:"list",tokenize:function(e,n,t){const r=this,i=r.events[r.events.length-1];let u=i&&"linePrefix"===i[1].type?i[2].sliceSerialize(i[1],!0).length:0,o=0;return function(n){const i=r.containerState.type||(42===n||43===n||45===n?"listUnordered":"listOrdered");if("listUnordered"===i?!r.containerState.marker||n===r.containerState.marker:x(n)){if(r.containerState.type||(r.containerState.type=i,e.enter(i,{_container:!0})),"listUnordered"===i)return e.enter("listItemPrefix"),42===n||45===n?e.check(N,t,s)(n):s(n);if(!r.interrupt||49===n)return e.enter("listItemPrefix"),e.enter("listItemValue"),c(n)}return t(n)};function c(n){return x(n)&&++o<10?(e.consume(n),c):(!r.interrupt||o<2)&&(r.containerState.marker?n===r.containerState.marker:41===n||46===n)?(e.exit("listItemValue"),s(n)):t(n)}function s(n){return e.enter("listItemMarker"),e.consume(n),e.exit("listItemMarker"),r.containerState.marker=r.containerState.marker||n,e.check(z,r.interrupt?t:l,e.attempt($,f,a))}function l(e){return r.containerState.initialBlankLine=!0,u++,f(e)}function a(n){return b(n)?(e.enter("listItemPrefixWhitespace"),e.consume(n),e.exit("listItemPrefixWhitespace"),f):t(n)}function f(t){return r.containerState.size=u+r.sliceSerialize(e.exit("listItemPrefix"),!0).length,n(t)}},continuation:{tokenize:function(e,n,t){const r=this;return r.containerState._closeFlow=void 0,e.check(z,(function(t){return r.containerState.furtherBlankLines=r.containerState.furtherBlankLines||r.containerState.initialBlankLine,I(e,n,"listItemIndent",r.containerState.size+1)(t)}),(function(t){if(r.containerState.furtherBlankLines||!b(t))return r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,i(t);return r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,e.attempt(W,n,i)(t)}));function i(i){return r.containerState._closeFlow=!0,r.interrupt=void 0,I(e,e.attempt(U,n,t),"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(i)}}},exit:function(e){e.exit(this.containerState.type)}},$={tokenize:function(e,n,t){const r=this;return I(e,(function(e){const i=r.events[r.events.length-1];return!b(e)&&i&&"listItemPrefixWhitespace"===i[1].type?n(e):t(e)}),"listItemPrefixWhitespace",r.parser.constructs.disable.null.includes("codeIndented")?void 0:5)},partial:!0},W={tokenize:function(e,n,t){const r=this;return I(e,(function(e){const i=r.events[r.events.length-1];return i&&"listItemIndent"===i[1].type&&i[2].sliceSerialize(i[1],!0).length===r.containerState.size?n(e):t(e)}),"listItemIndent",r.containerState.size+1)},partial:!0};const Z={name:"blockQuote",tokenize:function(e,n,t){const r=this;return function(n){if(62===n){const t=r.containerState;return t.open||(e.enter("blockQuote",{_container:!0}),t.open=!0),e.enter("blockQuotePrefix"),e.enter("blockQuoteMarker"),e.consume(n),e.exit("blockQuoteMarker"),i}return t(n)};function i(t){return b(t)?(e.enter("blockQuotePrefixWhitespace"),e.consume(t),e.exit("blockQuotePrefixWhitespace"),e.exit("blockQuotePrefix"),n):(e.exit("blockQuotePrefix"),n(t))}},continuation:{tokenize:function(e,n,t){const r=this;return function(n){if(b(n))return I(e,i,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(n);return i(n)};function i(r){return e.attempt(Z,n,t)(r)}}},exit:function(e){e.exit("blockQuote")}};function Y(e,n,t,r,i,u,o,c,s){const l=s||Number.POSITIVE_INFINITY;let a=0;return function(n){if(60===n)return e.enter(r),e.enter(i),e.enter(u),e.consume(n),e.exit(u),f;if(null===n||32===n||41===n||g(n))return t(n);return e.enter(r),e.enter(o),e.enter(c),e.enter("chunkString",{contentType:"string"}),p(n)};function f(t){return 62===t?(e.enter(u),e.consume(t),e.exit(u),e.exit(i),e.exit(r),n):(e.enter(c),e.enter("chunkString",{contentType:"string"}),d(t))}function d(n){return 62===n?(e.exit("chunkString"),e.exit(c),f(n)):null===n||60===n||F(n)?t(n):(e.consume(n),92===n?h:d)}function h(n){return 60===n||62===n||92===n?(e.consume(n),d):d(n)}function p(i){return a||null!==i&&41!==i&&!v(i)?a<l&&40===i?(e.consume(i),a++,p):41===i?(e.consume(i),a--,p):null===i||32===i||40===i||g(i)?t(i):(e.consume(i),92===i?m:p):(e.exit("chunkString"),e.exit(c),e.exit(o),e.exit(r),n(i))}function m(n){return 40===n||41===n||92===n?(e.consume(n),p):p(n)}}function G(e,n,t,r,i,u){const o=this;let c,s=0;return function(n){return e.enter(r),e.enter(i),e.consume(n),e.exit(i),e.enter(u),l};function l(f){return s>999||null===f||91===f||93===f&&!c||94===f&&!s&&"_hiddenFootnoteSupport"in o.parser.constructs?t(f):93===f?(e.exit(u),e.enter(i),e.consume(f),e.exit(i),e.exit(r),n):F(f)?(e.enter("lineEnding"),e.consume(f),e.exit("lineEnding"),l):(e.enter("chunkString",{contentType:"string"}),a(f))}function a(n){return null===n||91===n||93===n||F(n)||s++>999?(e.exit("chunkString"),l(n)):(e.consume(n),c||(c=!b(n)),92===n?f:a)}function f(n){return 91===n||92===n||93===n?(e.consume(n),s++,a):a(n)}}function J(e,n,t,r,i,u){let o;return function(n){if(34===n||39===n||40===n)return e.enter(r),e.enter(i),e.consume(n),e.exit(i),o=40===n?41:n,c;return t(n)};function c(t){return t===o?(e.enter(i),e.consume(t),e.exit(i),e.exit(r),n):(e.enter(u),s(t))}function s(n){return n===o?(e.exit(u),c(o)):null===n?t(n):F(n)?(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),I(e,s,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),l(n))}function l(n){return n===o||null===n||F(n)?(e.exit("chunkString"),s(n)):(e.consume(n),92===n?a:l)}function a(n){return n===o||92===n?(e.consume(n),l):l(n)}}function K(e,n){let t;return function r(i){if(F(i))return e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),t=!0,r;if(b(i))return I(e,r,t?"linePrefix":"lineSuffix")(i);return n(i)}}function X(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const ee={name:"definition",tokenize:function(e,n,t){const r=this;let i;return function(n){return e.enter("definition"),function(n){return G.call(r,e,u,t,"definitionLabel","definitionLabelMarker","definitionLabelString")(n)}(n)};function u(n){return i=X(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)),58===n?(e.enter("definitionMarker"),e.consume(n),e.exit("definitionMarker"),o):t(n)}function o(n){return v(n)?K(e,c)(n):c(n)}function c(n){return Y(e,s,t,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(n)}function s(n){return e.attempt(ne,l,l)(n)}function l(n){return b(n)?I(e,a,"whitespace")(n):a(n)}function a(u){return null===u||F(u)?(e.exit("definition"),r.parser.defined.push(i),n(u)):t(u)}}},ne={tokenize:function(e,n,t){return function(n){return v(n)?K(e,r)(n):t(n)};function r(n){return J(e,i,t,"definitionTitle","definitionTitleMarker","definitionTitleString")(n)}function i(n){return b(n)?I(e,u,"whitespace")(n):u(n)}function u(e){return null===e||F(e)?n(e):t(e)}},partial:!0};const te={name:"codeIndented",tokenize:function(e,n,t){const r=this;return function(n){return e.enter("codeIndented"),I(e,i,"linePrefix",5)(n)};function i(e){const n=r.events[r.events.length-1];return n&&"linePrefix"===n[1].type&&n[2].sliceSerialize(n[1],!0).length>=4?u(e):t(e)}function u(n){return null===n?c(n):F(n)?e.attempt(re,u,c)(n):(e.enter("codeFlowValue"),o(n))}function o(n){return null===n||F(n)?(e.exit("codeFlowValue"),u(n)):(e.consume(n),o)}function c(t){return e.exit("codeIndented"),n(t)}}},re={tokenize:function(e,n,t){const r=this;return i;function i(n){return r.parser.lazy[r.now().line]?t(n):F(n)?(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),i):I(e,u,"linePrefix",5)(n)}function u(e){const u=r.events[r.events.length-1];return u&&"linePrefix"===u[1].type&&u[2].sliceSerialize(u[1],!0).length>=4?n(e):F(e)?i(e):t(e)}},partial:!0};const ie={name:"headingAtx",tokenize:function(e,n,t){let r=0;return function(n){return e.enter("atxHeading"),function(n){return e.enter("atxHeadingSequence"),i(n)}(n)};function i(n){return 35===n&&r++<6?(e.consume(n),i):null===n||v(n)?(e.exit("atxHeadingSequence"),u(n)):t(n)}function u(t){return 35===t?(e.enter("atxHeadingSequence"),o(t)):null===t||F(t)?(e.exit("atxHeading"),n(t)):b(t)?I(e,u,"whitespace")(t):(e.enter("atxHeadingText"),c(t))}function o(n){return 35===n?(e.consume(n),o):(e.exit("atxHeadingSequence"),u(n))}function c(n){return null===n||35===n||v(n)?(e.exit("atxHeadingText"),u(n)):(e.consume(n),c)}},resolve:function(e,n){let t,r,i=e.length-2,u=3;"whitespace"===e[u][1].type&&(u+=2);i-2>u&&"whitespace"===e[i][1].type&&(i-=2);"atxHeadingSequence"===e[i][1].type&&(u===i-1||i-4>u&&"whitespace"===e[i-2][1].type)&&(i-=u+1===i?2:4);i>u&&(t={type:"atxHeadingText",start:e[u][1].start,end:e[i][1].end},r={type:"chunkText",start:e[u][1].start,end:e[i][1].end,contentType:"text"},s(e,u,i-u+1,[["enter",t,n],["enter",r,n],["exit",r,n],["exit",t,n]]));return e}};const ue={name:"setextUnderline",tokenize:function(e,n,t){const r=this;let i;return function(n){let o,c=r.events.length;for(;c--;)if("lineEnding"!==r.events[c][1].type&&"linePrefix"!==r.events[c][1].type&&"content"!==r.events[c][1].type){o="paragraph"===r.events[c][1].type;break}if(!r.parser.lazy[r.now().line]&&(r.interrupt||o))return e.enter("setextHeadingLine"),i=n,function(n){return e.enter("setextHeadingLineSequence"),u(n)}(n);return t(n)};function u(n){return n===i?(e.consume(n),u):(e.exit("setextHeadingLineSequence"),b(n)?I(e,o,"lineSuffix")(n):o(n))}function o(r){return null===r||F(r)?(e.exit("setextHeadingLine"),n(r)):t(r)}},resolveTo:function(e,n){let t,r,i,u=e.length;for(;u--;)if("enter"===e[u][0]){if("content"===e[u][1].type){t=u;break}"paragraph"===e[u][1].type&&(r=u)}else"content"===e[u][1].type&&e.splice(u,1),i||"definition"!==e[u][1].type||(i=u);const o={type:"setextHeading",start:Object.assign({},e[r][1].start),end:Object.assign({},e[e.length-1][1].end)};e[r][1].type="setextHeadingText",i?(e.splice(r,0,["enter",o,n]),e.splice(i+1,0,["exit",e[t][1],n]),e[t][1].end=Object.assign({},e[i][1].end)):e[t][1]=o;return e.push(["exit",o,n]),e}};const oe=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],ce=["pre","script","style","textarea"],se={name:"htmlFlow",tokenize:function(e,n,t){const r=this;let i,u,o,c,s;return function(n){return function(n){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(n),l}(n)};function l(c){return 33===c?(e.consume(c),a):47===c?(e.consume(c),u=!0,m):63===c?(e.consume(c),i=3,r.interrupt?n:H):h(c)?(e.consume(c),o=String.fromCharCode(c),g):t(c)}function a(u){return 45===u?(e.consume(u),i=2,f):91===u?(e.consume(u),i=5,c=0,d):h(u)?(e.consume(u),i=4,r.interrupt?n:H):t(u)}function f(i){return 45===i?(e.consume(i),r.interrupt?n:H):t(i)}function d(i){const u="CDATA[";return i===u.charCodeAt(c++)?(e.consume(i),6===c?r.interrupt?n:D:d):t(i)}function m(n){return h(n)?(e.consume(n),o=String.fromCharCode(n),g):t(n)}function g(c){if(null===c||47===c||62===c||v(c)){const s=47===c,l=o.toLowerCase();return s||u||!ce.includes(l)?oe.includes(o.toLowerCase())?(i=6,s?(e.consume(c),x):r.interrupt?n(c):D(c)):(i=7,r.interrupt&&!r.parser.lazy[r.now().line]?t(c):u?k(c):y(c)):(i=1,r.interrupt?n(c):D(c))}return 45===c||p(c)?(e.consume(c),o+=String.fromCharCode(c),g):t(c)}function x(i){return 62===i?(e.consume(i),r.interrupt?n:D):t(i)}function k(n){return b(n)?(e.consume(n),k):T(n)}function y(n){return 47===n?(e.consume(n),T):58===n||95===n||h(n)?(e.consume(n),S):b(n)?(e.consume(n),y):T(n)}function S(n){return 45===n||46===n||58===n||95===n||p(n)?(e.consume(n),S):E(n)}function E(n){return 61===n?(e.consume(n),A):b(n)?(e.consume(n),E):y(n)}function A(n){return null===n||60===n||61===n||62===n||96===n?t(n):34===n||39===n?(e.consume(n),s=n,I):b(n)?(e.consume(n),A):w(n)}function I(n){return n===s?(e.consume(n),s=null,C):null===n||F(n)?t(n):(e.consume(n),I)}function w(n){return null===n||34===n||39===n||47===n||60===n||61===n||62===n||96===n||v(n)?E(n):(e.consume(n),w)}function C(e){return 47===e||62===e||b(e)?y(e):t(e)}function T(n){return 62===n?(e.consume(n),z):t(n)}function z(n){return null===n||F(n)?D(n):b(n)?(e.consume(n),z):t(n)}function D(n){return 45===n&&2===i?(e.consume(n),L):60===n&&1===i?(e.consume(n),P):62===n&&4===i?(e.consume(n),R):63===n&&3===i?(e.consume(n),H):93===n&&5===i?(e.consume(n),j):!F(n)||6!==i&&7!==i?null===n||F(n)?(e.exit("htmlFlowData"),B(n)):(e.consume(n),D):(e.exit("htmlFlowData"),e.check(le,q,B)(n))}function B(n){return e.check(ae,_,q)(n)}function _(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),M}function M(n){return null===n||F(n)?B(n):(e.enter("htmlFlowData"),D(n))}function L(n){return 45===n?(e.consume(n),H):D(n)}function P(n){return 47===n?(e.consume(n),o="",O):D(n)}function O(n){if(62===n){const t=o.toLowerCase();return ce.includes(t)?(e.consume(n),R):D(n)}return h(n)&&o.length<8?(e.consume(n),o+=String.fromCharCode(n),O):D(n)}function j(n){return 93===n?(e.consume(n),H):D(n)}function H(n){return 62===n?(e.consume(n),R):45===n&&2===i?(e.consume(n),H):D(n)}function R(n){return null===n||F(n)?(e.exit("htmlFlowData"),q(n)):(e.consume(n),R)}function q(t){return e.exit("htmlFlow"),n(t)}},resolveTo:function(e){let n=e.length;for(;n--&&("enter"!==e[n][0]||"htmlFlow"!==e[n][1].type););n>1&&"linePrefix"===e[n-2][1].type&&(e[n][1].start=e[n-2][1].start,e[n+1][1].start=e[n-2][1].start,e.splice(n-2,2));return e},concrete:!0},le={tokenize:function(e,n,t){return function(r){return e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),e.attempt(z,n,t)}},partial:!0},ae={tokenize:function(e,n,t){const r=this;return function(n){if(F(n))return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),i;return t(n)};function i(e){return r.parser.lazy[r.now().line]?t(e):n(e)}},partial:!0};const fe={tokenize:function(e,n,t){const r=this;return function(n){if(null===n)return t(n);return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),i};function i(e){return r.parser.lazy[r.now().line]?t(e):n(e)}},partial:!0},de={name:"codeFenced",tokenize:function(e,n,t){const r=this,i={tokenize:function(e,n,t){let i=0;return o;function o(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),s}function s(n){return e.enter("codeFencedFence"),b(n)?I(e,l,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(n):l(n)}function l(n){return n===u?(e.enter("codeFencedFenceSequence"),a(n)):t(n)}function a(n){return n===u?(i++,e.consume(n),a):i>=c?(e.exit("codeFencedFenceSequence"),b(n)?I(e,f,"whitespace")(n):f(n)):t(n)}function f(r){return null===r||F(r)?(e.exit("codeFencedFence"),n(r)):t(r)}},partial:!0};let u,o=0,c=0;return function(n){return function(n){const t=r.events[r.events.length-1];return o=t&&"linePrefix"===t[1].type?t[2].sliceSerialize(t[1],!0).length:0,u=n,e.enter("codeFenced"),e.enter("codeFencedFence"),e.enter("codeFencedFenceSequence"),s(n)}(n)};function s(n){return n===u?(c++,e.consume(n),s):c<3?t(n):(e.exit("codeFencedFenceSequence"),b(n)?I(e,l,"whitespace")(n):l(n))}function l(t){return null===t||F(t)?(e.exit("codeFencedFence"),r.interrupt?n(t):e.check(fe,h,k)(t)):(e.enter("codeFencedFenceInfo"),e.enter("chunkString",{contentType:"string"}),a(t))}function a(n){return null===n||F(n)?(e.exit("chunkString"),e.exit("codeFencedFenceInfo"),l(n)):b(n)?(e.exit("chunkString"),e.exit("codeFencedFenceInfo"),I(e,f,"whitespace")(n)):96===n&&n===u?t(n):(e.consume(n),a)}function f(n){return null===n||F(n)?l(n):(e.enter("codeFencedFenceMeta"),e.enter("chunkString",{contentType:"string"}),d(n))}function d(n){return null===n||F(n)?(e.exit("chunkString"),e.exit("codeFencedFenceMeta"),l(n)):96===n&&n===u?t(n):(e.consume(n),d)}function h(n){return e.attempt(i,k,p)(n)}function p(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),m}function m(n){return o>0&&b(n)?I(e,g,"linePrefix",o+1)(n):g(n)}function g(n){return null===n||F(n)?e.check(fe,h,k)(n):(e.enter("codeFlowValue"),x(n))}function x(n){return null===n||F(n)?(e.exit("codeFlowValue"),g(n)):(e.consume(n),x)}function k(t){return e.exit("codeFenced"),n(t)}},concrete:!0};const he=document.createElement("i");function pe(e){const n="&"+e+";";he.innerHTML=n;const t=he.textContent;return(59!==t.charCodeAt(t.length-1)||"semi"===e)&&(t!==n&&t)}const me={name:"characterReference",tokenize:function(e,n,t){const r=this;let i,u,o=0;return function(n){return e.enter("characterReference"),e.enter("characterReferenceMarker"),e.consume(n),e.exit("characterReferenceMarker"),c};function c(n){return 35===n?(e.enter("characterReferenceMarkerNumeric"),e.consume(n),e.exit("characterReferenceMarkerNumeric"),s):(e.enter("characterReferenceValue"),i=31,u=p,l(n))}function s(n){return 88===n||120===n?(e.enter("characterReferenceMarkerHexadecimal"),e.consume(n),e.exit("characterReferenceMarkerHexadecimal"),e.enter("characterReferenceValue"),i=6,u=k,l):(e.enter("characterReferenceValue"),i=7,u=x,l(n))}function l(c){if(59===c&&o){const i=e.exit("characterReferenceValue");return u!==p||pe(r.sliceSerialize(i))?(e.enter("characterReferenceMarker"),e.consume(c),e.exit("characterReferenceMarker"),e.exit("characterReference"),n):t(c)}return u(c)&&o++<i?(e.consume(c),l):t(c)}}};const ge={name:"characterEscape",tokenize:function(e,n,t){return function(n){return e.enter("characterEscape"),e.enter("escapeMarker"),e.consume(n),e.exit("escapeMarker"),r};function r(r){return y(r)?(e.enter("characterEscapeValue"),e.consume(r),e.exit("characterEscapeValue"),e.exit("characterEscape"),n):t(r)}}};const xe={name:"lineEnding",tokenize:function(e,n){return function(t){return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),I(e,n,"linePrefix")}}};const ke={name:"labelEnd",tokenize:function(e,n,t){const r=this;let i,u,o=r.events.length;for(;o--;)if(("labelImage"===r.events[o][1].type||"labelLink"===r.events[o][1].type)&&!r.events[o][1]._balanced){i=r.events[o][1];break}return function(n){if(!i)return t(n);if(i._inactive)return a(n);return u=r.parser.defined.includes(X(r.sliceSerialize({start:i.end,end:r.now()}))),e.enter("labelEnd"),e.enter("labelMarker"),e.consume(n),e.exit("labelMarker"),e.exit("labelEnd"),c};function c(n){return 40===n?e.attempt(ye,l,u?l:a)(n):91===n?e.attempt(Fe,l,u?s:a)(n):u?l(n):a(n)}function s(n){return e.attempt(ve,l,a)(n)}function l(e){return n(e)}function a(e){return i._balanced=!0,t(e)}},resolveTo:function(e,n){let t,r,i,u,o=e.length,c=0;for(;o--;)if(t=e[o][1],r){if("link"===t.type||"labelLink"===t.type&&t._inactive)break;"enter"===e[o][0]&&"labelLink"===t.type&&(t._inactive=!0)}else if(i){if("enter"===e[o][0]&&("labelImage"===t.type||"labelLink"===t.type)&&!t._balanced&&(r=o,"labelLink"!==t.type)){c=2;break}}else"labelEnd"===t.type&&(i=o);const a={type:"labelLink"===e[r][1].type?"link":"image",start:Object.assign({},e[r][1].start),end:Object.assign({},e[e.length-1][1].end)},f={type:"label",start:Object.assign({},e[r][1].start),end:Object.assign({},e[i][1].end)},d={type:"labelText",start:Object.assign({},e[r+c+2][1].end),end:Object.assign({},e[i-2][1].start)};return u=[["enter",a,n],["enter",f,n]],u=l(u,e.slice(r+1,r+c+3)),u=l(u,[["enter",d,n]]),u=l(u,V(n.parser.constructs.insideSpan.null,e.slice(r+c+4,i-3),n)),u=l(u,[["exit",d,n],e[i-2],e[i-1],["exit",f,n]]),u=l(u,e.slice(i+1)),u=l(u,[["exit",a,n]]),s(e,r,e.length,u),e},resolveAll:function(e){let n=-1;for(;++n<e.length;){const t=e[n][1];"labelImage"!==t.type&&"labelLink"!==t.type&&"labelEnd"!==t.type||(e.splice(n+1,"labelImage"===t.type?4:2),t.type="data",n++)}return e}},ye={tokenize:function(e,n,t){return function(n){return e.enter("resource"),e.enter("resourceMarker"),e.consume(n),e.exit("resourceMarker"),r};function r(n){return v(n)?K(e,i)(n):i(n)}function i(n){return 41===n?l(n):Y(e,u,o,"resourceDestination","resourceDestinationLiteral","resourceDestinationLiteralMarker","resourceDestinationRaw","resourceDestinationString",32)(n)}function u(n){return v(n)?K(e,c)(n):l(n)}function o(e){return t(e)}function c(n){return 34===n||39===n||40===n?J(e,s,t,"resourceTitle","resourceTitleMarker","resourceTitleString")(n):l(n)}function s(n){return v(n)?K(e,l)(n):l(n)}function l(r){return 41===r?(e.enter("resourceMarker"),e.consume(r),e.exit("resourceMarker"),e.exit("resource"),n):t(r)}}},Fe={tokenize:function(e,n,t){const r=this;return function(n){return G.call(r,e,i,u,"reference","referenceMarker","referenceString")(n)};function i(e){return r.parser.defined.includes(X(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)))?n(e):t(e)}function u(e){return t(e)}}},ve={tokenize:function(e,n,t){return function(n){return e.enter("reference"),e.enter("referenceMarker"),e.consume(n),e.exit("referenceMarker"),r};function r(r){return 93===r?(e.enter("referenceMarker"),e.consume(r),e.exit("referenceMarker"),e.exit("reference"),n):t(r)}}};const be={name:"labelStartImage",tokenize:function(e,n,t){const r=this;return function(n){return e.enter("labelImage"),e.enter("labelImageMarker"),e.consume(n),e.exit("labelImageMarker"),i};function i(n){return 91===n?(e.enter("labelMarker"),e.consume(n),e.exit("labelMarker"),e.exit("labelImage"),u):t(n)}function u(e){return 94===e&&"_hiddenFootnoteSupport"in r.parser.constructs?t(e):n(e)}},resolveAll:ke.resolveAll};function Se(e){return null===e||v(e)||E(e)?1:S(e)?2:void 0}const Ee={name:"attention",tokenize:function(e,n){const t=this.parser.constructs.attentionMarkers.null,r=this.previous,i=Se(r);let u;return function(n){return u=n,e.enter("attentionSequence"),o(n)};function o(c){if(c===u)return e.consume(c),o;const s=e.exit("attentionSequence"),l=Se(c),a=!l||2===l&&i||t.includes(c),f=!i||2===i&&l||t.includes(r);return s._open=Boolean(42===u?a:a&&(i||!f)),s._close=Boolean(42===u?f:f&&(l||!a)),n(c)}},resolveAll:function(e,n){let t,r,i,u,o,c,a,f,d=-1;for(;++d<e.length;)if("enter"===e[d][0]&&"attentionSequence"===e[d][1].type&&e[d][1]._close)for(t=d;t--;)if("exit"===e[t][0]&&"attentionSequence"===e[t][1].type&&e[t][1]._open&&n.sliceSerialize(e[t][1]).charCodeAt(0)===n.sliceSerialize(e[d][1]).charCodeAt(0)){if((e[t][1]._close||e[d][1]._open)&&(e[d][1].end.offset-e[d][1].start.offset)%3&&!((e[t][1].end.offset-e[t][1].start.offset+e[d][1].end.offset-e[d][1].start.offset)%3))continue;c=e[t][1].end.offset-e[t][1].start.offset>1&&e[d][1].end.offset-e[d][1].start.offset>1?2:1;const h=Object.assign({},e[t][1].end),p=Object.assign({},e[d][1].start);Ae(h,-c),Ae(p,c),u={type:c>1?"strongSequence":"emphasisSequence",start:h,end:Object.assign({},e[t][1].end)},o={type:c>1?"strongSequence":"emphasisSequence",start:Object.assign({},e[d][1].start),end:p},i={type:c>1?"strongText":"emphasisText",start:Object.assign({},e[t][1].end),end:Object.assign({},e[d][1].start)},r={type:c>1?"strong":"emphasis",start:Object.assign({},u.start),end:Object.assign({},o.end)},e[t][1].end=Object.assign({},u.start),e[d][1].start=Object.assign({},o.end),a=[],e[t][1].end.offset-e[t][1].start.offset&&(a=l(a,[["enter",e[t][1],n],["exit",e[t][1],n]])),a=l(a,[["enter",r,n],["enter",u,n],["exit",u,n],["enter",i,n]]),a=l(a,V(n.parser.constructs.insideSpan.null,e.slice(t+1,d),n)),a=l(a,[["exit",i,n],["enter",o,n],["exit",o,n],["exit",r,n]]),e[d][1].end.offset-e[d][1].start.offset?(f=2,a=l(a,[["enter",e[d][1],n],["exit",e[d][1],n]])):f=0,s(e,t-1,d-t+3,a),d=t+a.length-f-2;break}d=-1;for(;++d<e.length;)"attentionSequence"===e[d][1].type&&(e[d][1].type="data");return e}};function Ae(e,n){e.column+=n,e.offset+=n,e._bufferIndex+=n}const Ie={name:"autolink",tokenize:function(e,n,t){let r=0;return function(n){return e.enter("autolink"),e.enter("autolinkMarker"),e.consume(n),e.exit("autolinkMarker"),e.enter("autolinkProtocol"),i};function i(n){return h(n)?(e.consume(n),u):s(n)}function u(e){return 43===e||45===e||46===e||p(e)?(r=1,o(e)):s(e)}function o(n){return 58===n?(e.consume(n),r=0,c):(43===n||45===n||46===n||p(n))&&r++<32?(e.consume(n),o):(r=0,s(n))}function c(r){return 62===r?(e.exit("autolinkProtocol"),e.enter("autolinkMarker"),e.consume(r),e.exit("autolinkMarker"),e.exit("autolink"),n):null===r||32===r||60===r||g(r)?t(r):(e.consume(r),c)}function s(n){return 64===n?(e.consume(n),l):m(n)?(e.consume(n),s):t(n)}function l(e){return p(e)?a(e):t(e)}function a(t){return 46===t?(e.consume(t),r=0,l):62===t?(e.exit("autolinkProtocol").type="autolinkEmail",e.enter("autolinkMarker"),e.consume(t),e.exit("autolinkMarker"),e.exit("autolink"),n):f(t)}function f(n){if((45===n||p(n))&&r++<63){const t=45===n?f:a;return e.consume(n),t}return t(n)}}};const we={name:"htmlText",tokenize:function(e,n,t){const r=this;let i,u,o;return function(n){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(n),c};function c(n){return 33===n?(e.consume(n),s):47===n?(e.consume(n),A):63===n?(e.consume(n),S):h(n)?(e.consume(n),T):t(n)}function s(n){return 45===n?(e.consume(n),l):91===n?(e.consume(n),u=0,m):h(n)?(e.consume(n),y):t(n)}function l(n){return 45===n?(e.consume(n),d):t(n)}function a(n){return null===n?t(n):45===n?(e.consume(n),f):F(n)?(o=a,j(n)):(e.consume(n),a)}function f(n){return 45===n?(e.consume(n),d):a(n)}function d(e){return 62===e?O(e):45===e?f(e):a(e)}function m(n){const r="CDATA[";return n===r.charCodeAt(u++)?(e.consume(n),6===u?g:m):t(n)}function g(n){return null===n?t(n):93===n?(e.consume(n),x):F(n)?(o=g,j(n)):(e.consume(n),g)}function x(n){return 93===n?(e.consume(n),k):g(n)}function k(n){return 62===n?O(n):93===n?(e.consume(n),k):g(n)}function y(n){return null===n||62===n?O(n):F(n)?(o=y,j(n)):(e.consume(n),y)}function S(n){return null===n?t(n):63===n?(e.consume(n),E):F(n)?(o=S,j(n)):(e.consume(n),S)}function E(e){return 62===e?O(e):S(e)}function A(n){return h(n)?(e.consume(n),w):t(n)}function w(n){return 45===n||p(n)?(e.consume(n),w):C(n)}function C(n){return F(n)?(o=C,j(n)):b(n)?(e.consume(n),C):O(n)}function T(n){return 45===n||p(n)?(e.consume(n),T):47===n||62===n||v(n)?z(n):t(n)}function z(n){return 47===n?(e.consume(n),O):58===n||95===n||h(n)?(e.consume(n),D):F(n)?(o=z,j(n)):b(n)?(e.consume(n),z):O(n)}function D(n){return 45===n||46===n||58===n||95===n||p(n)?(e.consume(n),D):B(n)}function B(n){return 61===n?(e.consume(n),_):F(n)?(o=B,j(n)):b(n)?(e.consume(n),B):z(n)}function _(n){return null===n||60===n||61===n||62===n||96===n?t(n):34===n||39===n?(e.consume(n),i=n,M):F(n)?(o=_,j(n)):b(n)?(e.consume(n),_):(e.consume(n),L)}function M(n){return n===i?(e.consume(n),i=void 0,P):null===n?t(n):F(n)?(o=M,j(n)):(e.consume(n),M)}function L(n){return null===n||34===n||39===n||60===n||61===n||96===n?t(n):47===n||62===n||v(n)?z(n):(e.consume(n),L)}function P(e){return 47===e||62===e||v(e)?z(e):t(e)}function O(r){return 62===r?(e.consume(r),e.exit("htmlTextData"),e.exit("htmlText"),n):t(r)}function j(n){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),H}function H(n){return b(n)?I(e,R,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(n):R(n)}function R(n){return e.enter("htmlTextData"),o(n)}}};const Ce={name:"labelStartLink",tokenize:function(e,n,t){const r=this;return function(n){return e.enter("labelLink"),e.enter("labelMarker"),e.consume(n),e.exit("labelMarker"),e.exit("labelLink"),i};function i(e){return 94===e&&"_hiddenFootnoteSupport"in r.parser.constructs?t(e):n(e)}},resolveAll:ke.resolveAll};const Te={name:"hardBreakEscape",tokenize:function(e,n,t){return function(n){return e.enter("hardBreakEscape"),e.consume(n),r};function r(r){return F(r)?(e.exit("hardBreakEscape"),n(r)):t(r)}}};const ze={name:"codeText",tokenize:function(e,n,t){let r,i,u=0;return function(n){return e.enter("codeText"),e.enter("codeTextSequence"),o(n)};function o(n){return 96===n?(e.consume(n),u++,o):(e.exit("codeTextSequence"),c(n))}function c(n){return null===n?t(n):32===n?(e.enter("space"),e.consume(n),e.exit("space"),c):96===n?(i=e.enter("codeTextSequence"),r=0,l(n)):F(n)?(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),c):(e.enter("codeTextData"),s(n))}function s(n){return null===n||32===n||96===n||F(n)?(e.exit("codeTextData"),c(n)):(e.consume(n),s)}function l(t){return 96===t?(e.consume(t),r++,l):r===u?(e.exit("codeTextSequence"),e.exit("codeText"),n(t)):(i.type="codeTextData",s(t))}},resolve:function(e){let n,t,r=e.length-4,i=3;if(!("lineEnding"!==e[i][1].type&&"space"!==e[i][1].type||"lineEnding"!==e[r][1].type&&"space"!==e[r][1].type))for(n=i;++n<r;)if("codeTextData"===e[n][1].type){e[i][1].type="codeTextPadding",e[r][1].type="codeTextPadding",i+=2,r-=2;break}n=i-1,r++;for(;++n<=r;)void 0===t?n!==r&&"lineEnding"!==e[n][1].type&&(t=n):n!==r&&"lineEnding"!==e[n][1].type||(e[t][1].type="codeTextData",n!==t+2&&(e[t][1].end=e[n-1][1].end,e.splice(t+2,n-t-2),r-=n-t-2,n=t+2),t=void 0);return e},previous:function(e){return 96!==e||"characterEscape"===this.events[this.events.length-1][1].type}};const De={42:U,43:U,45:U,48:U,49:U,50:U,51:U,52:U,53:U,54:U,55:U,56:U,57:U,62:Z},Be={91:ee},_e={[-2]:te,[-1]:te,32:te},Me={35:ie,42:N,45:[ue,N],60:se,61:ue,95:N,96:de,126:de},Le={38:me,92:ge},Pe={[-5]:xe,[-4]:xe,[-3]:xe,33:be,38:me,42:Ee,60:[Ie,we],91:Ce,92:[Te,ge],93:ke,95:Ee,96:ze},Oe={null:[Ee,P]},je={null:[42,95]},He={null:[]};function Re(e){const n=function(e){const n={};let t=-1;for(;++t<e.length;)f(n,e[t]);return n}([r,...(e||{}).extensions||[]]),t={defined:[],lazy:{},constructs:n,content:i(w),document:i(C),flow:i(L),string:i(O),text:i(j)};return t;function i(e){return function(n){return Q(t,e,n)}}}const qe=/[\0\t\n\r]/g;function Ve(e,n){const t=Number.parseInt(e,n);return t<9||11===t||t>13&&t<32||t>126&&t<160||t>55295&&t<57344||t>64975&&t<65008||!(65535&~t)||65534==(65535&t)||t>1114111?"\ufffd":String.fromCharCode(t)}const Qe=/\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi;function Ne(e,n,t){if(n)return n;if(35===t.charCodeAt(0)){const e=t.charCodeAt(1),n=120===e||88===e;return Ve(t.slice(n?2:1),n?16:10)}return pe(t)||e}function Ue(e){return e&&"object"==typeof e?"position"in e||"type"in e?We(e.position):"start"in e||"end"in e?We(e):"line"in e||"column"in e?$e(e):"":""}function $e(e){return Ze(e&&e.line)+":"+Ze(e&&e.column)}function We(e){return $e(e&&e.start)+"-"+$e(e&&e.end)}function Ze(e){return e&&"number"==typeof e?e:1}const Ye={}.hasOwnProperty,Ge=function(e,n,t){return"string"!=typeof n&&(t=n,n=void 0),function(e){const n={transforms:[],canContainEols:["emphasis","fragment","heading","paragraph","strong"],enter:{autolink:l(ue),autolinkProtocol:T,autolinkEmail:T,atxHeading:l(ne),blockQuote:l(Y),characterEscape:T,characterReference:T,codeFenced:l(G),codeFencedFenceInfo:a,codeFencedFenceMeta:a,codeIndented:l(G,a),codeText:l(J,a),codeTextData:T,data:T,codeFlowValue:T,definition:l(K),definitionDestinationString:a,definitionLabelString:a,definitionTitleString:a,emphasis:l(ee),hardBreakEscape:l(te),hardBreakTrailing:l(te),htmlFlow:l(re,a),htmlFlowData:T,htmlText:l(re,a),htmlTextData:T,image:l(ie),label:a,link:l(ue),listItem:l(ce),listItemValue:g,listOrdered:l(oe,m),listUnordered:l(oe),paragraph:l(se),reference:Q,referenceString:a,resourceDestinationString:a,resourceTitleString:a,setextHeading:l(ne),strong:l(le),thematicBreak:l(fe)},exit:{atxHeading:d(),atxHeadingSequence:A,autolink:d(),autolinkEmail:Z,autolinkProtocol:W,blockQuote:d(),characterEscapeValue:z,characterReferenceMarkerHexadecimal:U,characterReferenceMarkerNumeric:U,characterReferenceValue:$,codeFenced:d(F),codeFencedFence:y,codeFencedFenceInfo:x,codeFencedFenceMeta:k,codeFlowValue:z,codeIndented:d(v),codeText:d(L),codeTextData:z,data:z,definition:d(),definitionDestinationString:E,definitionLabelString:b,definitionTitleString:S,emphasis:d(),hardBreakEscape:d(B),hardBreakTrailing:d(B),htmlFlow:d(_),htmlFlowData:z,htmlText:d(M),htmlTextData:z,image:d(O),label:H,labelText:j,lineEnding:D,link:d(P),listItem:d(),listOrdered:d(),listUnordered:d(),paragraph:d(),referenceString:N,resourceDestinationString:R,resourceTitleString:q,resource:V,setextHeading:d(C),setextHeadingLineSequence:w,setextHeadingText:I,strong:d(),thematicBreak:d()}};Ke(n,(e||{}).mdastExtensions||[]);const t={};return r;function r(e){let t={type:"root",children:[]};const r={stack:[t],tokenStack:[],config:n,enter:f,exit:h,buffer:a,resume:p,setData:c,getData:s},u=[];let o=-1;for(;++o<e.length;)if("listOrdered"===e[o][1].type||"listUnordered"===e[o][1].type)if("enter"===e[o][0])u.push(o);else{o=i(e,u.pop(),o)}for(o=-1;++o<e.length;){const t=n[e[o][0]];Ye.call(t,e[o][1].type)&&t[e[o][1].type].call(Object.assign({sliceSerialize:e[o][2].sliceSerialize},r),e[o][1])}if(r.tokenStack.length>0){const e=r.tokenStack[r.tokenStack.length-1];(e[1]||en).call(r,void 0,e[0])}for(t.position={start:Je(e.length>0?e[0][1].start:{line:1,column:1,offset:0}),end:Je(e.length>0?e[e.length-2][1].end:{line:1,column:1,offset:0})},o=-1;++o<n.transforms.length;)t=n.transforms[o](t)||t;return t}function i(e,n,t){let r,i,u,o,c=n-1,s=-1,l=!1;for(;++c<=t;){const n=e[c];if("listUnordered"===n[1].type||"listOrdered"===n[1].type||"blockQuote"===n[1].type?("enter"===n[0]?s++:s--,o=void 0):"lineEndingBlank"===n[1].type?"enter"===n[0]&&(!r||o||s||u||(u=c),o=void 0):"linePrefix"===n[1].type||"listItemValue"===n[1].type||"listItemMarker"===n[1].type||"listItemPrefix"===n[1].type||"listItemPrefixWhitespace"===n[1].type||(o=void 0),!s&&"enter"===n[0]&&"listItemPrefix"===n[1].type||-1===s&&"exit"===n[0]&&("listUnordered"===n[1].type||"listOrdered"===n[1].type)){if(r){let o=c;for(i=void 0;o--;){const n=e[o];if("lineEnding"===n[1].type||"lineEndingBlank"===n[1].type){if("exit"===n[0])continue;i&&(e[i][1].type="lineEndingBlank",l=!0),n[1].type="lineEnding",i=o}else if("linePrefix"!==n[1].type&&"blockQuotePrefix"!==n[1].type&&"blockQuotePrefixWhitespace"!==n[1].type&&"blockQuoteMarker"!==n[1].type&&"listItemIndent"!==n[1].type)break}u&&(!i||u<i)&&(r._spread=!0),r.end=Object.assign({},i?e[i][1].start:n[1].end),e.splice(i||c,0,["exit",r,n[2]]),c++,t++}"listItemPrefix"===n[1].type&&(r={type:"listItem",_spread:!1,start:Object.assign({},n[1].start),end:void 0},e.splice(c,0,["enter",r,n[2]]),c++,t++,u=void 0,o=!0)}}return e[n][1]._spread=l,t}function c(e,n){t[e]=n}function s(e){return t[e]}function l(e,n){return t;function t(t){f.call(this,e(t),t),n&&n.call(this,t)}}function a(){this.stack.push({type:"fragment",children:[]})}function f(e,n,t){return this.stack[this.stack.length-1].children.push(e),this.stack.push(e),this.tokenStack.push([n,t]),e.position={start:Je(n.start)},e}function d(e){return n;function n(n){e&&e.call(this,n),h.call(this,n)}}function h(e,n){const t=this.stack.pop(),r=this.tokenStack.pop();if(!r)throw new Error("Cannot close `"+e.type+"` ("+Ue({start:e.start,end:e.end})+"): it\u2019s not open");if(r[0].type!==e.type)if(n)n.call(this,e,r[0]);else{(r[1]||en).call(this,e,r[0])}return t.position.end=Je(e.end),t}function p(){return function(e,n){const t=n||u;return o(e,"boolean"!=typeof t.includeImageAlt||t.includeImageAlt,"boolean"!=typeof t.includeHtml||t.includeHtml)}(this.stack.pop())}function m(){c("expectingFirstListItemValue",!0)}function g(e){if(s("expectingFirstListItemValue")){this.stack[this.stack.length-2].start=Number.parseInt(this.sliceSerialize(e),10),c("expectingFirstListItemValue")}}function x(){const e=this.resume();this.stack[this.stack.length-1].lang=e}function k(){const e=this.resume();this.stack[this.stack.length-1].meta=e}function y(){s("flowCodeInside")||(this.buffer(),c("flowCodeInside",!0))}function F(){const e=this.resume();this.stack[this.stack.length-1].value=e.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g,""),c("flowCodeInside")}function v(){const e=this.resume();this.stack[this.stack.length-1].value=e.replace(/(\r?\n|\r)$/g,"")}function b(e){const n=this.resume(),t=this.stack[this.stack.length-1];t.label=n,t.identifier=X(this.sliceSerialize(e)).toLowerCase()}function S(){const e=this.resume();this.stack[this.stack.length-1].title=e}function E(){const e=this.resume();this.stack[this.stack.length-1].url=e}function A(e){const n=this.stack[this.stack.length-1];if(!n.depth){const t=this.sliceSerialize(e).length;n.depth=t}}function I(){c("setextHeadingSlurpLineEnding",!0)}function w(e){this.stack[this.stack.length-1].depth=61===this.sliceSerialize(e).charCodeAt(0)?1:2}function C(){c("setextHeadingSlurpLineEnding")}function T(e){const n=this.stack[this.stack.length-1];let t=n.children[n.children.length-1];t&&"text"===t.type||(t=ae(),t.position={start:Je(e.start)},n.children.push(t)),this.stack.push(t)}function z(e){const n=this.stack.pop();n.value+=this.sliceSerialize(e),n.position.end=Je(e.end)}function D(e){const t=this.stack[this.stack.length-1];if(s("atHardBreak")){return t.children[t.children.length-1].position.end=Je(e.end),void c("atHardBreak")}!s("setextHeadingSlurpLineEnding")&&n.canContainEols.includes(t.type)&&(T.call(this,e),z.call(this,e))}function B(){c("atHardBreak",!0)}function _(){const e=this.resume();this.stack[this.stack.length-1].value=e}function M(){const e=this.resume();this.stack[this.stack.length-1].value=e}function L(){const e=this.resume();this.stack[this.stack.length-1].value=e}function P(){const e=this.stack[this.stack.length-1];if(s("inReference")){const n=s("referenceType")||"shortcut";e.type+="Reference",e.referenceType=n,delete e.url,delete e.title}else delete e.identifier,delete e.label;c("referenceType")}function O(){const e=this.stack[this.stack.length-1];if(s("inReference")){const n=s("referenceType")||"shortcut";e.type+="Reference",e.referenceType=n,delete e.url,delete e.title}else delete e.identifier,delete e.label;c("referenceType")}function j(e){const n=this.sliceSerialize(e),t=this.stack[this.stack.length-2];t.label=function(e){return e.replace(Qe,Ne)}(n),t.identifier=X(n).toLowerCase()}function H(){const e=this.stack[this.stack.length-1],n=this.resume(),t=this.stack[this.stack.length-1];if(c("inReference",!0),"link"===t.type){const n=e.children;t.children=n}else t.alt=n}function R(){const e=this.resume();this.stack[this.stack.length-1].url=e}function q(){const e=this.resume();this.stack[this.stack.length-1].title=e}function V(){c("inReference")}function Q(){c("referenceType","collapsed")}function N(e){const n=this.resume(),t=this.stack[this.stack.length-1];t.label=n,t.identifier=X(this.sliceSerialize(e)).toLowerCase(),c("referenceType","full")}function U(e){c("characterReferenceType",e.type)}function $(e){const n=this.sliceSerialize(e),t=s("characterReferenceType");let r;if(t)r=Ve(n,"characterReferenceMarkerNumeric"===t?10:16),c("characterReferenceType");else{r=pe(n)}const i=this.stack.pop();i.value+=r,i.position.end=Je(e.end)}function W(e){z.call(this,e);this.stack[this.stack.length-1].url=this.sliceSerialize(e)}function Z(e){z.call(this,e);this.stack[this.stack.length-1].url="mailto:"+this.sliceSerialize(e)}function Y(){return{type:"blockquote",children:[]}}function G(){return{type:"code",lang:null,meta:null,value:""}}function J(){return{type:"inlineCode",value:""}}function K(){return{type:"definition",identifier:"",label:null,title:null,url:""}}function ee(){return{type:"emphasis",children:[]}}function ne(){return{type:"heading",depth:void 0,children:[]}}function te(){return{type:"break"}}function re(){return{type:"html",value:""}}function ie(){return{type:"image",title:null,url:"",alt:null}}function ue(){return{type:"link",title:null,url:"",children:[]}}function oe(e){return{type:"list",ordered:"listOrdered"===e.type,start:null,spread:e._spread,children:[]}}function ce(e){return{type:"listItem",spread:e._spread,checked:null,children:[]}}function se(){return{type:"paragraph",children:[]}}function le(){return{type:"strong",children:[]}}function ae(){return{type:"text",value:""}}function fe(){return{type:"thematicBreak"}}}(t)(function(e){for(;!D(e););return e}(Re(t).document().write(function(){let e,n=1,t="",r=!0;return function(i,u,o){const c=[];let s,l,a,f,d;for(i=t+i.toString(u),a=0,t="",r&&(65279===i.charCodeAt(0)&&a++,r=void 0);a<i.length;){if(qe.lastIndex=a,s=qe.exec(i),f=s&&void 0!==s.index?s.index:i.length,d=i.charCodeAt(f),!s){t=i.slice(a);break}if(10===d&&a===f&&e)c.push(-3),e=void 0;else switch(e&&(c.push(-5),e=void 0),a<f&&(c.push(i.slice(a,f)),n+=f-a),d){case 0:c.push(65533),n++;break;case 9:for(l=4*Math.ceil(n/4),c.push(-2);n++<l;)c.push(-1);break;case 10:c.push(-4),n=1;break;default:e=!0,n=1}a=f+1}return o&&(e&&c.push(-5),t&&c.push(t),c.push(null)),c}}()(e,n,!0))))};function Je(e){return{line:e.line,column:e.column,offset:e.offset}}function Ke(e,n){let t=-1;for(;++t<n.length;){const r=n[t];Array.isArray(r)?Ke(e,r):Xe(e,r)}}function Xe(e,n){let t;for(t in n)if(Ye.call(n,t))if("canContainEols"===t){const r=n[t];r&&e[t].push(...r)}else if("transforms"===t){const r=n[t];r&&e[t].push(...r)}else if("enter"===t||"exit"===t){const r=n[t];r&&Object.assign(e[t],r)}}function en(e,n){throw e?new Error("Cannot close `"+e.type+"` ("+Ue({start:e.start,end:e.end})+"): a different token (`"+n.type+"`, "+Ue({start:n.start,end:n.end})+") is open"):new Error("Cannot close document, a token (`"+n.type+"`, "+Ue({start:n.start,end:n.end})+") is still open")}var nn=t(60513);function tn(e){const n=function(e){const n=e.replace(/\n{2,}/g,"\n");return(0,nn.T)(n)}(e),{children:t}=Ge(n),r=[[]];let i=0;function u(e,n="normal"){if("text"===e.type){e.value.split("\n").forEach(((e,t)=>{0!==t&&(i++,r.push([])),e.split(" ").forEach((e=>{e&&r[i].push({content:e,type:n})}))}))}else"strong"!==e.type&&"emphasis"!==e.type||e.children.forEach((n=>{u(n,e.type)}))}return t.forEach((e=>{"paragraph"===e.type&&e.children.forEach((e=>{u(e)}))})),r}function rn(e,n){var t;return un(e,[],(t=n.content,Intl.Segmenter?[...(new Intl.Segmenter).segment(t)].map((e=>e.segment)):[...t]),n.type)}function un(e,n,t,r){if(0===t.length)return[{content:n.join(""),type:r},{content:"",type:r}];const[i,...u]=t,o=[...n,i];return e([{content:o.join(""),type:r}])?un(e,o,u,r):(0===n.length&&i&&(n.push(i),t.shift()),[{content:n.join(""),type:r},{content:t.join(""),type:r}])}function on(e,n){if(e.some((({content:e})=>e.includes("\n"))))throw new Error("splitLineToFitWidth does not support newlines in the line");return cn(e,n)}function cn(e,n,t=[],r=[]){if(0===e.length)return r.length>0&&t.push(r),t.length>0?t:[];let i="";" "===e[0].content&&(i=" ",e.shift());const u=e.shift()??{content:" ",type:"normal"},o=[...r];if(""!==i&&o.push({content:i,type:"normal"}),o.push(u),n(o))return cn(e,n,t,o);if(r.length>0)t.push(r),e.unshift(u);else if(u.content){const[r,i]=rn(n,u);t.push([r]),i.content&&e.unshift(i)}return cn(e,n,t)}function sn(e,n,t){return e.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",n*t-.1+"em").attr("dy",t+"em")}function ln(e,n,t){const r=e.append("text"),i=sn(r,1,n);fn(i,t);const u=i.node().getComputedTextLength();return r.remove(),u}function an(e,n,t){var r;const i=e.append("text"),u=sn(i,1,n);fn(u,[{content:t,type:"normal"}]);const o=null==(r=u.node())?void 0:r.getBoundingClientRect();return o&&i.remove(),o}function fn(e,n){e.text(""),n.forEach(((n,t)=>{const r=e.append("tspan").attr("font-style","emphasis"===n.type?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight","strong"===n.type?"bold":"normal");0===t?r.text(n.content):r.text(" "+n.content)}))}const dn=(e,n="",{style:t="",isTitle:r=!1,classes:u="",useHtmlLabels:o=!0,isNode:c=!0,width:s=200,addSvgBackground:l=!1}={})=>{if(i.l.info("createText",n,t,r,u,o,c,l),o){const r=function(e){const{children:n}=Ge(e);return n.map((function e(n){return"text"===n.type?n.value.replace(/\n/g,"<br/>"):"strong"===n.type?`<strong>${n.children.map(e).join("")}</strong>`:"emphasis"===n.type?`<em>${n.children.map(e).join("")}</em>`:"paragraph"===n.type?`<p>${n.children.map(e).join("")}</p>`:`Unsupported markdown: ${n.type}`})).join("")}(n),o=function(e,n,t,r,i=!1){const u=e.append("foreignObject"),o=u.append("xhtml:div"),c=n.label,s=n.isNode?"nodeLabel":"edgeLabel";var l,a;o.html(`\n <span class="${s} ${r}" `+(n.labelStyle?'style="'+n.labelStyle+'"':"")+">"+c+"</span>"),l=o,(a=n.labelStyle)&&l.attr("style",a),o.style("display","table-cell"),o.style("white-space","nowrap"),o.style("max-width",t+"px"),o.attr("xmlns","http://www.w3.org/1999/xhtml"),i&&o.attr("class","labelBkg");let f=o.node().getBoundingClientRect();return f.width===t&&(o.style("display","table"),o.style("white-space","break-spaces"),o.style("width",t+"px"),f=o.node().getBoundingClientRect()),u.style("width",f.width),u.style("height",f.height),u.node()}(e,{isNode:c,label:(0,i.M)(r).replace(/fa[blrs]?:fa-[\w-]+/g,(e=>`<i class='${e.replace(":"," ")}'></i>`)),labelStyle:t.replace("fill:","color:")},s,u,l);return o}{const t=function(e,n,t,r=!1){const i=n.append("g"),u=i.insert("rect").attr("class","background"),o=i.append("text").attr("y","-10.1");let c=0;for(const s of t){const n=n=>ln(i,1.1,n)<=e,t=n(s)?[s]:on(s,n);for(const e of t)fn(sn(o,c,1.1),e),c++}if(r){const e=o.node().getBBox(),n=2;return u.attr("x",-n).attr("y",-n).attr("width",e.width+2*n).attr("height",e.height+2*n),i.node()}return o.node()}(s,e,tn(n),l);return t}}}}]); \ No newline at end of file diff --git a/assets/js/5830dd0a.4ff1620e.js b/assets/js/5830dd0a.4ff1620e.js new file mode 100644 index 0000000000..ae24f9f82f --- /dev/null +++ b/assets/js/5830dd0a.4ff1620e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9176],{70589:(s,d,e)=>{e.r(d),e.d(d,{assets:()=>a,contentTitle:()=>i,default:()=>x,frontMatter:()=>t,metadata:()=>c,toc:()=>h});var r=e(74848),n=e(28453);const t={},i="Overview",c={id:"standards/overview",title:"Overview",description:"Standards are the core deliverable of SCS. By standardizing the open source software components of a cloud computing stack, their versions, how they are to be configured, deployed and utilized, SCS guarantees the reproducibility of a certain behavior of this technology.",source:"@site/standards/standards/overview.md",sourceDirName:"standards",slug:"/standards/overview",permalink:"/standards/standards/overview",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"SCS Compatible KaaS",permalink:"/standards/scs-compatible-kaas"},next:{title:"Global Standards",permalink:"/standards/global/"}},a={},h=[];function l(s){const d={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...s.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(d.h1,{id:"overview",children:"Overview"}),"\n",(0,r.jsx)(d.p,{children:"Standards are the core deliverable of SCS. By standardizing the open source software components of a cloud computing stack, their versions, how they are to be configured, deployed and utilized, SCS guarantees the reproducibility of a certain behavior of this technology."}),"\n",(0,r.jsx)(d.p,{children:"SCS standards are discussed, developed and maintained in the community by the corresponding teams (see Track in the table below), which naturally include existing users of SCS."}),"\n",(0,r.jsx)(d.p,{children:"*Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective)."}),"\n",(0,r.jsxs)(d.table,{children:[(0,r.jsx)(d.thead,{children:(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.th,{children:"Standard"}),(0,r.jsx)(d.th,{children:"Track"}),(0,r.jsx)(d.th,{children:"Description"}),(0,r.jsx)(d.th,{children:"Draft"}),(0,r.jsx)(d.th,{children:"Stable*"}),(0,r.jsx)(d.th,{children:"Effective"}),(0,r.jsx)(d.th,{children:"Deprecated*"})]})}),(0,r.jsxs)(d.tbody,{children:[(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/global/scs-0001",children:"scs-0001"})}),(0,r.jsx)(d.td,{children:"Global"}),(0,r.jsx)(d.td,{children:"Sovereign Cloud Standards"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0001-v1-sovereign-cloud-standards",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/global/scs-0002",children:"scs-0002"})}),(0,r.jsx)(d.td,{children:"Global"}),(0,r.jsx)(d.td,{children:"Standards, Docs and Organisation"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0002-v2-standards-docs-org",children:"v2"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0002-v1-standards-docs-org",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/global/scs-0003",children:"scs-0003"})}),(0,r.jsx)(d.td,{children:"Global"}),(0,r.jsx)(d.td,{children:"Sovereign Cloud Standards YAML"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/global/scs-0004",children:"scs-0004"})}),(0,r.jsx)(d.td,{children:"Global"}),(0,r.jsx)(d.td,{children:"Regulations for achieving SCS-compatible certification"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0004-v1-achieving-certification",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/global/scs-0112",children:"scs-0112"})}),(0,r.jsx)(d.td,{children:"Global"}),(0,r.jsx)(d.td,{children:"SONiC Support in SCS"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0112-v1-sonic",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iaas/scs-0100",children:"scs-0100"})}),(0,r.jsx)(d.td,{children:"IaaS"}),(0,r.jsx)(d.td,{children:"SCS Flavor Naming Standard"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"v3"})}),(0,r.jsxs)(d.td,{children:[(0,r.jsx)(d.a,{href:"/standards/scs-0100-v1-flavor-naming",children:"v1"}),", ",(0,r.jsx)(d.a,{href:"/standards/scs-0100-v2-flavor-naming",children:"v2"})]})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{}),(0,r.jsx)(d.td,{}),(0,r.jsx)(d.td,{children:"Supplement: Implementation and Testing Notes"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0100-w1-flavor-naming-implementation-testing",children:"w1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iaas/scs-0101",children:"scs-0101"})}),(0,r.jsx)(d.td,{children:"IaaS"}),(0,r.jsx)(d.td,{children:"SCS Entropy"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0101-v1-entropy",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{}),(0,r.jsx)(d.td,{}),(0,r.jsx)(d.td,{children:"Supplement: Implementation and Testing Notes"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0101-w1-entropy-implementation-testing",children:"w1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iaas/scs-0102",children:"scs-0102"})}),(0,r.jsx)(d.td,{children:"IaaS"}),(0,r.jsx)(d.td,{children:"SCS Image Metadata Standard"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0102-v1-image-metadata",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iaas/scs-0103",children:"scs-0103"})}),(0,r.jsx)(d.td,{children:"IaaS"}),(0,r.jsx)(d.td,{children:"SCS Standard Flavors and Properties"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0103-v1-standard-flavors",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iaas/scs-0104",children:"scs-0104"})}),(0,r.jsx)(d.td,{children:"IaaS"}),(0,r.jsx)(d.td,{children:"SCS Standard Images"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0104-v1-standard-images",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iaas/scs-0110",children:"scs-0110"})}),(0,r.jsx)(d.td,{children:"IaaS"}),(0,r.jsx)(d.td,{children:"SSD Flavors"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0110-v1-ssd-flavors",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iaas/scs-0111",children:"scs-0111"})}),(0,r.jsx)(d.td,{children:"IaaS"}),(0,r.jsx)(d.td,{children:"Decisions for the Volume Type Standard"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0111-v1-volume-type-decisions",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iaas/scs-0113",children:"scs-0113"})}),(0,r.jsx)(d.td,{children:"IaaS"}),(0,r.jsx)(d.td,{children:"Security Groups Decision Record"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0113-v1-security-groups-decision-record",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iaas/scs-0114",children:"scs-0114"})}),(0,r.jsx)(d.td,{children:"IaaS"}),(0,r.jsx)(d.td,{children:"Volume Type Standard"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0114-v1-volume-type-standard",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iaas/scs-0115",children:"scs-0115"})}),(0,r.jsx)(d.td,{children:"IaaS"}),(0,r.jsx)(d.td,{children:"Default Rules for Security Groups"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0115-v1-default-rules-for-security-groups",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/kaas/scs-0200",children:"scs-0200"})}),(0,r.jsx)(d.td,{children:"KaaS"}),(0,r.jsx)(d.td,{children:"Using Sonobuoy for KaaS conformance tests"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/kaas/scs-0210",children:"scs-0210"})}),(0,r.jsx)(d.td,{children:"KaaS"}),(0,r.jsx)(d.td,{children:"SCS K8S Version Policy"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0210-v2-k8s-version-policy",children:"v2"})}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0210-v1-k8s-new-version-policy",children:"v1"})})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/kaas/scs-0211",children:"scs-0211"})}),(0,r.jsx)(d.td,{children:"KaaS"}),(0,r.jsx)(d.td,{children:"SCS KaaS default storage class"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0211-v1-kaas-default-storage-class",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/kaas/scs-0212",children:"scs-0212"})}),(0,r.jsx)(d.td,{children:"KaaS"}),(0,r.jsx)(d.td,{children:"Requirements for container registries"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0212-v1-requirements-for-container-registries",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/kaas/scs-0213",children:"scs-0213"})}),(0,r.jsx)(d.td,{children:"KaaS"}),(0,r.jsx)(d.td,{children:"Kubernetes Nodes Anti Affinity"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0213-v1-k8s-nodes-anti-affinity",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/kaas/scs-0214",children:"scs-0214"})}),(0,r.jsx)(d.td,{children:"KaaS"}),(0,r.jsx)(d.td,{children:"Kubernetes Node Distribution and Availability"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0214-v1-k8s-node-distribution",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/kaas/scs-0215",children:"scs-0215"})}),(0,r.jsx)(d.td,{children:"KaaS"}),(0,r.jsx)(d.td,{children:"Robustness features for Kubernetes clusters"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0215-v1-robustness-features",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/kaas/scs-0216",children:"scs-0216"})}),(0,r.jsx)(d.td,{children:"KaaS"}),(0,r.jsx)(d.td,{children:"Requirements for testing cluster-stacks"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/kaas/scs-0217",children:"scs-0217"})}),(0,r.jsx)(d.td,{children:"KaaS"}),(0,r.jsx)(d.td,{children:"Kubernetes cluster baseline security"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0217-v1-baseline-cluster-security",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/kaas/scs-0218",children:"scs-0218"})}),(0,r.jsx)(d.td,{children:"KaaS"}),(0,r.jsx)(d.td,{children:"Container registry for SCS standard implementation"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iam/scs-0300",children:"scs-0300"})}),(0,r.jsx)(d.td,{children:"IAM"}),(0,r.jsx)(d.td,{children:"Requirements for SSO identity federation"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0300-v1-requirements-for-sso-identity-federation",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iam/scs-0301",children:"scs-0301"})}),(0,r.jsx)(d.td,{children:"IAM"}),(0,r.jsx)(d.td,{children:"Naming for domains/groups/roles/project when onboarding new customers"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0301-v1-naming-conventions",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/iam/scs-0302",children:"scs-0302"})}),(0,r.jsx)(d.td,{children:"IAM"}),(0,r.jsx)(d.td,{children:"Domain Manager configuration for Keystone"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0302-v1-domain-manager-role",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/ops/scs-0400",children:"scs-0400"})}),(0,r.jsx)(d.td,{children:"Ops"}),(0,r.jsx)(d.td,{children:"Status Page create decision"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0400-v1-status-page-create-decision",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/ops/scs-0401",children:"scs-0401"})}),(0,r.jsx)(d.td,{children:"Ops"}),(0,r.jsx)(d.td,{children:"Status page reference implementation decision"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0401-v1-status-page-reference-implementation-decision",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/ops/scs-0402",children:"scs-0402"})}),(0,r.jsx)(d.td,{children:"Ops"}),(0,r.jsx)(d.td,{children:"Status page OpenAPI decision"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0402-v1-status-page-openapi-spec-decision",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/ops/scs-0403",children:"scs-0403"})}),(0,r.jsx)(d.td,{children:"Ops"}),(0,r.jsx)(d.td,{children:"Architecture for the Cloud Service provider Observability System for the KaaS Layer"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0403-v1-csp-kaas-observability-stack",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/ops/scs-0410",children:"scs-0410"})}),(0,r.jsx)(d.td,{children:"Ops"}),(0,r.jsx)(d.td,{children:"Gnocchi as database for metering"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0410-v1-gnocchi-as-metering-database",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/ops/scs-0411",children:"scs-0411"})}),(0,r.jsx)(d.td,{children:"Ops"}),(0,r.jsx)(d.td,{children:"Push-based approach for providing usage data"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0411-v1-publishing_method_for_metering_data",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]}),(0,r.jsxs)(d.tr,{children:[(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/ops/scs-0412",children:"scs-0412"})}),(0,r.jsx)(d.td,{children:"Ops"}),(0,r.jsx)(d.td,{children:"Exposition of IaaS metering data as JSON"}),(0,r.jsx)(d.td,{children:(0,r.jsx)(d.a,{href:"/standards/scs-0412-v1-metering-json",children:"v1"})}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"}),(0,r.jsx)(d.td,{children:"-"})]})]})]})]})}function x(s={}){const{wrapper:d}={...(0,n.R)(),...s.components};return d?(0,r.jsx)(d,{...s,children:(0,r.jsx)(l,{...s})}):l(s)}},28453:(s,d,e)=>{e.d(d,{R:()=>i,x:()=>c});var r=e(96540);const n={},t=r.createContext(n);function i(s){const d=r.useContext(t);return r.useMemo((function(){return"function"==typeof s?s(d):{...d,...s}}),[d,s])}function c(s){let d;return d=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:i(s.components),r.createElement(t.Provider,{value:d},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/589280f5.20dd2887.js b/assets/js/589280f5.20dd2887.js new file mode 100644 index 0000000000..cc08cff0ed --- /dev/null +++ b/assets/js/589280f5.20dd2887.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3530],{21435:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(74848),i=n(28453);const o={sidebar_label:"Infrastructure",sidebar_position:10},t="Infrastructure",c={id:"iaas/guides/deploy-guide/services/infrastructure",title:"Infrastructure",description:"Common issues with deploying infrastructure services required by OpenStack",source:"@site/docs/02-iaas/guides/deploy-guide/services/infrastructure.md",sourceDirName:"02-iaas/guides/deploy-guide/services",slug:"/iaas/guides/deploy-guide/services/infrastructure",permalink:"/docs/iaas/guides/deploy-guide/services/infrastructure",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/infrastructure.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Infrastructure",sidebar_position:10},sidebar:"docs",previous:{title:"Services",permalink:"/docs/iaas/guides/deploy-guide/services/"},next:{title:"Kubernetes",permalink:"/docs/iaas/guides/deploy-guide/services/kubernetes"}},d={},l=[];function a(e){const s={a:"a",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h1,{id:"infrastructure",children:"Infrastructure"}),"\n",(0,r.jsxs)(s.p,{children:["Common issues with deploying infrastructure services required by OpenStack\nare documented in the ",(0,r.jsx)(s.a,{href:"../../troubleshooting-guide/openstack",children:"OpenStack Troubleshooting Guide"}),"."]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Cron, Fluentd & Kolla Toolbox"}),"\n",(0,r.jsxs)(s.p,{children:["The common role of Kolla is used to manage the services ",(0,r.jsx)(s.code,{children:"cron"}),", ",(0,r.jsx)(s.code,{children:"fluentd"}),"\nand ",(0,r.jsx)(s.code,{children:"kolla-toolbox"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["It is important to do this deployment before any other deployements in the Kolla\nenvironment, as parts of the other deployments depend on the ",(0,r.jsx)(s.code,{children:"kolla-toolbox"}),"\nservice."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"osism apply -a pull common\nosism apply common\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Loadbalancer"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"osism apply -a pull loadbalancer\nosism apply loadbalancer\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Redis"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"osism apply -a pull redis\nosism apply redis\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Memcached"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"osism apply -a pull memcached\nosism apply memcached\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"RabbitMQ"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"osism apply -a pull rabbitmq\nosism apply rabbitmq\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"MariaDB"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"osism apply -a pull mariadb\nosism apply mariadb\n"})}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>c});var r=n(96540);const i={},o=r.createContext(i);function t(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/59307471.5752c851.js b/assets/js/59307471.5752c851.js new file mode 100644 index 0000000000..bce16a61a6 --- /dev/null +++ b/assets/js/59307471.5752c851.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2637],{77378:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>n,metadata:()=>c,toc:()=>i});var a=t(74848),r=t(28453);const n={},d="scs-0211: SCS KaaS default storage class",c={id:"kaas/scs-0211",title:"scs-0211: SCS KaaS default storage class",description:"The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).",source:"@site/standards/kaas/scs-0211.md",sourceDirName:"kaas",slug:"/kaas/scs-0211",permalink:"/standards/kaas/scs-0211",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"SCS K8S Version Policy",permalink:"/standards/scs-0210-v2-k8s-version-policy"},next:{title:"SCS KaaS default storage class",permalink:"/standards/scs-0211-v1-kaas-default-storage-class"}},o={},i=[];function l(e){const s={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(s.h1,{id:"scs-0211-scs-kaas-default-storage-class",children:"scs-0211: SCS KaaS default storage class"}),"\n",(0,a.jsx)(s.p,{children:'The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS).\nThe standard ensures that the default StorageClass, identified by the "storageclass.kubernetes.io/is-default-class"\nannotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or\nhost hardware failures.'}),"\n",(0,a.jsxs)(s.table,{children:[(0,a.jsx)(s.thead,{children:(0,a.jsxs)(s.tr,{children:[(0,a.jsx)(s.th,{children:"Version"}),(0,a.jsx)(s.th,{children:"Type"}),(0,a.jsx)(s.th,{children:"State"}),(0,a.jsx)(s.th,{children:"stabilized"}),(0,a.jsx)(s.th,{children:"deprecated"})]})}),(0,a.jsx)(s.tbody,{children:(0,a.jsxs)(s.tr,{children:[(0,a.jsx)(s.td,{children:(0,a.jsx)(s.a,{href:"/standards/scs-0211-v1-kaas-default-storage-class",children:"scs-0211-v1"})}),(0,a.jsx)(s.td,{children:"Standard"}),(0,a.jsx)(s.td,{children:"Stable"}),(0,a.jsx)(s.td,{children:"2023-02-13"}),(0,a.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,a.jsx)(s,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>d,x:()=>c});var a=t(96540);const r={},n=a.createContext(r);function d(e){const s=a.useContext(n);return a.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),a.createElement(n.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5abd544f.66cd3a76.js b/assets/js/5abd544f.66cd3a76.js new file mode 100644 index 0000000000..1932896e28 --- /dev/null +++ b/assets/js/5abd544f.66cd3a76.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9441],{67161:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>o});var n=s(74848),r=s(28453);const i={},c="scs-0401: Status page reference implementation decision",a={id:"ops/scs-0401",title:"scs-0401: Status page reference implementation decision",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/ops/scs-0401.md",sourceDirName:"ops",slug:"/ops/scs-0401",permalink:"/standards/ops/scs-0401",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Status Page create decision",permalink:"/standards/scs-0400-v1-status-page-create-decision"},next:{title:"Status page reference implementation decision",permalink:"/standards/scs-0401-v1-status-page-reference-implementation-decision"}},d={},o=[];function l(e){const t={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"scs-0401-status-page-reference-implementation-decision",children:"scs-0401: Status page reference implementation decision"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0401-v1-status-page-reference-implementation-decision",children:"scs-0401-v1"})}),(0,n.jsx)(t.td,{children:"Decision Record"}),(0,n.jsx)(t.td,{children:"Draft"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function p(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>a});var n=s(96540);const r={},i=n.createContext(r);function c(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5b235e06.b07b499e.js b/assets/js/5b235e06.b07b499e.js new file mode 100644 index 0000000000..41fafca2d5 --- /dev/null +++ b/assets/js/5b235e06.b07b499e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8523],{31327:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>n,default:()=>h,frontMatter:()=>r,metadata:()=>u,toc:()=>c});var i=s(74848),o=s(28453);const r={sidebar_label:"Contributor Guide"},n="Contributor Guide",u={id:"iaas/guides/other-guides/contributor-guide",title:"Contributor Guide",description:"We welcome any issues, change requests or general feedback. Do not hestiate to open an issue.",source:"@site/docs/02-iaas/guides/other-guides/contributor-guide.md",sourceDirName:"02-iaas/guides/other-guides",slug:"/iaas/guides/other-guides/contributor-guide",permalink:"/docs/iaas/guides/other-guides/contributor-guide",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/contributor-guide.md",tags:[],version:"current",frontMatter:{sidebar_label:"Contributor Guide"},sidebar:"docs",previous:{title:"Cloud in a Box Guide",permalink:"/docs/iaas/guides/other-guides/cloud-in-a-box"},next:{title:"Developer Guide",permalink:"/docs/iaas/guides/other-guides/developer-guide/"}},a={},c=[];function d(e){const t={a:"a",h1:"h1",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"contributor-guide",children:"Contributor Guide"}),"\n",(0,i.jsxs)(t.p,{children:["We welcome any issues, change requests or general feedback. Do not hestiate to ",(0,i.jsx)(t.a,{href:"https://github.com/osism/issues/issues/new",children:"open an issue"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["We use GitHub Issues to capture feature requests, feedback, bugs, etc. The tracker is available in the\n",(0,i.jsx)(t.a,{href:"https://github.com/osism/issues/issues",children:"osism/issues"})," repository. There are no specific requirements for the creation of an issue.\nError cases should be described in such a way that they are directly reproducible. The more outputs there are,\nthe better."]}),"\n",(0,i.jsxs)(t.p,{children:["We use GitHub pull requests for contributions. The use of pull requets is documented in the\nofficial ",(0,i.jsx)(t.a,{href:"https://docs.github.com/en/github/collaborating-with-pull-requests",children:"GitHub documentation"}),".\nThe process in detail for the creation of a fork, branch etc. is also documented in the\nofficial ",(0,i.jsx)(t.a,{href:"https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests",children:"GitHub documentation"}),".\nIt is recommended to use the ",(0,i.jsx)(t.a,{href:"https://cli.github.com",children:"GitHub CLI"}),". Makes many steps easier."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>n,x:()=>u});var i=s(96540);const o={},r=i.createContext(o);function n(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function u(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:n(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5b402526.3e7c75e7.js b/assets/js/5b402526.3e7c75e7.js new file mode 100644 index 0000000000..dbc7488474 --- /dev/null +++ b/assets/js/5b402526.3e7c75e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1001],{22185:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>c,toc:()=>a});var t=s(74848),o=s(28453);const r={title:"Standards, Docs and Organisation",type:"Procedural",status:"Stable",stabilized_at:new Date("2023-02-06T00:00:00.000Z"),track:"Global"},i=void 0,c={id:"scs-0002-v1-standards-docs-org",title:"Standards, Docs and Organisation",description:"Introduction",source:"@site/standards/scs-0002-v1-standards-docs-org.md",sourceDirName:".",slug:"/scs-0002-v1-standards-docs-org",permalink:"/standards/scs-0002-v1-standards-docs-org",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Standards, Docs and Organisation",type:"Procedural",status:"Stable",stabilized_at:"2023-02-06T00:00:00.000Z",track:"Global"},sidebar:"standards",previous:{title:"scs-0002: Standards, Docs and Organisation",permalink:"/standards/global/scs-0002"},next:{title:"SCS Documentation structure",permalink:"/standards/scs-0002-v2-standards-docs-org"}},d={},a=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Suggested cleanup (step 1)",id:"suggested-cleanup-step-1",level:2}];function l(e){const n={code:"code",h2:"h2",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsxs)(n.p,{children:["The old Docs repository had a subdirectory ",(0,t.jsx)(n.code,{children:"Design-Docs/"})," which holds Docs on\nDesign Considerations, older Architecture Decision Records (ADRs) and even\nStandards. It also has a ",(0,t.jsx)(n.code,{children:"Design-Docs/tools/"})," subdirectory with conformance\nchecks and our overall conformance check driver (from PR#182)."]}),"\n",(0,t.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,t.jsx)(n.p,{children:"This directory structure is confusing in a number of ways:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The conformance checks are hard to find."}),"\n",(0,t.jsx)(n.li,{children:"The mixture of document types requires searching at two or three places."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"We want to improve this (while avoiding unnecessary churn)."}),"\n",(0,t.jsx)(n.h2,{id:"suggested-cleanup-step-1",children:"Suggested cleanup (step 1)"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Move ",(0,t.jsx)(n.code,{children:"Design-Docs/tools/"})," contents to ",(0,t.jsx)(n.code,{children:"Tests/"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Also create subdirectories then for layers and test, while the overall\nconformance check tool, certification specs and README remain in ",(0,t.jsx)(n.code,{children:"Tests/"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Rename ",(0,t.jsx)(n.code,{children:"Design-Docs/"})," to ",(0,t.jsx)(n.code,{children:"Drafts/"}),".","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Use individual PRs to rewrite existing ADRs and Standards there to conform\nto our standards and move them over to ",(0,t.jsx)(n.code,{children:"Standards/"}),"."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Some documents with findings will remain in the ",(0,t.jsx)(n.code,{children:"Drafts"})," directory.\nWe may want to categorize these and have a folder e.g. for research results."]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const o={},r=t.createContext(o);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5b909c46.c91cf602.js b/assets/js/5b909c46.c91cf602.js new file mode 100644 index 0000000000..41cbdaa8dd --- /dev/null +++ b/assets/js/5b909c46.c91cf602.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6707],{72762:(t,n,e)=>{e.r(n),e.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>m,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var s=e(74848),i=e(28453);const o={},c="Mailing Lists",a={id:"tools/mailinglists",title:"Mailing Lists",description:"We have an announcements mailing list there announce@lists.scs.community and you",source:"@site/community/tools/mailinglists.md",sourceDirName:"tools",slug:"/tools/mailinglists",permalink:"/community/tools/mailinglists",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Matrix",permalink:"/community/tools/matrix"},next:{title:"Nextcloud",permalink:"/community/tools/nextcloud"}},r={},l=[];function u(t){const n={a:"a",code:"code",h1:"h1",p:"p",...(0,i.R)(),...t.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"mailing-lists",children:"Mailing Lists"}),"\n",(0,s.jsxs)(n.p,{children:["We have an announcements mailing list there ",(0,s.jsx)(n.code,{children:"announce@lists.scs.community"})," and you\ncan subscribe via the ",(0,s.jsx)(n.a,{href:"https://scs.sovereignit.de/mailman3/postorius/lists/",children:"mailman3 frontend"}),"\nalso without the SCS nextcloud account if you prefer."]})]})}function m(t={}){const{wrapper:n}={...(0,i.R)(),...t.components};return n?(0,s.jsx)(n,{...t,children:(0,s.jsx)(u,{...t})}):u(t)}},28453:(t,n,e)=>{e.d(n,{R:()=>c,x:()=>a});var s=e(96540);const i={},o=s.createContext(i);function c(t){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof t?t(n):{...n,...t}}),[n,t])}function a(t){let n;return n=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:c(t.components),s.createElement(o.Provider,{value:n},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/5b9bf978.bacb2041.js b/assets/js/5b9bf978.bacb2041.js new file mode 100644 index 0000000000..4f4188a88c --- /dev/null +++ b/assets/js/5b9bf978.bacb2041.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5773],{2872:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>o,contentTitle:()=>a,default:()=>u,frontMatter:()=>c,metadata:()=>r,toc:()=>d});var s=n(74848),t=n(28453);const c={sidebar_label:"Self-signed certificates",sidebar_position:20},a="Self-signed certificates",r={id:"iaas/guides/configuration-guide/self-signed-certificates",title:"Self-signed certificates",description:"The use of self-signed certificates with a custom CA is possible. However, a few",source:"@site/docs/02-iaas/guides/configuration-guide/self-signed-certificates.md",sourceDirName:"02-iaas/guides/configuration-guide",slug:"/iaas/guides/configuration-guide/self-signed-certificates",permalink:"/docs/iaas/guides/configuration-guide/self-signed-certificates",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/self-signed-certificates.md",tags:[],version:"current",sidebarPosition:20,frontMatter:{sidebar_label:"Self-signed certificates",sidebar_position:20},sidebar:"docs",previous:{title:"Loadbalancer",permalink:"/docs/iaas/guides/configuration-guide/loadbalancer"},next:{title:"Ceph",permalink:"/docs/iaas/guides/configuration-guide/ceph"}},o={},d=[];function l(e){const i={code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h1,{id:"self-signed-certificates",children:"Self-signed certificates"}),"\n",(0,s.jsx)(i.p,{children:"The use of self-signed certificates with a custom CA is possible. However, a few\nadditional parameters are then required in the configuration so that the custom CA\nis known everywhere and the self-signed certificates are accepted as valid."}),"\n",(0,s.jsxs)(i.ol,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:"Import custom CA"}),"\n",(0,s.jsxs)(i.p,{children:["Any custom CA can be added via the ",(0,s.jsx)(i.code,{children:"certificates_ca"})," parameter.\nThe import on the nodes is done via ",(0,s.jsx)(i.code,{children:"osism apply certificates"}),".\nThis is already done in the bootstrap of the nodes."]}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"certificates_ca:\n - name: custom.crt\n certificate: |\n -----BEGIN CERTIFICATE-----\n [...]\n -----END CERTIFICATE-----\n"})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:"Manager service"}),"\n",(0,s.jsxs)(i.p,{children:["The local environment variable ",(0,s.jsx)(i.code,{children:"REQUESTS_CA_BUNDLE"})," must be set explicitly so that\nthe manager service knows the custom CA in all necessary places."]}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-yaml",metastring:'title="environments/manager/configuration.yml"',children:"manager_environment_extra:\n REQUESTS_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt\n"})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:"Use in OpenStack"}),"\n",(0,s.jsxs)(i.p,{children:["The custom CA must also be copied into the OpenStack containers. To do this, the custom\nCA is first added in a file in the ",(0,s.jsx)(i.code,{children:"environments/kolla/certificates/ca"})," of the configuration\nrepository. It makes sense to use the same filename like in step 1."]}),"\n",(0,s.jsx)(i.p,{children:"The import of the custom CA must then be explicitly enabled."}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'kolla_copy_ca_into_containers: "yes"\nopenstack_cacert: /etc/ssl/certs/ca-certificates.crt\n'})}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:i}={...(0,t.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>a,x:()=>r});var s=n(96540);const t={},c=s.createContext(t);function a(e){const i=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),s.createElement(c.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5bd7bc3b.65e12fbc.js b/assets/js/5bd7bc3b.65e12fbc.js new file mode 100644 index 0000000000..a637fbe7d6 --- /dev/null +++ b/assets/js/5bd7bc3b.65e12fbc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[643],{2380:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>d,toc:()=>l});var i=s(74848),t=s(28453);const o={sidebar_label:"Operations Guide",sidebar_position:30},a="Operations Guide",d={id:"iaas/guides/operations-guide/index",title:"Operations Guide",description:"Change Node states",source:"@site/docs/02-iaas/guides/operations-guide/index.md",sourceDirName:"02-iaas/guides/operations-guide",slug:"/iaas/guides/operations-guide/",permalink:"/docs/iaas/guides/operations-guide/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/index.md",tags:[],version:"current",sidebarPosition:30,frontMatter:{sidebar_label:"Operations Guide",sidebar_position:30},sidebar:"docs",previous:{title:"Validations",permalink:"/docs/iaas/guides/configuration-guide/validations/"},next:{title:"Manager",permalink:"/docs/iaas/guides/operations-guide/manager/"}},r={},l=[{value:"Change Node states",id:"change-node-states",level:2},{value:"Maintenance",id:"maintenance",level:3},{value:"Bootstrap",id:"bootstrap",level:3},{value:"Use of custom plays",id:"use-of-custom-plays",level:2},{value:"Manage services",id:"manage-services",level:2},{value:"Manage containers",id:"manage-containers",level:2},{value:"Reboot nodes",id:"reboot-nodes",level:2},{value:"Working with the OOB Board via IPMI",id:"working-with-the-oob-board-via-ipmi",level:2},{value:"Display the IP address",id:"display-the-ip-address",level:3}];function c(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"operations-guide",children:"Operations Guide"}),"\n",(0,i.jsx)(n.h2,{id:"change-node-states",children:"Change Node states"}),"\n",(0,i.jsx)(n.p,{children:"A node can be in different states. Depending on the state, different actions\nare possible or are triggered."}),"\n",(0,i.jsx)(n.p,{children:"The individual states of a node can be retrieved via Ansible Facts and local\nfiles on the node itself."}),"\n",(0,i.jsx)(n.h3,{id:"maintenance",children:"Maintenance"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism set maintenance NODE\nosism noset maintenance NODE\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Ansible fact: ",(0,i.jsx)(n.code,{children:"ansible_local.osism.maintenance"})]}),"\n",(0,i.jsxs)(n.li,{children:["State file: ",(0,i.jsx)(n.code,{children:"/etc/osism/maintenance"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"bootstrap",children:"Bootstrap"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism set bootstrap NODE\nosism noset bootstrap NODE\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Ansible fact: ",(0,i.jsx)(n.code,{children:"ansible_local.osism.bootstrap"})]}),"\n",(0,i.jsxs)(n.li,{children:["State file: ",(0,i.jsx)(n.code,{children:"/etc/osism/bootstrap"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"use-of-custom-plays",children:"Use of custom plays"}),"\n",(0,i.jsx)(n.p,{children:"Custom Plays can be used in all environments in the configuration repository."}),"\n",(0,i.jsxs)(n.p,{children:["For example, this is a play to prepare all devices to be used for Ceph on a Ceph\nresource node. It is saved in the configuration repository in the file\n",(0,i.jsx)(n.code,{children:"environments/ceph/playbook-wipe-partitions.yml"}),". It is run with\n",(0,i.jsx)(n.code,{children:"osism apply -e ceph wipe-parititons"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/playbook-wipe-partitions.yml',children:'---\n- name: Wipe partitions\n hosts: ceph-resource\n gather_facts: false\n\n tasks:\n - name: Wipe partitions\n become: true\n ansible.builtin.shell: |\n wipefs --all "{{ item }}"\n dd if=/dev/zero of="{{ item }}" bs=1 count=4096\n changed_when: false\n with_items: "{{ devices }}"\n'})}),"\n",(0,i.jsx)(n.h2,{id:"manage-services",children:"Manage services"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply manage-service \\\n -e service_name=rsysloc \\\n -e service_state=restarted\n"})}),"\n",(0,i.jsx)(n.h2,{id:"manage-containers",children:"Manage containers"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply manage-container \\\n -e container_name=nova_compute \\\n -e container_action=restart\n"})}),"\n",(0,i.jsx)(n.h2,{id:"reboot-nodes",children:"Reboot nodes"}),"\n",(0,i.jsx)(n.p,{children:"When using reboot play, the node is rebooted directly. It is not ensured in\nadvance that there is no more payload on the node and no services etc. are\ndisabled."}),"\n",(0,i.jsxs)(n.p,{children:["Reboot node ",(0,i.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz"})," and wait until the reboot has\nbeen completed and the system is accessible again."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply reboot \\\n -e reboot_wait=True \\\n -e ireallymeanit=yes \\\n -l testbed-node-0.testbed.osism.xyz\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Reboot node ",(0,i.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz"})," and do not wait for the reboot\nto complete."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply reboot \\\n -e ireallymeanit=yes \\\n -l testbed-node-0.testbed.osism.xyz\n"})}),"\n",(0,i.jsx)(n.h2,{id:"working-with-the-oob-board-via-ipmi",children:"Working with the OOB Board via IPMI"}),"\n",(0,i.jsx)(n.h3,{id:"display-the-ip-address",children:"Display the IP address"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ sudo ipmitool lan print | grep 'IP Address'\nIP Address Source : DHCP Address\nIP Address : 10.10.0.100\n"})})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>d});var i=s(96540);const t={},o=i.createContext(t);function a(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c201b0a.8fe0e868.js b/assets/js/5c201b0a.8fe0e868.js new file mode 100644 index 0000000000..020c097cc7 --- /dev/null +++ b/assets/js/5c201b0a.8fe0e868.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2621],{95818:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var t=s(74848),r=s(28453);const i={},a="Release Notes for SCS Release 3",o={id:"releases/Release3",title:"Release Notes for SCS Release 3",description:"(Release Date: 2022-09-21)",source:"@site/docs/06-releases/Release3.md",sourceDirName:"06-releases",slug:"/releases/Release3",permalink:"/docs/releases/Release3",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release3.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Release Notes for SCS Release 2",permalink:"/docs/releases/Release2"},next:{title:"Release Notes for SCS Release 4",permalink:"/docs/releases/Release4"}},l={},d=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"New Features (Highlights)",id:"new-features-highlights",level:2},{value:"Operator focused improvements",id:"operator-focused-improvements",level:3},{value:"SCS Developer focused improvements (testbed and k8s cluster management)",id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Cluster Management",id:"cluster-management",level:3},{value:"OSISM",id:"osism",level:3},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Resolved Issues",id:"resolved-issues",level:2},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R3",id:"list-of-known-issues--restrictions-in-r3",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Thanks",id:"thanks",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"release-notes-for-scs-release-3",children:"Release Notes for SCS Release 3"}),"\n",(0,t.jsx)(n.p,{children:"(Release Date: 2022-09-21)"}),"\n",(0,t.jsx)(n.h2,{id:"scope",children:"Scope"}),"\n",(0,t.jsx)(n.p,{children:"Main goals for Release 3 (R3) were user federation, increase in deployment and upgrade\nvelocity by improving automated test coverage as well as bringing disk encryption based on\ntang from the state of a technical preview to be fully supported."}),"\n",(0,t.jsx)(n.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["We support the latest ",(0,t.jsx)(n.a,{href:"https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.25.md",children:"Kubernetes 1.25"}),"\nreleases."]}),"\n",(0,t.jsxs)(n.li,{children:["The Kubernetes Cluster API is now available in a stable v1beta1\n",(0,t.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api/releases",children:"release 1.2.x"}),"\nwith the corresponding ",(0,t.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api/releases",children:"cluster-api-provider-openstack 0.6.x"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/",children:"Kubernetes Cluster API cluster management service"}),"\nhas seen major managability improvements.\nPlease consult the\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R3.md",children:"k8s cluster api provider release notes"}),"\nfor more details."]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://releases.openstack.org/yoga/highlights.html",children:"OpenStack Yoga release"})}),"\n",(0,t.jsx)(n.li,{children:"Ceph Quincy is available, the default release of Ceph is still Pacific."}),"\n",(0,t.jsxs)(n.li,{children:["The base infrastructure is provided by\n",(0,t.jsx)(n.a,{href:"https://release.osism.tech/notes/4.0.0.html",children:"OSISM 4.0.0"}),"\nwhich in turn builds on top of kolla and kolla-ansible."]}),"\n",(0,t.jsx)(n.li,{children:"Disk encryption based on Network bound disk encryption (NBDE) is available."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"new-features-highlights",children:"New Features (Highlights)"}),"\n",(0,t.jsx)(n.h3,{id:"operator-focused-improvements",children:"Operator focused improvements"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Work is underway to supersede ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor",children:"openstack-health-monitor"}),"\nwith a comprehensive approach using scenarios with ansible playbooks\nthat has been developed and used by T-Systems for their Open Telekom Cloud.\nMeanwhile, openstack-health-monitor has seen the addition of data\ncollection with telegraf and influxdb as well as a good dashboard\nwith grafana."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["We have used our keystone to keycloak federation to use keycloak as identity\nbroker to federate identities from other (SCS) clouds' keycloaks.\nThis works well for the Web-Interface; we have still some work to do to also make it smooth\nalso for API/CLI usage. We have ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/IAM-federation/keystone-keycloak-federation.md",children:"documented the current status"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["We believe that Gaia-X self-descriptions should also contain a description of\ntechnical properties of services; higher-level services and workloads can than\ndeclare their requirements and be matched against lower level services / platforms.\nIn good platforms, most (or all) technical properties are discoverable. In the\nGaia-X Hackathon #4, we have worked on a demonstrator that characterizes some\naspects of an OpenStack-based IaaS platform and which produces self-descriptions\nthat can be submitted to the Gaia-X trust service, pass the tests and you can\nbe awared a verifiable credential. Code is available in the\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/gx-self-description-generator",children:"gx-self-description-generator repo"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"scs-developer-focused-improvements-testbed-and-k8s-cluster-management",children:"SCS Developer focused improvements (testbed and k8s cluster management)"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Following significant discussions on how to standardize our cluster management solution,\nthere is a draft concept as part of R3 now, which will be further worked on during\nthe R4 cycle. See ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R3.md#cluster-standardization",children:"Cluster standardization"}),"\nsection of the release notes from k8s-cluster-api-provider.\nWhile our reference implementation uses the concepts and code from k8s cluster API on\ntop of our SCS reference implementation (OpenStack automated by OSISM), we want to\nassure that non-OpenStack IaaS and solutions that diverge from cluster-API have the possibility\nto be SCS compliant."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Workload clusters managed by our SCS cluster management solutions can now much\nmore easily receive k8s version upgrades, ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R3.md#simplified-rolling-node-upgrades-223",children:"as the cluster-template no longer needs\nto be touched for this"}),". There is an ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/doc/Upgrade-Guide.md",children:"Upgrade Guide"})," available now."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"LUKS encryption is now documented and enabled in the testbed by default."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Further noteworthy improvements to testbed:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Public DNS for testbed is now available (",(0,t.jsx)(n.code,{children:"testbed.osism.xyz"}),"), allowing to access services\nvia TLS protected by a wildcard CA certificate."]}),"\n",(0,t.jsx)(n.li,{children:"The wireguard VPN service is deployed in the testbed by default."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["An overview over the used software versions is available from the\n",(0,t.jsx)(n.a,{href:"https://github.com/osism/release",children:"OSISM release"})," repository as input\nfor a complete SBOM. This allows to e.g. investigate the contents of the\nused (v4.0.0) images."]}),"\n",(0,t.jsx)(n.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,t.jsx)(n.h3,{id:"cluster-management",children:"Cluster Management"}),"\n",(0,t.jsxs)(n.p,{children:["Upgrade from R2 to R3 for cluster management and clusters:\nSee ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R3.md#incompatible-changes",children:"k8s-cluster-api-provider Release Notes"}),"\nfor more details. There is an Upgrade Guide written specifically to address the steps needed for upgrading\nyour cluster management and the workload clusters."]}),"\n",(0,t.jsx)(n.h3,{id:"osism",children:"OSISM"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["In ",(0,t.jsx)(n.code,{children:"environments/kolla/secrets.yml"})," the parameter ",(0,t.jsx)(n.code,{children:"neutron_ssh_key"})," must be\nadded."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"neutron_ssh_key:\n private_key:\n public_key:\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ssh key can be generated as follows: ",(0,t.jsx)(n.code,{children:'ssh-keygen -t rsa -b 4096 -N "" -f id_rsa.neutron -C "" -m PEM'})]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"removals",children:"Removals"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The Cockpit service has been removed."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,t.jsxs)(n.p,{children:["Deprecations happen according to our ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Release-Policies.md#deprecation",children:"deprecation policy"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Linux bridge support has been deprecated by the Neutron team and marked as experimental.\nIf Linux bridge is used in deployments, migrating to OpenVSwitch is recommended."}),"\n",(0,t.jsxs)(n.li,{children:["Debian dropped hddtemp (",(0,t.jsx)(n.a,{href:"https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1002484",children:"https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1002484"}),"),\ntherefore the ",(0,t.jsx)(n.code,{children:"hddtemp"})," service will be removed from the next OSISM release, as there is\nno package available for Ubuntu 22.04."]}),"\n",(0,t.jsx)(n.li,{children:"Heat will no longer be offered by default in the testbed in the future"}),"\n",(0,t.jsx)(n.li,{children:"The following services are currently not used and are deprecated and scheduled for removal as of now: Falco, Jenkins, Rundeck, Lynis, Trivy"}),"\n",(0,t.jsx)(n.li,{children:"The docker-compose CLI will be removed and replaced by the new compose plugin for Docker.\ndocker-compose is then no longer available and docker compose must be used instead"}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"cleanup-elasticsearch"})," playbook is deprecated. In the future,\nthe ",(0,t.jsx)(n.code,{children:"elasticsearch-curator"})," service (part of Kolla) has to be used\nfor Elasticsearch cleanup."]}),"\n",(0,t.jsx)(n.li,{children:"All osism- scripts on the manager are deprecated and will be replaced by the new OSISM CLI. The scripts will be removed in the next release"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,t.jsx)(n.p,{children:"No severe security issues need to be highlighted since Release 2. However, by updating to the latest stable version of\nthe integrated open source components, we benefit from the upstream security fixes and thus recommend to upgrade all\nSCS environments. Please note that Release 2 maintenance by the SCS project team will end by the end of October."}),"\n",(0,t.jsx)(n.h2,{id:"resolved-issues",children:"Resolved Issues"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Certificates in k8s clusters are subject to expiration - typically after one year.\nWe ensure these are renewed on control-plane upgrades, but operators may need manual attention\nin case upgrades are not performed for extended periods of time. This is documented in\nthe k8s-cluster-api-provider's\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/doc/Maintenance_and_Troubleshooting.md",children:"Maintenance and Troubleshooting Guide"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,t.jsxs)(n.p,{children:["The clusters created with our cluster-API cluster management solution pass\nthe ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Image-Properties-Spec.md",children:"CNCF conformance tests"}),"\nas reported by ",(0,t.jsx)(n.a,{href:"https://sonobuoy.io/",children:"sonobuoy"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://openstack.org/",children:"OpenStack"})," layer passes the\n",(0,t.jsx)(n.a,{href:"https://openinfra.dev/",children:"OIF"})," trademark tests, so cloud providers\nleveraging the stack should easily be able to achieve the\n",(0,t.jsx)(n.a,{href:"https://www.openstack.org/brand/interop/",children:'"OpenStack powered compute"'}),"\ntrademark certification."]}),"\n",(0,t.jsxs)(n.p,{children:["Our partner plusserver has ",(0,t.jsx)(n.a,{href:"https://www.openstack.org/brand/interop/",children:"achieved"}),"\na ",(0,t.jsx)(n.a,{href:"https://www.bsi.bund.de/EN/Themen/Unternehmen-und-Organisationen/Informationen-und-Empfehlungen/Empfehlungen-nach-Angriffszielen/Cloud-Computing/Kriterienkatalog-C5/kriterienkatalog-c5_node.html",children:"BSI C5"}),"\nsecurity certification for their SCS implementation pluscloud open."]}),"\n",(0,t.jsxs)(n.p,{children:["We are working within ",(0,t.jsx)(n.a,{href:"https://gaia-x.eu/",children:"Gaia-X"})," to further the power\nof Gaia-X self-descriptions and are closely working with the\n",(0,t.jsx)(n.a,{href:"https://gxfs.de/",children:"GXFS project"}),"\nto jointly deliver a standard toolbox for Gaia-X compliant\ninfrastructure and service offerings."]}),"\n",(0,t.jsxs)(n.p,{children:["The SCS standards for ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/flavor-naming.md",children:"flavor naming"})," and\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Image-Properties-Spec.md",children:"image metadata"}),"\nare largely unchanged since R1. We have however\nmade progress in our reference implementation fully implementing\nthem without any further tweaks. The\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/tools/flavor-name-check.py",children:"conformance test for the flavor naming"}),"\nhas seen minor improvements; a\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/tools/image-md-check.py",children:"conformance test for the image metadata"}),"\nhas been added."]}),"\n",(0,t.jsx)(n.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,t.jsxs)(n.p,{children:["See ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Release-Numbering-Scheme.md",children:"Release Numbering scheme"})," -- unchanged from R0.\nWe have added the tag ",(0,t.jsx)(n.code,{children:"v4.0.0"})," to the relevant repositories to designate the ",(0,t.jsx)(n.code,{children:"SCS_RELEASE_R3"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Note that we will release R4 (v5.0.0) in March 2023 and stop providing maintenance\nupdates for R3 at the end of April 2023."}),"\n",(0,t.jsx)(n.h2,{id:"list-of-known-issues--restrictions-in-r3",children:"List of known issues & restrictions in R3"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Distributed Virtual Routing (DVR) is not officially supported by OSISM, not tested and not recommended."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,t.jsxs)(n.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,t.jsx)(n.a,{href:"https://scs.community/contribute/",children:"How to contribute page"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"thanks",children:"Thanks"}),"\n",(0,t.jsx)(n.p,{children:"The work for R3 has been done by many contributors from our community.\nWe have not collected detailed stats that would split out the individual contributor's\nand companies shares ... we may do so in the future. We are grateful to have such an\nactive and engaged community that has done so much work! Thanks to our contributors!"}),"\n",(0,t.jsx)(n.p,{children:"Of course we are leveraging a huge amount of open source technology that has been\ncreated by our friends in other communities, many of which are part of the\nCNCF, Linux Foudation, OIF, and others. We participate and contribute where\nwe can and definitely want to acknowledge the great work that we build upon."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>o});var t=s(96540);const r={},i=t.createContext(r);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c2c818b.3ee91200.js b/assets/js/5c2c818b.3ee91200.js new file mode 100644 index 0000000000..0b39c337cc --- /dev/null +++ b/assets/js/5c2c818b.3ee91200.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7153],{72619:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>t,metadata:()=>o,toc:()=>d});var s=n(74848),a=n(28453);const t={sidebar_label:"Image Manager",sidebar_position:50},r="Image Manager",o={id:"iaas/guides/operations-guide/openstack/tools/image-manager/index",title:"Image Manager",description:"The OpenStack Image Manager is a tool for managing all",source:"@site/docs/02-iaas/guides/operations-guide/openstack/tools/image-manager/index.md",sourceDirName:"02-iaas/guides/operations-guide/openstack/tools/image-manager",slug:"/iaas/guides/operations-guide/openstack/tools/image-manager/",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/image-manager/index.md",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"Image Manager",sidebar_position:50},sidebar:"docs",previous:{title:"Tools",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/"},next:{title:"Automated updates",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update"}},l={},d=[{value:"Requirements",id:"requirements",level:2},{value:"OpenStack Image Service (Glance)",id:"openstack-image-service-glance",level:3},{value:"Object storage backend",id:"object-storage-backend",level:3},{value:"Getting started",id:"getting-started",level:2},{value:"Image definitions",id:"image-definitions",level:2},{value:"SCS image standard",id:"scs-image-standard",level:3},{value:"Image with regular rebuilds",id:"image-with-regular-rebuilds",level:3},{value:"Image without regular rebuild",id:"image-without-regular-rebuild",level:3},{value:"Other properties",id:"other-properties",level:3},{value:"Image properties",id:"image-properties",level:4},{value:"Image tags",id:"image-tags",level:4},{value:"image status",id:"image-status",level:4},{value:"Image visibility",id:"image-visibility",level:4},{value:"Usage",id:"usage",level:2},{value:"Mirroring images",id:"mirroring-images",level:3},{value:"Updating images",id:"updating-images",level:3}];function c(e){const i={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h1,{id:"image-manager",children:"Image Manager"}),"\n",(0,s.jsxs)(i.p,{children:["The ",(0,s.jsx)(i.a,{href:"https://pypi.org/project/openstack-image-manager/",children:"OpenStack Image Manager"})," is a tool for managing all\nimages on an OpenStack environment"]}),"\n",(0,s.jsx)(i.h2,{id:"requirements",children:"Requirements"}),"\n",(0,s.jsx)(i.p,{children:"This information is only relevant for the operator of an OpenStack environment. You can skip this section if\nyou want to use OpenStack Image Manager as a normal user and you are not an operator of an openStack environment."}),"\n",(0,s.jsx)(i.h3,{id:"openstack-image-service-glance",children:"OpenStack Image Service (Glance)"}),"\n",(0,s.jsx)(i.p,{children:"The OpenStack Image Service (Glance) is required to upload and discover data assets that are used by other\nservices."}),"\n",(0,s.jsx)(i.p,{children:"Since this script stores many images in a single project, the Glance quota must be set accordingly high or to unlimited."}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-ini",children:"[DEFAULT]\nuser_storage_quota = 1TB\n"})}),"\n",(0,s.jsxs)(i.p,{children:["With most storage backends it makes sense to convert the imported images directly to RAW. So it is required for using Ceph and it's\nfeatures too. Recited from the Ceph documentation ",(0,s.jsx)(i.a,{href:"https://docs.ceph.com/en/latest/rbd/qemu-rbd/",children:"QEMU and block devices"})," and\n",(0,s.jsx)(i.a,{href:"https://docs.ceph.com/en/latest/rbd/rbd-openstack/",children:"Block devices and OpenStack"}),"."]}),"\n",(0,s.jsxs)(i.admonition,{type:"info",children:[(0,s.jsx)(i.p,{children:"The raw data format is really the only sensible format option to use with RBD. Technically, you could use other QEMU-supported formats\n(such as qcow2 or vmdk), but doing so would add additional overhead, and would also render the volume unsafe for virtual machine live\nmigration when caching (see below) is enabled."}),(0,s.jsx)(i.p,{children:"Important Ceph doesn't support QCOW2 for hosting a virtual machine disk. Thus if you want to boot virtual machines in Ceph (ephemeral\nbackend or boot from volume), the Glance image format must be RAW."}),(0,s.jsxs)(i.p,{children:["See the ",(0,s.jsx)(i.a,{href:"https://docs.openstack.org/glance/latest/configuration/sample-configuration.html",children:"OpenStack Glance documentation"}),"\nfor more details."]})]}),"\n",(0,s.jsx)(i.p,{children:"This requires the following parameter for the image import workflow."}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-ini",children:"[taskflow_executor]\nconversion_format = raw\n\n[image_import_opts]\nimage_import_plugins = ['image_decompression', 'image_conversion']\n\n[image_conversion]\noutput_format = raw\n"})}),"\n",(0,s.jsx)(i.h3,{id:"object-storage-backend",children:"Object storage backend"}),"\n",(0,s.jsx)(i.p,{children:"If the mirror functionality is used, an object storage backend is required. The use of the mirror functionality\nis optional and is not used by default."}),"\n",(0,s.jsx)(i.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,s.jsxs)(i.p,{children:["This ",(0,s.jsx)(i.strong,{children:"Getting started"})," will upload a private image to your OpenStack environment with\nthe help of the OpenStack Image Manager."]}),"\n",(0,s.jsxs)(i.ol,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:["Install the ",(0,s.jsx)(i.a,{href:"https://pypi.org/project/openstack-image-manager/",children:"openstack-image-manager"})," package with\n",(0,s.jsx)(i.a,{href:"https://pypi.org/project/pip/",children:"pip"}),"."]}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-sh",children:"pip3 install openstack-image-manager\n"})}),"\n",(0,s.jsxs)(i.p,{children:["The installation can also be done via ",(0,s.jsx)(i.a,{href:"https://pypi.org/project/pipenv/",children:"pipenv"}),"."]}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"Pipefile"})," file is created with this content. The ",(0,s.jsx)(i.a,{href:"https://pypi.org/project/openstack-image-manager/#history",children:"latest version of openstack-image-manager"}),"\nis used."]}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-ini",children:'[[source]]\nurl = "https://pypi.org/simple"\nverify_ssl = true\nname = "pypi"\n\n[packages]\nopenstack-image-manager = "==0.20240403.0"\n\n[dev-packages]\n\n[requires]\npython_version = "3.10"\n'})}),"\n",(0,s.jsx)(i.p,{children:"The dependencies are then installed and the shell is prepared for use:"}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-sh",children:"pipenv install\npipenv shell\n"})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:["Create a image definition in the file ",(0,s.jsx)(i.code,{children:"getting-started.yml"})," in the local directory ",(0,s.jsx)(i.code,{children:"images"}),"."]}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-yaml",children:'---\nimages:\n - name: MyCirros\n format: qcow2\n login: cirros\n password: gocubsgo\n min_disk: 1\n min_ram: 32\n status: active\n visibility: private\n multi: false\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_rng_model: virtio\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n os_distro: cirros\n replace_frequency: never\n uuid_validity: none\n provided_until: none\n tags: []\n versions:\n - version: "0.6.0"\n url: https://github.com/cirros-dev/cirros/releases/download/0.6.0/cirros-0.6.0-x86_64-disk.img\n checksum: "sha256:94e1e2c94dbbae7d4bdc38e68590a1daf73c9de2d03dd693857b4b0a042548e8"\n build_date: 2022-09-28\n'})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:["Run the OpenStack Image Manager. It is assumed that a profile with the name ",(0,s.jsx)(i.code,{children:"openstack"})," exists in the\n",(0,s.jsx)(i.a,{href:"https://docs.openstack.org/python-openstackclient/latest/configuration/index.html#configuration-files",children:"clouds.yaml"}),"."]}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-bash",children:'openstack-image-manager --cloud openstack --filter ".*Cirr.*" --images images/\n'})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"image-definitions",children:"Image definitions"}),"\n",(0,s.jsxs)(i.p,{children:["The configuration consists of different parameter settings, such as values for\nminimum RAM or the visibility of the image. Have a look at the examples below\nfor all parameters. After a change to the configuration, validate it with\n",(0,s.jsx)(i.code,{children:"tox -- --dry-run"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"scs-image-standard",children:"SCS image standard"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["The value of ",(0,s.jsx)(i.code,{children:"login"})," is stored as ",(0,s.jsx)(i.code,{children:"image_original_user"})," in the metadata of an image."]}),"\n",(0,s.jsxs)(i.li,{children:["If ",(0,s.jsx)(i.code,{children:"image_description"})," is not set as meta information, ",(0,s.jsx)(i.code,{children:"image_description"})," is set to the name of the image."]}),"\n",(0,s.jsxs)(i.li,{children:["The value of ",(0,s.jsx)(i.code,{children:"build_date"})," of a specific version of an image is stored as ",(0,s.jsx)(i.code,{children:"image_build_date"})," in the metadata of an image."]}),"\n",(0,s.jsxs)(i.li,{children:["The value of ",(0,s.jsx)(i.code,{children:"url"})," of a specific version of an image is stored as ",(0,s.jsx)(i.code,{children:"image_source"})," in the metadata of an image."]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"image-with-regular-rebuilds",children:"Image with regular rebuilds"}),"\n",(0,s.jsx)(i.p,{children:"This type of image definition is used for images that are rebuilt at regular\nintervals. For example, this is the case for the daily builds of the Ubuntu\nimages."}),"\n",(0,s.jsxs)(i.p,{children:["The attribute ",(0,s.jsx)(i.code,{children:"multi: true"})," is set."]}),"\n",(0,s.jsxs)(i.p,{children:["With this type of image definition, the version of the distribution (or product,\nwhatever is contained in the image) used is already in the name of the image\ndefinition. The ",(0,s.jsx)(i.code,{children:"version"})," properties from the definition's ",(0,s.jsx)(i.code,{children:"versions"})," list\nare appended only to older iterations of the image as timestamp suffixes\nin parentheses upon each rotation (except for the latest entry)."]}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-yaml",children:"images:\n - name: Ubuntu 24.04\n format: qcow2\n login: ubuntu\n min_disk: 8\n min_ram: 512\n status: active\n visibility: public\n multi: true\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n os_distro: ubuntu\n os_version: '24.04'\n tags: []\n versions:\n - version: '20240416'\n url: https://cloud-images.ubuntu.com/noble/20240416/noble-server-cloudimg-amd64.img\n - version: '20240422'\n url: https://cloud-images.ubuntu.com/noble/20240422/noble-server-cloudimg-amd64.img\n"})}),"\n",(0,s.jsx)(i.p,{children:"This configuration creates the following images:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.strong,{children:"Ubuntu 24.04 (20240416)"})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.strong,{children:"Ubuntu 24.04"})}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"If a newer build is added, the following rotation takes place:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.strong,{children:"Ubuntu 24.04 (20240416)"})," does not change"]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.strong,{children:"Ubuntu 24.04"})," becomes ",(0,s.jsx)(i.strong,{children:"Ubuntu 24.04 (20240422)"})]}),"\n",(0,s.jsxs)(i.li,{children:["the new image becomes ",(0,s.jsx)(i.strong,{children:"Ubuntu 24.04"})]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["By default the last three images will be visible. When a fourth image is added, the visibility of\nthe last image in the list is changed to ",(0,s.jsx)(i.code,{children:"community"})," and the image can be deleted in the future."]}),"\n",(0,s.jsx)(i.h3,{id:"image-without-regular-rebuild",children:"Image without regular rebuild"}),"\n",(0,s.jsx)(i.p,{children:"This type of image definition is used for images that are not rebuilt. For example,\nthis is the case for the flatcar images. For each release of Flatcar there is exactly\none image which will not be rebuilt in the future."}),"\n",(0,s.jsxs)(i.p,{children:["The attribute ",(0,s.jsx)(i.code,{children:"multi: false"})," is set."]}),"\n",(0,s.jsxs)(i.p,{children:["With this type of image definition, the version of the distribution (or product,\nwhatever is contained in the image) used is not in the name of the image definition.\nInstead, the ",(0,s.jsx)(i.code,{children:"version"})," properties from the image definition's ",(0,s.jsx)(i.code,{children:"versions"})," list\nare appended as static version suffixes to the images' names."]}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-yaml",children:"images:\n - name: RancherOS\n format: qcow2\n login: rancher\n min_disk: 8\n min_ram: 2048\n status: active\n visibility: public\n multi: false\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n tags: []\n versions:\n - version: '1.3.0'\n url: https://github.com/rancher/os/releases/download/v1.3.0/rancheros-openstack.img\n - version: '1.4.0'\n url: https://github.com/rancher/os/releases/download/v1.4.0/rancheros-openstack.img\n - version: '1.4.1'\n url: https://github.com/rancher/os/releases/download/v1.4.1/rancheros-openstack.img\n"})}),"\n",(0,s.jsx)(i.p,{children:"This configuration creates the following images:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.strong,{children:"RancherOS 1.3.0"})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.strong,{children:"RancherOS 1.4.0"})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.strong,{children:"RancherOS 1.4.1"})}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["If a new version is added, no rotation takes place. The new version is added\nas ",(0,s.jsx)(i.strong,{children:"RancherOS x.y.z"}),". Here also the visibility of older images is not changed."]}),"\n",(0,s.jsx)(i.h3,{id:"other-properties",children:"Other properties"}),"\n",(0,s.jsx)(i.h4,{id:"image-properties",children:"Image properties"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Removal of properties is not yet possible"}),"\n",(0,s.jsx)(i.li,{children:"URL, name and format can not be changed"}),"\n",(0,s.jsxs)(i.li,{children:["Any keys can be added to ",(0,s.jsx)(i.code,{children:"meta"}),", these will be added to the image"]}),"\n",(0,s.jsxs)(i.li,{children:["Existing keys in ",(0,s.jsx)(i.code,{children:"meta"})," can be changed, the same applies to ",(0,s.jsx)(i.code,{children:"min_disk"}),"\nand ",(0,s.jsx)(i.code,{children:"min_ram"})]}),"\n"]}),"\n",(0,s.jsx)(i.h4,{id:"image-tags",children:"Image tags"}),"\n",(0,s.jsx)(i.h4,{id:"image-status",children:"image status"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["deactivation: change ",(0,s.jsx)(i.code,{children:"status"})," to ",(0,s.jsx)(i.code,{children:"deactivated"})]}),"\n",(0,s.jsxs)(i.li,{children:["reactivation: change ",(0,s.jsx)(i.code,{children:"status"})," to ",(0,s.jsx)(i.code,{children:"active"})]}),"\n"]}),"\n",(0,s.jsx)(i.h4,{id:"image-visibility",children:"Image visibility"}),"\n",(0,s.jsxs)(i.p,{children:["A full documentation about the visibility of images can be found in the ",(0,s.jsx)(i.strong,{children:"Image visibility"})," section in the\n",(0,s.jsx)(i.a,{href:"https://docs.openstack.org/api-ref/image/v2/index.html#general-information",children:"OpenStack Image Service API Documentation"}),"."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["public: set ",(0,s.jsx)(i.code,{children:"visibility"})," to ",(0,s.jsx)(i.code,{children:"public"})]}),"\n",(0,s.jsxs)(i.li,{children:["community: set ",(0,s.jsx)(i.code,{children:"visibility"})," to ",(0,s.jsx)(i.code,{children:"community"})]}),"\n",(0,s.jsxs)(i.li,{children:["shared: set ",(0,s.jsx)(i.code,{children:"visibility"})," to ",(0,s.jsx)(i.code,{children:"shared"})]}),"\n",(0,s.jsxs)(i.li,{children:["private: set ",(0,s.jsx)(i.code,{children:"visibility"})," to ",(0,s.jsx)(i.code,{children:"private"})]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"usage",children:"Usage"}),"\n",(0,s.jsx)(i.h3,{id:"mirroring-images",children:"Mirroring images"}),"\n",(0,s.jsx)(i.p,{children:"Since the upstreams often only keep their images for a short time, we mirror most of the images on REGIO.cloud.\nThis makes us independent of the availability of the images in the individual upstreams."}),"\n",(0,s.jsx)(i.h3,{id:"updating-images",children:"Updating images"}),"\n",(0,s.jsxs)(i.p,{children:["Some of the images are automatically updated by a ",(0,s.jsx)(i.a,{href:"update",children:"CI job"}),". The latest available build at the time of the CI job execution is mirrored and\nmade available as the current version."]}),"\n",(0,s.jsx)(i.p,{children:"Currently, the following images are updated once a week (every Sunday at 0 am):"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Almalinux"}),"\n",(0,s.jsx)(i.li,{children:"CentOS"}),"\n",(0,s.jsx)(i.li,{children:"Debian"}),"\n",(0,s.jsx)(i.li,{children:"Rockylinux"}),"\n",(0,s.jsx)(i.li,{children:"Ubuntu"}),"\n"]})]})}function h(e={}){const{wrapper:i}={...(0,a.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>r,x:()=>o});var s=n(96540);const a={},t=s.createContext(a);function r(e){const i=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function o(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(t.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5cc619f0.afd68d1a.js b/assets/js/5cc619f0.afd68d1a.js new file mode 100644 index 0000000000..aa62f5ee58 --- /dev/null +++ b/assets/js/5cc619f0.afd68d1a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9648],{41927:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>C,contentTitle:()=>y,default:()=>I,frontMatter:()=>f,metadata:()=>S,toc:()=>T});var s=i(74848),t=i(28453),l=i(96540),a=i(17632),r=i(97950),o=i(11244),c=i(38680),d=i(95257);const h="link_wr7g",u="button_gV6k",m=e=>{const{title:n,href:i,handleClick:t}=e;return(0,s.jsx)("a",{className:h,href:i,children:(0,s.jsx)("button",{onClick:t,className:u,children:n})})},p="modal__zVM",g="modalContent_zbmJ",x="modalTitle_u975",j="modalDescription_H8cB",b="modalH2_DhYb",v="buttonBox_NbRn",k=e=>{const{calendarEvent:n,onClose:i,show:t}=e;return(0,s.jsx)(s.Fragment,{children:t&&n&&(0,s.jsx)("div",{className:p,onClick:i,children:(0,s.jsxs)("div",{className:g,children:[(0,s.jsx)("div",{className:x,children:(0,s.jsx)("h2",{className:b,children:n.title})}),(0,s.jsxs)("div",{className:j,children:[(0,s.jsx)("p",{children:n.extendedProps.description}),(0,s.jsx)("p",{children:n.extendedProps.location}),(0,s.jsx)("div",{className:v,children:(0,s.jsx)(m,{handleClick:e=>{e.stopPropagation()},title:"Join Meeting",href:n.extendedProps.location})})]})]})})})},w=()=>{const[e,n]=(0,l.useState)(!1),[i,t]=(0,l.useState)();return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(a.A,{slotDuration:"00:15:00",slotMinTime:"09:00:00",slotMaxTime:"18:00:00",navLinks:!0,nowIndicator:!0,height:"auto",expandRows:!1,eventClick:i=>(i=>{n(!e),t(i.event)})(i),plugins:[r.A,o.A,d.A,c.Ay],initialView:"timeGridWeek",weekends:!1,events:{url:"https://sovereigncloudstack.github.io/calendar/scs.ics",format:"ics"},headerToolbar:{left:"prev,next today",center:"title",right:"timeGridDay,timeGridWeek,dayGridMonth"}}),(0,s.jsx)("div",{children:(0,s.jsx)(k,{show:e,calendarEvent:i,onClose:()=>n(!1)})})]})},f={},y="Collaboration",S={id:"collaboration/index",title:"Collaboration",description:"We\u2019re an open community",source:"@site/community/collaboration/index.mdx",sourceDirName:"collaboration",slug:"/collaboration/",permalink:"/community/collaboration/",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Mission Statement",permalink:"/community/mission-statement"},next:{title:"Team Iaas",permalink:"/community/collaboration/team-iaas"}},C={},T=[{value:"We\u2019re an open community",id:"were-an-open-community",level:2},{value:"Collaborating with issues and pull requests",id:"collaborating-with-issues-and-pull-requests",level:2},{value:"Meetings",id:"meetings",level:2},{value:"Project updates",id:"project-updates",level:3},{value:"Sprint review/Backlog refinement/Sprint planning meetings",id:"sprint-reviewbacklog-refinementsprint-planning-meetings",level:3},{value:"Special interest groups (SIGs) and hacking sessions",id:"special-interest-groups-sigs-and-hacking-sessions",level:3}];function G(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"collaboration",children:"Collaboration"}),"\n",(0,s.jsx)(n.h2,{id:"were-an-open-community",children:"We\u2019re an open community"}),"\n",(0,s.jsxs)(n.p,{children:["Our meetings are publicly announced and we are happy to welcome both newcomers and established members alike. You can navigate either through the calendar below or subscribe with your favorite client to ",(0,s.jsx)(n.a,{href:"https://sovereigncloudstack.github.io/calendar/scs.ics",children:"https://sovereigncloudstack.github.io/calendar/scs.ics"}),". The calendar is collaboratively maintained on GitHub and new entries, such as a lightning talk, are highly appreciated!"]}),"\n",(0,s.jsx)(w,{}),"\n",(0,s.jsx)(n.h2,{id:"collaborating-with-issues-and-pull-requests",children:"Collaborating with issues and pull requests"}),"\n",(0,s.jsxs)(n.p,{children:["We use the GitHub flow to track and discuss changes in issues, then propose and\nreview changes in pull requests. See the\n",(0,s.jsx)(n.a,{href:"https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests",children:"GitHub documentation"}),"\nfor more details."]}),"\n",(0,s.jsx)(n.h2,{id:"meetings",children:"Meetings"}),"\n",(0,s.jsx)(n.h3,{id:"project-updates",children:"Project updates"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Weekly with all teams on Thursday at 15:05 CEST (40 mins)"}),"\n",(0,s.jsx)(n.li,{children:"In some weeks we schedule an additional lightning talk at 15:40 CEST"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"sprint-reviewbacklog-refinementsprint-planning-meetings",children:"Sprint review/Backlog refinement/Sprint planning meetings"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Weekly Team meetings (~1hr) for currently 4 teams:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Team IaaS"}),"\n",(0,s.jsx)(n.li,{children:"Team Container"}),"\n",(0,s.jsx)(n.li,{children:"Team IAM & Security"}),"\n",(0,s.jsx)(n.li,{children:"Team Operations"}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:"Please refer to the public calendar above for details."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"special-interest-groups-sigs-and-hacking-sessions",children:"Special interest groups (SIGs) and hacking sessions"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["There are a number of SIG meetings and hacking sessions that meet weekly or bi-weekly","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"SIG Monitoring and Logging"}),"\n",(0,s.jsx)(n.li,{children:"SIG Standardization and Certification"}),"\n",(0,s.jsx)(n.li,{children:"SIG Documentation"}),"\n",(0,s.jsx)(n.li,{children:"SIG Community"}),"\n",(0,s.jsx)(n.li,{children:"SIG Central API"}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:"Please refer to the public calendar above for details."}),"\n"]})]})}function I(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(G,{...e})}):G(e)}}}]); \ No newline at end of file diff --git a/assets/js/5d503a86.a360d6a7.js b/assets/js/5d503a86.a360d6a7.js new file mode 100644 index 0000000000..71cde6fc79 --- /dev/null +++ b/assets/js/5d503a86.a360d6a7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8777],{57946:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>s,metadata:()=>a,toc:()=>d});var o=n(74848),i=n(28453);const s={},r="SCS automated pentesting",a={id:"operating-scs/components/automated-pentesting/overview",title:"SCS automated pentesting",description:"Security has a high priority in modern cloud infrastructures. If you look at it from an automation perspective, a basic distinction of tooling is needed to be considered:",source:"@site/docs/04-operating-scs/components/automated-pentesting/overview.md",sourceDirName:"04-operating-scs/components/automated-pentesting",slug:"/operating-scs/components/automated-pentesting/overview",permalink:"/docs/operating-scs/components/automated-pentesting/overview",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/automated-pentesting/overview.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Automated Pentesting",permalink:"/docs/category/automated-pentesting"},next:{title:"Tools Description",permalink:"/docs/operating-scs/components/automated-pentesting/tools"}},c={},d=[{value:"Source",id:"source",level:2},{value:"Tools",id:"tools",level:2}];function u(e){const t={a:"a",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"scs-automated-pentesting",children:"SCS automated pentesting"}),"\n",(0,o.jsx)(t.p,{children:"Security has a high priority in modern cloud infrastructures. If you look at it from an automation perspective, a basic distinction of tooling is needed to be considered:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"SAST or Static Application Security Testing: These tools scan code that is checked into e.g. git and are integrated into build pipelines. They only look at static artifacts: code, dependencies, container images."}),"\n",(0,o.jsx)(t.li,{children:"DAST or Dynamic Application Security Testing: With dynamic testing, running programs and deployed infrastructure are scanned. This allows to identify vulnerabilities, test infrastructure configuration and analyze the behaviour of running processes."}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"In this project, the SCS automated pentesting pipeline, we solely focus on DAST."}),"\n",(0,o.jsx)(t.h2,{id:"source",children:"Source"}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/security-infra-scan-pipeline",children:"github.com/SovereignCloudStack/security-infra-scan-pipeline"}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"tools",children:"Tools"}),"\n",(0,o.jsxs)(t.p,{children:["See ",(0,o.jsx)(t.a,{href:"/docs/operating-scs/components/automated-pentesting/tools",children:"the tools page"}),"."]})]})}function p(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var o=n(96540);const i={},s=o.createContext(i);function r(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5d54de92.3925fe91.js b/assets/js/5d54de92.3925fe91.js new file mode 100644 index 0000000000..780884b863 --- /dev/null +++ b/assets/js/5d54de92.3925fe91.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7299],{88366:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>t,metadata:()=>d,toc:()=>l});var o=s(74848),i=s(28453);const t={sidebar_label:"Ceph"},r="Ceph",d={id:"iaas/guides/operations-guide/ceph",title:"Ceph",description:"Where to find docs",source:"@site/docs/02-iaas/guides/operations-guide/ceph.md",sourceDirName:"02-iaas/guides/operations-guide",slug:"/iaas/guides/operations-guide/ceph",permalink:"/docs/iaas/guides/operations-guide/ceph",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/ceph.md",tags:[],version:"current",frontMatter:{sidebar_label:"Ceph"},sidebar:"docs",previous:{title:"Task",permalink:"/docs/iaas/guides/operations-guide/manager/task"},next:{title:"Infrastructure",permalink:"/docs/iaas/guides/operations-guide/infrastructure"}},a={},l=[{value:"Where to find docs",id:"where-to-find-docs",level:2},{value:"Advice on Ceph releases",id:"advice-on-ceph-releases",level:2},{value:"General maintenance",id:"general-maintenance",level:2},{value:"60 seconds cluster overview",id:"60-seconds-cluster-overview",level:3},{value:"Mute/Unmute a health warning",id:"muteunmute-a-health-warning",level:3},{value:"Disable/Enable (deep-)scrubbing",id:"disableenable-deep-scrubbing",level:3},{value:"Reboot a single node",id:"reboot-a-single-node",level:3},{value:"Gathering information about block devices",id:"gathering-information-about-block-devices",level:2},{value:"Enumerate typical storage devices and LVM",id:"enumerate-typical-storage-devices-and-lvm",level:3},{value:"SMART data for SATA/SAS and NVME devices",id:"smart-data-for-satasas-and-nvme-devices",level:3},{value:"Check format of a NVME device",id:"check-format-of-a-nvme-device",level:3},{value:"Format a NVME device to a different LBA format using nvme-cli",id:"format-a-nvme-device-to-a-different-lba-format-using-nvme-cli",level:3},{value:"Secure Erase a NVME drive using nvme-cli",id:"secure-erase-a-nvme-drive-using-nvme-cli",level:3},{value:"Secure Erase a SATA/SAS drive using hdparm",id:"secure-erase-a-satasas-drive-using-hdparm",level:3},{value:"OSD maintenance tasks",id:"osd-maintenance-tasks",level:2},{value:"Locate a specific OSD in the cluster",id:"locate-a-specific-osd-in-the-cluster",level:3},{value:"Get OSD metadata (global and single OSD)",id:"get-osd-metadata-global-and-single-osd",level:3},{value:"Add a new OSD",id:"add-a-new-osd",level:3},{value:"Replace a defect OSD",id:"replace-a-defect-osd",level:3},{value:"Remove a OSD",id:"remove-a-osd",level:3},{value:"Manual way",id:"manual-way",level:4},{value:"Remove a single OSD node",id:"remove-a-single-osd-node",level:3},{value:"Remove an OSD (temporarily e.g. when replacing a broken disk)",id:"remove-an-osd-temporarily-eg-when-replacing-a-broken-disk",level:3},{value:"Disable backfills/recovery completely",id:"disable-backfillsrecovery-completely",level:3},{value:"Rebalance OSDs",id:"rebalance-osds",level:3},{value:"Placement Group maintenance",id:"placement-group-maintenance",level:2},{value:"Dump placement groups",id:"dump-placement-groups",level:3},{value:"Query a PG about its status",id:"query-a-pg-about-its-status",level:3},{value:"Start (deep-)scrubbing of a placement group",id:"start-deep-scrubbing-of-a-placement-group",level:3},{value:"HEALTH_WARN - Large omap objects found...",id:"health_warn---large-omap-objects-found",level:3},{value:"Instruct a PG to repair in case of scrub errors (inconsistent PG)",id:"instruct-a-pg-to-repair-in-case-of-scrub-errors-inconsistent-pg",level:3},{value:"RADOS Pool maintenance",id:"rados-pool-maintenance",level:2},{value:"Get pools and their configuration",id:"get-pools-and-their-configuration",level:3},{value:"Dump all CRUSH rules",id:"dump-all-crush-rules",level:3},{value:"Get autoscaler status",id:"get-autoscaler-status",level:3},{value:"Create a replicated pool",id:"create-a-replicated-pool",level:3},{value:"Enabling an application on a pool",id:"enabling-an-application-on-a-pool",level:3},{value:"Delete a pool",id:"delete-a-pool",level:3},{value:"Set number of PGs for a pool",id:"set-number-of-pgs-for-a-pool",level:3},{value:"Create CRUSH rules for different storage classes",id:"create-crush-rules-for-different-storage-classes",level:3},{value:"Change CRUSH rule for a pool ("move pool")",id:"change-crush-rule-for-a-pool-move-pool",level:3},{value:"Advanced topics",id:"advanced-topics",level:2},{value:"Validating Ceph using OSISM playbooks",id:"validating-ceph-using-osism-playbooks",level:3},{value:"Shutdown a Ceph cluster",id:"shutdown-a-ceph-cluster",level:3},{value:"Restart a Ceph cluster after manual shutdown",id:"restart-a-ceph-cluster-after-manual-shutdown",level:3},{value:"Performance benchmark",id:"performance-benchmark",level:2},{value:"Where and how to get further help",id:"where-and-how-to-get-further-help",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"ceph",children:"Ceph"}),"\n",(0,o.jsx)(n.h2,{id:"where-to-find-docs",children:"Where to find docs"}),"\n",(0,o.jsxs)(n.p,{children:["The official Ceph documentation is located on ",(0,o.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/",children:"https://docs.ceph.com/en/latest/rados/operations/"})]}),"\n",(0,o.jsxs)(n.p,{children:["It is ",(0,o.jsx)(n.strong,{children:"strongly advised"})," to use the documentation for the version being used."]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Pacific - ",(0,o.jsx)(n.a,{href:"https://docs.ceph.com/en/pacific/rados/operations/",children:"https://docs.ceph.com/en/pacific/rados/operations/"})]}),"\n",(0,o.jsxs)(n.li,{children:["Quincy - ",(0,o.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/rados/operations/",children:"https://docs.ceph.com/en/quincy/rados/operations/"})]}),"\n",(0,o.jsxs)(n.li,{children:["Reef - ",(0,o.jsx)(n.a,{href:"https://docs.ceph.com/en/reef/rados/operations/",children:"https://docs.ceph.com/en/reef/rados/operations/"})]}),"\n"]}),"\n",(0,o.jsxs)(n.admonition,{type:"note",children:[(0,o.jsxs)(n.p,{children:["Do not take information in the documentation at face value.\nEspecially when it comes to advanced/rarely used/very new features it is ",(0,o.jsx)(n.strong,{children:"strongly advised"}),"\nto test any claims made in the documentation about any particular feature."]}),(0,o.jsx)(n.p,{children:"Never assume that things will work as written without actually testing it on a test setup\nas close to your real workload scenario as possible."})]}),"\n",(0,o.jsx)(n.h2,{id:"advice-on-ceph-releases",children:"Advice on Ceph releases"}),"\n",(0,o.jsxs)(n.p,{children:["The current Ceph releases and their support status can be found on ",(0,o.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/releases/",children:"https://docs.ceph.com/en/latest/releases/"})]}),"\n",(0,o.jsxs)(n.p,{children:["When a new Ceph stable version is released you are ",(0,o.jsx)(n.strong,{children:"strongly advised"}),"\nto not roll it out on any production cluster whatsoever.\nEven though its listed as \"stable\" it doesn't mean that this is actually true.\nEspecially avoid using .0 releases on anything remotely production\nunless you really, really now what you're doing and can live with a possible catastrophic failure."]}),"\n",(0,o.jsxs)(n.p,{children:["Be ",(0,o.jsx)(n.strong,{children:"very"})," conservative about what version you run on production systems."]}),"\n",(0,o.jsx)(n.p,{children:"Shiny new features aren't worth the risk of total or partial data loss/corruption."}),"\n",(0,o.jsx)(n.h2,{id:"general-maintenance",children:"General maintenance"}),"\n",(0,o.jsx)(n.h3,{id:"60-seconds-cluster-overview",children:"60 seconds cluster overview"}),"\n",(0,o.jsx)(n.p,{children:"The following commands can be used to quickly check the status of Ceph:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Print overall cluster status"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph -s\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Print detailed health information"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph health detail\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Display current OSD tree"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph osd tree\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Cluster storage usage by pool and storage class"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph df\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"List pools with detailed configuration"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph osd pool ls detail\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Get usage stats for OSDs"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph osd df {plain|tree} {class e.g. hdd|ssd}\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Watch Ceph health messages sequentially"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph -w\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"List daemon versions running in the cluster"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph versions\n"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"Also you can run the following on each node running ceph-daemons,\nto provide further debug information about the environment:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# lscpu\n# cat /proc/cpuinfo # if lscpu isn't available\n# free -g\n# ip l\n# ethtool <device> # for each network adapter\n"})}),"\n",(0,o.jsx)(n.h3,{id:"muteunmute-a-health-warning",children:"Mute/Unmute a health warning"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph health mute <what> <duration>\n$ ceph health unmute <what>\n"})}),"\n",(0,o.jsx)(n.h3,{id:"disableenable-deep-scrubbing",children:"Disable/Enable (deep-)scrubbing"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd set noscrub\n$ ceph osd set nodeep-scrub\n$ ceph osd unset noscrub\n$ ceph osd unset nodeep-scrub\n"})}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsx)(n.p,{children:"Use this sparingly only in emergency situations.\nSetting these flags will cause a HEALTH_WARN status,\nincrease risk of data corruption and also the risk of generating\na HEALTH_WARN due to PGs not being (deep-)scrubbed in time."})}),"\n",(0,o.jsx)(n.h3,{id:"reboot-a-single-node",children:"Reboot a single node"}),"\n",(0,o.jsxs)(n.p,{children:["The traditional way of doing this is by setting the ",(0,o.jsx)(n.code,{children:"noout"})," flag,\ndo the appropriate maintenance work and after the node is back online\nunset the flag like so:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph osd set noout\n"})}),"\n",(0,o.jsx)(n.p,{children:"After maintenance is done and host is back up:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph osd unset noout\n"})}),"\n",(0,o.jsx)(n.p,{children:"On versions Luminous or above you can set the flag individually for single\nOSDs or entire CRUSH buckets, which can be a safer option in case of prolonged\nmaintenance periods."}),"\n",(0,o.jsx)(n.p,{children:"Add noout for a OSD:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph osd add-noout osd.<ID>\n"})}),"\n",(0,o.jsx)(n.p,{children:"Remove noout for a OSD:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph osd rm-noout osd.<ID>\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Add noout for CRUSH bucket (e.g. host name as seen in ",(0,o.jsx)(n.code,{children:"ceph osd tree"}),"):"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph osd set-group noout <crush-bucket-name>\n"})}),"\n",(0,o.jsx)(n.p,{children:"Remove noout for CRUSH bucket:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ceph osd unset-group noout <crush-bucket-name>\n"})}),"\n",(0,o.jsx)(n.h2,{id:"gathering-information-about-block-devices",children:"Gathering information about block devices"}),"\n",(0,o.jsx)(n.h3,{id:"enumerate-typical-storage-devices-and-lvm",children:"Enumerate typical storage devices and LVM"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# lsblk\n# lsblk -S\n# lsscsi\n# nvme list\n# pvs\n# vgs\n# lvs\n"})}),"\n",(0,o.jsx)(n.h3,{id:"smart-data-for-satasas-and-nvme-devices",children:"SMART data for SATA/SAS and NVME devices"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# smartctl -a /dev/sdX\n# nvme smart-log /dev/nvmeXnY\n"})}),"\n",(0,o.jsx)(n.h3,{id:"check-format-of-a-nvme-device",children:"Check format of a NVME device"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# nvme id-ns -H /dev/nvmeXnY\n"})}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsx)(n.p,{children:'Check the last lines named "LBA Format".\nIt will show which formats are supported,\nwhich format is in use and which format offers the best performance\naccording to the vendor.'})}),"\n",(0,o.jsx)(n.h3,{id:"format-a-nvme-device-to-a-different-lba-format-using-nvme-cli",children:"Format a NVME device to a different LBA format using nvme-cli"}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsx)(n.p,{children:"This will destroy all data on the device!"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# nvme format --lbaf=<id> /dev/nvmeXnY\n"})}),"\n",(0,o.jsx)(n.h3,{id:"secure-erase-a-nvme-drive-using-nvme-cli",children:"Secure Erase a NVME drive using nvme-cli"}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsx)(n.p,{children:"This will destroy all data on the device!"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# nvme format -s2 /dev/nvmeXnY\n# blkdiscard /dev/nvmeXnY\n# nvme format -s1 /dev/nvmeXnY\n"})}),"\n",(0,o.jsx)(n.h3,{id:"secure-erase-a-satasas-drive-using-hdparm",children:"Secure Erase a SATA/SAS drive using hdparm"}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsx)(n.p,{children:"This will destroy all data on the device!"})}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Gather device info:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# hdparm -I /dev/sdX\n"})}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Check that the output says ",(0,o.jsx)(n.strong,{children:'"not frozen"'})," and ",(0,o.jsx)(n.strong,{children:'"not locked"'}),",\nalso it should list support for enhanced erase and list time estimates\nfor ",(0,o.jsx)(n.strong,{children:"SECURITY ERASE UNIT"})," and/or ",(0,o.jsx)(n.strong,{children:"ENHANCED SECURITY ERASE UNIT"})]}),"\n",(0,o.jsxs)(n.ol,{start:"2",children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Set a master password for the disk (required, will be automatically removed after wipe)"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# hdparm --user-master wipeit --security-set-pass wipeit /dev/sdX\n# hdparm -I /dev/sdX\n"})}),"\n",(0,o.jsxs)(n.p,{children:['Check that "Security level" is now ',(0,o.jsx)(n.strong,{children:'"high"'})," and master password is now\n",(0,o.jsx)(n.strong,{children:'"enabled"'})," instead of ",(0,o.jsx)(n.strong,{children:'"not enabled"'})," before"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Wipe the device"}),"\n",(0,o.jsx)(n.p,{children:"If device supports enhanced security erase (better), use the following:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# hdparm --user-master wipeit --security-erase-enhanced wipeit /dev/sdX\n"})}),"\n",(0,o.jsx)(n.p,{children:"If not, use standard security erase:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# hdparm --user-master wipeit --security-erase wipeit /dev/sdX\n"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:['On some systems the system firmware might "freeze" the device,\nwhich makes it impossible to issue a secure erase or reformat the device.\nIn that case it might be necessary to either "unfreeze" the drive or\nto install the drive in another system where it can be unfrozen.\nAlso make sure that the device is ',(0,o.jsx)(n.em,{children:"actually"})," wiped. Its recommended to\nat least perform a blanking pass on HDDs with a tool like nwipe."]})}),"\n",(0,o.jsx)(n.h2,{id:"osd-maintenance-tasks",children:"OSD maintenance tasks"}),"\n",(0,o.jsx)(n.h3,{id:"locate-a-specific-osd-in-the-cluster",children:"Locate a specific OSD in the cluster"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd find osd.<ID>\n"})}),"\n",(0,o.jsx)(n.h3,{id:"get-osd-metadata-global-and-single-osd",children:"Get OSD metadata (global and single OSD)"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd metadata\n$ ceph osd metadata osd.<ID>\n"})}),"\n",(0,o.jsx)(n.p,{children:"Interesting fields:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"bluefs_db_rotational"}),"\n",(0,o.jsx)(n.li,{children:"bluefs_dedicated_db"}),"\n",(0,o.jsx)(n.li,{children:"bluefs_dedicated_wal"}),"\n",(0,o.jsx)(n.li,{children:"bluefs_wal_rotational"}),"\n",(0,o.jsx)(n.li,{children:"bluestore_bdev_rotational"}),"\n",(0,o.jsx)(n.li,{children:"device_ids"}),"\n",(0,o.jsx)(n.li,{children:"device_paths"}),"\n",(0,o.jsx)(n.li,{children:"devices"}),"\n",(0,o.jsx)(n.li,{children:"hostname"}),"\n",(0,o.jsx)(n.li,{children:"osd_objectstore"}),"\n",(0,o.jsx)(n.li,{children:"rotational"}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"add-a-new-osd",children:"Add a new OSD"}),"\n",(0,o.jsx)(n.h3,{id:"replace-a-defect-osd",children:"Replace a defect OSD"}),"\n",(0,o.jsx)(n.h3,{id:"remove-a-osd",children:"Remove a OSD"}),"\n",(0,o.jsx)(n.p,{children:"As with \u2018Remove a single OSD node\u2019. Except that the steps are only executed\nfor a single OSD and the node is not removed from the CRUSH map and the inventory.\nOnly the entries relating to the removed OSD are removed from the host vars."}),"\n",(0,o.jsx)(n.h4,{id:"manual-way",children:"Manual way"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd crush reweight osd.<ID> 0.0\n# Wait for rebalance to complete...\n$ ceph osd out osd.<ID>\n# systemctl stop ceph-osd@<ID>\n# systemctl disable ceph-osd@<ID>\n$ ceph osd purge osd.<ID> --yes-i-really-mean-it\n"})}),"\n",(0,o.jsx)(n.p,{children:"The LV and VG defined in the inventory for this OSD must also be removed. The\nOSD itself should be wiped."}),"\n",(0,o.jsx)(n.h3,{id:"remove-a-single-osd-node",children:"Remove a single OSD node"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Get all OSDs of the node"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd tree\nID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF\n-1 0.11691 root default\n-3 0.03897 host testbed-node-0\n 0 hdd 0.01949 osd.0 up 1.00000 1.00000\n 4 hdd 0.01949 osd.4 up 1.00000 1.00000\n-5 0.03897 host testbed-node-1\n 1 hdd 0.01949 osd.1 up 1.00000 1.00000\n 3 hdd 0.01949 osd.3 up 1.00000 1.00000\n-7 0.03897 host testbed-node-2\n 2 hdd 0.01949 osd.2 up 1.00000 1.00000\n 5 hdd 0.01949 osd.5 up 1.00000 1.00000\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Reduce the weighting of all OSDs on the node to 0. Do this for each OSD\nin a row and wait after each adjustment until the Ceph cluster is balanced.\nDepending on how large the Ceph cluster and the individual OSDs are, this\nmay take some time."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd crush reweight osd.2 0.0\n$ ceph osd crush reweight osd.5 0.0\n"})}),"\n",(0,o.jsx)(n.p,{children:"The Ceph OSDs that are to be removed then have a weight of 0."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd tree\nID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF\n-1 0.07794 root default\n-3 0.03897 host testbed-node-0\n 0 hdd 0.01949 osd.0 up 1.00000 1.00000\n 4 hdd 0.01949 osd.4 up 1.00000 1.00000\n-5 0.03897 host testbed-node-1\n 1 hdd 0.01949 osd.1 up 1.00000 1.00000\n 3 hdd 0.01949 osd.3 up 1.00000 1.00000\n-7 0 host testbed-node-2\n 2 hdd 0 osd.2 up 1.00000 1.00000\n 5 hdd 0 osd.5 up 1.00000 1.00000\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Remove the OSDs and everything that belongs to them from the node.\nThis is a disruptive action that cannot be undone. The devices used\nare also reset."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ osism apply ceph-shrink-osd -e ireallymeanit=yes -e osd_to_kill=2,5\n"})}),"\n",(0,o.jsx)(n.p,{children:"All OSDs were removed."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd tree\nID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF\n-1 0.07794 root default\n-3 0.03897 host testbed-node-0\n 0 hdd 0.01949 osd.0 up 1.00000 1.00000\n 4 hdd 0.01949 osd.4 up 1.00000 1.00000\n-5 0.03897 host testbed-node-1\n 1 hdd 0.01949 osd.1 up 1.00000 1.00000\n 3 hdd 0.01949 osd.3 up 1.00000 1.00000\n-7 0 host testbed-node-2\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Remove the node from the CRUSH map."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd crush remove testbed-node-2\nremoved item id -7 name 'testbed-node-2' from crush map\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Remove the node from all Ceph groups in the inventory."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Remove all Ceph-specific parameters from the host vars of the node from the\ninventory"}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"remove-an-osd-temporarily-eg-when-replacing-a-broken-disk",children:"Remove an OSD (temporarily e.g. when replacing a broken disk)"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd out osd.<ID>\n# systemctl stop ceph-osd@<ID>\n# systemctl disable ceph-osd@<ID>\n"})}),"\n",(0,o.jsx)(n.h3,{id:"disable-backfillsrecovery-completely",children:"Disable backfills/recovery completely"}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsx)(n.p,{children:"Use only in emergency situations!"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd set nobackfill\n$ ceph osd set norecovery\n$ ceph osd set norebalance\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Unset the flags with ",(0,o.jsx)(n.code,{children:"ceph osd unset <flag>"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"rebalance-osds",children:"Rebalance OSDs"}),"\n",(0,o.jsx)(n.h2,{id:"placement-group-maintenance",children:"Placement Group maintenance"}),"\n",(0,o.jsx)(n.h3,{id:"dump-placement-groups",children:"Dump placement groups"}),"\n",(0,o.jsx)(n.p,{children:"Usually only useful when parsing it, so here are two ways to get the data:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph pg dump\n$ ceph pg dump --format=json-pretty\n"})}),"\n",(0,o.jsx)(n.h3,{id:"query-a-pg-about-its-status",children:"Query a PG about its status"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph pg <pgid> query\n"})}),"\n",(0,o.jsx)(n.h3,{id:"start-deep-scrubbing-of-a-placement-group",children:"Start (deep-)scrubbing of a placement group"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph pg scrub <pgid>\n$ ceph pg deep-scrub <pgid>\n"})}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsx)(n.p,{children:"Instructing a PG to (deep-)scrub does not mean that it will do so immediately,\nit can take some time for the scrub to start."})}),"\n",(0,o.jsx)(n.h3,{id:"health_warn---large-omap-objects-found",children:"HEALTH_WARN - Large omap objects found..."}),"\n",(0,o.jsx)(n.p,{children:"Finding PGs which have large OMAP objects:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# ceph pg dump --format=json | jq '.pg_map.pg_stats[] |\nselect(.stat_sum.num_large_omap_objects != 0) |\n(.pgid, .stat_sum.num_large_omap_objects, .up, .acting)'\n"})}),"\n",(0,o.jsxs)(n.p,{children:["(Remove the line breaks between the single quotes or ",(0,o.jsx)(n.code,{children:"jq"})," might act weird!)"]}),"\n",(0,o.jsxs)(n.p,{children:["This will dump all PG IDs with large OMAP objects and their up/acting OSDs.\nYou then can grep the logs of these OSDs for ",(0,o.jsx)(n.strong,{children:'"Large omap object"'}),"\nto find the actual objects causing the health warning."]}),"\n",(0,o.jsx)(n.p,{children:"Also the PG ID before the dot is equal to the pool ID it belongs to."}),"\n",(0,o.jsx)(n.p,{children:"In case the logs have been rotated, instruct those OSDs to do a deep-scrub\nand watch the logs for the message to appear."}),"\n",(0,o.jsx)(n.p,{children:"From there you can investigate the issue further,\nmostly it'll be due to the index of a RGW bucket getting too big due to too many objects,\nthus resharding that bucket's index will be necessary."}),"\n",(0,o.jsx)(n.h3,{id:"instruct-a-pg-to-repair-in-case-of-scrub-errors-inconsistent-pg",children:"Instruct a PG to repair in case of scrub errors (inconsistent PG)"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph pg repair <pgid>\n"})}),"\n",(0,o.jsxs)(n.admonition,{type:"note",children:[(0,o.jsxs)(n.p,{children:["Recovery might not start immediately and might take some time.\nYou can query the status of the recovery through ",(0,o.jsx)(n.code,{children:"ceph pg <pgid> query"}),".\nBe sure to read the Ceph manual about this topic ",(0,o.jsx)(n.em,{children:"thoroughly"}),":"]}),(0,o.jsx)(n.p,{children:(0,o.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshooting-pg/",children:"https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshooting-pg/"})})]}),"\n",(0,o.jsx)(n.h2,{id:"rados-pool-maintenance",children:"RADOS Pool maintenance"}),"\n",(0,o.jsxs)(n.admonition,{type:"note",children:[(0,o.jsx)(n.p,{children:"Read the RADOS pool operations documentation in detail before playing around with pools.\nEspecially when considering making changes to the CRUSH map.\nWrong decisions there can lead to data loss or other catastrophic failures."}),(0,o.jsx)(n.p,{children:(0,o.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/pools/",children:"https://docs.ceph.com/en/latest/rados/operations/pools/"})})]}),"\n",(0,o.jsx)(n.h3,{id:"get-pools-and-their-configuration",children:"Get pools and their configuration"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd pool ls detail\n"})}),"\n",(0,o.jsx)(n.h3,{id:"dump-all-crush-rules",children:"Dump all CRUSH rules"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd crush rule dump\n"})}),"\n",(0,o.jsx)(n.h3,{id:"get-autoscaler-status",children:"Get autoscaler status"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd pool autoscale-status\n"})}),"\n",(0,o.jsx)(n.h3,{id:"create-a-replicated-pool",children:"Create a replicated pool"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd pool create <pool_name> <pg_num> <pgp_num> replicated [<crush_rule_name>]\n"})}),"\n",(0,o.jsx)(n.h3,{id:"enabling-an-application-on-a-pool",children:"Enabling an application on a pool"}),"\n",(0,o.jsx)(n.p,{children:"Required, otherwise a health warning will be raised after some time."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd pool application enable <pool_name> <application_name> # Syntax\n$ ceph osd pool application enable cinder rbd # Example\n"})}),"\n",(0,o.jsx)(n.p,{children:"Typical application names are: rbd, rgw, cephfs"}),"\n",(0,o.jsx)(n.h3,{id:"delete-a-pool",children:"Delete a pool"}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsx)(n.p,{children:"This will delete all data in that pool. There is no undo/undelete."})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd pool delete <pool_name> <pool_name> --yes-i-really-really-mean-it\n"})}),"\n",(0,o.jsxs)(n.admonition,{type:"note",children:[(0,o.jsxs)(n.p,{children:["In order to be able to delete pools, it has to be enabled on the monitors\nby setting the ",(0,o.jsx)(n.code,{children:"mon_allow_pool_delete"})," flag to true. Default is false."]}),(0,o.jsxs)(n.p,{children:["See: ",(0,o.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/configuration/mon-config-ref",children:"https://docs.ceph.com/en/latest/rados/configuration/mon-config-ref"})]})]}),"\n",(0,o.jsx)(n.h3,{id:"set-number-of-pgs-for-a-pool",children:"Set number of PGs for a pool"}),"\n",(0,o.jsx)(n.p,{children:"If no autoscaling of PGs is used, it is very important to adapt the PGs per pool to the\nreal world when operating a Ceph cluster. If, for example, OSDs are exchanged, added, new\nnodes are added, etc., the number of PGs must also be taken into account."}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/pgcalc/",children:"PG Calc Tool"})," can be used\nto calculate a reasonable number of PGs per pool depending on all ODSs and pools."]}),"\n",(0,o.jsxs)(n.p,{children:["Further information on placement groups can be found in the\n",(0,o.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/operations/placement-groups/",children:"Ceph documentation"}),".\nYou should definitely read ",(0,o.jsx)(n.em,{children:"FACTORS RELEVANT TO SPECIFYING PG_NUM"})," and ",(0,o.jsx)(n.em,{children:"CHOOSING THE NUMBER OF PGS"}),"\nthere."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd pool set <poolname> pg_num <num_pgs>\n"})}),"\n",(0,o.jsxs)(n.admonition,{type:"note",children:[(0,o.jsx)(n.p,{children:"Num PGs must be a power of two! Be careful about changing number of PGs.\nChanging pg_num to a new value will gradually increase pgp_num on newer versions of Ceph."}),(0,o.jsx)(n.p,{children:"In older versions one also has to set pgp_num manually, either in increments or in one big leap."})]}),"\n",(0,o.jsx)(n.h3,{id:"create-crush-rules-for-different-storage-classes",children:"Create CRUSH rules for different storage classes"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd crush rule create-replicated replicated_hdd default host hdd\n$ ceph osd crush rule create-replicated replicated_ssd default host ssd\n$ ceph osd crush rule create-replicated replicated_nvme default host nvme\n"})}),"\n",(0,o.jsx)(n.h3,{id:"change-crush-rule-for-a-pool-move-pool",children:'Change CRUSH rule for a pool ("move pool")'}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd pool set <poolname> crush_rule <rule_name>\n"})}),"\n",(0,o.jsx)(n.p,{children:"This can be used to move a pool from e.g. HDD to SSD or NVME class\nor anything else that the new CRUSH rule specifies."}),"\n",(0,o.jsx)(n.h2,{id:"advanced-topics",children:"Advanced topics"}),"\n",(0,o.jsx)(n.h3,{id:"validating-ceph-using-osism-playbooks",children:"Validating Ceph using OSISM playbooks"}),"\n",(0,o.jsxs)(n.p,{children:["For Ceph, special playbooks were added to validate the deployment status of\nthe OSD, MON and MGR services. The commands for use are ",(0,o.jsx)(n.code,{children:"osism validate ceph-osds"}),",\n",(0,o.jsx)(n.code,{children:"osism validate ceph-mons"}),", and ",(0,o.jsx)(n.code,{children:"osism validate ceph-mgrs"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["These playbooks will validate that the deployed Ceph environment matches\nthe configuration and is overall in a healthy state. The playbooks will\ngenerate report files in JSON format on the first manager node in ",(0,o.jsx)(n.code,{children:"/opt/reports/validator"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"shutdown-a-ceph-cluster",children:"Shutdown a Ceph cluster"}),"\n",(0,o.jsx)(n.p,{children:"In order to fully shutdown a Ceph cluster safely, you first do the following steps:"}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsx)(n.p,{children:"Take GOOD NOTES of the unit names and OSD IDs running on each node.\nYou will need them to restart the cluster later."})}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Stop the workload that is using the cluster"}),"\n",(0,o.jsx)(n.p,{children:"This will vary depending on your environment and is not covered here."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Pause/Stop operations on the cluster by setting flags"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd set noout\n$ ceph osd set nobackfill\n$ ceph osd set norecover\n$ ceph osd set norebalance\n$ ceph osd set nodown\n$ ceph osd set pause\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Stop and disable the ",(0,o.jsx)(n.code,{children:"radosgw"})," services on all nodes (on each rgw node) (if RGW is used)"]}),"\n",(0,o.jsx)(n.p,{children:"Get the name of the unit (globs not supported for disable) and\nmake a note of the unit name for that node:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl | grep ceph-radosgw\n"})}),"\n",(0,o.jsx)(n.p,{children:"Then disable and stop the unit:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl disable --now ceph-radosgw@<name>.service\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Stop all CephFS file systems (if CephFS is used)"}),"\n",(0,o.jsx)(n.p,{children:"List all Ceph file systems"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph fs ls\n"})}),"\n",(0,o.jsx)(n.p,{children:"For each CephFS do:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph fs <file system name> down true\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["After that disable and stop all ",(0,o.jsx)(n.code,{children:"ceph-mds"})," services on all nodes (do this on each node)"]}),"\n",(0,o.jsx)(n.p,{children:"Get the name of the unit (globs not supported for disable) and\nmake a note of the unit name for that node:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl | grep ceph-mds\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl disable --now ceph-mds@<unit>.service\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Stop and disable the ",(0,o.jsx)(n.code,{children:"ceph-mgr"})," services on all nodes (do this on each node)"]}),"\n",(0,o.jsx)(n.p,{children:"Get the name of the unit (globs not supported for disable) and\nmake a note of the unit name for that node:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl | grep ceph-mgr\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl disable --now ceph-mgr@<unit>.service\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Stop and disable the ",(0,o.jsx)(n.code,{children:"ceph-osd"})," services on all nodes (do this on each node)"]}),"\n",(0,o.jsx)(n.p,{children:"Get the names of the units (globs not supported for disable) and\nmake a note of the unit names for that node (best to save it to a file):"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl | grep ceph-osd\n"})}),"\n",(0,o.jsx)(n.p,{children:"For each OSD unit execute:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl disable ceph-osd@<osd-id>.service\n"})}),"\n",(0,o.jsx)(n.p,{children:"Stop all OSDs at once:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl stop ceph-osd\\*.service\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Finally stop the ",(0,o.jsx)(n.code,{children:"ceph-mon"})," services on all nodes (do this on each node)"]}),"\n",(0,o.jsx)(n.p,{children:"Get the name of the unit (globs not supported for disable) and\nmake a note of the unit name for that node:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl | grep ceph-mon\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl disable --now ceph-mon@<unit>.service\n"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"restart-a-ceph-cluster-after-manual-shutdown",children:"Restart a Ceph cluster after manual shutdown"}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsxs)(n.p,{children:["You will need the notes taken during shutdown of the unit names.\nIt ",(0,o.jsx)(n.strong,{children:"can"})," be done without, but then it'll be way more work finding out the names."]})}),"\n",(0,o.jsx)(n.p,{children:"In order to restart a Ceph cluster after performing a manual shutdown like described\nin the section above, you do the following:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Enable & start the ",(0,o.jsx)(n.code,{children:"ceph-mon"})," services on all nodes (do this on each node)"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl enable --now ceph-mon@<unit-name>.service\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Enable & start the ",(0,o.jsx)(n.code,{children:"ceph-osd"})," services on all nodes (do this on each node)"]}),"\n",(0,o.jsx)(n.p,{children:"For each Ceph OSD on that node do:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl enable --now ceph-osd@<osd-id>.service\n"})}),"\n",(0,o.jsx)(n.p,{children:"Depending on the number of OSDs on that node it can take a while."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Enable & start the ",(0,o.jsx)(n.code,{children:"ceph-mgr"})," services on all nodes (do this on each node)"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl enable --now ceph-mgr@<unit-name>.service\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Check the status of your cluster and wait for all OSDs to come online"}),"\n",(0,o.jsx)(n.p,{children:"You can watch the status periodically by running:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ watch ceph -s\n"})}),"\n",(0,o.jsx)(n.p,{children:"You should wait until all OSDs are up + in again, before removing flags."}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Remove flags to unpause operations"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph osd unset pause\n$ ceph osd unset nodown\n$ ceph osd unset noout\n$ ceph osd unset nobackfill\n$ ceph osd unset norecover\n$ ceph osd unset norebalance\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Wait for cluster to resume operations"}),"\n",(0,o.jsx)(n.p,{children:'See step #4 of this SOP.\nNow you wait until the cluster seems "happy enough" to accept clients.\n(i.e. rebalancing finished etc.)\nMaybe it will complain about MDS being down, but that\'s normal for now.'}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Enable & start the ",(0,o.jsx)(n.code,{children:"ceph-mds"})," services on each node (if CephFS is used)"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl enable --now ceph-mds@<unit>.service\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Start CephFS file systems again"}),"\n",(0,o.jsx)(n.p,{children:"List all Ceph file systems"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph fs ls\n"})}),"\n",(0,o.jsx)(n.p,{children:"For each CephFS do:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ ceph fs <file system name> down false\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Enable & start the ",(0,o.jsx)(n.code,{children:"radosgw"})," services on each node (if RGW is used)"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# systemctl enable --now ceph-radosgw@<name>.service\n"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"performance-benchmark",children:"Performance benchmark"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# apt-get install -y fio\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'#!/usr/bin/env bash\n\nBENCH_DEVICE="$2"\nDATE=$(date +%s)\nIOENGINE="libaio"\nLOGPATH="$1"\nSIZE=1G\n\nmkdir -p $LOGPATH\n\nfor RW in "write" "randwrite" "read" "randread"\ndo\n for BS in "4K" "64K" "1M" "4M" "16M" "64M"\n do\n (\n echo "==== $RW - $BS - DIRECT ===="\n echo 3 > /proc/sys/vm/drop_caches\n fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json\n sync\n echo 3 > /proc/sys/vm/drop_caches\n echo "==== $RW - $BS - DIRECT IODEPTH 32 ===="\n fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --iodepth=32 --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-iod32-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json\n sync\n ) | tee $LOGPATH/$RW.$BS-$(basename $BENCH_DEVICE).$DATE.log\n echo\n done\ndone\n'})}),"\n",(0,o.jsx)(n.h2,{id:"where-and-how-to-get-further-help",children:"Where and how to get further help"}),"\n",(0,o.jsxs)(n.p,{children:["Join the ",(0,o.jsx)(n.strong,{children:"#ceph"})," IRC channel on ",(0,o.jsx)(n.strong,{children:"irc.oftc.net"}),', state the problem with as many details as possible\nincluding information about what steps have already been taken to solve the problem\nalso provide information from the command output from the "60 seconds cluster overview" above\nthrough a pastebin or a similar service. In order for people to be able\nto help, details and some patience are important.']})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>d});var o=s(96540);const i={},t=o.createContext(i);function r(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5e95c892.2c202730.js b/assets/js/5e95c892.2c202730.js new file mode 100644 index 0000000000..0248989a0d --- /dev/null +++ b/assets/js/5e95c892.2c202730.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9647],{7121:(e,s,r)=>{r.r(s),r.d(s,{default:()=>l});r(96540);var c=r(18215),u=r(61213),a=r(17559),d=r(22831),n=r(72415),t=r(74848);function l(e){return(0,t.jsx)(u.e3,{className:(0,c.A)(a.G.wrapper.docsPages),children:(0,t.jsx)(n.A,{children:(0,d.v)(e.route.routes)})})}}}]); \ No newline at end of file diff --git a/assets/js/609.3c7f80db.js b/assets/js/609.3c7f80db.js new file mode 100644 index 0000000000..904d736078 --- /dev/null +++ b/assets/js/609.3c7f80db.js @@ -0,0 +1,10814 @@ +"use strict"; +exports.id = 609; +exports.ids = [609]; +exports.modules = { + +/***/ 21176: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Zp: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(5664); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(74722); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(91395); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(697); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.A(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.A( + map/* default */.A(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.A(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.A(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.T(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.A(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.A(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.A(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.A(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.A(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.A('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.A(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.A(g.outEdges(v), function (e) { + if (has/* default */.A(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.A(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.A(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(98879); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(81942); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(23068); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.A)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(52528); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.A)(iteratee, 3); + + (0,_baseForOwn/* default */.A)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.A)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(41917); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.A.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.A(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.T().setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.T({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.A(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.A(range/* default */.A(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.A(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.A(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.A(layers, function (vs, i) { + if (isUndefined/* default */.A(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.A(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.A(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.A(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.A(children, dfs); + } + + if (has/* default */.A(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.A(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.A(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, reverseYOne); + if (has/* default */.A(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, swapXYOne); + if (has/* default */.A(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.A(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.A)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.A(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.A(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.A(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.T({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.A(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.A(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.A(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.A)(collection)) { + var iteratee = (0,_baseIteratee/* default */.A)(predicate, 3); + collection = (0,keys/* default */.A)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.A)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.A)(array, (0,_baseIteratee/* default */.A)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(69471); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(88496); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.A)(value) && (0,isObjectLike/* default */.A)(value) && (0,_baseGetTag/* default */.A)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.A)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.A)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.A)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.A)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.A(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.A(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.A(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.A(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.A(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.A(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.A(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.A(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(73046); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.A(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.A(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.A(tree.neighbors(v), function (w) { + if (!has/* default */.A(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.A(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.A(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.A(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.A(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.A(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.A(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.A(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.A(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.A( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(91641); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.A)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.A(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.T({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.A(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.A(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.A(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.A('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.A); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(52568); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.A)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.A)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + if ((0,isArray/* default */.A)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.A)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.A]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.A)(iteratees, (0,_baseUnary/* default */.A)(_baseIteratee/* default */.A)); + + var result = (0,_baseMap/* default */.A)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.A)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.A)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.A)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.A)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.A(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.A( + map/* default */.A(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.A(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.A(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.A( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.A(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.A(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.A(range/* default */.A(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.A(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.A(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.A(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.A(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.A( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.A(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.A(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.A(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.A(entryV) && !isUndefined/* default */.A(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.A(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.A(uEntry.barycenter) || + isUndefined/* default */.A(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.A(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.A(entry.out, handleOut(entry)); + } + + return map/* default */.A( + filter/* default */.A(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.A(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.A(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.A(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.A(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.A(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.A(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.A(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.A([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.A(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.A(entries, function (entry) { + entry.vs = flatten/* default */.A( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.A(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.A(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.A(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.A(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.T(); + forEach/* default */.A(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.A(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.A(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.A(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(99922); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(4574); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee), keysIn/* default */.A); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.A(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.A(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.A(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.A(range/* default */.A(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.A(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.A(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.A(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.A(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.A(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.A(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.T(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.A(layering, function (layer) { + var u; + forEach/* default */.A(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.A(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.A(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.A(['u', 'd'], function (vert) { + forEach/* default */.A(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.A(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.A(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.A(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.A(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.A(layering).reverse(); + forEach/* default */.A(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.A(adjustedLayering, function (inner) { + return values/* default */.A(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.A(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.A(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.A(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.A(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.A(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.A(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.A(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.T({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.A({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.A(graph, graphAttrs)) + ); + + forEach/* default */.A(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.A(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.A({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.A(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.A(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.A(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.A(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.A(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.A(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.A(layers, function (layer) { + var orderShift = 0; + forEach/* default */.A(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.A(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.A(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.A(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 73046: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + T: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(89610); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(66401); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.A)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(39857); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.A && (1 / (0,_setToArray/* default */.A)(new _Set/* default */.A([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.A(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.A)(set); + } + isCommon = false; + includes = _cacheHas/* default */.A; + seen = new _SetCache/* default */.A; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(53533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.A)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.A)(arrays, 1, isArrayLikeObject/* default */.A, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.A(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.A(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.A(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.A(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.A(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.A(this._nodes); + } + sources() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.A(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.A(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.A(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.A(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.A(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.A(keys/* default */.A(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.A(keys/* default */.A(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.A(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.A(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.A(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.A(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.A(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.A(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.A(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.A(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.A(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.A(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.A(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.A(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.A(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.A(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.A(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.A(inV); + if (!u) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.A(outV); + if (!w) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.A(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 697: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ T: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.T) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 62062: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(29471); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.A; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 72641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 2634: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 45572: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 76912: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 91641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(72641); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(22031); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keys/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keysIn/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(80154); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(39759); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(14792); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.A)(source, (0,_getSymbols/* default */.A)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(15647); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(13153); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.A : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.A)(result, (0,_getSymbols/* default */.A)(object)); + object = (0,_getPrototype/* default */.A)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.A)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(33831); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.A)(object, keysIn/* default */.A, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(90565); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.A)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(1801); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.A)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.A)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(18598); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(64841); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.A)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.A)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.A)(value)) { + return value; + } + var isArr = (0,isArray/* default */.A)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.A)(value, result); + } + } else { + var tag = (0,_getTag/* default */.A)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.A)(value)) { + return (0,_cloneBuffer/* default */.A)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.A)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.A); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.A) + : (isFlat ? keysIn/* default */.A : keys/* default */.A); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.A)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.A)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 6240: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.A)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.A); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 25707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 13588: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(52274); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.A ? _Symbol/* default */.A.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.A)(value) || (0,isArguments/* default */.A)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.A)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 79841: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4574); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 66318: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 33831: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76912); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 49574: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.A : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.A)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(43988); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(66984); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.A(object), new _Uint8Array/* default */.A(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.A)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.A); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.A)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.A)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(33858); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.A)(object), + othIsArr = (0,isArray/* default */.A)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.A)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.A)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.A)(object)) { + if (!(0,isBuffer/* default */.A)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.A); + return (objIsArr || (0,isTypedArray/* default */.A)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.A); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.A); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.A)(value) && !(0,isObjectLike/* default */.A)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.A; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.A)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.A)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.A)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.A)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.A)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.A)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.A)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.A)(path) ? (0,_baseProperty/* default */.A)((0,_toKey/* default */.A)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.A; + } + if (typeof value == 'object') { + return (0,isArray/* default */.A)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 52568: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6240); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 70805: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 64099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 99922: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(29008); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 7819: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(46632); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.A)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(28894); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.A)(value)) { + return value; + } + return (0,_isKey/* default */.A)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.A)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 19042: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33831); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14792); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 14792: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2634); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13153); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 85054: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(52274); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(92049); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25353); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5254); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 86586: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(61882); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 29959: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 30901: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61882); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 23068: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(24326); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66984); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6832); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55615); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 11662: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(2634); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.A)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.A)(collection) ? _arrayFilter/* default */.A : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.A)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 34098: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13588); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 8058: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72641); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6240); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99922); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 48585: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 39188: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 61882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(88496); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(53098); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 69592: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 27422: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(83607); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69471); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 74722: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(45572); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49574); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(52568); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 81942: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(7819); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(25353); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.A)(object)) { + return object; + } + path = (0,_castPath/* default */.A)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.A)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.A)(objValue) + ? objValue + : ((0,_isIndex/* default */.A)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.A)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.A)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.A)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.A)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(76875); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(67525); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.A)((0,_overRest/* default */.A)(func, undefined, flatten/* default */.A), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 91395: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.A)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.A)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.A)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.A)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 89463: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.A)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.A)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.A); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 13153: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 74342: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.A)(value)) { + return NAN; + } + if ((0,isObject/* default */.A)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.A)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 28894: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.A)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.A)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.A)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 5664: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28894); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 38207: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.A)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.A)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 58609: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(26292); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(21176); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(697); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(76257); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(99418); + + + + + + + + + + + + + + +const idCache = {}; +const set = (key, val) => { + idCache[key] = val; +}; +const get = (k) => idCache[k]; +const keys = () => Object.keys(idCache); +const size = () => keys().length; +const idCache$1 = { + get, + set, + keys, + size +}; +const drawStartState = (g) => g.append("circle").attr("class", "start-state").attr("r", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit).attr("cx", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit).attr("cy", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit); +const drawDivider = (g) => g.append("line").style("stroke", "grey").style("stroke-dasharray", "3").attr("x1", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight).attr("class", "divider").attr("x2", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight * 2).attr("y1", 0).attr("y2", 0); +const drawSimpleState = (g, stateDef) => { + const state = g.append("text").attr("x", 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("y", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight + 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("font-size", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.fontSize).attr("class", "state-title").text(stateDef.id); + const classBox = state.node().getBBox(); + g.insert("rect", ":first-child").attr("x", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("y", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("width", classBox.width + 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("height", classBox.height + 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("rx", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.radius); + return state; +}; +const drawDescrState = (g, stateDef) => { + const addTspan = function(textEl, txt, isFirst2) { + const tSpan = textEl.append("tspan").attr("x", 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).text(txt); + if (!isFirst2) { + tSpan.attr("dy", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight); + } + }; + const title = g.append("text").attr("x", 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("y", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight + 1.3 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("font-size", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.fontSize).attr("class", "state-title").text(stateDef.descriptions[0]); + const titleBox = title.node().getBBox(); + const titleHeight = titleBox.height; + const description = g.append("text").attr("x", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr( + "y", + titleHeight + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding * 0.4 + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.dividerMargin + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight + ).attr("class", "state-description"); + let isFirst = true; + let isSecond = true; + stateDef.descriptions.forEach(function(descr) { + if (!isFirst) { + addTspan(description, descr, isSecond); + isSecond = false; + } + isFirst = false; + }); + const descrLine = g.append("line").attr("x1", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("y1", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + titleHeight + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.dividerMargin / 2).attr("y2", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + titleHeight + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.dividerMargin / 2).attr("class", "descr-divider"); + const descrBox = description.node().getBBox(); + const width = Math.max(descrBox.width, titleBox.width); + descrLine.attr("x2", width + 3 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding); + g.insert("rect", ":first-child").attr("x", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("y", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("width", width + 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("height", descrBox.height + titleHeight + 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("rx", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.radius); + return g; +}; +const addTitleAndBox = (g, stateDef, altBkg) => { + const pad = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding; + const dblPad = 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding; + const orgBox = g.node().getBBox(); + const orgWidth = orgBox.width; + const orgX = orgBox.x; + const title = g.append("text").attr("x", 0).attr("y", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.titleShift).attr("font-size", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.fontSize).attr("class", "state-title").text(stateDef.id); + const titleBox = title.node().getBBox(); + const titleWidth = titleBox.width + dblPad; + let width = Math.max(titleWidth, orgWidth); + if (width === orgWidth) { + width = width + dblPad; + } + let startX; + const graphBox = g.node().getBBox(); + if (stateDef.doc) + ; + startX = orgX - pad; + if (titleWidth > orgWidth) { + startX = (orgWidth - width) / 2 + pad; + } + if (Math.abs(orgX - graphBox.x) < pad && titleWidth > orgWidth) { + startX = orgX - (titleWidth - orgWidth) / 2; + } + const lineY = 1 - (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight; + g.insert("rect", ":first-child").attr("x", startX).attr("y", lineY).attr("class", altBkg ? "alt-composit" : "composit").attr("width", width).attr( + "height", + graphBox.height + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.titleShift + 1 + ).attr("rx", "0"); + title.attr("x", startX + pad); + if (titleWidth <= orgWidth) { + title.attr("x", orgX + (width - dblPad) / 2 - titleWidth / 2 + pad); + } + g.insert("rect", ":first-child").attr("x", startX).attr( + "y", + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.titleShift - (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight - (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + ).attr("width", width).attr("height", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight * 3).attr("rx", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.radius); + g.insert("rect", ":first-child").attr("x", startX).attr( + "y", + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.titleShift - (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight - (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + ).attr("width", width).attr("height", graphBox.height + 3 + 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight).attr("rx", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.radius); + return g; +}; +const drawEndState = (g) => { + g.append("circle").attr("class", "end-state-outer").attr("r", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.miniPadding).attr( + "cx", + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.miniPadding + ).attr( + "cy", + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.miniPadding + ); + return g.append("circle").attr("class", "end-state-inner").attr("r", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit).attr("cx", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit + 2).attr("cy", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit + 2); +}; +const drawForkJoinState = (g, stateDef) => { + let width = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.forkWidth; + let height = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.forkHeight; + if (stateDef.parentId) { + let tmp = width; + width = height; + height = tmp; + } + return g.append("rect").style("stroke", "black").style("fill", "black").attr("width", width).attr("height", height).attr("x", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("y", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding); +}; +const _drawLongText = (_text, x, y, g) => { + let textHeight = 0; + const textElem = g.append("text"); + textElem.style("text-anchor", "start"); + textElem.attr("class", "noteText"); + let text = _text.replace(/\r\n/g, "<br/>"); + text = text.replace(/\n/g, "<br/>"); + const lines = text.split(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.e.lineBreakRegex); + let tHeight = 1.25 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.noteMargin; + for (const line2 of lines) { + const txt = line2.trim(); + if (txt.length > 0) { + const span = textElem.append("tspan"); + span.text(txt); + if (tHeight === 0) { + const textBounds = span.node().getBBox(); + tHeight += textBounds.height; + } + textHeight += tHeight; + span.attr("x", x + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.noteMargin); + span.attr("y", y + textHeight + 1.25 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.noteMargin); + } + } + return { textWidth: textElem.node().getBBox().width, textHeight }; +}; +const drawNote = (text, g) => { + g.attr("class", "state-note"); + const note = g.append("rect").attr("x", 0).attr("y", (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding); + const rectElem = g.append("g"); + const { textWidth, textHeight } = _drawLongText(text, 0, 0, rectElem); + note.attr("height", textHeight + 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.noteMargin); + note.attr("width", textWidth + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.noteMargin * 2); + return note; +}; +const drawState = function(elem, stateDef) { + const id = stateDef.id; + const stateInfo = { + id, + label: stateDef.id, + width: 0, + height: 0 + }; + const g = elem.append("g").attr("id", id).attr("class", "stateGroup"); + if (stateDef.type === "start") { + drawStartState(g); + } + if (stateDef.type === "end") { + drawEndState(g); + } + if (stateDef.type === "fork" || stateDef.type === "join") { + drawForkJoinState(g, stateDef); + } + if (stateDef.type === "note") { + drawNote(stateDef.note.text, g); + } + if (stateDef.type === "divider") { + drawDivider(g); + } + if (stateDef.type === "default" && stateDef.descriptions.length === 0) { + drawSimpleState(g, stateDef); + } + if (stateDef.type === "default" && stateDef.descriptions.length > 0) { + drawDescrState(g, stateDef); + } + const stateBox = g.node().getBBox(); + stateInfo.width = stateBox.width + 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding; + stateInfo.height = stateBox.height + 2 * (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding; + idCache$1.set(id, stateInfo); + return stateInfo; +}; +let edgeCount = 0; +const drawEdge = function(elem, path, relation) { + const getRelationType = function(type) { + switch (type) { + case _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.d.relationType.AGGREGATION: + return "aggregation"; + case _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.d.relationType.EXTENSION: + return "extension"; + case _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.d.relationType.COMPOSITION: + return "composition"; + case _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.d.relationType.DEPENDENCY: + return "dependency"; + } + }; + path.points = path.points.filter((p) => !Number.isNaN(p.y)); + const lineData = path.points; + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .n8j)().x(function(d) { + return d.x; + }).y(function(d) { + return d.y; + }).curve(d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .qrM); + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", "edge" + edgeCount).attr("class", "transition"); + let url = ""; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + svgPath.attr( + "marker-end", + "url(" + url + "#" + getRelationType(_styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.d.relationType.DEPENDENCY) + "End)" + ); + if (relation.title !== void 0) { + const label = elem.append("g").attr("class", "stateLabel"); + const { x, y } = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.u.calcLabelPosition(path.points); + const rows = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.e.getRows(relation.title); + let titleHeight = 0; + const titleRows = []; + let maxWidth = 0; + let minX = 0; + for (let i = 0; i <= rows.length; i++) { + const title = label.append("text").attr("text-anchor", "middle").text(rows[i]).attr("x", x).attr("y", y + titleHeight); + const boundsTmp = title.node().getBBox(); + maxWidth = Math.max(maxWidth, boundsTmp.width); + minX = Math.min(minX, boundsTmp.x); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.info(boundsTmp.x, x, y + titleHeight); + if (titleHeight === 0) { + const titleBox = title.node().getBBox(); + titleHeight = titleBox.height; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Title height", titleHeight, y); + } + titleRows.push(title); + } + let boxHeight = titleHeight * rows.length; + if (rows.length > 1) { + const heightAdj = (rows.length - 1) * titleHeight * 0.5; + titleRows.forEach((title, i) => title.attr("y", y + i * titleHeight - heightAdj)); + boxHeight = titleHeight * rows.length; + } + const bounds = label.node().getBBox(); + label.insert("rect", ":first-child").attr("class", "box").attr("x", x - maxWidth / 2 - (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding / 2).attr("y", y - boxHeight / 2 - (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding / 2 - 3.5).attr("width", maxWidth + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("height", boxHeight + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.info(bounds); + } + edgeCount++; +}; +let conf; +const transformationLog = {}; +const setConf = function() { +}; +const insertMarkers = function(elem) { + elem.append("defs").append("marker").attr("id", "dependencyEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const draw = function(text, id, _version, diagObj) { + conf = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().state; + const securityLevel = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Rendering diagram " + text); + const diagram2 = root.select(`[id='${id}']`); + insertMarkers(diagram2); + const rootDoc = diagObj.db.getRootDoc(); + renderDoc(rootDoc, diagram2, void 0, false, root, doc, diagObj); + const padding = conf.padding; + const bounds = diagram2.node().getBBox(); + const width = bounds.width + padding * 2; + const height = bounds.height + padding * 2; + const svgWidth = width * 1.75; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.i)(diagram2, height, svgWidth, conf.useMaxWidth); + diagram2.attr( + "viewBox", + `${bounds.x - conf.padding} ${bounds.y - conf.padding} ` + width + " " + height + ); +}; +const getLabelWidth = (text) => { + return text ? text.length * conf.fontSizeFactor : 1; +}; +const renderDoc = (doc, diagram2, parentId, altBkg, root, domDocument, diagObj) => { + const graph = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .T({ + compound: true, + multigraph: true + }); + let i; + let edgeFreeDoc = true; + for (i = 0; i < doc.length; i++) { + if (doc[i].stmt === "relation") { + edgeFreeDoc = false; + break; + } + } + if (parentId) { + graph.setGraph({ + rankdir: "LR", + multigraph: true, + compound: true, + // acyclicer: 'greedy', + ranker: "tight-tree", + ranksep: edgeFreeDoc ? 1 : conf.edgeLengthFactor, + nodeSep: edgeFreeDoc ? 1 : 50, + isMultiGraph: true + // ranksep: 5, + // nodesep: 1 + }); + } else { + graph.setGraph({ + rankdir: "TB", + multigraph: true, + compound: true, + // isCompound: true, + // acyclicer: 'greedy', + // ranker: 'longest-path' + ranksep: edgeFreeDoc ? 1 : conf.edgeLengthFactor, + nodeSep: edgeFreeDoc ? 1 : 50, + ranker: "tight-tree", + // ranker: 'network-simplex' + isMultiGraph: true + }); + } + graph.setDefaultEdgeLabel(function() { + return {}; + }); + diagObj.db.extract(doc); + const states = diagObj.db.getStates(); + const relations = diagObj.db.getRelations(); + const keys2 = Object.keys(states); + for (const key of keys2) { + const stateDef = states[key]; + if (parentId) { + stateDef.parentId = parentId; + } + let node; + if (stateDef.doc) { + let sub = diagram2.append("g").attr("id", stateDef.id).attr("class", "stateGroup"); + node = renderDoc(stateDef.doc, sub, stateDef.id, !altBkg, root, domDocument, diagObj); + { + sub = addTitleAndBox(sub, stateDef, altBkg); + let boxBounds = sub.node().getBBox(); + node.width = boxBounds.width; + node.height = boxBounds.height + conf.padding / 2; + transformationLog[stateDef.id] = { y: conf.compositTitleSize }; + } + } else { + node = drawState(diagram2, stateDef); + } + if (stateDef.note) { + const noteDef = { + descriptions: [], + id: stateDef.id + "-note", + note: stateDef.note, + type: "note" + }; + const note = drawState(diagram2, noteDef); + if (stateDef.note.position === "left of") { + graph.setNode(node.id + "-note", note); + graph.setNode(node.id, node); + } else { + graph.setNode(node.id, node); + graph.setNode(node.id + "-note", note); + } + graph.setParent(node.id, node.id + "-group"); + graph.setParent(node.id + "-note", node.id + "-group"); + } else { + graph.setNode(node.id, node); + } + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Count=", graph.nodeCount(), graph); + let cnt = 0; + relations.forEach(function(relation) { + cnt++; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Setting edge", relation); + graph.setEdge( + relation.id1, + relation.id2, + { + relation, + width: getLabelWidth(relation.title), + height: conf.labelHeight * _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.e.getRows(relation.title).length, + labelpos: "c" + }, + "id" + cnt + ); + }); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_1__/* .layout */ .Zp)(graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Graph after layout", graph.nodes()); + const svgElem = diagram2.node(); + graph.nodes().forEach(function(v) { + if (v !== void 0 && graph.node(v) !== void 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.warn("Node " + v + ": " + JSON.stringify(graph.node(v))); + root.select("#" + svgElem.id + " #" + v).attr( + "transform", + "translate(" + (graph.node(v).x - graph.node(v).width / 2) + "," + (graph.node(v).y + (transformationLog[v] ? transformationLog[v].y : 0) - graph.node(v).height / 2) + " )" + ); + root.select("#" + svgElem.id + " #" + v).attr("data-x-shift", graph.node(v).x - graph.node(v).width / 2); + const dividers = domDocument.querySelectorAll("#" + svgElem.id + " #" + v + " .divider"); + dividers.forEach((divider) => { + const parent = divider.parentElement; + let pWidth = 0; + let pShift = 0; + if (parent) { + if (parent.parentElement) { + pWidth = parent.parentElement.getBBox().width; + } + pShift = parseInt(parent.getAttribute("data-x-shift"), 10); + if (Number.isNaN(pShift)) { + pShift = 0; + } + } + divider.setAttribute("x1", 0 - pShift + 8); + divider.setAttribute("x2", pWidth - pShift - 8); + }); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("No Node " + v + ": " + JSON.stringify(graph.node(v))); + } + }); + let stateBox = svgElem.getBBox(); + graph.edges().forEach(function(e) { + if (e !== void 0 && graph.edge(e) !== void 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(graph.edge(e))); + drawEdge(diagram2, graph.edge(e), graph.edge(e).relation); + } + }); + stateBox = svgElem.getBBox(); + const stateInfo = { + id: parentId ? parentId : "root", + label: parentId ? parentId : "root", + width: 0, + height: 0 + }; + stateInfo.width = stateBox.width + 2 * conf.padding; + stateInfo.height = stateBox.height + 2 * conf.padding; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Doc rendered", stateInfo, graph); + return stateInfo; +}; +const renderer = { + setConf, + draw +}; +const diagram = { + parser: _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.p, + db: _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.d, + renderer, + styles: _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.s, + init: (cnf) => { + if (!cnf.state) { + cnf.state = {}; + } + cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.d.clear(); + } +}; + + + +/***/ }), + +/***/ 26292: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ D: () => (/* binding */ DEFAULT_STATE_TYPE), +/* harmony export */ S: () => (/* binding */ STMT_RELATION), +/* harmony export */ a: () => (/* binding */ DIVIDER_TYPE), +/* harmony export */ b: () => (/* binding */ STMT_STATE), +/* harmony export */ c: () => (/* binding */ DEFAULT_NESTED_DOC_DIR), +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ p: () => (/* binding */ parser$1), +/* harmony export */ s: () => (/* binding */ styles) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(76257); + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 2], $V1 = [1, 3], $V2 = [1, 4], $V3 = [2, 4], $V4 = [1, 9], $V5 = [1, 11], $V6 = [1, 15], $V7 = [1, 16], $V8 = [1, 17], $V9 = [1, 18], $Va = [1, 30], $Vb = [1, 19], $Vc = [1, 20], $Vd = [1, 21], $Ve = [1, 22], $Vf = [1, 23], $Vg = [1, 25], $Vh = [1, 26], $Vi = [1, 27], $Vj = [1, 28], $Vk = [1, 29], $Vl = [1, 32], $Vm = [1, 33], $Vn = [1, 34], $Vo = [1, 35], $Vp = [1, 31], $Vq = [1, 4, 5, 15, 16, 18, 20, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50], $Vr = [1, 4, 5, 13, 14, 15, 16, 18, 20, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50], $Vs = [4, 5, 15, 16, 18, 20, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "SPACE": 4, "NL": 5, "SD": 6, "document": 7, "line": 8, "statement": 9, "classDefStatement": 10, "cssClassStatement": 11, "idStatement": 12, "DESCR": 13, "-->": 14, "HIDE_EMPTY": 15, "scale": 16, "WIDTH": 17, "COMPOSIT_STATE": 18, "STRUCT_START": 19, "STRUCT_STOP": 20, "STATE_DESCR": 21, "AS": 22, "ID": 23, "FORK": 24, "JOIN": 25, "CHOICE": 26, "CONCURRENT": 27, "note": 28, "notePosition": 29, "NOTE_TEXT": 30, "direction": 31, "acc_title": 32, "acc_title_value": 33, "acc_descr": 34, "acc_descr_value": 35, "acc_descr_multiline_value": 36, "classDef": 37, "CLASSDEF_ID": 38, "CLASSDEF_STYLEOPTS": 39, "DEFAULT": 40, "class": 41, "CLASSENTITY_IDS": 42, "STYLECLASS": 43, "direction_tb": 44, "direction_bt": 45, "direction_rl": 46, "direction_lr": 47, "eol": 48, ";": 49, "EDGE_STATE": 50, "STYLE_SEPARATOR": 51, "left_of": 52, "right_of": 53, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "SPACE", 5: "NL", 6: "SD", 13: "DESCR", 14: "-->", 15: "HIDE_EMPTY", 16: "scale", 17: "WIDTH", 18: "COMPOSIT_STATE", 19: "STRUCT_START", 20: "STRUCT_STOP", 21: "STATE_DESCR", 22: "AS", 23: "ID", 24: "FORK", 25: "JOIN", 26: "CHOICE", 27: "CONCURRENT", 28: "note", 30: "NOTE_TEXT", 32: "acc_title", 33: "acc_title_value", 34: "acc_descr", 35: "acc_descr_value", 36: "acc_descr_multiline_value", 37: "classDef", 38: "CLASSDEF_ID", 39: "CLASSDEF_STYLEOPTS", 40: "DEFAULT", 41: "class", 42: "CLASSENTITY_IDS", 43: "STYLECLASS", 44: "direction_tb", 45: "direction_bt", 46: "direction_rl", 47: "direction_lr", 49: ";", 50: "EDGE_STATE", 51: "STYLE_SEPARATOR", 52: "left_of", 53: "right_of" }, + productions_: [0, [3, 2], [3, 2], [3, 2], [7, 0], [7, 2], [8, 2], [8, 1], [8, 1], [9, 1], [9, 1], [9, 1], [9, 2], [9, 3], [9, 4], [9, 1], [9, 2], [9, 1], [9, 4], [9, 3], [9, 6], [9, 1], [9, 1], [9, 1], [9, 1], [9, 4], [9, 4], [9, 1], [9, 2], [9, 2], [9, 1], [10, 3], [10, 3], [11, 3], [31, 1], [31, 1], [31, 1], [31, 1], [48, 1], [48, 1], [12, 1], [12, 1], [12, 3], [12, 3], [29, 1], [29, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 3: + yy.setRootDoc($$[$0]); + return $$[$0]; + case 4: + this.$ = []; + break; + case 5: + if ($$[$0] != "nl") { + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + } + break; + case 6: + case 7: + this.$ = $$[$0]; + break; + case 8: + this.$ = "nl"; + break; + case 11: + this.$ = $$[$0]; + break; + case 12: + const stateStmt = $$[$0 - 1]; + stateStmt.description = yy.trimColon($$[$0]); + this.$ = stateStmt; + break; + case 13: + this.$ = { stmt: "relation", state1: $$[$0 - 2], state2: $$[$0] }; + break; + case 14: + const relDescription = yy.trimColon($$[$0]); + this.$ = { stmt: "relation", state1: $$[$0 - 3], state2: $$[$0 - 1], description: relDescription }; + break; + case 18: + this.$ = { stmt: "state", id: $$[$0 - 3], type: "default", description: "", doc: $$[$0 - 1] }; + break; + case 19: + var id = $$[$0]; + var description = $$[$0 - 2].trim(); + if ($$[$0].match(":")) { + var parts = $$[$0].split(":"); + id = parts[0]; + description = [description, parts[1]]; + } + this.$ = { stmt: "state", id, type: "default", description }; + break; + case 20: + this.$ = { stmt: "state", id: $$[$0 - 3], type: "default", description: $$[$0 - 5], doc: $$[$0 - 1] }; + break; + case 21: + this.$ = { stmt: "state", id: $$[$0], type: "fork" }; + break; + case 22: + this.$ = { stmt: "state", id: $$[$0], type: "join" }; + break; + case 23: + this.$ = { stmt: "state", id: $$[$0], type: "choice" }; + break; + case 24: + this.$ = { stmt: "state", id: yy.getDividerId(), type: "divider" }; + break; + case 25: + this.$ = { stmt: "state", id: $$[$0 - 1].trim(), note: { position: $$[$0 - 2].trim(), text: $$[$0].trim() } }; + break; + case 28: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 29: + case 30: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 31: + case 32: + this.$ = { stmt: "classDef", id: $$[$0 - 1].trim(), classes: $$[$0].trim() }; + break; + case 33: + this.$ = { stmt: "applyClass", id: $$[$0 - 1].trim(), styleClass: $$[$0].trim() }; + break; + case 34: + yy.setDirection("TB"); + this.$ = { stmt: "dir", value: "TB" }; + break; + case 35: + yy.setDirection("BT"); + this.$ = { stmt: "dir", value: "BT" }; + break; + case 36: + yy.setDirection("RL"); + this.$ = { stmt: "dir", value: "RL" }; + break; + case 37: + yy.setDirection("LR"); + this.$ = { stmt: "dir", value: "LR" }; + break; + case 40: + case 41: + this.$ = { stmt: "state", id: $$[$0].trim(), type: "default", description: "" }; + break; + case 42: + this.$ = { stmt: "state", id: $$[$0 - 2].trim(), classes: [$$[$0].trim()], type: "default", description: "" }; + break; + case 43: + this.$ = { stmt: "state", id: $$[$0 - 2].trim(), classes: [$$[$0].trim()], type: "default", description: "" }; + break; + } + }, + table: [{ 3: 1, 4: $V0, 5: $V1, 6: $V2 }, { 1: [3] }, { 3: 5, 4: $V0, 5: $V1, 6: $V2 }, { 3: 6, 4: $V0, 5: $V1, 6: $V2 }, o([1, 4, 5, 15, 16, 18, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50], $V3, { 7: 7 }), { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3], 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 5]), { 9: 36, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 7]), o($Vq, [2, 8]), o($Vq, [2, 9]), o($Vq, [2, 10]), o($Vq, [2, 11], { 13: [1, 37], 14: [1, 38] }), o($Vq, [2, 15]), { 17: [1, 39] }, o($Vq, [2, 17], { 19: [1, 40] }), { 22: [1, 41] }, o($Vq, [2, 21]), o($Vq, [2, 22]), o($Vq, [2, 23]), o($Vq, [2, 24]), { 29: 42, 30: [1, 43], 52: [1, 44], 53: [1, 45] }, o($Vq, [2, 27]), { 33: [1, 46] }, { 35: [1, 47] }, o($Vq, [2, 30]), { 38: [1, 48], 40: [1, 49] }, { 42: [1, 50] }, o($Vr, [2, 40], { 51: [1, 51] }), o($Vr, [2, 41], { 51: [1, 52] }), o($Vq, [2, 34]), o($Vq, [2, 35]), o($Vq, [2, 36]), o($Vq, [2, 37]), o($Vq, [2, 6]), o($Vq, [2, 12]), { 12: 53, 23: $Va, 50: $Vp }, o($Vq, [2, 16]), o($Vs, $V3, { 7: 54 }), { 23: [1, 55] }, { 23: [1, 56] }, { 22: [1, 57] }, { 23: [2, 44] }, { 23: [2, 45] }, o($Vq, [2, 28]), o($Vq, [2, 29]), { 39: [1, 58] }, { 39: [1, 59] }, { 43: [1, 60] }, { 23: [1, 61] }, { 23: [1, 62] }, o($Vq, [2, 13], { 13: [1, 63] }), { 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 20: [1, 64], 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 19], { 19: [1, 65] }), { 30: [1, 66] }, { 23: [1, 67] }, o($Vq, [2, 31]), o($Vq, [2, 32]), o($Vq, [2, 33]), o($Vr, [2, 42]), o($Vr, [2, 43]), o($Vq, [2, 14]), o($Vq, [2, 18]), o($Vs, $V3, { 7: 68 }), o($Vq, [2, 25]), o($Vq, [2, 26]), { 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 20: [1, 69], 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 20])], + defaultActions: { 5: [2, 1], 6: [2, 2], 44: [2, 44], 45: [2, 45] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 40; + case 1: + return 44; + case 2: + return 45; + case 3: + return 46; + case 4: + return 47; + case 5: + break; + case 6: + break; + case 7: + return 5; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + this.pushState("SCALE"); + return 16; + case 13: + return 17; + case 14: + this.popState(); + break; + case 15: + this.begin("acc_title"); + return 32; + case 16: + this.popState(); + return "acc_title_value"; + case 17: + this.begin("acc_descr"); + return 34; + case 18: + this.popState(); + return "acc_descr_value"; + case 19: + this.begin("acc_descr_multiline"); + break; + case 20: + this.popState(); + break; + case 21: + return "acc_descr_multiline_value"; + case 22: + this.pushState("CLASSDEF"); + return 37; + case 23: + this.popState(); + this.pushState("CLASSDEFID"); + return "DEFAULT_CLASSDEF_ID"; + case 24: + this.popState(); + this.pushState("CLASSDEFID"); + return 38; + case 25: + this.popState(); + return 39; + case 26: + this.pushState("CLASS"); + return 41; + case 27: + this.popState(); + this.pushState("CLASS_STYLE"); + return 42; + case 28: + this.popState(); + return 43; + case 29: + this.pushState("SCALE"); + return 16; + case 30: + return 17; + case 31: + this.popState(); + break; + case 32: + this.pushState("STATE"); + break; + case 33: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 24; + case 34: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 25; + case 35: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -10).trim(); + return 26; + case 36: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 24; + case 37: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 25; + case 38: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -10).trim(); + return 26; + case 39: + return 44; + case 40: + return 45; + case 41: + return 46; + case 42: + return 47; + case 43: + this.pushState("STATE_STRING"); + break; + case 44: + this.pushState("STATE_ID"); + return "AS"; + case 45: + this.popState(); + return "ID"; + case 46: + this.popState(); + break; + case 47: + return "STATE_DESCR"; + case 48: + return 18; + case 49: + this.popState(); + break; + case 50: + this.popState(); + this.pushState("struct"); + return 19; + case 51: + break; + case 52: + this.popState(); + return 20; + case 53: + break; + case 54: + this.begin("NOTE"); + return 28; + case 55: + this.popState(); + this.pushState("NOTE_ID"); + return 52; + case 56: + this.popState(); + this.pushState("NOTE_ID"); + return 53; + case 57: + this.popState(); + this.pushState("FLOATING_NOTE"); + break; + case 58: + this.popState(); + this.pushState("FLOATING_NOTE_ID"); + return "AS"; + case 59: + break; + case 60: + return "NOTE_TEXT"; + case 61: + this.popState(); + return "ID"; + case 62: + this.popState(); + this.pushState("NOTE_TEXT"); + return 23; + case 63: + this.popState(); + yy_.yytext = yy_.yytext.substr(2).trim(); + return 30; + case 64: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 30; + case 65: + return 6; + case 66: + return 6; + case 67: + return 15; + case 68: + return 50; + case 69: + return 23; + case 70: + yy_.yytext = yy_.yytext.trim(); + return 13; + case 71: + return 14; + case 72: + return 27; + case 73: + return 51; + case 74: + return 5; + case 75: + return "INVALID"; + } + }, + rules: [/^(?:default\b)/i, /^(?:.*direction\s+TB[^\n]*)/i, /^(?:.*direction\s+BT[^\n]*)/i, /^(?:.*direction\s+RL[^\n]*)/i, /^(?:.*direction\s+LR[^\n]*)/i, /^(?:%%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[\n]+)/i, /^(?:[\s]+)/i, /^(?:((?!\n)\s)+)/i, /^(?:#[^\n]*)/i, /^(?:%[^\n]*)/i, /^(?:scale\s+)/i, /^(?:\d+)/i, /^(?:\s+width\b)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:classDef\s+)/i, /^(?:DEFAULT\s+)/i, /^(?:\w+\s+)/i, /^(?:[^\n]*)/i, /^(?:class\s+)/i, /^(?:(\w+)+((,\s*\w+)*))/i, /^(?:[^\n]*)/i, /^(?:scale\s+)/i, /^(?:\d+)/i, /^(?:\s+width\b)/i, /^(?:state\s+)/i, /^(?:.*<<fork>>)/i, /^(?:.*<<join>>)/i, /^(?:.*<<choice>>)/i, /^(?:.*\[\[fork\]\])/i, /^(?:.*\[\[join\]\])/i, /^(?:.*\[\[choice\]\])/i, /^(?:.*direction\s+TB[^\n]*)/i, /^(?:.*direction\s+BT[^\n]*)/i, /^(?:.*direction\s+RL[^\n]*)/i, /^(?:.*direction\s+LR[^\n]*)/i, /^(?:["])/i, /^(?:\s*as\s+)/i, /^(?:[^\n\{]*)/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:[^\n\s\{]+)/i, /^(?:\n)/i, /^(?:\{)/i, /^(?:%%(?!\{)[^\n]*)/i, /^(?:\})/i, /^(?:[\n])/i, /^(?:note\s+)/i, /^(?:left of\b)/i, /^(?:right of\b)/i, /^(?:")/i, /^(?:\s*as\s*)/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:[^\n]*)/i, /^(?:\s*[^:\n\s\-]+)/i, /^(?:\s*:[^:\n;]+)/i, /^(?:[\s\S]*?end note\b)/i, /^(?:stateDiagram\s+)/i, /^(?:stateDiagram-v2\s+)/i, /^(?:hide empty description\b)/i, /^(?:\[\*\])/i, /^(?:[^:\n\s\-\{]+)/i, /^(?:\s*:[^:\n;]+)/i, /^(?:-->)/i, /^(?:--)/i, /^(?::::)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "LINE": { "rules": [9, 10], "inclusive": false }, "struct": { "rules": [9, 10, 22, 26, 32, 39, 40, 41, 42, 51, 52, 53, 54, 68, 69, 70, 71, 72], "inclusive": false }, "FLOATING_NOTE_ID": { "rules": [61], "inclusive": false }, "FLOATING_NOTE": { "rules": [58, 59, 60], "inclusive": false }, "NOTE_TEXT": { "rules": [63, 64], "inclusive": false }, "NOTE_ID": { "rules": [62], "inclusive": false }, "NOTE": { "rules": [55, 56, 57], "inclusive": false }, "CLASS_STYLE": { "rules": [28], "inclusive": false }, "CLASS": { "rules": [27], "inclusive": false }, "CLASSDEFID": { "rules": [25], "inclusive": false }, "CLASSDEF": { "rules": [23, 24], "inclusive": false }, "acc_descr_multiline": { "rules": [20, 21], "inclusive": false }, "acc_descr": { "rules": [18], "inclusive": false }, "acc_title": { "rules": [16], "inclusive": false }, "SCALE": { "rules": [13, 14, 30, 31], "inclusive": false }, "ALIAS": { "rules": [], "inclusive": false }, "STATE_ID": { "rules": [45], "inclusive": false }, "STATE_STRING": { "rules": [46, 47], "inclusive": false }, "FORK_STATE": { "rules": [], "inclusive": false }, "STATE": { "rules": [9, 10, 33, 34, 35, 36, 37, 38, 43, 44, 48, 49, 50], "inclusive": false }, "ID": { "rules": [9, 10], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 15, 17, 19, 22, 26, 29, 32, 50, 54, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const DEFAULT_DIAGRAM_DIRECTION = "LR"; +const DEFAULT_NESTED_DOC_DIR = "TB"; +const STMT_STATE = "state"; +const STMT_RELATION = "relation"; +const STMT_CLASSDEF = "classDef"; +const STMT_APPLYCLASS = "applyClass"; +const DEFAULT_STATE_TYPE = "default"; +const DIVIDER_TYPE = "divider"; +const START_NODE = "[*]"; +const START_TYPE = "start"; +const END_NODE = START_NODE; +const END_TYPE = "end"; +const COLOR_KEYWORD = "color"; +const FILL_KEYWORD = "fill"; +const BG_FILL = "bgFill"; +const STYLECLASS_SEP = ","; +function newClassesList() { + return {}; +} +let direction = DEFAULT_DIAGRAM_DIRECTION; +let rootDoc = []; +let classes = newClassesList(); +const newDoc = () => { + return { + relations: [], + states: {}, + documents: {} + }; +}; +let documents = { + root: newDoc() +}; +let currentDocument = documents.root; +let startEndCount = 0; +let dividerCnt = 0; +const lineType = { + LINE: 0, + DOTTED_LINE: 1 +}; +const relationType = { + AGGREGATION: 0, + EXTENSION: 1, + COMPOSITION: 2, + DEPENDENCY: 3 +}; +const clone = (o) => JSON.parse(JSON.stringify(o)); +const setRootDoc = (o) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting root doc", o); + rootDoc = o; +}; +const getRootDoc = () => rootDoc; +const docTranslator = (parent, node, first) => { + if (node.stmt === STMT_RELATION) { + docTranslator(parent, node.state1, true); + docTranslator(parent, node.state2, false); + } else { + if (node.stmt === STMT_STATE) { + if (node.id === "[*]") { + node.id = first ? parent.id + "_start" : parent.id + "_end"; + node.start = first; + } else { + node.id = node.id.trim(); + } + } + if (node.doc) { + const doc = []; + let currentDoc = []; + let i; + for (i = 0; i < node.doc.length; i++) { + if (node.doc[i].type === DIVIDER_TYPE) { + const newNode = clone(node.doc[i]); + newNode.doc = clone(currentDoc); + doc.push(newNode); + currentDoc = []; + } else { + currentDoc.push(node.doc[i]); + } + } + if (doc.length > 0 && currentDoc.length > 0) { + const newNode = { + stmt: STMT_STATE, + id: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.I)(), + type: "divider", + doc: clone(currentDoc) + }; + doc.push(clone(newNode)); + node.doc = doc; + } + node.doc.forEach((docNode) => docTranslator(node, docNode, true)); + } + } +}; +const getRootDocV2 = () => { + docTranslator({ id: "root" }, { id: "root", doc: rootDoc }, true); + return { id: "root", doc: rootDoc }; +}; +const extract = (_doc) => { + let doc; + if (_doc.doc) { + doc = _doc.doc; + } else { + doc = _doc; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info(doc); + clear(true); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Extract", doc); + doc.forEach((item) => { + switch (item.stmt) { + case STMT_STATE: + addState( + item.id.trim(), + item.type, + item.doc, + item.description, + item.note, + item.classes, + item.styles, + item.textStyles + ); + break; + case STMT_RELATION: + addRelation(item.state1, item.state2, item.description); + break; + case STMT_CLASSDEF: + addStyleClass(item.id.trim(), item.classes); + break; + case STMT_APPLYCLASS: + setCssClass(item.id.trim(), item.styleClass); + break; + } + }); +}; +const addState = function(id, type = DEFAULT_STATE_TYPE, doc = null, descr = null, note = null, classes2 = null, styles2 = null, textStyles = null) { + const trimmedId = id == null ? void 0 : id.trim(); + if (currentDocument.states[trimmedId] === void 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Adding state ", trimmedId, descr); + currentDocument.states[trimmedId] = { + id: trimmedId, + descriptions: [], + type, + doc, + note, + classes: [], + styles: [], + textStyles: [] + }; + } else { + if (!currentDocument.states[trimmedId].doc) { + currentDocument.states[trimmedId].doc = doc; + } + if (!currentDocument.states[trimmedId].type) { + currentDocument.states[trimmedId].type = type; + } + } + if (descr) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state description", trimmedId, descr); + if (typeof descr === "string") { + addDescription(trimmedId, descr.trim()); + } + if (typeof descr === "object") { + descr.forEach((des) => addDescription(trimmedId, des.trim())); + } + } + if (note) { + currentDocument.states[trimmedId].note = note; + currentDocument.states[trimmedId].note.text = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText( + currentDocument.states[trimmedId].note.text, + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.c)() + ); + } + if (classes2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state classes", trimmedId, classes2); + const classesList = typeof classes2 === "string" ? [classes2] : classes2; + classesList.forEach((cssClass) => setCssClass(trimmedId, cssClass.trim())); + } + if (styles2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state styles", trimmedId, styles2); + const stylesList = typeof styles2 === "string" ? [styles2] : styles2; + stylesList.forEach((style) => setStyle(trimmedId, style.trim())); + } + if (textStyles) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state styles", trimmedId, styles2); + const textStylesList = typeof textStyles === "string" ? [textStyles] : textStyles; + textStylesList.forEach((textStyle) => setTextStyle(trimmedId, textStyle.trim())); + } +}; +const clear = function(saveCommon) { + documents = { + root: newDoc() + }; + currentDocument = documents.root; + startEndCount = 0; + classes = newClassesList(); + if (!saveCommon) { + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.v)(); + } +}; +const getState = function(id) { + return currentDocument.states[id]; +}; +const getStates = function() { + return currentDocument.states; +}; +const logDocuments = function() { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Documents = ", documents); +}; +const getRelations = function() { + return currentDocument.relations; +}; +function startIdIfNeeded(id = "") { + let fixedId = id; + if (id === START_NODE) { + startEndCount++; + fixedId = `${START_TYPE}${startEndCount}`; + } + return fixedId; +} +function startTypeIfNeeded(id = "", type = DEFAULT_STATE_TYPE) { + return id === START_NODE ? START_TYPE : type; +} +function endIdIfNeeded(id = "") { + let fixedId = id; + if (id === END_NODE) { + startEndCount++; + fixedId = `${END_TYPE}${startEndCount}`; + } + return fixedId; +} +function endTypeIfNeeded(id = "", type = DEFAULT_STATE_TYPE) { + return id === END_NODE ? END_TYPE : type; +} +function addRelationObjs(item1, item2, relationTitle) { + let id1 = startIdIfNeeded(item1.id.trim()); + let type1 = startTypeIfNeeded(item1.id.trim(), item1.type); + let id2 = startIdIfNeeded(item2.id.trim()); + let type2 = startTypeIfNeeded(item2.id.trim(), item2.type); + addState( + id1, + type1, + item1.doc, + item1.description, + item1.note, + item1.classes, + item1.styles, + item1.textStyles + ); + addState( + id2, + type2, + item2.doc, + item2.description, + item2.note, + item2.classes, + item2.styles, + item2.textStyles + ); + currentDocument.relations.push({ + id1, + id2, + relationTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText(relationTitle, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.c)()) + }); +} +const addRelation = function(item1, item2, title) { + if (typeof item1 === "object") { + addRelationObjs(item1, item2, title); + } else { + const id1 = startIdIfNeeded(item1.trim()); + const type1 = startTypeIfNeeded(item1); + const id2 = endIdIfNeeded(item2.trim()); + const type2 = endTypeIfNeeded(item2); + addState(id1, type1); + addState(id2, type2); + currentDocument.relations.push({ + id1, + id2, + title: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText(title, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.c)()) + }); + } +}; +const addDescription = function(id, descr) { + const theState = currentDocument.states[id]; + const _descr = descr.startsWith(":") ? descr.replace(":", "").trim() : descr; + theState.descriptions.push(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText(_descr, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.c)())); +}; +const cleanupLabel = function(label) { + if (label.substring(0, 1) === ":") { + return label.substr(2).trim(); + } else { + return label.trim(); + } +}; +const getDividerId = () => { + dividerCnt++; + return "divider-id-" + dividerCnt; +}; +const addStyleClass = function(id, styleAttributes = "") { + if (classes[id] === void 0) { + classes[id] = { id, styles: [], textStyles: [] }; + } + const foundClass = classes[id]; + if (styleAttributes !== void 0 && styleAttributes !== null) { + styleAttributes.split(STYLECLASS_SEP).forEach((attrib) => { + const fixedAttrib = attrib.replace(/([^;]*);/, "$1").trim(); + if (attrib.match(COLOR_KEYWORD)) { + const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL); + const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD); + foundClass.textStyles.push(newStyle2); + } + foundClass.styles.push(fixedAttrib); + }); + } +}; +const getClasses = function() { + return classes; +}; +const setCssClass = function(itemIds, cssClassName) { + itemIds.split(",").forEach(function(id) { + let foundState = getState(id); + if (foundState === void 0) { + const trimmedId = id.trim(); + addState(trimmedId); + foundState = getState(trimmedId); + } + foundState.classes.push(cssClassName); + }); +}; +const setStyle = function(itemId, styleText) { + const item = getState(itemId); + if (item !== void 0) { + item.textStyles.push(styleText); + } +}; +const setTextStyle = function(itemId, cssClassName) { + const item = getState(itemId); + if (item !== void 0) { + item.textStyles.push(cssClassName); + } +}; +const getDirection = () => direction; +const setDirection = (dir) => { + direction = dir; +}; +const trimColon = (str) => str && str[0] === ":" ? str.substr(1).trim() : str.trim(); +const db = { + getConfig: () => (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.c)().state, + addState, + clear, + getState, + getStates, + getRelations, + getClasses, + getDirection, + addRelation, + getDividerId, + setDirection, + cleanupLabel, + lineType, + relationType, + logDocuments, + getRootDoc, + setRootDoc, + getRootDocV2, + extract, + trimColon, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.g, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.s, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.a, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.b, + addStyleClass, + setCssClass, + addDescription, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.t +}; +const getStyles = (options) => ` +defs #statediagram-barbEnd { + fill: ${options.transitionColor}; + stroke: ${options.transitionColor}; + } +g.stateGroup text { + fill: ${options.nodeBorder}; + stroke: none; + font-size: 10px; +} +g.stateGroup text { + fill: ${options.textColor}; + stroke: none; + font-size: 10px; + +} +g.stateGroup .state-title { + font-weight: bolder; + fill: ${options.stateLabelColor}; +} + +g.stateGroup rect { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; +} + +g.stateGroup line { + stroke: ${options.lineColor}; + stroke-width: 1; +} + +.transition { + stroke: ${options.transitionColor}; + stroke-width: 1; + fill: none; +} + +.stateGroup .composit { + fill: ${options.background}; + border-bottom: 1px +} + +.stateGroup .alt-composit { + fill: #e0e0e0; + border-bottom: 1px +} + +.state-note { + stroke: ${options.noteBorderColor}; + fill: ${options.noteBkgColor}; + + text { + fill: ${options.noteTextColor}; + stroke: none; + font-size: 10px; + } +} + +.stateLabel .box { + stroke: none; + stroke-width: 0; + fill: ${options.mainBkg}; + opacity: 0.5; +} + +.edgeLabel .label rect { + fill: ${options.labelBackgroundColor}; + opacity: 0.5; +} +.edgeLabel .label text { + fill: ${options.transitionLabelColor || options.tertiaryTextColor}; +} +.label div .edgeLabel { + color: ${options.transitionLabelColor || options.tertiaryTextColor}; +} + +.stateLabel text { + fill: ${options.stateLabelColor}; + font-size: 10px; + font-weight: bold; +} + +.node circle.state-start { + fill: ${options.specialStateColor}; + stroke: ${options.specialStateColor}; +} + +.node .fork-join { + fill: ${options.specialStateColor}; + stroke: ${options.specialStateColor}; +} + +.node circle.state-end { + fill: ${options.innerEndBackground}; + stroke: ${options.background}; + stroke-width: 1.5 +} +.end-state-inner { + fill: ${options.compositeBackground || options.background}; + // stroke: ${options.background}; + stroke-width: 1.5 +} + +.node rect { + fill: ${options.stateBkg || options.mainBkg}; + stroke: ${options.stateBorder || options.nodeBorder}; + stroke-width: 1px; +} +.node polygon { + fill: ${options.mainBkg}; + stroke: ${options.stateBorder || options.nodeBorder};; + stroke-width: 1px; +} +#statediagram-barbEnd { + fill: ${options.lineColor}; +} + +.statediagram-cluster rect { + fill: ${options.compositeTitleBackground}; + stroke: ${options.stateBorder || options.nodeBorder}; + stroke-width: 1px; +} + +.cluster-label, .nodeLabel { + color: ${options.stateLabelColor}; +} + +.statediagram-cluster rect.outer { + rx: 5px; + ry: 5px; +} +.statediagram-state .divider { + stroke: ${options.stateBorder || options.nodeBorder}; +} + +.statediagram-state .title-state { + rx: 5px; + ry: 5px; +} +.statediagram-cluster.statediagram-cluster .inner { + fill: ${options.compositeBackground || options.background}; +} +.statediagram-cluster.statediagram-cluster-alt .inner { + fill: ${options.altBackground ? options.altBackground : "#efefef"}; +} + +.statediagram-cluster .inner { + rx:0; + ry:0; +} + +.statediagram-state rect.basic { + rx: 5px; + ry: 5px; +} +.statediagram-state rect.divider { + stroke-dasharray: 10,10; + fill: ${options.altBackground ? options.altBackground : "#efefef"}; +} + +.note-edge { + stroke-dasharray: 5; +} + +.statediagram-note rect { + fill: ${options.noteBkgColor}; + stroke: ${options.noteBorderColor}; + stroke-width: 1px; + rx: 0; + ry: 0; +} +.statediagram-note rect { + fill: ${options.noteBkgColor}; + stroke: ${options.noteBorderColor}; + stroke-width: 1px; + rx: 0; + ry: 0; +} + +.statediagram-note text { + fill: ${options.noteTextColor}; +} + +.statediagram-note .nodeLabel { + color: ${options.noteTextColor}; +} +.statediagram .edgeLabel { + color: red; // ${options.noteTextColor}; +} + +#dependencyStart, #dependencyEnd { + fill: ${options.lineColor}; + stroke: ${options.lineColor}; + stroke-width: 1; +} + +.statediagramTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; +} +`; +const styles = getStyles; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/60fc342f.07f52dea.js b/assets/js/60fc342f.07f52dea.js new file mode 100644 index 0000000000..cd5eddc1f0 --- /dev/null +++ b/assets/js/60fc342f.07f52dea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9525],{66290:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>p,frontMatter:()=>c,metadata:()=>o,toc:()=>r});var s=i(74848),a=i(28453);const c={sidebar_label:"Packages"},t="Packages",o={id:"iaas/guides/configuration-guide/commons/packages",title:"Packages",description:"With the osism.commons.packages role, it is possible to add packages on a node",source:"@site/docs/02-iaas/guides/configuration-guide/commons/packages.md",sourceDirName:"02-iaas/guides/configuration-guide/commons",slug:"/iaas/guides/configuration-guide/commons/packages",permalink:"/docs/iaas/guides/configuration-guide/commons/packages",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/packages.md",tags:[],version:"current",frontMatter:{sidebar_label:"Packages"},sidebar:"docs",previous:{title:"Certificates",permalink:"/docs/iaas/guides/configuration-guide/commons/certificates"},next:{title:"Resolvconf",permalink:"/docs/iaas/guides/configuration-guide/commons/resolvconf"}},d={},r=[{value:"Distribution specific packages",id:"distribution-specific-packages",level:2},{value:"Debian",id:"debian",level:3},{value:"CentOS",id:"centos",level:3},{value:"Upgrade of packages",id:"upgrade-of-packages",level:2}];function l(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"packages",children:"Packages"}),"\n",(0,s.jsxs)(n.p,{children:["With the ",(0,s.jsx)(n.code,{children:"osism.commons.packages"})," role, it is possible to add packages on a node\nThe parameters should be used in the inventory or in the\n",(0,s.jsx)(n.code,{children:"environments/configuration.yml"})," file."]}),"\n",(0,s.jsxs)(n.p,{children:["The role is applied during the bootstrap. The role can be applied manually using\n",(0,s.jsx)(n.code,{children:"osism apply packages"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The following packages are installed by default."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"required_packages_default:\n - curl\n - dmidecode\n - ethtool\n - iotop\n - jq\n - lsscsi\n - ltrace\n - mtr\n - nvme-cli\n - pciutils\n - rsyslog\n - socat\n - sysstat\n - tmux\n - tree\n - whois\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Additional packages can be added via the ",(0,s.jsx)(n.code,{children:"required_packages_extra"})," parameter."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"required_packages_extra: []\n"})}),"\n",(0,s.jsx)(n.h2,{id:"distribution-specific-packages",children:"Distribution specific packages"}),"\n",(0,s.jsx)(n.h3,{id:"debian",children:"Debian"}),"\n",(0,s.jsxs)(n.p,{children:["With Debian, the packages listed in ",(0,s.jsx)(n.code,{children:"required_packages_distribution"})," are installed by default."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"required_packages_distribution:\n - command-not-found\n - debconf\n - debsums\n - htop\n - iftop\n - iperf\n - multitail\n - ncdu\n - pv\n - python-is-python3\n - selinux-utils\n - ssh\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"apt_cache_valid_time"})," parameter can be used to set the ",(0,s.jsx)(n.code,{children:"cache_valid_time"})," paremter\nof the ",(0,s.jsx)(n.code,{children:"ansible.builtin.apt"})," module. The module updates the apt cache if it is older than\nthe ",(0,s.jsx)(n.code,{children:"cache_valid_time"}),". The parameter is set in seconds and defaults to ",(0,s.jsx)(n.code,{children:"3600"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"centos",children:"CentOS"}),"\n",(0,s.jsxs)(n.p,{children:["With CentOS, the packages listed in ",(0,s.jsx)(n.code,{children:"required_packages_distribution"})," are installed by default."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"required_packages_distribution:\n - libselinux-utils\n - openssh\n"})}),"\n",(0,s.jsx)(n.h2,{id:"upgrade-of-packages",children:"Upgrade of packages"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"upgrade_packages"})," parameter can be used to configure the upgrade of packages.\nThe parameter is set to ",(0,s.jsx)(n.code,{children:"true"})," by default."]})]})}function p(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>t,x:()=>o});var s=i(96540);const a={},c=s.createContext(a);function t(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:t(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/61171858.74c41916.js b/assets/js/61171858.74c41916.js new file mode 100644 index 0000000000..be83288fa0 --- /dev/null +++ b/assets/js/61171858.74c41916.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1400],{13943:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>o,contentTitle:()=>r,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var n=t(74848),c=t(28453);const i={sidebar_label:"Use cases",sidebar_position:40},r="Use cases",a={id:"iaas/guides/concept-guide/use-cases",title:"Use cases",description:"Hyper-converged infrastructure (HCI)",source:"@site/docs/02-iaas/guides/concept-guide/use-cases.md",sourceDirName:"02-iaas/guides/concept-guide",slug:"/iaas/guides/concept-guide/use-cases",permalink:"/docs/iaas/guides/concept-guide/use-cases",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/use-cases.md",tags:[],version:"current",sidebarPosition:40,frontMatter:{sidebar_label:"Use cases",sidebar_position:40},sidebar:"docs",previous:{title:"Cluster design",permalink:"/docs/iaas/guides/concept-guide/design"},next:{title:"Hardware Bill of Materials",permalink:"/docs/iaas/guides/concept-guide/hardware-bom"}},o={},d=[{value:"Hyper-converged infrastructure (HCI)",id:"hyper-converged-infrastructure-hci",level:2}];function u(e){const s={h1:"h1",h2:"h2",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"use-cases",children:"Use cases"}),"\n",(0,n.jsx)(s.h2,{id:"hyper-converged-infrastructure-hci",children:"Hyper-converged infrastructure (HCI)"})]})}function l(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>a});var n=t(96540);const c={},i=n.createContext(c);function r(e){const s=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),n.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6216.176d45ea.js b/assets/js/6216.176d45ea.js new file mode 100644 index 0000000000..2b2f9ccef2 --- /dev/null +++ b/assets/js/6216.176d45ea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6216],{66216:(t,e,s)=>{s.d(e,{d:()=>st,f:()=>et,p:()=>r});var u=s(26312),i=s(76257),n=function(){var t=function(t,e,s,u){for(s=s||{},u=t.length;u--;s[t[u]]=e);return s},e=[1,4],s=[1,3],u=[1,5],i=[1,8,9,10,11,27,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],n=[2,2],r=[1,13],a=[1,14],c=[1,15],o=[1,16],l=[1,23],h=[1,25],A=[1,26],d=[1,27],p=[1,49],y=[1,48],E=[1,29],f=[1,30],g=[1,31],k=[1,32],D=[1,33],b=[1,44],F=[1,46],T=[1,42],C=[1,47],_=[1,43],B=[1,50],S=[1,45],m=[1,51],x=[1,52],v=[1,34],L=[1,35],I=[1,36],R=[1,37],$=[1,57],N=[1,8,9,10,11,27,32,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],O=[1,61],w=[1,60],P=[1,62],U=[8,9,11,73,75],V=[1,88],G=[1,93],M=[1,92],K=[1,89],Y=[1,85],j=[1,91],X=[1,87],z=[1,94],H=[1,90],W=[1,95],Q=[1,86],q=[8,9,10,11,73,75],Z=[8,9,10,11,44,73,75],J=[8,9,10,11,29,42,44,46,48,50,52,54,56,58,61,63,65,66,68,73,75,86,99,102,103,106,108,111,112,113],tt=[8,9,11,42,58,73,75,86,99,102,103,106,108,111,112,113],et=[42,58,86,99,102,103,106,108,111,112,113],st=[1,121],ut=[1,120],it=[1,128],nt=[1,142],rt=[1,143],at=[1,144],ct=[1,145],ot=[1,130],lt=[1,132],ht=[1,136],At=[1,137],dt=[1,138],pt=[1,139],yt=[1,140],Et=[1,141],ft=[1,146],gt=[1,147],kt=[1,126],Dt=[1,127],bt=[1,134],Ft=[1,129],Tt=[1,133],Ct=[1,131],_t=[8,9,10,11,27,32,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],Bt=[1,149],St=[8,9,11],mt=[8,9,10,11,14,42,58,86,102,103,106,108,111,112,113],xt=[1,169],vt=[1,165],Lt=[1,166],It=[1,170],Rt=[1,167],$t=[1,168],Nt=[75,113,116],Ot=[8,9,10,11,12,14,27,29,32,42,58,73,81,82,83,84,85,86,87,102,106,108,111,112,113],wt=[10,103],Pt=[31,47,49,51,53,55,60,62,64,65,67,69,113,114,115],Ut=[1,235],Vt=[1,233],Gt=[1,237],Mt=[1,231],Kt=[1,232],Yt=[1,234],jt=[1,236],Xt=[1,238],zt=[1,255],Ht=[8,9,11,103],Wt=[8,9,10,11,58,81,102,103,106,107,108,109],Qt={trace:function(){},yy:{},symbols_:{error:2,start:3,graphConfig:4,document:5,line:6,statement:7,SEMI:8,NEWLINE:9,SPACE:10,EOF:11,GRAPH:12,NODIR:13,DIR:14,FirstStmtSeparator:15,ending:16,endToken:17,spaceList:18,spaceListNewline:19,vertexStatement:20,separator:21,styleStatement:22,linkStyleStatement:23,classDefStatement:24,classStatement:25,clickStatement:26,subgraph:27,textNoTags:28,SQS:29,text:30,SQE:31,end:32,direction:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,link:39,node:40,styledVertex:41,AMP:42,vertex:43,STYLE_SEPARATOR:44,idString:45,DOUBLECIRCLESTART:46,DOUBLECIRCLEEND:47,PS:48,PE:49,"(-":50,"-)":51,STADIUMSTART:52,STADIUMEND:53,SUBROUTINESTART:54,SUBROUTINEEND:55,VERTEX_WITH_PROPS_START:56,"NODE_STRING[field]":57,COLON:58,"NODE_STRING[value]":59,PIPE:60,CYLINDERSTART:61,CYLINDEREND:62,DIAMOND_START:63,DIAMOND_STOP:64,TAGEND:65,TRAPSTART:66,TRAPEND:67,INVTRAPSTART:68,INVTRAPEND:69,linkStatement:70,arrowText:71,TESTSTR:72,START_LINK:73,edgeText:74,LINK:75,edgeTextToken:76,STR:77,MD_STR:78,textToken:79,keywords:80,STYLE:81,LINKSTYLE:82,CLASSDEF:83,CLASS:84,CLICK:85,DOWN:86,UP:87,textNoTagsToken:88,stylesOpt:89,"idString[vertex]":90,"idString[class]":91,CALLBACKNAME:92,CALLBACKARGS:93,HREF:94,LINK_TARGET:95,"STR[link]":96,"STR[tooltip]":97,alphaNum:98,DEFAULT:99,numList:100,INTERPOLATE:101,NUM:102,COMMA:103,style:104,styleComponent:105,NODE_STRING:106,UNIT:107,BRKT:108,PCT:109,idStringToken:110,MINUS:111,MULT:112,UNICODE_TEXT:113,TEXT:114,TAGSTART:115,EDGE_TEXT:116,alphaNumToken:117,direction_tb:118,direction_bt:119,direction_rl:120,direction_lr:121,$accept:0,$end:1},terminals_:{2:"error",8:"SEMI",9:"NEWLINE",10:"SPACE",11:"EOF",12:"GRAPH",13:"NODIR",14:"DIR",27:"subgraph",29:"SQS",31:"SQE",32:"end",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",42:"AMP",44:"STYLE_SEPARATOR",46:"DOUBLECIRCLESTART",47:"DOUBLECIRCLEEND",48:"PS",49:"PE",50:"(-",51:"-)",52:"STADIUMSTART",53:"STADIUMEND",54:"SUBROUTINESTART",55:"SUBROUTINEEND",56:"VERTEX_WITH_PROPS_START",57:"NODE_STRING[field]",58:"COLON",59:"NODE_STRING[value]",60:"PIPE",61:"CYLINDERSTART",62:"CYLINDEREND",63:"DIAMOND_START",64:"DIAMOND_STOP",65:"TAGEND",66:"TRAPSTART",67:"TRAPEND",68:"INVTRAPSTART",69:"INVTRAPEND",72:"TESTSTR",73:"START_LINK",75:"LINK",77:"STR",78:"MD_STR",81:"STYLE",82:"LINKSTYLE",83:"CLASSDEF",84:"CLASS",85:"CLICK",86:"DOWN",87:"UP",90:"idString[vertex]",91:"idString[class]",92:"CALLBACKNAME",93:"CALLBACKARGS",94:"HREF",95:"LINK_TARGET",96:"STR[link]",97:"STR[tooltip]",99:"DEFAULT",101:"INTERPOLATE",102:"NUM",103:"COMMA",106:"NODE_STRING",107:"UNIT",108:"BRKT",109:"PCT",111:"MINUS",112:"MULT",113:"UNICODE_TEXT",114:"TEXT",115:"TAGSTART",116:"EDGE_TEXT",118:"direction_tb",119:"direction_bt",120:"direction_rl",121:"direction_lr"},productions_:[0,[3,2],[5,0],[5,2],[6,1],[6,1],[6,1],[6,1],[6,1],[4,2],[4,2],[4,2],[4,3],[16,2],[16,1],[17,1],[17,1],[17,1],[15,1],[15,1],[15,2],[19,2],[19,2],[19,1],[19,1],[18,2],[18,1],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,9],[7,6],[7,4],[7,1],[7,2],[7,2],[7,1],[21,1],[21,1],[21,1],[20,3],[20,4],[20,2],[20,1],[40,1],[40,5],[41,1],[41,3],[43,4],[43,4],[43,6],[43,4],[43,4],[43,4],[43,8],[43,4],[43,4],[43,4],[43,6],[43,4],[43,4],[43,4],[43,4],[43,4],[43,1],[39,2],[39,3],[39,3],[39,1],[39,3],[74,1],[74,2],[74,1],[74,1],[70,1],[71,3],[30,1],[30,2],[30,1],[30,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[28,1],[28,2],[28,1],[28,1],[24,5],[25,5],[26,2],[26,4],[26,3],[26,5],[26,3],[26,5],[26,5],[26,7],[26,2],[26,4],[26,2],[26,4],[26,4],[26,6],[22,5],[23,5],[23,5],[23,9],[23,9],[23,7],[23,7],[100,1],[100,3],[89,1],[89,3],[104,1],[104,2],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[79,1],[79,1],[79,1],[79,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[76,1],[76,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[45,1],[45,2],[98,1],[98,2],[33,1],[33,1],[33,1],[33,1]],performAction:function(t,e,s,u,i,n,r){var a=n.length-1;switch(i){case 2:case 28:case 29:case 30:case 31:case 32:this.$=[];break;case 3:(!Array.isArray(n[a])||n[a].length>0)&&n[a-1].push(n[a]),this.$=n[a-1];break;case 4:case 176:case 49:case 71:case 174:this.$=n[a];break;case 11:u.setDirection("TB"),this.$="TB";break;case 12:u.setDirection(n[a-1]),this.$=n[a-1];break;case 27:this.$=n[a-1].nodes;break;case 33:this.$=u.addSubGraph(n[a-6],n[a-1],n[a-4]);break;case 34:this.$=u.addSubGraph(n[a-3],n[a-1],n[a-3]);break;case 35:this.$=u.addSubGraph(void 0,n[a-1],void 0);break;case 37:this.$=n[a].trim(),u.setAccTitle(this.$);break;case 38:case 39:this.$=n[a].trim(),u.setAccDescription(this.$);break;case 43:u.addLink(n[a-2].stmt,n[a],n[a-1]),this.$={stmt:n[a],nodes:n[a].concat(n[a-2].nodes)};break;case 44:u.addLink(n[a-3].stmt,n[a-1],n[a-2]),this.$={stmt:n[a-1],nodes:n[a-1].concat(n[a-3].nodes)};break;case 45:this.$={stmt:n[a-1],nodes:n[a-1]};break;case 46:this.$={stmt:n[a],nodes:n[a]};break;case 47:case 121:case 123:this.$=[n[a]];break;case 48:this.$=n[a-4].concat(n[a]);break;case 50:this.$=n[a-2],u.setClass(n[a-2],n[a]);break;case 51:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"square");break;case 52:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"doublecircle");break;case 53:this.$=n[a-5],u.addVertex(n[a-5],n[a-2],"circle");break;case 54:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"ellipse");break;case 55:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"stadium");break;case 56:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"subroutine");break;case 57:this.$=n[a-7],u.addVertex(n[a-7],n[a-1],"rect",void 0,void 0,void 0,Object.fromEntries([[n[a-5],n[a-3]]]));break;case 58:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"cylinder");break;case 59:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"round");break;case 60:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"diamond");break;case 61:this.$=n[a-5],u.addVertex(n[a-5],n[a-2],"hexagon");break;case 62:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"odd");break;case 63:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"trapezoid");break;case 64:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"inv_trapezoid");break;case 65:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"lean_right");break;case 66:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"lean_left");break;case 67:this.$=n[a],u.addVertex(n[a]);break;case 68:n[a-1].text=n[a],this.$=n[a-1];break;case 69:case 70:n[a-2].text=n[a-1],this.$=n[a-2];break;case 72:var c=u.destructLink(n[a],n[a-2]);this.$={type:c.type,stroke:c.stroke,length:c.length,text:n[a-1]};break;case 73:case 79:case 94:case 96:this.$={text:n[a],type:"text"};break;case 74:case 80:case 95:this.$={text:n[a-1].text+""+n[a],type:n[a-1].type};break;case 75:case 81:this.$={text:n[a],type:"string"};break;case 76:case 82:case 97:this.$={text:n[a],type:"markdown"};break;case 77:c=u.destructLink(n[a]);this.$={type:c.type,stroke:c.stroke,length:c.length};break;case 78:this.$=n[a-1];break;case 98:this.$=n[a-4],u.addClass(n[a-2],n[a]);break;case 99:this.$=n[a-4],u.setClass(n[a-2],n[a]);break;case 100:case 108:this.$=n[a-1],u.setClickEvent(n[a-1],n[a]);break;case 101:case 109:this.$=n[a-3],u.setClickEvent(n[a-3],n[a-2]),u.setTooltip(n[a-3],n[a]);break;case 102:this.$=n[a-2],u.setClickEvent(n[a-2],n[a-1],n[a]);break;case 103:this.$=n[a-4],u.setClickEvent(n[a-4],n[a-3],n[a-2]),u.setTooltip(n[a-4],n[a]);break;case 104:this.$=n[a-2],u.setLink(n[a-2],n[a]);break;case 105:this.$=n[a-4],u.setLink(n[a-4],n[a-2]),u.setTooltip(n[a-4],n[a]);break;case 106:this.$=n[a-4],u.setLink(n[a-4],n[a-2],n[a]);break;case 107:this.$=n[a-6],u.setLink(n[a-6],n[a-4],n[a]),u.setTooltip(n[a-6],n[a-2]);break;case 110:this.$=n[a-1],u.setLink(n[a-1],n[a]);break;case 111:this.$=n[a-3],u.setLink(n[a-3],n[a-2]),u.setTooltip(n[a-3],n[a]);break;case 112:this.$=n[a-3],u.setLink(n[a-3],n[a-2],n[a]);break;case 113:this.$=n[a-5],u.setLink(n[a-5],n[a-4],n[a]),u.setTooltip(n[a-5],n[a-2]);break;case 114:this.$=n[a-4],u.addVertex(n[a-2],void 0,void 0,n[a]);break;case 115:this.$=n[a-4],u.updateLink([n[a-2]],n[a]);break;case 116:this.$=n[a-4],u.updateLink(n[a-2],n[a]);break;case 117:this.$=n[a-8],u.updateLinkInterpolate([n[a-6]],n[a-2]),u.updateLink([n[a-6]],n[a]);break;case 118:this.$=n[a-8],u.updateLinkInterpolate(n[a-6],n[a-2]),u.updateLink(n[a-6],n[a]);break;case 119:this.$=n[a-6],u.updateLinkInterpolate([n[a-4]],n[a]);break;case 120:this.$=n[a-6],u.updateLinkInterpolate(n[a-4],n[a]);break;case 122:case 124:n[a-2].push(n[a]),this.$=n[a-2];break;case 126:this.$=n[a-1]+n[a];break;case 175:case 177:this.$=n[a-1]+""+n[a];break;case 178:this.$={stmt:"dir",value:"TB"};break;case 179:this.$={stmt:"dir",value:"BT"};break;case 180:this.$={stmt:"dir",value:"RL"};break;case 181:this.$={stmt:"dir",value:"LR"}}},table:[{3:1,4:2,9:e,10:s,12:u},{1:[3]},t(i,n,{5:6}),{4:7,9:e,10:s,12:u},{4:8,9:e,10:s,12:u},{13:[1,9],14:[1,10]},{1:[2,1],6:11,7:12,8:r,9:a,10:c,11:o,20:17,22:18,23:19,24:20,25:21,26:22,27:l,33:24,34:h,36:A,38:d,40:28,41:38,42:p,43:39,45:40,58:y,81:E,82:f,83:g,84:k,85:D,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x,118:v,119:L,120:I,121:R},t(i,[2,9]),t(i,[2,10]),t(i,[2,11]),{8:[1,54],9:[1,55],10:$,15:53,18:56},t(N,[2,3]),t(N,[2,4]),t(N,[2,5]),t(N,[2,6]),t(N,[2,7]),t(N,[2,8]),{8:O,9:w,11:P,21:58,39:59,70:63,73:[1,64],75:[1,65]},{8:O,9:w,11:P,21:66},{8:O,9:w,11:P,21:67},{8:O,9:w,11:P,21:68},{8:O,9:w,11:P,21:69},{8:O,9:w,11:P,21:70},{8:O,9:w,10:[1,71],11:P,21:72},t(N,[2,36]),{35:[1,73]},{37:[1,74]},t(N,[2,39]),t(U,[2,46],{18:75,10:$}),{10:[1,76]},{10:[1,77]},{10:[1,78]},{10:[1,79]},{14:V,42:G,58:M,77:[1,83],86:K,92:[1,80],94:[1,81],98:82,102:Y,103:j,106:X,108:z,111:H,112:W,113:Q,117:84},t(N,[2,178]),t(N,[2,179]),t(N,[2,180]),t(N,[2,181]),t(q,[2,47]),t(q,[2,49],{44:[1,96]}),t(Z,[2,67],{110:109,29:[1,97],42:p,46:[1,98],48:[1,99],50:[1,100],52:[1,101],54:[1,102],56:[1,103],58:y,61:[1,104],63:[1,105],65:[1,106],66:[1,107],68:[1,108],86:b,99:F,102:T,103:C,106:_,108:B,111:S,112:m,113:x}),t(J,[2,174]),t(J,[2,135]),t(J,[2,136]),t(J,[2,137]),t(J,[2,138]),t(J,[2,139]),t(J,[2,140]),t(J,[2,141]),t(J,[2,142]),t(J,[2,143]),t(J,[2,144]),t(J,[2,145]),t(i,[2,12]),t(i,[2,18]),t(i,[2,19]),{9:[1,110]},t(tt,[2,26],{18:111,10:$}),t(N,[2,27]),{40:112,41:38,42:p,43:39,45:40,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},t(N,[2,40]),t(N,[2,41]),t(N,[2,42]),t(et,[2,71],{71:113,60:[1,115],72:[1,114]}),{74:116,76:117,77:[1,118],78:[1,119],113:st,116:ut},t([42,58,60,72,86,99,102,103,106,108,111,112,113],[2,77]),t(N,[2,28]),t(N,[2,29]),t(N,[2,30]),t(N,[2,31]),t(N,[2,32]),{10:it,12:nt,14:rt,27:at,28:122,32:ct,42:ot,58:lt,73:ht,77:[1,124],78:[1,125],80:135,81:At,82:dt,83:pt,84:yt,85:Et,86:ft,87:gt,88:123,102:kt,106:Dt,108:bt,111:Ft,112:Tt,113:Ct},t(_t,n,{5:148}),t(N,[2,37]),t(N,[2,38]),t(U,[2,45],{42:Bt}),{42:p,45:150,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},{99:[1,151],100:152,102:[1,153]},{42:p,45:154,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},{42:p,45:155,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},t(St,[2,100],{10:[1,156],93:[1,157]}),{77:[1,158]},t(St,[2,108],{117:160,10:[1,159],14:V,42:G,58:M,86:K,102:Y,103:j,106:X,108:z,111:H,112:W,113:Q}),t(St,[2,110],{10:[1,161]}),t(mt,[2,176]),t(mt,[2,163]),t(mt,[2,164]),t(mt,[2,165]),t(mt,[2,166]),t(mt,[2,167]),t(mt,[2,168]),t(mt,[2,169]),t(mt,[2,170]),t(mt,[2,171]),t(mt,[2,172]),t(mt,[2,173]),{42:p,45:162,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},{30:163,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:171,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:173,48:[1,172],65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:174,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:175,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:176,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{106:[1,177]},{30:178,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:179,63:[1,180],65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:181,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:182,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{30:183,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},t(J,[2,175]),t(i,[2,20]),t(tt,[2,25]),t(U,[2,43],{18:184,10:$}),t(et,[2,68],{10:[1,185]}),{10:[1,186]},{30:187,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{75:[1,188],76:189,113:st,116:ut},t(Nt,[2,73]),t(Nt,[2,75]),t(Nt,[2,76]),t(Nt,[2,161]),t(Nt,[2,162]),{8:O,9:w,10:it,11:P,12:nt,14:rt,21:191,27:at,29:[1,190],32:ct,42:ot,58:lt,73:ht,80:135,81:At,82:dt,83:pt,84:yt,85:Et,86:ft,87:gt,88:192,102:kt,106:Dt,108:bt,111:Ft,112:Tt,113:Ct},t(Ot,[2,94]),t(Ot,[2,96]),t(Ot,[2,97]),t(Ot,[2,150]),t(Ot,[2,151]),t(Ot,[2,152]),t(Ot,[2,153]),t(Ot,[2,154]),t(Ot,[2,155]),t(Ot,[2,156]),t(Ot,[2,157]),t(Ot,[2,158]),t(Ot,[2,159]),t(Ot,[2,160]),t(Ot,[2,83]),t(Ot,[2,84]),t(Ot,[2,85]),t(Ot,[2,86]),t(Ot,[2,87]),t(Ot,[2,88]),t(Ot,[2,89]),t(Ot,[2,90]),t(Ot,[2,91]),t(Ot,[2,92]),t(Ot,[2,93]),{6:11,7:12,8:r,9:a,10:c,11:o,20:17,22:18,23:19,24:20,25:21,26:22,27:l,32:[1,193],33:24,34:h,36:A,38:d,40:28,41:38,42:p,43:39,45:40,58:y,81:E,82:f,83:g,84:k,85:D,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x,118:v,119:L,120:I,121:R},{10:$,18:194},{10:[1,195],42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:109,111:S,112:m,113:x},{10:[1,196]},{10:[1,197],103:[1,198]},t(wt,[2,121]),{10:[1,199],42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:109,111:S,112:m,113:x},{10:[1,200],42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:109,111:S,112:m,113:x},{77:[1,201]},t(St,[2,102],{10:[1,202]}),t(St,[2,104],{10:[1,203]}),{77:[1,204]},t(mt,[2,177]),{77:[1,205],95:[1,206]},t(q,[2,50],{110:109,42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,111:S,112:m,113:x}),{31:[1,207],65:xt,79:208,113:It,114:Rt,115:$t},t(Pt,[2,79]),t(Pt,[2,81]),t(Pt,[2,82]),t(Pt,[2,146]),t(Pt,[2,147]),t(Pt,[2,148]),t(Pt,[2,149]),{47:[1,209],65:xt,79:208,113:It,114:Rt,115:$t},{30:210,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{49:[1,211],65:xt,79:208,113:It,114:Rt,115:$t},{51:[1,212],65:xt,79:208,113:It,114:Rt,115:$t},{53:[1,213],65:xt,79:208,113:It,114:Rt,115:$t},{55:[1,214],65:xt,79:208,113:It,114:Rt,115:$t},{58:[1,215]},{62:[1,216],65:xt,79:208,113:It,114:Rt,115:$t},{64:[1,217],65:xt,79:208,113:It,114:Rt,115:$t},{30:218,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},{31:[1,219],65:xt,79:208,113:It,114:Rt,115:$t},{65:xt,67:[1,220],69:[1,221],79:208,113:It,114:Rt,115:$t},{65:xt,67:[1,223],69:[1,222],79:208,113:It,114:Rt,115:$t},t(U,[2,44],{42:Bt}),t(et,[2,70]),t(et,[2,69]),{60:[1,224],65:xt,79:208,113:It,114:Rt,115:$t},t(et,[2,72]),t(Nt,[2,74]),{30:225,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},t(_t,n,{5:226}),t(Ot,[2,95]),t(N,[2,35]),{41:227,42:p,43:39,45:40,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},{10:Ut,58:Vt,81:Gt,89:228,102:Mt,104:229,105:230,106:Kt,107:Yt,108:jt,109:Xt},{10:Ut,58:Vt,81:Gt,89:239,101:[1,240],102:Mt,104:229,105:230,106:Kt,107:Yt,108:jt,109:Xt},{10:Ut,58:Vt,81:Gt,89:241,101:[1,242],102:Mt,104:229,105:230,106:Kt,107:Yt,108:jt,109:Xt},{102:[1,243]},{10:Ut,58:Vt,81:Gt,89:244,102:Mt,104:229,105:230,106:Kt,107:Yt,108:jt,109:Xt},{42:p,45:245,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},t(St,[2,101]),{77:[1,246]},{77:[1,247],95:[1,248]},t(St,[2,109]),t(St,[2,111],{10:[1,249]}),t(St,[2,112]),t(Z,[2,51]),t(Pt,[2,80]),t(Z,[2,52]),{49:[1,250],65:xt,79:208,113:It,114:Rt,115:$t},t(Z,[2,59]),t(Z,[2,54]),t(Z,[2,55]),t(Z,[2,56]),{106:[1,251]},t(Z,[2,58]),t(Z,[2,60]),{64:[1,252],65:xt,79:208,113:It,114:Rt,115:$t},t(Z,[2,62]),t(Z,[2,63]),t(Z,[2,65]),t(Z,[2,64]),t(Z,[2,66]),t([10,42,58,86,99,102,103,106,108,111,112,113],[2,78]),{31:[1,253],65:xt,79:208,113:It,114:Rt,115:$t},{6:11,7:12,8:r,9:a,10:c,11:o,20:17,22:18,23:19,24:20,25:21,26:22,27:l,32:[1,254],33:24,34:h,36:A,38:d,40:28,41:38,42:p,43:39,45:40,58:y,81:E,82:f,83:g,84:k,85:D,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x,118:v,119:L,120:I,121:R},t(q,[2,48]),t(St,[2,114],{103:zt}),t(Ht,[2,123],{105:256,10:Ut,58:Vt,81:Gt,102:Mt,106:Kt,107:Yt,108:jt,109:Xt}),t(Wt,[2,125]),t(Wt,[2,127]),t(Wt,[2,128]),t(Wt,[2,129]),t(Wt,[2,130]),t(Wt,[2,131]),t(Wt,[2,132]),t(Wt,[2,133]),t(Wt,[2,134]),t(St,[2,115],{103:zt}),{10:[1,257]},t(St,[2,116],{103:zt}),{10:[1,258]},t(wt,[2,122]),t(St,[2,98],{103:zt}),t(St,[2,99],{110:109,42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,111:S,112:m,113:x}),t(St,[2,103]),t(St,[2,105],{10:[1,259]}),t(St,[2,106]),{95:[1,260]},{49:[1,261]},{60:[1,262]},{64:[1,263]},{8:O,9:w,11:P,21:264},t(N,[2,34]),{10:Ut,58:Vt,81:Gt,102:Mt,104:265,105:230,106:Kt,107:Yt,108:jt,109:Xt},t(Wt,[2,126]),{14:V,42:G,58:M,86:K,98:266,102:Y,103:j,106:X,108:z,111:H,112:W,113:Q,117:84},{14:V,42:G,58:M,86:K,98:267,102:Y,103:j,106:X,108:z,111:H,112:W,113:Q,117:84},{95:[1,268]},t(St,[2,113]),t(Z,[2,53]),{30:269,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:$t},t(Z,[2,61]),t(_t,n,{5:270}),t(Ht,[2,124],{105:256,10:Ut,58:Vt,81:Gt,102:Mt,106:Kt,107:Yt,108:jt,109:Xt}),t(St,[2,119],{117:160,10:[1,271],14:V,42:G,58:M,86:K,102:Y,103:j,106:X,108:z,111:H,112:W,113:Q}),t(St,[2,120],{117:160,10:[1,272],14:V,42:G,58:M,86:K,102:Y,103:j,106:X,108:z,111:H,112:W,113:Q}),t(St,[2,107]),{31:[1,273],65:xt,79:208,113:It,114:Rt,115:$t},{6:11,7:12,8:r,9:a,10:c,11:o,20:17,22:18,23:19,24:20,25:21,26:22,27:l,32:[1,274],33:24,34:h,36:A,38:d,40:28,41:38,42:p,43:39,45:40,58:y,81:E,82:f,83:g,84:k,85:D,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x,118:v,119:L,120:I,121:R},{10:Ut,58:Vt,81:Gt,89:275,102:Mt,104:229,105:230,106:Kt,107:Yt,108:jt,109:Xt},{10:Ut,58:Vt,81:Gt,89:276,102:Mt,104:229,105:230,106:Kt,107:Yt,108:jt,109:Xt},t(Z,[2,57]),t(N,[2,33]),t(St,[2,117],{103:zt}),t(St,[2,118],{103:zt})],defaultActions:{},parseError:function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},parse:function(t){var e=this,s=[0],u=[],i=[null],n=[],r=this.table,a="",c=0,o=0,l=n.slice.call(arguments,1),h=Object.create(this.lexer),A={yy:{}};for(var d in this.yy)Object.prototype.hasOwnProperty.call(this.yy,d)&&(A.yy[d]=this.yy[d]);h.setInput(t,A.yy),A.yy.lexer=h,A.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var p=h.yylloc;n.push(p);var y=h.options&&h.options.ranges;"function"==typeof A.yy.parseError?this.parseError=A.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var E,f,g,k,D,b,F,T,C,_={};;){if(f=s[s.length-1],this.defaultActions[f]?g=this.defaultActions[f]:(null==E&&(C=void 0,"number"!=typeof(C=u.pop()||h.lex()||1)&&(C instanceof Array&&(C=(u=C).pop()),C=e.symbols_[C]||C),E=C),g=r[f]&&r[f][E]),void 0===g||!g.length||!g[0]){var B="";for(D in T=[],r[f])this.terminals_[D]&&D>2&&T.push("'"+this.terminals_[D]+"'");B=h.showPosition?"Parse error on line "+(c+1)+":\n"+h.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[E]||E)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==E?"end of input":"'"+(this.terminals_[E]||E)+"'"),this.parseError(B,{text:h.match,token:this.terminals_[E]||E,line:h.yylineno,loc:p,expected:T})}if(g[0]instanceof Array&&g.length>1)throw new Error("Parse Error: multiple actions possible at state: "+f+", token: "+E);switch(g[0]){case 1:s.push(E),i.push(h.yytext),n.push(h.yylloc),s.push(g[1]),E=null,o=h.yyleng,a=h.yytext,c=h.yylineno,p=h.yylloc;break;case 2:if(b=this.productions_[g[1]][1],_.$=i[i.length-b],_._$={first_line:n[n.length-(b||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(b||1)].first_column,last_column:n[n.length-1].last_column},y&&(_._$.range=[n[n.length-(b||1)].range[0],n[n.length-1].range[1]]),void 0!==(k=this.performAction.apply(_,[a,o,c,A.yy,g[1],i,n].concat(l))))return k;b&&(s=s.slice(0,-1*b*2),i=i.slice(0,-1*b),n=n.slice(0,-1*b)),s.push(this.productions_[g[1]][0]),i.push(_.$),n.push(_._$),F=r[s[s.length-2]][s[s.length-1]],s.push(F);break;case 3:return!0}}return!0}},qt={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var u=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===u.length?this.yylloc.first_column:0)+u[u.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var s,u,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(u=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=u.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:u?u[u.length-1].length-u[u.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var n in i)this[n]=i[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,s,u;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),n=0;n<i.length;n++)if((s=this._input.match(this.rules[i[n]]))&&(!e||s[0].length>e[0].length)){if(e=s,u=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,i[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[u]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,s,u){switch(s){case 0:return this.begin("acc_title"),34;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),36;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:case 8:case 11:case 14:case 17:case 27:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:this.begin("callbackname");break;case 9:this.popState(),this.begin("callbackargs");break;case 10:return 92;case 12:return 93;case 13:return"MD_STR";case 15:this.begin("md_string");break;case 16:return"STR";case 18:this.pushState("string");break;case 19:return 81;case 20:return 99;case 21:return 82;case 22:return 101;case 23:return 83;case 24:return 84;case 25:return 94;case 26:this.begin("click");break;case 28:return 85;case 29:case 30:case 31:return t.lex.firstGraph()&&this.begin("dir"),12;case 32:return 27;case 33:return 32;case 34:case 35:case 36:case 37:return 95;case 38:return this.popState(),13;case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 48:return this.popState(),14;case 49:return 118;case 50:return 119;case 51:return 120;case 52:return 121;case 53:return 102;case 54:case 95:return 108;case 55:return 44;case 56:return 58;case 57:case 96:return 42;case 58:return 8;case 59:return 103;case 60:case 94:return 112;case 61:case 64:case 67:return this.popState(),75;case 62:return this.pushState("edgeText"),73;case 63:case 66:case 69:return 116;case 65:return this.pushState("thickEdgeText"),73;case 68:return this.pushState("dottedEdgeText"),73;case 70:return 75;case 71:return this.popState(),51;case 72:case 108:return"TEXT";case 73:return this.pushState("ellipseText"),50;case 74:return this.popState(),53;case 75:return this.pushState("text"),52;case 76:return this.popState(),55;case 77:return this.pushState("text"),54;case 78:return 56;case 79:return this.pushState("text"),65;case 80:return this.popState(),62;case 81:return this.pushState("text"),61;case 82:return this.popState(),47;case 83:return this.pushState("text"),46;case 84:return this.popState(),67;case 85:return this.popState(),69;case 86:return 114;case 87:return this.pushState("trapText"),66;case 88:return this.pushState("trapText"),68;case 89:return 115;case 90:return 65;case 91:return 87;case 92:return"SEP";case 93:return 86;case 97:return 106;case 98:return 111;case 99:return 113;case 100:return this.popState(),60;case 101:return this.pushState("text"),60;case 102:return this.popState(),49;case 103:return this.pushState("text"),48;case 104:return this.popState(),31;case 105:return this.pushState("text"),29;case 106:return this.popState(),64;case 107:return this.pushState("text"),63;case 109:return"QUOTE";case 110:return 9;case 111:return 10;case 112:return 11}},rules:[/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["][`])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:["])/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s])/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:flowchart-elk\b)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:[^-]|-(?!-)+)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:[^=]|=(?!))/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:[^\.]|\.(?!))/,/^(?:\s*~~[\~]+\s*)/,/^(?:[-/\)][\)])/,/^(?:[^\(\)\[\]\{\}]|!\)+)/,/^(?:\(-)/,/^(?:\]\))/,/^(?:\(\[)/,/^(?:\]\])/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:>)/,/^(?:\)\])/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\(\(\()/,/^(?:[\\(?=\])][\]])/,/^(?:\/(?=\])\])/,/^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:\*)/,/^(?:#)/,/^(?:&)/,/^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/,/^(?:-)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\|)/,/^(?:\))/,/^(?:\()/,/^(?:\])/,/^(?:\[)/,/^(?:(\}))/,/^(?:\{)/,/^(?:[^\[\]\(\)\{\}\|\"]+)/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{callbackargs:{rules:[11,12,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},callbackname:{rules:[8,9,10,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},href:{rules:[15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},click:{rules:[15,18,27,28,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},dottedEdgeText:{rules:[15,18,67,69,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},thickEdgeText:{rules:[15,18,64,66,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},edgeText:{rules:[15,18,61,63,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},trapText:{rules:[15,18,70,73,75,77,81,83,84,85,86,87,88,101,103,105,107],inclusive:!1},ellipseText:{rules:[15,18,70,71,72,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},text:{rules:[15,18,70,73,74,75,76,77,80,81,82,83,87,88,100,101,102,103,104,105,106,107,108],inclusive:!1},vertex:{rules:[15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},dir:{rules:[15,18,38,39,40,41,42,43,44,45,46,47,48,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},acc_descr_multiline:{rules:[5,6,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},acc_descr:{rules:[3,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},acc_title:{rules:[1,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},md_string:{rules:[13,14,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},string:{rules:[15,16,17,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},INITIAL:{rules:[0,2,4,7,15,18,19,20,21,22,23,24,25,26,29,30,31,32,33,34,35,36,37,49,50,51,52,53,54,55,56,57,58,59,60,61,62,64,65,67,68,70,73,75,77,78,79,81,83,87,88,89,90,91,92,93,94,95,96,97,98,99,101,103,105,107,109,110,111,112],inclusive:!0}}};function Zt(){this.yy={}}return Qt.lexer=qt,Zt.prototype=Qt,Qt.Parser=Zt,new Zt}();n.parser=n;const r=n;let a,c,o=0,l=(0,i.c)(),h={},A=[],d={},p=[],y={},E={},f=0,g=!0,k=[];const D=t=>i.e.sanitizeText(t,l),b=function(t){const e=Object.keys(h);for(const s of e)if(h[s].id===t)return h[s].domId;return t},F=function(t,e,s,u,n,r,a={}){let c,A=t;void 0!==A&&0!==A.trim().length&&(void 0===h[A]&&(h[A]={id:A,labelType:"text",domId:"flowchart-"+A+"-"+o,styles:[],classes:[]}),o++,void 0!==e?(l=(0,i.c)(),c=D(e.text.trim()),h[A].labelType=e.type,'"'===c[0]&&'"'===c[c.length-1]&&(c=c.substring(1,c.length-1)),h[A].text=c):void 0===h[A].text&&(h[A].text=t),void 0!==s&&(h[A].type=s),null!=u&&u.forEach((function(t){h[A].styles.push(t)})),null!=n&&n.forEach((function(t){h[A].classes.push(t)})),void 0!==r&&(h[A].dir=r),void 0===h[A].props?h[A].props=a:void 0!==a&&Object.assign(h[A].props,a))},T=function(t,e,s){const u={start:t,end:e,type:void 0,text:"",labelType:"text"};i.l.info("abc78 Got edge...",u);const n=s.text;if(void 0!==n&&(u.text=D(n.text.trim()),'"'===u.text[0]&&'"'===u.text[u.text.length-1]&&(u.text=u.text.substring(1,u.text.length-1)),u.labelType=n.type),void 0!==s&&(u.type=s.type,u.stroke=s.stroke,u.length=s.length),(null==u?void 0:u.length)>10&&(u.length=10),!(A.length<(l.maxEdges??500)))throw new Error(`Edge limit exceeded. ${A.length} edges found, but the limit is ${l.maxEdges}.\n\nInitialize mermaid with maxEdges set to a higher number to allow more edges.\nYou cannot set this config via configuration inside the diagram as it is a secure config.\nYou have to call mermaid.initialize.`);i.l.info("abc78 pushing edge..."),A.push(u)},C=function(t,e,s){let u,n;for(i.l.info("addLink (abc78)",t,e,s),u=0;u<t.length;u++)for(n=0;n<e.length;n++)T(t[u],e[n],s)},_=function(t,e){t.forEach((function(t){"default"===t?A.defaultInterpolate=e:A[t].interpolate=e}))},B=function(t,e){t.forEach((function(t){if(t>=A.length)throw new Error(`The index ${t} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${A.length-1}. (Help: Ensure that the index is within the range of existing edges.)`);"default"===t?A.defaultStyle=e:(-1===i.u.isSubstringInArray("fill",e)&&e.push("fill:none"),A[t].style=e)}))},S=function(t,e){t.split(",").forEach((function(t){void 0===d[t]&&(d[t]={id:t,styles:[],textStyles:[]}),null!=e&&e.forEach((function(e){if(e.match("color")){const s=e.replace("fill","bgFill").replace("color","fill");d[t].textStyles.push(s)}d[t].styles.push(e)}))}))},m=function(t){a=t,a.match(/.*</)&&(a="RL"),a.match(/.*\^/)&&(a="BT"),a.match(/.*>/)&&(a="LR"),a.match(/.*v/)&&(a="TB"),"TD"===a&&(a="TB")},x=function(t,e){t.split(",").forEach((function(t){let s=t;void 0!==h[s]&&h[s].classes.push(e),void 0!==y[s]&&y[s].classes.push(e)}))},v=function(t,e,s){t.split(",").forEach((function(t){void 0!==h[t]&&(h[t].link=i.u.formatUrl(e,l),h[t].linkTarget=s)})),x(t,"clickable")},L=function(t){if(E.hasOwnProperty(t))return E[t]},I=function(t,e,s){t.split(",").forEach((function(t){!function(t,e,s){let u=b(t);if("loose"!==(0,i.c)().securityLevel)return;if(void 0===e)return;let n=[];if("string"==typeof s){n=s.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t<n.length;t++){let e=n[t].trim();'"'===e.charAt(0)&&'"'===e.charAt(e.length-1)&&(e=e.substr(1,e.length-2)),n[t]=e}}0===n.length&&n.push(t),void 0!==h[t]&&(h[t].haveCallback=!0,k.push((function(){const t=document.querySelector(`[id="${u}"]`);null!==t&&t.addEventListener("click",(function(){i.u.runFunc(e,...n)}),!1)})))}(t,e,s)})),x(t,"clickable")},R=function(t){k.forEach((function(e){e(t)}))},$=function(){return a.trim()},N=function(){return h},O=function(){return A},w=function(){return d},P=function(t){let e=(0,u.Ltv)(".mermaidTooltip");null===(e._groups||e)[0][0]&&(e=(0,u.Ltv)("body").append("div").attr("class","mermaidTooltip").style("opacity",0));(0,u.Ltv)(t).select("svg").selectAll("g.node").on("mouseover",(function(){const t=(0,u.Ltv)(this);if(null===t.attr("title"))return;const s=this.getBoundingClientRect();e.transition().duration(200).style("opacity",".9"),e.text(t.attr("title")).style("left",window.scrollX+s.left+(s.right-s.left)/2+"px").style("top",window.scrollY+s.bottom+"px"),e.html(e.html().replace(/<br\/>/g,"<br/>")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0);(0,u.Ltv)(this).classed("hover",!1)}))};k.push(P);const U=function(t="gen-1"){h={},d={},A=[],k=[P],p=[],y={},f=0,E={},g=!0,c=t,l=(0,i.c)(),(0,i.v)()},V=t=>{c=t||"gen-2"},G=function(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"},M=function(t,e,s){let u=t.text.trim(),n=s.text;t===s&&s.text.match(/\s/)&&(u=void 0);let r=[];const{nodeList:a,dir:o}=function(t){const e={boolean:{},number:{},string:{}},s=[];let u;return{nodeList:t.filter((function(t){const i=typeof t;return t.stmt&&"dir"===t.stmt?(u=t.value,!1):""!==t.trim()&&(i in e?!e[i].hasOwnProperty(t)&&(e[i][t]=!0):!s.includes(t)&&s.push(t))})),dir:u}}(r.concat.apply(r,e));if(r=a,"gen-1"===c)for(let i=0;i<r.length;i++)r[i]=b(r[i]);u=u||"subGraph"+f,n=n||"",n=D(n),f+=1;const l={id:u,nodes:r,title:n.trim(),classes:[],dir:o,labelType:s.type};return i.l.info("Adding",l.id,l.nodes,l.dir),l.nodes=J(l,p).nodes,p.push(l),y[u]=l,u},K=function(t){for(const[e,s]of p.entries())if(s.id===t)return e;return-1};let Y=-1;const j=[],X=function(t,e){const s=p[e].nodes;if(Y+=1,Y>2e3)return;if(j[Y]=e,p[e].id===t)return{result:!0,count:0};let u=0,i=1;for(;u<s.length;){const e=K(s[u]);if(e>=0){const s=X(t,e);if(s.result)return{result:!0,count:i+s.count};i+=s.count}u+=1}return{result:!1,count:i}},z=function(t){return j[t]},H=function(){Y=-1,p.length>0&&X("none",p.length-1)},W=function(){return p},Q=()=>!!g&&(g=!1,!0),q=(t,e)=>{const s=(t=>{const e=t.trim();let s=e.slice(0,-1),u="arrow_open";switch(e.slice(-1)){case"x":u="arrow_cross","x"===e[0]&&(u="double_"+u,s=s.slice(1));break;case">":u="arrow_point","<"===e[0]&&(u="double_"+u,s=s.slice(1));break;case"o":u="arrow_circle","o"===e[0]&&(u="double_"+u,s=s.slice(1))}let i="normal",n=s.length-1;"="===s[0]&&(i="thick"),"~"===s[0]&&(i="invisible");let r=((t,e)=>{const s=e.length;let u=0;for(let i=0;i<s;++i)e[i]===t&&++u;return u})(".",s);return r&&(i="dotted",n=r),{type:u,stroke:i,length:n}})(t);let u;if(e){if(u=(t=>{let e=t.trim(),s="arrow_open";switch(e[0]){case"<":s="arrow_point",e=e.slice(1);break;case"x":s="arrow_cross",e=e.slice(1);break;case"o":s="arrow_circle",e=e.slice(1)}let u="normal";return e.includes("=")&&(u="thick"),e.includes(".")&&(u="dotted"),{type:s,stroke:u}})(e),u.stroke!==s.stroke)return{type:"INVALID",stroke:"INVALID"};if("arrow_open"===u.type)u.type=s.type;else{if(u.type!==s.type)return{type:"INVALID",stroke:"INVALID"};u.type="double_"+u.type}return"double_arrow"===u.type&&(u.type="double_arrow_point"),u.length=s.length,u}return s},Z=(t,e)=>{let s=!1;return t.forEach((t=>{t.nodes.indexOf(e)>=0&&(s=!0)})),s},J=(t,e)=>{const s=[];return t.nodes.forEach(((u,i)=>{Z(e,u)||s.push(t.nodes[i])})),{nodes:s}},tt={firstGraph:Q},et={defaultConfig:()=>i.K.flowchart,setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,addVertex:F,lookUpDomId:b,addLink:C,updateLinkInterpolate:_,updateLink:B,addClass:S,setDirection:m,setClass:x,setTooltip:function(t,e){t.split(",").forEach((function(t){void 0!==e&&(E["gen-1"===c?b(t):t]=D(e))}))},getTooltip:L,setClickEvent:I,setLink:v,bindFunctions:R,getDirection:$,getVertices:N,getEdges:O,getClasses:w,clear:U,setGen:V,defaultStyle:G,addSubGraph:M,getDepthFirstPos:z,indexNodes:H,getSubGraphs:W,destructLink:q,lex:tt,exists:Z,makeUniq:J,setDiagramTitle:i.q,getDiagramTitle:i.t},st=Object.freeze(Object.defineProperty({__proto__:null,addClass:S,addLink:C,addSingleLink:T,addSubGraph:M,addVertex:F,bindFunctions:R,clear:U,default:et,defaultStyle:G,destructLink:q,firstGraph:Q,getClasses:w,getDepthFirstPos:z,getDirection:$,getEdges:O,getSubGraphs:W,getTooltip:L,getVertices:N,indexNodes:H,lex:tt,lookUpDomId:b,setClass:x,setClickEvent:I,setDirection:m,setGen:V,setLink:v,updateLink:B,updateLinkInterpolate:_},Symbol.toStringTag,{value:"Module"}))}}]); \ No newline at end of file diff --git a/assets/js/62337dff.5679955b.js b/assets/js/62337dff.5679955b.js new file mode 100644 index 0000000000..69d2c6c98f --- /dev/null +++ b/assets/js/62337dff.5679955b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9376],{6851:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var a=n(74848),o=n(28453);const r={},i="Team IAM",s={id:"collaboration/team-iam",title:"Team IAM",description:"The Team IAM deals with topics around Identity and Access Management.",source:"@site/community/collaboration/team-iam.md",sourceDirName:"collaboration",slug:"/collaboration/team-iam",permalink:"/community/collaboration/team-iam",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Team Iaas",permalink:"/community/collaboration/team-iaas"},next:{title:"Team Container",permalink:"/community/collaboration/team-container"}},c={},d=[];function m(e){const t={h1:"h1",p:"p",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h1,{id:"team-iam",children:"Team IAM"}),"\n",(0,a.jsx)(t.p,{children:"The Team IAM deals with topics around Identity and Access Management."}),"\n",(0,a.jsx)(t.p,{children:"Users that access cloud and container infrastructure need to authenticate themselves and then authorizations to see and access resources from the infrastructure are derived from the identity of the users as they belong to groups and are roles are assigned to them (or the groups they belong to)."}),"\n",(0,a.jsx)(t.p,{children:"Sovereign Cloud Stack has the goal that user identities can used across several layers in the stack (most importantly IaaS and Container layer), that user management should be a self-service capability and that user identities can be federated, i.e. user identities and authentication from one SCS cloud (or from one standards-compliant Identity Provider) can be used in other SCS clouds. Federation is an imporant principle in SCS."})]})}function l(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(m,{...e})}):m(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var a=n(96540);const o={},r=a.createContext(o);function i(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6292.394c3d84.js b/assets/js/6292.394c3d84.js new file mode 100644 index 0000000000..cd91cff249 --- /dev/null +++ b/assets/js/6292.394c3d84.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6292],{26292:(t,e,s)=>{s.d(e,{D:()=>l,S:()=>c,a:()=>h,b:()=>a,c:()=>o,d:()=>B,p:()=>r,s:()=>P});var i=s(76257),n=function(){var t=function(t,e,s,i){for(s=s||{},i=t.length;i--;s[t[i]]=e);return s},e=[1,2],s=[1,3],i=[1,4],n=[2,4],r=[1,9],o=[1,11],a=[1,15],c=[1,16],l=[1,17],h=[1,18],u=[1,30],d=[1,19],p=[1,20],y=[1,21],f=[1,22],m=[1,23],g=[1,25],S=[1,26],_=[1,27],k=[1,28],T=[1,29],b=[1,32],E=[1,33],x=[1,34],C=[1,35],$=[1,31],v=[1,4,5,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],D=[1,4,5,13,14,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],A=[4,5,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],L={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,cssClassStatement:11,idStatement:12,DESCR:13,"--\x3e":14,HIDE_EMPTY:15,scale:16,WIDTH:17,COMPOSIT_STATE:18,STRUCT_START:19,STRUCT_STOP:20,STATE_DESCR:21,AS:22,ID:23,FORK:24,JOIN:25,CHOICE:26,CONCURRENT:27,note:28,notePosition:29,NOTE_TEXT:30,direction:31,acc_title:32,acc_title_value:33,acc_descr:34,acc_descr_value:35,acc_descr_multiline_value:36,classDef:37,CLASSDEF_ID:38,CLASSDEF_STYLEOPTS:39,DEFAULT:40,class:41,CLASSENTITY_IDS:42,STYLECLASS:43,direction_tb:44,direction_bt:45,direction_rl:46,direction_lr:47,eol:48,";":49,EDGE_STATE:50,STYLE_SEPARATOR:51,left_of:52,right_of:53,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",13:"DESCR",14:"--\x3e",15:"HIDE_EMPTY",16:"scale",17:"WIDTH",18:"COMPOSIT_STATE",19:"STRUCT_START",20:"STRUCT_STOP",21:"STATE_DESCR",22:"AS",23:"ID",24:"FORK",25:"JOIN",26:"CHOICE",27:"CONCURRENT",28:"note",30:"NOTE_TEXT",32:"acc_title",33:"acc_title_value",34:"acc_descr",35:"acc_descr_value",36:"acc_descr_multiline_value",37:"classDef",38:"CLASSDEF_ID",39:"CLASSDEF_STYLEOPTS",40:"DEFAULT",41:"class",42:"CLASSENTITY_IDS",43:"STYLECLASS",44:"direction_tb",45:"direction_bt",46:"direction_rl",47:"direction_lr",49:";",50:"EDGE_STATE",51:"STYLE_SEPARATOR",52:"left_of",53:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,1],[9,4],[9,4],[9,1],[9,2],[9,2],[9,1],[10,3],[10,3],[11,3],[31,1],[31,1],[31,1],[31,1],[48,1],[48,1],[12,1],[12,1],[12,3],[12,3],[29,1],[29,1]],performAction:function(t,e,s,i,n,r,o){var a=r.length-1;switch(n){case 3:return i.setRootDoc(r[a]),r[a];case 4:this.$=[];break;case 5:"nl"!=r[a]&&(r[a-1].push(r[a]),this.$=r[a-1]);break;case 6:case 7:case 11:this.$=r[a];break;case 8:this.$="nl";break;case 12:const t=r[a-1];t.description=i.trimColon(r[a]),this.$=t;break;case 13:this.$={stmt:"relation",state1:r[a-2],state2:r[a]};break;case 14:const e=i.trimColon(r[a]);this.$={stmt:"relation",state1:r[a-3],state2:r[a-1],description:e};break;case 18:this.$={stmt:"state",id:r[a-3],type:"default",description:"",doc:r[a-1]};break;case 19:var c=r[a],l=r[a-2].trim();if(r[a].match(":")){var h=r[a].split(":");c=h[0],l=[l,h[1]]}this.$={stmt:"state",id:c,type:"default",description:l};break;case 20:this.$={stmt:"state",id:r[a-3],type:"default",description:r[a-5],doc:r[a-1]};break;case 21:this.$={stmt:"state",id:r[a],type:"fork"};break;case 22:this.$={stmt:"state",id:r[a],type:"join"};break;case 23:this.$={stmt:"state",id:r[a],type:"choice"};break;case 24:this.$={stmt:"state",id:i.getDividerId(),type:"divider"};break;case 25:this.$={stmt:"state",id:r[a-1].trim(),note:{position:r[a-2].trim(),text:r[a].trim()}};break;case 28:this.$=r[a].trim(),i.setAccTitle(this.$);break;case 29:case 30:this.$=r[a].trim(),i.setAccDescription(this.$);break;case 31:case 32:this.$={stmt:"classDef",id:r[a-1].trim(),classes:r[a].trim()};break;case 33:this.$={stmt:"applyClass",id:r[a-1].trim(),styleClass:r[a].trim()};break;case 34:i.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 35:i.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 36:i.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 37:i.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 40:case 41:this.$={stmt:"state",id:r[a].trim(),type:"default",description:""};break;case 42:case 43:this.$={stmt:"state",id:r[a-2].trim(),classes:[r[a].trim()],type:"default",description:""}}},table:[{3:1,4:e,5:s,6:i},{1:[3]},{3:5,4:e,5:s,6:i},{3:6,4:e,5:s,6:i},t([1,4,5,15,16,18,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],n,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:r,5:o,8:8,9:10,10:12,11:13,12:14,15:a,16:c,18:l,21:h,23:u,24:d,25:p,26:y,27:f,28:m,31:24,32:g,34:S,36:_,37:k,41:T,44:b,45:E,46:x,47:C,50:$},t(v,[2,5]),{9:36,10:12,11:13,12:14,15:a,16:c,18:l,21:h,23:u,24:d,25:p,26:y,27:f,28:m,31:24,32:g,34:S,36:_,37:k,41:T,44:b,45:E,46:x,47:C,50:$},t(v,[2,7]),t(v,[2,8]),t(v,[2,9]),t(v,[2,10]),t(v,[2,11],{13:[1,37],14:[1,38]}),t(v,[2,15]),{17:[1,39]},t(v,[2,17],{19:[1,40]}),{22:[1,41]},t(v,[2,21]),t(v,[2,22]),t(v,[2,23]),t(v,[2,24]),{29:42,30:[1,43],52:[1,44],53:[1,45]},t(v,[2,27]),{33:[1,46]},{35:[1,47]},t(v,[2,30]),{38:[1,48],40:[1,49]},{42:[1,50]},t(D,[2,40],{51:[1,51]}),t(D,[2,41],{51:[1,52]}),t(v,[2,34]),t(v,[2,35]),t(v,[2,36]),t(v,[2,37]),t(v,[2,6]),t(v,[2,12]),{12:53,23:u,50:$},t(v,[2,16]),t(A,n,{7:54}),{23:[1,55]},{23:[1,56]},{22:[1,57]},{23:[2,44]},{23:[2,45]},t(v,[2,28]),t(v,[2,29]),{39:[1,58]},{39:[1,59]},{43:[1,60]},{23:[1,61]},{23:[1,62]},t(v,[2,13],{13:[1,63]}),{4:r,5:o,8:8,9:10,10:12,11:13,12:14,15:a,16:c,18:l,20:[1,64],21:h,23:u,24:d,25:p,26:y,27:f,28:m,31:24,32:g,34:S,36:_,37:k,41:T,44:b,45:E,46:x,47:C,50:$},t(v,[2,19],{19:[1,65]}),{30:[1,66]},{23:[1,67]},t(v,[2,31]),t(v,[2,32]),t(v,[2,33]),t(D,[2,42]),t(D,[2,43]),t(v,[2,14]),t(v,[2,18]),t(A,n,{7:68}),t(v,[2,25]),t(v,[2,26]),{4:r,5:o,8:8,9:10,10:12,11:13,12:14,15:a,16:c,18:l,20:[1,69],21:h,23:u,24:d,25:p,26:y,27:f,28:m,31:24,32:g,34:S,36:_,37:k,41:T,44:b,45:E,46:x,47:C,50:$},t(v,[2,20])],defaultActions:{5:[2,1],6:[2,2],44:[2,44],45:[2,45]},parseError:function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},parse:function(t){var e=this,s=[0],i=[],n=[null],r=[],o=this.table,a="",c=0,l=0,h=r.slice.call(arguments,1),u=Object.create(this.lexer),d={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(d.yy[p]=this.yy[p]);u.setInput(t,d.yy),d.yy.lexer=u,d.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var y=u.yylloc;r.push(y);var f=u.options&&u.options.ranges;"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var m,g,S,_,k,T,b,E,x,C={};;){if(g=s[s.length-1],this.defaultActions[g]?S=this.defaultActions[g]:(null==m&&(x=void 0,"number"!=typeof(x=i.pop()||u.lex()||1)&&(x instanceof Array&&(x=(i=x).pop()),x=e.symbols_[x]||x),m=x),S=o[g]&&o[g][m]),void 0===S||!S.length||!S[0]){var $="";for(k in E=[],o[g])this.terminals_[k]&&k>2&&E.push("'"+this.terminals_[k]+"'");$=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError($,{text:u.match,token:this.terminals_[m]||m,line:u.yylineno,loc:y,expected:E})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+m);switch(S[0]){case 1:s.push(m),n.push(u.yytext),r.push(u.yylloc),s.push(S[1]),m=null,l=u.yyleng,a=u.yytext,c=u.yylineno,y=u.yylloc;break;case 2:if(T=this.productions_[S[1]][1],C.$=n[n.length-T],C._$={first_line:r[r.length-(T||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(T||1)].first_column,last_column:r[r.length-1].last_column},f&&(C._$.range=[r[r.length-(T||1)].range[0],r[r.length-1].range[1]]),void 0!==(_=this.performAction.apply(C,[a,l,c,d.yy,S[1],n,r].concat(h))))return _;T&&(s=s.slice(0,-1*T*2),n=n.slice(0,-1*T),r=r.slice(0,-1*T)),s.push(this.productions_[S[1]][0]),n.push(C.$),r.push(C._$),b=o[s[s.length-2]][s[s.length-1]],s.push(b);break;case 3:return!0}}return!0}},I={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===i.length?this.yylloc.first_column:0)+i[i.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var s,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,s,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;r<n.length;r++)if((s=this._input.match(this.rules[n[r]]))&&(!e||s[0].length>e[0].length)){if(e=s,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,n[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,s,i){switch(s){case 0:return 40;case 1:case 39:return 44;case 2:case 40:return 45;case 3:case 41:return 46;case 4:case 42:return 47;case 5:case 6:case 8:case 9:case 10:case 11:case 51:case 53:case 59:break;case 7:case 74:return 5;case 12:case 29:return this.pushState("SCALE"),16;case 13:case 30:return 17;case 14:case 20:case 31:case 46:case 49:this.popState();break;case 15:return this.begin("acc_title"),32;case 16:return this.popState(),"acc_title_value";case 17:return this.begin("acc_descr"),34;case 18:return this.popState(),"acc_descr_value";case 19:this.begin("acc_descr_multiline");break;case 21:return"acc_descr_multiline_value";case 22:return this.pushState("CLASSDEF"),37;case 23:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 24:return this.popState(),this.pushState("CLASSDEFID"),38;case 25:return this.popState(),39;case 26:return this.pushState("CLASS"),41;case 27:return this.popState(),this.pushState("CLASS_STYLE"),42;case 28:return this.popState(),43;case 32:this.pushState("STATE");break;case 33:case 36:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),24;case 34:case 37:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),25;case 35:case 38:return this.popState(),e.yytext=e.yytext.slice(0,-10).trim(),26;case 43:this.pushState("STATE_STRING");break;case 44:return this.pushState("STATE_ID"),"AS";case 45:case 61:return this.popState(),"ID";case 47:return"STATE_DESCR";case 48:return 18;case 50:return this.popState(),this.pushState("struct"),19;case 52:return this.popState(),20;case 54:return this.begin("NOTE"),28;case 55:return this.popState(),this.pushState("NOTE_ID"),52;case 56:return this.popState(),this.pushState("NOTE_ID"),53;case 57:this.popState(),this.pushState("FLOATING_NOTE");break;case 58:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 60:return"NOTE_TEXT";case 62:return this.popState(),this.pushState("NOTE_TEXT"),23;case 63:return this.popState(),e.yytext=e.yytext.substr(2).trim(),30;case 64:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),30;case 65:case 66:return 6;case 67:return 15;case 68:return 50;case 69:return 23;case 70:return e.yytext=e.yytext.trim(),13;case 71:return 14;case 72:return 27;case 73:return 51;case 75:return"INVALID"}},rules:[/^(?:default\b)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:classDef\s+)/i,/^(?:DEFAULT\s+)/i,/^(?:\w+\s+)/i,/^(?:[^\n]*)/i,/^(?:class\s+)/i,/^(?:(\w+)+((,\s*\w+)*))/i,/^(?:[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<<fork>>)/i,/^(?:.*<<join>>)/i,/^(?:.*<<choice>>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?::::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[9,10],inclusive:!1},struct:{rules:[9,10,22,26,32,39,40,41,42,51,52,53,54,68,69,70,71,72],inclusive:!1},FLOATING_NOTE_ID:{rules:[61],inclusive:!1},FLOATING_NOTE:{rules:[58,59,60],inclusive:!1},NOTE_TEXT:{rules:[63,64],inclusive:!1},NOTE_ID:{rules:[62],inclusive:!1},NOTE:{rules:[55,56,57],inclusive:!1},CLASS_STYLE:{rules:[28],inclusive:!1},CLASS:{rules:[27],inclusive:!1},CLASSDEFID:{rules:[25],inclusive:!1},CLASSDEF:{rules:[23,24],inclusive:!1},acc_descr_multiline:{rules:[20,21],inclusive:!1},acc_descr:{rules:[18],inclusive:!1},acc_title:{rules:[16],inclusive:!1},SCALE:{rules:[13,14,30,31],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[45],inclusive:!1},STATE_STRING:{rules:[46,47],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[9,10,33,34,35,36,37,38,43,44,48,49,50],inclusive:!1},ID:{rules:[9,10],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,10,11,12,15,17,19,22,26,29,32,50,54,65,66,67,68,69,70,71,73,74,75],inclusive:!0}}};function O(){this.yy={}}return L.lexer=I,O.prototype=L,L.Parser=O,new O}();n.parser=n;const r=n,o="TB",a="state",c="relation",l="default",h="divider",u="[*]",d="start",p=u,y="color",f="fill";let m="LR",g=[],S={};let _={root:{relations:[],states:{},documents:{}}},k=_.root,T=0,b=0;const E=t=>JSON.parse(JSON.stringify(t)),x=(t,e,s)=>{if(e.stmt===c)x(t,e.state1,!0),x(t,e.state2,!1);else if(e.stmt===a&&("[*]"===e.id?(e.id=s?t.id+"_start":t.id+"_end",e.start=s):e.id=e.id.trim()),e.doc){const t=[];let s,n=[];for(s=0;s<e.doc.length;s++)if(e.doc[s].type===h){const i=E(e.doc[s]);i.doc=E(n),t.push(i),n=[]}else n.push(e.doc[s]);if(t.length>0&&n.length>0){const s={stmt:a,id:(0,i.I)(),type:"divider",doc:E(n)};t.push(E(s)),e.doc=t}e.doc.forEach((t=>x(e,t,!0)))}},C=function(t,e=l,s=null,n=null,r=null,o=null,a=null,c=null){const h=null==t?void 0:t.trim();if(void 0===k.states[h]?(i.l.info("Adding state ",h,n),k.states[h]={id:h,descriptions:[],type:e,doc:s,note:r,classes:[],styles:[],textStyles:[]}):(k.states[h].doc||(k.states[h].doc=s),k.states[h].type||(k.states[h].type=e)),n&&(i.l.info("Setting state description",h,n),"string"==typeof n&&I(h,n.trim()),"object"==typeof n&&n.forEach((t=>I(h,t.trim())))),r&&(k.states[h].note=r,k.states[h].note.text=i.e.sanitizeText(k.states[h].note.text,(0,i.c)())),o){i.l.info("Setting state classes",h,o);("string"==typeof o?[o]:o).forEach((t=>N(h,t.trim())))}if(a){i.l.info("Setting state styles",h,a);("string"==typeof a?[a]:a).forEach((t=>R(h,t.trim())))}if(c){i.l.info("Setting state styles",h,a);("string"==typeof c?[c]:c).forEach((t=>w(h,t.trim())))}},$=function(t){_={root:{relations:[],states:{},documents:{}}},k=_.root,T=0,S={},t||(0,i.v)()},v=function(t){return k.states[t]};function D(t=""){let e=t;return t===u&&(T++,e=`${d}${T}`),e}function A(t="",e=l){return t===u?d:e}const L=function(t,e,s){if("object"==typeof t)!function(t,e,s){let n=D(t.id.trim()),r=A(t.id.trim(),t.type),o=D(e.id.trim()),a=A(e.id.trim(),e.type);C(n,r,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles),C(o,a,e.doc,e.description,e.note,e.classes,e.styles,e.textStyles),k.relations.push({id1:n,id2:o,relationTitle:i.e.sanitizeText(s,(0,i.c)())})}(t,e,s);else{const n=D(t.trim()),r=A(t),o=function(t=""){let e=t;return t===p&&(T++,e=`end${T}`),e}(e.trim()),a=function(t="",e=l){return t===p?"end":e}(e);C(n,r),C(o,a),k.relations.push({id1:n,id2:o,title:i.e.sanitizeText(s,(0,i.c)())})}},I=function(t,e){const s=k.states[t],n=e.startsWith(":")?e.replace(":","").trim():e;s.descriptions.push(i.e.sanitizeText(n,(0,i.c)()))},O=function(t,e=""){void 0===S[t]&&(S[t]={id:t,styles:[],textStyles:[]});const s=S[t];null!=e&&e.split(",").forEach((t=>{const e=t.replace(/([^;]*);/,"$1").trim();if(t.match(y)){const t=e.replace(f,"bgFill").replace(y,f);s.textStyles.push(t)}s.styles.push(e)}))},N=function(t,e){t.split(",").forEach((function(t){let s=v(t);if(void 0===s){const e=t.trim();C(e),s=v(e)}s.classes.push(e)}))},R=function(t,e){const s=v(t);void 0!==s&&s.textStyles.push(e)},w=function(t,e){const s=v(t);void 0!==s&&s.textStyles.push(e)},B={getConfig:()=>(0,i.c)().state,addState:C,clear:$,getState:v,getStates:function(){return k.states},getRelations:function(){return k.relations},getClasses:function(){return S},getDirection:()=>m,addRelation:L,getDividerId:()=>(b++,"divider-id-"+b),setDirection:t=>{m=t},cleanupLabel:function(t){return":"===t.substring(0,1)?t.substr(2).trim():t.trim()},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3},logDocuments:function(){i.l.info("Documents = ",_)},getRootDoc:()=>g,setRootDoc:t=>{i.l.info("Setting root doc",t),g=t},getRootDocV2:()=>(x({id:"root"},{id:"root",doc:g},!0),{id:"root",doc:g}),extract:t=>{let e;e=t.doc?t.doc:t,i.l.info(e),$(!0),i.l.info("Extract",e),e.forEach((t=>{switch(t.stmt){case a:C(t.id.trim(),t.type,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles);break;case c:L(t.state1,t.state2,t.description);break;case"classDef":O(t.id.trim(),t.classes);break;case"applyClass":N(t.id.trim(),t.styleClass)}}))},trimColon:t=>t&&":"===t[0]?t.substr(1).trim():t.trim(),getAccTitle:i.g,setAccTitle:i.s,getAccDescription:i.a,setAccDescription:i.b,addStyleClass:O,setCssClass:N,addDescription:I,setDiagramTitle:i.q,getDiagramTitle:i.t},P=t=>`\ndefs #statediagram-barbEnd {\n fill: ${t.transitionColor};\n stroke: ${t.transitionColor};\n }\ng.stateGroup text {\n fill: ${t.nodeBorder};\n stroke: none;\n font-size: 10px;\n}\ng.stateGroup text {\n fill: ${t.textColor};\n stroke: none;\n font-size: 10px;\n\n}\ng.stateGroup .state-title {\n font-weight: bolder;\n fill: ${t.stateLabelColor};\n}\n\ng.stateGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.stateGroup line {\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.transition {\n stroke: ${t.transitionColor};\n stroke-width: 1;\n fill: none;\n}\n\n.stateGroup .composit {\n fill: ${t.background};\n border-bottom: 1px\n}\n\n.stateGroup .alt-composit {\n fill: #e0e0e0;\n border-bottom: 1px\n}\n\n.state-note {\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n\n text {\n fill: ${t.noteTextColor};\n stroke: none;\n font-size: 10px;\n }\n}\n\n.stateLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.edgeLabel .label rect {\n fill: ${t.labelBackgroundColor};\n opacity: 0.5;\n}\n.edgeLabel .label text {\n fill: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n.label div .edgeLabel {\n color: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n\n.stateLabel text {\n fill: ${t.stateLabelColor};\n font-size: 10px;\n font-weight: bold;\n}\n\n.node circle.state-start {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node .fork-join {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node circle.state-end {\n fill: ${t.innerEndBackground};\n stroke: ${t.background};\n stroke-width: 1.5\n}\n.end-state-inner {\n fill: ${t.compositeBackground||t.background};\n // stroke: ${t.background};\n stroke-width: 1.5\n}\n\n.node rect {\n fill: ${t.stateBkg||t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n.node polygon {\n fill: ${t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};;\n stroke-width: 1px;\n}\n#statediagram-barbEnd {\n fill: ${t.lineColor};\n}\n\n.statediagram-cluster rect {\n fill: ${t.compositeTitleBackground};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n\n.cluster-label, .nodeLabel {\n color: ${t.stateLabelColor};\n}\n\n.statediagram-cluster rect.outer {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state .divider {\n stroke: ${t.stateBorder||t.nodeBorder};\n}\n\n.statediagram-state .title-state {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-cluster.statediagram-cluster .inner {\n fill: ${t.compositeBackground||t.background};\n}\n.statediagram-cluster.statediagram-cluster-alt .inner {\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.statediagram-cluster .inner {\n rx:0;\n ry:0;\n}\n\n.statediagram-state rect.basic {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state rect.divider {\n stroke-dasharray: 10,10;\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.note-edge {\n stroke-dasharray: 5;\n}\n\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n\n.statediagram-note text {\n fill: ${t.noteTextColor};\n}\n\n.statediagram-note .nodeLabel {\n color: ${t.noteTextColor};\n}\n.statediagram .edgeLabel {\n color: red; // ${t.noteTextColor};\n}\n\n#dependencyStart, #dependencyEnd {\n fill: ${t.lineColor};\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.statediagramTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`}}]); \ No newline at end of file diff --git a/assets/js/63.65521a84.js b/assets/js/63.65521a84.js new file mode 100644 index 0000000000..f544564fed --- /dev/null +++ b/assets/js/63.65521a84.js @@ -0,0 +1,742 @@ +"use strict"; +exports.id = 63; +exports.ids = [63]; +exports.modules = { + +/***/ 36063: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99418); + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 3], $V1 = [1, 4], $V2 = [1, 5], $V3 = [1, 6], $V4 = [1, 10, 12, 14, 16, 18, 19, 20, 21, 22], $V5 = [2, 4], $V6 = [1, 5, 10, 12, 14, 16, 18, 19, 20, 21, 22], $V7 = [20, 21, 22], $V8 = [2, 7], $V9 = [1, 12], $Va = [1, 13], $Vb = [1, 14], $Vc = [1, 15], $Vd = [1, 16], $Ve = [1, 17]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "eol": 4, "PIE": 5, "document": 6, "showData": 7, "line": 8, "statement": 9, "txt": 10, "value": 11, "title": 12, "title_value": 13, "acc_title": 14, "acc_title_value": 15, "acc_descr": 16, "acc_descr_value": 17, "acc_descr_multiline_value": 18, "section": 19, "NEWLINE": 20, ";": 21, "EOF": 22, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 5: "PIE", 7: "showData", 10: "txt", 11: "value", 12: "title", 13: "title_value", 14: "acc_title", 15: "acc_title_value", 16: "acc_descr", 17: "acc_descr_value", 18: "acc_descr_multiline_value", 19: "section", 20: "NEWLINE", 21: ";", 22: "EOF" }, + productions_: [0, [3, 2], [3, 2], [3, 3], [6, 0], [6, 2], [8, 2], [9, 0], [9, 2], [9, 2], [9, 2], [9, 2], [9, 1], [9, 1], [4, 1], [4, 1], [4, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 3: + yy.setShowData(true); + break; + case 6: + this.$ = $$[$0 - 1]; + break; + case 8: + yy.addSection($$[$0 - 1], yy.cleanupValue($$[$0])); + break; + case 9: + this.$ = $$[$0].trim(); + yy.setDiagramTitle(this.$); + break; + case 10: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 11: + case 12: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 13: + yy.addSection($$[$0].substr(8)); + this.$ = $$[$0].substr(8); + break; + } + }, + table: [{ 3: 1, 4: 2, 5: $V0, 20: $V1, 21: $V2, 22: $V3 }, { 1: [3] }, { 3: 7, 4: 2, 5: $V0, 20: $V1, 21: $V2, 22: $V3 }, o($V4, $V5, { 6: 8, 7: [1, 9] }), o($V6, [2, 14]), o($V6, [2, 15]), o($V6, [2, 16]), { 1: [2, 1] }, o($V7, $V8, { 8: 10, 9: 11, 1: [2, 2], 10: $V9, 12: $Va, 14: $Vb, 16: $Vc, 18: $Vd, 19: $Ve }), o($V4, $V5, { 6: 18 }), o($V4, [2, 5]), { 4: 19, 20: $V1, 21: $V2, 22: $V3 }, { 11: [1, 20] }, { 13: [1, 21] }, { 15: [1, 22] }, { 17: [1, 23] }, o($V7, [2, 12]), o($V7, [2, 13]), o($V7, $V8, { 8: 10, 9: 11, 1: [2, 3], 10: $V9, 12: $Va, 14: $Vb, 16: $Vc, 18: $Vd, 19: $Ve }), o($V4, [2, 6]), o($V7, [2, 8]), o($V7, [2, 9]), o($V7, [2, 10]), o($V7, [2, 11])], + defaultActions: { 7: [2, 1] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + break; + case 1: + break; + case 2: + return 20; + case 3: + break; + case 4: + break; + case 5: + this.begin("title"); + return 12; + case 6: + this.popState(); + return "title_value"; + case 7: + this.begin("acc_title"); + return 14; + case 8: + this.popState(); + return "acc_title_value"; + case 9: + this.begin("acc_descr"); + return 16; + case 10: + this.popState(); + return "acc_descr_value"; + case 11: + this.begin("acc_descr_multiline"); + break; + case 12: + this.popState(); + break; + case 13: + return "acc_descr_multiline_value"; + case 14: + this.begin("string"); + break; + case 15: + this.popState(); + break; + case 16: + return "txt"; + case 17: + return 5; + case 18: + return 7; + case 19: + return "value"; + case 20: + return 22; + } + }, + rules: [/^(?:%%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[\n\r]+)/i, /^(?:%%[^\n]*)/i, /^(?:[\s]+)/i, /^(?:title\b)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:pie\b)/i, /^(?:showData\b)/i, /^(?::[\s]*[\d]+(?:\.[\d]+)?)/i, /^(?:$)/i], + conditions: { "acc_descr_multiline": { "rules": [12, 13], "inclusive": false }, "acc_descr": { "rules": [10], "inclusive": false }, "acc_title": { "rules": [8], "inclusive": false }, "title": { "rules": [6], "inclusive": false }, "string": { "rules": [15, 16], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 7, 9, 11, 14, 17, 18, 19, 20], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const DEFAULT_PIE_CONFIG = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.B.pie; +const DEFAULT_PIE_DB = { + sections: {}, + showData: false, + config: DEFAULT_PIE_CONFIG +}; +let sections = DEFAULT_PIE_DB.sections; +let showData = DEFAULT_PIE_DB.showData; +const config = structuredClone(DEFAULT_PIE_CONFIG); +const getConfig = () => structuredClone(config); +const clear = () => { + sections = structuredClone(DEFAULT_PIE_DB.sections); + showData = DEFAULT_PIE_DB.showData; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.v)(); +}; +const addSection = (label, value) => { + label = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.d)(label, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + if (sections[label] === void 0) { + sections[label] = value; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(`added new section: ${label}, with value: ${value}`); + } +}; +const getSections = () => sections; +const cleanupValue = (value) => { + if (value.substring(0, 1) === ":") { + value = value.substring(1).trim(); + } + return Number(value.trim()); +}; +const setShowData = (toggle) => { + showData = toggle; +}; +const getShowData = () => showData; +const db = { + getConfig, + clear, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.t, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.g, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.b, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.a, + addSection, + getSections, + cleanupValue, + setShowData, + getShowData +}; +const getStyles = (options) => ` + .pieCircle{ + stroke: ${options.pieStrokeColor}; + stroke-width : ${options.pieStrokeWidth}; + opacity : ${options.pieOpacity}; + } + .pieOuterCircle{ + stroke: ${options.pieOuterStrokeColor}; + stroke-width: ${options.pieOuterStrokeWidth}; + fill: none; + } + .pieTitleText { + text-anchor: middle; + font-size: ${options.pieTitleTextSize}; + fill: ${options.pieTitleTextColor}; + font-family: ${options.fontFamily}; + } + .slice { + font-family: ${options.fontFamily}; + fill: ${options.pieSectionTextColor}; + font-size:${options.pieSectionTextSize}; + // fill: white; + } + .legend text { + fill: ${options.pieLegendTextColor}; + font-family: ${options.fontFamily}; + font-size: ${options.pieLegendTextSize}; + } +`; +const styles = getStyles; +const createPieArcs = (sections2) => { + const pieData = Object.entries(sections2).map((element) => { + return { + label: element[0], + value: element[1] + }; + }).sort((a, b) => { + return b.value - a.value; + }); + const pie$1 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .pie */ .rLf)().value( + (d3Section) => d3Section.value + ); + return pie$1(pieData); +}; +const draw = (text, id, _version, diagObj) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("rendering pie chart\n" + text); + const db2 = diagObj.db; + const globalConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const pieConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.C)(db2.getConfig(), globalConfig.pie); + const MARGIN = 40; + const LEGEND_RECT_SIZE = 18; + const LEGEND_SPACING = 4; + const height = 450; + const pieWidth = height; + const svg = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.A)(id); + const group = svg.append("g"); + const sections2 = db2.getSections(); + group.attr("transform", "translate(" + pieWidth / 2 + "," + height / 2 + ")"); + const { themeVariables } = globalConfig; + let [outerStrokeWidth] = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.D)(themeVariables.pieOuterStrokeWidth); + outerStrokeWidth ?? (outerStrokeWidth = 2); + const textPosition = pieConfig.textPosition; + const radius = Math.min(pieWidth, height) / 2 - MARGIN; + const arcGenerator = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .arc */ .JLW)().innerRadius(0).outerRadius(radius); + const labelArcGenerator = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .arc */ .JLW)().innerRadius(radius * textPosition).outerRadius(radius * textPosition); + group.append("circle").attr("cx", 0).attr("cy", 0).attr("r", radius + outerStrokeWidth / 2).attr("class", "pieOuterCircle"); + const arcs = createPieArcs(sections2); + const myGeneratedColors = [ + themeVariables.pie1, + themeVariables.pie2, + themeVariables.pie3, + themeVariables.pie4, + themeVariables.pie5, + themeVariables.pie6, + themeVariables.pie7, + themeVariables.pie8, + themeVariables.pie9, + themeVariables.pie10, + themeVariables.pie11, + themeVariables.pie12 + ]; + const color = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleOrdinal */ .UMr)(myGeneratedColors); + group.selectAll("mySlices").data(arcs).enter().append("path").attr("d", arcGenerator).attr("fill", (datum) => { + return color(datum.data.label); + }).attr("class", "pieCircle"); + let sum = 0; + Object.keys(sections2).forEach((key) => { + sum += sections2[key]; + }); + group.selectAll("mySlices").data(arcs).enter().append("text").text((datum) => { + return (datum.data.value / sum * 100).toFixed(0) + "%"; + }).attr("transform", (datum) => { + return "translate(" + labelArcGenerator.centroid(datum) + ")"; + }).style("text-anchor", "middle").attr("class", "slice"); + group.append("text").text(db2.getDiagramTitle()).attr("x", 0).attr("y", -(height - 50) / 2).attr("class", "pieTitleText"); + const legend = group.selectAll(".legend").data(color.domain()).enter().append("g").attr("class", "legend").attr("transform", (_datum, index) => { + const height2 = LEGEND_RECT_SIZE + LEGEND_SPACING; + const offset = height2 * color.domain().length / 2; + const horizontal = 12 * LEGEND_RECT_SIZE; + const vertical = index * height2 - offset; + return "translate(" + horizontal + "," + vertical + ")"; + }); + legend.append("rect").attr("width", LEGEND_RECT_SIZE).attr("height", LEGEND_RECT_SIZE).style("fill", color).style("stroke", color); + legend.data(arcs).append("text").attr("x", LEGEND_RECT_SIZE + LEGEND_SPACING).attr("y", LEGEND_RECT_SIZE - LEGEND_SPACING).text((datum) => { + const { label, value } = datum.data; + if (db2.getShowData()) { + return `${label} [${value}]`; + } + return label; + }); + const longestTextWidth = Math.max( + ...legend.selectAll("text").nodes().map((node) => (node == null ? void 0 : node.getBoundingClientRect().width) ?? 0) + ); + const totalWidth = pieWidth + MARGIN + LEGEND_RECT_SIZE + LEGEND_SPACING + longestTextWidth; + svg.attr("viewBox", `0 0 ${totalWidth} ${height}`); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.i)(svg, height, totalWidth, pieConfig.useMaxWidth); +}; +const renderer = { draw }; +const diagram = { + parser: parser$1, + db, + renderer, + styles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/63c8fde6.f8e64bd7.js b/assets/js/63c8fde6.f8e64bd7.js new file mode 100644 index 0000000000..1ee580fb09 --- /dev/null +++ b/assets/js/63c8fde6.f8e64bd7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4168],{97877:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=t(74848),i=t(28453);const r={title:"SCS Entropy",type:"Standard",status:"Stable",stabilized_at:new Date("2024-02-08T00:00:00.000Z"),track:"IaaS",description:"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations\nsuch as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and\nactivating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy\naccessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into\nvirtual instances and ensures the availability and quality of entropy in virtual environments, promoting system\nsecurity and efficiency.\n"},o=void 0,a={id:"scs-0101-v1-entropy",title:"SCS Entropy",description:"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations\nsuch as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and\nactivating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy\naccessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into\nvirtual instances and ensures the availability and quality of entropy in virtual environments, promoting system\nsecurity and efficiency.\n",source:"@site/standards/scs-0101-v1-entropy.md",sourceDirName:".",slug:"/scs-0101-v1-entropy",permalink:"/standards/scs-0101-v1-entropy",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS Entropy",type:"Standard",status:"Stable",stabilized_at:"2024-02-08T00:00:00.000Z",track:"IaaS",description:"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations\nsuch as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and\nactivating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy\naccessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into\nvirtual instances and ensures the availability and quality of entropy in virtual environments, promoting system\nsecurity and efficiency.\n"},sidebar:"standards",previous:{title:"scs-0101: SCS Entropy",permalink:"/standards/iaas/scs-0101"},next:{title:"SCS Entropy: Implementation and Testing Notes",permalink:"/standards/scs-0101-w1-entropy-implementation-testing"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Entropy in information technology",id:"entropy-in-information-technology",level:3},{value:"Real-world uses of entropy",id:"real-world-uses-of-entropy",level:3},{value:"Sources of entropy",id:"sources-of-entropy",level:3},{value:"Entropy in virtual instances",id:"entropy-in-virtual-instances",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Entropy in SCS clouds",id:"entropy-in-scs-clouds",level:2},{value:"Flavors",id:"flavors",level:3},{value:"Images",id:"images",level:3},{value:"Compute nodes",id:"compute-nodes",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.h3,{id:"entropy-in-information-technology",children:"Entropy in information technology"}),"\n",(0,s.jsx)(n.p,{children:"Entropy is a concept that is widely used in the scope of information\ntechnology. It is a measurement of the amount of disorder or randomness in\na system. Entropy is used to measure the amount of information in a\nself-contained system, as well as the amount of incertitude that exists in this\nsystem."}),"\n",(0,s.jsx)(n.h3,{id:"real-world-uses-of-entropy",children:"Real-world uses of entropy"}),"\n",(0,s.jsxs)(n.p,{children:["Cryptography is a very prominent, albeit not the only application that\nheavily relies on entropy for operations such as creating secure keys.\nWhen the available ",(0,s.jsx)(n.em,{children:"entropy runs out"}),", said operations can stall and\ntake an abnormally long amount of time, which in turn can lead to\nmalfunctions, e.g., with OpenSSL or load balancers."]}),"\n",(0,s.jsx)(n.h3,{id:"sources-of-entropy",children:"Sources of entropy"}),"\n",(0,s.jsxs)(n.p,{children:["In ",(0,s.jsx)(n.em,{children:"traditional baremetal systems"})," the amount of incertitude is sourced\nfrom the randomness of the read/write cycles of the disk heads of a disk drive,\nbus timings, or keyboard timings, to name a few."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"More recent methods"})," of generating entropy include measuring IRQ jitter\n(available in Linux since kernel 5.4 or, before that, via a daemon such as\n",(0,s.jsx)(n.a,{href:"http://www.issihosts.com/haveged/",children:"HavegeD"}),") as well as dedicated CPU\ninstructions (available in virtually all major CPUs: RDSEED or RDRAND\non x86_64 and RNDR on arm64)."]}),"\n",(0,s.jsxs)(n.p,{children:["Finally, a dedicated device can be utilized \u2014 if present \u2014 that is\ncalled ",(0,s.jsx)(n.em,{children:"hardware random number generator"})," or HRNG for short. For instance,\nthe ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Trusted_Platform_Module",children:"Trusted Platform Module"}),"\nincludes a HRNG. On Linux systems, the HRNG appears as ",(0,s.jsx)(n.code,{children:"/dev/hwrng"}),".\nNote that, while the dedicated CPU instructions can be construed as\na HRNG, they are not treated as such by the kernel, i.e., they ",(0,s.jsx)(n.em,{children:"do not"}),"\nappear as ",(0,s.jsx)(n.code,{children:"/dev/hwrng"}),"!"]}),"\n",(0,s.jsxs)(n.p,{children:["The Linux kernel combines multiple sources of entropy into a pool. To this\nend, it will use all of the sources discussed so far with one exception:\nthe HRNG must be fed into the pool (if so desired) via the daemon ",(0,s.jsx)(n.code,{children:"rngd"}),".\nThe kernel converts the entropy from the pool into cryptographically\nsecure random numbers that appear under ",(0,s.jsx)(n.code,{children:"/dev/random"})," and ",(0,s.jsx)(n.code,{children:"/dev/urandom"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["With kernel 5.18, the algorithm that accomplishes\nsaid conversion has been drastically improved (see\n",(0,s.jsx)(n.a,{href:"https://web.archive.org/web/20230321040526/https://www.zx2c4.com/projects/linux-rng-5.17-5.18/",children:"linux-rng-5.17-18"}),"),\nso much so that running out of entropy is virtually ruled out.\nThese patches have now also arrived in the upstream LTS images."]}),"\n",(0,s.jsx)(n.h3,{id:"entropy-in-virtual-instances",children:"Entropy in virtual instances"}),"\n",(0,s.jsx)(n.p,{children:"Virtual instances or virtual machines do not have the traditional sources\nof entropy mentioned above. However, the more recent methods mentioned\nabove do work just fine (the CPU instructions are not privileged)."}),"\n",(0,s.jsxs)(n.p,{children:["Alternatively, a virtualized HRNG called ",(0,s.jsx)(n.code,{children:"virtio-rng"})," can be established\nthat injects entropy from the host into the instance, where this\nentropy can be sourced optionally from either the host's ",(0,s.jsx)(n.code,{children:"/dev/random"})," or\nsome HRNG in the host. This virtualized HRNG behaves just like a real\none, that is, it appears as ",(0,s.jsx)(n.code,{children:"/dev/hwrng"}),", and the daemon ",(0,s.jsx)(n.code,{children:"rngd"})," must\nbe used to feed it into the kernel's entropy pool."]}),"\n",(0,s.jsxs)(n.p,{children:["On a side note, the kernel exposes available HRNGs via the special\ndirectory ",(0,s.jsx)(n.code,{children:"/sys/devices/virtual/misc/hw_random"}),". In particular, the\nfile ",(0,s.jsx)(n.code,{children:"rng_available"})," lists availabe HRNGs while the file ",(0,s.jsx)(n.code,{children:"rng_current"}),"\ncontains the HRNG currently used."]}),"\n",(0,s.jsxs)(n.p,{children:["In summary, with current kernels and CPUs entropy in virtual instances\nis readily available to a sufficient degree. In addition, the host's\nentropy sources can be injected using ",(0,s.jsx)(n.code,{children:"virtio-rng"})," if so desired, e.g.,\nto enable access to a HRNG."]}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(n.p,{children:"As stated above, good sources of entropy are paramount for many\nimportant applications. This standard ensures that sufficient entropy\nwill be available in virtual instances."}),"\n",(0,s.jsx)(n.h2,{id:"entropy-in-scs-clouds",children:"Entropy in SCS clouds"}),"\n",(0,s.jsx)(n.h3,{id:"flavors",children:"Flavors"}),"\n",(0,s.jsx)(n.p,{children:"It is recommended that all flavors have the following attribute:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",children:"hw_rng:allowed=True\n"})}),"\n",(0,s.jsx)(n.p,{children:"The following attributes are optional:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",children:"hw_rng:rate_bytes - The allowed amount of bytes for the the guest\n to read from the host's entropy per period.\nhw_rng:rate_period - Sets the duration of a read period in seconds.\n"})}),"\n",(0,s.jsx)(n.h3,{id:"images",children:"Images"}),"\n",(0,s.jsxs)(n.p,{children:["It is recommended to use images having a kernel (patch level) version 5.18\nor up. This condition is already satisfied by every mandatory image defined\nin the ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0102-v1-image-metadata.md",children:"Image Metadata Standard"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["It is recommended that images activate the attribute ",(0,s.jsx)(n.code,{children:"hw_rng_model: virtio"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The daemon ",(0,s.jsx)(n.code,{children:"rngd"})," must be installed (usually from ",(0,s.jsx)(n.code,{children:"rng-tools"}),"\nor ",(0,s.jsx)(n.code,{children:"rng-utils"}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["The user may choose to use the ",(0,s.jsx)(n.code,{children:"virtio-rng"})," device via ",(0,s.jsx)(n.code,{children:"rngd"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"compute-nodes",children:"Compute nodes"}),"\n",(0,s.jsx)(n.p,{children:"Compute nodes must use CPUs that offer instructions for accessing\nentropy (such as RDSEED or RDRAND on x86_64 or RNDR on arm64), and\nthese instructions may not be filtered by the hypervisor."}),"\n",(0,s.jsxs)(n.p,{children:["Compute nodes may provide a HRNG via ",(0,s.jsx)(n.code,{children:"rngd"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/640bb4cf.0cfb36a2.js b/assets/js/640bb4cf.0cfb36a2.js new file mode 100644 index 0000000000..3a2f8044d8 --- /dev/null +++ b/assets/js/640bb4cf.0cfb36a2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6358],{23243:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var a=t(74848),s=t(28453);const i={title:"SCS Flavor Naming Standard: Implementation and Testing Notes",type:"Supplement",track:"IaaS",status:"Proposal",supplements:["scs-0100-v1-flavor-naming.md","scs-0100-v2-flavor-naming.md","scs-0100-v3-flavor-naming.md"]},o=void 0,r={id:"scs-0100-w1-flavor-naming-implementation-testing",title:"SCS Flavor Naming Standard: Implementation and Testing Notes",description:"Introduction",source:"@site/standards/scs-0100-w1-flavor-naming-implementation-testing.md",sourceDirName:".",slug:"/scs-0100-w1-flavor-naming-implementation-testing",permalink:"/standards/scs-0100-w1-flavor-naming-implementation-testing",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS Flavor Naming Standard: Implementation and Testing Notes",type:"Supplement",track:"IaaS",status:"Proposal",supplements:["scs-0100-v1-flavor-naming.md","scs-0100-v2-flavor-naming.md","scs-0100-v3-flavor-naming.md"]},sidebar:"standards",previous:{title:"SCS Flavor Naming Standard",permalink:"/standards/scs-0100-v3-flavor-naming"},next:{title:"scs-0101: SCS Entropy",permalink:"/standards/iaas/scs-0101"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Implementation Notes",id:"implementation-notes",level:2},{value:"Operational Tooling",id:"operational-tooling",level:3},{value:"Syntax Check",id:"syntax-check",level:4},{value:"Flavor Creation",id:"flavor-creation",level:4},{value:"Automated Tests",id:"automated-tests",level:2},{value:"Errors",id:"errors",level:3},{value:"Warnings",id:"warnings",level:3},{value:"Implementation",id:"implementation",level:3},{value:"Manual Tests",id:"manual-tests",level:2}];function c(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,a.jsx)(n.p,{children:"The three major versions of the standard that exist so far are very similar, and deliberately so.\nTherefore, the procedures needed to implement or test them are very similar as well. Yet, this document\nwill only cover v3, because v1 and v2 are already obsolete by the time of writing."}),"\n",(0,a.jsx)(n.h2,{id:"implementation-notes",children:"Implementation Notes"}),"\n",(0,a.jsxs)(n.p,{children:["Every flavor whose name starts with ",(0,a.jsx)(n.code,{children:"SCS-"})," must conform with the naming scheme laid down in the standard."]}),"\n",(0,a.jsx)(n.h3,{id:"operational-tooling",children:"Operational Tooling"}),"\n",(0,a.jsx)(n.h4,{id:"syntax-check",children:"Syntax Check"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Tests/iaas/flavor-naming",children:"test suite"}),"\ncomes with a handy\n",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Tests/iaas/flavor-naming/cli.py",children:"command-line utility"}),"\nthat can be used to validate flavor names, to\ninteractively construct a flavor name via a questionnaire, and to generate prose descriptions for given\nflavor names. See the\n",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Tests/iaas/flavor-naming/README.md",children:"README"}),"\nfor more details."]}),"\n",(0,a.jsxs)(n.p,{children:["The functionality of this script is also (partially) exposed via the web page\n",(0,a.jsx)(n.a,{href:"https://flavors.scs.community/",children:"https://flavors.scs.community/"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["With the OpenStack tooling (",(0,a.jsx)(n.code,{children:"python3-openstackclient"}),", ",(0,a.jsx)(n.code,{children:"OS_CLOUD"}),") in place, you can call\n",(0,a.jsx)(n.code,{children:"cli.py -v parse v3 $(openstack flavor list -f value -c Name)"})," to get a report\non the syntax compliance of the flavor names of the cloud environment."]}),"\n",(0,a.jsx)(n.h4,{id:"flavor-creation",children:"Flavor Creation"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.a,{href:"https://github.com/osism/openstack-flavor-manager",children:"OpenStack Flavor Manager"})," will create a whole set\nof flavors in one go, given a YAML description of this set."]}),"\n",(0,a.jsx)(n.h2,{id:"automated-tests",children:"Automated Tests"}),"\n",(0,a.jsx)(n.h3,{id:"errors",children:"Errors"}),"\n",(0,a.jsx)(n.p,{children:"The following items MUST be detected and reported as an error:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["any syntax error in a name starting with ",(0,a.jsx)(n.code,{children:"SCS-"}),","]}),"\n",(0,a.jsx)(n.li,{children:"any mismatch between any immediately discoverable property of a flavor (currently, CPU, RAM and disk size)\nand the meaning of its name (which is usually a lower bound), such as the CPU generation or hypervisor."}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"In addition, the following items MAY be reported as an error:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"any mismatch between any non-immediately discoverable property of flavor and the meaning of its name."}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"warnings",children:"Warnings"}),"\n",(0,a.jsx)(n.p,{children:"None so far."}),"\n",(0,a.jsx)(n.h3,{id:"implementation",children:"Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["The script ",(0,a.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Tests/iaas/flavor-naming/flavor-names-openstack.py",children:(0,a.jsx)(n.code,{children:"flavor-names-openstack.py"})}),"\ntalks to the OpenStack API of the cloud specified by the ",(0,a.jsx)(n.code,{children:"OS_CLOUD"})," environment and queries properties and\nchecks the names for standards compliance."]}),"\n",(0,a.jsx)(n.h2,{id:"manual-tests",children:"Manual Tests"}),"\n",(0,a.jsx)(n.p,{children:"To be determined."})]})}function m(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var a=t(96540);const s={},i=a.createContext(s);function o(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/642.ba7b31a2.js b/assets/js/642.ba7b31a2.js new file mode 100644 index 0000000000..003c3e2ae6 --- /dev/null +++ b/assets/js/642.ba7b31a2.js @@ -0,0 +1,1242 @@ +"use strict"; +exports.id = 642; +exports.ids = [642]; +exports.modules = { + +/***/ 45642: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(3219); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(78041); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(75263); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99418); + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [6, 8, 10, 11, 12, 14, 16, 17, 20, 21], $V1 = [1, 9], $V2 = [1, 10], $V3 = [1, 11], $V4 = [1, 12], $V5 = [1, 13], $V6 = [1, 16], $V7 = [1, 17]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "timeline": 4, "document": 5, "EOF": 6, "line": 7, "SPACE": 8, "statement": 9, "NEWLINE": 10, "title": 11, "acc_title": 12, "acc_title_value": 13, "acc_descr": 14, "acc_descr_value": 15, "acc_descr_multiline_value": 16, "section": 17, "period_statement": 18, "event_statement": 19, "period": 20, "event": 21, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "timeline", 6: "EOF", 8: "SPACE", 10: "NEWLINE", 11: "title", 12: "acc_title", 13: "acc_title_value", 14: "acc_descr", 15: "acc_descr_value", 16: "acc_descr_multiline_value", 17: "section", 20: "period", 21: "event" }, + productions_: [0, [3, 3], [5, 0], [5, 2], [7, 2], [7, 1], [7, 1], [7, 1], [9, 1], [9, 2], [9, 2], [9, 1], [9, 1], [9, 1], [9, 1], [18, 1], [19, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 1: + return $$[$0 - 1]; + case 2: + this.$ = []; + break; + case 3: + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + break; + case 4: + case 5: + this.$ = $$[$0]; + break; + case 6: + case 7: + this.$ = []; + break; + case 8: + yy.getCommonDb().setDiagramTitle($$[$0].substr(6)); + this.$ = $$[$0].substr(6); + break; + case 9: + this.$ = $$[$0].trim(); + yy.getCommonDb().setAccTitle(this.$); + break; + case 10: + case 11: + this.$ = $$[$0].trim(); + yy.getCommonDb().setAccDescription(this.$); + break; + case 12: + yy.addSection($$[$0].substr(8)); + this.$ = $$[$0].substr(8); + break; + case 15: + yy.addTask($$[$0], 0, ""); + this.$ = $$[$0]; + break; + case 16: + yy.addEvent($$[$0].substr(2)); + this.$ = $$[$0]; + break; + } + }, + table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: [1, 6], 9: 7, 10: [1, 8], 11: $V1, 12: $V2, 14: $V3, 16: $V4, 17: $V5, 18: 14, 19: 15, 20: $V6, 21: $V7 }, o($V0, [2, 7], { 1: [2, 1] }), o($V0, [2, 3]), { 9: 18, 11: $V1, 12: $V2, 14: $V3, 16: $V4, 17: $V5, 18: 14, 19: 15, 20: $V6, 21: $V7 }, o($V0, [2, 5]), o($V0, [2, 6]), o($V0, [2, 8]), { 13: [1, 19] }, { 15: [1, 20] }, o($V0, [2, 11]), o($V0, [2, 12]), o($V0, [2, 13]), o($V0, [2, 14]), o($V0, [2, 15]), o($V0, [2, 16]), o($V0, [2, 4]), o($V0, [2, 9]), o($V0, [2, 10])], + defaultActions: {}, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + break; + case 1: + break; + case 2: + return 10; + case 3: + break; + case 4: + break; + case 5: + return 4; + case 6: + return 11; + case 7: + this.begin("acc_title"); + return 12; + case 8: + this.popState(); + return "acc_title_value"; + case 9: + this.begin("acc_descr"); + return 14; + case 10: + this.popState(); + return "acc_descr_value"; + case 11: + this.begin("acc_descr_multiline"); + break; + case 12: + this.popState(); + break; + case 13: + return "acc_descr_multiline_value"; + case 14: + return 17; + case 15: + return 21; + case 16: + return 20; + case 17: + return 6; + case 18: + return "INVALID"; + } + }, + rules: [/^(?:%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[\n]+)/i, /^(?:\s+)/i, /^(?:#[^\n]*)/i, /^(?:timeline\b)/i, /^(?:title\s[^#\n;]+)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:section\s[^#:\n;]+)/i, /^(?::\s[^#:\n;]+)/i, /^(?:[^#:\n;]+)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "acc_descr_multiline": { "rules": [12, 13], "inclusive": false }, "acc_descr": { "rules": [10], "inclusive": false }, "acc_title": { "rules": [8], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 18], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let currentSection = ""; +let currentTaskId = 0; +const sections = []; +const tasks = []; +const rawTasks = []; +const getCommonDb = () => _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.L; +const clear = function() { + sections.length = 0; + tasks.length = 0; + currentSection = ""; + rawTasks.length = 0; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.v)(); +}; +const addSection = function(txt) { + currentSection = txt; + sections.push(txt); +}; +const getSections = function() { + return sections; +}; +const getTasks = function() { + let allItemsProcessed = compileTasks(); + const maxDepth = 100; + let iterationCount = 0; + while (!allItemsProcessed && iterationCount < maxDepth) { + allItemsProcessed = compileTasks(); + iterationCount++; + } + tasks.push(...rawTasks); + return tasks; +}; +const addTask = function(period, length, event) { + const rawTask = { + id: currentTaskId++, + section: currentSection, + type: currentSection, + task: period, + score: length ? length : 0, + //if event is defined, then add it the events array + events: event ? [event] : [] + }; + rawTasks.push(rawTask); +}; +const addEvent = function(event) { + const currentTask = rawTasks.find((task) => task.id === currentTaskId - 1); + currentTask.events.push(event); +}; +const addTaskOrg = function(descr) { + const newTask = { + section: currentSection, + type: currentSection, + description: descr, + task: descr, + classes: [] + }; + tasks.push(newTask); +}; +const compileTasks = function() { + const compileTask = function(pos) { + return rawTasks[pos].processed; + }; + let allProcessed = true; + for (const [i, rawTask] of rawTasks.entries()) { + compileTask(i); + allProcessed = allProcessed && rawTask.processed; + } + return allProcessed; +}; +const timelineDb = { + clear, + getCommonDb, + addSection, + getSections, + getTasks, + addTask, + addTaskOrg, + addEvent +}; +const db = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + addEvent, + addSection, + addTask, + addTaskOrg, + clear, + default: timelineDb, + getCommonDb, + getSections, + getTasks +}, Symbol.toStringTag, { value: "Module" })); +const MAX_SECTIONS = 12; +const drawRect = function(elem, rectData) { + const rectElem = elem.append("rect"); + rectElem.attr("x", rectData.x); + rectElem.attr("y", rectData.y); + rectElem.attr("fill", rectData.fill); + rectElem.attr("stroke", rectData.stroke); + rectElem.attr("width", rectData.width); + rectElem.attr("height", rectData.height); + rectElem.attr("rx", rectData.rx); + rectElem.attr("ry", rectData.ry); + if (rectData.class !== void 0) { + rectElem.attr("class", rectData.class); + } + return rectElem; +}; +const drawFace = function(element, faceData) { + const radius = 15; + const circleElement = element.append("circle").attr("cx", faceData.cx).attr("cy", faceData.cy).attr("class", "face").attr("r", radius).attr("stroke-width", 2).attr("overflow", "visible"); + const face = element.append("g"); + face.append("circle").attr("cx", faceData.cx - radius / 3).attr("cy", faceData.cy - radius / 3).attr("r", 1.5).attr("stroke-width", 2).attr("fill", "#666").attr("stroke", "#666"); + face.append("circle").attr("cx", faceData.cx + radius / 3).attr("cy", faceData.cy - radius / 3).attr("r", 1.5).attr("stroke-width", 2).attr("fill", "#666").attr("stroke", "#666"); + function smile(face2) { + const arc$1 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .arc */ .JLW)().startAngle(Math.PI / 2).endAngle(3 * (Math.PI / 2)).innerRadius(radius / 2).outerRadius(radius / 2.2); + face2.append("path").attr("class", "mouth").attr("d", arc$1).attr("transform", "translate(" + faceData.cx + "," + (faceData.cy + 2) + ")"); + } + function sad(face2) { + const arc$1 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .arc */ .JLW)().startAngle(3 * Math.PI / 2).endAngle(5 * (Math.PI / 2)).innerRadius(radius / 2).outerRadius(radius / 2.2); + face2.append("path").attr("class", "mouth").attr("d", arc$1).attr("transform", "translate(" + faceData.cx + "," + (faceData.cy + 7) + ")"); + } + function ambivalent(face2) { + face2.append("line").attr("class", "mouth").attr("stroke", 2).attr("x1", faceData.cx - 5).attr("y1", faceData.cy + 7).attr("x2", faceData.cx + 5).attr("y2", faceData.cy + 7).attr("class", "mouth").attr("stroke-width", "1px").attr("stroke", "#666"); + } + if (faceData.score > 3) { + smile(face); + } else if (faceData.score < 3) { + sad(face); + } else { + ambivalent(face); + } + return circleElement; +}; +const drawCircle = function(element, circleData) { + const circleElement = element.append("circle"); + circleElement.attr("cx", circleData.cx); + circleElement.attr("cy", circleData.cy); + circleElement.attr("class", "actor-" + circleData.pos); + circleElement.attr("fill", circleData.fill); + circleElement.attr("stroke", circleData.stroke); + circleElement.attr("r", circleData.r); + if (circleElement.class !== void 0) { + circleElement.attr("class", circleElement.class); + } + if (circleData.title !== void 0) { + circleElement.append("title").text(circleData.title); + } + return circleElement; +}; +const drawText = function(elem, textData) { + const nText = textData.text.replace(/<br\s*\/?>/gi, " "); + const textElem = elem.append("text"); + textElem.attr("x", textData.x); + textElem.attr("y", textData.y); + textElem.attr("class", "legend"); + textElem.style("text-anchor", textData.anchor); + if (textData.class !== void 0) { + textElem.attr("class", textData.class); + } + const span = textElem.append("tspan"); + span.attr("x", textData.x + textData.textMargin * 2); + span.text(nText); + return textElem; +}; +const drawLabel = function(elem, txtObject) { + function genPoints(x, y, width, height, cut) { + return x + "," + y + " " + (x + width) + "," + y + " " + (x + width) + "," + (y + height - cut) + " " + (x + width - cut * 1.2) + "," + (y + height) + " " + x + "," + (y + height); + } + const polygon = elem.append("polygon"); + polygon.attr("points", genPoints(txtObject.x, txtObject.y, 50, 20, 7)); + polygon.attr("class", "labelBox"); + txtObject.y = txtObject.y + txtObject.labelMargin; + txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin; + drawText(elem, txtObject); +}; +const drawSection = function(elem, section, conf) { + const g = elem.append("g"); + const rect = getNoteRect(); + rect.x = section.x; + rect.y = section.y; + rect.fill = section.fill; + rect.width = conf.width; + rect.height = conf.height; + rect.class = "journey-section section-type-" + section.num; + rect.rx = 3; + rect.ry = 3; + drawRect(g, rect); + _drawTextCandidateFunc(conf)( + section.text, + g, + rect.x, + rect.y, + rect.width, + rect.height, + { class: "journey-section section-type-" + section.num }, + conf, + section.colour + ); +}; +let taskCount = -1; +const drawTask = function(elem, task, conf) { + const center = task.x + conf.width / 2; + const g = elem.append("g"); + taskCount++; + const maxHeight = 300 + 5 * 30; + g.append("line").attr("id", "task" + taskCount).attr("x1", center).attr("y1", task.y).attr("x2", center).attr("y2", maxHeight).attr("class", "task-line").attr("stroke-width", "1px").attr("stroke-dasharray", "4 2").attr("stroke", "#666"); + drawFace(g, { + cx: center, + cy: 300 + (5 - task.score) * 30, + score: task.score + }); + const rect = getNoteRect(); + rect.x = task.x; + rect.y = task.y; + rect.fill = task.fill; + rect.width = conf.width; + rect.height = conf.height; + rect.class = "task task-type-" + task.num; + rect.rx = 3; + rect.ry = 3; + drawRect(g, rect); + task.x + 14; + _drawTextCandidateFunc(conf)( + task.task, + g, + rect.x, + rect.y, + rect.width, + rect.height, + { class: "task" }, + conf, + task.colour + ); +}; +const drawBackgroundRect = function(elem, bounds) { + const rectElem = drawRect(elem, { + x: bounds.startx, + y: bounds.starty, + width: bounds.stopx - bounds.startx, + height: bounds.stopy - bounds.starty, + fill: bounds.fill, + class: "rect" + }); + rectElem.lower(); +}; +const getTextObj = function() { + return { + x: 0, + y: 0, + fill: void 0, + "text-anchor": "start", + width: 100, + height: 100, + textMargin: 0, + rx: 0, + ry: 0 + }; +}; +const getNoteRect = function() { + return { + x: 0, + y: 0, + width: 100, + anchor: "start", + height: 100, + rx: 0, + ry: 0 + }; +}; +const _drawTextCandidateFunc = function() { + function byText(content, g, x, y, width, height, textAttrs, colour) { + const text = g.append("text").attr("x", x + width / 2).attr("y", y + height / 2 + 5).style("font-color", colour).style("text-anchor", "middle").text(content); + _setTextAttrs(text, textAttrs); + } + function byTspan(content, g, x, y, width, height, textAttrs, conf, colour) { + const { taskFontSize, taskFontFamily } = conf; + const lines = content.split(/<br\s*\/?>/gi); + for (let i = 0; i < lines.length; i++) { + const dy = i * taskFontSize - taskFontSize * (lines.length - 1) / 2; + const text = g.append("text").attr("x", x + width / 2).attr("y", y).attr("fill", colour).style("text-anchor", "middle").style("font-size", taskFontSize).style("font-family", taskFontFamily); + text.append("tspan").attr("x", x + width / 2).attr("dy", dy).text(lines[i]); + text.attr("y", y + height / 2).attr("dominant-baseline", "central").attr("alignment-baseline", "central"); + _setTextAttrs(text, textAttrs); + } + } + function byFo(content, g, x, y, width, height, textAttrs, conf) { + const body = g.append("switch"); + const f = body.append("foreignObject").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("position", "fixed"); + const text = f.append("xhtml:div").style("display", "table").style("height", "100%").style("width", "100%"); + text.append("div").attr("class", "label").style("display", "table-cell").style("text-align", "center").style("vertical-align", "middle").text(content); + byTspan(content, body, x, y, width, height, textAttrs, conf); + _setTextAttrs(text, textAttrs); + } + function _setTextAttrs(toText, fromTextAttrsDict) { + for (const key in fromTextAttrsDict) { + if (key in fromTextAttrsDict) { + toText.attr(key, fromTextAttrsDict[key]); + } + } + } + return function(conf) { + return conf.textPlacement === "fo" ? byFo : conf.textPlacement === "old" ? byText : byTspan; + }; +}(); +const initGraphics = function(graphics) { + graphics.append("defs").append("marker").attr("id", "arrowhead").attr("refX", 5).attr("refY", 2).attr("markerWidth", 6).attr("markerHeight", 4).attr("orient", "auto").append("path").attr("d", "M 0,0 V 4 L6,2 Z"); +}; +function wrap(text, width) { + text.each(function() { + var text2 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(this), words = text2.text().split(/(\s+|<br>)/).reverse(), word, line = [], lineHeight = 1.1, y = text2.attr("y"), dy = parseFloat(text2.attr("dy")), tspan = text2.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em"); + for (let j = 0; j < words.length; j++) { + word = words[words.length - 1 - j]; + line.push(word); + tspan.text(line.join(" ").trim()); + if (tspan.node().getComputedTextLength() > width || word === "<br>") { + line.pop(); + tspan.text(line.join(" ").trim()); + if (word === "<br>") { + line = [""]; + } else { + line = [word]; + } + tspan = text2.append("tspan").attr("x", 0).attr("y", y).attr("dy", lineHeight + "em").text(word); + } + } + }); +} +const drawNode = function(elem, node, fullSection, conf) { + const section = fullSection % MAX_SECTIONS - 1; + const nodeElem = elem.append("g"); + node.section = section; + nodeElem.attr( + "class", + (node.class ? node.class + " " : "") + "timeline-node " + ("section-" + section) + ); + const bkgElem = nodeElem.append("g"); + const textElem = nodeElem.append("g"); + const txt = textElem.append("text").text(node.descr).attr("dy", "1em").attr("alignment-baseline", "middle").attr("dominant-baseline", "middle").attr("text-anchor", "middle").call(wrap, node.width); + const bbox = txt.node().getBBox(); + const fontSize = conf.fontSize && conf.fontSize.replace ? conf.fontSize.replace("px", "") : conf.fontSize; + node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding; + node.height = Math.max(node.height, node.maxHeight); + node.width = node.width + 2 * node.padding; + textElem.attr("transform", "translate(" + node.width / 2 + ", " + node.padding / 2 + ")"); + defaultBkg(bkgElem, node, section); + return node; +}; +const getVirtualNodeHeight = function(elem, node, conf) { + const textElem = elem.append("g"); + const txt = textElem.append("text").text(node.descr).attr("dy", "1em").attr("alignment-baseline", "middle").attr("dominant-baseline", "middle").attr("text-anchor", "middle").call(wrap, node.width); + const bbox = txt.node().getBBox(); + const fontSize = conf.fontSize && conf.fontSize.replace ? conf.fontSize.replace("px", "") : conf.fontSize; + textElem.remove(); + return bbox.height + fontSize * 1.1 * 0.5 + node.padding; +}; +const defaultBkg = function(elem, node, section) { + const rd = 5; + elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + node.type).attr( + "d", + `M0 ${node.height - rd} v${-node.height + 2 * rd} q0,-5 5,-5 h${node.width - 2 * rd} q5,0 5,5 v${node.height - rd} H0 Z` + ); + elem.append("line").attr("class", "node-line-" + section).attr("x1", 0).attr("y1", node.height).attr("x2", node.width).attr("y2", node.height); +}; +const svgDraw = { + drawRect, + drawCircle, + drawSection, + drawText, + drawLabel, + drawTask, + drawBackgroundRect, + getTextObj, + getNoteRect, + initGraphics, + drawNode, + getVirtualNodeHeight +}; +const draw = function(text, id, version, diagObj) { + var _a, _b; + const conf = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const LEFT_MARGIN = conf.leftMargin ?? 50; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("timeline", diagObj.db); + const securityLevel = conf.securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body"); + const svg = root.select("#" + id); + svg.append("g"); + const tasks2 = diagObj.db.getTasks(); + const title = diagObj.db.getCommonDb().getDiagramTitle(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("task", tasks2); + svgDraw.initGraphics(svg); + const sections2 = diagObj.db.getSections(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("sections", sections2); + let maxSectionHeight = 0; + let maxTaskHeight = 0; + let depthY = 0; + let sectionBeginY = 0; + let masterX = 50 + LEFT_MARGIN; + let masterY = 50; + sectionBeginY = 50; + let sectionNumber = 0; + let hasSections = true; + sections2.forEach(function(section) { + const sectionNode = { + number: sectionNumber, + descr: section, + section: sectionNumber, + width: 150, + padding: 20, + maxHeight: maxSectionHeight + }; + const sectionHeight = svgDraw.getVirtualNodeHeight(svg, sectionNode, conf); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("sectionHeight before draw", sectionHeight); + maxSectionHeight = Math.max(maxSectionHeight, sectionHeight + 20); + }); + let maxEventCount = 0; + let maxEventLineLength = 0; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("tasks.length", tasks2.length); + for (const [i, task] of tasks2.entries()) { + const taskNode = { + number: i, + descr: task, + section: task.section, + width: 150, + padding: 20, + maxHeight: maxTaskHeight + }; + const taskHeight = svgDraw.getVirtualNodeHeight(svg, taskNode, conf); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("taskHeight before draw", taskHeight); + maxTaskHeight = Math.max(maxTaskHeight, taskHeight + 20); + maxEventCount = Math.max(maxEventCount, task.events.length); + let maxEventLineLengthTemp = 0; + for (let j = 0; j < task.events.length; j++) { + const event = task.events[j]; + const eventNode = { + descr: event, + section: task.section, + number: task.section, + width: 150, + padding: 20, + maxHeight: 50 + }; + maxEventLineLengthTemp += svgDraw.getVirtualNodeHeight(svg, eventNode, conf); + } + maxEventLineLength = Math.max(maxEventLineLength, maxEventLineLengthTemp); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("maxSectionHeight before draw", maxSectionHeight); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("maxTaskHeight before draw", maxTaskHeight); + if (sections2 && sections2.length > 0) { + sections2.forEach((section) => { + const tasksForSection = tasks2.filter((task) => task.section === section); + const sectionNode = { + number: sectionNumber, + descr: section, + section: sectionNumber, + width: 200 * Math.max(tasksForSection.length, 1) - 50, + padding: 20, + maxHeight: maxSectionHeight + }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("sectionNode", sectionNode); + const sectionNodeWrapper = svg.append("g"); + const node = svgDraw.drawNode(sectionNodeWrapper, sectionNode, sectionNumber, conf); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("sectionNode output", node); + sectionNodeWrapper.attr("transform", `translate(${masterX}, ${sectionBeginY})`); + masterY += maxSectionHeight + 50; + if (tasksForSection.length > 0) { + drawTasks( + svg, + tasksForSection, + sectionNumber, + masterX, + masterY, + maxTaskHeight, + conf, + maxEventCount, + maxEventLineLength, + maxSectionHeight, + false + ); + } + masterX += 200 * Math.max(tasksForSection.length, 1); + masterY = sectionBeginY; + sectionNumber++; + }); + } else { + hasSections = false; + drawTasks( + svg, + tasks2, + sectionNumber, + masterX, + masterY, + maxTaskHeight, + conf, + maxEventCount, + maxEventLineLength, + maxSectionHeight, + true + ); + } + const box = svg.node().getBBox(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("bounds", box); + if (title) { + svg.append("text").text(title).attr("x", box.width / 2 - LEFT_MARGIN).attr("font-size", "4ex").attr("font-weight", "bold").attr("y", 20); + } + depthY = hasSections ? maxSectionHeight + maxTaskHeight + 150 : maxTaskHeight + 100; + const lineWrapper = svg.append("g").attr("class", "lineWrapper"); + lineWrapper.append("line").attr("x1", LEFT_MARGIN).attr("y1", depthY).attr("x2", box.width + 3 * LEFT_MARGIN).attr("y2", depthY).attr("stroke-width", 4).attr("stroke", "black").attr("marker-end", "url(#arrowhead)"); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.o)( + void 0, + svg, + ((_a = conf.timeline) == null ? void 0 : _a.padding) ?? 50, + ((_b = conf.timeline) == null ? void 0 : _b.useMaxWidth) ?? false + ); +}; +const drawTasks = function(diagram2, tasks2, sectionColor, masterX, masterY, maxTaskHeight, conf, maxEventCount, maxEventLineLength, maxSectionHeight, isWithoutSections) { + var _a; + for (const task of tasks2) { + const taskNode = { + descr: task.task, + section: sectionColor, + number: sectionColor, + width: 150, + padding: 20, + maxHeight: maxTaskHeight + }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("taskNode", taskNode); + const taskWrapper = diagram2.append("g").attr("class", "taskWrapper"); + const node = svgDraw.drawNode(taskWrapper, taskNode, sectionColor, conf); + const taskHeight = node.height; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("taskHeight after draw", taskHeight); + taskWrapper.attr("transform", `translate(${masterX}, ${masterY})`); + maxTaskHeight = Math.max(maxTaskHeight, taskHeight); + if (task.events) { + const lineWrapper = diagram2.append("g").attr("class", "lineWrapper"); + let lineLength = maxTaskHeight; + masterY += 100; + lineLength = lineLength + drawEvents(diagram2, task.events, sectionColor, masterX, masterY, conf); + masterY -= 100; + lineWrapper.append("line").attr("x1", masterX + 190 / 2).attr("y1", masterY + maxTaskHeight).attr("x2", masterX + 190 / 2).attr( + "y2", + masterY + maxTaskHeight + (isWithoutSections ? maxTaskHeight : maxSectionHeight) + maxEventLineLength + 120 + ).attr("stroke-width", 2).attr("stroke", "black").attr("marker-end", "url(#arrowhead)").attr("stroke-dasharray", "5,5"); + } + masterX = masterX + 200; + if (isWithoutSections && !((_a = conf.timeline) == null ? void 0 : _a.disableMulticolor)) { + sectionColor++; + } + } + masterY = masterY - 10; +}; +const drawEvents = function(diagram2, events, sectionColor, masterX, masterY, conf) { + let maxEventHeight = 0; + const eventBeginY = masterY; + masterY = masterY + 100; + for (const event of events) { + const eventNode = { + descr: event, + section: sectionColor, + number: sectionColor, + width: 150, + padding: 20, + maxHeight: 50 + }; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("eventNode", eventNode); + const eventWrapper = diagram2.append("g").attr("class", "eventWrapper"); + const node = svgDraw.drawNode(eventWrapper, eventNode, sectionColor, conf); + const eventHeight = node.height; + maxEventHeight = maxEventHeight + eventHeight; + eventWrapper.attr("transform", `translate(${masterX}, ${masterY})`); + masterY = masterY + 10 + eventHeight; + } + masterY = eventBeginY; + return maxEventHeight; +}; +const renderer = { + setConf: () => { + }, + draw +}; +const genSections = (options) => { + let sections2 = ""; + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { + options["lineColor" + i] = options["lineColor" + i] || options["cScaleInv" + i]; + if ((0,khroma__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(options["lineColor" + i])) { + options["lineColor" + i] = (0,khroma__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A)(options["lineColor" + i], 20); + } else { + options["lineColor" + i] = (0,khroma__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)(options["lineColor" + i], 20); + } + } + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { + const sw = "" + (17 - 3 * i); + sections2 += ` + .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${i - 1} path { + fill: ${options["cScale" + i]}; + } + .section-${i - 1} text { + fill: ${options["cScaleLabel" + i]}; + } + .node-icon-${i - 1} { + font-size: 40px; + color: ${options["cScaleLabel" + i]}; + } + .section-edge-${i - 1}{ + stroke: ${options["cScale" + i]}; + } + .edge-depth-${i - 1}{ + stroke-width: ${sw}; + } + .section-${i - 1} line { + stroke: ${options["cScaleInv" + i]} ; + stroke-width: 3; + } + + .lineWrapper line{ + stroke: ${options["cScaleLabel" + i]} ; + } + + .disabled, .disabled circle, .disabled text { + fill: lightgray; + } + .disabled text { + fill: #efefef; + } + `; + } + return sections2; +}; +const getStyles = (options) => ` + .edge { + stroke-width: 3; + } + ${genSections(options)} + .section-root rect, .section-root path, .section-root circle { + fill: ${options.git0}; + } + .section-root text { + fill: ${options.gitBranchLabel0}; + } + .icon-container { + height:100%; + display: flex; + justify-content: center; + align-items: center; + } + .edge { + fill: none; + } + .eventWrapper { + filter: brightness(120%); + } +`; +const styles = getStyles; +const diagram = { + db, + renderer, + parser: parser$1, + styles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/64f9507b.1afbc06e.js b/assets/js/64f9507b.1afbc06e.js new file mode 100644 index 0000000000..4f9bcd32fd --- /dev/null +++ b/assets/js/64f9507b.1afbc06e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5790],{20454:(s,t,e)=>{e.r(t),e.d(t,{assets:()=>i,contentTitle:()=>d,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>o});var n=e(74848),r=e(28453);const a={},d="scs-0110: SSD Flavors",c={id:"iaas/scs-0110",title:"scs-0110: SSD Flavors",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/iaas/scs-0110.md",sourceDirName:"iaas",slug:"/iaas/scs-0110",permalink:"/standards/iaas/scs-0110",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"SCS Standard Images",permalink:"/standards/scs-0104-v1-standard-images"},next:{title:"SSD Flavors",permalink:"/standards/scs-0110-v1-ssd-flavors"}},i={},o=[];function l(s){const t={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"scs-0110-ssd-flavors",children:"scs-0110: SSD Flavors"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0110-v1-ssd-flavors",children:"scs-0110-v1"})}),(0,n.jsx)(t.td,{children:"Decision Record"}),(0,n.jsx)(t.td,{children:"Stable"}),(0,n.jsx)(t.td,{children:"2023-06-14"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function h(s={}){const{wrapper:t}={...(0,r.R)(),...s.components};return t?(0,n.jsx)(t,{...s,children:(0,n.jsx)(l,{...s})}):l(s)}},28453:(s,t,e)=>{e.d(t,{R:()=>d,x:()=>c});var n=e(96540);const r={},a=n.createContext(r);function d(s){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof s?s(t):{...t,...s}}),[t,s])}function c(s){let t;return t=s.disableParentContext?"function"==typeof s.components?s.components(r):s.components||r:d(s.components),n.createElement(a.Provider,{value:t},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/6506.4add14f3.js b/assets/js/6506.4add14f3.js new file mode 100644 index 0000000000..067e480d5a --- /dev/null +++ b/assets/js/6506.4add14f3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6506],{66506:(t,e,r)=>{r.d(e,{diagram:()=>z});var i=r(76257),a=r(26312),n=(r(74353),r(16750),r(42838),function(){var t=function(t,e,r,i){for(r=r||{},i=t.length;i--;r[t[i]]=e);return r},e=[1,3],r=[1,6],i=[1,4],a=[1,5],n=[2,5],c=[1,12],s=[5,7,13,19,21,23,24,26,28,31,37,40,47],o=[7,13,19,21,23,24,26,28,31,37,40],l=[7,12,13,19,21,23,24,26,28,31,37,40],h=[7,13,47],m=[1,42],y=[1,41],u=[7,13,29,32,35,38,47],p=[1,55],g=[1,56],b=[1,57],d=[7,13,32,35,42,47],f={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,GG:5,document:6,EOF:7,":":8,DIR:9,options:10,body:11,OPT:12,NL:13,line:14,statement:15,commitStatement:16,mergeStatement:17,cherryPickStatement:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,section:24,branchStatement:25,CHECKOUT:26,ref:27,BRANCH:28,ORDER:29,NUM:30,CHERRY_PICK:31,COMMIT_ID:32,STR:33,PARENT_COMMIT:34,COMMIT_TAG:35,EMPTYSTR:36,MERGE:37,COMMIT_TYPE:38,commitType:39,COMMIT:40,commit_arg:41,COMMIT_MSG:42,NORMAL:43,REVERSE:44,HIGHLIGHT:45,ID:46,";":47,$accept:0,$end:1},terminals_:{2:"error",5:"GG",7:"EOF",8:":",9:"DIR",12:"OPT",13:"NL",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"section",26:"CHECKOUT",28:"BRANCH",29:"ORDER",30:"NUM",31:"CHERRY_PICK",32:"COMMIT_ID",33:"STR",34:"PARENT_COMMIT",35:"COMMIT_TAG",36:"EMPTYSTR",37:"MERGE",38:"COMMIT_TYPE",40:"COMMIT",42:"COMMIT_MSG",43:"NORMAL",44:"REVERSE",45:"HIGHLIGHT",46:"ID",47:";"},productions_:[0,[3,2],[3,3],[3,4],[3,5],[6,0],[6,2],[10,2],[10,1],[11,0],[11,2],[14,2],[14,1],[15,1],[15,1],[15,1],[15,2],[15,2],[15,1],[15,1],[15,1],[15,2],[25,2],[25,4],[18,3],[18,5],[18,5],[18,7],[18,7],[18,5],[18,5],[18,5],[18,7],[18,7],[18,7],[18,7],[17,2],[17,4],[17,4],[17,4],[17,6],[17,6],[17,6],[17,6],[17,6],[17,6],[17,8],[17,8],[17,8],[17,8],[17,8],[17,8],[16,2],[16,3],[16,3],[16,5],[16,5],[16,3],[16,5],[16,5],[16,5],[16,5],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,3],[16,5],[16,5],[16,5],[16,5],[16,5],[16,5],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[41,0],[41,1],[39,1],[39,1],[39,1],[27,1],[27,1],[4,1],[4,1],[4,1]],performAction:function(t,e,r,i,a,n,c){var s=n.length-1;switch(a){case 2:return n[s];case 3:return n[s-1];case 4:return i.setDirection(n[s-3]),n[s-1];case 6:i.setOptions(n[s-1]),this.$=n[s];break;case 7:n[s-1]+=n[s],this.$=n[s-1];break;case 9:this.$=[];break;case 10:n[s-1].push(n[s]),this.$=n[s-1];break;case 11:this.$=n[s-1];break;case 16:this.$=n[s].trim(),i.setAccTitle(this.$);break;case 17:case 18:this.$=n[s].trim(),i.setAccDescription(this.$);break;case 19:i.addSection(n[s].substr(8)),this.$=n[s].substr(8);break;case 21:i.checkout(n[s]);break;case 22:i.branch(n[s]);break;case 23:i.branch(n[s-2],n[s]);break;case 24:i.cherryPick(n[s],"",void 0);break;case 25:i.cherryPick(n[s-2],"",void 0,n[s]);break;case 26:i.cherryPick(n[s-2],"",n[s]);break;case 27:i.cherryPick(n[s-4],"",n[s],n[s-2]);break;case 28:i.cherryPick(n[s-4],"",n[s-2],n[s]);break;case 29:i.cherryPick(n[s],"",n[s-2]);break;case 30:i.cherryPick(n[s],"","");break;case 31:i.cherryPick(n[s-2],"","");break;case 32:i.cherryPick(n[s-4],"","",n[s-2]);break;case 33:i.cherryPick(n[s-4],"","",n[s]);break;case 34:i.cherryPick(n[s-2],"",n[s-4],n[s]);break;case 35:i.cherryPick(n[s-2],"","",n[s]);break;case 36:i.merge(n[s],"","","");break;case 37:i.merge(n[s-2],n[s],"","");break;case 38:i.merge(n[s-2],"",n[s],"");break;case 39:i.merge(n[s-2],"","",n[s]);break;case 40:i.merge(n[s-4],n[s],"",n[s-2]);break;case 41:i.merge(n[s-4],"",n[s],n[s-2]);break;case 42:i.merge(n[s-4],"",n[s-2],n[s]);break;case 43:i.merge(n[s-4],n[s-2],n[s],"");break;case 44:i.merge(n[s-4],n[s-2],"",n[s]);break;case 45:i.merge(n[s-4],n[s],n[s-2],"");break;case 46:i.merge(n[s-6],n[s-4],n[s-2],n[s]);break;case 47:i.merge(n[s-6],n[s],n[s-4],n[s-2]);break;case 48:i.merge(n[s-6],n[s-4],n[s],n[s-2]);break;case 49:i.merge(n[s-6],n[s-2],n[s-4],n[s]);break;case 50:i.merge(n[s-6],n[s],n[s-2],n[s-4]);break;case 51:i.merge(n[s-6],n[s-2],n[s],n[s-4]);break;case 52:i.commit(n[s]);break;case 53:i.commit("","",i.commitType.NORMAL,n[s]);break;case 54:i.commit("","",n[s],"");break;case 55:i.commit("","",n[s],n[s-2]);break;case 56:i.commit("","",n[s-2],n[s]);break;case 57:i.commit("",n[s],i.commitType.NORMAL,"");break;case 58:i.commit("",n[s-2],i.commitType.NORMAL,n[s]);break;case 59:i.commit("",n[s],i.commitType.NORMAL,n[s-2]);break;case 60:i.commit("",n[s-2],n[s],"");break;case 61:i.commit("",n[s],n[s-2],"");break;case 62:i.commit("",n[s-4],n[s-2],n[s]);break;case 63:i.commit("",n[s-4],n[s],n[s-2]);break;case 64:i.commit("",n[s-2],n[s-4],n[s]);break;case 65:i.commit("",n[s],n[s-4],n[s-2]);break;case 66:i.commit("",n[s],n[s-2],n[s-4]);break;case 67:i.commit("",n[s-2],n[s],n[s-4]);break;case 68:i.commit(n[s],"",i.commitType.NORMAL,"");break;case 69:i.commit(n[s],"",i.commitType.NORMAL,n[s-2]);break;case 70:i.commit(n[s-2],"",i.commitType.NORMAL,n[s]);break;case 71:i.commit(n[s-2],"",n[s],"");break;case 72:i.commit(n[s],"",n[s-2],"");break;case 73:i.commit(n[s],n[s-2],i.commitType.NORMAL,"");break;case 74:i.commit(n[s-2],n[s],i.commitType.NORMAL,"");break;case 75:i.commit(n[s-4],"",n[s-2],n[s]);break;case 76:i.commit(n[s-4],"",n[s],n[s-2]);break;case 77:i.commit(n[s-2],"",n[s-4],n[s]);break;case 78:i.commit(n[s],"",n[s-4],n[s-2]);break;case 79:i.commit(n[s],"",n[s-2],n[s-4]);break;case 80:i.commit(n[s-2],"",n[s],n[s-4]);break;case 81:i.commit(n[s-4],n[s],n[s-2],"");break;case 82:i.commit(n[s-4],n[s-2],n[s],"");break;case 83:i.commit(n[s-2],n[s],n[s-4],"");break;case 84:i.commit(n[s],n[s-2],n[s-4],"");break;case 85:i.commit(n[s],n[s-4],n[s-2],"");break;case 86:i.commit(n[s-2],n[s-4],n[s],"");break;case 87:i.commit(n[s-4],n[s],i.commitType.NORMAL,n[s-2]);break;case 88:i.commit(n[s-4],n[s-2],i.commitType.NORMAL,n[s]);break;case 89:i.commit(n[s-2],n[s],i.commitType.NORMAL,n[s-4]);break;case 90:i.commit(n[s],n[s-2],i.commitType.NORMAL,n[s-4]);break;case 91:i.commit(n[s],n[s-4],i.commitType.NORMAL,n[s-2]);break;case 92:i.commit(n[s-2],n[s-4],i.commitType.NORMAL,n[s]);break;case 93:i.commit(n[s-6],n[s-4],n[s-2],n[s]);break;case 94:i.commit(n[s-6],n[s-4],n[s],n[s-2]);break;case 95:i.commit(n[s-6],n[s-2],n[s-4],n[s]);break;case 96:i.commit(n[s-6],n[s],n[s-4],n[s-2]);break;case 97:i.commit(n[s-6],n[s-2],n[s],n[s-4]);break;case 98:i.commit(n[s-6],n[s],n[s-2],n[s-4]);break;case 99:i.commit(n[s-4],n[s-6],n[s-2],n[s]);break;case 100:i.commit(n[s-4],n[s-6],n[s],n[s-2]);break;case 101:i.commit(n[s-2],n[s-6],n[s-4],n[s]);break;case 102:i.commit(n[s],n[s-6],n[s-4],n[s-2]);break;case 103:i.commit(n[s-2],n[s-6],n[s],n[s-4]);break;case 104:i.commit(n[s],n[s-6],n[s-2],n[s-4]);break;case 105:i.commit(n[s],n[s-4],n[s-2],n[s-6]);break;case 106:i.commit(n[s-2],n[s-4],n[s],n[s-6]);break;case 107:i.commit(n[s],n[s-2],n[s-4],n[s-6]);break;case 108:i.commit(n[s-2],n[s],n[s-4],n[s-6]);break;case 109:i.commit(n[s-4],n[s-2],n[s],n[s-6]);break;case 110:i.commit(n[s-4],n[s],n[s-2],n[s-6]);break;case 111:i.commit(n[s-2],n[s-4],n[s-6],n[s]);break;case 112:i.commit(n[s],n[s-4],n[s-6],n[s-2]);break;case 113:i.commit(n[s-2],n[s],n[s-6],n[s-4]);break;case 114:i.commit(n[s],n[s-2],n[s-6],n[s-4]);break;case 115:i.commit(n[s-4],n[s-2],n[s-6],n[s]);break;case 116:i.commit(n[s-4],n[s],n[s-6],n[s-2]);break;case 117:this.$="";break;case 118:this.$=n[s];break;case 119:this.$=i.commitType.NORMAL;break;case 120:this.$=i.commitType.REVERSE;break;case 121:this.$=i.commitType.HIGHLIGHT}},table:[{3:1,4:2,5:e,7:r,13:i,47:a},{1:[3]},{3:7,4:2,5:e,7:r,13:i,47:a},{6:8,7:n,8:[1,9],9:[1,10],10:11,13:c},t(s,[2,124]),t(s,[2,125]),t(s,[2,126]),{1:[2,1]},{7:[1,13]},{6:14,7:n,10:11,13:c},{8:[1,15]},t(o,[2,9],{11:16,12:[1,17]}),t(l,[2,8]),{1:[2,2]},{7:[1,18]},{6:19,7:n,10:11,13:c},{7:[2,6],13:[1,22],14:20,15:21,16:23,17:24,18:25,19:[1,26],21:[1,27],23:[1,28],24:[1,29],25:30,26:[1,31],28:[1,35],31:[1,34],37:[1,33],40:[1,32]},t(l,[2,7]),{1:[2,3]},{7:[1,36]},t(o,[2,10]),{4:37,7:r,13:i,47:a},t(o,[2,12]),t(h,[2,13]),t(h,[2,14]),t(h,[2,15]),{20:[1,38]},{22:[1,39]},t(h,[2,18]),t(h,[2,19]),t(h,[2,20]),{27:40,33:m,46:y},t(h,[2,117],{41:43,32:[1,46],33:[1,48],35:[1,44],38:[1,45],42:[1,47]}),{27:49,33:m,46:y},{32:[1,50],35:[1,51]},{27:52,33:m,46:y},{1:[2,4]},t(o,[2,11]),t(h,[2,16]),t(h,[2,17]),t(h,[2,21]),t(u,[2,122]),t(u,[2,123]),t(h,[2,52]),{33:[1,53]},{39:54,43:p,44:g,45:b},{33:[1,58]},{33:[1,59]},t(h,[2,118]),t(h,[2,36],{32:[1,60],35:[1,62],38:[1,61]}),{33:[1,63]},{33:[1,64],36:[1,65]},t(h,[2,22],{29:[1,66]}),t(h,[2,53],{32:[1,68],38:[1,67],42:[1,69]}),t(h,[2,54],{32:[1,71],35:[1,70],42:[1,72]}),t(d,[2,119]),t(d,[2,120]),t(d,[2,121]),t(h,[2,57],{35:[1,73],38:[1,74],42:[1,75]}),t(h,[2,68],{32:[1,78],35:[1,76],38:[1,77]}),{33:[1,79]},{39:80,43:p,44:g,45:b},{33:[1,81]},t(h,[2,24],{34:[1,82],35:[1,83]}),{32:[1,84]},{32:[1,85]},{30:[1,86]},{39:87,43:p,44:g,45:b},{33:[1,88]},{33:[1,89]},{33:[1,90]},{33:[1,91]},{33:[1,92]},{33:[1,93]},{39:94,43:p,44:g,45:b},{33:[1,95]},{33:[1,96]},{39:97,43:p,44:g,45:b},{33:[1,98]},t(h,[2,37],{35:[1,100],38:[1,99]}),t(h,[2,38],{32:[1,102],35:[1,101]}),t(h,[2,39],{32:[1,103],38:[1,104]}),{33:[1,105]},{33:[1,106],36:[1,107]},{33:[1,108]},{33:[1,109]},t(h,[2,23]),t(h,[2,55],{32:[1,110],42:[1,111]}),t(h,[2,59],{38:[1,112],42:[1,113]}),t(h,[2,69],{32:[1,115],38:[1,114]}),t(h,[2,56],{32:[1,116],42:[1,117]}),t(h,[2,61],{35:[1,118],42:[1,119]}),t(h,[2,72],{32:[1,121],35:[1,120]}),t(h,[2,58],{38:[1,122],42:[1,123]}),t(h,[2,60],{35:[1,124],42:[1,125]}),t(h,[2,73],{35:[1,127],38:[1,126]}),t(h,[2,70],{32:[1,129],38:[1,128]}),t(h,[2,71],{32:[1,131],35:[1,130]}),t(h,[2,74],{35:[1,133],38:[1,132]}),{39:134,43:p,44:g,45:b},{33:[1,135]},{33:[1,136]},{33:[1,137]},{33:[1,138]},{39:139,43:p,44:g,45:b},t(h,[2,25],{35:[1,140]}),t(h,[2,26],{34:[1,141]}),t(h,[2,31],{34:[1,142]}),t(h,[2,29],{34:[1,143]}),t(h,[2,30],{34:[1,144]}),{33:[1,145]},{33:[1,146]},{39:147,43:p,44:g,45:b},{33:[1,148]},{39:149,43:p,44:g,45:b},{33:[1,150]},{33:[1,151]},{33:[1,152]},{33:[1,153]},{33:[1,154]},{33:[1,155]},{33:[1,156]},{39:157,43:p,44:g,45:b},{33:[1,158]},{33:[1,159]},{33:[1,160]},{39:161,43:p,44:g,45:b},{33:[1,162]},{39:163,43:p,44:g,45:b},{33:[1,164]},{33:[1,165]},{33:[1,166]},{39:167,43:p,44:g,45:b},{33:[1,168]},t(h,[2,43],{35:[1,169]}),t(h,[2,44],{38:[1,170]}),t(h,[2,42],{32:[1,171]}),t(h,[2,45],{35:[1,172]}),t(h,[2,40],{38:[1,173]}),t(h,[2,41],{32:[1,174]}),{33:[1,175],36:[1,176]},{33:[1,177]},{33:[1,178]},{33:[1,179]},{33:[1,180]},t(h,[2,66],{42:[1,181]}),t(h,[2,79],{32:[1,182]}),t(h,[2,67],{42:[1,183]}),t(h,[2,90],{38:[1,184]}),t(h,[2,80],{32:[1,185]}),t(h,[2,89],{38:[1,186]}),t(h,[2,65],{42:[1,187]}),t(h,[2,78],{32:[1,188]}),t(h,[2,64],{42:[1,189]}),t(h,[2,84],{35:[1,190]}),t(h,[2,77],{32:[1,191]}),t(h,[2,83],{35:[1,192]}),t(h,[2,63],{42:[1,193]}),t(h,[2,91],{38:[1,194]}),t(h,[2,62],{42:[1,195]}),t(h,[2,85],{35:[1,196]}),t(h,[2,86],{35:[1,197]}),t(h,[2,92],{38:[1,198]}),t(h,[2,76],{32:[1,199]}),t(h,[2,87],{38:[1,200]}),t(h,[2,75],{32:[1,201]}),t(h,[2,81],{35:[1,202]}),t(h,[2,82],{35:[1,203]}),t(h,[2,88],{38:[1,204]}),{33:[1,205]},{39:206,43:p,44:g,45:b},{33:[1,207]},{33:[1,208]},{39:209,43:p,44:g,45:b},{33:[1,210]},t(h,[2,27]),t(h,[2,32]),t(h,[2,28]),t(h,[2,33]),t(h,[2,34]),t(h,[2,35]),{33:[1,211]},{33:[1,212]},{33:[1,213]},{39:214,43:p,44:g,45:b},{33:[1,215]},{39:216,43:p,44:g,45:b},{33:[1,217]},{33:[1,218]},{33:[1,219]},{33:[1,220]},{33:[1,221]},{33:[1,222]},{33:[1,223]},{39:224,43:p,44:g,45:b},{33:[1,225]},{33:[1,226]},{33:[1,227]},{39:228,43:p,44:g,45:b},{33:[1,229]},{39:230,43:p,44:g,45:b},{33:[1,231]},{33:[1,232]},{33:[1,233]},{39:234,43:p,44:g,45:b},t(h,[2,46]),t(h,[2,48]),t(h,[2,47]),t(h,[2,49]),t(h,[2,51]),t(h,[2,50]),t(h,[2,107]),t(h,[2,108]),t(h,[2,105]),t(h,[2,106]),t(h,[2,110]),t(h,[2,109]),t(h,[2,114]),t(h,[2,113]),t(h,[2,112]),t(h,[2,111]),t(h,[2,116]),t(h,[2,115]),t(h,[2,104]),t(h,[2,103]),t(h,[2,102]),t(h,[2,101]),t(h,[2,99]),t(h,[2,100]),t(h,[2,98]),t(h,[2,97]),t(h,[2,96]),t(h,[2,95]),t(h,[2,93]),t(h,[2,94])],defaultActions:{7:[2,1],13:[2,2],18:[2,3],36:[2,4]},parseError:function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},parse:function(t){var e=this,r=[0],i=[],a=[null],n=[],c=this.table,s="",o=0,l=0,h=n.slice.call(arguments,1),m=Object.create(this.lexer),y={yy:{}};for(var u in this.yy)Object.prototype.hasOwnProperty.call(this.yy,u)&&(y.yy[u]=this.yy[u]);m.setInput(t,y.yy),y.yy.lexer=m,y.yy.parser=this,void 0===m.yylloc&&(m.yylloc={});var p=m.yylloc;n.push(p);var g=m.options&&m.options.ranges;"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var b,d,f,$,k,x,_,T,w,E={};;){if(d=r[r.length-1],this.defaultActions[d]?f=this.defaultActions[d]:(null==b&&(w=void 0,"number"!=typeof(w=i.pop()||m.lex()||1)&&(w instanceof Array&&(w=(i=w).pop()),w=e.symbols_[w]||w),b=w),f=c[d]&&c[d][b]),void 0===f||!f.length||!f[0]){var L="";for(k in T=[],c[d])this.terminals_[k]&&k>2&&T.push("'"+this.terminals_[k]+"'");L=m.showPosition?"Parse error on line "+(o+1)+":\n"+m.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(L,{text:m.match,token:this.terminals_[b]||b,line:m.yylineno,loc:p,expected:T})}if(f[0]instanceof Array&&f.length>1)throw new Error("Parse Error: multiple actions possible at state: "+d+", token: "+b);switch(f[0]){case 1:r.push(b),a.push(m.yytext),n.push(m.yylloc),r.push(f[1]),b=null,l=m.yyleng,s=m.yytext,o=m.yylineno,p=m.yylloc;break;case 2:if(x=this.productions_[f[1]][1],E.$=a[a.length-x],E._$={first_line:n[n.length-(x||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(x||1)].first_column,last_column:n[n.length-1].last_column},g&&(E._$.range=[n[n.length-(x||1)].range[0],n[n.length-1].range[1]]),void 0!==($=this.performAction.apply(E,[s,l,o,y.yy,f[1],a,n].concat(h))))return $;x&&(r=r.slice(0,-1*x*2),a=a.slice(0,-1*x),n=n.slice(0,-1*x)),r.push(this.productions_[f[1]][0]),a.push(E.$),n.push(E._$),_=c[r[r.length-2]][r[r.length-1]],r.push(_);break;case 3:return!0}}return!0}},$={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,r=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var a=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===i.length?this.yylloc.first_column:0)+i[i.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var r,i,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var n in a)this[n]=a[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,r,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),n=0;n<a.length;n++)if((r=this._input.match(this.rules[a[n]]))&&(!e||r[0].length>e[0].length)){if(e=r,i=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,a[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,a[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,r,i){switch(r){case 0:return this.begin("acc_title"),19;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),21;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:case 30:case 34:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 13;case 8:case 9:break;case 10:return 5;case 11:return 40;case 12:return 32;case 13:return 38;case 14:return 42;case 15:return 43;case 16:return 44;case 17:return 45;case 18:return 35;case 19:return 28;case 20:return 29;case 21:return 37;case 22:return 31;case 23:return 34;case 24:return 26;case 25:case 26:return 9;case 27:return 8;case 28:return"CARET";case 29:this.begin("options");break;case 31:return 12;case 32:return 36;case 33:this.begin("string");break;case 35:return 33;case 36:return 30;case 37:return 46;case 38:return 7}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit(?=\s|$))/i,/^(?:id:)/i,/^(?:type:)/i,/^(?:msg:)/i,/^(?:NORMAL\b)/i,/^(?:REVERSE\b)/i,/^(?:HIGHLIGHT\b)/i,/^(?:tag:)/i,/^(?:branch(?=\s|$))/i,/^(?:order:)/i,/^(?:merge(?=\s|$))/i,/^(?:cherry-pick(?=\s|$))/i,/^(?:parent:)/i,/^(?:checkout(?=\s|$))/i,/^(?:LR\b)/i,/^(?:TB\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:[ \r\n\t]+end\b)/i,/^(?:[\s\S]+(?=[ \r\n\t]+end))/i,/^(?:["]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[0-9]+(?=\s|$))/i,/^(?:\w([-\./\w]*[-\w])?)/i,/^(?:$)/i,/^(?:\s+)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},options:{rules:[30,31],inclusive:!1},string:{rules:[34,35],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,32,33,36,37,38,39],inclusive:!0}}};function k(){this.yy={}}return f.lexer=$,k.prototype=f,f.Parser=k,new k}());n.parser=n;const c=n;let s=(0,i.c)().gitGraph.mainBranchName,o=(0,i.c)().gitGraph.mainBranchOrder,l={},h=null,m={};m[s]={name:s,order:o};let y={};y[s]=h;let u=s,p="LR",g=0;function b(){return(0,i.y)({length:7})}let d={};const f=function(t){if(t=i.e.sanitizeText(t,(0,i.c)()),void 0===y[t]){let e=new Error('Trying to checkout branch which is not yet created. (Help try using "branch '+t+'")');throw e.hash={text:"checkout "+t,token:"checkout "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"branch '+t+'"']},e}{u=t;const e=y[u];h=l[e]}};function $(t,e,r){const i=t.indexOf(e);-1===i?t.push(r):t.splice(i,1,r)}function k(t){const e=t.reduce(((t,e)=>t.seq>e.seq?t:e),t[0]);let r="";t.forEach((function(t){r+=t===e?"\t*":"\t|"}));const a=[r,e.id,e.seq];for(let i in y)y[i]===e.id&&a.push(i);if(i.l.debug(a.join(" ")),e.parents&&2==e.parents.length){const r=l[e.parents[0]];$(t,e,r),t.push(l[e.parents[1]])}else{if(0==e.parents.length)return;{const r=l[e.parents];$(t,e,r)}}k(t=function(t,e){const r=Object.create(null);return t.reduce(((t,i)=>{const a=e(i);return r[a]||(r[a]=!0,t.push(i)),t}),[])}(t,(t=>t.id)))}const x=function(){const t=Object.keys(l).map((function(t){return l[t]}));return t.forEach((function(t){i.l.debug(t.id)})),t.sort(((t,e)=>t.seq-e.seq)),t},_={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4},T={getConfig:()=>(0,i.c)().gitGraph,setDirection:function(t){p=t},setOptions:function(t){i.l.debug("options str",t),t=(t=t&&t.trim())||"{}";try{d=JSON.parse(t)}catch(e){i.l.error("error while parsing gitGraph options",e.message)}},getOptions:function(){return d},commit:function(t,e,r,a){i.l.debug("Entering commit:",t,e,r,a),e=i.e.sanitizeText(e,(0,i.c)()),t=i.e.sanitizeText(t,(0,i.c)()),a=i.e.sanitizeText(a,(0,i.c)());const n={id:e||g+"-"+b(),message:t,seq:g++,type:r||_.NORMAL,tag:a||"",parents:null==h?[]:[h.id],branch:u};h=n,l[n.id]=n,y[u]=n.id,i.l.debug("in pushCommit "+n.id)},branch:function(t,e){if(t=i.e.sanitizeText(t,(0,i.c)()),void 0!==y[t]){let e=new Error('Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout '+t+'")');throw e.hash={text:"branch "+t,token:"branch "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"checkout '+t+'"']},e}y[t]=null!=h?h.id:null,m[t]={name:t,order:e?parseInt(e,10):null},f(t),i.l.debug("in createBranch")},merge:function(t,e,r,a){t=i.e.sanitizeText(t,(0,i.c)()),e=i.e.sanitizeText(e,(0,i.c)());const n=l[y[u]],c=l[y[t]];if(u===t){let e=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(void 0===n||!n){let e=new Error('Incorrect usage of "merge". Current branch ('+u+")has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["commit"]},e}if(void 0===y[t]){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") does not exist");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch "+t]},e}if(void 0===c||!c){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"commit"']},e}if(n===c){let e=new Error('Incorrect usage of "merge". Both branches have same head');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(e&&void 0!==l[e]){let i=new Error('Incorrect usage of "merge". Commit with id:'+e+" already exists, use different custom Id");throw i.hash={text:"merge "+t+e+r+a,token:"merge "+t+e+r+a,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["merge "+t+" "+e+"_UNIQUE "+r+" "+a]},i}const s={id:e||g+"-"+b(),message:"merged branch "+t+" into "+u,seq:g++,parents:[null==h?null:h.id,y[t]],branch:u,type:_.MERGE,customType:r,customId:!!e,tag:a||""};h=s,l[s.id]=s,y[u]=s.id,i.l.debug(y),i.l.debug("in mergeBranch")},cherryPick:function(t,e,r,a){if(i.l.debug("Entering cherryPick:",t,e,r),t=i.e.sanitizeText(t,(0,i.c)()),e=i.e.sanitizeText(e,(0,i.c)()),r=i.e.sanitizeText(r,(0,i.c)()),a=i.e.sanitizeText(a,(0,i.c)()),!t||void 0===l[t]){let r=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}let n=l[t],c=n.branch;if(a&&(!Array.isArray(n.parents)||!n.parents.includes(a))){throw new Error("Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit.")}if(n.type===_.MERGE&&!a){throw new Error("Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified.")}if(!e||void 0===l[e]){if(c===u){let r=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}const s=l[y[u]];if(void 0===s||!s){let r=new Error('Incorrect usage of "cherry-pick". Current branch ('+u+")has no commits");throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}const o={id:g+"-"+b(),message:"cherry-picked "+n+" into "+u,seq:g++,parents:[null==h?null:h.id,n.id],branch:u,type:_.CHERRY_PICK,tag:r??`cherry-pick:${n.id}${n.type===_.MERGE?`|parent:${a}`:""}`};h=o,l[o.id]=o,y[u]=o.id,i.l.debug(y),i.l.debug("in cherryPick")}},checkout:f,prettyPrint:function(){i.l.debug(l);k([x()[0]])},clear:function(){l={},h=null;let t=(0,i.c)().gitGraph.mainBranchName,e=(0,i.c)().gitGraph.mainBranchOrder;y={},y[t]=null,m={},m[t]={name:t,order:e},u=t,g=0,(0,i.v)()},getBranchesAsObjArray:function(){return Object.values(m).map(((t,e)=>null!==t.order?t:{...t,order:parseFloat(`0.${e}`,10)})).sort(((t,e)=>t.order-e.order)).map((({name:t})=>({name:t})))},getBranches:function(){return y},getCommits:function(){return l},getCommitsArray:x,getCurrentBranch:function(){return u},getDirection:function(){return p},getHead:function(){return h},setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,setDiagramTitle:i.q,getDiagramTitle:i.t,commitType:_};let w={};const E=0,L=1,M=2,v=3,I=4;let A={},R={},O=[],C=0,S="LR";const P=t=>{const e=document.createElementNS("http://www.w3.org/2000/svg","text");let r=[];r="string"==typeof t?t.split(/\\n|\n|<br\s*\/?>/gi):Array.isArray(t)?t:[];for(const i of r){const t=document.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","0"),t.setAttribute("class","row"),t.textContent=i.trim(),e.appendChild(t)}return e},B=(t,e,r)=>{const a=(0,i.c)().gitGraph,n=t.append("g").attr("class","commit-bullets"),c=t.append("g").attr("class","commit-labels");let s=0;"TB"===S&&(s=30);const o=Object.keys(e).sort(((t,r)=>e[t].seq-e[r].seq)),l=a.parallelCommits,h=10;o.forEach((t=>{const i=e[t];if(l)if(i.parents.length){const t=(t=>{let e="",r=0;return t.forEach((t=>{const i="TB"===S?R[t].y:R[t].x;i>=r&&(e=t,r=i)})),e||void 0})(i.parents);s="TB"===S?R[t].y+40:R[t].x+40}else s=0,"TB"===S&&(s=30);const o=s+h,m="TB"===S?o:A[i.branch].pos,y="TB"===S?A[i.branch].pos:o;if(r){let t,e=void 0!==i.customType&&""!==i.customType?i.customType:i.type;switch(e){case E:t="commit-normal";break;case L:t="commit-reverse";break;case M:t="commit-highlight";break;case v:t="commit-merge";break;case I:t="commit-cherry-pick";break;default:t="commit-normal"}if(e===M){const e=n.append("rect");e.attr("x",y-10),e.attr("y",m-10),e.attr("height",20),e.attr("width",20),e.attr("class",`commit ${i.id} commit-highlight${A[i.branch].index%8} ${t}-outer`),n.append("rect").attr("x",y-6).attr("y",m-6).attr("height",12).attr("width",12).attr("class",`commit ${i.id} commit${A[i.branch].index%8} ${t}-inner`)}else if(e===I)n.append("circle").attr("cx",y).attr("cy",m).attr("r",10).attr("class",`commit ${i.id} ${t}`),n.append("circle").attr("cx",y-3).attr("cy",m+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${i.id} ${t}`),n.append("circle").attr("cx",y+3).attr("cy",m+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${i.id} ${t}`),n.append("line").attr("x1",y+3).attr("y1",m+1).attr("x2",y).attr("y2",m-5).attr("stroke","#fff").attr("class",`commit ${i.id} ${t}`),n.append("line").attr("x1",y-3).attr("y1",m+1).attr("x2",y).attr("y2",m-5).attr("stroke","#fff").attr("class",`commit ${i.id} ${t}`);else{const r=n.append("circle");if(r.attr("cx",y),r.attr("cy",m),r.attr("r",i.type===v?9:10),r.attr("class",`commit ${i.id} commit${A[i.branch].index%8}`),e===v){const e=n.append("circle");e.attr("cx",y),e.attr("cy",m),e.attr("r",6),e.attr("class",`commit ${t} ${i.id} commit${A[i.branch].index%8}`)}if(e===L){n.append("path").attr("d",`M ${y-5},${m-5}L${y+5},${m+5}M${y-5},${m+5}L${y+5},${m-5}`).attr("class",`commit ${t} ${i.id} commit${A[i.branch].index%8}`)}}}if(R[i.id]="TB"===S?{x:y,y:o}:{x:o,y:m},r){const t=4,e=2;if(i.type!==I&&(i.customId&&i.type===v||i.type!==v)&&a.showCommitLabel){const r=c.append("g"),n=r.insert("rect").attr("class","commit-label-bkg"),l=r.append("text").attr("x",s).attr("y",m+25).attr("class","commit-label").text(i.id);let h=l.node().getBBox();if(n.attr("x",o-h.width/2-e).attr("y",m+13.5).attr("width",h.width+2*e).attr("height",h.height+2*e),"TB"===S&&(n.attr("x",y-(h.width+4*t+5)).attr("y",m-12),l.attr("x",y-(h.width+4*t)).attr("y",m+h.height-12)),"TB"!==S&&l.attr("x",o-h.width/2),a.rotateCommitLabel)if("TB"===S)l.attr("transform","rotate(-45, "+y+", "+m+")"),n.attr("transform","rotate(-45, "+y+", "+m+")");else{let t=-7.5-(h.width+10)/25*9.5,e=10+h.width/25*8.5;r.attr("transform","translate("+t+", "+e+") rotate(-45, "+s+", "+m+")")}}if(i.tag){const r=c.insert("polygon"),a=c.append("circle"),n=c.append("text").attr("y",m-16).attr("class","tag-label").text(i.tag);let l=n.node().getBBox();n.attr("x",o-l.width/2);const u=l.height/2,p=m-19.2;r.attr("class","tag-label-bkg").attr("points",`\n ${s-l.width/2-t/2},${p+e}\n ${s-l.width/2-t/2},${p-e}\n ${o-l.width/2-t},${p-u-e}\n ${o+l.width/2+t},${p-u-e}\n ${o+l.width/2+t},${p+u+e}\n ${o-l.width/2-t},${p+u+e}`),a.attr("cx",s-l.width/2+t/2).attr("cy",p).attr("r",1.5).attr("class","tag-hole"),"TB"===S&&(r.attr("class","tag-label-bkg").attr("points",`\n ${y},${s+e}\n ${y},${s-e}\n ${y+h},${s-u-e}\n ${y+h+l.width+t},${s-u-e}\n ${y+h+l.width+t},${s+u+e}\n ${y+h},${s+u+e}`).attr("transform","translate(12,12) rotate(45, "+y+","+s+")"),a.attr("cx",y+t/2).attr("cy",s).attr("transform","translate(12,12) rotate(45, "+y+","+s+")"),n.attr("x",y+5).attr("y",s+3).attr("transform","translate(14,14) rotate(45, "+y+","+s+")"))}}s+=50,s>C&&(C=s)}))},N=(t,e,r,i,a)=>{const n=("TB"===S?r.x<i.x:r.y<i.y)?e.branch:t.branch;return Object.values(a).some((r=>{return(i=r).seq>t.seq&&i.seq<e.seq&&(t=>t.branch===n)(r);var i}))},G=(t,e,r=0)=>{const i=t+Math.abs(t-e)/2;if(r>5)return i;if(O.every((t=>Math.abs(t-i)>=10)))return O.push(i),i;const a=Math.abs(t-e);return G(t,e-a/5,r+1)},H=(t,e)=>{const r=t.append("g").attr("class","commit-arrows");Object.keys(e).forEach((t=>{const i=e[t];i.parents&&i.parents.length>0&&i.parents.forEach((t=>{((t,e,r,i)=>{const a=R[e.id],n=R[r.id],c=N(e,r,a,n,i);let s,o="",l="",h=0,m=0,y=A[r.branch].index;if(r.type===v&&e.id!==r.parents[0]&&(y=A[e.branch].index),c){o="A 10 10, 0, 0, 0,",l="A 10 10, 0, 0, 1,",h=10,m=10;const t=a.y<n.y?G(a.y,n.y):G(n.y,a.y),r=a.x<n.x?G(a.x,n.x):G(n.x,a.x);"TB"===S?a.x<n.x?s=`M ${a.x} ${a.y} L ${r-h} ${a.y} ${l} ${r} ${a.y+m} L ${r} ${n.y-h} ${o} ${r+m} ${n.y} L ${n.x} ${n.y}`:(y=A[e.branch].index,s=`M ${a.x} ${a.y} L ${r+h} ${a.y} ${o} ${r} ${a.y+m} L ${r} ${n.y-h} ${l} ${r-m} ${n.y} L ${n.x} ${n.y}`):a.y<n.y?s=`M ${a.x} ${a.y} L ${a.x} ${t-h} ${o} ${a.x+m} ${t} L ${n.x-h} ${t} ${l} ${n.x} ${t+m} L ${n.x} ${n.y}`:(y=A[e.branch].index,s=`M ${a.x} ${a.y} L ${a.x} ${t+h} ${l} ${a.x+m} ${t} L ${n.x-h} ${t} ${o} ${n.x} ${t-m} L ${n.x} ${n.y}`)}else o="A 20 20, 0, 0, 0,",l="A 20 20, 0, 0, 1,",h=20,m=20,"TB"===S?(a.x<n.x&&(s=r.type===v&&e.id!==r.parents[0]?`M ${a.x} ${a.y} L ${a.x} ${n.y-h} ${o} ${a.x+m} ${n.y} L ${n.x} ${n.y}`:`M ${a.x} ${a.y} L ${n.x-h} ${a.y} ${l} ${n.x} ${a.y+m} L ${n.x} ${n.y}`),a.x>n.x&&(o="A 20 20, 0, 0, 0,",l="A 20 20, 0, 0, 1,",h=20,m=20,s=r.type===v&&e.id!==r.parents[0]?`M ${a.x} ${a.y} L ${a.x} ${n.y-h} ${l} ${a.x-m} ${n.y} L ${n.x} ${n.y}`:`M ${a.x} ${a.y} L ${n.x+h} ${a.y} ${o} ${n.x} ${a.y+m} L ${n.x} ${n.y}`),a.x===n.x&&(s=`M ${a.x} ${a.y} L ${n.x} ${n.y}`)):(a.y<n.y&&(s=r.type===v&&e.id!==r.parents[0]?`M ${a.x} ${a.y} L ${n.x-h} ${a.y} ${l} ${n.x} ${a.y+m} L ${n.x} ${n.y}`:`M ${a.x} ${a.y} L ${a.x} ${n.y-h} ${o} ${a.x+m} ${n.y} L ${n.x} ${n.y}`),a.y>n.y&&(s=r.type===v&&e.id!==r.parents[0]?`M ${a.x} ${a.y} L ${n.x-h} ${a.y} ${o} ${n.x} ${a.y-m} L ${n.x} ${n.y}`:`M ${a.x} ${a.y} L ${a.x} ${n.y+h} ${l} ${a.x+m} ${n.y} L ${n.x} ${n.y}`),a.y===n.y&&(s=`M ${a.x} ${a.y} L ${n.x} ${n.y}`));t.append("path").attr("d",s).attr("class","arrow arrow"+y%8)})(r,e[t],i,e)}))}))},z={parser:c,db:T,renderer:{draw:function(t,e,r,n){A={},R={},w={},C=0,O=[],S="LR";const c=(0,i.c)(),s=c.gitGraph;i.l.debug("in gitgraph renderer",t+"\n","id:",e,r),w=n.db.getCommits();const o=n.db.getBranchesAsObjArray();S=n.db.getDirection();const l=(0,a.Ltv)(`[id="${e}"]`);let h=0;o.forEach(((t,e)=>{const r=P(t.name),i=l.append("g"),a=i.insert("g").attr("class","branchLabel"),n=a.insert("g").attr("class","label branch-label");n.node().appendChild(r);let c=r.getBBox();A[t.name]={pos:h,index:e},h+=50+(s.rotateCommitLabel?40:0)+("TB"===S?c.width/2:0),n.remove(),a.remove(),i.remove()})),B(l,w,!1),s.showBranches&&((t,e)=>{const r=(0,i.c)().gitGraph,a=t.append("g");e.forEach(((t,e)=>{const i=e%8,n=A[t.name].pos,c=a.append("line");c.attr("x1",0),c.attr("y1",n),c.attr("x2",C),c.attr("y2",n),c.attr("class","branch branch"+i),"TB"===S&&(c.attr("y1",30),c.attr("x1",n),c.attr("y2",C),c.attr("x2",n)),O.push(n);let s=t.name;const o=P(s),l=a.insert("rect"),h=a.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+i);h.node().appendChild(o);let m=o.getBBox();l.attr("class","branchLabelBkg label"+i).attr("rx",4).attr("ry",4).attr("x",-m.width-4-(!0===r.rotateCommitLabel?30:0)).attr("y",-m.height/2+8).attr("width",m.width+18).attr("height",m.height+4),h.attr("transform","translate("+(-m.width-14-(!0===r.rotateCommitLabel?30:0))+", "+(n-m.height/2-1)+")"),"TB"===S&&(l.attr("x",n-m.width/2-10).attr("y",0),h.attr("transform","translate("+(n-m.width/2-5)+", 0)")),"TB"!==S&&l.attr("transform","translate(-19, "+(n-m.height/2)+")")}))})(l,o),H(l,w),B(l,w,!0),i.u.insertTitle(l,"gitTitleText",s.titleTopMargin,n.db.getDiagramTitle()),(0,i.z)(void 0,l,s.diagramPadding,s.useMaxWidth??c.useMaxWidth)}},styles:t=>`\n .commit-id,\n .commit-msg,\n .branch-label {\n fill: lightgrey;\n color: lightgrey;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n ${[0,1,2,3,4,5,6,7].map((e=>`\n .branch-label${e} { fill: ${t["gitBranchLabel"+e]}; }\n .commit${e} { stroke: ${t["git"+e]}; fill: ${t["git"+e]}; }\n .commit-highlight${e} { stroke: ${t["gitInv"+e]}; fill: ${t["gitInv"+e]}; }\n .label${e} { fill: ${t["git"+e]}; }\n .arrow${e} { stroke: ${t["git"+e]}; }\n `)).join("\n")}\n\n .branch {\n stroke-width: 1;\n stroke: ${t.lineColor};\n stroke-dasharray: 2;\n }\n .commit-label { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelColor};}\n .commit-label-bkg { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelBackground}; opacity: 0.5; }\n .tag-label { font-size: ${t.tagLabelFontSize}; fill: ${t.tagLabelColor};}\n .tag-label-bkg { fill: ${t.tagLabelBackground}; stroke: ${t.tagLabelBorder}; }\n .tag-hole { fill: ${t.textColor}; }\n\n .commit-merge {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n .commit-reverse {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n stroke-width: 3;\n }\n .commit-highlight-outer {\n }\n .commit-highlight-inner {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n\n .arrow { stroke-width: 8; stroke-linecap: round; fill: none}\n .gitTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/653904f7.8ecb6807.js b/assets/js/653904f7.8ecb6807.js new file mode 100644 index 0000000000..4b37640115 --- /dev/null +++ b/assets/js/653904f7.8ecb6807.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7653],{26093:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>a});var c=t(74848),s=t(28453);const o={},r="Custom CA",i={id:"container/components/k8s-cluster-api-provider/doc/usage/custom-ca",title:"Custom CA",description:"OpenStack provides public-facing API endpoints which protection by SSL/TLS certificates",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/custom-ca.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc/usage",slug:"/container/components/k8s-cluster-api-provider/doc/usage/custom-ca",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/usage/custom-ca.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Container registry configuration",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration"},next:{title:"Gateway-API",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api"}},d={},a=[{value:"Rotation",id:"rotation",level:2}];function l(e){const n={blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.h1,{id:"custom-ca",children:"Custom CA"}),"\n",(0,c.jsx)(n.p,{children:"OpenStack provides public-facing API endpoints which protection by SSL/TLS certificates\nis highly recommended in production environments.\nThese certificates are usually issued by public CA but also the custom or private CA could be used."}),"\n",(0,c.jsxs)(n.p,{children:["If the communication with OpenStack API is protected by the certificate issued by custom CA\nthe ",(0,c.jsx)(n.code,{children:"cacert"})," setting needs to be provided inside clouds.yaml, e.g.:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-yaml",children:"clouds:\n devstack:\n cacert: ca-bundle.pem\n auth:\n auth_url: https://10.0.3.15/identity\n project_domain_id: default\n project_name: demo\n user_domain_id: default\n identity_api_version: 3\n region_name: RegionOne\n interface: public\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Here the file ",(0,c.jsx)(n.code,{children:"ca-bundle.pem"})," contains custom root CA and potentially intermediate CA(s)."]}),"\n",(0,c.jsxs)(n.blockquote,{children:["\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"ca-bundle.pem"})," file will be copied to the management server and used by CAPO\nin the management cluster. Also, it will be copied to the workload cluster (control plane and worker nodes)\nand mounted and used by OCCM and CCSI pods.\nSo provide only the necessary certificates in that file."]}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Steps of what happens with the custom cacert in k8s-cluster-api-provider:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"cacert"})," setting is provided inside clouds.yaml"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["Cacert file referenced by ",(0,c.jsx)(n.code,{children:"cacert"})," key (1.) is copied to the management server\ndirectory ",(0,c.jsx)(n.code,{children:"~/cluster-defaults/${cloud_provider}-cacert"})," by OpenTofu"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["During the management server bootstrap process cacert is injected to\nthe ",(0,c.jsx)(n.code,{children:"~/cluster-defaults/cluster-template.yaml"})," to ",(0,c.jsx)(n.code,{children:"KubeadmControlPlane"})," and ",(0,c.jsx)(n.code,{children:"KubeadmConfigTemplate"})," files\nas file with cacert content from already defined secret ",(0,c.jsx)(n.code,{children:"${CLUSTER_NAME}-cloud-config"})," and will be later\ntemplated and copied to the workload cluster (control plane and worker nodes) provisioned by CAPO, e.g.:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-yaml",children:'files:\n- contentFrom:\n secret:\n key: cacert\n name: ${CLUSTER_NAME}-cloud-config\n owner: root:root\n path: /etc/ssl/certs/devstack-cacert\n permissions: "0644"\n'})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["When the creation of the workload cluster (",(0,c.jsx)(n.code,{children:"create_cluster.sh"}),") starts,\n",(0,c.jsx)(n.code,{children:"~/cluster-defaults/cluster-template.yaml"})," is copied into workload cluster directory (",(0,c.jsx)(n.code,{children:"~/$CLUSTER_NAME/"}),")"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["Then the cacert file content is base64 encoded and saved in OPENSTACK_CLOUD_CACERT_B64 variable\ninside ",(0,c.jsx)(n.code,{children:"~/$CLUSTER_NAME/clusterctl.yaml"}),", so it can be used during\nthe workload cluster templating"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["Later, when the workload cluster templates are applied to the management cluster,\nsecret ",(0,c.jsx)(n.code,{children:"${CLUSTER_NAME}-cloud-config"})," with base64 encoded cacert is created and used by CAPO"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"CAPO will create workload cluster (thanks to steps 5. and 6.) and cacert is\ntransferred to the control plane and worker nodes (thanks to steps 3. and 4.)"}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"OCCM and CCSI pods mount cacert via hostPath volume\nand use it for e.g. creating load balancers or volumes"}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"rotation",children:"Rotation"}),"\n",(0,c.jsxs)(n.p,{children:["When the custom CA expires or otherwise changes it needs to be rotated.\nCAPO uses the custom CA certificate in the management cluster for creating the infrastructure\nfor the workload clusters and in the workload clusters by OCCM and CCSI for e.g. creating load balancers or volumes.\nIn both cases, cacert is provided via secret ",(0,c.jsx)(n.code,{children:"${CLUSTER_NAME}-cloud-config"})," and needs to be updated."]}),"\n",(0,c.jsx)(n.p,{children:"There are 3 steps in this rotation process:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["Replace/append custom CA certificate in ",(0,c.jsx)(n.code,{children:"~/cluster-defaults/${cloud_provider}-cacert"})]}),"\n",(0,c.jsxs)(n.li,{children:["Increase generation counters ",(0,c.jsx)(n.code,{children:"CONTROL_PLANE_MACHINE_GEN"})," and ",(0,c.jsx)(n.code,{children:"WORKER_MACHINE_GEN"})," in ",(0,c.jsx)(n.code,{children:"~/$CLUSTER_NAME/clusterctl.yaml"})]}),"\n",(0,c.jsxs)(n.li,{children:["Run ",(0,c.jsx)(n.code,{children:"create_cluster.sh $CLUSTER_NAME"})," and wait for the rolling update of your workload cluster"]}),"\n"]}),"\n",(0,c.jsxs)(n.blockquote,{children:["\n",(0,c.jsx)(n.p,{children:"In step 1, appending can be useful for avoiding downtime of your services.\nYour cacert file will contain two CA certificates - old and new.\nThis should help with a smooth transition to a new certificate and later, the old one can be removed."}),"\n",(0,c.jsx)(n.p,{children:"Steps 2 and 3 need to be done per workload cluster."}),"\n",(0,c.jsx)(n.p,{children:"When step 2 is omitted, only cacert secret in the management cluster is updated and no rolling update of\nthe workload cluster in step 3 is started and existing nodes remain with the old certificate."}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var c=t(96540);const s={},o=c.createContext(s);function r(e){const n=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),c.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/65742e9f.9bf832bd.js b/assets/js/65742e9f.9bf832bd.js new file mode 100644 index 0000000000..0f896607eb --- /dev/null +++ b/assets/js/65742e9f.9bf832bd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5147],{96116:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var o=t(74848),i=t(28453);const r={},s="Example setup configuration in SCS deployment explained",c={id:"iam/SCS-example-setup-configuration-description",title:"Example setup configuration in SCS deployment explained",description:"The following document explains the idea behind the example configuration is done.",source:"@site/docs/05-iam/SCS-example-setup-configuration-description.md",sourceDirName:"05-iam",slug:"/iam/SCS-example-setup-configuration-description",permalink:"/docs/iam/SCS-example-setup-configuration-description",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/05-iam/SCS-example-setup-configuration-description.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Domain Manager setup and usage",permalink:"/docs/iam/domain-manager-setup-and-usage"},next:{title:"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)",permalink:"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations"}},a={},l=[];function d(e){const n={a:"a",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"example-setup-configuration-in-scs-deployment-explained",children:"Example setup configuration in SCS deployment explained"}),"\n",(0,o.jsxs)(n.p,{children:["The following document explains the idea behind the example configuration is done.\nThe playbook creates a proxy realm used to connect with ",(0,o.jsx)(n.code,{children:"Keystone"}),", a customer realm, the clients needed to connect the realms, the identity brokering for the customer realm, a login flow\nto be able to use the ",(0,o.jsx)(n.code,{children:"home-IdP-discovery"})," plugin to redirect to the correct customer realm and an example user.\nSCS operators can find the playbook that creates the setup ",(0,o.jsx)(n.a,{href:"https://github.com/osism/ansible-playbooks/blob/main/playbooks/infrastructure/keycloak-oidc-client-config.yml",children:"here"}),"."]}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["In the first place a proxy realm called ",(0,o.jsx)(n.code,{children:"osism"})," on the example deployment. That realm will\nbecome the realm that will be conected to ",(0,o.jsx)(n.code,{children:"Keystone"})]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["A customer realm called ",(0,o.jsx)(n.code,{children:"CustomerA"})," is created. On that realm a ",(0,o.jsx)(n.code,{children:"OIDC"})," client is created to hook\nup the realm to the proxy realm. This is done via ",(0,o.jsx)(n.code,{children:"Identity Brokering"})," in the proxy realm."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["An ",(0,o.jsx)(n.code,{children:"Identity provider"})," is configured in the ",(0,o.jsx)(n.code,{children:"osism"})," realm, this is configured to be connected to\nthe ",(0,o.jsx)(n.code,{children:"CustomerA"})," realm. For that, a set of mappers are created, the default ones are a ",(0,o.jsx)(n.code,{children:"hardcoded-attribute"}),"\nthat sets the domain where the user came from, and an ",(0,o.jsx)(n.code,{children:"attribute-importer"})," mapper for the ",(0,o.jsx)(n.code,{children:"openstack-default-project"})," that comes\nin the ",(0,o.jsx)(n.code,{children:"OIDC"})," claim from the customer realm."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["A new login flow has been created in the ",(0,o.jsx)(n.code,{children:"osism"})," realm, this login flow is needed to use the ",(0,o.jsx)(n.code,{children:"home-IdP-discovery"})," plugin."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Creation of an example user called ",(0,o.jsx)(n.code,{children:"Alice"}),"."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>c});var o=t(96540);const i={},r=o.createContext(i);function s(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/657efcba.61d46c3f.js b/assets/js/657efcba.61d46c3f.js new file mode 100644 index 0000000000..d954679d94 --- /dev/null +++ b/assets/js/657efcba.61d46c3f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1238],{18850:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var r=s(74848),t=s(28453);const i={},c="Quickstart",o={id:"container/components/container-registry/docs/quickstart",title:"Quickstart",description:"This guide shows you how to set up a working Harbor Container Registry that utilizes a Kubernetes cluster.",source:"@site/docs/03-container/components/container-registry/docs/quickstart.md",sourceDirName:"03-container/components/container-registry/docs",slug:"/container/components/container-registry/docs/quickstart",permalink:"/docs/container/components/container-registry/docs/quickstart",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/quickstart.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Container Registry",permalink:"/docs/category/container-registry"},next:{title:"SCS deployment",permalink:"/docs/container/components/container-registry/docs/scs-deployment"}},a={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install Harbor container registry",id:"install-harbor-container-registry",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"quickstart",children:"Quickstart"}),"\n",(0,r.jsx)(n.p,{children:"This guide shows you how to set up a working Harbor Container Registry that utilizes a Kubernetes cluster."}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Kubernetes cluster v1.20+","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Use existing cluster","\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"export KUBECONFIG=/path/to/kubeconfig\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Alternatively, spawn some dev cluster, e.g. using ",(0,r.jsx)(n.a,{href:"https://kind.sigs.k8s.io/docs/user/quick-start/",children:"KinD"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kind create cluster\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Flux CLI","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Installation documentation: ",(0,r.jsx)(n.a,{href:"https://fluxcd.io/flux/installation/#install-the-flux-cli",children:"https://fluxcd.io/flux/installation/#install-the-flux-cli"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s https://fluxcd.io/install.sh | sudo FLUX_VERSION=2.2.3 bash\nflux install\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"install-harbor-container-registry",children:"Install Harbor container registry"}),"\n",(0,r.jsxs)(n.p,{children:["Apply kustomization manifest in ",(0,r.jsx)(n.code,{children:"envs/dev"})," directory:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl apply -k envs/dev/\n"})}),"\n",(0,r.jsx)(n.p,{children:"Port-forward the Harbor container registry service:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl port-forward svc/harbor 8080:80\n"})}),"\n",(0,r.jsx)(n.p,{children:"Access the Harbor container registry UI and use Harbor's default credentials"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["username: ",(0,r.jsx)(n.code,{children:"admin"})]}),"\n",(0,r.jsxs)(n.li,{children:["password: ",(0,r.jsx)(n.code,{children:"Harbor12345"})]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"http://localhost:8080\n"})})]})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>o});var r=s(96540);const t={},i=r.createContext(t);function c(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/65c1efe1.e11b1659.js b/assets/js/65c1efe1.e11b1659.js new file mode 100644 index 0000000000..a122b76ca7 --- /dev/null +++ b/assets/js/65c1efe1.e11b1659.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5663],{25179:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>o});var r=s(74848),n=s(28453);const a={},i="scs-0212: Requirements for container registries",c={id:"kaas/scs-0212",title:"scs-0212: Requirements for container registries",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/kaas/scs-0212.md",sourceDirName:"kaas",slug:"/kaas/scs-0212",permalink:"/standards/kaas/scs-0212",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"SCS KaaS default storage class",permalink:"/standards/scs-0211-v1-kaas-default-storage-class"},next:{title:"Requirements for container registries",permalink:"/standards/scs-0212-v1-requirements-for-container-registries"}},d={},o=[];function l(e){const t={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"scs-0212-requirements-for-container-registries",children:"scs-0212: Requirements for container registries"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Version"}),(0,r.jsx)(t.th,{children:"Type"}),(0,r.jsx)(t.th,{children:"State"}),(0,r.jsx)(t.th,{children:"stabilized"}),(0,r.jsx)(t.th,{children:"deprecated"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/standards/scs-0212-v1-requirements-for-container-registries",children:"scs-0212-v1"})}),(0,r.jsx)(t.td,{children:"Standard"}),(0,r.jsx)(t.td,{children:"Draft"}),(0,r.jsx)(t.td,{children:"-"}),(0,r.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>c});var r=s(96540);const n={},a=r.createContext(n);function i(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/65c90e53.2b1ac8ca.js b/assets/js/65c90e53.2b1ac8ca.js new file mode 100644 index 0000000000..9cadaff9fd --- /dev/null +++ b/assets/js/65c90e53.2b1ac8ca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5985],{69782:e=>{e.exports=JSON.parse('{"title":"Components","slug":"/category/components-1","permalink":"/docs/category/components-1","navigation":{"previous":{"title":"Container Layer Introduction","permalink":"/docs/container/"},"next":{"title":"K8s Cluster API Provider","permalink":"/docs/category/k8s-cluster-api-provider"}}}')}}]); \ No newline at end of file diff --git a/assets/js/66dc81f9.632aa600.js b/assets/js/66dc81f9.632aa600.js new file mode 100644 index 0000000000..c6bd7c7f0d --- /dev/null +++ b/assets/js/66dc81f9.632aa600.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3734],{61230:t=>{t.exports=JSON.parse('{"title":"Tools","slug":"/category/tools","permalink":"/community/category/tools","navigation":{"previous":{"title":"SIG Standardization","permalink":"/community/collaboration/sig-standardization"},"next":{"title":"Jitsi","permalink":"/community/tools/jitsi"}}}')}}]); \ No newline at end of file diff --git a/assets/js/670b12e1.f150d3b8.js b/assets/js/670b12e1.f150d3b8.js new file mode 100644 index 0000000000..c60e85fadd --- /dev/null +++ b/assets/js/670b12e1.f150d3b8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3919],{22189:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>a});var o=s(74848),t=s(28453);const i={sidebar_label:"Console"},l="Console",d={id:"iaas/guides/operations-guide/manager/console",title:"Console",description:"A console command is available in the OSISM CLI. This allows specific parts of the",source:"@site/docs/02-iaas/guides/operations-guide/manager/console.md",sourceDirName:"02-iaas/guides/operations-guide/manager",slug:"/iaas/guides/operations-guide/manager/console",permalink:"/docs/iaas/guides/operations-guide/manager/console",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/manager/console.md",tags:[],version:"current",frontMatter:{sidebar_label:"Console"},sidebar:"docs",previous:{title:"Apply",permalink:"/docs/iaas/guides/operations-guide/manager/apply"},next:{title:"Get",permalink:"/docs/iaas/guides/operations-guide/manager/get"}},r={},a=[{value:"Ansible",id:"ansible",level:2},{value:"Clush",id:"clush",level:2},{value:"Container",id:"container",level:2},{value:"SSH",id:"ssh",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"console",children:"Console"}),"\n",(0,o.jsxs)(n.p,{children:["A ",(0,o.jsx)(n.code,{children:"console"})," command is available in the OSISM CLI. This allows specific parts of the\nenvironment to be operated interactively."]}),"\n",(0,o.jsx)(n.h2,{id:"ansible",children:"Ansible"}),"\n",(0,o.jsxs)(n.p,{children:["Used tool: ",(0,o.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/cli/ansible-console.html",children:"ansible-console"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ osism console --type ansible testbed-node-0\nWelcome to the ansible console. Type help or ? to list commands.\n\ndragon@testbed-node-0 (1)[f:5]$ !uptime\ntestbed-node-0 | CHANGED | rc=0 >>\n 18:14:15 up 80 days, 33 min, 0 users, load average: 4.00, 3.07, 2.67\ndragon@testbed-node-0 (1)[f:5]$\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Shortcut: ",(0,o.jsx)(n.code,{children:"osism console .testbed-node-0"})]}),"\n",(0,o.jsx)(n.h2,{id:"clush",children:"Clush"}),"\n",(0,o.jsxs)(n.p,{children:["Used tool: ",(0,o.jsx)(n.a,{href:"https://clustershell.readthedocs.io",children:"ClusterShell"})]}),"\n",(0,o.jsx)(n.p,{children:"The same groups as defined in the Ansible Inventory can be used."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ osism console --type clush control\nEnter 'quit' to leave this interactive mode\nWorking with nodes: testbed-node-[0-2]\nclush>\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Shortcut: ",(0,o.jsx)(n.code,{children:"osism console :control"})]}),"\n",(0,o.jsx)(n.h2,{id:"container",children:"Container"}),"\n",(0,o.jsxs)(n.p,{children:["Used tool: ",(0,o.jsx)(n.a,{href:"https://python-prompt-toolkit.readthedocs.io/en/master/index.html",children:"Python Prompt Toolkit"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ osism console --type container testbed-node-0/fluentd\n(fluentd)[td-agent@testbed-node-0 /]$ ps ax\n PID TTY STAT TIME COMMAND\n 1 ? Ss 0:00 dumb-init --single-child -- kolla_start\n 7 ? Sl 24:28 /opt/td-agent/bin/ruby /usr/sbin/td-agent -o /var/log/kolla/fluentd/fluent\n 25 ? Sl 3519:55 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /usr/sbin/td-agent -o /var\n 238 pts/0 Ss 0:00 bash\n 247 pts/0 R+ 0:00 ps ax\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Shortcut: ",(0,o.jsx)(n.code,{children:"osism console testbed-node-0/fluentd"})]}),"\n",(0,o.jsx)(n.h2,{id:"ssh",children:"SSH"}),"\n",(0,o.jsxs)(n.p,{children:["Used tool: ",(0,o.jsx)(n.a,{href:"https://www.openssh.com",children:"OpenSSH"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ osism console --type ssh testbed-node-0\nYou have new mail.\nLast login: Wed Sep 27 18:15:39 2023 from 192.168.16.5\ndragon@testbed-node-0:~$ uptime\n 18:16:25 up 80 days, 35 min, 1 user, load average: 2.85, 3.04, 2.71\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Shortcut: ",(0,o.jsx)(n.code,{children:"osism console testbed-node-0"})]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>d});var o=s(96540);const t={},i=o.createContext(t);function l(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/67140352.7db3c496.js b/assets/js/67140352.7db3c496.js new file mode 100644 index 0000000000..82fe9b9141 --- /dev/null +++ b/assets/js/67140352.7db3c496.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3575],{12826:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>t,toc:()=>l});var i=a(74848),o=a(28453);const s={},r="Domain Manager setup and usage",t={id:"iam/domain-manager-setup-and-usage",title:"Domain Manager setup and usage",description:"The following documentation refers to a SCS standard that is still in draft state.",source:"@site/docs/05-iam/domain-manager-setup-and-usage.md",sourceDirName:"05-iam",slug:"/iam/domain-manager-setup-and-usage",permalink:"/docs/iam/domain-manager-setup-and-usage",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/05-iam/domain-manager-setup-and-usage.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Guides",permalink:"/docs/category/guides-2"},next:{title:"Example setup configuration in SCS deployment explained",permalink:"/docs/iam/SCS-example-setup-configuration-description"}},d={},l=[{value:"Preface",id:"preface",level:2},{value:"Warning regarding the exposure of domain names",id:"warning-regarding-the-exposure-of-domain-names",level:3},{value:"Infrastructure configuration",id:"infrastructure-configuration",level:2},{value:"[Initial] Keystone API policy adjustments",id:"initial-keystone-api-policy-adjustments",level:3},{value:"[Initial] Keystone role creation",id:"initial-keystone-role-creation",level:3},{value:"[Runtime] Domain Manager managed roles adjustment",id:"runtime-domain-manager-managed-roles-adjustment",level:3},{value:"Administrative operation",id:"administrative-operation",level:2},{value:"Creating domains",id:"creating-domains",level:3},{value:"Creating a Domain Manager user",id:"creating-a-domain-manager-user",level:3},{value:"Assigning the Domain Manager role to an existing user",id:"assigning-the-domain-manager-role-to-an-existing-user",level:3},{value:"Revoking the Domain Manager role",id:"revoking-the-domain-manager-role",level:3},{value:"Domain Manager operation",id:"domain-manager-operation",level:2},{value:"Managing users within a domain",id:"managing-users-within-a-domain",level:3},{value:"Managing projects within a domain",id:"managing-projects-within-a-domain",level:3},{value:"Deleting projects",id:"deleting-projects",level:4},{value:"Managing groups within a domain",id:"managing-groups-within-a-domain",level:3},{value:"Managing group membership",id:"managing-group-membership",level:4},{value:"Managing role assignments within a domain",id:"managing-role-assignments-within-a-domain",level:3},{value:"Managing user role assignments",id:"managing-user-role-assignments",level:4},{value:"Managing group role assignments",id:"managing-group-role-assignments",level:4}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"domain-manager-setup-and-usage",children:"Domain Manager setup and usage"}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsx)(n.p,{children:"The following documentation refers to a SCS standard that is still in draft state.\nIt is not meant for productive use yet but CSPs are encouraged to test-drive and provide feedback!"})}),"\n",(0,i.jsx)(n.h2,{id:"preface",children:"Preface"}),"\n",(0,i.jsxs)(n.p,{children:["SCS defines the ",(0,i.jsx)(n.strong,{children:"Domain Manager"})," standard, introducing a special persona to the OpenStack Keystone identity manager.\nThis persona offers a properly domain-scoped permission set to manage users, groups, projects and role assignments within a domain.\nIts intended use case is to offer extensive identity management self-service capabilities to tenants mapped to a domain."]}),"\n",(0,i.jsx)(n.p,{children:"This guide will explain setup, configuration and usage of the SCS Domain Manager standard."}),"\n",(0,i.jsx)(n.h3,{id:"warning-regarding-the-exposure-of-domain-names",children:"Warning regarding the exposure of domain names"}),"\n",(0,i.jsxs)(n.p,{children:["Due to architectural limitations currently existing in OpenStack Keystone, assigning the ",(0,i.jsx)(n.code,{children:"manager"})," role to users while the configuration of the SCS Domain Manager standard has been applied will ",(0,i.jsx)(n.strong,{children:"enable them to see the IDs and names of all existing domains"}),".\nThis includes domains other than their own, meaning that other tenant's identities might be exposed depending on the relation between them and the name of their domain.\nCSPs aiming to appoint Domain Manager users must be aware of this limitation and should exclusively ",(0,i.jsx)(n.strong,{children:"use pseudonymized domain names across the whole infrastructure"}),".\nIf CSPs strictly follow the ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0301-v1-naming-conventions.md",children:"SCS naming conventions"})," for domains this is already addressed.\nIf this is not feasible for the CSP, they may opt to refrain from making use of the Domain Manager functionality at all, i.e. never assign the ",(0,i.jsx)(n.code,{children:"manager"})," role to tenant users."]}),"\n",(0,i.jsxs)(n.admonition,{type:"info",children:[(0,i.jsx)(n.p,{children:"This architectural limitation will be fixed in upcoming OpenStack and SCS releases."}),(0,i.jsxs)(n.p,{children:["See ",(0,i.jsx)(n.a,{href:"https://bugs.launchpad.net/keystone/+bug/2041611",children:"https://bugs.launchpad.net/keystone/+bug/2041611"})]})]}),"\n",(0,i.jsx)(n.h2,{id:"infrastructure-configuration",children:"Infrastructure configuration"}),"\n",(0,i.jsxs)(n.p,{children:["An initial infrastructure configuration of the Domain Manager persona must be completed before it can be used.\nThis includes adjusting the Keystone API policy configuration and the registration of the ",(0,i.jsx)(n.code,{children:"manager"})," role."]}),"\n",(0,i.jsx)(n.p,{children:'The following sections describe the configuration to be implemented on the infrastructure-level.\nThis requires infrastructure access and OpenStack admin rights.\nFor tasks marked with "[Initial]" the described procedure only has to happen once initially.\nFor tasks marked with "[Runtime]" the described procedure may be repeated later on to make adjustments.'}),"\n",(0,i.jsx)(n.h3,{id:"initial-keystone-api-policy-adjustments",children:"[Initial] Keystone API policy adjustments"}),"\n",(0,i.jsxs)(n.p,{children:['First, incorporate the Keystone API policy definitions as described in the SCS Domain Manager standard.\nThis is usually done in "',(0,i.jsx)(n.code,{children:"/etc/keystone/policy.yaml"}),'" of the Keystone API service.\nOtherwise, an entry called "',(0,i.jsx)(n.code,{children:"policy_file"}),'" under the "',(0,i.jsx)(n.code,{children:"[oslo_policy]"}),'" section of "',(0,i.jsx)(n.code,{children:"/etc/keystone/keystone.conf"}),'" might exist that points to a different policy file path.\nIn such case, adjust or create the file at the specified path.']}),"\n",(0,i.jsxs)(n.p,{children:['When incorporating the policy definitions from the standard make sure to properly merge it with existing policy definitions, if any exist.\nAlso choose the definition of manageable roles in the "',(0,i.jsx)(n.code,{children:"is_domain_managed_role"}),'" rule of the policy carefully according to your requirements and environment.\nSee the standard for more details on this rule.']}),"\n",(0,i.jsx)(n.p,{children:"Depending on the deployment method used, the adjustments may also need to be persisted in the corresponding infrastructure management solution, such as Ansible."}),"\n",(0,i.jsx)(n.h3,{id:"initial-keystone-role-creation",children:"[Initial] Keystone role creation"}),"\n",(0,i.jsxs)(n.p,{children:["The role ",(0,i.jsx)(n.code,{children:"manager"})," has to exist in Keystone.\nIf the role does not exist, it needs to be created in Keystone once.\nThis can be done with the OpenStackClient using the following command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack role create manager\n"})}),"\n",(0,i.jsx)(n.h3,{id:"runtime-domain-manager-managed-roles-adjustment",children:"[Runtime] Domain Manager managed roles adjustment"}),"\n",(0,i.jsxs)(n.p,{children:['The list of roles that a Domain Manager can assign within a domain is configured using the "',(0,i.jsx)(n.code,{children:"is_domain_managed_role"}),'" rule of the policy definitions.\nThe SCS Domain Manager standard allows flexibility in defining the set of roles a Domain Manager may assign and revoke within a domain and enables adjustments at runtime',(0,i.jsx)(n.sup,{children:(0,i.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"."]}),"\n",(0,i.jsxs)(n.p,{children:['The set of roles can be adjusted independently from the rest of the policy by changing only the "',(0,i.jsx)(n.code,{children:"is_domain_managed_role"}),"\" line it Keystone's API policy file.\nChanges will apply to existing and future Domain Manager users.\nThis means that changes can be implemented at runtime",(0,i.jsx)(n.sup,{children:(0,i.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The following example entry adjusts the rule to allow both ",(0,i.jsx)(n.code,{children:"member"})," and ",(0,i.jsx)(n.code,{children:"reader"})," roles to be managed by Domain Managers:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"'is_domain_managed_role': \"'member':%(target.role.name)s or 'reader':%(target.role.name)s\"\n"})}),"\n",(0,i.jsx)(n.p,{children:"Refer to the SCS Domain Manager standard for more information."}),"\n",(0,i.jsx)(n.h2,{id:"administrative-operation",children:"Administrative operation"}),"\n",(0,i.jsxs)(n.p,{children:["The following sections describe actions available to CSP operators that possess the ",(0,i.jsx)(n.code,{children:"admin"})," role."]}),"\n",(0,i.jsx)(n.h3,{id:"creating-domains",children:"Creating domains"}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsxs)(n.p,{children:["It is highly recommended to use pseudonymized domain names when creating domains, since Domain Managers will currently be able to see the names of all existing domains.\nSee ",(0,i.jsx)(n.a,{href:"#warning-regarding-the-exposure-of-domain-names",children:"Warning regarding the exposure of domain names"})," for more details."]})}),"\n",(0,i.jsx)(n.p,{children:"For each tenant for which a self-service area (i.e. a domain) is to be established, a domain should be created before creating any users, projects or groups for this tenant:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack domain create $DOMAIN\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Any creation of users, projects or group for a tenant should happen strictly within the tenant's domain by passing the \"",(0,i.jsx)(n.code,{children:"--domain"}),'" flag to the corresponding creation commands, regardless of whether the commands are executed by an administrator or a Domain Manager.\nSee the ',(0,i.jsx)(n.a,{href:"#domain-manager-operation",children:"Domain Manager operation"})," section further down for reference."]}),"\n",(0,i.jsx)(n.h3,{id:"creating-a-domain-manager-user",children:"Creating a Domain Manager user"}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Creating the first Domain Manager users for a domain is an action reserved for CSP administrators.\nDepending on whether the ",(0,i.jsx)(n.code,{children:"manager"})," role has been approved as a domain-managed role in the policy configuration by the CSP, Domain Manager users may be able to appoint further Domain Managers within the domain on their own later on."]})}),"\n",(0,i.jsxs)(n.p,{children:["First, create the user for the Domain Manager.\nYou may create the Domain Manager user either directly in the target tenant's domain or in a different domain.\nThe domain a Domain Manager will effectively be able to manage solely depends on where its role assignment of the ",(0,i.jsx)(n.code,{children:"manager"})," role is scoped, not the domain the Domain Manager user was originally created in."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack user create --domain $MANAGER_DOMAIN $USER_NAME\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"$MANAGER_DOMAIN"})," can be the same as the tenant domain ",(0,i.jsx)(n.code,{children:"$DOMAIN"})," or an entirely different one, depending on the desired origin domain of the user.\nIn the following sections ",(0,i.jsx)(n.code,{children:"$DOMAIN"})," will denote the tenant domain that the user is intended to manage as the Domain Manager persona."]})}),"\n",(0,i.jsxs)(n.p,{children:["Next, assign the ",(0,i.jsx)(n.code,{children:"manager"})," role in a domain-scoped fashion to the tenant domain:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack role add --user $USER_NAME --domain $DOMAIN manager\n"})}),"\n",(0,i.jsx)(n.h3,{id:"assigning-the-domain-manager-role-to-an-existing-user",children:"Assigning the Domain Manager role to an existing user"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack role add --user $USER_NAME --domain $DOMAIN manager\n"})}),"\n",(0,i.jsx)(n.h3,{id:"revoking-the-domain-manager-role",children:"Revoking the Domain Manager role"}),"\n",(0,i.jsxs)(n.p,{children:["In case the ",(0,i.jsx)(n.code,{children:"manager"})," role is to be revoked from an existing Domain Manager user, the following command can be used:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack role remove --user $USER_NAME --domain $DOMAIN manager\n"})}),"\n",(0,i.jsx)(n.h2,{id:"domain-manager-operation",children:"Domain Manager operation"}),"\n",(0,i.jsxs)(n.p,{children:["The following sections describe actions available to Domain Managers that possess the ",(0,i.jsx)(n.code,{children:"manager"})," role."]}),"\n",(0,i.jsx)(n.h3,{id:"managing-users-within-a-domain",children:"Managing users within a domain"}),"\n",(0,i.jsx)(n.p,{children:"Creating a user within a domain:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack user create --domain $DOMAIN $USER_NAME\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:['The explicit domain-scoping is only required for the creation command, any other user-centric commands like "',(0,i.jsx)(n.code,{children:"user set"}),'" or "',(0,i.jsx)(n.code,{children:"user delete"}),'" do not require the "',(0,i.jsx)(n.code,{children:"--domain"}),'" flag and are automatically scoped to the domain for Domain Managers.']})}),"\n",(0,i.jsx)(n.h3,{id:"managing-projects-within-a-domain",children:"Managing projects within a domain"}),"\n",(0,i.jsx)(n.p,{children:"Creating a project within a domain:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack project create --domain $DOMAIN $PROJECT_NAME\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:['The explicit domain-scoping is only required for the creation command, any other project-centric commands like "',(0,i.jsx)(n.code,{children:"project set"}),'" or "',(0,i.jsx)(n.code,{children:"project delete"}),'" do not require the "',(0,i.jsx)(n.code,{children:"--domain"}),'" flag and are automatically scoped to the domain for Domain Managers.']})}),"\n",(0,i.jsx)(n.h4,{id:"deleting-projects",children:"Deleting projects"}),"\n",(0,i.jsx)(n.p,{children:"Note that before deleting projects, make sure that all cloud resources (servers, volumes etc.) belonging to that project have been removed beforehand.\nOtherwise such resources might become orphaned and inaccessible without involving the CSP."}),"\n",(0,i.jsx)(n.h3,{id:"managing-groups-within-a-domain",children:"Managing groups within a domain"}),"\n",(0,i.jsx)(n.p,{children:"Creating a group within a domain:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack group create --domain $DOMAIN $GROUP_NAME\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:['The explicit domain-scoping is only required for the creation command, any other group-centric commands like "',(0,i.jsx)(n.code,{children:"group set"}),'" or "',(0,i.jsx)(n.code,{children:"group delete"}),'" do not require the "',(0,i.jsx)(n.code,{children:"--domain"}),'" flag and are automatically scoped to the domain for Domain Managers.']})}),"\n",(0,i.jsx)(n.h4,{id:"managing-group-membership",children:"Managing group membership"}),"\n",(0,i.jsx)(n.p,{children:"Adding a user to a group:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack group add user $GROUP $USER\n"})}),"\n",(0,i.jsx)(n.p,{children:"Removing a user from a group:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack group remove user $GROUP $USER\n"})}),"\n",(0,i.jsx)(n.h3,{id:"managing-role-assignments-within-a-domain",children:"Managing role assignments within a domain"}),"\n",(0,i.jsxs)(n.p,{children:["Role assignments managed by a Domain Manager work as usual with the exception that the roles that can be assigned and revoked are limited to a defined set which is explicitly approved for Domain Managers by the CSP.\nThis may or may not include the ",(0,i.jsx)(n.code,{children:"manager"})," role itself, meaning that Domain Managers may either be able to appoint other Domain Managers by themselves or have to ask the CSP to do so."]}),"\n",(0,i.jsx)(n.h4,{id:"managing-user-role-assignments",children:"Managing user role assignments"}),"\n",(0,i.jsx)(n.p,{children:"Assigning a role to a user within a project:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack role add --project $PROJECT --user $USER $ROLE\n"})}),"\n",(0,i.jsx)(n.p,{children:"Assigning a role to a user domain-wide:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack role add --domain $DOMAIN --user $USER $ROLE\n"})}),"\n",(0,i.jsx)(n.p,{children:"Revoking a project-level role assignment from a user:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack role remove --project $PROJECT --user $USER $ROLE\n"})}),"\n",(0,i.jsx)(n.p,{children:"Revoking a domain-wide role assignment from a user:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack role remove --domain $DOMAIN --user $USER $ROLE\n"})}),"\n",(0,i.jsx)(n.h4,{id:"managing-group-role-assignments",children:"Managing group role assignments"}),"\n",(0,i.jsx)(n.p,{children:"Assigning a role to a group within a project:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack role add --project $PROJECT --group $GROUP $ROLE\n"})}),"\n",(0,i.jsx)(n.p,{children:"Assigning a role to a group domain-wide:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack role add --domain $DOMAIN --group $GROUP $ROLE\n"})}),"\n",(0,i.jsx)(n.p,{children:"Revoking a project-level role assignment from a group:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack role remove --project $PROJECT --group $GROUP $ROLE\n"})}),"\n",(0,i.jsx)(n.p,{children:"Revoking a domain-wide role assignment from a group:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack role remove --domain $DOMAIN --group $GROUP $ROLE\n"})}),"\n","\n",(0,i.jsxs)(n.section,{"data-footnotes":!0,className:"footnotes",children:[(0,i.jsx)(n.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{id:"user-content-fn-1",children:["\n",(0,i.jsxs)(n.p,{children:['"at runtime" in this context means that the configuration may be changed repeatedly after the initial configuration of Keystone and take effect immediately.\nDepending on the infrastructure management solution and high-availability configuration the described adjustments may or may not require a restart of the Keystone API service or lead to a downtime of the service. ',(0,i.jsx)(n.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})," ",(0,i.jsxs)(n.a,{href:"#user-content-fnref-1-2","data-footnote-backref":"","aria-label":"Back to reference 1-2",className:"data-footnote-backref",children:["\u21a9",(0,i.jsx)(n.sup,{children:"2"})]})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>r,x:()=>t});var i=a(96540);const o={},s=i.createContext(o);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/67dad519.7de71521.js b/assets/js/67dad519.7de71521.js new file mode 100644 index 0000000000..46bd56ef88 --- /dev/null +++ b/assets/js/67dad519.7de71521.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4980],{71028:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>t,metadata:()=>l,toc:()=>a});var o=i(74848),s=i(28453);const t={sidebar_label:"Provisioning",sidebar_position:30},r="Provisioning of bare-metal nodes",l={id:"iaas/guides/deploy-guide/provisioning",title:"Provisioning of bare-metal nodes",description:"For the initial deployment of the management plane and the control plane of OSISM,",source:"@site/docs/02-iaas/guides/deploy-guide/provisioning.md",sourceDirName:"02-iaas/guides/deploy-guide",slug:"/iaas/guides/deploy-guide/provisioning",permalink:"/docs/iaas/guides/deploy-guide/provisioning",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/provisioning.md",tags:[],version:"current",sidebarPosition:30,frontMatter:{sidebar_label:"Provisioning",sidebar_position:30},sidebar:"docs",previous:{title:"Manager",permalink:"/docs/iaas/guides/deploy-guide/manager"},next:{title:"Bootstrap",permalink:"/docs/iaas/guides/deploy-guide/bootstrap"}},d={},a=[{value:"Manual provisioning",id:"manual-provisioning",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"provisioning-of-bare-metal-nodes",children:"Provisioning of bare-metal nodes"}),"\n",(0,o.jsx)(n.p,{children:"For the initial deployment of the management plane and the control plane of OSISM,\nthe nodes must be pre-provisioned with Ubuntu 22.04. Currently, only Ubuntu 22.04 is supported\nby OSISM."}),"\n",(0,o.jsx)(n.p,{children:"Data plane nodes can be automatically provisioned after the initial deployment and\ndo not need to be pre-provisioned."}),"\n",(0,o.jsxs)(n.p,{children:["It is recommended not to install the initial nodes of the management plane and the\ncontrol plane manually. An ISO image is provided for this purpose which automatically\nprovisions a node. The ISO images are available for download in the\n",(0,o.jsx)(n.a,{href:"https://github.com/osism/node-image",children:"osism/node-image"})," repository."]}),"\n",(0,o.jsxs)(n.p,{children:["There are different variants of the ISO image. The variants differ in the disc layout.\nThe available variants are described in the README file of the ",(0,o.jsx)(n.a,{href:"https://github.com/osism/node-image",children:"osism/node-image"}),"\nrepository."]}),"\n",(0,o.jsx)(n.h2,{id:"manual-provisioning",children:"Manual provisioning"}),"\n",(0,o.jsx)(n.p,{children:"If none of the provided variants is suitable, this section describes the manual\ninstallation with the help of the Ubuntu 22.04 live ISO image. The manual installation\nis possible without network connectivity."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Download the latest ISO image for Ubuntu 22.04 from ",(0,o.jsx)(n.a,{href:"https://www.releases.ubuntu.com/22.04/",children:"releases.ubuntu.com"}),".","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Use the ",(0,o.jsx)(n.code,{children:"ubuntu-22.04.1-live-server-amd64.iso"})," image."]}),"\n",(0,o.jsx)(n.li,{children:"The version number may be different, always use the latest available version of 22.04 LTS."}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"English"})," as language."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"Install Ubuntu Server"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"English as language"})," (again)."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose your location (e.g. ",(0,o.jsx)(n.code,{children:"Germany"}),")."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"en_US.UTF-8"})," as locale."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose the keyboard layout from a list, use ",(0,o.jsx)(n.code,{children:"English (US)"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose and configure the primary network interface.","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Depending on the environment, the network may not work at this point. Then select any interface\nand then select ",(0,o.jsx)(n.code,{children:"Do not configure the network at this time"})," in the next step."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["Set the hostname.","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The hostname is e.g. ",(0,o.jsx)(n.code,{children:"node"})," and not a FQDN like ",(0,o.jsx)(n.code,{children:"node.systems.osism.xyz"}),"."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["Set ",(0,o.jsx)(n.code,{children:"osism"})," as full name for the new user."]}),"\n",(0,o.jsxs)(n.li,{children:["Set ",(0,o.jsx)(n.code,{children:"osism"})," as the username for the account.","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The later used operator user ",(0,o.jsx)(n.code,{children:"dragon"})," is created during the bootstrap and ",(0,o.jsx)(n.strong,{children:"should not be created"})," during the installation"]}),"\n",(0,o.jsx)(n.li,{children:"The account is only needed initially and can be deleted after completion of the bootstrap."}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.li,{children:"Set a password for the account."}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"Manual"})," as partitioning method and execute the partitioning according to company specifications","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"The use of a UEFI is recommended"}),"\n",(0,o.jsx)(n.li,{children:"The use of a RAID is recommended. We prefer the use of software RAIDs to make us less dependent on hardware.\nBut there is nothing against using hardware RAIDs."}),"\n",(0,o.jsxs)(n.li,{children:["The use of a LVM2 is recommended. ",(0,o.jsx)(n.code,{children:"system"})," is recommended as the name for the volume group."]}),"\n",(0,o.jsxs)(n.li,{children:["Dedicated disks may be provided for ",(0,o.jsx)(n.code,{children:"/var/lib/docker"})," on the controller nodes. In this case, do not\nuse an LV for ",(0,o.jsx)(n.code,{children:"/var/lib/docker"})," but the devices provided for it."]}),"\n",(0,o.jsx)(n.li,{children:"Do not configure devices that are not required for the operating system."}),"\n",(0,o.jsxs)(n.li,{children:["The use of own file systems for the following mountpoints is recommended. The size of the partitions/LVs\nis minimal. Depending on the node type, the partitions/LVs should be made larger.","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/"})," (10 GByte, logical volume ",(0,o.jsx)(n.code,{children:"root"}),")"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/home"})," (2 GByte, logical volume ",(0,o.jsx)(n.code,{children:"home"}),")"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/tmp"})," (5 GByte, logical volume ",(0,o.jsx)(n.code,{children:"tmp"}),")"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/var/lib/ceph"})," (50 GByte, logical volume ",(0,o.jsx)(n.code,{children:"ceph"}),") (optional for storage nodes)"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/var/lib/docker"})," (30 GByte, logical volume ",(0,o.jsx)(n.code,{children:"docker"}),", do not set the ",(0,o.jsx)(n.code,{children:"nosuid"})," flag on ",(0,o.jsx)(n.code,{children:"/var/lib/docker"}),")","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["When using XFS as the file system for ",(0,o.jsx)(n.code,{children:"/var/lib/docker"}),", note the following: Running on XFS without ",(0,o.jsx)(n.code,{children:"d_type"})," support\ncauses Docker to skip the attempt to use the ",(0,o.jsx)(n.code,{children:"overlay"})," or ",(0,o.jsx)(n.code,{children:"overlay2"})," driver."]}),"\n",(0,o.jsx)(n.li,{children:"100 GB should be used on a control node at the beginning."}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/var/lib/docker"})," must be extended later during operation depending on the node type. You do this\nin operation when you can see how many logs etc. are generated."]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/var/log/audit"})," (1 GByte, logical volume ",(0,o.jsx)(n.code,{children:"audit"}),")"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"/var"})," (10 GByte, logical volume ",(0,o.jsx)(n.code,{children:"var"}),")"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"swap"})," (8 GByte, logical volume ",(0,o.jsx)(n.code,{children:"swap"}),")"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"No automatic updates"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Choose ",(0,o.jsx)(n.code,{children:"OpenSSH server"})," as software to install.","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.strong,{children:"Do not install any other software component."})," Everything you need will be installed later by OSISM.\nIn particular, it is not necessary to install a desktop environment."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.li,{children:"After completion, restart the system."}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>l});var o=i(96540);const s={},t=o.createContext(s);function r(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/685813dc.efaf89c6.js b/assets/js/685813dc.efaf89c6.js new file mode 100644 index 0000000000..1ed310a388 --- /dev/null +++ b/assets/js/685813dc.efaf89c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1953],{73757:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>t,contentTitle:()=>d,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>i});var c=a(74848),r=a(28453);const o={sidebar_label:"Resource Manager",sidebar_position:52},d="Resource Manager",s={id:"iaas/components/resource-manager",title:"Resource Manager",description:"Preparations",source:"@site/docs/02-iaas/components/resource-manager.md",sourceDirName:"02-iaas/components",slug:"/iaas/components/resource-manager",permalink:"/docs/iaas/components/resource-manager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/resource-manager.md",tags:[],version:"current",sidebarPosition:52,frontMatter:{sidebar_label:"Resource Manager",sidebar_position:52}},t={},i=[{value:"Preparations",id:"preparations",level:2},{value:"Nova",id:"nova",level:2},{value:"Live migration",id:"live-migration",level:3},{value:"Evacuation",id:"evacuation",level:3},{value:"Octavia",id:"octavia",level:2},{value:"Amphora rotation",id:"amphora-rotation",level:3},{value:"Cinder",id:"cinder",level:2},{value:"Orphans",id:"orphans",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.h1,{id:"resource-manager",children:"Resource Manager"}),"\n",(0,c.jsx)(n.h2,{id:"preparations",children:"Preparations"}),"\n",(0,c.jsx)(n.p,{children:"Prepare use of the OpenStack Resource Manager."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/osism/openstack-resource-manager\ncd openstack-resource-manager\npipenv install\npipenv shell\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Prepare cloud profile ",(0,c.jsx)(n.code,{children:"admin"})," in ",(0,c.jsx)(n.code,{children:"clouds.yml"})," and ",(0,c.jsx)(n.code,{children:"secure.yml"})," (use ",(0,c.jsx)(n.code,{children:"clouds.yml.sample"})," and ",(0,c.jsx)(n.code,{children:"secure.yml.sample"}),"\nin the ",(0,c.jsx)(n.a,{href:"https://github.com/osism/openstack-resource-manager",children:"openstack-resource-manager"})," repository as sample files)."]}),"\n",(0,c.jsx)(n.h2,{id:"nova",children:"Nova"}),"\n",(0,c.jsx)(n.h3,{id:"live-migration",children:"Live migration"}),"\n",(0,c.jsxs)(n.p,{children:["Live migrate all instances from compute node ",(0,c.jsx)(n.code,{children:"SOURCE"})," to compute node ",(0,c.jsx)(n.code,{children:"TARGET"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"python3 src/host-action.py --yes --disable --action live-migrate --host SOURCE --input TARGET\n"})}),"\n",(0,c.jsx)(n.h3,{id:"evacuation",children:"Evacuation"}),"\n",(0,c.jsxs)(n.p,{children:["Evacuate all instances from compute node ",(0,c.jsx)(n.code,{children:"SOURCE"})," to compute node ",(0,c.jsx)(n.code,{children:"TARGET"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"python3 src/host-action.py --yes --action evacutate --host SOURCE --input TARGET\n"})}),"\n",(0,c.jsx)(n.h2,{id:"octavia",children:"Octavia"}),"\n",(0,c.jsx)(n.h3,{id:"amphora-rotation",children:"Amphora rotation"}),"\n",(0,c.jsx)(n.p,{children:"Rotation of amphorae older than 30 days."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"$ python3 src/amphora.py --rotate\n2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa is older than 30 days\n2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa of loadbalancer 9008d3d7-f593-4bc3-941c-a740c178148d is rotated by a loadbalancer failover\n"})}),"\n",(0,c.jsx)(n.h2,{id:"cinder",children:"Cinder"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"$ python3 src/volume.py\n2023-12-11 23:09:44 | INFO | Volume ad848454-ba1f-4c28-b9a8-edada17948b0 hangs in CREATING status for more than 2 hours\nDelete volume ad848454-ba1f-4c28-b9a8-edada17948b0 [yes/no]:\n"})}),"\n",(0,c.jsx)(n.h2,{id:"orphans",children:"Orphans"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"$ python3 src/orphan.py\n2023-12-11 23:11:16 | INFO | Checking nova / server\n2023-12-11 23:11:21 | INFO | Checking neutron / port\n2023-12-11 23:11:23 | INFO | Checking neutron / router\n2023-12-11 23:11:23 | INFO | Checking neutron / network\n2023-12-11 23:11:24 | INFO | Checking neutron / subnet\n2023-12-11 23:11:24 | INFO | Checking neutron / floatingip\n2023-12-11 23:11:24 | INFO | Checking neutron / rbacpolicy\n2023-12-11 23:11:24 | INFO | Checking neutron / securitygroup\n2023-12-11 23:11:26 | INFO | Checking neutron / securitygrouprule\n2023-12-11 23:11:27 | INFO | Checking glance / image\n2023-12-11 23:11:30 | INFO | Checking glance / imagemember\n[...]\n+---------------+-------------------+--------------------------------------+----------------------------------+\n| servicename | resourcename | resource_id | project_id |\n|---------------+-------------------+--------------------------------------+----------------------------------|\n| neutron | port | 561f8f76-18b0-470a-92cd-4336346b4b18 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | port | 6d1986e4-1e6d-4d4a-961d-97d372945bb1 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | port | 74f9bddc-9bfa-4d06-a147-ca87127e501e | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | port | f630a66b-7725-4a68-868b-caebbaf1c003 | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | router | c0c4e4aa-53ee-4fd1-8f53-84d52cf6c60b | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | router | c8f9a13b-adcd-4a8e-942b-338bcf4dde7c | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | network | 62d6ad2a-0cda-4d45-9325-963b8eb67000 | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | network | 63b8fea6-7d7b-40c3-9c31-bee4404a92d6 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | subnet | 0cd16262-330a-44ad-9160-daef84aded2d | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | subnet | 690dee14-ac12-464d-a911-a873c27ec818 | d33b0d15fd474131a335207216297a2a |\n| neutron | subnet | 854e7c55-62e2-4679-9b18-805460b998ce | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | rbacpolicy | 00d7c2a2-6674-4f40-9f95-176a7858fcca | c8e4393b6d064a26a31014f82939172f |\n| neutron | rbacpolicy | 0608c701-5b81-4712-989b-ba03cdcc255d | c8e4393b6d064a26a31014f82939172f |\n[...]\n| neutron | securitygrouprule | fd3c553f-168e-4c24-ab40-09aa934bab86 | 3a96207b719643ae9ea9a81d95116e9e |\n| neutron | securitygrouprule | fdf337be-971c-4d5d-88ca-d90cdb468e88 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | securitygrouprule | ff8162fe-f053-49c9-8659-078061ce3e23 | d0b0add9ede0452791f71cb900e35242 |\n| glance | imagemember | c7f2cb0c25d34c5d886ecaf483e5fda6 | c7f2cb0c25d34c5d886ecaf483e5fda6 |\n| glance | imagemember | d4d0a161f9024fc8b517b0375eb97c89 | d4d0a161f9024fc8b517b0375eb97c89 |\n| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |\n| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |\n| glance | imagemember | d33b0d15fd474131a335207216297a2a | d33b0d15fd474131a335207216297a2a |\n| cinder | volume | e7c4b05c-b76a-40cc-8381-03262e57eb94 | 9b5f7f8ed70d410c81e3f45bf4e36498 |\n+---------------+-------------------+--------------------------------------+----------------------------------+\n"})})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>s});var c=a(96540);const r={},o=c.createContext(r);function d(e){const n=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),c.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6875c492.fbd1a093.js b/assets/js/6875c492.fbd1a093.js new file mode 100644 index 0000000000..a361a5a5d7 --- /dev/null +++ b/assets/js/6875c492.fbd1a093.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4813],{47713:(e,t,n)=>{n.d(t,{A:()=>l});n(96540);var s=n(21312),a=n(39022),i=n(74848);function l(e){const{metadata:t}=e,{previousPage:n,nextPage:l}=t;return(0,i.jsxs)("nav",{className:"pagination-nav","aria-label":(0,s.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[n&&(0,i.jsx)(a.A,{permalink:n,title:(0,i.jsx)(s.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer Entries"})}),l&&(0,i.jsx)(a.A,{permalink:l,title:(0,i.jsx)(s.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older Entries"}),isNext:!0})]})}},33892:(e,t,n)=>{n.d(t,{A:()=>l});n(96540);var s=n(7131),a=n(24651),i=n(74848);function l(e){let{items:t,component:n=a.A}=e;return(0,i.jsx)(i.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,i.jsx)(s.i,{content:t,children:(0,i.jsx)(n,{children:(0,i.jsx)(t,{})})},t.metadata.permalink)}))})}},33069:(e,t,n)=>{n.r(t),n.d(t,{default:()=>A});n(96540);var s=n(18215),a=n(21312),i=n(53465),l=n(61213),r=n(17559),o=n(28774),c=n(26535),d=n(47713),g=n(41463),u=n(33892),h=n(50996),p=n(51107),m=n(74848);function x(e){const t=function(){const{selectMessage:e}=(0,i.W)();return t=>e(t,(0,a.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}();return(0,a.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}function j(e){let{tag:t}=e;const n=x(t);return(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(l.be,{title:n}),(0,m.jsx)(g.A,{tag:"blog_tags_posts"})]})}function b(e){let{tag:t,items:n,sidebar:s,listMetadata:i}=e;const l=x(t);return(0,m.jsxs)(c.A,{sidebar:s,children:[t.unlisted&&(0,m.jsx)(h.A,{}),(0,m.jsxs)("header",{className:"margin-bottom--xl",children:[(0,m.jsx)(p.A,{as:"h1",children:l}),(0,m.jsx)(o.A,{href:t.allTagsPath,children:(0,m.jsx)(a.A,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page",children:"View All Tags"})})]}),(0,m.jsx)(u.A,{items:n}),(0,m.jsx)(d.A,{metadata:i})]})}function A(e){return(0,m.jsxs)(l.e3,{className:(0,s.A)(r.G.wrapper.blogPages,r.G.page.blogTagPostListPage),children:[(0,m.jsx)(j,{...e}),(0,m.jsx)(b,{...e})]})}},50996:(e,t,n)=>{n.d(t,{A:()=>h});n(96540);var s=n(18215),a=n(21312),i=n(5260),l=n(74848);function r(){return(0,l.jsx)(a.A,{id:"theme.unlistedContent.title",description:"The unlisted content banner title",children:"Unlisted page"})}function o(){return(0,l.jsx)(a.A,{id:"theme.unlistedContent.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,l.jsx)(i.A,{children:(0,l.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}var d=n(17559),g=n(27293);function u(e){let{className:t}=e;return(0,l.jsx)(g.A,{type:"caution",title:(0,l.jsx)(r,{}),className:(0,s.A)(t,d.G.common.unlistedBanner),children:(0,l.jsx)(o,{})})}function h(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c,{}),(0,l.jsx)(u,{...e})]})}}}]); \ No newline at end of file diff --git a/assets/js/688.54506875.js b/assets/js/688.54506875.js new file mode 100644 index 0000000000..5c8139885f --- /dev/null +++ b/assets/js/688.54506875.js @@ -0,0 +1,26093 @@ +"use strict"; +exports.id = 688; +exports.ids = [688]; +exports.modules = { + +/***/ 21176: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Zp: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(5664); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(74722); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(91395); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(697); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.A(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.A( + map/* default */.A(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.A(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.A(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.T(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.A(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.A(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.A(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.A(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.A(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.A('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.A(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.A(g.outEdges(v), function (e) { + if (has/* default */.A(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.A(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.A(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(98879); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(81942); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(23068); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.A)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(52528); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.A)(iteratee, 3); + + (0,_baseForOwn/* default */.A)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.A)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(41917); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.A.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.A(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.T().setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.T({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.A(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.A(range/* default */.A(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.A(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.A(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.A(layers, function (vs, i) { + if (isUndefined/* default */.A(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.A(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.A(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.A(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.A(children, dfs); + } + + if (has/* default */.A(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.A(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.A(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, reverseYOne); + if (has/* default */.A(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, swapXYOne); + if (has/* default */.A(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.A(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.A)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.A(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.A(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.A(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.T({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.A(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.A(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.A(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.A)(collection)) { + var iteratee = (0,_baseIteratee/* default */.A)(predicate, 3); + collection = (0,keys/* default */.A)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.A)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.A)(array, (0,_baseIteratee/* default */.A)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(69471); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(88496); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.A)(value) && (0,isObjectLike/* default */.A)(value) && (0,_baseGetTag/* default */.A)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.A)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.A)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.A)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.A)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.A(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.A(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.A(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.A(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.A(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.A(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.A(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.A(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(73046); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.A(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.A(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.A(tree.neighbors(v), function (w) { + if (!has/* default */.A(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.A(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.A(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.A(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.A(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.A(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.A(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.A(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.A(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.A( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(91641); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.A)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.A(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.T({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.A(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.A(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.A(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.A('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.A); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(52568); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.A)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.A)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + if ((0,isArray/* default */.A)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.A)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.A]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.A)(iteratees, (0,_baseUnary/* default */.A)(_baseIteratee/* default */.A)); + + var result = (0,_baseMap/* default */.A)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.A)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.A)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.A)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.A)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.A(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.A( + map/* default */.A(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.A(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.A(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.A( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.A(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.A(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.A(range/* default */.A(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.A(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.A(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.A(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.A(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.A( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.A(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.A(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.A(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.A(entryV) && !isUndefined/* default */.A(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.A(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.A(uEntry.barycenter) || + isUndefined/* default */.A(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.A(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.A(entry.out, handleOut(entry)); + } + + return map/* default */.A( + filter/* default */.A(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.A(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.A(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.A(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.A(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.A(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.A(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.A(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.A([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.A(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.A(entries, function (entry) { + entry.vs = flatten/* default */.A( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.A(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.A(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.A(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.A(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.T(); + forEach/* default */.A(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.A(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.A(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.A(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(99922); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(4574); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee), keysIn/* default */.A); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.A(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.A(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.A(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.A(range/* default */.A(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.A(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.A(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.A(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.A(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.A(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.A(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.T(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.A(layering, function (layer) { + var u; + forEach/* default */.A(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.A(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.A(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.A(['u', 'd'], function (vert) { + forEach/* default */.A(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.A(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.A(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.A(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.A(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.A(layering).reverse(); + forEach/* default */.A(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.A(adjustedLayering, function (inner) { + return values/* default */.A(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.A(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.A(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.A(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.A(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.A(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.A(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.A(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.T({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.A({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.A(graph, graphAttrs)) + ); + + forEach/* default */.A(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.A(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.A({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.A(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.A(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.A(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.A(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.A(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.A(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.A(layers, function (layer) { + var orderShift = 0; + forEach/* default */.A(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.A(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.A(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.A(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 73046: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + T: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(89610); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(66401); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.A)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(39857); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.A && (1 / (0,_setToArray/* default */.A)(new _Set/* default */.A([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.A(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.A)(set); + } + isCommon = false; + includes = _cacheHas/* default */.A; + seen = new _SetCache/* default */.A; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(53533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.A)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.A)(arrays, 1, isArrayLikeObject/* default */.A, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.A(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.A(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.A(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.A(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.A(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.A(this._nodes); + } + sources() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.A(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.A(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.A(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.A(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.A(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.A(keys/* default */.A(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.A(keys/* default */.A(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.A(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.A(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.A(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.A(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.A(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.A(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.A(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.A(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.A(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.A(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.A(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.A(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.A(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.A(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.A(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.A(inV); + if (!u) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.A(outV); + if (!w) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.A(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 697: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ T: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.T) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 14075: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ M: () => (/* binding */ write) +/* harmony export */ }); +/* unused harmony export read */ +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69592); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(50053); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74722); +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); + + + + + +function write(g) { + var json = { + options: { + directed: g.isDirected(), + multigraph: g.isMultigraph(), + compound: g.isCompound(), + }, + nodes: writeNodes(g), + edges: writeEdges(g), + }; + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(g.graph())) { + json.value = lodash_es__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A(g.graph()); + } + return json; +} + +function writeNodes(g) { + return lodash_es__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A(g.nodes(), function (v) { + var nodeValue = g.node(v); + var parent = g.parent(v); + var node = { v: v }; + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(nodeValue)) { + node.value = nodeValue; + } + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(parent)) { + node.parent = parent; + } + return node; + }); +} + +function writeEdges(g) { + return lodash_es__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A(g.edges(), function (e) { + var edgeValue = g.edge(e); + var edge = { v: e.v, w: e.w }; + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(e.name)) { + edge.name = e.name; + } + if (!lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A(edgeValue)) { + edge.value = edgeValue; + } + return edge; + }); +} + +function read(json) { + var g = new Graph(json.options).setGraph(json.value); + _.each(json.nodes, function (entry) { + g.setNode(entry.v, entry.value); + if (entry.parent) { + g.setParent(entry.v, entry.parent); + } + }); + _.each(json.edges, function (entry) { + g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value); + }); + return g; +} + + +/***/ }), + +/***/ 62062: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(29471); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.A; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 72641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 2634: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 45572: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 76912: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 91641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(72641); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(22031); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keys/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keysIn/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(80154); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(39759); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(14792); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.A)(source, (0,_getSymbols/* default */.A)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(15647); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(13153); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.A : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.A)(result, (0,_getSymbols/* default */.A)(object)); + object = (0,_getPrototype/* default */.A)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.A)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(33831); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.A)(object, keysIn/* default */.A, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(90565); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.A)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(1801); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.A)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.A)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(18598); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(64841); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.A)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.A)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.A)(value)) { + return value; + } + var isArr = (0,isArray/* default */.A)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.A)(value, result); + } + } else { + var tag = (0,_getTag/* default */.A)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.A)(value)) { + return (0,_cloneBuffer/* default */.A)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.A)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.A); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.A) + : (isFlat ? keysIn/* default */.A : keys/* default */.A); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.A)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.A)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 6240: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.A)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.A); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 25707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 13588: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(52274); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.A ? _Symbol/* default */.A.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.A)(value) || (0,isArguments/* default */.A)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.A)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 79841: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4574); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 66318: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 33831: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76912); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 49574: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.A : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.A)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(43988); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(66984); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.A(object), new _Uint8Array/* default */.A(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.A)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.A); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.A)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.A)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(33858); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.A)(object), + othIsArr = (0,isArray/* default */.A)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.A)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.A)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.A)(object)) { + if (!(0,isBuffer/* default */.A)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.A); + return (objIsArr || (0,isTypedArray/* default */.A)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.A); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.A); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.A)(value) && !(0,isObjectLike/* default */.A)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.A; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.A)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.A)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.A)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.A)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.A)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.A)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.A)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.A)(path) ? (0,_baseProperty/* default */.A)((0,_toKey/* default */.A)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.A; + } + if (typeof value == 'object') { + return (0,isArray/* default */.A)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 52568: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6240); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 70805: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 64099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 99922: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(29008); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 7819: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(46632); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.A)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(28894); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.A)(value)) { + return value; + } + return (0,_isKey/* default */.A)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.A)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 19042: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33831); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14792); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 14792: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2634); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13153); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 85054: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(52274); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(92049); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25353); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5254); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 86586: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(61882); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 29959: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 30901: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61882); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 50053: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseClone_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(91641); + + +/** Used to compose bitmasks for cloning. */ +var CLONE_SYMBOLS_FLAG = 4; + +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return (0,_baseClone_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value, CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (clone); + + +/***/ }), + +/***/ 23068: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(24326); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66984); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6832); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55615); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 11662: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(2634); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.A)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.A)(collection) ? _arrayFilter/* default */.A : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.A)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 34098: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13588); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 8058: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72641); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6240); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99922); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 48585: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 39188: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 61882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(88496); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(53098); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 69592: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 27422: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(83607); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69471); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 74722: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(45572); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49574); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(52568); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 81942: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(7819); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(25353); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.A)(object)) { + return object; + } + path = (0,_castPath/* default */.A)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.A)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.A)(objValue) + ? objValue + : ((0,_isIndex/* default */.A)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.A)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.A)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.A)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.A)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(76875); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(67525); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.A)((0,_overRest/* default */.A)(func, undefined, flatten/* default */.A), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 91395: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.A)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.A)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.A)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.A)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 89463: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.A)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.A)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.A); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 13153: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 74342: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.A)(value)) { + return NAN; + } + if ((0,isObject/* default */.A)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.A)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 28894: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.A)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.A)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.A)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 5664: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28894); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 38207: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.A)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.A)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 40351: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-f47111a7.js + 8 modules +var mermaid_f47111a7 = __webpack_require__(76257); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array<unknown>} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array<string>} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array<T>} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array<unknown>} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {Array<T>} items + * Items to add to `list`. + * @returns {Array<T>} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array<Extension>} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record<string, unknown>} */ + const left = maybe || (all[hook] = {}) + /** @type {Record<string, unknown> | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array<unknown>} existing + * @param {Array<unknown>} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array<unknown>} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array<HtmlExtension>} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array<StackItem>} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array<Event>} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record<string, number>} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array<Event>} */ + let parameters + /** @type {Array<Event>} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array<Event>} events + * @param {number} eventIndex + * @returns {Record<string, number>} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array<number>} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record<string, number>} */ + const gaps = {} + /** @type {Array<Chunk>} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array<Event>} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array<Event>} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array<Resolver>} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit<Point, '_bufferIndex' | '_index'> | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record<string, number>} */ + const columnStart = {} + /** @type {Array<Construct>} */ + const resolveAllConstructs = [] + /** @type {Array<Chunk>} */ + let chunks = [] + /** @type {Array<Token>} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array<Construct> | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array<Construct>} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array<Construct>} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array<Chunk>} chunks + * @param {Pick<Token, 'end' | 'start'>} token + * @returns {Array<Chunk>} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array<Chunk>} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array<Chunk>} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array<string>} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * <a> + * <a\>b> + * <a b> + * <a)> + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`<a>` or `b`). + * @param {TokenType} literalType + * Type when enclosed (`<a>`). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | <aa> + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | <a\*a> + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | <x /> + * ^ + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<!-`, inside a comment, at another `-`. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<![`, inside CDATA, expecting `CDATA[`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | </x> + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | <ab> + * ^^ + * > | </ab> + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > | <div/> + * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | <x/> + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | <a /> + * ^ + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * > | <a > + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | <a b> + * ^ + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | <a b=c> + * ^ + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | <a b="c"> + * ^ + * > | <a b='c'> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | <x> + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | <x> + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after `</`, in a raw tag name. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | <!--> + * ^ + * > | <?> + * ^ + * > | <!q> + * ^ + * > | <!--ab--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > | <div> + * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record<string, string>} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array<Event>} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + * <p>!<a href=\"b\">^a</a></p> + * <p>!<a href=\"c\">^a</a></p> + * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array<Event>} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | a<user.name@ex-ample.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code> | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a <b> c + * ^ + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * > | a <![CDATA[>&<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after `<!-`, at another `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After `<![`, in CDATA, expecting `CDATA[`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a <!b> c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After `</x`, in a tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After `<x`, in opening tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a <!--a + * ^ + * | b--> + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array<Chunk>} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array<Chunk>} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array<Event>} events + * @returns {Array<Event>} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract<Node, UnistParent>} Parent + * + * @typedef {Omit<UnistParent, 'type' | 'children'> & {type: 'fragment', children: Array<PhrasingContent>}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record<string, Handle>} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array<string>} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array<Transform>} transforms + * Tree transforms. + * + * @typedef {Partial<Config>} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array<Node | Fragment>} stack + * Stack of nodes. + * @property {Array<TokenTuple>} tokenStack + * Stack of tokens. + * @property {<Key extends keyof CompileData>(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {<Key extends keyof CompileData>(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {<Kind extends Node>(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array<Extension | Array<Extension>> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array<Event>} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit<CompileContext, 'sliceSerialize'>} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array<number>} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array<Event>} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array<StaticPhrasingContent>} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array<Extension | Array<Extension>>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(60513); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-6b48ae7d.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.T)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "<br/>"); + } else if (node.type === "strong") { + return `<strong>${node.children.map(output).join("")}</strong>`; + } else if (node.type === "emphasis") { + return `<em>${node.children.map(output).join("")}</em>`; + } else if (node.type === "paragraph") { + return `<p>${node.children.map(output).join("")}</p>`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + <span class="${labelClass} ${classes}" ` + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_f47111a7.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_f47111a7.M)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `<i class='${s.replace(":", " ")}'></i>` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 28747: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ insertMarkers$1), +/* harmony export */ b: () => (/* binding */ clear$1), +/* harmony export */ c: () => (/* binding */ createLabel$1), +/* harmony export */ d: () => (/* binding */ clear), +/* harmony export */ e: () => (/* binding */ insertNode), +/* harmony export */ f: () => (/* binding */ insertEdgeLabel), +/* harmony export */ g: () => (/* binding */ getSubGraphTitleMargins), +/* harmony export */ h: () => (/* binding */ insertEdge), +/* harmony export */ i: () => (/* binding */ intersectRect$1), +/* harmony export */ j: () => (/* binding */ positionEdgeLabel), +/* harmony export */ k: () => (/* binding */ getLineFunctionsWithOffset), +/* harmony export */ l: () => (/* binding */ labelHelper), +/* harmony export */ m: () => (/* binding */ addEdgeMarkers), +/* harmony export */ p: () => (/* binding */ positionNode), +/* harmony export */ s: () => (/* binding */ setNodeElem), +/* harmony export */ u: () => (/* binding */ updateNodeBounds) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(40351); + + + +const insertMarkers = (elem, markerArray, type, id) => { + markerArray.forEach((markerName) => { + markers[markerName](elem, type, id); + }); +}; +const extension = (elem, type, id) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Making markers for ", id); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); +}; +const composition = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const aggregation = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const dependency = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 6).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const lollipop = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopEnd").attr("class", "marker lollipop " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); +}; +const point = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 6).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 4.5).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const circle$1 = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const cross = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); +}; +const barb = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const markers = { + extension, + composition, + aggregation, + dependency, + lollipop, + point, + circle: circle$1, + cross, + barb +}; +const insertMarkers$1 = insertMarkers; +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlLabel(node) { + const fo = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + '<span class="' + labelClass + '" ' + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>" + ); + applyStyle(div, node.labelStyle); + div.style("display", "inline-block"); + div.style("white-space", "nowrap"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + return fo.node(); +} +const createLabel = (_vertexText, style, isTitle, isNode) => { + let vertexText = _vertexText || ""; + if (typeof vertexText === "object") { + vertexText = vertexText[0]; + } + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + vertexText = vertexText.replace(/\\n|\n/g, "<br />"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("vertexText" + vertexText); + const node = { + isNode, + label: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(vertexText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `<i class='${s.replace(":", " ")}'></i>` + ), + labelStyle: style.replace("fill:", "color:") + }; + let vertexNode = addHtmlLabel(node); + return vertexNode; + } else { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", style.replace("color:", "fill:")); + let rows = []; + if (typeof vertexText === "string") { + rows = vertexText.split(/\\n|\n|<br\s*\/?>/gi); + } else if (Array.isArray(vertexText)) { + rows = vertexText; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + if (isTitle) { + tspan.setAttribute("class", "title-row"); + } else { + tspan.setAttribute("class", "row"); + } + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; + } +}; +const createLabel$1 = createLabel; +const labelHelper = async (parent, node, _classes, isNode) => { + let classes; + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + if (!_classes) { + classes = "node default"; + } else { + classes = _classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle); + let labelText; + if (node.labelText === void 0) { + labelText = ""; + } else { + labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0]; + } + const textNode = label.node(); + let text; + if (node.labelType === "markdown") { + text = (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__.a)(label, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(labelText), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()), { + useHtmlLabels, + width: node.width || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.wrappingWidth, + classes: "markdown-node-label" + }); + } else { + text = textNode.appendChild( + createLabel$1( + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.M)(labelText), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()), + node.labelStyle, + false, + isNode + ) + ); + } + let bbox = text.getBBox(); + const halfPadding = node.padding / 2; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text); + const images = div.getElementsByTagName("img"); + if (images) { + const noImgText = labelText.replace(/<img[^>]*>/g, "").trim() === ""; + await Promise.all( + [...images].map( + (img) => new Promise((res) => { + function setupImage() { + img.style.display = "flex"; + img.style.flexDirection = "column"; + if (noImgText) { + const bodyFontSize = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize ? (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize : window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + const width = parseInt(bodyFontSize, 10) * enlargingFactor + "px"; + img.style.minWidth = width; + img.style.maxWidth = width; + } else { + img.style.width = "100%"; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener("error", setupImage); + img.addEventListener("load", setupImage); + }) + ) + ); + } + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (useHtmlLabels) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } else { + label.attr("transform", "translate(0, " + -bbox.height / 2 + ")"); + } + if (node.centerLabel) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } + label.insert("rect", ":first-child"); + return { shapeSvg, bbox, halfPadding, label }; +}; +const updateNodeBounds = (node, element) => { + const bbox = element.node().getBBox(); + node.width = bbox.width; + node.height = bbox.height; +}; +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +function intersectNode(node, point2) { + return node.intersect(point2); +} +function intersectEllipse(node, rx, ry, point2) { + var cx = node.x; + var cy = node.y; + var px = cx - point2.x; + var py = cy - point2.y; + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + var dx = Math.abs(rx * ry * px / det); + if (point2.x < cx) { + dx = -dx; + } + var dy = Math.abs(rx * ry * py / det); + if (point2.y < cy) { + dy = -dy; + } + return { x: cx + dx, y: cy + dy }; +} +function intersectCircle(node, rx, point2) { + return intersectEllipse(node, rx, rx, point2); +} +function intersectLine(p1, p2, q1, q2) { + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return; + } + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return; + } + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return; + } + offset = Math.abs(denom / 2); + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + return { x, y }; +} +function sameSign(r1, r2) { + return r1 * r2 > 0; +} +function intersectPolygon(node, polyPoints, point2) { + var x1 = node.x; + var y1 = node.y; + var intersections = []; + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + if (typeof polyPoints.forEach === "function") { + polyPoints.forEach(function(entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + } else { + minX = Math.min(minX, polyPoints.x); + minY = Math.min(minY, polyPoints.y); + } + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect2 = intersectLine( + node, + point2, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect2) { + intersections.push(intersect2); + } + } + if (!intersections.length) { + return node; + } + if (intersections.length > 1) { + intersections.sort(function(p, q) { + var pdx = p.x - point2.x; + var pdy = p.y - point2.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + var qdx = q.x - point2.x; + var qdy = q.y - point2.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} +const intersectRect = (node, point2) => { + var x = node.x; + var y = node.y; + var dx = point2.x - x; + var dy = point2.y - y; + var w = node.width / 2; + var h = node.height / 2; + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : h * dx / dy; + sy = h; + } else { + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : w * dy / dx; + } + return { x: x + sx, y: y + sy }; +}; +const intersectRect$1 = intersectRect; +const intersect = { + node: intersectNode, + circle: intersectCircle, + ellipse: intersectEllipse, + polygon: intersectPolygon, + rect: intersectRect$1 +}; +const note = async (parent, node) => { + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels; + if (!useHtmlLabels) { + node.centerLabel = true; + } + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Classes = ", node.classes); + const rect2 = shapeSvg.insert("rect", ":first-child"); + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const note$1 = note; +const expandAndDeduplicateDirections = (directions) => { + const uniqueDirections = /* @__PURE__ */ new Set(); + for (const direction of directions) { + switch (direction) { + case "x": + uniqueDirections.add("right"); + uniqueDirections.add("left"); + break; + case "y": + uniqueDirections.add("up"); + uniqueDirections.add("down"); + break; + default: + uniqueDirections.add(direction); + break; + } + } + return uniqueDirections; +}; +const getArrowPoints = (duplicatedDirections, bbox, node) => { + const directions = expandAndDeduplicateDirections(duplicatedDirections); + const f = 2; + const height = bbox.height + 2 * node.padding; + const midpoint = height / f; + const width = bbox.width + 2 * midpoint + node.padding; + const padding = node.padding / 2; + if (directions.has("right") && directions.has("left") && directions.has("up") && directions.has("down")) { + return [ + // Bottom + { x: 0, y: 0 }, + { x: midpoint, y: 0 }, + { x: width / 2, y: 2 * padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: 0 }, + // Right + { x: width, y: -height / 3 }, + { x: width + 2 * padding, y: -height / 2 }, + { x: width, y: -2 * height / 3 }, + { x: width, y: -height }, + // Top + { x: width - midpoint, y: -height }, + { x: width / 2, y: -height - 2 * padding }, + { x: midpoint, y: -height }, + // Left + { x: 0, y: -height }, + { x: 0, y: -2 * height / 3 }, + { x: -2 * padding, y: -height / 2 }, + { x: 0, y: -height / 3 } + ]; + } + if (directions.has("right") && directions.has("left") && directions.has("up")) { + return [ + { x: midpoint, y: 0 }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("right") && directions.has("left") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: midpoint, y: -height }, + { x: width - midpoint, y: -height }, + { x: width, y: 0 } + ]; + } + if (directions.has("right") && directions.has("up") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: width, y: -midpoint }, + { x: width, y: -height + midpoint }, + { x: 0, y: -height } + ]; + } + if (directions.has("left") && directions.has("up") && directions.has("down")) { + return [ + { x: width, y: 0 }, + { x: 0, y: -midpoint }, + { x: 0, y: -height + midpoint }, + { x: width, y: -height } + ]; + } + if (directions.has("right") && directions.has("left")) { + return [ + { x: midpoint, y: 0 }, + { x: midpoint, y: -padding }, + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: width - midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("up") && directions.has("down")) { + return [ + // Bottom center + { x: width / 2, y: 0 }, + // Left pont of bottom arrow + { x: 0, y: -padding }, + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: 0, y: -height + padding }, + // Top of arrow + { x: width / 2, y: -height }, + { x: width, y: -height + padding }, + // Top of right vertical bar + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding }, + { x: width, y: -padding } + ]; + } + if (directions.has("right") && directions.has("up")) { + return [ + { x: 0, y: 0 }, + { x: width, y: -midpoint }, + { x: 0, y: -height } + ]; + } + if (directions.has("right") && directions.has("down")) { + return [ + { x: 0, y: 0 }, + { x: width, y: 0 }, + { x: 0, y: -height } + ]; + } + if (directions.has("left") && directions.has("up")) { + return [ + { x: width, y: 0 }, + { x: 0, y: -midpoint }, + { x: width, y: -height } + ]; + } + if (directions.has("left") && directions.has("down")) { + return [ + { x: width, y: 0 }, + { x: 0, y: 0 }, + { x: width, y: -height } + ]; + } + if (directions.has("right")) { + return [ + { x: midpoint, y: -padding }, + { x: midpoint, y: -padding }, + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: 0 }, + { x: width, y: -height / 2 }, + { x: width - midpoint, y: -height }, + { x: width - midpoint, y: -height + padding }, + // top left corner of arrow + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding } + ]; + } + if (directions.has("left")) { + return [ + { x: midpoint, y: 0 }, + { x: midpoint, y: -padding }, + // Two points, the right corners + { x: width - midpoint, y: -padding }, + { x: width - midpoint, y: -height + padding }, + { x: midpoint, y: -height + padding }, + { x: midpoint, y: -height }, + { x: 0, y: -height / 2 } + ]; + } + if (directions.has("up")) { + return [ + // Bottom center + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: 0, y: -height + padding }, + // Top of arrow + { x: width / 2, y: -height }, + { x: width, y: -height + padding }, + // Top of right vertical bar + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding } + ]; + } + if (directions.has("down")) { + return [ + // Bottom center + { x: width / 2, y: 0 }, + // Left pont of bottom arrow + { x: 0, y: -padding }, + { x: midpoint, y: -padding }, + // Left top over vertical section + { x: midpoint, y: -height + padding }, + { x: width - midpoint, y: -height + padding }, + { x: width - midpoint, y: -padding }, + { x: width, y: -padding } + ]; + } + return [{ x: 0, y: 0 }]; +}; +const formatClass = (str) => { + if (str) { + return " " + str; + } + return ""; +}; +const getClassesFromNode = (node, otherClasses) => { + return `${otherClasses ? otherClasses : "node default"}${formatClass(node.classes)} ${formatClass( + node.class + )}`; +}; +const question = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const s = w + h; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Question main (Circle)"); + const questionElem = insertPolygonShape(shapeSvg, s, s, points); + questionElem.attr("style", node.style); + updateNodeBounds(node, questionElem); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("Intersect called"); + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const choice = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const s = 28; + const points = [ + { x: 0, y: s / 2 }, + { x: s / 2, y: 0 }, + { x: 0, y: -s / 2 }, + { x: -s / 2, y: 0 } + ]; + const choice2 = shapeSvg.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ); + choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28); + node.width = 28; + node.height = 28; + node.intersect = function(point2) { + return intersect.circle(node, 14, point2); + }; + return shapeSvg; +}; +const hexagon = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const f = 4; + const h = bbox.height + node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const hex = insertPolygonShape(shapeSvg, w, h, points); + hex.attr("style", node.style); + updateNodeBounds(node, hex); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const block_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true); + const f = 2; + const h = bbox.height + 2 * node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = getArrowPoints(node.directions, bbox, node); + const blockArrow = insertPolygonShape(shapeSvg, w, h, points); + blockArrow.attr("style", node.style); + updateNodeBounds(node, blockArrow); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_left_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + node.width = w + h; + node.height = h; + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_right = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_left = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const inv_trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_right_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const cylinder = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry + node.padding; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const el = shapeSvg.attr("label-offset-y", ry).insert("path", ":first-child").attr("style", node.style).attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + updateNodeBounds(node, el); + node.intersect = function(point2) { + const pos = intersect.rect(node, point2); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point2.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +}; +const rect = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes + " " + node.class, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding; + const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding; + rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const composite = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = node.positioned ? node.width : bbox.width + node.padding; + const totalHeight = node.positioned ? node.height : bbox.height + node.padding; + const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding; + const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding; + rect2.attr("class", "basic cluster composite label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", x).attr("y", y).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const labelRect = async (parent, node) => { + const { shapeSvg } = await labelHelper(parent, node, "label", true); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Classes = ", node.class); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = 0; + const totalHeight = 0; + rect2.attr("width", totalWidth).attr("height", totalHeight); + shapeSvg.attr("class", "label edgeLabel"); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) { + const strokeDashArray = []; + const addBorder = (length) => { + strokeDashArray.push(length, 0); + }; + const skipBorder = (length) => { + strokeDashArray.push(0, length); + }; + if (borders.includes("t")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add top border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("r")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add right border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + if (borders.includes("b")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add bottom border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("l")) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add left border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + rect2.attr("stroke-dasharray", strokeDashArray.join(" ")); +} +const rectWithTitle = (parent, node) => { + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const innerLine = shapeSvg.insert("line"); + const label = shapeSvg.insert("g").attr("class", "label"); + const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText; + let title = ""; + if (typeof text2 === "object") { + title = text2[0]; + } else { + title = text2; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Label text abc79", title, text2, typeof text2 === "object"); + const text = label.node().appendChild(createLabel$1(title, node.labelStyle, true, true)); + let bbox = { width: 0, height: 0 }; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Text 2", text2); + const textRows = text2.slice(1, text2.length); + let titleBox = text.getBBox(); + const descr = label.node().appendChild( + createLabel$1(textRows.join ? textRows.join("<br/>") : textRows, node.labelStyle, true, true) + ); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = descr.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(descr); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const halfPadding = node.padding / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(descr).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")" + ); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(text).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)" + ); + bbox = label.node().getBBox(); + label.attr( + "transform", + "translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")" + ); + rect2.attr("class", "outer title-state").attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + innerLine.attr("class", "divider").attr("x1", -bbox.width / 2 - halfPadding).attr("x2", bbox.width / 2 + halfPadding).attr("y1", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr("y2", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const stadium = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const h = bbox.height + node.padding; + const w = bbox.width + h / 4 + node.padding; + const rect2 = shapeSvg.insert("rect", ":first-child").attr("style", node.style).attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const circle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle main"); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle intersect", node, bbox.width / 2 + halfPadding, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding, point2); + }; + return shapeSvg; +}; +const doublecircle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const gap = 5; + const circleGroup = shapeSvg.insert("g", ":first-child"); + const outerCircle = circleGroup.insert("circle"); + const innerCircle = circleGroup.insert("circle"); + circleGroup.attr("class", node.class); + outerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding + gap).attr("width", bbox.width + node.padding + gap * 2).attr("height", bbox.height + node.padding + gap * 2); + innerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle main"); + updateNodeBounds(node, outerCircle); + node.intersect = function(point2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point2); + }; + return shapeSvg; +}; +const subroutine = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const start = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const forkJoin = (parent, node, dir) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + let width = 70; + let height = 10; + if (dir === "LR") { + width = 10; + height = 70; + } + const shape = shapeSvg.append("rect").attr("x", -1 * width / 2).attr("y", -1 * height / 2).attr("width", width).attr("height", height).attr("class", "fork-join"); + updateNodeBounds(node, shape); + node.height = node.height + node.padding / 2; + node.width = node.width + node.padding / 2; + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const end = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const innerCircle = shapeSvg.insert("circle", ":first-child"); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const class_box = (parent, node) => { + const halfPadding = node.padding / 2; + const rowPadding = 4; + const lineHeight = 8; + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const topLine = shapeSvg.insert("line"); + const bottomLine = shapeSvg.insert("line"); + let maxWidth = 0; + let maxHeight = rowPadding; + const labelContainer = shapeSvg.insert("g").attr("class", "label"); + let verticalPos = 0; + const hasInterface = node.classData.annotations && node.classData.annotations[0]; + const interfaceLabelText = node.classData.annotations[0] ? "«" + node.classData.annotations[0] + "»" : ""; + const interfaceLabel = labelContainer.node().appendChild(createLabel$1(interfaceLabelText, node.labelStyle, true, true)); + let interfaceBBox = interfaceLabel.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = interfaceLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(interfaceLabel); + interfaceBBox = div.getBoundingClientRect(); + dv.attr("width", interfaceBBox.width); + dv.attr("height", interfaceBBox.height); + } + if (node.classData.annotations[0]) { + maxHeight += interfaceBBox.height + rowPadding; + maxWidth += interfaceBBox.width; + } + let classTitleString = node.classData.label; + if (node.classData.type !== void 0 && node.classData.type !== "") { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + classTitleString += "<" + node.classData.type + ">"; + } else { + classTitleString += "<" + node.classData.type + ">"; + } + } + const classTitleLabel = labelContainer.node().appendChild(createLabel$1(classTitleString, node.labelStyle, true, true)); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel).attr("class", "classTitle"); + let classTitleBBox = classTitleLabel.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = classTitleLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel); + classTitleBBox = div.getBoundingClientRect(); + dv.attr("width", classTitleBBox.width); + dv.attr("height", classTitleBBox.height); + } + maxHeight += classTitleBBox.height + rowPadding; + if (classTitleBBox.width > maxWidth) { + maxWidth = classTitleBBox.width; + } + const classAttributes = []; + node.classData.members.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let parsedText = parsedInfo.displayText; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + parsedText = parsedText.replace(/</g, "<").replace(/>/g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + parsedText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classAttributes.push(lbl); + }); + maxHeight += lineHeight; + const classMethods = []; + node.classData.methods.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let displayText = parsedInfo.displayText; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + displayText = displayText.replace(/</g, "<").replace(/>/g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + displayText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classMethods.push(lbl); + }); + maxHeight += lineHeight; + if (hasInterface) { + let diffX2 = (maxWidth - interfaceBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(interfaceLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")" + ); + verticalPos = interfaceBBox.height + rowPadding; + } + let diffX = (maxWidth - classTitleBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(classTitleLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + verticalPos += classTitleBBox.height + rowPadding; + topLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classAttributes.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + verticalPos += lineHeight; + bottomLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classMethods.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + rect2.attr("style", node.style).attr("class", "outer title-state").attr("x", -maxWidth / 2 - halfPadding).attr("y", -(maxHeight / 2) - halfPadding).attr("width", maxWidth + node.padding).attr("height", maxHeight + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const shapes = { + rhombus: question, + composite, + question, + rect, + labelRect, + rectWithTitle, + choice, + circle, + doublecircle, + stadium, + hexagon, + block_arrow, + rect_left_inv_arrow, + lean_right, + lean_left, + trapezoid, + inv_trapezoid, + rect_right_inv_arrow, + cylinder, + start, + end, + note: note$1, + subroutine, + fork: forkJoin, + join: forkJoin, + class_box +}; +let nodeElems = {}; +const insertNode = async (elem, node, dir) => { + let newEl; + let el; + if (node.link) { + let target; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel === "sandbox") { + target = "_top"; + } else if (node.linkTarget) { + target = node.linkTarget || "_blank"; + } + newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target); + el = await shapes[node.shape](newEl, node, dir); + } else { + el = await shapes[node.shape](elem, node, dir); + newEl = el; + } + if (node.tooltip) { + el.attr("title", node.tooltip); + } + if (node.class) { + el.attr("class", "node default " + node.class); + } + newEl.attr("data-node", "true"); + newEl.attr("data-id", node.id); + nodeElems[node.id] = newEl; + if (node.haveCallback) { + nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable"); + } + return newEl; +}; +const setNodeElem = (elem, node) => { + nodeElems[node.id] = elem; +}; +const clear$1 = () => { + nodeElems = {}; +}; +const positionNode = (node) => { + const el = nodeElems[node.id]; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.trace( + "Transforming node", + node.diff, + node, + "translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")" + ); + const padding = 8; + const diff = node.diff || 0; + if (node.clusterNode) { + el.attr( + "transform", + "translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")" + ); + } else { + el.attr("transform", "translate(" + node.x + ", " + node.y + ")"); + } + return diff; +}; +const getSubGraphTitleMargins = ({ + flowchart +}) => { + var _a, _b; + const subGraphTitleTopMargin = ((_a = flowchart == null ? void 0 : flowchart.subGraphTitleMargin) == null ? void 0 : _a.top) ?? 0; + const subGraphTitleBottomMargin = ((_b = flowchart == null ? void 0 : flowchart.subGraphTitleMargin) == null ? void 0 : _b.bottom) ?? 0; + const subGraphTitleTotalMargin = subGraphTitleTopMargin + subGraphTitleBottomMargin; + return { + subGraphTitleTopMargin, + subGraphTitleBottomMargin, + subGraphTitleTotalMargin + }; +}; +const markerOffsets = { + aggregation: 18, + extension: 18, + composition: 18, + dependency: 6, + lollipop: 13.5, + arrow_point: 5.3 +}; +function calculateDeltaAndAngle(point1, point2) { + if (point1 === void 0 || point2 === void 0) { + return { angle: 0, deltaX: 0, deltaY: 0 }; + } + point1 = pointTransformer(point1); + point2 = pointTransformer(point2); + const [x1, y1] = [point1.x, point1.y]; + const [x2, y2] = [point2.x, point2.y]; + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY }; +} +const pointTransformer = (data) => { + if (Array.isArray(data)) { + return { x: data[0], y: data[1] }; + } + return data; +}; +const getLineFunctionsWithOffset = (edge) => { + return { + x: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaX } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } + return pointTransformer(d).x + offset; + }, + y: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaY } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } + return pointTransformer(d).y + offset; + } + }; +}; +const addEdgeMarkers = (svgPath, edge, url, id, diagramType) => { + if (edge.arrowTypeStart) { + addEdgeMarker(svgPath, "start", edge.arrowTypeStart, url, id, diagramType); + } + if (edge.arrowTypeEnd) { + addEdgeMarker(svgPath, "end", edge.arrowTypeEnd, url, id, diagramType); + } +}; +const arrowTypesMap = { + arrow_cross: "cross", + arrow_point: "point", + arrow_barb: "barb", + arrow_circle: "circle", + aggregation: "aggregation", + extension: "extension", + composition: "composition", + dependency: "dependency", + lollipop: "lollipop" +}; +const addEdgeMarker = (svgPath, position, arrowType, url, id, diagramType) => { + const endMarkerType = arrowTypesMap[arrowType]; + if (!endMarkerType) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown arrow type: ${arrowType}`); + return; + } + const suffix = position === "start" ? "Start" : "End"; + svgPath.attr(`marker-${position}`, `url(${url}#${id}_${diagramType}-${endMarkerType}${suffix})`); +}; +let edgeLabels = {}; +let terminalLabels = {}; +const clear = () => { + edgeLabels = {}; + terminalLabels = {}; +}; +const insertEdgeLabel = (elem, edge) => { + const useHtmlLabels = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + const labelElement = edge.labelType === "markdown" ? (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_2__.a)(elem, edge.label, { + style: edge.labelStyle, + useHtmlLabels, + addSvgBackground: true + }) : createLabel$1(edge.label, edge.labelStyle); + const edgeLabel = elem.insert("g").attr("class", "edgeLabel"); + const label = edgeLabel.insert("g").attr("class", "label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + if (useHtmlLabels) { + const div = labelElement.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(labelElement); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + edgeLabels[edge.id] = edgeLabel; + edge.width = bbox.width; + edge.height = bbox.height; + let fo; + if (edge.startLabelLeft) { + const startLabelElement = createLabel$1(edge.startLabelLeft, edge.labelStyle); + const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startLeft = startEdgeLabelLeft; + setTerminalWidth(fo, edge.startLabelLeft); + } + if (edge.startLabelRight) { + const startLabelElement = createLabel$1(edge.startLabelRight, edge.labelStyle); + const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelRight.insert("g").attr("class", "inner"); + fo = startEdgeLabelRight.node().appendChild(startLabelElement); + inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startRight = startEdgeLabelRight; + setTerminalWidth(fo, edge.startLabelRight); + } + if (edge.endLabelLeft) { + const endLabelElement = createLabel$1(edge.endLabelLeft, edge.labelStyle); + const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelLeft.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endLeft = endEdgeLabelLeft; + setTerminalWidth(fo, edge.endLabelLeft); + } + if (edge.endLabelRight) { + const endLabelElement = createLabel$1(edge.endLabelRight, edge.labelStyle); + const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelRight.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelRight.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endRight = endEdgeLabelRight; + setTerminalWidth(fo, edge.endLabelRight); + } + return labelElement; +}; +function setTerminalWidth(fo, value) { + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels && fo) { + fo.style.width = value.length * 9 + "px"; + fo.style.height = "12px"; + } +} +const positionEdgeLabel = (edge, paths) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("Moving label abc88 ", edge.id, edge.label, edgeLabels[edge.id], paths); + let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig); + if (edge.label) { + const el = edgeLabels[edge.id]; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcLabelPosition(path); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug( + "Moving label " + edge.label + " from (", + x, + ",", + y, + ") to (", + pos.x, + ",", + pos.y, + ") abc88" + ); + if (paths.updatedPath) { + x = pos.x; + y = pos.y; + } + } + el.attr("transform", `translate(${x}, ${y + subGraphTitleTotalMargin / 2})`); + } + if (edge.startLabelLeft) { + const el = terminalLabels[edge.id].startLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.startLabelRight) { + const el = terminalLabels[edge.id].startRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition( + edge.arrowTypeStart ? 10 : 0, + "start_right", + path + ); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.endLabelLeft) { + const el = terminalLabels[edge.id].endLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } + if (edge.endLabelRight) { + const el = terminalLabels[edge.id].endRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", `translate(${x}, ${y})`); + } +}; +const outsideNode = (node, point2) => { + const x = node.x; + const y = node.y; + const dx = Math.abs(point2.x - x); + const dy = Math.abs(point2.y - y); + const w = node.width / 2; + const h = node.height / 2; + if (dx >= w || dy >= h) { + return true; + } + return false; +}; +const intersection = (node, outsidePoint, insidePoint) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`intersection calc abc89: + outsidePoint: ${JSON.stringify(outsidePoint)} + insidePoint : ${JSON.stringify(insidePoint)} + node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`); + const x = node.x; + const y = node.y; + const dx = Math.abs(x - insidePoint.x); + const w = node.width / 2; + let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; + const h = node.height / 2; + const Q = Math.abs(outsidePoint.y - insidePoint.y); + const R = Math.abs(outsidePoint.x - insidePoint.x); + if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { + let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y; + r = R * q / Q; + const res = { + x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r, + y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q + }; + if (r === 0) { + res.x = outsidePoint.x; + res.y = outsidePoint.y; + } + if (R === 0) { + res.x = outsidePoint.x; + } + if (Q === 0) { + res.y = outsidePoint.y; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res); + return res; + } else { + if (insidePoint.x < outsidePoint.x) { + r = outsidePoint.x - w - x; + } else { + r = x - w - outsidePoint.x; + } + let q = Q * r / R; + let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r; + let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y }); + if (r === 0) { + _x = outsidePoint.x; + _y = outsidePoint.y; + } + if (R === 0) { + _x = outsidePoint.x; + } + if (Q === 0) { + _y = outsidePoint.y; + } + return { x: _x, y: _y }; + } +}; +const cutPathAtIntersect = (_points, boundaryNode) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("abc88 cutPathAtIntersect", _points, boundaryNode); + let points = []; + let lastPointOutside = _points[0]; + let isInside = false; + _points.forEach((point2) => { + if (!outsideNode(boundaryNode, point2) && !isInside) { + const inter = intersection(boundaryNode, lastPointOutside, point2); + let pointPresent = false; + points.forEach((p) => { + pointPresent = pointPresent || p.x === inter.x && p.y === inter.y; + }); + if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { + points.push(inter); + } + isInside = true; + } else { + lastPointOutside = point2; + if (!isInside) { + points.push(point2); + } + } + }); + return points; +}; +const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph, id) { + let points = edge.points; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("abc88 InsertEdge: edge=", edge, "e=", e); + let pointsHasChanged = false; + const tail = graph.node(e.v); + var head = graph.node(e.w); + if ((head == null ? void 0 : head.intersect) && (tail == null ? void 0 : tail.intersect)) { + points = points.slice(1, edge.points.length - 1); + points.unshift(tail.intersect(points[0])); + points.push(head.intersect(points[points.length - 1])); + } + if (edge.toCluster) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("to cluster abc88", clusterDb[edge.toCluster]); + points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); + pointsHasChanged = true; + } + if (edge.fromCluster) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("from cluster abc88", clusterDb[edge.fromCluster]); + points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse(); + pointsHasChanged = true; + } + const lineData = points.filter((p) => !Number.isNaN(p.y)); + let curve = d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .qrM; + if (edge.curve && (diagramType === "graph" || diagramType === "flowchart")) { + curve = edge.curve; + } + const { x, y } = getLineFunctionsWithOffset(edge); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .n8j)().x(x).y(y).curve(curve); + let strokeClasses; + switch (edge.thickness) { + case "normal": + strokeClasses = "edge-thickness-normal"; + break; + case "thick": + strokeClasses = "edge-thickness-thick"; + break; + case "invisible": + strokeClasses = "edge-thickness-thick"; + break; + default: + strokeClasses = ""; + } + switch (edge.pattern) { + case "solid": + strokeClasses += " edge-pattern-solid"; + break; + case "dotted": + strokeClasses += " edge-pattern-dotted"; + break; + case "dashed": + strokeClasses += " edge-pattern-dashed"; + break; + } + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style); + let url = ""; + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.arrowMarkerAbsolute || (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + addEdgeMarkers(svgPath, edge, url, id, diagramType); + let paths = {}; + if (pointsHasChanged) { + paths.updatedPath = points; + } + paths.originalPath = edge.points; + return paths; +}; + + + +/***/ }), + +/***/ 92746: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ r: () => (/* binding */ render) +/* harmony export */ }); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(21176); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14075); +/* harmony import */ var _edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(28747); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(76257); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(697); +/* harmony import */ var _createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(40351); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(26312); + + + + + + + +let clusterDb = {}; +let descendants = {}; +let parents = {}; +const clear$1 = () => { + descendants = {}; + parents = {}; + clusterDb = {}; +}; +const isDescendant = (id, ancestorId) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("In isDescendant", ancestorId, " ", id, " = ", descendants[ancestorId].includes(id)); + if (descendants[ancestorId].includes(id)) { + return true; + } + return false; +}; +const edgeInCluster = (edge, clusterId) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Descendants of ", clusterId, " is ", descendants[clusterId]); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge is ", edge); + if (edge.v === clusterId) { + return false; + } + if (edge.w === clusterId) { + return false; + } + if (!descendants[clusterId]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Tilt, ", clusterId, ",not in descendants"); + return false; + } + return descendants[clusterId].includes(edge.v) || isDescendant(edge.v, clusterId) || isDescendant(edge.w, clusterId) || descendants[clusterId].includes(edge.w); +}; +const copy = (clusterId, graph, newGraph, rootId) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Copying children of ", + clusterId, + "root", + rootId, + "data", + graph.node(clusterId), + rootId + ); + const nodes = graph.children(clusterId) || []; + if (clusterId !== rootId) { + nodes.push(clusterId); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Copying (nodes) clusterId", clusterId, "nodes", nodes); + nodes.forEach((node) => { + if (graph.children(node).length > 0) { + copy(node, graph, newGraph, rootId); + } else { + const data = graph.node(node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("cp ", node, " to ", rootId, " with parent ", clusterId); + newGraph.setNode(node, data); + if (rootId !== graph.parent(node)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Setting parent", node, graph.parent(node)); + newGraph.setParent(node, graph.parent(node)); + } + if (clusterId !== rootId && node !== clusterId) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Setting parent", node, clusterId); + newGraph.setParent(node, clusterId); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("In copy ", clusterId, "root", rootId, "data", graph.node(clusterId), rootId); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Not Setting parent for node=", + node, + "cluster!==rootId", + clusterId !== rootId, + "node!==clusterId", + node !== clusterId + ); + } + const edges = graph.edges(node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Copying Edges", edges); + edges.forEach((edge) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge", edge); + const data2 = graph.edge(edge.v, edge.w, edge.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge data", data2, rootId); + try { + if (edgeInCluster(edge, rootId)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Copying as ", edge.v, edge.w, data2, edge.name); + newGraph.setEdge(edge.v, edge.w, data2, edge.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("newGraph edges ", newGraph.edges(), newGraph.edge(newGraph.edges()[0])); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Skipping copy of edge ", + edge.v, + "-->", + edge.w, + " rootId: ", + rootId, + " clusterId:", + clusterId + ); + } + } catch (e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error(e); + } + }); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Removing node", node); + graph.removeNode(node); + }); +}; +const extractDescendants = (id, graph) => { + const children = graph.children(id); + let res = [...children]; + for (const child of children) { + parents[child] = id; + res = [...res, ...extractDescendants(child, graph)]; + } + return res; +}; +const findNonClusterChild = (id, graph) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching", id); + const children = graph.children(id); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching children of id ", id, children); + if (children.length < 1) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("This is a valid node", id); + return id; + } + for (const child of children) { + const _id = findNonClusterChild(child, graph); + if (_id) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Found replacement for", id, " => ", _id); + return _id; + } + } +}; +const getAnchorId = (id) => { + if (!clusterDb[id]) { + return id; + } + if (!clusterDb[id].externalConnections) { + return id; + } + if (clusterDb[id]) { + return clusterDb[id].id; + } + return id; +}; +const adjustClustersAndEdges = (graph, depth) => { + if (!graph || depth > 10) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting out, no graph "); + return; + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting in, graph "); + } + graph.nodes().forEach(function(id) { + const children = graph.children(id); + if (children.length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster identified", + id, + " Replacement id in edges: ", + findNonClusterChild(id, graph) + ); + descendants[id] = extractDescendants(id, graph); + clusterDb[id] = { id: findNonClusterChild(id, graph), clusterData: graph.node(id) }; + } + }); + graph.nodes().forEach(function(id) { + const children = graph.children(id); + const edges = graph.edges(); + if (children.length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Cluster identified", id, descendants); + edges.forEach((edge) => { + if (edge.v !== id && edge.w !== id) { + const d1 = isDescendant(edge.v, id); + const d2 = isDescendant(edge.w, id); + if (d1 ^ d2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge: ", edge, " leaves cluster ", id); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Descendants of XXX ", id, ": ", descendants[id]); + clusterDb[id].externalConnections = true; + } + } + }); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster ", id, descendants); + } + }); + for (let id of Object.keys(clusterDb)) { + const nonClusterChild = clusterDb[id].id; + const parent = graph.parent(nonClusterChild); + if (parent !== id && clusterDb[parent] && !clusterDb[parent].externalConnections) { + clusterDb[id].id = parent; + } + } + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(graph.edge(e))); + let v = e.v; + let w = e.w; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Fix XXX", + clusterDb, + "ids:", + e.v, + e.w, + "Translating: ", + clusterDb[e.v], + " --- ", + clusterDb[e.w] + ); + if (clusterDb[e.v] && clusterDb[e.w] && clusterDb[e.v] === clusterDb[e.w]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing link to self - removing XXX", e.v, e.w, e.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + const specialId = e.w + "---" + e.v; + graph.setNode(specialId, { + domId: specialId, + id: specialId, + labelStyle: "", + labelText: edge.label, + padding: 0, + shape: "labelRect", + style: "" + }); + const edge1 = structuredClone(edge); + const edge2 = structuredClone(edge); + edge1.label = ""; + edge1.arrowTypeEnd = "none"; + edge2.label = ""; + edge1.fromCluster = e.v; + edge2.toCluster = e.v; + graph.setEdge(v, specialId, edge1, e.name + "-cyclic-special"); + graph.setEdge(specialId, w, edge2, e.name + "-cyclic-special"); + } else if (clusterDb[e.v] || clusterDb[e.w]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + if (v !== e.v) { + const parent = graph.parent(v); + clusterDb[parent].externalConnections = true; + edge.fromCluster = e.v; + } + if (w !== e.w) { + const parent = graph.parent(w); + clusterDb[parent].externalConnections = true; + edge.toCluster = e.w; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fix Replacing with XXX", v, w, e.name); + graph.setEdge(v, w, edge, e.name); + } + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Adjusted Graph", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + extractor(graph, 0); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace(clusterDb); +}; +const extractor = (graph, depth) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("extractor - ", depth, dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph), graph.children("D")); + if (depth > 10) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.error("Bailing out"); + return; + } + let nodes = graph.nodes(); + let hasChildren = false; + for (const node of nodes) { + const children = graph.children(node); + hasChildren = hasChildren || children.length > 0; + } + if (!hasChildren) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Done, no node has children", graph.nodes()); + return; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Nodes = ", nodes, depth); + for (const node of nodes) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Extracting node", + node, + clusterDb, + clusterDb[node] && !clusterDb[node].externalConnections, + !graph.parent(node), + graph.node(node), + graph.children("D"), + " Depth ", + depth + ); + if (!clusterDb[node]) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster", node, depth); + } else if (!clusterDb[node].externalConnections && // !graph.parent(node) && + graph.children(node) && graph.children(node).length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster without external connections, without a parent and with children", + node, + depth + ); + const graphSettings = graph.graph(); + let dir = graphSettings.rankdir === "TB" ? "LR" : "TB"; + if (clusterDb[node] && clusterDb[node].clusterData && clusterDb[node].clusterData.dir) { + dir = clusterDb[node].clusterData.dir; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing dir", clusterDb[node].clusterData.dir, dir); + } + const clusterGraph = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .T({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + // Todo: set proper spacing + nodesep: 50, + ranksep: 50, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Old graph before copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + copy(node, graph, clusterGraph, node); + graph.setNode(node, { + clusterNode: true, + id: node, + clusterData: clusterDb[node].clusterData, + labelText: clusterDb[node].labelText, + graph: clusterGraph + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New graph after copy node: (", node, ")", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(clusterGraph)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Old graph after copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster ** ", + node, + " **not meeting the criteria !externalConnections:", + !clusterDb[node].externalConnections, + " no parent: ", + !graph.parent(node), + " children ", + graph.children(node) && graph.children(node).length > 0, + graph.children("D"), + depth + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(clusterDb); + } + } + nodes = graph.nodes(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New list of nodes", nodes); + for (const node of nodes) { + const data = graph.node(node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn(" Now next level", node, data); + if (data.clusterNode) { + extractor(data.graph, depth + 1); + } + } +}; +const sorter = (graph, nodes) => { + if (nodes.length === 0) { + return []; + } + let result = Object.assign(nodes); + nodes.forEach((node) => { + const children = graph.children(node); + const sorted = sorter(graph, children); + result = [...result, ...sorted]; + }); + return result; +}; +const sortNodesByHierarchy = (graph) => sorter(graph, graph.children()); +const rect = (parent, node) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Creating subgraph rect for ", node.id, node); + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const shapeSvg = parent.insert("g").attr("class", "cluster" + (node.class ? " " + node.class : "")).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const useHtmlLabels = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const text = node.labelType === "markdown" ? (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_5__.a)(label, node.labelText, { style: node.labelStyle, useHtmlLabels }) : label.node().appendChild((0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width; + if (node.width <= bbox.width + padding) { + node.diff = (bbox.width - node.width) / 2 - node.padding / 2; + } else { + node.diff = -node.padding / 2; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Data ", node, JSON.stringify(node)); + rect2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - width / 2).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width).attr("height", node.height + padding); + const { subGraphTitleTopMargin } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.g)(siteConfig); + if (useHtmlLabels) { + label.attr( + "transform", + // This puts the label on top of the box instead of inside it + `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 + subGraphTitleTopMargin})` + ); + } else { + label.attr( + "transform", + // This puts the label on top of the box instead of inside it + `translate(${node.x}, ${node.y - node.height / 2 + subGraphTitleTopMargin})` + ); + } + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const noteGroup = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "note-cluster").attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", node.width + padding).attr("height", node.height + padding).attr("fill", "none"); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const roundedWithTitle = (parent, node) => { + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const innerRect = shapeSvg.append("rect"); + const text = label.node().appendChild((0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ltv)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + bbox = text.getBBox(); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width; + if (node.width <= bbox.width + node.padding) { + node.diff = (bbox.width + node.padding * 0 - node.width) / 2; + } else { + node.diff = -node.padding / 2; + } + rect2.attr("class", "outer").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width + padding).attr("height", node.height + padding); + innerRect.attr("class", "inner").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding + bbox.height - 1).attr("width", width + padding).attr("height", node.height + padding - bbox.height - 3); + const { subGraphTitleTopMargin } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.g)(siteConfig); + label.attr( + "transform", + `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 - node.padding / 3 + ((0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.m)(siteConfig.flowchart.htmlLabels) ? 5 : 3) + subGraphTitleTopMargin})` + ); + const rectBox = rect2.node().getBBox(); + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const divider = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("class", "divider").attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2).attr("width", node.width + padding).attr("height", node.height + padding); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.diff = -node.padding / 2; + node.intersect = function(point) { + return (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const shapes = { rect, roundedWithTitle, noteGroup, divider }; +let clusterElems = {}; +const insertCluster = (elem, node) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Inserting cluster"); + const shape = node.shape || "rect"; + clusterElems[node.id] = shapes[shape](elem, node); +}; +const clear = () => { + clusterElems = {}; +}; +const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, siteConfig) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph in recursive render: XXX", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph), parentCluster); + const dir = graph.graph().rankdir; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Dir in recursive render - dir:", dir); + const elem = _elem.insert("g").attr("class", "root"); + if (!graph.nodes()) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("No nodes found for", graph); + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Recursive render XXX", graph.nodes()); + } + if (graph.edges().length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Recursive edges", graph.edge(graph.edges()[0])); + } + const clusters = elem.insert("g").attr("class", "clusters"); + const edgePaths = elem.insert("g").attr("class", "edgePaths"); + const edgeLabels = elem.insert("g").attr("class", "edgeLabels"); + const nodes = elem.insert("g").attr("class", "nodes"); + await Promise.all( + graph.nodes().map(async function(v) { + const node = graph.node(v); + if (parentCluster !== void 0) { + const data = JSON.parse(JSON.stringify(parentCluster.clusterData)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Setting data for cluster XXX (", v, ") ", data, parentCluster); + graph.setNode(parentCluster.id, data); + if (!graph.parent(v)) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Setting parent", v, parentCluster.id); + graph.setParent(v, parentCluster.id, data); + } + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("(Insert) Node XXX" + v + ": " + JSON.stringify(graph.node(v))); + if (node && node.clusterNode) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster identified", v, node.width, graph.node(v)); + const o = await recursiveRender( + nodes, + node.graph, + diagramType, + id, + graph.node(v), + siteConfig + ); + const newEl = o.elem; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.u)(node, newEl); + node.diff = o.diff || 0; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node bounds (abc123)", v, node, node.width, node.x, node.y); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.s)(newEl, node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Recursive render complete ", newEl, node); + } else { + if (graph.children(v).length > 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster - the non recursive path XXX", v, node.id, node, graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info(findNonClusterChild(node.id, graph)); + clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node }; + } else { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node - the non recursive path", v, node.id, node); + await (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.e)(nodes, graph.node(v), dir); + } + } + }) + ); + graph.edges().forEach(function(e) { + const edge = graph.edge(e.v, e.w, e.name); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": ", e, " ", JSON.stringify(graph.edge(e))); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Fix", clusterDb, "ids:", e.v, e.w, "Translating: ", clusterDb[e.v], clusterDb[e.w]); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.f)(edgeLabels, edge); + }); + graph.edges().forEach(function(e) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + }); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("### Layout ###"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info(graph); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__/* .layout */ .Zp)(graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph after layout:", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph)); + let diff = 0; + const { subGraphTitleTotalMargin } = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.g)(siteConfig); + sortNodesByHierarchy(graph).forEach(function(v) { + const node = graph.node(v); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Position " + v + ": " + JSON.stringify(graph.node(v))); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Position " + v + ": (" + node.x, + "," + node.y, + ") width: ", + node.width, + " height: ", + node.height + ); + if (node && node.clusterNode) { + node.y += subGraphTitleTotalMargin; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } else { + if (graph.children(v).length > 0) { + node.height += subGraphTitleTotalMargin; + insertCluster(clusters, node); + clusterDb[node.id].node = node; + } else { + node.y += subGraphTitleTotalMargin / 2; + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } + } + }); + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(edge), edge); + edge.points.forEach((point) => point.y += subGraphTitleTotalMargin / 2); + const paths = (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.h)(edgePaths, e, edge, clusterDb, diagramType, graph, id); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.j)(edge, paths); + }); + graph.nodes().forEach(function(v) { + const n = graph.node(v); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.info(v, n.type, n.diff); + if (n.type === "group") { + diff = n.diff; + } + }); + return { elem, diff }; +}; +const render = async (elem, graph, markers, diagramType, id) => { + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.a)(elem, markers, diagramType, id); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.b)(); + (0,_edges_d32062c0_js__WEBPACK_IMPORTED_MODULE_6__.d)(); + clear(); + clear$1(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph at first:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph))); + adjustClustersAndEdges(graph); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph after:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .M(graph))); + const siteConfig = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + await recursiveRender(elem, graph, diagramType, id, void 0, siteConfig); +}; + + + +/***/ }), + +/***/ 45688: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(26292); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(697); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(26312); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(76257); +/* harmony import */ var _index_fc10efb0_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(92746); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(99418); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(21176); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(14075); + + + + + + + + + + + + + + + + + + + +const SHAPE_STATE = "rect"; +const SHAPE_STATE_WITH_DESC = "rectWithTitle"; +const SHAPE_START = "start"; +const SHAPE_END = "end"; +const SHAPE_DIVIDER = "divider"; +const SHAPE_GROUP = "roundedWithTitle"; +const SHAPE_NOTE = "note"; +const SHAPE_NOTEGROUP = "noteGroup"; +const CSS_DIAGRAM = "statediagram"; +const CSS_STATE = "state"; +const CSS_DIAGRAM_STATE = `${CSS_DIAGRAM}-${CSS_STATE}`; +const CSS_EDGE = "transition"; +const CSS_NOTE = "note"; +const CSS_NOTE_EDGE = "note-edge"; +const CSS_EDGE_NOTE_EDGE = `${CSS_EDGE} ${CSS_NOTE_EDGE}`; +const CSS_DIAGRAM_NOTE = `${CSS_DIAGRAM}-${CSS_NOTE}`; +const CSS_CLUSTER = "cluster"; +const CSS_DIAGRAM_CLUSTER = `${CSS_DIAGRAM}-${CSS_CLUSTER}`; +const CSS_CLUSTER_ALT = "cluster-alt"; +const CSS_DIAGRAM_CLUSTER_ALT = `${CSS_DIAGRAM}-${CSS_CLUSTER_ALT}`; +const PARENT = "parent"; +const NOTE = "note"; +const DOMID_STATE = "state"; +const DOMID_TYPE_SPACER = "----"; +const NOTE_ID = `${DOMID_TYPE_SPACER}${NOTE}`; +const PARENT_ID = `${DOMID_TYPE_SPACER}${PARENT}`; +const G_EDGE_STYLE = "fill:none"; +const G_EDGE_ARROWHEADSTYLE = "fill: #333"; +const G_EDGE_LABELPOS = "c"; +const G_EDGE_LABELTYPE = "text"; +const G_EDGE_THICKNESS = "normal"; +let nodeDb = {}; +let graphItemCount = 0; +const setConf = function(cnf) { + const keys = Object.keys(cnf); + for (const key of keys) { + cnf[key]; + } +}; +const getClasses = function(text, diagramObj) { + diagramObj.db.extract(diagramObj.db.getRootDocV2()); + return diagramObj.db.getClasses(); +}; +function getClassesFromDbInfo(dbInfoItem) { + if (dbInfoItem === void 0 || dbInfoItem === null) { + return ""; + } else { + if (dbInfoItem.classes) { + return dbInfoItem.classes.join(" "); + } else { + return ""; + } + } +} +function stateDomId(itemId = "", counter = 0, type = "", typeSpacer = DOMID_TYPE_SPACER) { + const typeStr = type !== null && type.length > 0 ? `${typeSpacer}${type}` : ""; + return `${DOMID_STATE}-${itemId}${typeStr}-${counter}`; +} +const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => { + const itemId = parsedItem.id; + const classStr = getClassesFromDbInfo(diagramStates[itemId]); + if (itemId !== "root") { + let shape = SHAPE_STATE; + if (parsedItem.start === true) { + shape = SHAPE_START; + } + if (parsedItem.start === false) { + shape = SHAPE_END; + } + if (parsedItem.type !== _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.D) { + shape = parsedItem.type; + } + if (!nodeDb[itemId]) { + nodeDb[itemId] = { + id: itemId, + shape, + description: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.e.sanitizeText(itemId, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.c)()), + classes: `${classStr} ${CSS_DIAGRAM_STATE}` + }; + } + const newNode = nodeDb[itemId]; + if (parsedItem.description) { + if (Array.isArray(newNode.description)) { + newNode.shape = SHAPE_STATE_WITH_DESC; + newNode.description.push(parsedItem.description); + } else { + if (newNode.description.length > 0) { + newNode.shape = SHAPE_STATE_WITH_DESC; + if (newNode.description === itemId) { + newNode.description = [parsedItem.description]; + } else { + newNode.description = [newNode.description, parsedItem.description]; + } + } else { + newNode.shape = SHAPE_STATE; + newNode.description = parsedItem.description; + } + } + newNode.description = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.e.sanitizeTextOrArray(newNode.description, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.c)()); + } + if (newNode.description.length === 1 && newNode.shape === SHAPE_STATE_WITH_DESC) { + newNode.shape = SHAPE_STATE; + } + if (!newNode.type && parsedItem.doc) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.l.info("Setting cluster for ", itemId, getDir(parsedItem)); + newNode.type = "group"; + newNode.dir = getDir(parsedItem); + newNode.shape = parsedItem.type === _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.a ? SHAPE_DIVIDER : SHAPE_GROUP; + newNode.classes = newNode.classes + " " + CSS_DIAGRAM_CLUSTER + " " + (altFlag ? CSS_DIAGRAM_CLUSTER_ALT : ""); + } + const nodeData = { + labelStyle: "", + shape: newNode.shape, + labelText: newNode.description, + // typeof newNode.description === 'object' + // ? newNode.description[0] + // : newNode.description, + classes: newNode.classes, + style: "", + //styles.style, + id: itemId, + dir: newNode.dir, + domId: stateDomId(itemId, graphItemCount), + type: newNode.type, + padding: 15 + //getConfig().flowchart.padding + }; + nodeData.centerLabel = true; + if (parsedItem.note) { + const noteData = { + labelStyle: "", + shape: SHAPE_NOTE, + labelText: parsedItem.note.text, + classes: CSS_DIAGRAM_NOTE, + // useHtmlLabels: false, + style: "", + // styles.style, + id: itemId + NOTE_ID + "-" + graphItemCount, + domId: stateDomId(itemId, graphItemCount, NOTE), + type: newNode.type, + padding: 15 + //getConfig().flowchart.padding + }; + const groupData = { + labelStyle: "", + shape: SHAPE_NOTEGROUP, + labelText: parsedItem.note.text, + classes: newNode.classes, + style: "", + // styles.style, + id: itemId + PARENT_ID, + domId: stateDomId(itemId, graphItemCount, PARENT), + type: "group", + padding: 0 + //getConfig().flowchart.padding + }; + graphItemCount++; + const parentNodeId = itemId + PARENT_ID; + g.setNode(parentNodeId, groupData); + g.setNode(noteData.id, noteData); + g.setNode(itemId, nodeData); + g.setParent(itemId, parentNodeId); + g.setParent(noteData.id, parentNodeId); + let from = itemId; + let to = noteData.id; + if (parsedItem.note.position === "left of") { + from = noteData.id; + to = itemId; + } + g.setEdge(from, to, { + arrowhead: "none", + arrowType: "", + style: G_EDGE_STYLE, + labelStyle: "", + classes: CSS_EDGE_NOTE_EDGE, + arrowheadStyle: G_EDGE_ARROWHEADSTYLE, + labelpos: G_EDGE_LABELPOS, + labelType: G_EDGE_LABELTYPE, + thickness: G_EDGE_THICKNESS + }); + } else { + g.setNode(itemId, nodeData); + } + } + if (parent && parent.id !== "root") { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.l.trace("Setting node ", itemId, " to be child of its parent ", parent.id); + g.setParent(itemId, parent.id); + } + if (parsedItem.doc) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.l.trace("Adding nodes children "); + setupDoc(g, parsedItem, parsedItem.doc, diagramStates, diagramDb, !altFlag); + } +}; +const setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.l.trace("items", doc); + doc.forEach((item) => { + switch (item.stmt) { + case _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.b: + setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag); + break; + case _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.D: + setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag); + break; + case _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.S: + { + setupNode(g, parentParsedItem, item.state1, diagramStates, diagramDb, altFlag); + setupNode(g, parentParsedItem, item.state2, diagramStates, diagramDb, altFlag); + const edgeData = { + id: "edge" + graphItemCount, + arrowhead: "normal", + arrowTypeEnd: "arrow_barb", + style: G_EDGE_STYLE, + labelStyle: "", + label: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.e.sanitizeText(item.description, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.c)()), + arrowheadStyle: G_EDGE_ARROWHEADSTYLE, + labelpos: G_EDGE_LABELPOS, + labelType: G_EDGE_LABELTYPE, + thickness: G_EDGE_THICKNESS, + classes: CSS_EDGE + }; + g.setEdge(item.state1.id, item.state2.id, edgeData, graphItemCount); + graphItemCount++; + } + break; + } + }); +}; +const getDir = (parsedItem, defaultDir = _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.c) => { + let dir = defaultDir; + if (parsedItem.doc) { + for (let i = 0; i < parsedItem.doc.length; i++) { + const parsedItemDoc = parsedItem.doc[i]; + if (parsedItemDoc.stmt === "dir") { + dir = parsedItemDoc.value; + } + } + } + return dir; +}; +const draw = async function(text, id, _version, diag) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.l.info("Drawing state diagram (v2)", id); + nodeDb = {}; + diag.db.getDirection(); + const { securityLevel, state: conf } = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.c)(); + const nodeSpacing = conf.nodeSpacing || 50; + const rankSpacing = conf.rankSpacing || 50; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.l.info(diag.db.getRootDocV2()); + diag.db.extract(diag.db.getRootDocV2()); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.l.info(diag.db.getRootDocV2()); + const diagramStates = diag.db.getStates(); + const g = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_0__/* .Graph */ .T({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: getDir(diag.db.getRootDocV2()), + nodesep: nodeSpacing, + ranksep: rankSpacing, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + setupNode(g, void 0, diag.db.getRootDocV2(), diagramStates, diag.db, true); + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ltv)("body"); + const svg = root.select(`[id="${id}"]`); + const element = root.select("#" + id + " g"); + await (0,_index_fc10efb0_js__WEBPACK_IMPORTED_MODULE_9__.r)(element, g, ["barb"], CSS_DIAGRAM, id); + const padding = 8; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.u.insertTitle(svg, "statediagramTitleText", conf.titleTopMargin, diag.db.getDiagramTitle()); + const bounds = svg.node().getBBox(); + const width = bounds.width + padding * 2; + const height = bounds.height + padding * 2; + svg.attr("class", CSS_DIAGRAM); + const svgBounds = svg.node().getBBox(); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.i)(svg, height, width, conf.useMaxWidth); + const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_8__.l.debug(`viewBox ${vBox}`); + svg.attr("viewBox", vBox); + const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); + for (const label of labels) { + const dim = label.getBBox(); + const rect = document.createElementNS("http://www.w3.org/2000/svg", SHAPE_STATE); + rect.setAttribute("rx", 0); + rect.setAttribute("ry", 0); + rect.setAttribute("width", dim.width); + rect.setAttribute("height", dim.height); + label.insertBefore(rect, label.firstChild); + } +}; +const renderer = { + setConf, + getClasses, + draw +}; +const diagram = { + parser: _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.p, + db: _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.d, + renderer, + styles: _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.s, + init: (cnf) => { + if (!cnf.state) { + cnf.state = {}; + } + cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + _styles_d20c7d72_js__WEBPACK_IMPORTED_MODULE_7__.d.clear(); + } +}; + + + +/***/ }), + +/***/ 26292: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ D: () => (/* binding */ DEFAULT_STATE_TYPE), +/* harmony export */ S: () => (/* binding */ STMT_RELATION), +/* harmony export */ a: () => (/* binding */ DIVIDER_TYPE), +/* harmony export */ b: () => (/* binding */ STMT_STATE), +/* harmony export */ c: () => (/* binding */ DEFAULT_NESTED_DOC_DIR), +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ p: () => (/* binding */ parser$1), +/* harmony export */ s: () => (/* binding */ styles) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(76257); + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 2], $V1 = [1, 3], $V2 = [1, 4], $V3 = [2, 4], $V4 = [1, 9], $V5 = [1, 11], $V6 = [1, 15], $V7 = [1, 16], $V8 = [1, 17], $V9 = [1, 18], $Va = [1, 30], $Vb = [1, 19], $Vc = [1, 20], $Vd = [1, 21], $Ve = [1, 22], $Vf = [1, 23], $Vg = [1, 25], $Vh = [1, 26], $Vi = [1, 27], $Vj = [1, 28], $Vk = [1, 29], $Vl = [1, 32], $Vm = [1, 33], $Vn = [1, 34], $Vo = [1, 35], $Vp = [1, 31], $Vq = [1, 4, 5, 15, 16, 18, 20, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50], $Vr = [1, 4, 5, 13, 14, 15, 16, 18, 20, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50], $Vs = [4, 5, 15, 16, 18, 20, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "SPACE": 4, "NL": 5, "SD": 6, "document": 7, "line": 8, "statement": 9, "classDefStatement": 10, "cssClassStatement": 11, "idStatement": 12, "DESCR": 13, "-->": 14, "HIDE_EMPTY": 15, "scale": 16, "WIDTH": 17, "COMPOSIT_STATE": 18, "STRUCT_START": 19, "STRUCT_STOP": 20, "STATE_DESCR": 21, "AS": 22, "ID": 23, "FORK": 24, "JOIN": 25, "CHOICE": 26, "CONCURRENT": 27, "note": 28, "notePosition": 29, "NOTE_TEXT": 30, "direction": 31, "acc_title": 32, "acc_title_value": 33, "acc_descr": 34, "acc_descr_value": 35, "acc_descr_multiline_value": 36, "classDef": 37, "CLASSDEF_ID": 38, "CLASSDEF_STYLEOPTS": 39, "DEFAULT": 40, "class": 41, "CLASSENTITY_IDS": 42, "STYLECLASS": 43, "direction_tb": 44, "direction_bt": 45, "direction_rl": 46, "direction_lr": 47, "eol": 48, ";": 49, "EDGE_STATE": 50, "STYLE_SEPARATOR": 51, "left_of": 52, "right_of": 53, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "SPACE", 5: "NL", 6: "SD", 13: "DESCR", 14: "-->", 15: "HIDE_EMPTY", 16: "scale", 17: "WIDTH", 18: "COMPOSIT_STATE", 19: "STRUCT_START", 20: "STRUCT_STOP", 21: "STATE_DESCR", 22: "AS", 23: "ID", 24: "FORK", 25: "JOIN", 26: "CHOICE", 27: "CONCURRENT", 28: "note", 30: "NOTE_TEXT", 32: "acc_title", 33: "acc_title_value", 34: "acc_descr", 35: "acc_descr_value", 36: "acc_descr_multiline_value", 37: "classDef", 38: "CLASSDEF_ID", 39: "CLASSDEF_STYLEOPTS", 40: "DEFAULT", 41: "class", 42: "CLASSENTITY_IDS", 43: "STYLECLASS", 44: "direction_tb", 45: "direction_bt", 46: "direction_rl", 47: "direction_lr", 49: ";", 50: "EDGE_STATE", 51: "STYLE_SEPARATOR", 52: "left_of", 53: "right_of" }, + productions_: [0, [3, 2], [3, 2], [3, 2], [7, 0], [7, 2], [8, 2], [8, 1], [8, 1], [9, 1], [9, 1], [9, 1], [9, 2], [9, 3], [9, 4], [9, 1], [9, 2], [9, 1], [9, 4], [9, 3], [9, 6], [9, 1], [9, 1], [9, 1], [9, 1], [9, 4], [9, 4], [9, 1], [9, 2], [9, 2], [9, 1], [10, 3], [10, 3], [11, 3], [31, 1], [31, 1], [31, 1], [31, 1], [48, 1], [48, 1], [12, 1], [12, 1], [12, 3], [12, 3], [29, 1], [29, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 3: + yy.setRootDoc($$[$0]); + return $$[$0]; + case 4: + this.$ = []; + break; + case 5: + if ($$[$0] != "nl") { + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + } + break; + case 6: + case 7: + this.$ = $$[$0]; + break; + case 8: + this.$ = "nl"; + break; + case 11: + this.$ = $$[$0]; + break; + case 12: + const stateStmt = $$[$0 - 1]; + stateStmt.description = yy.trimColon($$[$0]); + this.$ = stateStmt; + break; + case 13: + this.$ = { stmt: "relation", state1: $$[$0 - 2], state2: $$[$0] }; + break; + case 14: + const relDescription = yy.trimColon($$[$0]); + this.$ = { stmt: "relation", state1: $$[$0 - 3], state2: $$[$0 - 1], description: relDescription }; + break; + case 18: + this.$ = { stmt: "state", id: $$[$0 - 3], type: "default", description: "", doc: $$[$0 - 1] }; + break; + case 19: + var id = $$[$0]; + var description = $$[$0 - 2].trim(); + if ($$[$0].match(":")) { + var parts = $$[$0].split(":"); + id = parts[0]; + description = [description, parts[1]]; + } + this.$ = { stmt: "state", id, type: "default", description }; + break; + case 20: + this.$ = { stmt: "state", id: $$[$0 - 3], type: "default", description: $$[$0 - 5], doc: $$[$0 - 1] }; + break; + case 21: + this.$ = { stmt: "state", id: $$[$0], type: "fork" }; + break; + case 22: + this.$ = { stmt: "state", id: $$[$0], type: "join" }; + break; + case 23: + this.$ = { stmt: "state", id: $$[$0], type: "choice" }; + break; + case 24: + this.$ = { stmt: "state", id: yy.getDividerId(), type: "divider" }; + break; + case 25: + this.$ = { stmt: "state", id: $$[$0 - 1].trim(), note: { position: $$[$0 - 2].trim(), text: $$[$0].trim() } }; + break; + case 28: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 29: + case 30: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 31: + case 32: + this.$ = { stmt: "classDef", id: $$[$0 - 1].trim(), classes: $$[$0].trim() }; + break; + case 33: + this.$ = { stmt: "applyClass", id: $$[$0 - 1].trim(), styleClass: $$[$0].trim() }; + break; + case 34: + yy.setDirection("TB"); + this.$ = { stmt: "dir", value: "TB" }; + break; + case 35: + yy.setDirection("BT"); + this.$ = { stmt: "dir", value: "BT" }; + break; + case 36: + yy.setDirection("RL"); + this.$ = { stmt: "dir", value: "RL" }; + break; + case 37: + yy.setDirection("LR"); + this.$ = { stmt: "dir", value: "LR" }; + break; + case 40: + case 41: + this.$ = { stmt: "state", id: $$[$0].trim(), type: "default", description: "" }; + break; + case 42: + this.$ = { stmt: "state", id: $$[$0 - 2].trim(), classes: [$$[$0].trim()], type: "default", description: "" }; + break; + case 43: + this.$ = { stmt: "state", id: $$[$0 - 2].trim(), classes: [$$[$0].trim()], type: "default", description: "" }; + break; + } + }, + table: [{ 3: 1, 4: $V0, 5: $V1, 6: $V2 }, { 1: [3] }, { 3: 5, 4: $V0, 5: $V1, 6: $V2 }, { 3: 6, 4: $V0, 5: $V1, 6: $V2 }, o([1, 4, 5, 15, 16, 18, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50], $V3, { 7: 7 }), { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3], 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 5]), { 9: 36, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 7]), o($Vq, [2, 8]), o($Vq, [2, 9]), o($Vq, [2, 10]), o($Vq, [2, 11], { 13: [1, 37], 14: [1, 38] }), o($Vq, [2, 15]), { 17: [1, 39] }, o($Vq, [2, 17], { 19: [1, 40] }), { 22: [1, 41] }, o($Vq, [2, 21]), o($Vq, [2, 22]), o($Vq, [2, 23]), o($Vq, [2, 24]), { 29: 42, 30: [1, 43], 52: [1, 44], 53: [1, 45] }, o($Vq, [2, 27]), { 33: [1, 46] }, { 35: [1, 47] }, o($Vq, [2, 30]), { 38: [1, 48], 40: [1, 49] }, { 42: [1, 50] }, o($Vr, [2, 40], { 51: [1, 51] }), o($Vr, [2, 41], { 51: [1, 52] }), o($Vq, [2, 34]), o($Vq, [2, 35]), o($Vq, [2, 36]), o($Vq, [2, 37]), o($Vq, [2, 6]), o($Vq, [2, 12]), { 12: 53, 23: $Va, 50: $Vp }, o($Vq, [2, 16]), o($Vs, $V3, { 7: 54 }), { 23: [1, 55] }, { 23: [1, 56] }, { 22: [1, 57] }, { 23: [2, 44] }, { 23: [2, 45] }, o($Vq, [2, 28]), o($Vq, [2, 29]), { 39: [1, 58] }, { 39: [1, 59] }, { 43: [1, 60] }, { 23: [1, 61] }, { 23: [1, 62] }, o($Vq, [2, 13], { 13: [1, 63] }), { 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 20: [1, 64], 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 19], { 19: [1, 65] }), { 30: [1, 66] }, { 23: [1, 67] }, o($Vq, [2, 31]), o($Vq, [2, 32]), o($Vq, [2, 33]), o($Vr, [2, 42]), o($Vr, [2, 43]), o($Vq, [2, 14]), o($Vq, [2, 18]), o($Vs, $V3, { 7: 68 }), o($Vq, [2, 25]), o($Vq, [2, 26]), { 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 20: [1, 69], 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 20])], + defaultActions: { 5: [2, 1], 6: [2, 2], 44: [2, 44], 45: [2, 45] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 40; + case 1: + return 44; + case 2: + return 45; + case 3: + return 46; + case 4: + return 47; + case 5: + break; + case 6: + break; + case 7: + return 5; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + this.pushState("SCALE"); + return 16; + case 13: + return 17; + case 14: + this.popState(); + break; + case 15: + this.begin("acc_title"); + return 32; + case 16: + this.popState(); + return "acc_title_value"; + case 17: + this.begin("acc_descr"); + return 34; + case 18: + this.popState(); + return "acc_descr_value"; + case 19: + this.begin("acc_descr_multiline"); + break; + case 20: + this.popState(); + break; + case 21: + return "acc_descr_multiline_value"; + case 22: + this.pushState("CLASSDEF"); + return 37; + case 23: + this.popState(); + this.pushState("CLASSDEFID"); + return "DEFAULT_CLASSDEF_ID"; + case 24: + this.popState(); + this.pushState("CLASSDEFID"); + return 38; + case 25: + this.popState(); + return 39; + case 26: + this.pushState("CLASS"); + return 41; + case 27: + this.popState(); + this.pushState("CLASS_STYLE"); + return 42; + case 28: + this.popState(); + return 43; + case 29: + this.pushState("SCALE"); + return 16; + case 30: + return 17; + case 31: + this.popState(); + break; + case 32: + this.pushState("STATE"); + break; + case 33: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 24; + case 34: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 25; + case 35: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -10).trim(); + return 26; + case 36: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 24; + case 37: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 25; + case 38: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -10).trim(); + return 26; + case 39: + return 44; + case 40: + return 45; + case 41: + return 46; + case 42: + return 47; + case 43: + this.pushState("STATE_STRING"); + break; + case 44: + this.pushState("STATE_ID"); + return "AS"; + case 45: + this.popState(); + return "ID"; + case 46: + this.popState(); + break; + case 47: + return "STATE_DESCR"; + case 48: + return 18; + case 49: + this.popState(); + break; + case 50: + this.popState(); + this.pushState("struct"); + return 19; + case 51: + break; + case 52: + this.popState(); + return 20; + case 53: + break; + case 54: + this.begin("NOTE"); + return 28; + case 55: + this.popState(); + this.pushState("NOTE_ID"); + return 52; + case 56: + this.popState(); + this.pushState("NOTE_ID"); + return 53; + case 57: + this.popState(); + this.pushState("FLOATING_NOTE"); + break; + case 58: + this.popState(); + this.pushState("FLOATING_NOTE_ID"); + return "AS"; + case 59: + break; + case 60: + return "NOTE_TEXT"; + case 61: + this.popState(); + return "ID"; + case 62: + this.popState(); + this.pushState("NOTE_TEXT"); + return 23; + case 63: + this.popState(); + yy_.yytext = yy_.yytext.substr(2).trim(); + return 30; + case 64: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 30; + case 65: + return 6; + case 66: + return 6; + case 67: + return 15; + case 68: + return 50; + case 69: + return 23; + case 70: + yy_.yytext = yy_.yytext.trim(); + return 13; + case 71: + return 14; + case 72: + return 27; + case 73: + return 51; + case 74: + return 5; + case 75: + return "INVALID"; + } + }, + rules: [/^(?:default\b)/i, /^(?:.*direction\s+TB[^\n]*)/i, /^(?:.*direction\s+BT[^\n]*)/i, /^(?:.*direction\s+RL[^\n]*)/i, /^(?:.*direction\s+LR[^\n]*)/i, /^(?:%%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[\n]+)/i, /^(?:[\s]+)/i, /^(?:((?!\n)\s)+)/i, /^(?:#[^\n]*)/i, /^(?:%[^\n]*)/i, /^(?:scale\s+)/i, /^(?:\d+)/i, /^(?:\s+width\b)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:classDef\s+)/i, /^(?:DEFAULT\s+)/i, /^(?:\w+\s+)/i, /^(?:[^\n]*)/i, /^(?:class\s+)/i, /^(?:(\w+)+((,\s*\w+)*))/i, /^(?:[^\n]*)/i, /^(?:scale\s+)/i, /^(?:\d+)/i, /^(?:\s+width\b)/i, /^(?:state\s+)/i, /^(?:.*<<fork>>)/i, /^(?:.*<<join>>)/i, /^(?:.*<<choice>>)/i, /^(?:.*\[\[fork\]\])/i, /^(?:.*\[\[join\]\])/i, /^(?:.*\[\[choice\]\])/i, /^(?:.*direction\s+TB[^\n]*)/i, /^(?:.*direction\s+BT[^\n]*)/i, /^(?:.*direction\s+RL[^\n]*)/i, /^(?:.*direction\s+LR[^\n]*)/i, /^(?:["])/i, /^(?:\s*as\s+)/i, /^(?:[^\n\{]*)/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:[^\n\s\{]+)/i, /^(?:\n)/i, /^(?:\{)/i, /^(?:%%(?!\{)[^\n]*)/i, /^(?:\})/i, /^(?:[\n])/i, /^(?:note\s+)/i, /^(?:left of\b)/i, /^(?:right of\b)/i, /^(?:")/i, /^(?:\s*as\s*)/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:[^\n]*)/i, /^(?:\s*[^:\n\s\-]+)/i, /^(?:\s*:[^:\n;]+)/i, /^(?:[\s\S]*?end note\b)/i, /^(?:stateDiagram\s+)/i, /^(?:stateDiagram-v2\s+)/i, /^(?:hide empty description\b)/i, /^(?:\[\*\])/i, /^(?:[^:\n\s\-\{]+)/i, /^(?:\s*:[^:\n;]+)/i, /^(?:-->)/i, /^(?:--)/i, /^(?::::)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "LINE": { "rules": [9, 10], "inclusive": false }, "struct": { "rules": [9, 10, 22, 26, 32, 39, 40, 41, 42, 51, 52, 53, 54, 68, 69, 70, 71, 72], "inclusive": false }, "FLOATING_NOTE_ID": { "rules": [61], "inclusive": false }, "FLOATING_NOTE": { "rules": [58, 59, 60], "inclusive": false }, "NOTE_TEXT": { "rules": [63, 64], "inclusive": false }, "NOTE_ID": { "rules": [62], "inclusive": false }, "NOTE": { "rules": [55, 56, 57], "inclusive": false }, "CLASS_STYLE": { "rules": [28], "inclusive": false }, "CLASS": { "rules": [27], "inclusive": false }, "CLASSDEFID": { "rules": [25], "inclusive": false }, "CLASSDEF": { "rules": [23, 24], "inclusive": false }, "acc_descr_multiline": { "rules": [20, 21], "inclusive": false }, "acc_descr": { "rules": [18], "inclusive": false }, "acc_title": { "rules": [16], "inclusive": false }, "SCALE": { "rules": [13, 14, 30, 31], "inclusive": false }, "ALIAS": { "rules": [], "inclusive": false }, "STATE_ID": { "rules": [45], "inclusive": false }, "STATE_STRING": { "rules": [46, 47], "inclusive": false }, "FORK_STATE": { "rules": [], "inclusive": false }, "STATE": { "rules": [9, 10, 33, 34, 35, 36, 37, 38, 43, 44, 48, 49, 50], "inclusive": false }, "ID": { "rules": [9, 10], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 15, 17, 19, 22, 26, 29, 32, 50, 54, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const DEFAULT_DIAGRAM_DIRECTION = "LR"; +const DEFAULT_NESTED_DOC_DIR = "TB"; +const STMT_STATE = "state"; +const STMT_RELATION = "relation"; +const STMT_CLASSDEF = "classDef"; +const STMT_APPLYCLASS = "applyClass"; +const DEFAULT_STATE_TYPE = "default"; +const DIVIDER_TYPE = "divider"; +const START_NODE = "[*]"; +const START_TYPE = "start"; +const END_NODE = START_NODE; +const END_TYPE = "end"; +const COLOR_KEYWORD = "color"; +const FILL_KEYWORD = "fill"; +const BG_FILL = "bgFill"; +const STYLECLASS_SEP = ","; +function newClassesList() { + return {}; +} +let direction = DEFAULT_DIAGRAM_DIRECTION; +let rootDoc = []; +let classes = newClassesList(); +const newDoc = () => { + return { + relations: [], + states: {}, + documents: {} + }; +}; +let documents = { + root: newDoc() +}; +let currentDocument = documents.root; +let startEndCount = 0; +let dividerCnt = 0; +const lineType = { + LINE: 0, + DOTTED_LINE: 1 +}; +const relationType = { + AGGREGATION: 0, + EXTENSION: 1, + COMPOSITION: 2, + DEPENDENCY: 3 +}; +const clone = (o) => JSON.parse(JSON.stringify(o)); +const setRootDoc = (o) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting root doc", o); + rootDoc = o; +}; +const getRootDoc = () => rootDoc; +const docTranslator = (parent, node, first) => { + if (node.stmt === STMT_RELATION) { + docTranslator(parent, node.state1, true); + docTranslator(parent, node.state2, false); + } else { + if (node.stmt === STMT_STATE) { + if (node.id === "[*]") { + node.id = first ? parent.id + "_start" : parent.id + "_end"; + node.start = first; + } else { + node.id = node.id.trim(); + } + } + if (node.doc) { + const doc = []; + let currentDoc = []; + let i; + for (i = 0; i < node.doc.length; i++) { + if (node.doc[i].type === DIVIDER_TYPE) { + const newNode = clone(node.doc[i]); + newNode.doc = clone(currentDoc); + doc.push(newNode); + currentDoc = []; + } else { + currentDoc.push(node.doc[i]); + } + } + if (doc.length > 0 && currentDoc.length > 0) { + const newNode = { + stmt: STMT_STATE, + id: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.I)(), + type: "divider", + doc: clone(currentDoc) + }; + doc.push(clone(newNode)); + node.doc = doc; + } + node.doc.forEach((docNode) => docTranslator(node, docNode, true)); + } + } +}; +const getRootDocV2 = () => { + docTranslator({ id: "root" }, { id: "root", doc: rootDoc }, true); + return { id: "root", doc: rootDoc }; +}; +const extract = (_doc) => { + let doc; + if (_doc.doc) { + doc = _doc.doc; + } else { + doc = _doc; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info(doc); + clear(true); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Extract", doc); + doc.forEach((item) => { + switch (item.stmt) { + case STMT_STATE: + addState( + item.id.trim(), + item.type, + item.doc, + item.description, + item.note, + item.classes, + item.styles, + item.textStyles + ); + break; + case STMT_RELATION: + addRelation(item.state1, item.state2, item.description); + break; + case STMT_CLASSDEF: + addStyleClass(item.id.trim(), item.classes); + break; + case STMT_APPLYCLASS: + setCssClass(item.id.trim(), item.styleClass); + break; + } + }); +}; +const addState = function(id, type = DEFAULT_STATE_TYPE, doc = null, descr = null, note = null, classes2 = null, styles2 = null, textStyles = null) { + const trimmedId = id == null ? void 0 : id.trim(); + if (currentDocument.states[trimmedId] === void 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Adding state ", trimmedId, descr); + currentDocument.states[trimmedId] = { + id: trimmedId, + descriptions: [], + type, + doc, + note, + classes: [], + styles: [], + textStyles: [] + }; + } else { + if (!currentDocument.states[trimmedId].doc) { + currentDocument.states[trimmedId].doc = doc; + } + if (!currentDocument.states[trimmedId].type) { + currentDocument.states[trimmedId].type = type; + } + } + if (descr) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state description", trimmedId, descr); + if (typeof descr === "string") { + addDescription(trimmedId, descr.trim()); + } + if (typeof descr === "object") { + descr.forEach((des) => addDescription(trimmedId, des.trim())); + } + } + if (note) { + currentDocument.states[trimmedId].note = note; + currentDocument.states[trimmedId].note.text = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText( + currentDocument.states[trimmedId].note.text, + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.c)() + ); + } + if (classes2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state classes", trimmedId, classes2); + const classesList = typeof classes2 === "string" ? [classes2] : classes2; + classesList.forEach((cssClass) => setCssClass(trimmedId, cssClass.trim())); + } + if (styles2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state styles", trimmedId, styles2); + const stylesList = typeof styles2 === "string" ? [styles2] : styles2; + stylesList.forEach((style) => setStyle(trimmedId, style.trim())); + } + if (textStyles) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state styles", trimmedId, styles2); + const textStylesList = typeof textStyles === "string" ? [textStyles] : textStyles; + textStylesList.forEach((textStyle) => setTextStyle(trimmedId, textStyle.trim())); + } +}; +const clear = function(saveCommon) { + documents = { + root: newDoc() + }; + currentDocument = documents.root; + startEndCount = 0; + classes = newClassesList(); + if (!saveCommon) { + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.v)(); + } +}; +const getState = function(id) { + return currentDocument.states[id]; +}; +const getStates = function() { + return currentDocument.states; +}; +const logDocuments = function() { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Documents = ", documents); +}; +const getRelations = function() { + return currentDocument.relations; +}; +function startIdIfNeeded(id = "") { + let fixedId = id; + if (id === START_NODE) { + startEndCount++; + fixedId = `${START_TYPE}${startEndCount}`; + } + return fixedId; +} +function startTypeIfNeeded(id = "", type = DEFAULT_STATE_TYPE) { + return id === START_NODE ? START_TYPE : type; +} +function endIdIfNeeded(id = "") { + let fixedId = id; + if (id === END_NODE) { + startEndCount++; + fixedId = `${END_TYPE}${startEndCount}`; + } + return fixedId; +} +function endTypeIfNeeded(id = "", type = DEFAULT_STATE_TYPE) { + return id === END_NODE ? END_TYPE : type; +} +function addRelationObjs(item1, item2, relationTitle) { + let id1 = startIdIfNeeded(item1.id.trim()); + let type1 = startTypeIfNeeded(item1.id.trim(), item1.type); + let id2 = startIdIfNeeded(item2.id.trim()); + let type2 = startTypeIfNeeded(item2.id.trim(), item2.type); + addState( + id1, + type1, + item1.doc, + item1.description, + item1.note, + item1.classes, + item1.styles, + item1.textStyles + ); + addState( + id2, + type2, + item2.doc, + item2.description, + item2.note, + item2.classes, + item2.styles, + item2.textStyles + ); + currentDocument.relations.push({ + id1, + id2, + relationTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText(relationTitle, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.c)()) + }); +} +const addRelation = function(item1, item2, title) { + if (typeof item1 === "object") { + addRelationObjs(item1, item2, title); + } else { + const id1 = startIdIfNeeded(item1.trim()); + const type1 = startTypeIfNeeded(item1); + const id2 = endIdIfNeeded(item2.trim()); + const type2 = endTypeIfNeeded(item2); + addState(id1, type1); + addState(id2, type2); + currentDocument.relations.push({ + id1, + id2, + title: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText(title, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.c)()) + }); + } +}; +const addDescription = function(id, descr) { + const theState = currentDocument.states[id]; + const _descr = descr.startsWith(":") ? descr.replace(":", "").trim() : descr; + theState.descriptions.push(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText(_descr, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.c)())); +}; +const cleanupLabel = function(label) { + if (label.substring(0, 1) === ":") { + return label.substr(2).trim(); + } else { + return label.trim(); + } +}; +const getDividerId = () => { + dividerCnt++; + return "divider-id-" + dividerCnt; +}; +const addStyleClass = function(id, styleAttributes = "") { + if (classes[id] === void 0) { + classes[id] = { id, styles: [], textStyles: [] }; + } + const foundClass = classes[id]; + if (styleAttributes !== void 0 && styleAttributes !== null) { + styleAttributes.split(STYLECLASS_SEP).forEach((attrib) => { + const fixedAttrib = attrib.replace(/([^;]*);/, "$1").trim(); + if (attrib.match(COLOR_KEYWORD)) { + const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL); + const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD); + foundClass.textStyles.push(newStyle2); + } + foundClass.styles.push(fixedAttrib); + }); + } +}; +const getClasses = function() { + return classes; +}; +const setCssClass = function(itemIds, cssClassName) { + itemIds.split(",").forEach(function(id) { + let foundState = getState(id); + if (foundState === void 0) { + const trimmedId = id.trim(); + addState(trimmedId); + foundState = getState(trimmedId); + } + foundState.classes.push(cssClassName); + }); +}; +const setStyle = function(itemId, styleText) { + const item = getState(itemId); + if (item !== void 0) { + item.textStyles.push(styleText); + } +}; +const setTextStyle = function(itemId, cssClassName) { + const item = getState(itemId); + if (item !== void 0) { + item.textStyles.push(cssClassName); + } +}; +const getDirection = () => direction; +const setDirection = (dir) => { + direction = dir; +}; +const trimColon = (str) => str && str[0] === ":" ? str.substr(1).trim() : str.trim(); +const db = { + getConfig: () => (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.c)().state, + addState, + clear, + getState, + getStates, + getRelations, + getClasses, + getDirection, + addRelation, + getDividerId, + setDirection, + cleanupLabel, + lineType, + relationType, + logDocuments, + getRootDoc, + setRootDoc, + getRootDocV2, + extract, + trimColon, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.g, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.s, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.a, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.b, + addStyleClass, + setCssClass, + addDescription, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_0__.t +}; +const getStyles = (options) => ` +defs #statediagram-barbEnd { + fill: ${options.transitionColor}; + stroke: ${options.transitionColor}; + } +g.stateGroup text { + fill: ${options.nodeBorder}; + stroke: none; + font-size: 10px; +} +g.stateGroup text { + fill: ${options.textColor}; + stroke: none; + font-size: 10px; + +} +g.stateGroup .state-title { + font-weight: bolder; + fill: ${options.stateLabelColor}; +} + +g.stateGroup rect { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; +} + +g.stateGroup line { + stroke: ${options.lineColor}; + stroke-width: 1; +} + +.transition { + stroke: ${options.transitionColor}; + stroke-width: 1; + fill: none; +} + +.stateGroup .composit { + fill: ${options.background}; + border-bottom: 1px +} + +.stateGroup .alt-composit { + fill: #e0e0e0; + border-bottom: 1px +} + +.state-note { + stroke: ${options.noteBorderColor}; + fill: ${options.noteBkgColor}; + + text { + fill: ${options.noteTextColor}; + stroke: none; + font-size: 10px; + } +} + +.stateLabel .box { + stroke: none; + stroke-width: 0; + fill: ${options.mainBkg}; + opacity: 0.5; +} + +.edgeLabel .label rect { + fill: ${options.labelBackgroundColor}; + opacity: 0.5; +} +.edgeLabel .label text { + fill: ${options.transitionLabelColor || options.tertiaryTextColor}; +} +.label div .edgeLabel { + color: ${options.transitionLabelColor || options.tertiaryTextColor}; +} + +.stateLabel text { + fill: ${options.stateLabelColor}; + font-size: 10px; + font-weight: bold; +} + +.node circle.state-start { + fill: ${options.specialStateColor}; + stroke: ${options.specialStateColor}; +} + +.node .fork-join { + fill: ${options.specialStateColor}; + stroke: ${options.specialStateColor}; +} + +.node circle.state-end { + fill: ${options.innerEndBackground}; + stroke: ${options.background}; + stroke-width: 1.5 +} +.end-state-inner { + fill: ${options.compositeBackground || options.background}; + // stroke: ${options.background}; + stroke-width: 1.5 +} + +.node rect { + fill: ${options.stateBkg || options.mainBkg}; + stroke: ${options.stateBorder || options.nodeBorder}; + stroke-width: 1px; +} +.node polygon { + fill: ${options.mainBkg}; + stroke: ${options.stateBorder || options.nodeBorder};; + stroke-width: 1px; +} +#statediagram-barbEnd { + fill: ${options.lineColor}; +} + +.statediagram-cluster rect { + fill: ${options.compositeTitleBackground}; + stroke: ${options.stateBorder || options.nodeBorder}; + stroke-width: 1px; +} + +.cluster-label, .nodeLabel { + color: ${options.stateLabelColor}; +} + +.statediagram-cluster rect.outer { + rx: 5px; + ry: 5px; +} +.statediagram-state .divider { + stroke: ${options.stateBorder || options.nodeBorder}; +} + +.statediagram-state .title-state { + rx: 5px; + ry: 5px; +} +.statediagram-cluster.statediagram-cluster .inner { + fill: ${options.compositeBackground || options.background}; +} +.statediagram-cluster.statediagram-cluster-alt .inner { + fill: ${options.altBackground ? options.altBackground : "#efefef"}; +} + +.statediagram-cluster .inner { + rx:0; + ry:0; +} + +.statediagram-state rect.basic { + rx: 5px; + ry: 5px; +} +.statediagram-state rect.divider { + stroke-dasharray: 10,10; + fill: ${options.altBackground ? options.altBackground : "#efefef"}; +} + +.note-edge { + stroke-dasharray: 5; +} + +.statediagram-note rect { + fill: ${options.noteBkgColor}; + stroke: ${options.noteBorderColor}; + stroke-width: 1px; + rx: 0; + ry: 0; +} +.statediagram-note rect { + fill: ${options.noteBkgColor}; + stroke: ${options.noteBorderColor}; + stroke-width: 1px; + rx: 0; + ry: 0; +} + +.statediagram-note text { + fill: ${options.noteTextColor}; +} + +.statediagram-note .nodeLabel { + color: ${options.noteTextColor}; +} +.statediagram .edgeLabel { + color: red; // ${options.noteTextColor}; +} + +#dependencyStart, #dependencyEnd { + fill: ${options.lineColor}; + stroke: ${options.lineColor}; + stroke-width: 1; +} + +.statediagramTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; +} +`; +const styles = getStyles; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/699c0e5c.f4efe239.js b/assets/js/699c0e5c.f4efe239.js new file mode 100644 index 0000000000..9dee851bdd --- /dev/null +++ b/assets/js/699c0e5c.f4efe239.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3725],{28052:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>l});var i=s(74848),n=s(28453);const o={title:"Decisions for the Volume Type Standard",type:"Decision Record",status:"Draft",track:"IaaS"},a=void 0,r={id:"scs-0111-v1-volume-type-decisions",title:"Decisions for the Volume Type Standard",description:"Introduction",source:"@site/standards/scs-0111-v1-volume-type-decisions.md",sourceDirName:".",slug:"/scs-0111-v1-volume-type-decisions",permalink:"/standards/scs-0111-v1-volume-type-decisions",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Decisions for the Volume Type Standard",type:"Decision Record",status:"Draft",track:"IaaS"},sidebar:"standards",previous:{title:"scs-0111: Decisions for the Volume Type Standard",permalink:"/standards/iaas/scs-0111"},next:{title:"scs-0113: Security Groups Decision Record",permalink:"/standards/iaas/scs-0113"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Encryption",id:"encryption",level:4},{value:"Backend Name",id:"backend-name",level:4},{value:"Availability Zones",id:"availability-zones",level:4},{value:"Multiattach",id:"multiattach",level:4},{value:"Replication",id:"replication",level:4},{value:"QoS",id:"qos",level:4},{value:"Other Backend-specific Highlights",id:"other-backend-specific-highlights",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2}];function c(e){const t={a:"a",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"Volumes in OpenStack are virtual drives. They are managed by the storage service Cinder, which abstracts creation and usage of many different storage backends. While it is possible to use a backend like lvm which can reside on the same host as the hypervisor, the SCS wants to make a more clear differentiation between volumes and the ephemeral storage of a virtual machine. For all SCS deployments we want to assume that volumes are always residing in a storage backend that is NOT on the same host as a hypervisor - in short terms: Volumes are network storage. Ephemeral storage on the other hand is the only storage residing on a compute host. It is created by creating a VM directly from an Image and is automatically los as soon as the VM cease to exist. Volumes on the other hand have to be created from Images and only after that can be used for VMs. They are persistent and will remain in the last state a VM has written on them before they cease to exit. Being persistent and not relying on the host where the VM resides, Volumes can easily be attached to another VM in case of a node outage and VMs be migrated way more easily, because only metadata and data in RAM has to be shifted to another host, accelerating any migration or evacuation of a VM."}),"\n",(0,i.jsx)(t.p,{children:"Volume Types are used to classify volumes and provide a basic decision for what kind of volume should be created. These volume types can sometimes very be backend-specific and it might be hard for a user to choose the most suitable volume type, if there is more than one default type. Nevertheless the most of configuration is done in the backends themself, so volume types only work as a rough classification."}),"\n",(0,i.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:"We want to standardize a few varieties of volume types. While a user can choose simple things like size when creating a volume, Volume Types define a few broader aspects of volume. Encryption of volumes for example is solely decided by the volume type. And whether the volume will be replicated is a mix between definiton in the volume type and backend specific configuration, but it's visiblity can only be reached in the volume type."}),"\n",(0,i.jsx)(t.p,{children:"In General: what the different volume types are capable of is highly dependend on both the used backend and the configurations of OpenStack. A few options are worth being at least recommended."}),"\n",(0,i.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsx)(t.p,{children:"We want to have a discoverable Standard. So there should be no naming conventions as per request by operators."}),"\n",(0,i.jsx)(t.p,{children:"This first decision will have impacts on upstream OpenStack development, as those things, that would be nice to discover, may not be currently dicoverable by users or not at all."}),"\n",(0,i.jsx)(t.p,{children:"There are severel aspects of volume types, which will be discussed in the following:"}),"\n",(0,i.jsx)(t.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,i.jsx)(t.h4,{id:"encryption",children:"Encryption"}),"\n",(0,i.jsx)(t.p,{children:"Encryption for volumes is an option which has to be configured within the volume type. As an admin it is possible to set encryption-provider, key size, cipher and control location. As an admin it is also currently possible to see these configurations in a volume type with list and show commands. A user should not see these parameters in detail, but a boolean value that descibes whether encryption is used or not. Currently this is not possible in upstream OpenStack."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Conclusion"}),": This is a solid aspect to be standardized. But it will need work on OpenStack, to have a boolean value presented to the users."]}),"\n",(0,i.jsx)(t.h4,{id:"backend-name",children:"Backend Name"}),"\n",(0,i.jsx)(t.p,{children:"OpenStack Cinder works with a lot of different backends. They all have some kind of special features, which might be attractive for a user. But showing the name of the backend to users is also considered a security risk by Cinder developers. Overall it is always an option to make users aware of special features through the name and description of a volume type and sometimes even through extra_specs."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Conclusion"}),": This should not be standardized."]}),"\n",(0,i.jsx)(t.h4,{id:"availability-zones",children:"Availability Zones"}),"\n",(0,i.jsx)(t.p,{children:"Availability Zones are used in Nova and Cinder seperatly to provide an often also physical separation of compute hosts or storage nodes. This leads to two options to consider:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Multiple Volume AZs: This might be used if there are different backends present in one IaaS structure. The different volume types are usually used for the different volume AZs. This makes migration between those AZs only be possible for administrators."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"Volume Types that can be attached to multiple Nova Azs: This option can be seen in the extra specs of a volume type also by normal users. Another option is to use backend specific options, as for example with ceph that directly interacts with nova for this. In that case there will not be any visible extra specs for the users."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"Another question is how many providers use one of these options or both."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Conclusion"}),": The first part doesn't make much sense to standardize, as migration between the volume types can only be done by admins. However the second part might be noteable, but due to the variety of configuration options very hard to standardize."]}),"\n",(0,i.jsx)(t.h4,{id:"multiattach",children:"Multiattach"}),"\n",(0,i.jsx)(t.p,{children:"It is possible in a few backends to attach a volume to multiple VMs. This has to be configured in the Volume Type and this information is also accessable for users. Nevertheless this option also needs a lot of work from users, as those types of volumes have to have a file system, that is capable of multiattach. Many providers don't provide multiattach."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Conclusion"}),": It might be noteable, that this already is a discoverable option."]}),"\n",(0,i.jsx)(t.h4,{id:"replication",children:"Replication"}),"\n",(0,i.jsx)(t.p,{children:"Replication states, whether or not there are multiple replicas of a volume. Thus answers the question, whether the data could survive a node outage. Again there are different ways to achive replicated volumes. It can either be defined in the volume type and is discoverable also by normal users or it is configured in the backend. The last option is usually used with ceph for example. This makes it hard to discover, whether a volume is replicated or not. Another point is the number of replicas, that exist."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Conclusion"}),": Replication is a good option to be standardized. Whether this should be done as a boolean option or if the number of replicas is also something users need to know should still be discussed. Nevertheless due to the different options to configure replication this will be quite complex."]}),"\n",(0,i.jsx)(t.h4,{id:"qos",children:"QoS"}),"\n",(0,i.jsx)(t.p,{children:"Quality of Service parameters can be stated in a volume qos object. These objects can then be associated to a volume type (or directly to a volume as an admin only option). But this is optional and thus even good or very good volume QoS parameters that are aquired through hardware configuration and storage parameters, might go by unmentioned.\nFurthermore the indirection makes it harder to discover the qos for a volume type. Only admins will see the associated qos ID and will have to take a closer look at the qos after discovering the volume type. PLUS: there can only be one qos association for one volume type. But a qos can be used for multiple volumes."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Conclusion"}),": The benefit of displaying qos parameters is clear, thus this option should be noted. But are volume qos objects widely used? If not, standardization process would be too much work."]}),"\n",(0,i.jsx)(t.h4,{id:"other-backend-specific-highlights",children:"Other Backend-specific Highlights"}),"\n",(0,i.jsx)(t.p,{children:"While every option above described things, that can at least be partly or for admins only visible in volume types, there are many different configuration options in hardware and backend providers can make use of. It is sadly not possible to get them into the volume type directly, but we recommend, that notable configurations are written into the description of a volume type to achieve transparency for the users."}),"\n",(0,i.jsx)(t.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"How often are the different options used by providers and users respectively? Especially important for qos and replication!"}),"\n",(0,i.jsx)(t.li,{children:"Regarding Replication: Is the number of replicas needed by users and is it okay for providers to provide this information?"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Aspect"}),(0,i.jsx)(t.th,{children:"Standardize?"}),(0,i.jsx)(t.th,{children:"Discoverability"}),(0,i.jsx)(t.th,{children:"other Things"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"encryption"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Recommended"})}),(0,i.jsx)(t.td,{children:"work needed"}),(0,i.jsx)(t.td,{children:"extra_spec: encrypted=True/False"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Backend name"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"AZs"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"describe as optional and backend-dependend"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"multiattach"}),(0,i.jsx)(t.td,{children:"-"}),(0,i.jsx)(t.td,{children:"yes"}),(0,i.jsx)(t.td,{children:"describe as optional"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Replication"}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Recommended"})}),(0,i.jsx)(t.td,{children:"lot of work"}),(0,i.jsx)(t.td,{children:"either get from backend to OS or as extra_spec defined by deployer"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Number of Replicas, etc"}),(0,i.jsx)(t.td,{children:"?"}),(0,i.jsx)(t.td,{children:"lot of work"}),(0,i.jsx)(t.td,{children:"optional, work on it after Replication is standardized"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Volume QoS"}),(0,i.jsx)(t.td,{children:"?"}),(0,i.jsx)(t.td,{children:"admin only"}),(0,i.jsx)(t.td,{children:"needs further discussion, should be at least described as optional"})]})]})]}),"\n",(0,i.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.a,{href:"https://input.scs.community/JnaY5i70R_yc7JkSNVtlKQ",children:"This is an etherpad"})," with a further look into the Options and a few examples."]})]})}function h(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>r});var i=s(96540);const n={},o=i.createContext(n);function a(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/69b09ea9.8e83441e.js b/assets/js/69b09ea9.8e83441e.js new file mode 100644 index 0000000000..9281b2805e --- /dev/null +++ b/assets/js/69b09ea9.8e83441e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8462],{26677:s=>{s.exports=JSON.parse('{"label":"community","permalink":"/blog/tags/community","allTagsPath":"/blog/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/6a0c14a5.07eefbbf.js b/assets/js/6a0c14a5.07eefbbf.js new file mode 100644 index 0000000000..8367c3a5c1 --- /dev/null +++ b/assets/js/6a0c14a5.07eefbbf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8834],{33285:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>l});var s=a(74848),r=a(28453);const o={sidebar_label:"Flavor Manager",sidebar_position:51},i="Flavor Manager",t={id:"iaas/guides/operations-guide/openstack/tools/flavor-manager",title:"Flavor Manager",description:"Overview",source:"@site/docs/02-iaas/guides/operations-guide/openstack/tools/flavor-manager.md",sourceDirName:"02-iaas/guides/operations-guide/openstack/tools",slug:"/iaas/guides/operations-guide/openstack/tools/flavor-manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/flavor-manager.md",tags:[],version:"current",sidebarPosition:51,frontMatter:{sidebar_label:"Flavor Manager",sidebar_position:51},sidebar:"docs",previous:{title:"Automated updates",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update"},next:{title:"Resource Manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager"}},d={},l=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Usage",id:"usage",level:2},{value:"Definitions",id:"definitions",level:2},{value:"Name parser and generator",id:"name-parser-and-generator",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"flavor-manager",children:"Flavor Manager"}),"\n",(0,s.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(n.p,{children:["The OpenStack Flavor Manager manages the creation, modification, and removal of flavors.\nIt operates as a facilitator that orchestrates compute flavors in alignment\nwith the standard ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS-0100: Flavor Naming"}),"\nby utilizing YAML files provided by the SCS project."]}),"\n",(0,s.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,s.jsxs)(n.p,{children:["The OpenStack Flavor Manager can be used via the OSISM CLI. This is the preferred way to use it.\nNo installation is then required. It is used via ",(0,s.jsx)(n.code,{children:"osism manage flavors"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["For use independent of OSISM install the ",(0,s.jsx)(n.code,{children:"openstack-flavor-manager"})," package with pip. It is likely\nthat additional dependencies such as ",(0,s.jsx)(n.code,{children:"pkg-config"})," or ",(0,s.jsx)(n.code,{children:"libssl-dev"})," must be installed in advance."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ pip install openstack-flavor-manager\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Or clone the repository ",(0,s.jsx)(n.a,{href:"https://github.com/osism/openstack-flavor-manager",children:"osism/openstack-flavor-manager"}),"\nand use the OpenStack Flavor Manager from source with tox."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ tox -- --help\n"})}),"\n",(0,s.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,s.jsxs)(n.p,{children:["There must be a ",(0,s.jsx)(n.code,{children:"clouds.yml"})," and a ",(0,s.jsx)(n.code,{children:"secure.yml"})," file in the directory where the OpenStack Flavor Manager\nwill be executed. When using the OSISM CLI, the files are expected in ",(0,s.jsx)(n.code,{children:"environments/openstack"}),"\nin your configuration repository."]}),"\n",(0,s.jsxs)(n.p,{children:["The cloud profile to be used can be specified via the optional ",(0,s.jsx)(n.code,{children:"--cloud"})," parameter.\nBy default the cloud profile with the name ",(0,s.jsx)(n.code,{children:"admin"})," is used. It must be possible to create and delete\nflavors with the used cloud credentials."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ openstack-flavor-manager --help\n\n Usage: openstack-flavor-manager [OPTIONS]\n\n\u256d\u2500 Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 --name TEXT Name of flavor definitions. [default: scs] \u2502\n\u2502 --debug Enable debug logging. \u2502\n\u2502 --cloud TEXT Cloud name in clouds.yaml. [default: admin] \u2502\n\u2502 --recommended Create recommended flavors. \u2502\n\u2502 --help Show this message and exit. \u2502\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n"})}),"\n",(0,s.jsxs)(n.p,{children:["To create the mandatory flavors by the ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS-0100: Flavor Naming"}),"\nstandard, you run:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ openstack-flavor-manager\n"})}),"\n",(0,s.jsx)(n.p,{children:"To create the recommended flavors by the SCS Flavor Naming Standard, you run:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ openstack-flavor-manager --recommended\n"})}),"\n",(0,s.jsx)(n.p,{children:"The output should look like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"2023-09-20 13:03:14 | INFO | Flavor SCS-1V-4 created\n2023-09-20 13:03:14 | INFO | Flavor SCS-2V-8 created\n2023-09-20 13:03:14 | INFO | Flavor SCS-4V-16 created\n2023-09-20 13:03:14 | INFO | Flavor SCS-8V-32 created\n...\n"})}),"\n",(0,s.jsx)(n.p,{children:"All recommended flavors are now be available in your OpenStack environment.\nCheck yourself by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ openstack --os-cloud admin flavor list\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ openstack --os-cloud admin flavor show SCS-2V-4-20s\n+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+\n| Field | Value |\n+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+\n| OS-FLV-DISABLED:disabled | False |\n| OS-FLV-EXT-DATA:ephemeral | 0 |\n| access_project_ids | None |\n| description | None |\n| disk | 20 |\n| id | 652e3a6c-330e-4ee3-922b-b49c3c093062 |\n| name | SCS-2V-4-20s |\n| os-flavor-access:is_public | True |\n| properties | hw_rng:allowed='true', scs:cpu-type='shared-core', scs:disk0-type='ssd', scs:name-v1='SCS-2V:4:20s', scs:name-v2='SCS-2V-4-20s' |\n| ram | 4096 |\n| rxtx_factor | 1.0 |\n| swap | 0 |\n| vcpus | 2 |\n+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+\n"})}),"\n",(0,s.jsx)(n.h2,{id:"definitions",children:"Definitions"}),"\n",(0,s.jsxs)(n.p,{children:["There are two flavor definitions available by default. One for\n",(0,s.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/iaas/SCS-Spec.MandatoryFlavors.verbose.yaml",children:"SCS"}),"\nand one for ",(0,s.jsx)(n.a,{href:"https://raw.githubusercontent.com/osism/openstack-flavor-manager/main/flavors.yaml",children:"OSISM"}),".\nEach definition has its own set of mandatory and recommended flavors. The definition of OSISM contains\nall definitions of SCS as well as some others."]}),"\n",(0,s.jsxs)(n.p,{children:["To run the OpenStack Flavor Manager with a specific definition, either ",(0,s.jsx)(n.code,{children:"scs"})," or ",(0,s.jsx)(n.code,{children:"osism"}),",\nuse the optional ",(0,s.jsx)(n.code,{children:"--name"})," parameter. By default the ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS-0100: Flavor Naming"}),"\nstandard definition will be used."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ openstack-flavor-manager --name osism\n"})}),"\n",(0,s.jsx)(n.h2,{id:"name-parser-and-generator",children:"Name parser and generator"}),"\n",(0,s.jsxs)(n.p,{children:["A generator and parser for flavor names according to the SCS standard is available on\n",(0,s.jsx)(n.a,{href:"https://flavors.scs.community",children:"flavors.scs.community"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The flavor name ",(0,s.jsx)(n.code,{children:"SCS-2V-4-20s"})," is inserted in field ",(0,s.jsx)(n.code,{children:"Flavor name"}),":"]}),"\n",(0,s.jsx)("img",{src:a(54965).A,width:"50%"}),"\n",(0,s.jsxs)(n.p,{children:["The flavor ",(0,s.jsx)(n.code,{children:"SCS-2V-4-20s"})," translated is\n",(0,s.jsx)(n.code,{children:"2 generic x86-64 vCPUs with 4.0 GiB RAM and SSD 20GB root volume"}),":"]}),"\n",(0,s.jsx)("img",{src:a(69214).A,width:"50%"})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},54965:(e,n,a)=>{a.d(n,{A:()=>s});const s=a.p+"assets/images/flavors-1-bd8d085759b264b3e58020d1390803fd.png"},69214:(e,n,a)=>{a.d(n,{A:()=>s});const s=a.p+"assets/images/flavors-2-d9a87ab2a63ed62ace4303facc069b8b.png"},28453:(e,n,a)=>{a.d(n,{R:()=>i,x:()=>t});var s=a(96540);const r={},o=s.createContext(r);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6ad9ab45.c14e6bfd.js b/assets/js/6ad9ab45.c14e6bfd.js new file mode 100644 index 0000000000..ebcc3f73f3 --- /dev/null +++ b/assets/js/6ad9ab45.c14e6bfd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[942],{20770:(s,e,t)=>{t.r(e),t.d(e,{assets:()=>o,contentTitle:()=>d,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>c});var n=t(74848),a=t(28453);const r={},d="scs-0103: SCS Standard Flavors and Properties",i={id:"iaas/scs-0103",title:"scs-0103: SCS Standard Flavors and Properties",description:"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack",source:"@site/standards/iaas/scs-0103.md",sourceDirName:"iaas",slug:"/iaas/scs-0103",permalink:"/standards/iaas/scs-0103",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"SCS Image Metadata Standard",permalink:"/standards/scs-0102-v1-image-metadata"},next:{title:"SCS Standard Flavors and Properties",permalink:"/standards/scs-0103-v1-standard-flavors"}},o={},c=[];function l(s){const e={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"scs-0103-scs-standard-flavors-and-properties",children:"scs-0103: SCS Standard Flavors and Properties"}),"\n",(0,n.jsxs)(e.p,{children:["The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack\nenvironments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific\nconfigurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs",":name-vN",", scs",":cpu-type",",\nand scs",":diskN-type"," to detail the flavor's specifications. This standard facilitates guaranteed availability and\nconsistency of flavors, simplifying the deployment process for DevOps teams."]}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:"Version"}),(0,n.jsx)(e.th,{children:"Type"}),(0,n.jsx)(e.th,{children:"State"}),(0,n.jsx)(e.th,{children:"stabilized"}),(0,n.jsx)(e.th,{children:"deprecated"})]})}),(0,n.jsx)(e.tbody,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0103-v1-standard-flavors",children:"scs-0103-v1"})}),(0,n.jsx)(e.td,{children:"Standard"}),(0,n.jsx)(e.td,{children:"Stable"}),(0,n.jsx)(e.td,{children:"2024-02-08"}),(0,n.jsx)(e.td,{children:"-"})]})})]})]})}function p(s={}){const{wrapper:e}={...(0,a.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(l,{...s})}):l(s)}},28453:(s,e,t)=>{t.d(e,{R:()=>d,x:()=>i});var n=t(96540);const a={},r=n.createContext(a);function d(s){const e=n.useContext(r);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function i(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(a):s.components||a:d(s.components),n.createElement(r.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/6bcd11f8.4dfd4edc.js b/assets/js/6bcd11f8.4dfd4edc.js new file mode 100644 index 0000000000..c3824abaab --- /dev/null +++ b/assets/js/6bcd11f8.4dfd4edc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8502],{10332:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var t=o(74848),c=o(28453);const s={},i="Keycloak",a={id:"iaas/guides/concept-guide/components/keycloak",title:"Keycloak",description:"Lifecycle Management of Keycloak in OSISM",source:"@site/docs/02-iaas/guides/concept-guide/components/keycloak.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/keycloak",permalink:"/docs/iaas/guides/concept-guide/components/keycloak",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/keycloak.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"K3S",permalink:"/docs/iaas/guides/concept-guide/components/k3s"},next:{title:"Netdata",permalink:"/docs/iaas/guides/concept-guide/components/netdata"}},d={},l=[{value:"Lifecycle Management of Keycloak in OSISM",id:"lifecycle-management-of-keycloak-in-osism",level:2}];function r(e){const n={h1:"h1",h2:"h2",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"keycloak",children:"Keycloak"}),"\n",(0,t.jsx)(n.h2,{id:"lifecycle-management-of-keycloak-in-osism",children:"Lifecycle Management of Keycloak in OSISM"})]})}function u(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(r,{...e})}):r(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>a});var t=o(96540);const c={},s=t.createContext(c);function i(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6c33bb99.6d7973e3.js b/assets/js/6c33bb99.6d7973e3.js new file mode 100644 index 0000000000..175e8112e5 --- /dev/null +++ b/assets/js/6c33bb99.6d7973e3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4810],{26132:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>t});var i=s(74848),d=s(28453);const c={sidebar_label:"Ceph",sidebar_position:30},r="Ceph",a={id:"iaas/guides/configuration-guide/ceph",title:"Ceph",description:"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/",source:"@site/docs/02-iaas/guides/configuration-guide/ceph.md",sourceDirName:"02-iaas/guides/configuration-guide",slug:"/iaas/guides/configuration-guide/ceph",permalink:"/docs/iaas/guides/configuration-guide/ceph",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/ceph.md",tags:[],version:"current",sidebarPosition:30,frontMatter:{sidebar_label:"Ceph",sidebar_position:30},sidebar:"docs",previous:{title:"Self-signed certificates",permalink:"/docs/iaas/guides/configuration-guide/self-signed-certificates"},next:{title:"OpenStack",permalink:"/docs/iaas/guides/configuration-guide/openstack/"}},o={},t=[{value:"Unique Identifier",id:"unique-identifier",level:2},{value:"Client",id:"client",level:2},{value:"Swappiness",id:"swappiness",level:2},{value:"RGW service",id:"rgw-service",level:2},{value:"Extra pools",id:"extra-pools",level:2},{value:"LVM devices",id:"lvm-devices",level:2},{value:"Full examples",id:"full-examples",level:3},{value:"Use of dedicated DB devices",id:"use-of-dedicated-db-devices",level:4},{value:"Use of partitions",id:"use-of-partitions",level:4},{value:"Dashboard",id:"dashboard",level:2},{value:"Configuring the openstack loadbalancer to expose the ceph dashboard",id:"configuring-the-openstack-loadbalancer-to-expose-the-ceph-dashboard",level:3},{value:"Second Ceph cluster",id:"second-ceph-cluster",level:2},{value:"Resource limits",id:"resource-limits",level:2},{value:"CPU Pinning",id:"cpu-pinning",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"ceph",children:"Ceph"}),"\n",(0,i.jsxs)(n.p,{children:["The official Ceph documentation is located on ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/rados/configuration/",children:"https://docs.ceph.com/en/latest/rados/configuration/"})]}),"\n",(0,i.jsxs)(n.p,{children:["It is ",(0,i.jsx)(n.strong,{children:"strongly advised"})," to use the documentation for the version being used."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Pacific - ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/pacific/rados/configuration/",children:"https://docs.ceph.com/en/pacific/rados/configuration/"})]}),"\n",(0,i.jsxs)(n.li,{children:["Quincy - ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/rados/configuration/",children:"https://docs.ceph.com/en/quincy/rados/configuration/"})]}),"\n",(0,i.jsxs)(n.li,{children:["Reef - ",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/reef/rados/configuration/",children:"https://docs.ceph.com/en/reef/rados/configuration/"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"unique-identifier",children:"Unique Identifier"}),"\n",(0,i.jsxs)(n.p,{children:["The File System ID is a unique identifier for the cluster.\nThe identifier is set via the parameter ",(0,i.jsx)(n.code,{children:"fsid"})," in ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"}),"\nand must be unique. It can be generated with ",(0,i.jsx)(n.code,{children:"uuidgen"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:"fsid: c2120a4a-669c-4769-a32c-b7e9d7b848f4\n"})}),"\n",(0,i.jsx)(n.h2,{id:"client",children:"Client"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"client.admin"})," keyring is placed in the file ",(0,i.jsx)(n.code,{children:"environments/infrastructure/files/ceph/ceph.client.admin.keyring"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"swappiness",children:"Swappiness"}),"\n",(0,i.jsxs)(n.p,{children:["The swappiness is set via the ",(0,i.jsx)(n.code,{children:"os_tuning_params"})," dictionary. The dictionary can\nonly be completely overwritten via an entry in the file ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"By default, the dictionary looks like this:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'os_tuning_params:\n - { name: fs.file-max, value: 26234859 }\n - { name: vm.zone_reclaim_mode, value: 0 }\n - { name: vm.swappiness, value: 10 }\n - { name: vm.min_free_kbytes, value: "{{ vm_min_free_kbytes }}" }\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The sysctl paremeters are written to the file ",(0,i.jsx)(n.code,{children:"/etc/sysctl.d/ceph-tuning.conf"}),"\non the storage nodes."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# cat /etc/sysctl.d/ceph-tuning.conf\nfs.aio-max-nr=1048576\nfs.file-max=26234859\nvm.zone_reclaim_mode=0\nvm.swappiness=10\nvm.min_free_kbytes=4194303\n"})}),"\n",(0,i.jsx)(n.h2,{id:"rgw-service",children:"RGW service"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add following configuration in ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:'ceph_conf_overrides:\n "client.rgw.{{ hostvars[inventory_hostname][\'ansible_hostname\'] }}.rgw0":\n "rgw content length compat": "true"\n "rgw enable apis": "swift, s3, admin"\n "rgw keystone accepted roles": "member, admin"\n "rgw keystone accepted admin roles": "admin"\n "rgw keystone admin domain": "default"\n "rgw keystone admin password": "{{ ceph_rgw_keystone_password }}"\n "rgw keystone admin project": "service"\n "rgw keystone admin tenant": "service"\n "rgw keystone admin user": "ceph_rgw"\n "rgw keystone api version": "3"\n "rgw keystone url": "https://api-int.testbed.osism.xyz:5000"\n "rgw keystone verify ssl": "false"\n "rgw keystone implicit tenants": "true"\n "rgw s3 auth use keystone": "true"\n "rgw swift account in url": "true"\n "rgw swift versioning enabled": "true"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"ceph_conf_overrides"})," parameter already exists in ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"}),",\nexpand it and do not overwrite it."]}),"\n",(0,i.jsx)(n.p,{children:"If self-signed SSL certificates are used, two additional parameters must be set."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:' "rgw keystone verify ssl": "false"\n "rgw verify ssl": "false"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["For all possible configuration parameters visit the\n",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/radosgw/config-ref/",children:"Ceph configuration reference"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add the ",(0,i.jsx)(n.code,{children:"ceph_rgw_keystone_password"})," from ",(0,i.jsx)(n.code,{children:"environments/kolla/secrets.yml"})," to\n",(0,i.jsx)(n.code,{children:"environments/ceph/secrets.yml"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add following configuration in ",(0,i.jsx)(n.code,{children:"environments/kolla/configuration.yml"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:"enable_ceph_rgw: true\nenable_ceph_rgw_keystone: true\n\nceph_rgw_swift_compatibility: false\nceph_rgw_swift_account_in_url: true\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the nodes on which the RGW service is to be deployed, ",(0,i.jsx)(n.code,{children:"radowsgw_interface"})," ",(0,i.jsx)(n.strong,{children:"or"}),"\n",(0,i.jsx)(n.code,{children:"radosgw_address"})," must be set in the host vars for the nodes in the inventory.\nIf ",(0,i.jsx)(n.code,{children:"radowsgw_interface"})," is used, the first IPv4 address on this interface is used."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:"title=inventory/host_vars/testbed-node-0.testbed.osism.xyz/vars.yml",children:"##########################################################\n# ceph\n\nradosgw_address: 192.168.16.10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The nodes on which the RGW service is to be deployed can be defined in inventory group\n",(0,i.jsx)(n.code,{children:"ceph-rgw"}),". By default, the RGW services are deployed on the Ceph control nodes.."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"[ceph-rgw:children]\nceph-control\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"extra-pools",children:"Extra pools"}),"\n",(0,i.jsxs)(n.p,{children:["Extra pools can be defined via the ",(0,i.jsx)(n.code,{children:"openstack_pools_extra"})," parameter."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/group_vars/generic/ceph.yml"',children:'openstack_cinder_extra001_pool:\n name: extra001\n pg_num: "{{ openstack_pool_default_pg_num }}"\n pgp_num: "{{ openstack_pool_default_pg_num }}"\n rule_name: "replicated_rule"\n min_size: "{{ openstack_pool_default_min_size }}"\n application: "rbd"\n\nopenstack_pools_extra:\n - "{{ openstack_cinder_extra001_pool }}"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["If more than one Ceph cluster is managed with one manager, do not place the\nparameters in ",(0,i.jsx)(n.code,{children:"inventory/group_vars/generic"})," but in a corresponding directory."]}),"\n",(0,i.jsxs)(n.p,{children:["If, for example, the inventory group of the Ceph cluster on which the additional\npools are to be created is ",(0,i.jsx)(n.code,{children:"ceph.rbd"}),", then the parameters would be stored in\n",(0,i.jsx)(n.code,{children:"inventory/group_vars/ceph.rbd.yml"})," accordingly."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Default value"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"openstack_pool_default_pg_num"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"64"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"openstack_pool_default_min_size"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"0"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"lvm-devices",children:"LVM devices"}),"\n",(0,i.jsxs)(n.p,{children:["For more advanced OSD layout requirements leave out the ",(0,i.jsx)(n.code,{children:"devices"})," key\nand instead use ",(0,i.jsx)(n.code,{children:"lvm_volumes"}),". Details for this can be found on the\n",(0,i.jsx)(n.a,{href:"https://docs.ceph.com/projects/ceph-ansible/en/latest/osds/scenarios.html",children:"OSD Scenario"})," documentation."]}),"\n",(0,i.jsxs)(n.p,{children:["In order to aid in creating the ",(0,i.jsx)(n.code,{children:"lvm_volumes"})," config entries and provision the LVM devices for them,\nOSISM has the two playbooks ",(0,i.jsx)(n.code,{children:"ceph-configure-lvm-volumes"})," and ",(0,i.jsx)(n.code,{children:"ceph-create-lvm-devices"})," available."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["For each Ceph storage node edit the file ",(0,i.jsx)(n.code,{children:"inventory/host_vars/<nodename>.yml"}),"\nadd a configuration like the following to it. Ensure that no ",(0,i.jsx)(n.code,{children:"devices"})," parameter\nis present in the file."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Parameters"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["With the optional parmaeter ",(0,i.jsx)(n.code,{children:"ceph_osd_db_wal_devices_buffer_space_percent"})," it is possible to\nset the percentage of VGs to leave free. The parameter is not set by default. Can be helpful\nfor SSD performance of some older SSD models or to extend lifetime of SSDs in general."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_db_wal_devices_buffer_space_percent: 10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["It is possible to configure the devices to be used with the parameters ",(0,i.jsx)(n.code,{children:"ceph_osd_devices"}),",\n",(0,i.jsx)(n.code,{children:"ceph_db_devices"}),", ",(0,i.jsx)(n.code,{children:"ceph_wal_devices"}),", and ",(0,i.jsx)(n.code,{children:"ceph_db_wal_devices"}),". This is described below."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["It is always possible to use device names such as ",(0,i.jsx)(n.code,{children:"sda"})," or device IDs such as\n",(0,i.jsx)(n.code,{children:"disk/by-id/wwn-<something>"})," or ",(0,i.jsx)(n.code,{children:"disk/by-id/nvme-eui.<something>"}),". ",(0,i.jsx)(n.code,{children:"/dev/"})," is not\nprefixed and is added automatically."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"db_size"})," parameter is optional and defaults to ",(0,i.jsx)(n.code,{children:"(VG size - buffer space (if enabled)) / num_osds"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"wal_size"})," parameter is optional and defaults to ",(0,i.jsx)(n.code,{children:"2 GB"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"num_osds"})," parameter specifies the maximum number of OSDs that can be assigned to a WAL device or DB device."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The optional parameter ",(0,i.jsx)(n.code,{children:"wal_pv"})," can be used to set the device that is to be used as the WAL device."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The optional parameter ",(0,i.jsx)(n.code,{children:"db_pv"})," can be used to set the device that is to be used as the DB device."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OSD only"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sda"})," device will be used as an OSD device without WAL and DB device."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OSD + DB device"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"nvme0n1"})," device will be used as an DB device. It is possible to use this DB device for up to 6 OSDs. Each\nOSD is provided with 30 GB."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_db_devices:\n nvme0n1:\n num_osds: 6\n db_size: 30 GB\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sda"})," device will be used as an OSD device with ",(0,i.jsx)(n.code,{children:"nvme0n1"})," as DB device."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n db_pv: nvme0n1\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OSD + WAL device"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"nvme0n1"})," device will be used as an WAL device. It is possible to use this WAL device for up to 6 OSDs. Each\nOSD is provided with 2 GB."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_wal_devices:\n nvme0n1:\n num_osds: 6\n wal_size: 2 GB\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sda"})," device will be used as an OSD device with ",(0,i.jsx)(n.code,{children:"nvme0n1"})," as WAL device."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n wal_pv: nvme0n1\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OSD + DB device + WAL device (same device for DB + WAL)"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"nvme0n1"})," device will be used as an DB device and a WAL device. It is possible to use those devices for up\nto 6 OSDs."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_db_wal_devices:\n nvme0n1:\n num_osds: 6\n db_size: 30 GB\n wal_size: 2 GB\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sda"})," device will be used as an OSD device with ",(0,i.jsx)(n.code,{children:"nvme0n1"})," as DB device and ",(0,i.jsx)(n.code,{children:"nvme0n1"})," as WAL device."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n db_pv: nvme0n1\n wal_pv: nvme0n1\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OSD + DB device + WAL device (different device for DB + WAL)"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"nvme0n1"})," device will be used as an DB device. It is possible to use this DB device for up to 6 OSDs. Each\nOSD is provided with 30 GB."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_db_devices:\n nvme0n1:\n num_osds: 6\n db_size: 30 GB\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"nvme1n1"})," device will be used as an WAL device. It is possible to use this WAL device for up to 6 OSDs. Each\nOSD is provided with 2 GB."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_wal_devices:\n nvme1n1:\n num_osds: 6\n wal_size: 2 GB\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sda"})," device will be used as an OSD device with ",(0,i.jsx)(n.code,{children:"nvme0n1"})," as DB device and ",(0,i.jsx)(n.code,{children:"nvme1n1"})," as WAL device."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sda:\n db_pv: nvme0n1\n wal_pv: nvme1n1\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Push the configuration to your configuration repository and after that do the following"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply configuration\n$ osism reconciler sync\n$ osism apply facts\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"After the configuration has been pulled and facts updated,\nyou can run the LVM configuration playbook:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply ceph-configure-lvm-volumes\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This will generate a new configuration file for each node in ",(0,i.jsx)(n.code,{children:"/tmp"}),"\non the first manager node named ",(0,i.jsx)(n.code,{children:"<nodename>-ceph-lvm-configuration.yml"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Take the generated configuration file from ",(0,i.jsx)(n.code,{children:"/tmp"})," and ",(0,i.jsx)(n.strong,{children:"replace the previously\nconfiguration"})," for each node."]}),"\n",(0,i.jsxs)(n.p,{children:["In this example, the following content was in the host vars file before\n",(0,i.jsx)(n.code,{children:"osism apply ceph-configure-lvm-volumes"})," was called."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sdb:\n sdc:\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The following content has now been generated in the file in the ",(0,i.jsx)(n.code,{children:"/tmp"})," directory by running\n",(0,i.jsx)(n.code,{children:"osism apply ceph-configure-lvm-volumes"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sdb:\n osd_lvm_uuid: 196aad32-7cc4-5350-8a45-1b03f50fc9bb\n sdc:\n osd_lvm_uuid: c6df96be-1264-5815-9cb2-da5eb453a6de\nlvm_volumes:\n- data: osd-block-196aad32-7cc4-5350-8a45-1b03f50fc9bb\n data_vg: ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb\n- data: osd-block-c6df96be-1264-5815-9cb2-da5eb453a6de\n data_vg: ceph-c6df96be-1264-5815-9cb2-da5eb453a6de\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This content from the file in the ",(0,i.jsx)(n.code,{children:"/tmp"})," directory is added in the host vars file.\nThe previous ",(0,i.jsx)(n.code,{children:"ceph_osd_devices"})," is replaced with the new content."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Push the updated configuration ",(0,i.jsx)(n.strong,{children:"again"})," to your configuration repository and re-run:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply configuration\n$ osism reconciler sync\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Finally create the LVM devices."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply ceph-create-lvm-devices\n"})}),"\n",(0,i.jsx)(n.p,{children:"These PVs, VGs and LVs are created using the example from step 4."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ sudo pvs\n PV VG Fmt Attr PSize PFree\n /dev/sdb ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb lvm2 a-- <20.00g 0\n /dev/sdc ceph-c6df96be-1264-5815-9cb2-da5eb453a6de lvm2 a-- <20.00g 0\n\n$ sudo vgs\n VG #PV #LV #SN Attr VSize VFree\n ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb 1 1 0 wz--n- <20.00g 0\n ceph-c6df96be-1264-5815-9cb2-da5eb453a6de 1 1 0 wz--n- <20.00g 0\n\n$ sudo lvs\n LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert\n osd-block-196aad32-7cc4-5350-8a45-1b03f50fc9bb ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb -wi-a----- <20.00g\n osd-block-c6df96be-1264-5815-9cb2-da5eb453a6de ceph-c6df96be-1264-5815-9cb2-da5eb453a6de -wi-a----- <20.00g\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Everything is now ready for the deployment of the OSDs.\nDetails on deploying Ceph in the ",(0,i.jsx)(n.a,{href:"../deploy-guide/services/ceph",children:"Ceph deploy guide"}),"."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"full-examples",children:"Full examples"}),"\n",(0,i.jsx)(n.h4,{id:"use-of-dedicated-db-devices",children:"Use of dedicated DB devices"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"ceph_osd_devices"})," and ",(0,i.jsx)(n.code,{children:"ceph_db_devices"})," parameters with the following content are initially added\nin the host vars of the node. Devices ",(0,i.jsx)(n.code,{children:"/dev/sda"})," and ",(0,i.jsx)(n.code,{children:"/dev/sdb"})," are used as OSD devices. The device ",(0,i.jsx)(n.code,{children:"/dev/sdd"}),"\nis used as a DB device for up to 2 OSDs. For each OSD that uses ",(0,i.jsx)(n.code,{children:"/dev/sdd"})," as DB device, an LV volume of\n(in this case) 5 GByte is created Please note that at least 30 GByte must be used for a DB device in production."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_db_devices:\n sdd:\n num_osds: 2\n db_size: 5 GB\n\nceph_osd_devices:\n sdb:\n db_pv: sdd\n sdc:\n db_pv: sdd\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then generate the required LVM2 device configuration with the ",(0,i.jsx)(n.code,{children:"ceph-configure-lvm-volumes"})," play."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply facts\nosism reconciler sync\nosism apply ceph-configure-lvm-volumes\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Check the ",(0,i.jsx)(n.code,{children:"/tmp"})," directory on the manager node for files like ",(0,i.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz-ceph-lvm-configuration.yml"}),".\nAdd this content to the host vars of the correspondingnode. The existing ",(0,i.jsx)(n.code,{children:"ceph_osd_devices"})," parameter is replaced."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"---\n#\n# This is Ceph LVM configuration for testbed-node-0.testbed.osism.xyz\n# generated by ceph-configure-lvm-volumes playbook.\n#\nceph_db_devices:\n sdd:\n db_size: 5 GB\n num_osds: 2\n vg_name: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb\nceph_osd_devices:\n sdb:\n db_pv: sdd\n osd_lvm_uuid: 75960289-2e0e-525d-8bb5-dd8552531ef5\n sdc:\n db_pv: sdd\n osd_lvm_uuid: ce2c2cb6-f911-52dd-b57f-4476bf7afe9f\nlvm_volumes:\n- data: osd-block-75960289-2e0e-525d-8bb5-dd8552531ef5\n data_vg: ceph-75960289-2e0e-525d-8bb5-dd8552531ef5\n db: osd-db-75960289-2e0e-525d-8bb5-dd8552531ef5\n db_vg: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb\n- data: osd-block-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f\n data_vg: ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f\n db: osd-db-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f\n db_vg: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Finally, create the necessary PVs, VGs and LVs. The parameter ",(0,i.jsx)(n.code,{children:"-e ignore_db_too_small=true"})," is only set\nhere in the example because we use less than 30 GByte for the size of the DB LV."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism reconciler sync\nosism apply ceph-create-lvm-devices -e ignore_db_too_small=true\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can check the PVs, VGs, and LVs on the node."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ sudo pvs\n PV VG Fmt Attr PSize PFree\n /dev/sdb ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 lvm2 a-- <20.00g 0\n /dev/sdc ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f lvm2 a-- <20.00g 0\n /dev/sdd ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb lvm2 a-- <20.00g <10.00g\n\n$ sudo vgs\n VG #PV #LV #SN Attr VSize VFree\n ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 1 1 0 wz--n- <20.00g 0\n ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f 1 1 0 wz--n- <20.00g 0\n ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb 1 2 0 wz--n- <20.00g <10.00g\n\n$ sudo lvs\n LV VG Attr LSize [...]\n osd-block-75960289-2e0e-525d-8bb5-dd8552531ef5 ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 -wi-a----- <20.00g\n osd-block-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f -wi-a----- <20.00g\n osd-db-75960289-2e0e-525d-8bb5-dd8552531ef5 ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb -wi-a----- 5.00g\n osd-db-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb -wi-a----- 5.00g\n"})}),"\n",(0,i.jsx)(n.h4,{id:"use-of-partitions",children:"Use of partitions"}),"\n",(0,i.jsx)(n.p,{children:"The use of partitions presented in this example is not recommended for use in production but only for POCs."}),"\n",(0,i.jsxs)(n.p,{children:["First create partitions that should be used for Ceph. In this example we use a block device ",(0,i.jsx)(n.code,{children:"/dev/sdb"}),"\nwith four partitions that will be used for Ceph OSDs."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ sudo fdisk -l /dev/sdb\nDisk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors\nDisk model: QEMU HARDDISK\nUnits: sectors of 1 * 512 = 512 bytes\nSector size (logical/physical): 512 bytes / 512 bytes\nI/O size (minimum/optimal): 512 bytes / 512 bytes\nDisklabel type: gpt\nDisk identifier: 709B8C6C-51E1-4644-9ED4-0604607FCCEE\n\nDevice Start End Sectors Size Type\n/dev/sdb1 2048 10487807 10485760 5G Linux filesystem\n/dev/sdb2 10487808 20973567 10485760 5G Linux filesystem\n/dev/sdb3 20973568 31459327 10485760 5G Linux filesystem\n/dev/sdb4 31459328 41943006 10483679 5G Linux filesystem\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"ceph_osd_devices"})," parameter with the following content is initially added in the host vars of the node.\nThe partitions ",(0,i.jsx)(n.code,{children:"/dev/sda1"}),", ",(0,i.jsx)(n.code,{children:"/dev/sdb1"}),", ",(0,i.jsx)(n.code,{children:"/dev/sdc1"})," and ",(0,i.jsx)(n.code,{children:"/dev/sdd1"}),", are to be used as OSD."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_osd_devices:\n sdb1:\n sdb2:\n sdb3:\n sdb4:\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then generate the required LVM2 device configuration with the ",(0,i.jsx)(n.code,{children:"ceph-configure-lvm-volumes"})," play."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply facts\nosism reconciler sync\nosism apply ceph-configure-lvm-volumes\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Check the ",(0,i.jsx)(n.code,{children:"/tmp"})," directory on the manager node for files like ",(0,i.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz-ceph-lvm-configuration.yml"}),".\nAdd this content to the host vars of the correspondingnode. The existing ",(0,i.jsx)(n.code,{children:"ceph_osd_devices"})," parameter is replaced."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"---\n#\n# This is Ceph LVM configuration for testbed-node-0.testbed.osism.xyz\n# generated by ceph-configure-lvm-volumes playbook.\n#\nceph_osd_devices:\n sdb1:\n osd_lvm_uuid: 9e8799ae-c716-5212-8833-49f153ffbcef\n sdb2:\n osd_lvm_uuid: 8518d3a2-3194-5764-b55a-c51222b9b576\n sdb3:\n osd_lvm_uuid: a0da232a-e5b8-5823-8c42-8fb231442edc\n sdb4:\n osd_lvm_uuid: 56f7b5bc-82b0-5626-90a5-adf6078ceba6\nlvm_volumes:\n- data: osd-block-9e8799ae-c716-5212-8833-49f153ffbcef\n data_vg: ceph-9e8799ae-c716-5212-8833-49f153ffbcef\n- data: osd-block-8518d3a2-3194-5764-b55a-c51222b9b576\n data_vg: ceph-8518d3a2-3194-5764-b55a-c51222b9b576\n- data: osd-block-a0da232a-e5b8-5823-8c42-8fb231442edc\n data_vg: ceph-a0da232a-e5b8-5823-8c42-8fb231442edc\n- data: osd-block-56f7b5bc-82b0-5626-90a5-adf6078ceba6\n data_vg: ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6\n"})}),"\n",(0,i.jsx)(n.p,{children:"Finally, create the necessary PVs, VGs and LVs."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism reconciler sync\nosism apply ceph-create-lvm-devices\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can check the PVs, VGs, and LVs on the node."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ sudo pvs\n PV VG Fmt Attr PSize PFree\n /dev/sdb1 ceph-9e8799ae-c716-5212-8833-49f153ffbcef lvm2 a-- <5.00g 0\n /dev/sdb2 ceph-8518d3a2-3194-5764-b55a-c51222b9b576 lvm2 a-- <5.00g 0\n /dev/sdb3 ceph-a0da232a-e5b8-5823-8c42-8fb231442edc lvm2 a-- <5.00g 0\n /dev/sdb4 ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 lvm2 a-- <5.00g 0\n\n$ sudo vgs\n VG #PV #LV #SN Attr VSize VFree\n ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 1 1 0 wz--n- <5.00g 0\n ceph-8518d3a2-3194-5764-b55a-c51222b9b576 1 1 0 wz--n- <5.00g 0\n ceph-9e8799ae-c716-5212-8833-49f153ffbcef 1 1 0 wz--n- <5.00g 0\n ceph-a0da232a-e5b8-5823-8c42-8fb231442edc 1 1 0 wz--n- <5.00g 0\n\n$ sudo lvs\n LV VG Attr LSize [...]\n osd-block-56f7b5bc-82b0-5626-90a5-adf6078ceba6 ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 -wi-a----- <5.00g\n osd-block-8518d3a2-3194-5764-b55a-c51222b9b576 ceph-8518d3a2-3194-5764-b55a-c51222b9b576 -wi-a----- <5.00g\n osd-block-9e8799ae-c716-5212-8833-49f153ffbcef ceph-9e8799ae-c716-5212-8833-49f153ffbcef -wi-a----- <5.00g\n osd-block-a0da232a-e5b8-5823-8c42-8fb231442edc ceph-a0da232a-e5b8-5823-8c42-8fb231442edc -wi-a----- <5.00g\n"})}),"\n",(0,i.jsx)(n.h2,{id:"dashboard",children:"Dashboard"}),"\n",(0,i.jsxs)(n.p,{children:["Password for the admin user of the Ceph dashboard is set via ",(0,i.jsx)(n.code,{children:"ceph_dashboard_password"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/secrets.yml"',children:"ceph_dashboard_password: password\n"})}),"\n",(0,i.jsx)(n.p,{children:"User name of the admin user, port and listen IP address can be set via additional parameters."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:"ceph_dashboard_addr: 0.0.0.0\nceph_dashboard_port: 7000\nceph_dashboard_username: admin\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The Ceph dashboard is bootstrapped with the ",(0,i.jsx)(n.code,{children:"ceph-bootstrap-dashboard"})," play."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply ceph-bootstrap-dashboard\n"})}),"\n",(0,i.jsx)(n.h3,{id:"configuring-the-openstack-loadbalancer-to-expose-the-ceph-dashboard",children:"Configuring the openstack loadbalancer to expose the ceph dashboard"}),"\n",(0,i.jsx)(n.p,{children:"The ceph dashboard runs in an active/standby configuration. In its default standby instances will\nredirect to the active instance. Most deployments will want to use the openstack loadbalancer to\nexpose the ceph dashboard on the internal network and direct traffic directly to the active\ninstance."}),"\n",(0,i.jsxs)(n.p,{children:["In this scenario the dashboard should be configured to return an http error with status ",(0,i.jsx)(n.code,{children:"404"})," on\nstandby instances."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:"ceph_dashboard_standby_behaviour: error\nceph_dashboard_standby_error_status_code: 404\n"})}),"\n",(0,i.jsx)(n.p,{children:"Create a loadbalancer configuration"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-jinja2",metastring:'title="environments/kolla/files/overlays/haproxy/services.d/ceph_dashboard.cfg"',children:"\n{%- set internal_tls_bind_info = 'ssl crt /etc/haproxy/certificates/haproxy-internal.pem' if kolla_enable_tls_internal|bool else '' %}\n\nlisten ceph_dashboard\n option httpchk\n http-check expect status 200,404\n http-check disable-on-404\n {{ \"bind %s:%s %s\"|e|format(kolla_internal_vip_address, 8140, internal_tls_bind_info)|trim() }}\n{% for host in groups['ceph-mgr'] %}\n server {{ hostvars[host]['ansible_facts']['hostname'] }} {{ hostvars[host]['monitor_address'] }}:7000 check inter 2000 rise 2 fall 5\n{% endfor %}\n"})}),"\n",(0,i.jsx)(n.p,{children:"and apply it."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply -a reconfigure loadbalancer\n"})}),"\n",(0,i.jsx)(n.h2,{id:"second-ceph-cluster",children:"Second Ceph cluster"}),"\n",(0,i.jsxs)(n.p,{children:["With OSISM, it is possible to manage any number of independent Ceph clusters via a single OSISM\nmanager service using sub-environments. A sub environment is basically nothing more than another directory\nbelow the ",(0,i.jsx)(n.code,{children:"environments"})," directory of the configuration repository with a special name."]}),"\n",(0,i.jsxs)(n.p,{children:["A sub-environment for Ceph always has the name ",(0,i.jsx)(n.code,{children:"ceph.NAME"}),". The ",(0,i.jsx)(n.code,{children:"ceph.NAME"})," directory in the\nconfiguration repository then contains the ",(0,i.jsx)(n.code,{children:"configuration.yml"}),", ",(0,i.jsx)(n.code,{children:"images.yml"})," and ",(0,i.jsx)(n.code,{children:"secrets.yml"}),"\nfiles as usual."]}),"\n",(0,i.jsxs)(n.p,{children:["In this example, a sub-environment ",(0,i.jsx)(n.code,{children:"ceph.rgw"})," is created which is used for a Ceph cluster that\nwill only be used as an RGW cluster."]}),"\n",(0,i.jsxs)(n.p,{children:["In comparison to the normal ",(0,i.jsx)(n.code,{children:"ceph"})," environment, the groups to be used must be overwritten for a\nCeph sub-environment. In this case, two groups are defined: ",(0,i.jsx)(n.code,{children:"ceph.rgw"})," and ",(0,i.jsx)(n.code,{children:"ceph.rgw.empty"}),".\nAny other groups can be used, e.g. ",(0,i.jsx)(n.code,{children:"ceph.rgw.osd"}),". It is recommended to base the name of the\ngroups on the name of the sub-environments."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"ceph.rgw.empty"})," group is important because there are plays in ceph-ansible that are executed\nwhen nodes are in a specific group. To explicitly avoid this, certain groups are set to the empty\ngroup."]}),"\n",(0,i.jsxs)(n.p,{children:["All available group name parameters are listed in the ",(0,i.jsx)(n.a,{href:"https://github.com/osism/defaults/blob/main/all/099-ceph.yml",children:"[099-ceph.yml]"}),"\nfile of the ",(0,i.jsx)(n.a,{href:"https://github.com/osism/defaults",children:"osism/defaults"})," repository."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph.rgw/configuration.yml"',children:"##########################\n# groups\n\nceph_group_name: ceph.rgw\n\nclient_group_name: ceph.rgw\ngrafana_server_group_name: ceph.rgw\niscsi_gw_group_name: ceph.rgw.empty\nmds_group_name: ceph.rgw.empty\nmgr_group_name: ceph.rgw\nmon_group_name: ceph.rgw\nnfs_group_name: ceph.rgw.empty\nosd_group_name: ceph.rgw\nrbdmirror_group_name: ceph.rgw.empty\nrestapi_group_name: ceph.rgw.empty\nrgw_group_name: ceph.rgw\nrgwloadbalancer_group_name: ceph.rgw.empty\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The groups used are then added in the inventory in the ",(0,i.jsx)(n.code,{children:"10-custom"})," file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/10-custom"',children:"[ceph.rgw]\ntestbed-node-3.testbed.osism.xyz\ntestbed-node-4.testbed.osism.xyz\ntestbed-node-5.testbed.osism.xyz\n\n[ceph.rgw.empty]\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The sub environment can then be specified with all ",(0,i.jsx)(n.code,{children:"apply"})," commands of the OSISM CLI. For example,\nto deploy the Ceph mon services of the ",(0,i.jsx)(n.code,{children:"ceph.rgw"})," sub environment:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply --sub rgw ceph-osds\n"})}),"\n",(0,i.jsx)(n.h2,{id:"resource-limits",children:"Resource limits"}),"\n",(0,i.jsxs)(n.p,{children:["Resource limits for the individual Ceph services can be set via ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"}),".\nThe possible parameters and their defaults for memory limits and CPU limits are listed below."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Memory limits"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'ceph_mds_docker_memory_limit: "{{ ansible_facts[\'memtotal_mb\'] }}m"\nceph_mgr_docker_memory_limit: "{{ ansible_facts[\'memtotal_mb\'] }}m"\nceph_mon_docker_memory_limit: "{{ ansible_facts[\'memtotal_mb\'] }}m"\nceph_osd_docker_memory_limit: "{{ ansible_facts[\'memtotal_mb\'] }}m"\nceph_rbd_mirror_docker_memory_limit: "{{ ansible_facts[\'memtotal_mb\'] }}m"\nceph_rgw_docker_memory_limit: "4096m"\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"CPU limits"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"ceph_mds_docker_cpu_limit: 4\nceph_mgr_docker_cpu_limit: 1\nceph_mon_docker_cpu_limit: 1\nceph_osd_docker_cpu_limit: 4\nceph_rbd_mirror_docker_cpu_limit: 1\nceph_rgw_docker_cpu_limit: 8\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"cpu-pinning",children:"CPU Pinning"}),"\n",(0,i.jsxs)(n.p,{children:["CPU pinning and specifying the NUMA nodes to be used for the Ceph OSD and RGW services can be\nset via ",(0,i.jsx)(n.code,{children:"environments/ceph/configuration.yml"}),".\nThe possible parameters and possible values are listed below. The parameters are not enabled\nby default."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Limit the specific CPUs or cores a container can use. A comma-separated list or\nhyphen-separated range of CPUs a container can use, if you have more than one CPU.\nThe first CPU is numbered 0. A valid value might be 0-3 (to use the first, second,\nthird, and fourth CPU) or 1,3 (to use the second and fourth CPU)."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# ceph_osd_docker_cpuset_cpus: "0,2,4,6,8,10,12,14,16"\n# ceph_rgw_docker_cpuset_cpus: "0,2,4,6,8,10,12,14,16"\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Memory nodes in which to allow execution (e.g. 0-3, 0,1). Only effective on NUMA systems."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# ceph_osd_docker_cpuset_mems: "0"\n# ceph_rgw_docker_cpuset_mems: "0"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Available NUMA nodes on a node can be displayed with ",(0,i.jsx)(n.a,{href:"https://github.com/numactl/numactl",children:"numactl"}),".\nIn this example, there are 2 NUMA nodes. The pinned CPUs should all be assigned to the\nspecified NUMA node."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# numactl --hardware\navailable: 2 nodes (0-1)\nnode 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59\nnode 0 size: 515581 MB\nnode 0 free: 511680 MB\nnode 1 cpus: 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79\nnode 1 size: 516078 MB\nnode 1 free: 511865 MB\nnode distances:\nnode 0 1\n 0: 10 20\n 1: 20 10\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>a});var i=s(96540);const d={},c=i.createContext(d);function r(e){const n=i.useContext(c);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:r(e.components),i.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6c4198a1.9e743a10.js b/assets/js/6c4198a1.9e743a10.js new file mode 100644 index 0000000000..1d6fd149e5 --- /dev/null +++ b/assets/js/6c4198a1.9e743a10.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7638],{93083:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var o=n(74848),i=n(28453);const r={sidebar_label:"Bootstrap",sidebar_position:40},t="Bootstrap",a={id:"iaas/guides/deploy-guide/bootstrap",title:"Bootstrap",description:"The prerequisite for bootstraping the nodes of a cluster the Manager node has to be",source:"@site/docs/02-iaas/guides/deploy-guide/bootstrap.md",sourceDirName:"02-iaas/guides/deploy-guide",slug:"/iaas/guides/deploy-guide/bootstrap",permalink:"/docs/iaas/guides/deploy-guide/bootstrap",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/bootstrap.md",tags:[],version:"current",sidebarPosition:40,frontMatter:{sidebar_label:"Bootstrap",sidebar_position:40},sidebar:"docs",previous:{title:"Provisioning",permalink:"/docs/iaas/guides/deploy-guide/provisioning"},next:{title:"Services",permalink:"/docs/iaas/guides/deploy-guide/services/"}},l={},d=[];function c(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.h1,{id:"bootstrap",children:"Bootstrap"}),"\n",(0,o.jsxs)(s.admonition,{type:"info",children:[(0,o.jsxs)(s.p,{children:["The prerequisite for bootstraping the nodes of a cluster the Manager node has to be\nprepares. What a Manager node is and how to prepare it is documented in the\n",(0,o.jsx)(s.a,{href:"./manager",children:"Manager chapter of the Deploy Guide"}),"."]}),(0,o.jsxs)(s.p,{children:["All the nodes must also have already been provisioned. How manual provisioning is done\nis documented in the ",(0,o.jsx)(s.a,{href:"./provisioning",children:"Provisioning chapter of the Deploy Guide"}),"."]})]}),"\n",(0,o.jsxs)(s.p,{children:["Before the nodes can be bootstrapped, they must all have already been provisioned.\nThe guide for this can be found in the section ",(0,o.jsx)(s.a,{href:"./provisioning",children:"Provisioning of bare-metal nodes"}),"."]}),"\n",(0,o.jsx)(s.p,{children:"The following steps are applied to bootstrap all nodes. After the completion of the bootstrap,\nthe nodes are already ready for use."}),"\n",(0,o.jsxs)(s.ol,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"Create operator user."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply operator -u osism\n"})}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["When using the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/node-image",children:"osism/node-image"})," the user is ",(0,o.jsx)(s.code,{children:"osism"}),"\nand the password of this user is ",(0,o.jsx)(s.code,{children:"password"}),". If you install Ubuntu manually the user usually\nis ",(0,o.jsx)(s.code,{children:"ubuntu"}),". If you want to use any other user here, that's no problem. It is important that\nthis user has sudo rights. The password according to what you have set yourself."]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["The operator public SSH key has to be added in advance on all nodes to ",(0,o.jsx)(s.code,{children:"authorized_keys"})," file\nof the user specified with ",(0,o.jsx)(s.code,{children:"-u"}),". This key is stored as ",(0,o.jsx)(s.code,{children:"operator_public_key"})," in the file\n",(0,o.jsx)(s.code,{children:"environments/configuration.yml"}),"."]}),"\n",(0,o.jsxs)(s.p,{children:["Alternatively (not recommended), the password can be stored in plain text in a file ",(0,o.jsx)(s.code,{children:"/opt/configuration/secrets/conn_password"}),".\nThe parameter ",(0,o.jsx)(s.code,{children:"--conn-pass-file /opt/configuration/secrets/conn_password"})," must then also be specified:"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply operator -u osism \\\n --conn-pass-file /opt/configuration/secrets/conn_password\n"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["It is important that this user has sudo rights with ",(0,o.jsx)(s.code,{children:"NOPASSWD"}),"."]}),"\n",(0,o.jsxs)(s.p,{children:["Alternatively (not recommended), the password can be stored in plain text in a file ",(0,o.jsx)(s.code,{children:"/opt/configuration/secrets/become_password"}),".\nThe parameter ",(0,o.jsx)(s.code,{children:"--become-pass-file /opt/configuration/secrets/become_password"})," must then also be specified:"]}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply operator -u osism \\\n --become-pass-file /opt/configuration/secrets/become_password\n"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"If a password is required for both sudo and login, use both arguments at the same time."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply operator -u osism \\\n --become-pass-file /opt/configuration/secrets/become_password \\\n --conn-pass-file /opt/configuration/secrets/conn_password\n"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsxs)(s.p,{children:["When using the ",(0,o.jsx)(s.a,{href:"https://github.com/osism/node-image",children:"osism/node-image"})," the user is ",(0,o.jsx)(s.code,{children:"osism"})," and the password of this\nuser is ",(0,o.jsx)(s.code,{children:"password"}),". If you install Ubuntu manually the user usually is ",(0,o.jsx)(s.code,{children:"ubuntu"}),". The password according to what you\nhave set yourself"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"Proxy deployment (optional). This is only necessary if you use the proxy on the manager to enable external access to\nthe nodes."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply squid\n"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"Proxy configuration (optional). This is only necessary if you use the proxy on the manager to enable external access to\nthe nodes."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply proxy\n"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"Network configuration. It is recommended to backup the existing network configuration."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply network\n"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"Reboot (optional). The reboot at this point is recommended to ensure that the network configuration is working."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply reboot -l 'all:!manager' -e ireallymeanit=yes\n"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"Check if all systems are reachable (you probably have to do this several times until all systems are accessible)."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply ping\n"})}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"System is currently rebooting and is not yet accessible via network."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:'fatal: [net003]: UNREACHABLE! => {"changed": false, "msg": "Connection timed\nout.", "unreachable": true}``\n'})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"System has already been rebooted and is not accessible via the network."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:'fatal: [net003]: UNREACHABLE! => {"changed": false, "msg": "EOF on stream;\nlast 100 lines received:\\nssh: connect to host 10.15.0.33 port 22: No route\nto host\\r", "unreachable": true}\n'})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"Refresh facts."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply facts\n"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"Bootstrap."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply bootstrap\n"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"Reboot (non-optional). Since the kernel version often changes after the initial bootstrap,\nthe reboot should always be performed."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply reboot -l 'all:!manager' -e ireallymeanit=yes\n"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"Check if all systems are reachable (you probably have to do this several times until all systems are accessible)."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply ping\n"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"Prepare the SSH configuration of the manager node."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply sshconfig\n"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:"Make all SSH public keys known."}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{children:"osism apply known-hosts\n"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(s.p,{children:"Ready. All nodes are now bootstrapped and available to deploy services."})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>a});var o=n(96540);const i={},r=o.createContext(i);function t(e){const s=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),o.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6d32cafb.ffa189f3.js b/assets/js/6d32cafb.ffa189f3.js new file mode 100644 index 0000000000..b3131a74db --- /dev/null +++ b/assets/js/6d32cafb.ffa189f3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5978],{21052:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>l,frontMatter:()=>r,metadata:()=>t,toc:()=>c});var i=s(74848),a=s(28453);const r={sidebar_label:"OpenStack",sidebar_position:40},o="OpenStack",t={id:"iaas/guides/upgrade-guide/openstack",title:"OpenStack",description:"When upgrade the different OpenStack services, all containers must be",source:"@site/docs/02-iaas/guides/upgrade-guide/openstack.md",sourceDirName:"02-iaas/guides/upgrade-guide",slug:"/iaas/guides/upgrade-guide/openstack",permalink:"/docs/iaas/guides/upgrade-guide/openstack",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/openstack.md",tags:[],version:"current",sidebarPosition:40,frontMatter:{sidebar_label:"OpenStack",sidebar_position:40},sidebar:"docs",previous:{title:"Logging & Monitoring",permalink:"/docs/iaas/guides/upgrade-guide/logging-monitoring"},next:{title:"Configuration Guide",permalink:"/docs/iaas/guides/configuration-guide/"}},d={},c=[];function p(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"openstack",children:"OpenStack"}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsx)(n.p,{children:"When upgrade the different OpenStack services, all containers must be\nrestarted. When restarting the API services, there is a short downtime\nof the APIs. This downtime is usually less than 1 minute."})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OpenStack client"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply openstackclient\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Keystone"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull keystone\nosism apply -a upgrade keystone\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Glance"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull glance\nosism apply -a upgrade glance\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Designate"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull designate\nosism apply -a upgrade designate\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Placement"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull placement\nosism apply -a upgrade placement\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Cinder"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull cinder\nosism apply -a upgrade cinder\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Neutron"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull neutron\nosism apply -a upgrade neutron\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Nova"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull nova\nosism apply -a upgrade nova\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Octavia"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull octavia\nosism apply -a upgrade octavia\n"})}),"\n",(0,i.jsx)(n.p,{children:"9.1. Update amphora image"}),"\n",(0,i.jsx)(n.p,{children:"This step is only necessary if the Amphora Driver is used. If OVN is used as the driver,\nthis step is not necessary."}),"\n",(0,i.jsxs)(n.p,{children:["We provide regularly updated images for Octavia in\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/openstack-octavia-amphora-image",children:"osism/openstack-octavia/amphora-image"}),".\nThe OSISM CLI can be used to upload the correct image depending on the OpenStack release\nused."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism manage image octavia\n"})}),"\n",(0,i.jsx)(n.p,{children:"9.2. Amphora rotation"}),"\n",(0,i.jsx)(n.p,{children:"This step is only necessary if the Amphora driver is used. If OVN is used as the driver,\nthis step is not necessary."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Horizon"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull horizon\nosism apply -a upgrade horizon\n"})}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>t});var i=s(96540);const a={},r=i.createContext(a);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6d890b23.796ee042.js b/assets/js/6d890b23.796ee042.js new file mode 100644 index 0000000000..286eaf59af --- /dev/null +++ b/assets/js/6d890b23.796ee042.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4331],{62699:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>d,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var n=t(74848),a=t(28453);const i={sidebar_label:"Task"},r="Task",o={id:"iaas/guides/operations-guide/manager/task",title:"Task",description:"List",source:"@site/docs/02-iaas/guides/operations-guide/manager/task.md",sourceDirName:"02-iaas/guides/operations-guide/manager",slug:"/iaas/guides/operations-guide/manager/task",permalink:"/docs/iaas/guides/operations-guide/manager/task",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/manager/task.md",tags:[],version:"current",frontMatter:{sidebar_label:"Task"},sidebar:"docs",previous:{title:"Logging",permalink:"/docs/iaas/guides/operations-guide/manager/log"},next:{title:"Ceph",permalink:"/docs/iaas/guides/operations-guide/ceph"}},d={},c=[{value:"List",id:"list",level:2},{value:"Broker reset",id:"broker-reset",level:2}];function l(e){const s={code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"task",children:"Task"}),"\n",(0,n.jsx)(s.h2,{id:"list",children:"List"}),"\n",(0,n.jsxs)(s.p,{children:["All running or scheduled tasks can be listed with ",(0,n.jsx)(s.code,{children:"osism task list"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"+----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------+\n| Worker | ID | Name | Status | Start time | Arguments |\n|----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------|\n| celery@kolla-ansible | 8a553e69-c532-4ba0-a5d4-08a983bde692 | osism.tasks.kolla.run | ACTIVE | 2023-09-27 17:55:54.252250 | ['kolla', 'common', ['-e kolla_action=pull']] |\n| celery@osism-ansible | dba72dd5-1885-408f-9262-e0ded111a007 | osism.tasks.ansible.run | ACTIVE | 2023-09-27 18:00:31.215879 | ['generic', 'facts', []] |\n+----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------+\n"})}),"\n",(0,n.jsx)(s.h2,{id:"broker-reset",children:"Broker reset"}),"\n",(0,n.jsx)(s.p,{children:"Sometimes tasks get stuck. Due to the internal locks it is then not possible to re-execute\nplays with the same name. Also it is currently not possible to cancel already running tasks\n(is on the todo list). The only way to unblock the situation is to stop the manager service\nand start it again."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"cd /opt/manager\ndocker compose down\ndocker compose up -d\n"})}),"\n",(0,n.jsx)(s.p,{children:"In earlier versions of OSISM, the Redis service was not stateless. In these cases, it is\nnecessary to delete the Redis service volume before restarting the manager service."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"docker volume rm manager_redis\n"})})]})}function u(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>o});var n=t(96540);const a={},i=n.createContext(a);function r(e){const s=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),n.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6d8acf16.1ce4a660.js b/assets/js/6d8acf16.1ce4a660.js new file mode 100644 index 0000000000..d92fc1628a --- /dev/null +++ b/assets/js/6d8acf16.1ce4a660.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3374],{3938:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var r=o(74848),t=o(28453);const s={},i="Tuning",a={id:"operating-scs/components/monitoring/docs/tuning",title:"Tuning",description:"This page contains recommended parameters to set for the Thanos components to improve performance in terms of query time.",source:"@site/docs/04-operating-scs/components/monitoring/docs/tuning.md",sourceDirName:"04-operating-scs/components/monitoring/docs",slug:"/operating-scs/components/monitoring/docs/tuning",permalink:"/docs/operating-scs/components/monitoring/docs/tuning",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/tuning.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Traces",permalink:"/docs/operating-scs/components/monitoring/docs/tracing"},next:{title:"Central API",permalink:"/docs/category/central-api"}},c={},l=[{value:"Query Frontend",id:"query-frontend",level:2},{value:"Compactor",id:"compactor",level:2},{value:"Query",id:"query",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"tuning",children:"Tuning"}),"\n",(0,r.jsx)(n.p,{children:"This page contains recommended parameters to set for the Thanos components to improve performance in terms of query time.\nThe following parameters have already been incorporated into the upstream dNation monitoring repositories,\nand therefore are already included in the SCS observability deployment."}),"\n",(0,r.jsx)(n.h2,{id:"query-frontend",children:"Query Frontend"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:'queryFrontend:\n extraFlags:\n - --query-range.split-interval=12h \n - --query-frontend.log-queries-longer-than=10s\n - --query-frontend.compress-responses\n - |-\n --query-range.response-cache-config="config":\n "max_size": "500MB"\n "max_size_items": 0\n "validity": 0s\n "type": "in-memory"\n'})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Notes on the parameters for query frontend:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"query-range.split-interval"})," - splits a long query into multiple short queries to improve query time. Default=24h."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"query-frontend.log-queries-longer-than=10s"})," - log queries running longer than 10s, which helps to identify new querries, which should be improved)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"query-frontend.compress-responses"})," - compress HTTP responses, helps with query time"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"query-range.response-cache-config"})," - cahcing is common solution to speed up response time(",(0,r.jsx)(n.a,{href:"https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/",children:"https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/"}),")"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"compactor",children:"Compactor"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"compactor:\n retentionResolutionRaw: 2d\n retentionResolution5m: 10d\n retentionResolution1h: 15d\n extraFlags:\n - --compact.concurrency=3\n - --downsample.concurrency=3\n"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Notes on the parameters for compactor:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"retentionResolutionRaw"})," - how long to retain raw samples in bucket. Minimum is two days, because just after 40 hours 5m downsampled data are created."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"retentionResolution5m"})," - how long to retain samples of resolution 1 (5 minutes) in bucket. Setting this to 0d will retain samples of this resolution forever. One hour downsampled data are created only after 10 days, so this is minimum if you want also 1h downsampled data."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"retentionResolution1h"})," - how long to retain samples of resolution 2 hour) in bucket."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"delete-delay"})," - make sure you have set this parameter. It is time before a block marked for deletion is deleted from bucket. Note that deleting blocks immediately can cause query failures, if store gateway still has the block loaded, or compactor is ignoring the deletion because it's compacting the block at the same time. Default=48h."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"compact.concurrency"})," - number of goroutines to use when compacting groups(",(0,r.jsx)(n.a,{href:"https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/",children:"https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/"}),"). Default=1."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"downsample.concurrency"})," - number of goroutines to use when downsampling block(",(0,r.jsx)(n.a,{href:"https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/",children:"https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/"}),"). Default=1."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"query",children:"Query"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"query:\n extraFlags:\n - --query.auto-downsampling\n - --query.replica-label=prometheus_replica\n"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Notes on the parameters for query:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"query.auto-downsampling"})," - enable automatic adjustment (step / 5) to what source of data should be used in store gateways if no ",(0,r.jsx)(n.code,{children:"max_source_resolution"})," param is specified. Default step for range queries is equal to 1s and it is only used when step is not set in UI. Can be changed by setting ",(0,r.jsx)(n.code,{children:"--query.default-step"})," parameter. Hovewer, when you are using ",(0,r.jsx)(n.strong,{children:"Grafana"})," as your UI, the step is taken from ",(0,r.jsx)(n.code,{children:"min_step"}),". The preferred options is to set HTTP URL/FORM parameter ",(0,r.jsx)(n.code,{children:"max_source_resolution"})," to ",(0,r.jsx)(n.code,{children:"auto"}),", which selects downsample resolution automatically based on the query."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"query.replica-label"})," - labels to treat as a replica indicator along which data is deduplicated."]}),"\n"]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>a});var r=o(96540);const t={},s=r.createContext(t);function i(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6db2ece2.066950d7.js b/assets/js/6db2ece2.066950d7.js new file mode 100644 index 0000000000..ee1b50373e --- /dev/null +++ b/assets/js/6db2ece2.066950d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9356],{33426:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>u,frontMatter:()=>t,metadata:()=>a,toc:()=>c});var r=i(74848),o=i(28453);const t={sidebar_label:"Inventory",sidebar_position:10},s="Inventory",a={id:"iaas/guides/configuration-guide/inventory",title:"Inventory",description:"The inventory used for the environment is located in the inventory directory.",source:"@site/docs/02-iaas/guides/configuration-guide/inventory.md",sourceDirName:"02-iaas/guides/configuration-guide",slug:"/iaas/guides/configuration-guide/inventory",permalink:"/docs/iaas/guides/configuration-guide/inventory",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/inventory.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Inventory",sidebar_position:10},sidebar:"docs",previous:{title:"Configuration repository",permalink:"/docs/iaas/guides/configuration-guide/configuration-repository"},next:{title:"Manager",permalink:"/docs/iaas/guides/configuration-guide/manager"}},d={},c=[{value:"Manager",id:"manager",level:2},{value:"Reconciler",id:"reconciler",level:2},{value:"Host Vars",id:"host-vars",level:2},{value:"Group Vars",id:"group-vars",level:2},{value:"Define variable for all nodes",id:"define-variable-for-all-nodes",level:3}];function l(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"inventory",children:"Inventory"}),"\n",(0,r.jsxs)(n.p,{children:["The inventory used for the environment is located in the ",(0,r.jsx)(n.code,{children:"inventory"})," directory."]}),"\n",(0,r.jsx)(n.h2,{id:"manager",children:"Manager"}),"\n",(0,r.jsxs)(n.p,{children:["The manager has his own inventory which is used exclusively for the seed phase of the manager.\nIt is located in the directory ",(0,r.jsx)(n.code,{children:"environments/manager"}),". There is a ",(0,r.jsx)(n.code,{children:"hosts"})," file with only the\nmanager node in it."]}),"\n",(0,r.jsx)(n.h2,{id:"reconciler",children:"Reconciler"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Inventory Reconciler",src:i(13519).A+"",width:"1366",height:"768"})}),"\n",(0,r.jsx)(n.h2,{id:"host-vars",children:"Host Vars"}),"\n",(0,r.jsx)(n.h2,{id:"group-vars",children:"Group Vars"}),"\n",(0,r.jsx)(n.h3,{id:"define-variable-for-all-nodes",children:"Define variable for all nodes"}),"\n",(0,r.jsxs)(n.p,{children:["The Ansible group ",(0,r.jsx)(n.code,{children:"all"})," is specifically used internally by OSISM, is reserved and is not supported\nfor additional variables. When variables are added in the configuration repository for the all group,\nthey are ignored. In OSISM the group ",(0,r.jsx)(n.code,{children:"generic"})," can be used to store variables for all nodes."]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},13519:(e,n,i)=>{i.d(n,{A:()=>r});const r=i.p+"assets/images/inventory-reconciler-acd822767003069a8935e016081383a5.png"},28453:(e,n,i)=>{i.d(n,{R:()=>s,x:()=>a});var r=i(96540);const o={},t=r.createContext(o);function s(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6ddb698c.87b117c5.js b/assets/js/6ddb698c.87b117c5.js new file mode 100644 index 0000000000..58f201df55 --- /dev/null +++ b/assets/js/6ddb698c.87b117c5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5679],{4584:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>d,contentTitle:()=>a,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var n=t(74848),r=t(28453);const c={},a="scs-0217: Kubernetes cluster baseline security",i={id:"kaas/scs-0217",title:"scs-0217: Kubernetes cluster baseline security",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/kaas/scs-0217.md",sourceDirName:"kaas",slug:"/kaas/scs-0217",permalink:"/standards/kaas/scs-0217",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Requirements for testing cluster-stacks",permalink:"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks"},next:{title:"Kubernetes cluster baseline security",permalink:"/standards/scs-0217-v1-baseline-cluster-security"}},d={},l=[];function o(e){const s={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"scs-0217-kubernetes-cluster-baseline-security",children:"scs-0217: Kubernetes cluster baseline security"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Version"}),(0,n.jsx)(s.th,{children:"Type"}),(0,n.jsx)(s.th,{children:"State"}),(0,n.jsx)(s.th,{children:"stabilized"}),(0,n.jsx)(s.th,{children:"deprecated"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0217-v1-baseline-cluster-security",children:"scs-0217-v1"})}),(0,n.jsx)(s.td,{children:"Standard"}),(0,n.jsx)(s.td,{children:"Draft"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]})})]})]})}function u(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(o,{...e})}):o(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>a,x:()=>i});var n=t(96540);const r={},c=n.createContext(r);function a(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6e45ed1a.102bbdc2.js b/assets/js/6e45ed1a.102bbdc2.js new file mode 100644 index 0000000000..244f273f4e --- /dev/null +++ b/assets/js/6e45ed1a.102bbdc2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4604],{20399:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>r,contentTitle:()=>c,default:()=>f,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var n=t(74848),s=t(28453);const o={sidebar_label:"Certificates"},c="Certificates",a={id:"iaas/guides/configuration-guide/commons/certificates",title:"Certificates",description:"With the osism.commons.certificates role, it is possible to add custom CA certificates",source:"@site/docs/02-iaas/guides/configuration-guide/commons/certificates.md",sourceDirName:"02-iaas/guides/configuration-guide/commons",slug:"/iaas/guides/configuration-guide/commons/certificates",permalink:"/docs/iaas/guides/configuration-guide/commons/certificates",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/certificates.md",tags:[],version:"current",frontMatter:{sidebar_label:"Certificates"},sidebar:"docs",previous:{title:"Commons",permalink:"/docs/iaas/guides/configuration-guide/commons/"},next:{title:"Packages",permalink:"/docs/iaas/guides/configuration-guide/commons/packages"}},r={},d=[];function u(e){const i={a:"a",code:"code",h1:"h1",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.h1,{id:"certificates",children:"Certificates"}),"\n",(0,n.jsxs)(i.p,{children:["With the ",(0,n.jsx)(i.code,{children:"osism.commons.certificates"})," role, it is possible to add custom CA certificates\non a node. The parameter should be used in the ",(0,n.jsx)(i.code,{children:"environments/configuration.yml"})," file."]}),"\n",(0,n.jsx)(i.pre,{children:(0,n.jsx)(i.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"certificates_ca:\n - name: custom.crt\n certificate: |\n -----BEGIN CERTIFICATE-----\n [...]\n -----END CERTIFICATE-----\n"})}),"\n",(0,n.jsxs)(i.p,{children:["The role is part of the bootstrap of a node. CA certificates can be added at a later\npoint in time via ",(0,n.jsx)(i.code,{children:"osism apply certificates"})," on a node."]}),"\n",(0,n.jsxs)(i.p,{children:["Further details on the use of self-signed certificates can be found in chapter\n",(0,n.jsx)(i.a,{href:"../self-signed-certificates",children:"Self-signed certificates"}),"\nof the configuration guide."]})]})}function f(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,i,t)=>{t.d(i,{R:()=>c,x:()=>a});var n=t(96540);const s={},o=n.createContext(s);function c(e){const i=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),n.createElement(o.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6e5bfc33.ca3dd247.js b/assets/js/6e5bfc33.ca3dd247.js new file mode 100644 index 0000000000..f91f75a49c --- /dev/null +++ b/assets/js/6e5bfc33.ca3dd247.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2758],{84450:e=>{e.exports=JSON.parse('{"title":"Central API","slug":"/category/central-api","permalink":"/docs/category/central-api","navigation":{"previous":{"title":"Tuning","permalink":"/docs/operating-scs/components/monitoring/docs/tuning"},"next":{"title":"Overview","permalink":"/docs/operating-scs/components/central-api/overview"}}}')}}]); \ No newline at end of file diff --git a/assets/js/6f1c571c.6cc3f4b2.js b/assets/js/6f1c571c.6cc3f4b2.js new file mode 100644 index 0000000000..aece1a233f --- /dev/null +++ b/assets/js/6f1c571c.6cc3f4b2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8071],{28269:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>d,toc:()=>c});var n=t(74848),i=t(28453);const o={sidebar_label:"Examples"},a="Examples",d={id:"iaas/guides/deploy-guide/examples/index",title:"Examples",description:"",source:"@site/docs/02-iaas/guides/deploy-guide/examples/index.md",sourceDirName:"02-iaas/guides/deploy-guide/examples",slug:"/iaas/guides/deploy-guide/examples/",permalink:"/docs/iaas/guides/deploy-guide/examples/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/examples/index.md",tags:[],version:"current",frontMatter:{sidebar_label:"Examples"},sidebar:"docs",previous:{title:"OpenStack",permalink:"/docs/iaas/guides/deploy-guide/services/openstack"},next:{title:"Cloud in a Box",permalink:"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box"}},l={},c=[];function r(e){const s={h1:"h1",...(0,i.R)(),...e.components};return(0,n.jsx)(s.h1,{id:"examples",children:"Examples"})}function u(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(r,{...e})}):r(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>a,x:()=>d});var n=t(96540);const i={},o=n.createContext(i);function a(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6f4a06ca.20889c99.js b/assets/js/6f4a06ca.20889c99.js new file mode 100644 index 0000000000..f2869b8e3a --- /dev/null +++ b/assets/js/6f4a06ca.20889c99.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2372],{36310:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>c,frontMatter:()=>i,metadata:()=>l,toc:()=>a});var t=s(74848),r=s(28453);const i={sidebar_label:"Manager",sidebar_position:20},o="Manager",l={id:"iaas/guides/deploy-guide/manager",title:"Manager",description:"The prerequisite for deploying the Manager node is a Seed node. What a Seed node is",source:"@site/docs/02-iaas/guides/deploy-guide/manager.md",sourceDirName:"02-iaas/guides/deploy-guide",slug:"/iaas/guides/deploy-guide/manager",permalink:"/docs/iaas/guides/deploy-guide/manager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/manager.md",tags:[],version:"current",sidebarPosition:20,frontMatter:{sidebar_label:"Manager",sidebar_position:20},sidebar:"docs",previous:{title:"Seed",permalink:"/docs/iaas/guides/deploy-guide/seed"},next:{title:"Provisioning",permalink:"/docs/iaas/guides/deploy-guide/provisioning"}},d={},a=[{value:"Deploy the manager service",id:"deploy-the-manager-service",level:2},{value:"Step 1: Create operator user",id:"step-1-create-operator-user",level:3},{value:"Step 2: Apply the network configuration",id:"step-2-apply-the-network-configuration",level:3},{value:"Step 3: Bootstrap the manager node",id:"step-3-bootstrap-the-manager-node",level:3},{value:"Step 4: Deploy the manager service",id:"step-4-deploy-the-manager-service",level:3},{value:"Step 5: Set vault password on the manager service",id:"step-5-set-vault-password-on-the-manager-service",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"manager",children:"Manager"}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsxs)(n.p,{children:["The prerequisite for deploying the Manager node is a Seed node. What a Seed node is\nand how to prepare it is documented in the ",(0,t.jsx)(n.a,{href:"./seed",children:"Seed chapter of the Deploy Guide"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:["The Manager node serves as the central administration instance for managing the cloud environment.\nWith the help of Ansible and other OSISM-specific ",(0,t.jsx)(n.a,{href:"/docs/iaas/guides/concept-guide/",children:"components"}),", the entire\nlife cycle of the system is coordinated from here (installation, customization, upgrades, etc.)."]}),"\n",(0,t.jsx)(n.p,{children:"Requirements for the manager node:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The system should have the following hardware features","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"at least 64 GB RAM (We assume here that the monitoring services are also run on the manager.\nIf the manager node is only used for the sanager Service, 32 GByte is sufficient and\nwith 16 GByte it will probably also work."}),"\n",(0,t.jsx)(n.li,{children:"at least 256 GB hard disk space"}),"\n",(0,t.jsx)(n.li,{children:"the system should be initially and permanently accessible independently of the cloud environment\nitself from the seed node"}),"\n",(0,t.jsx)(n.li,{children:"the system should have direct access to the network areas of the individual server systems in the\ncloud environment"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["An Ubuntu version matching the OSISM version should be ",(0,t.jsx)(n.a,{href:"/docs/iaas/guides/deploy-guide/provisioning",children:"provisioned"})," on the system\n(typically the latest Ubuntu LTS version, a system based on one of the ",(0,t.jsx)(n.a,{href:"https://github.com/osism/node-image",children:"OSISM node images"}),"\nwould be ideal)"]}),"\n",(0,t.jsx)(n.li,{children:"No manual adjustments or installations should have been made on the system apart from the basic installation"}),"\n",(0,t.jsxs)(n.li,{children:["The system has to be accessible from the ",(0,t.jsx)(n.a,{href:"/docs/iaas/guides/deploy-guide/seed",children:"seed node"})," via SSH"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"deploy-the-manager-service",children:"Deploy the manager service"}),"\n",(0,t.jsxs)(n.p,{children:["Change into the ",(0,t.jsx)(n.code,{children:"environments/manager"})," directory of the configuration repository\non the seed node. The deployment of the seed node itself is documented in the\n",(0,t.jsx)(n.a,{href:"../deploy-guide/seed",children:"Deploy Guide for the seed node"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"cd environments/manager\n"})}),"\n",(0,t.jsx)(n.h3,{id:"step-1-create-operator-user",children:"Step 1: Create operator user"}),"\n",(0,t.jsxs)(n.p,{children:["The operator user is created on each node. It is used as a service account for OSISM. All\ncontainers run with this user. Ansible also uses this user to access the nodes. Commands\non the manager node need to be run as this user. The name of the operator user is always ",(0,t.jsx)(n.code,{children:"dragon"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["With ",(0,t.jsx)(n.code,{children:"ANSIBLE_USER"})," the existing user account is set after the provsioning of the management\nnode. When using the ",(0,t.jsx)(n.a,{href:"https://github.com/osism/node-image",children:"osism/node-image"})," the user is ",(0,t.jsx)(n.code,{children:"osism"}),"\nand the password of this user is ",(0,t.jsx)(n.code,{children:"password"}),". If you install Ubuntu manually the user usually\nis ",(0,t.jsx)(n.code,{children:"ubuntu"}),". If you want to use any other user here, that's no problem. It is important that\nthis user has sudo rights. The password according to what you have set yourself."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"ANSIBLE_USER"})," parameter is only required when executing ",(0,t.jsx)(n.code,{children:"operator"})," play using the ",(0,t.jsx)(n.code,{children:"run.sh"}),"\nscript. After this step, the ",(0,t.jsx)(n.code,{children:"ANSIBLE_USER"})," is always set to ",(0,t.jsx)(n.code,{children:"dragon"})," in the ",(0,t.jsx)(n.code,{children:"run.sh"})," script.\nIt is therefore important to only set this parameter for exactly this step."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"ANSIBLE_BECOME_ASK_PASS=True \\\nANSIBLE_ASK_VAULT_PASS=True \\\nANSIBLE_ASK_PASS=True \\\nANSIBLE_USER=osism \\\n./run.sh operator\n"})}),"\n",(0,t.jsxs)(n.p,{children:["When the ",(0,t.jsx)(n.code,{children:"./run.sh operator"})," is executed, the following prompts are displayed."]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{style:{textAlign:"left"},children:"Prompt"}),(0,t.jsx)(n.th,{style:{textAlign:"left"},children:"Value"}),(0,t.jsx)(n.th,{style:{textAlign:"left"},children:"Comment"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:(0,t.jsx)(n.code,{children:"SSH password:"})}),(0,t.jsxs)(n.td,{style:{textAlign:"left"},children:["Password so that the ",(0,t.jsx)(n.code,{children:"ANSIBLE_USER"})," can login"]}),(0,t.jsxs)(n.td,{style:{textAlign:"left"},children:["Enabled by ",(0,t.jsx)(n.code,{children:"ANSIBLE_ASK_PASS"})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:(0,t.jsx)(n.code,{children:"BECOME password[defaults to SSH password]:"})}),(0,t.jsxs)(n.td,{style:{textAlign:"left"},children:["Password so that the ",(0,t.jsx)(n.code,{children:"ANSIBLE_USER"})," can use ",(0,t.jsx)(n.code,{children:"sudo"})]}),(0,t.jsxs)(n.td,{style:{textAlign:"left"},children:["Enabled by ",(0,t.jsx)(n.code,{children:"ANSIBLE_BECOME_ASK_PASS"})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:(0,t.jsx)(n.code,{children:"Vault password:"})}),(0,t.jsxs)(n.td,{style:{textAlign:"left"},children:["Value of ",(0,t.jsx)(n.code,{children:"secrets/vaultpass"})]}),(0,t.jsxs)(n.td,{style:{textAlign:"left"},children:["Enabled by ",(0,t.jsx)(n.code,{children:"ANSIBLE_ASK_VAULT_PASS"})]})]})]})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["If a password is required to login to the manager node, ",(0,t.jsx)(n.code,{children:"ANSIBLE_ASK_PASS=True"})," must be set."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["If an SSH key is required to login to the manager node, the key has to be added on the manager\nnode to ",(0,t.jsx)(n.code,{children:"~/.ssh/authorized_keys"})," in the home directory of the user specified as ",(0,t.jsx)(n.code,{children:"ANSIBLE_USER"})," first."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["If the error ",(0,t.jsx)(n.code,{children:"ERROR! Attempting to decrypt but no vault secrets found"})," occurs, ",(0,t.jsx)(n.code,{children:"ANSIBLE_ASK_VAULT_PASS=True"}),"\nhas to be set."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["If the error ",(0,t.jsx)(n.code,{children:"/bin/sh: 1: /usr/bin/python: not found occurs"}),", Python has to be installed first on\nthe manager node:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"ANSIBLE_USER=osism ./run.sh python3\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["If you receive the following error message ",(0,t.jsx)(n.code,{children:"ssh: Too many authentication failures"})," set\n",(0,t.jsx)(n.code,{children:"ANSIBLE_SSH_ARGS"})," environment variable to use only the operator ssh key for authentication."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'export ANSIBLE_SSH_ARGS="-o IdentitiesOnly=yes"\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["The warning message ",(0,t.jsx)(n.code,{children:"[WARNING]: running playbook inside collection osism.manager"})," can be ignored"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"If Ansible Vault is used, let Ansible ask for the Vault password:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"export ANSIBLE_ASK_VAULT_PASS=True\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Details on all parameters can be found in\n",(0,t.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/reference_appendices/config.html",children:"Ansible Configuration Settings"}),"\nin the Ansible documentation."]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{style:{textAlign:"left"},children:"Environment variable"}),(0,t.jsx)(n.th,{style:{textAlign:"left"},children:"Type"}),(0,t.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:(0,t.jsx)(n.code,{children:"ANSIBLE_ASK_PASS"})}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"Boolean"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"This controls whether an Ansible playbook should prompt for a login password. If using SSH keys for authentication, you probably do not need to change this setting."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:(0,t.jsx)(n.code,{children:"ANSIBLE_ASK_VAULT_PASS"})}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"Boolean"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"This controls whether an Ansible playbook should prompt for a vault password."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:(0,t.jsx)(n.code,{children:"ANSIBLE_BECOME_ASK_PASS"})}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"Boolean"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"Toggle to prompt for privilege escalation password."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:(0,t.jsx)(n.code,{children:"ANSIBLE_SSH_ARGS"})}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"String"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"If set, this will override the Ansible default ssh arguments."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:(0,t.jsx)(n.code,{children:"ANSIBLE_USER"})}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"String"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"The user Ansible \u2018logs in\u2019 as."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{style:{textAlign:"left"},children:["To verify the creation of the operator user, use the private key file ",(0,t.jsx)(n.code,{children:"id_rsa.operator"}),". Make"]}),(0,t.jsx)(n.td,{style:{textAlign:"left"}}),(0,t.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{style:{textAlign:"left"},children:["sure you purge all keys from ssh-agent identity cache using ",(0,t.jsx)(n.code,{children:"ssh-add -D"}),". You can print the list"]}),(0,t.jsx)(n.td,{style:{textAlign:"left"}}),(0,t.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{style:{textAlign:"left"},children:["using ",(0,t.jsx)(n.code,{children:"ssh-add -l"}),". The list should be empty."]}),(0,t.jsx)(n.td,{style:{textAlign:"left"}}),(0,t.jsx)(n.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"ssh-add -D\nssh -o IdentitiesOnly=yes -i id_rsa.operator dragon@testbed-manager\n"})}),"\n",(0,t.jsx)(n.h3,{id:"step-2-apply-the-network-configuration",children:"Step 2: Apply the network configuration"}),"\n",(0,t.jsxs)(n.p,{children:["Most of the parameters required for Ansible (",(0,t.jsx)(n.code,{children:"ANSIBLE_BECOME_ASK_PASS"}),", ",(0,t.jsx)(n.code,{children:"ANSIBLE_ASK_PASS"}),", ",(0,t.jsx)(n.code,{children:"ANSIBLE_USER"}),", ...)\nin the previous step are no longer necessary. If Ansible Vault is used, however, ",(0,t.jsx)(n.code,{children:"ANSIBLE_ASK_VAULT_PASS"}),"\nmust still be set."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"export ANSIBLE_ASK_VAULT_PASS=True\n"})}),"\n",(0,t.jsxs)(n.p,{children:["To prevent recurring installation of Ansible Collections, ",(0,t.jsx)(n.code,{children:"export INSTALL_ANSIBLE_ROLES=False"})," can be set."]}),"\n",(0,t.jsx)(n.p,{children:"The network configuration, already present on a node should be backuped before this step.\nThen you can deploy the network configuration with the network role."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"./run.sh network\n"})}),"\n",(0,t.jsx)(n.p,{children:"Upon completion of the network configurtion, a node reboot should be performed to ensure the configuration\nis functional and reboot safe. Since network services are not restarted automatically, later changes to the\nnetwork configuration are not effective without a manual apply of the network configuration or reboot of the\nnodes."}),"\n",(0,t.jsx)(n.h3,{id:"step-3-bootstrap-the-manager-node",children:"Step 3: Bootstrap the manager node"}),"\n",(0,t.jsxs)(n.p,{children:["Most of the parameters required for Ansible (",(0,t.jsx)(n.code,{children:"ANSIBLE_BECOME_ASK_PASS"}),", ",(0,t.jsx)(n.code,{children:"ANSIBLE_ASK_PASS"}),", ",(0,t.jsx)(n.code,{children:"ANSIBLE_USER"}),", ...)\nin the previous step are no longer necessary."]}),"\n",(0,t.jsxs)(n.p,{children:["If Ansible Vault is used, however, ",(0,t.jsx)(n.code,{children:"export ANSIBLE_ASK_VAULT_PASS=True"})," must still be set."]}),"\n",(0,t.jsxs)(n.p,{children:["To prevent recurring installation of Ansible Collections, ",(0,t.jsx)(n.code,{children:"export INSTALL_ANSIBLE_ROLES=False"})," can be set.\nThis is recommended."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Bootstrap the manager node."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"./run.sh bootstrap\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Reboot the manager node."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"./run.sh reboot\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"step-4-deploy-the-manager-service",children:"Step 4: Deploy the manager service"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Transfer the configuration repository."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"./run.sh configuration\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy the Traefik service. This is optional and only necessary if the Traefik service is to be used."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"./run.sh traefik\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy the Netbox service. This is optional and only necessary if the Netbox service is to be used."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"./run.sh netbox\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy the manager service."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"./run.sh manager\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"step-5-set-vault-password-on-the-manager-service",children:"Step 5: Set vault password on the manager service"}),"\n",(0,t.jsxs)(n.p,{children:["Finally, the Ansible Vault password is made known on the manager node. Before that, log in to the manager node\nwith the ",(0,t.jsx)(n.code,{children:"dragon"})," user."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism set vault password\nAnsible Vault password: ********\n"})}),"\n",(0,t.jsx)(n.p,{children:"Ready. The manager is now prepared and you can continue with the bootstrap of the other nodes.\nThe seed node used until here is no longer necessary."})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7023f74c.bba7410f.js b/assets/js/7023f74c.bba7410f.js new file mode 100644 index 0000000000..3aed42aca5 --- /dev/null +++ b/assets/js/7023f74c.bba7410f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4869],{398:(e,a,t)=>{t.r(a),t.d(a,{assets:()=>o,contentTitle:()=>c,default:()=>u,frontMatter:()=>d,metadata:()=>s,toc:()=>r});var n=t(74848),i=t(28453);const d={sidebar_label:"Automated updates",sidebar_position:1},c="Image Manager update.py",s={id:"iaas/components/image-manager/update",title:"Image Manager update.py",description:"Overview",source:"@site/docs/02-iaas/components/image-manager/update.md",sourceDirName:"02-iaas/components/image-manager",slug:"/iaas/components/image-manager/update",permalink:"/docs/iaas/components/image-manager/update",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/image-manager/update.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_label:"Automated updates",sidebar_position:1},sidebar:"docs",previous:{title:"Image Manager",permalink:"/docs/iaas/components/image-manager/"},next:{title:"Flavor Manager",permalink:"/docs/iaas/components/flavor-manager"}},o={},r=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Usage",id:"usage",level:2}];function m(e){const a={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(a.h1,{id:"image-manager-updatepy",children:"Image Manager update.py"}),"\n",(0,n.jsx)(a.h2,{id:"overview",children:"Overview"}),"\n",(0,n.jsxs)(a.p,{children:["The OpenStack Image Manager ",(0,n.jsx)(a.code,{children:"update.py"})," Script updates the ",(0,n.jsx)(a.code,{children:"/etc/images/*.yaml"})," files to the always latest release of the Distributions, set S3 Mirror Urls and uploads the Images to the mirror."]}),"\n",(0,n.jsx)(a.p,{children:"These updated yaml files are later processed by the Image Manger itself."}),"\n",(0,n.jsx)(a.h2,{id:"installation",children:"Installation"}),"\n",(0,n.jsxs)(a.p,{children:["Prepare to use the ",(0,n.jsx)(a.code,{children:"update.py"})," script."]}),"\n",(0,n.jsx)(a.pre,{children:(0,n.jsx)(a.code,{children:"git clone https://github.com/osism/openstack-image-manager/ \ncd openstack-image-manager\npipenv install\npipenv shell\n"})}),"\n",(0,n.jsx)(a.h2,{id:"usage",children:"Usage"}),"\n",(0,n.jsx)(a.pre,{children:(0,n.jsx)(a.code,{children:"python contrib/update.py --help\n \n Usage: update.py [OPTIONS] \n \n\u256d\u2500 Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 --debug Enable debug logging \u2502\n\u2502 --dry-run Do not perform any changes \u2502\n\u2502 --minio-access-key TEXT Minio access key [env var: MINIO_ACCESS_KEY] [default: None] \u2502\n\u2502 --minio-secret-key TEXT Minio secret key [env var: MINIO_SECRET_KEY] [default: None] \u2502\n\u2502 --minio-server TEXT Minio server [env var: MINIO_SERVER] [default: swift.services.a.regiocloud.tech] \u2502\n\u2502 --minio-bucket TEXT Minio bucket [env var: MINIO_BUCKET] [default: openstack-images] \u2502\n\u2502 --swift-prefix TEXT Swift prefix [env var: SWIFT_PREFIX] [default: swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/] \u2502\n\u2502 --install-completion Install completion for the current shell. \u2502\n\u2502 --show-completion Show completion for the current shell, to copy it or customize the installation. \u2502\n\u2502 --help Show this message and exit. \u2502\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n"})}),"\n",(0,n.jsx)(a.admonition,{type:"note",children:(0,n.jsxs)(a.ul,{children:["\n",(0,n.jsx)(a.li,{children:"At this time the update.py expects all yamls Files at /etc/images/, which can't be configured at the moment."}),"\n",(0,n.jsx)(a.li,{children:"Mirroring can't be disabled at the moment."}),"\n"]})}),"\n",(0,n.jsxs)(a.p,{children:["Best is to run this Script by cron or a CI job, to update all Distribution Files periodically to the latest release and afterwards run ",(0,n.jsx)(a.a,{href:"../image-manager/",children:"Openstack Image Manager"}),".\nThe Distribution Image yaml files must exists before running the script, you can use the files from Github repo at ",(0,n.jsx)(a.code,{children:"etc/images/"})," as template for your first run."]}),"\n",(0,n.jsx)(a.pre,{children:(0,n.jsx)(a.code,{children:"$ python contrib/update.py\n2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/centos.yml\n2024-04-24 09:29:44 | INFO | update_image:179 - Checking image CentOS Stream 9\n2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-HEREBE\\d+\\.\\dDRAGONS.x86_64.qcow2\n2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cloud.centos.org/centos/9-stream/x86_64/images/CHECKSUM\n2024-04-24 09:29:44 | INFO | get_latest_default:62 - Latest URL is now https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2\n2024-04-24 09:29:44 | INFO | get_latest_default:63 - Latest filename is now CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2\n2024-04-24 09:29:44 | INFO | update_image:192 - Checksum of current CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337\n2024-04-24 09:29:44 | INFO | update_image:208 - Our checksum is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337\n2024-04-24 09:29:44 | INFO | update_image:211 - Image CentOS Stream 9 is up-to-date, nothing to do\n2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/debian.yml\n2024-04-24 09:29:44 | INFO | update_image:179 - Checking image Debian 11\n2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bullseye/latest/debian-11-genericcloud-amd64.raw\n2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bullseye/latest/SHA512SUMS\n2024-04-24 09:29:45 | INFO | update_image:192 - Checksum of current debian-11-genericcloud-amd64-20240211-1654.raw is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4\n2024-04-24 09:29:45 | INFO | update_image:208 - Our checksum is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4\n2024-04-24 09:29:45 | INFO | update_image:211 - Image Debian 11 is up-to-date, nothing to do\n2024-04-24 09:29:45 | INFO | update_image:179 - Checking image Debian 12\n2024-04-24 09:29:45 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.raw\n2024-04-24 09:29:45 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS\n2024-04-24 09:29:46 | INFO | update_image:192 - Checksum of current debian-12-genericcloud-amd64-daily-20240424-1727.raw is sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e\n2024-04-24 09:29:46 | INFO | update_image:208 - Our checksum is sha512:5401f8c6361bb2a82c2c24b4b4606d95e77229152a80e61f9c613bc88e25de9257057d0ed68b0256b745c4059162a54970fe4a8daf456b2eb67b4f5db5c97fcc\n2024-04-24 09:29:46 | INFO | update_image:229 - New values are {'version': '20240424', 'build_date': datetime.date(2024, 4, 24), 'checksum': 'sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e', 'url': 'https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240424-1727/debian-12-genericcloud-amd64-daily-20240424-1727.raw'}\n2024-04-24 09:29:46 | INFO | main:300 - Processing file /etc/images/rockylinux.yml\n2024-04-24 09:29:46 | INFO | update_image:179 - Checking image Rocky 9\n2024-04-24 09:29:46 | INFO | update_image:182 - Latest download URL is https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2\n2024-04-24 09:29:46 | INFO | update_image:185 - Getting checksums from https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2.CHECKSUM\n2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current Rocky-9-GenericCloud.latest.x86_64.qcow2 is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651\n2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651\n2024-04-24 09:29:47 | INFO | update_image:211 - Image Rocky_9 is up-to-date, nothing to do\n2024-04-24 09:29:47 | INFO | main:300 - Processing file /etc/images/ubuntu.yml\n2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04\n2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img\n2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS\n2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current jammy-server-cloudimg-amd64.img is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710\n2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710\n2024-04-24 09:29:47 | INFO | update_image:211 - Image Ubuntu_22.04 is up-to-date, nothing to do\n2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04 Minimal\n2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64.img\n2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/minimal/releases/jammy/release/SHA256SUMS\n2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current ubuntu-22.04-minimal-cloudimg-amd64.img is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65\n2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65\n2024-04-24 09:29:48 | INFO | update_image:211 - Image Ubuntu 22.04 Minimal is up-to-date, nothing to do\n2024-04-24 09:29:48 | INFO | update_image:179 - Checking image Ubuntu 24.04\n2024-04-24 09:29:48 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img\n2024-04-24 09:29:48 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/noble/current/SHA256SUMS\n2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current noble-server-cloudimg-amd64.img is sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3\n2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:d7ba8d5d1d073f2dc8351973bf4f35157c846a0ea6ee16fb2a9f45a78953e4a7\n2024-04-24 09:29:48 | INFO | update_image:229 - New values are {'version': '20240423', 'build_date': datetime.date(2024, 4, 23), 'checksum': 'sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3', 'url': 'https://cloud-images.ubuntu.com/noble/20240423/noble-server-cloudimg-amd64.img'}\n"})}),"\n",(0,n.jsx)(a.p,{children:"These yaml files are now extended with additional fields and the update.py will take care of the versions, checksum, url and build date to the latest release in the yaml file on every run."}),"\n",(0,n.jsxs)(a.ul,{children:["\n",(0,n.jsx)(a.li,{children:"latest_checksum_url - URL of the distros checksum file"}),"\n",(0,n.jsx)(a.li,{children:"latest_url - URL of the distros latest image"}),"\n",(0,n.jsx)(a.li,{children:"mirror_url - URL of the Image File at the local S3 Mirror"}),"\n"]}),"\n",(0,n.jsx)(a.pre,{children:(0,n.jsx)(a.code,{className:"language-yaml",metastring:'title="someexample.yaml"',children:"---\nimages:\n - name: Debian 12\n enable: true\n shortname: debian-12\n format: qcow2\n login: debian\n min_disk: 8\n min_ram: 512\n status: active\n visibility: public\n multi: true\n meta:\n architecture: x86_64\n hw_disk_bus: scsi\n hw_rng_model: virtio\n hw_scsi_model: virtio-scsi\n hw_watchdog_action: reset\n hypervisor_type: qemu\n os_distro: debian\n os_version: '12'\n replace_frequency: quarterly\n uuid_validity: last-3\n provided_until: none\n tags: []\n latest_checksum_url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS\n latest_url:\n https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.qcow2\n versions:\n - build_date: 2024-04-11\n checksum:\n sha512:3d6f26616e2c8b705993ddef874232887cebe42f1e70fcc020827ac88e8990177d537d34538c71ae2afd3b8baca953fff71eaa7ef71e752e82532c93dcdca436\n url:\n https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240411-1714/debian-12-genericcloud-amd64-daily-20240411-1714.qcow2\n mirror_url:\n https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-images/debian-12/20240411-debian-12.qcow2\n version: '20240411'\n\n"})})]})}function u(e={}){const{wrapper:a}={...(0,i.R)(),...e.components};return a?(0,n.jsx)(a,{...e,children:(0,n.jsx)(m,{...e})}):m(e)}},28453:(e,a,t)=>{t.d(a,{R:()=>c,x:()=>s});var n=t(96540);const i={},d=n.createContext(i);function c(e){const a=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function s(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),n.createElement(d.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/70b53392.96f3eb66.js b/assets/js/70b53392.96f3eb66.js new file mode 100644 index 0000000000..97ec6c4fb7 --- /dev/null +++ b/assets/js/70b53392.96f3eb66.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9110],{24139:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var n=s(74848),r=s(28453);const i={title:"Architecture for the Cloud Service provider Observability System for the KaaS Layer",type:"Decision Record",status:"Draft",track:"Ops"},a=void 0,o={id:"scs-0403-v1-csp-kaas-observability-stack",title:"Architecture for the Cloud Service provider Observability System for the KaaS Layer",description:"Introduction",source:"@site/standards/scs-0403-v1-csp-kaas-observability-stack.md",sourceDirName:".",slug:"/scs-0403-v1-csp-kaas-observability-stack",permalink:"/standards/scs-0403-v1-csp-kaas-observability-stack",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Architecture for the Cloud Service provider Observability System for the KaaS Layer",type:"Decision Record",status:"Draft",track:"Ops"},sidebar:"standards",previous:{title:"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer",permalink:"/standards/ops/scs-0403"},next:{title:"scs-0410: Gnocchi as database for metering",permalink:"/standards/ops/scs-0410"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Requirements",id:"requirements",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Use of the dNation Observability Stack as a base",id:"use-of-the-dnation-observability-stack-as-a-base",level:4},{value:"Pull-based Architecture",id:"pull-based-architecture",level:4},{value:"Push-based Archtitecture",id:"push-based-archtitecture",level:4},{value:"Scope of the Observability Architecture",id:"scope-of-the-observability-architecture",level:4},{value:"Observing the Observability Infrastructure",id:"observing-the-observability-infrastructure",level:4},{value:"Alerting Rulesets",id:"alerting-rulesets",level:4},{value:"Decisions",id:"decisions",level:2},{value:"Reference",id:"reference",level:2},{value:"Outcome of the CSP Survey about Requirements for KaaS Observability",id:"outcome-of-the-csp-survey-about-requirements-for-kaas-observability",level:3}];function c(e){const t={a:"a",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsx)(t.p,{children:"Cloud Service Providers offer a variety of products to a customer. Those can include compute resources like virtual machines, networking, and identity and access management. As customers of those services build their applications upon those offered services the service provider needs to ensure a certain quality level of their offerings. This is done by observing the infrastructure. Observability systems leverage different types of telemetry data which include:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"Metrics: Usually time series data about different parameters of a system which can include e.g. CPU usage, number of active requests, health status, etc."}),"\n",(0,n.jsx)(t.li,{children:"Logs: Messages of software events during runtime"}),"\n",(0,n.jsx)(t.li,{children:"Traces: A more developer-oriented form of logging to provide insights into an application or to analyze request flows in distributed systems."}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"Based on those data, an alerting system can be used to send out notifications to an Operations Team if a system behaves abnormally. Based on the telemetry data the Operations Team can find the issue, work on it, and mitigate future incidents."}),"\n",(0,n.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,n.jsx)(t.p,{children:"Currently, only the IaaS Layer of the SCS Reference Implementation has an Observability Stack consisting of tools like Prometheus, Grafana, and Alertmanager as well as several Exporters to extract monitoring data from the several OpenStack components and additional software that is involved in the Reference Implementation. As the Kubernetes as a Service Layer becomes more and more important and the work on the Cluster API approach to create customer clusters progresses further, an observability solution for this layer is also needed. CSP should be able to watch over customer clusters and intervene if a cluster gets in a malfunctioning state. For this, a toolset and architecture are needed which is proposed in this ADR."}),"\n",(0,n.jsx)(t.h2,{id:"requirements",children:"Requirements"}),"\n",(0,n.jsx)(t.p,{children:"A survey was conducted to gather the needs and requirements of a CSP when providing Kubernetes as a Service. The feedback of the survey led to the following requirement on a Kubernetes as a Service Observability System:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Telemetry Data that MUST be fetched:","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"CPU, RAM, Disk, Network"}),"\n",(0,n.jsx)(t.li,{children:"HTTP Connectivity Metrics"}),"\n",(0,n.jsx)(t.li,{children:"Control Plane and Pod metrics (States, Ready, etc.)"}),"\n",(0,n.jsx)(t.li,{children:"K8s certs metrics"}),"\n",(0,n.jsx)(t.li,{children:"Metrics of underlying node"}),"\n",(0,n.jsx)(t.li,{children:"Logs of control plane, kubelet and containerd"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["Telemetry Data that MAY be fetched:","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"K8s resources (exporters, kubestate metrics, cadvisor, parts of the kubelet)"}),"\n",(0,n.jsx)(t.li,{children:"Ingress controller exporter (http error rate, cert metrics like expiration date)"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["Telemetry Data that SHOULD NOT BE fetched:","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Any metrics or logs a CSP does not need to provide support with respect to their SLA with a Customer."}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["Telemetry Data that MUST NOT be fetched:","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Secrets"}),"\n",(0,n.jsx)(t.li,{children:"Customer Specific Workload Metrics"}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.li,{children:"The Alerting Mechanism MUST include a default ruleset"}),"\n",(0,n.jsx)(t.li,{children:"The Observability Stack MUST run on the CSP Infrastructure"}),"\n",(0,n.jsx)(t.li,{children:"The Observability Stack MUST be High Available"}),"\n",(0,n.jsx)(t.li,{children:"The Observability Stack MUST be able to observe itself"}),"\n",(0,n.jsx)(t.li,{children:"Observed Clusters SHOULD have a low resource impact on the used software to provide telemetry data for the Observability Stack"}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,n.jsx)(t.h4,{id:"use-of-the-dnation-observability-stack-as-a-base",children:"Use of the dNation Observability Stack as a base"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.a,{href:"https://github.com/dNationCloud/kubernetes-monitoring",children:"dNation monitoring stack"})," offers a lot of basic capabilities needed on an observability stack for Kubernetes like Prometheus Operator, Grafana, Alertmanager, Loki, Promtail and Thanos."]}),"\n",(0,n.jsx)(t.h4,{id:"pull-based-architecture",children:"Pull-based Architecture"}),"\n",(0,n.jsx)(t.p,{children:"Each customer cluster has Thanos and Prometheus installed in addition to Thanos and Prometheus on the Observer Cluster. Metrics of a customer cluster are pulled from Thanos (Customer Cluster) for short term queries, as for long term queries the data of all Thanos instances is stored in an external Object Store of the CSP."}),"\n",(0,n.jsx)(t.h4,{id:"push-based-archtitecture",children:"Push-based Archtitecture"}),"\n",(0,n.jsx)(t.p,{children:"Here, Thanos and Prometheus are only used on the CSP side to store and manage all observability data. For the customer clusters only the Prometheus Agent will be used. Prometheus Agent will push all metrics of a Customer Cluster to the central Thanos instance and is preserved in an external Object Store. This introduces less complexity and resource consumption on the customer workload clusters."}),"\n",(0,n.jsx)(t.h4,{id:"scope-of-the-observability-architecture",children:"Scope of the Observability Architecture"}),"\n",(0,n.jsx)(t.p,{children:"The Observability Cluster and Architecture SHOULD be defined in a modular way so that it can be used to not only observe the Kubernetes Layer of an SCS Stack, but every aspect of an SCS Stack."}),"\n",(0,n.jsx)(t.h4,{id:"observing-the-observability-infrastructure",children:"Observing the Observability Infrastructure"}),"\n",(0,n.jsx)(t.p,{children:"For usage in production, it needs to be possible to observe the Observability Cluster itself."}),"\n",(0,n.jsx)(t.h4,{id:"alerting-rulesets",children:"Alerting Rulesets"}),"\n",(0,n.jsxs)(t.p,{children:["Use a mix of ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/alerts",children:"kubernetes-mixin alerts"})," and ",(0,n.jsx)(t.a,{href:"https://github.com/dNationCloud/kubernetes-monitoring/tree/main/jsonnet/rules",children:"dNation Alerts Ruleset"}),", as they offer an extensive and well reviewed set of default Alerts covering the important Parts of a Kubernetes Deployment (Nodes, Controlplane, K8s Resources, etc.)"]}),"\n",(0,n.jsx)(t.h2,{id:"decisions",children:"Decisions"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"Base the MVP-0 Implementation on the dNation Kubernetes Monitoring Stack."}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"Push-based"})," Architecture was chosen over the Pull-based Approach."]}),"\n",(0,n.jsx)(t.li,{children:"The Observability Stack will be created based on the dNation observability stack"}),"\n",(0,n.jsx)(t.li,{children:"The Observability Stack can be used as a standalone component to use with the Kubernetes Layer. It should be possible to observe other parts of an SCS Stack like the status of the OpenStack components, but this will not be mandatory."}),"\n",(0,n.jsx)(t.li,{children:"The Observability Stack should be designed that it is possible to provision two observer clusters side by side, observing each other. To do this is only a recommendation for production usage."}),"\n",(0,n.jsxs)(t.li,{children:["The MVP-0 will consist of the following features:","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Observability data from KaaS Clusters is scraped","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"K8s cluster that hosts observer deployment is deployed"}),"\n",(0,n.jsx)(t.li,{children:"S3 compatible bucket as a storage for long term metrics is configured"}),"\n",(0,n.jsx)(t.li,{children:"thanos query-frontend is deployed and configured"}),"\n",(0,n.jsx)(t.li,{children:"thanos query is deployed and configured"}),"\n",(0,n.jsx)(t.li,{children:"thanos reciever is deployed and configured (simple deployment, non HA, without router)"}),"\n",(0,n.jsx)(t.li,{children:"thanos ruler is deployed and configured"}),"\n",(0,n.jsx)(t.li,{children:"thanos compactor is deployed and configured"}),"\n",(0,n.jsx)(t.li,{children:"thanos bucket-web is deployed and configured"}),"\n",(0,n.jsx)(t.li,{children:"thanos storegateway is deployed and configured"}),"\n",(0,n.jsx)(t.li,{children:"prometheus server is deployed and configured"}),"\n",(0,n.jsx)(t.li,{children:"prometheus alertmanager is deployed and configured"}),"\n",(0,n.jsx)(t.li,{children:"prometheus black-box exporter is deployed and configured"}),"\n",(0,n.jsx)(t.li,{children:"kaas-metric-importer is deployed and configured (service aims to differentiate between intentional deletion of KaaS instances and failures in the KaaS monitoring agent)"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["Alerts are defined on the KaaS Clusters metrics","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"all prometheus alerts are working as expected"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["There exist Dashboards for KaaS Cluster Health","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"KaaS L0 dashboard counters are working correctly"}),"\n",(0,n.jsx)(t.li,{children:"Dedicated L0 dashboards are deployed for KaaS and for IaaS monitoring layers"}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.li,{children:"There exist Dashboards for SCS services endpoinds health (BlackBox exporter)"}),"\n",(0,n.jsx)(t.li,{children:"There exist Dashboards for IaaS layer health"}),"\n",(0,n.jsxs)(t.li,{children:["Automatic Setup of Exporters for Observability of managed K8s clusters","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"KaaS service is mocked"}),"\n",(0,n.jsx)(t.li,{children:"VM that will host a mock of KaaS service is deployed"}),"\n",(0,n.jsx)(t.li,{children:"a script that deploys a multiple KinD clusters and register them in observer is created"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["Automatic Setup of Thanos sidecar for Observability of IaaS layer (testbed)","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"IaaS service is mocked"}),"\n",(0,n.jsx)(t.li,{children:"OSISM testbed is deployed"}),"\n",(0,n.jsx)(t.li,{children:"implement an option to deploy thanos sidecar with some simple config in OSISM testbed"}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.li,{children:"There exist Dashboards for Harbor Registry Health"}),"\n",(0,n.jsx)(t.li,{children:"Alerts are defined on the Harbor Registry metrics"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"reference",children:"Reference"}),"\n",(0,n.jsx)(t.h3,{id:"outcome-of-the-csp-survey-about-requirements-for-kaas-observability",children:"Outcome of the CSP Survey about Requirements for KaaS Observability"}),"\n",(0,n.jsx)(t.p,{children:"A survey was conducted to gather the needs and requirements of a CSP when providing Kubernetes as a Service. The results of the Survey (Questions with answers) were the following:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"What is your understanding of a managed Kubernetes Offering:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Hassle-Free Installation and Maintainance (customer viewpoint); Providing Controlplane and worker nodes and responsibility for correct function but agnostic to workload"}),"\n",(0,n.jsx)(t.li,{children:"Day0, 1 and 2 (~planning, provisioning, operations) full lifecyle management or let customer manages some parts of that, depending on customer contract"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"What Type and Depth of observability is needed"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"CPU, RAM, HDD and Network usage, Health and Function of Cluster Nodes, Controlplane and if desired Customer Workload"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Do you have an observabiltiy infrastructure, if yes, how it is built"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Grafana/Thanos/Prometheus/Loki/Promtail/Alertmanger Stack, i.e. ",(0,n.jsx)(t.a,{href:"https://raw.githubusercontent.com/dNationCloud/kubernetes-monitoring-stack/main/thanos-deployment-architecture.svg",children:"Example Infrastructure"})]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Data Must haves"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"CPU, RAM, Disk, Network"}),"\n",(0,n.jsx)(t.li,{children:"HTTP Connectivity Metrics"}),"\n",(0,n.jsx)(t.li,{children:"Control Plane and Pod metrics (States, Ready, etc.)"}),"\n",(0,n.jsx)(t.li,{children:"Workload specific metrics"}),"\n",(0,n.jsx)(t.li,{children:"Node Stats"}),"\n",(0,n.jsx)(t.li,{children:"K8s resources (exporters, kubestate metrics, cadvisor, parts of the kubelet)"}),"\n",(0,n.jsx)(t.li,{children:"Ingress controller exporter (http error rate, cert metrics like expiration date)"}),"\n",(0,n.jsx)(t.li,{children:"K8s certs metrics"}),"\n",(0,n.jsx)(t.li,{children:"Metrics of underlying node"}),"\n",(0,n.jsx)(t.li,{children:"Logs of control plane, kubelet and containerd"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Must Not haves"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Secrets, otherwise as much as possible for anomaly detection over long time data"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Must have Alerts"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Dependent on SLAs and SLA Types, highly individual"}),"\n",(0,n.jsxs)(t.li,{children:["Use of ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/alerts",children:"kubernetes-mixin alerts"})," and ",(0,n.jsx)(t.a,{href:"https://github.com/dNationCloud/kubernetes-monitoring/tree/main/jsonnet/rules",children:"dNation Alerts Ruleset"})]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Must NOT Alert on"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Should not wake people, nothing that does not lead to Action items"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Observability from Within Or Outside KaaS. How does the architecture look like?"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Monitoring Infra on CSP Side"}),"\n",(0,n.jsx)(t.li,{children:"Data from Customer Clusters and Mon Infra on CSP and KaaS, get both data. KaaS Monitoring can also be used by customer"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Special Constraints"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"HA Setup in different Clusters on Different Sites"}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>o});var n=s(96540);const r={},i=n.createContext(r);function a(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7121.d558c084.js b/assets/js/7121.d558c084.js new file mode 100644 index 0000000000..0ab5be39e8 --- /dev/null +++ b/assets/js/7121.d558c084.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7121],{10646:(e,t,n)=>{n.d(t,{H:()=>l});var r=n(82933);function l(e,t){var n=e.append("foreignObject").attr("width","100000"),l=n.append("xhtml:div");l.attr("xmlns","http://www.w3.org/1999/xhtml");var o=t.label;switch(typeof o){case"function":l.insert(o);break;case"object":l.insert((function(){return o}));break;default:l.html(o)}r.AV(l,t.labelStyle),l.style("display","inline-block"),l.style("white-space","nowrap");var a=l.node().getBoundingClientRect();return n.attr("width",a.width).attr("height",a.height),n}},82933:(e,t,n)=>{n.d(t,{AV:()=>c,De:()=>o,c$:()=>p,gh:()=>a,nh:()=>d});var r=n(34963),l=n(89610);function o(e,t){return!!e.children(t).length}function a(e){return i(e.v)+":"+i(e.w)+":"+i(e.name)}var s=/:/g;function i(e){return e?String(e).replace(s,"\\:"):""}function c(e,t){t&&e.attr("style",t)}function d(e,t,n){t&&e.attr("class",t).attr("class",n+" "+e.attr("class"))}function p(e,t){var n=t.graph();if(r.A(n)){var o=n.transition;if(l.A(o))return o(e)}return e}},75937:(e,t,n)=>{n.d(t,{A:()=>o});var r=n(72453),l=n(74886);const o=(e,t)=>r.A.lang.round(l.A.parse(e)[t])},29502:(e,t,n)=>{n.d(t,{diagram:()=>i});var r=n(66216),l=(n(697),n(26312));n(76257),n(48585),n(23068),n(8058),n(21176),n(82933);n(10646);n(5664),n(91395);n(81942);l.lUB;var o=n(98696);n(74353),n(16750),n(42838),n(14075);const a={},s=function(e){const t=Object.keys(e);for(const n of t)a[n]=e[n]},i={parser:r.p,db:r.f,renderer:o.f,styles:o.a,init:e=>{e.flowchart||(e.flowchart={}),e.flowchart.arrowMarkerAbsolute=e.arrowMarkerAbsolute,s(e.flowchart),r.f.clear(),r.f.setGen("gen-1")}}},98696:(e,t,n)=>{n.d(t,{a:()=>f,f:()=>w});var r=n(697),l=n(26312),o=n(76257),a=n(92746),s=n(10646),i=n(75937),c=n(25582);const d={},p=async function(e,t,n,r,l,a){const i=r.select(`[id="${n}"]`),c=Object.keys(e);for(const d of c){const n=e[d];let r="default";n.classes.length>0&&(r=n.classes.join(" ")),r+=" flowchart-label";const c=(0,o.k)(n.styles);let p,b=void 0!==n.text?n.text:n.id;if(o.l.info("vertex",n,n.labelType),"markdown"===n.labelType)o.l.info("vertex",n,n.labelType);else if((0,o.m)((0,o.c)().flowchart.htmlLabels)){const e={label:b};p=(0,s.H)(i,e).node(),p.parentNode.removeChild(p)}else{const e=l.createElementNS("http://www.w3.org/2000/svg","text");e.setAttribute("style",c.labelStyle.replace("color:","fill:"));const t=b.split(o.e.lineBreakRegex);for(const n of t){const t=l.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","1"),t.textContent=n,e.appendChild(t)}p=e}let w=0,f="";switch(n.type){case"round":w=5,f="rect";break;case"square":case"group":default:f="rect";break;case"diamond":f="question";break;case"hexagon":f="hexagon";break;case"odd":case"odd_right":f="rect_left_inv_arrow";break;case"lean_right":f="lean_right";break;case"lean_left":f="lean_left";break;case"trapezoid":f="trapezoid";break;case"inv_trapezoid":f="inv_trapezoid";break;case"circle":f="circle";break;case"ellipse":f="ellipse";break;case"stadium":f="stadium";break;case"subroutine":f="subroutine";break;case"cylinder":f="cylinder";break;case"doublecircle":f="doublecircle"}const h=await(0,o.r)(b,(0,o.c)());t.setNode(n.id,{labelStyle:c.labelStyle,shape:f,labelText:h,labelType:n.labelType,rx:w,ry:w,class:r,style:c.style,id:n.id,link:n.link,linkTarget:n.linkTarget,tooltip:a.db.getTooltip(n.id)||"",domId:a.db.lookUpDomId(n.id),haveCallback:n.haveCallback,width:"group"===n.type?500:void 0,dir:n.dir,type:n.type,props:n.props,padding:(0,o.c)().flowchart.padding}),o.l.info("setNode",{labelStyle:c.labelStyle,labelType:n.labelType,shape:f,labelText:h,rx:w,ry:w,class:r,style:c.style,id:n.id,domId:a.db.lookUpDomId(n.id),width:"group"===n.type?500:void 0,type:n.type,dir:n.dir,props:n.props,padding:(0,o.c)().flowchart.padding})}},b=async function(e,t,n){o.l.info("abc78 edges = ",e);let r,a,s=0,i={};if(void 0!==e.defaultStyle){const t=(0,o.k)(e.defaultStyle);r=t.style,a=t.labelStyle}for(const c of e){s++;const n="L-"+c.start+"-"+c.end;void 0===i[n]?(i[n]=0,o.l.info("abc78 new entry",n,i[n])):(i[n]++,o.l.info("abc78 new entry",n,i[n]));let p=n+"-"+i[n];o.l.info("abc78 new link id to be used is",n,p,i[n]);const b="LS-"+c.start,w="LE-"+c.end,f={style:"",labelStyle:""};switch(f.minlen=c.length||1,"arrow_open"===c.type?f.arrowhead="none":f.arrowhead="normal",f.arrowTypeStart="arrow_open",f.arrowTypeEnd="arrow_open",c.type){case"double_arrow_cross":f.arrowTypeStart="arrow_cross";case"arrow_cross":f.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":f.arrowTypeStart="arrow_point";case"arrow_point":f.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":f.arrowTypeStart="arrow_circle";case"arrow_circle":f.arrowTypeEnd="arrow_circle"}let h="",u="";switch(c.stroke){case"normal":h="fill:none;",void 0!==r&&(h=r),void 0!==a&&(u=a),f.thickness="normal",f.pattern="solid";break;case"dotted":f.thickness="normal",f.pattern="dotted",f.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":f.thickness="thick",f.pattern="solid",f.style="stroke-width: 3.5px;fill:none;";break;case"invisible":f.thickness="invisible",f.pattern="solid",f.style="stroke-width: 0;fill:none;"}if(void 0!==c.style){const e=(0,o.k)(c.style);h=e.style,u=e.labelStyle}f.style=f.style+=h,f.labelStyle=f.labelStyle+=u,void 0!==c.interpolate?f.curve=(0,o.n)(c.interpolate,l.lUB):void 0!==e.defaultInterpolate?f.curve=(0,o.n)(e.defaultInterpolate,l.lUB):f.curve=(0,o.n)(d.curve,l.lUB),void 0===c.text?void 0!==c.style&&(f.arrowheadStyle="fill: #333"):(f.arrowheadStyle="fill: #333",f.labelpos="c"),f.labelType=c.labelType,f.label=await(0,o.r)(c.text.replace(o.e.lineBreakRegex,"\n"),(0,o.c)()),void 0===c.style&&(f.style=f.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),f.labelStyle=f.labelStyle.replace("color:","fill:"),f.id=p,f.classes="flowchart-link "+b+" "+w,t.setEdge(c.start,c.end,f,s)}},w={setConf:function(e){const t=Object.keys(e);for(const n of t)d[n]=e[n]},addVertices:p,addEdges:b,getClasses:function(e,t){return t.db.getClasses()},draw:async function(e,t,n,s){o.l.info("Drawing flowchart");let i=s.db.getDirection();void 0===i&&(i="TD");const{securityLevel:c,flowchart:d}=(0,o.c)(),w=d.nodeSpacing||50,f=d.rankSpacing||50;let h;"sandbox"===c&&(h=(0,l.Ltv)("#i"+t));const u="sandbox"===c?(0,l.Ltv)(h.nodes()[0].contentDocument.body):(0,l.Ltv)("body"),g="sandbox"===c?h.nodes()[0].contentDocument:document,y=new r.T({multigraph:!0,compound:!0}).setGraph({rankdir:i,nodesep:w,ranksep:f,marginx:0,marginy:0}).setDefaultEdgeLabel((function(){return{}}));let k;const x=s.db.getSubGraphs();o.l.info("Subgraphs - ",x);for(let r=x.length-1;r>=0;r--)k=x[r],o.l.info("Subgraph - ",k),s.db.addVertex(k.id,{text:k.title,type:k.labelType},"group",void 0,k.classes,k.dir);const v=s.db.getVertices(),m=s.db.getEdges();o.l.info("Edges",m);let S=0;for(S=x.length-1;S>=0;S--){k=x[S],(0,l.Ubm)("cluster").append("text");for(let e=0;e<k.nodes.length;e++)o.l.info("Setting up subgraphs",k.nodes[e],k.id),y.setParent(k.nodes[e],k.id)}await p(v,y,t,u,g,s),await b(m,y);const T=u.select(`[id="${t}"]`),_=u.select("#"+t+" g");if(await(0,a.r)(_,y,["point","circle","cross"],"flowchart",t),o.u.insertTitle(T,"flowchartTitleText",d.titleTopMargin,s.db.getDiagramTitle()),(0,o.o)(y,T,d.diagramPadding,d.useMaxWidth),s.db.indexNodes("subGraph"+S),!d.htmlLabels){const e=g.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const t of e){const e=t.getBBox(),n=g.createElementNS("http://www.w3.org/2000/svg","rect");n.setAttribute("rx",0),n.setAttribute("ry",0),n.setAttribute("width",e.width),n.setAttribute("height",e.height),t.insertBefore(n,t.firstChild)}}Object.keys(v).forEach((function(e){const n=v[e];if(n.link){const r=(0,l.Ltv)("#"+t+' [id="'+e+'"]');if(r){const e=g.createElementNS("http://www.w3.org/2000/svg","a");e.setAttributeNS("http://www.w3.org/2000/svg","class",n.classes.join(" ")),e.setAttributeNS("http://www.w3.org/2000/svg","href",n.link),e.setAttributeNS("http://www.w3.org/2000/svg","rel","noopener"),"sandbox"===c?e.setAttributeNS("http://www.w3.org/2000/svg","target","_top"):n.linkTarget&&e.setAttributeNS("http://www.w3.org/2000/svg","target",n.linkTarget);const t=r.insert((function(){return e}),":first-child"),l=r.select(".label-container");l&&t.append((function(){return l.node()}));const o=r.select(".label");o&&t.append((function(){return o.node()}))}}}))}},f=e=>`.label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .cluster-label text {\n fill: ${e.titleColor};\n }\n .cluster-label span,p {\n color: ${e.titleColor};\n }\n\n .label text,span,p {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .katex path {\n fill: #000;\n stroke: #000;\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${e.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${e.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${e.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${e.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${e.edgeLabelBackground};\n fill: ${e.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${((e,t)=>{const n=i.A,r=n(e,"r"),l=n(e,"g"),o=n(e,"b");return c.A(r,l,o,t)})(e.edgeLabelBackground,.5)};\n // background-color: \n }\n\n .cluster rect {\n fill: ${e.clusterBkg};\n stroke: ${e.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${e.titleColor};\n }\n\n .cluster span,p {\n color: ${e.titleColor};\n }\n /* .cluster div {\n color: ${e.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${e.fontFamily};\n font-size: 12px;\n background: ${e.tertiaryColor};\n border: 1px solid ${e.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n }\n`}}]); \ No newline at end of file diff --git a/assets/js/7147.af638f0b.js b/assets/js/7147.af638f0b.js new file mode 100644 index 0000000000..21d3e23de9 --- /dev/null +++ b/assets/js/7147.af638f0b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7147],{75937:(e,t,i)=>{i.d(t,{A:()=>r});var s=i(72453),n=i(74886);const r=(e,t)=>s.A.lang.round(n.A.parse(e)[t])},50053:(e,t,i)=>{i.d(t,{A:()=>n});var s=i(91641);const n=function(e){return(0,s.A)(e,4)}},87147:(e,t,i)=>{i.d(t,{diagram:()=>K});var s,n,r=i(76257),l=i(50053),o=i(75937),a=i(25582),c=i(28747),h=i(697),u=i(26312),d=(i(74353),i(16750),i(42838),function(){var e=function(e,t,i,s){for(i=i||{},s=e.length;s--;i[e[s]]=t);return i},t=[1,7],i=[1,13],s=[1,14],n=[1,15],r=[1,19],l=[1,16],o=[1,17],a=[1,18],c=[8,30],h=[8,21,28,29,30,31,32,40,44,47],u=[1,23],d=[1,24],g=[8,15,16,21,28,29,30,31,32,40,44,47],y=[8,15,16,21,27,28,29,30,31,32,40,44,47],p=[1,49],b={trace:function(){},yy:{},symbols_:{error:2,spaceLines:3,SPACELINE:4,NL:5,separator:6,SPACE:7,EOF:8,start:9,BLOCK_DIAGRAM_KEY:10,document:11,stop:12,statement:13,link:14,LINK:15,START_LINK:16,LINK_LABEL:17,STR:18,nodeStatement:19,columnsStatement:20,SPACE_BLOCK:21,blockStatement:22,classDefStatement:23,cssClassStatement:24,styleStatement:25,node:26,SIZE:27,COLUMNS:28,"id-block":29,end:30,block:31,NODE_ID:32,nodeShapeNLabel:33,dirList:34,DIR:35,NODE_DSTART:36,NODE_DEND:37,BLOCK_ARROW_START:38,BLOCK_ARROW_END:39,classDef:40,CLASSDEF_ID:41,CLASSDEF_STYLEOPTS:42,DEFAULT:43,class:44,CLASSENTITY_IDS:45,STYLECLASS:46,style:47,STYLE_ENTITY_IDS:48,STYLE_DEFINITION_DATA:49,$accept:0,$end:1},terminals_:{2:"error",4:"SPACELINE",5:"NL",7:"SPACE",8:"EOF",10:"BLOCK_DIAGRAM_KEY",15:"LINK",16:"START_LINK",17:"LINK_LABEL",18:"STR",21:"SPACE_BLOCK",27:"SIZE",28:"COLUMNS",29:"id-block",30:"end",31:"block",32:"NODE_ID",35:"DIR",36:"NODE_DSTART",37:"NODE_DEND",38:"BLOCK_ARROW_START",39:"BLOCK_ARROW_END",40:"classDef",41:"CLASSDEF_ID",42:"CLASSDEF_STYLEOPTS",43:"DEFAULT",44:"class",45:"CLASSENTITY_IDS",46:"STYLECLASS",47:"style",48:"STYLE_ENTITY_IDS",49:"STYLE_DEFINITION_DATA"},productions_:[0,[3,1],[3,2],[3,2],[6,1],[6,1],[6,1],[9,3],[12,1],[12,1],[12,2],[12,2],[11,1],[11,2],[14,1],[14,4],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[19,3],[19,2],[19,1],[20,1],[22,4],[22,3],[26,1],[26,2],[34,1],[34,2],[33,3],[33,4],[23,3],[23,3],[24,3],[25,3]],performAction:function(e,t,i,s,n,r,l){var o=r.length-1;switch(n){case 4:s.getLogger().debug("Rule: separator (NL) ");break;case 5:s.getLogger().debug("Rule: separator (Space) ");break;case 6:s.getLogger().debug("Rule: separator (EOF) ");break;case 7:s.getLogger().debug("Rule: hierarchy: ",r[o-1]),s.setHierarchy(r[o-1]);break;case 8:s.getLogger().debug("Stop NL ");break;case 9:s.getLogger().debug("Stop EOF ");break;case 10:s.getLogger().debug("Stop NL2 ");break;case 11:s.getLogger().debug("Stop EOF2 ");break;case 12:s.getLogger().debug("Rule: statement: ",r[o]),"number"==typeof r[o].length?this.$=r[o]:this.$=[r[o]];break;case 13:s.getLogger().debug("Rule: statement #2: ",r[o-1]),this.$=[r[o-1]].concat(r[o]);break;case 14:s.getLogger().debug("Rule: link: ",r[o],e),this.$={edgeTypeStr:r[o],label:""};break;case 15:s.getLogger().debug("Rule: LABEL link: ",r[o-3],r[o-1],r[o]),this.$={edgeTypeStr:r[o],label:r[o-1]};break;case 18:const t=parseInt(r[o]),i=s.generateId();this.$={id:i,type:"space",label:"",width:t,children:[]};break;case 23:s.getLogger().debug("Rule: (nodeStatement link node) ",r[o-2],r[o-1],r[o]," typestr: ",r[o-1].edgeTypeStr);const n=s.edgeStrToEdgeData(r[o-1].edgeTypeStr);this.$=[{id:r[o-2].id,label:r[o-2].label,type:r[o-2].type,directions:r[o-2].directions},{id:r[o-2].id+"-"+r[o].id,start:r[o-2].id,end:r[o].id,label:r[o-1].label,type:"edge",directions:r[o].directions,arrowTypeEnd:n,arrowTypeStart:"arrow_open"},{id:r[o].id,label:r[o].label,type:s.typeStr2Type(r[o].typeStr),directions:r[o].directions}];break;case 24:s.getLogger().debug("Rule: nodeStatement (abc88 node size) ",r[o-1],r[o]),this.$={id:r[o-1].id,label:r[o-1].label,type:s.typeStr2Type(r[o-1].typeStr),directions:r[o-1].directions,widthInColumns:parseInt(r[o],10)};break;case 25:s.getLogger().debug("Rule: nodeStatement (node) ",r[o]),this.$={id:r[o].id,label:r[o].label,type:s.typeStr2Type(r[o].typeStr),directions:r[o].directions,widthInColumns:1};break;case 26:s.getLogger().debug("APA123",this?this:"na"),s.getLogger().debug("COLUMNS: ",r[o]),this.$={type:"column-setting",columns:"auto"===r[o]?-1:parseInt(r[o])};break;case 27:s.getLogger().debug("Rule: id-block statement : ",r[o-2],r[o-1]),s.generateId(),this.$={...r[o-2],type:"composite",children:r[o-1]};break;case 28:s.getLogger().debug("Rule: blockStatement : ",r[o-2],r[o-1],r[o]);const l=s.generateId();this.$={id:l,type:"composite",label:"",children:r[o-1]};break;case 29:s.getLogger().debug("Rule: node (NODE_ID separator): ",r[o]),this.$={id:r[o]};break;case 30:s.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ",r[o-1],r[o]),this.$={id:r[o-1],label:r[o].label,typeStr:r[o].typeStr,directions:r[o].directions};break;case 31:s.getLogger().debug("Rule: dirList: ",r[o]),this.$=[r[o]];break;case 32:s.getLogger().debug("Rule: dirList: ",r[o-1],r[o]),this.$=[r[o-1]].concat(r[o]);break;case 33:s.getLogger().debug("Rule: nodeShapeNLabel: ",r[o-2],r[o-1],r[o]),this.$={typeStr:r[o-2]+r[o],label:r[o-1]};break;case 34:s.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ",r[o-3],r[o-2]," #3:",r[o-1],r[o]),this.$={typeStr:r[o-3]+r[o],label:r[o-2],directions:r[o-1]};break;case 35:case 36:this.$={type:"classDef",id:r[o-1].trim(),css:r[o].trim()};break;case 37:this.$={type:"applyClass",id:r[o-1].trim(),styleClass:r[o].trim()};break;case 38:this.$={type:"applyStyles",id:r[o-1].trim(),stylesStr:r[o].trim()}}},table:[{9:1,10:[1,2]},{1:[3]},{11:3,13:4,19:5,20:6,21:t,22:8,23:9,24:10,25:11,26:12,28:i,29:s,31:n,32:r,40:l,44:o,47:a},{8:[1,20]},e(c,[2,12],{13:4,19:5,20:6,22:8,23:9,24:10,25:11,26:12,11:21,21:t,28:i,29:s,31:n,32:r,40:l,44:o,47:a}),e(h,[2,16],{14:22,15:u,16:d}),e(h,[2,17]),e(h,[2,18]),e(h,[2,19]),e(h,[2,20]),e(h,[2,21]),e(h,[2,22]),e(g,[2,25],{27:[1,25]}),e(h,[2,26]),{19:26,26:12,32:r},{11:27,13:4,19:5,20:6,21:t,22:8,23:9,24:10,25:11,26:12,28:i,29:s,31:n,32:r,40:l,44:o,47:a},{41:[1,28],43:[1,29]},{45:[1,30]},{48:[1,31]},e(y,[2,29],{33:32,36:[1,33],38:[1,34]}),{1:[2,7]},e(c,[2,13]),{26:35,32:r},{32:[2,14]},{17:[1,36]},e(g,[2,24]),{11:37,13:4,14:22,15:u,16:d,19:5,20:6,21:t,22:8,23:9,24:10,25:11,26:12,28:i,29:s,31:n,32:r,40:l,44:o,47:a},{30:[1,38]},{42:[1,39]},{42:[1,40]},{46:[1,41]},{49:[1,42]},e(y,[2,30]),{18:[1,43]},{18:[1,44]},e(g,[2,23]),{18:[1,45]},{30:[1,46]},e(h,[2,28]),e(h,[2,35]),e(h,[2,36]),e(h,[2,37]),e(h,[2,38]),{37:[1,47]},{34:48,35:p},{15:[1,50]},e(h,[2,27]),e(y,[2,33]),{39:[1,51]},{34:52,35:p,39:[2,31]},{32:[2,15]},e(y,[2,34]),{39:[2,32]}],defaultActions:{20:[2,7],23:[2,14],50:[2,15],52:[2,32]},parseError:function(e,t){if(!t.recoverable){var i=new Error(e);throw i.hash=t,i}this.trace(e)},parse:function(e){var t=this,i=[0],s=[],n=[null],r=[],l=this.table,o="",a=0,c=0,h=r.slice.call(arguments,1),u=Object.create(this.lexer),d={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(d.yy[g]=this.yy[g]);u.setInput(e,d.yy),d.yy.lexer=u,d.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var y=u.yylloc;r.push(y);var p=u.options&&u.options.ranges;"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var b,x,L,S,f,m,_,k,E,w={};;){if(x=i[i.length-1],this.defaultActions[x]?L=this.defaultActions[x]:(null==b&&(E=void 0,"number"!=typeof(E=s.pop()||u.lex()||1)&&(E instanceof Array&&(E=(s=E).pop()),E=t.symbols_[E]||E),b=E),L=l[x]&&l[x][b]),void 0===L||!L.length||!L[0]){var v="";for(f in k=[],l[x])this.terminals_[f]&&f>2&&k.push("'"+this.terminals_[f]+"'");v=u.showPosition?"Parse error on line "+(a+1)+":\n"+u.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(a+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(v,{text:u.match,token:this.terminals_[b]||b,line:u.yylineno,loc:y,expected:k})}if(L[0]instanceof Array&&L.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+b);switch(L[0]){case 1:i.push(b),n.push(u.yytext),r.push(u.yylloc),i.push(L[1]),b=null,c=u.yyleng,o=u.yytext,a=u.yylineno,y=u.yylloc;break;case 2:if(m=this.productions_[L[1]][1],w.$=n[n.length-m],w._$={first_line:r[r.length-(m||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(m||1)].first_column,last_column:r[r.length-1].last_column},p&&(w._$.range=[r[r.length-(m||1)].range[0],r[r.length-1].range[1]]),void 0!==(S=this.performAction.apply(w,[o,c,a,d.yy,L[1],n,r].concat(h))))return S;m&&(i=i.slice(0,-1*m*2),n=n.slice(0,-1*m),r=r.slice(0,-1*m)),i.push(this.productions_[L[1]][0]),n.push(w.$),r.push(w._$),_=l[i[i.length-2]][i[i.length-1]],i.push(_);break;case 3:return!0}}return!0}},x={EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,i=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===s.length?this.yylloc.first_column:0)+s[s.length-i.length].length-i[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var i,s,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(s=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],i=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var e,t,i,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;r<n.length;r++)if((i=this._input.match(this.rules[n[r]]))&&(!t||i[0].length>t[0].length)){if(t=i,s=r,this.options.backtrack_lexer){if(!1!==(e=this.test_match(i,n[r])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,n[s]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(e,t,i,s){switch(i){case 0:return 10;case 1:return e.getLogger().debug("Found space-block"),31;case 2:return e.getLogger().debug("Found nl-block"),31;case 3:return e.getLogger().debug("Found space-block"),29;case 4:e.getLogger().debug(".",t.yytext);break;case 5:e.getLogger().debug("_",t.yytext);break;case 6:return 5;case 7:return t.yytext=-1,28;case 8:return t.yytext=t.yytext.replace(/columns\s+/,""),e.getLogger().debug("COLUMNS (LEX)",t.yytext),28;case 9:case 77:case 78:case 100:this.pushState("md_string");break;case 10:return"MD_STR";case 11:case 35:case 80:this.popState();break;case 12:this.pushState("string");break;case 13:e.getLogger().debug("LEX: POPPING STR:",t.yytext),this.popState();break;case 14:return e.getLogger().debug("LEX: STR end:",t.yytext),"STR";case 15:return t.yytext=t.yytext.replace(/space\:/,""),e.getLogger().debug("SPACE NUM (LEX)",t.yytext),21;case 16:return t.yytext="1",e.getLogger().debug("COLUMNS (LEX)",t.yytext),21;case 17:return 43;case 18:return"LINKSTYLE";case 19:return"INTERPOLATE";case 20:return this.pushState("CLASSDEF"),40;case 21:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 22:return this.popState(),this.pushState("CLASSDEFID"),41;case 23:return this.popState(),42;case 24:return this.pushState("CLASS"),44;case 25:return this.popState(),this.pushState("CLASS_STYLE"),45;case 26:return this.popState(),46;case 27:return this.pushState("STYLE_STMNT"),47;case 28:return this.popState(),this.pushState("STYLE_DEFINITION"),48;case 29:return this.popState(),49;case 30:return this.pushState("acc_title"),"acc_title";case 31:return this.popState(),"acc_title_value";case 32:return this.pushState("acc_descr"),"acc_descr";case 33:return this.popState(),"acc_descr_value";case 34:this.pushState("acc_descr_multiline");break;case 36:return"acc_descr_multiline_value";case 37:return 30;case 38:case 39:case 41:case 42:case 45:return this.popState(),e.getLogger().debug("Lex: (("),"NODE_DEND";case 40:return this.popState(),e.getLogger().debug("Lex: ))"),"NODE_DEND";case 43:return this.popState(),e.getLogger().debug("Lex: (-"),"NODE_DEND";case 44:return this.popState(),e.getLogger().debug("Lex: -)"),"NODE_DEND";case 46:return this.popState(),e.getLogger().debug("Lex: ]]"),"NODE_DEND";case 47:return this.popState(),e.getLogger().debug("Lex: ("),"NODE_DEND";case 48:return this.popState(),e.getLogger().debug("Lex: ])"),"NODE_DEND";case 49:case 50:return this.popState(),e.getLogger().debug("Lex: /]"),"NODE_DEND";case 51:return this.popState(),e.getLogger().debug("Lex: )]"),"NODE_DEND";case 52:return this.popState(),e.getLogger().debug("Lex: )"),"NODE_DEND";case 53:return this.popState(),e.getLogger().debug("Lex: ]>"),"NODE_DEND";case 54:return this.popState(),e.getLogger().debug("Lex: ]"),"NODE_DEND";case 55:return e.getLogger().debug("Lexa: -)"),this.pushState("NODE"),36;case 56:return e.getLogger().debug("Lexa: (-"),this.pushState("NODE"),36;case 57:return e.getLogger().debug("Lexa: ))"),this.pushState("NODE"),36;case 58:case 60:case 61:case 62:case 65:return e.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;case 59:return e.getLogger().debug("Lex: ((("),this.pushState("NODE"),36;case 63:return e.getLogger().debug("Lexc: >"),this.pushState("NODE"),36;case 64:return e.getLogger().debug("Lexa: (["),this.pushState("NODE"),36;case 66:case 67:case 68:case 69:case 70:case 71:case 72:return this.pushState("NODE"),36;case 73:return e.getLogger().debug("Lexa: ["),this.pushState("NODE"),36;case 74:return this.pushState("BLOCK_ARROW"),e.getLogger().debug("LEX ARR START"),38;case 75:return e.getLogger().debug("Lex: NODE_ID",t.yytext),32;case 76:return e.getLogger().debug("Lex: EOF",t.yytext),8;case 79:return"NODE_DESCR";case 81:e.getLogger().debug("Lex: Starting string"),this.pushState("string");break;case 82:e.getLogger().debug("LEX ARR: Starting string"),this.pushState("string");break;case 83:return e.getLogger().debug("LEX: NODE_DESCR:",t.yytext),"NODE_DESCR";case 84:e.getLogger().debug("LEX POPPING"),this.popState();break;case 85:e.getLogger().debug("Lex: =>BAE"),this.pushState("ARROW_DIR");break;case 86:return t.yytext=t.yytext.replace(/^,\s*/,""),e.getLogger().debug("Lex (right): dir:",t.yytext),"DIR";case 87:return t.yytext=t.yytext.replace(/^,\s*/,""),e.getLogger().debug("Lex (left):",t.yytext),"DIR";case 88:return t.yytext=t.yytext.replace(/^,\s*/,""),e.getLogger().debug("Lex (x):",t.yytext),"DIR";case 89:return t.yytext=t.yytext.replace(/^,\s*/,""),e.getLogger().debug("Lex (y):",t.yytext),"DIR";case 90:return t.yytext=t.yytext.replace(/^,\s*/,""),e.getLogger().debug("Lex (up):",t.yytext),"DIR";case 91:return t.yytext=t.yytext.replace(/^,\s*/,""),e.getLogger().debug("Lex (down):",t.yytext),"DIR";case 92:return t.yytext="]>",e.getLogger().debug("Lex (ARROW_DIR end):",t.yytext),this.popState(),this.popState(),"BLOCK_ARROW_END";case 93:return e.getLogger().debug("Lex: LINK","#"+t.yytext+"#"),15;case 94:case 95:case 96:return e.getLogger().debug("Lex: LINK",t.yytext),15;case 97:case 98:case 99:return e.getLogger().debug("Lex: START_LINK",t.yytext),this.pushState("LLABEL"),16;case 101:return e.getLogger().debug("Lex: Starting string"),this.pushState("string"),"LINK_LABEL";case 102:return this.popState(),e.getLogger().debug("Lex: LINK","#"+t.yytext+"#"),15;case 103:case 104:return this.popState(),e.getLogger().debug("Lex: LINK",t.yytext),15;case 105:return e.getLogger().debug("Lex: COLON",t.yytext),t.yytext=t.yytext.slice(1),27}},rules:[/^(?:block-beta\b)/,/^(?:block\s+)/,/^(?:block\n+)/,/^(?:block:)/,/^(?:[\s]+)/,/^(?:[\n]+)/,/^(?:((\u000D\u000A)|(\u000A)))/,/^(?:columns\s+auto\b)/,/^(?:columns\s+[\d]+)/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:space[:]\d+)/,/^(?:space\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\s+)/,/^(?:DEFAULT\s+)/,/^(?:\w+\s+)/,/^(?:[^\n]*)/,/^(?:class\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:style\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:end\b\s*)/,/^(?:\(\(\()/,/^(?:\)\)\))/,/^(?:[\)]\))/,/^(?:\}\})/,/^(?:\})/,/^(?:\(-)/,/^(?:-\))/,/^(?:\(\()/,/^(?:\]\])/,/^(?:\()/,/^(?:\]\))/,/^(?:\\\])/,/^(?:\/\])/,/^(?:\)\])/,/^(?:[\)])/,/^(?:\]>)/,/^(?:[\]])/,/^(?:-\))/,/^(?:\(-)/,/^(?:\)\))/,/^(?:\))/,/^(?:\(\(\()/,/^(?:\(\()/,/^(?:\{\{)/,/^(?:\{)/,/^(?:>)/,/^(?:\(\[)/,/^(?:\()/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\[\\)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:\[)/,/^(?:<\[)/,/^(?:[^\(\[\n\-\)\{\}\s\<\>:]+)/,/^(?:$)/,/^(?:["][`])/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:\]>\s*\()/,/^(?:,?\s*right\s*)/,/^(?:,?\s*left\s*)/,/^(?:,?\s*x\s*)/,/^(?:,?\s*y\s*)/,/^(?:,?\s*up\s*)/,/^(?:,?\s*down\s*)/,/^(?:\)\s*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*~~[\~]+\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:["][`])/,/^(?:["])/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?::\d+)/],conditions:{STYLE_DEFINITION:{rules:[29],inclusive:!1},STYLE_STMNT:{rules:[28],inclusive:!1},CLASSDEFID:{rules:[23],inclusive:!1},CLASSDEF:{rules:[21,22],inclusive:!1},CLASS_STYLE:{rules:[26],inclusive:!1},CLASS:{rules:[25],inclusive:!1},LLABEL:{rules:[100,101,102,103,104],inclusive:!1},ARROW_DIR:{rules:[86,87,88,89,90,91,92],inclusive:!1},BLOCK_ARROW:{rules:[77,82,85],inclusive:!1},NODE:{rules:[38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,78,81],inclusive:!1},md_string:{rules:[10,11,79,80],inclusive:!1},space:{rules:[],inclusive:!1},string:{rules:[13,14,83,84],inclusive:!1},acc_descr_multiline:{rules:[35,36],inclusive:!1},acc_descr:{rules:[33],inclusive:!1},acc_title:{rules:[31],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,12,15,16,17,18,19,20,24,27,30,32,34,37,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,93,94,95,96,97,98,99,105],inclusive:!0}}};function L(){this.yy={}}return b.lexer=x,L.prototype=b,b.Parser=L,new L}());d.parser=d;const g=d;let y={},p=[],b={};const x="color",L="fill";let S={};const f=function(e,t=""){void 0===S[e]&&(S[e]={id:e,styles:[],textStyles:[]});const i=S[e];null!=t&&t.split(",").forEach((e=>{const t=e.replace(/([^;]*);/,"$1").trim();if(e.match(x)){const e=t.replace(L,"bgFill").replace(x,L);i.textStyles.push(e)}i.styles.push(t)}))},m=function(e,t=""){const i=y[e];null!=t&&(i.styles=t.split(","))},_=function(e,t){e.split(",").forEach((function(e){let i=y[e];if(void 0===i){const t=e.trim();y[t]={id:t,type:"na",children:[]},i=y[t]}i.classes||(i.classes=[]),i.classes.push(t)}))},k=(e,t)=>{const i=e.flat(),s=[];for(const n of i)if("classDef"!==n.type)if("applyClass"!==n.type)if("applyStyles"!==n.type)if("column-setting"===n.type)t.columns=n.columns||-1;else if("edge"===n.type)b[n.id]?b[n.id]++:b[n.id]=1,n.id=b[n.id]+"-"+n.id,p.push(n);else{n.label||("composite"===n.type?n.label="":n.label=n.id);const e=!y[n.id];if(e?y[n.id]=n:("na"!==n.type&&(y[n.id].type=n.type),n.label!==n.id&&(y[n.id].label=n.label)),n.children&&k(n.children,n),"space"===n.type){const e=n.width||1;for(let t=0;t<e;t++){const e=(0,l.A)(n);e.id=e.id+"-"+t,y[e.id]=e,s.push(e)}}else e&&s.push(n)}else(null==n?void 0:n.stylesStr)&&m(n.id,null==n?void 0:n.stylesStr);else _(n.id,(null==n?void 0:n.styleClass)||"");else f(n.id,n.css);t.children=s};let E=[],w={id:"root",type:"composite",children:[],columns:-1};let v=0;const D={getConfig:()=>(0,r.F)().block,typeStr2Type:function(e){switch(r.l.debug("typeStr2Type",e),e){case"[]":return"square";case"()":return r.l.debug("we have a round"),"round";case"(())":return"circle";case">]":return"rect_left_inv_arrow";case"{}":return"diamond";case"{{}}":return"hexagon";case"([])":return"stadium";case"[[]]":return"subroutine";case"[()]":return"cylinder";case"((()))":return"doublecircle";case"[//]":return"lean_right";case"[\\\\]":return"lean_left";case"[/\\]":return"trapezoid";case"[\\/]":return"inv_trapezoid";case"<[]>":return"block_arrow";default:return"na"}},edgeTypeStr2Type:function(e){return r.l.debug("typeStr2Type",e),"=="===e?"thick":"normal"},edgeStrToEdgeData:function(e){switch(e.trim()){case"--x":return"arrow_cross";case"--o":return"arrow_circle";default:return"arrow_point"}},getLogger:()=>console,getBlocksFlat:()=>[...Object.values(y)],getBlocks:()=>E||[],getEdges:()=>p,setHierarchy:e=>{w.children=e,k(e,w),E=w.children},getBlock:e=>y[e],setBlock:e=>{y[e.id]=e},getColumns:e=>{const t=y[e];return t?t.columns?t.columns:t.children?t.children.length:-1:-1},getClasses:function(){return S},clear:()=>{r.l.debug("Clear called"),(0,r.v)(),w={id:"root",type:"composite",children:[],columns:-1},y={root:w},E=[],S={},p=[],b={}},generateId:()=>(v++,"id-"+Math.random().toString(36).substr(2,12)+"-"+v)},$=(e,t)=>{const i=o.A,s=i(e,"r"),n=i(e,"g"),r=i(e,"b");return a.A(s,n,r,t)},N=e=>`.label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .cluster-label text {\n fill: ${e.titleColor};\n }\n .cluster-label span,p {\n color: ${e.titleColor};\n }\n\n\n\n .label text,span,p {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${e.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${e.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${e.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${e.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${e.edgeLabelBackground};\n fill: ${e.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${$(e.edgeLabelBackground,.5)};\n // background-color:\n }\n\n .node .cluster {\n // fill: ${$(e.mainBkg,.5)};\n fill: ${$(e.clusterBkg,.5)};\n stroke: ${$(e.clusterBorder,.2)};\n box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${e.titleColor};\n }\n\n .cluster span,p {\n color: ${e.titleColor};\n }\n /* .cluster div {\n color: ${e.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${e.fontFamily};\n font-size: 12px;\n background: ${e.tertiaryColor};\n border: 1px solid ${e.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n }\n`;function I(e,t,i=!1){var s,n,l;const o=e;let a="default";((null==(s=null==o?void 0:o.classes)?void 0:s.length)||0)>0&&(a=((null==o?void 0:o.classes)||[]).join(" ")),a+=" flowchart-label";let c,h=0,u="";switch(o.type){case"round":h=5,u="rect";break;case"composite":h=0,u="composite",c=0;break;case"square":case"group":default:u="rect";break;case"diamond":u="question";break;case"hexagon":u="hexagon";break;case"block_arrow":u="block_arrow";break;case"odd":case"rect_left_inv_arrow":u="rect_left_inv_arrow";break;case"lean_right":u="lean_right";break;case"lean_left":u="lean_left";break;case"trapezoid":u="trapezoid";break;case"inv_trapezoid":u="inv_trapezoid";break;case"circle":u="circle";break;case"ellipse":u="ellipse";break;case"stadium":u="stadium";break;case"subroutine":u="subroutine";break;case"cylinder":u="cylinder";break;case"doublecircle":u="doublecircle"}const d=(0,r.k)((null==o?void 0:o.styles)||[]),g=o.label,y=o.size||{width:0,height:0,x:0,y:0};return{labelStyle:d.labelStyle,shape:u,labelText:g,rx:h,ry:h,class:a,style:d.style,id:o.id,directions:o.directions,width:y.width,height:y.height,x:y.x,y:y.y,positioned:i,intersect:void 0,type:o.type,padding:c??((null==(l=null==(n=(0,r.F)())?void 0:n.block)?void 0:l.padding)||0)}}async function T(e,t,i){const s=I(t,0,!1);if("group"===s.type)return;const n=await(0,c.e)(e,s),r=n.node().getBBox(),l=i.getBlock(s.id);l.size={width:r.width,height:r.height,x:0,y:0,node:n},i.setBlock(l),n.remove()}async function z(e,t,i){const s=I(t,0,!0);"space"!==i.getBlock(s.id).type&&(await(0,c.e)(e,s),t.intersect=null==s?void 0:s.intersect,(0,c.p)(s))}async function A(e,t,i,s){for(const n of t)await s(e,n,i),n.children&&await A(e,n.children,i,s)}const C=(null==(n=null==(s=(0,r.c)())?void 0:s.block)?void 0:n.padding)||8;function O(e,t){if(0===e||!Number.isInteger(e))throw new Error("Columns must be an integer !== 0.");if(t<0||!Number.isInteger(t))throw new Error("Position must be a non-negative integer."+t);if(e<0)return{px:t,py:0};if(1===e)return{px:0,py:t};return{px:t%e,py:Math.floor(t/e)}}const R=e=>{let t=0,i=0;for(const s of e.children){const{width:n,height:l,x:o,y:a}=s.size||{width:0,height:0,x:0,y:0};r.l.debug("getMaxChildSize abc95 child:",s.id,"width:",n,"height:",l,"x:",o,"y:",a,s.type),"space"!==s.type&&(n>t&&(t=n/(e.widthInColumns||1)),l>i&&(i=l))}return{width:t,height:i}};function B(e,t,i=0,s=0){var n,l,o,a,c,h,u,d,g,y,p;r.l.debug("setBlockSizes abc95 (start)",e.id,null==(n=null==e?void 0:e.size)?void 0:n.x,"block width =",null==e?void 0:e.size,"sieblingWidth",i),(null==(l=null==e?void 0:e.size)?void 0:l.width)||(e.size={width:i,height:s,x:0,y:0});let b=0,x=0;if((null==(o=e.children)?void 0:o.length)>0){for(const i of e.children)B(i,t);const n=R(e);b=n.width,x=n.height,r.l.debug("setBlockSizes abc95 maxWidth of",e.id,":s children is ",b,x);for(const t of e.children)t.size&&(r.l.debug(`abc95 Setting size of children of ${e.id} id=${t.id} ${b} ${x} ${t.size}`),t.size.width=b*(t.widthInColumns||1)+C*((t.widthInColumns||1)-1),t.size.height=x,t.size.x=0,t.size.y=0,r.l.debug(`abc95 updating size of ${e.id} children child:${t.id} maxWidth:${b} maxHeight:${x}`));for(const i of e.children)B(i,t,b,x);const l=e.columns||-1;let o=0;for(const t of e.children)o+=t.widthInColumns||1;let d=e.children.length;l>0&&l<o&&(d=l),e.widthInColumns;const g=Math.ceil(o/d);let y=d*(b+C)+C,p=g*(x+C)+C;if(y<i){r.l.debug(`Detected to small siebling: abc95 ${e.id} sieblingWidth ${i} sieblingHeight ${s} width ${y}`),y=i,p=s;const t=(i-d*C-C)/d,n=(s-g*C-C)/g;r.l.debug("Size indata abc88",e.id,"childWidth",t,"maxWidth",b),r.l.debug("Size indata abc88",e.id,"childHeight",n,"maxHeight",x),r.l.debug("Size indata abc88 xSize",d,"padding",C);for(const i of e.children)i.size&&(i.size.width=t,i.size.height=n,i.size.x=0,i.size.y=0)}if(r.l.debug(`abc95 (finale calc) ${e.id} xSize ${d} ySize ${g} columns ${l}${e.children.length} width=${Math.max(y,(null==(a=e.size)?void 0:a.width)||0)}`),y<((null==(c=null==e?void 0:e.size)?void 0:c.width)||0)){y=(null==(h=null==e?void 0:e.size)?void 0:h.width)||0;const t=l>0?Math.min(e.children.length,l):e.children.length;if(t>0){const i=(y-t*C-C)/t;r.l.debug("abc95 (growing to fit) width",e.id,y,null==(u=e.size)?void 0:u.width,i);for(const t of e.children)t.size&&(t.size.width=i)}}e.size={width:y,height:p,x:0,y:0}}r.l.debug("setBlockSizes abc94 (done)",e.id,null==(d=null==e?void 0:e.size)?void 0:d.x,null==(g=null==e?void 0:e.size)?void 0:g.width,null==(y=null==e?void 0:e.size)?void 0:y.y,null==(p=null==e?void 0:e.size)?void 0:p.height)}function F(e,t){var i,s,n,l,o,a,c,h,u,d,g,y,p,b,x,L,S;r.l.debug(`abc85 layout blocks (=>layoutBlocks) ${e.id} x: ${null==(i=null==e?void 0:e.size)?void 0:i.x} y: ${null==(s=null==e?void 0:e.size)?void 0:s.y} width: ${null==(n=null==e?void 0:e.size)?void 0:n.width}`);const f=e.columns||-1;if(r.l.debug("layoutBlocks columns abc95",e.id,"=>",f,e),e.children&&e.children.length>0){const t=(null==(o=null==(l=null==e?void 0:e.children[0])?void 0:l.size)?void 0:o.width)||0,i=e.children.length*t+(e.children.length-1)*C;r.l.debug("widthOfChildren 88",i,"posX");let s=0;r.l.debug("abc91 block?.size?.x",e.id,null==(a=null==e?void 0:e.size)?void 0:a.x);let n=(null==(c=null==e?void 0:e.size)?void 0:c.x)?(null==(h=null==e?void 0:e.size)?void 0:h.x)+(-(null==(u=null==e?void 0:e.size)?void 0:u.width)/2||0):-C,x=0;for(const l of e.children){const t=e;if(!l.size)continue;const{width:i,height:o}=l.size,{px:a,py:c}=O(f,s);if(c!=x&&(x=c,n=(null==(d=null==e?void 0:e.size)?void 0:d.x)?(null==(g=null==e?void 0:e.size)?void 0:g.x)+(-(null==(y=null==e?void 0:e.size)?void 0:y.width)/2||0):-C,r.l.debug("New row in layout for block",e.id," and child ",l.id,x)),r.l.debug(`abc89 layout blocks (child) id: ${l.id} Pos: ${s} (px, py) ${a},${c} (${null==(p=null==t?void 0:t.size)?void 0:p.x},${null==(b=null==t?void 0:t.size)?void 0:b.y}) parent: ${t.id} width: ${i}${C}`),t.size){const e=i/2;l.size.x=n+C+e,r.l.debug(`abc91 layout blocks (calc) px, pyid:${l.id} startingPos=X${n} new startingPosX${l.size.x} ${e} padding=${C} width=${i} halfWidth=${e} => x:${l.size.x} y:${l.size.y} ${l.widthInColumns} (width * (child?.w || 1)) / 2 ${i*((null==l?void 0:l.widthInColumns)||1)/2}`),n=l.size.x+e,l.size.y=t.size.y-t.size.height/2+c*(o+C)+o/2+C,r.l.debug(`abc88 layout blocks (calc) px, pyid:${l.id}startingPosX${n}${C}${e}=>x:${l.size.x}y:${l.size.y}${l.widthInColumns}(width * (child?.w || 1)) / 2${i*((null==l?void 0:l.widthInColumns)||1)/2}`)}l.children&&F(l),s+=(null==l?void 0:l.widthInColumns)||1,r.l.debug("abc88 columnsPos",l,s)}}r.l.debug(`layout blocks (<==layoutBlocks) ${e.id} x: ${null==(x=null==e?void 0:e.size)?void 0:x.x} y: ${null==(L=null==e?void 0:e.size)?void 0:L.y} width: ${null==(S=null==e?void 0:e.size)?void 0:S.width}`)}function P(e,{minX:t,minY:i,maxX:s,maxY:n}={minX:0,minY:0,maxX:0,maxY:0}){if(e.size&&"root"!==e.id){const{x:r,y:l,width:o,height:a}=e.size;r-o/2<t&&(t=r-o/2),l-a/2<i&&(i=l-a/2),r+o/2>s&&(s=r+o/2),l+a/2>n&&(n=l+a/2)}if(e.children)for(const r of e.children)({minX:t,minY:i,maxX:s,maxY:n}=P(r,{minX:t,minY:i,maxX:s,maxY:n}));return{minX:t,minY:i,maxX:s,maxY:n}}function Y(e){const t=e.getBlock("root");if(!t)return;B(t,e,0,0),F(t),r.l.debug("getBlocks",JSON.stringify(t,null,2));const{minX:i,minY:s,maxX:n,maxY:l}=P(t);return{x:i,y:s,width:n-i,height:l-s}}const K={parser:g,db:D,renderer:{draw:async function(e,t,i,s){const{securityLevel:n,block:l}=(0,r.F)(),o=s.db;let a;"sandbox"===n&&(a=(0,u.Ltv)("#i"+t));const d="sandbox"===n?(0,u.Ltv)(a.nodes()[0].contentDocument.body):(0,u.Ltv)("body"),g="sandbox"===n?d.select(`[id="${t}"]`):(0,u.Ltv)(`[id="${t}"]`);(0,c.a)(g,["point","circle","cross"],s.type,t);const y=o.getBlocks(),p=o.getBlocksFlat(),b=o.getEdges(),x=g.insert("g").attr("class","block");await async function(e,t,i){await A(e,t,i,T)}(x,y,o);const L=Y(o);if(await async function(e,t,i){await A(e,t,i,z)}(x,y,o),await async function(e,t,i,s,n){const r=new h.T({multigraph:!0,compound:!0});r.setGraph({rankdir:"TB",nodesep:10,ranksep:10,marginx:8,marginy:8});for(const l of i)l.size&&r.setNode(l.id,{width:l.size.width,height:l.size.height,intersect:l.intersect});for(const l of t)if(l.start&&l.end){const t=s.getBlock(l.start),i=s.getBlock(l.end);if((null==t?void 0:t.size)&&(null==i?void 0:i.size)){const s=t.size,o=i.size,a=[{x:s.x,y:s.y},{x:s.x+(o.x-s.x)/2,y:s.y+(o.y-s.y)/2},{x:o.x,y:o.y}];await(0,c.h)(e,{v:l.start,w:l.end,name:l.id},{...l,arrowTypeEnd:l.arrowTypeEnd,arrowTypeStart:l.arrowTypeStart,points:a,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"},void 0,"block",r,n),l.label&&(await(0,c.f)(e,{...l,label:l.label,labelStyle:"stroke: #333; stroke-width: 1.5px;fill:none;",arrowTypeEnd:l.arrowTypeEnd,arrowTypeStart:l.arrowTypeStart,points:a,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"}),await(0,c.j)({...l,x:a[1].x,y:a[1].y},{originalPath:a}))}}}(x,b,p,o,t),L){const e=L,t=Math.max(1,Math.round(e.width/e.height*.125)),i=e.height+t+10,s=e.width+10,{useMaxWidth:n}=l;(0,r.i)(g,i,s,!!n),r.l.debug("Here Bounds",L,e),g.attr("viewBox",`${e.x-5} ${e.y-5} ${e.width+10} ${e.height+10}`)}(0,u.UMr)(u.zt)},getClasses:function(e,t){return t.db.getClasses()}},styles:N}}}]); \ No newline at end of file diff --git a/assets/js/71499917.36aaf16a.js b/assets/js/71499917.36aaf16a.js new file mode 100644 index 0000000000..cafb8522ca --- /dev/null +++ b/assets/js/71499917.36aaf16a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5e3],{10442:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>a,toc:()=>d});var s=t(74848),i=t(28453);const l={sidebar_label:"Cloud in a Box Guide"},o="Cloud in a Box - CiaB",a={id:"iaas/guides/other-guides/cloud-in-a-box",title:"Cloud in a Box - CiaB",description:"\ud83d\udca1 Cloud in a Box (CiaB) is a minimalistic installation of the latest stable OSISM release with only services which are needed to",source:"@site/docs/02-iaas/guides/other-guides/cloud-in-a-box.md",sourceDirName:"02-iaas/guides/other-guides",slug:"/iaas/guides/other-guides/cloud-in-a-box",permalink:"/docs/iaas/guides/other-guides/cloud-in-a-box",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/cloud-in-a-box.md",tags:[],version:"current",frontMatter:{sidebar_label:"Cloud in a Box Guide"},sidebar:"docs",previous:{title:"Other Guides",permalink:"/docs/iaas/guides/other-guides/"},next:{title:"Contributor Guide",permalink:"/docs/iaas/guides/other-guides/contributor-guide"}},r={},d=[{value:"Requirements",id:"requirements",level:2},{value:"Types",id:"types",level:2},{value:"General notes and limitations",id:"general-notes-and-limitations",level:2},{value:"Installation",id:"installation",level:2},{value:"Automated installation (recommended)",id:"automated-installation-recommended",level:3},{value:"Manual installation",id:"manual-installation",level:3},{value:"Usage",id:"usage",level:2},{value:"Wireguard VPN service access",id:"wireguard-vpn-service-access",level:3},{value:"Webinterfaces",id:"webinterfaces",level:3},{value:"Command-line interfaces",id:"command-line-interfaces",level:3},{value:"Import of additional images",id:"import-of-additional-images",level:3},{value:"Upgrade",id:"upgrade",level:3},{value:"Customisations",id:"customisations",level:2},{value:"Use of 2nd NIC for external network",id:"use-of-2nd-nic-for-external-network",level:3},{value:"Running on a Virtual Machine",id:"running-on-a-virtual-machine",level:3},{value:"Nested virtualization",id:"nested-virtualization",level:4},{value:"Disk space saving",id:"disk-space-saving",level:4},{value:"QEMU guest agent",id:"qemu-guest-agent",level:4},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Development",id:"development",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"cloud-in-a-box---ciab",children:"Cloud in a Box - CiaB"}),"\n",(0,s.jsx)(n.p,{children:"\ud83d\udca1 Cloud in a Box (CiaB) is a minimalistic installation of the latest stable OSISM release with only services which are needed to\nmake it work with Kubernetes. It is intended for use as a development\nsystem on bare-metal or for use in edge environments."}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["At the moment the secrets are stored in plain text in the ",(0,s.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box",children:"osism/cloud-in-a-box"}),"\nrepository and are not secure. Do not use for public accessible systems. In the future, the secrets will be generated automatically."]})}),"\n",(0,s.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,s.jsx)(n.p,{children:"The system to be used as Cloud in a Box must fulfill these minimum requirements."}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Type of resource"}),(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Amount"}),(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"CPU"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"at least 1 socket with 4 cores"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"More is better here. This is the minimum where you can't use much payload (LBaaS, VMs). The use of Kubernetes with Cluster API is not possible with this minimum size."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"RAM"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"at least 32 GByte"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"More is better here. In principle, it also works with 8 GByte, but then no payload (LBaaS, VMs) can be used. Kubernetes with Cluster API cannot be used then."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Storage"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"at least 1 TByte"}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:["Has to be available as ",(0,s.jsx)(n.code,{children:"/dev/sda"})," or ",(0,s.jsx)(n.code,{children:"/dev/nvme0n1"}),". Less than 1 TByte is also possible, the smaller the less storage is available for use in Ceph."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Network"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"at least 1 network interface (DHCP and internet access)"}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:["An optional ",(0,s.jsx)(n.a,{href:"#use-of-2nd-nic-for-external-network",children:"2nd network interface can be used for external connectivity"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"USB stick"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"at least 2 GByte"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Installation media for Cloud in a Box bootstrapping"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"types",children:"Types"}),"\n",(0,s.jsx)(n.p,{children:"There are two types of Cloud in a Box."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"sandbox"})," type is intended for developers and demonstrations. A full OSISM installation\nis one there which also includes Ceph and OpenSearch, for example. In the course of the\ninstallation, necessary images, networks, etc. are also created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"edge"})," type is intended to be deployed as an appliance to provide an edge cloud on a\nsingle node. Compared to the sandbox, certain services are not provided there or are\nimplemented differently. For example, OpenSearch is not deployed because the logs are\ndelivered to a central location. The storage backend will also be implemented differently there\nin the future instead of Ceph."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"general-notes-and-limitations",children:"General notes and limitations"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Load balancing in Octavia is only possible via OVN. The Amphora driver is not supported. This is due\nto the limited resources we have. With the Amphora driver, a dedicated instance is started for each\nload balancer, each of which consumes 1 GByte of memory. This represents a very high consumption in\nrelation to the usual sizes of the Cloud in a Box."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,s.jsx)(n.h3,{id:"automated-installation-recommended",children:"Automated installation (recommended)"}),"\n",(0,s.jsxs)(n.p,{children:["The images currently download and install the\n",(0,s.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box",children:"latest state of the installation scripts"}),",\ntherefore it is mandatory to update the installation media at least when the underlying Ubuntu operating\nsystem release changes. The installation of older releases is currently not supported."]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Download one of the Cloud in a Box images of type sandbox"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/osism-node-image/ubuntu-autoinstall-cloud-in-a-box-1.iso",children:"ubuntu-autoinstall-cloud-in-a-box-1.iso"})," (with first block device as ",(0,s.jsx)(n.code,{children:"/dev/sda"}),")"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/osism-node-image/ubuntu-autoinstall-cloud-in-a-box-2.iso",children:"ubuntu-autoinstall-cloud-in-a-box-2.iso"})," (with first block device as ",(0,s.jsx)(n.code,{children:"/dev/nvme0n1"}),")"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Use a tool like ",(0,s.jsx)(n.a,{href:"https://etcher.balena.io",children:"balenaEtcher"})," or ",(0,s.jsx)(n.code,{children:"dd"})," to create a bootable USB stick with the Cloud\nin a Box image."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Boot from the USB stick. Make sure that the boot from USB is activated in the BIOS."}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"When booting from this USB stick, all data on the hard disks will be destroyed\nwithout confirmation."})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The installation of the operating system (Ubuntu 22.04) will start and take a few minutes. After that the system\nwill shutdown."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The first start of the system"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Remove the USB storage device\n(The USB stick is only needed again if the Cloud in a Box system is to be fully reinstalled.)"}),"\n",(0,s.jsx)(n.li,{children:"Connect the first network interface to an ethernet interface that provides access to the internet via DHCP configuration"}),"\n",(0,s.jsx)(n.li,{children:"Boot the system from the internal hard disk device"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The deployment will start. This takes some time and the system will shutdown when the\ndeployment is finished. This takes roughly an hour, possibly longer depending on the\nhardware and internet connection."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Start the system again. System is ready for use, by default DHCP is tried on the first network device."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Login via SSH. Use the user ",(0,s.jsx)(n.code,{children:"dragon"})," with the password ",(0,s.jsx)(n.code,{children:"password"}),".\n(You can obtain the ip address by inspecting the logs of your dhcp server or from the ",(0,s.jsx)(n.em,{children:"issue text"})," of the virtual consoles of the system)"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ssh dragon@IP_FROM_YOUR_SERVER\npasswd\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"CiaB Issue Text",src:t(95883).A+"",width:"420",height:"109"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"manual-installation",children:"Manual installation"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Follow the ",(0,s.jsx)(n.a,{href:"../deploy-guide/provisioning",children:"provisioning guide"}),",\nskip the part about disk layout and do it this way:"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Disk layout",src:t(38824).A+"",width:"1033",height:"769"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Create a 1 GByte ext4 partition mounted in ",(0,s.jsx)(n.code,{children:"/boot"})]}),"\n",(0,s.jsx)(n.li,{children:"Create a 8 GByte swap partition"}),"\n",(0,s.jsx)(n.li,{children:"Create a 120 GByte unformatted partition"}),"\n",(0,s.jsxs)(n.li,{children:["Use a ",(0,s.jsx)(n.code,{children:"Create volume group (LVM)"})," to create a volume group called ",(0,s.jsx)(n.code,{children:"system"})," with the size of\n120 GByte on the partition 4 you just created"]}),"\n",(0,s.jsxs)(n.li,{children:["Create a logical volume by selecting the ",(0,s.jsx)(n.code,{children:"Free Space"})," option under ",(0,s.jsx)(n.code,{children:"system"})," LVM. This volume\nshould be mounted in ",(0,s.jsx)(n.code,{children:"/"})," and have size of 100 GByte"]}),"\n",(0,s.jsx)(n.li,{children:"Create a partition with the size of the rest of the drive's space"}),"\n",(0,s.jsxs)(n.li,{children:["Create a new LVM volume group on partition 5 called ",(0,s.jsx)(n.code,{children:"osd-vg"})," (will be used for Ceph)"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"After the Ubuntu installation, the system will be rebooted"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Log into the machine via console to get its IP address and then use SSH to connect to the machine"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Clone the ",(0,s.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box",children:"osism/cloud-in-a-box"})," repository into ",(0,s.jsx)(n.code,{children:"/opt/cloud-in-a-box"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo git clone https://github.com/osism/cloud-in-a-box /opt/cloud-in-a-box\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Disable conflicting services from the default Ubuntu installation"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo /opt/cloud-in-a-box/cleanup.sh\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Install upgrades"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo apt update\nsudo apt upgrade\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run the ",(0,s.jsx)(n.code,{children:"bootstrap.sh"})," script with the required ",(0,s.jsx)(n.a,{href:"#types",children:"type"})," (use of ",(0,s.jsx)(n.code,{children:"sandbox"})," is recommended)"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo /opt/cloud-in-a-box/bootstrap.sh sandbox\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run the ",(0,s.jsx)(n.code,{children:"deploy.sh"})," script with the same type as in step 8 to deploy services like Ceph and OpenStack"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo /opt/cloud-in-a-box/deploy.sh sandbox\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Shutdown the system"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo shutdown -h now\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Start the system again. System is ready for use, by default DHCP is tried on the first network device."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Login via SSH. Use the user ",(0,s.jsx)(n.code,{children:"dragon"})," with the password ",(0,s.jsx)(n.code,{children:"password"}),".\n(You can obtain the ip address by inspecting the logs of your dhcp server or from the ",(0,s.jsx)(n.em,{children:"issue text"})," of the virtual consoles of the system)"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ssh dragon@IP_FROM_YOUR_SERVER\npasswd\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"CiaB Issue Text",src:t(95883).A+"",width:"420",height:"109"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["The scripts are not idempotent yet. In case there is any fail during ",(0,s.jsx)(n.code,{children:"bootstrap.sh"})," or ",(0,s.jsx)(n.code,{children:"deploy.sh"})," you have to\nstart over with fresh installation."]})}),"\n",(0,s.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,s.jsx)(n.h3,{id:"wireguard-vpn-service-access",children:"Wireguard VPN service access"}),"\n",(0,s.jsxs)(n.p,{children:["Copy the ",(0,s.jsx)(n.code,{children:"/home/dragon/wireguard-client.conf"})," file from Cloud in a Box to your workstation. This is necessary\nfor using the web endpoints on your workstation. Rename the wireguard config file to something\nlike ",(0,s.jsx)(n.code,{children:"cloud-in-a-box.conf"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"If you want to connect to the Cloud in a Box system from multiple clients, change the client IP\naddress in the config file to be different on each client."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"scp dragon@IP_FROM_YOUR_SERVER:/home/dragon/wireguard-client.conf $HOME/cloud-in-a-box.conf\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Install wireguard on your workstation, if you have not done this before. For instructions how to do\nit on your workstation, please have a look on the documentation of your used distribution. The\nwireguard documentation you will find ",(0,s.jsx)(n.a,{href:"https://www.wireguard.com",children:"here"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Start the wireguard tunnel."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo wg-quick up $HOME/cloud-in-a-box.conf\n"})}),"\n",(0,s.jsx)(n.h3,{id:"webinterfaces",children:"Webinterfaces"}),"\n",(0,s.jsx)(n.p,{children:"If you want to access the services please choose the URL from the following list:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Name"}),(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"URL"}),(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Username"}),(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Password"}),(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Note"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"ARA"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://ara.services.in-a-box.cloud",children:"https://ara.services.in-a-box.cloud"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"ara"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Ceph"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"http://manager.systems.in-a-box.cloud:7000",children:"http://manager.systems.in-a-box.cloud:7000"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"admin"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Flower"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://flower.services.in-a-box.cloud",children:"https://flower.services.in-a-box.cloud"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Grafana"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://api.in-a-box.cloud:3000",children:"https://api.in-a-box.cloud:3000"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"admin"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"HAProxy"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"http://manager.systems.in-a-box.cloud:1984",children:"http://manager.systems.in-a-box.cloud:1984"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"openstack"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Homer"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://homer.services.in-a-box.cloud",children:"https://homer.services.in-a-box.cloud"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Horizon - admin project"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://api.in-a-box.cloud",children:"https://api.in-a-box.cloud"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"admin"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"domain: default"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Horizon - test project"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://api.in-a-box.cloud",children:"https://api.in-a-box.cloud"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"test"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"test"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"domain: test"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Netbox"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://netbox.services.in-a-box.cloud",children:"https://netbox.services.in-a-box.cloud"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"admin"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Netdata"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"http://manager.systems.in-a-box.cloud:19999",children:"http://manager.systems.in-a-box.cloud:19999"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"-"}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"OpenSearch Dashboards"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://api.in-a-box.cloud:5601",children:"https://api.in-a-box.cloud:5601"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"opensearch"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"PhpMyAdmin"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://phpmyadmin.services.in-a-box.cloud",children:"https://phpmyadmin.services.in-a-box.cloud"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"root"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Starting with OSISM 7, root_shard_0 is used as the user name"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"RabbitMQ"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://api.in-a-box.cloud:15672",children:"https://api.in-a-box.cloud:15672"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"openstack"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Skyline - admin project"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://api.in-a-box.cloud:9999",children:"https://api.in-a-box.cloud:9999"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"admin"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"password"}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Skyline - test project"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://api.in-a-box.cloud:9999",children:"https://api.in-a-box.cloud:9999"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"test"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"test"}),(0,s.jsx)(n.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"command-line-interfaces",children:"Command-line interfaces"}),"\n",(0,s.jsx)(n.p,{children:"Login to Cloud in a Box as described in step 8 of the installation chapter."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Select one of the preconfigured environments:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"system"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"admin"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"test"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Set the environment by exporting the environment variable: ",(0,s.jsx)(n.code,{children:"OS_CLOUD"}),":","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"export OS_CLOUD=admin\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Use ",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/newton/user-guide/cli.html",children:"OpenStack CLI"})," via the command ",(0,s.jsx)(n.code,{children:"openstack"}),".","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"openstack availability zone list\nopenstack image list\nopenstack server list # After installation there are no servers\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"import-of-additional-images",children:"Import of additional images"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://github.com/osism/openstack-image-manager/",children:"OpenStack Image Manager"})," is used to manage images.\nIn the example, the ",(0,s.jsx)(n.code,{children:"Garden Linux"})," image is imported."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"osism manage images --cloud=admin --filter 'Garden Linux'\n"})}),"\n",(0,s.jsxs)(n.p,{children:["All available images can be found in the ",(0,s.jsx)(n.a,{href:"https://github.com/osism/openstack-image-manager/tree/main/etc/images",children:"osism/openstack-image-manager"})," repository."]}),"\n",(0,s.jsx)(n.h3,{id:"upgrade",children:"Upgrade"}),"\n",(0,s.jsx)(n.p,{children:"It is best to execute the commands within a screen session, it takes some time. Please note\nthat you cannot update the Ceph deployment at the moment. This will be enabled in the future."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"osism apply configuration\n/opt/configuration/upgrade.sh\ndocker system prune -a\n"})}),"\n",(0,s.jsx)(n.h2,{id:"customisations",children:"Customisations"}),"\n",(0,s.jsx)(n.h3,{id:"use-of-2nd-nic-for-external-network",children:"Use of 2nd NIC for external network"}),"\n",(0,s.jsx)(n.p,{children:"In the default configuration, the Cloud in a Box is built in such a way that an internal\nVLAN101 is used as an simulated external network and this is made usable via the 1st network\ninterface using masquerading. This makes it possible for instances running on the Cloud\nin a Box to reach the internet. The disadvantage of this is that the instances themselves\ncan only be reached via floating IP addresses from the Cloud in a Box system itself or\nvia the Wireguard tunnel. Especially in edge environments, however, one would usually like\nto have this differently and the instances should be directly accessible via the local\nnetwork."}),"\n",(0,s.jsx)(n.p,{children:"To make this work, first identify the name of a 2nd network card to be used."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"dragon@manager:~$ sudo lshw -class network -short\nH/W path Device Class Description\n============================================================\n/0/100/2.2/0 eno7 network Ethernet Connection X552 10 GbE SFP+\n/0/100/2.2/0.1 eno8 network Ethernet Connection X552 10 GbE SFP+\n/0/100/1c/0 eno1 network I210 Gigabit Network Connection\n/0/100/1c.1/0 eno2 network I210 Gigabit Network Connection\n/0/100/1c.4/0 eno3 network I350 Gigabit Network Connection\n/0/100/1c.4/0.1 eno4 network I350 Gigabit Network Connection\n/0/100/1c.4/0.2 eno5 network I350 Gigabit Network Connection\n/0/100/1c.4/0.3 eno6 network I350 Gigabit Network Connection\n"})}),"\n",(0,s.jsxs)(n.p,{children:["In the following we use ",(0,s.jsx)(n.code,{children:"eno7"}),". Activate the device manually with ",(0,s.jsx)(n.code,{children:"sudo ip link set up dev eno7"}),".\nThen check that a link is actually present."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"dragon@manager:~$ ethtool eno7\nSettings for eno7:\n\tSupported ports: [ FIBRE ]\n\tSupported link modes: 10000baseT/Full\n[...]\n\tLink detected: yes\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Now this device is made permanently known in the network configuration. Select the MTU\naccordingly. For 1 GBit rather ",(0,s.jsx)(n.code,{children:"1500"})," than ",(0,s.jsx)(n.code,{children:"9100"}),". The 2nd network interface should be\nconfigured without IP configuration (neither static nor DHCP)."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"/opt/configuration/inventory/group_vars/generic/network.yml"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"/opt/configuration/environments/manager/group_vars/manager.yml"})}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"network_ethernets:\n eno1:\n dhcp4: true\n eno7:\n mtu: 9100\n"})}),"\n",(0,s.jsx)(n.p,{children:"Then, this change is deployed and applied."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"osism apply network\nsudo netplan apply\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Now the configuration for Neutron and OVN is prepared. ",(0,s.jsx)(n.code,{children:"network_workload_interface"}),"\nis expanded by the 2nd network interface. The order is not random, first ",(0,s.jsx)(n.code,{children:"vlan101"}),"\nthen ",(0,s.jsx)(n.code,{children:"eno7"}),". ",(0,s.jsx)(n.code,{children:"neutron_bridge_name"})," is added."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"/opt/configuration/inventory/group_vars/generic/network.yml"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"/opt/configuration/environments/manager/group_vars/manager.yml"})}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'network_workload_interface: "vlan101,eno7"\nneutron_bridge_name: "br-ex,br-add"\n'})}),"\n",(0,s.jsx)(n.p,{children:"Then, this change is deployed."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"osism reconciler sync\nosism apply openvswitch\nosism apply ovn\nosism apply neutron\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Now segments and/or subnets can be configured. In this case, ",(0,s.jsx)(n.code,{children:"eno7"})," is configured as an\nuntagged port on the remote side."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"/opt/configuration/environments/openstack/playbook-additional-public-network.yml"})}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"- name: Create additional public network\n hosts: localhost\n connection: local\n\n tasks:\n - name: Create additional public network\n openstack.cloud.network:\n cloud: admin\n state: present\n name: public-add\n external: true\n provider_network_type: flat\n provider_physical_network: physnet2\n\n - name: Create additional public subnet\n openstack.cloud.subnet:\n cloud: admin\n state: present\n name: subnet-public-add\n network_name: public-add\n cidr: 192.168.23.0/24\n enable_dhcp: false\n allocation_pool_start: 192.168.23.100\n allocation_pool_end: 192.168.23.200\n gateway_ip: 192.168.23.1\n dns_nameservers:\n - 8.8.8.8\n - 9.9.9.9\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The additional public network can now be made known with\n",(0,s.jsx)(n.code,{children:"osism apply -e openstack additional-public-network"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["There is now a 2nd floating IP address pool with the name ",(0,s.jsx)(n.code,{children:"public-add"}),"\navailable for use. If instances are to be started directly in this network,\n",(0,s.jsx)(n.code,{children:"enable_dhcp: true"})," must be set. In this case, it should be clarified in\nadvance with the provider of the external network whether the use of DHCP\nis permitted there."]}),"\n",(0,s.jsx)(n.h3,{id:"running-on-a-virtual-machine",children:"Running on a Virtual Machine"}),"\n",(0,s.jsx)(n.p,{children:"The Cloud in a Box has been tested to run on a virtual machine. However, the Cloud in a Box is mainly made\nfor running on bare metal, the automated installation does not work, and other things may not work either."}),"\n",(0,s.jsx)(n.h4,{id:"nested-virtualization",children:"Nested virtualization"}),"\n",(0,s.jsx)(n.p,{children:"You likely want to run virtual machines on top of your Cloud in a Box.\nThe host machine has to support and enabled nested virtualization."}),"\n",(0,s.jsxs)(n.p,{children:["To enable nested virtualization the CPU configuration of the VM has to be ",(0,s.jsx)(n.code,{children:"host-passthrough"})," or ",(0,s.jsx)(n.code,{children:"host-model"})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.fedoraproject.org/en-US/quick-docs/using-nested-virtualization-in-kvm/",children:"Enabling nested virtualization in Fedora"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The linked guide can be used in other distributions as well."}),"\n",(0,s.jsx)(n.h4,{id:"disk-space-saving",children:"Disk space saving"}),"\n",(0,s.jsxs)(n.p,{children:["When using Cloud in a Box in a VM, you can utilize the qcow2 disk image or similar technology to save space.\nIn that case, the base installation requires just around 70 GB instead of a full 1 TB.\n(",(0,s.jsx)(n.em,{children:"The drive still needs to be made with a capacity of at least 1TB; however, the actual disk space usage is lower."}),")"]}),"\n",(0,s.jsxs)(n.p,{children:['Also in case you want to experiment a bit more and "hack around" using the manual installation\nyou can make disk snapshots when turned off after the Ubuntu installs, ',(0,s.jsx)(n.code,{children:"bootstrap.sh"})," and ",(0,s.jsx)(n.code,{children:"deploy.sh"})," to speed up your\nprogress."]}),"\n",(0,s.jsx)(n.p,{children:"If you use qemu, you can use following command to do snapshots."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'sudo virsh snapshot-create-as --domain cib bootstrap "run of bootstrap.sh" --disk-only --diskspec sda,snapshot=external,file=/var/lib/libvirt/images/ub2022_cib_boostrap.qcow2 --atomic\n'})}),"\n",(0,s.jsx)(n.h4,{id:"qemu-guest-agent",children:"QEMU guest agent"}),"\n",(0,s.jsx)(n.p,{children:"When running inside QEMU, it may be worth it to install the QEMU guest agent."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo apt -y install qemu-guest-agent\nsudo systemctl enable qemu-guest-agent\nsudo systemctl start qemu-guest-agent\n"})}),"\n",(0,s.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Broken disk setup",src:t(98099).A+"",width:"2020",height:"1194"})}),"\n",(0,s.jsxs)(n.p,{children:["This error means that your disk setup is broken. Use ",(0,s.jsx)(n.code,{children:"cfdisk"})," and delete all partitions on\nthe system on which you want to install the Cloud in a Box image."]}),"\n",(0,s.jsxs)(n.p,{children:["With ",(0,s.jsx)(n.code,{children:"lsblk"})," you can verify if the partitions are empty."]}),"\n",(0,s.jsx)(n.h2,{id:"development",children:"Development"}),"\n",(0,s.jsx)(n.p,{children:"For the further development of the scripts and the mechanisms of the Cloud in a Box,\nyou need to know the following."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The operating system is brought onto the node via ",(0,s.jsx)(n.a,{href:"https://github.com/osism/node-image",children:"an automatic Ubuntu installation"}),"\nthat uses ",(0,s.jsx)(n.a,{href:"https://cloud-init.io",children:"cloud-init"})]}),"\n",(0,s.jsxs)(n.li,{children:["The installation starts the script ",(0,s.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box/blob/main/init.sh",children:"init.sh"})," which performs\nan initial clone of the ",(0,s.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box",children:"osism/cloud-in-a-box"})," repository and a checkout of\nthe ",(0,s.jsx)(n.code,{children:"main"})," branch. It also executes the ",(0,s.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box/blob/main/deploy.sh",children:"deploy.sh"})," and\n",(0,s.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box/blob/main/bootstrap.sh",children:"bootstrap.sh"})," scripts."]}),"\n",(0,s.jsxs)(n.li,{children:["The installation persists the kernel parameters of the initial boot to the file ",(0,s.jsx)(n.code,{children:"/etc/.initial-kernel-commandline"})]}),"\n",(0,s.jsxs)(n.li,{children:["The status and activities of the deployment are logged in ",(0,s.jsx)(n.code,{children:"/var/log/install-cloud-in-a-box.log"}),". For proper colors use ",(0,s.jsx)(n.code,{children:"less -r"}),".\nSearch for ",(0,s.jsx)(n.code,{children:"OVERALL STATUS"})," to find the result of the specific installation steps."]}),"\n",(0,s.jsxs)(n.li,{children:["Branch and location of the ",(0,s.jsx)(n.a,{href:"https://github.com/osism/cloud-in-a-box",children:"osism/cloud-in-a-box"})," repository can be overriden\nby setting the kernel parameters ",(0,s.jsx)(n.code,{children:"ciab_repo_url"})," (a public repository address without authentication) and ",(0,s.jsx)(n.code,{children:"ciab_branch"}),"\n(a name of a branch, use only ASCII chars, ",(0,s.jsx)(n.code,{children:"-"}),", and ",(0,s.jsx)(n.code,{children:"_"}),")."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},38824:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/disk-layout-db64866af60ef6d2c41245db78dd15d1.png"},95883:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/issue-6cc9ac7387e0589d625dded707510641.png"},98099:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/screenshot1-c880f78ba33fc0577dce811dc2e42724.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},l=s.createContext(i);function o(e){const n=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/71acf54e.fc90ca36.js b/assets/js/71acf54e.fc90ca36.js new file mode 100644 index 0000000000..e65022f2a3 --- /dev/null +++ b/assets/js/71acf54e.fc90ca36.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[309],{87688:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>o,contentTitle:()=>s,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>d});var n=i(74848),r=i(28453);const c={sidebar_label:"Cluster design",sidebar_position:30},s="Cluster design",a={id:"iaas/guides/concept-guide/design",title:"Cluster design",description:"Parts of this chapter are based on the OpenStack Architecture Design Guide.",source:"@site/docs/02-iaas/guides/concept-guide/design.md",sourceDirName:"02-iaas/guides/concept-guide",slug:"/iaas/guides/concept-guide/design",permalink:"/docs/iaas/guides/concept-guide/design",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/design.md",tags:[],version:"current",sidebarPosition:30,frontMatter:{sidebar_label:"Cluster design",sidebar_position:30},sidebar:"docs",previous:{title:"Layers in a cluster",permalink:"/docs/iaas/guides/concept-guide/layers"},next:{title:"Use cases",permalink:"/docs/iaas/guides/concept-guide/use-cases"}},o={},d=[{value:"Compute architecture",id:"compute-architecture",level:2},{value:"Storage architecture",id:"storage-architecture",level:2},{value:"Network architecture",id:"network-architecture",level:2},{value:"Identity architecture",id:"identity-architecture",level:2},{value:"Control plane architecture",id:"control-plane-architecture",level:2}];function u(e){const t={a:"a",admonition:"admonition",h1:"h1",h2:"h2",p:"p",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"cluster-design",children:"Cluster design"}),"\n",(0,n.jsx)(t.admonition,{type:"info",children:(0,n.jsxs)(t.p,{children:["Parts of this chapter are based on the ",(0,n.jsx)(t.a,{href:"https://docs.openstack.org/arch-design/index.html",children:"OpenStack Architecture Design Guide"}),".\nThe sources for this guide can be found in repostory ",(0,n.jsx)(t.a,{href:"https://github.com/openstack/arch-design",children:"openstack/arch-design"}),"\nand have been published under the Apache Licence 2.0."]})}),"\n",(0,n.jsx)(t.h2,{id:"compute-architecture",children:"Compute architecture"}),"\n",(0,n.jsx)(t.h2,{id:"storage-architecture",children:"Storage architecture"}),"\n",(0,n.jsx)(t.h2,{id:"network-architecture",children:"Network architecture"}),"\n",(0,n.jsx)(t.h2,{id:"identity-architecture",children:"Identity architecture"}),"\n",(0,n.jsx)(t.h2,{id:"control-plane-architecture",children:"Control plane architecture"})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>a});var n=i(96540);const r={},c=n.createContext(r);function s(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7200.2d36d6d5.js b/assets/js/7200.2d36d6d5.js new file mode 100644 index 0000000000..164f1fd73a --- /dev/null +++ b/assets/js/7200.2d36d6d5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7200],{57200:(t,i,e)=>{e.d(i,{diagram:()=>d});var a=e(76257),n=e(26312),r=(e(74353),e(16750),e(42838),function(){var t=function(t,i,e,a){for(e=e||{},a=t.length;a--;e[t[a]]=i);return e},i=[1,3],e=[1,4],a=[1,5],n=[1,6],r=[1,7],s=[1,5,13,15,17,19,20,25,27,28,29,30,31,32,33,34,37,38,40,41,42,43,44,45,46,47,48,49,50],l=[1,5,6,13,15,17,19,20,25,27,28,29,30,31,32,33,34,37,38,40,41,42,43,44,45,46,47,48,49,50],o=[32,33,34],h=[2,7],c=[1,13],d=[1,17],u=[1,18],x=[1,19],g=[1,20],f=[1,21],y=[1,22],p=[1,23],q=[1,24],T=[1,25],m=[1,26],A=[1,27],_=[1,30],b=[1,31],S=[1,32],k=[1,33],F=[1,34],P=[1,35],v=[1,36],L=[1,37],C=[1,38],z=[1,39],B=[1,40],E=[1,41],D=[1,42],I=[1,57],w=[1,58],R=[5,22,26,32,33,34,40,41,42,43,44,45,46,47,48,49,50,51],W={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,SPACE:5,QUADRANT:6,document:7,line:8,statement:9,axisDetails:10,quadrantDetails:11,points:12,title:13,title_value:14,acc_title:15,acc_title_value:16,acc_descr:17,acc_descr_value:18,acc_descr_multiline_value:19,section:20,text:21,point_start:22,point_x:23,point_y:24,"X-AXIS":25,"AXIS-TEXT-DELIMITER":26,"Y-AXIS":27,QUADRANT_1:28,QUADRANT_2:29,QUADRANT_3:30,QUADRANT_4:31,NEWLINE:32,SEMI:33,EOF:34,alphaNumToken:35,textNoTagsToken:36,STR:37,MD_STR:38,alphaNum:39,PUNCTUATION:40,AMP:41,NUM:42,ALPHA:43,COMMA:44,PLUS:45,EQUALS:46,MULT:47,DOT:48,BRKT:49,UNDERSCORE:50,MINUS:51,$accept:0,$end:1},terminals_:{2:"error",5:"SPACE",6:"QUADRANT",13:"title",14:"title_value",15:"acc_title",16:"acc_title_value",17:"acc_descr",18:"acc_descr_value",19:"acc_descr_multiline_value",20:"section",22:"point_start",23:"point_x",24:"point_y",25:"X-AXIS",26:"AXIS-TEXT-DELIMITER",27:"Y-AXIS",28:"QUADRANT_1",29:"QUADRANT_2",30:"QUADRANT_3",31:"QUADRANT_4",32:"NEWLINE",33:"SEMI",34:"EOF",37:"STR",38:"MD_STR",40:"PUNCTUATION",41:"AMP",42:"NUM",43:"ALPHA",44:"COMMA",45:"PLUS",46:"EQUALS",47:"MULT",48:"DOT",49:"BRKT",50:"UNDERSCORE",51:"MINUS"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[9,0],[9,2],[9,1],[9,1],[9,1],[9,2],[9,2],[9,2],[9,1],[9,1],[12,4],[10,4],[10,3],[10,2],[10,4],[10,3],[10,2],[11,2],[11,2],[11,2],[11,2],[4,1],[4,1],[4,1],[21,1],[21,2],[21,1],[21,1],[39,1],[39,2],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[36,1],[36,1],[36,1]],performAction:function(t,i,e,a,n,r,s){var l=r.length-1;switch(n){case 12:this.$=r[l].trim(),a.setDiagramTitle(this.$);break;case 13:this.$=r[l].trim(),a.setAccTitle(this.$);break;case 14:case 15:this.$=r[l].trim(),a.setAccDescription(this.$);break;case 16:a.addSection(r[l].substr(8)),this.$=r[l].substr(8);break;case 17:a.addPoint(r[l-3],r[l-1],r[l]);break;case 18:a.setXAxisLeftText(r[l-2]),a.setXAxisRightText(r[l]);break;case 19:r[l-1].text+=" \u27f6 ",a.setXAxisLeftText(r[l-1]);break;case 20:a.setXAxisLeftText(r[l]);break;case 21:a.setYAxisBottomText(r[l-2]),a.setYAxisTopText(r[l]);break;case 22:r[l-1].text+=" \u27f6 ",a.setYAxisBottomText(r[l-1]);break;case 23:a.setYAxisBottomText(r[l]);break;case 24:a.setQuadrant1Text(r[l]);break;case 25:a.setQuadrant2Text(r[l]);break;case 26:a.setQuadrant3Text(r[l]);break;case 27:a.setQuadrant4Text(r[l]);break;case 31:case 33:this.$={text:r[l],type:"text"};break;case 32:this.$={text:r[l-1].text+""+r[l],type:r[l-1].type};break;case 34:this.$={text:r[l],type:"markdown"};break;case 35:this.$=r[l];break;case 36:this.$=r[l-1]+""+r[l]}},table:[{3:1,4:2,5:i,6:e,32:a,33:n,34:r},{1:[3]},{3:8,4:2,5:i,6:e,32:a,33:n,34:r},{3:9,4:2,5:i,6:e,32:a,33:n,34:r},t(s,[2,4],{7:10}),t(l,[2,28]),t(l,[2,29]),t(l,[2,30]),{1:[2,1]},{1:[2,2]},t(o,h,{8:11,9:12,10:14,11:15,12:16,21:28,35:29,1:[2,3],5:c,13:d,15:u,17:x,19:g,20:f,25:y,27:p,28:q,29:T,30:m,31:A,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D}),t(s,[2,5]),{4:43,32:a,33:n,34:r},t(o,h,{10:14,11:15,12:16,21:28,35:29,9:44,5:c,13:d,15:u,17:x,19:g,20:f,25:y,27:p,28:q,29:T,30:m,31:A,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D}),t(o,[2,9]),t(o,[2,10]),t(o,[2,11]),{14:[1,45]},{16:[1,46]},{18:[1,47]},t(o,[2,15]),t(o,[2,16]),{21:48,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D},{21:49,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D},{21:50,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D},{21:51,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D},{21:52,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D},{21:53,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D},{5:I,22:[1,54],35:56,36:55,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w},t(R,[2,31]),t(R,[2,33]),t(R,[2,34]),t(R,[2,37]),t(R,[2,38]),t(R,[2,39]),t(R,[2,40]),t(R,[2,41]),t(R,[2,42]),t(R,[2,43]),t(R,[2,44]),t(R,[2,45]),t(R,[2,46]),t(R,[2,47]),t(s,[2,6]),t(o,[2,8]),t(o,[2,12]),t(o,[2,13]),t(o,[2,14]),t(o,[2,20],{36:55,35:56,5:I,26:[1,59],40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,23],{36:55,35:56,5:I,26:[1,60],40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,24],{36:55,35:56,5:I,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,25],{36:55,35:56,5:I,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,26],{36:55,35:56,5:I,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,27],{36:55,35:56,5:I,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),{23:[1,61]},t(R,[2,32]),t(R,[2,48]),t(R,[2,49]),t(R,[2,50]),t(o,[2,19],{35:29,21:62,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D}),t(o,[2,22],{35:29,21:63,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D}),{24:[1,64]},t(o,[2,18],{36:55,35:56,5:I,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,21],{36:55,35:56,5:I,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:B,49:E,50:D,51:w}),t(o,[2,17])],defaultActions:{8:[2,1],9:[2,2]},parseError:function(t,i){if(!i.recoverable){var e=new Error(t);throw e.hash=i,e}this.trace(t)},parse:function(t){var i=this,e=[0],a=[],n=[null],r=[],s=this.table,l="",o=0,h=0,c=r.slice.call(arguments,1),d=Object.create(this.lexer),u={yy:{}};for(var x in this.yy)Object.prototype.hasOwnProperty.call(this.yy,x)&&(u.yy[x]=this.yy[x]);d.setInput(t,u.yy),u.yy.lexer=d,u.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var g=d.yylloc;r.push(g);var f=d.options&&d.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var y,p,q,T,m,A,_,b,S,k={};;){if(p=e[e.length-1],this.defaultActions[p]?q=this.defaultActions[p]:(null==y&&(S=void 0,"number"!=typeof(S=a.pop()||d.lex()||1)&&(S instanceof Array&&(S=(a=S).pop()),S=i.symbols_[S]||S),y=S),q=s[p]&&s[p][y]),void 0===q||!q.length||!q[0]){var F="";for(m in b=[],s[p])this.terminals_[m]&&m>2&&b.push("'"+this.terminals_[m]+"'");F=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+b.join(", ")+", got '"+(this.terminals_[y]||y)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==y?"end of input":"'"+(this.terminals_[y]||y)+"'"),this.parseError(F,{text:d.match,token:this.terminals_[y]||y,line:d.yylineno,loc:g,expected:b})}if(q[0]instanceof Array&&q.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+y);switch(q[0]){case 1:e.push(y),n.push(d.yytext),r.push(d.yylloc),e.push(q[1]),y=null,h=d.yyleng,l=d.yytext,o=d.yylineno,g=d.yylloc;break;case 2:if(A=this.productions_[q[1]][1],k.$=n[n.length-A],k._$={first_line:r[r.length-(A||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(A||1)].first_column,last_column:r[r.length-1].last_column},f&&(k._$.range=[r[r.length-(A||1)].range[0],r[r.length-1].range[1]]),void 0!==(T=this.performAction.apply(k,[l,h,o,u.yy,q[1],n,r].concat(c))))return T;A&&(e=e.slice(0,-1*A*2),n=n.slice(0,-1*A),r=r.slice(0,-1*A)),e.push(this.productions_[q[1]][0]),n.push(k.$),r.push(k._$),_=s[e[e.length-2]][e[e.length-1]],e.push(_);break;case 3:return!0}}return!0}},N={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)},setInput:function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var i=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var a=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===a.length?this.yylloc.first_column:0)+a[a.length-e.length].length-e[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"},test_match:function(t,i){var e,a,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,e,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;r<n.length;r++)if((e=this._input.match(this.rules[n[r]]))&&(!i||e[0].length>i[0].length)){if(i=e,a=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,n[r])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,n[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,e,a){switch(e){case 0:case 1:case 3:break;case 2:return 32;case 4:return this.begin("title"),13;case 5:return this.popState(),"title_value";case 6:return this.begin("acc_title"),15;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),17;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 22:case 24:case 28:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 25;case 14:return 27;case 15:return 26;case 16:return 28;case 17:return 29;case 18:return 30;case 19:return 31;case 20:this.begin("md_string");break;case 21:return"MD_STR";case 23:this.begin("string");break;case 25:return"STR";case 26:return this.begin("point_start"),22;case 27:return this.begin("point_x"),23;case 29:this.popState(),this.begin("point_y");break;case 30:return this.popState(),24;case 31:return 6;case 32:return 43;case 33:return"COLON";case 34:return 45;case 35:return 44;case 36:case 37:return 46;case 38:return 47;case 39:return 49;case 40:return 50;case 41:return 48;case 42:return 41;case 43:return 51;case 44:return 42;case 45:return 5;case 46:return 33;case 47:return 40;case 48:return 34}},rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?: *x-axis *)/i,/^(?: *y-axis *)/i,/^(?: *--+> *)/i,/^(?: *quadrant-1 *)/i,/^(?: *quadrant-2 *)/i,/^(?: *quadrant-3 *)/i,/^(?: *quadrant-4 *)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\s*:\s*\[\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?:\s*\] *)/i,/^(?:\s*,\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?: *quadrantChart *)/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s)/i,/^(?:;)/i,/^(?:[!"#$%&'*+,-.`?\\_/])/i,/^(?:$)/i],conditions:{point_y:{rules:[30],inclusive:!1},point_x:{rules:[29],inclusive:!1},point_start:{rules:[27,28],inclusive:!1},acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},title:{rules:[5],inclusive:!1},md_string:{rules:[21,22],inclusive:!1},string:{rules:[24,25],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,6,8,10,13,14,15,16,17,18,19,20,23,26,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],inclusive:!0}}};function U(){this.yy={}}return W.lexer=N,U.prototype=W,W.Parser=U,new U}());r.parser=r;const s=r,l=(0,a.E)();const o=(0,a.c)();function h(t){return(0,a.d)(t.trim(),o)}const c=new class{constructor(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData()}getDefaultData(){return{titleText:"",quadrant1Text:"",quadrant2Text:"",quadrant3Text:"",quadrant4Text:"",xAxisLeftText:"",xAxisRightText:"",yAxisBottomText:"",yAxisTopText:"",points:[]}}getDefaultConfig(){var t,i,e,n,r,s,l,o,h,c,d,u,x,g,f,y,p,q;return{showXAxis:!0,showYAxis:!0,showTitle:!0,chartHeight:(null==(t=a.B.quadrantChart)?void 0:t.chartWidth)||500,chartWidth:(null==(i=a.B.quadrantChart)?void 0:i.chartHeight)||500,titlePadding:(null==(e=a.B.quadrantChart)?void 0:e.titlePadding)||10,titleFontSize:(null==(n=a.B.quadrantChart)?void 0:n.titleFontSize)||20,quadrantPadding:(null==(r=a.B.quadrantChart)?void 0:r.quadrantPadding)||5,xAxisLabelPadding:(null==(s=a.B.quadrantChart)?void 0:s.xAxisLabelPadding)||5,yAxisLabelPadding:(null==(l=a.B.quadrantChart)?void 0:l.yAxisLabelPadding)||5,xAxisLabelFontSize:(null==(o=a.B.quadrantChart)?void 0:o.xAxisLabelFontSize)||16,yAxisLabelFontSize:(null==(h=a.B.quadrantChart)?void 0:h.yAxisLabelFontSize)||16,quadrantLabelFontSize:(null==(c=a.B.quadrantChart)?void 0:c.quadrantLabelFontSize)||16,quadrantTextTopPadding:(null==(d=a.B.quadrantChart)?void 0:d.quadrantTextTopPadding)||5,pointTextPadding:(null==(u=a.B.quadrantChart)?void 0:u.pointTextPadding)||5,pointLabelFontSize:(null==(x=a.B.quadrantChart)?void 0:x.pointLabelFontSize)||12,pointRadius:(null==(g=a.B.quadrantChart)?void 0:g.pointRadius)||5,xAxisPosition:(null==(f=a.B.quadrantChart)?void 0:f.xAxisPosition)||"top",yAxisPosition:(null==(y=a.B.quadrantChart)?void 0:y.yAxisPosition)||"left",quadrantInternalBorderStrokeWidth:(null==(p=a.B.quadrantChart)?void 0:p.quadrantInternalBorderStrokeWidth)||1,quadrantExternalBorderStrokeWidth:(null==(q=a.B.quadrantChart)?void 0:q.quadrantExternalBorderStrokeWidth)||2}}getDefaultThemeConfig(){return{quadrant1Fill:l.quadrant1Fill,quadrant2Fill:l.quadrant2Fill,quadrant3Fill:l.quadrant3Fill,quadrant4Fill:l.quadrant4Fill,quadrant1TextFill:l.quadrant1TextFill,quadrant2TextFill:l.quadrant2TextFill,quadrant3TextFill:l.quadrant3TextFill,quadrant4TextFill:l.quadrant4TextFill,quadrantPointFill:l.quadrantPointFill,quadrantPointTextFill:l.quadrantPointTextFill,quadrantXAxisTextFill:l.quadrantXAxisTextFill,quadrantYAxisTextFill:l.quadrantYAxisTextFill,quadrantTitleFill:l.quadrantTitleFill,quadrantInternalBorderStrokeFill:l.quadrantInternalBorderStrokeFill,quadrantExternalBorderStrokeFill:l.quadrantExternalBorderStrokeFill}}clear(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData(),a.l.info("clear called")}setData(t){this.data={...this.data,...t}}addPoints(t){this.data.points=[...t,...this.data.points]}setConfig(t){a.l.trace("setConfig called with: ",t),this.config={...this.config,...t}}setThemeConfig(t){a.l.trace("setThemeConfig called with: ",t),this.themeConfig={...this.themeConfig,...t}}calculateSpace(t,i,e,a){const n=2*this.config.xAxisLabelPadding+this.config.xAxisLabelFontSize,r={top:"top"===t&&i?n:0,bottom:"bottom"===t&&i?n:0},s=2*this.config.yAxisLabelPadding+this.config.yAxisLabelFontSize,l={left:"left"===this.config.yAxisPosition&&e?s:0,right:"right"===this.config.yAxisPosition&&e?s:0},o=this.config.titleFontSize+2*this.config.titlePadding,h={top:a?o:0},c=this.config.quadrantPadding+l.left,d=this.config.quadrantPadding+r.top+h.top,u=this.config.chartWidth-2*this.config.quadrantPadding-l.left-l.right,x=this.config.chartHeight-2*this.config.quadrantPadding-r.top-r.bottom-h.top;return{xAxisSpace:r,yAxisSpace:l,titleSpace:h,quadrantSpace:{quadrantLeft:c,quadrantTop:d,quadrantWidth:u,quadrantHalfWidth:u/2,quadrantHeight:x,quadrantHalfHeight:x/2}}}getAxisLabels(t,i,e,a){const{quadrantSpace:n,titleSpace:r}=a,{quadrantHalfHeight:s,quadrantHeight:l,quadrantLeft:o,quadrantHalfWidth:h,quadrantTop:c,quadrantWidth:d}=n,u=Boolean(this.data.xAxisRightText),x=Boolean(this.data.yAxisTopText),g=[];return this.data.xAxisLeftText&&i&&g.push({text:this.data.xAxisLeftText,fill:this.themeConfig.quadrantXAxisTextFill,x:o+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+r.top:this.config.xAxisLabelPadding+c+l+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.xAxisRightText&&i&&g.push({text:this.data.xAxisRightText,fill:this.themeConfig.quadrantXAxisTextFill,x:o+h+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+r.top:this.config.xAxisLabelPadding+c+l+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.yAxisBottomText&&e&&g.push({text:this.data.yAxisBottomText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+o+d+this.config.quadrantPadding,y:c+l-(x?s/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:x?"center":"left",horizontalPos:"top",rotation:-90}),this.data.yAxisTopText&&e&&g.push({text:this.data.yAxisTopText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+o+d+this.config.quadrantPadding,y:c+s-(x?s/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:x?"center":"left",horizontalPos:"top",rotation:-90}),g}getQuadrants(t){const{quadrantSpace:i}=t,{quadrantHalfHeight:e,quadrantLeft:a,quadrantHalfWidth:n,quadrantTop:r}=i,s=[{text:{text:this.data.quadrant1Text,fill:this.themeConfig.quadrant1TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:r,width:n,height:e,fill:this.themeConfig.quadrant1Fill},{text:{text:this.data.quadrant2Text,fill:this.themeConfig.quadrant2TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:r,width:n,height:e,fill:this.themeConfig.quadrant2Fill},{text:{text:this.data.quadrant3Text,fill:this.themeConfig.quadrant3TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:r+e,width:n,height:e,fill:this.themeConfig.quadrant3Fill},{text:{text:this.data.quadrant4Text,fill:this.themeConfig.quadrant4TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:r+e,width:n,height:e,fill:this.themeConfig.quadrant4Fill}];for(const l of s)l.text.x=l.x+l.width/2,0===this.data.points.length?(l.text.y=l.y+l.height/2,l.text.horizontalPos="middle"):(l.text.y=l.y+this.config.quadrantTextTopPadding,l.text.horizontalPos="top");return s}getQuadrantPoints(t){const{quadrantSpace:i}=t,{quadrantHeight:e,quadrantLeft:a,quadrantTop:r,quadrantWidth:s}=i,l=(0,n.m4Y)().domain([0,1]).range([a,s+a]),o=(0,n.m4Y)().domain([0,1]).range([e+r,r]);return this.data.points.map((t=>({x:l(t.x),y:o(t.y),fill:this.themeConfig.quadrantPointFill,radius:this.config.pointRadius,text:{text:t.text,fill:this.themeConfig.quadrantPointTextFill,x:l(t.x),y:o(t.y)+this.config.pointTextPadding,verticalPos:"center",horizontalPos:"top",fontSize:this.config.pointLabelFontSize,rotation:0}})))}getBorders(t){const i=this.config.quadrantExternalBorderStrokeWidth/2,{quadrantSpace:e}=t,{quadrantHalfHeight:a,quadrantHeight:n,quadrantLeft:r,quadrantHalfWidth:s,quadrantTop:l,quadrantWidth:o}=e;return[{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r-i,y1:l,x2:r+o+i,y2:l},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r+o,y1:l+i,x2:r+o,y2:l+n-i},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r-i,y1:l+n,x2:r+o+i,y2:l+n},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r,y1:l+i,x2:r,y2:l+n-i},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:r+s,y1:l+i,x2:r+s,y2:l+n-i},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:r+i,y1:l+a,x2:r+o-i,y2:l+a}]}getTitle(t){if(t)return{text:this.data.titleText,fill:this.themeConfig.quadrantTitleFill,fontSize:this.config.titleFontSize,horizontalPos:"top",verticalPos:"center",rotation:0,y:this.config.titlePadding,x:this.config.chartWidth/2}}build(){const t=this.config.showXAxis&&!(!this.data.xAxisLeftText&&!this.data.xAxisRightText),i=this.config.showYAxis&&!(!this.data.yAxisTopText&&!this.data.yAxisBottomText),e=this.config.showTitle&&!!this.data.titleText,a=this.data.points.length>0?"bottom":this.config.xAxisPosition,n=this.calculateSpace(a,t,i,e);return{points:this.getQuadrantPoints(n),quadrants:this.getQuadrants(n),axisLabels:this.getAxisLabels(a,t,i,n),borderLines:this.getBorders(n),title:this.getTitle(e)}}};const d={parser:s,db:{setWidth:function(t){c.setConfig({chartWidth:t})},setHeight:function(t){c.setConfig({chartHeight:t})},setQuadrant1Text:function(t){c.setData({quadrant1Text:h(t.text)})},setQuadrant2Text:function(t){c.setData({quadrant2Text:h(t.text)})},setQuadrant3Text:function(t){c.setData({quadrant3Text:h(t.text)})},setQuadrant4Text:function(t){c.setData({quadrant4Text:h(t.text)})},setXAxisLeftText:function(t){c.setData({xAxisLeftText:h(t.text)})},setXAxisRightText:function(t){c.setData({xAxisRightText:h(t.text)})},setYAxisTopText:function(t){c.setData({yAxisTopText:h(t.text)})},setYAxisBottomText:function(t){c.setData({yAxisBottomText:h(t.text)})},addPoint:function(t,i,e){c.addPoints([{x:i,y:e,text:h(t.text)}])},getQuadrantData:function(){const t=(0,a.c)(),{themeVariables:i,quadrantChart:e}=t;return e&&c.setConfig(e),c.setThemeConfig({quadrant1Fill:i.quadrant1Fill,quadrant2Fill:i.quadrant2Fill,quadrant3Fill:i.quadrant3Fill,quadrant4Fill:i.quadrant4Fill,quadrant1TextFill:i.quadrant1TextFill,quadrant2TextFill:i.quadrant2TextFill,quadrant3TextFill:i.quadrant3TextFill,quadrant4TextFill:i.quadrant4TextFill,quadrantPointFill:i.quadrantPointFill,quadrantPointTextFill:i.quadrantPointTextFill,quadrantXAxisTextFill:i.quadrantXAxisTextFill,quadrantYAxisTextFill:i.quadrantYAxisTextFill,quadrantExternalBorderStrokeFill:i.quadrantExternalBorderStrokeFill,quadrantInternalBorderStrokeFill:i.quadrantInternalBorderStrokeFill,quadrantTitleFill:i.quadrantTitleFill}),c.setData({titleText:(0,a.t)()}),c.build()},clear:function(){c.clear(),(0,a.v)()},setAccTitle:a.s,getAccTitle:a.g,setDiagramTitle:a.q,getDiagramTitle:a.t,getAccDescription:a.a,setAccDescription:a.b},renderer:{draw:(t,i,e,r)=>{var s,l,o;function h(t){return"top"===t?"hanging":"middle"}function c(t){return"left"===t?"start":"middle"}function d(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}const u=(0,a.c)();a.l.debug("Rendering quadrant chart\n"+t);const x=u.securityLevel;let g;"sandbox"===x&&(g=(0,n.Ltv)("#i"+i));const f=("sandbox"===x?(0,n.Ltv)(g.nodes()[0].contentDocument.body):(0,n.Ltv)("body")).select(`[id="${i}"]`),y=f.append("g").attr("class","main"),p=(null==(s=u.quadrantChart)?void 0:s.chartWidth)||500,q=(null==(l=u.quadrantChart)?void 0:l.chartHeight)||500;(0,a.i)(f,q,p,(null==(o=u.quadrantChart)?void 0:o.useMaxWidth)||!0),f.attr("viewBox","0 0 "+p+" "+q),r.db.setHeight(q),r.db.setWidth(p);const T=r.db.getQuadrantData(),m=y.append("g").attr("class","quadrants"),A=y.append("g").attr("class","border"),_=y.append("g").attr("class","data-points"),b=y.append("g").attr("class","labels"),S=y.append("g").attr("class","title");T.title&&S.append("text").attr("x",0).attr("y",0).attr("fill",T.title.fill).attr("font-size",T.title.fontSize).attr("dominant-baseline",h(T.title.horizontalPos)).attr("text-anchor",c(T.title.verticalPos)).attr("transform",d(T.title)).text(T.title.text),T.borderLines&&A.selectAll("line").data(T.borderLines).enter().append("line").attr("x1",(t=>t.x1)).attr("y1",(t=>t.y1)).attr("x2",(t=>t.x2)).attr("y2",(t=>t.y2)).style("stroke",(t=>t.strokeFill)).style("stroke-width",(t=>t.strokeWidth));const k=m.selectAll("g.quadrant").data(T.quadrants).enter().append("g").attr("class","quadrant");k.append("rect").attr("x",(t=>t.x)).attr("y",(t=>t.y)).attr("width",(t=>t.width)).attr("height",(t=>t.height)).attr("fill",(t=>t.fill)),k.append("text").attr("x",0).attr("y",0).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>h(t.text.horizontalPos))).attr("text-anchor",(t=>c(t.text.verticalPos))).attr("transform",(t=>d(t.text))).text((t=>t.text.text));b.selectAll("g.label").data(T.axisLabels).enter().append("g").attr("class","label").append("text").attr("x",0).attr("y",0).text((t=>t.text)).attr("fill",(t=>t.fill)).attr("font-size",(t=>t.fontSize)).attr("dominant-baseline",(t=>h(t.horizontalPos))).attr("text-anchor",(t=>c(t.verticalPos))).attr("transform",(t=>d(t)));const F=_.selectAll("g.data-point").data(T.points).enter().append("g").attr("class","data-point");F.append("circle").attr("cx",(t=>t.x)).attr("cy",(t=>t.y)).attr("r",(t=>t.radius)).attr("fill",(t=>t.fill)),F.append("text").attr("x",0).attr("y",0).text((t=>t.text.text)).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>h(t.text.horizontalPos))).attr("text-anchor",(t=>c(t.text.verticalPos))).attr("transform",(t=>d(t.text)))}},styles:()=>""}}}]); \ No newline at end of file diff --git a/assets/js/7211.cad29de9.js b/assets/js/7211.cad29de9.js new file mode 100644 index 0000000000..f0d75d33a7 --- /dev/null +++ b/assets/js/7211.cad29de9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7211],{77211:(t,e,a)=>{a.d(e,{diagram:()=>at});var r=a(76257),s=a(26312),i=a(58886),n=a(16750),o=(a(74353),a(42838),function(){var t=function(t,e,a,r){for(a=a||{},r=t.length;r--;a[t[r]]=e);return a},e=[1,2],a=[1,3],r=[1,4],s=[2,4],i=[1,9],n=[1,11],o=[1,13],c=[1,14],l=[1,16],d=[1,17],h=[1,18],p=[1,24],g=[1,25],u=[1,26],x=[1,27],y=[1,28],m=[1,29],b=[1,30],f=[1,31],T=[1,32],E=[1,33],w=[1,34],P=[1,35],v=[1,36],_=[1,37],L=[1,38],k=[1,39],I=[1,41],M=[1,42],N=[1,43],A=[1,44],O=[1,45],S=[1,46],D=[1,4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,48,49,50,52,53,54,59,60,61,62,70],R=[4,5,16,50,52,53],C=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],$=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,49,50,52,53,54,59,60,61,62,70],Y=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,48,50,52,53,54,59,60,61,62,70],B=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,50,52,53,54,59,60,61,62,70],V=[68,69,70],F=[1,120],q={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,SD:6,document:7,line:8,statement:9,box_section:10,box_line:11,participant_statement:12,create:13,box:14,restOfLine:15,end:16,signal:17,autonumber:18,NUM:19,off:20,activate:21,actor:22,deactivate:23,note_statement:24,links_statement:25,link_statement:26,properties_statement:27,details_statement:28,title:29,legacy_title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,loop:36,rect:37,opt:38,alt:39,else_sections:40,par:41,par_sections:42,par_over:43,critical:44,option_sections:45,break:46,option:47,and:48,else:49,participant:50,AS:51,participant_actor:52,destroy:53,note:54,placement:55,text2:56,over:57,actor_pair:58,links:59,link:60,properties:61,details:62,spaceList:63,",":64,left_of:65,right_of:66,signaltype:67,"+":68,"-":69,ACTOR:70,SOLID_OPEN_ARROW:71,DOTTED_OPEN_ARROW:72,SOLID_ARROW:73,DOTTED_ARROW:74,SOLID_CROSS:75,DOTTED_CROSS:76,SOLID_POINT:77,DOTTED_POINT:78,TXT:79,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",6:"SD",13:"create",14:"box",15:"restOfLine",16:"end",18:"autonumber",19:"NUM",20:"off",21:"activate",23:"deactivate",29:"title",30:"legacy_title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"loop",37:"rect",38:"opt",39:"alt",41:"par",43:"par_over",44:"critical",46:"break",47:"option",48:"and",49:"else",50:"participant",51:"AS",52:"participant_actor",53:"destroy",54:"note",57:"over",59:"links",60:"link",61:"properties",62:"details",64:",",65:"left_of",66:"right_of",68:"+",69:"-",70:"ACTOR",71:"SOLID_OPEN_ARROW",72:"DOTTED_OPEN_ARROW",73:"SOLID_ARROW",74:"DOTTED_ARROW",75:"SOLID_CROSS",76:"DOTTED_CROSS",77:"SOLID_POINT",78:"DOTTED_POINT",79:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[10,0],[10,2],[11,2],[11,1],[11,1],[9,1],[9,2],[9,4],[9,2],[9,4],[9,3],[9,3],[9,2],[9,3],[9,3],[9,2],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[9,2],[9,2],[9,1],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[45,1],[45,4],[42,1],[42,4],[40,1],[40,4],[12,5],[12,3],[12,5],[12,3],[12,3],[24,4],[24,4],[25,3],[26,3],[27,3],[28,3],[63,2],[63,1],[58,3],[58,1],[55,1],[55,1],[17,5],[17,5],[17,4],[22,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[56,1]],performAction:function(t,e,a,r,s,i,n){var o=i.length-1;switch(s){case 3:return r.apply(i[o]),i[o];case 4:case 9:case 8:case 13:this.$=[];break;case 5:case 10:i[o-1].push(i[o]),this.$=i[o-1];break;case 6:case 7:case 11:case 12:case 62:this.$=i[o];break;case 15:i[o].type="createParticipant",this.$=i[o];break;case 16:i[o-1].unshift({type:"boxStart",boxData:r.parseBoxData(i[o-2])}),i[o-1].push({type:"boxEnd",boxText:i[o-2]}),this.$=i[o-1];break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(i[o-2]),sequenceIndexStep:Number(i[o-1]),sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(i[o-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:r.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:i[o-1]};break;case 23:this.$={type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:i[o-1]};break;case 29:r.setDiagramTitle(i[o].substring(6)),this.$=i[o].substring(6);break;case 30:r.setDiagramTitle(i[o].substring(7)),this.$=i[o].substring(7);break;case 31:this.$=i[o].trim(),r.setAccTitle(this.$);break;case 32:case 33:this.$=i[o].trim(),r.setAccDescription(this.$);break;case 34:i[o-1].unshift({type:"loopStart",loopText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.LOOP_START}),i[o-1].push({type:"loopEnd",loopText:i[o-2],signalType:r.LINETYPE.LOOP_END}),this.$=i[o-1];break;case 35:i[o-1].unshift({type:"rectStart",color:r.parseMessage(i[o-2]),signalType:r.LINETYPE.RECT_START}),i[o-1].push({type:"rectEnd",color:r.parseMessage(i[o-2]),signalType:r.LINETYPE.RECT_END}),this.$=i[o-1];break;case 36:i[o-1].unshift({type:"optStart",optText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.OPT_START}),i[o-1].push({type:"optEnd",optText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.OPT_END}),this.$=i[o-1];break;case 37:i[o-1].unshift({type:"altStart",altText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.ALT_START}),i[o-1].push({type:"altEnd",signalType:r.LINETYPE.ALT_END}),this.$=i[o-1];break;case 38:i[o-1].unshift({type:"parStart",parText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.PAR_START}),i[o-1].push({type:"parEnd",signalType:r.LINETYPE.PAR_END}),this.$=i[o-1];break;case 39:i[o-1].unshift({type:"parStart",parText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.PAR_OVER_START}),i[o-1].push({type:"parEnd",signalType:r.LINETYPE.PAR_END}),this.$=i[o-1];break;case 40:i[o-1].unshift({type:"criticalStart",criticalText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.CRITICAL_START}),i[o-1].push({type:"criticalEnd",signalType:r.LINETYPE.CRITICAL_END}),this.$=i[o-1];break;case 41:i[o-1].unshift({type:"breakStart",breakText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.BREAK_START}),i[o-1].push({type:"breakEnd",optText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.BREAK_END}),this.$=i[o-1];break;case 43:this.$=i[o-3].concat([{type:"option",optionText:r.parseMessage(i[o-1]),signalType:r.LINETYPE.CRITICAL_OPTION},i[o]]);break;case 45:this.$=i[o-3].concat([{type:"and",parText:r.parseMessage(i[o-1]),signalType:r.LINETYPE.PAR_AND},i[o]]);break;case 47:this.$=i[o-3].concat([{type:"else",altText:r.parseMessage(i[o-1]),signalType:r.LINETYPE.ALT_ELSE},i[o]]);break;case 48:i[o-3].draw="participant",i[o-3].type="addParticipant",i[o-3].description=r.parseMessage(i[o-1]),this.$=i[o-3];break;case 49:i[o-1].draw="participant",i[o-1].type="addParticipant",this.$=i[o-1];break;case 50:i[o-3].draw="actor",i[o-3].type="addParticipant",i[o-3].description=r.parseMessage(i[o-1]),this.$=i[o-3];break;case 51:i[o-1].draw="actor",i[o-1].type="addParticipant",this.$=i[o-1];break;case 52:i[o-1].type="destroyParticipant",this.$=i[o-1];break;case 53:this.$=[i[o-1],{type:"addNote",placement:i[o-2],actor:i[o-1].actor,text:i[o]}];break;case 54:i[o-2]=[].concat(i[o-1],i[o-1]).slice(0,2),i[o-2][0]=i[o-2][0].actor,i[o-2][1]=i[o-2][1].actor,this.$=[i[o-1],{type:"addNote",placement:r.PLACEMENT.OVER,actor:i[o-2].slice(0,2),text:i[o]}];break;case 55:this.$=[i[o-1],{type:"addLinks",actor:i[o-1].actor,text:i[o]}];break;case 56:this.$=[i[o-1],{type:"addALink",actor:i[o-1].actor,text:i[o]}];break;case 57:this.$=[i[o-1],{type:"addProperties",actor:i[o-1].actor,text:i[o]}];break;case 58:this.$=[i[o-1],{type:"addDetails",actor:i[o-1].actor,text:i[o]}];break;case 61:this.$=[i[o-2],i[o]];break;case 63:this.$=r.PLACEMENT.LEFTOF;break;case 64:this.$=r.PLACEMENT.RIGHTOF;break;case 65:this.$=[i[o-4],i[o-1],{type:"addMessage",from:i[o-4].actor,to:i[o-1].actor,signalType:i[o-3],msg:i[o],activate:!0},{type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:i[o-1]}];break;case 66:this.$=[i[o-4],i[o-1],{type:"addMessage",from:i[o-4].actor,to:i[o-1].actor,signalType:i[o-3],msg:i[o]},{type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:i[o-4]}];break;case 67:this.$=[i[o-3],i[o-1],{type:"addMessage",from:i[o-3].actor,to:i[o-1].actor,signalType:i[o-2],msg:i[o]}];break;case 68:this.$={type:"addParticipant",actor:i[o]};break;case 69:this.$=r.LINETYPE.SOLID_OPEN;break;case 70:this.$=r.LINETYPE.DOTTED_OPEN;break;case 71:this.$=r.LINETYPE.SOLID;break;case 72:this.$=r.LINETYPE.DOTTED;break;case 73:this.$=r.LINETYPE.SOLID_CROSS;break;case 74:this.$=r.LINETYPE.DOTTED_CROSS;break;case 75:this.$=r.LINETYPE.SOLID_POINT;break;case 76:this.$=r.LINETYPE.DOTTED_POINT;break;case 77:this.$=r.parseMessage(i[o].trim().substring(1))}},table:[{3:1,4:e,5:a,6:r},{1:[3]},{3:5,4:e,5:a,6:r},{3:6,4:e,5:a,6:r},t([1,4,5,13,14,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],s,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:i,5:n,8:8,9:10,12:12,13:o,14:c,17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},t(D,[2,5]),{9:47,12:12,13:o,14:c,17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},t(D,[2,7]),t(D,[2,8]),t(D,[2,14]),{12:48,50:_,52:L,53:k},{15:[1,49]},{5:[1,50]},{5:[1,53],19:[1,51],20:[1,52]},{22:54,70:S},{22:55,70:S},{5:[1,56]},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},t(D,[2,29]),t(D,[2,30]),{32:[1,61]},{34:[1,62]},t(D,[2,33]),{15:[1,63]},{15:[1,64]},{15:[1,65]},{15:[1,66]},{15:[1,67]},{15:[1,68]},{15:[1,69]},{15:[1,70]},{22:71,70:S},{22:72,70:S},{22:73,70:S},{67:74,71:[1,75],72:[1,76],73:[1,77],74:[1,78],75:[1,79],76:[1,80],77:[1,81],78:[1,82]},{55:83,57:[1,84],65:[1,85],66:[1,86]},{22:87,70:S},{22:88,70:S},{22:89,70:S},{22:90,70:S},t([5,51,64,71,72,73,74,75,76,77,78,79],[2,68]),t(D,[2,6]),t(D,[2,15]),t(R,[2,9],{10:91}),t(D,[2,17]),{5:[1,93],19:[1,92]},{5:[1,94]},t(D,[2,21]),{5:[1,95]},{5:[1,96]},t(D,[2,24]),t(D,[2,25]),t(D,[2,26]),t(D,[2,27]),t(D,[2,28]),t(D,[2,31]),t(D,[2,32]),t(C,s,{7:97}),t(C,s,{7:98}),t(C,s,{7:99}),t($,s,{40:100,7:101}),t(Y,s,{42:102,7:103}),t(Y,s,{7:103,42:104}),t(B,s,{45:105,7:106}),t(C,s,{7:107}),{5:[1,109],51:[1,108]},{5:[1,111],51:[1,110]},{5:[1,112]},{22:115,68:[1,113],69:[1,114],70:S},t(V,[2,69]),t(V,[2,70]),t(V,[2,71]),t(V,[2,72]),t(V,[2,73]),t(V,[2,74]),t(V,[2,75]),t(V,[2,76]),{22:116,70:S},{22:118,58:117,70:S},{70:[2,63]},{70:[2,64]},{56:119,79:F},{56:121,79:F},{56:122,79:F},{56:123,79:F},{4:[1,126],5:[1,128],11:125,12:127,16:[1,124],50:_,52:L,53:k},{5:[1,129]},t(D,[2,19]),t(D,[2,20]),t(D,[2,22]),t(D,[2,23]),{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[1,130],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[1,131],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[1,132],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{16:[1,133]},{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[2,46],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,49:[1,134],50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{16:[1,135]},{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[2,44],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,48:[1,136],50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{16:[1,137]},{16:[1,138]},{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[2,42],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,47:[1,139],50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{4:i,5:n,8:8,9:10,12:12,13:o,14:c,16:[1,140],17:15,18:l,21:d,22:40,23:h,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:b,38:f,39:T,41:E,43:w,44:P,46:v,50:_,52:L,53:k,54:I,59:M,60:N,61:A,62:O,70:S},{15:[1,141]},t(D,[2,49]),{15:[1,142]},t(D,[2,51]),t(D,[2,52]),{22:143,70:S},{22:144,70:S},{56:145,79:F},{56:146,79:F},{56:147,79:F},{64:[1,148],79:[2,62]},{5:[2,55]},{5:[2,77]},{5:[2,56]},{5:[2,57]},{5:[2,58]},t(D,[2,16]),t(R,[2,10]),{12:149,50:_,52:L,53:k},t(R,[2,12]),t(R,[2,13]),t(D,[2,18]),t(D,[2,34]),t(D,[2,35]),t(D,[2,36]),t(D,[2,37]),{15:[1,150]},t(D,[2,38]),{15:[1,151]},t(D,[2,39]),t(D,[2,40]),{15:[1,152]},t(D,[2,41]),{5:[1,153]},{5:[1,154]},{56:155,79:F},{56:156,79:F},{5:[2,67]},{5:[2,53]},{5:[2,54]},{22:157,70:S},t(R,[2,11]),t($,s,{7:101,40:158}),t(Y,s,{7:103,42:159}),t(B,s,{7:106,45:160}),t(D,[2,48]),t(D,[2,50]),{5:[2,65]},{5:[2,66]},{79:[2,61]},{16:[2,47]},{16:[2,45]},{16:[2,43]}],defaultActions:{5:[2,1],6:[2,2],85:[2,63],86:[2,64],119:[2,55],120:[2,77],121:[2,56],122:[2,57],123:[2,58],145:[2,67],146:[2,53],147:[2,54],155:[2,65],156:[2,66],157:[2,61],158:[2,47],159:[2,45],160:[2,43]},parseError:function(t,e){if(!e.recoverable){var a=new Error(t);throw a.hash=e,a}this.trace(t)},parse:function(t){var e=this,a=[0],r=[],s=[null],i=[],n=this.table,o="",c=0,l=0,d=i.slice.call(arguments,1),h=Object.create(this.lexer),p={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(p.yy[g]=this.yy[g]);h.setInput(t,p.yy),p.yy.lexer=h,p.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var u=h.yylloc;i.push(u);var x=h.options&&h.options.ranges;"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var y,m,b,f,T,E,w,P,v,_={};;){if(m=a[a.length-1],this.defaultActions[m]?b=this.defaultActions[m]:(null==y&&(v=void 0,"number"!=typeof(v=r.pop()||h.lex()||1)&&(v instanceof Array&&(v=(r=v).pop()),v=e.symbols_[v]||v),y=v),b=n[m]&&n[m][y]),void 0===b||!b.length||!b[0]){var L="";for(T in P=[],n[m])this.terminals_[T]&&T>2&&P.push("'"+this.terminals_[T]+"'");L=h.showPosition?"Parse error on line "+(c+1)+":\n"+h.showPosition()+"\nExpecting "+P.join(", ")+", got '"+(this.terminals_[y]||y)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==y?"end of input":"'"+(this.terminals_[y]||y)+"'"),this.parseError(L,{text:h.match,token:this.terminals_[y]||y,line:h.yylineno,loc:u,expected:P})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+y);switch(b[0]){case 1:a.push(y),s.push(h.yytext),i.push(h.yylloc),a.push(b[1]),y=null,l=h.yyleng,o=h.yytext,c=h.yylineno,u=h.yylloc;break;case 2:if(E=this.productions_[b[1]][1],_.$=s[s.length-E],_._$={first_line:i[i.length-(E||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(E||1)].first_column,last_column:i[i.length-1].last_column},x&&(_._$.range=[i[i.length-(E||1)].range[0],i[i.length-1].range[1]]),void 0!==(f=this.performAction.apply(_,[o,l,c,p.yy,b[1],s,i].concat(d))))return f;E&&(a=a.slice(0,-1*E*2),s=s.slice(0,-1*E),i=i.slice(0,-1*E)),a.push(this.productions_[b[1]][0]),s.push(_.$),i.push(_._$),w=n[a[a.length-2]][a[a.length-1]],a.push(w);break;case 3:return!0}}return!0}},W={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,a=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),a.length-1&&(this.yylineno-=a.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:a?(a.length===r.length?this.yylloc.first_column:0)+r[r.length-a.length].length-a[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var a,r,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],a=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a)return a;if(this._backtrack){for(var i in s)this[i]=s[i];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,a,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),i=0;i<s.length;i++)if((a=this._input.match(this.rules[s[i]]))&&(!e||a[0].length>e[0].length)){if(e=a,r=i,this.options.backtrack_lexer){if(!1!==(t=this.test_match(a,s[i])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,a,r){switch(a){case 0:case 51:case 64:return 5;case 1:case 2:case 3:case 4:case 5:break;case 6:return 19;case 7:return this.begin("LINE"),14;case 8:return this.begin("ID"),50;case 9:return this.begin("ID"),52;case 10:return 13;case 11:return this.begin("ID"),53;case 12:return e.yytext=e.yytext.trim(),this.begin("ALIAS"),70;case 13:return this.popState(),this.popState(),this.begin("LINE"),51;case 14:return this.popState(),this.popState(),5;case 15:return this.begin("LINE"),36;case 16:return this.begin("LINE"),37;case 17:return this.begin("LINE"),38;case 18:return this.begin("LINE"),39;case 19:return this.begin("LINE"),49;case 20:return this.begin("LINE"),41;case 21:return this.begin("LINE"),43;case 22:return this.begin("LINE"),48;case 23:return this.begin("LINE"),44;case 24:return this.begin("LINE"),47;case 25:return this.begin("LINE"),46;case 26:return this.popState(),15;case 27:return 16;case 28:return 65;case 29:return 66;case 30:return 59;case 31:return 60;case 32:return 61;case 33:return 62;case 34:return 57;case 35:return 54;case 36:return this.begin("ID"),21;case 37:return this.begin("ID"),23;case 38:return 29;case 39:return 30;case 40:return this.begin("acc_title"),31;case 41:return this.popState(),"acc_title_value";case 42:return this.begin("acc_descr"),33;case 43:return this.popState(),"acc_descr_value";case 44:this.begin("acc_descr_multiline");break;case 45:this.popState();break;case 46:return"acc_descr_multiline_value";case 47:return 6;case 48:return 18;case 49:return 20;case 50:return 64;case 52:return e.yytext=e.yytext.trim(),70;case 53:return 73;case 54:return 74;case 55:return 71;case 56:return 72;case 57:return 75;case 58:return 76;case 59:return 77;case 60:return 78;case 61:return 79;case 62:return 68;case 63:return 69;case 65:return"INVALID"}},rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:box\b)/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:create\b)/i,/^(?:destroy\b)/i,/^(?:[^\->:\n,;]+?([\-]*[^\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:par_over\b)/i,/^(?:and\b)/i,/^(?:critical\b)/i,/^(?:option\b)/i,/^(?:break\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[45,46],inclusive:!1},acc_descr:{rules:[43],inclusive:!1},acc_title:{rules:[41],inclusive:!1},ID:{rules:[2,3,12],inclusive:!1},ALIAS:{rules:[2,3,13,14],inclusive:!1},LINE:{rules:[2,3,26],inclusive:!1},INITIAL:{rules:[0,1,3,4,5,6,7,8,9,10,11,15,16,17,18,19,20,21,22,23,24,25,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,44,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65],inclusive:!0}}};function z(){this.yy={}}return q.lexer=W,z.prototype=q,q.Parser=z,new z}());o.parser=o;const c=o;const l=new class{constructor(t){this.init=t,this.records=this.init()}reset(){this.records=this.init()}}((()=>({prevActor:void 0,actors:{},createdActors:{},destroyedActors:{},boxes:[],messages:[],notes:[],sequenceNumbersEnabled:!1,wrapEnabled:void 0,currentBox:void 0,lastCreated:void 0,lastDestroyed:void 0}))),d=function(t,e,a,r){let s=l.records.currentBox;const i=l.records.actors[t];if(i){if(l.records.currentBox&&i.box&&l.records.currentBox!==i.box)throw new Error("A same participant should only be defined in one Box: "+i.name+" can't be in '"+i.box.name+"' and in '"+l.records.currentBox.name+"' at the same time.");if(s=i.box?i.box:l.records.currentBox,i.box=s,i&&e===i.name&&null==a)return}null!=a&&null!=a.text||(a={text:e,wrap:null,type:r}),null!=r&&null!=a.text||(a={text:e,wrap:null,type:r}),l.records.actors[t]={box:s,name:e,description:a.text,wrap:void 0===a.wrap&&g()||!!a.wrap,prevActor:l.records.prevActor,links:{},properties:{},actorCnt:null,rectData:null,type:r||"participant"},l.records.prevActor&&l.records.actors[l.records.prevActor]&&(l.records.actors[l.records.prevActor].nextActor=t),l.records.currentBox&&l.records.currentBox.actorKeys.push(t),l.records.prevActor=t},h=function(t,e,a={text:void 0,wrap:void 0},r,s=!1){if(r===u.ACTIVE_END){if((t=>{let e,a=0;for(e=0;e<l.records.messages.length;e++)l.records.messages[e].type===u.ACTIVE_START&&l.records.messages[e].from.actor===t&&a++,l.records.messages[e].type===u.ACTIVE_END&&l.records.messages[e].from.actor===t&&a--;return a})(t.actor)<1){let e=new Error("Trying to inactivate an inactive participant ("+t.actor+")");throw e.hash={text:"->>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},e}}return l.records.messages.push({from:t,to:e,message:a.text,wrap:void 0===a.wrap&&g()||!!a.wrap,type:r,activate:s}),!0},p=function(t){return l.records.actors[t]},g=()=>void 0!==l.records.wrapEnabled?l.records.wrapEnabled:(0,r.c)().sequence.wrap,u={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25,AUTONUMBER:26,CRITICAL_START:27,CRITICAL_OPTION:28,CRITICAL_END:29,BREAK_START:30,BREAK_END:31,PAR_OVER_START:32},x=function(t,e,a){const r={actor:t,placement:e,message:a.text,wrap:void 0===a.wrap&&g()||!!a.wrap},s=[].concat(t,t);l.records.notes.push(r),l.records.messages.push({from:s[0],to:s[1],message:a.text,wrap:void 0===a.wrap&&g()||!!a.wrap,type:u.NOTE,placement:e})},y=function(t,e){const a=p(t);try{let t=(0,r.d)(e.text,(0,r.c)());t=t.replace(/&/g,"&"),t=t.replace(/=/g,"=");m(a,JSON.parse(t))}catch(s){r.l.error("error while parsing actor link text",s)}};function m(t,e){if(null==t.links)t.links=e;else for(let a in e)t.links[a]=e[a]}const b=function(t,e){const a=p(t);try{let t=(0,r.d)(e.text,(0,r.c)());f(a,JSON.parse(t))}catch(s){r.l.error("error while parsing actor properties text",s)}};function f(t,e){if(null==t.properties)t.properties=e;else for(let a in e)t.properties[a]=e[a]}const T=function(t,e){const a=p(t),s=document.getElementById(e.text);try{const t=s.innerHTML,e=JSON.parse(t);e.properties&&f(a,e.properties),e.links&&m(a,e.links)}catch(i){r.l.error("error while parsing actor details text",i)}},E=function(t){if(Array.isArray(t))t.forEach((function(t){E(t)}));else switch(t.type){case"sequenceIndex":l.records.messages.push({from:void 0,to:void 0,message:{start:t.sequenceIndex,step:t.sequenceIndexStep,visible:t.sequenceVisible},wrap:!1,type:t.signalType});break;case"addParticipant":d(t.actor,t.actor,t.description,t.draw);break;case"createParticipant":if(l.records.actors[t.actor])throw new Error("It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior");l.records.lastCreated=t.actor,d(t.actor,t.actor,t.description,t.draw),l.records.createdActors[t.actor]=l.records.messages.length;break;case"destroyParticipant":l.records.lastDestroyed=t.actor,l.records.destroyedActors[t.actor]=l.records.messages.length;break;case"activeStart":case"activeEnd":h(t.actor,void 0,void 0,t.signalType);break;case"addNote":x(t.actor,t.placement,t.text);break;case"addLinks":y(t.actor,t.text);break;case"addALink":!function(t,e){const a=p(t);try{const t={};let o=(0,r.d)(e.text,(0,r.c)());var s=o.indexOf("@");o=o.replace(/&/g,"&"),o=o.replace(/=/g,"=");var i=o.slice(0,s-1).trim(),n=o.slice(s+1).trim();t[i]=n,m(a,t)}catch(o){r.l.error("error while parsing actor link text",o)}}(t.actor,t.text);break;case"addProperties":b(t.actor,t.text);break;case"addDetails":T(t.actor,t.text);break;case"addMessage":if(l.records.lastCreated){if(t.to!==l.records.lastCreated)throw new Error("The created participant "+l.records.lastCreated+" does not have an associated creating message after its declaration. Please check the sequence diagram.");l.records.lastCreated=void 0}else if(l.records.lastDestroyed){if(t.to!==l.records.lastDestroyed&&t.from!==l.records.lastDestroyed)throw new Error("The destroyed participant "+l.records.lastDestroyed+" does not have an associated destroying message after its declaration. Please check the sequence diagram.");l.records.lastDestroyed=void 0}h(t.from,t.to,t.msg,t.signalType,t.activate);break;case"boxStart":e=t.boxData,l.records.boxes.push({name:e.text,wrap:void 0===e.wrap&&g()||!!e.wrap,fill:e.color,actorKeys:[]}),l.records.currentBox=l.records.boxes.slice(-1)[0];break;case"boxEnd":l.records.currentBox=void 0;break;case"loopStart":h(void 0,void 0,t.loopText,t.signalType);break;case"loopEnd":case"rectEnd":case"optEnd":case"altEnd":case"parEnd":case"criticalEnd":case"breakEnd":h(void 0,void 0,void 0,t.signalType);break;case"rectStart":h(void 0,void 0,t.color,t.signalType);break;case"optStart":h(void 0,void 0,t.optText,t.signalType);break;case"altStart":case"else":h(void 0,void 0,t.altText,t.signalType);break;case"setAccTitle":(0,r.s)(t.text);break;case"parStart":case"and":h(void 0,void 0,t.parText,t.signalType);break;case"criticalStart":h(void 0,void 0,t.criticalText,t.signalType);break;case"option":h(void 0,void 0,t.optionText,t.signalType);break;case"breakStart":h(void 0,void 0,t.breakText,t.signalType)}var e},w={addActor:d,addMessage:function(t,e,a,r){l.records.messages.push({from:t,to:e,message:a.text,wrap:void 0===a.wrap&&g()||!!a.wrap,answer:r})},addSignal:h,addLinks:y,addDetails:T,addProperties:b,autoWrap:g,setWrap:function(t){l.records.wrapEnabled=t},enableSequenceNumbers:function(){l.records.sequenceNumbersEnabled=!0},disableSequenceNumbers:function(){l.records.sequenceNumbersEnabled=!1},showSequenceNumbers:()=>l.records.sequenceNumbersEnabled,getMessages:function(){return l.records.messages},getActors:function(){return l.records.actors},getCreatedActors:function(){return l.records.createdActors},getDestroyedActors:function(){return l.records.destroyedActors},getActor:p,getActorKeys:function(){return Object.keys(l.records.actors)},getActorProperty:function(t,e){if(void 0!==t&&void 0!==t.properties)return t.properties[e]},getAccTitle:r.g,getBoxes:function(){return l.records.boxes},getDiagramTitle:r.t,setDiagramTitle:r.q,getConfig:()=>(0,r.c)().sequence,clear:function(){l.reset(),(0,r.v)()},parseMessage:function(t){const e=t.trim(),a={text:e.replace(/^:?(?:no)?wrap:/,"").trim(),wrap:null!==e.match(/^:?wrap:/)||null===e.match(/^:?nowrap:/)&&void 0};return r.l.debug("parseMessage:",a),a},parseBoxData:function(t){const e=t.match(/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/);let a=null!=e&&e[1]?e[1].trim():"transparent",s=null!=e&&e[2]?e[2].trim():void 0;if(window&&window.CSS)window.CSS.supports("color",a)||(a="transparent",s=t.trim());else{const e=(new Option).style;e.color=a,e.color!==a&&(a="transparent",s=t.trim())}return{color:a,text:void 0!==s?(0,r.d)(s.replace(/^:?(?:no)?wrap:/,""),(0,r.c)()):void 0,wrap:void 0!==s?null!==s.match(/^:?wrap:/)||null===s.match(/^:?nowrap:/)&&void 0:void 0}},LINETYPE:u,ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},addNote:x,setAccTitle:r.s,apply:E,setAccDescription:r.b,getAccDescription:r.a,hasAtLeastOneBox:function(){return l.records.boxes.length>0},hasAtLeastOneBoxWithTitle:function(){return l.records.boxes.some((t=>t.name))}},P=t=>`.actor {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n\n text.actor > tspan {\n fill: ${t.actorTextColor};\n stroke: none;\n }\n\n .actor-line {\n stroke: ${t.actorLineColor};\n }\n\n .messageLine0 {\n stroke-width: 1.5;\n stroke-dasharray: none;\n stroke: ${t.signalColor};\n }\n\n .messageLine1 {\n stroke-width: 1.5;\n stroke-dasharray: 2, 2;\n stroke: ${t.signalColor};\n }\n\n #arrowhead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .sequenceNumber {\n fill: ${t.sequenceNumberColor};\n }\n\n #sequencenumber {\n fill: ${t.signalColor};\n }\n\n #crosshead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .messageText {\n fill: ${t.signalTextColor};\n stroke: none;\n }\n\n .labelBox {\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBkgColor};\n }\n\n .labelText, .labelText > tspan {\n fill: ${t.labelTextColor};\n stroke: none;\n }\n\n .loopText, .loopText > tspan {\n fill: ${t.loopTextColor};\n stroke: none;\n }\n\n .loopLine {\n stroke-width: 2px;\n stroke-dasharray: 2, 2;\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBorderColor};\n }\n\n .note {\n //stroke: #decc93;\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n }\n\n .noteText, .noteText > tspan {\n fill: ${t.noteTextColor};\n stroke: none;\n }\n\n .activation0 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation1 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation2 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .actorPopupMenu {\n position: absolute;\n }\n\n .actorPopupMenuPanel {\n position: absolute;\n fill: ${t.actorBkg};\n box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);\n filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));\n}\n .actor-man line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n .actor-man circle, line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n stroke-width: 2px;\n }\n`,v="actor-top",_="actor-bottom",L=function(t,e){return(0,i.d)(t,e)},k=async function(t,e,a=null){let s=t.append("foreignObject");const i=await(0,r.r)(e.text,(0,r.F)()),n=s.append("xhtml:div").attr("style","width: fit-content;").attr("xmlns","http://www.w3.org/1999/xhtml").html(i).node().getBoundingClientRect();if(s.attr("height",Math.round(n.height)).attr("width",Math.round(n.width)),"noteText"===e.class){const a=t.node().firstChild;a.setAttribute("height",n.height+2*e.textMargin);const r=a.getBBox();s.attr("x",Math.round(r.x+r.width/2-n.width/2)).attr("y",Math.round(r.y+r.height/2-n.height/2))}else if(a){let{startx:t,stopx:r,starty:i}=a;if(t>r){const e=t;t=r,r=e}s.attr("x",Math.round(t+Math.abs(t-r)/2-n.width/2)),"loopText"===e.class?s.attr("y",Math.round(i)):s.attr("y",Math.round(i-n.height))}return[s]},I=function(t,e){let a=0,s=0;const i=e.text.split(r.e.lineBreakRegex),[n,o]=(0,r.D)(e.fontSize);let c=[],l=0,d=()=>e.y;if(void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0)switch(e.valign){case"top":case"start":d=()=>Math.round(e.y+e.textMargin);break;case"middle":case"center":d=()=>Math.round(e.y+(a+s+e.textMargin)/2);break;case"bottom":case"end":d=()=>Math.round(e.y+(a+s+2*e.textMargin)-e.textMargin)}if(void 0!==e.anchor&&void 0!==e.textMargin&&void 0!==e.width)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="middle",e.alignmentBaseline="middle"}for(let[h,p]of i.entries()){void 0!==e.textMargin&&0===e.textMargin&&void 0!==n&&(l=h*n);const i=t.append("text");i.attr("x",e.x),i.attr("y",d()),void 0!==e.anchor&&i.attr("text-anchor",e.anchor).attr("dominant-baseline",e.dominantBaseline).attr("alignment-baseline",e.alignmentBaseline),void 0!==e.fontFamily&&i.style("font-family",e.fontFamily),void 0!==o&&i.style("font-size",o),void 0!==e.fontWeight&&i.style("font-weight",e.fontWeight),void 0!==e.fill&&i.attr("fill",e.fill),void 0!==e.class&&i.attr("class",e.class),void 0!==e.dy?i.attr("dy",e.dy):0!==l&&i.attr("dy",l);const g=p||r.Z;if(e.tspan){const t=i.append("tspan");t.attr("x",e.x),void 0!==e.fill&&t.attr("fill",e.fill),t.text(g)}else i.text(g);void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0&&(s+=(i._groups||i)[0][0].getBBox().height,a=s),c.push(i)}return c},M=function(t,e){const a=t.append("polygon");var r,s,i,n,o;return a.attr("points",(r=e.x,s=e.y,i=e.width,n=e.height,r+","+s+" "+(r+i)+","+s+" "+(r+i)+","+(s+n-(o=7))+" "+(r+i-1.2*o)+","+(s+n)+" "+r+","+(s+n))),a.attr("class","labelBox"),e.y=e.y+e.height/2,I(t,e),a};let N=-1;const A=(t,e,a,r)=>{t.select&&a.forEach((a=>{const s=e[a],i=t.select("#actor"+s.actorCnt);!r.mirrorActors&&s.stopy?i.attr("y2",s.stopy+s.height/2):r.mirrorActors&&i.attr("y2",s.stopy)}))},O=function(t,e){(0,i.a)(t,e)},S=function(){return{x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}},D=function(){function t(t,e,a,r,s,n,o){i(e.append("text").attr("x",a+s/2).attr("y",r+n/2+5).style("text-anchor","middle").text(t),o)}function e(t,e,a,s,n,o,c,l){const{actorFontSize:d,actorFontFamily:h,actorFontWeight:p}=l,[g,u]=(0,r.D)(d),x=t.split(r.e.lineBreakRegex);for(let r=0;r<x.length;r++){const t=r*g-g*(x.length-1)/2,l=e.append("text").attr("x",a+n/2).attr("y",s).style("text-anchor","middle").style("font-size",u).style("font-weight",p).style("font-family",h);l.append("tspan").attr("x",a+n/2).attr("dy",t).text(x[r]),l.attr("y",s+o/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(l,c)}}function a(t,a,r,s,n,o,c,l){const d=a.append("switch"),h=d.append("foreignObject").attr("x",r).attr("y",s).attr("width",n).attr("height",o).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");h.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,d,r,s,n,o,c,l),i(h,c)}async function s(t,a,s,n,o,c,l,d){const h=await(0,r.H)(t,(0,r.F)()),p=a.append("switch"),g=p.append("foreignObject").attr("x",s+o/2-h.width/2).attr("y",n+c/2-h.height/2).attr("width",h.width).attr("height",h.height).append("xhtml:div").style("height","100%").style("width","100%");g.append("div").style("text-align","center").style("vertical-align","middle").html(await(0,r.r)(t,(0,r.F)())),e(t,p,s,n,o,c,l,d),i(g,l)}function i(t,e){for(const a in e)e.hasOwnProperty(a)&&t.attr(a,e[a])}return function(r,i=!1){return i?s:"fo"===r.textPlacement?a:"old"===r.textPlacement?t:e}}(),R=function(){function t(t,e,a,r,i,n,o){s(e.append("text").attr("x",a).attr("y",r).style("text-anchor","start").text(t),o)}function e(t,e,a,i,n,o,c,l){const{actorFontSize:d,actorFontFamily:h,actorFontWeight:p}=l,g=t.split(r.e.lineBreakRegex);for(let r=0;r<g.length;r++){const t=r*d-d*(g.length-1)/2,n=e.append("text").attr("x",a).attr("y",i).style("text-anchor","start").style("font-size",d).style("font-weight",p).style("font-family",h);n.append("tspan").attr("x",a).attr("dy",t).text(g[r]),n.attr("y",i+o/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),s(n,c)}}function a(t,a,r,i,n,o,c,l){const d=a.append("switch"),h=d.append("foreignObject").attr("x",r).attr("y",i).attr("width",n).attr("height",o).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");h.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,d,r,i,0,o,c,l),s(h,c)}function s(t,e){for(const a in e)e.hasOwnProperty(a)&&t.attr(a,e[a])}return function(r){return"fo"===r.textPlacement?a:"old"===r.textPlacement?t:e}}(),C={drawRect:L,drawText:I,drawLabel:M,drawActor:async function(t,e,a,s){switch(e.type){case"actor":return await async function(t,e,a,s){const n=s?e.stopy:e.starty,o=e.x+e.width/2,c=n+80;t.lower(),s||(N++,t.append("line").attr("id","actor"+N).attr("x1",o).attr("y1",c).attr("x2",o).attr("y2",2e3).attr("class","actor-line").attr("class","200").attr("stroke-width","0.5px").attr("stroke","#999"),e.actorCnt=N);const l=t.append("g");let d="actor-man";d+=s?` ${_}`:` ${v}`,l.attr("class",d),l.attr("name",e.name);const h=(0,i.g)();h.x=e.x,h.y=n,h.fill="#eaeaea",h.width=e.width,h.height=e.height,h.class="actor",h.rx=3,h.ry=3,l.append("line").attr("id","actor-man-torso"+N).attr("x1",o).attr("y1",n+25).attr("x2",o).attr("y2",n+45),l.append("line").attr("id","actor-man-arms"+N).attr("x1",o-18).attr("y1",n+33).attr("x2",o+18).attr("y2",n+33),l.append("line").attr("x1",o-18).attr("y1",n+60).attr("x2",o).attr("y2",n+45),l.append("line").attr("x1",o).attr("y1",n+45).attr("x2",o+18-2).attr("y2",n+60);const p=l.append("circle");p.attr("cx",e.x+e.width/2),p.attr("cy",n+10),p.attr("r",15),p.attr("width",e.width),p.attr("height",e.height);const g=l.node().getBBox();return e.height=g.height,await D(a,(0,r.G)(e.description))(e.description,l,h.x,h.y+35,h.width,h.height,{class:"actor"},a),e.height}(t,e,a,s);case"participant":return await async function(t,e,a,s){const n=s?e.stopy:e.starty,o=e.x+e.width/2,c=n+5,l=t.append("g").lower();var d,h=l;s||(N++,Object.keys(e.links||{}).length&&!a.forceMenus&&h.attr("onclick",(d=`actor${N}_popup`,"var pu = document.getElementById('"+d+"'); if (pu != null) { pu.style.display = pu.style.display == 'block' ? 'none' : 'block'; }")).attr("cursor","pointer"),h.append("line").attr("id","actor"+N).attr("x1",o).attr("y1",c).attr("x2",o).attr("y2",2e3).attr("class","actor-line").attr("class","200").attr("stroke-width","0.5px").attr("stroke","#999"),h=l.append("g"),e.actorCnt=N,null!=e.links&&h.attr("id","root-"+N));const p=(0,i.g)();var g="actor";null!=e.properties&&e.properties.class?g=e.properties.class:p.fill="#eaeaea",g+=s?` ${_}`:` ${v}`,p.x=e.x,p.y=n,p.width=e.width,p.height=e.height,p.class=g,p.rx=3,p.ry=3,p.name=e.name;const u=L(h,p);if(e.rectData=p,null!=e.properties&&e.properties.icon){const t=e.properties.icon.trim();"@"===t.charAt(0)?(0,i.b)(h,p.x+p.width-20,p.y+10,t.substr(1)):(0,i.c)(h,p.x+p.width-20,p.y+10,t)}await D(a,(0,r.G)(e.description))(e.description,h,p.x,p.y,p.width,p.height,{class:"actor"},a);let x=e.height;if(u.node){const t=u.node().getBBox();e.height=t.height,x=t.height}return x}(t,e,a,s)}},drawBox:async function(t,e,a){const r=t.append("g");O(r,e),e.name&&await D(a)(e.name,r,e.x,e.y+(e.textMaxHeight||0)/2,e.width,0,{class:"text"},a),r.lower()},drawPopup:function(t,e,a,r,s){if(void 0===e.links||null===e.links||0===Object.keys(e.links).length)return{height:0,width:0};const i=e.links,o=e.actorCnt,c=e.rectData;var l="none";s&&(l="block !important");const d=t.append("g");d.attr("id","actor"+o+"_popup"),d.attr("class","actorPopupMenu"),d.attr("display",l);var h="";void 0!==c.class&&(h=" "+c.class);let p=c.width>a?c.width:a;const g=d.append("rect");if(g.attr("class","actorPopupMenuPanel"+h),g.attr("x",c.x),g.attr("y",c.height),g.attr("fill",c.fill),g.attr("stroke",c.stroke),g.attr("width",p),g.attr("height",c.height),g.attr("rx",c.rx),g.attr("ry",c.ry),null!=i){var u=20;for(let t in i){var x=d.append("a"),y=(0,n.Jf)(i[t]);x.attr("xlink:href",y),x.attr("target","_blank"),R(r)(t,x,c.x+10,c.height+u,p,20,{class:"actor"},r),u+=30}}return g.attr("height",u),{height:c.height+u,width:p}},anchorElement:function(t){return t.append("g")},drawActivation:function(t,e,a,r,s){const n=(0,i.g)(),o=e.anchored;n.x=e.startx,n.y=e.starty,n.class="activation"+s%3,n.width=e.stopx-e.startx,n.height=a-e.starty,L(o,n)},drawLoop:async function(t,e,a,s){const{boxMargin:n,boxTextMargin:o,labelBoxHeight:c,labelBoxWidth:l,messageFontFamily:d,messageFontSize:h,messageFontWeight:p}=s,g=t.append("g"),u=function(t,e,a,r){return g.append("line").attr("x1",t).attr("y1",e).attr("x2",a).attr("y2",r).attr("class","loopLine")};u(e.startx,e.starty,e.stopx,e.starty),u(e.stopx,e.starty,e.stopx,e.stopy),u(e.startx,e.stopy,e.stopx,e.stopy),u(e.startx,e.starty,e.startx,e.stopy),void 0!==e.sections&&e.sections.forEach((function(t){u(e.startx,t.y,e.stopx,t.y).style("stroke-dasharray","3, 3")}));let x=(0,i.e)();x.text=a,x.x=e.startx,x.y=e.starty,x.fontFamily=d,x.fontSize=h,x.fontWeight=p,x.anchor="middle",x.valign="middle",x.tspan=!1,x.width=l||50,x.height=c||20,x.textMargin=o,x.class="labelText",M(g,x),x=S(),x.text=e.title,x.x=e.startx+l/2+(e.stopx-e.startx)/2,x.y=e.starty+n+o,x.anchor="middle",x.valign="middle",x.textMargin=o,x.class="loopText",x.fontFamily=d,x.fontSize=h,x.fontWeight=p,x.wrap=!0;let y=(0,r.G)(x.text)?await k(g,x,e):I(g,x);if(void 0!==e.sectionTitles)for(const[i,m]of Object.entries(e.sectionTitles))if(m.message){x.text=m.message,x.x=e.startx+(e.stopx-e.startx)/2,x.y=e.sections[i].y+n+o,x.class="loopText",x.anchor="middle",x.valign="middle",x.tspan=!1,x.fontFamily=d,x.fontSize=h,x.fontWeight=p,x.wrap=e.wrap,(0,r.G)(x.text)?(e.starty=e.sections[i].y,await k(g,x,e)):I(g,x);let t=Math.round(y.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));e.sections[i].height+=t-(n+o)}return e.height=Math.round(e.stopy-e.starty),g},drawBackgroundRect:O,insertArrowHead:function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",7.9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},insertArrowFilledHead:function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",15.5).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},insertSequenceNumber:function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},insertArrowCrossHead:function(t){t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",4).attr("refY",4.5).append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1pt").attr("d","M 1,2 L 6,7 M 6,2 L 1,7")},insertDatabaseIcon:function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},insertComputerIcon:function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},insertClockIcon:function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},getTextObj:S,getNoteRect:function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},fixLifeLineHeights:A,sanitizeUrl:n.Jf};let $={};const Y={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:function(){return Math.max.apply(null,0===this.actors.length?[0]:this.actors.map((t=>t.height||0)))+(0===this.loops.length?0:this.loops.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.messages.length?0:this.messages.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.notes.length?0:this.notes.map((t=>t.height||0)).reduce(((t,e)=>t+e)))},clear:function(){this.actors=[],this.boxes=[],this.loops=[],this.messages=[],this.notes=[]},addBox:function(t){this.boxes.push(t)},addActor:function(t){this.actors.push(t)},addLoop:function(t){this.loops.push(t)},addMessage:function(t){this.messages.push(t)},addNote:function(t){this.notes.push(t)},lastActor:function(){return this.actors[this.actors.length-1]},lastLoop:function(){return this.loops[this.loops.length-1]},lastMessage:function(){return this.messages[this.messages.length-1]},lastNote:function(){return this.notes[this.notes.length-1]},actors:[],boxes:[],loops:[],messages:[],notes:[]},init:function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,j((0,r.c)())},updateVal:function(t,e,a,r){void 0===t[e]?t[e]=a:t[e]=r(a,t[e])},updateBounds:function(t,e,a,r){const s=this;let i=0;function n(n){return function(o){i++;const c=s.sequenceItems.length-i+1;s.updateVal(o,"starty",e-c*$.boxMargin,Math.min),s.updateVal(o,"stopy",r+c*$.boxMargin,Math.max),s.updateVal(Y.data,"startx",t-c*$.boxMargin,Math.min),s.updateVal(Y.data,"stopx",a+c*$.boxMargin,Math.max),"activation"!==n&&(s.updateVal(o,"startx",t-c*$.boxMargin,Math.min),s.updateVal(o,"stopx",a+c*$.boxMargin,Math.max),s.updateVal(Y.data,"starty",e-c*$.boxMargin,Math.min),s.updateVal(Y.data,"stopy",r+c*$.boxMargin,Math.max))}}this.sequenceItems.forEach(n()),this.activations.forEach(n("activation"))},insert:function(t,e,a,s){const i=r.e.getMin(t,a),n=r.e.getMax(t,a),o=r.e.getMin(e,s),c=r.e.getMax(e,s);this.updateVal(Y.data,"startx",i,Math.min),this.updateVal(Y.data,"starty",o,Math.min),this.updateVal(Y.data,"stopx",n,Math.max),this.updateVal(Y.data,"stopy",c,Math.max),this.updateBounds(i,o,n,c)},newActivation:function(t,e,a){const r=a[t.from.actor],s=G(t.from.actor).length||0,i=r.x+r.width/2+(s-1)*$.activationWidth/2;this.activations.push({startx:i,starty:this.verticalPos+2,stopx:i+$.activationWidth,stopy:void 0,actor:t.from.actor,anchored:C.anchorElement(e)})},endActivation:function(t){const e=this.activations.map((function(t){return t.actor})).lastIndexOf(t.from.actor);return this.activations.splice(e,1)[0]},createLoop:function(t={message:void 0,wrap:!1,width:void 0},e){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}},newLoop:function(t={message:void 0,wrap:!1,width:void 0},e){this.sequenceItems.push(this.createLoop(t,e))},endLoop:function(){return this.sequenceItems.pop()},isLoopOverlap:function(){return!!this.sequenceItems.length&&this.sequenceItems[this.sequenceItems.length-1].overlap},addSectionToLoop:function(t){const e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:Y.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)},saveVerticalPos:function(){this.isLoopOverlap()&&(this.savedVerticalPos=this.verticalPos)},resetVerticalPos:function(){this.isLoopOverlap()&&(this.verticalPos=this.savedVerticalPos)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=r.e.getMax(this.data.stopy,this.verticalPos)},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return{bounds:this.data,models:this.models}}},B=async function(t,e){Y.bumpVerticalPos($.boxMargin),e.height=$.boxMargin,e.starty=Y.getVerticalPos();const a=(0,i.g)();a.x=e.startx,a.y=e.starty,a.width=e.width||$.width,a.class="note";const s=t.append("g"),n=C.drawRect(s,a),o=(0,i.e)();o.x=e.startx,o.y=e.starty,o.width=a.width,o.dy="1em",o.text=e.message,o.class="noteText",o.fontFamily=$.noteFontFamily,o.fontSize=$.noteFontSize,o.fontWeight=$.noteFontWeight,o.anchor=$.noteAlign,o.textMargin=$.noteMargin,o.valign="center";const c=(0,r.G)(o.text)?await k(s,o):I(s,o),l=Math.round(c.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));n.attr("height",l+2*$.noteMargin),e.height+=l+2*$.noteMargin,Y.bumpVerticalPos(l+2*$.noteMargin),e.stopy=e.starty+l+2*$.noteMargin,e.stopx=e.startx+a.width,Y.insert(e.startx,e.starty,e.stopx,e.stopy),Y.models.addNote(e)},V=t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),F=t=>({fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight}),q=t=>({fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight});async function W(t,e){Y.bumpVerticalPos(10);const{startx:a,stopx:s,message:i}=e,n=r.e.splitBreaks(i).length,o=(0,r.G)(i),c=o?await(0,r.H)(i,(0,r.c)()):r.u.calculateTextDimensions(i,V($));if(!o){const t=c.height/n;e.height+=t,Y.bumpVerticalPos(t)}let l,d=c.height-10;const h=c.width;if(a===s){l=Y.getVerticalPos()+d,$.rightAngles||(d+=$.boxMargin,l=Y.getVerticalPos()+d),d+=30;const t=r.e.getMax(h/2,$.width/2);Y.insert(a-t,Y.getVerticalPos()-10+d,s+t,Y.getVerticalPos()+30+d)}else d+=$.boxMargin,l=Y.getVerticalPos()+d,Y.insert(a,l-10,s,l);return Y.bumpVerticalPos(d),e.height+=d,e.stopy=e.starty+e.height,Y.insert(e.fromBounds,e.starty,e.toBounds,e.stopy),l}const z=async function(t,e,a,s){const{startx:n,stopx:o,starty:c,message:l,type:d,sequenceIndex:h,sequenceVisible:p}=e,g=r.u.calculateTextDimensions(l,V($)),u=(0,i.e)();u.x=n,u.y=c+10,u.width=o-n,u.class="messageText",u.dy="1em",u.text=l,u.fontFamily=$.messageFontFamily,u.fontSize=$.messageFontSize,u.fontWeight=$.messageFontWeight,u.anchor=$.messageAlign,u.valign="center",u.textMargin=$.wrapPadding,u.tspan=!1,(0,r.G)(u.text)?await k(t,u,{startx:n,stopx:o,starty:a}):I(t,u);const x=g.width;let y;n===o?y=$.rightAngles?t.append("path").attr("d",`M ${n},${a} H ${n+r.e.getMax($.width/2,x/2)} V ${a+25} H ${n}`):t.append("path").attr("d","M "+n+","+a+" C "+(n+60)+","+(a-10)+" "+(n+60)+","+(a+30)+" "+n+","+(a+20)):(y=t.append("line"),y.attr("x1",n),y.attr("y1",a),y.attr("x2",o),y.attr("y2",a)),d===s.db.LINETYPE.DOTTED||d===s.db.LINETYPE.DOTTED_CROSS||d===s.db.LINETYPE.DOTTED_POINT||d===s.db.LINETYPE.DOTTED_OPEN?(y.style("stroke-dasharray","3, 3"),y.attr("class","messageLine1")):y.attr("class","messageLine0");let m="";$.arrowMarkerAbsolute&&(m=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,m=m.replace(/\(/g,"\\("),m=m.replace(/\)/g,"\\)")),y.attr("stroke-width",2),y.attr("stroke","none"),y.style("fill","none"),d!==s.db.LINETYPE.SOLID&&d!==s.db.LINETYPE.DOTTED||y.attr("marker-end","url("+m+"#arrowhead)"),d!==s.db.LINETYPE.SOLID_POINT&&d!==s.db.LINETYPE.DOTTED_POINT||y.attr("marker-end","url("+m+"#filled-head)"),d!==s.db.LINETYPE.SOLID_CROSS&&d!==s.db.LINETYPE.DOTTED_CROSS||y.attr("marker-end","url("+m+"#crosshead)"),(p||$.showSequenceNumbers)&&(y.attr("marker-start","url("+m+"#sequencenumber)"),t.append("text").attr("x",n).attr("y",a+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(h))},H=async function(t,e,a,s){if(s){let s=0;Y.bumpVerticalPos(2*$.boxMargin);for(const i of a){const a=e[i];a.stopy||(a.stopy=Y.getVerticalPos());const n=await C.drawActor(t,a,$,!0);s=r.e.getMax(s,n)}Y.bumpVerticalPos(s+$.boxMargin)}else for(const r of a){const a=e[r];await C.drawActor(t,a,$,!1)}},U=function(t,e,a,r){let s=0,i=0;for(const n of a){const a=e[n],o=Z(a),c=C.drawPopup(t,a,o,$,$.forceMenus,r);c.height>s&&(s=c.height),c.width+a.x>i&&(i=c.width+a.x)}return{maxHeight:s,maxWidth:i}},j=function(t){(0,r.f)($,t),t.fontFamily&&($.actorFontFamily=$.noteFontFamily=$.messageFontFamily=t.fontFamily),t.fontSize&&($.actorFontSize=$.noteFontSize=$.messageFontSize=t.fontSize),t.fontWeight&&($.actorFontWeight=$.noteFontWeight=$.messageFontWeight=t.fontWeight)},G=function(t){return Y.activations.filter((function(e){return e.actor===t}))},K=function(t,e){const a=e[t],s=G(t);return[s.reduce((function(t,e){return r.e.getMin(t,e.startx)}),a.x+a.width/2-1),s.reduce((function(t,e){return r.e.getMax(t,e.stopx)}),a.x+a.width/2+1)]};function X(t,e,a,s,i){Y.bumpVerticalPos(a);let n=s;if(e.id&&e.message&&t[e.id]){const a=t[e.id].width,i=V($);e.message=r.u.wrapLabel(`[${e.message}]`,a-2*$.wrapPadding,i),e.width=a,e.wrap=!0;const o=r.u.calculateTextDimensions(e.message,i),c=r.e.getMax(o.height,$.labelBoxHeight);n=s+c,r.l.debug(`${c} - ${e.message}`)}i(e),Y.bumpVerticalPos(n)}function J(t,e,a,r,s,i,n){function o(a,r){a.x<s[t.from].x?(Y.insert(e.stopx-r,e.starty,e.startx,e.stopy+a.height/2+$.noteMargin),e.stopx=e.stopx+r):(Y.insert(e.startx,e.starty,e.stopx+r,e.stopy+a.height/2+$.noteMargin),e.stopx=e.stopx-r)}if(i[t.to]==r){const e=s[t.to];o(e,"actor"==e.type?21:e.width/2+3),e.starty=a-e.height/2,Y.bumpVerticalPos(e.height/2)}else if(n[t.from]==r){const r=s[t.from];if($.mirrorActors){!function(a,r){a.x<s[t.to].x?(Y.insert(e.startx-r,e.starty,e.stopx,e.stopy+a.height/2+$.noteMargin),e.startx=e.startx+r):(Y.insert(e.stopx,e.starty,e.startx+r,e.stopy+a.height/2+$.noteMargin),e.startx=e.startx-r)}(r,"actor"==r.type?18:r.width/2)}r.stopy=a-r.height/2,Y.bumpVerticalPos(r.height/2)}else if(n[t.to]==r){const e=s[t.to];if($.mirrorActors){o(e,"actor"==e.type?21:e.width/2+3)}e.stopy=a-e.height/2,Y.bumpVerticalPos(e.height/2)}}const Z=function(t){let e=0;const a=q($);for(const s in t.links){const t=r.u.calculateTextDimensions(s,a).width+2*$.wrapPadding+2*$.boxMargin;e<t&&(e=t)}return e};const Q=async function(t,e,a){const s=e[t.from].x,i=e[t.to].x,n=t.wrap&&t.message;let o=(0,r.G)(t.message)?await(0,r.H)(t.message,(0,r.c)()):r.u.calculateTextDimensions(n?r.u.wrapLabel(t.message,$.width,F($)):t.message,F($));const c={width:n?$.width:r.e.getMax($.width,o.width+2*$.noteMargin),height:0,startx:e[t.from].x,stopx:0,starty:0,stopy:0,message:t.message};return t.placement===a.db.PLACEMENT.RIGHTOF?(c.width=n?r.e.getMax($.width,o.width):r.e.getMax(e[t.from].width/2+e[t.to].width/2,o.width+2*$.noteMargin),c.startx=s+(e[t.from].width+$.actorMargin)/2):t.placement===a.db.PLACEMENT.LEFTOF?(c.width=n?r.e.getMax($.width,o.width+2*$.noteMargin):r.e.getMax(e[t.from].width/2+e[t.to].width/2,o.width+2*$.noteMargin),c.startx=s-c.width+(e[t.from].width-$.actorMargin)/2):t.to===t.from?(o=r.u.calculateTextDimensions(n?r.u.wrapLabel(t.message,r.e.getMax($.width,e[t.from].width),F($)):t.message,F($)),c.width=n?r.e.getMax($.width,e[t.from].width):r.e.getMax(e[t.from].width,$.width,o.width+2*$.noteMargin),c.startx=s+(e[t.from].width-c.width)/2):(c.width=Math.abs(s+e[t.from].width/2-(i+e[t.to].width/2))+$.actorMargin,c.startx=s<i?s+e[t.from].width/2-$.actorMargin/2:i+e[t.to].width/2-$.actorMargin/2),n&&(c.message=r.u.wrapLabel(t.message,c.width-2*$.wrapPadding,F($))),r.l.debug(`NM:[${c.startx},${c.stopx},${c.starty},${c.stopy}:${c.width},${c.height}=${t.message}]`),c},tt=function(t,e,a){if(![a.db.LINETYPE.SOLID_OPEN,a.db.LINETYPE.DOTTED_OPEN,a.db.LINETYPE.SOLID,a.db.LINETYPE.DOTTED,a.db.LINETYPE.SOLID_CROSS,a.db.LINETYPE.DOTTED_CROSS,a.db.LINETYPE.SOLID_POINT,a.db.LINETYPE.DOTTED_POINT].includes(t.type))return{};const[s,i]=K(t.from,e),[n,o]=K(t.to,e),c=s<=n,l=c?i:s;let d=c?n:o;const h=Math.abs(n-o)>2,p=t=>c?-t:t;t.from===t.to?d=l:(t.activate&&!h&&(d+=p($.activationWidth/2-1)),[a.db.LINETYPE.SOLID_OPEN,a.db.LINETYPE.DOTTED_OPEN].includes(t.type)||(d+=p(3)));const g=[s,i,n,o],u=Math.abs(l-d);t.wrap&&t.message&&(t.message=r.u.wrapLabel(t.message,r.e.getMax(u+2*$.wrapPadding,$.width),V($)));const x=r.u.calculateTextDimensions(t.message,V($));return{width:r.e.getMax(t.wrap?0:x.width+2*$.wrapPadding,u+2*$.wrapPadding,$.width),height:0,startx:l,stopx:d,starty:0,stopy:0,message:t.message,type:t.type,wrap:t.wrap,fromBounds:Math.min.apply(null,g),toBounds:Math.max.apply(null,g)}},et=async function(t,e,a,s){const i={},n=[];let o,c,l;for(const d of t){switch(d.id=r.u.random({length:10}),d.type){case s.db.LINETYPE.LOOP_START:case s.db.LINETYPE.ALT_START:case s.db.LINETYPE.OPT_START:case s.db.LINETYPE.PAR_START:case s.db.LINETYPE.PAR_OVER_START:case s.db.LINETYPE.CRITICAL_START:case s.db.LINETYPE.BREAK_START:n.push({id:d.id,msg:d.message,from:Number.MAX_SAFE_INTEGER,to:Number.MIN_SAFE_INTEGER,width:0});break;case s.db.LINETYPE.ALT_ELSE:case s.db.LINETYPE.PAR_AND:case s.db.LINETYPE.CRITICAL_OPTION:d.message&&(o=n.pop(),i[o.id]=o,i[d.id]=o,n.push(o));break;case s.db.LINETYPE.LOOP_END:case s.db.LINETYPE.ALT_END:case s.db.LINETYPE.OPT_END:case s.db.LINETYPE.PAR_END:case s.db.LINETYPE.CRITICAL_END:case s.db.LINETYPE.BREAK_END:o=n.pop(),i[o.id]=o;break;case s.db.LINETYPE.ACTIVE_START:{const t=e[d.from?d.from.actor:d.to.actor],a=G(d.from?d.from.actor:d.to.actor).length,r=t.x+t.width/2+(a-1)*$.activationWidth/2,s={startx:r,stopx:r+$.activationWidth,actor:d.from.actor,enabled:!0};Y.activations.push(s)}break;case s.db.LINETYPE.ACTIVE_END:{const t=Y.activations.map((t=>t.actor)).lastIndexOf(d.from.actor);delete Y.activations.splice(t,1)[0]}}void 0!==d.placement?(c=await Q(d,e,s),d.noteModel=c,n.forEach((t=>{o=t,o.from=r.e.getMin(o.from,c.startx),o.to=r.e.getMax(o.to,c.startx+c.width),o.width=r.e.getMax(o.width,Math.abs(o.from-o.to))-$.labelBoxWidth}))):(l=tt(d,e,s),d.msgModel=l,l.startx&&l.stopx&&n.length>0&&n.forEach((t=>{if(o=t,l.startx===l.stopx){const t=e[d.from],a=e[d.to];o.from=r.e.getMin(t.x-l.width/2,t.x-t.width/2,o.from),o.to=r.e.getMax(a.x+l.width/2,a.x+t.width/2,o.to),o.width=r.e.getMax(o.width,Math.abs(o.to-o.from))-$.labelBoxWidth}else o.from=r.e.getMin(l.startx,o.from),o.to=r.e.getMax(l.stopx,o.to),o.width=r.e.getMax(o.width,l.width)-$.labelBoxWidth})))}return Y.activations=[],r.l.debug("Loop type widths:",i),i},at={parser:c,db:w,renderer:{bounds:Y,drawActors:H,drawActorsPopup:U,setConf:j,draw:async function(t,e,a,i){const{securityLevel:n,sequence:o}=(0,r.c)();let c;$=o,"sandbox"===n&&(c=(0,s.Ltv)("#i"+e));const l="sandbox"===n?(0,s.Ltv)(c.nodes()[0].contentDocument.body):(0,s.Ltv)("body"),d="sandbox"===n?c.nodes()[0].contentDocument:document;Y.init(),r.l.debug(i.db);const h="sandbox"===n?l.select(`[id="${e}"]`):(0,s.Ltv)(`[id="${e}"]`),p=i.db.getActors(),g=i.db.getCreatedActors(),u=i.db.getDestroyedActors(),x=i.db.getBoxes();let y=i.db.getActorKeys();const m=i.db.getMessages(),b=i.db.getDiagramTitle(),f=i.db.hasAtLeastOneBox(),T=i.db.hasAtLeastOneBoxWithTitle(),E=await async function(t,e,a){const s={};for(const i of e)if(t[i.to]&&t[i.from]){const e=t[i.to];if(i.placement===a.db.PLACEMENT.LEFTOF&&!e.prevActor)continue;if(i.placement===a.db.PLACEMENT.RIGHTOF&&!e.nextActor)continue;const n=void 0!==i.placement,o=!n,c=n?F($):V($),l=i.wrap?r.u.wrapLabel(i.message,$.width-2*$.wrapPadding,c):i.message,d=((0,r.G)(l)?await(0,r.H)(i.message,(0,r.c)()):r.u.calculateTextDimensions(l,c)).width+2*$.wrapPadding;o&&i.from===e.nextActor?s[i.to]=r.e.getMax(s[i.to]||0,d):o&&i.from===e.prevActor?s[i.from]=r.e.getMax(s[i.from]||0,d):o&&i.from===i.to?(s[i.from]=r.e.getMax(s[i.from]||0,d/2),s[i.to]=r.e.getMax(s[i.to]||0,d/2)):i.placement===a.db.PLACEMENT.RIGHTOF?s[i.from]=r.e.getMax(s[i.from]||0,d):i.placement===a.db.PLACEMENT.LEFTOF?s[e.prevActor]=r.e.getMax(s[e.prevActor]||0,d):i.placement===a.db.PLACEMENT.OVER&&(e.prevActor&&(s[e.prevActor]=r.e.getMax(s[e.prevActor]||0,d/2)),e.nextActor&&(s[i.from]=r.e.getMax(s[i.from]||0,d/2)))}return r.l.debug("maxMessageWidthPerActor:",s),s}(p,m,i);if($.height=await async function(t,e,a){let s=0;for(const n of Object.keys(t)){const e=t[n];e.wrap&&(e.description=r.u.wrapLabel(e.description,$.width-2*$.wrapPadding,q($)));const a=(0,r.G)(e.description)?await(0,r.H)(e.description,(0,r.c)()):r.u.calculateTextDimensions(e.description,q($));e.width=e.wrap?$.width:r.e.getMax($.width,a.width+2*$.wrapPadding),e.height=e.wrap?r.e.getMax(a.height,$.height):$.height,s=r.e.getMax(s,e.height)}for(const n in e){const a=t[n];if(!a)continue;const s=t[a.nextActor];if(!s){const t=e[n]+$.actorMargin-a.width/2;a.margin=r.e.getMax(t,$.actorMargin);continue}const i=e[n]+$.actorMargin-a.width/2-s.width/2;a.margin=r.e.getMax(i,$.actorMargin)}let i=0;return a.forEach((e=>{const a=V($);let s=e.actorKeys.reduce(((e,a)=>e+(t[a].width+(t[a].margin||0))),0);s-=2*$.boxTextMargin,e.wrap&&(e.name=r.u.wrapLabel(e.name,s-2*$.wrapPadding,a));const n=r.u.calculateTextDimensions(e.name,a);i=r.e.getMax(n.height,i);const o=r.e.getMax(s,n.width+2*$.wrapPadding);if(e.margin=$.boxTextMargin,s<o){const t=(o-s)/2;e.margin+=t}})),a.forEach((t=>t.textMaxHeight=i)),r.e.getMax(s,$.height)}(p,E,x),C.insertComputerIcon(h),C.insertDatabaseIcon(h),C.insertClockIcon(h),f&&(Y.bumpVerticalPos($.boxMargin),T&&Y.bumpVerticalPos(x[0].textMaxHeight)),!0===$.hideUnusedParticipants){const t=new Set;m.forEach((e=>{t.add(e.from),t.add(e.to)})),y=y.filter((e=>t.has(e)))}await async function(t,e,a,s,i,n,o){let c,l=0,d=0,h=0;for(const p of s){const t=e[p],s=t.box;c&&c!=s&&(o||Y.models.addBox(c),d+=$.boxMargin+c.margin),s&&s!=c&&(o||(s.x=l+d,s.y=i),d+=s.margin),t.width=t.width||$.width,t.height=r.e.getMax(t.height||$.height,$.height),t.margin=t.margin||$.actorMargin,h=r.e.getMax(h,t.height),a[t.name]&&(d+=t.width/2),t.x=l+d,t.starty=Y.getVerticalPos(),Y.insert(t.x,i,t.x+t.width,t.height),l+=t.width+d,t.box&&(t.box.width=l+s.margin-t.box.x),d=t.margin,c=t.box,Y.models.addActor(t)}c&&!o&&Y.models.addBox(c),Y.bumpVerticalPos(h)}(0,p,g,y,0,0,!1);const w=await et(m,p,E,i);function P(t,e){const a=Y.endActivation(t);a.starty+18>e&&(a.starty=e-6,e+=12),C.drawActivation(h,a,e,$,G(t.from.actor).length),Y.insert(a.startx,e-10,a.stopx,e)}C.insertArrowHead(h),C.insertArrowCrossHead(h),C.insertArrowFilledHead(h),C.insertSequenceNumber(h);let v=1,_=1;const L=[],k=[];let I=0;for(const s of m){let t,e,a;switch(s.type){case i.db.LINETYPE.NOTE:Y.resetVerticalPos(),e=s.noteModel,await B(h,e);break;case i.db.LINETYPE.ACTIVE_START:Y.newActivation(s,h,p);break;case i.db.LINETYPE.ACTIVE_END:P(s,Y.getVerticalPos());break;case i.db.LINETYPE.LOOP_START:X(w,s,$.boxMargin,$.boxMargin+$.boxTextMargin,(t=>Y.newLoop(t)));break;case i.db.LINETYPE.LOOP_END:t=Y.endLoop(),await C.drawLoop(h,t,"loop",$),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos()),Y.models.addLoop(t);break;case i.db.LINETYPE.RECT_START:X(w,s,$.boxMargin,$.boxMargin,(t=>Y.newLoop(void 0,t.message)));break;case i.db.LINETYPE.RECT_END:t=Y.endLoop(),k.push(t),Y.models.addLoop(t),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos());break;case i.db.LINETYPE.OPT_START:X(w,s,$.boxMargin,$.boxMargin+$.boxTextMargin,(t=>Y.newLoop(t)));break;case i.db.LINETYPE.OPT_END:t=Y.endLoop(),await C.drawLoop(h,t,"opt",$),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos()),Y.models.addLoop(t);break;case i.db.LINETYPE.ALT_START:X(w,s,$.boxMargin,$.boxMargin+$.boxTextMargin,(t=>Y.newLoop(t)));break;case i.db.LINETYPE.ALT_ELSE:X(w,s,$.boxMargin+$.boxTextMargin,$.boxMargin,(t=>Y.addSectionToLoop(t)));break;case i.db.LINETYPE.ALT_END:t=Y.endLoop(),await C.drawLoop(h,t,"alt",$),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos()),Y.models.addLoop(t);break;case i.db.LINETYPE.PAR_START:case i.db.LINETYPE.PAR_OVER_START:X(w,s,$.boxMargin,$.boxMargin+$.boxTextMargin,(t=>Y.newLoop(t))),Y.saveVerticalPos();break;case i.db.LINETYPE.PAR_AND:X(w,s,$.boxMargin+$.boxTextMargin,$.boxMargin,(t=>Y.addSectionToLoop(t)));break;case i.db.LINETYPE.PAR_END:t=Y.endLoop(),await C.drawLoop(h,t,"par",$),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos()),Y.models.addLoop(t);break;case i.db.LINETYPE.AUTONUMBER:v=s.message.start||v,_=s.message.step||_,s.message.visible?i.db.enableSequenceNumbers():i.db.disableSequenceNumbers();break;case i.db.LINETYPE.CRITICAL_START:X(w,s,$.boxMargin,$.boxMargin+$.boxTextMargin,(t=>Y.newLoop(t)));break;case i.db.LINETYPE.CRITICAL_OPTION:X(w,s,$.boxMargin+$.boxTextMargin,$.boxMargin,(t=>Y.addSectionToLoop(t)));break;case i.db.LINETYPE.CRITICAL_END:t=Y.endLoop(),await C.drawLoop(h,t,"critical",$),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos()),Y.models.addLoop(t);break;case i.db.LINETYPE.BREAK_START:X(w,s,$.boxMargin,$.boxMargin+$.boxTextMargin,(t=>Y.newLoop(t)));break;case i.db.LINETYPE.BREAK_END:t=Y.endLoop(),await C.drawLoop(h,t,"break",$),Y.bumpVerticalPos(t.stopy-Y.getVerticalPos()),Y.models.addLoop(t);break;default:try{a=s.msgModel,a.starty=Y.getVerticalPos(),a.sequenceIndex=v,a.sequenceVisible=i.db.showSequenceNumbers();const t=await W(0,a);J(s,a,t,I,p,g,u),L.push({messageModel:a,lineStartY:t}),Y.models.addMessage(a)}catch(K){r.l.error("error while drawing message",K)}}[i.db.LINETYPE.SOLID_OPEN,i.db.LINETYPE.DOTTED_OPEN,i.db.LINETYPE.SOLID,i.db.LINETYPE.DOTTED,i.db.LINETYPE.SOLID_CROSS,i.db.LINETYPE.DOTTED_CROSS,i.db.LINETYPE.SOLID_POINT,i.db.LINETYPE.DOTTED_POINT].includes(s.type)&&(v+=_),I++}r.l.debug("createdActors",g),r.l.debug("destroyedActors",u),await H(h,p,y,!1);for(const r of L)await z(h,r.messageModel,r.lineStartY,i);$.mirrorActors&&await H(h,p,y,!0),k.forEach((t=>C.drawBackgroundRect(h,t))),A(h,p,y,$);for(const r of Y.models.boxes)r.height=Y.getVerticalPos()-r.y,Y.insert(r.x,r.y,r.x+r.width,r.height),r.startx=r.x,r.starty=r.y,r.stopx=r.startx+r.width,r.stopy=r.starty+r.height,r.stroke="rgb(0,0,0, 0.5)",await C.drawBox(h,r,$);f&&Y.bumpVerticalPos($.boxMargin);const M=U(h,p,y,d),{bounds:N}=Y.getBounds();let O=N.stopy-N.starty;O<M.maxHeight&&(O=M.maxHeight);let S=O+2*$.diagramMarginY;$.mirrorActors&&(S=S-$.boxMargin+$.bottomMarginAdj);let D=N.stopx-N.startx;D<M.maxWidth&&(D=M.maxWidth);const R=D+2*$.diagramMarginX;b&&h.append("text").text(b).attr("x",(N.stopx-N.startx)/2-2*$.diagramMarginX).attr("y",-25),(0,r.i)(h,S,R,$.useMaxWidth);const j=b?40:0;h.attr("viewBox",N.startx-$.diagramMarginX+" -"+($.diagramMarginY+j)+" "+R+" "+(S+j)),r.l.debug("models:",Y.models)}},styles:P,init:({wrap:t})=>{w.setWrap(t)}}},58886:(t,e,a)=>{a.d(e,{a:()=>n,b:()=>l,c:()=>c,d:()=>i,e:()=>h,f:()=>o,g:()=>d});var r=a(16750),s=a(76257);const i=(t,e)=>{const a=t.append("rect");if(a.attr("x",e.x),a.attr("y",e.y),a.attr("fill",e.fill),a.attr("stroke",e.stroke),a.attr("width",e.width),a.attr("height",e.height),e.name&&a.attr("name",e.name),void 0!==e.rx&&a.attr("rx",e.rx),void 0!==e.ry&&a.attr("ry",e.ry),void 0!==e.attrs)for(const r in e.attrs)a.attr(r,e.attrs[r]);return void 0!==e.class&&a.attr("class",e.class),a},n=(t,e)=>{const a={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};i(t,a).lower()},o=(t,e)=>{const a=e.text.replace(s.J," "),r=t.append("text");r.attr("x",e.x),r.attr("y",e.y),r.attr("class","legend"),r.style("text-anchor",e.anchor),void 0!==e.class&&r.attr("class",e.class);const i=r.append("tspan");return i.attr("x",e.x+2*e.textMargin),i.text(a),r},c=(t,e,a,s)=>{const i=t.append("image");i.attr("x",e),i.attr("y",a);const n=(0,r.Jf)(s);i.attr("xlink:href",n)},l=(t,e,a,s)=>{const i=t.append("use");i.attr("x",e),i.attr("y",a);const n=(0,r.Jf)(s);i.attr("xlink:href",`#${n}`)},d=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),h=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})}}]); \ No newline at end of file diff --git a/assets/js/7217b34c.ddce5803.js b/assets/js/7217b34c.ddce5803.js new file mode 100644 index 0000000000..f6b244d213 --- /dev/null +++ b/assets/js/7217b34c.ddce5803.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6098],{67768:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>c,contentTitle:()=>o,default:()=>g,frontMatter:()=>s,metadata:()=>u,toc:()=>r});var i=t(74848),a=t(28453);const s={sidebar_label:"Magnum"},o="Magnum",u={id:"iaas/guides/configuration-guide/openstack/magnum",title:"Magnum",description:"* Magnum admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/magnum.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/magnum",permalink:"/docs/iaas/guides/configuration-guide/openstack/magnum",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/magnum.md",tags:[],version:"current",frontMatter:{sidebar_label:"Magnum"},sidebar:"docs",previous:{title:"Keystone",permalink:"/docs/iaas/guides/configuration-guide/openstack/keystone"},next:{title:"Manila",permalink:"/docs/iaas/guides/configuration-guide/openstack/manila"}},c={},r=[];function d(n){const e={a:"a",h1:"h1",li:"li",ul:"ul",...(0,a.R)(),...n.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h1,{id:"magnum",children:"Magnum"}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:"https://docs.openstack.org/magnum/latest/admin/index.html",children:"Magnum admin guide"})}),"\n",(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:"https://docs.openstack.org/magnum/latest/configuration/index.html",children:"Magnum configuration reference"})}),"\n"]})]})}function g(n={}){const{wrapper:e}={...(0,a.R)(),...n.components};return e?(0,i.jsx)(e,{...n,children:(0,i.jsx)(d,{...n})}):d(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>o,x:()=>u});var i=t(96540);const a={},s=i.createContext(a);function o(n){const e=i.useContext(s);return i.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function u(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(a):n.components||a:o(n.components),i.createElement(s.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/7308.95db45a6.js b/assets/js/7308.95db45a6.js new file mode 100644 index 0000000000..5e56d1dabf --- /dev/null +++ b/assets/js/7308.95db45a6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7308],{27308:(t,e,s)=>{s.d(e,{d:()=>D,p:()=>r,s:()=>_});var n=s(26312),i=s(76257),u=function(){var t=function(t,e,s,n){for(s=s||{},n=t.length;n--;s[t[n]]=e);return s},e=[1,17],s=[1,18],n=[1,19],i=[1,39],u=[1,40],r=[1,25],a=[1,23],c=[1,24],o=[1,31],l=[1,32],h=[1,33],A=[1,34],p=[1,35],d=[1,36],y=[1,26],E=[1,27],C=[1,28],m=[1,29],f=[1,43],b=[1,30],F=[1,42],g=[1,44],k=[1,41],T=[1,45],B=[1,9],D=[1,8,9],_=[1,56],S=[1,57],N=[1,58],L=[1,59],$=[1,60],v=[1,61],O=[1,62],x=[1,8,9,39],I=[1,74],R=[1,8,9,12,13,21,37,39,42,59,60,61,62,63,64,65,70,72],w=[1,8,9,12,13,19,21,37,39,42,46,59,60,61,62,63,64,65,70,72,74,80,95,97,98],P=[13,74,80,95,97,98],M=[13,64,65,74,80,95,97,98],G=[13,59,60,61,62,63,74,80,95,97,98],U=[1,93],z=[1,110],K=[1,108],Y=[1,102],j=[1,103],Q=[1,104],X=[1,105],W=[1,106],q=[1,107],H=[1,109],J=[1,8,9,37,39,42],V=[1,8,9,21],Z=[1,8,9,78],tt=[1,8,9,21,73,74,78,80,81,82,83,84,85],et={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statements:5,graphConfig:6,CLASS_DIAGRAM:7,NEWLINE:8,EOF:9,statement:10,classLabel:11,SQS:12,STR:13,SQE:14,namespaceName:15,alphaNumToken:16,className:17,classLiteralName:18,GENERICTYPE:19,relationStatement:20,LABEL:21,namespaceStatement:22,classStatement:23,memberStatement:24,annotationStatement:25,clickStatement:26,styleStatement:27,cssClassStatement:28,noteStatement:29,direction:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,namespaceIdentifier:36,STRUCT_START:37,classStatements:38,STRUCT_STOP:39,NAMESPACE:40,classIdentifier:41,STYLE_SEPARATOR:42,members:43,CLASS:44,ANNOTATION_START:45,ANNOTATION_END:46,MEMBER:47,SEPARATOR:48,relation:49,NOTE_FOR:50,noteText:51,NOTE:52,direction_tb:53,direction_bt:54,direction_rl:55,direction_lr:56,relationType:57,lineType:58,AGGREGATION:59,EXTENSION:60,COMPOSITION:61,DEPENDENCY:62,LOLLIPOP:63,LINE:64,DOTTED_LINE:65,CALLBACK:66,LINK:67,LINK_TARGET:68,CLICK:69,CALLBACK_NAME:70,CALLBACK_ARGS:71,HREF:72,STYLE:73,ALPHA:74,stylesOpt:75,CSSCLASS:76,style:77,COMMA:78,styleComponent:79,NUM:80,COLON:81,UNIT:82,SPACE:83,BRKT:84,PCT:85,commentToken:86,textToken:87,graphCodeTokens:88,textNoTagsToken:89,TAGSTART:90,TAGEND:91,"==":92,"--":93,DEFAULT:94,MINUS:95,keywords:96,UNICODE_TEXT:97,BQUOTE_STR:98,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",19:"GENERICTYPE",21:"LABEL",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",37:"STRUCT_START",39:"STRUCT_STOP",40:"NAMESPACE",42:"STYLE_SEPARATOR",44:"CLASS",45:"ANNOTATION_START",46:"ANNOTATION_END",47:"MEMBER",48:"SEPARATOR",50:"NOTE_FOR",52:"NOTE",53:"direction_tb",54:"direction_bt",55:"direction_rl",56:"direction_lr",59:"AGGREGATION",60:"EXTENSION",61:"COMPOSITION",62:"DEPENDENCY",63:"LOLLIPOP",64:"LINE",65:"DOTTED_LINE",66:"CALLBACK",67:"LINK",68:"LINK_TARGET",69:"CLICK",70:"CALLBACK_NAME",71:"CALLBACK_ARGS",72:"HREF",73:"STYLE",74:"ALPHA",76:"CSSCLASS",78:"COMMA",80:"NUM",81:"COLON",82:"UNIT",83:"SPACE",84:"BRKT",85:"PCT",88:"graphCodeTokens",90:"TAGSTART",91:"TAGEND",92:"==",93:"--",94:"DEFAULT",95:"MINUS",96:"keywords",97:"UNICODE_TEXT",98:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,2],[17,1],[17,1],[17,2],[17,2],[17,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[22,4],[22,5],[36,2],[38,1],[38,2],[38,3],[23,1],[23,3],[23,4],[23,6],[41,2],[41,3],[25,4],[43,1],[43,2],[24,1],[24,2],[24,1],[24,1],[20,3],[20,4],[20,4],[20,5],[29,3],[29,2],[30,1],[30,1],[30,1],[30,1],[49,3],[49,2],[49,2],[49,1],[57,1],[57,1],[57,1],[57,1],[57,1],[58,1],[58,1],[26,3],[26,4],[26,3],[26,4],[26,4],[26,5],[26,3],[26,4],[26,4],[26,5],[26,4],[26,5],[26,5],[26,6],[27,3],[28,3],[75,1],[75,3],[77,1],[77,2],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[86,1],[86,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[89,1],[89,1],[89,1],[89,1],[16,1],[16,1],[16,1],[16,1],[18,1],[51,1]],performAction:function(t,e,s,n,i,u,r){var a=u.length-1;switch(i){case 8:this.$=u[a-1];break;case 9:case 11:case 12:this.$=u[a];break;case 10:case 13:case 89:this.$=u[a-1]+u[a];break;case 14:case 15:this.$=u[a-1]+"~"+u[a]+"~";break;case 16:n.addRelation(u[a]);break;case 17:u[a-1].title=n.cleanupLabel(u[a]),n.addRelation(u[a-1]);break;case 27:this.$=u[a].trim(),n.setAccTitle(this.$);break;case 28:case 29:this.$=u[a].trim(),n.setAccDescription(this.$);break;case 30:n.addClassesToNamespace(u[a-3],u[a-1]);break;case 31:n.addClassesToNamespace(u[a-4],u[a-1]);break;case 32:this.$=u[a],n.addNamespace(u[a]);break;case 33:case 43:case 86:this.$=[u[a]];break;case 34:this.$=[u[a-1]];break;case 35:u[a].unshift(u[a-2]),this.$=u[a];break;case 37:n.setCssClass(u[a-2],u[a]);break;case 38:n.addMembers(u[a-3],u[a-1]);break;case 39:n.setCssClass(u[a-5],u[a-3]),n.addMembers(u[a-5],u[a-1]);break;case 40:this.$=u[a],n.addClass(u[a]);break;case 41:this.$=u[a-1],n.addClass(u[a-1]),n.setClassLabel(u[a-1],u[a]);break;case 42:n.addAnnotation(u[a],u[a-2]);break;case 44:u[a].push(u[a-1]),this.$=u[a];break;case 45:case 47:case 48:break;case 46:n.addMember(u[a-1],n.cleanupLabel(u[a]));break;case 49:this.$={id1:u[a-2],id2:u[a],relation:u[a-1],relationTitle1:"none",relationTitle2:"none"};break;case 50:this.$={id1:u[a-3],id2:u[a],relation:u[a-1],relationTitle1:u[a-2],relationTitle2:"none"};break;case 51:this.$={id1:u[a-3],id2:u[a],relation:u[a-2],relationTitle1:"none",relationTitle2:u[a-1]};break;case 52:this.$={id1:u[a-4],id2:u[a],relation:u[a-2],relationTitle1:u[a-3],relationTitle2:u[a-1]};break;case 53:n.addNote(u[a],u[a-1]);break;case 54:n.addNote(u[a]);break;case 55:n.setDirection("TB");break;case 56:n.setDirection("BT");break;case 57:n.setDirection("RL");break;case 58:n.setDirection("LR");break;case 59:this.$={type1:u[a-2],type2:u[a],lineType:u[a-1]};break;case 60:this.$={type1:"none",type2:u[a],lineType:u[a-1]};break;case 61:this.$={type1:u[a-1],type2:"none",lineType:u[a]};break;case 62:this.$={type1:"none",type2:"none",lineType:u[a]};break;case 63:this.$=n.relationType.AGGREGATION;break;case 64:this.$=n.relationType.EXTENSION;break;case 65:this.$=n.relationType.COMPOSITION;break;case 66:this.$=n.relationType.DEPENDENCY;break;case 67:this.$=n.relationType.LOLLIPOP;break;case 68:this.$=n.lineType.LINE;break;case 69:this.$=n.lineType.DOTTED_LINE;break;case 70:case 76:this.$=u[a-2],n.setClickEvent(u[a-1],u[a]);break;case 71:case 77:this.$=u[a-3],n.setClickEvent(u[a-2],u[a-1]),n.setTooltip(u[a-2],u[a]);break;case 72:this.$=u[a-2],n.setLink(u[a-1],u[a]);break;case 73:this.$=u[a-3],n.setLink(u[a-2],u[a-1],u[a]);break;case 74:this.$=u[a-3],n.setLink(u[a-2],u[a-1]),n.setTooltip(u[a-2],u[a]);break;case 75:this.$=u[a-4],n.setLink(u[a-3],u[a-2],u[a]),n.setTooltip(u[a-3],u[a-1]);break;case 78:this.$=u[a-3],n.setClickEvent(u[a-2],u[a-1],u[a]);break;case 79:this.$=u[a-4],n.setClickEvent(u[a-3],u[a-2],u[a-1]),n.setTooltip(u[a-3],u[a]);break;case 80:this.$=u[a-3],n.setLink(u[a-2],u[a]);break;case 81:this.$=u[a-4],n.setLink(u[a-3],u[a-1],u[a]);break;case 82:this.$=u[a-4],n.setLink(u[a-3],u[a-1]),n.setTooltip(u[a-3],u[a]);break;case 83:this.$=u[a-5],n.setLink(u[a-4],u[a-2],u[a]),n.setTooltip(u[a-4],u[a-1]);break;case 84:this.$=u[a-2],n.setCssStyle(u[a-1],u[a]);break;case 85:n.setCssClass(u[a-1],u[a]);break;case 87:u[a-2].push(u[a]),this.$=u[a-2]}},table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:37,17:20,18:38,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,31:e,33:s,35:n,36:21,40:i,41:22,44:u,45:r,47:a,48:c,50:o,52:l,53:h,54:A,55:p,56:d,66:y,67:E,69:C,73:m,74:f,76:b,80:F,95:g,97:k,98:T},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},t(B,[2,5],{8:[1,46]}),{8:[1,47]},t(D,[2,16],{21:[1,48]}),t(D,[2,18]),t(D,[2,19]),t(D,[2,20]),t(D,[2,21]),t(D,[2,22]),t(D,[2,23]),t(D,[2,24]),t(D,[2,25]),t(D,[2,26]),{32:[1,49]},{34:[1,50]},t(D,[2,29]),t(D,[2,45],{49:51,57:54,58:55,13:[1,52],21:[1,53],59:_,60:S,61:N,62:L,63:$,64:v,65:O}),{37:[1,63]},t(x,[2,36],{37:[1,65],42:[1,64]}),t(D,[2,47]),t(D,[2,48]),{16:66,74:f,80:F,95:g,97:k},{16:37,17:67,18:38,74:f,80:F,95:g,97:k,98:T},{16:37,17:68,18:38,74:f,80:F,95:g,97:k,98:T},{16:37,17:69,18:38,74:f,80:F,95:g,97:k,98:T},{74:[1,70]},{13:[1,71]},{16:37,17:72,18:38,74:f,80:F,95:g,97:k,98:T},{13:I,51:73},t(D,[2,55]),t(D,[2,56]),t(D,[2,57]),t(D,[2,58]),t(R,[2,11],{16:37,18:38,17:75,19:[1,76],74:f,80:F,95:g,97:k,98:T}),t(R,[2,12],{19:[1,77]}),{15:78,16:79,74:f,80:F,95:g,97:k},{16:37,17:80,18:38,74:f,80:F,95:g,97:k,98:T},t(w,[2,112]),t(w,[2,113]),t(w,[2,114]),t(w,[2,115]),t([1,8,9,12,13,19,21,37,39,42,59,60,61,62,63,64,65,70,72],[2,116]),t(B,[2,6],{10:5,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,17:20,36:21,41:22,16:37,18:38,5:81,31:e,33:s,35:n,40:i,44:u,45:r,47:a,48:c,50:o,52:l,53:h,54:A,55:p,56:d,66:y,67:E,69:C,73:m,74:f,76:b,80:F,95:g,97:k,98:T}),{5:82,10:5,16:37,17:20,18:38,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,31:e,33:s,35:n,36:21,40:i,41:22,44:u,45:r,47:a,48:c,50:o,52:l,53:h,54:A,55:p,56:d,66:y,67:E,69:C,73:m,74:f,76:b,80:F,95:g,97:k,98:T},t(D,[2,17]),t(D,[2,27]),t(D,[2,28]),{13:[1,84],16:37,17:83,18:38,74:f,80:F,95:g,97:k,98:T},{49:85,57:54,58:55,59:_,60:S,61:N,62:L,63:$,64:v,65:O},t(D,[2,46]),{58:86,64:v,65:O},t(P,[2,62],{57:87,59:_,60:S,61:N,62:L,63:$}),t(M,[2,63]),t(M,[2,64]),t(M,[2,65]),t(M,[2,66]),t(M,[2,67]),t(G,[2,68]),t(G,[2,69]),{8:[1,89],23:90,38:88,41:22,44:u},{16:91,74:f,80:F,95:g,97:k},{43:92,47:U},{46:[1,94]},{13:[1,95]},{13:[1,96]},{70:[1,97],72:[1,98]},{21:z,73:K,74:Y,75:99,77:100,79:101,80:j,81:Q,82:X,83:W,84:q,85:H},{74:[1,111]},{13:I,51:112},t(D,[2,54]),t(D,[2,117]),t(R,[2,13]),t(R,[2,14]),t(R,[2,15]),{37:[2,32]},{15:113,16:79,37:[2,9],74:f,80:F,95:g,97:k},t(J,[2,40],{11:114,12:[1,115]}),t(B,[2,7]),{9:[1,116]},t(V,[2,49]),{16:37,17:117,18:38,74:f,80:F,95:g,97:k,98:T},{13:[1,119],16:37,17:118,18:38,74:f,80:F,95:g,97:k,98:T},t(P,[2,61],{57:120,59:_,60:S,61:N,62:L,63:$}),t(P,[2,60]),{39:[1,121]},{23:90,38:122,41:22,44:u},{8:[1,123],39:[2,33]},t(x,[2,37],{37:[1,124]}),{39:[1,125]},{39:[2,43],43:126,47:U},{16:37,17:127,18:38,74:f,80:F,95:g,97:k,98:T},t(D,[2,70],{13:[1,128]}),t(D,[2,72],{13:[1,130],68:[1,129]}),t(D,[2,76],{13:[1,131],71:[1,132]}),{13:[1,133]},t(D,[2,84],{78:[1,134]}),t(Z,[2,86],{79:135,21:z,73:K,74:Y,80:j,81:Q,82:X,83:W,84:q,85:H}),t(tt,[2,88]),t(tt,[2,90]),t(tt,[2,91]),t(tt,[2,92]),t(tt,[2,93]),t(tt,[2,94]),t(tt,[2,95]),t(tt,[2,96]),t(tt,[2,97]),t(tt,[2,98]),t(D,[2,85]),t(D,[2,53]),{37:[2,10]},t(J,[2,41]),{13:[1,136]},{1:[2,4]},t(V,[2,51]),t(V,[2,50]),{16:37,17:137,18:38,74:f,80:F,95:g,97:k,98:T},t(P,[2,59]),t(D,[2,30]),{39:[1,138]},{23:90,38:139,39:[2,34],41:22,44:u},{43:140,47:U},t(x,[2,38]),{39:[2,44]},t(D,[2,42]),t(D,[2,71]),t(D,[2,73]),t(D,[2,74],{68:[1,141]}),t(D,[2,77]),t(D,[2,78],{13:[1,142]}),t(D,[2,80],{13:[1,144],68:[1,143]}),{21:z,73:K,74:Y,77:145,79:101,80:j,81:Q,82:X,83:W,84:q,85:H},t(tt,[2,89]),{14:[1,146]},t(V,[2,52]),t(D,[2,31]),{39:[2,35]},{39:[1,147]},t(D,[2,75]),t(D,[2,79]),t(D,[2,81]),t(D,[2,82],{68:[1,148]}),t(Z,[2,87],{79:135,21:z,73:K,74:Y,80:j,81:Q,82:X,83:W,84:q,85:H}),t(J,[2,8]),t(x,[2,39]),t(D,[2,83])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],78:[2,32],113:[2,10],116:[2,4],126:[2,44],139:[2,35]},parseError:function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},parse:function(t){var e=this,s=[0],n=[],i=[null],u=[],r=this.table,a="",c=0,o=0,l=u.slice.call(arguments,1),h=Object.create(this.lexer),A={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(A.yy[p]=this.yy[p]);h.setInput(t,A.yy),A.yy.lexer=h,A.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var d=h.yylloc;u.push(d);var y=h.options&&h.options.ranges;"function"==typeof A.yy.parseError?this.parseError=A.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var E,C,m,f,b,F,g,k,T,B={};;){if(C=s[s.length-1],this.defaultActions[C]?m=this.defaultActions[C]:(null==E&&(T=void 0,"number"!=typeof(T=n.pop()||h.lex()||1)&&(T instanceof Array&&(T=(n=T).pop()),T=e.symbols_[T]||T),E=T),m=r[C]&&r[C][E]),void 0===m||!m.length||!m[0]){var D="";for(b in k=[],r[C])this.terminals_[b]&&b>2&&k.push("'"+this.terminals_[b]+"'");D=h.showPosition?"Parse error on line "+(c+1)+":\n"+h.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[E]||E)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==E?"end of input":"'"+(this.terminals_[E]||E)+"'"),this.parseError(D,{text:h.match,token:this.terminals_[E]||E,line:h.yylineno,loc:d,expected:k})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+C+", token: "+E);switch(m[0]){case 1:s.push(E),i.push(h.yytext),u.push(h.yylloc),s.push(m[1]),E=null,o=h.yyleng,a=h.yytext,c=h.yylineno,d=h.yylloc;break;case 2:if(F=this.productions_[m[1]][1],B.$=i[i.length-F],B._$={first_line:u[u.length-(F||1)].first_line,last_line:u[u.length-1].last_line,first_column:u[u.length-(F||1)].first_column,last_column:u[u.length-1].last_column},y&&(B._$.range=[u[u.length-(F||1)].range[0],u[u.length-1].range[1]]),void 0!==(f=this.performAction.apply(B,[a,o,c,A.yy,m[1],i,u].concat(l))))return f;F&&(s=s.slice(0,-1*F*2),i=i.slice(0,-1*F),u=u.slice(0,-1*F)),s.push(this.productions_[m[1]][0]),i.push(B.$),u.push(B._$),g=r[s[s.length-2]][s[s.length-1]],s.push(g);break;case 3:return!0}}return!0}},st={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===n.length?this.yylloc.first_column:0)+n[n.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var s,n,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var u in i)this[u]=i[u];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,s,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),u=0;u<i.length;u++)if((s=this._input.match(this.rules[i[u]]))&&(!e||s[0].length>e[0].length)){if(e=s,n=u,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,i[u])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,s,n){switch(s){case 0:return 53;case 1:return 54;case 2:return 55;case 3:return 56;case 4:case 5:case 14:case 30:case 35:case 39:case 46:break;case 6:return this.begin("acc_title"),31;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),33;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 19:case 22:case 24:case 57:case 60:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:case 34:return 8;case 15:case 16:return 7;case 17:case 36:case 44:return"EDGE_STATE";case 18:this.begin("callback_name");break;case 20:this.popState(),this.begin("callback_args");break;case 21:return 70;case 23:return 71;case 25:return"STR";case 26:this.begin("string");break;case 27:return 73;case 28:return this.begin("namespace"),40;case 29:case 38:return this.popState(),8;case 31:return this.begin("namespace-body"),37;case 32:case 42:return this.popState(),39;case 33:case 43:return"EOF_IN_STRUCT";case 37:return this.begin("class"),44;case 40:return this.popState(),this.popState(),39;case 41:return this.begin("class-body"),37;case 45:return"OPEN_IN_STRUCT";case 47:return"MEMBER";case 48:return 76;case 49:return 66;case 50:return 67;case 51:return 69;case 52:return 50;case 53:return 52;case 54:return 45;case 55:return 46;case 56:return 72;case 58:return"GENERICTYPE";case 59:this.begin("generic");break;case 61:return"BQUOTE_STR";case 62:this.begin("bqstring");break;case 63:case 64:case 65:case 66:return 68;case 67:case 68:return 60;case 69:case 70:return 62;case 71:return 61;case 72:return 59;case 73:return 63;case 74:return 64;case 75:return 65;case 76:return 21;case 77:return 42;case 78:return 95;case 79:return"DOT";case 80:return"PLUS";case 81:return 81;case 82:return 78;case 83:case 84:return 84;case 85:return 85;case 86:case 87:return"EQUALS";case 88:return 74;case 89:return 12;case 90:return 14;case 91:return"PUNCTUATION";case 92:return 80;case 93:return 97;case 94:case 95:return 83;case 96:return 9}},rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:\[\*\])/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:["])/,/^(?:[^"]*)/,/^(?:["])/,/^(?:style\b)/,/^(?:namespace\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:\[\*\])/,/^(?:class\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[}])/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\[\*\])/,/^(?:[{])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:note for\b)/,/^(?:note\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:href\b)/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:~)/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:[`])/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:\s*\(\))/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?::)/,/^(?:,)/,/^(?:#)/,/^(?:#)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:\[)/,/^(?:\])/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:\s)/,/^(?:$)/],conditions:{"namespace-body":{rules:[26,32,33,34,35,36,37,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},namespace:{rules:[26,28,29,30,31,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},"class-body":{rules:[26,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},class:{rules:[26,38,39,40,41,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},acc_descr_multiline:{rules:[11,12,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},acc_descr:{rules:[9,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},acc_title:{rules:[7,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},callback_args:{rules:[22,23,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},callback_name:{rules:[19,20,21,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},href:{rules:[26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},struct:{rules:[26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},generic:{rules:[26,48,49,50,51,52,53,54,55,56,57,58,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},bqstring:{rules:[26,48,49,50,51,52,53,54,55,56,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},string:{rules:[24,25,26,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,85,86,87,88,89,90,91,92,93,94,96],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,26,27,28,37,48,49,50,51,52,53,54,55,56,59,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96],inclusive:!0}}};function nt(){this.yy={}}return et.lexer=st,nt.prototype=et,et.Parser=nt,new nt}();u.parser=u;const r=u,a=["#","+","~","-",""];class c{constructor(t,e){this.memberType=e,this.visibility="",this.classifier="";const s=(0,i.d)(t,(0,i.c)());this.parseMember(s)}getDisplayDetails(){let t=this.visibility+(0,i.x)(this.id);"method"===this.memberType&&(t+=`(${(0,i.x)(this.parameters.trim())})`,this.returnType&&(t+=" : "+(0,i.x)(this.returnType))),t=t.trim();return{displayText:t,cssStyle:this.parseClassifier()}}parseMember(t){let e="";if("method"===this.memberType){const s=/([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/,n=t.match(s);if(n){const t=n[1]?n[1].trim():"";if(a.includes(t)&&(this.visibility=t),this.id=n[2].trim(),this.parameters=n[3]?n[3].trim():"",e=n[4]?n[4].trim():"",this.returnType=n[5]?n[5].trim():"",""===e){const t=this.returnType.substring(this.returnType.length-1);t.match(/[$*]/)&&(e=t,this.returnType=this.returnType.substring(0,this.returnType.length-1))}}}else{const s=t.length,n=t.substring(0,1),i=t.substring(s-1);a.includes(n)&&(this.visibility=n),i.match(/[$*]/)&&(e=i),this.id=t.substring(""===this.visibility?0:1,""===e?s:s-1)}this.classifier=e}parseClassifier(){switch(this.classifier){case"*":return"font-style:italic;";case"$":return"text-decoration:underline;";default:return""}}}const o="classId-";let l=[],h={},A=[],p=0,d={},y=0,E=[];const C=t=>i.e.sanitizeText(t,(0,i.c)()),m=function(t){const e=i.e.sanitizeText(t,(0,i.c)());let s="",n=e;if(e.indexOf("~")>0){const t=e.split("~");n=C(t[0]),s=C(t[1])}return{className:n,type:s}},f=function(t){const e=i.e.sanitizeText(t,(0,i.c)()),{className:s,type:n}=m(e);if(Object.hasOwn(h,s))return;const u=i.e.sanitizeText(s,(0,i.c)());h[u]={id:u,type:n,label:u,cssClasses:[],methods:[],members:[],annotations:[],styles:[],domId:o+u+"-"+p},p++},b=function(t){const e=i.e.sanitizeText(t,(0,i.c)());if(e in h)return h[e].domId;throw new Error("Class not found: "+e)},F=function(t,e){f(t);const s=m(t).className,n=h[s];if("string"==typeof e){const t=e.trim();t.startsWith("<<")&&t.endsWith(">>")?n.annotations.push(C(t.substring(2,t.length-2))):t.indexOf(")")>0?n.methods.push(new c(t,"method")):t&&n.members.push(new c(t,"attribute"))}},g=function(t,e){t.split(",").forEach((function(t){let s=t;t[0].match(/\d/)&&(s=o+s),void 0!==h[s]&&h[s].cssClasses.push(e)}))},k=function(t,e,s){const n=i.e.sanitizeText(t,(0,i.c)());if("loose"!==(0,i.c)().securityLevel)return;if(void 0===e)return;const u=n;if(void 0!==h[u]){const t=b(u);let n=[];if("string"==typeof s){n=s.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t<n.length;t++){let e=n[t].trim();'"'===e.charAt(0)&&'"'===e.charAt(e.length-1)&&(e=e.substr(1,e.length-2)),n[t]=e}}0===n.length&&n.push(t),E.push((function(){const s=document.querySelector(`[id="${t}"]`);null!==s&&s.addEventListener("click",(function(){i.u.runFunc(e,...n)}),!1)}))}},T=function(t){let e=(0,n.Ltv)(".mermaidTooltip");null===(e._groups||e)[0][0]&&(e=(0,n.Ltv)("body").append("div").attr("class","mermaidTooltip").style("opacity",0));(0,n.Ltv)(t).select("svg").selectAll("g.node").on("mouseover",(function(){const t=(0,n.Ltv)(this);if(null===t.attr("title"))return;const s=this.getBoundingClientRect();e.transition().duration(200).style("opacity",".9"),e.text(t.attr("title")).style("left",window.scrollX+s.left+(s.right-s.left)/2+"px").style("top",window.scrollY+s.top-14+document.body.scrollTop+"px"),e.html(e.html().replace(/<br\/>/g,"<br/>")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0);(0,n.Ltv)(this).classed("hover",!1)}))};E.push(T);let B="TB";const D={setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,getConfig:()=>(0,i.c)().class,addClass:f,bindFunctions:function(t){E.forEach((function(e){e(t)}))},clear:function(){l=[],h={},A=[],E=[],E.push(T),d={},y=0,(0,i.v)()},getClass:function(t){return h[t]},getClasses:function(){return h},getNotes:function(){return A},addAnnotation:function(t,e){const s=m(t).className;h[s].annotations.push(e)},addNote:function(t,e){const s={id:`note${A.length}`,class:e,text:t};A.push(s)},getRelations:function(){return l},addRelation:function(t){i.l.debug("Adding relation: "+JSON.stringify(t)),f(t.id1),f(t.id2),t.id1=m(t.id1).className,t.id2=m(t.id2).className,t.relationTitle1=i.e.sanitizeText(t.relationTitle1.trim(),(0,i.c)()),t.relationTitle2=i.e.sanitizeText(t.relationTitle2.trim(),(0,i.c)()),l.push(t)},getDirection:()=>B,setDirection:t=>{B=t},addMember:F,addMembers:function(t,e){Array.isArray(e)&&(e.reverse(),e.forEach((e=>F(t,e))))},cleanupLabel:function(t){return t.startsWith(":")&&(t=t.substring(1)),C(t.trim())},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3,LOLLIPOP:4},setClickEvent:function(t,e,s){t.split(",").forEach((function(t){k(t,e,s),h[t].haveCallback=!0})),g(t,"clickable")},setCssClass:g,setLink:function(t,e,s){const n=(0,i.c)();t.split(",").forEach((function(t){let u=t;t[0].match(/\d/)&&(u=o+u),void 0!==h[u]&&(h[u].link=i.u.formatUrl(e,n),"sandbox"===n.securityLevel?h[u].linkTarget="_top":h[u].linkTarget="string"==typeof s?C(s):"_blank")})),g(t,"clickable")},getTooltip:function(t,e){return e?d[e].classes[t].tooltip:h[t].tooltip},setTooltip:function(t,e){t.split(",").forEach((function(t){void 0!==e&&(h[t].tooltip=C(e))}))},lookUpDomId:b,setDiagramTitle:i.q,getDiagramTitle:i.t,setClassLabel:function(t,e){const s=i.e.sanitizeText(t,(0,i.c)());e&&(e=C(e));const{className:n}=m(s);h[n].label=e},addNamespace:function(t){void 0===d[t]&&(d[t]={id:t,classes:{},children:{},domId:o+t+"-"+y},y++)},addClassesToNamespace:function(t,e){if(void 0!==d[t])for(const s of e){const{className:e}=m(s);h[e].parent=t,d[t].classes[e]=h[e]}},getNamespace:function(t){return d[t]},getNamespaces:function(){return d},setCssStyle:function(t,e){const s=h[t];if(e&&s)for(const n of e)n.includes(",")?s.styles.push(...n.split(",")):s.styles.push(n)}},_=t=>`g.classGroup text {\n fill: ${t.nodeBorder||t.classText};\n stroke: none;\n font-family: ${t.fontFamily};\n font-size: 10px;\n\n .title {\n font-weight: bolder;\n }\n\n}\n\n.nodeLabel, .edgeLabel {\n color: ${t.classText};\n}\n.edgeLabel .label rect {\n fill: ${t.mainBkg};\n}\n.label text {\n fill: ${t.classText};\n}\n.edgeLabel .label span {\n background: ${t.mainBkg};\n}\n\n.classTitle {\n font-weight: bolder;\n}\n.node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n\n.divider {\n stroke: ${t.nodeBorder};\n stroke-width: 1;\n}\n\ng.clickable {\n cursor: pointer;\n}\n\ng.classGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.classGroup line {\n stroke: ${t.nodeBorder};\n stroke-width: 1;\n}\n\n.classLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.classLabel .label {\n fill: ${t.nodeBorder};\n font-size: 10px;\n}\n\n.relation {\n stroke: ${t.lineColor};\n stroke-width: 1;\n fill: none;\n}\n\n.dashed-line{\n stroke-dasharray: 3;\n}\n\n.dotted-line{\n stroke-dasharray: 1 2;\n}\n\n#compositionStart, .composition {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#compositionEnd, .composition {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionStart, .extension {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionEnd, .extension {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationStart, .aggregation {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationEnd, .aggregation {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopStart, .lollipop {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopEnd, .lollipop {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n.edgeTerminals {\n font-size: 11px;\n line-height: initial;\n}\n\n.classTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`}}]); \ No newline at end of file diff --git a/assets/js/73512cb1.66b7c61b.js b/assets/js/73512cb1.66b7c61b.js new file mode 100644 index 0000000000..7da91bf26c --- /dev/null +++ b/assets/js/73512cb1.66b7c61b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8897],{63259:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var t=s(74848),r=s(28453);const i={title:"Container registry for SCS standard implementation",type:"Decision Record",status:"Draft",track:"KaaS"},o=void 0,a={id:"scs-0218-v1-container-registry-for-scs-standard-implementation",title:"Container registry for SCS standard implementation",description:"Introduction",source:"@site/standards/scs-0218-v1-container-registry-for-scs-standard-implementation.md",sourceDirName:".",slug:"/scs-0218-v1-container-registry-for-scs-standard-implementation",permalink:"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Container registry for SCS standard implementation",type:"Decision Record",status:"Draft",track:"KaaS"},sidebar:"standards",previous:{title:"scs-0218: Container registry for SCS standard implementation",permalink:"/standards/kaas/scs-0218"},next:{title:"IAM Standards",permalink:"/standards/iam/"}},c={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Evaluated projects",id:"evaluated-projects",level:3},{value:"Deeper look into selected projects",id:"deeper-look-into-selected-projects",level:3},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2}];function l(e){const n={a:"a",h2:"h2",h3:"h3",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsx)(n.p,{children:"A container registry is an infrastructure service to enable storing and accessing container\nimages. Images can be pushed to the registry by e.g. Continuous integration pipelines and\nbe pulled from by runtime environments like Kubernetes clusters."}),"\n",(0,t.jsx)(n.p,{children:'In the standard document ["Requirements for container registries"], requirements for a\nregistry in the context of SCS were introduced. These are based on the principals, that\na usable project should be open source, active and feature-rich, especially with regard\nto security.'}),"\n",(0,t.jsx)(n.h2,{id:"terminology",children:"Terminology"}),"\n",(0,t.jsx)(n.p,{children:"Cloud Service Provider (abbr. CSP)\nEntity that provides scalable computing resources"}),"\n",(0,t.jsx)(n.p,{children:"Cloud Native Computing Foundation (abbr. CNCF)\nOrganization that hosts and develops open source projects for cloud native computing"}),"\n",(0,t.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,t.jsxs)(n.p,{children:['In order to provide a usable, complete experience for the SCS reference implementation, it must be decided\non a registry in accordance with requirements set by the ["Requirements for container registries"] standard\nas well as other dependencies set by the SCS project, including the ',(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Drafts/OSS-Health.md",children:"OSS requirements"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"This document should finally lead to a decision about the container registry used as a reference implementation of the SCS container registry."}),"\n",(0,t.jsx)(n.h3,{id:"evaluated-projects",children:"Evaluated projects"}),"\n",(0,t.jsxs)(n.p,{children:["A few open source projects were evaluated for this document in order to find suitable candidates\nfor the SCS reference implementation. These projects can be found in the following list of\nevaluated projects with their classified categories and comments. An initial assessment was\ndone with the checks for ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Drafts/OSS-Health.md",children:"OSS healthiness"}),'\nand a general overview of the features described in ["Requirements for container registries"], which enables\nclassifying the projects into one of three categories as follows:']}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["\u2714\ufe0f"," The project passed all OSS health checks and will be considered\nfurther as a valid candidate."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["\u2754"," The project passed almost all OSS health checks.\nThere is place for improvement, but the missing points are not crucial from the OSS\nhealth check perspective. The project will be considered further as a valid candidate."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["\u274c"," The project does not pass the OSS health checks. Some OSS health check\nshowstoppers have been found (e.g. open core software, not actively maintained).\nThe project is filtered at this stage and won't be considered further."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The following list contains these projects with a small assessment listed below them:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["\u2714\ufe0f"," ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor",children:"Harbor"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:['Harbor project meets all "four opens"',"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Source code is open and available under the ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor/blob/main/LICENSE",children:"Apache 2 license"})]}),"\n",(0,t.jsxs)(n.li,{children:["Community is ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor#community",children:"open"}),", structured and\nwell organized via ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/community",children:"workgroups"})," and\nvarious communications channels e.g. Slack, mailing lists, etc.\n(#harbor Slack channel contains 3k+ members)"]}),"\n",(0,t.jsxs)(n.li,{children:["The development process is open via GitHub issues and well described in the\n",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor/blob/main/CONTRIBUTING.md",children:"contributing"}),"\ndocument"]}),"\n",(0,t.jsxs)(n.li,{children:["The design process is open via GitHub issues. Proposals are ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/community/tree/main/proposals",children:"public"}),".\nThe decision process is well described as well. The project's roadmap is\navailable in the ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor/blob/main/ROADMAP.md",children:"roadmap"})," document"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Maturity is on the CNCF ",(0,t.jsx)(n.a,{href:"https://www.cncf.io/projects/harbor/",children:"graduation"})," level.\nCNCF graduated projects are considered to be stable, widely adopted and production-ready"]}),"\n",(0,t.jsxs)(n.li,{children:["Security","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The security disclosure and response policy is well described in the project's\n",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor/blob/main/SECURITY.md",children:"security"})," document"]}),"\n",(0,t.jsx)(n.li,{children:"The code is reviewed within a standard PR process"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Activity","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"250+ contributors, 4k+ forks, 13k+ GitHub stars"}),"\n",(0,t.jsxs)(n.li,{children:["The project has been ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor/blob/main/ADOPTERS.md",children:"adopted"}),"\nby many companies that run Harbor in their production environments"]}),"\n",(0,t.jsxs)(n.li,{children:["The project collaborates with other communities and projects\n(see ",(0,t.jsx)(n.a,{href:"https://goharbor.io/community/",children:"Partners of Harbor"})," section of the\nproject's website)"]}),"\n",(0,t.jsxs)(n.li,{children:["The project is visible and actively contributes to various conferences, e.g.\n",(0,t.jsx)(n.a,{href:"https://goharbor.io/blog/harbor-at-fosdem-2022/",children:"FOSDEM 22"}),",\n",(0,t.jsx)(n.a,{href:"https://www.youtube.com/watch?v=REgvBPH369M",children:"KubeCon Europe"}),", etc."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Lock-in risk assessment","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The project's ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/community/blob/main/MAINTAINERS.md",children:"maintainers"}),"\ndocument shows that there are a sufficient number of core\nmaintainers/contributors that differ over various companies, we therefore deem\nthe lock-in risk arising from a single point of failure to be low"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["\u2714\ufe0f"," ",(0,t.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2",children:"Dragonfly"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:['Dragonfly project meets all "four opens"',"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Source code is open and available under the ",(0,t.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2/blob/main/LICENSE",children:"Apache 2 license"})]}),"\n",(0,t.jsxs)(n.li,{children:["Community is ",(0,t.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2#community",children:"open"}),"\norganized via multiple channels e.g. Slack, mailing lists, etc.\n(#dragonfly Slack channel contains ~50 members)"]}),"\n",(0,t.jsxs)(n.li,{children:["The development process is open via GitHub issues and well described in the\n",(0,t.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2/blob/main/CONTRIBUTING.md",children:"contributing"})," document"]}),"\n",(0,t.jsxs)(n.li,{children:["The design process is open via GitHub issues. The project's roadmap is available in\nthe project's ",(0,t.jsx)(n.a,{href:"https://d7y.io/docs/others/roadmap/#2022-roadmap",children:"webpage"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Maturity is on the CNCF ",(0,t.jsx)(n.a,{href:"https://www.cncf.io/projects/dragonfly/",children:"incubating"})," level\nCNCF incubating project is considered stable and used in production by users with\nthe healthy pool of contributors"]}),"\n",(0,t.jsxs)(n.li,{children:["Security","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The security disclosure is handled via a dedicated email address"}),"\n",(0,t.jsx)(n.li,{children:"The code is reviewed within a standard PR process"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Activity","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"30+ contributors, 100+ forks, 1k+ GitHub stars"}),"\n",(0,t.jsxs)(n.li,{children:["The project has been ",(0,t.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2/blob/main/ADOPTERS.md",children:"adopted"}),"\nby many companies that run Harbor in their production environments"]}),"\n",(0,t.jsxs)(n.li,{children:["The project is visible and actively contributes to various conferences,\ne.g. ",(0,t.jsx)(n.a,{href:"https://www.youtube.com/watch?v=LcxBgmmeA80",children:"KubeCon North America"}),",\n",(0,t.jsx)(n.a,{href:"https://www.youtube.com/watch?v=MGNtPHQYP14",children:"KubeCon Europe"}),", etc."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Lock-in risk assessment","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The list of the project's ",(0,t.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2/blob/main/MAINTAINERS.md",children:"maintainers"}),"\nincludes contributors from various companies and the ",(0,t.jsx)(n.a,{href:"https://dragonfly.devstats.cncf.io/d/7/companies-contributing-in-repository-groups",children:"companies contributing dashboard"}),"\nshows that ~10 companies are actively contributing to a repository group"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["\u2754"," ",(0,t.jsx)(n.a,{href:"https://github.com/quay/quay",children:"Project Quay"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:['Project Quay meets all "four opens"',"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Source code is open and available under the ",(0,t.jsx)(n.a,{href:"https://github.com/quay/quay/blob/master/LICENSE",children:"Apache 2 license"})]}),"\n",(0,t.jsxs)(n.li,{children:["Community is ",(0,t.jsx)(n.a,{href:"https://github.com/quay/quay#community",children:"open"})," organized via mailing\nlist and IRC"]}),"\n",(0,t.jsxs)(n.li,{children:["Development process is open via ",(0,t.jsx)(n.a,{href:"https://issues.redhat.com/projects/PROJQUAY/issues",children:"JBoss JIRA"}),"\nissues and well described in the ",(0,t.jsx)(n.a,{href:"https://github.com/quay/quay/blob/master/GOVERNANCE.md",children:"governance"})," document"]}),"\n",(0,t.jsxs)(n.li,{children:["Design process is open via ",(0,t.jsx)(n.a,{href:"https://issues.redhat.com/projects/PROJQUAY/issues",children:"JBoss JIRA"}),"\nissues. The project's roadmap is available on the project's ",(0,t.jsx)(n.a,{href:"https://www.projectquay.io/#contribute",children:"webpage"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Maturity","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Project Quay is an open-source project that started ",(0,t.jsx)(n.a,{href:"https://github.com/quay/quay/commit/0349af754204375d74ac5833713b607398981ff7",children:"~9 years ago"}),".\nIt powers Red Hat enterprise products Red Hat Quay and Quay.io, which are used in\na productive way by many. Therefore, the project's maturity is at the good level"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Security","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The security disclosure is handled via a dedicated email address"}),"\n",(0,t.jsx)(n.li,{children:"The code is reviewed within a standard PR process"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Activity","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"50+ contributors, 200+ forks, 2k+ GitHub stars"}),"\n",(0,t.jsxs)(n.li,{children:["The project has been used by many ",(0,t.jsx)(n.a,{href:"https://www.projectquay.io",children:"companies"})," that\nrun Quay in their production environments"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Lock-in risk assessment","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The project's owners/maintainers list is not publicly available and is stored in\nthe ",(0,t.jsx)(n.a,{href:"https://github.com/quay/quay-docs#how-do-i-set-up",children:"downstream repository"}),".\nTherefore, it is hard to distinguish the risk of project failure caused by low\ndiversity across the companies. This should be improved."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["\u274c"," ",(0,t.jsx)(n.a,{href:"https://github.com/sapcc/keppel",children:"Keppel"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The project seems to be not widely used in a productive way and also the activity\naround is currently not on a good level (5+ contributors). The development\nprocess as well as the design process seem to be open, but neither of them are\ndocumented yet."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["\u274c"," ",(0,t.jsx)(n.a,{href:"https://github.com/sonatype/nexus-public",children:"Nexus"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Nexus is an ",(0,t.jsx)(n.strong,{children:"open core"})," software that offers paid ",(0,t.jsx)(n.a,{href:"https://www.sonatype.com/products/repository-oss-vs-pro-features",children:"pro version"})," with advanced features"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["\u274c"," ",(0,t.jsx)(n.a,{href:"https://jfrog.com/community/open-source/",children:"JFrog"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["JFrog Artifactory is shipped as an ",(0,t.jsx)(n.strong,{children:"open core"})," ",(0,t.jsx)(n.a,{href:"https://jfrog.com/community/open-source/",children:"software"}),"\nwith limited features. The software is primarily offered as a paid ",(0,t.jsx)(n.a,{href:"https://jfrog.com/pricing/#devops-onprem",children:"pro version"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["\u274c"," ",(0,t.jsx)(n.a,{href:"https://github.com/uber/kraken",children:"Kraken"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["It seems that the project is not actively maintained as is discussed in the related\nproject's ",(0,t.jsx)(n.a,{href:"https://github.com/uber/kraken/issues/313",children:"issue"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["\u274c"," ",(0,t.jsx)(n.a,{href:"https://github.com/SUSE/Portus",children:"Portus"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["It seems that the project is not actively maintained as is discussed in the related\nproject's ",(0,t.jsx)(n.a,{href:"https://github.com/SUSE/Portus/issues/2352",children:"issue"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"deeper-look-into-selected-projects",children:"Deeper look into selected projects"}),"\n",(0,t.jsx)(n.p,{children:"In the previous section, a wide range of open-source container registry projects (Quay, Harbor, Dragonfly,\nKeppel, Portus, Kraken, etc.) has been carefully evaluated based on the two main\nfactors: the open-source health and range of supported features."}),"\n",(0,t.jsx)(n.p,{children:"The open-source software health is crucial and container registry implementation should\npass it. It evaluates several important metrics of an open source software like whether the code/community/development/design\nis fully open or whether the project's maturity, security, and activity are on the desired\nlevel. This check also evaluates the lock-in risk due to possible single points of\nfailure or internal project conflicts and several other aspects.\nOverall, three projects passed the OSS health checks:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor",children:"Harbor"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/quay/quay",children:"Project Quay"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/quay/quay",children:"Dragonfly"})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:'The above projects were then evaluated from the "supported features" perspective.\nThe document ["Requirements for container registries"] provides a "Required and desirable features check", which\nprovides desired feature sets for open-source container registry implementations according to\nSCS requirements (and nice-to-haves). The list of required features is quite long and contains\nfeatures that are primarily focused on security (authentication, vulnerability scanning, content trust, and validation, etc.),\nscalability (HA mode, registry replication, p2p integration, etc.) and visibility (monitoring).\nThese requirements should ensure that the selected container registry implementation\ncould be offered by CSPs as a secure and enterprise-ready solution.'}),"\n",(0,t.jsx)(n.p,{children:"The following section compares the selected projects Dragonfly, Quay, and Harbor."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2",children:"Dragonfly"}),' is a healthy open-source project with a growing community\nand CNCF incubating maturity level. It is considered stable, and widely used by many\ncompanies in their production environments. We currently see that it is not as\nfeature-rich as Harbor or Quay, hence it is not considered the best choice here.\nIt seems, that its main aim (currently) is to offer (an efficient, stable, and secure)\ncontainer distribution solution based on p2p technology. This improves download\nefficiency and saves bandwidth across CSPs. It also offers integration possibilities\nthat allow one to use it as a p2p distribution network via a "preheat" API. This\nintegration was implemented in the Harbor project via Dragonfly "preheat" adapter, and\nboth parties may benefit from the integration. Harbor profits from Dragonfly\'s p2p\ndistribution capabilities and on the other hand the Dragonfly project profits from\nHarbor\'s feature-rich container registry "frontend".']}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://github.com/quay/quay",children:"Quay"})," is an open-source project maintained by Red Hat. Its OSS health is\non a good level, the surrounding community is growing, and we consider it to be quite\nmature as it powers enterprise solutions like Red Hat Quay and Quay.io.\nBesides this, there is still a place for OSS health improvement. It is hard to\ndistinguish the risk of project failure caused by low diversity across the companies\nbecause the project's owners/maintainers list is not publicly available and is stored in\nthe Red Hat private repository.\nIts feature set is impressive and this project fulfills all must-haves defined in\nthis document. Quay gives you security over your repositories with image\nvulnerability scanning (Clair integration), content validation (Cosign integration),\nand access controls. Harbor stands out here as it allows users to use also project Trivy\nfor vulnerability scanning. Project Quay also provides a scalable open-source\nplatform to host container images across any size organization. One drawback in\ncomparison to Harbor is that the proxy cache feature is still marked as a\n",(0,t.jsx)(n.a,{href:"https://docs.projectquay.io/use_quay.html#quay-as-cache-proxy",children:"Technology Preview"}),",\nhence this feature may not be completely production-ready yet. On the other hand,\nthe project Quay supports ",(0,t.jsx)(n.a,{href:"https://docs.projectquay.io/use_quay.html#build-support",children:"building Dockerfiles"}),"\nusing a set of workers on e.g. Kubernetes. Build triggers, such as GitHub webhooks\ncan be configured to automatically build new versions of repositories when new code is\ncommitted. This feature is not supported by the ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor/issues/6235",children:"Harbor project"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor",children:"Harbor"})," is an outstanding open-source, community-led project with fully open and\nwell-documented processes. Its large and thriving community powers the fast-growing\nfeature set and attracts more and more developers and companies to active contributions.\nHarbor's CNCF graduation in 2020 made it one of the best choices for enterprise\ncustomers that want to operate container registries securely and in a large scale.\nIts community size, landscape, and CNCF graduation make a significant difference in\ncomparison to Quay's open-source health capabilities.\nThe list of supported features is also impressive. This project fulfills all must-haves\ndefined in this document and overcome project Quay with a production-ready proxy cache\nfeature and more options that the user may use in case of image vulnerability scanning.\nIn addition, Harbor profits from p2p distribution capabilities via integration of p2p\nsolutions like Kraken and Dragonfly. It is worth mentioning that Harbor, by design,\noperates on a single storage backend (e.g. S3). It means that the storage of container\nimages is shared even when the Harbor instance serves multiple tenants. The same\napproach is used in Quay and Dragonfly projects, but e.g. Keppel uses multi-tenant-aware\nstorage drivers instead so that each customer gets their own separate storage backend.\nCSP that considers offering container registry \"as a service\" solution based on Harbor\nshould be aware of this shared storage backend architecture."]}),"\n",(0,t.jsx)(n.p,{children:"In the following table, the feature sets of the evaluated projects that passed the OSS health state\nare listed and matched against. This enables a better understanding of the decision-making for this document."}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Features"}),(0,t.jsx)(n.th,{children:"Harbor"}),(0,t.jsx)(n.th,{children:"Quay"}),(0,t.jsx)(n.th,{children:"Dragonfly"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Audit Logs"}),(0,t.jsx)(n.td,{children:"\u2713"}),(0,t.jsx)(n.td,{children:"\u2713"}),(0,t.jsx)(n.td,{children:"\u2717"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Authentication of system identities"}),(0,t.jsx)(n.td,{children:"\u2713 Robot Accounts"}),(0,t.jsx)(n.td,{children:"\u2713 Robot Accounts"}),(0,t.jsx)(n.td,{children:"\u2717"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Authentication of users"}),(0,t.jsx)(n.td,{children:"\u2713 Local database, LDAP, OIDC, UAA"}),(0,t.jsx)(n.td,{children:"\u2713 Local database, LDAP, Keystone, JWT"}),(0,t.jsx)(n.td,{children:"\u2713 Local database"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Authorization"}),(0,t.jsx)(n.td,{children:"\u2713"}),(0,t.jsx)(n.td,{children:"\u2713"}),(0,t.jsx)(n.td,{children:"\u2713"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Automation"}),(0,t.jsx)(n.td,{children:"\u2713 Webhooks (HTTP, Slack)"}),(0,t.jsx)(n.td,{children:"\u2713 Webhooks (HTTP, Slack, E-mail ...), building images"}),(0,t.jsx)(n.td,{children:"\u2717"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Vulnerability scanning"}),(0,t.jsx)(n.td,{children:"\u2713 Trivy, Clair"}),(0,t.jsx)(n.td,{children:"\u2713 Clair"}),(0,t.jsx)(n.td,{children:"\u2717"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Content Trust and Validation"}),(0,t.jsx)(n.td,{children:"\u2713 Cosign"}),(0,t.jsx)(n.td,{children:"\u2713 Cosign"}),(0,t.jsx)(n.td,{children:"\u2717"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Multi-tenancy"}),(0,t.jsx)(n.td,{children:"\u2713 (not on the storage level)"}),(0,t.jsx)(n.td,{children:"\u2713 (not on the storage level)"}),(0,t.jsx)(n.td,{children:"\u2713 (not on the storage level)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Backup and restore"}),(0,t.jsx)(n.td,{children:"\u2713"}),(0,t.jsx)(n.td,{children:"\u2713"}),(0,t.jsx)(n.td,{children:"\u2717"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Monitoring"}),(0,t.jsx)(n.td,{children:"\u2713 Prometheus metrics, Tracing"}),(0,t.jsx)(n.td,{children:"\u2713 Prometheus metrics, Tracing (only for Clair)"}),(0,t.jsx)(n.td,{children:"\u2713 Prometheus metrics, Tracing"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"HA mode"}),(0,t.jsx)(n.td,{children:"\u2713"}),(0,t.jsx)(n.td,{children:"\u2713"}),(0,t.jsx)(n.td,{children:"\u2717"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Registry replication"}),(0,t.jsx)(n.td,{children:"\u2713"}),(0,t.jsx)(n.td,{children:"\u2713"}),(0,t.jsx)(n.td,{children:"\u2713"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Proxy cache"}),(0,t.jsx)(n.td,{children:"\u2713"}),(0,t.jsx)(n.td,{children:"\u2713 Feature is in the technology preview stage (non production ready)"}),(0,t.jsx)(n.td,{children:"\u2717"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Quota management"}),(0,t.jsx)(n.td,{children:"\u2713 Based on storage consumption"}),(0,t.jsx)(n.td,{children:"\u2713 Based on storage consumption"}),(0,t.jsx)(n.td,{children:"\u2717"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Garbage collection"}),(0,t.jsx)(n.td,{children:"\u2713 Non-blocking"}),(0,t.jsx)(n.td,{children:"\u2713 Non-blocking"}),(0,t.jsx)(n.td,{children:"\u2717"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Retention policy"}),(0,t.jsx)(n.td,{children:"\u2713 Multiple tag retention rules"}),(0,t.jsx)(n.td,{children:"\u2713 Only tag expiration rules"}),(0,t.jsx)(n.td,{children:"\u2717"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Additional supported artifacts"}),(0,t.jsx)(n.td,{children:"\u2717 (only OCI artifacts)"}),(0,t.jsx)(n.td,{children:"\u2717 (only OCI artifacts)"}),(0,t.jsx)(n.td,{children:"\u2713 Maven, YUM"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Integration possibilities"}),(0,t.jsx)(n.td,{children:"\u2713 Dragonfly (P2P), Kraken (P2P)"}),(0,t.jsx)(n.td,{children:"\u2717"}),(0,t.jsx)(n.td,{children:"\u2713 Harbor, Nydus, eStargz"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Deployment capabilities"}),(0,t.jsx)(n.td,{children:"\u2713 Docker-compose, Helm chart, Operator"}),(0,t.jsx)(n.td,{children:"\u2713 Docker-compose, Operator"}),(0,t.jsx)(n.td,{children:"\u2713 Docker-compose, Helm chart"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Administration capabilities"}),(0,t.jsx)(n.td,{children:"\u2713 Terraform, CRDs, Client libraries"}),(0,t.jsx)(n.td,{children:"\u2713 Ansible, Client libraries"}),(0,t.jsx)(n.td,{children:"\u2713 Client libraries"})]})]})]}),"\n",(0,t.jsx)(n.p,{children:"Notes:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Automation: Harbor should support webhooks following CloudEvents spec in the ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor/issues/17748",children:"next release"})]}),"\n",(0,t.jsxs)(n.li,{children:["Content Trust and Validation: Harbor announced the deprecation of ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor/discussions/16612",children:"Notary"}),"\nintegration, hence it is not mentioned in the table"]}),"\n",(0,t.jsx)(n.li,{children:"Multi-tenancy: Harbor, Quay, as well as Dragonfly, operates on a single storage\nbackend (e.g. S3), i.e. the storage of container images is shared between tenants"}),"\n",(0,t.jsxs)(n.li,{children:["Additional supported artifacts: Harbor announced the deprecation of ",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor/discussions/15057",children:"Chartmuseum"}),"\nintegration, hence it is not mentioned in the table"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,t.jsxs)(n.p,{children:['Based on the requirements laid out in ["Requirements for container registries"], the OSS health check\nand the possible software solutions presented in this document, it was decided to use the ',(0,t.jsx)(n.strong,{children:"Harbor"})," project\nas the container registry for the SCS reference implementation."]}),"\n",(0,t.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/standards/scs-0212-v1-requirements-for-container-registries",children:'"Requirements for container registries"'}),"\n",(0,t.jsx)(n.a,{href:"https://github.com/goharbor/harbor",children:"harbor"}),"\n",(0,t.jsx)(n.a,{href:"https://github.com/dragonflyoss/Dragonfly2",children:"dragonfly"}),"\n",(0,t.jsx)(n.a,{href:"https://github.com/quay/quay",children:"projectquay"})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/73956345.5376df3f.js b/assets/js/73956345.5376df3f.js new file mode 100644 index 0000000000..3075e96dce --- /dev/null +++ b/assets/js/73956345.5376df3f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6083],{11009:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>u});var n=o(74848),r=o(28453);const s={},c="Compute",i={id:"iaas/overview/compute",title:"Compute",description:"TODO",source:"@site/docs/02-iaas/overview/compute.md",sourceDirName:"02-iaas/overview",slug:"/iaas/overview/compute",permalink:"/docs/iaas/overview/compute",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/overview/compute.md",tags:[],version:"current",frontMatter:{}},a={},u=[];function p(e){const t={h1:"h1",p:"p",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"compute",children:"Compute"}),"\n",(0,n.jsx)(t.p,{children:"TODO"})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},28453:(e,t,o)=>{o.d(t,{R:()=>c,x:()=>i});var n=o(96540);const r={},s=n.createContext(r);function c(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/739c0ae8.72f072ee.js b/assets/js/739c0ae8.72f072ee.js new file mode 100644 index 0000000000..baf45c27b9 --- /dev/null +++ b/assets/js/739c0ae8.72f072ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4807],{7084:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>u});var n=o(74848),s=o(28453);const a={},r="Gateway-API",i={id:"container/components/k8s-cluster-api-provider/doc/usage/gateway-api",title:"Gateway-API",description:"Starting with R5, this k8s-solution offers experimental kubernetes gateway API support. You need to set deploygatewayapi to true in your environments configuration. Also you need to use cilium as your CNI (default since R5).",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/gateway-api.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc/usage",slug:"/container/components/k8s-cluster-api-provider/doc/usage/gateway-api",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/usage/gateway-api.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Custom CA",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca"},next:{title:"Harbor",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor"}},c={},u=[];function p(e){const t={code:"code",h1:"h1",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"gateway-api",children:"Gateway-API"}),"\n",(0,n.jsxs)(t.p,{children:["Starting with R5, this k8s-solution offers experimental kubernetes gateway API support. You need to set ",(0,n.jsx)(t.code,{children:"deploy_gateway_api"})," to ",(0,n.jsx)(t.code,{children:"true"})," in your environments configuration. Also you need to use cilium as your CNI (default since R5)."]}),"\n",(0,n.jsx)(t.p,{children:"After deploying your cluster, you can use gateway API and deploy Gateways and HTTP-Routes. As a starting point you can deploy this example app:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/bookinfo/platform/kube/bookinfo.yaml\n"})}),"\n",(0,n.jsx)(t.p,{children:"and this example Gateway and HTTP-Route"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.15.1/examples/kubernetes/gateway/basic-http.yaml\n"})})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},28453:(e,t,o)=>{o.d(t,{R:()=>r,x:()=>i});var n=o(96540);const s={},a=n.createContext(s);function r(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/742db51e.eadccafc.js b/assets/js/742db51e.eadccafc.js new file mode 100644 index 0000000000..48548330ec --- /dev/null +++ b/assets/js/742db51e.eadccafc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8781],{68777:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>o});var n=s(74848),r=s(28453);const a={},i="scs-0218: Container registry for SCS standard implementation",d={id:"kaas/scs-0218",title:"scs-0218: Container registry for SCS standard implementation",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/kaas/scs-0218.md",sourceDirName:"kaas",slug:"/kaas/scs-0218",permalink:"/standards/kaas/scs-0218",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Kubernetes cluster baseline security",permalink:"/standards/scs-0217-v1-baseline-cluster-security"},next:{title:"Container registry for SCS standard implementation",permalink:"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation"}},c={},o=[];function l(t){const e={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"scs-0218-container-registry-for-scs-standard-implementation",children:"scs-0218: Container registry for SCS standard implementation"}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:"Version"}),(0,n.jsx)(e.th,{children:"Type"}),(0,n.jsx)(e.th,{children:"State"}),(0,n.jsx)(e.th,{children:"stabilized"}),(0,n.jsx)(e.th,{children:"deprecated"})]})}),(0,n.jsx)(e.tbody,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation",children:"scs-0218-v1"})}),(0,n.jsx)(e.td,{children:"Decision Record"}),(0,n.jsx)(e.td,{children:"Draft"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]})})]})]})}function h(t={}){const{wrapper:e}={...(0,r.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(l,{...t})}):l(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>i,x:()=>d});var n=s(96540);const r={},a=n.createContext(r);function i(t){const e=n.useContext(a);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function d(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:i(t.components),n.createElement(a.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/7440.1c1d16a2.js b/assets/js/7440.1c1d16a2.js new file mode 100644 index 0000000000..d1280850e4 --- /dev/null +++ b/assets/js/7440.1c1d16a2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7440],{7440:(t,n,e)=>{e.d(n,{diagram:()=>H});var i=e(76257),s=e(26312);function r(t,n){let e;if(void 0===n)for(const i of t)null!=i&&(e>i||void 0===e&&i>=i)&&(e=i);else{let i=-1;for(let s of t)null!=(s=n(s,++i,t))&&(e>s||void 0===e&&s>=s)&&(e=s)}return e}function o(t){return t.target.depth}function c(t,n){return t.sourceLinks.length?t.depth:n-1}function l(t,n){let e=0;if(void 0===n)for(let i of t)(i=+i)&&(e+=i);else{let i=-1;for(let s of t)(s=+n(s,++i,t))&&(e+=s)}return e}function h(t,n){let e;if(void 0===n)for(const i of t)null!=i&&(e<i||void 0===e&&i>=i)&&(e=i);else{let i=-1;for(let s of t)null!=(s=n(s,++i,t))&&(e<s||void 0===e&&s>=s)&&(e=s)}return e}function a(t){return function(){return t}}function u(t,n){return y(t.source,n.source)||t.index-n.index}function f(t,n){return y(t.target,n.target)||t.index-n.index}function y(t,n){return t.y0-n.y0}function d(t){return t.value}function p(t){return t.index}function g(t){return t.nodes}function _(t){return t.links}function x(t,n){const e=t.get(n);if(!e)throw new Error("missing: "+n);return e}function k({nodes:t}){for(const n of t){let t=n.y0,e=t;for(const i of n.sourceLinks)i.y0=t+i.width/2,t+=i.width;for(const i of n.targetLinks)i.y1=e+i.width/2,e+=i.width}}function m(){let t,n,e,i=0,s=0,o=1,m=1,v=24,b=8,w=p,L=c,E=g,A=_,S=6;function M(){const c={nodes:E.apply(null,arguments),links:A.apply(null,arguments)};return function({nodes:t,links:n}){for(const[e,s]of t.entries())s.index=e,s.sourceLinks=[],s.targetLinks=[];const i=new Map(t.map(((n,e)=>[w(n,e,t),n])));for(const[e,s]of n.entries()){s.index=e;let{source:t,target:n}=s;"object"!=typeof t&&(t=s.source=x(i,t)),"object"!=typeof n&&(n=s.target=x(i,n)),t.sourceLinks.push(s),n.targetLinks.push(s)}if(null!=e)for(const{sourceLinks:s,targetLinks:r}of t)s.sort(e),r.sort(e)}(c),function({nodes:t}){for(const n of t)n.value=void 0===n.fixedValue?Math.max(l(n.sourceLinks,d),l(n.targetLinks,d)):n.fixedValue}(c),function({nodes:t}){const n=t.length;let e=new Set(t),i=new Set,s=0;for(;e.size;){for(const t of e){t.depth=s;for(const{target:n}of t.sourceLinks)i.add(n)}if(++s>n)throw new Error("circular link");e=i,i=new Set}}(c),function({nodes:t}){const n=t.length;let e=new Set(t),i=new Set,s=0;for(;e.size;){for(const t of e){t.height=s;for(const{source:n}of t.targetLinks)i.add(n)}if(++s>n)throw new Error("circular link");e=i,i=new Set}}(c),function(e){const c=function({nodes:t}){const e=h(t,(t=>t.depth))+1,s=(o-i-v)/(e-1),r=new Array(e);for(const n of t){const t=Math.max(0,Math.min(e-1,Math.floor(L.call(null,n,e))));n.layer=t,n.x0=i+t*s,n.x1=n.x0+v,r[t]?r[t].push(n):r[t]=[n]}if(n)for(const i of r)i.sort(n);return r}(e);t=Math.min(b,(m-s)/(h(c,(t=>t.length))-1)),function(n){const e=r(n,(n=>(m-s-(n.length-1)*t)/l(n,d)));for(const i of n){let n=s;for(const s of i){s.y0=n,s.y1=n+s.value*e,n=s.y1+t;for(const t of s.sourceLinks)t.width=t.value*e}n=(m-n+t)/(i.length+1);for(let t=0;t<i.length;++t){const e=i[t];e.y0+=n*(t+1),e.y1+=n*(t+1)}N(i)}}(c);for(let t=0;t<S;++t){const n=Math.pow(.99,t),e=Math.max(1-n,(t+1)/S);T(c,n,e),I(c,n,e)}}(c),k(c),c}function I(t,e,i){for(let s=1,r=t.length;s<r;++s){const r=t[s];for(const t of r){let n=0,i=0;for(const{source:e,value:r}of t.targetLinks){let s=r*(t.layer-e.layer);n+=$(e,t)*s,i+=s}if(!(i>0))continue;let s=(n/i-t.y0)*e;t.y0+=s,t.y1+=s,P(t)}void 0===n&&r.sort(y),O(r,i)}}function T(t,e,i){for(let s=t.length-2;s>=0;--s){const r=t[s];for(const t of r){let n=0,i=0;for(const{target:e,value:r}of t.sourceLinks){let s=r*(e.layer-t.layer);n+=j(t,e)*s,i+=s}if(!(i>0))continue;let s=(n/i-t.y0)*e;t.y0+=s,t.y1+=s,P(t)}void 0===n&&r.sort(y),O(r,i)}}function O(n,e){const i=n.length>>1,r=n[i];D(n,r.y0-t,i-1,e),C(n,r.y1+t,i+1,e),D(n,m,n.length-1,e),C(n,s,0,e)}function C(n,e,i,s){for(;i<n.length;++i){const r=n[i],o=(e-r.y0)*s;o>1e-6&&(r.y0+=o,r.y1+=o),e=r.y1+t}}function D(n,e,i,s){for(;i>=0;--i){const r=n[i],o=(r.y1-e)*s;o>1e-6&&(r.y0-=o,r.y1-=o),e=r.y0-t}}function P({sourceLinks:t,targetLinks:n}){if(void 0===e){for(const{source:{sourceLinks:t}}of n)t.sort(f);for(const{target:{targetLinks:n}}of t)n.sort(u)}}function N(t){if(void 0===e)for(const{sourceLinks:n,targetLinks:e}of t)n.sort(f),e.sort(u)}function $(n,e){let i=n.y0-(n.sourceLinks.length-1)*t/2;for(const{target:s,width:r}of n.sourceLinks){if(s===e)break;i+=r+t}for(const{source:t,width:s}of e.targetLinks){if(t===n)break;i-=s}return i}function j(n,e){let i=e.y0-(e.targetLinks.length-1)*t/2;for(const{source:s,width:r}of e.targetLinks){if(s===n)break;i+=r+t}for(const{target:t,width:s}of n.sourceLinks){if(t===e)break;i-=s}return i}return M.update=function(t){return k(t),t},M.nodeId=function(t){return arguments.length?(w="function"==typeof t?t:a(t),M):w},M.nodeAlign=function(t){return arguments.length?(L="function"==typeof t?t:a(t),M):L},M.nodeSort=function(t){return arguments.length?(n=t,M):n},M.nodeWidth=function(t){return arguments.length?(v=+t,M):v},M.nodePadding=function(n){return arguments.length?(b=t=+n,M):b},M.nodes=function(t){return arguments.length?(E="function"==typeof t?t:a(t),M):E},M.links=function(t){return arguments.length?(A="function"==typeof t?t:a(t),M):A},M.linkSort=function(t){return arguments.length?(e=t,M):e},M.size=function(t){return arguments.length?(i=s=0,o=+t[0],m=+t[1],M):[o-i,m-s]},M.extent=function(t){return arguments.length?(i=+t[0][0],o=+t[1][0],s=+t[0][1],m=+t[1][1],M):[[i,s],[o,m]]},M.iterations=function(t){return arguments.length?(S=+t,M):S},M}var v=Math.PI,b=2*v,w=1e-6,L=b-w;function E(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function A(){return new E}E.prototype=A.prototype={constructor:E,moveTo:function(t,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,n){this._+="L"+(this._x1=+t)+","+(this._y1=+n)},quadraticCurveTo:function(t,n,e,i){this._+="Q"+ +t+","+ +n+","+(this._x1=+e)+","+(this._y1=+i)},bezierCurveTo:function(t,n,e,i,s,r){this._+="C"+ +t+","+ +n+","+ +e+","+ +i+","+(this._x1=+s)+","+(this._y1=+r)},arcTo:function(t,n,e,i,s){t=+t,n=+n,e=+e,i=+i,s=+s;var r=this._x1,o=this._y1,c=e-t,l=i-n,h=r-t,a=o-n,u=h*h+a*a;if(s<0)throw new Error("negative radius: "+s);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=n);else if(u>w)if(Math.abs(a*c-l*h)>w&&s){var f=e-r,y=i-o,d=c*c+l*l,p=f*f+y*y,g=Math.sqrt(d),_=Math.sqrt(u),x=s*Math.tan((v-Math.acos((d+u-p)/(2*g*_)))/2),k=x/_,m=x/g;Math.abs(k-1)>w&&(this._+="L"+(t+k*h)+","+(n+k*a)),this._+="A"+s+","+s+",0,0,"+ +(a*f>h*y)+","+(this._x1=t+m*c)+","+(this._y1=n+m*l)}else this._+="L"+(this._x1=t)+","+(this._y1=n);else;},arc:function(t,n,e,i,s,r){t=+t,n=+n,r=!!r;var o=(e=+e)*Math.cos(i),c=e*Math.sin(i),l=t+o,h=n+c,a=1^r,u=r?i-s:s-i;if(e<0)throw new Error("negative radius: "+e);null===this._x1?this._+="M"+l+","+h:(Math.abs(this._x1-l)>w||Math.abs(this._y1-h)>w)&&(this._+="L"+l+","+h),e&&(u<0&&(u=u%b+b),u>L?this._+="A"+e+","+e+",0,1,"+a+","+(t-o)+","+(n-c)+"A"+e+","+e+",0,1,"+a+","+(this._x1=l)+","+(this._y1=h):u>w&&(this._+="A"+e+","+e+",0,"+ +(u>=v)+","+a+","+(this._x1=t+e*Math.cos(s))+","+(this._y1=n+e*Math.sin(s))))},rect:function(t,n,e,i){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)+"h"+ +e+"v"+ +i+"h"+-e+"Z"},toString:function(){return this._}};const S=A;var M=Array.prototype.slice;function I(t){return function(){return t}}function T(t){return t[0]}function O(t){return t[1]}function C(t){return t.source}function D(t){return t.target}function P(t){var n=C,e=D,i=T,s=O,r=null;function o(){var o,c=M.call(arguments),l=n.apply(this,c),h=e.apply(this,c);if(r||(r=o=S()),t(r,+i.apply(this,(c[0]=l,c)),+s.apply(this,c),+i.apply(this,(c[0]=h,c)),+s.apply(this,c)),o)return r=null,o+""||null}return o.source=function(t){return arguments.length?(n=t,o):n},o.target=function(t){return arguments.length?(e=t,o):e},o.x=function(t){return arguments.length?(i="function"==typeof t?t:I(+t),o):i},o.y=function(t){return arguments.length?(s="function"==typeof t?t:I(+t),o):s},o.context=function(t){return arguments.length?(r=null==t?null:t,o):r},o}function N(t,n,e,i,s){t.moveTo(n,e),t.bezierCurveTo(n=(n+i)/2,e,n,s,i,s)}function $(t){return[t.source.x1,t.y0]}function j(t){return[t.target.x0,t.y1]}function z(){return P(N).source($).target(j)}e(74353),e(16750),e(42838);var U=function(){var t=function(t,n,e,i){for(e=e||{},i=t.length;i--;e[t[i]]=n);return e},n=[1,9],e=[1,10],i=[1,5,10,12],s={trace:function(){},yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:function(t,n,e,i,s,r,o){var c=r.length-1;switch(s){case 7:const t=i.findOrCreateNode(r[c-4].trim().replaceAll('""','"')),n=i.findOrCreateNode(r[c-2].trim().replaceAll('""','"')),e=parseFloat(r[c].trim());i.addLink(t,n,e);break;case 8:case 9:case 11:this.$=r[c];break;case 10:this.$=r[c-1]}},table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:n,20:e},{1:[2,6],7:11,10:[1,12]},t(e,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(i,[2,8]),t(i,[2,9]),{19:[1,16]},t(i,[2,11]),{1:[2,1]},{1:[2,5]},t(e,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:n,20:e},{15:18,16:7,17:8,18:n,20:e},{18:[1,19]},t(e,[2,3]),{12:[1,20]},t(i,[2,10]),{15:21,16:7,17:8,18:n,20:e},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:function(t,n){if(!n.recoverable){var e=new Error(t);throw e.hash=n,e}this.trace(t)},parse:function(t){var n=this,e=[0],i=[],s=[null],r=[],o=this.table,c="",l=0,h=0,a=r.slice.call(arguments,1),u=Object.create(this.lexer),f={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(f.yy[y]=this.yy[y]);u.setInput(t,f.yy),f.yy.lexer=u,f.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var d=u.yylloc;r.push(d);var p=u.options&&u.options.ranges;"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var g,_,x,k,m,v,b,w,L,E={};;){if(_=e[e.length-1],this.defaultActions[_]?x=this.defaultActions[_]:(null==g&&(L=void 0,"number"!=typeof(L=i.pop()||u.lex()||1)&&(L instanceof Array&&(L=(i=L).pop()),L=n.symbols_[L]||L),g=L),x=o[_]&&o[_][g]),void 0===x||!x.length||!x[0]){var A="";for(m in w=[],o[_])this.terminals_[m]&&m>2&&w.push("'"+this.terminals_[m]+"'");A=u.showPosition?"Parse error on line "+(l+1)+":\n"+u.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[g]||g)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==g?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(A,{text:u.match,token:this.terminals_[g]||g,line:u.yylineno,loc:d,expected:w})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+g);switch(x[0]){case 1:e.push(g),s.push(u.yytext),r.push(u.yylloc),e.push(x[1]),g=null,h=u.yyleng,c=u.yytext,l=u.yylineno,d=u.yylloc;break;case 2:if(v=this.productions_[x[1]][1],E.$=s[s.length-v],E._$={first_line:r[r.length-(v||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(v||1)].first_column,last_column:r[r.length-1].last_column},p&&(E._$.range=[r[r.length-(v||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply(E,[c,h,l,f.yy,x[1],s,r].concat(a))))return k;v&&(e=e.slice(0,-1*v*2),s=s.slice(0,-1*v),r=r.slice(0,-1*v)),e.push(this.productions_[x[1]][0]),s.push(E.$),r.push(E._$),b=o[e[e.length-2]][e[e.length-1]],e.push(b);break;case 3:return!0}}return!0}},r={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===i.length?this.yylloc.first_column:0)+i[i.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"},test_match:function(t,n){var e,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,n,e,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((e=this._input.match(this.rules[s[r]]))&&(!n||e[0].length>n[0].length)){if(n=e,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,s[r])))return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?!1!==(t=this.test_match(n,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,n,e,i){switch(e){case 0:return this.pushState("csv"),4;case 1:return 10;case 2:return 5;case 3:return 12;case 4:return this.pushState("escaped_text"),18;case 5:return 20;case 6:return this.popState("escaped_text"),18;case 7:return 19}},rules:[/^(?:sankey-beta\b)/i,/^(?:$)/i,/^(?:((\u000D\u000A)|(\u000A)))/i,/^(?:(\u002C))/i,/^(?:(\u0022))/i,/^(?:([\u0020-\u0021\u0023-\u002B\u002D-\u007E])*)/i,/^(?:(\u0022)(?!(\u0022)))/i,/^(?:(([\u0020-\u0021\u0023-\u002B\u002D-\u007E])|(\u002C)|(\u000D)|(\u000A)|(\u0022)(\u0022))*)/i],conditions:{csv:{rules:[1,2,3,4,5,6,7],inclusive:!1},escaped_text:{rules:[6,7],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7],inclusive:!0}}};function o(){this.yy={}}return s.lexer=r,o.prototype=s,s.Parser=o,new o}();U.parser=U;const F=U;let W=[],q=[],G={};class V{constructor(t,n,e=0){this.source=t,this.target=n,this.value=e}}class X{constructor(t){this.ID=t}}const K={nodesMap:G,getConfig:()=>(0,i.c)().sankey,getNodes:()=>q,getLinks:()=>W,getGraph:()=>({nodes:q.map((t=>({id:t.ID}))),links:W.map((t=>({source:t.source.ID,target:t.target.ID,value:t.value})))}),addLink:(t,n,e)=>{W.push(new V(t,n,e))},findOrCreateNode:t=>(t=i.e.sanitizeText(t,(0,i.c)()),G[t]||(G[t]=new X(t),q.push(G[t])),G[t]),getAccTitle:i.g,setAccTitle:i.s,getAccDescription:i.a,setAccDescription:i.b,getDiagramTitle:i.t,setDiagramTitle:i.q,clear:()=>{W=[],q=[],G={},(0,i.v)()}},Q=class t{static next(n){return new t(n+ ++t.count)}constructor(t){this.id=t,this.href=`#${t}`}toString(){return"url("+this.href+")"}};Q.count=0;let Y=Q;const B={left:function(t){return t.depth},right:function(t,n){return n-1-t.height},center:function(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?r(t.sourceLinks,o)-1:0},justify:c},R={draw:function(t,n,e,r){const{securityLevel:o,sankey:c}=(0,i.c)(),l=i.K.sankey;let h;"sandbox"===o&&(h=(0,s.Ltv)("#i"+n));const a="sandbox"===o?(0,s.Ltv)(h.nodes()[0].contentDocument.body):(0,s.Ltv)("body"),u="sandbox"===o?a.select(`[id="${n}"]`):(0,s.Ltv)(`[id="${n}"]`),f=(null==c?void 0:c.width)??l.width,y=(null==c?void 0:c.height)??l.width,d=(null==c?void 0:c.useMaxWidth)??l.useMaxWidth,p=(null==c?void 0:c.nodeAlignment)??l.nodeAlignment,g=(null==c?void 0:c.prefix)??l.prefix,_=(null==c?void 0:c.suffix)??l.suffix,x=(null==c?void 0:c.showValues)??l.showValues,k=r.db.getGraph(),v=B[p];m().nodeId((t=>t.id)).nodeWidth(10).nodePadding(10+(x?15:0)).nodeAlign(v).extent([[0,0],[f,y]])(k);const b=(0,s.UMr)(s.zt);u.append("g").attr("class","nodes").selectAll(".node").data(k.nodes).join("g").attr("class","node").attr("id",(t=>(t.uid=Y.next("node-")).id)).attr("transform",(function(t){return"translate("+t.x0+","+t.y0+")"})).attr("x",(t=>t.x0)).attr("y",(t=>t.y0)).append("rect").attr("height",(t=>t.y1-t.y0)).attr("width",(t=>t.x1-t.x0)).attr("fill",(t=>b(t.id)));u.append("g").attr("class","node-labels").attr("font-family","sans-serif").attr("font-size",14).selectAll("text").data(k.nodes).join("text").attr("x",(t=>t.x0<f/2?t.x1+6:t.x0-6)).attr("y",(t=>(t.y1+t.y0)/2)).attr("dy",(x?"0":"0.35")+"em").attr("text-anchor",(t=>t.x0<f/2?"start":"end")).text((({id:t,value:n})=>x?`${t}\n${g}${Math.round(100*n)/100}${_}`:t));const w=u.append("g").attr("class","links").attr("fill","none").attr("stroke-opacity",.5).selectAll(".link").data(k.links).join("g").attr("class","link").style("mix-blend-mode","multiply"),L=(null==c?void 0:c.linkColor)||"gradient";if("gradient"===L){const t=w.append("linearGradient").attr("id",(t=>(t.uid=Y.next("linearGradient-")).id)).attr("gradientUnits","userSpaceOnUse").attr("x1",(t=>t.source.x1)).attr("x2",(t=>t.target.x0));t.append("stop").attr("offset","0%").attr("stop-color",(t=>b(t.source.id))),t.append("stop").attr("offset","100%").attr("stop-color",(t=>b(t.target.id)))}let E;switch(L){case"gradient":E=t=>t.uid;break;case"source":E=t=>b(t.source.id);break;case"target":E=t=>b(t.target.id);break;default:E=L}w.append("path").attr("d",z()).attr("stroke",E).attr("stroke-width",(t=>Math.max(1,t.width))),(0,i.o)(void 0,u,0,d)}},Z=F.parse.bind(F);F.parse=t=>Z((t=>t.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g,"").replaceAll(/([\n\r])+/g,"\n").trim())(t));const H={parser:F,db:K,renderer:R}}}]); \ No newline at end of file diff --git a/assets/js/748dce39.aedc43d8.js b/assets/js/748dce39.aedc43d8.js new file mode 100644 index 0000000000..aa5bdb06e5 --- /dev/null +++ b/assets/js/748dce39.aedc43d8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[82],{41451:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var n=t(74848),o=t(28453);const i={sidebar_label:"Keystone"},r="Keystone",a={id:"iaas/guides/operations-guide/openstack/keystone",title:"Keystone",description:"* List all users of a project who have been assigned the member role",source:"@site/docs/02-iaas/guides/operations-guide/openstack/keystone.md",sourceDirName:"02-iaas/guides/operations-guide/openstack",slug:"/iaas/guides/operations-guide/openstack/keystone",permalink:"/docs/iaas/guides/operations-guide/openstack/keystone",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/keystone.md",tags:[],version:"current",frontMatter:{sidebar_label:"Keystone"},sidebar:"docs",previous:{title:"Cinder",permalink:"/docs/iaas/guides/operations-guide/openstack/cinder"},next:{title:"Neutron",permalink:"/docs/iaas/guides/operations-guide/openstack/neutron"}},c={},d=[];function u(e){const s={code:"code",h1:"h1",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"keystone",children:"Keystone"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["List all users of a project who have been assigned the ",(0,n.jsx)(s.code,{children:"member"})," role"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"$ openstack --os-cloud admin role assignment list --names --role member --project test\n+--------+-----------+-------+-----------+--------+--------+-----------+\n| Role | User | Group | Project | Domain | System | Inherited |\n+--------+-----------+-------+-----------+--------+--------+-----------+\n| member | test@test | | test@test | | | False |\n+--------+-----------+-------+-----------+--------+--------+-----------+\n"})}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>a});var n=t(96540);const o={},i=n.createContext(o);function r(e){const s=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/751.f9acba6e.js b/assets/js/751.f9acba6e.js new file mode 100644 index 0000000000..f6280413f7 --- /dev/null +++ b/assets/js/751.f9acba6e.js @@ -0,0 +1,10825 @@ +"use strict"; +exports.id = 751; +exports.ids = [751]; +exports.modules = { + +/***/ 21176: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Zp: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(5664); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(74722); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(91395); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(697); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.A(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.A( + map/* default */.A(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.A(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.A(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.T(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.A(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.A(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.A(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.A(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.A(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.A('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.A(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.A(g.outEdges(v), function (e) { + if (has/* default */.A(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.A(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.A(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(98879); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(81942); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(23068); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.A)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(52528); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.A)(iteratee, 3); + + (0,_baseForOwn/* default */.A)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.A)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.A, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(41917); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.A.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.A(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.T().setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.T({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.A(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.A(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.A(range/* default */.A(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.A(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.A(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.A(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.A(layers, function (vs, i) { + if (isUndefined/* default */.A(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.A(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.A(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.A(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.A(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.A(children, dfs); + } + + if (has/* default */.A(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.A(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.A(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, reverseYOne); + if (has/* default */.A(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.A(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, swapXYOne); + if (has/* default */.A(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.A(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.A)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.A(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.A(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.A(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.T({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.A(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.A(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.A(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.A)(collection)) { + var iteratee = (0,_baseIteratee/* default */.A)(predicate, 3); + collection = (0,keys/* default */.A)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.A)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.A)(array, (0,_baseIteratee/* default */.A)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.A(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(69471); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(88496); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.A)(value) && (0,isObjectLike/* default */.A)(value) && (0,_baseGetTag/* default */.A)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.A)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.A)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.A)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.A)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.A(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.A(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.A(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.A(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.A(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.A(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.A(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.A(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(73046); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.A(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.A(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.A(tree.neighbors(v), function (w) { + if (!has/* default */.A(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.A(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.A(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.A(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.A(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.A(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.A(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.A(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.A(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.A( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(91641); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.A)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.A(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.T({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.A(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.A(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.A(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.A('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.A); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(52568); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.A)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.A)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + if ((0,isArray/* default */.A)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.A)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.A]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.A)(iteratees, (0,_baseUnary/* default */.A)(_baseIteratee/* default */.A)); + + var result = (0,_baseMap/* default */.A)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.A)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.A)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.A)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.A)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.A)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.A(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.A( + map/* default */.A(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.A(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.A(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.A( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.A(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.A(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.A(range/* default */.A(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.A(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.A(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.A(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.A(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.A( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.A(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.A(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.A(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.A(entryV) && !isUndefined/* default */.A(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.A(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.A(uEntry.barycenter) || + isUndefined/* default */.A(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.A(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.A(entry.out, handleOut(entry)); + } + + return map/* default */.A( + filter/* default */.A(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.A(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.A(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.A(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.A(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.A(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.A(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.A(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.A([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.A(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.A(entries, function (entry) { + entry.vs = flatten/* default */.A( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.A(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.A(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.A(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.A(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.T(); + forEach/* default */.A(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.A(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.A(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.A(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.A(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(99922); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(4574); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.A)(object, (0,_castFunction/* default */.A)(iteratee), keysIn/* default */.A); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.A(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.A(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.A(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.A(range/* default */.A(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.A(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.A(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.A(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.A(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.A(layering, function (layer) { + forEach/* default */.A(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.A(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.A(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.A(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.T(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.A(layering, function (layer) { + var u; + forEach/* default */.A(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.A(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.A(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.A(['u', 'd'], function (vert) { + forEach/* default */.A(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.A(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.A(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.A(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.A(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.A(layering).reverse(); + forEach/* default */.A(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.A(adjustedLayering, function (inner) { + return values/* default */.A(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.A(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.A(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.A(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.A(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.A(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.A(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.A(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.T({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.A({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.A(graph, graphAttrs)) + ); + + forEach/* default */.A(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.A(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.A(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.A({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.A(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.A(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.A(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.A(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.A(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.A(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.A(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.A(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.A(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.A(layers, function (layer) { + var orderShift = 0; + forEach/* default */.A(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.A(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.A(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.A(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.A(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 73046: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + T: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(48585); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(39142); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(89610); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(11662); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(66401); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(8058); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(69592); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(13588); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(24326); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(25707); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.A)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(39857); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.A && (1 / (0,_setToArray/* default */.A)(new _Set/* default */.A([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.A(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.A)(set); + } + isCommon = false; + includes = _cacheHas/* default */.A; + seen = new _SetCache/* default */.A; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(53533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.A)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.A)(arrays, 1, isArrayLikeObject/* default */.A, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(38207); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(89463); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.A(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.A(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.A(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.A(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.A(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.A(this._nodes); + } + sources() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.A(this.nodes(), function (v) { + return isEmpty/* default */.A(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.A(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.A(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.A(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.A(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.A(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.A(keys/* default */.A(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.A(keys/* default */.A(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.A(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.A(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.A(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.A(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.A(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.A(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.A(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.A(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.A(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.A(newDefault)) { + newDefault = constant/* default */.A(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.A(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.A(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.A(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.A(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.A(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.A(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.A(inV); + if (!u) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.A(outV); + if (!w) { + return edges; + } + return filter/* default */.A(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.A(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 697: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ T: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.T) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(73046); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 62062: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(29471); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.A; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 72641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 2634: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 45572: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 76912: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 91641: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(72641); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(22031); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keys/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(55615); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.A)(source, (0,keysIn/* default */.A)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(80154); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(39759); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(14792); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.A)(source, (0,_getSymbols/* default */.A)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(15647); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(13153); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.A : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.A)(result, (0,_getSymbols/* default */.A)(object)); + object = (0,_getPrototype/* default */.A)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.A)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(33831); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.A)(object, keysIn/* default */.A, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(90565); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.A)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(1801); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.A)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.A)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(18598); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(52789); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(64841); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.A)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.A)(value) && (0,_getTag/* default */.A)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.A && _nodeUtil/* default */.A.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.A)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.A)(value)) { + return value; + } + var isArr = (0,isArray/* default */.A)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.A)(value, result); + } + } else { + var tag = (0,_getTag/* default */.A)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.A)(value)) { + return (0,_cloneBuffer/* default */.A)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.A)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.A); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.A) + : (isFlat ? keysIn/* default */.A : keys/* default */.A); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.A)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.A)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 6240: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(79841); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(38446); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.A)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.A); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 25707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 13588: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(76912); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(52274); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.A ? _Symbol/* default */.A.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.A)(value) || (0,isArguments/* default */.A)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.A)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 79841: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4574); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 66318: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 33831: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76912); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 49574: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(11754); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(62062); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(64099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.A : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.A)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(43988); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(66984); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(29959); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.A(object), new _Uint8Array/* default */.A(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.A)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.A); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(19042); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.A)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.A)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(9779); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(99912); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(33858); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.A)(object), + othIsArr = (0,isArray/* default */.A)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.A)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.A)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.A)(object)) { + if (!(0,isBuffer/* default */.A)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.A); + return (objIsArr || (0,isTypedArray/* default */.A)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.A); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.A); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(53098); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.A)(value) && !(0,isObjectLike/* default */.A)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.A; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.A)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.A)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.A)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.A)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.A)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.A)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(29008); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(70805); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.A)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.A)(path) ? (0,_baseProperty/* default */.A)((0,_toKey/* default */.A)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.A; + } + if (typeof value == 'object') { + return (0,isArray/* default */.A)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 52568: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6240); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 70805: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 64099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 99922: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(29008); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 7819: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(86586); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(46632); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.A)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(28894); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.A)(value)) { + return value; + } + return (0,_isKey/* default */.A)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.A)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 19042: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33831); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14792); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27422); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 14792: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2634); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13153); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 85054: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7819); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(52274); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(92049); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25353); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5254); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30901); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 86586: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(61882); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 29959: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 30901: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61882); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 23068: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(24326); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66984); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6832); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55615); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 11662: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(2634); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.A)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.A)(collection) ? _arrayFilter/* default */.A : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.A)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 34098: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13588); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 8058: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72641); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6240); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99922); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 48585: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 39188: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(85054); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.A)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 61882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(88496); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(53098); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 69592: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 27422: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(83607); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69471); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(38446); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 74722: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(45572); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49574); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(52568); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(92049); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 81942: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(66318); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(52851); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(7819); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(25353); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(30901); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.A)(object)) { + return object; + } + path = (0,_castPath/* default */.A)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.A)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.A)(objValue) + ? objValue + : ((0,_isIndex/* default */.A)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.A)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.A)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.A)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(39188); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.A)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(34098); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(76875); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(67525); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.A)((0,_overRest/* default */.A)(func, undefined, flatten/* default */.A), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 91395: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(6832); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(74342); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.A)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.A)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.A)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.A)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 89463: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(6240); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(49574); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.A)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.A)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.A); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 13153: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 74342: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(23149); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.A)(value)) { + return NAN; + } + if ((0,isObject/* default */.A)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.A)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 28894: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(241); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(92049); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(61882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.A ? _Symbol/* default */.A.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.A)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.A)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.A)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 5664: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28894); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 38207: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + A: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(45572); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.A)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(27422); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.A)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 70751: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _styles_991ebdfc_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(27308); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(21176); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(697); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(76257); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(99418); + + + + + + + + + + + + + + +let edgeCount = 0; +const drawEdge = function(elem, path, relation, conf, diagObj) { + const getRelationType = function(type) { + switch (type) { + case diagObj.db.relationType.AGGREGATION: + return "aggregation"; + case diagObj.db.relationType.EXTENSION: + return "extension"; + case diagObj.db.relationType.COMPOSITION: + return "composition"; + case diagObj.db.relationType.DEPENDENCY: + return "dependency"; + case diagObj.db.relationType.LOLLIPOP: + return "lollipop"; + } + }; + path.points = path.points.filter((p) => !Number.isNaN(p.y)); + const lineData = path.points; + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .n8j)().x(function(d) { + return d.x; + }).y(function(d) { + return d.y; + }).curve(d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .qrM); + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", "edge" + edgeCount).attr("class", "relation"); + let url = ""; + if (conf.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + if (relation.relation.lineType == 1) { + svgPath.attr("class", "relation dashed-line"); + } + if (relation.relation.lineType == 10) { + svgPath.attr("class", "relation dotted-line"); + } + if (relation.relation.type1 !== "none") { + svgPath.attr( + "marker-start", + "url(" + url + "#" + getRelationType(relation.relation.type1) + "Start)" + ); + } + if (relation.relation.type2 !== "none") { + svgPath.attr( + "marker-end", + "url(" + url + "#" + getRelationType(relation.relation.type2) + "End)" + ); + } + let x, y; + const l = path.points.length; + let labelPosition = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.u.calcLabelPosition(path.points); + x = labelPosition.x; + y = labelPosition.y; + let p1_card_x, p1_card_y; + let p2_card_x, p2_card_y; + if (l % 2 !== 0 && l > 1) { + let cardinality_1_point = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.u.calcCardinalityPosition( + relation.relation.type1 !== "none", + path.points, + path.points[0] + ); + let cardinality_2_point = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.u.calcCardinalityPosition( + relation.relation.type2 !== "none", + path.points, + path.points[l - 1] + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("cardinality_1_point " + JSON.stringify(cardinality_1_point)); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("cardinality_2_point " + JSON.stringify(cardinality_2_point)); + p1_card_x = cardinality_1_point.x; + p1_card_y = cardinality_1_point.y; + p2_card_x = cardinality_2_point.x; + p2_card_y = cardinality_2_point.y; + } + if (relation.title !== void 0) { + const g = elem.append("g").attr("class", "classLabel"); + const label = g.append("text").attr("class", "label").attr("x", x).attr("y", y).attr("fill", "red").attr("text-anchor", "middle").text(relation.title); + window.label = label; + const bounds = label.node().getBBox(); + g.insert("rect", ":first-child").attr("class", "box").attr("x", bounds.x - conf.padding / 2).attr("y", bounds.y - conf.padding / 2).attr("width", bounds.width + conf.padding).attr("height", bounds.height + conf.padding); + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Rendering relation " + JSON.stringify(relation)); + if (relation.relationTitle1 !== void 0 && relation.relationTitle1 !== "none") { + const g = elem.append("g").attr("class", "cardinality"); + g.append("text").attr("class", "type1").attr("x", p1_card_x).attr("y", p1_card_y).attr("fill", "black").attr("font-size", "6").text(relation.relationTitle1); + } + if (relation.relationTitle2 !== void 0 && relation.relationTitle2 !== "none") { + const g = elem.append("g").attr("class", "cardinality"); + g.append("text").attr("class", "type2").attr("x", p2_card_x).attr("y", p2_card_y).attr("fill", "black").attr("font-size", "6").text(relation.relationTitle2); + } + edgeCount++; +}; +const drawClass = function(elem, classDef, conf, diagObj) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Rendering class ", classDef, conf); + const id = classDef.id; + const classInfo = { + id, + label: classDef.id, + width: 0, + height: 0 + }; + const g = elem.append("g").attr("id", diagObj.db.lookUpDomId(id)).attr("class", "classGroup"); + let title; + if (classDef.link) { + title = g.append("svg:a").attr("xlink:href", classDef.link).attr("target", classDef.linkTarget).append("text").attr("y", conf.textHeight + conf.padding).attr("x", 0); + } else { + title = g.append("text").attr("y", conf.textHeight + conf.padding).attr("x", 0); + } + let isFirst = true; + classDef.annotations.forEach(function(member) { + const titleText2 = title.append("tspan").text("«" + member + "»"); + if (!isFirst) { + titleText2.attr("dy", conf.textHeight); + } + isFirst = false; + }); + let classTitleString = getClassTitleString(classDef); + const classTitle = title.append("tspan").text(classTitleString).attr("class", "title"); + if (!isFirst) { + classTitle.attr("dy", conf.textHeight); + } + const titleHeight = title.node().getBBox().height; + let membersLine; + let membersBox; + let methodsLine; + if (classDef.members.length > 0) { + membersLine = g.append("line").attr("x1", 0).attr("y1", conf.padding + titleHeight + conf.dividerMargin / 2).attr("y2", conf.padding + titleHeight + conf.dividerMargin / 2); + const members = g.append("text").attr("x", conf.padding).attr("y", titleHeight + conf.dividerMargin + conf.textHeight).attr("fill", "white").attr("class", "classText"); + isFirst = true; + classDef.members.forEach(function(member) { + addTspan(members, member, isFirst, conf); + isFirst = false; + }); + membersBox = members.node().getBBox(); + } + if (classDef.methods.length > 0) { + methodsLine = g.append("line").attr("x1", 0).attr("y1", conf.padding + titleHeight + conf.dividerMargin + membersBox.height).attr("y2", conf.padding + titleHeight + conf.dividerMargin + membersBox.height); + const methods = g.append("text").attr("x", conf.padding).attr("y", titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight).attr("fill", "white").attr("class", "classText"); + isFirst = true; + classDef.methods.forEach(function(method) { + addTspan(methods, method, isFirst, conf); + isFirst = false; + }); + } + const classBox = g.node().getBBox(); + var cssClassStr = " "; + if (classDef.cssClasses.length > 0) { + cssClassStr = cssClassStr + classDef.cssClasses.join(" "); + } + const rect = g.insert("rect", ":first-child").attr("x", 0).attr("y", 0).attr("width", classBox.width + 2 * conf.padding).attr("height", classBox.height + conf.padding + 0.5 * conf.dividerMargin).attr("class", cssClassStr); + const rectWidth = rect.node().getBBox().width; + title.node().childNodes.forEach(function(x) { + x.setAttribute("x", (rectWidth - x.getBBox().width) / 2); + }); + if (classDef.tooltip) { + title.insert("title").text(classDef.tooltip); + } + if (membersLine) { + membersLine.attr("x2", rectWidth); + } + if (methodsLine) { + methodsLine.attr("x2", rectWidth); + } + classInfo.width = rectWidth; + classInfo.height = classBox.height + conf.padding + 0.5 * conf.dividerMargin; + return classInfo; +}; +const getClassTitleString = function(classDef) { + let classTitleString = classDef.id; + if (classDef.type) { + classTitleString += "<" + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.x)(classDef.type) + ">"; + } + return classTitleString; +}; +const drawNote = function(elem, note, conf, diagObj) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Rendering note ", note, conf); + const id = note.id; + const noteInfo = { + id, + text: note.text, + width: 0, + height: 0 + }; + const g = elem.append("g").attr("id", id).attr("class", "classGroup"); + let text = g.append("text").attr("y", conf.textHeight + conf.padding).attr("x", 0); + const lines = JSON.parse(`"${note.text}"`).split("\n"); + lines.forEach(function(line2) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug(`Adding line: ${line2}`); + text.append("tspan").text(line2).attr("class", "title").attr("dy", conf.textHeight); + }); + const noteBox = g.node().getBBox(); + const rect = g.insert("rect", ":first-child").attr("x", 0).attr("y", 0).attr("width", noteBox.width + 2 * conf.padding).attr( + "height", + noteBox.height + lines.length * conf.textHeight + conf.padding + 0.5 * conf.dividerMargin + ); + const rectWidth = rect.node().getBBox().width; + text.node().childNodes.forEach(function(x) { + x.setAttribute("x", (rectWidth - x.getBBox().width) / 2); + }); + noteInfo.width = rectWidth; + noteInfo.height = noteBox.height + lines.length * conf.textHeight + conf.padding + 0.5 * conf.dividerMargin; + return noteInfo; +}; +const addTspan = function(textEl, member, isFirst, conf) { + const { displayText, cssStyle } = member.getDisplayDetails(); + const tSpan = textEl.append("tspan").attr("x", conf.padding).text(displayText); + if (cssStyle !== "") { + tSpan.attr("style", member.cssStyle); + } + if (!isFirst) { + tSpan.attr("dy", conf.textHeight); + } +}; +const svgDraw = { + getClassTitleString, + drawClass, + drawEdge, + drawNote +}; +let idCache = {}; +const padding = 20; +const getGraphId = function(label) { + const foundEntry = Object.entries(idCache).find((entry) => entry[1].label === label); + if (foundEntry) { + return foundEntry[0]; + } +}; +const insertMarkers = function(elem) { + elem.append("defs").append("marker").attr("id", "extensionStart").attr("class", "extension").attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", "extensionEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); + elem.append("defs").append("marker").attr("id", "compositionStart").attr("class", "extension").attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", "compositionEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", "aggregationStart").attr("class", "extension").attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", "aggregationEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", "dependencyStart").attr("class", "extension").attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", "dependencyEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const draw = function(text, id, _version, diagObj) { + const conf = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().class; + idCache = {}; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Rendering diagram " + text); + const securityLevel = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body"); + const diagram2 = root.select(`[id='${id}']`); + insertMarkers(diagram2); + const g = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .T({ + multigraph: true + }); + g.setGraph({ + isMultiGraph: true + }); + g.setDefaultEdgeLabel(function() { + return {}; + }); + const classes = diagObj.db.getClasses(); + const keys = Object.keys(classes); + for (const key of keys) { + const classDef = classes[key]; + const node = svgDraw.drawClass(diagram2, classDef, conf, diagObj); + idCache[node.id] = node; + g.setNode(node.id, node); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Org height: " + node.height); + } + const relations = diagObj.db.getRelations(); + relations.forEach(function(relation) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.info( + // cspell:ignore tjoho + "tjoho" + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation) + ); + g.setEdge( + getGraphId(relation.id1), + getGraphId(relation.id2), + { + relation + }, + relation.title || "DEFAULT" + ); + }); + const notes = diagObj.db.getNotes(); + notes.forEach(function(note) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug(`Adding note: ${JSON.stringify(note)}`); + const node = svgDraw.drawNote(diagram2, note, conf, diagObj); + idCache[node.id] = node; + g.setNode(node.id, node); + if (note.class && note.class in classes) { + g.setEdge( + note.id, + getGraphId(note.class), + { + relation: { + id1: note.id, + id2: note.class, + relation: { + type1: "none", + type2: "none", + lineType: 10 + } + } + }, + "DEFAULT" + ); + } + }); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_1__/* .layout */ .Zp)(g); + g.nodes().forEach(function(v) { + if (v !== void 0 && g.node(v) !== void 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Node " + v + ": " + JSON.stringify(g.node(v))); + root.select("#" + (diagObj.db.lookUpDomId(v) || v)).attr( + "transform", + "translate(" + (g.node(v).x - g.node(v).width / 2) + "," + (g.node(v).y - g.node(v).height / 2) + " )" + ); + } + }); + g.edges().forEach(function(e) { + if (e !== void 0 && g.edge(e) !== void 0) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(g.edge(e))); + svgDraw.drawEdge(diagram2, g.edge(e), g.edge(e).relation, conf, diagObj); + } + }); + const svgBounds = diagram2.node().getBBox(); + const width = svgBounds.width + padding * 2; + const height = svgBounds.height + padding * 2; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.i)(diagram2, height, width, conf.useMaxWidth); + const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug(`viewBox ${vBox}`); + diagram2.attr("viewBox", vBox); +}; +const renderer = { + draw +}; +const diagram = { + parser: _styles_991ebdfc_js__WEBPACK_IMPORTED_MODULE_7__.p, + db: _styles_991ebdfc_js__WEBPACK_IMPORTED_MODULE_7__.d, + renderer, + styles: _styles_991ebdfc_js__WEBPACK_IMPORTED_MODULE_7__.s, + init: (cnf) => { + if (!cnf.class) { + cnf.class = {}; + } + cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + _styles_991ebdfc_js__WEBPACK_IMPORTED_MODULE_7__.d.clear(); + } +}; + + + +/***/ }), + +/***/ 27308: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ p: () => (/* binding */ parser$1), +/* harmony export */ s: () => (/* binding */ styles) +/* harmony export */ }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 17], $V1 = [1, 18], $V2 = [1, 19], $V3 = [1, 39], $V4 = [1, 40], $V5 = [1, 25], $V6 = [1, 23], $V7 = [1, 24], $V8 = [1, 31], $V9 = [1, 32], $Va = [1, 33], $Vb = [1, 34], $Vc = [1, 35], $Vd = [1, 36], $Ve = [1, 26], $Vf = [1, 27], $Vg = [1, 28], $Vh = [1, 29], $Vi = [1, 43], $Vj = [1, 30], $Vk = [1, 42], $Vl = [1, 44], $Vm = [1, 41], $Vn = [1, 45], $Vo = [1, 9], $Vp = [1, 8, 9], $Vq = [1, 56], $Vr = [1, 57], $Vs = [1, 58], $Vt = [1, 59], $Vu = [1, 60], $Vv = [1, 61], $Vw = [1, 62], $Vx = [1, 8, 9, 39], $Vy = [1, 74], $Vz = [1, 8, 9, 12, 13, 21, 37, 39, 42, 59, 60, 61, 62, 63, 64, 65, 70, 72], $VA = [1, 8, 9, 12, 13, 19, 21, 37, 39, 42, 46, 59, 60, 61, 62, 63, 64, 65, 70, 72, 74, 80, 95, 97, 98], $VB = [13, 74, 80, 95, 97, 98], $VC = [13, 64, 65, 74, 80, 95, 97, 98], $VD = [13, 59, 60, 61, 62, 63, 74, 80, 95, 97, 98], $VE = [1, 93], $VF = [1, 110], $VG = [1, 108], $VH = [1, 102], $VI = [1, 103], $VJ = [1, 104], $VK = [1, 105], $VL = [1, 106], $VM = [1, 107], $VN = [1, 109], $VO = [1, 8, 9, 37, 39, 42], $VP = [1, 8, 9, 21], $VQ = [1, 8, 9, 78], $VR = [1, 8, 9, 21, 73, 74, 78, 80, 81, 82, 83, 84, 85]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "mermaidDoc": 4, "statements": 5, "graphConfig": 6, "CLASS_DIAGRAM": 7, "NEWLINE": 8, "EOF": 9, "statement": 10, "classLabel": 11, "SQS": 12, "STR": 13, "SQE": 14, "namespaceName": 15, "alphaNumToken": 16, "className": 17, "classLiteralName": 18, "GENERICTYPE": 19, "relationStatement": 20, "LABEL": 21, "namespaceStatement": 22, "classStatement": 23, "memberStatement": 24, "annotationStatement": 25, "clickStatement": 26, "styleStatement": 27, "cssClassStatement": 28, "noteStatement": 29, "direction": 30, "acc_title": 31, "acc_title_value": 32, "acc_descr": 33, "acc_descr_value": 34, "acc_descr_multiline_value": 35, "namespaceIdentifier": 36, "STRUCT_START": 37, "classStatements": 38, "STRUCT_STOP": 39, "NAMESPACE": 40, "classIdentifier": 41, "STYLE_SEPARATOR": 42, "members": 43, "CLASS": 44, "ANNOTATION_START": 45, "ANNOTATION_END": 46, "MEMBER": 47, "SEPARATOR": 48, "relation": 49, "NOTE_FOR": 50, "noteText": 51, "NOTE": 52, "direction_tb": 53, "direction_bt": 54, "direction_rl": 55, "direction_lr": 56, "relationType": 57, "lineType": 58, "AGGREGATION": 59, "EXTENSION": 60, "COMPOSITION": 61, "DEPENDENCY": 62, "LOLLIPOP": 63, "LINE": 64, "DOTTED_LINE": 65, "CALLBACK": 66, "LINK": 67, "LINK_TARGET": 68, "CLICK": 69, "CALLBACK_NAME": 70, "CALLBACK_ARGS": 71, "HREF": 72, "STYLE": 73, "ALPHA": 74, "stylesOpt": 75, "CSSCLASS": 76, "style": 77, "COMMA": 78, "styleComponent": 79, "NUM": 80, "COLON": 81, "UNIT": 82, "SPACE": 83, "BRKT": 84, "PCT": 85, "commentToken": 86, "textToken": 87, "graphCodeTokens": 88, "textNoTagsToken": 89, "TAGSTART": 90, "TAGEND": 91, "==": 92, "--": 93, "DEFAULT": 94, "MINUS": 95, "keywords": 96, "UNICODE_TEXT": 97, "BQUOTE_STR": 98, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 7: "CLASS_DIAGRAM", 8: "NEWLINE", 9: "EOF", 12: "SQS", 13: "STR", 14: "SQE", 19: "GENERICTYPE", 21: "LABEL", 31: "acc_title", 32: "acc_title_value", 33: "acc_descr", 34: "acc_descr_value", 35: "acc_descr_multiline_value", 37: "STRUCT_START", 39: "STRUCT_STOP", 40: "NAMESPACE", 42: "STYLE_SEPARATOR", 44: "CLASS", 45: "ANNOTATION_START", 46: "ANNOTATION_END", 47: "MEMBER", 48: "SEPARATOR", 50: "NOTE_FOR", 52: "NOTE", 53: "direction_tb", 54: "direction_bt", 55: "direction_rl", 56: "direction_lr", 59: "AGGREGATION", 60: "EXTENSION", 61: "COMPOSITION", 62: "DEPENDENCY", 63: "LOLLIPOP", 64: "LINE", 65: "DOTTED_LINE", 66: "CALLBACK", 67: "LINK", 68: "LINK_TARGET", 69: "CLICK", 70: "CALLBACK_NAME", 71: "CALLBACK_ARGS", 72: "HREF", 73: "STYLE", 74: "ALPHA", 76: "CSSCLASS", 78: "COMMA", 80: "NUM", 81: "COLON", 82: "UNIT", 83: "SPACE", 84: "BRKT", 85: "PCT", 88: "graphCodeTokens", 90: "TAGSTART", 91: "TAGEND", 92: "==", 93: "--", 94: "DEFAULT", 95: "MINUS", 96: "keywords", 97: "UNICODE_TEXT", 98: "BQUOTE_STR" }, + productions_: [0, [3, 1], [3, 1], [4, 1], [6, 4], [5, 1], [5, 2], [5, 3], [11, 3], [15, 1], [15, 2], [17, 1], [17, 1], [17, 2], [17, 2], [17, 2], [10, 1], [10, 2], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 2], [10, 2], [10, 1], [22, 4], [22, 5], [36, 2], [38, 1], [38, 2], [38, 3], [23, 1], [23, 3], [23, 4], [23, 6], [41, 2], [41, 3], [25, 4], [43, 1], [43, 2], [24, 1], [24, 2], [24, 1], [24, 1], [20, 3], [20, 4], [20, 4], [20, 5], [29, 3], [29, 2], [30, 1], [30, 1], [30, 1], [30, 1], [49, 3], [49, 2], [49, 2], [49, 1], [57, 1], [57, 1], [57, 1], [57, 1], [57, 1], [58, 1], [58, 1], [26, 3], [26, 4], [26, 3], [26, 4], [26, 4], [26, 5], [26, 3], [26, 4], [26, 4], [26, 5], [26, 4], [26, 5], [26, 5], [26, 6], [27, 3], [28, 3], [75, 1], [75, 3], [77, 1], [77, 2], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [86, 1], [86, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [89, 1], [89, 1], [89, 1], [89, 1], [16, 1], [16, 1], [16, 1], [16, 1], [18, 1], [51, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 8: + this.$ = $$[$0 - 1]; + break; + case 9: + case 11: + case 12: + this.$ = $$[$0]; + break; + case 10: + case 13: + this.$ = $$[$0 - 1] + $$[$0]; + break; + case 14: + case 15: + this.$ = $$[$0 - 1] + "~" + $$[$0] + "~"; + break; + case 16: + yy.addRelation($$[$0]); + break; + case 17: + $$[$0 - 1].title = yy.cleanupLabel($$[$0]); + yy.addRelation($$[$0 - 1]); + break; + case 27: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 28: + case 29: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 30: + yy.addClassesToNamespace($$[$0 - 3], $$[$0 - 1]); + break; + case 31: + yy.addClassesToNamespace($$[$0 - 4], $$[$0 - 1]); + break; + case 32: + this.$ = $$[$0]; + yy.addNamespace($$[$0]); + break; + case 33: + this.$ = [$$[$0]]; + break; + case 34: + this.$ = [$$[$0 - 1]]; + break; + case 35: + $$[$0].unshift($$[$0 - 2]); + this.$ = $$[$0]; + break; + case 37: + yy.setCssClass($$[$0 - 2], $$[$0]); + break; + case 38: + yy.addMembers($$[$0 - 3], $$[$0 - 1]); + break; + case 39: + yy.setCssClass($$[$0 - 5], $$[$0 - 3]); + yy.addMembers($$[$0 - 5], $$[$0 - 1]); + break; + case 40: + this.$ = $$[$0]; + yy.addClass($$[$0]); + break; + case 41: + this.$ = $$[$0 - 1]; + yy.addClass($$[$0 - 1]); + yy.setClassLabel($$[$0 - 1], $$[$0]); + break; + case 42: + yy.addAnnotation($$[$0], $$[$0 - 2]); + break; + case 43: + this.$ = [$$[$0]]; + break; + case 44: + $$[$0].push($$[$0 - 1]); + this.$ = $$[$0]; + break; + case 45: + break; + case 46: + yy.addMember($$[$0 - 1], yy.cleanupLabel($$[$0])); + break; + case 47: + break; + case 48: + break; + case 49: + this.$ = { "id1": $$[$0 - 2], "id2": $$[$0], relation: $$[$0 - 1], relationTitle1: "none", relationTitle2: "none" }; + break; + case 50: + this.$ = { id1: $$[$0 - 3], id2: $$[$0], relation: $$[$0 - 1], relationTitle1: $$[$0 - 2], relationTitle2: "none" }; + break; + case 51: + this.$ = { id1: $$[$0 - 3], id2: $$[$0], relation: $$[$0 - 2], relationTitle1: "none", relationTitle2: $$[$0 - 1] }; + break; + case 52: + this.$ = { id1: $$[$0 - 4], id2: $$[$0], relation: $$[$0 - 2], relationTitle1: $$[$0 - 3], relationTitle2: $$[$0 - 1] }; + break; + case 53: + yy.addNote($$[$0], $$[$0 - 1]); + break; + case 54: + yy.addNote($$[$0]); + break; + case 55: + yy.setDirection("TB"); + break; + case 56: + yy.setDirection("BT"); + break; + case 57: + yy.setDirection("RL"); + break; + case 58: + yy.setDirection("LR"); + break; + case 59: + this.$ = { type1: $$[$0 - 2], type2: $$[$0], lineType: $$[$0 - 1] }; + break; + case 60: + this.$ = { type1: "none", type2: $$[$0], lineType: $$[$0 - 1] }; + break; + case 61: + this.$ = { type1: $$[$0 - 1], type2: "none", lineType: $$[$0] }; + break; + case 62: + this.$ = { type1: "none", type2: "none", lineType: $$[$0] }; + break; + case 63: + this.$ = yy.relationType.AGGREGATION; + break; + case 64: + this.$ = yy.relationType.EXTENSION; + break; + case 65: + this.$ = yy.relationType.COMPOSITION; + break; + case 66: + this.$ = yy.relationType.DEPENDENCY; + break; + case 67: + this.$ = yy.relationType.LOLLIPOP; + break; + case 68: + this.$ = yy.lineType.LINE; + break; + case 69: + this.$ = yy.lineType.DOTTED_LINE; + break; + case 70: + case 76: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 1], $$[$0]); + break; + case 71: + case 77: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1]); + yy.setTooltip($$[$0 - 2], $$[$0]); + break; + case 72: + this.$ = $$[$0 - 2]; + yy.setLink($$[$0 - 1], $$[$0]); + break; + case 73: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 74: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 2], $$[$0 - 1]); + yy.setTooltip($$[$0 - 2], $$[$0]); + break; + case 75: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 3], $$[$0 - 2], $$[$0]); + yy.setTooltip($$[$0 - 3], $$[$0 - 1]); + break; + case 78: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 79: + this.$ = $$[$0 - 4]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 2], $$[$0 - 1]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 80: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 2], $$[$0]); + break; + case 81: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 3], $$[$0 - 1], $$[$0]); + break; + case 82: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 3], $$[$0 - 1]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 83: + this.$ = $$[$0 - 5]; + yy.setLink($$[$0 - 4], $$[$0 - 2], $$[$0]); + yy.setTooltip($$[$0 - 4], $$[$0 - 1]); + break; + case 84: + this.$ = $$[$0 - 2]; + yy.setCssStyle($$[$0 - 1], $$[$0]); + break; + case 85: + yy.setCssClass($$[$0 - 1], $$[$0]); + break; + case 86: + this.$ = [$$[$0]]; + break; + case 87: + $$[$0 - 2].push($$[$0]); + this.$ = $$[$0 - 2]; + break; + case 89: + this.$ = $$[$0 - 1] + $$[$0]; + break; + } + }, + table: [{ 3: 1, 4: 2, 5: 3, 6: 4, 7: [1, 6], 10: 5, 16: 37, 17: 20, 18: 38, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: 16, 31: $V0, 33: $V1, 35: $V2, 36: 21, 40: $V3, 41: 22, 44: $V4, 45: $V5, 47: $V6, 48: $V7, 50: $V8, 52: $V9, 53: $Va, 54: $Vb, 55: $Vc, 56: $Vd, 66: $Ve, 67: $Vf, 69: $Vg, 73: $Vh, 74: $Vi, 76: $Vj, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 1: [3] }, { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3] }, o($Vo, [2, 5], { 8: [1, 46] }), { 8: [1, 47] }, o($Vp, [2, 16], { 21: [1, 48] }), o($Vp, [2, 18]), o($Vp, [2, 19]), o($Vp, [2, 20]), o($Vp, [2, 21]), o($Vp, [2, 22]), o($Vp, [2, 23]), o($Vp, [2, 24]), o($Vp, [2, 25]), o($Vp, [2, 26]), { 32: [1, 49] }, { 34: [1, 50] }, o($Vp, [2, 29]), o($Vp, [2, 45], { 49: 51, 57: 54, 58: 55, 13: [1, 52], 21: [1, 53], 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu, 64: $Vv, 65: $Vw }), { 37: [1, 63] }, o($Vx, [2, 36], { 37: [1, 65], 42: [1, 64] }), o($Vp, [2, 47]), o($Vp, [2, 48]), { 16: 66, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm }, { 16: 37, 17: 67, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 16: 37, 17: 68, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 16: 37, 17: 69, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 74: [1, 70] }, { 13: [1, 71] }, { 16: 37, 17: 72, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 13: $Vy, 51: 73 }, o($Vp, [2, 55]), o($Vp, [2, 56]), o($Vp, [2, 57]), o($Vp, [2, 58]), o($Vz, [2, 11], { 16: 37, 18: 38, 17: 75, 19: [1, 76], 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }), o($Vz, [2, 12], { 19: [1, 77] }), { 15: 78, 16: 79, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm }, { 16: 37, 17: 80, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($VA, [2, 112]), o($VA, [2, 113]), o($VA, [2, 114]), o($VA, [2, 115]), o([1, 8, 9, 12, 13, 19, 21, 37, 39, 42, 59, 60, 61, 62, 63, 64, 65, 70, 72], [2, 116]), o($Vo, [2, 6], { 10: 5, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: 16, 17: 20, 36: 21, 41: 22, 16: 37, 18: 38, 5: 81, 31: $V0, 33: $V1, 35: $V2, 40: $V3, 44: $V4, 45: $V5, 47: $V6, 48: $V7, 50: $V8, 52: $V9, 53: $Va, 54: $Vb, 55: $Vc, 56: $Vd, 66: $Ve, 67: $Vf, 69: $Vg, 73: $Vh, 74: $Vi, 76: $Vj, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }), { 5: 82, 10: 5, 16: 37, 17: 20, 18: 38, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: 16, 31: $V0, 33: $V1, 35: $V2, 36: 21, 40: $V3, 41: 22, 44: $V4, 45: $V5, 47: $V6, 48: $V7, 50: $V8, 52: $V9, 53: $Va, 54: $Vb, 55: $Vc, 56: $Vd, 66: $Ve, 67: $Vf, 69: $Vg, 73: $Vh, 74: $Vi, 76: $Vj, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($Vp, [2, 17]), o($Vp, [2, 27]), o($Vp, [2, 28]), { 13: [1, 84], 16: 37, 17: 83, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 49: 85, 57: 54, 58: 55, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu, 64: $Vv, 65: $Vw }, o($Vp, [2, 46]), { 58: 86, 64: $Vv, 65: $Vw }, o($VB, [2, 62], { 57: 87, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu }), o($VC, [2, 63]), o($VC, [2, 64]), o($VC, [2, 65]), o($VC, [2, 66]), o($VC, [2, 67]), o($VD, [2, 68]), o($VD, [2, 69]), { 8: [1, 89], 23: 90, 38: 88, 41: 22, 44: $V4 }, { 16: 91, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm }, { 43: 92, 47: $VE }, { 46: [1, 94] }, { 13: [1, 95] }, { 13: [1, 96] }, { 70: [1, 97], 72: [1, 98] }, { 21: $VF, 73: $VG, 74: $VH, 75: 99, 77: 100, 79: 101, 80: $VI, 81: $VJ, 82: $VK, 83: $VL, 84: $VM, 85: $VN }, { 74: [1, 111] }, { 13: $Vy, 51: 112 }, o($Vp, [2, 54]), o($Vp, [2, 117]), o($Vz, [2, 13]), o($Vz, [2, 14]), o($Vz, [2, 15]), { 37: [2, 32] }, { 15: 113, 16: 79, 37: [2, 9], 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm }, o($VO, [2, 40], { 11: 114, 12: [1, 115] }), o($Vo, [2, 7]), { 9: [1, 116] }, o($VP, [2, 49]), { 16: 37, 17: 117, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 13: [1, 119], 16: 37, 17: 118, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($VB, [2, 61], { 57: 120, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu }), o($VB, [2, 60]), { 39: [1, 121] }, { 23: 90, 38: 122, 41: 22, 44: $V4 }, { 8: [1, 123], 39: [2, 33] }, o($Vx, [2, 37], { 37: [1, 124] }), { 39: [1, 125] }, { 39: [2, 43], 43: 126, 47: $VE }, { 16: 37, 17: 127, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($Vp, [2, 70], { 13: [1, 128] }), o($Vp, [2, 72], { 13: [1, 130], 68: [1, 129] }), o($Vp, [2, 76], { 13: [1, 131], 71: [1, 132] }), { 13: [1, 133] }, o($Vp, [2, 84], { 78: [1, 134] }), o($VQ, [2, 86], { 79: 135, 21: $VF, 73: $VG, 74: $VH, 80: $VI, 81: $VJ, 82: $VK, 83: $VL, 84: $VM, 85: $VN }), o($VR, [2, 88]), o($VR, [2, 90]), o($VR, [2, 91]), o($VR, [2, 92]), o($VR, [2, 93]), o($VR, [2, 94]), o($VR, [2, 95]), o($VR, [2, 96]), o($VR, [2, 97]), o($VR, [2, 98]), o($Vp, [2, 85]), o($Vp, [2, 53]), { 37: [2, 10] }, o($VO, [2, 41]), { 13: [1, 136] }, { 1: [2, 4] }, o($VP, [2, 51]), o($VP, [2, 50]), { 16: 37, 17: 137, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($VB, [2, 59]), o($Vp, [2, 30]), { 39: [1, 138] }, { 23: 90, 38: 139, 39: [2, 34], 41: 22, 44: $V4 }, { 43: 140, 47: $VE }, o($Vx, [2, 38]), { 39: [2, 44] }, o($Vp, [2, 42]), o($Vp, [2, 71]), o($Vp, [2, 73]), o($Vp, [2, 74], { 68: [1, 141] }), o($Vp, [2, 77]), o($Vp, [2, 78], { 13: [1, 142] }), o($Vp, [2, 80], { 13: [1, 144], 68: [1, 143] }), { 21: $VF, 73: $VG, 74: $VH, 77: 145, 79: 101, 80: $VI, 81: $VJ, 82: $VK, 83: $VL, 84: $VM, 85: $VN }, o($VR, [2, 89]), { 14: [1, 146] }, o($VP, [2, 52]), o($Vp, [2, 31]), { 39: [2, 35] }, { 39: [1, 147] }, o($Vp, [2, 75]), o($Vp, [2, 79]), o($Vp, [2, 81]), o($Vp, [2, 82], { 68: [1, 148] }), o($VQ, [2, 87], { 79: 135, 21: $VF, 73: $VG, 74: $VH, 80: $VI, 81: $VJ, 82: $VK, 83: $VL, 84: $VM, 85: $VN }), o($VO, [2, 8]), o($Vx, [2, 39]), o($Vp, [2, 83])], + defaultActions: { 2: [2, 1], 3: [2, 2], 4: [2, 3], 78: [2, 32], 113: [2, 10], 116: [2, 4], 126: [2, 44], 139: [2, 35] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 53; + case 1: + return 54; + case 2: + return 55; + case 3: + return 56; + case 4: + break; + case 5: + break; + case 6: + this.begin("acc_title"); + return 31; + case 7: + this.popState(); + return "acc_title_value"; + case 8: + this.begin("acc_descr"); + return 33; + case 9: + this.popState(); + return "acc_descr_value"; + case 10: + this.begin("acc_descr_multiline"); + break; + case 11: + this.popState(); + break; + case 12: + return "acc_descr_multiline_value"; + case 13: + return 8; + case 14: + break; + case 15: + return 7; + case 16: + return 7; + case 17: + return "EDGE_STATE"; + case 18: + this.begin("callback_name"); + break; + case 19: + this.popState(); + break; + case 20: + this.popState(); + this.begin("callback_args"); + break; + case 21: + return 70; + case 22: + this.popState(); + break; + case 23: + return 71; + case 24: + this.popState(); + break; + case 25: + return "STR"; + case 26: + this.begin("string"); + break; + case 27: + return 73; + case 28: + this.begin("namespace"); + return 40; + case 29: + this.popState(); + return 8; + case 30: + break; + case 31: + this.begin("namespace-body"); + return 37; + case 32: + this.popState(); + return 39; + case 33: + return "EOF_IN_STRUCT"; + case 34: + return 8; + case 35: + break; + case 36: + return "EDGE_STATE"; + case 37: + this.begin("class"); + return 44; + case 38: + this.popState(); + return 8; + case 39: + break; + case 40: + this.popState(); + this.popState(); + return 39; + case 41: + this.begin("class-body"); + return 37; + case 42: + this.popState(); + return 39; + case 43: + return "EOF_IN_STRUCT"; + case 44: + return "EDGE_STATE"; + case 45: + return "OPEN_IN_STRUCT"; + case 46: + break; + case 47: + return "MEMBER"; + case 48: + return 76; + case 49: + return 66; + case 50: + return 67; + case 51: + return 69; + case 52: + return 50; + case 53: + return 52; + case 54: + return 45; + case 55: + return 46; + case 56: + return 72; + case 57: + this.popState(); + break; + case 58: + return "GENERICTYPE"; + case 59: + this.begin("generic"); + break; + case 60: + this.popState(); + break; + case 61: + return "BQUOTE_STR"; + case 62: + this.begin("bqstring"); + break; + case 63: + return 68; + case 64: + return 68; + case 65: + return 68; + case 66: + return 68; + case 67: + return 60; + case 68: + return 60; + case 69: + return 62; + case 70: + return 62; + case 71: + return 61; + case 72: + return 59; + case 73: + return 63; + case 74: + return 64; + case 75: + return 65; + case 76: + return 21; + case 77: + return 42; + case 78: + return 95; + case 79: + return "DOT"; + case 80: + return "PLUS"; + case 81: + return 81; + case 82: + return 78; + case 83: + return 84; + case 84: + return 84; + case 85: + return 85; + case 86: + return "EQUALS"; + case 87: + return "EQUALS"; + case 88: + return 74; + case 89: + return 12; + case 90: + return 14; + case 91: + return "PUNCTUATION"; + case 92: + return 80; + case 93: + return 97; + case 94: + return 83; + case 95: + return 83; + case 96: + return 9; + } + }, + rules: [/^(?:.*direction\s+TB[^\n]*)/, /^(?:.*direction\s+BT[^\n]*)/, /^(?:.*direction\s+RL[^\n]*)/, /^(?:.*direction\s+LR[^\n]*)/, /^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/, /^(?:%%[^\n]*(\r?\n)*)/, /^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:classDiagram-v2\b)/, /^(?:classDiagram\b)/, /^(?:\[\*\])/, /^(?:call[\s]+)/, /^(?:\([\s]*\))/, /^(?:\()/, /^(?:[^(]*)/, /^(?:\))/, /^(?:[^)]*)/, /^(?:["])/, /^(?:[^"]*)/, /^(?:["])/, /^(?:style\b)/, /^(?:namespace\b)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:[{])/, /^(?:[}])/, /^(?:$)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:\[\*\])/, /^(?:class\b)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:[}])/, /^(?:[{])/, /^(?:[}])/, /^(?:$)/, /^(?:\[\*\])/, /^(?:[{])/, /^(?:[\n])/, /^(?:[^{}\n]*)/, /^(?:cssClass\b)/, /^(?:callback\b)/, /^(?:link\b)/, /^(?:click\b)/, /^(?:note for\b)/, /^(?:note\b)/, /^(?:<<)/, /^(?:>>)/, /^(?:href\b)/, /^(?:[~])/, /^(?:[^~]*)/, /^(?:~)/, /^(?:[`])/, /^(?:[^`]+)/, /^(?:[`])/, /^(?:_self\b)/, /^(?:_blank\b)/, /^(?:_parent\b)/, /^(?:_top\b)/, /^(?:\s*<\|)/, /^(?:\s*\|>)/, /^(?:\s*>)/, /^(?:\s*<)/, /^(?:\s*\*)/, /^(?:\s*o\b)/, /^(?:\s*\(\))/, /^(?:--)/, /^(?:\.\.)/, /^(?::{1}[^:\n;]+)/, /^(?::{3})/, /^(?:-)/, /^(?:\.)/, /^(?:\+)/, /^(?::)/, /^(?:,)/, /^(?:#)/, /^(?:#)/, /^(?:%)/, /^(?:=)/, /^(?:=)/, /^(?:\w+)/, /^(?:\[)/, /^(?:\])/, /^(?:[!"#$%&'*+,-.`?\\/])/, /^(?:[0-9]+)/, /^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/, /^(?:\s)/, /^(?:\s)/, /^(?:$)/], + conditions: { "namespace-body": { "rules": [26, 32, 33, 34, 35, 36, 37, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "namespace": { "rules": [26, 28, 29, 30, 31, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "class-body": { "rules": [26, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "class": { "rules": [26, 38, 39, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "acc_descr_multiline": { "rules": [11, 12, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "acc_descr": { "rules": [9, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "acc_title": { "rules": [7, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "callback_args": { "rules": [22, 23, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "callback_name": { "rules": [19, 20, 21, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "href": { "rules": [26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "struct": { "rules": [26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "generic": { "rules": [26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "bqstring": { "rules": [26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "string": { "rules": [24, 25, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 8, 10, 13, 14, 15, 16, 17, 18, 26, 27, 28, 37, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const visibilityValues = ["#", "+", "~", "-", ""]; +class ClassMember { + constructor(input, memberType) { + this.memberType = memberType; + this.visibility = ""; + this.classifier = ""; + const sanitizedInput = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.d)(input, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + this.parseMember(sanitizedInput); + } + getDisplayDetails() { + let displayText = this.visibility + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.x)(this.id); + if (this.memberType === "method") { + displayText += `(${(0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.x)(this.parameters.trim())})`; + if (this.returnType) { + displayText += " : " + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.x)(this.returnType); + } + } + displayText = displayText.trim(); + const cssStyle = this.parseClassifier(); + return { + displayText, + cssStyle + }; + } + parseMember(input) { + let potentialClassifier = ""; + if (this.memberType === "method") { + const methodRegEx = /([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/; + const match = input.match(methodRegEx); + if (match) { + const detectedVisibility = match[1] ? match[1].trim() : ""; + if (visibilityValues.includes(detectedVisibility)) { + this.visibility = detectedVisibility; + } + this.id = match[2].trim(); + this.parameters = match[3] ? match[3].trim() : ""; + potentialClassifier = match[4] ? match[4].trim() : ""; + this.returnType = match[5] ? match[5].trim() : ""; + if (potentialClassifier === "") { + const lastChar = this.returnType.substring(this.returnType.length - 1); + if (lastChar.match(/[$*]/)) { + potentialClassifier = lastChar; + this.returnType = this.returnType.substring(0, this.returnType.length - 1); + } + } + } + } else { + const length = input.length; + const firstChar = input.substring(0, 1); + const lastChar = input.substring(length - 1); + if (visibilityValues.includes(firstChar)) { + this.visibility = firstChar; + } + if (lastChar.match(/[$*]/)) { + potentialClassifier = lastChar; + } + this.id = input.substring( + this.visibility === "" ? 0 : 1, + potentialClassifier === "" ? length : length - 1 + ); + } + this.classifier = potentialClassifier; + } + parseClassifier() { + switch (this.classifier) { + case "*": + return "font-style:italic;"; + case "$": + return "text-decoration:underline;"; + default: + return ""; + } + } +} +const MERMAID_DOM_ID_PREFIX = "classId-"; +let relations = []; +let classes = {}; +let notes = []; +let classCounter = 0; +let namespaces = {}; +let namespaceCounter = 0; +let functions = []; +const sanitizeText = (txt) => _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(txt, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); +const splitClassNameAndType = function(_id) { + const id = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + let genericType = ""; + let className = id; + if (id.indexOf("~") > 0) { + const split = id.split("~"); + className = sanitizeText(split[0]); + genericType = sanitizeText(split[1]); + } + return { className, type: genericType }; +}; +const setClassLabel = function(_id, label) { + const id = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + if (label) { + label = sanitizeText(label); + } + const { className } = splitClassNameAndType(id); + classes[className].label = label; +}; +const addClass = function(_id) { + const id = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + const { className, type } = splitClassNameAndType(id); + if (Object.hasOwn(classes, className)) { + return; + } + const name = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(className, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + classes[name] = { + id: name, + type, + label: name, + cssClasses: [], + methods: [], + members: [], + annotations: [], + styles: [], + domId: MERMAID_DOM_ID_PREFIX + name + "-" + classCounter + }; + classCounter++; +}; +const lookUpDomId = function(_id) { + const id = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + if (id in classes) { + return classes[id].domId; + } + throw new Error("Class not found: " + id); +}; +const clear = function() { + relations = []; + classes = {}; + notes = []; + functions = []; + functions.push(setupToolTips); + namespaces = {}; + namespaceCounter = 0; + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.v)(); +}; +const getClass = function(id) { + return classes[id]; +}; +const getClasses = function() { + return classes; +}; +const getRelations = function() { + return relations; +}; +const getNotes = function() { + return notes; +}; +const addRelation = function(relation) { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("Adding relation: " + JSON.stringify(relation)); + addClass(relation.id1); + addClass(relation.id2); + relation.id1 = splitClassNameAndType(relation.id1).className; + relation.id2 = splitClassNameAndType(relation.id2).className; + relation.relationTitle1 = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(relation.relationTitle1.trim(), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + relation.relationTitle2 = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(relation.relationTitle2.trim(), (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + relations.push(relation); +}; +const addAnnotation = function(className, annotation) { + const validatedClassName = splitClassNameAndType(className).className; + classes[validatedClassName].annotations.push(annotation); +}; +const addMember = function(className, member) { + addClass(className); + const validatedClassName = splitClassNameAndType(className).className; + const theClass = classes[validatedClassName]; + if (typeof member === "string") { + const memberString = member.trim(); + if (memberString.startsWith("<<") && memberString.endsWith(">>")) { + theClass.annotations.push(sanitizeText(memberString.substring(2, memberString.length - 2))); + } else if (memberString.indexOf(")") > 0) { + theClass.methods.push(new ClassMember(memberString, "method")); + } else if (memberString) { + theClass.members.push(new ClassMember(memberString, "attribute")); + } + } +}; +const addMembers = function(className, members) { + if (Array.isArray(members)) { + members.reverse(); + members.forEach((member) => addMember(className, member)); + } +}; +const addNote = function(text, className) { + const note = { + id: `note${notes.length}`, + class: className, + text + }; + notes.push(note); +}; +const cleanupLabel = function(label) { + if (label.startsWith(":")) { + label = label.substring(1); + } + return sanitizeText(label.trim()); +}; +const setCssClass = function(ids, className) { + ids.split(",").forEach(function(_id) { + let id = _id; + if (_id[0].match(/\d/)) { + id = MERMAID_DOM_ID_PREFIX + id; + } + if (classes[id] !== void 0) { + classes[id].cssClasses.push(className); + } + }); +}; +const setTooltip = function(ids, tooltip) { + ids.split(",").forEach(function(id) { + if (tooltip !== void 0) { + classes[id].tooltip = sanitizeText(tooltip); + } + }); +}; +const getTooltip = function(id, namespace) { + if (namespace) { + return namespaces[namespace].classes[id].tooltip; + } + return classes[id].tooltip; +}; +const setLink = function(ids, linkStr, target) { + const config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + ids.split(",").forEach(function(_id) { + let id = _id; + if (_id[0].match(/\d/)) { + id = MERMAID_DOM_ID_PREFIX + id; + } + if (classes[id] !== void 0) { + classes[id].link = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.formatUrl(linkStr, config); + if (config.securityLevel === "sandbox") { + classes[id].linkTarget = "_top"; + } else if (typeof target === "string") { + classes[id].linkTarget = sanitizeText(target); + } else { + classes[id].linkTarget = "_blank"; + } + } + }); + setCssClass(ids, "clickable"); +}; +const setClickEvent = function(ids, functionName, functionArgs) { + ids.split(",").forEach(function(id) { + setClickFunc(id, functionName, functionArgs); + classes[id].haveCallback = true; + }); + setCssClass(ids, "clickable"); +}; +const setClickFunc = function(_domId, functionName, functionArgs) { + const domId = _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_domId, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + const config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + if (config.securityLevel !== "loose") { + return; + } + if (functionName === void 0) { + return; + } + const id = domId; + if (classes[id] !== void 0) { + const elemId = lookUpDomId(id); + let argList = []; + if (typeof functionArgs === "string") { + argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); + for (let i = 0; i < argList.length; i++) { + let item = argList[i].trim(); + if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') { + item = item.substr(1, item.length - 2); + } + argList[i] = item; + } + } + if (argList.length === 0) { + argList.push(elemId); + } + functions.push(function() { + const elem = document.querySelector(`[id="${elemId}"]`); + if (elem !== null) { + elem.addEventListener( + "click", + function() { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.u.runFunc(functionName, ...argList); + }, + false + ); + } + }); + } +}; +const bindFunctions = function(element) { + functions.forEach(function(fun) { + fun(element); + }); +}; +const lineType = { + LINE: 0, + DOTTED_LINE: 1 +}; +const relationType = { + AGGREGATION: 0, + EXTENSION: 1, + COMPOSITION: 2, + DEPENDENCY: 3, + LOLLIPOP: 4 +}; +const setupToolTips = function(element) { + let tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(".mermaidTooltip"); + if ((tooltipElem._groups || tooltipElem)[0][0] === null) { + tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body").append("div").attr("class", "mermaidTooltip").style("opacity", 0); + } + const svg = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(element).select("svg"); + const nodes = svg.selectAll("g.node"); + nodes.on("mouseover", function() { + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(this); + const title = el.attr("title"); + if (title === null) { + return; + } + const rect = this.getBoundingClientRect(); + tooltipElem.transition().duration(200).style("opacity", ".9"); + tooltipElem.text(el.attr("title")).style("left", window.scrollX + rect.left + (rect.right - rect.left) / 2 + "px").style("top", window.scrollY + rect.top - 14 + document.body.scrollTop + "px"); + tooltipElem.html(tooltipElem.html().replace(/<br\/>/g, "<br/>")); + el.classed("hover", true); + }).on("mouseout", function() { + tooltipElem.transition().duration(500).style("opacity", 0); + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(this); + el.classed("hover", false); + }); +}; +functions.push(setupToolTips); +let direction = "TB"; +const getDirection = () => direction; +const setDirection = (dir) => { + direction = dir; +}; +const addNamespace = function(id) { + if (namespaces[id] !== void 0) { + return; + } + namespaces[id] = { + id, + classes: {}, + children: {}, + domId: MERMAID_DOM_ID_PREFIX + id + "-" + namespaceCounter + }; + namespaceCounter++; +}; +const getNamespace = function(name) { + return namespaces[name]; +}; +const getNamespaces = function() { + return namespaces; +}; +const addClassesToNamespace = function(id, classNames) { + if (namespaces[id] === void 0) { + return; + } + for (const name of classNames) { + const { className } = splitClassNameAndType(name); + classes[className].parent = id; + namespaces[id].classes[className] = classes[className]; + } +}; +const setCssStyle = function(id, styles2) { + const thisClass = classes[id]; + if (!styles2 || !thisClass) { + return; + } + for (const s of styles2) { + if (s.includes(",")) { + thisClass.styles.push(...s.split(",")); + } else { + thisClass.styles.push(s); + } + } +}; +const db = { + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.g, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.a, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.b, + getConfig: () => (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.c)().class, + addClass, + bindFunctions, + clear, + getClass, + getClasses, + getNotes, + addAnnotation, + addNote, + getRelations, + addRelation, + getDirection, + setDirection, + addMember, + addMembers, + cleanupLabel, + lineType, + relationType, + setClickEvent, + setCssClass, + setLink, + getTooltip, + setTooltip, + lookUpDomId, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.t, + setClassLabel, + addNamespace, + addClassesToNamespace, + getNamespace, + getNamespaces, + setCssStyle +}; +const getStyles = (options) => `g.classGroup text { + fill: ${options.nodeBorder || options.classText}; + stroke: none; + font-family: ${options.fontFamily}; + font-size: 10px; + + .title { + font-weight: bolder; + } + +} + +.nodeLabel, .edgeLabel { + color: ${options.classText}; +} +.edgeLabel .label rect { + fill: ${options.mainBkg}; +} +.label text { + fill: ${options.classText}; +} +.edgeLabel .label span { + background: ${options.mainBkg}; +} + +.classTitle { + font-weight: bolder; +} +.node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + + +.divider { + stroke: ${options.nodeBorder}; + stroke-width: 1; +} + +g.clickable { + cursor: pointer; +} + +g.classGroup rect { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; +} + +g.classGroup line { + stroke: ${options.nodeBorder}; + stroke-width: 1; +} + +.classLabel .box { + stroke: none; + stroke-width: 0; + fill: ${options.mainBkg}; + opacity: 0.5; +} + +.classLabel .label { + fill: ${options.nodeBorder}; + font-size: 10px; +} + +.relation { + stroke: ${options.lineColor}; + stroke-width: 1; + fill: none; +} + +.dashed-line{ + stroke-dasharray: 3; +} + +.dotted-line{ + stroke-dasharray: 1 2; +} + +#compositionStart, .composition { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#compositionEnd, .composition { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#dependencyStart, .dependency { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#dependencyStart, .dependency { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#extensionStart, .extension { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#extensionEnd, .extension { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#aggregationStart, .aggregation { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#aggregationEnd, .aggregation { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#lollipopStart, .lollipop { + fill: ${options.mainBkg} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#lollipopEnd, .lollipop { + fill: ${options.mainBkg} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +.edgeTerminals { + font-size: 11px; + line-height: initial; +} + +.classTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; +} +`; +const styles = getStyles; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/755df717.5f5b8d3a.js b/assets/js/755df717.5f5b8d3a.js new file mode 100644 index 0000000000..b545c45bd2 --- /dev/null +++ b/assets/js/755df717.5f5b8d3a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5429],{48291:(n,e,i)=>{i.r(e),i.d(e,{assets:()=>s,contentTitle:()=>o,default:()=>l,frontMatter:()=>c,metadata:()=>r,toc:()=>d});var a=i(74848),t=i(28453);const c={sidebar_label:"Barbican"},o="Barbican",r={id:"iaas/guides/configuration-guide/openstack/barbican",title:"Barbican",description:"* Barbican admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/barbican.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/barbican",permalink:"/docs/iaas/guides/configuration-guide/openstack/barbican",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/barbican.md",tags:[],version:"current",frontMatter:{sidebar_label:"Barbican"},sidebar:"docs",previous:{title:"Aodh",permalink:"/docs/iaas/guides/configuration-guide/openstack/aodh"},next:{title:"Ceilometer",permalink:"/docs/iaas/guides/configuration-guide/openstack/ceilometer"}},s={},d=[];function u(n){const e={a:"a",h1:"h1",li:"li",ul:"ul",...(0,t.R)(),...n.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.h1,{id:"barbican",children:"Barbican"}),"\n",(0,a.jsxs)(e.ul,{children:["\n",(0,a.jsx)(e.li,{children:(0,a.jsx)(e.a,{href:"https://docs.openstack.org/barbican/latest/admin/index.html",children:"Barbican admin guide"})}),"\n",(0,a.jsx)(e.li,{children:(0,a.jsx)(e.a,{href:"https://docs.openstack.org/barbican/latest/configuration/index.html",children:"Barbican configuration guide"})}),"\n",(0,a.jsx)(e.li,{children:(0,a.jsx)(e.a,{href:"https://docs.openstack.org/barbican/latest/configuration/config.html",children:"Barbican configuration reference"})}),"\n"]})]})}function l(n={}){const{wrapper:e}={...(0,t.R)(),...n.components};return e?(0,a.jsx)(e,{...n,children:(0,a.jsx)(u,{...n})}):u(n)}},28453:(n,e,i)=>{i.d(e,{R:()=>o,x:()=>r});var a=i(96540);const t={},c=a.createContext(t);function o(n){const e=a.useContext(c);return a.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function r(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(t):n.components||t:o(n.components),a.createElement(c.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/760c57f4.e9dc72b5.js b/assets/js/760c57f4.e9dc72b5.js new file mode 100644 index 0000000000..cc4bd84d73 --- /dev/null +++ b/assets/js/760c57f4.e9dc72b5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4385],{83432:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>h});var s=r(74848),t=r(28453),i=r(11470),a=r(19365);const o={sidebar_label:"Ceph",sidebar_position:50},l="Ceph",c={id:"iaas/guides/deploy-guide/services/ceph",title:"Ceph",description:"In OSISM it is also possible to integrate and use existing Ceph clusters. It",source:"@site/docs/02-iaas/guides/deploy-guide/services/ceph.mdx",sourceDirName:"02-iaas/guides/deploy-guide/services",slug:"/iaas/guides/deploy-guide/services/ceph",permalink:"/docs/iaas/guides/deploy-guide/services/ceph",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/ceph.mdx",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"Ceph",sidebar_position:50},sidebar:"docs",previous:{title:"Logging & Monitoring",permalink:"/docs/iaas/guides/deploy-guide/services/logging-monitoring"},next:{title:"OpenStack",permalink:"/docs/iaas/guides/deploy-guide/services/openstack"}},d={},h=[{value:"RGW service",id:"rgw-service",level:2},{value:"Avoiding service restarts",id:"avoiding-service-restarts",level:2},{value:"Throttling service restarts",id:"throttling-service-restarts",level:2}];function p(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"ceph",children:"Ceph"}),"\n",(0,s.jsxs)(n.p,{children:["In OSISM it is also possible to integrate and use existing Ceph clusters. It\nis not necessary to deploy Ceph with OSISM. If Ceph is deployed with OSISM, it\nshould be noted that OSISM does not claim to provide all possible features of Ceph.\nCeph provided with OSISM is intended to provide the storage for Glance, Nova, Cinder\nand Manila. In a specific way that has been implemented by OSISM for years. It\nshould be checked in advance whether the way in OSISM the Ceph deployment and the\nprovided features are sufficient. If this is not the case, it is recommended to\ndeploy Ceph in a different way directly and independently of OSISM. For possible\nopen source projects, please refer to\n",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/latest/cephadm/index.html",children:"cephadm"})," and\n",(0,s.jsx)(n.a,{href:"https://rook.io",children:"Rook"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["Before starting the Ceph deployment, the configuration and creation of the necessary LVM2\nvolumes must be completed. The steps that are required for this can be found in the\n",(0,s.jsx)(n.a,{href:"../../configuration-guide/ceph#lvm-devices",children:"Ceph Configuration Guide"}),"."]})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Deploy services."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Deploy ",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/man/8/ceph-mon/",children:"ceph-mon"})," services"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-mons\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Deploy ceph-mgr services"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-mgrs\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Deploy ",(0,s.jsx)(n.a,{href:"https://docs.ceph.com/en/quincy/man/8/ceph-osd/",children:"ceph-osd"})," services"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-osds\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Generate pools and keys. This step is only necessary for OSISM >= 7.0.0."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-pools\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Deploy ceph-crash services"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-crash\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsx)(n.p,{children:"It's all done step by step here. It is also possible to do this in a single step.\nThis speeds up the entire process and avoids unnecessary restarts of individual\nservices."}),(0,s.jsxs)(i.A,{children:[(0,s.jsxs)(a.A,{value:"osism-7",label:"OSISM >= 7.0.0",children:[(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph\n"})}),(0,s.jsx)(n.p,{children:"Generate pools and keys."}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-pools\n"})})]}),(0,s.jsx)(a.A,{value:"osism-6",label:"OSISM < 7.0.0",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-base\n"})})})]})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Get ceph keys. This places the necessary keys in ",(0,s.jsx)(n.code,{children:"/opt/configuration"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply copy-ceph-keys\n"})}),"\n",(0,s.jsx)(n.p,{children:"After run, these keys must be permanently added to the configuration repository\nvia Git."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"environments/infrastructure/files/ceph/ceph.client.admin.keyring\nenvironments/kolla/files/overlays/gnocchi/ceph.client.gnocchi.keyring\nenvironments/kolla/files/overlays/nova/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/nova/ceph.client.nova.keyring\nenvironments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder-backup.keyring\nenvironments/kolla/files/overlays/cinder/cinder-volume/ceph.client.cinder.keyring\nenvironments/kolla/files/overlays/manila/ceph.client.manila.keyring\nenvironments/kolla/files/overlays/glance/ceph.client.glance.keyring\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"osism apply copy-ceph-keys"})," fails because the keys are not found in the ",(0,s.jsx)(n.code,{children:"/share"}),"\ndirectory, this can be ignored. The keys of the predefined keys (e.g. for Manila) were\nthen not created as they are not used. If you only use Ceph and do not need the predefined\nkeys for OpenStack at all, you can also overwrite the ",(0,s.jsx)(n.code,{children:"ceph_kolla_keys"})," parameter to skip\nthese keys."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/ceph/configuration.yml"',children:"ceph_kolla_keys: []\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"After the Ceph keys have been persisted in the configuration repository, the Ceph\nclient can be deployed."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply cephclient\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Enable and prepare the use of the Ceph dashboard."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-bootstrap-dashboard\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"rgw-service",children:"RGW service"}),"\n",(0,s.jsx)(n.p,{children:"Deployment of the Ceph RGW Service is optional. How the Ceph RGW service can be deployed\nand integrated into OpenStack is described here."}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["If an initial deployment is performed and Ceph RGW is not added to an existing deployment,\nsteps 4 and 5 are ",(0,s.jsx)(n.strong,{children:"not"})," required."]}),(0,s.jsxs)(n.p,{children:["Step 3 is then performed ",(0,s.jsx)(n.strong,{children:"later after"})," the OpenStack Keystone service has been deployed."]})]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"./../../configuration-guide/ceph#rgw-service",children:"Configure the RGW service"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Apply role ",(0,s.jsx)(n.code,{children:"ceph-rgws"})," to deploy the Ceph RGW services."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-rgws\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Apply role ",(0,s.jsx)(n.code,{children:"kolla-ceph-rgw"})," to add the OpenStack endpoint.\nIf an initial deployment is performed and Ceph RGW is not added\nto an existing deployment run this step later after the OpenStack\nKeystone service has been deployed."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply kolla-ceph-rgw\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Apply role ",(0,s.jsx)(n.code,{children:"loadbalancer"})," to add the HAProxy backend and frontend."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply loadbalancer\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Apply role ",(0,s.jsx)(n.code,{children:"horizon"})," to enable the Swift dashboard."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply horizon\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"avoiding-service-restarts",children:"Avoiding service restarts"}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsx)(n.p,{children:"Usable from OSISM 7.0.3 onwards."})}),"\n",(0,s.jsx)(n.p,{children:"If Ceph services are deployed sequentially, this can lead to unwanted service restarts.\nThis can also happen if, for example, new OSDs are added later or a new control node is\nadded."}),"\n",(0,s.jsx)(n.p,{children:"The Ceph RGW services are deployed here without restarting the Ceph OSD services."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-rgws -e ceph_handler_osds_restart=False\n"})}),"\n",(0,s.jsx)(n.p,{children:"The following parameters are available. Any number of parameters can be used with a single command."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph_handler_crash_restart\nceph_handler_mdss_restart\nceph_handler_mgrs_restart\nceph_handler_mons_restart\nceph_handler_osds_restart\nceph_handler_rbdmirrors_restart\nceph_handler_rgws_restart\n"})}),"\n",(0,s.jsx)(n.h2,{id:"throttling-service-restarts",children:"Throttling service restarts"}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsx)(n.p,{children:"Usable from OSISM 7.0.3 onwards."})}),"\n",(0,s.jsx)(n.p,{children:"Sometimes service restarts are required. For example, if the configuration has changed\nor if new OSDs have been added. It may be necessary and useful to only restart the\nservices on a specific number of nodes at a specific time."}),"\n",(0,s.jsxs)(n.p,{children:["Further information on throttling can be found in the\n",(0,s.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_strategies.html#restricting-execution-with-throttle",children:"Ansible documentation"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The Ceph OSD services are deployed here. If there is a restart required of other OSDs\nthat are already running, these restarts are executed on a maximum of 2 nodes at the\nsame time. The OSD services themselves on a node are always restarted one after the other\nand never all at the same time."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply ceph-osds -e ceph_handler_osds_restart_throttle=2\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the nodes are to be processed one after the other, ",(0,s.jsx)(n.code,{children:"ceph_handler_osds_restart_throttle=1"}),"\ncan be used."]}),"\n",(0,s.jsx)(n.p,{children:"The following parameters are available. Any number of parameters can be used with a single command."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"ceph_handler_crash_restart_throttle\nceph_handler_mdss_restart_throttle\nceph_handler_mgrs_restart_throttle\nceph_handler_mons_restart_throttle\nceph_handler_osds_restart_throttle\nceph_handler_rbdmirrors_restart_throttle\nceph_handler_rgws_restart_throttle\n"})})]})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},19365:(e,n,r)=>{r.d(n,{A:()=>a});r(96540);var s=r(18215);const t={tabItem:"tabItem_Ymn6"};var i=r(74848);function a(e){let{children:n,hidden:r,className:a}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,s.A)(t.tabItem,a),hidden:r,children:n})}},11470:(e,n,r)=>{r.d(n,{A:()=>_});var s=r(96540),t=r(18215),i=r(23104),a=r(56347),o=r(205),l=r(57485),c=r(31682),d=r(89466);function h(e){return s.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:n,children:r}=e;return(0,s.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:r,attributes:s,default:t}}=e;return{value:n,label:r,attributes:s,default:t}}))}(r);return function(e){const n=(0,c.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,r])}function u(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:r}=e;const t=(0,a.W6)(),i=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,l.aZ)(i),(0,s.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(t.location.search);n.set(i,e),t.replace({...t.location,search:n.toString()})}),[i,t])]}function f(e){const{defaultValue:n,queryString:r=!1,groupId:t}=e,i=p(e),[a,l]=(0,s.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!u({value:n,tabValues:r}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const s=r.find((e=>e.default))??r[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:i}))),[c,h]=m({queryString:r,groupId:t}),[f,x]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,i]=(0,d.Dv)(r);return[t,(0,s.useCallback)((e=>{r&&i.set(e)}),[r,i])]}({groupId:t}),y=(()=>{const e=c??f;return u({value:e,tabValues:i})?e:null})();(0,o.A)((()=>{y&&l(y)}),[y]);return{selectedValue:a,selectValue:(0,s.useCallback)((e=>{if(!u({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),h(e),x(e)}),[h,x,i]),tabValues:i}}var x=r(92303);const y={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var v=r(74848);function j(e){let{className:n,block:r,selectedValue:s,selectValue:a,tabValues:o}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,i.a_)(),d=e=>{const n=e.currentTarget,r=l.indexOf(n),t=o[r].value;t!==s&&(c(n),a(t))},h=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;n=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;n=l[r]??l[l.length-1];break}}n?.focus()};return(0,v.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":r},n),children:o.map((e=>{let{value:n,label:r,attributes:i}=e;return(0,v.jsx)("li",{role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,ref:e=>l.push(e),onKeyDown:h,onClick:d,...i,className:(0,t.A)("tabs__item",y.tabItem,i?.className,{"tabs__item--active":s===n}),children:r??n},n)}))})}function g(e){let{lazy:n,children:r,selectedValue:t}=e;const i=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===t));return e?(0,s.cloneElement)(e,{className:"margin-top--md"}):null}return(0,v.jsx)("div",{className:"margin-top--md",children:i.map(((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function b(e){const n=f(e);return(0,v.jsxs)("div",{className:(0,t.A)("tabs-container",y.tabList),children:[(0,v.jsx)(j,{...e,...n}),(0,v.jsx)(g,{...e,...n})]})}function _(e){const n=(0,x.A)();return(0,v.jsx)(b,{...e,children:h(e.children)},String(n))}},28453:(e,n,r)=>{r.d(n,{R:()=>a,x:()=>o});var s=r(96540);const t={},i=s.createContext(t);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/767805d3.e8fd2720.js b/assets/js/767805d3.e8fd2720.js new file mode 100644 index 0000000000..50e246cd0e --- /dev/null +++ b/assets/js/767805d3.e8fd2720.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8519],{63901:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>l,toc:()=>c});var i=t(74848),r=t(28453);const s={sidebar_label:"Configuration repository",sidebar_position:10},o="Configuration Repository",l={id:"iaas/guides/configuration-guide/configuration-repository",title:"Configuration Repository",description:"The configuration required for an OSISM managed cluster is stored in a single Git",source:"@site/docs/02-iaas/guides/configuration-guide/configuration-repository.md",sourceDirName:"02-iaas/guides/configuration-guide",slug:"/iaas/guides/configuration-guide/configuration-repository",permalink:"/docs/iaas/guides/configuration-guide/configuration-repository",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/configuration-repository.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Configuration repository",sidebar_position:10},sidebar:"docs",previous:{title:"Configuration Guide",permalink:"/docs/iaas/guides/configuration-guide/"},next:{title:"Inventory",permalink:"/docs/iaas/guides/configuration-guide/inventory"}},d={},c=[{value:"Creating a new configuration repository",id:"creating-a-new-configuration-repository",level:2},{value:"Step 1: Preparation",id:"step-1-preparation",level:3},{value:"Step 2: Run Cookiecutter",id:"step-2-run-cookiecutter",level:3},{value:"Step 3: Upload the new configuration to the remote git repository",id:"step-3-upload-the-new-configuration-to-the-remote-git-repository",level:3},{value:"Step 4: Post-processing of the generated configuration",id:"step-4-post-processing-of-the-generated-configuration",level:3},{value:"Secrets",id:"secrets",level:4},{value:"Manager inventory",id:"manager-inventory",level:4},{value:"Global inventory",id:"global-inventory",level:4},{value:"DNS servers",id:"dns-servers",level:4},{value:"NTP servers",id:"ntp-servers",level:4},{value:"SSL certificates",id:"ssl-certificates",level:4},{value:"Using latest",id:"using-latest",level:2},{value:"Parameter reference",id:"parameter-reference",level:2},{value:"Configuration repository layout",id:"configuration-repository-layout",level:2},{value:"Synchronising the configuration repository",id:"synchronising-the-configuration-repository",level:2},{value:"Locks",id:"locks",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"configuration-repository",children:"Configuration Repository"}),"\n",(0,i.jsx)(n.p,{children:"The configuration required for an OSISM managed cluster is stored in a single Git\nmonorepo, the configuration repository."}),"\n",(0,i.jsx)(n.h2,{id:"creating-a-new-configuration-repository",children:"Creating a new configuration repository"}),"\n",(0,i.jsxs)(n.p,{children:["The initial content for this configuration repository is generated using the\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/cfg-cookiecutter",children:"Cookiecutter"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Cookiecutter generates a simple initial configuration for your new cluster by prompting\nyou for the basic details of the new cluster."}),"\n",(0,i.jsxs)(n.p,{children:["The configuration repository is not created on the future Manager node. It is created on a\nlocal workstation. If the local workstation cannot be used for this purpose, a dedicated\nvirtual system can be used. For more information on this topic, refer to the\n",(0,i.jsx)(n.a,{href:"/docs/iaas/guides/deploy-guide/seed",children:"Seed Deploy Guide"}),".."]}),"\n",(0,i.jsx)(n.h3,{id:"step-1-preparation",children:"Step 1: Preparation"}),"\n",(0,i.jsxs)(n.p,{children:["First decide where to store your Git repository The content generated by the cookiecutter in\nthe ",(0,i.jsx)(n.code,{children:"output/configuration"})," directory is committed to a new Git repository. By default, the\nconfiguration repository is assumed to be on GitHub. This can also be GitLab or an internal\nGit service as well."]}),"\n",(0,i.jsxs)(n.p,{children:["Host and path to the Git repository are specified by the ",(0,i.jsx)(n.code,{children:"git_"})," parameters. These are\nrequested in step 2. The ",(0,i.jsx)(n.code,{children:"git_"})," parameters do not specify the path to the cookiecutter\nto use."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:" [8/20] git_host (github.com):\n [9/20] git_port (22):\n [10/20] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY): regiocloud/configuration\n [11/20] git_username (git):\n [12/20] git_version (main):\n"})}),"\n",(0,i.jsxs)(n.p,{children:["In this case, the generated configuration in the ",(0,i.jsx)(n.code,{children:"output/configuration"})," directory is\nstored on GitHub in the ",(0,i.jsx)(n.code,{children:"regiocloud/configuration"})," repository."]}),"\n",(0,i.jsxs)(n.p,{children:["See the ",(0,i.jsx)(n.a,{href:"#parameter-reference",children:"parameter reference"})," for more details. The parameters\nlisted there will be queried during the execution of Cookiecutter."]}),"\n",(0,i.jsx)(n.h3,{id:"step-2-run-cookiecutter",children:"Step 2: Run Cookiecutter"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The directory ",(0,i.jsx)(n.code,{children:"output"})," is created and used as output volume. It is only necessary to create the empty\ndirectory here."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"mkdir output\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The Cookiecutter runs inside a container. ",(0,i.jsx)(n.a,{href:"https://docs.docker.com/engine/install/",children:"Docker must be usable on the system"}),"\nwhere the Cookiecutter will be used. It should also work with Podman."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'docker run \\\n -e TARGET_UID="$(id -u)" \\\n -e TARGET_GID="$(id -g)" \\\n -v $(pwd)/output:/output \\\n --rm -it quay.io/osism/cookiecutter\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["A few parameters are requested. The parameters are documented in detail in the ",(0,i.jsx)(n.a,{href:"#parameters-reference",children:"Parameters reference"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["If you want to use the ",(0,i.jsx)(n.code,{children:"latest"})," version, this is done using the ",(0,i.jsx)(n.code,{children:"manager_version"})," parameter. By default,\nthis is always set to the latest stable version."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"manager_version [7.0.4]: latest\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"manager_version"})," parameter is set to ",(0,i.jsx)(n.code,{children:"latest"})," it is also possible to explicitly\nset the ",(0,i.jsx)(n.code,{children:"openstack_version"})," and the ",(0,i.jsx)(n.code,{children:"ceph_version"})," explicitly."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[1/19] with_ceph (1):\n[2/19] with_keycloak (0):\n[3/19] ceph_network(192.168.64.0/19):\n[4/19] ceph_version (quincy):\n[5/19] domain (osism.xyz):\n[6/19] fqdn_external (api.osism.xyz):\n[7/19] fqdn_internal (api-int.osism.xyz):\n[8/19] git_host (github.com):\n[9/19] git_port (22):\n[10/19] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY):\n[11/19] git_username (git):\n[12/19] git_version (main):\n[13/19] ip_external (192.168.96.9):\n[14/19] ip_internal (192.168.32.9):\n[15/19] manager_version (7.0.4):\n[16/19] name_server (149.112.112.112):\n[17/19] ntp_server (de.pool.ntp.org):\n[18/19] openstack_version (2023.2):\n[19/19] project_name (configuration):\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"step-3-upload-the-new-configuration-to-the-remote-git-repository",children:"Step 3: Upload the new configuration to the remote git repository"}),"\n",(0,i.jsxs)(n.p,{children:["Add the initial configuration state to the repository. How to add a deploy key on GitHub is documented in\n",(0,i.jsx)(n.a,{href:"https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys",children:"Managing deploy keys"}),".\nRead permissions are sufficient."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'$ git clone git@github.com:YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY.git YOUR_NEW_CONFIGURATION_REPOSITORY\n$ cp -r output/configuration/{*,.gitignore} YOUR_NEW_CONFIGURATION_REPOSITORY\n$ cd YOUR_NEW_CONFIGURATION_REPOSITORY\n$ git add -A .\n$ git commit -m "Initial commit after bootstrap"\n$ git push\n'})}),"\n",(0,i.jsx)(n.p,{children:"The content is now committed to the Git repository that was created earlier in the process."}),"\n",(0,i.jsxs)(n.admonition,{type:"warning",children:[(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"secrets"})," directory is not stored in the Git repository. Its contents can be\nstored in a trusted location."]}),(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"secrets"})," directory contains an SSH key pair which is used as the deploy key to\nmake the configuration repository available on the manager node later. Write access\nis not required. The public SSH key is stored in the ",(0,i.jsx)(n.code,{children:"secrets/id_rsa.configuration.pub"})," file."]})]}),"\n",(0,i.jsx)(n.h3,{id:"step-4-post-processing-of-the-generated-configuration",children:"Step 4: Post-processing of the generated configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The configuration repository that is initially created with the Cookiecutter is not immediately usable.\nFor example, the inventory needs to be built. All other information can be found in the\n",(0,i.jsx)(n.a,{href:"../configuration-guide/",children:"Configuration Guide"}),". Use ",(0,i.jsx)(n.code,{children:"git"})," to version all your configuration changes."]}),"\n",(0,i.jsx)(n.p,{children:"The following 6 points must be changed after the initial creation of the configuration repository."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#secrets",children:"Secrets"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#manager-inventory",children:"Manager inventory"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#global-inventory",children:"Global inventory"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#dns-servers",children:"DNS servers"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#ntp-servers",children:"NTP servers"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#ssl-certificates",children:"SSL certificates"})}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"secrets",children:"Secrets"}),"\n",(0,i.jsxs)(n.p,{children:["The password for Ansible Vault encrypted files, is stored in ",(0,i.jsx)(n.code,{children:"secrets/vaultpass"}),". Since the ",(0,i.jsx)(n.code,{children:"secrets"})," directory\nis not added to the configuration repository, it is important to store it in a password vault of your choice."]}),"\n",(0,i.jsxs)(n.p,{children:["The password of the generated Keepass file is ",(0,i.jsx)(n.code,{children:"password"}),". This should be changed when using the Keepass file.\nIf possible, an existing password vault should be used."]}),"\n",(0,i.jsx)(n.h4,{id:"manager-inventory",children:"Manager inventory"}),"\n",(0,i.jsx)(n.p,{children:"The information required to perform the initial bootstrap of the manager node and the initial\ndeployment of the manager service from the seed Node is provided in the inventory of the manager\nenvironment."}),"\n",(0,i.jsxs)(n.p,{children:["In the Cookiecutter, a node ",(0,i.jsx)(n.code,{children:"node01"})," is defined as an example in the manager inventory as well as\nin the global inventory. The name of this node must be changed to match the name of the node used\nas manager in your own cluster."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Roles"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Manager role"}),"\n",(0,i.jsxs)(n.p,{children:["The name of the node on which the manager service is to be deployed is\nadded to inventory group ",(0,i.jsx)(n.code,{children:"manager"})," in file ",(0,i.jsx)(n.code,{children:"environments/manager/hosts"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Only the ",(0,i.jsx)(n.code,{children:"manager"})," inventory group is available in ",(0,i.jsx)(n.code,{children:"environments/manager/hosts"}),". There are no\nother groups there."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="environments/manager/hosts"',children:"[manager]\nnode01\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Host vars"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ansible section"}),"\n",(0,i.jsx)(n.p,{children:"The IP address where the node can be reached via SSH from the manager node. If DHCP is used after the\ninitial provisioning to assign an initial IP address to the nodes, the address assigned via DHCP is\ninitially used here and later changed to the static IP address."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/host_vars/node01.yml"',children:"ansible_host: 192.168.16.10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Generic section"}),"\n",(0,i.jsx)(n.p,{children:"The network interface on which the internal communication of the cluster will take place. If the\ninternal interface does not yet exist at the time the configuration is created, e.g. because it is a\nbond interface or VLAN interface that is only created by the static network configuration, it can be\nalready used here."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/host_vars/node01.yml"',children:"internal_interface: eno1\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Network section"}),"\n",(0,i.jsxs)(n.p,{children:["The static and complete network configuration of the node. Further details on creating the\nnetwork configuration in the ",(0,i.jsx)(n.a,{href:"../configuration-guide/network",children:"network configuration guide"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/manager/host_vars/node01.yml"',children:'network_ethernets:\n eno1:\n addresses:\n - "192.168.16.10/20"\n gateway4: "192.168.16.1"\n mtu: 1500\n'})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"global-inventory",children:"Global inventory"}),"\n",(0,i.jsxs)(n.p,{children:["In the Cookiecutter, a node ",(0,i.jsx)(n.code,{children:"node01"})," is defined as an example in the manager inventory as well as\nin the global inventory. The name of this node must be changed to match the name of the node used\nas manager in your own cluster."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Roles"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Generic role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:'# The "all" group is not used in OSISM. Therefore it is important\n# that all nodes are explicitly listed here.\n[generic]\nnode01\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Manager role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes that act as manager (sometimes called deployment node)\n# are included in this group.\n[manager]\nnode01\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Monitoring role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes which are intended for monitoring services belong to\n# this group\n[monitoring]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Control role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes that serve as controllers, so things like scheduler,\n# API or database run there, of the environment.\n[control]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Compute role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Virtual systems managed by OpenStack Nova are placed on\n# nodes in this group.\n[compute]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Network role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Network resources managed by OpenStack Neutron, such as\n# L3 routers, are placed on these nodes. This group has nothing\n# to do with the general network configuration.\n[network]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceph control role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# Nodes that serve as controllers for Ceph, so things like the\n# Ceph Monitor service run here.\n[ceph-control]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceph resource role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"# The storage available in these systems is provided in the\n# form of OSDs for Ceph.\n[ceph-resource]\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceph rgw role"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/20-roles"',children:"[ceph-rgw:children]\nceph-control\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Host vars"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ansible section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"# NOTE: Address where the node can be reached via SSH.\nansible_host: 192.168.16.10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Generic section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"internal_interface: eno1\n\n# NOTE: The address of the internal interface.\ninternal_address: 192.168.16.10\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Netdata section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"netdata_host_type: client\n\n# NOTE: Uncomment this when this node should be a Netdata server.\n# netdata_host_type: server\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Network section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:'# NOTE: This is the initial management interface. Further interfaces can be added.\n# DOCS: https://osism.tech/docs/guides/configuration-guide/network\n\nnetwork_ethernets:\n eno1:\n addresses:\n - "192.168.16.10/20"\n gateway4: "192.168.16.1"\n mtu: 1500\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Kolla section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"network_interface: eno1\n\n# api_interface:\n# bifrost_network_interface:\n# dns_interface:\n# kolla_external_vip_interface:\n# migration_interface:\n# neutron_external_interface:\n# octavia_network_interface:\n# storage_interface:\n# tunnel_interface:\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceph section"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"# NOTE: Uncomment this when this node is a part of the Ceph cluster.\n# monitor_address:\n# radosgw_address:\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/node01.yml"',children:"# NOTE: Uncomment this when this node should be a OSD node.\n# DOCS: https://osism.tech/docs/guides/configuration-guide/ceph#lvm-devices\n\n# ceph_osd_devices:\n# sdb:\n# sdc:\n# sdd:\n# sde:\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"dns-servers",children:"DNS servers"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"resolvconf_nameserver:\n - 8.8.8.8\n - 9.9.9.9\n"})}),"\n",(0,i.jsx)(n.h4,{id:"ntp-servers",children:"NTP servers"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"chrony_servers:\n - 1.de.pool.ntp.org\n - 2.de.pool.ntp.org\n - 3.de.pool.ntp.org\n - 4.de.pool.ntp.org\n"})}),"\n",(0,i.jsx)(n.h4,{id:"ssl-certificates",children:"SSL certificates"}),"\n",(0,i.jsx)(n.h2,{id:"using-latest",children:"Using latest"}),"\n",(0,i.jsxs)(n.p,{children:["If you want to use the latest version, this is done using the ",(0,i.jsx)(n.code,{children:"manager_version"})," parameter. By default,\nthis is always set to the latest stable version."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"manager_version [7.0.0]: latest\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"manager_version"})," parameter is set to ",(0,i.jsx)(n.code,{children:"latest"})," it is also possible to explicitly\nset the ",(0,i.jsx)(n.code,{children:"openstack_version"})," and the ",(0,i.jsx)(n.code,{children:"ceph_version"})," explicitly."]}),"\n",(0,i.jsx)(n.h2,{id:"parameter-reference",children:"Parameter reference"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Description"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ceph_network"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Address range for Ceph's network"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"192.168.64.0/20"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ceph_version"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The version of Ceph. When using a stable OSISM release (",(0,i.jsx)(n.code,{children:"manager_version != latest"}),"), this value is ignored"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"quincy"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"domain"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"The domain used by hostnames"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"osism.xyz"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"fqdn_external"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"External API FQDN"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"api.osism.xyz"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"fqdn_internal"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Internal API FQDN"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"api-int.osism.xyz"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_host"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Address of the used Git server"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"github.com"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_port"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Port of the used Git server"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"22"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_repository"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Path to the git configuration repository"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"YOUR_ORG/YOUR_CONFIGURATION_REPOSITORY"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_username"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Username of the git repository"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"git_version"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Git branch name"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"main"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ip_external"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The external IP address of the API (resolves to ",(0,i.jsx)(n.code,{children:"fqdn_external"}),")"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"192.168.96.9"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ip_internal"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The internal IP address of the API (resolves to ",(0,i.jsx)(n.code,{children:"fqdn_internal"}),")"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"192.168.32.9"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"manager_version"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The version of OSISM. An overview of available OSISM releases can be found ",(0,i.jsx)(n.a,{href:"https://osism.tech/docs/release-notes/",children:"here"})]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"7.0.4"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"name_server"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Nameserver. Only one nameserver is set here because the query of multiple values in Cookiecutter is weird. Add more nameservers afterward."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"149.112.112.112"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ntp_server"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"NTP server. Only one NTP server is set here because the query of multiple values in Cookiecutter is weird. Add more NTP servers afterward."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"de.pool.ntp.org"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"openstack_version"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["The version of OpenStack. When using a stable OSISM release (",(0,i.jsx)(n.code,{children:"manager_version != latest"}),"), this value is ignored"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"2023.2"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"project_name"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Name of the configuration repository directory"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"configuration"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"with_ceph"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:[(0,i.jsx)(n.code,{children:"1"})," to use Ceph, ",(0,i.jsx)(n.code,{children:"0"})," to not use Ceph"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"1"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"with_keycloak"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:[(0,i.jsx)(n.code,{children:"1"})," to prepare Keycloak integration , ",(0,i.jsx)(n.code,{children:"0"})," to not prepare Keycloak integration"]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"0"})})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"configuration-repository-layout",children:"Configuration repository layout"}),"\n",(0,i.jsxs)(n.p,{children:["A configuration repository always has the same layout. This section describes\nthe content available in a configuration repository. In the section\n",(0,i.jsx)(n.a,{href:"#creating-a-new-configuration-repository",children:"Creating a new configuration repository"})," is the creation\nof a new configuration repository documented."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Directory/File"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"environments"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"inventory"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"netbox"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"optional"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"requirements.txt"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["In the ",(0,i.jsx)(n.code,{children:"requirements.txt"})," the necessary dependencies are listed to be able to execute Gilt."]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"gilt.yml"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"Makefile"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"gilt.yaml"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:[(0,i.jsx)(n.a,{href:"https://gilt.readthedocs.io",children:"Gilt"})," is a Git layering tool. We use Gilt to maintain the image versions, Ansible configuration and scripts within the ",(0,i.jsx)(n.code,{children:"environments/manager"})," directory."]})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"synchronising-the-configuration-repository",children:"Synchronising the configuration repository"}),"\n",(0,i.jsxs)(n.p,{children:["Once the manager has been deployed and the configuration repository has been initially\ntransferred to the manager node, the configuration repository can be updated using\n",(0,i.jsx)(n.code,{children:"osism apply configuration"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"If local changes were made directly in the configuration repository on the manager node,\nthese are overwritten."}),"\n",(0,i.jsx)(n.h2,{id:"locks",children:"Locks"}),"\n",(0,i.jsx)(n.p,{children:"It is possible to lock parts of the configuration repository or the complete configuration\nrepository. It is then no longer possible to execute plays assigned to these parts in the\nlocked parts. This makes it possible to prevent the execution of plays in specific areas."}),"\n",(0,i.jsxs)(n.p,{children:["To lock an environment, a .lock file is created in the corresponding directory of the environment.\nFor example, the file ",(0,i.jsx)(n.code,{children:"environments/kolla/.lock"})," locks the Kolla environment."]}),"\n",(0,i.jsx)(n.p,{children:"If you try to execute a play in the Kolla environment, an error message is displayed."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply common\n2024-06-02 10:52:44 | INFO | Task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) was prepared for execution.\n2024-06-02 10:52:44 | INFO | It takes a moment until task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) has been started and output is visible here.\nERROR: The environment kolla is locked via the configuration repository.\n"})}),"\n",(0,i.jsxs)(n.p,{children:["File ",(0,i.jsx)(n.code,{children:"environments/.lock"})," is created to lock everything."]}),"\n",(0,i.jsx)(n.p,{children:"If you try to execute a play, an error message is displayed."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ osism apply facts\n2024-06-02 10:53:08 | INFO | Task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) was prepared for execution.\n2024-06-02 10:53:08 | INFO | It takes a moment until task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) has been started and output is visible here.\nERROR: The configuration repository is locked.\n"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>l});var i=t(96540);const r={},s=i.createContext(r);function o(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/771.e32975e9.js b/assets/js/771.e32975e9.js new file mode 100644 index 0000000000..6ce6c5c765 --- /dev/null +++ b/assets/js/771.e32975e9.js @@ -0,0 +1,51749 @@ +exports.id = 771; +exports.ids = [771]; +exports.modules = { + +/***/ 87799: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +(function webpackUniversalModuleDefinition(root, factory) { + if(true) + module.exports = factory(__webpack_require__(23143)); + else {} +})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __nested_webpack_require_643__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_643__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __nested_webpack_require_643__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __nested_webpack_require_643__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __nested_webpack_require_643__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __nested_webpack_require_643__.d = function(exports, name, getter) { +/******/ if(!__nested_webpack_require_643__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __nested_webpack_require_643__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __nested_webpack_require_643__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __nested_webpack_require_643__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __nested_webpack_require_643__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __nested_webpack_require_643__(__nested_webpack_require_643__.s = 7); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_0__; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __nested_webpack_require_3185__) { + +"use strict"; + + +var FDLayoutConstants = __nested_webpack_require_3185__(0).FDLayoutConstants; + +function CoSEConstants() {} + +//CoSEConstants inherits static props in FDLayoutConstants +for (var prop in FDLayoutConstants) { + CoSEConstants[prop] = FDLayoutConstants[prop]; +} + +CoSEConstants.DEFAULT_USE_MULTI_LEVEL_SCALING = false; +CoSEConstants.DEFAULT_RADIAL_SEPARATION = FDLayoutConstants.DEFAULT_EDGE_LENGTH; +CoSEConstants.DEFAULT_COMPONENT_SEPERATION = 60; +CoSEConstants.TILE = true; +CoSEConstants.TILING_PADDING_VERTICAL = 10; +CoSEConstants.TILING_PADDING_HORIZONTAL = 10; +CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL = false; // make this true when cose is used incrementally as a part of other non-incremental layout + +module.exports = CoSEConstants; + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __nested_webpack_require_4002__) { + +"use strict"; + + +var FDLayoutEdge = __nested_webpack_require_4002__(0).FDLayoutEdge; + +function CoSEEdge(source, target, vEdge) { + FDLayoutEdge.call(this, source, target, vEdge); +} + +CoSEEdge.prototype = Object.create(FDLayoutEdge.prototype); +for (var prop in FDLayoutEdge) { + CoSEEdge[prop] = FDLayoutEdge[prop]; +} + +module.exports = CoSEEdge; + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __nested_webpack_require_4409__) { + +"use strict"; + + +var LGraph = __nested_webpack_require_4409__(0).LGraph; + +function CoSEGraph(parent, graphMgr, vGraph) { + LGraph.call(this, parent, graphMgr, vGraph); +} + +CoSEGraph.prototype = Object.create(LGraph.prototype); +for (var prop in LGraph) { + CoSEGraph[prop] = LGraph[prop]; +} + +module.exports = CoSEGraph; + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __nested_webpack_require_4790__) { + +"use strict"; + + +var LGraphManager = __nested_webpack_require_4790__(0).LGraphManager; + +function CoSEGraphManager(layout) { + LGraphManager.call(this, layout); +} + +CoSEGraphManager.prototype = Object.create(LGraphManager.prototype); +for (var prop in LGraphManager) { + CoSEGraphManager[prop] = LGraphManager[prop]; +} + +module.exports = CoSEGraphManager; + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __nested_webpack_require_5205__) { + +"use strict"; + + +var FDLayoutNode = __nested_webpack_require_5205__(0).FDLayoutNode; +var IMath = __nested_webpack_require_5205__(0).IMath; + +function CoSENode(gm, loc, size, vNode) { + FDLayoutNode.call(this, gm, loc, size, vNode); +} + +CoSENode.prototype = Object.create(FDLayoutNode.prototype); +for (var prop in FDLayoutNode) { + CoSENode[prop] = FDLayoutNode[prop]; +} + +CoSENode.prototype.move = function () { + var layout = this.graphManager.getLayout(); + this.displacementX = layout.coolingFactor * (this.springForceX + this.repulsionForceX + this.gravitationForceX) / this.noOfChildren; + this.displacementY = layout.coolingFactor * (this.springForceY + this.repulsionForceY + this.gravitationForceY) / this.noOfChildren; + + if (Math.abs(this.displacementX) > layout.coolingFactor * layout.maxNodeDisplacement) { + this.displacementX = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementX); + } + + if (Math.abs(this.displacementY) > layout.coolingFactor * layout.maxNodeDisplacement) { + this.displacementY = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementY); + } + + // a simple node, just move it + if (this.child == null) { + this.moveBy(this.displacementX, this.displacementY); + } + // an empty compound node, again just move it + else if (this.child.getNodes().length == 0) { + this.moveBy(this.displacementX, this.displacementY); + } + // non-empty compound node, propogate movement to children as well + else { + this.propogateDisplacementToChildren(this.displacementX, this.displacementY); + } + + layout.totalDisplacement += Math.abs(this.displacementX) + Math.abs(this.displacementY); + + this.springForceX = 0; + this.springForceY = 0; + this.repulsionForceX = 0; + this.repulsionForceY = 0; + this.gravitationForceX = 0; + this.gravitationForceY = 0; + this.displacementX = 0; + this.displacementY = 0; +}; + +CoSENode.prototype.propogateDisplacementToChildren = function (dX, dY) { + var nodes = this.getChild().getNodes(); + var node; + for (var i = 0; i < nodes.length; i++) { + node = nodes[i]; + if (node.getChild() == null) { + node.moveBy(dX, dY); + node.displacementX += dX; + node.displacementY += dY; + } else { + node.propogateDisplacementToChildren(dX, dY); + } + } +}; + +CoSENode.prototype.setPred1 = function (pred1) { + this.pred1 = pred1; +}; + +CoSENode.prototype.getPred1 = function () { + return pred1; +}; + +CoSENode.prototype.getPred2 = function () { + return pred2; +}; + +CoSENode.prototype.setNext = function (next) { + this.next = next; +}; + +CoSENode.prototype.getNext = function () { + return next; +}; + +CoSENode.prototype.setProcessed = function (processed) { + this.processed = processed; +}; + +CoSENode.prototype.isProcessed = function () { + return processed; +}; + +module.exports = CoSENode; + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __nested_webpack_require_8085__) { + +"use strict"; + + +var FDLayout = __nested_webpack_require_8085__(0).FDLayout; +var CoSEGraphManager = __nested_webpack_require_8085__(4); +var CoSEGraph = __nested_webpack_require_8085__(3); +var CoSENode = __nested_webpack_require_8085__(5); +var CoSEEdge = __nested_webpack_require_8085__(2); +var CoSEConstants = __nested_webpack_require_8085__(1); +var FDLayoutConstants = __nested_webpack_require_8085__(0).FDLayoutConstants; +var LayoutConstants = __nested_webpack_require_8085__(0).LayoutConstants; +var Point = __nested_webpack_require_8085__(0).Point; +var PointD = __nested_webpack_require_8085__(0).PointD; +var Layout = __nested_webpack_require_8085__(0).Layout; +var Integer = __nested_webpack_require_8085__(0).Integer; +var IGeometry = __nested_webpack_require_8085__(0).IGeometry; +var LGraph = __nested_webpack_require_8085__(0).LGraph; +var Transform = __nested_webpack_require_8085__(0).Transform; + +function CoSELayout() { + FDLayout.call(this); + + this.toBeTiled = {}; // Memorize if a node is to be tiled or is tiled +} + +CoSELayout.prototype = Object.create(FDLayout.prototype); + +for (var prop in FDLayout) { + CoSELayout[prop] = FDLayout[prop]; +} + +CoSELayout.prototype.newGraphManager = function () { + var gm = new CoSEGraphManager(this); + this.graphManager = gm; + return gm; +}; + +CoSELayout.prototype.newGraph = function (vGraph) { + return new CoSEGraph(null, this.graphManager, vGraph); +}; + +CoSELayout.prototype.newNode = function (vNode) { + return new CoSENode(this.graphManager, vNode); +}; + +CoSELayout.prototype.newEdge = function (vEdge) { + return new CoSEEdge(null, null, vEdge); +}; + +CoSELayout.prototype.initParameters = function () { + FDLayout.prototype.initParameters.call(this, arguments); + if (!this.isSubLayout) { + if (CoSEConstants.DEFAULT_EDGE_LENGTH < 10) { + this.idealEdgeLength = 10; + } else { + this.idealEdgeLength = CoSEConstants.DEFAULT_EDGE_LENGTH; + } + + this.useSmartIdealEdgeLengthCalculation = CoSEConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION; + this.springConstant = FDLayoutConstants.DEFAULT_SPRING_STRENGTH; + this.repulsionConstant = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH; + this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH; + this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH; + this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR; + this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR; + + // variables for tree reduction support + this.prunedNodesAll = []; + this.growTreeIterations = 0; + this.afterGrowthIterations = 0; + this.isTreeGrowing = false; + this.isGrowthFinished = false; + + // variables for cooling + this.coolingCycle = 0; + this.maxCoolingCycle = this.maxIterations / FDLayoutConstants.CONVERGENCE_CHECK_PERIOD; + this.finalTemperature = FDLayoutConstants.CONVERGENCE_CHECK_PERIOD / this.maxIterations; + this.coolingAdjuster = 1; + } +}; + +CoSELayout.prototype.layout = function () { + var createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED; + if (createBendsAsNeeded) { + this.createBendpoints(); + this.graphManager.resetAllEdges(); + } + + this.level = 0; + return this.classicLayout(); +}; + +CoSELayout.prototype.classicLayout = function () { + this.nodesWithGravity = this.calculateNodesToApplyGravitationTo(); + this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity); + this.calcNoOfChildrenForAllNodes(); + this.graphManager.calcLowestCommonAncestors(); + this.graphManager.calcInclusionTreeDepths(); + this.graphManager.getRoot().calcEstimatedSize(); + this.calcIdealEdgeLengths(); + + if (!this.incremental) { + var forest = this.getFlatForest(); + + // The graph associated with this layout is flat and a forest + if (forest.length > 0) { + this.positionNodesRadially(forest); + } + // The graph associated with this layout is not flat or a forest + else { + // Reduce the trees when incremental mode is not enabled and graph is not a forest + this.reduceTrees(); + // Update nodes that gravity will be applied + this.graphManager.resetAllNodesToApplyGravitation(); + var allNodes = new Set(this.getAllNodes()); + var intersection = this.nodesWithGravity.filter(function (x) { + return allNodes.has(x); + }); + this.graphManager.setAllNodesToApplyGravitation(intersection); + + this.positionNodesRandomly(); + } + } else { + if (CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL) { + // Reduce the trees in incremental mode if only this constant is set to true + this.reduceTrees(); + // Update nodes that gravity will be applied + this.graphManager.resetAllNodesToApplyGravitation(); + var allNodes = new Set(this.getAllNodes()); + var intersection = this.nodesWithGravity.filter(function (x) { + return allNodes.has(x); + }); + this.graphManager.setAllNodesToApplyGravitation(intersection); + } + } + + this.initSpringEmbedder(); + this.runSpringEmbedder(); + + return true; +}; + +CoSELayout.prototype.tick = function () { + this.totalIterations++; + + if (this.totalIterations === this.maxIterations && !this.isTreeGrowing && !this.isGrowthFinished) { + if (this.prunedNodesAll.length > 0) { + this.isTreeGrowing = true; + } else { + return true; + } + } + + if (this.totalIterations % FDLayoutConstants.CONVERGENCE_CHECK_PERIOD == 0 && !this.isTreeGrowing && !this.isGrowthFinished) { + if (this.isConverged()) { + if (this.prunedNodesAll.length > 0) { + this.isTreeGrowing = true; + } else { + return true; + } + } + + this.coolingCycle++; + + if (this.layoutQuality == 0) { + // quality - "draft" + this.coolingAdjuster = this.coolingCycle; + } else if (this.layoutQuality == 1) { + // quality - "default" + this.coolingAdjuster = this.coolingCycle / 3; + } + + // cooling schedule is based on http://www.btluke.com/simanf1.html -> cooling schedule 3 + this.coolingFactor = Math.max(this.initialCoolingFactor - Math.pow(this.coolingCycle, Math.log(100 * (this.initialCoolingFactor - this.finalTemperature)) / Math.log(this.maxCoolingCycle)) / 100 * this.coolingAdjuster, this.finalTemperature); + this.animationPeriod = Math.ceil(this.initialAnimationPeriod * Math.sqrt(this.coolingFactor)); + } + // Operations while tree is growing again + if (this.isTreeGrowing) { + if (this.growTreeIterations % 10 == 0) { + if (this.prunedNodesAll.length > 0) { + this.graphManager.updateBounds(); + this.updateGrid(); + this.growTree(this.prunedNodesAll); + // Update nodes that gravity will be applied + this.graphManager.resetAllNodesToApplyGravitation(); + var allNodes = new Set(this.getAllNodes()); + var intersection = this.nodesWithGravity.filter(function (x) { + return allNodes.has(x); + }); + this.graphManager.setAllNodesToApplyGravitation(intersection); + + this.graphManager.updateBounds(); + this.updateGrid(); + this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL; + } else { + this.isTreeGrowing = false; + this.isGrowthFinished = true; + } + } + this.growTreeIterations++; + } + // Operations after growth is finished + if (this.isGrowthFinished) { + if (this.isConverged()) { + return true; + } + if (this.afterGrowthIterations % 10 == 0) { + this.graphManager.updateBounds(); + this.updateGrid(); + } + this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL * ((100 - this.afterGrowthIterations) / 100); + this.afterGrowthIterations++; + } + + var gridUpdateAllowed = !this.isTreeGrowing && !this.isGrowthFinished; + var forceToNodeSurroundingUpdate = this.growTreeIterations % 10 == 1 && this.isTreeGrowing || this.afterGrowthIterations % 10 == 1 && this.isGrowthFinished; + + this.totalDisplacement = 0; + this.graphManager.updateBounds(); + this.calcSpringForces(); + this.calcRepulsionForces(gridUpdateAllowed, forceToNodeSurroundingUpdate); + this.calcGravitationalForces(); + this.moveNodes(); + this.animate(); + + return false; // Layout is not ended yet return false +}; + +CoSELayout.prototype.getPositionsData = function () { + var allNodes = this.graphManager.getAllNodes(); + var pData = {}; + for (var i = 0; i < allNodes.length; i++) { + var rect = allNodes[i].rect; + var id = allNodes[i].id; + pData[id] = { + id: id, + x: rect.getCenterX(), + y: rect.getCenterY(), + w: rect.width, + h: rect.height + }; + } + + return pData; +}; + +CoSELayout.prototype.runSpringEmbedder = function () { + this.initialAnimationPeriod = 25; + this.animationPeriod = this.initialAnimationPeriod; + var layoutEnded = false; + + // If aminate option is 'during' signal that layout is supposed to start iterating + if (FDLayoutConstants.ANIMATE === 'during') { + this.emit('layoutstarted'); + } else { + // If aminate option is 'during' tick() function will be called on index.js + while (!layoutEnded) { + layoutEnded = this.tick(); + } + + this.graphManager.updateBounds(); + } +}; + +CoSELayout.prototype.calculateNodesToApplyGravitationTo = function () { + var nodeList = []; + var graph; + + var graphs = this.graphManager.getGraphs(); + var size = graphs.length; + var i; + for (i = 0; i < size; i++) { + graph = graphs[i]; + + graph.updateConnected(); + + if (!graph.isConnected) { + nodeList = nodeList.concat(graph.getNodes()); + } + } + + return nodeList; +}; + +CoSELayout.prototype.createBendpoints = function () { + var edges = []; + edges = edges.concat(this.graphManager.getAllEdges()); + var visited = new Set(); + var i; + for (i = 0; i < edges.length; i++) { + var edge = edges[i]; + + if (!visited.has(edge)) { + var source = edge.getSource(); + var target = edge.getTarget(); + + if (source == target) { + edge.getBendpoints().push(new PointD()); + edge.getBendpoints().push(new PointD()); + this.createDummyNodesForBendpoints(edge); + visited.add(edge); + } else { + var edgeList = []; + + edgeList = edgeList.concat(source.getEdgeListToNode(target)); + edgeList = edgeList.concat(target.getEdgeListToNode(source)); + + if (!visited.has(edgeList[0])) { + if (edgeList.length > 1) { + var k; + for (k = 0; k < edgeList.length; k++) { + var multiEdge = edgeList[k]; + multiEdge.getBendpoints().push(new PointD()); + this.createDummyNodesForBendpoints(multiEdge); + } + } + edgeList.forEach(function (edge) { + visited.add(edge); + }); + } + } + } + + if (visited.size == edges.length) { + break; + } + } +}; + +CoSELayout.prototype.positionNodesRadially = function (forest) { + // We tile the trees to a grid row by row; first tree starts at (0,0) + var currentStartingPoint = new Point(0, 0); + var numberOfColumns = Math.ceil(Math.sqrt(forest.length)); + var height = 0; + var currentY = 0; + var currentX = 0; + var point = new PointD(0, 0); + + for (var i = 0; i < forest.length; i++) { + if (i % numberOfColumns == 0) { + // Start of a new row, make the x coordinate 0, increment the + // y coordinate with the max height of the previous row + currentX = 0; + currentY = height; + + if (i != 0) { + currentY += CoSEConstants.DEFAULT_COMPONENT_SEPERATION; + } + + height = 0; + } + + var tree = forest[i]; + + // Find the center of the tree + var centerNode = Layout.findCenterOfTree(tree); + + // Set the staring point of the next tree + currentStartingPoint.x = currentX; + currentStartingPoint.y = currentY; + + // Do a radial layout starting with the center + point = CoSELayout.radialLayout(tree, centerNode, currentStartingPoint); + + if (point.y > height) { + height = Math.floor(point.y); + } + + currentX = Math.floor(point.x + CoSEConstants.DEFAULT_COMPONENT_SEPERATION); + } + + this.transform(new PointD(LayoutConstants.WORLD_CENTER_X - point.x / 2, LayoutConstants.WORLD_CENTER_Y - point.y / 2)); +}; + +CoSELayout.radialLayout = function (tree, centerNode, startingPoint) { + var radialSep = Math.max(this.maxDiagonalInTree(tree), CoSEConstants.DEFAULT_RADIAL_SEPARATION); + CoSELayout.branchRadialLayout(centerNode, null, 0, 359, 0, radialSep); + var bounds = LGraph.calculateBounds(tree); + + var transform = new Transform(); + transform.setDeviceOrgX(bounds.getMinX()); + transform.setDeviceOrgY(bounds.getMinY()); + transform.setWorldOrgX(startingPoint.x); + transform.setWorldOrgY(startingPoint.y); + + for (var i = 0; i < tree.length; i++) { + var node = tree[i]; + node.transform(transform); + } + + var bottomRight = new PointD(bounds.getMaxX(), bounds.getMaxY()); + + return transform.inverseTransformPoint(bottomRight); +}; + +CoSELayout.branchRadialLayout = function (node, parentOfNode, startAngle, endAngle, distance, radialSeparation) { + // First, position this node by finding its angle. + var halfInterval = (endAngle - startAngle + 1) / 2; + + if (halfInterval < 0) { + halfInterval += 180; + } + + var nodeAngle = (halfInterval + startAngle) % 360; + var teta = nodeAngle * IGeometry.TWO_PI / 360; + + // Make polar to java cordinate conversion. + var cos_teta = Math.cos(teta); + var x_ = distance * Math.cos(teta); + var y_ = distance * Math.sin(teta); + + node.setCenter(x_, y_); + + // Traverse all neighbors of this node and recursively call this + // function. + var neighborEdges = []; + neighborEdges = neighborEdges.concat(node.getEdges()); + var childCount = neighborEdges.length; + + if (parentOfNode != null) { + childCount--; + } + + var branchCount = 0; + + var incEdgesCount = neighborEdges.length; + var startIndex; + + var edges = node.getEdgesBetween(parentOfNode); + + // If there are multiple edges, prune them until there remains only one + // edge. + while (edges.length > 1) { + //neighborEdges.remove(edges.remove(0)); + var temp = edges[0]; + edges.splice(0, 1); + var index = neighborEdges.indexOf(temp); + if (index >= 0) { + neighborEdges.splice(index, 1); + } + incEdgesCount--; + childCount--; + } + + if (parentOfNode != null) { + //assert edges.length == 1; + startIndex = (neighborEdges.indexOf(edges[0]) + 1) % incEdgesCount; + } else { + startIndex = 0; + } + + var stepAngle = Math.abs(endAngle - startAngle) / childCount; + + for (var i = startIndex; branchCount != childCount; i = ++i % incEdgesCount) { + var currentNeighbor = neighborEdges[i].getOtherEnd(node); + + // Don't back traverse to root node in current tree. + if (currentNeighbor == parentOfNode) { + continue; + } + + var childStartAngle = (startAngle + branchCount * stepAngle) % 360; + var childEndAngle = (childStartAngle + stepAngle) % 360; + + CoSELayout.branchRadialLayout(currentNeighbor, node, childStartAngle, childEndAngle, distance + radialSeparation, radialSeparation); + + branchCount++; + } +}; + +CoSELayout.maxDiagonalInTree = function (tree) { + var maxDiagonal = Integer.MIN_VALUE; + + for (var i = 0; i < tree.length; i++) { + var node = tree[i]; + var diagonal = node.getDiagonal(); + + if (diagonal > maxDiagonal) { + maxDiagonal = diagonal; + } + } + + return maxDiagonal; +}; + +CoSELayout.prototype.calcRepulsionRange = function () { + // formula is 2 x (level + 1) x idealEdgeLength + return 2 * (this.level + 1) * this.idealEdgeLength; +}; + +// Tiling methods + +// Group zero degree members whose parents are not to be tiled, create dummy parents where needed and fill memberGroups by their dummp parent id's +CoSELayout.prototype.groupZeroDegreeMembers = function () { + var self = this; + // array of [parent_id x oneDegreeNode_id] + var tempMemberGroups = {}; // A temporary map of parent node and its zero degree members + this.memberGroups = {}; // A map of dummy parent node and its zero degree members whose parents are not to be tiled + this.idToDummyNode = {}; // A map of id to dummy node + + var zeroDegree = []; // List of zero degree nodes whose parents are not to be tiled + var allNodes = this.graphManager.getAllNodes(); + + // Fill zero degree list + for (var i = 0; i < allNodes.length; i++) { + var node = allNodes[i]; + var parent = node.getParent(); + // If a node has zero degree and its parent is not to be tiled if exists add that node to zeroDegres list + if (this.getNodeDegreeWithChildren(node) === 0 && (parent.id == undefined || !this.getToBeTiled(parent))) { + zeroDegree.push(node); + } + } + + // Create a map of parent node and its zero degree members + for (var i = 0; i < zeroDegree.length; i++) { + var node = zeroDegree[i]; // Zero degree node itself + var p_id = node.getParent().id; // Parent id + + if (typeof tempMemberGroups[p_id] === "undefined") tempMemberGroups[p_id] = []; + + tempMemberGroups[p_id] = tempMemberGroups[p_id].concat(node); // Push node to the list belongs to its parent in tempMemberGroups + } + + // If there are at least two nodes at a level, create a dummy compound for them + Object.keys(tempMemberGroups).forEach(function (p_id) { + if (tempMemberGroups[p_id].length > 1) { + var dummyCompoundId = "DummyCompound_" + p_id; // The id of dummy compound which will be created soon + self.memberGroups[dummyCompoundId] = tempMemberGroups[p_id]; // Add dummy compound to memberGroups + + var parent = tempMemberGroups[p_id][0].getParent(); // The parent of zero degree nodes will be the parent of new dummy compound + + // Create a dummy compound with calculated id + var dummyCompound = new CoSENode(self.graphManager); + dummyCompound.id = dummyCompoundId; + dummyCompound.paddingLeft = parent.paddingLeft || 0; + dummyCompound.paddingRight = parent.paddingRight || 0; + dummyCompound.paddingBottom = parent.paddingBottom || 0; + dummyCompound.paddingTop = parent.paddingTop || 0; + + self.idToDummyNode[dummyCompoundId] = dummyCompound; + + var dummyParentGraph = self.getGraphManager().add(self.newGraph(), dummyCompound); + var parentGraph = parent.getChild(); + + // Add dummy compound to parent the graph + parentGraph.add(dummyCompound); + + // For each zero degree node in this level remove it from its parent graph and add it to the graph of dummy parent + for (var i = 0; i < tempMemberGroups[p_id].length; i++) { + var node = tempMemberGroups[p_id][i]; + + parentGraph.remove(node); + dummyParentGraph.add(node); + } + } + }); +}; + +CoSELayout.prototype.clearCompounds = function () { + var childGraphMap = {}; + var idToNode = {}; + + // Get compound ordering by finding the inner one first + this.performDFSOnCompounds(); + + for (var i = 0; i < this.compoundOrder.length; i++) { + + idToNode[this.compoundOrder[i].id] = this.compoundOrder[i]; + childGraphMap[this.compoundOrder[i].id] = [].concat(this.compoundOrder[i].getChild().getNodes()); + + // Remove children of compounds + this.graphManager.remove(this.compoundOrder[i].getChild()); + this.compoundOrder[i].child = null; + } + + this.graphManager.resetAllNodes(); + + // Tile the removed children + this.tileCompoundMembers(childGraphMap, idToNode); +}; + +CoSELayout.prototype.clearZeroDegreeMembers = function () { + var self = this; + var tiledZeroDegreePack = this.tiledZeroDegreePack = []; + + Object.keys(this.memberGroups).forEach(function (id) { + var compoundNode = self.idToDummyNode[id]; // Get the dummy compound + + tiledZeroDegreePack[id] = self.tileNodes(self.memberGroups[id], compoundNode.paddingLeft + compoundNode.paddingRight); + + // Set the width and height of the dummy compound as calculated + compoundNode.rect.width = tiledZeroDegreePack[id].width; + compoundNode.rect.height = tiledZeroDegreePack[id].height; + }); +}; + +CoSELayout.prototype.repopulateCompounds = function () { + for (var i = this.compoundOrder.length - 1; i >= 0; i--) { + var lCompoundNode = this.compoundOrder[i]; + var id = lCompoundNode.id; + var horizontalMargin = lCompoundNode.paddingLeft; + var verticalMargin = lCompoundNode.paddingTop; + + this.adjustLocations(this.tiledMemberPack[id], lCompoundNode.rect.x, lCompoundNode.rect.y, horizontalMargin, verticalMargin); + } +}; + +CoSELayout.prototype.repopulateZeroDegreeMembers = function () { + var self = this; + var tiledPack = this.tiledZeroDegreePack; + + Object.keys(tiledPack).forEach(function (id) { + var compoundNode = self.idToDummyNode[id]; // Get the dummy compound by its id + var horizontalMargin = compoundNode.paddingLeft; + var verticalMargin = compoundNode.paddingTop; + + // Adjust the positions of nodes wrt its compound + self.adjustLocations(tiledPack[id], compoundNode.rect.x, compoundNode.rect.y, horizontalMargin, verticalMargin); + }); +}; + +CoSELayout.prototype.getToBeTiled = function (node) { + var id = node.id; + //firstly check the previous results + if (this.toBeTiled[id] != null) { + return this.toBeTiled[id]; + } + + //only compound nodes are to be tiled + var childGraph = node.getChild(); + if (childGraph == null) { + this.toBeTiled[id] = false; + return false; + } + + var children = childGraph.getNodes(); // Get the children nodes + + //a compound node is not to be tiled if all of its compound children are not to be tiled + for (var i = 0; i < children.length; i++) { + var theChild = children[i]; + + if (this.getNodeDegree(theChild) > 0) { + this.toBeTiled[id] = false; + return false; + } + + //pass the children not having the compound structure + if (theChild.getChild() == null) { + this.toBeTiled[theChild.id] = false; + continue; + } + + if (!this.getToBeTiled(theChild)) { + this.toBeTiled[id] = false; + return false; + } + } + this.toBeTiled[id] = true; + return true; +}; + +// Get degree of a node depending of its edges and independent of its children +CoSELayout.prototype.getNodeDegree = function (node) { + var id = node.id; + var edges = node.getEdges(); + var degree = 0; + + // For the edges connected + for (var i = 0; i < edges.length; i++) { + var edge = edges[i]; + if (edge.getSource().id !== edge.getTarget().id) { + degree = degree + 1; + } + } + return degree; +}; + +// Get degree of a node with its children +CoSELayout.prototype.getNodeDegreeWithChildren = function (node) { + var degree = this.getNodeDegree(node); + if (node.getChild() == null) { + return degree; + } + var children = node.getChild().getNodes(); + for (var i = 0; i < children.length; i++) { + var child = children[i]; + degree += this.getNodeDegreeWithChildren(child); + } + return degree; +}; + +CoSELayout.prototype.performDFSOnCompounds = function () { + this.compoundOrder = []; + this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes()); +}; + +CoSELayout.prototype.fillCompexOrderByDFS = function (children) { + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (child.getChild() != null) { + this.fillCompexOrderByDFS(child.getChild().getNodes()); + } + if (this.getToBeTiled(child)) { + this.compoundOrder.push(child); + } + } +}; + +/** +* This method places each zero degree member wrt given (x,y) coordinates (top left). +*/ +CoSELayout.prototype.adjustLocations = function (organization, x, y, compoundHorizontalMargin, compoundVerticalMargin) { + x += compoundHorizontalMargin; + y += compoundVerticalMargin; + + var left = x; + + for (var i = 0; i < organization.rows.length; i++) { + var row = organization.rows[i]; + x = left; + var maxHeight = 0; + + for (var j = 0; j < row.length; j++) { + var lnode = row[j]; + + lnode.rect.x = x; // + lnode.rect.width / 2; + lnode.rect.y = y; // + lnode.rect.height / 2; + + x += lnode.rect.width + organization.horizontalPadding; + + if (lnode.rect.height > maxHeight) maxHeight = lnode.rect.height; + } + + y += maxHeight + organization.verticalPadding; + } +}; + +CoSELayout.prototype.tileCompoundMembers = function (childGraphMap, idToNode) { + var self = this; + this.tiledMemberPack = []; + + Object.keys(childGraphMap).forEach(function (id) { + // Get the compound node + var compoundNode = idToNode[id]; + + self.tiledMemberPack[id] = self.tileNodes(childGraphMap[id], compoundNode.paddingLeft + compoundNode.paddingRight); + + compoundNode.rect.width = self.tiledMemberPack[id].width; + compoundNode.rect.height = self.tiledMemberPack[id].height; + }); +}; + +CoSELayout.prototype.tileNodes = function (nodes, minWidth) { + var verticalPadding = CoSEConstants.TILING_PADDING_VERTICAL; + var horizontalPadding = CoSEConstants.TILING_PADDING_HORIZONTAL; + var organization = { + rows: [], + rowWidth: [], + rowHeight: [], + width: 0, + height: minWidth, // assume minHeight equals to minWidth + verticalPadding: verticalPadding, + horizontalPadding: horizontalPadding + }; + + // Sort the nodes in ascending order of their areas + nodes.sort(function (n1, n2) { + if (n1.rect.width * n1.rect.height > n2.rect.width * n2.rect.height) return -1; + if (n1.rect.width * n1.rect.height < n2.rect.width * n2.rect.height) return 1; + return 0; + }); + + // Create the organization -> tile members + for (var i = 0; i < nodes.length; i++) { + var lNode = nodes[i]; + + if (organization.rows.length == 0) { + this.insertNodeToRow(organization, lNode, 0, minWidth); + } else if (this.canAddHorizontal(organization, lNode.rect.width, lNode.rect.height)) { + this.insertNodeToRow(organization, lNode, this.getShortestRowIndex(organization), minWidth); + } else { + this.insertNodeToRow(organization, lNode, organization.rows.length, minWidth); + } + + this.shiftToLastRow(organization); + } + + return organization; +}; + +CoSELayout.prototype.insertNodeToRow = function (organization, node, rowIndex, minWidth) { + var minCompoundSize = minWidth; + + // Add new row if needed + if (rowIndex == organization.rows.length) { + var secondDimension = []; + + organization.rows.push(secondDimension); + organization.rowWidth.push(minCompoundSize); + organization.rowHeight.push(0); + } + + // Update row width + var w = organization.rowWidth[rowIndex] + node.rect.width; + + if (organization.rows[rowIndex].length > 0) { + w += organization.horizontalPadding; + } + + organization.rowWidth[rowIndex] = w; + // Update compound width + if (organization.width < w) { + organization.width = w; + } + + // Update height + var h = node.rect.height; + if (rowIndex > 0) h += organization.verticalPadding; + + var extraHeight = 0; + if (h > organization.rowHeight[rowIndex]) { + extraHeight = organization.rowHeight[rowIndex]; + organization.rowHeight[rowIndex] = h; + extraHeight = organization.rowHeight[rowIndex] - extraHeight; + } + + organization.height += extraHeight; + + // Insert node + organization.rows[rowIndex].push(node); +}; + +//Scans the rows of an organization and returns the one with the min width +CoSELayout.prototype.getShortestRowIndex = function (organization) { + var r = -1; + var min = Number.MAX_VALUE; + + for (var i = 0; i < organization.rows.length; i++) { + if (organization.rowWidth[i] < min) { + r = i; + min = organization.rowWidth[i]; + } + } + return r; +}; + +//Scans the rows of an organization and returns the one with the max width +CoSELayout.prototype.getLongestRowIndex = function (organization) { + var r = -1; + var max = Number.MIN_VALUE; + + for (var i = 0; i < organization.rows.length; i++) { + + if (organization.rowWidth[i] > max) { + r = i; + max = organization.rowWidth[i]; + } + } + + return r; +}; + +/** +* This method checks whether adding extra width to the organization violates +* the aspect ratio(1) or not. +*/ +CoSELayout.prototype.canAddHorizontal = function (organization, extraWidth, extraHeight) { + + var sri = this.getShortestRowIndex(organization); + + if (sri < 0) { + return true; + } + + var min = organization.rowWidth[sri]; + + if (min + organization.horizontalPadding + extraWidth <= organization.width) return true; + + var hDiff = 0; + + // Adding to an existing row + if (organization.rowHeight[sri] < extraHeight) { + if (sri > 0) hDiff = extraHeight + organization.verticalPadding - organization.rowHeight[sri]; + } + + var add_to_row_ratio; + if (organization.width - min >= extraWidth + organization.horizontalPadding) { + add_to_row_ratio = (organization.height + hDiff) / (min + extraWidth + organization.horizontalPadding); + } else { + add_to_row_ratio = (organization.height + hDiff) / organization.width; + } + + // Adding a new row for this node + hDiff = extraHeight + organization.verticalPadding; + var add_new_row_ratio; + if (organization.width < extraWidth) { + add_new_row_ratio = (organization.height + hDiff) / extraWidth; + } else { + add_new_row_ratio = (organization.height + hDiff) / organization.width; + } + + if (add_new_row_ratio < 1) add_new_row_ratio = 1 / add_new_row_ratio; + + if (add_to_row_ratio < 1) add_to_row_ratio = 1 / add_to_row_ratio; + + return add_to_row_ratio < add_new_row_ratio; +}; + +//If moving the last node from the longest row and adding it to the last +//row makes the bounding box smaller, do it. +CoSELayout.prototype.shiftToLastRow = function (organization) { + var longest = this.getLongestRowIndex(organization); + var last = organization.rowWidth.length - 1; + var row = organization.rows[longest]; + var node = row[row.length - 1]; + + var diff = node.width + organization.horizontalPadding; + + // Check if there is enough space on the last row + if (organization.width - organization.rowWidth[last] > diff && longest != last) { + // Remove the last element of the longest row + row.splice(-1, 1); + + // Push it to the last row + organization.rows[last].push(node); + + organization.rowWidth[longest] = organization.rowWidth[longest] - diff; + organization.rowWidth[last] = organization.rowWidth[last] + diff; + organization.width = organization.rowWidth[instance.getLongestRowIndex(organization)]; + + // Update heights of the organization + var maxHeight = Number.MIN_VALUE; + for (var i = 0; i < row.length; i++) { + if (row[i].height > maxHeight) maxHeight = row[i].height; + } + if (longest > 0) maxHeight += organization.verticalPadding; + + var prevTotal = organization.rowHeight[longest] + organization.rowHeight[last]; + + organization.rowHeight[longest] = maxHeight; + if (organization.rowHeight[last] < node.height + organization.verticalPadding) organization.rowHeight[last] = node.height + organization.verticalPadding; + + var finalTotal = organization.rowHeight[longest] + organization.rowHeight[last]; + organization.height += finalTotal - prevTotal; + + this.shiftToLastRow(organization); + } +}; + +CoSELayout.prototype.tilingPreLayout = function () { + if (CoSEConstants.TILE) { + // Find zero degree nodes and create a compound for each level + this.groupZeroDegreeMembers(); + // Tile and clear children of each compound + this.clearCompounds(); + // Separately tile and clear zero degree nodes for each level + this.clearZeroDegreeMembers(); + } +}; + +CoSELayout.prototype.tilingPostLayout = function () { + if (CoSEConstants.TILE) { + this.repopulateZeroDegreeMembers(); + this.repopulateCompounds(); + } +}; + +// ----------------------------------------------------------------------------- +// Section: Tree Reduction methods +// ----------------------------------------------------------------------------- +// Reduce trees +CoSELayout.prototype.reduceTrees = function () { + var prunedNodesAll = []; + var containsLeaf = true; + var node; + + while (containsLeaf) { + var allNodes = this.graphManager.getAllNodes(); + var prunedNodesInStepTemp = []; + containsLeaf = false; + + for (var i = 0; i < allNodes.length; i++) { + node = allNodes[i]; + if (node.getEdges().length == 1 && !node.getEdges()[0].isInterGraph && node.getChild() == null) { + prunedNodesInStepTemp.push([node, node.getEdges()[0], node.getOwner()]); + containsLeaf = true; + } + } + if (containsLeaf == true) { + var prunedNodesInStep = []; + for (var j = 0; j < prunedNodesInStepTemp.length; j++) { + if (prunedNodesInStepTemp[j][0].getEdges().length == 1) { + prunedNodesInStep.push(prunedNodesInStepTemp[j]); + prunedNodesInStepTemp[j][0].getOwner().remove(prunedNodesInStepTemp[j][0]); + } + } + prunedNodesAll.push(prunedNodesInStep); + this.graphManager.resetAllNodes(); + this.graphManager.resetAllEdges(); + } + } + this.prunedNodesAll = prunedNodesAll; +}; + +// Grow tree one step +CoSELayout.prototype.growTree = function (prunedNodesAll) { + var lengthOfPrunedNodesInStep = prunedNodesAll.length; + var prunedNodesInStep = prunedNodesAll[lengthOfPrunedNodesInStep - 1]; + + var nodeData; + for (var i = 0; i < prunedNodesInStep.length; i++) { + nodeData = prunedNodesInStep[i]; + + this.findPlaceforPrunedNode(nodeData); + + nodeData[2].add(nodeData[0]); + nodeData[2].add(nodeData[1], nodeData[1].source, nodeData[1].target); + } + + prunedNodesAll.splice(prunedNodesAll.length - 1, 1); + this.graphManager.resetAllNodes(); + this.graphManager.resetAllEdges(); +}; + +// Find an appropriate position to replace pruned node, this method can be improved +CoSELayout.prototype.findPlaceforPrunedNode = function (nodeData) { + + var gridForPrunedNode; + var nodeToConnect; + var prunedNode = nodeData[0]; + if (prunedNode == nodeData[1].source) { + nodeToConnect = nodeData[1].target; + } else { + nodeToConnect = nodeData[1].source; + } + var startGridX = nodeToConnect.startX; + var finishGridX = nodeToConnect.finishX; + var startGridY = nodeToConnect.startY; + var finishGridY = nodeToConnect.finishY; + + var upNodeCount = 0; + var downNodeCount = 0; + var rightNodeCount = 0; + var leftNodeCount = 0; + var controlRegions = [upNodeCount, rightNodeCount, downNodeCount, leftNodeCount]; + + if (startGridY > 0) { + for (var i = startGridX; i <= finishGridX; i++) { + controlRegions[0] += this.grid[i][startGridY - 1].length + this.grid[i][startGridY].length - 1; + } + } + if (finishGridX < this.grid.length - 1) { + for (var i = startGridY; i <= finishGridY; i++) { + controlRegions[1] += this.grid[finishGridX + 1][i].length + this.grid[finishGridX][i].length - 1; + } + } + if (finishGridY < this.grid[0].length - 1) { + for (var i = startGridX; i <= finishGridX; i++) { + controlRegions[2] += this.grid[i][finishGridY + 1].length + this.grid[i][finishGridY].length - 1; + } + } + if (startGridX > 0) { + for (var i = startGridY; i <= finishGridY; i++) { + controlRegions[3] += this.grid[startGridX - 1][i].length + this.grid[startGridX][i].length - 1; + } + } + var min = Integer.MAX_VALUE; + var minCount; + var minIndex; + for (var j = 0; j < controlRegions.length; j++) { + if (controlRegions[j] < min) { + min = controlRegions[j]; + minCount = 1; + minIndex = j; + } else if (controlRegions[j] == min) { + minCount++; + } + } + + if (minCount == 3 && min == 0) { + if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[2] == 0) { + gridForPrunedNode = 1; + } else if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[3] == 0) { + gridForPrunedNode = 0; + } else if (controlRegions[0] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) { + gridForPrunedNode = 3; + } else if (controlRegions[1] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) { + gridForPrunedNode = 2; + } + } else if (minCount == 2 && min == 0) { + var random = Math.floor(Math.random() * 2); + if (controlRegions[0] == 0 && controlRegions[1] == 0) { + ; + if (random == 0) { + gridForPrunedNode = 0; + } else { + gridForPrunedNode = 1; + } + } else if (controlRegions[0] == 0 && controlRegions[2] == 0) { + if (random == 0) { + gridForPrunedNode = 0; + } else { + gridForPrunedNode = 2; + } + } else if (controlRegions[0] == 0 && controlRegions[3] == 0) { + if (random == 0) { + gridForPrunedNode = 0; + } else { + gridForPrunedNode = 3; + } + } else if (controlRegions[1] == 0 && controlRegions[2] == 0) { + if (random == 0) { + gridForPrunedNode = 1; + } else { + gridForPrunedNode = 2; + } + } else if (controlRegions[1] == 0 && controlRegions[3] == 0) { + if (random == 0) { + gridForPrunedNode = 1; + } else { + gridForPrunedNode = 3; + } + } else { + if (random == 0) { + gridForPrunedNode = 2; + } else { + gridForPrunedNode = 3; + } + } + } else if (minCount == 4 && min == 0) { + var random = Math.floor(Math.random() * 4); + gridForPrunedNode = random; + } else { + gridForPrunedNode = minIndex; + } + + if (gridForPrunedNode == 0) { + prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() - nodeToConnect.getHeight() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getHeight() / 2); + } else if (gridForPrunedNode == 1) { + prunedNode.setCenter(nodeToConnect.getCenterX() + nodeToConnect.getWidth() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getWidth() / 2, nodeToConnect.getCenterY()); + } else if (gridForPrunedNode == 2) { + prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() + nodeToConnect.getHeight() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getHeight() / 2); + } else { + prunedNode.setCenter(nodeToConnect.getCenterX() - nodeToConnect.getWidth() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getWidth() / 2, nodeToConnect.getCenterY()); + } +}; + +module.exports = CoSELayout; + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __nested_webpack_require_45620__) { + +"use strict"; + + +var coseBase = {}; + +coseBase.layoutBase = __nested_webpack_require_45620__(0); +coseBase.CoSEConstants = __nested_webpack_require_45620__(1); +coseBase.CoSEEdge = __nested_webpack_require_45620__(2); +coseBase.CoSEGraph = __nested_webpack_require_45620__(3); +coseBase.CoSEGraphManager = __nested_webpack_require_45620__(4); +coseBase.CoSELayout = __nested_webpack_require_45620__(6); +coseBase.CoSENode = __nested_webpack_require_45620__(5); + +module.exports = coseBase; + +/***/ }) +/******/ ]); +}); + +/***/ }), + +/***/ 43457: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +(function webpackUniversalModuleDefinition(root, factory) { + if(true) + module.exports = factory(__webpack_require__(87799)); + else {} +})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __nested_webpack_require_659__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_659__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __nested_webpack_require_659__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __nested_webpack_require_659__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __nested_webpack_require_659__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __nested_webpack_require_659__.d = function(exports, name, getter) { +/******/ if(!__nested_webpack_require_659__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __nested_webpack_require_659__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __nested_webpack_require_659__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __nested_webpack_require_659__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __nested_webpack_require_659__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __nested_webpack_require_659__(__nested_webpack_require_659__.s = 1); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_0__; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __nested_webpack_require_3201__) { + +"use strict"; + + +var LayoutConstants = __nested_webpack_require_3201__(0).layoutBase.LayoutConstants; +var FDLayoutConstants = __nested_webpack_require_3201__(0).layoutBase.FDLayoutConstants; +var CoSEConstants = __nested_webpack_require_3201__(0).CoSEConstants; +var CoSELayout = __nested_webpack_require_3201__(0).CoSELayout; +var CoSENode = __nested_webpack_require_3201__(0).CoSENode; +var PointD = __nested_webpack_require_3201__(0).layoutBase.PointD; +var DimensionD = __nested_webpack_require_3201__(0).layoutBase.DimensionD; + +var defaults = { + // Called on `layoutready` + ready: function ready() {}, + // Called on `layoutstop` + stop: function stop() {}, + // 'draft', 'default' or 'proof" + // - 'draft' fast cooling rate + // - 'default' moderate cooling rate + // - "proof" slow cooling rate + quality: 'default', + // include labels in node dimensions + nodeDimensionsIncludeLabels: false, + // number of ticks per frame; higher is faster but more jerky + refresh: 30, + // Whether to fit the network view after when done + fit: true, + // Padding on fit + padding: 10, + // Whether to enable incremental mode + randomize: true, + // Node repulsion (non overlapping) multiplier + nodeRepulsion: 4500, + // Ideal edge (non nested) length + idealEdgeLength: 50, + // Divisor to compute edge forces + edgeElasticity: 0.45, + // Nesting factor (multiplier) to compute ideal edge length for nested edges + nestingFactor: 0.1, + // Gravity force (constant) + gravity: 0.25, + // Maximum number of iterations to perform + numIter: 2500, + // For enabling tiling + tile: true, + // Type of layout animation. The option set is {'during', 'end', false} + animate: 'end', + // Duration for animate:end + animationDuration: 500, + // Represents the amount of the vertical space to put between the zero degree members during the tiling operation(can also be a function) + tilingPaddingVertical: 10, + // Represents the amount of the horizontal space to put between the zero degree members during the tiling operation(can also be a function) + tilingPaddingHorizontal: 10, + // Gravity range (constant) for compounds + gravityRangeCompound: 1.5, + // Gravity force (constant) for compounds + gravityCompound: 1.0, + // Gravity range (constant) + gravityRange: 3.8, + // Initial cooling factor for incremental layout + initialEnergyOnIncremental: 0.5 +}; + +function extend(defaults, options) { + var obj = {}; + + for (var i in defaults) { + obj[i] = defaults[i]; + } + + for (var i in options) { + obj[i] = options[i]; + } + + return obj; +}; + +function _CoSELayout(_options) { + this.options = extend(defaults, _options); + getUserOptions(this.options); +} + +var getUserOptions = function getUserOptions(options) { + if (options.nodeRepulsion != null) CoSEConstants.DEFAULT_REPULSION_STRENGTH = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = options.nodeRepulsion; + if (options.idealEdgeLength != null) CoSEConstants.DEFAULT_EDGE_LENGTH = FDLayoutConstants.DEFAULT_EDGE_LENGTH = options.idealEdgeLength; + if (options.edgeElasticity != null) CoSEConstants.DEFAULT_SPRING_STRENGTH = FDLayoutConstants.DEFAULT_SPRING_STRENGTH = options.edgeElasticity; + if (options.nestingFactor != null) CoSEConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = options.nestingFactor; + if (options.gravity != null) CoSEConstants.DEFAULT_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = options.gravity; + if (options.numIter != null) CoSEConstants.MAX_ITERATIONS = FDLayoutConstants.MAX_ITERATIONS = options.numIter; + if (options.gravityRange != null) CoSEConstants.DEFAULT_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = options.gravityRange; + if (options.gravityCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = options.gravityCompound; + if (options.gravityRangeCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = options.gravityRangeCompound; + if (options.initialEnergyOnIncremental != null) CoSEConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = options.initialEnergyOnIncremental; + + if (options.quality == 'draft') LayoutConstants.QUALITY = 0;else if (options.quality == 'proof') LayoutConstants.QUALITY = 2;else LayoutConstants.QUALITY = 1; + + CoSEConstants.NODE_DIMENSIONS_INCLUDE_LABELS = FDLayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = options.nodeDimensionsIncludeLabels; + CoSEConstants.DEFAULT_INCREMENTAL = FDLayoutConstants.DEFAULT_INCREMENTAL = LayoutConstants.DEFAULT_INCREMENTAL = !options.randomize; + CoSEConstants.ANIMATE = FDLayoutConstants.ANIMATE = LayoutConstants.ANIMATE = options.animate; + CoSEConstants.TILE = options.tile; + CoSEConstants.TILING_PADDING_VERTICAL = typeof options.tilingPaddingVertical === 'function' ? options.tilingPaddingVertical.call() : options.tilingPaddingVertical; + CoSEConstants.TILING_PADDING_HORIZONTAL = typeof options.tilingPaddingHorizontal === 'function' ? options.tilingPaddingHorizontal.call() : options.tilingPaddingHorizontal; +}; + +_CoSELayout.prototype.run = function () { + var ready; + var frameId; + var options = this.options; + var idToLNode = this.idToLNode = {}; + var layout = this.layout = new CoSELayout(); + var self = this; + + self.stopped = false; + + this.cy = this.options.cy; + + this.cy.trigger({ type: 'layoutstart', layout: this }); + + var gm = layout.newGraphManager(); + this.gm = gm; + + var nodes = this.options.eles.nodes(); + var edges = this.options.eles.edges(); + + this.root = gm.addRoot(); + this.processChildrenList(this.root, this.getTopMostNodes(nodes), layout); + + for (var i = 0; i < edges.length; i++) { + var edge = edges[i]; + var sourceNode = this.idToLNode[edge.data("source")]; + var targetNode = this.idToLNode[edge.data("target")]; + if (sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0) { + var e1 = gm.add(layout.newEdge(), sourceNode, targetNode); + e1.id = edge.id(); + } + } + + var getPositions = function getPositions(ele, i) { + if (typeof ele === "number") { + ele = i; + } + var theId = ele.data('id'); + var lNode = self.idToLNode[theId]; + + return { + x: lNode.getRect().getCenterX(), + y: lNode.getRect().getCenterY() + }; + }; + + /* + * Reposition nodes in iterations animatedly + */ + var iterateAnimated = function iterateAnimated() { + // Thigs to perform after nodes are repositioned on screen + var afterReposition = function afterReposition() { + if (options.fit) { + options.cy.fit(options.eles, options.padding); + } + + if (!ready) { + ready = true; + self.cy.one('layoutready', options.ready); + self.cy.trigger({ type: 'layoutready', layout: self }); + } + }; + + var ticksPerFrame = self.options.refresh; + var isDone; + + for (var i = 0; i < ticksPerFrame && !isDone; i++) { + isDone = self.stopped || self.layout.tick(); + } + + // If layout is done + if (isDone) { + // If the layout is not a sublayout and it is successful perform post layout. + if (layout.checkLayoutSuccess() && !layout.isSubLayout) { + layout.doPostLayout(); + } + + // If layout has a tilingPostLayout function property call it. + if (layout.tilingPostLayout) { + layout.tilingPostLayout(); + } + + layout.isLayoutFinished = true; + + self.options.eles.nodes().positions(getPositions); + + afterReposition(); + + // trigger layoutstop when the layout stops (e.g. finishes) + self.cy.one('layoutstop', self.options.stop); + self.cy.trigger({ type: 'layoutstop', layout: self }); + + if (frameId) { + cancelAnimationFrame(frameId); + } + + ready = false; + return; + } + + var animationData = self.layout.getPositionsData(); // Get positions of layout nodes note that all nodes may not be layout nodes because of tiling + + // Position nodes, for the nodes whose id does not included in data (because they are removed from their parents and included in dummy compounds) + // use position of their ancestors or dummy ancestors + options.eles.nodes().positions(function (ele, i) { + if (typeof ele === "number") { + ele = i; + } + // If ele is a compound node, then its position will be defined by its children + if (!ele.isParent()) { + var theId = ele.id(); + var pNode = animationData[theId]; + var temp = ele; + // If pNode is undefined search until finding position data of its first ancestor (It may be dummy as well) + while (pNode == null) { + pNode = animationData[temp.data('parent')] || animationData['DummyCompound_' + temp.data('parent')]; + animationData[theId] = pNode; + temp = temp.parent()[0]; + if (temp == undefined) { + break; + } + } + if (pNode != null) { + return { + x: pNode.x, + y: pNode.y + }; + } else { + return { + x: ele.position('x'), + y: ele.position('y') + }; + } + } + }); + + afterReposition(); + + frameId = requestAnimationFrame(iterateAnimated); + }; + + /* + * Listen 'layoutstarted' event and start animated iteration if animate option is 'during' + */ + layout.addListener('layoutstarted', function () { + if (self.options.animate === 'during') { + frameId = requestAnimationFrame(iterateAnimated); + } + }); + + layout.runLayout(); // Run cose layout + + /* + * If animate option is not 'during' ('end' or false) perform these here (If it is 'during' similar things are already performed) + */ + if (this.options.animate !== "during") { + self.options.eles.nodes().not(":parent").layoutPositions(self, self.options, getPositions); // Use layout positions to reposition the nodes it considers the options parameter + ready = false; + } + + return this; // chaining +}; + +//Get the top most ones of a list of nodes +_CoSELayout.prototype.getTopMostNodes = function (nodes) { + var nodesMap = {}; + for (var i = 0; i < nodes.length; i++) { + nodesMap[nodes[i].id()] = true; + } + var roots = nodes.filter(function (ele, i) { + if (typeof ele === "number") { + ele = i; + } + var parent = ele.parent()[0]; + while (parent != null) { + if (nodesMap[parent.id()]) { + return false; + } + parent = parent.parent()[0]; + } + return true; + }); + + return roots; +}; + +_CoSELayout.prototype.processChildrenList = function (parent, children, layout) { + var size = children.length; + for (var i = 0; i < size; i++) { + var theChild = children[i]; + var children_of_children = theChild.children(); + var theNode; + + var dimensions = theChild.layoutDimensions({ + nodeDimensionsIncludeLabels: this.options.nodeDimensionsIncludeLabels + }); + + if (theChild.outerWidth() != null && theChild.outerHeight() != null) { + theNode = parent.add(new CoSENode(layout.graphManager, new PointD(theChild.position('x') - dimensions.w / 2, theChild.position('y') - dimensions.h / 2), new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h)))); + } else { + theNode = parent.add(new CoSENode(this.graphManager)); + } + // Attach id to the layout node + theNode.id = theChild.data("id"); + // Attach the paddings of cy node to layout node + theNode.paddingLeft = parseInt(theChild.css('padding')); + theNode.paddingTop = parseInt(theChild.css('padding')); + theNode.paddingRight = parseInt(theChild.css('padding')); + theNode.paddingBottom = parseInt(theChild.css('padding')); + + //Attach the label properties to compound if labels will be included in node dimensions + if (this.options.nodeDimensionsIncludeLabels) { + if (theChild.isParent()) { + var labelWidth = theChild.boundingBox({ includeLabels: true, includeNodes: false }).w; + var labelHeight = theChild.boundingBox({ includeLabels: true, includeNodes: false }).h; + var labelPos = theChild.css("text-halign"); + theNode.labelWidth = labelWidth; + theNode.labelHeight = labelHeight; + theNode.labelPos = labelPos; + } + } + + // Map the layout node + this.idToLNode[theChild.data("id")] = theNode; + + if (isNaN(theNode.rect.x)) { + theNode.rect.x = 0; + } + + if (isNaN(theNode.rect.y)) { + theNode.rect.y = 0; + } + + if (children_of_children != null && children_of_children.length > 0) { + var theNewGraph; + theNewGraph = layout.getGraphManager().add(layout.newGraph(), theNode); + this.processChildrenList(theNewGraph, children_of_children, layout); + } + } +}; + +/** + * @brief : called on continuous layouts to stop them before they finish + */ +_CoSELayout.prototype.stop = function () { + this.stopped = true; + + return this; // chaining +}; + +var register = function register(cytoscape) { + // var Layout = getLayout( cytoscape ); + + cytoscape('layout', 'cose-bilkent', _CoSELayout); +}; + +// auto reg for globals +if (typeof cytoscape !== 'undefined') { + register(cytoscape); +} + +module.exports = register; + +/***/ }) +/******/ ]); +}); + +/***/ }), + +/***/ 44726: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +"use strict"; +/** + * Copyright (c) 2016-2023, The Cytoscape Consortium. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the “Software”), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + + +var debounce = __webpack_require__(38221); +var Heap = __webpack_require__(65731); +var get = __webpack_require__(58156); +var set = __webpack_require__(63560); +var toPath = __webpack_require__(42072); + +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + +var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce); +var Heap__default = /*#__PURE__*/_interopDefaultLegacy(Heap); +var get__default = /*#__PURE__*/_interopDefaultLegacy(get); +var set__default = /*#__PURE__*/_interopDefaultLegacy(set); +var toPath__default = /*#__PURE__*/_interopDefaultLegacy(toPath); + +function _typeof(obj) { + "@babel/helpers - typeof"; + + return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { + return typeof obj; + } : function (obj) { + return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }, _typeof(obj); +} +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +} +function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } +} +function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + Object.defineProperty(Constructor, "prototype", { + writable: false + }); + return Constructor; +} +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + return obj; +} +function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); +} +function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; +} +function _iterableToArrayLimit(arr, i) { + var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; + if (_i == null) return; + var _arr = []; + var _n = true; + var _d = false; + var _s, _e; + try { + for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + return _arr; +} +function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); +} +function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + return arr2; +} +function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +} + +var _window = typeof window === 'undefined' ? null : window; // eslint-disable-line no-undef + +var navigator = _window ? _window.navigator : null; +_window ? _window.document : null; +var typeofstr = _typeof(''); +var typeofobj = _typeof({}); +var typeoffn = _typeof(function () {}); +var typeofhtmlele = typeof HTMLElement === "undefined" ? "undefined" : _typeof(HTMLElement); +var instanceStr = function instanceStr(obj) { + return obj && obj.instanceString && fn$6(obj.instanceString) ? obj.instanceString() : null; +}; + +var string = function string(obj) { + return obj != null && _typeof(obj) == typeofstr; +}; +var fn$6 = function fn(obj) { + return obj != null && _typeof(obj) === typeoffn; +}; +var array = function array(obj) { + return !elementOrCollection(obj) && (Array.isArray ? Array.isArray(obj) : obj != null && obj instanceof Array); +}; +var plainObject = function plainObject(obj) { + return obj != null && _typeof(obj) === typeofobj && !array(obj) && obj.constructor === Object; +}; +var object = function object(obj) { + return obj != null && _typeof(obj) === typeofobj; +}; +var number$1 = function number(obj) { + return obj != null && _typeof(obj) === _typeof(1) && !isNaN(obj); +}; +var integer = function integer(obj) { + return number$1(obj) && Math.floor(obj) === obj; +}; +var htmlElement = function htmlElement(obj) { + if ('undefined' === typeofhtmlele) { + return undefined; + } else { + return null != obj && obj instanceof HTMLElement; + } +}; +var elementOrCollection = function elementOrCollection(obj) { + return element(obj) || collection(obj); +}; +var element = function element(obj) { + return instanceStr(obj) === 'collection' && obj._private.single; +}; +var collection = function collection(obj) { + return instanceStr(obj) === 'collection' && !obj._private.single; +}; +var core = function core(obj) { + return instanceStr(obj) === 'core'; +}; +var stylesheet = function stylesheet(obj) { + return instanceStr(obj) === 'stylesheet'; +}; +var event = function event(obj) { + return instanceStr(obj) === 'event'; +}; +var emptyString = function emptyString(obj) { + if (obj === undefined || obj === null) { + // null is empty + return true; + } else if (obj === '' || obj.match(/^\s+$/)) { + return true; // empty string is empty + } + + return false; // otherwise, we don't know what we've got +}; +var domElement = function domElement(obj) { + if (typeof HTMLElement === 'undefined') { + return false; // we're not in a browser so it doesn't matter + } else { + return obj instanceof HTMLElement; + } +}; +var boundingBox = function boundingBox(obj) { + return plainObject(obj) && number$1(obj.x1) && number$1(obj.x2) && number$1(obj.y1) && number$1(obj.y2); +}; +var promise = function promise(obj) { + return object(obj) && fn$6(obj.then); +}; +var ms = function ms() { + return navigator && navigator.userAgent.match(/msie|trident|edge/i); +}; // probably a better way to detect this... + +var memoize = function memoize(fn, keyFn) { + if (!keyFn) { + keyFn = function keyFn() { + if (arguments.length === 1) { + return arguments[0]; + } else if (arguments.length === 0) { + return 'undefined'; + } + var args = []; + for (var i = 0; i < arguments.length; i++) { + args.push(arguments[i]); + } + return args.join('$'); + }; + } + var memoizedFn = function memoizedFn() { + var self = this; + var args = arguments; + var ret; + var k = keyFn.apply(self, args); + var cache = memoizedFn.cache; + if (!(ret = cache[k])) { + ret = cache[k] = fn.apply(self, args); + } + return ret; + }; + memoizedFn.cache = {}; + return memoizedFn; +}; + +var camel2dash = memoize(function (str) { + return str.replace(/([A-Z])/g, function (v) { + return '-' + v.toLowerCase(); + }); +}); +var dash2camel = memoize(function (str) { + return str.replace(/(-\w)/g, function (v) { + return v[1].toUpperCase(); + }); +}); +var prependCamel = memoize(function (prefix, str) { + return prefix + str[0].toUpperCase() + str.substring(1); +}, function (prefix, str) { + return prefix + '$' + str; +}); +var capitalize = function capitalize(str) { + if (emptyString(str)) { + return str; + } + return str.charAt(0).toUpperCase() + str.substring(1); +}; + +var number = '(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))'; +var rgba = 'rgb[a]?\\((' + number + '[%]?)\\s*,\\s*(' + number + '[%]?)\\s*,\\s*(' + number + '[%]?)(?:\\s*,\\s*(' + number + '))?\\)'; +var rgbaNoBackRefs = 'rgb[a]?\\((?:' + number + '[%]?)\\s*,\\s*(?:' + number + '[%]?)\\s*,\\s*(?:' + number + '[%]?)(?:\\s*,\\s*(?:' + number + '))?\\)'; +var hsla = 'hsl[a]?\\((' + number + ')\\s*,\\s*(' + number + '[%])\\s*,\\s*(' + number + '[%])(?:\\s*,\\s*(' + number + '))?\\)'; +var hslaNoBackRefs = 'hsl[a]?\\((?:' + number + ')\\s*,\\s*(?:' + number + '[%])\\s*,\\s*(?:' + number + '[%])(?:\\s*,\\s*(?:' + number + '))?\\)'; +var hex3 = '\\#[0-9a-fA-F]{3}'; +var hex6 = '\\#[0-9a-fA-F]{6}'; + +var ascending = function ascending(a, b) { + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else { + return 0; + } +}; +var descending = function descending(a, b) { + return -1 * ascending(a, b); +}; + +var extend = Object.assign != null ? Object.assign.bind(Object) : function (tgt) { + var args = arguments; + for (var i = 1; i < args.length; i++) { + var obj = args[i]; + if (obj == null) { + continue; + } + var keys = Object.keys(obj); + for (var j = 0; j < keys.length; j++) { + var k = keys[j]; + tgt[k] = obj[k]; + } + } + return tgt; +}; + +// get [r, g, b] from #abc or #aabbcc +var hex2tuple = function hex2tuple(hex) { + if (!(hex.length === 4 || hex.length === 7) || hex[0] !== '#') { + return; + } + var shortHex = hex.length === 4; + var r, g, b; + var base = 16; + if (shortHex) { + r = parseInt(hex[1] + hex[1], base); + g = parseInt(hex[2] + hex[2], base); + b = parseInt(hex[3] + hex[3], base); + } else { + r = parseInt(hex[1] + hex[2], base); + g = parseInt(hex[3] + hex[4], base); + b = parseInt(hex[5] + hex[6], base); + } + return [r, g, b]; +}; + +// get [r, g, b, a] from hsl(0, 0, 0) or hsla(0, 0, 0, 0) +var hsl2tuple = function hsl2tuple(hsl) { + var ret; + var h, s, l, a, r, g, b; + function hue2rgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + } + var m = new RegExp('^' + hsla + '$').exec(hsl); + if (m) { + // get hue + h = parseInt(m[1]); + if (h < 0) { + h = (360 - -1 * h % 360) % 360; + } else if (h > 360) { + h = h % 360; + } + h /= 360; // normalise on [0, 1] + + s = parseFloat(m[2]); + if (s < 0 || s > 100) { + return; + } // saturation is [0, 100] + s = s / 100; // normalise on [0, 1] + + l = parseFloat(m[3]); + if (l < 0 || l > 100) { + return; + } // lightness is [0, 100] + l = l / 100; // normalise on [0, 1] + + a = m[4]; + if (a !== undefined) { + a = parseFloat(a); + if (a < 0 || a > 1) { + return; + } // alpha is [0, 1] + } + + // now, convert to rgb + // code from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + if (s === 0) { + r = g = b = Math.round(l * 255); // achromatic + } else { + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = Math.round(255 * hue2rgb(p, q, h + 1 / 3)); + g = Math.round(255 * hue2rgb(p, q, h)); + b = Math.round(255 * hue2rgb(p, q, h - 1 / 3)); + } + ret = [r, g, b, a]; + } + return ret; +}; + +// get [r, g, b, a] from rgb(0, 0, 0) or rgba(0, 0, 0, 0) +var rgb2tuple = function rgb2tuple(rgb) { + var ret; + var m = new RegExp('^' + rgba + '$').exec(rgb); + if (m) { + ret = []; + var isPct = []; + for (var i = 1; i <= 3; i++) { + var channel = m[i]; + if (channel[channel.length - 1] === '%') { + isPct[i] = true; + } + channel = parseFloat(channel); + if (isPct[i]) { + channel = channel / 100 * 255; // normalise to [0, 255] + } + + if (channel < 0 || channel > 255) { + return; + } // invalid channel value + + ret.push(Math.floor(channel)); + } + var atLeastOneIsPct = isPct[1] || isPct[2] || isPct[3]; + var allArePct = isPct[1] && isPct[2] && isPct[3]; + if (atLeastOneIsPct && !allArePct) { + return; + } // must all be percent values if one is + + var alpha = m[4]; + if (alpha !== undefined) { + alpha = parseFloat(alpha); + if (alpha < 0 || alpha > 1) { + return; + } // invalid alpha value + + ret.push(alpha); + } + } + return ret; +}; +var colorname2tuple = function colorname2tuple(color) { + return colors[color.toLowerCase()]; +}; +var color2tuple = function color2tuple(color) { + return (array(color) ? color : null) || colorname2tuple(color) || hex2tuple(color) || rgb2tuple(color) || hsl2tuple(color); +}; +var colors = { + // special colour names + transparent: [0, 0, 0, 0], + // NB alpha === 0 + + // regular colours + aliceblue: [240, 248, 255], + antiquewhite: [250, 235, 215], + aqua: [0, 255, 255], + aquamarine: [127, 255, 212], + azure: [240, 255, 255], + beige: [245, 245, 220], + bisque: [255, 228, 196], + black: [0, 0, 0], + blanchedalmond: [255, 235, 205], + blue: [0, 0, 255], + blueviolet: [138, 43, 226], + brown: [165, 42, 42], + burlywood: [222, 184, 135], + cadetblue: [95, 158, 160], + chartreuse: [127, 255, 0], + chocolate: [210, 105, 30], + coral: [255, 127, 80], + cornflowerblue: [100, 149, 237], + cornsilk: [255, 248, 220], + crimson: [220, 20, 60], + cyan: [0, 255, 255], + darkblue: [0, 0, 139], + darkcyan: [0, 139, 139], + darkgoldenrod: [184, 134, 11], + darkgray: [169, 169, 169], + darkgreen: [0, 100, 0], + darkgrey: [169, 169, 169], + darkkhaki: [189, 183, 107], + darkmagenta: [139, 0, 139], + darkolivegreen: [85, 107, 47], + darkorange: [255, 140, 0], + darkorchid: [153, 50, 204], + darkred: [139, 0, 0], + darksalmon: [233, 150, 122], + darkseagreen: [143, 188, 143], + darkslateblue: [72, 61, 139], + darkslategray: [47, 79, 79], + darkslategrey: [47, 79, 79], + darkturquoise: [0, 206, 209], + darkviolet: [148, 0, 211], + deeppink: [255, 20, 147], + deepskyblue: [0, 191, 255], + dimgray: [105, 105, 105], + dimgrey: [105, 105, 105], + dodgerblue: [30, 144, 255], + firebrick: [178, 34, 34], + floralwhite: [255, 250, 240], + forestgreen: [34, 139, 34], + fuchsia: [255, 0, 255], + gainsboro: [220, 220, 220], + ghostwhite: [248, 248, 255], + gold: [255, 215, 0], + goldenrod: [218, 165, 32], + gray: [128, 128, 128], + grey: [128, 128, 128], + green: [0, 128, 0], + greenyellow: [173, 255, 47], + honeydew: [240, 255, 240], + hotpink: [255, 105, 180], + indianred: [205, 92, 92], + indigo: [75, 0, 130], + ivory: [255, 255, 240], + khaki: [240, 230, 140], + lavender: [230, 230, 250], + lavenderblush: [255, 240, 245], + lawngreen: [124, 252, 0], + lemonchiffon: [255, 250, 205], + lightblue: [173, 216, 230], + lightcoral: [240, 128, 128], + lightcyan: [224, 255, 255], + lightgoldenrodyellow: [250, 250, 210], + lightgray: [211, 211, 211], + lightgreen: [144, 238, 144], + lightgrey: [211, 211, 211], + lightpink: [255, 182, 193], + lightsalmon: [255, 160, 122], + lightseagreen: [32, 178, 170], + lightskyblue: [135, 206, 250], + lightslategray: [119, 136, 153], + lightslategrey: [119, 136, 153], + lightsteelblue: [176, 196, 222], + lightyellow: [255, 255, 224], + lime: [0, 255, 0], + limegreen: [50, 205, 50], + linen: [250, 240, 230], + magenta: [255, 0, 255], + maroon: [128, 0, 0], + mediumaquamarine: [102, 205, 170], + mediumblue: [0, 0, 205], + mediumorchid: [186, 85, 211], + mediumpurple: [147, 112, 219], + mediumseagreen: [60, 179, 113], + mediumslateblue: [123, 104, 238], + mediumspringgreen: [0, 250, 154], + mediumturquoise: [72, 209, 204], + mediumvioletred: [199, 21, 133], + midnightblue: [25, 25, 112], + mintcream: [245, 255, 250], + mistyrose: [255, 228, 225], + moccasin: [255, 228, 181], + navajowhite: [255, 222, 173], + navy: [0, 0, 128], + oldlace: [253, 245, 230], + olive: [128, 128, 0], + olivedrab: [107, 142, 35], + orange: [255, 165, 0], + orangered: [255, 69, 0], + orchid: [218, 112, 214], + palegoldenrod: [238, 232, 170], + palegreen: [152, 251, 152], + paleturquoise: [175, 238, 238], + palevioletred: [219, 112, 147], + papayawhip: [255, 239, 213], + peachpuff: [255, 218, 185], + peru: [205, 133, 63], + pink: [255, 192, 203], + plum: [221, 160, 221], + powderblue: [176, 224, 230], + purple: [128, 0, 128], + red: [255, 0, 0], + rosybrown: [188, 143, 143], + royalblue: [65, 105, 225], + saddlebrown: [139, 69, 19], + salmon: [250, 128, 114], + sandybrown: [244, 164, 96], + seagreen: [46, 139, 87], + seashell: [255, 245, 238], + sienna: [160, 82, 45], + silver: [192, 192, 192], + skyblue: [135, 206, 235], + slateblue: [106, 90, 205], + slategray: [112, 128, 144], + slategrey: [112, 128, 144], + snow: [255, 250, 250], + springgreen: [0, 255, 127], + steelblue: [70, 130, 180], + tan: [210, 180, 140], + teal: [0, 128, 128], + thistle: [216, 191, 216], + tomato: [255, 99, 71], + turquoise: [64, 224, 208], + violet: [238, 130, 238], + wheat: [245, 222, 179], + white: [255, 255, 255], + whitesmoke: [245, 245, 245], + yellow: [255, 255, 0], + yellowgreen: [154, 205, 50] +}; + +// sets the value in a map (map may not be built) +var setMap = function setMap(options) { + var obj = options.map; + var keys = options.keys; + var l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (plainObject(key)) { + throw Error('Tried to set map with object key'); + } + if (i < keys.length - 1) { + // extend the map if necessary + if (obj[key] == null) { + obj[key] = {}; + } + obj = obj[key]; + } else { + // set the value + obj[key] = options.value; + } + } +}; + +// gets the value in a map even if it's not built in places +var getMap = function getMap(options) { + var obj = options.map; + var keys = options.keys; + var l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (plainObject(key)) { + throw Error('Tried to get map with object key'); + } + obj = obj[key]; + if (obj == null) { + return obj; + } + } + return obj; +}; + +var performance = _window ? _window.performance : null; +var pnow = performance && performance.now ? function () { + return performance.now(); +} : function () { + return Date.now(); +}; +var raf = function () { + if (_window) { + if (_window.requestAnimationFrame) { + return function (fn) { + _window.requestAnimationFrame(fn); + }; + } else if (_window.mozRequestAnimationFrame) { + return function (fn) { + _window.mozRequestAnimationFrame(fn); + }; + } else if (_window.webkitRequestAnimationFrame) { + return function (fn) { + _window.webkitRequestAnimationFrame(fn); + }; + } else if (_window.msRequestAnimationFrame) { + return function (fn) { + _window.msRequestAnimationFrame(fn); + }; + } + } + return function (fn) { + if (fn) { + setTimeout(function () { + fn(pnow()); + }, 1000 / 60); + } + }; +}(); +var requestAnimationFrame = function requestAnimationFrame(fn) { + return raf(fn); +}; +var performanceNow = pnow; + +var DEFAULT_HASH_SEED = 9261; +var K = 65599; // 37 also works pretty well +var DEFAULT_HASH_SEED_ALT = 5381; +var hashIterableInts = function hashIterableInts(iterator) { + var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED; + // sdbm/string-hash + var hash = seed; + var entry; + for (;;) { + entry = iterator.next(); + if (entry.done) { + break; + } + hash = hash * K + entry.value | 0; + } + return hash; +}; +var hashInt = function hashInt(num) { + var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED; + // sdbm/string-hash + return seed * K + num | 0; +}; +var hashIntAlt = function hashIntAlt(num) { + var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED_ALT; + // djb2/string-hash + return (seed << 5) + seed + num | 0; +}; +var combineHashes = function combineHashes(hash1, hash2) { + return hash1 * 0x200000 + hash2; +}; +var combineHashesArray = function combineHashesArray(hashes) { + return hashes[0] * 0x200000 + hashes[1]; +}; +var hashArrays = function hashArrays(hashes1, hashes2) { + return [hashInt(hashes1[0], hashes2[0]), hashIntAlt(hashes1[1], hashes2[1])]; +}; +var hashIntsArray = function hashIntsArray(ints, seed) { + var entry = { + value: 0, + done: false + }; + var i = 0; + var length = ints.length; + var iterator = { + next: function next() { + if (i < length) { + entry.value = ints[i++]; + } else { + entry.done = true; + } + return entry; + } + }; + return hashIterableInts(iterator, seed); +}; +var hashString = function hashString(str, seed) { + var entry = { + value: 0, + done: false + }; + var i = 0; + var length = str.length; + var iterator = { + next: function next() { + if (i < length) { + entry.value = str.charCodeAt(i++); + } else { + entry.done = true; + } + return entry; + } + }; + return hashIterableInts(iterator, seed); +}; +var hashStrings = function hashStrings() { + return hashStringsArray(arguments); +}; +var hashStringsArray = function hashStringsArray(strs) { + var hash; + for (var i = 0; i < strs.length; i++) { + var str = strs[i]; + if (i === 0) { + hash = hashString(str); + } else { + hash = hashString(str, hash); + } + } + return hash; +}; + +/*global console */ +var warningsEnabled = true; +var warnSupported = console.warn != null; // eslint-disable-line no-console +var traceSupported = console.trace != null; // eslint-disable-line no-console + +var MAX_INT$1 = Number.MAX_SAFE_INTEGER || 9007199254740991; +var trueify = function trueify() { + return true; +}; +var falsify = function falsify() { + return false; +}; +var zeroify = function zeroify() { + return 0; +}; +var noop$1 = function noop() {}; +var error = function error(msg) { + throw new Error(msg); +}; +var warnings = function warnings(enabled) { + if (enabled !== undefined) { + warningsEnabled = !!enabled; + } else { + return warningsEnabled; + } +}; +var warn = function warn(msg) { + /* eslint-disable no-console */ + if (!warnings()) { + return; + } + if (warnSupported) { + console.warn(msg); + } else { + console.log(msg); + if (traceSupported) { + console.trace(); + } + } +}; /* eslint-enable */ + +var clone = function clone(obj) { + return extend({}, obj); +}; + +// gets a shallow copy of the argument +var copy = function copy(obj) { + if (obj == null) { + return obj; + } + if (array(obj)) { + return obj.slice(); + } else if (plainObject(obj)) { + return clone(obj); + } else { + return obj; + } +}; +var copyArray = function copyArray(arr) { + return arr.slice(); +}; +var uuid = function uuid(a, b /* placeholders */) { + for ( + // loop :) + b = a = ''; + // b - result , a - numeric letiable + a++ < 36; + // + b += a * 51 & 52 // if "a" is not 9 or 14 or 19 or 24 + ? + // return a random number or 4 + (a ^ 15 // if "a" is not 15 + ? + // generate a random number from 0 to 15 + 8 ^ Math.random() * (a ^ 20 ? 16 : 4) // unless "a" is 20, in which case a random number from 8 to 11 + : 4 // otherwise 4 + ).toString(16) : '-' // in other cases (if "a" is 9,14,19,24) insert "-" + ) { + } + return b; +}; +var _staticEmptyObject = {}; +var staticEmptyObject = function staticEmptyObject() { + return _staticEmptyObject; +}; +var defaults$g = function defaults(_defaults) { + var keys = Object.keys(_defaults); + return function (opts) { + var filledOpts = {}; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var optVal = opts == null ? undefined : opts[key]; + filledOpts[key] = optVal === undefined ? _defaults[key] : optVal; + } + return filledOpts; + }; +}; +var removeFromArray = function removeFromArray(arr, ele, oneCopy) { + for (var i = arr.length - 1; i >= 0; i--) { + if (arr[i] === ele) { + arr.splice(i, 1); + if (oneCopy) { + break; + } + } + } +}; +var clearArray = function clearArray(arr) { + arr.splice(0, arr.length); +}; +var push = function push(arr, otherArr) { + for (var i = 0; i < otherArr.length; i++) { + var el = otherArr[i]; + arr.push(el); + } +}; +var getPrefixedProperty = function getPrefixedProperty(obj, propName, prefix) { + if (prefix) { + propName = prependCamel(prefix, propName); // e.g. (labelWidth, source) => sourceLabelWidth + } + + return obj[propName]; +}; +var setPrefixedProperty = function setPrefixedProperty(obj, propName, prefix, value) { + if (prefix) { + propName = prependCamel(prefix, propName); // e.g. (labelWidth, source) => sourceLabelWidth + } + + obj[propName] = value; +}; + +/* global Map */ +var ObjectMap = /*#__PURE__*/function () { + function ObjectMap() { + _classCallCheck(this, ObjectMap); + this._obj = {}; + } + _createClass(ObjectMap, [{ + key: "set", + value: function set(key, val) { + this._obj[key] = val; + return this; + } + }, { + key: "delete", + value: function _delete(key) { + this._obj[key] = undefined; + return this; + } + }, { + key: "clear", + value: function clear() { + this._obj = {}; + } + }, { + key: "has", + value: function has(key) { + return this._obj[key] !== undefined; + } + }, { + key: "get", + value: function get(key) { + return this._obj[key]; + } + }]); + return ObjectMap; +}(); +var Map$1 = typeof Map !== 'undefined' ? Map : ObjectMap; + +/* global Set */ + +var undef = "undefined" ; +var ObjectSet = /*#__PURE__*/function () { + function ObjectSet(arrayOrObjectSet) { + _classCallCheck(this, ObjectSet); + this._obj = Object.create(null); + this.size = 0; + if (arrayOrObjectSet != null) { + var arr; + if (arrayOrObjectSet.instanceString != null && arrayOrObjectSet.instanceString() === this.instanceString()) { + arr = arrayOrObjectSet.toArray(); + } else { + arr = arrayOrObjectSet; + } + for (var i = 0; i < arr.length; i++) { + this.add(arr[i]); + } + } + } + _createClass(ObjectSet, [{ + key: "instanceString", + value: function instanceString() { + return 'set'; + } + }, { + key: "add", + value: function add(val) { + var o = this._obj; + if (o[val] !== 1) { + o[val] = 1; + this.size++; + } + } + }, { + key: "delete", + value: function _delete(val) { + var o = this._obj; + if (o[val] === 1) { + o[val] = 0; + this.size--; + } + } + }, { + key: "clear", + value: function clear() { + this._obj = Object.create(null); + } + }, { + key: "has", + value: function has(val) { + return this._obj[val] === 1; + } + }, { + key: "toArray", + value: function toArray() { + var _this = this; + return Object.keys(this._obj).filter(function (key) { + return _this.has(key); + }); + } + }, { + key: "forEach", + value: function forEach(callback, thisArg) { + return this.toArray().forEach(callback, thisArg); + } + }]); + return ObjectSet; +}(); +var Set$1 = (typeof Set === "undefined" ? "undefined" : _typeof(Set)) !== undef ? Set : ObjectSet; + +// represents a node or an edge +var Element = function Element(cy, params) { + var restore = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + if (cy === undefined || params === undefined || !core(cy)) { + error('An element must have a core reference and parameters set'); + return; + } + var group = params.group; + + // try to automatically infer the group if unspecified + if (group == null) { + if (params.data && params.data.source != null && params.data.target != null) { + group = 'edges'; + } else { + group = 'nodes'; + } + } + + // validate group + if (group !== 'nodes' && group !== 'edges') { + error('An element must be of type `nodes` or `edges`; you specified `' + group + '`'); + return; + } + + // make the element array-like, just like a collection + this.length = 1; + this[0] = this; + + // NOTE: when something is added here, add also to ele.json() + var _p = this._private = { + cy: cy, + single: true, + // indicates this is an element + data: params.data || {}, + // data object + position: params.position || { + x: 0, + y: 0 + }, + // (x, y) position pair + autoWidth: undefined, + // width and height of nodes calculated by the renderer when set to special 'auto' value + autoHeight: undefined, + autoPadding: undefined, + compoundBoundsClean: false, + // whether the compound dimensions need to be recalculated the next time dimensions are read + listeners: [], + // array of bound listeners + group: group, + // string; 'nodes' or 'edges' + style: {}, + // properties as set by the style + rstyle: {}, + // properties for style sent from the renderer to the core + styleCxts: [], + // applied style contexts from the styler + styleKeys: {}, + // per-group keys of style property values + removed: true, + // whether it's inside the vis; true if removed (set true here since we call restore) + selected: params.selected ? true : false, + // whether it's selected + selectable: params.selectable === undefined ? true : params.selectable ? true : false, + // whether it's selectable + locked: params.locked ? true : false, + // whether the element is locked (cannot be moved) + grabbed: false, + // whether the element is grabbed by the mouse; renderer sets this privately + grabbable: params.grabbable === undefined ? true : params.grabbable ? true : false, + // whether the element can be grabbed + pannable: params.pannable === undefined ? group === 'edges' ? true : false : params.pannable ? true : false, + // whether the element has passthrough panning enabled + active: false, + // whether the element is active from user interaction + classes: new Set$1(), + // map ( className => true ) + animation: { + // object for currently-running animations + current: [], + queue: [] + }, + rscratch: {}, + // object in which the renderer can store information + scratch: params.scratch || {}, + // scratch objects + edges: [], + // array of connected edges + children: [], + // array of children + parent: params.parent && params.parent.isNode() ? params.parent : null, + // parent ref + traversalCache: {}, + // cache of output of traversal functions + backgrounding: false, + // whether background images are loading + bbCache: null, + // cache of the current bounding box + bbCacheShift: { + x: 0, + y: 0 + }, + // shift applied to cached bb to be applied on next get + bodyBounds: null, + // bounds cache of element body, w/o overlay + overlayBounds: null, + // bounds cache of element body, including overlay + labelBounds: { + // bounds cache of labels + all: null, + source: null, + target: null, + main: null + }, + arrowBounds: { + // bounds cache of edge arrows + source: null, + target: null, + 'mid-source': null, + 'mid-target': null + } + }; + if (_p.position.x == null) { + _p.position.x = 0; + } + if (_p.position.y == null) { + _p.position.y = 0; + } + + // renderedPosition overrides if specified + if (params.renderedPosition) { + var rpos = params.renderedPosition; + var pan = cy.pan(); + var zoom = cy.zoom(); + _p.position = { + x: (rpos.x - pan.x) / zoom, + y: (rpos.y - pan.y) / zoom + }; + } + var classes = []; + if (array(params.classes)) { + classes = params.classes; + } else if (string(params.classes)) { + classes = params.classes.split(/\s+/); + } + for (var i = 0, l = classes.length; i < l; i++) { + var cls = classes[i]; + if (!cls || cls === '') { + continue; + } + _p.classes.add(cls); + } + this.createEmitter(); + var bypass = params.style || params.css; + if (bypass) { + warn('Setting a `style` bypass at element creation should be done only when absolutely necessary. Try to use the stylesheet instead.'); + this.style(bypass); + } + if (restore === undefined || restore) { + this.restore(); + } +}; + +var defineSearch = function defineSearch(params) { + params = { + bfs: params.bfs || !params.dfs, + dfs: params.dfs || !params.bfs + }; + + // from pseudocode on wikipedia + return function searchFn(roots, fn, directed) { + var options; + if (plainObject(roots) && !elementOrCollection(roots)) { + options = roots; + roots = options.roots || options.root; + fn = options.visit; + directed = options.directed; + } + directed = arguments.length === 2 && !fn$6(fn) ? fn : directed; + fn = fn$6(fn) ? fn : function () {}; + var cy = this._private.cy; + var v = roots = string(roots) ? this.filter(roots) : roots; + var Q = []; + var connectedNodes = []; + var connectedBy = {}; + var id2depth = {}; + var V = {}; + var j = 0; + var found; + var _this$byGroup = this.byGroup(), + nodes = _this$byGroup.nodes, + edges = _this$byGroup.edges; + + // enqueue v + for (var i = 0; i < v.length; i++) { + var vi = v[i]; + var viId = vi.id(); + if (vi.isNode()) { + Q.unshift(vi); + if (params.bfs) { + V[viId] = true; + connectedNodes.push(vi); + } + id2depth[viId] = 0; + } + } + var _loop = function _loop() { + var v = params.bfs ? Q.shift() : Q.pop(); + var vId = v.id(); + if (params.dfs) { + if (V[vId]) { + return "continue"; + } + V[vId] = true; + connectedNodes.push(v); + } + var depth = id2depth[vId]; + var prevEdge = connectedBy[vId]; + var src = prevEdge != null ? prevEdge.source() : null; + var tgt = prevEdge != null ? prevEdge.target() : null; + var prevNode = prevEdge == null ? undefined : v.same(src) ? tgt[0] : src[0]; + var ret = void 0; + ret = fn(v, prevEdge, prevNode, j++, depth); + if (ret === true) { + found = v; + return "break"; + } + if (ret === false) { + return "break"; + } + var vwEdges = v.connectedEdges().filter(function (e) { + return (!directed || e.source().same(v)) && edges.has(e); + }); + for (var _i2 = 0; _i2 < vwEdges.length; _i2++) { + var e = vwEdges[_i2]; + var w = e.connectedNodes().filter(function (n) { + return !n.same(v) && nodes.has(n); + }); + var wId = w.id(); + if (w.length !== 0 && !V[wId]) { + w = w[0]; + Q.push(w); + if (params.bfs) { + V[wId] = true; + connectedNodes.push(w); + } + connectedBy[wId] = e; + id2depth[wId] = id2depth[vId] + 1; + } + } + }; + while (Q.length !== 0) { + var _ret = _loop(); + if (_ret === "continue") continue; + if (_ret === "break") break; + } + var connectedEles = cy.collection(); + for (var _i = 0; _i < connectedNodes.length; _i++) { + var node = connectedNodes[_i]; + var edge = connectedBy[node.id()]; + if (edge != null) { + connectedEles.push(edge); + } + connectedEles.push(node); + } + return { + path: cy.collection(connectedEles), + found: cy.collection(found) + }; + }; +}; + +// search, spanning trees, etc +var elesfn$v = { + breadthFirstSearch: defineSearch({ + bfs: true + }), + depthFirstSearch: defineSearch({ + dfs: true + }) +}; + +// nice, short mathematical alias +elesfn$v.bfs = elesfn$v.breadthFirstSearch; +elesfn$v.dfs = elesfn$v.depthFirstSearch; + +var dijkstraDefaults = defaults$g({ + root: null, + weight: function weight(edge) { + return 1; + }, + directed: false +}); +var elesfn$u = { + dijkstra: function dijkstra(options) { + if (!plainObject(options)) { + var args = arguments; + options = { + root: args[0], + weight: args[1], + directed: args[2] + }; + } + var _dijkstraDefaults = dijkstraDefaults(options), + root = _dijkstraDefaults.root, + weight = _dijkstraDefaults.weight, + directed = _dijkstraDefaults.directed; + var eles = this; + var weightFn = weight; + var source = string(root) ? this.filter(root)[0] : root[0]; + var dist = {}; + var prev = {}; + var knownDist = {}; + var _this$byGroup = this.byGroup(), + nodes = _this$byGroup.nodes, + edges = _this$byGroup.edges; + edges.unmergeBy(function (ele) { + return ele.isLoop(); + }); + var getDist = function getDist(node) { + return dist[node.id()]; + }; + var setDist = function setDist(node, d) { + dist[node.id()] = d; + Q.updateItem(node); + }; + var Q = new Heap__default["default"](function (a, b) { + return getDist(a) - getDist(b); + }); + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + dist[node.id()] = node.same(source) ? 0 : Infinity; + Q.push(node); + } + var distBetween = function distBetween(u, v) { + var uvs = (directed ? u.edgesTo(v) : u.edgesWith(v)).intersect(edges); + var smallestDistance = Infinity; + var smallestEdge; + for (var _i = 0; _i < uvs.length; _i++) { + var edge = uvs[_i]; + var _weight = weightFn(edge); + if (_weight < smallestDistance || !smallestEdge) { + smallestDistance = _weight; + smallestEdge = edge; + } + } + return { + edge: smallestEdge, + dist: smallestDistance + }; + }; + while (Q.size() > 0) { + var u = Q.pop(); + var smalletsDist = getDist(u); + var uid = u.id(); + knownDist[uid] = smalletsDist; + if (smalletsDist === Infinity) { + continue; + } + var neighbors = u.neighborhood().intersect(nodes); + for (var _i2 = 0; _i2 < neighbors.length; _i2++) { + var v = neighbors[_i2]; + var vid = v.id(); + var vDist = distBetween(u, v); + var alt = smalletsDist + vDist.dist; + if (alt < getDist(v)) { + setDist(v, alt); + prev[vid] = { + node: u, + edge: vDist.edge + }; + } + } // for + } // while + + return { + distanceTo: function distanceTo(node) { + var target = string(node) ? nodes.filter(node)[0] : node[0]; + return knownDist[target.id()]; + }, + pathTo: function pathTo(node) { + var target = string(node) ? nodes.filter(node)[0] : node[0]; + var S = []; + var u = target; + var uid = u.id(); + if (target.length > 0) { + S.unshift(target); + while (prev[uid]) { + var p = prev[uid]; + S.unshift(p.edge); + S.unshift(p.node); + u = p.node; + uid = u.id(); + } + } + return eles.spawn(S); + } + }; + } +}; + +var elesfn$t = { + // kruskal's algorithm (finds min spanning tree, assuming undirected graph) + // implemented from pseudocode from wikipedia + kruskal: function kruskal(weightFn) { + weightFn = weightFn || function (edge) { + return 1; + }; + var _this$byGroup = this.byGroup(), + nodes = _this$byGroup.nodes, + edges = _this$byGroup.edges; + var numNodes = nodes.length; + var forest = new Array(numNodes); + var A = nodes; // assumes byGroup() creates new collections that can be safely mutated + + var findSetIndex = function findSetIndex(ele) { + for (var i = 0; i < forest.length; i++) { + var eles = forest[i]; + if (eles.has(ele)) { + return i; + } + } + }; + + // start with one forest per node + for (var i = 0; i < numNodes; i++) { + forest[i] = this.spawn(nodes[i]); + } + var S = edges.sort(function (a, b) { + return weightFn(a) - weightFn(b); + }); + for (var _i = 0; _i < S.length; _i++) { + var edge = S[_i]; + var u = edge.source()[0]; + var v = edge.target()[0]; + var setUIndex = findSetIndex(u); + var setVIndex = findSetIndex(v); + var setU = forest[setUIndex]; + var setV = forest[setVIndex]; + if (setUIndex !== setVIndex) { + A.merge(edge); + + // combine forests for u and v + setU.merge(setV); + forest.splice(setVIndex, 1); + } + } + return A; + } +}; + +var aStarDefaults = defaults$g({ + root: null, + goal: null, + weight: function weight(edge) { + return 1; + }, + heuristic: function heuristic(edge) { + return 0; + }, + directed: false +}); +var elesfn$s = { + // Implemented from pseudocode from wikipedia + aStar: function aStar(options) { + var cy = this.cy(); + var _aStarDefaults = aStarDefaults(options), + root = _aStarDefaults.root, + goal = _aStarDefaults.goal, + heuristic = _aStarDefaults.heuristic, + directed = _aStarDefaults.directed, + weight = _aStarDefaults.weight; + root = cy.collection(root)[0]; + goal = cy.collection(goal)[0]; + var sid = root.id(); + var tid = goal.id(); + var gScore = {}; + var fScore = {}; + var closedSetIds = {}; + var openSet = new Heap__default["default"](function (a, b) { + return fScore[a.id()] - fScore[b.id()]; + }); + var openSetIds = new Set$1(); + var cameFrom = {}; + var cameFromEdge = {}; + var addToOpenSet = function addToOpenSet(ele, id) { + openSet.push(ele); + openSetIds.add(id); + }; + var cMin, cMinId; + var popFromOpenSet = function popFromOpenSet() { + cMin = openSet.pop(); + cMinId = cMin.id(); + openSetIds["delete"](cMinId); + }; + var isInOpenSet = function isInOpenSet(id) { + return openSetIds.has(id); + }; + addToOpenSet(root, sid); + gScore[sid] = 0; + fScore[sid] = heuristic(root); + + // Counter + var steps = 0; + + // Main loop + while (openSet.size() > 0) { + popFromOpenSet(); + steps++; + + // If we've found our goal, then we are done + if (cMinId === tid) { + var path = []; + var pathNode = goal; + var pathNodeId = tid; + var pathEdge = cameFromEdge[pathNodeId]; + for (;;) { + path.unshift(pathNode); + if (pathEdge != null) { + path.unshift(pathEdge); + } + pathNode = cameFrom[pathNodeId]; + if (pathNode == null) { + break; + } + pathNodeId = pathNode.id(); + pathEdge = cameFromEdge[pathNodeId]; + } + return { + found: true, + distance: gScore[cMinId], + path: this.spawn(path), + steps: steps + }; + } + + // Add cMin to processed nodes + closedSetIds[cMinId] = true; + + // Update scores for neighbors of cMin + // Take into account if graph is directed or not + var vwEdges = cMin._private.edges; + for (var i = 0; i < vwEdges.length; i++) { + var e = vwEdges[i]; + + // edge must be in set of calling eles + if (!this.hasElementWithId(e.id())) { + continue; + } + + // cMin must be the source of edge if directed + if (directed && e.data('source') !== cMinId) { + continue; + } + var wSrc = e.source(); + var wTgt = e.target(); + var w = wSrc.id() !== cMinId ? wSrc : wTgt; + var wid = w.id(); + + // node must be in set of calling eles + if (!this.hasElementWithId(wid)) { + continue; + } + + // if node is in closedSet, ignore it + if (closedSetIds[wid]) { + continue; + } + + // New tentative score for node w + var tempScore = gScore[cMinId] + weight(e); + + // Update gScore for node w if: + // w not present in openSet + // OR + // tentative gScore is less than previous value + + // w not in openSet + if (!isInOpenSet(wid)) { + gScore[wid] = tempScore; + fScore[wid] = tempScore + heuristic(w); + addToOpenSet(w, wid); + cameFrom[wid] = cMin; + cameFromEdge[wid] = e; + continue; + } + + // w already in openSet, but with greater gScore + if (tempScore < gScore[wid]) { + gScore[wid] = tempScore; + fScore[wid] = tempScore + heuristic(w); + cameFrom[wid] = cMin; + cameFromEdge[wid] = e; + } + } // End of neighbors update + } // End of main loop + + // If we've reached here, then we've not reached our goal + return { + found: false, + distance: undefined, + path: undefined, + steps: steps + }; + } +}; // elesfn + +var floydWarshallDefaults = defaults$g({ + weight: function weight(edge) { + return 1; + }, + directed: false +}); +var elesfn$r = { + // Implemented from pseudocode from wikipedia + floydWarshall: function floydWarshall(options) { + var cy = this.cy(); + var _floydWarshallDefault = floydWarshallDefaults(options), + weight = _floydWarshallDefault.weight, + directed = _floydWarshallDefault.directed; + var weightFn = weight; + var _this$byGroup = this.byGroup(), + nodes = _this$byGroup.nodes, + edges = _this$byGroup.edges; + var N = nodes.length; + var Nsq = N * N; + var indexOf = function indexOf(node) { + return nodes.indexOf(node); + }; + var atIndex = function atIndex(i) { + return nodes[i]; + }; + + // Initialize distance matrix + var dist = new Array(Nsq); + for (var n = 0; n < Nsq; n++) { + var j = n % N; + var i = (n - j) / N; + if (i === j) { + dist[n] = 0; + } else { + dist[n] = Infinity; + } + } + + // Initialize matrix used for path reconstruction + // Initialize distance matrix + var next = new Array(Nsq); + var edgeNext = new Array(Nsq); + + // Process edges + for (var _i = 0; _i < edges.length; _i++) { + var edge = edges[_i]; + var src = edge.source()[0]; + var tgt = edge.target()[0]; + if (src === tgt) { + continue; + } // exclude loops + + var s = indexOf(src); + var t = indexOf(tgt); + var st = s * N + t; // source to target index + var _weight = weightFn(edge); + + // Check if already process another edge between same 2 nodes + if (dist[st] > _weight) { + dist[st] = _weight; + next[st] = t; + edgeNext[st] = edge; + } + + // If undirected graph, process 'reversed' edge + if (!directed) { + var ts = t * N + s; // target to source index + + if (!directed && dist[ts] > _weight) { + dist[ts] = _weight; + next[ts] = s; + edgeNext[ts] = edge; + } + } + } + + // Main loop + for (var k = 0; k < N; k++) { + for (var _i2 = 0; _i2 < N; _i2++) { + var ik = _i2 * N + k; + for (var _j = 0; _j < N; _j++) { + var ij = _i2 * N + _j; + var kj = k * N + _j; + if (dist[ik] + dist[kj] < dist[ij]) { + dist[ij] = dist[ik] + dist[kj]; + next[ij] = next[ik]; + } + } + } + } + var getArgEle = function getArgEle(ele) { + return (string(ele) ? cy.filter(ele) : ele)[0]; + }; + var indexOfArgEle = function indexOfArgEle(ele) { + return indexOf(getArgEle(ele)); + }; + var res = { + distance: function distance(from, to) { + var i = indexOfArgEle(from); + var j = indexOfArgEle(to); + return dist[i * N + j]; + }, + path: function path(from, to) { + var i = indexOfArgEle(from); + var j = indexOfArgEle(to); + var fromNode = atIndex(i); + if (i === j) { + return fromNode.collection(); + } + if (next[i * N + j] == null) { + return cy.collection(); + } + var path = cy.collection(); + var prev = i; + var edge; + path.merge(fromNode); + while (i !== j) { + prev = i; + i = next[i * N + j]; + edge = edgeNext[prev * N + i]; + path.merge(edge); + path.merge(atIndex(i)); + } + return path; + } + }; + return res; + } // floydWarshall +}; // elesfn + +var bellmanFordDefaults = defaults$g({ + weight: function weight(edge) { + return 1; + }, + directed: false, + root: null +}); +var elesfn$q = { + // Implemented from pseudocode from wikipedia + bellmanFord: function bellmanFord(options) { + var _this = this; + var _bellmanFordDefaults = bellmanFordDefaults(options), + weight = _bellmanFordDefaults.weight, + directed = _bellmanFordDefaults.directed, + root = _bellmanFordDefaults.root; + var weightFn = weight; + var eles = this; + var cy = this.cy(); + var _this$byGroup = this.byGroup(), + edges = _this$byGroup.edges, + nodes = _this$byGroup.nodes; + var numNodes = nodes.length; + var infoMap = new Map$1(); + var hasNegativeWeightCycle = false; + var negativeWeightCycles = []; + root = cy.collection(root)[0]; // in case selector passed + + edges.unmergeBy(function (edge) { + return edge.isLoop(); + }); + var numEdges = edges.length; + var getInfo = function getInfo(node) { + var obj = infoMap.get(node.id()); + if (!obj) { + obj = {}; + infoMap.set(node.id(), obj); + } + return obj; + }; + var getNodeFromTo = function getNodeFromTo(to) { + return (string(to) ? cy.$(to) : to)[0]; + }; + var distanceTo = function distanceTo(to) { + return getInfo(getNodeFromTo(to)).dist; + }; + var pathTo = function pathTo(to) { + var thisStart = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : root; + var end = getNodeFromTo(to); + var path = []; + var node = end; + for (;;) { + if (node == null) { + return _this.spawn(); + } + var _getInfo = getInfo(node), + edge = _getInfo.edge, + pred = _getInfo.pred; + path.unshift(node[0]); + if (node.same(thisStart) && path.length > 0) { + break; + } + if (edge != null) { + path.unshift(edge); + } + node = pred; + } + return eles.spawn(path); + }; + + // Initializations { dist, pred, edge } + for (var i = 0; i < numNodes; i++) { + var node = nodes[i]; + var info = getInfo(node); + if (node.same(root)) { + info.dist = 0; + } else { + info.dist = Infinity; + } + info.pred = null; + info.edge = null; + } + + // Edges relaxation + var replacedEdge = false; + var checkForEdgeReplacement = function checkForEdgeReplacement(node1, node2, edge, info1, info2, weight) { + var dist = info1.dist + weight; + if (dist < info2.dist && !edge.same(info1.edge)) { + info2.dist = dist; + info2.pred = node1; + info2.edge = edge; + replacedEdge = true; + } + }; + for (var _i = 1; _i < numNodes; _i++) { + replacedEdge = false; + for (var e = 0; e < numEdges; e++) { + var edge = edges[e]; + var src = edge.source(); + var tgt = edge.target(); + var _weight = weightFn(edge); + var srcInfo = getInfo(src); + var tgtInfo = getInfo(tgt); + checkForEdgeReplacement(src, tgt, edge, srcInfo, tgtInfo, _weight); + + // If undirected graph, we need to take into account the 'reverse' edge + if (!directed) { + checkForEdgeReplacement(tgt, src, edge, tgtInfo, srcInfo, _weight); + } + } + if (!replacedEdge) { + break; + } + } + if (replacedEdge) { + // Check for negative weight cycles + var negativeWeightCycleIds = []; + for (var _e = 0; _e < numEdges; _e++) { + var _edge = edges[_e]; + var _src = _edge.source(); + var _tgt = _edge.target(); + var _weight2 = weightFn(_edge); + var srcDist = getInfo(_src).dist; + var tgtDist = getInfo(_tgt).dist; + if (srcDist + _weight2 < tgtDist || !directed && tgtDist + _weight2 < srcDist) { + if (!hasNegativeWeightCycle) { + warn('Graph contains a negative weight cycle for Bellman-Ford'); + hasNegativeWeightCycle = true; + } + if (options.findNegativeWeightCycles !== false) { + var negativeNodes = []; + if (srcDist + _weight2 < tgtDist) { + negativeNodes.push(_src); + } + if (!directed && tgtDist + _weight2 < srcDist) { + negativeNodes.push(_tgt); + } + var numNegativeNodes = negativeNodes.length; + for (var n = 0; n < numNegativeNodes; n++) { + var start = negativeNodes[n]; + var cycle = [start]; + cycle.push(getInfo(start).edge); + var _node = getInfo(start).pred; + while (cycle.indexOf(_node) === -1) { + cycle.push(_node); + cycle.push(getInfo(_node).edge); + _node = getInfo(_node).pred; + } + cycle = cycle.slice(cycle.indexOf(_node)); + var smallestId = cycle[0].id(); + var smallestIndex = 0; + for (var c = 2; c < cycle.length; c += 2) { + if (cycle[c].id() < smallestId) { + smallestId = cycle[c].id(); + smallestIndex = c; + } + } + cycle = cycle.slice(smallestIndex).concat(cycle.slice(0, smallestIndex)); + cycle.push(cycle[0]); + var cycleId = cycle.map(function (el) { + return el.id(); + }).join(","); + if (negativeWeightCycleIds.indexOf(cycleId) === -1) { + negativeWeightCycles.push(eles.spawn(cycle)); + negativeWeightCycleIds.push(cycleId); + } + } + } else { + break; + } + } + } + } + return { + distanceTo: distanceTo, + pathTo: pathTo, + hasNegativeWeightCycle: hasNegativeWeightCycle, + negativeWeightCycles: negativeWeightCycles + }; + } // bellmanFord +}; // elesfn + +var sqrt2 = Math.sqrt(2); + +// Function which colapses 2 (meta) nodes into one +// Updates the remaining edge lists +// Receives as a paramater the edge which causes the collapse +var collapse = function collapse(edgeIndex, nodeMap, remainingEdges) { + if (remainingEdges.length === 0) { + error("Karger-Stein must be run on a connected (sub)graph"); + } + var edgeInfo = remainingEdges[edgeIndex]; + var sourceIn = edgeInfo[1]; + var targetIn = edgeInfo[2]; + var partition1 = nodeMap[sourceIn]; + var partition2 = nodeMap[targetIn]; + var newEdges = remainingEdges; // re-use array + + // Delete all edges between partition1 and partition2 + for (var i = newEdges.length - 1; i >= 0; i--) { + var edge = newEdges[i]; + var src = edge[1]; + var tgt = edge[2]; + if (nodeMap[src] === partition1 && nodeMap[tgt] === partition2 || nodeMap[src] === partition2 && nodeMap[tgt] === partition1) { + newEdges.splice(i, 1); + } + } + + // All edges pointing to partition2 should now point to partition1 + for (var _i = 0; _i < newEdges.length; _i++) { + var _edge = newEdges[_i]; + if (_edge[1] === partition2) { + // Check source + newEdges[_i] = _edge.slice(); // copy + newEdges[_i][1] = partition1; + } else if (_edge[2] === partition2) { + // Check target + newEdges[_i] = _edge.slice(); // copy + newEdges[_i][2] = partition1; + } + } + + // Move all nodes from partition2 to partition1 + for (var _i2 = 0; _i2 < nodeMap.length; _i2++) { + if (nodeMap[_i2] === partition2) { + nodeMap[_i2] = partition1; + } + } + return newEdges; +}; + +// Contracts a graph until we reach a certain number of meta nodes +var contractUntil = function contractUntil(metaNodeMap, remainingEdges, size, sizeLimit) { + while (size > sizeLimit) { + // Choose an edge randomly + var edgeIndex = Math.floor(Math.random() * remainingEdges.length); + + // Collapse graph based on edge + remainingEdges = collapse(edgeIndex, metaNodeMap, remainingEdges); + size--; + } + return remainingEdges; +}; +var elesfn$p = { + // Computes the minimum cut of an undirected graph + // Returns the correct answer with high probability + kargerStein: function kargerStein() { + var _this = this; + var _this$byGroup = this.byGroup(), + nodes = _this$byGroup.nodes, + edges = _this$byGroup.edges; + edges.unmergeBy(function (edge) { + return edge.isLoop(); + }); + var numNodes = nodes.length; + var numEdges = edges.length; + var numIter = Math.ceil(Math.pow(Math.log(numNodes) / Math.LN2, 2)); + var stopSize = Math.floor(numNodes / sqrt2); + if (numNodes < 2) { + error('At least 2 nodes are required for Karger-Stein algorithm'); + return undefined; + } + + // Now store edge destination as indexes + // Format for each edge (edge index, source node index, target node index) + var edgeIndexes = []; + for (var i = 0; i < numEdges; i++) { + var e = edges[i]; + edgeIndexes.push([i, nodes.indexOf(e.source()), nodes.indexOf(e.target())]); + } + + // We will store the best cut found here + var minCutSize = Infinity; + var minCutEdgeIndexes = []; + var minCutNodeMap = new Array(numNodes); + + // Initial meta node partition + var metaNodeMap = new Array(numNodes); + var metaNodeMap2 = new Array(numNodes); + var copyNodesMap = function copyNodesMap(from, to) { + for (var _i3 = 0; _i3 < numNodes; _i3++) { + to[_i3] = from[_i3]; + } + }; + + // Main loop + for (var iter = 0; iter <= numIter; iter++) { + // Reset meta node partition + for (var _i4 = 0; _i4 < numNodes; _i4++) { + metaNodeMap[_i4] = _i4; + } + + // Contract until stop point (stopSize nodes) + var edgesState = contractUntil(metaNodeMap, edgeIndexes.slice(), numNodes, stopSize); + var edgesState2 = edgesState.slice(); // copy + + // Create a copy of the colapsed nodes state + copyNodesMap(metaNodeMap, metaNodeMap2); + + // Run 2 iterations starting in the stop state + var res1 = contractUntil(metaNodeMap, edgesState, stopSize, 2); + var res2 = contractUntil(metaNodeMap2, edgesState2, stopSize, 2); + + // Is any of the 2 results the best cut so far? + if (res1.length <= res2.length && res1.length < minCutSize) { + minCutSize = res1.length; + minCutEdgeIndexes = res1; + copyNodesMap(metaNodeMap, minCutNodeMap); + } else if (res2.length <= res1.length && res2.length < minCutSize) { + minCutSize = res2.length; + minCutEdgeIndexes = res2; + copyNodesMap(metaNodeMap2, minCutNodeMap); + } + } // end of main loop + + // Construct result + var cut = this.spawn(minCutEdgeIndexes.map(function (e) { + return edges[e[0]]; + })); + var partition1 = this.spawn(); + var partition2 = this.spawn(); + + // traverse metaNodeMap for best cut + var witnessNodePartition = minCutNodeMap[0]; + for (var _i5 = 0; _i5 < minCutNodeMap.length; _i5++) { + var partitionId = minCutNodeMap[_i5]; + var node = nodes[_i5]; + if (partitionId === witnessNodePartition) { + partition1.merge(node); + } else { + partition2.merge(node); + } + } + + // construct components corresponding to each disjoint subset of nodes + var constructComponent = function constructComponent(subset) { + var component = _this.spawn(); + subset.forEach(function (node) { + component.merge(node); + node.connectedEdges().forEach(function (edge) { + // ensure edge is within calling collection and edge is not in cut + if (_this.contains(edge) && !cut.contains(edge)) { + component.merge(edge); + } + }); + }); + return component; + }; + var components = [constructComponent(partition1), constructComponent(partition2)]; + var ret = { + cut: cut, + components: components, + // n.b. partitions are included to be compatible with the old api spec + // (could be removed in a future major version) + partition1: partition1, + partition2: partition2 + }; + return ret; + } +}; // elesfn + +var copyPosition = function copyPosition(p) { + return { + x: p.x, + y: p.y + }; +}; +var modelToRenderedPosition = function modelToRenderedPosition(p, zoom, pan) { + return { + x: p.x * zoom + pan.x, + y: p.y * zoom + pan.y + }; +}; +var renderedToModelPosition = function renderedToModelPosition(p, zoom, pan) { + return { + x: (p.x - pan.x) / zoom, + y: (p.y - pan.y) / zoom + }; +}; +var array2point = function array2point(arr) { + return { + x: arr[0], + y: arr[1] + }; +}; +var min = function min(arr) { + var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length; + var min = Infinity; + for (var i = begin; i < end; i++) { + var val = arr[i]; + if (isFinite(val)) { + min = Math.min(val, min); + } + } + return min; +}; +var max = function max(arr) { + var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length; + var max = -Infinity; + for (var i = begin; i < end; i++) { + var val = arr[i]; + if (isFinite(val)) { + max = Math.max(val, max); + } + } + return max; +}; +var mean = function mean(arr) { + var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length; + var total = 0; + var n = 0; + for (var i = begin; i < end; i++) { + var val = arr[i]; + if (isFinite(val)) { + total += val; + n++; + } + } + return total / n; +}; +var median = function median(arr) { + var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length; + var copy = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var sort = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; + var includeHoles = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true; + if (copy) { + arr = arr.slice(begin, end); + } else { + if (end < arr.length) { + arr.splice(end, arr.length - end); + } + if (begin > 0) { + arr.splice(0, begin); + } + } + + // all non finite (e.g. Infinity, NaN) elements must be -Infinity so they go to the start + var off = 0; // offset from non-finite values + for (var i = arr.length - 1; i >= 0; i--) { + var v = arr[i]; + if (includeHoles) { + if (!isFinite(v)) { + arr[i] = -Infinity; + off++; + } + } else { + // just remove it if we don't want to consider holes + arr.splice(i, 1); + } + } + if (sort) { + arr.sort(function (a, b) { + return a - b; + }); // requires copy = true if you don't want to change the orig + } + + var len = arr.length; + var mid = Math.floor(len / 2); + if (len % 2 !== 0) { + return arr[mid + 1 + off]; + } else { + return (arr[mid - 1 + off] + arr[mid + off]) / 2; + } +}; +var deg2rad = function deg2rad(deg) { + return Math.PI * deg / 180; +}; +var getAngleFromDisp = function getAngleFromDisp(dispX, dispY) { + return Math.atan2(dispY, dispX) - Math.PI / 2; +}; +var log2 = Math.log2 || function (n) { + return Math.log(n) / Math.log(2); +}; +var signum = function signum(x) { + if (x > 0) { + return 1; + } else if (x < 0) { + return -1; + } else { + return 0; + } +}; +var dist = function dist(p1, p2) { + return Math.sqrt(sqdist(p1, p2)); +}; +var sqdist = function sqdist(p1, p2) { + var dx = p2.x - p1.x; + var dy = p2.y - p1.y; + return dx * dx + dy * dy; +}; +var inPlaceSumNormalize = function inPlaceSumNormalize(v) { + var length = v.length; + + // First, get sum of all elements + var total = 0; + for (var i = 0; i < length; i++) { + total += v[i]; + } + + // Now, divide each by the sum of all elements + for (var _i = 0; _i < length; _i++) { + v[_i] = v[_i] / total; + } + return v; +}; + +// from http://en.wikipedia.org/wiki/Bézier_curve#Quadratic_curves +var qbezierAt = function qbezierAt(p0, p1, p2, t) { + return (1 - t) * (1 - t) * p0 + 2 * (1 - t) * t * p1 + t * t * p2; +}; +var qbezierPtAt = function qbezierPtAt(p0, p1, p2, t) { + return { + x: qbezierAt(p0.x, p1.x, p2.x, t), + y: qbezierAt(p0.y, p1.y, p2.y, t) + }; +}; +var lineAt = function lineAt(p0, p1, t, d) { + var vec = { + x: p1.x - p0.x, + y: p1.y - p0.y + }; + var vecDist = dist(p0, p1); + var normVec = { + x: vec.x / vecDist, + y: vec.y / vecDist + }; + t = t == null ? 0 : t; + d = d != null ? d : t * vecDist; + return { + x: p0.x + normVec.x * d, + y: p0.y + normVec.y * d + }; +}; +var bound = function bound(min, val, max) { + return Math.max(min, Math.min(max, val)); +}; + +// makes a full bb (x1, y1, x2, y2, w, h) from implicit params +var makeBoundingBox = function makeBoundingBox(bb) { + if (bb == null) { + return { + x1: Infinity, + y1: Infinity, + x2: -Infinity, + y2: -Infinity, + w: 0, + h: 0 + }; + } else if (bb.x1 != null && bb.y1 != null) { + if (bb.x2 != null && bb.y2 != null && bb.x2 >= bb.x1 && bb.y2 >= bb.y1) { + return { + x1: bb.x1, + y1: bb.y1, + x2: bb.x2, + y2: bb.y2, + w: bb.x2 - bb.x1, + h: bb.y2 - bb.y1 + }; + } else if (bb.w != null && bb.h != null && bb.w >= 0 && bb.h >= 0) { + return { + x1: bb.x1, + y1: bb.y1, + x2: bb.x1 + bb.w, + y2: bb.y1 + bb.h, + w: bb.w, + h: bb.h + }; + } + } +}; +var copyBoundingBox = function copyBoundingBox(bb) { + return { + x1: bb.x1, + x2: bb.x2, + w: bb.w, + y1: bb.y1, + y2: bb.y2, + h: bb.h + }; +}; +var clearBoundingBox = function clearBoundingBox(bb) { + bb.x1 = Infinity; + bb.y1 = Infinity; + bb.x2 = -Infinity; + bb.y2 = -Infinity; + bb.w = 0; + bb.h = 0; +}; +var shiftBoundingBox = function shiftBoundingBox(bb, dx, dy) { + return { + x1: bb.x1 + dx, + x2: bb.x2 + dx, + y1: bb.y1 + dy, + y2: bb.y2 + dy, + w: bb.w, + h: bb.h + }; +}; +var updateBoundingBox = function updateBoundingBox(bb1, bb2) { + // update bb1 with bb2 bounds + + bb1.x1 = Math.min(bb1.x1, bb2.x1); + bb1.x2 = Math.max(bb1.x2, bb2.x2); + bb1.w = bb1.x2 - bb1.x1; + bb1.y1 = Math.min(bb1.y1, bb2.y1); + bb1.y2 = Math.max(bb1.y2, bb2.y2); + bb1.h = bb1.y2 - bb1.y1; +}; +var expandBoundingBoxByPoint = function expandBoundingBoxByPoint(bb, x, y) { + bb.x1 = Math.min(bb.x1, x); + bb.x2 = Math.max(bb.x2, x); + bb.w = bb.x2 - bb.x1; + bb.y1 = Math.min(bb.y1, y); + bb.y2 = Math.max(bb.y2, y); + bb.h = bb.y2 - bb.y1; +}; +var expandBoundingBox = function expandBoundingBox(bb) { + var padding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + bb.x1 -= padding; + bb.x2 += padding; + bb.y1 -= padding; + bb.y2 += padding; + bb.w = bb.x2 - bb.x1; + bb.h = bb.y2 - bb.y1; + return bb; +}; +var expandBoundingBoxSides = function expandBoundingBoxSides(bb) { + var padding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [0]; + var top, right, bottom, left; + if (padding.length === 1) { + top = right = bottom = left = padding[0]; + } else if (padding.length === 2) { + top = bottom = padding[0]; + left = right = padding[1]; + } else if (padding.length === 4) { + var _padding = _slicedToArray(padding, 4); + top = _padding[0]; + right = _padding[1]; + bottom = _padding[2]; + left = _padding[3]; + } + bb.x1 -= left; + bb.x2 += right; + bb.y1 -= top; + bb.y2 += bottom; + bb.w = bb.x2 - bb.x1; + bb.h = bb.y2 - bb.y1; + return bb; +}; + +// assign the values of bb2 into bb1 +var assignBoundingBox = function assignBoundingBox(bb1, bb2) { + bb1.x1 = bb2.x1; + bb1.y1 = bb2.y1; + bb1.x2 = bb2.x2; + bb1.y2 = bb2.y2; + bb1.w = bb1.x2 - bb1.x1; + bb1.h = bb1.y2 - bb1.y1; +}; +var boundingBoxesIntersect = function boundingBoxesIntersect(bb1, bb2) { + // case: one bb to right of other + if (bb1.x1 > bb2.x2) { + return false; + } + if (bb2.x1 > bb1.x2) { + return false; + } + + // case: one bb to left of other + if (bb1.x2 < bb2.x1) { + return false; + } + if (bb2.x2 < bb1.x1) { + return false; + } + + // case: one bb above other + if (bb1.y2 < bb2.y1) { + return false; + } + if (bb2.y2 < bb1.y1) { + return false; + } + + // case: one bb below other + if (bb1.y1 > bb2.y2) { + return false; + } + if (bb2.y1 > bb1.y2) { + return false; + } + + // otherwise, must have some overlap + return true; +}; +var inBoundingBox = function inBoundingBox(bb, x, y) { + return bb.x1 <= x && x <= bb.x2 && bb.y1 <= y && y <= bb.y2; +}; +var pointInBoundingBox = function pointInBoundingBox(bb, pt) { + return inBoundingBox(bb, pt.x, pt.y); +}; +var boundingBoxInBoundingBox = function boundingBoxInBoundingBox(bb1, bb2) { + return inBoundingBox(bb1, bb2.x1, bb2.y1) && inBoundingBox(bb1, bb2.x2, bb2.y2); +}; +var roundRectangleIntersectLine = function roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding) { + var cornerRadius = getRoundRectangleRadius(width, height); + var halfWidth = width / 2; + var halfHeight = height / 2; + + // Check intersections with straight line segments + var straightLineIntersections; + + // Top segment, left to right + { + var topStartX = nodeX - halfWidth + cornerRadius - padding; + var topStartY = nodeY - halfHeight - padding; + var topEndX = nodeX + halfWidth - cornerRadius + padding; + var topEndY = topStartY; + straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false); + if (straightLineIntersections.length > 0) { + return straightLineIntersections; + } + } + + // Right segment, top to bottom + { + var rightStartX = nodeX + halfWidth + padding; + var rightStartY = nodeY - halfHeight + cornerRadius - padding; + var rightEndX = rightStartX; + var rightEndY = nodeY + halfHeight - cornerRadius + padding; + straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, rightStartX, rightStartY, rightEndX, rightEndY, false); + if (straightLineIntersections.length > 0) { + return straightLineIntersections; + } + } + + // Bottom segment, left to right + { + var bottomStartX = nodeX - halfWidth + cornerRadius - padding; + var bottomStartY = nodeY + halfHeight + padding; + var bottomEndX = nodeX + halfWidth - cornerRadius + padding; + var bottomEndY = bottomStartY; + straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, bottomStartX, bottomStartY, bottomEndX, bottomEndY, false); + if (straightLineIntersections.length > 0) { + return straightLineIntersections; + } + } + + // Left segment, top to bottom + { + var leftStartX = nodeX - halfWidth - padding; + var leftStartY = nodeY - halfHeight + cornerRadius - padding; + var leftEndX = leftStartX; + var leftEndY = nodeY + halfHeight - cornerRadius + padding; + straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, leftStartX, leftStartY, leftEndX, leftEndY, false); + if (straightLineIntersections.length > 0) { + return straightLineIntersections; + } + } + + // Check intersections with arc segments + var arcIntersections; + + // Top Left + { + var topLeftCenterX = nodeX - halfWidth + cornerRadius; + var topLeftCenterY = nodeY - halfHeight + cornerRadius; + arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, topLeftCenterX, topLeftCenterY, cornerRadius + padding); + + // Ensure the intersection is on the desired quarter of the circle + if (arcIntersections.length > 0 && arcIntersections[0] <= topLeftCenterX && arcIntersections[1] <= topLeftCenterY) { + return [arcIntersections[0], arcIntersections[1]]; + } + } + + // Top Right + { + var topRightCenterX = nodeX + halfWidth - cornerRadius; + var topRightCenterY = nodeY - halfHeight + cornerRadius; + arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, topRightCenterX, topRightCenterY, cornerRadius + padding); + + // Ensure the intersection is on the desired quarter of the circle + if (arcIntersections.length > 0 && arcIntersections[0] >= topRightCenterX && arcIntersections[1] <= topRightCenterY) { + return [arcIntersections[0], arcIntersections[1]]; + } + } + + // Bottom Right + { + var bottomRightCenterX = nodeX + halfWidth - cornerRadius; + var bottomRightCenterY = nodeY + halfHeight - cornerRadius; + arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, bottomRightCenterX, bottomRightCenterY, cornerRadius + padding); + + // Ensure the intersection is on the desired quarter of the circle + if (arcIntersections.length > 0 && arcIntersections[0] >= bottomRightCenterX && arcIntersections[1] >= bottomRightCenterY) { + return [arcIntersections[0], arcIntersections[1]]; + } + } + + // Bottom Left + { + var bottomLeftCenterX = nodeX - halfWidth + cornerRadius; + var bottomLeftCenterY = nodeY + halfHeight - cornerRadius; + arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, bottomLeftCenterX, bottomLeftCenterY, cornerRadius + padding); + + // Ensure the intersection is on the desired quarter of the circle + if (arcIntersections.length > 0 && arcIntersections[0] <= bottomLeftCenterX && arcIntersections[1] >= bottomLeftCenterY) { + return [arcIntersections[0], arcIntersections[1]]; + } + } + return []; // if nothing +}; + +var inLineVicinity = function inLineVicinity(x, y, lx1, ly1, lx2, ly2, tolerance) { + var t = tolerance; + var x1 = Math.min(lx1, lx2); + var x2 = Math.max(lx1, lx2); + var y1 = Math.min(ly1, ly2); + var y2 = Math.max(ly1, ly2); + return x1 - t <= x && x <= x2 + t && y1 - t <= y && y <= y2 + t; +}; +var inBezierVicinity = function inBezierVicinity(x, y, x1, y1, x2, y2, x3, y3, tolerance) { + var bb = { + x1: Math.min(x1, x3, x2) - tolerance, + x2: Math.max(x1, x3, x2) + tolerance, + y1: Math.min(y1, y3, y2) - tolerance, + y2: Math.max(y1, y3, y2) + tolerance + }; + + // if outside the rough bounding box for the bezier, then it can't be a hit + if (x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2) { + // console.log('bezier out of rough bb') + return false; + } else { + // console.log('do more expensive check'); + return true; + } +}; +var solveQuadratic = function solveQuadratic(a, b, c, val) { + c -= val; + var r = b * b - 4 * a * c; + if (r < 0) { + return []; + } + var sqrtR = Math.sqrt(r); + var denom = 2 * a; + var root1 = (-b + sqrtR) / denom; + var root2 = (-b - sqrtR) / denom; + return [root1, root2]; +}; +var solveCubic = function solveCubic(a, b, c, d, result) { + // Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where + // r is the real component, i is the imaginary component + + // An implementation of the Cardano method from the year 1545 + // http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots + + var epsilon = 0.00001; + + // avoid division by zero while keeping the overall expression close in value + if (a === 0) { + a = epsilon; + } + b /= a; + c /= a; + d /= a; + var discriminant, q, r, dum1, s, t, term1, r13; + q = (3.0 * c - b * b) / 9.0; + r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b)); + r /= 54.0; + discriminant = q * q * q + r * r; + result[1] = 0; + term1 = b / 3.0; + if (discriminant > 0) { + s = r + Math.sqrt(discriminant); + s = s < 0 ? -Math.pow(-s, 1.0 / 3.0) : Math.pow(s, 1.0 / 3.0); + t = r - Math.sqrt(discriminant); + t = t < 0 ? -Math.pow(-t, 1.0 / 3.0) : Math.pow(t, 1.0 / 3.0); + result[0] = -term1 + s + t; + term1 += (s + t) / 2.0; + result[4] = result[2] = -term1; + term1 = Math.sqrt(3.0) * (-t + s) / 2; + result[3] = term1; + result[5] = -term1; + return; + } + result[5] = result[3] = 0; + if (discriminant === 0) { + r13 = r < 0 ? -Math.pow(-r, 1.0 / 3.0) : Math.pow(r, 1.0 / 3.0); + result[0] = -term1 + 2.0 * r13; + result[4] = result[2] = -(r13 + term1); + return; + } + q = -q; + dum1 = q * q * q; + dum1 = Math.acos(r / Math.sqrt(dum1)); + r13 = 2.0 * Math.sqrt(q); + result[0] = -term1 + r13 * Math.cos(dum1 / 3.0); + result[2] = -term1 + r13 * Math.cos((dum1 + 2.0 * Math.PI) / 3.0); + result[4] = -term1 + r13 * Math.cos((dum1 + 4.0 * Math.PI) / 3.0); + return; +}; +var sqdistToQuadraticBezier = function sqdistToQuadraticBezier(x, y, x1, y1, x2, y2, x3, y3) { + // Find minimum distance by using the minimum of the distance + // function between the given point and the curve + + // This gives the coefficients of the resulting cubic equation + // whose roots tell us where a possible minimum is + // (Coefficients are divided by 4) + + var a = 1.0 * x1 * x1 - 4 * x1 * x2 + 2 * x1 * x3 + 4 * x2 * x2 - 4 * x2 * x3 + x3 * x3 + y1 * y1 - 4 * y1 * y2 + 2 * y1 * y3 + 4 * y2 * y2 - 4 * y2 * y3 + y3 * y3; + var b = 1.0 * 9 * x1 * x2 - 3 * x1 * x1 - 3 * x1 * x3 - 6 * x2 * x2 + 3 * x2 * x3 + 9 * y1 * y2 - 3 * y1 * y1 - 3 * y1 * y3 - 6 * y2 * y2 + 3 * y2 * y3; + var c = 1.0 * 3 * x1 * x1 - 6 * x1 * x2 + x1 * x3 - x1 * x + 2 * x2 * x2 + 2 * x2 * x - x3 * x + 3 * y1 * y1 - 6 * y1 * y2 + y1 * y3 - y1 * y + 2 * y2 * y2 + 2 * y2 * y - y3 * y; + var d = 1.0 * x1 * x2 - x1 * x1 + x1 * x - x2 * x + y1 * y2 - y1 * y1 + y1 * y - y2 * y; + + // debug("coefficients: " + a / a + ", " + b / a + ", " + c / a + ", " + d / a); + + var roots = []; + + // Use the cubic solving algorithm + solveCubic(a, b, c, d, roots); + var zeroThreshold = 0.0000001; + var params = []; + for (var index = 0; index < 6; index += 2) { + if (Math.abs(roots[index + 1]) < zeroThreshold && roots[index] >= 0 && roots[index] <= 1.0) { + params.push(roots[index]); + } + } + params.push(1.0); + params.push(0.0); + var minDistanceSquared = -1; + var curX, curY, distSquared; + for (var i = 0; i < params.length; i++) { + curX = Math.pow(1.0 - params[i], 2.0) * x1 + 2.0 * (1 - params[i]) * params[i] * x2 + params[i] * params[i] * x3; + curY = Math.pow(1 - params[i], 2.0) * y1 + 2 * (1.0 - params[i]) * params[i] * y2 + params[i] * params[i] * y3; + distSquared = Math.pow(curX - x, 2) + Math.pow(curY - y, 2); + // debug('distance for param ' + params[i] + ": " + Math.sqrt(distSquared)); + if (minDistanceSquared >= 0) { + if (distSquared < minDistanceSquared) { + minDistanceSquared = distSquared; + } + } else { + minDistanceSquared = distSquared; + } + } + return minDistanceSquared; +}; +var sqdistToFiniteLine = function sqdistToFiniteLine(x, y, x1, y1, x2, y2) { + var offset = [x - x1, y - y1]; + var line = [x2 - x1, y2 - y1]; + var lineSq = line[0] * line[0] + line[1] * line[1]; + var hypSq = offset[0] * offset[0] + offset[1] * offset[1]; + var dotProduct = offset[0] * line[0] + offset[1] * line[1]; + var adjSq = dotProduct * dotProduct / lineSq; + if (dotProduct < 0) { + return hypSq; + } + if (adjSq > lineSq) { + return (x - x2) * (x - x2) + (y - y2) * (y - y2); + } + return hypSq - adjSq; +}; +var pointInsidePolygonPoints = function pointInsidePolygonPoints(x, y, points) { + var x1, y1, x2, y2; + var y3; + + // Intersect with vertical line through (x, y) + var up = 0; + // let down = 0; + for (var i = 0; i < points.length / 2; i++) { + x1 = points[i * 2]; + y1 = points[i * 2 + 1]; + if (i + 1 < points.length / 2) { + x2 = points[(i + 1) * 2]; + y2 = points[(i + 1) * 2 + 1]; + } else { + x2 = points[(i + 1 - points.length / 2) * 2]; + y2 = points[(i + 1 - points.length / 2) * 2 + 1]; + } + if (x1 == x && x2 == x) ; else if (x1 >= x && x >= x2 || x1 <= x && x <= x2) { + y3 = (x - x1) / (x2 - x1) * (y2 - y1) + y1; + if (y3 > y) { + up++; + } + + // if( y3 < y ){ + // down++; + // } + } else { + continue; + } + } + if (up % 2 === 0) { + return false; + } else { + return true; + } +}; +var pointInsidePolygon = function pointInsidePolygon(x, y, basePoints, centerX, centerY, width, height, direction, padding) { + var transformedPoints = new Array(basePoints.length); + + // Gives negative angle + var angle; + if (direction[0] != null) { + angle = Math.atan(direction[1] / direction[0]); + if (direction[0] < 0) { + angle = angle + Math.PI / 2; + } else { + angle = -angle - Math.PI / 2; + } + } else { + angle = direction; + } + var cos = Math.cos(-angle); + var sin = Math.sin(-angle); + + // console.log("base: " + basePoints); + for (var i = 0; i < transformedPoints.length / 2; i++) { + transformedPoints[i * 2] = width / 2 * (basePoints[i * 2] * cos - basePoints[i * 2 + 1] * sin); + transformedPoints[i * 2 + 1] = height / 2 * (basePoints[i * 2 + 1] * cos + basePoints[i * 2] * sin); + transformedPoints[i * 2] += centerX; + transformedPoints[i * 2 + 1] += centerY; + } + var points; + if (padding > 0) { + var expandedLineSet = expandPolygon(transformedPoints, -padding); + points = joinLines(expandedLineSet); + } else { + points = transformedPoints; + } + return pointInsidePolygonPoints(x, y, points); +}; +var pointInsideRoundPolygon = function pointInsideRoundPolygon(x, y, basePoints, centerX, centerY, width, height) { + var cutPolygonPoints = new Array(basePoints.length); + var halfW = width / 2; + var halfH = height / 2; + var cornerRadius = getRoundPolygonRadius(width, height); + var squaredCornerRadius = cornerRadius * cornerRadius; + for (var i = 0; i < basePoints.length / 4; i++) { + var sourceUv = void 0, + destUv = void 0; + if (i === 0) { + sourceUv = basePoints.length - 2; + } else { + sourceUv = i * 4 - 2; + } + destUv = i * 4 + 2; + var px = centerX + halfW * basePoints[i * 4]; + var py = centerY + halfH * basePoints[i * 4 + 1]; + var cosTheta = -basePoints[sourceUv] * basePoints[destUv] - basePoints[sourceUv + 1] * basePoints[destUv + 1]; + var offset = cornerRadius / Math.tan(Math.acos(cosTheta) / 2); + var cp0x = px - offset * basePoints[sourceUv]; + var cp0y = py - offset * basePoints[sourceUv + 1]; + var cp1x = px + offset * basePoints[destUv]; + var cp1y = py + offset * basePoints[destUv + 1]; + cutPolygonPoints[i * 4] = cp0x; + cutPolygonPoints[i * 4 + 1] = cp0y; + cutPolygonPoints[i * 4 + 2] = cp1x; + cutPolygonPoints[i * 4 + 3] = cp1y; + var orthx = basePoints[sourceUv + 1]; + var orthy = -basePoints[sourceUv]; + var cosAlpha = orthx * basePoints[destUv] + orthy * basePoints[destUv + 1]; + if (cosAlpha < 0) { + orthx *= -1; + orthy *= -1; + } + var cx = cp0x + orthx * cornerRadius; + var cy = cp0y + orthy * cornerRadius; + var squaredDistance = Math.pow(cx - x, 2) + Math.pow(cy - y, 2); + if (squaredDistance <= squaredCornerRadius) { + return true; + } + } + return pointInsidePolygonPoints(x, y, cutPolygonPoints); +}; +var joinLines = function joinLines(lineSet) { + var vertices = new Array(lineSet.length / 2); + var currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY; + var nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY; + for (var i = 0; i < lineSet.length / 4; i++) { + currentLineStartX = lineSet[i * 4]; + currentLineStartY = lineSet[i * 4 + 1]; + currentLineEndX = lineSet[i * 4 + 2]; + currentLineEndY = lineSet[i * 4 + 3]; + if (i < lineSet.length / 4 - 1) { + nextLineStartX = lineSet[(i + 1) * 4]; + nextLineStartY = lineSet[(i + 1) * 4 + 1]; + nextLineEndX = lineSet[(i + 1) * 4 + 2]; + nextLineEndY = lineSet[(i + 1) * 4 + 3]; + } else { + nextLineStartX = lineSet[0]; + nextLineStartY = lineSet[1]; + nextLineEndX = lineSet[2]; + nextLineEndY = lineSet[3]; + } + var intersection = finiteLinesIntersect(currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY, nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY, true); + vertices[i * 2] = intersection[0]; + vertices[i * 2 + 1] = intersection[1]; + } + return vertices; +}; +var expandPolygon = function expandPolygon(points, pad) { + var expandedLineSet = new Array(points.length * 2); + var currentPointX, currentPointY, nextPointX, nextPointY; + for (var i = 0; i < points.length / 2; i++) { + currentPointX = points[i * 2]; + currentPointY = points[i * 2 + 1]; + if (i < points.length / 2 - 1) { + nextPointX = points[(i + 1) * 2]; + nextPointY = points[(i + 1) * 2 + 1]; + } else { + nextPointX = points[0]; + nextPointY = points[1]; + } + + // Current line: [currentPointX, currentPointY] to [nextPointX, nextPointY] + + // Assume CCW polygon winding + + var offsetX = nextPointY - currentPointY; + var offsetY = -(nextPointX - currentPointX); + + // Normalize + var offsetLength = Math.sqrt(offsetX * offsetX + offsetY * offsetY); + var normalizedOffsetX = offsetX / offsetLength; + var normalizedOffsetY = offsetY / offsetLength; + expandedLineSet[i * 4] = currentPointX + normalizedOffsetX * pad; + expandedLineSet[i * 4 + 1] = currentPointY + normalizedOffsetY * pad; + expandedLineSet[i * 4 + 2] = nextPointX + normalizedOffsetX * pad; + expandedLineSet[i * 4 + 3] = nextPointY + normalizedOffsetY * pad; + } + return expandedLineSet; +}; +var intersectLineEllipse = function intersectLineEllipse(x, y, centerX, centerY, ellipseWradius, ellipseHradius) { + var dispX = centerX - x; + var dispY = centerY - y; + dispX /= ellipseWradius; + dispY /= ellipseHradius; + var len = Math.sqrt(dispX * dispX + dispY * dispY); + var newLength = len - 1; + if (newLength < 0) { + return []; + } + var lenProportion = newLength / len; + return [(centerX - x) * lenProportion + x, (centerY - y) * lenProportion + y]; +}; +var checkInEllipse = function checkInEllipse(x, y, width, height, centerX, centerY, padding) { + x -= centerX; + y -= centerY; + x /= width / 2 + padding; + y /= height / 2 + padding; + return x * x + y * y <= 1; +}; + +// Returns intersections of increasing distance from line's start point +var intersectLineCircle = function intersectLineCircle(x1, y1, x2, y2, centerX, centerY, radius) { + // Calculate d, direction vector of line + var d = [x2 - x1, y2 - y1]; // Direction vector of line + var f = [x1 - centerX, y1 - centerY]; + var a = d[0] * d[0] + d[1] * d[1]; + var b = 2 * (f[0] * d[0] + f[1] * d[1]); + var c = f[0] * f[0] + f[1] * f[1] - radius * radius; + var discriminant = b * b - 4 * a * c; + if (discriminant < 0) { + return []; + } + var t1 = (-b + Math.sqrt(discriminant)) / (2 * a); + var t2 = (-b - Math.sqrt(discriminant)) / (2 * a); + var tMin = Math.min(t1, t2); + var tMax = Math.max(t1, t2); + var inRangeParams = []; + if (tMin >= 0 && tMin <= 1) { + inRangeParams.push(tMin); + } + if (tMax >= 0 && tMax <= 1) { + inRangeParams.push(tMax); + } + if (inRangeParams.length === 0) { + return []; + } + var nearIntersectionX = inRangeParams[0] * d[0] + x1; + var nearIntersectionY = inRangeParams[0] * d[1] + y1; + if (inRangeParams.length > 1) { + if (inRangeParams[0] == inRangeParams[1]) { + return [nearIntersectionX, nearIntersectionY]; + } else { + var farIntersectionX = inRangeParams[1] * d[0] + x1; + var farIntersectionY = inRangeParams[1] * d[1] + y1; + return [nearIntersectionX, nearIntersectionY, farIntersectionX, farIntersectionY]; + } + } else { + return [nearIntersectionX, nearIntersectionY]; + } +}; +var midOfThree = function midOfThree(a, b, c) { + if (b <= a && a <= c || c <= a && a <= b) { + return a; + } else if (a <= b && b <= c || c <= b && b <= a) { + return b; + } else { + return c; + } +}; + +// (x1,y1)=>(x2,y2) intersect with (x3,y3)=>(x4,y4) +var finiteLinesIntersect = function finiteLinesIntersect(x1, y1, x2, y2, x3, y3, x4, y4, infiniteLines) { + var dx13 = x1 - x3; + var dx21 = x2 - x1; + var dx43 = x4 - x3; + var dy13 = y1 - y3; + var dy21 = y2 - y1; + var dy43 = y4 - y3; + var ua_t = dx43 * dy13 - dy43 * dx13; + var ub_t = dx21 * dy13 - dy21 * dx13; + var u_b = dy43 * dx21 - dx43 * dy21; + if (u_b !== 0) { + var ua = ua_t / u_b; + var ub = ub_t / u_b; + var flptThreshold = 0.001; + var _min = 0 - flptThreshold; + var _max = 1 + flptThreshold; + if (_min <= ua && ua <= _max && _min <= ub && ub <= _max) { + return [x1 + ua * dx21, y1 + ua * dy21]; + } else { + if (!infiniteLines) { + return []; + } else { + return [x1 + ua * dx21, y1 + ua * dy21]; + } + } + } else { + if (ua_t === 0 || ub_t === 0) { + // Parallel, coincident lines. Check if overlap + + // Check endpoint of second line + if (midOfThree(x1, x2, x4) === x4) { + return [x4, y4]; + } + + // Check start point of second line + if (midOfThree(x1, x2, x3) === x3) { + return [x3, y3]; + } + + // Endpoint of first line + if (midOfThree(x3, x4, x2) === x2) { + return [x2, y2]; + } + return []; + } else { + // Parallel, non-coincident + return []; + } + } +}; + +// math.polygonIntersectLine( x, y, basePoints, centerX, centerY, width, height, padding ) +// intersect a node polygon (pts transformed) +// +// math.polygonIntersectLine( x, y, basePoints, centerX, centerY ) +// intersect the points (no transform) +var polygonIntersectLine = function polygonIntersectLine(x, y, basePoints, centerX, centerY, width, height, padding) { + var intersections = []; + var intersection; + var transformedPoints = new Array(basePoints.length); + var doTransform = true; + if (width == null) { + doTransform = false; + } + var points; + if (doTransform) { + for (var i = 0; i < transformedPoints.length / 2; i++) { + transformedPoints[i * 2] = basePoints[i * 2] * width + centerX; + transformedPoints[i * 2 + 1] = basePoints[i * 2 + 1] * height + centerY; + } + if (padding > 0) { + var expandedLineSet = expandPolygon(transformedPoints, -padding); + points = joinLines(expandedLineSet); + } else { + points = transformedPoints; + } + } else { + points = basePoints; + } + var currentX, currentY, nextX, nextY; + for (var _i2 = 0; _i2 < points.length / 2; _i2++) { + currentX = points[_i2 * 2]; + currentY = points[_i2 * 2 + 1]; + if (_i2 < points.length / 2 - 1) { + nextX = points[(_i2 + 1) * 2]; + nextY = points[(_i2 + 1) * 2 + 1]; + } else { + nextX = points[0]; + nextY = points[1]; + } + intersection = finiteLinesIntersect(x, y, centerX, centerY, currentX, currentY, nextX, nextY); + if (intersection.length !== 0) { + intersections.push(intersection[0], intersection[1]); + } + } + return intersections; +}; +var roundPolygonIntersectLine = function roundPolygonIntersectLine(x, y, basePoints, centerX, centerY, width, height, padding) { + var intersections = []; + var intersection; + var lines = new Array(basePoints.length); + var halfW = width / 2; + var halfH = height / 2; + var cornerRadius = getRoundPolygonRadius(width, height); + for (var i = 0; i < basePoints.length / 4; i++) { + var sourceUv = void 0, + destUv = void 0; + if (i === 0) { + sourceUv = basePoints.length - 2; + } else { + sourceUv = i * 4 - 2; + } + destUv = i * 4 + 2; + var px = centerX + halfW * basePoints[i * 4]; + var py = centerY + halfH * basePoints[i * 4 + 1]; + var cosTheta = -basePoints[sourceUv] * basePoints[destUv] - basePoints[sourceUv + 1] * basePoints[destUv + 1]; + var offset = cornerRadius / Math.tan(Math.acos(cosTheta) / 2); + var cp0x = px - offset * basePoints[sourceUv]; + var cp0y = py - offset * basePoints[sourceUv + 1]; + var cp1x = px + offset * basePoints[destUv]; + var cp1y = py + offset * basePoints[destUv + 1]; + if (i === 0) { + lines[basePoints.length - 2] = cp0x; + lines[basePoints.length - 1] = cp0y; + } else { + lines[i * 4 - 2] = cp0x; + lines[i * 4 - 1] = cp0y; + } + lines[i * 4] = cp1x; + lines[i * 4 + 1] = cp1y; + var orthx = basePoints[sourceUv + 1]; + var orthy = -basePoints[sourceUv]; + var cosAlpha = orthx * basePoints[destUv] + orthy * basePoints[destUv + 1]; + if (cosAlpha < 0) { + orthx *= -1; + orthy *= -1; + } + var cx = cp0x + orthx * cornerRadius; + var cy = cp0y + orthy * cornerRadius; + intersection = intersectLineCircle(x, y, centerX, centerY, cx, cy, cornerRadius); + if (intersection.length !== 0) { + intersections.push(intersection[0], intersection[1]); + } + } + for (var _i3 = 0; _i3 < lines.length / 4; _i3++) { + intersection = finiteLinesIntersect(x, y, centerX, centerY, lines[_i3 * 4], lines[_i3 * 4 + 1], lines[_i3 * 4 + 2], lines[_i3 * 4 + 3], false); + if (intersection.length !== 0) { + intersections.push(intersection[0], intersection[1]); + } + } + if (intersections.length > 2) { + var lowestIntersection = [intersections[0], intersections[1]]; + var lowestSquaredDistance = Math.pow(lowestIntersection[0] - x, 2) + Math.pow(lowestIntersection[1] - y, 2); + for (var _i4 = 1; _i4 < intersections.length / 2; _i4++) { + var squaredDistance = Math.pow(intersections[_i4 * 2] - x, 2) + Math.pow(intersections[_i4 * 2 + 1] - y, 2); + if (squaredDistance <= lowestSquaredDistance) { + lowestIntersection[0] = intersections[_i4 * 2]; + lowestIntersection[1] = intersections[_i4 * 2 + 1]; + lowestSquaredDistance = squaredDistance; + } + } + return lowestIntersection; + } + return intersections; +}; +var shortenIntersection = function shortenIntersection(intersection, offset, amount) { + var disp = [intersection[0] - offset[0], intersection[1] - offset[1]]; + var length = Math.sqrt(disp[0] * disp[0] + disp[1] * disp[1]); + var lenRatio = (length - amount) / length; + if (lenRatio < 0) { + lenRatio = 0.00001; + } + return [offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1]]; +}; +var generateUnitNgonPointsFitToSquare = function generateUnitNgonPointsFitToSquare(sides, rotationRadians) { + var points = generateUnitNgonPoints(sides, rotationRadians); + points = fitPolygonToSquare(points); + return points; +}; +var fitPolygonToSquare = function fitPolygonToSquare(points) { + var x, y; + var sides = points.length / 2; + var minX = Infinity, + minY = Infinity, + maxX = -Infinity, + maxY = -Infinity; + for (var i = 0; i < sides; i++) { + x = points[2 * i]; + y = points[2 * i + 1]; + minX = Math.min(minX, x); + maxX = Math.max(maxX, x); + minY = Math.min(minY, y); + maxY = Math.max(maxY, y); + } + + // stretch factors + var sx = 2 / (maxX - minX); + var sy = 2 / (maxY - minY); + for (var _i5 = 0; _i5 < sides; _i5++) { + x = points[2 * _i5] = points[2 * _i5] * sx; + y = points[2 * _i5 + 1] = points[2 * _i5 + 1] * sy; + minX = Math.min(minX, x); + maxX = Math.max(maxX, x); + minY = Math.min(minY, y); + maxY = Math.max(maxY, y); + } + if (minY < -1) { + for (var _i6 = 0; _i6 < sides; _i6++) { + y = points[2 * _i6 + 1] = points[2 * _i6 + 1] + (-1 - minY); + } + } + return points; +}; +var generateUnitNgonPoints = function generateUnitNgonPoints(sides, rotationRadians) { + var increment = 1.0 / sides * 2 * Math.PI; + var startAngle = sides % 2 === 0 ? Math.PI / 2.0 + increment / 2.0 : Math.PI / 2.0; + startAngle += rotationRadians; + var points = new Array(sides * 2); + var currentAngle; + for (var i = 0; i < sides; i++) { + currentAngle = i * increment + startAngle; + points[2 * i] = Math.cos(currentAngle); // x + points[2 * i + 1] = Math.sin(-currentAngle); // y + } + + return points; +}; + +// Set the default radius, unless half of width or height is smaller than default +var getRoundRectangleRadius = function getRoundRectangleRadius(width, height) { + return Math.min(width / 4, height / 4, 8); +}; + +// Set the default radius +var getRoundPolygonRadius = function getRoundPolygonRadius(width, height) { + return Math.min(width / 10, height / 10, 8); +}; +var getCutRectangleCornerLength = function getCutRectangleCornerLength() { + return 8; +}; +var bezierPtsToQuadCoeff = function bezierPtsToQuadCoeff(p0, p1, p2) { + return [p0 - 2 * p1 + p2, 2 * (p1 - p0), p0]; +}; + +// get curve width, height, and control point position offsets as a percentage of node height / width +var getBarrelCurveConstants = function getBarrelCurveConstants(width, height) { + return { + heightOffset: Math.min(15, 0.05 * height), + widthOffset: Math.min(100, 0.25 * width), + ctrlPtOffsetPct: 0.05 + }; +}; + +var pageRankDefaults = defaults$g({ + dampingFactor: 0.8, + precision: 0.000001, + iterations: 200, + weight: function weight(edge) { + return 1; + } +}); +var elesfn$o = { + pageRank: function pageRank(options) { + var _pageRankDefaults = pageRankDefaults(options), + dampingFactor = _pageRankDefaults.dampingFactor, + precision = _pageRankDefaults.precision, + iterations = _pageRankDefaults.iterations, + weight = _pageRankDefaults.weight; + var cy = this._private.cy; + var _this$byGroup = this.byGroup(), + nodes = _this$byGroup.nodes, + edges = _this$byGroup.edges; + var numNodes = nodes.length; + var numNodesSqd = numNodes * numNodes; + var numEdges = edges.length; + + // Construct transposed adjacency matrix + // First lets have a zeroed matrix of the right size + // We'll also keep track of the sum of each column + var matrix = new Array(numNodesSqd); + var columnSum = new Array(numNodes); + var additionalProb = (1 - dampingFactor) / numNodes; + + // Create null matrix + for (var i = 0; i < numNodes; i++) { + for (var j = 0; j < numNodes; j++) { + var n = i * numNodes + j; + matrix[n] = 0; + } + columnSum[i] = 0; + } + + // Now, process edges + for (var _i = 0; _i < numEdges; _i++) { + var edge = edges[_i]; + var srcId = edge.data('source'); + var tgtId = edge.data('target'); + + // Don't include loops in the matrix + if (srcId === tgtId) { + continue; + } + var s = nodes.indexOfId(srcId); + var t = nodes.indexOfId(tgtId); + var w = weight(edge); + var _n = t * numNodes + s; + + // Update matrix + matrix[_n] += w; + + // Update column sum + columnSum[s] += w; + } + + // Add additional probability based on damping factor + // Also, take into account columns that have sum = 0 + var p = 1.0 / numNodes + additionalProb; // Shorthand + + // Traverse matrix, column by column + for (var _j = 0; _j < numNodes; _j++) { + if (columnSum[_j] === 0) { + // No 'links' out from node jth, assume equal probability for each possible node + for (var _i2 = 0; _i2 < numNodes; _i2++) { + var _n2 = _i2 * numNodes + _j; + matrix[_n2] = p; + } + } else { + // Node jth has outgoing link, compute normalized probabilities + for (var _i3 = 0; _i3 < numNodes; _i3++) { + var _n3 = _i3 * numNodes + _j; + matrix[_n3] = matrix[_n3] / columnSum[_j] + additionalProb; + } + } + } + + // Compute dominant eigenvector using power method + var eigenvector = new Array(numNodes); + var temp = new Array(numNodes); + var previous; + + // Start with a vector of all 1's + // Also, initialize a null vector which will be used as shorthand + for (var _i4 = 0; _i4 < numNodes; _i4++) { + eigenvector[_i4] = 1; + } + for (var iter = 0; iter < iterations; iter++) { + // Temp array with all 0's + for (var _i5 = 0; _i5 < numNodes; _i5++) { + temp[_i5] = 0; + } + + // Multiply matrix with previous result + for (var _i6 = 0; _i6 < numNodes; _i6++) { + for (var _j2 = 0; _j2 < numNodes; _j2++) { + var _n4 = _i6 * numNodes + _j2; + temp[_i6] += matrix[_n4] * eigenvector[_j2]; + } + } + inPlaceSumNormalize(temp); + previous = eigenvector; + eigenvector = temp; + temp = previous; + var diff = 0; + // Compute difference (squared module) of both vectors + for (var _i7 = 0; _i7 < numNodes; _i7++) { + var delta = previous[_i7] - eigenvector[_i7]; + diff += delta * delta; + } + + // If difference is less than the desired threshold, stop iterating + if (diff < precision) { + break; + } + } + + // Construct result + var res = { + rank: function rank(node) { + node = cy.collection(node)[0]; + return eigenvector[nodes.indexOf(node)]; + } + }; + return res; + } // pageRank +}; // elesfn + +var defaults$f = defaults$g({ + root: null, + weight: function weight(edge) { + return 1; + }, + directed: false, + alpha: 0 +}); +var elesfn$n = { + degreeCentralityNormalized: function degreeCentralityNormalized(options) { + options = defaults$f(options); + var cy = this.cy(); + var nodes = this.nodes(); + var numNodes = nodes.length; + if (!options.directed) { + var degrees = {}; + var maxDegree = 0; + for (var i = 0; i < numNodes; i++) { + var node = nodes[i]; + + // add current node to the current options object and call degreeCentrality + options.root = node; + var currDegree = this.degreeCentrality(options); + if (maxDegree < currDegree.degree) { + maxDegree = currDegree.degree; + } + degrees[node.id()] = currDegree.degree; + } + return { + degree: function degree(node) { + if (maxDegree === 0) { + return 0; + } + if (string(node)) { + // from is a selector string + node = cy.filter(node); + } + return degrees[node.id()] / maxDegree; + } + }; + } else { + var indegrees = {}; + var outdegrees = {}; + var maxIndegree = 0; + var maxOutdegree = 0; + for (var _i = 0; _i < numNodes; _i++) { + var _node = nodes[_i]; + var id = _node.id(); + + // add current node to the current options object and call degreeCentrality + options.root = _node; + var _currDegree = this.degreeCentrality(options); + if (maxIndegree < _currDegree.indegree) maxIndegree = _currDegree.indegree; + if (maxOutdegree < _currDegree.outdegree) maxOutdegree = _currDegree.outdegree; + indegrees[id] = _currDegree.indegree; + outdegrees[id] = _currDegree.outdegree; + } + return { + indegree: function indegree(node) { + if (maxIndegree == 0) { + return 0; + } + if (string(node)) { + // from is a selector string + node = cy.filter(node); + } + return indegrees[node.id()] / maxIndegree; + }, + outdegree: function outdegree(node) { + if (maxOutdegree === 0) { + return 0; + } + if (string(node)) { + // from is a selector string + node = cy.filter(node); + } + return outdegrees[node.id()] / maxOutdegree; + } + }; + } + }, + // degreeCentralityNormalized + + // Implemented from the algorithm in Opsahl's paper + // "Node centrality in weighted networks: Generalizing degree and shortest paths" + // check the heading 2 "Degree" + degreeCentrality: function degreeCentrality(options) { + options = defaults$f(options); + var cy = this.cy(); + var callingEles = this; + var _options = options, + root = _options.root, + weight = _options.weight, + directed = _options.directed, + alpha = _options.alpha; + root = cy.collection(root)[0]; + if (!directed) { + var connEdges = root.connectedEdges().intersection(callingEles); + var k = connEdges.length; + var s = 0; + + // Now, sum edge weights + for (var i = 0; i < connEdges.length; i++) { + s += weight(connEdges[i]); + } + return { + degree: Math.pow(k, 1 - alpha) * Math.pow(s, alpha) + }; + } else { + var edges = root.connectedEdges(); + var incoming = edges.filter(function (edge) { + return edge.target().same(root) && callingEles.has(edge); + }); + var outgoing = edges.filter(function (edge) { + return edge.source().same(root) && callingEles.has(edge); + }); + var k_in = incoming.length; + var k_out = outgoing.length; + var s_in = 0; + var s_out = 0; + + // Now, sum incoming edge weights + for (var _i2 = 0; _i2 < incoming.length; _i2++) { + s_in += weight(incoming[_i2]); + } + + // Now, sum outgoing edge weights + for (var _i3 = 0; _i3 < outgoing.length; _i3++) { + s_out += weight(outgoing[_i3]); + } + return { + indegree: Math.pow(k_in, 1 - alpha) * Math.pow(s_in, alpha), + outdegree: Math.pow(k_out, 1 - alpha) * Math.pow(s_out, alpha) + }; + } + } // degreeCentrality +}; // elesfn + +// nice, short mathematical alias +elesfn$n.dc = elesfn$n.degreeCentrality; +elesfn$n.dcn = elesfn$n.degreeCentralityNormalised = elesfn$n.degreeCentralityNormalized; + +var defaults$e = defaults$g({ + harmonic: true, + weight: function weight() { + return 1; + }, + directed: false, + root: null +}); +var elesfn$m = { + closenessCentralityNormalized: function closenessCentralityNormalized(options) { + var _defaults = defaults$e(options), + harmonic = _defaults.harmonic, + weight = _defaults.weight, + directed = _defaults.directed; + var cy = this.cy(); + var closenesses = {}; + var maxCloseness = 0; + var nodes = this.nodes(); + var fw = this.floydWarshall({ + weight: weight, + directed: directed + }); + + // Compute closeness for every node and find the maximum closeness + for (var i = 0; i < nodes.length; i++) { + var currCloseness = 0; + var node_i = nodes[i]; + for (var j = 0; j < nodes.length; j++) { + if (i !== j) { + var d = fw.distance(node_i, nodes[j]); + if (harmonic) { + currCloseness += 1 / d; + } else { + currCloseness += d; + } + } + } + if (!harmonic) { + currCloseness = 1 / currCloseness; + } + if (maxCloseness < currCloseness) { + maxCloseness = currCloseness; + } + closenesses[node_i.id()] = currCloseness; + } + return { + closeness: function closeness(node) { + if (maxCloseness == 0) { + return 0; + } + if (string(node)) { + // from is a selector string + node = cy.filter(node)[0].id(); + } else { + // from is a node + node = node.id(); + } + return closenesses[node] / maxCloseness; + } + }; + }, + // Implemented from pseudocode from wikipedia + closenessCentrality: function closenessCentrality(options) { + var _defaults2 = defaults$e(options), + root = _defaults2.root, + weight = _defaults2.weight, + directed = _defaults2.directed, + harmonic = _defaults2.harmonic; + root = this.filter(root)[0]; + + // we need distance from this node to every other node + var dijkstra = this.dijkstra({ + root: root, + weight: weight, + directed: directed + }); + var totalDistance = 0; + var nodes = this.nodes(); + for (var i = 0; i < nodes.length; i++) { + var n = nodes[i]; + if (!n.same(root)) { + var d = dijkstra.distanceTo(n); + if (harmonic) { + totalDistance += 1 / d; + } else { + totalDistance += d; + } + } + } + return harmonic ? totalDistance : 1 / totalDistance; + } // closenessCentrality +}; // elesfn + +// nice, short mathematical alias +elesfn$m.cc = elesfn$m.closenessCentrality; +elesfn$m.ccn = elesfn$m.closenessCentralityNormalised = elesfn$m.closenessCentralityNormalized; + +var defaults$d = defaults$g({ + weight: null, + directed: false +}); +var elesfn$l = { + // Implemented from the algorithm in the paper "On Variants of Shortest-Path Betweenness Centrality and their Generic Computation" by Ulrik Brandes + betweennessCentrality: function betweennessCentrality(options) { + var _defaults = defaults$d(options), + directed = _defaults.directed, + weight = _defaults.weight; + var weighted = weight != null; + var cy = this.cy(); + + // starting + var V = this.nodes(); + var A = {}; + var _C = {}; + var max = 0; + var C = { + set: function set(key, val) { + _C[key] = val; + if (val > max) { + max = val; + } + }, + get: function get(key) { + return _C[key]; + } + }; + + // A contains the neighborhoods of every node + for (var i = 0; i < V.length; i++) { + var v = V[i]; + var vid = v.id(); + if (directed) { + A[vid] = v.outgoers().nodes(); // get outgoers of every node + } else { + A[vid] = v.openNeighborhood().nodes(); // get neighbors of every node + } + + C.set(vid, 0); + } + var _loop = function _loop(s) { + var sid = V[s].id(); + var S = []; // stack + var P = {}; + var g = {}; + var d = {}; + var Q = new Heap__default["default"](function (a, b) { + return d[a] - d[b]; + }); // queue + + // init dictionaries + for (var _i = 0; _i < V.length; _i++) { + var _vid = V[_i].id(); + P[_vid] = []; + g[_vid] = 0; + d[_vid] = Infinity; + } + g[sid] = 1; // sigma + d[sid] = 0; // distance to s + + Q.push(sid); + while (!Q.empty()) { + var _v = Q.pop(); + S.push(_v); + if (weighted) { + for (var j = 0; j < A[_v].length; j++) { + var w = A[_v][j]; + var vEle = cy.getElementById(_v); + var edge = void 0; + if (vEle.edgesTo(w).length > 0) { + edge = vEle.edgesTo(w)[0]; + } else { + edge = w.edgesTo(vEle)[0]; + } + var edgeWeight = weight(edge); + w = w.id(); + if (d[w] > d[_v] + edgeWeight) { + d[w] = d[_v] + edgeWeight; + if (Q.nodes.indexOf(w) < 0) { + //if w is not in Q + Q.push(w); + } else { + // update position if w is in Q + Q.updateItem(w); + } + g[w] = 0; + P[w] = []; + } + if (d[w] == d[_v] + edgeWeight) { + g[w] = g[w] + g[_v]; + P[w].push(_v); + } + } + } else { + for (var _j = 0; _j < A[_v].length; _j++) { + var _w = A[_v][_j].id(); + if (d[_w] == Infinity) { + Q.push(_w); + d[_w] = d[_v] + 1; + } + if (d[_w] == d[_v] + 1) { + g[_w] = g[_w] + g[_v]; + P[_w].push(_v); + } + } + } + } + var e = {}; + for (var _i2 = 0; _i2 < V.length; _i2++) { + e[V[_i2].id()] = 0; + } + while (S.length > 0) { + var _w2 = S.pop(); + for (var _j2 = 0; _j2 < P[_w2].length; _j2++) { + var _v2 = P[_w2][_j2]; + e[_v2] = e[_v2] + g[_v2] / g[_w2] * (1 + e[_w2]); + } + if (_w2 != V[s].id()) { + C.set(_w2, C.get(_w2) + e[_w2]); + } + } + }; + for (var s = 0; s < V.length; s++) { + _loop(s); + } + var ret = { + betweenness: function betweenness(node) { + var id = cy.collection(node).id(); + return C.get(id); + }, + betweennessNormalized: function betweennessNormalized(node) { + if (max == 0) { + return 0; + } + var id = cy.collection(node).id(); + return C.get(id) / max; + } + }; + + // alias + ret.betweennessNormalised = ret.betweennessNormalized; + return ret; + } // betweennessCentrality +}; // elesfn + +// nice, short mathematical alias +elesfn$l.bc = elesfn$l.betweennessCentrality; + +// Implemented by Zoe Xi @zoexi for GSOC 2016 + +/* eslint-disable no-unused-vars */ +var defaults$c = defaults$g({ + expandFactor: 2, + // affects time of computation and cluster granularity to some extent: M * M + inflateFactor: 2, + // affects cluster granularity (the greater the value, the more clusters): M(i,j) / E(j) + multFactor: 1, + // optional self loops for each node. Use a neutral value to improve cluster computations. + maxIterations: 20, + // maximum number of iterations of the MCL algorithm in a single run + attributes: [ + // attributes/features used to group nodes, ie. similarity values between nodes + function (edge) { + return 1; + }] +}); +/* eslint-enable */ + +var setOptions$3 = function setOptions(options) { + return defaults$c(options); +}; +/* eslint-enable */ + +var getSimilarity$1 = function getSimilarity(edge, attributes) { + var total = 0; + for (var i = 0; i < attributes.length; i++) { + total += attributes[i](edge); + } + return total; +}; +var addLoops = function addLoops(M, n, val) { + for (var i = 0; i < n; i++) { + M[i * n + i] = val; + } +}; +var normalize = function normalize(M, n) { + var sum; + for (var col = 0; col < n; col++) { + sum = 0; + for (var row = 0; row < n; row++) { + sum += M[row * n + col]; + } + for (var _row = 0; _row < n; _row++) { + M[_row * n + col] = M[_row * n + col] / sum; + } + } +}; + +// TODO: blocked matrix multiplication? +var mmult = function mmult(A, B, n) { + var C = new Array(n * n); + for (var i = 0; i < n; i++) { + for (var j = 0; j < n; j++) { + C[i * n + j] = 0; + } + for (var k = 0; k < n; k++) { + for (var _j = 0; _j < n; _j++) { + C[i * n + _j] += A[i * n + k] * B[k * n + _j]; + } + } + } + return C; +}; +var expand = function expand(M, n, expandFactor /** power **/) { + var _M = M.slice(0); + for (var p = 1; p < expandFactor; p++) { + M = mmult(M, _M, n); + } + return M; +}; +var inflate = function inflate(M, n, inflateFactor /** r **/) { + var _M = new Array(n * n); + + // M(i,j) ^ inflatePower + for (var i = 0; i < n * n; i++) { + _M[i] = Math.pow(M[i], inflateFactor); + } + normalize(_M, n); + return _M; +}; +var hasConverged = function hasConverged(M, _M, n2, roundFactor) { + // Check that both matrices have the same elements (i,j) + for (var i = 0; i < n2; i++) { + var v1 = Math.round(M[i] * Math.pow(10, roundFactor)) / Math.pow(10, roundFactor); // truncate to 'roundFactor' decimal places + var v2 = Math.round(_M[i] * Math.pow(10, roundFactor)) / Math.pow(10, roundFactor); + if (v1 !== v2) { + return false; + } + } + return true; +}; +var assign$2 = function assign(M, n, nodes, cy) { + var clusters = []; + for (var i = 0; i < n; i++) { + var cluster = []; + for (var j = 0; j < n; j++) { + // Row-wise attractors and elements that they attract belong in same cluster + if (Math.round(M[i * n + j] * 1000) / 1000 > 0) { + cluster.push(nodes[j]); + } + } + if (cluster.length !== 0) { + clusters.push(cy.collection(cluster)); + } + } + return clusters; +}; +var isDuplicate = function isDuplicate(c1, c2) { + for (var i = 0; i < c1.length; i++) { + if (!c2[i] || c1[i].id() !== c2[i].id()) { + return false; + } + } + return true; +}; +var removeDuplicates = function removeDuplicates(clusters) { + for (var i = 0; i < clusters.length; i++) { + for (var j = 0; j < clusters.length; j++) { + if (i != j && isDuplicate(clusters[i], clusters[j])) { + clusters.splice(j, 1); + } + } + } + return clusters; +}; +var markovClustering = function markovClustering(options) { + var nodes = this.nodes(); + var edges = this.edges(); + var cy = this.cy(); + + // Set parameters of algorithm: + var opts = setOptions$3(options); + + // Map each node to its position in node array + var id2position = {}; + for (var i = 0; i < nodes.length; i++) { + id2position[nodes[i].id()] = i; + } + + // Generate stochastic matrix M from input graph G (should be symmetric/undirected) + var n = nodes.length, + n2 = n * n; + var M = new Array(n2), + _M; + for (var _i = 0; _i < n2; _i++) { + M[_i] = 0; + } + for (var e = 0; e < edges.length; e++) { + var edge = edges[e]; + var _i2 = id2position[edge.source().id()]; + var j = id2position[edge.target().id()]; + var sim = getSimilarity$1(edge, opts.attributes); + M[_i2 * n + j] += sim; // G should be symmetric and undirected + M[j * n + _i2] += sim; + } + + // Begin Markov cluster algorithm + + // Step 1: Add self loops to each node, ie. add multFactor to matrix diagonal + addLoops(M, n, opts.multFactor); + + // Step 2: M = normalize( M ); + normalize(M, n); + var isStillMoving = true; + var iterations = 0; + while (isStillMoving && iterations < opts.maxIterations) { + isStillMoving = false; + + // Step 3: + _M = expand(M, n, opts.expandFactor); + + // Step 4: + M = inflate(_M, n, opts.inflateFactor); + + // Step 5: check to see if ~steady state has been reached + if (!hasConverged(M, _M, n2, 4)) { + isStillMoving = true; + } + iterations++; + } + + // Build clusters from matrix + var clusters = assign$2(M, n, nodes, cy); + + // Remove duplicate clusters due to symmetry of graph and M matrix + clusters = removeDuplicates(clusters); + return clusters; +}; +var markovClustering$1 = { + markovClustering: markovClustering, + mcl: markovClustering +}; + +// Common distance metrics for clustering algorithms +var identity = function identity(x) { + return x; +}; +var absDiff = function absDiff(p, q) { + return Math.abs(q - p); +}; +var addAbsDiff = function addAbsDiff(total, p, q) { + return total + absDiff(p, q); +}; +var addSquaredDiff = function addSquaredDiff(total, p, q) { + return total + Math.pow(q - p, 2); +}; +var sqrt = function sqrt(x) { + return Math.sqrt(x); +}; +var maxAbsDiff = function maxAbsDiff(currentMax, p, q) { + return Math.max(currentMax, absDiff(p, q)); +}; +var getDistance = function getDistance(length, getP, getQ, init, visit) { + var post = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : identity; + var ret = init; + var p, q; + for (var dim = 0; dim < length; dim++) { + p = getP(dim); + q = getQ(dim); + ret = visit(ret, p, q); + } + return post(ret); +}; +var distances = { + euclidean: function euclidean(length, getP, getQ) { + if (length >= 2) { + return getDistance(length, getP, getQ, 0, addSquaredDiff, sqrt); + } else { + // for single attr case, more efficient to avoid sqrt + return getDistance(length, getP, getQ, 0, addAbsDiff); + } + }, + squaredEuclidean: function squaredEuclidean(length, getP, getQ) { + return getDistance(length, getP, getQ, 0, addSquaredDiff); + }, + manhattan: function manhattan(length, getP, getQ) { + return getDistance(length, getP, getQ, 0, addAbsDiff); + }, + max: function max(length, getP, getQ) { + return getDistance(length, getP, getQ, -Infinity, maxAbsDiff); + } +}; + +// in case the user accidentally doesn't use camel case +distances['squared-euclidean'] = distances['squaredEuclidean']; +distances['squaredeuclidean'] = distances['squaredEuclidean']; +function clusteringDistance (method, length, getP, getQ, nodeP, nodeQ) { + var impl; + if (fn$6(method)) { + impl = method; + } else { + impl = distances[method] || distances.euclidean; + } + if (length === 0 && fn$6(method)) { + return impl(nodeP, nodeQ); + } else { + return impl(length, getP, getQ, nodeP, nodeQ); + } +} + +var defaults$b = defaults$g({ + k: 2, + m: 2, + sensitivityThreshold: 0.0001, + distance: 'euclidean', + maxIterations: 10, + attributes: [], + testMode: false, + testCentroids: null +}); +var setOptions$2 = function setOptions(options) { + return defaults$b(options); +}; + +var getDist = function getDist(type, node, centroid, attributes, mode) { + var noNodeP = mode !== 'kMedoids'; + var getP = noNodeP ? function (i) { + return centroid[i]; + } : function (i) { + return attributes[i](centroid); + }; + var getQ = function getQ(i) { + return attributes[i](node); + }; + var nodeP = centroid; + var nodeQ = node; + return clusteringDistance(type, attributes.length, getP, getQ, nodeP, nodeQ); +}; +var randomCentroids = function randomCentroids(nodes, k, attributes) { + var ndim = attributes.length; + var min = new Array(ndim); + var max = new Array(ndim); + var centroids = new Array(k); + var centroid = null; + + // Find min, max values for each attribute dimension + for (var i = 0; i < ndim; i++) { + min[i] = nodes.min(attributes[i]).value; + max[i] = nodes.max(attributes[i]).value; + } + + // Build k centroids, each represented as an n-dim feature vector + for (var c = 0; c < k; c++) { + centroid = []; + for (var _i = 0; _i < ndim; _i++) { + centroid[_i] = Math.random() * (max[_i] - min[_i]) + min[_i]; // random initial value + } + + centroids[c] = centroid; + } + return centroids; +}; +var classify = function classify(node, centroids, distance, attributes, type) { + var min = Infinity; + var index = 0; + for (var i = 0; i < centroids.length; i++) { + var dist = getDist(distance, node, centroids[i], attributes, type); + if (dist < min) { + min = dist; + index = i; + } + } + return index; +}; +var buildCluster = function buildCluster(centroid, nodes, assignment) { + var cluster = []; + var node = null; + for (var n = 0; n < nodes.length; n++) { + node = nodes[n]; + if (assignment[node.id()] === centroid) { + //console.log("Node " + node.id() + " is associated with medoid #: " + m); + cluster.push(node); + } + } + return cluster; +}; +var haveValuesConverged = function haveValuesConverged(v1, v2, sensitivityThreshold) { + return Math.abs(v2 - v1) <= sensitivityThreshold; +}; +var haveMatricesConverged = function haveMatricesConverged(v1, v2, sensitivityThreshold) { + for (var i = 0; i < v1.length; i++) { + for (var j = 0; j < v1[i].length; j++) { + var diff = Math.abs(v1[i][j] - v2[i][j]); + if (diff > sensitivityThreshold) { + return false; + } + } + } + return true; +}; +var seenBefore = function seenBefore(node, medoids, n) { + for (var i = 0; i < n; i++) { + if (node === medoids[i]) return true; + } + return false; +}; +var randomMedoids = function randomMedoids(nodes, k) { + var medoids = new Array(k); + + // For small data sets, the probability of medoid conflict is greater, + // so we need to check to see if we've already seen or chose this node before. + if (nodes.length < 50) { + // Randomly select k medoids from the n nodes + for (var i = 0; i < k; i++) { + var node = nodes[Math.floor(Math.random() * nodes.length)]; + + // If we've already chosen this node to be a medoid, don't choose it again (for small data sets). + // Instead choose a different random node. + while (seenBefore(node, medoids, i)) { + node = nodes[Math.floor(Math.random() * nodes.length)]; + } + medoids[i] = node; + } + } else { + // Relatively large data set, so pretty safe to not check and just select random nodes + for (var _i2 = 0; _i2 < k; _i2++) { + medoids[_i2] = nodes[Math.floor(Math.random() * nodes.length)]; + } + } + return medoids; +}; +var findCost = function findCost(potentialNewMedoid, cluster, attributes) { + var cost = 0; + for (var n = 0; n < cluster.length; n++) { + cost += getDist('manhattan', cluster[n], potentialNewMedoid, attributes, 'kMedoids'); + } + return cost; +}; +var kMeans = function kMeans(options) { + var cy = this.cy(); + var nodes = this.nodes(); + var node = null; + + // Set parameters of algorithm: # of clusters, distance metric, etc. + var opts = setOptions$2(options); + + // Begin k-means algorithm + var clusters = new Array(opts.k); + var assignment = {}; + var centroids; + + // Step 1: Initialize centroid positions + if (opts.testMode) { + if (typeof opts.testCentroids === 'number') { + // TODO: implement a seeded random number generator. + opts.testCentroids; + centroids = randomCentroids(nodes, opts.k, opts.attributes); + } else if (_typeof(opts.testCentroids) === 'object') { + centroids = opts.testCentroids; + } else { + centroids = randomCentroids(nodes, opts.k, opts.attributes); + } + } else { + centroids = randomCentroids(nodes, opts.k, opts.attributes); + } + var isStillMoving = true; + var iterations = 0; + while (isStillMoving && iterations < opts.maxIterations) { + // Step 2: Assign nodes to the nearest centroid + for (var n = 0; n < nodes.length; n++) { + node = nodes[n]; + // Determine which cluster this node belongs to: node id => cluster # + assignment[node.id()] = classify(node, centroids, opts.distance, opts.attributes, 'kMeans'); + } + + // Step 3: For each of the k clusters, update its centroid + isStillMoving = false; + for (var c = 0; c < opts.k; c++) { + // Get all nodes that belong to this cluster + var cluster = buildCluster(c, nodes, assignment); + if (cluster.length === 0) { + // If cluster is empty, break out early & move to next cluster + continue; + } + + // Update centroids by calculating avg of all nodes within the cluster. + var ndim = opts.attributes.length; + var centroid = centroids[c]; // [ dim_1, dim_2, dim_3, ... , dim_n ] + var newCentroid = new Array(ndim); + var sum = new Array(ndim); + for (var d = 0; d < ndim; d++) { + sum[d] = 0.0; + for (var i = 0; i < cluster.length; i++) { + node = cluster[i]; + sum[d] += opts.attributes[d](node); + } + newCentroid[d] = sum[d] / cluster.length; + + // Check to see if algorithm has converged, i.e. when centroids no longer change + if (!haveValuesConverged(newCentroid[d], centroid[d], opts.sensitivityThreshold)) { + isStillMoving = true; + } + } + centroids[c] = newCentroid; + clusters[c] = cy.collection(cluster); + } + iterations++; + } + return clusters; +}; +var kMedoids = function kMedoids(options) { + var cy = this.cy(); + var nodes = this.nodes(); + var node = null; + var opts = setOptions$2(options); + + // Begin k-medoids algorithm + var clusters = new Array(opts.k); + var medoids; + var assignment = {}; + var curCost; + var minCosts = new Array(opts.k); // minimum cost configuration for each cluster + + // Step 1: Initialize k medoids + if (opts.testMode) { + if (typeof opts.testCentroids === 'number') ; else if (_typeof(opts.testCentroids) === 'object') { + medoids = opts.testCentroids; + } else { + medoids = randomMedoids(nodes, opts.k); + } + } else { + medoids = randomMedoids(nodes, opts.k); + } + var isStillMoving = true; + var iterations = 0; + while (isStillMoving && iterations < opts.maxIterations) { + // Step 2: Assign nodes to the nearest medoid + for (var n = 0; n < nodes.length; n++) { + node = nodes[n]; + // Determine which cluster this node belongs to: node id => cluster # + assignment[node.id()] = classify(node, medoids, opts.distance, opts.attributes, 'kMedoids'); + } + isStillMoving = false; + // Step 3: For each medoid m, and for each node associated with mediod m, + // select the node with the lowest configuration cost as new medoid. + for (var m = 0; m < medoids.length; m++) { + // Get all nodes that belong to this medoid + var cluster = buildCluster(m, nodes, assignment); + if (cluster.length === 0) { + // If cluster is empty, break out early & move to next cluster + continue; + } + minCosts[m] = findCost(medoids[m], cluster, opts.attributes); // original cost + + // Select different medoid if its configuration has the lowest cost + for (var _n = 0; _n < cluster.length; _n++) { + curCost = findCost(cluster[_n], cluster, opts.attributes); + if (curCost < minCosts[m]) { + minCosts[m] = curCost; + medoids[m] = cluster[_n]; + isStillMoving = true; + } + } + clusters[m] = cy.collection(cluster); + } + iterations++; + } + return clusters; +}; +var updateCentroids = function updateCentroids(centroids, nodes, U, weight, opts) { + var numerator, denominator; + for (var n = 0; n < nodes.length; n++) { + for (var c = 0; c < centroids.length; c++) { + weight[n][c] = Math.pow(U[n][c], opts.m); + } + } + for (var _c = 0; _c < centroids.length; _c++) { + for (var dim = 0; dim < opts.attributes.length; dim++) { + numerator = 0; + denominator = 0; + for (var _n2 = 0; _n2 < nodes.length; _n2++) { + numerator += weight[_n2][_c] * opts.attributes[dim](nodes[_n2]); + denominator += weight[_n2][_c]; + } + centroids[_c][dim] = numerator / denominator; + } + } +}; +var updateMembership = function updateMembership(U, _U, centroids, nodes, opts) { + // Save previous step + for (var i = 0; i < U.length; i++) { + _U[i] = U[i].slice(); + } + var sum, numerator, denominator; + var pow = 2 / (opts.m - 1); + for (var c = 0; c < centroids.length; c++) { + for (var n = 0; n < nodes.length; n++) { + sum = 0; + for (var k = 0; k < centroids.length; k++) { + // against all other centroids + numerator = getDist(opts.distance, nodes[n], centroids[c], opts.attributes, 'cmeans'); + denominator = getDist(opts.distance, nodes[n], centroids[k], opts.attributes, 'cmeans'); + sum += Math.pow(numerator / denominator, pow); + } + U[n][c] = 1 / sum; + } + } +}; +var assign$1 = function assign(nodes, U, opts, cy) { + var clusters = new Array(opts.k); + for (var c = 0; c < clusters.length; c++) { + clusters[c] = []; + } + var max; + var index; + for (var n = 0; n < U.length; n++) { + // for each node (U is N x C matrix) + max = -Infinity; + index = -1; + // Determine which cluster the node is most likely to belong in + for (var _c2 = 0; _c2 < U[0].length; _c2++) { + if (U[n][_c2] > max) { + max = U[n][_c2]; + index = _c2; + } + } + clusters[index].push(nodes[n]); + } + + // Turn every array into a collection of nodes + for (var _c3 = 0; _c3 < clusters.length; _c3++) { + clusters[_c3] = cy.collection(clusters[_c3]); + } + return clusters; +}; +var fuzzyCMeans = function fuzzyCMeans(options) { + var cy = this.cy(); + var nodes = this.nodes(); + var opts = setOptions$2(options); + + // Begin fuzzy c-means algorithm + var clusters; + var centroids; + var U; + var _U; + var weight; + + // Step 1: Initialize letiables. + _U = new Array(nodes.length); + for (var i = 0; i < nodes.length; i++) { + // N x C matrix + _U[i] = new Array(opts.k); + } + U = new Array(nodes.length); + for (var _i3 = 0; _i3 < nodes.length; _i3++) { + // N x C matrix + U[_i3] = new Array(opts.k); + } + for (var _i4 = 0; _i4 < nodes.length; _i4++) { + var total = 0; + for (var j = 0; j < opts.k; j++) { + U[_i4][j] = Math.random(); + total += U[_i4][j]; + } + for (var _j = 0; _j < opts.k; _j++) { + U[_i4][_j] = U[_i4][_j] / total; + } + } + centroids = new Array(opts.k); + for (var _i5 = 0; _i5 < opts.k; _i5++) { + centroids[_i5] = new Array(opts.attributes.length); + } + weight = new Array(nodes.length); + for (var _i6 = 0; _i6 < nodes.length; _i6++) { + // N x C matrix + weight[_i6] = new Array(opts.k); + } + // end init FCM + + var isStillMoving = true; + var iterations = 0; + while (isStillMoving && iterations < opts.maxIterations) { + isStillMoving = false; + + // Step 2: Calculate the centroids for each step. + updateCentroids(centroids, nodes, U, weight, opts); + + // Step 3: Update the partition matrix U. + updateMembership(U, _U, centroids, nodes, opts); + + // Step 4: Check for convergence. + if (!haveMatricesConverged(U, _U, opts.sensitivityThreshold)) { + isStillMoving = true; + } + iterations++; + } + + // Assign nodes to clusters with highest probability. + clusters = assign$1(nodes, U, opts, cy); + return { + clusters: clusters, + degreeOfMembership: U + }; +}; +var kClustering = { + kMeans: kMeans, + kMedoids: kMedoids, + fuzzyCMeans: fuzzyCMeans, + fcm: fuzzyCMeans +}; + +// Implemented by Zoe Xi @zoexi for GSOC 2016 +var defaults$a = defaults$g({ + distance: 'euclidean', + // distance metric to compare nodes + linkage: 'min', + // linkage criterion : how to determine the distance between clusters of nodes + mode: 'threshold', + // mode:'threshold' => clusters must be threshold distance apart + threshold: Infinity, + // the distance threshold + // mode:'dendrogram' => the nodes are organised as leaves in a tree (siblings are close), merging makes clusters + addDendrogram: false, + // whether to add the dendrogram to the graph for viz + dendrogramDepth: 0, + // depth at which dendrogram branches are merged into the returned clusters + attributes: [] // array of attr functions +}); + +var linkageAliases = { + 'single': 'min', + 'complete': 'max' +}; +var setOptions$1 = function setOptions(options) { + var opts = defaults$a(options); + var preferredAlias = linkageAliases[opts.linkage]; + if (preferredAlias != null) { + opts.linkage = preferredAlias; + } + return opts; +}; +var mergeClosest = function mergeClosest(clusters, index, dists, mins, opts) { + // Find two closest clusters from cached mins + var minKey = 0; + var min = Infinity; + var dist; + var attrs = opts.attributes; + var getDist = function getDist(n1, n2) { + return clusteringDistance(opts.distance, attrs.length, function (i) { + return attrs[i](n1); + }, function (i) { + return attrs[i](n2); + }, n1, n2); + }; + for (var i = 0; i < clusters.length; i++) { + var key = clusters[i].key; + var _dist = dists[key][mins[key]]; + if (_dist < min) { + minKey = key; + min = _dist; + } + } + if (opts.mode === 'threshold' && min >= opts.threshold || opts.mode === 'dendrogram' && clusters.length === 1) { + return false; + } + var c1 = index[minKey]; + var c2 = index[mins[minKey]]; + var merged; + + // Merge two closest clusters + if (opts.mode === 'dendrogram') { + merged = { + left: c1, + right: c2, + key: c1.key + }; + } else { + merged = { + value: c1.value.concat(c2.value), + key: c1.key + }; + } + clusters[c1.index] = merged; + clusters.splice(c2.index, 1); + index[c1.key] = merged; + + // Update distances with new merged cluster + for (var _i = 0; _i < clusters.length; _i++) { + var cur = clusters[_i]; + if (c1.key === cur.key) { + dist = Infinity; + } else if (opts.linkage === 'min') { + dist = dists[c1.key][cur.key]; + if (dists[c1.key][cur.key] > dists[c2.key][cur.key]) { + dist = dists[c2.key][cur.key]; + } + } else if (opts.linkage === 'max') { + dist = dists[c1.key][cur.key]; + if (dists[c1.key][cur.key] < dists[c2.key][cur.key]) { + dist = dists[c2.key][cur.key]; + } + } else if (opts.linkage === 'mean') { + dist = (dists[c1.key][cur.key] * c1.size + dists[c2.key][cur.key] * c2.size) / (c1.size + c2.size); + } else { + if (opts.mode === 'dendrogram') dist = getDist(cur.value, c1.value);else dist = getDist(cur.value[0], c1.value[0]); + } + dists[c1.key][cur.key] = dists[cur.key][c1.key] = dist; // distance matrix is symmetric + } + + // Update cached mins + for (var _i2 = 0; _i2 < clusters.length; _i2++) { + var key1 = clusters[_i2].key; + if (mins[key1] === c1.key || mins[key1] === c2.key) { + var _min = key1; + for (var j = 0; j < clusters.length; j++) { + var key2 = clusters[j].key; + if (dists[key1][key2] < dists[key1][_min]) { + _min = key2; + } + } + mins[key1] = _min; + } + clusters[_i2].index = _i2; + } + + // Clean up meta data used for clustering + c1.key = c2.key = c1.index = c2.index = null; + return true; +}; +var getAllChildren = function getAllChildren(root, arr, cy) { + if (!root) return; + if (root.value) { + arr.push(root.value); + } else { + if (root.left) getAllChildren(root.left, arr); + if (root.right) getAllChildren(root.right, arr); + } +}; +var buildDendrogram = function buildDendrogram(root, cy) { + if (!root) return ''; + if (root.left && root.right) { + var leftStr = buildDendrogram(root.left, cy); + var rightStr = buildDendrogram(root.right, cy); + var node = cy.add({ + group: 'nodes', + data: { + id: leftStr + ',' + rightStr + } + }); + cy.add({ + group: 'edges', + data: { + source: leftStr, + target: node.id() + } + }); + cy.add({ + group: 'edges', + data: { + source: rightStr, + target: node.id() + } + }); + return node.id(); + } else if (root.value) { + return root.value.id(); + } +}; +var buildClustersFromTree = function buildClustersFromTree(root, k, cy) { + if (!root) return []; + var left = [], + right = [], + leaves = []; + if (k === 0) { + // don't cut tree, simply return all nodes as 1 single cluster + if (root.left) getAllChildren(root.left, left); + if (root.right) getAllChildren(root.right, right); + leaves = left.concat(right); + return [cy.collection(leaves)]; + } else if (k === 1) { + // cut at root + + if (root.value) { + // leaf node + return [cy.collection(root.value)]; + } else { + if (root.left) getAllChildren(root.left, left); + if (root.right) getAllChildren(root.right, right); + return [cy.collection(left), cy.collection(right)]; + } + } else { + if (root.value) { + return [cy.collection(root.value)]; + } else { + if (root.left) left = buildClustersFromTree(root.left, k - 1, cy); + if (root.right) right = buildClustersFromTree(root.right, k - 1, cy); + return left.concat(right); + } + } +}; + +var hierarchicalClustering = function hierarchicalClustering(options) { + var cy = this.cy(); + var nodes = this.nodes(); + + // Set parameters of algorithm: linkage type, distance metric, etc. + var opts = setOptions$1(options); + var attrs = opts.attributes; + var getDist = function getDist(n1, n2) { + return clusteringDistance(opts.distance, attrs.length, function (i) { + return attrs[i](n1); + }, function (i) { + return attrs[i](n2); + }, n1, n2); + }; + + // Begin hierarchical algorithm + var clusters = []; + var dists = []; // distances between each pair of clusters + var mins = []; // closest cluster for each cluster + var index = []; // hash of all clusters by key + + // In agglomerative (bottom-up) clustering, each node starts as its own cluster + for (var n = 0; n < nodes.length; n++) { + var cluster = { + value: opts.mode === 'dendrogram' ? nodes[n] : [nodes[n]], + key: n, + index: n + }; + clusters[n] = cluster; + index[n] = cluster; + dists[n] = []; + mins[n] = 0; + } + + // Calculate the distance between each pair of clusters + for (var i = 0; i < clusters.length; i++) { + for (var j = 0; j <= i; j++) { + var dist = void 0; + if (opts.mode === 'dendrogram') { + // modes store cluster values differently + dist = i === j ? Infinity : getDist(clusters[i].value, clusters[j].value); + } else { + dist = i === j ? Infinity : getDist(clusters[i].value[0], clusters[j].value[0]); + } + dists[i][j] = dist; + dists[j][i] = dist; + if (dist < dists[i][mins[i]]) { + mins[i] = j; // Cache mins: closest cluster to cluster i is cluster j + } + } + } + + // Find the closest pair of clusters and merge them into a single cluster. + // Update distances between new cluster and each of the old clusters, and loop until threshold reached. + var merged = mergeClosest(clusters, index, dists, mins, opts); + while (merged) { + merged = mergeClosest(clusters, index, dists, mins, opts); + } + var retClusters; + + // Dendrogram mode builds the hierarchy and adds intermediary nodes + edges + // in addition to returning the clusters. + if (opts.mode === 'dendrogram') { + retClusters = buildClustersFromTree(clusters[0], opts.dendrogramDepth, cy); + if (opts.addDendrogram) buildDendrogram(clusters[0], cy); + } else { + // Regular mode simply returns the clusters + + retClusters = new Array(clusters.length); + clusters.forEach(function (cluster, i) { + // Clean up meta data used for clustering + cluster.key = cluster.index = null; + retClusters[i] = cy.collection(cluster.value); + }); + } + return retClusters; +}; +var hierarchicalClustering$1 = { + hierarchicalClustering: hierarchicalClustering, + hca: hierarchicalClustering +}; + +// Implemented by Zoe Xi @zoexi for GSOC 2016 +var defaults$9 = defaults$g({ + distance: 'euclidean', + // distance metric to compare attributes between two nodes + preference: 'median', + // suitability of a data point to serve as an exemplar + damping: 0.8, + // damping factor between [0.5, 1) + maxIterations: 1000, + // max number of iterations to run + minIterations: 100, + // min number of iterations to run in order for clustering to stop + attributes: [// functions to quantify the similarity between any two points + // e.g. node => node.data('weight') + ] +}); +var setOptions = function setOptions(options) { + var dmp = options.damping; + var pref = options.preference; + if (!(0.5 <= dmp && dmp < 1)) { + error("Damping must range on [0.5, 1). Got: ".concat(dmp)); + } + var validPrefs = ['median', 'mean', 'min', 'max']; + if (!(validPrefs.some(function (v) { + return v === pref; + }) || number$1(pref))) { + error("Preference must be one of [".concat(validPrefs.map(function (p) { + return "'".concat(p, "'"); + }).join(', '), "] or a number. Got: ").concat(pref)); + } + return defaults$9(options); +}; + +var getSimilarity = function getSimilarity(type, n1, n2, attributes) { + var attr = function attr(n, i) { + return attributes[i](n); + }; + + // nb negative because similarity should have an inverse relationship to distance + return -clusteringDistance(type, attributes.length, function (i) { + return attr(n1, i); + }, function (i) { + return attr(n2, i); + }, n1, n2); +}; +var getPreference = function getPreference(S, preference) { + // larger preference = greater # of clusters + var p = null; + if (preference === 'median') { + p = median(S); + } else if (preference === 'mean') { + p = mean(S); + } else if (preference === 'min') { + p = min(S); + } else if (preference === 'max') { + p = max(S); + } else { + // Custom preference number, as set by user + p = preference; + } + return p; +}; +var findExemplars = function findExemplars(n, R, A) { + var indices = []; + for (var i = 0; i < n; i++) { + if (R[i * n + i] + A[i * n + i] > 0) { + indices.push(i); + } + } + return indices; +}; +var assignClusters = function assignClusters(n, S, exemplars) { + var clusters = []; + for (var i = 0; i < n; i++) { + var index = -1; + var max = -Infinity; + for (var ei = 0; ei < exemplars.length; ei++) { + var e = exemplars[ei]; + if (S[i * n + e] > max) { + index = e; + max = S[i * n + e]; + } + } + if (index > 0) { + clusters.push(index); + } + } + for (var _ei = 0; _ei < exemplars.length; _ei++) { + clusters[exemplars[_ei]] = exemplars[_ei]; + } + return clusters; +}; +var assign = function assign(n, S, exemplars) { + var clusters = assignClusters(n, S, exemplars); + for (var ei = 0; ei < exemplars.length; ei++) { + var ii = []; + for (var c = 0; c < clusters.length; c++) { + if (clusters[c] === exemplars[ei]) { + ii.push(c); + } + } + var maxI = -1; + var maxSum = -Infinity; + for (var i = 0; i < ii.length; i++) { + var sum = 0; + for (var j = 0; j < ii.length; j++) { + sum += S[ii[j] * n + ii[i]]; + } + if (sum > maxSum) { + maxI = i; + maxSum = sum; + } + } + exemplars[ei] = ii[maxI]; + } + clusters = assignClusters(n, S, exemplars); + return clusters; +}; +var affinityPropagation = function affinityPropagation(options) { + var cy = this.cy(); + var nodes = this.nodes(); + var opts = setOptions(options); + + // Map each node to its position in node array + var id2position = {}; + for (var i = 0; i < nodes.length; i++) { + id2position[nodes[i].id()] = i; + } + + // Begin affinity propagation algorithm + + var n; // number of data points + var n2; // size of matrices + var S; // similarity matrix (1D array) + var p; // preference/suitability of a data point to serve as an exemplar + var R; // responsibility matrix (1D array) + var A; // availability matrix (1D array) + + n = nodes.length; + n2 = n * n; + + // Initialize and build S similarity matrix + S = new Array(n2); + for (var _i = 0; _i < n2; _i++) { + S[_i] = -Infinity; // for cases where two data points shouldn't be linked together + } + + for (var _i2 = 0; _i2 < n; _i2++) { + for (var j = 0; j < n; j++) { + if (_i2 !== j) { + S[_i2 * n + j] = getSimilarity(opts.distance, nodes[_i2], nodes[j], opts.attributes); + } + } + } + + // Place preferences on the diagonal of S + p = getPreference(S, opts.preference); + for (var _i3 = 0; _i3 < n; _i3++) { + S[_i3 * n + _i3] = p; + } + + // Initialize R responsibility matrix + R = new Array(n2); + for (var _i4 = 0; _i4 < n2; _i4++) { + R[_i4] = 0.0; + } + + // Initialize A availability matrix + A = new Array(n2); + for (var _i5 = 0; _i5 < n2; _i5++) { + A[_i5] = 0.0; + } + var old = new Array(n); + var Rp = new Array(n); + var se = new Array(n); + for (var _i6 = 0; _i6 < n; _i6++) { + old[_i6] = 0.0; + Rp[_i6] = 0.0; + se[_i6] = 0; + } + var e = new Array(n * opts.minIterations); + for (var _i7 = 0; _i7 < e.length; _i7++) { + e[_i7] = 0; + } + var iter; + for (iter = 0; iter < opts.maxIterations; iter++) { + // main algorithmic loop + + // Update R responsibility matrix + for (var _i8 = 0; _i8 < n; _i8++) { + var max = -Infinity, + max2 = -Infinity, + maxI = -1, + AS = 0.0; + for (var _j = 0; _j < n; _j++) { + old[_j] = R[_i8 * n + _j]; + AS = A[_i8 * n + _j] + S[_i8 * n + _j]; + if (AS >= max) { + max2 = max; + max = AS; + maxI = _j; + } else if (AS > max2) { + max2 = AS; + } + } + for (var _j2 = 0; _j2 < n; _j2++) { + R[_i8 * n + _j2] = (1 - opts.damping) * (S[_i8 * n + _j2] - max) + opts.damping * old[_j2]; + } + R[_i8 * n + maxI] = (1 - opts.damping) * (S[_i8 * n + maxI] - max2) + opts.damping * old[maxI]; + } + + // Update A availability matrix + for (var _i9 = 0; _i9 < n; _i9++) { + var sum = 0; + for (var _j3 = 0; _j3 < n; _j3++) { + old[_j3] = A[_j3 * n + _i9]; + Rp[_j3] = Math.max(0, R[_j3 * n + _i9]); + sum += Rp[_j3]; + } + sum -= Rp[_i9]; + Rp[_i9] = R[_i9 * n + _i9]; + sum += Rp[_i9]; + for (var _j4 = 0; _j4 < n; _j4++) { + A[_j4 * n + _i9] = (1 - opts.damping) * Math.min(0, sum - Rp[_j4]) + opts.damping * old[_j4]; + } + A[_i9 * n + _i9] = (1 - opts.damping) * (sum - Rp[_i9]) + opts.damping * old[_i9]; + } + + // Check for convergence + var K = 0; + for (var _i10 = 0; _i10 < n; _i10++) { + var E = A[_i10 * n + _i10] + R[_i10 * n + _i10] > 0 ? 1 : 0; + e[iter % opts.minIterations * n + _i10] = E; + K += E; + } + if (K > 0 && (iter >= opts.minIterations - 1 || iter == opts.maxIterations - 1)) { + var _sum = 0; + for (var _i11 = 0; _i11 < n; _i11++) { + se[_i11] = 0; + for (var _j5 = 0; _j5 < opts.minIterations; _j5++) { + se[_i11] += e[_j5 * n + _i11]; + } + if (se[_i11] === 0 || se[_i11] === opts.minIterations) { + _sum++; + } + } + if (_sum === n) { + // then we have convergence + break; + } + } + } + + // Identify exemplars (cluster centers) + var exemplarsIndices = findExemplars(n, R, A); + + // Assign nodes to clusters + var clusterIndices = assign(n, S, exemplarsIndices); + var clusters = {}; + for (var c = 0; c < exemplarsIndices.length; c++) { + clusters[exemplarsIndices[c]] = []; + } + for (var _i12 = 0; _i12 < nodes.length; _i12++) { + var pos = id2position[nodes[_i12].id()]; + var clusterIndex = clusterIndices[pos]; + if (clusterIndex != null) { + // the node may have not been assigned a cluster if no valid attributes were specified + clusters[clusterIndex].push(nodes[_i12]); + } + } + var retClusters = new Array(exemplarsIndices.length); + for (var _c = 0; _c < exemplarsIndices.length; _c++) { + retClusters[_c] = cy.collection(clusters[exemplarsIndices[_c]]); + } + return retClusters; +}; +var affinityPropagation$1 = { + affinityPropagation: affinityPropagation, + ap: affinityPropagation +}; + +var hierholzerDefaults = defaults$g({ + root: undefined, + directed: false +}); +var elesfn$k = { + hierholzer: function hierholzer(options) { + if (!plainObject(options)) { + var args = arguments; + options = { + root: args[0], + directed: args[1] + }; + } + var _hierholzerDefaults = hierholzerDefaults(options), + root = _hierholzerDefaults.root, + directed = _hierholzerDefaults.directed; + var eles = this; + var dflag = false; + var oddIn; + var oddOut; + var startVertex; + if (root) startVertex = string(root) ? this.filter(root)[0].id() : root[0].id(); + var nodes = {}; + var edges = {}; + if (directed) { + eles.forEach(function (ele) { + var id = ele.id(); + if (ele.isNode()) { + var ind = ele.indegree(true); + var outd = ele.outdegree(true); + var d1 = ind - outd; + var d2 = outd - ind; + if (d1 == 1) { + if (oddIn) dflag = true;else oddIn = id; + } else if (d2 == 1) { + if (oddOut) dflag = true;else oddOut = id; + } else if (d2 > 1 || d1 > 1) { + dflag = true; + } + nodes[id] = []; + ele.outgoers().forEach(function (e) { + if (e.isEdge()) nodes[id].push(e.id()); + }); + } else { + edges[id] = [undefined, ele.target().id()]; + } + }); + } else { + eles.forEach(function (ele) { + var id = ele.id(); + if (ele.isNode()) { + var d = ele.degree(true); + if (d % 2) { + if (!oddIn) oddIn = id;else if (!oddOut) oddOut = id;else dflag = true; + } + nodes[id] = []; + ele.connectedEdges().forEach(function (e) { + return nodes[id].push(e.id()); + }); + } else { + edges[id] = [ele.source().id(), ele.target().id()]; + } + }); + } + var result = { + found: false, + trail: undefined + }; + if (dflag) return result;else if (oddOut && oddIn) { + if (directed) { + if (startVertex && oddOut != startVertex) { + return result; + } + startVertex = oddOut; + } else { + if (startVertex && oddOut != startVertex && oddIn != startVertex) { + return result; + } else if (!startVertex) { + startVertex = oddOut; + } + } + } else { + if (!startVertex) startVertex = eles[0].id(); + } + var walk = function walk(v) { + var currentNode = v; + var subtour = [v]; + var adj, adjTail, adjHead; + while (nodes[currentNode].length) { + adj = nodes[currentNode].shift(); + adjTail = edges[adj][0]; + adjHead = edges[adj][1]; + if (currentNode != adjHead) { + nodes[adjHead] = nodes[adjHead].filter(function (e) { + return e != adj; + }); + currentNode = adjHead; + } else if (!directed && currentNode != adjTail) { + nodes[adjTail] = nodes[adjTail].filter(function (e) { + return e != adj; + }); + currentNode = adjTail; + } + subtour.unshift(adj); + subtour.unshift(currentNode); + } + return subtour; + }; + var trail = []; + var subtour = []; + subtour = walk(startVertex); + while (subtour.length != 1) { + if (nodes[subtour[0]].length == 0) { + trail.unshift(eles.getElementById(subtour.shift())); + trail.unshift(eles.getElementById(subtour.shift())); + } else { + subtour = walk(subtour.shift()).concat(subtour); + } + } + trail.unshift(eles.getElementById(subtour.shift())); // final node + + for (var d in nodes) { + if (nodes[d].length) { + return result; + } + } + result.found = true; + result.trail = this.spawn(trail, true); + return result; + } +}; + +var hopcroftTarjanBiconnected = function hopcroftTarjanBiconnected() { + var eles = this; + var nodes = {}; + var id = 0; + var edgeCount = 0; + var components = []; + var stack = []; + var visitedEdges = {}; + var buildComponent = function buildComponent(x, y) { + var i = stack.length - 1; + var cutset = []; + var component = eles.spawn(); + while (stack[i].x != x || stack[i].y != y) { + cutset.push(stack.pop().edge); + i--; + } + cutset.push(stack.pop().edge); + cutset.forEach(function (edge) { + var connectedNodes = edge.connectedNodes().intersection(eles); + component.merge(edge); + connectedNodes.forEach(function (node) { + var nodeId = node.id(); + var connectedEdges = node.connectedEdges().intersection(eles); + component.merge(node); + if (!nodes[nodeId].cutVertex) { + component.merge(connectedEdges); + } else { + component.merge(connectedEdges.filter(function (edge) { + return edge.isLoop(); + })); + } + }); + }); + components.push(component); + }; + var biconnectedSearch = function biconnectedSearch(root, currentNode, parent) { + if (root === parent) edgeCount += 1; + nodes[currentNode] = { + id: id, + low: id++, + cutVertex: false + }; + var edges = eles.getElementById(currentNode).connectedEdges().intersection(eles); + if (edges.size() === 0) { + components.push(eles.spawn(eles.getElementById(currentNode))); + } else { + var sourceId, targetId, otherNodeId, edgeId; + edges.forEach(function (edge) { + sourceId = edge.source().id(); + targetId = edge.target().id(); + otherNodeId = sourceId === currentNode ? targetId : sourceId; + if (otherNodeId !== parent) { + edgeId = edge.id(); + if (!visitedEdges[edgeId]) { + visitedEdges[edgeId] = true; + stack.push({ + x: currentNode, + y: otherNodeId, + edge: edge + }); + } + if (!(otherNodeId in nodes)) { + biconnectedSearch(root, otherNodeId, currentNode); + nodes[currentNode].low = Math.min(nodes[currentNode].low, nodes[otherNodeId].low); + if (nodes[currentNode].id <= nodes[otherNodeId].low) { + nodes[currentNode].cutVertex = true; + buildComponent(currentNode, otherNodeId); + } + } else { + nodes[currentNode].low = Math.min(nodes[currentNode].low, nodes[otherNodeId].id); + } + } + }); + } + }; + eles.forEach(function (ele) { + if (ele.isNode()) { + var nodeId = ele.id(); + if (!(nodeId in nodes)) { + edgeCount = 0; + biconnectedSearch(nodeId, nodeId); + nodes[nodeId].cutVertex = edgeCount > 1; + } + } + }); + var cutVertices = Object.keys(nodes).filter(function (id) { + return nodes[id].cutVertex; + }).map(function (id) { + return eles.getElementById(id); + }); + return { + cut: eles.spawn(cutVertices), + components: components + }; +}; +var hopcroftTarjanBiconnected$1 = { + hopcroftTarjanBiconnected: hopcroftTarjanBiconnected, + htbc: hopcroftTarjanBiconnected, + htb: hopcroftTarjanBiconnected, + hopcroftTarjanBiconnectedComponents: hopcroftTarjanBiconnected +}; + +var tarjanStronglyConnected = function tarjanStronglyConnected() { + var eles = this; + var nodes = {}; + var index = 0; + var components = []; + var stack = []; + var cut = eles.spawn(eles); + var stronglyConnectedSearch = function stronglyConnectedSearch(sourceNodeId) { + stack.push(sourceNodeId); + nodes[sourceNodeId] = { + index: index, + low: index++, + explored: false + }; + var connectedEdges = eles.getElementById(sourceNodeId).connectedEdges().intersection(eles); + connectedEdges.forEach(function (edge) { + var targetNodeId = edge.target().id(); + if (targetNodeId !== sourceNodeId) { + if (!(targetNodeId in nodes)) { + stronglyConnectedSearch(targetNodeId); + } + if (!nodes[targetNodeId].explored) { + nodes[sourceNodeId].low = Math.min(nodes[sourceNodeId].low, nodes[targetNodeId].low); + } + } + }); + if (nodes[sourceNodeId].index === nodes[sourceNodeId].low) { + var componentNodes = eles.spawn(); + for (;;) { + var nodeId = stack.pop(); + componentNodes.merge(eles.getElementById(nodeId)); + nodes[nodeId].low = nodes[sourceNodeId].index; + nodes[nodeId].explored = true; + if (nodeId === sourceNodeId) { + break; + } + } + var componentEdges = componentNodes.edgesWith(componentNodes); + var component = componentNodes.merge(componentEdges); + components.push(component); + cut = cut.difference(component); + } + }; + eles.forEach(function (ele) { + if (ele.isNode()) { + var nodeId = ele.id(); + if (!(nodeId in nodes)) { + stronglyConnectedSearch(nodeId); + } + } + }); + return { + cut: cut, + components: components + }; +}; +var tarjanStronglyConnected$1 = { + tarjanStronglyConnected: tarjanStronglyConnected, + tsc: tarjanStronglyConnected, + tscc: tarjanStronglyConnected, + tarjanStronglyConnectedComponents: tarjanStronglyConnected +}; + +var elesfn$j = {}; +[elesfn$v, elesfn$u, elesfn$t, elesfn$s, elesfn$r, elesfn$q, elesfn$p, elesfn$o, elesfn$n, elesfn$m, elesfn$l, markovClustering$1, kClustering, hierarchicalClustering$1, affinityPropagation$1, elesfn$k, hopcroftTarjanBiconnected$1, tarjanStronglyConnected$1].forEach(function (props) { + extend(elesfn$j, props); +}); + +/*! +Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable +Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com) +Licensed under The MIT License (http://opensource.org/licenses/MIT) +*/ + +/* promise states [Promises/A+ 2.1] */ +var STATE_PENDING = 0; /* [Promises/A+ 2.1.1] */ +var STATE_FULFILLED = 1; /* [Promises/A+ 2.1.2] */ +var STATE_REJECTED = 2; /* [Promises/A+ 2.1.3] */ + +/* promise object constructor */ +var api = function api(executor) { + /* optionally support non-constructor/plain-function call */ + if (!(this instanceof api)) return new api(executor); + + /* initialize object */ + this.id = 'Thenable/1.0.7'; + this.state = STATE_PENDING; /* initial state */ + this.fulfillValue = undefined; /* initial value */ /* [Promises/A+ 1.3, 2.1.2.2] */ + this.rejectReason = undefined; /* initial reason */ /* [Promises/A+ 1.5, 2.1.3.2] */ + this.onFulfilled = []; /* initial handlers */ + this.onRejected = []; /* initial handlers */ + + /* provide optional information-hiding proxy */ + this.proxy = { + then: this.then.bind(this) + }; + + /* support optional executor function */ + if (typeof executor === 'function') executor.call(this, this.fulfill.bind(this), this.reject.bind(this)); +}; + +/* promise API methods */ +api.prototype = { + /* promise resolving methods */ + fulfill: function fulfill(value) { + return deliver(this, STATE_FULFILLED, 'fulfillValue', value); + }, + reject: function reject(value) { + return deliver(this, STATE_REJECTED, 'rejectReason', value); + }, + /* "The then Method" [Promises/A+ 1.1, 1.2, 2.2] */ + then: function then(onFulfilled, onRejected) { + var curr = this; + var next = new api(); /* [Promises/A+ 2.2.7] */ + curr.onFulfilled.push(resolver(onFulfilled, next, 'fulfill')); /* [Promises/A+ 2.2.2/2.2.6] */ + curr.onRejected.push(resolver(onRejected, next, 'reject')); /* [Promises/A+ 2.2.3/2.2.6] */ + execute(curr); + return next.proxy; /* [Promises/A+ 2.2.7, 3.3] */ + } +}; + +/* deliver an action */ +var deliver = function deliver(curr, state, name, value) { + if (curr.state === STATE_PENDING) { + curr.state = state; /* [Promises/A+ 2.1.2.1, 2.1.3.1] */ + curr[name] = value; /* [Promises/A+ 2.1.2.2, 2.1.3.2] */ + execute(curr); + } + return curr; +}; + +/* execute all handlers */ +var execute = function execute(curr) { + if (curr.state === STATE_FULFILLED) execute_handlers(curr, 'onFulfilled', curr.fulfillValue);else if (curr.state === STATE_REJECTED) execute_handlers(curr, 'onRejected', curr.rejectReason); +}; + +/* execute particular set of handlers */ +var execute_handlers = function execute_handlers(curr, name, value) { + /* global setImmediate: true */ + /* global setTimeout: true */ + + /* short-circuit processing */ + if (curr[name].length === 0) return; + + /* iterate over all handlers, exactly once */ + var handlers = curr[name]; + curr[name] = []; /* [Promises/A+ 2.2.2.3, 2.2.3.3] */ + var func = function func() { + for (var i = 0; i < handlers.length; i++) { + handlers[i](value); + } /* [Promises/A+ 2.2.5] */ + }; + + /* execute procedure asynchronously */ /* [Promises/A+ 2.2.4, 3.1] */ + if (typeof setImmediate === 'function') setImmediate(func);else setTimeout(func, 0); +}; + +/* generate a resolver function */ +var resolver = function resolver(cb, next, method) { + return function (value) { + if (typeof cb !== 'function') /* [Promises/A+ 2.2.1, 2.2.7.3, 2.2.7.4] */ + next[method].call(next, value); /* [Promises/A+ 2.2.7.3, 2.2.7.4] */else { + var result; + try { + result = cb(value); + } /* [Promises/A+ 2.2.2.1, 2.2.3.1, 2.2.5, 3.2] */ catch (e) { + next.reject(e); /* [Promises/A+ 2.2.7.2] */ + return; + } + resolve(next, result); /* [Promises/A+ 2.2.7.1] */ + } + }; +}; + +/* "Promise Resolution Procedure" */ /* [Promises/A+ 2.3] */ +var resolve = function resolve(promise, x) { + /* sanity check arguments */ /* [Promises/A+ 2.3.1] */ + if (promise === x || promise.proxy === x) { + promise.reject(new TypeError('cannot resolve promise with itself')); + return; + } + + /* surgically check for a "then" method + (mainly to just call the "getter" of "then" only once) */ + var then; + if (_typeof(x) === 'object' && x !== null || typeof x === 'function') { + try { + then = x.then; + } /* [Promises/A+ 2.3.3.1, 3.5] */ catch (e) { + promise.reject(e); /* [Promises/A+ 2.3.3.2] */ + return; + } + } + + /* handle own Thenables [Promises/A+ 2.3.2] + and similar "thenables" [Promises/A+ 2.3.3] */ + if (typeof then === 'function') { + var resolved = false; + try { + /* call retrieved "then" method */ /* [Promises/A+ 2.3.3.3] */ + then.call(x, /* resolvePromise */ /* [Promises/A+ 2.3.3.3.1] */ + function (y) { + if (resolved) return; + resolved = true; /* [Promises/A+ 2.3.3.3.3] */ + if (y === x) /* [Promises/A+ 3.6] */ + promise.reject(new TypeError('circular thenable chain'));else resolve(promise, y); + }, /* rejectPromise */ /* [Promises/A+ 2.3.3.3.2] */ + function (r) { + if (resolved) return; + resolved = true; /* [Promises/A+ 2.3.3.3.3] */ + promise.reject(r); + }); + } catch (e) { + if (!resolved) /* [Promises/A+ 2.3.3.3.3] */ + promise.reject(e); /* [Promises/A+ 2.3.3.3.4] */ + } + + return; + } + + /* handle other values */ + promise.fulfill(x); /* [Promises/A+ 2.3.4, 2.3.3.4] */ +}; + +// so we always have Promise.all() +api.all = function (ps) { + return new api(function (resolveAll, rejectAll) { + var vals = new Array(ps.length); + var doneCount = 0; + var fulfill = function fulfill(i, val) { + vals[i] = val; + doneCount++; + if (doneCount === ps.length) { + resolveAll(vals); + } + }; + for (var i = 0; i < ps.length; i++) { + (function (i) { + var p = ps[i]; + var isPromise = p != null && p.then != null; + if (isPromise) { + p.then(function (val) { + fulfill(i, val); + }, function (err) { + rejectAll(err); + }); + } else { + var val = p; + fulfill(i, val); + } + })(i); + } + }); +}; +api.resolve = function (val) { + return new api(function (resolve, reject) { + resolve(val); + }); +}; +api.reject = function (val) { + return new api(function (resolve, reject) { + reject(val); + }); +}; +var Promise$1 = typeof Promise !== 'undefined' ? Promise : api; // eslint-disable-line no-undef + +var Animation = function Animation(target, opts, opts2) { + var isCore = core(target); + var isEle = !isCore; + var _p = this._private = extend({ + duration: 1000 + }, opts, opts2); + _p.target = target; + _p.style = _p.style || _p.css; + _p.started = false; + _p.playing = false; + _p.hooked = false; + _p.applying = false; + _p.progress = 0; + _p.completes = []; + _p.frames = []; + if (_p.complete && fn$6(_p.complete)) { + _p.completes.push(_p.complete); + } + if (isEle) { + var pos = target.position(); + _p.startPosition = _p.startPosition || { + x: pos.x, + y: pos.y + }; + _p.startStyle = _p.startStyle || target.cy().style().getAnimationStartStyle(target, _p.style); + } + if (isCore) { + var pan = target.pan(); + _p.startPan = { + x: pan.x, + y: pan.y + }; + _p.startZoom = target.zoom(); + } + + // for future timeline/animations impl + this.length = 1; + this[0] = this; +}; +var anifn = Animation.prototype; +extend(anifn, { + instanceString: function instanceString() { + return 'animation'; + }, + hook: function hook() { + var _p = this._private; + if (!_p.hooked) { + // add to target's animation queue + var q; + var tAni = _p.target._private.animation; + if (_p.queue) { + q = tAni.queue; + } else { + q = tAni.current; + } + q.push(this); + + // add to the animation loop pool + if (elementOrCollection(_p.target)) { + _p.target.cy().addToAnimationPool(_p.target); + } + _p.hooked = true; + } + return this; + }, + play: function play() { + var _p = this._private; + + // autorewind + if (_p.progress === 1) { + _p.progress = 0; + } + _p.playing = true; + _p.started = false; // needs to be started by animation loop + _p.stopped = false; + this.hook(); + + // the animation loop will start the animation... + + return this; + }, + playing: function playing() { + return this._private.playing; + }, + apply: function apply() { + var _p = this._private; + _p.applying = true; + _p.started = false; // needs to be started by animation loop + _p.stopped = false; + this.hook(); + + // the animation loop will apply the animation at this progress + + return this; + }, + applying: function applying() { + return this._private.applying; + }, + pause: function pause() { + var _p = this._private; + _p.playing = false; + _p.started = false; + return this; + }, + stop: function stop() { + var _p = this._private; + _p.playing = false; + _p.started = false; + _p.stopped = true; // to be removed from animation queues + + return this; + }, + rewind: function rewind() { + return this.progress(0); + }, + fastforward: function fastforward() { + return this.progress(1); + }, + time: function time(t) { + var _p = this._private; + if (t === undefined) { + return _p.progress * _p.duration; + } else { + return this.progress(t / _p.duration); + } + }, + progress: function progress(p) { + var _p = this._private; + var wasPlaying = _p.playing; + if (p === undefined) { + return _p.progress; + } else { + if (wasPlaying) { + this.pause(); + } + _p.progress = p; + _p.started = false; + if (wasPlaying) { + this.play(); + } + } + return this; + }, + completed: function completed() { + return this._private.progress === 1; + }, + reverse: function reverse() { + var _p = this._private; + var wasPlaying = _p.playing; + if (wasPlaying) { + this.pause(); + } + _p.progress = 1 - _p.progress; + _p.started = false; + var swap = function swap(a, b) { + var _pa = _p[a]; + if (_pa == null) { + return; + } + _p[a] = _p[b]; + _p[b] = _pa; + }; + swap('zoom', 'startZoom'); + swap('pan', 'startPan'); + swap('position', 'startPosition'); + + // swap styles + if (_p.style) { + for (var i = 0; i < _p.style.length; i++) { + var prop = _p.style[i]; + var name = prop.name; + var startStyleProp = _p.startStyle[name]; + _p.startStyle[name] = prop; + _p.style[i] = startStyleProp; + } + } + if (wasPlaying) { + this.play(); + } + return this; + }, + promise: function promise(type) { + var _p = this._private; + var arr; + switch (type) { + case 'frame': + arr = _p.frames; + break; + default: + case 'complete': + case 'completed': + arr = _p.completes; + } + return new Promise$1(function (resolve, reject) { + arr.push(function () { + resolve(); + }); + }); + } +}); +anifn.complete = anifn.completed; +anifn.run = anifn.play; +anifn.running = anifn.playing; + +var define$3 = { + animated: function animated() { + return function animatedImpl() { + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var cy = this._private.cy || this; + if (!cy.styleEnabled()) { + return false; + } + var ele = all[0]; + if (ele) { + return ele._private.animation.current.length > 0; + } + }; + }, + // animated + + clearQueue: function clearQueue() { + return function clearQueueImpl() { + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var cy = this._private.cy || this; + if (!cy.styleEnabled()) { + return this; + } + for (var i = 0; i < all.length; i++) { + var ele = all[i]; + ele._private.animation.queue = []; + } + return this; + }; + }, + // clearQueue + + delay: function delay() { + return function delayImpl(time, complete) { + var cy = this._private.cy || this; + if (!cy.styleEnabled()) { + return this; + } + return this.animate({ + delay: time, + duration: time, + complete: complete + }); + }; + }, + // delay + + delayAnimation: function delayAnimation() { + return function delayAnimationImpl(time, complete) { + var cy = this._private.cy || this; + if (!cy.styleEnabled()) { + return this; + } + return this.animation({ + delay: time, + duration: time, + complete: complete + }); + }; + }, + // delay + + animation: function animation() { + return function animationImpl(properties, params) { + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var cy = this._private.cy || this; + var isCore = !selfIsArrayLike; + var isEles = !isCore; + if (!cy.styleEnabled()) { + return this; + } + var style = cy.style(); + properties = extend({}, properties, params); + var propertiesEmpty = Object.keys(properties).length === 0; + if (propertiesEmpty) { + return new Animation(all[0], properties); // nothing to animate + } + + if (properties.duration === undefined) { + properties.duration = 400; + } + switch (properties.duration) { + case 'slow': + properties.duration = 600; + break; + case 'fast': + properties.duration = 200; + break; + } + if (isEles) { + properties.style = style.getPropsList(properties.style || properties.css); + properties.css = undefined; + } + if (isEles && properties.renderedPosition != null) { + var rpos = properties.renderedPosition; + var pan = cy.pan(); + var zoom = cy.zoom(); + properties.position = renderedToModelPosition(rpos, zoom, pan); + } + + // override pan w/ panBy if set + if (isCore && properties.panBy != null) { + var panBy = properties.panBy; + var cyPan = cy.pan(); + properties.pan = { + x: cyPan.x + panBy.x, + y: cyPan.y + panBy.y + }; + } + + // override pan w/ center if set + var center = properties.center || properties.centre; + if (isCore && center != null) { + var centerPan = cy.getCenterPan(center.eles, properties.zoom); + if (centerPan != null) { + properties.pan = centerPan; + } + } + + // override pan & zoom w/ fit if set + if (isCore && properties.fit != null) { + var fit = properties.fit; + var fitVp = cy.getFitViewport(fit.eles || fit.boundingBox, fit.padding); + if (fitVp != null) { + properties.pan = fitVp.pan; + properties.zoom = fitVp.zoom; + } + } + + // override zoom (& potentially pan) w/ zoom obj if set + if (isCore && plainObject(properties.zoom)) { + var vp = cy.getZoomedViewport(properties.zoom); + if (vp != null) { + if (vp.zoomed) { + properties.zoom = vp.zoom; + } + if (vp.panned) { + properties.pan = vp.pan; + } + } else { + properties.zoom = null; // an inavalid zoom (e.g. no delta) gets automatically destroyed + } + } + + return new Animation(all[0], properties); + }; + }, + // animate + + animate: function animate() { + return function animateImpl(properties, params) { + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var cy = this._private.cy || this; + if (!cy.styleEnabled()) { + return this; + } + if (params) { + properties = extend({}, properties, params); + } + + // manually hook and run the animation + for (var i = 0; i < all.length; i++) { + var ele = all[i]; + var queue = ele.animated() && (properties.queue === undefined || properties.queue); + var ani = ele.animation(properties, queue ? { + queue: true + } : undefined); + ani.play(); + } + return this; // chaining + }; + }, + + // animate + + stop: function stop() { + return function stopImpl(clearQueue, jumpToEnd) { + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var cy = this._private.cy || this; + if (!cy.styleEnabled()) { + return this; + } + for (var i = 0; i < all.length; i++) { + var ele = all[i]; + var _p = ele._private; + var anis = _p.animation.current; + for (var j = 0; j < anis.length; j++) { + var ani = anis[j]; + var ani_p = ani._private; + if (jumpToEnd) { + // next iteration of the animation loop, the animation + // will go straight to the end and be removed + ani_p.duration = 0; + } + } + + // clear the queue of future animations + if (clearQueue) { + _p.animation.queue = []; + } + if (!jumpToEnd) { + _p.animation.current = []; + } + } + + // we have to notify (the animation loop doesn't do it for us on `stop`) + cy.notify('draw'); + return this; + }; + } // stop +}; // define + +var define$2 = { + // access data field + data: function data(params) { + var defaults = { + field: 'data', + bindingEvent: 'data', + allowBinding: false, + allowSetting: false, + allowGetting: false, + settingEvent: 'data', + settingTriggersEvent: false, + triggerFnName: 'trigger', + immutableKeys: {}, + // key => true if immutable + updateStyle: false, + beforeGet: function beforeGet(self) {}, + beforeSet: function beforeSet(self, obj) {}, + onSet: function onSet(self) {}, + canSet: function canSet(self) { + return true; + } + }; + params = extend({}, defaults, params); + return function dataImpl(name, value) { + var p = params; + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var single = selfIsArrayLike ? self[0] : self; + + // .data('foo', ...) + if (string(name)) { + // set or get property + var isPathLike = name.indexOf('.') !== -1; // there might be a normal field with a dot + var path = isPathLike && toPath__default["default"](name); + + // .data('foo') + if (p.allowGetting && value === undefined) { + // get + + var ret; + if (single) { + p.beforeGet(single); + + // check if it's path and a field with the same name doesn't exist + if (path && single._private[p.field][name] === undefined) { + ret = get__default["default"](single._private[p.field], path); + } else { + ret = single._private[p.field][name]; + } + } + return ret; + + // .data('foo', 'bar') + } else if (p.allowSetting && value !== undefined) { + // set + var valid = !p.immutableKeys[name]; + if (valid) { + var change = _defineProperty({}, name, value); + p.beforeSet(self, change); + for (var i = 0, l = all.length; i < l; i++) { + var ele = all[i]; + if (p.canSet(ele)) { + if (path && single._private[p.field][name] === undefined) { + set__default["default"](ele._private[p.field], path, value); + } else { + ele._private[p.field][name] = value; + } + } + } + + // update mappers if asked + if (p.updateStyle) { + self.updateStyle(); + } + + // call onSet callback + p.onSet(self); + if (p.settingTriggersEvent) { + self[p.triggerFnName](p.settingEvent); + } + } + } + + // .data({ 'foo': 'bar' }) + } else if (p.allowSetting && plainObject(name)) { + // extend + var obj = name; + var k, v; + var keys = Object.keys(obj); + p.beforeSet(self, obj); + for (var _i = 0; _i < keys.length; _i++) { + k = keys[_i]; + v = obj[k]; + var _valid = !p.immutableKeys[k]; + if (_valid) { + for (var j = 0; j < all.length; j++) { + var _ele = all[j]; + if (p.canSet(_ele)) { + _ele._private[p.field][k] = v; + } + } + } + } + + // update mappers if asked + if (p.updateStyle) { + self.updateStyle(); + } + + // call onSet callback + p.onSet(self); + if (p.settingTriggersEvent) { + self[p.triggerFnName](p.settingEvent); + } + + // .data(function(){ ... }) + } else if (p.allowBinding && fn$6(name)) { + // bind to event + var fn = name; + self.on(p.bindingEvent, fn); + + // .data() + } else if (p.allowGetting && name === undefined) { + // get whole object + var _ret; + if (single) { + p.beforeGet(single); + _ret = single._private[p.field]; + } + return _ret; + } + return self; // maintain chainability + }; // function + }, + + // data + + // remove data field + removeData: function removeData(params) { + var defaults = { + field: 'data', + event: 'data', + triggerFnName: 'trigger', + triggerEvent: false, + immutableKeys: {} // key => true if immutable + }; + + params = extend({}, defaults, params); + return function removeDataImpl(names) { + var p = params; + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + + // .removeData('foo bar') + if (string(names)) { + // then get the list of keys, and delete them + var keys = names.split(/\s+/); + var l = keys.length; + for (var i = 0; i < l; i++) { + // delete each non-empty key + var key = keys[i]; + if (emptyString(key)) { + continue; + } + var valid = !p.immutableKeys[key]; // not valid if immutable + if (valid) { + for (var i_a = 0, l_a = all.length; i_a < l_a; i_a++) { + all[i_a]._private[p.field][key] = undefined; + } + } + } + if (p.triggerEvent) { + self[p.triggerFnName](p.event); + } + + // .removeData() + } else if (names === undefined) { + // then delete all keys + + for (var _i_a = 0, _l_a = all.length; _i_a < _l_a; _i_a++) { + var _privateFields = all[_i_a]._private[p.field]; + var _keys = Object.keys(_privateFields); + for (var _i2 = 0; _i2 < _keys.length; _i2++) { + var _key = _keys[_i2]; + var validKeyToDelete = !p.immutableKeys[_key]; + if (validKeyToDelete) { + _privateFields[_key] = undefined; + } + } + } + if (p.triggerEvent) { + self[p.triggerFnName](p.event); + } + } + return self; // maintain chaining + }; // function + } // removeData +}; // define + +var define$1 = { + eventAliasesOn: function eventAliasesOn(proto) { + var p = proto; + p.addListener = p.listen = p.bind = p.on; + p.unlisten = p.unbind = p.off = p.removeListener; + p.trigger = p.emit; + + // this is just a wrapper alias of .on() + p.pon = p.promiseOn = function (events, selector) { + var self = this; + var args = Array.prototype.slice.call(arguments, 0); + return new Promise$1(function (resolve, reject) { + var callback = function callback(e) { + self.off.apply(self, offArgs); + resolve(e); + }; + var onArgs = args.concat([callback]); + var offArgs = onArgs.concat([]); + self.on.apply(self, onArgs); + }); + }; + } +}; // define + +// use this module to cherry pick functions into your prototype +var define = {}; +[define$3, define$2, define$1].forEach(function (m) { + extend(define, m); +}); + +var elesfn$i = { + animate: define.animate(), + animation: define.animation(), + animated: define.animated(), + clearQueue: define.clearQueue(), + delay: define.delay(), + delayAnimation: define.delayAnimation(), + stop: define.stop() +}; + +var elesfn$h = { + classes: function classes(_classes) { + var self = this; + if (_classes === undefined) { + var ret = []; + self[0]._private.classes.forEach(function (cls) { + return ret.push(cls); + }); + return ret; + } else if (!array(_classes)) { + // extract classes from string + _classes = (_classes || '').match(/\S+/g) || []; + } + var changed = []; + var classesSet = new Set$1(_classes); + + // check and update each ele + for (var j = 0; j < self.length; j++) { + var ele = self[j]; + var _p = ele._private; + var eleClasses = _p.classes; + var changedEle = false; + + // check if ele has all of the passed classes + for (var i = 0; i < _classes.length; i++) { + var cls = _classes[i]; + var eleHasClass = eleClasses.has(cls); + if (!eleHasClass) { + changedEle = true; + break; + } + } + + // check if ele has classes outside of those passed + if (!changedEle) { + changedEle = eleClasses.size !== _classes.length; + } + if (changedEle) { + _p.classes = classesSet; + changed.push(ele); + } + } + + // trigger update style on those eles that had class changes + if (changed.length > 0) { + this.spawn(changed).updateStyle().emit('class'); + } + return self; + }, + addClass: function addClass(classes) { + return this.toggleClass(classes, true); + }, + hasClass: function hasClass(className) { + var ele = this[0]; + return ele != null && ele._private.classes.has(className); + }, + toggleClass: function toggleClass(classes, toggle) { + if (!array(classes)) { + // extract classes from string + classes = classes.match(/\S+/g) || []; + } + var self = this; + var toggleUndefd = toggle === undefined; + var changed = []; // eles who had classes changed + + for (var i = 0, il = self.length; i < il; i++) { + var ele = self[i]; + var eleClasses = ele._private.classes; + var changedEle = false; + for (var j = 0; j < classes.length; j++) { + var cls = classes[j]; + var hasClass = eleClasses.has(cls); + var changedNow = false; + if (toggle || toggleUndefd && !hasClass) { + eleClasses.add(cls); + changedNow = true; + } else if (!toggle || toggleUndefd && hasClass) { + eleClasses["delete"](cls); + changedNow = true; + } + if (!changedEle && changedNow) { + changed.push(ele); + changedEle = true; + } + } // for j classes + } // for i eles + + // trigger update style on those eles that had class changes + if (changed.length > 0) { + this.spawn(changed).updateStyle().emit('class'); + } + return self; + }, + removeClass: function removeClass(classes) { + return this.toggleClass(classes, false); + }, + flashClass: function flashClass(classes, duration) { + var self = this; + if (duration == null) { + duration = 250; + } else if (duration === 0) { + return self; // nothing to do really + } + + self.addClass(classes); + setTimeout(function () { + self.removeClass(classes); + }, duration); + return self; + } +}; +elesfn$h.className = elesfn$h.classNames = elesfn$h.classes; + +// tokens in the query language +var tokens = { + metaChar: '[\\!\\"\\#\\$\\%\\&\\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]', + // chars we need to escape in let names, etc + comparatorOp: '=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=', + // binary comparison op (used in data selectors) + boolOp: '\\?|\\!|\\^', + // boolean (unary) operators (used in data selectors) + string: '"(?:\\\\"|[^"])*"' + '|' + "'(?:\\\\'|[^'])*'", + // string literals (used in data selectors) -- doublequotes | singlequotes + number: number, + // number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123 + meta: 'degree|indegree|outdegree', + // allowed metadata fields (i.e. allowed functions to use from Collection) + separator: '\\s*,\\s*', + // queries are separated by commas, e.g. edge[foo = 'bar'], node.someClass + descendant: '\\s+', + child: '\\s+>\\s+', + subject: '\\$', + group: 'node|edge|\\*', + directedEdge: '\\s+->\\s+', + undirectedEdge: '\\s+<->\\s+' +}; +tokens.variable = '(?:[\\w-.]|(?:\\\\' + tokens.metaChar + '))+'; // a variable name can have letters, numbers, dashes, and periods +tokens.className = '(?:[\\w-]|(?:\\\\' + tokens.metaChar + '))+'; // a class name has the same rules as a variable except it can't have a '.' in the name +tokens.value = tokens.string + '|' + tokens.number; // a value literal, either a string or number +tokens.id = tokens.variable; // an element id (follows variable conventions) + +(function () { + var ops, op, i; + + // add @ variants to comparatorOp + ops = tokens.comparatorOp.split('|'); + for (i = 0; i < ops.length; i++) { + op = ops[i]; + tokens.comparatorOp += '|@' + op; + } + + // add ! variants to comparatorOp + ops = tokens.comparatorOp.split('|'); + for (i = 0; i < ops.length; i++) { + op = ops[i]; + if (op.indexOf('!') >= 0) { + continue; + } // skip ops that explicitly contain ! + if (op === '=') { + continue; + } // skip = b/c != is explicitly defined + + tokens.comparatorOp += '|\\!' + op; + } +})(); + +/** + * Make a new query object + * + * @prop type {Type} The type enum (int) of the query + * @prop checks List of checks to make against an ele to test for a match + */ +var newQuery = function newQuery() { + return { + checks: [] + }; +}; + +/** + * A check type enum-like object. Uses integer values for fast match() lookup. + * The ordering does not matter as long as the ints are unique. + */ +var Type = { + /** E.g. node */ + GROUP: 0, + /** A collection of elements */ + COLLECTION: 1, + /** A filter(ele) function */ + FILTER: 2, + /** E.g. [foo > 1] */ + DATA_COMPARE: 3, + /** E.g. [foo] */ + DATA_EXIST: 4, + /** E.g. [?foo] */ + DATA_BOOL: 5, + /** E.g. [[degree > 2]] */ + META_COMPARE: 6, + /** E.g. :selected */ + STATE: 7, + /** E.g. #foo */ + ID: 8, + /** E.g. .foo */ + CLASS: 9, + /** E.g. #foo <-> #bar */ + UNDIRECTED_EDGE: 10, + /** E.g. #foo -> #bar */ + DIRECTED_EDGE: 11, + /** E.g. $#foo -> #bar */ + NODE_SOURCE: 12, + /** E.g. #foo -> $#bar */ + NODE_TARGET: 13, + /** E.g. $#foo <-> #bar */ + NODE_NEIGHBOR: 14, + /** E.g. #foo > #bar */ + CHILD: 15, + /** E.g. #foo #bar */ + DESCENDANT: 16, + /** E.g. $#foo > #bar */ + PARENT: 17, + /** E.g. $#foo #bar */ + ANCESTOR: 18, + /** E.g. #foo > $bar > #baz */ + COMPOUND_SPLIT: 19, + /** Always matches, useful placeholder for subject in `COMPOUND_SPLIT` */ + TRUE: 20 +}; + +var stateSelectors = [{ + selector: ':selected', + matches: function matches(ele) { + return ele.selected(); + } +}, { + selector: ':unselected', + matches: function matches(ele) { + return !ele.selected(); + } +}, { + selector: ':selectable', + matches: function matches(ele) { + return ele.selectable(); + } +}, { + selector: ':unselectable', + matches: function matches(ele) { + return !ele.selectable(); + } +}, { + selector: ':locked', + matches: function matches(ele) { + return ele.locked(); + } +}, { + selector: ':unlocked', + matches: function matches(ele) { + return !ele.locked(); + } +}, { + selector: ':visible', + matches: function matches(ele) { + return ele.visible(); + } +}, { + selector: ':hidden', + matches: function matches(ele) { + return !ele.visible(); + } +}, { + selector: ':transparent', + matches: function matches(ele) { + return ele.transparent(); + } +}, { + selector: ':grabbed', + matches: function matches(ele) { + return ele.grabbed(); + } +}, { + selector: ':free', + matches: function matches(ele) { + return !ele.grabbed(); + } +}, { + selector: ':removed', + matches: function matches(ele) { + return ele.removed(); + } +}, { + selector: ':inside', + matches: function matches(ele) { + return !ele.removed(); + } +}, { + selector: ':grabbable', + matches: function matches(ele) { + return ele.grabbable(); + } +}, { + selector: ':ungrabbable', + matches: function matches(ele) { + return !ele.grabbable(); + } +}, { + selector: ':animated', + matches: function matches(ele) { + return ele.animated(); + } +}, { + selector: ':unanimated', + matches: function matches(ele) { + return !ele.animated(); + } +}, { + selector: ':parent', + matches: function matches(ele) { + return ele.isParent(); + } +}, { + selector: ':childless', + matches: function matches(ele) { + return ele.isChildless(); + } +}, { + selector: ':child', + matches: function matches(ele) { + return ele.isChild(); + } +}, { + selector: ':orphan', + matches: function matches(ele) { + return ele.isOrphan(); + } +}, { + selector: ':nonorphan', + matches: function matches(ele) { + return ele.isChild(); + } +}, { + selector: ':compound', + matches: function matches(ele) { + if (ele.isNode()) { + return ele.isParent(); + } else { + return ele.source().isParent() || ele.target().isParent(); + } + } +}, { + selector: ':loop', + matches: function matches(ele) { + return ele.isLoop(); + } +}, { + selector: ':simple', + matches: function matches(ele) { + return ele.isSimple(); + } +}, { + selector: ':active', + matches: function matches(ele) { + return ele.active(); + } +}, { + selector: ':inactive', + matches: function matches(ele) { + return !ele.active(); + } +}, { + selector: ':backgrounding', + matches: function matches(ele) { + return ele.backgrounding(); + } +}, { + selector: ':nonbackgrounding', + matches: function matches(ele) { + return !ele.backgrounding(); + } +}].sort(function (a, b) { + // n.b. selectors that are starting substrings of others must have the longer ones first + return descending(a.selector, b.selector); +}); +var lookup = function () { + var selToFn = {}; + var s; + for (var i = 0; i < stateSelectors.length; i++) { + s = stateSelectors[i]; + selToFn[s.selector] = s.matches; + } + return selToFn; +}(); +var stateSelectorMatches = function stateSelectorMatches(sel, ele) { + return lookup[sel](ele); +}; +var stateSelectorRegex = '(' + stateSelectors.map(function (s) { + return s.selector; +}).join('|') + ')'; + +// when a token like a variable has escaped meta characters, we need to clean the backslashes out +// so that values get compared properly in Selector.filter() +var cleanMetaChars = function cleanMetaChars(str) { + return str.replace(new RegExp('\\\\(' + tokens.metaChar + ')', 'g'), function (match, $1) { + return $1; + }); +}; +var replaceLastQuery = function replaceLastQuery(selector, examiningQuery, replacementQuery) { + selector[selector.length - 1] = replacementQuery; +}; + +// NOTE: add new expression syntax here to have it recognised by the parser; +// - a query contains all adjacent (i.e. no separator in between) expressions; +// - the current query is stored in selector[i] +// - you need to check the query objects in match() for it actually filter properly, but that's pretty straight forward +var exprs = [{ + name: 'group', + // just used for identifying when debugging + query: true, + regex: '(' + tokens.group + ')', + populate: function populate(selector, query, _ref) { + var _ref2 = _slicedToArray(_ref, 1), + group = _ref2[0]; + query.checks.push({ + type: Type.GROUP, + value: group === '*' ? group : group + 's' + }); + } +}, { + name: 'state', + query: true, + regex: stateSelectorRegex, + populate: function populate(selector, query, _ref3) { + var _ref4 = _slicedToArray(_ref3, 1), + state = _ref4[0]; + query.checks.push({ + type: Type.STATE, + value: state + }); + } +}, { + name: 'id', + query: true, + regex: '\\#(' + tokens.id + ')', + populate: function populate(selector, query, _ref5) { + var _ref6 = _slicedToArray(_ref5, 1), + id = _ref6[0]; + query.checks.push({ + type: Type.ID, + value: cleanMetaChars(id) + }); + } +}, { + name: 'className', + query: true, + regex: '\\.(' + tokens.className + ')', + populate: function populate(selector, query, _ref7) { + var _ref8 = _slicedToArray(_ref7, 1), + className = _ref8[0]; + query.checks.push({ + type: Type.CLASS, + value: cleanMetaChars(className) + }); + } +}, { + name: 'dataExists', + query: true, + regex: '\\[\\s*(' + tokens.variable + ')\\s*\\]', + populate: function populate(selector, query, _ref9) { + var _ref10 = _slicedToArray(_ref9, 1), + variable = _ref10[0]; + query.checks.push({ + type: Type.DATA_EXIST, + field: cleanMetaChars(variable) + }); + } +}, { + name: 'dataCompare', + query: true, + regex: '\\[\\s*(' + tokens.variable + ')\\s*(' + tokens.comparatorOp + ')\\s*(' + tokens.value + ')\\s*\\]', + populate: function populate(selector, query, _ref11) { + var _ref12 = _slicedToArray(_ref11, 3), + variable = _ref12[0], + comparatorOp = _ref12[1], + value = _ref12[2]; + var valueIsString = new RegExp('^' + tokens.string + '$').exec(value) != null; + if (valueIsString) { + value = value.substring(1, value.length - 1); + } else { + value = parseFloat(value); + } + query.checks.push({ + type: Type.DATA_COMPARE, + field: cleanMetaChars(variable), + operator: comparatorOp, + value: value + }); + } +}, { + name: 'dataBool', + query: true, + regex: '\\[\\s*(' + tokens.boolOp + ')\\s*(' + tokens.variable + ')\\s*\\]', + populate: function populate(selector, query, _ref13) { + var _ref14 = _slicedToArray(_ref13, 2), + boolOp = _ref14[0], + variable = _ref14[1]; + query.checks.push({ + type: Type.DATA_BOOL, + field: cleanMetaChars(variable), + operator: boolOp + }); + } +}, { + name: 'metaCompare', + query: true, + regex: '\\[\\[\\s*(' + tokens.meta + ')\\s*(' + tokens.comparatorOp + ')\\s*(' + tokens.number + ')\\s*\\]\\]', + populate: function populate(selector, query, _ref15) { + var _ref16 = _slicedToArray(_ref15, 3), + meta = _ref16[0], + comparatorOp = _ref16[1], + number = _ref16[2]; + query.checks.push({ + type: Type.META_COMPARE, + field: cleanMetaChars(meta), + operator: comparatorOp, + value: parseFloat(number) + }); + } +}, { + name: 'nextQuery', + separator: true, + regex: tokens.separator, + populate: function populate(selector, query) { + var currentSubject = selector.currentSubject; + var edgeCount = selector.edgeCount; + var compoundCount = selector.compoundCount; + var lastQ = selector[selector.length - 1]; + if (currentSubject != null) { + lastQ.subject = currentSubject; + selector.currentSubject = null; + } + lastQ.edgeCount = edgeCount; + lastQ.compoundCount = compoundCount; + selector.edgeCount = 0; + selector.compoundCount = 0; + + // go on to next query + var nextQuery = selector[selector.length++] = newQuery(); + return nextQuery; // this is the new query to be filled by the following exprs + } +}, { + name: 'directedEdge', + separator: true, + regex: tokens.directedEdge, + populate: function populate(selector, query) { + if (selector.currentSubject == null) { + // undirected edge + var edgeQuery = newQuery(); + var source = query; + var target = newQuery(); + edgeQuery.checks.push({ + type: Type.DIRECTED_EDGE, + source: source, + target: target + }); + + // the query in the selector should be the edge rather than the source + replaceLastQuery(selector, query, edgeQuery); + selector.edgeCount++; + + // we're now populating the target query with expressions that follow + return target; + } else { + // source/target + var srcTgtQ = newQuery(); + var _source = query; + var _target = newQuery(); + srcTgtQ.checks.push({ + type: Type.NODE_SOURCE, + source: _source, + target: _target + }); + + // the query in the selector should be the neighbourhood rather than the node + replaceLastQuery(selector, query, srcTgtQ); + selector.edgeCount++; + return _target; // now populating the target with the following expressions + } + } +}, { + name: 'undirectedEdge', + separator: true, + regex: tokens.undirectedEdge, + populate: function populate(selector, query) { + if (selector.currentSubject == null) { + // undirected edge + var edgeQuery = newQuery(); + var source = query; + var target = newQuery(); + edgeQuery.checks.push({ + type: Type.UNDIRECTED_EDGE, + nodes: [source, target] + }); + + // the query in the selector should be the edge rather than the source + replaceLastQuery(selector, query, edgeQuery); + selector.edgeCount++; + + // we're now populating the target query with expressions that follow + return target; + } else { + // neighbourhood + var nhoodQ = newQuery(); + var node = query; + var neighbor = newQuery(); + nhoodQ.checks.push({ + type: Type.NODE_NEIGHBOR, + node: node, + neighbor: neighbor + }); + + // the query in the selector should be the neighbourhood rather than the node + replaceLastQuery(selector, query, nhoodQ); + return neighbor; // now populating the neighbor with following expressions + } + } +}, { + name: 'child', + separator: true, + regex: tokens.child, + populate: function populate(selector, query) { + if (selector.currentSubject == null) { + // default: child query + var parentChildQuery = newQuery(); + var child = newQuery(); + var parent = selector[selector.length - 1]; + parentChildQuery.checks.push({ + type: Type.CHILD, + parent: parent, + child: child + }); + + // the query in the selector should be the '>' itself + replaceLastQuery(selector, query, parentChildQuery); + selector.compoundCount++; + + // we're now populating the child query with expressions that follow + return child; + } else if (selector.currentSubject === query) { + // compound split query + var compound = newQuery(); + var left = selector[selector.length - 1]; + var right = newQuery(); + var subject = newQuery(); + var _child = newQuery(); + var _parent = newQuery(); + + // set up the root compound q + compound.checks.push({ + type: Type.COMPOUND_SPLIT, + left: left, + right: right, + subject: subject + }); + + // populate the subject and replace the q at the old spot (within left) with TRUE + subject.checks = query.checks; // take the checks from the left + query.checks = [{ + type: Type.TRUE + }]; // checks under left refs the subject implicitly + + // set up the right q + _parent.checks.push({ + type: Type.TRUE + }); // parent implicitly refs the subject + right.checks.push({ + type: Type.PARENT, + // type is swapped on right side queries + parent: _parent, + child: _child // empty for now + }); + + replaceLastQuery(selector, left, compound); + + // update the ref since we moved things around for `query` + selector.currentSubject = subject; + selector.compoundCount++; + return _child; // now populating the right side's child + } else { + // parent query + // info for parent query + var _parent2 = newQuery(); + var _child2 = newQuery(); + var pcQChecks = [{ + type: Type.PARENT, + parent: _parent2, + child: _child2 + }]; + + // the parent-child query takes the place of the query previously being populated + _parent2.checks = query.checks; // the previous query contains the checks for the parent + query.checks = pcQChecks; // pc query takes over + + selector.compoundCount++; + return _child2; // we're now populating the child + } + } +}, { + name: 'descendant', + separator: true, + regex: tokens.descendant, + populate: function populate(selector, query) { + if (selector.currentSubject == null) { + // default: descendant query + var ancChQuery = newQuery(); + var descendant = newQuery(); + var ancestor = selector[selector.length - 1]; + ancChQuery.checks.push({ + type: Type.DESCENDANT, + ancestor: ancestor, + descendant: descendant + }); + + // the query in the selector should be the '>' itself + replaceLastQuery(selector, query, ancChQuery); + selector.compoundCount++; + + // we're now populating the descendant query with expressions that follow + return descendant; + } else if (selector.currentSubject === query) { + // compound split query + var compound = newQuery(); + var left = selector[selector.length - 1]; + var right = newQuery(); + var subject = newQuery(); + var _descendant = newQuery(); + var _ancestor = newQuery(); + + // set up the root compound q + compound.checks.push({ + type: Type.COMPOUND_SPLIT, + left: left, + right: right, + subject: subject + }); + + // populate the subject and replace the q at the old spot (within left) with TRUE + subject.checks = query.checks; // take the checks from the left + query.checks = [{ + type: Type.TRUE + }]; // checks under left refs the subject implicitly + + // set up the right q + _ancestor.checks.push({ + type: Type.TRUE + }); // ancestor implicitly refs the subject + right.checks.push({ + type: Type.ANCESTOR, + // type is swapped on right side queries + ancestor: _ancestor, + descendant: _descendant // empty for now + }); + + replaceLastQuery(selector, left, compound); + + // update the ref since we moved things around for `query` + selector.currentSubject = subject; + selector.compoundCount++; + return _descendant; // now populating the right side's descendant + } else { + // ancestor query + // info for parent query + var _ancestor2 = newQuery(); + var _descendant2 = newQuery(); + var adQChecks = [{ + type: Type.ANCESTOR, + ancestor: _ancestor2, + descendant: _descendant2 + }]; + + // the parent-child query takes the place of the query previously being populated + _ancestor2.checks = query.checks; // the previous query contains the checks for the parent + query.checks = adQChecks; // pc query takes over + + selector.compoundCount++; + return _descendant2; // we're now populating the child + } + } +}, { + name: 'subject', + modifier: true, + regex: tokens.subject, + populate: function populate(selector, query) { + if (selector.currentSubject != null && selector.currentSubject !== query) { + warn('Redefinition of subject in selector `' + selector.toString() + '`'); + return false; + } + selector.currentSubject = query; + var topQ = selector[selector.length - 1]; + var topChk = topQ.checks[0]; + var topType = topChk == null ? null : topChk.type; + if (topType === Type.DIRECTED_EDGE) { + // directed edge with subject on the target + + // change to target node check + topChk.type = Type.NODE_TARGET; + } else if (topType === Type.UNDIRECTED_EDGE) { + // undirected edge with subject on the second node + + // change to neighbor check + topChk.type = Type.NODE_NEIGHBOR; + topChk.node = topChk.nodes[1]; // second node is subject + topChk.neighbor = topChk.nodes[0]; + + // clean up unused fields for new type + topChk.nodes = null; + } + } +}]; +exprs.forEach(function (e) { + return e.regexObj = new RegExp('^' + e.regex); +}); + +/** + * Of all the expressions, find the first match in the remaining text. + * @param {string} remaining The remaining text to parse + * @returns The matched expression and the newly remaining text `{ expr, match, name, remaining }` + */ +var consumeExpr = function consumeExpr(remaining) { + var expr; + var match; + var name; + for (var j = 0; j < exprs.length; j++) { + var e = exprs[j]; + var n = e.name; + var m = remaining.match(e.regexObj); + if (m != null) { + match = m; + expr = e; + name = n; + var consumed = m[0]; + remaining = remaining.substring(consumed.length); + break; // we've consumed one expr, so we can return now + } + } + + return { + expr: expr, + match: match, + name: name, + remaining: remaining + }; +}; + +/** + * Consume all the leading whitespace + * @param {string} remaining The text to consume + * @returns The text with the leading whitespace removed + */ +var consumeWhitespace = function consumeWhitespace(remaining) { + var match = remaining.match(/^\s+/); + if (match) { + var consumed = match[0]; + remaining = remaining.substring(consumed.length); + } + return remaining; +}; + +/** + * Parse the string and store the parsed representation in the Selector. + * @param {string} selector The selector string + * @returns `true` if the selector was successfully parsed, `false` otherwise + */ +var parse = function parse(selector) { + var self = this; + var remaining = self.inputText = selector; + var currentQuery = self[0] = newQuery(); + self.length = 1; + remaining = consumeWhitespace(remaining); // get rid of leading whitespace + + for (;;) { + var exprInfo = consumeExpr(remaining); + if (exprInfo.expr == null) { + warn('The selector `' + selector + '`is invalid'); + return false; + } else { + var args = exprInfo.match.slice(1); + + // let the token populate the selector object in currentQuery + var ret = exprInfo.expr.populate(self, currentQuery, args); + if (ret === false) { + return false; // exit if population failed + } else if (ret != null) { + currentQuery = ret; // change the current query to be filled if the expr specifies + } + } + + remaining = exprInfo.remaining; + + // we're done when there's nothing left to parse + if (remaining.match(/^\s*$/)) { + break; + } + } + var lastQ = self[self.length - 1]; + if (self.currentSubject != null) { + lastQ.subject = self.currentSubject; + } + lastQ.edgeCount = self.edgeCount; + lastQ.compoundCount = self.compoundCount; + for (var i = 0; i < self.length; i++) { + var q = self[i]; + + // in future, this could potentially be allowed if there were operator precedence and detection of invalid combinations + if (q.compoundCount > 0 && q.edgeCount > 0) { + warn('The selector `' + selector + '` is invalid because it uses both a compound selector and an edge selector'); + return false; + } + if (q.edgeCount > 1) { + warn('The selector `' + selector + '` is invalid because it uses multiple edge selectors'); + return false; + } else if (q.edgeCount === 1) { + warn('The selector `' + selector + '` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.'); + } + } + return true; // success +}; + +/** + * Get the selector represented as a string. This value uses default formatting, + * so things like spacing may differ from the input text passed to the constructor. + * @returns {string} The selector string + */ +var toString = function toString() { + if (this.toStringCache != null) { + return this.toStringCache; + } + var clean = function clean(obj) { + if (obj == null) { + return ''; + } else { + return obj; + } + }; + var cleanVal = function cleanVal(val) { + if (string(val)) { + return '"' + val + '"'; + } else { + return clean(val); + } + }; + var space = function space(val) { + return ' ' + val + ' '; + }; + var checkToString = function checkToString(check, subject) { + var type = check.type, + value = check.value; + switch (type) { + case Type.GROUP: + { + var group = clean(value); + return group.substring(0, group.length - 1); + } + case Type.DATA_COMPARE: + { + var field = check.field, + operator = check.operator; + return '[' + field + space(clean(operator)) + cleanVal(value) + ']'; + } + case Type.DATA_BOOL: + { + var _operator = check.operator, + _field = check.field; + return '[' + clean(_operator) + _field + ']'; + } + case Type.DATA_EXIST: + { + var _field2 = check.field; + return '[' + _field2 + ']'; + } + case Type.META_COMPARE: + { + var _operator2 = check.operator, + _field3 = check.field; + return '[[' + _field3 + space(clean(_operator2)) + cleanVal(value) + ']]'; + } + case Type.STATE: + { + return value; + } + case Type.ID: + { + return '#' + value; + } + case Type.CLASS: + { + return '.' + value; + } + case Type.PARENT: + case Type.CHILD: + { + return queryToString(check.parent, subject) + space('>') + queryToString(check.child, subject); + } + case Type.ANCESTOR: + case Type.DESCENDANT: + { + return queryToString(check.ancestor, subject) + ' ' + queryToString(check.descendant, subject); + } + case Type.COMPOUND_SPLIT: + { + var lhs = queryToString(check.left, subject); + var sub = queryToString(check.subject, subject); + var rhs = queryToString(check.right, subject); + return lhs + (lhs.length > 0 ? ' ' : '') + sub + rhs; + } + case Type.TRUE: + { + return ''; + } + } + }; + var queryToString = function queryToString(query, subject) { + return query.checks.reduce(function (str, chk, i) { + return str + (subject === query && i === 0 ? '$' : '') + checkToString(chk, subject); + }, ''); + }; + var str = ''; + for (var i = 0; i < this.length; i++) { + var query = this[i]; + str += queryToString(query, query.subject); + if (this.length > 1 && i < this.length - 1) { + str += ', '; + } + } + this.toStringCache = str; + return str; +}; +var parse$1 = { + parse: parse, + toString: toString +}; + +var valCmp = function valCmp(fieldVal, operator, value) { + var matches; + var isFieldStr = string(fieldVal); + var isFieldNum = number$1(fieldVal); + var isValStr = string(value); + var fieldStr, valStr; + var caseInsensitive = false; + var notExpr = false; + var isIneqCmp = false; + if (operator.indexOf('!') >= 0) { + operator = operator.replace('!', ''); + notExpr = true; + } + if (operator.indexOf('@') >= 0) { + operator = operator.replace('@', ''); + caseInsensitive = true; + } + if (isFieldStr || isValStr || caseInsensitive) { + fieldStr = !isFieldStr && !isFieldNum ? '' : '' + fieldVal; + valStr = '' + value; + } + + // if we're doing a case insensitive comparison, then we're using a STRING comparison + // even if we're comparing numbers + if (caseInsensitive) { + fieldVal = fieldStr = fieldStr.toLowerCase(); + value = valStr = valStr.toLowerCase(); + } + switch (operator) { + case '*=': + matches = fieldStr.indexOf(valStr) >= 0; + break; + case '$=': + matches = fieldStr.indexOf(valStr, fieldStr.length - valStr.length) >= 0; + break; + case '^=': + matches = fieldStr.indexOf(valStr) === 0; + break; + case '=': + matches = fieldVal === value; + break; + case '>': + isIneqCmp = true; + matches = fieldVal > value; + break; + case '>=': + isIneqCmp = true; + matches = fieldVal >= value; + break; + case '<': + isIneqCmp = true; + matches = fieldVal < value; + break; + case '<=': + isIneqCmp = true; + matches = fieldVal <= value; + break; + default: + matches = false; + break; + } + + // apply the not op, but null vals for inequalities should always stay non-matching + if (notExpr && (fieldVal != null || !isIneqCmp)) { + matches = !matches; + } + return matches; +}; +var boolCmp = function boolCmp(fieldVal, operator) { + switch (operator) { + case '?': + return fieldVal ? true : false; + case '!': + return fieldVal ? false : true; + case '^': + return fieldVal === undefined; + } +}; +var existCmp = function existCmp(fieldVal) { + return fieldVal !== undefined; +}; +var data$1 = function data(ele, field) { + return ele.data(field); +}; +var meta = function meta(ele, field) { + return ele[field](); +}; + +/** A lookup of `match(check, ele)` functions by `Type` int */ +var match = []; + +/** + * Returns whether the query matches for the element + * @param query The `{ type, value, ... }` query object + * @param ele The element to compare against +*/ +var matches$1 = function matches(query, ele) { + return query.checks.every(function (chk) { + return match[chk.type](chk, ele); + }); +}; +match[Type.GROUP] = function (check, ele) { + var group = check.value; + return group === '*' || group === ele.group(); +}; +match[Type.STATE] = function (check, ele) { + var stateSelector = check.value; + return stateSelectorMatches(stateSelector, ele); +}; +match[Type.ID] = function (check, ele) { + var id = check.value; + return ele.id() === id; +}; +match[Type.CLASS] = function (check, ele) { + var cls = check.value; + return ele.hasClass(cls); +}; +match[Type.META_COMPARE] = function (check, ele) { + var field = check.field, + operator = check.operator, + value = check.value; + return valCmp(meta(ele, field), operator, value); +}; +match[Type.DATA_COMPARE] = function (check, ele) { + var field = check.field, + operator = check.operator, + value = check.value; + return valCmp(data$1(ele, field), operator, value); +}; +match[Type.DATA_BOOL] = function (check, ele) { + var field = check.field, + operator = check.operator; + return boolCmp(data$1(ele, field), operator); +}; +match[Type.DATA_EXIST] = function (check, ele) { + var field = check.field; + check.operator; + return existCmp(data$1(ele, field)); +}; +match[Type.UNDIRECTED_EDGE] = function (check, ele) { + var qA = check.nodes[0]; + var qB = check.nodes[1]; + var src = ele.source(); + var tgt = ele.target(); + return matches$1(qA, src) && matches$1(qB, tgt) || matches$1(qB, src) && matches$1(qA, tgt); +}; +match[Type.NODE_NEIGHBOR] = function (check, ele) { + return matches$1(check.node, ele) && ele.neighborhood().some(function (n) { + return n.isNode() && matches$1(check.neighbor, n); + }); +}; +match[Type.DIRECTED_EDGE] = function (check, ele) { + return matches$1(check.source, ele.source()) && matches$1(check.target, ele.target()); +}; +match[Type.NODE_SOURCE] = function (check, ele) { + return matches$1(check.source, ele) && ele.outgoers().some(function (n) { + return n.isNode() && matches$1(check.target, n); + }); +}; +match[Type.NODE_TARGET] = function (check, ele) { + return matches$1(check.target, ele) && ele.incomers().some(function (n) { + return n.isNode() && matches$1(check.source, n); + }); +}; +match[Type.CHILD] = function (check, ele) { + return matches$1(check.child, ele) && matches$1(check.parent, ele.parent()); +}; +match[Type.PARENT] = function (check, ele) { + return matches$1(check.parent, ele) && ele.children().some(function (c) { + return matches$1(check.child, c); + }); +}; +match[Type.DESCENDANT] = function (check, ele) { + return matches$1(check.descendant, ele) && ele.ancestors().some(function (a) { + return matches$1(check.ancestor, a); + }); +}; +match[Type.ANCESTOR] = function (check, ele) { + return matches$1(check.ancestor, ele) && ele.descendants().some(function (d) { + return matches$1(check.descendant, d); + }); +}; +match[Type.COMPOUND_SPLIT] = function (check, ele) { + return matches$1(check.subject, ele) && matches$1(check.left, ele) && matches$1(check.right, ele); +}; +match[Type.TRUE] = function () { + return true; +}; +match[Type.COLLECTION] = function (check, ele) { + var collection = check.value; + return collection.has(ele); +}; +match[Type.FILTER] = function (check, ele) { + var filter = check.value; + return filter(ele); +}; + +// filter an existing collection +var filter = function filter(collection) { + var self = this; + + // for 1 id #foo queries, just get the element + if (self.length === 1 && self[0].checks.length === 1 && self[0].checks[0].type === Type.ID) { + return collection.getElementById(self[0].checks[0].value).collection(); + } + var selectorFunction = function selectorFunction(element) { + for (var j = 0; j < self.length; j++) { + var query = self[j]; + if (matches$1(query, element)) { + return true; + } + } + return false; + }; + if (self.text() == null) { + selectorFunction = function selectorFunction() { + return true; + }; + } + return collection.filter(selectorFunction); +}; // filter + +// does selector match a single element? +var matches = function matches(ele) { + var self = this; + for (var j = 0; j < self.length; j++) { + var query = self[j]; + if (matches$1(query, ele)) { + return true; + } + } + return false; +}; // matches + +var matching = { + matches: matches, + filter: filter +}; + +var Selector = function Selector(selector) { + this.inputText = selector; + this.currentSubject = null; + this.compoundCount = 0; + this.edgeCount = 0; + this.length = 0; + if (selector == null || string(selector) && selector.match(/^\s*$/)) ; else if (elementOrCollection(selector)) { + this.addQuery({ + checks: [{ + type: Type.COLLECTION, + value: selector.collection() + }] + }); + } else if (fn$6(selector)) { + this.addQuery({ + checks: [{ + type: Type.FILTER, + value: selector + }] + }); + } else if (string(selector)) { + if (!this.parse(selector)) { + this.invalid = true; + } + } else { + error('A selector must be created from a string; found '); + } +}; +var selfn = Selector.prototype; +[parse$1, matching].forEach(function (p) { + return extend(selfn, p); +}); +selfn.text = function () { + return this.inputText; +}; +selfn.size = function () { + return this.length; +}; +selfn.eq = function (i) { + return this[i]; +}; +selfn.sameText = function (otherSel) { + return !this.invalid && !otherSel.invalid && this.text() === otherSel.text(); +}; +selfn.addQuery = function (q) { + this[this.length++] = q; +}; +selfn.selector = selfn.toString; + +var elesfn$g = { + allAre: function allAre(selector) { + var selObj = new Selector(selector); + return this.every(function (ele) { + return selObj.matches(ele); + }); + }, + is: function is(selector) { + var selObj = new Selector(selector); + return this.some(function (ele) { + return selObj.matches(ele); + }); + }, + some: function some(fn, thisArg) { + for (var i = 0; i < this.length; i++) { + var ret = !thisArg ? fn(this[i], i, this) : fn.apply(thisArg, [this[i], i, this]); + if (ret) { + return true; + } + } + return false; + }, + every: function every(fn, thisArg) { + for (var i = 0; i < this.length; i++) { + var ret = !thisArg ? fn(this[i], i, this) : fn.apply(thisArg, [this[i], i, this]); + if (!ret) { + return false; + } + } + return true; + }, + same: function same(collection) { + // cheap collection ref check + if (this === collection) { + return true; + } + collection = this.cy().collection(collection); + var thisLength = this.length; + var collectionLength = collection.length; + + // cheap length check + if (thisLength !== collectionLength) { + return false; + } + + // cheap element ref check + if (thisLength === 1) { + return this[0] === collection[0]; + } + return this.every(function (ele) { + return collection.hasElementWithId(ele.id()); + }); + }, + anySame: function anySame(collection) { + collection = this.cy().collection(collection); + return this.some(function (ele) { + return collection.hasElementWithId(ele.id()); + }); + }, + allAreNeighbors: function allAreNeighbors(collection) { + collection = this.cy().collection(collection); + var nhood = this.neighborhood(); + return collection.every(function (ele) { + return nhood.hasElementWithId(ele.id()); + }); + }, + contains: function contains(collection) { + collection = this.cy().collection(collection); + var self = this; + return collection.every(function (ele) { + return self.hasElementWithId(ele.id()); + }); + } +}; +elesfn$g.allAreNeighbours = elesfn$g.allAreNeighbors; +elesfn$g.has = elesfn$g.contains; +elesfn$g.equal = elesfn$g.equals = elesfn$g.same; + +var cache = function cache(fn, name) { + return function traversalCache(arg1, arg2, arg3, arg4) { + var selectorOrEles = arg1; + var eles = this; + var key; + if (selectorOrEles == null) { + key = ''; + } else if (elementOrCollection(selectorOrEles) && selectorOrEles.length === 1) { + key = selectorOrEles.id(); + } + if (eles.length === 1 && key) { + var _p = eles[0]._private; + var tch = _p.traversalCache = _p.traversalCache || {}; + var ch = tch[name] = tch[name] || []; + var hash = hashString(key); + var cacheHit = ch[hash]; + if (cacheHit) { + return cacheHit; + } else { + return ch[hash] = fn.call(eles, arg1, arg2, arg3, arg4); + } + } else { + return fn.call(eles, arg1, arg2, arg3, arg4); + } + }; +}; + +var elesfn$f = { + parent: function parent(selector) { + var parents = []; + + // optimisation for single ele call + if (this.length === 1) { + var parent = this[0]._private.parent; + if (parent) { + return parent; + } + } + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var _parent = ele._private.parent; + if (_parent) { + parents.push(_parent); + } + } + return this.spawn(parents, true).filter(selector); + }, + parents: function parents(selector) { + var parents = []; + var eles = this.parent(); + while (eles.nonempty()) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + parents.push(ele); + } + eles = eles.parent(); + } + return this.spawn(parents, true).filter(selector); + }, + commonAncestors: function commonAncestors(selector) { + var ancestors; + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var parents = ele.parents(); + ancestors = ancestors || parents; + ancestors = ancestors.intersect(parents); // current list must be common with current ele parents set + } + + return ancestors.filter(selector); + }, + orphans: function orphans(selector) { + return this.stdFilter(function (ele) { + return ele.isOrphan(); + }).filter(selector); + }, + nonorphans: function nonorphans(selector) { + return this.stdFilter(function (ele) { + return ele.isChild(); + }).filter(selector); + }, + children: cache(function (selector) { + var children = []; + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var eleChildren = ele._private.children; + for (var j = 0; j < eleChildren.length; j++) { + children.push(eleChildren[j]); + } + } + return this.spawn(children, true).filter(selector); + }, 'children'), + siblings: function siblings(selector) { + return this.parent().children().not(this).filter(selector); + }, + isParent: function isParent() { + var ele = this[0]; + if (ele) { + return ele.isNode() && ele._private.children.length !== 0; + } + }, + isChildless: function isChildless() { + var ele = this[0]; + if (ele) { + return ele.isNode() && ele._private.children.length === 0; + } + }, + isChild: function isChild() { + var ele = this[0]; + if (ele) { + return ele.isNode() && ele._private.parent != null; + } + }, + isOrphan: function isOrphan() { + var ele = this[0]; + if (ele) { + return ele.isNode() && ele._private.parent == null; + } + }, + descendants: function descendants(selector) { + var elements = []; + function add(eles) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + elements.push(ele); + if (ele.children().nonempty()) { + add(ele.children()); + } + } + } + add(this.children()); + return this.spawn(elements, true).filter(selector); + } +}; +function forEachCompound(eles, fn, includeSelf, recursiveStep) { + var q = []; + var did = new Set$1(); + var cy = eles.cy(); + var hasCompounds = cy.hasCompoundNodes(); + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + if (includeSelf) { + q.push(ele); + } else if (hasCompounds) { + recursiveStep(q, did, ele); + } + } + while (q.length > 0) { + var _ele = q.shift(); + fn(_ele); + did.add(_ele.id()); + if (hasCompounds) { + recursiveStep(q, did, _ele); + } + } + return eles; +} +function addChildren(q, did, ele) { + if (ele.isParent()) { + var children = ele._private.children; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (!did.has(child.id())) { + q.push(child); + } + } + } +} + +// very efficient version of eles.add( eles.descendants() ).forEach() +// for internal use +elesfn$f.forEachDown = function (fn) { + var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + return forEachCompound(this, fn, includeSelf, addChildren); +}; +function addParent(q, did, ele) { + if (ele.isChild()) { + var parent = ele._private.parent; + if (!did.has(parent.id())) { + q.push(parent); + } + } +} +elesfn$f.forEachUp = function (fn) { + var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + return forEachCompound(this, fn, includeSelf, addParent); +}; +function addParentAndChildren(q, did, ele) { + addParent(q, did, ele); + addChildren(q, did, ele); +} +elesfn$f.forEachUpAndDown = function (fn) { + var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + return forEachCompound(this, fn, includeSelf, addParentAndChildren); +}; + +// aliases +elesfn$f.ancestors = elesfn$f.parents; + +var fn$5, elesfn$e; +fn$5 = elesfn$e = { + data: define.data({ + field: 'data', + bindingEvent: 'data', + allowBinding: true, + allowSetting: true, + settingEvent: 'data', + settingTriggersEvent: true, + triggerFnName: 'trigger', + allowGetting: true, + immutableKeys: { + 'id': true, + 'source': true, + 'target': true, + 'parent': true + }, + updateStyle: true + }), + removeData: define.removeData({ + field: 'data', + event: 'data', + triggerFnName: 'trigger', + triggerEvent: true, + immutableKeys: { + 'id': true, + 'source': true, + 'target': true, + 'parent': true + }, + updateStyle: true + }), + scratch: define.data({ + field: 'scratch', + bindingEvent: 'scratch', + allowBinding: true, + allowSetting: true, + settingEvent: 'scratch', + settingTriggersEvent: true, + triggerFnName: 'trigger', + allowGetting: true, + updateStyle: true + }), + removeScratch: define.removeData({ + field: 'scratch', + event: 'scratch', + triggerFnName: 'trigger', + triggerEvent: true, + updateStyle: true + }), + rscratch: define.data({ + field: 'rscratch', + allowBinding: false, + allowSetting: true, + settingTriggersEvent: false, + allowGetting: true + }), + removeRscratch: define.removeData({ + field: 'rscratch', + triggerEvent: false + }), + id: function id() { + var ele = this[0]; + if (ele) { + return ele._private.data.id; + } + } +}; + +// aliases +fn$5.attr = fn$5.data; +fn$5.removeAttr = fn$5.removeData; +var data = elesfn$e; + +var elesfn$d = {}; +function defineDegreeFunction(callback) { + return function (includeLoops) { + var self = this; + if (includeLoops === undefined) { + includeLoops = true; + } + if (self.length === 0) { + return; + } + if (self.isNode() && !self.removed()) { + var degree = 0; + var node = self[0]; + var connectedEdges = node._private.edges; + for (var i = 0; i < connectedEdges.length; i++) { + var edge = connectedEdges[i]; + if (!includeLoops && edge.isLoop()) { + continue; + } + degree += callback(node, edge); + } + return degree; + } else { + return; + } + }; +} +extend(elesfn$d, { + degree: defineDegreeFunction(function (node, edge) { + if (edge.source().same(edge.target())) { + return 2; + } else { + return 1; + } + }), + indegree: defineDegreeFunction(function (node, edge) { + if (edge.target().same(node)) { + return 1; + } else { + return 0; + } + }), + outdegree: defineDegreeFunction(function (node, edge) { + if (edge.source().same(node)) { + return 1; + } else { + return 0; + } + }) +}); +function defineDegreeBoundsFunction(degreeFn, callback) { + return function (includeLoops) { + var ret; + var nodes = this.nodes(); + for (var i = 0; i < nodes.length; i++) { + var ele = nodes[i]; + var degree = ele[degreeFn](includeLoops); + if (degree !== undefined && (ret === undefined || callback(degree, ret))) { + ret = degree; + } + } + return ret; + }; +} +extend(elesfn$d, { + minDegree: defineDegreeBoundsFunction('degree', function (degree, min) { + return degree < min; + }), + maxDegree: defineDegreeBoundsFunction('degree', function (degree, max) { + return degree > max; + }), + minIndegree: defineDegreeBoundsFunction('indegree', function (degree, min) { + return degree < min; + }), + maxIndegree: defineDegreeBoundsFunction('indegree', function (degree, max) { + return degree > max; + }), + minOutdegree: defineDegreeBoundsFunction('outdegree', function (degree, min) { + return degree < min; + }), + maxOutdegree: defineDegreeBoundsFunction('outdegree', function (degree, max) { + return degree > max; + }) +}); +extend(elesfn$d, { + totalDegree: function totalDegree(includeLoops) { + var total = 0; + var nodes = this.nodes(); + for (var i = 0; i < nodes.length; i++) { + total += nodes[i].degree(includeLoops); + } + return total; + } +}); + +var fn$4, elesfn$c; +var beforePositionSet = function beforePositionSet(eles, newPos, silent) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + if (!ele.locked()) { + var oldPos = ele._private.position; + var delta = { + x: newPos.x != null ? newPos.x - oldPos.x : 0, + y: newPos.y != null ? newPos.y - oldPos.y : 0 + }; + if (ele.isParent() && !(delta.x === 0 && delta.y === 0)) { + ele.children().shift(delta, silent); + } + ele.dirtyBoundingBoxCache(); + } + } +}; +var positionDef = { + field: 'position', + bindingEvent: 'position', + allowBinding: true, + allowSetting: true, + settingEvent: 'position', + settingTriggersEvent: true, + triggerFnName: 'emitAndNotify', + allowGetting: true, + validKeys: ['x', 'y'], + beforeGet: function beforeGet(ele) { + ele.updateCompoundBounds(); + }, + beforeSet: function beforeSet(eles, newPos) { + beforePositionSet(eles, newPos, false); + }, + onSet: function onSet(eles) { + eles.dirtyCompoundBoundsCache(); + }, + canSet: function canSet(ele) { + return !ele.locked(); + } +}; +fn$4 = elesfn$c = { + position: define.data(positionDef), + // position but no notification to renderer + silentPosition: define.data(extend({}, positionDef, { + allowBinding: false, + allowSetting: true, + settingTriggersEvent: false, + allowGetting: false, + beforeSet: function beforeSet(eles, newPos) { + beforePositionSet(eles, newPos, true); + }, + onSet: function onSet(eles) { + eles.dirtyCompoundBoundsCache(); + } + })), + positions: function positions(pos, silent) { + if (plainObject(pos)) { + if (silent) { + this.silentPosition(pos); + } else { + this.position(pos); + } + } else if (fn$6(pos)) { + var _fn = pos; + var cy = this.cy(); + cy.startBatch(); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var _pos = void 0; + if (_pos = _fn(ele, i)) { + if (silent) { + ele.silentPosition(_pos); + } else { + ele.position(_pos); + } + } + } + cy.endBatch(); + } + return this; // chaining + }, + + silentPositions: function silentPositions(pos) { + return this.positions(pos, true); + }, + shift: function shift(dim, val, silent) { + var delta; + if (plainObject(dim)) { + delta = { + x: number$1(dim.x) ? dim.x : 0, + y: number$1(dim.y) ? dim.y : 0 + }; + silent = val; + } else if (string(dim) && number$1(val)) { + delta = { + x: 0, + y: 0 + }; + delta[dim] = val; + } + if (delta != null) { + var cy = this.cy(); + cy.startBatch(); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + + // exclude any node that is a descendant of the calling collection + if (cy.hasCompoundNodes() && ele.isChild() && ele.ancestors().anySame(this)) { + continue; + } + var pos = ele.position(); + var newPos = { + x: pos.x + delta.x, + y: pos.y + delta.y + }; + if (silent) { + ele.silentPosition(newPos); + } else { + ele.position(newPos); + } + } + cy.endBatch(); + } + return this; + }, + silentShift: function silentShift(dim, val) { + if (plainObject(dim)) { + this.shift(dim, true); + } else if (string(dim) && number$1(val)) { + this.shift(dim, val, true); + } + return this; + }, + // get/set the rendered (i.e. on screen) positon of the element + renderedPosition: function renderedPosition(dim, val) { + var ele = this[0]; + var cy = this.cy(); + var zoom = cy.zoom(); + var pan = cy.pan(); + var rpos = plainObject(dim) ? dim : undefined; + var setting = rpos !== undefined || val !== undefined && string(dim); + if (ele && ele.isNode()) { + // must have an element and must be a node to return position + if (setting) { + for (var i = 0; i < this.length; i++) { + var _ele = this[i]; + if (val !== undefined) { + // set one dimension + _ele.position(dim, (val - pan[dim]) / zoom); + } else if (rpos !== undefined) { + // set whole position + _ele.position(renderedToModelPosition(rpos, zoom, pan)); + } + } + } else { + // getting + var pos = ele.position(); + rpos = modelToRenderedPosition(pos, zoom, pan); + if (dim === undefined) { + // then return the whole rendered position + return rpos; + } else { + // then return the specified dimension + return rpos[dim]; + } + } + } else if (!setting) { + return undefined; // for empty collection case + } + + return this; // chaining + }, + + // get/set the position relative to the parent + relativePosition: function relativePosition(dim, val) { + var ele = this[0]; + var cy = this.cy(); + var ppos = plainObject(dim) ? dim : undefined; + var setting = ppos !== undefined || val !== undefined && string(dim); + var hasCompoundNodes = cy.hasCompoundNodes(); + if (ele && ele.isNode()) { + // must have an element and must be a node to return position + if (setting) { + for (var i = 0; i < this.length; i++) { + var _ele2 = this[i]; + var parent = hasCompoundNodes ? _ele2.parent() : null; + var hasParent = parent && parent.length > 0; + var relativeToParent = hasParent; + if (hasParent) { + parent = parent[0]; + } + var origin = relativeToParent ? parent.position() : { + x: 0, + y: 0 + }; + if (val !== undefined) { + // set one dimension + _ele2.position(dim, val + origin[dim]); + } else if (ppos !== undefined) { + // set whole position + _ele2.position({ + x: ppos.x + origin.x, + y: ppos.y + origin.y + }); + } + } + } else { + // getting + var pos = ele.position(); + var _parent = hasCompoundNodes ? ele.parent() : null; + var _hasParent = _parent && _parent.length > 0; + var _relativeToParent = _hasParent; + if (_hasParent) { + _parent = _parent[0]; + } + var _origin = _relativeToParent ? _parent.position() : { + x: 0, + y: 0 + }; + ppos = { + x: pos.x - _origin.x, + y: pos.y - _origin.y + }; + if (dim === undefined) { + // then return the whole rendered position + return ppos; + } else { + // then return the specified dimension + return ppos[dim]; + } + } + } else if (!setting) { + return undefined; // for empty collection case + } + + return this; // chaining + } +}; + +// aliases +fn$4.modelPosition = fn$4.point = fn$4.position; +fn$4.modelPositions = fn$4.points = fn$4.positions; +fn$4.renderedPoint = fn$4.renderedPosition; +fn$4.relativePoint = fn$4.relativePosition; +var position = elesfn$c; + +var fn$3, elesfn$b; +fn$3 = elesfn$b = {}; +elesfn$b.renderedBoundingBox = function (options) { + var bb = this.boundingBox(options); + var cy = this.cy(); + var zoom = cy.zoom(); + var pan = cy.pan(); + var x1 = bb.x1 * zoom + pan.x; + var x2 = bb.x2 * zoom + pan.x; + var y1 = bb.y1 * zoom + pan.y; + var y2 = bb.y2 * zoom + pan.y; + return { + x1: x1, + x2: x2, + y1: y1, + y2: y2, + w: x2 - x1, + h: y2 - y1 + }; +}; +elesfn$b.dirtyCompoundBoundsCache = function () { + var silent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var cy = this.cy(); + if (!cy.styleEnabled() || !cy.hasCompoundNodes()) { + return this; + } + this.forEachUp(function (ele) { + if (ele.isParent()) { + var _p = ele._private; + _p.compoundBoundsClean = false; + _p.bbCache = null; + if (!silent) { + ele.emitAndNotify('bounds'); + } + } + }); + return this; +}; +elesfn$b.updateCompoundBounds = function () { + var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var cy = this.cy(); + + // not possible to do on non-compound graphs or with the style disabled + if (!cy.styleEnabled() || !cy.hasCompoundNodes()) { + return this; + } + + // save cycles when batching -- but bounds will be stale (or not exist yet) + if (!force && cy.batching()) { + return this; + } + function update(parent) { + if (!parent.isParent()) { + return; + } + var _p = parent._private; + var children = parent.children(); + var includeLabels = parent.pstyle('compound-sizing-wrt-labels').value === 'include'; + var min = { + width: { + val: parent.pstyle('min-width').pfValue, + left: parent.pstyle('min-width-bias-left'), + right: parent.pstyle('min-width-bias-right') + }, + height: { + val: parent.pstyle('min-height').pfValue, + top: parent.pstyle('min-height-bias-top'), + bottom: parent.pstyle('min-height-bias-bottom') + } + }; + var bb = children.boundingBox({ + includeLabels: includeLabels, + includeOverlays: false, + // updating the compound bounds happens outside of the regular + // cache cycle (i.e. before fired events) + useCache: false + }); + var pos = _p.position; + + // if children take up zero area then keep position and fall back on stylesheet w/h + if (bb.w === 0 || bb.h === 0) { + bb = { + w: parent.pstyle('width').pfValue, + h: parent.pstyle('height').pfValue + }; + bb.x1 = pos.x - bb.w / 2; + bb.x2 = pos.x + bb.w / 2; + bb.y1 = pos.y - bb.h / 2; + bb.y2 = pos.y + bb.h / 2; + } + function computeBiasValues(propDiff, propBias, propBiasComplement) { + var biasDiff = 0; + var biasComplementDiff = 0; + var biasTotal = propBias + propBiasComplement; + if (propDiff > 0 && biasTotal > 0) { + biasDiff = propBias / biasTotal * propDiff; + biasComplementDiff = propBiasComplement / biasTotal * propDiff; + } + return { + biasDiff: biasDiff, + biasComplementDiff: biasComplementDiff + }; + } + function computePaddingValues(width, height, paddingObject, relativeTo) { + // Assuming percentage is number from 0 to 1 + if (paddingObject.units === '%') { + switch (relativeTo) { + case 'width': + return width > 0 ? paddingObject.pfValue * width : 0; + case 'height': + return height > 0 ? paddingObject.pfValue * height : 0; + case 'average': + return width > 0 && height > 0 ? paddingObject.pfValue * (width + height) / 2 : 0; + case 'min': + return width > 0 && height > 0 ? width > height ? paddingObject.pfValue * height : paddingObject.pfValue * width : 0; + case 'max': + return width > 0 && height > 0 ? width > height ? paddingObject.pfValue * width : paddingObject.pfValue * height : 0; + default: + return 0; + } + } else if (paddingObject.units === 'px') { + return paddingObject.pfValue; + } else { + return 0; + } + } + var leftVal = min.width.left.value; + if (min.width.left.units === 'px' && min.width.val > 0) { + leftVal = leftVal * 100 / min.width.val; + } + var rightVal = min.width.right.value; + if (min.width.right.units === 'px' && min.width.val > 0) { + rightVal = rightVal * 100 / min.width.val; + } + var topVal = min.height.top.value; + if (min.height.top.units === 'px' && min.height.val > 0) { + topVal = topVal * 100 / min.height.val; + } + var bottomVal = min.height.bottom.value; + if (min.height.bottom.units === 'px' && min.height.val > 0) { + bottomVal = bottomVal * 100 / min.height.val; + } + var widthBiasDiffs = computeBiasValues(min.width.val - bb.w, leftVal, rightVal); + var diffLeft = widthBiasDiffs.biasDiff; + var diffRight = widthBiasDiffs.biasComplementDiff; + var heightBiasDiffs = computeBiasValues(min.height.val - bb.h, topVal, bottomVal); + var diffTop = heightBiasDiffs.biasDiff; + var diffBottom = heightBiasDiffs.biasComplementDiff; + _p.autoPadding = computePaddingValues(bb.w, bb.h, parent.pstyle('padding'), parent.pstyle('padding-relative-to').value); + _p.autoWidth = Math.max(bb.w, min.width.val); + pos.x = (-diffLeft + bb.x1 + bb.x2 + diffRight) / 2; + _p.autoHeight = Math.max(bb.h, min.height.val); + pos.y = (-diffTop + bb.y1 + bb.y2 + diffBottom) / 2; + } + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var _p = ele._private; + if (!_p.compoundBoundsClean || force) { + update(ele); + if (!cy.batching()) { + _p.compoundBoundsClean = true; + } + } + } + return this; +}; +var noninf = function noninf(x) { + if (x === Infinity || x === -Infinity) { + return 0; + } + return x; +}; +var updateBounds = function updateBounds(b, x1, y1, x2, y2) { + // don't update with zero area boxes + if (x2 - x1 === 0 || y2 - y1 === 0) { + return; + } + + // don't update with null dim + if (x1 == null || y1 == null || x2 == null || y2 == null) { + return; + } + b.x1 = x1 < b.x1 ? x1 : b.x1; + b.x2 = x2 > b.x2 ? x2 : b.x2; + b.y1 = y1 < b.y1 ? y1 : b.y1; + b.y2 = y2 > b.y2 ? y2 : b.y2; + b.w = b.x2 - b.x1; + b.h = b.y2 - b.y1; +}; +var updateBoundsFromBox = function updateBoundsFromBox(b, b2) { + if (b2 == null) { + return b; + } + return updateBounds(b, b2.x1, b2.y1, b2.x2, b2.y2); +}; +var prefixedProperty = function prefixedProperty(obj, field, prefix) { + return getPrefixedProperty(obj, field, prefix); +}; +var updateBoundsFromArrow = function updateBoundsFromArrow(bounds, ele, prefix) { + if (ele.cy().headless()) { + return; + } + var _p = ele._private; + var rstyle = _p.rstyle; + var halfArW = rstyle.arrowWidth / 2; + var arrowType = ele.pstyle(prefix + '-arrow-shape').value; + var x; + var y; + if (arrowType !== 'none') { + if (prefix === 'source') { + x = rstyle.srcX; + y = rstyle.srcY; + } else if (prefix === 'target') { + x = rstyle.tgtX; + y = rstyle.tgtY; + } else { + x = rstyle.midX; + y = rstyle.midY; + } + + // always store the individual arrow bounds + var bbs = _p.arrowBounds = _p.arrowBounds || {}; + var bb = bbs[prefix] = bbs[prefix] || {}; + bb.x1 = x - halfArW; + bb.y1 = y - halfArW; + bb.x2 = x + halfArW; + bb.y2 = y + halfArW; + bb.w = bb.x2 - bb.x1; + bb.h = bb.y2 - bb.y1; + expandBoundingBox(bb, 1); + updateBounds(bounds, bb.x1, bb.y1, bb.x2, bb.y2); + } +}; +var updateBoundsFromLabel = function updateBoundsFromLabel(bounds, ele, prefix) { + if (ele.cy().headless()) { + return; + } + var prefixDash; + if (prefix) { + prefixDash = prefix + '-'; + } else { + prefixDash = ''; + } + var _p = ele._private; + var rstyle = _p.rstyle; + var label = ele.pstyle(prefixDash + 'label').strValue; + if (label) { + var halign = ele.pstyle('text-halign'); + var valign = ele.pstyle('text-valign'); + var labelWidth = prefixedProperty(rstyle, 'labelWidth', prefix); + var labelHeight = prefixedProperty(rstyle, 'labelHeight', prefix); + var labelX = prefixedProperty(rstyle, 'labelX', prefix); + var labelY = prefixedProperty(rstyle, 'labelY', prefix); + var marginX = ele.pstyle(prefixDash + 'text-margin-x').pfValue; + var marginY = ele.pstyle(prefixDash + 'text-margin-y').pfValue; + var isEdge = ele.isEdge(); + var rotation = ele.pstyle(prefixDash + 'text-rotation'); + var outlineWidth = ele.pstyle('text-outline-width').pfValue; + var borderWidth = ele.pstyle('text-border-width').pfValue; + var halfBorderWidth = borderWidth / 2; + var padding = ele.pstyle('text-background-padding').pfValue; + var marginOfError = 2; // expand to work around browser dimension inaccuracies + + var lh = labelHeight; + var lw = labelWidth; + var lw_2 = lw / 2; + var lh_2 = lh / 2; + var lx1, lx2, ly1, ly2; + if (isEdge) { + lx1 = labelX - lw_2; + lx2 = labelX + lw_2; + ly1 = labelY - lh_2; + ly2 = labelY + lh_2; + } else { + switch (halign.value) { + case 'left': + lx1 = labelX - lw; + lx2 = labelX; + break; + case 'center': + lx1 = labelX - lw_2; + lx2 = labelX + lw_2; + break; + case 'right': + lx1 = labelX; + lx2 = labelX + lw; + break; + } + switch (valign.value) { + case 'top': + ly1 = labelY - lh; + ly2 = labelY; + break; + case 'center': + ly1 = labelY - lh_2; + ly2 = labelY + lh_2; + break; + case 'bottom': + ly1 = labelY; + ly2 = labelY + lh; + break; + } + } + + // shift by margin and expand by outline and border + lx1 += marginX - Math.max(outlineWidth, halfBorderWidth) - padding - marginOfError; + lx2 += marginX + Math.max(outlineWidth, halfBorderWidth) + padding + marginOfError; + ly1 += marginY - Math.max(outlineWidth, halfBorderWidth) - padding - marginOfError; + ly2 += marginY + Math.max(outlineWidth, halfBorderWidth) + padding + marginOfError; + + // always store the unrotated label bounds separately + var bbPrefix = prefix || 'main'; + var bbs = _p.labelBounds; + var bb = bbs[bbPrefix] = bbs[bbPrefix] || {}; + bb.x1 = lx1; + bb.y1 = ly1; + bb.x2 = lx2; + bb.y2 = ly2; + bb.w = lx2 - lx1; + bb.h = ly2 - ly1; + var isAutorotate = isEdge && rotation.strValue === 'autorotate'; + var isPfValue = rotation.pfValue != null && rotation.pfValue !== 0; + if (isAutorotate || isPfValue) { + var theta = isAutorotate ? prefixedProperty(_p.rstyle, 'labelAngle', prefix) : rotation.pfValue; + var cos = Math.cos(theta); + var sin = Math.sin(theta); + + // rotation point (default value for center-center) + var xo = (lx1 + lx2) / 2; + var yo = (ly1 + ly2) / 2; + if (!isEdge) { + switch (halign.value) { + case 'left': + xo = lx2; + break; + case 'right': + xo = lx1; + break; + } + switch (valign.value) { + case 'top': + yo = ly2; + break; + case 'bottom': + yo = ly1; + break; + } + } + var rotate = function rotate(x, y) { + x = x - xo; + y = y - yo; + return { + x: x * cos - y * sin + xo, + y: x * sin + y * cos + yo + }; + }; + var px1y1 = rotate(lx1, ly1); + var px1y2 = rotate(lx1, ly2); + var px2y1 = rotate(lx2, ly1); + var px2y2 = rotate(lx2, ly2); + lx1 = Math.min(px1y1.x, px1y2.x, px2y1.x, px2y2.x); + lx2 = Math.max(px1y1.x, px1y2.x, px2y1.x, px2y2.x); + ly1 = Math.min(px1y1.y, px1y2.y, px2y1.y, px2y2.y); + ly2 = Math.max(px1y1.y, px1y2.y, px2y1.y, px2y2.y); + } + var bbPrefixRot = bbPrefix + 'Rot'; + var bbRot = bbs[bbPrefixRot] = bbs[bbPrefixRot] || {}; + bbRot.x1 = lx1; + bbRot.y1 = ly1; + bbRot.x2 = lx2; + bbRot.y2 = ly2; + bbRot.w = lx2 - lx1; + bbRot.h = ly2 - ly1; + updateBounds(bounds, lx1, ly1, lx2, ly2); + updateBounds(_p.labelBounds.all, lx1, ly1, lx2, ly2); + } + return bounds; +}; +var updateBoundsFromOutline = function updateBoundsFromOutline(bounds, ele) { + if (ele.cy().headless()) { + return; + } + var outlineOpacity = ele.pstyle('outline-opacity').value; + var outlineWidth = ele.pstyle('outline-width').value; + if (outlineOpacity > 0 && outlineWidth > 0) { + var outlineOffset = ele.pstyle('outline-offset').value; + var nodeShape = ele.pstyle('shape').value; + var outlineSize = outlineWidth + outlineOffset; + var scaleX = (bounds.w + outlineSize * 2) / bounds.w; + var scaleY = (bounds.h + outlineSize * 2) / bounds.h; + var xOffset = 0; + var yOffset = 0; + if (["diamond", "pentagon", "round-triangle"].includes(nodeShape)) { + scaleX = (bounds.w + outlineSize * 2.4) / bounds.w; + yOffset = -outlineSize / 3.6; + } else if (["concave-hexagon", "rhomboid", "right-rhomboid"].includes(nodeShape)) { + scaleX = (bounds.w + outlineSize * 2.4) / bounds.w; + } else if (nodeShape === "star") { + scaleX = (bounds.w + outlineSize * 2.8) / bounds.w; + scaleY = (bounds.h + outlineSize * 2.6) / bounds.h; + yOffset = -outlineSize / 3.8; + } else if (nodeShape === "triangle") { + scaleX = (bounds.w + outlineSize * 2.8) / bounds.w; + scaleY = (bounds.h + outlineSize * 2.4) / bounds.h; + yOffset = -outlineSize / 1.4; + } else if (nodeShape === "vee") { + scaleX = (bounds.w + outlineSize * 4.4) / bounds.w; + scaleY = (bounds.h + outlineSize * 3.8) / bounds.h; + yOffset = -outlineSize * .5; + } + var hDelta = bounds.h * scaleY - bounds.h; + var wDelta = bounds.w * scaleX - bounds.w; + expandBoundingBoxSides(bounds, [Math.ceil(hDelta / 2), Math.ceil(wDelta / 2)]); + if (xOffset != 0 || yOffset !== 0) { + var oBounds = shiftBoundingBox(bounds, xOffset, yOffset); + updateBoundingBox(bounds, oBounds); + } + } +}; + +// get the bounding box of the elements (in raw model position) +var boundingBoxImpl = function boundingBoxImpl(ele, options) { + var cy = ele._private.cy; + var styleEnabled = cy.styleEnabled(); + var headless = cy.headless(); + var bounds = makeBoundingBox(); + var _p = ele._private; + var isNode = ele.isNode(); + var isEdge = ele.isEdge(); + var ex1, ex2, ey1, ey2; // extrema of body / lines + var x, y; // node pos + var rstyle = _p.rstyle; + var manualExpansion = isNode && styleEnabled ? ele.pstyle('bounds-expansion').pfValue : [0]; + + // must use `display` prop only, as reading `compound.width()` causes recursion + // (other factors like width values will be considered later in this function anyway) + var isDisplayed = function isDisplayed(ele) { + return ele.pstyle('display').value !== 'none'; + }; + var displayed = !styleEnabled || isDisplayed(ele) + + // must take into account connected nodes b/c of implicit edge hiding on display:none node + && (!isEdge || isDisplayed(ele.source()) && isDisplayed(ele.target())); + if (displayed) { + // displayed suffices, since we will find zero area eles anyway + var overlayOpacity = 0; + var overlayPadding = 0; + if (styleEnabled && options.includeOverlays) { + overlayOpacity = ele.pstyle('overlay-opacity').value; + if (overlayOpacity !== 0) { + overlayPadding = ele.pstyle('overlay-padding').value; + } + } + var underlayOpacity = 0; + var underlayPadding = 0; + if (styleEnabled && options.includeUnderlays) { + underlayOpacity = ele.pstyle('underlay-opacity').value; + if (underlayOpacity !== 0) { + underlayPadding = ele.pstyle('underlay-padding').value; + } + } + var padding = Math.max(overlayPadding, underlayPadding); + var w = 0; + var wHalf = 0; + if (styleEnabled) { + w = ele.pstyle('width').pfValue; + wHalf = w / 2; + } + if (isNode && options.includeNodes) { + var pos = ele.position(); + x = pos.x; + y = pos.y; + var _w = ele.outerWidth(); + var halfW = _w / 2; + var h = ele.outerHeight(); + var halfH = h / 2; + + // handle node dimensions + ///////////////////////// + + ex1 = x - halfW; + ex2 = x + halfW; + ey1 = y - halfH; + ey2 = y + halfH; + updateBounds(bounds, ex1, ey1, ex2, ey2); + if (styleEnabled && options.includeOutlines) { + updateBoundsFromOutline(bounds, ele); + } + } else if (isEdge && options.includeEdges) { + if (styleEnabled && !headless) { + var curveStyle = ele.pstyle('curve-style').strValue; + + // handle edge dimensions (rough box estimate) + ////////////////////////////////////////////// + + ex1 = Math.min(rstyle.srcX, rstyle.midX, rstyle.tgtX); + ex2 = Math.max(rstyle.srcX, rstyle.midX, rstyle.tgtX); + ey1 = Math.min(rstyle.srcY, rstyle.midY, rstyle.tgtY); + ey2 = Math.max(rstyle.srcY, rstyle.midY, rstyle.tgtY); + + // take into account edge width + ex1 -= wHalf; + ex2 += wHalf; + ey1 -= wHalf; + ey2 += wHalf; + updateBounds(bounds, ex1, ey1, ex2, ey2); + + // precise edges + //////////////// + + if (curveStyle === 'haystack') { + var hpts = rstyle.haystackPts; + if (hpts && hpts.length === 2) { + ex1 = hpts[0].x; + ey1 = hpts[0].y; + ex2 = hpts[1].x; + ey2 = hpts[1].y; + if (ex1 > ex2) { + var temp = ex1; + ex1 = ex2; + ex2 = temp; + } + if (ey1 > ey2) { + var _temp = ey1; + ey1 = ey2; + ey2 = _temp; + } + updateBounds(bounds, ex1 - wHalf, ey1 - wHalf, ex2 + wHalf, ey2 + wHalf); + } + } else if (curveStyle === 'bezier' || curveStyle === 'unbundled-bezier' || curveStyle === 'segments' || curveStyle === 'taxi') { + var pts; + switch (curveStyle) { + case 'bezier': + case 'unbundled-bezier': + pts = rstyle.bezierPts; + break; + case 'segments': + case 'taxi': + pts = rstyle.linePts; + break; + } + if (pts != null) { + for (var j = 0; j < pts.length; j++) { + var pt = pts[j]; + ex1 = pt.x - wHalf; + ex2 = pt.x + wHalf; + ey1 = pt.y - wHalf; + ey2 = pt.y + wHalf; + updateBounds(bounds, ex1, ey1, ex2, ey2); + } + } + } // bezier-like or segment-like edge + } else { + // headless or style disabled + + // fallback on source and target positions + ////////////////////////////////////////// + + var n1 = ele.source(); + var n1pos = n1.position(); + var n2 = ele.target(); + var n2pos = n2.position(); + ex1 = n1pos.x; + ex2 = n2pos.x; + ey1 = n1pos.y; + ey2 = n2pos.y; + if (ex1 > ex2) { + var _temp2 = ex1; + ex1 = ex2; + ex2 = _temp2; + } + if (ey1 > ey2) { + var _temp3 = ey1; + ey1 = ey2; + ey2 = _temp3; + } + + // take into account edge width + ex1 -= wHalf; + ex2 += wHalf; + ey1 -= wHalf; + ey2 += wHalf; + updateBounds(bounds, ex1, ey1, ex2, ey2); + } // headless or style disabled + } // edges + + // handle edge arrow size + ///////////////////////// + + if (styleEnabled && options.includeEdges && isEdge) { + updateBoundsFromArrow(bounds, ele, 'mid-source'); + updateBoundsFromArrow(bounds, ele, 'mid-target'); + updateBoundsFromArrow(bounds, ele, 'source'); + updateBoundsFromArrow(bounds, ele, 'target'); + } + + // ghost + //////// + + if (styleEnabled) { + var ghost = ele.pstyle('ghost').value === 'yes'; + if (ghost) { + var gx = ele.pstyle('ghost-offset-x').pfValue; + var gy = ele.pstyle('ghost-offset-y').pfValue; + updateBounds(bounds, bounds.x1 + gx, bounds.y1 + gy, bounds.x2 + gx, bounds.y2 + gy); + } + } + + // always store the body bounds separately from the labels + var bbBody = _p.bodyBounds = _p.bodyBounds || {}; + assignBoundingBox(bbBody, bounds); + expandBoundingBoxSides(bbBody, manualExpansion); + expandBoundingBox(bbBody, 1); // expand to work around browser dimension inaccuracies + + // overlay + ////////// + + if (styleEnabled) { + ex1 = bounds.x1; + ex2 = bounds.x2; + ey1 = bounds.y1; + ey2 = bounds.y2; + updateBounds(bounds, ex1 - padding, ey1 - padding, ex2 + padding, ey2 + padding); + } + + // always store the body bounds separately from the labels + var bbOverlay = _p.overlayBounds = _p.overlayBounds || {}; + assignBoundingBox(bbOverlay, bounds); + expandBoundingBoxSides(bbOverlay, manualExpansion); + expandBoundingBox(bbOverlay, 1); // expand to work around browser dimension inaccuracies + + // handle label dimensions + ////////////////////////// + + var bbLabels = _p.labelBounds = _p.labelBounds || {}; + if (bbLabels.all != null) { + clearBoundingBox(bbLabels.all); + } else { + bbLabels.all = makeBoundingBox(); + } + if (styleEnabled && options.includeLabels) { + if (options.includeMainLabels) { + updateBoundsFromLabel(bounds, ele, null); + } + if (isEdge) { + if (options.includeSourceLabels) { + updateBoundsFromLabel(bounds, ele, 'source'); + } + if (options.includeTargetLabels) { + updateBoundsFromLabel(bounds, ele, 'target'); + } + } + } // style enabled for labels + } // if displayed + + bounds.x1 = noninf(bounds.x1); + bounds.y1 = noninf(bounds.y1); + bounds.x2 = noninf(bounds.x2); + bounds.y2 = noninf(bounds.y2); + bounds.w = noninf(bounds.x2 - bounds.x1); + bounds.h = noninf(bounds.y2 - bounds.y1); + if (bounds.w > 0 && bounds.h > 0 && displayed) { + expandBoundingBoxSides(bounds, manualExpansion); + + // expand bounds by 1 because antialiasing can increase the visual/effective size by 1 on all sides + expandBoundingBox(bounds, 1); + } + return bounds; +}; +var getKey = function getKey(opts) { + var i = 0; + var tf = function tf(val) { + return (val ? 1 : 0) << i++; + }; + var key = 0; + key += tf(opts.incudeNodes); + key += tf(opts.includeEdges); + key += tf(opts.includeLabels); + key += tf(opts.includeMainLabels); + key += tf(opts.includeSourceLabels); + key += tf(opts.includeTargetLabels); + key += tf(opts.includeOverlays); + key += tf(opts.includeOutlines); + return key; +}; +var getBoundingBoxPosKey = function getBoundingBoxPosKey(ele) { + if (ele.isEdge()) { + var p1 = ele.source().position(); + var p2 = ele.target().position(); + var r = function r(x) { + return Math.round(x); + }; + return hashIntsArray([r(p1.x), r(p1.y), r(p2.x), r(p2.y)]); + } else { + return 0; + } +}; +var cachedBoundingBoxImpl = function cachedBoundingBoxImpl(ele, opts) { + var _p = ele._private; + var bb; + var isEdge = ele.isEdge(); + var key = opts == null ? defBbOptsKey : getKey(opts); + var usingDefOpts = key === defBbOptsKey; + var currPosKey = getBoundingBoxPosKey(ele); + var isPosKeySame = _p.bbCachePosKey === currPosKey; + var useCache = opts.useCache && isPosKeySame; + var isDirty = function isDirty(ele) { + return ele._private.bbCache == null || ele._private.styleDirty; + }; + var needRecalc = !useCache || isDirty(ele) || isEdge && isDirty(ele.source()) || isDirty(ele.target()); + if (needRecalc) { + if (!isPosKeySame) { + ele.recalculateRenderedStyle(useCache); + } + bb = boundingBoxImpl(ele, defBbOpts); + _p.bbCache = bb; + _p.bbCachePosKey = currPosKey; + } else { + bb = _p.bbCache; + } + + // not using def opts => need to build up bb from combination of sub bbs + if (!usingDefOpts) { + var isNode = ele.isNode(); + bb = makeBoundingBox(); + if (opts.includeNodes && isNode || opts.includeEdges && !isNode) { + if (opts.includeOverlays) { + updateBoundsFromBox(bb, _p.overlayBounds); + } else { + updateBoundsFromBox(bb, _p.bodyBounds); + } + } + if (opts.includeLabels) { + if (opts.includeMainLabels && (!isEdge || opts.includeSourceLabels && opts.includeTargetLabels)) { + updateBoundsFromBox(bb, _p.labelBounds.all); + } else { + if (opts.includeMainLabels) { + updateBoundsFromBox(bb, _p.labelBounds.mainRot); + } + if (opts.includeSourceLabels) { + updateBoundsFromBox(bb, _p.labelBounds.sourceRot); + } + if (opts.includeTargetLabels) { + updateBoundsFromBox(bb, _p.labelBounds.targetRot); + } + } + } + bb.w = bb.x2 - bb.x1; + bb.h = bb.y2 - bb.y1; + } + return bb; +}; +var defBbOpts = { + includeNodes: true, + includeEdges: true, + includeLabels: true, + includeMainLabels: true, + includeSourceLabels: true, + includeTargetLabels: true, + includeOverlays: true, + includeUnderlays: true, + includeOutlines: true, + useCache: true +}; +var defBbOptsKey = getKey(defBbOpts); +var filledBbOpts = defaults$g(defBbOpts); +elesfn$b.boundingBox = function (options) { + var bounds; + + // the main usecase is ele.boundingBox() for a single element with no/def options + // specified s.t. the cache is used, so check for this case to make it faster by + // avoiding the overhead of the rest of the function + if (this.length === 1 && this[0]._private.bbCache != null && !this[0]._private.styleDirty && (options === undefined || options.useCache === undefined || options.useCache === true)) { + if (options === undefined) { + options = defBbOpts; + } else { + options = filledBbOpts(options); + } + bounds = cachedBoundingBoxImpl(this[0], options); + } else { + bounds = makeBoundingBox(); + options = options || defBbOpts; + var opts = filledBbOpts(options); + var eles = this; + var cy = eles.cy(); + var styleEnabled = cy.styleEnabled(); + if (styleEnabled) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var _p = ele._private; + var currPosKey = getBoundingBoxPosKey(ele); + var isPosKeySame = _p.bbCachePosKey === currPosKey; + var useCache = opts.useCache && isPosKeySame && !_p.styleDirty; + ele.recalculateRenderedStyle(useCache); + } + } + this.updateCompoundBounds(!options.useCache); + for (var _i = 0; _i < eles.length; _i++) { + var _ele = eles[_i]; + updateBoundsFromBox(bounds, cachedBoundingBoxImpl(_ele, opts)); + } + } + bounds.x1 = noninf(bounds.x1); + bounds.y1 = noninf(bounds.y1); + bounds.x2 = noninf(bounds.x2); + bounds.y2 = noninf(bounds.y2); + bounds.w = noninf(bounds.x2 - bounds.x1); + bounds.h = noninf(bounds.y2 - bounds.y1); + return bounds; +}; +elesfn$b.dirtyBoundingBoxCache = function () { + for (var i = 0; i < this.length; i++) { + var _p = this[i]._private; + _p.bbCache = null; + _p.bbCachePosKey = null; + _p.bodyBounds = null; + _p.overlayBounds = null; + _p.labelBounds.all = null; + _p.labelBounds.source = null; + _p.labelBounds.target = null; + _p.labelBounds.main = null; + _p.labelBounds.sourceRot = null; + _p.labelBounds.targetRot = null; + _p.labelBounds.mainRot = null; + _p.arrowBounds.source = null; + _p.arrowBounds.target = null; + _p.arrowBounds['mid-source'] = null; + _p.arrowBounds['mid-target'] = null; + } + this.emitAndNotify('bounds'); + return this; +}; + +// private helper to get bounding box for custom node positions +// - good for perf in certain cases but currently requires dirtying the rendered style +// - would be better to not modify the nodes but the nodes are read directly everywhere in the renderer... +// - try to use for only things like discrete layouts where the node position would change anyway +elesfn$b.boundingBoxAt = function (fn) { + var nodes = this.nodes(); + var cy = this.cy(); + var hasCompoundNodes = cy.hasCompoundNodes(); + var parents = cy.collection(); + if (hasCompoundNodes) { + parents = nodes.filter(function (node) { + return node.isParent(); + }); + nodes = nodes.not(parents); + } + if (plainObject(fn)) { + var obj = fn; + fn = function fn() { + return obj; + }; + } + var storeOldPos = function storeOldPos(node, i) { + return node._private.bbAtOldPos = fn(node, i); + }; + var getOldPos = function getOldPos(node) { + return node._private.bbAtOldPos; + }; + cy.startBatch(); + nodes.forEach(storeOldPos).silentPositions(fn); + if (hasCompoundNodes) { + parents.dirtyCompoundBoundsCache(); + parents.dirtyBoundingBoxCache(); + parents.updateCompoundBounds(true); // force update b/c we're inside a batch cycle + } + + var bb = copyBoundingBox(this.boundingBox({ + useCache: false + })); + nodes.silentPositions(getOldPos); + if (hasCompoundNodes) { + parents.dirtyCompoundBoundsCache(); + parents.dirtyBoundingBoxCache(); + parents.updateCompoundBounds(true); // force update b/c we're inside a batch cycle + } + + cy.endBatch(); + return bb; +}; +fn$3.boundingbox = fn$3.bb = fn$3.boundingBox; +fn$3.renderedBoundingbox = fn$3.renderedBoundingBox; +var bounds = elesfn$b; + +var fn$2, elesfn$a; +fn$2 = elesfn$a = {}; +var defineDimFns = function defineDimFns(opts) { + opts.uppercaseName = capitalize(opts.name); + opts.autoName = 'auto' + opts.uppercaseName; + opts.labelName = 'label' + opts.uppercaseName; + opts.outerName = 'outer' + opts.uppercaseName; + opts.uppercaseOuterName = capitalize(opts.outerName); + fn$2[opts.name] = function dimImpl() { + var ele = this[0]; + var _p = ele._private; + var cy = _p.cy; + var styleEnabled = cy._private.styleEnabled; + if (ele) { + if (styleEnabled) { + if (ele.isParent()) { + ele.updateCompoundBounds(); + return _p[opts.autoName] || 0; + } + var d = ele.pstyle(opts.name); + switch (d.strValue) { + case 'label': + ele.recalculateRenderedStyle(); + return _p.rstyle[opts.labelName] || 0; + default: + return d.pfValue; + } + } else { + return 1; + } + } + }; + fn$2['outer' + opts.uppercaseName] = function outerDimImpl() { + var ele = this[0]; + var _p = ele._private; + var cy = _p.cy; + var styleEnabled = cy._private.styleEnabled; + if (ele) { + if (styleEnabled) { + var dim = ele[opts.name](); + var border = ele.pstyle('border-width').pfValue; // n.b. 1/2 each side + var padding = 2 * ele.padding(); + return dim + border + padding; + } else { + return 1; + } + } + }; + fn$2['rendered' + opts.uppercaseName] = function renderedDimImpl() { + var ele = this[0]; + if (ele) { + var d = ele[opts.name](); + return d * this.cy().zoom(); + } + }; + fn$2['rendered' + opts.uppercaseOuterName] = function renderedOuterDimImpl() { + var ele = this[0]; + if (ele) { + var od = ele[opts.outerName](); + return od * this.cy().zoom(); + } + }; +}; +defineDimFns({ + name: 'width' +}); +defineDimFns({ + name: 'height' +}); +elesfn$a.padding = function () { + var ele = this[0]; + var _p = ele._private; + if (ele.isParent()) { + ele.updateCompoundBounds(); + if (_p.autoPadding !== undefined) { + return _p.autoPadding; + } else { + return ele.pstyle('padding').pfValue; + } + } else { + return ele.pstyle('padding').pfValue; + } +}; +elesfn$a.paddedHeight = function () { + var ele = this[0]; + return ele.height() + 2 * ele.padding(); +}; +elesfn$a.paddedWidth = function () { + var ele = this[0]; + return ele.width() + 2 * ele.padding(); +}; +var widthHeight = elesfn$a; + +var ifEdge = function ifEdge(ele, getValue) { + if (ele.isEdge()) { + return getValue(ele); + } +}; +var ifEdgeRenderedPosition = function ifEdgeRenderedPosition(ele, getPoint) { + if (ele.isEdge()) { + var cy = ele.cy(); + return modelToRenderedPosition(getPoint(ele), cy.zoom(), cy.pan()); + } +}; +var ifEdgeRenderedPositions = function ifEdgeRenderedPositions(ele, getPoints) { + if (ele.isEdge()) { + var cy = ele.cy(); + var pan = cy.pan(); + var zoom = cy.zoom(); + return getPoints(ele).map(function (p) { + return modelToRenderedPosition(p, zoom, pan); + }); + } +}; +var controlPoints = function controlPoints(ele) { + return ele.renderer().getControlPoints(ele); +}; +var segmentPoints = function segmentPoints(ele) { + return ele.renderer().getSegmentPoints(ele); +}; +var sourceEndpoint = function sourceEndpoint(ele) { + return ele.renderer().getSourceEndpoint(ele); +}; +var targetEndpoint = function targetEndpoint(ele) { + return ele.renderer().getTargetEndpoint(ele); +}; +var midpoint = function midpoint(ele) { + return ele.renderer().getEdgeMidpoint(ele); +}; +var pts = { + controlPoints: { + get: controlPoints, + mult: true + }, + segmentPoints: { + get: segmentPoints, + mult: true + }, + sourceEndpoint: { + get: sourceEndpoint + }, + targetEndpoint: { + get: targetEndpoint + }, + midpoint: { + get: midpoint + } +}; +var renderedName = function renderedName(name) { + return 'rendered' + name[0].toUpperCase() + name.substr(1); +}; +var edgePoints = Object.keys(pts).reduce(function (obj, name) { + var spec = pts[name]; + var rName = renderedName(name); + obj[name] = function () { + return ifEdge(this, spec.get); + }; + if (spec.mult) { + obj[rName] = function () { + return ifEdgeRenderedPositions(this, spec.get); + }; + } else { + obj[rName] = function () { + return ifEdgeRenderedPosition(this, spec.get); + }; + } + return obj; +}, {}); + +var dimensions = extend({}, position, bounds, widthHeight, edgePoints); + +/*! +Event object based on jQuery events, MIT license + +https://jquery.org/license/ +https://tldrlegal.com/license/mit-license +https://github.com/jquery/jquery/blob/master/src/event.js +*/ + +var Event = function Event(src, props) { + this.recycle(src, props); +}; +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +Event.prototype = { + instanceString: function instanceString() { + return 'event'; + }, + recycle: function recycle(src, props) { + this.isImmediatePropagationStopped = this.isPropagationStopped = this.isDefaultPrevented = returnFalse; + if (src != null && src.preventDefault) { + // Browser Event object + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented ? returnTrue : returnFalse; + } else if (src != null && src.type) { + // Plain object containing all event details + props = src; + } else { + // Event string + this.type = src; + } + + // Put explicitly provided properties onto the event object + if (props != null) { + // more efficient to manually copy fields we use + this.originalEvent = props.originalEvent; + this.type = props.type != null ? props.type : this.type; + this.cy = props.cy; + this.target = props.target; + this.position = props.position; + this.renderedPosition = props.renderedPosition; + this.namespace = props.namespace; + this.layout = props.layout; + } + if (this.cy != null && this.position != null && this.renderedPosition == null) { + // create a rendered position based on the passed position + var pos = this.position; + var zoom = this.cy.zoom(); + var pan = this.cy.pan(); + this.renderedPosition = { + x: pos.x * zoom + pan.x, + y: pos.y * zoom + pan.y + }; + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + }, + preventDefault: function preventDefault() { + this.isDefaultPrevented = returnTrue; + var e = this.originalEvent; + if (!e) { + return; + } + + // if preventDefault exists run it on the original event + if (e.preventDefault) { + e.preventDefault(); + } + }, + stopPropagation: function stopPropagation() { + this.isPropagationStopped = returnTrue; + var e = this.originalEvent; + if (!e) { + return; + } + + // if stopPropagation exists run it on the original event + if (e.stopPropagation) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function stopImmediatePropagation() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +var eventRegex = /^([^.]+)(\.(?:[^.]+))?$/; // regex for matching event strings (e.g. "click.namespace") +var universalNamespace = '.*'; // matches as if no namespace specified and prevents users from unbinding accidentally + +var defaults$8 = { + qualifierCompare: function qualifierCompare(q1, q2) { + return q1 === q2; + }, + eventMatches: function eventMatches( /*context, listener, eventObj*/ + ) { + return true; + }, + addEventFields: function addEventFields( /*context, evt*/ + ) {}, + callbackContext: function callbackContext(context /*, listener, eventObj*/) { + return context; + }, + beforeEmit: function beforeEmit( /* context, listener, eventObj */ + ) {}, + afterEmit: function afterEmit( /* context, listener, eventObj */ + ) {}, + bubble: function bubble( /*context*/ + ) { + return false; + }, + parent: function parent( /*context*/ + ) { + return null; + }, + context: null +}; +var defaultsKeys = Object.keys(defaults$8); +var emptyOpts = {}; +function Emitter() { + var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : emptyOpts; + var context = arguments.length > 1 ? arguments[1] : undefined; + // micro-optimisation vs Object.assign() -- reduces Element instantiation time + for (var i = 0; i < defaultsKeys.length; i++) { + var key = defaultsKeys[i]; + this[key] = opts[key] || defaults$8[key]; + } + this.context = context || this.context; + this.listeners = []; + this.emitting = 0; +} +var p = Emitter.prototype; +var forEachEvent = function forEachEvent(self, handler, events, qualifier, callback, conf, confOverrides) { + if (fn$6(qualifier)) { + callback = qualifier; + qualifier = null; + } + if (confOverrides) { + if (conf == null) { + conf = confOverrides; + } else { + conf = extend({}, conf, confOverrides); + } + } + var eventList = array(events) ? events : events.split(/\s+/); + for (var i = 0; i < eventList.length; i++) { + var evt = eventList[i]; + if (emptyString(evt)) { + continue; + } + var match = evt.match(eventRegex); // type[.namespace] + + if (match) { + var type = match[1]; + var namespace = match[2] ? match[2] : null; + var ret = handler(self, evt, type, namespace, qualifier, callback, conf); + if (ret === false) { + break; + } // allow exiting early + } + } +}; + +var makeEventObj = function makeEventObj(self, obj) { + self.addEventFields(self.context, obj); + return new Event(obj.type, obj); +}; +var forEachEventObj = function forEachEventObj(self, handler, events) { + if (event(events)) { + handler(self, events); + return; + } else if (plainObject(events)) { + handler(self, makeEventObj(self, events)); + return; + } + var eventList = array(events) ? events : events.split(/\s+/); + for (var i = 0; i < eventList.length; i++) { + var evt = eventList[i]; + if (emptyString(evt)) { + continue; + } + var match = evt.match(eventRegex); // type[.namespace] + + if (match) { + var type = match[1]; + var namespace = match[2] ? match[2] : null; + var eventObj = makeEventObj(self, { + type: type, + namespace: namespace, + target: self.context + }); + handler(self, eventObj); + } + } +}; +p.on = p.addListener = function (events, qualifier, callback, conf, confOverrides) { + forEachEvent(this, function (self, event, type, namespace, qualifier, callback, conf) { + if (fn$6(callback)) { + self.listeners.push({ + event: event, + // full event string + callback: callback, + // callback to run + type: type, + // the event type (e.g. 'click') + namespace: namespace, + // the event namespace (e.g. ".foo") + qualifier: qualifier, + // a restriction on whether to match this emitter + conf: conf // additional configuration + }); + } + }, events, qualifier, callback, conf, confOverrides); + return this; +}; +p.one = function (events, qualifier, callback, conf) { + return this.on(events, qualifier, callback, conf, { + one: true + }); +}; +p.removeListener = p.off = function (events, qualifier, callback, conf) { + var _this = this; + if (this.emitting !== 0) { + this.listeners = copyArray(this.listeners); + } + var listeners = this.listeners; + var _loop = function _loop(i) { + var listener = listeners[i]; + forEachEvent(_this, function (self, event, type, namespace, qualifier, callback /*, conf*/) { + if ((listener.type === type || events === '*') && (!namespace && listener.namespace !== '.*' || listener.namespace === namespace) && (!qualifier || self.qualifierCompare(listener.qualifier, qualifier)) && (!callback || listener.callback === callback)) { + listeners.splice(i, 1); + return false; + } + }, events, qualifier, callback, conf); + }; + for (var i = listeners.length - 1; i >= 0; i--) { + _loop(i); + } + return this; +}; +p.removeAllListeners = function () { + return this.removeListener('*'); +}; +p.emit = p.trigger = function (events, extraParams, manualCallback) { + var listeners = this.listeners; + var numListenersBeforeEmit = listeners.length; + this.emitting++; + if (!array(extraParams)) { + extraParams = [extraParams]; + } + forEachEventObj(this, function (self, eventObj) { + if (manualCallback != null) { + listeners = [{ + event: eventObj.event, + type: eventObj.type, + namespace: eventObj.namespace, + callback: manualCallback + }]; + numListenersBeforeEmit = listeners.length; + } + var _loop2 = function _loop2(i) { + var listener = listeners[i]; + if (listener.type === eventObj.type && (!listener.namespace || listener.namespace === eventObj.namespace || listener.namespace === universalNamespace) && self.eventMatches(self.context, listener, eventObj)) { + var args = [eventObj]; + if (extraParams != null) { + push(args, extraParams); + } + self.beforeEmit(self.context, listener, eventObj); + if (listener.conf && listener.conf.one) { + self.listeners = self.listeners.filter(function (l) { + return l !== listener; + }); + } + var context = self.callbackContext(self.context, listener, eventObj); + var ret = listener.callback.apply(context, args); + self.afterEmit(self.context, listener, eventObj); + if (ret === false) { + eventObj.stopPropagation(); + eventObj.preventDefault(); + } + } // if listener matches + }; + for (var i = 0; i < numListenersBeforeEmit; i++) { + _loop2(i); + } // for listener + + if (self.bubble(self.context) && !eventObj.isPropagationStopped()) { + self.parent(self.context).emit(eventObj, extraParams); + } + }, events); + this.emitting--; + return this; +}; + +var emitterOptions$1 = { + qualifierCompare: function qualifierCompare(selector1, selector2) { + if (selector1 == null || selector2 == null) { + return selector1 == null && selector2 == null; + } else { + return selector1.sameText(selector2); + } + }, + eventMatches: function eventMatches(ele, listener, eventObj) { + var selector = listener.qualifier; + if (selector != null) { + return ele !== eventObj.target && element(eventObj.target) && selector.matches(eventObj.target); + } + return true; + }, + addEventFields: function addEventFields(ele, evt) { + evt.cy = ele.cy(); + evt.target = ele; + }, + callbackContext: function callbackContext(ele, listener, eventObj) { + return listener.qualifier != null ? eventObj.target : ele; + }, + beforeEmit: function beforeEmit(context, listener /*, eventObj*/) { + if (listener.conf && listener.conf.once) { + listener.conf.onceCollection.removeListener(listener.event, listener.qualifier, listener.callback); + } + }, + bubble: function bubble() { + return true; + }, + parent: function parent(ele) { + return ele.isChild() ? ele.parent() : ele.cy(); + } +}; +var argSelector$1 = function argSelector(arg) { + if (string(arg)) { + return new Selector(arg); + } else { + return arg; + } +}; +var elesfn$9 = { + createEmitter: function createEmitter() { + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var _p = ele._private; + if (!_p.emitter) { + _p.emitter = new Emitter(emitterOptions$1, ele); + } + } + return this; + }, + emitter: function emitter() { + return this._private.emitter; + }, + on: function on(events, selector, callback) { + var argSel = argSelector$1(selector); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + ele.emitter().on(events, argSel, callback); + } + return this; + }, + removeListener: function removeListener(events, selector, callback) { + var argSel = argSelector$1(selector); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + ele.emitter().removeListener(events, argSel, callback); + } + return this; + }, + removeAllListeners: function removeAllListeners() { + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + ele.emitter().removeAllListeners(); + } + return this; + }, + one: function one(events, selector, callback) { + var argSel = argSelector$1(selector); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + ele.emitter().one(events, argSel, callback); + } + return this; + }, + once: function once(events, selector, callback) { + var argSel = argSelector$1(selector); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + ele.emitter().on(events, argSel, callback, { + once: true, + onceCollection: this + }); + } + }, + emit: function emit(events, extraParams) { + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + ele.emitter().emit(events, extraParams); + } + return this; + }, + emitAndNotify: function emitAndNotify(event, extraParams) { + // for internal use only + if (this.length === 0) { + return; + } // empty collections don't need to notify anything + + // notify renderer + this.cy().notify(event, this); + this.emit(event, extraParams); + return this; + } +}; +define.eventAliasesOn(elesfn$9); + +var elesfn$8 = { + nodes: function nodes(selector) { + return this.filter(function (ele) { + return ele.isNode(); + }).filter(selector); + }, + edges: function edges(selector) { + return this.filter(function (ele) { + return ele.isEdge(); + }).filter(selector); + }, + // internal helper to get nodes and edges as separate collections with single iteration over elements + byGroup: function byGroup() { + var nodes = this.spawn(); + var edges = this.spawn(); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + if (ele.isNode()) { + nodes.push(ele); + } else { + edges.push(ele); + } + } + return { + nodes: nodes, + edges: edges + }; + }, + filter: function filter(_filter, thisArg) { + if (_filter === undefined) { + // check this first b/c it's the most common/performant case + return this; + } else if (string(_filter) || elementOrCollection(_filter)) { + return new Selector(_filter).filter(this); + } else if (fn$6(_filter)) { + var filterEles = this.spawn(); + var eles = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var include = thisArg ? _filter.apply(thisArg, [ele, i, eles]) : _filter(ele, i, eles); + if (include) { + filterEles.push(ele); + } + } + return filterEles; + } + return this.spawn(); // if not handled by above, give 'em an empty collection + }, + + not: function not(toRemove) { + if (!toRemove) { + return this; + } else { + if (string(toRemove)) { + toRemove = this.filter(toRemove); + } + var elements = this.spawn(); + for (var i = 0; i < this.length; i++) { + var element = this[i]; + var remove = toRemove.has(element); + if (!remove) { + elements.push(element); + } + } + return elements; + } + }, + absoluteComplement: function absoluteComplement() { + var cy = this.cy(); + return cy.mutableElements().not(this); + }, + intersect: function intersect(other) { + // if a selector is specified, then filter by it instead + if (string(other)) { + var selector = other; + return this.filter(selector); + } + var elements = this.spawn(); + var col1 = this; + var col2 = other; + var col1Smaller = this.length < other.length; + var colS = col1Smaller ? col1 : col2; + var colL = col1Smaller ? col2 : col1; + for (var i = 0; i < colS.length; i++) { + var ele = colS[i]; + if (colL.has(ele)) { + elements.push(ele); + } + } + return elements; + }, + xor: function xor(other) { + var cy = this._private.cy; + if (string(other)) { + other = cy.$(other); + } + var elements = this.spawn(); + var col1 = this; + var col2 = other; + var add = function add(col, other) { + for (var i = 0; i < col.length; i++) { + var ele = col[i]; + var id = ele._private.data.id; + var inOther = other.hasElementWithId(id); + if (!inOther) { + elements.push(ele); + } + } + }; + add(col1, col2); + add(col2, col1); + return elements; + }, + diff: function diff(other) { + var cy = this._private.cy; + if (string(other)) { + other = cy.$(other); + } + var left = this.spawn(); + var right = this.spawn(); + var both = this.spawn(); + var col1 = this; + var col2 = other; + var add = function add(col, other, retEles) { + for (var i = 0; i < col.length; i++) { + var ele = col[i]; + var id = ele._private.data.id; + var inOther = other.hasElementWithId(id); + if (inOther) { + both.merge(ele); + } else { + retEles.push(ele); + } + } + }; + add(col1, col2, left); + add(col2, col1, right); + return { + left: left, + right: right, + both: both + }; + }, + add: function add(toAdd) { + var cy = this._private.cy; + if (!toAdd) { + return this; + } + if (string(toAdd)) { + var selector = toAdd; + toAdd = cy.mutableElements().filter(selector); + } + var elements = this.spawnSelf(); + for (var i = 0; i < toAdd.length; i++) { + var ele = toAdd[i]; + var add = !this.has(ele); + if (add) { + elements.push(ele); + } + } + return elements; + }, + // in place merge on calling collection + merge: function merge(toAdd) { + var _p = this._private; + var cy = _p.cy; + if (!toAdd) { + return this; + } + if (toAdd && string(toAdd)) { + var selector = toAdd; + toAdd = cy.mutableElements().filter(selector); + } + var map = _p.map; + for (var i = 0; i < toAdd.length; i++) { + var toAddEle = toAdd[i]; + var id = toAddEle._private.data.id; + var add = !map.has(id); + if (add) { + var index = this.length++; + this[index] = toAddEle; + map.set(id, { + ele: toAddEle, + index: index + }); + } + } + return this; // chaining + }, + + unmergeAt: function unmergeAt(i) { + var ele = this[i]; + var id = ele.id(); + var _p = this._private; + var map = _p.map; + + // remove ele + this[i] = undefined; + map["delete"](id); + var unmergedLastEle = i === this.length - 1; + + // replace empty spot with last ele in collection + if (this.length > 1 && !unmergedLastEle) { + var lastEleI = this.length - 1; + var lastEle = this[lastEleI]; + var lastEleId = lastEle._private.data.id; + this[lastEleI] = undefined; + this[i] = lastEle; + map.set(lastEleId, { + ele: lastEle, + index: i + }); + } + + // the collection is now 1 ele smaller + this.length--; + return this; + }, + // remove single ele in place in calling collection + unmergeOne: function unmergeOne(ele) { + ele = ele[0]; + var _p = this._private; + var id = ele._private.data.id; + var map = _p.map; + var entry = map.get(id); + if (!entry) { + return this; // no need to remove + } + + var i = entry.index; + this.unmergeAt(i); + return this; + }, + // remove eles in place on calling collection + unmerge: function unmerge(toRemove) { + var cy = this._private.cy; + if (!toRemove) { + return this; + } + if (toRemove && string(toRemove)) { + var selector = toRemove; + toRemove = cy.mutableElements().filter(selector); + } + for (var i = 0; i < toRemove.length; i++) { + this.unmergeOne(toRemove[i]); + } + return this; // chaining + }, + + unmergeBy: function unmergeBy(toRmFn) { + for (var i = this.length - 1; i >= 0; i--) { + var ele = this[i]; + if (toRmFn(ele)) { + this.unmergeAt(i); + } + } + return this; + }, + map: function map(mapFn, thisArg) { + var arr = []; + var eles = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var ret = thisArg ? mapFn.apply(thisArg, [ele, i, eles]) : mapFn(ele, i, eles); + arr.push(ret); + } + return arr; + }, + reduce: function reduce(fn, initialValue) { + var val = initialValue; + var eles = this; + for (var i = 0; i < eles.length; i++) { + val = fn(val, eles[i], i, eles); + } + return val; + }, + max: function max(valFn, thisArg) { + var max = -Infinity; + var maxEle; + var eles = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var val = thisArg ? valFn.apply(thisArg, [ele, i, eles]) : valFn(ele, i, eles); + if (val > max) { + max = val; + maxEle = ele; + } + } + return { + value: max, + ele: maxEle + }; + }, + min: function min(valFn, thisArg) { + var min = Infinity; + var minEle; + var eles = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var val = thisArg ? valFn.apply(thisArg, [ele, i, eles]) : valFn(ele, i, eles); + if (val < min) { + min = val; + minEle = ele; + } + } + return { + value: min, + ele: minEle + }; + } +}; + +// aliases +var fn$1 = elesfn$8; +fn$1['u'] = fn$1['|'] = fn$1['+'] = fn$1.union = fn$1.or = fn$1.add; +fn$1['\\'] = fn$1['!'] = fn$1['-'] = fn$1.difference = fn$1.relativeComplement = fn$1.subtract = fn$1.not; +fn$1['n'] = fn$1['&'] = fn$1['.'] = fn$1.and = fn$1.intersection = fn$1.intersect; +fn$1['^'] = fn$1['(+)'] = fn$1['(-)'] = fn$1.symmetricDifference = fn$1.symdiff = fn$1.xor; +fn$1.fnFilter = fn$1.filterFn = fn$1.stdFilter = fn$1.filter; +fn$1.complement = fn$1.abscomp = fn$1.absoluteComplement; + +var elesfn$7 = { + isNode: function isNode() { + return this.group() === 'nodes'; + }, + isEdge: function isEdge() { + return this.group() === 'edges'; + }, + isLoop: function isLoop() { + return this.isEdge() && this.source()[0] === this.target()[0]; + }, + isSimple: function isSimple() { + return this.isEdge() && this.source()[0] !== this.target()[0]; + }, + group: function group() { + var ele = this[0]; + if (ele) { + return ele._private.group; + } + } +}; + +/** + * Elements are drawn in a specific order based on compound depth (low to high), the element type (nodes above edges), + * and z-index (low to high). These styles affect how this applies: + * + * z-compound-depth: May be `bottom | orphan | auto | top`. The first drawn is `bottom`, then `orphan` which is the + * same depth as the root of the compound graph, followed by the default value `auto` which draws in order from + * root to leaves of the compound graph. The last drawn is `top`. + * z-index-compare: May be `auto | manual`. The default value is `auto` which always draws edges under nodes. + * `manual` ignores this convention and draws based on the `z-index` value setting. + * z-index: An integer value that affects the relative draw order of elements. In general, an element with a higher + * `z-index` will be drawn on top of an element with a lower `z-index`. + */ +var zIndexSort = function zIndexSort(a, b) { + var cy = a.cy(); + var hasCompoundNodes = cy.hasCompoundNodes(); + function getDepth(ele) { + var style = ele.pstyle('z-compound-depth'); + if (style.value === 'auto') { + return hasCompoundNodes ? ele.zDepth() : 0; + } else if (style.value === 'bottom') { + return -1; + } else if (style.value === 'top') { + return MAX_INT$1; + } + // 'orphan' + return 0; + } + var depthDiff = getDepth(a) - getDepth(b); + if (depthDiff !== 0) { + return depthDiff; + } + function getEleDepth(ele) { + var style = ele.pstyle('z-index-compare'); + if (style.value === 'auto') { + return ele.isNode() ? 1 : 0; + } + // 'manual' + return 0; + } + var eleDiff = getEleDepth(a) - getEleDepth(b); + if (eleDiff !== 0) { + return eleDiff; + } + var zDiff = a.pstyle('z-index').value - b.pstyle('z-index').value; + if (zDiff !== 0) { + return zDiff; + } + // compare indices in the core (order added to graph w/ last on top) + return a.poolIndex() - b.poolIndex(); +}; + +var elesfn$6 = { + forEach: function forEach(fn, thisArg) { + if (fn$6(fn)) { + var N = this.length; + for (var i = 0; i < N; i++) { + var ele = this[i]; + var ret = thisArg ? fn.apply(thisArg, [ele, i, this]) : fn(ele, i, this); + if (ret === false) { + break; + } // exit each early on return false + } + } + + return this; + }, + toArray: function toArray() { + var array = []; + for (var i = 0; i < this.length; i++) { + array.push(this[i]); + } + return array; + }, + slice: function slice(start, end) { + var array = []; + var thisSize = this.length; + if (end == null) { + end = thisSize; + } + if (start == null) { + start = 0; + } + if (start < 0) { + start = thisSize + start; + } + if (end < 0) { + end = thisSize + end; + } + for (var i = start; i >= 0 && i < end && i < thisSize; i++) { + array.push(this[i]); + } + return this.spawn(array); + }, + size: function size() { + return this.length; + }, + eq: function eq(i) { + return this[i] || this.spawn(); + }, + first: function first() { + return this[0] || this.spawn(); + }, + last: function last() { + return this[this.length - 1] || this.spawn(); + }, + empty: function empty() { + return this.length === 0; + }, + nonempty: function nonempty() { + return !this.empty(); + }, + sort: function sort(sortFn) { + if (!fn$6(sortFn)) { + return this; + } + var sorted = this.toArray().sort(sortFn); + return this.spawn(sorted); + }, + sortByZIndex: function sortByZIndex() { + return this.sort(zIndexSort); + }, + zDepth: function zDepth() { + var ele = this[0]; + if (!ele) { + return undefined; + } + + // let cy = ele.cy(); + var _p = ele._private; + var group = _p.group; + if (group === 'nodes') { + var depth = _p.data.parent ? ele.parents().size() : 0; + if (!ele.isParent()) { + return MAX_INT$1 - 1; // childless nodes always on top + } + + return depth; + } else { + var src = _p.source; + var tgt = _p.target; + var srcDepth = src.zDepth(); + var tgtDepth = tgt.zDepth(); + return Math.max(srcDepth, tgtDepth, 0); // depth of deepest parent + } + } +}; + +elesfn$6.each = elesfn$6.forEach; +var defineSymbolIterator = function defineSymbolIterator() { + var typeofUndef = "undefined" ; + var isIteratorSupported = (typeof Symbol === "undefined" ? "undefined" : _typeof(Symbol)) != typeofUndef && _typeof(Symbol.iterator) != typeofUndef; // eslint-disable-line no-undef + + if (isIteratorSupported) { + elesfn$6[Symbol.iterator] = function () { + var _this = this; + // eslint-disable-line no-undef + var entry = { + value: undefined, + done: false + }; + var i = 0; + var length = this.length; + return _defineProperty({ + next: function next() { + if (i < length) { + entry.value = _this[i++]; + } else { + entry.value = undefined; + entry.done = true; + } + return entry; + } + }, Symbol.iterator, function () { + // eslint-disable-line no-undef + return this; + }); + }; + } +}; +defineSymbolIterator(); + +var getLayoutDimensionOptions = defaults$g({ + nodeDimensionsIncludeLabels: false +}); +var elesfn$5 = { + // Calculates and returns node dimensions { x, y } based on options given + layoutDimensions: function layoutDimensions(options) { + options = getLayoutDimensionOptions(options); + var dims; + if (!this.takesUpSpace()) { + dims = { + w: 0, + h: 0 + }; + } else if (options.nodeDimensionsIncludeLabels) { + var bbDim = this.boundingBox(); + dims = { + w: bbDim.w, + h: bbDim.h + }; + } else { + dims = { + w: this.outerWidth(), + h: this.outerHeight() + }; + } + + // sanitise the dimensions for external layouts (avoid division by zero) + if (dims.w === 0 || dims.h === 0) { + dims.w = dims.h = 1; + } + return dims; + }, + // using standard layout options, apply position function (w/ or w/o animation) + layoutPositions: function layoutPositions(layout, options, fn) { + var nodes = this.nodes().filter(function (n) { + return !n.isParent(); + }); + var cy = this.cy(); + var layoutEles = options.eles; // nodes & edges + var getMemoizeKey = function getMemoizeKey(node) { + return node.id(); + }; + var fnMem = memoize(fn, getMemoizeKey); // memoized version of position function + + layout.emit({ + type: 'layoutstart', + layout: layout + }); + layout.animations = []; + var calculateSpacing = function calculateSpacing(spacing, nodesBb, pos) { + var center = { + x: nodesBb.x1 + nodesBb.w / 2, + y: nodesBb.y1 + nodesBb.h / 2 + }; + var spacingVector = { + // scale from center of bounding box (not necessarily 0,0) + x: (pos.x - center.x) * spacing, + y: (pos.y - center.y) * spacing + }; + return { + x: center.x + spacingVector.x, + y: center.y + spacingVector.y + }; + }; + var useSpacingFactor = options.spacingFactor && options.spacingFactor !== 1; + var spacingBb = function spacingBb() { + if (!useSpacingFactor) { + return null; + } + var bb = makeBoundingBox(); + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var pos = fnMem(node, i); + expandBoundingBoxByPoint(bb, pos.x, pos.y); + } + return bb; + }; + var bb = spacingBb(); + var getFinalPos = memoize(function (node, i) { + var newPos = fnMem(node, i); + if (useSpacingFactor) { + var spacing = Math.abs(options.spacingFactor); + newPos = calculateSpacing(spacing, bb, newPos); + } + if (options.transform != null) { + newPos = options.transform(node, newPos); + } + return newPos; + }, getMemoizeKey); + if (options.animate) { + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var newPos = getFinalPos(node, i); + var animateNode = options.animateFilter == null || options.animateFilter(node, i); + if (animateNode) { + var ani = node.animation({ + position: newPos, + duration: options.animationDuration, + easing: options.animationEasing + }); + layout.animations.push(ani); + } else { + node.position(newPos); + } + } + if (options.fit) { + var fitAni = cy.animation({ + fit: { + boundingBox: layoutEles.boundingBoxAt(getFinalPos), + padding: options.padding + }, + duration: options.animationDuration, + easing: options.animationEasing + }); + layout.animations.push(fitAni); + } else if (options.zoom !== undefined && options.pan !== undefined) { + var zoomPanAni = cy.animation({ + zoom: options.zoom, + pan: options.pan, + duration: options.animationDuration, + easing: options.animationEasing + }); + layout.animations.push(zoomPanAni); + } + layout.animations.forEach(function (ani) { + return ani.play(); + }); + layout.one('layoutready', options.ready); + layout.emit({ + type: 'layoutready', + layout: layout + }); + Promise$1.all(layout.animations.map(function (ani) { + return ani.promise(); + })).then(function () { + layout.one('layoutstop', options.stop); + layout.emit({ + type: 'layoutstop', + layout: layout + }); + }); + } else { + nodes.positions(getFinalPos); + if (options.fit) { + cy.fit(options.eles, options.padding); + } + if (options.zoom != null) { + cy.zoom(options.zoom); + } + if (options.pan) { + cy.pan(options.pan); + } + layout.one('layoutready', options.ready); + layout.emit({ + type: 'layoutready', + layout: layout + }); + layout.one('layoutstop', options.stop); + layout.emit({ + type: 'layoutstop', + layout: layout + }); + } + return this; // chaining + }, + + layout: function layout(options) { + var cy = this.cy(); + return cy.makeLayout(extend({}, options, { + eles: this + })); + } +}; + +// aliases: +elesfn$5.createLayout = elesfn$5.makeLayout = elesfn$5.layout; + +function styleCache(key, fn, ele) { + var _p = ele._private; + var cache = _p.styleCache = _p.styleCache || []; + var val; + if ((val = cache[key]) != null) { + return val; + } else { + val = cache[key] = fn(ele); + return val; + } +} +function cacheStyleFunction(key, fn) { + key = hashString(key); + return function cachedStyleFunction(ele) { + return styleCache(key, fn, ele); + }; +} +function cachePrototypeStyleFunction(key, fn) { + key = hashString(key); + var selfFn = function selfFn(ele) { + return fn.call(ele); + }; + return function cachedPrototypeStyleFunction() { + var ele = this[0]; + if (ele) { + return styleCache(key, selfFn, ele); + } + }; +} +var elesfn$4 = { + recalculateRenderedStyle: function recalculateRenderedStyle(useCache) { + var cy = this.cy(); + var renderer = cy.renderer(); + var styleEnabled = cy.styleEnabled(); + if (renderer && styleEnabled) { + renderer.recalculateRenderedStyle(this, useCache); + } + return this; + }, + dirtyStyleCache: function dirtyStyleCache() { + var cy = this.cy(); + var dirty = function dirty(ele) { + return ele._private.styleCache = null; + }; + if (cy.hasCompoundNodes()) { + var eles; + eles = this.spawnSelf().merge(this.descendants()).merge(this.parents()); + eles.merge(eles.connectedEdges()); + eles.forEach(dirty); + } else { + this.forEach(function (ele) { + dirty(ele); + ele.connectedEdges().forEach(dirty); + }); + } + return this; + }, + // fully updates (recalculates) the style for the elements + updateStyle: function updateStyle(notifyRenderer) { + var cy = this._private.cy; + if (!cy.styleEnabled()) { + return this; + } + if (cy.batching()) { + var bEles = cy._private.batchStyleEles; + bEles.merge(this); + return this; // chaining and exit early when batching + } + + var hasCompounds = cy.hasCompoundNodes(); + var updatedEles = this; + notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false; + if (hasCompounds) { + // then add everything up and down for compound selector checks + updatedEles = this.spawnSelf().merge(this.descendants()).merge(this.parents()); + } + + // let changedEles = style.apply( updatedEles ); + var changedEles = updatedEles; + if (notifyRenderer) { + changedEles.emitAndNotify('style'); // let renderer know we changed style + } else { + changedEles.emit('style'); // just fire the event + } + + updatedEles.forEach(function (ele) { + return ele._private.styleDirty = true; + }); + return this; // chaining + }, + + // private: clears dirty flag and recalculates style + cleanStyle: function cleanStyle() { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return; + } + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + if (ele._private.styleDirty) { + // n.b. this flag should be set before apply() to avoid potential infinite recursion + ele._private.styleDirty = false; + cy.style().apply(ele); + } + } + }, + // get the internal parsed style object for the specified property + parsedStyle: function parsedStyle(property) { + var includeNonDefault = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var ele = this[0]; + var cy = ele.cy(); + if (!cy.styleEnabled()) { + return; + } + if (ele) { + this.cleanStyle(); + var overriddenStyle = ele._private.style[property]; + if (overriddenStyle != null) { + return overriddenStyle; + } else if (includeNonDefault) { + return cy.style().getDefaultProperty(property); + } else { + return null; + } + } + }, + numericStyle: function numericStyle(property) { + var ele = this[0]; + if (!ele.cy().styleEnabled()) { + return; + } + if (ele) { + var pstyle = ele.pstyle(property); + return pstyle.pfValue !== undefined ? pstyle.pfValue : pstyle.value; + } + }, + numericStyleUnits: function numericStyleUnits(property) { + var ele = this[0]; + if (!ele.cy().styleEnabled()) { + return; + } + if (ele) { + return ele.pstyle(property).units; + } + }, + // get the specified css property as a rendered value (i.e. on-screen value) + // or get the whole rendered style if no property specified (NB doesn't allow setting) + renderedStyle: function renderedStyle(property) { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return this; + } + var ele = this[0]; + if (ele) { + return cy.style().getRenderedStyle(ele, property); + } + }, + // read the calculated css style of the element or override the style (via a bypass) + style: function style(name, value) { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return this; + } + var updateTransitions = false; + var style = cy.style(); + if (plainObject(name)) { + // then extend the bypass + var props = name; + style.applyBypass(this, props, updateTransitions); + this.emitAndNotify('style'); // let the renderer know we've updated style + } else if (string(name)) { + if (value === undefined) { + // then get the property from the style + var ele = this[0]; + if (ele) { + return style.getStylePropertyValue(ele, name); + } else { + // empty collection => can't get any value + return; + } + } else { + // then set the bypass with the property value + style.applyBypass(this, name, value, updateTransitions); + this.emitAndNotify('style'); // let the renderer know we've updated style + } + } else if (name === undefined) { + var _ele = this[0]; + if (_ele) { + return style.getRawStyle(_ele); + } else { + // empty collection => can't get any value + return; + } + } + return this; // chaining + }, + + removeStyle: function removeStyle(names) { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return this; + } + var updateTransitions = false; + var style = cy.style(); + var eles = this; + if (names === undefined) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + style.removeAllBypasses(ele, updateTransitions); + } + } else { + names = names.split(/\s+/); + for (var _i = 0; _i < eles.length; _i++) { + var _ele2 = eles[_i]; + style.removeBypasses(_ele2, names, updateTransitions); + } + } + this.emitAndNotify('style'); // let the renderer know we've updated style + + return this; // chaining + }, + + show: function show() { + this.css('display', 'element'); + return this; // chaining + }, + + hide: function hide() { + this.css('display', 'none'); + return this; // chaining + }, + + effectiveOpacity: function effectiveOpacity() { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return 1; + } + var hasCompoundNodes = cy.hasCompoundNodes(); + var ele = this[0]; + if (ele) { + var _p = ele._private; + var parentOpacity = ele.pstyle('opacity').value; + if (!hasCompoundNodes) { + return parentOpacity; + } + var parents = !_p.data.parent ? null : ele.parents(); + if (parents) { + for (var i = 0; i < parents.length; i++) { + var parent = parents[i]; + var opacity = parent.pstyle('opacity').value; + parentOpacity = opacity * parentOpacity; + } + } + return parentOpacity; + } + }, + transparent: function transparent() { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return false; + } + var ele = this[0]; + var hasCompoundNodes = ele.cy().hasCompoundNodes(); + if (ele) { + if (!hasCompoundNodes) { + return ele.pstyle('opacity').value === 0; + } else { + return ele.effectiveOpacity() === 0; + } + } + }, + backgrounding: function backgrounding() { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return false; + } + var ele = this[0]; + return ele._private.backgrounding ? true : false; + } +}; +function checkCompound(ele, parentOk) { + var _p = ele._private; + var parents = _p.data.parent ? ele.parents() : null; + if (parents) { + for (var i = 0; i < parents.length; i++) { + var parent = parents[i]; + if (!parentOk(parent)) { + return false; + } + } + } + return true; +} +function defineDerivedStateFunction(specs) { + var ok = specs.ok; + var edgeOkViaNode = specs.edgeOkViaNode || specs.ok; + var parentOk = specs.parentOk || specs.ok; + return function () { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return true; + } + var ele = this[0]; + var hasCompoundNodes = cy.hasCompoundNodes(); + if (ele) { + var _p = ele._private; + if (!ok(ele)) { + return false; + } + if (ele.isNode()) { + return !hasCompoundNodes || checkCompound(ele, parentOk); + } else { + var src = _p.source; + var tgt = _p.target; + return edgeOkViaNode(src) && (!hasCompoundNodes || checkCompound(src, edgeOkViaNode)) && (src === tgt || edgeOkViaNode(tgt) && (!hasCompoundNodes || checkCompound(tgt, edgeOkViaNode))); + } + } + }; +} +var eleTakesUpSpace = cacheStyleFunction('eleTakesUpSpace', function (ele) { + return ele.pstyle('display').value === 'element' && ele.width() !== 0 && (ele.isNode() ? ele.height() !== 0 : true); +}); +elesfn$4.takesUpSpace = cachePrototypeStyleFunction('takesUpSpace', defineDerivedStateFunction({ + ok: eleTakesUpSpace +})); +var eleInteractive = cacheStyleFunction('eleInteractive', function (ele) { + return ele.pstyle('events').value === 'yes' && ele.pstyle('visibility').value === 'visible' && eleTakesUpSpace(ele); +}); +var parentInteractive = cacheStyleFunction('parentInteractive', function (parent) { + return parent.pstyle('visibility').value === 'visible' && eleTakesUpSpace(parent); +}); +elesfn$4.interactive = cachePrototypeStyleFunction('interactive', defineDerivedStateFunction({ + ok: eleInteractive, + parentOk: parentInteractive, + edgeOkViaNode: eleTakesUpSpace +})); +elesfn$4.noninteractive = function () { + var ele = this[0]; + if (ele) { + return !ele.interactive(); + } +}; +var eleVisible = cacheStyleFunction('eleVisible', function (ele) { + return ele.pstyle('visibility').value === 'visible' && ele.pstyle('opacity').pfValue !== 0 && eleTakesUpSpace(ele); +}); +var edgeVisibleViaNode = eleTakesUpSpace; +elesfn$4.visible = cachePrototypeStyleFunction('visible', defineDerivedStateFunction({ + ok: eleVisible, + edgeOkViaNode: edgeVisibleViaNode +})); +elesfn$4.hidden = function () { + var ele = this[0]; + if (ele) { + return !ele.visible(); + } +}; +elesfn$4.isBundledBezier = cachePrototypeStyleFunction('isBundledBezier', function () { + if (!this.cy().styleEnabled()) { + return false; + } + return !this.removed() && this.pstyle('curve-style').value === 'bezier' && this.takesUpSpace(); +}); +elesfn$4.bypass = elesfn$4.css = elesfn$4.style; +elesfn$4.renderedCss = elesfn$4.renderedStyle; +elesfn$4.removeBypass = elesfn$4.removeCss = elesfn$4.removeStyle; +elesfn$4.pstyle = elesfn$4.parsedStyle; + +var elesfn$3 = {}; +function defineSwitchFunction(params) { + return function () { + var args = arguments; + var changedEles = []; + + // e.g. cy.nodes().select( data, handler ) + if (args.length === 2) { + var data = args[0]; + var handler = args[1]; + this.on(params.event, data, handler); + } + + // e.g. cy.nodes().select( handler ) + else if (args.length === 1 && fn$6(args[0])) { + var _handler = args[0]; + this.on(params.event, _handler); + } + + // e.g. cy.nodes().select() + // e.g. (private) cy.nodes().select(['tapselect']) + else if (args.length === 0 || args.length === 1 && array(args[0])) { + var addlEvents = args.length === 1 ? args[0] : null; + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var able = !params.ableField || ele._private[params.ableField]; + var changed = ele._private[params.field] != params.value; + if (params.overrideAble) { + var overrideAble = params.overrideAble(ele); + if (overrideAble !== undefined) { + able = overrideAble; + if (!overrideAble) { + return this; + } // to save cycles assume not able for all on override + } + } + + if (able) { + ele._private[params.field] = params.value; + if (changed) { + changedEles.push(ele); + } + } + } + var changedColl = this.spawn(changedEles); + changedColl.updateStyle(); // change of state => possible change of style + changedColl.emit(params.event); + if (addlEvents) { + changedColl.emit(addlEvents); + } + } + return this; + }; +} +function defineSwitchSet(params) { + elesfn$3[params.field] = function () { + var ele = this[0]; + if (ele) { + if (params.overrideField) { + var val = params.overrideField(ele); + if (val !== undefined) { + return val; + } + } + return ele._private[params.field]; + } + }; + elesfn$3[params.on] = defineSwitchFunction({ + event: params.on, + field: params.field, + ableField: params.ableField, + overrideAble: params.overrideAble, + value: true + }); + elesfn$3[params.off] = defineSwitchFunction({ + event: params.off, + field: params.field, + ableField: params.ableField, + overrideAble: params.overrideAble, + value: false + }); +} +defineSwitchSet({ + field: 'locked', + overrideField: function overrideField(ele) { + return ele.cy().autolock() ? true : undefined; + }, + on: 'lock', + off: 'unlock' +}); +defineSwitchSet({ + field: 'grabbable', + overrideField: function overrideField(ele) { + return ele.cy().autoungrabify() || ele.pannable() ? false : undefined; + }, + on: 'grabify', + off: 'ungrabify' +}); +defineSwitchSet({ + field: 'selected', + ableField: 'selectable', + overrideAble: function overrideAble(ele) { + return ele.cy().autounselectify() ? false : undefined; + }, + on: 'select', + off: 'unselect' +}); +defineSwitchSet({ + field: 'selectable', + overrideField: function overrideField(ele) { + return ele.cy().autounselectify() ? false : undefined; + }, + on: 'selectify', + off: 'unselectify' +}); +elesfn$3.deselect = elesfn$3.unselect; +elesfn$3.grabbed = function () { + var ele = this[0]; + if (ele) { + return ele._private.grabbed; + } +}; +defineSwitchSet({ + field: 'active', + on: 'activate', + off: 'unactivate' +}); +defineSwitchSet({ + field: 'pannable', + on: 'panify', + off: 'unpanify' +}); +elesfn$3.inactive = function () { + var ele = this[0]; + if (ele) { + return !ele._private.active; + } +}; + +var elesfn$2 = {}; + +// DAG functions +//////////////// + +var defineDagExtremity = function defineDagExtremity(params) { + return function dagExtremityImpl(selector) { + var eles = this; + var ret = []; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + if (!ele.isNode()) { + continue; + } + var disqualified = false; + var edges = ele.connectedEdges(); + for (var j = 0; j < edges.length; j++) { + var edge = edges[j]; + var src = edge.source(); + var tgt = edge.target(); + if (params.noIncomingEdges && tgt === ele && src !== ele || params.noOutgoingEdges && src === ele && tgt !== ele) { + disqualified = true; + break; + } + } + if (!disqualified) { + ret.push(ele); + } + } + return this.spawn(ret, true).filter(selector); + }; +}; +var defineDagOneHop = function defineDagOneHop(params) { + return function (selector) { + var eles = this; + var oEles = []; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + if (!ele.isNode()) { + continue; + } + var edges = ele.connectedEdges(); + for (var j = 0; j < edges.length; j++) { + var edge = edges[j]; + var src = edge.source(); + var tgt = edge.target(); + if (params.outgoing && src === ele) { + oEles.push(edge); + oEles.push(tgt); + } else if (params.incoming && tgt === ele) { + oEles.push(edge); + oEles.push(src); + } + } + } + return this.spawn(oEles, true).filter(selector); + }; +}; +var defineDagAllHops = function defineDagAllHops(params) { + return function (selector) { + var eles = this; + var sEles = []; + var sElesIds = {}; + for (;;) { + var next = params.outgoing ? eles.outgoers() : eles.incomers(); + if (next.length === 0) { + break; + } // done if none left + + var newNext = false; + for (var i = 0; i < next.length; i++) { + var n = next[i]; + var nid = n.id(); + if (!sElesIds[nid]) { + sElesIds[nid] = true; + sEles.push(n); + newNext = true; + } + } + if (!newNext) { + break; + } // done if touched all outgoers already + + eles = next; + } + return this.spawn(sEles, true).filter(selector); + }; +}; +elesfn$2.clearTraversalCache = function () { + for (var i = 0; i < this.length; i++) { + this[i]._private.traversalCache = null; + } +}; +extend(elesfn$2, { + // get the root nodes in the DAG + roots: defineDagExtremity({ + noIncomingEdges: true + }), + // get the leaf nodes in the DAG + leaves: defineDagExtremity({ + noOutgoingEdges: true + }), + // normally called children in graph theory + // these nodes =edges=> outgoing nodes + outgoers: cache(defineDagOneHop({ + outgoing: true + }), 'outgoers'), + // aka DAG descendants + successors: defineDagAllHops({ + outgoing: true + }), + // normally called parents in graph theory + // these nodes <=edges= incoming nodes + incomers: cache(defineDagOneHop({ + incoming: true + }), 'incomers'), + // aka DAG ancestors + predecessors: defineDagAllHops({ + incoming: true + }) +}); + +// Neighbourhood functions +////////////////////////// + +extend(elesfn$2, { + neighborhood: cache(function (selector) { + var elements = []; + var nodes = this.nodes(); + for (var i = 0; i < nodes.length; i++) { + // for all nodes + var node = nodes[i]; + var connectedEdges = node.connectedEdges(); + + // for each connected edge, add the edge and the other node + for (var j = 0; j < connectedEdges.length; j++) { + var edge = connectedEdges[j]; + var src = edge.source(); + var tgt = edge.target(); + var otherNode = node === src ? tgt : src; + + // need check in case of loop + if (otherNode.length > 0) { + elements.push(otherNode[0]); // add node 1 hop away + } + + // add connected edge + elements.push(edge[0]); + } + } + return this.spawn(elements, true).filter(selector); + }, 'neighborhood'), + closedNeighborhood: function closedNeighborhood(selector) { + return this.neighborhood().add(this).filter(selector); + }, + openNeighborhood: function openNeighborhood(selector) { + return this.neighborhood(selector); + } +}); + +// aliases +elesfn$2.neighbourhood = elesfn$2.neighborhood; +elesfn$2.closedNeighbourhood = elesfn$2.closedNeighborhood; +elesfn$2.openNeighbourhood = elesfn$2.openNeighborhood; + +// Edge functions +///////////////// + +extend(elesfn$2, { + source: cache(function sourceImpl(selector) { + var ele = this[0]; + var src; + if (ele) { + src = ele._private.source || ele.cy().collection(); + } + return src && selector ? src.filter(selector) : src; + }, 'source'), + target: cache(function targetImpl(selector) { + var ele = this[0]; + var tgt; + if (ele) { + tgt = ele._private.target || ele.cy().collection(); + } + return tgt && selector ? tgt.filter(selector) : tgt; + }, 'target'), + sources: defineSourceFunction({ + attr: 'source' + }), + targets: defineSourceFunction({ + attr: 'target' + }) +}); +function defineSourceFunction(params) { + return function sourceImpl(selector) { + var sources = []; + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var src = ele._private[params.attr]; + if (src) { + sources.push(src); + } + } + return this.spawn(sources, true).filter(selector); + }; +} +extend(elesfn$2, { + edgesWith: cache(defineEdgesWithFunction(), 'edgesWith'), + edgesTo: cache(defineEdgesWithFunction({ + thisIsSrc: true + }), 'edgesTo') +}); +function defineEdgesWithFunction(params) { + return function edgesWithImpl(otherNodes) { + var elements = []; + var cy = this._private.cy; + var p = params || {}; + + // get elements if a selector is specified + if (string(otherNodes)) { + otherNodes = cy.$(otherNodes); + } + for (var h = 0; h < otherNodes.length; h++) { + var edges = otherNodes[h]._private.edges; + for (var i = 0; i < edges.length; i++) { + var edge = edges[i]; + var edgeData = edge._private.data; + var thisToOther = this.hasElementWithId(edgeData.source) && otherNodes.hasElementWithId(edgeData.target); + var otherToThis = otherNodes.hasElementWithId(edgeData.source) && this.hasElementWithId(edgeData.target); + var edgeConnectsThisAndOther = thisToOther || otherToThis; + if (!edgeConnectsThisAndOther) { + continue; + } + if (p.thisIsSrc || p.thisIsTgt) { + if (p.thisIsSrc && !thisToOther) { + continue; + } + if (p.thisIsTgt && !otherToThis) { + continue; + } + } + elements.push(edge); + } + } + return this.spawn(elements, true); + }; +} +extend(elesfn$2, { + connectedEdges: cache(function (selector) { + var retEles = []; + var eles = this; + for (var i = 0; i < eles.length; i++) { + var node = eles[i]; + if (!node.isNode()) { + continue; + } + var edges = node._private.edges; + for (var j = 0; j < edges.length; j++) { + var edge = edges[j]; + retEles.push(edge); + } + } + return this.spawn(retEles, true).filter(selector); + }, 'connectedEdges'), + connectedNodes: cache(function (selector) { + var retEles = []; + var eles = this; + for (var i = 0; i < eles.length; i++) { + var edge = eles[i]; + if (!edge.isEdge()) { + continue; + } + retEles.push(edge.source()[0]); + retEles.push(edge.target()[0]); + } + return this.spawn(retEles, true).filter(selector); + }, 'connectedNodes'), + parallelEdges: cache(defineParallelEdgesFunction(), 'parallelEdges'), + codirectedEdges: cache(defineParallelEdgesFunction({ + codirected: true + }), 'codirectedEdges') +}); +function defineParallelEdgesFunction(params) { + var defaults = { + codirected: false + }; + params = extend({}, defaults, params); + return function parallelEdgesImpl(selector) { + // micro-optimised for renderer + var elements = []; + var edges = this.edges(); + var p = params; + + // look at all the edges in the collection + for (var i = 0; i < edges.length; i++) { + var edge1 = edges[i]; + var edge1_p = edge1._private; + var src1 = edge1_p.source; + var srcid1 = src1._private.data.id; + var tgtid1 = edge1_p.data.target; + var srcEdges1 = src1._private.edges; + + // look at edges connected to the src node of this edge + for (var j = 0; j < srcEdges1.length; j++) { + var edge2 = srcEdges1[j]; + var edge2data = edge2._private.data; + var tgtid2 = edge2data.target; + var srcid2 = edge2data.source; + var codirected = tgtid2 === tgtid1 && srcid2 === srcid1; + var oppdirected = srcid1 === tgtid2 && tgtid1 === srcid2; + if (p.codirected && codirected || !p.codirected && (codirected || oppdirected)) { + elements.push(edge2); + } + } + } + return this.spawn(elements, true).filter(selector); + }; +} + +// Misc functions +///////////////// + +extend(elesfn$2, { + components: function components(root) { + var self = this; + var cy = self.cy(); + var visited = cy.collection(); + var unvisited = root == null ? self.nodes() : root.nodes(); + var components = []; + if (root != null && unvisited.empty()) { + // root may contain only edges + unvisited = root.sources(); // doesn't matter which node to use (undirected), so just use the source sides + } + + var visitInComponent = function visitInComponent(node, component) { + visited.merge(node); + unvisited.unmerge(node); + component.merge(node); + }; + if (unvisited.empty()) { + return self.spawn(); + } + var _loop = function _loop() { + // each iteration yields a component + var cmpt = cy.collection(); + components.push(cmpt); + var root = unvisited[0]; + visitInComponent(root, cmpt); + self.bfs({ + directed: false, + roots: root, + visit: function visit(v) { + return visitInComponent(v, cmpt); + } + }); + cmpt.forEach(function (node) { + node.connectedEdges().forEach(function (e) { + // connectedEdges() usually cached + if (self.has(e) && cmpt.has(e.source()) && cmpt.has(e.target())) { + // has() is cheap + cmpt.merge(e); // forEach() only considers nodes -- sets N at call time + } + }); + }); + }; + do { + _loop(); + } while (unvisited.length > 0); + return components; + }, + component: function component() { + var ele = this[0]; + return ele.cy().mutableElements().components(ele)[0]; + } +}); +elesfn$2.componentsOf = elesfn$2.components; + +// represents a set of nodes, edges, or both together +var Collection = function Collection(cy, elements) { + var unique = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var removed = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + if (cy === undefined) { + error('A collection must have a reference to the core'); + return; + } + var map = new Map$1(); + var createdElements = false; + if (!elements) { + elements = []; + } else if (elements.length > 0 && plainObject(elements[0]) && !element(elements[0])) { + createdElements = true; + + // make elements from json and restore all at once later + var eles = []; + var elesIds = new Set$1(); + for (var i = 0, l = elements.length; i < l; i++) { + var json = elements[i]; + if (json.data == null) { + json.data = {}; + } + var _data = json.data; + + // make sure newly created elements have valid ids + if (_data.id == null) { + _data.id = uuid(); + } else if (cy.hasElementWithId(_data.id) || elesIds.has(_data.id)) { + continue; // can't create element if prior id already exists + } + + var ele = new Element(cy, json, false); + eles.push(ele); + elesIds.add(_data.id); + } + elements = eles; + } + this.length = 0; + for (var _i = 0, _l = elements.length; _i < _l; _i++) { + var element$1 = elements[_i][0]; // [0] in case elements is an array of collections, rather than array of elements + if (element$1 == null) { + continue; + } + var id = element$1._private.data.id; + if (!unique || !map.has(id)) { + if (unique) { + map.set(id, { + index: this.length, + ele: element$1 + }); + } + this[this.length] = element$1; + this.length++; + } + } + this._private = { + eles: this, + cy: cy, + get map() { + if (this.lazyMap == null) { + this.rebuildMap(); + } + return this.lazyMap; + }, + set map(m) { + this.lazyMap = m; + }, + rebuildMap: function rebuildMap() { + var m = this.lazyMap = new Map$1(); + var eles = this.eles; + for (var _i2 = 0; _i2 < eles.length; _i2++) { + var _ele = eles[_i2]; + m.set(_ele.id(), { + index: _i2, + ele: _ele + }); + } + } + }; + if (unique) { + this._private.map = map; + } + + // restore the elements if we created them from json + if (createdElements && !removed) { + this.restore(); + } +}; + +// Functions +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// keep the prototypes in sync (an element has the same functions as a collection) +// and use elefn and elesfn as shorthands to the prototypes +var elesfn$1 = Element.prototype = Collection.prototype = Object.create(Array.prototype); +elesfn$1.instanceString = function () { + return 'collection'; +}; +elesfn$1.spawn = function (eles, unique) { + return new Collection(this.cy(), eles, unique); +}; +elesfn$1.spawnSelf = function () { + return this.spawn(this); +}; +elesfn$1.cy = function () { + return this._private.cy; +}; +elesfn$1.renderer = function () { + return this._private.cy.renderer(); +}; +elesfn$1.element = function () { + return this[0]; +}; +elesfn$1.collection = function () { + if (collection(this)) { + return this; + } else { + // an element + return new Collection(this._private.cy, [this]); + } +}; +elesfn$1.unique = function () { + return new Collection(this._private.cy, this, true); +}; +elesfn$1.hasElementWithId = function (id) { + id = '' + id; // id must be string + + return this._private.map.has(id); +}; +elesfn$1.getElementById = function (id) { + id = '' + id; // id must be string + + var cy = this._private.cy; + var entry = this._private.map.get(id); + return entry ? entry.ele : new Collection(cy); // get ele or empty collection +}; + +elesfn$1.$id = elesfn$1.getElementById; +elesfn$1.poolIndex = function () { + var cy = this._private.cy; + var eles = cy._private.elements; + var id = this[0]._private.data.id; + return eles._private.map.get(id).index; +}; +elesfn$1.indexOf = function (ele) { + var id = ele[0]._private.data.id; + return this._private.map.get(id).index; +}; +elesfn$1.indexOfId = function (id) { + id = '' + id; // id must be string + + return this._private.map.get(id).index; +}; +elesfn$1.json = function (obj) { + var ele = this.element(); + var cy = this.cy(); + if (ele == null && obj) { + return this; + } // can't set to no eles + + if (ele == null) { + return undefined; + } // can't get from no eles + + var p = ele._private; + if (plainObject(obj)) { + // set + + cy.startBatch(); + if (obj.data) { + ele.data(obj.data); + var _data2 = p.data; + if (ele.isEdge()) { + // source and target are immutable via data() + var move = false; + var spec = {}; + var src = obj.data.source; + var tgt = obj.data.target; + if (src != null && src != _data2.source) { + spec.source = '' + src; // id must be string + move = true; + } + if (tgt != null && tgt != _data2.target) { + spec.target = '' + tgt; // id must be string + move = true; + } + if (move) { + ele = ele.move(spec); + } + } else { + // parent is immutable via data() + var newParentValSpecd = ('parent' in obj.data); + var parent = obj.data.parent; + if (newParentValSpecd && (parent != null || _data2.parent != null) && parent != _data2.parent) { + if (parent === undefined) { + // can't set undefined imperatively, so use null + parent = null; + } + if (parent != null) { + parent = '' + parent; // id must be string + } + + ele = ele.move({ + parent: parent + }); + } + } + } + if (obj.position) { + ele.position(obj.position); + } + + // ignore group -- immutable + + var checkSwitch = function checkSwitch(k, trueFnName, falseFnName) { + var obj_k = obj[k]; + if (obj_k != null && obj_k !== p[k]) { + if (obj_k) { + ele[trueFnName](); + } else { + ele[falseFnName](); + } + } + }; + checkSwitch('removed', 'remove', 'restore'); + checkSwitch('selected', 'select', 'unselect'); + checkSwitch('selectable', 'selectify', 'unselectify'); + checkSwitch('locked', 'lock', 'unlock'); + checkSwitch('grabbable', 'grabify', 'ungrabify'); + checkSwitch('pannable', 'panify', 'unpanify'); + if (obj.classes != null) { + ele.classes(obj.classes); + } + cy.endBatch(); + return this; + } else if (obj === undefined) { + // get + + var json = { + data: copy(p.data), + position: copy(p.position), + group: p.group, + removed: p.removed, + selected: p.selected, + selectable: p.selectable, + locked: p.locked, + grabbable: p.grabbable, + pannable: p.pannable, + classes: null + }; + json.classes = ''; + var i = 0; + p.classes.forEach(function (cls) { + return json.classes += i++ === 0 ? cls : ' ' + cls; + }); + return json; + } +}; +elesfn$1.jsons = function () { + var jsons = []; + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var json = ele.json(); + jsons.push(json); + } + return jsons; +}; +elesfn$1.clone = function () { + var cy = this.cy(); + var elesArr = []; + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var json = ele.json(); + var clone = new Element(cy, json, false); // NB no restore + + elesArr.push(clone); + } + return new Collection(cy, elesArr); +}; +elesfn$1.copy = elesfn$1.clone; +elesfn$1.restore = function () { + var notifyRenderer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + var addToPool = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var self = this; + var cy = self.cy(); + var cy_p = cy._private; + + // create arrays of nodes and edges, since we need to + // restore the nodes first + var nodes = []; + var edges = []; + var elements; + for (var _i3 = 0, l = self.length; _i3 < l; _i3++) { + var ele = self[_i3]; + if (addToPool && !ele.removed()) { + // don't need to handle this ele + continue; + } + + // keep nodes first in the array and edges after + if (ele.isNode()) { + // put to front of array if node + nodes.push(ele); + } else { + // put to end of array if edge + edges.push(ele); + } + } + elements = nodes.concat(edges); + var i; + var removeFromElements = function removeFromElements() { + elements.splice(i, 1); + i--; + }; + + // now, restore each element + for (i = 0; i < elements.length; i++) { + var _ele2 = elements[i]; + var _private = _ele2._private; + var _data3 = _private.data; + + // the traversal cache should start fresh when ele is added + _ele2.clearTraversalCache(); + + // set id and validate + if (!addToPool && !_private.removed) ; else if (_data3.id === undefined) { + _data3.id = uuid(); + } else if (number$1(_data3.id)) { + _data3.id = '' + _data3.id; // now it's a string + } else if (emptyString(_data3.id) || !string(_data3.id)) { + error('Can not create element with invalid string ID `' + _data3.id + '`'); + + // can't create element if it has empty string as id or non-string id + removeFromElements(); + continue; + } else if (cy.hasElementWithId(_data3.id)) { + error('Can not create second element with ID `' + _data3.id + '`'); + + // can't create element if one already has that id + removeFromElements(); + continue; + } + var id = _data3.id; // id is finalised, now let's keep a ref + + if (_ele2.isNode()) { + // extra checks for nodes + var pos = _private.position; + + // make sure the nodes have a defined position + + if (pos.x == null) { + pos.x = 0; + } + if (pos.y == null) { + pos.y = 0; + } + } + if (_ele2.isEdge()) { + // extra checks for edges + + var edge = _ele2; + var fields = ['source', 'target']; + var fieldsLength = fields.length; + var badSourceOrTarget = false; + for (var j = 0; j < fieldsLength; j++) { + var field = fields[j]; + var val = _data3[field]; + if (number$1(val)) { + val = _data3[field] = '' + _data3[field]; // now string + } + + if (val == null || val === '') { + // can't create if source or target is not defined properly + error('Can not create edge `' + id + '` with unspecified ' + field); + badSourceOrTarget = true; + } else if (!cy.hasElementWithId(val)) { + // can't create edge if one of its nodes doesn't exist + error('Can not create edge `' + id + '` with nonexistant ' + field + ' `' + val + '`'); + badSourceOrTarget = true; + } + } + if (badSourceOrTarget) { + removeFromElements(); + continue; + } // can't create this + + var src = cy.getElementById(_data3.source); + var tgt = cy.getElementById(_data3.target); + + // only one edge in node if loop + if (src.same(tgt)) { + src._private.edges.push(edge); + } else { + src._private.edges.push(edge); + tgt._private.edges.push(edge); + } + edge._private.source = src; + edge._private.target = tgt; + } // if is edge + + // create mock ids / indexes maps for element so it can be used like collections + _private.map = new Map$1(); + _private.map.set(id, { + ele: _ele2, + index: 0 + }); + _private.removed = false; + if (addToPool) { + cy.addToPool(_ele2); + } + } // for each element + + // do compound node sanity checks + for (var _i4 = 0; _i4 < nodes.length; _i4++) { + // each node + var node = nodes[_i4]; + var _data4 = node._private.data; + if (number$1(_data4.parent)) { + // then automake string + _data4.parent = '' + _data4.parent; + } + var parentId = _data4.parent; + var specifiedParent = parentId != null; + if (specifiedParent || node._private.parent) { + var parent = node._private.parent ? cy.collection().merge(node._private.parent) : cy.getElementById(parentId); + if (parent.empty()) { + // non-existant parent; just remove it + _data4.parent = undefined; + } else if (parent[0].removed()) { + warn('Node added with missing parent, reference to parent removed'); + _data4.parent = undefined; + node._private.parent = null; + } else { + var selfAsParent = false; + var ancestor = parent; + while (!ancestor.empty()) { + if (node.same(ancestor)) { + // mark self as parent and remove from data + selfAsParent = true; + _data4.parent = undefined; // remove parent reference + + // exit or we loop forever + break; + } + ancestor = ancestor.parent(); + } + if (!selfAsParent) { + // connect with children + parent[0]._private.children.push(node); + node._private.parent = parent[0]; + + // let the core know we have a compound graph + cy_p.hasCompoundNodes = true; + } + } // else + } // if specified parent + } // for each node + + if (elements.length > 0) { + var restored = elements.length === self.length ? self : new Collection(cy, elements); + for (var _i5 = 0; _i5 < restored.length; _i5++) { + var _ele3 = restored[_i5]; + if (_ele3.isNode()) { + continue; + } + + // adding an edge invalidates the traversal caches for the parallel edges + _ele3.parallelEdges().clearTraversalCache(); + + // adding an edge invalidates the traversal cache for the connected nodes + _ele3.source().clearTraversalCache(); + _ele3.target().clearTraversalCache(); + } + var toUpdateStyle; + if (cy_p.hasCompoundNodes) { + toUpdateStyle = cy.collection().merge(restored).merge(restored.connectedNodes()).merge(restored.parent()); + } else { + toUpdateStyle = restored; + } + toUpdateStyle.dirtyCompoundBoundsCache().dirtyBoundingBoxCache().updateStyle(notifyRenderer); + if (notifyRenderer) { + restored.emitAndNotify('add'); + } else if (addToPool) { + restored.emit('add'); + } + } + return self; // chainability +}; + +elesfn$1.removed = function () { + var ele = this[0]; + return ele && ele._private.removed; +}; +elesfn$1.inside = function () { + var ele = this[0]; + return ele && !ele._private.removed; +}; +elesfn$1.remove = function () { + var notifyRenderer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + var removeFromPool = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var self = this; + var elesToRemove = []; + var elesToRemoveIds = {}; + var cy = self._private.cy; + + // add connected edges + function addConnectedEdges(node) { + var edges = node._private.edges; + for (var i = 0; i < edges.length; i++) { + add(edges[i]); + } + } + + // add descendant nodes + function addChildren(node) { + var children = node._private.children; + for (var i = 0; i < children.length; i++) { + add(children[i]); + } + } + function add(ele) { + var alreadyAdded = elesToRemoveIds[ele.id()]; + if (removeFromPool && ele.removed() || alreadyAdded) { + return; + } else { + elesToRemoveIds[ele.id()] = true; + } + if (ele.isNode()) { + elesToRemove.push(ele); // nodes are removed last + + addConnectedEdges(ele); + addChildren(ele); + } else { + elesToRemove.unshift(ele); // edges are removed first + } + } + + // make the list of elements to remove + // (may be removing more than specified due to connected edges etc) + + for (var i = 0, l = self.length; i < l; i++) { + var ele = self[i]; + add(ele); + } + function removeEdgeRef(node, edge) { + var connectedEdges = node._private.edges; + removeFromArray(connectedEdges, edge); + + // removing an edges invalidates the traversal cache for its nodes + node.clearTraversalCache(); + } + function removeParallelRef(pllEdge) { + // removing an edge invalidates the traversal caches for the parallel edges + pllEdge.clearTraversalCache(); + } + var alteredParents = []; + alteredParents.ids = {}; + function removeChildRef(parent, ele) { + ele = ele[0]; + parent = parent[0]; + var children = parent._private.children; + var pid = parent.id(); + removeFromArray(children, ele); // remove parent => child ref + + ele._private.parent = null; // remove child => parent ref + + if (!alteredParents.ids[pid]) { + alteredParents.ids[pid] = true; + alteredParents.push(parent); + } + } + self.dirtyCompoundBoundsCache(); + if (removeFromPool) { + cy.removeFromPool(elesToRemove); // remove from core pool + } + + for (var _i6 = 0; _i6 < elesToRemove.length; _i6++) { + var _ele4 = elesToRemove[_i6]; + if (_ele4.isEdge()) { + // remove references to this edge in its connected nodes + var src = _ele4.source()[0]; + var tgt = _ele4.target()[0]; + removeEdgeRef(src, _ele4); + removeEdgeRef(tgt, _ele4); + var pllEdges = _ele4.parallelEdges(); + for (var j = 0; j < pllEdges.length; j++) { + var pllEdge = pllEdges[j]; + removeParallelRef(pllEdge); + if (pllEdge.isBundledBezier()) { + pllEdge.dirtyBoundingBoxCache(); + } + } + } else { + // remove reference to parent + var parent = _ele4.parent(); + if (parent.length !== 0) { + removeChildRef(parent, _ele4); + } + } + if (removeFromPool) { + // mark as removed + _ele4._private.removed = true; + } + } + + // check to see if we have a compound graph or not + var elesStillInside = cy._private.elements; + cy._private.hasCompoundNodes = false; + for (var _i7 = 0; _i7 < elesStillInside.length; _i7++) { + var _ele5 = elesStillInside[_i7]; + if (_ele5.isParent()) { + cy._private.hasCompoundNodes = true; + break; + } + } + var removedElements = new Collection(this.cy(), elesToRemove); + if (removedElements.size() > 0) { + // must manually notify since trigger won't do this automatically once removed + + if (notifyRenderer) { + removedElements.emitAndNotify('remove'); + } else if (removeFromPool) { + removedElements.emit('remove'); + } + } + + // the parents who were modified by the removal need their style updated + for (var _i8 = 0; _i8 < alteredParents.length; _i8++) { + var _ele6 = alteredParents[_i8]; + if (!removeFromPool || !_ele6.removed()) { + _ele6.updateStyle(); + } + } + return removedElements; +}; +elesfn$1.move = function (struct) { + var cy = this._private.cy; + var eles = this; + + // just clean up refs, caches, etc. in the same way as when removing and then restoring + // (our calls to remove/restore do not remove from the graph or make events) + var notifyRenderer = false; + var modifyPool = false; + var toString = function toString(id) { + return id == null ? id : '' + id; + }; // id must be string + + if (struct.source !== undefined || struct.target !== undefined) { + var srcId = toString(struct.source); + var tgtId = toString(struct.target); + var srcExists = srcId != null && cy.hasElementWithId(srcId); + var tgtExists = tgtId != null && cy.hasElementWithId(tgtId); + if (srcExists || tgtExists) { + cy.batch(function () { + // avoid duplicate style updates + eles.remove(notifyRenderer, modifyPool); // clean up refs etc. + eles.emitAndNotify('moveout'); + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var _data5 = ele._private.data; + if (ele.isEdge()) { + if (srcExists) { + _data5.source = srcId; + } + if (tgtExists) { + _data5.target = tgtId; + } + } + } + eles.restore(notifyRenderer, modifyPool); // make new refs, style, etc. + }); + + eles.emitAndNotify('move'); + } + } else if (struct.parent !== undefined) { + // move node to new parent + var parentId = toString(struct.parent); + var parentExists = parentId === null || cy.hasElementWithId(parentId); + if (parentExists) { + var pidToAssign = parentId === null ? undefined : parentId; + cy.batch(function () { + // avoid duplicate style updates + var updated = eles.remove(notifyRenderer, modifyPool); // clean up refs etc. + updated.emitAndNotify('moveout'); + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var _data6 = ele._private.data; + if (ele.isNode()) { + _data6.parent = pidToAssign; + } + } + updated.restore(notifyRenderer, modifyPool); // make new refs, style, etc. + }); + + eles.emitAndNotify('move'); + } + } + return this; +}; +[elesfn$j, elesfn$i, elesfn$h, elesfn$g, elesfn$f, data, elesfn$d, dimensions, elesfn$9, elesfn$8, elesfn$7, elesfn$6, elesfn$5, elesfn$4, elesfn$3, elesfn$2].forEach(function (props) { + extend(elesfn$1, props); +}); + +var corefn$9 = { + add: function add(opts) { + var elements; + var cy = this; + + // add the elements + if (elementOrCollection(opts)) { + var eles = opts; + if (eles._private.cy === cy) { + // same instance => just restore + elements = eles.restore(); + } else { + // otherwise, copy from json + var jsons = []; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + jsons.push(ele.json()); + } + elements = new Collection(cy, jsons); + } + } + + // specify an array of options + else if (array(opts)) { + var _jsons = opts; + elements = new Collection(cy, _jsons); + } + + // specify via opts.nodes and opts.edges + else if (plainObject(opts) && (array(opts.nodes) || array(opts.edges))) { + var elesByGroup = opts; + var _jsons2 = []; + var grs = ['nodes', 'edges']; + for (var _i = 0, il = grs.length; _i < il; _i++) { + var group = grs[_i]; + var elesArray = elesByGroup[group]; + if (array(elesArray)) { + for (var j = 0, jl = elesArray.length; j < jl; j++) { + var json = extend({ + group: group + }, elesArray[j]); + _jsons2.push(json); + } + } + } + elements = new Collection(cy, _jsons2); + } + + // specify options for one element + else { + var _json = opts; + elements = new Element(cy, _json).collection(); + } + return elements; + }, + remove: function remove(collection) { + if (elementOrCollection(collection)) ; else if (string(collection)) { + var selector = collection; + collection = this.$(selector); + } + return collection.remove(); + } +}; + +/* global Float32Array */ + +/*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */ +function generateCubicBezier(mX1, mY1, mX2, mY2) { + var NEWTON_ITERATIONS = 4, + NEWTON_MIN_SLOPE = 0.001, + SUBDIVISION_PRECISION = 0.0000001, + SUBDIVISION_MAX_ITERATIONS = 10, + kSplineTableSize = 11, + kSampleStepSize = 1.0 / (kSplineTableSize - 1.0), + float32ArraySupported = typeof Float32Array !== 'undefined'; + + /* Must contain four arguments. */ + if (arguments.length !== 4) { + return false; + } + + /* Arguments must be numbers. */ + for (var i = 0; i < 4; ++i) { + if (typeof arguments[i] !== "number" || isNaN(arguments[i]) || !isFinite(arguments[i])) { + return false; + } + } + + /* X values must be in the [0, 1] range. */ + mX1 = Math.min(mX1, 1); + mX2 = Math.min(mX2, 1); + mX1 = Math.max(mX1, 0); + mX2 = Math.max(mX2, 0); + var mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize); + function A(aA1, aA2) { + return 1.0 - 3.0 * aA2 + 3.0 * aA1; + } + function B(aA1, aA2) { + return 3.0 * aA2 - 6.0 * aA1; + } + function C(aA1) { + return 3.0 * aA1; + } + function calcBezier(aT, aA1, aA2) { + return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; + } + function getSlope(aT, aA1, aA2) { + return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); + } + function newtonRaphsonIterate(aX, aGuessT) { + for (var _i = 0; _i < NEWTON_ITERATIONS; ++_i) { + var currentSlope = getSlope(aGuessT, mX1, mX2); + if (currentSlope === 0.0) { + return aGuessT; + } + var currentX = calcBezier(aGuessT, mX1, mX2) - aX; + aGuessT -= currentX / currentSlope; + } + return aGuessT; + } + function calcSampleValues() { + for (var _i2 = 0; _i2 < kSplineTableSize; ++_i2) { + mSampleValues[_i2] = calcBezier(_i2 * kSampleStepSize, mX1, mX2); + } + } + function binarySubdivide(aX, aA, aB) { + var currentX, + currentT, + i = 0; + do { + currentT = aA + (aB - aA) / 2.0; + currentX = calcBezier(currentT, mX1, mX2) - aX; + if (currentX > 0.0) { + aB = currentT; + } else { + aA = currentT; + } + } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); + return currentT; + } + function getTForX(aX) { + var intervalStart = 0.0, + currentSample = 1, + lastSample = kSplineTableSize - 1; + for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) { + intervalStart += kSampleStepSize; + } + --currentSample; + var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]), + guessForT = intervalStart + dist * kSampleStepSize, + initialSlope = getSlope(guessForT, mX1, mX2); + if (initialSlope >= NEWTON_MIN_SLOPE) { + return newtonRaphsonIterate(aX, guessForT); + } else if (initialSlope === 0.0) { + return guessForT; + } else { + return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize); + } + } + var _precomputed = false; + function precompute() { + _precomputed = true; + if (mX1 !== mY1 || mX2 !== mY2) { + calcSampleValues(); + } + } + var f = function f(aX) { + if (!_precomputed) { + precompute(); + } + if (mX1 === mY1 && mX2 === mY2) { + return aX; + } + if (aX === 0) { + return 0; + } + if (aX === 1) { + return 1; + } + return calcBezier(getTForX(aX), mY1, mY2); + }; + f.getControlPoints = function () { + return [{ + x: mX1, + y: mY1 + }, { + x: mX2, + y: mY2 + }]; + }; + var str = "generateBezier(" + [mX1, mY1, mX2, mY2] + ")"; + f.toString = function () { + return str; + }; + return f; +} + +/*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */ +/* Given a tension, friction, and duration, a simulation at 60FPS will first run without a defined duration in order to calculate the full path. A second pass + then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */ +var generateSpringRK4 = function () { + function springAccelerationForState(state) { + return -state.tension * state.x - state.friction * state.v; + } + function springEvaluateStateWithDerivative(initialState, dt, derivative) { + var state = { + x: initialState.x + derivative.dx * dt, + v: initialState.v + derivative.dv * dt, + tension: initialState.tension, + friction: initialState.friction + }; + return { + dx: state.v, + dv: springAccelerationForState(state) + }; + } + function springIntegrateState(state, dt) { + var a = { + dx: state.v, + dv: springAccelerationForState(state) + }, + b = springEvaluateStateWithDerivative(state, dt * 0.5, a), + c = springEvaluateStateWithDerivative(state, dt * 0.5, b), + d = springEvaluateStateWithDerivative(state, dt, c), + dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx), + dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv); + state.x = state.x + dxdt * dt; + state.v = state.v + dvdt * dt; + return state; + } + return function springRK4Factory(tension, friction, duration) { + var initState = { + x: -1, + v: 0, + tension: null, + friction: null + }, + path = [0], + time_lapsed = 0, + tolerance = 1 / 10000, + DT = 16 / 1000, + have_duration, + dt, + last_state; + tension = parseFloat(tension) || 500; + friction = parseFloat(friction) || 20; + duration = duration || null; + initState.tension = tension; + initState.friction = friction; + have_duration = duration !== null; + + /* Calculate the actual time it takes for this animation to complete with the provided conditions. */ + if (have_duration) { + /* Run the simulation without a duration. */ + time_lapsed = springRK4Factory(tension, friction); + /* Compute the adjusted time delta. */ + dt = time_lapsed / duration * DT; + } else { + dt = DT; + } + for (;;) { + /* Next/step function .*/ + last_state = springIntegrateState(last_state || initState, dt); + /* Store the position. */ + path.push(1 + last_state.x); + time_lapsed += 16; + /* If the change threshold is reached, break. */ + if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) { + break; + } + } + + /* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the + computed path and returns a snapshot of the position according to a given percentComplete. */ + return !have_duration ? time_lapsed : function (percentComplete) { + return path[percentComplete * (path.length - 1) | 0]; + }; + }; +}(); + +var cubicBezier = function cubicBezier(t1, p1, t2, p2) { + var bezier = generateCubicBezier(t1, p1, t2, p2); + return function (start, end, percent) { + return start + (end - start) * bezier(percent); + }; +}; +var easings = { + 'linear': function linear(start, end, percent) { + return start + (end - start) * percent; + }, + // default easings + 'ease': cubicBezier(0.25, 0.1, 0.25, 1), + 'ease-in': cubicBezier(0.42, 0, 1, 1), + 'ease-out': cubicBezier(0, 0, 0.58, 1), + 'ease-in-out': cubicBezier(0.42, 0, 0.58, 1), + // sine + 'ease-in-sine': cubicBezier(0.47, 0, 0.745, 0.715), + 'ease-out-sine': cubicBezier(0.39, 0.575, 0.565, 1), + 'ease-in-out-sine': cubicBezier(0.445, 0.05, 0.55, 0.95), + // quad + 'ease-in-quad': cubicBezier(0.55, 0.085, 0.68, 0.53), + 'ease-out-quad': cubicBezier(0.25, 0.46, 0.45, 0.94), + 'ease-in-out-quad': cubicBezier(0.455, 0.03, 0.515, 0.955), + // cubic + 'ease-in-cubic': cubicBezier(0.55, 0.055, 0.675, 0.19), + 'ease-out-cubic': cubicBezier(0.215, 0.61, 0.355, 1), + 'ease-in-out-cubic': cubicBezier(0.645, 0.045, 0.355, 1), + // quart + 'ease-in-quart': cubicBezier(0.895, 0.03, 0.685, 0.22), + 'ease-out-quart': cubicBezier(0.165, 0.84, 0.44, 1), + 'ease-in-out-quart': cubicBezier(0.77, 0, 0.175, 1), + // quint + 'ease-in-quint': cubicBezier(0.755, 0.05, 0.855, 0.06), + 'ease-out-quint': cubicBezier(0.23, 1, 0.32, 1), + 'ease-in-out-quint': cubicBezier(0.86, 0, 0.07, 1), + // expo + 'ease-in-expo': cubicBezier(0.95, 0.05, 0.795, 0.035), + 'ease-out-expo': cubicBezier(0.19, 1, 0.22, 1), + 'ease-in-out-expo': cubicBezier(1, 0, 0, 1), + // circ + 'ease-in-circ': cubicBezier(0.6, 0.04, 0.98, 0.335), + 'ease-out-circ': cubicBezier(0.075, 0.82, 0.165, 1), + 'ease-in-out-circ': cubicBezier(0.785, 0.135, 0.15, 0.86), + // user param easings... + + 'spring': function spring(tension, friction, duration) { + if (duration === 0) { + // can't get a spring w/ duration 0 + return easings.linear; // duration 0 => jump to end so impl doesn't matter + } + + var spring = generateSpringRK4(tension, friction, duration); + return function (start, end, percent) { + return start + (end - start) * spring(percent); + }; + }, + 'cubic-bezier': cubicBezier +}; + +function getEasedValue(type, start, end, percent, easingFn) { + if (percent === 1) { + return end; + } + if (start === end) { + return end; + } + var val = easingFn(start, end, percent); + if (type == null) { + return val; + } + if (type.roundValue || type.color) { + val = Math.round(val); + } + if (type.min !== undefined) { + val = Math.max(val, type.min); + } + if (type.max !== undefined) { + val = Math.min(val, type.max); + } + return val; +} +function getValue(prop, spec) { + if (prop.pfValue != null || prop.value != null) { + if (prop.pfValue != null && (spec == null || spec.type.units !== '%')) { + return prop.pfValue; + } else { + return prop.value; + } + } else { + return prop; + } +} +function ease(startProp, endProp, percent, easingFn, propSpec) { + var type = propSpec != null ? propSpec.type : null; + if (percent < 0) { + percent = 0; + } else if (percent > 1) { + percent = 1; + } + var start = getValue(startProp, propSpec); + var end = getValue(endProp, propSpec); + if (number$1(start) && number$1(end)) { + return getEasedValue(type, start, end, percent, easingFn); + } else if (array(start) && array(end)) { + var easedArr = []; + for (var i = 0; i < end.length; i++) { + var si = start[i]; + var ei = end[i]; + if (si != null && ei != null) { + var val = getEasedValue(type, si, ei, percent, easingFn); + easedArr.push(val); + } else { + easedArr.push(ei); + } + } + return easedArr; + } + return undefined; +} + +function step$1(self, ani, now, isCore) { + var isEles = !isCore; + var _p = self._private; + var ani_p = ani._private; + var pEasing = ani_p.easing; + var startTime = ani_p.startTime; + var cy = isCore ? self : self.cy(); + var style = cy.style(); + if (!ani_p.easingImpl) { + if (pEasing == null) { + // use default + ani_p.easingImpl = easings['linear']; + } else { + // then define w/ name + var easingVals; + if (string(pEasing)) { + var easingProp = style.parse('transition-timing-function', pEasing); + easingVals = easingProp.value; + } else { + // then assume preparsed array + easingVals = pEasing; + } + var name, args; + if (string(easingVals)) { + name = easingVals; + args = []; + } else { + name = easingVals[1]; + args = easingVals.slice(2).map(function (n) { + return +n; + }); + } + if (args.length > 0) { + // create with args + if (name === 'spring') { + args.push(ani_p.duration); // need duration to generate spring + } + + ani_p.easingImpl = easings[name].apply(null, args); + } else { + // static impl by name + ani_p.easingImpl = easings[name]; + } + } + } + var easing = ani_p.easingImpl; + var percent; + if (ani_p.duration === 0) { + percent = 1; + } else { + percent = (now - startTime) / ani_p.duration; + } + if (ani_p.applying) { + percent = ani_p.progress; + } + if (percent < 0) { + percent = 0; + } else if (percent > 1) { + percent = 1; + } + if (ani_p.delay == null) { + // then update + + var startPos = ani_p.startPosition; + var endPos = ani_p.position; + if (endPos && isEles && !self.locked()) { + var newPos = {}; + if (valid(startPos.x, endPos.x)) { + newPos.x = ease(startPos.x, endPos.x, percent, easing); + } + if (valid(startPos.y, endPos.y)) { + newPos.y = ease(startPos.y, endPos.y, percent, easing); + } + self.position(newPos); + } + var startPan = ani_p.startPan; + var endPan = ani_p.pan; + var pan = _p.pan; + var animatingPan = endPan != null && isCore; + if (animatingPan) { + if (valid(startPan.x, endPan.x)) { + pan.x = ease(startPan.x, endPan.x, percent, easing); + } + if (valid(startPan.y, endPan.y)) { + pan.y = ease(startPan.y, endPan.y, percent, easing); + } + self.emit('pan'); + } + var startZoom = ani_p.startZoom; + var endZoom = ani_p.zoom; + var animatingZoom = endZoom != null && isCore; + if (animatingZoom) { + if (valid(startZoom, endZoom)) { + _p.zoom = bound(_p.minZoom, ease(startZoom, endZoom, percent, easing), _p.maxZoom); + } + self.emit('zoom'); + } + if (animatingPan || animatingZoom) { + self.emit('viewport'); + } + var props = ani_p.style; + if (props && props.length > 0 && isEles) { + for (var i = 0; i < props.length; i++) { + var prop = props[i]; + var _name = prop.name; + var end = prop; + var start = ani_p.startStyle[_name]; + var propSpec = style.properties[start.name]; + var easedVal = ease(start, end, percent, easing, propSpec); + style.overrideBypass(self, _name, easedVal); + } // for props + + self.emit('style'); + } // if + } + + ani_p.progress = percent; + return percent; +} +function valid(start, end) { + if (start == null || end == null) { + return false; + } + if (number$1(start) && number$1(end)) { + return true; + } else if (start && end) { + return true; + } + return false; +} + +function startAnimation(self, ani, now, isCore) { + var ani_p = ani._private; + ani_p.started = true; + ani_p.startTime = now - ani_p.progress * ani_p.duration; +} + +function stepAll(now, cy) { + var eles = cy._private.aniEles; + var doneEles = []; + function stepOne(ele, isCore) { + var _p = ele._private; + var current = _p.animation.current; + var queue = _p.animation.queue; + var ranAnis = false; + + // if nothing currently animating, get something from the queue + if (current.length === 0) { + var next = queue.shift(); + if (next) { + current.push(next); + } + } + var callbacks = function callbacks(_callbacks) { + for (var j = _callbacks.length - 1; j >= 0; j--) { + var cb = _callbacks[j]; + cb(); + } + _callbacks.splice(0, _callbacks.length); + }; + + // step and remove if done + for (var i = current.length - 1; i >= 0; i--) { + var ani = current[i]; + var ani_p = ani._private; + if (ani_p.stopped) { + current.splice(i, 1); + ani_p.hooked = false; + ani_p.playing = false; + ani_p.started = false; + callbacks(ani_p.frames); + continue; + } + if (!ani_p.playing && !ani_p.applying) { + continue; + } + + // an apply() while playing shouldn't do anything + if (ani_p.playing && ani_p.applying) { + ani_p.applying = false; + } + if (!ani_p.started) { + startAnimation(ele, ani, now); + } + step$1(ele, ani, now, isCore); + if (ani_p.applying) { + ani_p.applying = false; + } + callbacks(ani_p.frames); + if (ani_p.step != null) { + ani_p.step(now); + } + if (ani.completed()) { + current.splice(i, 1); + ani_p.hooked = false; + ani_p.playing = false; + ani_p.started = false; + callbacks(ani_p.completes); + } + ranAnis = true; + } + if (!isCore && current.length === 0 && queue.length === 0) { + doneEles.push(ele); + } + return ranAnis; + } // stepElement + + // handle all eles + var ranEleAni = false; + for (var e = 0; e < eles.length; e++) { + var ele = eles[e]; + var handledThisEle = stepOne(ele); + ranEleAni = ranEleAni || handledThisEle; + } // each element + + var ranCoreAni = stepOne(cy, true); + + // notify renderer + if (ranEleAni || ranCoreAni) { + if (eles.length > 0) { + cy.notify('draw', eles); + } else { + cy.notify('draw'); + } + } + + // remove elements from list of currently animating if its queues are empty + eles.unmerge(doneEles); + cy.emit('step'); +} // stepAll + +var corefn$8 = { + // pull in animation functions + animate: define.animate(), + animation: define.animation(), + animated: define.animated(), + clearQueue: define.clearQueue(), + delay: define.delay(), + delayAnimation: define.delayAnimation(), + stop: define.stop(), + addToAnimationPool: function addToAnimationPool(eles) { + var cy = this; + if (!cy.styleEnabled()) { + return; + } // save cycles when no style used + + cy._private.aniEles.merge(eles); + }, + stopAnimationLoop: function stopAnimationLoop() { + this._private.animationsRunning = false; + }, + startAnimationLoop: function startAnimationLoop() { + var cy = this; + cy._private.animationsRunning = true; + if (!cy.styleEnabled()) { + return; + } // save cycles when no style used + + // NB the animation loop will exec in headless environments if style enabled + // and explicit cy.destroy() is necessary to stop the loop + + function headlessStep() { + if (!cy._private.animationsRunning) { + return; + } + requestAnimationFrame(function animationStep(now) { + stepAll(now, cy); + headlessStep(); + }); + } + var renderer = cy.renderer(); + if (renderer && renderer.beforeRender) { + // let the renderer schedule animations + renderer.beforeRender(function rendererAnimationStep(willDraw, now) { + stepAll(now, cy); + }, renderer.beforeRenderPriorities.animations); + } else { + // manage the animation loop ourselves + headlessStep(); // first call + } + } +}; + +var emitterOptions = { + qualifierCompare: function qualifierCompare(selector1, selector2) { + if (selector1 == null || selector2 == null) { + return selector1 == null && selector2 == null; + } else { + return selector1.sameText(selector2); + } + }, + eventMatches: function eventMatches(cy, listener, eventObj) { + var selector = listener.qualifier; + if (selector != null) { + return cy !== eventObj.target && element(eventObj.target) && selector.matches(eventObj.target); + } + return true; + }, + addEventFields: function addEventFields(cy, evt) { + evt.cy = cy; + evt.target = cy; + }, + callbackContext: function callbackContext(cy, listener, eventObj) { + return listener.qualifier != null ? eventObj.target : cy; + } +}; +var argSelector = function argSelector(arg) { + if (string(arg)) { + return new Selector(arg); + } else { + return arg; + } +}; +var elesfn = { + createEmitter: function createEmitter() { + var _p = this._private; + if (!_p.emitter) { + _p.emitter = new Emitter(emitterOptions, this); + } + return this; + }, + emitter: function emitter() { + return this._private.emitter; + }, + on: function on(events, selector, callback) { + this.emitter().on(events, argSelector(selector), callback); + return this; + }, + removeListener: function removeListener(events, selector, callback) { + this.emitter().removeListener(events, argSelector(selector), callback); + return this; + }, + removeAllListeners: function removeAllListeners() { + this.emitter().removeAllListeners(); + return this; + }, + one: function one(events, selector, callback) { + this.emitter().one(events, argSelector(selector), callback); + return this; + }, + once: function once(events, selector, callback) { + this.emitter().one(events, argSelector(selector), callback); + return this; + }, + emit: function emit(events, extraParams) { + this.emitter().emit(events, extraParams); + return this; + }, + emitAndNotify: function emitAndNotify(event, eles) { + this.emit(event); + this.notify(event, eles); + return this; + } +}; +define.eventAliasesOn(elesfn); + +var corefn$7 = { + png: function png(options) { + var renderer = this._private.renderer; + options = options || {}; + return renderer.png(options); + }, + jpg: function jpg(options) { + var renderer = this._private.renderer; + options = options || {}; + options.bg = options.bg || '#fff'; + return renderer.jpg(options); + } +}; +corefn$7.jpeg = corefn$7.jpg; + +var corefn$6 = { + layout: function layout(options) { + var cy = this; + if (options == null) { + error('Layout options must be specified to make a layout'); + return; + } + if (options.name == null) { + error('A `name` must be specified to make a layout'); + return; + } + var name = options.name; + var Layout = cy.extension('layout', name); + if (Layout == null) { + error('No such layout `' + name + '` found. Did you forget to import it and `cytoscape.use()` it?'); + return; + } + var eles; + if (string(options.eles)) { + eles = cy.$(options.eles); + } else { + eles = options.eles != null ? options.eles : cy.$(); + } + var layout = new Layout(extend({}, options, { + cy: cy, + eles: eles + })); + return layout; + } +}; +corefn$6.createLayout = corefn$6.makeLayout = corefn$6.layout; + +var corefn$5 = { + notify: function notify(eventName, eventEles) { + var _p = this._private; + if (this.batching()) { + _p.batchNotifications = _p.batchNotifications || {}; + var eles = _p.batchNotifications[eventName] = _p.batchNotifications[eventName] || this.collection(); + if (eventEles != null) { + eles.merge(eventEles); + } + return; // notifications are disabled during batching + } + + if (!_p.notificationsEnabled) { + return; + } // exit on disabled + + var renderer = this.renderer(); + + // exit if destroy() called on core or renderer in between frames #1499 #1528 + if (this.destroyed() || !renderer) { + return; + } + renderer.notify(eventName, eventEles); + }, + notifications: function notifications(bool) { + var p = this._private; + if (bool === undefined) { + return p.notificationsEnabled; + } else { + p.notificationsEnabled = bool ? true : false; + } + return this; + }, + noNotifications: function noNotifications(callback) { + this.notifications(false); + callback(); + this.notifications(true); + }, + batching: function batching() { + return this._private.batchCount > 0; + }, + startBatch: function startBatch() { + var _p = this._private; + if (_p.batchCount == null) { + _p.batchCount = 0; + } + if (_p.batchCount === 0) { + _p.batchStyleEles = this.collection(); + _p.batchNotifications = {}; + } + _p.batchCount++; + return this; + }, + endBatch: function endBatch() { + var _p = this._private; + if (_p.batchCount === 0) { + return this; + } + _p.batchCount--; + if (_p.batchCount === 0) { + // update style for dirty eles + _p.batchStyleEles.updateStyle(); + var renderer = this.renderer(); + + // notify the renderer of queued eles and event types + Object.keys(_p.batchNotifications).forEach(function (eventName) { + var eles = _p.batchNotifications[eventName]; + if (eles.empty()) { + renderer.notify(eventName); + } else { + renderer.notify(eventName, eles); + } + }); + } + return this; + }, + batch: function batch(callback) { + this.startBatch(); + callback(); + this.endBatch(); + return this; + }, + // for backwards compatibility + batchData: function batchData(map) { + var cy = this; + return this.batch(function () { + var ids = Object.keys(map); + for (var i = 0; i < ids.length; i++) { + var id = ids[i]; + var data = map[id]; + var ele = cy.getElementById(id); + ele.data(data); + } + }); + } +}; + +var rendererDefaults = defaults$g({ + hideEdgesOnViewport: false, + textureOnViewport: false, + motionBlur: false, + motionBlurOpacity: 0.05, + pixelRatio: undefined, + desktopTapThreshold: 4, + touchTapThreshold: 8, + wheelSensitivity: 1, + debug: false, + showFps: false +}); +var corefn$4 = { + renderTo: function renderTo(context, zoom, pan, pxRatio) { + var r = this._private.renderer; + r.renderTo(context, zoom, pan, pxRatio); + return this; + }, + renderer: function renderer() { + return this._private.renderer; + }, + forceRender: function forceRender() { + this.notify('draw'); + return this; + }, + resize: function resize() { + this.invalidateSize(); + this.emitAndNotify('resize'); + return this; + }, + initRenderer: function initRenderer(options) { + var cy = this; + var RendererProto = cy.extension('renderer', options.name); + if (RendererProto == null) { + error("Can not initialise: No such renderer `".concat(options.name, "` found. Did you forget to import it and `cytoscape.use()` it?")); + return; + } + if (options.wheelSensitivity !== undefined) { + warn("You have set a custom wheel sensitivity. This will make your app zoom unnaturally when using mainstream mice. You should change this value from the default only if you can guarantee that all your users will use the same hardware and OS configuration as your current machine."); + } + var rOpts = rendererDefaults(options); + rOpts.cy = cy; + cy._private.renderer = new RendererProto(rOpts); + this.notify('init'); + }, + destroyRenderer: function destroyRenderer() { + var cy = this; + cy.notify('destroy'); // destroy the renderer + + var domEle = cy.container(); + if (domEle) { + domEle._cyreg = null; + while (domEle.childNodes.length > 0) { + domEle.removeChild(domEle.childNodes[0]); + } + } + cy._private.renderer = null; // to be extra safe, remove the ref + cy.mutableElements().forEach(function (ele) { + var _p = ele._private; + _p.rscratch = {}; + _p.rstyle = {}; + _p.animation.current = []; + _p.animation.queue = []; + }); + }, + onRender: function onRender(fn) { + return this.on('render', fn); + }, + offRender: function offRender(fn) { + return this.off('render', fn); + } +}; +corefn$4.invalidateDimensions = corefn$4.resize; + +var corefn$3 = { + // get a collection + // - empty collection on no args + // - collection of elements in the graph on selector arg + // - guarantee a returned collection when elements or collection specified + collection: function collection(eles, opts) { + if (string(eles)) { + return this.$(eles); + } else if (elementOrCollection(eles)) { + return eles.collection(); + } else if (array(eles)) { + if (!opts) { + opts = {}; + } + return new Collection(this, eles, opts.unique, opts.removed); + } + return new Collection(this); + }, + nodes: function nodes(selector) { + var nodes = this.$(function (ele) { + return ele.isNode(); + }); + if (selector) { + return nodes.filter(selector); + } + return nodes; + }, + edges: function edges(selector) { + var edges = this.$(function (ele) { + return ele.isEdge(); + }); + if (selector) { + return edges.filter(selector); + } + return edges; + }, + // search the graph like jQuery + $: function $(selector) { + var eles = this._private.elements; + if (selector) { + return eles.filter(selector); + } else { + return eles.spawnSelf(); + } + }, + mutableElements: function mutableElements() { + return this._private.elements; + } +}; + +// aliases +corefn$3.elements = corefn$3.filter = corefn$3.$; + +var styfn$8 = {}; + +// keys for style blocks, e.g. ttfftt +var TRUE = 't'; +var FALSE = 'f'; + +// (potentially expensive calculation) +// apply the style to the element based on +// - its bypass +// - what selectors match it +styfn$8.apply = function (eles) { + var self = this; + var _p = self._private; + var cy = _p.cy; + var updatedEles = cy.collection(); + for (var ie = 0; ie < eles.length; ie++) { + var ele = eles[ie]; + var cxtMeta = self.getContextMeta(ele); + if (cxtMeta.empty) { + continue; + } + var cxtStyle = self.getContextStyle(cxtMeta); + var app = self.applyContextStyle(cxtMeta, cxtStyle, ele); + if (ele._private.appliedInitStyle) { + self.updateTransitions(ele, app.diffProps); + } else { + ele._private.appliedInitStyle = true; + } + var hintsDiff = self.updateStyleHints(ele); + if (hintsDiff) { + updatedEles.push(ele); + } + } // for elements + + return updatedEles; +}; +styfn$8.getPropertiesDiff = function (oldCxtKey, newCxtKey) { + var self = this; + var cache = self._private.propDiffs = self._private.propDiffs || {}; + var dualCxtKey = oldCxtKey + '-' + newCxtKey; + var cachedVal = cache[dualCxtKey]; + if (cachedVal) { + return cachedVal; + } + var diffProps = []; + var addedProp = {}; + for (var i = 0; i < self.length; i++) { + var cxt = self[i]; + var oldHasCxt = oldCxtKey[i] === TRUE; + var newHasCxt = newCxtKey[i] === TRUE; + var cxtHasDiffed = oldHasCxt !== newHasCxt; + var cxtHasMappedProps = cxt.mappedProperties.length > 0; + if (cxtHasDiffed || newHasCxt && cxtHasMappedProps) { + var props = void 0; + if (cxtHasDiffed && cxtHasMappedProps) { + props = cxt.properties; // suffices b/c mappedProperties is a subset of properties + } else if (cxtHasDiffed) { + props = cxt.properties; // need to check them all + } else if (cxtHasMappedProps) { + props = cxt.mappedProperties; // only need to check mapped + } + + for (var j = 0; j < props.length; j++) { + var prop = props[j]; + var name = prop.name; + + // if a later context overrides this property, then the fact that this context has switched/diffed doesn't matter + // (semi expensive check since it makes this function O(n^2) on context length, but worth it since overall result + // is cached) + var laterCxtOverrides = false; + for (var k = i + 1; k < self.length; k++) { + var laterCxt = self[k]; + var hasLaterCxt = newCxtKey[k] === TRUE; + if (!hasLaterCxt) { + continue; + } // can't override unless the context is active + + laterCxtOverrides = laterCxt.properties[prop.name] != null; + if (laterCxtOverrides) { + break; + } // exit early as long as one later context overrides + } + + if (!addedProp[name] && !laterCxtOverrides) { + addedProp[name] = true; + diffProps.push(name); + } + } // for props + } // if + } // for contexts + + cache[dualCxtKey] = diffProps; + return diffProps; +}; +styfn$8.getContextMeta = function (ele) { + var self = this; + var cxtKey = ''; + var diffProps; + var prevKey = ele._private.styleCxtKey || ''; + + // get the cxt key + for (var i = 0; i < self.length; i++) { + var context = self[i]; + var contextSelectorMatches = context.selector && context.selector.matches(ele); // NB: context.selector may be null for 'core' + + if (contextSelectorMatches) { + cxtKey += TRUE; + } else { + cxtKey += FALSE; + } + } // for context + + diffProps = self.getPropertiesDiff(prevKey, cxtKey); + ele._private.styleCxtKey = cxtKey; + return { + key: cxtKey, + diffPropNames: diffProps, + empty: diffProps.length === 0 + }; +}; + +// gets a computed ele style object based on matched contexts +styfn$8.getContextStyle = function (cxtMeta) { + var cxtKey = cxtMeta.key; + var self = this; + var cxtStyles = this._private.contextStyles = this._private.contextStyles || {}; + + // if already computed style, returned cached copy + if (cxtStyles[cxtKey]) { + return cxtStyles[cxtKey]; + } + var style = { + _private: { + key: cxtKey + } + }; + for (var i = 0; i < self.length; i++) { + var cxt = self[i]; + var hasCxt = cxtKey[i] === TRUE; + if (!hasCxt) { + continue; + } + for (var j = 0; j < cxt.properties.length; j++) { + var prop = cxt.properties[j]; + style[prop.name] = prop; + } + } + cxtStyles[cxtKey] = style; + return style; +}; +styfn$8.applyContextStyle = function (cxtMeta, cxtStyle, ele) { + var self = this; + var diffProps = cxtMeta.diffPropNames; + var retDiffProps = {}; + var types = self.types; + for (var i = 0; i < diffProps.length; i++) { + var diffPropName = diffProps[i]; + var cxtProp = cxtStyle[diffPropName]; + var eleProp = ele.pstyle(diffPropName); + if (!cxtProp) { + // no context prop means delete + if (!eleProp) { + continue; // no existing prop means nothing needs to be removed + // nb affects initial application on mapped values like control-point-distances + } else if (eleProp.bypass) { + cxtProp = { + name: diffPropName, + deleteBypassed: true + }; + } else { + cxtProp = { + name: diffPropName, + "delete": true + }; + } + } + + // save cycles when the context prop doesn't need to be applied + if (eleProp === cxtProp) { + continue; + } + + // save cycles when a mapped context prop doesn't need to be applied + if (cxtProp.mapped === types.fn // context prop is function mapper + && eleProp != null // some props can be null even by default (e.g. a prop that overrides another one) + && eleProp.mapping != null // ele prop is a concrete value from from a mapper + && eleProp.mapping.value === cxtProp.value // the current prop on the ele is a flat prop value for the function mapper + ) { + // NB don't write to cxtProp, as it's shared among eles (stored in stylesheet) + var mapping = eleProp.mapping; // can write to mapping, as it's a per-ele copy + var fnValue = mapping.fnValue = cxtProp.value(ele); // temporarily cache the value in case of a miss + + if (fnValue === mapping.prevFnValue) { + continue; + } + } + var retDiffProp = retDiffProps[diffPropName] = { + prev: eleProp + }; + self.applyParsedProperty(ele, cxtProp); + retDiffProp.next = ele.pstyle(diffPropName); + if (retDiffProp.next && retDiffProp.next.bypass) { + retDiffProp.next = retDiffProp.next.bypassed; + } + } + return { + diffProps: retDiffProps + }; +}; +styfn$8.updateStyleHints = function (ele) { + var _p = ele._private; + var self = this; + var propNames = self.propertyGroupNames; + var propGrKeys = self.propertyGroupKeys; + var propHash = function propHash(ele, propNames, seedKey) { + return self.getPropertiesHash(ele, propNames, seedKey); + }; + var oldStyleKey = _p.styleKey; + if (ele.removed()) { + return false; + } + var isNode = _p.group === 'nodes'; + + // get the style key hashes per prop group + // but lazily -- only use non-default prop values to reduce the number of hashes + // + + var overriddenStyles = ele._private.style; + propNames = Object.keys(overriddenStyles); + for (var i = 0; i < propGrKeys.length; i++) { + var grKey = propGrKeys[i]; + _p.styleKeys[grKey] = [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT]; + } + var updateGrKey1 = function updateGrKey1(val, grKey) { + return _p.styleKeys[grKey][0] = hashInt(val, _p.styleKeys[grKey][0]); + }; + var updateGrKey2 = function updateGrKey2(val, grKey) { + return _p.styleKeys[grKey][1] = hashIntAlt(val, _p.styleKeys[grKey][1]); + }; + var updateGrKey = function updateGrKey(val, grKey) { + updateGrKey1(val, grKey); + updateGrKey2(val, grKey); + }; + var updateGrKeyWStr = function updateGrKeyWStr(strVal, grKey) { + for (var j = 0; j < strVal.length; j++) { + var ch = strVal.charCodeAt(j); + updateGrKey1(ch, grKey); + updateGrKey2(ch, grKey); + } + }; + + // - hashing works on 32 bit ints b/c we use bitwise ops + // - small numbers get cut off (e.g. 0.123 is seen as 0 by the hashing function) + // - raise up small numbers so more significant digits are seen by hashing + // - make small numbers larger than a normal value to avoid collisions + // - works in practice and it's relatively cheap + var N = 2000000000; + var cleanNum = function cleanNum(val) { + return -128 < val && val < 128 && Math.floor(val) !== val ? N - (val * 1024 | 0) : val; + }; + for (var _i = 0; _i < propNames.length; _i++) { + var name = propNames[_i]; + var parsedProp = overriddenStyles[name]; + if (parsedProp == null) { + continue; + } + var propInfo = this.properties[name]; + var type = propInfo.type; + var _grKey = propInfo.groupKey; + var normalizedNumberVal = void 0; + if (propInfo.hashOverride != null) { + normalizedNumberVal = propInfo.hashOverride(ele, parsedProp); + } else if (parsedProp.pfValue != null) { + normalizedNumberVal = parsedProp.pfValue; + } + + // might not be a number if it allows enums + var numberVal = propInfo.enums == null ? parsedProp.value : null; + var haveNormNum = normalizedNumberVal != null; + var haveUnitedNum = numberVal != null; + var haveNum = haveNormNum || haveUnitedNum; + var units = parsedProp.units; + + // numbers are cheaper to hash than strings + // 1 hash op vs n hash ops (for length n string) + if (type.number && haveNum && !type.multiple) { + var v = haveNormNum ? normalizedNumberVal : numberVal; + updateGrKey(cleanNum(v), _grKey); + if (!haveNormNum && units != null) { + updateGrKeyWStr(units, _grKey); + } + } else { + updateGrKeyWStr(parsedProp.strValue, _grKey); + } + } + + // overall style key + // + + var hash = [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT]; + for (var _i2 = 0; _i2 < propGrKeys.length; _i2++) { + var _grKey2 = propGrKeys[_i2]; + var grHash = _p.styleKeys[_grKey2]; + hash[0] = hashInt(grHash[0], hash[0]); + hash[1] = hashIntAlt(grHash[1], hash[1]); + } + _p.styleKey = combineHashes(hash[0], hash[1]); + + // label dims + // + + var sk = _p.styleKeys; + _p.labelDimsKey = combineHashesArray(sk.labelDimensions); + var labelKeys = propHash(ele, ['label'], sk.labelDimensions); + _p.labelKey = combineHashesArray(labelKeys); + _p.labelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, labelKeys)); + if (!isNode) { + var sourceLabelKeys = propHash(ele, ['source-label'], sk.labelDimensions); + _p.sourceLabelKey = combineHashesArray(sourceLabelKeys); + _p.sourceLabelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, sourceLabelKeys)); + var targetLabelKeys = propHash(ele, ['target-label'], sk.labelDimensions); + _p.targetLabelKey = combineHashesArray(targetLabelKeys); + _p.targetLabelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, targetLabelKeys)); + } + + // node + // + + if (isNode) { + var _p$styleKeys = _p.styleKeys, + nodeBody = _p$styleKeys.nodeBody, + nodeBorder = _p$styleKeys.nodeBorder, + nodeOutline = _p$styleKeys.nodeOutline, + backgroundImage = _p$styleKeys.backgroundImage, + compound = _p$styleKeys.compound, + pie = _p$styleKeys.pie; + var nodeKeys = [nodeBody, nodeBorder, nodeOutline, backgroundImage, compound, pie].filter(function (k) { + return k != null; + }).reduce(hashArrays, [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT]); + _p.nodeKey = combineHashesArray(nodeKeys); + _p.hasPie = pie != null && pie[0] !== DEFAULT_HASH_SEED && pie[1] !== DEFAULT_HASH_SEED_ALT; + } + return oldStyleKey !== _p.styleKey; +}; +styfn$8.clearStyleHints = function (ele) { + var _p = ele._private; + _p.styleCxtKey = ''; + _p.styleKeys = {}; + _p.styleKey = null; + _p.labelKey = null; + _p.labelStyleKey = null; + _p.sourceLabelKey = null; + _p.sourceLabelStyleKey = null; + _p.targetLabelKey = null; + _p.targetLabelStyleKey = null; + _p.nodeKey = null; + _p.hasPie = null; +}; + +// apply a property to the style (for internal use) +// returns whether application was successful +// +// now, this function flattens the property, and here's how: +// +// for parsedProp:{ bypass: true, deleteBypass: true } +// no property is generated, instead the bypass property in the +// element's style is replaced by what's pointed to by the `bypassed` +// field in the bypass property (i.e. restoring the property the +// bypass was overriding) +// +// for parsedProp:{ mapped: truthy } +// the generated flattenedProp:{ mapping: prop } +// +// for parsedProp:{ bypass: true } +// the generated flattenedProp:{ bypassed: parsedProp } +styfn$8.applyParsedProperty = function (ele, parsedProp) { + var self = this; + var prop = parsedProp; + var style = ele._private.style; + var flatProp; + var types = self.types; + var type = self.properties[prop.name].type; + var propIsBypass = prop.bypass; + var origProp = style[prop.name]; + var origPropIsBypass = origProp && origProp.bypass; + var _p = ele._private; + var flatPropMapping = 'mapping'; + var getVal = function getVal(p) { + if (p == null) { + return null; + } else if (p.pfValue != null) { + return p.pfValue; + } else { + return p.value; + } + }; + var checkTriggers = function checkTriggers() { + var fromVal = getVal(origProp); + var toVal = getVal(prop); + self.checkTriggers(ele, prop.name, fromVal, toVal); + }; + + // edge sanity checks to prevent the client from making serious mistakes + if (parsedProp.name === 'curve-style' && ele.isEdge() && ( + // loops must be bundled beziers + parsedProp.value !== 'bezier' && ele.isLoop() || + // edges connected to compound nodes can not be haystacks + parsedProp.value === 'haystack' && (ele.source().isParent() || ele.target().isParent()))) { + prop = parsedProp = this.parse(parsedProp.name, 'bezier', propIsBypass); + } + if (prop["delete"]) { + // delete the property and use the default value on falsey value + style[prop.name] = undefined; + checkTriggers(); + return true; + } + if (prop.deleteBypassed) { + // delete the property that the + if (!origProp) { + checkTriggers(); + return true; // can't delete if no prop + } else if (origProp.bypass) { + // delete bypassed + origProp.bypassed = undefined; + checkTriggers(); + return true; + } else { + return false; // we're unsuccessful deleting the bypassed + } + } + + // check if we need to delete the current bypass + if (prop.deleteBypass) { + // then this property is just here to indicate we need to delete + if (!origProp) { + checkTriggers(); + return true; // property is already not defined + } else if (origProp.bypass) { + // then replace the bypass property with the original + // because the bypassed property was already applied (and therefore parsed), we can just replace it (no reapplying necessary) + style[prop.name] = origProp.bypassed; + checkTriggers(); + return true; + } else { + return false; // we're unsuccessful deleting the bypass + } + } + + var printMappingErr = function printMappingErr() { + warn('Do not assign mappings to elements without corresponding data (i.e. ele `' + ele.id() + '` has no mapping for property `' + prop.name + '` with data field `' + prop.field + '`); try a `[' + prop.field + ']` selector to limit scope to elements with `' + prop.field + '` defined'); + }; + + // put the property in the style objects + switch (prop.mapped) { + // flatten the property if mapped + case types.mapData: + { + // flatten the field (e.g. data.foo.bar) + var fields = prop.field.split('.'); + var fieldVal = _p.data; + for (var i = 0; i < fields.length && fieldVal; i++) { + var field = fields[i]; + fieldVal = fieldVal[field]; + } + if (fieldVal == null) { + printMappingErr(); + return false; + } + var percent; + if (!number$1(fieldVal)) { + // then don't apply and fall back on the existing style + warn('Do not use continuous mappers without specifying numeric data (i.e. `' + prop.field + ': ' + fieldVal + '` for `' + ele.id() + '` is non-numeric)'); + return false; + } else { + var fieldWidth = prop.fieldMax - prop.fieldMin; + if (fieldWidth === 0) { + // safety check -- not strictly necessary as no props of zero range should be passed here + percent = 0; + } else { + percent = (fieldVal - prop.fieldMin) / fieldWidth; + } + } + + // make sure to bound percent value + if (percent < 0) { + percent = 0; + } else if (percent > 1) { + percent = 1; + } + if (type.color) { + var r1 = prop.valueMin[0]; + var r2 = prop.valueMax[0]; + var g1 = prop.valueMin[1]; + var g2 = prop.valueMax[1]; + var b1 = prop.valueMin[2]; + var b2 = prop.valueMax[2]; + var a1 = prop.valueMin[3] == null ? 1 : prop.valueMin[3]; + var a2 = prop.valueMax[3] == null ? 1 : prop.valueMax[3]; + var clr = [Math.round(r1 + (r2 - r1) * percent), Math.round(g1 + (g2 - g1) * percent), Math.round(b1 + (b2 - b1) * percent), Math.round(a1 + (a2 - a1) * percent)]; + flatProp = { + // colours are simple, so just create the flat property instead of expensive string parsing + bypass: prop.bypass, + // we're a bypass if the mapping property is a bypass + name: prop.name, + value: clr, + strValue: 'rgb(' + clr[0] + ', ' + clr[1] + ', ' + clr[2] + ')' + }; + } else if (type.number) { + var calcValue = prop.valueMin + (prop.valueMax - prop.valueMin) * percent; + flatProp = this.parse(prop.name, calcValue, prop.bypass, flatPropMapping); + } else { + return false; // can only map to colours and numbers + } + + if (!flatProp) { + // if we can't flatten the property, then don't apply the property and fall back on the existing style + printMappingErr(); + return false; + } + flatProp.mapping = prop; // keep a reference to the mapping + prop = flatProp; // the flattened (mapped) property is the one we want + + break; + } + + // direct mapping + case types.data: + { + // flatten the field (e.g. data.foo.bar) + var _fields = prop.field.split('.'); + var _fieldVal = _p.data; + for (var _i3 = 0; _i3 < _fields.length && _fieldVal; _i3++) { + var _field = _fields[_i3]; + _fieldVal = _fieldVal[_field]; + } + if (_fieldVal != null) { + flatProp = this.parse(prop.name, _fieldVal, prop.bypass, flatPropMapping); + } + if (!flatProp) { + // if we can't flatten the property, then don't apply and fall back on the existing style + printMappingErr(); + return false; + } + flatProp.mapping = prop; // keep a reference to the mapping + prop = flatProp; // the flattened (mapped) property is the one we want + + break; + } + case types.fn: + { + var fn = prop.value; + var fnRetVal = prop.fnValue != null ? prop.fnValue : fn(ele); // check for cached value before calling function + + prop.prevFnValue = fnRetVal; + if (fnRetVal == null) { + warn('Custom function mappers may not return null (i.e. `' + prop.name + '` for ele `' + ele.id() + '` is null)'); + return false; + } + flatProp = this.parse(prop.name, fnRetVal, prop.bypass, flatPropMapping); + if (!flatProp) { + warn('Custom function mappers may not return invalid values for the property type (i.e. `' + prop.name + '` for ele `' + ele.id() + '` is invalid)'); + return false; + } + flatProp.mapping = copy(prop); // keep a reference to the mapping + prop = flatProp; // the flattened (mapped) property is the one we want + + break; + } + case undefined: + break; + // just set the property + + default: + return false; + // not a valid mapping + } + + // if the property is a bypass property, then link the resultant property to the original one + if (propIsBypass) { + if (origPropIsBypass) { + // then this bypass overrides the existing one + prop.bypassed = origProp.bypassed; // steal bypassed prop from old bypass + } else { + // then link the orig prop to the new bypass + prop.bypassed = origProp; + } + style[prop.name] = prop; // and set + } else { + // prop is not bypass + if (origPropIsBypass) { + // then keep the orig prop (since it's a bypass) and link to the new prop + origProp.bypassed = prop; + } else { + // then just replace the old prop with the new one + style[prop.name] = prop; + } + } + checkTriggers(); + return true; +}; +styfn$8.cleanElements = function (eles, keepBypasses) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + this.clearStyleHints(ele); + ele.dirtyCompoundBoundsCache(); + ele.dirtyBoundingBoxCache(); + if (!keepBypasses) { + ele._private.style = {}; + } else { + var style = ele._private.style; + var propNames = Object.keys(style); + for (var j = 0; j < propNames.length; j++) { + var propName = propNames[j]; + var eleProp = style[propName]; + if (eleProp != null) { + if (eleProp.bypass) { + eleProp.bypassed = null; + } else { + style[propName] = null; + } + } + } + } + } +}; + +// updates the visual style for all elements (useful for manual style modification after init) +styfn$8.update = function () { + var cy = this._private.cy; + var eles = cy.mutableElements(); + eles.updateStyle(); +}; + +// diffProps : { name => { prev, next } } +styfn$8.updateTransitions = function (ele, diffProps) { + var self = this; + var _p = ele._private; + var props = ele.pstyle('transition-property').value; + var duration = ele.pstyle('transition-duration').pfValue; + var delay = ele.pstyle('transition-delay').pfValue; + if (props.length > 0 && duration > 0) { + var style = {}; + + // build up the style to animate towards + var anyPrev = false; + for (var i = 0; i < props.length; i++) { + var prop = props[i]; + var styProp = ele.pstyle(prop); + var diffProp = diffProps[prop]; + if (!diffProp) { + continue; + } + var prevProp = diffProp.prev; + var fromProp = prevProp; + var toProp = diffProp.next != null ? diffProp.next : styProp; + var diff = false; + var initVal = void 0; + var initDt = 0.000001; // delta time % value for initVal (allows animating out of init zero opacity) + + if (!fromProp) { + continue; + } + + // consider px values + if (number$1(fromProp.pfValue) && number$1(toProp.pfValue)) { + diff = toProp.pfValue - fromProp.pfValue; // nonzero is truthy + initVal = fromProp.pfValue + initDt * diff; + + // consider numerical values + } else if (number$1(fromProp.value) && number$1(toProp.value)) { + diff = toProp.value - fromProp.value; // nonzero is truthy + initVal = fromProp.value + initDt * diff; + + // consider colour values + } else if (array(fromProp.value) && array(toProp.value)) { + diff = fromProp.value[0] !== toProp.value[0] || fromProp.value[1] !== toProp.value[1] || fromProp.value[2] !== toProp.value[2]; + initVal = fromProp.strValue; + } + + // the previous value is good for an animation only if it's different + if (diff) { + style[prop] = toProp.strValue; // to val + this.applyBypass(ele, prop, initVal); // from val + anyPrev = true; + } + } // end if props allow ani + + // can't transition if there's nothing previous to transition from + if (!anyPrev) { + return; + } + _p.transitioning = true; + new Promise$1(function (resolve) { + if (delay > 0) { + ele.delayAnimation(delay).play().promise().then(resolve); + } else { + resolve(); + } + }).then(function () { + return ele.animation({ + style: style, + duration: duration, + easing: ele.pstyle('transition-timing-function').value, + queue: false + }).play().promise(); + }).then(function () { + // if( !isBypass ){ + self.removeBypasses(ele, props); + ele.emitAndNotify('style'); + // } + + _p.transitioning = false; + }); + } else if (_p.transitioning) { + this.removeBypasses(ele, props); + ele.emitAndNotify('style'); + _p.transitioning = false; + } +}; +styfn$8.checkTrigger = function (ele, name, fromValue, toValue, getTrigger, onTrigger) { + var prop = this.properties[name]; + var triggerCheck = getTrigger(prop); + if (triggerCheck != null && triggerCheck(fromValue, toValue)) { + onTrigger(prop); + } +}; +styfn$8.checkZOrderTrigger = function (ele, name, fromValue, toValue) { + var _this = this; + this.checkTrigger(ele, name, fromValue, toValue, function (prop) { + return prop.triggersZOrder; + }, function () { + _this._private.cy.notify('zorder', ele); + }); +}; +styfn$8.checkBoundsTrigger = function (ele, name, fromValue, toValue) { + this.checkTrigger(ele, name, fromValue, toValue, function (prop) { + return prop.triggersBounds; + }, function (prop) { + ele.dirtyCompoundBoundsCache(); + ele.dirtyBoundingBoxCache(); + + // if the prop change makes the bb of pll bezier edges invalid, + // then dirty the pll edge bb cache as well + if ( + // only for beziers -- so performance of other edges isn't affected + prop.triggersBoundsOfParallelBeziers && name === 'curve-style' && (fromValue === 'bezier' || toValue === 'bezier')) { + ele.parallelEdges().forEach(function (pllEdge) { + if (pllEdge.isBundledBezier()) { + pllEdge.dirtyBoundingBoxCache(); + } + }); + } + if (prop.triggersBoundsOfConnectedEdges && name === 'display' && (fromValue === 'none' || toValue === 'none')) { + ele.connectedEdges().forEach(function (edge) { + edge.dirtyBoundingBoxCache(); + }); + } + }); +}; +styfn$8.checkTriggers = function (ele, name, fromValue, toValue) { + ele.dirtyStyleCache(); + this.checkZOrderTrigger(ele, name, fromValue, toValue); + this.checkBoundsTrigger(ele, name, fromValue, toValue); +}; + +var styfn$7 = {}; + +// bypasses are applied to an existing style on an element, and just tacked on temporarily +// returns true iff application was successful for at least 1 specified property +styfn$7.applyBypass = function (eles, name, value, updateTransitions) { + var self = this; + var props = []; + var isBypass = true; + + // put all the properties (can specify one or many) in an array after parsing them + if (name === '*' || name === '**') { + // apply to all property names + + if (value !== undefined) { + for (var i = 0; i < self.properties.length; i++) { + var prop = self.properties[i]; + var _name = prop.name; + var parsedProp = this.parse(_name, value, true); + if (parsedProp) { + props.push(parsedProp); + } + } + } + } else if (string(name)) { + // then parse the single property + var _parsedProp = this.parse(name, value, true); + if (_parsedProp) { + props.push(_parsedProp); + } + } else if (plainObject(name)) { + // then parse each property + var specifiedProps = name; + updateTransitions = value; + var names = Object.keys(specifiedProps); + for (var _i = 0; _i < names.length; _i++) { + var _name2 = names[_i]; + var _value = specifiedProps[_name2]; + if (_value === undefined) { + // try camel case name too + _value = specifiedProps[dash2camel(_name2)]; + } + if (_value !== undefined) { + var _parsedProp2 = this.parse(_name2, _value, true); + if (_parsedProp2) { + props.push(_parsedProp2); + } + } + } + } else { + // can't do anything without well defined properties + return false; + } + + // we've failed if there are no valid properties + if (props.length === 0) { + return false; + } + + // now, apply the bypass properties on the elements + var ret = false; // return true if at least one succesful bypass applied + for (var _i2 = 0; _i2 < eles.length; _i2++) { + // for each ele + var ele = eles[_i2]; + var diffProps = {}; + var diffProp = void 0; + for (var j = 0; j < props.length; j++) { + // for each prop + var _prop = props[j]; + if (updateTransitions) { + var prevProp = ele.pstyle(_prop.name); + diffProp = diffProps[_prop.name] = { + prev: prevProp + }; + } + ret = this.applyParsedProperty(ele, copy(_prop)) || ret; + if (updateTransitions) { + diffProp.next = ele.pstyle(_prop.name); + } + } // for props + + if (ret) { + this.updateStyleHints(ele); + } + if (updateTransitions) { + this.updateTransitions(ele, diffProps, isBypass); + } + } // for eles + + return ret; +}; + +// only useful in specific cases like animation +styfn$7.overrideBypass = function (eles, name, value) { + name = camel2dash(name); + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var prop = ele._private.style[name]; + var type = this.properties[name].type; + var isColor = type.color; + var isMulti = type.mutiple; + var oldValue = !prop ? null : prop.pfValue != null ? prop.pfValue : prop.value; + if (!prop || !prop.bypass) { + // need a bypass if one doesn't exist + this.applyBypass(ele, name, value); + } else { + prop.value = value; + if (prop.pfValue != null) { + prop.pfValue = value; + } + if (isColor) { + prop.strValue = 'rgb(' + value.join(',') + ')'; + } else if (isMulti) { + prop.strValue = value.join(' '); + } else { + prop.strValue = '' + value; + } + this.updateStyleHints(ele); + } + this.checkTriggers(ele, name, oldValue, value); + } +}; +styfn$7.removeAllBypasses = function (eles, updateTransitions) { + return this.removeBypasses(eles, this.propertyNames, updateTransitions); +}; +styfn$7.removeBypasses = function (eles, props, updateTransitions) { + var isBypass = true; + for (var j = 0; j < eles.length; j++) { + var ele = eles[j]; + var diffProps = {}; + for (var i = 0; i < props.length; i++) { + var name = props[i]; + var prop = this.properties[name]; + var prevProp = ele.pstyle(prop.name); + if (!prevProp || !prevProp.bypass) { + // if a bypass doesn't exist for the prop, nothing needs to be removed + continue; + } + var value = ''; // empty => remove bypass + var parsedProp = this.parse(name, value, true); + var diffProp = diffProps[prop.name] = { + prev: prevProp + }; + this.applyParsedProperty(ele, parsedProp); + diffProp.next = ele.pstyle(prop.name); + } // for props + + this.updateStyleHints(ele); + if (updateTransitions) { + this.updateTransitions(ele, diffProps, isBypass); + } + } // for eles +}; + +var styfn$6 = {}; + +// gets what an em size corresponds to in pixels relative to a dom element +styfn$6.getEmSizeInPixels = function () { + var px = this.containerCss('font-size'); + if (px != null) { + return parseFloat(px); + } else { + return 1; // for headless + } +}; + +// gets css property from the core container +styfn$6.containerCss = function (propName) { + var cy = this._private.cy; + var domElement = cy.container(); + var containerWindow = cy.window(); + if (containerWindow && domElement && containerWindow.getComputedStyle) { + return containerWindow.getComputedStyle(domElement).getPropertyValue(propName); + } +}; + +var styfn$5 = {}; + +// gets the rendered style for an element +styfn$5.getRenderedStyle = function (ele, prop) { + if (prop) { + return this.getStylePropertyValue(ele, prop, true); + } else { + return this.getRawStyle(ele, true); + } +}; + +// gets the raw style for an element +styfn$5.getRawStyle = function (ele, isRenderedVal) { + var self = this; + ele = ele[0]; // insure it's an element + + if (ele) { + var rstyle = {}; + for (var i = 0; i < self.properties.length; i++) { + var prop = self.properties[i]; + var val = self.getStylePropertyValue(ele, prop.name, isRenderedVal); + if (val != null) { + rstyle[prop.name] = val; + rstyle[dash2camel(prop.name)] = val; + } + } + return rstyle; + } +}; +styfn$5.getIndexedStyle = function (ele, property, subproperty, index) { + var pstyle = ele.pstyle(property)[subproperty][index]; + return pstyle != null ? pstyle : ele.cy().style().getDefaultProperty(property)[subproperty][0]; +}; +styfn$5.getStylePropertyValue = function (ele, propName, isRenderedVal) { + var self = this; + ele = ele[0]; // insure it's an element + + if (ele) { + var prop = self.properties[propName]; + if (prop.alias) { + prop = prop.pointsTo; + } + var type = prop.type; + var styleProp = ele.pstyle(prop.name); + if (styleProp) { + var value = styleProp.value, + units = styleProp.units, + strValue = styleProp.strValue; + if (isRenderedVal && type.number && value != null && number$1(value)) { + var zoom = ele.cy().zoom(); + var getRenderedValue = function getRenderedValue(val) { + return val * zoom; + }; + var getValueStringWithUnits = function getValueStringWithUnits(val, units) { + return getRenderedValue(val) + units; + }; + var isArrayValue = array(value); + var haveUnits = isArrayValue ? units.every(function (u) { + return u != null; + }) : units != null; + if (haveUnits) { + if (isArrayValue) { + return value.map(function (v, i) { + return getValueStringWithUnits(v, units[i]); + }).join(' '); + } else { + return getValueStringWithUnits(value, units); + } + } else { + if (isArrayValue) { + return value.map(function (v) { + return string(v) ? v : '' + getRenderedValue(v); + }).join(' '); + } else { + return '' + getRenderedValue(value); + } + } + } else if (strValue != null) { + return strValue; + } + } + return null; + } +}; +styfn$5.getAnimationStartStyle = function (ele, aniProps) { + var rstyle = {}; + for (var i = 0; i < aniProps.length; i++) { + var aniProp = aniProps[i]; + var name = aniProp.name; + var styleProp = ele.pstyle(name); + if (styleProp !== undefined) { + // then make a prop of it + if (plainObject(styleProp)) { + styleProp = this.parse(name, styleProp.strValue); + } else { + styleProp = this.parse(name, styleProp); + } + } + if (styleProp) { + rstyle[name] = styleProp; + } + } + return rstyle; +}; +styfn$5.getPropsList = function (propsObj) { + var self = this; + var rstyle = []; + var style = propsObj; + var props = self.properties; + if (style) { + var names = Object.keys(style); + for (var i = 0; i < names.length; i++) { + var name = names[i]; + var val = style[name]; + var prop = props[name] || props[camel2dash(name)]; + var styleProp = this.parse(prop.name, val); + if (styleProp) { + rstyle.push(styleProp); + } + } + } + return rstyle; +}; +styfn$5.getNonDefaultPropertiesHash = function (ele, propNames, seed) { + var hash = seed.slice(); + var name, val, strVal, chVal; + var i, j; + for (i = 0; i < propNames.length; i++) { + name = propNames[i]; + val = ele.pstyle(name, false); + if (val == null) { + continue; + } else if (val.pfValue != null) { + hash[0] = hashInt(chVal, hash[0]); + hash[1] = hashIntAlt(chVal, hash[1]); + } else { + strVal = val.strValue; + for (j = 0; j < strVal.length; j++) { + chVal = strVal.charCodeAt(j); + hash[0] = hashInt(chVal, hash[0]); + hash[1] = hashIntAlt(chVal, hash[1]); + } + } + } + return hash; +}; +styfn$5.getPropertiesHash = styfn$5.getNonDefaultPropertiesHash; + +var styfn$4 = {}; +styfn$4.appendFromJson = function (json) { + var style = this; + for (var i = 0; i < json.length; i++) { + var context = json[i]; + var selector = context.selector; + var props = context.style || context.css; + var names = Object.keys(props); + style.selector(selector); // apply selector + + for (var j = 0; j < names.length; j++) { + var name = names[j]; + var value = props[name]; + style.css(name, value); // apply property + } + } + + return style; +}; + +// accessible cy.style() function +styfn$4.fromJson = function (json) { + var style = this; + style.resetToDefault(); + style.appendFromJson(json); + return style; +}; + +// get json from cy.style() api +styfn$4.json = function () { + var json = []; + for (var i = this.defaultLength; i < this.length; i++) { + var cxt = this[i]; + var selector = cxt.selector; + var props = cxt.properties; + var css = {}; + for (var j = 0; j < props.length; j++) { + var prop = props[j]; + css[prop.name] = prop.strValue; + } + json.push({ + selector: !selector ? 'core' : selector.toString(), + style: css + }); + } + return json; +}; + +var styfn$3 = {}; +styfn$3.appendFromString = function (string) { + var self = this; + var style = this; + var remaining = '' + string; + var selAndBlockStr; + var blockRem; + var propAndValStr; + + // remove comments from the style string + remaining = remaining.replace(/[/][*](\s|.)+?[*][/]/g, ''); + function removeSelAndBlockFromRemaining() { + // remove the parsed selector and block from the remaining text to parse + if (remaining.length > selAndBlockStr.length) { + remaining = remaining.substr(selAndBlockStr.length); + } else { + remaining = ''; + } + } + function removePropAndValFromRem() { + // remove the parsed property and value from the remaining block text to parse + if (blockRem.length > propAndValStr.length) { + blockRem = blockRem.substr(propAndValStr.length); + } else { + blockRem = ''; + } + } + for (;;) { + var nothingLeftToParse = remaining.match(/^\s*$/); + if (nothingLeftToParse) { + break; + } + var selAndBlock = remaining.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/); + if (!selAndBlock) { + warn('Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: ' + remaining); + break; + } + selAndBlockStr = selAndBlock[0]; + + // parse the selector + var selectorStr = selAndBlock[1]; + if (selectorStr !== 'core') { + var selector = new Selector(selectorStr); + if (selector.invalid) { + warn('Skipping parsing of block: Invalid selector found in string stylesheet: ' + selectorStr); + + // skip this selector and block + removeSelAndBlockFromRemaining(); + continue; + } + } + + // parse the block of properties and values + var blockStr = selAndBlock[2]; + var invalidBlock = false; + blockRem = blockStr; + var props = []; + for (;;) { + var _nothingLeftToParse = blockRem.match(/^\s*$/); + if (_nothingLeftToParse) { + break; + } + var propAndVal = blockRem.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/); + if (!propAndVal) { + warn('Skipping parsing of block: Invalid formatting of style property and value definitions found in:' + blockStr); + invalidBlock = true; + break; + } + propAndValStr = propAndVal[0]; + var propStr = propAndVal[1]; + var valStr = propAndVal[2]; + var prop = self.properties[propStr]; + if (!prop) { + warn('Skipping property: Invalid property name in: ' + propAndValStr); + + // skip this property in the block + removePropAndValFromRem(); + continue; + } + var parsedProp = style.parse(propStr, valStr); + if (!parsedProp) { + warn('Skipping property: Invalid property definition in: ' + propAndValStr); + + // skip this property in the block + removePropAndValFromRem(); + continue; + } + props.push({ + name: propStr, + val: valStr + }); + removePropAndValFromRem(); + } + if (invalidBlock) { + removeSelAndBlockFromRemaining(); + break; + } + + // put the parsed block in the style + style.selector(selectorStr); + for (var i = 0; i < props.length; i++) { + var _prop = props[i]; + style.css(_prop.name, _prop.val); + } + removeSelAndBlockFromRemaining(); + } + return style; +}; +styfn$3.fromString = function (string) { + var style = this; + style.resetToDefault(); + style.appendFromString(string); + return style; +}; + +var styfn$2 = {}; +(function () { + var number$1 = number; + var rgba = rgbaNoBackRefs; + var hsla = hslaNoBackRefs; + var hex3$1 = hex3; + var hex6$1 = hex6; + var data = function data(prefix) { + return '^' + prefix + '\\s*\\(\\s*([\\w\\.]+)\\s*\\)$'; + }; + var mapData = function mapData(prefix) { + var mapArg = number$1 + '|\\w+|' + rgba + '|' + hsla + '|' + hex3$1 + '|' + hex6$1; + return '^' + prefix + '\\s*\\(([\\w\\.]+)\\s*\\,\\s*(' + number$1 + ')\\s*\\,\\s*(' + number$1 + ')\\s*,\\s*(' + mapArg + ')\\s*\\,\\s*(' + mapArg + ')\\)$'; + }; + var urlRegexes = ['^url\\s*\\(\\s*[\'"]?(.+?)[\'"]?\\s*\\)$', '^(none)$', '^(.+)$']; + + // each visual style property has a type and needs to be validated according to it + styfn$2.types = { + time: { + number: true, + min: 0, + units: 's|ms', + implicitUnits: 'ms' + }, + percent: { + number: true, + min: 0, + max: 100, + units: '%', + implicitUnits: '%' + }, + percentages: { + number: true, + min: 0, + max: 100, + units: '%', + implicitUnits: '%', + multiple: true + }, + zeroOneNumber: { + number: true, + min: 0, + max: 1, + unitless: true + }, + zeroOneNumbers: { + number: true, + min: 0, + max: 1, + unitless: true, + multiple: true + }, + nOneOneNumber: { + number: true, + min: -1, + max: 1, + unitless: true + }, + nonNegativeInt: { + number: true, + min: 0, + integer: true, + unitless: true + }, + nonNegativeNumber: { + number: true, + min: 0, + unitless: true + }, + position: { + enums: ['parent', 'origin'] + }, + nodeSize: { + number: true, + min: 0, + enums: ['label'] + }, + number: { + number: true, + unitless: true + }, + numbers: { + number: true, + unitless: true, + multiple: true + }, + positiveNumber: { + number: true, + unitless: true, + min: 0, + strictMin: true + }, + size: { + number: true, + min: 0 + }, + bidirectionalSize: { + number: true + }, + // allows negative + bidirectionalSizeMaybePercent: { + number: true, + allowPercent: true + }, + // allows negative + bidirectionalSizes: { + number: true, + multiple: true + }, + // allows negative + sizeMaybePercent: { + number: true, + min: 0, + allowPercent: true + }, + axisDirection: { + enums: ['horizontal', 'leftward', 'rightward', 'vertical', 'upward', 'downward', 'auto'] + }, + paddingRelativeTo: { + enums: ['width', 'height', 'average', 'min', 'max'] + }, + bgWH: { + number: true, + min: 0, + allowPercent: true, + enums: ['auto'], + multiple: true + }, + bgPos: { + number: true, + allowPercent: true, + multiple: true + }, + bgRelativeTo: { + enums: ['inner', 'include-padding'], + multiple: true + }, + bgRepeat: { + enums: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'], + multiple: true + }, + bgFit: { + enums: ['none', 'contain', 'cover'], + multiple: true + }, + bgCrossOrigin: { + enums: ['anonymous', 'use-credentials', 'null'], + multiple: true + }, + bgClip: { + enums: ['none', 'node'], + multiple: true + }, + bgContainment: { + enums: ['inside', 'over'], + multiple: true + }, + color: { + color: true + }, + colors: { + color: true, + multiple: true + }, + fill: { + enums: ['solid', 'linear-gradient', 'radial-gradient'] + }, + bool: { + enums: ['yes', 'no'] + }, + bools: { + enums: ['yes', 'no'], + multiple: true + }, + lineStyle: { + enums: ['solid', 'dotted', 'dashed'] + }, + lineCap: { + enums: ['butt', 'round', 'square'] + }, + borderStyle: { + enums: ['solid', 'dotted', 'dashed', 'double'] + }, + curveStyle: { + enums: ['bezier', 'unbundled-bezier', 'haystack', 'segments', 'straight', 'straight-triangle', 'taxi'] + }, + fontFamily: { + regex: '^([\\w- \\"]+(?:\\s*,\\s*[\\w- \\"]+)*)$' + }, + fontStyle: { + enums: ['italic', 'normal', 'oblique'] + }, + fontWeight: { + enums: ['normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '800', '900', 100, 200, 300, 400, 500, 600, 700, 800, 900] + }, + textDecoration: { + enums: ['none', 'underline', 'overline', 'line-through'] + }, + textTransform: { + enums: ['none', 'uppercase', 'lowercase'] + }, + textWrap: { + enums: ['none', 'wrap', 'ellipsis'] + }, + textOverflowWrap: { + enums: ['whitespace', 'anywhere'] + }, + textBackgroundShape: { + enums: ['rectangle', 'roundrectangle', 'round-rectangle'] + }, + nodeShape: { + enums: ['rectangle', 'roundrectangle', 'round-rectangle', 'cutrectangle', 'cut-rectangle', 'bottomroundrectangle', 'bottom-round-rectangle', 'barrel', 'ellipse', 'triangle', 'round-triangle', 'square', 'pentagon', 'round-pentagon', 'hexagon', 'round-hexagon', 'concavehexagon', 'concave-hexagon', 'heptagon', 'round-heptagon', 'octagon', 'round-octagon', 'tag', 'round-tag', 'star', 'diamond', 'round-diamond', 'vee', 'rhomboid', 'right-rhomboid', 'polygon'] + }, + overlayShape: { + enums: ['roundrectangle', 'round-rectangle', 'ellipse'] + }, + compoundIncludeLabels: { + enums: ['include', 'exclude'] + }, + arrowShape: { + enums: ['tee', 'triangle', 'triangle-tee', 'circle-triangle', 'triangle-cross', 'triangle-backcurve', 'vee', 'square', 'circle', 'diamond', 'chevron', 'none'] + }, + arrowFill: { + enums: ['filled', 'hollow'] + }, + arrowWidth: { + number: true, + units: '%|px|em', + implicitUnits: 'px', + enums: ['match-line'] + }, + display: { + enums: ['element', 'none'] + }, + visibility: { + enums: ['hidden', 'visible'] + }, + zCompoundDepth: { + enums: ['bottom', 'orphan', 'auto', 'top'] + }, + zIndexCompare: { + enums: ['auto', 'manual'] + }, + valign: { + enums: ['top', 'center', 'bottom'] + }, + halign: { + enums: ['left', 'center', 'right'] + }, + justification: { + enums: ['left', 'center', 'right', 'auto'] + }, + text: { + string: true + }, + data: { + mapping: true, + regex: data('data') + }, + layoutData: { + mapping: true, + regex: data('layoutData') + }, + scratch: { + mapping: true, + regex: data('scratch') + }, + mapData: { + mapping: true, + regex: mapData('mapData') + }, + mapLayoutData: { + mapping: true, + regex: mapData('mapLayoutData') + }, + mapScratch: { + mapping: true, + regex: mapData('mapScratch') + }, + fn: { + mapping: true, + fn: true + }, + url: { + regexes: urlRegexes, + singleRegexMatchValue: true + }, + urls: { + regexes: urlRegexes, + singleRegexMatchValue: true, + multiple: true + }, + propList: { + propList: true + }, + angle: { + number: true, + units: 'deg|rad', + implicitUnits: 'rad' + }, + textRotation: { + number: true, + units: 'deg|rad', + implicitUnits: 'rad', + enums: ['none', 'autorotate'] + }, + polygonPointList: { + number: true, + multiple: true, + evenMultiple: true, + min: -1, + max: 1, + unitless: true + }, + edgeDistances: { + enums: ['intersection', 'node-position', 'endpoints'] + }, + edgeEndpoint: { + number: true, + multiple: true, + units: '%|px|em|deg|rad', + implicitUnits: 'px', + enums: ['inside-to-node', 'outside-to-node', 'outside-to-node-or-label', 'outside-to-line', 'outside-to-line-or-label'], + singleEnum: true, + validate: function validate(valArr, unitsArr) { + switch (valArr.length) { + case 2: + // can be % or px only + return unitsArr[0] !== 'deg' && unitsArr[0] !== 'rad' && unitsArr[1] !== 'deg' && unitsArr[1] !== 'rad'; + case 1: + // can be enum, deg, or rad only + return string(valArr[0]) || unitsArr[0] === 'deg' || unitsArr[0] === 'rad'; + default: + return false; + } + } + }, + easing: { + regexes: ['^(spring)\\s*\\(\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*\\)$', '^(cubic-bezier)\\s*\\(\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*\\)$'], + enums: ['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'ease-in-sine', 'ease-out-sine', 'ease-in-out-sine', 'ease-in-quad', 'ease-out-quad', 'ease-in-out-quad', 'ease-in-cubic', 'ease-out-cubic', 'ease-in-out-cubic', 'ease-in-quart', 'ease-out-quart', 'ease-in-out-quart', 'ease-in-quint', 'ease-out-quint', 'ease-in-out-quint', 'ease-in-expo', 'ease-out-expo', 'ease-in-out-expo', 'ease-in-circ', 'ease-out-circ', 'ease-in-out-circ'] + }, + gradientDirection: { + enums: ['to-bottom', 'to-top', 'to-left', 'to-right', 'to-bottom-right', 'to-bottom-left', 'to-top-right', 'to-top-left', 'to-right-bottom', 'to-left-bottom', 'to-right-top', 'to-left-top' // different order + ] + }, + + boundsExpansion: { + number: true, + multiple: true, + min: 0, + validate: function validate(valArr) { + var length = valArr.length; + return length === 1 || length === 2 || length === 4; + } + } + }; + var diff = { + zeroNonZero: function zeroNonZero(val1, val2) { + if ((val1 == null || val2 == null) && val1 !== val2) { + return true; // null cases could represent any value + } + if (val1 == 0 && val2 != 0) { + return true; + } else if (val1 != 0 && val2 == 0) { + return true; + } else { + return false; + } + }, + any: function any(val1, val2) { + return val1 != val2; + }, + emptyNonEmpty: function emptyNonEmpty(str1, str2) { + var empty1 = emptyString(str1); + var empty2 = emptyString(str2); + return empty1 && !empty2 || !empty1 && empty2; + } + }; + + // define visual style properties + // + // - n.b. adding a new group of props may require updates to updateStyleHints() + // - adding new props to an existing group gets handled automatically + + var t = styfn$2.types; + var mainLabel = [{ + name: 'label', + type: t.text, + triggersBounds: diff.any, + triggersZOrder: diff.emptyNonEmpty + }, { + name: 'text-rotation', + type: t.textRotation, + triggersBounds: diff.any + }, { + name: 'text-margin-x', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'text-margin-y', + type: t.bidirectionalSize, + triggersBounds: diff.any + }]; + var sourceLabel = [{ + name: 'source-label', + type: t.text, + triggersBounds: diff.any + }, { + name: 'source-text-rotation', + type: t.textRotation, + triggersBounds: diff.any + }, { + name: 'source-text-margin-x', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'source-text-margin-y', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'source-text-offset', + type: t.size, + triggersBounds: diff.any + }]; + var targetLabel = [{ + name: 'target-label', + type: t.text, + triggersBounds: diff.any + }, { + name: 'target-text-rotation', + type: t.textRotation, + triggersBounds: diff.any + }, { + name: 'target-text-margin-x', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'target-text-margin-y', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'target-text-offset', + type: t.size, + triggersBounds: diff.any + }]; + var labelDimensions = [{ + name: 'font-family', + type: t.fontFamily, + triggersBounds: diff.any + }, { + name: 'font-style', + type: t.fontStyle, + triggersBounds: diff.any + }, { + name: 'font-weight', + type: t.fontWeight, + triggersBounds: diff.any + }, { + name: 'font-size', + type: t.size, + triggersBounds: diff.any + }, { + name: 'text-transform', + type: t.textTransform, + triggersBounds: diff.any + }, { + name: 'text-wrap', + type: t.textWrap, + triggersBounds: diff.any + }, { + name: 'text-overflow-wrap', + type: t.textOverflowWrap, + triggersBounds: diff.any + }, { + name: 'text-max-width', + type: t.size, + triggersBounds: diff.any + }, { + name: 'text-outline-width', + type: t.size, + triggersBounds: diff.any + }, { + name: 'line-height', + type: t.positiveNumber, + triggersBounds: diff.any + }]; + var commonLabel = [{ + name: 'text-valign', + type: t.valign, + triggersBounds: diff.any + }, { + name: 'text-halign', + type: t.halign, + triggersBounds: diff.any + }, { + name: 'color', + type: t.color + }, { + name: 'text-outline-color', + type: t.color + }, { + name: 'text-outline-opacity', + type: t.zeroOneNumber + }, { + name: 'text-background-color', + type: t.color + }, { + name: 'text-background-opacity', + type: t.zeroOneNumber + }, { + name: 'text-background-padding', + type: t.size, + triggersBounds: diff.any + }, { + name: 'text-border-opacity', + type: t.zeroOneNumber + }, { + name: 'text-border-color', + type: t.color + }, { + name: 'text-border-width', + type: t.size, + triggersBounds: diff.any + }, { + name: 'text-border-style', + type: t.borderStyle, + triggersBounds: diff.any + }, { + name: 'text-background-shape', + type: t.textBackgroundShape, + triggersBounds: diff.any + }, { + name: 'text-justification', + type: t.justification + }]; + var behavior = [{ + name: 'events', + type: t.bool, + triggersZOrder: diff.any + }, { + name: 'text-events', + type: t.bool, + triggersZOrder: diff.any + }]; + var visibility = [{ + name: 'display', + type: t.display, + triggersZOrder: diff.any, + triggersBounds: diff.any, + triggersBoundsOfConnectedEdges: true + }, { + name: 'visibility', + type: t.visibility, + triggersZOrder: diff.any + }, { + name: 'opacity', + type: t.zeroOneNumber, + triggersZOrder: diff.zeroNonZero + }, { + name: 'text-opacity', + type: t.zeroOneNumber + }, { + name: 'min-zoomed-font-size', + type: t.size + }, { + name: 'z-compound-depth', + type: t.zCompoundDepth, + triggersZOrder: diff.any + }, { + name: 'z-index-compare', + type: t.zIndexCompare, + triggersZOrder: diff.any + }, { + name: 'z-index', + type: t.number, + triggersZOrder: diff.any + }]; + var overlay = [{ + name: 'overlay-padding', + type: t.size, + triggersBounds: diff.any + }, { + name: 'overlay-color', + type: t.color + }, { + name: 'overlay-opacity', + type: t.zeroOneNumber, + triggersBounds: diff.zeroNonZero + }, { + name: 'overlay-shape', + type: t.overlayShape, + triggersBounds: diff.any + }]; + var underlay = [{ + name: 'underlay-padding', + type: t.size, + triggersBounds: diff.any + }, { + name: 'underlay-color', + type: t.color + }, { + name: 'underlay-opacity', + type: t.zeroOneNumber, + triggersBounds: diff.zeroNonZero + }, { + name: 'underlay-shape', + type: t.overlayShape, + triggersBounds: diff.any + }]; + var transition = [{ + name: 'transition-property', + type: t.propList + }, { + name: 'transition-duration', + type: t.time + }, { + name: 'transition-delay', + type: t.time + }, { + name: 'transition-timing-function', + type: t.easing + }]; + var nodeSizeHashOverride = function nodeSizeHashOverride(ele, parsedProp) { + if (parsedProp.value === 'label') { + return -ele.poolIndex(); // no hash key hits is using label size (hitrate for perf probably low anyway) + } else { + return parsedProp.pfValue; + } + }; + var nodeBody = [{ + name: 'height', + type: t.nodeSize, + triggersBounds: diff.any, + hashOverride: nodeSizeHashOverride + }, { + name: 'width', + type: t.nodeSize, + triggersBounds: diff.any, + hashOverride: nodeSizeHashOverride + }, { + name: 'shape', + type: t.nodeShape, + triggersBounds: diff.any + }, { + name: 'shape-polygon-points', + type: t.polygonPointList, + triggersBounds: diff.any + }, { + name: 'background-color', + type: t.color + }, { + name: 'background-fill', + type: t.fill + }, { + name: 'background-opacity', + type: t.zeroOneNumber + }, { + name: 'background-blacken', + type: t.nOneOneNumber + }, { + name: 'background-gradient-stop-colors', + type: t.colors + }, { + name: 'background-gradient-stop-positions', + type: t.percentages + }, { + name: 'background-gradient-direction', + type: t.gradientDirection + }, { + name: 'padding', + type: t.sizeMaybePercent, + triggersBounds: diff.any + }, { + name: 'padding-relative-to', + type: t.paddingRelativeTo, + triggersBounds: diff.any + }, { + name: 'bounds-expansion', + type: t.boundsExpansion, + triggersBounds: diff.any + }]; + var nodeBorder = [{ + name: 'border-color', + type: t.color + }, { + name: 'border-opacity', + type: t.zeroOneNumber + }, { + name: 'border-width', + type: t.size, + triggersBounds: diff.any + }, { + name: 'border-style', + type: t.borderStyle + }]; + var nodeOutline = [{ + name: 'outline-color', + type: t.color + }, { + name: 'outline-opacity', + type: t.zeroOneNumber + }, { + name: 'outline-width', + type: t.size, + triggersBounds: diff.any + }, { + name: 'outline-style', + type: t.borderStyle + }, { + name: 'outline-offset', + type: t.size, + triggersBounds: diff.any + }]; + var backgroundImage = [{ + name: 'background-image', + type: t.urls + }, { + name: 'background-image-crossorigin', + type: t.bgCrossOrigin + }, { + name: 'background-image-opacity', + type: t.zeroOneNumbers + }, { + name: 'background-image-containment', + type: t.bgContainment + }, { + name: 'background-image-smoothing', + type: t.bools + }, { + name: 'background-position-x', + type: t.bgPos + }, { + name: 'background-position-y', + type: t.bgPos + }, { + name: 'background-width-relative-to', + type: t.bgRelativeTo + }, { + name: 'background-height-relative-to', + type: t.bgRelativeTo + }, { + name: 'background-repeat', + type: t.bgRepeat + }, { + name: 'background-fit', + type: t.bgFit + }, { + name: 'background-clip', + type: t.bgClip + }, { + name: 'background-width', + type: t.bgWH + }, { + name: 'background-height', + type: t.bgWH + }, { + name: 'background-offset-x', + type: t.bgPos + }, { + name: 'background-offset-y', + type: t.bgPos + }]; + var compound = [{ + name: 'position', + type: t.position, + triggersBounds: diff.any + }, { + name: 'compound-sizing-wrt-labels', + type: t.compoundIncludeLabels, + triggersBounds: diff.any + }, { + name: 'min-width', + type: t.size, + triggersBounds: diff.any + }, { + name: 'min-width-bias-left', + type: t.sizeMaybePercent, + triggersBounds: diff.any + }, { + name: 'min-width-bias-right', + type: t.sizeMaybePercent, + triggersBounds: diff.any + }, { + name: 'min-height', + type: t.size, + triggersBounds: diff.any + }, { + name: 'min-height-bias-top', + type: t.sizeMaybePercent, + triggersBounds: diff.any + }, { + name: 'min-height-bias-bottom', + type: t.sizeMaybePercent, + triggersBounds: diff.any + }]; + var edgeLine = [{ + name: 'line-style', + type: t.lineStyle + }, { + name: 'line-color', + type: t.color + }, { + name: 'line-fill', + type: t.fill + }, { + name: 'line-cap', + type: t.lineCap + }, { + name: 'line-opacity', + type: t.zeroOneNumber + }, { + name: 'line-dash-pattern', + type: t.numbers + }, { + name: 'line-dash-offset', + type: t.number + }, { + name: 'line-gradient-stop-colors', + type: t.colors + }, { + name: 'line-gradient-stop-positions', + type: t.percentages + }, { + name: 'curve-style', + type: t.curveStyle, + triggersBounds: diff.any, + triggersBoundsOfParallelBeziers: true + }, { + name: 'haystack-radius', + type: t.zeroOneNumber, + triggersBounds: diff.any + }, { + name: 'source-endpoint', + type: t.edgeEndpoint, + triggersBounds: diff.any + }, { + name: 'target-endpoint', + type: t.edgeEndpoint, + triggersBounds: diff.any + }, { + name: 'control-point-step-size', + type: t.size, + triggersBounds: diff.any + }, { + name: 'control-point-distances', + type: t.bidirectionalSizes, + triggersBounds: diff.any + }, { + name: 'control-point-weights', + type: t.numbers, + triggersBounds: diff.any + }, { + name: 'segment-distances', + type: t.bidirectionalSizes, + triggersBounds: diff.any + }, { + name: 'segment-weights', + type: t.numbers, + triggersBounds: diff.any + }, { + name: 'taxi-turn', + type: t.bidirectionalSizeMaybePercent, + triggersBounds: diff.any + }, { + name: 'taxi-turn-min-distance', + type: t.size, + triggersBounds: diff.any + }, { + name: 'taxi-direction', + type: t.axisDirection, + triggersBounds: diff.any + }, { + name: 'edge-distances', + type: t.edgeDistances, + triggersBounds: diff.any + }, { + name: 'arrow-scale', + type: t.positiveNumber, + triggersBounds: diff.any + }, { + name: 'loop-direction', + type: t.angle, + triggersBounds: diff.any + }, { + name: 'loop-sweep', + type: t.angle, + triggersBounds: diff.any + }, { + name: 'source-distance-from-node', + type: t.size, + triggersBounds: diff.any + }, { + name: 'target-distance-from-node', + type: t.size, + triggersBounds: diff.any + }]; + var ghost = [{ + name: 'ghost', + type: t.bool, + triggersBounds: diff.any + }, { + name: 'ghost-offset-x', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'ghost-offset-y', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'ghost-opacity', + type: t.zeroOneNumber + }]; + var core = [{ + name: 'selection-box-color', + type: t.color + }, { + name: 'selection-box-opacity', + type: t.zeroOneNumber + }, { + name: 'selection-box-border-color', + type: t.color + }, { + name: 'selection-box-border-width', + type: t.size + }, { + name: 'active-bg-color', + type: t.color + }, { + name: 'active-bg-opacity', + type: t.zeroOneNumber + }, { + name: 'active-bg-size', + type: t.size + }, { + name: 'outside-texture-bg-color', + type: t.color + }, { + name: 'outside-texture-bg-opacity', + type: t.zeroOneNumber + }]; + + // pie backgrounds for nodes + var pie = []; + styfn$2.pieBackgroundN = 16; // because the pie properties are numbered, give access to a constant N (for renderer use) + pie.push({ + name: 'pie-size', + type: t.sizeMaybePercent + }); + for (var i = 1; i <= styfn$2.pieBackgroundN; i++) { + pie.push({ + name: 'pie-' + i + '-background-color', + type: t.color + }); + pie.push({ + name: 'pie-' + i + '-background-size', + type: t.percent + }); + pie.push({ + name: 'pie-' + i + '-background-opacity', + type: t.zeroOneNumber + }); + } + + // edge arrows + var edgeArrow = []; + var arrowPrefixes = styfn$2.arrowPrefixes = ['source', 'mid-source', 'target', 'mid-target']; + [{ + name: 'arrow-shape', + type: t.arrowShape, + triggersBounds: diff.any + }, { + name: 'arrow-color', + type: t.color + }, { + name: 'arrow-fill', + type: t.arrowFill + }, { + name: 'arrow-width', + type: t.arrowWidth + }].forEach(function (prop) { + arrowPrefixes.forEach(function (prefix) { + var name = prefix + '-' + prop.name; + var type = prop.type, + triggersBounds = prop.triggersBounds; + edgeArrow.push({ + name: name, + type: type, + triggersBounds: triggersBounds + }); + }); + }, {}); + var props = styfn$2.properties = [].concat(behavior, transition, visibility, overlay, underlay, ghost, commonLabel, labelDimensions, mainLabel, sourceLabel, targetLabel, nodeBody, nodeBorder, nodeOutline, backgroundImage, pie, compound, edgeLine, edgeArrow, core); + var propGroups = styfn$2.propertyGroups = { + // common to all eles + behavior: behavior, + transition: transition, + visibility: visibility, + overlay: overlay, + underlay: underlay, + ghost: ghost, + // labels + commonLabel: commonLabel, + labelDimensions: labelDimensions, + mainLabel: mainLabel, + sourceLabel: sourceLabel, + targetLabel: targetLabel, + // node props + nodeBody: nodeBody, + nodeBorder: nodeBorder, + nodeOutline: nodeOutline, + backgroundImage: backgroundImage, + pie: pie, + compound: compound, + // edge props + edgeLine: edgeLine, + edgeArrow: edgeArrow, + core: core + }; + var propGroupNames = styfn$2.propertyGroupNames = {}; + var propGroupKeys = styfn$2.propertyGroupKeys = Object.keys(propGroups); + propGroupKeys.forEach(function (key) { + propGroupNames[key] = propGroups[key].map(function (prop) { + return prop.name; + }); + propGroups[key].forEach(function (prop) { + return prop.groupKey = key; + }); + }); + + // define aliases + var aliases = styfn$2.aliases = [{ + name: 'content', + pointsTo: 'label' + }, { + name: 'control-point-distance', + pointsTo: 'control-point-distances' + }, { + name: 'control-point-weight', + pointsTo: 'control-point-weights' + }, { + name: 'edge-text-rotation', + pointsTo: 'text-rotation' + }, { + name: 'padding-left', + pointsTo: 'padding' + }, { + name: 'padding-right', + pointsTo: 'padding' + }, { + name: 'padding-top', + pointsTo: 'padding' + }, { + name: 'padding-bottom', + pointsTo: 'padding' + }]; + + // list of property names + styfn$2.propertyNames = props.map(function (p) { + return p.name; + }); + + // allow access of properties by name ( e.g. style.properties.height ) + for (var _i = 0; _i < props.length; _i++) { + var prop = props[_i]; + props[prop.name] = prop; // allow lookup by name + } + + // map aliases + for (var _i2 = 0; _i2 < aliases.length; _i2++) { + var alias = aliases[_i2]; + var pointsToProp = props[alias.pointsTo]; + var aliasProp = { + name: alias.name, + alias: true, + pointsTo: pointsToProp + }; + + // add alias prop for parsing + props.push(aliasProp); + props[alias.name] = aliasProp; // allow lookup by name + } +})(); + +styfn$2.getDefaultProperty = function (name) { + return this.getDefaultProperties()[name]; +}; +styfn$2.getDefaultProperties = function () { + var _p = this._private; + if (_p.defaultProperties != null) { + return _p.defaultProperties; + } + var rawProps = extend({ + // core props + 'selection-box-color': '#ddd', + 'selection-box-opacity': 0.65, + 'selection-box-border-color': '#aaa', + 'selection-box-border-width': 1, + 'active-bg-color': 'black', + 'active-bg-opacity': 0.15, + 'active-bg-size': 30, + 'outside-texture-bg-color': '#000', + 'outside-texture-bg-opacity': 0.125, + // common node/edge props + 'events': 'yes', + 'text-events': 'no', + 'text-valign': 'top', + 'text-halign': 'center', + 'text-justification': 'auto', + 'line-height': 1, + 'color': '#000', + 'text-outline-color': '#000', + 'text-outline-width': 0, + 'text-outline-opacity': 1, + 'text-opacity': 1, + 'text-decoration': 'none', + 'text-transform': 'none', + 'text-wrap': 'none', + 'text-overflow-wrap': 'whitespace', + 'text-max-width': 9999, + 'text-background-color': '#000', + 'text-background-opacity': 0, + 'text-background-shape': 'rectangle', + 'text-background-padding': 0, + 'text-border-opacity': 0, + 'text-border-width': 0, + 'text-border-style': 'solid', + 'text-border-color': '#000', + 'font-family': 'Helvetica Neue, Helvetica, sans-serif', + 'font-style': 'normal', + 'font-weight': 'normal', + 'font-size': 16, + 'min-zoomed-font-size': 0, + 'text-rotation': 'none', + 'source-text-rotation': 'none', + 'target-text-rotation': 'none', + 'visibility': 'visible', + 'display': 'element', + 'opacity': 1, + 'z-compound-depth': 'auto', + 'z-index-compare': 'auto', + 'z-index': 0, + 'label': '', + 'text-margin-x': 0, + 'text-margin-y': 0, + 'source-label': '', + 'source-text-offset': 0, + 'source-text-margin-x': 0, + 'source-text-margin-y': 0, + 'target-label': '', + 'target-text-offset': 0, + 'target-text-margin-x': 0, + 'target-text-margin-y': 0, + 'overlay-opacity': 0, + 'overlay-color': '#000', + 'overlay-padding': 10, + 'overlay-shape': 'round-rectangle', + 'underlay-opacity': 0, + 'underlay-color': '#000', + 'underlay-padding': 10, + 'underlay-shape': 'round-rectangle', + 'transition-property': 'none', + 'transition-duration': 0, + 'transition-delay': 0, + 'transition-timing-function': 'linear', + // node props + 'background-blacken': 0, + 'background-color': '#999', + 'background-fill': 'solid', + 'background-opacity': 1, + 'background-image': 'none', + 'background-image-crossorigin': 'anonymous', + 'background-image-opacity': 1, + 'background-image-containment': 'inside', + 'background-image-smoothing': 'yes', + 'background-position-x': '50%', + 'background-position-y': '50%', + 'background-offset-x': 0, + 'background-offset-y': 0, + 'background-width-relative-to': 'include-padding', + 'background-height-relative-to': 'include-padding', + 'background-repeat': 'no-repeat', + 'background-fit': 'none', + 'background-clip': 'node', + 'background-width': 'auto', + 'background-height': 'auto', + 'border-color': '#000', + 'border-opacity': 1, + 'border-width': 0, + 'border-style': 'solid', + 'outline-color': '#999', + 'outline-opacity': 1, + 'outline-width': 0, + 'outline-offset': 0, + 'outline-style': 'solid', + 'height': 30, + 'width': 30, + 'shape': 'ellipse', + 'shape-polygon-points': '-1, -1, 1, -1, 1, 1, -1, 1', + 'bounds-expansion': 0, + // node gradient + 'background-gradient-direction': 'to-bottom', + 'background-gradient-stop-colors': '#999', + 'background-gradient-stop-positions': '0%', + // ghost props + 'ghost': 'no', + 'ghost-offset-y': 0, + 'ghost-offset-x': 0, + 'ghost-opacity': 0, + // compound props + 'padding': 0, + 'padding-relative-to': 'width', + 'position': 'origin', + 'compound-sizing-wrt-labels': 'include', + 'min-width': 0, + 'min-width-bias-left': 0, + 'min-width-bias-right': 0, + 'min-height': 0, + 'min-height-bias-top': 0, + 'min-height-bias-bottom': 0 + }, { + // node pie bg + 'pie-size': '100%' + }, [{ + name: 'pie-{{i}}-background-color', + value: 'black' + }, { + name: 'pie-{{i}}-background-size', + value: '0%' + }, { + name: 'pie-{{i}}-background-opacity', + value: 1 + }].reduce(function (css, prop) { + for (var i = 1; i <= styfn$2.pieBackgroundN; i++) { + var name = prop.name.replace('{{i}}', i); + var val = prop.value; + css[name] = val; + } + return css; + }, {}), { + // edge props + 'line-style': 'solid', + 'line-color': '#999', + 'line-fill': 'solid', + 'line-cap': 'butt', + 'line-opacity': 1, + 'line-gradient-stop-colors': '#999', + 'line-gradient-stop-positions': '0%', + 'control-point-step-size': 40, + 'control-point-weights': 0.5, + 'segment-weights': 0.5, + 'segment-distances': 20, + 'taxi-turn': '50%', + 'taxi-turn-min-distance': 10, + 'taxi-direction': 'auto', + 'edge-distances': 'intersection', + 'curve-style': 'haystack', + 'haystack-radius': 0, + 'arrow-scale': 1, + 'loop-direction': '-45deg', + 'loop-sweep': '-90deg', + 'source-distance-from-node': 0, + 'target-distance-from-node': 0, + 'source-endpoint': 'outside-to-node', + 'target-endpoint': 'outside-to-node', + 'line-dash-pattern': [6, 3], + 'line-dash-offset': 0 + }, [{ + name: 'arrow-shape', + value: 'none' + }, { + name: 'arrow-color', + value: '#999' + }, { + name: 'arrow-fill', + value: 'filled' + }, { + name: 'arrow-width', + value: 1 + }].reduce(function (css, prop) { + styfn$2.arrowPrefixes.forEach(function (prefix) { + var name = prefix + '-' + prop.name; + var val = prop.value; + css[name] = val; + }); + return css; + }, {})); + var parsedProps = {}; + for (var i = 0; i < this.properties.length; i++) { + var prop = this.properties[i]; + if (prop.pointsTo) { + continue; + } + var name = prop.name; + var val = rawProps[name]; + var parsedProp = this.parse(name, val); + parsedProps[name] = parsedProp; + } + _p.defaultProperties = parsedProps; + return _p.defaultProperties; +}; +styfn$2.addDefaultStylesheet = function () { + this.selector(':parent').css({ + 'shape': 'rectangle', + 'padding': 10, + 'background-color': '#eee', + 'border-color': '#ccc', + 'border-width': 1 + }).selector('edge').css({ + 'width': 3 + }).selector(':loop').css({ + 'curve-style': 'bezier' + }).selector('edge:compound').css({ + 'curve-style': 'bezier', + 'source-endpoint': 'outside-to-line', + 'target-endpoint': 'outside-to-line' + }).selector(':selected').css({ + 'background-color': '#0169D9', + 'line-color': '#0169D9', + 'source-arrow-color': '#0169D9', + 'target-arrow-color': '#0169D9', + 'mid-source-arrow-color': '#0169D9', + 'mid-target-arrow-color': '#0169D9' + }).selector(':parent:selected').css({ + 'background-color': '#CCE1F9', + 'border-color': '#aec8e5' + }).selector(':active').css({ + 'overlay-color': 'black', + 'overlay-padding': 10, + 'overlay-opacity': 0.25 + }); + this.defaultLength = this.length; +}; + +var styfn$1 = {}; + +// a caching layer for property parsing +styfn$1.parse = function (name, value, propIsBypass, propIsFlat) { + var self = this; + + // function values can't be cached in all cases, and there isn't much benefit of caching them anyway + if (fn$6(value)) { + return self.parseImplWarn(name, value, propIsBypass, propIsFlat); + } + var flatKey = propIsFlat === 'mapping' || propIsFlat === true || propIsFlat === false || propIsFlat == null ? 'dontcare' : propIsFlat; + var bypassKey = propIsBypass ? 't' : 'f'; + var valueKey = '' + value; + var argHash = hashStrings(name, valueKey, bypassKey, flatKey); + var propCache = self.propCache = self.propCache || []; + var ret; + if (!(ret = propCache[argHash])) { + ret = propCache[argHash] = self.parseImplWarn(name, value, propIsBypass, propIsFlat); + } + + // - bypasses can't be shared b/c the value can be changed by animations or otherwise overridden + // - mappings can't be shared b/c mappings are per-element + if (propIsBypass || propIsFlat === 'mapping') { + // need a copy since props are mutated later in their lifecycles + ret = copy(ret); + if (ret) { + ret.value = copy(ret.value); // because it could be an array, e.g. colour + } + } + + return ret; +}; +styfn$1.parseImplWarn = function (name, value, propIsBypass, propIsFlat) { + var prop = this.parseImpl(name, value, propIsBypass, propIsFlat); + if (!prop && value != null) { + warn("The style property `".concat(name, ": ").concat(value, "` is invalid")); + } + if (prop && (prop.name === 'width' || prop.name === 'height') && value === 'label') { + warn('The style value of `label` is deprecated for `' + prop.name + '`'); + } + return prop; +}; + +// parse a property; return null on invalid; return parsed property otherwise +// fields : +// - name : the name of the property +// - value : the parsed, native-typed value of the property +// - strValue : a string value that represents the property value in valid css +// - bypass : true iff the property is a bypass property +styfn$1.parseImpl = function (name, value, propIsBypass, propIsFlat) { + var self = this; + name = camel2dash(name); // make sure the property name is in dash form (e.g. 'property-name' not 'propertyName') + + var property = self.properties[name]; + var passedValue = value; + var types = self.types; + if (!property) { + return null; + } // return null on property of unknown name + if (value === undefined) { + return null; + } // can't assign undefined + + // the property may be an alias + if (property.alias) { + property = property.pointsTo; + name = property.name; + } + var valueIsString = string(value); + if (valueIsString) { + // trim the value to make parsing easier + value = value.trim(); + } + var type = property.type; + if (!type) { + return null; + } // no type, no luck + + // check if bypass is null or empty string (i.e. indication to delete bypass property) + if (propIsBypass && (value === '' || value === null)) { + return { + name: name, + value: value, + bypass: true, + deleteBypass: true + }; + } + + // check if value is a function used as a mapper + if (fn$6(value)) { + return { + name: name, + value: value, + strValue: 'fn', + mapped: types.fn, + bypass: propIsBypass + }; + } + + // check if value is mapped + var data, mapData; + if (!valueIsString || propIsFlat || value.length < 7 || value[1] !== 'a') ; else if (value.length >= 7 && value[0] === 'd' && (data = new RegExp(types.data.regex).exec(value))) { + if (propIsBypass) { + return false; + } // mappers not allowed in bypass + + var mapped = types.data; + return { + name: name, + value: data, + strValue: '' + value, + mapped: mapped, + field: data[1], + bypass: propIsBypass + }; + } else if (value.length >= 10 && value[0] === 'm' && (mapData = new RegExp(types.mapData.regex).exec(value))) { + if (propIsBypass) { + return false; + } // mappers not allowed in bypass + if (type.multiple) { + return false; + } // impossible to map to num + + var _mapped = types.mapData; + + // we can map only if the type is a colour or a number + if (!(type.color || type.number)) { + return false; + } + var valueMin = this.parse(name, mapData[4]); // parse to validate + if (!valueMin || valueMin.mapped) { + return false; + } // can't be invalid or mapped + + var valueMax = this.parse(name, mapData[5]); // parse to validate + if (!valueMax || valueMax.mapped) { + return false; + } // can't be invalid or mapped + + // check if valueMin and valueMax are the same + if (valueMin.pfValue === valueMax.pfValue || valueMin.strValue === valueMax.strValue) { + warn('`' + name + ': ' + value + '` is not a valid mapper because the output range is zero; converting to `' + name + ': ' + valueMin.strValue + '`'); + return this.parse(name, valueMin.strValue); // can't make much of a mapper without a range + } else if (type.color) { + var c1 = valueMin.value; + var c2 = valueMax.value; + var same = c1[0] === c2[0] // red + && c1[1] === c2[1] // green + && c1[2] === c2[2] // blue + && ( + // optional alpha + c1[3] === c2[3] // same alpha outright + || (c1[3] == null || c1[3] === 1 // full opacity for colour 1? + ) && (c2[3] == null || c2[3] === 1) // full opacity for colour 2? + ); + + if (same) { + return false; + } // can't make a mapper without a range + } + + return { + name: name, + value: mapData, + strValue: '' + value, + mapped: _mapped, + field: mapData[1], + fieldMin: parseFloat(mapData[2]), + // min & max are numeric + fieldMax: parseFloat(mapData[3]), + valueMin: valueMin.value, + valueMax: valueMax.value, + bypass: propIsBypass + }; + } + if (type.multiple && propIsFlat !== 'multiple') { + var vals; + if (valueIsString) { + vals = value.split(/\s+/); + } else if (array(value)) { + vals = value; + } else { + vals = [value]; + } + if (type.evenMultiple && vals.length % 2 !== 0) { + return null; + } + var valArr = []; + var unitsArr = []; + var pfValArr = []; + var strVal = ''; + var hasEnum = false; + for (var i = 0; i < vals.length; i++) { + var p = self.parse(name, vals[i], propIsBypass, 'multiple'); + hasEnum = hasEnum || string(p.value); + valArr.push(p.value); + pfValArr.push(p.pfValue != null ? p.pfValue : p.value); + unitsArr.push(p.units); + strVal += (i > 0 ? ' ' : '') + p.strValue; + } + if (type.validate && !type.validate(valArr, unitsArr)) { + return null; + } + if (type.singleEnum && hasEnum) { + if (valArr.length === 1 && string(valArr[0])) { + return { + name: name, + value: valArr[0], + strValue: valArr[0], + bypass: propIsBypass + }; + } else { + return null; + } + } + return { + name: name, + value: valArr, + pfValue: pfValArr, + strValue: strVal, + bypass: propIsBypass, + units: unitsArr + }; + } + + // several types also allow enums + var checkEnums = function checkEnums() { + for (var _i = 0; _i < type.enums.length; _i++) { + var en = type.enums[_i]; + if (en === value) { + return { + name: name, + value: value, + strValue: '' + value, + bypass: propIsBypass + }; + } + } + return null; + }; + + // check the type and return the appropriate object + if (type.number) { + var units; + var implicitUnits = 'px'; // not set => px + + if (type.units) { + // use specified units if set + units = type.units; + } + if (type.implicitUnits) { + implicitUnits = type.implicitUnits; + } + if (!type.unitless) { + if (valueIsString) { + var unitsRegex = 'px|em' + (type.allowPercent ? '|\\%' : ''); + if (units) { + unitsRegex = units; + } // only allow explicit units if so set + var match = value.match('^(' + number + ')(' + unitsRegex + ')?' + '$'); + if (match) { + value = match[1]; + units = match[2] || implicitUnits; + } + } else if (!units || type.implicitUnits) { + units = implicitUnits; // implicitly px if unspecified + } + } + + value = parseFloat(value); + + // if not a number and enums not allowed, then the value is invalid + if (isNaN(value) && type.enums === undefined) { + return null; + } + + // check if this number type also accepts special keywords in place of numbers + // (i.e. `left`, `auto`, etc) + if (isNaN(value) && type.enums !== undefined) { + value = passedValue; + return checkEnums(); + } + + // check if value must be an integer + if (type.integer && !integer(value)) { + return null; + } + + // check value is within range + if (type.min !== undefined && (value < type.min || type.strictMin && value === type.min) || type.max !== undefined && (value > type.max || type.strictMax && value === type.max)) { + return null; + } + var ret = { + name: name, + value: value, + strValue: '' + value + (units ? units : ''), + units: units, + bypass: propIsBypass + }; + + // normalise value in pixels + if (type.unitless || units !== 'px' && units !== 'em') { + ret.pfValue = value; + } else { + ret.pfValue = units === 'px' || !units ? value : this.getEmSizeInPixels() * value; + } + + // normalise value in ms + if (units === 'ms' || units === 's') { + ret.pfValue = units === 'ms' ? value : 1000 * value; + } + + // normalise value in rad + if (units === 'deg' || units === 'rad') { + ret.pfValue = units === 'rad' ? value : deg2rad(value); + } + + // normalize value in % + if (units === '%') { + ret.pfValue = value / 100; + } + return ret; + } else if (type.propList) { + var props = []; + var propsStr = '' + value; + if (propsStr === 'none') ; else { + // go over each prop + + var propsSplit = propsStr.split(/\s*,\s*|\s+/); + for (var _i2 = 0; _i2 < propsSplit.length; _i2++) { + var propName = propsSplit[_i2].trim(); + if (self.properties[propName]) { + props.push(propName); + } else { + warn('`' + propName + '` is not a valid property name'); + } + } + if (props.length === 0) { + return null; + } + } + return { + name: name, + value: props, + strValue: props.length === 0 ? 'none' : props.join(' '), + bypass: propIsBypass + }; + } else if (type.color) { + var tuple = color2tuple(value); + if (!tuple) { + return null; + } + return { + name: name, + value: tuple, + pfValue: tuple, + strValue: 'rgb(' + tuple[0] + ',' + tuple[1] + ',' + tuple[2] + ')', + // n.b. no spaces b/c of multiple support + bypass: propIsBypass + }; + } else if (type.regex || type.regexes) { + // first check enums + if (type.enums) { + var enumProp = checkEnums(); + if (enumProp) { + return enumProp; + } + } + var regexes = type.regexes ? type.regexes : [type.regex]; + for (var _i3 = 0; _i3 < regexes.length; _i3++) { + var regex = new RegExp(regexes[_i3]); // make a regex from the type string + var m = regex.exec(value); + if (m) { + // regex matches + return { + name: name, + value: type.singleRegexMatchValue ? m[1] : m, + strValue: '' + value, + bypass: propIsBypass + }; + } + } + return null; // didn't match any + } else if (type.string) { + // just return + return { + name: name, + value: '' + value, + strValue: '' + value, + bypass: propIsBypass + }; + } else if (type.enums) { + // check enums last because it's a combo type in others + return checkEnums(); + } else { + return null; // not a type we can handle + } +}; + +var Style = function Style(cy) { + if (!(this instanceof Style)) { + return new Style(cy); + } + if (!core(cy)) { + error('A style must have a core reference'); + return; + } + this._private = { + cy: cy, + coreStyle: {} + }; + this.length = 0; + this.resetToDefault(); +}; +var styfn = Style.prototype; +styfn.instanceString = function () { + return 'style'; +}; + +// remove all contexts +styfn.clear = function () { + var _p = this._private; + var cy = _p.cy; + var eles = cy.elements(); + for (var i = 0; i < this.length; i++) { + this[i] = undefined; + } + this.length = 0; + _p.contextStyles = {}; + _p.propDiffs = {}; + this.cleanElements(eles, true); + eles.forEach(function (ele) { + var ele_p = ele[0]._private; + ele_p.styleDirty = true; + ele_p.appliedInitStyle = false; + }); + return this; // chaining +}; + +styfn.resetToDefault = function () { + this.clear(); + this.addDefaultStylesheet(); + return this; +}; + +// builds a style object for the 'core' selector +styfn.core = function (propName) { + return this._private.coreStyle[propName] || this.getDefaultProperty(propName); +}; + +// create a new context from the specified selector string and switch to that context +styfn.selector = function (selectorStr) { + // 'core' is a special case and does not need a selector + var selector = selectorStr === 'core' ? null : new Selector(selectorStr); + var i = this.length++; // new context means new index + this[i] = { + selector: selector, + properties: [], + mappedProperties: [], + index: i + }; + return this; // chaining +}; + +// add one or many css rules to the current context +styfn.css = function () { + var self = this; + var args = arguments; + if (args.length === 1) { + var map = args[0]; + for (var i = 0; i < self.properties.length; i++) { + var prop = self.properties[i]; + var mapVal = map[prop.name]; + if (mapVal === undefined) { + mapVal = map[dash2camel(prop.name)]; + } + if (mapVal !== undefined) { + this.cssRule(prop.name, mapVal); + } + } + } else if (args.length === 2) { + this.cssRule(args[0], args[1]); + } + + // do nothing if args are invalid + + return this; // chaining +}; + +styfn.style = styfn.css; + +// add a single css rule to the current context +styfn.cssRule = function (name, value) { + // name-value pair + var property = this.parse(name, value); + + // add property to current context if valid + if (property) { + var i = this.length - 1; + this[i].properties.push(property); + this[i].properties[property.name] = property; // allow access by name as well + + if (property.name.match(/pie-(\d+)-background-size/) && property.value) { + this._private.hasPie = true; + } + if (property.mapped) { + this[i].mappedProperties.push(property); + } + + // add to core style if necessary + var currentSelectorIsCore = !this[i].selector; + if (currentSelectorIsCore) { + this._private.coreStyle[property.name] = property; + } + } + return this; // chaining +}; + +styfn.append = function (style) { + if (stylesheet(style)) { + style.appendToStyle(this); + } else if (array(style)) { + this.appendFromJson(style); + } else if (string(style)) { + this.appendFromString(style); + } // you probably wouldn't want to append a Style, since you'd duplicate the default parts + + return this; +}; + +// static function +Style.fromJson = function (cy, json) { + var style = new Style(cy); + style.fromJson(json); + return style; +}; +Style.fromString = function (cy, string) { + return new Style(cy).fromString(string); +}; +[styfn$8, styfn$7, styfn$6, styfn$5, styfn$4, styfn$3, styfn$2, styfn$1].forEach(function (props) { + extend(styfn, props); +}); +Style.types = styfn.types; +Style.properties = styfn.properties; +Style.propertyGroups = styfn.propertyGroups; +Style.propertyGroupNames = styfn.propertyGroupNames; +Style.propertyGroupKeys = styfn.propertyGroupKeys; + +var corefn$2 = { + style: function style(newStyle) { + if (newStyle) { + var s = this.setStyle(newStyle); + s.update(); + } + return this._private.style; + }, + setStyle: function setStyle(style) { + var _p = this._private; + if (stylesheet(style)) { + _p.style = style.generateStyle(this); + } else if (array(style)) { + _p.style = Style.fromJson(this, style); + } else if (string(style)) { + _p.style = Style.fromString(this, style); + } else { + _p.style = Style(this); + } + return _p.style; + }, + // e.g. cy.data() changed => recalc ele mappers + updateStyle: function updateStyle() { + this.mutableElements().updateStyle(); // just send to all eles + } +}; + +var defaultSelectionType = 'single'; +var corefn$1 = { + autolock: function autolock(bool) { + if (bool !== undefined) { + this._private.autolock = bool ? true : false; + } else { + return this._private.autolock; + } + return this; // chaining + }, + + autoungrabify: function autoungrabify(bool) { + if (bool !== undefined) { + this._private.autoungrabify = bool ? true : false; + } else { + return this._private.autoungrabify; + } + return this; // chaining + }, + + autounselectify: function autounselectify(bool) { + if (bool !== undefined) { + this._private.autounselectify = bool ? true : false; + } else { + return this._private.autounselectify; + } + return this; // chaining + }, + + selectionType: function selectionType(selType) { + var _p = this._private; + if (_p.selectionType == null) { + _p.selectionType = defaultSelectionType; + } + if (selType !== undefined) { + if (selType === 'additive' || selType === 'single') { + _p.selectionType = selType; + } + } else { + return _p.selectionType; + } + return this; + }, + panningEnabled: function panningEnabled(bool) { + if (bool !== undefined) { + this._private.panningEnabled = bool ? true : false; + } else { + return this._private.panningEnabled; + } + return this; // chaining + }, + + userPanningEnabled: function userPanningEnabled(bool) { + if (bool !== undefined) { + this._private.userPanningEnabled = bool ? true : false; + } else { + return this._private.userPanningEnabled; + } + return this; // chaining + }, + + zoomingEnabled: function zoomingEnabled(bool) { + if (bool !== undefined) { + this._private.zoomingEnabled = bool ? true : false; + } else { + return this._private.zoomingEnabled; + } + return this; // chaining + }, + + userZoomingEnabled: function userZoomingEnabled(bool) { + if (bool !== undefined) { + this._private.userZoomingEnabled = bool ? true : false; + } else { + return this._private.userZoomingEnabled; + } + return this; // chaining + }, + + boxSelectionEnabled: function boxSelectionEnabled(bool) { + if (bool !== undefined) { + this._private.boxSelectionEnabled = bool ? true : false; + } else { + return this._private.boxSelectionEnabled; + } + return this; // chaining + }, + + pan: function pan() { + var args = arguments; + var pan = this._private.pan; + var dim, val, dims, x, y; + switch (args.length) { + case 0: + // .pan() + return pan; + case 1: + if (string(args[0])) { + // .pan('x') + dim = args[0]; + return pan[dim]; + } else if (plainObject(args[0])) { + // .pan({ x: 0, y: 100 }) + if (!this._private.panningEnabled) { + return this; + } + dims = args[0]; + x = dims.x; + y = dims.y; + if (number$1(x)) { + pan.x = x; + } + if (number$1(y)) { + pan.y = y; + } + this.emit('pan viewport'); + } + break; + case 2: + // .pan('x', 100) + if (!this._private.panningEnabled) { + return this; + } + dim = args[0]; + val = args[1]; + if ((dim === 'x' || dim === 'y') && number$1(val)) { + pan[dim] = val; + } + this.emit('pan viewport'); + break; + // invalid + } + + this.notify('viewport'); + return this; // chaining + }, + + panBy: function panBy(arg0, arg1) { + var args = arguments; + var pan = this._private.pan; + var dim, val, dims, x, y; + if (!this._private.panningEnabled) { + return this; + } + switch (args.length) { + case 1: + if (plainObject(arg0)) { + // .panBy({ x: 0, y: 100 }) + dims = args[0]; + x = dims.x; + y = dims.y; + if (number$1(x)) { + pan.x += x; + } + if (number$1(y)) { + pan.y += y; + } + this.emit('pan viewport'); + } + break; + case 2: + // .panBy('x', 100) + dim = arg0; + val = arg1; + if ((dim === 'x' || dim === 'y') && number$1(val)) { + pan[dim] += val; + } + this.emit('pan viewport'); + break; + // invalid + } + + this.notify('viewport'); + return this; // chaining + }, + + fit: function fit(elements, padding) { + var viewportState = this.getFitViewport(elements, padding); + if (viewportState) { + var _p = this._private; + _p.zoom = viewportState.zoom; + _p.pan = viewportState.pan; + this.emit('pan zoom viewport'); + this.notify('viewport'); + } + return this; // chaining + }, + + getFitViewport: function getFitViewport(elements, padding) { + if (number$1(elements) && padding === undefined) { + // elements is optional + padding = elements; + elements = undefined; + } + if (!this._private.panningEnabled || !this._private.zoomingEnabled) { + return; + } + var bb; + if (string(elements)) { + var sel = elements; + elements = this.$(sel); + } else if (boundingBox(elements)) { + // assume bb + var bbe = elements; + bb = { + x1: bbe.x1, + y1: bbe.y1, + x2: bbe.x2, + y2: bbe.y2 + }; + bb.w = bb.x2 - bb.x1; + bb.h = bb.y2 - bb.y1; + } else if (!elementOrCollection(elements)) { + elements = this.mutableElements(); + } + if (elementOrCollection(elements) && elements.empty()) { + return; + } // can't fit to nothing + + bb = bb || elements.boundingBox(); + var w = this.width(); + var h = this.height(); + var zoom; + padding = number$1(padding) ? padding : 0; + if (!isNaN(w) && !isNaN(h) && w > 0 && h > 0 && !isNaN(bb.w) && !isNaN(bb.h) && bb.w > 0 && bb.h > 0) { + zoom = Math.min((w - 2 * padding) / bb.w, (h - 2 * padding) / bb.h); + + // crop zoom + zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom; + zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom; + var pan = { + // now pan to middle + x: (w - zoom * (bb.x1 + bb.x2)) / 2, + y: (h - zoom * (bb.y1 + bb.y2)) / 2 + }; + return { + zoom: zoom, + pan: pan + }; + } + return; + }, + zoomRange: function zoomRange(min, max) { + var _p = this._private; + if (max == null) { + var opts = min; + min = opts.min; + max = opts.max; + } + if (number$1(min) && number$1(max) && min <= max) { + _p.minZoom = min; + _p.maxZoom = max; + } else if (number$1(min) && max === undefined && min <= _p.maxZoom) { + _p.minZoom = min; + } else if (number$1(max) && min === undefined && max >= _p.minZoom) { + _p.maxZoom = max; + } + return this; + }, + minZoom: function minZoom(zoom) { + if (zoom === undefined) { + return this._private.minZoom; + } else { + return this.zoomRange({ + min: zoom + }); + } + }, + maxZoom: function maxZoom(zoom) { + if (zoom === undefined) { + return this._private.maxZoom; + } else { + return this.zoomRange({ + max: zoom + }); + } + }, + getZoomedViewport: function getZoomedViewport(params) { + var _p = this._private; + var currentPan = _p.pan; + var currentZoom = _p.zoom; + var pos; // in rendered px + var zoom; + var bail = false; + if (!_p.zoomingEnabled) { + // zooming disabled + bail = true; + } + if (number$1(params)) { + // then set the zoom + zoom = params; + } else if (plainObject(params)) { + // then zoom about a point + zoom = params.level; + if (params.position != null) { + pos = modelToRenderedPosition(params.position, currentZoom, currentPan); + } else if (params.renderedPosition != null) { + pos = params.renderedPosition; + } + if (pos != null && !_p.panningEnabled) { + // panning disabled + bail = true; + } + } + + // crop zoom + zoom = zoom > _p.maxZoom ? _p.maxZoom : zoom; + zoom = zoom < _p.minZoom ? _p.minZoom : zoom; + + // can't zoom with invalid params + if (bail || !number$1(zoom) || zoom === currentZoom || pos != null && (!number$1(pos.x) || !number$1(pos.y))) { + return null; + } + if (pos != null) { + // set zoom about position + var pan1 = currentPan; + var zoom1 = currentZoom; + var zoom2 = zoom; + var pan2 = { + x: -zoom2 / zoom1 * (pos.x - pan1.x) + pos.x, + y: -zoom2 / zoom1 * (pos.y - pan1.y) + pos.y + }; + return { + zoomed: true, + panned: true, + zoom: zoom2, + pan: pan2 + }; + } else { + // just set the zoom + return { + zoomed: true, + panned: false, + zoom: zoom, + pan: currentPan + }; + } + }, + zoom: function zoom(params) { + if (params === undefined) { + // get + return this._private.zoom; + } else { + // set + var vp = this.getZoomedViewport(params); + var _p = this._private; + if (vp == null || !vp.zoomed) { + return this; + } + _p.zoom = vp.zoom; + if (vp.panned) { + _p.pan.x = vp.pan.x; + _p.pan.y = vp.pan.y; + } + this.emit('zoom' + (vp.panned ? ' pan' : '') + ' viewport'); + this.notify('viewport'); + return this; // chaining + } + }, + + viewport: function viewport(opts) { + var _p = this._private; + var zoomDefd = true; + var panDefd = true; + var events = []; // to trigger + var zoomFailed = false; + var panFailed = false; + if (!opts) { + return this; + } + if (!number$1(opts.zoom)) { + zoomDefd = false; + } + if (!plainObject(opts.pan)) { + panDefd = false; + } + if (!zoomDefd && !panDefd) { + return this; + } + if (zoomDefd) { + var z = opts.zoom; + if (z < _p.minZoom || z > _p.maxZoom || !_p.zoomingEnabled) { + zoomFailed = true; + } else { + _p.zoom = z; + events.push('zoom'); + } + } + if (panDefd && (!zoomFailed || !opts.cancelOnFailedZoom) && _p.panningEnabled) { + var p = opts.pan; + if (number$1(p.x)) { + _p.pan.x = p.x; + panFailed = false; + } + if (number$1(p.y)) { + _p.pan.y = p.y; + panFailed = false; + } + if (!panFailed) { + events.push('pan'); + } + } + if (events.length > 0) { + events.push('viewport'); + this.emit(events.join(' ')); + this.notify('viewport'); + } + return this; // chaining + }, + + center: function center(elements) { + var pan = this.getCenterPan(elements); + if (pan) { + this._private.pan = pan; + this.emit('pan viewport'); + this.notify('viewport'); + } + return this; // chaining + }, + + getCenterPan: function getCenterPan(elements, zoom) { + if (!this._private.panningEnabled) { + return; + } + if (string(elements)) { + var selector = elements; + elements = this.mutableElements().filter(selector); + } else if (!elementOrCollection(elements)) { + elements = this.mutableElements(); + } + if (elements.length === 0) { + return; + } // can't centre pan to nothing + + var bb = elements.boundingBox(); + var w = this.width(); + var h = this.height(); + zoom = zoom === undefined ? this._private.zoom : zoom; + var pan = { + // middle + x: (w - zoom * (bb.x1 + bb.x2)) / 2, + y: (h - zoom * (bb.y1 + bb.y2)) / 2 + }; + return pan; + }, + reset: function reset() { + if (!this._private.panningEnabled || !this._private.zoomingEnabled) { + return this; + } + this.viewport({ + pan: { + x: 0, + y: 0 + }, + zoom: 1 + }); + return this; // chaining + }, + + invalidateSize: function invalidateSize() { + this._private.sizeCache = null; + }, + size: function size() { + var _p = this._private; + var container = _p.container; + var cy = this; + return _p.sizeCache = _p.sizeCache || (container ? function () { + var style = cy.window().getComputedStyle(container); + var val = function val(name) { + return parseFloat(style.getPropertyValue(name)); + }; + return { + width: container.clientWidth - val('padding-left') - val('padding-right'), + height: container.clientHeight - val('padding-top') - val('padding-bottom') + }; + }() : { + // fallback if no container (not 0 b/c can be used for dividing etc) + width: 1, + height: 1 + }); + }, + width: function width() { + return this.size().width; + }, + height: function height() { + return this.size().height; + }, + extent: function extent() { + var pan = this._private.pan; + var zoom = this._private.zoom; + var rb = this.renderedExtent(); + var b = { + x1: (rb.x1 - pan.x) / zoom, + x2: (rb.x2 - pan.x) / zoom, + y1: (rb.y1 - pan.y) / zoom, + y2: (rb.y2 - pan.y) / zoom + }; + b.w = b.x2 - b.x1; + b.h = b.y2 - b.y1; + return b; + }, + renderedExtent: function renderedExtent() { + var width = this.width(); + var height = this.height(); + return { + x1: 0, + y1: 0, + x2: width, + y2: height, + w: width, + h: height + }; + }, + multiClickDebounceTime: function multiClickDebounceTime(_int) { + if (_int) this._private.multiClickDebounceTime = _int;else return this._private.multiClickDebounceTime; + return this; // chaining + } +}; + +// aliases +corefn$1.centre = corefn$1.center; + +// backwards compatibility +corefn$1.autolockNodes = corefn$1.autolock; +corefn$1.autoungrabifyNodes = corefn$1.autoungrabify; + +var fn = { + data: define.data({ + field: 'data', + bindingEvent: 'data', + allowBinding: true, + allowSetting: true, + settingEvent: 'data', + settingTriggersEvent: true, + triggerFnName: 'trigger', + allowGetting: true, + updateStyle: true + }), + removeData: define.removeData({ + field: 'data', + event: 'data', + triggerFnName: 'trigger', + triggerEvent: true, + updateStyle: true + }), + scratch: define.data({ + field: 'scratch', + bindingEvent: 'scratch', + allowBinding: true, + allowSetting: true, + settingEvent: 'scratch', + settingTriggersEvent: true, + triggerFnName: 'trigger', + allowGetting: true, + updateStyle: true + }), + removeScratch: define.removeData({ + field: 'scratch', + event: 'scratch', + triggerFnName: 'trigger', + triggerEvent: true, + updateStyle: true + }) +}; + +// aliases +fn.attr = fn.data; +fn.removeAttr = fn.removeData; + +var Core = function Core(opts) { + var cy = this; + opts = extend({}, opts); + var container = opts.container; + + // allow for passing a wrapped jquery object + // e.g. cytoscape({ container: $('#cy') }) + if (container && !htmlElement(container) && htmlElement(container[0])) { + container = container[0]; + } + var reg = container ? container._cyreg : null; // e.g. already registered some info (e.g. readies) via jquery + reg = reg || {}; + if (reg && reg.cy) { + reg.cy.destroy(); + reg = {}; // old instance => replace reg completely + } + + var readies = reg.readies = reg.readies || []; + if (container) { + container._cyreg = reg; + } // make sure container assoc'd reg points to this cy + reg.cy = cy; + var head = _window !== undefined && container !== undefined && !opts.headless; + var options = opts; + options.layout = extend({ + name: head ? 'grid' : 'null' + }, options.layout); + options.renderer = extend({ + name: head ? 'canvas' : 'null' + }, options.renderer); + var defVal = function defVal(def, val, altVal) { + if (val !== undefined) { + return val; + } else if (altVal !== undefined) { + return altVal; + } else { + return def; + } + }; + var _p = this._private = { + container: container, + // html dom ele container + ready: false, + // whether ready has been triggered + options: options, + // cached options + elements: new Collection(this), + // elements in the graph + listeners: [], + // list of listeners + aniEles: new Collection(this), + // elements being animated + data: options.data || {}, + // data for the core + scratch: {}, + // scratch object for core + layout: null, + renderer: null, + destroyed: false, + // whether destroy was called + notificationsEnabled: true, + // whether notifications are sent to the renderer + minZoom: 1e-50, + maxZoom: 1e50, + zoomingEnabled: defVal(true, options.zoomingEnabled), + userZoomingEnabled: defVal(true, options.userZoomingEnabled), + panningEnabled: defVal(true, options.panningEnabled), + userPanningEnabled: defVal(true, options.userPanningEnabled), + boxSelectionEnabled: defVal(true, options.boxSelectionEnabled), + autolock: defVal(false, options.autolock, options.autolockNodes), + autoungrabify: defVal(false, options.autoungrabify, options.autoungrabifyNodes), + autounselectify: defVal(false, options.autounselectify), + styleEnabled: options.styleEnabled === undefined ? head : options.styleEnabled, + zoom: number$1(options.zoom) ? options.zoom : 1, + pan: { + x: plainObject(options.pan) && number$1(options.pan.x) ? options.pan.x : 0, + y: plainObject(options.pan) && number$1(options.pan.y) ? options.pan.y : 0 + }, + animation: { + // object for currently-running animations + current: [], + queue: [] + }, + hasCompoundNodes: false, + multiClickDebounceTime: defVal(250, options.multiClickDebounceTime) + }; + this.createEmitter(); + + // set selection type + this.selectionType(options.selectionType); + + // init zoom bounds + this.zoomRange({ + min: options.minZoom, + max: options.maxZoom + }); + var loadExtData = function loadExtData(extData, next) { + var anyIsPromise = extData.some(promise); + if (anyIsPromise) { + return Promise$1.all(extData).then(next); // load all data asynchronously, then exec rest of init + } else { + next(extData); // exec synchronously for convenience + } + }; + + // start with the default stylesheet so we have something before loading an external stylesheet + if (_p.styleEnabled) { + cy.setStyle([]); + } + + // create the renderer + var rendererOptions = extend({}, options, options.renderer); // allow rendering hints in top level options + cy.initRenderer(rendererOptions); + var setElesAndLayout = function setElesAndLayout(elements, onload, ondone) { + cy.notifications(false); + + // remove old elements + var oldEles = cy.mutableElements(); + if (oldEles.length > 0) { + oldEles.remove(); + } + if (elements != null) { + if (plainObject(elements) || array(elements)) { + cy.add(elements); + } + } + cy.one('layoutready', function (e) { + cy.notifications(true); + cy.emit(e); // we missed this event by turning notifications off, so pass it on + + cy.one('load', onload); + cy.emitAndNotify('load'); + }).one('layoutstop', function () { + cy.one('done', ondone); + cy.emit('done'); + }); + var layoutOpts = extend({}, cy._private.options.layout); + layoutOpts.eles = cy.elements(); + cy.layout(layoutOpts).run(); + }; + loadExtData([options.style, options.elements], function (thens) { + var initStyle = thens[0]; + var initEles = thens[1]; + + // init style + if (_p.styleEnabled) { + cy.style().append(initStyle); + } + + // initial load + setElesAndLayout(initEles, function () { + // onready + cy.startAnimationLoop(); + _p.ready = true; + + // if a ready callback is specified as an option, the bind it + if (fn$6(options.ready)) { + cy.on('ready', options.ready); + } + + // bind all the ready handlers registered before creating this instance + for (var i = 0; i < readies.length; i++) { + var fn = readies[i]; + cy.on('ready', fn); + } + if (reg) { + reg.readies = []; + } // clear b/c we've bound them all and don't want to keep it around in case a new core uses the same div etc + + cy.emit('ready'); + }, options.done); + }); +}; +var corefn = Core.prototype; // short alias + +extend(corefn, { + instanceString: function instanceString() { + return 'core'; + }, + isReady: function isReady() { + return this._private.ready; + }, + destroyed: function destroyed() { + return this._private.destroyed; + }, + ready: function ready(fn) { + if (this.isReady()) { + this.emitter().emit('ready', [], fn); // just calls fn as though triggered via ready event + } else { + this.on('ready', fn); + } + return this; + }, + destroy: function destroy() { + var cy = this; + if (cy.destroyed()) return; + cy.stopAnimationLoop(); + cy.destroyRenderer(); + this.emit('destroy'); + cy._private.destroyed = true; + return cy; + }, + hasElementWithId: function hasElementWithId(id) { + return this._private.elements.hasElementWithId(id); + }, + getElementById: function getElementById(id) { + return this._private.elements.getElementById(id); + }, + hasCompoundNodes: function hasCompoundNodes() { + return this._private.hasCompoundNodes; + }, + headless: function headless() { + return this._private.renderer.isHeadless(); + }, + styleEnabled: function styleEnabled() { + return this._private.styleEnabled; + }, + addToPool: function addToPool(eles) { + this._private.elements.merge(eles); + return this; // chaining + }, + + removeFromPool: function removeFromPool(eles) { + this._private.elements.unmerge(eles); + return this; + }, + container: function container() { + return this._private.container || null; + }, + window: function window() { + var container = this._private.container; + if (container == null) return _window; + var ownerDocument = this._private.container.ownerDocument; + if (ownerDocument === undefined || ownerDocument == null) { + return _window; + } + return ownerDocument.defaultView || _window; + }, + mount: function mount(container) { + if (container == null) { + return; + } + var cy = this; + var _p = cy._private; + var options = _p.options; + if (!htmlElement(container) && htmlElement(container[0])) { + container = container[0]; + } + cy.stopAnimationLoop(); + cy.destroyRenderer(); + _p.container = container; + _p.styleEnabled = true; + cy.invalidateSize(); + cy.initRenderer(extend({}, options, options.renderer, { + // allow custom renderer name to be re-used, otherwise use canvas + name: options.renderer.name === 'null' ? 'canvas' : options.renderer.name + })); + cy.startAnimationLoop(); + cy.style(options.style); + cy.emit('mount'); + return cy; + }, + unmount: function unmount() { + var cy = this; + cy.stopAnimationLoop(); + cy.destroyRenderer(); + cy.initRenderer({ + name: 'null' + }); + cy.emit('unmount'); + return cy; + }, + options: function options() { + return copy(this._private.options); + }, + json: function json(obj) { + var cy = this; + var _p = cy._private; + var eles = cy.mutableElements(); + var getFreshRef = function getFreshRef(ele) { + return cy.getElementById(ele.id()); + }; + if (plainObject(obj)) { + // set + + cy.startBatch(); + if (obj.elements) { + var idInJson = {}; + var updateEles = function updateEles(jsons, gr) { + var toAdd = []; + var toMod = []; + for (var i = 0; i < jsons.length; i++) { + var json = jsons[i]; + if (!json.data.id) { + warn('cy.json() cannot handle elements without an ID attribute'); + continue; + } + var id = '' + json.data.id; // id must be string + var ele = cy.getElementById(id); + idInJson[id] = true; + if (ele.length !== 0) { + // existing element should be updated + toMod.push({ + ele: ele, + json: json + }); + } else { + // otherwise should be added + if (gr) { + json.group = gr; + toAdd.push(json); + } else { + toAdd.push(json); + } + } + } + cy.add(toAdd); + for (var _i = 0; _i < toMod.length; _i++) { + var _toMod$_i = toMod[_i], + _ele = _toMod$_i.ele, + _json = _toMod$_i.json; + _ele.json(_json); + } + }; + if (array(obj.elements)) { + // elements: [] + updateEles(obj.elements); + } else { + // elements: { nodes: [], edges: [] } + var grs = ['nodes', 'edges']; + for (var i = 0; i < grs.length; i++) { + var gr = grs[i]; + var elements = obj.elements[gr]; + if (array(elements)) { + updateEles(elements, gr); + } + } + } + var parentsToRemove = cy.collection(); + eles.filter(function (ele) { + return !idInJson[ele.id()]; + }).forEach(function (ele) { + if (ele.isParent()) { + parentsToRemove.merge(ele); + } else { + ele.remove(); + } + }); + + // so that children are not removed w/parent + parentsToRemove.forEach(function (ele) { + return ele.children().move({ + parent: null + }); + }); + + // intermediate parents may be moved by prior line, so make sure we remove by fresh refs + parentsToRemove.forEach(function (ele) { + return getFreshRef(ele).remove(); + }); + } + if (obj.style) { + cy.style(obj.style); + } + if (obj.zoom != null && obj.zoom !== _p.zoom) { + cy.zoom(obj.zoom); + } + if (obj.pan) { + if (obj.pan.x !== _p.pan.x || obj.pan.y !== _p.pan.y) { + cy.pan(obj.pan); + } + } + if (obj.data) { + cy.data(obj.data); + } + var fields = ['minZoom', 'maxZoom', 'zoomingEnabled', 'userZoomingEnabled', 'panningEnabled', 'userPanningEnabled', 'boxSelectionEnabled', 'autolock', 'autoungrabify', 'autounselectify', 'multiClickDebounceTime']; + for (var _i2 = 0; _i2 < fields.length; _i2++) { + var f = fields[_i2]; + if (obj[f] != null) { + cy[f](obj[f]); + } + } + cy.endBatch(); + return this; // chaining + } else { + // get + var flat = !!obj; + var json = {}; + if (flat) { + json.elements = this.elements().map(function (ele) { + return ele.json(); + }); + } else { + json.elements = {}; + eles.forEach(function (ele) { + var group = ele.group(); + if (!json.elements[group]) { + json.elements[group] = []; + } + json.elements[group].push(ele.json()); + }); + } + if (this._private.styleEnabled) { + json.style = cy.style().json(); + } + json.data = copy(cy.data()); + var options = _p.options; + json.zoomingEnabled = _p.zoomingEnabled; + json.userZoomingEnabled = _p.userZoomingEnabled; + json.zoom = _p.zoom; + json.minZoom = _p.minZoom; + json.maxZoom = _p.maxZoom; + json.panningEnabled = _p.panningEnabled; + json.userPanningEnabled = _p.userPanningEnabled; + json.pan = copy(_p.pan); + json.boxSelectionEnabled = _p.boxSelectionEnabled; + json.renderer = copy(options.renderer); + json.hideEdgesOnViewport = options.hideEdgesOnViewport; + json.textureOnViewport = options.textureOnViewport; + json.wheelSensitivity = options.wheelSensitivity; + json.motionBlur = options.motionBlur; + json.multiClickDebounceTime = options.multiClickDebounceTime; + return json; + } + } +}); +corefn.$id = corefn.getElementById; +[corefn$9, corefn$8, elesfn, corefn$7, corefn$6, corefn$5, corefn$4, corefn$3, corefn$2, corefn$1, fn].forEach(function (props) { + extend(corefn, props); +}); + +/* eslint-disable no-unused-vars */ +var defaults$7 = { + fit: true, + // whether to fit the viewport to the graph + directed: false, + // whether the tree is directed downwards (or edges can point in any direction if false) + padding: 30, + // padding on fit + circle: false, + // put depths in concentric circles if true, put depths top down if false + grid: false, + // whether to create an even grid into which the DAG is placed (circle:false only) + spacingFactor: 1.75, + // positive spacing factor, larger => more space between nodes (N.B. n/a if causes overlap) + boundingBox: undefined, + // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } + avoidOverlap: true, + // prevents node overlap, may overflow boundingBox if not enough space + nodeDimensionsIncludeLabels: false, + // Excludes the label when calculating node bounding boxes for the layout algorithm + roots: undefined, + // the roots of the trees + depthSort: undefined, + // a sorting function to order nodes at equal depth. e.g. function(a, b){ return a.data('weight') - b.data('weight') } + animate: false, + // whether to transition the node positions + animationDuration: 500, + // duration of animation in ms if enabled + animationEasing: undefined, + // easing of animation if enabled, + animateFilter: function animateFilter(node, i) { + return true; + }, + // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts + ready: undefined, + // callback on layoutready + stop: undefined, + // callback on layoutstop + transform: function transform(node, position) { + return position; + } // transform a given node position. Useful for changing flow direction in discrete layouts +}; + +var deprecatedOptionDefaults = { + maximal: false, + // whether to shift nodes down their natural BFS depths in order to avoid upwards edges (DAGS only); setting acyclic to true sets maximal to true also + acyclic: false // whether the tree is acyclic and thus a node could be shifted (due to the maximal option) multiple times without causing an infinite loop; setting to true sets maximal to true also; if you are uncertain whether a tree is acyclic, set to false to avoid potential infinite loops +}; + +/* eslint-enable */ + +var getInfo = function getInfo(ele) { + return ele.scratch('breadthfirst'); +}; +var setInfo = function setInfo(ele, obj) { + return ele.scratch('breadthfirst', obj); +}; +function BreadthFirstLayout(options) { + this.options = extend({}, defaults$7, deprecatedOptionDefaults, options); +} +BreadthFirstLayout.prototype.run = function () { + var params = this.options; + var options = params; + var cy = params.cy; + var eles = options.eles; + var nodes = eles.nodes().filter(function (n) { + return !n.isParent(); + }); + var graph = eles; + var directed = options.directed; + var maximal = options.acyclic || options.maximal || options.maximalAdjustments > 0; // maximalAdjustments for compat. w/ old code; also, setting acyclic to true sets maximal to true + + var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : { + x1: 0, + y1: 0, + w: cy.width(), + h: cy.height() + }); + var roots; + if (elementOrCollection(options.roots)) { + roots = options.roots; + } else if (array(options.roots)) { + var rootsArray = []; + for (var i = 0; i < options.roots.length; i++) { + var id = options.roots[i]; + var ele = cy.getElementById(id); + rootsArray.push(ele); + } + roots = cy.collection(rootsArray); + } else if (string(options.roots)) { + roots = cy.$(options.roots); + } else { + if (directed) { + roots = nodes.roots(); + } else { + var components = eles.components(); + roots = cy.collection(); + var _loop = function _loop(_i) { + var comp = components[_i]; + var maxDegree = comp.maxDegree(false); + var compRoots = comp.filter(function (ele) { + return ele.degree(false) === maxDegree; + }); + roots = roots.add(compRoots); + }; + for (var _i = 0; _i < components.length; _i++) { + _loop(_i); + } + } + } + var depths = []; + var foundByBfs = {}; + var addToDepth = function addToDepth(ele, d) { + if (depths[d] == null) { + depths[d] = []; + } + var i = depths[d].length; + depths[d].push(ele); + setInfo(ele, { + index: i, + depth: d + }); + }; + var changeDepth = function changeDepth(ele, newDepth) { + var _getInfo = getInfo(ele), + depth = _getInfo.depth, + index = _getInfo.index; + depths[depth][index] = null; + addToDepth(ele, newDepth); + }; + + // find the depths of the nodes + graph.bfs({ + roots: roots, + directed: options.directed, + visit: function visit(node, edge, pNode, i, depth) { + var ele = node[0]; + var id = ele.id(); + addToDepth(ele, depth); + foundByBfs[id] = true; + } + }); + + // check for nodes not found by bfs + var orphanNodes = []; + for (var _i2 = 0; _i2 < nodes.length; _i2++) { + var _ele = nodes[_i2]; + if (foundByBfs[_ele.id()]) { + continue; + } else { + orphanNodes.push(_ele); + } + } + + // assign the nodes a depth and index + + var assignDepthsAt = function assignDepthsAt(i) { + var eles = depths[i]; + for (var j = 0; j < eles.length; j++) { + var _ele2 = eles[j]; + if (_ele2 == null) { + eles.splice(j, 1); + j--; + continue; + } + setInfo(_ele2, { + depth: i, + index: j + }); + } + }; + var assignDepths = function assignDepths() { + for (var _i3 = 0; _i3 < depths.length; _i3++) { + assignDepthsAt(_i3); + } + }; + var adjustMaximally = function adjustMaximally(ele, shifted) { + var eInfo = getInfo(ele); + var incomers = ele.incomers().filter(function (el) { + return el.isNode() && eles.has(el); + }); + var maxDepth = -1; + var id = ele.id(); + for (var k = 0; k < incomers.length; k++) { + var incmr = incomers[k]; + var iInfo = getInfo(incmr); + maxDepth = Math.max(maxDepth, iInfo.depth); + } + if (eInfo.depth <= maxDepth) { + if (!options.acyclic && shifted[id]) { + return null; + } + var newDepth = maxDepth + 1; + changeDepth(ele, newDepth); + shifted[id] = newDepth; + return true; + } + return false; + }; + + // for the directed case, try to make the edges all go down (i.e. depth i => depth i + 1) + if (directed && maximal) { + var Q = []; + var shifted = {}; + var enqueue = function enqueue(n) { + return Q.push(n); + }; + var dequeue = function dequeue() { + return Q.shift(); + }; + nodes.forEach(function (n) { + return Q.push(n); + }); + while (Q.length > 0) { + var _ele3 = dequeue(); + var didShift = adjustMaximally(_ele3, shifted); + if (didShift) { + _ele3.outgoers().filter(function (el) { + return el.isNode() && eles.has(el); + }).forEach(enqueue); + } else if (didShift === null) { + warn('Detected double maximal shift for node `' + _ele3.id() + '`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.'); + break; // exit on failure + } + } + } + + assignDepths(); // clear holes + + // find min distance we need to leave between nodes + var minDistance = 0; + if (options.avoidOverlap) { + for (var _i4 = 0; _i4 < nodes.length; _i4++) { + var n = nodes[_i4]; + var nbb = n.layoutDimensions(options); + var w = nbb.w; + var h = nbb.h; + minDistance = Math.max(minDistance, w, h); + } + } + + // get the weighted percent for an element based on its connectivity to other levels + var cachedWeightedPercent = {}; + var getWeightedPercent = function getWeightedPercent(ele) { + if (cachedWeightedPercent[ele.id()]) { + return cachedWeightedPercent[ele.id()]; + } + var eleDepth = getInfo(ele).depth; + var neighbors = ele.neighborhood(); + var percent = 0; + var samples = 0; + for (var _i5 = 0; _i5 < neighbors.length; _i5++) { + var neighbor = neighbors[_i5]; + if (neighbor.isEdge() || neighbor.isParent() || !nodes.has(neighbor)) { + continue; + } + var bf = getInfo(neighbor); + if (bf == null) { + continue; + } + var index = bf.index; + var depth = bf.depth; + + // unassigned neighbours shouldn't affect the ordering + if (index == null || depth == null) { + continue; + } + var nDepth = depths[depth].length; + if (depth < eleDepth) { + // only get influenced by elements above + percent += index / nDepth; + samples++; + } + } + samples = Math.max(1, samples); + percent = percent / samples; + if (samples === 0) { + // put lone nodes at the start + percent = 0; + } + cachedWeightedPercent[ele.id()] = percent; + return percent; + }; + + // rearrange the indices in each depth level based on connectivity + + var sortFn = function sortFn(a, b) { + var apct = getWeightedPercent(a); + var bpct = getWeightedPercent(b); + var diff = apct - bpct; + if (diff === 0) { + return ascending(a.id(), b.id()); // make sure sort doesn't have don't-care comparisons + } else { + return diff; + } + }; + if (options.depthSort !== undefined) { + sortFn = options.depthSort; + } + + // sort each level to make connected nodes closer + for (var _i6 = 0; _i6 < depths.length; _i6++) { + depths[_i6].sort(sortFn); + assignDepthsAt(_i6); + } + + // assign orphan nodes to a new top-level depth + var orphanDepth = []; + for (var _i7 = 0; _i7 < orphanNodes.length; _i7++) { + orphanDepth.push(orphanNodes[_i7]); + } + depths.unshift(orphanDepth); + assignDepths(); + var biggestDepthSize = 0; + for (var _i8 = 0; _i8 < depths.length; _i8++) { + biggestDepthSize = Math.max(depths[_i8].length, biggestDepthSize); + } + var center = { + x: bb.x1 + bb.w / 2, + y: bb.x1 + bb.h / 2 + }; + var maxDepthSize = depths.reduce(function (max, eles) { + return Math.max(max, eles.length); + }, 0); + var getPosition = function getPosition(ele) { + var _getInfo2 = getInfo(ele), + depth = _getInfo2.depth, + index = _getInfo2.index; + var depthSize = depths[depth].length; + var distanceX = Math.max(bb.w / ((options.grid ? maxDepthSize : depthSize) + 1), minDistance); + var distanceY = Math.max(bb.h / (depths.length + 1), minDistance); + var radiusStepSize = Math.min(bb.w / 2 / depths.length, bb.h / 2 / depths.length); + radiusStepSize = Math.max(radiusStepSize, minDistance); + if (!options.circle) { + var epos = { + x: center.x + (index + 1 - (depthSize + 1) / 2) * distanceX, + y: (depth + 1) * distanceY + }; + return epos; + } else { + var radius = radiusStepSize * depth + radiusStepSize - (depths.length > 0 && depths[0].length <= 3 ? radiusStepSize / 2 : 0); + var theta = 2 * Math.PI / depths[depth].length * index; + if (depth === 0 && depths[0].length === 1) { + radius = 1; + } + return { + x: center.x + radius * Math.cos(theta), + y: center.y + radius * Math.sin(theta) + }; + } + }; + eles.nodes().layoutPositions(this, options, getPosition); + return this; // chaining +}; + +var defaults$6 = { + fit: true, + // whether to fit the viewport to the graph + padding: 30, + // the padding on fit + boundingBox: undefined, + // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } + avoidOverlap: true, + // prevents node overlap, may overflow boundingBox and radius if not enough space + nodeDimensionsIncludeLabels: false, + // Excludes the label when calculating node bounding boxes for the layout algorithm + spacingFactor: undefined, + // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up + radius: undefined, + // the radius of the circle + startAngle: 3 / 2 * Math.PI, + // where nodes start in radians + sweep: undefined, + // how many radians should be between the first and last node (defaults to full circle) + clockwise: true, + // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false) + sort: undefined, + // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') } + animate: false, + // whether to transition the node positions + animationDuration: 500, + // duration of animation in ms if enabled + animationEasing: undefined, + // easing of animation if enabled + animateFilter: function animateFilter(node, i) { + return true; + }, + // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts + ready: undefined, + // callback on layoutready + stop: undefined, + // callback on layoutstop + transform: function transform(node, position) { + return position; + } // transform a given node position. Useful for changing flow direction in discrete layouts +}; + +function CircleLayout(options) { + this.options = extend({}, defaults$6, options); +} +CircleLayout.prototype.run = function () { + var params = this.options; + var options = params; + var cy = params.cy; + var eles = options.eles; + var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise; + var nodes = eles.nodes().not(':parent'); + if (options.sort) { + nodes = nodes.sort(options.sort); + } + var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : { + x1: 0, + y1: 0, + w: cy.width(), + h: cy.height() + }); + var center = { + x: bb.x1 + bb.w / 2, + y: bb.y1 + bb.h / 2 + }; + var sweep = options.sweep === undefined ? 2 * Math.PI - 2 * Math.PI / nodes.length : options.sweep; + var dTheta = sweep / Math.max(1, nodes.length - 1); + var r; + var minDistance = 0; + for (var i = 0; i < nodes.length; i++) { + var n = nodes[i]; + var nbb = n.layoutDimensions(options); + var w = nbb.w; + var h = nbb.h; + minDistance = Math.max(minDistance, w, h); + } + if (number$1(options.radius)) { + r = options.radius; + } else if (nodes.length <= 1) { + r = 0; + } else { + r = Math.min(bb.h, bb.w) / 2 - minDistance; + } + + // calculate the radius + if (nodes.length > 1 && options.avoidOverlap) { + // but only if more than one node (can't overlap) + minDistance *= 1.75; // just to have some nice spacing + + var dcos = Math.cos(dTheta) - Math.cos(0); + var dsin = Math.sin(dTheta) - Math.sin(0); + var rMin = Math.sqrt(minDistance * minDistance / (dcos * dcos + dsin * dsin)); // s.t. no nodes overlapping + r = Math.max(rMin, r); + } + var getPos = function getPos(ele, i) { + var theta = options.startAngle + i * dTheta * (clockwise ? 1 : -1); + var rx = r * Math.cos(theta); + var ry = r * Math.sin(theta); + var pos = { + x: center.x + rx, + y: center.y + ry + }; + return pos; + }; + eles.nodes().layoutPositions(this, options, getPos); + return this; // chaining +}; + +var defaults$5 = { + fit: true, + // whether to fit the viewport to the graph + padding: 30, + // the padding on fit + startAngle: 3 / 2 * Math.PI, + // where nodes start in radians + sweep: undefined, + // how many radians should be between the first and last node (defaults to full circle) + clockwise: true, + // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false) + equidistant: false, + // whether levels have an equal radial distance betwen them, may cause bounding box overflow + minNodeSpacing: 10, + // min spacing between outside of nodes (used for radius adjustment) + boundingBox: undefined, + // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } + avoidOverlap: true, + // prevents node overlap, may overflow boundingBox if not enough space + nodeDimensionsIncludeLabels: false, + // Excludes the label when calculating node bounding boxes for the layout algorithm + height: undefined, + // height of layout area (overrides container height) + width: undefined, + // width of layout area (overrides container width) + spacingFactor: undefined, + // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up + concentric: function concentric(node) { + // returns numeric value for each node, placing higher nodes in levels towards the centre + return node.degree(); + }, + levelWidth: function levelWidth(nodes) { + // the variation of concentric values in each level + return nodes.maxDegree() / 4; + }, + animate: false, + // whether to transition the node positions + animationDuration: 500, + // duration of animation in ms if enabled + animationEasing: undefined, + // easing of animation if enabled + animateFilter: function animateFilter(node, i) { + return true; + }, + // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts + ready: undefined, + // callback on layoutready + stop: undefined, + // callback on layoutstop + transform: function transform(node, position) { + return position; + } // transform a given node position. Useful for changing flow direction in discrete layouts +}; + +function ConcentricLayout(options) { + this.options = extend({}, defaults$5, options); +} +ConcentricLayout.prototype.run = function () { + var params = this.options; + var options = params; + var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise; + var cy = params.cy; + var eles = options.eles; + var nodes = eles.nodes().not(':parent'); + var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : { + x1: 0, + y1: 0, + w: cy.width(), + h: cy.height() + }); + var center = { + x: bb.x1 + bb.w / 2, + y: bb.y1 + bb.h / 2 + }; + var nodeValues = []; // { node, value } + var maxNodeSize = 0; + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var value = void 0; + + // calculate the node value + value = options.concentric(node); + nodeValues.push({ + value: value, + node: node + }); + + // for style mapping + node._private.scratch.concentric = value; + } + + // in case we used the `concentric` in style + nodes.updateStyle(); + + // calculate max size now based on potentially updated mappers + for (var _i = 0; _i < nodes.length; _i++) { + var _node = nodes[_i]; + var nbb = _node.layoutDimensions(options); + maxNodeSize = Math.max(maxNodeSize, nbb.w, nbb.h); + } + + // sort node values in descreasing order + nodeValues.sort(function (a, b) { + return b.value - a.value; + }); + var levelWidth = options.levelWidth(nodes); + + // put the values into levels + var levels = [[]]; + var currentLevel = levels[0]; + for (var _i2 = 0; _i2 < nodeValues.length; _i2++) { + var val = nodeValues[_i2]; + if (currentLevel.length > 0) { + var diff = Math.abs(currentLevel[0].value - val.value); + if (diff >= levelWidth) { + currentLevel = []; + levels.push(currentLevel); + } + } + currentLevel.push(val); + } + + // create positions from levels + + var minDist = maxNodeSize + options.minNodeSpacing; // min dist between nodes + + if (!options.avoidOverlap) { + // then strictly constrain to bb + var firstLvlHasMulti = levels.length > 0 && levels[0].length > 1; + var maxR = Math.min(bb.w, bb.h) / 2 - minDist; + var rStep = maxR / (levels.length + firstLvlHasMulti ? 1 : 0); + minDist = Math.min(minDist, rStep); + } + + // find the metrics for each level + var r = 0; + for (var _i3 = 0; _i3 < levels.length; _i3++) { + var level = levels[_i3]; + var sweep = options.sweep === undefined ? 2 * Math.PI - 2 * Math.PI / level.length : options.sweep; + var dTheta = level.dTheta = sweep / Math.max(1, level.length - 1); + + // calculate the radius + if (level.length > 1 && options.avoidOverlap) { + // but only if more than one node (can't overlap) + var dcos = Math.cos(dTheta) - Math.cos(0); + var dsin = Math.sin(dTheta) - Math.sin(0); + var rMin = Math.sqrt(minDist * minDist / (dcos * dcos + dsin * dsin)); // s.t. no nodes overlapping + + r = Math.max(rMin, r); + } + level.r = r; + r += minDist; + } + if (options.equidistant) { + var rDeltaMax = 0; + var _r = 0; + for (var _i4 = 0; _i4 < levels.length; _i4++) { + var _level = levels[_i4]; + var rDelta = _level.r - _r; + rDeltaMax = Math.max(rDeltaMax, rDelta); + } + _r = 0; + for (var _i5 = 0; _i5 < levels.length; _i5++) { + var _level2 = levels[_i5]; + if (_i5 === 0) { + _r = _level2.r; + } + _level2.r = _r; + _r += rDeltaMax; + } + } + + // calculate the node positions + var pos = {}; // id => position + for (var _i6 = 0; _i6 < levels.length; _i6++) { + var _level3 = levels[_i6]; + var _dTheta = _level3.dTheta; + var _r2 = _level3.r; + for (var j = 0; j < _level3.length; j++) { + var _val = _level3[j]; + var theta = options.startAngle + (clockwise ? 1 : -1) * _dTheta * j; + var p = { + x: center.x + _r2 * Math.cos(theta), + y: center.y + _r2 * Math.sin(theta) + }; + pos[_val.node.id()] = p; + } + } + + // position the nodes + eles.nodes().layoutPositions(this, options, function (ele) { + var id = ele.id(); + return pos[id]; + }); + return this; // chaining +}; + +/* +The CoSE layout was written by Gerardo Huck. +https://www.linkedin.com/in/gerardohuck/ + +Based on the following article: +http://dl.acm.org/citation.cfm?id=1498047 + +Modifications tracked on Github. +*/ +var DEBUG; + +/** + * @brief : default layout options + */ +var defaults$4 = { + // Called on `layoutready` + ready: function ready() {}, + // Called on `layoutstop` + stop: function stop() {}, + // Whether to animate while running the layout + // true : Animate continuously as the layout is running + // false : Just show the end result + // 'end' : Animate with the end result, from the initial positions to the end positions + animate: true, + // Easing of the animation for animate:'end' + animationEasing: undefined, + // The duration of the animation for animate:'end' + animationDuration: undefined, + // A function that determines whether the node should be animated + // All nodes animated by default on animate enabled + // Non-animated nodes are positioned immediately when the layout starts + animateFilter: function animateFilter(node, i) { + return true; + }, + // The layout animates only after this many milliseconds for animate:true + // (prevents flashing on fast runs) + animationThreshold: 250, + // Number of iterations between consecutive screen positions update + refresh: 20, + // Whether to fit the network view after when done + fit: true, + // Padding on fit + padding: 30, + // Constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } + boundingBox: undefined, + // Excludes the label when calculating node bounding boxes for the layout algorithm + nodeDimensionsIncludeLabels: false, + // Randomize the initial positions of the nodes (true) or use existing positions (false) + randomize: false, + // Extra spacing between components in non-compound graphs + componentSpacing: 40, + // Node repulsion (non overlapping) multiplier + nodeRepulsion: function nodeRepulsion(node) { + return 2048; + }, + // Node repulsion (overlapping) multiplier + nodeOverlap: 4, + // Ideal edge (non nested) length + idealEdgeLength: function idealEdgeLength(edge) { + return 32; + }, + // Divisor to compute edge forces + edgeElasticity: function edgeElasticity(edge) { + return 32; + }, + // Nesting factor (multiplier) to compute ideal edge length for nested edges + nestingFactor: 1.2, + // Gravity force (constant) + gravity: 1, + // Maximum number of iterations to perform + numIter: 1000, + // Initial temperature (maximum node displacement) + initialTemp: 1000, + // Cooling factor (how the temperature is reduced between consecutive iterations + coolingFactor: 0.99, + // Lower temperature threshold (below this point the layout will end) + minTemp: 1.0 +}; + +/** + * @brief : constructor + * @arg options : object containing layout options + */ +function CoseLayout(options) { + this.options = extend({}, defaults$4, options); + this.options.layout = this; + + // Exclude any edge that has a source or target node that is not in the set of passed-in nodes + var nodes = this.options.eles.nodes(); + var edges = this.options.eles.edges(); + var notEdges = edges.filter(function (e) { + var sourceId = e.source().data('id'); + var targetId = e.target().data('id'); + var hasSource = nodes.some(function (n) { + return n.data('id') === sourceId; + }); + var hasTarget = nodes.some(function (n) { + return n.data('id') === targetId; + }); + return !hasSource || !hasTarget; + }); + this.options.eles = this.options.eles.not(notEdges); +} + +/** + * @brief : runs the layout + */ +CoseLayout.prototype.run = function () { + var options = this.options; + var cy = options.cy; + var layout = this; + layout.stopped = false; + if (options.animate === true || options.animate === false) { + layout.emit({ + type: 'layoutstart', + layout: layout + }); + } + + // Set DEBUG - Global variable + if (true === options.debug) { + DEBUG = true; + } else { + DEBUG = false; + } + + // Initialize layout info + var layoutInfo = createLayoutInfo(cy, layout, options); + + // Show LayoutInfo contents if debugging + if (DEBUG) { + printLayoutInfo(layoutInfo); + } + + // If required, randomize node positions + if (options.randomize) { + randomizePositions(layoutInfo); + } + var startTime = performanceNow(); + var refresh = function refresh() { + refreshPositions(layoutInfo, cy, options); + + // Fit the graph if necessary + if (true === options.fit) { + cy.fit(options.padding); + } + }; + var mainLoop = function mainLoop(i) { + if (layout.stopped || i >= options.numIter) { + // logDebug("Layout manually stopped. Stopping computation in step " + i); + return false; + } + + // Do one step in the phisical simulation + step(layoutInfo, options); + + // Update temperature + layoutInfo.temperature = layoutInfo.temperature * options.coolingFactor; + // logDebug("New temperature: " + layoutInfo.temperature); + + if (layoutInfo.temperature < options.minTemp) { + // logDebug("Temperature drop below minimum threshold. Stopping computation in step " + i); + return false; + } + return true; + }; + var done = function done() { + if (options.animate === true || options.animate === false) { + refresh(); + + // Layout has finished + layout.one('layoutstop', options.stop); + layout.emit({ + type: 'layoutstop', + layout: layout + }); + } else { + var nodes = options.eles.nodes(); + var getScaledPos = getScaleInBoundsFn(layoutInfo, options, nodes); + nodes.layoutPositions(layout, options, getScaledPos); + } + }; + var i = 0; + var loopRet = true; + if (options.animate === true) { + var frame = function frame() { + var f = 0; + while (loopRet && f < options.refresh) { + loopRet = mainLoop(i); + i++; + f++; + } + if (!loopRet) { + // it's done + separateComponents(layoutInfo, options); + done(); + } else { + var now = performanceNow(); + if (now - startTime >= options.animationThreshold) { + refresh(); + } + requestAnimationFrame(frame); + } + }; + frame(); + } else { + while (loopRet) { + loopRet = mainLoop(i); + i++; + } + separateComponents(layoutInfo, options); + done(); + } + return this; // chaining +}; + +/** + * @brief : called on continuous layouts to stop them before they finish + */ +CoseLayout.prototype.stop = function () { + this.stopped = true; + if (this.thread) { + this.thread.stop(); + } + this.emit('layoutstop'); + return this; // chaining +}; + +CoseLayout.prototype.destroy = function () { + if (this.thread) { + this.thread.stop(); + } + return this; // chaining +}; + +/** + * @brief : Creates an object which is contains all the data + * used in the layout process + * @arg cy : cytoscape.js object + * @return : layoutInfo object initialized + */ +var createLayoutInfo = function createLayoutInfo(cy, layout, options) { + // Shortcut + var edges = options.eles.edges(); + var nodes = options.eles.nodes(); + var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : { + x1: 0, + y1: 0, + w: cy.width(), + h: cy.height() + }); + var layoutInfo = { + isCompound: cy.hasCompoundNodes(), + layoutNodes: [], + idToIndex: {}, + nodeSize: nodes.size(), + graphSet: [], + indexToGraph: [], + layoutEdges: [], + edgeSize: edges.size(), + temperature: options.initialTemp, + clientWidth: bb.w, + clientHeight: bb.h, + boundingBox: bb + }; + var components = options.eles.components(); + var id2cmptId = {}; + for (var i = 0; i < components.length; i++) { + var component = components[i]; + for (var j = 0; j < component.length; j++) { + var node = component[j]; + id2cmptId[node.id()] = i; + } + } + + // Iterate over all nodes, creating layout nodes + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = nodes[i]; + var nbb = n.layoutDimensions(options); + var tempNode = {}; + tempNode.isLocked = n.locked(); + tempNode.id = n.data('id'); + tempNode.parentId = n.data('parent'); + tempNode.cmptId = id2cmptId[n.id()]; + tempNode.children = []; + tempNode.positionX = n.position('x'); + tempNode.positionY = n.position('y'); + tempNode.offsetX = 0; + tempNode.offsetY = 0; + tempNode.height = nbb.w; + tempNode.width = nbb.h; + tempNode.maxX = tempNode.positionX + tempNode.width / 2; + tempNode.minX = tempNode.positionX - tempNode.width / 2; + tempNode.maxY = tempNode.positionY + tempNode.height / 2; + tempNode.minY = tempNode.positionY - tempNode.height / 2; + tempNode.padLeft = parseFloat(n.style('padding')); + tempNode.padRight = parseFloat(n.style('padding')); + tempNode.padTop = parseFloat(n.style('padding')); + tempNode.padBottom = parseFloat(n.style('padding')); + + // forces + tempNode.nodeRepulsion = fn$6(options.nodeRepulsion) ? options.nodeRepulsion(n) : options.nodeRepulsion; + + // Add new node + layoutInfo.layoutNodes.push(tempNode); + // Add entry to id-index map + layoutInfo.idToIndex[tempNode.id] = i; + } + + // Inline implementation of a queue, used for traversing the graph in BFS order + var queue = []; + var start = 0; // Points to the start the queue + var end = -1; // Points to the end of the queue + + var tempGraph = []; + + // Second pass to add child information and + // initialize queue for hierarchical traversal + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = layoutInfo.layoutNodes[i]; + var p_id = n.parentId; + // Check if node n has a parent node + if (null != p_id) { + // Add node Id to parent's list of children + layoutInfo.layoutNodes[layoutInfo.idToIndex[p_id]].children.push(n.id); + } else { + // If a node doesn't have a parent, then it's in the root graph + queue[++end] = n.id; + tempGraph.push(n.id); + } + } + + // Add root graph to graphSet + layoutInfo.graphSet.push(tempGraph); + + // Traverse the graph, level by level, + while (start <= end) { + // Get the node to visit and remove it from queue + var node_id = queue[start++]; + var node_ix = layoutInfo.idToIndex[node_id]; + var node = layoutInfo.layoutNodes[node_ix]; + var children = node.children; + if (children.length > 0) { + // Add children nodes as a new graph to graph set + layoutInfo.graphSet.push(children); + // Add children to que queue to be visited + for (var i = 0; i < children.length; i++) { + queue[++end] = children[i]; + } + } + } + + // Create indexToGraph map + for (var i = 0; i < layoutInfo.graphSet.length; i++) { + var graph = layoutInfo.graphSet[i]; + for (var j = 0; j < graph.length; j++) { + var index = layoutInfo.idToIndex[graph[j]]; + layoutInfo.indexToGraph[index] = i; + } + } + + // Iterate over all edges, creating Layout Edges + for (var i = 0; i < layoutInfo.edgeSize; i++) { + var e = edges[i]; + var tempEdge = {}; + tempEdge.id = e.data('id'); + tempEdge.sourceId = e.data('source'); + tempEdge.targetId = e.data('target'); + + // Compute ideal length + var idealLength = fn$6(options.idealEdgeLength) ? options.idealEdgeLength(e) : options.idealEdgeLength; + var elasticity = fn$6(options.edgeElasticity) ? options.edgeElasticity(e) : options.edgeElasticity; + + // Check if it's an inter graph edge + var sourceIx = layoutInfo.idToIndex[tempEdge.sourceId]; + var targetIx = layoutInfo.idToIndex[tempEdge.targetId]; + var sourceGraph = layoutInfo.indexToGraph[sourceIx]; + var targetGraph = layoutInfo.indexToGraph[targetIx]; + if (sourceGraph != targetGraph) { + // Find lowest common graph ancestor + var lca = findLCA(tempEdge.sourceId, tempEdge.targetId, layoutInfo); + + // Compute sum of node depths, relative to lca graph + var lcaGraph = layoutInfo.graphSet[lca]; + var depth = 0; + + // Source depth + var tempNode = layoutInfo.layoutNodes[sourceIx]; + while (-1 === lcaGraph.indexOf(tempNode.id)) { + tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]]; + depth++; + } + + // Target depth + tempNode = layoutInfo.layoutNodes[targetIx]; + while (-1 === lcaGraph.indexOf(tempNode.id)) { + tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]]; + depth++; + } + + // logDebug('LCA of nodes ' + tempEdge.sourceId + ' and ' + tempEdge.targetId + + // ". Index: " + lca + " Contents: " + lcaGraph.toString() + + // ". Depth: " + depth); + + // Update idealLength + idealLength *= depth * options.nestingFactor; + } + tempEdge.idealLength = idealLength; + tempEdge.elasticity = elasticity; + layoutInfo.layoutEdges.push(tempEdge); + } + + // Finally, return layoutInfo object + return layoutInfo; +}; + +/** + * @brief : This function finds the index of the lowest common + * graph ancestor between 2 nodes in the subtree + * (from the graph hierarchy induced tree) whose + * root is graphIx + * + * @arg node1: node1's ID + * @arg node2: node2's ID + * @arg layoutInfo: layoutInfo object + * + */ +var findLCA = function findLCA(node1, node2, layoutInfo) { + // Find their common ancester, starting from the root graph + var res = findLCA_aux(node1, node2, 0, layoutInfo); + if (2 > res.count) { + // If aux function couldn't find the common ancester, + // then it is the root graph + return 0; + } else { + return res.graph; + } +}; + +/** + * @brief : Auxiliary function used for LCA computation + * + * @arg node1 : node1's ID + * @arg node2 : node2's ID + * @arg graphIx : subgraph index + * @arg layoutInfo : layoutInfo object + * + * @return : object of the form {count: X, graph: Y}, where: + * X is the number of ancestors (max: 2) found in + * graphIx (and it's subgraphs), + * Y is the graph index of the lowest graph containing + * all X nodes + */ +var findLCA_aux = function findLCA_aux(node1, node2, graphIx, layoutInfo) { + var graph = layoutInfo.graphSet[graphIx]; + // If both nodes belongs to graphIx + if (-1 < graph.indexOf(node1) && -1 < graph.indexOf(node2)) { + return { + count: 2, + graph: graphIx + }; + } + + // Make recursive calls for all subgraphs + var c = 0; + for (var i = 0; i < graph.length; i++) { + var nodeId = graph[i]; + var nodeIx = layoutInfo.idToIndex[nodeId]; + var children = layoutInfo.layoutNodes[nodeIx].children; + + // If the node has no child, skip it + if (0 === children.length) { + continue; + } + var childGraphIx = layoutInfo.indexToGraph[layoutInfo.idToIndex[children[0]]]; + var result = findLCA_aux(node1, node2, childGraphIx, layoutInfo); + if (0 === result.count) { + // Neither node1 nor node2 are present in this subgraph + continue; + } else if (1 === result.count) { + // One of (node1, node2) is present in this subgraph + c++; + if (2 === c) { + // We've already found both nodes, no need to keep searching + break; + } + } else { + // Both nodes are present in this subgraph + return result; + } + } + return { + count: c, + graph: graphIx + }; +}; + +/** + * @brief: printsLayoutInfo into js console + * Only used for debbuging + */ +var printLayoutInfo; + +/** + * @brief : Randomizes the position of all nodes + */ +var randomizePositions = function randomizePositions(layoutInfo, cy) { + var width = layoutInfo.clientWidth; + var height = layoutInfo.clientHeight; + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = layoutInfo.layoutNodes[i]; + + // No need to randomize compound nodes or locked nodes + if (0 === n.children.length && !n.isLocked) { + n.positionX = Math.random() * width; + n.positionY = Math.random() * height; + } + } +}; +var getScaleInBoundsFn = function getScaleInBoundsFn(layoutInfo, options, nodes) { + var bb = layoutInfo.boundingBox; + var coseBB = { + x1: Infinity, + x2: -Infinity, + y1: Infinity, + y2: -Infinity + }; + if (options.boundingBox) { + nodes.forEach(function (node) { + var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[node.data('id')]]; + coseBB.x1 = Math.min(coseBB.x1, lnode.positionX); + coseBB.x2 = Math.max(coseBB.x2, lnode.positionX); + coseBB.y1 = Math.min(coseBB.y1, lnode.positionY); + coseBB.y2 = Math.max(coseBB.y2, lnode.positionY); + }); + coseBB.w = coseBB.x2 - coseBB.x1; + coseBB.h = coseBB.y2 - coseBB.y1; + } + return function (ele, i) { + var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[ele.data('id')]]; + if (options.boundingBox) { + // then add extra bounding box constraint + var pctX = (lnode.positionX - coseBB.x1) / coseBB.w; + var pctY = (lnode.positionY - coseBB.y1) / coseBB.h; + return { + x: bb.x1 + pctX * bb.w, + y: bb.y1 + pctY * bb.h + }; + } else { + return { + x: lnode.positionX, + y: lnode.positionY + }; + } + }; +}; + +/** + * @brief : Updates the positions of nodes in the network + * @arg layoutInfo : LayoutInfo object + * @arg cy : Cytoscape object + * @arg options : Layout options + */ +var refreshPositions = function refreshPositions(layoutInfo, cy, options) { + // var s = 'Refreshing positions'; + // logDebug(s); + + var layout = options.layout; + var nodes = options.eles.nodes(); + var getScaledPos = getScaleInBoundsFn(layoutInfo, options, nodes); + nodes.positions(getScaledPos); + + // Trigger layoutReady only on first call + if (true !== layoutInfo.ready) { + // s = 'Triggering layoutready'; + // logDebug(s); + layoutInfo.ready = true; + layout.one('layoutready', options.ready); + layout.emit({ + type: 'layoutready', + layout: this + }); + } +}; + +/** + * @brief : Logs a debug message in JS console, if DEBUG is ON + */ +// var logDebug = function(text) { +// if (DEBUG) { +// console.debug(text); +// } +// }; + +/** + * @brief : Performs one iteration of the physical simulation + * @arg layoutInfo : LayoutInfo object already initialized + * @arg cy : Cytoscape object + * @arg options : Layout options + */ +var step = function step(layoutInfo, options, _step) { + // var s = "\n\n###############################"; + // s += "\nSTEP: " + step; + // s += "\n###############################\n"; + // logDebug(s); + + // Calculate node repulsions + calculateNodeForces(layoutInfo, options); + // Calculate edge forces + calculateEdgeForces(layoutInfo); + // Calculate gravity forces + calculateGravityForces(layoutInfo, options); + // Propagate forces from parent to child + propagateForces(layoutInfo); + // Update positions based on calculated forces + updatePositions(layoutInfo); +}; + +/** + * @brief : Computes the node repulsion forces + */ +var calculateNodeForces = function calculateNodeForces(layoutInfo, options) { + // Go through each of the graphs in graphSet + // Nodes only repel each other if they belong to the same graph + // var s = 'calculateNodeForces'; + // logDebug(s); + for (var i = 0; i < layoutInfo.graphSet.length; i++) { + var graph = layoutInfo.graphSet[i]; + var numNodes = graph.length; + + // s = "Set: " + graph.toString(); + // logDebug(s); + + // Now get all the pairs of nodes + // Only get each pair once, (A, B) = (B, A) + for (var j = 0; j < numNodes; j++) { + var node1 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]]; + for (var k = j + 1; k < numNodes; k++) { + var node2 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[k]]]; + nodeRepulsion(node1, node2, layoutInfo, options); + } + } + } +}; +var randomDistance = function randomDistance(max) { + return -max + 2 * max * Math.random(); +}; + +/** + * @brief : Compute the node repulsion forces between a pair of nodes + */ +var nodeRepulsion = function nodeRepulsion(node1, node2, layoutInfo, options) { + // var s = "Node repulsion. Node1: " + node1.id + " Node2: " + node2.id; + + var cmptId1 = node1.cmptId; + var cmptId2 = node2.cmptId; + if (cmptId1 !== cmptId2 && !layoutInfo.isCompound) { + return; + } + + // Get direction of line connecting both node centers + var directionX = node2.positionX - node1.positionX; + var directionY = node2.positionY - node1.positionY; + var maxRandDist = 1; + // s += "\ndirectionX: " + directionX + ", directionY: " + directionY; + + // If both centers are the same, apply a random force + if (0 === directionX && 0 === directionY) { + directionX = randomDistance(maxRandDist); + directionY = randomDistance(maxRandDist); + } + var overlap = nodesOverlap(node1, node2, directionX, directionY); + if (overlap > 0) { + // s += "\nNodes DO overlap."; + // s += "\nOverlap: " + overlap; + // If nodes overlap, repulsion force is proportional + // to the overlap + var force = options.nodeOverlap * overlap; + + // Compute the module and components of the force vector + var distance = Math.sqrt(directionX * directionX + directionY * directionY); + // s += "\nDistance: " + distance; + var forceX = force * directionX / distance; + var forceY = force * directionY / distance; + } else { + // s += "\nNodes do NOT overlap."; + // If there's no overlap, force is inversely proportional + // to squared distance + + // Get clipping points for both nodes + var point1 = findClippingPoint(node1, directionX, directionY); + var point2 = findClippingPoint(node2, -1 * directionX, -1 * directionY); + + // Use clipping points to compute distance + var distanceX = point2.x - point1.x; + var distanceY = point2.y - point1.y; + var distanceSqr = distanceX * distanceX + distanceY * distanceY; + var distance = Math.sqrt(distanceSqr); + // s += "\nDistance: " + distance; + + // Compute the module and components of the force vector + var force = (node1.nodeRepulsion + node2.nodeRepulsion) / distanceSqr; + var forceX = force * distanceX / distance; + var forceY = force * distanceY / distance; + } + + // Apply force + if (!node1.isLocked) { + node1.offsetX -= forceX; + node1.offsetY -= forceY; + } + if (!node2.isLocked) { + node2.offsetX += forceX; + node2.offsetY += forceY; + } + + // s += "\nForceX: " + forceX + " ForceY: " + forceY; + // logDebug(s); + + return; +}; + +/** + * @brief : Determines whether two nodes overlap or not + * @return : Amount of overlapping (0 => no overlap) + */ +var nodesOverlap = function nodesOverlap(node1, node2, dX, dY) { + if (dX > 0) { + var overlapX = node1.maxX - node2.minX; + } else { + var overlapX = node2.maxX - node1.minX; + } + if (dY > 0) { + var overlapY = node1.maxY - node2.minY; + } else { + var overlapY = node2.maxY - node1.minY; + } + if (overlapX >= 0 && overlapY >= 0) { + return Math.sqrt(overlapX * overlapX + overlapY * overlapY); + } else { + return 0; + } +}; + +/** + * @brief : Finds the point in which an edge (direction dX, dY) intersects + * the rectangular bounding box of it's source/target node + */ +var findClippingPoint = function findClippingPoint(node, dX, dY) { + // Shorcuts + var X = node.positionX; + var Y = node.positionY; + var H = node.height || 1; + var W = node.width || 1; + var dirSlope = dY / dX; + var nodeSlope = H / W; + + // var s = 'Computing clipping point of node ' + node.id + + // " . Height: " + H + ", Width: " + W + + // "\nDirection " + dX + ", " + dY; + // + // Compute intersection + var res = {}; + + // Case: Vertical direction (up) + if (0 === dX && 0 < dY) { + res.x = X; + // s += "\nUp direction"; + res.y = Y + H / 2; + return res; + } + + // Case: Vertical direction (down) + if (0 === dX && 0 > dY) { + res.x = X; + res.y = Y + H / 2; + // s += "\nDown direction"; + + return res; + } + + // Case: Intersects the right border + if (0 < dX && -1 * nodeSlope <= dirSlope && dirSlope <= nodeSlope) { + res.x = X + W / 2; + res.y = Y + W * dY / 2 / dX; + // s += "\nRightborder"; + + return res; + } + + // Case: Intersects the left border + if (0 > dX && -1 * nodeSlope <= dirSlope && dirSlope <= nodeSlope) { + res.x = X - W / 2; + res.y = Y - W * dY / 2 / dX; + // s += "\nLeftborder"; + + return res; + } + + // Case: Intersects the top border + if (0 < dY && (dirSlope <= -1 * nodeSlope || dirSlope >= nodeSlope)) { + res.x = X + H * dX / 2 / dY; + res.y = Y + H / 2; + // s += "\nTop border"; + + return res; + } + + // Case: Intersects the bottom border + if (0 > dY && (dirSlope <= -1 * nodeSlope || dirSlope >= nodeSlope)) { + res.x = X - H * dX / 2 / dY; + res.y = Y - H / 2; + // s += "\nBottom border"; + + return res; + } + + // s += "\nClipping point found at " + res.x + ", " + res.y; + // logDebug(s); + return res; +}; + +/** + * @brief : Calculates all edge forces + */ +var calculateEdgeForces = function calculateEdgeForces(layoutInfo, options) { + // Iterate over all edges + for (var i = 0; i < layoutInfo.edgeSize; i++) { + // Get edge, source & target nodes + var edge = layoutInfo.layoutEdges[i]; + var sourceIx = layoutInfo.idToIndex[edge.sourceId]; + var source = layoutInfo.layoutNodes[sourceIx]; + var targetIx = layoutInfo.idToIndex[edge.targetId]; + var target = layoutInfo.layoutNodes[targetIx]; + + // Get direction of line connecting both node centers + var directionX = target.positionX - source.positionX; + var directionY = target.positionY - source.positionY; + + // If both centers are the same, do nothing. + // A random force has already been applied as node repulsion + if (0 === directionX && 0 === directionY) { + continue; + } + + // Get clipping points for both nodes + var point1 = findClippingPoint(source, directionX, directionY); + var point2 = findClippingPoint(target, -1 * directionX, -1 * directionY); + var lx = point2.x - point1.x; + var ly = point2.y - point1.y; + var l = Math.sqrt(lx * lx + ly * ly); + var force = Math.pow(edge.idealLength - l, 2) / edge.elasticity; + if (0 !== l) { + var forceX = force * lx / l; + var forceY = force * ly / l; + } else { + var forceX = 0; + var forceY = 0; + } + + // Add this force to target and source nodes + if (!source.isLocked) { + source.offsetX += forceX; + source.offsetY += forceY; + } + if (!target.isLocked) { + target.offsetX -= forceX; + target.offsetY -= forceY; + } + + // var s = 'Edge force between nodes ' + source.id + ' and ' + target.id; + // s += "\nDistance: " + l + " Force: (" + forceX + ", " + forceY + ")"; + // logDebug(s); + } +}; + +/** + * @brief : Computes gravity forces for all nodes + */ +var calculateGravityForces = function calculateGravityForces(layoutInfo, options) { + if (options.gravity === 0) { + return; + } + var distThreshold = 1; + + // var s = 'calculateGravityForces'; + // logDebug(s); + for (var i = 0; i < layoutInfo.graphSet.length; i++) { + var graph = layoutInfo.graphSet[i]; + var numNodes = graph.length; + + // s = "Set: " + graph.toString(); + // logDebug(s); + + // Compute graph center + if (0 === i) { + var centerX = layoutInfo.clientHeight / 2; + var centerY = layoutInfo.clientWidth / 2; + } else { + // Get Parent node for this graph, and use its position as center + var temp = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[0]]]; + var parent = layoutInfo.layoutNodes[layoutInfo.idToIndex[temp.parentId]]; + var centerX = parent.positionX; + var centerY = parent.positionY; + } + // s = "Center found at: " + centerX + ", " + centerY; + // logDebug(s); + + // Apply force to all nodes in graph + for (var j = 0; j < numNodes; j++) { + var node = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]]; + // s = "Node: " + node.id; + + if (node.isLocked) { + continue; + } + var dx = centerX - node.positionX; + var dy = centerY - node.positionY; + var d = Math.sqrt(dx * dx + dy * dy); + if (d > distThreshold) { + var fx = options.gravity * dx / d; + var fy = options.gravity * dy / d; + node.offsetX += fx; + node.offsetY += fy; + // s += ": Applied force: " + fx + ", " + fy; + } + // logDebug(s); + } + } +}; + +/** + * @brief : This function propagates the existing offsets from + * parent nodes to its descendents. + * @arg layoutInfo : layoutInfo Object + * @arg cy : cytoscape Object + * @arg options : Layout options + */ +var propagateForces = function propagateForces(layoutInfo, options) { + // Inline implementation of a queue, used for traversing the graph in BFS order + var queue = []; + var start = 0; // Points to the start the queue + var end = -1; // Points to the end of the queue + + // logDebug('propagateForces'); + + // Start by visiting the nodes in the root graph + queue.push.apply(queue, layoutInfo.graphSet[0]); + end += layoutInfo.graphSet[0].length; + + // Traverse the graph, level by level, + while (start <= end) { + // Get the node to visit and remove it from queue + var nodeId = queue[start++]; + var nodeIndex = layoutInfo.idToIndex[nodeId]; + var node = layoutInfo.layoutNodes[nodeIndex]; + var children = node.children; + + // We only need to process the node if it's compound + if (0 < children.length && !node.isLocked) { + var offX = node.offsetX; + var offY = node.offsetY; + + // var s = "Propagating offset from parent node : " + node.id + + // ". OffsetX: " + offX + ". OffsetY: " + offY; + // s += "\n Children: " + children.toString(); + // logDebug(s); + + for (var i = 0; i < children.length; i++) { + var childNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[children[i]]]; + // Propagate offset + childNode.offsetX += offX; + childNode.offsetY += offY; + // Add children to queue to be visited + queue[++end] = children[i]; + } + + // Reset parent offsets + node.offsetX = 0; + node.offsetY = 0; + } + } +}; + +/** + * @brief : Updates the layout model positions, based on + * the accumulated forces + */ +var updatePositions = function updatePositions(layoutInfo, options) { + // var s = 'Updating positions'; + // logDebug(s); + + // Reset boundaries for compound nodes + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = layoutInfo.layoutNodes[i]; + if (0 < n.children.length) { + // logDebug("Resetting boundaries of compound node: " + n.id); + n.maxX = undefined; + n.minX = undefined; + n.maxY = undefined; + n.minY = undefined; + } + } + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = layoutInfo.layoutNodes[i]; + if (0 < n.children.length || n.isLocked) { + // No need to set compound or locked node position + // logDebug("Skipping position update of node: " + n.id); + continue; + } + // s = "Node: " + n.id + " Previous position: (" + + // n.positionX + ", " + n.positionY + ")."; + + // Limit displacement in order to improve stability + var tempForce = limitForce(n.offsetX, n.offsetY, layoutInfo.temperature); + n.positionX += tempForce.x; + n.positionY += tempForce.y; + n.offsetX = 0; + n.offsetY = 0; + n.minX = n.positionX - n.width; + n.maxX = n.positionX + n.width; + n.minY = n.positionY - n.height; + n.maxY = n.positionY + n.height; + // s += " New Position: (" + n.positionX + ", " + n.positionY + ")."; + // logDebug(s); + + // Update ancestry boudaries + updateAncestryBoundaries(n, layoutInfo); + } + + // Update size, position of compund nodes + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = layoutInfo.layoutNodes[i]; + if (0 < n.children.length && !n.isLocked) { + n.positionX = (n.maxX + n.minX) / 2; + n.positionY = (n.maxY + n.minY) / 2; + n.width = n.maxX - n.minX; + n.height = n.maxY - n.minY; + // s = "Updating position, size of compound node " + n.id; + // s += "\nPositionX: " + n.positionX + ", PositionY: " + n.positionY; + // s += "\nWidth: " + n.width + ", Height: " + n.height; + // logDebug(s); + } + } +}; + +/** + * @brief : Limits a force (forceX, forceY) to be not + * greater (in modulo) than max. + 8 Preserves force direction. + */ +var limitForce = function limitForce(forceX, forceY, max) { + // var s = "Limiting force: (" + forceX + ", " + forceY + "). Max: " + max; + var force = Math.sqrt(forceX * forceX + forceY * forceY); + if (force > max) { + var res = { + x: max * forceX / force, + y: max * forceY / force + }; + } else { + var res = { + x: forceX, + y: forceY + }; + } + + // s += ".\nResult: (" + res.x + ", " + res.y + ")"; + // logDebug(s); + + return res; +}; + +/** + * @brief : Function used for keeping track of compound node + * sizes, since they should bound all their subnodes. + */ +var updateAncestryBoundaries = function updateAncestryBoundaries(node, layoutInfo) { + // var s = "Propagating new position/size of node " + node.id; + var parentId = node.parentId; + if (null == parentId) { + // If there's no parent, we are done + // s += ". No parent node."; + // logDebug(s); + return; + } + + // Get Parent Node + var p = layoutInfo.layoutNodes[layoutInfo.idToIndex[parentId]]; + var flag = false; + + // MaxX + if (null == p.maxX || node.maxX + p.padRight > p.maxX) { + p.maxX = node.maxX + p.padRight; + flag = true; + // s += "\nNew maxX for parent node " + p.id + ": " + p.maxX; + } + + // MinX + if (null == p.minX || node.minX - p.padLeft < p.minX) { + p.minX = node.minX - p.padLeft; + flag = true; + // s += "\nNew minX for parent node " + p.id + ": " + p.minX; + } + + // MaxY + if (null == p.maxY || node.maxY + p.padBottom > p.maxY) { + p.maxY = node.maxY + p.padBottom; + flag = true; + // s += "\nNew maxY for parent node " + p.id + ": " + p.maxY; + } + + // MinY + if (null == p.minY || node.minY - p.padTop < p.minY) { + p.minY = node.minY - p.padTop; + flag = true; + // s += "\nNew minY for parent node " + p.id + ": " + p.minY; + } + + // If updated boundaries, propagate changes upward + if (flag) { + // logDebug(s); + return updateAncestryBoundaries(p, layoutInfo); + } + + // s += ". No changes in boundaries/position of parent node " + p.id; + // logDebug(s); + return; +}; +var separateComponents = function separateComponents(layoutInfo, options) { + var nodes = layoutInfo.layoutNodes; + var components = []; + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var cid = node.cmptId; + var component = components[cid] = components[cid] || []; + component.push(node); + } + var totalA = 0; + for (var i = 0; i < components.length; i++) { + var c = components[i]; + if (!c) { + continue; + } + c.x1 = Infinity; + c.x2 = -Infinity; + c.y1 = Infinity; + c.y2 = -Infinity; + for (var j = 0; j < c.length; j++) { + var n = c[j]; + c.x1 = Math.min(c.x1, n.positionX - n.width / 2); + c.x2 = Math.max(c.x2, n.positionX + n.width / 2); + c.y1 = Math.min(c.y1, n.positionY - n.height / 2); + c.y2 = Math.max(c.y2, n.positionY + n.height / 2); + } + c.w = c.x2 - c.x1; + c.h = c.y2 - c.y1; + totalA += c.w * c.h; + } + components.sort(function (c1, c2) { + return c2.w * c2.h - c1.w * c1.h; + }); + var x = 0; + var y = 0; + var usedW = 0; + var rowH = 0; + var maxRowW = Math.sqrt(totalA) * layoutInfo.clientWidth / layoutInfo.clientHeight; + for (var i = 0; i < components.length; i++) { + var c = components[i]; + if (!c) { + continue; + } + for (var j = 0; j < c.length; j++) { + var n = c[j]; + if (!n.isLocked) { + n.positionX += x - c.x1; + n.positionY += y - c.y1; + } + } + x += c.w + options.componentSpacing; + usedW += c.w + options.componentSpacing; + rowH = Math.max(rowH, c.h); + if (usedW > maxRowW) { + y += rowH + options.componentSpacing; + x = 0; + usedW = 0; + rowH = 0; + } + } +}; + +var defaults$3 = { + fit: true, + // whether to fit the viewport to the graph + padding: 30, + // padding used on fit + boundingBox: undefined, + // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } + avoidOverlap: true, + // prevents node overlap, may overflow boundingBox if not enough space + avoidOverlapPadding: 10, + // extra spacing around nodes when avoidOverlap: true + nodeDimensionsIncludeLabels: false, + // Excludes the label when calculating node bounding boxes for the layout algorithm + spacingFactor: undefined, + // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up + condense: false, + // uses all available space on false, uses minimal space on true + rows: undefined, + // force num of rows in the grid + cols: undefined, + // force num of columns in the grid + position: function position(node) {}, + // returns { row, col } for element + sort: undefined, + // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') } + animate: false, + // whether to transition the node positions + animationDuration: 500, + // duration of animation in ms if enabled + animationEasing: undefined, + // easing of animation if enabled + animateFilter: function animateFilter(node, i) { + return true; + }, + // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts + ready: undefined, + // callback on layoutready + stop: undefined, + // callback on layoutstop + transform: function transform(node, position) { + return position; + } // transform a given node position. Useful for changing flow direction in discrete layouts +}; + +function GridLayout(options) { + this.options = extend({}, defaults$3, options); +} +GridLayout.prototype.run = function () { + var params = this.options; + var options = params; + var cy = params.cy; + var eles = options.eles; + var nodes = eles.nodes().not(':parent'); + if (options.sort) { + nodes = nodes.sort(options.sort); + } + var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : { + x1: 0, + y1: 0, + w: cy.width(), + h: cy.height() + }); + if (bb.h === 0 || bb.w === 0) { + eles.nodes().layoutPositions(this, options, function (ele) { + return { + x: bb.x1, + y: bb.y1 + }; + }); + } else { + // width/height * splits^2 = cells where splits is number of times to split width + var cells = nodes.size(); + var splits = Math.sqrt(cells * bb.h / bb.w); + var rows = Math.round(splits); + var cols = Math.round(bb.w / bb.h * splits); + var small = function small(val) { + if (val == null) { + return Math.min(rows, cols); + } else { + var min = Math.min(rows, cols); + if (min == rows) { + rows = val; + } else { + cols = val; + } + } + }; + var large = function large(val) { + if (val == null) { + return Math.max(rows, cols); + } else { + var max = Math.max(rows, cols); + if (max == rows) { + rows = val; + } else { + cols = val; + } + } + }; + var oRows = options.rows; + var oCols = options.cols != null ? options.cols : options.columns; + + // if rows or columns were set in options, use those values + if (oRows != null && oCols != null) { + rows = oRows; + cols = oCols; + } else if (oRows != null && oCols == null) { + rows = oRows; + cols = Math.ceil(cells / rows); + } else if (oRows == null && oCols != null) { + cols = oCols; + rows = Math.ceil(cells / cols); + } + + // otherwise use the automatic values and adjust accordingly + + // if rounding was up, see if we can reduce rows or columns + else if (cols * rows > cells) { + var sm = small(); + var lg = large(); + + // reducing the small side takes away the most cells, so try it first + if ((sm - 1) * lg >= cells) { + small(sm - 1); + } else if ((lg - 1) * sm >= cells) { + large(lg - 1); + } + } else { + // if rounding was too low, add rows or columns + while (cols * rows < cells) { + var _sm = small(); + var _lg = large(); + + // try to add to larger side first (adds less in multiplication) + if ((_lg + 1) * _sm >= cells) { + large(_lg + 1); + } else { + small(_sm + 1); + } + } + } + var cellWidth = bb.w / cols; + var cellHeight = bb.h / rows; + if (options.condense) { + cellWidth = 0; + cellHeight = 0; + } + if (options.avoidOverlap) { + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var pos = node._private.position; + if (pos.x == null || pos.y == null) { + // for bb + pos.x = 0; + pos.y = 0; + } + var nbb = node.layoutDimensions(options); + var p = options.avoidOverlapPadding; + var w = nbb.w + p; + var h = nbb.h + p; + cellWidth = Math.max(cellWidth, w); + cellHeight = Math.max(cellHeight, h); + } + } + var cellUsed = {}; // e.g. 'c-0-2' => true + + var used = function used(row, col) { + return cellUsed['c-' + row + '-' + col] ? true : false; + }; + var use = function use(row, col) { + cellUsed['c-' + row + '-' + col] = true; + }; + + // to keep track of current cell position + var row = 0; + var col = 0; + var moveToNextCell = function moveToNextCell() { + col++; + if (col >= cols) { + col = 0; + row++; + } + }; + + // get a cache of all the manual positions + var id2manPos = {}; + for (var _i = 0; _i < nodes.length; _i++) { + var _node = nodes[_i]; + var rcPos = options.position(_node); + if (rcPos && (rcPos.row !== undefined || rcPos.col !== undefined)) { + // must have at least row or col def'd + var _pos = { + row: rcPos.row, + col: rcPos.col + }; + if (_pos.col === undefined) { + // find unused col + _pos.col = 0; + while (used(_pos.row, _pos.col)) { + _pos.col++; + } + } else if (_pos.row === undefined) { + // find unused row + _pos.row = 0; + while (used(_pos.row, _pos.col)) { + _pos.row++; + } + } + id2manPos[_node.id()] = _pos; + use(_pos.row, _pos.col); + } + } + var getPos = function getPos(element, i) { + var x, y; + if (element.locked() || element.isParent()) { + return false; + } + + // see if we have a manual position set + var rcPos = id2manPos[element.id()]; + if (rcPos) { + x = rcPos.col * cellWidth + cellWidth / 2 + bb.x1; + y = rcPos.row * cellHeight + cellHeight / 2 + bb.y1; + } else { + // otherwise set automatically + + while (used(row, col)) { + moveToNextCell(); + } + x = col * cellWidth + cellWidth / 2 + bb.x1; + y = row * cellHeight + cellHeight / 2 + bb.y1; + use(row, col); + moveToNextCell(); + } + return { + x: x, + y: y + }; + }; + nodes.layoutPositions(this, options, getPos); + } + return this; // chaining +}; + +// default layout options +var defaults$2 = { + ready: function ready() {}, + // on layoutready + stop: function stop() {} // on layoutstop +}; + +// constructor +// options : object containing layout options +function NullLayout(options) { + this.options = extend({}, defaults$2, options); +} + +// runs the layout +NullLayout.prototype.run = function () { + var options = this.options; + var eles = options.eles; // elements to consider in the layout + var layout = this; + + // cy is automatically populated for us in the constructor + // (disable eslint for next line as this serves as example layout code to external developers) + // eslint-disable-next-line no-unused-vars + options.cy; + layout.emit('layoutstart'); + + // puts all nodes at (0, 0) + // n.b. most layouts would use layoutPositions(), instead of positions() and manual events + eles.nodes().positions(function () { + return { + x: 0, + y: 0 + }; + }); + + // trigger layoutready when each node has had its position set at least once + layout.one('layoutready', options.ready); + layout.emit('layoutready'); + + // trigger layoutstop when the layout stops (e.g. finishes) + layout.one('layoutstop', options.stop); + layout.emit('layoutstop'); + return this; // chaining +}; + +// called on continuous layouts to stop them before they finish +NullLayout.prototype.stop = function () { + return this; // chaining +}; + +var defaults$1 = { + positions: undefined, + // map of (node id) => (position obj); or function(node){ return somPos; } + zoom: undefined, + // the zoom level to set (prob want fit = false if set) + pan: undefined, + // the pan level to set (prob want fit = false if set) + fit: true, + // whether to fit to viewport + padding: 30, + // padding on fit + spacingFactor: undefined, + // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up + animate: false, + // whether to transition the node positions + animationDuration: 500, + // duration of animation in ms if enabled + animationEasing: undefined, + // easing of animation if enabled + animateFilter: function animateFilter(node, i) { + return true; + }, + // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts + ready: undefined, + // callback on layoutready + stop: undefined, + // callback on layoutstop + transform: function transform(node, position) { + return position; + } // transform a given node position. Useful for changing flow direction in discrete layouts +}; + +function PresetLayout(options) { + this.options = extend({}, defaults$1, options); +} +PresetLayout.prototype.run = function () { + var options = this.options; + var eles = options.eles; + var nodes = eles.nodes(); + var posIsFn = fn$6(options.positions); + function getPosition(node) { + if (options.positions == null) { + return copyPosition(node.position()); + } + if (posIsFn) { + return options.positions(node); + } + var pos = options.positions[node._private.data.id]; + if (pos == null) { + return null; + } + return pos; + } + nodes.layoutPositions(this, options, function (node, i) { + var position = getPosition(node); + if (node.locked() || position == null) { + return false; + } + return position; + }); + return this; // chaining +}; + +var defaults = { + fit: true, + // whether to fit to viewport + padding: 30, + // fit padding + boundingBox: undefined, + // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } + animate: false, + // whether to transition the node positions + animationDuration: 500, + // duration of animation in ms if enabled + animationEasing: undefined, + // easing of animation if enabled + animateFilter: function animateFilter(node, i) { + return true; + }, + // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts + ready: undefined, + // callback on layoutready + stop: undefined, + // callback on layoutstop + transform: function transform(node, position) { + return position; + } // transform a given node position. Useful for changing flow direction in discrete layouts +}; + +function RandomLayout(options) { + this.options = extend({}, defaults, options); +} +RandomLayout.prototype.run = function () { + var options = this.options; + var cy = options.cy; + var eles = options.eles; + var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : { + x1: 0, + y1: 0, + w: cy.width(), + h: cy.height() + }); + var getPos = function getPos(node, i) { + return { + x: bb.x1 + Math.round(Math.random() * bb.w), + y: bb.y1 + Math.round(Math.random() * bb.h) + }; + }; + eles.nodes().layoutPositions(this, options, getPos); + return this; // chaining +}; + +var layout = [{ + name: 'breadthfirst', + impl: BreadthFirstLayout +}, { + name: 'circle', + impl: CircleLayout +}, { + name: 'concentric', + impl: ConcentricLayout +}, { + name: 'cose', + impl: CoseLayout +}, { + name: 'grid', + impl: GridLayout +}, { + name: 'null', + impl: NullLayout +}, { + name: 'preset', + impl: PresetLayout +}, { + name: 'random', + impl: RandomLayout +}]; + +function NullRenderer(options) { + this.options = options; + this.notifications = 0; // for testing +} + +var noop = function noop() {}; +var throwImgErr = function throwImgErr() { + throw new Error('A headless instance can not render images'); +}; +NullRenderer.prototype = { + recalculateRenderedStyle: noop, + notify: function notify() { + this.notifications++; + }, + init: noop, + isHeadless: function isHeadless() { + return true; + }, + png: throwImgErr, + jpg: throwImgErr +}; + +var BRp$f = {}; +BRp$f.arrowShapeWidth = 0.3; +BRp$f.registerArrowShapes = function () { + var arrowShapes = this.arrowShapes = {}; + var renderer = this; + + // Contract for arrow shapes: + // 0, 0 is arrow tip + // (0, 1) is direction towards node + // (1, 0) is right + // + // functional api: + // collide: check x, y in shape + // roughCollide: called before collide, no false negatives + // draw: draw + // spacing: dist(arrowTip, nodeBoundary) + // gap: dist(edgeTip, nodeBoundary), edgeTip may != arrowTip + + var bbCollide = function bbCollide(x, y, size, angle, translation, edgeWidth, padding) { + var x1 = translation.x - size / 2 - padding; + var x2 = translation.x + size / 2 + padding; + var y1 = translation.y - size / 2 - padding; + var y2 = translation.y + size / 2 + padding; + var inside = x1 <= x && x <= x2 && y1 <= y && y <= y2; + return inside; + }; + var transform = function transform(x, y, size, angle, translation) { + var xRotated = x * Math.cos(angle) - y * Math.sin(angle); + var yRotated = x * Math.sin(angle) + y * Math.cos(angle); + var xScaled = xRotated * size; + var yScaled = yRotated * size; + var xTranslated = xScaled + translation.x; + var yTranslated = yScaled + translation.y; + return { + x: xTranslated, + y: yTranslated + }; + }; + var transformPoints = function transformPoints(pts, size, angle, translation) { + var retPts = []; + for (var i = 0; i < pts.length; i += 2) { + var x = pts[i]; + var y = pts[i + 1]; + retPts.push(transform(x, y, size, angle, translation)); + } + return retPts; + }; + var pointsToArr = function pointsToArr(pts) { + var ret = []; + for (var i = 0; i < pts.length; i++) { + var p = pts[i]; + ret.push(p.x, p.y); + } + return ret; + }; + var standardGap = function standardGap(edge) { + return edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').pfValue * 2; + }; + var defineArrowShape = function defineArrowShape(name, defn) { + if (string(defn)) { + defn = arrowShapes[defn]; + } + arrowShapes[name] = extend({ + name: name, + points: [-0.15, -0.3, 0.15, -0.3, 0.15, 0.3, -0.15, 0.3], + collide: function collide(x, y, size, angle, translation, padding) { + var points = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation)); + var inside = pointInsidePolygonPoints(x, y, points); + return inside; + }, + roughCollide: bbCollide, + draw: function draw(context, size, angle, translation) { + var points = transformPoints(this.points, size, angle, translation); + renderer.arrowShapeImpl('polygon')(context, points); + }, + spacing: function spacing(edge) { + return 0; + }, + gap: standardGap + }, defn); + }; + defineArrowShape('none', { + collide: falsify, + roughCollide: falsify, + draw: noop$1, + spacing: zeroify, + gap: zeroify + }); + defineArrowShape('triangle', { + points: [-0.15, -0.3, 0, 0, 0.15, -0.3] + }); + defineArrowShape('arrow', 'triangle'); + defineArrowShape('triangle-backcurve', { + points: arrowShapes['triangle'].points, + controlPoint: [0, -0.15], + roughCollide: bbCollide, + draw: function draw(context, size, angle, translation, edgeWidth) { + var ptsTrans = transformPoints(this.points, size, angle, translation); + var ctrlPt = this.controlPoint; + var ctrlPtTrans = transform(ctrlPt[0], ctrlPt[1], size, angle, translation); + renderer.arrowShapeImpl(this.name)(context, ptsTrans, ctrlPtTrans); + }, + gap: function gap(edge) { + return standardGap(edge) * 0.8; + } + }); + defineArrowShape('triangle-tee', { + points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0], + pointsTee: [-0.15, -0.4, -0.15, -0.5, 0.15, -0.5, 0.15, -0.4], + collide: function collide(x, y, size, angle, translation, edgeWidth, padding) { + var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation)); + var teePts = pointsToArr(transformPoints(this.pointsTee, size + 2 * padding, angle, translation)); + var inside = pointInsidePolygonPoints(x, y, triPts) || pointInsidePolygonPoints(x, y, teePts); + return inside; + }, + draw: function draw(context, size, angle, translation, edgeWidth) { + var triPts = transformPoints(this.points, size, angle, translation); + var teePts = transformPoints(this.pointsTee, size, angle, translation); + renderer.arrowShapeImpl(this.name)(context, triPts, teePts); + } + }); + defineArrowShape('circle-triangle', { + radius: 0.15, + pointsTr: [0, -0.15, 0.15, -0.45, -0.15, -0.45, 0, -0.15], + collide: function collide(x, y, size, angle, translation, edgeWidth, padding) { + var t = translation; + var circleInside = Math.pow(t.x - x, 2) + Math.pow(t.y - y, 2) <= Math.pow((size + 2 * padding) * this.radius, 2); + var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation)); + return pointInsidePolygonPoints(x, y, triPts) || circleInside; + }, + draw: function draw(context, size, angle, translation, edgeWidth) { + var triPts = transformPoints(this.pointsTr, size, angle, translation); + renderer.arrowShapeImpl(this.name)(context, triPts, translation.x, translation.y, this.radius * size); + }, + spacing: function spacing(edge) { + return renderer.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.radius; + } + }); + defineArrowShape('triangle-cross', { + points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0], + baseCrossLinePts: [-0.15, -0.4, + // first half of the rectangle + -0.15, -0.4, 0.15, -0.4, + // second half of the rectangle + 0.15, -0.4], + crossLinePts: function crossLinePts(size, edgeWidth) { + // shift points so that the distance between the cross points matches edge width + var p = this.baseCrossLinePts.slice(); + var shiftFactor = edgeWidth / size; + var y0 = 3; + var y1 = 5; + p[y0] = p[y0] - shiftFactor; + p[y1] = p[y1] - shiftFactor; + return p; + }, + collide: function collide(x, y, size, angle, translation, edgeWidth, padding) { + var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation)); + var teePts = pointsToArr(transformPoints(this.crossLinePts(size, edgeWidth), size + 2 * padding, angle, translation)); + var inside = pointInsidePolygonPoints(x, y, triPts) || pointInsidePolygonPoints(x, y, teePts); + return inside; + }, + draw: function draw(context, size, angle, translation, edgeWidth) { + var triPts = transformPoints(this.points, size, angle, translation); + var crossLinePts = transformPoints(this.crossLinePts(size, edgeWidth), size, angle, translation); + renderer.arrowShapeImpl(this.name)(context, triPts, crossLinePts); + } + }); + defineArrowShape('vee', { + points: [-0.15, -0.3, 0, 0, 0.15, -0.3, 0, -0.15], + gap: function gap(edge) { + return standardGap(edge) * 0.525; + } + }); + defineArrowShape('circle', { + radius: 0.15, + collide: function collide(x, y, size, angle, translation, edgeWidth, padding) { + var t = translation; + var inside = Math.pow(t.x - x, 2) + Math.pow(t.y - y, 2) <= Math.pow((size + 2 * padding) * this.radius, 2); + return inside; + }, + draw: function draw(context, size, angle, translation, edgeWidth) { + renderer.arrowShapeImpl(this.name)(context, translation.x, translation.y, this.radius * size); + }, + spacing: function spacing(edge) { + return renderer.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.radius; + } + }); + defineArrowShape('tee', { + points: [-0.15, 0, -0.15, -0.1, 0.15, -0.1, 0.15, 0], + spacing: function spacing(edge) { + return 1; + }, + gap: function gap(edge) { + return 1; + } + }); + defineArrowShape('square', { + points: [-0.15, 0.00, 0.15, 0.00, 0.15, -0.3, -0.15, -0.3] + }); + defineArrowShape('diamond', { + points: [-0.15, -0.15, 0, -0.3, 0.15, -0.15, 0, 0], + gap: function gap(edge) { + return edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').value; + } + }); + defineArrowShape('chevron', { + points: [0, 0, -0.15, -0.15, -0.1, -0.2, 0, -0.1, 0.1, -0.2, 0.15, -0.15], + gap: function gap(edge) { + return 0.95 * edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').value; + } + }); +}; + +var BRp$e = {}; + +// Project mouse +BRp$e.projectIntoViewport = function (clientX, clientY) { + var cy = this.cy; + var offsets = this.findContainerClientCoords(); + var offsetLeft = offsets[0]; + var offsetTop = offsets[1]; + var scale = offsets[4]; + var pan = cy.pan(); + var zoom = cy.zoom(); + var x = ((clientX - offsetLeft) / scale - pan.x) / zoom; + var y = ((clientY - offsetTop) / scale - pan.y) / zoom; + return [x, y]; +}; +BRp$e.findContainerClientCoords = function () { + if (this.containerBB) { + return this.containerBB; + } + var container = this.container; + var rect = container.getBoundingClientRect(); + var style = this.cy.window().getComputedStyle(container); + var styleValue = function styleValue(name) { + return parseFloat(style.getPropertyValue(name)); + }; + var padding = { + left: styleValue('padding-left'), + right: styleValue('padding-right'), + top: styleValue('padding-top'), + bottom: styleValue('padding-bottom') + }; + var border = { + left: styleValue('border-left-width'), + right: styleValue('border-right-width'), + top: styleValue('border-top-width'), + bottom: styleValue('border-bottom-width') + }; + var clientWidth = container.clientWidth; + var clientHeight = container.clientHeight; + var paddingHor = padding.left + padding.right; + var paddingVer = padding.top + padding.bottom; + var borderHor = border.left + border.right; + var scale = rect.width / (clientWidth + borderHor); + var unscaledW = clientWidth - paddingHor; + var unscaledH = clientHeight - paddingVer; + var left = rect.left + padding.left + border.left; + var top = rect.top + padding.top + border.top; + return this.containerBB = [left, top, unscaledW, unscaledH, scale]; +}; +BRp$e.invalidateContainerClientCoordsCache = function () { + this.containerBB = null; +}; +BRp$e.findNearestElement = function (x, y, interactiveElementsOnly, isTouch) { + return this.findNearestElements(x, y, interactiveElementsOnly, isTouch)[0]; +}; +BRp$e.findNearestElements = function (x, y, interactiveElementsOnly, isTouch) { + var self = this; + var r = this; + var eles = r.getCachedZSortedEles(); + var near = []; // 1 node max, 1 edge max + var zoom = r.cy.zoom(); + var hasCompounds = r.cy.hasCompoundNodes(); + var edgeThreshold = (isTouch ? 24 : 8) / zoom; + var nodeThreshold = (isTouch ? 8 : 2) / zoom; + var labelThreshold = (isTouch ? 8 : 2) / zoom; + var minSqDist = Infinity; + var nearEdge; + var nearNode; + if (interactiveElementsOnly) { + eles = eles.interactive; + } + function addEle(ele, sqDist) { + if (ele.isNode()) { + if (nearNode) { + return; // can't replace node + } else { + nearNode = ele; + near.push(ele); + } + } + if (ele.isEdge() && (sqDist == null || sqDist < minSqDist)) { + if (nearEdge) { + // then replace existing edge + // can replace only if same z-index + if (nearEdge.pstyle('z-compound-depth').value === ele.pstyle('z-compound-depth').value && nearEdge.pstyle('z-compound-depth').value === ele.pstyle('z-compound-depth').value) { + for (var i = 0; i < near.length; i++) { + if (near[i].isEdge()) { + near[i] = ele; + nearEdge = ele; + minSqDist = sqDist != null ? sqDist : minSqDist; + break; + } + } + } + } else { + near.push(ele); + nearEdge = ele; + minSqDist = sqDist != null ? sqDist : minSqDist; + } + } + } + function checkNode(node) { + var width = node.outerWidth() + 2 * nodeThreshold; + var height = node.outerHeight() + 2 * nodeThreshold; + var hw = width / 2; + var hh = height / 2; + var pos = node.position(); + if (pos.x - hw <= x && x <= pos.x + hw // bb check x + && pos.y - hh <= y && y <= pos.y + hh // bb check y + ) { + var shape = r.nodeShapes[self.getNodeShape(node)]; + if (shape.checkPoint(x, y, 0, width, height, pos.x, pos.y)) { + addEle(node, 0); + return true; + } + } + } + function checkEdge(edge) { + var _p = edge._private; + var rs = _p.rscratch; + var styleWidth = edge.pstyle('width').pfValue; + var scale = edge.pstyle('arrow-scale').value; + var width = styleWidth / 2 + edgeThreshold; // more like a distance radius from centre + var widthSq = width * width; + var width2 = width * 2; + var src = _p.source; + var tgt = _p.target; + var sqDist; + if (rs.edgeType === 'segments' || rs.edgeType === 'straight' || rs.edgeType === 'haystack') { + var pts = rs.allpts; + for (var i = 0; i + 3 < pts.length; i += 2) { + if (inLineVicinity(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], width2) && widthSq > (sqDist = sqdistToFiniteLine(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3]))) { + addEle(edge, sqDist); + return true; + } + } + } else if (rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound') { + var pts = rs.allpts; + for (var i = 0; i + 5 < rs.allpts.length; i += 4) { + if (inBezierVicinity(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5], width2) && widthSq > (sqDist = sqdistToQuadraticBezier(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5]))) { + addEle(edge, sqDist); + return true; + } + } + } + + // if we're close to the edge but didn't hit it, maybe we hit its arrows + + var src = src || _p.source; + var tgt = tgt || _p.target; + var arSize = self.getArrowWidth(styleWidth, scale); + var arrows = [{ + name: 'source', + x: rs.arrowStartX, + y: rs.arrowStartY, + angle: rs.srcArrowAngle + }, { + name: 'target', + x: rs.arrowEndX, + y: rs.arrowEndY, + angle: rs.tgtArrowAngle + }, { + name: 'mid-source', + x: rs.midX, + y: rs.midY, + angle: rs.midsrcArrowAngle + }, { + name: 'mid-target', + x: rs.midX, + y: rs.midY, + angle: rs.midtgtArrowAngle + }]; + for (var i = 0; i < arrows.length; i++) { + var ar = arrows[i]; + var shape = r.arrowShapes[edge.pstyle(ar.name + '-arrow-shape').value]; + var edgeWidth = edge.pstyle('width').pfValue; + if (shape.roughCollide(x, y, arSize, ar.angle, { + x: ar.x, + y: ar.y + }, edgeWidth, edgeThreshold) && shape.collide(x, y, arSize, ar.angle, { + x: ar.x, + y: ar.y + }, edgeWidth, edgeThreshold)) { + addEle(edge); + return true; + } + } + + // for compound graphs, hitting edge may actually want a connected node instead (b/c edge may have greater z-index precedence) + if (hasCompounds && near.length > 0) { + checkNode(src); + checkNode(tgt); + } + } + function preprop(obj, name, pre) { + return getPrefixedProperty(obj, name, pre); + } + function checkLabel(ele, prefix) { + var _p = ele._private; + var th = labelThreshold; + var prefixDash; + if (prefix) { + prefixDash = prefix + '-'; + } else { + prefixDash = ''; + } + ele.boundingBox(); + var bb = _p.labelBounds[prefix || 'main']; + var text = ele.pstyle(prefixDash + 'label').value; + var eventsEnabled = ele.pstyle('text-events').strValue === 'yes'; + if (!eventsEnabled || !text) { + return; + } + var lx = preprop(_p.rscratch, 'labelX', prefix); + var ly = preprop(_p.rscratch, 'labelY', prefix); + var theta = preprop(_p.rscratch, 'labelAngle', prefix); + var ox = ele.pstyle(prefixDash + 'text-margin-x').pfValue; + var oy = ele.pstyle(prefixDash + 'text-margin-y').pfValue; + var lx1 = bb.x1 - th - ox; // (-ox, -oy) as bb already includes margin + var lx2 = bb.x2 + th - ox; // and rotation is about (lx, ly) + var ly1 = bb.y1 - th - oy; + var ly2 = bb.y2 + th - oy; + if (theta) { + var cos = Math.cos(theta); + var sin = Math.sin(theta); + var rotate = function rotate(x, y) { + x = x - lx; + y = y - ly; + return { + x: x * cos - y * sin + lx, + y: x * sin + y * cos + ly + }; + }; + var px1y1 = rotate(lx1, ly1); + var px1y2 = rotate(lx1, ly2); + var px2y1 = rotate(lx2, ly1); + var px2y2 = rotate(lx2, ly2); + var points = [ + // with the margin added after the rotation is applied + px1y1.x + ox, px1y1.y + oy, px2y1.x + ox, px2y1.y + oy, px2y2.x + ox, px2y2.y + oy, px1y2.x + ox, px1y2.y + oy]; + if (pointInsidePolygonPoints(x, y, points)) { + addEle(ele); + return true; + } + } else { + // do a cheaper bb check + if (inBoundingBox(bb, x, y)) { + addEle(ele); + return true; + } + } + } + for (var i = eles.length - 1; i >= 0; i--) { + // reverse order for precedence + var ele = eles[i]; + if (ele.isNode()) { + checkNode(ele) || checkLabel(ele); + } else { + // then edge + checkEdge(ele) || checkLabel(ele) || checkLabel(ele, 'source') || checkLabel(ele, 'target'); + } + } + return near; +}; + +// 'Give me everything from this box' +BRp$e.getAllInBox = function (x1, y1, x2, y2) { + var eles = this.getCachedZSortedEles().interactive; + var box = []; + var x1c = Math.min(x1, x2); + var x2c = Math.max(x1, x2); + var y1c = Math.min(y1, y2); + var y2c = Math.max(y1, y2); + x1 = x1c; + x2 = x2c; + y1 = y1c; + y2 = y2c; + var boxBb = makeBoundingBox({ + x1: x1, + y1: y1, + x2: x2, + y2: y2 + }); + for (var e = 0; e < eles.length; e++) { + var ele = eles[e]; + if (ele.isNode()) { + var node = ele; + var nodeBb = node.boundingBox({ + includeNodes: true, + includeEdges: false, + includeLabels: false + }); + if (boundingBoxesIntersect(boxBb, nodeBb) && !boundingBoxInBoundingBox(nodeBb, boxBb)) { + box.push(node); + } + } else { + var edge = ele; + var _p = edge._private; + var rs = _p.rscratch; + if (rs.startX != null && rs.startY != null && !inBoundingBox(boxBb, rs.startX, rs.startY)) { + continue; + } + if (rs.endX != null && rs.endY != null && !inBoundingBox(boxBb, rs.endX, rs.endY)) { + continue; + } + if (rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound' || rs.edgeType === 'segments' || rs.edgeType === 'haystack') { + var pts = _p.rstyle.bezierPts || _p.rstyle.linePts || _p.rstyle.haystackPts; + var allInside = true; + for (var i = 0; i < pts.length; i++) { + if (!pointInBoundingBox(boxBb, pts[i])) { + allInside = false; + break; + } + } + if (allInside) { + box.push(edge); + } + } else if (rs.edgeType === 'haystack' || rs.edgeType === 'straight') { + box.push(edge); + } + } + } + return box; +}; + +var BRp$d = {}; +BRp$d.calculateArrowAngles = function (edge) { + var rs = edge._private.rscratch; + var isHaystack = rs.edgeType === 'haystack'; + var isBezier = rs.edgeType === 'bezier'; + var isMultibezier = rs.edgeType === 'multibezier'; + var isSegments = rs.edgeType === 'segments'; + var isCompound = rs.edgeType === 'compound'; + var isSelf = rs.edgeType === 'self'; + + // Displacement gives direction for arrowhead orientation + var dispX, dispY; + var startX, startY, endX, endY, midX, midY; + if (isHaystack) { + startX = rs.haystackPts[0]; + startY = rs.haystackPts[1]; + endX = rs.haystackPts[2]; + endY = rs.haystackPts[3]; + } else { + startX = rs.arrowStartX; + startY = rs.arrowStartY; + endX = rs.arrowEndX; + endY = rs.arrowEndY; + } + midX = rs.midX; + midY = rs.midY; + + // source + // + + if (isSegments) { + dispX = startX - rs.segpts[0]; + dispY = startY - rs.segpts[1]; + } else if (isMultibezier || isCompound || isSelf || isBezier) { + var pts = rs.allpts; + var bX = qbezierAt(pts[0], pts[2], pts[4], 0.1); + var bY = qbezierAt(pts[1], pts[3], pts[5], 0.1); + dispX = startX - bX; + dispY = startY - bY; + } else { + dispX = startX - midX; + dispY = startY - midY; + } + rs.srcArrowAngle = getAngleFromDisp(dispX, dispY); + + // mid target + // + + var midX = rs.midX; + var midY = rs.midY; + if (isHaystack) { + midX = (startX + endX) / 2; + midY = (startY + endY) / 2; + } + dispX = endX - startX; + dispY = endY - startY; + if (isSegments) { + var pts = rs.allpts; + if (pts.length / 2 % 2 === 0) { + var i2 = pts.length / 2; + var i1 = i2 - 2; + dispX = pts[i2] - pts[i1]; + dispY = pts[i2 + 1] - pts[i1 + 1]; + } else { + var i2 = pts.length / 2 - 1; + var i1 = i2 - 2; + var i3 = i2 + 2; + dispX = pts[i2] - pts[i1]; + dispY = pts[i2 + 1] - pts[i1 + 1]; + } + } else if (isMultibezier || isCompound || isSelf) { + var pts = rs.allpts; + var cpts = rs.ctrlpts; + var bp0x, bp0y; + var bp1x, bp1y; + if (cpts.length / 2 % 2 === 0) { + var p0 = pts.length / 2 - 1; // startpt + var ic = p0 + 2; + var p1 = ic + 2; + bp0x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.0); + bp0y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.0); + bp1x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.0001); + bp1y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.0001); + } else { + var ic = pts.length / 2 - 1; // ctrpt + var p0 = ic - 2; // startpt + var p1 = ic + 2; // endpt + + bp0x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.4999); + bp0y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.4999); + bp1x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.5); + bp1y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.5); + } + dispX = bp1x - bp0x; + dispY = bp1y - bp0y; + } + rs.midtgtArrowAngle = getAngleFromDisp(dispX, dispY); + rs.midDispX = dispX; + rs.midDispY = dispY; + + // mid source + // + + dispX *= -1; + dispY *= -1; + if (isSegments) { + var pts = rs.allpts; + if (pts.length / 2 % 2 === 0) ; else { + var i2 = pts.length / 2 - 1; + var i3 = i2 + 2; + dispX = -(pts[i3] - pts[i2]); + dispY = -(pts[i3 + 1] - pts[i2 + 1]); + } + } + rs.midsrcArrowAngle = getAngleFromDisp(dispX, dispY); + + // target + // + + if (isSegments) { + dispX = endX - rs.segpts[rs.segpts.length - 2]; + dispY = endY - rs.segpts[rs.segpts.length - 1]; + } else if (isMultibezier || isCompound || isSelf || isBezier) { + var pts = rs.allpts; + var l = pts.length; + var bX = qbezierAt(pts[l - 6], pts[l - 4], pts[l - 2], 0.9); + var bY = qbezierAt(pts[l - 5], pts[l - 3], pts[l - 1], 0.9); + dispX = endX - bX; + dispY = endY - bY; + } else { + dispX = endX - midX; + dispY = endY - midY; + } + rs.tgtArrowAngle = getAngleFromDisp(dispX, dispY); +}; +BRp$d.getArrowWidth = BRp$d.getArrowHeight = function (edgeWidth, scale) { + var cache = this.arrowWidthCache = this.arrowWidthCache || {}; + var cachedVal = cache[edgeWidth + ', ' + scale]; + if (cachedVal) { + return cachedVal; + } + cachedVal = Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29) * scale; + cache[edgeWidth + ', ' + scale] = cachedVal; + return cachedVal; +}; + +var BRp$c = {}; +BRp$c.findMidptPtsEtc = function (edge, pairInfo) { + var posPts = pairInfo.posPts, + intersectionPts = pairInfo.intersectionPts, + vectorNormInverse = pairInfo.vectorNormInverse; + var midptPts; + + // n.b. assumes all edges in bezier bundle have same endpoints specified + var srcManEndpt = edge.pstyle('source-endpoint'); + var tgtManEndpt = edge.pstyle('target-endpoint'); + var haveManualEndPts = srcManEndpt.units != null && tgtManEndpt.units != null; + var recalcVectorNormInverse = function recalcVectorNormInverse(x1, y1, x2, y2) { + var dy = y2 - y1; + var dx = x2 - x1; + var l = Math.sqrt(dx * dx + dy * dy); + return { + x: -dy / l, + y: dx / l + }; + }; + var edgeDistances = edge.pstyle('edge-distances').value; + switch (edgeDistances) { + case 'node-position': + midptPts = posPts; + break; + case 'intersection': + midptPts = intersectionPts; + break; + case 'endpoints': + { + if (haveManualEndPts) { + var _this$manualEndptToPx = this.manualEndptToPx(edge.source()[0], srcManEndpt), + _this$manualEndptToPx2 = _slicedToArray(_this$manualEndptToPx, 2), + x1 = _this$manualEndptToPx2[0], + y1 = _this$manualEndptToPx2[1]; + var _this$manualEndptToPx3 = this.manualEndptToPx(edge.target()[0], tgtManEndpt), + _this$manualEndptToPx4 = _slicedToArray(_this$manualEndptToPx3, 2), + x2 = _this$manualEndptToPx4[0], + y2 = _this$manualEndptToPx4[1]; + var endPts = { + x1: x1, + y1: y1, + x2: x2, + y2: y2 + }; + vectorNormInverse = recalcVectorNormInverse(x1, y1, x2, y2); + midptPts = endPts; + } else { + warn("Edge ".concat(edge.id(), " has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint. Falling back on edge-distances:intersection (default).")); + midptPts = intersectionPts; // back to default + } + + break; + } + } + return { + midptPts: midptPts, + vectorNormInverse: vectorNormInverse + }; +}; +BRp$c.findHaystackPoints = function (edges) { + for (var i = 0; i < edges.length; i++) { + var edge = edges[i]; + var _p = edge._private; + var rs = _p.rscratch; + if (!rs.haystack) { + var angle = Math.random() * 2 * Math.PI; + rs.source = { + x: Math.cos(angle), + y: Math.sin(angle) + }; + angle = Math.random() * 2 * Math.PI; + rs.target = { + x: Math.cos(angle), + y: Math.sin(angle) + }; + } + var src = _p.source; + var tgt = _p.target; + var srcPos = src.position(); + var tgtPos = tgt.position(); + var srcW = src.width(); + var tgtW = tgt.width(); + var srcH = src.height(); + var tgtH = tgt.height(); + var radius = edge.pstyle('haystack-radius').value; + var halfRadius = radius / 2; // b/c have to half width/height + + rs.haystackPts = rs.allpts = [rs.source.x * srcW * halfRadius + srcPos.x, rs.source.y * srcH * halfRadius + srcPos.y, rs.target.x * tgtW * halfRadius + tgtPos.x, rs.target.y * tgtH * halfRadius + tgtPos.y]; + rs.midX = (rs.allpts[0] + rs.allpts[2]) / 2; + rs.midY = (rs.allpts[1] + rs.allpts[3]) / 2; + + // always override as haystack in case set to different type previously + rs.edgeType = 'haystack'; + rs.haystack = true; + this.storeEdgeProjections(edge); + this.calculateArrowAngles(edge); + this.recalculateEdgeLabelProjections(edge); + this.calculateLabelAngles(edge); + } +}; +BRp$c.findSegmentsPoints = function (edge, pairInfo) { + // Segments (multiple straight lines) + + var rs = edge._private.rscratch; + var segmentWs = edge.pstyle('segment-weights'); + var segmentDs = edge.pstyle('segment-distances'); + var segmentsN = Math.min(segmentWs.pfValue.length, segmentDs.pfValue.length); + rs.edgeType = 'segments'; + rs.segpts = []; + for (var s = 0; s < segmentsN; s++) { + var w = segmentWs.pfValue[s]; + var d = segmentDs.pfValue[s]; + var w1 = 1 - w; + var w2 = w; + var _this$findMidptPtsEtc = this.findMidptPtsEtc(edge, pairInfo), + midptPts = _this$findMidptPtsEtc.midptPts, + vectorNormInverse = _this$findMidptPtsEtc.vectorNormInverse; + var adjustedMidpt = { + x: midptPts.x1 * w1 + midptPts.x2 * w2, + y: midptPts.y1 * w1 + midptPts.y2 * w2 + }; + rs.segpts.push(adjustedMidpt.x + vectorNormInverse.x * d, adjustedMidpt.y + vectorNormInverse.y * d); + } +}; +BRp$c.findLoopPoints = function (edge, pairInfo, i, edgeIsUnbundled) { + // Self-edge + + var rs = edge._private.rscratch; + var dirCounts = pairInfo.dirCounts, + srcPos = pairInfo.srcPos; + var ctrlptDists = edge.pstyle('control-point-distances'); + var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined; + var loopDir = edge.pstyle('loop-direction').pfValue; + var loopSwp = edge.pstyle('loop-sweep').pfValue; + var stepSize = edge.pstyle('control-point-step-size').pfValue; + rs.edgeType = 'self'; + var j = i; + var loopDist = stepSize; + if (edgeIsUnbundled) { + j = 0; + loopDist = ctrlptDist; + } + var loopAngle = loopDir - Math.PI / 2; + var outAngle = loopAngle - loopSwp / 2; + var inAngle = loopAngle + loopSwp / 2; + + // increase by step size for overlapping loops, keyed on direction and sweep values + var dc = String(loopDir + '_' + loopSwp); + j = dirCounts[dc] === undefined ? dirCounts[dc] = 0 : ++dirCounts[dc]; + rs.ctrlpts = [srcPos.x + Math.cos(outAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.y + Math.sin(outAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.x + Math.cos(inAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.y + Math.sin(inAngle) * 1.4 * loopDist * (j / 3 + 1)]; +}; +BRp$c.findCompoundLoopPoints = function (edge, pairInfo, i, edgeIsUnbundled) { + // Compound edge + + var rs = edge._private.rscratch; + rs.edgeType = 'compound'; + var srcPos = pairInfo.srcPos, + tgtPos = pairInfo.tgtPos, + srcW = pairInfo.srcW, + srcH = pairInfo.srcH, + tgtW = pairInfo.tgtW, + tgtH = pairInfo.tgtH; + var stepSize = edge.pstyle('control-point-step-size').pfValue; + var ctrlptDists = edge.pstyle('control-point-distances'); + var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined; + var j = i; + var loopDist = stepSize; + if (edgeIsUnbundled) { + j = 0; + loopDist = ctrlptDist; + } + var loopW = 50; + var loopaPos = { + x: srcPos.x - srcW / 2, + y: srcPos.y - srcH / 2 + }; + var loopbPos = { + x: tgtPos.x - tgtW / 2, + y: tgtPos.y - tgtH / 2 + }; + var loopPos = { + x: Math.min(loopaPos.x, loopbPos.x), + y: Math.min(loopaPos.y, loopbPos.y) + }; + + // avoids cases with impossible beziers + var minCompoundStretch = 0.5; + var compoundStretchA = Math.max(minCompoundStretch, Math.log(srcW * 0.01)); + var compoundStretchB = Math.max(minCompoundStretch, Math.log(tgtW * 0.01)); + rs.ctrlpts = [loopPos.x, loopPos.y - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchA, loopPos.x - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchB, loopPos.y]; +}; +BRp$c.findStraightEdgePoints = function (edge) { + // Straight edge within bundle + + edge._private.rscratch.edgeType = 'straight'; +}; +BRp$c.findBezierPoints = function (edge, pairInfo, i, edgeIsUnbundled, edgeIsSwapped) { + var rs = edge._private.rscratch; + var stepSize = edge.pstyle('control-point-step-size').pfValue; + var ctrlptDists = edge.pstyle('control-point-distances'); + var ctrlptWs = edge.pstyle('control-point-weights'); + var bezierN = ctrlptDists && ctrlptWs ? Math.min(ctrlptDists.value.length, ctrlptWs.value.length) : 1; + var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined; + var ctrlptWeight = ctrlptWs.value[0]; + + // (Multi)bezier + + var multi = edgeIsUnbundled; + rs.edgeType = multi ? 'multibezier' : 'bezier'; + rs.ctrlpts = []; + for (var b = 0; b < bezierN; b++) { + var normctrlptDist = (0.5 - pairInfo.eles.length / 2 + i) * stepSize * (edgeIsSwapped ? -1 : 1); + var manctrlptDist = void 0; + var sign = signum(normctrlptDist); + if (multi) { + ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[b] : stepSize; // fall back on step size + ctrlptWeight = ctrlptWs.value[b]; + } + if (edgeIsUnbundled) { + // multi or single unbundled + manctrlptDist = ctrlptDist; + } else { + manctrlptDist = ctrlptDist !== undefined ? sign * ctrlptDist : undefined; + } + var distanceFromMidpoint = manctrlptDist !== undefined ? manctrlptDist : normctrlptDist; + var w1 = 1 - ctrlptWeight; + var w2 = ctrlptWeight; + var _this$findMidptPtsEtc2 = this.findMidptPtsEtc(edge, pairInfo), + midptPts = _this$findMidptPtsEtc2.midptPts, + vectorNormInverse = _this$findMidptPtsEtc2.vectorNormInverse; + var adjustedMidpt = { + x: midptPts.x1 * w1 + midptPts.x2 * w2, + y: midptPts.y1 * w1 + midptPts.y2 * w2 + }; + rs.ctrlpts.push(adjustedMidpt.x + vectorNormInverse.x * distanceFromMidpoint, adjustedMidpt.y + vectorNormInverse.y * distanceFromMidpoint); + } +}; +BRp$c.findTaxiPoints = function (edge, pairInfo) { + // Taxicab geometry with two turns maximum + + var rs = edge._private.rscratch; + rs.edgeType = 'segments'; + var VERTICAL = 'vertical'; + var HORIZONTAL = 'horizontal'; + var LEFTWARD = 'leftward'; + var RIGHTWARD = 'rightward'; + var DOWNWARD = 'downward'; + var UPWARD = 'upward'; + var AUTO = 'auto'; + var posPts = pairInfo.posPts, + srcW = pairInfo.srcW, + srcH = pairInfo.srcH, + tgtW = pairInfo.tgtW, + tgtH = pairInfo.tgtH; + var edgeDistances = edge.pstyle('edge-distances').value; + var dIncludesNodeBody = edgeDistances !== 'node-position'; + var taxiDir = edge.pstyle('taxi-direction').value; + var rawTaxiDir = taxiDir; // unprocessed value + var taxiTurn = edge.pstyle('taxi-turn'); + var turnIsPercent = taxiTurn.units === '%'; + var taxiTurnPfVal = taxiTurn.pfValue; + var turnIsNegative = taxiTurnPfVal < 0; // i.e. from target side + var minD = edge.pstyle('taxi-turn-min-distance').pfValue; + var dw = dIncludesNodeBody ? (srcW + tgtW) / 2 : 0; + var dh = dIncludesNodeBody ? (srcH + tgtH) / 2 : 0; + var pdx = posPts.x2 - posPts.x1; + var pdy = posPts.y2 - posPts.y1; + + // take away the effective w/h from the magnitude of the delta value + var subDWH = function subDWH(dxy, dwh) { + if (dxy > 0) { + return Math.max(dxy - dwh, 0); + } else { + return Math.min(dxy + dwh, 0); + } + }; + var dx = subDWH(pdx, dw); + var dy = subDWH(pdy, dh); + var isExplicitDir = false; + if (rawTaxiDir === AUTO) { + taxiDir = Math.abs(dx) > Math.abs(dy) ? HORIZONTAL : VERTICAL; + } else if (rawTaxiDir === UPWARD || rawTaxiDir === DOWNWARD) { + taxiDir = VERTICAL; + isExplicitDir = true; + } else if (rawTaxiDir === LEFTWARD || rawTaxiDir === RIGHTWARD) { + taxiDir = HORIZONTAL; + isExplicitDir = true; + } + var isVert = taxiDir === VERTICAL; + var l = isVert ? dy : dx; + var pl = isVert ? pdy : pdx; + var sgnL = signum(pl); + var forcedDir = false; + if (!(isExplicitDir && (turnIsPercent || turnIsNegative)) // forcing in this case would cause weird growing in the opposite direction + && (rawTaxiDir === DOWNWARD && pl < 0 || rawTaxiDir === UPWARD && pl > 0 || rawTaxiDir === LEFTWARD && pl > 0 || rawTaxiDir === RIGHTWARD && pl < 0)) { + sgnL *= -1; + l = sgnL * Math.abs(l); + forcedDir = true; + } + var d; + if (turnIsPercent) { + var p = taxiTurnPfVal < 0 ? 1 + taxiTurnPfVal : taxiTurnPfVal; + d = p * l; + } else { + var k = taxiTurnPfVal < 0 ? l : 0; + d = k + taxiTurnPfVal * sgnL; + } + var getIsTooClose = function getIsTooClose(d) { + return Math.abs(d) < minD || Math.abs(d) >= Math.abs(l); + }; + var isTooCloseSrc = getIsTooClose(d); + var isTooCloseTgt = getIsTooClose(Math.abs(l) - Math.abs(d)); + var isTooClose = isTooCloseSrc || isTooCloseTgt; + if (isTooClose && !forcedDir) { + // non-ideal routing + if (isVert) { + // vertical fallbacks + var lShapeInsideSrc = Math.abs(pl) <= srcH / 2; + var lShapeInsideTgt = Math.abs(pdx) <= tgtW / 2; + if (lShapeInsideSrc) { + // horizontal Z-shape (direction not respected) + var x = (posPts.x1 + posPts.x2) / 2; + var y1 = posPts.y1, + y2 = posPts.y2; + rs.segpts = [x, y1, x, y2]; + } else if (lShapeInsideTgt) { + // vertical Z-shape (distance not respected) + var y = (posPts.y1 + posPts.y2) / 2; + var x1 = posPts.x1, + x2 = posPts.x2; + rs.segpts = [x1, y, x2, y]; + } else { + // L-shape fallback (turn distance not respected, but works well with tree siblings) + rs.segpts = [posPts.x1, posPts.y2]; + } + } else { + // horizontal fallbacks + var _lShapeInsideSrc = Math.abs(pl) <= srcW / 2; + var _lShapeInsideTgt = Math.abs(pdy) <= tgtH / 2; + if (_lShapeInsideSrc) { + // vertical Z-shape (direction not respected) + var _y = (posPts.y1 + posPts.y2) / 2; + var _x = posPts.x1, + _x2 = posPts.x2; + rs.segpts = [_x, _y, _x2, _y]; + } else if (_lShapeInsideTgt) { + // horizontal Z-shape (turn distance not respected) + var _x3 = (posPts.x1 + posPts.x2) / 2; + var _y2 = posPts.y1, + _y3 = posPts.y2; + rs.segpts = [_x3, _y2, _x3, _y3]; + } else { + // L-shape (turn distance not respected, but works well for tree siblings) + rs.segpts = [posPts.x2, posPts.y1]; + } + } + } else { + // ideal routing + if (isVert) { + var _y4 = posPts.y1 + d + (dIncludesNodeBody ? srcH / 2 * sgnL : 0); + var _x4 = posPts.x1, + _x5 = posPts.x2; + rs.segpts = [_x4, _y4, _x5, _y4]; + } else { + // horizontal + var _x6 = posPts.x1 + d + (dIncludesNodeBody ? srcW / 2 * sgnL : 0); + var _y5 = posPts.y1, + _y6 = posPts.y2; + rs.segpts = [_x6, _y5, _x6, _y6]; + } + } +}; +BRp$c.tryToCorrectInvalidPoints = function (edge, pairInfo) { + var rs = edge._private.rscratch; + + // can only correct beziers for now... + if (rs.edgeType === 'bezier') { + var srcPos = pairInfo.srcPos, + tgtPos = pairInfo.tgtPos, + srcW = pairInfo.srcW, + srcH = pairInfo.srcH, + tgtW = pairInfo.tgtW, + tgtH = pairInfo.tgtH, + srcShape = pairInfo.srcShape, + tgtShape = pairInfo.tgtShape; + var badStart = !number$1(rs.startX) || !number$1(rs.startY); + var badAStart = !number$1(rs.arrowStartX) || !number$1(rs.arrowStartY); + var badEnd = !number$1(rs.endX) || !number$1(rs.endY); + var badAEnd = !number$1(rs.arrowEndX) || !number$1(rs.arrowEndY); + var minCpADistFactor = 3; + var arrowW = this.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.arrowShapeWidth; + var minCpADist = minCpADistFactor * arrowW; + var startACpDist = dist({ + x: rs.ctrlpts[0], + y: rs.ctrlpts[1] + }, { + x: rs.startX, + y: rs.startY + }); + var closeStartACp = startACpDist < minCpADist; + var endACpDist = dist({ + x: rs.ctrlpts[0], + y: rs.ctrlpts[1] + }, { + x: rs.endX, + y: rs.endY + }); + var closeEndACp = endACpDist < minCpADist; + var overlapping = false; + if (badStart || badAStart || closeStartACp) { + overlapping = true; + + // project control point along line from src centre to outside the src shape + // (otherwise intersection will yield nothing) + var cpD = { + // delta + x: rs.ctrlpts[0] - srcPos.x, + y: rs.ctrlpts[1] - srcPos.y + }; + var cpL = Math.sqrt(cpD.x * cpD.x + cpD.y * cpD.y); // length of line + var cpM = { + // normalised delta + x: cpD.x / cpL, + y: cpD.y / cpL + }; + var radius = Math.max(srcW, srcH); + var cpProj = { + // *2 radius guarantees outside shape + x: rs.ctrlpts[0] + cpM.x * 2 * radius, + y: rs.ctrlpts[1] + cpM.y * 2 * radius + }; + var srcCtrlPtIntn = srcShape.intersectLine(srcPos.x, srcPos.y, srcW, srcH, cpProj.x, cpProj.y, 0); + if (closeStartACp) { + rs.ctrlpts[0] = rs.ctrlpts[0] + cpM.x * (minCpADist - startACpDist); + rs.ctrlpts[1] = rs.ctrlpts[1] + cpM.y * (minCpADist - startACpDist); + } else { + rs.ctrlpts[0] = srcCtrlPtIntn[0] + cpM.x * minCpADist; + rs.ctrlpts[1] = srcCtrlPtIntn[1] + cpM.y * minCpADist; + } + } + if (badEnd || badAEnd || closeEndACp) { + overlapping = true; + + // project control point along line from tgt centre to outside the tgt shape + // (otherwise intersection will yield nothing) + var _cpD = { + // delta + x: rs.ctrlpts[0] - tgtPos.x, + y: rs.ctrlpts[1] - tgtPos.y + }; + var _cpL = Math.sqrt(_cpD.x * _cpD.x + _cpD.y * _cpD.y); // length of line + var _cpM = { + // normalised delta + x: _cpD.x / _cpL, + y: _cpD.y / _cpL + }; + var _radius = Math.max(srcW, srcH); + var _cpProj = { + // *2 radius guarantees outside shape + x: rs.ctrlpts[0] + _cpM.x * 2 * _radius, + y: rs.ctrlpts[1] + _cpM.y * 2 * _radius + }; + var tgtCtrlPtIntn = tgtShape.intersectLine(tgtPos.x, tgtPos.y, tgtW, tgtH, _cpProj.x, _cpProj.y, 0); + if (closeEndACp) { + rs.ctrlpts[0] = rs.ctrlpts[0] + _cpM.x * (minCpADist - endACpDist); + rs.ctrlpts[1] = rs.ctrlpts[1] + _cpM.y * (minCpADist - endACpDist); + } else { + rs.ctrlpts[0] = tgtCtrlPtIntn[0] + _cpM.x * minCpADist; + rs.ctrlpts[1] = tgtCtrlPtIntn[1] + _cpM.y * minCpADist; + } + } + if (overlapping) { + // recalc endpts + this.findEndpoints(edge); + } + } +}; +BRp$c.storeAllpts = function (edge) { + var rs = edge._private.rscratch; + if (rs.edgeType === 'multibezier' || rs.edgeType === 'bezier' || rs.edgeType === 'self' || rs.edgeType === 'compound') { + rs.allpts = []; + rs.allpts.push(rs.startX, rs.startY); + for (var b = 0; b + 1 < rs.ctrlpts.length; b += 2) { + // ctrl pt itself + rs.allpts.push(rs.ctrlpts[b], rs.ctrlpts[b + 1]); + + // the midpt between ctrlpts as intermediate destination pts + if (b + 3 < rs.ctrlpts.length) { + rs.allpts.push((rs.ctrlpts[b] + rs.ctrlpts[b + 2]) / 2, (rs.ctrlpts[b + 1] + rs.ctrlpts[b + 3]) / 2); + } + } + rs.allpts.push(rs.endX, rs.endY); + var m, mt; + if (rs.ctrlpts.length / 2 % 2 === 0) { + m = rs.allpts.length / 2 - 1; + rs.midX = rs.allpts[m]; + rs.midY = rs.allpts[m + 1]; + } else { + m = rs.allpts.length / 2 - 3; + mt = 0.5; + rs.midX = qbezierAt(rs.allpts[m], rs.allpts[m + 2], rs.allpts[m + 4], mt); + rs.midY = qbezierAt(rs.allpts[m + 1], rs.allpts[m + 3], rs.allpts[m + 5], mt); + } + } else if (rs.edgeType === 'straight') { + // need to calc these after endpts + rs.allpts = [rs.startX, rs.startY, rs.endX, rs.endY]; + + // default midpt for labels etc + rs.midX = (rs.startX + rs.endX + rs.arrowStartX + rs.arrowEndX) / 4; + rs.midY = (rs.startY + rs.endY + rs.arrowStartY + rs.arrowEndY) / 4; + } else if (rs.edgeType === 'segments') { + rs.allpts = []; + rs.allpts.push(rs.startX, rs.startY); + rs.allpts.push.apply(rs.allpts, rs.segpts); + rs.allpts.push(rs.endX, rs.endY); + if (rs.segpts.length % 4 === 0) { + var i2 = rs.segpts.length / 2; + var i1 = i2 - 2; + rs.midX = (rs.segpts[i1] + rs.segpts[i2]) / 2; + rs.midY = (rs.segpts[i1 + 1] + rs.segpts[i2 + 1]) / 2; + } else { + var _i = rs.segpts.length / 2 - 1; + rs.midX = rs.segpts[_i]; + rs.midY = rs.segpts[_i + 1]; + } + } +}; +BRp$c.checkForInvalidEdgeWarning = function (edge) { + var rs = edge[0]._private.rscratch; + if (rs.nodesOverlap || number$1(rs.startX) && number$1(rs.startY) && number$1(rs.endX) && number$1(rs.endY)) { + rs.loggedErr = false; + } else { + if (!rs.loggedErr) { + rs.loggedErr = true; + warn('Edge `' + edge.id() + '` has invalid endpoints and so it is impossible to draw. Adjust your edge style (e.g. control points) accordingly or use an alternative edge type. This is expected behaviour when the source node and the target node overlap.'); + } + } +}; +BRp$c.findEdgeControlPoints = function (edges) { + var _this = this; + if (!edges || edges.length === 0) { + return; + } + var r = this; + var cy = r.cy; + var hasCompounds = cy.hasCompoundNodes(); + var hashTable = { + map: new Map$1(), + get: function get(pairId) { + var map2 = this.map.get(pairId[0]); + if (map2 != null) { + return map2.get(pairId[1]); + } else { + return null; + } + }, + set: function set(pairId, val) { + var map2 = this.map.get(pairId[0]); + if (map2 == null) { + map2 = new Map$1(); + this.map.set(pairId[0], map2); + } + map2.set(pairId[1], val); + } + }; + var pairIds = []; + var haystackEdges = []; + + // create a table of edge (src, tgt) => list of edges between them + for (var i = 0; i < edges.length; i++) { + var edge = edges[i]; + var _p = edge._private; + var curveStyle = edge.pstyle('curve-style').value; + + // ignore edges who are not to be displayed + // they shouldn't take up space + if (edge.removed() || !edge.takesUpSpace()) { + continue; + } + if (curveStyle === 'haystack') { + haystackEdges.push(edge); + continue; + } + var edgeIsUnbundled = curveStyle === 'unbundled-bezier' || curveStyle === 'segments' || curveStyle === 'straight' || curveStyle === 'straight-triangle' || curveStyle === 'taxi'; + var edgeIsBezier = curveStyle === 'unbundled-bezier' || curveStyle === 'bezier'; + var src = _p.source; + var tgt = _p.target; + var srcIndex = src.poolIndex(); + var tgtIndex = tgt.poolIndex(); + var pairId = [srcIndex, tgtIndex].sort(); + var tableEntry = hashTable.get(pairId); + if (tableEntry == null) { + tableEntry = { + eles: [] + }; + hashTable.set(pairId, tableEntry); + pairIds.push(pairId); + } + tableEntry.eles.push(edge); + if (edgeIsUnbundled) { + tableEntry.hasUnbundled = true; + } + if (edgeIsBezier) { + tableEntry.hasBezier = true; + } + } + + // for each pair (src, tgt), create the ctrl pts + // Nested for loop is OK; total number of iterations for both loops = edgeCount + var _loop = function _loop(p) { + var pairId = pairIds[p]; + var pairInfo = hashTable.get(pairId); + var swappedpairInfo = void 0; + if (!pairInfo.hasUnbundled) { + var pllEdges = pairInfo.eles[0].parallelEdges().filter(function (e) { + return e.isBundledBezier(); + }); + clearArray(pairInfo.eles); + pllEdges.forEach(function (edge) { + return pairInfo.eles.push(edge); + }); + + // for each pair id, the edges should be sorted by index + pairInfo.eles.sort(function (edge1, edge2) { + return edge1.poolIndex() - edge2.poolIndex(); + }); + } + var firstEdge = pairInfo.eles[0]; + var src = firstEdge.source(); + var tgt = firstEdge.target(); + + // make sure src/tgt distinction is consistent w.r.t. pairId + if (src.poolIndex() > tgt.poolIndex()) { + var temp = src; + src = tgt; + tgt = temp; + } + var srcPos = pairInfo.srcPos = src.position(); + var tgtPos = pairInfo.tgtPos = tgt.position(); + var srcW = pairInfo.srcW = src.outerWidth(); + var srcH = pairInfo.srcH = src.outerHeight(); + var tgtW = pairInfo.tgtW = tgt.outerWidth(); + var tgtH = pairInfo.tgtH = tgt.outerHeight(); + var srcShape = pairInfo.srcShape = r.nodeShapes[_this.getNodeShape(src)]; + var tgtShape = pairInfo.tgtShape = r.nodeShapes[_this.getNodeShape(tgt)]; + pairInfo.dirCounts = { + 'north': 0, + 'west': 0, + 'south': 0, + 'east': 0, + 'northwest': 0, + 'southwest': 0, + 'northeast': 0, + 'southeast': 0 + }; + for (var _i2 = 0; _i2 < pairInfo.eles.length; _i2++) { + var _edge = pairInfo.eles[_i2]; + var rs = _edge[0]._private.rscratch; + var _curveStyle = _edge.pstyle('curve-style').value; + var _edgeIsUnbundled = _curveStyle === 'unbundled-bezier' || _curveStyle === 'segments' || _curveStyle === 'taxi'; + + // whether the normalised pair order is the reverse of the edge's src-tgt order + var edgeIsSwapped = !src.same(_edge.source()); + if (!pairInfo.calculatedIntersection && src !== tgt && (pairInfo.hasBezier || pairInfo.hasUnbundled)) { + pairInfo.calculatedIntersection = true; + + // pt outside src shape to calc distance/displacement from src to tgt + var srcOutside = srcShape.intersectLine(srcPos.x, srcPos.y, srcW, srcH, tgtPos.x, tgtPos.y, 0); + var srcIntn = pairInfo.srcIntn = srcOutside; + + // pt outside tgt shape to calc distance/displacement from src to tgt + var tgtOutside = tgtShape.intersectLine(tgtPos.x, tgtPos.y, tgtW, tgtH, srcPos.x, srcPos.y, 0); + var tgtIntn = pairInfo.tgtIntn = tgtOutside; + var intersectionPts = pairInfo.intersectionPts = { + x1: srcOutside[0], + x2: tgtOutside[0], + y1: srcOutside[1], + y2: tgtOutside[1] + }; + var posPts = pairInfo.posPts = { + x1: srcPos.x, + x2: tgtPos.x, + y1: srcPos.y, + y2: tgtPos.y + }; + var dy = tgtOutside[1] - srcOutside[1]; + var dx = tgtOutside[0] - srcOutside[0]; + var l = Math.sqrt(dx * dx + dy * dy); + var vector = pairInfo.vector = { + x: dx, + y: dy + }; + var vectorNorm = pairInfo.vectorNorm = { + x: vector.x / l, + y: vector.y / l + }; + var vectorNormInverse = { + x: -vectorNorm.y, + y: vectorNorm.x + }; + + // if node shapes overlap, then no ctrl pts to draw + pairInfo.nodesOverlap = !number$1(l) || tgtShape.checkPoint(srcOutside[0], srcOutside[1], 0, tgtW, tgtH, tgtPos.x, tgtPos.y) || srcShape.checkPoint(tgtOutside[0], tgtOutside[1], 0, srcW, srcH, srcPos.x, srcPos.y); + pairInfo.vectorNormInverse = vectorNormInverse; + swappedpairInfo = { + nodesOverlap: pairInfo.nodesOverlap, + dirCounts: pairInfo.dirCounts, + calculatedIntersection: true, + hasBezier: pairInfo.hasBezier, + hasUnbundled: pairInfo.hasUnbundled, + eles: pairInfo.eles, + srcPos: tgtPos, + tgtPos: srcPos, + srcW: tgtW, + srcH: tgtH, + tgtW: srcW, + tgtH: srcH, + srcIntn: tgtIntn, + tgtIntn: srcIntn, + srcShape: tgtShape, + tgtShape: srcShape, + posPts: { + x1: posPts.x2, + y1: posPts.y2, + x2: posPts.x1, + y2: posPts.y1 + }, + intersectionPts: { + x1: intersectionPts.x2, + y1: intersectionPts.y2, + x2: intersectionPts.x1, + y2: intersectionPts.y1 + }, + vector: { + x: -vector.x, + y: -vector.y + }, + vectorNorm: { + x: -vectorNorm.x, + y: -vectorNorm.y + }, + vectorNormInverse: { + x: -vectorNormInverse.x, + y: -vectorNormInverse.y + } + }; + } + var passedPairInfo = edgeIsSwapped ? swappedpairInfo : pairInfo; + rs.nodesOverlap = passedPairInfo.nodesOverlap; + rs.srcIntn = passedPairInfo.srcIntn; + rs.tgtIntn = passedPairInfo.tgtIntn; + if (hasCompounds && (src.isParent() || src.isChild() || tgt.isParent() || tgt.isChild()) && (src.parents().anySame(tgt) || tgt.parents().anySame(src) || src.same(tgt) && src.isParent())) { + _this.findCompoundLoopPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled); + } else if (src === tgt) { + _this.findLoopPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled); + } else if (_curveStyle === 'segments') { + _this.findSegmentsPoints(_edge, passedPairInfo); + } else if (_curveStyle === 'taxi') { + _this.findTaxiPoints(_edge, passedPairInfo); + } else if (_curveStyle === 'straight' || !_edgeIsUnbundled && pairInfo.eles.length % 2 === 1 && _i2 === Math.floor(pairInfo.eles.length / 2)) { + _this.findStraightEdgePoints(_edge); + } else { + _this.findBezierPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled, edgeIsSwapped); + } + _this.findEndpoints(_edge); + _this.tryToCorrectInvalidPoints(_edge, passedPairInfo); + _this.checkForInvalidEdgeWarning(_edge); + _this.storeAllpts(_edge); + _this.storeEdgeProjections(_edge); + _this.calculateArrowAngles(_edge); + _this.recalculateEdgeLabelProjections(_edge); + _this.calculateLabelAngles(_edge); + } // for pair edges + }; + for (var p = 0; p < pairIds.length; p++) { + _loop(p); + } // for pair ids + + // haystacks avoid the expense of pairInfo stuff (intersections etc.) + this.findHaystackPoints(haystackEdges); +}; +function getPts(pts) { + var retPts = []; + if (pts == null) { + return; + } + for (var i = 0; i < pts.length; i += 2) { + var x = pts[i]; + var y = pts[i + 1]; + retPts.push({ + x: x, + y: y + }); + } + return retPts; +} +BRp$c.getSegmentPoints = function (edge) { + var rs = edge[0]._private.rscratch; + var type = rs.edgeType; + if (type === 'segments') { + this.recalculateRenderedStyle(edge); + return getPts(rs.segpts); + } +}; +BRp$c.getControlPoints = function (edge) { + var rs = edge[0]._private.rscratch; + var type = rs.edgeType; + if (type === 'bezier' || type === 'multibezier' || type === 'self' || type === 'compound') { + this.recalculateRenderedStyle(edge); + return getPts(rs.ctrlpts); + } +}; +BRp$c.getEdgeMidpoint = function (edge) { + var rs = edge[0]._private.rscratch; + this.recalculateRenderedStyle(edge); + return { + x: rs.midX, + y: rs.midY + }; +}; + +var BRp$b = {}; +BRp$b.manualEndptToPx = function (node, prop) { + var r = this; + var npos = node.position(); + var w = node.outerWidth(); + var h = node.outerHeight(); + if (prop.value.length === 2) { + var p = [prop.pfValue[0], prop.pfValue[1]]; + if (prop.units[0] === '%') { + p[0] = p[0] * w; + } + if (prop.units[1] === '%') { + p[1] = p[1] * h; + } + p[0] += npos.x; + p[1] += npos.y; + return p; + } else { + var angle = prop.pfValue[0]; + angle = -Math.PI / 2 + angle; // start at 12 o'clock + + var l = 2 * Math.max(w, h); + var _p = [npos.x + Math.cos(angle) * l, npos.y + Math.sin(angle) * l]; + return r.nodeShapes[this.getNodeShape(node)].intersectLine(npos.x, npos.y, w, h, _p[0], _p[1], 0); + } +}; +BRp$b.findEndpoints = function (edge) { + var r = this; + var intersect; + var source = edge.source()[0]; + var target = edge.target()[0]; + var srcPos = source.position(); + var tgtPos = target.position(); + var tgtArShape = edge.pstyle('target-arrow-shape').value; + var srcArShape = edge.pstyle('source-arrow-shape').value; + var tgtDist = edge.pstyle('target-distance-from-node').pfValue; + var srcDist = edge.pstyle('source-distance-from-node').pfValue; + var curveStyle = edge.pstyle('curve-style').value; + var rs = edge._private.rscratch; + var et = rs.edgeType; + var taxi = curveStyle === 'taxi'; + var self = et === 'self' || et === 'compound'; + var bezier = et === 'bezier' || et === 'multibezier' || self; + var multi = et !== 'bezier'; + var lines = et === 'straight' || et === 'segments'; + var segments = et === 'segments'; + var hasEndpts = bezier || multi || lines; + var overrideEndpts = self || taxi; + var srcManEndpt = edge.pstyle('source-endpoint'); + var srcManEndptVal = overrideEndpts ? 'outside-to-node' : srcManEndpt.value; + var tgtManEndpt = edge.pstyle('target-endpoint'); + var tgtManEndptVal = overrideEndpts ? 'outside-to-node' : tgtManEndpt.value; + rs.srcManEndpt = srcManEndpt; + rs.tgtManEndpt = tgtManEndpt; + var p1; // last known point of edge on target side + var p2; // last known point of edge on source side + + var p1_i; // point to intersect with target shape + var p2_i; // point to intersect with source shape + + if (bezier) { + var cpStart = [rs.ctrlpts[0], rs.ctrlpts[1]]; + var cpEnd = multi ? [rs.ctrlpts[rs.ctrlpts.length - 2], rs.ctrlpts[rs.ctrlpts.length - 1]] : cpStart; + p1 = cpEnd; + p2 = cpStart; + } else if (lines) { + var srcArrowFromPt = !segments ? [tgtPos.x, tgtPos.y] : rs.segpts.slice(0, 2); + var tgtArrowFromPt = !segments ? [srcPos.x, srcPos.y] : rs.segpts.slice(rs.segpts.length - 2); + p1 = tgtArrowFromPt; + p2 = srcArrowFromPt; + } + if (tgtManEndptVal === 'inside-to-node') { + intersect = [tgtPos.x, tgtPos.y]; + } else if (tgtManEndpt.units) { + intersect = this.manualEndptToPx(target, tgtManEndpt); + } else if (tgtManEndptVal === 'outside-to-line') { + intersect = rs.tgtIntn; // use cached value from ctrlpt calc + } else { + if (tgtManEndptVal === 'outside-to-node' || tgtManEndptVal === 'outside-to-node-or-label') { + p1_i = p1; + } else if (tgtManEndptVal === 'outside-to-line' || tgtManEndptVal === 'outside-to-line-or-label') { + p1_i = [srcPos.x, srcPos.y]; + } + intersect = r.nodeShapes[this.getNodeShape(target)].intersectLine(tgtPos.x, tgtPos.y, target.outerWidth(), target.outerHeight(), p1_i[0], p1_i[1], 0); + if (tgtManEndptVal === 'outside-to-node-or-label' || tgtManEndptVal === 'outside-to-line-or-label') { + var trs = target._private.rscratch; + var lw = trs.labelWidth; + var lh = trs.labelHeight; + var lx = trs.labelX; + var ly = trs.labelY; + var lw2 = lw / 2; + var lh2 = lh / 2; + var va = target.pstyle('text-valign').value; + if (va === 'top') { + ly -= lh2; + } else if (va === 'bottom') { + ly += lh2; + } + var ha = target.pstyle('text-halign').value; + if (ha === 'left') { + lx -= lw2; + } else if (ha === 'right') { + lx += lw2; + } + var labelIntersect = polygonIntersectLine(p1_i[0], p1_i[1], [lx - lw2, ly - lh2, lx + lw2, ly - lh2, lx + lw2, ly + lh2, lx - lw2, ly + lh2], tgtPos.x, tgtPos.y); + if (labelIntersect.length > 0) { + var refPt = srcPos; + var intSqdist = sqdist(refPt, array2point(intersect)); + var labIntSqdist = sqdist(refPt, array2point(labelIntersect)); + var minSqDist = intSqdist; + if (labIntSqdist < intSqdist) { + intersect = labelIntersect; + minSqDist = labIntSqdist; + } + if (labelIntersect.length > 2) { + var labInt2SqDist = sqdist(refPt, { + x: labelIntersect[2], + y: labelIntersect[3] + }); + if (labInt2SqDist < minSqDist) { + intersect = [labelIntersect[2], labelIntersect[3]]; + } + } + } + } + } + var arrowEnd = shortenIntersection(intersect, p1, r.arrowShapes[tgtArShape].spacing(edge) + tgtDist); + var edgeEnd = shortenIntersection(intersect, p1, r.arrowShapes[tgtArShape].gap(edge) + tgtDist); + rs.endX = edgeEnd[0]; + rs.endY = edgeEnd[1]; + rs.arrowEndX = arrowEnd[0]; + rs.arrowEndY = arrowEnd[1]; + if (srcManEndptVal === 'inside-to-node') { + intersect = [srcPos.x, srcPos.y]; + } else if (srcManEndpt.units) { + intersect = this.manualEndptToPx(source, srcManEndpt); + } else if (srcManEndptVal === 'outside-to-line') { + intersect = rs.srcIntn; // use cached value from ctrlpt calc + } else { + if (srcManEndptVal === 'outside-to-node' || srcManEndptVal === 'outside-to-node-or-label') { + p2_i = p2; + } else if (srcManEndptVal === 'outside-to-line' || srcManEndptVal === 'outside-to-line-or-label') { + p2_i = [tgtPos.x, tgtPos.y]; + } + intersect = r.nodeShapes[this.getNodeShape(source)].intersectLine(srcPos.x, srcPos.y, source.outerWidth(), source.outerHeight(), p2_i[0], p2_i[1], 0); + if (srcManEndptVal === 'outside-to-node-or-label' || srcManEndptVal === 'outside-to-line-or-label') { + var srs = source._private.rscratch; + var _lw = srs.labelWidth; + var _lh = srs.labelHeight; + var _lx = srs.labelX; + var _ly = srs.labelY; + var _lw2 = _lw / 2; + var _lh2 = _lh / 2; + var _va = source.pstyle('text-valign').value; + if (_va === 'top') { + _ly -= _lh2; + } else if (_va === 'bottom') { + _ly += _lh2; + } + var _ha = source.pstyle('text-halign').value; + if (_ha === 'left') { + _lx -= _lw2; + } else if (_ha === 'right') { + _lx += _lw2; + } + var _labelIntersect = polygonIntersectLine(p2_i[0], p2_i[1], [_lx - _lw2, _ly - _lh2, _lx + _lw2, _ly - _lh2, _lx + _lw2, _ly + _lh2, _lx - _lw2, _ly + _lh2], srcPos.x, srcPos.y); + if (_labelIntersect.length > 0) { + var _refPt = tgtPos; + var _intSqdist = sqdist(_refPt, array2point(intersect)); + var _labIntSqdist = sqdist(_refPt, array2point(_labelIntersect)); + var _minSqDist = _intSqdist; + if (_labIntSqdist < _intSqdist) { + intersect = [_labelIntersect[0], _labelIntersect[1]]; + _minSqDist = _labIntSqdist; + } + if (_labelIntersect.length > 2) { + var _labInt2SqDist = sqdist(_refPt, { + x: _labelIntersect[2], + y: _labelIntersect[3] + }); + if (_labInt2SqDist < _minSqDist) { + intersect = [_labelIntersect[2], _labelIntersect[3]]; + } + } + } + } + } + var arrowStart = shortenIntersection(intersect, p2, r.arrowShapes[srcArShape].spacing(edge) + srcDist); + var edgeStart = shortenIntersection(intersect, p2, r.arrowShapes[srcArShape].gap(edge) + srcDist); + rs.startX = edgeStart[0]; + rs.startY = edgeStart[1]; + rs.arrowStartX = arrowStart[0]; + rs.arrowStartY = arrowStart[1]; + if (hasEndpts) { + if (!number$1(rs.startX) || !number$1(rs.startY) || !number$1(rs.endX) || !number$1(rs.endY)) { + rs.badLine = true; + } else { + rs.badLine = false; + } + } +}; +BRp$b.getSourceEndpoint = function (edge) { + var rs = edge[0]._private.rscratch; + this.recalculateRenderedStyle(edge); + switch (rs.edgeType) { + case 'haystack': + return { + x: rs.haystackPts[0], + y: rs.haystackPts[1] + }; + default: + return { + x: rs.arrowStartX, + y: rs.arrowStartY + }; + } +}; +BRp$b.getTargetEndpoint = function (edge) { + var rs = edge[0]._private.rscratch; + this.recalculateRenderedStyle(edge); + switch (rs.edgeType) { + case 'haystack': + return { + x: rs.haystackPts[2], + y: rs.haystackPts[3] + }; + default: + return { + x: rs.arrowEndX, + y: rs.arrowEndY + }; + } +}; + +var BRp$a = {}; +function pushBezierPts(r, edge, pts) { + var qbezierAt$1 = function qbezierAt$1(p1, p2, p3, t) { + return qbezierAt(p1, p2, p3, t); + }; + var _p = edge._private; + var bpts = _p.rstyle.bezierPts; + for (var i = 0; i < r.bezierProjPcts.length; i++) { + var p = r.bezierProjPcts[i]; + bpts.push({ + x: qbezierAt$1(pts[0], pts[2], pts[4], p), + y: qbezierAt$1(pts[1], pts[3], pts[5], p) + }); + } +} +BRp$a.storeEdgeProjections = function (edge) { + var _p = edge._private; + var rs = _p.rscratch; + var et = rs.edgeType; + + // clear the cached points state + _p.rstyle.bezierPts = null; + _p.rstyle.linePts = null; + _p.rstyle.haystackPts = null; + if (et === 'multibezier' || et === 'bezier' || et === 'self' || et === 'compound') { + _p.rstyle.bezierPts = []; + for (var i = 0; i + 5 < rs.allpts.length; i += 4) { + pushBezierPts(this, edge, rs.allpts.slice(i, i + 6)); + } + } else if (et === 'segments') { + var lpts = _p.rstyle.linePts = []; + for (var i = 0; i + 1 < rs.allpts.length; i += 2) { + lpts.push({ + x: rs.allpts[i], + y: rs.allpts[i + 1] + }); + } + } else if (et === 'haystack') { + var hpts = rs.haystackPts; + _p.rstyle.haystackPts = [{ + x: hpts[0], + y: hpts[1] + }, { + x: hpts[2], + y: hpts[3] + }]; + } + _p.rstyle.arrowWidth = this.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.arrowShapeWidth; +}; +BRp$a.recalculateEdgeProjections = function (edges) { + this.findEdgeControlPoints(edges); +}; + +/* global document */ + +var BRp$9 = {}; +BRp$9.recalculateNodeLabelProjection = function (node) { + var content = node.pstyle('label').strValue; + if (emptyString(content)) { + return; + } + var textX, textY; + var _p = node._private; + var nodeWidth = node.width(); + var nodeHeight = node.height(); + var padding = node.padding(); + var nodePos = node.position(); + var textHalign = node.pstyle('text-halign').strValue; + var textValign = node.pstyle('text-valign').strValue; + var rs = _p.rscratch; + var rstyle = _p.rstyle; + switch (textHalign) { + case 'left': + textX = nodePos.x - nodeWidth / 2 - padding; + break; + case 'right': + textX = nodePos.x + nodeWidth / 2 + padding; + break; + default: + // e.g. center + textX = nodePos.x; + } + switch (textValign) { + case 'top': + textY = nodePos.y - nodeHeight / 2 - padding; + break; + case 'bottom': + textY = nodePos.y + nodeHeight / 2 + padding; + break; + default: + // e.g. middle + textY = nodePos.y; + } + rs.labelX = textX; + rs.labelY = textY; + rstyle.labelX = textX; + rstyle.labelY = textY; + this.calculateLabelAngles(node); + this.applyLabelDimensions(node); +}; +var lineAngleFromDelta = function lineAngleFromDelta(dx, dy) { + var angle = Math.atan(dy / dx); + if (dx === 0 && angle < 0) { + angle = angle * -1; + } + return angle; +}; +var lineAngle = function lineAngle(p0, p1) { + var dx = p1.x - p0.x; + var dy = p1.y - p0.y; + return lineAngleFromDelta(dx, dy); +}; +var bezierAngle = function bezierAngle(p0, p1, p2, t) { + var t0 = bound(0, t - 0.001, 1); + var t1 = bound(0, t + 0.001, 1); + var lp0 = qbezierPtAt(p0, p1, p2, t0); + var lp1 = qbezierPtAt(p0, p1, p2, t1); + return lineAngle(lp0, lp1); +}; +BRp$9.recalculateEdgeLabelProjections = function (edge) { + var p; + var _p = edge._private; + var rs = _p.rscratch; + var r = this; + var content = { + mid: edge.pstyle('label').strValue, + source: edge.pstyle('source-label').strValue, + target: edge.pstyle('target-label').strValue + }; + if (content.mid || content.source || content.target) ; else { + return; // no labels => no calcs + } + + // add center point to style so bounding box calculations can use it + // + p = { + x: rs.midX, + y: rs.midY + }; + var setRs = function setRs(propName, prefix, value) { + setPrefixedProperty(_p.rscratch, propName, prefix, value); + setPrefixedProperty(_p.rstyle, propName, prefix, value); + }; + setRs('labelX', null, p.x); + setRs('labelY', null, p.y); + var midAngle = lineAngleFromDelta(rs.midDispX, rs.midDispY); + setRs('labelAutoAngle', null, midAngle); + var createControlPointInfo = function createControlPointInfo() { + if (createControlPointInfo.cache) { + return createControlPointInfo.cache; + } // use cache so only 1x per edge + + var ctrlpts = []; + + // store each ctrlpt info init + for (var i = 0; i + 5 < rs.allpts.length; i += 4) { + var p0 = { + x: rs.allpts[i], + y: rs.allpts[i + 1] + }; + var p1 = { + x: rs.allpts[i + 2], + y: rs.allpts[i + 3] + }; // ctrlpt + var p2 = { + x: rs.allpts[i + 4], + y: rs.allpts[i + 5] + }; + ctrlpts.push({ + p0: p0, + p1: p1, + p2: p2, + startDist: 0, + length: 0, + segments: [] + }); + } + var bpts = _p.rstyle.bezierPts; + var nProjs = r.bezierProjPcts.length; + function addSegment(cp, p0, p1, t0, t1) { + var length = dist(p0, p1); + var prevSegment = cp.segments[cp.segments.length - 1]; + var segment = { + p0: p0, + p1: p1, + t0: t0, + t1: t1, + startDist: prevSegment ? prevSegment.startDist + prevSegment.length : 0, + length: length + }; + cp.segments.push(segment); + cp.length += length; + } + + // update each ctrlpt with segment info + for (var _i = 0; _i < ctrlpts.length; _i++) { + var cp = ctrlpts[_i]; + var prevCp = ctrlpts[_i - 1]; + if (prevCp) { + cp.startDist = prevCp.startDist + prevCp.length; + } + addSegment(cp, cp.p0, bpts[_i * nProjs], 0, r.bezierProjPcts[0]); // first + + for (var j = 0; j < nProjs - 1; j++) { + addSegment(cp, bpts[_i * nProjs + j], bpts[_i * nProjs + j + 1], r.bezierProjPcts[j], r.bezierProjPcts[j + 1]); + } + addSegment(cp, bpts[_i * nProjs + nProjs - 1], cp.p2, r.bezierProjPcts[nProjs - 1], 1); // last + } + + return createControlPointInfo.cache = ctrlpts; + }; + var calculateEndProjection = function calculateEndProjection(prefix) { + var angle; + var isSrc = prefix === 'source'; + if (!content[prefix]) { + return; + } + var offset = edge.pstyle(prefix + '-text-offset').pfValue; + switch (rs.edgeType) { + case 'self': + case 'compound': + case 'bezier': + case 'multibezier': + { + var cps = createControlPointInfo(); + var selected; + var startDist = 0; + var totalDist = 0; + + // find the segment we're on + for (var i = 0; i < cps.length; i++) { + var _cp = cps[isSrc ? i : cps.length - 1 - i]; + for (var j = 0; j < _cp.segments.length; j++) { + var _seg = _cp.segments[isSrc ? j : _cp.segments.length - 1 - j]; + var lastSeg = i === cps.length - 1 && j === _cp.segments.length - 1; + startDist = totalDist; + totalDist += _seg.length; + if (totalDist >= offset || lastSeg) { + selected = { + cp: _cp, + segment: _seg + }; + break; + } + } + if (selected) { + break; + } + } + var cp = selected.cp; + var seg = selected.segment; + var tSegment = (offset - startDist) / seg.length; + var segDt = seg.t1 - seg.t0; + var t = isSrc ? seg.t0 + segDt * tSegment : seg.t1 - segDt * tSegment; + t = bound(0, t, 1); + p = qbezierPtAt(cp.p0, cp.p1, cp.p2, t); + angle = bezierAngle(cp.p0, cp.p1, cp.p2, t); + break; + } + case 'straight': + case 'segments': + case 'haystack': + { + var d = 0, + di, + d0; + var p0, p1; + var l = rs.allpts.length; + for (var _i2 = 0; _i2 + 3 < l; _i2 += 2) { + if (isSrc) { + p0 = { + x: rs.allpts[_i2], + y: rs.allpts[_i2 + 1] + }; + p1 = { + x: rs.allpts[_i2 + 2], + y: rs.allpts[_i2 + 3] + }; + } else { + p0 = { + x: rs.allpts[l - 2 - _i2], + y: rs.allpts[l - 1 - _i2] + }; + p1 = { + x: rs.allpts[l - 4 - _i2], + y: rs.allpts[l - 3 - _i2] + }; + } + di = dist(p0, p1); + d0 = d; + d += di; + if (d >= offset) { + break; + } + } + var pD = offset - d0; + var _t = pD / di; + _t = bound(0, _t, 1); + p = lineAt(p0, p1, _t); + angle = lineAngle(p0, p1); + break; + } + } + setRs('labelX', prefix, p.x); + setRs('labelY', prefix, p.y); + setRs('labelAutoAngle', prefix, angle); + }; + calculateEndProjection('source'); + calculateEndProjection('target'); + this.applyLabelDimensions(edge); +}; +BRp$9.applyLabelDimensions = function (ele) { + this.applyPrefixedLabelDimensions(ele); + if (ele.isEdge()) { + this.applyPrefixedLabelDimensions(ele, 'source'); + this.applyPrefixedLabelDimensions(ele, 'target'); + } +}; +BRp$9.applyPrefixedLabelDimensions = function (ele, prefix) { + var _p = ele._private; + var text = this.getLabelText(ele, prefix); + var labelDims = this.calculateLabelDimensions(ele, text); + var lineHeight = ele.pstyle('line-height').pfValue; + var textWrap = ele.pstyle('text-wrap').strValue; + var lines = getPrefixedProperty(_p.rscratch, 'labelWrapCachedLines', prefix) || []; + var numLines = textWrap !== 'wrap' ? 1 : Math.max(lines.length, 1); + var normPerLineHeight = labelDims.height / numLines; + var labelLineHeight = normPerLineHeight * lineHeight; + var width = labelDims.width; + var height = labelDims.height + (numLines - 1) * (lineHeight - 1) * normPerLineHeight; + setPrefixedProperty(_p.rstyle, 'labelWidth', prefix, width); + setPrefixedProperty(_p.rscratch, 'labelWidth', prefix, width); + setPrefixedProperty(_p.rstyle, 'labelHeight', prefix, height); + setPrefixedProperty(_p.rscratch, 'labelHeight', prefix, height); + setPrefixedProperty(_p.rscratch, 'labelLineHeight', prefix, labelLineHeight); +}; +BRp$9.getLabelText = function (ele, prefix) { + var _p = ele._private; + var pfd = prefix ? prefix + '-' : ''; + var text = ele.pstyle(pfd + 'label').strValue; + var textTransform = ele.pstyle('text-transform').value; + var rscratch = function rscratch(propName, value) { + if (value) { + setPrefixedProperty(_p.rscratch, propName, prefix, value); + return value; + } else { + return getPrefixedProperty(_p.rscratch, propName, prefix); + } + }; + + // for empty text, skip all processing + if (!text) { + return ''; + } + if (textTransform == 'none') ; else if (textTransform == 'uppercase') { + text = text.toUpperCase(); + } else if (textTransform == 'lowercase') { + text = text.toLowerCase(); + } + var wrapStyle = ele.pstyle('text-wrap').value; + if (wrapStyle === 'wrap') { + var labelKey = rscratch('labelKey'); + + // save recalc if the label is the same as before + if (labelKey != null && rscratch('labelWrapKey') === labelKey) { + return rscratch('labelWrapCachedText'); + } + var zwsp = "\u200B"; + var lines = text.split('\n'); + var maxW = ele.pstyle('text-max-width').pfValue; + var overflow = ele.pstyle('text-overflow-wrap').value; + var overflowAny = overflow === 'anywhere'; + var wrappedLines = []; + var wordsRegex = /[\s\u200b]+/; + var wordSeparator = overflowAny ? '' : ' '; + for (var l = 0; l < lines.length; l++) { + var line = lines[l]; + var lineDims = this.calculateLabelDimensions(ele, line); + var lineW = lineDims.width; + if (overflowAny) { + var processedLine = line.split('').join(zwsp); + line = processedLine; + } + if (lineW > maxW) { + // line is too long + var words = line.split(wordsRegex); + var subline = ''; + for (var w = 0; w < words.length; w++) { + var word = words[w]; + var testLine = subline.length === 0 ? word : subline + wordSeparator + word; + var testDims = this.calculateLabelDimensions(ele, testLine); + var testW = testDims.width; + if (testW <= maxW) { + // word fits on current line + subline += word + wordSeparator; + } else { + // word starts new line + if (subline) { + wrappedLines.push(subline); + } + subline = word + wordSeparator; + } + } + + // if there's remaining text, put it in a wrapped line + if (!subline.match(/^[\s\u200b]+$/)) { + wrappedLines.push(subline); + } + } else { + // line is already short enough + wrappedLines.push(line); + } + } // for + + rscratch('labelWrapCachedLines', wrappedLines); + text = rscratch('labelWrapCachedText', wrappedLines.join('\n')); + rscratch('labelWrapKey', labelKey); + } else if (wrapStyle === 'ellipsis') { + var _maxW = ele.pstyle('text-max-width').pfValue; + var ellipsized = ''; + var ellipsis = "\u2026"; + var incLastCh = false; + if (this.calculateLabelDimensions(ele, text).width < _maxW) { + // the label already fits + return text; + } + for (var i = 0; i < text.length; i++) { + var widthWithNextCh = this.calculateLabelDimensions(ele, ellipsized + text[i] + ellipsis).width; + if (widthWithNextCh > _maxW) { + break; + } + ellipsized += text[i]; + if (i === text.length - 1) { + incLastCh = true; + } + } + if (!incLastCh) { + ellipsized += ellipsis; + } + return ellipsized; + } // if ellipsize + + return text; +}; +BRp$9.getLabelJustification = function (ele) { + var justification = ele.pstyle('text-justification').strValue; + var textHalign = ele.pstyle('text-halign').strValue; + if (justification === 'auto') { + if (ele.isNode()) { + switch (textHalign) { + case 'left': + return 'right'; + case 'right': + return 'left'; + default: + return 'center'; + } + } else { + return 'center'; + } + } else { + return justification; + } +}; +BRp$9.calculateLabelDimensions = function (ele, text) { + var r = this; + var cacheKey = hashString(text, ele._private.labelDimsKey); + var cache = r.labelDimCache || (r.labelDimCache = []); + var existingVal = cache[cacheKey]; + if (existingVal != null) { + return existingVal; + } + var padding = 0; // add padding around text dims, as the measurement isn't that accurate + var fStyle = ele.pstyle('font-style').strValue; + var size = ele.pstyle('font-size').pfValue; + var family = ele.pstyle('font-family').strValue; + var weight = ele.pstyle('font-weight').strValue; + var canvas = this.labelCalcCanvas; + var c2d = this.labelCalcCanvasContext; + if (!canvas) { + canvas = this.labelCalcCanvas = document.createElement('canvas'); + c2d = this.labelCalcCanvasContext = canvas.getContext('2d'); + var ds = canvas.style; + ds.position = 'absolute'; + ds.left = '-9999px'; + ds.top = '-9999px'; + ds.zIndex = '-1'; + ds.visibility = 'hidden'; + ds.pointerEvents = 'none'; + } + c2d.font = "".concat(fStyle, " ").concat(weight, " ").concat(size, "px ").concat(family); + var width = 0; + var height = 0; + var lines = text.split('\n'); + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + var metrics = c2d.measureText(line); + var w = Math.ceil(metrics.width); + var h = size; + width = Math.max(w, width); + height += h; + } + width += padding; + height += padding; + return cache[cacheKey] = { + width: width, + height: height + }; +}; +BRp$9.calculateLabelAngle = function (ele, prefix) { + var _p = ele._private; + var rs = _p.rscratch; + var isEdge = ele.isEdge(); + var prefixDash = prefix ? prefix + '-' : ''; + var rot = ele.pstyle(prefixDash + 'text-rotation'); + var rotStr = rot.strValue; + if (rotStr === 'none') { + return 0; + } else if (isEdge && rotStr === 'autorotate') { + return rs.labelAutoAngle; + } else if (rotStr === 'autorotate') { + return 0; + } else { + return rot.pfValue; + } +}; +BRp$9.calculateLabelAngles = function (ele) { + var r = this; + var isEdge = ele.isEdge(); + var _p = ele._private; + var rs = _p.rscratch; + rs.labelAngle = r.calculateLabelAngle(ele); + if (isEdge) { + rs.sourceLabelAngle = r.calculateLabelAngle(ele, 'source'); + rs.targetLabelAngle = r.calculateLabelAngle(ele, 'target'); + } +}; + +var BRp$8 = {}; +var TOO_SMALL_CUT_RECT = 28; +var warnedCutRect = false; +BRp$8.getNodeShape = function (node) { + var r = this; + var shape = node.pstyle('shape').value; + if (shape === 'cutrectangle' && (node.width() < TOO_SMALL_CUT_RECT || node.height() < TOO_SMALL_CUT_RECT)) { + if (!warnedCutRect) { + warn('The `cutrectangle` node shape can not be used at small sizes so `rectangle` is used instead'); + warnedCutRect = true; + } + return 'rectangle'; + } + if (node.isParent()) { + if (shape === 'rectangle' || shape === 'roundrectangle' || shape === 'round-rectangle' || shape === 'cutrectangle' || shape === 'cut-rectangle' || shape === 'barrel') { + return shape; + } else { + return 'rectangle'; + } + } + if (shape === 'polygon') { + var points = node.pstyle('shape-polygon-points').value; + return r.nodeShapes.makePolygon(points).name; + } + return shape; +}; + +var BRp$7 = {}; +BRp$7.registerCalculationListeners = function () { + var cy = this.cy; + var elesToUpdate = cy.collection(); + var r = this; + var enqueue = function enqueue(eles) { + var dirtyStyleCaches = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + elesToUpdate.merge(eles); + if (dirtyStyleCaches) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var _p = ele._private; + var rstyle = _p.rstyle; + rstyle.clean = false; + rstyle.cleanConnected = false; + } + } + }; + r.binder(cy).on('bounds.* dirty.*', function onDirtyBounds(e) { + var ele = e.target; + enqueue(ele); + }).on('style.* background.*', function onDirtyStyle(e) { + var ele = e.target; + enqueue(ele, false); + }); + var updateEleCalcs = function updateEleCalcs(willDraw) { + if (willDraw) { + var fns = r.onUpdateEleCalcsFns; + + // because we need to have up-to-date style (e.g. stylesheet mappers) + // before calculating rendered style (and pstyle might not be called yet) + elesToUpdate.cleanStyle(); + for (var i = 0; i < elesToUpdate.length; i++) { + var ele = elesToUpdate[i]; + var rstyle = ele._private.rstyle; + if (ele.isNode() && !rstyle.cleanConnected) { + enqueue(ele.connectedEdges()); + rstyle.cleanConnected = true; + } + } + if (fns) { + for (var _i = 0; _i < fns.length; _i++) { + var fn = fns[_i]; + fn(willDraw, elesToUpdate); + } + } + r.recalculateRenderedStyle(elesToUpdate); + elesToUpdate = cy.collection(); + } + }; + r.flushRenderedStyleQueue = function () { + updateEleCalcs(true); + }; + r.beforeRender(updateEleCalcs, r.beforeRenderPriorities.eleCalcs); +}; +BRp$7.onUpdateEleCalcs = function (fn) { + var fns = this.onUpdateEleCalcsFns = this.onUpdateEleCalcsFns || []; + fns.push(fn); +}; +BRp$7.recalculateRenderedStyle = function (eles, useCache) { + var isCleanConnected = function isCleanConnected(ele) { + return ele._private.rstyle.cleanConnected; + }; + var edges = []; + var nodes = []; + + // the renderer can't be used for calcs when destroyed, e.g. ele.boundingBox() + if (this.destroyed) { + return; + } + + // use cache by default for perf + if (useCache === undefined) { + useCache = true; + } + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var _p = ele._private; + var rstyle = _p.rstyle; + + // an edge may be implicitly dirty b/c of one of its connected nodes + // (and a request for recalc may come in between frames) + if (ele.isEdge() && (!isCleanConnected(ele.source()) || !isCleanConnected(ele.target()))) { + rstyle.clean = false; + } + + // only update if dirty and in graph + if (useCache && rstyle.clean || ele.removed()) { + continue; + } + + // only update if not display: none + if (ele.pstyle('display').value === 'none') { + continue; + } + if (_p.group === 'nodes') { + nodes.push(ele); + } else { + // edges + edges.push(ele); + } + rstyle.clean = true; + } + + // update node data from projections + for (var _i2 = 0; _i2 < nodes.length; _i2++) { + var _ele = nodes[_i2]; + var _p2 = _ele._private; + var _rstyle = _p2.rstyle; + var pos = _ele.position(); + this.recalculateNodeLabelProjection(_ele); + _rstyle.nodeX = pos.x; + _rstyle.nodeY = pos.y; + _rstyle.nodeW = _ele.pstyle('width').pfValue; + _rstyle.nodeH = _ele.pstyle('height').pfValue; + } + this.recalculateEdgeProjections(edges); + + // update edge data from projections + for (var _i3 = 0; _i3 < edges.length; _i3++) { + var _ele2 = edges[_i3]; + var _p3 = _ele2._private; + var _rstyle2 = _p3.rstyle; + var rs = _p3.rscratch; + + // update rstyle positions + _rstyle2.srcX = rs.arrowStartX; + _rstyle2.srcY = rs.arrowStartY; + _rstyle2.tgtX = rs.arrowEndX; + _rstyle2.tgtY = rs.arrowEndY; + _rstyle2.midX = rs.midX; + _rstyle2.midY = rs.midY; + _rstyle2.labelAngle = rs.labelAngle; + _rstyle2.sourceLabelAngle = rs.sourceLabelAngle; + _rstyle2.targetLabelAngle = rs.targetLabelAngle; + } +}; + +var BRp$6 = {}; +BRp$6.updateCachedGrabbedEles = function () { + var eles = this.cachedZSortedEles; + if (!eles) { + // just let this be recalculated on the next z sort tick + return; + } + eles.drag = []; + eles.nondrag = []; + var grabTargets = []; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var rs = ele._private.rscratch; + if (ele.grabbed() && !ele.isParent()) { + grabTargets.push(ele); + } else if (rs.inDragLayer) { + eles.drag.push(ele); + } else { + eles.nondrag.push(ele); + } + } + + // put the grab target nodes last so it's on top of its neighbourhood + for (var i = 0; i < grabTargets.length; i++) { + var ele = grabTargets[i]; + eles.drag.push(ele); + } +}; +BRp$6.invalidateCachedZSortedEles = function () { + this.cachedZSortedEles = null; +}; +BRp$6.getCachedZSortedEles = function (forceRecalc) { + if (forceRecalc || !this.cachedZSortedEles) { + var eles = this.cy.mutableElements().toArray(); + eles.sort(zIndexSort); + eles.interactive = eles.filter(function (ele) { + return ele.interactive(); + }); + this.cachedZSortedEles = eles; + this.updateCachedGrabbedEles(); + } else { + eles = this.cachedZSortedEles; + } + return eles; +}; + +var BRp$5 = {}; +[BRp$e, BRp$d, BRp$c, BRp$b, BRp$a, BRp$9, BRp$8, BRp$7, BRp$6].forEach(function (props) { + extend(BRp$5, props); +}); + +var BRp$4 = {}; +BRp$4.getCachedImage = function (url, crossOrigin, onLoad) { + var r = this; + var imageCache = r.imageCache = r.imageCache || {}; + var cache = imageCache[url]; + if (cache) { + if (!cache.image.complete) { + cache.image.addEventListener('load', onLoad); + } + return cache.image; + } else { + cache = imageCache[url] = imageCache[url] || {}; + var image = cache.image = new Image(); // eslint-disable-line no-undef + + image.addEventListener('load', onLoad); + image.addEventListener('error', function () { + image.error = true; + }); + + // #1582 safari doesn't load data uris with crossOrigin properly + // https://bugs.webkit.org/show_bug.cgi?id=123978 + var dataUriPrefix = 'data:'; + var isDataUri = url.substring(0, dataUriPrefix.length).toLowerCase() === dataUriPrefix; + if (!isDataUri) { + // if crossorigin is 'null'(stringified), then manually set it to null + crossOrigin = crossOrigin === 'null' ? null : crossOrigin; + image.crossOrigin = crossOrigin; // prevent tainted canvas + } + + image.src = url; + return image; + } +}; + +var BRp$3 = {}; + +/* global document, window, ResizeObserver, MutationObserver */ + +BRp$3.registerBinding = function (target, event, handler, useCapture) { + // eslint-disable-line no-unused-vars + var args = Array.prototype.slice.apply(arguments, [1]); // copy + var b = this.binder(target); + return b.on.apply(b, args); +}; +BRp$3.binder = function (tgt) { + var r = this; + var containerWindow = r.cy.window(); + var tgtIsDom = tgt === containerWindow || tgt === containerWindow.document || tgt === containerWindow.document.body || domElement(tgt); + if (r.supportsPassiveEvents == null) { + // from https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection + var supportsPassive = false; + try { + var opts = Object.defineProperty({}, 'passive', { + get: function get() { + supportsPassive = true; + return true; + } + }); + containerWindow.addEventListener('test', null, opts); + } catch (err) { + // not supported + } + r.supportsPassiveEvents = supportsPassive; + } + var on = function on(event, handler, useCapture) { + var args = Array.prototype.slice.call(arguments); + if (tgtIsDom && r.supportsPassiveEvents) { + // replace useCapture w/ opts obj + args[2] = { + capture: useCapture != null ? useCapture : false, + passive: false, + once: false + }; + } + r.bindings.push({ + target: tgt, + args: args + }); + (tgt.addEventListener || tgt.on).apply(tgt, args); + return this; + }; + return { + on: on, + addEventListener: on, + addListener: on, + bind: on + }; +}; +BRp$3.nodeIsDraggable = function (node) { + return node && node.isNode() && !node.locked() && node.grabbable(); +}; +BRp$3.nodeIsGrabbable = function (node) { + return this.nodeIsDraggable(node) && node.interactive(); +}; +BRp$3.load = function () { + var r = this; + var containerWindow = r.cy.window(); + var isSelected = function isSelected(ele) { + return ele.selected(); + }; + var triggerEvents = function triggerEvents(target, names, e, position) { + if (target == null) { + target = r.cy; + } + for (var i = 0; i < names.length; i++) { + var name = names[i]; + target.emit({ + originalEvent: e, + type: name, + position: position + }); + } + }; + var isMultSelKeyDown = function isMultSelKeyDown(e) { + return e.shiftKey || e.metaKey || e.ctrlKey; // maybe e.altKey + }; + + var allowPanningPassthrough = function allowPanningPassthrough(down, downs) { + var allowPassthrough = true; + if (r.cy.hasCompoundNodes() && down && down.pannable()) { + // a grabbable compound node below the ele => no passthrough panning + for (var i = 0; downs && i < downs.length; i++) { + var down = downs[i]; + + //if any parent node in event hierarchy isn't pannable, reject passthrough + if (down.isNode() && down.isParent() && !down.pannable()) { + allowPassthrough = false; + break; + } + } + } else { + allowPassthrough = true; + } + return allowPassthrough; + }; + var setGrabbed = function setGrabbed(ele) { + ele[0]._private.grabbed = true; + }; + var setFreed = function setFreed(ele) { + ele[0]._private.grabbed = false; + }; + var setInDragLayer = function setInDragLayer(ele) { + ele[0]._private.rscratch.inDragLayer = true; + }; + var setOutDragLayer = function setOutDragLayer(ele) { + ele[0]._private.rscratch.inDragLayer = false; + }; + var setGrabTarget = function setGrabTarget(ele) { + ele[0]._private.rscratch.isGrabTarget = true; + }; + var removeGrabTarget = function removeGrabTarget(ele) { + ele[0]._private.rscratch.isGrabTarget = false; + }; + var addToDragList = function addToDragList(ele, opts) { + var list = opts.addToList; + var listHasEle = list.has(ele); + if (!listHasEle && ele.grabbable() && !ele.locked()) { + list.merge(ele); + setGrabbed(ele); + } + }; + + // helper function to determine which child nodes and inner edges + // of a compound node to be dragged as well as the grabbed and selected nodes + var addDescendantsToDrag = function addDescendantsToDrag(node, opts) { + if (!node.cy().hasCompoundNodes()) { + return; + } + if (opts.inDragLayer == null && opts.addToList == null) { + return; + } // nothing to do + + var innerNodes = node.descendants(); + if (opts.inDragLayer) { + innerNodes.forEach(setInDragLayer); + innerNodes.connectedEdges().forEach(setInDragLayer); + } + if (opts.addToList) { + addToDragList(innerNodes, opts); + } + }; + + // adds the given nodes and its neighbourhood to the drag layer + var addNodesToDrag = function addNodesToDrag(nodes, opts) { + opts = opts || {}; + var hasCompoundNodes = nodes.cy().hasCompoundNodes(); + if (opts.inDragLayer) { + nodes.forEach(setInDragLayer); + nodes.neighborhood().stdFilter(function (ele) { + return !hasCompoundNodes || ele.isEdge(); + }).forEach(setInDragLayer); + } + if (opts.addToList) { + nodes.forEach(function (ele) { + addToDragList(ele, opts); + }); + } + addDescendantsToDrag(nodes, opts); // always add to drag + + // also add nodes and edges related to the topmost ancestor + updateAncestorsInDragLayer(nodes, { + inDragLayer: opts.inDragLayer + }); + r.updateCachedGrabbedEles(); + }; + var addNodeToDrag = addNodesToDrag; + var freeDraggedElements = function freeDraggedElements(grabbedEles) { + if (!grabbedEles) { + return; + } + + // just go over all elements rather than doing a bunch of (possibly expensive) traversals + r.getCachedZSortedEles().forEach(function (ele) { + setFreed(ele); + setOutDragLayer(ele); + removeGrabTarget(ele); + }); + r.updateCachedGrabbedEles(); + }; + + // helper function to determine which ancestor nodes and edges should go + // to the drag layer (or should be removed from drag layer). + var updateAncestorsInDragLayer = function updateAncestorsInDragLayer(node, opts) { + if (opts.inDragLayer == null && opts.addToList == null) { + return; + } // nothing to do + + if (!node.cy().hasCompoundNodes()) { + return; + } + + // find top-level parent + var parent = node.ancestors().orphans(); + + // no parent node: no nodes to add to the drag layer + if (parent.same(node)) { + return; + } + var nodes = parent.descendants().spawnSelf().merge(parent).unmerge(node).unmerge(node.descendants()); + var edges = nodes.connectedEdges(); + if (opts.inDragLayer) { + edges.forEach(setInDragLayer); + nodes.forEach(setInDragLayer); + } + if (opts.addToList) { + nodes.forEach(function (ele) { + addToDragList(ele, opts); + }); + } + }; + var blurActiveDomElement = function blurActiveDomElement() { + if (document.activeElement != null && document.activeElement.blur != null) { + document.activeElement.blur(); + } + }; + var haveMutationsApi = typeof MutationObserver !== 'undefined'; + var haveResizeObserverApi = typeof ResizeObserver !== 'undefined'; + + // watch for when the cy container is removed from the dom + if (haveMutationsApi) { + r.removeObserver = new MutationObserver(function (mutns) { + // eslint-disable-line no-undef + for (var i = 0; i < mutns.length; i++) { + var mutn = mutns[i]; + var rNodes = mutn.removedNodes; + if (rNodes) { + for (var j = 0; j < rNodes.length; j++) { + var rNode = rNodes[j]; + if (rNode === r.container) { + r.destroy(); + break; + } + } + } + } + }); + if (r.container.parentNode) { + r.removeObserver.observe(r.container.parentNode, { + childList: true + }); + } + } else { + r.registerBinding(r.container, 'DOMNodeRemoved', function (e) { + // eslint-disable-line no-unused-vars + r.destroy(); + }); + } + var onResize = debounce__default["default"](function () { + r.cy.resize(); + }, 100); + if (haveMutationsApi) { + r.styleObserver = new MutationObserver(onResize); // eslint-disable-line no-undef + + r.styleObserver.observe(r.container, { + attributes: true + }); + } + + // auto resize + r.registerBinding(containerWindow, 'resize', onResize); // eslint-disable-line no-undef + + if (haveResizeObserverApi) { + r.resizeObserver = new ResizeObserver(onResize); // eslint-disable-line no-undef + + r.resizeObserver.observe(r.container); + } + var forEachUp = function forEachUp(domEle, fn) { + while (domEle != null) { + fn(domEle); + domEle = domEle.parentNode; + } + }; + var invalidateCoords = function invalidateCoords() { + r.invalidateContainerClientCoordsCache(); + }; + forEachUp(r.container, function (domEle) { + r.registerBinding(domEle, 'transitionend', invalidateCoords); + r.registerBinding(domEle, 'animationend', invalidateCoords); + r.registerBinding(domEle, 'scroll', invalidateCoords); + }); + + // stop right click menu from appearing on cy + r.registerBinding(r.container, 'contextmenu', function (e) { + e.preventDefault(); + }); + var inBoxSelection = function inBoxSelection() { + return r.selection[4] !== 0; + }; + var eventInContainer = function eventInContainer(e) { + // save cycles if mouse events aren't to be captured + var containerPageCoords = r.findContainerClientCoords(); + var x = containerPageCoords[0]; + var y = containerPageCoords[1]; + var width = containerPageCoords[2]; + var height = containerPageCoords[3]; + var positions = e.touches ? e.touches : [e]; + var atLeastOnePosInside = false; + for (var i = 0; i < positions.length; i++) { + var p = positions[i]; + if (x <= p.clientX && p.clientX <= x + width && y <= p.clientY && p.clientY <= y + height) { + atLeastOnePosInside = true; + break; + } + } + if (!atLeastOnePosInside) { + return false; + } + var container = r.container; + var target = e.target; + var tParent = target.parentNode; + var containerIsTarget = false; + while (tParent) { + if (tParent === container) { + containerIsTarget = true; + break; + } + tParent = tParent.parentNode; + } + if (!containerIsTarget) { + return false; + } // if target is outisde cy container, then this event is not for us + + return true; + }; + + // Primary key + r.registerBinding(r.container, 'mousedown', function mousedownHandler(e) { + if (!eventInContainer(e)) { + return; + } + e.preventDefault(); + blurActiveDomElement(); + r.hoverData.capture = true; + r.hoverData.which = e.which; + var cy = r.cy; + var gpos = [e.clientX, e.clientY]; + var pos = r.projectIntoViewport(gpos[0], gpos[1]); + var select = r.selection; + var nears = r.findNearestElements(pos[0], pos[1], true, false); + var near = nears[0]; + var draggedElements = r.dragData.possibleDragElements; + r.hoverData.mdownPos = pos; + r.hoverData.mdownGPos = gpos; + var checkForTaphold = function checkForTaphold() { + r.hoverData.tapholdCancelled = false; + clearTimeout(r.hoverData.tapholdTimeout); + r.hoverData.tapholdTimeout = setTimeout(function () { + if (r.hoverData.tapholdCancelled) { + return; + } else { + var ele = r.hoverData.down; + if (ele) { + ele.emit({ + originalEvent: e, + type: 'taphold', + position: { + x: pos[0], + y: pos[1] + } + }); + } else { + cy.emit({ + originalEvent: e, + type: 'taphold', + position: { + x: pos[0], + y: pos[1] + } + }); + } + } + }, r.tapholdDuration); + }; + + // Right click button + if (e.which == 3) { + r.hoverData.cxtStarted = true; + var cxtEvt = { + originalEvent: e, + type: 'cxttapstart', + position: { + x: pos[0], + y: pos[1] + } + }; + if (near) { + near.activate(); + near.emit(cxtEvt); + r.hoverData.down = near; + } else { + cy.emit(cxtEvt); + } + r.hoverData.downTime = new Date().getTime(); + r.hoverData.cxtDragged = false; + + // Primary button + } else if (e.which == 1) { + if (near) { + near.activate(); + } + + // Element dragging + { + // If something is under the cursor and it is draggable, prepare to grab it + if (near != null) { + if (r.nodeIsGrabbable(near)) { + var makeEvent = function makeEvent(type) { + return { + originalEvent: e, + type: type, + position: { + x: pos[0], + y: pos[1] + } + }; + }; + var triggerGrab = function triggerGrab(ele) { + ele.emit(makeEvent('grab')); + }; + setGrabTarget(near); + if (!near.selected()) { + draggedElements = r.dragData.possibleDragElements = cy.collection(); + addNodeToDrag(near, { + addToList: draggedElements + }); + near.emit(makeEvent('grabon')).emit(makeEvent('grab')); + } else { + draggedElements = r.dragData.possibleDragElements = cy.collection(); + var selectedNodes = cy.$(function (ele) { + return ele.isNode() && ele.selected() && r.nodeIsGrabbable(ele); + }); + addNodesToDrag(selectedNodes, { + addToList: draggedElements + }); + near.emit(makeEvent('grabon')); + selectedNodes.forEach(triggerGrab); + } + r.redrawHint('eles', true); + r.redrawHint('drag', true); + } + } + r.hoverData.down = near; + r.hoverData.downs = nears; + r.hoverData.downTime = new Date().getTime(); + } + triggerEvents(near, ['mousedown', 'tapstart', 'vmousedown'], e, { + x: pos[0], + y: pos[1] + }); + if (near == null) { + select[4] = 1; + r.data.bgActivePosistion = { + x: pos[0], + y: pos[1] + }; + r.redrawHint('select', true); + r.redraw(); + } else if (near.pannable()) { + select[4] = 1; // for future pan + } + + checkForTaphold(); + } + + // Initialize selection box coordinates + select[0] = select[2] = pos[0]; + select[1] = select[3] = pos[1]; + }, false); + r.registerBinding(containerWindow, 'mousemove', function mousemoveHandler(e) { + // eslint-disable-line no-undef + var capture = r.hoverData.capture; + if (!capture && !eventInContainer(e)) { + return; + } + var preventDefault = false; + var cy = r.cy; + var zoom = cy.zoom(); + var gpos = [e.clientX, e.clientY]; + var pos = r.projectIntoViewport(gpos[0], gpos[1]); + var mdownPos = r.hoverData.mdownPos; + var mdownGPos = r.hoverData.mdownGPos; + var select = r.selection; + var near = null; + if (!r.hoverData.draggingEles && !r.hoverData.dragging && !r.hoverData.selecting) { + near = r.findNearestElement(pos[0], pos[1], true, false); + } + var last = r.hoverData.last; + var down = r.hoverData.down; + var disp = [pos[0] - select[2], pos[1] - select[3]]; + var draggedElements = r.dragData.possibleDragElements; + var isOverThresholdDrag; + if (mdownGPos) { + var dx = gpos[0] - mdownGPos[0]; + var dx2 = dx * dx; + var dy = gpos[1] - mdownGPos[1]; + var dy2 = dy * dy; + var dist2 = dx2 + dy2; + r.hoverData.isOverThresholdDrag = isOverThresholdDrag = dist2 >= r.desktopTapThreshold2; + } + var multSelKeyDown = isMultSelKeyDown(e); + if (isOverThresholdDrag) { + r.hoverData.tapholdCancelled = true; + } + var updateDragDelta = function updateDragDelta() { + var dragDelta = r.hoverData.dragDelta = r.hoverData.dragDelta || []; + if (dragDelta.length === 0) { + dragDelta.push(disp[0]); + dragDelta.push(disp[1]); + } else { + dragDelta[0] += disp[0]; + dragDelta[1] += disp[1]; + } + }; + preventDefault = true; + triggerEvents(near, ['mousemove', 'vmousemove', 'tapdrag'], e, { + x: pos[0], + y: pos[1] + }); + var goIntoBoxMode = function goIntoBoxMode() { + r.data.bgActivePosistion = undefined; + if (!r.hoverData.selecting) { + cy.emit({ + originalEvent: e, + type: 'boxstart', + position: { + x: pos[0], + y: pos[1] + } + }); + } + select[4] = 1; + r.hoverData.selecting = true; + r.redrawHint('select', true); + r.redraw(); + }; + + // trigger context drag if rmouse down + if (r.hoverData.which === 3) { + // but only if over threshold + if (isOverThresholdDrag) { + var cxtEvt = { + originalEvent: e, + type: 'cxtdrag', + position: { + x: pos[0], + y: pos[1] + } + }; + if (down) { + down.emit(cxtEvt); + } else { + cy.emit(cxtEvt); + } + r.hoverData.cxtDragged = true; + if (!r.hoverData.cxtOver || near !== r.hoverData.cxtOver) { + if (r.hoverData.cxtOver) { + r.hoverData.cxtOver.emit({ + originalEvent: e, + type: 'cxtdragout', + position: { + x: pos[0], + y: pos[1] + } + }); + } + r.hoverData.cxtOver = near; + if (near) { + near.emit({ + originalEvent: e, + type: 'cxtdragover', + position: { + x: pos[0], + y: pos[1] + } + }); + } + } + } + + // Check if we are drag panning the entire graph + } else if (r.hoverData.dragging) { + preventDefault = true; + if (cy.panningEnabled() && cy.userPanningEnabled()) { + var deltaP; + if (r.hoverData.justStartedPan) { + var mdPos = r.hoverData.mdownPos; + deltaP = { + x: (pos[0] - mdPos[0]) * zoom, + y: (pos[1] - mdPos[1]) * zoom + }; + r.hoverData.justStartedPan = false; + } else { + deltaP = { + x: disp[0] * zoom, + y: disp[1] * zoom + }; + } + cy.panBy(deltaP); + cy.emit('dragpan'); + r.hoverData.dragged = true; + } + + // Needs reproject due to pan changing viewport + pos = r.projectIntoViewport(e.clientX, e.clientY); + + // Checks primary button down & out of time & mouse not moved much + } else if (select[4] == 1 && (down == null || down.pannable())) { + if (isOverThresholdDrag) { + if (!r.hoverData.dragging && cy.boxSelectionEnabled() && (multSelKeyDown || !cy.panningEnabled() || !cy.userPanningEnabled())) { + goIntoBoxMode(); + } else if (!r.hoverData.selecting && cy.panningEnabled() && cy.userPanningEnabled()) { + var allowPassthrough = allowPanningPassthrough(down, r.hoverData.downs); + if (allowPassthrough) { + r.hoverData.dragging = true; + r.hoverData.justStartedPan = true; + select[4] = 0; + r.data.bgActivePosistion = array2point(mdownPos); + r.redrawHint('select', true); + r.redraw(); + } + } + if (down && down.pannable() && down.active()) { + down.unactivate(); + } + } + } else { + if (down && down.pannable() && down.active()) { + down.unactivate(); + } + if ((!down || !down.grabbed()) && near != last) { + if (last) { + triggerEvents(last, ['mouseout', 'tapdragout'], e, { + x: pos[0], + y: pos[1] + }); + } + if (near) { + triggerEvents(near, ['mouseover', 'tapdragover'], e, { + x: pos[0], + y: pos[1] + }); + } + r.hoverData.last = near; + } + if (down) { + if (isOverThresholdDrag) { + // then we can take action + + if (cy.boxSelectionEnabled() && multSelKeyDown) { + // then selection overrides + if (down && down.grabbed()) { + freeDraggedElements(draggedElements); + down.emit('freeon'); + draggedElements.emit('free'); + if (r.dragData.didDrag) { + down.emit('dragfreeon'); + draggedElements.emit('dragfree'); + } + } + goIntoBoxMode(); + } else if (down && down.grabbed() && r.nodeIsDraggable(down)) { + // drag node + var justStartedDrag = !r.dragData.didDrag; + if (justStartedDrag) { + r.redrawHint('eles', true); + } + r.dragData.didDrag = true; // indicate that we actually did drag the node + + // now, add the elements to the drag layer if not done already + if (!r.hoverData.draggingEles) { + addNodesToDrag(draggedElements, { + inDragLayer: true + }); + } + var totalShift = { + x: 0, + y: 0 + }; + if (number$1(disp[0]) && number$1(disp[1])) { + totalShift.x += disp[0]; + totalShift.y += disp[1]; + if (justStartedDrag) { + var dragDelta = r.hoverData.dragDelta; + if (dragDelta && number$1(dragDelta[0]) && number$1(dragDelta[1])) { + totalShift.x += dragDelta[0]; + totalShift.y += dragDelta[1]; + } + } + } + r.hoverData.draggingEles = true; + draggedElements.silentShift(totalShift).emit('position drag'); + r.redrawHint('drag', true); + r.redraw(); + } + } else { + // otherwise save drag delta for when we actually start dragging so the relative grab pos is constant + updateDragDelta(); + } + } + + // prevent the dragging from triggering text selection on the page + preventDefault = true; + } + select[2] = pos[0]; + select[3] = pos[1]; + if (preventDefault) { + if (e.stopPropagation) e.stopPropagation(); + if (e.preventDefault) e.preventDefault(); + return false; + } + }, false); + var clickTimeout, didDoubleClick, prevClickTimeStamp; + r.registerBinding(containerWindow, 'mouseup', function mouseupHandler(e) { + // eslint-disable-line no-undef + var capture = r.hoverData.capture; + if (!capture) { + return; + } + r.hoverData.capture = false; + var cy = r.cy; + var pos = r.projectIntoViewport(e.clientX, e.clientY); + var select = r.selection; + var near = r.findNearestElement(pos[0], pos[1], true, false); + var draggedElements = r.dragData.possibleDragElements; + var down = r.hoverData.down; + var multSelKeyDown = isMultSelKeyDown(e); + if (r.data.bgActivePosistion) { + r.redrawHint('select', true); + r.redraw(); + } + r.hoverData.tapholdCancelled = true; + r.data.bgActivePosistion = undefined; // not active bg now + + if (down) { + down.unactivate(); + } + if (r.hoverData.which === 3) { + var cxtEvt = { + originalEvent: e, + type: 'cxttapend', + position: { + x: pos[0], + y: pos[1] + } + }; + if (down) { + down.emit(cxtEvt); + } else { + cy.emit(cxtEvt); + } + if (!r.hoverData.cxtDragged) { + var cxtTap = { + originalEvent: e, + type: 'cxttap', + position: { + x: pos[0], + y: pos[1] + } + }; + if (down) { + down.emit(cxtTap); + } else { + cy.emit(cxtTap); + } + } + r.hoverData.cxtDragged = false; + r.hoverData.which = null; + } else if (r.hoverData.which === 1) { + triggerEvents(near, ['mouseup', 'tapend', 'vmouseup'], e, { + x: pos[0], + y: pos[1] + }); + if (!r.dragData.didDrag && + // didn't move a node around + !r.hoverData.dragged && + // didn't pan + !r.hoverData.selecting && + // not box selection + !r.hoverData.isOverThresholdDrag // didn't move too much + ) { + triggerEvents(down, ["click", "tap", "vclick"], e, { + x: pos[0], + y: pos[1] + }); + didDoubleClick = false; + if (e.timeStamp - prevClickTimeStamp <= cy.multiClickDebounceTime()) { + clickTimeout && clearTimeout(clickTimeout); + didDoubleClick = true; + prevClickTimeStamp = null; + triggerEvents(down, ["dblclick", "dbltap", "vdblclick"], e, { + x: pos[0], + y: pos[1] + }); + } else { + clickTimeout = setTimeout(function () { + if (didDoubleClick) return; + triggerEvents(down, ["oneclick", "onetap", "voneclick"], e, { + x: pos[0], + y: pos[1] + }); + }, cy.multiClickDebounceTime()); + prevClickTimeStamp = e.timeStamp; + } + } + + // Deselect all elements if nothing is currently under the mouse cursor and we aren't dragging something + if (down == null // not mousedown on node + && !r.dragData.didDrag // didn't move the node around + && !r.hoverData.selecting // not box selection + && !r.hoverData.dragged // didn't pan + && !isMultSelKeyDown(e)) { + cy.$(isSelected).unselect(['tapunselect']); + if (draggedElements.length > 0) { + r.redrawHint('eles', true); + } + r.dragData.possibleDragElements = draggedElements = cy.collection(); + } + + // Single selection + if (near == down && !r.dragData.didDrag && !r.hoverData.selecting) { + if (near != null && near._private.selectable) { + if (r.hoverData.dragging) ; else if (cy.selectionType() === 'additive' || multSelKeyDown) { + if (near.selected()) { + near.unselect(['tapunselect']); + } else { + near.select(['tapselect']); + } + } else { + if (!multSelKeyDown) { + cy.$(isSelected).unmerge(near).unselect(['tapunselect']); + near.select(['tapselect']); + } + } + r.redrawHint('eles', true); + } + } + if (r.hoverData.selecting) { + var box = cy.collection(r.getAllInBox(select[0], select[1], select[2], select[3])); + r.redrawHint('select', true); + if (box.length > 0) { + r.redrawHint('eles', true); + } + cy.emit({ + type: 'boxend', + originalEvent: e, + position: { + x: pos[0], + y: pos[1] + } + }); + var eleWouldBeSelected = function eleWouldBeSelected(ele) { + return ele.selectable() && !ele.selected(); + }; + if (cy.selectionType() === 'additive') { + box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect'); + } else { + if (!multSelKeyDown) { + cy.$(isSelected).unmerge(box).unselect(); + } + box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect'); + } + + // always need redraw in case eles unselectable + r.redraw(); + } + + // Cancel drag pan + if (r.hoverData.dragging) { + r.hoverData.dragging = false; + r.redrawHint('select', true); + r.redrawHint('eles', true); + r.redraw(); + } + if (!select[4]) { + r.redrawHint('drag', true); + r.redrawHint('eles', true); + var downWasGrabbed = down && down.grabbed(); + freeDraggedElements(draggedElements); + if (downWasGrabbed) { + down.emit('freeon'); + draggedElements.emit('free'); + if (r.dragData.didDrag) { + down.emit('dragfreeon'); + draggedElements.emit('dragfree'); + } + } + } + } // else not right mouse + + select[4] = 0; + r.hoverData.down = null; + r.hoverData.cxtStarted = false; + r.hoverData.draggingEles = false; + r.hoverData.selecting = false; + r.hoverData.isOverThresholdDrag = false; + r.dragData.didDrag = false; + r.hoverData.dragged = false; + r.hoverData.dragDelta = []; + r.hoverData.mdownPos = null; + r.hoverData.mdownGPos = null; + }, false); + var wheelHandler = function wheelHandler(e) { + if (r.scrollingPage) { + return; + } // while scrolling, ignore wheel-to-zoom + + var cy = r.cy; + var zoom = cy.zoom(); + var pan = cy.pan(); + var pos = r.projectIntoViewport(e.clientX, e.clientY); + var rpos = [pos[0] * zoom + pan.x, pos[1] * zoom + pan.y]; + if (r.hoverData.draggingEles || r.hoverData.dragging || r.hoverData.cxtStarted || inBoxSelection()) { + // if pan dragging or cxt dragging, wheel movements make no zoom + e.preventDefault(); + return; + } + if (cy.panningEnabled() && cy.userPanningEnabled() && cy.zoomingEnabled() && cy.userZoomingEnabled()) { + e.preventDefault(); + r.data.wheelZooming = true; + clearTimeout(r.data.wheelTimeout); + r.data.wheelTimeout = setTimeout(function () { + r.data.wheelZooming = false; + r.redrawHint('eles', true); + r.redraw(); + }, 150); + var diff; + if (e.deltaY != null) { + diff = e.deltaY / -250; + } else if (e.wheelDeltaY != null) { + diff = e.wheelDeltaY / 1000; + } else { + diff = e.wheelDelta / 1000; + } + diff = diff * r.wheelSensitivity; + var needsWheelFix = e.deltaMode === 1; + if (needsWheelFix) { + // fixes slow wheel events on ff/linux and ff/windows + diff *= 33; + } + var newZoom = cy.zoom() * Math.pow(10, diff); + if (e.type === 'gesturechange') { + newZoom = r.gestureStartZoom * e.scale; + } + cy.zoom({ + level: newZoom, + renderedPosition: { + x: rpos[0], + y: rpos[1] + } + }); + cy.emit(e.type === 'gesturechange' ? 'pinchzoom' : 'scrollzoom'); + } + }; + + // Functions to help with whether mouse wheel should trigger zooming + // -- + r.registerBinding(r.container, 'wheel', wheelHandler, true); + + // disable nonstandard wheel events + // r.registerBinding(r.container, 'mousewheel', wheelHandler, true); + // r.registerBinding(r.container, 'DOMMouseScroll', wheelHandler, true); + // r.registerBinding(r.container, 'MozMousePixelScroll', wheelHandler, true); // older firefox + + r.registerBinding(containerWindow, 'scroll', function scrollHandler(e) { + // eslint-disable-line no-unused-vars + r.scrollingPage = true; + clearTimeout(r.scrollingPageTimeout); + r.scrollingPageTimeout = setTimeout(function () { + r.scrollingPage = false; + }, 250); + }, true); + + // desktop safari pinch to zoom start + r.registerBinding(r.container, 'gesturestart', function gestureStartHandler(e) { + r.gestureStartZoom = r.cy.zoom(); + if (!r.hasTouchStarted) { + // don't affect touch devices like iphone + e.preventDefault(); + } + }, true); + r.registerBinding(r.container, 'gesturechange', function (e) { + if (!r.hasTouchStarted) { + // don't affect touch devices like iphone + wheelHandler(e); + } + }, true); + + // Functions to help with handling mouseout/mouseover on the Cytoscape container + // Handle mouseout on Cytoscape container + r.registerBinding(r.container, 'mouseout', function mouseOutHandler(e) { + var pos = r.projectIntoViewport(e.clientX, e.clientY); + r.cy.emit({ + originalEvent: e, + type: 'mouseout', + position: { + x: pos[0], + y: pos[1] + } + }); + }, false); + r.registerBinding(r.container, 'mouseover', function mouseOverHandler(e) { + var pos = r.projectIntoViewport(e.clientX, e.clientY); + r.cy.emit({ + originalEvent: e, + type: 'mouseover', + position: { + x: pos[0], + y: pos[1] + } + }); + }, false); + var f1x1, f1y1, f2x1, f2y1; // starting points for pinch-to-zoom + var distance1, distance1Sq; // initial distance between finger 1 and finger 2 for pinch-to-zoom + var center1, modelCenter1; // center point on start pinch to zoom + var offsetLeft, offsetTop; + var containerWidth, containerHeight; + var twoFingersStartInside; + var distance = function distance(x1, y1, x2, y2) { + return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + }; + var distanceSq = function distanceSq(x1, y1, x2, y2) { + return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); + }; + var touchstartHandler; + r.registerBinding(r.container, 'touchstart', touchstartHandler = function touchstartHandler(e) { + r.hasTouchStarted = true; + if (!eventInContainer(e)) { + return; + } + blurActiveDomElement(); + r.touchData.capture = true; + r.data.bgActivePosistion = undefined; + var cy = r.cy; + var now = r.touchData.now; + var earlier = r.touchData.earlier; + if (e.touches[0]) { + var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); + now[0] = pos[0]; + now[1] = pos[1]; + } + if (e.touches[1]) { + var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY); + now[2] = pos[0]; + now[3] = pos[1]; + } + if (e.touches[2]) { + var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY); + now[4] = pos[0]; + now[5] = pos[1]; + } + + // record starting points for pinch-to-zoom + if (e.touches[1]) { + r.touchData.singleTouchMoved = true; + freeDraggedElements(r.dragData.touchDragEles); + var offsets = r.findContainerClientCoords(); + offsetLeft = offsets[0]; + offsetTop = offsets[1]; + containerWidth = offsets[2]; + containerHeight = offsets[3]; + f1x1 = e.touches[0].clientX - offsetLeft; + f1y1 = e.touches[0].clientY - offsetTop; + f2x1 = e.touches[1].clientX - offsetLeft; + f2y1 = e.touches[1].clientY - offsetTop; + twoFingersStartInside = 0 <= f1x1 && f1x1 <= containerWidth && 0 <= f2x1 && f2x1 <= containerWidth && 0 <= f1y1 && f1y1 <= containerHeight && 0 <= f2y1 && f2y1 <= containerHeight; + var pan = cy.pan(); + var zoom = cy.zoom(); + distance1 = distance(f1x1, f1y1, f2x1, f2y1); + distance1Sq = distanceSq(f1x1, f1y1, f2x1, f2y1); + center1 = [(f1x1 + f2x1) / 2, (f1y1 + f2y1) / 2]; + modelCenter1 = [(center1[0] - pan.x) / zoom, (center1[1] - pan.y) / zoom]; + + // consider context tap + var cxtDistThreshold = 200; + var cxtDistThresholdSq = cxtDistThreshold * cxtDistThreshold; + if (distance1Sq < cxtDistThresholdSq && !e.touches[2]) { + var near1 = r.findNearestElement(now[0], now[1], true, true); + var near2 = r.findNearestElement(now[2], now[3], true, true); + if (near1 && near1.isNode()) { + near1.activate().emit({ + originalEvent: e, + type: 'cxttapstart', + position: { + x: now[0], + y: now[1] + } + }); + r.touchData.start = near1; + } else if (near2 && near2.isNode()) { + near2.activate().emit({ + originalEvent: e, + type: 'cxttapstart', + position: { + x: now[0], + y: now[1] + } + }); + r.touchData.start = near2; + } else { + cy.emit({ + originalEvent: e, + type: 'cxttapstart', + position: { + x: now[0], + y: now[1] + } + }); + } + if (r.touchData.start) { + r.touchData.start._private.grabbed = false; + } + r.touchData.cxt = true; + r.touchData.cxtDragged = false; + r.data.bgActivePosistion = undefined; + r.redraw(); + return; + } + } + if (e.touches[2]) { + // ignore + + // safari on ios pans the page otherwise (normally you should be able to preventdefault on touchmove...) + if (cy.boxSelectionEnabled()) { + e.preventDefault(); + } + } else if (e.touches[1]) ; else if (e.touches[0]) { + var nears = r.findNearestElements(now[0], now[1], true, true); + var near = nears[0]; + if (near != null) { + near.activate(); + r.touchData.start = near; + r.touchData.starts = nears; + if (r.nodeIsGrabbable(near)) { + var draggedEles = r.dragData.touchDragEles = cy.collection(); + var selectedNodes = null; + r.redrawHint('eles', true); + r.redrawHint('drag', true); + if (near.selected()) { + // reset drag elements, since near will be added again + + selectedNodes = cy.$(function (ele) { + return ele.selected() && r.nodeIsGrabbable(ele); + }); + addNodesToDrag(selectedNodes, { + addToList: draggedEles + }); + } else { + addNodeToDrag(near, { + addToList: draggedEles + }); + } + setGrabTarget(near); + var makeEvent = function makeEvent(type) { + return { + originalEvent: e, + type: type, + position: { + x: now[0], + y: now[1] + } + }; + }; + near.emit(makeEvent('grabon')); + if (selectedNodes) { + selectedNodes.forEach(function (n) { + n.emit(makeEvent('grab')); + }); + } else { + near.emit(makeEvent('grab')); + } + } + } + triggerEvents(near, ['touchstart', 'tapstart', 'vmousedown'], e, { + x: now[0], + y: now[1] + }); + if (near == null) { + r.data.bgActivePosistion = { + x: pos[0], + y: pos[1] + }; + r.redrawHint('select', true); + r.redraw(); + } + + // Tap, taphold + // ----- + + r.touchData.singleTouchMoved = false; + r.touchData.singleTouchStartTime = +new Date(); + clearTimeout(r.touchData.tapholdTimeout); + r.touchData.tapholdTimeout = setTimeout(function () { + if (r.touchData.singleTouchMoved === false && !r.pinching // if pinching, then taphold unselect shouldn't take effect + && !r.touchData.selecting // box selection shouldn't allow taphold through + ) { + triggerEvents(r.touchData.start, ['taphold'], e, { + x: now[0], + y: now[1] + }); + } + }, r.tapholdDuration); + } + if (e.touches.length >= 1) { + var sPos = r.touchData.startPosition = [null, null, null, null, null, null]; + for (var i = 0; i < now.length; i++) { + sPos[i] = earlier[i] = now[i]; + } + var touch0 = e.touches[0]; + r.touchData.startGPosition = [touch0.clientX, touch0.clientY]; + } + }, false); + var touchmoveHandler; + r.registerBinding(window, 'touchmove', touchmoveHandler = function touchmoveHandler(e) { + // eslint-disable-line no-undef + var capture = r.touchData.capture; + if (!capture && !eventInContainer(e)) { + return; + } + var select = r.selection; + var cy = r.cy; + var now = r.touchData.now; + var earlier = r.touchData.earlier; + var zoom = cy.zoom(); + if (e.touches[0]) { + var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); + now[0] = pos[0]; + now[1] = pos[1]; + } + if (e.touches[1]) { + var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY); + now[2] = pos[0]; + now[3] = pos[1]; + } + if (e.touches[2]) { + var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY); + now[4] = pos[0]; + now[5] = pos[1]; + } + var startGPos = r.touchData.startGPosition; + var isOverThresholdDrag; + if (capture && e.touches[0] && startGPos) { + var disp = []; + for (var j = 0; j < now.length; j++) { + disp[j] = now[j] - earlier[j]; + } + var dx = e.touches[0].clientX - startGPos[0]; + var dx2 = dx * dx; + var dy = e.touches[0].clientY - startGPos[1]; + var dy2 = dy * dy; + var dist2 = dx2 + dy2; + isOverThresholdDrag = dist2 >= r.touchTapThreshold2; + } + + // context swipe cancelling + if (capture && r.touchData.cxt) { + e.preventDefault(); + var f1x2 = e.touches[0].clientX - offsetLeft, + f1y2 = e.touches[0].clientY - offsetTop; + var f2x2 = e.touches[1].clientX - offsetLeft, + f2y2 = e.touches[1].clientY - offsetTop; + // var distance2 = distance( f1x2, f1y2, f2x2, f2y2 ); + var distance2Sq = distanceSq(f1x2, f1y2, f2x2, f2y2); + var factorSq = distance2Sq / distance1Sq; + var distThreshold = 150; + var distThresholdSq = distThreshold * distThreshold; + var factorThreshold = 1.5; + var factorThresholdSq = factorThreshold * factorThreshold; + + // cancel ctx gestures if the distance b/t the fingers increases + if (factorSq >= factorThresholdSq || distance2Sq >= distThresholdSq) { + r.touchData.cxt = false; + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + var cxtEvt = { + originalEvent: e, + type: 'cxttapend', + position: { + x: now[0], + y: now[1] + } + }; + if (r.touchData.start) { + r.touchData.start.unactivate().emit(cxtEvt); + r.touchData.start = null; + } else { + cy.emit(cxtEvt); + } + } + } + + // context swipe + if (capture && r.touchData.cxt) { + var cxtEvt = { + originalEvent: e, + type: 'cxtdrag', + position: { + x: now[0], + y: now[1] + } + }; + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + if (r.touchData.start) { + r.touchData.start.emit(cxtEvt); + } else { + cy.emit(cxtEvt); + } + if (r.touchData.start) { + r.touchData.start._private.grabbed = false; + } + r.touchData.cxtDragged = true; + var near = r.findNearestElement(now[0], now[1], true, true); + if (!r.touchData.cxtOver || near !== r.touchData.cxtOver) { + if (r.touchData.cxtOver) { + r.touchData.cxtOver.emit({ + originalEvent: e, + type: 'cxtdragout', + position: { + x: now[0], + y: now[1] + } + }); + } + r.touchData.cxtOver = near; + if (near) { + near.emit({ + originalEvent: e, + type: 'cxtdragover', + position: { + x: now[0], + y: now[1] + } + }); + } + } + + // box selection + } else if (capture && e.touches[2] && cy.boxSelectionEnabled()) { + e.preventDefault(); + r.data.bgActivePosistion = undefined; + this.lastThreeTouch = +new Date(); + if (!r.touchData.selecting) { + cy.emit({ + originalEvent: e, + type: 'boxstart', + position: { + x: now[0], + y: now[1] + } + }); + } + r.touchData.selecting = true; + r.touchData.didSelect = true; + select[4] = 1; + if (!select || select.length === 0 || select[0] === undefined) { + select[0] = (now[0] + now[2] + now[4]) / 3; + select[1] = (now[1] + now[3] + now[5]) / 3; + select[2] = (now[0] + now[2] + now[4]) / 3 + 1; + select[3] = (now[1] + now[3] + now[5]) / 3 + 1; + } else { + select[2] = (now[0] + now[2] + now[4]) / 3; + select[3] = (now[1] + now[3] + now[5]) / 3; + } + r.redrawHint('select', true); + r.redraw(); + + // pinch to zoom + } else if (capture && e.touches[1] && !r.touchData.didSelect // don't allow box selection to degrade to pinch-to-zoom + && cy.zoomingEnabled() && cy.panningEnabled() && cy.userZoomingEnabled() && cy.userPanningEnabled()) { + // two fingers => pinch to zoom + e.preventDefault(); + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + var draggedEles = r.dragData.touchDragEles; + if (draggedEles) { + r.redrawHint('drag', true); + for (var i = 0; i < draggedEles.length; i++) { + var de_p = draggedEles[i]._private; + de_p.grabbed = false; + de_p.rscratch.inDragLayer = false; + } + } + var _start = r.touchData.start; + + // (x2, y2) for fingers 1 and 2 + var f1x2 = e.touches[0].clientX - offsetLeft, + f1y2 = e.touches[0].clientY - offsetTop; + var f2x2 = e.touches[1].clientX - offsetLeft, + f2y2 = e.touches[1].clientY - offsetTop; + var distance2 = distance(f1x2, f1y2, f2x2, f2y2); + // var distance2Sq = distanceSq( f1x2, f1y2, f2x2, f2y2 ); + // var factor = Math.sqrt( distance2Sq ) / Math.sqrt( distance1Sq ); + var factor = distance2 / distance1; + if (twoFingersStartInside) { + // delta finger1 + var df1x = f1x2 - f1x1; + var df1y = f1y2 - f1y1; + + // delta finger 2 + var df2x = f2x2 - f2x1; + var df2y = f2y2 - f2y1; + + // translation is the normalised vector of the two fingers movement + // i.e. so pinching cancels out and moving together pans + var tx = (df1x + df2x) / 2; + var ty = (df1y + df2y) / 2; + + // now calculate the zoom + var zoom1 = cy.zoom(); + var zoom2 = zoom1 * factor; + var pan1 = cy.pan(); + + // the model center point converted to the current rendered pos + var ctrx = modelCenter1[0] * zoom1 + pan1.x; + var ctry = modelCenter1[1] * zoom1 + pan1.y; + var pan2 = { + x: -zoom2 / zoom1 * (ctrx - pan1.x - tx) + ctrx, + y: -zoom2 / zoom1 * (ctry - pan1.y - ty) + ctry + }; + + // remove dragged eles + if (_start && _start.active()) { + var draggedEles = r.dragData.touchDragEles; + freeDraggedElements(draggedEles); + r.redrawHint('drag', true); + r.redrawHint('eles', true); + _start.unactivate().emit('freeon'); + draggedEles.emit('free'); + if (r.dragData.didDrag) { + _start.emit('dragfreeon'); + draggedEles.emit('dragfree'); + } + } + cy.viewport({ + zoom: zoom2, + pan: pan2, + cancelOnFailedZoom: true + }); + cy.emit('pinchzoom'); + distance1 = distance2; + f1x1 = f1x2; + f1y1 = f1y2; + f2x1 = f2x2; + f2y1 = f2y2; + r.pinching = true; + } + + // Re-project + if (e.touches[0]) { + var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); + now[0] = pos[0]; + now[1] = pos[1]; + } + if (e.touches[1]) { + var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY); + now[2] = pos[0]; + now[3] = pos[1]; + } + if (e.touches[2]) { + var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY); + now[4] = pos[0]; + now[5] = pos[1]; + } + } else if (e.touches[0] && !r.touchData.didSelect // don't allow box selection to degrade to single finger events like panning + ) { + var start = r.touchData.start; + var last = r.touchData.last; + var near; + if (!r.hoverData.draggingEles && !r.swipePanning) { + near = r.findNearestElement(now[0], now[1], true, true); + } + if (capture && start != null) { + e.preventDefault(); + } + + // dragging nodes + if (capture && start != null && r.nodeIsDraggable(start)) { + if (isOverThresholdDrag) { + // then dragging can happen + var draggedEles = r.dragData.touchDragEles; + var justStartedDrag = !r.dragData.didDrag; + if (justStartedDrag) { + addNodesToDrag(draggedEles, { + inDragLayer: true + }); + } + r.dragData.didDrag = true; + var totalShift = { + x: 0, + y: 0 + }; + if (number$1(disp[0]) && number$1(disp[1])) { + totalShift.x += disp[0]; + totalShift.y += disp[1]; + if (justStartedDrag) { + r.redrawHint('eles', true); + var dragDelta = r.touchData.dragDelta; + if (dragDelta && number$1(dragDelta[0]) && number$1(dragDelta[1])) { + totalShift.x += dragDelta[0]; + totalShift.y += dragDelta[1]; + } + } + } + r.hoverData.draggingEles = true; + draggedEles.silentShift(totalShift).emit('position drag'); + r.redrawHint('drag', true); + if (r.touchData.startPosition[0] == earlier[0] && r.touchData.startPosition[1] == earlier[1]) { + r.redrawHint('eles', true); + } + r.redraw(); + } else { + // otherwise keep track of drag delta for later + var dragDelta = r.touchData.dragDelta = r.touchData.dragDelta || []; + if (dragDelta.length === 0) { + dragDelta.push(disp[0]); + dragDelta.push(disp[1]); + } else { + dragDelta[0] += disp[0]; + dragDelta[1] += disp[1]; + } + } + } + + // touchmove + { + triggerEvents(start || near, ['touchmove', 'tapdrag', 'vmousemove'], e, { + x: now[0], + y: now[1] + }); + if ((!start || !start.grabbed()) && near != last) { + if (last) { + last.emit({ + originalEvent: e, + type: 'tapdragout', + position: { + x: now[0], + y: now[1] + } + }); + } + if (near) { + near.emit({ + originalEvent: e, + type: 'tapdragover', + position: { + x: now[0], + y: now[1] + } + }); + } + } + r.touchData.last = near; + } + + // check to cancel taphold + if (capture) { + for (var i = 0; i < now.length; i++) { + if (now[i] && r.touchData.startPosition[i] && isOverThresholdDrag) { + r.touchData.singleTouchMoved = true; + } + } + } + + // panning + if (capture && (start == null || start.pannable()) && cy.panningEnabled() && cy.userPanningEnabled()) { + var allowPassthrough = allowPanningPassthrough(start, r.touchData.starts); + if (allowPassthrough) { + e.preventDefault(); + if (!r.data.bgActivePosistion) { + r.data.bgActivePosistion = array2point(r.touchData.startPosition); + } + if (r.swipePanning) { + cy.panBy({ + x: disp[0] * zoom, + y: disp[1] * zoom + }); + cy.emit('dragpan'); + } else if (isOverThresholdDrag) { + r.swipePanning = true; + cy.panBy({ + x: dx * zoom, + y: dy * zoom + }); + cy.emit('dragpan'); + if (start) { + start.unactivate(); + r.redrawHint('select', true); + r.touchData.start = null; + } + } + } + + // Re-project + var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); + now[0] = pos[0]; + now[1] = pos[1]; + } + } + for (var j = 0; j < now.length; j++) { + earlier[j] = now[j]; + } + + // the active bg indicator should be removed when making a swipe that is neither for dragging nodes or panning + if (capture && e.touches.length > 0 && !r.hoverData.draggingEles && !r.swipePanning && r.data.bgActivePosistion != null) { + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + r.redraw(); + } + }, false); + var touchcancelHandler; + r.registerBinding(containerWindow, 'touchcancel', touchcancelHandler = function touchcancelHandler(e) { + // eslint-disable-line no-unused-vars + var start = r.touchData.start; + r.touchData.capture = false; + if (start) { + start.unactivate(); + } + }); + var touchendHandler, didDoubleTouch, touchTimeout, prevTouchTimeStamp; + r.registerBinding(containerWindow, 'touchend', touchendHandler = function touchendHandler(e) { + // eslint-disable-line no-unused-vars + var start = r.touchData.start; + var capture = r.touchData.capture; + if (capture) { + if (e.touches.length === 0) { + r.touchData.capture = false; + } + e.preventDefault(); + } else { + return; + } + var select = r.selection; + r.swipePanning = false; + r.hoverData.draggingEles = false; + var cy = r.cy; + var zoom = cy.zoom(); + var now = r.touchData.now; + var earlier = r.touchData.earlier; + if (e.touches[0]) { + var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); + now[0] = pos[0]; + now[1] = pos[1]; + } + if (e.touches[1]) { + var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY); + now[2] = pos[0]; + now[3] = pos[1]; + } + if (e.touches[2]) { + var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY); + now[4] = pos[0]; + now[5] = pos[1]; + } + if (start) { + start.unactivate(); + } + var ctxTapend; + if (r.touchData.cxt) { + ctxTapend = { + originalEvent: e, + type: 'cxttapend', + position: { + x: now[0], + y: now[1] + } + }; + if (start) { + start.emit(ctxTapend); + } else { + cy.emit(ctxTapend); + } + if (!r.touchData.cxtDragged) { + var ctxTap = { + originalEvent: e, + type: 'cxttap', + position: { + x: now[0], + y: now[1] + } + }; + if (start) { + start.emit(ctxTap); + } else { + cy.emit(ctxTap); + } + } + if (r.touchData.start) { + r.touchData.start._private.grabbed = false; + } + r.touchData.cxt = false; + r.touchData.start = null; + r.redraw(); + return; + } + + // no more box selection if we don't have three fingers + if (!e.touches[2] && cy.boxSelectionEnabled() && r.touchData.selecting) { + r.touchData.selecting = false; + var box = cy.collection(r.getAllInBox(select[0], select[1], select[2], select[3])); + select[0] = undefined; + select[1] = undefined; + select[2] = undefined; + select[3] = undefined; + select[4] = 0; + r.redrawHint('select', true); + cy.emit({ + type: 'boxend', + originalEvent: e, + position: { + x: now[0], + y: now[1] + } + }); + var eleWouldBeSelected = function eleWouldBeSelected(ele) { + return ele.selectable() && !ele.selected(); + }; + box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect'); + if (box.nonempty()) { + r.redrawHint('eles', true); + } + r.redraw(); + } + if (start != null) { + start.unactivate(); + } + if (e.touches[2]) { + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + } else if (e.touches[1]) ; else if (e.touches[0]) ; else if (!e.touches[0]) { + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + var draggedEles = r.dragData.touchDragEles; + if (start != null) { + var startWasGrabbed = start._private.grabbed; + freeDraggedElements(draggedEles); + r.redrawHint('drag', true); + r.redrawHint('eles', true); + if (startWasGrabbed) { + start.emit('freeon'); + draggedEles.emit('free'); + if (r.dragData.didDrag) { + start.emit('dragfreeon'); + draggedEles.emit('dragfree'); + } + } + triggerEvents(start, ['touchend', 'tapend', 'vmouseup', 'tapdragout'], e, { + x: now[0], + y: now[1] + }); + start.unactivate(); + r.touchData.start = null; + } else { + var near = r.findNearestElement(now[0], now[1], true, true); + triggerEvents(near, ['touchend', 'tapend', 'vmouseup', 'tapdragout'], e, { + x: now[0], + y: now[1] + }); + } + var dx = r.touchData.startPosition[0] - now[0]; + var dx2 = dx * dx; + var dy = r.touchData.startPosition[1] - now[1]; + var dy2 = dy * dy; + var dist2 = dx2 + dy2; + var rdist2 = dist2 * zoom * zoom; + + // Tap event, roughly same as mouse click event for touch + if (!r.touchData.singleTouchMoved) { + if (!start) { + cy.$(':selected').unselect(['tapunselect']); + } + triggerEvents(start, ['tap', 'vclick'], e, { + x: now[0], + y: now[1] + }); + didDoubleTouch = false; + if (e.timeStamp - prevTouchTimeStamp <= cy.multiClickDebounceTime()) { + touchTimeout && clearTimeout(touchTimeout); + didDoubleTouch = true; + prevTouchTimeStamp = null; + triggerEvents(start, ['dbltap', 'vdblclick'], e, { + x: now[0], + y: now[1] + }); + } else { + touchTimeout = setTimeout(function () { + if (didDoubleTouch) return; + triggerEvents(start, ['onetap', 'voneclick'], e, { + x: now[0], + y: now[1] + }); + }, cy.multiClickDebounceTime()); + prevTouchTimeStamp = e.timeStamp; + } + } + + // Prepare to select the currently touched node, only if it hasn't been dragged past a certain distance + if (start != null && !r.dragData.didDrag // didn't drag nodes around + && start._private.selectable && rdist2 < r.touchTapThreshold2 && !r.pinching // pinch to zoom should not affect selection + ) { + if (cy.selectionType() === 'single') { + cy.$(isSelected).unmerge(start).unselect(['tapunselect']); + start.select(['tapselect']); + } else { + if (start.selected()) { + start.unselect(['tapunselect']); + } else { + start.select(['tapselect']); + } + } + r.redrawHint('eles', true); + } + r.touchData.singleTouchMoved = true; + } + for (var j = 0; j < now.length; j++) { + earlier[j] = now[j]; + } + r.dragData.didDrag = false; // reset for next touchstart + + if (e.touches.length === 0) { + r.touchData.dragDelta = []; + r.touchData.startPosition = [null, null, null, null, null, null]; + r.touchData.startGPosition = null; + r.touchData.didSelect = false; + } + if (e.touches.length < 2) { + if (e.touches.length === 1) { + // the old start global pos'n may not be the same finger that remains + r.touchData.startGPosition = [e.touches[0].clientX, e.touches[0].clientY]; + } + r.pinching = false; + r.redrawHint('eles', true); + r.redraw(); + } + + //r.redraw(); + }, false); + + // fallback compatibility layer for ms pointer events + if (typeof TouchEvent === 'undefined') { + var pointers = []; + var makeTouch = function makeTouch(e) { + return { + clientX: e.clientX, + clientY: e.clientY, + force: 1, + identifier: e.pointerId, + pageX: e.pageX, + pageY: e.pageY, + radiusX: e.width / 2, + radiusY: e.height / 2, + screenX: e.screenX, + screenY: e.screenY, + target: e.target + }; + }; + var makePointer = function makePointer(e) { + return { + event: e, + touch: makeTouch(e) + }; + }; + var addPointer = function addPointer(e) { + pointers.push(makePointer(e)); + }; + var removePointer = function removePointer(e) { + for (var i = 0; i < pointers.length; i++) { + var p = pointers[i]; + if (p.event.pointerId === e.pointerId) { + pointers.splice(i, 1); + return; + } + } + }; + var updatePointer = function updatePointer(e) { + var p = pointers.filter(function (p) { + return p.event.pointerId === e.pointerId; + })[0]; + p.event = e; + p.touch = makeTouch(e); + }; + var addTouchesToEvent = function addTouchesToEvent(e) { + e.touches = pointers.map(function (p) { + return p.touch; + }); + }; + var pointerIsMouse = function pointerIsMouse(e) { + return e.pointerType === 'mouse' || e.pointerType === 4; + }; + r.registerBinding(r.container, 'pointerdown', function (e) { + if (pointerIsMouse(e)) { + return; + } // mouse already handled + + e.preventDefault(); + addPointer(e); + addTouchesToEvent(e); + touchstartHandler(e); + }); + r.registerBinding(r.container, 'pointerup', function (e) { + if (pointerIsMouse(e)) { + return; + } // mouse already handled + + removePointer(e); + addTouchesToEvent(e); + touchendHandler(e); + }); + r.registerBinding(r.container, 'pointercancel', function (e) { + if (pointerIsMouse(e)) { + return; + } // mouse already handled + + removePointer(e); + addTouchesToEvent(e); + touchcancelHandler(e); + }); + r.registerBinding(r.container, 'pointermove', function (e) { + if (pointerIsMouse(e)) { + return; + } // mouse already handled + + e.preventDefault(); + updatePointer(e); + addTouchesToEvent(e); + touchmoveHandler(e); + }); + } +}; + +var BRp$2 = {}; +BRp$2.generatePolygon = function (name, points) { + return this.nodeShapes[name] = { + renderer: this, + name: name, + points: points, + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl('polygon', context, centerX, centerY, width, height, this.points); + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + return polygonIntersectLine(x, y, this.points, nodeX, nodeY, width / 2, height / 2, padding); + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + return pointInsidePolygon(x, y, this.points, centerX, centerY, width, height, [0, -1], padding); + } + }; +}; +BRp$2.generateEllipse = function () { + return this.nodeShapes['ellipse'] = { + renderer: this, + name: 'ellipse', + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height); + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + return intersectLineEllipse(x, y, nodeX, nodeY, width / 2 + padding, height / 2 + padding); + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + return checkInEllipse(x, y, width, height, centerX, centerY, padding); + } + }; +}; +BRp$2.generateRoundPolygon = function (name, points) { + // Pre-compute control points + // Since these points depend on the radius length (which in turns depend on the width/height of the node) we will only pre-compute + // the unit vectors. + // For simplicity the layout will be: + // [ p0, UnitVectorP0P1, p1, UniVectorP1P2, ..., pn, UnitVectorPnP0 ] + var allPoints = new Array(points.length * 2); + for (var i = 0; i < points.length / 2; i++) { + var sourceIndex = i * 2; + var destIndex = void 0; + if (i < points.length / 2 - 1) { + destIndex = (i + 1) * 2; + } else { + destIndex = 0; + } + allPoints[i * 4] = points[sourceIndex]; + allPoints[i * 4 + 1] = points[sourceIndex + 1]; + var xDest = points[destIndex] - points[sourceIndex]; + var yDest = points[destIndex + 1] - points[sourceIndex + 1]; + var norm = Math.sqrt(xDest * xDest + yDest * yDest); + allPoints[i * 4 + 2] = xDest / norm; + allPoints[i * 4 + 3] = yDest / norm; + } + return this.nodeShapes[name] = { + renderer: this, + name: name, + points: allPoints, + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl('round-polygon', context, centerX, centerY, width, height, this.points); + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + return roundPolygonIntersectLine(x, y, this.points, nodeX, nodeY, width, height); + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + return pointInsideRoundPolygon(x, y, this.points, centerX, centerY, width, height); + } + }; +}; +BRp$2.generateRoundRectangle = function () { + return this.nodeShapes['round-rectangle'] = this.nodeShapes['roundrectangle'] = { + renderer: this, + name: 'round-rectangle', + points: generateUnitNgonPointsFitToSquare(4, 0), + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height); + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + return roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding); + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + var cornerRadius = getRoundRectangleRadius(width, height); + var diam = cornerRadius * 2; + + // Check hBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - diam, [0, -1], padding)) { + return true; + } + + // Check vBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - diam, height, [0, -1], padding)) { + return true; + } + + // Check top left quarter circle + if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY - height / 2 + cornerRadius, padding)) { + return true; + } + + // Check top right quarter circle + if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY - height / 2 + cornerRadius, padding)) { + return true; + } + + // Check bottom right quarter circle + if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY + height / 2 - cornerRadius, padding)) { + return true; + } + + // Check bottom left quarter circle + if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY + height / 2 - cornerRadius, padding)) { + return true; + } + return false; + } + }; +}; +BRp$2.generateCutRectangle = function () { + return this.nodeShapes['cut-rectangle'] = this.nodeShapes['cutrectangle'] = { + renderer: this, + name: 'cut-rectangle', + cornerLength: getCutRectangleCornerLength(), + points: generateUnitNgonPointsFitToSquare(4, 0), + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height); + }, + generateCutTrianglePts: function generateCutTrianglePts(width, height, centerX, centerY) { + var cl = this.cornerLength; + var hh = height / 2; + var hw = width / 2; + var xBegin = centerX - hw; + var xEnd = centerX + hw; + var yBegin = centerY - hh; + var yEnd = centerY + hh; + + // points are in clockwise order, inner (imaginary) triangle pt on [4, 5] + return { + topLeft: [xBegin, yBegin + cl, xBegin + cl, yBegin, xBegin + cl, yBegin + cl], + topRight: [xEnd - cl, yBegin, xEnd, yBegin + cl, xEnd - cl, yBegin + cl], + bottomRight: [xEnd, yEnd - cl, xEnd - cl, yEnd, xEnd - cl, yEnd - cl], + bottomLeft: [xBegin + cl, yEnd, xBegin, yEnd - cl, xBegin + cl, yEnd - cl] + }; + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + var cPts = this.generateCutTrianglePts(width + 2 * padding, height + 2 * padding, nodeX, nodeY); + var pts = [].concat.apply([], [cPts.topLeft.splice(0, 4), cPts.topRight.splice(0, 4), cPts.bottomRight.splice(0, 4), cPts.bottomLeft.splice(0, 4)]); + return polygonIntersectLine(x, y, pts, nodeX, nodeY); + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + // Check hBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - 2 * this.cornerLength, [0, -1], padding)) { + return true; + } + + // Check vBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - 2 * this.cornerLength, height, [0, -1], padding)) { + return true; + } + var cutTrianglePts = this.generateCutTrianglePts(width, height, centerX, centerY); + return pointInsidePolygonPoints(x, y, cutTrianglePts.topLeft) || pointInsidePolygonPoints(x, y, cutTrianglePts.topRight) || pointInsidePolygonPoints(x, y, cutTrianglePts.bottomRight) || pointInsidePolygonPoints(x, y, cutTrianglePts.bottomLeft); + } + }; +}; +BRp$2.generateBarrel = function () { + return this.nodeShapes['barrel'] = { + renderer: this, + name: 'barrel', + points: generateUnitNgonPointsFitToSquare(4, 0), + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height); + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + // use two fixed t values for the bezier curve approximation + + var t0 = 0.15; + var t1 = 0.5; + var t2 = 0.85; + var bPts = this.generateBarrelBezierPts(width + 2 * padding, height + 2 * padding, nodeX, nodeY); + var approximateBarrelCurvePts = function approximateBarrelCurvePts(pts) { + // approximate curve pts based on the two t values + var m0 = qbezierPtAt({ + x: pts[0], + y: pts[1] + }, { + x: pts[2], + y: pts[3] + }, { + x: pts[4], + y: pts[5] + }, t0); + var m1 = qbezierPtAt({ + x: pts[0], + y: pts[1] + }, { + x: pts[2], + y: pts[3] + }, { + x: pts[4], + y: pts[5] + }, t1); + var m2 = qbezierPtAt({ + x: pts[0], + y: pts[1] + }, { + x: pts[2], + y: pts[3] + }, { + x: pts[4], + y: pts[5] + }, t2); + return [pts[0], pts[1], m0.x, m0.y, m1.x, m1.y, m2.x, m2.y, pts[4], pts[5]]; + }; + var pts = [].concat(approximateBarrelCurvePts(bPts.topLeft), approximateBarrelCurvePts(bPts.topRight), approximateBarrelCurvePts(bPts.bottomRight), approximateBarrelCurvePts(bPts.bottomLeft)); + return polygonIntersectLine(x, y, pts, nodeX, nodeY); + }, + generateBarrelBezierPts: function generateBarrelBezierPts(width, height, centerX, centerY) { + var hh = height / 2; + var hw = width / 2; + var xBegin = centerX - hw; + var xEnd = centerX + hw; + var yBegin = centerY - hh; + var yEnd = centerY + hh; + var curveConstants = getBarrelCurveConstants(width, height); + var hOffset = curveConstants.heightOffset; + var wOffset = curveConstants.widthOffset; + var ctrlPtXOffset = curveConstants.ctrlPtOffsetPct * width; + + // points are in clockwise order, inner (imaginary) control pt on [4, 5] + var pts = { + topLeft: [xBegin, yBegin + hOffset, xBegin + ctrlPtXOffset, yBegin, xBegin + wOffset, yBegin], + topRight: [xEnd - wOffset, yBegin, xEnd - ctrlPtXOffset, yBegin, xEnd, yBegin + hOffset], + bottomRight: [xEnd, yEnd - hOffset, xEnd - ctrlPtXOffset, yEnd, xEnd - wOffset, yEnd], + bottomLeft: [xBegin + wOffset, yEnd, xBegin + ctrlPtXOffset, yEnd, xBegin, yEnd - hOffset] + }; + pts.topLeft.isTop = true; + pts.topRight.isTop = true; + pts.bottomLeft.isBottom = true; + pts.bottomRight.isBottom = true; + return pts; + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + var curveConstants = getBarrelCurveConstants(width, height); + var hOffset = curveConstants.heightOffset; + var wOffset = curveConstants.widthOffset; + + // Check hBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - 2 * hOffset, [0, -1], padding)) { + return true; + } + + // Check vBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - 2 * wOffset, height, [0, -1], padding)) { + return true; + } + var barrelCurvePts = this.generateBarrelBezierPts(width, height, centerX, centerY); + var getCurveT = function getCurveT(x, y, curvePts) { + var x0 = curvePts[4]; + var x1 = curvePts[2]; + var x2 = curvePts[0]; + var y0 = curvePts[5]; + // var y1 = curvePts[ 3 ]; + var y2 = curvePts[1]; + var xMin = Math.min(x0, x2); + var xMax = Math.max(x0, x2); + var yMin = Math.min(y0, y2); + var yMax = Math.max(y0, y2); + if (xMin <= x && x <= xMax && yMin <= y && y <= yMax) { + var coeff = bezierPtsToQuadCoeff(x0, x1, x2); + var roots = solveQuadratic(coeff[0], coeff[1], coeff[2], x); + var validRoots = roots.filter(function (r) { + return 0 <= r && r <= 1; + }); + if (validRoots.length > 0) { + return validRoots[0]; + } + } + return null; + }; + var curveRegions = Object.keys(barrelCurvePts); + for (var i = 0; i < curveRegions.length; i++) { + var corner = curveRegions[i]; + var cornerPts = barrelCurvePts[corner]; + var t = getCurveT(x, y, cornerPts); + if (t == null) { + continue; + } + var y0 = cornerPts[5]; + var y1 = cornerPts[3]; + var y2 = cornerPts[1]; + var bezY = qbezierAt(y0, y1, y2, t); + if (cornerPts.isTop && bezY <= y) { + return true; + } + if (cornerPts.isBottom && y <= bezY) { + return true; + } + } + return false; + } + }; +}; +BRp$2.generateBottomRoundrectangle = function () { + return this.nodeShapes['bottom-round-rectangle'] = this.nodeShapes['bottomroundrectangle'] = { + renderer: this, + name: 'bottom-round-rectangle', + points: generateUnitNgonPointsFitToSquare(4, 0), + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height); + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + var topStartX = nodeX - (width / 2 + padding); + var topStartY = nodeY - (height / 2 + padding); + var topEndY = topStartY; + var topEndX = nodeX + (width / 2 + padding); + var topIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false); + if (topIntersections.length > 0) { + return topIntersections; + } + return roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding); + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + var cornerRadius = getRoundRectangleRadius(width, height); + var diam = 2 * cornerRadius; + + // Check hBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - diam, [0, -1], padding)) { + return true; + } + + // Check vBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - diam, height, [0, -1], padding)) { + return true; + } + + // check non-rounded top side + var outerWidth = width / 2 + 2 * padding; + var outerHeight = height / 2 + 2 * padding; + var points = [centerX - outerWidth, centerY - outerHeight, centerX - outerWidth, centerY, centerX + outerWidth, centerY, centerX + outerWidth, centerY - outerHeight]; + if (pointInsidePolygonPoints(x, y, points)) { + return true; + } + + // Check bottom right quarter circle + if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY + height / 2 - cornerRadius, padding)) { + return true; + } + + // Check bottom left quarter circle + if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY + height / 2 - cornerRadius, padding)) { + return true; + } + return false; + } + }; +}; +BRp$2.registerNodeShapes = function () { + var nodeShapes = this.nodeShapes = {}; + var renderer = this; + this.generateEllipse(); + this.generatePolygon('triangle', generateUnitNgonPointsFitToSquare(3, 0)); + this.generateRoundPolygon('round-triangle', generateUnitNgonPointsFitToSquare(3, 0)); + this.generatePolygon('rectangle', generateUnitNgonPointsFitToSquare(4, 0)); + nodeShapes['square'] = nodeShapes['rectangle']; + this.generateRoundRectangle(); + this.generateCutRectangle(); + this.generateBarrel(); + this.generateBottomRoundrectangle(); + { + var diamondPoints = [0, 1, 1, 0, 0, -1, -1, 0]; + this.generatePolygon('diamond', diamondPoints); + this.generateRoundPolygon('round-diamond', diamondPoints); + } + this.generatePolygon('pentagon', generateUnitNgonPointsFitToSquare(5, 0)); + this.generateRoundPolygon('round-pentagon', generateUnitNgonPointsFitToSquare(5, 0)); + this.generatePolygon('hexagon', generateUnitNgonPointsFitToSquare(6, 0)); + this.generateRoundPolygon('round-hexagon', generateUnitNgonPointsFitToSquare(6, 0)); + this.generatePolygon('heptagon', generateUnitNgonPointsFitToSquare(7, 0)); + this.generateRoundPolygon('round-heptagon', generateUnitNgonPointsFitToSquare(7, 0)); + this.generatePolygon('octagon', generateUnitNgonPointsFitToSquare(8, 0)); + this.generateRoundPolygon('round-octagon', generateUnitNgonPointsFitToSquare(8, 0)); + var star5Points = new Array(20); + { + var outerPoints = generateUnitNgonPoints(5, 0); + var innerPoints = generateUnitNgonPoints(5, Math.PI / 5); + + // Outer radius is 1; inner radius of star is smaller + var innerRadius = 0.5 * (3 - Math.sqrt(5)); + innerRadius *= 1.57; + for (var i = 0; i < innerPoints.length / 2; i++) { + innerPoints[i * 2] *= innerRadius; + innerPoints[i * 2 + 1] *= innerRadius; + } + for (var i = 0; i < 20 / 4; i++) { + star5Points[i * 4] = outerPoints[i * 2]; + star5Points[i * 4 + 1] = outerPoints[i * 2 + 1]; + star5Points[i * 4 + 2] = innerPoints[i * 2]; + star5Points[i * 4 + 3] = innerPoints[i * 2 + 1]; + } + } + star5Points = fitPolygonToSquare(star5Points); + this.generatePolygon('star', star5Points); + this.generatePolygon('vee', [-1, -1, 0, -0.333, 1, -1, 0, 1]); + this.generatePolygon('rhomboid', [-1, -1, 0.333, -1, 1, 1, -0.333, 1]); + this.generatePolygon('right-rhomboid', [-0.333, -1, 1, -1, 0.333, 1, -1, 1]); + this.nodeShapes['concavehexagon'] = this.generatePolygon('concave-hexagon', [-1, -0.95, -0.75, 0, -1, 0.95, 1, 0.95, 0.75, 0, 1, -0.95]); + { + var tagPoints = [-1, -1, 0.25, -1, 1, 0, 0.25, 1, -1, 1]; + this.generatePolygon('tag', tagPoints); + this.generateRoundPolygon('round-tag', tagPoints); + } + nodeShapes.makePolygon = function (points) { + // use caching on user-specified polygons so they are as fast as native shapes + + var key = points.join('$'); + var name = 'polygon-' + key; + var shape; + if (shape = this[name]) { + // got cached shape + return shape; + } + + // create and cache new shape + return renderer.generatePolygon(name, points); + }; +}; + +var BRp$1 = {}; +BRp$1.timeToRender = function () { + return this.redrawTotalTime / this.redrawCount; +}; +BRp$1.redraw = function (options) { + options = options || staticEmptyObject(); + var r = this; + if (r.averageRedrawTime === undefined) { + r.averageRedrawTime = 0; + } + if (r.lastRedrawTime === undefined) { + r.lastRedrawTime = 0; + } + if (r.lastDrawTime === undefined) { + r.lastDrawTime = 0; + } + r.requestedFrame = true; + r.renderOptions = options; +}; +BRp$1.beforeRender = function (fn, priority) { + // the renderer can't add tick callbacks when destroyed + if (this.destroyed) { + return; + } + if (priority == null) { + error('Priority is not optional for beforeRender'); + } + var cbs = this.beforeRenderCallbacks; + cbs.push({ + fn: fn, + priority: priority + }); + + // higher priority callbacks executed first + cbs.sort(function (a, b) { + return b.priority - a.priority; + }); +}; +var beforeRenderCallbacks = function beforeRenderCallbacks(r, willDraw, startTime) { + var cbs = r.beforeRenderCallbacks; + for (var i = 0; i < cbs.length; i++) { + cbs[i].fn(willDraw, startTime); + } +}; +BRp$1.startRenderLoop = function () { + var r = this; + var cy = r.cy; + if (r.renderLoopStarted) { + return; + } else { + r.renderLoopStarted = true; + } + var renderFn = function renderFn(requestTime) { + if (r.destroyed) { + return; + } + if (cy.batching()) ; else if (r.requestedFrame && !r.skipFrame) { + beforeRenderCallbacks(r, true, requestTime); + var startTime = performanceNow(); + r.render(r.renderOptions); + var endTime = r.lastDrawTime = performanceNow(); + if (r.averageRedrawTime === undefined) { + r.averageRedrawTime = endTime - startTime; + } + if (r.redrawCount === undefined) { + r.redrawCount = 0; + } + r.redrawCount++; + if (r.redrawTotalTime === undefined) { + r.redrawTotalTime = 0; + } + var duration = endTime - startTime; + r.redrawTotalTime += duration; + r.lastRedrawTime = duration; + + // use a weighted average with a bias from the previous average so we don't spike so easily + r.averageRedrawTime = r.averageRedrawTime / 2 + duration / 2; + r.requestedFrame = false; + } else { + beforeRenderCallbacks(r, false, requestTime); + } + r.skipFrame = false; + requestAnimationFrame(renderFn); + }; + requestAnimationFrame(renderFn); +}; + +var BaseRenderer = function BaseRenderer(options) { + this.init(options); +}; +var BR = BaseRenderer; +var BRp = BR.prototype; +BRp.clientFunctions = ['redrawHint', 'render', 'renderTo', 'matchCanvasSize', 'nodeShapeImpl', 'arrowShapeImpl']; +BRp.init = function (options) { + var r = this; + r.options = options; + r.cy = options.cy; + var ctr = r.container = options.cy.container(); + var containerWindow = r.cy.window(); + + // prepend a stylesheet in the head such that + if (containerWindow) { + var document = containerWindow.document; + var head = document.head; + var stylesheetId = '__________cytoscape_stylesheet'; + var className = '__________cytoscape_container'; + var stylesheetAlreadyExists = document.getElementById(stylesheetId) != null; + if (ctr.className.indexOf(className) < 0) { + ctr.className = (ctr.className || '') + ' ' + className; + } + if (!stylesheetAlreadyExists) { + var stylesheet = document.createElement('style'); + stylesheet.id = stylesheetId; + stylesheet.textContent = '.' + className + ' { position: relative; }'; + head.insertBefore(stylesheet, head.children[0]); // first so lowest priority + } + + var computedStyle = containerWindow.getComputedStyle(ctr); + var position = computedStyle.getPropertyValue('position'); + if (position === 'static') { + warn('A Cytoscape container has style position:static and so can not use UI extensions properly'); + } + } + r.selection = [undefined, undefined, undefined, undefined, 0]; // Coordinates for selection box, plus enabled flag + + r.bezierProjPcts = [0.05, 0.225, 0.4, 0.5, 0.6, 0.775, 0.95]; + + //--Pointer-related data + r.hoverData = { + down: null, + last: null, + downTime: null, + triggerMode: null, + dragging: false, + initialPan: [null, null], + capture: false + }; + r.dragData = { + possibleDragElements: [] + }; + r.touchData = { + start: null, + capture: false, + // These 3 fields related to tap, taphold events + startPosition: [null, null, null, null, null, null], + singleTouchStartTime: null, + singleTouchMoved: true, + now: [null, null, null, null, null, null], + earlier: [null, null, null, null, null, null] + }; + r.redraws = 0; + r.showFps = options.showFps; + r.debug = options.debug; + r.hideEdgesOnViewport = options.hideEdgesOnViewport; + r.textureOnViewport = options.textureOnViewport; + r.wheelSensitivity = options.wheelSensitivity; + r.motionBlurEnabled = options.motionBlur; // on by default + r.forcedPixelRatio = number$1(options.pixelRatio) ? options.pixelRatio : null; + r.motionBlur = options.motionBlur; // for initial kick off + r.motionBlurOpacity = options.motionBlurOpacity; + r.motionBlurTransparency = 1 - r.motionBlurOpacity; + r.motionBlurPxRatio = 1; + r.mbPxRBlurry = 1; //0.8; + r.minMbLowQualFrames = 4; + r.fullQualityMb = false; + r.clearedForMotionBlur = []; + r.desktopTapThreshold = options.desktopTapThreshold; + r.desktopTapThreshold2 = options.desktopTapThreshold * options.desktopTapThreshold; + r.touchTapThreshold = options.touchTapThreshold; + r.touchTapThreshold2 = options.touchTapThreshold * options.touchTapThreshold; + r.tapholdDuration = 500; + r.bindings = []; + r.beforeRenderCallbacks = []; + r.beforeRenderPriorities = { + // higher priority execs before lower one + animations: 400, + eleCalcs: 300, + eleTxrDeq: 200, + lyrTxrDeq: 150, + lyrTxrSkip: 100 + }; + r.registerNodeShapes(); + r.registerArrowShapes(); + r.registerCalculationListeners(); +}; +BRp.notify = function (eventName, eles) { + var r = this; + var cy = r.cy; + + // the renderer can't be notified after it's destroyed + if (this.destroyed) { + return; + } + if (eventName === 'init') { + r.load(); + return; + } + if (eventName === 'destroy') { + r.destroy(); + return; + } + if (eventName === 'add' || eventName === 'remove' || eventName === 'move' && cy.hasCompoundNodes() || eventName === 'load' || eventName === 'zorder' || eventName === 'mount') { + r.invalidateCachedZSortedEles(); + } + if (eventName === 'viewport') { + r.redrawHint('select', true); + } + if (eventName === 'load' || eventName === 'resize' || eventName === 'mount') { + r.invalidateContainerClientCoordsCache(); + r.matchCanvasSize(r.container); + } + r.redrawHint('eles', true); + r.redrawHint('drag', true); + this.startRenderLoop(); + this.redraw(); +}; +BRp.destroy = function () { + var r = this; + r.destroyed = true; + r.cy.stopAnimationLoop(); + for (var i = 0; i < r.bindings.length; i++) { + var binding = r.bindings[i]; + var b = binding; + var tgt = b.target; + (tgt.off || tgt.removeEventListener).apply(tgt, b.args); + } + r.bindings = []; + r.beforeRenderCallbacks = []; + r.onUpdateEleCalcsFns = []; + if (r.removeObserver) { + r.removeObserver.disconnect(); + } + if (r.styleObserver) { + r.styleObserver.disconnect(); + } + if (r.resizeObserver) { + r.resizeObserver.disconnect(); + } + if (r.labelCalcDiv) { + try { + document.body.removeChild(r.labelCalcDiv); // eslint-disable-line no-undef + } catch (e) { + // ie10 issue #1014 + } + } +}; +BRp.isHeadless = function () { + return false; +}; +[BRp$f, BRp$5, BRp$4, BRp$3, BRp$2, BRp$1].forEach(function (props) { + extend(BRp, props); +}); + +var fullFpsTime = 1000 / 60; // assume 60 frames per second + +var defs = { + setupDequeueing: function setupDequeueing(opts) { + return function setupDequeueingImpl() { + var self = this; + var r = this.renderer; + if (self.dequeueingSetup) { + return; + } else { + self.dequeueingSetup = true; + } + var queueRedraw = debounce__default["default"](function () { + r.redrawHint('eles', true); + r.redrawHint('drag', true); + r.redraw(); + }, opts.deqRedrawThreshold); + var dequeue = function dequeue(willDraw, frameStartTime) { + var startTime = performanceNow(); + var avgRenderTime = r.averageRedrawTime; + var renderTime = r.lastRedrawTime; + var deqd = []; + var extent = r.cy.extent(); + var pixelRatio = r.getPixelRatio(); + + // if we aren't in a tick that causes a draw, then the rendered style + // queue won't automatically be flushed before dequeueing starts + if (!willDraw) { + r.flushRenderedStyleQueue(); + } + while (true) { + // eslint-disable-line no-constant-condition + var now = performanceNow(); + var duration = now - startTime; + var frameDuration = now - frameStartTime; + if (renderTime < fullFpsTime) { + // if we're rendering faster than the ideal fps, then do dequeueing + // during all of the remaining frame time + + var timeAvailable = fullFpsTime - (willDraw ? avgRenderTime : 0); + if (frameDuration >= opts.deqFastCost * timeAvailable) { + break; + } + } else { + if (willDraw) { + if (duration >= opts.deqCost * renderTime || duration >= opts.deqAvgCost * avgRenderTime) { + break; + } + } else if (frameDuration >= opts.deqNoDrawCost * fullFpsTime) { + break; + } + } + var thisDeqd = opts.deq(self, pixelRatio, extent); + if (thisDeqd.length > 0) { + for (var i = 0; i < thisDeqd.length; i++) { + deqd.push(thisDeqd[i]); + } + } else { + break; + } + } + + // callbacks on dequeue + if (deqd.length > 0) { + opts.onDeqd(self, deqd); + if (!willDraw && opts.shouldRedraw(self, deqd, pixelRatio, extent)) { + queueRedraw(); + } + } + }; + var priority = opts.priority || noop$1; + r.beforeRender(dequeue, priority(self)); + }; + } +}; + +// Allows lookups for (ele, lvl) => cache. +// Uses keys so elements may share the same cache. +var ElementTextureCacheLookup = /*#__PURE__*/function () { + function ElementTextureCacheLookup(getKey) { + var doesEleInvalidateKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : falsify; + _classCallCheck(this, ElementTextureCacheLookup); + this.idsByKey = new Map$1(); + this.keyForId = new Map$1(); + this.cachesByLvl = new Map$1(); + this.lvls = []; + this.getKey = getKey; + this.doesEleInvalidateKey = doesEleInvalidateKey; + } + _createClass(ElementTextureCacheLookup, [{ + key: "getIdsFor", + value: function getIdsFor(key) { + if (key == null) { + error("Can not get id list for null key"); + } + var idsByKey = this.idsByKey; + var ids = this.idsByKey.get(key); + if (!ids) { + ids = new Set$1(); + idsByKey.set(key, ids); + } + return ids; + } + }, { + key: "addIdForKey", + value: function addIdForKey(key, id) { + if (key != null) { + this.getIdsFor(key).add(id); + } + } + }, { + key: "deleteIdForKey", + value: function deleteIdForKey(key, id) { + if (key != null) { + this.getIdsFor(key)["delete"](id); + } + } + }, { + key: "getNumberOfIdsForKey", + value: function getNumberOfIdsForKey(key) { + if (key == null) { + return 0; + } else { + return this.getIdsFor(key).size; + } + } + }, { + key: "updateKeyMappingFor", + value: function updateKeyMappingFor(ele) { + var id = ele.id(); + var prevKey = this.keyForId.get(id); + var currKey = this.getKey(ele); + this.deleteIdForKey(prevKey, id); + this.addIdForKey(currKey, id); + this.keyForId.set(id, currKey); + } + }, { + key: "deleteKeyMappingFor", + value: function deleteKeyMappingFor(ele) { + var id = ele.id(); + var prevKey = this.keyForId.get(id); + this.deleteIdForKey(prevKey, id); + this.keyForId["delete"](id); + } + }, { + key: "keyHasChangedFor", + value: function keyHasChangedFor(ele) { + var id = ele.id(); + var prevKey = this.keyForId.get(id); + var newKey = this.getKey(ele); + return prevKey !== newKey; + } + }, { + key: "isInvalid", + value: function isInvalid(ele) { + return this.keyHasChangedFor(ele) || this.doesEleInvalidateKey(ele); + } + }, { + key: "getCachesAt", + value: function getCachesAt(lvl) { + var cachesByLvl = this.cachesByLvl, + lvls = this.lvls; + var caches = cachesByLvl.get(lvl); + if (!caches) { + caches = new Map$1(); + cachesByLvl.set(lvl, caches); + lvls.push(lvl); + } + return caches; + } + }, { + key: "getCache", + value: function getCache(key, lvl) { + return this.getCachesAt(lvl).get(key); + } + }, { + key: "get", + value: function get(ele, lvl) { + var key = this.getKey(ele); + var cache = this.getCache(key, lvl); + + // getting for an element may need to add to the id list b/c eles can share keys + if (cache != null) { + this.updateKeyMappingFor(ele); + } + return cache; + } + }, { + key: "getForCachedKey", + value: function getForCachedKey(ele, lvl) { + var key = this.keyForId.get(ele.id()); // n.b. use cached key, not newly computed key + var cache = this.getCache(key, lvl); + return cache; + } + }, { + key: "hasCache", + value: function hasCache(key, lvl) { + return this.getCachesAt(lvl).has(key); + } + }, { + key: "has", + value: function has(ele, lvl) { + var key = this.getKey(ele); + return this.hasCache(key, lvl); + } + }, { + key: "setCache", + value: function setCache(key, lvl, cache) { + cache.key = key; + this.getCachesAt(lvl).set(key, cache); + } + }, { + key: "set", + value: function set(ele, lvl, cache) { + var key = this.getKey(ele); + this.setCache(key, lvl, cache); + this.updateKeyMappingFor(ele); + } + }, { + key: "deleteCache", + value: function deleteCache(key, lvl) { + this.getCachesAt(lvl)["delete"](key); + } + }, { + key: "delete", + value: function _delete(ele, lvl) { + var key = this.getKey(ele); + this.deleteCache(key, lvl); + } + }, { + key: "invalidateKey", + value: function invalidateKey(key) { + var _this = this; + this.lvls.forEach(function (lvl) { + return _this.deleteCache(key, lvl); + }); + } + + // returns true if no other eles reference the invalidated cache (n.b. other eles may need the cache with the same key) + }, { + key: "invalidate", + value: function invalidate(ele) { + var id = ele.id(); + var key = this.keyForId.get(id); // n.b. use stored key rather than current (potential key) + + this.deleteKeyMappingFor(ele); + var entireKeyInvalidated = this.doesEleInvalidateKey(ele); + if (entireKeyInvalidated) { + // clear mapping for current key + this.invalidateKey(key); + } + return entireKeyInvalidated || this.getNumberOfIdsForKey(key) === 0; + } + }]); + return ElementTextureCacheLookup; +}(); + +var minTxrH = 25; // the size of the texture cache for small height eles (special case) +var txrStepH = 50; // the min size of the regular cache, and the size it increases with each step up +var minLvl$1 = -4; // when scaling smaller than that we don't need to re-render +var maxLvl$1 = 3; // when larger than this scale just render directly (caching is not helpful) +var maxZoom$1 = 7.99; // beyond this zoom level, layered textures are not used +var eleTxrSpacing = 8; // spacing between elements on textures to avoid blitting overlaps +var defTxrWidth = 1024; // default/minimum texture width +var maxTxrW = 1024; // the maximum width of a texture +var maxTxrH = 1024; // the maximum height of a texture +var minUtility = 0.2; // if usage of texture is less than this, it is retired +var maxFullness = 0.8; // fullness of texture after which queue removal is checked +var maxFullnessChecks = 10; // dequeued after this many checks +var deqCost$1 = 0.15; // % of add'l rendering cost allowed for dequeuing ele caches each frame +var deqAvgCost$1 = 0.1; // % of add'l rendering cost compared to average overall redraw time +var deqNoDrawCost$1 = 0.9; // % of avg frame time that can be used for dequeueing when not drawing +var deqFastCost$1 = 0.9; // % of frame time to be used when >60fps +var deqRedrawThreshold$1 = 100; // time to batch redraws together from dequeueing to allow more dequeueing calcs to happen in the meanwhile +var maxDeqSize$1 = 1; // number of eles to dequeue and render at higher texture in each batch + +var getTxrReasons = { + dequeue: 'dequeue', + downscale: 'downscale', + highQuality: 'highQuality' +}; +var initDefaults = defaults$g({ + getKey: null, + doesEleInvalidateKey: falsify, + drawElement: null, + getBoundingBox: null, + getRotationPoint: null, + getRotationOffset: null, + isVisible: trueify, + allowEdgeTxrCaching: true, + allowParentTxrCaching: true +}); +var ElementTextureCache = function ElementTextureCache(renderer, initOptions) { + var self = this; + self.renderer = renderer; + self.onDequeues = []; + var opts = initDefaults(initOptions); + extend(self, opts); + self.lookup = new ElementTextureCacheLookup(opts.getKey, opts.doesEleInvalidateKey); + self.setupDequeueing(); +}; +var ETCp = ElementTextureCache.prototype; +ETCp.reasons = getTxrReasons; + +// the list of textures in which new subtextures for elements can be placed +ETCp.getTextureQueue = function (txrH) { + var self = this; + self.eleImgCaches = self.eleImgCaches || {}; + return self.eleImgCaches[txrH] = self.eleImgCaches[txrH] || []; +}; + +// the list of usused textures which can be recycled (in use in texture queue) +ETCp.getRetiredTextureQueue = function (txrH) { + var self = this; + var rtxtrQs = self.eleImgCaches.retired = self.eleImgCaches.retired || {}; + var rtxtrQ = rtxtrQs[txrH] = rtxtrQs[txrH] || []; + return rtxtrQ; +}; + +// queue of element draw requests at different scale levels +ETCp.getElementQueue = function () { + var self = this; + var q = self.eleCacheQueue = self.eleCacheQueue || new Heap__default["default"](function (a, b) { + return b.reqs - a.reqs; + }); + return q; +}; + +// queue of element draw requests at different scale levels (element id lookup) +ETCp.getElementKeyToQueue = function () { + var self = this; + var k2q = self.eleKeyToCacheQueue = self.eleKeyToCacheQueue || {}; + return k2q; +}; +ETCp.getElement = function (ele, bb, pxRatio, lvl, reason) { + var self = this; + var r = this.renderer; + var zoom = r.cy.zoom(); + var lookup = this.lookup; + if (!bb || bb.w === 0 || bb.h === 0 || isNaN(bb.w) || isNaN(bb.h) || !ele.visible() || ele.removed()) { + return null; + } + if (!self.allowEdgeTxrCaching && ele.isEdge() || !self.allowParentTxrCaching && ele.isParent()) { + return null; + } + if (lvl == null) { + lvl = Math.ceil(log2(zoom * pxRatio)); + } + if (lvl < minLvl$1) { + lvl = minLvl$1; + } else if (zoom >= maxZoom$1 || lvl > maxLvl$1) { + return null; + } + var scale = Math.pow(2, lvl); + var eleScaledH = bb.h * scale; + var eleScaledW = bb.w * scale; + var scaledLabelShown = r.eleTextBiggerThanMin(ele, scale); + if (!this.isVisible(ele, scaledLabelShown)) { + return null; + } + var eleCache = lookup.get(ele, lvl); + + // if this get was on an unused/invalidated cache, then restore the texture usage metric + if (eleCache && eleCache.invalidated) { + eleCache.invalidated = false; + eleCache.texture.invalidatedWidth -= eleCache.width; + } + if (eleCache) { + return eleCache; + } + var txrH; // which texture height this ele belongs to + + if (eleScaledH <= minTxrH) { + txrH = minTxrH; + } else if (eleScaledH <= txrStepH) { + txrH = txrStepH; + } else { + txrH = Math.ceil(eleScaledH / txrStepH) * txrStepH; + } + if (eleScaledH > maxTxrH || eleScaledW > maxTxrW) { + return null; // caching large elements is not efficient + } + + var txrQ = self.getTextureQueue(txrH); + + // first try the second last one in case it has space at the end + var txr = txrQ[txrQ.length - 2]; + var addNewTxr = function addNewTxr() { + return self.recycleTexture(txrH, eleScaledW) || self.addTexture(txrH, eleScaledW); + }; + + // try the last one if there is no second last one + if (!txr) { + txr = txrQ[txrQ.length - 1]; + } + + // if the last one doesn't exist, we need a first one + if (!txr) { + txr = addNewTxr(); + } + + // if there's no room in the current texture, we need a new one + if (txr.width - txr.usedWidth < eleScaledW) { + txr = addNewTxr(); + } + var scalableFrom = function scalableFrom(otherCache) { + return otherCache && otherCache.scaledLabelShown === scaledLabelShown; + }; + var deqing = reason && reason === getTxrReasons.dequeue; + var highQualityReq = reason && reason === getTxrReasons.highQuality; + var downscaleReq = reason && reason === getTxrReasons.downscale; + var higherCache; // the nearest cache with a higher level + for (var l = lvl + 1; l <= maxLvl$1; l++) { + var c = lookup.get(ele, l); + if (c) { + higherCache = c; + break; + } + } + var oneUpCache = higherCache && higherCache.level === lvl + 1 ? higherCache : null; + var downscale = function downscale() { + txr.context.drawImage(oneUpCache.texture.canvas, oneUpCache.x, 0, oneUpCache.width, oneUpCache.height, txr.usedWidth, 0, eleScaledW, eleScaledH); + }; + + // reset ele area in texture + txr.context.setTransform(1, 0, 0, 1, 0, 0); + txr.context.clearRect(txr.usedWidth, 0, eleScaledW, txrH); + if (scalableFrom(oneUpCache)) { + // then we can relatively cheaply rescale the existing image w/o rerendering + downscale(); + } else if (scalableFrom(higherCache)) { + // then use the higher cache for now and queue the next level down + // to cheaply scale towards the smaller level + + if (highQualityReq) { + for (var _l = higherCache.level; _l > lvl; _l--) { + oneUpCache = self.getElement(ele, bb, pxRatio, _l, getTxrReasons.downscale); + } + downscale(); + } else { + self.queueElement(ele, higherCache.level - 1); + return higherCache; + } + } else { + var lowerCache; // the nearest cache with a lower level + if (!deqing && !highQualityReq && !downscaleReq) { + for (var _l2 = lvl - 1; _l2 >= minLvl$1; _l2--) { + var _c = lookup.get(ele, _l2); + if (_c) { + lowerCache = _c; + break; + } + } + } + if (scalableFrom(lowerCache)) { + // then use the lower quality cache for now and queue the better one for later + + self.queueElement(ele, lvl); + return lowerCache; + } + txr.context.translate(txr.usedWidth, 0); + txr.context.scale(scale, scale); + this.drawElement(txr.context, ele, bb, scaledLabelShown, false); + txr.context.scale(1 / scale, 1 / scale); + txr.context.translate(-txr.usedWidth, 0); + } + eleCache = { + x: txr.usedWidth, + texture: txr, + level: lvl, + scale: scale, + width: eleScaledW, + height: eleScaledH, + scaledLabelShown: scaledLabelShown + }; + txr.usedWidth += Math.ceil(eleScaledW + eleTxrSpacing); + txr.eleCaches.push(eleCache); + lookup.set(ele, lvl, eleCache); + self.checkTextureFullness(txr); + return eleCache; +}; +ETCp.invalidateElements = function (eles) { + for (var i = 0; i < eles.length; i++) { + this.invalidateElement(eles[i]); + } +}; +ETCp.invalidateElement = function (ele) { + var self = this; + var lookup = self.lookup; + var caches = []; + var invalid = lookup.isInvalid(ele); + if (!invalid) { + return; // override the invalidation request if the element key has not changed + } + + for (var lvl = minLvl$1; lvl <= maxLvl$1; lvl++) { + var cache = lookup.getForCachedKey(ele, lvl); + if (cache) { + caches.push(cache); + } + } + var noOtherElesUseCache = lookup.invalidate(ele); + if (noOtherElesUseCache) { + for (var i = 0; i < caches.length; i++) { + var _cache = caches[i]; + var txr = _cache.texture; + + // remove space from the texture it belongs to + txr.invalidatedWidth += _cache.width; + + // mark the cache as invalidated + _cache.invalidated = true; + + // retire the texture if its utility is low + self.checkTextureUtility(txr); + } + } + + // remove from queue since the old req was for the old state + self.removeFromQueue(ele); +}; +ETCp.checkTextureUtility = function (txr) { + // invalidate all entries in the cache if the cache size is small + if (txr.invalidatedWidth >= minUtility * txr.width) { + this.retireTexture(txr); + } +}; +ETCp.checkTextureFullness = function (txr) { + // if texture has been mostly filled and passed over several times, remove + // it from the queue so we don't need to waste time looking at it to put new things + + var self = this; + var txrQ = self.getTextureQueue(txr.height); + if (txr.usedWidth / txr.width > maxFullness && txr.fullnessChecks >= maxFullnessChecks) { + removeFromArray(txrQ, txr); + } else { + txr.fullnessChecks++; + } +}; +ETCp.retireTexture = function (txr) { + var self = this; + var txrH = txr.height; + var txrQ = self.getTextureQueue(txrH); + var lookup = this.lookup; + + // retire the texture from the active / searchable queue: + + removeFromArray(txrQ, txr); + txr.retired = true; + + // remove the refs from the eles to the caches: + + var eleCaches = txr.eleCaches; + for (var i = 0; i < eleCaches.length; i++) { + var eleCache = eleCaches[i]; + lookup.deleteCache(eleCache.key, eleCache.level); + } + clearArray(eleCaches); + + // add the texture to a retired queue so it can be recycled in future: + + var rtxtrQ = self.getRetiredTextureQueue(txrH); + rtxtrQ.push(txr); +}; +ETCp.addTexture = function (txrH, minW) { + var self = this; + var txrQ = self.getTextureQueue(txrH); + var txr = {}; + txrQ.push(txr); + txr.eleCaches = []; + txr.height = txrH; + txr.width = Math.max(defTxrWidth, minW); + txr.usedWidth = 0; + txr.invalidatedWidth = 0; + txr.fullnessChecks = 0; + txr.canvas = self.renderer.makeOffscreenCanvas(txr.width, txr.height); + txr.context = txr.canvas.getContext('2d'); + return txr; +}; +ETCp.recycleTexture = function (txrH, minW) { + var self = this; + var txrQ = self.getTextureQueue(txrH); + var rtxtrQ = self.getRetiredTextureQueue(txrH); + for (var i = 0; i < rtxtrQ.length; i++) { + var txr = rtxtrQ[i]; + if (txr.width >= minW) { + txr.retired = false; + txr.usedWidth = 0; + txr.invalidatedWidth = 0; + txr.fullnessChecks = 0; + clearArray(txr.eleCaches); + txr.context.setTransform(1, 0, 0, 1, 0, 0); + txr.context.clearRect(0, 0, txr.width, txr.height); + removeFromArray(rtxtrQ, txr); + txrQ.push(txr); + return txr; + } + } +}; +ETCp.queueElement = function (ele, lvl) { + var self = this; + var q = self.getElementQueue(); + var k2q = self.getElementKeyToQueue(); + var key = this.getKey(ele); + var existingReq = k2q[key]; + if (existingReq) { + // use the max lvl b/c in between lvls are cheap to make + existingReq.level = Math.max(existingReq.level, lvl); + existingReq.eles.merge(ele); + existingReq.reqs++; + q.updateItem(existingReq); + } else { + var req = { + eles: ele.spawn().merge(ele), + level: lvl, + reqs: 1, + key: key + }; + q.push(req); + k2q[key] = req; + } +}; +ETCp.dequeue = function (pxRatio /*, extent*/) { + var self = this; + var q = self.getElementQueue(); + var k2q = self.getElementKeyToQueue(); + var dequeued = []; + var lookup = self.lookup; + for (var i = 0; i < maxDeqSize$1; i++) { + if (q.size() > 0) { + var req = q.pop(); + var key = req.key; + var ele = req.eles[0]; // all eles have the same key + var cacheExists = lookup.hasCache(ele, req.level); + + // clear out the key to req lookup + k2q[key] = null; + + // dequeueing isn't necessary with an existing cache + if (cacheExists) { + continue; + } + dequeued.push(req); + var bb = self.getBoundingBox(ele); + self.getElement(ele, bb, pxRatio, req.level, getTxrReasons.dequeue); + } else { + break; + } + } + return dequeued; +}; +ETCp.removeFromQueue = function (ele) { + var self = this; + var q = self.getElementQueue(); + var k2q = self.getElementKeyToQueue(); + var key = this.getKey(ele); + var req = k2q[key]; + if (req != null) { + if (req.eles.length === 1) { + // remove if last ele in the req + // bring to front of queue + req.reqs = MAX_INT$1; + q.updateItem(req); + q.pop(); // remove from queue + + k2q[key] = null; // remove from lookup map + } else { + // otherwise just remove ele from req + req.eles.unmerge(ele); + } + } +}; +ETCp.onDequeue = function (fn) { + this.onDequeues.push(fn); +}; +ETCp.offDequeue = function (fn) { + removeFromArray(this.onDequeues, fn); +}; +ETCp.setupDequeueing = defs.setupDequeueing({ + deqRedrawThreshold: deqRedrawThreshold$1, + deqCost: deqCost$1, + deqAvgCost: deqAvgCost$1, + deqNoDrawCost: deqNoDrawCost$1, + deqFastCost: deqFastCost$1, + deq: function deq(self, pxRatio, extent) { + return self.dequeue(pxRatio, extent); + }, + onDeqd: function onDeqd(self, deqd) { + for (var i = 0; i < self.onDequeues.length; i++) { + var fn = self.onDequeues[i]; + fn(deqd); + } + }, + shouldRedraw: function shouldRedraw(self, deqd, pxRatio, extent) { + for (var i = 0; i < deqd.length; i++) { + var eles = deqd[i].eles; + for (var j = 0; j < eles.length; j++) { + var bb = eles[j].boundingBox(); + if (boundingBoxesIntersect(bb, extent)) { + return true; + } + } + } + return false; + }, + priority: function priority(self) { + return self.renderer.beforeRenderPriorities.eleTxrDeq; + } +}); + +var defNumLayers = 1; // default number of layers to use +var minLvl = -4; // when scaling smaller than that we don't need to re-render +var maxLvl = 2; // when larger than this scale just render directly (caching is not helpful) +var maxZoom = 3.99; // beyond this zoom level, layered textures are not used +var deqRedrawThreshold = 50; // time to batch redraws together from dequeueing to allow more dequeueing calcs to happen in the meanwhile +var refineEleDebounceTime = 50; // time to debounce sharper ele texture updates +var deqCost = 0.15; // % of add'l rendering cost allowed for dequeuing ele caches each frame +var deqAvgCost = 0.1; // % of add'l rendering cost compared to average overall redraw time +var deqNoDrawCost = 0.9; // % of avg frame time that can be used for dequeueing when not drawing +var deqFastCost = 0.9; // % of frame time to be used when >60fps +var maxDeqSize = 1; // number of eles to dequeue and render at higher texture in each batch +var invalidThreshold = 250; // time threshold for disabling b/c of invalidations +var maxLayerArea = 4000 * 4000; // layers can't be bigger than this +var useHighQualityEleTxrReqs = true; // whether to use high quality ele txr requests (generally faster and cheaper in the longterm) + +// var log = function(){ console.log.apply( console, arguments ); }; + +var LayeredTextureCache = function LayeredTextureCache(renderer) { + var self = this; + var r = self.renderer = renderer; + var cy = r.cy; + self.layersByLevel = {}; // e.g. 2 => [ layer1, layer2, ..., layerN ] + + self.firstGet = true; + self.lastInvalidationTime = performanceNow() - 2 * invalidThreshold; + self.skipping = false; + self.eleTxrDeqs = cy.collection(); + self.scheduleElementRefinement = debounce__default["default"](function () { + self.refineElementTextures(self.eleTxrDeqs); + self.eleTxrDeqs.unmerge(self.eleTxrDeqs); + }, refineEleDebounceTime); + r.beforeRender(function (willDraw, now) { + if (now - self.lastInvalidationTime <= invalidThreshold) { + self.skipping = true; + } else { + self.skipping = false; + } + }, r.beforeRenderPriorities.lyrTxrSkip); + var qSort = function qSort(a, b) { + return b.reqs - a.reqs; + }; + self.layersQueue = new Heap__default["default"](qSort); + self.setupDequeueing(); +}; +var LTCp = LayeredTextureCache.prototype; +var layerIdPool = 0; +var MAX_INT = Math.pow(2, 53) - 1; +LTCp.makeLayer = function (bb, lvl) { + var scale = Math.pow(2, lvl); + var w = Math.ceil(bb.w * scale); + var h = Math.ceil(bb.h * scale); + var canvas = this.renderer.makeOffscreenCanvas(w, h); + var layer = { + id: layerIdPool = ++layerIdPool % MAX_INT, + bb: bb, + level: lvl, + width: w, + height: h, + canvas: canvas, + context: canvas.getContext('2d'), + eles: [], + elesQueue: [], + reqs: 0 + }; + + // log('make layer %s with w %s and h %s and lvl %s', layer.id, layer.width, layer.height, layer.level); + + var cxt = layer.context; + var dx = -layer.bb.x1; + var dy = -layer.bb.y1; + + // do the transform on creation to save cycles (it's the same for all eles) + cxt.scale(scale, scale); + cxt.translate(dx, dy); + return layer; +}; +LTCp.getLayers = function (eles, pxRatio, lvl) { + var self = this; + var r = self.renderer; + var cy = r.cy; + var zoom = cy.zoom(); + var firstGet = self.firstGet; + self.firstGet = false; + + // log('--\nget layers with %s eles', eles.length); + //log eles.map(function(ele){ return ele.id() }) ); + + if (lvl == null) { + lvl = Math.ceil(log2(zoom * pxRatio)); + if (lvl < minLvl) { + lvl = minLvl; + } else if (zoom >= maxZoom || lvl > maxLvl) { + return null; + } + } + self.validateLayersElesOrdering(lvl, eles); + var layersByLvl = self.layersByLevel; + var scale = Math.pow(2, lvl); + var layers = layersByLvl[lvl] = layersByLvl[lvl] || []; + var bb; + var lvlComplete = self.levelIsComplete(lvl, eles); + var tmpLayers; + var checkTempLevels = function checkTempLevels() { + var canUseAsTmpLvl = function canUseAsTmpLvl(l) { + self.validateLayersElesOrdering(l, eles); + if (self.levelIsComplete(l, eles)) { + tmpLayers = layersByLvl[l]; + return true; + } + }; + var checkLvls = function checkLvls(dir) { + if (tmpLayers) { + return; + } + for (var l = lvl + dir; minLvl <= l && l <= maxLvl; l += dir) { + if (canUseAsTmpLvl(l)) { + break; + } + } + }; + checkLvls(+1); + checkLvls(-1); + + // remove the invalid layers; they will be replaced as needed later in this function + for (var i = layers.length - 1; i >= 0; i--) { + var layer = layers[i]; + if (layer.invalid) { + removeFromArray(layers, layer); + } + } + }; + if (!lvlComplete) { + // if the current level is incomplete, then use the closest, best quality layerset temporarily + // and later queue the current layerset so we can get the proper quality level soon + + checkTempLevels(); + } else { + // log('level complete, using existing layers\n--'); + return layers; + } + var getBb = function getBb() { + if (!bb) { + bb = makeBoundingBox(); + for (var i = 0; i < eles.length; i++) { + updateBoundingBox(bb, eles[i].boundingBox()); + } + } + return bb; + }; + var makeLayer = function makeLayer(opts) { + opts = opts || {}; + var after = opts.after; + getBb(); + var area = bb.w * scale * (bb.h * scale); + if (area > maxLayerArea) { + return null; + } + var layer = self.makeLayer(bb, lvl); + if (after != null) { + var index = layers.indexOf(after) + 1; + layers.splice(index, 0, layer); + } else if (opts.insert === undefined || opts.insert) { + // no after specified => first layer made so put at start + layers.unshift(layer); + } + + // if( tmpLayers ){ + //self.queueLayer( layer ); + // } + + return layer; + }; + if (self.skipping && !firstGet) { + // log('skip layers'); + return null; + } + + // log('do layers'); + + var layer = null; + var maxElesPerLayer = eles.length / defNumLayers; + var allowLazyQueueing = !firstGet; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var rs = ele._private.rscratch; + var caches = rs.imgLayerCaches = rs.imgLayerCaches || {}; + + // log('look at ele', ele.id()); + + var existingLayer = caches[lvl]; + if (existingLayer) { + // reuse layer for later eles + // log('reuse layer for', ele.id()); + layer = existingLayer; + continue; + } + if (!layer || layer.eles.length >= maxElesPerLayer || !boundingBoxInBoundingBox(layer.bb, ele.boundingBox())) { + // log('make new layer for ele %s', ele.id()); + + layer = makeLayer({ + insert: true, + after: layer + }); + + // if now layer can be built then we can't use layers at this level + if (!layer) { + return null; + } + + // log('new layer with id %s', layer.id); + } + + if (tmpLayers || allowLazyQueueing) { + // log('queue ele %s in layer %s', ele.id(), layer.id); + self.queueLayer(layer, ele); + } else { + // log('draw ele %s in layer %s', ele.id(), layer.id); + self.drawEleInLayer(layer, ele, lvl, pxRatio); + } + layer.eles.push(ele); + caches[lvl] = layer; + } + + // log('--'); + + if (tmpLayers) { + // then we only queued the current layerset and can't draw it yet + return tmpLayers; + } + if (allowLazyQueueing) { + // log('lazy queue level', lvl); + return null; + } + return layers; +}; + +// a layer may want to use an ele cache of a higher level to avoid blurriness +// so the layer level might not equal the ele level +LTCp.getEleLevelForLayerLevel = function (lvl, pxRatio) { + return lvl; +}; +LTCp.drawEleInLayer = function (layer, ele, lvl, pxRatio) { + var self = this; + var r = this.renderer; + var context = layer.context; + var bb = ele.boundingBox(); + if (bb.w === 0 || bb.h === 0 || !ele.visible()) { + return; + } + lvl = self.getEleLevelForLayerLevel(lvl, pxRatio); + { + r.setImgSmoothing(context, false); + } + { + r.drawCachedElement(context, ele, null, null, lvl, useHighQualityEleTxrReqs); + } + { + r.setImgSmoothing(context, true); + } +}; +LTCp.levelIsComplete = function (lvl, eles) { + var self = this; + var layers = self.layersByLevel[lvl]; + if (!layers || layers.length === 0) { + return false; + } + var numElesInLayers = 0; + for (var i = 0; i < layers.length; i++) { + var layer = layers[i]; + + // if there are any eles needed to be drawn yet, the level is not complete + if (layer.reqs > 0) { + return false; + } + + // if the layer is invalid, the level is not complete + if (layer.invalid) { + return false; + } + numElesInLayers += layer.eles.length; + } + + // we should have exactly the number of eles passed in to be complete + if (numElesInLayers !== eles.length) { + return false; + } + return true; +}; +LTCp.validateLayersElesOrdering = function (lvl, eles) { + var layers = this.layersByLevel[lvl]; + if (!layers) { + return; + } + + // if in a layer the eles are not in the same order, then the layer is invalid + // (i.e. there is an ele in between the eles in the layer) + + for (var i = 0; i < layers.length; i++) { + var layer = layers[i]; + var offset = -1; + + // find the offset + for (var j = 0; j < eles.length; j++) { + if (layer.eles[0] === eles[j]) { + offset = j; + break; + } + } + if (offset < 0) { + // then the layer has nonexistent elements and is invalid + this.invalidateLayer(layer); + continue; + } + + // the eles in the layer must be in the same continuous order, else the layer is invalid + + var o = offset; + for (var j = 0; j < layer.eles.length; j++) { + if (layer.eles[j] !== eles[o + j]) { + // log('invalidate based on ordering', layer.id); + + this.invalidateLayer(layer); + break; + } + } + } +}; +LTCp.updateElementsInLayers = function (eles, update) { + var self = this; + var isEles = element(eles[0]); + + // collect udpated elements (cascaded from the layers) and update each + // layer itself along the way + for (var i = 0; i < eles.length; i++) { + var req = isEles ? null : eles[i]; + var ele = isEles ? eles[i] : eles[i].ele; + var rs = ele._private.rscratch; + var caches = rs.imgLayerCaches = rs.imgLayerCaches || {}; + for (var l = minLvl; l <= maxLvl; l++) { + var layer = caches[l]; + if (!layer) { + continue; + } + + // if update is a request from the ele cache, then it affects only + // the matching level + if (req && self.getEleLevelForLayerLevel(layer.level) !== req.level) { + continue; + } + update(layer, ele, req); + } + } +}; +LTCp.haveLayers = function () { + var self = this; + var haveLayers = false; + for (var l = minLvl; l <= maxLvl; l++) { + var layers = self.layersByLevel[l]; + if (layers && layers.length > 0) { + haveLayers = true; + break; + } + } + return haveLayers; +}; +LTCp.invalidateElements = function (eles) { + var self = this; + if (eles.length === 0) { + return; + } + self.lastInvalidationTime = performanceNow(); + + // log('update invalidate layer time from eles'); + + if (eles.length === 0 || !self.haveLayers()) { + return; + } + self.updateElementsInLayers(eles, function invalAssocLayers(layer, ele, req) { + self.invalidateLayer(layer); + }); +}; +LTCp.invalidateLayer = function (layer) { + // log('update invalidate layer time'); + + this.lastInvalidationTime = performanceNow(); + if (layer.invalid) { + return; + } // save cycles + + var lvl = layer.level; + var eles = layer.eles; + var layers = this.layersByLevel[lvl]; + + // log('invalidate layer', layer.id ); + + removeFromArray(layers, layer); + // layer.eles = []; + + layer.elesQueue = []; + layer.invalid = true; + if (layer.replacement) { + layer.replacement.invalid = true; + } + for (var i = 0; i < eles.length; i++) { + var caches = eles[i]._private.rscratch.imgLayerCaches; + if (caches) { + caches[lvl] = null; + } + } +}; +LTCp.refineElementTextures = function (eles) { + var self = this; + + // log('refine', eles.length); + + self.updateElementsInLayers(eles, function refineEachEle(layer, ele, req) { + var rLyr = layer.replacement; + if (!rLyr) { + rLyr = layer.replacement = self.makeLayer(layer.bb, layer.level); + rLyr.replaces = layer; + rLyr.eles = layer.eles; + + // log('make replacement layer %s for %s with level %s', rLyr.id, layer.id, rLyr.level); + } + + if (!rLyr.reqs) { + for (var i = 0; i < rLyr.eles.length; i++) { + self.queueLayer(rLyr, rLyr.eles[i]); + } + + // log('queue replacement layer refinement', rLyr.id); + } + }); +}; + +LTCp.enqueueElementRefinement = function (ele) { + this.eleTxrDeqs.merge(ele); + this.scheduleElementRefinement(); +}; +LTCp.queueLayer = function (layer, ele) { + var self = this; + var q = self.layersQueue; + var elesQ = layer.elesQueue; + var hasId = elesQ.hasId = elesQ.hasId || {}; + + // if a layer is going to be replaced, queuing is a waste of time + if (layer.replacement) { + return; + } + if (ele) { + if (hasId[ele.id()]) { + return; + } + elesQ.push(ele); + hasId[ele.id()] = true; + } + if (layer.reqs) { + layer.reqs++; + q.updateItem(layer); + } else { + layer.reqs = 1; + q.push(layer); + } +}; +LTCp.dequeue = function (pxRatio) { + var self = this; + var q = self.layersQueue; + var deqd = []; + var eleDeqs = 0; + while (eleDeqs < maxDeqSize) { + if (q.size() === 0) { + break; + } + var layer = q.peek(); + + // if a layer has been or will be replaced, then don't waste time with it + if (layer.replacement) { + // log('layer %s in queue skipped b/c it already has a replacement', layer.id); + q.pop(); + continue; + } + + // if this is a replacement layer that has been superceded, then forget it + if (layer.replaces && layer !== layer.replaces.replacement) { + // log('layer is no longer the most uptodate replacement; dequeued', layer.id) + q.pop(); + continue; + } + if (layer.invalid) { + // log('replacement layer %s is invalid; dequeued', layer.id); + q.pop(); + continue; + } + var ele = layer.elesQueue.shift(); + if (ele) { + // log('dequeue layer %s', layer.id); + + self.drawEleInLayer(layer, ele, layer.level, pxRatio); + eleDeqs++; + } + if (deqd.length === 0) { + // we need only one entry in deqd to queue redrawing etc + deqd.push(true); + } + + // if the layer has all its eles done, then remove from the queue + if (layer.elesQueue.length === 0) { + q.pop(); + layer.reqs = 0; + + // log('dequeue of layer %s complete', layer.id); + + // when a replacement layer is dequeued, it replaces the old layer in the level + if (layer.replaces) { + self.applyLayerReplacement(layer); + } + self.requestRedraw(); + } + } + return deqd; +}; +LTCp.applyLayerReplacement = function (layer) { + var self = this; + var layersInLevel = self.layersByLevel[layer.level]; + var replaced = layer.replaces; + var index = layersInLevel.indexOf(replaced); + + // if the replaced layer is not in the active list for the level, then replacing + // refs would be a mistake (i.e. overwriting the true active layer) + if (index < 0 || replaced.invalid) { + // log('replacement layer would have no effect', layer.id); + return; + } + layersInLevel[index] = layer; // replace level ref + + // replace refs in eles + for (var i = 0; i < layer.eles.length; i++) { + var _p = layer.eles[i]._private; + var cache = _p.imgLayerCaches = _p.imgLayerCaches || {}; + if (cache) { + cache[layer.level] = layer; + } + } + + // log('apply replacement layer %s over %s', layer.id, replaced.id); + + self.requestRedraw(); +}; +LTCp.requestRedraw = debounce__default["default"](function () { + var r = this.renderer; + r.redrawHint('eles', true); + r.redrawHint('drag', true); + r.redraw(); +}, 100); +LTCp.setupDequeueing = defs.setupDequeueing({ + deqRedrawThreshold: deqRedrawThreshold, + deqCost: deqCost, + deqAvgCost: deqAvgCost, + deqNoDrawCost: deqNoDrawCost, + deqFastCost: deqFastCost, + deq: function deq(self, pxRatio) { + return self.dequeue(pxRatio); + }, + onDeqd: noop$1, + shouldRedraw: trueify, + priority: function priority(self) { + return self.renderer.beforeRenderPriorities.lyrTxrDeq; + } +}); + +var CRp$a = {}; +var impl; +function polygon(context, points) { + for (var i = 0; i < points.length; i++) { + var pt = points[i]; + context.lineTo(pt.x, pt.y); + } +} +function triangleBackcurve(context, points, controlPoint) { + var firstPt; + for (var i = 0; i < points.length; i++) { + var pt = points[i]; + if (i === 0) { + firstPt = pt; + } + context.lineTo(pt.x, pt.y); + } + context.quadraticCurveTo(controlPoint.x, controlPoint.y, firstPt.x, firstPt.y); +} +function triangleTee(context, trianglePoints, teePoints) { + if (context.beginPath) { + context.beginPath(); + } + var triPts = trianglePoints; + for (var i = 0; i < triPts.length; i++) { + var pt = triPts[i]; + context.lineTo(pt.x, pt.y); + } + var teePts = teePoints; + var firstTeePt = teePoints[0]; + context.moveTo(firstTeePt.x, firstTeePt.y); + for (var i = 1; i < teePts.length; i++) { + var pt = teePts[i]; + context.lineTo(pt.x, pt.y); + } + if (context.closePath) { + context.closePath(); + } +} +function circleTriangle(context, trianglePoints, rx, ry, r) { + if (context.beginPath) { + context.beginPath(); + } + context.arc(rx, ry, r, 0, Math.PI * 2, false); + var triPts = trianglePoints; + var firstTrPt = triPts[0]; + context.moveTo(firstTrPt.x, firstTrPt.y); + for (var i = 0; i < triPts.length; i++) { + var pt = triPts[i]; + context.lineTo(pt.x, pt.y); + } + if (context.closePath) { + context.closePath(); + } +} +function circle(context, rx, ry, r) { + context.arc(rx, ry, r, 0, Math.PI * 2, false); +} +CRp$a.arrowShapeImpl = function (name) { + return (impl || (impl = { + 'polygon': polygon, + 'triangle-backcurve': triangleBackcurve, + 'triangle-tee': triangleTee, + 'circle-triangle': circleTriangle, + 'triangle-cross': triangleTee, + 'circle': circle + }))[name]; +}; + +var CRp$9 = {}; +CRp$9.drawElement = function (context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity) { + var r = this; + if (ele.isNode()) { + r.drawNode(context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity); + } else { + r.drawEdge(context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity); + } +}; +CRp$9.drawElementOverlay = function (context, ele) { + var r = this; + if (ele.isNode()) { + r.drawNodeOverlay(context, ele); + } else { + r.drawEdgeOverlay(context, ele); + } +}; +CRp$9.drawElementUnderlay = function (context, ele) { + var r = this; + if (ele.isNode()) { + r.drawNodeUnderlay(context, ele); + } else { + r.drawEdgeUnderlay(context, ele); + } +}; +CRp$9.drawCachedElementPortion = function (context, ele, eleTxrCache, pxRatio, lvl, reason, getRotation, getOpacity) { + var r = this; + var bb = eleTxrCache.getBoundingBox(ele); + if (bb.w === 0 || bb.h === 0) { + return; + } // ignore zero size case + + var eleCache = eleTxrCache.getElement(ele, bb, pxRatio, lvl, reason); + if (eleCache != null) { + var opacity = getOpacity(r, ele); + if (opacity === 0) { + return; + } + var theta = getRotation(r, ele); + var x1 = bb.x1, + y1 = bb.y1, + w = bb.w, + h = bb.h; + var x, y, sx, sy, smooth; + if (theta !== 0) { + var rotPt = eleTxrCache.getRotationPoint(ele); + sx = rotPt.x; + sy = rotPt.y; + context.translate(sx, sy); + context.rotate(theta); + smooth = r.getImgSmoothing(context); + if (!smooth) { + r.setImgSmoothing(context, true); + } + var off = eleTxrCache.getRotationOffset(ele); + x = off.x; + y = off.y; + } else { + x = x1; + y = y1; + } + var oldGlobalAlpha; + if (opacity !== 1) { + oldGlobalAlpha = context.globalAlpha; + context.globalAlpha = oldGlobalAlpha * opacity; + } + context.drawImage(eleCache.texture.canvas, eleCache.x, 0, eleCache.width, eleCache.height, x, y, w, h); + if (opacity !== 1) { + context.globalAlpha = oldGlobalAlpha; + } + if (theta !== 0) { + context.rotate(-theta); + context.translate(-sx, -sy); + if (!smooth) { + r.setImgSmoothing(context, false); + } + } + } else { + eleTxrCache.drawElement(context, ele); // direct draw fallback + } +}; + +var getZeroRotation = function getZeroRotation() { + return 0; +}; +var getLabelRotation = function getLabelRotation(r, ele) { + return r.getTextAngle(ele, null); +}; +var getSourceLabelRotation = function getSourceLabelRotation(r, ele) { + return r.getTextAngle(ele, 'source'); +}; +var getTargetLabelRotation = function getTargetLabelRotation(r, ele) { + return r.getTextAngle(ele, 'target'); +}; +var getOpacity = function getOpacity(r, ele) { + return ele.effectiveOpacity(); +}; +var getTextOpacity = function getTextOpacity(e, ele) { + return ele.pstyle('text-opacity').pfValue * ele.effectiveOpacity(); +}; +CRp$9.drawCachedElement = function (context, ele, pxRatio, extent, lvl, requestHighQuality) { + var r = this; + var _r$data = r.data, + eleTxrCache = _r$data.eleTxrCache, + lblTxrCache = _r$data.lblTxrCache, + slbTxrCache = _r$data.slbTxrCache, + tlbTxrCache = _r$data.tlbTxrCache; + var bb = ele.boundingBox(); + var reason = requestHighQuality === true ? eleTxrCache.reasons.highQuality : null; + if (bb.w === 0 || bb.h === 0 || !ele.visible()) { + return; + } + if (!extent || boundingBoxesIntersect(bb, extent)) { + var isEdge = ele.isEdge(); + var badLine = ele.element()._private.rscratch.badLine; + r.drawElementUnderlay(context, ele); + r.drawCachedElementPortion(context, ele, eleTxrCache, pxRatio, lvl, reason, getZeroRotation, getOpacity); + if (!isEdge || !badLine) { + r.drawCachedElementPortion(context, ele, lblTxrCache, pxRatio, lvl, reason, getLabelRotation, getTextOpacity); + } + if (isEdge && !badLine) { + r.drawCachedElementPortion(context, ele, slbTxrCache, pxRatio, lvl, reason, getSourceLabelRotation, getTextOpacity); + r.drawCachedElementPortion(context, ele, tlbTxrCache, pxRatio, lvl, reason, getTargetLabelRotation, getTextOpacity); + } + r.drawElementOverlay(context, ele); + } +}; +CRp$9.drawElements = function (context, eles) { + var r = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + r.drawElement(context, ele); + } +}; +CRp$9.drawCachedElements = function (context, eles, pxRatio, extent) { + var r = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + r.drawCachedElement(context, ele, pxRatio, extent); + } +}; +CRp$9.drawCachedNodes = function (context, eles, pxRatio, extent) { + var r = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + if (!ele.isNode()) { + continue; + } + r.drawCachedElement(context, ele, pxRatio, extent); + } +}; +CRp$9.drawLayeredElements = function (context, eles, pxRatio, extent) { + var r = this; + var layers = r.data.lyrTxrCache.getLayers(eles, pxRatio); + if (layers) { + for (var i = 0; i < layers.length; i++) { + var layer = layers[i]; + var bb = layer.bb; + if (bb.w === 0 || bb.h === 0) { + continue; + } + context.drawImage(layer.canvas, bb.x1, bb.y1, bb.w, bb.h); + } + } else { + // fall back on plain caching if no layers + r.drawCachedElements(context, eles, pxRatio, extent); + } +}; + +/* global Path2D */ +var CRp$8 = {}; +CRp$8.drawEdge = function (context, edge, shiftToOriginWithBb) { + var drawLabel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var shouldDrawOverlay = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; + var shouldDrawOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true; + var r = this; + var rs = edge._private.rscratch; + if (shouldDrawOpacity && !edge.visible()) { + return; + } + + // if bezier ctrl pts can not be calculated, then die + if (rs.badLine || rs.allpts == null || isNaN(rs.allpts[0])) { + // isNaN in case edge is impossible and browser bugs (e.g. safari) + return; + } + var bb; + if (shiftToOriginWithBb) { + bb = shiftToOriginWithBb; + context.translate(-bb.x1, -bb.y1); + } + var opacity = shouldDrawOpacity ? edge.pstyle('opacity').value : 1; + var lineOpacity = shouldDrawOpacity ? edge.pstyle('line-opacity').value : 1; + var curveStyle = edge.pstyle('curve-style').value; + var lineStyle = edge.pstyle('line-style').value; + var edgeWidth = edge.pstyle('width').pfValue; + var lineCap = edge.pstyle('line-cap').value; + var effectiveLineOpacity = opacity * lineOpacity; + // separate arrow opacity would require arrow-opacity property + var effectiveArrowOpacity = opacity * lineOpacity; + var drawLine = function drawLine() { + var strokeOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : effectiveLineOpacity; + if (curveStyle === 'straight-triangle') { + r.eleStrokeStyle(context, edge, strokeOpacity); + r.drawEdgeTrianglePath(edge, context, rs.allpts); + } else { + context.lineWidth = edgeWidth; + context.lineCap = lineCap; + r.eleStrokeStyle(context, edge, strokeOpacity); + r.drawEdgePath(edge, context, rs.allpts, lineStyle); + context.lineCap = 'butt'; // reset for other drawing functions + } + }; + + var drawOverlay = function drawOverlay() { + if (!shouldDrawOverlay) { + return; + } + r.drawEdgeOverlay(context, edge); + }; + var drawUnderlay = function drawUnderlay() { + if (!shouldDrawOverlay) { + return; + } + r.drawEdgeUnderlay(context, edge); + }; + var drawArrows = function drawArrows() { + var arrowOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : effectiveArrowOpacity; + r.drawArrowheads(context, edge, arrowOpacity); + }; + var drawText = function drawText() { + r.drawElementText(context, edge, null, drawLabel); + }; + context.lineJoin = 'round'; + var ghost = edge.pstyle('ghost').value === 'yes'; + if (ghost) { + var gx = edge.pstyle('ghost-offset-x').pfValue; + var gy = edge.pstyle('ghost-offset-y').pfValue; + var ghostOpacity = edge.pstyle('ghost-opacity').value; + var effectiveGhostOpacity = effectiveLineOpacity * ghostOpacity; + context.translate(gx, gy); + drawLine(effectiveGhostOpacity); + drawArrows(effectiveGhostOpacity); + context.translate(-gx, -gy); + } + drawUnderlay(); + drawLine(); + drawArrows(); + drawOverlay(); + drawText(); + if (shiftToOriginWithBb) { + context.translate(bb.x1, bb.y1); + } +}; +var drawEdgeOverlayUnderlay = function drawEdgeOverlayUnderlay(overlayOrUnderlay) { + if (!['overlay', 'underlay'].includes(overlayOrUnderlay)) { + throw new Error('Invalid state'); + } + return function (context, edge) { + if (!edge.visible()) { + return; + } + var opacity = edge.pstyle("".concat(overlayOrUnderlay, "-opacity")).value; + if (opacity === 0) { + return; + } + var r = this; + var usePaths = r.usePaths(); + var rs = edge._private.rscratch; + var padding = edge.pstyle("".concat(overlayOrUnderlay, "-padding")).pfValue; + var width = 2 * padding; + var color = edge.pstyle("".concat(overlayOrUnderlay, "-color")).value; + context.lineWidth = width; + if (rs.edgeType === 'self' && !usePaths) { + context.lineCap = 'butt'; + } else { + context.lineCap = 'round'; + } + r.colorStrokeStyle(context, color[0], color[1], color[2], opacity); + r.drawEdgePath(edge, context, rs.allpts, 'solid'); + }; +}; +CRp$8.drawEdgeOverlay = drawEdgeOverlayUnderlay('overlay'); +CRp$8.drawEdgeUnderlay = drawEdgeOverlayUnderlay('underlay'); +CRp$8.drawEdgePath = function (edge, context, pts, type) { + var rs = edge._private.rscratch; + var canvasCxt = context; + var path; + var pathCacheHit = false; + var usePaths = this.usePaths(); + var lineDashPattern = edge.pstyle('line-dash-pattern').pfValue; + var lineDashOffset = edge.pstyle('line-dash-offset').pfValue; + if (usePaths) { + var pathCacheKey = pts.join('$'); + var keyMatches = rs.pathCacheKey && rs.pathCacheKey === pathCacheKey; + if (keyMatches) { + path = context = rs.pathCache; + pathCacheHit = true; + } else { + path = context = new Path2D(); + rs.pathCacheKey = pathCacheKey; + rs.pathCache = path; + } + } + if (canvasCxt.setLineDash) { + // for very outofdate browsers + switch (type) { + case 'dotted': + canvasCxt.setLineDash([1, 1]); + break; + case 'dashed': + canvasCxt.setLineDash(lineDashPattern); + canvasCxt.lineDashOffset = lineDashOffset; + break; + case 'solid': + canvasCxt.setLineDash([]); + break; + } + } + if (!pathCacheHit && !rs.badLine) { + if (context.beginPath) { + context.beginPath(); + } + context.moveTo(pts[0], pts[1]); + switch (rs.edgeType) { + case 'bezier': + case 'self': + case 'compound': + case 'multibezier': + for (var i = 2; i + 3 < pts.length; i += 4) { + context.quadraticCurveTo(pts[i], pts[i + 1], pts[i + 2], pts[i + 3]); + } + break; + case 'straight': + case 'segments': + case 'haystack': + for (var _i = 2; _i + 1 < pts.length; _i += 2) { + context.lineTo(pts[_i], pts[_i + 1]); + } + break; + } + } + context = canvasCxt; + if (usePaths) { + context.stroke(path); + } else { + context.stroke(); + } + + // reset any line dashes + if (context.setLineDash) { + // for very outofdate browsers + context.setLineDash([]); + } +}; +CRp$8.drawEdgeTrianglePath = function (edge, context, pts) { + // use line stroke style for triangle fill style + context.fillStyle = context.strokeStyle; + var edgeWidth = edge.pstyle('width').pfValue; + for (var i = 0; i + 1 < pts.length; i += 2) { + var vector = [pts[i + 2] - pts[i], pts[i + 3] - pts[i + 1]]; + var length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]); + var normal = [vector[1] / length, -vector[0] / length]; + var triangleHead = [normal[0] * edgeWidth / 2, normal[1] * edgeWidth / 2]; + context.beginPath(); + context.moveTo(pts[i] - triangleHead[0], pts[i + 1] - triangleHead[1]); + context.lineTo(pts[i] + triangleHead[0], pts[i + 1] + triangleHead[1]); + context.lineTo(pts[i + 2], pts[i + 3]); + context.closePath(); + context.fill(); + } +}; +CRp$8.drawArrowheads = function (context, edge, opacity) { + var rs = edge._private.rscratch; + var isHaystack = rs.edgeType === 'haystack'; + if (!isHaystack) { + this.drawArrowhead(context, edge, 'source', rs.arrowStartX, rs.arrowStartY, rs.srcArrowAngle, opacity); + } + this.drawArrowhead(context, edge, 'mid-target', rs.midX, rs.midY, rs.midtgtArrowAngle, opacity); + this.drawArrowhead(context, edge, 'mid-source', rs.midX, rs.midY, rs.midsrcArrowAngle, opacity); + if (!isHaystack) { + this.drawArrowhead(context, edge, 'target', rs.arrowEndX, rs.arrowEndY, rs.tgtArrowAngle, opacity); + } +}; +CRp$8.drawArrowhead = function (context, edge, prefix, x, y, angle, opacity) { + if (isNaN(x) || x == null || isNaN(y) || y == null || isNaN(angle) || angle == null) { + return; + } + var self = this; + var arrowShape = edge.pstyle(prefix + '-arrow-shape').value; + if (arrowShape === 'none') { + return; + } + var arrowClearFill = edge.pstyle(prefix + '-arrow-fill').value === 'hollow' ? 'both' : 'filled'; + var arrowFill = edge.pstyle(prefix + '-arrow-fill').value; + var edgeWidth = edge.pstyle('width').pfValue; + var pArrowWidth = edge.pstyle(prefix + '-arrow-width'); + var arrowWidth = pArrowWidth.value === 'match-line' ? edgeWidth : pArrowWidth.pfValue; + if (pArrowWidth.units === '%') arrowWidth *= edgeWidth; + var edgeOpacity = edge.pstyle('opacity').value; + if (opacity === undefined) { + opacity = edgeOpacity; + } + var gco = context.globalCompositeOperation; + if (opacity !== 1 || arrowFill === 'hollow') { + // then extra clear is needed + context.globalCompositeOperation = 'destination-out'; + self.colorFillStyle(context, 255, 255, 255, 1); + self.colorStrokeStyle(context, 255, 255, 255, 1); + self.drawArrowShape(edge, context, arrowClearFill, edgeWidth, arrowShape, arrowWidth, x, y, angle); + context.globalCompositeOperation = gco; + } // otherwise, the opaque arrow clears it for free :) + + var color = edge.pstyle(prefix + '-arrow-color').value; + self.colorFillStyle(context, color[0], color[1], color[2], opacity); + self.colorStrokeStyle(context, color[0], color[1], color[2], opacity); + self.drawArrowShape(edge, context, arrowFill, edgeWidth, arrowShape, arrowWidth, x, y, angle); +}; +CRp$8.drawArrowShape = function (edge, context, fill, edgeWidth, shape, shapeWidth, x, y, angle) { + var r = this; + var usePaths = this.usePaths() && shape !== 'triangle-cross'; + var pathCacheHit = false; + var path; + var canvasContext = context; + var translation = { + x: x, + y: y + }; + var scale = edge.pstyle('arrow-scale').value; + var size = this.getArrowWidth(edgeWidth, scale); + var shapeImpl = r.arrowShapes[shape]; + if (usePaths) { + var cache = r.arrowPathCache = r.arrowPathCache || []; + var key = hashString(shape); + var cachedPath = cache[key]; + if (cachedPath != null) { + path = context = cachedPath; + pathCacheHit = true; + } else { + path = context = new Path2D(); + cache[key] = path; + } + } + if (!pathCacheHit) { + if (context.beginPath) { + context.beginPath(); + } + if (usePaths) { + // store in the path cache with values easily manipulated later + shapeImpl.draw(context, 1, 0, { + x: 0, + y: 0 + }, 1); + } else { + shapeImpl.draw(context, size, angle, translation, edgeWidth); + } + if (context.closePath) { + context.closePath(); + } + } + context = canvasContext; + if (usePaths) { + // set transform to arrow position/orientation + context.translate(x, y); + context.rotate(angle); + context.scale(size, size); + } + if (fill === 'filled' || fill === 'both') { + if (usePaths) { + context.fill(path); + } else { + context.fill(); + } + } + if (fill === 'hollow' || fill === 'both') { + context.lineWidth = shapeWidth / (usePaths ? size : 1); + context.lineJoin = 'miter'; + if (usePaths) { + context.stroke(path); + } else { + context.stroke(); + } + } + if (usePaths) { + // reset transform by applying inverse + context.scale(1 / size, 1 / size); + context.rotate(-angle); + context.translate(-x, -y); + } +}; + +var CRp$7 = {}; +CRp$7.safeDrawImage = function (context, img, ix, iy, iw, ih, x, y, w, h) { + // detect problematic cases for old browsers with bad images (cheaper than try-catch) + if (iw <= 0 || ih <= 0 || w <= 0 || h <= 0) { + return; + } + try { + context.drawImage(img, ix, iy, iw, ih, x, y, w, h); + } catch (e) { + warn(e); + } +}; +CRp$7.drawInscribedImage = function (context, img, node, index, nodeOpacity) { + var r = this; + var pos = node.position(); + var nodeX = pos.x; + var nodeY = pos.y; + var styleObj = node.cy().style(); + var getIndexedStyle = styleObj.getIndexedStyle.bind(styleObj); + var fit = getIndexedStyle(node, 'background-fit', 'value', index); + var repeat = getIndexedStyle(node, 'background-repeat', 'value', index); + var nodeW = node.width(); + var nodeH = node.height(); + var paddingX2 = node.padding() * 2; + var nodeTW = nodeW + (getIndexedStyle(node, 'background-width-relative-to', 'value', index) === 'inner' ? 0 : paddingX2); + var nodeTH = nodeH + (getIndexedStyle(node, 'background-height-relative-to', 'value', index) === 'inner' ? 0 : paddingX2); + var rs = node._private.rscratch; + var clip = getIndexedStyle(node, 'background-clip', 'value', index); + var shouldClip = clip === 'node'; + var imgOpacity = getIndexedStyle(node, 'background-image-opacity', 'value', index) * nodeOpacity; + var smooth = getIndexedStyle(node, 'background-image-smoothing', 'value', index); + var imgW = img.width || img.cachedW; + var imgH = img.height || img.cachedH; + + // workaround for broken browsers like ie + if (null == imgW || null == imgH) { + document.body.appendChild(img); // eslint-disable-line no-undef + + imgW = img.cachedW = img.width || img.offsetWidth; + imgH = img.cachedH = img.height || img.offsetHeight; + document.body.removeChild(img); // eslint-disable-line no-undef + } + + var w = imgW; + var h = imgH; + if (getIndexedStyle(node, 'background-width', 'value', index) !== 'auto') { + if (getIndexedStyle(node, 'background-width', 'units', index) === '%') { + w = getIndexedStyle(node, 'background-width', 'pfValue', index) * nodeTW; + } else { + w = getIndexedStyle(node, 'background-width', 'pfValue', index); + } + } + if (getIndexedStyle(node, 'background-height', 'value', index) !== 'auto') { + if (getIndexedStyle(node, 'background-height', 'units', index) === '%') { + h = getIndexedStyle(node, 'background-height', 'pfValue', index) * nodeTH; + } else { + h = getIndexedStyle(node, 'background-height', 'pfValue', index); + } + } + if (w === 0 || h === 0) { + return; // no point in drawing empty image (and chrome is broken in this case) + } + + if (fit === 'contain') { + var scale = Math.min(nodeTW / w, nodeTH / h); + w *= scale; + h *= scale; + } else if (fit === 'cover') { + var scale = Math.max(nodeTW / w, nodeTH / h); + w *= scale; + h *= scale; + } + var x = nodeX - nodeTW / 2; // left + var posXUnits = getIndexedStyle(node, 'background-position-x', 'units', index); + var posXPfVal = getIndexedStyle(node, 'background-position-x', 'pfValue', index); + if (posXUnits === '%') { + x += (nodeTW - w) * posXPfVal; + } else { + x += posXPfVal; + } + var offXUnits = getIndexedStyle(node, 'background-offset-x', 'units', index); + var offXPfVal = getIndexedStyle(node, 'background-offset-x', 'pfValue', index); + if (offXUnits === '%') { + x += (nodeTW - w) * offXPfVal; + } else { + x += offXPfVal; + } + var y = nodeY - nodeTH / 2; // top + var posYUnits = getIndexedStyle(node, 'background-position-y', 'units', index); + var posYPfVal = getIndexedStyle(node, 'background-position-y', 'pfValue', index); + if (posYUnits === '%') { + y += (nodeTH - h) * posYPfVal; + } else { + y += posYPfVal; + } + var offYUnits = getIndexedStyle(node, 'background-offset-y', 'units', index); + var offYPfVal = getIndexedStyle(node, 'background-offset-y', 'pfValue', index); + if (offYUnits === '%') { + y += (nodeTH - h) * offYPfVal; + } else { + y += offYPfVal; + } + if (rs.pathCache) { + x -= nodeX; + y -= nodeY; + nodeX = 0; + nodeY = 0; + } + var gAlpha = context.globalAlpha; + context.globalAlpha = imgOpacity; + var smoothingEnabled = r.getImgSmoothing(context); + var isSmoothingSwitched = false; + if (smooth === 'no' && smoothingEnabled) { + r.setImgSmoothing(context, false); + isSmoothingSwitched = true; + } else if (smooth === 'yes' && !smoothingEnabled) { + r.setImgSmoothing(context, true); + isSmoothingSwitched = true; + } + if (repeat === 'no-repeat') { + if (shouldClip) { + context.save(); + if (rs.pathCache) { + context.clip(rs.pathCache); + } else { + r.nodeShapes[r.getNodeShape(node)].draw(context, nodeX, nodeY, nodeTW, nodeTH); + context.clip(); + } + } + r.safeDrawImage(context, img, 0, 0, imgW, imgH, x, y, w, h); + if (shouldClip) { + context.restore(); + } + } else { + var pattern = context.createPattern(img, repeat); + context.fillStyle = pattern; + r.nodeShapes[r.getNodeShape(node)].draw(context, nodeX, nodeY, nodeTW, nodeTH); + context.translate(x, y); + context.fill(); + context.translate(-x, -y); + } + context.globalAlpha = gAlpha; + if (isSmoothingSwitched) { + r.setImgSmoothing(context, smoothingEnabled); + } +}; + +var CRp$6 = {}; +CRp$6.eleTextBiggerThanMin = function (ele, scale) { + if (!scale) { + var zoom = ele.cy().zoom(); + var pxRatio = this.getPixelRatio(); + var lvl = Math.ceil(log2(zoom * pxRatio)); // the effective texture level + + scale = Math.pow(2, lvl); + } + var computedSize = ele.pstyle('font-size').pfValue * scale; + var minSize = ele.pstyle('min-zoomed-font-size').pfValue; + if (computedSize < minSize) { + return false; + } + return true; +}; +CRp$6.drawElementText = function (context, ele, shiftToOriginWithBb, force, prefix) { + var useEleOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true; + var r = this; + if (force == null) { + if (useEleOpacity && !r.eleTextBiggerThanMin(ele)) { + return; + } + } else if (force === false) { + return; + } + if (ele.isNode()) { + var label = ele.pstyle('label'); + if (!label || !label.value) { + return; + } + var justification = r.getLabelJustification(ele); + context.textAlign = justification; + context.textBaseline = 'bottom'; + } else { + var badLine = ele.element()._private.rscratch.badLine; + var _label = ele.pstyle('label'); + var srcLabel = ele.pstyle('source-label'); + var tgtLabel = ele.pstyle('target-label'); + if (badLine || (!_label || !_label.value) && (!srcLabel || !srcLabel.value) && (!tgtLabel || !tgtLabel.value)) { + return; + } + context.textAlign = 'center'; + context.textBaseline = 'bottom'; + } + var applyRotation = !shiftToOriginWithBb; + var bb; + if (shiftToOriginWithBb) { + bb = shiftToOriginWithBb; + context.translate(-bb.x1, -bb.y1); + } + if (prefix == null) { + r.drawText(context, ele, null, applyRotation, useEleOpacity); + if (ele.isEdge()) { + r.drawText(context, ele, 'source', applyRotation, useEleOpacity); + r.drawText(context, ele, 'target', applyRotation, useEleOpacity); + } + } else { + r.drawText(context, ele, prefix, applyRotation, useEleOpacity); + } + if (shiftToOriginWithBb) { + context.translate(bb.x1, bb.y1); + } +}; +CRp$6.getFontCache = function (context) { + var cache; + this.fontCaches = this.fontCaches || []; + for (var i = 0; i < this.fontCaches.length; i++) { + cache = this.fontCaches[i]; + if (cache.context === context) { + return cache; + } + } + cache = { + context: context + }; + this.fontCaches.push(cache); + return cache; +}; + +// set up canvas context with font +// returns transformed text string +CRp$6.setupTextStyle = function (context, ele) { + var useEleOpacity = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + // Font style + var labelStyle = ele.pstyle('font-style').strValue; + var labelSize = ele.pstyle('font-size').pfValue + 'px'; + var labelFamily = ele.pstyle('font-family').strValue; + var labelWeight = ele.pstyle('font-weight').strValue; + var opacity = useEleOpacity ? ele.effectiveOpacity() * ele.pstyle('text-opacity').value : 1; + var outlineOpacity = ele.pstyle('text-outline-opacity').value * opacity; + var color = ele.pstyle('color').value; + var outlineColor = ele.pstyle('text-outline-color').value; + context.font = labelStyle + ' ' + labelWeight + ' ' + labelSize + ' ' + labelFamily; + context.lineJoin = 'round'; // so text outlines aren't jagged + + this.colorFillStyle(context, color[0], color[1], color[2], opacity); + this.colorStrokeStyle(context, outlineColor[0], outlineColor[1], outlineColor[2], outlineOpacity); +}; + +// TODO ensure re-used +function roundRect(ctx, x, y, width, height) { + var radius = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 5; + var stroke = arguments.length > 6 ? arguments[6] : undefined; + ctx.beginPath(); + ctx.moveTo(x + radius, y); + ctx.lineTo(x + width - radius, y); + ctx.quadraticCurveTo(x + width, y, x + width, y + radius); + ctx.lineTo(x + width, y + height - radius); + ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); + ctx.lineTo(x + radius, y + height); + ctx.quadraticCurveTo(x, y + height, x, y + height - radius); + ctx.lineTo(x, y + radius); + ctx.quadraticCurveTo(x, y, x + radius, y); + ctx.closePath(); + if (stroke) ctx.stroke();else ctx.fill(); +} +CRp$6.getTextAngle = function (ele, prefix) { + var theta; + var _p = ele._private; + var rscratch = _p.rscratch; + var pdash = prefix ? prefix + '-' : ''; + var rotation = ele.pstyle(pdash + 'text-rotation'); + var textAngle = getPrefixedProperty(rscratch, 'labelAngle', prefix); + if (rotation.strValue === 'autorotate') { + theta = ele.isEdge() ? textAngle : 0; + } else if (rotation.strValue === 'none') { + theta = 0; + } else { + theta = rotation.pfValue; + } + return theta; +}; +CRp$6.drawText = function (context, ele, prefix) { + var applyRotation = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var useEleOpacity = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; + var _p = ele._private; + var rscratch = _p.rscratch; + var parentOpacity = useEleOpacity ? ele.effectiveOpacity() : 1; + if (useEleOpacity && (parentOpacity === 0 || ele.pstyle('text-opacity').value === 0)) { + return; + } + + // use 'main' as an alias for the main label (i.e. null prefix) + if (prefix === 'main') { + prefix = null; + } + var textX = getPrefixedProperty(rscratch, 'labelX', prefix); + var textY = getPrefixedProperty(rscratch, 'labelY', prefix); + var orgTextX, orgTextY; // used for rotation + var text = this.getLabelText(ele, prefix); + if (text != null && text !== '' && !isNaN(textX) && !isNaN(textY)) { + this.setupTextStyle(context, ele, useEleOpacity); + var pdash = prefix ? prefix + '-' : ''; + var textW = getPrefixedProperty(rscratch, 'labelWidth', prefix); + var textH = getPrefixedProperty(rscratch, 'labelHeight', prefix); + var marginX = ele.pstyle(pdash + 'text-margin-x').pfValue; + var marginY = ele.pstyle(pdash + 'text-margin-y').pfValue; + var isEdge = ele.isEdge(); + var halign = ele.pstyle('text-halign').value; + var valign = ele.pstyle('text-valign').value; + if (isEdge) { + halign = 'center'; + valign = 'center'; + } + textX += marginX; + textY += marginY; + var theta; + if (!applyRotation) { + theta = 0; + } else { + theta = this.getTextAngle(ele, prefix); + } + if (theta !== 0) { + orgTextX = textX; + orgTextY = textY; + context.translate(orgTextX, orgTextY); + context.rotate(theta); + textX = 0; + textY = 0; + } + switch (valign) { + case 'top': + break; + case 'center': + textY += textH / 2; + break; + case 'bottom': + textY += textH; + break; + } + var backgroundOpacity = ele.pstyle('text-background-opacity').value; + var borderOpacity = ele.pstyle('text-border-opacity').value; + var textBorderWidth = ele.pstyle('text-border-width').pfValue; + var backgroundPadding = ele.pstyle('text-background-padding').pfValue; + var styleShape = ele.pstyle('text-background-shape').strValue; + var rounded = styleShape.indexOf('round') === 0; + var roundRadius = 2; + if (backgroundOpacity > 0 || textBorderWidth > 0 && borderOpacity > 0) { + var bgX = textX - backgroundPadding; + switch (halign) { + case 'left': + bgX -= textW; + break; + case 'center': + bgX -= textW / 2; + break; + } + var bgY = textY - textH - backgroundPadding; + var bgW = textW + 2 * backgroundPadding; + var bgH = textH + 2 * backgroundPadding; + if (backgroundOpacity > 0) { + var textFill = context.fillStyle; + var textBackgroundColor = ele.pstyle('text-background-color').value; + context.fillStyle = 'rgba(' + textBackgroundColor[0] + ',' + textBackgroundColor[1] + ',' + textBackgroundColor[2] + ',' + backgroundOpacity * parentOpacity + ')'; + if (rounded) { + roundRect(context, bgX, bgY, bgW, bgH, roundRadius); + } else { + context.fillRect(bgX, bgY, bgW, bgH); + } + context.fillStyle = textFill; + } + if (textBorderWidth > 0 && borderOpacity > 0) { + var textStroke = context.strokeStyle; + var textLineWidth = context.lineWidth; + var textBorderColor = ele.pstyle('text-border-color').value; + var textBorderStyle = ele.pstyle('text-border-style').value; + context.strokeStyle = 'rgba(' + textBorderColor[0] + ',' + textBorderColor[1] + ',' + textBorderColor[2] + ',' + borderOpacity * parentOpacity + ')'; + context.lineWidth = textBorderWidth; + if (context.setLineDash) { + // for very outofdate browsers + switch (textBorderStyle) { + case 'dotted': + context.setLineDash([1, 1]); + break; + case 'dashed': + context.setLineDash([4, 2]); + break; + case 'double': + context.lineWidth = textBorderWidth / 4; // 50% reserved for white between the two borders + context.setLineDash([]); + break; + case 'solid': + context.setLineDash([]); + break; + } + } + if (rounded) { + roundRect(context, bgX, bgY, bgW, bgH, roundRadius, 'stroke'); + } else { + context.strokeRect(bgX, bgY, bgW, bgH); + } + if (textBorderStyle === 'double') { + var whiteWidth = textBorderWidth / 2; + if (rounded) { + roundRect(context, bgX + whiteWidth, bgY + whiteWidth, bgW - whiteWidth * 2, bgH - whiteWidth * 2, roundRadius, 'stroke'); + } else { + context.strokeRect(bgX + whiteWidth, bgY + whiteWidth, bgW - whiteWidth * 2, bgH - whiteWidth * 2); + } + } + if (context.setLineDash) { + // for very outofdate browsers + context.setLineDash([]); + } + context.lineWidth = textLineWidth; + context.strokeStyle = textStroke; + } + } + var lineWidth = 2 * ele.pstyle('text-outline-width').pfValue; // *2 b/c the stroke is drawn centred on the middle + + if (lineWidth > 0) { + context.lineWidth = lineWidth; + } + if (ele.pstyle('text-wrap').value === 'wrap') { + var lines = getPrefixedProperty(rscratch, 'labelWrapCachedLines', prefix); + var lineHeight = getPrefixedProperty(rscratch, 'labelLineHeight', prefix); + var halfTextW = textW / 2; + var justification = this.getLabelJustification(ele); + if (justification === 'auto') ; else if (halign === 'left') { + // auto justification : right + if (justification === 'left') { + textX += -textW; + } else if (justification === 'center') { + textX += -halfTextW; + } // else same as auto + } else if (halign === 'center') { + // auto justfication : center + if (justification === 'left') { + textX += -halfTextW; + } else if (justification === 'right') { + textX += halfTextW; + } // else same as auto + } else if (halign === 'right') { + // auto justification : left + if (justification === 'center') { + textX += halfTextW; + } else if (justification === 'right') { + textX += textW; + } // else same as auto + } + + switch (valign) { + case 'top': + textY -= (lines.length - 1) * lineHeight; + break; + case 'center': + case 'bottom': + textY -= (lines.length - 1) * lineHeight; + break; + } + for (var l = 0; l < lines.length; l++) { + if (lineWidth > 0) { + context.strokeText(lines[l], textX, textY); + } + context.fillText(lines[l], textX, textY); + textY += lineHeight; + } + } else { + if (lineWidth > 0) { + context.strokeText(text, textX, textY); + } + context.fillText(text, textX, textY); + } + if (theta !== 0) { + context.rotate(-theta); + context.translate(-orgTextX, -orgTextY); + } + } +}; + +/* global Path2D */ +var CRp$5 = {}; +CRp$5.drawNode = function (context, node, shiftToOriginWithBb) { + var drawLabel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var shouldDrawOverlay = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; + var shouldDrawOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true; + var r = this; + var nodeWidth, nodeHeight; + var _p = node._private; + var rs = _p.rscratch; + var pos = node.position(); + if (!number$1(pos.x) || !number$1(pos.y)) { + return; // can't draw node with undefined position + } + + if (shouldDrawOpacity && !node.visible()) { + return; + } + var eleOpacity = shouldDrawOpacity ? node.effectiveOpacity() : 1; + var usePaths = r.usePaths(); + var path; + var pathCacheHit = false; + var padding = node.padding(); + nodeWidth = node.width() + 2 * padding; + nodeHeight = node.height() + 2 * padding; + + // + // setup shift + + var bb; + if (shiftToOriginWithBb) { + bb = shiftToOriginWithBb; + context.translate(-bb.x1, -bb.y1); + } + + // + // load bg image + + var bgImgProp = node.pstyle('background-image'); + var urls = bgImgProp.value; + var urlDefined = new Array(urls.length); + var image = new Array(urls.length); + var numImages = 0; + for (var i = 0; i < urls.length; i++) { + var url = urls[i]; + var defd = urlDefined[i] = url != null && url !== 'none'; + if (defd) { + var bgImgCrossOrigin = node.cy().style().getIndexedStyle(node, 'background-image-crossorigin', 'value', i); + numImages++; + + // get image, and if not loaded then ask to redraw when later loaded + image[i] = r.getCachedImage(url, bgImgCrossOrigin, function () { + _p.backgroundTimestamp = Date.now(); + node.emitAndNotify('background'); + }); + } + } + + // + // setup styles + + var darkness = node.pstyle('background-blacken').value; + var borderWidth = node.pstyle('border-width').pfValue; + var bgOpacity = node.pstyle('background-opacity').value * eleOpacity; + var borderColor = node.pstyle('border-color').value; + var borderStyle = node.pstyle('border-style').value; + var borderOpacity = node.pstyle('border-opacity').value * eleOpacity; + var outlineWidth = node.pstyle('outline-width').pfValue; + var outlineColor = node.pstyle('outline-color').value; + var outlineStyle = node.pstyle('outline-style').value; + var outlineOpacity = node.pstyle('outline-opacity').value * eleOpacity; + var outlineOffset = node.pstyle('outline-offset').value; + context.lineJoin = 'miter'; // so borders are square with the node shape + + var setupShapeColor = function setupShapeColor() { + var bgOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : bgOpacity; + r.eleFillStyle(context, node, bgOpy); + }; + var setupBorderColor = function setupBorderColor() { + var bdrOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : borderOpacity; + r.colorStrokeStyle(context, borderColor[0], borderColor[1], borderColor[2], bdrOpy); + }; + var setupOutlineColor = function setupOutlineColor() { + var otlnOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : outlineOpacity; + r.colorStrokeStyle(context, outlineColor[0], outlineColor[1], outlineColor[2], otlnOpy); + }; + + // + // setup shape + + var getPath = function getPath(width, height, shape, points) { + var pathCache = r.nodePathCache = r.nodePathCache || []; + var key = hashStrings(shape === 'polygon' ? shape + ',' + points.join(',') : shape, '' + height, '' + width); + var cachedPath = pathCache[key]; + var path; + var cacheHit = false; + if (cachedPath != null) { + path = cachedPath; + cacheHit = true; + rs.pathCache = path; + } else { + path = new Path2D(); + pathCache[key] = rs.pathCache = path; + } + return { + path: path, + cacheHit: cacheHit + }; + }; + var styleShape = node.pstyle('shape').strValue; + var shapePts = node.pstyle('shape-polygon-points').pfValue; + if (usePaths) { + context.translate(pos.x, pos.y); + var shapePath = getPath(nodeWidth, nodeHeight, styleShape, shapePts); + path = shapePath.path; + pathCacheHit = shapePath.cacheHit; + } + var drawShape = function drawShape() { + if (!pathCacheHit) { + var npos = pos; + if (usePaths) { + npos = { + x: 0, + y: 0 + }; + } + r.nodeShapes[r.getNodeShape(node)].draw(path || context, npos.x, npos.y, nodeWidth, nodeHeight); + } + if (usePaths) { + context.fill(path); + } else { + context.fill(); + } + }; + var drawImages = function drawImages() { + var nodeOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : eleOpacity; + var inside = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var prevBging = _p.backgrounding; + var totalCompleted = 0; + for (var _i = 0; _i < image.length; _i++) { + var bgContainment = node.cy().style().getIndexedStyle(node, 'background-image-containment', 'value', _i); + if (inside && bgContainment === 'over' || !inside && bgContainment === 'inside') { + totalCompleted++; + continue; + } + if (urlDefined[_i] && image[_i].complete && !image[_i].error) { + totalCompleted++; + r.drawInscribedImage(context, image[_i], node, _i, nodeOpacity); + } + } + _p.backgrounding = !(totalCompleted === numImages); + if (prevBging !== _p.backgrounding) { + // update style b/c :backgrounding state changed + node.updateStyle(false); + } + }; + var drawPie = function drawPie() { + var redrawShape = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var pieOpacity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : eleOpacity; + if (r.hasPie(node)) { + r.drawPie(context, node, pieOpacity); + + // redraw/restore path if steps after pie need it + if (redrawShape) { + if (!usePaths) { + r.nodeShapes[r.getNodeShape(node)].draw(context, pos.x, pos.y, nodeWidth, nodeHeight); + } + } + } + }; + var darken = function darken() { + var darkenOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : eleOpacity; + var opacity = (darkness > 0 ? darkness : -darkness) * darkenOpacity; + var c = darkness > 0 ? 0 : 255; + if (darkness !== 0) { + r.colorFillStyle(context, c, c, c, opacity); + if (usePaths) { + context.fill(path); + } else { + context.fill(); + } + } + }; + var drawBorder = function drawBorder() { + if (borderWidth > 0) { + context.lineWidth = borderWidth; + context.lineCap = 'butt'; + if (context.setLineDash) { + // for very outofdate browsers + switch (borderStyle) { + case 'dotted': + context.setLineDash([1, 1]); + break; + case 'dashed': + context.setLineDash([4, 2]); + break; + case 'solid': + case 'double': + context.setLineDash([]); + break; + } + } + if (usePaths) { + context.stroke(path); + } else { + context.stroke(); + } + if (borderStyle === 'double') { + context.lineWidth = borderWidth / 3; + var gco = context.globalCompositeOperation; + context.globalCompositeOperation = 'destination-out'; + if (usePaths) { + context.stroke(path); + } else { + context.stroke(); + } + context.globalCompositeOperation = gco; + } + + // reset in case we changed the border style + if (context.setLineDash) { + // for very outofdate browsers + context.setLineDash([]); + } + } + }; + var drawOutline = function drawOutline() { + if (outlineWidth > 0) { + context.lineWidth = outlineWidth; + context.lineCap = 'butt'; + if (context.setLineDash) { + // for very outofdate browsers + switch (outlineStyle) { + case 'dotted': + context.setLineDash([1, 1]); + break; + case 'dashed': + context.setLineDash([4, 2]); + break; + case 'solid': + case 'double': + context.setLineDash([]); + break; + } + } + var npos = pos; + if (usePaths) { + npos = { + x: 0, + y: 0 + }; + } + var shape = r.getNodeShape(node); + var scaleX = (nodeWidth + borderWidth + (outlineWidth + outlineOffset)) / nodeWidth; + var scaleY = (nodeHeight + borderWidth + (outlineWidth + outlineOffset)) / nodeHeight; + var sWidth = nodeWidth * scaleX; + var sHeight = nodeHeight * scaleY; + var points = r.nodeShapes[shape].points; + var _path; + if (usePaths) { + var outlinePath = getPath(sWidth, sHeight, shape, points); + _path = outlinePath.path; + } + + // draw the outline path, either by using expanded points or by scaling + // the dimensions, depending on shape + if (shape === "ellipse") { + r.drawEllipsePath(_path || context, npos.x, npos.y, sWidth, sHeight); + } else if (['round-diamond', 'round-heptagon', 'round-hexagon', 'round-octagon', 'round-pentagon', 'round-polygon', 'round-triangle', 'round-tag'].includes(shape)) { + var sMult = 0; + var offsetX = 0; + var offsetY = 0; + if (shape === 'round-diamond') { + sMult = (borderWidth + outlineOffset + outlineWidth) * 1.4; + } else if (shape === 'round-heptagon') { + sMult = (borderWidth + outlineOffset + outlineWidth) * 1.075; + offsetY = -(borderWidth / 2 + outlineOffset + outlineWidth) / 35; + } else if (shape === 'round-hexagon') { + sMult = (borderWidth + outlineOffset + outlineWidth) * 1.12; + } else if (shape === 'round-pentagon') { + sMult = (borderWidth + outlineOffset + outlineWidth) * 1.13; + offsetY = -(borderWidth / 2 + outlineOffset + outlineWidth) / 15; + } else if (shape === 'round-tag') { + sMult = (borderWidth + outlineOffset + outlineWidth) * 1.12; + offsetX = (borderWidth / 2 + outlineWidth + outlineOffset) * .07; + } else if (shape === 'round-triangle') { + sMult = (borderWidth + outlineOffset + outlineWidth) * (Math.PI / 2); + offsetY = -(borderWidth + outlineOffset / 2 + outlineWidth) / Math.PI; + } + if (sMult !== 0) { + scaleX = (nodeWidth + sMult) / nodeWidth; + scaleY = (nodeHeight + sMult) / nodeHeight; + } + r.drawRoundPolygonPath(_path || context, npos.x + offsetX, npos.y + offsetY, nodeWidth * scaleX, nodeHeight * scaleY, points); + } else if (['roundrectangle', 'round-rectangle'].includes(shape)) { + r.drawRoundRectanglePath(_path || context, npos.x, npos.y, sWidth, sHeight); + } else if (['cutrectangle', 'cut-rectangle'].includes(shape)) { + r.drawCutRectanglePath(_path || context, npos.x, npos.y, sWidth, sHeight); + } else if (['bottomroundrectangle', 'bottom-round-rectangle'].includes(shape)) { + r.drawBottomRoundRectanglePath(_path || context, npos.x, npos.y, sWidth, sHeight); + } else if (shape === "barrel") { + r.drawBarrelPath(_path || context, npos.x, npos.y, sWidth, sHeight); + } else if (shape.startsWith("polygon") || ['rhomboid', 'right-rhomboid', 'round-tag', 'tag', 'vee'].includes(shape)) { + var pad = (borderWidth + outlineWidth + outlineOffset) / nodeWidth; + points = joinLines(expandPolygon(points, pad)); + r.drawPolygonPath(_path || context, npos.x, npos.y, nodeWidth, nodeHeight, points); + } else { + var _pad = (borderWidth + outlineWidth + outlineOffset) / nodeWidth; + points = joinLines(expandPolygon(points, -_pad)); + r.drawPolygonPath(_path || context, npos.x, npos.y, nodeWidth, nodeHeight, points); + } + if (usePaths) { + context.stroke(_path); + } else { + context.stroke(); + } + if (outlineStyle === 'double') { + context.lineWidth = borderWidth / 3; + var gco = context.globalCompositeOperation; + context.globalCompositeOperation = 'destination-out'; + if (usePaths) { + context.stroke(_path); + } else { + context.stroke(); + } + context.globalCompositeOperation = gco; + } + + // reset in case we changed the border style + if (context.setLineDash) { + // for very outofdate browsers + context.setLineDash([]); + } + } + }; + var drawOverlay = function drawOverlay() { + if (shouldDrawOverlay) { + r.drawNodeOverlay(context, node, pos, nodeWidth, nodeHeight); + } + }; + var drawUnderlay = function drawUnderlay() { + if (shouldDrawOverlay) { + r.drawNodeUnderlay(context, node, pos, nodeWidth, nodeHeight); + } + }; + var drawText = function drawText() { + r.drawElementText(context, node, null, drawLabel); + }; + var ghost = node.pstyle('ghost').value === 'yes'; + if (ghost) { + var gx = node.pstyle('ghost-offset-x').pfValue; + var gy = node.pstyle('ghost-offset-y').pfValue; + var ghostOpacity = node.pstyle('ghost-opacity').value; + var effGhostOpacity = ghostOpacity * eleOpacity; + context.translate(gx, gy); + setupOutlineColor(); + drawOutline(); + setupShapeColor(ghostOpacity * bgOpacity); + drawShape(); + drawImages(effGhostOpacity, true); + setupBorderColor(ghostOpacity * borderOpacity); + drawBorder(); + drawPie(darkness !== 0 || borderWidth !== 0); + drawImages(effGhostOpacity, false); + darken(effGhostOpacity); + context.translate(-gx, -gy); + } + if (usePaths) { + context.translate(-pos.x, -pos.y); + } + drawUnderlay(); + if (usePaths) { + context.translate(pos.x, pos.y); + } + setupOutlineColor(); + drawOutline(); + setupShapeColor(); + drawShape(); + drawImages(eleOpacity, true); + setupBorderColor(); + drawBorder(); + drawPie(darkness !== 0 || borderWidth !== 0); + drawImages(eleOpacity, false); + darken(); + if (usePaths) { + context.translate(-pos.x, -pos.y); + } + drawText(); + drawOverlay(); + + // + // clean up shift + + if (shiftToOriginWithBb) { + context.translate(bb.x1, bb.y1); + } +}; +var drawNodeOverlayUnderlay = function drawNodeOverlayUnderlay(overlayOrUnderlay) { + if (!['overlay', 'underlay'].includes(overlayOrUnderlay)) { + throw new Error('Invalid state'); + } + return function (context, node, pos, nodeWidth, nodeHeight) { + var r = this; + if (!node.visible()) { + return; + } + var padding = node.pstyle("".concat(overlayOrUnderlay, "-padding")).pfValue; + var opacity = node.pstyle("".concat(overlayOrUnderlay, "-opacity")).value; + var color = node.pstyle("".concat(overlayOrUnderlay, "-color")).value; + var shape = node.pstyle("".concat(overlayOrUnderlay, "-shape")).value; + if (opacity > 0) { + pos = pos || node.position(); + if (nodeWidth == null || nodeHeight == null) { + var _padding = node.padding(); + nodeWidth = node.width() + 2 * _padding; + nodeHeight = node.height() + 2 * _padding; + } + r.colorFillStyle(context, color[0], color[1], color[2], opacity); + r.nodeShapes[shape].draw(context, pos.x, pos.y, nodeWidth + padding * 2, nodeHeight + padding * 2); + context.fill(); + } + }; +}; +CRp$5.drawNodeOverlay = drawNodeOverlayUnderlay('overlay'); +CRp$5.drawNodeUnderlay = drawNodeOverlayUnderlay('underlay'); + +// does the node have at least one pie piece? +CRp$5.hasPie = function (node) { + node = node[0]; // ensure ele ref + + return node._private.hasPie; +}; +CRp$5.drawPie = function (context, node, nodeOpacity, pos) { + node = node[0]; // ensure ele ref + pos = pos || node.position(); + var cyStyle = node.cy().style(); + var pieSize = node.pstyle('pie-size'); + var x = pos.x; + var y = pos.y; + var nodeW = node.width(); + var nodeH = node.height(); + var radius = Math.min(nodeW, nodeH) / 2; // must fit in node + var lastPercent = 0; // what % to continue drawing pie slices from on [0, 1] + var usePaths = this.usePaths(); + if (usePaths) { + x = 0; + y = 0; + } + if (pieSize.units === '%') { + radius = radius * pieSize.pfValue; + } else if (pieSize.pfValue !== undefined) { + radius = pieSize.pfValue / 2; + } + for (var i = 1; i <= cyStyle.pieBackgroundN; i++) { + // 1..N + var size = node.pstyle('pie-' + i + '-background-size').value; + var color = node.pstyle('pie-' + i + '-background-color').value; + var opacity = node.pstyle('pie-' + i + '-background-opacity').value * nodeOpacity; + var percent = size / 100; // map integer range [0, 100] to [0, 1] + + // percent can't push beyond 1 + if (percent + lastPercent > 1) { + percent = 1 - lastPercent; + } + var angleStart = 1.5 * Math.PI + 2 * Math.PI * lastPercent; // start at 12 o'clock and go clockwise + var angleDelta = 2 * Math.PI * percent; + var angleEnd = angleStart + angleDelta; + + // ignore if + // - zero size + // - we're already beyond the full circle + // - adding the current slice would go beyond the full circle + if (size === 0 || lastPercent >= 1 || lastPercent + percent > 1) { + continue; + } + context.beginPath(); + context.moveTo(x, y); + context.arc(x, y, radius, angleStart, angleEnd); + context.closePath(); + this.colorFillStyle(context, color[0], color[1], color[2], opacity); + context.fill(); + lastPercent += percent; + } +}; + +var CRp$4 = {}; +var motionBlurDelay = 100; + +// var isFirefox = typeof InstallTrigger !== 'undefined'; + +CRp$4.getPixelRatio = function () { + var context = this.data.contexts[0]; + if (this.forcedPixelRatio != null) { + return this.forcedPixelRatio; + } + var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1; + return (window.devicePixelRatio || 1) / backingStore; // eslint-disable-line no-undef +}; + +CRp$4.paintCache = function (context) { + var caches = this.paintCaches = this.paintCaches || []; + var needToCreateCache = true; + var cache; + for (var i = 0; i < caches.length; i++) { + cache = caches[i]; + if (cache.context === context) { + needToCreateCache = false; + break; + } + } + if (needToCreateCache) { + cache = { + context: context + }; + caches.push(cache); + } + return cache; +}; +CRp$4.createGradientStyleFor = function (context, shapeStyleName, ele, fill, opacity) { + var gradientStyle; + var usePaths = this.usePaths(); + var colors = ele.pstyle(shapeStyleName + '-gradient-stop-colors').value, + positions = ele.pstyle(shapeStyleName + '-gradient-stop-positions').pfValue; + if (fill === 'radial-gradient') { + if (ele.isEdge()) { + var start = ele.sourceEndpoint(), + end = ele.targetEndpoint(), + mid = ele.midpoint(); + var d1 = dist(start, mid); + var d2 = dist(end, mid); + gradientStyle = context.createRadialGradient(mid.x, mid.y, 0, mid.x, mid.y, Math.max(d1, d2)); + } else { + var pos = usePaths ? { + x: 0, + y: 0 + } : ele.position(), + width = ele.paddedWidth(), + height = ele.paddedHeight(); + gradientStyle = context.createRadialGradient(pos.x, pos.y, 0, pos.x, pos.y, Math.max(width, height)); + } + } else { + if (ele.isEdge()) { + var _start = ele.sourceEndpoint(), + _end = ele.targetEndpoint(); + gradientStyle = context.createLinearGradient(_start.x, _start.y, _end.x, _end.y); + } else { + var _pos = usePaths ? { + x: 0, + y: 0 + } : ele.position(), + _width = ele.paddedWidth(), + _height = ele.paddedHeight(), + halfWidth = _width / 2, + halfHeight = _height / 2; + var direction = ele.pstyle('background-gradient-direction').value; + switch (direction) { + case 'to-bottom': + gradientStyle = context.createLinearGradient(_pos.x, _pos.y - halfHeight, _pos.x, _pos.y + halfHeight); + break; + case 'to-top': + gradientStyle = context.createLinearGradient(_pos.x, _pos.y + halfHeight, _pos.x, _pos.y - halfHeight); + break; + case 'to-left': + gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y, _pos.x - halfWidth, _pos.y); + break; + case 'to-right': + gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y, _pos.x + halfWidth, _pos.y); + break; + case 'to-bottom-right': + case 'to-right-bottom': + gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y - halfHeight, _pos.x + halfWidth, _pos.y + halfHeight); + break; + case 'to-top-right': + case 'to-right-top': + gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y + halfHeight, _pos.x + halfWidth, _pos.y - halfHeight); + break; + case 'to-bottom-left': + case 'to-left-bottom': + gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y - halfHeight, _pos.x - halfWidth, _pos.y + halfHeight); + break; + case 'to-top-left': + case 'to-left-top': + gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y + halfHeight, _pos.x - halfWidth, _pos.y - halfHeight); + break; + } + } + } + if (!gradientStyle) return null; // invalid gradient style + + var hasPositions = positions.length === colors.length; + var length = colors.length; + for (var i = 0; i < length; i++) { + gradientStyle.addColorStop(hasPositions ? positions[i] : i / (length - 1), 'rgba(' + colors[i][0] + ',' + colors[i][1] + ',' + colors[i][2] + ',' + opacity + ')'); + } + return gradientStyle; +}; +CRp$4.gradientFillStyle = function (context, ele, fill, opacity) { + var gradientStyle = this.createGradientStyleFor(context, 'background', ele, fill, opacity); + if (!gradientStyle) return null; // error + context.fillStyle = gradientStyle; +}; +CRp$4.colorFillStyle = function (context, r, g, b, a) { + context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; + // turn off for now, seems context does its own caching + + // var cache = this.paintCache(context); + + // var fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; + + // if( cache.fillStyle !== fillStyle ){ + // context.fillStyle = cache.fillStyle = fillStyle; + // } +}; + +CRp$4.eleFillStyle = function (context, ele, opacity) { + var backgroundFill = ele.pstyle('background-fill').value; + if (backgroundFill === 'linear-gradient' || backgroundFill === 'radial-gradient') { + this.gradientFillStyle(context, ele, backgroundFill, opacity); + } else { + var backgroundColor = ele.pstyle('background-color').value; + this.colorFillStyle(context, backgroundColor[0], backgroundColor[1], backgroundColor[2], opacity); + } +}; +CRp$4.gradientStrokeStyle = function (context, ele, fill, opacity) { + var gradientStyle = this.createGradientStyleFor(context, 'line', ele, fill, opacity); + if (!gradientStyle) return null; // error + context.strokeStyle = gradientStyle; +}; +CRp$4.colorStrokeStyle = function (context, r, g, b, a) { + context.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; + // turn off for now, seems context does its own caching + + // var cache = this.paintCache(context); + + // var strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; + + // if( cache.strokeStyle !== strokeStyle ){ + // context.strokeStyle = cache.strokeStyle = strokeStyle; + // } +}; + +CRp$4.eleStrokeStyle = function (context, ele, opacity) { + var lineFill = ele.pstyle('line-fill').value; + if (lineFill === 'linear-gradient' || lineFill === 'radial-gradient') { + this.gradientStrokeStyle(context, ele, lineFill, opacity); + } else { + var lineColor = ele.pstyle('line-color').value; + this.colorStrokeStyle(context, lineColor[0], lineColor[1], lineColor[2], opacity); + } +}; + +// Resize canvas +CRp$4.matchCanvasSize = function (container) { + var r = this; + var data = r.data; + var bb = r.findContainerClientCoords(); + var width = bb[2]; + var height = bb[3]; + var pixelRatio = r.getPixelRatio(); + var mbPxRatio = r.motionBlurPxRatio; + if (container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_NODE] || container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_DRAG]) { + pixelRatio = mbPxRatio; + } + var canvasWidth = width * pixelRatio; + var canvasHeight = height * pixelRatio; + var canvas; + if (canvasWidth === r.canvasWidth && canvasHeight === r.canvasHeight) { + return; // save cycles if same + } + + r.fontCaches = null; // resizing resets the style + + var canvasContainer = data.canvasContainer; + canvasContainer.style.width = width + 'px'; + canvasContainer.style.height = height + 'px'; + for (var i = 0; i < r.CANVAS_LAYERS; i++) { + canvas = data.canvases[i]; + canvas.width = canvasWidth; + canvas.height = canvasHeight; + canvas.style.width = width + 'px'; + canvas.style.height = height + 'px'; + } + for (var i = 0; i < r.BUFFER_COUNT; i++) { + canvas = data.bufferCanvases[i]; + canvas.width = canvasWidth; + canvas.height = canvasHeight; + canvas.style.width = width + 'px'; + canvas.style.height = height + 'px'; + } + r.textureMult = 1; + if (pixelRatio <= 1) { + canvas = data.bufferCanvases[r.TEXTURE_BUFFER]; + r.textureMult = 2; + canvas.width = canvasWidth * r.textureMult; + canvas.height = canvasHeight * r.textureMult; + } + r.canvasWidth = canvasWidth; + r.canvasHeight = canvasHeight; +}; +CRp$4.renderTo = function (cxt, zoom, pan, pxRatio) { + this.render({ + forcedContext: cxt, + forcedZoom: zoom, + forcedPan: pan, + drawAllLayers: true, + forcedPxRatio: pxRatio + }); +}; +CRp$4.render = function (options) { + options = options || staticEmptyObject(); + var forcedContext = options.forcedContext; + var drawAllLayers = options.drawAllLayers; + var drawOnlyNodeLayer = options.drawOnlyNodeLayer; + var forcedZoom = options.forcedZoom; + var forcedPan = options.forcedPan; + var r = this; + var pixelRatio = options.forcedPxRatio === undefined ? this.getPixelRatio() : options.forcedPxRatio; + var cy = r.cy; + var data = r.data; + var needDraw = data.canvasNeedsRedraw; + var textureDraw = r.textureOnViewport && !forcedContext && (r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming); + var motionBlur = options.motionBlur !== undefined ? options.motionBlur : r.motionBlur; + var mbPxRatio = r.motionBlurPxRatio; + var hasCompoundNodes = cy.hasCompoundNodes(); + var inNodeDragGesture = r.hoverData.draggingEles; + var inBoxSelection = r.hoverData.selecting || r.touchData.selecting ? true : false; + motionBlur = motionBlur && !forcedContext && r.motionBlurEnabled && !inBoxSelection; + var motionBlurFadeEffect = motionBlur; + if (!forcedContext) { + if (r.prevPxRatio !== pixelRatio) { + r.invalidateContainerClientCoordsCache(); + r.matchCanvasSize(r.container); + r.redrawHint('eles', true); + r.redrawHint('drag', true); + } + r.prevPxRatio = pixelRatio; + } + if (!forcedContext && r.motionBlurTimeout) { + clearTimeout(r.motionBlurTimeout); + } + if (motionBlur) { + if (r.mbFrames == null) { + r.mbFrames = 0; + } + r.mbFrames++; + if (r.mbFrames < 3) { + // need several frames before even high quality motionblur + motionBlurFadeEffect = false; + } + + // go to lower quality blurry frames when several m/b frames have been rendered (avoids flashing) + if (r.mbFrames > r.minMbLowQualFrames) { + //r.fullQualityMb = false; + r.motionBlurPxRatio = r.mbPxRBlurry; + } + } + if (r.clearingMotionBlur) { + r.motionBlurPxRatio = 1; + } + + // b/c drawToContext() may be async w.r.t. redraw(), keep track of last texture frame + // because a rogue async texture frame would clear needDraw + if (r.textureDrawLastFrame && !textureDraw) { + needDraw[r.NODE] = true; + needDraw[r.SELECT_BOX] = true; + } + var style = cy.style(); + var zoom = cy.zoom(); + var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom; + var pan = cy.pan(); + var effectivePan = { + x: pan.x, + y: pan.y + }; + var vp = { + zoom: zoom, + pan: { + x: pan.x, + y: pan.y + } + }; + var prevVp = r.prevViewport; + var viewportIsDiff = prevVp === undefined || vp.zoom !== prevVp.zoom || vp.pan.x !== prevVp.pan.x || vp.pan.y !== prevVp.pan.y; + + // we want the low quality motionblur only when the viewport is being manipulated etc (where it's not noticed) + if (!viewportIsDiff && !(inNodeDragGesture && !hasCompoundNodes)) { + r.motionBlurPxRatio = 1; + } + if (forcedPan) { + effectivePan = forcedPan; + } + + // apply pixel ratio + + effectiveZoom *= pixelRatio; + effectivePan.x *= pixelRatio; + effectivePan.y *= pixelRatio; + var eles = r.getCachedZSortedEles(); + function mbclear(context, x, y, w, h) { + var gco = context.globalCompositeOperation; + context.globalCompositeOperation = 'destination-out'; + r.colorFillStyle(context, 255, 255, 255, r.motionBlurTransparency); + context.fillRect(x, y, w, h); + context.globalCompositeOperation = gco; + } + function setContextTransform(context, clear) { + var ePan, eZoom, w, h; + if (!r.clearingMotionBlur && (context === data.bufferContexts[r.MOTIONBLUR_BUFFER_NODE] || context === data.bufferContexts[r.MOTIONBLUR_BUFFER_DRAG])) { + ePan = { + x: pan.x * mbPxRatio, + y: pan.y * mbPxRatio + }; + eZoom = zoom * mbPxRatio; + w = r.canvasWidth * mbPxRatio; + h = r.canvasHeight * mbPxRatio; + } else { + ePan = effectivePan; + eZoom = effectiveZoom; + w = r.canvasWidth; + h = r.canvasHeight; + } + context.setTransform(1, 0, 0, 1, 0, 0); + if (clear === 'motionBlur') { + mbclear(context, 0, 0, w, h); + } else if (!forcedContext && (clear === undefined || clear)) { + context.clearRect(0, 0, w, h); + } + if (!drawAllLayers) { + context.translate(ePan.x, ePan.y); + context.scale(eZoom, eZoom); + } + if (forcedPan) { + context.translate(forcedPan.x, forcedPan.y); + } + if (forcedZoom) { + context.scale(forcedZoom, forcedZoom); + } + } + if (!textureDraw) { + r.textureDrawLastFrame = false; + } + if (textureDraw) { + r.textureDrawLastFrame = true; + if (!r.textureCache) { + r.textureCache = {}; + r.textureCache.bb = cy.mutableElements().boundingBox(); + r.textureCache.texture = r.data.bufferCanvases[r.TEXTURE_BUFFER]; + var cxt = r.data.bufferContexts[r.TEXTURE_BUFFER]; + cxt.setTransform(1, 0, 0, 1, 0, 0); + cxt.clearRect(0, 0, r.canvasWidth * r.textureMult, r.canvasHeight * r.textureMult); + r.render({ + forcedContext: cxt, + drawOnlyNodeLayer: true, + forcedPxRatio: pixelRatio * r.textureMult + }); + var vp = r.textureCache.viewport = { + zoom: cy.zoom(), + pan: cy.pan(), + width: r.canvasWidth, + height: r.canvasHeight + }; + vp.mpan = { + x: (0 - vp.pan.x) / vp.zoom, + y: (0 - vp.pan.y) / vp.zoom + }; + } + needDraw[r.DRAG] = false; + needDraw[r.NODE] = false; + var context = data.contexts[r.NODE]; + var texture = r.textureCache.texture; + var vp = r.textureCache.viewport; + context.setTransform(1, 0, 0, 1, 0, 0); + if (motionBlur) { + mbclear(context, 0, 0, vp.width, vp.height); + } else { + context.clearRect(0, 0, vp.width, vp.height); + } + var outsideBgColor = style.core('outside-texture-bg-color').value; + var outsideBgOpacity = style.core('outside-texture-bg-opacity').value; + r.colorFillStyle(context, outsideBgColor[0], outsideBgColor[1], outsideBgColor[2], outsideBgOpacity); + context.fillRect(0, 0, vp.width, vp.height); + var zoom = cy.zoom(); + setContextTransform(context, false); + context.clearRect(vp.mpan.x, vp.mpan.y, vp.width / vp.zoom / pixelRatio, vp.height / vp.zoom / pixelRatio); + context.drawImage(texture, vp.mpan.x, vp.mpan.y, vp.width / vp.zoom / pixelRatio, vp.height / vp.zoom / pixelRatio); + } else if (r.textureOnViewport && !forcedContext) { + // clear the cache since we don't need it + r.textureCache = null; + } + var extent = cy.extent(); + var vpManip = r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming || r.hoverData.draggingEles || r.cy.animated(); + var hideEdges = r.hideEdgesOnViewport && vpManip; + var needMbClear = []; + needMbClear[r.NODE] = !needDraw[r.NODE] && motionBlur && !r.clearedForMotionBlur[r.NODE] || r.clearingMotionBlur; + if (needMbClear[r.NODE]) { + r.clearedForMotionBlur[r.NODE] = true; + } + needMbClear[r.DRAG] = !needDraw[r.DRAG] && motionBlur && !r.clearedForMotionBlur[r.DRAG] || r.clearingMotionBlur; + if (needMbClear[r.DRAG]) { + r.clearedForMotionBlur[r.DRAG] = true; + } + if (needDraw[r.NODE] || drawAllLayers || drawOnlyNodeLayer || needMbClear[r.NODE]) { + var useBuffer = motionBlur && !needMbClear[r.NODE] && mbPxRatio !== 1; + var context = forcedContext || (useBuffer ? r.data.bufferContexts[r.MOTIONBLUR_BUFFER_NODE] : data.contexts[r.NODE]); + var clear = motionBlur && !useBuffer ? 'motionBlur' : undefined; + setContextTransform(context, clear); + if (hideEdges) { + r.drawCachedNodes(context, eles.nondrag, pixelRatio, extent); + } else { + r.drawLayeredElements(context, eles.nondrag, pixelRatio, extent); + } + if (r.debug) { + r.drawDebugPoints(context, eles.nondrag); + } + if (!drawAllLayers && !motionBlur) { + needDraw[r.NODE] = false; + } + } + if (!drawOnlyNodeLayer && (needDraw[r.DRAG] || drawAllLayers || needMbClear[r.DRAG])) { + var useBuffer = motionBlur && !needMbClear[r.DRAG] && mbPxRatio !== 1; + var context = forcedContext || (useBuffer ? r.data.bufferContexts[r.MOTIONBLUR_BUFFER_DRAG] : data.contexts[r.DRAG]); + setContextTransform(context, motionBlur && !useBuffer ? 'motionBlur' : undefined); + if (hideEdges) { + r.drawCachedNodes(context, eles.drag, pixelRatio, extent); + } else { + r.drawCachedElements(context, eles.drag, pixelRatio, extent); + } + if (r.debug) { + r.drawDebugPoints(context, eles.drag); + } + if (!drawAllLayers && !motionBlur) { + needDraw[r.DRAG] = false; + } + } + if (r.showFps || !drawOnlyNodeLayer && needDraw[r.SELECT_BOX] && !drawAllLayers) { + var context = forcedContext || data.contexts[r.SELECT_BOX]; + setContextTransform(context); + if (r.selection[4] == 1 && (r.hoverData.selecting || r.touchData.selecting)) { + var zoom = r.cy.zoom(); + var borderWidth = style.core('selection-box-border-width').value / zoom; + context.lineWidth = borderWidth; + context.fillStyle = 'rgba(' + style.core('selection-box-color').value[0] + ',' + style.core('selection-box-color').value[1] + ',' + style.core('selection-box-color').value[2] + ',' + style.core('selection-box-opacity').value + ')'; + context.fillRect(r.selection[0], r.selection[1], r.selection[2] - r.selection[0], r.selection[3] - r.selection[1]); + if (borderWidth > 0) { + context.strokeStyle = 'rgba(' + style.core('selection-box-border-color').value[0] + ',' + style.core('selection-box-border-color').value[1] + ',' + style.core('selection-box-border-color').value[2] + ',' + style.core('selection-box-opacity').value + ')'; + context.strokeRect(r.selection[0], r.selection[1], r.selection[2] - r.selection[0], r.selection[3] - r.selection[1]); + } + } + if (data.bgActivePosistion && !r.hoverData.selecting) { + var zoom = r.cy.zoom(); + var pos = data.bgActivePosistion; + context.fillStyle = 'rgba(' + style.core('active-bg-color').value[0] + ',' + style.core('active-bg-color').value[1] + ',' + style.core('active-bg-color').value[2] + ',' + style.core('active-bg-opacity').value + ')'; + context.beginPath(); + context.arc(pos.x, pos.y, style.core('active-bg-size').pfValue / zoom, 0, 2 * Math.PI); + context.fill(); + } + var timeToRender = r.lastRedrawTime; + if (r.showFps && timeToRender) { + timeToRender = Math.round(timeToRender); + var fps = Math.round(1000 / timeToRender); + context.setTransform(1, 0, 0, 1, 0, 0); + context.fillStyle = 'rgba(255, 0, 0, 0.75)'; + context.strokeStyle = 'rgba(255, 0, 0, 0.75)'; + context.lineWidth = 1; + context.fillText('1 frame = ' + timeToRender + ' ms = ' + fps + ' fps', 0, 20); + var maxFps = 60; + context.strokeRect(0, 30, 250, 20); + context.fillRect(0, 30, 250 * Math.min(fps / maxFps, 1), 20); + } + if (!drawAllLayers) { + needDraw[r.SELECT_BOX] = false; + } + } + + // motionblur: blit rendered blurry frames + if (motionBlur && mbPxRatio !== 1) { + var cxtNode = data.contexts[r.NODE]; + var txtNode = r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_NODE]; + var cxtDrag = data.contexts[r.DRAG]; + var txtDrag = r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_DRAG]; + var drawMotionBlur = function drawMotionBlur(cxt, txt, needClear) { + cxt.setTransform(1, 0, 0, 1, 0, 0); + if (needClear || !motionBlurFadeEffect) { + cxt.clearRect(0, 0, r.canvasWidth, r.canvasHeight); + } else { + mbclear(cxt, 0, 0, r.canvasWidth, r.canvasHeight); + } + var pxr = mbPxRatio; + cxt.drawImage(txt, + // img + 0, 0, + // sx, sy + r.canvasWidth * pxr, r.canvasHeight * pxr, + // sw, sh + 0, 0, + // x, y + r.canvasWidth, r.canvasHeight // w, h + ); + }; + + if (needDraw[r.NODE] || needMbClear[r.NODE]) { + drawMotionBlur(cxtNode, txtNode, needMbClear[r.NODE]); + needDraw[r.NODE] = false; + } + if (needDraw[r.DRAG] || needMbClear[r.DRAG]) { + drawMotionBlur(cxtDrag, txtDrag, needMbClear[r.DRAG]); + needDraw[r.DRAG] = false; + } + } + r.prevViewport = vp; + if (r.clearingMotionBlur) { + r.clearingMotionBlur = false; + r.motionBlurCleared = true; + r.motionBlur = true; + } + if (motionBlur) { + r.motionBlurTimeout = setTimeout(function () { + r.motionBlurTimeout = null; + r.clearedForMotionBlur[r.NODE] = false; + r.clearedForMotionBlur[r.DRAG] = false; + r.motionBlur = false; + r.clearingMotionBlur = !textureDraw; + r.mbFrames = 0; + needDraw[r.NODE] = true; + needDraw[r.DRAG] = true; + r.redraw(); + }, motionBlurDelay); + } + if (!forcedContext) { + cy.emit('render'); + } +}; + +var CRp$3 = {}; + +// @O Polygon drawing +CRp$3.drawPolygonPath = function (context, x, y, width, height, points) { + var halfW = width / 2; + var halfH = height / 2; + if (context.beginPath) { + context.beginPath(); + } + context.moveTo(x + halfW * points[0], y + halfH * points[1]); + for (var i = 1; i < points.length / 2; i++) { + context.lineTo(x + halfW * points[i * 2], y + halfH * points[i * 2 + 1]); + } + context.closePath(); +}; +CRp$3.drawRoundPolygonPath = function (context, x, y, width, height, points) { + var halfW = width / 2; + var halfH = height / 2; + var cornerRadius = getRoundPolygonRadius(width, height); + if (context.beginPath) { + context.beginPath(); + } + for (var _i = 0; _i < points.length / 4; _i++) { + var sourceUv = void 0, + destUv = void 0; + if (_i === 0) { + sourceUv = points.length - 2; + } else { + sourceUv = _i * 4 - 2; + } + destUv = _i * 4 + 2; + var px = x + halfW * points[_i * 4]; + var py = y + halfH * points[_i * 4 + 1]; + var cosTheta = -points[sourceUv] * points[destUv] - points[sourceUv + 1] * points[destUv + 1]; + var offset = cornerRadius / Math.tan(Math.acos(cosTheta) / 2); + var cp0x = px - offset * points[sourceUv]; + var cp0y = py - offset * points[sourceUv + 1]; + var cp1x = px + offset * points[destUv]; + var cp1y = py + offset * points[destUv + 1]; + if (_i === 0) { + context.moveTo(cp0x, cp0y); + } else { + context.lineTo(cp0x, cp0y); + } + context.arcTo(px, py, cp1x, cp1y, cornerRadius); + } + context.closePath(); +}; + +// Round rectangle drawing +CRp$3.drawRoundRectanglePath = function (context, x, y, width, height) { + var halfWidth = width / 2; + var halfHeight = height / 2; + var cornerRadius = getRoundRectangleRadius(width, height); + if (context.beginPath) { + context.beginPath(); + } + + // Start at top middle + context.moveTo(x, y - halfHeight); + // Arc from middle top to right side + context.arcTo(x + halfWidth, y - halfHeight, x + halfWidth, y, cornerRadius); + // Arc from right side to bottom + context.arcTo(x + halfWidth, y + halfHeight, x, y + halfHeight, cornerRadius); + // Arc from bottom to left side + context.arcTo(x - halfWidth, y + halfHeight, x - halfWidth, y, cornerRadius); + // Arc from left side to topBorder + context.arcTo(x - halfWidth, y - halfHeight, x, y - halfHeight, cornerRadius); + // Join line + context.lineTo(x, y - halfHeight); + context.closePath(); +}; +CRp$3.drawBottomRoundRectanglePath = function (context, x, y, width, height) { + var halfWidth = width / 2; + var halfHeight = height / 2; + var cornerRadius = getRoundRectangleRadius(width, height); + if (context.beginPath) { + context.beginPath(); + } + + // Start at top middle + context.moveTo(x, y - halfHeight); + context.lineTo(x + halfWidth, y - halfHeight); + context.lineTo(x + halfWidth, y); + context.arcTo(x + halfWidth, y + halfHeight, x, y + halfHeight, cornerRadius); + context.arcTo(x - halfWidth, y + halfHeight, x - halfWidth, y, cornerRadius); + context.lineTo(x - halfWidth, y - halfHeight); + context.lineTo(x, y - halfHeight); + context.closePath(); +}; +CRp$3.drawCutRectanglePath = function (context, x, y, width, height) { + var halfWidth = width / 2; + var halfHeight = height / 2; + var cornerLength = getCutRectangleCornerLength(); + if (context.beginPath) { + context.beginPath(); + } + context.moveTo(x - halfWidth + cornerLength, y - halfHeight); + context.lineTo(x + halfWidth - cornerLength, y - halfHeight); + context.lineTo(x + halfWidth, y - halfHeight + cornerLength); + context.lineTo(x + halfWidth, y + halfHeight - cornerLength); + context.lineTo(x + halfWidth - cornerLength, y + halfHeight); + context.lineTo(x - halfWidth + cornerLength, y + halfHeight); + context.lineTo(x - halfWidth, y + halfHeight - cornerLength); + context.lineTo(x - halfWidth, y - halfHeight + cornerLength); + context.closePath(); +}; +CRp$3.drawBarrelPath = function (context, x, y, width, height) { + var halfWidth = width / 2; + var halfHeight = height / 2; + var xBegin = x - halfWidth; + var xEnd = x + halfWidth; + var yBegin = y - halfHeight; + var yEnd = y + halfHeight; + var barrelCurveConstants = getBarrelCurveConstants(width, height); + var wOffset = barrelCurveConstants.widthOffset; + var hOffset = barrelCurveConstants.heightOffset; + var ctrlPtXOffset = barrelCurveConstants.ctrlPtOffsetPct * wOffset; + if (context.beginPath) { + context.beginPath(); + } + context.moveTo(xBegin, yBegin + hOffset); + context.lineTo(xBegin, yEnd - hOffset); + context.quadraticCurveTo(xBegin + ctrlPtXOffset, yEnd, xBegin + wOffset, yEnd); + context.lineTo(xEnd - wOffset, yEnd); + context.quadraticCurveTo(xEnd - ctrlPtXOffset, yEnd, xEnd, yEnd - hOffset); + context.lineTo(xEnd, yBegin + hOffset); + context.quadraticCurveTo(xEnd - ctrlPtXOffset, yBegin, xEnd - wOffset, yBegin); + context.lineTo(xBegin + wOffset, yBegin); + context.quadraticCurveTo(xBegin + ctrlPtXOffset, yBegin, xBegin, yBegin + hOffset); + context.closePath(); +}; +var sin0 = Math.sin(0); +var cos0 = Math.cos(0); +var sin = {}; +var cos = {}; +var ellipseStepSize = Math.PI / 40; +for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize) { + sin[i] = Math.sin(i); + cos[i] = Math.cos(i); +} +CRp$3.drawEllipsePath = function (context, centerX, centerY, width, height) { + if (context.beginPath) { + context.beginPath(); + } + if (context.ellipse) { + context.ellipse(centerX, centerY, width / 2, height / 2, 0, 0, 2 * Math.PI); + } else { + var xPos, yPos; + var rw = width / 2; + var rh = height / 2; + for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize) { + xPos = centerX - rw * sin[i] * sin0 + rw * cos[i] * cos0; + yPos = centerY + rh * cos[i] * sin0 + rh * sin[i] * cos0; + if (i === 0) { + context.moveTo(xPos, yPos); + } else { + context.lineTo(xPos, yPos); + } + } + } + context.closePath(); +}; + +/* global atob, ArrayBuffer, Uint8Array, Blob */ +var CRp$2 = {}; +CRp$2.createBuffer = function (w, h) { + var buffer = document.createElement('canvas'); // eslint-disable-line no-undef + buffer.width = w; + buffer.height = h; + return [buffer, buffer.getContext('2d')]; +}; +CRp$2.bufferCanvasImage = function (options) { + var cy = this.cy; + var eles = cy.mutableElements(); + var bb = eles.boundingBox(); + var ctrRect = this.findContainerClientCoords(); + var width = options.full ? Math.ceil(bb.w) : ctrRect[2]; + var height = options.full ? Math.ceil(bb.h) : ctrRect[3]; + var specdMaxDims = number$1(options.maxWidth) || number$1(options.maxHeight); + var pxRatio = this.getPixelRatio(); + var scale = 1; + if (options.scale !== undefined) { + width *= options.scale; + height *= options.scale; + scale = options.scale; + } else if (specdMaxDims) { + var maxScaleW = Infinity; + var maxScaleH = Infinity; + if (number$1(options.maxWidth)) { + maxScaleW = scale * options.maxWidth / width; + } + if (number$1(options.maxHeight)) { + maxScaleH = scale * options.maxHeight / height; + } + scale = Math.min(maxScaleW, maxScaleH); + width *= scale; + height *= scale; + } + if (!specdMaxDims) { + width *= pxRatio; + height *= pxRatio; + scale *= pxRatio; + } + var buffCanvas = document.createElement('canvas'); // eslint-disable-line no-undef + + buffCanvas.width = width; + buffCanvas.height = height; + buffCanvas.style.width = width + 'px'; + buffCanvas.style.height = height + 'px'; + var buffCxt = buffCanvas.getContext('2d'); + + // Rasterize the layers, but only if container has nonzero size + if (width > 0 && height > 0) { + buffCxt.clearRect(0, 0, width, height); + buffCxt.globalCompositeOperation = 'source-over'; + var zsortedEles = this.getCachedZSortedEles(); + if (options.full) { + // draw the full bounds of the graph + buffCxt.translate(-bb.x1 * scale, -bb.y1 * scale); + buffCxt.scale(scale, scale); + this.drawElements(buffCxt, zsortedEles); + buffCxt.scale(1 / scale, 1 / scale); + buffCxt.translate(bb.x1 * scale, bb.y1 * scale); + } else { + // draw the current view + var pan = cy.pan(); + var translation = { + x: pan.x * scale, + y: pan.y * scale + }; + scale *= cy.zoom(); + buffCxt.translate(translation.x, translation.y); + buffCxt.scale(scale, scale); + this.drawElements(buffCxt, zsortedEles); + buffCxt.scale(1 / scale, 1 / scale); + buffCxt.translate(-translation.x, -translation.y); + } + + // need to fill bg at end like this in order to fill cleared transparent pixels in jpgs + if (options.bg) { + buffCxt.globalCompositeOperation = 'destination-over'; + buffCxt.fillStyle = options.bg; + buffCxt.rect(0, 0, width, height); + buffCxt.fill(); + } + } + return buffCanvas; +}; +function b64ToBlob(b64, mimeType) { + var bytes = atob(b64); + var buff = new ArrayBuffer(bytes.length); + var buffUint8 = new Uint8Array(buff); + for (var i = 0; i < bytes.length; i++) { + buffUint8[i] = bytes.charCodeAt(i); + } + return new Blob([buff], { + type: mimeType + }); +} +function b64UriToB64(b64uri) { + var i = b64uri.indexOf(','); + return b64uri.substr(i + 1); +} +function output(options, canvas, mimeType) { + var getB64Uri = function getB64Uri() { + return canvas.toDataURL(mimeType, options.quality); + }; + switch (options.output) { + case 'blob-promise': + return new Promise$1(function (resolve, reject) { + try { + canvas.toBlob(function (blob) { + if (blob != null) { + resolve(blob); + } else { + reject(new Error('`canvas.toBlob()` sent a null value in its callback')); + } + }, mimeType, options.quality); + } catch (err) { + reject(err); + } + }); + case 'blob': + return b64ToBlob(b64UriToB64(getB64Uri()), mimeType); + case 'base64': + return b64UriToB64(getB64Uri()); + case 'base64uri': + default: + return getB64Uri(); + } +} +CRp$2.png = function (options) { + return output(options, this.bufferCanvasImage(options), 'image/png'); +}; +CRp$2.jpg = function (options) { + return output(options, this.bufferCanvasImage(options), 'image/jpeg'); +}; + +var CRp$1 = {}; +CRp$1.nodeShapeImpl = function (name, context, centerX, centerY, width, height, points) { + switch (name) { + case 'ellipse': + return this.drawEllipsePath(context, centerX, centerY, width, height); + case 'polygon': + return this.drawPolygonPath(context, centerX, centerY, width, height, points); + case 'round-polygon': + return this.drawRoundPolygonPath(context, centerX, centerY, width, height, points); + case 'roundrectangle': + case 'round-rectangle': + return this.drawRoundRectanglePath(context, centerX, centerY, width, height); + case 'cutrectangle': + case 'cut-rectangle': + return this.drawCutRectanglePath(context, centerX, centerY, width, height); + case 'bottomroundrectangle': + case 'bottom-round-rectangle': + return this.drawBottomRoundRectanglePath(context, centerX, centerY, width, height); + case 'barrel': + return this.drawBarrelPath(context, centerX, centerY, width, height); + } +}; + +var CR = CanvasRenderer; +var CRp = CanvasRenderer.prototype; +CRp.CANVAS_LAYERS = 3; +// +CRp.SELECT_BOX = 0; +CRp.DRAG = 1; +CRp.NODE = 2; +CRp.BUFFER_COUNT = 3; +// +CRp.TEXTURE_BUFFER = 0; +CRp.MOTIONBLUR_BUFFER_NODE = 1; +CRp.MOTIONBLUR_BUFFER_DRAG = 2; +function CanvasRenderer(options) { + var r = this; + r.data = { + canvases: new Array(CRp.CANVAS_LAYERS), + contexts: new Array(CRp.CANVAS_LAYERS), + canvasNeedsRedraw: new Array(CRp.CANVAS_LAYERS), + bufferCanvases: new Array(CRp.BUFFER_COUNT), + bufferContexts: new Array(CRp.CANVAS_LAYERS) + }; + var tapHlOffAttr = '-webkit-tap-highlight-color'; + var tapHlOffStyle = 'rgba(0,0,0,0)'; + r.data.canvasContainer = document.createElement('div'); // eslint-disable-line no-undef + var containerStyle = r.data.canvasContainer.style; + r.data.canvasContainer.style[tapHlOffAttr] = tapHlOffStyle; + containerStyle.position = 'relative'; + containerStyle.zIndex = '0'; + containerStyle.overflow = 'hidden'; + var container = options.cy.container(); + container.appendChild(r.data.canvasContainer); + container.style[tapHlOffAttr] = tapHlOffStyle; + var styleMap = { + '-webkit-user-select': 'none', + '-moz-user-select': '-moz-none', + 'user-select': 'none', + '-webkit-tap-highlight-color': 'rgba(0,0,0,0)', + 'outline-style': 'none' + }; + if (ms()) { + styleMap['-ms-touch-action'] = 'none'; + styleMap['touch-action'] = 'none'; + } + for (var i = 0; i < CRp.CANVAS_LAYERS; i++) { + var canvas = r.data.canvases[i] = document.createElement('canvas'); // eslint-disable-line no-undef + r.data.contexts[i] = canvas.getContext('2d'); + Object.keys(styleMap).forEach(function (k) { + canvas.style[k] = styleMap[k]; + }); + canvas.style.position = 'absolute'; + canvas.setAttribute('data-id', 'layer' + i); + canvas.style.zIndex = String(CRp.CANVAS_LAYERS - i); + r.data.canvasContainer.appendChild(canvas); + r.data.canvasNeedsRedraw[i] = false; + } + r.data.topCanvas = r.data.canvases[0]; + r.data.canvases[CRp.NODE].setAttribute('data-id', 'layer' + CRp.NODE + '-node'); + r.data.canvases[CRp.SELECT_BOX].setAttribute('data-id', 'layer' + CRp.SELECT_BOX + '-selectbox'); + r.data.canvases[CRp.DRAG].setAttribute('data-id', 'layer' + CRp.DRAG + '-drag'); + for (var i = 0; i < CRp.BUFFER_COUNT; i++) { + r.data.bufferCanvases[i] = document.createElement('canvas'); // eslint-disable-line no-undef + r.data.bufferContexts[i] = r.data.bufferCanvases[i].getContext('2d'); + r.data.bufferCanvases[i].style.position = 'absolute'; + r.data.bufferCanvases[i].setAttribute('data-id', 'buffer' + i); + r.data.bufferCanvases[i].style.zIndex = String(-i - 1); + r.data.bufferCanvases[i].style.visibility = 'hidden'; + //r.data.canvasContainer.appendChild(r.data.bufferCanvases[i]); + } + + r.pathsEnabled = true; + var emptyBb = makeBoundingBox(); + var getBoxCenter = function getBoxCenter(bb) { + return { + x: (bb.x1 + bb.x2) / 2, + y: (bb.y1 + bb.y2) / 2 + }; + }; + var getCenterOffset = function getCenterOffset(bb) { + return { + x: -bb.w / 2, + y: -bb.h / 2 + }; + }; + var backgroundTimestampHasChanged = function backgroundTimestampHasChanged(ele) { + var _p = ele[0]._private; + var same = _p.oldBackgroundTimestamp === _p.backgroundTimestamp; + return !same; + }; + var getStyleKey = function getStyleKey(ele) { + return ele[0]._private.nodeKey; + }; + var getLabelKey = function getLabelKey(ele) { + return ele[0]._private.labelStyleKey; + }; + var getSourceLabelKey = function getSourceLabelKey(ele) { + return ele[0]._private.sourceLabelStyleKey; + }; + var getTargetLabelKey = function getTargetLabelKey(ele) { + return ele[0]._private.targetLabelStyleKey; + }; + var drawElement = function drawElement(context, ele, bb, scaledLabelShown, useEleOpacity) { + return r.drawElement(context, ele, bb, false, false, useEleOpacity); + }; + var drawLabel = function drawLabel(context, ele, bb, scaledLabelShown, useEleOpacity) { + return r.drawElementText(context, ele, bb, scaledLabelShown, 'main', useEleOpacity); + }; + var drawSourceLabel = function drawSourceLabel(context, ele, bb, scaledLabelShown, useEleOpacity) { + return r.drawElementText(context, ele, bb, scaledLabelShown, 'source', useEleOpacity); + }; + var drawTargetLabel = function drawTargetLabel(context, ele, bb, scaledLabelShown, useEleOpacity) { + return r.drawElementText(context, ele, bb, scaledLabelShown, 'target', useEleOpacity); + }; + var getElementBox = function getElementBox(ele) { + ele.boundingBox(); + return ele[0]._private.bodyBounds; + }; + var getLabelBox = function getLabelBox(ele) { + ele.boundingBox(); + return ele[0]._private.labelBounds.main || emptyBb; + }; + var getSourceLabelBox = function getSourceLabelBox(ele) { + ele.boundingBox(); + return ele[0]._private.labelBounds.source || emptyBb; + }; + var getTargetLabelBox = function getTargetLabelBox(ele) { + ele.boundingBox(); + return ele[0]._private.labelBounds.target || emptyBb; + }; + var isLabelVisibleAtScale = function isLabelVisibleAtScale(ele, scaledLabelShown) { + return scaledLabelShown; + }; + var getElementRotationPoint = function getElementRotationPoint(ele) { + return getBoxCenter(getElementBox(ele)); + }; + var addTextMargin = function addTextMargin(prefix, pt, ele) { + var pre = prefix ? prefix + '-' : ''; + return { + x: pt.x + ele.pstyle(pre + 'text-margin-x').pfValue, + y: pt.y + ele.pstyle(pre + 'text-margin-y').pfValue + }; + }; + var getRsPt = function getRsPt(ele, x, y) { + var rs = ele[0]._private.rscratch; + return { + x: rs[x], + y: rs[y] + }; + }; + var getLabelRotationPoint = function getLabelRotationPoint(ele) { + return addTextMargin('', getRsPt(ele, 'labelX', 'labelY'), ele); + }; + var getSourceLabelRotationPoint = function getSourceLabelRotationPoint(ele) { + return addTextMargin('source', getRsPt(ele, 'sourceLabelX', 'sourceLabelY'), ele); + }; + var getTargetLabelRotationPoint = function getTargetLabelRotationPoint(ele) { + return addTextMargin('target', getRsPt(ele, 'targetLabelX', 'targetLabelY'), ele); + }; + var getElementRotationOffset = function getElementRotationOffset(ele) { + return getCenterOffset(getElementBox(ele)); + }; + var getSourceLabelRotationOffset = function getSourceLabelRotationOffset(ele) { + return getCenterOffset(getSourceLabelBox(ele)); + }; + var getTargetLabelRotationOffset = function getTargetLabelRotationOffset(ele) { + return getCenterOffset(getTargetLabelBox(ele)); + }; + var getLabelRotationOffset = function getLabelRotationOffset(ele) { + var bb = getLabelBox(ele); + var p = getCenterOffset(getLabelBox(ele)); + if (ele.isNode()) { + switch (ele.pstyle('text-halign').value) { + case 'left': + p.x = -bb.w; + break; + case 'right': + p.x = 0; + break; + } + switch (ele.pstyle('text-valign').value) { + case 'top': + p.y = -bb.h; + break; + case 'bottom': + p.y = 0; + break; + } + } + return p; + }; + var eleTxrCache = r.data.eleTxrCache = new ElementTextureCache(r, { + getKey: getStyleKey, + doesEleInvalidateKey: backgroundTimestampHasChanged, + drawElement: drawElement, + getBoundingBox: getElementBox, + getRotationPoint: getElementRotationPoint, + getRotationOffset: getElementRotationOffset, + allowEdgeTxrCaching: false, + allowParentTxrCaching: false + }); + var lblTxrCache = r.data.lblTxrCache = new ElementTextureCache(r, { + getKey: getLabelKey, + drawElement: drawLabel, + getBoundingBox: getLabelBox, + getRotationPoint: getLabelRotationPoint, + getRotationOffset: getLabelRotationOffset, + isVisible: isLabelVisibleAtScale + }); + var slbTxrCache = r.data.slbTxrCache = new ElementTextureCache(r, { + getKey: getSourceLabelKey, + drawElement: drawSourceLabel, + getBoundingBox: getSourceLabelBox, + getRotationPoint: getSourceLabelRotationPoint, + getRotationOffset: getSourceLabelRotationOffset, + isVisible: isLabelVisibleAtScale + }); + var tlbTxrCache = r.data.tlbTxrCache = new ElementTextureCache(r, { + getKey: getTargetLabelKey, + drawElement: drawTargetLabel, + getBoundingBox: getTargetLabelBox, + getRotationPoint: getTargetLabelRotationPoint, + getRotationOffset: getTargetLabelRotationOffset, + isVisible: isLabelVisibleAtScale + }); + var lyrTxrCache = r.data.lyrTxrCache = new LayeredTextureCache(r); + r.onUpdateEleCalcs(function invalidateTextureCaches(willDraw, eles) { + // each cache should check for sub-key diff to see that the update affects that cache particularly + eleTxrCache.invalidateElements(eles); + lblTxrCache.invalidateElements(eles); + slbTxrCache.invalidateElements(eles); + tlbTxrCache.invalidateElements(eles); + + // any change invalidates the layers + lyrTxrCache.invalidateElements(eles); + + // update the old bg timestamp so diffs can be done in the ele txr caches + for (var _i = 0; _i < eles.length; _i++) { + var _p = eles[_i]._private; + _p.oldBackgroundTimestamp = _p.backgroundTimestamp; + } + }); + var refineInLayers = function refineInLayers(reqs) { + for (var i = 0; i < reqs.length; i++) { + lyrTxrCache.enqueueElementRefinement(reqs[i].ele); + } + }; + eleTxrCache.onDequeue(refineInLayers); + lblTxrCache.onDequeue(refineInLayers); + slbTxrCache.onDequeue(refineInLayers); + tlbTxrCache.onDequeue(refineInLayers); +} +CRp.redrawHint = function (group, bool) { + var r = this; + switch (group) { + case 'eles': + r.data.canvasNeedsRedraw[CRp.NODE] = bool; + break; + case 'drag': + r.data.canvasNeedsRedraw[CRp.DRAG] = bool; + break; + case 'select': + r.data.canvasNeedsRedraw[CRp.SELECT_BOX] = bool; + break; + } +}; + +// whether to use Path2D caching for drawing +var pathsImpld = typeof Path2D !== 'undefined'; +CRp.path2dEnabled = function (on) { + if (on === undefined) { + return this.pathsEnabled; + } + this.pathsEnabled = on ? true : false; +}; +CRp.usePaths = function () { + return pathsImpld && this.pathsEnabled; +}; +CRp.setImgSmoothing = function (context, bool) { + if (context.imageSmoothingEnabled != null) { + context.imageSmoothingEnabled = bool; + } else { + context.webkitImageSmoothingEnabled = bool; + context.mozImageSmoothingEnabled = bool; + context.msImageSmoothingEnabled = bool; + } +}; +CRp.getImgSmoothing = function (context) { + if (context.imageSmoothingEnabled != null) { + return context.imageSmoothingEnabled; + } else { + return context.webkitImageSmoothingEnabled || context.mozImageSmoothingEnabled || context.msImageSmoothingEnabled; + } +}; +CRp.makeOffscreenCanvas = function (width, height) { + var canvas; + if ((typeof OffscreenCanvas === "undefined" ? "undefined" : _typeof(OffscreenCanvas)) !== ("undefined" )) { + canvas = new OffscreenCanvas(width, height); + } else { + canvas = document.createElement('canvas'); // eslint-disable-line no-undef + canvas.width = width; + canvas.height = height; + } + return canvas; +}; +[CRp$a, CRp$9, CRp$8, CRp$7, CRp$6, CRp$5, CRp$4, CRp$3, CRp$2, CRp$1].forEach(function (props) { + extend(CRp, props); +}); + +var renderer = [{ + name: 'null', + impl: NullRenderer +}, { + name: 'base', + impl: BR +}, { + name: 'canvas', + impl: CR +}]; + +var incExts = [{ + type: 'layout', + extensions: layout +}, { + type: 'renderer', + extensions: renderer +}]; + +// registered extensions to cytoscape, indexed by name +var extensions = {}; + +// registered modules for extensions, indexed by name +var modules = {}; +function setExtension(type, name, registrant) { + var ext = registrant; + var overrideErr = function overrideErr(field) { + warn('Can not register `' + name + '` for `' + type + '` since `' + field + '` already exists in the prototype and can not be overridden'); + }; + if (type === 'core') { + if (Core.prototype[name]) { + return overrideErr(name); + } else { + Core.prototype[name] = registrant; + } + } else if (type === 'collection') { + if (Collection.prototype[name]) { + return overrideErr(name); + } else { + Collection.prototype[name] = registrant; + } + } else if (type === 'layout') { + // fill in missing layout functions in the prototype + + var Layout = function Layout(options) { + this.options = options; + registrant.call(this, options); + + // make sure layout has _private for use w/ std apis like .on() + if (!plainObject(this._private)) { + this._private = {}; + } + this._private.cy = options.cy; + this._private.listeners = []; + this.createEmitter(); + }; + var layoutProto = Layout.prototype = Object.create(registrant.prototype); + var optLayoutFns = []; + for (var i = 0; i < optLayoutFns.length; i++) { + var fnName = optLayoutFns[i]; + layoutProto[fnName] = layoutProto[fnName] || function () { + return this; + }; + } + + // either .start() or .run() is defined, so autogen the other + if (layoutProto.start && !layoutProto.run) { + layoutProto.run = function () { + this.start(); + return this; + }; + } else if (!layoutProto.start && layoutProto.run) { + layoutProto.start = function () { + this.run(); + return this; + }; + } + var regStop = registrant.prototype.stop; + layoutProto.stop = function () { + var opts = this.options; + if (opts && opts.animate) { + var anis = this.animations; + if (anis) { + for (var _i = 0; _i < anis.length; _i++) { + anis[_i].stop(); + } + } + } + if (regStop) { + regStop.call(this); + } else { + this.emit('layoutstop'); + } + return this; + }; + if (!layoutProto.destroy) { + layoutProto.destroy = function () { + return this; + }; + } + layoutProto.cy = function () { + return this._private.cy; + }; + var getCy = function getCy(layout) { + return layout._private.cy; + }; + var emitterOpts = { + addEventFields: function addEventFields(layout, evt) { + evt.layout = layout; + evt.cy = getCy(layout); + evt.target = layout; + }, + bubble: function bubble() { + return true; + }, + parent: function parent(layout) { + return getCy(layout); + } + }; + extend(layoutProto, { + createEmitter: function createEmitter() { + this._private.emitter = new Emitter(emitterOpts, this); + return this; + }, + emitter: function emitter() { + return this._private.emitter; + }, + on: function on(evt, cb) { + this.emitter().on(evt, cb); + return this; + }, + one: function one(evt, cb) { + this.emitter().one(evt, cb); + return this; + }, + once: function once(evt, cb) { + this.emitter().one(evt, cb); + return this; + }, + removeListener: function removeListener(evt, cb) { + this.emitter().removeListener(evt, cb); + return this; + }, + removeAllListeners: function removeAllListeners() { + this.emitter().removeAllListeners(); + return this; + }, + emit: function emit(evt, params) { + this.emitter().emit(evt, params); + return this; + } + }); + define.eventAliasesOn(layoutProto); + ext = Layout; // replace with our wrapped layout + } else if (type === 'renderer' && name !== 'null' && name !== 'base') { + // user registered renderers inherit from base + + var BaseRenderer = getExtension('renderer', 'base'); + var bProto = BaseRenderer.prototype; + var RegistrantRenderer = registrant; + var rProto = registrant.prototype; + var Renderer = function Renderer() { + BaseRenderer.apply(this, arguments); + RegistrantRenderer.apply(this, arguments); + }; + var proto = Renderer.prototype; + for (var pName in bProto) { + var pVal = bProto[pName]; + var existsInR = rProto[pName] != null; + if (existsInR) { + return overrideErr(pName); + } + proto[pName] = pVal; // take impl from base + } + + for (var _pName in rProto) { + proto[_pName] = rProto[_pName]; // take impl from registrant + } + + bProto.clientFunctions.forEach(function (name) { + proto[name] = proto[name] || function () { + error('Renderer does not implement `renderer.' + name + '()` on its prototype'); + }; + }); + ext = Renderer; + } else if (type === '__proto__' || type === 'constructor' || type === 'prototype') { + // to avoid potential prototype pollution + return error(type + ' is an illegal type to be registered, possibly lead to prototype pollutions'); + } + return setMap({ + map: extensions, + keys: [type, name], + value: ext + }); +} +function getExtension(type, name) { + return getMap({ + map: extensions, + keys: [type, name] + }); +} +function setModule(type, name, moduleType, moduleName, registrant) { + return setMap({ + map: modules, + keys: [type, name, moduleType, moduleName], + value: registrant + }); +} +function getModule(type, name, moduleType, moduleName) { + return getMap({ + map: modules, + keys: [type, name, moduleType, moduleName] + }); +} +var extension = function extension() { + // e.g. extension('renderer', 'svg') + if (arguments.length === 2) { + return getExtension.apply(null, arguments); + } + + // e.g. extension('renderer', 'svg', { ... }) + else if (arguments.length === 3) { + return setExtension.apply(null, arguments); + } + + // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse') + else if (arguments.length === 4) { + return getModule.apply(null, arguments); + } + + // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse', { ... }) + else if (arguments.length === 5) { + return setModule.apply(null, arguments); + } else { + error('Invalid extension access syntax'); + } +}; + +// allows a core instance to access extensions internally +Core.prototype.extension = extension; + +// included extensions +incExts.forEach(function (group) { + group.extensions.forEach(function (ext) { + setExtension(group.type, ext.name, ext.impl); + }); +}); + +// a dummy stylesheet object that doesn't need a reference to the core +// (useful for init) +var Stylesheet = function Stylesheet() { + if (!(this instanceof Stylesheet)) { + return new Stylesheet(); + } + this.length = 0; +}; +var sheetfn = Stylesheet.prototype; +sheetfn.instanceString = function () { + return 'stylesheet'; +}; + +// just store the selector to be parsed later +sheetfn.selector = function (selector) { + var i = this.length++; + this[i] = { + selector: selector, + properties: [] + }; + return this; // chaining +}; + +// just store the property to be parsed later +sheetfn.css = function (name, value) { + var i = this.length - 1; + if (string(name)) { + this[i].properties.push({ + name: name, + value: value + }); + } else if (plainObject(name)) { + var map = name; + var propNames = Object.keys(map); + for (var j = 0; j < propNames.length; j++) { + var key = propNames[j]; + var mapVal = map[key]; + if (mapVal == null) { + continue; + } + var prop = Style.properties[key] || Style.properties[dash2camel(key)]; + if (prop == null) { + continue; + } + var _name = prop.name; + var _value = mapVal; + this[i].properties.push({ + name: _name, + value: _value + }); + } + } + return this; // chaining +}; + +sheetfn.style = sheetfn.css; + +// generate a real style object from the dummy stylesheet +sheetfn.generateStyle = function (cy) { + var style = new Style(cy); + return this.appendToStyle(style); +}; + +// append a dummy stylesheet object on a real style object +sheetfn.appendToStyle = function (style) { + for (var i = 0; i < this.length; i++) { + var context = this[i]; + var selector = context.selector; + var props = context.properties; + style.selector(selector); // apply selector + + for (var j = 0; j < props.length; j++) { + var prop = props[j]; + style.css(prop.name, prop.value); // apply property + } + } + + return style; +}; + +var version = "3.28.1"; + +var cytoscape = function cytoscape(options) { + // if no options specified, use default + if (options === undefined) { + options = {}; + } + + // create instance + if (plainObject(options)) { + return new Core(options); + } + + // allow for registration of extensions + else if (string(options)) { + return extension.apply(extension, arguments); + } +}; + +// e.g. cytoscape.use( require('cytoscape-foo'), bar ) +cytoscape.use = function (ext) { + var args = Array.prototype.slice.call(arguments, 1); // args to pass to ext + + args.unshift(cytoscape); // cytoscape is first arg to ext + + ext.apply(null, args); + return this; +}; +cytoscape.warnings = function (bool) { + return warnings(bool); +}; + +// replaced by build system +cytoscape.version = version; + +// expose public apis (mostly for extensions) +cytoscape.stylesheet = cytoscape.Stylesheet = Stylesheet; + +module.exports = cytoscape; + + +/***/ }), + +/***/ 65731: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +module.exports = __webpack_require__(34297); + + +/***/ }), + +/***/ 34297: +/***/ (function(module, exports) { + +var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Generated by CoffeeScript 1.8.0 +(function() { + var Heap, defaultCmp, floor, heapify, heappop, heappush, heappushpop, heapreplace, insort, min, nlargest, nsmallest, updateItem, _siftdown, _siftup; + + floor = Math.floor, min = Math.min; + + + /* + Default comparison function to be used + */ + + defaultCmp = function(x, y) { + if (x < y) { + return -1; + } + if (x > y) { + return 1; + } + return 0; + }; + + + /* + Insert item x in list a, and keep it sorted assuming a is sorted. + + If x is already in a, insert it to the right of the rightmost x. + + Optional args lo (default 0) and hi (default a.length) bound the slice + of a to be searched. + */ + + insort = function(a, x, lo, hi, cmp) { + var mid; + if (lo == null) { + lo = 0; + } + if (cmp == null) { + cmp = defaultCmp; + } + if (lo < 0) { + throw new Error('lo must be non-negative'); + } + if (hi == null) { + hi = a.length; + } + while (lo < hi) { + mid = floor((lo + hi) / 2); + if (cmp(x, a[mid]) < 0) { + hi = mid; + } else { + lo = mid + 1; + } + } + return ([].splice.apply(a, [lo, lo - lo].concat(x)), x); + }; + + + /* + Push item onto heap, maintaining the heap invariant. + */ + + heappush = function(array, item, cmp) { + if (cmp == null) { + cmp = defaultCmp; + } + array.push(item); + return _siftdown(array, 0, array.length - 1, cmp); + }; + + + /* + Pop the smallest item off the heap, maintaining the heap invariant. + */ + + heappop = function(array, cmp) { + var lastelt, returnitem; + if (cmp == null) { + cmp = defaultCmp; + } + lastelt = array.pop(); + if (array.length) { + returnitem = array[0]; + array[0] = lastelt; + _siftup(array, 0, cmp); + } else { + returnitem = lastelt; + } + return returnitem; + }; + + + /* + Pop and return the current smallest value, and add the new item. + + This is more efficient than heappop() followed by heappush(), and can be + more appropriate when using a fixed size heap. Note that the value + returned may be larger than item! That constrains reasonable use of + this routine unless written as part of a conditional replacement: + if item > array[0] + item = heapreplace(array, item) + */ + + heapreplace = function(array, item, cmp) { + var returnitem; + if (cmp == null) { + cmp = defaultCmp; + } + returnitem = array[0]; + array[0] = item; + _siftup(array, 0, cmp); + return returnitem; + }; + + + /* + Fast version of a heappush followed by a heappop. + */ + + heappushpop = function(array, item, cmp) { + var _ref; + if (cmp == null) { + cmp = defaultCmp; + } + if (array.length && cmp(array[0], item) < 0) { + _ref = [array[0], item], item = _ref[0], array[0] = _ref[1]; + _siftup(array, 0, cmp); + } + return item; + }; + + + /* + Transform list into a heap, in-place, in O(array.length) time. + */ + + heapify = function(array, cmp) { + var i, _i, _j, _len, _ref, _ref1, _results, _results1; + if (cmp == null) { + cmp = defaultCmp; + } + _ref1 = (function() { + _results1 = []; + for (var _j = 0, _ref = floor(array.length / 2); 0 <= _ref ? _j < _ref : _j > _ref; 0 <= _ref ? _j++ : _j--){ _results1.push(_j); } + return _results1; + }).apply(this).reverse(); + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + i = _ref1[_i]; + _results.push(_siftup(array, i, cmp)); + } + return _results; + }; + + + /* + Update the position of the given item in the heap. + This function should be called every time the item is being modified. + */ + + updateItem = function(array, item, cmp) { + var pos; + if (cmp == null) { + cmp = defaultCmp; + } + pos = array.indexOf(item); + if (pos === -1) { + return; + } + _siftdown(array, 0, pos, cmp); + return _siftup(array, pos, cmp); + }; + + + /* + Find the n largest elements in a dataset. + */ + + nlargest = function(array, n, cmp) { + var elem, result, _i, _len, _ref; + if (cmp == null) { + cmp = defaultCmp; + } + result = array.slice(0, n); + if (!result.length) { + return result; + } + heapify(result, cmp); + _ref = array.slice(n); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + elem = _ref[_i]; + heappushpop(result, elem, cmp); + } + return result.sort(cmp).reverse(); + }; + + + /* + Find the n smallest elements in a dataset. + */ + + nsmallest = function(array, n, cmp) { + var elem, i, los, result, _i, _j, _len, _ref, _ref1, _results; + if (cmp == null) { + cmp = defaultCmp; + } + if (n * 10 <= array.length) { + result = array.slice(0, n).sort(cmp); + if (!result.length) { + return result; + } + los = result[result.length - 1]; + _ref = array.slice(n); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + elem = _ref[_i]; + if (cmp(elem, los) < 0) { + insort(result, elem, 0, null, cmp); + result.pop(); + los = result[result.length - 1]; + } + } + return result; + } + heapify(array, cmp); + _results = []; + for (i = _j = 0, _ref1 = min(n, array.length); 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) { + _results.push(heappop(array, cmp)); + } + return _results; + }; + + _siftdown = function(array, startpos, pos, cmp) { + var newitem, parent, parentpos; + if (cmp == null) { + cmp = defaultCmp; + } + newitem = array[pos]; + while (pos > startpos) { + parentpos = (pos - 1) >> 1; + parent = array[parentpos]; + if (cmp(newitem, parent) < 0) { + array[pos] = parent; + pos = parentpos; + continue; + } + break; + } + return array[pos] = newitem; + }; + + _siftup = function(array, pos, cmp) { + var childpos, endpos, newitem, rightpos, startpos; + if (cmp == null) { + cmp = defaultCmp; + } + endpos = array.length; + startpos = pos; + newitem = array[pos]; + childpos = 2 * pos + 1; + while (childpos < endpos) { + rightpos = childpos + 1; + if (rightpos < endpos && !(cmp(array[childpos], array[rightpos]) < 0)) { + childpos = rightpos; + } + array[pos] = array[childpos]; + pos = childpos; + childpos = 2 * pos + 1; + } + array[pos] = newitem; + return _siftdown(array, startpos, pos, cmp); + }; + + Heap = (function() { + Heap.push = heappush; + + Heap.pop = heappop; + + Heap.replace = heapreplace; + + Heap.pushpop = heappushpop; + + Heap.heapify = heapify; + + Heap.updateItem = updateItem; + + Heap.nlargest = nlargest; + + Heap.nsmallest = nsmallest; + + function Heap(cmp) { + this.cmp = cmp != null ? cmp : defaultCmp; + this.nodes = []; + } + + Heap.prototype.push = function(x) { + return heappush(this.nodes, x, this.cmp); + }; + + Heap.prototype.pop = function() { + return heappop(this.nodes, this.cmp); + }; + + Heap.prototype.peek = function() { + return this.nodes[0]; + }; + + Heap.prototype.contains = function(x) { + return this.nodes.indexOf(x) !== -1; + }; + + Heap.prototype.replace = function(x) { + return heapreplace(this.nodes, x, this.cmp); + }; + + Heap.prototype.pushpop = function(x) { + return heappushpop(this.nodes, x, this.cmp); + }; + + Heap.prototype.heapify = function() { + return heapify(this.nodes, this.cmp); + }; + + Heap.prototype.updateItem = function(x) { + return updateItem(this.nodes, x, this.cmp); + }; + + Heap.prototype.clear = function() { + return this.nodes = []; + }; + + Heap.prototype.empty = function() { + return this.nodes.length === 0; + }; + + Heap.prototype.size = function() { + return this.nodes.length; + }; + + Heap.prototype.clone = function() { + var heap; + heap = new Heap(); + heap.nodes = this.nodes.slice(0); + return heap; + }; + + Heap.prototype.toArray = function() { + return this.nodes.slice(0); + }; + + Heap.prototype.insert = Heap.prototype.push; + + Heap.prototype.top = Heap.prototype.peek; + + Heap.prototype.front = Heap.prototype.peek; + + Heap.prototype.has = Heap.prototype.contains; + + Heap.prototype.copy = Heap.prototype.clone; + + return Heap; + + })(); + + (function(root, factory) { + if (true) { + return !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), + __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? + (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + } else {} + })(this, function() { + return Heap; + }); + +}).call(this); + + +/***/ }), + +/***/ 23143: +/***/ (function(module) { + +(function webpackUniversalModuleDefinition(root, factory) { + if(true) + module.exports = factory(); + else {} +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __nested_webpack_require_543__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_543__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __nested_webpack_require_543__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __nested_webpack_require_543__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __nested_webpack_require_543__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __nested_webpack_require_543__.d = function(exports, name, getter) { +/******/ if(!__nested_webpack_require_543__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __nested_webpack_require_543__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __nested_webpack_require_543__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __nested_webpack_require_543__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __nested_webpack_require_543__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __nested_webpack_require_543__(__nested_webpack_require_543__.s = 26); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function LayoutConstants() {} + +/** + * Layout Quality: 0:draft, 1:default, 2:proof + */ +LayoutConstants.QUALITY = 1; + +/** + * Default parameters + */ +LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED = false; +LayoutConstants.DEFAULT_INCREMENTAL = false; +LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT = true; +LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT = false; +LayoutConstants.DEFAULT_ANIMATION_PERIOD = 50; +LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES = false; + +// ----------------------------------------------------------------------------- +// Section: General other constants +// ----------------------------------------------------------------------------- +/* + * Margins of a graph to be applied on bouding rectangle of its contents. We + * assume margins on all four sides to be uniform. + */ +LayoutConstants.DEFAULT_GRAPH_MARGIN = 15; + +/* + * Whether to consider labels in node dimensions or not + */ +LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = false; + +/* + * Default dimension of a non-compound node. + */ +LayoutConstants.SIMPLE_NODE_SIZE = 40; + +/* + * Default dimension of a non-compound node. + */ +LayoutConstants.SIMPLE_NODE_HALF_SIZE = LayoutConstants.SIMPLE_NODE_SIZE / 2; + +/* + * Empty compound node size. When a compound node is empty, its both + * dimensions should be of this value. + */ +LayoutConstants.EMPTY_COMPOUND_NODE_SIZE = 40; + +/* + * Minimum length that an edge should take during layout + */ +LayoutConstants.MIN_EDGE_LENGTH = 1; + +/* + * World boundaries that layout operates on + */ +LayoutConstants.WORLD_BOUNDARY = 1000000; + +/* + * World boundaries that random positioning can be performed with + */ +LayoutConstants.INITIAL_WORLD_BOUNDARY = LayoutConstants.WORLD_BOUNDARY / 1000; + +/* + * Coordinates of the world center + */ +LayoutConstants.WORLD_CENTER_X = 1200; +LayoutConstants.WORLD_CENTER_Y = 900; + +module.exports = LayoutConstants; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __nested_webpack_require_4947__) { + +"use strict"; + + +var LGraphObject = __nested_webpack_require_4947__(2); +var IGeometry = __nested_webpack_require_4947__(8); +var IMath = __nested_webpack_require_4947__(9); + +function LEdge(source, target, vEdge) { + LGraphObject.call(this, vEdge); + + this.isOverlapingSourceAndTarget = false; + this.vGraphObject = vEdge; + this.bendpoints = []; + this.source = source; + this.target = target; +} + +LEdge.prototype = Object.create(LGraphObject.prototype); + +for (var prop in LGraphObject) { + LEdge[prop] = LGraphObject[prop]; +} + +LEdge.prototype.getSource = function () { + return this.source; +}; + +LEdge.prototype.getTarget = function () { + return this.target; +}; + +LEdge.prototype.isInterGraph = function () { + return this.isInterGraph; +}; + +LEdge.prototype.getLength = function () { + return this.length; +}; + +LEdge.prototype.isOverlapingSourceAndTarget = function () { + return this.isOverlapingSourceAndTarget; +}; + +LEdge.prototype.getBendpoints = function () { + return this.bendpoints; +}; + +LEdge.prototype.getLca = function () { + return this.lca; +}; + +LEdge.prototype.getSourceInLca = function () { + return this.sourceInLca; +}; + +LEdge.prototype.getTargetInLca = function () { + return this.targetInLca; +}; + +LEdge.prototype.getOtherEnd = function (node) { + if (this.source === node) { + return this.target; + } else if (this.target === node) { + return this.source; + } else { + throw "Node is not incident with this edge"; + } +}; + +LEdge.prototype.getOtherEndInGraph = function (node, graph) { + var otherEnd = this.getOtherEnd(node); + var root = graph.getGraphManager().getRoot(); + + while (true) { + if (otherEnd.getOwner() == graph) { + return otherEnd; + } + + if (otherEnd.getOwner() == root) { + break; + } + + otherEnd = otherEnd.getOwner().getParent(); + } + + return null; +}; + +LEdge.prototype.updateLength = function () { + var clipPointCoordinates = new Array(4); + + this.isOverlapingSourceAndTarget = IGeometry.getIntersection(this.target.getRect(), this.source.getRect(), clipPointCoordinates); + + if (!this.isOverlapingSourceAndTarget) { + this.lengthX = clipPointCoordinates[0] - clipPointCoordinates[2]; + this.lengthY = clipPointCoordinates[1] - clipPointCoordinates[3]; + + if (Math.abs(this.lengthX) < 1.0) { + this.lengthX = IMath.sign(this.lengthX); + } + + if (Math.abs(this.lengthY) < 1.0) { + this.lengthY = IMath.sign(this.lengthY); + } + + this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY); + } +}; + +LEdge.prototype.updateLengthSimple = function () { + this.lengthX = this.target.getCenterX() - this.source.getCenterX(); + this.lengthY = this.target.getCenterY() - this.source.getCenterY(); + + if (Math.abs(this.lengthX) < 1.0) { + this.lengthX = IMath.sign(this.lengthX); + } + + if (Math.abs(this.lengthY) < 1.0) { + this.lengthY = IMath.sign(this.lengthY); + } + + this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY); +}; + +module.exports = LEdge; + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function LGraphObject(vGraphObject) { + this.vGraphObject = vGraphObject; +} + +module.exports = LGraphObject; + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __nested_webpack_require_8167__) { + +"use strict"; + + +var LGraphObject = __nested_webpack_require_8167__(2); +var Integer = __nested_webpack_require_8167__(10); +var RectangleD = __nested_webpack_require_8167__(13); +var LayoutConstants = __nested_webpack_require_8167__(0); +var RandomSeed = __nested_webpack_require_8167__(16); +var PointD = __nested_webpack_require_8167__(4); + +function LNode(gm, loc, size, vNode) { + //Alternative constructor 1 : LNode(LGraphManager gm, Point loc, Dimension size, Object vNode) + if (size == null && vNode == null) { + vNode = loc; + } + + LGraphObject.call(this, vNode); + + //Alternative constructor 2 : LNode(Layout layout, Object vNode) + if (gm.graphManager != null) gm = gm.graphManager; + + this.estimatedSize = Integer.MIN_VALUE; + this.inclusionTreeDepth = Integer.MAX_VALUE; + this.vGraphObject = vNode; + this.edges = []; + this.graphManager = gm; + + if (size != null && loc != null) this.rect = new RectangleD(loc.x, loc.y, size.width, size.height);else this.rect = new RectangleD(); +} + +LNode.prototype = Object.create(LGraphObject.prototype); +for (var prop in LGraphObject) { + LNode[prop] = LGraphObject[prop]; +} + +LNode.prototype.getEdges = function () { + return this.edges; +}; + +LNode.prototype.getChild = function () { + return this.child; +}; + +LNode.prototype.getOwner = function () { + // if (this.owner != null) { + // if (!(this.owner == null || this.owner.getNodes().indexOf(this) > -1)) { + // throw "assert failed"; + // } + // } + + return this.owner; +}; + +LNode.prototype.getWidth = function () { + return this.rect.width; +}; + +LNode.prototype.setWidth = function (width) { + this.rect.width = width; +}; + +LNode.prototype.getHeight = function () { + return this.rect.height; +}; + +LNode.prototype.setHeight = function (height) { + this.rect.height = height; +}; + +LNode.prototype.getCenterX = function () { + return this.rect.x + this.rect.width / 2; +}; + +LNode.prototype.getCenterY = function () { + return this.rect.y + this.rect.height / 2; +}; + +LNode.prototype.getCenter = function () { + return new PointD(this.rect.x + this.rect.width / 2, this.rect.y + this.rect.height / 2); +}; + +LNode.prototype.getLocation = function () { + return new PointD(this.rect.x, this.rect.y); +}; + +LNode.prototype.getRect = function () { + return this.rect; +}; + +LNode.prototype.getDiagonal = function () { + return Math.sqrt(this.rect.width * this.rect.width + this.rect.height * this.rect.height); +}; + +/** + * This method returns half the diagonal length of this node. + */ +LNode.prototype.getHalfTheDiagonal = function () { + return Math.sqrt(this.rect.height * this.rect.height + this.rect.width * this.rect.width) / 2; +}; + +LNode.prototype.setRect = function (upperLeft, dimension) { + this.rect.x = upperLeft.x; + this.rect.y = upperLeft.y; + this.rect.width = dimension.width; + this.rect.height = dimension.height; +}; + +LNode.prototype.setCenter = function (cx, cy) { + this.rect.x = cx - this.rect.width / 2; + this.rect.y = cy - this.rect.height / 2; +}; + +LNode.prototype.setLocation = function (x, y) { + this.rect.x = x; + this.rect.y = y; +}; + +LNode.prototype.moveBy = function (dx, dy) { + this.rect.x += dx; + this.rect.y += dy; +}; + +LNode.prototype.getEdgeListToNode = function (to) { + var edgeList = []; + var edge; + var self = this; + + self.edges.forEach(function (edge) { + + if (edge.target == to) { + if (edge.source != self) throw "Incorrect edge source!"; + + edgeList.push(edge); + } + }); + + return edgeList; +}; + +LNode.prototype.getEdgesBetween = function (other) { + var edgeList = []; + var edge; + + var self = this; + self.edges.forEach(function (edge) { + + if (!(edge.source == self || edge.target == self)) throw "Incorrect edge source and/or target"; + + if (edge.target == other || edge.source == other) { + edgeList.push(edge); + } + }); + + return edgeList; +}; + +LNode.prototype.getNeighborsList = function () { + var neighbors = new Set(); + + var self = this; + self.edges.forEach(function (edge) { + + if (edge.source == self) { + neighbors.add(edge.target); + } else { + if (edge.target != self) { + throw "Incorrect incidency!"; + } + + neighbors.add(edge.source); + } + }); + + return neighbors; +}; + +LNode.prototype.withChildren = function () { + var withNeighborsList = new Set(); + var childNode; + var children; + + withNeighborsList.add(this); + + if (this.child != null) { + var nodes = this.child.getNodes(); + for (var i = 0; i < nodes.length; i++) { + childNode = nodes[i]; + children = childNode.withChildren(); + children.forEach(function (node) { + withNeighborsList.add(node); + }); + } + } + + return withNeighborsList; +}; + +LNode.prototype.getNoOfChildren = function () { + var noOfChildren = 0; + var childNode; + + if (this.child == null) { + noOfChildren = 1; + } else { + var nodes = this.child.getNodes(); + for (var i = 0; i < nodes.length; i++) { + childNode = nodes[i]; + + noOfChildren += childNode.getNoOfChildren(); + } + } + + if (noOfChildren == 0) { + noOfChildren = 1; + } + return noOfChildren; +}; + +LNode.prototype.getEstimatedSize = function () { + if (this.estimatedSize == Integer.MIN_VALUE) { + throw "assert failed"; + } + return this.estimatedSize; +}; + +LNode.prototype.calcEstimatedSize = function () { + if (this.child == null) { + return this.estimatedSize = (this.rect.width + this.rect.height) / 2; + } else { + this.estimatedSize = this.child.calcEstimatedSize(); + this.rect.width = this.estimatedSize; + this.rect.height = this.estimatedSize; + + return this.estimatedSize; + } +}; + +LNode.prototype.scatter = function () { + var randomCenterX; + var randomCenterY; + + var minX = -LayoutConstants.INITIAL_WORLD_BOUNDARY; + var maxX = LayoutConstants.INITIAL_WORLD_BOUNDARY; + randomCenterX = LayoutConstants.WORLD_CENTER_X + RandomSeed.nextDouble() * (maxX - minX) + minX; + + var minY = -LayoutConstants.INITIAL_WORLD_BOUNDARY; + var maxY = LayoutConstants.INITIAL_WORLD_BOUNDARY; + randomCenterY = LayoutConstants.WORLD_CENTER_Y + RandomSeed.nextDouble() * (maxY - minY) + minY; + + this.rect.x = randomCenterX; + this.rect.y = randomCenterY; +}; + +LNode.prototype.updateBounds = function () { + if (this.getChild() == null) { + throw "assert failed"; + } + if (this.getChild().getNodes().length != 0) { + // wrap the children nodes by re-arranging the boundaries + var childGraph = this.getChild(); + childGraph.updateBounds(true); + + this.rect.x = childGraph.getLeft(); + this.rect.y = childGraph.getTop(); + + this.setWidth(childGraph.getRight() - childGraph.getLeft()); + this.setHeight(childGraph.getBottom() - childGraph.getTop()); + + // Update compound bounds considering its label properties + if (LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS) { + + var width = childGraph.getRight() - childGraph.getLeft(); + var height = childGraph.getBottom() - childGraph.getTop(); + + if (this.labelWidth > width) { + this.rect.x -= (this.labelWidth - width) / 2; + this.setWidth(this.labelWidth); + } + + if (this.labelHeight > height) { + if (this.labelPos == "center") { + this.rect.y -= (this.labelHeight - height) / 2; + } else if (this.labelPos == "top") { + this.rect.y -= this.labelHeight - height; + } + this.setHeight(this.labelHeight); + } + } + } +}; + +LNode.prototype.getInclusionTreeDepth = function () { + if (this.inclusionTreeDepth == Integer.MAX_VALUE) { + throw "assert failed"; + } + return this.inclusionTreeDepth; +}; + +LNode.prototype.transform = function (trans) { + var left = this.rect.x; + + if (left > LayoutConstants.WORLD_BOUNDARY) { + left = LayoutConstants.WORLD_BOUNDARY; + } else if (left < -LayoutConstants.WORLD_BOUNDARY) { + left = -LayoutConstants.WORLD_BOUNDARY; + } + + var top = this.rect.y; + + if (top > LayoutConstants.WORLD_BOUNDARY) { + top = LayoutConstants.WORLD_BOUNDARY; + } else if (top < -LayoutConstants.WORLD_BOUNDARY) { + top = -LayoutConstants.WORLD_BOUNDARY; + } + + var leftTop = new PointD(left, top); + var vLeftTop = trans.inverseTransformPoint(leftTop); + + this.setLocation(vLeftTop.x, vLeftTop.y); +}; + +LNode.prototype.getLeft = function () { + return this.rect.x; +}; + +LNode.prototype.getRight = function () { + return this.rect.x + this.rect.width; +}; + +LNode.prototype.getTop = function () { + return this.rect.y; +}; + +LNode.prototype.getBottom = function () { + return this.rect.y + this.rect.height; +}; + +LNode.prototype.getParent = function () { + if (this.owner == null) { + return null; + } + + return this.owner.getParent(); +}; + +module.exports = LNode; + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function PointD(x, y) { + if (x == null && y == null) { + this.x = 0; + this.y = 0; + } else { + this.x = x; + this.y = y; + } +} + +PointD.prototype.getX = function () { + return this.x; +}; + +PointD.prototype.getY = function () { + return this.y; +}; + +PointD.prototype.setX = function (x) { + this.x = x; +}; + +PointD.prototype.setY = function (y) { + this.y = y; +}; + +PointD.prototype.getDifference = function (pt) { + return new DimensionD(this.x - pt.x, this.y - pt.y); +}; + +PointD.prototype.getCopy = function () { + return new PointD(this.x, this.y); +}; + +PointD.prototype.translate = function (dim) { + this.x += dim.width; + this.y += dim.height; + return this; +}; + +module.exports = PointD; + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __nested_webpack_require_17549__) { + +"use strict"; + + +var LGraphObject = __nested_webpack_require_17549__(2); +var Integer = __nested_webpack_require_17549__(10); +var LayoutConstants = __nested_webpack_require_17549__(0); +var LGraphManager = __nested_webpack_require_17549__(6); +var LNode = __nested_webpack_require_17549__(3); +var LEdge = __nested_webpack_require_17549__(1); +var RectangleD = __nested_webpack_require_17549__(13); +var Point = __nested_webpack_require_17549__(12); +var LinkedList = __nested_webpack_require_17549__(11); + +function LGraph(parent, obj2, vGraph) { + LGraphObject.call(this, vGraph); + this.estimatedSize = Integer.MIN_VALUE; + this.margin = LayoutConstants.DEFAULT_GRAPH_MARGIN; + this.edges = []; + this.nodes = []; + this.isConnected = false; + this.parent = parent; + + if (obj2 != null && obj2 instanceof LGraphManager) { + this.graphManager = obj2; + } else if (obj2 != null && obj2 instanceof Layout) { + this.graphManager = obj2.graphManager; + } +} + +LGraph.prototype = Object.create(LGraphObject.prototype); +for (var prop in LGraphObject) { + LGraph[prop] = LGraphObject[prop]; +} + +LGraph.prototype.getNodes = function () { + return this.nodes; +}; + +LGraph.prototype.getEdges = function () { + return this.edges; +}; + +LGraph.prototype.getGraphManager = function () { + return this.graphManager; +}; + +LGraph.prototype.getParent = function () { + return this.parent; +}; + +LGraph.prototype.getLeft = function () { + return this.left; +}; + +LGraph.prototype.getRight = function () { + return this.right; +}; + +LGraph.prototype.getTop = function () { + return this.top; +}; + +LGraph.prototype.getBottom = function () { + return this.bottom; +}; + +LGraph.prototype.isConnected = function () { + return this.isConnected; +}; + +LGraph.prototype.add = function (obj1, sourceNode, targetNode) { + if (sourceNode == null && targetNode == null) { + var newNode = obj1; + if (this.graphManager == null) { + throw "Graph has no graph mgr!"; + } + if (this.getNodes().indexOf(newNode) > -1) { + throw "Node already in graph!"; + } + newNode.owner = this; + this.getNodes().push(newNode); + + return newNode; + } else { + var newEdge = obj1; + if (!(this.getNodes().indexOf(sourceNode) > -1 && this.getNodes().indexOf(targetNode) > -1)) { + throw "Source or target not in graph!"; + } + + if (!(sourceNode.owner == targetNode.owner && sourceNode.owner == this)) { + throw "Both owners must be this graph!"; + } + + if (sourceNode.owner != targetNode.owner) { + return null; + } + + // set source and target + newEdge.source = sourceNode; + newEdge.target = targetNode; + + // set as intra-graph edge + newEdge.isInterGraph = false; + + // add to graph edge list + this.getEdges().push(newEdge); + + // add to incidency lists + sourceNode.edges.push(newEdge); + + if (targetNode != sourceNode) { + targetNode.edges.push(newEdge); + } + + return newEdge; + } +}; + +LGraph.prototype.remove = function (obj) { + var node = obj; + if (obj instanceof LNode) { + if (node == null) { + throw "Node is null!"; + } + if (!(node.owner != null && node.owner == this)) { + throw "Owner graph is invalid!"; + } + if (this.graphManager == null) { + throw "Owner graph manager is invalid!"; + } + // remove incident edges first (make a copy to do it safely) + var edgesToBeRemoved = node.edges.slice(); + var edge; + var s = edgesToBeRemoved.length; + for (var i = 0; i < s; i++) { + edge = edgesToBeRemoved[i]; + + if (edge.isInterGraph) { + this.graphManager.remove(edge); + } else { + edge.source.owner.remove(edge); + } + } + + // now the node itself + var index = this.nodes.indexOf(node); + if (index == -1) { + throw "Node not in owner node list!"; + } + + this.nodes.splice(index, 1); + } else if (obj instanceof LEdge) { + var edge = obj; + if (edge == null) { + throw "Edge is null!"; + } + if (!(edge.source != null && edge.target != null)) { + throw "Source and/or target is null!"; + } + if (!(edge.source.owner != null && edge.target.owner != null && edge.source.owner == this && edge.target.owner == this)) { + throw "Source and/or target owner is invalid!"; + } + + var sourceIndex = edge.source.edges.indexOf(edge); + var targetIndex = edge.target.edges.indexOf(edge); + if (!(sourceIndex > -1 && targetIndex > -1)) { + throw "Source and/or target doesn't know this edge!"; + } + + edge.source.edges.splice(sourceIndex, 1); + + if (edge.target != edge.source) { + edge.target.edges.splice(targetIndex, 1); + } + + var index = edge.source.owner.getEdges().indexOf(edge); + if (index == -1) { + throw "Not in owner's edge list!"; + } + + edge.source.owner.getEdges().splice(index, 1); + } +}; + +LGraph.prototype.updateLeftTop = function () { + var top = Integer.MAX_VALUE; + var left = Integer.MAX_VALUE; + var nodeTop; + var nodeLeft; + var margin; + + var nodes = this.getNodes(); + var s = nodes.length; + + for (var i = 0; i < s; i++) { + var lNode = nodes[i]; + nodeTop = lNode.getTop(); + nodeLeft = lNode.getLeft(); + + if (top > nodeTop) { + top = nodeTop; + } + + if (left > nodeLeft) { + left = nodeLeft; + } + } + + // Do we have any nodes in this graph? + if (top == Integer.MAX_VALUE) { + return null; + } + + if (nodes[0].getParent().paddingLeft != undefined) { + margin = nodes[0].getParent().paddingLeft; + } else { + margin = this.margin; + } + + this.left = left - margin; + this.top = top - margin; + + // Apply the margins and return the result + return new Point(this.left, this.top); +}; + +LGraph.prototype.updateBounds = function (recursive) { + // calculate bounds + var left = Integer.MAX_VALUE; + var right = -Integer.MAX_VALUE; + var top = Integer.MAX_VALUE; + var bottom = -Integer.MAX_VALUE; + var nodeLeft; + var nodeRight; + var nodeTop; + var nodeBottom; + var margin; + + var nodes = this.nodes; + var s = nodes.length; + for (var i = 0; i < s; i++) { + var lNode = nodes[i]; + + if (recursive && lNode.child != null) { + lNode.updateBounds(); + } + nodeLeft = lNode.getLeft(); + nodeRight = lNode.getRight(); + nodeTop = lNode.getTop(); + nodeBottom = lNode.getBottom(); + + if (left > nodeLeft) { + left = nodeLeft; + } + + if (right < nodeRight) { + right = nodeRight; + } + + if (top > nodeTop) { + top = nodeTop; + } + + if (bottom < nodeBottom) { + bottom = nodeBottom; + } + } + + var boundingRect = new RectangleD(left, top, right - left, bottom - top); + if (left == Integer.MAX_VALUE) { + this.left = this.parent.getLeft(); + this.right = this.parent.getRight(); + this.top = this.parent.getTop(); + this.bottom = this.parent.getBottom(); + } + + if (nodes[0].getParent().paddingLeft != undefined) { + margin = nodes[0].getParent().paddingLeft; + } else { + margin = this.margin; + } + + this.left = boundingRect.x - margin; + this.right = boundingRect.x + boundingRect.width + margin; + this.top = boundingRect.y - margin; + this.bottom = boundingRect.y + boundingRect.height + margin; +}; + +LGraph.calculateBounds = function (nodes) { + var left = Integer.MAX_VALUE; + var right = -Integer.MAX_VALUE; + var top = Integer.MAX_VALUE; + var bottom = -Integer.MAX_VALUE; + var nodeLeft; + var nodeRight; + var nodeTop; + var nodeBottom; + + var s = nodes.length; + + for (var i = 0; i < s; i++) { + var lNode = nodes[i]; + nodeLeft = lNode.getLeft(); + nodeRight = lNode.getRight(); + nodeTop = lNode.getTop(); + nodeBottom = lNode.getBottom(); + + if (left > nodeLeft) { + left = nodeLeft; + } + + if (right < nodeRight) { + right = nodeRight; + } + + if (top > nodeTop) { + top = nodeTop; + } + + if (bottom < nodeBottom) { + bottom = nodeBottom; + } + } + + var boundingRect = new RectangleD(left, top, right - left, bottom - top); + + return boundingRect; +}; + +LGraph.prototype.getInclusionTreeDepth = function () { + if (this == this.graphManager.getRoot()) { + return 1; + } else { + return this.parent.getInclusionTreeDepth(); + } +}; + +LGraph.prototype.getEstimatedSize = function () { + if (this.estimatedSize == Integer.MIN_VALUE) { + throw "assert failed"; + } + return this.estimatedSize; +}; + +LGraph.prototype.calcEstimatedSize = function () { + var size = 0; + var nodes = this.nodes; + var s = nodes.length; + + for (var i = 0; i < s; i++) { + var lNode = nodes[i]; + size += lNode.calcEstimatedSize(); + } + + if (size == 0) { + this.estimatedSize = LayoutConstants.EMPTY_COMPOUND_NODE_SIZE; + } else { + this.estimatedSize = size / Math.sqrt(this.nodes.length); + } + + return this.estimatedSize; +}; + +LGraph.prototype.updateConnected = function () { + var self = this; + if (this.nodes.length == 0) { + this.isConnected = true; + return; + } + + var queue = new LinkedList(); + var visited = new Set(); + var currentNode = this.nodes[0]; + var neighborEdges; + var currentNeighbor; + var childrenOfNode = currentNode.withChildren(); + childrenOfNode.forEach(function (node) { + queue.push(node); + visited.add(node); + }); + + while (queue.length !== 0) { + currentNode = queue.shift(); + + // Traverse all neighbors of this node + neighborEdges = currentNode.getEdges(); + var size = neighborEdges.length; + for (var i = 0; i < size; i++) { + var neighborEdge = neighborEdges[i]; + currentNeighbor = neighborEdge.getOtherEndInGraph(currentNode, this); + + // Add unvisited neighbors to the list to visit + if (currentNeighbor != null && !visited.has(currentNeighbor)) { + var childrenOfNeighbor = currentNeighbor.withChildren(); + + childrenOfNeighbor.forEach(function (node) { + queue.push(node); + visited.add(node); + }); + } + } + } + + this.isConnected = false; + + if (visited.size >= this.nodes.length) { + var noOfVisitedInThisGraph = 0; + + visited.forEach(function (visitedNode) { + if (visitedNode.owner == self) { + noOfVisitedInThisGraph++; + } + }); + + if (noOfVisitedInThisGraph == this.nodes.length) { + this.isConnected = true; + } + } +}; + +module.exports = LGraph; + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __nested_webpack_require_27617__) { + +"use strict"; + + +var LGraph; +var LEdge = __nested_webpack_require_27617__(1); + +function LGraphManager(layout) { + LGraph = __nested_webpack_require_27617__(5); // It may be better to initilize this out of this function but it gives an error (Right-hand side of 'instanceof' is not callable) now. + this.layout = layout; + + this.graphs = []; + this.edges = []; +} + +LGraphManager.prototype.addRoot = function () { + var ngraph = this.layout.newGraph(); + var nnode = this.layout.newNode(null); + var root = this.add(ngraph, nnode); + this.setRootGraph(root); + return this.rootGraph; +}; + +LGraphManager.prototype.add = function (newGraph, parentNode, newEdge, sourceNode, targetNode) { + //there are just 2 parameters are passed then it adds an LGraph else it adds an LEdge + if (newEdge == null && sourceNode == null && targetNode == null) { + if (newGraph == null) { + throw "Graph is null!"; + } + if (parentNode == null) { + throw "Parent node is null!"; + } + if (this.graphs.indexOf(newGraph) > -1) { + throw "Graph already in this graph mgr!"; + } + + this.graphs.push(newGraph); + + if (newGraph.parent != null) { + throw "Already has a parent!"; + } + if (parentNode.child != null) { + throw "Already has a child!"; + } + + newGraph.parent = parentNode; + parentNode.child = newGraph; + + return newGraph; + } else { + //change the order of the parameters + targetNode = newEdge; + sourceNode = parentNode; + newEdge = newGraph; + var sourceGraph = sourceNode.getOwner(); + var targetGraph = targetNode.getOwner(); + + if (!(sourceGraph != null && sourceGraph.getGraphManager() == this)) { + throw "Source not in this graph mgr!"; + } + if (!(targetGraph != null && targetGraph.getGraphManager() == this)) { + throw "Target not in this graph mgr!"; + } + + if (sourceGraph == targetGraph) { + newEdge.isInterGraph = false; + return sourceGraph.add(newEdge, sourceNode, targetNode); + } else { + newEdge.isInterGraph = true; + + // set source and target + newEdge.source = sourceNode; + newEdge.target = targetNode; + + // add edge to inter-graph edge list + if (this.edges.indexOf(newEdge) > -1) { + throw "Edge already in inter-graph edge list!"; + } + + this.edges.push(newEdge); + + // add edge to source and target incidency lists + if (!(newEdge.source != null && newEdge.target != null)) { + throw "Edge source and/or target is null!"; + } + + if (!(newEdge.source.edges.indexOf(newEdge) == -1 && newEdge.target.edges.indexOf(newEdge) == -1)) { + throw "Edge already in source and/or target incidency list!"; + } + + newEdge.source.edges.push(newEdge); + newEdge.target.edges.push(newEdge); + + return newEdge; + } + } +}; + +LGraphManager.prototype.remove = function (lObj) { + if (lObj instanceof LGraph) { + var graph = lObj; + if (graph.getGraphManager() != this) { + throw "Graph not in this graph mgr"; + } + if (!(graph == this.rootGraph || graph.parent != null && graph.parent.graphManager == this)) { + throw "Invalid parent node!"; + } + + // first the edges (make a copy to do it safely) + var edgesToBeRemoved = []; + + edgesToBeRemoved = edgesToBeRemoved.concat(graph.getEdges()); + + var edge; + var s = edgesToBeRemoved.length; + for (var i = 0; i < s; i++) { + edge = edgesToBeRemoved[i]; + graph.remove(edge); + } + + // then the nodes (make a copy to do it safely) + var nodesToBeRemoved = []; + + nodesToBeRemoved = nodesToBeRemoved.concat(graph.getNodes()); + + var node; + s = nodesToBeRemoved.length; + for (var i = 0; i < s; i++) { + node = nodesToBeRemoved[i]; + graph.remove(node); + } + + // check if graph is the root + if (graph == this.rootGraph) { + this.setRootGraph(null); + } + + // now remove the graph itself + var index = this.graphs.indexOf(graph); + this.graphs.splice(index, 1); + + // also reset the parent of the graph + graph.parent = null; + } else if (lObj instanceof LEdge) { + edge = lObj; + if (edge == null) { + throw "Edge is null!"; + } + if (!edge.isInterGraph) { + throw "Not an inter-graph edge!"; + } + if (!(edge.source != null && edge.target != null)) { + throw "Source and/or target is null!"; + } + + // remove edge from source and target nodes' incidency lists + + if (!(edge.source.edges.indexOf(edge) != -1 && edge.target.edges.indexOf(edge) != -1)) { + throw "Source and/or target doesn't know this edge!"; + } + + var index = edge.source.edges.indexOf(edge); + edge.source.edges.splice(index, 1); + index = edge.target.edges.indexOf(edge); + edge.target.edges.splice(index, 1); + + // remove edge from owner graph manager's inter-graph edge list + + if (!(edge.source.owner != null && edge.source.owner.getGraphManager() != null)) { + throw "Edge owner graph or owner graph manager is null!"; + } + if (edge.source.owner.getGraphManager().edges.indexOf(edge) == -1) { + throw "Not in owner graph manager's edge list!"; + } + + var index = edge.source.owner.getGraphManager().edges.indexOf(edge); + edge.source.owner.getGraphManager().edges.splice(index, 1); + } +}; + +LGraphManager.prototype.updateBounds = function () { + this.rootGraph.updateBounds(true); +}; + +LGraphManager.prototype.getGraphs = function () { + return this.graphs; +}; + +LGraphManager.prototype.getAllNodes = function () { + if (this.allNodes == null) { + var nodeList = []; + var graphs = this.getGraphs(); + var s = graphs.length; + for (var i = 0; i < s; i++) { + nodeList = nodeList.concat(graphs[i].getNodes()); + } + this.allNodes = nodeList; + } + return this.allNodes; +}; + +LGraphManager.prototype.resetAllNodes = function () { + this.allNodes = null; +}; + +LGraphManager.prototype.resetAllEdges = function () { + this.allEdges = null; +}; + +LGraphManager.prototype.resetAllNodesToApplyGravitation = function () { + this.allNodesToApplyGravitation = null; +}; + +LGraphManager.prototype.getAllEdges = function () { + if (this.allEdges == null) { + var edgeList = []; + var graphs = this.getGraphs(); + var s = graphs.length; + for (var i = 0; i < graphs.length; i++) { + edgeList = edgeList.concat(graphs[i].getEdges()); + } + + edgeList = edgeList.concat(this.edges); + + this.allEdges = edgeList; + } + return this.allEdges; +}; + +LGraphManager.prototype.getAllNodesToApplyGravitation = function () { + return this.allNodesToApplyGravitation; +}; + +LGraphManager.prototype.setAllNodesToApplyGravitation = function (nodeList) { + if (this.allNodesToApplyGravitation != null) { + throw "assert failed"; + } + + this.allNodesToApplyGravitation = nodeList; +}; + +LGraphManager.prototype.getRoot = function () { + return this.rootGraph; +}; + +LGraphManager.prototype.setRootGraph = function (graph) { + if (graph.getGraphManager() != this) { + throw "Root not in this graph mgr!"; + } + + this.rootGraph = graph; + // root graph must have a root node associated with it for convenience + if (graph.parent == null) { + graph.parent = this.layout.newNode("Root node"); + } +}; + +LGraphManager.prototype.getLayout = function () { + return this.layout; +}; + +LGraphManager.prototype.isOneAncestorOfOther = function (firstNode, secondNode) { + if (!(firstNode != null && secondNode != null)) { + throw "assert failed"; + } + + if (firstNode == secondNode) { + return true; + } + // Is second node an ancestor of the first one? + var ownerGraph = firstNode.getOwner(); + var parentNode; + + do { + parentNode = ownerGraph.getParent(); + + if (parentNode == null) { + break; + } + + if (parentNode == secondNode) { + return true; + } + + ownerGraph = parentNode.getOwner(); + if (ownerGraph == null) { + break; + } + } while (true); + // Is first node an ancestor of the second one? + ownerGraph = secondNode.getOwner(); + + do { + parentNode = ownerGraph.getParent(); + + if (parentNode == null) { + break; + } + + if (parentNode == firstNode) { + return true; + } + + ownerGraph = parentNode.getOwner(); + if (ownerGraph == null) { + break; + } + } while (true); + + return false; +}; + +LGraphManager.prototype.calcLowestCommonAncestors = function () { + var edge; + var sourceNode; + var targetNode; + var sourceAncestorGraph; + var targetAncestorGraph; + + var edges = this.getAllEdges(); + var s = edges.length; + for (var i = 0; i < s; i++) { + edge = edges[i]; + + sourceNode = edge.source; + targetNode = edge.target; + edge.lca = null; + edge.sourceInLca = sourceNode; + edge.targetInLca = targetNode; + + if (sourceNode == targetNode) { + edge.lca = sourceNode.getOwner(); + continue; + } + + sourceAncestorGraph = sourceNode.getOwner(); + + while (edge.lca == null) { + edge.targetInLca = targetNode; + targetAncestorGraph = targetNode.getOwner(); + + while (edge.lca == null) { + if (targetAncestorGraph == sourceAncestorGraph) { + edge.lca = targetAncestorGraph; + break; + } + + if (targetAncestorGraph == this.rootGraph) { + break; + } + + if (edge.lca != null) { + throw "assert failed"; + } + edge.targetInLca = targetAncestorGraph.getParent(); + targetAncestorGraph = edge.targetInLca.getOwner(); + } + + if (sourceAncestorGraph == this.rootGraph) { + break; + } + + if (edge.lca == null) { + edge.sourceInLca = sourceAncestorGraph.getParent(); + sourceAncestorGraph = edge.sourceInLca.getOwner(); + } + } + + if (edge.lca == null) { + throw "assert failed"; + } + } +}; + +LGraphManager.prototype.calcLowestCommonAncestor = function (firstNode, secondNode) { + if (firstNode == secondNode) { + return firstNode.getOwner(); + } + var firstOwnerGraph = firstNode.getOwner(); + + do { + if (firstOwnerGraph == null) { + break; + } + var secondOwnerGraph = secondNode.getOwner(); + + do { + if (secondOwnerGraph == null) { + break; + } + + if (secondOwnerGraph == firstOwnerGraph) { + return secondOwnerGraph; + } + secondOwnerGraph = secondOwnerGraph.getParent().getOwner(); + } while (true); + + firstOwnerGraph = firstOwnerGraph.getParent().getOwner(); + } while (true); + + return firstOwnerGraph; +}; + +LGraphManager.prototype.calcInclusionTreeDepths = function (graph, depth) { + if (graph == null && depth == null) { + graph = this.rootGraph; + depth = 1; + } + var node; + + var nodes = graph.getNodes(); + var s = nodes.length; + for (var i = 0; i < s; i++) { + node = nodes[i]; + node.inclusionTreeDepth = depth; + + if (node.child != null) { + this.calcInclusionTreeDepths(node.child, depth + 1); + } + } +}; + +LGraphManager.prototype.includesInvalidEdge = function () { + var edge; + + var s = this.edges.length; + for (var i = 0; i < s; i++) { + edge = this.edges[i]; + + if (this.isOneAncestorOfOther(edge.source, edge.target)) { + return true; + } + } + return false; +}; + +module.exports = LGraphManager; + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __nested_webpack_require_38707__) { + +"use strict"; + + +var LayoutConstants = __nested_webpack_require_38707__(0); + +function FDLayoutConstants() {} + +//FDLayoutConstants inherits static props in LayoutConstants +for (var prop in LayoutConstants) { + FDLayoutConstants[prop] = LayoutConstants[prop]; +} + +FDLayoutConstants.MAX_ITERATIONS = 2500; + +FDLayoutConstants.DEFAULT_EDGE_LENGTH = 50; +FDLayoutConstants.DEFAULT_SPRING_STRENGTH = 0.45; +FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = 4500.0; +FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = 0.4; +FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = 1.0; +FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = 3.8; +FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = 1.5; +FDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION = true; +FDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION = true; +FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = 0.3; +FDLayoutConstants.COOLING_ADAPTATION_FACTOR = 0.33; +FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT = 1000; +FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT = 5000; +FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL = 100.0; +FDLayoutConstants.MAX_NODE_DISPLACEMENT = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL * 3; +FDLayoutConstants.MIN_REPULSION_DIST = FDLayoutConstants.DEFAULT_EDGE_LENGTH / 10.0; +FDLayoutConstants.CONVERGENCE_CHECK_PERIOD = 100; +FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = 0.1; +FDLayoutConstants.MIN_EDGE_LENGTH = 1; +FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD = 10; + +module.exports = FDLayoutConstants; + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __nested_webpack_require_40298__) { + +"use strict"; + + +/** + * This class maintains a list of static geometry related utility methods. + * + * + * Copyright: i-Vis Research Group, Bilkent University, 2007 - present + */ + +var Point = __nested_webpack_require_40298__(12); + +function IGeometry() {} + +/** + * This method calculates *half* the amount in x and y directions of the two + * input rectangles needed to separate them keeping their respective + * positioning, and returns the result in the input array. An input + * separation buffer added to the amount in both directions. We assume that + * the two rectangles do intersect. + */ +IGeometry.calcSeparationAmount = function (rectA, rectB, overlapAmount, separationBuffer) { + if (!rectA.intersects(rectB)) { + throw "assert failed"; + } + + var directions = new Array(2); + + this.decideDirectionsForOverlappingNodes(rectA, rectB, directions); + + overlapAmount[0] = Math.min(rectA.getRight(), rectB.getRight()) - Math.max(rectA.x, rectB.x); + overlapAmount[1] = Math.min(rectA.getBottom(), rectB.getBottom()) - Math.max(rectA.y, rectB.y); + + // update the overlapping amounts for the following cases: + if (rectA.getX() <= rectB.getX() && rectA.getRight() >= rectB.getRight()) { + /* Case x.1: + * + * rectA + * | | + * | _________ | + * | | | | + * |________|_______|______| + * | | + * | | + * rectB + */ + overlapAmount[0] += Math.min(rectB.getX() - rectA.getX(), rectA.getRight() - rectB.getRight()); + } else if (rectB.getX() <= rectA.getX() && rectB.getRight() >= rectA.getRight()) { + /* Case x.2: + * + * rectB + * | | + * | _________ | + * | | | | + * |________|_______|______| + * | | + * | | + * rectA + */ + overlapAmount[0] += Math.min(rectA.getX() - rectB.getX(), rectB.getRight() - rectA.getRight()); + } + if (rectA.getY() <= rectB.getY() && rectA.getBottom() >= rectB.getBottom()) { + /* Case y.1: + * ________ rectA + * | + * | + * ______|____ rectB + * | | + * | | + * ______|____| + * | + * | + * |________ + * + */ + overlapAmount[1] += Math.min(rectB.getY() - rectA.getY(), rectA.getBottom() - rectB.getBottom()); + } else if (rectB.getY() <= rectA.getY() && rectB.getBottom() >= rectA.getBottom()) { + /* Case y.2: + * ________ rectB + * | + * | + * ______|____ rectA + * | | + * | | + * ______|____| + * | + * | + * |________ + * + */ + overlapAmount[1] += Math.min(rectA.getY() - rectB.getY(), rectB.getBottom() - rectA.getBottom()); + } + + // find slope of the line passes two centers + var slope = Math.abs((rectB.getCenterY() - rectA.getCenterY()) / (rectB.getCenterX() - rectA.getCenterX())); + // if centers are overlapped + if (rectB.getCenterY() === rectA.getCenterY() && rectB.getCenterX() === rectA.getCenterX()) { + // assume the slope is 1 (45 degree) + slope = 1.0; + } + + var moveByY = slope * overlapAmount[0]; + var moveByX = overlapAmount[1] / slope; + if (overlapAmount[0] < moveByX) { + moveByX = overlapAmount[0]; + } else { + moveByY = overlapAmount[1]; + } + // return half the amount so that if each rectangle is moved by these + // amounts in opposite directions, overlap will be resolved + overlapAmount[0] = -1 * directions[0] * (moveByX / 2 + separationBuffer); + overlapAmount[1] = -1 * directions[1] * (moveByY / 2 + separationBuffer); +}; + +/** + * This method decides the separation direction of overlapping nodes + * + * if directions[0] = -1, then rectA goes left + * if directions[0] = 1, then rectA goes right + * if directions[1] = -1, then rectA goes up + * if directions[1] = 1, then rectA goes down + */ +IGeometry.decideDirectionsForOverlappingNodes = function (rectA, rectB, directions) { + if (rectA.getCenterX() < rectB.getCenterX()) { + directions[0] = -1; + } else { + directions[0] = 1; + } + + if (rectA.getCenterY() < rectB.getCenterY()) { + directions[1] = -1; + } else { + directions[1] = 1; + } +}; + +/** + * This method calculates the intersection (clipping) points of the two + * input rectangles with line segment defined by the centers of these two + * rectangles. The clipping points are saved in the input double array and + * whether or not the two rectangles overlap is returned. + */ +IGeometry.getIntersection2 = function (rectA, rectB, result) { + //result[0-1] will contain clipPoint of rectA, result[2-3] will contain clipPoint of rectB + var p1x = rectA.getCenterX(); + var p1y = rectA.getCenterY(); + var p2x = rectB.getCenterX(); + var p2y = rectB.getCenterY(); + + //if two rectangles intersect, then clipping points are centers + if (rectA.intersects(rectB)) { + result[0] = p1x; + result[1] = p1y; + result[2] = p2x; + result[3] = p2y; + return true; + } + //variables for rectA + var topLeftAx = rectA.getX(); + var topLeftAy = rectA.getY(); + var topRightAx = rectA.getRight(); + var bottomLeftAx = rectA.getX(); + var bottomLeftAy = rectA.getBottom(); + var bottomRightAx = rectA.getRight(); + var halfWidthA = rectA.getWidthHalf(); + var halfHeightA = rectA.getHeightHalf(); + //variables for rectB + var topLeftBx = rectB.getX(); + var topLeftBy = rectB.getY(); + var topRightBx = rectB.getRight(); + var bottomLeftBx = rectB.getX(); + var bottomLeftBy = rectB.getBottom(); + var bottomRightBx = rectB.getRight(); + var halfWidthB = rectB.getWidthHalf(); + var halfHeightB = rectB.getHeightHalf(); + + //flag whether clipping points are found + var clipPointAFound = false; + var clipPointBFound = false; + + // line is vertical + if (p1x === p2x) { + if (p1y > p2y) { + result[0] = p1x; + result[1] = topLeftAy; + result[2] = p2x; + result[3] = bottomLeftBy; + return false; + } else if (p1y < p2y) { + result[0] = p1x; + result[1] = bottomLeftAy; + result[2] = p2x; + result[3] = topLeftBy; + return false; + } else { + //not line, return null; + } + } + // line is horizontal + else if (p1y === p2y) { + if (p1x > p2x) { + result[0] = topLeftAx; + result[1] = p1y; + result[2] = topRightBx; + result[3] = p2y; + return false; + } else if (p1x < p2x) { + result[0] = topRightAx; + result[1] = p1y; + result[2] = topLeftBx; + result[3] = p2y; + return false; + } else { + //not valid line, return null; + } + } else { + //slopes of rectA's and rectB's diagonals + var slopeA = rectA.height / rectA.width; + var slopeB = rectB.height / rectB.width; + + //slope of line between center of rectA and center of rectB + var slopePrime = (p2y - p1y) / (p2x - p1x); + var cardinalDirectionA = void 0; + var cardinalDirectionB = void 0; + var tempPointAx = void 0; + var tempPointAy = void 0; + var tempPointBx = void 0; + var tempPointBy = void 0; + + //determine whether clipping point is the corner of nodeA + if (-slopeA === slopePrime) { + if (p1x > p2x) { + result[0] = bottomLeftAx; + result[1] = bottomLeftAy; + clipPointAFound = true; + } else { + result[0] = topRightAx; + result[1] = topLeftAy; + clipPointAFound = true; + } + } else if (slopeA === slopePrime) { + if (p1x > p2x) { + result[0] = topLeftAx; + result[1] = topLeftAy; + clipPointAFound = true; + } else { + result[0] = bottomRightAx; + result[1] = bottomLeftAy; + clipPointAFound = true; + } + } + + //determine whether clipping point is the corner of nodeB + if (-slopeB === slopePrime) { + if (p2x > p1x) { + result[2] = bottomLeftBx; + result[3] = bottomLeftBy; + clipPointBFound = true; + } else { + result[2] = topRightBx; + result[3] = topLeftBy; + clipPointBFound = true; + } + } else if (slopeB === slopePrime) { + if (p2x > p1x) { + result[2] = topLeftBx; + result[3] = topLeftBy; + clipPointBFound = true; + } else { + result[2] = bottomRightBx; + result[3] = bottomLeftBy; + clipPointBFound = true; + } + } + + //if both clipping points are corners + if (clipPointAFound && clipPointBFound) { + return false; + } + + //determine Cardinal Direction of rectangles + if (p1x > p2x) { + if (p1y > p2y) { + cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 4); + cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 2); + } else { + cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 3); + cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 1); + } + } else { + if (p1y > p2y) { + cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 1); + cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 3); + } else { + cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 2); + cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 4); + } + } + //calculate clipping Point if it is not found before + if (!clipPointAFound) { + switch (cardinalDirectionA) { + case 1: + tempPointAy = topLeftAy; + tempPointAx = p1x + -halfHeightA / slopePrime; + result[0] = tempPointAx; + result[1] = tempPointAy; + break; + case 2: + tempPointAx = bottomRightAx; + tempPointAy = p1y + halfWidthA * slopePrime; + result[0] = tempPointAx; + result[1] = tempPointAy; + break; + case 3: + tempPointAy = bottomLeftAy; + tempPointAx = p1x + halfHeightA / slopePrime; + result[0] = tempPointAx; + result[1] = tempPointAy; + break; + case 4: + tempPointAx = bottomLeftAx; + tempPointAy = p1y + -halfWidthA * slopePrime; + result[0] = tempPointAx; + result[1] = tempPointAy; + break; + } + } + if (!clipPointBFound) { + switch (cardinalDirectionB) { + case 1: + tempPointBy = topLeftBy; + tempPointBx = p2x + -halfHeightB / slopePrime; + result[2] = tempPointBx; + result[3] = tempPointBy; + break; + case 2: + tempPointBx = bottomRightBx; + tempPointBy = p2y + halfWidthB * slopePrime; + result[2] = tempPointBx; + result[3] = tempPointBy; + break; + case 3: + tempPointBy = bottomLeftBy; + tempPointBx = p2x + halfHeightB / slopePrime; + result[2] = tempPointBx; + result[3] = tempPointBy; + break; + case 4: + tempPointBx = bottomLeftBx; + tempPointBy = p2y + -halfWidthB * slopePrime; + result[2] = tempPointBx; + result[3] = tempPointBy; + break; + } + } + } + return false; +}; + +/** + * This method returns in which cardinal direction does input point stays + * 1: North + * 2: East + * 3: South + * 4: West + */ +IGeometry.getCardinalDirection = function (slope, slopePrime, line) { + if (slope > slopePrime) { + return line; + } else { + return 1 + line % 4; + } +}; + +/** + * This method calculates the intersection of the two lines defined by + * point pairs (s1,s2) and (f1,f2). + */ +IGeometry.getIntersection = function (s1, s2, f1, f2) { + if (f2 == null) { + return this.getIntersection2(s1, s2, f1); + } + + var x1 = s1.x; + var y1 = s1.y; + var x2 = s2.x; + var y2 = s2.y; + var x3 = f1.x; + var y3 = f1.y; + var x4 = f2.x; + var y4 = f2.y; + var x = void 0, + y = void 0; // intersection point + var a1 = void 0, + a2 = void 0, + b1 = void 0, + b2 = void 0, + c1 = void 0, + c2 = void 0; // coefficients of line eqns. + var denom = void 0; + + a1 = y2 - y1; + b1 = x1 - x2; + c1 = x2 * y1 - x1 * y2; // { a1*x + b1*y + c1 = 0 is line 1 } + + a2 = y4 - y3; + b2 = x3 - x4; + c2 = x4 * y3 - x3 * y4; // { a2*x + b2*y + c2 = 0 is line 2 } + + denom = a1 * b2 - a2 * b1; + + if (denom === 0) { + return null; + } + + x = (b1 * c2 - b2 * c1) / denom; + y = (a2 * c1 - a1 * c2) / denom; + + return new Point(x, y); +}; + +/** + * This method finds and returns the angle of the vector from the + x-axis + * in clockwise direction (compatible w/ Java coordinate system!). + */ +IGeometry.angleOfVector = function (Cx, Cy, Nx, Ny) { + var C_angle = void 0; + + if (Cx !== Nx) { + C_angle = Math.atan((Ny - Cy) / (Nx - Cx)); + + if (Nx < Cx) { + C_angle += Math.PI; + } else if (Ny < Cy) { + C_angle += this.TWO_PI; + } + } else if (Ny < Cy) { + C_angle = this.ONE_AND_HALF_PI; // 270 degrees + } else { + C_angle = this.HALF_PI; // 90 degrees + } + + return C_angle; +}; + +/** + * This method checks whether the given two line segments (one with point + * p1 and p2, the other with point p3 and p4) intersect at a point other + * than these points. + */ +IGeometry.doIntersect = function (p1, p2, p3, p4) { + var a = p1.x; + var b = p1.y; + var c = p2.x; + var d = p2.y; + var p = p3.x; + var q = p3.y; + var r = p4.x; + var s = p4.y; + var det = (c - a) * (s - q) - (r - p) * (d - b); + + if (det === 0) { + return false; + } else { + var lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det; + var gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det; + return 0 < lambda && lambda < 1 && 0 < gamma && gamma < 1; + } +}; + +// ----------------------------------------------------------------------------- +// Section: Class Constants +// ----------------------------------------------------------------------------- +/** + * Some useful pre-calculated constants + */ +IGeometry.HALF_PI = 0.5 * Math.PI; +IGeometry.ONE_AND_HALF_PI = 1.5 * Math.PI; +IGeometry.TWO_PI = 2.0 * Math.PI; +IGeometry.THREE_PI = 3.0 * Math.PI; + +module.exports = IGeometry; + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function IMath() {} + +/** + * This method returns the sign of the input value. + */ +IMath.sign = function (value) { + if (value > 0) { + return 1; + } else if (value < 0) { + return -1; + } else { + return 0; + } +}; + +IMath.floor = function (value) { + return value < 0 ? Math.ceil(value) : Math.floor(value); +}; + +IMath.ceil = function (value) { + return value < 0 ? Math.floor(value) : Math.ceil(value); +}; + +module.exports = IMath; + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function Integer() {} + +Integer.MAX_VALUE = 2147483647; +Integer.MIN_VALUE = -2147483648; + +module.exports = Integer; + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var nodeFrom = function nodeFrom(value) { + return { value: value, next: null, prev: null }; +}; + +var add = function add(prev, node, next, list) { + if (prev !== null) { + prev.next = node; + } else { + list.head = node; + } + + if (next !== null) { + next.prev = node; + } else { + list.tail = node; + } + + node.prev = prev; + node.next = next; + + list.length++; + + return node; +}; + +var _remove = function _remove(node, list) { + var prev = node.prev, + next = node.next; + + + if (prev !== null) { + prev.next = next; + } else { + list.head = next; + } + + if (next !== null) { + next.prev = prev; + } else { + list.tail = prev; + } + + node.prev = node.next = null; + + list.length--; + + return node; +}; + +var LinkedList = function () { + function LinkedList(vals) { + var _this = this; + + _classCallCheck(this, LinkedList); + + this.length = 0; + this.head = null; + this.tail = null; + + if (vals != null) { + vals.forEach(function (v) { + return _this.push(v); + }); + } + } + + _createClass(LinkedList, [{ + key: "size", + value: function size() { + return this.length; + } + }, { + key: "insertBefore", + value: function insertBefore(val, otherNode) { + return add(otherNode.prev, nodeFrom(val), otherNode, this); + } + }, { + key: "insertAfter", + value: function insertAfter(val, otherNode) { + return add(otherNode, nodeFrom(val), otherNode.next, this); + } + }, { + key: "insertNodeBefore", + value: function insertNodeBefore(newNode, otherNode) { + return add(otherNode.prev, newNode, otherNode, this); + } + }, { + key: "insertNodeAfter", + value: function insertNodeAfter(newNode, otherNode) { + return add(otherNode, newNode, otherNode.next, this); + } + }, { + key: "push", + value: function push(val) { + return add(this.tail, nodeFrom(val), null, this); + } + }, { + key: "unshift", + value: function unshift(val) { + return add(null, nodeFrom(val), this.head, this); + } + }, { + key: "remove", + value: function remove(node) { + return _remove(node, this); + } + }, { + key: "pop", + value: function pop() { + return _remove(this.tail, this).value; + } + }, { + key: "popNode", + value: function popNode() { + return _remove(this.tail, this); + } + }, { + key: "shift", + value: function shift() { + return _remove(this.head, this).value; + } + }, { + key: "shiftNode", + value: function shiftNode() { + return _remove(this.head, this); + } + }, { + key: "get_object_at", + value: function get_object_at(index) { + if (index <= this.length()) { + var i = 1; + var current = this.head; + while (i < index) { + current = current.next; + i++; + } + return current.value; + } + } + }, { + key: "set_object_at", + value: function set_object_at(index, value) { + if (index <= this.length()) { + var i = 1; + var current = this.head; + while (i < index) { + current = current.next; + i++; + } + current.value = value; + } + } + }]); + + return LinkedList; +}(); + +module.exports = LinkedList; + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/* + *This class is the javascript implementation of the Point.java class in jdk + */ +function Point(x, y, p) { + this.x = null; + this.y = null; + if (x == null && y == null && p == null) { + this.x = 0; + this.y = 0; + } else if (typeof x == 'number' && typeof y == 'number' && p == null) { + this.x = x; + this.y = y; + } else if (x.constructor.name == 'Point' && y == null && p == null) { + p = x; + this.x = p.x; + this.y = p.y; + } +} + +Point.prototype.getX = function () { + return this.x; +}; + +Point.prototype.getY = function () { + return this.y; +}; + +Point.prototype.getLocation = function () { + return new Point(this.x, this.y); +}; + +Point.prototype.setLocation = function (x, y, p) { + if (x.constructor.name == 'Point' && y == null && p == null) { + p = x; + this.setLocation(p.x, p.y); + } else if (typeof x == 'number' && typeof y == 'number' && p == null) { + //if both parameters are integer just move (x,y) location + if (parseInt(x) == x && parseInt(y) == y) { + this.move(x, y); + } else { + this.x = Math.floor(x + 0.5); + this.y = Math.floor(y + 0.5); + } + } +}; + +Point.prototype.move = function (x, y) { + this.x = x; + this.y = y; +}; + +Point.prototype.translate = function (dx, dy) { + this.x += dx; + this.y += dy; +}; + +Point.prototype.equals = function (obj) { + if (obj.constructor.name == "Point") { + var pt = obj; + return this.x == pt.x && this.y == pt.y; + } + return this == obj; +}; + +Point.prototype.toString = function () { + return new Point().constructor.name + "[x=" + this.x + ",y=" + this.y + "]"; +}; + +module.exports = Point; + +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function RectangleD(x, y, width, height) { + this.x = 0; + this.y = 0; + this.width = 0; + this.height = 0; + + if (x != null && y != null && width != null && height != null) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } +} + +RectangleD.prototype.getX = function () { + return this.x; +}; + +RectangleD.prototype.setX = function (x) { + this.x = x; +}; + +RectangleD.prototype.getY = function () { + return this.y; +}; + +RectangleD.prototype.setY = function (y) { + this.y = y; +}; + +RectangleD.prototype.getWidth = function () { + return this.width; +}; + +RectangleD.prototype.setWidth = function (width) { + this.width = width; +}; + +RectangleD.prototype.getHeight = function () { + return this.height; +}; + +RectangleD.prototype.setHeight = function (height) { + this.height = height; +}; + +RectangleD.prototype.getRight = function () { + return this.x + this.width; +}; + +RectangleD.prototype.getBottom = function () { + return this.y + this.height; +}; + +RectangleD.prototype.intersects = function (a) { + if (this.getRight() < a.x) { + return false; + } + + if (this.getBottom() < a.y) { + return false; + } + + if (a.getRight() < this.x) { + return false; + } + + if (a.getBottom() < this.y) { + return false; + } + + return true; +}; + +RectangleD.prototype.getCenterX = function () { + return this.x + this.width / 2; +}; + +RectangleD.prototype.getMinX = function () { + return this.getX(); +}; + +RectangleD.prototype.getMaxX = function () { + return this.getX() + this.width; +}; + +RectangleD.prototype.getCenterY = function () { + return this.y + this.height / 2; +}; + +RectangleD.prototype.getMinY = function () { + return this.getY(); +}; + +RectangleD.prototype.getMaxY = function () { + return this.getY() + this.height; +}; + +RectangleD.prototype.getWidthHalf = function () { + return this.width / 2; +}; + +RectangleD.prototype.getHeightHalf = function () { + return this.height / 2; +}; + +module.exports = RectangleD; + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +function UniqueIDGeneretor() {} + +UniqueIDGeneretor.lastID = 0; + +UniqueIDGeneretor.createID = function (obj) { + if (UniqueIDGeneretor.isPrimitive(obj)) { + return obj; + } + if (obj.uniqueID != null) { + return obj.uniqueID; + } + obj.uniqueID = UniqueIDGeneretor.getString(); + UniqueIDGeneretor.lastID++; + return obj.uniqueID; +}; + +UniqueIDGeneretor.getString = function (id) { + if (id == null) id = UniqueIDGeneretor.lastID; + return "Object#" + id + ""; +}; + +UniqueIDGeneretor.isPrimitive = function (arg) { + var type = typeof arg === "undefined" ? "undefined" : _typeof(arg); + return arg == null || type != "object" && type != "function"; +}; + +module.exports = UniqueIDGeneretor; + +/***/ }), +/* 15 */ +/***/ (function(module, exports, __nested_webpack_require_64072__) { + +"use strict"; + + +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var LayoutConstants = __nested_webpack_require_64072__(0); +var LGraphManager = __nested_webpack_require_64072__(6); +var LNode = __nested_webpack_require_64072__(3); +var LEdge = __nested_webpack_require_64072__(1); +var LGraph = __nested_webpack_require_64072__(5); +var PointD = __nested_webpack_require_64072__(4); +var Transform = __nested_webpack_require_64072__(17); +var Emitter = __nested_webpack_require_64072__(27); + +function Layout(isRemoteUse) { + Emitter.call(this); + + //Layout Quality: 0:draft, 1:default, 2:proof + this.layoutQuality = LayoutConstants.QUALITY; + //Whether layout should create bendpoints as needed or not + this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED; + //Whether layout should be incremental or not + this.incremental = LayoutConstants.DEFAULT_INCREMENTAL; + //Whether we animate from before to after layout node positions + this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT; + //Whether we animate the layout process or not + this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT; + //Number iterations that should be done between two successive animations + this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD; + /** + * Whether or not leaf nodes (non-compound nodes) are of uniform sizes. When + * they are, both spring and repulsion forces between two leaf nodes can be + * calculated without the expensive clipping point calculations, resulting + * in major speed-up. + */ + this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES; + /** + * This is used for creation of bendpoints by using dummy nodes and edges. + * Maps an LEdge to its dummy bendpoint path. + */ + this.edgeToDummyNodes = new Map(); + this.graphManager = new LGraphManager(this); + this.isLayoutFinished = false; + this.isSubLayout = false; + this.isRemoteUse = false; + + if (isRemoteUse != null) { + this.isRemoteUse = isRemoteUse; + } +} + +Layout.RANDOM_SEED = 1; + +Layout.prototype = Object.create(Emitter.prototype); + +Layout.prototype.getGraphManager = function () { + return this.graphManager; +}; + +Layout.prototype.getAllNodes = function () { + return this.graphManager.getAllNodes(); +}; + +Layout.prototype.getAllEdges = function () { + return this.graphManager.getAllEdges(); +}; + +Layout.prototype.getAllNodesToApplyGravitation = function () { + return this.graphManager.getAllNodesToApplyGravitation(); +}; + +Layout.prototype.newGraphManager = function () { + var gm = new LGraphManager(this); + this.graphManager = gm; + return gm; +}; + +Layout.prototype.newGraph = function (vGraph) { + return new LGraph(null, this.graphManager, vGraph); +}; + +Layout.prototype.newNode = function (vNode) { + return new LNode(this.graphManager, vNode); +}; + +Layout.prototype.newEdge = function (vEdge) { + return new LEdge(null, null, vEdge); +}; + +Layout.prototype.checkLayoutSuccess = function () { + return this.graphManager.getRoot() == null || this.graphManager.getRoot().getNodes().length == 0 || this.graphManager.includesInvalidEdge(); +}; + +Layout.prototype.runLayout = function () { + this.isLayoutFinished = false; + + if (this.tilingPreLayout) { + this.tilingPreLayout(); + } + + this.initParameters(); + var isLayoutSuccessfull; + + if (this.checkLayoutSuccess()) { + isLayoutSuccessfull = false; + } else { + isLayoutSuccessfull = this.layout(); + } + + if (LayoutConstants.ANIMATE === 'during') { + // If this is a 'during' layout animation. Layout is not finished yet. + // We need to perform these in index.js when layout is really finished. + return false; + } + + if (isLayoutSuccessfull) { + if (!this.isSubLayout) { + this.doPostLayout(); + } + } + + if (this.tilingPostLayout) { + this.tilingPostLayout(); + } + + this.isLayoutFinished = true; + + return isLayoutSuccessfull; +}; + +/** + * This method performs the operations required after layout. + */ +Layout.prototype.doPostLayout = function () { + //assert !isSubLayout : "Should not be called on sub-layout!"; + // Propagate geometric changes to v-level objects + if (!this.incremental) { + this.transform(); + } + this.update(); +}; + +/** + * This method updates the geometry of the target graph according to + * calculated layout. + */ +Layout.prototype.update2 = function () { + // update bend points + if (this.createBendsAsNeeded) { + this.createBendpointsFromDummyNodes(); + + // reset all edges, since the topology has changed + this.graphManager.resetAllEdges(); + } + + // perform edge, node and root updates if layout is not called + // remotely + if (!this.isRemoteUse) { + // update all edges + var edge; + var allEdges = this.graphManager.getAllEdges(); + for (var i = 0; i < allEdges.length; i++) { + edge = allEdges[i]; + // this.update(edge); + } + + // recursively update nodes + var node; + var nodes = this.graphManager.getRoot().getNodes(); + for (var i = 0; i < nodes.length; i++) { + node = nodes[i]; + // this.update(node); + } + + // update root graph + this.update(this.graphManager.getRoot()); + } +}; + +Layout.prototype.update = function (obj) { + if (obj == null) { + this.update2(); + } else if (obj instanceof LNode) { + var node = obj; + if (node.getChild() != null) { + // since node is compound, recursively update child nodes + var nodes = node.getChild().getNodes(); + for (var i = 0; i < nodes.length; i++) { + update(nodes[i]); + } + } + + // if the l-level node is associated with a v-level graph object, + // then it is assumed that the v-level node implements the + // interface Updatable. + if (node.vGraphObject != null) { + // cast to Updatable without any type check + var vNode = node.vGraphObject; + + // call the update method of the interface + vNode.update(node); + } + } else if (obj instanceof LEdge) { + var edge = obj; + // if the l-level edge is associated with a v-level graph object, + // then it is assumed that the v-level edge implements the + // interface Updatable. + + if (edge.vGraphObject != null) { + // cast to Updatable without any type check + var vEdge = edge.vGraphObject; + + // call the update method of the interface + vEdge.update(edge); + } + } else if (obj instanceof LGraph) { + var graph = obj; + // if the l-level graph is associated with a v-level graph object, + // then it is assumed that the v-level object implements the + // interface Updatable. + + if (graph.vGraphObject != null) { + // cast to Updatable without any type check + var vGraph = graph.vGraphObject; + + // call the update method of the interface + vGraph.update(graph); + } + } +}; + +/** + * This method is used to set all layout parameters to default values + * determined at compile time. + */ +Layout.prototype.initParameters = function () { + if (!this.isSubLayout) { + this.layoutQuality = LayoutConstants.QUALITY; + this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT; + this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD; + this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT; + this.incremental = LayoutConstants.DEFAULT_INCREMENTAL; + this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED; + this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES; + } + + if (this.animationDuringLayout) { + this.animationOnLayout = false; + } +}; + +Layout.prototype.transform = function (newLeftTop) { + if (newLeftTop == undefined) { + this.transform(new PointD(0, 0)); + } else { + // create a transformation object (from Eclipse to layout). When an + // inverse transform is applied, we get upper-left coordinate of the + // drawing or the root graph at given input coordinate (some margins + // already included in calculation of left-top). + + var trans = new Transform(); + var leftTop = this.graphManager.getRoot().updateLeftTop(); + + if (leftTop != null) { + trans.setWorldOrgX(newLeftTop.x); + trans.setWorldOrgY(newLeftTop.y); + + trans.setDeviceOrgX(leftTop.x); + trans.setDeviceOrgY(leftTop.y); + + var nodes = this.getAllNodes(); + var node; + + for (var i = 0; i < nodes.length; i++) { + node = nodes[i]; + node.transform(trans); + } + } + } +}; + +Layout.prototype.positionNodesRandomly = function (graph) { + + if (graph == undefined) { + //assert !this.incremental; + this.positionNodesRandomly(this.getGraphManager().getRoot()); + this.getGraphManager().getRoot().updateBounds(true); + } else { + var lNode; + var childGraph; + + var nodes = graph.getNodes(); + for (var i = 0; i < nodes.length; i++) { + lNode = nodes[i]; + childGraph = lNode.getChild(); + + if (childGraph == null) { + lNode.scatter(); + } else if (childGraph.getNodes().length == 0) { + lNode.scatter(); + } else { + this.positionNodesRandomly(childGraph); + lNode.updateBounds(); + } + } + } +}; + +/** + * This method returns a list of trees where each tree is represented as a + * list of l-nodes. The method returns a list of size 0 when: + * - The graph is not flat or + * - One of the component(s) of the graph is not a tree. + */ +Layout.prototype.getFlatForest = function () { + var flatForest = []; + var isForest = true; + + // Quick reference for all nodes in the graph manager associated with + // this layout. The list should not be changed. + var allNodes = this.graphManager.getRoot().getNodes(); + + // First be sure that the graph is flat + var isFlat = true; + + for (var i = 0; i < allNodes.length; i++) { + if (allNodes[i].getChild() != null) { + isFlat = false; + } + } + + // Return empty forest if the graph is not flat. + if (!isFlat) { + return flatForest; + } + + // Run BFS for each component of the graph. + + var visited = new Set(); + var toBeVisited = []; + var parents = new Map(); + var unProcessedNodes = []; + + unProcessedNodes = unProcessedNodes.concat(allNodes); + + // Each iteration of this loop finds a component of the graph and + // decides whether it is a tree or not. If it is a tree, adds it to the + // forest and continued with the next component. + + while (unProcessedNodes.length > 0 && isForest) { + toBeVisited.push(unProcessedNodes[0]); + + // Start the BFS. Each iteration of this loop visits a node in a + // BFS manner. + while (toBeVisited.length > 0 && isForest) { + //pool operation + var currentNode = toBeVisited[0]; + toBeVisited.splice(0, 1); + visited.add(currentNode); + + // Traverse all neighbors of this node + var neighborEdges = currentNode.getEdges(); + + for (var i = 0; i < neighborEdges.length; i++) { + var currentNeighbor = neighborEdges[i].getOtherEnd(currentNode); + + // If BFS is not growing from this neighbor. + if (parents.get(currentNode) != currentNeighbor) { + // We haven't previously visited this neighbor. + if (!visited.has(currentNeighbor)) { + toBeVisited.push(currentNeighbor); + parents.set(currentNeighbor, currentNode); + } + // Since we have previously visited this neighbor and + // this neighbor is not parent of currentNode, given + // graph contains a component that is not tree, hence + // it is not a forest. + else { + isForest = false; + break; + } + } + } + } + + // The graph contains a component that is not a tree. Empty + // previously found trees. The method will end. + if (!isForest) { + flatForest = []; + } + // Save currently visited nodes as a tree in our forest. Reset + // visited and parents lists. Continue with the next component of + // the graph, if any. + else { + var temp = [].concat(_toConsumableArray(visited)); + flatForest.push(temp); + //flatForest = flatForest.concat(temp); + //unProcessedNodes.removeAll(visited); + for (var i = 0; i < temp.length; i++) { + var value = temp[i]; + var index = unProcessedNodes.indexOf(value); + if (index > -1) { + unProcessedNodes.splice(index, 1); + } + } + visited = new Set(); + parents = new Map(); + } + } + + return flatForest; +}; + +/** + * This method creates dummy nodes (an l-level node with minimal dimensions) + * for the given edge (one per bendpoint). The existing l-level structure + * is updated accordingly. + */ +Layout.prototype.createDummyNodesForBendpoints = function (edge) { + var dummyNodes = []; + var prev = edge.source; + + var graph = this.graphManager.calcLowestCommonAncestor(edge.source, edge.target); + + for (var i = 0; i < edge.bendpoints.length; i++) { + // create new dummy node + var dummyNode = this.newNode(null); + dummyNode.setRect(new Point(0, 0), new Dimension(1, 1)); + + graph.add(dummyNode); + + // create new dummy edge between prev and dummy node + var dummyEdge = this.newEdge(null); + this.graphManager.add(dummyEdge, prev, dummyNode); + + dummyNodes.add(dummyNode); + prev = dummyNode; + } + + var dummyEdge = this.newEdge(null); + this.graphManager.add(dummyEdge, prev, edge.target); + + this.edgeToDummyNodes.set(edge, dummyNodes); + + // remove real edge from graph manager if it is inter-graph + if (edge.isInterGraph()) { + this.graphManager.remove(edge); + } + // else, remove the edge from the current graph + else { + graph.remove(edge); + } + + return dummyNodes; +}; + +/** + * This method creates bendpoints for edges from the dummy nodes + * at l-level. + */ +Layout.prototype.createBendpointsFromDummyNodes = function () { + var edges = []; + edges = edges.concat(this.graphManager.getAllEdges()); + edges = [].concat(_toConsumableArray(this.edgeToDummyNodes.keys())).concat(edges); + + for (var k = 0; k < edges.length; k++) { + var lEdge = edges[k]; + + if (lEdge.bendpoints.length > 0) { + var path = this.edgeToDummyNodes.get(lEdge); + + for (var i = 0; i < path.length; i++) { + var dummyNode = path[i]; + var p = new PointD(dummyNode.getCenterX(), dummyNode.getCenterY()); + + // update bendpoint's location according to dummy node + var ebp = lEdge.bendpoints.get(i); + ebp.x = p.x; + ebp.y = p.y; + + // remove the dummy node, dummy edges incident with this + // dummy node is also removed (within the remove method) + dummyNode.getOwner().remove(dummyNode); + } + + // add the real edge to graph + this.graphManager.add(lEdge, lEdge.source, lEdge.target); + } + } +}; + +Layout.transform = function (sliderValue, defaultValue, minDiv, maxMul) { + if (minDiv != undefined && maxMul != undefined) { + var value = defaultValue; + + if (sliderValue <= 50) { + var minValue = defaultValue / minDiv; + value -= (defaultValue - minValue) / 50 * (50 - sliderValue); + } else { + var maxValue = defaultValue * maxMul; + value += (maxValue - defaultValue) / 50 * (sliderValue - 50); + } + + return value; + } else { + var a, b; + + if (sliderValue <= 50) { + a = 9.0 * defaultValue / 500.0; + b = defaultValue / 10.0; + } else { + a = 9.0 * defaultValue / 50.0; + b = -8 * defaultValue; + } + + return a * sliderValue + b; + } +}; + +/** + * This method finds and returns the center of the given nodes, assuming + * that the given nodes form a tree in themselves. + */ +Layout.findCenterOfTree = function (nodes) { + var list = []; + list = list.concat(nodes); + + var removedNodes = []; + var remainingDegrees = new Map(); + var foundCenter = false; + var centerNode = null; + + if (list.length == 1 || list.length == 2) { + foundCenter = true; + centerNode = list[0]; + } + + for (var i = 0; i < list.length; i++) { + var node = list[i]; + var degree = node.getNeighborsList().size; + remainingDegrees.set(node, node.getNeighborsList().size); + + if (degree == 1) { + removedNodes.push(node); + } + } + + var tempList = []; + tempList = tempList.concat(removedNodes); + + while (!foundCenter) { + var tempList2 = []; + tempList2 = tempList2.concat(tempList); + tempList = []; + + for (var i = 0; i < list.length; i++) { + var node = list[i]; + + var index = list.indexOf(node); + if (index >= 0) { + list.splice(index, 1); + } + + var neighbours = node.getNeighborsList(); + + neighbours.forEach(function (neighbour) { + if (removedNodes.indexOf(neighbour) < 0) { + var otherDegree = remainingDegrees.get(neighbour); + var newDegree = otherDegree - 1; + + if (newDegree == 1) { + tempList.push(neighbour); + } + + remainingDegrees.set(neighbour, newDegree); + } + }); + } + + removedNodes = removedNodes.concat(tempList); + + if (list.length == 1 || list.length == 2) { + foundCenter = true; + centerNode = list[0]; + } + } + + return centerNode; +}; + +/** + * During the coarsening process, this layout may be referenced by two graph managers + * this setter function grants access to change the currently being used graph manager + */ +Layout.prototype.setGraphManager = function (gm) { + this.graphManager = gm; +}; + +module.exports = Layout; + +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function RandomSeed() {} +// adapted from: https://stackoverflow.com/a/19303725 +RandomSeed.seed = 1; +RandomSeed.x = 0; + +RandomSeed.nextDouble = function () { + RandomSeed.x = Math.sin(RandomSeed.seed++) * 10000; + return RandomSeed.x - Math.floor(RandomSeed.x); +}; + +module.exports = RandomSeed; + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __nested_webpack_require_81860__) { + +"use strict"; + + +var PointD = __nested_webpack_require_81860__(4); + +function Transform(x, y) { + this.lworldOrgX = 0.0; + this.lworldOrgY = 0.0; + this.ldeviceOrgX = 0.0; + this.ldeviceOrgY = 0.0; + this.lworldExtX = 1.0; + this.lworldExtY = 1.0; + this.ldeviceExtX = 1.0; + this.ldeviceExtY = 1.0; +} + +Transform.prototype.getWorldOrgX = function () { + return this.lworldOrgX; +}; + +Transform.prototype.setWorldOrgX = function (wox) { + this.lworldOrgX = wox; +}; + +Transform.prototype.getWorldOrgY = function () { + return this.lworldOrgY; +}; + +Transform.prototype.setWorldOrgY = function (woy) { + this.lworldOrgY = woy; +}; + +Transform.prototype.getWorldExtX = function () { + return this.lworldExtX; +}; + +Transform.prototype.setWorldExtX = function (wex) { + this.lworldExtX = wex; +}; + +Transform.prototype.getWorldExtY = function () { + return this.lworldExtY; +}; + +Transform.prototype.setWorldExtY = function (wey) { + this.lworldExtY = wey; +}; + +/* Device related */ + +Transform.prototype.getDeviceOrgX = function () { + return this.ldeviceOrgX; +}; + +Transform.prototype.setDeviceOrgX = function (dox) { + this.ldeviceOrgX = dox; +}; + +Transform.prototype.getDeviceOrgY = function () { + return this.ldeviceOrgY; +}; + +Transform.prototype.setDeviceOrgY = function (doy) { + this.ldeviceOrgY = doy; +}; + +Transform.prototype.getDeviceExtX = function () { + return this.ldeviceExtX; +}; + +Transform.prototype.setDeviceExtX = function (dex) { + this.ldeviceExtX = dex; +}; + +Transform.prototype.getDeviceExtY = function () { + return this.ldeviceExtY; +}; + +Transform.prototype.setDeviceExtY = function (dey) { + this.ldeviceExtY = dey; +}; + +Transform.prototype.transformX = function (x) { + var xDevice = 0.0; + var worldExtX = this.lworldExtX; + if (worldExtX != 0.0) { + xDevice = this.ldeviceOrgX + (x - this.lworldOrgX) * this.ldeviceExtX / worldExtX; + } + + return xDevice; +}; + +Transform.prototype.transformY = function (y) { + var yDevice = 0.0; + var worldExtY = this.lworldExtY; + if (worldExtY != 0.0) { + yDevice = this.ldeviceOrgY + (y - this.lworldOrgY) * this.ldeviceExtY / worldExtY; + } + + return yDevice; +}; + +Transform.prototype.inverseTransformX = function (x) { + var xWorld = 0.0; + var deviceExtX = this.ldeviceExtX; + if (deviceExtX != 0.0) { + xWorld = this.lworldOrgX + (x - this.ldeviceOrgX) * this.lworldExtX / deviceExtX; + } + + return xWorld; +}; + +Transform.prototype.inverseTransformY = function (y) { + var yWorld = 0.0; + var deviceExtY = this.ldeviceExtY; + if (deviceExtY != 0.0) { + yWorld = this.lworldOrgY + (y - this.ldeviceOrgY) * this.lworldExtY / deviceExtY; + } + return yWorld; +}; + +Transform.prototype.inverseTransformPoint = function (inPoint) { + var outPoint = new PointD(this.inverseTransformX(inPoint.x), this.inverseTransformY(inPoint.y)); + return outPoint; +}; + +module.exports = Transform; + +/***/ }), +/* 18 */ +/***/ (function(module, exports, __nested_webpack_require_84747__) { + +"use strict"; + + +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var Layout = __nested_webpack_require_84747__(15); +var FDLayoutConstants = __nested_webpack_require_84747__(7); +var LayoutConstants = __nested_webpack_require_84747__(0); +var IGeometry = __nested_webpack_require_84747__(8); +var IMath = __nested_webpack_require_84747__(9); + +function FDLayout() { + Layout.call(this); + + this.useSmartIdealEdgeLengthCalculation = FDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION; + this.idealEdgeLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH; + this.springConstant = FDLayoutConstants.DEFAULT_SPRING_STRENGTH; + this.repulsionConstant = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH; + this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH; + this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH; + this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR; + this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR; + this.displacementThresholdPerNode = 3.0 * FDLayoutConstants.DEFAULT_EDGE_LENGTH / 100; + this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL; + this.initialCoolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL; + this.totalDisplacement = 0.0; + this.oldTotalDisplacement = 0.0; + this.maxIterations = FDLayoutConstants.MAX_ITERATIONS; +} + +FDLayout.prototype = Object.create(Layout.prototype); + +for (var prop in Layout) { + FDLayout[prop] = Layout[prop]; +} + +FDLayout.prototype.initParameters = function () { + Layout.prototype.initParameters.call(this, arguments); + + this.totalIterations = 0; + this.notAnimatedIterations = 0; + + this.useFRGridVariant = FDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION; + + this.grid = []; +}; + +FDLayout.prototype.calcIdealEdgeLengths = function () { + var edge; + var lcaDepth; + var source; + var target; + var sizeOfSourceInLca; + var sizeOfTargetInLca; + + var allEdges = this.getGraphManager().getAllEdges(); + for (var i = 0; i < allEdges.length; i++) { + edge = allEdges[i]; + + edge.idealLength = this.idealEdgeLength; + + if (edge.isInterGraph) { + source = edge.getSource(); + target = edge.getTarget(); + + sizeOfSourceInLca = edge.getSourceInLca().getEstimatedSize(); + sizeOfTargetInLca = edge.getTargetInLca().getEstimatedSize(); + + if (this.useSmartIdealEdgeLengthCalculation) { + edge.idealLength += sizeOfSourceInLca + sizeOfTargetInLca - 2 * LayoutConstants.SIMPLE_NODE_SIZE; + } + + lcaDepth = edge.getLca().getInclusionTreeDepth(); + + edge.idealLength += FDLayoutConstants.DEFAULT_EDGE_LENGTH * FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR * (source.getInclusionTreeDepth() + target.getInclusionTreeDepth() - 2 * lcaDepth); + } + } +}; + +FDLayout.prototype.initSpringEmbedder = function () { + + var s = this.getAllNodes().length; + if (this.incremental) { + if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) { + this.coolingFactor = Math.max(this.coolingFactor * FDLayoutConstants.COOLING_ADAPTATION_FACTOR, this.coolingFactor - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * this.coolingFactor * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR)); + } + this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL; + } else { + if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) { + this.coolingFactor = Math.max(FDLayoutConstants.COOLING_ADAPTATION_FACTOR, 1.0 - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR)); + } else { + this.coolingFactor = 1.0; + } + this.initialCoolingFactor = this.coolingFactor; + this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT; + } + + this.maxIterations = Math.max(this.getAllNodes().length * 5, this.maxIterations); + + this.totalDisplacementThreshold = this.displacementThresholdPerNode * this.getAllNodes().length; + + this.repulsionRange = this.calcRepulsionRange(); +}; + +FDLayout.prototype.calcSpringForces = function () { + var lEdges = this.getAllEdges(); + var edge; + + for (var i = 0; i < lEdges.length; i++) { + edge = lEdges[i]; + + this.calcSpringForce(edge, edge.idealLength); + } +}; + +FDLayout.prototype.calcRepulsionForces = function () { + var gridUpdateAllowed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + var forceToNodeSurroundingUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var i, j; + var nodeA, nodeB; + var lNodes = this.getAllNodes(); + var processedNodeSet; + + if (this.useFRGridVariant) { + if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed) { + this.updateGrid(); + } + + processedNodeSet = new Set(); + + // calculate repulsion forces between each nodes and its surrounding + for (i = 0; i < lNodes.length; i++) { + nodeA = lNodes[i]; + this.calculateRepulsionForceOfANode(nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate); + processedNodeSet.add(nodeA); + } + } else { + for (i = 0; i < lNodes.length; i++) { + nodeA = lNodes[i]; + + for (j = i + 1; j < lNodes.length; j++) { + nodeB = lNodes[j]; + + // If both nodes are not members of the same graph, skip. + if (nodeA.getOwner() != nodeB.getOwner()) { + continue; + } + + this.calcRepulsionForce(nodeA, nodeB); + } + } + } +}; + +FDLayout.prototype.calcGravitationalForces = function () { + var node; + var lNodes = this.getAllNodesToApplyGravitation(); + + for (var i = 0; i < lNodes.length; i++) { + node = lNodes[i]; + this.calcGravitationalForce(node); + } +}; + +FDLayout.prototype.moveNodes = function () { + var lNodes = this.getAllNodes(); + var node; + + for (var i = 0; i < lNodes.length; i++) { + node = lNodes[i]; + node.move(); + } +}; + +FDLayout.prototype.calcSpringForce = function (edge, idealLength) { + var sourceNode = edge.getSource(); + var targetNode = edge.getTarget(); + + var length; + var springForce; + var springForceX; + var springForceY; + + // Update edge length + if (this.uniformLeafNodeSizes && sourceNode.getChild() == null && targetNode.getChild() == null) { + edge.updateLengthSimple(); + } else { + edge.updateLength(); + + if (edge.isOverlapingSourceAndTarget) { + return; + } + } + + length = edge.getLength(); + + if (length == 0) return; + + // Calculate spring forces + springForce = this.springConstant * (length - idealLength); + + // Project force onto x and y axes + springForceX = springForce * (edge.lengthX / length); + springForceY = springForce * (edge.lengthY / length); + + // Apply forces on the end nodes + sourceNode.springForceX += springForceX; + sourceNode.springForceY += springForceY; + targetNode.springForceX -= springForceX; + targetNode.springForceY -= springForceY; +}; + +FDLayout.prototype.calcRepulsionForce = function (nodeA, nodeB) { + var rectA = nodeA.getRect(); + var rectB = nodeB.getRect(); + var overlapAmount = new Array(2); + var clipPoints = new Array(4); + var distanceX; + var distanceY; + var distanceSquared; + var distance; + var repulsionForce; + var repulsionForceX; + var repulsionForceY; + + if (rectA.intersects(rectB)) // two nodes overlap + { + // calculate separation amount in x and y directions + IGeometry.calcSeparationAmount(rectA, rectB, overlapAmount, FDLayoutConstants.DEFAULT_EDGE_LENGTH / 2.0); + + repulsionForceX = 2 * overlapAmount[0]; + repulsionForceY = 2 * overlapAmount[1]; + + var childrenConstant = nodeA.noOfChildren * nodeB.noOfChildren / (nodeA.noOfChildren + nodeB.noOfChildren); + + // Apply forces on the two nodes + nodeA.repulsionForceX -= childrenConstant * repulsionForceX; + nodeA.repulsionForceY -= childrenConstant * repulsionForceY; + nodeB.repulsionForceX += childrenConstant * repulsionForceX; + nodeB.repulsionForceY += childrenConstant * repulsionForceY; + } else // no overlap + { + // calculate distance + + if (this.uniformLeafNodeSizes && nodeA.getChild() == null && nodeB.getChild() == null) // simply base repulsion on distance of node centers + { + distanceX = rectB.getCenterX() - rectA.getCenterX(); + distanceY = rectB.getCenterY() - rectA.getCenterY(); + } else // use clipping points + { + IGeometry.getIntersection(rectA, rectB, clipPoints); + + distanceX = clipPoints[2] - clipPoints[0]; + distanceY = clipPoints[3] - clipPoints[1]; + } + + // No repulsion range. FR grid variant should take care of this. + if (Math.abs(distanceX) < FDLayoutConstants.MIN_REPULSION_DIST) { + distanceX = IMath.sign(distanceX) * FDLayoutConstants.MIN_REPULSION_DIST; + } + + if (Math.abs(distanceY) < FDLayoutConstants.MIN_REPULSION_DIST) { + distanceY = IMath.sign(distanceY) * FDLayoutConstants.MIN_REPULSION_DIST; + } + + distanceSquared = distanceX * distanceX + distanceY * distanceY; + distance = Math.sqrt(distanceSquared); + + repulsionForce = this.repulsionConstant * nodeA.noOfChildren * nodeB.noOfChildren / distanceSquared; + + // Project force onto x and y axes + repulsionForceX = repulsionForce * distanceX / distance; + repulsionForceY = repulsionForce * distanceY / distance; + + // Apply forces on the two nodes + nodeA.repulsionForceX -= repulsionForceX; + nodeA.repulsionForceY -= repulsionForceY; + nodeB.repulsionForceX += repulsionForceX; + nodeB.repulsionForceY += repulsionForceY; + } +}; + +FDLayout.prototype.calcGravitationalForce = function (node) { + var ownerGraph; + var ownerCenterX; + var ownerCenterY; + var distanceX; + var distanceY; + var absDistanceX; + var absDistanceY; + var estimatedSize; + ownerGraph = node.getOwner(); + + ownerCenterX = (ownerGraph.getRight() + ownerGraph.getLeft()) / 2; + ownerCenterY = (ownerGraph.getTop() + ownerGraph.getBottom()) / 2; + distanceX = node.getCenterX() - ownerCenterX; + distanceY = node.getCenterY() - ownerCenterY; + absDistanceX = Math.abs(distanceX) + node.getWidth() / 2; + absDistanceY = Math.abs(distanceY) + node.getHeight() / 2; + + if (node.getOwner() == this.graphManager.getRoot()) // in the root graph + { + estimatedSize = ownerGraph.getEstimatedSize() * this.gravityRangeFactor; + + if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) { + node.gravitationForceX = -this.gravityConstant * distanceX; + node.gravitationForceY = -this.gravityConstant * distanceY; + } + } else // inside a compound + { + estimatedSize = ownerGraph.getEstimatedSize() * this.compoundGravityRangeFactor; + + if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) { + node.gravitationForceX = -this.gravityConstant * distanceX * this.compoundGravityConstant; + node.gravitationForceY = -this.gravityConstant * distanceY * this.compoundGravityConstant; + } + } +}; + +FDLayout.prototype.isConverged = function () { + var converged; + var oscilating = false; + + if (this.totalIterations > this.maxIterations / 3) { + oscilating = Math.abs(this.totalDisplacement - this.oldTotalDisplacement) < 2; + } + + converged = this.totalDisplacement < this.totalDisplacementThreshold; + + this.oldTotalDisplacement = this.totalDisplacement; + + return converged || oscilating; +}; + +FDLayout.prototype.animate = function () { + if (this.animationDuringLayout && !this.isSubLayout) { + if (this.notAnimatedIterations == this.animationPeriod) { + this.update(); + this.notAnimatedIterations = 0; + } else { + this.notAnimatedIterations++; + } + } +}; + +//This method calculates the number of children (weight) for all nodes +FDLayout.prototype.calcNoOfChildrenForAllNodes = function () { + var node; + var allNodes = this.graphManager.getAllNodes(); + + for (var i = 0; i < allNodes.length; i++) { + node = allNodes[i]; + node.noOfChildren = node.getNoOfChildren(); + } +}; + +// ----------------------------------------------------------------------------- +// Section: FR-Grid Variant Repulsion Force Calculation +// ----------------------------------------------------------------------------- + +FDLayout.prototype.calcGrid = function (graph) { + + var sizeX = 0; + var sizeY = 0; + + sizeX = parseInt(Math.ceil((graph.getRight() - graph.getLeft()) / this.repulsionRange)); + sizeY = parseInt(Math.ceil((graph.getBottom() - graph.getTop()) / this.repulsionRange)); + + var grid = new Array(sizeX); + + for (var i = 0; i < sizeX; i++) { + grid[i] = new Array(sizeY); + } + + for (var i = 0; i < sizeX; i++) { + for (var j = 0; j < sizeY; j++) { + grid[i][j] = new Array(); + } + } + + return grid; +}; + +FDLayout.prototype.addNodeToGrid = function (v, left, top) { + + var startX = 0; + var finishX = 0; + var startY = 0; + var finishY = 0; + + startX = parseInt(Math.floor((v.getRect().x - left) / this.repulsionRange)); + finishX = parseInt(Math.floor((v.getRect().width + v.getRect().x - left) / this.repulsionRange)); + startY = parseInt(Math.floor((v.getRect().y - top) / this.repulsionRange)); + finishY = parseInt(Math.floor((v.getRect().height + v.getRect().y - top) / this.repulsionRange)); + + for (var i = startX; i <= finishX; i++) { + for (var j = startY; j <= finishY; j++) { + this.grid[i][j].push(v); + v.setGridCoordinates(startX, finishX, startY, finishY); + } + } +}; + +FDLayout.prototype.updateGrid = function () { + var i; + var nodeA; + var lNodes = this.getAllNodes(); + + this.grid = this.calcGrid(this.graphManager.getRoot()); + + // put all nodes to proper grid cells + for (i = 0; i < lNodes.length; i++) { + nodeA = lNodes[i]; + this.addNodeToGrid(nodeA, this.graphManager.getRoot().getLeft(), this.graphManager.getRoot().getTop()); + } +}; + +FDLayout.prototype.calculateRepulsionForceOfANode = function (nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate) { + + if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed || forceToNodeSurroundingUpdate) { + var surrounding = new Set(); + nodeA.surrounding = new Array(); + var nodeB; + var grid = this.grid; + + for (var i = nodeA.startX - 1; i < nodeA.finishX + 2; i++) { + for (var j = nodeA.startY - 1; j < nodeA.finishY + 2; j++) { + if (!(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length)) { + for (var k = 0; k < grid[i][j].length; k++) { + nodeB = grid[i][j][k]; + + // If both nodes are not members of the same graph, + // or both nodes are the same, skip. + if (nodeA.getOwner() != nodeB.getOwner() || nodeA == nodeB) { + continue; + } + + // check if the repulsion force between + // nodeA and nodeB has already been calculated + if (!processedNodeSet.has(nodeB) && !surrounding.has(nodeB)) { + var distanceX = Math.abs(nodeA.getCenterX() - nodeB.getCenterX()) - (nodeA.getWidth() / 2 + nodeB.getWidth() / 2); + var distanceY = Math.abs(nodeA.getCenterY() - nodeB.getCenterY()) - (nodeA.getHeight() / 2 + nodeB.getHeight() / 2); + + // if the distance between nodeA and nodeB + // is less then calculation range + if (distanceX <= this.repulsionRange && distanceY <= this.repulsionRange) { + //then add nodeB to surrounding of nodeA + surrounding.add(nodeB); + } + } + } + } + } + } + + nodeA.surrounding = [].concat(_toConsumableArray(surrounding)); + } + for (i = 0; i < nodeA.surrounding.length; i++) { + this.calcRepulsionForce(nodeA, nodeA.surrounding[i]); + } +}; + +FDLayout.prototype.calcRepulsionRange = function () { + return 0.0; +}; + +module.exports = FDLayout; + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __nested_webpack_require_100902__) { + +"use strict"; + + +var LEdge = __nested_webpack_require_100902__(1); +var FDLayoutConstants = __nested_webpack_require_100902__(7); + +function FDLayoutEdge(source, target, vEdge) { + LEdge.call(this, source, target, vEdge); + this.idealLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH; +} + +FDLayoutEdge.prototype = Object.create(LEdge.prototype); + +for (var prop in LEdge) { + FDLayoutEdge[prop] = LEdge[prop]; +} + +module.exports = FDLayoutEdge; + +/***/ }), +/* 20 */ +/***/ (function(module, exports, __nested_webpack_require_101387__) { + +"use strict"; + + +var LNode = __nested_webpack_require_101387__(3); + +function FDLayoutNode(gm, loc, size, vNode) { + // alternative constructor is handled inside LNode + LNode.call(this, gm, loc, size, vNode); + //Spring, repulsion and gravitational forces acting on this node + this.springForceX = 0; + this.springForceY = 0; + this.repulsionForceX = 0; + this.repulsionForceY = 0; + this.gravitationForceX = 0; + this.gravitationForceY = 0; + //Amount by which this node is to be moved in this iteration + this.displacementX = 0; + this.displacementY = 0; + + //Start and finish grid coordinates that this node is fallen into + this.startX = 0; + this.finishX = 0; + this.startY = 0; + this.finishY = 0; + + //Geometric neighbors of this node + this.surrounding = []; +} + +FDLayoutNode.prototype = Object.create(LNode.prototype); + +for (var prop in LNode) { + FDLayoutNode[prop] = LNode[prop]; +} + +FDLayoutNode.prototype.setGridCoordinates = function (_startX, _finishX, _startY, _finishY) { + this.startX = _startX; + this.finishX = _finishX; + this.startY = _startY; + this.finishY = _finishY; +}; + +module.exports = FDLayoutNode; + +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function DimensionD(width, height) { + this.width = 0; + this.height = 0; + if (width !== null && height !== null) { + this.height = height; + this.width = width; + } +} + +DimensionD.prototype.getWidth = function () { + return this.width; +}; + +DimensionD.prototype.setWidth = function (width) { + this.width = width; +}; + +DimensionD.prototype.getHeight = function () { + return this.height; +}; + +DimensionD.prototype.setHeight = function (height) { + this.height = height; +}; + +module.exports = DimensionD; + +/***/ }), +/* 22 */ +/***/ (function(module, exports, __nested_webpack_require_103173__) { + +"use strict"; + + +var UniqueIDGeneretor = __nested_webpack_require_103173__(14); + +function HashMap() { + this.map = {}; + this.keys = []; +} + +HashMap.prototype.put = function (key, value) { + var theId = UniqueIDGeneretor.createID(key); + if (!this.contains(theId)) { + this.map[theId] = value; + this.keys.push(key); + } +}; + +HashMap.prototype.contains = function (key) { + var theId = UniqueIDGeneretor.createID(key); + return this.map[key] != null; +}; + +HashMap.prototype.get = function (key) { + var theId = UniqueIDGeneretor.createID(key); + return this.map[theId]; +}; + +HashMap.prototype.keySet = function () { + return this.keys; +}; + +module.exports = HashMap; + +/***/ }), +/* 23 */ +/***/ (function(module, exports, __nested_webpack_require_103901__) { + +"use strict"; + + +var UniqueIDGeneretor = __nested_webpack_require_103901__(14); + +function HashSet() { + this.set = {}; +} +; + +HashSet.prototype.add = function (obj) { + var theId = UniqueIDGeneretor.createID(obj); + if (!this.contains(theId)) this.set[theId] = obj; +}; + +HashSet.prototype.remove = function (obj) { + delete this.set[UniqueIDGeneretor.createID(obj)]; +}; + +HashSet.prototype.clear = function () { + this.set = {}; +}; + +HashSet.prototype.contains = function (obj) { + return this.set[UniqueIDGeneretor.createID(obj)] == obj; +}; + +HashSet.prototype.isEmpty = function () { + return this.size() === 0; +}; + +HashSet.prototype.size = function () { + return Object.keys(this.set).length; +}; + +//concats this.set to the given list +HashSet.prototype.addAllTo = function (list) { + var keys = Object.keys(this.set); + var length = keys.length; + for (var i = 0; i < length; i++) { + list.push(this.set[keys[i]]); + } +}; + +HashSet.prototype.size = function () { + return Object.keys(this.set).length; +}; + +HashSet.prototype.addAll = function (list) { + var s = list.length; + for (var i = 0; i < s; i++) { + var v = list[i]; + this.add(v); + } +}; + +module.exports = HashSet; + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __nested_webpack_require_105138__) { + +"use strict"; + + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * A classic Quicksort algorithm with Hoare's partition + * - Works also on LinkedList objects + * + * Copyright: i-Vis Research Group, Bilkent University, 2007 - present + */ + +var LinkedList = __nested_webpack_require_105138__(11); + +var Quicksort = function () { + function Quicksort(A, compareFunction) { + _classCallCheck(this, Quicksort); + + if (compareFunction !== null || compareFunction !== undefined) this.compareFunction = this._defaultCompareFunction; + + var length = void 0; + if (A instanceof LinkedList) length = A.size();else length = A.length; + + this._quicksort(A, 0, length - 1); + } + + _createClass(Quicksort, [{ + key: '_quicksort', + value: function _quicksort(A, p, r) { + if (p < r) { + var q = this._partition(A, p, r); + this._quicksort(A, p, q); + this._quicksort(A, q + 1, r); + } + } + }, { + key: '_partition', + value: function _partition(A, p, r) { + var x = this._get(A, p); + var i = p; + var j = r; + while (true) { + while (this.compareFunction(x, this._get(A, j))) { + j--; + }while (this.compareFunction(this._get(A, i), x)) { + i++; + }if (i < j) { + this._swap(A, i, j); + i++; + j--; + } else return j; + } + } + }, { + key: '_get', + value: function _get(object, index) { + if (object instanceof LinkedList) return object.get_object_at(index);else return object[index]; + } + }, { + key: '_set', + value: function _set(object, index, value) { + if (object instanceof LinkedList) object.set_object_at(index, value);else object[index] = value; + } + }, { + key: '_swap', + value: function _swap(A, i, j) { + var temp = this._get(A, i); + this._set(A, i, this._get(A, j)); + this._set(A, j, temp); + } + }, { + key: '_defaultCompareFunction', + value: function _defaultCompareFunction(a, b) { + return b > a; + } + }]); + + return Quicksort; +}(); + +module.exports = Quicksort; + +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Needleman-Wunsch algorithm is an procedure to compute the optimal global alignment of two string + * sequences by S.B.Needleman and C.D.Wunsch (1970). + * + * Aside from the inputs, you can assign the scores for, + * - Match: The two characters at the current index are same. + * - Mismatch: The two characters at the current index are different. + * - Insertion/Deletion(gaps): The best alignment involves one letter aligning to a gap in the other string. + */ + +var NeedlemanWunsch = function () { + function NeedlemanWunsch(sequence1, sequence2) { + var match_score = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + var mismatch_penalty = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : -1; + var gap_penalty = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1; + + _classCallCheck(this, NeedlemanWunsch); + + this.sequence1 = sequence1; + this.sequence2 = sequence2; + this.match_score = match_score; + this.mismatch_penalty = mismatch_penalty; + this.gap_penalty = gap_penalty; + + // Just the remove redundancy + this.iMax = sequence1.length + 1; + this.jMax = sequence2.length + 1; + + // Grid matrix of scores + this.grid = new Array(this.iMax); + for (var i = 0; i < this.iMax; i++) { + this.grid[i] = new Array(this.jMax); + + for (var j = 0; j < this.jMax; j++) { + this.grid[i][j] = 0; + } + } + + // Traceback matrix (2D array, each cell is an array of boolean values for [`Diag`, `Up`, `Left`] positions) + this.tracebackGrid = new Array(this.iMax); + for (var _i = 0; _i < this.iMax; _i++) { + this.tracebackGrid[_i] = new Array(this.jMax); + + for (var _j = 0; _j < this.jMax; _j++) { + this.tracebackGrid[_i][_j] = [null, null, null]; + } + } + + // The aligned sequences (return multiple possibilities) + this.alignments = []; + + // Final alignment score + this.score = -1; + + // Calculate scores and tracebacks + this.computeGrids(); + } + + _createClass(NeedlemanWunsch, [{ + key: "getScore", + value: function getScore() { + return this.score; + } + }, { + key: "getAlignments", + value: function getAlignments() { + return this.alignments; + } + + // Main dynamic programming procedure + + }, { + key: "computeGrids", + value: function computeGrids() { + // Fill in the first row + for (var j = 1; j < this.jMax; j++) { + this.grid[0][j] = this.grid[0][j - 1] + this.gap_penalty; + this.tracebackGrid[0][j] = [false, false, true]; + } + + // Fill in the first column + for (var i = 1; i < this.iMax; i++) { + this.grid[i][0] = this.grid[i - 1][0] + this.gap_penalty; + this.tracebackGrid[i][0] = [false, true, false]; + } + + // Fill the rest of the grid + for (var _i2 = 1; _i2 < this.iMax; _i2++) { + for (var _j2 = 1; _j2 < this.jMax; _j2++) { + // Find the max score(s) among [`Diag`, `Up`, `Left`] + var diag = void 0; + if (this.sequence1[_i2 - 1] === this.sequence2[_j2 - 1]) diag = this.grid[_i2 - 1][_j2 - 1] + this.match_score;else diag = this.grid[_i2 - 1][_j2 - 1] + this.mismatch_penalty; + + var up = this.grid[_i2 - 1][_j2] + this.gap_penalty; + var left = this.grid[_i2][_j2 - 1] + this.gap_penalty; + + // If there exists multiple max values, capture them for multiple paths + var maxOf = [diag, up, left]; + var indices = this.arrayAllMaxIndexes(maxOf); + + // Update Grids + this.grid[_i2][_j2] = maxOf[indices[0]]; + this.tracebackGrid[_i2][_j2] = [indices.includes(0), indices.includes(1), indices.includes(2)]; + } + } + + // Update alignment score + this.score = this.grid[this.iMax - 1][this.jMax - 1]; + } + + // Gets all possible valid sequence combinations + + }, { + key: "alignmentTraceback", + value: function alignmentTraceback() { + var inProcessAlignments = []; + + inProcessAlignments.push({ pos: [this.sequence1.length, this.sequence2.length], + seq1: "", + seq2: "" + }); + + while (inProcessAlignments[0]) { + var current = inProcessAlignments[0]; + var directions = this.tracebackGrid[current.pos[0]][current.pos[1]]; + + if (directions[0]) { + inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1] - 1], + seq1: this.sequence1[current.pos[0] - 1] + current.seq1, + seq2: this.sequence2[current.pos[1] - 1] + current.seq2 + }); + } + if (directions[1]) { + inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1]], + seq1: this.sequence1[current.pos[0] - 1] + current.seq1, + seq2: '-' + current.seq2 + }); + } + if (directions[2]) { + inProcessAlignments.push({ pos: [current.pos[0], current.pos[1] - 1], + seq1: '-' + current.seq1, + seq2: this.sequence2[current.pos[1] - 1] + current.seq2 + }); + } + + if (current.pos[0] === 0 && current.pos[1] === 0) this.alignments.push({ sequence1: current.seq1, + sequence2: current.seq2 + }); + + inProcessAlignments.shift(); + } + + return this.alignments; + } + + // Helper Functions + + }, { + key: "getAllIndexes", + value: function getAllIndexes(arr, val) { + var indexes = [], + i = -1; + while ((i = arr.indexOf(val, i + 1)) !== -1) { + indexes.push(i); + } + return indexes; + } + }, { + key: "arrayAllMaxIndexes", + value: function arrayAllMaxIndexes(array) { + return this.getAllIndexes(array, Math.max.apply(null, array)); + } + }]); + + return NeedlemanWunsch; +}(); + +module.exports = NeedlemanWunsch; + +/***/ }), +/* 26 */ +/***/ (function(module, exports, __nested_webpack_require_115611__) { + +"use strict"; + + +var layoutBase = function layoutBase() { + return; +}; + +layoutBase.FDLayout = __nested_webpack_require_115611__(18); +layoutBase.FDLayoutConstants = __nested_webpack_require_115611__(7); +layoutBase.FDLayoutEdge = __nested_webpack_require_115611__(19); +layoutBase.FDLayoutNode = __nested_webpack_require_115611__(20); +layoutBase.DimensionD = __nested_webpack_require_115611__(21); +layoutBase.HashMap = __nested_webpack_require_115611__(22); +layoutBase.HashSet = __nested_webpack_require_115611__(23); +layoutBase.IGeometry = __nested_webpack_require_115611__(8); +layoutBase.IMath = __nested_webpack_require_115611__(9); +layoutBase.Integer = __nested_webpack_require_115611__(10); +layoutBase.Point = __nested_webpack_require_115611__(12); +layoutBase.PointD = __nested_webpack_require_115611__(4); +layoutBase.RandomSeed = __nested_webpack_require_115611__(16); +layoutBase.RectangleD = __nested_webpack_require_115611__(13); +layoutBase.Transform = __nested_webpack_require_115611__(17); +layoutBase.UniqueIDGeneretor = __nested_webpack_require_115611__(14); +layoutBase.Quicksort = __nested_webpack_require_115611__(24); +layoutBase.LinkedList = __nested_webpack_require_115611__(11); +layoutBase.LGraphObject = __nested_webpack_require_115611__(2); +layoutBase.LGraph = __nested_webpack_require_115611__(5); +layoutBase.LEdge = __nested_webpack_require_115611__(1); +layoutBase.LGraphManager = __nested_webpack_require_115611__(6); +layoutBase.LNode = __nested_webpack_require_115611__(3); +layoutBase.Layout = __nested_webpack_require_115611__(15); +layoutBase.LayoutConstants = __nested_webpack_require_115611__(0); +layoutBase.NeedlemanWunsch = __nested_webpack_require_115611__(25); + +module.exports = layoutBase; + +/***/ }), +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function Emitter() { + this.listeners = []; +} + +var p = Emitter.prototype; + +p.addListener = function (event, callback) { + this.listeners.push({ + event: event, + callback: callback + }); +}; + +p.removeListener = function (event, callback) { + for (var i = this.listeners.length; i >= 0; i--) { + var l = this.listeners[i]; + + if (l.event === event && l.callback === callback) { + this.listeners.splice(i, 1); + } + } +}; + +p.emit = function (event, data) { + for (var i = 0; i < this.listeners.length; i++) { + var l = this.listeners[i]; + + if (event === l.event) { + l.callback(data); + } + } +}; + +module.exports = Emitter; + +/***/ }) +/******/ ]); +}); + +/***/ }), + +/***/ 21549: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var hashClear = __webpack_require__(22032), + hashDelete = __webpack_require__(63862), + hashGet = __webpack_require__(66721), + hashHas = __webpack_require__(12749), + hashSet = __webpack_require__(35749); + +/** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; + +module.exports = Hash; + + +/***/ }), + +/***/ 80079: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var listCacheClear = __webpack_require__(63702), + listCacheDelete = __webpack_require__(70080), + listCacheGet = __webpack_require__(24739), + listCacheHas = __webpack_require__(48655), + listCacheSet = __webpack_require__(31175); + +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; + +module.exports = ListCache; + + +/***/ }), + +/***/ 68223: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getNative = __webpack_require__(56110), + root = __webpack_require__(9325); + +/* Built-in method references that are verified to be native. */ +var Map = getNative(root, 'Map'); + +module.exports = Map; + + +/***/ }), + +/***/ 53661: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var mapCacheClear = __webpack_require__(63040), + mapCacheDelete = __webpack_require__(17670), + mapCacheGet = __webpack_require__(90289), + mapCacheHas = __webpack_require__(4509), + mapCacheSet = __webpack_require__(72949); + +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; + +module.exports = MapCache; + + +/***/ }), + +/***/ 51873: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var root = __webpack_require__(9325); + +/** Built-in value references. */ +var Symbol = root.Symbol; + +module.exports = Symbol; + + +/***/ }), + +/***/ 34932: +/***/ ((module) => { + +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +module.exports = arrayMap; + + +/***/ }), + +/***/ 16547: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseAssignValue = __webpack_require__(43360), + eq = __webpack_require__(75288); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } +} + +module.exports = assignValue; + + +/***/ }), + +/***/ 26025: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var eq = __webpack_require__(75288); + +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; +} + +module.exports = assocIndexOf; + + +/***/ }), + +/***/ 43360: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var defineProperty = __webpack_require__(93243); + +/** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } +} + +module.exports = baseAssignValue; + + +/***/ }), + +/***/ 47422: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var castPath = __webpack_require__(31769), + toKey = __webpack_require__(77797); + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = castPath(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +module.exports = baseGet; + + +/***/ }), + +/***/ 72552: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Symbol = __webpack_require__(51873), + getRawTag = __webpack_require__(659), + objectToString = __webpack_require__(59350); + +/** `Object#toString` result references. */ +var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + +/** Built-in value references. */ +var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + +/** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); +} + +module.exports = baseGetTag; + + +/***/ }), + +/***/ 45083: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var isFunction = __webpack_require__(1882), + isMasked = __webpack_require__(87296), + isObject = __webpack_require__(23805), + toSource = __webpack_require__(47473); + +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} + +module.exports = baseIsNative; + + +/***/ }), + +/***/ 73170: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var assignValue = __webpack_require__(16547), + castPath = __webpack_require__(31769), + isIndex = __webpack_require__(30361), + isObject = __webpack_require__(23805), + toKey = __webpack_require__(77797); + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject(objValue) + ? objValue + : (isIndex(path[index + 1]) ? [] : {}); + } + } + assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +module.exports = baseSet; + + +/***/ }), + +/***/ 77556: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Symbol = __webpack_require__(51873), + arrayMap = __webpack_require__(34932), + isArray = __webpack_require__(56449), + isSymbol = __webpack_require__(44394); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +module.exports = baseToString; + + +/***/ }), + +/***/ 54128: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var trimmedEndIndex = __webpack_require__(31800); + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +module.exports = baseTrim; + + +/***/ }), + +/***/ 31769: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var isArray = __webpack_require__(56449), + isKey = __webpack_require__(28586), + stringToPath = __webpack_require__(61802), + toString = __webpack_require__(13222); + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); +} + +module.exports = castPath; + + +/***/ }), + +/***/ 23007: +/***/ ((module) => { + +/** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ +function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; +} + +module.exports = copyArray; + + +/***/ }), + +/***/ 55481: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var root = __webpack_require__(9325); + +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; + +module.exports = coreJsData; + + +/***/ }), + +/***/ 93243: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getNative = __webpack_require__(56110); + +var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} +}()); + +module.exports = defineProperty; + + +/***/ }), + +/***/ 34840: +/***/ ((module) => { + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + +module.exports = freeGlobal; + + +/***/ }), + +/***/ 12651: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var isKeyable = __webpack_require__(74218); + +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ +function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; +} + +module.exports = getMapData; + + +/***/ }), + +/***/ 56110: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseIsNative = __webpack_require__(45083), + getValue = __webpack_require__(10392); + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} + +module.exports = getNative; + + +/***/ }), + +/***/ 659: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Symbol = __webpack_require__(51873); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; + +/** Built-in value references. */ +var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + +/** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ +function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; +} + +module.exports = getRawTag; + + +/***/ }), + +/***/ 10392: +/***/ ((module) => { + +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; +} + +module.exports = getValue; + + +/***/ }), + +/***/ 22032: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var nativeCreate = __webpack_require__(81042); + +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; +} + +module.exports = hashClear; + + +/***/ }), + +/***/ 63862: +/***/ ((module) => { + +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; +} + +module.exports = hashDelete; + + +/***/ }), + +/***/ 66721: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var nativeCreate = __webpack_require__(81042); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; +} + +module.exports = hashGet; + + +/***/ }), + +/***/ 12749: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var nativeCreate = __webpack_require__(81042); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); +} + +module.exports = hashHas; + + +/***/ }), + +/***/ 35749: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var nativeCreate = __webpack_require__(81042); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ +function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; +} + +module.exports = hashSet; + + +/***/ }), + +/***/ 30361: +/***/ ((module) => { + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); +} + +module.exports = isIndex; + + +/***/ }), + +/***/ 28586: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var isArray = __webpack_require__(56449), + isSymbol = __webpack_require__(44394); + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +module.exports = isKey; + + +/***/ }), + +/***/ 74218: +/***/ ((module) => { + +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); +} + +module.exports = isKeyable; + + +/***/ }), + +/***/ 87296: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var coreJsData = __webpack_require__(55481); + +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); + +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} + +module.exports = isMasked; + + +/***/ }), + +/***/ 63702: +/***/ ((module) => { + +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; + this.size = 0; +} + +module.exports = listCacheClear; + + +/***/ }), + +/***/ 70080: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var assocIndexOf = __webpack_require__(26025); + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; +} + +module.exports = listCacheDelete; + + +/***/ }), + +/***/ 24739: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var assocIndexOf = __webpack_require__(26025); + +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; +} + +module.exports = listCacheGet; + + +/***/ }), + +/***/ 48655: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var assocIndexOf = __webpack_require__(26025); + +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; +} + +module.exports = listCacheHas; + + +/***/ }), + +/***/ 31175: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var assocIndexOf = __webpack_require__(26025); + +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ +function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} + +module.exports = listCacheSet; + + +/***/ }), + +/***/ 63040: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Hash = __webpack_require__(21549), + ListCache = __webpack_require__(80079), + Map = __webpack_require__(68223); + +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; +} + +module.exports = mapCacheClear; + + +/***/ }), + +/***/ 17670: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getMapData = __webpack_require__(12651); + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; +} + +module.exports = mapCacheDelete; + + +/***/ }), + +/***/ 90289: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getMapData = __webpack_require__(12651); + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapCacheGet(key) { + return getMapData(this, key).get(key); +} + +module.exports = mapCacheGet; + + +/***/ }), + +/***/ 4509: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getMapData = __webpack_require__(12651); + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapCacheHas(key) { + return getMapData(this, key).has(key); +} + +module.exports = mapCacheHas; + + +/***/ }), + +/***/ 72949: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getMapData = __webpack_require__(12651); + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ +function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; +} + +module.exports = mapCacheSet; + + +/***/ }), + +/***/ 62224: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var memoize = __webpack_require__(50104); + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +module.exports = memoizeCapped; + + +/***/ }), + +/***/ 81042: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getNative = __webpack_require__(56110); + +/* Built-in method references that are verified to be native. */ +var nativeCreate = getNative(Object, 'create'); + +module.exports = nativeCreate; + + +/***/ }), + +/***/ 59350: +/***/ ((module) => { + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; + +/** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ +function objectToString(value) { + return nativeObjectToString.call(value); +} + +module.exports = objectToString; + + +/***/ }), + +/***/ 9325: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var freeGlobal = __webpack_require__(34840); + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +module.exports = root; + + +/***/ }), + +/***/ 61802: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var memoizeCapped = __webpack_require__(62224); + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +module.exports = stringToPath; + + +/***/ }), + +/***/ 77797: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var isSymbol = __webpack_require__(44394); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +module.exports = toKey; + + +/***/ }), + +/***/ 47473: +/***/ ((module) => { + +/** Used for built-in method references. */ +var funcProto = Function.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; +} + +module.exports = toSource; + + +/***/ }), + +/***/ 31800: +/***/ ((module) => { + +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +module.exports = trimmedEndIndex; + + +/***/ }), + +/***/ 38221: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var isObject = __webpack_require__(23805), + now = __webpack_require__(10124), + toNumber = __webpack_require__(99374); + +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ +function debounce(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + timeWaiting = wait - timeSinceLastCall; + + return maxing + ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) + : timeWaiting; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now()); + } + + function debounced() { + var time = now(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + clearTimeout(timerId); + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; +} + +module.exports = debounce; + + +/***/ }), + +/***/ 75288: +/***/ ((module) => { + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +module.exports = eq; + + +/***/ }), + +/***/ 58156: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseGet = __webpack_require__(47422); + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; +} + +module.exports = get; + + +/***/ }), + +/***/ 56449: +/***/ ((module) => { + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +module.exports = isArray; + + +/***/ }), + +/***/ 1882: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseGetTag = __webpack_require__(72552), + isObject = __webpack_require__(23805); + +/** `Object#toString` result references. */ +var asyncTag = '[object AsyncFunction]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; +} + +module.exports = isFunction; + + +/***/ }), + +/***/ 23805: +/***/ ((module) => { + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); +} + +module.exports = isObject; + + +/***/ }), + +/***/ 40346: +/***/ ((module) => { + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return value != null && typeof value == 'object'; +} + +module.exports = isObjectLike; + + +/***/ }), + +/***/ 44394: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseGetTag = __webpack_require__(72552), + isObjectLike = __webpack_require__(40346); + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); +} + +module.exports = isSymbol; + + +/***/ }), + +/***/ 50104: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var MapCache = __webpack_require__(53661); + +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ +function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; +} + +// Expose `MapCache`. +memoize.Cache = MapCache; + +module.exports = memoize; + + +/***/ }), + +/***/ 10124: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var root = __webpack_require__(9325); + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return root.Date.now(); +}; + +module.exports = now; + + +/***/ }), + +/***/ 63560: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseSet = __webpack_require__(73170); + +/** + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, ['x', '0', 'y', 'z'], 5); + * console.log(object.x[0].y.z); + * // => 5 + */ +function set(object, path, value) { + return object == null ? object : baseSet(object, path, value); +} + +module.exports = set; + + +/***/ }), + +/***/ 99374: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseTrim = __webpack_require__(54128), + isObject = __webpack_require__(23805), + isSymbol = __webpack_require__(44394); + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +module.exports = toNumber; + + +/***/ }), + +/***/ 42072: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var arrayMap = __webpack_require__(34932), + copyArray = __webpack_require__(23007), + isArray = __webpack_require__(56449), + isSymbol = __webpack_require__(44394), + stringToPath = __webpack_require__(61802), + toKey = __webpack_require__(77797), + toString = __webpack_require__(13222); + +/** + * Converts `value` to a property path array. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Util + * @param {*} value The value to convert. + * @returns {Array} Returns the new property path array. + * @example + * + * _.toPath('a.b.c'); + * // => ['a', 'b', 'c'] + * + * _.toPath('a[0].b.c'); + * // => ['a', '0', 'b', 'c'] + */ +function toPath(value) { + if (isArray(value)) { + return arrayMap(value, toKey); + } + return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value))); +} + +module.exports = toPath; + + +/***/ }), + +/***/ 13222: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseToString = __webpack_require__(77556); + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString(value) { + return value == null ? '' : baseToString(value); +} + +module.exports = toString; + + +/***/ }), + +/***/ 40351: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-f47111a7.js + 8 modules +var mermaid_f47111a7 = __webpack_require__(76257); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array<unknown>} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array<string>} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array<T>} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array<unknown>} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {Array<T>} items + * Items to add to `list`. + * @returns {Array<T>} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array<Extension>} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record<string, unknown>} */ + const left = maybe || (all[hook] = {}) + /** @type {Record<string, unknown> | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array<unknown>} existing + * @param {Array<unknown>} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array<unknown>} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array<HtmlExtension>} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array<StackItem>} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array<Event>} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record<string, number>} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array<Event>} */ + let parameters + /** @type {Array<Event>} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array<Event>} events + * @param {number} eventIndex + * @returns {Record<string, number>} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array<number>} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record<string, number>} */ + const gaps = {} + /** @type {Array<Chunk>} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array<Event>} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array<Event>} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array<Resolver>} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit<Point, '_bufferIndex' | '_index'> | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record<string, number>} */ + const columnStart = {} + /** @type {Array<Construct>} */ + const resolveAllConstructs = [] + /** @type {Array<Chunk>} */ + let chunks = [] + /** @type {Array<Token>} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array<Construct> | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array<Construct>} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array<Construct>} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array<Chunk>} chunks + * @param {Pick<Token, 'end' | 'start'>} token + * @returns {Array<Chunk>} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array<Chunk>} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array<Chunk>} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array<string>} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * <a> + * <a\>b> + * <a b> + * <a)> + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`<a>` or `b`). + * @param {TokenType} literalType + * Type when enclosed (`<a>`). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | <aa> + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | <a\*a> + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | <x /> + * ^ + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<!-`, inside a comment, at another `-`. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<![`, inside CDATA, expecting `CDATA[`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | </x> + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | <ab> + * ^^ + * > | </ab> + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > | <div/> + * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | <x/> + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | <a /> + * ^ + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * > | <a > + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | <a b> + * ^ + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | <a b=c> + * ^ + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | <a b="c"> + * ^ + * > | <a b='c'> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | <x> + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | <x> + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after `</`, in a raw tag name. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | <!--> + * ^ + * > | <?> + * ^ + * > | <!q> + * ^ + * > | <!--ab--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > | <div> + * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record<string, string>} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array<Event>} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + * <p>!<a href=\"b\">^a</a></p> + * <p>!<a href=\"c\">^a</a></p> + * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array<Event>} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | a<user.name@ex-ample.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code> | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a <b> c + * ^ + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * > | a <![CDATA[>&<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after `<!-`, at another `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After `<![`, in CDATA, expecting `CDATA[`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a <!b> c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After `</x`, in a tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After `<x`, in opening tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a <!--a + * ^ + * | b--> + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array<Chunk>} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array<Chunk>} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array<Event>} events + * @returns {Array<Event>} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract<Node, UnistParent>} Parent + * + * @typedef {Omit<UnistParent, 'type' | 'children'> & {type: 'fragment', children: Array<PhrasingContent>}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record<string, Handle>} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array<string>} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array<Transform>} transforms + * Tree transforms. + * + * @typedef {Partial<Config>} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array<Node | Fragment>} stack + * Stack of nodes. + * @property {Array<TokenTuple>} tokenStack + * Stack of tokens. + * @property {<Key extends keyof CompileData>(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {<Key extends keyof CompileData>(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {<Kind extends Node>(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array<Extension | Array<Extension>> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array<Event>} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit<CompileContext, 'sliceSerialize'>} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array<number>} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array<Event>} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array<StaticPhrasingContent>} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array<Extension | Array<Extension>>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(60513); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-6b48ae7d.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.T)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "<br/>"); + } else if (node.type === "strong") { + return `<strong>${node.children.map(output).join("")}</strong>`; + } else if (node.type === "emphasis") { + return `<em>${node.children.map(output).join("")}</em>`; + } else if (node.type === "paragraph") { + return `<p>${node.children.map(output).join("")}</p>`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + <span class="${labelClass} ${classes}" ` + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_f47111a7.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_f47111a7.M)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `<i class='${s.replace(":", " ")}'></i>` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 93771: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(76257); +/* harmony import */ var cytoscape__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(44726); +/* harmony import */ var cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(43457); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(26312); +/* harmony import */ var _createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(40351); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(3219); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(78041); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(75263); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(99418); + + + + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 4], $V1 = [1, 13], $V2 = [1, 12], $V3 = [1, 15], $V4 = [1, 16], $V5 = [1, 20], $V6 = [1, 19], $V7 = [6, 7, 8], $V8 = [1, 26], $V9 = [1, 24], $Va = [1, 25], $Vb = [6, 7, 11], $Vc = [1, 6, 13, 15, 16, 19, 22], $Vd = [1, 33], $Ve = [1, 34], $Vf = [1, 6, 7, 11, 13, 15, 16, 19, 22]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "mindMap": 4, "spaceLines": 5, "SPACELINE": 6, "NL": 7, "MINDMAP": 8, "document": 9, "stop": 10, "EOF": 11, "statement": 12, "SPACELIST": 13, "node": 14, "ICON": 15, "CLASS": 16, "nodeWithId": 17, "nodeWithoutId": 18, "NODE_DSTART": 19, "NODE_DESCR": 20, "NODE_DEND": 21, "NODE_ID": 22, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 6: "SPACELINE", 7: "NL", 8: "MINDMAP", 11: "EOF", 13: "SPACELIST", 15: "ICON", 16: "CLASS", 19: "NODE_DSTART", 20: "NODE_DESCR", 21: "NODE_DEND", 22: "NODE_ID" }, + productions_: [0, [3, 1], [3, 2], [5, 1], [5, 2], [5, 2], [4, 2], [4, 3], [10, 1], [10, 1], [10, 1], [10, 2], [10, 2], [9, 3], [9, 2], [12, 2], [12, 2], [12, 2], [12, 1], [12, 1], [12, 1], [12, 1], [12, 1], [14, 1], [14, 1], [18, 3], [17, 1], [17, 4]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 6: + case 7: + return yy; + case 8: + yy.getLogger().trace("Stop NL "); + break; + case 9: + yy.getLogger().trace("Stop EOF "); + break; + case 11: + yy.getLogger().trace("Stop NL2 "); + break; + case 12: + yy.getLogger().trace("Stop EOF2 "); + break; + case 15: + yy.getLogger().info("Node: ", $$[$0].id); + yy.addNode($$[$0 - 1].length, $$[$0].id, $$[$0].descr, $$[$0].type); + break; + case 16: + yy.getLogger().trace("Icon: ", $$[$0]); + yy.decorateNode({ icon: $$[$0] }); + break; + case 17: + case 21: + yy.decorateNode({ class: $$[$0] }); + break; + case 18: + yy.getLogger().trace("SPACELIST"); + break; + case 19: + yy.getLogger().trace("Node: ", $$[$0].id); + yy.addNode(0, $$[$0].id, $$[$0].descr, $$[$0].type); + break; + case 20: + yy.decorateNode({ icon: $$[$0] }); + break; + case 25: + yy.getLogger().trace("node found ..", $$[$0 - 2]); + this.$ = { id: $$[$0 - 1], descr: $$[$0 - 1], type: yy.getType($$[$0 - 2], $$[$0]) }; + break; + case 26: + this.$ = { id: $$[$0], descr: $$[$0], type: yy.nodeType.DEFAULT }; + break; + case 27: + yy.getLogger().trace("node found ..", $$[$0 - 3]); + this.$ = { id: $$[$0 - 3], descr: $$[$0 - 1], type: yy.getType($$[$0 - 2], $$[$0]) }; + break; + } + }, + table: [{ 3: 1, 4: 2, 5: 3, 6: [1, 5], 8: $V0 }, { 1: [3] }, { 1: [2, 1] }, { 4: 6, 6: [1, 7], 7: [1, 8], 8: $V0 }, { 6: $V1, 7: [1, 10], 9: 9, 12: 11, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, o($V7, [2, 3]), { 1: [2, 2] }, o($V7, [2, 4]), o($V7, [2, 5]), { 1: [2, 6], 6: $V1, 12: 21, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, { 6: $V1, 9: 22, 12: 11, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, { 6: $V8, 7: $V9, 10: 23, 11: $Va }, o($Vb, [2, 22], { 17: 17, 18: 18, 14: 27, 15: [1, 28], 16: [1, 29], 19: $V5, 22: $V6 }), o($Vb, [2, 18]), o($Vb, [2, 19]), o($Vb, [2, 20]), o($Vb, [2, 21]), o($Vb, [2, 23]), o($Vb, [2, 24]), o($Vb, [2, 26], { 19: [1, 30] }), { 20: [1, 31] }, { 6: $V8, 7: $V9, 10: 32, 11: $Va }, { 1: [2, 7], 6: $V1, 12: 21, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, o($Vc, [2, 14], { 7: $Vd, 11: $Ve }), o($Vf, [2, 8]), o($Vf, [2, 9]), o($Vf, [2, 10]), o($Vb, [2, 15]), o($Vb, [2, 16]), o($Vb, [2, 17]), { 20: [1, 35] }, { 21: [1, 36] }, o($Vc, [2, 13], { 7: $Vd, 11: $Ve }), o($Vf, [2, 11]), o($Vf, [2, 12]), { 21: [1, 37] }, o($Vb, [2, 25]), o($Vb, [2, 27])], + defaultActions: { 2: [2, 1], 6: [2, 2] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + yy.getLogger().trace("Found comment", yy_.yytext); + return 6; + case 1: + return 8; + case 2: + this.begin("CLASS"); + break; + case 3: + this.popState(); + return 16; + case 4: + this.popState(); + break; + case 5: + yy.getLogger().trace("Begin icon"); + this.begin("ICON"); + break; + case 6: + yy.getLogger().trace("SPACELINE"); + return 6; + case 7: + return 7; + case 8: + return 15; + case 9: + yy.getLogger().trace("end icon"); + this.popState(); + break; + case 10: + yy.getLogger().trace("Exploding node"); + this.begin("NODE"); + return 19; + case 11: + yy.getLogger().trace("Cloud"); + this.begin("NODE"); + return 19; + case 12: + yy.getLogger().trace("Explosion Bang"); + this.begin("NODE"); + return 19; + case 13: + yy.getLogger().trace("Cloud Bang"); + this.begin("NODE"); + return 19; + case 14: + this.begin("NODE"); + return 19; + case 15: + this.begin("NODE"); + return 19; + case 16: + this.begin("NODE"); + return 19; + case 17: + this.begin("NODE"); + return 19; + case 18: + return 13; + case 19: + return 22; + case 20: + return 11; + case 21: + this.begin("NSTR2"); + break; + case 22: + return "NODE_DESCR"; + case 23: + this.popState(); + break; + case 24: + yy.getLogger().trace("Starting NSTR"); + this.begin("NSTR"); + break; + case 25: + yy.getLogger().trace("description:", yy_.yytext); + return "NODE_DESCR"; + case 26: + this.popState(); + break; + case 27: + this.popState(); + yy.getLogger().trace("node end ))"); + return "NODE_DEND"; + case 28: + this.popState(); + yy.getLogger().trace("node end )"); + return "NODE_DEND"; + case 29: + this.popState(); + yy.getLogger().trace("node end ...", yy_.yytext); + return "NODE_DEND"; + case 30: + this.popState(); + yy.getLogger().trace("node end (("); + return "NODE_DEND"; + case 31: + this.popState(); + yy.getLogger().trace("node end (-"); + return "NODE_DEND"; + case 32: + this.popState(); + yy.getLogger().trace("node end (-"); + return "NODE_DEND"; + case 33: + this.popState(); + yy.getLogger().trace("node end (("); + return "NODE_DEND"; + case 34: + this.popState(); + yy.getLogger().trace("node end (("); + return "NODE_DEND"; + case 35: + yy.getLogger().trace("Long description:", yy_.yytext); + return 20; + case 36: + yy.getLogger().trace("Long description:", yy_.yytext); + return 20; + } + }, + rules: [/^(?:\s*%%.*)/i, /^(?:mindmap\b)/i, /^(?::::)/i, /^(?:.+)/i, /^(?:\n)/i, /^(?:::icon\()/i, /^(?:[\s]+[\n])/i, /^(?:[\n]+)/i, /^(?:[^\)]+)/i, /^(?:\))/i, /^(?:-\))/i, /^(?:\(-)/i, /^(?:\)\))/i, /^(?:\))/i, /^(?:\(\()/i, /^(?:\{\{)/i, /^(?:\()/i, /^(?:\[)/i, /^(?:[\s]+)/i, /^(?:[^\(\[\n\)\{\}]+)/i, /^(?:$)/i, /^(?:["][`])/i, /^(?:[^`"]+)/i, /^(?:[`]["])/i, /^(?:["])/i, /^(?:[^"]+)/i, /^(?:["])/i, /^(?:[\)]\))/i, /^(?:[\)])/i, /^(?:[\]])/i, /^(?:\}\})/i, /^(?:\(-)/i, /^(?:-\))/i, /^(?:\(\()/i, /^(?:\()/i, /^(?:[^\)\]\(\}]+)/i, /^(?:.+(?!\(\())/i], + conditions: { "CLASS": { "rules": [3, 4], "inclusive": false }, "ICON": { "rules": [8, 9], "inclusive": false }, "NSTR2": { "rules": [22, 23], "inclusive": false }, "NSTR": { "rules": [25, 26], "inclusive": false }, "NODE": { "rules": [21, 24, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let nodes = []; +let cnt = 0; +let elements = {}; +const clear = () => { + nodes = []; + cnt = 0; + elements = {}; +}; +const getParent = function(level) { + for (let i = nodes.length - 1; i >= 0; i--) { + if (nodes[i].level < level) { + return nodes[i]; + } + } + return null; +}; +const getMindmap = () => { + return nodes.length > 0 ? nodes[0] : null; +}; +const addNode = (level, id, descr, type) => { + var _a, _b; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.info("addNode", level, id, descr, type); + const conf = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)(); + let padding = ((_a = conf.mindmap) == null ? void 0 : _a.padding) ?? _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.B.mindmap.padding; + switch (type) { + case nodeType.ROUNDED_RECT: + case nodeType.RECT: + case nodeType.HEXAGON: + padding *= 2; + } + const node = { + id: cnt++, + nodeId: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.d)(id, conf), + level, + descr: (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.d)(descr, conf), + type, + children: [], + width: ((_b = conf.mindmap) == null ? void 0 : _b.maxNodeWidth) ?? _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.B.mindmap.maxNodeWidth, + padding + }; + const parent = getParent(level); + if (parent) { + parent.children.push(node); + nodes.push(node); + } else { + if (nodes.length === 0) { + nodes.push(node); + } else { + throw new Error( + 'There can be only one root. No parent could be found for ("' + node.descr + '")' + ); + } + } +}; +const nodeType = { + DEFAULT: 0, + NO_BORDER: 0, + ROUNDED_RECT: 1, + RECT: 2, + CIRCLE: 3, + CLOUD: 4, + BANG: 5, + HEXAGON: 6 +}; +const getType = (startStr, endStr) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("In get type", startStr, endStr); + switch (startStr) { + case "[": + return nodeType.RECT; + case "(": + return endStr === ")" ? nodeType.ROUNDED_RECT : nodeType.CLOUD; + case "((": + return nodeType.CIRCLE; + case ")": + return nodeType.CLOUD; + case "))": + return nodeType.BANG; + case "{{": + return nodeType.HEXAGON; + default: + return nodeType.DEFAULT; + } +}; +const setElementForId = (id, element) => { + elements[id] = element; +}; +const decorateNode = (decoration) => { + if (!decoration) { + return; + } + const config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)(); + const node = nodes[nodes.length - 1]; + if (decoration.icon) { + node.icon = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.d)(decoration.icon, config); + } + if (decoration.class) { + node.class = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.d)(decoration.class, config); + } +}; +const type2Str = (type) => { + switch (type) { + case nodeType.DEFAULT: + return "no-border"; + case nodeType.RECT: + return "rect"; + case nodeType.ROUNDED_RECT: + return "rounded-rect"; + case nodeType.CIRCLE: + return "circle"; + case nodeType.CLOUD: + return "cloud"; + case nodeType.BANG: + return "bang"; + case nodeType.HEXAGON: + return "hexgon"; + default: + return "no-border"; + } +}; +const getLogger = () => _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l; +const getElementById = (id) => elements[id]; +const db = { + clear, + addNode, + getMindmap, + nodeType, + getType, + setElementForId, + decorateNode, + type2Str, + getLogger, + getElementById +}; +const db$1 = db; +const MAX_SECTIONS = 12; +const defaultBkg = function(db2, elem, node, section) { + const rd = 5; + elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + db2.type2Str(node.type)).attr( + "d", + `M0 ${node.height - rd} v${-node.height + 2 * rd} q0,-5 5,-5 h${node.width - 2 * rd} q5,0 5,5 v${node.height - rd} H0 Z` + ); + elem.append("line").attr("class", "node-line-" + section).attr("x1", 0).attr("y1", node.height).attr("x2", node.width).attr("y2", node.height); +}; +const rectBkg = function(db2, elem, node) { + elem.append("rect").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + db2.type2Str(node.type)).attr("height", node.height).attr("width", node.width); +}; +const cloudBkg = function(db2, elem, node) { + const w = node.width; + const h = node.height; + const r1 = 0.15 * w; + const r2 = 0.25 * w; + const r3 = 0.35 * w; + const r4 = 0.2 * w; + elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + db2.type2Str(node.type)).attr( + "d", + `M0 0 a${r1},${r1} 0 0,1 ${w * 0.25},${-1 * w * 0.1} + a${r3},${r3} 1 0,1 ${w * 0.4},${-1 * w * 0.1} + a${r2},${r2} 1 0,1 ${w * 0.35},${1 * w * 0.2} + + a${r1},${r1} 1 0,1 ${w * 0.15},${1 * h * 0.35} + a${r4},${r4} 1 0,1 ${-1 * w * 0.15},${1 * h * 0.65} + + a${r2},${r1} 1 0,1 ${-1 * w * 0.25},${w * 0.15} + a${r3},${r3} 1 0,1 ${-1 * w * 0.5},${0} + a${r1},${r1} 1 0,1 ${-1 * w * 0.25},${-1 * w * 0.15} + + a${r1},${r1} 1 0,1 ${-1 * w * 0.1},${-1 * h * 0.35} + a${r4},${r4} 1 0,1 ${w * 0.1},${-1 * h * 0.65} + + H0 V0 Z` + ); +}; +const bangBkg = function(db2, elem, node) { + const w = node.width; + const h = node.height; + const r = 0.15 * w; + elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + db2.type2Str(node.type)).attr( + "d", + `M0 0 a${r},${r} 1 0,0 ${w * 0.25},${-1 * h * 0.1} + a${r},${r} 1 0,0 ${w * 0.25},${0} + a${r},${r} 1 0,0 ${w * 0.25},${0} + a${r},${r} 1 0,0 ${w * 0.25},${1 * h * 0.1} + + a${r},${r} 1 0,0 ${w * 0.15},${1 * h * 0.33} + a${r * 0.8},${r * 0.8} 1 0,0 ${0},${1 * h * 0.34} + a${r},${r} 1 0,0 ${-1 * w * 0.15},${1 * h * 0.33} + + a${r},${r} 1 0,0 ${-1 * w * 0.25},${h * 0.15} + a${r},${r} 1 0,0 ${-1 * w * 0.25},${0} + a${r},${r} 1 0,0 ${-1 * w * 0.25},${0} + a${r},${r} 1 0,0 ${-1 * w * 0.25},${-1 * h * 0.15} + + a${r},${r} 1 0,0 ${-1 * w * 0.1},${-1 * h * 0.33} + a${r * 0.8},${r * 0.8} 1 0,0 ${0},${-1 * h * 0.34} + a${r},${r} 1 0,0 ${w * 0.1},${-1 * h * 0.33} + + H0 V0 Z` + ); +}; +const circleBkg = function(db2, elem, node) { + elem.append("circle").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + db2.type2Str(node.type)).attr("r", node.width / 2); +}; +function insertPolygonShape(parent, w, h, points, node) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("transform", "translate(" + (node.width - w) / 2 + ", " + h + ")"); +} +const hexagonBkg = function(_db, elem, node) { + const h = node.height; + const f = 4; + const m = h / f; + const w = node.width - node.padding + 2 * m; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + insertPolygonShape(elem, w, h, points, node); +}; +const roundedRectBkg = function(db2, elem, node) { + elem.append("rect").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + db2.type2Str(node.type)).attr("height", node.height).attr("rx", node.padding).attr("ry", node.padding).attr("width", node.width); +}; +const drawNode = function(db2, elem, node, fullSection, conf) { + const htmlLabels = conf.htmlLabels; + const section = fullSection % (MAX_SECTIONS - 1); + const nodeElem = elem.append("g"); + node.section = section; + let sectionClass = "section-" + section; + if (section < 0) { + sectionClass += " section-root"; + } + nodeElem.attr("class", (node.class ? node.class + " " : "") + "mindmap-node " + sectionClass); + const bkgElem = nodeElem.append("g"); + const textElem = nodeElem.append("g"); + const description = node.descr.replace(/(<br\/*>)/g, "\n"); + (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_7__.a)(textElem, description, { + useHtmlLabels: htmlLabels, + width: node.width, + classes: "mindmap-node-label" + }); + if (!htmlLabels) { + textElem.attr("dy", "1em").attr("alignment-baseline", "middle").attr("dominant-baseline", "middle").attr("text-anchor", "middle"); + } + const bbox = textElem.node().getBBox(); + const [fontSize] = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.D)(conf.fontSize); + node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding; + node.width = bbox.width + 2 * node.padding; + if (node.icon) { + if (node.type === db2.nodeType.CIRCLE) { + node.height += 50; + node.width += 50; + const icon = nodeElem.append("foreignObject").attr("height", "50px").attr("width", node.width).attr("style", "text-align: center;"); + icon.append("div").attr("class", "icon-container").append("i").attr("class", "node-icon-" + section + " " + node.icon); + textElem.attr( + "transform", + "translate(" + node.width / 2 + ", " + (node.height / 2 - 1.5 * node.padding) + ")" + ); + } else { + node.width += 50; + const orgHeight = node.height; + node.height = Math.max(orgHeight, 60); + const heightDiff = Math.abs(node.height - orgHeight); + const icon = nodeElem.append("foreignObject").attr("width", "60px").attr("height", node.height).attr("style", "text-align: center;margin-top:" + heightDiff / 2 + "px;"); + icon.append("div").attr("class", "icon-container").append("i").attr("class", "node-icon-" + section + " " + node.icon); + textElem.attr( + "transform", + "translate(" + (25 + node.width / 2) + ", " + (heightDiff / 2 + node.padding / 2) + ")" + ); + } + } else { + if (!htmlLabels) { + const dx = node.width / 2; + const dy = node.padding / 2; + textElem.attr("transform", "translate(" + dx + ", " + dy + ")"); + } else { + const dx = (node.width - bbox.width) / 2; + const dy = (node.height - bbox.height) / 2; + textElem.attr("transform", "translate(" + dx + ", " + dy + ")"); + } + } + switch (node.type) { + case db2.nodeType.DEFAULT: + defaultBkg(db2, bkgElem, node, section); + break; + case db2.nodeType.ROUNDED_RECT: + roundedRectBkg(db2, bkgElem, node); + break; + case db2.nodeType.RECT: + rectBkg(db2, bkgElem, node); + break; + case db2.nodeType.CIRCLE: + bkgElem.attr("transform", "translate(" + node.width / 2 + ", " + +node.height / 2 + ")"); + circleBkg(db2, bkgElem, node); + break; + case db2.nodeType.CLOUD: + cloudBkg(db2, bkgElem, node); + break; + case db2.nodeType.BANG: + bangBkg(db2, bkgElem, node); + break; + case db2.nodeType.HEXAGON: + hexagonBkg(db2, bkgElem, node); + break; + } + db2.setElementForId(node.id, nodeElem); + return node.height; +}; +const positionNode = function(db2, node) { + const nodeElem = db2.getElementById(node.id); + const x = node.x || 0; + const y = node.y || 0; + nodeElem.attr("transform", "translate(" + x + "," + y + ")"); +}; +cytoscape__WEBPACK_IMPORTED_MODULE_0__.use(cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_1__); +function drawNodes(db2, svg, mindmap, section, conf) { + drawNode(db2, svg, mindmap, section, conf); + if (mindmap.children) { + mindmap.children.forEach((child, index) => { + drawNodes(db2, svg, child, section < 0 ? index : section, conf); + }); + } +} +function drawEdges(edgesEl, cy) { + cy.edges().map((edge, id) => { + const data = edge.data(); + if (edge[0]._private.bodyBounds) { + const bounds = edge[0]._private.rscratch; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.trace("Edge: ", id, data); + edgesEl.insert("path").attr( + "d", + `M ${bounds.startX},${bounds.startY} L ${bounds.midX},${bounds.midY} L${bounds.endX},${bounds.endY} ` + ).attr("class", "edge section-edge-" + data.section + " edge-depth-" + data.depth); + } + }); +} +function addNodes(mindmap, cy, conf, level) { + cy.add({ + group: "nodes", + data: { + id: mindmap.id.toString(), + labelText: mindmap.descr, + height: mindmap.height, + width: mindmap.width, + level, + nodeId: mindmap.id, + padding: mindmap.padding, + type: mindmap.type + }, + position: { + x: mindmap.x, + y: mindmap.y + } + }); + if (mindmap.children) { + mindmap.children.forEach((child) => { + addNodes(child, cy, conf, level + 1); + cy.add({ + group: "edges", + data: { + id: `${mindmap.id}_${child.id}`, + source: mindmap.id, + target: child.id, + depth: level, + section: child.section + } + }); + }); + } +} +function layoutMindmap(node, conf) { + return new Promise((resolve) => { + const renderEl = (0,d3__WEBPACK_IMPORTED_MODULE_2__/* .select */ .Ltv)("body").append("div").attr("id", "cy").attr("style", "display:none"); + const cy = cytoscape__WEBPACK_IMPORTED_MODULE_0__({ + container: document.getElementById("cy"), + // container to render in + style: [ + { + selector: "edge", + style: { + "curve-style": "bezier" + } + } + ] + }); + renderEl.remove(); + addNodes(node, cy, conf, 0); + cy.nodes().forEach(function(n) { + n.layoutDimensions = () => { + const data = n.data(); + return { w: data.width, h: data.height }; + }; + }); + cy.layout({ + name: "cose-bilkent", + // @ts-ignore Types for cose-bilkent are not correct? + quality: "proof", + styleEnabled: false, + animate: false + }).run(); + cy.ready((e) => { + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Ready", e); + resolve(cy); + }); + }); +} +function positionNodes(db2, cy) { + cy.nodes().map((node, id) => { + const data = node.data(); + data.x = node.position().x; + data.y = node.position().y; + positionNode(db2, data); + const el = db2.getElementById(data.nodeId); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Id:", id, "Position: (", node.position().x, ", ", node.position().y, ")", data); + el.attr( + "transform", + `translate(${node.position().x - data.width / 2}, ${node.position().y - data.height / 2})` + ); + el.attr("attr", `apa-${id})`); + }); +} +const draw = async (text, id, _version, diagObj) => { + var _a, _b; + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Rendering mindmap diagram\n" + text); + const db2 = diagObj.db; + const mm = db2.getMindmap(); + if (!mm) { + return; + } + const conf = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.c)(); + conf.htmlLabels = false; + const svg = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.A)(id); + const edgesElem = svg.append("g"); + edgesElem.attr("class", "mindmap-edges"); + const nodesElem = svg.append("g"); + nodesElem.attr("class", "mindmap-nodes"); + drawNodes(db2, nodesElem, mm, -1, conf); + const cy = await layoutMindmap(mm, conf); + drawEdges(edgesElem, cy); + positionNodes(db2, cy); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.o)( + void 0, + svg, + ((_a = conf.mindmap) == null ? void 0 : _a.padding) ?? _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.B.mindmap.padding, + ((_b = conf.mindmap) == null ? void 0 : _b.useMaxWidth) ?? _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_6__.B.mindmap.useMaxWidth + ); +}; +const renderer = { + draw +}; +const genSections = (options) => { + let sections = ""; + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { + options["lineColor" + i] = options["lineColor" + i] || options["cScaleInv" + i]; + if ((0,khroma__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .A)(options["lineColor" + i])) { + options["lineColor" + i] = (0,khroma__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .A)(options["lineColor" + i], 20); + } else { + options["lineColor" + i] = (0,khroma__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .A)(options["lineColor" + i], 20); + } + } + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { + const sw = "" + (17 - 3 * i); + sections += ` + .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${i - 1} polygon, .section-${i - 1} path { + fill: ${options["cScale" + i]}; + } + .section-${i - 1} text { + fill: ${options["cScaleLabel" + i]}; + } + .node-icon-${i - 1} { + font-size: 40px; + color: ${options["cScaleLabel" + i]}; + } + .section-edge-${i - 1}{ + stroke: ${options["cScale" + i]}; + } + .edge-depth-${i - 1}{ + stroke-width: ${sw}; + } + .section-${i - 1} line { + stroke: ${options["cScaleInv" + i]} ; + stroke-width: 3; + } + + .disabled, .disabled circle, .disabled text { + fill: lightgray; + } + .disabled text { + fill: #efefef; + } + `; + } + return sections; +}; +const getStyles = (options) => ` + .edge { + stroke-width: 3; + } + ${genSections(options)} + .section-root rect, .section-root path, .section-root circle, .section-root polygon { + fill: ${options.git0}; + } + .section-root text { + fill: ${options.gitBranchLabel0}; + } + .icon-container { + height:100%; + display: flex; + justify-content: center; + align-items: center; + } + .edge { + fill: none; + } + .mindmap-node-label { + dy: 1em; + alignment-baseline: middle; + text-anchor: middle; + dominant-baseline: middle; + text-align: center; + } +`; +const styles = getStyles; +const diagram = { + db: db$1, + renderer, + parser: parser$1, + styles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/7850b12c.088a57d9.js b/assets/js/7850b12c.088a57d9.js new file mode 100644 index 0000000000..44b4fa340f --- /dev/null +++ b/assets/js/7850b12c.088a57d9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[675],{81008:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>a});var i=n(74848),r=n(28453);const t={},l="Persistence",c={id:"container/components/container-registry/docs/persistence",title:"Persistence",description:"This page briefly describes and provides pointers on how Harbor persists data when it is",source:"@site/docs/03-container/components/container-registry/docs/persistence.md",sourceDirName:"03-container/components/container-registry/docs",slug:"/container/components/container-registry/docs/persistence",permalink:"/docs/container/components/container-registry/docs/persistence",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/persistence.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Migration",permalink:"/docs/container/components/container-registry/docs/migration"},next:{title:"HA deployment",permalink:"/docs/container/components/container-registry/docs/ha-deployment"}},o={},a=[{value:"Data Access Layer",id:"data-access-layer",level:2},{value:"Redis",id:"redis",level:3},{value:"Database (PostgreSQL)",id:"database-postgresql",level:3},{value:"OCI Distribution Registry",id:"oci-distribution-registry",level:3},{value:"Fundamental Services",id:"fundamental-services",level:2},{value:"Proxy, Core, Web Portal",id:"proxy-core-web-portal",level:3},{value:"Trivy",id:"trivy",level:3},{value:"JobService",id:"jobservice",level:3}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h1,{id:"persistence",children:"Persistence"}),"\n",(0,i.jsxs)(s.p,{children:["This page briefly describes and provides pointers on how Harbor persists data when it is\ndeployed in a Kubernetes cluster environment. It points out the default persistence settings\nof ",(0,i.jsx)(s.a,{href:"https://github.com/goharbor/harbor-helm",children:"Harbor helm chart"})," as well as available options."]}),"\n",(0,i.jsxs)(s.p,{children:["Harbor, by design, consists of multiple (micro)services that could store their data\nvariously, based on the Harbor configuration, see the ",(0,i.jsx)(s.a,{href:"https://github.com/goharbor/harbor/wiki/Architecture-Overview-of-Harbor",children:"Architecture Overview of Harbor"}),"."]}),"\n",(0,i.jsx)(s.h2,{id:"data-access-layer",children:"Data Access Layer"}),"\n",(0,i.jsx)(s.h3,{id:"redis",children:"Redis"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Usage","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Key value storage used as a login session cache, a registry manifest cache, and a queue for the jobservice (e.g. see ",(0,i.jsx)(s.a,{href:"#trivy",children:"Trivy"}),")"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["Default settings","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:['Deployed as an "internal" single node database into the same Kubernetes cluster as Harbor (helm value: ',(0,i.jsx)(s.code,{children:"redis.type.internal"}),")"]}),"\n",(0,i.jsx)(s.li,{children:"Deployed as a StatefulSet with 1 replica"}),"\n",(0,i.jsxs)(s.li,{children:["PV persistence is enabled by default (helm value: ",(0,i.jsx)(s.code,{children:"persistence.enabled.true"}),"), Redis POD mounts PV into the ",(0,i.jsx)(s.code,{children:"/var/lib/redis"})," directory"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["Additional settings","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:['Harbor could be pointed to the "external" Redis (or Redis Sentinel) database (helm value: ',(0,i.jsx)(s.code,{children:"redis.type.external"}),")"]}),"\n",(0,i.jsxs)(s.li,{children:['"Internal" Redis could be deployed without any persistence, i.e. it could use ',(0,i.jsx)(s.code,{children:"emptyDir"})," (helm value: ",(0,i.jsx)(s.code,{children:"persistence.enabled.false"}),")"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["Notes","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://github.com/goharbor/harbor/issues/13544",children:"What is the role of Redis in Harbor?"})}),"\n",(0,i.jsxs)(s.li,{children:["Redis data does not need to be backed up, see the ",(0,i.jsx)(s.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#limitations",children:"Limitations docs"})," for more details of the potential impact"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"database-postgresql",children:"Database (PostgreSQL)"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Usage","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Stores the related metadata of Harbor models, like projects, users, roles, replication policies, tag retention policies, scanners, charts, and images"}),"\n",(0,i.jsxs)(s.li,{children:["Could store ",(0,i.jsx)(s.a,{href:"#jobservice",children:"JobService"})," logs (helm value: ",(0,i.jsx)(s.code,{children:"jobservice.jobLoggers.[database]"}),")"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["Default settings","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:['Deployed as an "internal" single node database into the same Kubernetes cluster as Harbor (helm value: ',(0,i.jsx)(s.code,{children:"database.type.internal"}),")"]}),"\n",(0,i.jsx)(s.li,{children:"Deployed as a StatefulSet with 1 replica"}),"\n",(0,i.jsxs)(s.li,{children:["PV persistence is enabled by default (helm value: ",(0,i.jsx)(s.code,{children:"persistence.enabled.true"}),"), PostgreSQL POD mounts PV into the ",(0,i.jsx)(s.code,{children:"/var/lib/postgresql/data"})," directory"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["Additional settings","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:['Harbor could be pointed to the "external" database (PostgreSQL) (helm value: ',(0,i.jsx)(s.code,{children:"database.type.external"}),")"]}),"\n",(0,i.jsxs)(s.li,{children:['"Internal" database could be deployed without any persistence, i.e. it could use ',(0,i.jsx)(s.code,{children:"emptyDir"})," (helm value: ",(0,i.jsx)(s.code,{children:"persistence.enabled.false"}),")"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"oci-distribution-registry",children:"OCI Distribution Registry"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Usage","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Backend storage of container images and charts"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["Default settings","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Images and charts are stored in ",(0,i.jsx)(s.code,{children:"registry"})," POD filesystem directory ",(0,i.jsx)(s.code,{children:"/storage"})," (helm value: ",(0,i.jsx)(s.code,{children:"persistence.imageChartStorage.type.filesystem"}),"), this directory is mounted to the PV"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["Additional settings","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:['Various object storage backends: "azure", "gcs", "s3", "swift", "oss" (helm value: ',(0,i.jsx)(s.code,{children:"persistence.imageChartStorage.type.<backend>"}),")"]}),"\n",(0,i.jsxs)(s.li,{children:["Backend storage could be",(0,i.jsx)(s.code,{children:"emptyDir"})," (helm value: ",(0,i.jsx)(s.code,{children:"persistence.enabled.false"}),")"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"fundamental-services",children:"Fundamental Services"}),"\n",(0,i.jsx)(s.h3,{id:"proxy-core-web-portal",children:"Proxy, Core, Web Portal"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"These Harbor services are stateless"}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"trivy",children:"Trivy"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Usage","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"A 3rd party vulnerability scanner provided by Aqua Security"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["Default settings","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Deployed as a StatefulSet with 1 replica"}),"\n",(0,i.jsxs)(s.li,{children:["PV persistence is enabled by default (helm value: ",(0,i.jsx)(s.code,{children:"persistence.enabled.true"}),"), Trivy POD mounts PV into the ",(0,i.jsx)(s.code,{children:"/home/scanner/.cache"})," directory"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["Additional settings","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Trivy could be deployed without any persistence, i.e. it could use ",(0,i.jsx)(s.code,{children:"emptyDir"})," (helm value: ",(0,i.jsx)(s.code,{children:"persistence.enabled.false"}),")"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["Notes","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://github.com/aquasecurity/harbor-scanner-trivy/issues/135#issuecomment-671259649",children:"What kind of data are stored in /home/scanner/.cache?"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h3,{id:"jobservice",children:"JobService"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["Usage","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"General job execution queue service to let other components/services submit requests of running asynchronous tasks concurrently"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["Default settings","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:"Deployed as a Deployment with 1 replica"}),"\n",(0,i.jsxs)(s.li,{children:["Store logs in the POD filesystem directory ",(0,i.jsx)(s.code,{children:"/var/log/jobs"})," (helm value: ",(0,i.jsx)(s.code,{children:"jobservice.jobLoggers.[file]"}),"), this directory is mounted to the PV"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["Additional settings","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["JobService could be deployed without any persistence, i.e. it could use ",(0,i.jsx)(s.code,{children:"emptyDir"})," (helm value: ",(0,i.jsx)(s.code,{children:"persistence.enabled.false"}),")"]}),"\n",(0,i.jsxs)(s.li,{children:["Logs could be stored in ",(0,i.jsx)(s.a,{href:"#database-postgresql",children:"Harbor database"})," (helm value: ",(0,i.jsx)(s.code,{children:"jobservice.jobLoggers.[database]"}),") or just printed to the STDOUT (helm value: ",(0,i.jsx)(s.code,{children:"jobservice.jobLoggers.[stdout]"}),")"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>l,x:()=>c});var i=n(96540);const r={},t=i.createContext(r);function l(e){const s=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),i.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7997867a.3ab5cf09.js b/assets/js/7997867a.3ab5cf09.js new file mode 100644 index 0000000000..bdfdfe491b --- /dev/null +++ b/assets/js/7997867a.3ab5cf09.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6985],{514:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var t=i(74848),s=i(28453);const o={},r="Tools Description",a={id:"operating-scs/components/automated-pentesting/tools",title:"Tools Description",description:"The following tools make up the automated pentesting pipeline. Each tool has it's own use case and they build up onto each other.",source:"@site/docs/04-operating-scs/components/automated-pentesting/tools.md",sourceDirName:"04-operating-scs/components/automated-pentesting",slug:"/operating-scs/components/automated-pentesting/tools",permalink:"/docs/operating-scs/components/automated-pentesting/tools",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/automated-pentesting/tools.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"SCS automated pentesting",permalink:"/docs/operating-scs/components/automated-pentesting/overview"},next:{title:"Guides",permalink:"/docs/category/guides-1"}},l={},d=[{value:"Naabu",id:"naabu",level:2},{value:"HTTPx",id:"httpx",level:2},{value:"Nuclei",id:"nuclei",level:2},{value:"Greenbone Community Edition (OpenVAS)",id:"greenbone-community-edition-openvas",level:2},{value:"ZAP Proxy",id:"zap-proxy",level:2},{value:"Defect Dojo",id:"defect-dojo",level:2}];function c(e){const n={h1:"h1",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"tools-description",children:"Tools Description"}),"\n",(0,t.jsx)(n.p,{children:"The following tools make up the automated pentesting pipeline. Each tool has it's own use case and they build up onto each other."}),"\n",(0,t.jsx)(n.h2,{id:"naabu",children:"Naabu"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Functionality"}),": Naabu is a port scanning tool used for identifying open ports on a target host or IP range, crucial for initial reconnaissance in penetration testing."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Fast Scanning: Utilizes a high-speed, asynchronous approach for efficient port scanning."}),"\n",(0,t.jsx)(n.li,{children:"Multiple Output Formats: Supports text, JSON, and XML formats for integration with other tools."}),"\n",(0,t.jsx)(n.li,{children:"Flexible Target Specification: Capable of scanning individual hosts, IP ranges, or CIDR notations."}),"\n",(0,t.jsx)(n.li,{children:"Custom Port Ranges: Allows scanning specific port ranges or using standard lists of common ports."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Updates"}),": Regularly updated for performance improvements and new features."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"httpx",children:"HTTPx"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Functionality"}),": HTTPx is a powerful HTTP toolkit for web server fingerprinting, crucial for identifying web technologies and analyzing responses from web servers."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"High-Speed HTTP Detection: Efficient in analyzing HTTP servers and responses."}),"\n",(0,t.jsx)(n.li,{children:"Status Code Retrieval: Collects HTTP status codes to identify live hosts and valid endpoints."}),"\n",(0,t.jsx)(n.li,{children:"Custom Headers and Methods: Supports advanced HTTP requests for detailed analysis."}),"\n",(0,t.jsx)(n.li,{children:"Automation-Friendly: Easily integrates into automated workflows and pipelines."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Updates"}),": Continuously updated with enhancements for speed, accuracy, and additional features."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"nuclei",children:"Nuclei"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Functionality"}),": Nuclei is a template-based vulnerability scanner, essential for detecting known vulnerabilities using predefined and community-driven templates."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Extensive Template Library: Wide range of continuously updated templates for various vulnerabilities."}),"\n",(0,t.jsx)(n.li,{children:"Custom Template Creation: Allows creation of tailored templates for specific environment needs."}),"\n",(0,t.jsx)(n.li,{children:"Broad Vulnerability Coverage: Capable of scanning a variety of security weaknesses and exposures."}),"\n",(0,t.jsx)(n.li,{children:"Integration-Ready: Designed to fit seamlessly into CI/CD pipelines."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Updates"}),": Community and developers regularly update templates and tool features."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"greenbone-community-edition-openvas",children:"Greenbone Community Edition (OpenVAS)"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Functionality"}),": Greenbone CE, known as OpenVAS, is a full-featured vulnerability scanner for comprehensive assessments of networks, hosts, and applications."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Wide Range of Tests: Offers a broad spectrum of network and application vulnerability tests."}),"\n",(0,t.jsx)(n.li,{children:"Regular Feed Updates: The vulnerability feed is frequently updated for new threats."}),"\n",(0,t.jsx)(n.li,{children:"Scan Customization: Supports various scan configurations and scheduling."}),"\n",(0,t.jsx)(n.li,{children:"Detailed Reporting: Generates comprehensive reports for compliance and remediation planning."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Updates"}),": Maintained with regular updates to the vulnerability feed and software enhancements."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"zap-proxy",children:"ZAP Proxy"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Functionality"}),": ZAP Proxy is an intercepting proxy for dynamic application security testing (DAST), vital for identifying vulnerabilities in web applications."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Passive and Active Scanning: Provides both passive scanning (traffic analysis) and active scanning (direct testing)."}),"\n",(0,t.jsx)(n.li,{children:"Comprehensive Web App Mapping: Includes tools like Spider and AJAX Spider for thorough application mapping."}),"\n",(0,t.jsx)(n.li,{children:"Supports Various Authentication Types: Handles different web application authentication mechanisms."}),"\n",(0,t.jsx)(n.li,{children:"Extensibility: Offers a range of plugins and extensions for additional functionalities."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Updates"}),": Regularly updated with new features and security tests."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"defect-dojo",children:"Defect Dojo"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Functionality"}),": Defect Dojo is a security program and vulnerability management tool. It centralizes and streamlines the management of security programs, allowing for efficient tracking, measurement, and reporting of vulnerabilities."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Capabilities"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Vulnerability Management: Enables tracking and management of vulnerabilities discovered across different tools and tests."}),"\n",(0,t.jsx)(n.li,{children:"Reporting and Metrics: Offers comprehensive reporting features for understanding security postures and metrics."}),"\n",(0,t.jsx)(n.li,{children:"Integration with CI/CD: Seamlessly integrates with CI/CD pipelines for automated importing of scan results."}),"\n",(0,t.jsx)(n.li,{children:"Customization and Flexibility: Allows customizations to fit various workflow requirements and integrates with other tools via APIs."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Updates"}),": Regularly updated with enhancements for functionality, usability, and security."]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>a});var t=i(96540);const s={},o=t.createContext(s);function r(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7aa8d561.db98d47a.js b/assets/js/7aa8d561.db98d47a.js new file mode 100644 index 0000000000..8c86400f02 --- /dev/null +++ b/assets/js/7aa8d561.db98d47a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1362],{54182:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var n=r(74848),s=r(28453);const a={title:"Default Rules for Security Groups",type:"Standard",status:"Draft",track:"IaaS"},o=void 0,i={id:"scs-0115-v1-default-rules-for-security-groups",title:"Default Rules for Security Groups",description:"Introduction",source:"@site/standards/scs-0115-v1-default-rules-for-security-groups.md",sourceDirName:".",slug:"/scs-0115-v1-default-rules-for-security-groups",permalink:"/standards/scs-0115-v1-default-rules-for-security-groups",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Default Rules for Security Groups",type:"Standard",status:"Draft",track:"IaaS"},sidebar:"standards",previous:{title:"scs-0115: Default Rules for Security Groups",permalink:"/standards/iaas/scs-0115"},next:{title:"KaaS Standards",permalink:"/standards/kaas/"}},u={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Default Security Groups, Custom Security Groups and default Security Group Rules",id:"default-security-groups-custom-security-groups-and-default-security-group-rules",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Further Annotations",id:"further-annotations",level:3},{value:"Standard",id:"standard",level:2},{value:"Example",id:"example",level:3},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const t={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",section:"section",strong:"strong",sup:"sup",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsx)(t.p,{children:"Security Groups in IaaS (OpenStack) are part of the network security mechanisms provided for the users.\nThey resemble sets of virtual firewall rules allowing specific network traffic at a port of a VM that connects it to a network.\nThey are project-bound, which means that all Security Groups that are newly created are only available to the project in which they were created.\nThis is also the case for the default Security Group that is created for each project as soon as the project itself is created."}),"\n",(0,n.jsx)(t.h2,{id:"terminology",children:"Terminology"}),"\n",(0,n.jsx)(t.p,{children:"Security Group (abbr. SG)\nSet of ip table rules, used for tenant network security."}),"\n",(0,n.jsx)(t.p,{children:"Security Group Rule (abbr. SG Rule)\nA single ip table rule, that is part of a SG."}),"\n",(0,n.jsx)(t.p,{children:"Administrator (abbr. Admin)\nOperator = User of an OpenStack cloud with the admin role."}),"\n",(0,n.jsx)(t.h3,{id:"default-security-groups-custom-security-groups-and-default-security-group-rules",children:"Default Security Groups, Custom Security Groups and default Security Group Rules"}),"\n",(0,n.jsx)(t.p,{children:"To properly understand the concepts in this standard and avoid ambiguity, is very important to distinguish between the following similar-sounding but different resources in the OpenStack Networking API:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"default Security Group"}),"\n",(0,n.jsx)(t.li,{children:"custom Security Group"}),"\n",(0,n.jsx)(t.li,{children:"default Security Group Rules"}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["A ",(0,n.jsx)(t.strong,{children:"default Security Group"}),' is a predefined Security Group which is automatically created once a project is created and is specific to that project.\nThis Security Group is called "default" and there exists only one per project.\nIt will automatically be assigned to VMs that have no other Security Group explicitly assigned to it, when a VM is created.']}),"\n",(0,n.jsxs)(t.p,{children:["A ",(0,n.jsx)(t.strong,{children:"custom Security Group"})," is any additional Security Group created within a project separate from the ",(0,n.jsx)(t.em,{children:"default Security Group"})," of the project."]}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.strong,{children:"default Security Group Rules"})," may target the ",(0,n.jsx)(t.em,{children:"default Security Groups"})," or the ",(0,n.jsx)(t.em,{children:"custom Security Groups"})," or both.\nThey resemble a rule template and each Security Group will be initially created with rules according to this template."]}),"\n",(0,n.jsx)(t.p,{children:"Although the rules of a Security Group may be adjusted freely after its creation, these default rule presets applied on initialization are predefined.\nIn recent OpenStack releases, both presets can be adjusted independently by administrators of the infrastructure."}),"\n",(0,n.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,n.jsxs)(t.p,{children:["The rules of a Security Group can be edited by default by any user with the member role within a project.\nBut when a Security Group is created it automatically incorporates a few SG rules that are configured as default rules.\nSince the 2023.2 release, the default set of Security Group rules can be adjusted.\nThis functionality is only available to administrators",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),".\nIn combination with the OpenStack behavior that when a VM is created with no Security Group specified, the default SG of the project is automatically applied to the ports of the VM,\na user cannot be sure which firewall rules are applied to such a VM."]}),"\n",(0,n.jsx)(t.p,{children:"Therefore this standard proposes default Security Group rules that MUST be set by administrators to avoid divergence in default network security between different IaaS environments."}),"\n",(0,n.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,n.jsx)(t.p,{children:"Up to the 2023.1 release (antelope) the default Security Group rules are hardcoded in the OpenStack code.\nWe should not require to change this behavior through code changes in deployments."}),"\n",(0,n.jsx)(t.p,{children:"Beginning with the 2023.2 release (bobcat) the default Security Group rules can now be edited by administrators through an API.\nAll rules that should be present as default in Security Groups have to be configured by admins through this API."}),"\n",(0,n.jsx)(t.p,{children:"There are two ways to approach a standard for the default rules of Security Groups."}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"There could be a set of rules standardized that has to be configured by admins."})}),"\n",(0,n.jsx)(t.p,{children:"OpenStack's default rules for Security Groups already provide a good baseline for port security, because they allow all egress traffic and for the default Security Group only ingress traffic from the same group."}),"\n",(0,n.jsx)(t.p,{children:"Allowing more rules would not benefit the security level, while reducing or limiting the existing rules would barely improve it.\nNevertheless a standard could hold up the current security level against possible future release with more open default rules.\nChanging the default rules will not change the rules of any existing Security Groups."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"With the already strict OpenStack default rules users are required in most use cases to create and manage their own Security Groups."})}),"\n",(0,n.jsxs)(t.p,{children:["This has the benefit that users need to explicitly think about the port security of their VMs and may be less likely to apply Security Groups which rules open up more ports than needed.\nThere is also a guide from the SCS project on how to set up a Security Group that also focuses on having a good port security",(0,n.jsx)(t.sup,{children:(0,n.jsx)(t.a,{href:"#user-content-fn-3",id:"user-content-fnref-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),"."]}),"\n",(0,n.jsx)(t.p,{children:"With the default OpenStack behavior of having already strict rules, which in most cases require users to manage their own Security Groups, this standard should mandate a middle way:\nIt should allow adjusting the default rules, but only to a stricter version."}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"Allowing all outgoing traffic in the default rules in combination with blocking all incoming traffic would be strict enough from a security point of view.\nAnd it would make it necessary for users to check and change the rules of their Security Group to a meaningful set."}),"\n",(0,n.jsx)(t.h3,{id:"further-annotations",children:"Further Annotations"}),"\n",(0,n.jsx)(t.p,{children:"This standard should only be applied onto versions of OpenStack that implement the new endpoint for the default Security Group rules, which would only include 2023.2 or higher releases."}),"\n",(0,n.jsx)(t.p,{children:"It is possible to have different default Security Group rules for the default SG and custom SGs.\nAnd it is arguable to have a more strict standard for default rules for the default Security Group than for the custom Security Groups.\nBecause the latter ones are not automatically applied to a VM but are always edited by the users to apply to their requirements."}),"\n",(0,n.jsx)(t.p,{children:"The allowlisting concept of Security Group rules makes it hard to allow traffic with an exception of certain ports.\nIt would be possible to just define many rules to achieve what a blocklist would achieve.\nBut having many rules may confuse users and they may not disable unnecessary default rules in their SGs."}),"\n",(0,n.jsx)(t.h2,{id:"standard",children:"Standard"}),"\n",(0,n.jsx)(t.p,{children:'The default Security Group rules for the default Security Groups SHOULD allow incoming traffic from the same Security Group.\nThe default Security Group rules for ALL Security Groups MUST NOT allow any other incoming traffic. Neither IPv4 nor IPv6.\nThis can be achieved through having ingress rules in the default Security Group rules that allow ingress traffic from the Remote Security Group "PARENT" but are only used in the default Security Group.'}),"\n",(0,n.jsx)(t.p,{children:"The default Security Group rules for ALL Security Groups SHOULD allow egress Traffic for both IPv4 and IPv6."}),"\n",(0,n.jsx)(t.h3,{id:"example",children:"Example"}),"\n",(0,n.jsx)(t.p,{children:"In the following table, there is only ingress traffic between the same default Security Groups allowed plus all egress traffic:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"$ openstack default security group rule list\n+--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+\n| ID | IP Protocol | Ethertype | IP Range | Port Range | Direction | Remote Security Group | Remote Address Group | Used in default Security Group | Used in custom Security Group |\n+--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+\n| 47b929fd-9b39-4f22-abc5- | None | IPv6 | ::/0 | | egress | None | None | True | True |\n| 7d4f64d10909 | | | | | | | | | |\n| 92a79600-5358-4fef-a390- | None | IPv4 | 0.0.0.0/0 | | egress | None | None | True | True |\n| 822665f46070 | | | | | | | | | |\n| 93e35d0c-2482-4ec1-9fbd- | None | IPv4 | 0.0.0.0/0 | | ingress | PARENT | None | True | False |\n| fd8c9a21a04e | | | | | | | | | |\n| ed5cd662-add2-4e42-b0a7- | None | IPv6 | ::/0 | | ingress | PARENT | None | True | False |\n| 3b585d348820 | | | | | | | | | |\n+--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+\n"})}),"\n",(0,n.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,n.jsxs)(t.p,{children:["The spec for introducing configurability for the default Security Groups Rules can be found ",(0,n.jsx)(t.a,{href:"https://specs.openstack.org/openstack/neutron-specs/specs/2023.2/configurable-default-sg-rules.html",children:"here"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["More about Security Groups as a resource in OpenStack can be found ",(0,n.jsx)(t.a,{href:"https://docs.openstack.org/nova/latest/user/security-groups.html",children:"here"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,n.jsxs)(t.p,{children:["The conformance tests should check for the absence of any ingress traffic rules except traffic from the same Security Group in the ",(0,n.jsx)(t.code,{children:"openstack default security group rule list"}),".\nAs having egress rules is allowed by this standard, but not forced and can be set in various ways, the tests should check for presence of any egress rules."]}),"\n","\n",(0,n.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,n.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://bugs.launchpad.net/neutron/+bug/1983053",children:"Tracking of development for editable default SG rules"})," ",(0,n.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{id:"user-content-fn-2",children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://docs.openstack.org/releasenotes/neutron/2023.2.html",children:"Release Notes of Neutron 2023.2"})," ",(0,n.jsx)(t.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{id:"user-content-fn-3",children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://docs.scs.community/docs/iaas/guides/user-guide/security-groups/",children:"Guide for Security Groups"})," ",(0,n.jsx)(t.a,{href:"#user-content-fnref-3","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>i});var n=r(96540);const s={},a=n.createContext(s);function o(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7ace79c4.595aface.js b/assets/js/7ace79c4.595aface.js new file mode 100644 index 0000000000..6ba742e768 --- /dev/null +++ b/assets/js/7ace79c4.595aface.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[974],{27845:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>d,metadata:()=>c,toc:()=>o});var n=t(74848),r=t(28453);const d={},a="scs-0111: Decisions for the Volume Type Standard",c={id:"iaas/scs-0111",title:"scs-0111: Decisions for the Volume Type Standard",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/iaas/scs-0111.md",sourceDirName:"iaas",slug:"/iaas/scs-0111",permalink:"/standards/iaas/scs-0111",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"SSD Flavors",permalink:"/standards/scs-0110-v1-ssd-flavors"},next:{title:"Decisions for the Volume Type Standard",permalink:"/standards/scs-0111-v1-volume-type-decisions"}},i={},o=[];function l(e){const s={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"scs-0111-decisions-for-the-volume-type-standard",children:"scs-0111: Decisions for the Volume Type Standard"}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Version"}),(0,n.jsx)(s.th,{children:"Type"}),(0,n.jsx)(s.th,{children:"State"}),(0,n.jsx)(s.th,{children:"stabilized"}),(0,n.jsx)(s.th,{children:"deprecated"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0111-v1-volume-type-decisions",children:"scs-0111-v1"})}),(0,n.jsx)(s.td,{children:"Decision Record"}),(0,n.jsx)(s.td,{children:"Draft"}),(0,n.jsx)(s.td,{children:"-"}),(0,n.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>a,x:()=>c});var n=t(96540);const r={},d=n.createContext(r);function a(e){const s=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(d.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7b449e09.d5ac906f.js b/assets/js/7b449e09.d5ac906f.js new file mode 100644 index 0000000000..6a6fbc2dcb --- /dev/null +++ b/assets/js/7b449e09.d5ac906f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5123],{44222:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var i=t(74848),o=t(28453);const s={title:"SCS Documentation structure",type:"Procedural",version:"2023-08-03-001",authors:"Max Wolfs",status:"Draft",track:"Global",replaces:"scs-0002-v1-standards-docs-org.md",description:"SCS-0002 outlines the standardized structure and maintenance processes for easily accessible and\ncomprehensible content of the SCS project.\n"},a=void 0,r={id:"scs-0002-v2-standards-docs-org",title:"SCS Documentation structure",description:"SCS-0002 outlines the standardized structure and maintenance processes for easily accessible and\ncomprehensible content of the SCS project.\n",source:"@site/standards/scs-0002-v2-standards-docs-org.md",sourceDirName:".",slug:"/scs-0002-v2-standards-docs-org",permalink:"/standards/scs-0002-v2-standards-docs-org",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS Documentation structure",type:"Procedural",version:"2023-08-03-001",authors:"Max Wolfs",status:"Draft",track:"Global",replaces:"scs-0002-v1-standards-docs-org.md",description:"SCS-0002 outlines the standardized structure and maintenance processes for easily accessible and\ncomprehensible content of the SCS project.\n"},sidebar:"standards",previous:{title:"Standards, Docs and Organisation",permalink:"/standards/scs-0002-v1-standards-docs-org"},next:{title:"scs-0003: Sovereign Cloud Standards YAML",permalink:"/standards/global/scs-0003"}},c={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Distributed Documentation",id:"distributed-documentation",level:2},{value:"Methodology and Taxonomy",id:"methodology-and-taxonomy",level:2},{value:"Structure Template",id:"structure-template",level:2},{value:"Single Component/Component",id:"single-componentcomponent",level:3},{value:"Overview",id:"overview",level:4},{value:"Requirements",id:"requirements",level:4},{value:"Quickstart",id:"quickstart",level:4},{value:"Configuration",id:"configuration",level:4},{value:"Contribute",id:"contribute",level:4},{value:"Technical Implementation",id:"technical-implementation",level:3},{value:"Documentation Framework",id:"documentation-framework",level:4},{value:"Special Implementation Details",id:"special-implementation-details",level:4},{value:"Writing Style and Format \u2013 Style Guide",id:"writing-style-and-format--style-guide",level:3},{value:"Formatting and Linting",id:"formatting-and-linting",level:4},{value:"Diagrams, Charts, and Images",id:"diagrams-charts-and-images",level:4},{value:"Linting",id:"linting",level:4},{value:"Pre Commit",id:"pre-commit",level:5},{value:"GitHub Workflows",id:"github-workflows",level:5},{value:"Open Questions",id:"open-questions",level:3},{value:"Reference",id:"reference",level:3}];function l(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"The Sovereign Cloud Stack (SCS) is a complex ecosystem, comprised of numerous Components and packages designed to accommodate a wide array of use cases. Given the unique functionalities of these components, the creation of a unified and comprehensible documentation presents a significant challenge. This procedural standard aims to define the structure and maintenance process for our documentation, thereby offering seamless and efficient access to users."}),"\n",(0,i.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(n.p,{children:"SCS promotes a collaborative environment by actively contributing to upstream projects. The involvement of individuals and companies within our community significantly enhances the SCS Bill of Materials (BOM), further amplifying its complexity. Consequently, our documentation must:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Offer an overview and visual representation of the architectural model"}),"\n",(0,i.jsx)(n.li,{children:"Foster coherence by maintaining a consistent theme throughout the documentation"}),"\n",(0,i.jsx)(n.li,{children:"Facilitate a transparent and inclusive community environment"}),"\n",(0,i.jsx)(n.li,{children:"Describe various deployment examples and use cases"}),"\n",(0,i.jsx)(n.li,{children:"Reflect the SCS structure in the documentation's navigation"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"distributed-documentation",children:"Distributed Documentation"}),"\n",(0,i.jsxs)(n.p,{children:["In line with the ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/doc-contrib-guide/",children:"OpenStack documentation approach"}),", most SCS Components and components maintain independent documentation. To keep this documentation up-to-date and eliminate manual duplication, we utilize a custom workflow that synchronizes individual documents during the static documentation page's build process."]}),"\n",(0,i.jsx)(n.h2,{id:"methodology-and-taxonomy",children:"Methodology and Taxonomy"}),"\n",(0,i.jsxs)(n.p,{children:["Addressing the complexity of SCS requires an effective documentation structure. Accordingly, we have adopted the ",(0,i.jsx)(n.a,{href:"https://diataxis.fr/",children:"Diataxis taxonomy"}),", categorizing the documentation into four distinct sections: Tutorials, Guides, References, and Explanations."]}),"\n",(0,i.jsx)(n.h2,{id:"structure-template",children:"Structure Template"}),"\n",(0,i.jsx)(n.p,{children:"The technical documentation and navigation should parallel the logical structure of the SCS Architecture. By doing so, users can better comprehend the information hierarchy and effectively visualize the SCS. The proposed structure is as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tree",children:"\u251c\u2500\u2500 Introduction\n\u251c\u2500\u2500 Getting Started\n\u2502 \u251c\u2500\u2500 Overview\n\u2502 \u251c\u2500\u2500 Virtualization\n\u2502 \u2514\u2500\u2500 Containerization\n\u251c\u2500\u2500 IaaS Layer\n\u2502 \u251c\u2500\u2500 Overview\n\u2502 \u2502 \u251c\u2500\u2500 Architecture\n\u2502 \u2502 \u251c\u2500\u2500 Compute\n\u2502 \u2502 \u251c\u2500\u2500 Storage\n\u2502 \u2502 \u251c\u2500\u2500 Knowledge\n\u2502 \u2502 \u2514\u2500\u2500 Network\n\u2502 \u251c\u2500\u2500 Deployment Examples\n\u2502 \u2502 \u251c\u2500\u2500 Example 1\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Hardware\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 Software\n\u2502 \u2502 \u251c\u2500\u2500 ...\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Hardware\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 Software\n\u2502 \u2502 \u2514\u2500\u2500 Example x\n\u2502 \u2502 \u251c\u2500\u2500 Hardware\n\u2502 \u2502 \u2514\u2500\u2500 Software\n\u2502 \u251c\u2500\u2500 Guides\n\u2502 \u2502 \u251c\u2500\u2500 Guide 1\n\u2502 \u2502 \u251c ...\n\u2502 \u2502 \u2514\u2500\u2500 Guide x\n\u2502 \u2514\u2500\u2500 Components\n\u2502 \u251c\u2500\u2500 Component 1\n\u2502 \u251c ...\n\u2502 \u2514\u2500\u2500 Component x\n\u251c\u2500\u2500 Container Layer\n\u2502 \u251c\u2500\u2500 Overview\n\u2502 \u2502 \u251c\u2500\u2500 Architecture\n\u2502 \u2502 \u2514\u2500\u2500 ...\n\u2502 \u251c\u2500\u2500 Prerequisites\n\u2502 \u2502 \u251c\u2500\u2500 Hardware\n\u2502 \u2502 \u251c\u2500\u2500 Software\n\u2502 \u2502 \u2514\u2500\u2500 Knowledge\n\u2502 \u251c\u2500\u2500 Guides\n\u2502 \u2502 \u251c\u2500\u2500 Guide 1\n\u2502 \u2502 \u251c\u2500\u2500 ...\n\u2502 \u2502 \u2514\u2500\u2500 Guide x\n\u2502 \u2514\u2500\u2500 Components\n\u2502 \u251c\u2500\u2500 k8s-cluster-api-provider\n\u2502 \u251c ...\n\u2502 \u2514\u2500\u2500 Component x\n\u251c\u2500\u2500 Operating SCS\n\u2502 \u251c\u2500\u2500 Overview\n\u2502 \u251c\u2500\u2500 Guides\n\u2502 \u2502 \u251c\u2500\u2500 Guide 1\n\u2502 \u2502 \u251c\u2500\u2500 ...\n\u2502 \u2502 \u2514\u2500\u2500 Guide x\n\u2502 \u251c\u2500\u2500 Monitoring\n\u2502 \u251c\u2500\u2500 Incident Management\n\u2502 \u251c\u2500\u2500 Audits\n\u2502 \u251c\u2500\u2500 Lifecycle Management: Patches/Updates & Upgrades\n\u2502 \u2514\u2500\u2500 Logging\n\u251c\u2500\u2500 Identity and Access Management (IAM)\n\u251c\u2500\u2500 Releases\n\u251c\u2500\u2500 Standards\n\u251c\u2500\u2500 FAQ\n\u2514\u2500\u2500 Glossary\n"})}),"\n",(0,i.jsx)(n.h3,{id:"single-componentcomponent",children:"Single Component/Component"}),"\n",(0,i.jsx)(n.p,{children:"The technical documentation and navigation should parallel the logical structure of the SCS Architecture. By doing so, users can better comprehend the information hierarchy and effectively visualize the SCS. The proposed structure is as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tree",children:"\u2502 \u251c\u2500\u2500 Component\n\u2502 \u2502 \u251c\u2500\u2500 overview.md\n\u2502 \u2502 \u2514\u2500\u2500 requirements.md\n\u2502 \u2502 \u251c\u2500\u2500 quickstart.md\n\u2502 \u2502 \u251c\u2500\u2500 configuration.md\n\u2502 \u2502 \u251c\u2500\u2500 contribute.md\n"})}),"\n",(0,i.jsx)(n.p,{children:"Each document serves a specific purpose:"}),"\n",(0,i.jsx)(n.h4,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(n.p,{children:'This document introduces the Component/component by addressing the basic "Why," "How," and "What" questions, and articulating the problems it solves in the broader SCS context answering the following questions:'}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"What is it and for what do I need this? What benefits does it have for users?"}),"\n",(0,i.jsx)(n.li,{children:"What organization/company does this belong to? (Link to company/organization)"}),"\n",(0,i.jsx)(n.li,{children:"Where am I \u2013 as module \u2013 within the bigger context of SCS?"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"requirements",children:"Requirements"}),"\n",(0,i.jsx)(n.p,{children:"This section enumerates the necessary prerequisites to utilize the component, including software, hardware, and any required technical knowledge. What are the minimal requirements needed for a quickstart?"}),"\n",(0,i.jsx)(n.h4,{id:"quickstart",children:"Quickstart"}),"\n",(0,i.jsx)(n.p,{children:"A concise guide providing users with a quick set up of the component, covering installation instructions, basic configuration, and initial steps. Caution: it is only for testing and not for production."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"What is the aim of this quickstart guide?"}),"\n",(0,i.jsx)(n.li,{children:"Rule: one line per command for easy copy&paste and one line for description where possible"}),"\n",(0,i.jsx)(n.li,{children:"Rule: only one working path for installation."}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"configuration",children:"Configuration"}),"\n",(0,i.jsx)(n.p,{children:"This section elaborates on the configurable aspects of the component, such as options, parameters, or settings that users can modify to suit their needs."}),"\n",(0,i.jsx)(n.h4,{id:"contribute",children:"Contribute"}),"\n",(0,i.jsx)(n.p,{children:"This document provides instructions on how interested parties can contribute to the component's development. It includes information on issue submission, proposed changes, and participation in discussions."}),"\n",(0,i.jsx)(n.h3,{id:"technical-implementation",children:"Technical Implementation"}),"\n",(0,i.jsx)(n.p,{children:"SCS employs Docusaurus, a contemporary static website generator, to implement the Docs Standard. Docusaurus serves as an ideal platform for creating, managing, and deploying extensive documentation."}),"\n",(0,i.jsx)(n.h4,{id:"documentation-framework",children:"Documentation Framework"}),"\n",(0,i.jsx)(n.p,{children:"Docusaurus' robust toolkit assists in crafting and maintaining quality documentation. It offers comprehensive features such as Markdown support, customizable themes, and versioning, making it an excellent choice for our needs. This platform allows us to create user-friendly and visually engaging documentation."}),"\n",(0,i.jsx)(n.h4,{id:"special-implementation-details",children:"Special Implementation Details"}),"\n",(0,i.jsx)(n.p,{children:"SCS's unique architecture necessitates a unique approach to documentation. To ensure seamless integration of reference documentation for Components and components developed for SCS, we have created a custom workflow. This workflow automatically syncs upstream repositories, pulling the most recent documentation at regular intervals."}),"\n",(0,i.jsxs)(n.p,{children:["We have accomplished this by utilizing a Node.js post-install script found ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs-page/blob/main/getDocs.js",children:"here"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"This script prompts the system to pull the latest docs every eight hours and build the static page. The workflow's specifications can be viewed here."}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"https://docs.scs.community/",children:"SCS documentation"})," is built by the tooling from the ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs-page/",children:"docs-page"})," repository, pulling content from ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/",children:"docs repository"})," as well as many other components as defined in the docs.package.json ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs-page/blob/main/docs.package.json",children:"here"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"writing-style-and-format--style-guide",children:"Writing Style and Format \u2013 Style Guide"}),"\n",(0,i.jsx)(n.h4,{id:"formatting-and-linting",children:"Formatting and Linting"}),"\n",(0,i.jsx)(n.p,{children:"All documentation text files must be provided as markdown files with an .md extension. This prerequisite ensures uniformity across our documents, making them more accessible and comprehensible."}),"\n",(0,i.jsx)(n.h4,{id:"diagrams-charts-and-images",children:"Diagrams, Charts, and Images"}),"\n",(0,i.jsx)(n.p,{children:"When necessary, diagrams, charts, and images can be used to simplify complex information. They should be properly captioned and referenced in the text."}),"\n",(0,i.jsx)(n.h4,{id:"linting",children:"Linting"}),"\n",(0,i.jsx)(n.p,{children:"To maintain a clean and consistent content repository, we enforce linting on:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"All staged files before committing"}),"\n",(0,i.jsx)(n.li,{children:"All Pull Requests"}),"\n"]}),"\n",(0,i.jsx)(n.h5,{id:"pre-commit",children:"Pre Commit"}),"\n",(0,i.jsxs)(n.p,{children:["We run markdownlint against staged Git files using the Husky Git hook. This process is facilitated by ",(0,i.jsx)(n.a,{href:"https://github.com/okonet/lint-staged",children:"lint-staged"})," and ",(0,i.jsx)(n.a,{href:"https://github.com/typicode/husky",children:"husky"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The markdown files are linted according to the rules specified by ",(0,i.jsx)(n.a,{href:"https://github.com/DavidAnson/markdownlint-cli2",children:"markdownlint-cli2"})," and formatted with ",(0,i.jsx)(n.a,{href:"https://github.com/prettier/prettier",children:"prettier"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The linting rules are specified in the configuration file .markdownlint-cli2.jsonc. Additionally, ",(0,i.jsx)(n.a,{href:"https://github.com/OnkarRuikar/markdownlint",children:"markdownlint-rule-search-replace"})]}),"\n",(0,i.jsx)(n.h5,{id:"github-workflows",children:"GitHub Workflows"}),"\n",(0,i.jsx)(n.p,{children:"There are two actions running on every Pull Request on the main branch:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"link-validator.yml validates every link in the markdown files."}),"\n",(0,i.jsx)(n.li,{children:"pr-markdownlint.yml checks all markdown files according to the rules defined within .markdownlint-cli2.jsonc."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The Style Guide can be found ",(0,i.jsx)(n.a,{href:"https://docs.scs.community/community/community/contribute/styleguide/",children:"here"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"open-questions",children:"Open Questions"}),"\n",(0,i.jsx)(n.p,{children:"--"}),"\n",(0,i.jsx)(n.h3,{id:"reference",children:"Reference"}),"\n",(0,i.jsx)(n.p,{children:"--"})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var i=t(96540);const o={},s=i.createContext(o);function a(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7b787d81.a054ef5e.js b/assets/js/7b787d81.a054ef5e.js new file mode 100644 index 0000000000..99a745c78b --- /dev/null +++ b/assets/js/7b787d81.a054ef5e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2257],{84387:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var s=t(74848),a=t(28453);const o={},r="Release Notes for SCS Release 0",i={id:"releases/Release0",title:"Release Notes for SCS Release 0",description:"(Release Date: 2021-07-15)",source:"@site/docs/06-releases/Release0.md",sourceDirName:"06-releases",slug:"/releases/Release0",permalink:"/docs/releases/Release0",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release0.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Releases",permalink:"/docs/category/releases"},next:{title:"Release Notes for SCS Release 1",permalink:"/docs/releases/Release1"}},l={},c=[{value:"Scope",id:"scope",level:2},{value:"Features",id:"features",level:2},{value:"Get SCS",id:"get-scs",level:2},{value:"Known Bugs",id:"known-bugs",level:2},{value:"Technical Previews",id:"technical-previews",level:2},{value:"Release tagging",id:"release-tagging",level:2},{value:"Updates",id:"updates",level:2},{value:"Bug reporting",id:"bug-reporting",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",p:"p",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"release-notes-for-scs-release-0",children:"Release Notes for SCS Release 0"}),"\n",(0,s.jsx)(n.p,{children:"(Release Date: 2021-07-15)"}),"\n",(0,s.jsx)(n.h2,{id:"scope",children:"Scope"}),"\n",(0,s.jsx)(n.p,{children:"The main focus of R0 is to demonstrate the viability of our approach to a much broader\naudience by providing a well-documented testbed. This will allow anyone interested\nto study the system in real-life, test, contribute, compare, ... it."}),"\n",(0,s.jsx)(n.p,{children:"Also we learn performing the release process."}),"\n",(0,s.jsx)(n.h2,{id:"features",children:"Features"}),"\n",(0,s.jsx)(n.p,{children:"Fully automated virtual (testbed setup) with ansible (terraform bootstrap to create\nstorage, networking and VM resources for bootstrapping via cloud-init injected\nscripts that call ansible).)"}),"\n",(0,s.jsx)(n.p,{children:"The infrastructure, management and openstack services are all deployed in containers."}),"\n",(0,s.jsx)(n.p,{children:"Included tools for Operations: ARA, Netbox, Cockpit, Netdata, Skydive (opt-in),\nPatchman, phpMyAdmin, Elasticsearch (b/f license change), Kibana, Grafana, influxdb"}),"\n",(0,s.jsx)(n.p,{children:"Validation: Rally, Refstack"}),"\n",(0,s.jsx)(n.p,{children:"Infrastructure: Linux, KVM, ceph (pacific), OpenVSwitch, OVN, MariaDB, RabbitMQ, Redis,\nEtcd, HAproxy, Keepalived, Memcached, Keycloak"}),"\n",(0,s.jsx)(n.p,{children:"IaaS (OpenStack - Wallaby): keystone, nova, glance, cinder, neutron, octavia, horizon"}),"\n",(0,s.jsx)(n.p,{children:"Optional OpenStack services: designate, heat, gnocchi, ceilometer, aodh, panko, senlin,\nbarbican, manila, magnum"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"https://docs.osism.de/testbed/overview.html#software-bill-of-materials-sbom",children:"testbed SBOM"})," for\na complete list. The exact versions of the contained components can be retrieved from the\n",(0,s.jsx)(n.a,{href:"https://github.com/osism/release/tree/master/1.0.0",children:"release repo"})," of OSISM."]}),"\n",(0,s.jsx)(n.h2,{id:"get-scs",children:"Get SCS"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/README.md",children:"main README"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"known-bugs",children:"Known Bugs"}),"\n",(0,s.jsx)(n.p,{children:"Nothing major known yet."}),"\n",(0,s.jsx)(n.h2,{id:"technical-previews",children:"Technical Previews"}),"\n",(0,s.jsx)(n.p,{children:"While already in productive use (on bare metal) by two providers, the bare metal\nsetup currently has a few more manual steps than we would like. This will improve\nwith the next releases."}),"\n",(0,s.jsx)(n.p,{children:"We have worked hard on supporting identity federation (OIDC and SAML) during the last\nfew months. We have also spent significant effort on getting the k8s stack with\nk8s cluster API into a good shape. However, we have determined that we do not\nyet consider those two key pieces as production-ready. The goal is to change that\nfor R1 (see below)."}),"\n",(0,s.jsx)(n.p,{children:"For now, you can use the software to see where SCS is going and test our technical\npreview code. We really appreciate feedback we get on these pieces as well.\nHowever keep in mind that we do not guarantee to ship technical previews from\na Release as production-ready software in one of the next releases. We certainly\nhope to do so."}),"\n",(0,s.jsxs)(n.p,{children:["To test how our k8s aaS platform will look like, have a look at the\n",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"k8s-cluster-api-provider repository"}),"\nYou can follow the documentation to set up the k8s cluster API on an SCS\ncloud (or other well configured OpenStack clouds that support octavia)."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor",children:"openstack-health-monitor"}),"\nis used by us to monitor that the API works and successfully creates working resources\nin finite time. We plan to integrate it with a dashboard and an alarming mechanism in\nthe next releases."]}),"\n",(0,s.jsx)(n.h2,{id:"release-tagging",children:"Release tagging"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Release-Numbering-Scheme.md",children:"Release Numbering scheme"}),".\nThe containers have version number v1.0.0 for R0."]}),"\n",(0,s.jsx)(n.h2,{id:"updates",children:"Updates"}),"\n",(0,s.jsxs)(n.p,{children:["Updating the software can conveniently be done from the manager node by running the\nansible playbooks again. Details are in the\n",(0,s.jsx)(n.a,{href:"https://docs.osism.tech/testbed/usage.html#update-services",children:"OSISM testbed documentation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"bug-reporting",children:"Bug reporting"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/README.md",children:"main README"})," file."]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var s=t(96540);const a={},o=s.createContext(a);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7bd33c3d.3e0ed241.js b/assets/js/7bd33c3d.3e0ed241.js new file mode 100644 index 0000000000..e77bf8f132 --- /dev/null +++ b/assets/js/7bd33c3d.3e0ed241.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[192],{98817:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>a});var s=t(74848),i=t(28453);const c={title:"Getting Started with OpenStack",version:new Date("2023-08-04T00:00:00.000Z"),author:"Ralf Heiringhoff, Eduard Itrich, Mathias Fechner"},r=void 0,o={id:"cloud-resources/getting-started-openstack",title:"Getting Started with OpenStack",description:"Getting Started with OpenStack CLI",source:"@site/community/cloud-resources/getting-started-openstack.md",sourceDirName:"cloud-resources",slug:"/cloud-resources/getting-started-openstack",permalink:"/community/cloud-resources/getting-started-openstack",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Getting Started with OpenStack",version:"2023-08-04T00:00:00.000Z",author:"Ralf Heiringhoff, Eduard Itrich, Mathias Fechner"},sidebar:"community",previous:{title:"Test and development cloud resources",permalink:"/community/cloud-resources/"},next:{title:"Getting Started Gaia-X Demonstrator @ plusserver",permalink:"/community/cloud-resources/plusserver-gx-scs"}},l={},a=[{value:"Getting Started with OpenStack CLI",id:"getting-started-with-openstack-cli",level:2},{value:"OpenStackClient (CLI)",id:"openstackclient-cli",level:2},{value:"Object Storage (S3)",id:"object-storage-s3",level:2},{value:"References",id:"references",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h2:"h2",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"getting-started-with-openstack-cli",children:"Getting Started with OpenStack CLI"}),"\n",(0,s.jsx)(n.h2,{id:"openstackclient-cli",children:"OpenStackClient (CLI)"}),"\n",(0,s.jsx)(n.p,{children:"The OpenStackClient is installable via all major Linux Distributions:"}),"\n",(0,s.jsx)(n.p,{children:"for debian and ubuntu with apt:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo apt install python3-openstackclient\n"})}),"\n",(0,s.jsx)(n.p,{children:"for ubuntu with snap openstack CLI is installable too:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo snap install openstackclients\n"})}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"[!NOTE]\nVersions from Linux repository could be in a stable but old state."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Install it directly via ",(0,s.jsx)(n.a,{href:"https://pypi.org/project/python-openstackclient",children:"pypi"}),"\nfrom upstream is the recommend way."]}),"\n",(0,s.jsx)(n.p,{children:"Here for example RHEL:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo dnf install python3 python3-devel gcc python3-pip\n"})}),"\n",(0,s.jsx)(n.p,{children:"Here for example Debian and Ubuntu:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo apt install python3-minimal python3-pip python3-venv python3-dev build-essential\n"})}),"\n",(0,s.jsx)(n.p,{children:"Here as example for SUSE"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo zypper in python3-pip python3-venv python3-dev\n"})}),"\n",(0,s.jsx)(n.p,{children:"Here for example with Apple's MacOS"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"brew install python3\n"})}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["[!NOTE]\nPython installation for windows systems please use the ",(0,s.jsx)(n.a,{href:"https://www.python.org/downloads/windows/",children:"python installation guide"}),"\nor recommend use the ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/de-de/windows/wsl/install",children:"Linux Subsystem WSL"})]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Python Virtualenv"}),"\n",(0,s.jsx)(n.p,{children:"It is also recommended to use virtual environments, here as an example for\nLinux and MacOS:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"python3 -m venv oscli\nsource oscli/bin/activate\npip install --upgrade pip\npip install python-openstackclient \\\npython-cinderclient \\\npython-designateclient \\\npython-glanceclient \\\npython-neutronclient \\\npython-novaclient \\\npython-octaviaclient \\\npython-barbicanclient\n\n"})}),"\n",(0,s.jsxs)(n.p,{children:["For further Information see the OpenStack Project upstream website\n",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/python-openstackclient/latest/index.html",children:"python-openstackclient"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This repo holds examples for ",(0,s.jsx)(n.a,{target:"_blank","data-noBrokenLinkCheck":!0,href:t(31814).A+"",children:"clouds-public.yaml"})," + ",(0,s.jsx)(n.a,{target:"_blank","data-noBrokenLinkCheck":!0,href:t(14486).A+"",children:"clouds.yaml"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Alternatively you can download an OpenRC Environment file when you're logged\nin to Horizon:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["upper right side ","\u27a1\ufe0f"," ",(0,s.jsx)(n.code,{children:"<your login name>"})]}),"\n",(0,s.jsx)(n.li,{children:"OpenStack RC File"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ source ./<$yourfile>-openrc.sh\nPlease enter your OpenStack Password for project XXX as user YYY:\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"openstack --help\n"})}),"\n",(0,s.jsxs)(n.p,{children:["when you're using clouds.yaml you can specify multiple endpoints and\nselect the specific endpoint by passing ",(0,s.jsx)(n.code,{children:"--os-cloud="})," to the\nopenstack cmdline or setting ",(0,s.jsx)(n.code,{children:"OS_CLOUD"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"openstack --os-cloud MYCLOUD\n"})}),"\n",(0,s.jsx)(n.p,{children:"or"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"export OS_CLOUD=MYCLOUD\nopenstack\n"})}),"\n",(0,s.jsxs)(n.p,{children:["OpenStack Client in action inside of the OSISM testbed:\n",(0,s.jsx)(n.img,{alt:"Example OpenStackClient in testbed",src:t(77508).A+"",width:"2520",height:"1098"})]}),"\n",(0,s.jsx)(n.h2,{id:"object-storage-s3",children:"Object Storage (S3)"}),"\n",(0,s.jsxs)(n.p,{children:["Create AWS like credentials with ",(0,s.jsx)(n.code,{children:"openstack ec2 credentials create"}),".\nIf you use libs3, store the access field in ",(0,s.jsx)(n.code,{children:"S3_ACCESS_KEY_ID"})," and the secret\nfield in",(0,s.jsx)(n.code,{children:"S3_SECRET_ACCESS_KEY"})," and set ",(0,s.jsx)(n.code,{children:"S3_HOSTNAME=<Object Storage endpoint>"}),".\nYou will see the same buckets (containers) and objects whether you access your\nobject store via the swift or via the s3 protocol."]}),"\n",(0,s.jsx)(n.h2,{id:"references",children:"References"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://www.openstack.org",title:"OpenStack Site",children:"OpenStack"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack",title:"SovereignCloudStack on github",children:"SovereignCloudStack"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/osism",title:"OSISM on github",children:"OSISM"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/collections/openstack/cloud/index.html",title:"Ansible Module OpenStack",children:"ansible"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs",title:"OpenStack Terraform Provider",children:"terraform"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://cloudinit.readthedocs.io/en/latest/",title:"cloud-init documentation",children:"cloud-init"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},31814:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/files/clouds-public-e9ba939dfde1c0efe3a32ec6f5d1f612.yaml"},14486:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/files/clouds.yaml-9c0c983f9c293bc5adeae683d442174e.sample"},77508:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/getting_started_openstack_anim-d88d134eff244cf8891c5ca1efcfc65a.gif"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var s=t(96540);const i={},c=s.createContext(i);function r(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7bed4829.f6c31600.js b/assets/js/7bed4829.f6c31600.js new file mode 100644 index 0000000000..fcf83d3e46 --- /dev/null +++ b/assets/js/7bed4829.f6c31600.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4984],{20186:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var r=s(74848),t=s(28453);const a={},o="Backup and restore",i={id:"container/components/container-registry/docs/backup_and_restore",title:"Backup and restore",description:"This page aims at providing a step-by-step guide for backup and restore Harbor",source:"@site/docs/03-container/components/container-registry/docs/backup_and_restore.md",sourceDirName:"03-container/components/container-registry/docs",slug:"/container/components/container-registry/docs/backup_and_restore",permalink:"/docs/container/components/container-registry/docs/backup_and_restore",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/backup_and_restore.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Upgrade",permalink:"/docs/container/components/container-registry/docs/upgrade"},next:{title:"Migration",permalink:"/docs/container/components/container-registry/docs/migration"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Kubernetes cluster",id:"kubernetes-cluster",level:3},{value:"S3 bucket and EC2 credentials",id:"s3-bucket-and-ec2-credentials",level:3},{value:"Velero client",id:"velero-client",level:3},{value:"Velero server",id:"velero-server",level:3},{value:"Backup and restore",id:"backup-and-restore-1",level:2},{value:"Backup Harbor Instance",id:"backup-harbor-instance",level:3},{value:"Restore Harbor Instance",id:"restore-harbor-instance",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"backup-and-restore",children:"Backup and restore"}),"\n",(0,r.jsxs)(n.p,{children:["This page aims at providing a step-by-step guide for backup and restore ",(0,r.jsx)(n.a,{href:"https://goharbor.io/",children:"Harbor"}),"\ncontainer registry using ",(0,r.jsx)(n.a,{href:"https://velero.io/",children:"Velero"})," tool.\nIt extends the official ",(0,r.jsx)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/",children:"Harbor backup-restore docs page"}),"\nwith up-to-date commands, explanations, and an extensive prerequisites section. This\nguide references and uses Velero in ",(0,r.jsx)(n.a,{href:"https://github.com/vmware-tanzu/velero/releases/tag/v1.10.2",children:"v1.10.2"}),"\nas this is the latest stable version at the time of writing this guide."]}),"\n",(0,r.jsx)(n.p,{children:"It provides guidance and commands that readers are encouraged to try out by themselves\non Harbor deployment as described in the next sections. It does not aim at providing an\nexhaustive list of commands nor all the possible ways how to use them."}),"\n",(0,r.jsx)(n.p,{children:"The guide covers two strategies to save Harbor data:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Backup: a regular backup created by the ",(0,r.jsx)(n.a,{href:"https://restic.net/",children:"restic"})," integration in Velero as described in the related ",(0,r.jsx)(n.a,{href:"https://velero.io/docs/main/file-system-backup/",children:"docs"})]}),"\n",(0,r.jsxs)(n.li,{children:["Snapshot: a point-in-time snapshot be the Container Storage Interface (CSI) snapshot support in Velero as described in the related ",(0,r.jsx)(n.a,{href:"https://velero.io/docs/main/csi/",children:"docs"})]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Before you choose the right strategy for your Harbor deployment backup, make sure that you understand\n",(0,r.jsx)(n.a,{href:"https://www.terra-master.com/global/snapshot",children:"differences"})," between the backup and snapshot.\nIn general, for long-term protection of Harbor data, you may use backup and for\ntemporary protection of data (e.g. before Harbor upgrade) you may use snapshot."]}),"\n",(0,r.jsxs)(n.p,{children:["Note that this guide is not limited to Harbor deployments that utilize SCS environments,\nbut it is required to have a set of tools and services (e.g. Kubernetes CSI plugin with volume snapshot\nsupport, S3 compatible object store for backups) for successful backup and restore procedure\n(see the ",(0,r.jsx)(n.a,{href:"#prerequisites",children:"prerequisites"})," section). These tools and services come out of\nthe box when the SCS infrastructure and KaaS are used for Harbor deployment, hence it is\nconvenient to use them."]}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsx)(n.h3,{id:"kubernetes-cluster",children:"Kubernetes cluster"}),"\n",(0,r.jsxs)(n.p,{children:["If you want to use ",(0,r.jsx)(n.code,{children:"snapshot"})," to back up Harbor data ensure the following:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Your cluster is Kubernetes version 1.20 or greater"}),"\n",(0,r.jsxs)(n.li,{children:["Your cluster is running a ",(0,r.jsx)(n.a,{href:"https://kubernetes-csi.github.io/docs/drivers.html",children:"CSI driver"}),"\ncapable of support volume snapshots at the ",(0,r.jsx)(n.a,{href:"https://kubernetes.io/blog/2020/12/10/kubernetes-1.20-volume-snapshot-moves-to-ga/",children:"v1 API level"}),".\nTo enable creating volume snapshots, the ",(0,r.jsx)(n.a,{href:"https://kubernetes-csi.github.io/docs/snapshot-controller.html",children:"snapshot-controller"}),"\nand its CRDs should be deployed in the Kubernetes cluster as well. The snapshot-controller\nis independent of any CSI Driver. These prerequisites come out of the box with the SCS KaaS solution."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["If you want to create Harbor ",(0,r.jsx)(n.code,{children:"backup"})," ensure the following:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Your cluster is Kubernetes version 1.16 or greater"}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["If your cluster meets the above, export its kubeconfig path in env. variable ",(0,r.jsx)(n.code,{children:"KUBECONFIG"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"export KUBECONFIG=/path/to/kubeconfig\n"})}),"\n",(0,r.jsx)(n.h3,{id:"s3-bucket-and-ec2-credentials",children:"S3 bucket and EC2 credentials"}),"\n",(0,r.jsx)(n.p,{children:"This guide assumes that the public cloud's object store with S3-compatible API is available as\nthe storage backend for Velero. In this guide, we are using OpenStack Swift which\noffers S3-compatible API. Let's create an S3 bucket on Swift object storage and EC2 credentials\nthat will be later used by Velero."}),"\n",(0,r.jsx)(n.p,{children:"You should have access to your OpenStack project, and the OpenStack RC file that contains access\nvalues. Set the environment variables by sourcing the OpenStack RC file:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"source <project>-openrc.sh\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Swift object store service does not support application credentials authentication\nto access S3 API. To authenticate in S3 API, you should generate and use the EC2 credentials\nmechanism.\nNote that EC2 credentials are associated with a user and are scoped only to a specific project.\nEC2 credentials are not protected by limited roles, expiration time, or\naccess rules, therefore they have the same access as the user who created them. If you\nwant to restrict EC2 credentials you could use application credentials for their creation,\nthen EC2 credentials should inherit a (potentially) limited subset of roles that creator\nowns (see ",(0,r.jsx)(n.a,{href:"https://opendev.org/openstack/keystone/commit/487c7276c7608fb11086b9875b0d7cc7cf594a5a",children:"this"})," for details)."]}),"\n",(0,r.jsx)(n.p,{children:"You can generate EC2 credentials as follows:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"$ openstack ec2 credentials create\n+------------+----------------------------------------------------------------------------------------------------------+\n| Field | Value |\n+------------+----------------------------------------------------------------------------------------------------------+\n| access | <aws_access_key_id> |\n| links | {'self': 'https://api.gx-scs.sovereignit.cloud:5000/v3/users/<user_id>/credentials/OS-EC2/<project_id>'} |\n| project_id | <project_id> |\n| secret | <aws_secret_access_key> |\n| trust_id | None |\n| user_id | <user_id> |\n+------------+----------------------------------------------------------------------------------------------------------+\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Write down ",(0,r.jsx)(n.code,{children:"aws_access_key_id"})," and ",(0,r.jsx)(n.code,{children:"aws_secret_access_key"})," values from the output of ",(0,r.jsx)(n.code,{children:"openstack ec2 credentials create"}),"\ncommand and store them in the ",(0,r.jsx)(n.code,{children:"~/.aws/credentials"})," file as follows:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"mkdir ~/.aws\ncat >~/.aws/credentials <<EOF\n[default]\naws_access_key_id = <aws_access_key_id>\naws_secret_access_key = <aws_secret_access_key>\nEOF\n"})}),"\n",(0,r.jsx)(n.p,{children:"This credential file is then used as an access and secret source for AWS CLI tool and also\nas a source for Velero. If your environment does not have AWS CLI installed, install it as follows:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"pip3 install awscli awscli-plugin-endpoint\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Finally, create a new bucket. Note that the following command contains ",(0,r.jsx)(n.code,{children:"endpoint-url"}),"\nargument that points AWS CLI to the GX-SCS OpenStack Swift object store API."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"aws --endpoint-url https://api.gx-scs.sovereignit.cloud:8080 s3 mb s3://velero-backup\n"})}),"\n",(0,r.jsx)(n.h3,{id:"velero-client",children:"Velero client"}),"\n",(0,r.jsxs)(n.p,{children:["In this guide, we are using ",(0,r.jsx)(n.a,{href:"https://velero.io/",children:"Velero"})," to back up and restore a Harbor instance.\nVelero is an open source tool to safely back up and restore, perform disaster recovery,\nand migrate Kubernetes cluster resources."]}),"\n",(0,r.jsxs)(n.p,{children:["Go through the ",(0,r.jsx)(n.a,{href:"https://velero.io/docs/main/basic-install/",children:"official docs"})," and\ninstall the Velero client on your desired environment. If your environment is Linux distribution\nyou can use the following steps and install the Velero client from the GitHub release binaries:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"wget https://github.com/vmware-tanzu/velero/releases/download/v1.10.2/velero-v1.10.2-linux-amd64.tar.gz \ntar -zxvf velero-v1.10.2-linux-amd64.tar.gz \nsudo mv velero-v1.10.2-linux-amd64/velero /usr/local/bin/\n"})}),"\n",(0,r.jsx)(n.h3,{id:"velero-server",children:"Velero server"}),"\n",(0,r.jsxs)(n.p,{children:["Install Velero server components along with the appropriate plugins, into the Kubernetes cluster.\nThis will create a namespace called ",(0,r.jsx)(n.code,{children:"velero"}),", and place a deployment named ",(0,r.jsx)(n.code,{children:"velero"})," in it.\nNote that the installation command sets the bucket ",(0,r.jsx)(n.code,{children:"velero-backup"})," that has been created a few steps\nearlier as well as EC2 credentials located in ",(0,r.jsx)(n.code,{children:"~/.aws/credentials"})," file. Also note that\nthe ",(0,r.jsx)(n.code,{children:"region"})," and ",(0,r.jsx)(n.code,{children:"s3Url"})," parameters are GX-SCS specific. For further details about installation\noptions, supported storage providers, and more visit the official Velero ",(0,r.jsx)(n.a,{href:"https://velero.io/docs/",children:"docs"}),"."]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["If you want to use ",(0,r.jsx)(n.code,{children:"snapshot"})," to back up Harbor data:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Install Velero:"}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:' velero install \\\n --features=EnableCSI \\\n --provider aws \\\n --plugins velero/velero-plugin-for-aws:v1.6.1,velero/velero-plugin-for-csi:v0.4.2 \\\n --bucket velero-backup \\\n --secret-file ~/.aws/credentials \\\n --backup-location-config region=RegionOne,s3ForcePathStyle="true",s3Url=https://api.gx-scs.sovereignit.cloud:8080 \\\n --snapshot-location-config region=RegionOne,enableSharedConfig=true\n'})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"In order to allow Velero to do Volume Snapshots, we need to deploy a new VolumeSnapshotClass. Create a velero-snapclass.yaml file as follows:"}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'cat > velero-snapclass.yaml << EOF\napiVersion: snapshot.storage.k8s.io/v1\ndeletionPolicy: Delete\ndriver: cinder.csi.openstack.org\nkind: VolumeSnapshotClass\nmetadata:\n name: csi-cinder-snapclass-in-use-v1-velero\n labels:\n velero.io/csi-volumesnapshot-class: "true"\nparameters:\n force-create: "true"\nEOF\n'})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Apply the new class:"}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f velero-snapclass.yaml\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["If you want to create Harbor ",(0,r.jsx)(n.code,{children:"backup"})," with Restic:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Install Velero:"}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'velero install \\\n --provider aws \\\n --plugins velero/velero-plugin-for-aws:v1.6.1 \\\n --bucket velero-backup \\\n --secret-file ~/.aws/credentials \\\n --use-volume-snapshots=false \\\n --uploader-type=restic \\\n --use-node-agent \\\n --backup-location-config region=RegionOne,s3ForcePathStyle="true",s3Url=https://api.gx-scs.sovereignit.cloud:8080\n'})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"backup-and-restore-1",children:"Backup and restore"}),"\n",(0,r.jsxs)(n.p,{children:["Note that the following backup steps mainly point to actions from an official ",(0,r.jsx)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore",children:"Backup And Restore Harbor With Velero"})," tutorial.\nIn this guide, find the added value from additional explanations/hints and up-to-date commands."]}),"\n",(0,r.jsxs)(n.p,{children:["Harbor, by design, consists of multiple (micro)services that could store their data\nvariously, based on the Harbor configuration. See the ",(0,r.jsx)(n.a,{href:"/docs/container/components/container-registry/docs/persistence",children:"Harbor persistence"}),'\ndocs for further information regarding the Harbor persistence layer. The following steps cover\ncases when Harbor persistence is enabled and the "internal" databases (PostgreSQL and Redis)\nare used.']}),"\n",(0,r.jsx)(n.p,{children:'Note that Redis key-value database is not backed up in both cases, i.e. when "internal"\nor "external" Redis instance is used. As a result, the user sessions of logged users\nthat are stored in Redis will be lost. Hence, after the restore, users should log in\nagain. This data loss should be a low impact on your restored Harbor instance.'}),"\n",(0,r.jsx)(n.p,{children:'PostgreSQL database should be backed up as it stores important metadata of Harbor models,\nlike projects, users, roles, etc. The backup and restore of "internal" PostgreSQL instance\nis covered by this guide. The "external" PostgreSQL backup is not supported by the\nofficial tutorial and is out of the scope of this guide as well.'}),"\n",(0,r.jsxs)(n.p,{children:["Also, keep an eye on the official backup and restore ",(0,r.jsx)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#limitations",children:"limitations"}),"\nsection to be aware of the potential impact on your Harbor instance. The limitation:\n",(0,r.jsx)(n.code,{children:"The upload purging process may cause backup failure"})," mentioned that it is better to\nincrease registry upload purging interval (it is a background process that periodically\nremoves orphaned files from the upload directories of the registry, see the ",(0,r.jsx)(n.a,{href:"https://docs.docker.com/registry/configuration/#uploadpurging",children:"docs"}),").\nThis interval is by ",(0,r.jsx)(n.a,{href:"https://github.com/goharbor/harbor-helm/blob/master/values.yaml#L598",children:"default"}),"\nset to 24h (helm value: ",(0,r.jsx)(n.code,{children:"registry.upload_purging.interval"}),"). If you do not want to change\nthe registry configuration at all you should ensure that the backup will be performed in\nthe middle of two rounds of purging. This background process starts when the registry\ncontainer is initialized, therefore is a good idea to check logs of the registry container\nand determine when is a good time to do a backup, e.g. as follows:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'$ kubectl logs -l component=registry -c registry --tail -1 | grep -i purge\ntime="2023-04-17T09:02:08.320514706Z" level=info msg="Starting upload purge in 24h0m0s" go.version=go1.15.6 instance.id=xxx service=registry version=v2.7.1.m \ntime="2023-04-17T09:09:08.321004645Z" level=info msg="PurgeUploads starting: olderThan=2023-04-10 09:09:08.320738572 +0000 UTC m=-604379.969424455, actuallyDelete=true" \ntime="2023-04-17T09:09:08.331433127Z" level=info msg="Purge uploads finished. Num deleted=0, num errors=0" \n...\n'})}),"\n",(0,r.jsx)(n.h3,{id:"backup-harbor-instance",children:"Backup Harbor Instance"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#set-harbor-to-readonly",children:["Set Harbor to the ",(0,r.jsx)(n.code,{children:"ReadOnly"})," mode"]})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Backup Harbor:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Using ",(0,r.jsx)(n.code,{children:"snapshot"})," to back up Harbor data:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Exclude the volume of Redis in backup, we need to label the Redis pod, PVC and PV with specific label:","\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# label the Pod of Redis, replace the namespace and Pod name with yours\n kubectl -n default label pod/harbor-harbor-redis-0 velero.io/exclude-from-backup=true\n # label the PVC of Redis, replace the namespace and PVC name with yours\n kubectl -n default label pvc/data-harbor-harbor-redis-0 velero.io/exclude-from-backup=true\n # get the name of Redis PV, replace the namespace and PVC name with yours\n kubectl -n default get pvc data-harbor-harbor-redis-0 --template={{.spec.volumeName}}\n # label the PV of Redis, replace the pv-name with the one get from last command\n kubectl label pv/pv-name velero.io/exclude-from-backup=true\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Back up Harbor","\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# replace the namespace and backup name with yours\nvelero backup create harbor-backup --include-namespaces default --snapshot-volumes --wait\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Using ",(0,r.jsx)(n.code,{children:"Restic"})," to back up Harbor data:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Exclude the volume of Redis in backup","\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# replace the namespace and pod name with yours\nkubectl -n default annotate pod/harbor-harbor-redis-0 backup.velero.io/backup-volumes-excludes=data\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Back up Harbor","\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"velero backup create harbor-backup --include-namespaces default --default-volumes-to-fs-backup --wait\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#unset-readonly",children:["Unset Harbor from the ",(0,r.jsx)(n.code,{children:"ReadOnly"})," mode"]})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"restore-harbor-instance",children:"Restore Harbor Instance"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#restore-harbor-instance",children:"Restore Harbor Instance"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>i});var r=s(96540);const t={},a=r.createContext(t);function o(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7cf96b3e.a51eef9c.js b/assets/js/7cf96b3e.a51eef9c.js new file mode 100644 index 0000000000..44c10ab137 --- /dev/null +++ b/assets/js/7cf96b3e.a51eef9c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5770],{62305:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var r=s(74848),n=s(28453);const o={title:"Security Groups Decision Record",type:"Decision Record",status:"Draft",track:"IaaS"},i=void 0,a={id:"scs-0113-v1-security-groups-decision-record",title:"Security Groups Decision Record",description:"Introduction",source:"@site/standards/scs-0113-v1-security-groups-decision-record.md",sourceDirName:".",slug:"/scs-0113-v1-security-groups-decision-record",permalink:"/standards/scs-0113-v1-security-groups-decision-record",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Security Groups Decision Record",type:"Decision Record",status:"Draft",track:"IaaS"},sidebar:"standards",previous:{title:"scs-0113: Security Groups Decision Record",permalink:"/standards/iaas/scs-0113"},next:{title:"scs-0114: Volume Type Standard",permalink:"/standards/iaas/scs-0114"}},c={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Context",id:"context",level:2},{value:"Reasons for and against a standard for security groups",id:"reasons-for-and-against-a-standard-for-security-groups",level:3},{value:"Technical limitations",id:"technical-limitations",level:3},{value:"Option 0: Pre-Requirement: default rules for the (default) security group",id:"option-0-pre-requirement-default-rules-for-the-default-security-group",level:3},{value:"Option 1: operator usage of network rbac",id:"option-1-operator-usage-of-network-rbac",level:3},{value:"Option 2: stay project-scoped",id:"option-2-stay-project-scoped",level:3},{value:"Option 3: security-focused guide",id:"option-3-security-focused-guide",level:3},{value:"Decisions",id:"decisions",level:2},{value:"Consequences",id:"consequences",level:2},{value:"Related Documents",id:"related-documents",level:2}];function u(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",section:"section",sup:"sup",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsx)(t.p,{children:"Security Groups in IaaS (OpenStack) are sets of ip table rules, that are applied to ports which connect a virtual machine to a network.\nIn contrast to other resources like flavors or volume types that are always publicly accessible, or images that can be both public and private, security groups are always bound to the project level.\nThat creates some difficulties for a possible standard of Security Groups, which are discussed in this document."}),"\n",(0,r.jsx)(t.h2,{id:"terminology",children:"Terminology"}),"\n",(0,r.jsx)(t.p,{children:"Security Group\nA set of iptables rules that is applied to ports connecting a virtual machine and a network."}),"\n",(0,r.jsx)(t.p,{children:"Security Group Rule (abbr. Rule)\nThis references a single rule within a security group."}),"\n",(0,r.jsx)(t.p,{children:"RBAC\nRole Based Access Control used for policies and alike."}),"\n",(0,r.jsx)(t.p,{children:"network rbac / neutron rbac\nThese access controls will let administrators and users share neutron related resources with other projects."}),"\n",(0,r.jsx)(t.p,{children:"admin\nThe most powerful role in OpenStack. Only given to some Operators of the Cloud Infrastructure."}),"\n",(0,r.jsx)(t.h2,{id:"context",children:"Context"}),"\n",(0,r.jsxs)(t.p,{children:["While creating a virtual machine and also later on, one or more security groups can be added to it.\nWhen there is no security group specified the default security group will always be added.\nLike every other security group, the default group is also project bound.\nThat means, it can be edited as required by project members.\nBy design of OpenStack and when not changed, default rules in the default security group block all incoming traffic except from the same Security Group and only allow outgoing traffic",(0,r.jsx)(t.sup,{children:(0,r.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"reasons-for-and-against-a-standard-for-security-groups",children:"Reasons for and against a standard for security groups"}),"\n",(0,r.jsx)(t.p,{children:"Considering having most likely similiar security groups within different projects, it might make sense to standardize a few security groups for often used cases like ssh, http, https and maybe icmp.\nWhat speaks for standardizing a certain set of security groups:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Having a set of correctly configured security groups could reduce misconfiguration from users"}),"\n",(0,r.jsx)(t.li,{children:"Re-using correctly configured security groups saves time for users"}),"\n",(0,r.jsx)(t.li,{children:"Auditing security groups would be way easier for operators when helping customers"}),"\n",(0,r.jsx)(t.li,{children:"The configuration for the Security Groups can be done by networking experts, which may result in a higher security level as when users without expertise configure them"}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"What are the downsides of having a set of standardized security groups:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"A bug or misconfiguration is a single point of failure for ALL customers"}),"\n",(0,r.jsx)(t.li,{children:"Users might apply the wrong security group to their port or VM because they lack the domain knowledge, unknowingly opening themselves to attacks"}),"\n",(0,r.jsx)(t.li,{children:"Users will not inspect such default security groups: this may result in applying a wrong group and opening traffic too much"}),"\n",(0,r.jsx)(t.li,{children:"the central authority managing the groups does not necessarily know the usecase of the user, the user/operator must know best what kind of security their workload needs. What is a necessary port for 99% of deployments might be a security disaster for my deployment"}),"\n",(0,r.jsx)(t.li,{children:"Providing default groups could have the effect of stopping customers to think about their specific security needs and instead just copying default groups and or rules"}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"This leads to a conclusion, that a set of default security groups is only more valuable than harmful for users:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"when the rules in those groups are configured correctly"}),"\n",(0,r.jsx)(t.li,{children:"and when the users still have to think about their network security on their own for each VM they start"}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"technical-limitations",children:"Technical limitations"}),"\n",(0,r.jsx)(t.p,{children:"As security groups are project bound and there is no native way to them to be shared, we are left with three options:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["To use another endpoint ",(0,r.jsx)(t.code,{children:"network rbac"})," to share security groups among different projects."]}),"\n",(0,r.jsx)(t.li,{children:"To adhere to the project scope of security groups and only give documentation about recommended security groups to users."}),"\n",(0,r.jsx)(t.li,{children:"To only add a tutorial on how to create your own security group in general, how to detect what kind of network permissions your project needs for most frequent (linux) workloads and how to craft your own security groups in a secure way."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"option-0-pre-requirement-default-rules-for-the-default-security-group",children:"Option 0: Pre-Requirement: default rules for the (default) security group"}),"\n",(0,r.jsx)(t.p,{children:"For every project that is created there will also be a project-specific default security group created.\nThe default rules for the default groups and all other newly created groups can be looked up like this:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"stack@devstack:~/devstack$ openstack default security group rule list\n+------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+\n| ID | IP Protocol | Ethertype | IP Range | Port Range | Direction | Remote Security Group | Remote Address Group | Used in default Security Group | Used in custom Security Group |\n+------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+\n| 47b929fd-9b39-4f22- | None | IPv6 | ::/0 | | egress | None | None | True | True |\n| abc5-7d4f64d10909 | | | | | | | | | |\n| 6ace51bb-5258-45ab- | None | IPv6 | ::/0 | | ingress | PARENT | None | True | False |\n| 9ba9-1efbebfb086b | | | | | | | | | |\n| 92a79600-5358-4fef- | None | IPv4 | 0.0.0.0/0 | | egress | None | None | True | True |\n| a390-822665f46070 | | | | | | | | | |\n| 997bb0c2-652e-4d1f- | None | IPv4 | 0.0.0.0/0 | | ingress | PARENT | None | True | False |\n| b910-e12c89f88b44 | | | | | | | | | |\n+------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+\n"})}),"\n",(0,r.jsxs)(t.p,{children:["Those rules can be edited, which may pose a security risk for customers consuming the default security group.\nThis should be adressed as a pre-requirement ",(0,r.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/issues/521",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"option-1-operator-usage-of-network-rbac",children:"Option 1: operator usage of network rbac"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"network rbac"})," endpoint",(0,r.jsx)(t.sup,{children:(0,r.jsx)(t.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})})," manages the possibitity to share and access certain network-specific resources such as security groups.\nFor admins it is possible to use this endpoint to share a security group with ALL projects within the the cloud including ALL projects of ALL domains:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"stack@devstack:~/devstack$ openstack network rbac create --target-all-projects --action access_as_shared --type security_group group-for-everyone\n+-------------------+--------------------------------------+\n| Field | Value |\n+-------------------+--------------------------------------+\n| action | access_as_shared |\n| id | 394d8e71-143f-4c5b-a72f-cd10af3222df |\n| object_id | b6a3834a-f89c-47a9-9ed6-ca89e93701c4 |\n| object_type | security_group |\n| project_id | 15f2ab0eaa5b4372b759bde609e86224 |\n| target_project_id | * |\n+-------------------+--------------------------------------+\n"})}),"\n",(0,r.jsx)(t.p,{children:"This would fulfill our goal to grant access to predefined security groups for all projects and all groups recieved as shared do not count into the projects quota for security groups.\nBut there are a few downsides to this:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"This should be strictly bound to the admin: no other user should be able to share security groups so to not confuse user."}),"\n",(0,r.jsxs)(t.li,{children:["The managing of those ",(0,r.jsx)(t.code,{children:"network rbac"})," objects can get out of hand pretty quickly, because there neither is an explicit name for such an object nor do the names of the shared objects appear:"]}),"\n"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"stack@devstack:~/devstack$ openstack network rbac list --long\n+-----------------------------+----------------+-----------------------------+--------------------+\n| ID | Object Type | Object ID | Action |\n+-----------------------------+----------------+-----------------------------+--------------------+\n| 97507e4c-7413-4d61-ab21- | security_group | 110b1bea-f0e0-4fb7-9fc7- | access_as_shared |\n| 047fc23516dd | | cda1b6f927b0 | |\n| bc22a865-46f9-4cd2-80af- | security_group | 5f22e42e-95dc-4c0a-8651- | access_as_shared |\n| 3c249ba0e010 | | 57b1dfc8639f | |\n| 2467806f-5428-4506-8e23- | network | 02ef8579-9917-4a01-893d- | access_as_shared |\n| f4690db04e01 | | cb2f9f3d5f98 | |\n| ed40996e-218d-4daa-b222- | network | 73edb86b-d7ab-4db3-82b7- | access_as_external |\n| f3c603a5b8a6 | | 25fa8b012e40 | |\n| 45e0a707-af82-42a6-b93f- | subnetpool | cd7addd1-05d9-48a8-bc38- | access_as_shared |\n| efde18216f13 | | 4a581354983f | |\n| e514c2c8-65ac-4062-8b03- | subnetpool | ad1cc1ed-3261-4df2-8c73- | access_as_shared |\n| fe24f6fc4656 | | c3dd72d59061 | |\n+-----------------------------+----------------+-----------------------------+--------------------+\nstack@devstack:~/devstack$ openstack network rbac show bc22a865-46f9-4cd2-80af-3c249ba0e010\n+-------------------+--------------------------------------+\n| Field | Value |\n+-------------------+--------------------------------------+\n| action | access_as_shared |\n| id | bc22a865-46f9-4cd2-80af-3c249ba0e010 |\n| object_id | 5f22e42e-95dc-4c0a-8651-57b1dfc8639f |\n| object_type | security_group |\n| project_id | 15f2ab0eaa5b4372b759bde609e86224 |\n| target_project_id | * |\n+-------------------+--------------------------------------+\n"})}),"\n",(0,r.jsx)(t.p,{children:"The biggest downside: As soon as a security group is shared, everyone from every project, can edit the rules of this group."}),"\n",(0,r.jsx)(t.h3,{id:"option-2-stay-project-scoped",children:"Option 2: stay project-scoped"}),"\n",(0,r.jsx)(t.p,{children:"Using and adhering the project scope of the security groups has the consequence, that:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"either an admin has to set up security groups for each project"}),"\n",(0,r.jsx)(t.li,{children:"or the SCS project only provides a guide on how to setup and use some recommended security groups."}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"As users are allowed to, will and should edit their security groups, there is no way to ensure, that a certain set of security groups with certain rules is always present in a project.\nSo packing an extra burden on admins is unreasonable.\nThe option to give a guide and recommend a few security groups however is a quite good option."}),"\n",(0,r.jsx)(t.h3,{id:"option-3-security-focused-guide",children:"Option 3: security-focused guide"}),"\n",(0,r.jsx)(t.p,{children:"Instead of providing users with a set of default groups or the knowledge about how to create default groups, there could be a guide created that focuses on the crafting of a security group in a secure way.\nThat would include identifying what kind of network permission a single VM needs and how to proceed after gathering all requirements of the customers workload."}),"\n",(0,r.jsx)(t.h2,{id:"decisions",children:"Decisions"}),"\n",(0,r.jsx)(t.p,{children:"The default Security Group Rules should be standardized as a pre-requirement (Option 0)."}),"\n",(0,r.jsxs)(t.p,{children:["Using the ",(0,r.jsx)(t.code,{children:"network rbac"})," endpoint (Option 1) would not solve the idea of having pre-defined and administrator audited Security Groups, because it is possible for any user to edit the rules of shared Security Groups.\nInstead the project-scope of the Security Groups should by focused and a guide prepared, that gives insight about creating and using Security Groups with a few examples but with a clear security focus (Mix of Option 2 and 3)."]}),"\n",(0,r.jsx)(t.h2,{id:"consequences",children:"Consequences"}),"\n",(0,r.jsx)(t.p,{children:"Any CSP will have to follow the standard for the default Security Group Rules.\nThere are no consequences regarding Security Groups as it and users stay in full control and responsible for their own Security Groups"}),"\n",(0,r.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/pull/525",children:"A PR to standardize default Security Group Rules"}),"\n",(0,r.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/docs/pull/142",children:"A PR to a first draft for a guide for security groups"})]}),"\n","\n",(0,r.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,r.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://github.com/openstack/neutron/blob/master/neutron/db/migration/alembic_migrations/versions/2023.2/expand/c33da356b165_security_group_default_rules.py",children:"Default Security Group Rules"})," ",(0,r.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{id:"user-content-fn-2",children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://docs.openstack.org/neutron/latest/admin/config-rbac.html",children:"Neutron RBAC"})," ",(0,r.jsx)(t.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>a});var r=s(96540);const n={},o=r.createContext(n);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7d3935d1.75c6af94.js b/assets/js/7d3935d1.75c6af94.js new file mode 100644 index 0000000000..965dc32c94 --- /dev/null +++ b/assets/js/7d3935d1.75c6af94.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2683],{69654:(e,r,s)=>{s.r(r),s.d(r,{assets:()=>u,contentTitle:()=>o,default:()=>d,frontMatter:()=>n,metadata:()=>a,toc:()=>c});var t=s(74848),i=s(28453);const n={},o="Best Practise: How to configure and use security groups",a={id:"iaas/guides/user-guide/security-groups/security-groups",title:"Best Practise: How to configure and use security groups",description:"Security groups in OpenStack are part of the network security mechanisms provided for the users.",source:"@site/docs/02-iaas/guides/user-guide/security-groups/security-groups.md",sourceDirName:"02-iaas/guides/user-guide/security-groups",slug:"/iaas/guides/user-guide/security-groups/",permalink:"/docs/iaas/guides/user-guide/security-groups/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/security-groups/security-groups.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"User Data Backups",permalink:"/docs/iaas/guides/user-guide/openstack/user-data-backups"},next:{title:"User Data Backups",permalink:"/docs/iaas/guides/user-guide/user-data-backups"}},u={},c=[{value:"Identify the requirements of your setup",id:"identify-the-requirements-of-your-setup",level:2},{value:"Further security considerations",id:"further-security-considerations",level:3},{value:"How to create security groups",id:"how-to-create-security-groups",level:2},{value:"Default security group",id:"default-security-group",level:3},{value:"Recommended security groups",id:"recommended-security-groups",level:3},{value:"How to use security groups",id:"how-to-use-security-groups",level:2}];function l(e){const r={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.h1,{id:"best-practise-how-to-configure-and-use-security-groups",children:"Best Practise: How to configure and use security groups"}),"\n",(0,t.jsx)(r.p,{children:"Security groups in OpenStack are part of the network security mechanisms provided for the users.\nThey resemble sets of simple firewall rules allowing specific network traffic at a Port of a VM that connects it to a network.\nThe rules allow specific network port numbers and protocols while also differentiating between ingress and egress directions.\nUsually security groups are assigned to the Port(s) when a virtual machine is created, but assignments can also be changed at runtime later on.\nMultiple security groups can be assigned to a VM or Port simultaneously and in such case they will be combined as the union of all their rules."}),"\n",(0,t.jsx)(r.admonition,{type:"caution",children:(0,t.jsxs)(r.p,{children:["Security groups are mutable resources.\nTheir rules can be adjusted at any time after creation.\n",(0,t.jsx)(r.strong,{children:"Changing the rules of a security group will immediately apply the changes to all Ports or VMs it is assigned to."}),"\nIt is advisable to always review resources which use a security group before making changes to it."]})}),"\n",(0,t.jsx)(r.h2,{id:"identify-the-requirements-of-your-setup",children:"Identify the requirements of your setup"}),"\n",(0,t.jsx)(r.p,{children:"Every virtual machine that is created may need different firewall rules.\nThese requirements can also change over time.\nAdding or removing security groups will allow users to adapt the firewall rules specifically to their virtual machines."}),"\n",(0,t.jsx)(r.p,{children:"To harden the firewall settings for your virtual machine you may follow these steps:"}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"Before creating a virtual machine its purpose is usually already known. Use this information to identify all incoming and outgoing traffic rules that will be needed based on the communication patterns of the services it is meant to deploy. This includes communication protocols, port numbers, communication directions and optionally target/source address ranges."}),"\n",(0,t.jsx)(r.li,{children:"Look through already existing security groups and their rules. If a security group allows more traffic than needed it SHOULD NOT be used. If a security group contains only a subset of the required rules it MAY be used in combination with other security groups that contain rules which fulfill the remaining required traffic rules from point 1."}),"\n",(0,t.jsx)(r.li,{children:"If you were not successful in finding an appropriate combination of existing security groups or you need additional specific rules to cover all requirements, you MAY create one or more new Security Groups in which you can add the required rules."}),"\n",(0,t.jsx)(r.li,{children:"After ensuring the existence of one or more security groups that fulfill your requirements, you can create the VM with those security groups already specified in the creation command."}),"\n"]}),"\n",(0,t.jsx)(r.h3,{id:"further-security-considerations",children:"Further security considerations"}),"\n",(0,t.jsx)(r.p,{children:"When implementing network security requirements, firewall rules alone are not always sufficient and might need to be augmented with additional configuration or time-based constraints. Notable examples are:"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"SSH"}),"\nSSH is needed on many virtual machines to operate their guest operating system.\nIn a security group the port 22 can be opened for the TCP protocol to allow incoming SSH connections.\nBut that only should be done while also restricting the SSH configuration to public key authentication only (the recommended way) or having a strong username and password policy already applied to the operating system of the virtual machine.\nOtherwise default usernames and passwords which are often preconfigured in system images may be exploited through the exposed SSH port which enables attackers to compromise the virtual machine."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"ICMP"}),"\nIt might be useful to be able to ping a virtual machine or use other ICMP requests.\nBut for some virtual machine configurations this is either not necessary at all or only temporarily needed.\nOne benefit of security groups among other things is the ability to be easily added to and removed from existing virtual machines.\nSo a dedicated security group allowing ICMP could be added temporarily to a virtual machine for debugging purposes and removed from it afterwards."]}),"\n",(0,t.jsx)(r.h2,{id:"how-to-create-security-groups",children:"How to create security groups"}),"\n",(0,t.jsx)(r.p,{children:"Security groups are managed within a project.\nSo every project will have a different set of security groups.\nThey can be added dynamically to each virtual machine, during their creation or afterwards.\nAdditionally, they may also be removed from VMs at any point."}),"\n",(0,t.jsx)(r.p,{children:"Every project has its own default security group, which rules can be edited.\nAdditionally other security groups can be added until the project's quota is exhausted.\nTo add a security group, use the following command:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group create $SECURITY_GROUP\n"})}),"\n",(0,t.jsx)(r.p,{children:"Within every security group rules can be added up unto a defined maximum of rules, that usually is about 100.\nRules can be added to security groups with the following command:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group rule create [...] $SECURITY_GROUP\n"})}),"\n",(0,t.jsx)(r.p,{children:"To delete rules from a security group, the rule id has to be used.\nIt is listed in the details of the rules section of the security group."}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group rule delete $RULE_ID\n"})}),"\n",(0,t.jsx)(r.h3,{id:"default-security-group",children:"Default security group"}),"\n",(0,t.jsx)(r.p,{children:"Unless specified otherwise, the default security group is assigned to all VMs or Ports at creation.\nTo use any other than the default security group at creation it is necessary to specify the desired security group(s) during the creation process."}),"\n",(0,t.jsx)(r.p,{children:"To review which rules are defined in a security group, the following command can be used:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group show default\n"})}),"\n",(0,t.jsx)(r.h3,{id:"recommended-security-groups",children:"Recommended security groups"}),"\n",(0,t.jsx)(r.p,{children:"While projects can use very different aspects in security group rules and thus the security groups will always differ between projects, there are some security groups that are widely used.\nThrough the nature of security groups being seen as a set of rules that can be combined, having some basic security groups that allow basic protocols is a commonly used setup.\nThis section will demonstrate how to create some security groups for commonly used protocols and ports."}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"A security groups, that allows incoming SSH traffic:"}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group create ssh\nopenstack security group rule create --ingress --protocol tcp --dst-port 22 ssh\n"})}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"A security group, that allows incoming HTTP requests:"}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group create http\nopenstack security group rule create --ingress --protocol tcp --dst-port 80 http\n"})}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"A security group, that allows incoming HTTPS requests:"}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group create https\nopenstack security group rule create --ingress --protocol tcp --dst-port 443 https\n"})}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"A security group, that allows incoming ICMP requests:"}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group create icmp\nopenstack security group rule create --protocol icmp icmp\n"})}),"\n",(0,t.jsx)(r.h2,{id:"how-to-use-security-groups",children:"How to use security groups"}),"\n",(0,t.jsx)(r.admonition,{type:"info",children:(0,t.jsx)(r.p,{children:"Security groups can be assigned to multiple resources simultaneously (such as VMs or Ports).\nThis means that security groups are reusable and don't need to be recreated for each applicable resource individually."})}),"\n",(0,t.jsxs)(r.p,{children:["Usually, initial security groups are added at the time of the creation of a VM.\nDuring creation, multiple security groups can also be added at the same time by repeating the ",(0,t.jsx)(r.code,{children:"--security-group"})," argument:"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack server create [...] --security-group $SECURITY_GROUP_1 --security-group $SECURITY_GROUP_2 $SERVER_NAME\n"})}),"\n",(0,t.jsx)(r.p,{children:"To add a security group to an existing VM, the following command can be used:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack server add security group $SERVER_NAME $SECURITY_GROUP\n"})}),"\n",(0,t.jsx)(r.p,{children:"To remove a security group from a VM, the following command can be used:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack server remove security group $SERVER_NAME $SECURITY_GROUP\n"})})]})}function d(e={}){const{wrapper:r}={...(0,i.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,r,s)=>{s.d(r,{R:()=>o,x:()=>a});var t=s(96540);const i={},n=t.createContext(i);function o(e){const r=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(n.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7e7cf0e4.889e6837.js b/assets/js/7e7cf0e4.889e6837.js new file mode 100644 index 0000000000..7fea053562 --- /dev/null +++ b/assets/js/7e7cf0e4.889e6837.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4612],{57550:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>d,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var n=s(74848),r=s(28453);const a={},d="scs-0003: Sovereign Cloud Standards YAML",o={id:"global/scs-0003",title:"scs-0003: Sovereign Cloud Standards YAML",description:"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,",source:"@site/standards/global/scs-0003.md",sourceDirName:"global",slug:"/global/scs-0003",permalink:"/standards/global/scs-0003",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"SCS Documentation structure",permalink:"/standards/scs-0002-v2-standards-docs-org"},next:{title:"Sovereign Cloud Standards YAML",permalink:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml"}},i={},c=[];function l(e){const t={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"scs-0003-sovereign-cloud-standards-yaml",children:"scs-0003: Sovereign Cloud Standards YAML"}),"\n",(0,n.jsx)(t.p,{children:"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings,\ncategorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning\nin a machine-readable YAML format for clarity, traceability, and tool integration."}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",children:"scs-0003-v1"})}),(0,n.jsx)(t.td,{children:"Procedural"}),(0,n.jsx)(t.td,{children:"Draft"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>d,x:()=>o});var n=s(96540);const r={},a=n.createContext(r);function d(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7ebec009.418e9656.js b/assets/js/7ebec009.418e9656.js new file mode 100644 index 0000000000..9c8107e42d --- /dev/null +++ b/assets/js/7ebec009.418e9656.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5564],{82592:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var t=s(74848),r=s(28453);const a={},o="Migration to KaaS v2",c={id:"container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2",title:"Migration to KaaS v2",description:"From R6, k8s-cluster-api-provider repository (SCS KaaS reference implementation v1) is deprecated",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc/usage",slug:"/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2.md",tags:[],version:"current",frontMatter:{}},l={},i=[{value:"Migration",id:"migration",level:2},{value:"Steps",id:"steps",level:3}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"migration-to-kaas-v2",children:"Migration to KaaS v2"}),"\n",(0,t.jsx)(n.p,{children:"From R6, k8s-cluster-api-provider repository (SCS KaaS reference implementation v1) is deprecated\nand should not be used for new deployments. We intend to remove it with the next release (R7)."}),"\n",(0,t.jsxs)(n.p,{children:["Therefore, it is recommended to migrate to ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks",children:"Cluster Stacks"})," - SCS\nKaaS reference implementation v2. For list of known issues and in restrictions KaaS v2 see ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/release-notes/blob/main/Release6.md#kaas-2",children:"SCS R6 Release Notes"}),".\nWe will try to address most of the gaps during the next release cycle (R7)."]}),"\n",(0,t.jsx)(n.h2,{id:"migration",children:"Migration"}),"\n",(0,t.jsxs)(n.p,{children:["In R6, we migrated to ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R6.md#clusterclass",children:"ClusterClass"}),"\nfeature to ease the migration to KaaS v2, because Cluster Classes are the main component there. So this guide will work\nonly on release >= R6 (use upgrade ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/doc/Upgrade-Guide.md",children:"guide"}),"\nfirst, when you are on release < R6)."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["Warning: This guide supports only ",(0,t.jsx)(n.code,{children:"cilium"})," CNI (the only CNI Cluster Addon in KaaS v2)"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["Warning: After the migration, ",(0,t.jsx)(n.code,{children:"create_cluster.sh"})," and other KaaS v1 scripts and features should not be used anymore"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"steps",children:"Steps"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Deploy KaaS v1, e.g.:","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-terraform",children:'cloud_provider = "gx-scs"\navailability_zone = "nova"\ncontroller_flavor = "SCS-2V-4"\nworker_flavor = "SCS-2V-4"\ndns_nameservers = ["62.138.222.111", "62.138.222.222"]\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Deploy ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/",children:"CSO"})," and ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-provider-openstack",children:"CSPO"}),":","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["deploy with make (access token optional and recommended)","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make deploy-cso GIT_ACCESS_TOKEN=<github-access-token>\nmake deploy-cspo GIT_ACCESS_TOKEN=<github-access-token>\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Export ",(0,t.jsx)(n.code,{children:"${PREFIX}"})," and ",(0,t.jsx)(n.code,{children:"${CLUSTER_NAME}"}),":","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:". ~/bin/cccfg.inc\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Patch secret with ",(0,t.jsx)(n.code,{children:"cloudName"}),":","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'kubectl patch secret -n ${CLUSTER_NAME} ${CLUSTER_NAME}-cloud-config -p \'{"stringData":{"cloudName":"\'"${PREFIX}-${CLUSTER_NAME}"\'"}}\'\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Create Cluster Stack:","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'kubectl -n ${CLUSTER_NAME} apply -f - <<EOF\napiVersion: clusterstack.x-k8s.io/v1alpha1\nkind: ClusterStack\nmetadata:\n name: scs\nspec:\n provider: openstack\n name: scs\n kubernetesVersion: "1.28"\n channel: stable\n autoSubscribe: false\n providerRef:\n apiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1\n kind: OpenStackClusterStackReleaseTemplate\n name: cspotemplate\n versions:\n - v1\n---\napiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1\nkind: OpenStackClusterStackReleaseTemplate\nmetadata:\n name: cspotemplate\nspec:\n template:\n spec:\n identityRef:\n kind: Secret\n name: ${CLUSTER_NAME}-cloud-config\nEOF\n'})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ kubectl -n ${CLUSTER_NAME} get clusterstack\nNAME PROVIDER CLUSTERSTACK K8S CHANNEL AUTOSUBSCRIBE USABLE LATEST AGE REASON MESSAGE\nscs openstack scs 1.28 stable false v1 openstack-scs-1-28-v1 | v1.28.7 15m\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Migrate Cluster to KaaS v2:","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'cat << "EOF" | clusterctl generate yaml --config ~/${CLUSTER_NAME}/clusterctl.yaml | kubectl -n ${CLUSTER_NAME} apply -f -\napiVersion: cluster.x-k8s.io/v1beta1\nkind: Cluster\nmetadata:\n name: ${CLUSTER_NAME}\nspec:\n clusterNetwork:\n pods:\n cidrBlocks: ["${POD_CIDR}"]\n services:\n cidrBlocks: ["${SERVICE_CIDR}"]\n serviceDomain: "cluster.local"\n topology:\n variables:\n - name: dns_nameservers\n value: ${OPENSTACK_DNS_NAMESERVERS}\n - name: controller_flavor\n value: ${OPENSTACK_CONTROL_PLANE_MACHINE_FLAVOR}\n - name: worker_flavor\n value: ${OPENSTACK_NODE_MACHINE_FLAVOR}\n - name: controller_root_disk\n value: ${CONTROL_PLANE_ROOT_DISKSIZE}\n - name: worker_root_disk\n value: ${WORKER_ROOT_DISKSIZE}\n - name: external_id\n value: ${OPENSTACK_EXTERNAL_NETWORK_ID}\n - name: node_cidr\n value: ${NODE_CIDR}\n - name: openstack_security_groups\n value: [${PREFIX}-allow-ssh, ${PREFIX}-allow-icmp, ${PREFIX}-${CLUSTER_NAME}-cilium]\n - name: cloud_name\n value: ${OPENSTACK_CLOUD}\n - name: secret_name\n value: ${CLUSTER_NAME}-cloud-config\n - name: controller_server_group_id\n value: ${OPENSTACK_SRVGRP_CONTROLLER}\n - name: worker_server_group_id\n value: ${OPENSTACK_SRVGRP_WORKER}\n - name: ssh_key\n value: ${OPENSTACK_SSH_KEY_NAME}\n class: openstack-scs-1-28-v1\n version: ${KUBERNETES_VERSION}\n controlPlane:\n replicas: ${CONTROL_PLANE_MACHINE_COUNT}\n workers:\n machineDeployments:\n - class: openstack-scs-1-28-v1-md-0-no1\n name: "${PREFIX}-${CLUSTER_NAME}-md-0-no1"\n replicas: ${WORKER_MACHINE_COUNT}\n failureDomain: ${OPENSTACK_FAILURE_DOMAIN}\nEOF\n'})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["Note: If you are using flavors with a disk, comment ",(0,t.jsx)(n.code,{children:"controller_root_disk"})," and ",(0,t.jsx)(n.code,{children:"worker_root_disk"})," variables"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Fix metrics-server Cluster Addon:","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'$ kubectl -n ${CLUSTER_NAME} get clusteraddon\nNAME CLUSTER READY AGE REASON MESSAGE\ncluster-addon-testcluster testcluster false 20m FailedToApplyObjects failed to successfully apply everything\n$ KUBECONFIG=~/${CLUSTER_NAME}/${CLUSTER_NAME}.yaml kubectl delete deployment -n kube-system metrics-server\ndeployment.apps "metrics-server" deleted\n$ kubectl -n ${CLUSTER_NAME} get clusteraddon\nNAME CLUSTER READY AGE REASON MESSAGE\ncluster-addon-testcluster testcluster true 25m\n'})}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var t=s(96540);const r={},a=t.createContext(r);function o(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7f1a31c3.1c30dcee.js b/assets/js/7f1a31c3.1c30dcee.js new file mode 100644 index 0000000000..12e6ae1e7e --- /dev/null +++ b/assets/js/7f1a31c3.1c30dcee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9464],{13257:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var t=s(74848),i=s(28453);const r={},o="Release Notes for SCS Release 2",a={id:"releases/Release2",title:"Release Notes for SCS Release 2",description:"(Release Date: 2022-03-23)",source:"@site/docs/06-releases/Release2.md",sourceDirName:"06-releases",slug:"/releases/Release2",permalink:"/docs/releases/Release2",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release2.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Release Notes for SCS Release 1",permalink:"/docs/releases/Release1"},next:{title:"Release Notes for SCS Release 3",permalink:"/docs/releases/Release3"}},l={},d=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"New Features (Highlights)",id:"new-features-highlights",level:2},{value:"Operator focused improvements",id:"operator-focused-improvements",level:3},{value:"SCS Developer focused improvements (testbed)",id:"scs-developer-focused-improvements-testbed",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Cluster Management",id:"cluster-management",level:3},{value:"OSISM",id:"osism",level:3},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Resolved Issues",id:"resolved-issues",level:2},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R2",id:"list-of-known-issues--restrictions-in-r2",level:2},{value:"Future directions (selected Highlights)",id:"future-directions-selected-highlights",level:2},{value:"Contributing",id:"contributing",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"release-notes-for-scs-release-2",children:"Release Notes for SCS Release 2"}),"\n",(0,t.jsx)(n.p,{children:"(Release Date: 2022-03-23)"}),"\n",(0,t.jsx)(n.h2,{id:"scope",children:"Scope"}),"\n",(0,t.jsx)(n.p,{children:"Main goals for Release 2 (R2) were massive improvements in bare\nmetal deployment and our cluster management layer gaining the\nability to handle many clusters independently with a number\nof optional services."}),"\n",(0,t.jsx)(n.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["We support the latest ",(0,t.jsx)(n.a,{href:"https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.22.md",children:"Kubernetes 1.22"})," and\n",(0,t.jsx)(n.a,{href:"https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.23.md",children:"1.23"})," releases."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["The Kubernetes Cluster API is now available in a stable v1beta1\n",(0,t.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api/releases",children:"release 1.0.x"}),"\nwith the corresponding ",(0,t.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api/releases",children:"cluster-api-provider-openstack 0.5.x"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["There are a number of new standard services available for the\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/",children:"k8s capi"}),"\nmanaged clusters, amongst which cert-manager and flux. The clusters\nhave better default settings for the nginx-ingress, anti-affinity\nfor the nodes and the ability to chose cilium over calico and\nto have stable multi-controller node setups on clouds without\nlow-latency local storage.\nPlease consult the\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/master/Release-Notes-R2.md",children:"k8s capi provider release notes"}),"\nfor more details."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"https://releases.openstack.org/xena/highlights.html",children:"OpenStack Xena release"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"We have also enabled SPICE support in addition to noVNC to\naccess the graphical console of VMs."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["The base infrastructure is provided by\n",(0,t.jsx)(n.a,{href:"https://github.com/osism/release/blob/main/notes/3.0.0/NOTES.md",children:"OSISM 3.0.0"}),"\nwhich in turn build on top of kolla and kolla-ansible."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"new-features-highlights",children:"New Features (Highlights)"}),"\n",(0,t.jsx)(n.h3,{id:"operator-focused-improvements",children:"Operator focused improvements"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"The Cluster Management Node is now well prepared to manage numerous\nclusters with independent settings and different feature sets by\ncreating default settings and then keeping track of various workload\nclusters in own directories. Documentation has been vastly improved."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"The Cluster Management node now gets its artifacts directly from\ngit, making incremental updates to it a lot easier, thus also\navoiding to disrupt workload clusters through redeployed management\nnodes to roll out updates."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Added dashboards for the operators:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Homer"}),"\n",(0,t.jsx)(n.li,{children:"Flower"}),"\n",(0,t.jsx)(n.li,{children:"Grafana dashboards"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Work is underway to supersede ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor",children:"openstack-health-monitor"}),"\nwith a solution that is using tempest and rally. The health-monitor\nhas received improvements though and is at this point still fully\nsupported and recommended -- it has surfaced a number of issues with\ntest clouds, especially failed metadata services."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"User federation has been prepared to be ready for Gaia-X federation integration"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Keystone can consume users from Keycloak via OpenID-Connect"}),"\n",(0,t.jsx)(n.li,{children:"Keycloak uses the highly-available Galera database cluster now"}),"\n",(0,t.jsx)(n.li,{children:"mod_oauth2 support for Keystone"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Vast improvements in the SCS Deployment automation"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Full automation of bare metal deployment with Bifrost and Ironic"}),"\n",(0,t.jsx)(n.li,{children:"Using NetBox as central source of truth for the complete setup"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"New services available (opt-in)"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"ClamAV, dnsdist, cgit, FRRouting, Nexus, Tang"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Traefik centrally routes the connections to Nexus, NetBox, phpMyAdmin, Homer, Flower, ARA, cgit"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"scs-developer-focused-improvements-testbed",children:"SCS Developer focused improvements (testbed)"}),"\n",(0,t.jsx)(n.p,{children:"We now have scripts that allow us to connect to the workload cluster node network\nfor debugging purposes."}),"\n",(0,t.jsx)(n.p,{children:"The configuration of the testbed was minimized and the deployment was made more production-oriented."}),"\n",(0,t.jsx)(n.p,{children:"Further noteworthy improvements to testbed:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"TLS is implemented throughout the services also in testbed"}),"\n",(0,t.jsx)(n.li,{children:"Virtual BMC in testbed"}),"\n",(0,t.jsxs)(n.li,{children:["Public DNS for testbed (",(0,t.jsx)(n.code,{children:"testbed.osism.xyz"}),")"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"We have a Zuul CI framework running and started migrating CI testing from github actions to\nusing our Zuul infrastructure."}),"\n",(0,t.jsx)(n.p,{children:"Renovate is being used to keep the pinned versions up-to-date and consistent across the\nmany repositories."}),"\n",(0,t.jsxs)(n.p,{children:["An overview over the used software versions is available from the\n",(0,t.jsx)(n.a,{href:"https://github.com/osism/release",children:"OSISM release"})," repository as input\nfor a complete SBOM. This allows to e.g. investigate the contents of the\nused (v3.0.0) images."]}),"\n",(0,t.jsx)(n.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,t.jsx)(n.h3,{id:"cluster-management",children:"Cluster Management"}),"\n",(0,t.jsxs)(n.p,{children:["The names of a few settings have changed since R1 -- if you have diverged from the defaults,\nthis may require adjusting the ",(0,t.jsx)(n.code,{children:"environment.tfvars"})," or the ",(0,t.jsx)(n.code,{children:"clusterctl.yaml"})," files.\nSee ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/master/Release-Notes-R2.md#incompatible-changes",children:"k8s-cluster-api-provider Release Notes"}),"\nfor more details."]}),"\n",(0,t.jsx)(n.p,{children:"The updating approach has fundamentally changed:\nIf you were used to deploy fresh management nodes regularly to\nbenefit from the upstream improvements, this need has been vastly reduced now,\nallowing for long-living management nodes and workload clusters managed by them."}),"\n",(0,t.jsx)(n.h3,{id:"osism",children:"OSISM"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Playbook generic-configuration.yml was deprecated. From now on, please use the playbook of\nthe same name in the manager environment (manager-configuration.yml). All configuration\nparameters from environments/configuration.yml should be moved to environments/manager/configuration.yml."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"In kolla-ansible the haproxy role was renamed to loadbalancer. Accordingly, loadbalancer must now be\nused for the deployment of HAProxy."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"removals",children:"Removals"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"OpenStack Victoria images are no longer built and thus no longer kept updated"}),"\n",(0,t.jsx)(n.li,{children:"Support for Zabbix has been removed, Prometheus will be used as the only monitoring stack in the future"}),"\n",(0,t.jsx)(n.li,{children:"Heimdall as a service was removed, as an alternative Homer is now available"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,t.jsxs)(n.p,{children:["Deprecations happen according to our ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Release-Policies.md#deprecation",children:"deprecation policy"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Cockpit is deprecated in favor of Boundary by HashiCorp or Teleport"}),"\n",(0,t.jsx)(n.li,{children:"ceph-ansible is deprecated in preparation for cephadm"}),"\n",(0,t.jsx)(n.li,{children:"All osism- scripts on the manager are deprecated and will be replaced by the new OSISM CLI. The scripts will be removed in the next release"}),"\n",(0,t.jsx)(n.li,{children:"The following services are currently not used and are deprecated and scheduled for removal as of now: Falco, Jenkins, Rundeck, Lynis, Trivy"}),"\n",(0,t.jsx)(n.li,{children:"Heat will no longer be offered by default in the testbed in the future"}),"\n",(0,t.jsx)(n.li,{children:"The docker-compose CLI will be removed and replaced by the new compose plugin for Docker.\ndocker-compose is then no longer available and docker compose must be used instead"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The Elasticsearch container included in OSISM testbed was exposed to the log4j\nissue -- new images were provided for addressing this. See the\n",(0,t.jsx)(n.a,{href:"https://scs.community/de/security/2021/12/13/advisory-log4j/",children:"security advisory"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"resolved-issues",children:"Resolved Issues"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"The nginx-ingress loadbalancer could run into name conflicts before.\nThe loadbalancer now uses a health monitor to avoid routing to the wrong\nnodes, which typically resulted in 10s delays when connecting to the service\nbehind the ingress controller."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"cAdvisor has now reduced number of Prometheus metrics and labels exported by\ndefault - this will ease the load on the system.\nThis implies that corresponding time series data will no longer be created."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,t.jsxs)(n.p,{children:["The clusters created with our cluster-API cluster management solution pass\nthe ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Image-Properties-Spec.md",children:"CNCF conformance tests"}),"\nas reported by ",(0,t.jsx)(n.a,{href:"https://sonobuoy.io/",children:"sonobuoy"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://openstack.org/",children:"OpenStack"})," layer passes the\n",(0,t.jsx)(n.a,{href:"https://openinfra.dev/",children:"OIF"})," trademark tests, so cloud providers\nleveraging the stack should easily be able to achieve the\n",(0,t.jsx)(n.a,{href:"https://www.openstack.org/brand/interop/",children:'"OpenStack powered compute"'}),"\ntrademark certification."]}),"\n",(0,t.jsxs)(n.p,{children:["Our partner plusserver has ",(0,t.jsx)(n.a,{href:"https://www.openstack.org/brand/interop/",children:"achieved"}),"\na ",(0,t.jsx)(n.a,{href:"https://www.bsi.bund.de/EN/Topics/CloudComputing/Compliance_Criteria_Catalogue/Compliance_Criteria_Catalogue_node.html",children:"BSI C5"}),"\nsecurity certification for their SCS implementation pluscloud open."]}),"\n",(0,t.jsxs)(n.p,{children:["We are working within ",(0,t.jsx)(n.a,{href:"https://gaia-x.eu/",children:"Gaia-X"})," to further the power\nof Gaia-X self-descriptions and are closely working with the\n",(0,t.jsx)(n.a,{href:"https://gxfs.de/",children:"GXFS project"}),"\nto jointly deliver a standard toolbox for Gaia-X compliant\ninfrastructure and service offerings."]}),"\n",(0,t.jsxs)(n.p,{children:["The SCS standards for ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/flavor-naming.md",children:"flavor naming"})," and\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Image-Properties-Spec.md",children:"image metadata"}),"\nare largely unchanged since R1. We have however\nmade progress in our reference implementation fully implementing\nthem without any further tweaks."]}),"\n",(0,t.jsx)(n.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,t.jsxs)(n.p,{children:["See ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Release-Numbering-Scheme.md",children:"Release Numbering scheme"})," -- unchanged from R0.\nWe have added the tag ",(0,t.jsx)(n.code,{children:"v3.0.0"})," to the relevant repositories to designate the ",(0,t.jsx)(n.code,{children:"SCS_RELEASE_R2"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Note that we will release R3 (v4.0.0) in September 2022 and stop providing maintenance\nupdates for R2 at the end of October."}),"\n",(0,t.jsx)(n.h2,{id:"list-of-known-issues--restrictions-in-r2",children:"List of known issues & restrictions in R2"}),"\n",(0,t.jsx)(n.h2,{id:"future-directions-selected-highlights",children:"Future directions (selected Highlights)"}),"\n",(0,t.jsxs)(n.p,{children:["Alongside with R2 we published a blog post on some first thoughts on\n",(0,t.jsx)(n.a,{href:"https://scs.community/tech/2022/03/23/r2-and-future-directions/",children:"future directions towards R3"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"contributing",children:"Contributing"}),"\n",(0,t.jsxs)(n.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,t.jsx)(n.a,{href:"https://scs.community/docs/contributor/",children:"contributor guide"}),".\nWe also have worked on a ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/pull/26",children:"Code of Conduct"}),"\nto document the expected behavior of contributors and how we deal with\ncases where individuals fail to meet the expectation."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const i={},r=t.createContext(i);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7fd33963.feca781d.js b/assets/js/7fd33963.feca781d.js new file mode 100644 index 0000000000..70d995dded --- /dev/null +++ b/assets/js/7fd33963.feca781d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8526],{84367:(s,e,t)=>{t.r(e),t.d(e,{assets:()=>d,contentTitle:()=>a,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>o});var r=t(74848),n=t(28453);const c={},a="scs-0216: Requirements for testing cluster-stacks",i={id:"kaas/scs-0216",title:"scs-0216: Requirements for testing cluster-stacks",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/kaas/scs-0216.md",sourceDirName:"kaas",slug:"/kaas/scs-0216",permalink:"/standards/kaas/scs-0216",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Robustness features for Kubernetes clusters",permalink:"/standards/scs-0215-v1-robustness-features"},next:{title:"Requirements for testing cluster-stacks",permalink:"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks"}},d={},o=[];function l(s){const e={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...s.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.h1,{id:"scs-0216-requirements-for-testing-cluster-stacks",children:"scs-0216: Requirements for testing cluster-stacks"}),"\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Version"}),(0,r.jsx)(e.th,{children:"Type"}),(0,r.jsx)(e.th,{children:"State"}),(0,r.jsx)(e.th,{children:"stabilized"}),(0,r.jsx)(e.th,{children:"deprecated"})]})}),(0,r.jsx)(e.tbody,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks",children:"scs-0216-v1"})}),(0,r.jsx)(e.td,{children:"Decision Record"}),(0,r.jsx)(e.td,{children:"Draft"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]})})]})]})}function u(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,r.jsx)(e,{...s,children:(0,r.jsx)(l,{...s})}):l(s)}},28453:(s,e,t)=>{t.d(e,{R:()=>a,x:()=>i});var r=t(96540);const n={},c=r.createContext(n);function a(s){const e=r.useContext(c);return r.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function i(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:a(s.components),r.createElement(c.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/8092c627.c98f6819.js b/assets/js/8092c627.c98f6819.js new file mode 100644 index 0000000000..e9e3ccaa76 --- /dev/null +++ b/assets/js/8092c627.c98f6819.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4880],{50561:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>l});var i=a(74848),t=a(28453);const s={},r="User Data Backups",c={id:"iaas/guides/user-guide/user-data-backups",title:"User Data Backups",description:"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.",source:"@site/docs/02-iaas/guides/user-guide/user-data-backups.md",sourceDirName:"02-iaas/guides/user-guide",slug:"/iaas/guides/user-guide/user-data-backups",permalink:"/docs/iaas/guides/user-guide/user-data-backups",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/user-data-backups.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Best Practise: How to configure and use security groups",permalink:"/docs/iaas/guides/user-guide/security-groups/"},next:{title:"Other Guides",permalink:"/docs/iaas/guides/other-guides/"}},o={},l=[{value:"Glossary",id:"glossary",level:2},{value:"Scope",id:"scope",level:2},{value:"Overview of applicable User Data",id:"overview-of-applicable-user-data",level:3},{value:"Image backup using download",id:"image-backup-using-download",level:2},{value:"Ephemeral Storage backup using Glance images",id:"ephemeral-storage-backup-using-glance-images",level:2},{value:"Volume data backup using Cinder Backup API",id:"volume-data-backup-using-cinder-backup-api",level:2},{value:"Backup of detached volumes",id:"backup-of-detached-volumes",level:3},{value:"Backup of attached volumes",id:"backup-of-attached-volumes",level:3},{value:"Volume data backup using Glance images",id:"volume-data-backup-using-glance-images",level:2},{value:"Glance image backups of detached volumes",id:"glance-image-backups-of-detached-volumes",level:3},{value:"Glance image backups of attached (in-use) volumes",id:"glance-image-backups-of-attached-in-use-volumes",level:3},{value:"Barbican secrets backup using download",id:"barbican-secrets-backup-using-download",level:2},{value:"Retrieving encryption keys from Barbican",id:"retrieving-encryption-keys-from-barbican",level:3},{value:"Restore",id:"restore",level:2},{value:"Restoring a backup of a Barbican secret",id:"restoring-a-backup-of-a-barbican-secret",level:3},{value:"Restoring a backup of an unencrypted image",id:"restoring-a-backup-of-an-unencrypted-image",level:3},{value:"Restoring a backup of an encrypted image",id:"restoring-a-backup-of-an-encrypted-image",level:3},{value:"Restoring a volume backup from an image",id:"restoring-a-volume-backup-from-an-image",level:3},{value:"Restoring a volume backup from the Cinder Backup service",id:"restoring-a-volume-backup-from-the-cinder-backup-service",level:3},{value:"Restoring to a new volume (Cinder Backup)",id:"restoring-to-a-new-volume-cinder-backup",level:4},{value:"Restoring on an existing volume (Cinder Backup)",id:"restoring-on-an-existing-volume-cinder-backup",level:4},{value:"Restoring an encrypted volume backup (Cinder Backup)",id:"restoring-an-encrypted-volume-backup-cinder-backup",level:4},{value:"Appendix",id:"appendix",level:2},{value:"Image creation action for servers with attached volumes",id:"image-creation-action-for-servers-with-attached-volumes",level:3},{value:"LUKS encryption key conversion to decrypt volume images",id:"luks-encryption-key-conversion-to-decrypt-volume-images",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"user-data-backups",children:"User Data Backups"}),"\n",(0,i.jsx)(n.p,{children:"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks."}),"\n",(0,i.jsx)(n.h2,{id:"glossary",children:"Glossary"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Term"}),(0,i.jsx)(n.th,{children:"Explanation"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Virtual Machine"}),(0,i.jsxs)(n.td,{children:["Equals the ",(0,i.jsx)(n.code,{children:"server"})," resource in Nova."]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Ephemeral Storage"}),(0,i.jsx)(n.td,{children:"Disk storage directly supplied to a virtual machine by Nova. Different from volumes."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"(Glance) Image"}),(0,i.jsx)(n.td,{children:"IaaS resource usually storing raw disk data. Managed by the Glance service."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"(Cinder) Volume"}),(0,i.jsx)(n.td,{children:"IaaS resource representing block storage disk that can be attached as a virtual disk to virtual machines. Managed by the Cinder service."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"(Volume) Snapshot"}),(0,i.jsx)(n.td,{children:"Thinly-provisioned copy-on-write snapshots of volumes. Stored in the same Cinder storage backend as volumes."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Volume Type"}),(0,i.jsx)(n.td,{children:"Attribute of volumes determining storage details of a volume such as backend location or whether the volume will be encrypted."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"(Barbican) Secret"}),(0,i.jsx)(n.td,{children:"IaaS resource storing cryptographic assets such as encryption keys. Managed by the Barbican service."})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"scope",children:"Scope"}),"\n",(0,i.jsx)(n.p,{children:"User data in the context of this guide describes data accumulated in cloud resources of a user at runtime.\nThis concerns primarily storage data of virtual machines stored at at-rest.\nThis does not cover in-transit or in-use data such as network traffic, virtual machines' RAM contents or IaaS configuration and metadata of cloud resources."}),"\n",(0,i.jsx)(n.h3,{id:"overview-of-applicable-user-data",children:"Overview of applicable User Data"}),"\n",(0,i.jsx)(n.p,{children:"Given the mentioned scope, the following can be classified as user data:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"images stored in Glance"}),"\n",(0,i.jsxs)(n.li,{children:["virtual machine disks, either:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Ephemeral Storage stored in Nova"}),"\n",(0,i.jsx)(n.li,{children:"volumes stored in Cinder"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:"encryption keys stored as secrets in Barbican"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The following sections will describe backup procedures for each of those resources individually."}),"\n",(0,i.jsx)(n.h2,{id:"image-backup-using-download",children:"Image backup using download"}),"\n",(0,i.jsx)(n.p,{children:"Glance images may act as backup targets for other resources (such as volumes) but don't have a dedicated backup service for themselves."}),"\n",(0,i.jsx)(n.p,{children:"When an image is to be backed up, it can be downloaded from the Glance image service and stored outside of the IaaS infrastructure for backup purposes.\nIn this case it is the user's responsibility to establish the backup procedure and appropriate target storage."}),"\n",(0,i.jsxs)(n.admonition,{type:"caution",children:[(0,i.jsx)(n.p,{children:"When creating images from volumes with a volume type that uses encryption, the resulting image will contain the raw LUKS-encrypted blocks of the volume.\nWhen transferred outside of the IaaS infrastructure, this data is only useful as a backup together with the corresponding encryption key."}),(0,i.jsxs)(n.p,{children:["Such images can be identified by an attribute called ",(0,i.jsx)(n.code,{children:"cinder_encryption_key_id"})," in the ",(0,i.jsx)(n.code,{children:"properties"})," metadata field of the image.\nIt only exists for encrypted images and references the encryption key in Barbican.\nRefer to the ",(0,i.jsx)(n.a,{href:"#barbican-secrets-backup-using-download",children:"Barbican secrets section"})," for instructions on how to backup the key."]})]}),"\n",(0,i.jsx)(n.p,{children:"The API or the OpenStack client may be used to initiate the download, for example:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack image save --file $TARGET_FILE_PATH $IMAGE_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.p,{children:"This or the underlying API request may be automated as part of a regular backup schedule involving the backup storage target on the user side."}),"\n",(0,i.jsx)(n.h2,{id:"ephemeral-storage-backup-using-glance-images",children:"Ephemeral Storage backup using Glance images"}),"\n",(0,i.jsxs)(n.admonition,{type:"caution",children:[(0,i.jsxs)(n.p,{children:["When using the ",(0,i.jsx)(n.code,{children:"createImage"})," Compute API action (e.g. via the ",(0,i.jsx)(n.code,{children:"openstack server image create"})," command) on a virtual machine that has volumes attached to it in addition to its Ephemeral Storage disk, the volumes will not be backed up into the image. Instead, a snapshot will be created for each attached volume and referenced in the image metadata. This does not replace genuine volume backups."]}),(0,i.jsxs)(n.p,{children:["See the ",(0,i.jsx)(n.a,{href:"#image-creation-action-for-servers-with-attached-volumes",children:"corresponding appendix section"})," for further details."]})]}),"\n",(0,i.jsxs)(n.p,{children:["Ephemeral Storage disks of virtual machines can be backed up to Glance images easily by using the ",(0,i.jsx)(n.code,{children:"createImage"})," Compute API action or the corresponding OpenStack client command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack server image create --name $IMAGE_NAME $SERVER_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.p,{children:"This will create a Glance image containing a one-to-one copy of the data on the Ephemeral Storage disk at the time of execution."}),"\n",(0,i.jsxs)(n.p,{children:["If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in ",(0,i.jsx)(n.a,{href:"#image-backup-using-download",children:"Image backup using download"})," may be used after the image creation."]}),"\n",(0,i.jsx)(n.h2,{id:"volume-data-backup-using-cinder-backup-api",children:"Volume data backup using Cinder Backup API"}),"\n",(0,i.jsx)(n.p,{children:"The following instructions only apply if the infrastructure offers the Cinder Backup API."}),"\n",(0,i.jsxs)(n.admonition,{type:"note",children:[(0,i.jsx)(n.p,{children:"Backups of volumes using a volume type that uses encryption will retain their encryption and a clone of the original encryption key is created in Barbican linked to the backup.\nThese backups can only be restored when the Barbican service is available and still has the corresponding copy of the encryption key."}),(0,i.jsxs)(n.p,{children:["Also, it is advised to take note of the exact volume type when creating a backup of an encrypted volume, because this information will be needed to restore the backup.\nSee ",(0,i.jsx)(n.a,{href:"#restoring-an-encrypted-volume-backup-cinder-backup",children:"restoring an encrypted volume backup"}),"."]})]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["It might be difficult or even impossible for a user to transfer backups created by the Cinder Backup API outside of the IaaS infrastructure, depending on the backup backend.\nA more easily accessible backup of volumes can be created by using Glance images.\nSee the ",(0,i.jsx)(n.a,{href:"#volume-data-backup-using-glance-images",children:"section about volume data backup using Glance images"})," for details."]})}),"\n",(0,i.jsx)(n.h3,{id:"backup-of-detached-volumes",children:"Backup of detached volumes"}),"\n",(0,i.jsx)(n.p,{children:"Backups can be created using the Cinder Backup API or the corresponding OpenStack client commands:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create $VOLUME_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.p,{children:"Further backups of the same volume can subsequently be created as incremental backups using the following command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create --incremental $VOLUME_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.h3,{id:"backup-of-attached-volumes",children:"Backup of attached volumes"}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"When creating backups of attached (in-use) volumes, the state of the full volume is captured at runtime. Backups created this way will be crash-consistent but not app-consistent."})}),"\n",(0,i.jsxs)(n.p,{children:["In case of attached (in-use) volumes, backups can only be created while also specfiying the ",(0,i.jsx)(n.code,{children:"force"})," parameter:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create --force $VOLUME_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.p,{children:"Further backups of the same volume can subsequently be created as incremental backups using the following command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create --force --incremental $VOLUME_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.h2,{id:"volume-data-backup-using-glance-images",children:"Volume data backup using Glance images"}),"\n",(0,i.jsx)(n.p,{children:"In case the Cinder Backup storage is not available in the IaaS infrastructure, Glance images can be used as a backup target instead.\nSuch images may also subsequently be downloaded to transfer the backup outside of the IaaS infrastructure."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Glance image backups of Cinder volumes only allow full backup copies and do not offer incremental or differential backup mechanisms."})}),"\n",(0,i.jsx)(n.h3,{id:"glance-image-backups-of-detached-volumes",children:"Glance image backups of detached volumes"}),"\n",(0,i.jsxs)(n.p,{children:["Volumes not attached to virtual machines can be directly copied into an image.\nSuch volumes can be identified by their status being ",(0,i.jsx)(n.code,{children:"available"}),".\nTo backup a detached volume to a Glance image, directly use the corresponding image creation action:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack image create --volume $VOLUME_NAME_OR_ID $IMAGE_NAME\n"})}),"\n",(0,i.jsx)(n.p,{children:"After the image creation has finished, a full backup copy of the volume will reside in the Glance storage backend."}),"\n",(0,i.jsxs)(n.p,{children:["If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in ",(0,i.jsx)(n.a,{href:"#image-backup-using-download",children:"Image backup using download"})," may be used after the image creation."]}),"\n",(0,i.jsx)(n.h3,{id:"glance-image-backups-of-attached-in-use-volumes",children:"Glance image backups of attached (in-use) volumes"}),"\n",(0,i.jsx)(n.p,{children:"Cinder is unable to directly create Glance images from volumes which are attached to virtual machines.\nTo create backups of such volumes regardless, a detour using volume snapshots can be used which will be described below."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["When creating snapshots of attached (in-use) volumes, the ",(0,i.jsx)(n.code,{children:"force"})," parameter has to be used. These snapshots capture a state of the full volume at runtime. They will be crash-consistent but not app-consistent."]})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Create a snapshot of the target volume while including the ",(0,i.jsx)(n.code,{children:"force"})," parameter in the request:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"openstack volume snapshot create --volume $VOLUME_NAME_OR_ID $SNAPSHOT_NAME"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Create a new temporary volume based on the snapshot to act as backup source:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"openstack volume create --snapshot $SNAPSHOT_NAME $TEMP_VOLUME_NAME"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Wait until the volume creation is finished and the temporary volume reaches the ",(0,i.jsx)(n.code,{children:"available"})," status."]}),"\n",(0,i.jsxs)(n.li,{children:["Create a backup image of the temporary volume:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"openstack image create --volume $TEMP_VOLUME_NAME $IMAGE_NAME"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Wait until the image creation finishes and the target image reaches the ",(0,i.jsx)(n.code,{children:"active"})," status."]}),"\n",(0,i.jsxs)(n.li,{children:["Delete the temporary volume and snapshot:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"openstack volume delete $TEMP_VOLUME_NAME"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"openstack volume snapshot delete $SNAPSHOT_NAME"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"A full backup copy of the volume now resides in the Glance storage backend."}),"\n",(0,i.jsxs)(n.p,{children:["If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in ",(0,i.jsx)(n.a,{href:"#image-backup-using-download",children:"Image backup using download"})," may be used after the image creation."]}),"\n",(0,i.jsx)(n.h2,{id:"barbican-secrets-backup-using-download",children:"Barbican secrets backup using download"}),"\n",(0,i.jsx)(n.admonition,{type:"danger",children:(0,i.jsx)(n.p,{children:"Secrets downloaded from Barbican will be in plaintext, which means that the secret is unprotected once received from the API.\nBefore downloading secrets from Barbican make sure that a secure target environment is established for receiving and securely storing the secret's contents."})}),"\n",(0,i.jsx)(n.p,{children:"Barbican secrets can be downloaded in plaintext using the corresponding API or client command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'openstack secret get --file $TARGET_FILE_PATH --payload_content_type "application/octet-stream" $SECRET_ID\n'})}),"\n",(0,i.jsxs)(n.admonition,{type:"tip",children:[(0,i.jsxs)(n.p,{children:["In case the secret needs to be restored into an OpenStack Barbican later on, it is recommended to also note down the following attributes shown by ",(0,i.jsx)(n.code,{children:"openstack secret get $SECRET_ID"}),":"]}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Algorithm"}),"\n",(0,i.jsx)(n.li,{children:"Bit length"}),"\n",(0,i.jsx)(n.li,{children:"Secret type"}),"\n",(0,i.jsx)(n.li,{children:"Mode"}),"\n"]})]}),"\n",(0,i.jsx)(n.h3,{id:"retrieving-encryption-keys-from-barbican",children:"Retrieving encryption keys from Barbican"}),"\n",(0,i.jsx)(n.p,{children:"In case of encrypted volumes (i.e. using a volume type with encryption), a corresponding encryption key is stored in Barbican.\nWhen an image is created from such a volume, the encryption key is duplicated in Barbican for the image.\nIn order to backup those keys, the corresponding secret must first be identified."}),"\n",(0,i.jsx)(n.p,{children:"For volumes, this is possible starting with the Volume API microversion 3.64:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume show --os-volume-api-version 3.64 $VOLUME_NAME_OR_ID\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The response will contain an ",(0,i.jsx)(n.code,{children:"encryption_key_id"})," field with the ID of the Barbican secret."]}),"\n",(0,i.jsxs)(n.p,{children:["For images, the secret reference is stored in the ",(0,i.jsx)(n.code,{children:"properties"})," field instead:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack image show -f value -c properties $IMAGE_NAME_OR_ID\n"})}),"\n",(0,i.jsxs)(n.p,{children:["In case of images created from encrypted volumes, the resulting output will have a nested ",(0,i.jsx)(n.code,{children:"cinder_encryption_key_id"})," field that contains the ID of the Barbican secret."]}),"\n",(0,i.jsxs)(n.p,{children:["The resulting IDs can be used to retrieve the corresponding key using the ",(0,i.jsx)(n.a,{href:"#barbican-secrets-backup-using-download",children:"Barbican instructions"})," above."]}),"\n",(0,i.jsxs)(n.admonition,{type:"caution",children:[(0,i.jsx)(n.p,{children:"Note that the key retrieved from the secret is not immediately usable as LUKS passphrase to the image data of the volume.\nOpenStack does some processing to the key before it is passed to the LUKS encryption, which must be mimicked accordingly in order to unlock the encryption outside of OpenStack!"}),(0,i.jsxs)(n.p,{children:["See the ",(0,i.jsx)(n.a,{href:"#luks-encryption-key-conversion-to-decrypt-volume-images",children:"example procedure for converting the LUKS key"})," in the appendix section."]})]}),"\n",(0,i.jsx)(n.h2,{id:"restore",children:"Restore"}),"\n",(0,i.jsx)(n.p,{children:"The following sections will illustrate how to restore the individual resource backups that have been documented above."}),"\n",(0,i.jsx)(n.h3,{id:"restoring-a-backup-of-a-barbican-secret",children:"Restoring a backup of a Barbican secret"}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Note that restoring a Barbican secret by re-uploading it via the Barbican API will lead to the secret receiving a new ID.\nExisting resources referencing an old secret ID cannot make use of the restored copy."})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack secret store --algorithm aes --bit-length 256 --mode cbc \\\n --secret-type symmetric --file $KEY_FILE_PATH --name $SECRET_NAME\n"})}),"\n",(0,i.jsx)(n.p,{children:"Notes:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Attributes like algorithm, bit length, mode and secret type are not verified by Barbican. Their main purpose is to classify the secret on a metadata level. Make sure to align the attributes with the original secret."}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"$KEY_FILE_PATH"})," is the local file path of the secret backup as created originally using the ",(0,i.jsx)(n.a,{href:"#barbican-secrets-backup-using-download",children:"instructions above"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"$SECRET_NAME"})," is entirely optional but helps identifying the restored secret later on and to distinguish it from secrets created by OpenStack itself. It is best to not put whitespace characters in the name, otherwise it has to be surrounded by quotes."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The successful registration of the restored secret can subsequently be verified using:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack secret list --name $SECRET_NAME\n"})}),"\n",(0,i.jsx)(n.h3,{id:"restoring-a-backup-of-an-unencrypted-image",children:"Restoring a backup of an unencrypted image"}),"\n",(0,i.jsx)(n.p,{children:"Unencrypted image backups can simply be restored using the regular image upload functionality and specifying the backup file:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack image create --file $IMAGE_FILE_PATH $IMAGE_NAME\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["In case the original image backup was not based on a volume originally, the image may have had a non-default disk or container format.\nIn this case, add the command parameters ",(0,i.jsx)(n.code,{children:"--container-format"})," and ",(0,i.jsx)(n.code,{children:"--disk-format"})," to the command accordingly."]})}),"\n",(0,i.jsx)(n.h3,{id:"restoring-a-backup-of-an-encrypted-image",children:"Restoring a backup of an encrypted image"}),"\n",(0,i.jsx)(n.p,{children:"The following section only applies to image backups that were originally created from images of encrypted volumes."}),"\n",(0,i.jsxs)(n.p,{children:["First, restore the corresponding secret of the image using the ",(0,i.jsx)(n.a,{href:"#restoring-a-backup-of-a-barbican-secret",children:"instructions above"}),".\nThe restored secret will receive a new ID in the form of a ",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Universally_unique_identifier",children:"UUID"}),".\nNote down the ID of the restored secret and insert it in place of ",(0,i.jsx)(n.code,{children:"$SECRET_ID"})," in the command below."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack image create --file $IMAGE_FILE_PATH \\\n --property cinder_encryption_key_id=$SECRET_ID \\\n --property cinder_encryption_key_deletion_policy=on_image_deletion \\\n $IMAGE_NAME\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"cinder_encryption_key_deletion_policy"})," attribute is optional.\nIf not specified, the referenced secret will not be deleted on image deletion automatically.\nIn contrast, if set to ",(0,i.jsx)(n.code,{children:"on_image_deletion"}),", the referenced secret will be deleted as soon as the image referencing it is deleted."]}),"\n",(0,i.jsx)(n.h3,{id:"restoring-a-volume-backup-from-an-image",children:"Restoring a volume backup from an image"}),"\n",(0,i.jsx)(n.p,{children:"To restore a volume from an image backup, simply use the volume creation action and specify the image as source."}),"\n",(0,i.jsxs)(n.p,{children:["Depending on whether the original volume the image was created from was encrypted or not, the target volume type might need to be specified accordingly.\nWhether this is the case can be identified by inspecting the image's metadata using ",(0,i.jsx)(n.code,{children:"openstack image show $IMAGE_NAME_OR_ID"}),' and looking for a "cinder_encryption_key_id" field within "properties".\nIf it exists, the source volume of the image was encrypted.']}),"\n",(0,i.jsx)(n.p,{children:"To restore the image of an unencrypted volume:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume create --image $IMAGE_NAME_OR_ID \\\n --size $VOLUME_SIZE_IN_GB $VOLUME_NAME\n"})}),"\n",(0,i.jsx)(n.p,{children:"To restore the image of an encrypted volume:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume create --image $IMAGE_NAME_OR_ID \\\n --type $ENCRYPTED_VOLUME_TYPE \\\n --size $VOLUME_SIZE_IN_GB $VOLUME_NAME\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If restoring an encrypted image, make sure to specify ",(0,i.jsx)(n.code,{children:"$ENCRYPTED_VOLUME_TYPE"})," correctly and have it reference a volume type which also supports the encryption.\nOtherwise the volume will be unbootable or unusable by Nova instances."]}),"\n",(0,i.jsx)(n.h3,{id:"restoring-a-volume-backup-from-the-cinder-backup-service",children:"Restoring a volume backup from the Cinder Backup service"}),"\n",(0,i.jsx)(n.p,{children:"The Cinder Backup service offers dedicated API actions and commands for restoring volume backups created using the service.\nThese backups can be restored in one of two ways:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Letting the Cinder Backup service create a new volume based on the backup."}),"\n",(0,i.jsx)(n.li,{children:"Overwriting an existing volume with the backup data."}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["If the volume backup was originally created from a volume that used a non-default encrypted volume type, letting Cinder Backup create a new volume for backup restoration does not work and the volume type must match exactly.\nIn such case provision an empty volume with the correct type first and then restore the backup onto it ",(0,i.jsx)(n.a,{href:"#restoring-an-encrypted-volume-backup-cinder-backup",children:"as explained further down"}),"."]})}),"\n",(0,i.jsx)(n.h4,{id:"restoring-to-a-new-volume-cinder-backup",children:"Restoring to a new volume (Cinder Backup)"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup restore $BACKUP_NAME_OR_ID $TARGET_NAME\n"})}),"\n",(0,i.jsxs)(n.p,{children:["... where ",(0,i.jsx)(n.code,{children:"$TARGET_NAME"})," is the desired name of the new volume to be created.\nMake sure that no volume with this name already exists.\nThe Cinder Backup service will create the volume with the same size as the backup indicates."]}),"\n",(0,i.jsx)(n.h4,{id:"restoring-on-an-existing-volume-cinder-backup",children:"Restoring on an existing volume (Cinder Backup)"}),"\n",(0,i.jsx)(n.p,{children:"As an alternative to creating a new volume as the restore target, the backup can also be restored on an existing volume:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup restore --force $BACKUP_NAME_OR_ID $VOLUME_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.p,{children:"... which will overwrite the data on the existing volume, regardless of whether it is empty or not!"}),"\n",(0,i.jsx)(n.p,{children:'The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.'}),"\n",(0,i.jsx)(n.h4,{id:"restoring-an-encrypted-volume-backup-cinder-backup",children:"Restoring an encrypted volume backup (Cinder Backup)"}),"\n",(0,i.jsx)(n.p,{children:'When restoring a volume backup of a volume that was using a non-default encrypted volume type, a new volume of that type needs to be created first and then the backup restored onto it.\nOtherwise, the restoration will fail with the target volume ending up in the "error_restoring" state.\nFor this procedure to succeed it is necessary to know the exact volume type of the volume the backup was created from.'}),"\n",(0,i.jsxs)(n.p,{children:["If the source volume of the backup still exists, the original volume type can be determined by inspecting the backup's ",(0,i.jsx)(n.code,{children:"volume_id"})," attribute and then using it to look up the corresponding volume and its ",(0,i.jsx)(n.code,{children:"type"})," attribute.\nThe following client command can be used for this (fill in the value for ",(0,i.jsx)(n.code,{children:"BACKUP_ID"}),"):"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'export BACKUP_ID=...\n\nSOURCE_VOLUME_ID="$(openstack volume backup show $BACKUP_ID -f value -c volume_id)"\nopenstack volume show -f value -c type "$SOURCE_VOLUME_ID"\n'})}),"\n",(0,i.jsx)(n.p,{children:"This returns the name of the original volume type.\nIf the source volume does not exist anymore, rely on documentation about the backup to determine the type, if available."}),"\n",(0,i.jsxs)(n.p,{children:["First, create a new empty volume as the restore target and use the backup's ",(0,i.jsx)(n.code,{children:"size"})," metadata attribute to match the size of the volume to the backup:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume create --size $BACKUP_SIZE --type $VOLUME_TYPE $TARGET_NAME\n"})}),"\n",(0,i.jsxs)(n.p,{children:["... where ",(0,i.jsx)(n.code,{children:"$TARGET_NAME"})," is the desired name of the new volume."]}),"\n",(0,i.jsx)(n.p,{children:'Once the volume reaches "available" state, restore the backup onto it:'}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup restore --force $BACKUP_NAME_OR_ID $TARGET_NAME\n"})}),"\n",(0,i.jsx)(n.p,{children:'The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.'}),"\n",(0,i.jsx)(n.h2,{id:"appendix",children:"Appendix"}),"\n",(0,i.jsx)(n.h3,{id:"image-creation-action-for-servers-with-attached-volumes",children:"Image creation action for servers with attached volumes"}),"\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"createImage"})," action of the Compute API (",(0,i.jsx)(n.code,{children:"openstack server image create"}),") is used on virtual machines that have at least one volume attached, a snapshot will be created for each attached volume individually and referenced in the resulting image's metadata."]}),"\n",(0,i.jsx)(n.p,{children:"This happens regardless of whether the virtual machine has an Ephemeral Storage disk attached.\nIn case of an Ephemeral Storage disk, only the Ephemeral Storage is copied into the Glance image as a 1:1 copy."}),"\n",(0,i.jsxs)(n.p,{children:["In case of a virtual machine that has no Ephemeral Storage but only volumes, the ",(0,i.jsx)(n.code,{children:"createImage"})," action leads to a Glance image that only consists of metadata (including the resulting volume snapshot references) but carries no actual binary data."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Figure: createImage action flow involving Ephemeral Storage and/or volumes",src:a(75028).A+"",width:"1342",height:"1202"})}),"\n",(0,i.jsx)(n.h3,{id:"luks-encryption-key-conversion-to-decrypt-volume-images",children:"LUKS encryption key conversion to decrypt volume images"}),"\n",(0,i.jsx)(n.p,{children:"The volume encryption keys stored in Barbican are not directly used as LUKS passphrases by OpenStack because they are in binary format.\nOpenStack converts them to ASCII internally before passing them to the encryption layer.\nThis behavior needs to be reproduced if a decryption of a volume image is desired outside of OpenStack."}),"\n",(0,i.jsx)(n.admonition,{type:"danger",children:(0,i.jsx)(n.p,{children:"The instructions below will expose plaintext data of encryption keys and encrypted volume images.\nMake sure to only execute these steps in a secure and trusted environment."})}),"\n",(0,i.jsx)(n.p,{children:"First, download the image:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack image save --file image.raw $IMAGE_NAME_OR_ID\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Next, inspect the image metadata, determine the reference to the encryption key (",(0,i.jsx)(n.code,{children:"cinder_encryption_key_id"})," property) and download the encryption key:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'openstack image show -f value -c properties $IMAGE_NAME_OR_ID\n# (use the value of `cinder_encryption_key_id` as `$SECRET_ID` below)\nopenstack secret get --file image.key --payload_content_type "application/octet-stream" $SECRET_ID\n'})}),"\n",(0,i.jsx)(n.p,{children:"This will result in the following local files:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"image.raw"})," = the raw encrypted image downloaded from Glance"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"image.key"})," = the LUKS encryption key in binary format (plaintext)"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Since OpenStack internally uses Python's ",(0,i.jsx)(n.code,{children:"binascii.hexlify()"})," to convert the binary encryption key before passing it as a passphrase to the LUKS encryption, as a last step this conversion must be mimicked to unlock the encryption:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"python3 -c \"import binascii; \\\n f = open('image.key', 'rb'); \\\n print(binascii.hexlify(f.read()).decode('utf-8'))\" \\\n | sudo cryptsetup luksOpen ./image.raw decrypted_image\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The decrypted image is now accessible at ",(0,i.jsx)(n.code,{children:"/dev/mapper/decrypted_image"}),".\nNote that this is a live en-/decryption operation on the ",(0,i.jsx)(n.code,{children:"image.raw"})," file.\nThe image is not converted, the encryption is simply unlocked in-memory using LUKS and dm-crypt until the encryption is closed again."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"/dev/mapper/decrypted_image"})," can now be handled like a raw block device (e.g. mounted as a filesystem) or snapshotted in decrypted form."]}),"\n",(0,i.jsx)(n.p,{children:"To close the encryption execute:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo cryptsetup luksClose decrypted_image\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},75028:(e,n,a)=>{a.d(n,{A:()=>i});const i=a.p+"assets/images/user_data_backups_figure1-988dbd55659509cc1ddc9f68f2437648.png"},28453:(e,n,a)=>{a.d(n,{R:()=>r,x:()=>c});var i=a(96540);const t={},s=i.createContext(t);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/814f3328.48ccac70.js b/assets/js/814f3328.48ccac70.js new file mode 100644 index 0000000000..e137a7716b --- /dev/null +++ b/assets/js/814f3328.48ccac70.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7472],{55513:s=>{s.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"First Blog Post","permalink":"/blog/first-blog-post","unlisted":false}]}')}}]); \ No newline at end of file diff --git a/assets/js/8159.d20bf7bf.js b/assets/js/8159.d20bf7bf.js new file mode 100644 index 0000000000..e999d50683 --- /dev/null +++ b/assets/js/8159.d20bf7bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8159],{58159:(t,e,r)=>{r.d(e,{diagram:()=>D});var i=r(76257),a=r(697),n=r(26312),s=r(21176);const o=[];for(let S=0;S<256;++S)o.push((S+256).toString(16).slice(1));function c(t,e=0){return o[t[e+0]]+o[t[e+1]]+o[t[e+2]]+o[t[e+3]]+"-"+o[t[e+4]]+o[t[e+5]]+"-"+o[t[e+6]]+o[t[e+7]]+"-"+o[t[e+8]]+o[t[e+9]]+"-"+o[t[e+10]]+o[t[e+11]]+o[t[e+12]]+o[t[e+13]]+o[t[e+14]]+o[t[e+15]]}const l=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;const h=function(t){return"string"==typeof t&&l.test(t)};const d=function(t){if(!h(t))throw TypeError("Invalid UUID");let e;const r=new Uint8Array(16);return r[0]=(e=parseInt(t.slice(0,8),16))>>>24,r[1]=e>>>16&255,r[2]=e>>>8&255,r[3]=255&e,r[4]=(e=parseInt(t.slice(9,13),16))>>>8,r[5]=255&e,r[6]=(e=parseInt(t.slice(14,18),16))>>>8,r[7]=255&e,r[8]=(e=parseInt(t.slice(19,23),16))>>>8,r[9]=255&e,r[10]=(e=parseInt(t.slice(24,36),16))/1099511627776&255,r[11]=e/4294967296&255,r[12]=e>>>24&255,r[13]=e>>>16&255,r[14]=e>>>8&255,r[15]=255&e,r};function y(t,e,r,i){switch(t){case 0:return e&r^~e&i;case 1:case 3:return e^r^i;case 2:return e&r^e&i^r&i}}function u(t,e){return t<<e|t>>>32-e}const p=function(t,e,r){function i(t,i,a,n){var s;if("string"==typeof t&&(t=function(t){t=unescape(encodeURIComponent(t));const e=[];for(let r=0;r<t.length;++r)e.push(t.charCodeAt(r));return e}(t)),"string"==typeof i&&(i=d(i)),16!==(null===(s=i)||void 0===s?void 0:s.length))throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)");let o=new Uint8Array(16+t.length);if(o.set(i),o.set(t,i.length),o=r(o),o[6]=15&o[6]|e,o[8]=63&o[8]|128,a){n=n||0;for(let t=0;t<16;++t)a[n+t]=o[t];return a}return c(o)}try{i.name=t}catch(a){}return i.DNS="6ba7b810-9dad-11d1-80b4-00c04fd430c8",i.URL="6ba7b811-9dad-11d1-80b4-00c04fd430c8",i}("v5",80,(function(t){const e=[1518500249,1859775393,2400959708,3395469782],r=[1732584193,4023233417,2562383102,271733878,3285377520];if("string"==typeof t){const e=unescape(encodeURIComponent(t));t=[];for(let r=0;r<e.length;++r)t.push(e.charCodeAt(r))}else Array.isArray(t)||(t=Array.prototype.slice.call(t));t.push(128);const i=t.length/4+2,a=Math.ceil(i/16),n=new Array(a);for(let s=0;s<a;++s){const e=new Uint32Array(16);for(let r=0;r<16;++r)e[r]=t[64*s+4*r]<<24|t[64*s+4*r+1]<<16|t[64*s+4*r+2]<<8|t[64*s+4*r+3];n[s]=e}n[a-1][14]=8*(t.length-1)/Math.pow(2,32),n[a-1][14]=Math.floor(n[a-1][14]),n[a-1][15]=8*(t.length-1)&4294967295;for(let s=0;s<a;++s){const t=new Uint32Array(80);for(let e=0;e<16;++e)t[e]=n[s][e];for(let e=16;e<80;++e)t[e]=u(t[e-3]^t[e-8]^t[e-14]^t[e-16],1);let i=r[0],a=r[1],o=r[2],c=r[3],l=r[4];for(let r=0;r<80;++r){const n=Math.floor(r/20),s=u(i,5)+y(n,a,o,c)+l+e[n]+t[r]>>>0;l=c,c=o,o=u(a,30)>>>0,a=i,i=s}r[0]=r[0]+i>>>0,r[1]=r[1]+a>>>0,r[2]=r[2]+o>>>0,r[3]=r[3]+c>>>0,r[4]=r[4]+l>>>0}return[r[0]>>24&255,r[0]>>16&255,r[0]>>8&255,255&r[0],r[1]>>24&255,r[1]>>16&255,r[1]>>8&255,255&r[1],r[2]>>24&255,r[2]>>16&255,r[2]>>8&255,255&r[2],r[3]>>24&255,r[3]>>16&255,r[3]>>8&255,255&r[3],r[4]>>24&255,r[4]>>16&255,r[4]>>8&255,255&r[4]]}));r(74353),r(16750),r(42838);var _=function(){var t=function(t,e,r,i){for(r=r||{},i=t.length;i--;r[t[i]]=e);return r},e=[6,8,10,20,22,24,26,27,28],r=[1,10],i=[1,11],a=[1,12],n=[1,13],s=[1,14],o=[1,15],c=[1,21],l=[1,22],h=[1,23],d=[1,24],y=[1,25],u=[6,8,10,13,15,18,19,20,22,24,26,27,28,41,42,43,44,45],p=[1,34],_=[27,28,46,47],f=[41,42,43,44,45],m=[17,34],E=[1,54],g=[1,53],O=[17,34,36,38],b={trace:function(){},yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,entityName:11,relSpec:12,":":13,role:14,BLOCK_START:15,attributes:16,BLOCK_STOP:17,SQS:18,SQE:19,title:20,title_value:21,acc_title:22,acc_title_value:23,acc_descr:24,acc_descr_value:25,acc_descr_multiline_value:26,ALPHANUM:27,ENTITY_NAME:28,attribute:29,attributeType:30,attributeName:31,attributeKeyTypeList:32,attributeComment:33,ATTRIBUTE_WORD:34,attributeKeyType:35,COMMA:36,ATTRIBUTE_KEY:37,COMMENT:38,cardinality:39,relType:40,ZERO_OR_ONE:41,ZERO_OR_MORE:42,ONE_OR_MORE:43,ONLY_ONE:44,MD_PARENT:45,NON_IDENTIFYING:46,IDENTIFYING:47,WORD:48,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:":",15:"BLOCK_START",17:"BLOCK_STOP",18:"SQS",19:"SQE",20:"title",21:"title_value",22:"acc_title",23:"acc_title_value",24:"acc_descr",25:"acc_descr_value",26:"acc_descr_multiline_value",27:"ALPHANUM",28:"ENTITY_NAME",34:"ATTRIBUTE_WORD",36:"COMMA",37:"ATTRIBUTE_KEY",38:"COMMENT",41:"ZERO_OR_ONE",42:"ZERO_OR_MORE",43:"ONE_OR_MORE",44:"ONLY_ONE",45:"MD_PARENT",46:"NON_IDENTIFYING",47:"IDENTIFYING",48:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,4],[9,3],[9,1],[9,7],[9,6],[9,4],[9,2],[9,2],[9,2],[9,1],[11,1],[11,1],[16,1],[16,2],[29,2],[29,3],[29,3],[29,4],[30,1],[31,1],[32,1],[32,3],[35,1],[33,1],[12,3],[39,1],[39,1],[39,1],[39,1],[39,1],[40,1],[40,1],[14,1],[14,1],[14,1]],performAction:function(t,e,r,i,a,n,s){var o=n.length-1;switch(a){case 1:break;case 2:case 6:case 7:this.$=[];break;case 3:n[o-1].push(n[o]),this.$=n[o-1];break;case 4:case 5:case 19:case 43:case 27:case 28:case 31:this.$=n[o];break;case 8:i.addEntity(n[o-4]),i.addEntity(n[o-2]),i.addRelationship(n[o-4],n[o],n[o-2],n[o-3]);break;case 9:i.addEntity(n[o-3]),i.addAttributes(n[o-3],n[o-1]);break;case 10:i.addEntity(n[o-2]);break;case 11:i.addEntity(n[o]);break;case 12:i.addEntity(n[o-6],n[o-4]),i.addAttributes(n[o-6],n[o-1]);break;case 13:i.addEntity(n[o-5],n[o-3]);break;case 14:i.addEntity(n[o-3],n[o-1]);break;case 15:case 16:this.$=n[o].trim(),i.setAccTitle(this.$);break;case 17:case 18:this.$=n[o].trim(),i.setAccDescription(this.$);break;case 20:case 41:case 42:case 32:this.$=n[o].replace(/"/g,"");break;case 21:case 29:this.$=[n[o]];break;case 22:n[o].push(n[o-1]),this.$=n[o];break;case 23:this.$={attributeType:n[o-1],attributeName:n[o]};break;case 24:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeKeyTypeList:n[o]};break;case 25:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeComment:n[o]};break;case 26:this.$={attributeType:n[o-3],attributeName:n[o-2],attributeKeyTypeList:n[o-1],attributeComment:n[o]};break;case 30:n[o-2].push(n[o]),this.$=n[o-2];break;case 33:this.$={cardA:n[o],relType:n[o-1],cardB:n[o-2]};break;case 34:this.$=i.Cardinality.ZERO_OR_ONE;break;case 35:this.$=i.Cardinality.ZERO_OR_MORE;break;case 36:this.$=i.Cardinality.ONE_OR_MORE;break;case 37:this.$=i.Cardinality.ONLY_ONE;break;case 38:this.$=i.Cardinality.MD_PARENT;break;case 39:this.$=i.Identification.NON_IDENTIFYING;break;case 40:this.$=i.Identification.IDENTIFYING}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,20:r,22:i,24:a,26:n,27:s,28:o},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:16,11:9,20:r,22:i,24:a,26:n,27:s,28:o},t(e,[2,5]),t(e,[2,6]),t(e,[2,11],{12:17,39:20,15:[1,18],18:[1,19],41:c,42:l,43:h,44:d,45:y}),{21:[1,26]},{23:[1,27]},{25:[1,28]},t(e,[2,18]),t(u,[2,19]),t(u,[2,20]),t(e,[2,4]),{11:29,27:s,28:o},{16:30,17:[1,31],29:32,30:33,34:p},{11:35,27:s,28:o},{40:36,46:[1,37],47:[1,38]},t(_,[2,34]),t(_,[2,35]),t(_,[2,36]),t(_,[2,37]),t(_,[2,38]),t(e,[2,15]),t(e,[2,16]),t(e,[2,17]),{13:[1,39]},{17:[1,40]},t(e,[2,10]),{16:41,17:[2,21],29:32,30:33,34:p},{31:42,34:[1,43]},{34:[2,27]},{19:[1,44]},{39:45,41:c,42:l,43:h,44:d,45:y},t(f,[2,39]),t(f,[2,40]),{14:46,27:[1,49],28:[1,48],48:[1,47]},t(e,[2,9]),{17:[2,22]},t(m,[2,23],{32:50,33:51,35:52,37:E,38:g}),t([17,34,37,38],[2,28]),t(e,[2,14],{15:[1,55]}),t([27,28],[2,33]),t(e,[2,8]),t(e,[2,41]),t(e,[2,42]),t(e,[2,43]),t(m,[2,24],{33:56,36:[1,57],38:g}),t(m,[2,25]),t(O,[2,29]),t(m,[2,32]),t(O,[2,31]),{16:58,17:[1,59],29:32,30:33,34:p},t(m,[2,26]),{35:60,37:E},{17:[1,61]},t(e,[2,13]),t(O,[2,30]),t(e,[2,12])],defaultActions:{34:[2,27],41:[2,22]},parseError:function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},parse:function(t){var e=this,r=[0],i=[],a=[null],n=[],s=this.table,o="",c=0,l=0,h=n.slice.call(arguments,1),d=Object.create(this.lexer),y={yy:{}};for(var u in this.yy)Object.prototype.hasOwnProperty.call(this.yy,u)&&(y.yy[u]=this.yy[u]);d.setInput(t,y.yy),y.yy.lexer=d,y.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var p=d.yylloc;n.push(p);var _=d.options&&d.options.ranges;"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,m,E,g,O,b,k,R,N,T={};;){if(m=r[r.length-1],this.defaultActions[m]?E=this.defaultActions[m]:(null==f&&(N=void 0,"number"!=typeof(N=i.pop()||d.lex()||1)&&(N instanceof Array&&(N=(i=N).pop()),N=e.symbols_[N]||N),f=N),E=s[m]&&s[m][f]),void 0===E||!E.length||!E[0]){var x="";for(O in R=[],s[m])this.terminals_[O]&&O>2&&R.push("'"+this.terminals_[O]+"'");x=d.showPosition?"Parse error on line "+(c+1)+":\n"+d.showPosition()+"\nExpecting "+R.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(x,{text:d.match,token:this.terminals_[f]||f,line:d.yylineno,loc:p,expected:R})}if(E[0]instanceof Array&&E.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+f);switch(E[0]){case 1:r.push(f),a.push(d.yytext),n.push(d.yylloc),r.push(E[1]),f=null,l=d.yyleng,o=d.yytext,c=d.yylineno,p=d.yylloc;break;case 2:if(b=this.productions_[E[1]][1],T.$=a[a.length-b],T._$={first_line:n[n.length-(b||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(b||1)].first_column,last_column:n[n.length-1].last_column},_&&(T._$.range=[n[n.length-(b||1)].range[0],n[n.length-1].range[1]]),void 0!==(g=this.performAction.apply(T,[o,l,c,y.yy,E[1],a,n].concat(h))))return g;b&&(r=r.slice(0,-1*b*2),a=a.slice(0,-1*b),n=n.slice(0,-1*b)),r.push(this.productions_[E[1]][0]),a.push(T.$),n.push(T._$),k=s[r[r.length-2]][r[r.length-1]],r.push(k);break;case 3:return!0}}return!0}},k={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,r=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var a=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===i.length?this.yylloc.first_column:0)+i[i.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var r,i,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var n in a)this[n]=a[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,r,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),n=0;n<a.length;n++)if((r=this._input.match(this.rules[a[n]]))&&(!e||r[0].length>e[0].length)){if(e=r,i=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,a[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,a[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,r,i){switch(r){case 0:return this.begin("acc_title"),22;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),24;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 10;case 8:case 15:case 20:break;case 9:return 8;case 10:return 28;case 11:return 48;case 12:return 4;case 13:return this.begin("block"),15;case 14:return 36;case 16:return 37;case 17:case 18:return 34;case 19:return 38;case 21:return this.popState(),17;case 22:case 54:return e.yytext[0];case 23:return 18;case 24:return 19;case 25:case 29:case 30:case 43:return 41;case 26:case 27:case 28:case 36:case 38:case 45:return 43;case 31:case 32:case 33:case 34:case 35:case 37:case 44:return 42;case 39:case 40:case 41:case 42:return 44;case 46:return 45;case 47:case 50:case 51:case 52:return 46;case 48:case 49:return 47;case 53:return 27;case 55:return 6}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:,)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i,/^(?:(.*?)[~](.*?)*[~])/i,/^(?:[\*A-Za-z_][A-Za-z0-9\-_\[\]\(\)]*)/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:one or zero\b)/i,/^(?:one or more\b)/i,/^(?:one or many\b)/i,/^(?:1\+)/i,/^(?:\|o\b)/i,/^(?:zero or one\b)/i,/^(?:zero or more\b)/i,/^(?:zero or many\b)/i,/^(?:0\+)/i,/^(?:\}o\b)/i,/^(?:many\(0\))/i,/^(?:many\(1\))/i,/^(?:many\b)/i,/^(?:\}\|)/i,/^(?:one\b)/i,/^(?:only one\b)/i,/^(?:1\b)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\s*u\b)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:to\b)/i,/^(?:optionally to\b)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:[A-Za-z_][A-Za-z0-9\-_]*)/i,/^(?:.)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},block:{rules:[14,15,16,17,18,19,20,21,22],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55],inclusive:!0}}};function R(){this.yy={}}return b.lexer=k,R.prototype=b,b.Parser=R,new R}();_.parser=_;const f=_;let m={},E=[];const g=function(t,e=void 0){return void 0===m[t]?(m[t]={attributes:[],alias:e},i.l.info("Added new entity :",t)):m[t]&&!m[t].alias&&e&&(m[t].alias=e,i.l.info(`Add alias '${e}' to entity '${t}'`)),m[t]},O={Cardinality:{ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE",MD_PARENT:"MD_PARENT"},Identification:{NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"},getConfig:()=>(0,i.c)().er,addEntity:g,addAttributes:function(t,e){let r,a=g(t);for(r=e.length-1;r>=0;r--)a.attributes.push(e[r]),i.l.debug("Added attribute ",e[r].attributeName)},getEntities:()=>m,addRelationship:function(t,e,r,a){let n={entityA:t,roleA:e,entityB:r,relSpec:a};E.push(n),i.l.debug("Added new relationship :",n)},getRelationships:()=>E,clear:function(){m={},E=[],(0,i.v)()},setAccTitle:i.s,getAccTitle:i.g,setAccDescription:i.b,getAccDescription:i.a,setDiagramTitle:i.q,getDiagramTitle:i.t},b={ONLY_ONE_START:"ONLY_ONE_START",ONLY_ONE_END:"ONLY_ONE_END",ZERO_OR_ONE_START:"ZERO_OR_ONE_START",ZERO_OR_ONE_END:"ZERO_OR_ONE_END",ONE_OR_MORE_START:"ONE_OR_MORE_START",ONE_OR_MORE_END:"ONE_OR_MORE_END",ZERO_OR_MORE_START:"ZERO_OR_MORE_START",ZERO_OR_MORE_END:"ZERO_OR_MORE_END",MD_PARENT_END:"MD_PARENT_END",MD_PARENT_START:"MD_PARENT_START"},k=b,R=function(t,e){let r;t.append("defs").append("marker").attr("id",b.MD_PARENT_START).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",b.MD_PARENT_END).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",b.ONLY_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",b.ONLY_ONE_END).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,0 L3,18 M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",b.ZERO_OR_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",b.ZERO_OR_ONE_END).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,0 L21,18"),t.append("defs").append("marker").attr("id",b.ONE_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",b.ONE_OR_MORE_END).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18"),r=t.append("defs").append("marker").attr("id",b.ZERO_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18"),r=t.append("defs").append("marker").attr("id",b.ZERO_OR_MORE_END).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")},N=/[^\dA-Za-z](\W)*/g;let T={},x=new Map;const A=function(t,e,r){let a;return Object.keys(e).forEach((function(n){const s=function(t="",e=""){const r=t.replace(N,"");return`${v(e)}${v(r)}${p(t,I)}`}(n,"entity");x.set(n,s);const o=t.append("g").attr("id",s);a=void 0===a?s:a;const c="text-"+s,l=o.append("text").classed("er entityLabel",!0).attr("id",c).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","middle").style("font-family",(0,i.c)().fontFamily).style("font-size",T.fontSize+"px").text(e[n].alias??n),{width:h,height:d}=((t,e,r)=>{const a=T.entityPadding/3,n=T.entityPadding/3,s=.85*T.fontSize,o=e.node().getBBox(),c=[];let l=!1,h=!1,d=0,y=0,u=0,p=0,_=o.height+2*a,f=1;r.forEach((t=>{void 0!==t.attributeKeyTypeList&&t.attributeKeyTypeList.length>0&&(l=!0),void 0!==t.attributeComment&&(h=!0)})),r.forEach((r=>{const n=`${e.node().id}-attr-${f}`;let o=0;const m=(0,i.x)(r.attributeType),E=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-type`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(m),g=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-name`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(r.attributeName),O={};O.tn=E,O.nn=g;const b=E.node().getBBox(),k=g.node().getBBox();if(d=Math.max(d,b.width),y=Math.max(y,k.width),o=Math.max(b.height,k.height),l){const e=void 0!==r.attributeKeyTypeList?r.attributeKeyTypeList.join(","):"",a=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-key`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(e);O.kn=a;const c=a.node().getBBox();u=Math.max(u,c.width),o=Math.max(o,c.height)}if(h){const e=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-comment`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(r.attributeComment||"");O.cn=e;const a=e.node().getBBox();p=Math.max(p,a.width),o=Math.max(o,a.height)}O.height=o,c.push(O),_+=o+2*a,f+=1}));let m=4;l&&(m+=2),h&&(m+=2);const E=d+y+u+p,g={width:Math.max(T.minEntityWidth,Math.max(o.width+2*T.entityPadding,E+n*m)),height:r.length>0?_:Math.max(T.minEntityHeight,o.height+2*T.entityPadding)};if(r.length>0){const r=Math.max(0,(g.width-E-n*m)/(m/2));e.attr("transform","translate("+g.width/2+","+(a+o.height/2)+")");let i=o.height+2*a,s="attributeBoxOdd";c.forEach((e=>{const o=i+a+e.height/2;e.tn.attr("transform","translate("+n+","+o+")");const c=t.insert("rect","#"+e.tn.node().id).classed(`er ${s}`,!0).attr("x",0).attr("y",i).attr("width",d+2*n+r).attr("height",e.height+2*a),_=parseFloat(c.attr("x"))+parseFloat(c.attr("width"));e.nn.attr("transform","translate("+(_+n)+","+o+")");const f=t.insert("rect","#"+e.nn.node().id).classed(`er ${s}`,!0).attr("x",_).attr("y",i).attr("width",y+2*n+r).attr("height",e.height+2*a);let m=parseFloat(f.attr("x"))+parseFloat(f.attr("width"));if(l){e.kn.attr("transform","translate("+(m+n)+","+o+")");const c=t.insert("rect","#"+e.kn.node().id).classed(`er ${s}`,!0).attr("x",m).attr("y",i).attr("width",u+2*n+r).attr("height",e.height+2*a);m=parseFloat(c.attr("x"))+parseFloat(c.attr("width"))}h&&(e.cn.attr("transform","translate("+(m+n)+","+o+")"),t.insert("rect","#"+e.cn.node().id).classed(`er ${s}`,"true").attr("x",m).attr("y",i).attr("width",p+2*n+r).attr("height",e.height+2*a)),i+=e.height+2*a,s="attributeBoxOdd"===s?"attributeBoxEven":"attributeBoxOdd"}))}else g.height=Math.max(T.minEntityHeight,_),e.attr("transform","translate("+g.width/2+","+g.height/2+")");return g})(o,l,e[n].attributes),y=o.insert("rect","#"+c).classed("er entityBox",!0).attr("x",0).attr("y",0).attr("width",h).attr("height",d).node().getBBox();r.setNode(s,{width:y.width,height:y.height,shape:"rect",id:s})})),a},M=function(t){return(t.entityA+t.roleA+t.entityB).replace(/\s/g,"")};let w=0;const I="28e9f9db-3c8d-5aa5-9faf-44286ae5937c";function v(t=""){return t.length>0?`${t}-`:""}const D={parser:f,db:O,renderer:{setConf:function(t){const e=Object.keys(t);for(const r of e)T[r]=t[r]},draw:function(t,e,r,o){T=(0,i.c)().er,i.l.info("Drawing ER diagram");const c=(0,i.c)().securityLevel;let l;"sandbox"===c&&(l=(0,n.Ltv)("#i"+e));const h=("sandbox"===c?(0,n.Ltv)(l.nodes()[0].contentDocument.body):(0,n.Ltv)("body")).select(`[id='${e}']`);let d;R(h,T),d=new a.T({multigraph:!0,directed:!0,compound:!1}).setGraph({rankdir:T.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));const y=A(h,o.db.getEntities(),d),u=function(t,e){return t.forEach((function(t){e.setEdge(x.get(t.entityA),x.get(t.entityB),{relationship:t},M(t))})),t}(o.db.getRelationships(),d);var p,_;(0,s.Zp)(d),p=h,(_=d).nodes().forEach((function(t){void 0!==t&&void 0!==_.node(t)&&p.select("#"+t).attr("transform","translate("+(_.node(t).x-_.node(t).width/2)+","+(_.node(t).y-_.node(t).height/2)+" )")})),u.forEach((function(t){!function(t,e,r,a,s){w++;const o=r.edge(x.get(e.entityA),x.get(e.entityB),M(e)),c=(0,n.n8j)().x((function(t){return t.x})).y((function(t){return t.y})).curve(n.qrM),l=t.insert("path","#"+a).classed("er relationshipLine",!0).attr("d",c(o.points)).style("stroke",T.stroke).style("fill","none");e.relSpec.relType===s.db.Identification.NON_IDENTIFYING&&l.attr("stroke-dasharray","8,8");let h="";switch(T.arrowMarkerAbsolute&&(h=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,h=h.replace(/\(/g,"\\("),h=h.replace(/\)/g,"\\)")),e.relSpec.cardA){case s.db.Cardinality.ZERO_OR_ONE:l.attr("marker-end","url("+h+"#"+k.ZERO_OR_ONE_END+")");break;case s.db.Cardinality.ZERO_OR_MORE:l.attr("marker-end","url("+h+"#"+k.ZERO_OR_MORE_END+")");break;case s.db.Cardinality.ONE_OR_MORE:l.attr("marker-end","url("+h+"#"+k.ONE_OR_MORE_END+")");break;case s.db.Cardinality.ONLY_ONE:l.attr("marker-end","url("+h+"#"+k.ONLY_ONE_END+")");break;case s.db.Cardinality.MD_PARENT:l.attr("marker-end","url("+h+"#"+k.MD_PARENT_END+")")}switch(e.relSpec.cardB){case s.db.Cardinality.ZERO_OR_ONE:l.attr("marker-start","url("+h+"#"+k.ZERO_OR_ONE_START+")");break;case s.db.Cardinality.ZERO_OR_MORE:l.attr("marker-start","url("+h+"#"+k.ZERO_OR_MORE_START+")");break;case s.db.Cardinality.ONE_OR_MORE:l.attr("marker-start","url("+h+"#"+k.ONE_OR_MORE_START+")");break;case s.db.Cardinality.ONLY_ONE:l.attr("marker-start","url("+h+"#"+k.ONLY_ONE_START+")");break;case s.db.Cardinality.MD_PARENT:l.attr("marker-start","url("+h+"#"+k.MD_PARENT_START+")")}const d=l.node().getTotalLength(),y=l.node().getPointAtLength(.5*d),u="rel"+w,p=t.append("text").classed("er relationshipLabel",!0).attr("id",u).attr("x",y.x).attr("y",y.y).style("text-anchor","middle").style("dominant-baseline","middle").style("font-family",(0,i.c)().fontFamily).style("font-size",T.fontSize+"px").text(e.roleA).node().getBBox();t.insert("rect","#"+u).classed("er relationshipLabelBox",!0).attr("x",y.x-p.width/2).attr("y",y.y-p.height/2).attr("width",p.width).attr("height",p.height)}(h,t,d,y,o)}));const f=T.diagramPadding;i.u.insertTitle(h,"entityTitleText",T.titleTopMargin,o.db.getDiagramTitle());const m=h.node().getBBox(),E=m.width+2*f,g=m.height+2*f;(0,i.i)(h,g,E,T.useMaxWidth),h.attr("viewBox",`${m.x-f} ${m.y-f} ${E} ${g}`)}},styles:t=>`\n .entityBox {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxOdd {\n fill: ${t.attributeBackgroundColorOdd};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxEven {\n fill: ${t.attributeBackgroundColorEven};\n stroke: ${t.nodeBorder};\n }\n\n .relationshipLabelBox {\n fill: ${t.tertiaryColor};\n opacity: 0.7;\n background-color: ${t.tertiaryColor};\n rect {\n opacity: 0.5;\n }\n }\n\n .relationshipLine {\n stroke: ${t.lineColor};\n }\n\n .entityTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n } \n #MD_PARENT_START {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n #MD_PARENT_END {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n \n`}}}]); \ No newline at end of file diff --git a/assets/js/83100446.f32a0f06.js b/assets/js/83100446.f32a0f06.js new file mode 100644 index 0000000000..a26212f379 --- /dev/null +++ b/assets/js/83100446.f32a0f06.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3953],{87658:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>p,frontMatter:()=>s,metadata:()=>i,toc:()=>d});var o=t(74848),r=t(28453);const s={},c="Overview",i={id:"container/deployment-examples/a/index",title:"Overview",description:"TODO",source:"@site/docs/03-container/deployment-examples/a/index.md",sourceDirName:"03-container/deployment-examples/a",slug:"/container/deployment-examples/a/",permalink:"/docs/container/deployment-examples/a/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/deployment-examples/a/index.md",tags:[],version:"current",frontMatter:{}},a={},d=[];function l(e){const n={h1:"h1",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"overview",children:"Overview"}),"\n",(0,o.jsx)(n.p,{children:"TODO"})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var o=t(96540);const r={},s=o.createContext(r);function c(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8327.fc19b891.js b/assets/js/8327.fc19b891.js new file mode 100644 index 0000000000..478b76af33 --- /dev/null +++ b/assets/js/8327.fc19b891.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8327],{30708:(t,e,n)=>{n.d(e,{diagram:()=>j});var i=n(76257),s=n(26312),r=n(58886),a=(n(74353),n(16750),n(42838),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[6,8,10,11,12,14,16,17,18],n=[1,9],i=[1,10],s=[1,11],r=[1,12],a=[1,13],o=[1,14],c={trace:function(){},yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 9:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 10:case 11:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 12:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 13:i.addTask(r[o-1],r[o]),this.$="task"}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:n,12:i,14:s,16:r,17:a,18:o},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:n,12:i,14:s,16:r,17:a,18:o},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,o="",c=0,l=0,h=r.slice.call(arguments,1),y=Object.create(this.lexer),u={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(u.yy[p]=this.yy[p]);y.setInput(t,u.yy),u.yy.lexer=y,u.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var d=y.yylloc;r.push(d);var f=y.options&&y.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var g,x,m,k,_,b,v,$,w,M={};;){if(x=n[n.length-1],this.defaultActions[x]?m=this.defaultActions[x]:(null==g&&(w=void 0,"number"!=typeof(w=i.pop()||y.lex()||1)&&(w instanceof Array&&(w=(i=w).pop()),w=e.symbols_[w]||w),g=w),m=a[x]&&a[x][g]),void 0===m||!m.length||!m[0]){var E="";for(_ in $=[],a[x])this.terminals_[_]&&_>2&&$.push("'"+this.terminals_[_]+"'");E=y.showPosition?"Parse error on line "+(c+1)+":\n"+y.showPosition()+"\nExpecting "+$.join(", ")+", got '"+(this.terminals_[g]||g)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==g?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(E,{text:y.match,token:this.terminals_[g]||g,line:y.yylineno,loc:d,expected:$})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+g);switch(m[0]){case 1:n.push(g),s.push(y.yytext),r.push(y.yylloc),n.push(m[1]),g=null,l=y.yyleng,o=y.yytext,c=y.yylineno,d=y.yylloc;break;case 2:if(b=this.productions_[m[1]][1],M.$=s[s.length-b],M._$={first_line:r[r.length-(b||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(b||1)].first_column,last_column:r[r.length-1].last_column},f&&(M._$.range=[r[r.length-(b||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply(M,[o,l,c,u.yy,m[1],s,r].concat(h))))return k;b&&(n=n.slice(0,-1*b*2),s=s.slice(0,-1*b),r=r.slice(0,-1*b)),n.push(this.productions_[m[1]][0]),s.push(M.$),r.push(M._$),v=a[n[n.length-2]][n[n.length-1]],n.push(v);break;case 3:return!0}}return!0}},l={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:case 1:case 3:case 4:break;case 2:return 10;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),14;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 18;case 16:return 19;case 17:return":";case 18:return 6;case 19:return"INVALID"}},rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18,19],inclusive:!0}}};function h(){this.yy={}}return c.lexer=l,h.prototype=c,c.Parser=h,new h}());a.parser=a;const o=a;let c="";const l=[],h=[],y=[],u=function(){let t=!0;for(const[e,n]of y.entries())y[e].processed,t=t&&n.processed;return t},p={getConfig:()=>(0,i.c)().journey,clear:function(){l.length=0,h.length=0,c="",y.length=0,(0,i.v)()},setDiagramTitle:i.q,getDiagramTitle:i.t,setAccTitle:i.s,getAccTitle:i.g,setAccDescription:i.b,getAccDescription:i.a,addSection:function(t){c=t,l.push(t)},getSections:function(){return l},getTasks:function(){let t=u();let e=0;for(;!t&&e<100;)t=u(),e++;return h.push(...y),h},addTask:function(t,e){const n=e.substr(1).split(":");let i=0,s=[];1===n.length?(i=Number(n[0]),s=[]):(i=Number(n[0]),s=n[1].split(","));const r=s.map((t=>t.trim())),a={section:c,type:c,people:r,task:t,score:i};y.push(a)},addTaskOrg:function(t){const e={section:c,type:c,description:t,task:t,classes:[]};h.push(e)},getActors:function(){return function(){const t=[];return h.forEach((e=>{e.people&&t.push(...e.people)})),[...new Set(t)].sort()}()}},d=t=>`.label {\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n color: ${t.textColor};\n }\n .mouth {\n stroke: #666;\n }\n\n line {\n stroke: ${t.textColor}\n }\n\n .legend {\n fill: ${t.textColor};\n }\n\n .label text {\n fill: #333;\n }\n .label {\n color: ${t.textColor}\n }\n\n .face {\n ${t.faceColor?`fill: ${t.faceColor}`:"fill: #FFF8DC"};\n stroke: #999;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 1.5px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n rect {\n opacity: 0.5;\n }\n text-align: center;\n }\n\n .cluster rect {\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .task-type-0, .section-type-0 {\n ${t.fillType0?`fill: ${t.fillType0}`:""};\n }\n .task-type-1, .section-type-1 {\n ${t.fillType0?`fill: ${t.fillType1}`:""};\n }\n .task-type-2, .section-type-2 {\n ${t.fillType0?`fill: ${t.fillType2}`:""};\n }\n .task-type-3, .section-type-3 {\n ${t.fillType0?`fill: ${t.fillType3}`:""};\n }\n .task-type-4, .section-type-4 {\n ${t.fillType0?`fill: ${t.fillType4}`:""};\n }\n .task-type-5, .section-type-5 {\n ${t.fillType0?`fill: ${t.fillType5}`:""};\n }\n .task-type-6, .section-type-6 {\n ${t.fillType0?`fill: ${t.fillType6}`:""};\n }\n .task-type-7, .section-type-7 {\n ${t.fillType0?`fill: ${t.fillType7}`:""};\n }\n\n .actor-0 {\n ${t.actor0?`fill: ${t.actor0}`:""};\n }\n .actor-1 {\n ${t.actor1?`fill: ${t.actor1}`:""};\n }\n .actor-2 {\n ${t.actor2?`fill: ${t.actor2}`:""};\n }\n .actor-3 {\n ${t.actor3?`fill: ${t.actor3}`:""};\n }\n .actor-4 {\n ${t.actor4?`fill: ${t.actor4}`:""};\n }\n .actor-5 {\n ${t.actor5?`fill: ${t.actor5}`:""};\n }\n`,f=function(t,e){return(0,r.d)(t,e)},g=function(t,e){const n=t.append("circle");return n.attr("cx",e.cx),n.attr("cy",e.cy),n.attr("class","actor-"+e.pos),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("r",e.r),void 0!==n.class&&n.attr("class",n.class),void 0!==e.title&&n.append("title").text(e.title),n},x=function(t,e){return(0,r.f)(t,e)};let m=-1;const k=function(){function t(t,e,n,s,r,a,o,c){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",c).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,c,l){const{taskFontSize:h,taskFontFamily:y}=c,u=t.split(/<br\s*\/?>/gi);for(let p=0;p<u.length;p++){const t=p*h-h*(u.length-1)/2,c=e.append("text").attr("x",n+r/2).attr("y",s).attr("fill",l).style("text-anchor","middle").style("font-size",h).style("font-family",y);c.append("tspan").attr("x",n+r/2).attr("dy",t).text(u[p]),c.attr("y",s+a/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(c,o)}}function n(t,n,s,r,a,o,c,l){const h=n.append("switch"),y=h.append("foreignObject").attr("x",s).attr("y",r).attr("width",a).attr("height",o).attr("position","fixed").append("xhtml:div").style("display","table").style("height","100%").style("width","100%");y.append("div").attr("class","label").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,s,r,a,o,c,l),i(y,c)}function i(t,e){for(const n in e)n in e&&t.attr(n,e[n])}return function(i){return"fo"===i.textPlacement?n:"old"===i.textPlacement?t:e}}(),_=g,b=function(t,e,n){const i=t.append("g"),s=(0,r.g)();s.x=e.x,s.y=e.y,s.fill=e.fill,s.width=n.width*e.taskCount+n.diagramMarginX*(e.taskCount-1),s.height=n.height,s.class="journey-section section-type-"+e.num,s.rx=3,s.ry=3,f(i,s),k(n)(e.text,i,s.x,s.y,s.width,s.height,{class:"journey-section section-type-"+e.num},n,e.colour)},v=x,$=function(t,e,n){const i=e.x+n.width/2,a=t.append("g");m++;a.append("line").attr("id","task"+m).attr("x1",i).attr("y1",e.y).attr("x2",i).attr("y2",450).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),function(t,e){const n=15,i=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",n).attr("stroke-width",2).attr("overflow","visible"),r=t.append("g");r.append("circle").attr("cx",e.cx-5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),r.append("circle").attr("cx",e.cx+5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),e.score>3?function(t){const i=(0,s.JLW)().startAngle(Math.PI/2).endAngle(Math.PI/2*3).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}(r):e.score<3?function(t){const i=(0,s.JLW)().startAngle(3*Math.PI/2).endAngle(Math.PI/2*5).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}(r):r.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}(a,{cx:i,cy:300+30*(5-e.score),score:e.score});const o=(0,r.g)();o.x=e.x,o.y=e.y,o.fill=e.fill,o.width=n.width,o.height=n.height,o.class="task task-type-"+e.num,o.rx=3,o.ry=3,f(a,o);let c=e.x+14;e.people.forEach((t=>{const n=e.actors[t].color,i={cx:c,cy:e.y,r:7,fill:n,stroke:"#000",title:t,pos:e.actors[t].position};g(a,i),c+=10})),k(n)(e.task,a,o.x,o.y,o.width,o.height,{class:"task"},n,e.colour)},w=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},M={};const E=(0,i.c)().journey,T=E.leftMargin,S={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},updateVal:function(t,e,n,i){void 0===t[e]?t[e]=n:t[e]=i(n,t[e])},updateBounds:function(t,e,n,s){const r=(0,i.c)().journey,a=this;let o=0;var c;this.sequenceItems.forEach((function(i){o++;const l=a.sequenceItems.length-o+1;a.updateVal(i,"starty",e-l*r.boxMargin,Math.min),a.updateVal(i,"stopy",s+l*r.boxMargin,Math.max),a.updateVal(S.data,"startx",t-l*r.boxMargin,Math.min),a.updateVal(S.data,"stopx",n+l*r.boxMargin,Math.max),"activation"!==c&&(a.updateVal(i,"startx",t-l*r.boxMargin,Math.min),a.updateVal(i,"stopx",n+l*r.boxMargin,Math.max),a.updateVal(S.data,"starty",e-l*r.boxMargin,Math.min),a.updateVal(S.data,"stopy",s+l*r.boxMargin,Math.max))}))},insert:function(t,e,n,i){const s=Math.min(t,n),r=Math.max(t,n),a=Math.min(e,i),o=Math.max(e,i);this.updateVal(S.data,"startx",s,Math.min),this.updateVal(S.data,"starty",a,Math.min),this.updateVal(S.data,"stopx",r,Math.max),this.updateVal(S.data,"stopy",o,Math.max),this.updateBounds(s,a,r,o)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return this.data}},A=E.sectionFills,I=E.sectionColours,P=function(t,e,n){const s=(0,i.c)().journey;let r="";const a=n+(2*s.height+s.diagramMarginY);let o=0,c="#CCC",l="black",h=0;for(const[i,y]of e.entries()){if(r!==y.section){c=A[o%A.length],h=o%A.length,l=I[o%I.length];let n=0;const a=y.section;for(let t=i;t<e.length&&e[t].section==a;t++)n+=1;const u={x:i*s.taskMargin+i*s.width+T,y:50,text:y.section,fill:c,num:h,colour:l,taskCount:n};b(t,u,s),r=y.section,o++}const n=y.people.reduce(((t,e)=>(M[e]&&(t[e]=M[e]),t)),{});y.x=i*s.taskMargin+i*s.width+T,y.y=a,y.width=s.diagramMarginX,y.height=s.diagramMarginY,y.colour=l,y.fill=c,y.num=h,y.actors=n,$(t,y,s),S.insert(y.x,y.y,y.x+y.width+s.taskMargin,450)}},C={setConf:function(t){Object.keys(t).forEach((function(e){E[e]=t[e]}))},draw:function(t,e,n,r){const a=(0,i.c)().journey,o=(0,i.c)().securityLevel;let c;"sandbox"===o&&(c=(0,s.Ltv)("#i"+e));const l="sandbox"===o?(0,s.Ltv)(c.nodes()[0].contentDocument.body):(0,s.Ltv)("body");S.init();const h=l.select("#"+e);w(h);const y=r.db.getTasks(),u=r.db.getDiagramTitle(),p=r.db.getActors();for(const i in M)delete M[i];let d=0;p.forEach((t=>{M[t]={color:a.actorColours[d%a.actorColours.length],position:d},d++})),function(t){const e=(0,i.c)().journey;let n=60;Object.keys(M).forEach((i=>{const s=M[i].color,r={cx:20,cy:n,r:7,fill:s,stroke:"#000",pos:M[i].position};_(t,r);const a={x:40,y:n+7,fill:"#666",text:i,textMargin:5|e.boxTextMargin};v(t,a),n+=20}))}(h),S.insert(0,0,T,50*Object.keys(M).length),P(h,y,0);const f=S.getBounds();u&&h.append("text").text(u).attr("x",T).attr("font-size","4ex").attr("font-weight","bold").attr("y",25);const g=f.stopy-f.starty+2*a.diagramMarginY,x=T+f.stopx+2*a.diagramMarginX;(0,i.i)(h,g,x,a.useMaxWidth),h.append("line").attr("x1",T).attr("y1",4*a.height).attr("x2",x-T-4).attr("y2",4*a.height).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");const m=u?70:0;h.attr("viewBox",`${f.startx} -25 ${x} ${g+m}`),h.attr("preserveAspectRatio","xMinYMin meet"),h.attr("height",g+m+25)}},j={parser:o,db:p,renderer:C,styles:d,init:t=>{C.setConf(t.journey),p.clear()}}},58886:(t,e,n)=>{n.d(e,{a:()=>a,b:()=>l,c:()=>c,d:()=>r,e:()=>y,f:()=>o,g:()=>h});var i=n(16750),s=n(76257);const r=(t,e)=>{const n=t.append("rect");if(n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),e.name&&n.attr("name",e.name),void 0!==e.rx&&n.attr("rx",e.rx),void 0!==e.ry&&n.attr("ry",e.ry),void 0!==e.attrs)for(const i in e.attrs)n.attr(i,e.attrs[i]);return void 0!==e.class&&n.attr("class",e.class),n},a=(t,e)=>{const n={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};r(t,n).lower()},o=(t,e)=>{const n=e.text.replace(s.J," "),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.attr("class","legend"),i.style("text-anchor",e.anchor),void 0!==e.class&&i.attr("class",e.class);const r=i.append("tspan");return r.attr("x",e.x+2*e.textMargin),r.text(n),i},c=(t,e,n,s)=>{const r=t.append("image");r.attr("x",e),r.attr("y",n);const a=(0,i.Jf)(s);r.attr("xlink:href",a)},l=(t,e,n,s)=>{const r=t.append("use");r.attr("x",e),r.attr("y",n);const a=(0,i.Jf)(s);r.attr("xlink:href",`#${a}`)},h=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),y=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})}}]); \ No newline at end of file diff --git a/assets/js/8444.e056eb00.js b/assets/js/8444.e056eb00.js new file mode 100644 index 0000000000..8702f479c2 --- /dev/null +++ b/assets/js/8444.e056eb00.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8444],{36063:(t,e,i)=>{i.d(e,{diagram:()=>d});var n=i(76257),s=i(26312),r=(i(74353),i(16750),i(42838),function(){var t=function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i},e=[1,3],i=[1,4],n=[1,5],s=[1,6],r=[1,10,12,14,16,18,19,20,21,22],l=[2,4],a=[1,5,10,12,14,16,18,19,20,21,22],c=[20,21,22],o=[2,7],h=[1,12],u=[1,13],y=[1,14],p=[1,15],d=[1,16],g=[1,17],f={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,PIE:5,document:6,showData:7,line:8,statement:9,txt:10,value:11,title:12,title_value:13,acc_title:14,acc_title_value:15,acc_descr:16,acc_descr_value:17,acc_descr_multiline_value:18,section:19,NEWLINE:20,";":21,EOF:22,$accept:0,$end:1},terminals_:{2:"error",5:"PIE",7:"showData",10:"txt",11:"value",12:"title",13:"title_value",14:"acc_title",15:"acc_title_value",16:"acc_descr",17:"acc_descr_value",18:"acc_descr_multiline_value",19:"section",20:"NEWLINE",21:";",22:"EOF"},productions_:[0,[3,2],[3,2],[3,3],[6,0],[6,2],[8,2],[9,0],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[4,1],[4,1],[4,1]],performAction:function(t,e,i,n,s,r,l){var a=r.length-1;switch(s){case 3:n.setShowData(!0);break;case 6:this.$=r[a-1];break;case 8:n.addSection(r[a-1],n.cleanupValue(r[a]));break;case 9:this.$=r[a].trim(),n.setDiagramTitle(this.$);break;case 10:this.$=r[a].trim(),n.setAccTitle(this.$);break;case 11:case 12:this.$=r[a].trim(),n.setAccDescription(this.$);break;case 13:n.addSection(r[a].substr(8)),this.$=r[a].substr(8)}},table:[{3:1,4:2,5:e,20:i,21:n,22:s},{1:[3]},{3:7,4:2,5:e,20:i,21:n,22:s},t(r,l,{6:8,7:[1,9]}),t(a,[2,14]),t(a,[2,15]),t(a,[2,16]),{1:[2,1]},t(c,o,{8:10,9:11,1:[2,2],10:h,12:u,14:y,16:p,18:d,19:g}),t(r,l,{6:18}),t(r,[2,5]),{4:19,20:i,21:n,22:s},{11:[1,20]},{13:[1,21]},{15:[1,22]},{17:[1,23]},t(c,[2,12]),t(c,[2,13]),t(c,o,{8:10,9:11,1:[2,3],10:h,12:u,14:y,16:p,18:d,19:g}),t(r,[2,6]),t(c,[2,8]),t(c,[2,9]),t(c,[2,10]),t(c,[2,11])],defaultActions:{7:[2,1]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=this,i=[0],n=[],s=[null],r=[],l=this.table,a="",c=0,o=0,h=r.slice.call(arguments,1),u=Object.create(this.lexer),y={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(y.yy[p]=this.yy[p]);u.setInput(t,y.yy),y.yy.lexer=u,y.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var d=u.yylloc;r.push(d);var g=u.options&&u.options.ranges;"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,_,m,k,b,x,v,S,w,$={};;){if(_=i[i.length-1],this.defaultActions[_]?m=this.defaultActions[_]:(null==f&&(w=void 0,"number"!=typeof(w=n.pop()||u.lex()||1)&&(w instanceof Array&&(w=(n=w).pop()),w=e.symbols_[w]||w),f=w),m=l[_]&&l[_][f]),void 0===m||!m.length||!m[0]){var E="";for(b in S=[],l[_])this.terminals_[b]&&b>2&&S.push("'"+this.terminals_[b]+"'");E=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+S.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(E,{text:u.match,token:this.terminals_[f]||f,line:u.yylineno,loc:d,expected:S})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+f);switch(m[0]){case 1:i.push(f),s.push(u.yytext),r.push(u.yylloc),i.push(m[1]),f=null,o=u.yyleng,a=u.yytext,c=u.yylineno,d=u.yylloc;break;case 2:if(x=this.productions_[m[1]][1],$.$=s[s.length-x],$._$={first_line:r[r.length-(x||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(x||1)].first_column,last_column:r[r.length-1].last_column},g&&($._$.range=[r[r.length-(x||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply($,[a,o,c,y.yy,m[1],s,r].concat(h))))return k;x&&(i=i.slice(0,-1*x*2),s=s.slice(0,-1*x),r=r.slice(0,-1*x)),i.push(this.productions_[m[1]][0]),s.push($.$),r.push($._$),v=l[i[i.length-2]][i[i.length-1]],i.push(v);break;case 3:return!0}}return!0}},_={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,i=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var i,n,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((i=this._input.match(this.rules[s[r]]))&&(!e||i[0].length>e[0].length)){if(e=i,n=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,i,n){switch(i){case 0:case 1:case 3:case 4:break;case 2:return 20;case 5:return this.begin("title"),12;case 6:return this.popState(),"title_value";case 7:return this.begin("acc_title"),14;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),16;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:case 15:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:this.begin("string");break;case 16:return"txt";case 17:return 5;case 18:return 7;case 19:return"value";case 20:return 22}},rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:[\s]+)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:pie\b)/i,/^(?:showData\b)/i,/^(?::[\s]*[\d]+(?:\.[\d]+)?)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[6],inclusive:!1},string:{rules:[15,16],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,7,9,11,14,17,18,19,20],inclusive:!0}}};function m(){this.yy={}}return f.lexer=_,m.prototype=f,f.Parser=m,new m}());r.parser=r;const l=r,a=n.B.pie,c={},o=!1;let h=c,u=o;const y=structuredClone(a),p={getConfig:()=>structuredClone(y),clear:()=>{h=structuredClone(c),u=o,(0,n.v)()},setDiagramTitle:n.q,getDiagramTitle:n.t,setAccTitle:n.s,getAccTitle:n.g,setAccDescription:n.b,getAccDescription:n.a,addSection:(t,e)=>{t=(0,n.d)(t,(0,n.c)()),void 0===h[t]&&(h[t]=e,n.l.debug(`added new section: ${t}, with value: ${e}`))},getSections:()=>h,cleanupValue:t=>(":"===t.substring(0,1)&&(t=t.substring(1).trim()),Number(t.trim())),setShowData:t=>{u=t},getShowData:()=>u},d={parser:l,db:p,renderer:{draw:(t,e,i,r)=>{n.l.debug("rendering pie chart\n"+t);const l=r.db,a=(0,n.c)(),c=(0,n.C)(l.getConfig(),a.pie),o=18,h=450,u=h,y=(0,n.A)(e),p=y.append("g"),d=l.getSections();p.attr("transform","translate(225,225)");const{themeVariables:g}=a;let[f]=(0,n.D)(g.pieOuterStrokeWidth);f??(f=2);const _=c.textPosition,m=Math.min(u,h)/2-40,k=(0,s.JLW)().innerRadius(0).outerRadius(m),b=(0,s.JLW)().innerRadius(m*_).outerRadius(m*_);p.append("circle").attr("cx",0).attr("cy",0).attr("r",m+f/2).attr("class","pieOuterCircle");const x=(t=>{const e=Object.entries(t).map((t=>({label:t[0],value:t[1]}))).sort(((t,e)=>e.value-t.value));return(0,s.rLf)().value((t=>t.value))(e)})(d),v=[g.pie1,g.pie2,g.pie3,g.pie4,g.pie5,g.pie6,g.pie7,g.pie8,g.pie9,g.pie10,g.pie11,g.pie12],S=(0,s.UMr)(v);p.selectAll("mySlices").data(x).enter().append("path").attr("d",k).attr("fill",(t=>S(t.data.label))).attr("class","pieCircle");let w=0;Object.keys(d).forEach((t=>{w+=d[t]})),p.selectAll("mySlices").data(x).enter().append("text").text((t=>(t.data.value/w*100).toFixed(0)+"%")).attr("transform",(t=>"translate("+b.centroid(t)+")")).style("text-anchor","middle").attr("class","slice"),p.append("text").text(l.getDiagramTitle()).attr("x",0).attr("y",-200).attr("class","pieTitleText");const $=p.selectAll(".legend").data(S.domain()).enter().append("g").attr("class","legend").attr("transform",((t,e)=>"translate(216,"+(22*e-22*S.domain().length/2)+")"));$.append("rect").attr("width",o).attr("height",o).style("fill",S).style("stroke",S),$.data(x).append("text").attr("x",22).attr("y",14).text((t=>{const{label:e,value:i}=t.data;return l.getShowData()?`${e} [${i}]`:e}));const E=512+Math.max(...$.selectAll("text").nodes().map((t=>(null==t?void 0:t.getBoundingClientRect().width)??0)));y.attr("viewBox",`0 0 ${E} 450`),(0,n.i)(y,h,E,c.useMaxWidth)}},styles:t=>`\n .pieCircle{\n stroke: ${t.pieStrokeColor};\n stroke-width : ${t.pieStrokeWidth};\n opacity : ${t.pieOpacity};\n }\n .pieOuterCircle{\n stroke: ${t.pieOuterStrokeColor};\n stroke-width: ${t.pieOuterStrokeWidth};\n fill: none;\n }\n .pieTitleText {\n text-anchor: middle;\n font-size: ${t.pieTitleTextSize};\n fill: ${t.pieTitleTextColor};\n font-family: ${t.fontFamily};\n }\n .slice {\n font-family: ${t.fontFamily};\n fill: ${t.pieSectionTextColor};\n font-size:${t.pieSectionTextSize};\n // fill: white;\n }\n .legend text {\n fill: ${t.pieLegendTextColor};\n font-family: ${t.fontFamily};\n font-size: ${t.pieLegendTextSize};\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/8493ac52.0281f0fe.js b/assets/js/8493ac52.0281f0fe.js new file mode 100644 index 0000000000..f2cc65e12f --- /dev/null +++ b/assets/js/8493ac52.0281f0fe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5054],{8905:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>u,frontMatter:()=>c,metadata:()=>r,toc:()=>i});var o=s(74848),n=s(28453);const c={},l="Developer Guide",r={id:"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop",title:"Developer Guide",description:"Developing Cluster Stack Provider OpenStack operator is quite straightforward. First, you need to install some basic prerequisites:",source:"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop.md",sourceDirName:"03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs",slug:"/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop",permalink:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Controllers",permalink:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers"},next:{title:"Container Registry",permalink:"/docs/category/container-registry"}},a={},i=[{value:"Setting Tilt up",id:"setting-tilt-up",level:2},{value:"Developing with Tilt",id:"developing-with-tilt",level:2},{value:"Applying ClusterStack",id:"applying-clusterstack",level:3},{value:"Creating workload cluster",id:"creating-workload-cluster",level:3},{value:"Toggle between local_mode and remote mode",id:"toggle-between-local_mode-and-remote-mode",level:2}];function d(e){const t={a:"a",blockquote:"blockquote",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,n.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"developer-guide",children:"Developer Guide"}),"\n",(0,o.jsx)(t.p,{children:"Developing Cluster Stack Provider OpenStack operator is quite straightforward. First, you need to install some basic prerequisites:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Docker"}),"\n",(0,o.jsx)(t.li,{children:"Go"}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"Next, configure your environment variables. Once that's done, you can initiate development using the local Kind cluster and the Tilt UI to create a workload cluster that comes pre-configured."}),"\n",(0,o.jsx)(t.h2,{id:"setting-tilt-up",children:"Setting Tilt up"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsx)(t.li,{children:"Install Docker and Go. We expect you to run on a Linux OS."}),"\n",(0,o.jsxs)(t.li,{children:["Create an ",(0,o.jsx)(t.code,{children:".envrc"})," file and specify the values you need. See the ",(0,o.jsx)(t.code,{children:".envrc.sample"})," for details."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"developing-with-tilt",children:"Developing with Tilt"}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"tilt",src:s(8860).A+"",title:"Tilt",width:"1848",height:"902"})}),"\n",(0,o.jsx)(t.p,{children:"Operator development requires a lot of iteration, and the \u201cbuild, tag, push, update deployment\u201d workflow can be very tedious. Tilt makes this process much simpler by watching for updates and automatically building and deploying them. To build a kind cluster and to start Tilt, run:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-shell",children:"make tilt-up\n"})}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsxs)(t.p,{children:["To access the Tilt UI please go to: ",(0,o.jsx)(t.code,{children:"http://localhost:10351"})]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"You should make sure that everything in the UI looks green. If not, you can trigger the Tilt workflow again."}),"\n",(0,o.jsx)(t.h3,{id:"applying-clusterstack",children:"Applying ClusterStack"}),"\n",(0,o.jsxs)(t.p,{children:["When you start your tilt setup then the ClusterStack manifest gets copied from ",(0,o.jsx)(t.code,{children:"config/cspo"})," directory to root of your repository. In order to apply the ClusterStack to the running local development cluster, you can click on the tilt UI. There should a click on the top-right hand side that is named as ",(0,o.jsx)(t.code,{children:"apply-clusterstack"})," if you hover over it.\nOnce the ClusterStack is applied wait for the ClusterStack and ClusterStackRelease object to be ready. In case your ClusterStack shows that it is ready, you can deploy a workload cluster."]}),"\n",(0,o.jsx)(t.h3,{id:"creating-workload-cluster",children:"Creating workload cluster"}),"\n",(0,o.jsxs)(t.p,{children:["This could be done through the Tilt UI, by pressing the button in the top right corner ",(0,o.jsx)(t.code,{children:"Create Workload Cluster"}),". This triggers the ",(0,o.jsx)(t.code,{children:"make create-workload-cluster-openstack"}),", which uses the environment variables and the cluster-template."]}),"\n",(0,o.jsx)(t.p,{children:"To interact with your freshly created workload cluster, you can use these commands:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-shell",children:'make get-kubeconfig-workload-cluster #KUBECONFIG for the workload cluster is placed here: ".workload-cluster-kubeconfig.yaml"\nexport KUBECONFIG=$PWD/.workload-cluster-kubeconfig.yaml\n'})}),"\n",(0,o.jsx)(t.p,{children:"In case you want to change some code, you can do so and see that Tilt triggers on save. It will update the container of the operator automatically."}),"\n",(0,o.jsxs)(t.p,{children:["If you want to change something in your ClusterStack or Cluster custom resources, you can have a look at ",(0,o.jsx)(t.code,{children:".cluster.yaml"})," and ",(0,o.jsx)(t.code,{children:".clusterstack.yaml"}),", which Tilt uses."]}),"\n",(0,o.jsxs)(t.p,{children:["To delete the ClusterStack you can click on the ",(0,o.jsx)(t.code,{children:"delete-clusterstack"})," button in the tilt UI."]}),"\n",(0,o.jsxs)(t.p,{children:["To tear down the workload cluster, click on the ",(0,o.jsx)(t.code,{children:"Delete Workload Cluster"})," button in the top right corner of the Tilt UI. This action triggers the execution of ",(0,o.jsx)(t.code,{children:"make delete-workload-cluster-openstack"}),". After a few minutes, the resources should be successfully deleted."]}),"\n",(0,o.jsx)(t.p,{children:"To tear down the kind cluster, use:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-shell",children:"make delete-bootstrap-cluster\n"})}),"\n",(0,o.jsxs)(t.p,{children:["If you have any trouble finding the right command, then you can use ",(0,o.jsx)(t.code,{children:"make help"})," to get a list of all available make targets."]}),"\n",(0,o.jsx)(t.h2,{id:"toggle-between-local_mode-and-remote-mode",children:"Toggle between local_mode and remote mode"}),"\n",(0,o.jsxs)(t.p,{children:["We can retrieve cluster-stacks in two modes. One way is to let the controller fetch it from GitHub which is remote mode and other is we mount the cluster-stacks inside the container at ",(0,o.jsx)(t.code,{children:"/tmp/downloads/cluster-stacks"})," directory."]}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsxs)(t.p,{children:["[!NOTE]",(0,o.jsx)(t.br,{}),"\n","Using remote mode is the default behavior."]}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["Switching between both modes is relatively simple if you're using Tilt. There is a file at the root of the repo ",(0,o.jsx)(t.code,{children:"tilt-settings.yaml.example"}),"\nMake a copy of that file with the name of ",(0,o.jsx)(t.code,{children:"tilt-settings.yaml"})]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"cp tilt-settings.yaml.example tilt-settings.yaml\n"})}),"\n",(0,o.jsxs)(t.p,{children:["Now, open the file and set the ",(0,o.jsx)(t.code,{children:"local_mode"})," to ",(0,o.jsx)(t.code,{children:"true"})," to use cluster-stacks in local_mode. It should look the following content wise."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-yaml",children:"local_mode: true\n"})}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsx)(t.p,{children:"[!NOTE]\nIn this mode you need to have cluster-stacks present locally."}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"Downloading cluster-stacks can be achieved by many ways but below is a simple way to download it quickly."}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"mkdir -p .release/openstack-scs-1-27-v1/\ncd .release/openstack-scs-1-27-v1\ngh release download --repo SovereignCloudStack/cluster-stacks openstack-scs-1-27-v1\n"})}),"\n",(0,o.jsxs)(t.p,{children:["Change the repo and tag as per the requirement. You can also download it directly from browser and move it to ",(0,o.jsx)(t.code,{children:".release"})," directory."]}),"\n",(0,o.jsxs)(t.p,{children:["Please make sure the directory structure remains the same otherwise you'll not be able to start the tilt setup. Here's an example of structuring ",(0,o.jsx)(t.code,{children:"openstack-scs-1-27-v1"})," cluster-stack."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"$ tree .release/openstack-scs-1-27-v1/\n.release/openstack-scs-1-27-v1/\n\u251c\u2500\u2500 clusterstack.yaml\n\u251c\u2500\u2500 metadata.yaml\n\u2514\u2500\u2500 openstack-scs-1-27-cluster-class-v1.tgz\n"})}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsxs)(t.p,{children:["[!IMPORTANT]\nThere's an alternative way to get clusterstacks using ",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/csctl",children:"csctl"}),". You can follow the README of csctl for specific instructions and a good quickstart."]}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["You can use ",(0,o.jsx)(t.code,{children:"csctl create"})," subcommand to create clusterstack locally. You'll need a csctl.yaml file in the cluster-stack configuration directory. Please read more about creating configuration file for csctl in the csctl docs."]})]})}function u(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},8860:(e,t,s)=>{s.d(t,{A:()=>o});const o=s.p+"assets/images/tilt-4af6fa61d9a6a82abdfa1c82985f182e.png"},28453:(e,t,s)=>{s.d(t,{R:()=>l,x:()=>r});var o=s(96540);const n={},c=o.createContext(n);function l(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:l(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/853df457.f1079892.js b/assets/js/853df457.f1079892.js new file mode 100644 index 0000000000..7c25416b81 --- /dev/null +++ b/assets/js/853df457.f1079892.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4365],{51095:(e,o,t)=>{t.r(o),t.d(o,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var s=t(74848),n=t(28453);const i={sidebar_label:"Tools",sidebar_position:10},a="Tools",r={id:"iaas/guides/operations-guide/openstack/tools/index",title:"Tools",description:"",source:"@site/docs/02-iaas/guides/operations-guide/openstack/tools/index.md",sourceDirName:"02-iaas/guides/operations-guide/openstack/tools",slug:"/iaas/guides/operations-guide/openstack/tools/",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/index.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Tools",sidebar_position:10},sidebar:"docs",previous:{title:"OpenStack",permalink:"/docs/iaas/guides/operations-guide/openstack/"},next:{title:"Image Manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/"}},c={},d=[];function u(e){const o={h1:"h1",...(0,n.R)(),...e.components};return(0,s.jsx)(o.h1,{id:"tools",children:"Tools"})}function l(e={}){const{wrapper:o}={...(0,n.R)(),...e.components};return o?(0,s.jsx)(o,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,o,t)=>{t.d(o,{R:()=>a,x:()=>r});var s=t(96540);const n={},i=s.createContext(n);function a(e){const o=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function r(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),s.createElement(i.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8609.ef47321b.js b/assets/js/8609.ef47321b.js new file mode 100644 index 0000000000..9cd1f512fb --- /dev/null +++ b/assets/js/8609.ef47321b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8609],{58609:(t,e,a)=>{a.d(e,{diagram:()=>b});var i=a(26292),n=a(26312),d=a(21176),r=a(697),s=a(76257);a(74353),a(16750),a(42838);const o={},c=(t,e)=>{o[t]=e},g=(t,e)=>{const a=t.append("text").attr("x",2*(0,s.c)().state.padding).attr("y",(0,s.c)().state.textHeight+1.3*(0,s.c)().state.padding).attr("font-size",(0,s.c)().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),i=a.height,n=t.append("text").attr("x",(0,s.c)().state.padding).attr("y",i+.4*(0,s.c)().state.padding+(0,s.c)().state.dividerMargin+(0,s.c)().state.textHeight).attr("class","state-description");let d=!0,r=!0;e.descriptions.forEach((function(t){d||(!function(t,e,a){const i=t.append("tspan").attr("x",2*(0,s.c)().state.padding).text(e);a||i.attr("dy",(0,s.c)().state.textHeight)}(n,t,r),r=!1),d=!1}));const o=t.append("line").attr("x1",(0,s.c)().state.padding).attr("y1",(0,s.c)().state.padding+i+(0,s.c)().state.dividerMargin/2).attr("y2",(0,s.c)().state.padding+i+(0,s.c)().state.dividerMargin/2).attr("class","descr-divider"),c=n.node().getBBox(),g=Math.max(c.width,a.width);return o.attr("x2",g+3*(0,s.c)().state.padding),t.insert("rect",":first-child").attr("x",(0,s.c)().state.padding).attr("y",(0,s.c)().state.padding).attr("width",g+2*(0,s.c)().state.padding).attr("height",c.height+i+2*(0,s.c)().state.padding).attr("rx",(0,s.c)().state.radius),t},p=(t,e,a)=>{const i=(0,s.c)().state.padding,n=2*(0,s.c)().state.padding,d=t.node().getBBox(),r=d.width,o=d.x,c=t.append("text").attr("x",0).attr("y",(0,s.c)().state.titleShift).attr("font-size",(0,s.c)().state.fontSize).attr("class","state-title").text(e.id),g=c.node().getBBox().width+n;let p,h=Math.max(g,r);h===r&&(h+=n);const l=t.node().getBBox();e.doc,p=o-i,g>r&&(p=(r-h)/2+i),Math.abs(o-l.x)<i&&g>r&&(p=o-(g-r)/2);const x=1-(0,s.c)().state.textHeight;return t.insert("rect",":first-child").attr("x",p).attr("y",x).attr("class",a?"alt-composit":"composit").attr("width",h).attr("height",l.height+(0,s.c)().state.textHeight+(0,s.c)().state.titleShift+1).attr("rx","0"),c.attr("x",p+i),g<=r&&c.attr("x",o+(h-n)/2-g/2+i),t.insert("rect",":first-child").attr("x",p).attr("y",(0,s.c)().state.titleShift-(0,s.c)().state.textHeight-(0,s.c)().state.padding).attr("width",h).attr("height",3*(0,s.c)().state.textHeight).attr("rx",(0,s.c)().state.radius),t.insert("rect",":first-child").attr("x",p).attr("y",(0,s.c)().state.titleShift-(0,s.c)().state.textHeight-(0,s.c)().state.padding).attr("width",h).attr("height",l.height+3+2*(0,s.c)().state.textHeight).attr("rx",(0,s.c)().state.radius),t},h=(t,e)=>{e.attr("class","state-note");const a=e.append("rect").attr("x",0).attr("y",(0,s.c)().state.padding),i=e.append("g"),{textWidth:n,textHeight:d}=((t,e,a,i)=>{let n=0;const d=i.append("text");d.style("text-anchor","start"),d.attr("class","noteText");let r=t.replace(/\r\n/g,"<br/>");r=r.replace(/\n/g,"<br/>");const o=r.split(s.e.lineBreakRegex);let c=1.25*(0,s.c)().state.noteMargin;for(const g of o){const t=g.trim();if(t.length>0){const i=d.append("tspan");i.text(t),0===c&&(c+=i.node().getBBox().height),n+=c,i.attr("x",e+(0,s.c)().state.noteMargin),i.attr("y",a+n+1.25*(0,s.c)().state.noteMargin)}}return{textWidth:d.node().getBBox().width,textHeight:n}})(t,0,0,i);return a.attr("height",d+2*(0,s.c)().state.noteMargin),a.attr("width",n+2*(0,s.c)().state.noteMargin),a},l=function(t,e){const a=e.id,i={id:a,label:e.id,width:0,height:0},n=t.append("g").attr("id",a).attr("class","stateGroup");"start"===e.type&&(t=>{t.append("circle").attr("class","start-state").attr("r",(0,s.c)().state.sizeUnit).attr("cx",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit).attr("cy",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit)})(n),"end"===e.type&&(t=>{t.append("circle").attr("class","end-state-outer").attr("r",(0,s.c)().state.sizeUnit+(0,s.c)().state.miniPadding).attr("cx",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+(0,s.c)().state.miniPadding).attr("cy",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+(0,s.c)().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",(0,s.c)().state.sizeUnit).attr("cx",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+2).attr("cy",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+2)})(n),"fork"!==e.type&&"join"!==e.type||((t,e)=>{let a=(0,s.c)().state.forkWidth,i=(0,s.c)().state.forkHeight;if(e.parentId){let t=a;a=i,i=t}t.append("rect").style("stroke","black").style("fill","black").attr("width",a).attr("height",i).attr("x",(0,s.c)().state.padding).attr("y",(0,s.c)().state.padding)})(n,e),"note"===e.type&&h(e.note.text,n),"divider"===e.type&&(t=>{t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",(0,s.c)().state.textHeight).attr("class","divider").attr("x2",2*(0,s.c)().state.textHeight).attr("y1",0).attr("y2",0)})(n),"default"===e.type&&0===e.descriptions.length&&((t,e)=>{const a=t.append("text").attr("x",2*(0,s.c)().state.padding).attr("y",(0,s.c)().state.textHeight+2*(0,s.c)().state.padding).attr("font-size",(0,s.c)().state.fontSize).attr("class","state-title").text(e.id),i=a.node().getBBox();t.insert("rect",":first-child").attr("x",(0,s.c)().state.padding).attr("y",(0,s.c)().state.padding).attr("width",i.width+2*(0,s.c)().state.padding).attr("height",i.height+2*(0,s.c)().state.padding).attr("rx",(0,s.c)().state.radius)})(n,e),"default"===e.type&&e.descriptions.length>0&&g(n,e);const d=n.node().getBBox();return i.width=d.width+2*(0,s.c)().state.padding,i.height=d.height+2*(0,s.c)().state.padding,c(a,i),i};let x=0;let u;const f={},y=(t,e,a,o,c,g,h)=>{const w=new r.T({compound:!0,multigraph:!0});let b,B=!0;for(b=0;b<t.length;b++)if("relation"===t[b].stmt){B=!1;break}a?w.setGraph({rankdir:"LR",multigraph:!0,compound:!0,ranker:"tight-tree",ranksep:B?1:u.edgeLengthFactor,nodeSep:B?1:50,isMultiGraph:!0}):w.setGraph({rankdir:"TB",multigraph:!0,compound:!0,ranksep:B?1:u.edgeLengthFactor,nodeSep:B?1:50,ranker:"tight-tree",isMultiGraph:!0}),w.setDefaultEdgeLabel((function(){return{}})),h.db.extract(t);const m=h.db.getStates(),k=h.db.getRelations(),N=Object.keys(m);for(const i of N){const t=m[i];let n;if(a&&(t.parentId=a),t.doc){let a=e.append("g").attr("id",t.id).attr("class","stateGroup");n=y(t.doc,a,t.id,!o,c,g,h);{a=p(a,t,o);let e=a.node().getBBox();n.width=e.width,n.height=e.height+u.padding/2,f[t.id]={y:u.compositTitleSize}}}else n=l(e,t);if(t.note){const a={descriptions:[],id:t.id+"-note",note:t.note,type:"note"},i=l(e,a);"left of"===t.note.position?(w.setNode(n.id+"-note",i),w.setNode(n.id,n)):(w.setNode(n.id,n),w.setNode(n.id+"-note",i)),w.setParent(n.id,n.id+"-group"),w.setParent(n.id+"-note",n.id+"-group")}else w.setNode(n.id,n)}s.l.debug("Count=",w.nodeCount(),w);let E=0;k.forEach((function(t){var e;E++,s.l.debug("Setting edge",t),w.setEdge(t.id1,t.id2,{relation:t,width:(e=t.title,e?e.length*u.fontSizeFactor:1),height:u.labelHeight*s.e.getRows(t.title).length,labelpos:"c"},"id"+E)})),(0,d.Zp)(w),s.l.debug("Graph after layout",w.nodes());const v=e.node();w.nodes().forEach((function(t){if(void 0!==t&&void 0!==w.node(t)){s.l.warn("Node "+t+": "+JSON.stringify(w.node(t))),c.select("#"+v.id+" #"+t).attr("transform","translate("+(w.node(t).x-w.node(t).width/2)+","+(w.node(t).y+(f[t]?f[t].y:0)-w.node(t).height/2)+" )"),c.select("#"+v.id+" #"+t).attr("data-x-shift",w.node(t).x-w.node(t).width/2);g.querySelectorAll("#"+v.id+" #"+t+" .divider").forEach((t=>{const e=t.parentElement;let a=0,i=0;e&&(e.parentElement&&(a=e.parentElement.getBBox().width),i=parseInt(e.getAttribute("data-x-shift"),10),Number.isNaN(i)&&(i=0)),t.setAttribute("x1",0-i+8),t.setAttribute("x2",a-i-8)}))}else s.l.debug("No Node "+t+": "+JSON.stringify(w.node(t)))}));let M=v.getBBox();w.edges().forEach((function(t){void 0!==t&&void 0!==w.edge(t)&&(s.l.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(w.edge(t))),function(t,e,a){e.points=e.points.filter((t=>!Number.isNaN(t.y)));const d=e.points,r=(0,n.n8j)().x((function(t){return t.x})).y((function(t){return t.y})).curve(n.qrM),o=t.append("path").attr("d",r(d)).attr("id","edge"+x).attr("class","transition");let c="";if((0,s.c)().state.arrowMarkerAbsolute&&(c=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,c=c.replace(/\(/g,"\\("),c=c.replace(/\)/g,"\\)")),o.attr("marker-end","url("+c+"#"+function(t){switch(t){case i.d.relationType.AGGREGATION:return"aggregation";case i.d.relationType.EXTENSION:return"extension";case i.d.relationType.COMPOSITION:return"composition";case i.d.relationType.DEPENDENCY:return"dependency"}}(i.d.relationType.DEPENDENCY)+"End)"),void 0!==a.title){const i=t.append("g").attr("class","stateLabel"),{x:n,y:d}=s.u.calcLabelPosition(e.points),r=s.e.getRows(a.title);let o=0;const c=[];let g=0,p=0;for(let t=0;t<=r.length;t++){const e=i.append("text").attr("text-anchor","middle").text(r[t]).attr("x",n).attr("y",d+o),a=e.node().getBBox();if(g=Math.max(g,a.width),p=Math.min(p,a.x),s.l.info(a.x,n,d+o),0===o){const t=e.node().getBBox();o=t.height,s.l.info("Title height",o,d)}c.push(e)}let h=o*r.length;if(r.length>1){const t=(r.length-1)*o*.5;c.forEach(((e,a)=>e.attr("y",d+a*o-t))),h=o*r.length}const l=i.node().getBBox();i.insert("rect",":first-child").attr("class","box").attr("x",n-g/2-(0,s.c)().state.padding/2).attr("y",d-h/2-(0,s.c)().state.padding/2-3.5).attr("width",g+(0,s.c)().state.padding).attr("height",h+(0,s.c)().state.padding),s.l.info(l)}x++}(e,w.edge(t),w.edge(t).relation))})),M=v.getBBox();const S={id:a||"root",label:a||"root",width:0,height:0};return S.width=M.width+2*u.padding,S.height=M.height+2*u.padding,s.l.debug("Doc rendered",S,w),S},w={setConf:function(){},draw:function(t,e,a,i){u=(0,s.c)().state;const d=(0,s.c)().securityLevel;let r;"sandbox"===d&&(r=(0,n.Ltv)("#i"+e));const o="sandbox"===d?(0,n.Ltv)(r.nodes()[0].contentDocument.body):(0,n.Ltv)("body"),c="sandbox"===d?r.nodes()[0].contentDocument:document;s.l.debug("Rendering diagram "+t);const g=o.select(`[id='${e}']`);g.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z");const p=i.db.getRootDoc();y(p,g,void 0,!1,o,c,i);const h=u.padding,l=g.node().getBBox(),x=l.width+2*h,f=l.height+2*h,w=1.75*x;(0,s.i)(g,f,w,u.useMaxWidth),g.attr("viewBox",`${l.x-u.padding} ${l.y-u.padding} `+x+" "+f)}},b={parser:i.p,db:i.d,renderer:w,styles:i.s,init:t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute,i.d.clear()}}}}]); \ No newline at end of file diff --git a/assets/js/863.6f72a130.js b/assets/js/863.6f72a130.js new file mode 100644 index 0000000000..609d1b4618 --- /dev/null +++ b/assets/js/863.6f72a130.js @@ -0,0 +1,2605 @@ +"use strict"; +exports.id = 863; +exports.ids = [863]; +exports.modules = { + +/***/ 83863: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(76257); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var _svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(58886); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16750); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(74353); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99418); + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 24], $V1 = [1, 25], $V2 = [1, 26], $V3 = [1, 27], $V4 = [1, 28], $V5 = [1, 63], $V6 = [1, 64], $V7 = [1, 65], $V8 = [1, 66], $V9 = [1, 67], $Va = [1, 68], $Vb = [1, 69], $Vc = [1, 29], $Vd = [1, 30], $Ve = [1, 31], $Vf = [1, 32], $Vg = [1, 33], $Vh = [1, 34], $Vi = [1, 35], $Vj = [1, 36], $Vk = [1, 37], $Vl = [1, 38], $Vm = [1, 39], $Vn = [1, 40], $Vo = [1, 41], $Vp = [1, 42], $Vq = [1, 43], $Vr = [1, 44], $Vs = [1, 45], $Vt = [1, 46], $Vu = [1, 47], $Vv = [1, 48], $Vw = [1, 50], $Vx = [1, 51], $Vy = [1, 52], $Vz = [1, 53], $VA = [1, 54], $VB = [1, 55], $VC = [1, 56], $VD = [1, 57], $VE = [1, 58], $VF = [1, 59], $VG = [1, 60], $VH = [14, 42], $VI = [14, 34, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74], $VJ = [12, 14, 34, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74], $VK = [1, 82], $VL = [1, 83], $VM = [1, 84], $VN = [1, 85], $VO = [12, 14, 42], $VP = [12, 14, 33, 42], $VQ = [12, 14, 33, 42, 76, 77, 79, 80], $VR = [12, 33], $VS = [34, 36, 37, 38, 39, 40, 41, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "mermaidDoc": 4, "direction": 5, "direction_tb": 6, "direction_bt": 7, "direction_rl": 8, "direction_lr": 9, "graphConfig": 10, "C4_CONTEXT": 11, "NEWLINE": 12, "statements": 13, "EOF": 14, "C4_CONTAINER": 15, "C4_COMPONENT": 16, "C4_DYNAMIC": 17, "C4_DEPLOYMENT": 18, "otherStatements": 19, "diagramStatements": 20, "otherStatement": 21, "title": 22, "accDescription": 23, "acc_title": 24, "acc_title_value": 25, "acc_descr": 26, "acc_descr_value": 27, "acc_descr_multiline_value": 28, "boundaryStatement": 29, "boundaryStartStatement": 30, "boundaryStopStatement": 31, "boundaryStart": 32, "LBRACE": 33, "ENTERPRISE_BOUNDARY": 34, "attributes": 35, "SYSTEM_BOUNDARY": 36, "BOUNDARY": 37, "CONTAINER_BOUNDARY": 38, "NODE": 39, "NODE_L": 40, "NODE_R": 41, "RBRACE": 42, "diagramStatement": 43, "PERSON": 44, "PERSON_EXT": 45, "SYSTEM": 46, "SYSTEM_DB": 47, "SYSTEM_QUEUE": 48, "SYSTEM_EXT": 49, "SYSTEM_EXT_DB": 50, "SYSTEM_EXT_QUEUE": 51, "CONTAINER": 52, "CONTAINER_DB": 53, "CONTAINER_QUEUE": 54, "CONTAINER_EXT": 55, "CONTAINER_EXT_DB": 56, "CONTAINER_EXT_QUEUE": 57, "COMPONENT": 58, "COMPONENT_DB": 59, "COMPONENT_QUEUE": 60, "COMPONENT_EXT": 61, "COMPONENT_EXT_DB": 62, "COMPONENT_EXT_QUEUE": 63, "REL": 64, "BIREL": 65, "REL_U": 66, "REL_D": 67, "REL_L": 68, "REL_R": 69, "REL_B": 70, "REL_INDEX": 71, "UPDATE_EL_STYLE": 72, "UPDATE_REL_STYLE": 73, "UPDATE_LAYOUT_CONFIG": 74, "attribute": 75, "STR": 76, "STR_KEY": 77, "STR_VALUE": 78, "ATTRIBUTE": 79, "ATTRIBUTE_EMPTY": 80, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 6: "direction_tb", 7: "direction_bt", 8: "direction_rl", 9: "direction_lr", 11: "C4_CONTEXT", 12: "NEWLINE", 14: "EOF", 15: "C4_CONTAINER", 16: "C4_COMPONENT", 17: "C4_DYNAMIC", 18: "C4_DEPLOYMENT", 22: "title", 23: "accDescription", 24: "acc_title", 25: "acc_title_value", 26: "acc_descr", 27: "acc_descr_value", 28: "acc_descr_multiline_value", 33: "LBRACE", 34: "ENTERPRISE_BOUNDARY", 36: "SYSTEM_BOUNDARY", 37: "BOUNDARY", 38: "CONTAINER_BOUNDARY", 39: "NODE", 40: "NODE_L", 41: "NODE_R", 42: "RBRACE", 44: "PERSON", 45: "PERSON_EXT", 46: "SYSTEM", 47: "SYSTEM_DB", 48: "SYSTEM_QUEUE", 49: "SYSTEM_EXT", 50: "SYSTEM_EXT_DB", 51: "SYSTEM_EXT_QUEUE", 52: "CONTAINER", 53: "CONTAINER_DB", 54: "CONTAINER_QUEUE", 55: "CONTAINER_EXT", 56: "CONTAINER_EXT_DB", 57: "CONTAINER_EXT_QUEUE", 58: "COMPONENT", 59: "COMPONENT_DB", 60: "COMPONENT_QUEUE", 61: "COMPONENT_EXT", 62: "COMPONENT_EXT_DB", 63: "COMPONENT_EXT_QUEUE", 64: "REL", 65: "BIREL", 66: "REL_U", 67: "REL_D", 68: "REL_L", 69: "REL_R", 70: "REL_B", 71: "REL_INDEX", 72: "UPDATE_EL_STYLE", 73: "UPDATE_REL_STYLE", 74: "UPDATE_LAYOUT_CONFIG", 76: "STR", 77: "STR_KEY", 78: "STR_VALUE", 79: "ATTRIBUTE", 80: "ATTRIBUTE_EMPTY" }, + productions_: [0, [3, 1], [3, 1], [5, 1], [5, 1], [5, 1], [5, 1], [4, 1], [10, 4], [10, 4], [10, 4], [10, 4], [10, 4], [13, 1], [13, 1], [13, 2], [19, 1], [19, 2], [19, 3], [21, 1], [21, 1], [21, 2], [21, 2], [21, 1], [29, 3], [30, 3], [30, 3], [30, 4], [32, 2], [32, 2], [32, 2], [32, 2], [32, 2], [32, 2], [32, 2], [31, 1], [20, 1], [20, 2], [20, 3], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 1], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [35, 1], [35, 2], [75, 1], [75, 2], [75, 1], [75, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 3: + yy.setDirection("TB"); + break; + case 4: + yy.setDirection("BT"); + break; + case 5: + yy.setDirection("RL"); + break; + case 6: + yy.setDirection("LR"); + break; + case 8: + case 9: + case 10: + case 11: + case 12: + yy.setC4Type($$[$0 - 3]); + break; + case 19: + yy.setTitle($$[$0].substring(6)); + this.$ = $$[$0].substring(6); + break; + case 20: + yy.setAccDescription($$[$0].substring(15)); + this.$ = $$[$0].substring(15); + break; + case 21: + this.$ = $$[$0].trim(); + yy.setTitle(this.$); + break; + case 22: + case 23: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 28: + case 29: + $$[$0].splice(2, 0, "ENTERPRISE"); + yy.addPersonOrSystemBoundary(...$$[$0]); + this.$ = $$[$0]; + break; + case 30: + yy.addPersonOrSystemBoundary(...$$[$0]); + this.$ = $$[$0]; + break; + case 31: + $$[$0].splice(2, 0, "CONTAINER"); + yy.addContainerBoundary(...$$[$0]); + this.$ = $$[$0]; + break; + case 32: + yy.addDeploymentNode("node", ...$$[$0]); + this.$ = $$[$0]; + break; + case 33: + yy.addDeploymentNode("nodeL", ...$$[$0]); + this.$ = $$[$0]; + break; + case 34: + yy.addDeploymentNode("nodeR", ...$$[$0]); + this.$ = $$[$0]; + break; + case 35: + yy.popBoundaryParseStack(); + break; + case 39: + yy.addPersonOrSystem("person", ...$$[$0]); + this.$ = $$[$0]; + break; + case 40: + yy.addPersonOrSystem("external_person", ...$$[$0]); + this.$ = $$[$0]; + break; + case 41: + yy.addPersonOrSystem("system", ...$$[$0]); + this.$ = $$[$0]; + break; + case 42: + yy.addPersonOrSystem("system_db", ...$$[$0]); + this.$ = $$[$0]; + break; + case 43: + yy.addPersonOrSystem("system_queue", ...$$[$0]); + this.$ = $$[$0]; + break; + case 44: + yy.addPersonOrSystem("external_system", ...$$[$0]); + this.$ = $$[$0]; + break; + case 45: + yy.addPersonOrSystem("external_system_db", ...$$[$0]); + this.$ = $$[$0]; + break; + case 46: + yy.addPersonOrSystem("external_system_queue", ...$$[$0]); + this.$ = $$[$0]; + break; + case 47: + yy.addContainer("container", ...$$[$0]); + this.$ = $$[$0]; + break; + case 48: + yy.addContainer("container_db", ...$$[$0]); + this.$ = $$[$0]; + break; + case 49: + yy.addContainer("container_queue", ...$$[$0]); + this.$ = $$[$0]; + break; + case 50: + yy.addContainer("external_container", ...$$[$0]); + this.$ = $$[$0]; + break; + case 51: + yy.addContainer("external_container_db", ...$$[$0]); + this.$ = $$[$0]; + break; + case 52: + yy.addContainer("external_container_queue", ...$$[$0]); + this.$ = $$[$0]; + break; + case 53: + yy.addComponent("component", ...$$[$0]); + this.$ = $$[$0]; + break; + case 54: + yy.addComponent("component_db", ...$$[$0]); + this.$ = $$[$0]; + break; + case 55: + yy.addComponent("component_queue", ...$$[$0]); + this.$ = $$[$0]; + break; + case 56: + yy.addComponent("external_component", ...$$[$0]); + this.$ = $$[$0]; + break; + case 57: + yy.addComponent("external_component_db", ...$$[$0]); + this.$ = $$[$0]; + break; + case 58: + yy.addComponent("external_component_queue", ...$$[$0]); + this.$ = $$[$0]; + break; + case 60: + yy.addRel("rel", ...$$[$0]); + this.$ = $$[$0]; + break; + case 61: + yy.addRel("birel", ...$$[$0]); + this.$ = $$[$0]; + break; + case 62: + yy.addRel("rel_u", ...$$[$0]); + this.$ = $$[$0]; + break; + case 63: + yy.addRel("rel_d", ...$$[$0]); + this.$ = $$[$0]; + break; + case 64: + yy.addRel("rel_l", ...$$[$0]); + this.$ = $$[$0]; + break; + case 65: + yy.addRel("rel_r", ...$$[$0]); + this.$ = $$[$0]; + break; + case 66: + yy.addRel("rel_b", ...$$[$0]); + this.$ = $$[$0]; + break; + case 67: + $$[$0].splice(0, 1); + yy.addRel("rel", ...$$[$0]); + this.$ = $$[$0]; + break; + case 68: + yy.updateElStyle("update_el_style", ...$$[$0]); + this.$ = $$[$0]; + break; + case 69: + yy.updateRelStyle("update_rel_style", ...$$[$0]); + this.$ = $$[$0]; + break; + case 70: + yy.updateLayoutConfig("update_layout_config", ...$$[$0]); + this.$ = $$[$0]; + break; + case 71: + this.$ = [$$[$0]]; + break; + case 72: + $$[$0].unshift($$[$0 - 1]); + this.$ = $$[$0]; + break; + case 73: + case 75: + this.$ = $$[$0].trim(); + break; + case 74: + let kv = {}; + kv[$$[$0 - 1].trim()] = $$[$0].trim(); + this.$ = kv; + break; + case 76: + this.$ = ""; + break; + } + }, + table: [{ 3: 1, 4: 2, 5: 3, 6: [1, 5], 7: [1, 6], 8: [1, 7], 9: [1, 8], 10: 4, 11: [1, 9], 15: [1, 10], 16: [1, 11], 17: [1, 12], 18: [1, 13] }, { 1: [3] }, { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 7] }, { 1: [2, 3] }, { 1: [2, 4] }, { 1: [2, 5] }, { 1: [2, 6] }, { 12: [1, 14] }, { 12: [1, 15] }, { 12: [1, 16] }, { 12: [1, 17] }, { 12: [1, 18] }, { 13: 19, 19: 20, 20: 21, 21: 22, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4, 29: 49, 30: 61, 32: 62, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 43: 23, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }, { 13: 70, 19: 20, 20: 21, 21: 22, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4, 29: 49, 30: 61, 32: 62, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 43: 23, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }, { 13: 71, 19: 20, 20: 21, 21: 22, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4, 29: 49, 30: 61, 32: 62, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 43: 23, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }, { 13: 72, 19: 20, 20: 21, 21: 22, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4, 29: 49, 30: 61, 32: 62, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 43: 23, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }, { 13: 73, 19: 20, 20: 21, 21: 22, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4, 29: 49, 30: 61, 32: 62, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 43: 23, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }, { 14: [1, 74] }, o($VH, [2, 13], { 43: 23, 29: 49, 30: 61, 32: 62, 20: 75, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }), o($VH, [2, 14]), o($VI, [2, 16], { 12: [1, 76] }), o($VH, [2, 36], { 12: [1, 77] }), o($VJ, [2, 19]), o($VJ, [2, 20]), { 25: [1, 78] }, { 27: [1, 79] }, o($VJ, [2, 23]), { 35: 80, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 86, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 87, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 88, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 89, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 90, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 91, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 92, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 93, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 94, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 95, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 96, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 97, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 98, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 99, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 100, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 101, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 102, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 103, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 104, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, o($VO, [2, 59]), { 35: 105, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 106, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 107, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 108, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 109, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 110, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 111, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 112, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 113, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 114, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 115, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 20: 116, 29: 49, 30: 61, 32: 62, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 43: 23, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }, { 12: [1, 118], 33: [1, 117] }, { 35: 119, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 120, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 121, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 122, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 123, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 124, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 125, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 14: [1, 126] }, { 14: [1, 127] }, { 14: [1, 128] }, { 14: [1, 129] }, { 1: [2, 8] }, o($VH, [2, 15]), o($VI, [2, 17], { 21: 22, 19: 130, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4 }), o($VH, [2, 37], { 19: 20, 20: 21, 21: 22, 43: 23, 29: 49, 30: 61, 32: 62, 13: 131, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }), o($VJ, [2, 21]), o($VJ, [2, 22]), o($VO, [2, 39]), o($VP, [2, 71], { 75: 81, 35: 132, 76: $VK, 77: $VL, 79: $VM, 80: $VN }), o($VQ, [2, 73]), { 78: [1, 133] }, o($VQ, [2, 75]), o($VQ, [2, 76]), o($VO, [2, 40]), o($VO, [2, 41]), o($VO, [2, 42]), o($VO, [2, 43]), o($VO, [2, 44]), o($VO, [2, 45]), o($VO, [2, 46]), o($VO, [2, 47]), o($VO, [2, 48]), o($VO, [2, 49]), o($VO, [2, 50]), o($VO, [2, 51]), o($VO, [2, 52]), o($VO, [2, 53]), o($VO, [2, 54]), o($VO, [2, 55]), o($VO, [2, 56]), o($VO, [2, 57]), o($VO, [2, 58]), o($VO, [2, 60]), o($VO, [2, 61]), o($VO, [2, 62]), o($VO, [2, 63]), o($VO, [2, 64]), o($VO, [2, 65]), o($VO, [2, 66]), o($VO, [2, 67]), o($VO, [2, 68]), o($VO, [2, 69]), o($VO, [2, 70]), { 31: 134, 42: [1, 135] }, { 12: [1, 136] }, { 33: [1, 137] }, o($VR, [2, 28]), o($VR, [2, 29]), o($VR, [2, 30]), o($VR, [2, 31]), o($VR, [2, 32]), o($VR, [2, 33]), o($VR, [2, 34]), { 1: [2, 9] }, { 1: [2, 10] }, { 1: [2, 11] }, { 1: [2, 12] }, o($VI, [2, 18]), o($VH, [2, 38]), o($VP, [2, 72]), o($VQ, [2, 74]), o($VO, [2, 24]), o($VO, [2, 35]), o($VS, [2, 25]), o($VS, [2, 26], { 12: [1, 138] }), o($VS, [2, 27])], + defaultActions: { 2: [2, 1], 3: [2, 2], 4: [2, 7], 5: [2, 3], 6: [2, 4], 7: [2, 5], 8: [2, 6], 74: [2, 8], 126: [2, 9], 127: [2, 10], 128: [2, 11], 129: [2, 12] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c2 = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c2 + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 6; + case 1: + return 7; + case 2: + return 8; + case 3: + return 9; + case 4: + return 22; + case 5: + return 23; + case 6: + this.begin("acc_title"); + return 24; + case 7: + this.popState(); + return "acc_title_value"; + case 8: + this.begin("acc_descr"); + return 26; + case 9: + this.popState(); + return "acc_descr_value"; + case 10: + this.begin("acc_descr_multiline"); + break; + case 11: + this.popState(); + break; + case 12: + return "acc_descr_multiline_value"; + case 13: + break; + case 14: + c; + break; + case 15: + return 12; + case 16: + break; + case 17: + return 11; + case 18: + return 15; + case 19: + return 16; + case 20: + return 17; + case 21: + return 18; + case 22: + this.begin("person_ext"); + return 45; + case 23: + this.begin("person"); + return 44; + case 24: + this.begin("system_ext_queue"); + return 51; + case 25: + this.begin("system_ext_db"); + return 50; + case 26: + this.begin("system_ext"); + return 49; + case 27: + this.begin("system_queue"); + return 48; + case 28: + this.begin("system_db"); + return 47; + case 29: + this.begin("system"); + return 46; + case 30: + this.begin("boundary"); + return 37; + case 31: + this.begin("enterprise_boundary"); + return 34; + case 32: + this.begin("system_boundary"); + return 36; + case 33: + this.begin("container_ext_queue"); + return 57; + case 34: + this.begin("container_ext_db"); + return 56; + case 35: + this.begin("container_ext"); + return 55; + case 36: + this.begin("container_queue"); + return 54; + case 37: + this.begin("container_db"); + return 53; + case 38: + this.begin("container"); + return 52; + case 39: + this.begin("container_boundary"); + return 38; + case 40: + this.begin("component_ext_queue"); + return 63; + case 41: + this.begin("component_ext_db"); + return 62; + case 42: + this.begin("component_ext"); + return 61; + case 43: + this.begin("component_queue"); + return 60; + case 44: + this.begin("component_db"); + return 59; + case 45: + this.begin("component"); + return 58; + case 46: + this.begin("node"); + return 39; + case 47: + this.begin("node"); + return 39; + case 48: + this.begin("node_l"); + return 40; + case 49: + this.begin("node_r"); + return 41; + case 50: + this.begin("rel"); + return 64; + case 51: + this.begin("birel"); + return 65; + case 52: + this.begin("rel_u"); + return 66; + case 53: + this.begin("rel_u"); + return 66; + case 54: + this.begin("rel_d"); + return 67; + case 55: + this.begin("rel_d"); + return 67; + case 56: + this.begin("rel_l"); + return 68; + case 57: + this.begin("rel_l"); + return 68; + case 58: + this.begin("rel_r"); + return 69; + case 59: + this.begin("rel_r"); + return 69; + case 60: + this.begin("rel_b"); + return 70; + case 61: + this.begin("rel_index"); + return 71; + case 62: + this.begin("update_el_style"); + return 72; + case 63: + this.begin("update_rel_style"); + return 73; + case 64: + this.begin("update_layout_config"); + return 74; + case 65: + return "EOF_IN_STRUCT"; + case 66: + this.begin("attribute"); + return "ATTRIBUTE_EMPTY"; + case 67: + this.begin("attribute"); + break; + case 68: + this.popState(); + this.popState(); + break; + case 69: + return 80; + case 70: + break; + case 71: + return 80; + case 72: + this.begin("string"); + break; + case 73: + this.popState(); + break; + case 74: + return "STR"; + case 75: + this.begin("string_kv"); + break; + case 76: + this.begin("string_kv_key"); + return "STR_KEY"; + case 77: + this.popState(); + this.begin("string_kv_value"); + break; + case 78: + return "STR_VALUE"; + case 79: + this.popState(); + this.popState(); + break; + case 80: + return "STR"; + case 81: + return "LBRACE"; + case 82: + return "RBRACE"; + case 83: + return "SPACE"; + case 84: + return "EOL"; + case 85: + return 14; + } + }, + rules: [/^(?:.*direction\s+TB[^\n]*)/, /^(?:.*direction\s+BT[^\n]*)/, /^(?:.*direction\s+RL[^\n]*)/, /^(?:.*direction\s+LR[^\n]*)/, /^(?:title\s[^#\n;]+)/, /^(?:accDescription\s[^#\n;]+)/, /^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/, /^(?:%%[^\n]*(\r?\n)*)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:C4Context\b)/, /^(?:C4Container\b)/, /^(?:C4Component\b)/, /^(?:C4Dynamic\b)/, /^(?:C4Deployment\b)/, /^(?:Person_Ext\b)/, /^(?:Person\b)/, /^(?:SystemQueue_Ext\b)/, /^(?:SystemDb_Ext\b)/, /^(?:System_Ext\b)/, /^(?:SystemQueue\b)/, /^(?:SystemDb\b)/, /^(?:System\b)/, /^(?:Boundary\b)/, /^(?:Enterprise_Boundary\b)/, /^(?:System_Boundary\b)/, /^(?:ContainerQueue_Ext\b)/, /^(?:ContainerDb_Ext\b)/, /^(?:Container_Ext\b)/, /^(?:ContainerQueue\b)/, /^(?:ContainerDb\b)/, /^(?:Container\b)/, /^(?:Container_Boundary\b)/, /^(?:ComponentQueue_Ext\b)/, /^(?:ComponentDb_Ext\b)/, /^(?:Component_Ext\b)/, /^(?:ComponentQueue\b)/, /^(?:ComponentDb\b)/, /^(?:Component\b)/, /^(?:Deployment_Node\b)/, /^(?:Node\b)/, /^(?:Node_L\b)/, /^(?:Node_R\b)/, /^(?:Rel\b)/, /^(?:BiRel\b)/, /^(?:Rel_Up\b)/, /^(?:Rel_U\b)/, /^(?:Rel_Down\b)/, /^(?:Rel_D\b)/, /^(?:Rel_Left\b)/, /^(?:Rel_L\b)/, /^(?:Rel_Right\b)/, /^(?:Rel_R\b)/, /^(?:Rel_Back\b)/, /^(?:RelIndex\b)/, /^(?:UpdateElementStyle\b)/, /^(?:UpdateRelStyle\b)/, /^(?:UpdateLayoutConfig\b)/, /^(?:$)/, /^(?:[(][ ]*[,])/, /^(?:[(])/, /^(?:[)])/, /^(?:,,)/, /^(?:,)/, /^(?:[ ]*["]["])/, /^(?:[ ]*["])/, /^(?:["])/, /^(?:[^"]*)/, /^(?:[ ]*[\$])/, /^(?:[^=]*)/, /^(?:[=][ ]*["])/, /^(?:[^"]+)/, /^(?:["])/, /^(?:[^,]+)/, /^(?:\{)/, /^(?:\})/, /^(?:[\s]+)/, /^(?:[\n\r]+)/, /^(?:$)/], + conditions: { "acc_descr_multiline": { "rules": [11, 12], "inclusive": false }, "acc_descr": { "rules": [9], "inclusive": false }, "acc_title": { "rules": [7], "inclusive": false }, "string_kv_value": { "rules": [78, 79], "inclusive": false }, "string_kv_key": { "rules": [77], "inclusive": false }, "string_kv": { "rules": [76], "inclusive": false }, "string": { "rules": [73, 74], "inclusive": false }, "attribute": { "rules": [68, 69, 70, 71, 72, 75, 80], "inclusive": false }, "update_layout_config": { "rules": [65, 66, 67, 68], "inclusive": false }, "update_rel_style": { "rules": [65, 66, 67, 68], "inclusive": false }, "update_el_style": { "rules": [65, 66, 67, 68], "inclusive": false }, "rel_b": { "rules": [65, 66, 67, 68], "inclusive": false }, "rel_r": { "rules": [65, 66, 67, 68], "inclusive": false }, "rel_l": { "rules": [65, 66, 67, 68], "inclusive": false }, "rel_d": { "rules": [65, 66, 67, 68], "inclusive": false }, "rel_u": { "rules": [65, 66, 67, 68], "inclusive": false }, "rel_bi": { "rules": [], "inclusive": false }, "rel": { "rules": [65, 66, 67, 68], "inclusive": false }, "node_r": { "rules": [65, 66, 67, 68], "inclusive": false }, "node_l": { "rules": [65, 66, 67, 68], "inclusive": false }, "node": { "rules": [65, 66, 67, 68], "inclusive": false }, "index": { "rules": [], "inclusive": false }, "rel_index": { "rules": [65, 66, 67, 68], "inclusive": false }, "component_ext_queue": { "rules": [], "inclusive": false }, "component_ext_db": { "rules": [65, 66, 67, 68], "inclusive": false }, "component_ext": { "rules": [65, 66, 67, 68], "inclusive": false }, "component_queue": { "rules": [65, 66, 67, 68], "inclusive": false }, "component_db": { "rules": [65, 66, 67, 68], "inclusive": false }, "component": { "rules": [65, 66, 67, 68], "inclusive": false }, "container_boundary": { "rules": [65, 66, 67, 68], "inclusive": false }, "container_ext_queue": { "rules": [65, 66, 67, 68], "inclusive": false }, "container_ext_db": { "rules": [65, 66, 67, 68], "inclusive": false }, "container_ext": { "rules": [65, 66, 67, 68], "inclusive": false }, "container_queue": { "rules": [65, 66, 67, 68], "inclusive": false }, "container_db": { "rules": [65, 66, 67, 68], "inclusive": false }, "container": { "rules": [65, 66, 67, 68], "inclusive": false }, "birel": { "rules": [65, 66, 67, 68], "inclusive": false }, "system_boundary": { "rules": [65, 66, 67, 68], "inclusive": false }, "enterprise_boundary": { "rules": [65, 66, 67, 68], "inclusive": false }, "boundary": { "rules": [65, 66, 67, 68], "inclusive": false }, "system_ext_queue": { "rules": [65, 66, 67, 68], "inclusive": false }, "system_ext_db": { "rules": [65, 66, 67, 68], "inclusive": false }, "system_ext": { "rules": [65, 66, 67, 68], "inclusive": false }, "system_queue": { "rules": [65, 66, 67, 68], "inclusive": false }, "system_db": { "rules": [65, 66, 67, 68], "inclusive": false }, "system": { "rules": [65, 66, 67, 68], "inclusive": false }, "person_ext": { "rules": [65, 66, 67, 68], "inclusive": false }, "person": { "rules": [65, 66, 67, 68], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 8, 10, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 81, 82, 83, 84, 85], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let c4ShapeArray = []; +let boundaryParseStack = [""]; +let currentBoundaryParse = "global"; +let parentBoundaryParse = ""; +let boundaries = [ + { + alias: "global", + label: { text: "global" }, + type: { text: "global" }, + tags: null, + link: null, + parentBoundary: "" + } +]; +let rels = []; +let title = ""; +let wrapEnabled = false; +let c4ShapeInRow$1 = 4; +let c4BoundaryInRow$1 = 2; +var c4Type; +const getC4Type = function() { + return c4Type; +}; +const setC4Type = function(c4TypeParam) { + let sanitizedText = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.d)(c4TypeParam, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + c4Type = sanitizedText; +}; +const addRel = function(type, from, to, label, techn, descr, sprite, tags, link) { + if (type === void 0 || type === null || from === void 0 || from === null || to === void 0 || to === null || label === void 0 || label === null) { + return; + } + let rel = {}; + const old = rels.find((rel2) => rel2.from === from && rel2.to === to); + if (old) { + rel = old; + } else { + rels.push(rel); + } + rel.type = type; + rel.from = from; + rel.to = to; + rel.label = { text: label }; + if (techn === void 0 || techn === null) { + rel.techn = { text: "" }; + } else { + if (typeof techn === "object") { + let [key, value] = Object.entries(techn)[0]; + rel[key] = { text: value }; + } else { + rel.techn = { text: techn }; + } + } + if (descr === void 0 || descr === null) { + rel.descr = { text: "" }; + } else { + if (typeof descr === "object") { + let [key, value] = Object.entries(descr)[0]; + rel[key] = { text: value }; + } else { + rel.descr = { text: descr }; + } + } + if (typeof sprite === "object") { + let [key, value] = Object.entries(sprite)[0]; + rel[key] = value; + } else { + rel.sprite = sprite; + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + rel[key] = value; + } else { + rel.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + rel[key] = value; + } else { + rel.link = link; + } + rel.wrap = autoWrap(); +}; +const addPersonOrSystem = function(typeC4Shape, alias, label, descr, sprite, tags, link) { + if (alias === null || label === null) { + return; + } + let personOrSystem = {}; + const old = c4ShapeArray.find((personOrSystem2) => personOrSystem2.alias === alias); + if (old && alias === old.alias) { + personOrSystem = old; + } else { + personOrSystem.alias = alias; + c4ShapeArray.push(personOrSystem); + } + if (label === void 0 || label === null) { + personOrSystem.label = { text: "" }; + } else { + personOrSystem.label = { text: label }; + } + if (descr === void 0 || descr === null) { + personOrSystem.descr = { text: "" }; + } else { + if (typeof descr === "object") { + let [key, value] = Object.entries(descr)[0]; + personOrSystem[key] = { text: value }; + } else { + personOrSystem.descr = { text: descr }; + } + } + if (typeof sprite === "object") { + let [key, value] = Object.entries(sprite)[0]; + personOrSystem[key] = value; + } else { + personOrSystem.sprite = sprite; + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + personOrSystem[key] = value; + } else { + personOrSystem.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + personOrSystem[key] = value; + } else { + personOrSystem.link = link; + } + personOrSystem.typeC4Shape = { text: typeC4Shape }; + personOrSystem.parentBoundary = currentBoundaryParse; + personOrSystem.wrap = autoWrap(); +}; +const addContainer = function(typeC4Shape, alias, label, techn, descr, sprite, tags, link) { + if (alias === null || label === null) { + return; + } + let container = {}; + const old = c4ShapeArray.find((container2) => container2.alias === alias); + if (old && alias === old.alias) { + container = old; + } else { + container.alias = alias; + c4ShapeArray.push(container); + } + if (label === void 0 || label === null) { + container.label = { text: "" }; + } else { + container.label = { text: label }; + } + if (techn === void 0 || techn === null) { + container.techn = { text: "" }; + } else { + if (typeof techn === "object") { + let [key, value] = Object.entries(techn)[0]; + container[key] = { text: value }; + } else { + container.techn = { text: techn }; + } + } + if (descr === void 0 || descr === null) { + container.descr = { text: "" }; + } else { + if (typeof descr === "object") { + let [key, value] = Object.entries(descr)[0]; + container[key] = { text: value }; + } else { + container.descr = { text: descr }; + } + } + if (typeof sprite === "object") { + let [key, value] = Object.entries(sprite)[0]; + container[key] = value; + } else { + container.sprite = sprite; + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + container[key] = value; + } else { + container.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + container[key] = value; + } else { + container.link = link; + } + container.wrap = autoWrap(); + container.typeC4Shape = { text: typeC4Shape }; + container.parentBoundary = currentBoundaryParse; +}; +const addComponent = function(typeC4Shape, alias, label, techn, descr, sprite, tags, link) { + if (alias === null || label === null) { + return; + } + let component = {}; + const old = c4ShapeArray.find((component2) => component2.alias === alias); + if (old && alias === old.alias) { + component = old; + } else { + component.alias = alias; + c4ShapeArray.push(component); + } + if (label === void 0 || label === null) { + component.label = { text: "" }; + } else { + component.label = { text: label }; + } + if (techn === void 0 || techn === null) { + component.techn = { text: "" }; + } else { + if (typeof techn === "object") { + let [key, value] = Object.entries(techn)[0]; + component[key] = { text: value }; + } else { + component.techn = { text: techn }; + } + } + if (descr === void 0 || descr === null) { + component.descr = { text: "" }; + } else { + if (typeof descr === "object") { + let [key, value] = Object.entries(descr)[0]; + component[key] = { text: value }; + } else { + component.descr = { text: descr }; + } + } + if (typeof sprite === "object") { + let [key, value] = Object.entries(sprite)[0]; + component[key] = value; + } else { + component.sprite = sprite; + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + component[key] = value; + } else { + component.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + component[key] = value; + } else { + component.link = link; + } + component.wrap = autoWrap(); + component.typeC4Shape = { text: typeC4Shape }; + component.parentBoundary = currentBoundaryParse; +}; +const addPersonOrSystemBoundary = function(alias, label, type, tags, link) { + if (alias === null || label === null) { + return; + } + let boundary = {}; + const old = boundaries.find((boundary2) => boundary2.alias === alias); + if (old && alias === old.alias) { + boundary = old; + } else { + boundary.alias = alias; + boundaries.push(boundary); + } + if (label === void 0 || label === null) { + boundary.label = { text: "" }; + } else { + boundary.label = { text: label }; + } + if (type === void 0 || type === null) { + boundary.type = { text: "system" }; + } else { + if (typeof type === "object") { + let [key, value] = Object.entries(type)[0]; + boundary[key] = { text: value }; + } else { + boundary.type = { text: type }; + } + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + boundary[key] = value; + } else { + boundary.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + boundary[key] = value; + } else { + boundary.link = link; + } + boundary.parentBoundary = currentBoundaryParse; + boundary.wrap = autoWrap(); + parentBoundaryParse = currentBoundaryParse; + currentBoundaryParse = alias; + boundaryParseStack.push(parentBoundaryParse); +}; +const addContainerBoundary = function(alias, label, type, tags, link) { + if (alias === null || label === null) { + return; + } + let boundary = {}; + const old = boundaries.find((boundary2) => boundary2.alias === alias); + if (old && alias === old.alias) { + boundary = old; + } else { + boundary.alias = alias; + boundaries.push(boundary); + } + if (label === void 0 || label === null) { + boundary.label = { text: "" }; + } else { + boundary.label = { text: label }; + } + if (type === void 0 || type === null) { + boundary.type = { text: "container" }; + } else { + if (typeof type === "object") { + let [key, value] = Object.entries(type)[0]; + boundary[key] = { text: value }; + } else { + boundary.type = { text: type }; + } + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + boundary[key] = value; + } else { + boundary.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + boundary[key] = value; + } else { + boundary.link = link; + } + boundary.parentBoundary = currentBoundaryParse; + boundary.wrap = autoWrap(); + parentBoundaryParse = currentBoundaryParse; + currentBoundaryParse = alias; + boundaryParseStack.push(parentBoundaryParse); +}; +const addDeploymentNode = function(nodeType, alias, label, type, descr, sprite, tags, link) { + if (alias === null || label === null) { + return; + } + let boundary = {}; + const old = boundaries.find((boundary2) => boundary2.alias === alias); + if (old && alias === old.alias) { + boundary = old; + } else { + boundary.alias = alias; + boundaries.push(boundary); + } + if (label === void 0 || label === null) { + boundary.label = { text: "" }; + } else { + boundary.label = { text: label }; + } + if (type === void 0 || type === null) { + boundary.type = { text: "node" }; + } else { + if (typeof type === "object") { + let [key, value] = Object.entries(type)[0]; + boundary[key] = { text: value }; + } else { + boundary.type = { text: type }; + } + } + if (descr === void 0 || descr === null) { + boundary.descr = { text: "" }; + } else { + if (typeof descr === "object") { + let [key, value] = Object.entries(descr)[0]; + boundary[key] = { text: value }; + } else { + boundary.descr = { text: descr }; + } + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + boundary[key] = value; + } else { + boundary.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + boundary[key] = value; + } else { + boundary.link = link; + } + boundary.nodeType = nodeType; + boundary.parentBoundary = currentBoundaryParse; + boundary.wrap = autoWrap(); + parentBoundaryParse = currentBoundaryParse; + currentBoundaryParse = alias; + boundaryParseStack.push(parentBoundaryParse); +}; +const popBoundaryParseStack = function() { + currentBoundaryParse = parentBoundaryParse; + boundaryParseStack.pop(); + parentBoundaryParse = boundaryParseStack.pop(); + boundaryParseStack.push(parentBoundaryParse); +}; +const updateElStyle = function(typeC4Shape, elementName, bgColor, fontColor, borderColor, shadowing, shape, sprite, techn, legendText, legendSprite) { + let old = c4ShapeArray.find((element) => element.alias === elementName); + if (old === void 0) { + old = boundaries.find((element) => element.alias === elementName); + if (old === void 0) { + return; + } + } + if (bgColor !== void 0 && bgColor !== null) { + if (typeof bgColor === "object") { + let [key, value] = Object.entries(bgColor)[0]; + old[key] = value; + } else { + old.bgColor = bgColor; + } + } + if (fontColor !== void 0 && fontColor !== null) { + if (typeof fontColor === "object") { + let [key, value] = Object.entries(fontColor)[0]; + old[key] = value; + } else { + old.fontColor = fontColor; + } + } + if (borderColor !== void 0 && borderColor !== null) { + if (typeof borderColor === "object") { + let [key, value] = Object.entries(borderColor)[0]; + old[key] = value; + } else { + old.borderColor = borderColor; + } + } + if (shadowing !== void 0 && shadowing !== null) { + if (typeof shadowing === "object") { + let [key, value] = Object.entries(shadowing)[0]; + old[key] = value; + } else { + old.shadowing = shadowing; + } + } + if (shape !== void 0 && shape !== null) { + if (typeof shape === "object") { + let [key, value] = Object.entries(shape)[0]; + old[key] = value; + } else { + old.shape = shape; + } + } + if (sprite !== void 0 && sprite !== null) { + if (typeof sprite === "object") { + let [key, value] = Object.entries(sprite)[0]; + old[key] = value; + } else { + old.sprite = sprite; + } + } + if (techn !== void 0 && techn !== null) { + if (typeof techn === "object") { + let [key, value] = Object.entries(techn)[0]; + old[key] = value; + } else { + old.techn = techn; + } + } + if (legendText !== void 0 && legendText !== null) { + if (typeof legendText === "object") { + let [key, value] = Object.entries(legendText)[0]; + old[key] = value; + } else { + old.legendText = legendText; + } + } + if (legendSprite !== void 0 && legendSprite !== null) { + if (typeof legendSprite === "object") { + let [key, value] = Object.entries(legendSprite)[0]; + old[key] = value; + } else { + old.legendSprite = legendSprite; + } + } +}; +const updateRelStyle = function(typeC4Shape, from, to, textColor, lineColor, offsetX, offsetY) { + const old = rels.find((rel) => rel.from === from && rel.to === to); + if (old === void 0) { + return; + } + if (textColor !== void 0 && textColor !== null) { + if (typeof textColor === "object") { + let [key, value] = Object.entries(textColor)[0]; + old[key] = value; + } else { + old.textColor = textColor; + } + } + if (lineColor !== void 0 && lineColor !== null) { + if (typeof lineColor === "object") { + let [key, value] = Object.entries(lineColor)[0]; + old[key] = value; + } else { + old.lineColor = lineColor; + } + } + if (offsetX !== void 0 && offsetX !== null) { + if (typeof offsetX === "object") { + let [key, value] = Object.entries(offsetX)[0]; + old[key] = parseInt(value); + } else { + old.offsetX = parseInt(offsetX); + } + } + if (offsetY !== void 0 && offsetY !== null) { + if (typeof offsetY === "object") { + let [key, value] = Object.entries(offsetY)[0]; + old[key] = parseInt(value); + } else { + old.offsetY = parseInt(offsetY); + } + } +}; +const updateLayoutConfig = function(typeC4Shape, c4ShapeInRowParam, c4BoundaryInRowParam) { + let c4ShapeInRowValue = c4ShapeInRow$1; + let c4BoundaryInRowValue = c4BoundaryInRow$1; + if (typeof c4ShapeInRowParam === "object") { + const value = Object.values(c4ShapeInRowParam)[0]; + c4ShapeInRowValue = parseInt(value); + } else { + c4ShapeInRowValue = parseInt(c4ShapeInRowParam); + } + if (typeof c4BoundaryInRowParam === "object") { + const value = Object.values(c4BoundaryInRowParam)[0]; + c4BoundaryInRowValue = parseInt(value); + } else { + c4BoundaryInRowValue = parseInt(c4BoundaryInRowParam); + } + if (c4ShapeInRowValue >= 1) { + c4ShapeInRow$1 = c4ShapeInRowValue; + } + if (c4BoundaryInRowValue >= 1) { + c4BoundaryInRow$1 = c4BoundaryInRowValue; + } +}; +const getC4ShapeInRow = function() { + return c4ShapeInRow$1; +}; +const getC4BoundaryInRow = function() { + return c4BoundaryInRow$1; +}; +const getCurrentBoundaryParse = function() { + return currentBoundaryParse; +}; +const getParentBoundaryParse = function() { + return parentBoundaryParse; +}; +const getC4ShapeArray = function(parentBoundary) { + if (parentBoundary === void 0 || parentBoundary === null) { + return c4ShapeArray; + } else { + return c4ShapeArray.filter((personOrSystem) => { + return personOrSystem.parentBoundary === parentBoundary; + }); + } +}; +const getC4Shape = function(alias) { + return c4ShapeArray.find((personOrSystem) => personOrSystem.alias === alias); +}; +const getC4ShapeKeys = function(parentBoundary) { + return Object.keys(getC4ShapeArray(parentBoundary)); +}; +const getBoundaries = function(parentBoundary) { + if (parentBoundary === void 0 || parentBoundary === null) { + return boundaries; + } else { + return boundaries.filter((boundary) => boundary.parentBoundary === parentBoundary); + } +}; +const getBoundarys = getBoundaries; +const getRels = function() { + return rels; +}; +const getTitle = function() { + return title; +}; +const setWrap = function(wrapSetting) { + wrapEnabled = wrapSetting; +}; +const autoWrap = function() { + return wrapEnabled; +}; +const clear = function() { + c4ShapeArray = []; + boundaries = [ + { + alias: "global", + label: { text: "global" }, + type: { text: "global" }, + tags: null, + link: null, + parentBoundary: "" + } + ]; + parentBoundaryParse = ""; + currentBoundaryParse = "global"; + boundaryParseStack = [""]; + rels = []; + boundaryParseStack = [""]; + title = ""; + wrapEnabled = false; + c4ShapeInRow$1 = 4; + c4BoundaryInRow$1 = 2; +}; +const LINETYPE = { + SOLID: 0, + DOTTED: 1, + NOTE: 2, + SOLID_CROSS: 3, + DOTTED_CROSS: 4, + SOLID_OPEN: 5, + DOTTED_OPEN: 6, + LOOP_START: 10, + LOOP_END: 11, + ALT_START: 12, + ALT_ELSE: 13, + ALT_END: 14, + OPT_START: 15, + OPT_END: 16, + ACTIVE_START: 17, + ACTIVE_END: 18, + PAR_START: 19, + PAR_AND: 20, + PAR_END: 21, + RECT_START: 22, + RECT_END: 23, + SOLID_POINT: 24, + DOTTED_POINT: 25 +}; +const ARROWTYPE = { + FILLED: 0, + OPEN: 1 +}; +const PLACEMENT = { + LEFTOF: 0, + RIGHTOF: 1, + OVER: 2 +}; +const setTitle = function(txt) { + let sanitizedText = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.d)(txt, (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + title = sanitizedText; +}; +const db = { + addPersonOrSystem, + addPersonOrSystemBoundary, + addContainer, + addContainerBoundary, + addComponent, + addDeploymentNode, + popBoundaryParseStack, + addRel, + updateElStyle, + updateRelStyle, + updateLayoutConfig, + autoWrap, + setWrap, + getC4ShapeArray, + getC4Shape, + getC4ShapeKeys, + getBoundaries, + getBoundarys, + getCurrentBoundaryParse, + getParentBoundaryParse, + getRels, + getTitle, + getC4Type, + getC4ShapeInRow, + getC4BoundaryInRow, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.g, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.a, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.b, + getConfig: () => (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().c4, + clear, + LINETYPE, + ARROWTYPE, + PLACEMENT, + setTitle, + setC4Type + // apply, +}; +const drawRect = function(elem, rectData) { + return (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.d)(elem, rectData); +}; +const drawImage = function(elem, width, height, x, y, link) { + const imageElem = elem.append("image"); + imageElem.attr("width", width); + imageElem.attr("height", height); + imageElem.attr("x", x); + imageElem.attr("y", y); + let sanitizedLink = link.startsWith("data:image/png;base64") ? link : (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_1__/* .sanitizeUrl */ .Jf)(link); + imageElem.attr("xlink:href", sanitizedLink); +}; +const drawRels$1 = (elem, rels2, conf2) => { + const relsElem = elem.append("g"); + let i = 0; + for (let rel of rels2) { + let textColor = rel.textColor ? rel.textColor : "#444444"; + let strokeColor = rel.lineColor ? rel.lineColor : "#444444"; + let offsetX = rel.offsetX ? parseInt(rel.offsetX) : 0; + let offsetY = rel.offsetY ? parseInt(rel.offsetY) : 0; + let url = ""; + if (i === 0) { + let line = relsElem.append("line"); + line.attr("x1", rel.startPoint.x); + line.attr("y1", rel.startPoint.y); + line.attr("x2", rel.endPoint.x); + line.attr("y2", rel.endPoint.y); + line.attr("stroke-width", "1"); + line.attr("stroke", strokeColor); + line.style("fill", "none"); + if (rel.type !== "rel_b") { + line.attr("marker-end", "url(" + url + "#arrowhead)"); + } + if (rel.type === "birel" || rel.type === "rel_b") { + line.attr("marker-start", "url(" + url + "#arrowend)"); + } + i = -1; + } else { + let line = relsElem.append("path"); + line.attr("fill", "none").attr("stroke-width", "1").attr("stroke", strokeColor).attr( + "d", + "Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx", rel.startPoint.x).replaceAll("starty", rel.startPoint.y).replaceAll( + "controlx", + rel.startPoint.x + (rel.endPoint.x - rel.startPoint.x) / 2 - (rel.endPoint.x - rel.startPoint.x) / 4 + ).replaceAll("controly", rel.startPoint.y + (rel.endPoint.y - rel.startPoint.y) / 2).replaceAll("stopx", rel.endPoint.x).replaceAll("stopy", rel.endPoint.y) + ); + if (rel.type !== "rel_b") { + line.attr("marker-end", "url(" + url + "#arrowhead)"); + } + if (rel.type === "birel" || rel.type === "rel_b") { + line.attr("marker-start", "url(" + url + "#arrowend)"); + } + } + let messageConf = conf2.messageFont(); + _drawTextCandidateFunc(conf2)( + rel.label.text, + relsElem, + Math.min(rel.startPoint.x, rel.endPoint.x) + Math.abs(rel.endPoint.x - rel.startPoint.x) / 2 + offsetX, + Math.min(rel.startPoint.y, rel.endPoint.y) + Math.abs(rel.endPoint.y - rel.startPoint.y) / 2 + offsetY, + rel.label.width, + rel.label.height, + { fill: textColor }, + messageConf + ); + if (rel.techn && rel.techn.text !== "") { + messageConf = conf2.messageFont(); + _drawTextCandidateFunc(conf2)( + "[" + rel.techn.text + "]", + relsElem, + Math.min(rel.startPoint.x, rel.endPoint.x) + Math.abs(rel.endPoint.x - rel.startPoint.x) / 2 + offsetX, + Math.min(rel.startPoint.y, rel.endPoint.y) + Math.abs(rel.endPoint.y - rel.startPoint.y) / 2 + conf2.messageFontSize + 5 + offsetY, + Math.max(rel.label.width, rel.techn.width), + rel.techn.height, + { fill: textColor, "font-style": "italic" }, + messageConf + ); + } + } +}; +const drawBoundary$1 = function(elem, boundary, conf2) { + const boundaryElem = elem.append("g"); + let fillColor = boundary.bgColor ? boundary.bgColor : "none"; + let strokeColor = boundary.borderColor ? boundary.borderColor : "#444444"; + let fontColor = boundary.fontColor ? boundary.fontColor : "black"; + let attrsValue = { "stroke-width": 1, "stroke-dasharray": "7.0,7.0" }; + if (boundary.nodeType) { + attrsValue = { "stroke-width": 1 }; + } + let rectData = { + x: boundary.x, + y: boundary.y, + fill: fillColor, + stroke: strokeColor, + width: boundary.width, + height: boundary.height, + rx: 2.5, + ry: 2.5, + attrs: attrsValue + }; + drawRect(boundaryElem, rectData); + let boundaryConf = conf2.boundaryFont(); + boundaryConf.fontWeight = "bold"; + boundaryConf.fontSize = boundaryConf.fontSize + 2; + boundaryConf.fontColor = fontColor; + _drawTextCandidateFunc(conf2)( + boundary.label.text, + boundaryElem, + boundary.x, + boundary.y + boundary.label.Y, + boundary.width, + boundary.height, + { fill: "#444444" }, + boundaryConf + ); + if (boundary.type && boundary.type.text !== "") { + boundaryConf = conf2.boundaryFont(); + boundaryConf.fontColor = fontColor; + _drawTextCandidateFunc(conf2)( + boundary.type.text, + boundaryElem, + boundary.x, + boundary.y + boundary.type.Y, + boundary.width, + boundary.height, + { fill: "#444444" }, + boundaryConf + ); + } + if (boundary.descr && boundary.descr.text !== "") { + boundaryConf = conf2.boundaryFont(); + boundaryConf.fontSize = boundaryConf.fontSize - 2; + boundaryConf.fontColor = fontColor; + _drawTextCandidateFunc(conf2)( + boundary.descr.text, + boundaryElem, + boundary.x, + boundary.y + boundary.descr.Y, + boundary.width, + boundary.height, + { fill: "#444444" }, + boundaryConf + ); + } +}; +const drawC4Shape = function(elem, c4Shape, conf2) { + var _a; + let fillColor = c4Shape.bgColor ? c4Shape.bgColor : conf2[c4Shape.typeC4Shape.text + "_bg_color"]; + let strokeColor = c4Shape.borderColor ? c4Shape.borderColor : conf2[c4Shape.typeC4Shape.text + "_border_color"]; + let fontColor = c4Shape.fontColor ? c4Shape.fontColor : "#FFFFFF"; + let personImg = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII="; + switch (c4Shape.typeC4Shape.text) { + case "person": + personImg = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII="; + break; + case "external_person": + personImg = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAB6ElEQVR4Xu2YLY+EMBCG9+dWr0aj0Wg0Go1Go0+j8Xdv2uTCvv1gpt0ebHKPuhDaeW4605Z9mJvx4AdXUyTUdd08z+u6flmWZRnHsWkafk9DptAwDPu+f0eAYtu2PEaGWuj5fCIZrBAC2eLBAnRCsEkkxmeaJp7iDJ2QMDdHsLg8SxKFEJaAo8lAXnmuOFIhTMpxxKATebo4UiFknuNo4OniSIXQyRxEA3YsnjGCVEjVXD7yLUAqxBGUyPv/Y4W2beMgGuS7kVQIBycH0fD+oi5pezQETxdHKmQKGk1eQEYldK+jw5GxPfZ9z7Mk0Qnhf1W1m3w//EUn5BDmSZsbR44QQLBEqrBHqOrmSKaQAxdnLArCrxZcM7A7ZKs4ioRq8LFC+NpC3WCBJsvpVw5edm9iEXFuyNfxXAgSwfrFQ1c0iNda8AdejvUgnktOtJQQxmcfFzGglc5WVCj7oDgFqU18boeFSs52CUh8LE8BIVQDT1ABrB0HtgSEYlX5doJnCwv9TXocKCaKbnwhdDKPq4lf3SwU3HLq4V/+WYhHVMa/3b4IlfyikAduCkcBc7mQ3/z/Qq/cTuikhkzB12Ae/mcJC9U+Vo8Ej1gWAtgbeGgFsAMHr50BIWOLCbezvhpBFUdY6EJuJ/QDW0XoMX60zZ0AAAAASUVORK5CYII="; + break; + } + const c4ShapeElem = elem.append("g"); + c4ShapeElem.attr("class", "person-man"); + const rect = (0,_svgDrawCommon_5ccd53ef_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + switch (c4Shape.typeC4Shape.text) { + case "person": + case "external_person": + case "system": + case "external_system": + case "container": + case "external_container": + case "component": + case "external_component": + rect.x = c4Shape.x; + rect.y = c4Shape.y; + rect.fill = fillColor; + rect.width = c4Shape.width; + rect.height = c4Shape.height; + rect.stroke = strokeColor; + rect.rx = 2.5; + rect.ry = 2.5; + rect.attrs = { "stroke-width": 0.5 }; + drawRect(c4ShapeElem, rect); + break; + case "system_db": + case "external_system_db": + case "container_db": + case "external_container_db": + case "component_db": + case "external_component_db": + c4ShapeElem.append("path").attr("fill", fillColor).attr("stroke-width", "0.5").attr("stroke", strokeColor).attr( + "d", + "Mstartx,startyc0,-10 half,-10 half,-10c0,0 half,0 half,10l0,heightc0,10 -half,10 -half,10c0,0 -half,0 -half,-10l0,-height".replaceAll("startx", c4Shape.x).replaceAll("starty", c4Shape.y).replaceAll("half", c4Shape.width / 2).replaceAll("height", c4Shape.height) + ); + c4ShapeElem.append("path").attr("fill", "none").attr("stroke-width", "0.5").attr("stroke", strokeColor).attr( + "d", + "Mstartx,startyc0,10 half,10 half,10c0,0 half,0 half,-10".replaceAll("startx", c4Shape.x).replaceAll("starty", c4Shape.y).replaceAll("half", c4Shape.width / 2) + ); + break; + case "system_queue": + case "external_system_queue": + case "container_queue": + case "external_container_queue": + case "component_queue": + case "external_component_queue": + c4ShapeElem.append("path").attr("fill", fillColor).attr("stroke-width", "0.5").attr("stroke", strokeColor).attr( + "d", + "Mstartx,startylwidth,0c5,0 5,half 5,halfc0,0 0,half -5,halfl-width,0c-5,0 -5,-half -5,-halfc0,0 0,-half 5,-half".replaceAll("startx", c4Shape.x).replaceAll("starty", c4Shape.y).replaceAll("width", c4Shape.width).replaceAll("half", c4Shape.height / 2) + ); + c4ShapeElem.append("path").attr("fill", "none").attr("stroke-width", "0.5").attr("stroke", strokeColor).attr( + "d", + "Mstartx,startyc-5,0 -5,half -5,halfc0,half 5,half 5,half".replaceAll("startx", c4Shape.x + c4Shape.width).replaceAll("starty", c4Shape.y).replaceAll("half", c4Shape.height / 2) + ); + break; + } + let c4ShapeFontConf = getC4ShapeFont(conf2, c4Shape.typeC4Shape.text); + c4ShapeElem.append("text").attr("fill", fontColor).attr("font-family", c4ShapeFontConf.fontFamily).attr("font-size", c4ShapeFontConf.fontSize - 2).attr("font-style", "italic").attr("lengthAdjust", "spacing").attr("textLength", c4Shape.typeC4Shape.width).attr("x", c4Shape.x + c4Shape.width / 2 - c4Shape.typeC4Shape.width / 2).attr("y", c4Shape.y + c4Shape.typeC4Shape.Y).text("<<" + c4Shape.typeC4Shape.text + ">>"); + switch (c4Shape.typeC4Shape.text) { + case "person": + case "external_person": + drawImage( + c4ShapeElem, + 48, + 48, + c4Shape.x + c4Shape.width / 2 - 24, + c4Shape.y + c4Shape.image.Y, + personImg + ); + break; + } + let textFontConf = conf2[c4Shape.typeC4Shape.text + "Font"](); + textFontConf.fontWeight = "bold"; + textFontConf.fontSize = textFontConf.fontSize + 2; + textFontConf.fontColor = fontColor; + _drawTextCandidateFunc(conf2)( + c4Shape.label.text, + c4ShapeElem, + c4Shape.x, + c4Shape.y + c4Shape.label.Y, + c4Shape.width, + c4Shape.height, + { fill: fontColor }, + textFontConf + ); + textFontConf = conf2[c4Shape.typeC4Shape.text + "Font"](); + textFontConf.fontColor = fontColor; + if (c4Shape.techn && ((_a = c4Shape.techn) == null ? void 0 : _a.text) !== "") { + _drawTextCandidateFunc(conf2)( + c4Shape.techn.text, + c4ShapeElem, + c4Shape.x, + c4Shape.y + c4Shape.techn.Y, + c4Shape.width, + c4Shape.height, + { fill: fontColor, "font-style": "italic" }, + textFontConf + ); + } else if (c4Shape.type && c4Shape.type.text !== "") { + _drawTextCandidateFunc(conf2)( + c4Shape.type.text, + c4ShapeElem, + c4Shape.x, + c4Shape.y + c4Shape.type.Y, + c4Shape.width, + c4Shape.height, + { fill: fontColor, "font-style": "italic" }, + textFontConf + ); + } + if (c4Shape.descr && c4Shape.descr.text !== "") { + textFontConf = conf2.personFont(); + textFontConf.fontColor = fontColor; + _drawTextCandidateFunc(conf2)( + c4Shape.descr.text, + c4ShapeElem, + c4Shape.x, + c4Shape.y + c4Shape.descr.Y, + c4Shape.width, + c4Shape.height, + { fill: fontColor }, + textFontConf + ); + } + return c4Shape.height; +}; +const insertDatabaseIcon = function(elem) { + elem.append("defs").append("symbol").attr("id", "database").attr("fill-rule", "evenodd").attr("clip-rule", "evenodd").append("path").attr("transform", "scale(.5)").attr( + "d", + "M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z" + ); +}; +const insertComputerIcon = function(elem) { + elem.append("defs").append("symbol").attr("id", "computer").attr("width", "24").attr("height", "24").append("path").attr("transform", "scale(.5)").attr( + "d", + "M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z" + ); +}; +const insertClockIcon = function(elem) { + elem.append("defs").append("symbol").attr("id", "clock").attr("width", "24").attr("height", "24").append("path").attr("transform", "scale(.5)").attr( + "d", + "M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z" + ); +}; +const insertArrowHead = function(elem) { + elem.append("defs").append("marker").attr("id", "arrowhead").attr("refX", 9).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z"); +}; +const insertArrowEnd = function(elem) { + elem.append("defs").append("marker").attr("id", "arrowend").attr("refX", 1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 10 0 L 0 5 L 10 10 z"); +}; +const insertArrowFilledHead = function(elem) { + elem.append("defs").append("marker").attr("id", "filled-head").attr("refX", 18).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const insertDynamicNumber = function(elem) { + elem.append("defs").append("marker").attr("id", "sequencenumber").attr("refX", 15).attr("refY", 15).attr("markerWidth", 60).attr("markerHeight", 40).attr("orient", "auto").append("circle").attr("cx", 15).attr("cy", 15).attr("r", 6); +}; +const insertArrowCrossHead = function(elem) { + const defs = elem.append("defs"); + const marker = defs.append("marker").attr("id", "crosshead").attr("markerWidth", 15).attr("markerHeight", 8).attr("orient", "auto").attr("refX", 16).attr("refY", 4); + marker.append("path").attr("fill", "black").attr("stroke", "#000000").style("stroke-dasharray", "0, 0").attr("stroke-width", "1px").attr("d", "M 9,2 V 6 L16,4 Z"); + marker.append("path").attr("fill", "none").attr("stroke", "#000000").style("stroke-dasharray", "0, 0").attr("stroke-width", "1px").attr("d", "M 0,1 L 6,7 M 6,1 L 0,7"); +}; +const getC4ShapeFont = (cnf, typeC4Shape) => { + return { + fontFamily: cnf[typeC4Shape + "FontFamily"], + fontSize: cnf[typeC4Shape + "FontSize"], + fontWeight: cnf[typeC4Shape + "FontWeight"] + }; +}; +const _drawTextCandidateFunc = function() { + function byText(content, g, x, y, width, height, textAttrs) { + const text = g.append("text").attr("x", x + width / 2).attr("y", y + height / 2 + 5).style("text-anchor", "middle").text(content); + _setTextAttrs(text, textAttrs); + } + function byTspan(content, g, x, y, width, height, textAttrs, conf2) { + const { fontSize, fontFamily, fontWeight } = conf2; + const lines = content.split(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.lineBreakRegex); + for (let i = 0; i < lines.length; i++) { + const dy = i * fontSize - fontSize * (lines.length - 1) / 2; + const text = g.append("text").attr("x", x + width / 2).attr("y", y).style("text-anchor", "middle").attr("dominant-baseline", "middle").style("font-size", fontSize).style("font-weight", fontWeight).style("font-family", fontFamily); + text.append("tspan").attr("dy", dy).text(lines[i]).attr("alignment-baseline", "mathematical"); + _setTextAttrs(text, textAttrs); + } + } + function byFo(content, g, x, y, width, height, textAttrs, conf2) { + const s = g.append("switch"); + const f = s.append("foreignObject").attr("x", x).attr("y", y).attr("width", width).attr("height", height); + const text = f.append("xhtml:div").style("display", "table").style("height", "100%").style("width", "100%"); + text.append("div").style("display", "table-cell").style("text-align", "center").style("vertical-align", "middle").text(content); + byTspan(content, s, x, y, width, height, textAttrs, conf2); + _setTextAttrs(text, textAttrs); + } + function _setTextAttrs(toText, fromTextAttrsDict) { + for (const key in fromTextAttrsDict) { + if (fromTextAttrsDict.hasOwnProperty(key)) { + toText.attr(key, fromTextAttrsDict[key]); + } + } + } + return function(conf2) { + return conf2.textPlacement === "fo" ? byFo : conf2.textPlacement === "old" ? byText : byTspan; + }; +}(); +const svgDraw = { + drawRect, + drawBoundary: drawBoundary$1, + drawC4Shape, + drawRels: drawRels$1, + drawImage, + insertArrowHead, + insertArrowEnd, + insertArrowFilledHead, + insertDynamicNumber, + insertArrowCrossHead, + insertDatabaseIcon, + insertComputerIcon, + insertClockIcon +}; +let globalBoundaryMaxX = 0, globalBoundaryMaxY = 0; +let c4ShapeInRow = 4; +let c4BoundaryInRow = 2; +parser.yy = db; +let conf = {}; +class Bounds { + constructor(diagObj) { + this.name = ""; + this.data = {}; + this.data.startx = void 0; + this.data.stopx = void 0; + this.data.starty = void 0; + this.data.stopy = void 0; + this.data.widthLimit = void 0; + this.nextData = {}; + this.nextData.startx = void 0; + this.nextData.stopx = void 0; + this.nextData.starty = void 0; + this.nextData.stopy = void 0; + this.nextData.cnt = 0; + setConf(diagObj.db.getConfig()); + } + setData(startx, stopx, starty, stopy) { + this.nextData.startx = this.data.startx = startx; + this.nextData.stopx = this.data.stopx = stopx; + this.nextData.starty = this.data.starty = starty; + this.nextData.stopy = this.data.stopy = stopy; + } + updateVal(obj, key, val, fun) { + if (obj[key] === void 0) { + obj[key] = val; + } else { + obj[key] = fun(val, obj[key]); + } + } + insert(c4Shape) { + this.nextData.cnt = this.nextData.cnt + 1; + let _startx = this.nextData.startx === this.nextData.stopx ? this.nextData.stopx + c4Shape.margin : this.nextData.stopx + c4Shape.margin * 2; + let _stopx = _startx + c4Shape.width; + let _starty = this.nextData.starty + c4Shape.margin * 2; + let _stopy = _starty + c4Shape.height; + if (_startx >= this.data.widthLimit || _stopx >= this.data.widthLimit || this.nextData.cnt > c4ShapeInRow) { + _startx = this.nextData.startx + c4Shape.margin + conf.nextLinePaddingX; + _starty = this.nextData.stopy + c4Shape.margin * 2; + this.nextData.stopx = _stopx = _startx + c4Shape.width; + this.nextData.starty = this.nextData.stopy; + this.nextData.stopy = _stopy = _starty + c4Shape.height; + this.nextData.cnt = 1; + } + c4Shape.x = _startx; + c4Shape.y = _starty; + this.updateVal(this.data, "startx", _startx, Math.min); + this.updateVal(this.data, "starty", _starty, Math.min); + this.updateVal(this.data, "stopx", _stopx, Math.max); + this.updateVal(this.data, "stopy", _stopy, Math.max); + this.updateVal(this.nextData, "startx", _startx, Math.min); + this.updateVal(this.nextData, "starty", _starty, Math.min); + this.updateVal(this.nextData, "stopx", _stopx, Math.max); + this.updateVal(this.nextData, "stopy", _stopy, Math.max); + } + init(diagObj) { + this.name = ""; + this.data = { + startx: void 0, + stopx: void 0, + starty: void 0, + stopy: void 0, + widthLimit: void 0 + }; + this.nextData = { + startx: void 0, + stopx: void 0, + starty: void 0, + stopy: void 0, + cnt: 0 + }; + setConf(diagObj.db.getConfig()); + } + bumpLastMargin(margin) { + this.data.stopx += margin; + this.data.stopy += margin; + } +} +const setConf = function(cnf) { + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.f)(conf, cnf); + if (cnf.fontFamily) { + conf.personFontFamily = conf.systemFontFamily = conf.messageFontFamily = cnf.fontFamily; + } + if (cnf.fontSize) { + conf.personFontSize = conf.systemFontSize = conf.messageFontSize = cnf.fontSize; + } + if (cnf.fontWeight) { + conf.personFontWeight = conf.systemFontWeight = conf.messageFontWeight = cnf.fontWeight; + } +}; +const c4ShapeFont = (cnf, typeC4Shape) => { + return { + fontFamily: cnf[typeC4Shape + "FontFamily"], + fontSize: cnf[typeC4Shape + "FontSize"], + fontWeight: cnf[typeC4Shape + "FontWeight"] + }; +}; +const boundaryFont = (cnf) => { + return { + fontFamily: cnf.boundaryFontFamily, + fontSize: cnf.boundaryFontSize, + fontWeight: cnf.boundaryFontWeight + }; +}; +const messageFont = (cnf) => { + return { + fontFamily: cnf.messageFontFamily, + fontSize: cnf.messageFontSize, + fontWeight: cnf.messageFontWeight + }; +}; +function calcC4ShapeTextWH(textType, c4Shape, c4ShapeTextWrap, textConf, textLimitWidth) { + if (!c4Shape[textType].width) { + if (c4ShapeTextWrap) { + c4Shape[textType].text = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.w)(c4Shape[textType].text, textLimitWidth, textConf); + c4Shape[textType].textLines = c4Shape[textType].text.split(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.lineBreakRegex).length; + c4Shape[textType].width = textLimitWidth; + c4Shape[textType].height = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.j)(c4Shape[textType].text, textConf); + } else { + let lines = c4Shape[textType].text.split(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.e.lineBreakRegex); + c4Shape[textType].textLines = lines.length; + let lineHeight = 0; + c4Shape[textType].height = 0; + c4Shape[textType].width = 0; + for (const line of lines) { + c4Shape[textType].width = Math.max( + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.h)(line, textConf), + c4Shape[textType].width + ); + lineHeight = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.j)(line, textConf); + c4Shape[textType].height = c4Shape[textType].height + lineHeight; + } + } + } +} +const drawBoundary = function(diagram2, boundary, bounds) { + boundary.x = bounds.data.startx; + boundary.y = bounds.data.starty; + boundary.width = bounds.data.stopx - bounds.data.startx; + boundary.height = bounds.data.stopy - bounds.data.starty; + boundary.label.y = conf.c4ShapeMargin - 35; + let boundaryTextWrap = boundary.wrap && conf.wrap; + let boundaryLabelConf = boundaryFont(conf); + boundaryLabelConf.fontSize = boundaryLabelConf.fontSize + 2; + boundaryLabelConf.fontWeight = "bold"; + let textLimitWidth = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.h)(boundary.label.text, boundaryLabelConf); + calcC4ShapeTextWH("label", boundary, boundaryTextWrap, boundaryLabelConf, textLimitWidth); + svgDraw.drawBoundary(diagram2, boundary, conf); +}; +const drawC4ShapeArray = function(currentBounds, diagram2, c4ShapeArray2, c4ShapeKeys) { + let Y = 0; + for (const c4ShapeKey of c4ShapeKeys) { + Y = 0; + const c4Shape = c4ShapeArray2[c4ShapeKey]; + let c4ShapeTypeConf = c4ShapeFont(conf, c4Shape.typeC4Shape.text); + c4ShapeTypeConf.fontSize = c4ShapeTypeConf.fontSize - 2; + c4Shape.typeC4Shape.width = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.h)( + "«" + c4Shape.typeC4Shape.text + "»", + c4ShapeTypeConf + ); + c4Shape.typeC4Shape.height = c4ShapeTypeConf.fontSize + 2; + c4Shape.typeC4Shape.Y = conf.c4ShapePadding; + Y = c4Shape.typeC4Shape.Y + c4Shape.typeC4Shape.height - 4; + c4Shape.image = { width: 0, height: 0, Y: 0 }; + switch (c4Shape.typeC4Shape.text) { + case "person": + case "external_person": + c4Shape.image.width = 48; + c4Shape.image.height = 48; + c4Shape.image.Y = Y; + Y = c4Shape.image.Y + c4Shape.image.height; + break; + } + if (c4Shape.sprite) { + c4Shape.image.width = 48; + c4Shape.image.height = 48; + c4Shape.image.Y = Y; + Y = c4Shape.image.Y + c4Shape.image.height; + } + let c4ShapeTextWrap = c4Shape.wrap && conf.wrap; + let textLimitWidth = conf.width - conf.c4ShapePadding * 2; + let c4ShapeLabelConf = c4ShapeFont(conf, c4Shape.typeC4Shape.text); + c4ShapeLabelConf.fontSize = c4ShapeLabelConf.fontSize + 2; + c4ShapeLabelConf.fontWeight = "bold"; + calcC4ShapeTextWH("label", c4Shape, c4ShapeTextWrap, c4ShapeLabelConf, textLimitWidth); + c4Shape["label"].Y = Y + 8; + Y = c4Shape["label"].Y + c4Shape["label"].height; + if (c4Shape.type && c4Shape.type.text !== "") { + c4Shape.type.text = "[" + c4Shape.type.text + "]"; + let c4ShapeTypeConf2 = c4ShapeFont(conf, c4Shape.typeC4Shape.text); + calcC4ShapeTextWH("type", c4Shape, c4ShapeTextWrap, c4ShapeTypeConf2, textLimitWidth); + c4Shape["type"].Y = Y + 5; + Y = c4Shape["type"].Y + c4Shape["type"].height; + } else if (c4Shape.techn && c4Shape.techn.text !== "") { + c4Shape.techn.text = "[" + c4Shape.techn.text + "]"; + let c4ShapeTechnConf = c4ShapeFont(conf, c4Shape.techn.text); + calcC4ShapeTextWH("techn", c4Shape, c4ShapeTextWrap, c4ShapeTechnConf, textLimitWidth); + c4Shape["techn"].Y = Y + 5; + Y = c4Shape["techn"].Y + c4Shape["techn"].height; + } + let rectHeight = Y; + let rectWidth = c4Shape.label.width; + if (c4Shape.descr && c4Shape.descr.text !== "") { + let c4ShapeDescrConf = c4ShapeFont(conf, c4Shape.typeC4Shape.text); + calcC4ShapeTextWH("descr", c4Shape, c4ShapeTextWrap, c4ShapeDescrConf, textLimitWidth); + c4Shape["descr"].Y = Y + 20; + Y = c4Shape["descr"].Y + c4Shape["descr"].height; + rectWidth = Math.max(c4Shape.label.width, c4Shape.descr.width); + rectHeight = Y - c4Shape["descr"].textLines * 5; + } + rectWidth = rectWidth + conf.c4ShapePadding; + c4Shape.width = Math.max(c4Shape.width || conf.width, rectWidth, conf.width); + c4Shape.height = Math.max(c4Shape.height || conf.height, rectHeight, conf.height); + c4Shape.margin = c4Shape.margin || conf.c4ShapeMargin; + currentBounds.insert(c4Shape); + svgDraw.drawC4Shape(diagram2, c4Shape, conf); + } + currentBounds.bumpLastMargin(conf.c4ShapeMargin); +}; +class Point { + constructor(x, y) { + this.x = x; + this.y = y; + } +} +let getIntersectPoint = function(fromNode, endPoint) { + let x1 = fromNode.x; + let y1 = fromNode.y; + let x2 = endPoint.x; + let y2 = endPoint.y; + let fromCenterX = x1 + fromNode.width / 2; + let fromCenterY = y1 + fromNode.height / 2; + let dx = Math.abs(x1 - x2); + let dy = Math.abs(y1 - y2); + let tanDYX = dy / dx; + let fromDYX = fromNode.height / fromNode.width; + let returnPoint = null; + if (y1 == y2 && x1 < x2) { + returnPoint = new Point(x1 + fromNode.width, fromCenterY); + } else if (y1 == y2 && x1 > x2) { + returnPoint = new Point(x1, fromCenterY); + } else if (x1 == x2 && y1 < y2) { + returnPoint = new Point(fromCenterX, y1 + fromNode.height); + } else if (x1 == x2 && y1 > y2) { + returnPoint = new Point(fromCenterX, y1); + } + if (x1 > x2 && y1 < y2) { + if (fromDYX >= tanDYX) { + returnPoint = new Point(x1, fromCenterY + tanDYX * fromNode.width / 2); + } else { + returnPoint = new Point( + fromCenterX - dx / dy * fromNode.height / 2, + y1 + fromNode.height + ); + } + } else if (x1 < x2 && y1 < y2) { + if (fromDYX >= tanDYX) { + returnPoint = new Point(x1 + fromNode.width, fromCenterY + tanDYX * fromNode.width / 2); + } else { + returnPoint = new Point( + fromCenterX + dx / dy * fromNode.height / 2, + y1 + fromNode.height + ); + } + } else if (x1 < x2 && y1 > y2) { + if (fromDYX >= tanDYX) { + returnPoint = new Point(x1 + fromNode.width, fromCenterY - tanDYX * fromNode.width / 2); + } else { + returnPoint = new Point(fromCenterX + fromNode.height / 2 * dx / dy, y1); + } + } else if (x1 > x2 && y1 > y2) { + if (fromDYX >= tanDYX) { + returnPoint = new Point(x1, fromCenterY - fromNode.width / 2 * tanDYX); + } else { + returnPoint = new Point(fromCenterX - fromNode.height / 2 * dx / dy, y1); + } + } + return returnPoint; +}; +let getIntersectPoints = function(fromNode, endNode) { + let endIntersectPoint = { x: 0, y: 0 }; + endIntersectPoint.x = endNode.x + endNode.width / 2; + endIntersectPoint.y = endNode.y + endNode.height / 2; + let startPoint = getIntersectPoint(fromNode, endIntersectPoint); + endIntersectPoint.x = fromNode.x + fromNode.width / 2; + endIntersectPoint.y = fromNode.y + fromNode.height / 2; + let endPoint = getIntersectPoint(endNode, endIntersectPoint); + return { startPoint, endPoint }; +}; +const drawRels = function(diagram2, rels2, getC4ShapeObj, diagObj) { + let i = 0; + for (let rel of rels2) { + i = i + 1; + let relTextWrap = rel.wrap && conf.wrap; + let relConf = messageFont(conf); + let diagramType = diagObj.db.getC4Type(); + if (diagramType === "C4Dynamic") { + rel.label.text = i + ": " + rel.label.text; + } + let textLimitWidth = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.h)(rel.label.text, relConf); + calcC4ShapeTextWH("label", rel, relTextWrap, relConf, textLimitWidth); + if (rel.techn && rel.techn.text !== "") { + textLimitWidth = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.h)(rel.techn.text, relConf); + calcC4ShapeTextWH("techn", rel, relTextWrap, relConf, textLimitWidth); + } + if (rel.descr && rel.descr.text !== "") { + textLimitWidth = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.h)(rel.descr.text, relConf); + calcC4ShapeTextWH("descr", rel, relTextWrap, relConf, textLimitWidth); + } + let fromNode = getC4ShapeObj(rel.from); + let endNode = getC4ShapeObj(rel.to); + let points = getIntersectPoints(fromNode, endNode); + rel.startPoint = points.startPoint; + rel.endPoint = points.endPoint; + } + svgDraw.drawRels(diagram2, rels2, conf); +}; +function drawInsideBoundary(diagram2, parentBoundaryAlias, parentBounds, currentBoundaries, diagObj) { + let currentBounds = new Bounds(diagObj); + currentBounds.data.widthLimit = parentBounds.data.widthLimit / Math.min(c4BoundaryInRow, currentBoundaries.length); + for (let [i, currentBoundary] of currentBoundaries.entries()) { + let Y = 0; + currentBoundary.image = { width: 0, height: 0, Y: 0 }; + if (currentBoundary.sprite) { + currentBoundary.image.width = 48; + currentBoundary.image.height = 48; + currentBoundary.image.Y = Y; + Y = currentBoundary.image.Y + currentBoundary.image.height; + } + let currentBoundaryTextWrap = currentBoundary.wrap && conf.wrap; + let currentBoundaryLabelConf = boundaryFont(conf); + currentBoundaryLabelConf.fontSize = currentBoundaryLabelConf.fontSize + 2; + currentBoundaryLabelConf.fontWeight = "bold"; + calcC4ShapeTextWH( + "label", + currentBoundary, + currentBoundaryTextWrap, + currentBoundaryLabelConf, + currentBounds.data.widthLimit + ); + currentBoundary["label"].Y = Y + 8; + Y = currentBoundary["label"].Y + currentBoundary["label"].height; + if (currentBoundary.type && currentBoundary.type.text !== "") { + currentBoundary.type.text = "[" + currentBoundary.type.text + "]"; + let currentBoundaryTypeConf = boundaryFont(conf); + calcC4ShapeTextWH( + "type", + currentBoundary, + currentBoundaryTextWrap, + currentBoundaryTypeConf, + currentBounds.data.widthLimit + ); + currentBoundary["type"].Y = Y + 5; + Y = currentBoundary["type"].Y + currentBoundary["type"].height; + } + if (currentBoundary.descr && currentBoundary.descr.text !== "") { + let currentBoundaryDescrConf = boundaryFont(conf); + currentBoundaryDescrConf.fontSize = currentBoundaryDescrConf.fontSize - 2; + calcC4ShapeTextWH( + "descr", + currentBoundary, + currentBoundaryTextWrap, + currentBoundaryDescrConf, + currentBounds.data.widthLimit + ); + currentBoundary["descr"].Y = Y + 20; + Y = currentBoundary["descr"].Y + currentBoundary["descr"].height; + } + if (i == 0 || i % c4BoundaryInRow === 0) { + let _x = parentBounds.data.startx + conf.diagramMarginX; + let _y = parentBounds.data.stopy + conf.diagramMarginY + Y; + currentBounds.setData(_x, _x, _y, _y); + } else { + let _x = currentBounds.data.stopx !== currentBounds.data.startx ? currentBounds.data.stopx + conf.diagramMarginX : currentBounds.data.startx; + let _y = currentBounds.data.starty; + currentBounds.setData(_x, _x, _y, _y); + } + currentBounds.name = currentBoundary.alias; + let currentPersonOrSystemArray = diagObj.db.getC4ShapeArray(currentBoundary.alias); + let currentPersonOrSystemKeys = diagObj.db.getC4ShapeKeys(currentBoundary.alias); + if (currentPersonOrSystemKeys.length > 0) { + drawC4ShapeArray( + currentBounds, + diagram2, + currentPersonOrSystemArray, + currentPersonOrSystemKeys + ); + } + parentBoundaryAlias = currentBoundary.alias; + let nextCurrentBoundaries = diagObj.db.getBoundarys(parentBoundaryAlias); + if (nextCurrentBoundaries.length > 0) { + drawInsideBoundary( + diagram2, + parentBoundaryAlias, + currentBounds, + nextCurrentBoundaries, + diagObj + ); + } + if (currentBoundary.alias !== "global") { + drawBoundary(diagram2, currentBoundary, currentBounds); + } + parentBounds.data.stopy = Math.max( + currentBounds.data.stopy + conf.c4ShapeMargin, + parentBounds.data.stopy + ); + parentBounds.data.stopx = Math.max( + currentBounds.data.stopx + conf.c4ShapeMargin, + parentBounds.data.stopx + ); + globalBoundaryMaxX = Math.max(globalBoundaryMaxX, parentBounds.data.stopx); + globalBoundaryMaxY = Math.max(globalBoundaryMaxY, parentBounds.data.stopy); + } +} +const draw = function(_text, id, _version, diagObj) { + conf = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().c4; + const securityLevel = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body"); + let db2 = diagObj.db; + diagObj.db.setWrap(conf.wrap); + c4ShapeInRow = db2.getC4ShapeInRow(); + c4BoundaryInRow = db2.getC4BoundaryInRow(); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(`C:${JSON.stringify(conf, null, 2)}`); + const diagram2 = securityLevel === "sandbox" ? root.select(`[id="${id}"]`) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(`[id="${id}"]`); + svgDraw.insertComputerIcon(diagram2); + svgDraw.insertDatabaseIcon(diagram2); + svgDraw.insertClockIcon(diagram2); + let screenBounds = new Bounds(diagObj); + screenBounds.setData( + conf.diagramMarginX, + conf.diagramMarginX, + conf.diagramMarginY, + conf.diagramMarginY + ); + screenBounds.data.widthLimit = screen.availWidth; + globalBoundaryMaxX = conf.diagramMarginX; + globalBoundaryMaxY = conf.diagramMarginY; + const title2 = diagObj.db.getTitle(); + let currentBoundaries = diagObj.db.getBoundarys(""); + drawInsideBoundary(diagram2, "", screenBounds, currentBoundaries, diagObj); + svgDraw.insertArrowHead(diagram2); + svgDraw.insertArrowEnd(diagram2); + svgDraw.insertArrowCrossHead(diagram2); + svgDraw.insertArrowFilledHead(diagram2); + drawRels(diagram2, diagObj.db.getRels(), diagObj.db.getC4Shape, diagObj); + screenBounds.data.stopx = globalBoundaryMaxX; + screenBounds.data.stopy = globalBoundaryMaxY; + const box = screenBounds.data; + let boxHeight = box.stopy - box.starty; + let height = boxHeight + 2 * conf.diagramMarginY; + let boxWidth = box.stopx - box.startx; + const width = boxWidth + 2 * conf.diagramMarginX; + if (title2) { + diagram2.append("text").text(title2).attr("x", (box.stopx - box.startx) / 2 - 4 * conf.diagramMarginX).attr("y", box.starty + conf.diagramMarginY); + } + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.i)(diagram2, height, width, conf.useMaxWidth); + const extraVertForTitle = title2 ? 60 : 0; + diagram2.attr( + "viewBox", + box.startx - conf.diagramMarginX + " -" + (conf.diagramMarginY + extraVertForTitle) + " " + width + " " + (height + extraVertForTitle) + ); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(`models:`, box); +}; +const renderer = { + drawPersonOrSystemArray: drawC4ShapeArray, + drawBoundary, + setConf, + draw +}; +const getStyles = (options) => `.person { + stroke: ${options.personBorder}; + fill: ${options.personBkg}; + } +`; +const styles = getStyles; +const diagram = { + parser: parser$1, + db, + renderer, + styles, + init: ({ c4, wrap }) => { + renderer.setConf(c4); + db.setWrap(wrap); + } +}; + + + +/***/ }), + +/***/ 58886: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ drawBackgroundRect), +/* harmony export */ b: () => (/* binding */ drawEmbeddedImage), +/* harmony export */ c: () => (/* binding */ drawImage), +/* harmony export */ d: () => (/* binding */ drawRect), +/* harmony export */ e: () => (/* binding */ getTextObj), +/* harmony export */ f: () => (/* binding */ drawText), +/* harmony export */ g: () => (/* binding */ getNoteRect) +/* harmony export */ }); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(16750); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76257); + + +const drawRect = (element, rectData) => { + const rectElement = element.append("rect"); + rectElement.attr("x", rectData.x); + rectElement.attr("y", rectData.y); + rectElement.attr("fill", rectData.fill); + rectElement.attr("stroke", rectData.stroke); + rectElement.attr("width", rectData.width); + rectElement.attr("height", rectData.height); + if (rectData.name) { + rectElement.attr("name", rectData.name); + } + rectData.rx !== void 0 && rectElement.attr("rx", rectData.rx); + rectData.ry !== void 0 && rectElement.attr("ry", rectData.ry); + if (rectData.attrs !== void 0) { + for (const attrKey in rectData.attrs) { + rectElement.attr(attrKey, rectData.attrs[attrKey]); + } + } + rectData.class !== void 0 && rectElement.attr("class", rectData.class); + return rectElement; +}; +const drawBackgroundRect = (element, bounds) => { + const rectData = { + x: bounds.startx, + y: bounds.starty, + width: bounds.stopx - bounds.startx, + height: bounds.stopy - bounds.starty, + fill: bounds.fill, + stroke: bounds.stroke, + class: "rect" + }; + const rectElement = drawRect(element, rectData); + rectElement.lower(); +}; +const drawText = (element, textData) => { + const nText = textData.text.replace(_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_1__.J, " "); + const textElem = element.append("text"); + textElem.attr("x", textData.x); + textElem.attr("y", textData.y); + textElem.attr("class", "legend"); + textElem.style("text-anchor", textData.anchor); + textData.class !== void 0 && textElem.attr("class", textData.class); + const tspan = textElem.append("tspan"); + tspan.attr("x", textData.x + textData.textMargin * 2); + tspan.text(nText); + return textElem; +}; +const drawImage = (elem, x, y, link) => { + const imageElement = elem.append("image"); + imageElement.attr("x", x); + imageElement.attr("y", y); + const sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Jf)(link); + imageElement.attr("xlink:href", sanitizedLink); +}; +const drawEmbeddedImage = (element, x, y, link) => { + const imageElement = element.append("use"); + imageElement.attr("x", x); + imageElement.attr("y", y); + const sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Jf)(link); + imageElement.attr("xlink:href", `#${sanitizedLink}`); +}; +const getNoteRect = () => { + const noteRectData = { + x: 0, + y: 0, + width: 100, + height: 100, + fill: "#EDF2AE", + stroke: "#666", + anchor: "start", + rx: 0, + ry: 0 + }; + return noteRectData; +}; +const getTextObj = () => { + const testObject = { + x: 0, + y: 0, + width: 100, + height: 100, + "text-anchor": "start", + style: "#666", + textMargin: 0, + rx: 0, + ry: 0, + tspan: true + }; + return testObject; +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/8679ddc4.81b643e4.js b/assets/js/8679ddc4.81b643e4.js new file mode 100644 index 0000000000..77f626f066 --- /dev/null +++ b/assets/js/8679ddc4.81b643e4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6960],{38395:(e,i,o)=>{o.r(i),o.d(i,{assets:()=>d,contentTitle:()=>c,default:()=>g,frontMatter:()=>s,metadata:()=>t,toc:()=>a});var n=o(74848),r=o(28453);const s={sidebar_label:"Docker"},c="Docker",t={id:"iaas/guides/configuration-guide/services/docker",title:"Docker",description:"With the osism.services.docker role, it is possible to manage Docker.",source:"@site/docs/02-iaas/guides/configuration-guide/services/docker.md",sourceDirName:"02-iaas/guides/configuration-guide/services",slug:"/iaas/guides/configuration-guide/services/docker",permalink:"/docs/iaas/guides/configuration-guide/services/docker",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/services/docker.md",tags:[],version:"current",frontMatter:{sidebar_label:"Docker"},sidebar:"docs",previous:{title:"Chrony",permalink:"/docs/iaas/guides/configuration-guide/services/chrony"},next:{title:"Tuned",permalink:"/docs/iaas/guides/configuration-guide/services/tuned"}},d={},a=[{value:"Configure logging drivers",id:"configure-logging-drivers",level:2}];function l(e){const i={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.h1,{id:"docker",children:"Docker"}),"\n",(0,n.jsxs)(i.p,{children:["With the ",(0,n.jsx)(i.code,{children:"osism.services.docker"})," role, it is possible to manage Docker."]}),"\n",(0,n.jsx)(i.h2,{id:"configure-logging-drivers",children:"Configure logging drivers"}),"\n",(0,n.jsxs)(i.p,{children:["Docker documentation: ",(0,n.jsx)(i.a,{href:"https://docs.docker.com/config/containers/logging/configure/",children:"https://docs.docker.com/config/containers/logging/configure/"})]}),"\n",(0,n.jsx)(i.p,{children:"The role currently supports the following parameters with their respective defaults."}),"\n",(0,n.jsx)(i.pre,{children:(0,n.jsx)(i.code,{className:"language-yaml",children:'docker_log_driver: "json-file"\ndocker_log_level: info\ndocker_log_opts:\n max-size: 10m\n max-file: 3\n'})}),"\n",(0,n.jsxs)(i.p,{children:["The log driver to be used can be configured with ",(0,n.jsx)(i.code,{children:"docker_log_driver"}),". By default,\n",(0,n.jsx)(i.a,{href:"https://docs.docker.com/config/containers/logging/json-file/",children:"json-file"})," is used.\nThe log driver writes all logs of a container to a JSON file\nin ",(0,n.jsx)(i.code,{children:"/var/lib/docker/containers"}),". All supported log drivers can be found in the\n",(0,n.jsx)(i.a,{href:"https://docs.docker.com/config/containers/logging/configure/#supported-logging-drivers",children:"Docker documentation"}),"."]}),"\n",(0,n.jsxs)(i.p,{children:["The log level can be configured via ",(0,n.jsx)(i.code,{children:"docker_log_level"}),"."]}),"\n",(0,n.jsxs)(i.p,{children:["Parameters for the log driver used can be set with the ",(0,n.jsx)(i.code,{children:"docker_log_opts"})," dictionary.\nBy default, the maximum size of a JSON file is set to 10 MByte with ",(0,n.jsx)(i.code,{children:"max-size: 10m"}),".\nIf it contains more, the file is rotated."]}),"\n",(0,n.jsxs)(i.p,{children:["Furthermore, ",(0,n.jsx)(i.code,{children:"max-file: 3"})," specifies that up to 3 files should be available."]}),"\n",(0,n.jsx)(i.p,{children:"Existing containers don't use the new logging configuration automatically."})]})}function g(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,i,o)=>{o.d(i,{R:()=>c,x:()=>t});var n=o(96540);const r={},s=n.createContext(r);function c(e){const i=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function t(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(s.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/86ee3414.b8446b41.js b/assets/js/86ee3414.b8446b41.js new file mode 100644 index 0000000000..1eb316414a --- /dev/null +++ b/assets/js/86ee3414.b8446b41.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3365],{37427:(o,e,t)=>{t.r(e),t.d(e,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var n=t(74848),s=t(28453);const i={sidebar_label:"Tools",sidebar_position:10},c="Tools",r={id:"iaas/components/index",title:"Tools",description:"",source:"@site/docs/02-iaas/components/index.md",sourceDirName:"02-iaas/components",slug:"/iaas/components/",permalink:"/docs/iaas/components/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/index.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Tools",sidebar_position:10}},a={},d=[];function l(o){const e={h1:"h1",...(0,s.R)(),...o.components};return(0,n.jsx)(e.h1,{id:"tools",children:"Tools"})}function u(o={}){const{wrapper:e}={...(0,s.R)(),...o.components};return e?(0,n.jsx)(e,{...o,children:(0,n.jsx)(l,{...o})}):l(o)}},28453:(o,e,t)=>{t.d(e,{R:()=>c,x:()=>r});var n=t(96540);const s={},i=n.createContext(s);function c(o){const e=n.useContext(i);return n.useMemo((function(){return"function"==typeof o?o(e):{...e,...o}}),[e,o])}function r(o){let e;return e=o.disableParentContext?"function"==typeof o.components?o.components(s):o.components||s:c(o.components),n.createElement(i.Provider,{value:e},o.children)}}}]); \ No newline at end of file diff --git a/assets/js/87293620.e6e8b3d7.js b/assets/js/87293620.e6e8b3d7.js new file mode 100644 index 0000000000..3d2261bcc6 --- /dev/null +++ b/assets/js/87293620.e6e8b3d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4850],{58320:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var o=t(74848),a=t(28453);const r={},i="SIG Central API",s={id:"collaboration/sig-central-api",title:"SIG Central API",description:"For defining a Common and Central interface for the Customers of SCS cloud to manage the Infrastructure cloud resources open stack and Kubernetes and identity and Access management.",source:"@site/community/collaboration/sig-central-api.md",sourceDirName:"collaboration",slug:"/collaboration/sig-central-api",permalink:"/community/collaboration/sig-central-api",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Team Ops",permalink:"/community/collaboration/team-ops"},next:{title:"SIG Community",permalink:"/community/collaboration/sig-community"}},c={},l=[];function u(e){const n={h1:"h1",p:"p",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"sig-central-api",children:"SIG Central API"}),"\n",(0,o.jsx)(n.p,{children:"For defining a Common and Central interface for the Customers of SCS cloud to manage the Infrastructure cloud resources open stack and Kubernetes and identity and Access management."}),"\n",(0,o.jsx)(n.p,{children:"We want to define a single point of managment with consistent experience for managing the entire infrastructure."}),"\n",(0,o.jsx)(n.p,{children:"We aim to establish an unified and central interface that provides customers\nof the SCS clouds with the ability to manage cloud resources and/or services."}),"\n",(0,o.jsx)(n.p,{children:"SIG explores the possibilities for a central API by creating a MVP."})]})}function m(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>s});var o=t(96540);const a={},r=o.createContext(a);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8747.d998ad87.js b/assets/js/8747.d998ad87.js new file mode 100644 index 0000000000..a803308ea8 --- /dev/null +++ b/assets/js/8747.d998ad87.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8747],{28747:(t,e,a)=>{a.d(e,{a:()=>l,b:()=>B,c:()=>d,d:()=>I,e:()=>M,f:()=>j,g:()=>C,h:()=>A,i:()=>x,j:()=>N,k:()=>R,l:()=>o,m:()=>Y,p:()=>_,s:()=>T,u:()=>h});var r=a(76257),n=a(26312),i=a(45829);const s={extension:(t,e,a)=>{r.l.trace("Making markers for ",a),t.append("defs").append("marker").attr("id",a+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",a+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},composition:(t,e,a)=>{t.append("defs").append("marker").attr("id",a+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",a+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},aggregation:(t,e,a)=>{t.append("defs").append("marker").attr("id",a+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",a+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},dependency:(t,e,a)=>{t.append("defs").append("marker").attr("id",a+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",a+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},lollipop:(t,e,a)=>{t.append("defs").append("marker").attr("id",a+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",a+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},point:(t,e,a)=>{t.append("marker").attr("id",a+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",6).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",a+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},circle:(t,e,a)=>{t.append("marker").attr("id",a+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",a+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},cross:(t,e,a)=>{t.append("marker").attr("id",a+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",a+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},barb:(t,e,a)=>{t.append("defs").append("marker").attr("id",a+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")}},l=(t,e,a,r)=>{e.forEach((e=>{s[e](t,a,r)}))};const d=(t,e,a,i)=>{let s=t||"";if("object"==typeof s&&(s=s[0]),(0,r.m)((0,r.c)().flowchart.htmlLabels)){s=s.replace(/\\n|\n/g,"<br />"),r.l.debug("vertexText"+s);let t=function(t){const e=(0,n.Ltv)(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),a=e.append("xhtml:div"),r=t.label,i=t.isNode?"nodeLabel":"edgeLabel";var s,l;return a.html('<span class="'+i+'" '+(t.labelStyle?'style="'+t.labelStyle+'"':"")+">"+r+"</span>"),s=a,(l=t.labelStyle)&&s.attr("style",l),a.style("display","inline-block"),a.style("white-space","nowrap"),a.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}({isNode:i,label:(0,r.M)(s).replace(/fa[blrs]?:fa-[\w-]+/g,(t=>`<i class='${t.replace(":"," ")}'></i>`)),labelStyle:e.replace("fill:","color:")});return t}{const t=document.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("style",e.replace("color:","fill:"));let r=[];r="string"==typeof s?s.split(/\\n|\n|<br\s*\/?>/gi):Array.isArray(s)?s:[];for(const e of r){const r=document.createElementNS("http://www.w3.org/2000/svg","tspan");r.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),r.setAttribute("dy","1em"),r.setAttribute("x","0"),a?r.setAttribute("class","title-row"):r.setAttribute("class","row"),r.textContent=e.trim(),t.appendChild(r)}return t}},o=async(t,e,a,s)=>{let l;const o=e.useHtmlLabels||(0,r.m)((0,r.c)().flowchart.htmlLabels);l=a||"node default";const h=t.insert("g").attr("class",l).attr("id",e.domId||e.id),c=h.insert("g").attr("class","label").attr("style",e.labelStyle);let y;y=void 0===e.labelText?"":"string"==typeof e.labelText?e.labelText:e.labelText[0];const p=c.node();let g;g="markdown"===e.labelType?(0,i.a)(c,(0,r.d)((0,r.M)(y),(0,r.c)()),{useHtmlLabels:o,width:e.width||(0,r.c)().flowchart.wrappingWidth,classes:"markdown-node-label"}):p.appendChild(d((0,r.d)((0,r.M)(y),(0,r.c)()),e.labelStyle,!1,s));let x=g.getBBox();const f=e.padding/2;if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=g.children[0],e=(0,n.Ltv)(g),a=t.getElementsByTagName("img");if(a){const t=""===y.replace(/<img[^>]*>/g,"").trim();await Promise.all([...a].map((e=>new Promise((a=>{function n(){if(e.style.display="flex",e.style.flexDirection="column",t){const t=(0,r.c)().fontSize?(0,r.c)().fontSize:window.getComputedStyle(document.body).fontSize,a=5,n=parseInt(t,10)*a+"px";e.style.minWidth=n,e.style.maxWidth=n}else e.style.width="100%";a(e)}setTimeout((()=>{e.complete&&n()})),e.addEventListener("error",n),e.addEventListener("load",n)})))))}x=t.getBoundingClientRect(),e.attr("width",x.width),e.attr("height",x.height)}return o?c.attr("transform","translate("+-x.width/2+", "+-x.height/2+")"):c.attr("transform","translate(0, "+-x.height/2+")"),e.centerLabel&&c.attr("transform","translate("+-x.width/2+", "+-x.height/2+")"),c.insert("rect",":first-child"),{shapeSvg:h,bbox:x,halfPadding:f,label:c}},h=(t,e)=>{const a=e.node().getBBox();t.width=a.width,t.height=a.height};function c(t,e,a,r){return t.insert("polygon",":first-child").attr("points",r.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+a/2+")")}function y(t,e,a,r){var n=t.x,i=t.y,s=n-r.x,l=i-r.y,d=Math.sqrt(e*e*l*l+a*a*s*s),o=Math.abs(e*a*s/d);r.x<n&&(o=-o);var h=Math.abs(e*a*l/d);return r.y<i&&(h=-h),{x:n+o,y:i+h}}function p(t,e,a,r){var n,i,s,l,d,o,h,c,y,p,x,f,u;if(n=e.y-t.y,s=t.x-e.x,d=e.x*t.y-t.x*e.y,y=n*a.x+s*a.y+d,p=n*r.x+s*r.y+d,!(0!==y&&0!==p&&g(y,p)||(i=r.y-a.y,l=a.x-r.x,o=r.x*a.y-a.x*r.y,h=i*t.x+l*t.y+o,c=i*e.x+l*e.y+o,0!==h&&0!==c&&g(h,c)||0==(x=n*l-i*s))))return f=Math.abs(x/2),{x:(u=s*o-l*d)<0?(u-f)/x:(u+f)/x,y:(u=i*d-n*o)<0?(u-f)/x:(u+f)/x}}function g(t,e){return t*e>0}const x=(t,e)=>{var a,r,n=t.x,i=t.y,s=e.x-n,l=e.y-i,d=t.width/2,o=t.height/2;return Math.abs(l)*d>Math.abs(s)*o?(l<0&&(o=-o),a=0===l?0:o*s/l,r=o):(s<0&&(d=-d),a=d,r=0===s?0:d*l/s),{x:n+a,y:i+r}},f={node:function(t,e){return t.intersect(e)},circle:function(t,e,a){return y(t,e,e,a)},ellipse:y,polygon:function(t,e,a){var r=t.x,n=t.y,i=[],s=Number.POSITIVE_INFINITY,l=Number.POSITIVE_INFINITY;"function"==typeof e.forEach?e.forEach((function(t){s=Math.min(s,t.x),l=Math.min(l,t.y)})):(s=Math.min(s,e.x),l=Math.min(l,e.y));for(var d=r-t.width/2-s,o=n-t.height/2-l,h=0;h<e.length;h++){var c=e[h],y=e[h<e.length-1?h+1:0],g=p(t,a,{x:d+c.x,y:o+c.y},{x:d+y.x,y:o+y.y});g&&i.push(g)}return i.length?(i.length>1&&i.sort((function(t,e){var r=t.x-a.x,n=t.y-a.y,i=Math.sqrt(r*r+n*n),s=e.x-a.x,l=e.y-a.y,d=Math.sqrt(s*s+l*l);return i<d?-1:i===d?0:1})),i[0]):t},rect:x},u=(t,e,a)=>{const r=(t=>{const e=new Set;for(const a of t)switch(a){case"x":e.add("right"),e.add("left");break;case"y":e.add("up"),e.add("down");break;default:e.add(a)}return e})(t),n=e.height+2*a.padding,i=n/2,s=e.width+2*i+a.padding,l=a.padding/2;return r.has("right")&&r.has("left")&&r.has("up")&&r.has("down")?[{x:0,y:0},{x:i,y:0},{x:s/2,y:2*l},{x:s-i,y:0},{x:s,y:0},{x:s,y:-n/3},{x:s+2*l,y:-n/2},{x:s,y:-2*n/3},{x:s,y:-n},{x:s-i,y:-n},{x:s/2,y:-n-2*l},{x:i,y:-n},{x:0,y:-n},{x:0,y:-2*n/3},{x:-2*l,y:-n/2},{x:0,y:-n/3}]:r.has("right")&&r.has("left")&&r.has("up")?[{x:i,y:0},{x:s-i,y:0},{x:s,y:-n/2},{x:s-i,y:-n},{x:i,y:-n},{x:0,y:-n/2}]:r.has("right")&&r.has("left")&&r.has("down")?[{x:0,y:0},{x:i,y:-n},{x:s-i,y:-n},{x:s,y:0}]:r.has("right")&&r.has("up")&&r.has("down")?[{x:0,y:0},{x:s,y:-i},{x:s,y:-n+i},{x:0,y:-n}]:r.has("left")&&r.has("up")&&r.has("down")?[{x:s,y:0},{x:0,y:-i},{x:0,y:-n+i},{x:s,y:-n}]:r.has("right")&&r.has("left")?[{x:i,y:0},{x:i,y:-l},{x:s-i,y:-l},{x:s-i,y:0},{x:s,y:-n/2},{x:s-i,y:-n},{x:s-i,y:-n+l},{x:i,y:-n+l},{x:i,y:-n},{x:0,y:-n/2}]:r.has("up")&&r.has("down")?[{x:s/2,y:0},{x:0,y:-l},{x:i,y:-l},{x:i,y:-n+l},{x:0,y:-n+l},{x:s/2,y:-n},{x:s,y:-n+l},{x:s-i,y:-n+l},{x:s-i,y:-l},{x:s,y:-l}]:r.has("right")&&r.has("up")?[{x:0,y:0},{x:s,y:-i},{x:0,y:-n}]:r.has("right")&&r.has("down")?[{x:0,y:0},{x:s,y:0},{x:0,y:-n}]:r.has("left")&&r.has("up")?[{x:s,y:0},{x:0,y:-i},{x:s,y:-n}]:r.has("left")&&r.has("down")?[{x:s,y:0},{x:0,y:0},{x:s,y:-n}]:r.has("right")?[{x:i,y:-l},{x:i,y:-l},{x:s-i,y:-l},{x:s-i,y:0},{x:s,y:-n/2},{x:s-i,y:-n},{x:s-i,y:-n+l},{x:i,y:-n+l},{x:i,y:-n+l}]:r.has("left")?[{x:i,y:0},{x:i,y:-l},{x:s-i,y:-l},{x:s-i,y:-n+l},{x:i,y:-n+l},{x:i,y:-n},{x:0,y:-n/2}]:r.has("up")?[{x:i,y:-l},{x:i,y:-n+l},{x:0,y:-n+l},{x:s/2,y:-n},{x:s,y:-n+l},{x:s-i,y:-n+l},{x:s-i,y:-l}]:r.has("down")?[{x:s/2,y:0},{x:0,y:-l},{x:i,y:-l},{x:i,y:-n+l},{x:s-i,y:-n+l},{x:s-i,y:-l},{x:s,y:-l}]:[{x:0,y:0}]},w=t=>t?" "+t:"",b=(t,e)=>`${e||"node default"}${w(t.classes)} ${w(t.class)}`,m=async(t,e)=>{const{shapeSvg:a,bbox:n}=await o(t,e,b(e,void 0),!0),i=n.width+e.padding+(n.height+e.padding),s=[{x:i/2,y:0},{x:i,y:-i/2},{x:i/2,y:-i},{x:0,y:-i/2}];r.l.info("Question main (Circle)");const l=c(a,i,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return r.l.warn("Intersect called"),f.polygon(e,s,t)},a};function k(t,e,a,n){const i=[],s=t=>{i.push(t,0)},l=t=>{i.push(0,t)};e.includes("t")?(r.l.debug("add top border"),s(a)):l(a),e.includes("r")?(r.l.debug("add right border"),s(n)):l(n),e.includes("b")?(r.l.debug("add bottom border"),s(a)):l(a),e.includes("l")?(r.l.debug("add left border"),s(n)):l(n),t.attr("stroke-dasharray",i.join(" "))}const v=(t,e,a)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id);let n=70,i=10;"LR"===a&&(n=10,i=70);const s=r.append("rect").attr("x",-1*n/2).attr("y",-1*i/2).attr("width",n).attr("height",i).attr("class","fork-join");return h(e,s),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(t){return f.rect(e,t)},r},L={rhombus:m,composite:async(t,e)=>{const{shapeSvg:a,bbox:n,halfPadding:i}=await o(t,e,"node "+e.classes,!0),s=a.insert("rect",":first-child"),l=e.positioned?e.width:n.width+e.padding,d=e.positioned?e.height:n.height+e.padding,c=e.positioned?-l/2:-n.width/2-i,y=e.positioned?-d/2:-n.height/2-i;if(s.attr("class","basic cluster composite label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",c).attr("y",y).attr("width",l).attr("height",d),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(k(s,e.props.borders,l,d),t.delete("borders")),t.forEach((t=>{r.l.warn(`Unknown node property ${t}`)}))}return h(e,s),e.intersect=function(t){return f.rect(e,t)},a},question:m,rect:async(t,e)=>{const{shapeSvg:a,bbox:n,halfPadding:i}=await o(t,e,"node "+e.classes+" "+e.class,!0),s=a.insert("rect",":first-child"),l=e.positioned?e.width:n.width+e.padding,d=e.positioned?e.height:n.height+e.padding,c=e.positioned?-l/2:-n.width/2-i,y=e.positioned?-d/2:-n.height/2-i;if(s.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",c).attr("y",y).attr("width",l).attr("height",d),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(k(s,e.props.borders,l,d),t.delete("borders")),t.forEach((t=>{r.l.warn(`Unknown node property ${t}`)}))}return h(e,s),e.intersect=function(t){return f.rect(e,t)},a},labelRect:async(t,e)=>{const{shapeSvg:a}=await o(t,e,"label",!0);r.l.trace("Classes = ",e.class);const n=a.insert("rect",":first-child");if(n.attr("width",0).attr("height",0),a.attr("class","label edgeLabel"),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(k(n,e.props.borders,0,0),t.delete("borders")),t.forEach((t=>{r.l.warn(`Unknown node property ${t}`)}))}return h(e,n),e.intersect=function(t){return f.rect(e,t)},a},rectWithTitle:(t,e)=>{let a;a=e.classes?"node "+e.classes:"node default";const i=t.insert("g").attr("class",a).attr("id",e.domId||e.id),s=i.insert("rect",":first-child"),l=i.insert("line"),o=i.insert("g").attr("class","label"),c=e.labelText.flat?e.labelText.flat():e.labelText;let y="";y="object"==typeof c?c[0]:c,r.l.info("Label text abc79",y,c,"object"==typeof c);const p=o.node().appendChild(d(y,e.labelStyle,!0,!0));let g={width:0,height:0};if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=p.children[0],e=(0,n.Ltv)(p);g=t.getBoundingClientRect(),e.attr("width",g.width),e.attr("height",g.height)}r.l.info("Text 2",c);const x=c.slice(1,c.length);let u=p.getBBox();const w=o.node().appendChild(d(x.join?x.join("<br/>"):x,e.labelStyle,!0,!0));if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=w.children[0],e=(0,n.Ltv)(w);g=t.getBoundingClientRect(),e.attr("width",g.width),e.attr("height",g.height)}const b=e.padding/2;return(0,n.Ltv)(w).attr("transform","translate( "+(g.width>u.width?0:(u.width-g.width)/2)+", "+(u.height+b+5)+")"),(0,n.Ltv)(p).attr("transform","translate( "+(g.width<u.width?0:-(u.width-g.width)/2)+", 0)"),g=o.node().getBBox(),o.attr("transform","translate("+-g.width/2+", "+(-g.height/2-b+3)+")"),s.attr("class","outer title-state").attr("x",-g.width/2-b).attr("y",-g.height/2-b).attr("width",g.width+e.padding).attr("height",g.height+e.padding),l.attr("class","divider").attr("x1",-g.width/2-b).attr("x2",g.width/2+b).attr("y1",-g.height/2-b+u.height+b).attr("y2",-g.height/2-b+u.height+b),h(e,s),e.intersect=function(t){return f.rect(e,t)},i},choice:(t,e)=>{const a=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),r=[{x:0,y:14},{x:14,y:0},{x:0,y:-14},{x:-14,y:0}];return a.insert("polygon",":first-child").attr("points",r.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),e.width=28,e.height=28,e.intersect=function(t){return f.circle(e,14,t)},a},circle:async(t,e)=>{const{shapeSvg:a,bbox:n,halfPadding:i}=await o(t,e,b(e,void 0),!0),s=a.insert("circle",":first-child");return s.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),r.l.info("Circle main"),h(e,s),e.intersect=function(t){return r.l.info("Circle intersect",e,n.width/2+i,t),f.circle(e,n.width/2+i,t)},a},doublecircle:async(t,e)=>{const{shapeSvg:a,bbox:n,halfPadding:i}=await o(t,e,b(e,void 0),!0),s=a.insert("g",":first-child"),l=s.insert("circle"),d=s.insert("circle");return s.attr("class",e.class),l.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i+5).attr("width",n.width+e.padding+10).attr("height",n.height+e.padding+10),d.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),r.l.info("DoubleCircle main"),h(e,l),e.intersect=function(t){return r.l.info("DoubleCircle intersect",e,n.width/2+i+5,t),f.circle(e,n.width/2+i+5,t)},a},stadium:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.height+e.padding,i=r.width+n/4+e.padding,s=a.insert("rect",":first-child").attr("style",e.style).attr("rx",n/2).attr("ry",n/2).attr("x",-i/2).attr("y",-n/2).attr("width",i).attr("height",n);return h(e,s),e.intersect=function(t){return f.rect(e,t)},a},hexagon:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.height+e.padding,i=n/4,s=r.width+2*i+e.padding,l=[{x:i,y:0},{x:s-i,y:0},{x:s,y:-n/2},{x:s-i,y:-n},{x:i,y:-n},{x:0,y:-n/2}],d=c(a,s,n,l);return d.attr("style",e.style),h(e,d),e.intersect=function(t){return f.polygon(e,l,t)},a},block_arrow:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,void 0,!0),n=r.height+2*e.padding,i=n/2,s=r.width+2*i+e.padding,l=u(e.directions,r,e),d=c(a,s,n,l);return d.attr("style",e.style),h(e,d),e.intersect=function(t){return f.polygon(e,l,t)},a},rect_left_inv_arrow:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:-i/2,y:0},{x:n,y:0},{x:n,y:-i},{x:-i/2,y:-i},{x:0,y:-i/2}];return c(a,n,i,s).attr("style",e.style),e.width=n+i,e.height=i,e.intersect=function(t){return f.polygon(e,s,t)},a},lean_right:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:-2*i/6,y:0},{x:n-i/6,y:0},{x:n+2*i/6,y:-i},{x:i/6,y:-i}],l=c(a,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return f.polygon(e,s,t)},a},lean_left:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:2*i/6,y:0},{x:n+i/6,y:0},{x:n-2*i/6,y:-i},{x:-i/6,y:-i}],l=c(a,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return f.polygon(e,s,t)},a},trapezoid:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:-2*i/6,y:0},{x:n+2*i/6,y:0},{x:n-i/6,y:-i},{x:i/6,y:-i}],l=c(a,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return f.polygon(e,s,t)},a},inv_trapezoid:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:i/6,y:0},{x:n-i/6,y:0},{x:n+2*i/6,y:-i},{x:-2*i/6,y:-i}],l=c(a,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return f.polygon(e,s,t)},a},rect_right_inv_arrow:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:0,y:0},{x:n+i/2,y:0},{x:n,y:-i/2},{x:n+i/2,y:-i},{x:0,y:-i}],l=c(a,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return f.polygon(e,s,t)},a},cylinder:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=n/2,s=i/(2.5+n/50),l=r.height+s+e.padding,d="M 0,"+s+" a "+i+","+s+" 0,0,0 "+n+" 0 a "+i+","+s+" 0,0,0 "+-n+" 0 l 0,"+l+" a "+i+","+s+" 0,0,0 "+n+" 0 l 0,"+-l,c=a.attr("label-offset-y",s).insert("path",":first-child").attr("style",e.style).attr("d",d).attr("transform","translate("+-n/2+","+-(l/2+s)+")");return h(e,c),e.intersect=function(t){const a=f.rect(e,t),r=a.x-e.x;if(0!=i&&(Math.abs(r)<e.width/2||Math.abs(r)==e.width/2&&Math.abs(a.y-e.y)>e.height/2-s)){let n=s*s*(1-r*r/(i*i));0!=n&&(n=Math.sqrt(n)),n=s-n,t.y-e.y>0&&(n=-n),a.y+=n}return a},a},start:(t,e)=>{const a=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),r=a.insert("circle",":first-child");return r.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),h(e,r),e.intersect=function(t){return f.circle(e,7,t)},a},end:(t,e)=>{const a=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),r=a.insert("circle",":first-child"),n=a.insert("circle",":first-child");return n.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),r.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),h(e,n),e.intersect=function(t){return f.circle(e,7,t)},a},note:async(t,e)=>{e.useHtmlLabels||(0,r.c)().flowchart.htmlLabels||(e.centerLabel=!0);const{shapeSvg:a,bbox:n,halfPadding:i}=await o(t,e,"node "+e.classes,!0);r.l.info("Classes = ",e.classes);const s=a.insert("rect",":first-child");return s.attr("rx",e.rx).attr("ry",e.ry).attr("x",-n.width/2-i).attr("y",-n.height/2-i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),h(e,s),e.intersect=function(t){return f.rect(e,t)},a},subroutine:async(t,e)=>{const{shapeSvg:a,bbox:r}=await o(t,e,b(e,void 0),!0),n=r.width+e.padding,i=r.height+e.padding,s=[{x:0,y:0},{x:n,y:0},{x:n,y:-i},{x:0,y:-i},{x:0,y:0},{x:-8,y:0},{x:n+8,y:0},{x:n+8,y:-i},{x:-8,y:-i},{x:-8,y:0}],l=c(a,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return f.polygon(e,s,t)},a},fork:v,join:v,class_box:(t,e)=>{const a=e.padding/2;let i;i=e.classes?"node "+e.classes:"node default";const s=t.insert("g").attr("class",i).attr("id",e.domId||e.id),l=s.insert("rect",":first-child"),o=s.insert("line"),c=s.insert("line");let y=0,p=4;const g=s.insert("g").attr("class","label");let x=0;const u=e.classData.annotations&&e.classData.annotations[0],w=e.classData.annotations[0]?"\xab"+e.classData.annotations[0]+"\xbb":"",b=g.node().appendChild(d(w,e.labelStyle,!0,!0));let m=b.getBBox();if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=b.children[0],e=(0,n.Ltv)(b);m=t.getBoundingClientRect(),e.attr("width",m.width),e.attr("height",m.height)}e.classData.annotations[0]&&(p+=m.height+4,y+=m.width);let k=e.classData.label;void 0!==e.classData.type&&""!==e.classData.type&&((0,r.c)().flowchart.htmlLabels?k+="<"+e.classData.type+">":k+="<"+e.classData.type+">");const v=g.node().appendChild(d(k,e.labelStyle,!0,!0));(0,n.Ltv)(v).attr("class","classTitle");let L=v.getBBox();if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=v.children[0],e=(0,n.Ltv)(v);L=t.getBoundingClientRect(),e.attr("width",L.width),e.attr("height",L.height)}p+=L.height+4,L.width>y&&(y=L.width);const S=[];e.classData.members.forEach((t=>{const a=t.getDisplayDetails();let i=a.displayText;(0,r.c)().flowchart.htmlLabels&&(i=i.replace(/</g,"<").replace(/>/g,">"));const s=g.node().appendChild(d(i,a.cssStyle?a.cssStyle:e.labelStyle,!0,!0));let l=s.getBBox();if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=s.children[0],e=(0,n.Ltv)(s);l=t.getBoundingClientRect(),e.attr("width",l.width),e.attr("height",l.height)}l.width>y&&(y=l.width),p+=l.height+4,S.push(s)})),p+=8;const M=[];if(e.classData.methods.forEach((t=>{const a=t.getDisplayDetails();let i=a.displayText;(0,r.c)().flowchart.htmlLabels&&(i=i.replace(/</g,"<").replace(/>/g,">"));const s=g.node().appendChild(d(i,a.cssStyle?a.cssStyle:e.labelStyle,!0,!0));let l=s.getBBox();if((0,r.m)((0,r.c)().flowchart.htmlLabels)){const t=s.children[0],e=(0,n.Ltv)(s);l=t.getBoundingClientRect(),e.attr("width",l.width),e.attr("height",l.height)}l.width>y&&(y=l.width),p+=l.height+4,M.push(s)})),p+=8,u){let t=(y-m.width)/2;(0,n.Ltv)(b).attr("transform","translate( "+(-1*y/2+t)+", "+-1*p/2+")"),x=m.height+4}let T=(y-L.width)/2;return(0,n.Ltv)(v).attr("transform","translate( "+(-1*y/2+T)+", "+(-1*p/2+x)+")"),x+=L.height+4,o.attr("class","divider").attr("x1",-y/2-a).attr("x2",y/2+a).attr("y1",-p/2-a+8+x).attr("y2",-p/2-a+8+x),x+=8,S.forEach((t=>{(0,n.Ltv)(t).attr("transform","translate( "+-y/2+", "+(-1*p/2+x+4)+")");const e=null==t?void 0:t.getBBox();x+=((null==e?void 0:e.height)??0)+4})),x+=8,c.attr("class","divider").attr("x1",-y/2-a).attr("x2",y/2+a).attr("y1",-p/2-a+8+x).attr("y2",-p/2-a+8+x),x+=8,M.forEach((t=>{(0,n.Ltv)(t).attr("transform","translate( "+-y/2+", "+(-1*p/2+x)+")");const e=null==t?void 0:t.getBBox();x+=((null==e?void 0:e.height)??0)+4})),l.attr("style",e.style).attr("class","outer title-state").attr("x",-y/2-a).attr("y",-p/2-a).attr("width",y+e.padding).attr("height",p+e.padding),h(e,l),e.intersect=function(t){return f.rect(e,t)},s}};let S={};const M=async(t,e,a)=>{let n,i;if(e.link){let s;"sandbox"===(0,r.c)().securityLevel?s="_top":e.linkTarget&&(s=e.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",e.link).attr("target",s),i=await L[e.shape](n,e,a)}else i=await L[e.shape](t,e,a),n=i;return e.tooltip&&i.attr("title",e.tooltip),e.class&&i.attr("class","node default "+e.class),n.attr("data-node","true"),n.attr("data-id",e.id),S[e.id]=n,e.haveCallback&&S[e.id].attr("class",S[e.id].attr("class")+" clickable"),n},T=(t,e)=>{S[e.id]=t},B=()=>{S={}},_=t=>{const e=S[t.id];r.l.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");const a=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+a-t.width/2)+", "+(t.y-t.height/2-8)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),a},C=({flowchart:t})=>{var e,a;const r=(null==(e=null==t?void 0:t.subGraphTitleMargin)?void 0:e.top)??0,n=(null==(a=null==t?void 0:t.subGraphTitleMargin)?void 0:a.bottom)??0;return{subGraphTitleTopMargin:r,subGraphTitleBottomMargin:n,subGraphTitleTotalMargin:r+n}},E={aggregation:18,extension:18,composition:18,dependency:6,lollipop:13.5,arrow_point:5.3};function $(t,e){if(void 0===t||void 0===e)return{angle:0,deltaX:0,deltaY:0};t=P(t),e=P(e);const[a,r]=[t.x,t.y],[n,i]=[e.x,e.y],s=n-a,l=i-r;return{angle:Math.atan(l/s),deltaX:s,deltaY:l}}const P=t=>Array.isArray(t)?{x:t[0],y:t[1]}:t,R=t=>({x:function(e,a,r){let n=0;if(0===a&&Object.hasOwn(E,t.arrowTypeStart)){const{angle:e,deltaX:a}=$(r[0],r[1]);n=E[t.arrowTypeStart]*Math.cos(e)*(a>=0?1:-1)}else if(a===r.length-1&&Object.hasOwn(E,t.arrowTypeEnd)){const{angle:e,deltaX:a}=$(r[r.length-1],r[r.length-2]);n=E[t.arrowTypeEnd]*Math.cos(e)*(a>=0?1:-1)}return P(e).x+n},y:function(e,a,r){let n=0;if(0===a&&Object.hasOwn(E,t.arrowTypeStart)){const{angle:e,deltaY:a}=$(r[0],r[1]);n=E[t.arrowTypeStart]*Math.abs(Math.sin(e))*(a>=0?1:-1)}else if(a===r.length-1&&Object.hasOwn(E,t.arrowTypeEnd)){const{angle:e,deltaY:a}=$(r[r.length-1],r[r.length-2]);n=E[t.arrowTypeEnd]*Math.abs(Math.sin(e))*(a>=0?1:-1)}return P(e).y+n}}),Y=(t,e,a,r,n)=>{e.arrowTypeStart&&W(t,"start",e.arrowTypeStart,a,r,n),e.arrowTypeEnd&&W(t,"end",e.arrowTypeEnd,a,r,n)},O={arrow_cross:"cross",arrow_point:"point",arrow_barb:"barb",arrow_circle:"circle",aggregation:"aggregation",extension:"extension",composition:"composition",dependency:"dependency",lollipop:"lollipop"},W=(t,e,a,n,i,s)=>{const l=O[a];if(!l)return void r.l.warn(`Unknown arrow type: ${a}`);const d="start"===e?"Start":"End";t.attr(`marker-${e}`,`url(${n}#${i}_${s}-${l}${d})`)};let X={},H={};const I=()=>{X={},H={}},j=(t,e)=>{const a=(0,r.m)((0,r.c)().flowchart.htmlLabels),s="markdown"===e.labelType?(0,i.a)(t,e.label,{style:e.labelStyle,useHtmlLabels:a,addSvgBackground:!0}):d(e.label,e.labelStyle),l=t.insert("g").attr("class","edgeLabel"),o=l.insert("g").attr("class","label");o.node().appendChild(s);let h,c=s.getBBox();if(a){const t=s.children[0],e=(0,n.Ltv)(s);c=t.getBoundingClientRect(),e.attr("width",c.width),e.attr("height",c.height)}if(o.attr("transform","translate("+-c.width/2+", "+-c.height/2+")"),X[e.id]=l,e.width=c.width,e.height=c.height,e.startLabelLeft){const a=d(e.startLabelLeft,e.labelStyle),r=t.insert("g").attr("class","edgeTerminals"),n=r.insert("g").attr("class","inner");h=n.node().appendChild(a);const i=a.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),H[e.id]||(H[e.id]={}),H[e.id].startLeft=r,D(h,e.startLabelLeft)}if(e.startLabelRight){const a=d(e.startLabelRight,e.labelStyle),r=t.insert("g").attr("class","edgeTerminals"),n=r.insert("g").attr("class","inner");h=r.node().appendChild(a),n.node().appendChild(a);const i=a.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),H[e.id]||(H[e.id]={}),H[e.id].startRight=r,D(h,e.startLabelRight)}if(e.endLabelLeft){const a=d(e.endLabelLeft,e.labelStyle),r=t.insert("g").attr("class","edgeTerminals"),n=r.insert("g").attr("class","inner");h=n.node().appendChild(a);const i=a.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),r.node().appendChild(a),H[e.id]||(H[e.id]={}),H[e.id].endLeft=r,D(h,e.endLabelLeft)}if(e.endLabelRight){const a=d(e.endLabelRight,e.labelStyle),r=t.insert("g").attr("class","edgeTerminals"),n=r.insert("g").attr("class","inner");h=n.node().appendChild(a);const i=a.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),r.node().appendChild(a),H[e.id]||(H[e.id]={}),H[e.id].endRight=r,D(h,e.endLabelRight)}return s};function D(t,e){(0,r.c)().flowchart.htmlLabels&&t&&(t.style.width=9*e.length+"px",t.style.height="12px")}const N=(t,e)=>{r.l.debug("Moving label abc88 ",t.id,t.label,X[t.id],e);let a=e.updatedPath?e.updatedPath:e.originalPath;const n=(0,r.c)(),{subGraphTitleTotalMargin:i}=C(n);if(t.label){const n=X[t.id];let s=t.x,l=t.y;if(a){const n=r.u.calcLabelPosition(a);r.l.debug("Moving label "+t.label+" from (",s,",",l,") to (",n.x,",",n.y,") abc88"),e.updatedPath&&(s=n.x,l=n.y)}n.attr("transform",`translate(${s}, ${l+i/2})`)}if(t.startLabelLeft){const e=H[t.id].startLeft;let n=t.x,i=t.y;if(a){const e=r.u.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",a);n=e.x,i=e.y}e.attr("transform",`translate(${n}, ${i})`)}if(t.startLabelRight){const e=H[t.id].startRight;let n=t.x,i=t.y;if(a){const e=r.u.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",a);n=e.x,i=e.y}e.attr("transform",`translate(${n}, ${i})`)}if(t.endLabelLeft){const e=H[t.id].endLeft;let n=t.x,i=t.y;if(a){const e=r.u.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",a);n=e.x,i=e.y}e.attr("transform",`translate(${n}, ${i})`)}if(t.endLabelRight){const e=H[t.id].endRight;let n=t.x,i=t.y;if(a){const e=r.u.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",a);n=e.x,i=e.y}e.attr("transform",`translate(${n}, ${i})`)}},U=(t,e)=>{r.l.debug("abc88 cutPathAtIntersect",t,e);let a=[],n=t[0],i=!1;return t.forEach((t=>{if(((t,e)=>{const a=t.x,r=t.y,n=Math.abs(e.x-a),i=Math.abs(e.y-r),s=t.width/2,l=t.height/2;return n>=s||i>=l})(e,t)||i)n=t,i||a.push(t);else{const s=((t,e,a)=>{r.l.debug(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(e)}\n insidePoint : ${JSON.stringify(a)}\n node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);const n=t.x,i=t.y,s=Math.abs(n-a.x),l=t.width/2;let d=a.x<e.x?l-s:l+s;const o=t.height/2,h=Math.abs(e.y-a.y),c=Math.abs(e.x-a.x);if(Math.abs(i-e.y)*l>Math.abs(n-e.x)*o){let t=a.y<e.y?e.y-o-i:i-o-e.y;d=c*t/h;const n={x:a.x<e.x?a.x+d:a.x-c+d,y:a.y<e.y?a.y+h-t:a.y-h+t};return 0===d&&(n.x=e.x,n.y=e.y),0===c&&(n.x=e.x),0===h&&(n.y=e.y),r.l.debug(`abc89 topp/bott calc, Q ${h}, q ${t}, R ${c}, r ${d}`,n),n}{d=a.x<e.x?e.x-l-n:n-l-e.x;let t=h*d/c,i=a.x<e.x?a.x+c-d:a.x-c+d,s=a.y<e.y?a.y+t:a.y-t;return r.l.debug(`sides calc abc89, Q ${h}, q ${t}, R ${c}, r ${d}`,{_x:i,_y:s}),0===d&&(i=e.x,s=e.y),0===c&&(i=e.x),0===h&&(s=e.y),{x:i,y:s}}})(e,n,t);let l=!1;a.forEach((t=>{l=l||t.x===s.x&&t.y===s.y})),a.some((t=>t.x===s.x&&t.y===s.y))||a.push(s),i=!0}})),a},A=function(t,e,a,i,s,l,d){let o=a.points;r.l.debug("abc88 InsertEdge: edge=",a,"e=",e);let h=!1;const c=l.node(e.v);var y=l.node(e.w);(null==y?void 0:y.intersect)&&(null==c?void 0:c.intersect)&&(o=o.slice(1,a.points.length-1),o.unshift(c.intersect(o[0])),o.push(y.intersect(o[o.length-1]))),a.toCluster&&(r.l.debug("to cluster abc88",i[a.toCluster]),o=U(a.points,i[a.toCluster].node),h=!0),a.fromCluster&&(r.l.debug("from cluster abc88",i[a.fromCluster]),o=U(o.reverse(),i[a.fromCluster].node).reverse(),h=!0);const p=o.filter((t=>!Number.isNaN(t.y)));let g=n.qrM;!a.curve||"graph"!==s&&"flowchart"!==s||(g=a.curve);const{x:x,y:f}=R(a),u=(0,n.n8j)().x(x).y(f).curve(g);let w;switch(a.thickness){case"normal":w="edge-thickness-normal";break;case"thick":case"invisible":w="edge-thickness-thick";break;default:w=""}switch(a.pattern){case"solid":w+=" edge-pattern-solid";break;case"dotted":w+=" edge-pattern-dotted";break;case"dashed":w+=" edge-pattern-dashed"}const b=t.append("path").attr("d",u(p)).attr("id",a.id).attr("class"," "+w+(a.classes?" "+a.classes:"")).attr("style",a.style);let m="";((0,r.c)().flowchart.arrowMarkerAbsolute||(0,r.c)().state.arrowMarkerAbsolute)&&(m=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,m=m.replace(/\(/g,"\\("),m=m.replace(/\)/g,"\\)")),Y(b,a,m,d,s);let k={};return h&&(k.updatedPath=o),k.originalPath=a.points,k}}}]); \ No newline at end of file diff --git a/assets/js/88684b71.5a5acb4c.js b/assets/js/88684b71.5a5acb4c.js new file mode 100644 index 0000000000..103dcff903 --- /dev/null +++ b/assets/js/88684b71.5a5acb4c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2151],{10665:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>c});var s=a(74848),r=a(28453);const o={sidebar_label:"Flavor Manager",sidebar_position:51},i="Flavor Manager",t={id:"iaas/components/flavor-manager",title:"Flavor Manager",description:"Overview",source:"@site/docs/02-iaas/components/flavor-manager.md",sourceDirName:"02-iaas/components",slug:"/iaas/components/flavor-manager",permalink:"/docs/iaas/components/flavor-manager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/flavor-manager.md",tags:[],version:"current",sidebarPosition:51,frontMatter:{sidebar_label:"Flavor Manager",sidebar_position:51},sidebar:"docs",previous:{title:"Automated updates",permalink:"/docs/iaas/components/image-manager/update"},next:{title:"Container Layer Introduction",permalink:"/docs/container/"}},d={},c=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Usage",id:"usage",level:2},{value:"Definitions",id:"definitions",level:2},{value:"Name parser and generator",id:"name-parser-and-generator",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"flavor-manager",children:"Flavor Manager"}),"\n",(0,s.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(n.p,{children:["The OpenStack Flavor Manager manages the creation, modification, and removal of flavors.\nIt operates as a facilitator that orchestrates compute flavors in alignment\nwith the standard ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS-0100: Flavor Naming"}),"\nby utilizing YAML files provided by the SCS project."]}),"\n",(0,s.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,s.jsxs)(n.p,{children:["The OpenStack Flavor Manager can be used via the OSISM CLI. This is the preferred way to use it.\nNo installation is then required. It is used via ",(0,s.jsx)(n.code,{children:"osism manage flavors"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["For use independent of OSISM install the ",(0,s.jsx)(n.code,{children:"openstack-flavor-manager"})," package with pip. It is likely\nthat additional dependencies such as ",(0,s.jsx)(n.code,{children:"pkg-config"})," or ",(0,s.jsx)(n.code,{children:"libssl-dev"})," must be installed in advance."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ pip install openstack-flavor-manager\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Or clone the repository ",(0,s.jsx)(n.a,{href:"https://github.com/osism/openstack-flavor-manager",children:"osism/openstack-flavor-manager"}),"\nand use the OpenStack Flavor Manager from source with tox."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ tox -- --help\n"})}),"\n",(0,s.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,s.jsxs)(n.p,{children:["There must be a ",(0,s.jsx)(n.code,{children:"clouds.yml"})," and a ",(0,s.jsx)(n.code,{children:"secure.yml"})," file in the directory where the OpenStack Flavor Manager\nwill be executed. When using the OSISM CLI, the files are expected in ",(0,s.jsx)(n.code,{children:"environments/openstack"}),"\nin your configuration repository."]}),"\n",(0,s.jsxs)(n.p,{children:["The cloud profile to be used can be specified via the optional ",(0,s.jsx)(n.code,{children:"--cloud"})," parameter.\nBy default the cloud profile with the name ",(0,s.jsx)(n.code,{children:"admin"})," is used. It must be possible to create and delete\nflavors with the used cloud credentials."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ openstack-flavor-manager --help\n\n Usage: openstack-flavor-manager [OPTIONS]\n\n\u256d\u2500 Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 --name TEXT Name of flavor definitions. [default: scs] \u2502\n\u2502 --debug Enable debug logging. \u2502\n\u2502 --cloud TEXT Cloud name in clouds.yaml. [default: admin] \u2502\n\u2502 --recommended Create recommended flavors. \u2502\n\u2502 --help Show this message and exit. \u2502\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n"})}),"\n",(0,s.jsxs)(n.p,{children:["To create the mandatory flavors by the ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS-0100: Flavor Naming"}),"\nstandard, you run:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ openstack-flavor-manager\n"})}),"\n",(0,s.jsx)(n.p,{children:"To create the recommended flavors by the SCS Flavor Naming Standard, you run:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ openstack-flavor-manager --recommended\n"})}),"\n",(0,s.jsx)(n.p,{children:"The output should look like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"2023-09-20 13:03:14 | INFO | Flavor SCS-1V-4 created\n2023-09-20 13:03:14 | INFO | Flavor SCS-2V-8 created\n2023-09-20 13:03:14 | INFO | Flavor SCS-4V-16 created\n2023-09-20 13:03:14 | INFO | Flavor SCS-8V-32 created\n...\n"})}),"\n",(0,s.jsx)(n.p,{children:"All recommended flavors are now be available in your OpenStack environment.\nCheck yourself by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ openstack --os-cloud admin flavor list\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ openstack --os-cloud admin flavor show SCS-2V-4-20s\n+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+\n| Field | Value |\n+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+\n| OS-FLV-DISABLED:disabled | False |\n| OS-FLV-EXT-DATA:ephemeral | 0 |\n| access_project_ids | None |\n| description | None |\n| disk | 20 |\n| id | 652e3a6c-330e-4ee3-922b-b49c3c093062 |\n| name | SCS-2V-4-20s |\n| os-flavor-access:is_public | True |\n| properties | hw_rng:allowed='true', scs:cpu-type='shared-core', scs:disk0-type='ssd', scs:name-v1='SCS-2V:4:20s', scs:name-v2='SCS-2V-4-20s' |\n| ram | 4096 |\n| rxtx_factor | 1.0 |\n| swap | 0 |\n| vcpus | 2 |\n+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+\n"})}),"\n",(0,s.jsx)(n.h2,{id:"definitions",children:"Definitions"}),"\n",(0,s.jsxs)(n.p,{children:["There are two flavor definitions available by default. One for\n",(0,s.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/iaas/SCS-Spec.MandatoryFlavors.verbose.yaml",children:"SCS"}),"\nand one for ",(0,s.jsx)(n.a,{href:"https://raw.githubusercontent.com/osism/openstack-flavor-manager/main/flavors.yaml",children:"OSISM"}),".\nEach definition has its own set of mandatory and recommended flavors. The definition of OSISM contains\nall definitions of SCS as well as some others."]}),"\n",(0,s.jsxs)(n.p,{children:["To run the OpenStack Flavor Manager with a specific definition, either ",(0,s.jsx)(n.code,{children:"scs"})," or ",(0,s.jsx)(n.code,{children:"osism"}),",\nuse the optional ",(0,s.jsx)(n.code,{children:"--name"})," parameter. By default the ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/standards/iaas/scs-0100",children:"SCS-0100: Flavor Naming"}),"\nstandard definition will be used."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ openstack-flavor-manager --name osism\n"})}),"\n",(0,s.jsx)(n.h2,{id:"name-parser-and-generator",children:"Name parser and generator"}),"\n",(0,s.jsxs)(n.p,{children:["A generator and parser for flavor names according to the SCS standard is available on\n",(0,s.jsx)(n.a,{href:"https://flavors.scs.community",children:"flavors.scs.community"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The flavor name ",(0,s.jsx)(n.code,{children:"SCS-2V-4-20s"})," is inserted in field ",(0,s.jsx)(n.code,{children:"Flavor name"}),":"]}),"\n",(0,s.jsx)("img",{src:a(77215).A,width:"50%"}),"\n",(0,s.jsxs)(n.p,{children:["The flavor ",(0,s.jsx)(n.code,{children:"SCS-2V-4-20s"})," translated is\n",(0,s.jsx)(n.code,{children:"2 generic x86-64 vCPUs with 4.0 GiB RAM and SSD 20GB root volume"}),":"]}),"\n",(0,s.jsx)("img",{src:a(91940).A,width:"50%"})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},77215:(e,n,a)=>{a.d(n,{A:()=>s});const s=a.p+"assets/images/flavors-1-bd8d085759b264b3e58020d1390803fd.png"},91940:(e,n,a)=>{a.d(n,{A:()=>s});const s=a.p+"assets/images/flavors-2-d9a87ab2a63ed62ace4303facc069b8b.png"},28453:(e,n,a)=>{a.d(n,{R:()=>i,x:()=>t});var s=a(96540);const r={},o=s.createContext(r);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/88f37d1b.5268da7b.js b/assets/js/88f37d1b.5268da7b.js new file mode 100644 index 0000000000..a49670142c --- /dev/null +++ b/assets/js/88f37d1b.5268da7b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6734],{87999:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>d,contentTitle:()=>s,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>r});var t=n(74848),i=n(28453);const c={},s="Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)",a={id:"iam/intra-SCS-federation-setup-description-for-osism-doc-operations",title:"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)",description:"The followig section is a reasonably detailed hands on description of how",source:"@site/docs/05-iam/intra-SCS-federation-setup-description-for-osism-doc-operations.md",sourceDirName:"05-iam",slug:"/iam/intra-SCS-federation-setup-description-for-osism-doc-operations",permalink:"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/05-iam/intra-SCS-federation-setup-description-for-osism-doc-operations.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Example setup configuration in SCS deployment explained",permalink:"/docs/iam/SCS-example-setup-configuration-description"},next:{title:"Releases",permalink:"/docs/category/releases"}},d={},r=[{value:"Detailed tutorial on how to configure Federation (OpenID Connect) between two Keycloak instances in two separate SCS domains",id:"detailed-tutorial-on-how-to-configure-federation-openid-connect-between-two-keycloak-instances-in-two-separate-scs-domains",level:2}];function l(e){const o={code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.h1,{id:"proposal-for-documentation-for-keycloak-to-keycloak-federation-websso",children:"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)"}),"\n",(0,t.jsxs)(o.p,{children:["The followig section is a reasonably detailed hands on description of how\nto configure a federation between two separate SCS compliant domains by means\nof Keycloak ",(0,t.jsx)(o.code,{children:"Identity Brokering"}),". If we decide to use Keycloak as a component\nto allow self service by tenants, then this documentation may be a useful addition\nto some tenant facing documentation (or for the SCS operators too)."]}),"\n",(0,t.jsx)(o.p,{children:"OTOH one could probably also script pretty much everything of this to allow\ntenants to use a CLI tool to automate the setup. For that purpose the documentation\nmay be useful to guide the implementation of such a scripted solution."}),"\n",(0,t.jsx)(o.h2,{id:"detailed-tutorial-on-how-to-configure-federation-openid-connect-between-two-keycloak-instances-in-two-separate-scs-domains",children:"Detailed tutorial on how to configure Federation (OpenID Connect) between two Keycloak instances in two separate SCS domains"}),"\n",(0,t.jsxs)(o.p,{children:['Assume you have two CSPs using SCS. The first one wants to grant access to users of the other.\nSo let\'s call the first domain "resource domain" and the second one "accounts domain".\nBoth domains need to agree upon a name for the "OIDC RP" (which Keycloak calls ',(0,t.jsx)(o.code,{children:"Clients"}),').\nThe Keycloak in the "resource domain" will be the OIDC RP and the Keycloak in the "accounts domain" will be the OIDC OP.\nAssuming the "resource domain" is called ',(0,t.jsx)(o.code,{children:"foo"}),' and the "accounts domain" is called bar, the name for the "OIDC RP" could be ',(0,t.jsx)(o.code,{children:"oidc-rp-foo"}),"."]}),"\n",(0,t.jsxs)(o.ol,{children:["\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:["In the accounts domain (",(0,t.jsx)(o.code,{children:"bar"}),") open Keycloak realm ",(0,t.jsx)(o.code,{children:"osism"}),", click on ",(0,t.jsx)(o.code,{children:"Clients"})," in the sidebar and click on ",(0,t.jsx)(o.code,{children:"Create client"}),".\nLeave the client type as ",(0,t.jsx)(o.code,{children:"OpenID Connect"})," and enter the ",(0,t.jsx)(o.code,{children:"Client ID"}),", e.g. ",(0,t.jsx)(o.code,{children:"oidc-rp-foo"}),".\nTurn on ",(0,t.jsx)(o.code,{children:"Client authentication"})," for it and click ",(0,t.jsx)(o.code,{children:"Save"}),"."]}),"\n",(0,t.jsxs)(o.p,{children:["On the ",(0,t.jsx)(o.code,{children:"Client details"})," page open the tab ",(0,t.jsx)(o.code,{children:"Credentials"})," and copy the ",(0,t.jsx)(o.code,{children:"Client secret"}),'. Communicate this to the operato of the "resource domain" ',(0,t.jsx)(o.code,{children:"foo"})," via a secure channel."]}),"\n"]}),"\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:["In the resource domain (",(0,t.jsx)(o.code,{children:"foo"}),") open Keycloak realm ",(0,t.jsx)(o.code,{children:"osism"}),", click on ",(0,t.jsx)(o.code,{children:"Identity providers"}),"\nand create a new provider definition of type ",(0,t.jsx)(o.code,{children:"OpenID Connect v1.0"}),". As ",(0,t.jsx)(o.code,{children:"Alias"})," choose a name,\ne.g. ",(0,t.jsx)(o.code,{children:"oidc-op-bar"}),". Don't copy the ",(0,t.jsx)(o.code,{children:"Redirect URI"})," given at the top yet, because is will change depending\non the chosen ",(0,t.jsx)(o.code,{children:"Alias"}),". Instead, scroll down to the mandatory field ",(0,t.jsx)(o.code,{children:"Discovery endpoint"})," and paste\nthe OpenID Connect metadata URL of the KEycloak realm ",(0,t.jsx)(o.code,{children:"osism"}),' in the "accounts domain" (',(0,t.jsx)(o.code,{children:"bar"}),').\nThe operator of the "accounts domain" (',(0,t.jsx)(o.code,{children:"bar"}),") may easily copy that URL from the ",(0,t.jsx)(o.code,{children:"Realm Settins"})," in the\nsidebar of his Keycloak instance, where the ",(0,t.jsx)(o.code,{children:"Endpoints"})," are listed on the bottom of that form.\nThe URL may have the format ",(0,t.jsx)(o.code,{children:"https://bar.com/auth/realms/osism/.well-known/openid-configuration"}),".\nOnce you leave that input field, Keycloak will attempt to fetch the metadata and extract the required\ndetails about protocol enspoints from the retrieved document. If this shows an error, it will give you\nan HTTP status code. If this shows an error code of 500, then this may be caused by a failure in\ncertificate verification. In that case you may want to check the output of ",(0,t.jsx)(o.code,{children:"docker logs keycloak"})," for\njava stack traces. If you find any, the top of those stack traces may indicate what kind of problem\noccurred to the java code. From here we will assume that the emtadata URL could be fecthed without\nany issues."]}),"\n",(0,t.jsxs)(o.p,{children:["Now, go to the bottom of that form and insert tjhe ",(0,t.jsx)(o.code,{children:"Client ID"})," (",(0,t.jsx)(o.code,{children:"oidc-rp-foo"}),") and the\n",(0,t.jsx)(o.code,{children:"Client secret"}),' that was provided by the operator of the "accounts domain" (',(0,t.jsx)(o.code,{children:"bar"}),").\nFinally click on ",(0,t.jsx)(o.code,{children:"Add"}),". From the ",(0,t.jsx)(o.code,{children:"Provider Details"})," page on the top for the ",(0,t.jsx)(o.code,{children:"Settings"})," tab copy the value of the\n",(0,t.jsx)(o.code,{children:"Redirect URI"}),' and communicate it back to the operator of the "accounts domain" (',(0,t.jsx)(o.code,{children:"bar"}),")."]}),"\n"]}),"\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:["In the accounts domain (",(0,t.jsx)(o.code,{children:"bar"}),") open Keycloak realm ",(0,t.jsx)(o.code,{children:"osism"}),", click on ",(0,t.jsx)(o.code,{children:"Clients"})," in the sidebar and click\non the name of the OIDC RP clinent that you created for domain ",(0,t.jsx)(o.code,{children:"foo"})," (e.g. ",(0,t.jsx)(o.code,{children:"oidc-rp-foo"}),").\nOn the ",(0,t.jsx)(o.code,{children:"Client details"})," page on the tab ",(0,t.jsx)(o.code,{children:"Settings"})," fill in the field ",(0,t.jsx)(o.code,{children:"Valid redirect URIs"})," with the value\nobtained from the resource domain (",(0,t.jsx)(o.code,{children:"foo"}),"), which should look similar to\n",(0,t.jsx)(o.code,{children:"https://foo.com/auth/realms/osism/broker/oidc-op-bar/endpoint"}),". Additionally the\n",(0,t.jsx)(o.code,{children:"Valid post logout redirect URIs"})," need to be set to something like ",(0,t.jsx)(o.code,{children:"https://foo.com/auth/realms/osism/*"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:['To test federated login in the "resource domain" (',(0,t.jsx)(o.code,{children:"foo"}),") open the URL of the Keycloak admin console for\nthe realm ",(0,t.jsx)(o.code,{children:"osism"}),": ",(0,t.jsx)(o.code,{children:"https://foo.com/auth/admin/osism/console"})," (or ",(0,t.jsx)(o.code,{children:"https://foo.com/auth/realms/osism/protocol/openid-connect/auth?client_id=security-admin-console"}),").\nIgnore the top section of the login form titled\n",(0,t.jsx)(o.code,{children:"Sign in to your account"})," and choose one of the OIDC OP federation choises below the line ",(0,t.jsx)(o.code,{children:"Or sign in with"}),".\nIn this example it would be ",(0,t.jsx)(o.code,{children:"oidc-op-bar"}),'. This should redirect your browser to the authentication endpoint\nof the "accounts domain" (',(0,t.jsx)(o.code,{children:"https://bar.com/auth/realms/osism/protocol/openid-connect/auth?scope=openid&..."}),')\nwhere you should be able to log in with credentials that are valid in the "accounts domain" (',(0,t.jsx)(o.code,{children:"bar"}),').\nAfter successull authentication your broser should be redirected to admin console of the "resource domain",\nwhich may offer you a "first login flow" form where you can choose a username, email, firstname and lastname.\nThe details depend on the ',(0,t.jsx)(o.code,{children:"Mappers"})," that have been configured for the Identity Provider ",(0,t.jsx)(o.code,{children:"oidc-op-bar"}),".\nAfter that you will be presented with a Keycloak themed page with the error message ",(0,t.jsx)(o.code,{children:"Request failed with status code 403"}),",\nwhich is normal because the test account is not authorized to access any elements of the Keycloak admin console."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:o}={...(0,i.R)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,o,n)=>{n.d(o,{R:()=>s,x:()=>a});var t=n(96540);const i={},c=t.createContext(i);function s(e){const o=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function a(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(c.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/89176cae.79fc0195.js b/assets/js/89176cae.79fc0195.js new file mode 100644 index 0000000000..332292da7d --- /dev/null +++ b/assets/js/89176cae.79fc0195.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5673],{96169:(t,n,e)=>{e.r(n),e.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>d,metadata:()=>a,toc:()=>i});var s=e(74848),r=e(28453);const d={},o="Standards",a={id:"standards/index",title:"Standards",description:"TODO",source:"@site/docs/07-standards/index.md",sourceDirName:"07-standards",slug:"/standards/",permalink:"/docs/standards/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/07-standards/index.md",tags:[],version:"current",frontMatter:{}},c={},i=[];function u(t){const n={h1:"h1",p:"p",...(0,r.R)(),...t.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"standards",children:"Standards"}),"\n",(0,s.jsx)(n.p,{children:"TODO"})]})}function l(t={}){const{wrapper:n}={...(0,r.R)(),...t.components};return n?(0,s.jsx)(n,{...t,children:(0,s.jsx)(u,{...t})}):u(t)}},28453:(t,n,e)=>{e.d(n,{R:()=>o,x:()=>a});var s=e(96540);const r={},d=s.createContext(r);function o(t){const n=s.useContext(d);return s.useMemo((function(){return"function"==typeof t?t(n):{...n,...t}}),[n,t])}function a(t){let n;return n=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:o(t.components),s.createElement(d.Provider,{value:n},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/8947.26a7a172.js b/assets/js/8947.26a7a172.js new file mode 100644 index 0000000000..333d7b3eb3 --- /dev/null +++ b/assets/js/8947.26a7a172.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8947],{18947:(t,i,e)=>{e.d(i,{diagram:()=>F});var s=e(76257),n=e(45829),a=e(26312),h=(e(74353),e(16750),e(42838),function(){var t=function(t,i,e,s){for(e=e||{},s=t.length;s--;e[t[s]]=i);return e},i=[1,10,12,14,16,18,19,21,23],e=[2,6],s=[1,3],n=[1,5],a=[1,6],h=[1,7],o=[1,5,10,12,14,16,18,19,21,23,34,35,36],r=[1,25],l=[1,26],c=[1,28],g=[1,29],u=[1,30],x=[1,31],d=[1,32],p=[1,33],f=[1,34],y=[1,35],m=[1,36],b=[1,37],A=[1,43],w=[1,42],S=[1,47],C=[1,50],k=[1,10,12,14,16,18,19,21,23,34,35,36],_=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],T=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],R=[1,64],D={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:function(t,i,e,s,n,a,h){var o=a.length-1;switch(n){case 5:s.setOrientation(a[o]);break;case 9:s.setDiagramTitle(a[o].text.trim());break;case 12:s.setLineData({text:"",type:"text"},a[o]);break;case 13:s.setLineData(a[o-1],a[o]);break;case 14:s.setBarData({text:"",type:"text"},a[o]);break;case 15:s.setBarData(a[o-1],a[o]);break;case 16:this.$=a[o].trim(),s.setAccTitle(this.$);break;case 17:case 18:this.$=a[o].trim(),s.setAccDescription(this.$);break;case 19:case 27:this.$=a[o-1];break;case 20:this.$=[Number(a[o-2]),...a[o]];break;case 21:this.$=[Number(a[o])];break;case 22:s.setXAxisTitle(a[o]);break;case 23:s.setXAxisTitle(a[o-1]);break;case 24:s.setXAxisTitle({type:"text",text:""});break;case 25:s.setXAxisBand(a[o]);break;case 26:s.setXAxisRangeData(Number(a[o-2]),Number(a[o]));break;case 28:this.$=[a[o-2],...a[o]];break;case 29:this.$=[a[o]];break;case 30:s.setYAxisTitle(a[o]);break;case 31:s.setYAxisTitle(a[o-1]);break;case 32:s.setYAxisTitle({type:"text",text:""});break;case 33:s.setYAxisRangeData(Number(a[o-2]),Number(a[o]));break;case 37:case 38:this.$={text:a[o],type:"text"};break;case 39:this.$={text:a[o],type:"markdown"};break;case 40:this.$=a[o];break;case 41:this.$=a[o-1]+""+a[o]}},table:[t(i,e,{3:1,4:2,7:4,5:s,34:n,35:a,36:h}),{1:[3]},t(i,e,{4:2,7:4,3:8,5:s,34:n,35:a,36:h}),t(i,e,{4:2,7:4,6:9,3:10,5:s,8:[1,11],34:n,35:a,36:h}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},t(o,[2,34]),t(o,[2,35]),t(o,[2,36]),{1:[2,1]},t(i,e,{4:2,7:4,3:21,5:s,34:n,35:a,36:h}),{1:[2,3]},t(o,[2,5]),t(i,[2,7],{4:22,34:n,35:a,36:h}),{11:23,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{11:39,13:38,24:A,27:w,29:40,30:41,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{11:45,15:44,27:S,33:46,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{11:49,17:48,24:C,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{11:52,17:51,24:C,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{20:[1,53]},{22:[1,54]},t(k,[2,18]),{1:[2,2]},t(k,[2,8]),t(k,[2,9]),t(_,[2,37],{40:55,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b}),t(_,[2,38]),t(_,[2,39]),t(T,[2,40]),t(T,[2,42]),t(T,[2,43]),t(T,[2,44]),t(T,[2,45]),t(T,[2,46]),t(T,[2,47]),t(T,[2,48]),t(T,[2,49]),t(T,[2,50]),t(T,[2,51]),t(k,[2,10]),t(k,[2,22],{30:41,29:56,24:A,27:w}),t(k,[2,24]),t(k,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},t(k,[2,11]),t(k,[2,30],{33:60,27:S}),t(k,[2,32]),{31:[1,61]},t(k,[2,12]),{17:62,24:C},{25:63,27:R},t(k,[2,14]),{17:65,24:C},t(k,[2,16]),t(k,[2,17]),t(T,[2,41]),t(k,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},t(k,[2,31]),{27:[1,69]},t(k,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},t(k,[2,15]),t(k,[2,26]),t(k,[2,27]),{11:59,32:72,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},t(k,[2,33]),t(k,[2,19]),{25:73,27:R},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:function(t,i){if(!i.recoverable){var e=new Error(t);throw e.hash=i,e}this.trace(t)},parse:function(t){var i=this,e=[0],s=[],n=[null],a=[],h=this.table,o="",r=0,l=0,c=a.slice.call(arguments,1),g=Object.create(this.lexer),u={yy:{}};for(var x in this.yy)Object.prototype.hasOwnProperty.call(this.yy,x)&&(u.yy[x]=this.yy[x]);g.setInput(t,u.yy),u.yy.lexer=g,u.yy.parser=this,void 0===g.yylloc&&(g.yylloc={});var d=g.yylloc;a.push(d);var p=g.options&&g.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,y,m,b,A,w,S,C,k,_={};;){if(y=e[e.length-1],this.defaultActions[y]?m=this.defaultActions[y]:(null==f&&(k=void 0,"number"!=typeof(k=s.pop()||g.lex()||1)&&(k instanceof Array&&(k=(s=k).pop()),k=i.symbols_[k]||k),f=k),m=h[y]&&h[y][f]),void 0===m||!m.length||!m[0]){var T="";for(A in C=[],h[y])this.terminals_[A]&&A>2&&C.push("'"+this.terminals_[A]+"'");T=g.showPosition?"Parse error on line "+(r+1)+":\n"+g.showPosition()+"\nExpecting "+C.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(r+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(T,{text:g.match,token:this.terminals_[f]||f,line:g.yylineno,loc:d,expected:C})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+y+", token: "+f);switch(m[0]){case 1:e.push(f),n.push(g.yytext),a.push(g.yylloc),e.push(m[1]),f=null,l=g.yyleng,o=g.yytext,r=g.yylineno,d=g.yylloc;break;case 2:if(w=this.productions_[m[1]][1],_.$=n[n.length-w],_._$={first_line:a[a.length-(w||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(w||1)].first_column,last_column:a[a.length-1].last_column},p&&(_._$.range=[a[a.length-(w||1)].range[0],a[a.length-1].range[1]]),void 0!==(b=this.performAction.apply(_,[o,l,r,u.yy,m[1],n,a].concat(c))))return b;w&&(e=e.slice(0,-1*w*2),n=n.slice(0,-1*w),a=a.slice(0,-1*w)),e.push(this.productions_[m[1]][0]),n.push(_.$),a.push(_._$),S=h[e[e.length-2]][e[e.length-1]],e.push(S);break;case 3:return!0}}return!0}},L={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)},setInput:function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var i=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===s.length?this.yylloc.first_column:0)+s[s.length-e.length].length-e[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"},test_match:function(t,i){var e,s,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var a in n)this[a]=n[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,e,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),a=0;a<n.length;a++)if((e=this._input.match(this.rules[n[a]]))&&(!i||e[0].length>i[0].length)){if(i=e,s=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,n[a])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,n[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,e,s){switch(e){case 0:case 1:case 5:case 43:break;case 2:case 3:return this.popState(),34;case 4:return 34;case 6:return 10;case 7:return this.pushState("acc_title"),19;case 8:return this.popState(),"acc_title_value";case 9:return this.pushState("acc_descr"),21;case 10:return this.popState(),"acc_descr_value";case 11:this.pushState("acc_descr_multiline");break;case 12:case 25:case 27:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 5;case 15:return 8;case 16:return this.pushState("axis_data"),"X_AXIS";case 17:return this.pushState("axis_data"),"Y_AXIS";case 18:return this.pushState("axis_band_data"),24;case 19:return 31;case 20:return this.pushState("data"),16;case 21:return this.pushState("data"),18;case 22:return this.pushState("data_inner"),24;case 23:return 27;case 24:return this.popState(),26;case 26:this.pushState("string");break;case 28:return"STR";case 29:return 24;case 30:return 26;case 31:return 43;case 32:return"COLON";case 33:return 44;case 34:return 28;case 35:return 45;case 36:return 46;case 37:return 48;case 38:return 50;case 39:return 47;case 40:return 41;case 41:return 49;case 42:return 42;case 44:return 35;case 45:return 36}},rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:(\r?\n))/i,/^(?:(\r?\n))/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:\{)/i,/^(?:[^\}]*)/i,/^(?:xychart-beta\b)/i,/^(?:(?:vertical|horizontal))/i,/^(?:x-axis\b)/i,/^(?:y-axis\b)/i,/^(?:\[)/i,/^(?:-->)/i,/^(?:line\b)/i,/^(?:bar\b)/i,/^(?:\[)/i,/^(?:[+-]?(?:\d+(?:\.\d+)?|\.\d+))/i,/^(?:\])/i,/^(?:(?:`\) \{ this\.pushState\(md_string\); \}\n<md_string>\(\?:\(\?!`"\)\.\)\+ \{ return MD_STR; \}\n<md_string>\(\?:`))/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s+)/i,/^(?:;)/i,/^(?:$)/i],conditions:{data_inner:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,23,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},data:{rules:[0,1,3,4,5,6,7,9,11,14,15,16,17,20,21,22,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_band_data:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_data:{rules:[0,1,2,4,5,6,7,9,11,14,15,16,17,18,19,20,21,23,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[],inclusive:!1},md_string:{rules:[],inclusive:!1},string:{rules:[27,28],inclusive:!1},INITIAL:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0}}};function P(){this.yy={}}return D.lexer=L,P.prototype=D,D.Parser=P,new P}());h.parser=h;const o=h;function r(t){return"bar"===t.type}function l(t){return"band"===t.type}function c(t){return"linear"===t.type}class g{constructor(t){this.parentGroup=t}getMaxDimension(t,i){if(!this.parentGroup)return{width:t.reduce(((t,i)=>Math.max(i.length,t)),0)*i,height:i};const e={width:0,height:0},s=this.parentGroup.append("g").attr("visibility","hidden").attr("font-size",i);for(const a of t){const t=(0,n.c)(s,1,a),h=t?t.width:a.length*i,o=t?t.height:i;e.width=Math.max(e.width,h),e.height=Math.max(e.height,o)}return s.remove(),e}}class u{constructor(t,i,e,s){this.axisConfig=t,this.title=i,this.textDimensionCalculator=e,this.axisThemeConfig=s,this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left",this.showTitle=!1,this.showLabel=!1,this.showTick=!1,this.showAxisLine=!1,this.outerPadding=0,this.titleTextHeight=0,this.labelTextHeight=0,this.range=[0,10],this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left"}setRange(t){this.range=t,"left"===this.axisPosition||"right"===this.axisPosition?this.boundingRect.height=t[1]-t[0]:this.boundingRect.width=t[1]-t[0],this.recalculateScale()}getRange(){return[this.range[0]+this.outerPadding,this.range[1]-this.outerPadding]}setAxisPosition(t){this.axisPosition=t,this.setRange(this.range)}getTickDistance(){const t=this.getRange();return Math.abs(t[0]-t[1])/this.getTickValues().length}getAxisOuterPadding(){return this.outerPadding}getLabelDimension(){return this.textDimensionCalculator.getMaxDimension(this.getTickValues().map((t=>t.toString())),this.axisConfig.labelFontSize)}recalculateOuterPaddingToDrawBar(){.7*this.getTickDistance()>2*this.outerPadding&&(this.outerPadding=Math.floor(.7*this.getTickDistance()/2)),this.recalculateScale()}calculateSpaceIfDrawnHorizontally(t){let i=t.height;if(this.axisConfig.showAxisLine&&i>this.axisConfig.axisLineWidth&&(i-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const e=this.getLabelDimension(),s=.2*t.width;this.outerPadding=Math.min(e.width/2,s);const n=e.height+2*this.axisConfig.labelPadding;this.labelTextHeight=e.height,n<=i&&(i-=n,this.showLabel=!0)}if(this.axisConfig.showTick&&i>=this.axisConfig.tickLength&&(this.showTick=!0,i-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const t=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),e=t.height+2*this.axisConfig.titlePadding;this.titleTextHeight=t.height,e<=i&&(i-=e,this.showTitle=!0)}this.boundingRect.width=t.width,this.boundingRect.height=t.height-i}calculateSpaceIfDrawnVertical(t){let i=t.width;if(this.axisConfig.showAxisLine&&i>this.axisConfig.axisLineWidth&&(i-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const e=this.getLabelDimension(),s=.2*t.height;this.outerPadding=Math.min(e.height/2,s);const n=e.width+2*this.axisConfig.labelPadding;n<=i&&(i-=n,this.showLabel=!0)}if(this.axisConfig.showTick&&i>=this.axisConfig.tickLength&&(this.showTick=!0,i-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const t=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),e=t.height+2*this.axisConfig.titlePadding;this.titleTextHeight=t.height,e<=i&&(i-=e,this.showTitle=!0)}this.boundingRect.width=t.width-i,this.boundingRect.height=t.height}calculateSpace(t){return"left"===this.axisPosition||"right"===this.axisPosition?this.calculateSpaceIfDrawnVertical(t):this.calculateSpaceIfDrawnHorizontally(t),this.recalculateScale(),{width:this.boundingRect.width,height:this.boundingRect.height}}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}getDrawableElementsForLeftAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.x+this.boundingRect.width-this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["left-axis","axisl-line"],data:[{path:`M ${i},${this.boundingRect.y} L ${i},${this.boundingRect.y+this.boundingRect.height} `,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["left-axis","label"],data:this.getTickValues().map((t=>({text:t.toString(),x:this.boundingRect.x+this.boundingRect.width-(this.showLabel?this.axisConfig.labelPadding:0)-(this.showTick?this.axisConfig.tickLength:0)-(this.showAxisLine?this.axisConfig.axisLineWidth:0),y:this.getScaleValue(t),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"middle",horizontalPos:"right"})))}),this.showTick){const i=this.boundingRect.x+this.boundingRect.width-(this.showAxisLine?this.axisConfig.axisLineWidth:0);t.push({type:"path",groupTexts:["left-axis","ticks"],data:this.getTickValues().map((t=>({path:`M ${i},${this.getScaleValue(t)} L ${i-this.axisConfig.tickLength},${this.getScaleValue(t)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth})))})}return this.showTitle&&t.push({type:"text",groupTexts:["left-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.axisConfig.titlePadding,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:270,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElementsForBottomAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.y+this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["bottom-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${i} L ${this.boundingRect.x+this.boundingRect.width},${i}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["bottom-axis","label"],data:this.getTickValues().map((t=>({text:t.toString(),x:this.getScaleValue(t),y:this.boundingRect.y+this.axisConfig.labelPadding+(this.showTick?this.axisConfig.tickLength:0)+(this.showAxisLine?this.axisConfig.axisLineWidth:0),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"})))}),this.showTick){const i=this.boundingRect.y+(this.showAxisLine?this.axisConfig.axisLineWidth:0);t.push({type:"path",groupTexts:["bottom-axis","ticks"],data:this.getTickValues().map((t=>({path:`M ${this.getScaleValue(t)},${i} L ${this.getScaleValue(t)},${i+this.axisConfig.tickLength}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth})))})}return this.showTitle&&t.push({type:"text",groupTexts:["bottom-axis","title"],data:[{text:this.title,x:this.range[0]+(this.range[1]-this.range[0])/2,y:this.boundingRect.y+this.boundingRect.height-this.axisConfig.titlePadding-this.titleTextHeight,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElementsForTopAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.y+this.boundingRect.height-this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["top-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${i} L ${this.boundingRect.x+this.boundingRect.width},${i}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["top-axis","label"],data:this.getTickValues().map((t=>({text:t.toString(),x:this.getScaleValue(t),y:this.boundingRect.y+(this.showTitle?this.titleTextHeight+2*this.axisConfig.titlePadding:0)+this.axisConfig.labelPadding,fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"})))}),this.showTick){const i=this.boundingRect.y;t.push({type:"path",groupTexts:["top-axis","ticks"],data:this.getTickValues().map((t=>({path:`M ${this.getScaleValue(t)},${i+this.boundingRect.height-(this.showAxisLine?this.axisConfig.axisLineWidth:0)} L ${this.getScaleValue(t)},${i+this.boundingRect.height-this.axisConfig.tickLength-(this.showAxisLine?this.axisConfig.axisLineWidth:0)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth})))})}return this.showTitle&&t.push({type:"text",groupTexts:["top-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.axisConfig.titlePadding,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElements(){if("left"===this.axisPosition)return this.getDrawableElementsForLeftAxis();if("right"===this.axisPosition)throw Error("Drawing of right axis is not implemented");return"bottom"===this.axisPosition?this.getDrawableElementsForBottomAxis():"top"===this.axisPosition?this.getDrawableElementsForTopAxis():[]}}class x extends u{constructor(t,i,e,s,n){super(t,s,n,i),this.categories=e,this.scale=(0,a.WH)().domain(this.categories).range(this.getRange())}setRange(t){super.setRange(t)}recalculateScale(){this.scale=(0,a.WH)().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(.5),s.l.trace("BandAxis axis final categories, range: ",this.categories,this.getRange())}getTickValues(){return this.categories}getScaleValue(t){return this.scale(t)||this.getRange()[0]}}class d extends u{constructor(t,i,e,s,n){super(t,s,n,i),this.domain=e,this.scale=(0,a.m4Y)().domain(this.domain).range(this.getRange())}getTickValues(){return this.scale.ticks()}recalculateScale(){const t=[...this.domain];"left"===this.axisPosition&&t.reverse(),this.scale=(0,a.m4Y)().domain(t).range(this.getRange())}getScaleValue(t){return this.scale(t)}}function p(t,i,e,s){const n=new g(s);return l(t)?new x(i,e,t.categories,t.title,n):new d(i,e,[t.min,t.max],t.title,n)}class f{constructor(t,i,e,s){this.textDimensionCalculator=t,this.chartConfig=i,this.chartData=e,this.chartThemeConfig=s,this.boundingRect={x:0,y:0,width:0,height:0},this.showChartTitle=!1}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){const i=this.textDimensionCalculator.getMaxDimension([this.chartData.title],this.chartConfig.titleFontSize),e=Math.max(i.width,t.width),s=i.height+2*this.chartConfig.titlePadding;return i.width<=e&&i.height<=s&&this.chartConfig.showTitle&&this.chartData.title&&(this.boundingRect.width=e,this.boundingRect.height=s,this.showChartTitle=!0),{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){const t=[];return this.showChartTitle&&t.push({groupTexts:["chart-title"],type:"text",data:[{fontSize:this.chartConfig.titleFontSize,text:this.chartData.title,verticalPos:"middle",horizontalPos:"center",x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.chartThemeConfig.titleColor,rotation:0}]}),t}}function y(t,i,e,s){const n=new g(s);return new f(n,t,i,e)}class m{constructor(t,i,e,s,n){this.plotData=t,this.xAxis=i,this.yAxis=e,this.orientation=s,this.plotIndex=n}getDrawableElement(){const t=this.plotData.data.map((t=>[this.xAxis.getScaleValue(t[0]),this.yAxis.getScaleValue(t[1])]));let i;return i="horizontal"===this.orientation?(0,a.n8j)().y((t=>t[0])).x((t=>t[1]))(t):(0,a.n8j)().x((t=>t[0])).y((t=>t[1]))(t),i?[{groupTexts:["plot",`line-plot-${this.plotIndex}`],type:"path",data:[{path:i,strokeFill:this.plotData.strokeFill,strokeWidth:this.plotData.strokeWidth}]}]:[]}}class b{constructor(t,i,e,s,n,a){this.barData=t,this.boundingRect=i,this.xAxis=e,this.yAxis=s,this.orientation=n,this.plotIndex=a}getDrawableElement(){const t=this.barData.data.map((t=>[this.xAxis.getScaleValue(t[0]),this.yAxis.getScaleValue(t[1])])),i=.95*Math.min(2*this.xAxis.getAxisOuterPadding(),this.xAxis.getTickDistance()),e=i/2;return"horizontal"===this.orientation?[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:t.map((t=>({x:this.boundingRect.x,y:t[0]-e,height:i,width:t[1]-this.boundingRect.x,fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill})))}]:[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:t.map((t=>({x:t[0]-e,y:t[1],width:i,height:this.boundingRect.y+this.boundingRect.height-t[1],fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill})))}]}}class A{constructor(t,i,e){this.chartConfig=t,this.chartData=i,this.chartThemeConfig=e,this.boundingRect={x:0,y:0,width:0,height:0}}setAxes(t,i){this.xAxis=t,this.yAxis=i}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){return this.boundingRect.width=t.width,this.boundingRect.height=t.height,{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){if(!this.xAxis||!this.yAxis)throw Error("Axes must be passed to render Plots");const t=[];for(const[i,e]of this.chartData.plots.entries())switch(e.type){case"line":{const s=new m(e,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,i);t.push(...s.getDrawableElement())}break;case"bar":{const s=new b(e,this.boundingRect,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,i);t.push(...s.getDrawableElement())}}return t}}function w(t,i,e){return new A(t,i,e)}class S{constructor(t,i,e,s){this.chartConfig=t,this.chartData=i,this.componentStore={title:y(t,i,e,s),plot:w(t,i,e),xAxis:p(i.xAxis,t.xAxis,{titleColor:e.xAxisTitleColor,labelColor:e.xAxisLabelColor,tickColor:e.xAxisTickColor,axisLineColor:e.xAxisLineColor},s),yAxis:p(i.yAxis,t.yAxis,{titleColor:e.yAxisTitleColor,labelColor:e.yAxisLabelColor,tickColor:e.yAxisTickColor,axisLineColor:e.yAxisLineColor},s)}}calculateVerticalSpace(){let t=this.chartConfig.width,i=this.chartConfig.height,e=0,s=0,n=Math.floor(t*this.chartConfig.plotReservedSpacePercent/100),a=Math.floor(i*this.chartConfig.plotReservedSpacePercent/100),h=this.componentStore.plot.calculateSpace({width:n,height:a});t-=h.width,i-=h.height,h=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:i}),s=h.height,i-=h.height,this.componentStore.xAxis.setAxisPosition("bottom"),h=this.componentStore.xAxis.calculateSpace({width:t,height:i}),i-=h.height,this.componentStore.yAxis.setAxisPosition("left"),h=this.componentStore.yAxis.calculateSpace({width:t,height:i}),e=h.width,t-=h.width,t>0&&(n+=t,t=0),i>0&&(a+=i,i=0),this.componentStore.plot.calculateSpace({width:n,height:a}),this.componentStore.plot.setBoundingBoxXY({x:e,y:s}),this.componentStore.xAxis.setRange([e,e+n]),this.componentStore.xAxis.setBoundingBoxXY({x:e,y:s+a}),this.componentStore.yAxis.setRange([s,s+a]),this.componentStore.yAxis.setBoundingBoxXY({x:0,y:s}),this.chartData.plots.some((t=>r(t)))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateHorizontalSpace(){let t=this.chartConfig.width,i=this.chartConfig.height,e=0,s=0,n=0,a=Math.floor(t*this.chartConfig.plotReservedSpacePercent/100),h=Math.floor(i*this.chartConfig.plotReservedSpacePercent/100),o=this.componentStore.plot.calculateSpace({width:a,height:h});t-=o.width,i-=o.height,o=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:i}),e=o.height,i-=o.height,this.componentStore.xAxis.setAxisPosition("left"),o=this.componentStore.xAxis.calculateSpace({width:t,height:i}),t-=o.width,s=o.width,this.componentStore.yAxis.setAxisPosition("top"),o=this.componentStore.yAxis.calculateSpace({width:t,height:i}),i-=o.height,n=e+o.height,t>0&&(a+=t,t=0),i>0&&(h+=i,i=0),this.componentStore.plot.calculateSpace({width:a,height:h}),this.componentStore.plot.setBoundingBoxXY({x:s,y:n}),this.componentStore.yAxis.setRange([s,s+a]),this.componentStore.yAxis.setBoundingBoxXY({x:s,y:e}),this.componentStore.xAxis.setRange([n,n+h]),this.componentStore.xAxis.setBoundingBoxXY({x:0,y:n}),this.chartData.plots.some((t=>r(t)))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateSpace(){"horizontal"===this.chartConfig.chartOrientation?this.calculateHorizontalSpace():this.calculateVerticalSpace()}getDrawableElement(){this.calculateSpace();const t=[];this.componentStore.plot.setAxes(this.componentStore.xAxis,this.componentStore.yAxis);for(const i of Object.values(this.componentStore))t.push(...i.getDrawableElements());return t}}class C{static build(t,i,e,s){return new S(t,i,e,s).getDrawableElement()}}let k,_=0,T=I(),R=v(),D=M(),L=R.plotColorPalette.split(",").map((t=>t.trim())),P=!1,E=!1;function v(){const t=(0,s.E)(),i=(0,s.F)();return(0,s.C)(t.xyChart,i.themeVariables.xyChart)}function I(){const t=(0,s.F)();return(0,s.C)(s.B.xyChart,t.xyChart)}function M(){return{yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]}}function $(t){const i=(0,s.F)();return(0,s.d)(t.trim(),i)}function z(t,i){D.xAxis={type:"linear",title:D.xAxis.title,min:t,max:i},P=!0}function B(t){let i=[];if(0===t.length)return i;if(!P){const i=c(D.xAxis)?D.xAxis.min:1/0,e=c(D.xAxis)?D.xAxis.max:-1/0;z(Math.min(i,1),Math.max(e,t.length))}if(E||function(t){const i=Math.min(...t),e=Math.max(...t),s=c(D.yAxis)?D.yAxis.min:1/0,n=c(D.yAxis)?D.yAxis.max:-1/0;D.yAxis={type:"linear",title:D.yAxis.title,min:Math.min(s,i),max:Math.max(n,e)}}(t),l(D.xAxis)&&(i=D.xAxis.categories.map(((i,e)=>[i,t[e]]))),c(D.xAxis)){const e=D.xAxis.min,s=D.xAxis.max,n=(s-e+1)/t.length,a=[];for(let t=e;t<=s;t+=n)a.push(`${t}`);i=a.map(((i,e)=>[i,t[e]]))}return i}function W(t){return L[0===t?0:t%L.length]}const F={parser:o,db:{getDrawableElem:function(){if(0===D.plots.length)throw Error("No Plot to render, please provide a plot with some data");return D.title=(0,s.t)(),C.build(T,D,R,k)},clear:function(){(0,s.v)(),_=0,T=I(),D={yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]},R=v(),L=R.plotColorPalette.split(",").map((t=>t.trim())),P=!1,E=!1},setAccTitle:s.s,getAccTitle:s.g,setDiagramTitle:s.q,getDiagramTitle:s.t,getAccDescription:s.a,setAccDescription:s.b,setOrientation:function(t){T.chartOrientation="horizontal"===t?"horizontal":"vertical"},setXAxisTitle:function(t){D.xAxis.title=$(t.text)},setXAxisRangeData:z,setXAxisBand:function(t){D.xAxis={type:"band",title:D.xAxis.title,categories:t.map((t=>$(t.text)))},P=!0},setYAxisTitle:function(t){D.yAxis.title=$(t.text)},setYAxisRangeData:function(t,i){D.yAxis={type:"linear",title:D.yAxis.title,min:t,max:i},E=!0},setLineData:function(t,i){const e=B(i);D.plots.push({type:"line",strokeFill:W(_),strokeWidth:2,data:e}),_++},setBarData:function(t,i){const e=B(i);D.plots.push({type:"bar",fill:W(_),data:e}),_++},setTmpSVGG:function(t){k=t},getChartThemeConfig:function(){return R},getChartConfig:function(){return T}},renderer:{draw:(t,i,e,n)=>{const a=n.db,h=a.getChartThemeConfig(),o=a.getChartConfig();function r(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}s.l.debug("Rendering xychart chart\n"+t);const l=(0,s.A)(i),c=l.append("g").attr("class","main"),g=c.append("rect").attr("width",o.width).attr("height",o.height).attr("class","background");(0,s.i)(l,o.height,o.width,!0),l.attr("viewBox",`0 0 ${o.width} ${o.height}`),g.attr("fill",h.backgroundColor),a.setTmpSVGG(l.append("g").attr("class","mermaid-tmp-group"));const u=a.getDrawableElem(),x={};function d(t){let i=c,e="";for(const[s]of t.entries()){let n=c;s>0&&x[e]&&(n=x[e]),e+=t[s],i=x[e],i||(i=x[e]=n.append("g").attr("class",t[s]))}return i}for(const s of u){if(0===s.data.length)continue;const t=d(s.groupTexts);switch(s.type){case"rect":t.selectAll("rect").data(s.data).enter().append("rect").attr("x",(t=>t.x)).attr("y",(t=>t.y)).attr("width",(t=>t.width)).attr("height",(t=>t.height)).attr("fill",(t=>t.fill)).attr("stroke",(t=>t.strokeFill)).attr("stroke-width",(t=>t.strokeWidth));break;case"text":t.selectAll("text").data(s.data).enter().append("text").attr("x",0).attr("y",0).attr("fill",(t=>t.fill)).attr("font-size",(t=>t.fontSize)).attr("dominant-baseline",(t=>"top"===t.verticalPos?"text-before-edge":"middle")).attr("text-anchor",(t=>{return"left"===(i=t.horizontalPos)?"start":"right"===i?"end":"middle";var i})).attr("transform",(t=>r(t))).text((t=>t.text));break;case"path":t.selectAll("path").data(s.data).enter().append("path").attr("d",(t=>t.path)).attr("fill",(t=>t.fill?t.fill:"none")).attr("stroke",(t=>t.strokeFill)).attr("stroke-width",(t=>t.strokeWidth))}}}}}}}]); \ No newline at end of file diff --git a/assets/js/89ad43f4.6d3b4c61.js b/assets/js/89ad43f4.6d3b4c61.js new file mode 100644 index 0000000000..e02d92467a --- /dev/null +++ b/assets/js/89ad43f4.6d3b4c61.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2884],{56498:(e,i,s)=>{s.r(i),s.d(i,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>c,toc:()=>a});var t=s(74848),n=s(28453);const r={sidebar_label:"Services",sidebar_position:100},o="Services",c={id:"iaas/guides/deploy-guide/services/index",title:"Services",description:"The prerequisite for depoying the services of a cluster is the bootstrap of",source:"@site/docs/02-iaas/guides/deploy-guide/services/index.md",sourceDirName:"02-iaas/guides/deploy-guide/services",slug:"/iaas/guides/deploy-guide/services/",permalink:"/docs/iaas/guides/deploy-guide/services/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/index.md",tags:[],version:"current",sidebarPosition:100,frontMatter:{sidebar_label:"Services",sidebar_position:100},sidebar:"docs",previous:{title:"Bootstrap",permalink:"/docs/iaas/guides/deploy-guide/bootstrap"},next:{title:"Infrastructure",permalink:"/docs/iaas/guides/deploy-guide/services/infrastructure"}},d={},a=[];function l(e){const i={a:"a",admonition:"admonition",h1:"h1",li:"li",ol:"ol",p:"p",...(0,n.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.h1,{id:"services",children:"Services"}),"\n",(0,t.jsx)(i.admonition,{type:"info",children:(0,t.jsxs)(i.p,{children:["The prerequisite for depoying the services of a cluster is the bootstrap of\nthe nodes. How to bootstrap the nodes is documented in the\n",(0,t.jsx)(i.a,{href:"../bootstrap",children:"Bootstrap chapter of the Deploy Guide"}),"."]})}),"\n",(0,t.jsx)(i.p,{children:"When setting up a new cluster, the services are deployed in a specific order."}),"\n",(0,t.jsxs)(i.ol,{children:["\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"./infrastructure",children:"Infrastructure"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"./network",children:"Network"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"./logging-monitoring",children:"Logging & Monitoring"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"./ceph",children:"Ceph"})}),"\n",(0,t.jsx)(i.li,{children:(0,t.jsx)(i.a,{href:"./openstack",children:"OpenStack"})}),"\n"]})]})}function u(e={}){const{wrapper:i}={...(0,n.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,i,s)=>{s.d(i,{R:()=>o,x:()=>c});var t=s(96540);const n={},r=t.createContext(n);function o(e){const i=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function c(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),t.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8a671cf8.3c6e95e1.js b/assets/js/8a671cf8.3c6e95e1.js new file mode 100644 index 0000000000..a9497e1d3f --- /dev/null +++ b/assets/js/8a671cf8.3c6e95e1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4717],{92010:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>i});var s=t(74848),o=t(28453);const c={},r="Cluster Management on the capi management node",a={id:"container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node",title:"Cluster Management on the capi management node",description:"You can use make ssh to log in to the capi management server. There you can issueclusterctl and kubectl (aliased",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc/usage",slug:"/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Managing many clusters",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters"},next:{title:"Multi-AZ and multi-cloud environments",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments"}},l={},i=[];function d(e){const n={a:"a",br:"br",code:"code",h1:"h1",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"cluster-management-on-the-capi-management-node",children:"Cluster Management on the capi management node"}),"\n",(0,s.jsxs)(n.p,{children:["You can use ",(0,s.jsx)(n.code,{children:"make ssh"})," to log in to the capi management server. There you can issue",(0,s.jsx)(n.code,{children:"clusterctl"})," and ",(0,s.jsx)(n.code,{children:"kubectl"})," (aliased\nto ",(0,s.jsx)(n.code,{children:"k"}),") commands. The context ",(0,s.jsx)(n.code,{children:"kind-kind"}),"\nis used for the CAPI management while the context ",(0,s.jsx)(n.code,{children:"testcluster-admin@testcluster"})," can\nbe used to control the workload cluster ",(0,s.jsx)(n.code,{children:"testcluster"}),". You can of course create many\nof them. There are management scripts on the management server:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["In the user's (ubuntu) home directory, create a subdirectory with the CLUSTERNAME\nto hold your cluster's configuration data. Copy over the ",(0,s.jsx)(n.code,{children:"clusterctl.yaml"})," file\nfrom ",(0,s.jsx)(n.code,{children:"~/cluster-defaults/"})," and edit it to meet your needs. Note that you can also\ncopy over ",(0,s.jsx)(n.code,{children:"cloud.conf"})," and ",(0,s.jsx)(n.code,{children:"cluster-template.yaml"})," and adjust them, but you don't\nneed to. (If you don't create the subdirectory, the ",(0,s.jsx)(n.code,{children:"create_cluster.sh"})," script\nwill do so for you and use all defaults settings.)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"create_cluster.sh CLUSTERNAME"}),": Use this command to create a cluster with\nthe settings from ",(0,s.jsx)(n.code,{children:"~/$CLUSTERNAME/clusterctl.yaml"}),". More precisely, it uses the template\n",(0,s.jsx)(n.code,{children:"$CLUSTERNAME/cluster-template.yaml"})," and fills in the settings from\n",(0,s.jsx)(n.code,{children:"$CLUSTERNAME/clusterctl.yaml"})," to render a config file ",(0,s.jsx)(n.code,{children:"$CLUSTERNAME/$CLUSTERNAME-config.yaml"}),"\nwhich will then be submitted to the capi server (",(0,s.jsx)(n.code,{children:"kind-kind"})," context) for creating\nthe control plane nodes and worker nodes. The script will also apply openstack integration,\ncinder CSI, calico or cilium CNI, and optionally also metrics server, nginx ingress controller,\nflux, cert-manager. (These can be controlled by ",(0,s.jsx)(n.code,{children:"DEPLOY_XXX"})," variables, see below.\nDefaults can be preconfigured from the environment.tfvars file during management server\ncreation.)\nNote that ",(0,s.jsx)(n.code,{children:"CLUSTERNAME"})," defaults to ",(0,s.jsx)(n.code,{children:"testcluster"})," and must not contain\nwhitespace.\nThe script also makes sure that appropriate CAPI images are available (it grabs them\nfrom ",(0,s.jsx)(n.a,{href:"https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-k8s-capi-images",children:"OSISM"}),"\nas needed and registers them with OpenStack, following the SCS image metadata\nstandard).\nThe script returns once the control plane is fully working (the worker\nnodes might still be under construction). The kubectl file to talk to this\ncluster (as admin) can be found in ",(0,s.jsx)(n.code,{children:"~/$CLUSTERNAME/$CLUSTERNAME.yaml"}),". Expect the cluster\ncreation to take ~8mins. (CLUSTERNAME defaults to testcluster.) You can pass\n",(0,s.jsx)(n.code,{children:"--context=${CLUSTERNAME}-admin@$CLUSTERNAME"})," to ",(0,s.jsx)(n.code,{children:"kubectl"})," (with the\ndefault ",(0,s.jsx)(n.code,{children:"~/.kubernetes/config"})," config file) or ",(0,s.jsx)(n.code,{children:"export KUBECONFIG=$CLUSTERNAME.yaml"}),(0,s.jsx)(n.br,{}),"\n","to talk to the workload cluster."]}),"\n",(0,s.jsxs)(n.li,{children:["The subdirectory ",(0,s.jsx)(n.code,{children:"~/$CLUSTERNAME/deployed-manifests.d/"})," will contain the\ndeployed manifests for reference (and in case of nginx-ingress also to facilitate\na full cleanup)."]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"clusterctl.yaml"})," file can be edited the ",(0,s.jsx)(n.code,{children:"create_cluster.sh"})," script\nbe called again to submit the changes. (If you have not done any changes,\nre-running the script again is harmless.) Note that the ",(0,s.jsx)(n.code,{children:"create_cluster.sh"}),"\ndoes not currently remove any of the previously deployed services/deployments\nfrom the workload clusters -- this will be added later on with the appropriate\ncare and warnings. Also note that not all changes are allowed. You can easily\nchange the number of nodes or add k8s services to a cluster. For changing\nmachine flavors, machine images, kubernetes versions ... you will need to\nalso increase the ",(0,s.jsx)(n.code,{children:"CONTROL_PLANE_MACHINE_GEN"})," or the ",(0,s.jsx)(n.code,{children:"WORKER_MACHINE_GEN"}),"\ncounter to add a different suffix to these read-only resources. This will\ncause Cluster-API to orchestrate a rolling upgrade for you on rollout.\n(This is solved more elegantly in the helm chart style cluster management, see below.)"]}),"\n",(0,s.jsxs)(n.li,{children:["The directory ",(0,s.jsx)(n.code,{children:"~/k8s-cluster-api-provider/"})," contains a checked out git tree\nfrom the SCS project. It can be updated (",(0,s.jsx)(n.code,{children:"git pull"}),") to receive the latest\nfixes and improvements. This way, most incremental updates do not need the\nrecreation of the management server (and thus also not the recreation of your\nmanaged workload clusters), but can be applied with calling ",(0,s.jsx)(n.code,{children:"create_cluster.sh"}),"\nagain to the workload clusters."]}),"\n",(0,s.jsxs)(n.li,{children:["The installation of the openstack integration, cinder CSI, metrics server and\nnginx ingress controller is done via the ",(0,s.jsx)(n.code,{children:"bin/apply_*.sh"})," scripts that are called\nfrom ",(0,s.jsx)(n.code,{children:"create_cluster.sh"}),". You can manually call them as well -- they take\nthe cluster name as argument. (It's better to just call ",(0,s.jsx)(n.code,{children:"create_cluster.sh"}),"\nagain, though.) The applied yaml files are collected in\n",(0,s.jsx)(n.code,{children:"~/$CLUSTERNAME/deployed-manifests.d/"}),". You can ",(0,s.jsx)(n.code,{children:"kubectl delete -f"})," them\nto remove the functionality again."]}),"\n",(0,s.jsx)(n.li,{children:"You can, of course, also delete the cluster and create a new one if that\nlevel of disruption is fine for you. (See below in Advanced cluster templating\nwith helm to get an idea how we want to make this more convenient in the future.)"}),"\n",(0,s.jsxs)(n.li,{children:["Use ",(0,s.jsx)(n.code,{children:"kubectl get clusters -A"})," in the ",(0,s.jsx)(n.code,{children:"kind-kind"})," context to see what clusters\nexist. Use ",(0,s.jsx)(n.code,{children:"kubectl get all -A"})," in the ",(0,s.jsx)(n.code,{children:"testcluster-admin@testcluster"})," context\nto get an overview over the state of your workload cluster. You can access the logs\nfrom the capo controller in case you have trouble with cluster creation."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delete_cluster.sh [CLUSTERNAME]"}),": Tell the capi management server to remove\nthe cluster $CLUSTERNAME. It will also remove persistent volume claims belonging\nto the cluster. The script will return once the removal is done."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"cleanup.sh"}),": Remove all running clusters."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"add_cluster-network.sh CLUSTERNAME"})," adds the management server to the node network\nof the cluster ",(0,s.jsx)(n.code,{children:"CLUSTERNAME"}),", assuming that it runs on the same cloud (a region).\n",(0,s.jsx)(n.code,{children:"remove_cluster-network.sh"})," undoes this again. This is useful for debugging\npurposes."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For your convenience, ",(0,s.jsx)(n.code,{children:"k9s"})," is installed on the management server as well\nas ",(0,s.jsx)(n.code,{children:"calicoctl"}),", ",(0,s.jsx)(n.code,{children:"cilium"}),", ",(0,s.jsx)(n.code,{children:"hubble"}),", ",(0,s.jsx)(n.code,{children:"cmctl"}),", ",(0,s.jsx)(n.code,{children:"helm"})," and ",(0,s.jsx)(n.code,{children:"sonobuoy"}),".\nThese binaries can all be found in ",(0,s.jsx)(n.code,{children:"/usr/local/bin"})," while the helper scripts\nhave been deployed to ",(0,s.jsx)(n.code,{children:"~/bin/"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const o={},c=s.createContext(o);function r(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8aade8b1.61ea1937.js b/assets/js/8aade8b1.61ea1937.js new file mode 100644 index 0000000000..cfb1bdbaa3 --- /dev/null +++ b/assets/js/8aade8b1.61ea1937.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6305],{13637:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>u,frontMatter:()=>t,metadata:()=>d,toc:()=>c});var o=s(74848),a=s(28453);const t={sidebar_label:"Nova"},r="Nova",d={id:"iaas/guides/operations-guide/openstack/nova",title:"Nova",description:"Get all servers on a node",source:"@site/docs/02-iaas/guides/operations-guide/openstack/nova.md",sourceDirName:"02-iaas/guides/operations-guide/openstack",slug:"/iaas/guides/operations-guide/openstack/nova",permalink:"/docs/iaas/guides/operations-guide/openstack/nova",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/nova.md",tags:[],version:"current",frontMatter:{sidebar_label:"Nova"},sidebar:"docs",previous:{title:"Neutron",permalink:"/docs/iaas/guides/operations-guide/openstack/neutron"},next:{title:"Octavia",permalink:"/docs/iaas/guides/operations-guide/openstack/octavia"}},i={},c=[{value:"Get all servers on a node",id:"get-all-servers-on-a-node",level:2},{value:"Stop all servers running on a node",id:"stop-all-servers-running-on-a-node",level:2},{value:"Disable & enable a compute service",id:"disable--enable-a-compute-service",level:2},{value:"Force down & up a compute service",id:"force-down--up-a-compute-service",level:2},{value:"Huge pages",id:"huge-pages",level:2},{value:"Quality of Service (QoS)",id:"quality-of-service-qos",level:2},{value:"Host aggregates",id:"host-aggregates",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"nova",children:"Nova"}),"\n",(0,o.jsx)(n.h2,{id:"get-all-servers-on-a-node",children:"Get all servers on a node"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack --os-cloud admin server list --all-projects --host testbed-node-0\n"})}),"\n",(0,o.jsx)(n.h2,{id:"stop-all-servers-running-on-a-node",children:"Stop all servers running on a node"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"for server in $(openstack --os-cloud admin server list --all-projects --host testbed-node-0 --vm-state active -f value -c ID | tr -d '\\r'); do\n echo stopping server $server\n openstack --os-cloud admin server stop $server\n sleep 2\ndone\n"})}),"\n",(0,o.jsx)(n.h2,{id:"disable--enable-a-compute-service",children:"Disable & enable a compute service"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack --os-cloud admin compute service set --disable --description MAINTENANCE testbed-node-0 nova-compute\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack --os-cloud admin compute service list --long\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n| ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | up | 2023-12-14T14:20:24.000000 | MAINTENANCE | False |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack --os-cloud admin compute service set --enable testbed-node-0 nova-compute\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack --os-cloud admin compute service list\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+\n| ID | Binary | Host | Zone | Status | State | Updated At |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+\n| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | enabled | up | 2023-12-14T14:22:54.000000 |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+\n"})}),"\n",(0,o.jsx)(n.h2,{id:"force-down--up-a-compute-service",children:"Force down & up a compute service"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack --os-cloud admin --os-compute-api-version 2.12 compute service set --down testbed-node-0 nova-compute\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack --os-cloud admin compute service list --long\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n| ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | down | 2023-12-14T14:21:47.000000 | None | True |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack --os-cloud admin --os-compute-api-version 2.12 compute service set --up testbed-node-0 nova-compute\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack --os-cloud admin compute service list --long\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n| ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | up | 2023-12-14T14:20:24.000000 | None | False |\n+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+\n"})}),"\n",(0,o.jsx)(n.h2,{id:"huge-pages",children:"Huge pages"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ grep Huge /proc/meminfo\nAnonHugePages: 0 kB\nShmemHugePages: 0 kB\nFileHugePages: 0 kB\nHugePages_Total: 0\nHugePages_Free: 0\nHugePages_Rsvd: 0\nHugePages_Surp: 0\nHugepagesize: 2048 kB\nHugetlb: 0 kB\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ sudo sudo hugeadm --pool-list\nlibhugetlbfs: ERROR: Line too long when parsing mounts\n Size Minimum Current Maximum Default\n 2097152 0 0 0 *\n1073741824 0 0 0\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'/etc/default/grub\nGRUB_CMDLINE_LINUX="default_hugepagesz=1G hugepagesz=1G hugepages=512 transparent_hugepage=never"\n'})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"update-grub\nreboot\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ grep Huge /proc/meminfo\nAnonHugePages: 0 kB\nShmemHugePages: 0 kB\nFileHugePages: 0 kB\nHugePages_Total: 512\nHugePages_Free: 512\nHugePages_Rsvd: 0\nHugePages_Surp: 0\nHugepagesize: 1048576 kB\nHugetlb: 536870912 kB\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ sudo hugeadm --pool-list\nlibhugetlbfs: ERROR: Line too long when parsing mounts\n Size Minimum Current Maximum Default\n 2097152 0 0 0 *\n1073741824 512 512 512\n"})}),"\n",(0,o.jsx)(n.h2,{id:"quality-of-service-qos",children:"Quality of Service (QoS)"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/admin/resource-limits.html",children:"https://docs.openstack.org/nova/latest/admin/resource-limits.html"})}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"host-aggregates",children:"Host aggregates"}),"\n",(0,o.jsxs)(n.p,{children:["Host aggregates can be managed with the playbook. The playbook is used with\n",(0,o.jsx)(n.code,{children:"osism apply -e openstack host-aggregates"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Further arguments for host aggregates can be found in the\n",(0,o.jsx)(n.a,{href:"https://docs.ansible.com/ansible/latest/collections/openstack/cloud/host_aggregate_module.html",children:"documentation for the openstack.cloud.host_aggregate"})," Ansible module."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/openstack/playbook-host-aggregates.yml"',children:'---\n- name: Manage host aggregates\n hosts: localhost\n connection: local\n\n vars:\n host_aggregates:\n - name: aggregate1\n hosts:\n - host1\n - host2\n - host3\n\n tasks:\n - name: Create host aggregate\n openstack.cloud.host_aggregate:\n cloud: admin\n state: present\n name: "{{ item.name }}"\n hosts: "{{ item.hosts }}"\n loop: "{{ host_aggregates }}"\n'})})]})}function u(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>d});var o=s(96540);const a={},t=o.createContext(a);function r(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8b8a137c.b2b371d7.js b/assets/js/8b8a137c.b2b371d7.js new file mode 100644 index 0000000000..b16d167f56 --- /dev/null +++ b/assets/js/8b8a137c.b2b371d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7074],{44748:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>o});var s=t(74848),i=t(28453);const r={sidebar_label:"Network",sidebar_position:15},l="Network",a={id:"iaas/guides/configuration-guide/network",title:"Network",description:"Netplan",source:"@site/docs/02-iaas/guides/configuration-guide/network.md",sourceDirName:"02-iaas/guides/configuration-guide",slug:"/iaas/guides/configuration-guide/network",permalink:"/docs/iaas/guides/configuration-guide/network",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/network.md",tags:[],version:"current",sidebarPosition:15,frontMatter:{sidebar_label:"Network",sidebar_position:15},sidebar:"docs",previous:{title:"Manager",permalink:"/docs/iaas/guides/configuration-guide/manager"},next:{title:"Proxy",permalink:"/docs/iaas/guides/configuration-guide/proxy"}},d={},o=[{value:"Netplan",id:"netplan",level:2},{value:"Example",id:"example",level:3},{value:"Dispatcher scripts",id:"dispatcher-scripts",level:3},{value:"Dummy interfaces",id:"dummy-interfaces",level:3},{value:"<code>/etc/interfaces</code>",id:"etcinterfaces",level:2},{value:"IPv6 fabric underlay",id:"ipv6-fabric-underlay",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"network",children:"Network"}),"\n",(0,s.jsx)(n.h2,{id:"netplan",children:"Netplan"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="Since OSISM 6.1.0, the default network type is a netplan and no longer needs to be set explicitly"',children:"network_type: netplan\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The configuration is written to ",(0,s.jsx)(n.code,{children:"/etc/netplan/01-osism.yaml"})," by default. Can be changed\nvia the ",(0,s.jsx)(n.code,{children:"network_netplan_path"})," and ",(0,s.jsx)(n.code,{children:"network_netplan_file"})," parameters. The file permissions\nare ",(0,s.jsx)(n.code,{children:"0600"})," by default (cane be changed via the ",(0,s.jsx)(n.code,{children:"network_netplan_permissions"})," parameter).\nBy default, all other files in ",(0,s.jsx)(n.code,{children:"/etc/netplan"})," are removed. If you do not want this, you\ncan set ",(0,s.jsx)(n.code,{children:"network_netplan_remove_unmanaged_files"})," to ",(0,s.jsx)(n.code,{children:"false"}),". It is also possible to explicitly\nlist individual files that should not be deleted in ",(0,s.jsx)(n.code,{children:"network_netplan_managed_files_extra"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["An existing ",(0,s.jsx)(n.code,{children:"/etc/intefaces"})," file is replaced with a placeholder file. It is not possible\nto use ",(0,s.jsx)(n.code,{children:"/etc/interfaces"})," and Netplan in parallel."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="This template is used as the base for the configuration"',children:"# This file describes the network interfaces available on your system\n# For more information, see netplan(5).\n---\nnetwork:\n version: {{ network_version }}\n renderer: {{ network_renderer }}\n\n bonds:\n {{ network_bonds|to_nice_yaml(indent=4)|indent(4) }}\n\n bridges:\n {{ network_bridges|to_nice_yaml(indent=4)|indent(4) }}\n\n ethernets:\n {{ network_ethernets|to_nice_yaml(indent=4)|indent(4) }}\n\n tunnels:\n {{ network_tunnels|to_nice_yaml(indent=4)|indent(4) }}\n\n vlans:\n {{ network_vlans|to_nice_yaml(indent=4)|indent(4) }}\n\n vrfs:\n {{ network_vrfs|to_nice_yaml(indent=4)|indent(4) }}\n"})}),"\n",(0,s.jsx)(n.p,{children:"The parameters listed in the following table can be used in the template."}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Default"}),(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"network_version"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"2"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Defines what version of the configuration format is used. The only value supported at the moment is 2."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"network_renderer"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"networkd"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Defines what network configuration tool will be used to set up your configuration."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"network_bonds"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"{}"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bonds",children:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bonds"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"network_bridges"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"{}"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bridges",children:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bridges"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"network_ethernets"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"{}"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-ethernets",children:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-ethernets"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"network_tunnels"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"{}"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-tunnels",children:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-tunnels"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"network_vlans"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"{}"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vlans",children:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vlans"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"network_vrfs"}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.code,{children:"{}"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vrfs",children:"https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vrfs"})})]})]})]}),"\n",(0,s.jsxs)(n.p,{children:["By default changes to the network configuration are not applied automatically. This is done on\npurpose to allow a manual check in advance. Changes to the network configuration can\nbe applied either by rebooting or by executing ",(0,s.jsx)(n.code,{children:"netplan apply"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ osism console --type clush all\nEnter 'quit' to leave this interactive mode\nWorking with nodes: testbed-manager.testbed.osism.xyz,testbed-node-[0-2].testbed.osism.xyz\nclush> sudo netplan apply\n"})}),"\n",(0,s.jsxs)(n.p,{children:["It is possible to execute the ",(0,s.jsx)(n.code,{children:"netplan apply"})," automatically via a handler when changes are made.\nThe parameter ",(0,s.jsx)(n.code,{children:"network_allow_service_restart"})," is used for this."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"network_allow_service_restart: true\n"})}),"\n",(0,s.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,s.jsxs)(n.p,{children:["The Netplan documentation contains a large number of example configurations. The following\nexample shows the use of ",(0,s.jsx)(n.a,{href:"https://netplan.readthedocs.io/en/stable/examples/#how-to-create-vlans",children:"How to create VLANs"})," with the osism.commons.network role."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'network_ethernets:\n mainif:\n match:\n macaddress: "de:ad:be:ef:ca:fe"\n set-name: mainif\n addresses: [ "10.3.0.5/23" ]\n nameservers:\n addresses: [ "8.8.8.8", "8.8.4.4" ]\n search: [ example.com ]\n routes:\n - to: default\n via: 10.3.0.1\n\nnetwork_vlans:\n vlan15:\n id: 15\n link: mainif\n addresses: [ "10.3.99.5/24" ]\n vlan10:\n id: 10\n link: mainif\n addresses: [ "10.3.98.5/24" ]\n nameservers:\n addresses: [ "127.0.0.1" ]\n search: [ domain1.example.com, domain2.example.com ]\n'})}),"\n",(0,s.jsx)(n.h3,{id:"dispatcher-scripts",children:"Dispatcher scripts"}),"\n",(0,s.jsx)(n.h3,{id:"dummy-interfaces",children:"Dummy interfaces"}),"\n",(0,s.jsxs)(n.p,{children:["Dummy devices are created with the help of\n",(0,s.jsx)(n.a,{href:"https://www.freedesktop.org/software/systemd/man/latest/systemd.netdev.html",children:"systemd.netdev"}),"\nand can then be used as a normal netowrk device in the Netplan configuration."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"network_dummy_interfaces:\n - dummy0\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The MTU is set to 9000 by default and can be set via ",(0,s.jsx)(n.code,{children:"network_dummy_interface_mtu"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"etcinterfaces",children:(0,s.jsx)(n.code,{children:"/etc/interfaces"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="If /etc/interfaces is to be used, the network_type must be explicitly set in environments/configuration.yml"',children:"network_type: interfaces\n"})}),"\n",(0,s.jsx)(n.h2,{id:"ipv6-fabric-underlay",children:"IPv6 fabric underlay"}),"\n",(0,s.jsxs)(n.p,{children:["Example configuration for a node. The configuration is stored in the ",(0,s.jsx)(n.code,{children:"host_vars"})," file for the node in ",(0,s.jsx)(n.code,{children:"inventory"}),"\ndirectory in the configuration repository."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"##########################################################\n# ansible\n\nansible_host: 10.10.42.10\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"##########################################################\n# generic\n\ninternal_interface: dummy0\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"##########################################################\n# network\n\nnetwork_type: netplan\nnetwork_dummy_interfaces:\n - dummy0\nnetwork_ethernets:\n enp99s0f0np0:\n mtu: 9100\n enp99s0f1np1:\n mtu: 9100\n dummy0:\n addresses:\n - 10.10.42.10/32\n - 2001:db8::10:10:42:10/128\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"##########################################################\n# frr\n\nfrr_local_as: 4210042010\nfrr_loopback_v4: 10.10.42.10\nfrr_loopback_v6: 2001:db8::10:10:42:10\nfrr_uplinks:\n - interface: enp99s0f0np0\n remote_as: 65401\n - interface: enp99s0f1np1\n remote_as: 65402\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'##########################################################\n# kolla\n\nnetwork_interface: "{{ internal_interface }}"\n'})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>l,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function l(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8ba37aa2.c4cdbc29.js b/assets/js/8ba37aa2.c4cdbc29.js new file mode 100644 index 0000000000..0df4cc00cb --- /dev/null +++ b/assets/js/8ba37aa2.c4cdbc29.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3416],{13967:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>s,default:()=>p,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var o=n(74848),a=n(28453);const c={},s="Roadmap",i={id:"container/components/k8s-cluster-api-provider/doc/roadmap",title:"Roadmap",description:"Advanced cluster templating with helm (Technical Preview)",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/roadmap.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc",slug:"/container/components/k8s-cluster-api-provider/doc/roadmap",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/roadmap",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/roadmap.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Continuous integration",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration"},next:{title:"Usage",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/"}},r={},d=[{value:"Advanced cluster templating with helm (Technical Preview)",id:"advanced-cluster-templating-with-helm-technical-preview",level:2}];function l(e){const t={a:"a",h1:"h1",h2:"h2",p:"p",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"roadmap",children:"Roadmap"}),"\n",(0,o.jsx)(t.h2,{id:"advanced-cluster-templating-with-helm-technical-preview",children:"Advanced cluster templating with helm (Technical Preview)"}),"\n",(0,o.jsxs)(t.p,{children:["On the management server, we have not only helm installed, but also the repository ",(0,o.jsx)(t.a,{href:"https://github.com/stackhpc/capi-helm-charts",children:"https://github.com/stackhpc/capi-helm-charts"})," checked out. Amongst other things, it automates the creation of new machine templates when needed and doing rolling updates on your k8s cluster with clusterctl. This allows for an easy adaptation of your cluster to\ndifferent requirements, new k8s versions etc."]}),"\n",(0,o.jsx)(t.p,{children:"Please note that this is currently evolving quickly and we have not completely assessed and tested the capabilities. We intend to do this after R2 and eventually recommend this as the standard way of managing clusters in production. At this point, it's included as a technical preview."})]})}function p(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>i});var o=n(96540);const a={},c=o.createContext(a);function s(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8d25d5d4.a5124146.js b/assets/js/8d25d5d4.a5124146.js new file mode 100644 index 0000000000..ee28ba97d5 --- /dev/null +++ b/assets/js/8d25d5d4.a5124146.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4277],{81456:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var o=n(74848),s=n(28453);const i={title:"OpenStack Federation via OpenID-Connect",type:null,status:"Draft",track:"Global"},a=void 0,r={id:"operations/iam/openstack-federation-via-oidc",title:"OpenStack Federation via OpenID-Connect",description:"Keystone supports federating authentication and authorization decisions via several mechanisms",source:"@site/contributor-docs/operations/iam/openstack-federation-via-oidc.md",sourceDirName:"operations/iam",slug:"/operations/iam/openstack-federation-via-oidc",permalink:"/contributor-docs/operations/iam/openstack-federation-via-oidc",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"OpenStack Federation via OpenID-Connect",type:null,status:"Draft",track:"Global"},sidebar:"devDocs",previous:{title:"Identity Federation in SCS",permalink:"/contributor-docs/operations/iam/identity-federation-in-scs"},next:{title:"Zuul users guide",permalink:"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide"}},c={},d=[{value:"1. Keystone",id:"1-keystone",level:2},{value:"1.1 Keycloak IdP realm discovery",id:"11-keycloak-idp-realm-discovery",level:3},{value:"1.2 Keystone mapping of token claims",id:"12-keystone-mapping-of-token-claims",level:3},{value:"1.3 Horizon WebSSO for federated users",id:"13-horizon-websso-for-federated-users",level:3},{value:"1.4 OpenStack CLI and API access for federated users",id:"14-openstack-cli-and-api-access-for-federated-users",level:3},{value:"1.5 SSO Federation between to SCS deployments",id:"15-sso-federation-between-to-scs-deployments",level:3}];function h(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(t.p,{children:["Keystone supports federating authentication and authorization decisions via several mechanisms\nas ",(0,o.jsx)(t.a,{href:"https://docs.openstack.org/keystone/latest/admin/federation/introduction.html",children:"documented by the project"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["In SCS OpenID Connect is used for federation between Keystone and the IdP, which is\n",(0,o.jsx)(t.a,{href:"https://docs.scs.community/standards/scs-0300-v1-requirements-for-sso-identity-federation",children:"currently provided by Keycloak"}),"\nin SCS."]}),"\n",(0,o.jsx)(t.p,{children:"The following sections describe the setup."}),"\n",(0,o.jsx)(t.h2,{id:"1-keystone",children:"1. Keystone"}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.a,{href:"https://docs.openstack.org/keystone/latest/admin/federation/federated_identity.html",children:"Keystone supports federated identities"}),".\nTo allow SCS to consume identities managed in external IAM solutions,\nfederation protocols like OpenID Connect or SAML can be used.\nKeystone currently makes use of third party apache modules like\n",(0,o.jsx)(t.a,{href:"https://github.com/OpenIDC/mod_auth_openidc",children:"mod_auth_openidc"}),",\n",(0,o.jsx)(t.a,{href:"https://github.com/OpenIDC/mod_oauth2",children:"mod_oauth2"})," and\n",(0,o.jsx)(t.a,{href:"https://github.com/UNINETT/mod_auth_mellon",children:"mod_auth_mellon"})," to delegate\nauthentication to a SSO IdP (i.e. SAML IdP or OpenID Connect provider)."]}),"\n",(0,o.jsxs)(t.p,{children:["In OpenStack the apache modules are configured using the\n",(0,o.jsx)(t.a,{href:"https://github.com/openstack/kolla-ansible/tree/master/ansible/roles/keystone/templates",children:"wsgi-keystone.conf template"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"In SCS we make use of the OAuth 2.0 Authorization Code Grant flow between Keystone and Keycloak\nand use PKCE (RFC 7636) with the S256 challenge method."}),"\n",(0,o.jsx)(t.p,{children:"In addition to the usual SSL CA of the environment, Keycloak uses separate certificates to sign the OIDC tokens."}),"\n",(0,o.jsx)(t.p,{children:"Due to the way the Keystone container image runs apache (in the foreground) and keystone itself (as WSGI module),\nreconfiguring the apache URL locations on the fly is not possible currently without a downtime of several seconds.\nThat is the reason why SCS currently makes use of a single central proxy realm in Keycloak, to which Keystone\nconnects."}),"\n",(0,o.jsx)(t.h3,{id:"11-keycloak-idp-realm-discovery",children:"1.1 Keycloak IdP realm discovery"}),"\n",(0,o.jsxs)(t.p,{children:["Keycloak offers standard OIDC service discovery via ",(0,o.jsx)(t.code,{children:".well-known"})," documents to advertise its endpoints."]}),"\n",(0,o.jsx)(t.p,{children:"In SCS we want to represent each customer by a separate dedicated Keycloak realm, which can enventually be used\nfor customer self service and to federate out to customer owned IAM external solutions."}),"\n",(0,o.jsxs)(t.p,{children:["In the SCS testbed we currently experiment with the implications of using a single central proxy realm in Keycloak\nand chaining federation from there to customer specific realms, also hosted in the same Keycloak instance.\nTo make this usable, SCS makes use of the\n",(0,o.jsx)(t.a,{href:"https://github.com/sventorben/keycloak-home-idp-discovery",children:"Keycloak Home IdP Discovery"}),"\nextension."]}),"\n",(0,o.jsx)(t.h3,{id:"12-keystone-mapping-of-token-claims",children:"1.2 Keystone mapping of token claims"}),"\n",(0,o.jsxs)(t.p,{children:["Upon login of a user Keystone evaluates the credentials obtained from the ID token that the IdP issued.\nThese include group memberships and roles, which can be used to assign the user to a certain project.\nKeystone maps these external identities to internal (shadow) users.\nIt can either attempt to map the obtained information to a ",(0,o.jsx)(t.code,{children:"local"})," type user, which needs to be\nprovisioned before authentication by external tooling, or it can be instructed via the mapping to\ngenerate an ",(0,o.jsx)(t.code,{children:"ephemeral"})," type user. ",(0,o.jsx)(t.code,{children:"ephemeral"})," users are cleaned up automatically after some time\nof inactivity and with that, they lose access to projects, iff the access is granted indirectly\nvia group membership rather than directly to the user itself."]}),"\n",(0,o.jsxs)(t.p,{children:["Group memberships for ",(0,o.jsx)(t.code,{children:"ephemeral"})," users are only represented via their tokens, but not stored in the\nKeystone backend database."]}),"\n",(0,o.jsxs)(t.p,{children:["After successful authorization Keystone issues an OpenStack specific ",(0,o.jsx)(t.code,{children:"fernet"})," token to the user,\nwhich is the currency that is understood by other OpenStack services and can be used to access them."]}),"\n",(0,o.jsx)(t.p,{children:"In SCS we want to represent each customer by a sepatate dedicated OpenStack domain to host\ntheir projects and (shadow) user accounts."}),"\n",(0,o.jsxs)(t.p,{children:["The processing of information from the OIDC tokens is configured by two parts. The first part is the\n",(0,o.jsx)(t.code,{children:"rules.json"})," mapping which is described in the\n",(0,o.jsx)(t.a,{href:"https://docs.openstack.org/keystone/latest/admin/federation/mapping_combinations.html",children:"OpenStack federation mapping combinations"}),"\ndocument. This file is used to configure Keystones internal mapping engine\nand it needs to be attached to some OpenStack domain, which is named ",(0,o.jsx)(t.code,{children:"keycloak"})," by default in SCS."]}),"\n",(0,o.jsxs)(t.p,{children:["The second (static) part is the ",(0,o.jsx)(t.code,{children:"[auth]"})," and ",(0,o.jsx)(t.code,{children:"[mapped]"})," sections in ",(0,o.jsx)(t.code,{children:"keystone.conf"})," (see e.g.\n",(0,o.jsx)(t.a,{href:"https://github.com/osism/testbed/tree/main/environments/kolla/files/overlays/keystone",children:"the overlays currently used in the OSISM testbed"}),"\n)."]}),"\n",(0,o.jsx)(t.h3,{id:"13-horizon-websso-for-federated-users",children:"1.3 Horizon WebSSO for federated users"}),"\n",(0,o.jsx)(t.p,{children:"The Horizon dashboard supports login via OpenID Connect via Keystone endpoint.\nSCS adjusted the logout behavior to invalidate both, the OpenID Connect session\nwith the IdP and the Keystone token."}),"\n",(0,o.jsx)(t.h3,{id:"14-openstack-cli-and-api-access-for-federated-users",children:"1.4 OpenStack CLI and API access for federated users"}),"\n",(0,o.jsx)(t.p,{children:"To support OpenStack CLI and API access, SCS implemented support for the OIDC Device Authorization Grant\nin Keystone. On top we added support for PKCE (RFC 7636) in combination with that."}),"\n",(0,o.jsx)(t.h3,{id:"15-sso-federation-between-to-scs-deployments",children:"1.5 SSO Federation between to SCS deployments"}),"\n",(0,o.jsxs)(t.p,{children:["To show the potential of this approach to federation SCS created a\n",(0,o.jsx)(t.a,{href:"https://docs-staging.scs.community/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations",children:"Howto for OIDC federation between SCS deployments"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var o=n(96540);const s={},i=o.createContext(s);function a(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8db05b07.24ad3227.js b/assets/js/8db05b07.24ad3227.js new file mode 100644 index 0000000000..b5e551608e --- /dev/null +++ b/assets/js/8db05b07.24ad3227.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3663],{92257:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var o=t(74848),s=t(28453);const a={sidebar_label:"OpenStack Health Monitor"},i="Setting up OpenStack health monitor on Debian",r={id:"iaas/components/openstack-health-monitor",title:"Setting up OpenStack health monitor on Debian",description:"Kurt Garloff, 2024-02-20",source:"@site/docs/02-iaas/components/openstack-health-monitor.md",sourceDirName:"02-iaas/components",slug:"/iaas/components/openstack-health-monitor",permalink:"/docs/iaas/components/openstack-health-monitor",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/openstack-health-monitor.md",tags:[],version:"current",frontMatter:{sidebar_label:"OpenStack Health Monitor"}},l={},d=[{value:"Intro",id:"intro",level:2},{value:"Setting up the driver VM",id:"setting-up-the-driver-vm",level:2},{value:"Internal vs external monitoring",id:"internal-vs-external-monitoring",level:3},{value:"Unprivileged operation",id:"unprivileged-operation",level:3},{value:"Driver VM via openstack CLI",id:"driver-vm-via-openstack-cli",level:3},{value:"Configuring openstack CLI on the driver VM",id:"configuring-openstack-cli-on-the-driver-vm",level:3},{value:"Custom CA",id:"custom-ca",level:3},{value:"Your first <code>api_monitor.sh</code> iteration",id:"your-first-api_monitorsh-iteration",level:2},{value:"Resource impact and charging",id:"resource-impact-and-charging",level:3},{value:"Automating startup and cleanup",id:"automating-startup-and-cleanup",level:2},{value:"Changing parameters and restarting",id:"changing-parameters-and-restarting",level:3},{value:"Multiple instances",id:"multiple-instances",level:3},{value:"Alarming and Logs",id:"alarming-and-logs",level:2},{value:"eMail",id:"email",level:3},{value:"Log files",id:"log-files",level:3},{value:"Data collection and dashboard",id:"data-collection-and-dashboard",level:2},{value:"telegraf",id:"telegraf",level:3},{value:"influxdb",id:"influxdb",level:3},{value:"Add <code>-S CLOUDNAME</code> to your <code>run_CLOUDNAME.sh</code> script",id:"add--s-cloudname-to-your-run_cloudnamesh-script",level:3},{value:"grafana",id:"grafana",level:3},{value:"Basic config",id:"basic-config",level:4},{value:"Enable influx database in grafana",id:"enable-influx-database-in-grafana",level:4},{value:"Importing the dashboard",id:"importing-the-dashboard",level:4},{value:"No data displayed?",id:"no-data-displayed",level:4},{value:"Dashboard features",id:"dashboard-features",level:4},{value:"github OIDC integration",id:"github-oidc-integration",level:4},{value:"Alternative approach to install and configure the dashboard behind a reverse proxy",id:"alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy",level:2},{value:"Maintenance",id:"maintenance",level:2},{value:"Unattended upgrades",id:"unattended-upgrades",level:3},{value:"Updating openstack-health-monitor",id:"updating-openstack-health-monitor",level:3},{value:"Backup",id:"backup",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Debugging issues",id:"debugging-issues",level:3},{value:"Analyzing failures",id:"analyzing-failures",level:3},{value:"Cleaning things up",id:"cleaning-things-up",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"setting-up-openstack-health-monitor-on-debian",children:"Setting up OpenStack health monitor on Debian"}),"\n",(0,o.jsx)(n.p,{children:"Kurt Garloff, 2024-02-20"}),"\n",(0,o.jsx)(n.h2,{id:"intro",children:"Intro"}),"\n",(0,o.jsxs)(n.p,{children:["The development of ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/",children:"openstack-health-monitor"})," was done on ",(0,o.jsx)(n.a,{href:"https://kfg.images.obs-website.eu-de.otc.t-systems.com/",children:"openSUSE 15.x images"}),", just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution."]}),"\n",(0,o.jsx)(n.p,{children:"Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here."}),"\n",(0,o.jsxs)(n.p,{children:["Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor",children:"successor project"})," for the increasingly hard to maintain shell code, this may not be worth the trouble."]}),"\n",(0,o.jsxs)(n.p,{children:["openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested.\nThe scenario is described in a bit more detail in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"repository's README.md"})," file."]}),"\n",(0,o.jsxs)(n.p,{children:["The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the ",(0,o.jsx)(n.a,{href:"https://docs.scs.community/docs/category/monitoring",children:"monitoring section"})," of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up."]}),"\n",(0,o.jsx)(n.h2,{id:"setting-up-the-driver-vm",children:"Setting up the driver VM"}),"\n",(0,o.jsxs)(n.p,{children:["So we start a ",(0,o.jsx)(n.code,{children:"Debian 12"})," image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard;\nthe instructions use flavor names and image names from the SCS standards.\nFor many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack)."]}),"\n",(0,o.jsx)(n.h3,{id:"internal-vs-external-monitoring",children:"Internal vs external monitoring"}),"\n",(0,o.jsx)(n.p,{children:"There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor."}),"\n",(0,o.jsx)(n.p,{children:"The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems."}),"\n",(0,o.jsx)(n.h3,{id:"unprivileged-operation",children:"Unprivileged operation"}),"\n",(0,o.jsx)(n.p,{children:"Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own."}),"\n",(0,o.jsxs)(n.p,{children:["If ",(0,o.jsx)(n.code,{children:"openstack availability zone list --compute"})," fails for you without admin rights, please fix your openstack client. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Healh-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)"]}),"\n",(0,o.jsx)(n.h3,{id:"driver-vm-via-openstack-cli",children:"Driver VM via openstack CLI"}),"\n",(0,o.jsxs)(n.p,{children:["The author prefers to setup the VM via ",(0,o.jsx)(n.code,{children:"openstack"})," CLI tooling. He has working entries for all clouds he uses in his ",(0,o.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})," and ",(0,o.jsx)(n.code,{children:"secure.yaml"})," and has exported the ",(0,o.jsx)(n.code,{children:"OS_CLOUD"})," environment variable to point to the cloud he is working on to set up the driver VM. The author uses the ",(0,o.jsx)(n.code,{children:"bash"})," shell. All of this of course could be scripted."]}),"\n",(0,o.jsx)(n.p,{children:"So here we go"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["Create the network setup for a VM in a network ",(0,o.jsx)(n.code,{children:"oshm-network"})," with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network."]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"PUBLIC=$(openstack network list --external -f value -c Name)\nopenstack router create oshm-router\nopenstack router set --external-gateway $PUBLIC oshm-driver-router\nopenstack network create oshm-network\nopenstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet\nopenstack router add subnet oshm-router oshm-subnet\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"2",children:["\n",(0,o.jsx)(n.li,{children:"Create a security group that allows ssh and ping access"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack security group create sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"3",children:["\n",(0,o.jsx)(n.li,{children:"Being at it, we also create the security group for grafana"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack security group create grafana\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"4",children:["\n",(0,o.jsx)(n.li,{children:"To connect to the VM via ssh later, we create an SSH keypair"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key\nchmod og-r ~/.ssh/oshm-key.pem \n"})}),"\n",(0,o.jsxs)(n.p,{children:["Rather than creating a new key (and storing and protecting the private key), we could have passed ",(0,o.jsx)(n.code,{children:"--public-key"})," and used an existing keypair."]}),"\n",(0,o.jsxs)(n.ol,{start:"5",children:["\n",(0,o.jsx)(n.li,{children:"Look up Debian 12 image UUID."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"IMGUUID=$(openstack image list --name \"Debian 12\" -f value -c ID | tr -d '\\r')\necho $IMGUUID\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Sidenote: The ",(0,o.jsx)(n.code,{children:"tr"})," command is there to handle broken tooling that embeds a trailing ",(0,o.jsx)(n.code,{children:"\\r"})," in the output."]}),"\n",(0,o.jsxs)(n.ol,{start:"6",children:["\n",(0,o.jsx)(n.li,{children:"Boot the driver VM"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing ",(0,o.jsx)(n.code,{children:"--block-device"}),". See ",(0,o.jsx)(n.a,{href:"https://scs.community/2023/08/21/diskless-flavors/",children:"diskless flavor blog article"}),". For flavors with local root disks, you could have used the ",(0,o.jsx)(n.code,{children:"--image $IMGUUID"})," parameter instead."]}),"\n",(0,o.jsxs)(n.ol,{start:"7",children:["\n",(0,o.jsxs)(n.li,{children:["Wait for it to boot (optional)\nYou can look at the boot log with ",(0,o.jsx)(n.code,{children:"openstack console log show oshm-driver"})," or connect to it via VNC at the URL given by ",(0,o.jsx)(n.code,{children:"openstack console url show oshm-driver"}),". You can of course also query openstack on the status ",(0,o.jsx)(n.code,{children:"openstack server list"})," or ",(0,o.jsx)(n.code,{children:"openstack server show oshm-driver"}),". You can also just create a simple loop:"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'declare -i ctr=0 RC=0\nwhile [ $ctr -le 120 ]; do\n STATUS="$(openstack server list --name oshm-driver -f value -c Status)"\n if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi \n if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi\n if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi\n sleep 2\n let ctr+=1\ndone\n# return $RC\nif [ $RC != 0 ]; then false; fi\n'})}),"\n",(0,o.jsxs)(n.ol,{start:"8",children:["\n",(0,o.jsx)(n.li,{children:"Attach a floating IP so it's reachable from the outside."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks | sed "s@^[^:]*:[^\']*\'\\([0-9\\.]*\\)\'.*\\$@\\1@")\nFIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)\necho $FIXEDIP $FIXEDPORT\nopenstack floating ip create --port $FIXEDPORT $PUBLIC\nFLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")\necho "Floating IP: $FLOATINGIP"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Remember this floating IP address."}),"\n",(0,o.jsxs)(n.ol,{start:"9",children:["\n",(0,o.jsx)(n.li,{children:"Connect to it via ssh"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP\n"})}),"\n",(0,o.jsx)(n.p,{children:"On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"All the following commands are performed on the newly started driver VM."})}),"\n",(0,o.jsx)(n.h3,{id:"configuring-openstack-cli-on-the-driver-vm",children:"Configuring openstack CLI on the driver VM"}),"\n",(0,o.jsx)(n.p,{children:"We need to install the openstack client utilities."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo apt-get update\nsudo apt-get install python3-openstackclient\nsudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Configure your cloud access in ",(0,o.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n interface: public\n identity-api-version: 3\n #region_name: REGION\n auth:\n auth_url: KEYSTONE_ENDPOINT\n project_id: PROJECT_UUID\n #alternatively project_name and project_domain_name\n user_domain_name: default\n # change to your real domain\n"})}),"\n",(0,o.jsxs)(n.p,{children:["and ",(0,o.jsx)(n.code,{children:"secure.yaml"})," (in the same directory)"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n auth:\n username: USERNAME\n password: PASSWORD\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"CLOUDNAME"})," can be freely chosen. This is the value passed to the openstack CLI with ",(0,o.jsx)(n.code,{children:"--os-cloud"})," or exported to your environment in ",(0,o.jsx)(n.code,{children:"OS_CLOUD"}),". The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample ",(0,o.jsx)(n.code,{children:"clouds.yaml"})," file that works (but lacks the password)."]}),"\n",(0,o.jsxs)(n.p,{children:["Protect your ",(0,o.jsx)(n.code,{children:"secure.yaml"})," from being read by others: ",(0,o.jsx)(n.code,{children:"chmod 0600 ~/.config/openstack/secure.yaml"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["If you are using application credentials instead of username, password to authenticate, you don't need to specify ",(0,o.jsx)(n.code,{children:"project_id"})," nor project's nor user's domain names in ",(0,o.jsx)(n.code,{children:"clouds.yaml"}),". Just (in ",(0,o.jsx)(n.code,{children:"secure.yaml"}),"):"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'clouds:\n CLOUDNAME:\n auth_type: v3applicationcredential\n auth:\n application_credential_id: APPCRED_ID\n application_credential_secret: "APPCRED_SECRET"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Configure this to be your default cloud:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"export OS_CLOUD=CLOUDNAME\n"})}),"\n",(0,o.jsxs)(n.p,{children:["You might consider adding this to your ",(0,o.jsx)(n.code,{children:"~/.bashrc"})," for convenience. Being at it, you might want to add ",(0,o.jsx)(n.code,{children:"export CLIFF_FIT_WIDTH=1"})," there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste)."]}),"\n",(0,o.jsx)(n.p,{children:"Verify that your openstack CLI works:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack catalog list\nopenstack server list\n"})}),"\n",(0,o.jsx)(n.p,{children:"You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases."}),"\n",(0,o.jsx)(n.h3,{id:"custom-ca",children:"Custom CA"}),"\n",(0,o.jsxs)(n.p,{children:["If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in ",(0,o.jsx)(n.code,{children:"/etc/ssl/certs/ca-certificates.crt"}),". You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the ",(0,o.jsx)(n.code,{children:"debian"})," user."]}),"\n",(0,o.jsxs)(n.p,{children:["Add it to your ",(0,o.jsx)(n.code,{children:"clouds.yaml"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"clouds:\n CLOUDNAME:\n cacert: /PATH/TO/CACERT.CRT\n [...]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If you want to allow ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"export OS_CACERT=/PATH/TO/CACERT.CRT\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Consider adding this to your ",(0,o.jsx)(n.code,{children:"~/.bashrc"})," as well."]}),"\n",(0,o.jsxs)(n.h2,{id:"your-first-api_monitorsh-iteration",children:["Your first ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," iteration"]}),"\n",(0,o.jsx)(n.p,{children:"Checkout openstack-health-monitor:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install git bc jq netcat-traditional tmux zstd\ngit clone https://github.com/SovereignCloudStack/openstack-health-monitor\ncd openstack-health-monitor\n"})}),"\n",(0,o.jsxs)(n.p,{children:["You may want to start a ",(0,o.jsx)(n.code,{children:"tmux"})," (or ",(0,o.jsx)(n.code,{children:"screen"}),") session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect."]}),"\n",(0,o.jsxs)(n.p,{children:["The script ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"})," file."]}),"\n",(0,o.jsxs)(n.p,{children:["It is good practice to use ",(0,o.jsx)(n.code,{children:"tmux"}),". This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to ",(0,o.jsx)(n.code,{children:"screen"})," over ",(0,o.jsx)(n.code,{children:"tmux"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'export IMG="Debian 12"\nexport JHIMG="Debian 12"\n./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Leave out the ",(0,o.jsx)(n.code,{children:"-LL"})," if you don't have a working loadbalancer service or replace ",(0,o.jsx)(n.code,{children:"-LL"})," with ",(0,o.jsx)(n.code,{children:"-LO"})," if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources)."]}),"\n",(0,o.jsxs)(n.p,{children:["Feel free to study the meaning of all the command line parameters by looking at the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"}),". (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)"]}),"\n",(0,o.jsxs)(n.p,{children:["This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs ",(0,o.jsx)(n.code,{children:"DOWN"}),", ",(0,o.jsx)(n.code,{children:"BUILD"}),", ",(0,o.jsx)(n.code,{children:"creating"})," are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual ",(0,o.jsx)(n.code,{children:"openstack RESOURCE list"})," and ",(0,o.jsx)(n.code,{children:"openstack RESOURCE show NAME"})," and ",(0,o.jsx)(n.code,{children:"RESOURCE"})," being something like ",(0,o.jsx)(n.code,{children:"router"}),", ",(0,o.jsx)(n.code,{children:"network"}),", ",(0,o.jsx)(n.code,{children:"subnet"}),", ",(0,o.jsx)(n.code,{children:"port"}),", ",(0,o.jsx)(n.code,{children:"volume"}),", ",(0,o.jsx)(n.code,{children:"server"}),", ",(0,o.jsx)(n.code,{children:"floating ip"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer pool"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer listener"}),", ",(0,o.jsx)(n.code,{children:"security group"}),", ",(0,o.jsx)(n.code,{children:"keypair"}),", ",(0,o.jsx)(n.code,{children:"image"}),", ...)"]}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," uses and ",(0,o.jsx)(n.code,{children:"APIMonitor_TIMESTAMP"})," prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong.\n",(0,o.jsx)(n.code,{children:"TIMESTAMP"})," is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time)."]}),"\n",(0,o.jsxs)(n.p,{children:["This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least ",(0,o.jsx)(n.code,{children:"-N 2"})," to test the ability of the router to route traffic between networks. So expect ",(0,o.jsx)(n.code,{children:"-n 6"})," to become ",(0,o.jsx)(n.code,{children:"-N 2 -n 6"})," for a very small single-AZ cloud or ",(0,o.jsx)(n.code,{children:"-n 12"})," for a large 3 AZ cloud region. So, re-run the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," with the target sizing."]}),"\n",(0,o.jsx)(n.h3,{id:"resource-impact-and-charging",children:"Resource impact and charging"}),"\n",(0,o.jsxs)(n.p,{children:["Note that ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," uses small flavors (",(0,o.jsx)(n.code,{children:"SCS-1V-2"})," for the N jump hosts and ",(0,o.jsx)(n.code,{children:"SCS-1L-1"})," for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors."]}),"\n",(0,o.jsxs)(n.p,{children:["If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," in a loop (which you will) with say 10 VMs (e.g. ",(0,o.jsx)(n.code,{children:"-N 2 -n 8"}),") in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference."]}),"\n",(0,o.jsxs)(n.p,{children:["Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of ",(0,o.jsx)(n.code,{children:"openstack volume list"}),", ",(0,o.jsx)(n.code,{children:"openstack volume show BROKEN_VOLUME"}),", ",(0,o.jsx)(n.code,{children:"openstack loadbalancer list"}),", ",(0,o.jsx)(n.code,{children:"openstack loadbalancer show BROKEN_LB"}),".)"]}),"\n",(0,o.jsxs)(n.p,{children:["Using ",(0,o.jsx)(n.code,{children:"-w -1"})," makes ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," wait for interactive input whenever an error occurs; this can be convenient for debugging."]}),"\n",(0,o.jsx)(n.p,{children:"Once you have single iterations working nicely, we can proceed."}),"\n",(0,o.jsx)(n.h2,{id:"automating-startup-and-cleanup",children:"Automating startup and cleanup"}),"\n",(0,o.jsxs)(n.p,{children:["Typically, we run ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'#!/bin/bash\n# run_CLOUDNAME.sh\n# Do some global settings\nexport IMG="Debian 12"\nexport JHIMG="Debian 12"\n#export OS_CACERT=/home/debian/ca-certificates.pem\n# Additional settings to override flavors or to\n# configure email addresses for sending alarms can be set here\n\n# Does openstack CLI work?\nopenstack server list >/dev/null || exit 1\n# Upload log files to this swift container (which you need to create)\n#export SWIFTCONTAINER=OS-HM-Logfiles\n\n# CLEANUP\necho "Finding resources from previous runs to clean up ..."\n# Find Floating IPs\nFIPLIST=""\nFIPS=$(openstack floating ip list -f value -c ID)\nfor fip in $FIPS; do\n FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")\n if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_\n"; fi\ndone\nFIPLIST=$(echo "$FIPLIST" | grep -v \'^$\' | sort -u)\n# Cleanup previous interrupted runs\nSERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nKEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nVOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nNETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nLOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nSECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)\necho CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS\nfor ENV in $FIPLIST; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV\n echo "******************************"\ndone\nTOCLEAN=$(echo "$SERVERS\n$KEYPAIR\n$VOLUMES\n$NETWORK\n$LOADBAL\n$ROUTERS\n$SECGRPS\n" | grep -v \'^$\' | sort -u)\nfor ENV in $TOCLEAN; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV\n echo "******************************"\ndone\n\n# Now run the monitor\n#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"\nexec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Compared to the previous run, we have explicitly set two networks here ",(0,o.jsx)(n.code,{children:"-N 2"})," and rely on the iterations being passed in as command line arguments. Add parameter ",(0,o.jsx)(n.code,{children:"-t"})," if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (",(0,o.jsx)(n.code,{children:"-LO"}),") in this example rather than the amphora based one (",(0,o.jsx)(n.code,{children:"-LL"}),")."]}),"\n",(0,o.jsxs)(n.p,{children:["You may use one of the existing ",(0,o.jsx)(n.code,{children:"run_XXXX.sh"})," scripts as example. Beware: eMail alerting with ",(0,o.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESS"})," and ",(0,o.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESS"})," (and limiting with ",(0,o.jsx)(n.code,{children:"-a"})," and ",(0,o.jsx)(n.code,{children:"-R"})," ) and reporting data to telegraf (option ",(0,o.jsx)(n.code,{children:"-S"}),") may be present in the samples. Make this script executable (",(0,o.jsx)(n.code,{children:"chmod +x run_CLOUDNAME.sh"}),")."]}),"\n",(0,o.jsxs)(n.p,{children:["We wrap a loop around this in ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'#!/bin/bash\n# run_in_loop.sh\nrm stop-os-hm 2>/dev/null\nwhile true; do\n ./run_CLOUDNAME.sh -i 200\n if test -e stop-os-hm; then break; fi\n echo -n "Hit ^C to abort ..."\n sleep 15; echo\ndone\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Also make this executable (",(0,o.jsx)(n.code,{children:"chmod +x run_in_loop.sh"}),").\nTo run this automatically in a tmux window whenever the system starts, we follow the steps in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/startup/README.md",children:"startup README.md"})]}),"\n",(0,o.jsxs)(n.p,{children:["Change ",(0,o.jsx)(n.code,{children:"OS_CLOUD"})," in ",(0,o.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"}),". (If you need to set ",(0,o.jsx)(n.code,{children:"OS_CACERT"}),", also add it in this file and pass it into the windows.)"]}),"\n",(0,o.jsx)(n.p,{children:"Activate everything:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"mkdir -p ~/.config/systemd/user/\ncp -p startup/apimon.service ~/.config/systemd/user/\nsystemctl --user enable apimon\nsystemctl --user start apimon\nsudo loginctl enable-linger debian\ntmux attach oshealthmon\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This assumes that you are using the user ",(0,o.jsx)(n.code,{children:"debian"})," for this monitoring and have checked out the repository at ",(0,o.jsx)(n.code,{children:"~/openstack-health-monitor/"}),". Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)"]}),"\n",(0,o.jsx)(n.h3,{id:"changing-parameters-and-restarting",children:"Changing parameters and restarting"}),"\n",(0,o.jsxs)(n.p,{children:["If you want to change the parameters passed to ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),", you best do this by editing ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),", potentially after testing it with one iteration before."]}),"\n",(0,o.jsxs)(n.p,{children:["To make the change effective, you can wait until the current 200 iterations are completed and the ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"})," calls ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," again. You can also hit ",(0,o.jsx)(n.code,{children:"^C"})," in the tmux window that has",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ",(0,o.jsx)(n.code,{children:"^C"})," during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ",(0,o.jsx)(n.code,{children:"^C"})," twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ",(0,o.jsx)(n.code,{children:"./run_in_loop.sh"})," again."]}),"\n",(0,o.jsxs)(n.p,{children:["You can also issue the ",(0,o.jsx)(n.code,{children:"systemctl --user stop apimon"})," command; it will basically do the same thing: Send ",(0,o.jsx)(n.code,{children:"^C"})," and then wait for everything to be completed and tear down the tmux session.\nAfter waiting for that to complete, you can start it again with ",(0,o.jsx)(n.code,{children:"systemctl --user start apimon"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"multiple-instances",children:"Multiple instances"}),"\n",(0,o.jsxs)(n.p,{children:["You can run multiple instances of ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," on the same driver VM. In this case, you should rename ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"})," to e.g. ",(0,o.jsx)(n.code,{children:"run_in_loop_CLOUDNAME1.sh"})," and call ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME1.sh"})," from there. Don't forget to adjust ",(0,o.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"})," and ",(0,o.jsx)(n.code,{children:"startup/kill-apimon-in-tmux.sh"})," to start more windows."]}),"\n",(0,o.jsxs)(n.p,{children:["It is not recommended to run multiple instances against the same OpenStack project however. While the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations."]}),"\n",(0,o.jsx)(n.h2,{id:"alarming-and-logs",children:"Alarming and Logs"}),"\n",(0,o.jsx)(n.h3,{id:"email",children:"eMail"}),"\n",(0,o.jsxs)(n.p,{children:["If wanted, the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the ",(0,o.jsx)(n.code,{children:"-a N"})," and ",(0,o.jsx)(n.code,{children:"-R"})," options. In order to enable sending emails from the driver VM, it needs to have ",(0,o.jsx)(n.code,{children:"postfix"})," (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly."]}),"\n",(0,o.jsxs)(n.p,{children:["Once you have configured ",(0,o.jsx)(n.code,{children:"postfix"}),", you can enable eMail notifications using the option ",(0,o.jsx)(n.code,{children:"-e"}),". Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ",(0,o.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESSES"})," and ",(0,o.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESSES"})," environment variables to ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),", e.g. by setting it in the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"log-files",children:"Log files"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"api_monitor.sh"})," writes a log file with the name ",(0,o.jsx)(n.code,{children:"APIMonitor_TIMESTAMP.log"}),". It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (",(0,o.jsx)(n.code,{children:"TIMESTAMP"})," is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)"]}),"\n",(0,o.jsxs)(n.p,{children:["Note that ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties."]}),"\n",(0,o.jsxs)(n.p,{children:["The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable ",(0,o.jsx)(n.code,{children:"SWIFTCONTAINER"})," has been set (in ",(0,o.jsx)(n.code,{children:"run_COULDNAME.sh"}),") when starting ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),". the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: ",(0,o.jsx)(n.code,{children:"export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER"})]}),"\n",(0,o.jsxs)(n.p,{children:["After the 200 iterations, a ",(0,o.jsx)(n.code,{children:".psv"})," file (pipe-separated values) is created ",(0,o.jsx)(n.code,{children:"Stats.STARTTIME-ENDTIME.psv"})," (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured)."]}),"\n",(0,o.jsx)(n.h2,{id:"data-collection-and-dashboard",children:"Data collection and dashboard"}),"\n",(0,o.jsxs)(n.p,{children:["See ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md",children:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md"})]}),"\n",(0,o.jsx)(n.h3,{id:"telegraf",children:"telegraf"}),"\n",(0,o.jsx)(n.p,{children:"To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key\necho "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list\nsudo apt update\nsudo apt -y install telegraf\n'})}),"\n",(0,o.jsxs)(n.p,{children:["In the config file ",(0,o.jsx)(n.code,{children:"/etc/telegraf/telegraf.conf"}),", we enable"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'[[inputs.influxdb_listener]]\n service_address = ":8186"\n\n[[outputs.influxdb]]\n urls = ["http://127.0.0.1:8086"]\n'})}),"\n",(0,o.jsxs)(n.p,{children:["and restart the service (",(0,o.jsx)(n.code,{children:"sudo systemctl restart telegraf"}),").\nEnable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable telegraf"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"influxdb",children:"influxdb"}),"\n",(0,o.jsx)(n.p,{children:"We proceed to influxdb:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo apt-get install influxdb\n"})}),"\n",(0,o.jsxs)(n.p,{children:["In the configuration file ",(0,o.jsx)(n.code,{children:"/etc/influxdb/influxdb.conf"}),", ensure that the http interface on port 8086 is enabled."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'[http]\n enabled = true\n bind-address = ":8086"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Restart influxdb as needed with ",(0,o.jsx)(n.code,{children:"sudo systemctl restart influxdb"}),".\nAlso enable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable influxdb"}),"."]}),"\n",(0,o.jsxs)(n.h3,{id:"add--s-cloudname-to-your-run_cloudnamesh-script",children:["Add ",(0,o.jsx)(n.code,{children:"-S CLOUDNAME"})," to your ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script"]}),"\n",(0,o.jsxs)(n.p,{children:["You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter ",(0,o.jsx)(n.code,{children:"-S CLOUDNAME"})," to the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," call in ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),". Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete)."]}),"\n",(0,o.jsx)(n.h3,{id:"grafana",children:"grafana"}),"\n",(0,o.jsx)(n.h4,{id:"basic-config",children:"Basic config"}),"\n",(0,o.jsxs)(n.p,{children:["Finally grafana: We (still as root) follow ",(0,o.jsx)(n.a,{href:"https://www.server-world.info/en/note?os=Debian_12&p=grafana",children:"https://www.server-world.info/en/note?os=Debian_12&p=grafana"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'sudo wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key\necho "deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list\nsudo apt update\nsudo apt -y install grafana\n'})}),"\n",(0,o.jsxs)(n.p,{children:["The config file ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," needs some adjustments:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Set the hostname in ",(0,o.jsx)(n.code,{children:"[server]"})," section: ",(0,o.jsx)(n.code,{children:"domain = health.YOURCLOUD.sovereignit.cloud"}),". Set the ",(0,o.jsx)(n.code,{children:"protocol = https"})," if not enabled by default.\nYou can use a hostname of your liking, but we will need to create TLS certificates for this host. So we should have control over DNS TXT records for this domain if we want to use Let's Encrypt with DNSAUTH. The ",(0,o.jsx)(n.code,{children:"sovereignit.cloud"})," domain is controlled by the SCS project team and has been used for a number of health mon instances.\nIn this same section, set ",(0,o.jsx)(n.code,{children:"cert_file = /etc/grafana/health-fullchain.pem"})," and ",(0,o.jsx)(n.code,{children:"cert_key = /etc/grafana/health-key.pem"}),". Ensure that both files are readable by ",(0,o.jsx)(n.code,{children:"root:grafana"})," and that the key file is ",(0,o.jsx)(n.em,{children:"not"})," world-readable."]}),"\n",(0,o.jsxs)(n.li,{children:["Configure the admin access. In section ",(0,o.jsx)(n.code,{children:"[security]"}),", set the ",(0,o.jsx)(n.code,{children:"admin_user = admin"})," and ",(0,o.jsx)(n.code,{children:"admin_password = SOME_SECRET_PASS"})," which you keep private."]}),"\n",(0,o.jsxs)(n.li,{children:["Allow local data sources (same section): ",(0,o.jsx)(n.code,{children:"data_source_proxy_whitelist = localhost:8088 localhost:8086"})]}),"\n",(0,o.jsxs)(n.li,{children:["Let's disallow user signup (in section ",(0,o.jsx)(n.code,{children:"[users]"}),"): ",(0,o.jsx)(n.code,{children:"allow_sign_up = false"})," and ",(0,o.jsx)(n.code,{children:"allow_org_create = false"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["We do the OIDC connection with ",(0,o.jsx)(n.code,{children:"[auth.github]"})," later."]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["We can now restart the service: ",(0,o.jsx)(n.code,{children:"sudo systemctl restart grafana-server"}),".\nBeing at it, also enable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable grafana-server"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["You should now be able to access your dashboard on ",(0,o.jsx)(n.code,{children:"https://health.YOURCLOUD.sovereignit.de:3000"})," and log in via the configured username ",(0,o.jsx)(n.code,{children:"admin"})," and your ",(0,o.jsx)(n.code,{children:"SOME_SECRET_PASS"})," password."]}),"\n",(0,o.jsx)(n.h4,{id:"enable-influx-database-in-grafana",children:"Enable influx database in grafana"}),"\n",(0,o.jsxs)(n.p,{children:["In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to ",(0,o.jsx)(n.code,{children:"http://localhost:8086"})," (despite this being the suggestion). Set the database name to ",(0,o.jsx)(n.code,{children:"telegraf"}),". Save&test should succeed."]}),"\n",(0,o.jsx)(n.h4,{id:"importing-the-dashboard",children:"Importing the dashboard"}),"\n",(0,o.jsxs)(n.p,{children:["Go to Home, Dashboards, New, Import.\nUpload the dashboard ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard.json",children:".json file"})," from the repository, user the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard-10.json",children:"Grafana-10 variant"})," if you use Grafana 10 or newer."]}),"\n",(0,o.jsx)(n.p,{children:"In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.)\nSave."}),"\n",(0,o.jsx)(n.p,{children:"Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable)."}),"\n",(0,o.jsx)(n.h4,{id:"no-data-displayed",children:"No data displayed?"}),"\n",(0,o.jsx)(n.p,{children:'Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.'}),"\n",(0,o.jsx)(n.p,{children:"One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved."}),"\n",(0,o.jsx)(n.h4,{id:"dashboard-features",children:"Dashboard features"}),"\n",(0,o.jsx)(n.p,{children:"Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended."}),"\n",(0,o.jsx)(n.p,{children:"The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously."}),"\n",(0,o.jsx)(n.p,{children:"You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term."}),"\n",(0,o.jsx)(n.h4,{id:"github-oidc-integration",children:"github OIDC integration"}),"\n",(0,o.jsxs)(n.p,{children:["The SCS providers do allow all github users that belong to the SovereignCloudStack organization to get Viewer access to the dashboards by adding a ",(0,o.jsx)(n.code,{children:"client_id"})," and ",(0,o.jsx)(n.code,{children:"client_secret"})," in the ",(0,o.jsx)(n.code,{children:"[github.auth]"})," section that you request from the SCS github admins (github's oauth auth). This allows to exchange experience and to get a feeling for the achievable stability. (Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)"]}),"\n",(0,o.jsx)(n.h2,{id:"alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy",children:"Alternative approach to install and configure the dashboard behind a reverse proxy"}),"\n",(0,o.jsxs)(n.p,{children:["Install influxdb via apt: ",(0,o.jsx)(n.a,{href:"https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss",children:"https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss"}),"\nInstall telegraf (same apt repo as influxdb): ",(0,o.jsx)(n.code,{children:"sudo apt update && sudo apt install telegraf"}),"\nInstall grafana: ",(0,o.jsx)(n.a,{href:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository",children:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository"})]}),"\n",(0,o.jsx)(n.p,{children:"Prepare configuration by using the config files from the repository as an alternative to doing the changes manually (as described above):"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo cp dashboard/telegraf.conf /etc/telegraf && sudo chown root:root /etc/telegraf/telegraf.conf && sudo chmod 0644 /etc/telegraf/telegraf.conf\nsudo cp dashboard/config.toml /etc/influxdb && sudo chown root:influxdb /etc/influxdb/config.toml && sudo chmod 0640 /etc/influxdb/config.toml\nsudo cp dashboard/grafana.ini /etc/grafana && sudo chown root:grafana /etc/grafana/grafana.ini && sudo chmod 0640 /etc/grafana/grafana.ini\n"})}),"\n",(0,o.jsx)(n.p,{children:"These config files should work as long as the versions of telegraf, influxdb and grafana don't evolve too far from the ones used in the repository. (Otherwise refer to above instructions how to tweak the default config files.)"}),"\n",(0,o.jsxs)(n.p,{children:["Changes to ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," as we do tls termination at the reverse proxy:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["set ",(0,o.jsx)(n.code,{children:"protocol = http"})]}),"\n",(0,o.jsxs)(n.li,{children:["comment out ",(0,o.jsx)(n.code,{children:"domain"})," option (? FIXME) or set it to the hostname"]}),"\n",(0,o.jsxs)(n.li,{children:["comment out ",(0,o.jsx)(n.code,{children:"cert_*"})," options"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Also change the admin password in ",(0,o.jsx)(n.code,{children:"grafana.ini"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Changes to ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," if github auth should not be used yet:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["comment out whole ",(0,o.jsx)(n.code,{children:"[auth.github]"})," section for now (can be enabled later)"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Restart services: ",(0,o.jsx)(n.code,{children:"sudo systemctl restart telegraf && sudo systemctl restart influxdb && sudo systemctl restart grafana-server"})]}),"\n",(0,o.jsx)(n.p,{children:"Configuration in grafana web gui:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Login to grafana ",(0,o.jsx)(n.code,{children:"http(s)://<domain>:3000"})," with user admin and default password from ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," and change password."]}),"\n",(0,o.jsxs)(n.li,{children:["Create influxdb datasource with url ",(0,o.jsx)(n.code,{children:"http://localhost:8086"})," and database name ",(0,o.jsx)(n.code,{children:"telegraf"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Finally import dashboard ",(0,o.jsx)(n.code,{children:"dashboard/openstack-health-dashboard.json"})," to grafana."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"TODO:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Reverse proxy (aka ingress) with Let's Encrypt cert"}),"\n",(0,o.jsx)(n.li,{children:"Github auth as described above"}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"maintenance",children:"Maintenance"}),"\n",(0,o.jsx)(n.p,{children:"The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained."}),"\n",(0,o.jsx)(n.h3,{id:"unattended-upgrades",children:"Unattended upgrades"}),"\n",(0,o.jsxs)(n.p,{children:["It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See ",(0,o.jsx)(n.a,{href:"https://wiki.debian.org/UnattendedUpgrades",children:"https://wiki.debian.org/UnattendedUpgrades"}),". If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and grafana (port 3000)."]}),"\n",(0,o.jsx)(n.h3,{id:"updating-openstack-health-monitor",children:"Updating openstack-health-monitor"}),"\n",(0,o.jsxs)(n.p,{children:["You can just do a ",(0,o.jsx)(n.code,{children:"git update"})," in the ",(0,o.jsx)(n.code,{children:"openstack-health-monitor"})," directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ",(0,o.jsx)(n.code,{children:"^C"}),", see above in the restart section."]}),"\n",(0,o.jsx)(n.h3,{id:"backup",children:"Backup"}),"\n",(0,o.jsxs)(n.p,{children:["The system holds two things that you might consider valuable for long-term storage:\n(1) The log files. These are compressed and uploaded to object storage if you enable the ",(0,o.jsx)(n.code,{children:"SWIFTCONTAINER"})," setting, which probably means that these do not need any additional backing up then.\n(2) The influx time series data. Back up the data in ",(0,o.jsx)(n.code,{children:"/var/lib/influxdb"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, ",(0,o.jsx)(n.code,{children:"clouds.yaml"}),", etc. Be careful not to expose sensitive data by granting too generous access to your backed up files."]}),"\n",(0,o.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsx)(n.h3,{id:"debugging-issues",children:"Debugging issues"}),"\n",(0,o.jsx)(n.p,{children:"In case there is trouble with your cloud, the normal course of action to analyze is as follows:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Look at the dashboard (see above)"}),"\n",(0,o.jsxs)(n.li,{children:["Connect to the driver VM and attach to the tmux session and look at the console output of ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})]}),"\n",(0,o.jsx)(n.li,{children:"Analyze the logfile (locally on the driver VM or grab it from the object storage)"}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"analyzing-failures",children:"Analyzing failures"}),"\n",(0,o.jsxs)(n.p,{children:["When VM instances are created successfully, but then end up in ",(0,o.jsx)(n.code,{children:"ERROR"})," state, the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," does an explicit ",(0,o.jsx)(n.code,{children:"openstack server show"}),", so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files."]}),"\n",(0,o.jsxs)(n.p,{children:["Sometimes the VMs end up being ",(0,o.jsx)(n.code,{children:"ACTIVE"})," as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail."]}),"\n",(0,o.jsxs)(n.p,{children:["To gather more details, you can look at the console output ",(0,o.jsx)(n.code,{children:"openstack console log show VM"})," (where ",(0,o.jsx)(n.code,{children:"VM"})," is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ",(0,o.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_JH.pem debian@FIP"}),", whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ",(0,o.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP"}),". Replace ",(0,o.jsx)(n.code,{children:"XXXXX"})," with the number in your current APIMonitor prefix, ",(0,o.jsx)(n.code,{children:"FIP"})," with the floating IP address of the responsible JumpHost and ",(0,o.jsx)(n.code,{children:"debian"})," with the user name used by the images you boot. Use ",(0,o.jsx)(n.code,{children:"223"})," to connect to the second VM in the network, ",(0,o.jsx)(n.code,{children:"224"})," the third etc."]}),"\n",(0,o.jsxs)(n.p,{children:["When logged in, look at ",(0,o.jsx)(n.code,{children:"/var/log/cloud-init-output.log"})," and ",(0,o.jsx)(n.code,{children:"/var/log/cloud-init.log"}),". You can find the metadata in ",(0,o.jsx)(n.code,{children:"/var/lib/cloud/instance/"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["You will not have much time to look around -- the still running ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," script does continue and clean things up again. So you might want to suspend it with ",(0,o.jsx)(n.code,{children:"^Z"})," (and continue it later with ",(0,o.jsx)(n.code,{children:"fg"}),"). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script as it would do cleanup against the running instance, but rather copy the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," command line from the bottom (without the ",(0,o.jsx)(n.code,{children:"exec"}),"), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach ",(0,o.jsx)(n.code,{children:"-w -1"})," to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work."]}),"\n",(0,o.jsx)(n.h3,{id:"cleaning-things-up",children:"Cleaning things up"}),"\n",(0,o.jsx)(n.p,{children:"If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard)."}),"\n",(0,o.jsx)(n.p,{children:"There are a few things that may need support from a cloud admin:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Volumes may end up permanently in a ",(0,o.jsx)(n.code,{children:"deleting"})," or ",(0,o.jsx)(n.code,{children:"reserved"})," state or may be ",(0,o.jsx)(n.code,{children:"in-use"}),", attached to a VM that has long gone. The admin needs to set the state to ",(0,o.jsx)(n.code,{children:"error"})," and then delete them."]}),"\n",(0,o.jsxs)(n.li,{children:["Loadbalancers may end up in a ",(0,o.jsx)(n.code,{children:"PENDING_XXX"})," state (",(0,o.jsx)(n.code,{children:"XXX"})," being ",(0,o.jsx)(n.code,{children:"CREATE"}),", ",(0,o.jsx)(n.code,{children:"UPDATE"})," or ",(0,o.jsx)(n.code,{children:"DELETE"}),") without ever changing. This also needs the cloud admin to set the status to ",(0,o.jsx)(n.code,{children:"ERROR"}),", so it can be cleaned up. amphorae are more prone to this than ovn LBs."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted."}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsxs)(n.em,{children:["The source of this document can be found in the ",(0,o.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/openstack-health-monitor/main/docs/Debian12-Install.md",children:"SovereignCloudStack/openstack-health-monitor"})," repository."]})}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.em,{children:"Author: SCS Community, License: CC by Attribution 4.0 International"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var o=t(96540);const s={},a=o.createContext(s);function i(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8e8909f7.62db56cb.js b/assets/js/8e8909f7.62db56cb.js new file mode 100644 index 0000000000..029c988708 --- /dev/null +++ b/assets/js/8e8909f7.62db56cb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9407],{98894:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>r,toc:()=>a});var s=i(74848),t=i(28453);const o={sidebar_label:"Skyline"},l="Skyline",r={id:"iaas/guides/configuration-guide/openstack/skyline",title:"Skyline",description:"Skyline APIServer",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/skyline.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/skyline",permalink:"/docs/iaas/guides/configuration-guide/openstack/skyline",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/skyline.md",tags:[],version:"current",frontMatter:{sidebar_label:"Skyline"},sidebar:"docs",previous:{title:"Placement",permalink:"/docs/iaas/guides/configuration-guide/openstack/placement"},next:{title:"Commons",permalink:"/docs/iaas/guides/configuration-guide/commons/"}},c={},a=[{value:"Skyline APIServer",id:"skyline-apiserver",level:2},{value:"Skyline Console",id:"skyline-console",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",li:"li",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"skyline",children:"Skyline"}),"\n",(0,s.jsx)(n.h2,{id:"skyline-apiserver",children:"Skyline APIServer"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/skyline-apiserver/latest/configuration/settings.html",children:"Skyline APIServer configuration reference"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"skyline-console",children:"Skyline Console"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/skyline-console/latest/admin/index.html",children:"Skyline Console admin guide"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/skyline-console/latest/configuration/skyline-console-settings.html",children:"Skyline Console configuration reference"})}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>l,x:()=>r});var s=i(96540);const t={},o=s.createContext(t);function l(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8fc094a7.8dc38e73.js b/assets/js/8fc094a7.8dc38e73.js new file mode 100644 index 0000000000..77c007973e --- /dev/null +++ b/assets/js/8fc094a7.8dc38e73.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6251],{79736:(e,a,n)=>{n.r(a),n.d(a,{assets:()=>d,contentTitle:()=>o,default:()=>g,frontMatter:()=>s,metadata:()=>r,toc:()=>c});var t=n(74848),i=n(28453);const s={sidebar_label:"Manager",sidebar_position:10},o="Manager",r={id:"iaas/guides/operations-guide/manager/index",title:"Manager",description:"OSISM orchestrator",source:"@site/docs/02-iaas/guides/operations-guide/manager/index.md",sourceDirName:"02-iaas/guides/operations-guide/manager",slug:"/iaas/guides/operations-guide/manager/",permalink:"/docs/iaas/guides/operations-guide/manager/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/manager/index.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Manager",sidebar_position:10},sidebar:"docs",previous:{title:"Operations Guide",permalink:"/docs/iaas/guides/operations-guide/"},next:{title:"Apply",permalink:"/docs/iaas/guides/operations-guide/manager/apply"}},d={},c=[];function u(e){const a={h1:"h1",img:"img",p:"p",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(a.h1,{id:"manager",children:"Manager"}),"\n",(0,t.jsx)(a.p,{children:(0,t.jsx)(a.img,{alt:"OSISM orchestrator",src:n(5479).A+"",width:"1303",height:"591"})})]})}function g(e={}){const{wrapper:a}={...(0,i.R)(),...e.components};return a?(0,t.jsx)(a,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},5479:(e,a,n)=>{n.d(a,{A:()=>t});const t=n.p+"assets/images/python-osism.drawio-19e90813de60b4afa58bc7ee4a3aeae8.png"},28453:(e,a,n)=>{n.d(a,{R:()=>o,x:()=>r});var t=n(96540);const i={},s=t.createContext(i);function o(e){const a=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function r(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(s.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9099a3d2.aa79434b.js b/assets/js/9099a3d2.aa79434b.js new file mode 100644 index 0000000000..104e44a084 --- /dev/null +++ b/assets/js/9099a3d2.aa79434b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6172],{73016:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>a,frontMatter:()=>l,metadata:()=>t,toc:()=>h});var i=s(74848),r=s(28453);const l={},c="Central services",t={id:"central-services/plusserver-gx-scs",title:"Central services",description:"This document gives an overview of what SCS central services are deployed and who is responsible for them in plusserver gx-scs infrastructure.",source:"@site/community/central-services/plusserver-gx-scs.md",sourceDirName:"central-services",slug:"/central-services/plusserver-gx-scs",permalink:"/community/central-services/plusserver-gx-scs",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{}},o={},h=[{value:"Project p500924-harbor",id:"project-p500924-harbor",level:2},{value:"K8s clusters",id:"k8s-clusters",level:3},{value:"Harbor",id:"harbor",level:4},{value:"Project p500924-sig-monitoring1",id:"project-p500924-sig-monitoring1",level:2},{value:"K8s clusters",id:"k8s-clusters-1",level:3},{value:"Monitoring",id:"monitoring",level:4}];function d(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"central-services",children:"Central services"}),"\n",(0,i.jsx)(n.p,{children:"This document gives an overview of what SCS central services are deployed and who is responsible for them in plusserver gx-scs infrastructure."}),"\n",(0,i.jsx)(n.h2,{id:"project-p500924-harbor",children:"Project p500924-harbor"}),"\n",(0,i.jsx)(n.h3,{id:"k8s-clusters",children:"K8s clusters"}),"\n",(0,i.jsx)(n.h4,{id:"harbor",children:"Harbor"}),"\n",(0,i.jsxs)(n.p,{children:["Responsibility: ",(0,i.jsx)(n.a,{href:"https://github.com/orgs/SovereignCloudStack/teams/vp06c",children:"@SovereignCloudStack/vp06c"})]}),"\n",(0,i.jsx)(n.p,{children:"Services:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://registry.scs.community/",children:"SCS Registry"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-harbor/tree/main/envs/public",children:"k8s-harbor"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Utilization:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Instances: 7"}),"\n",(0,i.jsx)(n.li,{children:"VCPUs: 32"}),"\n",(0,i.jsx)(n.li,{children:"RAM: 64GB"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Spec:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"version: v7.0.0 - R6"}),"\n",(0,i.jsxs)(n.li,{children:["management cluster:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"1 instance: SCS-2V:4:20"}),"\n",(0,i.jsx)(n.li,{children:"image: Ubuntu 22.04 (20230416)"}),"\n",(0,i.jsx)(n.li,{children:"k8s: v1.25.3 - KinD"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["workload cluster:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["6 instances:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"3 control-planes: SCS-2V:4:20"}),"\n",(0,i.jsx)(n.li,{children:"3 workers: SCS-8V:16:100"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:"image: ubuntu-capi-image-v1.28.7"}),"\n",(0,i.jsx)(n.li,{children:"k8s: v1.28.7"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"project-p500924-sig-monitoring1",children:"Project p500924-sig-monitoring1"}),"\n",(0,i.jsx)(n.h3,{id:"k8s-clusters-1",children:"K8s clusters"}),"\n",(0,i.jsx)(n.h4,{id:"monitoring",children:"Monitoring"}),"\n",(0,i.jsxs)(n.p,{children:["Responsibility: ",(0,i.jsx)(n.a,{href:"https://github.com/orgs/SovereignCloudStack/teams/vp06c",children:"@SovereignCloudStack/vp06c"})]}),"\n",(0,i.jsx)(n.p,{children:"Services:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-observability",children:"k8s-observability"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Utilization:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Instances: 7"}),"\n",(0,i.jsx)(n.li,{children:"VCPUs: 32"}),"\n",(0,i.jsx)(n.li,{children:"RAM: 64GB"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Spec:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"version: v6.0.0 - R5"}),"\n",(0,i.jsxs)(n.li,{children:["management cluster:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"1 instance: SCS-2V:4:20"}),"\n",(0,i.jsx)(n.li,{children:"image: Ubuntu 22.04 (20231211)"}),"\n",(0,i.jsx)(n.li,{children:"k8s: v1.27.3 - KinD"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["workload cluster:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["6 instances:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"3 control-planes: SCS-2V:4:20"}),"\n",(0,i.jsx)(n.li,{children:"3 workers: SCS-8V:16:100"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:"image: ubuntu-capi-image-v1.27.5"}),"\n",(0,i.jsx)(n.li,{children:"k8s: v1.27.5"}),"\n"]}),"\n"]}),"\n"]})]})}function a(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>t});var i=s(96540);const r={},l=i.createContext(r);function c(e){const n=i.useContext(l);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),i.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/915e2cf4.5887122e.js b/assets/js/915e2cf4.5887122e.js new file mode 100644 index 0000000000..f903bc8c1e --- /dev/null +++ b/assets/js/915e2cf4.5887122e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9260],{45410:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>l});var i=a(74848),t=a(28453);const s={sidebar_label:"User Data Backups"},r="User Data Backups",c={id:"iaas/guides/user-guide/openstack/user-data-backups",title:"User Data Backups",description:"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.",source:"@site/docs/02-iaas/guides/user-guide/openstack/user-data-backups.md",sourceDirName:"02-iaas/guides/user-guide/openstack",slug:"/iaas/guides/user-guide/openstack/user-data-backups",permalink:"/docs/iaas/guides/user-guide/openstack/user-data-backups",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/openstack/user-data-backups.md",tags:[],version:"current",frontMatter:{sidebar_label:"User Data Backups"},sidebar:"docs",previous:{title:"Security groups",permalink:"/docs/iaas/guides/user-guide/openstack/security-groups"},next:{title:"Best Practise: How to configure and use security groups",permalink:"/docs/iaas/guides/user-guide/security-groups/"}},o={},l=[{value:"Glossary",id:"glossary",level:2},{value:"Scope",id:"scope",level:2},{value:"Overview of applicable User Data",id:"overview-of-applicable-user-data",level:3},{value:"Image backup using download",id:"image-backup-using-download",level:2},{value:"Ephemeral Storage backup using Glance images",id:"ephemeral-storage-backup-using-glance-images",level:2},{value:"Volume data backup using Cinder Backup API",id:"volume-data-backup-using-cinder-backup-api",level:2},{value:"Backup of detached volumes",id:"backup-of-detached-volumes",level:3},{value:"Backup of attached volumes",id:"backup-of-attached-volumes",level:3},{value:"Volume data backup using Glance images",id:"volume-data-backup-using-glance-images",level:2},{value:"Glance image backups of detached volumes",id:"glance-image-backups-of-detached-volumes",level:3},{value:"Glance image backups of attached (in-use) volumes",id:"glance-image-backups-of-attached-in-use-volumes",level:3},{value:"Barbican secrets backup using download",id:"barbican-secrets-backup-using-download",level:2},{value:"Retrieving encryption keys from Barbican",id:"retrieving-encryption-keys-from-barbican",level:3},{value:"Restore",id:"restore",level:2},{value:"Restoring a backup of a Barbican secret",id:"restoring-a-backup-of-a-barbican-secret",level:3},{value:"Restoring a backup of an unencrypted image",id:"restoring-a-backup-of-an-unencrypted-image",level:3},{value:"Restoring a backup of an encrypted image",id:"restoring-a-backup-of-an-encrypted-image",level:3},{value:"Restoring a volume backup from an image",id:"restoring-a-volume-backup-from-an-image",level:3},{value:"Restoring a volume backup from the Cinder Backup service",id:"restoring-a-volume-backup-from-the-cinder-backup-service",level:3},{value:"Restoring to a new volume (Cinder Backup)",id:"restoring-to-a-new-volume-cinder-backup",level:4},{value:"Restoring on an existing volume (Cinder Backup)",id:"restoring-on-an-existing-volume-cinder-backup",level:4},{value:"Restoring an encrypted volume backup (Cinder Backup)",id:"restoring-an-encrypted-volume-backup-cinder-backup",level:4},{value:"Appendix",id:"appendix",level:2},{value:"Image creation action for servers with attached volumes",id:"image-creation-action-for-servers-with-attached-volumes",level:3},{value:"LUKS encryption key conversion to decrypt volume images",id:"luks-encryption-key-conversion-to-decrypt-volume-images",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"user-data-backups",children:"User Data Backups"}),"\n",(0,i.jsx)(n.p,{children:"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks."}),"\n",(0,i.jsx)(n.h2,{id:"glossary",children:"Glossary"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Term"}),(0,i.jsx)(n.th,{children:"Explanation"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Virtual Machine"}),(0,i.jsxs)(n.td,{children:["Equals the ",(0,i.jsx)(n.code,{children:"server"})," resource in Nova."]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Ephemeral Storage"}),(0,i.jsx)(n.td,{children:"Disk storage directly supplied to a virtual machine by Nova. Different from volumes."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"(Glance) Image"}),(0,i.jsx)(n.td,{children:"IaaS resource usually storing raw disk data. Managed by the Glance service."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"(Cinder) Volume"}),(0,i.jsx)(n.td,{children:"IaaS resource representing block storage disk that can be attached as a virtual disk to virtual machines. Managed by the Cinder service."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"(Volume) Snapshot"}),(0,i.jsx)(n.td,{children:"Thinly-provisioned copy-on-write snapshots of volumes. Stored in the same Cinder storage backend as volumes."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Volume Type"}),(0,i.jsx)(n.td,{children:"Attribute of volumes determining storage details of a volume such as backend location or whether the volume will be encrypted."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"(Barbican) Secret"}),(0,i.jsx)(n.td,{children:"IaaS resource storing cryptographic assets such as encryption keys. Managed by the Barbican service."})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"scope",children:"Scope"}),"\n",(0,i.jsx)(n.p,{children:"User data in the context of this guide describes data accumulated in cloud resources of a user at runtime.\nThis concerns primarily storage data of virtual machines stored at at-rest.\nThis does not cover in-transit or in-use data such as network traffic, virtual machines' RAM contents or IaaS configuration and metadata of cloud resources."}),"\n",(0,i.jsx)(n.h3,{id:"overview-of-applicable-user-data",children:"Overview of applicable User Data"}),"\n",(0,i.jsx)(n.p,{children:"Given the mentioned scope, the following can be classified as user data:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"images stored in Glance"}),"\n",(0,i.jsxs)(n.li,{children:["virtual machine disks, either:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Ephemeral Storage stored in Nova"}),"\n",(0,i.jsx)(n.li,{children:"volumes stored in Cinder"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:"encryption keys stored as secrets in Barbican"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The following sections will describe backup procedures for each of those resources individually."}),"\n",(0,i.jsx)(n.h2,{id:"image-backup-using-download",children:"Image backup using download"}),"\n",(0,i.jsx)(n.p,{children:"Glance images may act as backup targets for other resources (such as volumes) but don't have a dedicated backup service for themselves."}),"\n",(0,i.jsx)(n.p,{children:"When an image is to be backed up, it can be downloaded from the Glance image service and stored outside of the IaaS infrastructure for backup purposes.\nIn this case it is the user's responsibility to establish the backup procedure and appropriate target storage."}),"\n",(0,i.jsxs)(n.admonition,{type:"caution",children:[(0,i.jsx)(n.p,{children:"When creating images from volumes with a volume type that uses encryption, the resulting image will contain the raw LUKS-encrypted blocks of the volume.\nWhen transferred outside of the IaaS infrastructure, this data is only useful as a backup together with the corresponding encryption key."}),(0,i.jsxs)(n.p,{children:["Such images can be identified by an attribute called ",(0,i.jsx)(n.code,{children:"cinder_encryption_key_id"})," in the ",(0,i.jsx)(n.code,{children:"properties"})," metadata field of the image.\nIt only exists for encrypted images and references the encryption key in Barbican.\nRefer to the ",(0,i.jsx)(n.a,{href:"#barbican-secrets-backup-using-download",children:"Barbican secrets section"})," for instructions on how to backup the key."]})]}),"\n",(0,i.jsx)(n.p,{children:"The API or the OpenStack client may be used to initiate the download, for example:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack image save --file $TARGET_FILE_PATH $IMAGE_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.p,{children:"This or the underlying API request may be automated as part of a regular backup schedule involving the backup storage target on the user side."}),"\n",(0,i.jsx)(n.h2,{id:"ephemeral-storage-backup-using-glance-images",children:"Ephemeral Storage backup using Glance images"}),"\n",(0,i.jsxs)(n.admonition,{type:"caution",children:[(0,i.jsxs)(n.p,{children:["When using the ",(0,i.jsx)(n.code,{children:"createImage"})," Compute API action (e.g. via the ",(0,i.jsx)(n.code,{children:"openstack server image create"})," command) on a virtual machine that has volumes attached to it in addition to its Ephemeral Storage disk, the volumes will not be backed up into the image. Instead, a snapshot will be created for each attached volume and referenced in the image metadata. This does not replace genuine volume backups."]}),(0,i.jsxs)(n.p,{children:["See the ",(0,i.jsx)(n.a,{href:"#image-creation-action-for-servers-with-attached-volumes",children:"corresponding appendix section"})," for further details."]})]}),"\n",(0,i.jsxs)(n.p,{children:["Ephemeral Storage disks of virtual machines can be backed up to Glance images easily by using the ",(0,i.jsx)(n.code,{children:"createImage"})," Compute API action or the corresponding OpenStack client command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack server image create --name $IMAGE_NAME $SERVER_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.p,{children:"This will create a Glance image containing a one-to-one copy of the data on the Ephemeral Storage disk at the time of execution."}),"\n",(0,i.jsxs)(n.p,{children:["If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in ",(0,i.jsx)(n.a,{href:"#image-backup-using-download",children:"Image backup using download"})," may be used after the image creation."]}),"\n",(0,i.jsx)(n.h2,{id:"volume-data-backup-using-cinder-backup-api",children:"Volume data backup using Cinder Backup API"}),"\n",(0,i.jsx)(n.p,{children:"The following instructions only apply if the infrastructure offers the Cinder Backup API."}),"\n",(0,i.jsxs)(n.admonition,{type:"note",children:[(0,i.jsx)(n.p,{children:"Backups of volumes using a volume type that uses encryption will retain their encryption and a clone of the original encryption key is created in Barbican linked to the backup.\nThese backups can only be restored when the Barbican service is available and still has the corresponding copy of the encryption key."}),(0,i.jsxs)(n.p,{children:["Also, it is advised to take note of the exact volume type when creating a backup of an encrypted volume, because this information will be needed to restore the backup.\nSee ",(0,i.jsx)(n.a,{href:"#restoring-an-encrypted-volume-backup-cinder-backup",children:"restoring an encrypted volume backup"}),"."]})]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["It might be difficult or even impossible for a user to transfer backups created by the Cinder Backup API outside of the IaaS infrastructure, depending on the backup backend.\nA more easily accessible backup of volumes can be created by using Glance images.\nSee the ",(0,i.jsx)(n.a,{href:"#volume-data-backup-using-glance-images",children:"section about volume data backup using Glance images"})," for details."]})}),"\n",(0,i.jsx)(n.h3,{id:"backup-of-detached-volumes",children:"Backup of detached volumes"}),"\n",(0,i.jsx)(n.p,{children:"Backups can be created using the Cinder Backup API or the corresponding OpenStack client commands:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create $VOLUME_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.p,{children:"Further backups of the same volume can subsequently be created as incremental backups using the following command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create --incremental $VOLUME_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.h3,{id:"backup-of-attached-volumes",children:"Backup of attached volumes"}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"When creating backups of attached (in-use) volumes, the state of the full volume is captured at runtime. Backups created this way will be crash-consistent but not app-consistent."})}),"\n",(0,i.jsxs)(n.p,{children:["In case of attached (in-use) volumes, backups can only be created while also specfiying the ",(0,i.jsx)(n.code,{children:"force"})," parameter:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create --force $VOLUME_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.p,{children:"Further backups of the same volume can subsequently be created as incremental backups using the following command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup create --force --incremental $VOLUME_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.h2,{id:"volume-data-backup-using-glance-images",children:"Volume data backup using Glance images"}),"\n",(0,i.jsx)(n.p,{children:"In case the Cinder Backup storage is not available in the IaaS infrastructure, Glance images can be used as a backup target instead.\nSuch images may also subsequently be downloaded to transfer the backup outside of the IaaS infrastructure."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Glance image backups of Cinder volumes only allow full backup copies and do not offer incremental or differential backup mechanisms."})}),"\n",(0,i.jsx)(n.h3,{id:"glance-image-backups-of-detached-volumes",children:"Glance image backups of detached volumes"}),"\n",(0,i.jsxs)(n.p,{children:["Volumes not attached to virtual machines can be directly copied into an image.\nSuch volumes can be identified by their status being ",(0,i.jsx)(n.code,{children:"available"}),".\nTo backup a detached volume to a Glance image, directly use the corresponding image creation action:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack image create --volume $VOLUME_NAME_OR_ID $IMAGE_NAME\n"})}),"\n",(0,i.jsx)(n.p,{children:"After the image creation has finished, a full backup copy of the volume will reside in the Glance storage backend."}),"\n",(0,i.jsxs)(n.p,{children:["If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in ",(0,i.jsx)(n.a,{href:"#image-backup-using-download",children:"Image backup using download"})," may be used after the image creation."]}),"\n",(0,i.jsx)(n.h3,{id:"glance-image-backups-of-attached-in-use-volumes",children:"Glance image backups of attached (in-use) volumes"}),"\n",(0,i.jsx)(n.p,{children:"Cinder is unable to directly create Glance images from volumes which are attached to virtual machines.\nTo create backups of such volumes regardless, a detour using volume snapshots can be used which will be described below."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["When creating snapshots of attached (in-use) volumes, the ",(0,i.jsx)(n.code,{children:"force"})," parameter has to be used. These snapshots capture a state of the full volume at runtime. They will be crash-consistent but not app-consistent."]})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Create a snapshot of the target volume while including the ",(0,i.jsx)(n.code,{children:"force"})," parameter in the request:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"openstack volume snapshot create --volume $VOLUME_NAME_OR_ID $SNAPSHOT_NAME"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Create a new temporary volume based on the snapshot to act as backup source:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"openstack volume create --snapshot $SNAPSHOT_NAME $TEMP_VOLUME_NAME"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Wait until the volume creation is finished and the temporary volume reaches the ",(0,i.jsx)(n.code,{children:"available"})," status."]}),"\n",(0,i.jsxs)(n.li,{children:["Create a backup image of the temporary volume:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"openstack image create --volume $TEMP_VOLUME_NAME $IMAGE_NAME"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Wait until the image creation finishes and the target image reaches the ",(0,i.jsx)(n.code,{children:"active"})," status."]}),"\n",(0,i.jsxs)(n.li,{children:["Delete the temporary volume and snapshot:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"openstack volume delete $TEMP_VOLUME_NAME"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"openstack volume snapshot delete $SNAPSHOT_NAME"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"A full backup copy of the volume now resides in the Glance storage backend."}),"\n",(0,i.jsxs)(n.p,{children:["If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in ",(0,i.jsx)(n.a,{href:"#image-backup-using-download",children:"Image backup using download"})," may be used after the image creation."]}),"\n",(0,i.jsx)(n.h2,{id:"barbican-secrets-backup-using-download",children:"Barbican secrets backup using download"}),"\n",(0,i.jsx)(n.admonition,{type:"danger",children:(0,i.jsx)(n.p,{children:"Secrets downloaded from Barbican will be in plaintext, which means that the secret is unprotected once received from the API.\nBefore downloading secrets from Barbican make sure that a secure target environment is established for receiving and securely storing the secret's contents."})}),"\n",(0,i.jsx)(n.p,{children:"Barbican secrets can be downloaded in plaintext using the corresponding API or client command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'openstack secret get --file $TARGET_FILE_PATH --payload_content_type "application/octet-stream" $SECRET_ID\n'})}),"\n",(0,i.jsxs)(n.admonition,{type:"tip",children:[(0,i.jsxs)(n.p,{children:["In case the secret needs to be restored into an OpenStack Barbican later on, it is recommended to also note down the following attributes shown by ",(0,i.jsx)(n.code,{children:"openstack secret get $SECRET_ID"}),":"]}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Algorithm"}),"\n",(0,i.jsx)(n.li,{children:"Bit length"}),"\n",(0,i.jsx)(n.li,{children:"Secret type"}),"\n",(0,i.jsx)(n.li,{children:"Mode"}),"\n"]})]}),"\n",(0,i.jsx)(n.h3,{id:"retrieving-encryption-keys-from-barbican",children:"Retrieving encryption keys from Barbican"}),"\n",(0,i.jsx)(n.p,{children:"In case of encrypted volumes (i.e. using a volume type with encryption), a corresponding encryption key is stored in Barbican.\nWhen an image is created from such a volume, the encryption key is duplicated in Barbican for the image.\nIn order to backup those keys, the corresponding secret must first be identified."}),"\n",(0,i.jsx)(n.p,{children:"For volumes, this is possible starting with the Volume API microversion 3.64:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume show --os-volume-api-version 3.64 $VOLUME_NAME_OR_ID\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The response will contain an ",(0,i.jsx)(n.code,{children:"encryption_key_id"})," field with the ID of the Barbican secret."]}),"\n",(0,i.jsxs)(n.p,{children:["For images, the secret reference is stored in the ",(0,i.jsx)(n.code,{children:"properties"})," field instead:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack image show -f value -c properties $IMAGE_NAME_OR_ID\n"})}),"\n",(0,i.jsxs)(n.p,{children:["In case of images created from encrypted volumes, the resulting output will have a nested ",(0,i.jsx)(n.code,{children:"cinder_encryption_key_id"})," field that contains the ID of the Barbican secret."]}),"\n",(0,i.jsxs)(n.p,{children:["The resulting IDs can be used to retrieve the corresponding key using the ",(0,i.jsx)(n.a,{href:"#barbican-secrets-backup-using-download",children:"Barbican instructions"})," above."]}),"\n",(0,i.jsxs)(n.admonition,{type:"caution",children:[(0,i.jsx)(n.p,{children:"Note that the key retrieved from the secret is not immediately usable as LUKS passphrase to the image data of the volume.\nOpenStack does some processing to the key before it is passed to the LUKS encryption, which must be mimicked accordingly in order to unlock the encryption outside of OpenStack!"}),(0,i.jsxs)(n.p,{children:["See the ",(0,i.jsx)(n.a,{href:"#luks-encryption-key-conversion-to-decrypt-volume-images",children:"example procedure for converting the LUKS key"})," in the appendix section."]})]}),"\n",(0,i.jsx)(n.h2,{id:"restore",children:"Restore"}),"\n",(0,i.jsx)(n.p,{children:"The following sections will illustrate how to restore the individual resource backups that have been documented above."}),"\n",(0,i.jsx)(n.h3,{id:"restoring-a-backup-of-a-barbican-secret",children:"Restoring a backup of a Barbican secret"}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Note that restoring a Barbican secret by re-uploading it via the Barbican API will lead to the secret receiving a new ID.\nExisting resources referencing an old secret ID cannot make use of the restored copy."})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack secret store --algorithm aes --bit-length 256 --mode cbc \\\n --secret-type symmetric --file $KEY_FILE_PATH --name $SECRET_NAME\n"})}),"\n",(0,i.jsx)(n.p,{children:"Notes:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Attributes like algorithm, bit length, mode and secret type are not verified by Barbican. Their main purpose is to classify the secret on a metadata level. Make sure to align the attributes with the original secret."}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"$KEY_FILE_PATH"})," is the local file path of the secret backup as created originally using the ",(0,i.jsx)(n.a,{href:"#barbican-secrets-backup-using-download",children:"instructions above"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"$SECRET_NAME"})," is entirely optional but helps identifying the restored secret later on and to distinguish it from secrets created by OpenStack itself. It is best to not put whitespace characters in the name, otherwise it has to be surrounded by quotes."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The successful registration of the restored secret can subsequently be verified using:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack secret list --name $SECRET_NAME\n"})}),"\n",(0,i.jsx)(n.h3,{id:"restoring-a-backup-of-an-unencrypted-image",children:"Restoring a backup of an unencrypted image"}),"\n",(0,i.jsx)(n.p,{children:"Unencrypted image backups can simply be restored using the regular image upload functionality and specifying the backup file:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack image create --file $IMAGE_FILE_PATH $IMAGE_NAME\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["In case the original image backup was not based on a volume originally, the image may have had a non-default disk or container format.\nIn this case, add the command parameters ",(0,i.jsx)(n.code,{children:"--container-format"})," and ",(0,i.jsx)(n.code,{children:"--disk-format"})," to the command accordingly."]})}),"\n",(0,i.jsx)(n.h3,{id:"restoring-a-backup-of-an-encrypted-image",children:"Restoring a backup of an encrypted image"}),"\n",(0,i.jsx)(n.p,{children:"The following section only applies to image backups that were originally created from images of encrypted volumes."}),"\n",(0,i.jsxs)(n.p,{children:["First, restore the corresponding secret of the image using the ",(0,i.jsx)(n.a,{href:"#restoring-a-backup-of-a-barbican-secret",children:"instructions above"}),".\nThe restored secret will receive a new ID in the form of a ",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Universally_unique_identifier",children:"UUID"}),".\nNote down the ID of the restored secret and insert it in place of ",(0,i.jsx)(n.code,{children:"$SECRET_ID"})," in the command below."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack image create --file $IMAGE_FILE_PATH \\\n --property cinder_encryption_key_id=$SECRET_ID \\\n --property cinder_encryption_key_deletion_policy=on_image_deletion \\\n $IMAGE_NAME\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"cinder_encryption_key_deletion_policy"})," attribute is optional.\nIf not specified, the referenced secret will not be deleted on image deletion automatically.\nIn contrast, if set to ",(0,i.jsx)(n.code,{children:"on_image_deletion"}),", the referenced secret will be deleted as soon as the image referencing it is deleted."]}),"\n",(0,i.jsx)(n.h3,{id:"restoring-a-volume-backup-from-an-image",children:"Restoring a volume backup from an image"}),"\n",(0,i.jsx)(n.p,{children:"To restore a volume from an image backup, simply use the volume creation action and specify the image as source."}),"\n",(0,i.jsxs)(n.p,{children:["Depending on whether the original volume the image was created from was encrypted or not, the target volume type might need to be specified accordingly.\nWhether this is the case can be identified by inspecting the image's metadata using ",(0,i.jsx)(n.code,{children:"openstack image show $IMAGE_NAME_OR_ID"}),' and looking for a "cinder_encryption_key_id" field within "properties".\nIf it exists, the source volume of the image was encrypted.']}),"\n",(0,i.jsx)(n.p,{children:"To restore the image of an unencrypted volume:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume create --image $IMAGE_NAME_OR_ID \\\n --size $VOLUME_SIZE_IN_GB $VOLUME_NAME\n"})}),"\n",(0,i.jsx)(n.p,{children:"To restore the image of an encrypted volume:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume create --image $IMAGE_NAME_OR_ID \\\n --type $ENCRYPTED_VOLUME_TYPE \\\n --size $VOLUME_SIZE_IN_GB $VOLUME_NAME\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If restoring an encrypted image, make sure to specify ",(0,i.jsx)(n.code,{children:"$ENCRYPTED_VOLUME_TYPE"})," correctly and have it reference a volume type which also supports the encryption.\nOtherwise the volume will be unbootable or unusable by Nova instances."]}),"\n",(0,i.jsx)(n.h3,{id:"restoring-a-volume-backup-from-the-cinder-backup-service",children:"Restoring a volume backup from the Cinder Backup service"}),"\n",(0,i.jsx)(n.p,{children:"The Cinder Backup service offers dedicated API actions and commands for restoring volume backups created using the service.\nThese backups can be restored in one of two ways:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Letting the Cinder Backup service create a new volume based on the backup."}),"\n",(0,i.jsx)(n.li,{children:"Overwriting an existing volume with the backup data."}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["If the volume backup was originally created from a volume that used a non-default encrypted volume type, letting Cinder Backup create a new volume for backup restoration does not work and the volume type must match exactly.\nIn such case provision an empty volume with the correct type first and then restore the backup onto it ",(0,i.jsx)(n.a,{href:"#restoring-an-encrypted-volume-backup-cinder-backup",children:"as explained further down"}),"."]})}),"\n",(0,i.jsx)(n.h4,{id:"restoring-to-a-new-volume-cinder-backup",children:"Restoring to a new volume (Cinder Backup)"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup restore $BACKUP_NAME_OR_ID $TARGET_NAME\n"})}),"\n",(0,i.jsxs)(n.p,{children:["... where ",(0,i.jsx)(n.code,{children:"$TARGET_NAME"})," is the desired name of the new volume to be created.\nMake sure that no volume with this name already exists.\nThe Cinder Backup service will create the volume with the same size as the backup indicates."]}),"\n",(0,i.jsx)(n.h4,{id:"restoring-on-an-existing-volume-cinder-backup",children:"Restoring on an existing volume (Cinder Backup)"}),"\n",(0,i.jsx)(n.p,{children:"As an alternative to creating a new volume as the restore target, the backup can also be restored on an existing volume:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup restore --force $BACKUP_NAME_OR_ID $VOLUME_NAME_OR_ID\n"})}),"\n",(0,i.jsx)(n.p,{children:"... which will overwrite the data on the existing volume, regardless of whether it is empty or not!"}),"\n",(0,i.jsx)(n.p,{children:'The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.'}),"\n",(0,i.jsx)(n.h4,{id:"restoring-an-encrypted-volume-backup-cinder-backup",children:"Restoring an encrypted volume backup (Cinder Backup)"}),"\n",(0,i.jsx)(n.p,{children:'When restoring a volume backup of a volume that was using a non-default encrypted volume type, a new volume of that type needs to be created first and then the backup restored onto it.\nOtherwise, the restoration will fail with the target volume ending up in the "error_restoring" state.\nFor this procedure to succeed it is necessary to know the exact volume type of the volume the backup was created from.'}),"\n",(0,i.jsxs)(n.p,{children:["If the source volume of the backup still exists, the original volume type can be determined by inspecting the backup's ",(0,i.jsx)(n.code,{children:"volume_id"})," attribute and then using it to look up the corresponding volume and its ",(0,i.jsx)(n.code,{children:"type"})," attribute.\nThe following client command can be used for this (fill in the value for ",(0,i.jsx)(n.code,{children:"BACKUP_ID"}),"):"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'export BACKUP_ID=...\n\nSOURCE_VOLUME_ID="$(openstack volume backup show $BACKUP_ID -f value -c volume_id)"\nopenstack volume show -f value -c type "$SOURCE_VOLUME_ID"\n'})}),"\n",(0,i.jsx)(n.p,{children:"This returns the name of the original volume type.\nIf the source volume does not exist anymore, rely on documentation about the backup to determine the type, if available."}),"\n",(0,i.jsxs)(n.p,{children:["First, create a new empty volume as the restore target and use the backup's ",(0,i.jsx)(n.code,{children:"size"})," metadata attribute to match the size of the volume to the backup:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume create --size $BACKUP_SIZE --type $VOLUME_TYPE $TARGET_NAME\n"})}),"\n",(0,i.jsxs)(n.p,{children:["... where ",(0,i.jsx)(n.code,{children:"$TARGET_NAME"})," is the desired name of the new volume."]}),"\n",(0,i.jsx)(n.p,{children:'Once the volume reaches "available" state, restore the backup onto it:'}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack volume backup restore --force $BACKUP_NAME_OR_ID $TARGET_NAME\n"})}),"\n",(0,i.jsx)(n.p,{children:'The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.'}),"\n",(0,i.jsx)(n.h2,{id:"appendix",children:"Appendix"}),"\n",(0,i.jsx)(n.h3,{id:"image-creation-action-for-servers-with-attached-volumes",children:"Image creation action for servers with attached volumes"}),"\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"createImage"})," action of the Compute API (",(0,i.jsx)(n.code,{children:"openstack server image create"}),") is used on virtual machines that have at least one volume attached, a snapshot will be created for each attached volume individually and referenced in the resulting image's metadata."]}),"\n",(0,i.jsx)(n.p,{children:"This happens regardless of whether the virtual machine has an Ephemeral Storage disk attached.\nIn case of an Ephemeral Storage disk, only the Ephemeral Storage is copied into the Glance image as a 1:1 copy."}),"\n",(0,i.jsxs)(n.p,{children:["In case of a virtual machine that has no Ephemeral Storage but only volumes, the ",(0,i.jsx)(n.code,{children:"createImage"})," action leads to a Glance image that only consists of metadata (including the resulting volume snapshot references) but carries no actual binary data."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Figure: createImage action flow involving Ephemeral Storage and/or volumes",src:a(41131).A+"",width:"1342",height:"1202"})}),"\n",(0,i.jsx)(n.h3,{id:"luks-encryption-key-conversion-to-decrypt-volume-images",children:"LUKS encryption key conversion to decrypt volume images"}),"\n",(0,i.jsx)(n.p,{children:"The volume encryption keys stored in Barbican are not directly used as LUKS passphrases by OpenStack because they are in binary format.\nOpenStack converts them to ASCII internally before passing them to the encryption layer.\nThis behavior needs to be reproduced if a decryption of a volume image is desired outside of OpenStack."}),"\n",(0,i.jsx)(n.admonition,{type:"danger",children:(0,i.jsx)(n.p,{children:"The instructions below will expose plaintext data of encryption keys and encrypted volume images.\nMake sure to only execute these steps in a secure and trusted environment."})}),"\n",(0,i.jsx)(n.p,{children:"First, download the image:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"openstack image save --file image.raw $IMAGE_NAME_OR_ID\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Next, inspect the image metadata, determine the reference to the encryption key (",(0,i.jsx)(n.code,{children:"cinder_encryption_key_id"})," property) and download the encryption key:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'openstack image show -f value -c properties $IMAGE_NAME_OR_ID\n# (use the value of `cinder_encryption_key_id` as `$SECRET_ID` below)\nopenstack secret get --file image.key --payload_content_type "application/octet-stream" $SECRET_ID\n'})}),"\n",(0,i.jsx)(n.p,{children:"This will result in the following local files:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"image.raw"})," = the raw encrypted image downloaded from Glance"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"image.key"})," = the LUKS encryption key in binary format (plaintext)"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Since OpenStack internally uses Python's ",(0,i.jsx)(n.code,{children:"binascii.hexlify()"})," to convert the binary encryption key before passing it as a passphrase to the LUKS encryption, as a last step this conversion must be mimicked to unlock the encryption:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"python3 -c \"import binascii; \\\n f = open('image.key', 'rb'); \\\n print(binascii.hexlify(f.read()).decode('utf-8'))\" \\\n | sudo cryptsetup luksOpen ./image.raw decrypted_image\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The decrypted image is now accessible at ",(0,i.jsx)(n.code,{children:"/dev/mapper/decrypted_image"}),".\nNote that this is a live en-/decryption operation on the ",(0,i.jsx)(n.code,{children:"image.raw"})," file.\nThe image is not converted, the encryption is simply unlocked in-memory using LUKS and dm-crypt until the encryption is closed again."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"/dev/mapper/decrypted_image"})," can now be handled like a raw block device (e.g. mounted as a filesystem) or snapshotted in decrypted form."]}),"\n",(0,i.jsx)(n.p,{children:"To close the encryption execute:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo cryptsetup luksClose decrypted_image\n"})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsxs)(n.em,{children:["The source of this document can be found in the ",(0,i.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/docs/main/docs/02-iaas/guides/user-guide/user-data-backups.md",children:"SovereignCloudStack/docs"})," repository."]})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.em,{children:"Author: SCS Community, License: CC by Attribution 4.0 International"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},41131:(e,n,a)=>{a.d(n,{A:()=>i});const i=a.p+"assets/images/user_data_backups_figure1-988dbd55659509cc1ddc9f68f2437648.png"},28453:(e,n,a)=>{a.d(n,{R:()=>r,x:()=>c});var i=a(96540);const t={},s=i.createContext(t);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9278f3d6.4c9c2f47.js b/assets/js/9278f3d6.4c9c2f47.js new file mode 100644 index 0000000000..ce6c0acb90 --- /dev/null +++ b/assets/js/9278f3d6.4c9c2f47.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[904],{22712:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var i=n(74848),s=n(28453);const o={title:"Kubernetes Nodes Anti Affinity",type:"Decision Record",status:"Draft",track:"KaaS"},r=void 0,a={id:"scs-0213-v1-k8s-nodes-anti-affinity",title:"Kubernetes Nodes Anti Affinity",description:"Introduction",source:"@site/standards/scs-0213-v1-k8s-nodes-anti-affinity.md",sourceDirName:".",slug:"/scs-0213-v1-k8s-nodes-anti-affinity",permalink:"/standards/scs-0213-v1-k8s-nodes-anti-affinity",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Kubernetes Nodes Anti Affinity",type:"Decision Record",status:"Draft",track:"KaaS"},sidebar:"standards",previous:{title:"scs-0213: Kubernetes Nodes Anti Affinity",permalink:"/standards/kaas/scs-0213"},next:{title:"scs-0214: Kubernetes Node Distribution and Availability",permalink:"/standards/kaas/scs-0214"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Glossary",id:"glossary",level:3},{value:"Motivation",id:"motivation",level:2},{value:"Design considerations",id:"design-considerations",level:2},{value:"Decision",id:"decision",level:2},{value:"Documents",id:"documents",level:2}];function c(e){const t={a:"a",h2:"h2",h3:"h3",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"A Kubernetes instance is provided as a cluster, which consists of a set of worker machines,\nso called nodes. A cluster is composed of a control plane and at least one worker node.\nThe control plane manages the worker nodes and therefore the pods in the cluster by making\ndecisions about scheduling, event detection and global decisions. Inside the control plane,\nmultiple components exist, which can be duplicated and distributed over multiple machines\ninside the cluster. Typically, no user containers are run on these machines in order to\nseparate the control plane from the live system."}),"\n",(0,i.jsx)(t.h3,{id:"glossary",children:"Glossary"}),"\n",(0,i.jsx)(t.p,{children:"The following special terms are used throughout this decision record document:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Term"}),(0,i.jsx)(t.th,{children:"Meaning"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Worker"}),(0,i.jsx)(t.td,{children:"Virtual or bare-metal machine, which hosts workloads of customers"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Control Plane"}),(0,i.jsx)(t.td,{children:"Virtual or bare-metal machine, which hosts the container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Machine"}),(0,i.jsx)(t.td,{children:"Virtual or bare-metal entity with computational capabilities"})]})]})]}),"\n",(0,i.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:"In a productive environment, the control plane usually runs across multiple machines and\na cluster usually contains multiple worker nodes in order to provide fault-tolerance and\nhigh availability."}),"\n",(0,i.jsx)(t.p,{children:"In order to ensure availability and scaling of workloads, even if some nodes in the cluster\ncould fail, they should be distributed over multiple nodes on different machines.\nThis can be steered with the Affinity or Anti Affinity features, which are separated by\nKubernetes into two features:"}),"\n",(0,i.jsx)(t.p,{children:"Node Affinity\nThe Node Affinity feature allows to match pods according to logical matches of\nkey-value-pairs referring to labels of nodes.\nThese can be defined with different weights or preferences in order to allow fine-grained\nselection of nodes. The feature works similar to the Kubernetes nodeSelector.\nIt is defined in the PodSpec using the nodeAffinity field in the affinity section."}),"\n",(0,i.jsx)(t.p,{children:"Pod Affinity\nPod Affinity or Pod Anti Affinity allows the constraint of pod scheduling based on the\nlabels of pods already running on a node.\nThis means the constraint will match other pods on a node according to their labels key-value-pairs\nand then either schedule the pod to the same (Affinity) or another (Anti Affinity) node.\nThis feature is also defined in the PodSpec using the podAffinity and podAntiAffinity\nfields in the affinity section. [3]"}),"\n",(0,i.jsx)(t.p,{children:'Both features allow the usage of "required" or "preferred" keywords, which create\n"hard" or "soft" affinities. By using a hard affinity, a pod would need to be scheduled\naccording to the rules set. If this possibility is not given, the pod can\'t be scheduled.\nA soft affinity would allow scheduling even if the requirements are not fulfilled, but\nthey would be preferred if possible.'}),"\n",(0,i.jsx)(t.p,{children:"These features allow efficient resource usage (e.g. by scheduling workloads to evenly\ndistribute across nodes) and provide fault-tolerance and therefore high availability.\nBut they also require more work during the setup of a service architecture, since nodes\nand pods need to be labelled and described consistently."}),"\n",(0,i.jsx)(t.p,{children:"In the case of SCS, affinity of the workloads themselves is not relevant, since this\nfeature is mostly used by the customers of the providers.\nInstead, the expected standard should enable the Kubernetes cluster to handle Anti Affinity\nrules with a real physical separation as well as distributing the control plane over\nmultiple machines in order to provide fault-tolerance during system outages.\nIf the control plane survives an outage, a Kubernetes cluster can recover later on."}),"\n",(0,i.jsx)(t.h2,{id:"design-considerations",children:"Design considerations"}),"\n",(0,i.jsx)(t.p,{children:"SCS plans to require a Hard Anti Affinity and/or Redundancy for the control plane and\na Soft Anti Affinity for workers. This means, that Anti Affinity would be required for\nthe control planes and their pods and only optional (but encouraged) for workers."}),"\n",(0,i.jsx)(t.p,{children:"In order to achieve the goals for these components, meaning availability and fault tolerance\nfor the control plane, an outage resistant cluster, and the availability\npromise given with Anti Affinity for pods on the worker nodes, a separation of nodes\non the hardware level would need to be achieved."}),"\n",(0,i.jsx)(t.p,{children:'For the control plane, a reference to the "Kubernetes High Availability" [1]\ncan be useful, since it provides two ways to set up a highly available cluster.\nBoth approaches are very similar. The "Stacked Control Plane" [2] requires less infrastructure,\nbut also runs the risk of failed coupling, where if one node fails, the redundancy could be\ncompromised due to the loss of a complete control plane instance.\nThe "External ETCD" solves this problem, but also requires double the infrastructure, due\nto the externally incorporated etcd clusters.'}),"\n",(0,i.jsx)(t.p,{children:'This also shows, that the wording "anti affinity" as used with Kubernetes pods is probably\nslightly misleading in the context of a Kubernetes control plane. It may consist of multiple\npods with individual tasks, but distributing them over different nodes through Anti Affinity\nwould probably still cascade the whole control plane into a complete failure, if one of\nthe used nodes goes down. It could be possible to replicate specific important pods and\nassign them to different nodes, but at this point, a redundant setup like presented in [1] could be used.\nSo Anti Affinity in this context probably means more like distribution over multiple\nphysical machines, which needs to be planned beforehand on the machine/server level.'}),"\n",(0,i.jsx)(t.p,{children:'Therefore would it be preferred for the control plane to use a redundant setup, which\nis separated over different physical machines, meaning at least half of the control plane\nnodes runs on a different physical machine as the rest. The currently used ClusterAPI\nenables this by establishing the concept of "failure domains". These are used to control\nthe placement of k8s nodes and distribute them over multiple physical machines.\nFor example, a High Availability K8s cluster with three control plane nodes could be\ndistributed over three different availability zones (and therefore 3 different\nphysical machines) in order to survive the failure of one availability zone. [5]'}),"\n",(0,i.jsx)(t.p,{children:"For worker nodes, the whole idea of Anti Affinity is more of a preferable situation.\nThe nodes themselves should at best be distributed over different machines, but this\nis not a requirement, especially since smaller providers wouldn't have the capacity to\nprovide enough machines for these distributed Kubernetes clusters. Since customers that\nuse the Affinity or Topology spread constraint [4] features would be especially interested\nin the worker nodes that host their workloads, it should be ensured that a good labeling\nsystem is provided for the nodes in order to see if two nodes are hosted on the same machine."}),"\n",(0,i.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(t.p,{children:"The future standard should define a few important things in order to provide a solid base\nfor the usage and advantages of workloads with Anti Affinity rules."}),"\n",(0,i.jsx)(t.p,{children:"Control planes SHOULD be made redundant in order to provide fault-tolerance and security\nagainst fatal errors on this layer, in the case of node failures. How this redundancy\nis achieved SHOULD be left to the providers, but since failure must be avoided, it is\nREQUIRED to at least duplicate control plane components. Half of every component SHOULD\nbe located on a different node on a different physical machine than the other half\nof them. This should provide at least the minimum requirements for a fault-tolerant control plane.\nFor the standard, there is also a possibility to define multiple stages of distributed infrastructure\nand only make sensible ones a requirement and the rest optional, e.g."}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"non-distributed clusters"}),"\n",(0,i.jsxs)(t.li,{children:["High-Availability clusters that are","\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"distributed over multiple machines/availability zones"}),"\n",(0,i.jsx)(t.li,{children:"distributed over multiple clouds"}),"\n",(0,i.jsx)(t.li,{children:"distributed over multiple physical locations/datacenters"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The worker nodes are RECOMMENDED to be distributed over different machines. In order to\nprovide clear information to the users, the nodes should be labeled to reflect the\nmapping to the underlying clusters. The labels can be obfuscated in order to not reveal\nthe underlying structures to customers and users. It should be noted, that it is NOT REQUIRED\nto have this anti affinity for the worker nodes due to the requirements of infrastructure\nand complexity associated with this."}),"\n",(0,i.jsx)(t.h2,{id:"documents",children:"Documents"}),"\n",(0,i.jsxs)(t.p,{children:["Kubernetes High Availability Documentation ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/",children:"1"}),"\nKubernetes High Availability - Stacked ETCD ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/#stacked-etcd-topology",children:"2"}),"\nAffinity and Anti-Affinity ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity",children:"3"}),"\nTopology Spread Constraints ",(0,i.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/",children:"4"}),"\nSCS Multi AZ and Multi Cloud Environments ",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/doc/usage/multi-az-and-multi-cloud-environments.md",children:"5"})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var i=n(96540);const s={},o=i.createContext(s);function r(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/929c4e1b.b628b7cf.js b/assets/js/929c4e1b.b628b7cf.js new file mode 100644 index 0000000000..5638878aab --- /dev/null +++ b/assets/js/929c4e1b.b628b7cf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3802],{86825:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var s=t(74848),r=t(28453);const a={},i="Introduction",o={id:"index",title:"Introduction",description:"The Sovereign Cloud Stack (SCS) is a community-driven project that curates a set of standards\u2014including both existing standards, such as the OpenInfra interoperability guides or the CNCF Kubernetes conformance, and newly created ones\u2014to enable and ensure compatibility, openness, and sovereignty of cloud services across a wide range of providers, particularly small and medium businesses.",source:"@site/standards/index.md",sourceDirName:".",slug:"/",permalink:"/standards/",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",next:{title:"overview",permalink:"/standards/certification/overview"}},d={},c=[];function u(e){const n={a:"a",h1:"h1",img:"img",p:"p",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"The Sovereign Cloud Stack (SCS) is a community-driven project that curates a set of standards\u2014including both existing standards, such as the OpenInfra interoperability guides or the CNCF Kubernetes conformance, and newly created ones\u2014to enable and ensure compatibility, openness, and sovereignty of cloud services across a wide range of providers, particularly small and medium businesses."}),"\n",(0,s.jsx)(n.p,{children:"In addition, SCS provides a certification framework that enables these providers to verify and advertise their compliance with these standards. This framework consists of six kinds of certificates of varying scope, where each scope corresponds to a subset of the set of standards mentioned above."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Alt text",src:t(77704).A+"",width:"835",height:"711"})}),"\n",(0,s.jsxs)(n.p,{children:["Learn more about these scopes as well as the currently certified clouds under ",(0,s.jsx)(n.a,{href:"/standards/certification/overview",children:"Certification"}),". More details on individual standards can be found under ",(0,s.jsx)(n.a,{href:"/standards/standards/overview",children:"Standards"}),"."]})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},77704:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/image-01d5564077ed43bda1d921e522df7dd7.png"},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>o});var s=t(96540);const r={},a=s.createContext(r);function i(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/931040e8.b02c7073.js b/assets/js/931040e8.b02c7073.js new file mode 100644 index 0000000000..84559ea666 --- /dev/null +++ b/assets/js/931040e8.b02c7073.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7743],{42697:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>d,toc:()=>a});var t=o(74848),s=o(28453);const i={},r="Styleguide",d={id:"contribute/styleguide",title:"Styleguide",description:"Admonitions",source:"@site/community/contribute/styleguide.md",sourceDirName:"contribute",slug:"/contribute/styleguide",permalink:"/community/contribute/styleguide",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Installation",permalink:"/community/contribute/local-docusaurus-development-guide"}},c={},a=[{value:"Admonitions",id:"admonitions",level:2},{value:"Blockquotes",id:"blockquotes",level:2},{value:"Codeblocks",id:"codeblocks",level:2}];function l(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"styleguide",children:"Styleguide"}),"\n",(0,t.jsx)(n.h2,{id:"admonitions",children:"Admonitions"}),"\n",(0,t.jsx)(n.p,{children:"We adopt the default Admonition colors for Note, Tip, Info, Caution, Danger by docusaurus:"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"https://docusaurus-archive-october-2023.netlify.app/docs/markdown-features/admonitions",children:"Docusaurus Admonitons"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Some ",(0,t.jsx)(n.strong,{children:"content"})," with ",(0,t.jsx)(n.em,{children:"Markdown"})," ",(0,t.jsx)(n.code,{children:"syntax"}),"."]})}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["Some ",(0,t.jsx)(n.strong,{children:"content"})," with ",(0,t.jsx)(n.em,{children:"Markdown"})," ",(0,t.jsx)(n.code,{children:"syntax"}),"."]})}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsxs)(n.p,{children:["Some ",(0,t.jsx)(n.strong,{children:"content"})," with ",(0,t.jsx)(n.em,{children:"Markdown"})," ",(0,t.jsx)(n.code,{children:"syntax"}),"."]})}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsxs)(n.p,{children:["Some ",(0,t.jsx)(n.strong,{children:"content"})," with ",(0,t.jsx)(n.em,{children:"Markdown"})," ",(0,t.jsx)(n.code,{children:"syntax"}),"."]})}),"\n",(0,t.jsx)(n.admonition,{type:"danger",children:(0,t.jsxs)(n.p,{children:["Some ",(0,t.jsx)(n.strong,{children:"content"})," with ",(0,t.jsx)(n.em,{children:"Markdown"})," ",(0,t.jsx)(n.code,{children:"syntax"}),"."]})}),"\n",(0,t.jsx)(n.h2,{id:"blockquotes",children:"Blockquotes"}),"\n",(0,t.jsxs)(n.p,{children:["Blockquotes should be handled with standard markdown ",(0,t.jsx)(n.code,{children:">"})]}),"\n",(0,t.jsx)(n.p,{children:"Example Blockquote:"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"The raw data format is really the only sensible format option to use with RBD. asdasdasdasd asd asd a\nTechnically, you could use other QEMU-supported formats\n(such as qcow2 or vmdk), but doing so would add additional overhead, and would\nalso render the volume unsafe for virtual machine live\nmigration when caching (see below) is enabled."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"codeblocks",children:"Codeblocks"}),"\n",(0,t.jsxs)(n.p,{children:["We support markdown language features for Codeblocks.\nIt is mandatory to define the language to be quoted, when using codeblocks.\nSyntax Highlighting is also supported by ",(0,t.jsx)(n.a,{href:"https://docusaurus-archive-october-2023.netlify.app/docs/markdown-features/code-blocks#supported-languages",children:"Docusaurus via Prism"}),".\nWe are using the GitHub language themeing as default."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",metastring:'title="Python example"',children:"def code_block():\n # Everything in this function is part of the same code block\n print (1)\n print (2)\n\nfor i in range(4):\n # Everyting in this loop is part of the same code block\n print (i)\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",metastring:'title="Javascript example"',children:"const code_block = () => {\n console.log('inside code_block')\n}\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="YAML example"',children:"---\ndoe: 'a deer, a female deer'\nray: 'a drop of golden sun'\npi: 3.14159\nxmas: true\nfrench-hens: 3\ncalling-birds:\n - huey\n - dewey\n - louie\n - fred\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ruby",metastring:'title="Ruby example"',children:"require 'redcarpet'\nmarkdown = Redcarpet.new(\"Hello World!\")\nputs markdown.to_html\n"})})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>r,x:()=>d});var t=o(96540);const s={},i=t.createContext(s);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.3d5daa2c.js b/assets/js/935f2afb.3d5daa2c.js new file mode 100644 index 0000000000..576cbeabde --- /dev/null +++ b/assets/js/935f2afb.3d5daa2c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8581],{35610:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"docs":[{"type":"link","label":"Introduction","href":"/docs/","docId":"index","unlisted":false},{"type":"category","label":"IaaS Layer","items":[{"type":"category","label":"Guides","items":[{"type":"category","label":"Concept Guide","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Components","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Ceph","href":"/docs/iaas/guides/concept-guide/components/ceph","docId":"iaas/guides/concept-guide/components/ceph","unlisted":false},{"type":"link","label":"Cluster API","href":"/docs/iaas/guides/concept-guide/components/clusterapi","docId":"iaas/guides/concept-guide/components/clusterapi","unlisted":false},{"type":"link","label":"Gardener","href":"/docs/iaas/guides/concept-guide/components/gardener","docId":"iaas/guides/concept-guide/components/gardener","unlisted":false},{"type":"link","label":"Ironic","href":"/docs/iaas/guides/concept-guide/components/ironic","docId":"iaas/guides/concept-guide/components/ironic","unlisted":false},{"type":"link","label":"K3S","href":"/docs/iaas/guides/concept-guide/components/k3s","docId":"iaas/guides/concept-guide/components/k3s","unlisted":false},{"type":"link","label":"Keycloak","href":"/docs/iaas/guides/concept-guide/components/keycloak","docId":"iaas/guides/concept-guide/components/keycloak","unlisted":false},{"type":"link","label":"Netdata","href":"/docs/iaas/guides/concept-guide/components/netdata","docId":"iaas/guides/concept-guide/components/netdata","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/iaas/guides/concept-guide/components/openstack","docId":"iaas/guides/concept-guide/components/openstack","unlisted":false},{"type":"link","label":"Prometheus & Grafana","href":"/docs/iaas/guides/concept-guide/components/prometheus","docId":"iaas/guides/concept-guide/components/prometheus","unlisted":false},{"type":"link","label":"Proxmox VE","href":"/docs/iaas/guides/concept-guide/components/proxmox","docId":"iaas/guides/concept-guide/components/proxmox","unlisted":false},{"type":"link","label":"SONiC & OVN","href":"/docs/iaas/guides/concept-guide/components/sonic","docId":"iaas/guides/concept-guide/components/sonic","unlisted":false},{"type":"link","label":"Teleport","href":"/docs/iaas/guides/concept-guide/components/teleport","docId":"iaas/guides/concept-guide/components/teleport","unlisted":false}],"href":"/docs/iaas/guides/concept-guide/components/"},{"type":"link","label":"Layers in a cluster","href":"/docs/iaas/guides/concept-guide/layers","docId":"iaas/guides/concept-guide/layers","unlisted":false},{"type":"link","label":"Cluster design","href":"/docs/iaas/guides/concept-guide/design","docId":"iaas/guides/concept-guide/design","unlisted":false},{"type":"link","label":"Use cases","href":"/docs/iaas/guides/concept-guide/use-cases","docId":"iaas/guides/concept-guide/use-cases","unlisted":false},{"type":"link","label":"Hardware Bill of Materials","href":"/docs/iaas/guides/concept-guide/hardware-bom","docId":"iaas/guides/concept-guide/hardware-bom","unlisted":false}],"href":"/docs/iaas/guides/concept-guide/"},{"type":"category","label":"Deploy Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Seed","href":"/docs/iaas/guides/deploy-guide/seed","docId":"iaas/guides/deploy-guide/seed","unlisted":false},{"type":"link","label":"Manager","href":"/docs/iaas/guides/deploy-guide/manager","docId":"iaas/guides/deploy-guide/manager","unlisted":false},{"type":"link","label":"Provisioning","href":"/docs/iaas/guides/deploy-guide/provisioning","docId":"iaas/guides/deploy-guide/provisioning","unlisted":false},{"type":"link","label":"Bootstrap","href":"/docs/iaas/guides/deploy-guide/bootstrap","docId":"iaas/guides/deploy-guide/bootstrap","unlisted":false},{"type":"category","label":"Services","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Infrastructure","href":"/docs/iaas/guides/deploy-guide/services/infrastructure","docId":"iaas/guides/deploy-guide/services/infrastructure","unlisted":false},{"type":"link","label":"Kubernetes","href":"/docs/iaas/guides/deploy-guide/services/kubernetes","docId":"iaas/guides/deploy-guide/services/kubernetes","unlisted":false},{"type":"link","label":"Network","href":"/docs/iaas/guides/deploy-guide/services/network","docId":"iaas/guides/deploy-guide/services/network","unlisted":false},{"type":"link","label":"Logging & Monitoring","href":"/docs/iaas/guides/deploy-guide/services/logging-monitoring","docId":"iaas/guides/deploy-guide/services/logging-monitoring","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/iaas/guides/deploy-guide/services/ceph","docId":"iaas/guides/deploy-guide/services/ceph","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/iaas/guides/deploy-guide/services/openstack","docId":"iaas/guides/deploy-guide/services/openstack","unlisted":false}],"href":"/docs/iaas/guides/deploy-guide/services/"},{"type":"category","label":"Examples","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cloud in a Box","href":"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box","docId":"iaas/guides/deploy-guide/examples/cloud-in-a-box","unlisted":false},{"type":"link","label":"Testbed","href":"/docs/iaas/guides/deploy-guide/examples/testbed","docId":"iaas/guides/deploy-guide/examples/testbed","unlisted":false}],"href":"/docs/iaas/guides/deploy-guide/examples/"}],"href":"/docs/iaas/guides/deploy-guide/"},{"type":"category","label":"Upgrade Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Manager","href":"/docs/iaas/guides/upgrade-guide/manager","docId":"iaas/guides/upgrade-guide/manager","unlisted":false},{"type":"link","label":"Network","href":"/docs/iaas/guides/upgrade-guide/network","docId":"iaas/guides/upgrade-guide/network","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/iaas/guides/upgrade-guide/ceph","docId":"iaas/guides/upgrade-guide/ceph","unlisted":false},{"type":"link","label":"Docker","href":"/docs/iaas/guides/upgrade-guide/docker","docId":"iaas/guides/upgrade-guide/docker","unlisted":false},{"type":"link","label":"Infrastructure","href":"/docs/iaas/guides/upgrade-guide/infrastructure","docId":"iaas/guides/upgrade-guide/infrastructure","unlisted":false},{"type":"link","label":"Logging & Monitoring","href":"/docs/iaas/guides/upgrade-guide/logging-monitoring","docId":"iaas/guides/upgrade-guide/logging-monitoring","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/iaas/guides/upgrade-guide/openstack","docId":"iaas/guides/upgrade-guide/openstack","unlisted":false}],"href":"/docs/iaas/guides/upgrade-guide/"},{"type":"category","label":"Configuration Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Configuration repository","href":"/docs/iaas/guides/configuration-guide/configuration-repository","docId":"iaas/guides/configuration-guide/configuration-repository","unlisted":false},{"type":"link","label":"Inventory","href":"/docs/iaas/guides/configuration-guide/inventory","docId":"iaas/guides/configuration-guide/inventory","unlisted":false},{"type":"link","label":"Manager","href":"/docs/iaas/guides/configuration-guide/manager","docId":"iaas/guides/configuration-guide/manager","unlisted":false},{"type":"link","label":"Network","href":"/docs/iaas/guides/configuration-guide/network","docId":"iaas/guides/configuration-guide/network","unlisted":false},{"type":"link","label":"Proxy","href":"/docs/iaas/guides/configuration-guide/proxy","docId":"iaas/guides/configuration-guide/proxy","unlisted":false},{"type":"link","label":"Loadbalancer","href":"/docs/iaas/guides/configuration-guide/loadbalancer","docId":"iaas/guides/configuration-guide/loadbalancer","unlisted":false},{"type":"link","label":"Self-signed certificates","href":"/docs/iaas/guides/configuration-guide/self-signed-certificates","docId":"iaas/guides/configuration-guide/self-signed-certificates","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/iaas/guides/configuration-guide/ceph","docId":"iaas/guides/configuration-guide/ceph","unlisted":false},{"type":"category","label":"OpenStack","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Aodh","href":"/docs/iaas/guides/configuration-guide/openstack/aodh","docId":"iaas/guides/configuration-guide/openstack/aodh","unlisted":false},{"type":"link","label":"Barbican","href":"/docs/iaas/guides/configuration-guide/openstack/barbican","docId":"iaas/guides/configuration-guide/openstack/barbican","unlisted":false},{"type":"link","label":"Ceilometer","href":"/docs/iaas/guides/configuration-guide/openstack/ceilometer","docId":"iaas/guides/configuration-guide/openstack/ceilometer","unlisted":false},{"type":"link","label":"Cinder","href":"/docs/iaas/guides/configuration-guide/openstack/cinder","docId":"iaas/guides/configuration-guide/openstack/cinder","unlisted":false},{"type":"link","label":"Designate","href":"/docs/iaas/guides/configuration-guide/openstack/designate","docId":"iaas/guides/configuration-guide/openstack/designate","unlisted":false},{"type":"link","label":"Glance","href":"/docs/iaas/guides/configuration-guide/openstack/glance","docId":"iaas/guides/configuration-guide/openstack/glance","unlisted":false},{"type":"link","label":"Heat","href":"/docs/iaas/guides/configuration-guide/openstack/heat","docId":"iaas/guides/configuration-guide/openstack/heat","unlisted":false},{"type":"link","label":"Horizon","href":"/docs/iaas/guides/configuration-guide/openstack/horizon","docId":"iaas/guides/configuration-guide/openstack/horizon","unlisted":false},{"type":"link","label":"Ironic","href":"/docs/iaas/guides/configuration-guide/openstack/ironic","docId":"iaas/guides/configuration-guide/openstack/ironic","unlisted":false},{"type":"link","label":"Keystone","href":"/docs/iaas/guides/configuration-guide/openstack/keystone","docId":"iaas/guides/configuration-guide/openstack/keystone","unlisted":false},{"type":"link","label":"Magnum","href":"/docs/iaas/guides/configuration-guide/openstack/magnum","docId":"iaas/guides/configuration-guide/openstack/magnum","unlisted":false},{"type":"link","label":"Manila","href":"/docs/iaas/guides/configuration-guide/openstack/manila","docId":"iaas/guides/configuration-guide/openstack/manila","unlisted":false},{"type":"link","label":"Neutron","href":"/docs/iaas/guides/configuration-guide/openstack/neutron","docId":"iaas/guides/configuration-guide/openstack/neutron","unlisted":false},{"type":"link","label":"Nova","href":"/docs/iaas/guides/configuration-guide/openstack/nova","docId":"iaas/guides/configuration-guide/openstack/nova","unlisted":false},{"type":"link","label":"Octavia","href":"/docs/iaas/guides/configuration-guide/openstack/octavia","docId":"iaas/guides/configuration-guide/openstack/octavia","unlisted":false},{"type":"link","label":"Placement","href":"/docs/iaas/guides/configuration-guide/openstack/placement","docId":"iaas/guides/configuration-guide/openstack/placement","unlisted":false},{"type":"link","label":"Skyline","href":"/docs/iaas/guides/configuration-guide/openstack/skyline","docId":"iaas/guides/configuration-guide/openstack/skyline","unlisted":false}],"href":"/docs/iaas/guides/configuration-guide/openstack/"},{"type":"category","label":"Commons","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Certificates","href":"/docs/iaas/guides/configuration-guide/commons/certificates","docId":"iaas/guides/configuration-guide/commons/certificates","unlisted":false},{"type":"link","label":"Packages","href":"/docs/iaas/guides/configuration-guide/commons/packages","docId":"iaas/guides/configuration-guide/commons/packages","unlisted":false},{"type":"link","label":"Resolvconf","href":"/docs/iaas/guides/configuration-guide/commons/resolvconf","docId":"iaas/guides/configuration-guide/commons/resolvconf","unlisted":false},{"type":"link","label":"Services","href":"/docs/iaas/guides/configuration-guide/commons/services","docId":"iaas/guides/configuration-guide/commons/services","unlisted":false},{"type":"link","label":"SSH Config","href":"/docs/iaas/guides/configuration-guide/commons/sshconfig","docId":"iaas/guides/configuration-guide/commons/sshconfig","unlisted":false},{"type":"link","label":"Sysctl","href":"/docs/iaas/guides/configuration-guide/commons/sysctl","docId":"iaas/guides/configuration-guide/commons/sysctl","unlisted":false},{"type":"link","label":"Timezone","href":"/docs/iaas/guides/configuration-guide/commons/timezone","docId":"iaas/guides/configuration-guide/commons/timezone","unlisted":false},{"type":"link","label":"User","href":"/docs/iaas/guides/configuration-guide/commons/user","docId":"iaas/guides/configuration-guide/commons/user","unlisted":false}],"href":"/docs/iaas/guides/configuration-guide/commons/"},{"type":"category","label":"Services","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Chrony","href":"/docs/iaas/guides/configuration-guide/services/chrony","docId":"iaas/guides/configuration-guide/services/chrony","unlisted":false},{"type":"link","label":"Docker","href":"/docs/iaas/guides/configuration-guide/services/docker","docId":"iaas/guides/configuration-guide/services/docker","unlisted":false},{"type":"link","label":"Tuned","href":"/docs/iaas/guides/configuration-guide/services/tuned","docId":"iaas/guides/configuration-guide/services/tuned","unlisted":false}],"href":"/docs/iaas/guides/configuration-guide/services/"},{"type":"link","label":"Validations","href":"/docs/iaas/guides/configuration-guide/validations/","docId":"iaas/guides/configuration-guide/validations/index","unlisted":false}],"href":"/docs/iaas/guides/configuration-guide/"},{"type":"category","label":"Operations Guide","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Manager","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Apply","href":"/docs/iaas/guides/operations-guide/manager/apply","docId":"iaas/guides/operations-guide/manager/apply","unlisted":false},{"type":"link","label":"Console","href":"/docs/iaas/guides/operations-guide/manager/console","docId":"iaas/guides/operations-guide/manager/console","unlisted":false},{"type":"link","label":"Get","href":"/docs/iaas/guides/operations-guide/manager/get","docId":"iaas/guides/operations-guide/manager/get","unlisted":false},{"type":"link","label":"Logging","href":"/docs/iaas/guides/operations-guide/manager/log","docId":"iaas/guides/operations-guide/manager/log","unlisted":false},{"type":"link","label":"Task","href":"/docs/iaas/guides/operations-guide/manager/task","docId":"iaas/guides/operations-guide/manager/task","unlisted":false}],"href":"/docs/iaas/guides/operations-guide/manager/"},{"type":"link","label":"Ceph","href":"/docs/iaas/guides/operations-guide/ceph","docId":"iaas/guides/operations-guide/ceph","unlisted":false},{"type":"link","label":"Infrastructure","href":"/docs/iaas/guides/operations-guide/infrastructure","docId":"iaas/guides/operations-guide/infrastructure","unlisted":false},{"type":"link","label":"Network","href":"/docs/iaas/guides/operations-guide/network","docId":"iaas/guides/operations-guide/network","unlisted":false},{"type":"category","label":"OpenStack","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Tools","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Image Manager","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Automated updates","href":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","docId":"iaas/guides/operations-guide/openstack/tools/image-manager/update","unlisted":false}],"href":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/"},{"type":"link","label":"Flavor Manager","href":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","docId":"iaas/guides/operations-guide/openstack/tools/flavor-manager","unlisted":false},{"type":"link","label":"Resource Manager","href":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","docId":"iaas/guides/operations-guide/openstack/tools/resource-manager","unlisted":false},{"type":"link","label":"Project Manager","href":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","docId":"iaas/guides/operations-guide/openstack/tools/project-manager","unlisted":false},{"type":"link","label":"Sandbox Manager","href":"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager","docId":"iaas/guides/operations-guide/openstack/tools/sandbox-manager","unlisted":false},{"type":"link","label":"Simple Stress","href":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","docId":"iaas/guides/operations-guide/openstack/tools/simple-stress","unlisted":false},{"type":"link","label":"OpenStack Health Monitor","href":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","docId":"iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","unlisted":false}],"href":"/docs/iaas/guides/operations-guide/openstack/tools/"},{"type":"link","label":"Cinder","href":"/docs/iaas/guides/operations-guide/openstack/cinder","docId":"iaas/guides/operations-guide/openstack/cinder","unlisted":false},{"type":"link","label":"Keystone","href":"/docs/iaas/guides/operations-guide/openstack/keystone","docId":"iaas/guides/operations-guide/openstack/keystone","unlisted":false},{"type":"link","label":"Neutron","href":"/docs/iaas/guides/operations-guide/openstack/neutron","docId":"iaas/guides/operations-guide/openstack/neutron","unlisted":false},{"type":"link","label":"Nova","href":"/docs/iaas/guides/operations-guide/openstack/nova","docId":"iaas/guides/operations-guide/openstack/nova","unlisted":false},{"type":"link","label":"Octavia","href":"/docs/iaas/guides/operations-guide/openstack/octavia","docId":"iaas/guides/operations-guide/openstack/octavia","unlisted":false}],"href":"/docs/iaas/guides/operations-guide/openstack/"}],"href":"/docs/iaas/guides/operations-guide/"},{"type":"category","label":"Troubleshooting Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Manager","href":"/docs/iaas/guides/troubleshooting-guide/manager","docId":"iaas/guides/troubleshooting-guide/manager","unlisted":false},{"type":"link","label":"OpenStack","href":"/docs/iaas/guides/troubleshooting-guide/openstack","docId":"iaas/guides/troubleshooting-guide/openstack","unlisted":false},{"type":"link","label":"Ceph","href":"/docs/iaas/guides/troubleshooting-guide/ceph","docId":"iaas/guides/troubleshooting-guide/ceph","unlisted":false}],"href":"/docs/iaas/guides/troubleshooting-guide/"},{"type":"link","label":"Guides","href":"/docs/iaas/guides/","docId":"iaas/guides/index","unlisted":false},{"type":"category","label":"User Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Migrate from VMware ESXi to OpenStack","href":"/docs/iaas/guides/user-guide/migration-vmware-esix","docId":"iaas/guides/user-guide/migration-vmware-esix","unlisted":false},{"type":"category","label":"OpenStack","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Security groups","href":"/docs/iaas/guides/user-guide/openstack/security-groups","docId":"iaas/guides/user-guide/openstack/security-groups","unlisted":false},{"type":"link","label":"User Data Backups","href":"/docs/iaas/guides/user-guide/openstack/user-data-backups","docId":"iaas/guides/user-guide/openstack/user-data-backups","unlisted":false}],"href":"/docs/iaas/guides/user-guide/openstack/"},{"type":"link","label":"Best Practise: How to configure and use security groups","href":"/docs/iaas/guides/user-guide/security-groups/","docId":"iaas/guides/user-guide/security-groups/security-groups","unlisted":false},{"type":"link","label":"User Data Backups","href":"/docs/iaas/guides/user-guide/user-data-backups","docId":"iaas/guides/user-guide/user-data-backups","unlisted":false}],"href":"/docs/iaas/guides/user-guide/"},{"type":"category","label":"Other Guides","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cloud in a Box Guide","href":"/docs/iaas/guides/other-guides/cloud-in-a-box","docId":"iaas/guides/other-guides/cloud-in-a-box","unlisted":false},{"type":"link","label":"Contributor Guide","href":"/docs/iaas/guides/other-guides/contributor-guide","docId":"iaas/guides/other-guides/contributor-guide","unlisted":false},{"type":"category","label":"Developer Guide","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Releases","href":"/docs/iaas/guides/other-guides/developer-guide/releases","docId":"iaas/guides/other-guides/developer-guide/releases","unlisted":false},{"type":"link","label":"Scripts","href":"/docs/iaas/guides/other-guides/developer-guide/scripts","docId":"iaas/guides/other-guides/developer-guide/scripts","unlisted":false},{"type":"link","label":"Zuul CI","href":"/docs/iaas/guides/other-guides/developer-guide/zuul","docId":"iaas/guides/other-guides/developer-guide/zuul","unlisted":false}],"href":"/docs/iaas/guides/other-guides/developer-guide/"},{"type":"link","label":"Style Guide","href":"/docs/iaas/guides/other-guides/style-guide","docId":"iaas/guides/other-guides/style-guide","unlisted":false},{"type":"link","label":"Testbed Guide","href":"/docs/iaas/guides/other-guides/testbed","docId":"iaas/guides/other-guides/testbed","unlisted":false}],"href":"/docs/iaas/guides/other-guides/"}],"collapsed":true,"collapsible":true},{"type":"category","label":"Components","items":[{"type":"category","label":"Openstack Image Manager","items":[{"type":"link","label":"Automated updates","href":"/docs/iaas/components/image-manager/update","docId":"iaas/components/image-manager/update","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/iaas/components/image-manager/"},{"type":"link","label":"Flavor Manager","href":"/docs/iaas/components/flavor-manager","docId":"iaas/components/flavor-manager","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/components"}],"collapsed":true,"collapsible":true,"href":"/docs/category/iaas-layer"},{"type":"category","label":"Container Layer","items":[{"type":"category","label":"Components","items":[{"type":"category","label":"K8s Cluster API Provider","items":[{"type":"link","label":"Overview","href":"/docs/container/components/k8s-cluster-api-provider/doc/overview","docId":"container/components/k8s-cluster-api-provider/doc/overview","unlisted":false},{"type":"link","label":"Requirements","href":"/docs/container/components/k8s-cluster-api-provider/doc/requirements","docId":"container/components/k8s-cluster-api-provider/doc/requirements","unlisted":false},{"type":"link","label":"Quickstart","href":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","docId":"container/components/k8s-cluster-api-provider/doc/quickstart","unlisted":false},{"type":"link","label":"Makefile reference","href":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","docId":"container/components/k8s-cluster-api-provider/doc/make-reference","unlisted":false},{"type":"link","label":"Application Credentials","href":"/docs/container/components/k8s-cluster-api-provider/doc/application-credentials","docId":"container/components/k8s-cluster-api-provider/doc/application-credentials","unlisted":false},{"type":"link","label":"Configuration","href":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","docId":"container/components/k8s-cluster-api-provider/doc/configuration","unlisted":false},{"type":"link","label":"Maintenance and Troubleshooting Guide for SCS k8s-cluster-api-provider","href":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","docId":"container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","unlisted":false},{"type":"link","label":"Ingress with externalTrafficPolicy: local","href":"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","docId":"container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","unlisted":false},{"type":"link","label":"SCS k8s-cluster-api-provider upgrade guide","href":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","docId":"container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","unlisted":false},{"type":"link","label":"Continuous integration","href":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","docId":"container/components/k8s-cluster-api-provider/doc/continuous-integration","unlisted":false},{"type":"link","label":"Roadmap","href":"/docs/container/components/k8s-cluster-api-provider/doc/roadmap","docId":"container/components/k8s-cluster-api-provider/doc/roadmap","unlisted":false},{"type":"category","label":"Usage","items":[{"type":"link","label":"Usage","href":"/docs/container/components/k8s-cluster-api-provider/doc/usage/","docId":"container/components/k8s-cluster-api-provider/doc/usage/usage","unlisted":false},{"type":"link","label":"Create a new cluster","href":"/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster","docId":"container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster","unlisted":false},{"type":"link","label":"Managing many clusters","href":"/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters","docId":"container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters","unlisted":false},{"type":"link","label":"Cluster Management on the capi management node","href":"/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node","docId":"container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node","unlisted":false},{"type":"link","label":"Multi-AZ and multi-cloud environments","href":"/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments","docId":"container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments","unlisted":false},{"type":"link","label":"Testing","href":"/docs/container/components/k8s-cluster-api-provider/doc/usage/testing","docId":"container/components/k8s-cluster-api-provider/doc/usage/testing","unlisted":false},{"type":"link","label":"Container registry configuration","href":"/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration","docId":"container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration","unlisted":false},{"type":"link","label":"Custom CA","href":"/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca","docId":"container/components/k8s-cluster-api-provider/doc/usage/custom-ca","unlisted":false},{"type":"link","label":"Gateway-API","href":"/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api","docId":"container/components/k8s-cluster-api-provider/doc/usage/gateway-api","unlisted":false},{"type":"link","label":"Harbor","href":"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor","docId":"container/components/k8s-cluster-api-provider/doc/usage/harbor","unlisted":false},{"type":"link","label":"Migration to ClusterClass","href":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class","docId":"container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class","unlisted":false}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true,"href":"/docs/category/k8s-cluster-api-provider"},{"type":"category","label":"Cluster Stacks","items":[{"type":"category","label":"Cluster Stack Provider OpenStack","items":[{"type":"link","label":"Overview","href":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","docId":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","unlisted":false},{"type":"link","label":"Quickstart","href":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","docId":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","unlisted":false},{"type":"link","label":"Controllers","href":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","docId":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","unlisted":false},{"type":"link","label":"Developer Guide","href":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","docId":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","unlisted":false}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true,"href":"/docs/category/cluster-stacks"},{"type":"category","label":"Container Registry","items":[{"type":"link","label":"Quickstart","href":"/docs/container/components/container-registry/docs/quickstart","docId":"container/components/container-registry/docs/quickstart","unlisted":false},{"type":"link","label":"SCS deployment","href":"/docs/container/components/container-registry/docs/scs-deployment","docId":"container/components/container-registry/docs/scs-deployment","unlisted":false},{"type":"link","label":"Rate limit","href":"/docs/container/components/container-registry/docs/rate_limit","docId":"container/components/container-registry/docs/rate_limit","unlisted":false},{"type":"link","label":"Upgrade","href":"/docs/container/components/container-registry/docs/upgrade","docId":"container/components/container-registry/docs/upgrade","unlisted":false},{"type":"link","label":"Backup and restore","href":"/docs/container/components/container-registry/docs/backup_and_restore","docId":"container/components/container-registry/docs/backup_and_restore","unlisted":false},{"type":"link","label":"Migration","href":"/docs/container/components/container-registry/docs/migration","docId":"container/components/container-registry/docs/migration","unlisted":false},{"type":"link","label":"Persistence","href":"/docs/container/components/container-registry/docs/persistence","docId":"container/components/container-registry/docs/persistence","unlisted":false},{"type":"link","label":"HA deployment","href":"/docs/container/components/container-registry/docs/ha-deployment","docId":"container/components/container-registry/docs/ha-deployment","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/container-registry"}],"collapsed":true,"collapsible":true,"href":"/docs/category/components-1"}],"collapsed":true,"collapsible":true,"href":"/docs/container/"},{"type":"category","label":"Operating SCS","items":[{"type":"category","label":"Components","items":[{"type":"category","label":"Status Page API","items":[{"type":"link","label":"Overview","href":"/docs/operating-scs/components/status-page/docs/overview","docId":"operating-scs/components/status-page/docs/overview","unlisted":false},{"type":"link","label":"Component Overview","href":"/docs/operating-scs/components/status-page/docs/component_overview","docId":"operating-scs/components/status-page/docs/component_overview","unlisted":false},{"type":"link","label":"Components","href":"/docs/operating-scs/components/status-page/docs/components","docId":"operating-scs/components/status-page/docs/components","unlisted":false},{"type":"link","label":"\\"Levels of consensus\\"","href":"/docs/operating-scs/components/status-page/docs/levels_of_consensus","docId":"operating-scs/components/status-page/docs/levels_of_consensus","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/status-page-api"},{"type":"category","label":"Monitoring","items":[{"type":"link","label":"Overview","href":"/docs/operating-scs/components/monitoring/docs/overview","docId":"operating-scs/components/monitoring/docs/overview","unlisted":false},{"type":"link","label":"Quickstart","href":"/docs/operating-scs/components/monitoring/docs/quickstart","docId":"operating-scs/components/monitoring/docs/quickstart","unlisted":false},{"type":"link","label":"SCS deployment","href":"/docs/operating-scs/components/monitoring/docs/scs-deployment","docId":"operating-scs/components/monitoring/docs/scs-deployment","unlisted":false},{"type":"link","label":"K3s support","href":"/docs/operating-scs/components/monitoring/docs/k3s","docId":"operating-scs/components/monitoring/docs/k3s","unlisted":false},{"type":"link","label":"Infrastructure service endpoints","href":"/docs/operating-scs/components/monitoring/docs/infrastructure_services","docId":"operating-scs/components/monitoring/docs/infrastructure_services","unlisted":false},{"type":"link","label":"IaaS monitoring (experimental)","href":"/docs/operating-scs/components/monitoring/docs/iaas","docId":"operating-scs/components/monitoring/docs/iaas","unlisted":false},{"type":"link","label":"KaaS monitoring (experimental)","href":"/docs/operating-scs/components/monitoring/docs/kaas","docId":"operating-scs/components/monitoring/docs/kaas","unlisted":false},{"type":"link","label":"Zuul monitoring","href":"/docs/operating-scs/components/monitoring/docs/zuul","docId":"operating-scs/components/monitoring/docs/zuul","unlisted":false},{"type":"link","label":"Alertmanager notifications in Matrix chat","href":"/docs/operating-scs/components/monitoring/docs/alertmanager","docId":"operating-scs/components/monitoring/docs/alertmanager","unlisted":false},{"type":"link","label":"OAUTH","href":"/docs/operating-scs/components/monitoring/docs/oauth","docId":"operating-scs/components/monitoring/docs/oauth","unlisted":false},{"type":"link","label":"Traces","href":"/docs/operating-scs/components/monitoring/docs/tracing","docId":"operating-scs/components/monitoring/docs/tracing","unlisted":false},{"type":"link","label":"Tuning","href":"/docs/operating-scs/components/monitoring/docs/tuning","docId":"operating-scs/components/monitoring/docs/tuning","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/monitoring"},{"type":"category","label":"Central API","items":[{"type":"link","label":"Overview","href":"/docs/operating-scs/components/central-api/overview","docId":"operating-scs/components/central-api/overview","unlisted":false},{"type":"link","label":"Central API MVP","href":"/docs/operating-scs/components/central-api/poc-setup","docId":"operating-scs/components/central-api/poc-setup","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/central-api"},{"type":"category","label":"Automated Pentesting","items":[{"type":"link","label":"SCS automated pentesting","href":"/docs/operating-scs/components/automated-pentesting/overview","docId":"operating-scs/components/automated-pentesting/overview","unlisted":false},{"type":"link","label":"Tools Description","href":"/docs/operating-scs/components/automated-pentesting/tools","docId":"operating-scs/components/automated-pentesting/tools","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/automated-pentesting"}],"collapsed":true,"collapsible":true,"href":"/docs/category/components-2"},{"type":"category","label":"Guides","items":[{"type":"link","label":"Guide: Setting up openstack-health-monitor on Debian 12","href":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","docId":"operating-scs/guides/openstack-health-monitor/Debian12-Install","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/guides-1"},{"type":"category","label":"Metering","items":[{"type":"link","label":"Metering Configuration","href":"/docs/operating-scs/metering/meter_configuration","docId":"operating-scs/metering/meter_configuration","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/metering"}],"collapsed":true,"collapsible":true,"href":"/docs/category/operating-scs"},{"type":"category","label":"Identity and Access Management (IAM)","items":[{"type":"category","label":"Guides","items":[{"type":"link","label":"Domain Manager setup and usage","href":"/docs/iam/domain-manager-setup-and-usage","docId":"iam/domain-manager-setup-and-usage","unlisted":false},{"type":"link","label":"Example setup configuration in SCS deployment explained","href":"/docs/iam/SCS-example-setup-configuration-description","docId":"iam/SCS-example-setup-configuration-description","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/guides-2"},{"type":"link","label":"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)","href":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","docId":"iam/intra-SCS-federation-setup-description-for-osism-doc-operations","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/iam/"},{"type":"category","label":"Releases","items":[{"type":"link","label":"Release Notes for SCS Release 0","href":"/docs/releases/Release0","docId":"releases/Release0","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 1","href":"/docs/releases/Release1","docId":"releases/Release1","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 2","href":"/docs/releases/Release2","docId":"releases/Release2","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 3","href":"/docs/releases/Release3","docId":"releases/Release3","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 4","href":"/docs/releases/Release4","docId":"releases/Release4","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 5","href":"/docs/releases/Release5","docId":"releases/Release5","unlisted":false},{"type":"link","label":"Release Notes for SCS Release 6","href":"/docs/releases/Release6","docId":"releases/Release6","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/docs/category/releases"},{"type":"link","label":"FAQ","href":"/docs/faq/","docId":"faq/index","unlisted":false},{"type":"link","label":"Glossary","href":"/docs/glossary","docId":"glossary","unlisted":false}]},"docs":{"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers":{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","title":"Controllers","description":"OpenStackClusterStackRelease controller","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop":{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","title":"Developer Guide","description":"Developing Cluster Stack Provider OpenStack operator is quite straightforward. First, you need to install some basic prerequisites:","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview":{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","title":"Overview","description":"The Cluster Stack Provider OpenStack (CSPO) works with the Cluster Stack Operator (CSO) and Cluster Stacks, enabling the creation of Kubernetes clusters in a Cluster-API-native (CAPI) fashion.","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart":{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","title":"Quickstart","description":"This document has been moved.","sidebar":"docs"},"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting":{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","title":"Troubleshooting","description":"This guide explains general info on how to debug issues if a cluster creation fails."},"container/components/container-registry/docs/backup_and_restore":{"id":"container/components/container-registry/docs/backup_and_restore","title":"Backup and restore","description":"This page aims at providing a step-by-step guide for backup and restore Harbor","sidebar":"docs"},"container/components/container-registry/docs/ha-deployment":{"id":"container/components/container-registry/docs/ha-deployment","title":"HA deployment","description":"Prerequisites","sidebar":"docs"},"container/components/container-registry/docs/migration":{"id":"container/components/container-registry/docs/migration","title":"Migration","description":"harbormigration.png","sidebar":"docs"},"container/components/container-registry/docs/persistence":{"id":"container/components/container-registry/docs/persistence","title":"Persistence","description":"This page briefly describes and provides pointers on how Harbor persists data when it is","sidebar":"docs"},"container/components/container-registry/docs/quickstart":{"id":"container/components/container-registry/docs/quickstart","title":"Quickstart","description":"This guide shows you how to set up a working Harbor Container Registry that utilizes a Kubernetes cluster.","sidebar":"docs"},"container/components/container-registry/docs/rate_limit":{"id":"container/components/container-registry/docs/rate_limit","title":"Rate limit","description":"This page describes how the rate limiting can be set up for the Harbor container registry.","sidebar":"docs"},"container/components/container-registry/docs/scs-deployment":{"id":"container/components/container-registry/docs/scs-deployment","title":"SCS deployment","description":"The following steps were utilized for deploying the SCS reference installation of the Harbor container registry,","sidebar":"docs"},"container/components/container-registry/docs/upgrade":{"id":"container/components/container-registry/docs/upgrade","title":"Upgrade","description":"This page aims at providing additional information for upgrading Harbor","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/application-credentials":{"id":"container/components/k8s-cluster-api-provider/doc/application-credentials","title":"Application Credentials","description":"OpenTofu creates an application credential that it passes into the created VM. This one is then used to authenticate the cluster API provider against the OpenStack API to allow it to create resources needed for the k8s cluster.","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/configuration":{"id":"container/components/k8s-cluster-api-provider/doc/configuration","title":"Configuration","description":"Supported k8s versions","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/continuous-integration":{"id":"container/components/k8s-cluster-api-provider/doc/continuous-integration","title":"Continuous integration","description":"Project k8s-cluster-api-provider uses SCS Zuul CI platform to","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal":{"id":"container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","title":"Ingress with externalTrafficPolicy: local","description":"Setting up the nginx ingress controller from the upstream deployment templates","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting":{"id":"container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","title":"Maintenance and Troubleshooting Guide for SCS k8s-cluster-api-provider","description":"Client Certificates in Kubernetes expire after one year","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/make-reference":{"id":"container/components/k8s-cluster-api-provider/doc/make-reference","title":"Makefile reference","description":"This is a reference to the Makefile targets.","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/overview":{"id":"container/components/k8s-cluster-api-provider/doc/overview","title":"Overview","description":"Creating and scaling k8s clusters on demand is providing a lot of flexibility to DevOps teams that develop, test, deploy and operate services and applications.","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/quickstart":{"id":"container/components/k8s-cluster-api-provider/doc/quickstart","title":"Quickstart","description":"This guide shows you how to get working Kubernetes clusters on a SCS cloud","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/requirements":{"id":"container/components/k8s-cluster-api-provider/doc/requirements","title":"Requirements","description":"Cluster API requires an existing Kubernetes cluster to operate. In our setup, we","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/roadmap":{"id":"container/components/k8s-cluster-api-provider/doc/roadmap","title":"Roadmap","description":"Advanced cluster templating with helm (Technical Preview)","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/Upgrade-Guide":{"id":"container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","title":"SCS k8s-cluster-api-provider upgrade guide","description":"SCS k8s-cluster-api-provider upgrade guide","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node":{"id":"container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node","title":"Cluster Management on the capi management node","description":"You can use make ssh to log in to the capi management server. There you can issueclusterctl and kubectl (aliased","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration":{"id":"container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration","title":"Container registry configuration","description":"Containerd as container runtime","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster":{"id":"container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster","title":"Create a new cluster","description":"On the management server (login with make ssh), create a directory (below the home of","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/usage/custom-ca":{"id":"container/components/k8s-cluster-api-provider/doc/usage/custom-ca","title":"Custom CA","description":"OpenStack provides public-facing API endpoints which protection by SSL/TLS certificates","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/usage/gateway-api":{"id":"container/components/k8s-cluster-api-provider/doc/usage/gateway-api","title":"Gateway-API","description":"Starting with R5, this k8s-solution offers experimental kubernetes gateway API support. You need to set deploygatewayapi to true in your environments configuration. Also you need to use cilium as your CNI (default since R5).","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/usage/harbor":{"id":"container/components/k8s-cluster-api-provider/doc/usage/harbor","title":"Harbor","description":"Project k8s-harbor is used for the SCS Harbor","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters":{"id":"container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters","title":"Managing many clusters","description":"While the scripts all use a default testcluster, they have","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class":{"id":"container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class","title":"Migration to ClusterClass","description":"From #600, this repository uses CAPI","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2":{"id":"container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2","title":"Migration to KaaS v2","description":"From R6, k8s-cluster-api-provider repository (SCS KaaS reference implementation v1) is deprecated"},"container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments":{"id":"container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments","title":"Multi-AZ and multi-cloud environments","description":"The provided cluster-template.yaml assumes that all control nodes on one hand and all worker nodes on the other are","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/usage/testing":{"id":"container/components/k8s-cluster-api-provider/doc/usage/testing","title":"Testing","description":"To test the created k8s cluster, there are several tools available.","sidebar":"docs"},"container/components/k8s-cluster-api-provider/doc/usage/usage":{"id":"container/components/k8s-cluster-api-provider/doc/usage/usage","title":"Usage","description":"The subsequent management of the cluster can best be done from the management server VM, as it has all the tools","sidebar":"docs"},"container/deployment-examples/a/hardware":{"id":"container/deployment-examples/a/hardware","title":"Hardware Requirements","description":"TODO"},"container/deployment-examples/a/index":{"id":"container/deployment-examples/a/index","title":"Overview","description":"TODO"},"container/deployment-examples/a/software":{"id":"container/deployment-examples/a/software","title":"Software Requirements","description":"TODO"},"container/guides/guide1":{"id":"container/guides/guide1","title":"Guide 1","description":"TODO"},"container/index":{"id":"container/index","title":"Container Layer Introduction","description":"The container layer within the Sovereign Cloud Stack (SCS) offers a robust solution for managing container workloads on a Kubernetes infrastructure. It facilitates the on-demand creation and scaling of Kubernetes clusters, catering to various needs across development, testing, deployment, and operation of services and applications. While the container layer is versatile for a range of use cases, the most common ones include:","sidebar":"docs"},"container/overview/architecture":{"id":"container/overview/architecture","title":"Architecture","description":"TODO"},"container/overview/knowledge":{"id":"container/overview/knowledge","title":"Knowledge","description":"TODO"},"faq/index":{"id":"faq/index","title":"Frequently Asked Questions","description":"What does SCS stand for?","sidebar":"docs"},"getting-started/containerization":{"id":"getting-started/containerization","title":"Containerization","description":"TODO"},"getting-started/overview":{"id":"getting-started/overview","title":"Overview","description":"TODO"},"getting-started/virtualization":{"id":"getting-started/virtualization","title":"Virtualization","description":"TODO"},"glossary":{"id":"glossary","title":"Glossary","description":"This file serves as the central glossary within SCS. It is intended to clearly","sidebar":"docs"},"iaas/components/flavor-manager":{"id":"iaas/components/flavor-manager","title":"Flavor Manager","description":"Overview","sidebar":"docs"},"iaas/components/image-manager/index":{"id":"iaas/components/image-manager/index","title":"Image Manager","description":"The OpenStack Image Manager is a tool for managing all","sidebar":"docs"},"iaas/components/image-manager/update":{"id":"iaas/components/image-manager/update","title":"Image Manager update.py","description":"Overview","sidebar":"docs"},"iaas/components/index":{"id":"iaas/components/index","title":"Tools","description":""},"iaas/components/openstack-health-monitor":{"id":"iaas/components/openstack-health-monitor","title":"Setting up OpenStack health monitor on Debian","description":"Kurt Garloff, 2024-02-20"},"iaas/components/project-manager":{"id":"iaas/components/project-manager","title":"Project Manager","description":"Overview"},"iaas/components/resource-manager":{"id":"iaas/components/resource-manager","title":"Resource Manager","description":"Preparations"},"iaas/components/sandbox-manager":{"id":"iaas/components/sandbox-manager","title":"Sandbox Manager","description":""},"iaas/components/simple-stress":{"id":"iaas/components/simple-stress","title":"Simple Stress","description":"Overview"},"iaas/guides/concept-guide/components/ceph":{"id":"iaas/guides/concept-guide/components/ceph","title":"Ceph","description":"Ceph is an Open Source software defined storage platform designed to provide highly scalable","sidebar":"docs"},"iaas/guides/concept-guide/components/clusterapi":{"id":"iaas/guides/concept-guide/components/clusterapi","title":"Cluster API","description":"Kubernetes as a Service (KaaS) is a cloud service model that simplifies the deployment,","sidebar":"docs"},"iaas/guides/concept-guide/components/gardener":{"id":"iaas/guides/concept-guide/components/gardener","title":"Gardener","description":"Kubernetes as a Service (KaaS) simplifies the deployment, management, and scaling of","sidebar":"docs"},"iaas/guides/concept-guide/components/index":{"id":"iaas/guides/concept-guide/components/index","title":"Components","description":"* Infrastructure as a Service (IaaS) with OpenStack","sidebar":"docs"},"iaas/guides/concept-guide/components/ironic":{"id":"iaas/guides/concept-guide/components/ironic","title":"Ironic","description":"OpenStack Ironic is a project that provides Baremetal as a Service (BMaaS), enabling the","sidebar":"docs"},"iaas/guides/concept-guide/components/k3s":{"id":"iaas/guides/concept-guide/components/k3s","title":"K3S","description":"Lifecycle Management of K3S in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/components/keycloak":{"id":"iaas/guides/concept-guide/components/keycloak","title":"Keycloak","description":"Lifecycle Management of Keycloak in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/components/netdata":{"id":"iaas/guides/concept-guide/components/netdata","title":"Netdata","description":"Lifecycle Management of Netdata in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/components/openstack":{"id":"iaas/guides/concept-guide/components/openstack","title":"OpenStack","description":"Lifecycle Management of OpenStack in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/components/prometheus":{"id":"iaas/guides/concept-guide/components/prometheus","title":"Prometheus & Grafana","description":"Lifecycle Management of Prometheus in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/components/proxmox":{"id":"iaas/guides/concept-guide/components/proxmox","title":"Proxmox VE","description":"Proxmox Virtual Environment (Proxmox VE) is an open-source server virtualization management","sidebar":"docs"},"iaas/guides/concept-guide/components/sonic":{"id":"iaas/guides/concept-guide/components/sonic","title":"SONiC & OVN","description":"Lifecycle Management of SONiC in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/components/teleport":{"id":"iaas/guides/concept-guide/components/teleport","title":"Teleport","description":"Lifecycle Management of Teleport in OSISM","sidebar":"docs"},"iaas/guides/concept-guide/design":{"id":"iaas/guides/concept-guide/design","title":"Cluster design","description":"Parts of this chapter are based on the OpenStack Architecture Design Guide.","sidebar":"docs"},"iaas/guides/concept-guide/hardware-bom":{"id":"iaas/guides/concept-guide/hardware-bom","title":"Hardware Bill of Materials","description":"The brands, models and configurations listed are examples. There is no","sidebar":"docs"},"iaas/guides/concept-guide/index":{"id":"iaas/guides/concept-guide/index","title":"Concept Guide","description":"Highlevel Overview","sidebar":"docs"},"iaas/guides/concept-guide/layers":{"id":"iaas/guides/concept-guide/layers","title":"Layers in a cluster","description":"Compute Plane","sidebar":"docs"},"iaas/guides/concept-guide/use-cases":{"id":"iaas/guides/concept-guide/use-cases","title":"Use cases","description":"Hyper-converged infrastructure (HCI)","sidebar":"docs"},"iaas/guides/configuration-guide/ceph":{"id":"iaas/guides/configuration-guide/ceph","title":"Ceph","description":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/","sidebar":"docs"},"iaas/guides/configuration-guide/commons/certificates":{"id":"iaas/guides/configuration-guide/commons/certificates","title":"Certificates","description":"With the osism.commons.certificates role, it is possible to add custom CA certificates","sidebar":"docs"},"iaas/guides/configuration-guide/commons/index":{"id":"iaas/guides/configuration-guide/commons/index","title":"Commons","description":"This section contains the documentation of the Ansible collection osism.commons.","sidebar":"docs"},"iaas/guides/configuration-guide/commons/packages":{"id":"iaas/guides/configuration-guide/commons/packages","title":"Packages","description":"With the osism.commons.packages role, it is possible to add packages on a node","sidebar":"docs"},"iaas/guides/configuration-guide/commons/resolvconf":{"id":"iaas/guides/configuration-guide/commons/resolvconf","title":"Resolvconf","description":"With the osism.commons.resolvconf role, it is possible to manage the used DNS servers on a node.","sidebar":"docs"},"iaas/guides/configuration-guide/commons/services":{"id":"iaas/guides/configuration-guide/commons/services","title":"Services","description":"With the osism.commons.services role, it is possible to manage services on a node","sidebar":"docs"},"iaas/guides/configuration-guide/commons/sshconfig":{"id":"iaas/guides/configuration-guide/commons/sshconfig","title":"SSH Config","description":"With the osism.commons.sshconfig role, it is possible to manage a SSH config","sidebar":"docs"},"iaas/guides/configuration-guide/commons/sysctl":{"id":"iaas/guides/configuration-guide/commons/sysctl","title":"Sysctl","description":"With the osism.commons.sysctl role, it is possible to manage the attributes of the kernel","sidebar":"docs"},"iaas/guides/configuration-guide/commons/timezone":{"id":"iaas/guides/configuration-guide/commons/timezone","title":"Timezone","description":"With the osism.commons.timezone role, it is possible to manage the used timezone on a node.","sidebar":"docs"},"iaas/guides/configuration-guide/commons/user":{"id":"iaas/guides/configuration-guide/commons/user","title":"User","description":"With the osism.commons.user role, it is possible to manage additional","sidebar":"docs"},"iaas/guides/configuration-guide/configuration-repository":{"id":"iaas/guides/configuration-guide/configuration-repository","title":"Configuration Repository","description":"The configuration required for an OSISM managed cluster is stored in a single Git","sidebar":"docs"},"iaas/guides/configuration-guide/index":{"id":"iaas/guides/configuration-guide/index","title":"Configuration Guide","description":"","sidebar":"docs"},"iaas/guides/configuration-guide/inventory":{"id":"iaas/guides/configuration-guide/inventory","title":"Inventory","description":"The inventory used for the environment is located in the inventory directory.","sidebar":"docs"},"iaas/guides/configuration-guide/loadbalancer":{"id":"iaas/guides/configuration-guide/loadbalancer","title":"Loadbalancer","description":"Second Loadbalancer","sidebar":"docs"},"iaas/guides/configuration-guide/manager":{"id":"iaas/guides/configuration-guide/manager","title":"Manager","description":"Stable release","sidebar":"docs"},"iaas/guides/configuration-guide/network":{"id":"iaas/guides/configuration-guide/network","title":"Network","description":"Netplan","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/aodh":{"id":"iaas/guides/configuration-guide/openstack/aodh","title":"Aodh","description":"* Aodh admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/barbican":{"id":"iaas/guides/configuration-guide/openstack/barbican","title":"Barbican","description":"* Barbican admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/ceilometer":{"id":"iaas/guides/configuration-guide/openstack/ceilometer","title":"Ceilometer","description":"* Ceilometer admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/cinder":{"id":"iaas/guides/configuration-guide/openstack/cinder","title":"Cinder","description":"* Cinder admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/designate":{"id":"iaas/guides/configuration-guide/openstack/designate","title":"Designate","description":"* Designate admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/glance":{"id":"iaas/guides/configuration-guide/openstack/glance","title":"Glance","description":"* Glance admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/heat":{"id":"iaas/guides/configuration-guide/openstack/heat","title":"Heat","description":"* Heat admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/horizon":{"id":"iaas/guides/configuration-guide/openstack/horizon","title":"Horizon","description":"* Horizon admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/index":{"id":"iaas/guides/configuration-guide/openstack/index","title":"OpenStack","description":"Image tags","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/ironic":{"id":"iaas/guides/configuration-guide/openstack/ironic","title":"Ironic","description":"* Ironic admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/keystone":{"id":"iaas/guides/configuration-guide/openstack/keystone","title":"Keystone","description":"* Keystone admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/magnum":{"id":"iaas/guides/configuration-guide/openstack/magnum","title":"Magnum","description":"* Magnum admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/manila":{"id":"iaas/guides/configuration-guide/openstack/manila","title":"Manila","description":"* Manila admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/neutron":{"id":"iaas/guides/configuration-guide/openstack/neutron","title":"Neutron","description":"* Neutron admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/nova":{"id":"iaas/guides/configuration-guide/openstack/nova","title":"Nova","description":"* Nova admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/octavia":{"id":"iaas/guides/configuration-guide/openstack/octavia","title":"Octavia","description":"* Octavia admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/placement":{"id":"iaas/guides/configuration-guide/openstack/placement","title":"Placement","description":"* Placement admin guide","sidebar":"docs"},"iaas/guides/configuration-guide/openstack/skyline":{"id":"iaas/guides/configuration-guide/openstack/skyline","title":"Skyline","description":"Skyline APIServer","sidebar":"docs"},"iaas/guides/configuration-guide/proxy":{"id":"iaas/guides/configuration-guide/proxy","title":"Proxy","description":"In the following examples, it is assumed that the Squid proxy integrated by OSISM","sidebar":"docs"},"iaas/guides/configuration-guide/self-signed-certificates":{"id":"iaas/guides/configuration-guide/self-signed-certificates","title":"Self-signed certificates","description":"The use of self-signed certificates with a custom CA is possible. However, a few","sidebar":"docs"},"iaas/guides/configuration-guide/services/chrony":{"id":"iaas/guides/configuration-guide/services/chrony","title":"Chrony","description":"With the osism.services.chrony role, it is possible to manage the used NTP servers on a node.","sidebar":"docs"},"iaas/guides/configuration-guide/services/docker":{"id":"iaas/guides/configuration-guide/services/docker","title":"Docker","description":"With the osism.services.docker role, it is possible to manage Docker.","sidebar":"docs"},"iaas/guides/configuration-guide/services/index":{"id":"iaas/guides/configuration-guide/services/index","title":"Services","description":"This section contains the documentation of the Ansible collection","sidebar":"docs"},"iaas/guides/configuration-guide/services/tuned":{"id":"iaas/guides/configuration-guide/services/tuned","title":"Tuned","description":"The roller can be applied with osism apply tuned. The role is applied to all","sidebar":"docs"},"iaas/guides/configuration-guide/validations/index":{"id":"iaas/guides/configuration-guide/validations/index","title":"Validations","description":"This section contains the documentation of the Ansible collection","sidebar":"docs"},"iaas/guides/deploy-guide/bootstrap":{"id":"iaas/guides/deploy-guide/bootstrap","title":"Bootstrap","description":"The prerequisite for bootstraping the nodes of a cluster the Manager node has to be","sidebar":"docs"},"iaas/guides/deploy-guide/examples/cloud-in-a-box":{"id":"iaas/guides/deploy-guide/examples/cloud-in-a-box","title":"Cloud in a Box","description":"This section has moved. You can now find the content in the","sidebar":"docs"},"iaas/guides/deploy-guide/examples/index":{"id":"iaas/guides/deploy-guide/examples/index","title":"Examples","description":"","sidebar":"docs"},"iaas/guides/deploy-guide/examples/testbed":{"id":"iaas/guides/deploy-guide/examples/testbed","title":"Testbed","description":"This section has moved. You can now find the content in the","sidebar":"docs"},"iaas/guides/deploy-guide/index":{"id":"iaas/guides/deploy-guide/index","title":"Deploy Guide","description":"OSISM is deployed in a series of successive steps. The steps are documented in the Deploy Guide.","sidebar":"docs"},"iaas/guides/deploy-guide/manager":{"id":"iaas/guides/deploy-guide/manager","title":"Manager","description":"The prerequisite for deploying the Manager node is a Seed node. What a Seed node is","sidebar":"docs"},"iaas/guides/deploy-guide/provisioning":{"id":"iaas/guides/deploy-guide/provisioning","title":"Provisioning of bare-metal nodes","description":"For the initial deployment of the management plane and the control plane of OSISM,","sidebar":"docs"},"iaas/guides/deploy-guide/seed":{"id":"iaas/guides/deploy-guide/seed","title":"Seed","description":"The prerequisite for the deployment of a cluster is a configuration repository.","sidebar":"docs"},"iaas/guides/deploy-guide/services/ceph":{"id":"iaas/guides/deploy-guide/services/ceph","title":"Ceph","description":"In OSISM it is also possible to integrate and use existing Ceph clusters. It","sidebar":"docs"},"iaas/guides/deploy-guide/services/index":{"id":"iaas/guides/deploy-guide/services/index","title":"Services","description":"The prerequisite for depoying the services of a cluster is the bootstrap of","sidebar":"docs"},"iaas/guides/deploy-guide/services/infrastructure":{"id":"iaas/guides/deploy-guide/services/infrastructure","title":"Infrastructure","description":"Common issues with deploying infrastructure services required by OpenStack","sidebar":"docs"},"iaas/guides/deploy-guide/services/kubernetes":{"id":"iaas/guides/deploy-guide/services/kubernetes","title":"Kubernetes","description":"As of OSISM 7, it is possible to create a Kubernetes cluster on all nodes.","sidebar":"docs"},"iaas/guides/deploy-guide/services/logging-monitoring":{"id":"iaas/guides/deploy-guide/services/logging-monitoring","title":"Logging & Monitoring","description":"Common issues with deploying logging & monitoring services provided by Kolla","sidebar":"docs"},"iaas/guides/deploy-guide/services/network":{"id":"iaas/guides/deploy-guide/services/network","title":"Network","description":"1. Open vSwitch (OVS)","sidebar":"docs"},"iaas/guides/deploy-guide/services/openstack":{"id":"iaas/guides/deploy-guide/services/openstack","title":"OpenStack","description":"Common issues with deploying OpenStack services are documented in the","sidebar":"docs"},"iaas/guides/index":{"id":"iaas/guides/index","title":"Guides","description":"* The Concept Guide explains which components and modules make up OSISM. It also","sidebar":"docs"},"iaas/guides/operations-guide/ceph":{"id":"iaas/guides/operations-guide/ceph","title":"Ceph","description":"Where to find docs","sidebar":"docs"},"iaas/guides/operations-guide/index":{"id":"iaas/guides/operations-guide/index","title":"Operations Guide","description":"Change Node states","sidebar":"docs"},"iaas/guides/operations-guide/infrastructure":{"id":"iaas/guides/operations-guide/infrastructure","title":"Infrastructure","description":"MariaDB","sidebar":"docs"},"iaas/guides/operations-guide/manager/apply":{"id":"iaas/guides/operations-guide/manager/apply","title":"Apply","description":"List all available plays","sidebar":"docs"},"iaas/guides/operations-guide/manager/console":{"id":"iaas/guides/operations-guide/manager/console","title":"Console","description":"A console command is available in the OSISM CLI. This allows specific parts of the","sidebar":"docs"},"iaas/guides/operations-guide/manager/get":{"id":"iaas/guides/operations-guide/manager/get","title":"Get","description":"A get command is available in the OSISM CLI. This allows to gather specific information.","sidebar":"docs"},"iaas/guides/operations-guide/manager/index":{"id":"iaas/guides/operations-guide/manager/index","title":"Manager","description":"OSISM orchestrator","sidebar":"docs"},"iaas/guides/operations-guide/manager/log":{"id":"iaas/guides/operations-guide/manager/log","title":"Logging","description":"Ansible","sidebar":"docs"},"iaas/guides/operations-guide/manager/task":{"id":"iaas/guides/operations-guide/manager/task","title":"Task","description":"List","sidebar":"docs"},"iaas/guides/operations-guide/network":{"id":"iaas/guides/operations-guide/network","title":"Network","description":"OpenStack, OVN, and Open vSwitch all really like UUIDs.","sidebar":"docs"},"iaas/guides/operations-guide/openstack/cinder":{"id":"iaas/guides/operations-guide/openstack/cinder","title":"Cinder","description":"Remove service","sidebar":"docs"},"iaas/guides/operations-guide/openstack/index":{"id":"iaas/guides/operations-guide/openstack/index","title":"OpenStack","description":"Create an external network","sidebar":"docs"},"iaas/guides/operations-guide/openstack/keystone":{"id":"iaas/guides/operations-guide/openstack/keystone","title":"Keystone","description":"* List all users of a project who have been assigned the member role","sidebar":"docs"},"iaas/guides/operations-guide/openstack/neutron":{"id":"iaas/guides/operations-guide/openstack/neutron","title":"Neutron","description":"Quality of Service (QoS)","sidebar":"docs"},"iaas/guides/operations-guide/openstack/nova":{"id":"iaas/guides/operations-guide/openstack/nova","title":"Nova","description":"Get all servers on a node","sidebar":"docs"},"iaas/guides/operations-guide/openstack/octavia":{"id":"iaas/guides/operations-guide/openstack/octavia","title":"Octavia","description":"Cleanup of amphorae missing from the DB","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/flavor-manager":{"id":"iaas/guides/operations-guide/openstack/tools/flavor-manager","title":"Flavor Manager","description":"Overview","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/image-manager/index":{"id":"iaas/guides/operations-guide/openstack/tools/image-manager/index","title":"Image Manager","description":"The OpenStack Image Manager is a tool for managing all","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/image-manager/update":{"id":"iaas/guides/operations-guide/openstack/tools/image-manager/update","title":"Image Manager update.py","description":"Overview","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/index":{"id":"iaas/guides/operations-guide/openstack/tools/index","title":"Tools","description":"","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/openstack-health-monitor":{"id":"iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","title":"Setting up OpenStack health monitor on Debian","description":"Kurt Garloff, 2024-02-20","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/project-manager":{"id":"iaas/guides/operations-guide/openstack/tools/project-manager","title":"Project Manager","description":"Overview","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/resource-manager":{"id":"iaas/guides/operations-guide/openstack/tools/resource-manager","title":"Resource Manager","description":"Preparations","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/sandbox-manager":{"id":"iaas/guides/operations-guide/openstack/tools/sandbox-manager","title":"Sandbox Manager","description":"","sidebar":"docs"},"iaas/guides/operations-guide/openstack/tools/simple-stress":{"id":"iaas/guides/operations-guide/openstack/tools/simple-stress","title":"Simple Stress","description":"Overview","sidebar":"docs"},"iaas/guides/other-guides/cloud-in-a-box":{"id":"iaas/guides/other-guides/cloud-in-a-box","title":"Cloud in a Box - CiaB","description":"\ud83d\udca1 Cloud in a Box (CiaB) is a minimalistic installation of the latest stable OSISM release with only services which are needed to","sidebar":"docs"},"iaas/guides/other-guides/contributor-guide":{"id":"iaas/guides/other-guides/contributor-guide","title":"Contributor Guide","description":"We welcome any issues, change requests or general feedback. Do not hestiate to open an issue.","sidebar":"docs"},"iaas/guides/other-guides/developer-guide/index":{"id":"iaas/guides/other-guides/developer-guide/index","title":"Developer Guide","description":"How to add a new service","sidebar":"docs"},"iaas/guides/other-guides/developer-guide/releases":{"id":"iaas/guides/other-guides/developer-guide/releases","title":"Releases","description":"How we handle releases","sidebar":"docs"},"iaas/guides/other-guides/developer-guide/scripts":{"id":"iaas/guides/other-guides/developer-guide/scripts","title":"Scripts","description":"Scripts are included in container images to simplify development work and to enable","sidebar":"docs"},"iaas/guides/other-guides/developer-guide/zuul":{"id":"iaas/guides/other-guides/developer-guide/zuul","title":"Zuul CI","description":"We use Zuul CI as a CI service for OSISM. The service is not required for","sidebar":"docs"},"iaas/guides/other-guides/index":{"id":"iaas/guides/other-guides/index","title":"Other Guides","description":"","sidebar":"docs"},"iaas/guides/other-guides/style-guide":{"id":"iaas/guides/other-guides/style-guide","title":"Style Guide","description":"Ansible","sidebar":"docs"},"iaas/guides/other-guides/testbed":{"id":"iaas/guides/other-guides/testbed","title":"Testbed","description":"With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack","sidebar":"docs"},"iaas/guides/troubleshooting-guide/ceph":{"id":"iaas/guides/troubleshooting-guide/ceph","title":"Ceph","description":"Where to find docs","sidebar":"docs"},"iaas/guides/troubleshooting-guide/index":{"id":"iaas/guides/troubleshooting-guide/index","title":"Troubleshooting Guide","description":"\ud83d\udca1 The Troubleshooting Guide describe how to solve issues.","sidebar":"docs"},"iaas/guides/troubleshooting-guide/manager":{"id":"iaas/guides/troubleshooting-guide/manager","title":"Manager","description":"Reset","sidebar":"docs"},"iaas/guides/troubleshooting-guide/openstack":{"id":"iaas/guides/troubleshooting-guide/openstack","title":"OpenStack","description":"Database creation fails","sidebar":"docs"},"iaas/guides/upgrade-guide/ceph":{"id":"iaas/guides/upgrade-guide/ceph","title":"Ceph","description":"","sidebar":"docs"},"iaas/guides/upgrade-guide/docker":{"id":"iaas/guides/upgrade-guide/docker","title":"Docker","description":"The Docker version used is defined via the parameter docker_version in the file","sidebar":"docs"},"iaas/guides/upgrade-guide/index":{"id":"iaas/guides/upgrade-guide/index","title":"Upgrade Guide","description":"In the examples, the pull of images (if supported by a role) is always run first. While","sidebar":"docs"},"iaas/guides/upgrade-guide/infrastructure":{"id":"iaas/guides/upgrade-guide/infrastructure","title":"Infrastructure","description":"1. Kubernetes","sidebar":"docs"},"iaas/guides/upgrade-guide/logging-monitoring":{"id":"iaas/guides/upgrade-guide/logging-monitoring","title":"Logging & Monitoring","description":"1. OpenSearch","sidebar":"docs"},"iaas/guides/upgrade-guide/manager":{"id":"iaas/guides/upgrade-guide/manager","title":"Manager","description":"Always read the release notes first to learn what has changed and what","sidebar":"docs"},"iaas/guides/upgrade-guide/network":{"id":"iaas/guides/upgrade-guide/network","title":"Network","description":"1. Open vSwitch (OVS)","sidebar":"docs"},"iaas/guides/upgrade-guide/openstack":{"id":"iaas/guides/upgrade-guide/openstack","title":"OpenStack","description":"When upgrade the different OpenStack services, all containers must be","sidebar":"docs"},"iaas/guides/user-guide/index":{"id":"iaas/guides/user-guide/index","title":"User Guide","description":"","sidebar":"docs"},"iaas/guides/user-guide/migration-vmware-esix":{"id":"iaas/guides/user-guide/migration-vmware-esix","title":"Migrate from VMware ESXi to OpenStack","description":"This guide is an example of how to perform a manual migration from a VMware ESXi host to OpenStack.","sidebar":"docs"},"iaas/guides/user-guide/openstack/index":{"id":"iaas/guides/user-guide/openstack/index","title":"OpenStack","description":"","sidebar":"docs"},"iaas/guides/user-guide/openstack/security-groups":{"id":"iaas/guides/user-guide/openstack/security-groups","title":"How to configure and use security groups","description":"Security groups in OpenStack are part of the network security mechanisms provided for the users.","sidebar":"docs"},"iaas/guides/user-guide/openstack/user-data-backups":{"id":"iaas/guides/user-guide/openstack/user-data-backups","title":"User Data Backups","description":"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.","sidebar":"docs"},"iaas/guides/user-guide/security-groups/security-groups":{"id":"iaas/guides/user-guide/security-groups/security-groups","title":"Best Practise: How to configure and use security groups","description":"Security groups in OpenStack are part of the network security mechanisms provided for the users.","sidebar":"docs"},"iaas/guides/user-guide/user-data-backups":{"id":"iaas/guides/user-guide/user-data-backups","title":"User Data Backups","description":"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.","sidebar":"docs"},"iaas/overview/architecture":{"id":"iaas/overview/architecture","title":"Architecture","description":"TODO"},"iaas/overview/compute":{"id":"iaas/overview/compute","title":"Compute","description":"TODO"},"iaas/overview/knowledge":{"id":"iaas/overview/knowledge","title":"Knowledge","description":"TODO"},"iaas/overview/network":{"id":"iaas/overview/network","title":"Network","description":"TODO"},"iaas/overview/storage":{"id":"iaas/overview/storage","title":"Storage","description":"TODO"},"iam/domain-manager-setup-and-usage":{"id":"iam/domain-manager-setup-and-usage","title":"Domain Manager setup and usage","description":"The following documentation refers to a SCS standard that is still in draft state.","sidebar":"docs"},"iam/index":{"id":"iam/index","title":"Introduction on Identity Management and Federation in SCS","description":"Sovereign Cloud Stack wants to make it possible for operators to delegate","sidebar":"docs"},"iam/intra-SCS-federation-setup-description-for-osism-doc-operations":{"id":"iam/intra-SCS-federation-setup-description-for-osism-doc-operations","title":"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)","description":"The followig section is a reasonably detailed hands on description of how","sidebar":"docs"},"iam/SCS-example-setup-configuration-description":{"id":"iam/SCS-example-setup-configuration-description","title":"Example setup configuration in SCS deployment explained","description":"The following document explains the idea behind the example configuration is done.","sidebar":"docs"},"index":{"id":"index","title":"Introduction","description":"About","sidebar":"docs"},"operating-scs/audits/index":{"id":"operating-scs/audits/index","title":"Overview","description":"TODO"},"operating-scs/components/automated-pentesting/overview":{"id":"operating-scs/components/automated-pentesting/overview","title":"SCS automated pentesting","description":"Security has a high priority in modern cloud infrastructures. If you look at it from an automation perspective, a basic distinction of tooling is needed to be considered:","sidebar":"docs"},"operating-scs/components/automated-pentesting/tools":{"id":"operating-scs/components/automated-pentesting/tools","title":"Tools Description","description":"The following tools make up the automated pentesting pipeline. Each tool has it\'s own use case and they build up onto each other.","sidebar":"docs"},"operating-scs/components/central-api/overview":{"id":"operating-scs/components/central-api/overview","title":"Overview","description":"Premise","sidebar":"docs"},"operating-scs/components/central-api/poc-setup":{"id":"operating-scs/components/central-api/poc-setup","title":"Central API MVP","description":"Right now, this repository implements issue 374.","sidebar":"docs"},"operating-scs/components/monitoring/docs/alertmanager":{"id":"operating-scs/components/monitoring/docs/alertmanager","title":"Alertmanager notifications in Matrix chat","description":"This page contains instructions on how to enable the Alertmanager to Matrix chat notifications in the Observer solution.","sidebar":"docs"},"operating-scs/components/monitoring/docs/iaas":{"id":"operating-scs/components/monitoring/docs/iaas","title":"IaaS monitoring (experimental)","description":"This component is marked as experimental, and it is not part of the reference SCS installation available","sidebar":"docs"},"operating-scs/components/monitoring/docs/infrastructure_services":{"id":"operating-scs/components/monitoring/docs/infrastructure_services","title":"Infrastructure service endpoints","description":"This page contains instructions on how to enable probing of infrastructure service endpoints using blackbox exporter.","sidebar":"docs"},"operating-scs/components/monitoring/docs/k3s":{"id":"operating-scs/components/monitoring/docs/k3s","title":"K3s support","description":"K3s is a certified Kubernetes distribution optimized for production environments, particularly in remote locations","sidebar":"docs"},"operating-scs/components/monitoring/docs/kaas":{"id":"operating-scs/components/monitoring/docs/kaas","title":"KaaS monitoring (experimental)","description":"This component is marked as experimental, and it is not part of the reference SCS installation available","sidebar":"docs"},"operating-scs/components/monitoring/docs/oauth":{"id":"operating-scs/components/monitoring/docs/oauth","title":"OAUTH","description":"We set up oauth2 with GitHub provider for the https//kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/.","sidebar":"docs"},"operating-scs/components/monitoring/docs/overview":{"id":"operating-scs/components/monitoring/docs/overview","title":"Overview","description":"This repository aims to build an Observer monitoring solution intended to offer a global metrics","sidebar":"docs"},"operating-scs/components/monitoring/docs/quickstart":{"id":"operating-scs/components/monitoring/docs/quickstart","title":"Quickstart","description":"These page covers the process of deploying the Observer monitoring solution","sidebar":"docs"},"operating-scs/components/monitoring/docs/scs-deployment":{"id":"operating-scs/components/monitoring/docs/scs-deployment","title":"SCS deployment","description":"The following steps were utilized to deploy the SCS reference installation of the Observer monitoring solution,","sidebar":"docs"},"operating-scs/components/monitoring/docs/tracing":{"id":"operating-scs/components/monitoring/docs/tracing","title":"Traces","description":"This page contains a guide on how to enable traces in Thanos. Traces are not enabled by default.","sidebar":"docs"},"operating-scs/components/monitoring/docs/tuning":{"id":"operating-scs/components/monitoring/docs/tuning","title":"Tuning","description":"This page contains recommended parameters to set for the Thanos components to improve performance in terms of query time.","sidebar":"docs"},"operating-scs/components/monitoring/docs/zuul":{"id":"operating-scs/components/monitoring/docs/zuul","title":"Zuul monitoring","description":"This page contains instructions on how to enable the Zuul monitoring in the Observer solution.","sidebar":"docs"},"operating-scs/components/status-page/docs/component_overview":{"id":"operating-scs/components/status-page/docs/component_overview","title":"Component Overview","description":"This represents a part of the decision process related to the overall structure the API wants to represent.","sidebar":"docs"},"operating-scs/components/status-page/docs/components":{"id":"operating-scs/components/status-page/docs/components","title":"Components","description":"Illustrating multiple interchangable logical \\"layers\\" of possible Status Page application stacks:","sidebar":"docs"},"operating-scs/components/status-page/docs/levels_of_consensus":{"id":"operating-scs/components/status-page/docs/levels_of_consensus","title":"\\"Levels of consensus\\"","description":"When implementing any system to be used by a group of potential users, there will be varying use cases and opinions about API\'s, programming languages, persistence models, authentication, authorization, deployment options and so on.","sidebar":"docs"},"operating-scs/components/status-page/docs/overview":{"id":"operating-scs/components/status-page/docs/overview","title":"Overview","description":"Service providers often times want to communicate the status of their systems transparently to their users.","sidebar":"docs"},"operating-scs/guides/openstack-health-monitor/Debian12-Install":{"id":"operating-scs/guides/openstack-health-monitor/Debian12-Install","title":"Guide: Setting up openstack-health-monitor on Debian 12","description":"Kurt Garloff, 2024-02-20","sidebar":"docs"},"operating-scs/incident-management/index":{"id":"operating-scs/incident-management/index","title":"Overview","description":"TODO"},"operating-scs/lifecycle-management/index":{"id":"operating-scs/lifecycle-management/index","title":"Overview","description":"TODO"},"operating-scs/logging/index":{"id":"operating-scs/logging/index","title":"Overview","description":"TODO"},"operating-scs/metering/meter_configuration":{"id":"operating-scs/metering/meter_configuration","title":"Metering Configuration","description":"The Metrics and events we want to use in the metering process can be defined in two ways. The first one is to allow ceilometer to poll distinct metrics and events.","sidebar":"docs"},"operating-scs/monitoring/index":{"id":"operating-scs/monitoring/index","title":"Overview","description":"TODO"},"operating-scs/overview":{"id":"operating-scs/overview","title":"Overview","description":"TODO"},"releases/Release0":{"id":"releases/Release0","title":"Release Notes for SCS Release 0","description":"(Release Date: 2021-07-15)","sidebar":"docs"},"releases/Release1":{"id":"releases/Release1","title":"Release Notes for SCS Release 1","description":"(Release Date: 2021-09-29)","sidebar":"docs"},"releases/Release2":{"id":"releases/Release2","title":"Release Notes for SCS Release 2","description":"(Release Date: 2022-03-23)","sidebar":"docs"},"releases/Release3":{"id":"releases/Release3","title":"Release Notes for SCS Release 3","description":"(Release Date: 2022-09-21)","sidebar":"docs"},"releases/Release4":{"id":"releases/Release4","title":"Release Notes for SCS Release 4","description":"(Release Date: 2023-03-22)","sidebar":"docs"},"releases/Release5":{"id":"releases/Release5","title":"Release Notes for SCS Release 5","description":"(Release Date: 2023-09-20)","sidebar":"docs"},"releases/Release6":{"id":"releases/Release6","title":"Release Notes for SCS Release 6","description":"SCS Release 6 has been published on 2024-03-20.","sidebar":"docs"},"releases/ReleaseX":{"id":"releases/ReleaseX","title":"Release Notes for SCS Release X","description":"This document is work in progress for the upcoming Release X."},"standards/index":{"id":"standards/index","title":"Standards","description":"TODO"}}}')}}]); \ No newline at end of file diff --git a/assets/js/94298c6b.4f435156.js b/assets/js/94298c6b.4f435156.js new file mode 100644 index 0000000000..42be784343 --- /dev/null +++ b/assets/js/94298c6b.4f435156.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8612],{79844:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"contributor-docs"}')}}]); \ No newline at end of file diff --git a/assets/js/9469.9cb41622.js b/assets/js/9469.9cb41622.js new file mode 100644 index 0000000000..8ec541e36a --- /dev/null +++ b/assets/js/9469.9cb41622.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9469],{59469:(t,i,n)=>{n.d(i,{diagram:()=>o});var s=n(76257),e=(n(74353),n(16750),n(26312),n(42838),function(){var t=function(t,i,n,s){for(n=n||{},s=t.length;s--;n[t[s]]=i);return n},i=[6,9,10],n={trace:function(){},yy:{},symbols_:{error:2,start:3,info:4,document:5,EOF:6,line:7,statement:8,NL:9,showInfo:10,$accept:0,$end:1},terminals_:{2:"error",4:"info",6:"EOF",9:"NL",10:"showInfo"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,1]],performAction:function(t,i,n,s,e,r,h){switch(r.length,e){case 1:return s;case 4:break;case 6:s.setInfo(!0)}},table:[{3:1,4:[1,2]},{1:[3]},t(i,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},t(i,[2,3]),t(i,[2,4]),t(i,[2,5]),t(i,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,i){if(!i.recoverable){var n=new Error(t);throw n.hash=i,n}this.trace(t)},parse:function(t){var i=this,n=[0],s=[],e=[null],r=[],h=this.table,o="",l=0,c=0,a=r.slice.call(arguments,1),y=Object.create(this.lexer),u={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(u.yy[p]=this.yy[p]);y.setInput(t,u.yy),u.yy.lexer=y,u.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var f=y.yylloc;r.push(f);var g=y.options&&y.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,m,d,k,x,b,v,w,I,S={};;){if(m=n[n.length-1],this.defaultActions[m]?d=this.defaultActions[m]:(null==_&&(I=void 0,"number"!=typeof(I=s.pop()||y.lex()||1)&&(I instanceof Array&&(I=(s=I).pop()),I=i.symbols_[I]||I),_=I),d=h[m]&&h[m][_]),void 0===d||!d.length||!d[0]){var E="";for(x in w=[],h[m])this.terminals_[x]&&x>2&&w.push("'"+this.terminals_[x]+"'");E=y.showPosition?"Parse error on line "+(l+1)+":\n"+y.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==_?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(E,{text:y.match,token:this.terminals_[_]||_,line:y.yylineno,loc:f,expected:w})}if(d[0]instanceof Array&&d.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+_);switch(d[0]){case 1:n.push(_),e.push(y.yytext),r.push(y.yylloc),n.push(d[1]),_=null,c=y.yyleng,o=y.yytext,l=y.yylineno,f=y.yylloc;break;case 2:if(b=this.productions_[d[1]][1],S.$=e[e.length-b],S._$={first_line:r[r.length-(b||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(b||1)].first_column,last_column:r[r.length-1].last_column},g&&(S._$.range=[r[r.length-(b||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,c,l,u.yy,d[1],e,r].concat(a))))return k;b&&(n=n.slice(0,-1*b*2),e=e.slice(0,-1*b),r=r.slice(0,-1*b)),n.push(this.productions_[d[1]][0]),e.push(S.$),r.push(S._$),v=h[n[n.length-2]][n[n.length-1]],n.push(v);break;case 3:return!0}}return!0}},s={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)},setInput:function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var i=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===s.length?this.yylloc.first_column:0)+s[s.length-n.length].length-n[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[e[0],e[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"},test_match:function(t,i){var n,s,e;if(this.options.backtrack_lexer&&(e={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(e.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in e)this[r]=e[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,n,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var e=this._currentRules(),r=0;r<e.length;r++)if((n=this._input.match(this.rules[e[r]]))&&(!i||n[0].length>i[0].length)){if(i=n,s=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,e[r])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,e[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,n,s){switch(n){case 0:return 4;case 1:return 9;case 2:return"space";case 3:return 10;case 4:return 6;case 5:return"TXT"}},rules:[/^(?:info\b)/i,/^(?:[\s\n\r]+)/i,/^(?:[\s]+)/i,/^(?:showInfo\b)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5],inclusive:!0}}};function e(){this.yy={}}return n.lexer=s,e.prototype=n,n.Parser=e,new e}());e.parser=e;const r=!1;let h=r;const o={parser:e,db:{clear:()=>{h=r},setInfo:t=>{h=t},getInfo:()=>h},renderer:{draw:(t,i,n)=>{s.l.debug("rendering info diagram\n"+t);const e=(0,s.A)(i);(0,s.i)(e,100,400,!0);e.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${n}`)}}}}}]); \ No newline at end of file diff --git a/assets/js/947.9d53f5a7.js b/assets/js/947.9d53f5a7.js new file mode 100644 index 0000000000..d6235d3655 --- /dev/null +++ b/assets/js/947.9d53f5a7.js @@ -0,0 +1,14571 @@ +"use strict"; +exports.id = 947; +exports.ids = [947]; +exports.modules = { + +/***/ 40351: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-f47111a7.js + 8 modules +var mermaid_f47111a7 = __webpack_require__(76257); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array<unknown>} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array<string>} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array<T>} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array<unknown>} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {Array<T>} items + * Items to add to `list`. + * @returns {Array<T>} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array<Extension>} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record<string, unknown>} */ + const left = maybe || (all[hook] = {}) + /** @type {Record<string, unknown> | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array<unknown>} existing + * @param {Array<unknown>} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array<unknown>} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array<HtmlExtension>} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array<StackItem>} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array<Event>} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record<string, number>} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array<Event>} */ + let parameters + /** @type {Array<Event>} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array<Event>} events + * @param {number} eventIndex + * @returns {Record<string, number>} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array<number>} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record<string, number>} */ + const gaps = {} + /** @type {Array<Chunk>} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array<Event>} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array<Event>} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array<Resolver>} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit<Point, '_bufferIndex' | '_index'> | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record<string, number>} */ + const columnStart = {} + /** @type {Array<Construct>} */ + const resolveAllConstructs = [] + /** @type {Array<Chunk>} */ + let chunks = [] + /** @type {Array<Token>} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array<Construct> | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array<Construct>} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array<Construct>} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array<Chunk>} chunks + * @param {Pick<Token, 'end' | 'start'>} token + * @returns {Array<Chunk>} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array<Chunk>} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array<Chunk>} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array<string>} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * <a> + * <a\>b> + * <a b> + * <a)> + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`<a>` or `b`). + * @param {TokenType} literalType + * Type when enclosed (`<a>`). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | <aa> + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | <a\*a> + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | <x /> + * ^ + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<!-`, inside a comment, at another `-`. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<![`, inside CDATA, expecting `CDATA[`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | </x> + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | <ab> + * ^^ + * > | </ab> + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > | <div/> + * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | <x/> + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | <a /> + * ^ + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * > | <a > + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | <a b> + * ^ + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | <a b=c> + * ^ + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | <a b="c"> + * ^ + * > | <a b='c'> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | <x> + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | <x> + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after `</`, in a raw tag name. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | <!--> + * ^ + * > | <?> + * ^ + * > | <!q> + * ^ + * > | <!--ab--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > | <div> + * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record<string, string>} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array<Event>} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + * <p>!<a href=\"b\">^a</a></p> + * <p>!<a href=\"c\">^a</a></p> + * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array<Event>} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | a<user.name@ex-ample.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code> | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a <b> c + * ^ + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * > | a <![CDATA[>&<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after `<!-`, at another `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After `<![`, in CDATA, expecting `CDATA[`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a <!b> c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After `</x`, in a tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After `<x`, in opening tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a <!--a + * ^ + * | b--> + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array<Chunk>} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array<Chunk>} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array<Event>} events + * @returns {Array<Event>} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract<Node, UnistParent>} Parent + * + * @typedef {Omit<UnistParent, 'type' | 'children'> & {type: 'fragment', children: Array<PhrasingContent>}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record<string, Handle>} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array<string>} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array<Transform>} transforms + * Tree transforms. + * + * @typedef {Partial<Config>} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array<Node | Fragment>} stack + * Stack of nodes. + * @property {Array<TokenTuple>} tokenStack + * Stack of tokens. + * @property {<Key extends keyof CompileData>(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {<Key extends keyof CompileData>(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {<Kind extends Node>(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array<Extension | Array<Extension>> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array<Event>} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit<CompileContext, 'sliceSerialize'>} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array<number>} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array<Event>} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array<StaticPhrasingContent>} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array<Extension | Array<Extension>>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(60513); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-6b48ae7d.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.T)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "<br/>"); + } else if (node.type === "strong") { + return `<strong>${node.children.map(output).join("")}</strong>`; + } else if (node.type === "emphasis") { + return `<em>${node.children.map(output).join("")}</em>`; + } else if (node.type === "paragraph") { + return `<p>${node.children.map(output).join("")}</p>`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + <span class="${labelClass} ${classes}" ` + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_f47111a7.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_f47111a7.M)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + // cspell: disable-line + (s) => `<i class='${s.replace(":", " ")}'></i>` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 18947: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(76257); +/* harmony import */ var _createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(40351); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26312); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74353); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16750); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(99418); + + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 10, 12, 14, 16, 18, 19, 21, 23], $V1 = [2, 6], $V2 = [1, 3], $V3 = [1, 5], $V4 = [1, 6], $V5 = [1, 7], $V6 = [1, 5, 10, 12, 14, 16, 18, 19, 21, 23, 34, 35, 36], $V7 = [1, 25], $V8 = [1, 26], $V9 = [1, 28], $Va = [1, 29], $Vb = [1, 30], $Vc = [1, 31], $Vd = [1, 32], $Ve = [1, 33], $Vf = [1, 34], $Vg = [1, 35], $Vh = [1, 36], $Vi = [1, 37], $Vj = [1, 43], $Vk = [1, 42], $Vl = [1, 47], $Vm = [1, 50], $Vn = [1, 10, 12, 14, 16, 18, 19, 21, 23, 34, 35, 36], $Vo = [1, 10, 12, 14, 16, 18, 19, 21, 23, 24, 26, 27, 28, 34, 35, 36], $Vp = [1, 10, 12, 14, 16, 18, 19, 21, 23, 24, 26, 27, 28, 34, 35, 36, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50], $Vq = [1, 64]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "eol": 4, "XYCHART": 5, "chartConfig": 6, "document": 7, "CHART_ORIENTATION": 8, "statement": 9, "title": 10, "text": 11, "X_AXIS": 12, "parseXAxis": 13, "Y_AXIS": 14, "parseYAxis": 15, "LINE": 16, "plotData": 17, "BAR": 18, "acc_title": 19, "acc_title_value": 20, "acc_descr": 21, "acc_descr_value": 22, "acc_descr_multiline_value": 23, "SQUARE_BRACES_START": 24, "commaSeparatedNumbers": 25, "SQUARE_BRACES_END": 26, "NUMBER_WITH_DECIMAL": 27, "COMMA": 28, "xAxisData": 29, "bandData": 30, "ARROW_DELIMITER": 31, "commaSeparatedTexts": 32, "yAxisData": 33, "NEWLINE": 34, "SEMI": 35, "EOF": 36, "alphaNum": 37, "STR": 38, "MD_STR": 39, "alphaNumToken": 40, "AMP": 41, "NUM": 42, "ALPHA": 43, "PLUS": 44, "EQUALS": 45, "MULT": 46, "DOT": 47, "BRKT": 48, "MINUS": 49, "UNDERSCORE": 50, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 5: "XYCHART", 8: "CHART_ORIENTATION", 10: "title", 12: "X_AXIS", 14: "Y_AXIS", 16: "LINE", 18: "BAR", 19: "acc_title", 20: "acc_title_value", 21: "acc_descr", 22: "acc_descr_value", 23: "acc_descr_multiline_value", 24: "SQUARE_BRACES_START", 26: "SQUARE_BRACES_END", 27: "NUMBER_WITH_DECIMAL", 28: "COMMA", 31: "ARROW_DELIMITER", 34: "NEWLINE", 35: "SEMI", 36: "EOF", 38: "STR", 39: "MD_STR", 41: "AMP", 42: "NUM", 43: "ALPHA", 44: "PLUS", 45: "EQUALS", 46: "MULT", 47: "DOT", 48: "BRKT", 49: "MINUS", 50: "UNDERSCORE" }, + productions_: [0, [3, 2], [3, 3], [3, 2], [3, 1], [6, 1], [7, 0], [7, 2], [9, 2], [9, 2], [9, 2], [9, 2], [9, 2], [9, 3], [9, 2], [9, 3], [9, 2], [9, 2], [9, 1], [17, 3], [25, 3], [25, 1], [13, 1], [13, 2], [13, 1], [29, 1], [29, 3], [30, 3], [32, 3], [32, 1], [15, 1], [15, 2], [15, 1], [33, 3], [4, 1], [4, 1], [4, 1], [11, 1], [11, 1], [11, 1], [37, 1], [37, 2], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 5: + yy.setOrientation($$[$0]); + break; + case 9: + yy.setDiagramTitle($$[$0].text.trim()); + break; + case 12: + yy.setLineData({ text: "", type: "text" }, $$[$0]); + break; + case 13: + yy.setLineData($$[$0 - 1], $$[$0]); + break; + case 14: + yy.setBarData({ text: "", type: "text" }, $$[$0]); + break; + case 15: + yy.setBarData($$[$0 - 1], $$[$0]); + break; + case 16: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 17: + case 18: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 19: + this.$ = $$[$0 - 1]; + break; + case 20: + this.$ = [Number($$[$0 - 2]), ...$$[$0]]; + break; + case 21: + this.$ = [Number($$[$0])]; + break; + case 22: + yy.setXAxisTitle($$[$0]); + break; + case 23: + yy.setXAxisTitle($$[$0 - 1]); + break; + case 24: + yy.setXAxisTitle({ type: "text", text: "" }); + break; + case 25: + yy.setXAxisBand($$[$0]); + break; + case 26: + yy.setXAxisRangeData(Number($$[$0 - 2]), Number($$[$0])); + break; + case 27: + this.$ = $$[$0 - 1]; + break; + case 28: + this.$ = [$$[$0 - 2], ...$$[$0]]; + break; + case 29: + this.$ = [$$[$0]]; + break; + case 30: + yy.setYAxisTitle($$[$0]); + break; + case 31: + yy.setYAxisTitle($$[$0 - 1]); + break; + case 32: + yy.setYAxisTitle({ type: "text", text: "" }); + break; + case 33: + yy.setYAxisRangeData(Number($$[$0 - 2]), Number($$[$0])); + break; + case 37: + this.$ = { text: $$[$0], type: "text" }; + break; + case 38: + this.$ = { text: $$[$0], type: "text" }; + break; + case 39: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 40: + this.$ = $$[$0]; + break; + case 41: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + } + }, + table: [o($V0, $V1, { 3: 1, 4: 2, 7: 4, 5: $V2, 34: $V3, 35: $V4, 36: $V5 }), { 1: [3] }, o($V0, $V1, { 4: 2, 7: 4, 3: 8, 5: $V2, 34: $V3, 35: $V4, 36: $V5 }), o($V0, $V1, { 4: 2, 7: 4, 6: 9, 3: 10, 5: $V2, 8: [1, 11], 34: $V3, 35: $V4, 36: $V5 }), { 1: [2, 4], 9: 12, 10: [1, 13], 12: [1, 14], 14: [1, 15], 16: [1, 16], 18: [1, 17], 19: [1, 18], 21: [1, 19], 23: [1, 20] }, o($V6, [2, 34]), o($V6, [2, 35]), o($V6, [2, 36]), { 1: [2, 1] }, o($V0, $V1, { 4: 2, 7: 4, 3: 21, 5: $V2, 34: $V3, 35: $V4, 36: $V5 }), { 1: [2, 3] }, o($V6, [2, 5]), o($V0, [2, 7], { 4: 22, 34: $V3, 35: $V4, 36: $V5 }), { 11: 23, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 11: 39, 13: 38, 24: $Vj, 27: $Vk, 29: 40, 30: 41, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 11: 45, 15: 44, 27: $Vl, 33: 46, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 11: 49, 17: 48, 24: $Vm, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 11: 52, 17: 51, 24: $Vm, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 20: [1, 53] }, { 22: [1, 54] }, o($Vn, [2, 18]), { 1: [2, 2] }, o($Vn, [2, 8]), o($Vn, [2, 9]), o($Vo, [2, 37], { 40: 55, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }), o($Vo, [2, 38]), o($Vo, [2, 39]), o($Vp, [2, 40]), o($Vp, [2, 42]), o($Vp, [2, 43]), o($Vp, [2, 44]), o($Vp, [2, 45]), o($Vp, [2, 46]), o($Vp, [2, 47]), o($Vp, [2, 48]), o($Vp, [2, 49]), o($Vp, [2, 50]), o($Vp, [2, 51]), o($Vn, [2, 10]), o($Vn, [2, 22], { 30: 41, 29: 56, 24: $Vj, 27: $Vk }), o($Vn, [2, 24]), o($Vn, [2, 25]), { 31: [1, 57] }, { 11: 59, 32: 58, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, o($Vn, [2, 11]), o($Vn, [2, 30], { 33: 60, 27: $Vl }), o($Vn, [2, 32]), { 31: [1, 61] }, o($Vn, [2, 12]), { 17: 62, 24: $Vm }, { 25: 63, 27: $Vq }, o($Vn, [2, 14]), { 17: 65, 24: $Vm }, o($Vn, [2, 16]), o($Vn, [2, 17]), o($Vp, [2, 41]), o($Vn, [2, 23]), { 27: [1, 66] }, { 26: [1, 67] }, { 26: [2, 29], 28: [1, 68] }, o($Vn, [2, 31]), { 27: [1, 69] }, o($Vn, [2, 13]), { 26: [1, 70] }, { 26: [2, 21], 28: [1, 71] }, o($Vn, [2, 15]), o($Vn, [2, 26]), o($Vn, [2, 27]), { 11: 59, 32: 72, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, o($Vn, [2, 33]), o($Vn, [2, 19]), { 25: 73, 27: $Vq }, { 26: [2, 28] }, { 26: [2, 20] }], + defaultActions: { 8: [2, 1], 10: [2, 3], 21: [2, 2], 72: [2, 28], 73: [2, 20] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + break; + case 1: + break; + case 2: + this.popState(); + return 34; + case 3: + this.popState(); + return 34; + case 4: + return 34; + case 5: + break; + case 6: + return 10; + case 7: + this.pushState("acc_title"); + return 19; + case 8: + this.popState(); + return "acc_title_value"; + case 9: + this.pushState("acc_descr"); + return 21; + case 10: + this.popState(); + return "acc_descr_value"; + case 11: + this.pushState("acc_descr_multiline"); + break; + case 12: + this.popState(); + break; + case 13: + return "acc_descr_multiline_value"; + case 14: + return 5; + case 15: + return 8; + case 16: + this.pushState("axis_data"); + return "X_AXIS"; + case 17: + this.pushState("axis_data"); + return "Y_AXIS"; + case 18: + this.pushState("axis_band_data"); + return 24; + case 19: + return 31; + case 20: + this.pushState("data"); + return 16; + case 21: + this.pushState("data"); + return 18; + case 22: + this.pushState("data_inner"); + return 24; + case 23: + return 27; + case 24: + this.popState(); + return 26; + case 25: + this.popState(); + break; + case 26: + this.pushState("string"); + break; + case 27: + this.popState(); + break; + case 28: + return "STR"; + case 29: + return 24; + case 30: + return 26; + case 31: + return 43; + case 32: + return "COLON"; + case 33: + return 44; + case 34: + return 28; + case 35: + return 45; + case 36: + return 46; + case 37: + return 48; + case 38: + return 50; + case 39: + return 47; + case 40: + return 41; + case 41: + return 49; + case 42: + return 42; + case 43: + break; + case 44: + return 35; + case 45: + return 36; + } + }, + rules: [/^(?:%%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:(\r?\n))/i, /^(?:(\r?\n))/i, /^(?:[\n\r]+)/i, /^(?:%%[^\n]*)/i, /^(?:title\b)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:\{)/i, /^(?:[^\}]*)/i, /^(?:xychart-beta\b)/i, /^(?:(?:vertical|horizontal))/i, /^(?:x-axis\b)/i, /^(?:y-axis\b)/i, /^(?:\[)/i, /^(?:-->)/i, /^(?:line\b)/i, /^(?:bar\b)/i, /^(?:\[)/i, /^(?:[+-]?(?:\d+(?:\.\d+)?|\.\d+))/i, /^(?:\])/i, /^(?:(?:`\) \{ this\.pushState\(md_string\); \}\n<md_string>\(\?:\(\?!`"\)\.\)\+ \{ return MD_STR; \}\n<md_string>\(\?:`))/i, /^(?:["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:\[)/i, /^(?:\])/i, /^(?:[A-Za-z]+)/i, /^(?::)/i, /^(?:\+)/i, /^(?:,)/i, /^(?:=)/i, /^(?:\*)/i, /^(?:#)/i, /^(?:[\_])/i, /^(?:\.)/i, /^(?:&)/i, /^(?:-)/i, /^(?:[0-9]+)/i, /^(?:\s+)/i, /^(?:;)/i, /^(?:$)/i], + conditions: { "data_inner": { "rules": [0, 1, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 20, 21, 23, 24, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "inclusive": true }, "data": { "rules": [0, 1, 3, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 20, 21, 22, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "inclusive": true }, "axis_band_data": { "rules": [0, 1, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 20, 21, 24, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "inclusive": true }, "axis_data": { "rules": [0, 1, 2, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 18, 19, 20, 21, 23, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "inclusive": true }, "acc_descr_multiline": { "rules": [12, 13], "inclusive": false }, "acc_descr": { "rules": [10], "inclusive": false }, "acc_title": { "rules": [8], "inclusive": false }, "title": { "rules": [], "inclusive": false }, "md_string": { "rules": [], "inclusive": false }, "string": { "rules": [27, 28], "inclusive": false }, "INITIAL": { "rules": [0, 1, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 20, 21, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +function isBarPlot(data) { + return data.type === "bar"; +} +function isBandAxisData(data) { + return data.type === "band"; +} +function isLinearAxisData(data) { + return data.type === "linear"; +} +class TextDimensionCalculatorWithFont { + constructor(parentGroup) { + this.parentGroup = parentGroup; + } + getMaxDimension(texts, fontSize) { + if (!this.parentGroup) { + return { + width: texts.reduce((acc, cur) => Math.max(cur.length, acc), 0) * fontSize, + height: fontSize + }; + } + const dimension = { + width: 0, + height: 0 + }; + const elem = this.parentGroup.append("g").attr("visibility", "hidden").attr("font-size", fontSize); + for (const t of texts) { + const bbox = (0,_createText_6b48ae7d_js__WEBPACK_IMPORTED_MODULE_4__.c)(elem, 1, t); + const width = bbox ? bbox.width : t.length * fontSize; + const height = bbox ? bbox.height : fontSize; + dimension.width = Math.max(dimension.width, width); + dimension.height = Math.max(dimension.height, height); + } + elem.remove(); + return dimension; + } +} +const BAR_WIDTH_TO_TICK_WIDTH_RATIO = 0.7; +const MAX_OUTER_PADDING_PERCENT_FOR_WRT_LABEL = 0.2; +class BaseAxis { + constructor(axisConfig, title, textDimensionCalculator, axisThemeConfig) { + this.axisConfig = axisConfig; + this.title = title; + this.textDimensionCalculator = textDimensionCalculator; + this.axisThemeConfig = axisThemeConfig; + this.boundingRect = { x: 0, y: 0, width: 0, height: 0 }; + this.axisPosition = "left"; + this.showTitle = false; + this.showLabel = false; + this.showTick = false; + this.showAxisLine = false; + this.outerPadding = 0; + this.titleTextHeight = 0; + this.labelTextHeight = 0; + this.range = [0, 10]; + this.boundingRect = { x: 0, y: 0, width: 0, height: 0 }; + this.axisPosition = "left"; + } + setRange(range) { + this.range = range; + if (this.axisPosition === "left" || this.axisPosition === "right") { + this.boundingRect.height = range[1] - range[0]; + } else { + this.boundingRect.width = range[1] - range[0]; + } + this.recalculateScale(); + } + getRange() { + return [this.range[0] + this.outerPadding, this.range[1] - this.outerPadding]; + } + setAxisPosition(axisPosition) { + this.axisPosition = axisPosition; + this.setRange(this.range); + } + getTickDistance() { + const range = this.getRange(); + return Math.abs(range[0] - range[1]) / this.getTickValues().length; + } + getAxisOuterPadding() { + return this.outerPadding; + } + getLabelDimension() { + return this.textDimensionCalculator.getMaxDimension( + this.getTickValues().map((tick) => tick.toString()), + this.axisConfig.labelFontSize + ); + } + recalculateOuterPaddingToDrawBar() { + if (BAR_WIDTH_TO_TICK_WIDTH_RATIO * this.getTickDistance() > this.outerPadding * 2) { + this.outerPadding = Math.floor(BAR_WIDTH_TO_TICK_WIDTH_RATIO * this.getTickDistance() / 2); + } + this.recalculateScale(); + } + calculateSpaceIfDrawnHorizontally(availableSpace) { + let availableHeight = availableSpace.height; + if (this.axisConfig.showAxisLine && availableHeight > this.axisConfig.axisLineWidth) { + availableHeight -= this.axisConfig.axisLineWidth; + this.showAxisLine = true; + } + if (this.axisConfig.showLabel) { + const spaceRequired = this.getLabelDimension(); + const maxPadding = MAX_OUTER_PADDING_PERCENT_FOR_WRT_LABEL * availableSpace.width; + this.outerPadding = Math.min(spaceRequired.width / 2, maxPadding); + const heightRequired = spaceRequired.height + this.axisConfig.labelPadding * 2; + this.labelTextHeight = spaceRequired.height; + if (heightRequired <= availableHeight) { + availableHeight -= heightRequired; + this.showLabel = true; + } + } + if (this.axisConfig.showTick && availableHeight >= this.axisConfig.tickLength) { + this.showTick = true; + availableHeight -= this.axisConfig.tickLength; + } + if (this.axisConfig.showTitle && this.title) { + const spaceRequired = this.textDimensionCalculator.getMaxDimension( + [this.title], + this.axisConfig.titleFontSize + ); + const heightRequired = spaceRequired.height + this.axisConfig.titlePadding * 2; + this.titleTextHeight = spaceRequired.height; + if (heightRequired <= availableHeight) { + availableHeight -= heightRequired; + this.showTitle = true; + } + } + this.boundingRect.width = availableSpace.width; + this.boundingRect.height = availableSpace.height - availableHeight; + } + calculateSpaceIfDrawnVertical(availableSpace) { + let availableWidth = availableSpace.width; + if (this.axisConfig.showAxisLine && availableWidth > this.axisConfig.axisLineWidth) { + availableWidth -= this.axisConfig.axisLineWidth; + this.showAxisLine = true; + } + if (this.axisConfig.showLabel) { + const spaceRequired = this.getLabelDimension(); + const maxPadding = MAX_OUTER_PADDING_PERCENT_FOR_WRT_LABEL * availableSpace.height; + this.outerPadding = Math.min(spaceRequired.height / 2, maxPadding); + const widthRequired = spaceRequired.width + this.axisConfig.labelPadding * 2; + if (widthRequired <= availableWidth) { + availableWidth -= widthRequired; + this.showLabel = true; + } + } + if (this.axisConfig.showTick && availableWidth >= this.axisConfig.tickLength) { + this.showTick = true; + availableWidth -= this.axisConfig.tickLength; + } + if (this.axisConfig.showTitle && this.title) { + const spaceRequired = this.textDimensionCalculator.getMaxDimension( + [this.title], + this.axisConfig.titleFontSize + ); + const widthRequired = spaceRequired.height + this.axisConfig.titlePadding * 2; + this.titleTextHeight = spaceRequired.height; + if (widthRequired <= availableWidth) { + availableWidth -= widthRequired; + this.showTitle = true; + } + } + this.boundingRect.width = availableSpace.width - availableWidth; + this.boundingRect.height = availableSpace.height; + } + calculateSpace(availableSpace) { + if (this.axisPosition === "left" || this.axisPosition === "right") { + this.calculateSpaceIfDrawnVertical(availableSpace); + } else { + this.calculateSpaceIfDrawnHorizontally(availableSpace); + } + this.recalculateScale(); + return { + width: this.boundingRect.width, + height: this.boundingRect.height + }; + } + setBoundingBoxXY(point) { + this.boundingRect.x = point.x; + this.boundingRect.y = point.y; + } + getDrawableElementsForLeftAxis() { + const drawableElement = []; + if (this.showAxisLine) { + const x = this.boundingRect.x + this.boundingRect.width - this.axisConfig.axisLineWidth / 2; + drawableElement.push({ + type: "path", + groupTexts: ["left-axis", "axisl-line"], + data: [ + { + path: `M ${x},${this.boundingRect.y} L ${x},${this.boundingRect.y + this.boundingRect.height} `, + strokeFill: this.axisThemeConfig.axisLineColor, + strokeWidth: this.axisConfig.axisLineWidth + } + ] + }); + } + if (this.showLabel) { + drawableElement.push({ + type: "text", + groupTexts: ["left-axis", "label"], + data: this.getTickValues().map((tick) => ({ + text: tick.toString(), + x: this.boundingRect.x + this.boundingRect.width - (this.showLabel ? this.axisConfig.labelPadding : 0) - (this.showTick ? this.axisConfig.tickLength : 0) - (this.showAxisLine ? this.axisConfig.axisLineWidth : 0), + y: this.getScaleValue(tick), + fill: this.axisThemeConfig.labelColor, + fontSize: this.axisConfig.labelFontSize, + rotation: 0, + verticalPos: "middle", + horizontalPos: "right" + })) + }); + } + if (this.showTick) { + const x = this.boundingRect.x + this.boundingRect.width - (this.showAxisLine ? this.axisConfig.axisLineWidth : 0); + drawableElement.push({ + type: "path", + groupTexts: ["left-axis", "ticks"], + data: this.getTickValues().map((tick) => ({ + path: `M ${x},${this.getScaleValue(tick)} L ${x - this.axisConfig.tickLength},${this.getScaleValue(tick)}`, + strokeFill: this.axisThemeConfig.tickColor, + strokeWidth: this.axisConfig.tickWidth + })) + }); + } + if (this.showTitle) { + drawableElement.push({ + type: "text", + groupTexts: ["left-axis", "title"], + data: [ + { + text: this.title, + x: this.boundingRect.x + this.axisConfig.titlePadding, + y: this.boundingRect.y + this.boundingRect.height / 2, + fill: this.axisThemeConfig.titleColor, + fontSize: this.axisConfig.titleFontSize, + rotation: 270, + verticalPos: "top", + horizontalPos: "center" + } + ] + }); + } + return drawableElement; + } + getDrawableElementsForBottomAxis() { + const drawableElement = []; + if (this.showAxisLine) { + const y = this.boundingRect.y + this.axisConfig.axisLineWidth / 2; + drawableElement.push({ + type: "path", + groupTexts: ["bottom-axis", "axis-line"], + data: [ + { + path: `M ${this.boundingRect.x},${y} L ${this.boundingRect.x + this.boundingRect.width},${y}`, + strokeFill: this.axisThemeConfig.axisLineColor, + strokeWidth: this.axisConfig.axisLineWidth + } + ] + }); + } + if (this.showLabel) { + drawableElement.push({ + type: "text", + groupTexts: ["bottom-axis", "label"], + data: this.getTickValues().map((tick) => ({ + text: tick.toString(), + x: this.getScaleValue(tick), + y: this.boundingRect.y + this.axisConfig.labelPadding + (this.showTick ? this.axisConfig.tickLength : 0) + (this.showAxisLine ? this.axisConfig.axisLineWidth : 0), + fill: this.axisThemeConfig.labelColor, + fontSize: this.axisConfig.labelFontSize, + rotation: 0, + verticalPos: "top", + horizontalPos: "center" + })) + }); + } + if (this.showTick) { + const y = this.boundingRect.y + (this.showAxisLine ? this.axisConfig.axisLineWidth : 0); + drawableElement.push({ + type: "path", + groupTexts: ["bottom-axis", "ticks"], + data: this.getTickValues().map((tick) => ({ + path: `M ${this.getScaleValue(tick)},${y} L ${this.getScaleValue(tick)},${y + this.axisConfig.tickLength}`, + strokeFill: this.axisThemeConfig.tickColor, + strokeWidth: this.axisConfig.tickWidth + })) + }); + } + if (this.showTitle) { + drawableElement.push({ + type: "text", + groupTexts: ["bottom-axis", "title"], + data: [ + { + text: this.title, + x: this.range[0] + (this.range[1] - this.range[0]) / 2, + y: this.boundingRect.y + this.boundingRect.height - this.axisConfig.titlePadding - this.titleTextHeight, + fill: this.axisThemeConfig.titleColor, + fontSize: this.axisConfig.titleFontSize, + rotation: 0, + verticalPos: "top", + horizontalPos: "center" + } + ] + }); + } + return drawableElement; + } + getDrawableElementsForTopAxis() { + const drawableElement = []; + if (this.showAxisLine) { + const y = this.boundingRect.y + this.boundingRect.height - this.axisConfig.axisLineWidth / 2; + drawableElement.push({ + type: "path", + groupTexts: ["top-axis", "axis-line"], + data: [ + { + path: `M ${this.boundingRect.x},${y} L ${this.boundingRect.x + this.boundingRect.width},${y}`, + strokeFill: this.axisThemeConfig.axisLineColor, + strokeWidth: this.axisConfig.axisLineWidth + } + ] + }); + } + if (this.showLabel) { + drawableElement.push({ + type: "text", + groupTexts: ["top-axis", "label"], + data: this.getTickValues().map((tick) => ({ + text: tick.toString(), + x: this.getScaleValue(tick), + y: this.boundingRect.y + (this.showTitle ? this.titleTextHeight + this.axisConfig.titlePadding * 2 : 0) + this.axisConfig.labelPadding, + fill: this.axisThemeConfig.labelColor, + fontSize: this.axisConfig.labelFontSize, + rotation: 0, + verticalPos: "top", + horizontalPos: "center" + })) + }); + } + if (this.showTick) { + const y = this.boundingRect.y; + drawableElement.push({ + type: "path", + groupTexts: ["top-axis", "ticks"], + data: this.getTickValues().map((tick) => ({ + path: `M ${this.getScaleValue(tick)},${y + this.boundingRect.height - (this.showAxisLine ? this.axisConfig.axisLineWidth : 0)} L ${this.getScaleValue(tick)},${y + this.boundingRect.height - this.axisConfig.tickLength - (this.showAxisLine ? this.axisConfig.axisLineWidth : 0)}`, + strokeFill: this.axisThemeConfig.tickColor, + strokeWidth: this.axisConfig.tickWidth + })) + }); + } + if (this.showTitle) { + drawableElement.push({ + type: "text", + groupTexts: ["top-axis", "title"], + data: [ + { + text: this.title, + x: this.boundingRect.x + this.boundingRect.width / 2, + y: this.boundingRect.y + this.axisConfig.titlePadding, + fill: this.axisThemeConfig.titleColor, + fontSize: this.axisConfig.titleFontSize, + rotation: 0, + verticalPos: "top", + horizontalPos: "center" + } + ] + }); + } + return drawableElement; + } + getDrawableElements() { + if (this.axisPosition === "left") { + return this.getDrawableElementsForLeftAxis(); + } + if (this.axisPosition === "right") { + throw Error("Drawing of right axis is not implemented"); + } + if (this.axisPosition === "bottom") { + return this.getDrawableElementsForBottomAxis(); + } + if (this.axisPosition === "top") { + return this.getDrawableElementsForTopAxis(); + } + return []; + } +} +class BandAxis extends BaseAxis { + constructor(axisConfig, axisThemeConfig, categories, title, textDimensionCalculator) { + super(axisConfig, title, textDimensionCalculator, axisThemeConfig); + this.categories = categories; + this.scale = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleBand */ .WH)().domain(this.categories).range(this.getRange()); + } + setRange(range) { + super.setRange(range); + } + recalculateScale() { + this.scale = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleBand */ .WH)().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(0.5); + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.trace("BandAxis axis final categories, range: ", this.categories, this.getRange()); + } + getTickValues() { + return this.categories; + } + getScaleValue(value) { + return this.scale(value) || this.getRange()[0]; + } +} +class LinearAxis extends BaseAxis { + constructor(axisConfig, axisThemeConfig, domain, title, textDimensionCalculator) { + super(axisConfig, title, textDimensionCalculator, axisThemeConfig); + this.domain = domain; + this.scale = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleLinear */ .m4Y)().domain(this.domain).range(this.getRange()); + } + getTickValues() { + return this.scale.ticks(); + } + recalculateScale() { + const domain = [...this.domain]; + if (this.axisPosition === "left") { + domain.reverse(); + } + this.scale = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleLinear */ .m4Y)().domain(domain).range(this.getRange()); + } + getScaleValue(value) { + return this.scale(value); + } +} +function getAxis(data, axisConfig, axisThemeConfig, tmpSVGGroup2) { + const textDimensionCalculator = new TextDimensionCalculatorWithFont(tmpSVGGroup2); + if (isBandAxisData(data)) { + return new BandAxis( + axisConfig, + axisThemeConfig, + data.categories, + data.title, + textDimensionCalculator + ); + } + return new LinearAxis( + axisConfig, + axisThemeConfig, + [data.min, data.max], + data.title, + textDimensionCalculator + ); +} +class ChartTitle { + constructor(textDimensionCalculator, chartConfig, chartData, chartThemeConfig) { + this.textDimensionCalculator = textDimensionCalculator; + this.chartConfig = chartConfig; + this.chartData = chartData; + this.chartThemeConfig = chartThemeConfig; + this.boundingRect = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + this.showChartTitle = false; + } + setBoundingBoxXY(point) { + this.boundingRect.x = point.x; + this.boundingRect.y = point.y; + } + calculateSpace(availableSpace) { + const titleDimension = this.textDimensionCalculator.getMaxDimension( + [this.chartData.title], + this.chartConfig.titleFontSize + ); + const widthRequired = Math.max(titleDimension.width, availableSpace.width); + const heightRequired = titleDimension.height + 2 * this.chartConfig.titlePadding; + if (titleDimension.width <= widthRequired && titleDimension.height <= heightRequired && this.chartConfig.showTitle && this.chartData.title) { + this.boundingRect.width = widthRequired; + this.boundingRect.height = heightRequired; + this.showChartTitle = true; + } + return { + width: this.boundingRect.width, + height: this.boundingRect.height + }; + } + getDrawableElements() { + const drawableElem = []; + if (this.showChartTitle) { + drawableElem.push({ + groupTexts: ["chart-title"], + type: "text", + data: [ + { + fontSize: this.chartConfig.titleFontSize, + text: this.chartData.title, + verticalPos: "middle", + horizontalPos: "center", + x: this.boundingRect.x + this.boundingRect.width / 2, + y: this.boundingRect.y + this.boundingRect.height / 2, + fill: this.chartThemeConfig.titleColor, + rotation: 0 + } + ] + }); + } + return drawableElem; + } +} +function getChartTitleComponent(chartConfig, chartData, chartThemeConfig, tmpSVGGroup2) { + const textDimensionCalculator = new TextDimensionCalculatorWithFont(tmpSVGGroup2); + return new ChartTitle(textDimensionCalculator, chartConfig, chartData, chartThemeConfig); +} +class LinePlot { + constructor(plotData, xAxis, yAxis, orientation, plotIndex2) { + this.plotData = plotData; + this.xAxis = xAxis; + this.yAxis = yAxis; + this.orientation = orientation; + this.plotIndex = plotIndex2; + } + getDrawableElement() { + const finalData = this.plotData.data.map((d) => [ + this.xAxis.getScaleValue(d[0]), + this.yAxis.getScaleValue(d[1]) + ]); + let path; + if (this.orientation === "horizontal") { + path = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .n8j)().y((d) => d[0]).x((d) => d[1])(finalData); + } else { + path = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .n8j)().x((d) => d[0]).y((d) => d[1])(finalData); + } + if (!path) { + return []; + } + return [ + { + groupTexts: ["plot", `line-plot-${this.plotIndex}`], + type: "path", + data: [ + { + path, + strokeFill: this.plotData.strokeFill, + strokeWidth: this.plotData.strokeWidth + } + ] + } + ]; + } +} +class BarPlot { + constructor(barData, boundingRect, xAxis, yAxis, orientation, plotIndex2) { + this.barData = barData; + this.boundingRect = boundingRect; + this.xAxis = xAxis; + this.yAxis = yAxis; + this.orientation = orientation; + this.plotIndex = plotIndex2; + } + getDrawableElement() { + const finalData = this.barData.data.map((d) => [ + this.xAxis.getScaleValue(d[0]), + this.yAxis.getScaleValue(d[1]) + ]); + const barPaddingPercent = 0.05; + const barWidth = Math.min(this.xAxis.getAxisOuterPadding() * 2, this.xAxis.getTickDistance()) * (1 - barPaddingPercent); + const barWidthHalf = barWidth / 2; + if (this.orientation === "horizontal") { + return [ + { + groupTexts: ["plot", `bar-plot-${this.plotIndex}`], + type: "rect", + data: finalData.map((data) => ({ + x: this.boundingRect.x, + y: data[0] - barWidthHalf, + height: barWidth, + width: data[1] - this.boundingRect.x, + fill: this.barData.fill, + strokeWidth: 0, + strokeFill: this.barData.fill + })) + } + ]; + } + return [ + { + groupTexts: ["plot", `bar-plot-${this.plotIndex}`], + type: "rect", + data: finalData.map((data) => ({ + x: data[0] - barWidthHalf, + y: data[1], + width: barWidth, + height: this.boundingRect.y + this.boundingRect.height - data[1], + fill: this.barData.fill, + strokeWidth: 0, + strokeFill: this.barData.fill + })) + } + ]; + } +} +class BasePlot { + constructor(chartConfig, chartData, chartThemeConfig) { + this.chartConfig = chartConfig; + this.chartData = chartData; + this.chartThemeConfig = chartThemeConfig; + this.boundingRect = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + } + setAxes(xAxis, yAxis) { + this.xAxis = xAxis; + this.yAxis = yAxis; + } + setBoundingBoxXY(point) { + this.boundingRect.x = point.x; + this.boundingRect.y = point.y; + } + calculateSpace(availableSpace) { + this.boundingRect.width = availableSpace.width; + this.boundingRect.height = availableSpace.height; + return { + width: this.boundingRect.width, + height: this.boundingRect.height + }; + } + getDrawableElements() { + if (!(this.xAxis && this.yAxis)) { + throw Error("Axes must be passed to render Plots"); + } + const drawableElem = []; + for (const [i, plot] of this.chartData.plots.entries()) { + switch (plot.type) { + case "line": + { + const linePlot = new LinePlot( + plot, + this.xAxis, + this.yAxis, + this.chartConfig.chartOrientation, + i + ); + drawableElem.push(...linePlot.getDrawableElement()); + } + break; + case "bar": + { + const barPlot = new BarPlot( + plot, + this.boundingRect, + this.xAxis, + this.yAxis, + this.chartConfig.chartOrientation, + i + ); + drawableElem.push(...barPlot.getDrawableElement()); + } + break; + } + } + return drawableElem; + } +} +function getPlotComponent(chartConfig, chartData, chartThemeConfig) { + return new BasePlot(chartConfig, chartData, chartThemeConfig); +} +class Orchestrator { + constructor(chartConfig, chartData, chartThemeConfig, tmpSVGGroup2) { + this.chartConfig = chartConfig; + this.chartData = chartData; + this.componentStore = { + title: getChartTitleComponent(chartConfig, chartData, chartThemeConfig, tmpSVGGroup2), + plot: getPlotComponent(chartConfig, chartData, chartThemeConfig), + xAxis: getAxis( + chartData.xAxis, + chartConfig.xAxis, + { + titleColor: chartThemeConfig.xAxisTitleColor, + labelColor: chartThemeConfig.xAxisLabelColor, + tickColor: chartThemeConfig.xAxisTickColor, + axisLineColor: chartThemeConfig.xAxisLineColor + }, + tmpSVGGroup2 + ), + yAxis: getAxis( + chartData.yAxis, + chartConfig.yAxis, + { + titleColor: chartThemeConfig.yAxisTitleColor, + labelColor: chartThemeConfig.yAxisLabelColor, + tickColor: chartThemeConfig.yAxisTickColor, + axisLineColor: chartThemeConfig.yAxisLineColor + }, + tmpSVGGroup2 + ) + }; + } + calculateVerticalSpace() { + let availableWidth = this.chartConfig.width; + let availableHeight = this.chartConfig.height; + let plotX = 0; + let plotY = 0; + let chartWidth = Math.floor(availableWidth * this.chartConfig.plotReservedSpacePercent / 100); + let chartHeight = Math.floor( + availableHeight * this.chartConfig.plotReservedSpacePercent / 100 + ); + let spaceUsed = this.componentStore.plot.calculateSpace({ + width: chartWidth, + height: chartHeight + }); + availableWidth -= spaceUsed.width; + availableHeight -= spaceUsed.height; + spaceUsed = this.componentStore.title.calculateSpace({ + width: this.chartConfig.width, + height: availableHeight + }); + plotY = spaceUsed.height; + availableHeight -= spaceUsed.height; + this.componentStore.xAxis.setAxisPosition("bottom"); + spaceUsed = this.componentStore.xAxis.calculateSpace({ + width: availableWidth, + height: availableHeight + }); + availableHeight -= spaceUsed.height; + this.componentStore.yAxis.setAxisPosition("left"); + spaceUsed = this.componentStore.yAxis.calculateSpace({ + width: availableWidth, + height: availableHeight + }); + plotX = spaceUsed.width; + availableWidth -= spaceUsed.width; + if (availableWidth > 0) { + chartWidth += availableWidth; + availableWidth = 0; + } + if (availableHeight > 0) { + chartHeight += availableHeight; + availableHeight = 0; + } + this.componentStore.plot.calculateSpace({ + width: chartWidth, + height: chartHeight + }); + this.componentStore.plot.setBoundingBoxXY({ x: plotX, y: plotY }); + this.componentStore.xAxis.setRange([plotX, plotX + chartWidth]); + this.componentStore.xAxis.setBoundingBoxXY({ x: plotX, y: plotY + chartHeight }); + this.componentStore.yAxis.setRange([plotY, plotY + chartHeight]); + this.componentStore.yAxis.setBoundingBoxXY({ x: 0, y: plotY }); + if (this.chartData.plots.some((p) => isBarPlot(p))) { + this.componentStore.xAxis.recalculateOuterPaddingToDrawBar(); + } + } + calculateHorizontalSpace() { + let availableWidth = this.chartConfig.width; + let availableHeight = this.chartConfig.height; + let titleYEnd = 0; + let plotX = 0; + let plotY = 0; + let chartWidth = Math.floor(availableWidth * this.chartConfig.plotReservedSpacePercent / 100); + let chartHeight = Math.floor( + availableHeight * this.chartConfig.plotReservedSpacePercent / 100 + ); + let spaceUsed = this.componentStore.plot.calculateSpace({ + width: chartWidth, + height: chartHeight + }); + availableWidth -= spaceUsed.width; + availableHeight -= spaceUsed.height; + spaceUsed = this.componentStore.title.calculateSpace({ + width: this.chartConfig.width, + height: availableHeight + }); + titleYEnd = spaceUsed.height; + availableHeight -= spaceUsed.height; + this.componentStore.xAxis.setAxisPosition("left"); + spaceUsed = this.componentStore.xAxis.calculateSpace({ + width: availableWidth, + height: availableHeight + }); + availableWidth -= spaceUsed.width; + plotX = spaceUsed.width; + this.componentStore.yAxis.setAxisPosition("top"); + spaceUsed = this.componentStore.yAxis.calculateSpace({ + width: availableWidth, + height: availableHeight + }); + availableHeight -= spaceUsed.height; + plotY = titleYEnd + spaceUsed.height; + if (availableWidth > 0) { + chartWidth += availableWidth; + availableWidth = 0; + } + if (availableHeight > 0) { + chartHeight += availableHeight; + availableHeight = 0; + } + this.componentStore.plot.calculateSpace({ + width: chartWidth, + height: chartHeight + }); + this.componentStore.plot.setBoundingBoxXY({ x: plotX, y: plotY }); + this.componentStore.yAxis.setRange([plotX, plotX + chartWidth]); + this.componentStore.yAxis.setBoundingBoxXY({ x: plotX, y: titleYEnd }); + this.componentStore.xAxis.setRange([plotY, plotY + chartHeight]); + this.componentStore.xAxis.setBoundingBoxXY({ x: 0, y: plotY }); + if (this.chartData.plots.some((p) => isBarPlot(p))) { + this.componentStore.xAxis.recalculateOuterPaddingToDrawBar(); + } + } + calculateSpace() { + if (this.chartConfig.chartOrientation === "horizontal") { + this.calculateHorizontalSpace(); + } else { + this.calculateVerticalSpace(); + } + } + getDrawableElement() { + this.calculateSpace(); + const drawableElem = []; + this.componentStore.plot.setAxes(this.componentStore.xAxis, this.componentStore.yAxis); + for (const component of Object.values(this.componentStore)) { + drawableElem.push(...component.getDrawableElements()); + } + return drawableElem; + } +} +class XYChartBuilder { + static build(config, chartData, chartThemeConfig, tmpSVGGroup2) { + const orchestrator = new Orchestrator(config, chartData, chartThemeConfig, tmpSVGGroup2); + return orchestrator.getDrawableElement(); + } +} +let plotIndex = 0; +let tmpSVGGroup; +let xyChartConfig = getChartDefaultConfig(); +let xyChartThemeConfig = getChartDefaultThemeConfig(); +let xyChartData = getChartDefaultData(); +let plotColorPalette = xyChartThemeConfig.plotColorPalette.split(",").map((color) => color.trim()); +let hasSetXAxis = false; +let hasSetYAxis = false; +function getChartDefaultThemeConfig() { + const defaultThemeVariables = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.E)(); + const config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.F)(); + return (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.C)(defaultThemeVariables.xyChart, config.themeVariables.xyChart); +} +function getChartDefaultConfig() { + const config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.F)(); + return (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.C)( + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.B.xyChart, + config.xyChart + ); +} +function getChartDefaultData() { + return { + yAxis: { + type: "linear", + title: "", + min: Infinity, + max: -Infinity + }, + xAxis: { + type: "band", + title: "", + categories: [] + }, + title: "", + plots: [] + }; +} +function textSanitizer(text) { + const config = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.F)(); + return (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.d)(text.trim(), config); +} +function setTmpSVGG(SVGG) { + tmpSVGGroup = SVGG; +} +function setOrientation(orientation) { + if (orientation === "horizontal") { + xyChartConfig.chartOrientation = "horizontal"; + } else { + xyChartConfig.chartOrientation = "vertical"; + } +} +function setXAxisTitle(title) { + xyChartData.xAxis.title = textSanitizer(title.text); +} +function setXAxisRangeData(min, max) { + xyChartData.xAxis = { type: "linear", title: xyChartData.xAxis.title, min, max }; + hasSetXAxis = true; +} +function setXAxisBand(categories) { + xyChartData.xAxis = { + type: "band", + title: xyChartData.xAxis.title, + categories: categories.map((c) => textSanitizer(c.text)) + }; + hasSetXAxis = true; +} +function setYAxisTitle(title) { + xyChartData.yAxis.title = textSanitizer(title.text); +} +function setYAxisRangeData(min, max) { + xyChartData.yAxis = { type: "linear", title: xyChartData.yAxis.title, min, max }; + hasSetYAxis = true; +} +function setYAxisRangeFromPlotData(data) { + const minValue = Math.min(...data); + const maxValue = Math.max(...data); + const prevMinValue = isLinearAxisData(xyChartData.yAxis) ? xyChartData.yAxis.min : Infinity; + const prevMaxValue = isLinearAxisData(xyChartData.yAxis) ? xyChartData.yAxis.max : -Infinity; + xyChartData.yAxis = { + type: "linear", + title: xyChartData.yAxis.title, + min: Math.min(prevMinValue, minValue), + max: Math.max(prevMaxValue, maxValue) + }; +} +function transformDataWithoutCategory(data) { + let retData = []; + if (data.length === 0) { + return retData; + } + if (!hasSetXAxis) { + const prevMinValue = isLinearAxisData(xyChartData.xAxis) ? xyChartData.xAxis.min : Infinity; + const prevMaxValue = isLinearAxisData(xyChartData.xAxis) ? xyChartData.xAxis.max : -Infinity; + setXAxisRangeData(Math.min(prevMinValue, 1), Math.max(prevMaxValue, data.length)); + } + if (!hasSetYAxis) { + setYAxisRangeFromPlotData(data); + } + if (isBandAxisData(xyChartData.xAxis)) { + retData = xyChartData.xAxis.categories.map((c, i) => [c, data[i]]); + } + if (isLinearAxisData(xyChartData.xAxis)) { + const min = xyChartData.xAxis.min; + const max = xyChartData.xAxis.max; + const step = (max - min + 1) / data.length; + const categories = []; + for (let i = min; i <= max; i += step) { + categories.push(`${i}`); + } + retData = categories.map((c, i) => [c, data[i]]); + } + return retData; +} +function getPlotColorFromPalette(plotIndex2) { + return plotColorPalette[plotIndex2 === 0 ? 0 : plotIndex2 % plotColorPalette.length]; +} +function setLineData(title, data) { + const plotData = transformDataWithoutCategory(data); + xyChartData.plots.push({ + type: "line", + strokeFill: getPlotColorFromPalette(plotIndex), + strokeWidth: 2, + data: plotData + }); + plotIndex++; +} +function setBarData(title, data) { + const plotData = transformDataWithoutCategory(data); + xyChartData.plots.push({ + type: "bar", + fill: getPlotColorFromPalette(plotIndex), + data: plotData + }); + plotIndex++; +} +function getDrawableElem() { + if (xyChartData.plots.length === 0) { + throw Error("No Plot to render, please provide a plot with some data"); + } + xyChartData.title = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.t)(); + return XYChartBuilder.build(xyChartConfig, xyChartData, xyChartThemeConfig, tmpSVGGroup); +} +function getChartThemeConfig() { + return xyChartThemeConfig; +} +function getChartConfig() { + return xyChartConfig; +} +const clear = function() { + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.v)(); + plotIndex = 0; + xyChartConfig = getChartDefaultConfig(); + xyChartData = getChartDefaultData(); + xyChartThemeConfig = getChartDefaultThemeConfig(); + plotColorPalette = xyChartThemeConfig.plotColorPalette.split(",").map((color) => color.trim()); + hasSetXAxis = false; + hasSetYAxis = false; +}; +const db = { + getDrawableElem, + clear, + setAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.s, + getAccTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.g, + setDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.q, + getDiagramTitle: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.t, + getAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.a, + setAccDescription: _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.b, + setOrientation, + setXAxisTitle, + setXAxisRangeData, + setXAxisBand, + setYAxisTitle, + setYAxisRangeData, + setLineData, + setBarData, + setTmpSVGG, + getChartThemeConfig, + getChartConfig +}; +const draw = (txt, id, _version, diagObj) => { + const db2 = diagObj.db; + const themeConfig = db2.getChartThemeConfig(); + const chartConfig = db2.getChartConfig(); + function getDominantBaseLine(horizontalPos) { + return horizontalPos === "top" ? "text-before-edge" : "middle"; + } + function getTextAnchor(verticalPos) { + return verticalPos === "left" ? "start" : verticalPos === "right" ? "end" : "middle"; + } + function getTextTransformation(data) { + return `translate(${data.x}, ${data.y}) rotate(${data.rotation || 0})`; + } + _mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.l.debug("Rendering xychart chart\n" + txt); + const svg = (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.A)(id); + const group = svg.append("g").attr("class", "main"); + const background = group.append("rect").attr("width", chartConfig.width).attr("height", chartConfig.height).attr("class", "background"); + (0,_mermaid_f47111a7_js__WEBPACK_IMPORTED_MODULE_5__.i)(svg, chartConfig.height, chartConfig.width, true); + svg.attr("viewBox", `0 0 ${chartConfig.width} ${chartConfig.height}`); + background.attr("fill", themeConfig.backgroundColor); + db2.setTmpSVGG(svg.append("g").attr("class", "mermaid-tmp-group")); + const shapes = db2.getDrawableElem(); + const groups = {}; + function getGroup(gList) { + let elem = group; + let prefix = ""; + for (const [i] of gList.entries()) { + let parent = group; + if (i > 0 && groups[prefix]) { + parent = groups[prefix]; + } + prefix += gList[i]; + elem = groups[prefix]; + if (!elem) { + elem = groups[prefix] = parent.append("g").attr("class", gList[i]); + } + } + return elem; + } + for (const shape of shapes) { + if (shape.data.length === 0) { + continue; + } + const shapeGroup = getGroup(shape.groupTexts); + switch (shape.type) { + case "rect": + shapeGroup.selectAll("rect").data(shape.data).enter().append("rect").attr("x", (data) => data.x).attr("y", (data) => data.y).attr("width", (data) => data.width).attr("height", (data) => data.height).attr("fill", (data) => data.fill).attr("stroke", (data) => data.strokeFill).attr("stroke-width", (data) => data.strokeWidth); + break; + case "text": + shapeGroup.selectAll("text").data(shape.data).enter().append("text").attr("x", 0).attr("y", 0).attr("fill", (data) => data.fill).attr("font-size", (data) => data.fontSize).attr("dominant-baseline", (data) => getDominantBaseLine(data.verticalPos)).attr("text-anchor", (data) => getTextAnchor(data.horizontalPos)).attr("transform", (data) => getTextTransformation(data)).text((data) => data.text); + break; + case "path": + shapeGroup.selectAll("path").data(shape.data).enter().append("path").attr("d", (data) => data.path).attr("fill", (data) => data.fill ? data.fill : "none").attr("stroke", (data) => data.strokeFill).attr("stroke-width", (data) => data.strokeWidth); + break; + } + } +}; +const renderer = { + draw +}; +const diagram = { + parser: parser$1, + db, + renderer +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/9490f32b.757e45e3.js b/assets/js/9490f32b.757e45e3.js new file mode 100644 index 0000000000..f4814c476c --- /dev/null +++ b/assets/js/9490f32b.757e45e3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3874],{30405:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>l,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var i=t(74848),a=t(28453);const s={sidebar_label:"Glance"},c="Glance",o={id:"iaas/guides/configuration-guide/openstack/glance",title:"Glance",description:"* Glance admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/glance.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/glance",permalink:"/docs/iaas/guides/configuration-guide/openstack/glance",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/glance.md",tags:[],version:"current",frontMatter:{sidebar_label:"Glance"},sidebar:"docs",previous:{title:"Designate",permalink:"/docs/iaas/guides/configuration-guide/openstack/designate"},next:{title:"Heat",permalink:"/docs/iaas/guides/configuration-guide/openstack/heat"}},r={},d=[];function u(e){const n={a:"a",h1:"h1",li:"li",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"glance",children:"Glance"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/glance/latest/admin/index.html",children:"Glance admin guide"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.openstack.org/glance/latest/configuration/index.html",children:"Glance configuration reference"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var i=t(96540);const a={},s=i.createContext(a);function c(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/94b13e0d.a2fb603b.js b/assets/js/94b13e0d.a2fb603b.js new file mode 100644 index 0000000000..eb8b52e023 --- /dev/null +++ b/assets/js/94b13e0d.a2fb603b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9088],{27781:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var o=t(74848),s=t(28453);const i={sidebar_label:"OpenStack Health Monitor"},a="Setting up OpenStack health monitor on Debian",r={id:"iaas/guides/operations-guide/openstack/tools/openstack-health-monitor",title:"Setting up OpenStack health monitor on Debian",description:"Kurt Garloff, 2024-02-20",source:"@site/docs/02-iaas/guides/operations-guide/openstack/tools/openstack-health-monitor.md",sourceDirName:"02-iaas/guides/operations-guide/openstack/tools",slug:"/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/openstack-health-monitor.md",tags:[],version:"current",frontMatter:{sidebar_label:"OpenStack Health Monitor"},sidebar:"docs",previous:{title:"Simple Stress",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress"},next:{title:"Cinder",permalink:"/docs/iaas/guides/operations-guide/openstack/cinder"}},l={},d=[{value:"Intro",id:"intro",level:2},{value:"Setting up the driver VM",id:"setting-up-the-driver-vm",level:2},{value:"Internal vs external monitoring",id:"internal-vs-external-monitoring",level:3},{value:"Unprivileged operation",id:"unprivileged-operation",level:3},{value:"Driver VM via openstack CLI",id:"driver-vm-via-openstack-cli",level:3},{value:"Configuring openstack CLI on the driver VM",id:"configuring-openstack-cli-on-the-driver-vm",level:3},{value:"Custom CA",id:"custom-ca",level:3},{value:"Your first <code>api_monitor.sh</code> iteration",id:"your-first-api_monitorsh-iteration",level:2},{value:"Resource impact and charging",id:"resource-impact-and-charging",level:3},{value:"Automating startup and cleanup",id:"automating-startup-and-cleanup",level:2},{value:"Changing parameters and restarting",id:"changing-parameters-and-restarting",level:3},{value:"Multiple instances",id:"multiple-instances",level:3},{value:"Alarming and Logs",id:"alarming-and-logs",level:2},{value:"eMail",id:"email",level:3},{value:"Log files",id:"log-files",level:3},{value:"Data collection and dashboard",id:"data-collection-and-dashboard",level:2},{value:"telegraf",id:"telegraf",level:3},{value:"influxdb",id:"influxdb",level:3},{value:"Add <code>-S CLOUDNAME</code> to your <code>run_CLOUDNAME.sh</code> script",id:"add--s-cloudname-to-your-run_cloudnamesh-script",level:3},{value:"grafana",id:"grafana",level:3},{value:"Basic config",id:"basic-config",level:4},{value:"Enable influx database in grafana",id:"enable-influx-database-in-grafana",level:4},{value:"Importing the dashboard",id:"importing-the-dashboard",level:4},{value:"No data displayed?",id:"no-data-displayed",level:4},{value:"Dashboard features",id:"dashboard-features",level:4},{value:"github OIDC integration",id:"github-oidc-integration",level:4},{value:"Alternative approach to install and configure the dashboard behind a reverse proxy",id:"alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy",level:2},{value:"Maintenance",id:"maintenance",level:2},{value:"Unattended upgrades",id:"unattended-upgrades",level:3},{value:"Updating openstack-health-monitor",id:"updating-openstack-health-monitor",level:3},{value:"Backup",id:"backup",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Debugging issues",id:"debugging-issues",level:3},{value:"Analyzing failures",id:"analyzing-failures",level:3},{value:"Cleaning things up",id:"cleaning-things-up",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"setting-up-openstack-health-monitor-on-debian",children:"Setting up OpenStack health monitor on Debian"}),"\n",(0,o.jsx)(n.p,{children:"Kurt Garloff, 2024-02-20"}),"\n",(0,o.jsx)(n.h2,{id:"intro",children:"Intro"}),"\n",(0,o.jsxs)(n.p,{children:["The development of ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/",children:"openstack-health-monitor"})," was done on ",(0,o.jsx)(n.a,{href:"https://kfg.images.obs-website.eu-de.otc.t-systems.com/",children:"openSUSE 15.x images"}),", just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution."]}),"\n",(0,o.jsx)(n.p,{children:"Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here."}),"\n",(0,o.jsxs)(n.p,{children:["Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor",children:"successor project"})," for the increasingly hard to maintain shell code, this may not be worth the trouble."]}),"\n",(0,o.jsxs)(n.p,{children:["openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested.\nThe scenario is described in a bit more detail in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"repository's README.md"})," file."]}),"\n",(0,o.jsxs)(n.p,{children:["The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the ",(0,o.jsx)(n.a,{href:"https://docs.scs.community/docs/category/monitoring",children:"monitoring section"})," of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up."]}),"\n",(0,o.jsx)(n.h2,{id:"setting-up-the-driver-vm",children:"Setting up the driver VM"}),"\n",(0,o.jsxs)(n.p,{children:["So we start a ",(0,o.jsx)(n.code,{children:"Debian 12"})," image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard;\nthe instructions use flavor names and image names from the SCS standards.\nFor many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack)."]}),"\n",(0,o.jsx)(n.h3,{id:"internal-vs-external-monitoring",children:"Internal vs external monitoring"}),"\n",(0,o.jsx)(n.p,{children:"There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor."}),"\n",(0,o.jsx)(n.p,{children:"The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems."}),"\n",(0,o.jsx)(n.h3,{id:"unprivileged-operation",children:"Unprivileged operation"}),"\n",(0,o.jsx)(n.p,{children:"Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own."}),"\n",(0,o.jsxs)(n.p,{children:["If ",(0,o.jsx)(n.code,{children:"openstack availability zone list --compute"})," fails for you without admin rights, please fix your openstack client. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Healh-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)"]}),"\n",(0,o.jsx)(n.h3,{id:"driver-vm-via-openstack-cli",children:"Driver VM via openstack CLI"}),"\n",(0,o.jsxs)(n.p,{children:["The author prefers to setup the VM via ",(0,o.jsx)(n.code,{children:"openstack"})," CLI tooling. He has working entries for all clouds he uses in his ",(0,o.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})," and ",(0,o.jsx)(n.code,{children:"secure.yaml"})," and has exported the ",(0,o.jsx)(n.code,{children:"OS_CLOUD"})," environment variable to point to the cloud he is working on to set up the driver VM. The author uses the ",(0,o.jsx)(n.code,{children:"bash"})," shell. All of this of course could be scripted."]}),"\n",(0,o.jsx)(n.p,{children:"So here we go"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["Create the network setup for a VM in a network ",(0,o.jsx)(n.code,{children:"oshm-network"})," with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network."]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"PUBLIC=$(openstack network list --external -f value -c Name)\nopenstack router create oshm-router\nopenstack router set --external-gateway $PUBLIC oshm-driver-router\nopenstack network create oshm-network\nopenstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet\nopenstack router add subnet oshm-router oshm-subnet\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"2",children:["\n",(0,o.jsx)(n.li,{children:"Create a security group that allows ssh and ping access"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack security group create sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"3",children:["\n",(0,o.jsx)(n.li,{children:"Being at it, we also create the security group for grafana"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack security group create grafana\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"4",children:["\n",(0,o.jsx)(n.li,{children:"To connect to the VM via ssh later, we create an SSH keypair"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key\nchmod og-r ~/.ssh/oshm-key.pem \n"})}),"\n",(0,o.jsxs)(n.p,{children:["Rather than creating a new key (and storing and protecting the private key), we could have passed ",(0,o.jsx)(n.code,{children:"--public-key"})," and used an existing keypair."]}),"\n",(0,o.jsxs)(n.ol,{start:"5",children:["\n",(0,o.jsx)(n.li,{children:"Look up Debian 12 image UUID."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"IMGUUID=$(openstack image list --name \"Debian 12\" -f value -c ID | tr -d '\\r')\necho $IMGUUID\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Sidenote: The ",(0,o.jsx)(n.code,{children:"tr"})," command is there to handle broken tooling that embeds a trailing ",(0,o.jsx)(n.code,{children:"\\r"})," in the output."]}),"\n",(0,o.jsxs)(n.ol,{start:"6",children:["\n",(0,o.jsx)(n.li,{children:"Boot the driver VM"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing ",(0,o.jsx)(n.code,{children:"--block-device"}),". See ",(0,o.jsx)(n.a,{href:"https://scs.community/2023/08/21/diskless-flavors/",children:"diskless flavor blog article"}),". For flavors with local root disks, you could have used the ",(0,o.jsx)(n.code,{children:"--image $IMGUUID"})," parameter instead."]}),"\n",(0,o.jsxs)(n.ol,{start:"7",children:["\n",(0,o.jsxs)(n.li,{children:["Wait for it to boot (optional)\nYou can look at the boot log with ",(0,o.jsx)(n.code,{children:"openstack console log show oshm-driver"})," or connect to it via VNC at the URL given by ",(0,o.jsx)(n.code,{children:"openstack console url show oshm-driver"}),". You can of course also query openstack on the status ",(0,o.jsx)(n.code,{children:"openstack server list"})," or ",(0,o.jsx)(n.code,{children:"openstack server show oshm-driver"}),". You can also just create a simple loop:"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'declare -i ctr=0 RC=0\nwhile [ $ctr -le 120 ]; do\n STATUS="$(openstack server list --name oshm-driver -f value -c Status)"\n if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi \n if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi\n if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi\n sleep 2\n let ctr+=1\ndone\n# return $RC\nif [ $RC != 0 ]; then false; fi\n'})}),"\n",(0,o.jsxs)(n.ol,{start:"8",children:["\n",(0,o.jsx)(n.li,{children:"Attach a floating IP so it's reachable from the outside."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks | sed "s@^[^:]*:[^\']*\'\\([0-9\\.]*\\)\'.*\\$@\\1@")\nFIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)\necho $FIXEDIP $FIXEDPORT\nopenstack floating ip create --port $FIXEDPORT $PUBLIC\nFLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")\necho "Floating IP: $FLOATINGIP"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Remember this floating IP address."}),"\n",(0,o.jsxs)(n.ol,{start:"9",children:["\n",(0,o.jsx)(n.li,{children:"Connect to it via ssh"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP\n"})}),"\n",(0,o.jsx)(n.p,{children:"On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"All the following commands are performed on the newly started driver VM."})}),"\n",(0,o.jsx)(n.h3,{id:"configuring-openstack-cli-on-the-driver-vm",children:"Configuring openstack CLI on the driver VM"}),"\n",(0,o.jsx)(n.p,{children:"We need to install the openstack client utilities."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo apt-get update\nsudo apt-get install python3-openstackclient\nsudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Configure your cloud access in ",(0,o.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n interface: public\n identity-api-version: 3\n #region_name: REGION\n auth:\n auth_url: KEYSTONE_ENDPOINT\n project_id: PROJECT_UUID\n #alternatively project_name and project_domain_name\n user_domain_name: default\n # change to your real domain\n"})}),"\n",(0,o.jsxs)(n.p,{children:["and ",(0,o.jsx)(n.code,{children:"secure.yaml"})," (in the same directory)"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n auth:\n username: USERNAME\n password: PASSWORD\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"CLOUDNAME"})," can be freely chosen. This is the value passed to the openstack CLI with ",(0,o.jsx)(n.code,{children:"--os-cloud"})," or exported to your environment in ",(0,o.jsx)(n.code,{children:"OS_CLOUD"}),". The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample ",(0,o.jsx)(n.code,{children:"clouds.yaml"})," file that works (but lacks the password)."]}),"\n",(0,o.jsxs)(n.p,{children:["Protect your ",(0,o.jsx)(n.code,{children:"secure.yaml"})," from being read by others: ",(0,o.jsx)(n.code,{children:"chmod 0600 ~/.config/openstack/secure.yaml"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["If you are using application credentials instead of username, password to authenticate, you don't need to specify ",(0,o.jsx)(n.code,{children:"project_id"})," nor project's nor user's domain names in ",(0,o.jsx)(n.code,{children:"clouds.yaml"}),". Just (in ",(0,o.jsx)(n.code,{children:"secure.yaml"}),"):"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'clouds:\n CLOUDNAME:\n auth_type: v3applicationcredential\n auth:\n application_credential_id: APPCRED_ID\n application_credential_secret: "APPCRED_SECRET"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Configure this to be your default cloud:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"export OS_CLOUD=CLOUDNAME\n"})}),"\n",(0,o.jsxs)(n.p,{children:["You might consider adding this to your ",(0,o.jsx)(n.code,{children:"~/.bashrc"})," for convenience. Being at it, you might want to add ",(0,o.jsx)(n.code,{children:"export CLIFF_FIT_WIDTH=1"})," there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste)."]}),"\n",(0,o.jsx)(n.p,{children:"Verify that your openstack CLI works:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack catalog list\nopenstack server list\n"})}),"\n",(0,o.jsx)(n.p,{children:"You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases."}),"\n",(0,o.jsx)(n.h3,{id:"custom-ca",children:"Custom CA"}),"\n",(0,o.jsxs)(n.p,{children:["If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in ",(0,o.jsx)(n.code,{children:"/etc/ssl/certs/ca-certificates.crt"}),". You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the ",(0,o.jsx)(n.code,{children:"debian"})," user."]}),"\n",(0,o.jsxs)(n.p,{children:["Add it to your ",(0,o.jsx)(n.code,{children:"clouds.yaml"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"clouds:\n CLOUDNAME:\n cacert: /PATH/TO/CACERT.CRT\n [...]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If you want to allow ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"export OS_CACERT=/PATH/TO/CACERT.CRT\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Consider adding this to your ",(0,o.jsx)(n.code,{children:"~/.bashrc"})," as well."]}),"\n",(0,o.jsxs)(n.h2,{id:"your-first-api_monitorsh-iteration",children:["Your first ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," iteration"]}),"\n",(0,o.jsx)(n.p,{children:"Checkout openstack-health-monitor:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install git bc jq netcat-traditional tmux zstd\ngit clone https://github.com/SovereignCloudStack/openstack-health-monitor\ncd openstack-health-monitor\n"})}),"\n",(0,o.jsxs)(n.p,{children:["You may want to start a ",(0,o.jsx)(n.code,{children:"tmux"})," (or ",(0,o.jsx)(n.code,{children:"screen"}),") session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect."]}),"\n",(0,o.jsxs)(n.p,{children:["The script ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"})," file."]}),"\n",(0,o.jsxs)(n.p,{children:["It is good practice to use ",(0,o.jsx)(n.code,{children:"tmux"}),". This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to ",(0,o.jsx)(n.code,{children:"screen"})," over ",(0,o.jsx)(n.code,{children:"tmux"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'export IMG="Debian 12"\nexport JHIMG="Debian 12"\n./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Leave out the ",(0,o.jsx)(n.code,{children:"-LL"})," if you don't have a working loadbalancer service or replace ",(0,o.jsx)(n.code,{children:"-LL"})," with ",(0,o.jsx)(n.code,{children:"-LO"})," if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources)."]}),"\n",(0,o.jsxs)(n.p,{children:["Feel free to study the meaning of all the command line parameters by looking at the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"}),". (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)"]}),"\n",(0,o.jsxs)(n.p,{children:["This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs ",(0,o.jsx)(n.code,{children:"DOWN"}),", ",(0,o.jsx)(n.code,{children:"BUILD"}),", ",(0,o.jsx)(n.code,{children:"creating"})," are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual ",(0,o.jsx)(n.code,{children:"openstack RESOURCE list"})," and ",(0,o.jsx)(n.code,{children:"openstack RESOURCE show NAME"})," and ",(0,o.jsx)(n.code,{children:"RESOURCE"})," being something like ",(0,o.jsx)(n.code,{children:"router"}),", ",(0,o.jsx)(n.code,{children:"network"}),", ",(0,o.jsx)(n.code,{children:"subnet"}),", ",(0,o.jsx)(n.code,{children:"port"}),", ",(0,o.jsx)(n.code,{children:"volume"}),", ",(0,o.jsx)(n.code,{children:"server"}),", ",(0,o.jsx)(n.code,{children:"floating ip"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer pool"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer listener"}),", ",(0,o.jsx)(n.code,{children:"security group"}),", ",(0,o.jsx)(n.code,{children:"keypair"}),", ",(0,o.jsx)(n.code,{children:"image"}),", ...)"]}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," uses and ",(0,o.jsx)(n.code,{children:"APIMonitor_TIMESTAMP"})," prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong.\n",(0,o.jsx)(n.code,{children:"TIMESTAMP"})," is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time)."]}),"\n",(0,o.jsxs)(n.p,{children:["This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least ",(0,o.jsx)(n.code,{children:"-N 2"})," to test the ability of the router to route traffic between networks. So expect ",(0,o.jsx)(n.code,{children:"-n 6"})," to become ",(0,o.jsx)(n.code,{children:"-N 2 -n 6"})," for a very small single-AZ cloud or ",(0,o.jsx)(n.code,{children:"-n 12"})," for a large 3 AZ cloud region. So, re-run the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," with the target sizing."]}),"\n",(0,o.jsx)(n.h3,{id:"resource-impact-and-charging",children:"Resource impact and charging"}),"\n",(0,o.jsxs)(n.p,{children:["Note that ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," uses small flavors (",(0,o.jsx)(n.code,{children:"SCS-1V-2"})," for the N jump hosts and ",(0,o.jsx)(n.code,{children:"SCS-1L-1"})," for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors."]}),"\n",(0,o.jsxs)(n.p,{children:["If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," in a loop (which you will) with say 10 VMs (e.g. ",(0,o.jsx)(n.code,{children:"-N 2 -n 8"}),") in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference."]}),"\n",(0,o.jsxs)(n.p,{children:["Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of ",(0,o.jsx)(n.code,{children:"openstack volume list"}),", ",(0,o.jsx)(n.code,{children:"openstack volume show BROKEN_VOLUME"}),", ",(0,o.jsx)(n.code,{children:"openstack loadbalancer list"}),", ",(0,o.jsx)(n.code,{children:"openstack loadbalancer show BROKEN_LB"}),".)"]}),"\n",(0,o.jsxs)(n.p,{children:["Using ",(0,o.jsx)(n.code,{children:"-w -1"})," makes ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," wait for interactive input whenever an error occurs; this can be convenient for debugging."]}),"\n",(0,o.jsx)(n.p,{children:"Once you have single iterations working nicely, we can proceed."}),"\n",(0,o.jsx)(n.h2,{id:"automating-startup-and-cleanup",children:"Automating startup and cleanup"}),"\n",(0,o.jsxs)(n.p,{children:["Typically, we run ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'#!/bin/bash\n# run_CLOUDNAME.sh\n# Do some global settings\nexport IMG="Debian 12"\nexport JHIMG="Debian 12"\n#export OS_CACERT=/home/debian/ca-certificates.pem\n# Additional settings to override flavors or to\n# configure email addresses for sending alarms can be set here\n\n# Does openstack CLI work?\nopenstack server list >/dev/null || exit 1\n# Upload log files to this swift container (which you need to create)\n#export SWIFTCONTAINER=OS-HM-Logfiles\n\n# CLEANUP\necho "Finding resources from previous runs to clean up ..."\n# Find Floating IPs\nFIPLIST=""\nFIPS=$(openstack floating ip list -f value -c ID)\nfor fip in $FIPS; do\n FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")\n if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_\n"; fi\ndone\nFIPLIST=$(echo "$FIPLIST" | grep -v \'^$\' | sort -u)\n# Cleanup previous interrupted runs\nSERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nKEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nVOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nNETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nLOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nSECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)\necho CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS\nfor ENV in $FIPLIST; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV\n echo "******************************"\ndone\nTOCLEAN=$(echo "$SERVERS\n$KEYPAIR\n$VOLUMES\n$NETWORK\n$LOADBAL\n$ROUTERS\n$SECGRPS\n" | grep -v \'^$\' | sort -u)\nfor ENV in $TOCLEAN; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV\n echo "******************************"\ndone\n\n# Now run the monitor\n#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"\nexec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Compared to the previous run, we have explicitly set two networks here ",(0,o.jsx)(n.code,{children:"-N 2"})," and rely on the iterations being passed in as command line arguments. Add parameter ",(0,o.jsx)(n.code,{children:"-t"})," if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (",(0,o.jsx)(n.code,{children:"-LO"}),") in this example rather than the amphora based one (",(0,o.jsx)(n.code,{children:"-LL"}),")."]}),"\n",(0,o.jsxs)(n.p,{children:["You may use one of the existing ",(0,o.jsx)(n.code,{children:"run_XXXX.sh"})," scripts as example. Beware: eMail alerting with ",(0,o.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESS"})," and ",(0,o.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESS"})," (and limiting with ",(0,o.jsx)(n.code,{children:"-a"})," and ",(0,o.jsx)(n.code,{children:"-R"})," ) and reporting data to telegraf (option ",(0,o.jsx)(n.code,{children:"-S"}),") may be present in the samples. Make this script executable (",(0,o.jsx)(n.code,{children:"chmod +x run_CLOUDNAME.sh"}),")."]}),"\n",(0,o.jsxs)(n.p,{children:["We wrap a loop around this in ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'#!/bin/bash\n# run_in_loop.sh\nrm stop-os-hm 2>/dev/null\nwhile true; do\n ./run_CLOUDNAME.sh -i 200\n if test -e stop-os-hm; then break; fi\n echo -n "Hit ^C to abort ..."\n sleep 15; echo\ndone\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Also make this executable (",(0,o.jsx)(n.code,{children:"chmod +x run_in_loop.sh"}),").\nTo run this automatically in a tmux window whenever the system starts, we follow the steps in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/startup/README.md",children:"startup README.md"})]}),"\n",(0,o.jsxs)(n.p,{children:["Change ",(0,o.jsx)(n.code,{children:"OS_CLOUD"})," in ",(0,o.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"}),". (If you need to set ",(0,o.jsx)(n.code,{children:"OS_CACERT"}),", also add it in this file and pass it into the windows.)"]}),"\n",(0,o.jsx)(n.p,{children:"Activate everything:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"mkdir -p ~/.config/systemd/user/\ncp -p startup/apimon.service ~/.config/systemd/user/\nsystemctl --user enable apimon\nsystemctl --user start apimon\nsudo loginctl enable-linger debian\ntmux attach oshealthmon\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This assumes that you are using the user ",(0,o.jsx)(n.code,{children:"debian"})," for this monitoring and have checked out the repository at ",(0,o.jsx)(n.code,{children:"~/openstack-health-monitor/"}),". Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)"]}),"\n",(0,o.jsx)(n.h3,{id:"changing-parameters-and-restarting",children:"Changing parameters and restarting"}),"\n",(0,o.jsxs)(n.p,{children:["If you want to change the parameters passed to ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),", you best do this by editing ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),", potentially after testing it with one iteration before."]}),"\n",(0,o.jsxs)(n.p,{children:["To make the change effective, you can wait until the current 200 iterations are completed and the ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"})," calls ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," again. You can also hit ",(0,o.jsx)(n.code,{children:"^C"})," in the tmux window that has",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ",(0,o.jsx)(n.code,{children:"^C"})," during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ",(0,o.jsx)(n.code,{children:"^C"})," twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ",(0,o.jsx)(n.code,{children:"./run_in_loop.sh"})," again."]}),"\n",(0,o.jsxs)(n.p,{children:["You can also issue the ",(0,o.jsx)(n.code,{children:"systemctl --user stop apimon"})," command; it will basically do the same thing: Send ",(0,o.jsx)(n.code,{children:"^C"})," and then wait for everything to be completed and tear down the tmux session.\nAfter waiting for that to complete, you can start it again with ",(0,o.jsx)(n.code,{children:"systemctl --user start apimon"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"multiple-instances",children:"Multiple instances"}),"\n",(0,o.jsxs)(n.p,{children:["You can run multiple instances of ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," on the same driver VM. In this case, you should rename ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"})," to e.g. ",(0,o.jsx)(n.code,{children:"run_in_loop_CLOUDNAME1.sh"})," and call ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME1.sh"})," from there. Don't forget to adjust ",(0,o.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"})," and ",(0,o.jsx)(n.code,{children:"startup/kill-apimon-in-tmux.sh"})," to start more windows."]}),"\n",(0,o.jsxs)(n.p,{children:["It is not recommended to run multiple instances against the same OpenStack project however. While the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations."]}),"\n",(0,o.jsx)(n.h2,{id:"alarming-and-logs",children:"Alarming and Logs"}),"\n",(0,o.jsx)(n.h3,{id:"email",children:"eMail"}),"\n",(0,o.jsxs)(n.p,{children:["If wanted, the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the ",(0,o.jsx)(n.code,{children:"-a N"})," and ",(0,o.jsx)(n.code,{children:"-R"})," options. In order to enable sending emails from the driver VM, it needs to have ",(0,o.jsx)(n.code,{children:"postfix"})," (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly."]}),"\n",(0,o.jsxs)(n.p,{children:["Once you have configured ",(0,o.jsx)(n.code,{children:"postfix"}),", you can enable eMail notifications using the option ",(0,o.jsx)(n.code,{children:"-e"}),". Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ",(0,o.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESSES"})," and ",(0,o.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESSES"})," environment variables to ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),", e.g. by setting it in the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"log-files",children:"Log files"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"api_monitor.sh"})," writes a log file with the name ",(0,o.jsx)(n.code,{children:"APIMonitor_TIMESTAMP.log"}),". It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (",(0,o.jsx)(n.code,{children:"TIMESTAMP"})," is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)"]}),"\n",(0,o.jsxs)(n.p,{children:["Note that ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties."]}),"\n",(0,o.jsxs)(n.p,{children:["The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable ",(0,o.jsx)(n.code,{children:"SWIFTCONTAINER"})," has been set (in ",(0,o.jsx)(n.code,{children:"run_COULDNAME.sh"}),") when starting ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),". the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: ",(0,o.jsx)(n.code,{children:"export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER"})]}),"\n",(0,o.jsxs)(n.p,{children:["After the 200 iterations, a ",(0,o.jsx)(n.code,{children:".psv"})," file (pipe-separated values) is created ",(0,o.jsx)(n.code,{children:"Stats.STARTTIME-ENDTIME.psv"})," (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured)."]}),"\n",(0,o.jsx)(n.h2,{id:"data-collection-and-dashboard",children:"Data collection and dashboard"}),"\n",(0,o.jsxs)(n.p,{children:["See ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md",children:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md"})]}),"\n",(0,o.jsx)(n.h3,{id:"telegraf",children:"telegraf"}),"\n",(0,o.jsx)(n.p,{children:"To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key\necho "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list\nsudo apt update\nsudo apt -y install telegraf\n'})}),"\n",(0,o.jsxs)(n.p,{children:["In the config file ",(0,o.jsx)(n.code,{children:"/etc/telegraf/telegraf.conf"}),", we enable"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'[[inputs.influxdb_listener]]\n service_address = ":8186"\n\n[[outputs.influxdb]]\n urls = ["http://127.0.0.1:8086"]\n'})}),"\n",(0,o.jsxs)(n.p,{children:["and restart the service (",(0,o.jsx)(n.code,{children:"sudo systemctl restart telegraf"}),").\nEnable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable telegraf"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"influxdb",children:"influxdb"}),"\n",(0,o.jsx)(n.p,{children:"We proceed to influxdb:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo apt-get install influxdb\n"})}),"\n",(0,o.jsxs)(n.p,{children:["In the configuration file ",(0,o.jsx)(n.code,{children:"/etc/influxdb/influxdb.conf"}),", ensure that the http interface on port 8086 is enabled."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'[http]\n enabled = true\n bind-address = ":8086"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Restart influxdb as needed with ",(0,o.jsx)(n.code,{children:"sudo systemctl restart influxdb"}),".\nAlso enable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable influxdb"}),"."]}),"\n",(0,o.jsxs)(n.h3,{id:"add--s-cloudname-to-your-run_cloudnamesh-script",children:["Add ",(0,o.jsx)(n.code,{children:"-S CLOUDNAME"})," to your ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script"]}),"\n",(0,o.jsxs)(n.p,{children:["You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter ",(0,o.jsx)(n.code,{children:"-S CLOUDNAME"})," to the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," call in ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),". Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete)."]}),"\n",(0,o.jsx)(n.h3,{id:"grafana",children:"grafana"}),"\n",(0,o.jsx)(n.h4,{id:"basic-config",children:"Basic config"}),"\n",(0,o.jsxs)(n.p,{children:["Finally grafana: We (still as root) follow ",(0,o.jsx)(n.a,{href:"https://www.server-world.info/en/note?os=Debian_12&p=grafana",children:"https://www.server-world.info/en/note?os=Debian_12&p=grafana"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'sudo wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key\necho "deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list\nsudo apt update\nsudo apt -y install grafana\n'})}),"\n",(0,o.jsxs)(n.p,{children:["The config file ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," needs some adjustments:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Set the hostname in ",(0,o.jsx)(n.code,{children:"[server]"})," section: ",(0,o.jsx)(n.code,{children:"domain = health.YOURCLOUD.sovereignit.cloud"}),". Set the ",(0,o.jsx)(n.code,{children:"protocol = https"})," if not enabled by default.\nYou can use a hostname of your liking, but we will need to create TLS certificates for this host. So we should have control over DNS TXT records for this domain if we want to use Let's Encrypt with DNSAUTH. The ",(0,o.jsx)(n.code,{children:"sovereignit.cloud"})," domain is controlled by the SCS project team and has been used for a number of health mon instances.\nIn this same section, set ",(0,o.jsx)(n.code,{children:"cert_file = /etc/grafana/health-fullchain.pem"})," and ",(0,o.jsx)(n.code,{children:"cert_key = /etc/grafana/health-key.pem"}),". Ensure that both files are readable by ",(0,o.jsx)(n.code,{children:"root:grafana"})," and that the key file is ",(0,o.jsx)(n.em,{children:"not"})," world-readable."]}),"\n",(0,o.jsxs)(n.li,{children:["Configure the admin access. In section ",(0,o.jsx)(n.code,{children:"[security]"}),", set the ",(0,o.jsx)(n.code,{children:"admin_user = admin"})," and ",(0,o.jsx)(n.code,{children:"admin_password = SOME_SECRET_PASS"})," which you keep private."]}),"\n",(0,o.jsxs)(n.li,{children:["Allow local data sources (same section): ",(0,o.jsx)(n.code,{children:"data_source_proxy_whitelist = localhost:8088 localhost:8086"})]}),"\n",(0,o.jsxs)(n.li,{children:["Let's disallow user signup (in section ",(0,o.jsx)(n.code,{children:"[users]"}),"): ",(0,o.jsx)(n.code,{children:"allow_sign_up = false"})," and ",(0,o.jsx)(n.code,{children:"allow_org_create = false"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["We do the OIDC connection with ",(0,o.jsx)(n.code,{children:"[auth.github]"})," later."]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["We can now restart the service: ",(0,o.jsx)(n.code,{children:"sudo systemctl restart grafana-server"}),".\nBeing at it, also enable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable grafana-server"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["You should now be able to access your dashboard on ",(0,o.jsx)(n.code,{children:"https://health.YOURCLOUD.sovereignit.de:3000"})," and log in via the configured username ",(0,o.jsx)(n.code,{children:"admin"})," and your ",(0,o.jsx)(n.code,{children:"SOME_SECRET_PASS"})," password."]}),"\n",(0,o.jsx)(n.h4,{id:"enable-influx-database-in-grafana",children:"Enable influx database in grafana"}),"\n",(0,o.jsxs)(n.p,{children:["In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to ",(0,o.jsx)(n.code,{children:"http://localhost:8086"})," (despite this being the suggestion). Set the database name to ",(0,o.jsx)(n.code,{children:"telegraf"}),". Save&test should succeed."]}),"\n",(0,o.jsx)(n.h4,{id:"importing-the-dashboard",children:"Importing the dashboard"}),"\n",(0,o.jsxs)(n.p,{children:["Go to Home, Dashboards, New, Import.\nUpload the dashboard ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard.json",children:".json file"})," from the repository, user the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard-10.json",children:"Grafana-10 variant"})," if you use Grafana 10 or newer."]}),"\n",(0,o.jsx)(n.p,{children:"In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.)\nSave."}),"\n",(0,o.jsx)(n.p,{children:"Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable)."}),"\n",(0,o.jsx)(n.h4,{id:"no-data-displayed",children:"No data displayed?"}),"\n",(0,o.jsx)(n.p,{children:'Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.'}),"\n",(0,o.jsx)(n.p,{children:"One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved."}),"\n",(0,o.jsx)(n.h4,{id:"dashboard-features",children:"Dashboard features"}),"\n",(0,o.jsx)(n.p,{children:"Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended."}),"\n",(0,o.jsx)(n.p,{children:"The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously."}),"\n",(0,o.jsx)(n.p,{children:"You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term."}),"\n",(0,o.jsx)(n.h4,{id:"github-oidc-integration",children:"github OIDC integration"}),"\n",(0,o.jsxs)(n.p,{children:["The SCS providers do allow all github users that belong to the SovereignCloudStack organization to get Viewer access to the dashboards by adding a ",(0,o.jsx)(n.code,{children:"client_id"})," and ",(0,o.jsx)(n.code,{children:"client_secret"})," in the ",(0,o.jsx)(n.code,{children:"[github.auth]"})," section that you request from the SCS github admins (github's oauth auth). This allows to exchange experience and to get a feeling for the achievable stability. (Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)"]}),"\n",(0,o.jsx)(n.h2,{id:"alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy",children:"Alternative approach to install and configure the dashboard behind a reverse proxy"}),"\n",(0,o.jsxs)(n.p,{children:["Install influxdb via apt: ",(0,o.jsx)(n.a,{href:"https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss",children:"https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss"}),"\nInstall telegraf (same apt repo as influxdb): ",(0,o.jsx)(n.code,{children:"sudo apt update && sudo apt install telegraf"}),"\nInstall grafana: ",(0,o.jsx)(n.a,{href:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository",children:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository"})]}),"\n",(0,o.jsx)(n.p,{children:"Prepare configuration by using the config files from the repository as an alternative to doing the changes manually (as described above):"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo cp dashboard/telegraf.conf /etc/telegraf && sudo chown root:root /etc/telegraf/telegraf.conf && sudo chmod 0644 /etc/telegraf/telegraf.conf\nsudo cp dashboard/config.toml /etc/influxdb && sudo chown root:influxdb /etc/influxdb/config.toml && sudo chmod 0640 /etc/influxdb/config.toml\nsudo cp dashboard/grafana.ini /etc/grafana && sudo chown root:grafana /etc/grafana/grafana.ini && sudo chmod 0640 /etc/grafana/grafana.ini\n"})}),"\n",(0,o.jsx)(n.p,{children:"These config files should work as long as the versions of telegraf, influxdb and grafana don't evolve too far from the ones used in the repository. (Otherwise refer to above instructions how to tweak the default config files.)"}),"\n",(0,o.jsxs)(n.p,{children:["Changes to ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," as we do tls termination at the reverse proxy:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["set ",(0,o.jsx)(n.code,{children:"protocol = http"})]}),"\n",(0,o.jsxs)(n.li,{children:["comment out ",(0,o.jsx)(n.code,{children:"domain"})," option (? FIXME) or set it to the hostname"]}),"\n",(0,o.jsxs)(n.li,{children:["comment out ",(0,o.jsx)(n.code,{children:"cert_*"})," options"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Also change the admin password in ",(0,o.jsx)(n.code,{children:"grafana.ini"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Changes to ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," if github auth should not be used yet:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["comment out whole ",(0,o.jsx)(n.code,{children:"[auth.github]"})," section for now (can be enabled later)"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Restart services: ",(0,o.jsx)(n.code,{children:"sudo systemctl restart telegraf && sudo systemctl restart influxdb && sudo systemctl restart grafana-server"})]}),"\n",(0,o.jsx)(n.p,{children:"Configuration in grafana web gui:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Login to grafana ",(0,o.jsx)(n.code,{children:"http(s)://<domain>:3000"})," with user admin and default password from ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," and change password."]}),"\n",(0,o.jsxs)(n.li,{children:["Create influxdb datasource with url ",(0,o.jsx)(n.code,{children:"http://localhost:8086"})," and database name ",(0,o.jsx)(n.code,{children:"telegraf"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Finally import dashboard ",(0,o.jsx)(n.code,{children:"dashboard/openstack-health-dashboard.json"})," to grafana."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"TODO:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Reverse proxy (aka ingress) with Let's Encrypt cert"}),"\n",(0,o.jsx)(n.li,{children:"Github auth as described above"}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"maintenance",children:"Maintenance"}),"\n",(0,o.jsx)(n.p,{children:"The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained."}),"\n",(0,o.jsx)(n.h3,{id:"unattended-upgrades",children:"Unattended upgrades"}),"\n",(0,o.jsxs)(n.p,{children:["It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See ",(0,o.jsx)(n.a,{href:"https://wiki.debian.org/UnattendedUpgrades",children:"https://wiki.debian.org/UnattendedUpgrades"}),". If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and grafana (port 3000)."]}),"\n",(0,o.jsx)(n.h3,{id:"updating-openstack-health-monitor",children:"Updating openstack-health-monitor"}),"\n",(0,o.jsxs)(n.p,{children:["You can just do a ",(0,o.jsx)(n.code,{children:"git update"})," in the ",(0,o.jsx)(n.code,{children:"openstack-health-monitor"})," directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ",(0,o.jsx)(n.code,{children:"^C"}),", see above in the restart section."]}),"\n",(0,o.jsx)(n.h3,{id:"backup",children:"Backup"}),"\n",(0,o.jsxs)(n.p,{children:["The system holds two things that you might consider valuable for long-term storage:\n(1) The log files. These are compressed and uploaded to object storage if you enable the ",(0,o.jsx)(n.code,{children:"SWIFTCONTAINER"})," setting, which probably means that these do not need any additional backing up then.\n(2) The influx time series data. Back up the data in ",(0,o.jsx)(n.code,{children:"/var/lib/influxdb"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, ",(0,o.jsx)(n.code,{children:"clouds.yaml"}),", etc. Be careful not to expose sensitive data by granting too generous access to your backed up files."]}),"\n",(0,o.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsx)(n.h3,{id:"debugging-issues",children:"Debugging issues"}),"\n",(0,o.jsx)(n.p,{children:"In case there is trouble with your cloud, the normal course of action to analyze is as follows:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Look at the dashboard (see above)"}),"\n",(0,o.jsxs)(n.li,{children:["Connect to the driver VM and attach to the tmux session and look at the console output of ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})]}),"\n",(0,o.jsx)(n.li,{children:"Analyze the logfile (locally on the driver VM or grab it from the object storage)"}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"analyzing-failures",children:"Analyzing failures"}),"\n",(0,o.jsxs)(n.p,{children:["When VM instances are created successfully, but then end up in ",(0,o.jsx)(n.code,{children:"ERROR"})," state, the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," does an explicit ",(0,o.jsx)(n.code,{children:"openstack server show"}),", so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files."]}),"\n",(0,o.jsxs)(n.p,{children:["Sometimes the VMs end up being ",(0,o.jsx)(n.code,{children:"ACTIVE"})," as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail."]}),"\n",(0,o.jsxs)(n.p,{children:["To gather more details, you can look at the console output ",(0,o.jsx)(n.code,{children:"openstack console log show VM"})," (where ",(0,o.jsx)(n.code,{children:"VM"})," is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ",(0,o.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_JH.pem debian@FIP"}),", whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ",(0,o.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP"}),". Replace ",(0,o.jsx)(n.code,{children:"XXXXX"})," with the number in your current APIMonitor prefix, ",(0,o.jsx)(n.code,{children:"FIP"})," with the floating IP address of the responsible JumpHost and ",(0,o.jsx)(n.code,{children:"debian"})," with the user name used by the images you boot. Use ",(0,o.jsx)(n.code,{children:"223"})," to connect to the second VM in the network, ",(0,o.jsx)(n.code,{children:"224"})," the third etc."]}),"\n",(0,o.jsxs)(n.p,{children:["When logged in, look at ",(0,o.jsx)(n.code,{children:"/var/log/cloud-init-output.log"})," and ",(0,o.jsx)(n.code,{children:"/var/log/cloud-init.log"}),". You can find the metadata in ",(0,o.jsx)(n.code,{children:"/var/lib/cloud/instance/"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["You will not have much time to look around -- the still running ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," script does continue and clean things up again. So you might want to suspend it with ",(0,o.jsx)(n.code,{children:"^Z"})," (and continue it later with ",(0,o.jsx)(n.code,{children:"fg"}),"). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script as it would do cleanup against the running instance, but rather copy the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," command line from the bottom (without the ",(0,o.jsx)(n.code,{children:"exec"}),"), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach ",(0,o.jsx)(n.code,{children:"-w -1"})," to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work."]}),"\n",(0,o.jsx)(n.h3,{id:"cleaning-things-up",children:"Cleaning things up"}),"\n",(0,o.jsx)(n.p,{children:"If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard)."}),"\n",(0,o.jsx)(n.p,{children:"There are a few things that may need support from a cloud admin:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Volumes may end up permanently in a ",(0,o.jsx)(n.code,{children:"deleting"})," or ",(0,o.jsx)(n.code,{children:"reserved"})," state or may be ",(0,o.jsx)(n.code,{children:"in-use"}),", attached to a VM that has long gone. The admin needs to set the state to ",(0,o.jsx)(n.code,{children:"error"})," and then delete them."]}),"\n",(0,o.jsxs)(n.li,{children:["Loadbalancers may end up in a ",(0,o.jsx)(n.code,{children:"PENDING_XXX"})," state (",(0,o.jsx)(n.code,{children:"XXX"})," being ",(0,o.jsx)(n.code,{children:"CREATE"}),", ",(0,o.jsx)(n.code,{children:"UPDATE"})," or ",(0,o.jsx)(n.code,{children:"DELETE"}),") without ever changing. This also needs the cloud admin to set the status to ",(0,o.jsx)(n.code,{children:"ERROR"}),", so it can be cleaned up. amphorae are more prone to this than ovn LBs."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted."}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsxs)(n.em,{children:["The source of this document can be found in the ",(0,o.jsx)(n.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/openstack-health-monitor/main/docs/Debian12-Install.md",children:"SovereignCloudStack/openstack-health-monitor"})," repository."]})}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.em,{children:"Author: SCS Community, License: CC by Attribution 4.0 International"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var o=t(96540);const s={},i=o.createContext(s);function a(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/94f31572.7a306872.js b/assets/js/94f31572.7a306872.js new file mode 100644 index 0000000000..037403d3c3 --- /dev/null +++ b/assets/js/94f31572.7a306872.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9752],{36626:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>c});var s=t(74848),a=t(28453);const o={},i="Frequently Asked Questions",r={id:"faq/index",title:"Frequently Asked Questions",description:"What does SCS stand for?",source:"@site/docs/08-faq/index.mdx",sourceDirName:"08-faq",slug:"/faq/",permalink:"/docs/faq/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/08-faq/index.mdx",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Release Notes for SCS Release 6",permalink:"/docs/releases/Release6"},next:{title:"Glossary",permalink:"/docs/glossary"}},d={},c=[{value:"What does SCS stand for?",id:"what-does-scs-stand-for",level:2},{value:"Who is SCS intended for?",id:"who-is-scs-intended-for",level:2},{value:"Who or what is behind SCS?",id:"who-or-what-is-behind-scs",level:2},{value:"Why is there a need for a standardized cloud environment?",id:"why-is-there-a-need-for-a-standardized-cloud-environment",level:2},{value:"Where can I find the SCS standards?",id:"where-can-i-find-the-scs-standards",level:2},{value:"How is the SCS different from other cloud environments (e.g. AWS, Azure,...)?",id:"how-is-the-scs-different-from-other-cloud-environments-eg-aws-azure",level:2},{value:"My company already has a cloud environment. Can we still use the SCS?",id:"my-company-already-has-a-cloud-environment-can-we-still-use-the-scs",level:2},{value:"What does reference implementation mean?",id:"what-does-reference-implementation-mean",level:2},{value:"Do I need to use the reference implementation to be SCS compliant?",id:"do-i-need-to-use-the-reference-implementation-to-be-scs-compliant",level:2},{value:"Do I have to use all layers of the reference implementation (IaaS, CaaS)?",id:"do-i-have-to-use-all-layers-of-the-reference-implementation-iaas-caas",level:2},{value:"What does IaaS mean?",id:"what-does-iaas-mean",level:2},{value:"How is the IaaS layer structured?",id:"how-is-the-iaas-layer-structured",level:2},{value:"What does CaaS mean? (Container Layer)",id:"what-does-caas-mean-container-layer",level:2},{value:"I want to try out the SCS! Where do I start?",id:"i-want-to-try-out-the-scs-where-do-i-start",level:2},{value:"I want to use an SCS Cloud! How do I get started?",id:"i-want-to-use-an-scs-cloud-how-do-i-get-started",level:2},{value:"I want to use the SCS in my company and build my own cloud! Where do I start?",id:"i-want-to-use-the-scs-in-my-company-and-build-my-own-cloud-where-do-i-start",level:2},{value:"I have a technical problem. Where can I find help?",id:"i-have-a-technical-problem-where-can-i-find-help",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"frequently-asked-questions",children:"Frequently Asked Questions"}),"\n",(0,s.jsx)(n.h2,{id:"what-does-scs-stand-for",children:"What does SCS stand for?"}),"\n",(0,s.jsx)(n.p,{children:"The Sovereign Cloud Stack (SCS) provides standards for a range of cloud infrastructure types. It strives for interoperable and sovereign cloud offerings which can be deployed and used by a wide range of organizations and individuals."}),"\n",(0,s.jsx)(n.h2,{id:"who-is-scs-intended-for",children:"Who is SCS intended for?"}),"\n",(0,s.jsx)(n.p,{children:"SCS is a Software Stack to power data centers of different scale. It empowers public or private cloud service providers to offer resources to their endusers."}),"\n",(0,s.jsx)(n.h2,{id:"who-or-what-is-behind-scs",children:"Who or what is behind SCS?"}),"\n",(0,s.jsx)(n.p,{children:"SCS is run by the SCS Project Team which is based at the Open Source Business Alliance e.V. and 100% funded by the German Ministry of Economics and Climate Action (BMWK). Public money means public code."}),"\n",(0,s.jsx)(n.h2,{id:"why-is-there-a-need-for-a-standardized-cloud-environment",children:"Why is there a need for a standardized cloud environment?"}),"\n",(0,s.jsx)(n.p,{children:"A standardized environment promotes interoperability, reduces vendor lock-in, and facilitates smoother transitions between providers. It gives individuals, companies and public institutions the freedom of choice."}),"\n",(0,s.jsx)(n.h2,{id:"where-can-i-find-the-scs-standards",children:"Where can I find the SCS standards?"}),"\n",(0,s.jsxs)(n.p,{children:["The SCS standards are available on the standards pages within our documentation page. ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/standards",children:"Find them here"})]}),"\n",(0,s.jsx)(n.h2,{id:"how-is-the-scs-different-from-other-cloud-environments-eg-aws-azure",children:"How is the SCS different from other cloud environments (e.g. AWS, Azure,...)?"}),"\n",(0,s.jsx)(n.p,{children:"Unlike proprietary clouds, SCS emphasizes standardization, ensuring interoperability and reduced dependency on one provider."}),"\n",(0,s.jsx)(n.h2,{id:"my-company-already-has-a-cloud-environment-can-we-still-use-the-scs",children:"My company already has a cloud environment. Can we still use the SCS?"}),"\n",(0,s.jsx)(n.p,{children:"Yes, SCS can complement existing environments, enhancing standardization and interoperability."}),"\n",(0,s.jsx)(n.h2,{id:"what-does-reference-implementation-mean",children:"What does reference implementation mean?"}),"\n",(0,s.jsx)(n.p,{children:"Reference implementation is a concrete example or blueprint of how the SCS standards can be implemented."}),"\n",(0,s.jsx)(n.h2,{id:"do-i-need-to-use-the-reference-implementation-to-be-scs-compliant",children:"Do I need to use the reference implementation to be SCS compliant?"}),"\n",(0,s.jsxs)(n.p,{children:["No, while the reference implementation is a guide, compliance requires adhering to SCS standards, not the exact blueprint of the reference implementation. ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/standards/",children:"Check the standards page on how to be SCS-compatible"})]}),"\n",(0,s.jsx)(n.h2,{id:"do-i-have-to-use-all-layers-of-the-reference-implementation-iaas-caas",children:"Do I have to use all layers of the reference implementation (IaaS, CaaS)?"}),"\n",(0,s.jsx)(n.p,{children:"No, you can choose layers based on your needs and still be SCS compliant."}),"\n",(0,s.jsx)(n.h2,{id:"what-does-iaas-mean",children:"What does IaaS mean?"}),"\n",(0,s.jsx)(n.p,{children:"IaaS stands for Infrastructure as a Service, providing virtualized computing resources over the internet."}),"\n",(0,s.jsx)(n.h2,{id:"how-is-the-iaas-layer-structured",children:"How is the IaaS layer structured?"}),"\n",(0,s.jsxs)(n.p,{children:["IaaS typically comprises virtual machines, storage, and network resources, all offered as scalable services. ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/docs/category/iaas-layer",children:"Find the architecture here"})]}),"\n",(0,s.jsx)(n.h2,{id:"what-does-caas-mean-container-layer",children:"What does CaaS mean? (Container Layer)"}),"\n",(0,s.jsx)(n.p,{children:"CaaS refers to Container as a Service, where providers offer container orchestration platforms."}),"\n",(0,s.jsx)(n.h2,{id:"i-want-to-try-out-the-scs-where-do-i-start",children:"I want to try out the SCS! Where do I start?"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"As a user"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Existing SCS Clouds: Explore and test on any of the cloud providers offering SCS. ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/standards/certification/overview#compliant-cloud-environments",children:"Choose one from here"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"As a Cloud Service Provider"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Cloud in a Box"}),": Start with our pre-packaged solutions. ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/docs/iaas/deployment-examples/cloud-in-a-box/advanced-guides/cloud-in-a-box",children:"Link to Ciab"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testbed"}),": Use the SCS test environment to experiment. ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/docs/iaas/deployment-examples/cloud-in-a-box/advanced-guides/testbed",children:"Link to Testbed/deployment example"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"i-want-to-use-an-scs-cloud-how-do-i-get-started",children:"I want to use an SCS Cloud! How do I get started?"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"As a user"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Browse our ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/standards/certification/overview#compliant-cloud-environments",children:"list of providers"})," and choose one that fits your needs."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"As a Cloud Service Provider"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Adopt SCS standards and utilize our ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/docs/category/components",children:"resources and tools"})," to integrate them."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"i-want-to-use-the-scs-in-my-company-and-build-my-own-cloud-where-do-i-start",children:"I want to use the SCS in my company and build my own cloud! Where do I start?"}),"\n",(0,s.jsxs)(n.p,{children:["Start by understanding SCS standards and then move on to the reference implementation. ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/standards/",children:"Link to guide"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"i-have-a-technical-problem-where-can-i-find-help",children:"I have a technical problem. Where can I find help?"}),"\n",(0,s.jsxs)(n.p,{children:["Refer to our support section or check our community channels for assistance. ",(0,s.jsx)(n.a,{href:"https://docs.scs.community/community",children:"Link to community"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var s=t(96540);const a={},o=s.createContext(a);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/950c7487.029c2414.js b/assets/js/950c7487.029c2414.js new file mode 100644 index 0000000000..f9fa9bbb73 --- /dev/null +++ b/assets/js/950c7487.029c2414.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2456],{72512:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var i=t(74848),s=t(28453);const o={},r="Zuul users guide",l={id:"operations/operations/zuul-ci-cd-quickstart-user-guide",title:"Zuul users guide",description:"Prerequisites",source:"@site/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide.md",sourceDirName:"operations/operations",slug:"/operations/operations/zuul-ci-cd-quickstart-user-guide",permalink:"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"devDocs",previous:{title:"OpenStack Federation via OpenID-Connect",permalink:"/contributor-docs/operations/iam/openstack-federation-via-oidc"}},a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Who is it for?",id:"who-is-it-for",level:2},{value:"Where do I start?",id:"where-do-i-start",level:2},{value:"Where to save the Zuul relevant data?",id:"where-to-save-the-zuul-relevant-data",level:2},{value:"Projects",id:"projects",level:3},{value:"Pipelines",id:"pipelines",level:3},{value:"1. check",id:"1-check",level:4},{value:"2. gate",id:"2-gate",level:4},{value:"3. post",id:"3-post",level:4},{value:"4. tag",id:"4-tag",level:4},{value:"5. e2e-test",id:"5-e2e-test",level:4},{value:"6. e2e-quick-test",id:"6-e2e-quick-test",level:4},{value:"7. unlabel-on-update-e2e-test",id:"7-unlabel-on-update-e2e-test",level:4},{value:"8. unlabel-on-update-e2e-quick-test",id:"8-unlabel-on-update-e2e-quick-test",level:4},{value:"9. periodic-hourly",id:"9-periodic-hourly",level:4},{value:"10. periodic-daily",id:"10-periodic-daily",level:4},{value:"11. compliance_check",id:"11-compliance_check",level:4},{value:"Reports",id:"reports",level:3},{value:"Jobs",id:"jobs",level:3},{value:"What about secrets?",id:"what-about-secrets",level:4},{value:"Let's put it all together",id:"lets-put-it-all-together",level:4}];function u(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"zuul-users-guide",children:"Zuul users guide"}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Repository is known by ",(0,i.jsx)(n.a,{href:"https://zuul.scs.community",children:"SCS Zuul"})]}),"\n",(0,i.jsx)(n.li,{children:"Basic ansible knowledge"}),"\n",(0,i.jsx)(n.li,{children:"Basic yaml knowledge"}),"\n",(0,i.jsxs)(n.li,{children:["zuul-client installed (Only if you want to create secrets. ",(0,i.jsx)(n.a,{href:"#what-about-secrets",children:"See also"}),")"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Check ",(0,i.jsx)(n.a,{href:"https://zuul.scs.community/t/SCS/projects",children:"SCS Zuul projects"})," for your repository to\nbe available. If it is missing you need an administrator to get your repository\nconfigured to Zuul."]}),"\n",(0,i.jsx)(n.h2,{id:"who-is-it-for",children:"Who is it for?"}),"\n",(0,i.jsx)(n.p,{children:"You may have heard about Zuul and may ask yourself if it is capable to support you.\nBasically everything you use ansible for can be done using Zuul. That is not always\na good thing since you may get careless and your workload will exceed the CI/CD concept."}),"\n",(0,i.jsx)(n.p,{children:"If you find yourself doing things under the following list you are at the right place."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Code testing"}),"\n",(0,i.jsx)(n.li,{children:"Deployment tests using IaC"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"If you want to, let's say, monitor something using Zuul, that is possible but not the\nintended use case."}),"\n",(0,i.jsx)(n.h2,{id:"where-do-i-start",children:"Where do I start?"}),"\n",(0,i.jsx)(n.p,{children:"Right in your project's repository! The only prerequisite is that\nyour repository you want Zuul to work on is known by Zuul. This is done by the Zuul's\ntenant configuration. To update this configuration you need access to the Zuul instance\nor ask an administrator for help."}),"\n",(0,i.jsx)(n.p,{children:'We assume that Zuul knows about your repository so we can get started. There are three\ntopics that you should know about. To get jobs running you need the "job" itself. Jobs run\nwithin a "pipeline". The third important thing is to provide a "project" definition.'}),"\n",(0,i.jsx)(n.h2,{id:"where-to-save-the-zuul-relevant-data",children:"Where to save the Zuul relevant data?"}),"\n",(0,i.jsx)(n.p,{children:'Zuul will parse all branches of the untrusted repositories that Zuul knows about.\nYour repository is most likely an untrusted one since only the configuration repositories should\nhave the "trusted" state.\nSo it doesn\'t matter whether you have just one branch containing Zuul files or all branches. Zuul\nis looking for the following pathes on your repositories root.'}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"./zuul.yaml # everything is in here\n\n./.zuul.yaml # ... or here\n\n./zuul.d/ # use directory style to get a bit of a structure\n\u251c\u2500\u2500 jobs.yaml\n\u2514\u2500\u2500 project.yaml\n\n./.zuul.d/ # the same as before just hidden\n\u251c\u2500\u2500 jobs.yaml\n\u2514\u2500\u2500 project.yaml\n"})}),"\n",(0,i.jsx)(n.p,{children:"Just use exactly one of the four possibilities."}),"\n",(0,i.jsxs)(n.p,{children:["If using the directory style configuration all ",(0,i.jsx)(n.code,{children:"yaml"})," files within this directory will be\nprocessed. If your projects configuration is small enough you may put all information in\na single file called ",(0,i.jsx)(n.code,{children:"zuul.yaml"}),". It is also possible to create the file or the directory\nwith a leading dot to hide them for non zuul related work within the repository."]}),"\n",(0,i.jsx)(n.h3,{id:"projects",children:"Projects"}),"\n",(0,i.jsx)(n.p,{children:"If Zuul is configured to observe your repository it will have a look at your projects\ndefinition. Minimal example:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'- project:\n name: my-org/my-repo\n default-branch: main\n merge-mode: "squash-merge"\n my_pipeline1:\n jobs:\n - my_job1\n - my_job2\n ......\n my_pipeline2:\n jobs:\n - my_jobs\n ...\n\n'})}),"\n",(0,i.jsx)(n.p,{children:"By default Zuul will observe all branches for such files. We have to set the repository name\nthat have to match the exact value that was set for Zuul. Set a default-branch where actions\nthat don't match an explicit branch are executed on. Set the merge-mode that Zuul has to use.\nBut beware that not all issue tracker support all methods. For github squash-merge will work."}),"\n",(0,i.jsxs)(n.p,{children:["After these three properties add the pipelines you want to use to the project definition.\nWith the ",(0,i.jsx)(n.code,{children:"jobs"})," list you define which jobs to run in which pipeline."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/project.html",children:"See official documentation"})}),"\n",(0,i.jsx)(n.h3,{id:"pipelines",children:"Pipelines"}),"\n",(0,i.jsx)(n.p,{children:"Every Zuul instance will have at least one repository that is used for configuration. There\nyou will find the available pipelines. Pipelines are used to run your jobs on a periodic or\nevent driven base. Pipelines can be used to run other pipelines and to keep your jobs in a\ndefined order if you need this."}),"\n",(0,i.jsxs)(n.p,{children:["Have a look at the configuration repository to utilize the pipelines for your repository.\nSee available ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-config/blob/main/zuul.d/gh_pipelines.yaml",children:"pipelines"}),' for SCS.\nYou are not able to define new pipelines outside of a so called "configuration" repository. Since,\nby default your repo is considered "untrusted". So in the first place you don\'t need to\nthink about, how to create a pipeline. Just use one that fits your needs as close as possible. Next you will\nfind an enumeration and a small description about the available pipelines in SCS Zuul.']}),"\n",(0,i.jsx)(n.p,{children:"Pipelines available in SCS Zuul:"}),"\n",(0,i.jsx)(n.h4,{id:"1-check",children:"1. check"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,i.jsx)(n.li,{children:"runs if a pull request is created, changed or reopened"}),"\n",(0,i.jsxs)(n.li,{children:["re-runs if a comment contains ",(0,i.jsx)(n.code,{children:"recheck"})]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"2-gate",children:"2. gate"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,i.jsx)(n.li,{children:"trigger events: pull_request_review, pull_request, check_run"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"3-post",children:"3. post"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,i.jsx)(n.li,{children:"trigger event: post"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"4-tag",children:"4. tag"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,i.jsx)(n.li,{children:"trigger event: push"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"5-e2e-test",children:"5. e2e-test"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,i.jsx)(n.li,{children:"trigger event: pull_request"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"6-e2e-quick-test",children:"6. e2e-quick-test"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,i.jsx)(n.li,{children:"trigger event: pull_request"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"7-unlabel-on-update-e2e-test",children:"7. unlabel-on-update-e2e-test"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,i.jsx)(n.li,{children:"trigger event: pull_request"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"8-unlabel-on-update-e2e-quick-test",children:"8. unlabel-on-update-e2e-quick-test"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"event driven pipeline"}),"\n",(0,i.jsx)(n.li,{children:"trigger event: pull_request"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"9-periodic-hourly",children:"9. periodic-hourly"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"time based pipeline that runs every hour"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"10-periodic-daily",children:"10. periodic-daily"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"time based pipeline that runs every day at 3 o'clock am."}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"11-compliance_check",children:"11. compliance_check"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"time based pipeline that runs every 15 minutes"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you want to know more about pipelines: ",(0,i.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/pipeline.html",children:"See official documentation"})]}),"\n",(0,i.jsx)(n.h3,{id:"reports",children:"Reports"}),"\n",(0,i.jsxs)(n.p,{children:["The SCS Zuul instance can transmit build reports through an MQTT connection\nto the dedicated Matrix chat room ",(0,i.jsx)(n.code,{children:"SCS | Zuul Reports"}),". Currently, this MQTT reporting\nfeature is activated for periodic pipelines (periodic-hourly, periodic-daily,\ncompliance_check), and reports are dispatched solely in the event of\nfailures occurring in builds triggered by the mentioned pipelines."]}),"\n",(0,i.jsxs)(n.p,{children:["See an example pipeline that reports failed result to the ",(0,i.jsx)(n.code,{children:"SCS | Zuul Reports"})," Matrix room:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'- pipeline:\n name: pipeline-that-reports-to-matrix\n description: |\n In the event of a failure, this pipeline transmits reports to\n the SCS | Zuul Reports Matrix chat room.\n failure:\n mqtt:\n topic: "zuul/{pipeline}/{project}/{branch}/{change}"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Visit the ",(0,i.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/pipeline.html#reporters",children:"official Zuul documentation"}),"\nand explore the configuration options available for Zuul's reporters."]}),"\n",(0,i.jsx)(n.h3,{id:"jobs",children:"Jobs"}),"\n",(0,i.jsxs)(n.p,{children:["All jobs that your Zuul instances knows of can be used for your own purposes.\nCall them directly or implement a job that uses an existing job as parent.\nDidn't find the right job? Than we have to create a new one. Existing jobs\ncan be found in the web ui of your Zuul instance: ",(0,i.jsx)(n.a,{href:"https://zuul.scs.community/t/SCS/jobs",children:"Example"})]}),"\n",(0,i.jsx)(n.p,{children:"First have a look on a basic job example:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"- job:\n name: base\n parent: null\n description: |\n The recommended base job.\n\n All jobs ultimately inherit from this. It runs a pre-playbook\n which copies all of the job's prepared git repos on to all of\n the nodes in the nodeset.\n\n It also sets a default timeout value (which may be overidden).\n pre-run: playbooks/base/pre.yaml\n post-run:\n - playbooks/base/post.yaml\n - playbooks/base/post-logs.yaml\n roles:\n - zuul: zuul/zuul-jobs\n timeout: 1800\n nodeset:\n nodes:\n - name: ubuntu-jammy\n label: ubuntu-jammy\n"})}),"\n",(0,i.jsx)(n.p,{children:'Each job needs a name that has to be unique within the whole tenant.\nA useful convention to achieve this is to prepend the name of the repository.\nEach job need to define whether there is parent job or not.\nJobs without a parent are called "base" jobs. Usually you don\'t want to implement base jobs since\nthere are already some base jobs that implement often used stuff. A description may not be mandatory\nbut is obviously useful.'}),"\n",(0,i.jsxs)(n.p,{children:["Necessary for Zuul to do anything you just need to add a ",(0,i.jsx)(n.code,{children:"run"})," or ",(0,i.jsx)(n.code,{children:"roles"})," property. Within a job that is\nlike a ",(0,i.jsx)(n.code,{children:"noop"})," job or just printing something to stdout that is everything you need to run your first job.\nSince anything we want to do requires a little bit more you have to define a nodeset. The nodes\nare used to run your playbooks on. In 99,9% you will need this too."]}),"\n",(0,i.jsxs)(n.p,{children:["The properties ",(0,i.jsx)(n.code,{children:"pre-run"})," and ",(0,i.jsx)(n.code,{children:"post-run"})," are useful for bootstrap and cleanup. If your actual job wants to create\nbootstrap some infrastructure you can to this in the ",(0,i.jsx)(n.code,{children:"pre-run"}),". Using an cloud provider you want to release\nno longer used resources. That can be done in the ",(0,i.jsx)(n.code,{children:"post-run"}),'. If you are using a parent job it is likely\nthat the parent job may has pre- and post-run playbooks. In this case your pre- and post-run playbooks are\n"nested". Example:']}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"pre-run parent"}),"\n",(0,i.jsx)(n.li,{children:"pre-run my job"}),"\n",(0,i.jsx)(n.li,{children:"post-run my job"}),"\n",(0,i.jsx)(n.li,{children:"post-run parent"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"If your job exceeds the defined timeout, the job is considered as failed."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/job.html",children:"See official documentation"})}),"\n",(0,i.jsx)(n.h4,{id:"what-about-secrets",children:"What about secrets?"}),"\n",(0,i.jsx)(n.p,{children:"Right now you should be able to run basic tasks. But what if you try to test something\nthat needs credentials to connect to an outside service? Or you have to address additional\nressources in an openstack environment and you have to use something like app credentials?"}),"\n",(0,i.jsx)(n.p,{children:"That is where job secrets are used. Example:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"- job:\n name: SOME_JOB\n parent: base\n description: |\n A job basic job used as example\n secrets:\n - name: clouds_conf\n secret: app_credential_cloud_conf\n run: playbooks/my-playbook.yaml\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Secrets for a job are simply defined by the keyword ",(0,i.jsx)(n.code,{children:"secrets"}),".\nEach secret needs a name that can be used in your playbooks.\nThe property ",(0,i.jsx)(n.code,{children:"secret"})," references the secret that is defined within your project."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"ATTENTION!"})," If your job is using a secret ",(0,i.jsx)(n.code,{children:"job.post-review"})," is automatically\nset to ",(0,i.jsx)(n.code,{children:"true"}),". For untrusted projects, that means that your job is only called\nin piplines that have the ",(0,i.jsx)(n.code,{children:"pipeline.post-review"})," flag set to ",(0,i.jsx)(n.code,{children:"true"}),". In SCS context\nthat means you may run these jobs only with the pipelines ",(0,i.jsx)(n.code,{children:"tag"})," and ",(0,i.jsx)(n.code,{children:"post"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["If you want to run jobs on pipelines that have ",(0,i.jsx)(n.code,{children:"post-review"})," set to ",(0,i.jsx)(n.code,{children:"false"}),", which\nis default, and your job needs a secret, the secret may be defined in the zuul-config repository."]}),"\n",(0,i.jsx)(n.p,{children:"Example:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"- secret:\n name: app_credential_cloud_conf\n data:\n credentials: my-secret-value\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Within ",(0,i.jsx)(n.code,{children:"my-playbook.yaml"})," you can reference the secret value using ",(0,i.jsx)(n.code,{children:'"{{ clouds_conf.credentials }}"'}),".\nIn this example ",(0,i.jsx)(n.code,{children:"my-secret-value"})," is clear readable text. That is not something we want to keep\nsecrets. But how do you encrypt secrets in a way that they are secure and also can be decrypted by\nZuul?"]}),"\n",(0,i.jsx)(n.p,{children:"For this purpose Zuul creates its own public/private key pair for each project. Everyone may use the\npublic key to create secrets. But only Zuul will be able to decrypt these values. To avoid the user\nto be responsible for the correct encryption there is an zuul-client tool that will do this for you."}),"\n",(0,i.jsx)(n.p,{children:"Example (reading from stdin and writing to stdout):"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"zuul-client --zuul-url ZUUL_URL encrypt --tenant SCS --project SovereignCloudStack/REPO\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Add ",(0,i.jsx)(n.code,{children:"--infile INFILE"})," or ",(0,i.jsx)(n.code,{children:"--outfile OUTFILE"})," if you prefer to work with files directly."]}),"\n",(0,i.jsx)(n.p,{children:"The output might look like this:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"- secret:\n name: <name>\n data:\n <fieldname>: !encrypted/pkcs1-oaep\n - IGZ2Wu47R9mEY4fjetbxSAUGNaz4HR1mjk9lCLq3HsUMjHGj9YPlb2MvnPQw1LCJSvpaK\n ogth7hi2zYwrs5tNAik/qlVSB7AM+LQRP7lmlM4JmD6WOyR7DisHu7oMD1Gqem2ZuMggA\n DIBn5+DeBIvnwihDOcS+BKPTVMEtXOJNkuObZHE8DweB/RQIGUvjyeq5yoAmz/y+qGVqe\n 0Vk4pTYFIBgk5DMzwVnDzDkqs/QokoOupMUoBcpapmM11do4ymjbDpeINjayoro6VXTtX\n Mkk9fDv9wuJIQTuyHAOfMD+UYS/HqVSF/Hm9ScUvfhw02gTdzKCxliWhFHJOj7RbdUUMK\n OYYcUkNp5cXZUYFnflMhxVEnzREbdAIklNPfoHOizsxLPaUZ9yk6XcFRflFfMvqBtUS00\n LCx0Uh906NwdaEUrv2ZdrN123rwfwfw4333232rDFDFfsdfddsfdDFSFSdqrrtwms5Mi0\n szUBaM4j+Mayep+41vl0cpsLU91GzXEATWMaPIN8OnEHF6qQIv0wB6VaKd5aeAyERisb3\n wFdjEo4faLO70RWzR33k+4xqAYNIIFyTMpWJz21CUSfoYG8ygL6t7RJGgyjA+0KsVEyj+\n ewEtiaUOLYyD7pXtqdw1HgzjqiXnfxk+wSv/y5y/TGGYpQj8zU76jS7Zj0ft/0=\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You may use this content or the file to provide it as a secret. You just have to update the ",(0,i.jsx)(n.code,{children:"<name>"})," and the\n",(0,i.jsx)(n.code,{children:"<fieldname>"})," part."]}),"\n",(0,i.jsxs)(n.p,{children:["The secret name has to be unique across all projects. Because of this, we have a naming convention in the\n",(0,i.jsx)(n.code,{children:"SovereignCloudStack"})," organisation that ensures that a secret has a unique name."]}),"\n",(0,i.jsxs)(n.p,{children:["Our convention is as follows. There is only one secret per Zuul configuration per project (for exceptions,\nsee below). This secret always has a name in the form\n",(0,i.jsx)(n.code,{children:"SECRET_REPOSITORY_NAME"}),". For instance, if a secret in the ",(0,i.jsx)(n.code,{children:"SovereignCloudStack/k8s-cluster-api-provider"}),"\nrepository is\nto be used, it is given the name ",(0,i.jsx)(n.code,{children:"SECRET_K8S_CLUSTER_API_PROVIDER"}),". The name of the repository is\nalways written in capital letters. A dash is replaced with an underscore. Any number of values\n(",(0,i.jsx)(n.code,{children:"<fieldname>: !encrypted/pkcs1-oaep"}),") can then be assigned to this one secret."]}),"\n",(0,i.jsxs)(n.p,{children:["In certain cases, it can be undesireable to expose all secret information to all jobs in a project.\nThen additional secrets may be used, whose names have to be formed by appending an underscore and some\nupper-case prefix to the name of the primary secret. For instance, we might use the\nname ",(0,i.jsx)(n.code,{children:"SECRET_REPOSITORY_NAME_FOOBAR"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Official documentation:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/config/secret.html#secret",children:"Secrets documentation"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/project-config.html#encryption",children:"Encryption documentation"})}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"lets-put-it-all-together",children:"Let's put it all together"}),"\n",(0,i.jsxs)(n.p,{children:["For a basic but working example the following content may be written into a ",(0,i.jsx)(n.code,{children:"zuul.yaml"})," file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# zuul.yaml content\n---\n- secret:\n name: SECRET_REPOSITORY_NAME\n data:\n secretValue1: !encrypted/pkcs1-oaep\n - <ENCRYPTED_DATA>\n secretValue2: !encrypted/pkcs1-oaep\n - <ENCRYPTED_DATA>\n secretValue3: !encrypted/pkcs1-oaep\n - <ENCRYPTED_DATA>\n\n- job:\n name: myFirstTestJob\n parent: base\n secrets:\n - name: secretName # The name of the secret that is used within "playbooks/testPlaybook.yaml"\n secret: SECRET_REPOSITORY_NAME\n run: playbooks/testPlaybook.yaml\n\n- job:\n name: mySecondTestJob\n parent: base\n run: playbooks/testPlaybookTwo.yaml\n\n- project:\n tag:\n jobs:\n - myFirstTestJob\n check:\n jobs:\n - mySecondTestJob\n'})}),"\n",(0,i.jsxs)(n.p,{children:["This will run the job ",(0,i.jsx)(n.code,{children:"myFirstTestJob"})," whenever the ",(0,i.jsx)(n.code,{children:"tag"})," pipeline is triggered, and\n",(0,i.jsx)(n.code,{children:"mySecondTestJob"})," whenever ",(0,i.jsx)(n.code,{children:"check"})," is triggered."]}),"\n",(0,i.jsxs)(n.p,{children:["Within SCS the ",(0,i.jsx)(n.code,{children:"check"})," pipeline is always triggered if you open, change or reopen a pull request.\nThis pipeline can also be triggered manually if you write a comment on an already\nexisting pull request and place the string ",(0,i.jsx)(n.code,{children:"recheck"})," in it."]}),"\n",(0,i.jsxs)(n.p,{children:["Recall that the first test job cannot run on the same pipeline because it uses a secret.\nThe ",(0,i.jsx)(n.code,{children:"tag"})," pipeline is run whenever a new tag is created."]}),"\n",(0,i.jsx)(n.p,{children:"The path to you playbook is always the full path within the repository. The playbook\ncontains the tasks you actually want to run on all or a specific subset of nodes.\nExample playbook:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"# playbooks/testPlaybook.yaml content\n---\n- hosts: all\n tasks:\n - debug:\n msg: 'Debug print my secrets! {{ secretName.secretValue1 }}' # do not do this as it will expose your secrets\n"})})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>l});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/95800b3e.192dcdf0.js b/assets/js/95800b3e.192dcdf0.js new file mode 100644 index 0000000000..a42365cc22 --- /dev/null +++ b/assets/js/95800b3e.192dcdf0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5515],{76284:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>l,toc:()=>c});var a=t(74848),i=t(28453);const s={sidebar_label:"Layers in a cluster",sidebar_position:20},o="Layers in a cluster",l={id:"iaas/guides/concept-guide/layers",title:"Layers in a cluster",description:"Compute Plane",source:"@site/docs/02-iaas/guides/concept-guide/layers.md",sourceDirName:"02-iaas/guides/concept-guide",slug:"/iaas/guides/concept-guide/layers",permalink:"/docs/iaas/guides/concept-guide/layers",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/layers.md",tags:[],version:"current",sidebarPosition:20,frontMatter:{sidebar_label:"Layers in a cluster",sidebar_position:20},sidebar:"docs",previous:{title:"Teleport",permalink:"/docs/iaas/guides/concept-guide/components/teleport"},next:{title:"Cluster design",permalink:"/docs/iaas/guides/concept-guide/design"}},r={},c=[{value:"Compute Plane",id:"compute-plane",level:2},{value:"Control Plane",id:"control-plane",level:2},{value:"Data Plane",id:"data-plane",level:2},{value:"Management Plane",id:"management-plane",level:2},{value:"Monitoring Plane",id:"monitoring-plane",level:2},{value:"Network Plane",id:"network-plane",level:2}];function d(e){const n={h1:"h1",h2:"h2",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h1,{id:"layers-in-a-cluster",children:"Layers in a cluster"}),"\n",(0,a.jsx)(n.h2,{id:"compute-plane",children:"Compute Plane"}),"\n",(0,a.jsx)(n.h2,{id:"control-plane",children:"Control Plane"}),"\n",(0,a.jsx)(n.h2,{id:"data-plane",children:"Data Plane"}),"\n",(0,a.jsx)(n.h2,{id:"management-plane",children:"Management Plane"}),"\n",(0,a.jsx)(n.h2,{id:"monitoring-plane",children:"Monitoring Plane"}),"\n",(0,a.jsx)(n.h2,{id:"network-plane",children:"Network Plane"})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>l});var a=t(96540);const i={},s=a.createContext(i);function o(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/95967863.b925d6f1.js b/assets/js/95967863.b925d6f1.js new file mode 100644 index 0000000000..72a95923c2 --- /dev/null +++ b/assets/js/95967863.b925d6f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8200],{13784:e=>{e.exports=JSON.parse('{"pluginId":"contributor-docs","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"devDocs":[{"type":"category","label":"Developer documentation","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"tests","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"SCS RFC2119 Keyword Test Guide","href":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","docId":"development/tests/rfc2119-keyword-test-guide","unlisted":false},{"type":"link","label":"SCS Conformance Test Implementation Guide","href":"/contributor-docs/development/tests/test-implementation-guide","docId":"development/tests/test-implementation-guide","unlisted":false}]}],"href":"/contributor-docs/development/"},{"type":"link","label":"Documentation for SCS Contributors","href":"/contributor-docs/","docId":"index","unlisted":false},{"type":"category","label":"operations","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"iam","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Identity Federation in SCS","href":"/contributor-docs/operations/iam/identity-federation-in-scs","docId":"operations/iam/identity-federation-in-scs","unlisted":false},{"type":"link","label":"OpenStack Federation via OpenID-Connect","href":"/contributor-docs/operations/iam/openstack-federation-via-oidc","docId":"operations/iam/openstack-federation-via-oidc","unlisted":false}]},{"type":"category","label":"operations","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Zuul users guide","href":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","docId":"operations/operations/zuul-ci-cd-quickstart-user-guide","unlisted":false}]}]}]},"docs":{"development/index":{"id":"development/index","title":"Developer documentation","description":"Welcome to the developer section of the contributor docs. Here you will find","sidebar":"devDocs"},"development/tests/rfc2119-keyword-test-guide":{"id":"development/tests/rfc2119-keyword-test-guide","title":"SCS RFC2119 Keyword Test Guide","description":"Introduction","sidebar":"devDocs"},"development/tests/test-implementation-guide":{"id":"development/tests/test-implementation-guide","title":"SCS Conformance Test Implementation Guide","description":"SovereignCloudStack (SCS) uses conformance tests to certify","sidebar":"devDocs"},"index":{"id":"index","title":"Documentation for SCS Contributors","description":"Welcome to the Contributor Docs. This section is primarily for SCS Contributors and will contain documentation regarding the Development and Architecture of the Sovereign Cloud Stack and its components. You will find documents, explanations and guides regarding the tooling necessary for the development of SCS.","sidebar":"devDocs"},"operations/iam/identity-federation-in-scs":{"id":"operations/iam/identity-federation-in-scs","title":"Identity Federation in SCS","description":"SovereignCloudStack wants to make it possible for operators to delegate","sidebar":"devDocs"},"operations/iam/openstack-federation-via-oidc":{"id":"operations/iam/openstack-federation-via-oidc","title":"OpenStack Federation via OpenID-Connect","description":"Keystone supports federating authentication and authorization decisions via several mechanisms","sidebar":"devDocs"},"operations/operations/zuul-ci-cd-quickstart-user-guide":{"id":"operations/operations/zuul-ci-cd-quickstart-user-guide","title":"Zuul users guide","description":"Prerequisites","sidebar":"devDocs"}}}')}}]); \ No newline at end of file diff --git a/assets/js/95d93785.d32a37bc.js b/assets/js/95d93785.d32a37bc.js new file mode 100644 index 0000000000..3af1864dea --- /dev/null +++ b/assets/js/95d93785.d32a37bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4503],{30667:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var r=o(74848),t=o(28453);const i={},s="Requirements",c={id:"container/components/k8s-cluster-api-provider/doc/requirements",title:"Requirements",description:"Cluster API requires an existing Kubernetes cluster to operate. In our setup, we",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/requirements.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc",slug:"/container/components/k8s-cluster-api-provider/doc/requirements",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/requirements",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/requirements.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Overview",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/overview"},next:{title:"Quickstart",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/quickstart"}},l={},a=[{value:"Environments",id:"environments",level:2},{value:"Plusserver community environment",id:"plusserver-community-environment",level:3},{value:"Wavestack environment",id:"wavestack-environment",level:3},{value:"Custom environment",id:"custom-environment",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"requirements",children:"Requirements"}),"\n",(0,r.jsxs)(n.p,{children:["Cluster API requires an existing Kubernetes cluster to operate. In our setup, we\nutilize ",(0,r.jsx)(n.a,{href:"https://kind.sigs.k8s.io/",children:"kind"})," a tool for running Kubernetes clusters using Docker containers, to create\nthe initial management Kubernetes cluster in a single docker container. The OpenStack instance serves as the CAPI\nmanagement server or management cluster, responsible for overseeing the\nmanagement and operation of the created kubernetes clusters."]}),"\n",(0,r.jsx)(n.p,{children:"The provisioning of the CAPI management server is done on a deployment host, possibly a tiny jumphost style VM, or some\nLinux/MacOS/WSL laptop."}),"\n",(0,r.jsx)(n.p,{children:"Requirements for the deployment host:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["You need to have installed:","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://opentofu.org/docs/intro/install/",children:"OpenTofu"})}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"yq"})," (python3-yq or yq snap)"]}),"\n",(0,r.jsx)(n.li,{children:"GNU make"}),"\n",(0,r.jsxs)(n.li,{children:["openstack (python3-openstackclient) and plugin for octavia (python3-octaviaclient) Via pip or your distribution.\n",(0,r.jsx)(n.em,{children:"Needed only in case you want to clean the management server or interact with openstack directly."})]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["You must have credentials to access the cloud. OpenTofu will look for ",(0,r.jsx)(n.code,{children:"clouds.yaml"})," and optionally ",(0,r.jsx)(n.code,{children:"secure.yaml"})," in\nthe current working directory (",(0,r.jsx)(n.code,{children:"terraform"}),"), in ",(0,r.jsx)(n.code,{children:"~/.config/openstack/"})," or ",(0,r.jsx)(n.code,{children:"/etc/openstack"})," (in this order), just like\nthe ",(0,r.jsx)(n.a,{href:"https://docs.openstack.org/python-openstackclient/latest/configuration/index.html#clouds-yaml",children:"openstack client"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"The API endpoints of the OpenStack cloud should have a certificate signed by a trusted CA. (Self-signed or custom CAs\nneed significant manual work -- this will be improved after R4.)"}),"\n",(0,r.jsxs)(n.li,{children:["An Environment file for the cloud you want to use. See ",(0,r.jsx)(n.a,{href:"#environments",children:"Environments"})," below for more details."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"environments",children:"Environments"}),"\n",(0,r.jsxs)(n.p,{children:["To use a specific environment, you have to set the ",(0,r.jsx)(n.code,{children:"ENVIRONMENT"})," variable (",(0,r.jsx)(n.code,{children:"export ENVIRONMENT=<yourcloud>"}),") or pass it\nto the ",(0,r.jsx)(n.code,{children:"make"})," command by using ",(0,r.jsx)(n.code,{children:"make <command> ENVIRONMENT=<yourcloud>"}),".\nYou can also do the same by utilizing the ",(0,r.jsx)(n.code,{children:"OS_CLOUD"})," (openstack native) variable.\nThe name of the environment is derived from the name of the file ",(0,r.jsx)(n.code,{children:"environments/environment-<yourcloud>.tfvars"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The name of the environment specified either via ",(0,r.jsx)(n.code,{children:"ENVIRONMENT"})," or ",(0,r.jsx)(n.code,{children:"OS_CLOUD"})," has to be equal the name of the\ncloud (",(0,r.jsx)(n.code,{children:"cloud_provider"}),") as specified in your ",(0,r.jsx)(n.code,{children:"clouds.yaml"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["In case you use ",(0,r.jsx)(n.a,{href:"#plusserver-community-environment",children:"plusserver community environment"}),"\nor ",(0,r.jsx)(n.a,{href:"#wavestack-environment",children:"wavestack environment"})," you can use the default environment file for\nthose directly or base your configuration on it. In case you need custom configuration\nsee ",(0,r.jsx)(n.a,{href:"#custom-environment",children:"Custom environment"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["More information about the configuration options can be found in the ",(0,r.jsx)(n.a,{href:"/docs/container/components/k8s-cluster-api-provider/doc/configuration",children:"configuration documentation"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"plusserver-community-environment",children:"Plusserver community environment"}),"\n",(0,r.jsxs)(n.p,{children:["Using it directly:\n",(0,r.jsx)(n.code,{children:"export ENVIRONMENT=gx-scs"})]}),"\n",(0,r.jsxs)(n.p,{children:["or insert inside of Makefile:\n",(0,r.jsx)(n.code,{children:"ENVIRONMENT=gx-scs"})]}),"\n",(0,r.jsxs)(n.p,{children:["File: ",(0,r.jsx)(n.code,{children:"environments/environment-gx-scs.tfvars"})]}),"\n",(0,r.jsxs)(n.p,{children:["The name of the cloud has to be ",(0,r.jsx)(n.code,{children:"gx-scs"})," in the ",(0,r.jsx)(n.code,{children:"cloud.yaml"})," file, otherwise you will need\nto change the ",(0,r.jsx)(n.code,{children:"cloud_provider"})," variable inside of ",(0,r.jsx)(n.code,{children:"terraform/environments/environment-gx-scs.tfvars"})," file."]}),"\n",(0,r.jsx)(n.h3,{id:"wavestack-environment",children:"Wavestack environment"}),"\n",(0,r.jsxs)(n.p,{children:["Using it directly:\n",(0,r.jsx)(n.code,{children:"export ENVIRONMENT=gx-wavestack"})]}),"\n",(0,r.jsxs)(n.p,{children:["or insert inside of Makefile:\n",(0,r.jsx)(n.code,{children:"ENVIRONMENT=gx-wavestack"})]}),"\n",(0,r.jsxs)(n.p,{children:["File: ",(0,r.jsx)(n.code,{children:"environments/environment-gx-wavestack.tfvars"})]}),"\n",(0,r.jsxs)(n.p,{children:["The name of the cloud has to be ",(0,r.jsx)(n.code,{children:"gx-wavestack"})," in the ",(0,r.jsx)(n.code,{children:"cloud.yaml"})," file, otherwise you will need\nto change the ",(0,r.jsx)(n.code,{children:"cloud_provider"})," variable inside of ",(0,r.jsx)(n.code,{children:"terraform/environments/environment-gx-scs.tfvars"})," file."]}),"\n",(0,r.jsx)(n.h3,{id:"custom-environment",children:"Custom environment"}),"\n",(0,r.jsxs)(n.p,{children:["You can create your own environment file from the sample file ",(0,r.jsx)(n.code,{children:"environments/environment-default.tfvars"})," and provide the\nnecessary information like machine flavor or machine image. You can comment out all lines where the defaults match your\nneeds."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>c});var r=o(96540);const t={},i=r.createContext(t);function s(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/95fe5f6c.1582ab24.js b/assets/js/95fe5f6c.1582ab24.js new file mode 100644 index 0000000000..628ddb6728 --- /dev/null +++ b/assets/js/95fe5f6c.1582ab24.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9850],{85728:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>l,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var s=n(74848),o=n(28453);const r={},c="Usage",a={id:"container/components/k8s-cluster-api-provider/doc/usage/usage",title:"Usage",description:"The subsequent management of the cluster can best be done from the management server VM, as it has all the tools",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/usage.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc/usage",slug:"/container/components/k8s-cluster-api-provider/doc/usage/",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/usage/usage.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Roadmap",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/roadmap"},next:{title:"Create a new cluster",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster"}},i={},d=[];function u(e){const t={code:"code",h1:"h1",p:"p",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"usage",children:"Usage"}),"\n",(0,s.jsxs)(t.p,{children:["The subsequent management of the cluster can best be done from the management server VM, as it has all the tools\ndeployed there and config files can be edited and resubmitted to the kubernetes kind cluster for reconciliation. To log\nin to this management server via ssh, you can issue ",(0,s.jsx)(t.code,{children:"make ssh"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"You can create and do life cycle management for many more clusters from this management server."}),"\n",(0,s.jsxs)(t.p,{children:["The kubeconfig with admin power for the created testcluster is named ",(0,s.jsx)(t.code,{children:"testcluster/testcluster.yaml"})," (\nor ",(0,s.jsx)(t.code,{children:"$CLUSTER_NAME/$CLUSTER_NAME.yaml"})," for all the other clusters) and can be handed out to users that should get full\nadministrative control over the cluster. You can also retrieve them\nusing ",(0,s.jsx)(t.code,{children:"make get-kubeconfig TESTCLUSTER=${CLUSTER_NAME}"})," from the machines where you created the management server from,\nand possibly create an encrypted .zip file for handing these out. (You can omit ",(0,s.jsx)(t.code,{children:"TESTCLUSTER=..."})," for the\ndefault testcluster.)"]})]})}function l(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>a});var s=n(96540);const o={},r=s.createContext(o);function c(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9688.2bdfb4b9.js b/assets/js/9688.2bdfb4b9.js new file mode 100644 index 0000000000..891efcc1ae --- /dev/null +++ b/assets/js/9688.2bdfb4b9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9688],{39688:(t,e,i)=>{i.d(e,{diagram:()=>T});var n=i(76257),r=i(26312),s=i(21176),a=i(697),l=(i(74353),i(16750),i(42838),function(){var t=function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i},e=[1,3],i=[1,4],n=[1,5],r=[1,6],s=[5,6,8,9,11,13,31,32,33,34,35,36,44,62,63],a=[1,18],l=[2,7],c=[1,22],o=[1,23],h=[1,24],u=[1,25],y=[1,26],d=[1,27],p=[1,20],_=[1,28],E=[1,29],g=[62,63],R=[5,8,9,11,13,31,32,33,34,35,36,44,51,53,62,63],m=[1,47],f=[1,48],I=[1,49],b=[1,50],k=[1,51],S=[1,52],T=[1,53],N=[53,54],x=[1,64],A=[1,60],v=[1,61],q=[1,62],$=[1,63],O=[1,65],w=[1,69],C=[1,70],L=[1,67],F=[1,68],M=[5,8,9,11,13,31,32,33,34,35,36,44,62,63],D={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,acc_title:9,acc_title_value:10,acc_descr:11,acc_descr_value:12,acc_descr_multiline_value:13,requirementDef:14,elementDef:15,relationshipDef:16,requirementType:17,requirementName:18,STRUCT_START:19,requirementBody:20,ID:21,COLONSEP:22,id:23,TEXT:24,text:25,RISK:26,riskLevel:27,VERIFYMTHD:28,verifyType:29,STRUCT_STOP:30,REQUIREMENT:31,FUNCTIONAL_REQUIREMENT:32,INTERFACE_REQUIREMENT:33,PERFORMANCE_REQUIREMENT:34,PHYSICAL_REQUIREMENT:35,DESIGN_CONSTRAINT:36,LOW_RISK:37,MED_RISK:38,HIGH_RISK:39,VERIFY_ANALYSIS:40,VERIFY_DEMONSTRATION:41,VERIFY_INSPECTION:42,VERIFY_TEST:43,ELEMENT:44,elementName:45,elementBody:46,TYPE:47,type:48,DOCREF:49,ref:50,END_ARROW_L:51,relationship:52,LINE:53,END_ARROW_R:54,CONTAINS:55,COPIES:56,DERIVES:57,SATISFIES:58,VERIFIES:59,REFINES:60,TRACES:61,unqString:62,qString:63,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",9:"acc_title",10:"acc_title_value",11:"acc_descr",12:"acc_descr_value",13:"acc_descr_multiline_value",19:"STRUCT_START",21:"ID",22:"COLONSEP",24:"TEXT",26:"RISK",28:"VERIFYMTHD",30:"STRUCT_STOP",31:"REQUIREMENT",32:"FUNCTIONAL_REQUIREMENT",33:"INTERFACE_REQUIREMENT",34:"PERFORMANCE_REQUIREMENT",35:"PHYSICAL_REQUIREMENT",36:"DESIGN_CONSTRAINT",37:"LOW_RISK",38:"MED_RISK",39:"HIGH_RISK",40:"VERIFY_ANALYSIS",41:"VERIFY_DEMONSTRATION",42:"VERIFY_INSPECTION",43:"VERIFY_TEST",44:"ELEMENT",47:"TYPE",49:"DOCREF",51:"END_ARROW_L",53:"LINE",54:"END_ARROW_R",55:"CONTAINS",56:"COPIES",57:"DERIVES",58:"SATISFIES",59:"VERIFIES",60:"REFINES",61:"TRACES",62:"unqString",63:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,2],[4,2],[4,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[14,5],[20,5],[20,5],[20,5],[20,5],[20,2],[20,1],[17,1],[17,1],[17,1],[17,1],[17,1],[17,1],[27,1],[27,1],[27,1],[29,1],[29,1],[29,1],[29,1],[15,5],[46,5],[46,5],[46,2],[46,1],[16,5],[16,5],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[18,1],[18,1],[23,1],[23,1],[25,1],[25,1],[45,1],[45,1],[48,1],[48,1],[50,1],[50,1]],performAction:function(t,e,i,n,r,s,a){var l=s.length-1;switch(r){case 4:this.$=s[l].trim(),n.setAccTitle(this.$);break;case 5:case 6:this.$=s[l].trim(),n.setAccDescription(this.$);break;case 7:this.$=[];break;case 13:n.addRequirement(s[l-3],s[l-4]);break;case 14:n.setNewReqId(s[l-2]);break;case 15:n.setNewReqText(s[l-2]);break;case 16:n.setNewReqRisk(s[l-2]);break;case 17:n.setNewReqVerifyMethod(s[l-2]);break;case 20:this.$=n.RequirementType.REQUIREMENT;break;case 21:this.$=n.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 22:this.$=n.RequirementType.INTERFACE_REQUIREMENT;break;case 23:this.$=n.RequirementType.PERFORMANCE_REQUIREMENT;break;case 24:this.$=n.RequirementType.PHYSICAL_REQUIREMENT;break;case 25:this.$=n.RequirementType.DESIGN_CONSTRAINT;break;case 26:this.$=n.RiskLevel.LOW_RISK;break;case 27:this.$=n.RiskLevel.MED_RISK;break;case 28:this.$=n.RiskLevel.HIGH_RISK;break;case 29:this.$=n.VerifyType.VERIFY_ANALYSIS;break;case 30:this.$=n.VerifyType.VERIFY_DEMONSTRATION;break;case 31:this.$=n.VerifyType.VERIFY_INSPECTION;break;case 32:this.$=n.VerifyType.VERIFY_TEST;break;case 33:n.addElement(s[l-3]);break;case 34:n.setNewElementType(s[l-2]);break;case 35:n.setNewElementDocRef(s[l-2]);break;case 38:n.addRelationship(s[l-2],s[l],s[l-4]);break;case 39:n.addRelationship(s[l-2],s[l-4],s[l]);break;case 40:this.$=n.Relationships.CONTAINS;break;case 41:this.$=n.Relationships.COPIES;break;case 42:this.$=n.Relationships.DERIVES;break;case 43:this.$=n.Relationships.SATISFIES;break;case 44:this.$=n.Relationships.VERIFIES;break;case 45:this.$=n.Relationships.REFINES;break;case 46:this.$=n.Relationships.TRACES}},table:[{3:1,4:2,6:e,9:i,11:n,13:r},{1:[3]},{3:8,4:2,5:[1,7],6:e,9:i,11:n,13:r},{5:[1,9]},{10:[1,10]},{12:[1,11]},t(s,[2,6]),{3:12,4:2,6:e,9:i,11:n,13:r},{1:[2,2]},{4:17,5:a,7:13,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},t(s,[2,4]),t(s,[2,5]),{1:[2,1]},{8:[1,30]},{4:17,5:a,7:31,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{4:17,5:a,7:32,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{4:17,5:a,7:33,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{4:17,5:a,7:34,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{4:17,5:a,7:35,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{18:36,62:[1,37],63:[1,38]},{45:39,62:[1,40],63:[1,41]},{51:[1,42],53:[1,43]},t(g,[2,20]),t(g,[2,21]),t(g,[2,22]),t(g,[2,23]),t(g,[2,24]),t(g,[2,25]),t(R,[2,49]),t(R,[2,50]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{19:[1,44]},{19:[2,47]},{19:[2,48]},{19:[1,45]},{19:[2,53]},{19:[2,54]},{52:46,55:m,56:f,57:I,58:b,59:k,60:S,61:T},{52:54,55:m,56:f,57:I,58:b,59:k,60:S,61:T},{5:[1,55]},{5:[1,56]},{53:[1,57]},t(N,[2,40]),t(N,[2,41]),t(N,[2,42]),t(N,[2,43]),t(N,[2,44]),t(N,[2,45]),t(N,[2,46]),{54:[1,58]},{5:x,20:59,21:A,24:v,26:q,28:$,30:O},{5:w,30:C,46:66,47:L,49:F},{23:71,62:_,63:E},{23:72,62:_,63:E},t(M,[2,13]),{22:[1,73]},{22:[1,74]},{22:[1,75]},{22:[1,76]},{5:x,20:77,21:A,24:v,26:q,28:$,30:O},t(M,[2,19]),t(M,[2,33]),{22:[1,78]},{22:[1,79]},{5:w,30:C,46:80,47:L,49:F},t(M,[2,37]),t(M,[2,38]),t(M,[2,39]),{23:81,62:_,63:E},{25:82,62:[1,83],63:[1,84]},{27:85,37:[1,86],38:[1,87],39:[1,88]},{29:89,40:[1,90],41:[1,91],42:[1,92],43:[1,93]},t(M,[2,18]),{48:94,62:[1,95],63:[1,96]},{50:97,62:[1,98],63:[1,99]},t(M,[2,36]),{5:[1,100]},{5:[1,101]},{5:[2,51]},{5:[2,52]},{5:[1,102]},{5:[2,26]},{5:[2,27]},{5:[2,28]},{5:[1,103]},{5:[2,29]},{5:[2,30]},{5:[2,31]},{5:[2,32]},{5:[1,104]},{5:[2,55]},{5:[2,56]},{5:[1,105]},{5:[2,57]},{5:[2,58]},{5:x,20:106,21:A,24:v,26:q,28:$,30:O},{5:x,20:107,21:A,24:v,26:q,28:$,30:O},{5:x,20:108,21:A,24:v,26:q,28:$,30:O},{5:x,20:109,21:A,24:v,26:q,28:$,30:O},{5:w,30:C,46:110,47:L,49:F},{5:w,30:C,46:111,47:L,49:F},t(M,[2,14]),t(M,[2,15]),t(M,[2,16]),t(M,[2,17]),t(M,[2,34]),t(M,[2,35])],defaultActions:{8:[2,2],12:[2,1],30:[2,3],31:[2,8],32:[2,9],33:[2,10],34:[2,11],35:[2,12],37:[2,47],38:[2,48],40:[2,53],41:[2,54],83:[2,51],84:[2,52],86:[2,26],87:[2,27],88:[2,28],90:[2,29],91:[2,30],92:[2,31],93:[2,32],95:[2,55],96:[2,56],98:[2,57],99:[2,58]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=this,i=[0],n=[],r=[null],s=[],a=this.table,l="",c=0,o=0,h=s.slice.call(arguments,1),u=Object.create(this.lexer),y={yy:{}};for(var d in this.yy)Object.prototype.hasOwnProperty.call(this.yy,d)&&(y.yy[d]=this.yy[d]);u.setInput(t,y.yy),y.yy.lexer=u,y.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var p=u.yylloc;s.push(p);var _=u.options&&u.options.ranges;"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var E,g,R,m,f,I,b,k,S,T={};;){if(g=i[i.length-1],this.defaultActions[g]?R=this.defaultActions[g]:(null==E&&(S=void 0,"number"!=typeof(S=n.pop()||u.lex()||1)&&(S instanceof Array&&(S=(n=S).pop()),S=e.symbols_[S]||S),E=S),R=a[g]&&a[g][E]),void 0===R||!R.length||!R[0]){var N="";for(f in k=[],a[g])this.terminals_[f]&&f>2&&k.push("'"+this.terminals_[f]+"'");N=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[E]||E)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==E?"end of input":"'"+(this.terminals_[E]||E)+"'"),this.parseError(N,{text:u.match,token:this.terminals_[E]||E,line:u.yylineno,loc:p,expected:k})}if(R[0]instanceof Array&&R.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+E);switch(R[0]){case 1:i.push(E),r.push(u.yytext),s.push(u.yylloc),i.push(R[1]),E=null,o=u.yyleng,l=u.yytext,c=u.yylineno,p=u.yylloc;break;case 2:if(I=this.productions_[R[1]][1],T.$=r[r.length-I],T._$={first_line:s[s.length-(I||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(I||1)].first_column,last_column:s[s.length-1].last_column},_&&(T._$.range=[s[s.length-(I||1)].range[0],s[s.length-1].range[1]]),void 0!==(m=this.performAction.apply(T,[l,o,c,y.yy,R[1],r,s].concat(h))))return m;I&&(i=i.slice(0,-1*I*2),r=r.slice(0,-1*I),s=s.slice(0,-1*I)),i.push(this.productions_[R[1]][0]),r.push(T.$),s.push(T._$),b=a[i[i.length-2]][i[i.length-1]],i.push(b);break;case 3:return!0}}return!0}},P={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,i=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var i,n,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in r)this[s]=r[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),s=0;s<r.length;s++)if((i=this._input.match(this.rules[r[s]]))&&(!e||i[0].length>e[0].length)){if(e=i,n=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,r[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,i,n){switch(i){case 0:return"title";case 1:return this.begin("acc_title"),9;case 2:return this.popState(),"acc_title_value";case 3:return this.begin("acc_descr"),11;case 4:return this.popState(),"acc_descr_value";case 5:this.begin("acc_descr_multiline");break;case 6:case 48:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:return 5;case 9:case 10:case 11:break;case 12:return 8;case 13:return 6;case 14:return 19;case 15:return 30;case 16:return 22;case 17:return 21;case 18:return 24;case 19:return 26;case 20:return 28;case 21:return 31;case 22:return 32;case 23:return 33;case 24:return 34;case 25:return 35;case 26:return 36;case 27:return 37;case 28:return 38;case 29:return 39;case 30:return 40;case 31:return 41;case 32:return 42;case 33:return 43;case 34:return 44;case 35:return 55;case 36:return 56;case 37:return 57;case 38:return 58;case 39:return 59;case 40:return 60;case 41:return 61;case 42:return 47;case 43:return 49;case 44:return 51;case 45:return 54;case 46:return 53;case 47:this.begin("string");break;case 49:return"qString";case 50:return e.yytext=e.yytext.trim(),62}},rules:[/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^\r\n\{\<\>\-\=]*)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},unqString:{rules:[],inclusive:!1},token:{rules:[],inclusive:!1},string:{rules:[48,49],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,50],inclusive:!0}}};function V(){this.yy={}}return D.lexer=P,V.prototype=D,D.Parser=V,new V}());l.parser=l;const c=l;let o=[],h={},u={},y={},d={};const p={RequirementType:{REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"},RiskLevel:{LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"},VerifyType:{VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"},Relationships:{CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"},getConfig:()=>(0,n.c)().req,addRequirement:(t,e)=>(void 0===u[t]&&(u[t]={name:t,type:e,id:h.id,text:h.text,risk:h.risk,verifyMethod:h.verifyMethod}),h={},u[t]),getRequirements:()=>u,setNewReqId:t=>{void 0!==h&&(h.id=t)},setNewReqText:t=>{void 0!==h&&(h.text=t)},setNewReqRisk:t=>{void 0!==h&&(h.risk=t)},setNewReqVerifyMethod:t=>{void 0!==h&&(h.verifyMethod=t)},setAccTitle:n.s,getAccTitle:n.g,setAccDescription:n.b,getAccDescription:n.a,addElement:t=>(void 0===d[t]&&(d[t]={name:t,type:y.type,docRef:y.docRef},n.l.info("Added new requirement: ",t)),y={},d[t]),getElements:()=>d,setNewElementType:t=>{void 0!==y&&(y.type=t)},setNewElementDocRef:t=>{void 0!==y&&(y.docRef=t)},addRelationship:(t,e,i)=>{o.push({type:t,src:e,dst:i})},getRelationships:()=>o,clear:()=>{o=[],h={},u={},y={},d={},(0,n.v)()}},_={CONTAINS:"contains",ARROW:"arrow"},E=_,g=(t,e)=>{let i=t.append("defs").append("marker").attr("id",_.CONTAINS+"_line_ending").attr("refX",0).attr("refY",e.line_height/2).attr("markerWidth",e.line_height).attr("markerHeight",e.line_height).attr("orient","auto").append("g");i.append("circle").attr("cx",e.line_height/2).attr("cy",e.line_height/2).attr("r",e.line_height/2).attr("fill","none"),i.append("line").attr("x1",0).attr("x2",e.line_height).attr("y1",e.line_height/2).attr("y2",e.line_height/2).attr("stroke-width",1),i.append("line").attr("y1",0).attr("y2",e.line_height).attr("x1",e.line_height/2).attr("x2",e.line_height/2).attr("stroke-width",1),t.append("defs").append("marker").attr("id",_.ARROW+"_line_ending").attr("refX",e.line_height).attr("refY",.5*e.line_height).attr("markerWidth",e.line_height).attr("markerHeight",e.line_height).attr("orient","auto").append("path").attr("d",`M0,0\n L${e.line_height},${e.line_height/2}\n M${e.line_height},${e.line_height/2}\n L0,${e.line_height}`).attr("stroke-width",1)};let R={},m=0;const f=(t,e)=>t.insert("rect","#"+e).attr("class","req reqBox").attr("x",0).attr("y",0).attr("width",R.rect_min_width+"px").attr("height",R.rect_min_height+"px"),I=(t,e,i)=>{let n=R.rect_min_width/2,r=t.append("text").attr("class","req reqLabel reqTitle").attr("id",e).attr("x",n).attr("y",R.rect_padding).attr("dominant-baseline","hanging"),s=0;i.forEach((t=>{0==s?r.append("tspan").attr("text-anchor","middle").attr("x",R.rect_min_width/2).attr("dy",0).text(t):r.append("tspan").attr("text-anchor","middle").attr("x",R.rect_min_width/2).attr("dy",.75*R.line_height).text(t),s++}));let a=1.5*R.rect_padding+s*R.line_height*.75;return t.append("line").attr("class","req-title-line").attr("x1","0").attr("x2",R.rect_min_width).attr("y1",a).attr("y2",a),{titleNode:r,y:a}},b=(t,e,i,n)=>{let r=t.append("text").attr("class","req reqLabel").attr("id",e).attr("x",R.rect_padding).attr("y",n).attr("dominant-baseline","hanging"),s=0;let a=[];return i.forEach((t=>{let e=t.length;for(;e>30&&s<3;){let i=t.substring(0,30);e=(t=t.substring(30,t.length)).length,a[a.length]=i,s++}if(3==s){let t=a[a.length-1];a[a.length-1]=t.substring(0,t.length-4)+"..."}else a[a.length]=t;s=0})),a.forEach((t=>{r.append("tspan").attr("x",R.rect_padding).attr("dy",R.line_height).text(t)})),r},k=function(t,e,i,s,a){const l=i.edge(S(e.src),S(e.dst)),c=(0,r.n8j)().x((function(t){return t.x})).y((function(t){return t.y})),o=t.insert("path","#"+s).attr("class","er relationshipLine").attr("d",c(l.points)).attr("fill","none");e.type==a.db.Relationships.CONTAINS?o.attr("marker-start","url("+n.e.getUrl(R.arrowMarkerAbsolute)+"#"+e.type+"_line_ending)"):(o.attr("stroke-dasharray","10,7"),o.attr("marker-end","url("+n.e.getUrl(R.arrowMarkerAbsolute)+"#"+E.ARROW+"_line_ending)")),((t,e,i,n)=>{const r=e.node().getTotalLength(),s=e.node().getPointAtLength(.5*r),a="rel"+m;m++;const l=t.append("text").attr("class","req relationshipLabel").attr("id",a).attr("x",s.x).attr("y",s.y).attr("text-anchor","middle").attr("dominant-baseline","middle").text(n).node().getBBox();t.insert("rect","#"+a).attr("class","req reqLabelBox").attr("x",s.x-l.width/2).attr("y",s.y-l.height/2).attr("width",l.width).attr("height",l.height).attr("fill","white").attr("fill-opacity","85%")})(t,o,0,`<<${e.type}>>`)},S=t=>t.replace(/\s/g,"").replace(/\./g,"_"),T={parser:c,db:p,renderer:{draw:(t,e,i,l)=>{R=(0,n.c)().requirement;const c=R.securityLevel;let o;"sandbox"===c&&(o=(0,r.Ltv)("#i"+e));const h=("sandbox"===c?(0,r.Ltv)(o.nodes()[0].contentDocument.body):(0,r.Ltv)("body")).select(`[id='${e}']`);g(h,R);const u=new a.T({multigraph:!1,compound:!1,directed:!0}).setGraph({rankdir:R.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));let y=l.db.getRequirements(),d=l.db.getElements(),p=l.db.getRelationships();var _,E,m;_=y,E=u,m=h,Object.keys(_).forEach((t=>{let e=_[t];t=S(t),n.l.info("Added new requirement: ",t);const i=m.append("g").attr("id",t),r=f(i,"req-"+t);let s=I(i,t+"_title",[`<<${e.type}>>`,`${e.name}`]);b(i,t+"_body",[`Id: ${e.id}`,`Text: ${e.text}`,`Risk: ${e.risk}`,`Verification: ${e.verifyMethod}`],s.y);const a=r.node().getBBox();E.setNode(t,{width:a.width,height:a.height,shape:"rect",id:t})})),((t,e,i)=>{Object.keys(t).forEach((n=>{let r=t[n];const s=S(n),a=i.append("g").attr("id",s),l="element-"+s,c=f(a,l);let o=I(a,l+"_title",["<<Element>>",`${n}`]);b(a,l+"_body",[`Type: ${r.type||"Not Specified"}`,`Doc Ref: ${r.docRef||"None"}`],o.y);const h=c.node().getBBox();e.setNode(s,{width:h.width,height:h.height,shape:"rect",id:s})}))})(d,u,h),((t,e)=>{t.forEach((function(t){let i=S(t.src),n=S(t.dst);e.setEdge(i,n,{relationship:t})}))})(p,u),(0,s.Zp)(u),function(t,e){e.nodes().forEach((function(i){void 0!==i&&void 0!==e.node(i)&&(t.select("#"+i),t.select("#"+i).attr("transform","translate("+(e.node(i).x-e.node(i).width/2)+","+(e.node(i).y-e.node(i).height/2)+" )"))}))}(h,u),p.forEach((function(t){k(h,t,u,e,l)}));const T=R.rect_padding,N=h.node().getBBox(),x=N.width+2*T,A=N.height+2*T;(0,n.i)(h,A,x,R.useMaxWidth),h.attr("viewBox",`${N.x-T} ${N.y-T} ${x} ${A}`)}},styles:t=>`\n\n marker {\n fill: ${t.relationColor};\n stroke: ${t.relationColor};\n }\n\n marker.cross {\n stroke: ${t.lineColor};\n }\n\n svg {\n font-family: ${t.fontFamily};\n font-size: ${t.fontSize};\n }\n\n .reqBox {\n fill: ${t.requirementBackground};\n fill-opacity: 1.0;\n stroke: ${t.requirementBorderColor};\n stroke-width: ${t.requirementBorderSize};\n }\n \n .reqTitle, .reqLabel{\n fill: ${t.requirementTextColor};\n }\n .reqLabelBox {\n fill: ${t.relationLabelBackground};\n fill-opacity: 1.0;\n }\n\n .req-title-line {\n stroke: ${t.requirementBorderColor};\n stroke-width: ${t.requirementBorderSize};\n }\n .relationshipLine {\n stroke: ${t.relationColor};\n stroke-width: 1;\n }\n .relationshipLabel {\n fill: ${t.relationLabelColor};\n }\n\n`}}}]); \ No newline at end of file diff --git a/assets/js/96f8fd49.68f0f7ba.js b/assets/js/96f8fd49.68f0f7ba.js new file mode 100644 index 0000000000..c8c70ea8bf --- /dev/null +++ b/assets/js/96f8fd49.68f0f7ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[667],{43878:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>r,contentTitle:()=>l,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var s=o(74848),t=o(28453);const a={sidebar_label:"Logging"},l="Logging",i={id:"iaas/guides/operations-guide/manager/log",title:"Logging",description:"Ansible",source:"@site/docs/02-iaas/guides/operations-guide/manager/log.md",sourceDirName:"02-iaas/guides/operations-guide/manager",slug:"/iaas/guides/operations-guide/manager/log",permalink:"/docs/iaas/guides/operations-guide/manager/log",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/manager/log.md",tags:[],version:"current",frontMatter:{sidebar_label:"Logging"},sidebar:"docs",previous:{title:"Get",permalink:"/docs/iaas/guides/operations-guide/manager/get"},next:{title:"Task",permalink:"/docs/iaas/guides/operations-guide/manager/task"}},r={},c=[{value:"Ansible",id:"ansible",level:2},{value:"Files",id:"files",level:3},{value:"ARA - ARA Records Ansible",id:"ara---ara-records-ansible",level:3},{value:"Sample usage",id:"sample-usage",level:4},{value:"Container",id:"container",level:2},{value:"OpenSearch",id:"opensearch",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"logging",children:"Logging"}),"\n",(0,s.jsx)(n.h2,{id:"ansible",children:"Ansible"}),"\n",(0,s.jsx)(n.h3,{id:"files",children:"Files"}),"\n",(0,s.jsx)(n.p,{children:"Each Ansible service has its own local Ansible log file. These log files are not persistent. The ARA service is\nused for the persistence of Ansible logs. The log files can be used to view currently running Ansible Plays,\nfor example if they are running as a background task."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ docker exec -it osism-ansible tail -f /ansible/logs/ansible.log\n$ docker exec -it ceph-ansible tail -f /ansible/logs/ansible.log\n$ docker exec -it kolla-ansible tail -f /ansible/logs/ansible.log\n"})}),"\n",(0,s.jsx)(n.h3,{id:"ara---ara-records-ansible",children:"ARA - ARA Records Ansible"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ osism log ansible\n(ara) help\n\nDocumented commands (use 'help -v' for verbose/'help <topic>' for details):\n===========================================================================\nalias exit history quit run_script shell\nedit help macro run_pyscript set shortcuts\n\nApplication commands (type help <topic>):\n=========================================\ncomplete host metrics playbook delete record delete result show\nexpire host show playbook list record list task delete\nhelp play delete playbook metrics record show task list\nhost delete play list playbook prune result delete task metrics\nhost list play show playbook show result list task show\n"})}),"\n",(0,s.jsx)(n.h4,{id:"sample-usage",children:"Sample usage"}),"\n",(0,s.jsx)(n.p,{children:"As an example, the role common is run. Irrelevant parts of outputs have been removed."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ osism apply common\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ osism log ansible\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"(ara) play list\n+----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+\n| id | status | name | playbook | tasks | results | started | duration |\n+----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+\n| 69 | completed | Apply role common | 49 | 21 | 68 | 2023-09-30T10:14:01.731212Z | 00:00:38.238032 |\n+----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"(ara) play show 69\n+----------+------------------------------------------+\n| Field | Value |\n+----------+------------------------------------------+\n| id | 69 |\n| report | http://ara-server:8000/playbooks/49.html |\n| status | completed |\n| name | Apply role common |\n| playbook | (49) /ansible/kolla-common.yml |\n| started | 2023-09-30T10:14:01.731212Z |\n| ended | 2023-09-30T10:14:39.969244Z |\n| duration | 00:00:38.238032 |\n| items | {'tasks': 21, 'results': 68} |\n+----------+------------------------------------------+\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"(ara) task list\n+-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+\n| id | status | results | action | name | playbook | started | duration |\n+-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+\n| 910 | completed | 0 | meta | common : Flush handlers | 49 | 2023-09-30T10:14:37.126872Z | 00:00:02.552006 |\n| 909 | completed | 4 | file | common : Link kolla_logs volume to /var/log/kolla | 49 | 2023-09-30T10:14:35.502754Z | 00:00:01.039468 |\n| 908 | completed | 4 | kolla_docker | common : Creating log volume | 49 | 2023-09-30T10:14:34.134312Z | 00:00:01.076976 |\n| 907 | completed | 4 | kolla_docker | common : Check common containers | 49 | 2023-09-30T10:14:31.411916Z | 00:00:02.146165 |\n| 906 | completed | 4 | template | common : Copy rabbitmq erl_inetrc to kolla toolbox | 49 | 2023-09-30T10:14:29.500998Z | 00:00:01.327607 |\n| 905 | completed | 4 | template | common : Copy rabbitmq-env.conf to kolla toolbox | 49 | 2023-09-30T10:14:27.979869Z | 00:00:01.231630 |\n| 904 | completed | 4 | file | common : Ensuring config directories have correct owner and permission | 49 | 2023-09-30T10:14:26.422535Z | 00:00:01.263370 |\n| 903 | completed | 4 | template | common : Ensure RabbitMQ Erlang cookie exists | 49 | 2023-09-30T10:14:24.880329Z | 00:00:01.255475 |\n| 902 | completed | 4 | template | common : Copying over cron logrotate config file | 49 | 2023-09-30T10:14:23.199518Z | 00:00:01.392765 |\n| 901 | completed | 4 | template | common : Copying over td-agent.conf | 49 | 2023-09-30T10:14:21.085351Z | 00:00:01.826039 |\n| 900 | completed | 1 | find | common : Find custom fluentd output config files | 49 | 2023-09-30T10:14:19.859670Z | 00:00:00.939663 |\n| 899 | completed | 1 | find | common : Find custom fluentd format config files | 49 | 2023-09-30T10:14:18.711171Z | 00:00:00.858586 |\n| 898 | completed | 1 | find | common : Find custom fluentd filter config files | 49 | 2023-09-30T10:14:17.542234Z | 00:00:00.877270 |\n| 897 | completed | 1 | find | common : Find custom fluentd input config files | 49 | 2023-09-30T10:14:15.911699Z | 00:00:01.315217 |\n| 896 | completed | 4 | template | common : Copying over config.json files for services | 49 | 2023-09-30T10:14:13.588195Z | 00:00:02.031647 |\n| 895 | completed | 4 | copy | service-cert-copy : common | Copying over backend internal TLS key | 49 | 2023-09-30T10:14:12.216984Z | 00:00:01.074853 |\n| 894 | completed | 4 | copy | service-cert-copy : common | Copying over backend internal TLS certificate | 49 | 2023-09-30T10:14:10.895833Z | 00:00:01.022530 |\n| 893 | completed | 4 | copy | service-cert-copy : common | Copying over extra CA certificates | 49 | 2023-09-30T10:14:08.551850Z | 00:00:02.040932 |\n| 892 | completed | 4 | include_tasks | common : include_tasks | 49 | 2023-09-30T10:14:07.019883Z | 00:00:00.950605 |\n| 891 | completed | 4 | file | common : Ensuring config directories exist | 49 | 2023-09-30T10:14:04.801633Z | 00:00:01.926842 |\n| 890 | completed | 4 | include_tasks | common : include_tasks | 49 | 2023-09-30T10:14:03.054547Z | 00:00:01.166032 |\n+-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"(ara) task show 910\n+----------+------------------------------------------+\n| Field | Value |\n+----------+------------------------------------------+\n| id | 910 |\n| uuid | 0242ac1f-6510-3867-9eea-00000000004f |\n| report | http://ara-server:8000/playbooks/49.html |\n| name | common : Flush handlers |\n| action | meta |\n| status | completed |\n| path | /ansible/roles/common/tasks/deploy.yml |\n| lineno | 8 |\n| started | 2023-09-30T10:14:37.126872Z |\n| ended | 2023-09-30T10:14:39.678878Z |\n| duration | 00:00:02.552006 |\n| tags | ['common'] |\n| handler | False |\n+----------+------------------------------------------+\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"(ara) playbook list\n+----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+\n| id | status | controller | user | ansible_version | path | tasks | results | hosts | started | duration |\n+----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+\n| 49 | completed | kolla-ansible.manager_default | dragon | 2.14.10 | /ansible/kolla-common.yml | 21 | 68 | 5 | 2023-09-30T10:14:01.410334Z | 00:00:39.135309 |\n+----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"(ara) playbook metrics\n+---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+\n| aggregate | count | duration_total | duration_avg | tasks | results | hosts | completed | failed | running |\n+---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+\n| /ansible/kolla-common.yml | 2 | 0:02:53.934432 | 0:01:26.967216 | 46 | 152 | 10 | 2 | 0 | 0 |\n+---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"(ara) host list\n+-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+\n| id | name | playbook | changed | failed | ok | skipped | unreachable | updated |\n+-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+\n| 164 | testbed-node-2.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.543599Z |\n| 161 | testbed-manager.testbed.osism.xyz | 49 | 0 | 0 | 18 | 2 | 0 | 2023-09-30T10:14:40.283581Z |\n| 163 | testbed-node-1.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.280601Z |\n| 162 | testbed-node-0.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.279181Z |\n| 165 | kolla-ansible.manager_default | 49 | 0 | 0 | 0 | 0 | 0 | 2023-09-30T10:14:16.932135Z |\n+-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"(ara) host show 164\n+-------------+------------------------------------------+\n| Field | Value |\n+-------------+------------------------------------------+\n| id | 164 |\n| report | http://ara-server:8000/playbooks/49.html |\n| name | testbed-node-2.testbed.osism.xyz |\n| changed | 0 |\n| failed | 0 |\n| ok | 14 |\n| skipped | 2 |\n| unreachable | 0 |\n| updated | 2023-09-30T10:14:40.543599Z |\n+-------------+------------------------------------------+\n"})}),"\n",(0,s.jsx)(n.h2,{id:"container",children:"Container"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ osism log container testbed-node-0 horizon\n[...]\n++++ APACHE_LOCK_DIR=/var/lock/apache2\n++++ export APACHE_LOG_DIR=/var/log/apache2\n++++ APACHE_LOG_DIR=/var/log/apache2\n++++ export LANG=C\n++++ LANG=C\n++++ export LANG\n+++ install -d /var/run/apache2/\n+++ rm -rf '/var/run/apache2/*'\n+++ [[ ubuntu =~ centos|rocky ]]\n+ echo 'Running command: '\\''/usr/sbin/apache2 -DFOREGROUND'\\'''\n+ exec /usr/sbin/apache2 -DFOREGROUND\nAH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.16.10. Set the 'ServerName' directive globally to suppress this message\n"})}),"\n",(0,s.jsx)(n.h2,{id:"opensearch",children:"OpenSearch"}),"\n",(0,s.jsxs)(n.p,{children:["OpenSearch can be queried with ",(0,s.jsx)(n.a,{href:"https://opensearch.org/docs/latest/search-plugins/sql/sql/index/",children:"SQL"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ osism log opensearch\n>>> SELECT * FROM flog-2023.10.31 LIMIT 1;\nOct 31 10:45:36 testbed-node-0 docker[847573]: cluster 2023-10-31T10:45:35.498718+0000 mgr.testbed-node-0 (mgr.5184) 24194 : cluster [DBG] pgmap v24196: 321 pgs: 321 active+clean; 577 KiB data, 270 MiB used, 60 GiB / 60 GiB avail\n\n>>> SELECT * FROM flog-2023.10.31 LIMIT 5;\nOct 31 11:19:57 testbed-node-2 docker[880827]: 2023-10-31T11:19:57.650+0000 7fa7e7c88700 0 [dashboard INFO root] Redirecting to active 'http://192.168.16.10:7000/'\nOct 31 11:19:57 testbed-node-2 docker[880827]: 2023-10-31T11:19:57.650+0000 7fa7e7c88700 0 [dashboard INFO request] [::ffff:192.168.16.11:56210] [OPTIONS] [302] [0.001s] [105.0B] [8a69cc7a-23db-410b-b744-cc5689cb4f4c] /\nOct 31 11:19:58 testbed-node-2 docker[844686]: cluster 2023-10-31T11:19:56.329684+0000 mgr.testbed-node-0 (mgr.5184) 25224 : cluster [DBG] pgmap v25226: 321 pgs: 321 active+clean; 577 KiB data, 270 MiB used, 60 GiB / 60 GiB avail\nOct 31 11:19:58 testbed-node-2 docker[844686]: debug 2023-10-31T11:19:58.566+0000 7fdbc9728700 1 mon.testbed-node-2@2(peon).osd e74 _set_new_cache_sizes cache_size:1020054731 inc_alloc: 348127232 full_alloc: 348127232 kv_alloc: 322961408\nOct 31 11:19:58 testbed-node-2 docker[880827]: 2023-10-31T11:19:58.710+0000 7fa7eb48f700 0 [dashboard INFO root] Redirecting to active 'http://192.168.16.10:7000/'\n\n>>> SELECT * FROM flog-2023.10.31 WHERE Hostname = 'testbed-node-0' LIMIT 5\nPATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29\nREQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27\nSCRIPT_NAME: `` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:28\n192.168.16.10 - - [31/Oct/2023 10:57:33] \"GET / HTTP/1.1\" 300 1761 0.001253\n(1039) accepted ('192.168.16.10', 58732) server /var/lib/kolla/venv/lib/python3.10/site-packages/eventlet/wsgi.py:1004\n\n>>> SELECT * FROM flog-2023.10.31 WHERE Hostname = 'testbed-node-0' AND programname = 'keystone' LIMIT 5\nPATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29\nREQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27\nSCRIPT_NAME: `` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:28\nPATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29\nREQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27\n"})})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>l,x:()=>i});var s=o(96540);const t={},a=s.createContext(t);function l(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/97630173.b98d5be3.js b/assets/js/97630173.b98d5be3.js new file mode 100644 index 0000000000..9d37223151 --- /dev/null +++ b/assets/js/97630173.b98d5be3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8533],{85102:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>r,toc:()=>c});var o=i(74848),t=i(28453);const a={},s="Proxmox VE",r={id:"iaas/guides/concept-guide/components/proxmox",title:"Proxmox VE",description:"Proxmox Virtual Environment (Proxmox VE) is an open-source server virtualization management",source:"@site/docs/02-iaas/guides/concept-guide/components/proxmox.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/proxmox",permalink:"/docs/iaas/guides/concept-guide/components/proxmox",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/proxmox.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Prometheus & Grafana",permalink:"/docs/iaas/guides/concept-guide/components/prometheus"},next:{title:"SONiC & OVN",permalink:"/docs/iaas/guides/concept-guide/components/sonic"}},l={},c=[{value:"Lifecycle Management of Proxmox VE in OSISM",id:"lifecycle-management-of-proxmox-ve-in-osism",level:2}];function d(e){const n={h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"proxmox-ve",children:"Proxmox VE"}),"\n",(0,o.jsx)(n.p,{children:"Proxmox Virtual Environment (Proxmox VE) is an open-source server virtualization management\nplatform designed to manage virtual machines (VMs), containers, and software-defined storage.\nLeveraging the power of KVM (Kernel-based Virtual Machine) for full virtualization and LXC\n(Linux Containers) for containerization, Proxmox VE provides a robust and flexible solution\nfor enterprise virtualization needs."}),"\n",(0,o.jsx)(n.p,{children:"Key benefits of Proxmox VE:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Comprehensive Virtualization:","\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"KVM Virtual Machines: Proxmox VE supports KVM-based virtualization, allowing users to run\nmultiple, isolated VMs on a single physical server. KVM provides near-native performance\nand supports various operating systems, including Windows, Linux, and BSD."}),"\n",(0,o.jsx)(n.li,{children:"LXC Containers: For lightweight virtualization, Proxmox VE uses LXC containers, which share\nthe host\u2019s kernel but maintain isolated user spaces. This approach is ideal for runningx\nLinux-based applications with minimal overhead."}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.li,{children:"Integrated Management Interface: Proxmox VE includes a web-based management interface, enabling\nadministrators to manage VMs, containers, storage, and network configurations from a single,\nintuitive dashboard. This interface supports various administrative tasks, including VM creation,\nbackup scheduling, and live migration."}),"\n",(0,o.jsx)(n.li,{children:"High Availability (HA) and Clustering: Proxmox VE supports clustering, allowing multiple Proxmox\nservers to be managed as a single entity. Clustering facilitates high availability by automatically\nrestarting VMs or containers on other nodes in the event of hardware failure, ensuring minimal downtime."}),"\n",(0,o.jsx)(n.li,{children:"Storage Options: Proxmox VE offers flexible storage management with support for local storage,\nshared storage (NFS, iSCSI, Ceph), and distributed storage systems. The built-in Proxmox VE storage\nreplication feature ensures data redundancy and high availability."}),"\n",(0,o.jsx)(n.li,{children:"Backup and Restore: Proxmox VE includes integrated backup tools, supporting scheduled backups of VMs\nand containers. These backups can be stored locally or on remote storage solutions, and can be restored\neasily via the management interface."}),"\n",(0,o.jsx)(n.li,{children:"Networking: Proxmox VE supports advanced networking features, including VLANs, bridges, and bonding.\nThis allows for complex network topologies and efficient use of network resources. The platform also\nintegrates seamlessly with SDN (Software-Defined Networking) solutions for enhanced network management."}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"By using Proxmox VE, organizations can leverage a powerful, open-source virtualization platform\nthat combines the benefits of both KVM and LXC. Proxmox VE\u2019s comprehensive feature set,\nintuitive management interface, and robust high availability options make it an ideal choice for\nmanaging virtualized environments efficiently and effectively."}),"\n",(0,o.jsx)(n.h2,{id:"lifecycle-management-of-proxmox-ve-in-osism",children:"Lifecycle Management of Proxmox VE in OSISM"})]})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>s,x:()=>r});var o=i(96540);const t={},a=o.createContext(t);function s(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/97b1504a.eb7eeb20.js b/assets/js/97b1504a.eb7eeb20.js new file mode 100644 index 0000000000..4b58a4b657 --- /dev/null +++ b/assets/js/97b1504a.eb7eeb20.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4346],{1583:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>o});var n=t(74848),a=t(28453);const r={},d="scs-0104: SCS Standard Images",i={id:"iaas/scs-0104",title:"scs-0104: SCS Standard Images",description:"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,",source:"@site/standards/iaas/scs-0104.md",sourceDirName:"iaas",slug:"/iaas/scs-0104",permalink:"/standards/iaas/scs-0104",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"SCS Standard Flavors and Properties",permalink:"/standards/scs-0103-v1-standard-flavors"},next:{title:"SCS Standard Images",permalink:"/standards/scs-0104-v1-standard-images"}},c={},o=[];function l(e){const s={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"scs-0104-scs-standard-images",children:"scs-0104: SCS Standard Images"}),"\n",(0,n.jsx)(s.p,{children:"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,\nspecifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined\ndeployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard's\nmachine-readable document facilitates automated processing for compliance and integration purposes, promoting\nconsistency and reliability in cloud environments."}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Version"}),(0,n.jsx)(s.th,{children:"Type"}),(0,n.jsx)(s.th,{children:"State"}),(0,n.jsx)(s.th,{children:"stabilized"}),(0,n.jsx)(s.th,{children:"deprecated"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/standards/scs-0104-v1-standard-images",children:"scs-0104-v1"})}),(0,n.jsx)(s.td,{children:"Standard"}),(0,n.jsx)(s.td,{children:"Stable"}),(0,n.jsx)(s.td,{children:"2024-02-21"}),(0,n.jsx)(s.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>d,x:()=>i});var n=t(96540);const a={},r=n.createContext(a);function d(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/97ef9758.97b043ea.js b/assets/js/97ef9758.97b043ea.js new file mode 100644 index 0000000000..6350f1f998 --- /dev/null +++ b/assets/js/97ef9758.97b043ea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6529],{66034:(t,e,a)=>{a.r(e),a.d(e,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>m});var n=a(74848),o=a(28453);const r={},i="Team Iaas",s={id:"collaboration/team-iaas",title:"Team Iaas",description:"We build the reference implementation of the IaaS parts of SCS that informs and adheres to the SCS IaaS standards.",source:"@site/community/collaboration/team-iaas.md",sourceDirName:"collaboration",slug:"/collaboration/team-iaas",permalink:"/community/collaboration/team-iaas",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Collaboration",permalink:"/community/collaboration/"},next:{title:"Team IAM",permalink:"/community/collaboration/team-iam"}},c={},m=[];function l(t){const e={h1:"h1",p:"p",...(0,o.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"team-iaas",children:"Team Iaas"}),"\n",(0,n.jsx)(e.p,{children:"We build the reference implementation of the IaaS parts of SCS that informs and adheres to the SCS IaaS standards."})]})}function u(t={}){const{wrapper:e}={...(0,o.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(l,{...t})}):l(t)}},28453:(t,e,a)=>{a.d(e,{R:()=>i,x:()=>s});var n=a(96540);const o={},r=n.createContext(o);function i(t){const e=n.useContext(r);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(o):t.components||o:i(t.components),n.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/9890ac63.5c6d014d.js b/assets/js/9890ac63.5c6d014d.js new file mode 100644 index 0000000000..fb6996c425 --- /dev/null +++ b/assets/js/9890ac63.5c6d014d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1298],{74355:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>d});var n=s(74848),i=s(28453);const c={},r="scs-0004: Regulations for achieving SCS-compatible certification",a={id:"global/scs-0004",title:"scs-0004: Regulations for achieving SCS-compatible certification",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/global/scs-0004.md",sourceDirName:"global",slug:"/global/scs-0004",permalink:"/standards/global/scs-0004",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Sovereign Cloud Standards YAML",permalink:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml"},next:{title:"Regulations for achieving SCS-compatible certification",permalink:"/standards/scs-0004-v1-achieving-certification"}},o={},d=[];function l(t){const e={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"scs-0004-regulations-for-achieving-scs-compatible-certification",children:"scs-0004: Regulations for achieving SCS-compatible certification"}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:"Version"}),(0,n.jsx)(e.th,{children:"Type"}),(0,n.jsx)(e.th,{children:"State"}),(0,n.jsx)(e.th,{children:"stabilized"}),(0,n.jsx)(e.th,{children:"deprecated"})]})}),(0,n.jsx)(e.tbody,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0004-v1-achieving-certification",children:"scs-0004-v1"})}),(0,n.jsx)(e.td,{children:"Procedural"}),(0,n.jsx)(e.td,{children:"Draft"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]})})]})]})}function h(t={}){const{wrapper:e}={...(0,i.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(l,{...t})}):l(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>r,x:()=>a});var n=s(96540);const i={},c=n.createContext(i);function r(t){const e=n.useContext(c);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:r(t.components),n.createElement(c.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/99b53e63.822f2b46.js b/assets/js/99b53e63.822f2b46.js new file mode 100644 index 0000000000..681b43c133 --- /dev/null +++ b/assets/js/99b53e63.822f2b46.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9579],{75861:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>p,toc:()=>c});var s=n(74848),o=n(28453);const a={},i="Components",p={id:"operating-scs/components/status-page/docs/components",title:"Components",description:'Illustrating multiple interchangable logical "layers" of possible Status Page application stacks:',source:"@site/docs/04-operating-scs/components/status-page/docs/components.md",sourceDirName:"04-operating-scs/components/status-page/docs",slug:"/operating-scs/components/status-page/docs/components",permalink:"/docs/operating-scs/components/status-page/docs/components",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page/docs/components.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Component Overview",permalink:"/docs/operating-scs/components/status-page/docs/component_overview"},next:{title:'"Levels of consensus"',permalink:"/docs/operating-scs/components/status-page/docs/levels_of_consensus"}},r={},c=[];function l(e){const t={h1:"h1",mermaid:"mermaid",p:"p",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"components",children:"Components"}),"\n",(0,s.jsx)(t.p,{children:'Illustrating multiple interchangable logical "layers" of possible Status Page application stacks:'}),"\n",(0,s.jsx)(t.mermaid,{value:' C4Container\n title SCS Status Page components\n UpdateLayoutConfig("100", "1")\n Boundary(b4, "Application layer") {\n Container(app1, "Flask App", "OAuth2 impl. etc.")\n Container(app2, "Vue App", "OAuth2 impl. etc.")\n Container(app3, "CLI Client", "CLI Client")\n }\n Boundary(b3, "Policy layer") {\n Container(policy1, "istio end-user auth", "")\n Container(policy2, "custom auth proxy", "")\n Container(policy3, "Caddy", "")\n }\n Boundary(b2, "API server layer") {\n Container(api1, "API Server (Go)", "")\n Container(api2, "API Server (Python)", "")\n Container(api3, "API Server (Go)", "")\n }\n Boundary(b1, "Database layer") {\n Container(db1, "postgres", "")\n Container(db2, "mysql", "")\n Container(db3, "github", "Github Projects API")\n }\n Rel(api1, db1, "Uses", "Postgres protocol")\n Rel(api2, db2, "Uses", "MySQL protocol")\n Rel(api3, db3, "Uses", "GraphQL API")\n Rel(policy1, api1, "Relays", "SCS Status Page API")\n Rel(policy2, api2, "Relays", "SCS Status Page API")\n Rel(policy3, api3, "Relays", "SCS Status Page API")\n Rel(app1, policy1, "Requests", "SCS Status Page API + Auth")\n Rel(app2, policy2, "Requests", "SCS Status Page API + Auth")\n Rel(app3, policy3, "Requests", "SCS Status Page API + Auth")'}),"\n",(0,s.jsx)(t.p,{children:"Note that not everything that is shown here, actually exists or was tested. It is just shown for illustration purposes."})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>p});var s=n(96540);const o={},a=s.createContext(o);function i(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function p(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9a7c0197.dc6369a8.js b/assets/js/9a7c0197.dc6369a8.js new file mode 100644 index 0000000000..b6883585a9 --- /dev/null +++ b/assets/js/9a7c0197.dc6369a8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3402],{41705:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var o=n(74848),i=n(28453);const s={title:"Identity Federation in SCS",type:null,status:"Draft",track:"Global"},a=void 0,r={id:"operations/iam/identity-federation-in-scs",title:"Identity Federation in SCS",description:"SovereignCloudStack wants to make it possible for operators to delegate",source:"@site/contributor-docs/operations/iam/identity-federation-in-scs.md",sourceDirName:"operations/iam",slug:"/operations/iam/identity-federation-in-scs",permalink:"/contributor-docs/operations/iam/identity-federation-in-scs",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Identity Federation in SCS",type:null,status:"Draft",track:"Global"},sidebar:"devDocs",previous:{title:"Documentation for SCS Contributors",permalink:"/contributor-docs/"},next:{title:"OpenStack Federation via OpenID-Connect",permalink:"/contributor-docs/operations/iam/openstack-federation-via-oidc"}},c={},d=[{value:"1. IaaS / OpenStack",id:"1-iaas--openstack",level:2},{value:"2. CaaS",id:"2-caas",level:2}];function l(e){const t={a:"a",h2:"h2",p:"p",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.p,{children:"SovereignCloudStack wants to make it possible for operators to delegate\nadministration of user identities to the organizational entities that the\nusers are part of. Usually that's customer organizations but it could also\nbe the operator itself. Federation protocols like OpenID Connect can be used\nto achieve that goal. To simplify connecting the different parts of SCS\nto customer owned IAM solutions, SCS deploys Keycloak as central Identity\nProvider (IdP) service."}),"\n",(0,o.jsxs)(t.p,{children:["Currently this is deployed automatically only in the ",(0,o.jsx)(t.a,{href:"https://docs.scs.community/docs/iaas/guides/deploy-guide/examples/testbed/",children:"osism/testbed"}),",\nwhich provides ",(0,o.jsx)(t.a,{href:"https://docs.scs.community/docs/iaas/guides/deploy-guide/examples/testbed#authentication-with-oidc",children:"its own documentation for authentication with OIDC"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"The following sections describe how this is done."}),"\n",(0,o.jsx)(t.h2,{id:"1-iaas--openstack",children:"1. IaaS / OpenStack"}),"\n",(0,o.jsxs)(t.p,{children:["To provide Infrastrucure as a Service SCS builds upon\nOpenStack. See section ",(0,o.jsx)(t.a,{href:"https://docs.scs.community/dev-docs/operations/iam/openstack-federation-via-oidc",children:"OpenStack Federation via OpenID-Connect"}),"\nfor more details on identity federation for OpenStack."]}),"\n",(0,o.jsx)(t.h2,{id:"2-caas",children:"2. CaaS"}),"\n",(0,o.jsxs)(t.p,{children:["To provide Container as a Service SCS builds upon\nKubernetes. There is\n",(0,o.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/issues/issues/373",children:"work in progress"}),"\nto optionally connect Kubernetes to Keycloak and to\nmap authorization decisions based on claims via cluster role bindings."]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var o=n(96540);const i={},s=o.createContext(i);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9b5d9131.f81de50f.js b/assets/js/9b5d9131.f81de50f.js new file mode 100644 index 0000000000..eb13c9e510 --- /dev/null +++ b/assets/js/9b5d9131.f81de50f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1427],{53321:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>o,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var a=t(74848),s=t(28453);const i={},r="Central API MVP",c={id:"operating-scs/components/central-api/poc-setup",title:"Central API MVP",description:"Right now, this repository implements issue 374.",source:"@site/docs/04-operating-scs/components/central-api/poc-setup.md",sourceDirName:"04-operating-scs/components/central-api",slug:"/operating-scs/components/central-api/poc-setup",permalink:"/docs/operating-scs/components/central-api/poc-setup",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/central-api/poc-setup.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Overview",permalink:"/docs/operating-scs/components/central-api/overview"},next:{title:"Automated Pentesting",permalink:"/docs/category/automated-pentesting"}},o={},l=[{value:"Quick Start",id:"quick-start",level:2}];function p(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...n.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.h1,{id:"central-api-mvp",children:"Central API MVP"}),"\n",(0,a.jsxs)(e.p,{children:["Right now, this repository implements ",(0,a.jsx)(e.a,{href:"https://github.com/SovereignCloudStack/issues/issues/374",children:"issue 374"}),".\nIt contains a script (",(0,a.jsx)(e.code,{children:"gen.py"}),") to mirror all crossplane openstack provider cluster-scoped resources to namespaced resources in an SCS API group."]}),"\n",(0,a.jsxs)(e.p,{children:["Also, these instructions are striving to implement ",(0,a.jsx)(e.a,{href:"https://docs.crossplane.io/knowledge-base/guides/multi-tenant/#namespaces-as-an-isolation-mechanism",children:"namespaces as isolation mechanism"})," to implement a multi-tenant system backed by a single Kubernetes cluster."]}),"\n",(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.a,{href:"https://github.com/crossplane-contrib/x-generation",children:"crossplane-contrib/x-generation"})," might be used as soon as ",(0,a.jsx)(e.a,{href:"https://github.com/crossplane-contrib/x-generation/issues/21",children:"the required feature for namespace mapping"})," is implemented."]}),"\n",(0,a.jsx)(e.h2,{id:"quick-start",children:"Quick Start"}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsx)(e.li,{children:"Setup testing Kubernetes cluster"}),"\n",(0,a.jsx)(e.li,{children:"Install crossplane"}),"\n",(0,a.jsxs)(e.li,{children:["Install openstack provider (See ",(0,a.jsx)(e.code,{children:"provider.yaml"}),")"]}),"\n",(0,a.jsxs)(e.li,{children:["Mirror openstack resources (See ",(0,a.jsx)(e.code,{children:"gen.py"}),")"]}),"\n",(0,a.jsxs)(e.li,{children:["Setup provider config (wearing CSP hat)","\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-yaml",children:'apiVersion: v1\nkind: Namespace\nmetadata:\n name: tenant-name\n---\napiVersion: openstack.upbound.io/v1beta1\nkind: ProviderConfig\nmetadata:\n name: tenant-name\nspec:\n credentials:\n secretRef:\n namespace: crossplane-system\n name: tenant-name-clouds-yaml\n key: clouds.json\n source: Secret\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: tenant-name-clouds-yaml\n namespace: crossplane-system\nstringData:\n clouds.json: |\n {\n "auth_url": "https://api.gx-scs.sovereignit.cloud:5000",\n "application_credential_id": "...",\n "application_credential_secret": "...",\n "tenant_name": "tenant-name"\n }\n'})}),"\n"]}),"\n",(0,a.jsxs)(e.li,{children:["Setup RBAC for tenants (wearing CSP hat)","\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-yaml",children:"apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n name: tenant\nrules:\n- apiGroups:\n - api.scs.community\n resources:\n - '*'\n verbs:\n - '*'\n---\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: tenant\n namespace: tenant-name\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n name: scs-bind\n namespace: tenant-name\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: tenant\nsubjects:\n- kind: ServiceAccount\n name: tenant\n namespace: tenant-name\n"})}),"\n"]}),"\n",(0,a.jsxs)(e.li,{children:["Create resource (wearing tenant hat, ",(0,a.jsx)(e.code,{children:"kubectl --as system:serviceaccount:tenant-name:tenant -n tenant-name"}),")","\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-yaml",children:"apiVersion: api.scs.community/v1alpha1\nkind: KeypairV2\nmetadata:\n name: admin\n namespace: tenant-name\nspec:\n name: admin-keypair\n publicKey: |-\n ssh-rsa ...\n---\napiVersion: api.scs.community/v1alpha1\nkind: InstanceV2\nmetadata:\n name: testing-vm\n namespace: tenant-name\nspec:\n name: testing-vm\n keyPair: admin-keyPair\n imageName: 'Debian 12'\n flavorName: 'SCS-1V:1:20'\n"})}),"\n"]}),"\n",(0,a.jsx)(e.li,{children:"Observe creation of resources"}),"\n"]}),"\n",(0,a.jsxs)(e.p,{children:["Right now, it would be expected to hand out the ",(0,a.jsx)(e.code,{children:"ServiceAccount"})," token to the actual tenant; When AuthN is done via OIDC (or other means), the ",(0,a.jsx)(e.code,{children:"ServiceAccount"})," ",(0,a.jsx)(e.code,{children:"tenant-name/tenant"})," may be dropped and ",(0,a.jsx)(e.code,{children:"RoleBinding"})," ",(0,a.jsx)(e.code,{children:"tenant-name/scs-bind"})," may point to an actual user/group."]})]})}function d(n={}){const{wrapper:e}={...(0,s.R)(),...n.components};return e?(0,a.jsx)(e,{...n,children:(0,a.jsx)(p,{...n})}):p(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>r,x:()=>c});var a=t(96540);const s={},i=a.createContext(s);function r(n){const e=a.useContext(i);return a.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(s):n.components||s:r(n.components),a.createElement(i.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/9d1324c7.ef1eeb3a.js b/assets/js/9d1324c7.ef1eeb3a.js new file mode 100644 index 0000000000..0682b3cc3a --- /dev/null +++ b/assets/js/9d1324c7.ef1eeb3a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6568],{88862:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>t,metadata:()=>l,toc:()=>a});var i=s(74848),r=s(28453);const t={title:"SCS Flavor Naming Standard",version:"2022-09-08-002",authors:"Matthias Hamm, Kurt Garloff, Tim Beermann",type:"Standard",track:"IaaS",status:"Deprecated",state:"v1.1 (for R3)",stabilized_at:new Date("2022-09-08T00:00:00.000Z"),deprecated_at:new Date("2023-10-31T00:00:00.000Z")},d=void 0,l={id:"scs-0100-v1-flavor-naming",title:"SCS Flavor Naming Standard",description:"Introduction",source:"@site/standards/scs-0100-v1-flavor-naming.md",sourceDirName:".",slug:"/scs-0100-v1-flavor-naming",permalink:"/standards/scs-0100-v1-flavor-naming",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS Flavor Naming Standard",version:"2022-09-08-002",authors:"Matthias Hamm, Kurt Garloff, Tim Beermann",type:"Standard",track:"IaaS",status:"Deprecated",state:"v1.1 (for R3)",stabilized_at:"2022-09-08T00:00:00.000Z",deprecated_at:"2023-10-31T00:00:00.000Z"},sidebar:"standards",previous:{title:"scs-0100: SCS Flavor Naming Standard",permalink:"/standards/iaas/scs-0100"},next:{title:"SCS Flavor Naming Standard",permalink:"/standards/scs-0100-v2-flavor-naming"}},o={},a=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Proposal",id:"proposal",level:2},{value:"Type of information included",id:"type-of-information-included",level:3},{value:"Complete Proposal",id:"complete-proposal",level:3},{value:"Proposal Details",id:"proposal-details",level:2},{value:"[REQUIRED] CPU Suffixes",id:"required-cpu-suffixes",level:3},{value:"Baseline",id:"baseline",level:4},{value:"Higher oversubscription",id:"higher-oversubscription",level:4},{value:"Insufficient microcode",id:"insufficient-microcode",level:4},{value:"Examples",id:"examples",level:4},{value:"[REQUIRED] Memory",id:"required-memory",level:3},{value:"Baseline",id:"baseline-1",level:4},{value:"No ECC",id:"no-ecc",level:4},{value:"Enabled Oversubscription",id:"enabled-oversubscription",level:4},{value:"Examples",id:"examples-1",level:4},{value:"[OPTIONAL] Disk sizes and types",id:"optional-disk-sizes-and-types",level:3},{value:"Baseline",id:"baseline-2",level:4},{value:"Multi-provisioned Disk",id:"multi-provisioned-disk",level:4},{value:"Examples",id:"examples-2",level:4},{value:"[OPTIONAL] Hypervisor",id:"optional-hypervisor",level:3},{value:"Examples",id:"examples-3",level:4},{value:"[OPTIONAL] Hardware virtualization / Nested virtualization",id:"optional-hardware-virtualization--nested-virtualization",level:3},{value:"Examples",id:"examples-4",level:4},{value:"[OPTIONAL] CPU Architecture Details",id:"optional-cpu-architecture-details",level:3},{value:"Generation and Vendor",id:"generation-and-vendor",level:4},{value:"Frequency Suffixes",id:"frequency-suffixes",level:4},{value:"Examples",id:"examples-5",level:4},{value:"[OPTIONAL] Extra features",id:"optional-extra-features",level:3},{value:"Proposal Examples",id:"proposal-examples",level:2},{value:"Standard SCS flavors",id:"standard-scs-flavors",level:2},{value:"Naming policies",id:"naming-policies",level:2},{value:"Rationale",id:"rationale",level:3},{value:"Validation",id:"validation",level:2},{value:"Beyond SCS: Gaia-X",id:"beyond-scs-gaia-x",level:2}];function c(e){const n={a:"a",code:"code",del:"del",div:"div",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"This is the standard v1.0 for SCS Release 0.\nNote that we intend to only extend it (so it's always backwards compatible),\nbut try to avoid changing in incompatible ways."}),"\n",(0,i.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(n.p,{children:"In OpenStack environments there is a need to define different flavors for instances.\nThe flavors are pre-defined by the operator, the customer can not change these.\nOpenStack providers thus typically offer a large selection of flavors."}),"\n",(0,i.jsxs)(n.p,{children:["While flavors can be discovered (",(0,i.jsx)(n.code,{children:"openstack flavor list"}),"), it is helpful for users (DevOps teams),\nto have"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere."}),"\n",(0,i.jsx)(n.li,{children:"Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"While not all details will be encoded in the name, the key features should be obvious:\nNumber of vCPUs, RAM, Root Disk.\nExtra features are important as well: There will be flavors with GPU support, fast disks for databases,\nmemory-heavy applications, and other useful aspects of an instance."}),"\n",(0,i.jsx)(n.p,{children:"It may also be important to make the CPU generation clearly recognisable, as this is always a topic in\ndiscussions with customers."}),"\n",(0,i.jsx)(n.h2,{id:"proposal",children:"Proposal"}),"\n",(0,i.jsx)(n.h3,{id:"type-of-information-included",children:"Type of information included"}),"\n",(0,i.jsx)(n.p,{children:"We believe the following characteristics are important in a flavour description:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Type"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Generation"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"CPU Generation"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Number of CPU"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Number of vCPUs - suffixed by L,V,T,C (see below)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Amount of RAM"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Amount of memory available for the VM"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Performance Class"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Ability to label high-performance CPUs, disks, network"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"CPU Type"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"X86-intel, X86-amd, ARM, RISC-V, Generic"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:'"bms"'}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Bare Metal System (no virtualization/hypervisor)"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"complete-proposal",children:"Complete Proposal"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Prefix"}),(0,i.jsx)(n.th,{children:"CPU"}),(0,i.jsx)(n.th,{children:"Suffix"}),(0,i.jsx)(n.th,{children:"RAM[GiB]"}),(0,i.jsx)(n.th,{children:"optional: Disk[GB]"}),(0,i.jsx)(n.th,{children:"optional: Disk type"}),(0,i.jsx)(n.th,{children:"optional: extra features"})]})}),(0,i.jsx)(n.tbody,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"SCS-"})}),(0,i.jsx)(n.td,{children:"N"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"L/V/T/C[i]"})}),(0,i.jsxs)(n.td,{children:[":N",(0,i.jsx)(n.code,{children:"[u][o]"})]}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"[:["}),"M",(0,i.jsx)(n.code,{children:"x]"}),"N",(0,i.jsx)(n.code,{children:"]"})]}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"[n/s/l/p]"})}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"[-"}),"hyp",(0,i.jsx)(n.code,{children:"][-hwv]-["}),"arch",(0,i.jsx)(n.code,{children:"["}),"N",(0,i.jsx)(n.code,{children:"][h][-[G/g]"}),"X",(0,i.jsx)(n.code,{children:"["}),"N",(0,i.jsx)(n.code,{children:"][:"}),"M",(0,i.jsx)(n.code,{children:"[h]]][-ib]"})]})]})})]}),"\n",(0,i.jsx)(n.p,{children:"(Note that N and M are placeholders for numbers here)."}),"\n",(0,i.jsx)(n.h2,{id:"proposal-details",children:"Proposal Details"}),"\n",(0,i.jsx)(n.h3,{id:"required-cpu-suffixes",children:"[REQUIRED] CPU Suffixes"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Suffix"}),(0,i.jsx)(n.th,{children:"Meaning"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"C"}),(0,i.jsx)(n.td,{children:"dedicated Core"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"T"}),(0,i.jsx)(n.td,{children:"dedicated Thread (SMT)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V"}),(0,i.jsx)(n.td,{children:"vCPU (oversubscribed)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"L"}),(0,i.jsx)(n.td,{children:"vCPU (heavily oversubscribed)"})]})]})]}),"\n",(0,i.jsx)(n.h4,{id:"baseline",children:"Baseline"}),"\n",(0,i.jsxs)(n.p,{children:["Note that vCPU oversubscription for a ",(0,i.jsx)(n.code,{children:"V"})," vCPU should be implemented such, that we\ncan guarantee ",(0,i.jsx)(n.code,{children:"at least 20% of a core in >99% of the time"}),"; this can be achieved by\nlimiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled)\nor by more advanced workload management logic. Otherwise ",(0,i.jsx)(n.code,{children:"L"})," (low performance) must be\nused. The >99% is measured over a month (1% is 7.2h/month)."]}),"\n",(0,i.jsxs)(n.p,{children:["Note that CPUs must use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.).\nWe expect that microcode gets updated within less than a month of a new release; for CVSS scores above 8,\nwe expect less than a week.\nThe provider must enable at least all mitigations that are enabled by default in the Linux kernel. CPUs that\nare susceptible to L1TF (intel x86 pre Cascade Lake) must switch off hyperthreading OR (in the future)\nuse core scheduling implementations that are deemed to be secure by the SCS security team, or declare themselves\nas insecure with the ",(0,i.jsx)(n.code,{children:"i"})," suffix (see below)."]}),"\n",(0,i.jsx)(n.h4,{id:"higher-oversubscription",children:"Higher oversubscription"}),"\n",(0,i.jsxs)(n.p,{children:["Must be indicated with a ",(0,i.jsx)(n.code,{children:"L"})," vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and\nthe lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month)."]}),"\n",(0,i.jsx)(n.h4,{id:"insufficient-microcode",children:"Insufficient microcode"}),"\n",(0,i.jsxs)(n.p,{children:["Not using these mitigations must be indicated by an additional ",(0,i.jsx)(n.code,{children:"i suffix"})," for insecure\n(weak protection against CPU vulns through insufficient microcode, lack of disabled hyperthreading\non L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor)."]}),"\n",(0,i.jsx)(n.h4,{id:"examples",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2C"}),":4:10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2T"}),":4:10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2V"}),":4:10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2L"}),":4:10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2Li"}),":4:10n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2"}),":**4:10n"]})," - CPU suffix missing"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2iT"}),":4:10n"]})," - This order is forbidden"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"required-memory",children:"[REQUIRED] Memory"}),"\n",(0,i.jsx)(n.h4,{id:"baseline-1",children:"Baseline"}),"\n",(0,i.jsx)(n.p,{children:"We expect cloud providers to use ECC memory.\nMemory oversubscription is not recommended.\nIt is allowed to specify half GiBs (e.g. 3.5), though this is discouraged for larger memory sizes (>= 10GiB)."}),"\n",(0,i.jsx)(n.h4,{id:"no-ecc",children:"No ECC"}),"\n",(0,i.jsxs)(n.p,{children:["If no ECC is used, the ",(0,i.jsx)(n.code,{children:"u suffix"})," must indicate this."]}),"\n",(0,i.jsx)(n.h4,{id:"enabled-oversubscription",children:"Enabled Oversubscription"}),"\n",(0,i.jsxs)(n.p,{children:["You have to expose this with the ",(0,i.jsx)(n.code,{children:"o sufffix"}),"."]}),"\n",(0,i.jsx)(n.h4,{id:"examples-1",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["SCS-2C:",(0,i.jsx)(n.strong,{children:"4"}),":10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:",(0,i.jsx)(n.strong,{children:"3.5"}),":10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:",(0,i.jsx)(n.strong,{children:"4u"}),":10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:",(0,i.jsx)(n.strong,{children:"4o"}),":10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:",(0,i.jsx)(n.strong,{children:"4uo"}),":10n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-2C:",(0,i.jsx)(n.strong,{children:"4ou"}),":10n"]})," - This order is forbidden"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-disk-sizes-and-types",children:"[OPTIONAL] Disk sizes and types"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Disk type"}),(0,i.jsx)(n.th,{children:"Meaning"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"n"}),(0,i.jsx)(n.td,{children:"Network shared storage (ceph/cinder)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"h"}),(0,i.jsx)(n.td,{children:"Local disk (HDD: SATA/SAS class)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"s"}),(0,i.jsx)(n.td,{children:"Local SSD disk"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"p"}),(0,i.jsx)(n.td,{children:"Local high-perf NVMe"})]})]})]}),"\n",(0,i.jsx)(n.h4,{id:"baseline-2",children:"Baseline"}),"\n",(0,i.jsx)(n.p,{children:"Note that disk type might be omitted \u2014 the user then can not take any assumptions\non what storage is provided for the root disk (that the image gets provisioned to)."}),"\n",(0,i.jsxs)(n.p,{children:["It does make sense for ",(0,i.jsx)(n.code,{children:"n"})," to be requested explicitly to allow for smooth live migration.\n",(0,i.jsx)(n.code,{children:"h"})," typically provides latency advantages vs ",(0,i.jsx)(n.code,{children:"n"})," (but not necessarily bandwidth and\nalso is more likely to fail), ",(0,i.jsx)(n.code,{children:"s"})," and ",(0,i.jsx)(n.code,{children:"p"})," are for applications that need low\nlatency (high IOPS) and bandwidth disk I/O. ",(0,i.jsx)(n.code,{children:"n"})," storage is expected to survive\nsingle-disk and single-node failure."]}),"\n",(0,i.jsxs)(n.p,{children:["If the disk size is left out, the cloud is expected to allocate a disk (network or local)\nthat is large enough to fit the root file system (",(0,i.jsx)(n.code,{children:"min_disk"})," in image). This automatic\nallocation is indicated with ",(0,i.jsx)(n.code,{children:":"})," without a disk size.\nIf the ",(0,i.jsx)(n.code,{children:":"})," is left out completely, the user must create a boot volume manually and\ntell the instance to boot from it or use the\n",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/api-ref/compute/?expanded=create-server-detail#create-server",children:"block_device_mapping_v2"}),"\nmechanism explicitly to create the boot volume from an image."]}),"\n",(0,i.jsx)(n.h4,{id:"multi-provisioned-disk",children:"Multi-provisioned Disk"}),"\n",(0,i.jsxs)(n.p,{children:["The disk size can be prefixed with ",(0,i.jsx)(n.code,{children:"Mx prefix"}),", where M is an integer specifying that the disk\nis provisioned M times."]}),"\n",(0,i.jsx)(n.h4,{id:"examples-2",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:",(0,i.jsx)(n.strong,{children:"10n"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:",(0,i.jsx)(n.strong,{children:"10s"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:",(0,i.jsx)(n.strong,{children:"10s"}),"-bms-z3"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:",(0,i.jsx)(n.strong,{children:"3x10s"})," - Cloud creates three 10GB SSDs"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:",(0,i.jsx)(n.strong,{children:"3x10s"}),"-bms-z3"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:",(0,i.jsx)(n.strong,{children:"10"})," - Cloud decides disk type"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:",(0,i.jsx)(n.strong,{children:"10"}),"-bms-z3"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:",(0,i.jsx)(n.strong,{children:"n"})," - Cloud decides disk size (min_disk from image or larger)"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:",(0,i.jsx)(n.strong,{children:"n"}),"-bms-3"]}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C:4: - Cloud decides disk type and size"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C:4:-bms-z3"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C:4:-bms-z3h-GNa:64-ib"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C:4:-ib"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C:4 - You need to specify a boot volume yourself (boot from volume, or use block_device_mapping_v2)"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C:4-bms-z3"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C:4:3x - Cloud decides disk type and size and creates three of them (FIXME: Is this useful?)"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C:4:3xs - Cloud decides size and creates three local SSD volumes (FIXME: useful?)"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C:4:3x10 - Cloud decides type and creates three 10GB volumes"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-2C:4:",(0,i.jsx)(n.strong,{children:"1.5n"})]})," - You must not specify disk sizes which are not in full GiBs"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-hypervisor",children:"[OPTIONAL] Hypervisor"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"default Hypervisor"})," is assumed to be ",(0,i.jsx)(n.code,{children:"KVM"}),". Clouds, that offer different hypervisors\nor Bare Metal Systems should indicate the Hypervisor according to the following table:"]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"hyp"}),(0,i.jsx)(n.th,{children:"Meaning"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"kvm"}),(0,i.jsx)(n.td,{children:"KVM"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"xen"}),(0,i.jsx)(n.td,{children:"Xen"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"vmw"}),(0,i.jsx)(n.td,{children:"VMware"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"hyv"}),(0,i.jsx)(n.td,{children:"Hyper-V"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"bms"}),(0,i.jsx)(n.td,{children:"Bare Metal System"})]})]})]}),"\n",(0,i.jsx)(n.h4,{id:"examples-3",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"SCS-2C:4:10n"}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10n-",(0,i.jsx)(n.strong,{children:"bms"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10n-",(0,i.jsx)(n.strong,{children:"bms"}),"-z3h"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-hardware-virtualization--nested-virtualization",children:"[OPTIONAL] Hardware virtualization / Nested virtualization"}),"\n",(0,i.jsxs)(n.p,{children:["If the instances that are created with this flavor support hardware-accelerated\nvirtualization, this can be reflected with the ",(0,i.jsx)(n.code,{children:"-hwv"})," flag (after the optional\nHypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel)\nor svm (AMD) is available. This will be the case on Bare Metal flavors on almost\nall non-ancient x86 CPUs or if your virtualization hypervisor is configured to\nsupport nested virtualization.\nFlavors without the ",(0,i.jsx)(n.code,{children:"-hwv"})," flag may or may not support hardware virtualization (as we\nrecommend enabling nesting, but don't require flavor names to reflect all\ncapabilities. Flavors may overdeliver ...)"]}),"\n",(0,i.jsx)(n.h4,{id:"examples-4",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"SCS-2C:4:10 - may or may not support HW virtualization in VMs"}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10-kvm-",(0,i.jsx)(n.strong,{children:"hwv"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10-",(0,i.jsx)(n.strong,{children:"hwv"})," - not recommended, but allowed"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-2C:4:10-",(0,i.jsx)(n.strong,{children:"hwv"}),"-xen"]})," - illegal, wrong ordering"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-cpu-architecture-details",children:"[OPTIONAL] CPU Architecture Details"}),"\n",(0,i.jsx)(n.p,{children:"Arch details provide more details on the specific CPU:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Vendor"}),"\n",(0,i.jsx)(n.li,{children:"Generation"}),"\n",(0,i.jsx)(n.li,{children:"Frequency"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"generation-and-vendor",children:"Generation and Vendor"}),"\n",(0,i.jsxs)(n.p,{children:["The generations are vendor specific and can be left out.\nNot specifying arch means that we have a generic CPU (",(0,i.jsx)(n.strong,{children:"x86-64"}),")."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Generation"}),(0,i.jsx)(n.th,{children:"i (Intel x86-64)"}),(0,i.jsx)(n.th,{children:"z (AMD x86-64)"}),(0,i.jsx)(n.th,{children:"\xa0a (AArch64)"}),(0,i.jsx)(n.th,{children:"r (RISC-V)"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"0"}),(0,i.jsx)(n.td,{children:"pre Skylake"}),(0,i.jsx)(n.td,{children:"pre Zen"}),(0,i.jsx)(n.td,{children:"pre Cortex A76"}),(0,i.jsx)(n.td,{children:"TBD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"1"}),(0,i.jsx)(n.td,{children:"Skylake"}),(0,i.jsx)(n.td,{children:"Zen-1 (Naples)"}),(0,i.jsx)(n.td,{children:"A76/NeoN1 class"}),(0,i.jsx)(n.td,{children:"TBD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"2"}),(0,i.jsx)(n.td,{children:"Cascade Lake"}),(0,i.jsx)(n.td,{children:"Zen-2 (Rome)"}),(0,i.jsx)(n.td,{children:"A78/x1/NeoV1 class"}),(0,i.jsx)(n.td,{children:"TBD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"3"}),(0,i.jsx)(n.td,{children:"Ice Lake"}),(0,i.jsx)(n.td,{children:"Zen-3 (Milan)"}),(0,i.jsx)(n.td,{children:"A71x/NeoN2 (ARMv9)"}),(0,i.jsx)(n.td,{children:"TBD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"4"}),(0,i.jsx)(n.td,{}),(0,i.jsx)(n.td,{children:"Zen-4 (Genoa)"}),(0,i.jsx)(n.td,{}),(0,i.jsx)(n.td,{children:"TBD"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["It is recommended to leave out the ",(0,i.jsx)(n.code,{children:"0"}),' when specifying the old generation; this will\nhelp the parser tool, which assumes 0 for an unspecified value and does leave it\nout when generating the name for comparison. In other words: 0 has a meaning of\n"rather old or unspecified".']}),"\n",(0,i.jsx)(n.h4,{id:"frequency-suffixes",children:"Frequency Suffixes"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Suffix"}),(0,i.jsx)(n.th,{children:"Meaning"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"h"}),(0,i.jsx)(n.td,{children:">2.75GHz all-core"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"hh"}),(0,i.jsx)(n.td,{children:">3.25GHz all-core"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"hhh"}),(0,i.jsx)(n.td,{children:">3.75GHz all-core"})]})]})]}),"\n",(0,i.jsx)(n.h4,{id:"examples-5",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"SCS-2C:4:10n"}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10n-",(0,i.jsx)(n.strong,{children:"z"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10n-",(0,i.jsx)(n.strong,{children:"z3"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10n-",(0,i.jsx)(n.strong,{children:"z3h"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10n-",(0,i.jsx)(n.strong,{children:"z3hh"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10n-bms-",(0,i.jsx)(n.strong,{children:"z"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10n-bms-",(0,i.jsx)(n.strong,{children:"z3"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10n-bms-",(0,i.jsx)(n.strong,{children:"z3"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10n-bms-",(0,i.jsx)(n.strong,{children:"z3h"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C:4:10n-bms-",(0,i.jsx)(n.strong,{children:"z3hh"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-extra-features",children:"[OPTIONAL] Extra features"}),"\n",(0,i.jsxs)(n.p,{children:["Note that these are optional \u2014 it is recommended for providers to encode this information\ninto the flavor name, so there is a systematic way of differentiating flavors.\nProviders could leave it out however, leaving it to ",(0,i.jsx)(n.code,{children:"extra_specs"})," to make these flavor\ncapabilities discoverable. Nothing prevents providers from registering the same flavor\nunder a secondary (or tertiary) name."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"-GX[N][:M[h]]"})," indicates a Pass-Through GPU from vendor X of gen N with M compute units / SMs / EUs exposed.\n",(0,i.jsx)(n.code,{children:"-gX[N][:M[h]]"})," indicates a vGPU from vendor X of gen N with M compute units / SMs / EUs assigned."]}),"\n",(0,i.jsx)(n.p,{children:"Note that the vendor letter is mandatory, generation and compute units are optional."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"GPU"}),(0,i.jsx)(n.th,{children:"Vendor"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"N"}),(0,i.jsx)(n.td,{children:"nVidia"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"A"}),(0,i.jsx)(n.td,{children:"AMD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"I"}),(0,i.jsx)(n.td,{children:"Intel"})]})]})]}),"\n",(0,i.jsx)(n.p,{children:"Generations could be nVidia (f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, ...),\nAMD (GCN-x=0.x, RDNA1=1, RDNA2=2), intel (Gen9=0.9, Xe(12.1)=1, ...), ...\n(Note: This may need further work to properly reflect what's out there.)"}),"\n",(0,i.jsxs)(n.p,{children:["The optional ",(0,i.jsx)(n.code,{children:"h"})," suffix to the comput unit count indicates high-performance (e.g. high freq or special\nhigh bandwidth gfx memory such as HBM);\n",(0,i.jsx)(n.code,{children:"h"})," can be duplicated for even higher performance."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"-ib"})," indicates Inifinband networking."]}),"\n",(0,i.jsx)(n.p,{children:"More extensions will be forthcoming."}),"\n",(0,i.jsx)(n.p,{children:"Extensions need to be specified in the above mentioned order."}),"\n",(0,i.jsx)(n.h2,{id:"proposal-examples",children:"Proposal Examples"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Example"}),(0,i.jsx)(n.th,{children:"Decoding"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-2C:4:10n"}),(0,i.jsx)(n.td,{children:"2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-8Ti:32:50p-i1"}),(0,i.jsx)(n.td,{children:"8 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-1L:1u:5"}),(0,i.jsx)(n.td,{children:"1 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-16T:64:200s-GNa:64-ib"}),(0,i.jsx)(n.td,{children:"16 dedicated threads, 64GiB RAM, 200GB local SSD, Inifiniband, 64 Passthrough nVidia Ampere SMs"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-4C:16:2x200p-a1"}),(0,i.jsx)(n.td,{children:"4 dedicated Arm64 cores (A78 class), 16GiB RAM, 2x200GB local NVMe drives"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-1V:0.5"}),(0,i.jsx)(n.td,{children:"1 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"standard-scs-flavors",children:"Standard SCS flavors"}),"\n",(0,i.jsx)(n.p,{children:"These are flavors expected to exist on standard SCS clouds (x86-64)."}),"\n",(0,i.jsxs)(n.p,{children:["We expect disk sizes to be 5, 10, 20, 50, 100, 200, 500, 1000GB, 2000GB.\nWe expect a typical CPU",(0,i.jsx)(n.div,{children:"GiB"})," ratio of 1:4."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsxs)(n.th,{children:["vCPU",":RAM"," ratio"]}),(0,i.jsx)(n.th,{children:"Mandatory Flavors"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"1:4"}),(0,i.jsx)(n.td,{children:"SCS-1V:4, SCS-1V:4:10"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"2:8"}),(0,i.jsx)(n.td,{children:"SCS-2V:8, SCS-2V:8:20"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"4:16"}),(0,i.jsx)(n.td,{children:"SCS-4V:16, SCS-4V:16:50"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"8:32"}),(0,i.jsx)(n.td,{children:"SCS-8V:32, SCS-8V:32:100"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"1:2"}),(0,i.jsx)(n.td,{children:"SCS-1V:2, SCS-1V:2:5"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"2:4"}),(0,i.jsx)(n.td,{children:"SCS-2V:4, SCS-2V:4:10"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"4:8"}),(0,i.jsx)(n.td,{children:"SCS-4V:8, SCS-4V:8:20"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"8:16"}),(0,i.jsx)(n.td,{children:"SCS-8V:16, SCS-8V:16:50"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"16:32"}),(0,i.jsx)(n.td,{children:"SCS-16V:32, SCS-16V:32:100"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"1:8"}),(0,i.jsx)(n.td,{children:"SCS-1V:8, SCS-1V:8:20"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"2:16"}),(0,i.jsx)(n.td,{children:"SCS-2V:16, SCS-2V:16:50"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"4:32"}),(0,i.jsx)(n.td,{children:"SCS-4V:32, SCS-4V:32:100"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"1:1"}),(0,i.jsx)(n.td,{children:"SCS-1L:1, SCS-1L:1:5"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["Note that all vCPUs are oversubscribed \u2014 the smallest ",(0,i.jsx)(n.code,{children:"1L:1"})," flavor allows\nfor heavy oversubscription (note the ",(0,i.jsx)(n.code,{children:"L"}),"), and thus can be offered very\ncheaply \u2014 imagine jump hosts ...\nDisks types are not specified (and expected to be n or h typically)."]}),"\n",(0,i.jsx)(n.p,{children:"The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM\ncompute hosts) to offer all flavors."}),"\n",(0,i.jsxs)(n.p,{children:["Note: Compared to previous drafts, we have heavily reduced the variations\non disk sizes \u2014 this reflects that for the standard networked cinder\ndisks, you can pass block",(0,i.jsx)(n.em,{children:"device_mapping_v2 on server (VM) creation to\nallocate a boot disk of any size you desire. We have scaled the few\nmandatory disk sizes with the amount of RAM. For each flavor there is\nalso one _without"})," a pre-attached disk \u2014 these are meant to be used\nto boot from a volume (either created beforehand or allocated on-the-fly\nwith block_device_mapping_v2, e.g.\n",(0,i.jsx)(n.code,{children:"openstack server create --flavor SCS-1V:2 --block-device-mapping sda=IMGUUID:image:12:true"}),"\nto create a bootable 12G cinder volume from image ",(0,i.jsx)(n.code,{children:"IMGUUID"})," that gets tied to the VM\ninstance lifecycle.)"]}),"\n",(0,i.jsx)(n.h2,{id:"naming-policies",children:"Naming policies"}),"\n",(0,i.jsx)(n.p,{children:"To be certified as an SCS compliant x86-64 IaaS platform, you must offer all standard SCS flavors\naccording to the previous section. (We may define a mechanism that allows exceptions to be\ngranted in a way that makes this very transparent and visible to clients.)"}),"\n",(0,i.jsx)(n.p,{children:"You are allowed to understate your performance; you may implement a SCS-1Vl:1:5 flavor with\na flavor that actually implements SCS-1T:1:5n (i.e. you dedicate a secured hyperthread instead\nof high oversubscription) or even SCS-1D:1.5:8s (1 dedicated core, 50% more RAM and a 8GiB SSD)."}),"\n",(0,i.jsx)(n.p,{children:"We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V:32:100).\nLarger providers that offer more details are expected to still also offer the short variants\nfor usability and easier portability, even beyond the mandated flavors."}),"\n",(0,i.jsxs)(n.p,{children:["You must be very careful to expose low vCPU guarantees (",(0,i.jsx)(n.code,{children:"L"})," instead ov ",(0,i.jsx)(n.code,{children:"V"}),"), insecure\nhyperthreading/microcode ",(0,i.jsx)(n.code,{children:"i"}),", non-ECC-RAM ",(0,i.jsx)(n.code,{children:"u"}),", memory oversubscription ",(0,i.jsx)(n.code,{children:"o"}),". Note that omitting these qualifiers is\noverstating your security, reliability or performance properties and may be reason for\nclients to feel betrayed or claim damages. It might in extreme cases also cause SCS to withdraw certification\nalong with public statements."]}),"\n",(0,i.jsx)(n.p,{children:"You may offer additional SCS- flavors, following the naming scheme outlined here."}),"\n",(0,i.jsx)(n.p,{children:"You may offer additional flavors, not following above scheme."}),"\n",(0,i.jsx)(n.p,{children:"You must not offer flavors with the SCS- prefix which do not follow this naming scheme.\nYou must not extend the SCS naming scheme with your own suffices; you are encouraged however\nto suggest extensions that we can discuss and add to the official scheme."}),"\n",(0,i.jsx)(n.p,{children:"Note that all letters are case-sensitive.\nIn case you wonder: Feature indicators are capitalized, modifiers are lower case.\n(An exception is the uppercase -G for a passthrough GPU vs. lowercase -g for vGPU.)"}),"\n",(0,i.jsx)(n.h3,{id:"rationale",children:"Rationale"}),"\n",(0,i.jsx)(n.p,{children:"Note that we expect most clouds to prefer short flavor names,\nnot indicating CPU details or hypervisor types. See above list\nof standard flavors to get a feeling."}),"\n",(0,i.jsxs)(n.p,{children:["However, more successful providers will often need to differentiate their\nofferings in response to customer demand and allow customers to request\nflavors with specific detailed properties. The goal of this proposal is to avoid\nproviders to invent their own names and then refer customers to ",(0,i.jsx)(n.code,{children:"extra_specs"}),"\nor worse a non-machine-readable service description to find out the details."]}),"\n",(0,i.jsxs)(n.p,{children:["So a cloud provider might well evolve from offering ",(0,i.jsx)(n.code,{children:"SCS-8T:16:50"})," to offering\n",(0,i.jsx)(n.code,{children:"SCS-8T:16:50n"}),", ",(0,i.jsx)(n.code,{children:"SCS-8T:16:50n-i2"})," and ",(0,i.jsx)(n.code,{children:"SCS-8T:16:50n-a2"})," to specify that he\nis using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome.\nWe would expect the cloud provider to still offer the generic flavor\n",(0,i.jsx)(n.code,{children:"SCS-8C:16:50"})," and allow the scheduler (placement service) to pick both more\nspecific types (or just one if e.g. capacity management considerations suggest\nso). We would expect providers in such cases to ensure that the price of a requested\nflavor does not depend on the scheduler decisions."]}),"\n",(0,i.jsxs)(n.p,{children:["We are looking into the ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/image-guide/introduction.html#metadata-definition-metadefs-service",children:"metadefs"}),"\nmechanism and ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/api-guide/compute/extra_specs_and_properties.html",children:"extra_specs"}),"\nto allow customers to ask for specific flavor properties without the need to\nencode all these flavor details into the flavor name, so the optional pieces\nmay not be needed much. However, there must be a way to request flavor\nproperties without encoding the need into an image \u2014 this indirection is\nconsidered broken by the SCS team."]}),"\n",(0,i.jsx)(n.h2,{id:"validation",children:"Validation"}),"\n",(0,i.jsxs)(n.p,{children:["There is a script in ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/flavor-naming/flavor-name-check.py",children:"flavor_name_check.py"}),"\nwhich can be used to decode, validate and construct flavor names.\nThis script must stay in sync with the specification text."]}),"\n",(0,i.jsxs)(n.p,{children:["Ensure you have your OpenStack tooling (",(0,i.jsx)(n.code,{children:"python3-openstackclient"}),", ",(0,i.jsx)(n.code,{children:"OS_CLOUD"}),") setup and call\n",(0,i.jsx)(n.code,{children:"tools/flavor-name-check.py -c $(openstack flavor list -f value -c Name)"})," to get a report\non the flavor list compliance of the cloud environment."]}),"\n",(0,i.jsx)(n.h2,{id:"beyond-scs-gaia-x",children:"Beyond SCS: Gaia-X"}),"\n",(0,i.jsx)(n.p,{children:'Some providers might offer VM services ("IaaS") without trying to adhere to SCS standards,\nyet still finding the flavor naming standards useful. The Gaia-X Technical Committee\'s\nProvider Working Group (WG) would seem like a logical place for such dicussions then.\nIf so, we could\nreplace the SCS- prefix with a GX- prefix and transfer the naming scheme governance from\nthe SCS project to the Gaia-X Provider WG (where we participate). SCS certification would\nthen reference the Gaia-X flavor naming standard as a requirement.'})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>l});var i=s(96540);const r={},t=i.createContext(r);function d(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9d187656.62ab2c10.js b/assets/js/9d187656.62ab2c10.js new file mode 100644 index 0000000000..ab8debf36b --- /dev/null +++ b/assets/js/9d187656.62ab2c10.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6805],{9930:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>r,toc:()=>l});var s=n(74848),i=n(28453);const o={},a="Overview",r={id:"operating-scs/components/status-page/docs/overview",title:"Overview",description:"Service providers often times want to communicate the status of their systems transparently to their users.",source:"@site/docs/04-operating-scs/components/status-page/docs/overview.md",sourceDirName:"04-operating-scs/components/status-page/docs",slug:"/operating-scs/components/status-page/docs/overview",permalink:"/docs/operating-scs/components/status-page/docs/overview",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page/docs/overview.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Status Page API",permalink:"/docs/category/status-page-api"},next:{title:"Component Overview",permalink:"/docs/operating-scs/components/status-page/docs/component_overview"}},c={},l=[{value:"The SCS status page <strong>API</strong>",id:"the-scs-status-page-api",level:2},{value:"Reference implementation",id:"reference-implementation",level:3},{value:"The SCS status page <strong>frontend</strong>",id:"the-scs-status-page-frontend",level:2},{value:"Reference implementation",id:"reference-implementation-1",level:3}];function d(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",section:"section",strong:"strong",sup:"sup",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"overview",children:"Overview"}),"\n",(0,s.jsx)(t.p,{children:'Service providers often times want to communicate the status of their systems transparently to their users.\nA commonly used pattern is to provide a "status page" web application, where the current system health as well as recent incidents are made available.'}),"\n",(0,s.jsx)(t.p,{children:"SCS strives to implement a status page that works well, while being interoperable with other systems."}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["How was the decision to implement a new status page application made? What were the requirements? See the ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/1fb174da1ee906f0da6a8bbefbd3d95884df5669/Standards/scs-0400-v1-status-page-create-decision.md",children:"decision record"}),"."]})}),"\n",(0,s.jsxs)(t.p,{children:['To be easily interoperable with other software, being "API-first" is a priority.\nAs such, the status page should not ',(0,s.jsx)(t.em,{children:"need to"})," be a typical monolithic web application (even though it could be), hence making it possible to split functionality into an API server and a frontend component."]}),"\n",(0,s.jsxs)(t.h2,{id:"the-scs-status-page-api",children:["The SCS status page ",(0,s.jsx)(t.strong,{children:"API"})]}),"\n",(0,s.jsxs)(t.p,{children:["The SCS status page ",(0,s.jsx)(t.strong,{children:"API"})," (as opposed to actual implementations) is supposed to be as un-opinionated as possible regarding deployment, user management, persistence and tech stack, to allow operators/developers (1) to make their own decisions regarding these topics and (2) to quickly implement the API with their own tech stack opinions, if the reference implementation does not fit theirs."]}),"\n",(0,s.jsxs)(t.p,{children:["In particular, the ",(0,s.jsx)(t.strong,{children:"API"})," has no opinion about:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["How authentication/authorization is done (apart from splitting Read-only from Read-write ",(0,s.jsx)(t.sup,{children:(0,s.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"; See below)"]}),"\n",(0,s.jsx)(t.li,{children:"Server implementation, used database, deployment automation, high availability"}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"However, as un-opinionated the API (in its first iteration) strives to be, it is...:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"a REST API (no GRPC/GraphQL/...)"}),"\n",(0,s.jsx)(t.li,{children:"defined using an OpenAPI file to make use of OpenAPI tooling"}),"\n",(0,s.jsxs)(t.li,{children:["split in two parts ",(0,s.jsx)(t.sup,{children:(0,s.jsx)(t.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),":","\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"Read-only anonymous access"}),"\n",(0,s.jsx)(t.li,{children:"Read-write authenticated access"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"reference-implementation",children:"Reference implementation"}),"\n",(0,s.jsxs)(t.p,{children:["It is envisioned to have a well-maintained reference implementation of the status page API with some basic tech stack decisions made, to not ",(0,s.jsx)(t.em,{children:"require"})," anyone to implement the API themselves:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Programming Language: Go"}),"\n",(0,s.jsx)(t.li,{children:"Persistence: Postgres compatible database"}),"\n"]}),"\n",(0,s.jsxs)(t.h2,{id:"the-scs-status-page-frontend",children:["The SCS status page ",(0,s.jsx)(t.strong,{children:"frontend"})]}),"\n",(0,s.jsxs)(t.p,{children:["The SCS status page ",(0,s.jsx)(t.strong,{children:"frontend"})," is supposed to be an application which uses the status page API to get information. This could be an CLI tool as well as an web application."]}),"\n",(0,s.jsx)(t.h3,{id:"reference-implementation-1",children:"Reference implementation"}),"\n",(0,s.jsx)(t.p,{children:"It is envisioned to have a well-maintained reference implementation of an status page frontend with some basic tech stack decisions made:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Platform: Web (HTML/JS/...)"}),"\n",(0,s.jsx)(t.li,{children:"Framework: VueJS, Vuetify"}),"\n"]}),"\n","\n",(0,s.jsxs)(t.section,{"data-footnotes":!0,className:"footnotes",children:[(0,s.jsx)(t.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{id:"user-content-fn-1",children:["\n",(0,s.jsxs)(t.p,{children:["In the future ",(0,s.jsx)(t.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})," ",(0,s.jsxs)(t.a,{href:"#user-content-fnref-1-2","data-footnote-backref":"","aria-label":"Back to reference 1-2",className:"data-footnote-backref",children:["\u21a9",(0,s.jsx)(t.sup,{children:"2"})]})]}),"\n"]}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var s=n(96540);const i={},o=s.createContext(i);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9d49bc50.b55b5ac4.js b/assets/js/9d49bc50.b55b5ac4.js new file mode 100644 index 0000000000..91c6b15fc8 --- /dev/null +++ b/assets/js/9d49bc50.b55b5ac4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5875],{48963:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>c,frontMatter:()=>t,metadata:()=>l,toc:()=>u});var i=o(74848),s=o(28453);const t={sidebar_label:"Zuul CI"},r="Zuul CI",l={id:"iaas/guides/other-guides/developer-guide/zuul",title:"Zuul CI",description:"We use Zuul CI as a CI service for OSISM. The service is not required for",source:"@site/docs/02-iaas/guides/other-guides/developer-guide/zuul.md",sourceDirName:"02-iaas/guides/other-guides/developer-guide",slug:"/iaas/guides/other-guides/developer-guide/zuul",permalink:"/docs/iaas/guides/other-guides/developer-guide/zuul",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/developer-guide/zuul.md",tags:[],version:"current",frontMatter:{sidebar_label:"Zuul CI"},sidebar:"docs",previous:{title:"Scripts",permalink:"/docs/iaas/guides/other-guides/developer-guide/scripts"},next:{title:"Style Guide",permalink:"/docs/iaas/guides/other-guides/style-guide"}},a={},u=[{value:"The <code>zuul</code> label",id:"the-zuul-label",level:2},{value:"Installation",id:"installation",level:2},{value:"Server preparation",id:"server-preparation",level:3},{value:"Define secrets",id:"define-secrets",level:3},{value:"Github App setup",id:"github-app-setup",level:3},{value:"Example Playbook",id:"example-playbook",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Your git repos are not displayed?",id:"your-git-repos-are-not-displayed",level:3},{value:"Your git repos are using the wrong branch?",id:"your-git-repos-are-using-the-wrong-branch",level:3},{value:"Your logs are not displayed in the web-UI?",id:"your-logs-are-not-displayed-in-the-web-ui",level:3},{value:"Hanging jobs in a pipeline?",id:"hanging-jobs-in-a-pipeline",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"zuul-ci",children:"Zuul CI"}),"\n",(0,i.jsxs)(n.admonition,{type:"note",children:[(0,i.jsx)(n.p,{children:"We use Zuul CI as a CI service for OSISM. The service is not required for\nthe use of OSISM itself. However, as we deploy and provide Zuul CI ourselves,\nthe documentation for this is also included in the OSISM Developer Guide."}),(0,i.jsxs)(n.p,{children:["Our Zuul CI instance is available at\n",(0,i.jsx)(n.a,{href:"https://zuul.services.betacloud.xyz/t/osism/status",children:"zuul.services.betacloud.xyz"}),"."]})]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"osism.services.zuul"})," is the Ansible role to set up Zuul CI as a single-node\ninstallation with Docker Compose."]}),"\n",(0,i.jsxs)(n.h2,{id:"the-zuul-label",children:["The ",(0,i.jsx)(n.code,{children:"zuul"})," label"]}),"\n",(0,i.jsxs)(n.p,{children:["On CI jobs that consume a lot of resources and have long runtimes we use a label\n",(0,i.jsx)(n.code,{children:"zuul"})," to run these jobs."]}),"\n",(0,i.jsxs)(n.p,{children:["These CI jobs run in the ",(0,i.jsx)(n.a,{href:"https://zuul.services.betacloud.xyz/t/osism/buildsets?pipeline=label",children:"label pipeline"}),"\nand are only started once after the label has been assigned. If changes are made\nto a PR, the label must first be removed and then reassigned for a new run of the\nCI jobs."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"zuul"})," label is usable in the following repositories:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://github.com/osism/container-images-kolla",children:"osism/container-images-kolla"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://github.com/osism/testbed",children:"osism/testbed"})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsx)(n.h3,{id:"server-preparation",children:"Server preparation"}),"\n",(0,i.jsx)(n.p,{children:"Set up a server (VM) with Ubuntu Server 22.04 LTS and make\nsure that these packages are installed:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"docker.io"}),"\n",(0,i.jsx)(n.li,{children:"docker-compose"}),"\n",(0,i.jsx)(n.li,{children:"python3-docker"}),"\n",(0,i.jsx)(n.li,{children:"python3-openstackclient"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Also configure your deploy user to be in the docker group and set up the\naccount for the zuul user. TCP-Ports 80 and 443 should be accessible\nfrom the internet, port 22 for management via SSH will also often be\nuseful, but not required."}),"\n",(0,i.jsx)(n.p,{children:"If you have an OpenStack tenant where you want to deploy the Zuul\nserver, you can download and adapt this example\nplaybook:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'---\n- name: Setup zuul server\n hosts: localhost\n vars:\n cloud: mycloud\n flavor: myflavor\n image: Ubuntu 22.04\n keypair: mykeypair\n network: myprivatenet\n project: myproject\n zuul_domain: mydomain.xyz.\n zuul_fqdn: "zuul01.services.{{ zuul_domain }}"\n zuul_host: zuul01\n\n tasks:\n - name: Create security group\n openstack.cloud.security_group:\n cloud: "{{ cloud }}"\n name: "{{ project }}-zuul"\n description: "Default security group for {{ project }}-zuul"\n\n - name: Create security group rule (icmp)\n openstack.cloud.security_group_rule:\n cloud: "{{ cloud }}"\n security_group: "{{ project }}-zuul"\n protocol: icmp\n remote_ip_prefix: 0.0.0.0/0\n\n - name: Create security group rules (tcp)\n openstack.cloud.security_group_rule:\n cloud: "{{ cloud }}"\n security_group: "{{ project }}-zuul"\n protocol: tcp\n remote_ip_prefix: 0.0.0.0/0\n port_range_min: "{{ item }}"\n port_range_max: "{{ item }}"\n loop:\n - 22\n - 80\n - 443\n\n - name: Create zuul server\n openstack.cloud.server:\n cloud: "{{ cloud }}"\n flavor: "{{ flavor }}"\n image: "{{ image }}"\n key_name: "{{ keypair }}"\n name: "{{ zuul_host }}"\n network: "{{ network }}"\n security_groups:\n - default\n - "{{ project }}-zuul"\n meta:\n hostname: "{{ zuul_host }}"\n register: zuul_server\n\n - name: Add host\n ansible.builtin.add_host:\n name: "{{ zuul_server.openstack.accessIPv4 }}"\n groups: zuul\n ansible_user: ubuntu\n\n- name: Initialize zuul server\n hosts: zuul\n gather_facts: false\n vars:\n zuul_user: zuul\n\n tasks:\n - name: Wait for system to become reachable\n ansible.builtin.wait_for_connection:\n\n - name: Update all packages\n ansible.builtin.apt:\n update_cache: true\n name: \'*\'\n state: latest\n become: true\n\n - name: Install required packages\n ansible.builtin.apt:\n name:\n - docker.io\n - docker-compose\n - python3-docker\n - python3-openstackclient\n become: true\n\n - name: Add user to docker group\n ansible.builtin.user:\n name: "{{ ansible_ssh_user }}"\n groups: docker\n append: true\n become: true\n\n - name: Add group\n ansible.builtin.group:\n name: "{{ zuul_user }}"\n become: true\n\n - name: Add user\n ansible.builtin.user:\n name: "{{ zuul_user }}"\n uid: 10001\n shell: /bin/bash\n group: "{{ zuul_user }}"\n groups: sudo\n append: true\n home: "/home/{{ zuul_user }}"\n become: true\n'})}),"\n",(0,i.jsx)(n.h3,{id:"define-secrets",children:"Define secrets"}),"\n",(0,i.jsxs)(n.p,{children:["There need to be some secrets handed to the deployment, the suggested\nmethod is to have a dedicated file that contains them, which will be\nincluded in the example playbook below via a ",(0,i.jsx)(n.code,{children:"vars_files"})," statement.\nThis allows you to easily protect all your secrets by applying\n",(0,i.jsx)(n.code,{children:"ansible-vault encrypt"})," to that file. The contents of this file should\nlook like:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"---\nzuul_auth_secret: secret used for zuul web auth\nwebhook_token: token defined for github webhooks\ndb_user_pass: DB password for the zuul user\ndb_root_pass: DB root password\n"})}),"\n",(0,i.jsxs)(n.p,{children:["In addition you need to prepare some further data that needs to be\nplaced into a ",(0,i.jsx)(n.code,{children:"files"})," directory in order to be consumed by the zuul\nrole. These are:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["A ",(0,i.jsx)(n.code,{children:"clouds.yaml"})," file for nodepool. This will be used by\n",(0,i.jsx)(n.code,{children:"nodepool-builder"})," to upload the newly created images and by\n",(0,i.jsx)(n.code,{children:"nodepool-launcher"})," to start instances running these images, these\nwill then be handed over to Zuul as CI nodes."]}),"\n",(0,i.jsxs)(n.li,{children:["An SSH private key in the file ",(0,i.jsx)(n.code,{children:"nodepool"})," and the matching public\nkey in ",(0,i.jsx)(n.code,{children:"nodepool.pub"}),". These will be used by nodepool and zuul to\naccess the CI nodes via SSH."]}),"\n",(0,i.jsxs)(n.li,{children:["An SSL private key and certificate pasted together in a file\nnamed ",(0,i.jsx)(n.code,{children:"server.crt"}),". This file will be used in the https setup by\nthe webserver. The certificate should cover both ",(0,i.jsx)(n.code,{children:"zuul_webserver_fqdn"}),"\nand ",(0,i.jsx)(n.code,{children:"zuul_logserver_fqdn"}),"."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"github-app-setup",children:"Github App setup"}),"\n",(0,i.jsxs)(n.p,{children:["In order for zuul to be able to interact with repositories hosted on\ngithub, you need to set up a github application. Follow the instructions\nat ",(0,i.jsx)(n.a,{href:"https://zuul-ci.org/docs/zuul/latest/drivers/github.html#application",children:"https://zuul-ci.org/docs/zuul/latest/drivers/github.html#application"}),"\nto do this. The webhook token to use is the one defined in the\npervious section. Use ",(0,i.jsx)(n.code,{children:"github"})," in place of ",(0,i.jsx)(n.code,{children:"<connection-name>"})," for the\nWebhook URL in the app configuration. After the app has been created,\nplace the PEM files that you downloaded into a\ndirectory named ",(0,i.jsx)(n.code,{children:"pem-files"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ mkdir -p pem-files\n$ cp ~/Downloads/my-org-zuul.*.private-key.pem pem-files/my-org-zuul.pem\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Now add the information about your github app to ",(0,i.jsx)(n.code,{children:"vars.yml"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"github_app_id: 000000\ngithub_pem_name: my-org-zuul\n"})}),"\n",(0,i.jsx)(n.h3,{id:"example-playbook",children:"Example Playbook"}),"\n",(0,i.jsxs)(n.p,{children:["Save this file as ",(0,i.jsx)(n.code,{children:"main.yaml"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'---\n- name: Set up zuul\n hosts: zuul.example.com\n vars_files:\n - vars.yml\n pre_tasks:\n - name: Create /etc/openstack/\n ansible.builtin.file:\n state: directory\n path: /etc/openstack\n owner: root\n group: root\n mode: 0755\n become: true\n\n - name: Deploy clouds.yaml file\n ansible.builtin.copy:\n src: clouds.yaml\n dest: /etc/openstack/clouds.yaml\n owner: root\n group: zuul\n mode: \'0640\'\n become: true\n\n - name: Create keypair in the cloud\n openstack.cloud.keypair:\n cloud: osism-ci\n name: osism-zuul\n public_key: "{{ lookup(\'file\', \'nodepool.pub\') }}"\n become: true\n\n roles:\n - name: Execute zuul role\n role: zuul\n vars:\n zuul_connections:\n github:\n driver: github\n webhook_token: "{{ webhook_token }}"\n app_id: "{{ github_app_id }}"\n app_key: "/etc/zuul/pem-files/{{ github_pem_name }}.pem"\n opendevorg:\n name: opendev\n driver: git\n baseurl: https://opendev.org\n zuul_tenants:\n - tenant:\n name: my-tenant-name\n source:\n opendevorg:\n untrusted-projects:\n - zuul/zuul-jobs:\n include:\n - job\n github:\n config-projects:\n - my-org/zuul_demo_config:\n load-branch: main\n untrusted-projects:\n - my-org/zuul_demo_repo\n become: true\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Create an ",(0,i.jsx)(n.code,{children:"inventory"})," file containing the login information for your zuul\nserver, it might look like:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"zuul.example.com ansible_host=192.0.2.2 ansible_user=ubuntu\n"})}),"\n",(0,i.jsx)(n.p,{children:"Then you can deploy your zuul server by running:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"ansible-playbook -i inventory main.yaml\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This will deploy a simple zuul setup with sample example repos being\nreferenced. You can fork the example repos from the\n",(0,i.jsx)(n.a,{href:"https://github.com/osism",children:"https://github.com/osism"})," tenant or just use them as a guide for how\nto build your own."]}),"\n",(0,i.jsx)(n.p,{children:"For further information about how to tune this setup for\nyou specific environment, have a look at the sections covering\nnodepool and tenant configuration."}),"\n",(0,i.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,i.jsx)(n.h3,{id:"your-git-repos-are-not-displayed",children:"Your git repos are not displayed?"}),"\n",(0,i.jsxs)(n.p,{children:["Have you thought of naming your repos with the prefix of your organization? ",(0,i.jsx)(n.code,{children:"release"})," should be ",(0,i.jsx)(n.code,{children:"osism/release"})," for example."]}),"\n",(0,i.jsx)(n.h3,{id:"your-git-repos-are-using-the-wrong-branch",children:"Your git repos are using the wrong branch?"}),"\n",(0,i.jsxs)(n.p,{children:["For ",(0,i.jsx)(n.code,{children:"config-projects"})," you set this value in the tenant-configuration with the ",(0,i.jsx)(n.code,{children:"load-branch"})," stanza.\nFor ",(0,i.jsx)(n.code,{children:"untrusted-projects"})," you set this value in the config-projects ",(0,i.jsx)(n.code,{children:"project"})," sections AND in EVERY ",(0,i.jsx)(n.code,{children:"untrusted-project"}),".\nEach ",(0,i.jsx)(n.code,{children:"project"})," section needs to have the ",(0,i.jsx)(n.code,{children:"default-branch"})," stanza."]}),"\n",(0,i.jsx)(n.h3,{id:"your-logs-are-not-displayed-in-the-web-ui",children:"Your logs are not displayed in the web-UI?"}),"\n",(0,i.jsx)(n.p,{children:"Check, if the IP of the logfile server is really correct. In combination with GitHub there is a\nbug which keeps the GitHub App posting to the old IP even if the webhook IP was changed. Current\nworkaround: Delete the old GitHub App and create a new one."}),"\n",(0,i.jsx)(n.h3,{id:"hanging-jobs-in-a-pipeline",children:"Hanging jobs in a pipeline?"}),"\n",(0,i.jsx)(n.p,{children:"Sometimes jobs get stuck in a pipeline and are never scheduled. They must then be removed manually\nso that they do not block other jobs."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Hanging jobs in a pipeline",src:o(85723).A+"",width:"774",height:"588"})}),"\n",(0,i.jsxs)(n.p,{children:["First create a local ",(0,i.jsx)(n.code,{children:".zuul.conf"})," configuration file in your home directory."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="$HOME/.zuul.conf"'})}),"\n",(0,i.jsxs)(n.p,{children:["[osism]\nurl=",(0,i.jsx)(n.a,{href:"https://zuul.services.betacloud.xyz/",children:"https://zuul.services.betacloud.xyz/"}),"\nauth_token=TOKEN\ntenant=osism"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"\nThe required auth token can be generated on the Zuul control node with the `zuul-admin` client.\n\n"})}),"\n",(0,i.jsx)(n.p,{children:"docker exec -it zuul_scheduler zuul-admin create-auth-token --user USER --tenant osism --expires-in 3600 --auth-config zuul_operator"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"\nWith the [zuul-client](https://zuul-ci.org/docs/zuul-client/index.html) it is possible to\nremove the two hanging jobs from the screenshot.\n\n"})}),"\n",(0,i.jsx)(n.p,{children:"zuul-client --use-config osism dequeue --pipeline periodic-daily --project osism/k8s-capi-images --ref refs/heads/main\nzuul-client --use-config osism dequeue --pipeline periodic-daily --project osism/cfg-generics --ref refs/heads/main"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"\n## Important daily CI jobs\n\n* [osism/container-image-ceph-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-ceph-ansible&pipeline=periodic-daily&skip=0)\n* [osism/container-image-kolla-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-kolla-ansible&pipeline=periodic-daily&skip=0)\n* [osism/container-image-osism-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-osism-ansible&pipeline=periodic-daily&skip=0)\n* [osism/container-images-kolla](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-images-kolla&pipeline=periodic-midnight&skip=0)\n* [osism/testbed](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Ftestbed&pipeline=periodic-daily&skip=0)\n"})})]})}function c(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},85723:(e,n,o)=>{o.d(n,{A:()=>i});const i=o.p+"assets/images/zuul-hanging-jobs-in-a-pipeline-047d29fda9946dd80cebb88778249bce.png"},28453:(e,n,o)=>{o.d(n,{R:()=>r,x:()=>l});var i=o(96540);const s={},t=i.createContext(s);function r(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9e4087bc.a8acb5d3.js b/assets/js/9e4087bc.a8acb5d3.js new file mode 100644 index 0000000000..6ceeed16ae --- /dev/null +++ b/assets/js/9e4087bc.a8acb5d3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2711],{89331:(e,r,t)=>{t.r(r),t.d(r,{default:()=>m});t(96540);var a=t(28774),n=t(21312),s=t(61213),i=t(36266),c=t(72415),l=t(51107),o=t(74848);function d(e){let{year:r,posts:t}=e;const n=(0,i.i)({day:"numeric",month:"long",timeZone:"UTC"});return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(l.A,{as:"h3",id:r,children:r}),(0,o.jsx)("ul",{children:t.map((e=>{return(0,o.jsx)("li",{children:(0,o.jsxs)(a.A,{to:e.metadata.permalink,children:[(r=e.metadata.date,n.format(new Date(r)))," - ",e.metadata.title]})},e.metadata.date);var r}))})]})}function h(e){let{years:r}=e;return(0,o.jsx)("section",{className:"margin-vert--lg",children:(0,o.jsx)("div",{className:"container",children:(0,o.jsx)("div",{className:"row",children:r.map(((e,r)=>(0,o.jsx)("div",{className:"col col--4 margin-vert--lg",children:(0,o.jsx)(d,{...e})},r)))})})})}function m(e){let{archive:r}=e;const t=(0,n.T)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),a=(0,n.T)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),i=function(e){const r=e.reduce(((e,r)=>{const t=r.metadata.date.split("-")[0],a=e.get(t)??[];return e.set(t,[r,...a])}),new Map);return Array.from(r,(e=>{let[r,t]=e;return{year:r,posts:t}}))}(r.blogPosts);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.be,{title:t,description:a}),(0,o.jsxs)(c.A,{children:[(0,o.jsx)("header",{className:"hero hero--primary",children:(0,o.jsxs)("div",{className:"container",children:[(0,o.jsx)(l.A,{as:"h1",className:"hero__title",children:t}),(0,o.jsx)("p",{className:"hero__subtitle",children:a})]})}),(0,o.jsx)("main",{children:i.length>0&&(0,o.jsx)(h,{years:i})})]})]})}},36266:(e,r,t)=>{t.d(r,{i:()=>n});var a=t(44586);function n(e){void 0===e&&(e={});const{i18n:{currentLocale:r}}=(0,a.A)(),t=function(){const{i18n:{currentLocale:e,localeConfigs:r}}=(0,a.A)();return r[e].calendar}();return new Intl.DateTimeFormat(r,{calendar:t,...e})}}}]); \ No newline at end of file diff --git a/assets/js/9f356e5b.6a0bc2b3.js b/assets/js/9f356e5b.6a0bc2b3.js new file mode 100644 index 0000000000..cd645ecc51 --- /dev/null +++ b/assets/js/9f356e5b.6a0bc2b3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1844],{24901:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>u});var n=r(74848),c=r(28453);const o={},i="Architecture",s={id:"iaas/overview/architecture",title:"Architecture",description:"TODO",source:"@site/docs/02-iaas/overview/architecture.md",sourceDirName:"02-iaas/overview",slug:"/iaas/overview/architecture",permalink:"/docs/iaas/overview/architecture",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/overview/architecture.md",tags:[],version:"current",frontMatter:{}},a={},u=[];function d(e){const t={h1:"h1",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"architecture",children:"Architecture"}),"\n",(0,n.jsx)(t.p,{children:"TODO"})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>s});var n=r(96540);const c={},o=n.createContext(c);function i(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9fb1f91e.4f451039.js b/assets/js/9fb1f91e.4f451039.js new file mode 100644 index 0000000000..236fb5cd3f --- /dev/null +++ b/assets/js/9fb1f91e.4f451039.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6088],{18909:e=>{e.exports=JSON.parse('{"title":"K8s Cluster API Provider","slug":"/category/k8s-cluster-api-provider","permalink":"/docs/category/k8s-cluster-api-provider","navigation":{"previous":{"title":"Components","permalink":"/docs/category/components-1"},"next":{"title":"Overview","permalink":"/docs/container/components/k8s-cluster-api-provider/doc/overview"}}}')}}]); \ No newline at end of file diff --git a/assets/js/a0b1bbd7.81d4ebbc.js b/assets/js/a0b1bbd7.81d4ebbc.js new file mode 100644 index 0000000000..8e422c95bf --- /dev/null +++ b/assets/js/a0b1bbd7.81d4ebbc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7984],{64208:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var t=n(74848),i=n(28453);const r={},a="Release Notes for SCS Release 5",o={id:"releases/Release5",title:"Release Notes for SCS Release 5",description:"(Release Date: 2023-09-20)",source:"@site/docs/06-releases/Release5.md",sourceDirName:"06-releases",slug:"/releases/Release5",permalink:"/docs/releases/Release5",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release5.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Release Notes for SCS Release 4",permalink:"/docs/releases/Release4"},next:{title:"Release Notes for SCS Release 6",permalink:"/docs/releases/Release6"}},l={},d=[{value:"Scope",id:"scope",level:2},{value:"Component Versions and User-visible improvements (highlights)",id:"component-versions-and-user-visible-improvements-highlights",level:2},{value:"IaaS",id:"iaas",level:3},{value:"Container Management",id:"container-management",level:3},{value:"Preview: Cluster-Stacks",id:"preview-cluster-stacks",level:3},{value:"Operations and IAM related",id:"operations-and-iam-related",level:3},{value:"SCS Developer focused improvements (Cloud-in-a-Box, testbed and k8s cluster management)",id:"scs-developer-focused-improvements-cloud-in-a-box-testbed-and-k8s-cluster-management",level:3},{value:"Project Infrastructure",id:"project-infrastructure",level:3},{value:"Upgrade/Migration notes",id:"upgrademigration-notes",level:2},{value:"Removals",id:"removals",level:2},{value:"Deprecations",id:"deprecations",level:2},{value:"Deprecations via OSISM",id:"deprecations-via-osism",level:3},{value:"Security Fixes",id:"security-fixes",level:2},{value:"Resolved Issues",id:"resolved-issues",level:2},{value:"Standards Conformance",id:"standards-conformance",level:2},{value:"Release Tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R5",id:"list-of-known-issues--restrictions-in-r5",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Thanks",id:"thanks",level:2}];function c(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h1,{id:"release-notes-for-scs-release-5",children:"Release Notes for SCS Release 5"}),"\n",(0,t.jsx)(s.p,{children:"(Release Date: 2023-09-20)"}),"\n",(0,t.jsx)(s.h2,{id:"scope",children:"Scope"}),"\n",(0,t.jsx)(s.p,{children:"Just as our previous release, Release 5 has been developed alongside a set of associated outcomes.\nThese outcomes are comprised of:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"SCS is standardized"}),"\n",(0,t.jsx)(s.li,{children:"SCS is understandable"}),"\n",(0,t.jsx)(s.li,{children:"SCS is transparent"}),"\n",(0,t.jsx)(s.li,{children:"SCS is continuously built and tested"}),"\n",(0,t.jsx)(s.li,{children:"SCS is opinionated"}),"\n",(0,t.jsx)(s.li,{children:"SCS enables"}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"component-versions-and-user-visible-improvements-highlights",children:"Component Versions and User-visible improvements (highlights)"}),"\n",(0,t.jsx)(s.h3,{id:"iaas",children:"IaaS"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["The IaaS reference implementation is based on ",(0,t.jsx)(s.a,{href:"https://release.osism.tech/notes/6.0.0.html",children:"OSISM 6.0.0"}),"."]}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://releases.openstack.org/antelope/highlights.html",children:"OpenStack 2023.1 (Antelope)"})}),"\n",(0,t.jsxs)(s.li,{children:["Default Ceph version is now ",(0,t.jsx)(s.a,{href:"https://docs.ceph.com/en/reef/releases/quincy/#v17-2-5-quincy",children:"Ceph Quincy"}),"."]}),"\n",(0,t.jsx)(s.li,{children:"OVN and OVS have been updated to their latest versions (OVN: 23.06.1, OVS: 3.2.0)."}),"\n",(0,t.jsx)(s.li,{children:"IPv6 east-west and north-south support is present and documented upstream."}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://github.com/osism/cloud-in-a-box",children:"Cloud-in-a-Box"})," now comes with Swift enabled as well as the option\nfor secondary NIC for external connectivity."]}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"container-management",children:"Container Management"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["The Kubernetes Cluster Management solution is ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R5.md",children:"available as version 6.0.0"})]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://github.com/kubernetes/kubernetes",children:"Kubernetes"})," v1.24 .. ",(0,t.jsx)(s.a,{href:"https://github.com/kubernetes/kubernetes/releases/tag/v1.27.6",children:"1.27"})," are officially supported. ",(0,t.jsx)(s.a,{href:"https://github.com/kubernetes/kubernetes/releases/tag/v1.28.2",children:"v1.28"})," also works (technical preview until officially supported by capo) as do older versions (with downgrading nginx-ingress), matching OCCM and CSI versions."]}),"\n",(0,t.jsx)(s.li,{children:"Cluster-API (capi) v1.5.1, Cluster-API provider for Openstack (capo) v0.7.3"}),"\n",(0,t.jsx)(s.li,{children:"The node images now use Ubuntu 22.04, the management host can use Ubuntu 22.04 or Debian 12."}),"\n",(0,t.jsx)(s.li,{children:"Cilium v1.14.1, default now, though Calico (3.26.x) is still supported."}),"\n",(0,t.jsx)(s.li,{children:"Cilium also brings the upcoming gateway API (opt-in) as technical preview."}),"\n",(0,t.jsx)(s.li,{children:"The Harbor container registry can now be rolled out with each cluster."}),"\n",(0,t.jsx)(s.li,{children:"The clusters can use a registry as cache to upstream dockerhub or gcr registries."}),"\n",(0,t.jsx)(s.li,{children:"The cluster management now works also on OpenStack clouds with a custom CA."}),"\n",(0,t.jsx)(s.li,{children:"Storage snapshots are supported now (fix was also backported to maintained branches)."}),"\n",(0,t.jsx)(s.li,{children:"Diskless flavors are supported everywhere (cluster-management, health-monitor)."}),"\n",(0,t.jsx)(s.li,{children:"etcd defragmentation and backup."}),"\n",(0,t.jsx)(s.li,{children:"Controls for pod and service IP ranges."}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"preview-cluster-stacks",children:"Preview: Cluster-Stacks"}),"\n",(0,t.jsxs)(s.p,{children:["The old scripts that are used to create, change and delete Kubernetes clusters with\nCluster API will be replaced by a proper Operator in the next release. A description can be found at the\n",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks",children:"cluster-stacks"}),"\nand ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator",children:"cluster-stack-operator"}),"\nrepositories. The technical preview can be tried with the ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks-demo",children:"cluster-stacks-demo"}),".\nThis solution will fit more nicely into the CNCF landscape and\nalso allow for easier support of IaaS solutions that do not comply to our SCS\nIaaS standards."]}),"\n",(0,t.jsx)(s.h3,{id:"operations-and-iam-related",children:"Operations and IAM related"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"A number of improvements when using identity federation via OIDC has been added, including\naddressing openstack CLI usage with PKCE Device Authz Grant, logout, and the usage of a\nproxy realm in keycloak. Improvements have been contributed to upstream keystone."}),"\n",(0,t.jsxs)(s.li,{children:["With the ",(0,t.jsx)(s.code,{children:"openstack-resource-manager"})," a new day 2 operations tool has been added.\nFurthermore an osism role for tuned to optimize system profiles is now present."]}),"\n",(0,t.jsxs)(s.li,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/osism/openstack-flavor-manager",children:"openstack-flavor-manager"})," is now able to create all standard, mandatory SCS flavors for you."]}),"\n",(0,t.jsx)(s.li,{children:"Scaphandre Prometheus Exporter has been added to export power consumption metrics more easily."}),"\n",(0,t.jsx)(s.li,{children:"To optimize system profiles an osism role for tuned is now present."}),"\n",(0,t.jsx)(s.li,{children:"Full support for air-gapped installation and operation of environments."}),"\n",(0,t.jsx)(s.li,{children:"A migration script and guide for moving from R4 to R5 clusters is available."}),"\n",(0,t.jsx)(s.li,{children:"Metering has been improved and a reference billing API implementation is available as technical preview."}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"scs-developer-focused-improvements-cloud-in-a-box-testbed-and-k8s-cluster-management",children:"SCS Developer focused improvements (Cloud-in-a-Box, testbed and k8s cluster management)"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"Documentation on testbed and Cloud-in-a-Box have been reworked."}),"\n",(0,t.jsx)(s.li,{children:"Reflecting CiaB's usage as edge cloud appliance, it now receives more automated testing."}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"project-infrastructure",children:"Project Infrastructure"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"zuul.scs.community now complements OSISM's existing zuul infrastructure and is used also\nby the container layer to execute the CNCF e2e tests."}),"\n",(0,t.jsx)(s.li,{children:"registry.scs.community has been migrated to a new IaaS location (documented in a blog\narticle) and is kept up-to-date now."}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"upgrademigration-notes",children:"Upgrade/Migration notes"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["For the IaaS reference implementation, please refer to the ",(0,t.jsx)(s.a,{href:"https://release.osism.tech/notes/6.0.0.html#upgrade-notes",children:"OSISM 6.0.0 Upgrade Notes"}),"."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"removals",children:"Removals"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["Please check the removals for OSISM in the ",(0,t.jsx)(s.a,{href:"https://release.osism.tech/notes/6.0.0.html#removals",children:"upstream removal notices"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["The services ",(0,t.jsx)(s.code,{children:"minio.services.osism.tech"})," and ",(0,t.jsx)(s.code,{children:"harbor.services.osism.tech"})," are deprecated and will be turned of on October 20th, 2023."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"deprecations",children:"Deprecations"}),"\n",(0,t.jsx)(s.h3,{id:"deprecations-via-osism",children:"Deprecations via OSISM"}),"\n",(0,t.jsxs)(s.p,{children:["For these please also refer to the ",(0,t.jsx)(s.a,{href:"https://release.osism.tech/notes/6.0.0.html#deprecations",children:"upstream deprecation notices"}),"."]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["It is again noted that the old scripts of the form ",(0,t.jsx)(s.code,{children:"osism-"})," will be removed in the future.\nA note has been added to the scripts showing this when they are executed."]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"The following services are deprecated and will be removed with R6 (OSISM 6.1.0):"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"Patchman"}),"\n",(0,t.jsx)(s.li,{children:"Adminer"}),"\n",(0,t.jsx)(s.li,{children:"Patchman Client"}),"\n",(0,t.jsx)(s.li,{children:"Virtualbmc"}),"\n",(0,t.jsx)(s.li,{children:"Bird"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"security-fixes",children:"Security Fixes"}),"\n",(0,t.jsx)(s.p,{children:"Throughout the Release 5 development cycle, the SCS project issued two security advisories for upstream components:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["In April 2023 an advisory in Open vSwitch (OvS) (",(0,t.jsx)(s.a,{href:"https://cve.report/CVE-2023-1668",children:"CVE-2023-1668"})," was issued.\nOur ",(0,t.jsx)(s.a,{href:"https://scs.community/security/2023/04/21/cve-2023-1668/",children:"advisory"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["In May 2023 an advisory affecting the OpenStack component Cinder (",(0,t.jsx)(s.a,{href:"https://cve.report/CVE-2023-2088",children:"CVE-2023-2088"}),") was issued.\nOur ",(0,t.jsx)(s.a,{href:"https://scs.community/security/2023/05/10/cve-2023-2088/",children:"advisory"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"resolved-issues",children:"Resolved Issues"}),"\n",(0,t.jsx)(s.p,{children:"Numerous minor issue have been resolved. The most important steps on the IaaS side probably being the move to ceph Quincy\nto avoid running out of upstream support. On the container side, the fix of storage snapshots is probably most significant."}),"\n",(0,t.jsxs)(s.p,{children:["For details, we again refer to the ",(0,t.jsx)(s.a,{href:"https://release.osism.tech/notes/6.0.0.html",children:"OSISM"})," and\n",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R5.md",children:"k8s-cluster-api-provider"})," release notes."]}),"\n",(0,t.jsx)(s.h2,{id:"standards-conformance",children:"Standards Conformance"}),"\n",(0,t.jsxs)(s.p,{children:["A new certification set is expected in December. It will ensure we\nrun all automated tests also for all new standards, such as\n",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0100-v3-flavor-naming.md",children:"v3 flavor naming"}),",\nand the (previously included) ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0103-v1-standard-flavors.md",children:"v1 standard flavors"})," -- which includes the ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0110-v1-ssd-flavors.md$a",children:"new SSD flavors"}),", the ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0101-v1-entropy.md",children:"v1 entropy standard"}),". We have also split image naming and standard image recommendations into ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0104-v1-standard-images.md",children:"v1 standards images"}),"."]}),"\n",(0,t.jsxs)(s.p,{children:["Requirements for ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0210-v1-k8s-new-version-policy.md",children:"k8s version recency"}),", ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0211-v1-kaas-default-storage-class.md",children:"default storage class"})," as well as requirements to the ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0212-v1-requirements-for-container-registry.md",children:"container registry"})," have been captured."]}),"\n",(0,t.jsx)(s.p,{children:"The IAM area has seen ADRs on the chosen architecture."}),"\n",(0,t.jsx)(s.p,{children:"The (design) decisions on the metering work as well as on the status page project have also been\ncaptured."}),"\n",(0,t.jsxs)(s.p,{children:["The standards and the standards compliance of our operators' clouds can be seen in the\n",(0,t.jsx)(s.a,{href:"https://docs.scs.community/standards",children:"standards section of our doc pages"})," while the raw content is developed\nand discussed in the respective ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/standards",children:"github standards repository"}),"."]}),"\n",(0,t.jsx)(s.p,{children:"The SCS reference implementation follows all approved SCS standards."}),"\n",(0,t.jsx)(s.h2,{id:"release-tagging",children:"Release Tagging"}),"\n",(0,t.jsxs)(s.p,{children:["Relevant repositories have been tagged with ",(0,t.jsx)(s.code,{children:"v6.0.0"})," tag.\nFor some repositories ",(0,t.jsx)(s.code,{children:"maintained/v6.x"})," and ",(0,t.jsx)(s.code,{children:"maintained/v6.0.x"})," branches have been created."]}),"\n",(0,t.jsx)(s.h2,{id:"list-of-known-issues--restrictions-in-r5",children:"List of known issues & restrictions in R5"}),"\n",(0,t.jsx)(s.p,{children:"Nothing that we are aware of at this point."}),"\n",(0,t.jsx)(s.h2,{id:"contributing",children:"Contributing"}),"\n",(0,t.jsxs)(s.p,{children:["We appreciate contribution to strategy and implementation, please join\nour community -- or just leave input on the github issues and PRs.\nHave a look at our ",(0,t.jsx)(s.a,{href:"https://scs.community/contribute/",children:"How to contribute page"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"thanks",children:"Thanks"}),"\n",(0,t.jsx)(s.p,{children:"Our wonderful community of integrators, operators, contractors and volunteers\nmade R5 possible. The project management team is employed by the OSB Alliance\nand we as well as the contractors are paid thanks to funding from the German\nMinistry for economic affairs and climate action. We build on top of a lot of\nexisting open source code from the CNCF, the OIF and various others and we\ntry to contribute back as much as we can."})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var t=n(96540);const i={},r=t.createContext(i);function a(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a12f05ab.abcb42fa.js b/assets/js/a12f05ab.abcb42fa.js new file mode 100644 index 0000000000..3aae9993e6 --- /dev/null +++ b/assets/js/a12f05ab.abcb42fa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3453],{71290:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>r,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var d=s(74848),i=s(28453);const o={sidebar_label:"Cinder"},r="Cinder",c={id:"iaas/guides/operations-guide/openstack/cinder",title:"Cinder",description:"Remove service",source:"@site/docs/02-iaas/guides/operations-guide/openstack/cinder.md",sourceDirName:"02-iaas/guides/operations-guide/openstack",slug:"/iaas/guides/operations-guide/openstack/cinder",permalink:"/docs/iaas/guides/operations-guide/openstack/cinder",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/cinder.md",tags:[],version:"current",frontMatter:{sidebar_label:"Cinder"},sidebar:"docs",previous:{title:"OpenStack Health Monitor",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor"},next:{title:"Keystone",permalink:"/docs/iaas/guides/operations-guide/openstack/keystone"}},t={},l=[{value:"Remove service",id:"remove-service",level:2},{value:"Sync quota",id:"sync-quota",level:2},{value:"Quality of Service (QoS)",id:"quality-of-service-qos",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.h1,{id:"cinder",children:"Cinder"}),"\n",(0,d.jsx)(n.h2,{id:"remove-service",children:"Remove service"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{children:"$ openstack --os-cloud admin volume service list\n+------------------+-----------------------------------+----------+---------+-------+----------------------------+\n| Binary | Host | Zone | Status | State | Updated At |\n+------------------+-----------------------------------+----------+---------+-------+----------------------------+\n| cinder-scheduler | testbed-node-0 | internal | enabled | up | 2023-10-01T08:53:14.000000 |\n| cinder-scheduler | testbed-node-1 | internal | enabled | up | 2023-10-01T08:53:15.000000 |\n| cinder-scheduler | testbed-node-2 | internal | enabled | up | 2023-10-01T08:53:15.000000 |\n| cinder-volume | testbed-node-0@rbd-1 | nova | enabled | down | 2023-09-30T18:50:05.000000 |\n| cinder-volume | testbed-node-2@rbd-1 | nova | enabled | down | 2023-09-30T18:50:05.000000 |\n| cinder-volume | testbed-node-1@rbd-1 | nova | enabled | down | 2023-09-30T18:50:08.000000 |\n+------------------+-----------------------------------+----------+---------+-------+----------------------------+\n"})}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{children:"$ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-0@rbd-1\nService cinder-volume on host testbed-node-0@rbd-1 removed.\n$ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-1@rbd-1\nService cinder-volume on host testbed-node-1@rbd-1 removed.\n$ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-2@rbd-1\nService cinder-volume on host testbed-node-2@rbd-1 removed.\n"})}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{children:"$ openstack --os-cloud admin volume service list\n+------------------+-----------------------------------+----------+---------+-------+----------------------------+\n| Binary | Host | Zone | Status | State | Updated At |\n+------------------+-----------------------------------+----------+---------+-------+----------------------------+\n| cinder-scheduler | testbed-node-0 | internal | enabled | up | 2023-10-01T08:56:24.000000 |\n| cinder-scheduler | testbed-node-1 | internal | enabled | up | 2023-10-01T08:56:25.000000 |\n| cinder-scheduler | testbed-node-2 | internal | enabled | up | 2023-10-01T08:56:25.000000 |\n+------------------+-----------------------------------+----------+---------+-------+----------------------------+\n"})}),"\n",(0,d.jsx)(n.h2,{id:"sync-quota",children:"Sync quota"}),"\n",(0,d.jsxs)(n.p,{children:["It can happen that more block storage usage is stored in the database for a project than\nis actually used. This can be corrected using ",(0,d.jsx)(n.a,{href:"https://docs.openstack.org/cinder/latest/cli/cinder-manage.html",children:"cinder-manage"}),"."]}),"\n",(0,d.jsx)(n.p,{children:"For all projects:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{children:"$ docker exec -it cinder_api cinder-manage quota sync\n"})}),"\n",(0,d.jsx)(n.p,{children:"Only for a specific project:"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{children:"$ docker exec -it cinder_api cinder-manage quota sync --project-id PROJECT_ID\n"})}),"\n",(0,d.jsx)(n.h2,{id:"quality-of-service-qos",children:"Quality of Service (QoS)"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.a,{href:"https://docs.openstack.org/cinder/latest/admin/basic-volume-qos.html",children:"https://docs.openstack.org/cinder/latest/admin/basic-volume-qos.html"})}),"\n"]}),"\n",(0,d.jsxs)(n.p,{children:["Create ",(0,d.jsx)(n.code,{children:"default"})," volume QoS policy that allows 1000 read IOPS and 1000 write IOPS."]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{children:"$ openstack --os-cloud admin volume qos create \\\n --consumer both \\\n --property read_iops_sec=1000 \\\n --property write_iops_sec=1000 \\\n default\n+------------+---------------------------------------------+\n| Field | Value |\n+------------+---------------------------------------------+\n| consumer | both |\n| id | 48920d26-e85f-4920-8ed4-ff8d322c77b9 |\n| name | testing |\n| properties | read_iops_sec='1000', write_iops_sec='1000' |\n+------------+---------------------------------------------+\n"})}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{children:"$ openstack --os-cloud admin volume qos list\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n| ID | Name | Consumer | Associations | Properties |\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n| 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | | read_iops_sec='1000', write_iops_sec='1000' |\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n"})}),"\n",(0,d.jsxs)(n.p,{children:["Assign the ",(0,d.jsx)(n.code,{children:"default"})," volume QoS policy to the ",(0,d.jsx)(n.code,{children:"__DEFAULT"})," volume type."]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{children:"$ openstack --os-cloud admin volume qos associate default __DEFAULT__\n"})}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{children:"$ openstack --os-cloud admin volume qos list\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n| ID | Name | Consumer | Associations | Properties |\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n| 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | __DEFAULT__ | read_iops_sec='1000', write_iops_sec='1000' |\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n"})}),"\n",(0,d.jsxs)(n.p,{children:["Change the read IOPS from 1000 to 2000 and the write IOPS from 1000 to 2000 of the ",(0,d.jsx)(n.code,{children:"default"})," volume QoS policy."]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{children:"$ openstack --os-cloud admin volume qos set \\\n --property read_iops_sec=2000 \\\n --property write_iops_sec=2000 \\\n default\n"})}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{children:"$ openstack --os-cloud admin volume qos list\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n| ID | Name | Consumer | Associations | Properties |\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n| 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | __DEFAULT__ | read_iops_sec='2000', write_iops_sec='2000' |\n+--------------------------------------+---------+----------+--------------+---------------------------------------------+\n"})}),"\n",(0,d.jsx)(n.p,{children:"The following properties are available."}),"\n",(0,d.jsx)(n.p,{children:"For Fixed IOPS per volume:"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"read_iops_sec"})}),"\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"write_iops_sec"})}),"\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"total_iops_sec"})}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"For Burst IOPS per volume:"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"read_iops_sec_max"})}),"\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"write_iops_sec_max"})}),"\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"total_iops_sec_max"})}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"For Fixed bandwidth per volume:"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"read_bytes_sec"})}),"\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"write_bytes_sec"})}),"\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"total_bytes_sec"})}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"For Burst bandwidth per volume:"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"read_bytes_sec_max"})}),"\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"write_bytes_sec_max"})}),"\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"total_bytes_sec_max"})}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"For burst bucket size:"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.code,{children:"size_iops_sec"})}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>c});var d=s(96540);const i={},o=d.createContext(i);function r(e){const n=d.useContext(o);return d.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),d.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a15c4cb6.0ac7da5c.js b/assets/js/a15c4cb6.0ac7da5c.js new file mode 100644 index 0000000000..a5914fd2a5 --- /dev/null +++ b/assets/js/a15c4cb6.0ac7da5c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1290],{69149:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var i=t(74848),o=t(28453);const a={title:"Exposition of IaaS metering data as JSON",type:"Standard",status:"Draft",track:"Ops",description:"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format\nwithin the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with\ntheir existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format\nprovided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation\nlayers and implementation components.\n"},s=void 0,r={id:"scs-0412-v1-metering-json",title:"Exposition of IaaS metering data as JSON",description:"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format\nwithin the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with\ntheir existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format\nprovided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation\nlayers and implementation components.\n",source:"@site/standards/scs-0412-v1-metering-json.md",sourceDirName:".",slug:"/scs-0412-v1-metering-json",permalink:"/standards/scs-0412-v1-metering-json",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Exposition of IaaS metering data as JSON",type:"Standard",status:"Draft",track:"Ops",description:"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format\nwithin the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with\ntheir existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format\nprovided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation\nlayers and implementation components.\n"},sidebar:"standards",previous:{title:"scs-0412: Exposition of IaaS metering data as JSON",permalink:"/standards/ops/scs-0412"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Use Ceilometer HTTP hook format",id:"use-ceilometer-http-hook-format",level:4},{value:"Use another format",id:"use-another-format",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const n={em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"The Sovereign Cloud Stack project intends to standardise an infrastructure-as-a-service (IaaS) layer.\nIn order to economically sustainably run a cloud,\nit is generally useful to know which user or tenant consumes which amount of resources in which time frame."}),"\n",(0,i.jsx)(n.p,{children:"Similarly to how the SCS provides an interface for connecting monitoring services to detect outages,\nthis standard aims for providing an interface for connecting systems which aggregate customer resource usage."}),"\n",(0,i.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(n.p,{children:"In general,\nusers of the SCS (i.e. cloud operators) may already have different systems in place\nfor tracking customer relationships\nas well as billing."}),"\n",(0,i.jsx)(n.p,{children:"Those systems are unlikely to have a uniform interface across all possible implementations.\nLikewise, those systems are unlikely to have a way to interface with OpenStack,\nthe reference IaaS layer in SCS."}),"\n",(0,i.jsx)(n.p,{children:"In order to provide SCS operators with a way to integrate the SCS IaaS layer with their billing,\nthis document shall provide a standard format,\nupon which shim conversion layers (to whichever billing system is in place)\ncan be built."}),"\n",(0,i.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsx)(n.p,{children:"In order to define a standard,\nthe various options for formats need to be considered.\nHowever, all formats also come with different implementation costs."}),"\n",(0,i.jsx)(n.p,{children:"These aspects are weighed in this section."}),"\n",(0,i.jsx)(n.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,i.jsx)(n.h4,{id:"use-ceilometer-http-hook-format",children:"Use Ceilometer HTTP hook format"}),"\n",(0,i.jsx)(n.p,{children:"The OpenStack Ceilometer project,\nwhich serves as a hub for all things telemetry and metering,\nprovides an HTTP-based hook to extract metering data.\nThis hook receives JSON-formatted data."}),"\n",(0,i.jsx)(n.p,{children:"Using this data has the advantage\nthat we do not need to implement another component to translate the format\nwhich may in turn be a point of failure."}),"\n",(0,i.jsx)(n.h4,{id:"use-another-format",children:"Use another format"}),"\n",(0,i.jsx)(n.p,{children:"In this option,\na format for metering data is researched and reused, or defined and specified by the SCS project."}),"\n",(0,i.jsx)(n.p,{children:"This option was not explored deeply, for the reasons explained in the decision."}),"\n",(0,i.jsx)(n.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,i.jsx)(n.p,{children:"None."}),"\n",(0,i.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(n.p,{children:"We chose the Ceilometer HTTP hook format, described below, for the following reasons:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ceilometer is a component which needs to be there anyway for successful metering of OpenStack. Re-using the format makes sense."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Using any other format requires a translation layer. However, users will likely need their own translation layer ",(0,i.jsx)(n.em,{children:"anyway"}),", to integrate the metering with their own infrastructure. Hence, it makes more sense to expose the data from Ceilometer directly."]}),"\n",(0,i.jsx)(n.p,{children:"A notable downside of this approach is that a change in Ceilometers format will inevitably cause issues in all downstream consumers."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"SCS-0410-v1"}),"\n",(0,i.jsx)(n.li,{children:"SCS-0411-v1"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,i.jsx)(n.p,{children:"None."})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>r});var i=t(96540);const o={},a=i.createContext(o);function s(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a2317717.a9b8ac04.js b/assets/js/a2317717.a9b8ac04.js new file mode 100644 index 0000000000..a39c54d97a --- /dev/null +++ b/assets/js/a2317717.a9b8ac04.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3400],{74782:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>a,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var n=i(74848),o=i(28453);const r={sidebar_label:"Chrony"},t="Chrony",c={id:"iaas/guides/configuration-guide/services/chrony",title:"Chrony",description:"With the osism.services.chrony role, it is possible to manage the used NTP servers on a node.",source:"@site/docs/02-iaas/guides/configuration-guide/services/chrony.md",sourceDirName:"02-iaas/guides/configuration-guide/services",slug:"/iaas/guides/configuration-guide/services/chrony",permalink:"/docs/iaas/guides/configuration-guide/services/chrony",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/services/chrony.md",tags:[],version:"current",frontMatter:{sidebar_label:"Chrony"},sidebar:"docs",previous:{title:"Services",permalink:"/docs/iaas/guides/configuration-guide/services/"},next:{title:"Docker",permalink:"/docs/iaas/guides/configuration-guide/services/docker"}},a={},d=[];function u(e){const s={code:"code",h1:"h1",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"chrony",children:"Chrony"}),"\n",(0,n.jsxs)(s.p,{children:["With the ",(0,n.jsx)(s.code,{children:"osism.services.chrony"})," role, it is possible to manage the used NTP servers on a node.\nIt is also possible to configure the Chrony service for use inside the cluster."]})]})}function h(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,s,i)=>{i.d(s,{R:()=>t,x:()=>c});var n=i(96540);const o={},r=n.createContext(o);function t(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a24f5044.95e7fbd3.js b/assets/js/a24f5044.95e7fbd3.js new file mode 100644 index 0000000000..a6b7081d84 --- /dev/null +++ b/assets/js/a24f5044.95e7fbd3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9755],{45103:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>p,frontMatter:()=>o,metadata:()=>r,toc:()=>l});var i=t(74848),s=t(28453);const o={title:"_Descriptive title_",type:"Standard",status:"Draft",track:"Global"},d=void 0,r={id:"scs-XXXX-vN-standard-template",title:"_Descriptive title_",description:"\x3c!---",source:"@site/standards/scs-XXXX-vN-standard-template.md",sourceDirName:".",slug:"/scs-XXXX-vN-standard-template",permalink:"/standards/scs-XXXX-vN-standard-template",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"_Descriptive title_",type:"Standard",status:"Draft",track:"Global"}},a={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"<em>Option 1</em>",id:"option-1",level:4},{value:"<em>Option 2</em>",id:"option-2",level:4},{value:"Open questions",id:"open-questions",level:3},{value:"Standard",id:"standard",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const n={em:"em",h2:"h2",h3:"h3",h4:"h4",p:"p",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"Introduction"}),"\n",(0,i.jsx)(n.h2,{id:"terminology",children:"Terminology"}),"\n",(0,i.jsx)(n.p,{children:"Example (abbr. Ex)\nThis is the description for an example terminology."}),"\n",(0,i.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(n.p,{children:"Motivation"}),"\n",(0,i.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsx)(n.p,{children:"OPTIONAL"}),"\n",(0,i.jsx)(n.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,i.jsx)(n.h4,{id:"option-1",children:(0,i.jsx)(n.em,{children:"Option 1"})}),"\n",(0,i.jsx)(n.p,{children:"Option 1 description"}),"\n",(0,i.jsx)(n.h4,{id:"option-2",children:(0,i.jsx)(n.em,{children:"Option 2"})}),"\n",(0,i.jsx)(n.p,{children:"Option 2 description"}),"\n",(0,i.jsx)(n.h3,{id:"open-questions",children:"Open questions"}),"\n",(0,i.jsx)(n.p,{children:"RECOMMENDED"}),"\n",(0,i.jsx)(n.h2,{id:"standard",children:"Standard"}),"\n",(0,i.jsx)(n.p,{children:"What is the essence of this standard? Adjust heading accordingly."}),"\n",(0,i.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,i.jsx)(n.p,{children:"Related Documents, OPTIONAL"}),"\n",(0,i.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,i.jsx)(n.p,{children:"Conformance Tests, OPTIONAL"})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>r});var i=t(96540);const s={},o=i.createContext(s);function d(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a35d3433.13bf18b8.js b/assets/js/a35d3433.13bf18b8.js new file mode 100644 index 0000000000..1d8c846868 --- /dev/null +++ b/assets/js/a35d3433.13bf18b8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[123],{32451:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var s=i(74848),t=i(28453);const r={title:"Requirements for container registries",type:"Standard",status:"Draft",track:"KaaS"},a=void 0,o={id:"scs-0212-v1-requirements-for-container-registries",title:"Requirements for container registries",description:"Introduction",source:"@site/standards/scs-0212-v1-requirements-for-container-registries.md",sourceDirName:".",slug:"/scs-0212-v1-requirements-for-container-registries",permalink:"/standards/scs-0212-v1-requirements-for-container-registries",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Requirements for container registries",type:"Standard",status:"Draft",track:"KaaS"},sidebar:"standards",previous:{title:"scs-0212: Requirements for container registries",permalink:"/standards/kaas/scs-0212"},next:{title:"scs-0213: Kubernetes Nodes Anti Affinity",permalink:"/standards/kaas/scs-0213"}},l={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design considerations",id:"design-considerations",level:2},{value:"OSS health check",id:"oss-health-check",level:3},{value:"Required and desirable features check",id:"required-and-desirable-features-check",level:3},{value:"Required features",id:"required-features",level:4},{value:"Desirable features",id:"desirable-features",level:4},{value:"Standard",id:"standard",level:2},{value:"Related Documents",id:"related-documents",level:2}];function d(e){const n={a:"a",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"A container registry is an infrastructure service to enable storing and accessing container\nimages. Images can be pushed to the registry by e.g. Continuous integration pipelines and\nbe pulled from by runtime environments like Kubernetes clusters."}),"\n",(0,s.jsx)(n.p,{children:"Container registries come in various forms, e.g. publicly accessible ones like Docker Hub or\nself-hosted and cloud-hosted services. The latter examples may apply various access control\nmechanisms to restrict access. Both solutions offer a wide range of features that may or may not\nattract potential users and CSPs."}),"\n",(0,s.jsx)(n.h2,{id:"terminology",children:"Terminology"}),"\n",(0,s.jsx)(n.p,{children:"Cloud Service Provider (abbr. CSP)\nEntity that provides scalable computing resources"}),"\n",(0,s.jsx)(n.p,{children:"Identity Provider (abbr. IdP)\nSystem that creates, maintains, and manages identity information"}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(n.p,{children:'This standard is motivated by different use cases identified through the topics in the SCS project.\nOne use case would be the offering of private registries for customers by CSPs, which means that a CSP could\noffer private container registries either as a service or as a provided "recipe" to deploy a private registry\nutilizing the CSPs infrastructure.\nAnother use case would be the selection of a registry for the SCS reference implementation.'}),"\n",(0,s.jsx)(n.p,{children:"The idea and purpose of this document is to specify what requirements a specific technical container\nregistry implementation (i.e. software solution) needs to fulfill for an SCS-compliant registry."}),"\n",(0,s.jsx)(n.h2,{id:"design-considerations",children:"Design considerations"}),"\n",(0,s.jsx)(n.p,{children:"There are numerous features that should be evaluated for a container registry solution.\nIt is important to assess the registries based on the requirements of the OSS health checks and\ndesired features defined by the SCS. The following two subsections show these requirements."}),"\n",(0,s.jsx)(n.h3,{id:"oss-health-check",children:"OSS health check"}),"\n",(0,s.jsxs)(n.p,{children:["It is important to evaluate the health of a project before even evaluating the project for its feature set.\nA project should therefore fulfill all OSS health checks be defined by the\n",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Drafts/OSS-Health.md",children:"OSS-Health"})," document.\nThis document evaluates the health of the open-source projects that were selected from\nthe currently available solutions. The container registry software must fulfill all OSS\nhealth checks defined below:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Four Opens (code is fully open source, community is open and diverse, development process is open, design process is open)"}),"\n",(0,s.jsx)(n.li,{children:"Maturity"}),"\n",(0,s.jsx)(n.li,{children:"Security"}),"\n",(0,s.jsx)(n.li,{children:"Activity"}),"\n",(0,s.jsx)(n.li,{children:"Lock-in risk assessment"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"required-and-desirable-features-check",children:"Required and desirable features check"}),"\n",(0,s.jsx)(n.p,{children:"A container registry provides a specific feature set, which can be mapped out against the requirements\ndescribed in this section. The registry should generally be robust (e.g. operate under heavy load) and\nsecure in order to be acceptable for the SCS standard. Therefore, a required and optional feature set\nwere defined, to which a container registry must abide and be evaluated against."}),"\n",(0,s.jsx)(n.h4,{id:"required-features",children:"Required features"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Audit Logs","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"ability to record use in auditable logs so that activity can be traced to a single user"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Authentication of system identities","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"support for authenticating system identities like Kubernetes clusters"}),"\n",(0,s.jsx)(n.li,{children:"possibly support for dynamic identity tokens from some IdP"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Authentication of users","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"support for multiple authentication systems (IdM integration)"}),"\n",(0,s.jsx)(n.li,{children:"user and user account management"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Authorization","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"role-based access control to ensure strict access controls"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Automation","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"integration with CI/CD tools e.g. via webhooks"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Vulnerability scanning","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"reveal security vulnerabilities in container images"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Content Trust and Validation","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"verify image authenticity before running"}),"\n",(0,s.jsx)(n.li,{children:"image signing"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Multi-tenancy","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"container registry is able to serve multiple tenants (projects, teams, namespaces)"}),"\n",(0,s.jsxs)(n.li,{children:["implementation on the storage level, see e.g. ",(0,s.jsx)(n.a,{href:"https://github.com/sapcc/keppel#overview",children:"Keppel"}),", which uses\nmulti-tenant-aware storage drivers"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Backup and restore","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"possible strategies for disaster recovery and data migration scenarios"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Monitoring","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"observability is a key feature for operating a service in production so the container registry should expose key metrics"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["HA mode","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"enable the possibility of system uptime, even if a failure of some sort could occur"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Registry replication","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"replication allows users to replicate container images between registries of the same instances and between registries of different instances as well"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Proxy cache (pull-through cache)","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Proxy cache enables the use of a container registry to proxy and cache images from a target public or private registry"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Quota management","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"ability to control resource use of components or the whole registry"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Garbage collection","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"removing blobs from the filesystem when they are no longer referenced by a manifest"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Retention policy","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"reduce the number of image tags, many of which might not be required after a given time or once a subsequent image tag has superseded them"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"desirable-features",children:"Desirable features"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Additionally supported artifacts","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Additional artifacts that the registry is able to store in addition to OCI artifacts, e.g. Java, Node.js, or Python packages"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Integration possibilities","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Ability to cooperate with another software solution in order to improve own feature set (e.g. integration of P2P solution for improving container image distribution (download speed and stability, high scalability, ...))"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Deployment capabilities","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:'ways to deploy a container registry (only "official" ways are mentioned)'}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:['Administration capabilities "as a code"',"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:'ability to manage container registry via "as a code" solutions, e.g. Ansible role'}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"standard",children:"Standard"}),"\n",(0,s.jsx)(n.p,{children:"It is very unlikely, that every Container registry can fulfill every requirement defined by this document, and probably\nnot all deployments require every feature listed here. The required feature set should therefore be carefully considered\nby the provider of the registry. We nevertheless RECOMMEND using most of the feature set provided in this document."}),"\n",(0,s.jsx)(n.p,{children:"If the features mentioned above are all considered, a possible registry solution SHOULD fulfill the majority of\nthe required features. But this is again dependent on the specific use case and the surrounding architecture."}),"\n",(0,s.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Drafts/OSS-Health.md",children:"OSS-Health"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>o});var s=i(96540);const t={},r=s.createContext(t);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a38b6a75.17b79818.js b/assets/js/a38b6a75.17b79818.js new file mode 100644 index 0000000000..a128801a12 --- /dev/null +++ b/assets/js/a38b6a75.17b79818.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3782],{7665:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var t=s(74848),o=s(28453);const i={},c="Makefile reference",a={id:"container/components/k8s-cluster-api-provider/doc/make-reference",title:"Makefile reference",description:"This is a reference to the Makefile targets.",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/make-reference.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc",slug:"/container/components/k8s-cluster-api-provider/doc/make-reference",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/make-reference",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/make-reference.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Quickstart",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/quickstart"},next:{title:"Application Credentials",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/application-credentials"}},r={},l=[{value:"General commands",id:"general-commands",level:2},{value:"make create",id:"make-create",level:3},{value:"make get-kubeconfig",id:"make-get-kubeconfig",level:3},{value:"make ssh",id:"make-ssh",level:3},{value:"make openstack",id:"make-openstack",level:3},{value:"make k9s",id:"make-k9s",level:3},{value:"make log",id:"make-log",level:3},{value:"make console",id:"make-console",level:3},{value:"make deploy-cso",id:"make-deploy-cso",level:3},{value:"make deploy-cspo",id:"make-deploy-cspo",level:3},{value:"Teardown",id:"teardown",level:2},{value:"Make clean",id:"make-clean",level:3},{value:"Make fullclean",id:"make-fullclean",level:3},{value:"Make purge",id:"make-purge",level:3},{value:"Testing commands",id:"testing-commands",level:2},{value:"make check",id:"make-check",level:3},{value:"make check-quick",id:"make-check-quick",level:3},{value:"make check-conformance",id:"make-check-conformance",level:3},{value:"make check-storage",id:"make-check-storage",level:3},{value:"make check-csi",id:"make-check-csi",level:3},{value:"OpenTofu commands",id:"opentofu-commands",level:2},{value:"make init",id:"make-init",level:3},{value:"make attach",id:"make-attach",level:3},{value:"make detach",id:"make-detach",level:3},{value:"make state-push",id:"make-state-push",level:3},{value:"make dry-run",id:"make-dry-run",level:3},{value:"make show",id:"make-show",level:3},{value:"make list",id:"make-list",level:3}];function h(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",p:"p",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"makefile-reference",children:"Makefile reference"}),"\n",(0,t.jsx)(n.p,{children:"This is a reference to the Makefile targets."}),"\n",(0,t.jsxs)(n.p,{children:["Almost all targets require the ",(0,t.jsx)(n.code,{children:"ENVIRONMENT"})," variable to be set to the name of the environment you want to use.\n(See ",(0,t.jsx)(n.a,{href:"/docs/container/components/k8s-cluster-api-provider/doc/requirements#environments",children:"Environments"})," in the requirements documentation for more information.)"]}),"\n",(0,t.jsx)(n.h2,{id:"general-commands",children:"General commands"}),"\n",(0,t.jsx)(n.h3,{id:"make-create",children:"make create"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make create"})}),"\n",(0,t.jsx)(n.p,{children:"To initiate the management server setup, various components are created. This includes the provisioning of networks,\nsecurity groups, and a virtual machine. An application credential is also generated for authentication purposes. Once\nthe virtual machine is up and running, it is bootstrapped by cloning the specified git repository. Additionally,\nspecific tools are installed to facilitate the process."}),"\n",(0,t.jsxs)(n.p,{children:["Next, a local Kubernetes cluster is deployed using ",(0,t.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/kind",children:"kind"}),". The cluster acts as a foundation for further operations. During\nthe setup, the ",(0,t.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api",children:"Cluster API"}),", as well as the Cluster API Provider (e.g. ",(0,t.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api-provider-openstack",children:"CAPO"}),"), are installed within the local cluster. This provider serves as the API server for\nKubernetes CAPI, enabling management and interaction with the cloud backends (e.g. OpenStack)."]}),"\n",(0,t.jsx)(n.p,{children:"Finally, a test cluster is created utilizing Kubernetes CAPI. This test cluster allows for experimentation, validation,\nand development within the CAPI environment."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["Note that ",(0,t.jsx)(n.code,{children:"make create"})," will not create a testcluster if you have set ",(0,t.jsx)(n.code,{children:"controller_count"})," to zero in your\nenvironment file (",(0,t.jsx)(n.code,{children:"environment-<yourcloud>.tfvars"}),")."]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["Note that ",(0,t.jsx)(n.code,{children:"make create"})," does not copy local files to the management server, only some files are templated there from the ",(0,t.jsx)(n.code,{children:"terraform/files/template"})," directory. If you want to change any of the scripts\nbeing copied to the management server, you need to commit, push your changes, and run ",(0,t.jsx)(n.code,{children:"make create"})," again.\n",(0,t.jsx)(n.code,{children:"make create"})," will pull the latest changes from the git repository."]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"make-get-kubeconfig",children:"make get-kubeconfig"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make get-kubeconfig"})}),"\n",(0,t.jsxs)(n.p,{children:["This will get the kubeconfig of the testcluster and store it in the file ",(0,t.jsx)(n.code,{children:"testcluster.yaml.<yourcloud>"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"make-ssh",children:"make ssh"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make ssh"})}),"\n",(0,t.jsxs)(n.p,{children:["This will ssh into the management server, using the username that was set in your ",(0,t.jsx)(n.code,{children:"environment-<yourcloud>.tfvars"}),"file. The default in the environment file is ",(0,t.jsx)(n.code,{children:"ubuntu"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["Note: there is also an alias to this ",(0,t.jsx)(n.code,{children:"make login"})]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"make-openstack",children:"make openstack"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make openstack"})}),"\n",(0,t.jsx)(n.p,{children:"This will run openstack cli."}),"\n",(0,t.jsx)(n.h3,{id:"make-k9s",children:"make k9s"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make k9s"})}),"\n",(0,t.jsx)(n.p,{children:"This will run k9s on the management server."}),"\n",(0,t.jsx)(n.h3,{id:"make-log",children:"make log"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make log CONSOLE=capi-mgmtcluster"})}),"\n",(0,t.jsxs)(n.p,{children:["This will show openstack console log of the management server. You can specify the console log you want to see by\nsetting the ",(0,t.jsx)(n.code,{children:"CONSOLE"})," variable. The default is ",(0,t.jsx)(n.code,{children:"capi-mgmtcluster"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"make-console",children:"make console"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make console CONSOLE=capi-mgmtcluster"})}),"\n",(0,t.jsxs)(n.p,{children:["This will open openstack console of the management server in the browser using XDG-open. You can specify the console you\nwant to open by setting the ",(0,t.jsx)(n.code,{children:"CONSOLE"})," variable. The default is ",(0,t.jsx)(n.code,{children:"capi-mgmtcluster"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"make-deploy-cso",children:"make deploy-cso"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make deploy-cso"})}),"\n",(0,t.jsxs)(n.p,{children:["This will deploy the ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator",children:"cluster-stack-operator"}),". The preconfigured repo to look for cluster-stacks is ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks/",children:"https://github.com/SovereignCloudStack/cluster-stacks/"}),".\n",(0,t.jsx)(n.code,{children:"GIT_ACCESS_TOKEN"})," can be specified."]}),"\n",(0,t.jsx)(n.h3,{id:"make-deploy-cspo",children:"make deploy-cspo"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make deploy-cspo"})}),"\n",(0,t.jsxs)(n.p,{children:["This will deploy the ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-provider-openstack",children:"cluster-stack-provider-openstack"}),". The preconfigured repo to look for cluster-stacks is ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks/",children:"https://github.com/SovereignCloudStack/cluster-stacks/"}),".\n",(0,t.jsx)(n.code,{children:"GIT_ACCESS_TOKEN"})," can be specified."]}),"\n",(0,t.jsx)(n.h2,{id:"teardown",children:"Teardown"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["Note that ",(0,t.jsx)(n.code,{children:"clean"})," and ",(0,t.jsx)(n.code,{children:"fullclean"})," leave the ",(0,t.jsx)(n.code,{children:"ubuntu-capi-image-$KUBERNETES_VERSION"})," image registered,\nso it can be reused.\nYou need to manually unregister it, if you want your next deployment to register a new image with\nthe same kubernetes version number."]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"make-clean",children:"Make clean"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"make clean"})," does ssh to the capi management server to clean up the created clusters prior\nto opentofu cleaning up the resources it has created. This is sometimes insufficient to clean up\nunfortunately, some error in the deployment may result in resources left around."]}),"\n",(0,t.jsx)(n.h3,{id:"make-fullclean",children:"Make fullclean"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"make fullclean"})," uses a custom script ",(0,t.jsx)(n.code,{children:"cleanup/cleanup.sh"})," (using the openstack CLI) to clean up\neverything while trying to not hit any resources not created by the CAPI or opentofu for\nclusters from this management host.\nIt is the recommended way for doing cleanups if ",(0,t.jsx)(n.code,{children:"make clean"})," fails. Watch out for leftover\nfloating IP addresses and persistent volumes, as these can not be easily traced back to the\nCluster API created resources and may thus be left. There is also a ",(0,t.jsx)(n.code,{children:"make forceclean"})," variant\nthat hits unused floating IPs and all persistent volumes -- this is risky as there is no good\nway to tell which PVCs belong to us unless we find them attached to cluster nodes in which\ncase we don't need the force options."]}),"\n",(0,t.jsx)(n.h3,{id:"make-purge",children:"Make purge"}),"\n",(0,t.jsxs)(n.p,{children:["You can purge the whole project via ",(0,t.jsx)(n.code,{children:"make purge"}),". Be careful with that command as it will purge\n",(0,t.jsx)(n.em,{children:"all resources in the OpenStack project"})," even those that have not been created through this\nOpenTofu script or the Cluster API.\nIt requires the ",(0,t.jsx)(n.a,{href:"https://opendev.org/x/ospurge",children:(0,t.jsx)(n.code,{children:"ospurge"})})," tool.\nInstall it with ",(0,t.jsx)(n.code,{children:"python3 -m pip install git+https://git.openstack.org/openstack/ospurge"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"testing-commands",children:"Testing commands"}),"\n",(0,t.jsx)(n.h3,{id:"make-check",children:"make check"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make check SONOMODE=..."})}),"\n",(0,t.jsxs)(n.p,{children:["This will run tests of the configuration on testcluster using ",(0,t.jsx)(n.a,{href:"https://sonobuoy.io/",children:"sonobuoy"}),". It will also download the results and\nprint them to the console. Optionally you can also specify a mode by using for example ",(0,t.jsx)(n.code,{children:'SONOMODE="--mode quick"'})]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Note: This runs over 5000 tests and takes a long time to complete (~ 2 hours)."}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"make-check-quick",children:"make check-quick"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make check-quick"})}),"\n",(0,t.jsx)(n.p,{children:"This will run tests of the configuration on testcluster using sonobuoy with mode quick."}),"\n",(0,t.jsx)(n.h3,{id:"make-check-conformance",children:"make check-conformance"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make check-conformance"})}),"\n",(0,t.jsx)(n.p,{children:"This will run tests of the configuration on testcluster using sonobuoy with mode conformance meaning it will test if the\ncluster is conformant to the CNCF."}),"\n",(0,t.jsx)(n.h3,{id:"make-check-storage",children:"make check-storage"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make check-storage"})}),"\n",(0,t.jsx)(n.p,{children:"This will run tests of the configuration on testcluster using sonobuoy of the storage."}),"\n",(0,t.jsx)(n.h3,{id:"make-check-csi",children:"make check-csi"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make check-csi"})}),"\n",(0,t.jsx)(n.p,{children:"This will run tests of the configuration on testcluster using sonobuoy of the CSI."}),"\n",(0,t.jsx)(n.h2,{id:"opentofu-commands",children:"OpenTofu commands"}),"\n",(0,t.jsx)(n.h3,{id:"make-init",children:"make init"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make init"})}),"\n",(0,t.jsxs)(n.p,{children:["This will initialize opentofu. It will download the required providers and modules.\nIt will also select or create a new workspace for you. The workspace name is the same as the\n",(0,t.jsx)(n.code,{children:"ENVIROMENT"})," variable."]}),"\n",(0,t.jsx)(n.h3,{id:"make-attach",children:"make attach"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make attach RESOURCE=<resource-id> PARAMS=..."})}),"\n",(0,t.jsx)(n.p,{children:"This will attach a resource to the opentofu state. This is useful if you have created a resource outside of opentofu\nand want to manage it with opentofu."}),"\n",(0,t.jsx)(n.h3,{id:"make-detach",children:"make detach"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make detach RESOURCE=<resource-id> PARAMS=..."})}),"\n",(0,t.jsx)(n.p,{children:"This will detach a resource from the opentofu state. This is useful if you have changed a resource outside of opentofu\nor you no longer want to manage it with opentofu."}),"\n",(0,t.jsx)(n.h3,{id:"make-state-push",children:"make state-push"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make state-push"})}),"\n",(0,t.jsx)(n.p,{children:"This will push the opentofu state to specified storage if set. This is useful if you don't want to store the state\nlocally."}),"\n",(0,t.jsx)(n.h3,{id:"make-dry-run",children:"make dry-run"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make dry-run"})}),"\n",(0,t.jsx)(n.p,{children:"This will run a dry-run of the opentofu apply command. This is useful if you want to see what opentofu will do before\nactually doing it."}),"\n",(0,t.jsx)(n.h3,{id:"make-show",children:"make show"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make show"})}),"\n",(0,t.jsx)(n.p,{children:"This will show the opentofu state. This is useful if you want to see what opentofu is managing."}),"\n",(0,t.jsx)(n.h3,{id:"make-list",children:"make list"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make list"})}),"\n",(0,t.jsx)(n.p,{children:"This will list all the resources managed by opentofu. This is useful if you want to see what opentofu is managing."})]})}function d(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>a});var t=s(96540);const o={},i=t.createContext(o);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a3dd9468.2b30eec9.js b/assets/js/a3dd9468.2b30eec9.js new file mode 100644 index 0000000000..a83a2d224c --- /dev/null +++ b/assets/js/a3dd9468.2b30eec9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6018],{57343:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>o,contentTitle:()=>i,default:()=>u,frontMatter:()=>c,metadata:()=>d,toc:()=>a});var r=t(74848),n=t(28453);const c={},i="scs-0113: Security Groups Decision Record",d={id:"iaas/scs-0113",title:"scs-0113: Security Groups Decision Record",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/iaas/scs-0113.md",sourceDirName:"iaas",slug:"/iaas/scs-0113",permalink:"/standards/iaas/scs-0113",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Decisions for the Volume Type Standard",permalink:"/standards/scs-0111-v1-volume-type-decisions"},next:{title:"Security Groups Decision Record",permalink:"/standards/scs-0113-v1-security-groups-decision-record"}},o={},a=[];function l(e){const s={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h1,{id:"scs-0113-security-groups-decision-record",children:"scs-0113: Security Groups Decision Record"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Version"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"State"}),(0,r.jsx)(s.th,{children:"stabilized"}),(0,r.jsx)(s.th,{children:"deprecated"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.a,{href:"/standards/scs-0113-v1-security-groups-decision-record",children:"scs-0113-v1"})}),(0,r.jsx)(s.td,{children:"Decision Record"}),(0,r.jsx)(s.td,{children:"Draft"}),(0,r.jsx)(s.td,{children:"-"}),(0,r.jsx)(s.td,{children:"-"})]})})]})]})}function u(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>d});var r=t(96540);const n={},c=r.createContext(n);function i(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a3e11933.b1d84099.js b/assets/js/a3e11933.b1d84099.js new file mode 100644 index 0000000000..47d6c4965c --- /dev/null +++ b/assets/js/a3e11933.b1d84099.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9657],{20812:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var t=s(74848),o=s(28453);const i={},a="Release Notes for SCS Release 1",r={id:"releases/Release1",title:"Release Notes for SCS Release 1",description:"(Release Date: 2021-09-29)",source:"@site/docs/06-releases/Release1.md",sourceDirName:"06-releases",slug:"/releases/Release1",permalink:"/docs/releases/Release1",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/06-releases/Release1.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Release Notes for SCS Release 0",permalink:"/docs/releases/Release0"},next:{title:"Release Notes for SCS Release 2",permalink:"/docs/releases/Release2"}},l={},d=[{value:"Scope",id:"scope",level:2},{value:"CI framework",id:"ci-framework",level:2},{value:"Zuul-CI",id:"zuul-ci",level:3},{value:"Metrics collection and dashboards",id:"metrics-collection-and-dashboards",level:2},{value:"Prometheus exporters and Grafana dashboards",id:"prometheus-exporters-and-grafana-dashboards",level:3},{value:"openstack-health-monitor",id:"openstack-health-monitor",level:3},{value:"Logging",id:"logging",level:2},{value:"Central logging",id:"central-logging",level:3},{value:"Federation",id:"federation",level:2},{value:"OIDC support via keycloak",id:"oidc-support-via-keycloak",level:3},{value:"non-TLS restrictions (testbed)",id:"non-tls-restrictions-testbed",level:3},{value:"Known Issue with OIDC Logout",id:"known-issue-with-oidc-logout",level:3},{value:"Bare Metal Service",id:"bare-metal-service",level:2},{value:"Container Layer",id:"container-layer",level:2},{value:"Overview and Goals for R1",id:"overview-and-goals-for-r1",level:3},{value:"Beyond CAPI",id:"beyond-capi",level:3},{value:"Standardization",id:"standardization",level:2},{value:"SBOM and Links",id:"sbom-and-links",level:2},{value:"Release tagging",id:"release-tagging",level:2},{value:"List of known issues & restrictions in R1",id:"list-of-known-issues--restrictions-in-r1",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"release-notes-for-scs-release-1",children:"Release Notes for SCS Release 1"}),"\n",(0,t.jsx)(n.p,{children:"(Release Date: 2021-09-29)"}),"\n",(0,t.jsx)(n.h2,{id:"scope",children:"Scope"}),"\n",(0,t.jsx)(n.p,{children:"Main goals for Release 1 (R1) was the strengthening of our CI test coverage and\nintegration, the operational tooling (metrics collection, dashboards, logging),\nlatest versions of upstream software (OpenStack Wallaby, Kubernetes-1.21.5),\nsupport for Bare Metal service, progress on user federation for clouds, and\nprogress on the integration of the container layer with k8s Cluster API (now in\nversion 0.4.x)."}),"\n",(0,t.jsx)(n.h2,{id:"ci-framework",children:"CI framework"}),"\n",(0,t.jsx)(n.h3,{id:"zuul-ci",children:"Zuul-CI"}),"\n",(0,t.jsxs)(n.p,{children:["For our internal development workflows we are planning to switch from GitHub\nActions to Zuul-CI (mostly). The infrastructure itself is already available,\nyet most of the repositories in the SovereignCloudStack organisation have not\nswitched over. Reasons for switching include cross-dependencies, scalability\nand costs. Reasons for using Zuul-CI include the close connection to the\nOpenStack project and the enormous flexibility in comparison to other similar\ntools. On top of that you have also gating instead of only CI. A quick example\nfor a Zuul-CI operated repository can be found here:\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/zuul-sandbox",children:"https://github.com/SovereignCloudStack/zuul-sandbox"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"metrics-collection-and-dashboards",children:"Metrics collection and dashboards"}),"\n",(0,t.jsx)(n.h3,{id:"prometheus-exporters-and-grafana-dashboards",children:"Prometheus exporters and Grafana dashboards"}),"\n",(0,t.jsxs)(n.p,{children:["We provide generic configuration examples and blueprints for prometheus rules\nand grafana dashboards. The examples need to be understood and adapted to the\nparticular needs of your environment. You can find the examples at\n",(0,t.jsx)(n.a,{href:"https://github.com/osism/kolla-operations",children:"https://github.com/osism/kolla-operations"}),"]."]}),"\n",(0,t.jsx)(n.p,{children:"With R2 we plan to implement a basic set of these alerts and dashboards in the\ntestbed deployment in order to make them even easier consumable for new users.\nFeel free to give feedback on the examples and contribute your own generic\nexamples."}),"\n",(0,t.jsx)(n.p,{children:"We're working on bringing a basic set of prometheus exporters to the\nOpenStack-kolla upstream community."}),"\n",(0,t.jsxs)(n.p,{children:["As part of our effort to add more monitoring tooling, we're integrating further\nprometheus exporters such as\n",(0,t.jsx)(n.a,{href:"https://review.opendev.org/c/openstack/kolla-ansible/+/643568",children:"libvirt"})," and\n",(0,t.jsx)(n.a,{href:"https://review.opendev.org/c/openstack/kolla/+/762986",children:"ovn"}),". Integration is\ntargeted for R2."]}),"\n",(0,t.jsxs)(n.p,{children:["More detailed information on monitoring topics will be continously provided in\nthe ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/monitoring.md",children:"corresponding design document"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"openstack-health-monitor",children:"openstack-health-monitor"}),"\n",(0,t.jsx)(n.p,{children:"We have made some progress with openstack-health-monitor since R0, but we have\nnot yet created ready-to-be-used influx data collection and the grafana\ndashboard. While the black box monitoring is perceived as very useful, the\nscript certainly has reached a complexity that is not handled well with bash\nscripting and makes it a difficult to maintain and even to use tool, so the\nusefulness of shipping it with SCS to make it available for Ops teams to\nmonitor has been questioned. Instead an expectation has been expressed that the\nSCS uses this to monitor all SCS partner clouds and provides some transparency\nthis way to the public -- and detailed statistics via e.g. a prometheus\nexporter to the respective cloud provider. This is currently under consideration."}),"\n",(0,t.jsx)(n.h2,{id:"logging",children:"Logging"}),"\n",(0,t.jsx)(n.h3,{id:"central-logging",children:"Central logging"}),"\n",(0,t.jsx)(n.p,{children:"OSISM now enables kolla-ansible centralized logging by default. The default\nrules need to be further refined to suit your needs. We plan to implement a\nmore generic set of rules for R2."}),"\n",(0,t.jsx)(n.h2,{id:"federation",children:"Federation"}),"\n",(0,t.jsx)(n.h3,{id:"oidc-support-via-keycloak",children:"OIDC support via keycloak"}),"\n",(0,t.jsxs)(n.p,{children:["Logging in to Horizon by authenticating with OIDC via Keycloak is now possible.\nFor details see the ",(0,t.jsx)(n.a,{href:"https://github.com/osism/testbed/blob/8430afdd36307acc1bf5ebd930ecbd3dd4b1dd22/docs/source/usage.rst#authentication-with-openid-connect",children:"testbed documentation"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"non-tls-restrictions-testbed",children:"non-TLS restrictions (testbed)"}),"\n",(0,t.jsxs)(n.p,{children:["Only TLS secured deployments get full support.\nWithout TLS, certain browsers won't be able to log in.\nFor deatils see the ",(0,t.jsx)(n.a,{href:"https://github.com/osism/testbed/blob/8430afdd36307acc1bf5ebd930ecbd3dd4b1dd22/docs/source/usage.rst#ssl-tls-connection-to-keycloak-openid-connect-provider",children:"testbed documentation"})]}),"\n",(0,t.jsx)(n.h3,{id:"known-issue-with-oidc-logout",children:"Known Issue with OIDC Logout"}),"\n",(0,t.jsxs)(n.p,{children:["Clicking ",(0,t.jsx)(n.code,{children:"Sign Out"})," on the Horizon dashboard doesn't perform\na proper OIDC logout. This is documented in ",(0,t.jsx)(n.a,{href:"https://github.com/osism/testbed/blob/8430afdd36307acc1bf5ebd930ecbd3dd4b1dd22/docs/source/usage.rst#openstack-web-dashboard-horizon-logout",children:"osism testbed"}),",\nwith some Keycloak settings that can be relevant for alleviating the issue,\nbut in Release 1 there is no solution for this yet."]}),"\n",(0,t.jsx)(n.h2,{id:"bare-metal-service",children:"Bare Metal Service"}),"\n",(0,t.jsx)(n.p,{children:"The ironic Bare Metal service can be deployed with the SCS (OSISM)\ninstallation. For it to get full test coverage, a virtual BMC\nsolution has been created, so bare metal can be validated in our testbed\nsetup just as nicely as the other components. While most pieces\nare ready, the final integration steps are still work-in-progress\nand will happen after R1."}),"\n",(0,t.jsx)(n.h2,{id:"container-layer",children:"Container Layer"}),"\n",(0,t.jsx)(n.h3,{id:"overview-and-goals-for-r1",children:"Overview and Goals for R1"}),"\n",(0,t.jsxs)(n.p,{children:["The container layer on SCS is implemented as a Self-Service,\nleveraging the ",(0,t.jsx)(n.a,{href:"https://cluster-api.sigs.k8s.io/",children:"Kubernetes cluster API"}),"\ntechnology. This was provided as a technical preview from the\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"SCS k8s-cluster-api-provider"}),"\nrepository for R0 back in July."]}),"\n",(0,t.jsx)(n.p,{children:"The focus for R1 was to make it ready for production, so DevOps teams can\nuse this to create and manage their k8s clusters in self-service for\ndevelopment, testing, deployment and production."}),"\n",(0,t.jsx)(n.p,{children:"To achieve this, a lot of work has been invested, updating the\ncluster API to 0.4 along the way, fixing snapshot classes, enabling\noptional metrics and ingress services, using application credentials\nand much improved management scripts. The sonobuoy test automation has\nbeen included and successfully used to validate the created clusters.\nReal-world testing has happened though the Gaia-X Hackathon #1, where\nclusters were provided on the fly for the various work streams."}),"\n",(0,t.jsxs)(n.p,{children:["The detailed list of changes for R1 is covered in the\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/master/Release-Notes-R1.md",children:"k8s capi provider Release Notes"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Still in technical preview, but very promising are the helm charts\nbased k8s cluster management templates also documented there."}),"\n",(0,t.jsx)(n.h3,{id:"beyond-capi",children:"Beyond CAPI"}),"\n",(0,t.jsxs)(n.p,{children:["Some of our partners are using ",(0,t.jsx)(n.a,{href:"https://gardener.cloud",children:"Gardener"})," as a layer to manage\nlarge fleets of (optionally cross-cloud) k8s clusters. While there is a bit of\noverlap in functionality, they do happily coexist and our partner is actually\nusing k8s capi to bootstrap clusters on SCS clouds for Gardener management."]}),"\n",(0,t.jsx)(n.h2,{id:"standardization",children:"Standardization"}),"\n",(0,t.jsx)(n.p,{children:"As of this writing, the list of SCS defined standards still comprises\ntwo standards:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/flavor-naming.md",children:"SCS Flavor naming and standard flavors standard"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Image-Properties-Spec.md",children:"SCS Image naming and metadata standard"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"As before, we continue to rely on OpenStack and CNCF defined standards\nin addition to this -- the k8s clusters need to pass the conformance\ntests with sonobuoy and the OpenStack environment the OpenStack powered\nguidelines (with refstack)."}),"\n",(0,t.jsx)(n.p,{children:"There is a discussion on a glossary, detailing what we expect from regions,\navailability zones etc. Some major parts of it still need to be agreed\nbefore a useful doc can be published -- this will happen in due time and\nis expected before R2."}),"\n",(0,t.jsx)(n.h2,{id:"sbom-and-links",children:"SBOM and Links"}),"\n",(0,t.jsx)(n.p,{children:"We stand on the shoulders of giants:\nWithout all the great work from many open source communities, we would\nnot get anywhere."}),"\n",(0,t.jsx)(n.p,{children:"We are working on automation to create a complete list for all the software\nthat is used and deployed with SCS, so we have a complete Software Bill\nof Materials (SBoM). The reason this is non-trivial is that we are not\naggregating it all ourselves, but rely on pre-integrated pieces, such\nas Linux distributions, OpenStack, CNCF projects etc. The good news is\nthat these projects are diligent in their work, making sure we don't need\nto be too worried about security risks or legal risks introduced this way.\nNevertheless, the goal of creating a complete graph remains."}),"\n",(0,t.jsx)(n.p,{children:"We have started to put SPDX license identifiers into the SCS produced\ncode, so we make it easier for downstream consumers of our software to\nautomate the license compliance checks when assembling an SBoM."}),"\n",(0,t.jsx)(n.p,{children:"For R1, some of the major projects we build on have had releases that we\nincorporated and whose release notes we want to link here for convenience:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/kubernetes/kubernetes/releases",children:"Kubernetes v1.21.x"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api/releases",children:"Kubernetes Cluster API v0.4"}),"\nand ",(0,t.jsx)(n.a,{href:"https://github.com/kubernetes-sigs/cluster-api-provider-openstack/releases",children:"k8s cluster-api-provider openstack v0.4"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://releases.openstack.org/wallaby/",children:"OpenStack Wallaby"})," ",(0,t.jsx)(n.a,{href:"https://releases.openstack.org/wallaby/highlights.html",children:"Release Highlights"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"release-tagging",children:"Release tagging"}),"\n",(0,t.jsxs)(n.p,{children:["See ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Design-Docs/Release-Numbering-Scheme.md",children:"Release Numbering scheme"})," -- unchanged from R0.\nWe have added the tag ",(0,t.jsx)(n.code,{children:"v2.0.0"})," to the relevant repositories to designate the ",(0,t.jsx)(n.code,{children:"SCS_RELEASE_R1"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"list-of-known-issues--restrictions-in-r1",children:"List of known issues & restrictions in R1"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"#Known-Issue-with-OIDC-Logout",children:"OIDC Logout doesn't work properly"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["OIDC Login is meant to be used with TLS, on\n",(0,t.jsx)(n.a,{href:"#non-TLS-restrictions-testbed",children:"non-TLS setups it only works with restrictions"}),"."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var t=s(96540);const o={},i=t.createContext(o);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a4833b52.9c1ac905.js b/assets/js/a4833b52.9c1ac905.js new file mode 100644 index 0000000000..8e83469b84 --- /dev/null +++ b/assets/js/a4833b52.9c1ac905.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7753],{41639:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>c});var s=i(74848),a=i(28453);const t={title:"SCS Standard Images",type:"Standard",status:"Stable",stabilized_at:new Date("2024-02-21T00:00:00.000Z"),track:"IaaS",description:"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,\nspecifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined\ndeployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard's\nmachine-readable document facilitates automated processing for compliance and integration purposes, promoting\nconsistency and reliability in cloud environments.\n"},o=void 0,r={id:"scs-0104-v1-standard-images",title:"SCS Standard Images",description:"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,\nspecifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined\ndeployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard's\nmachine-readable document facilitates automated processing for compliance and integration purposes, promoting\nconsistency and reliability in cloud environments.\n",source:"@site/standards/scs-0104-v1-standard-images.md",sourceDirName:".",slug:"/scs-0104-v1-standard-images",permalink:"/standards/scs-0104-v1-standard-images",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS Standard Images",type:"Standard",status:"Stable",stabilized_at:"2024-02-21T00:00:00.000Z",track:"IaaS",description:"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments,\nspecifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined\ndeployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard's\nmachine-readable document facilitates automated processing for compliance and integration purposes, promoting\nconsistency and reliability in cloud environments.\n"},sidebar:"standards",previous:{title:"scs-0104: SCS Standard Images",permalink:"/standards/iaas/scs-0104"},next:{title:"scs-0110: SSD Flavors",permalink:"/standards/iaas/scs-0110"}},d={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Uploading custom images",id:"uploading-custom-images",level:2},{value:"Standard images YAML",id:"standard-images-yaml",level:2},{value:"Image specification, single image",id:"image-specification-single-image",level:3},{value:"Image specification, class of images",id:"image-specification-class-of-images",level:3},{value:"Full example",id:"full-example",level:2},{value:"Lifecycle considerations",id:"lifecycle-considerations",level:2},{value:"YAML lifecycle",id:"yaml-lifecycle",level:3},{value:"Image lifecycle",id:"image-lifecycle",level:3},{value:"Conformance Tests",id:"conformance-tests",level:2},{value:"Operational tooling",id:"operational-tooling",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://scs.community",children:"Sovereign Cloud Stack (SCS)"})," provides standards for a range of cloud infrastructure types.\nIt strives for interoperable and sovereign cloud offerings which can be deployed and used by a wide range of organizations and individuals."]}),"\n",(0,s.jsx)(n.p,{children:"To this end, SCS unifies the naming and sourcing of virtual machine images, and for certain images their presence is mandated or recommended."}),"\n",(0,s.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsxs)(n.p,{children:["Following the example of the ",(0,s.jsx)(n.a,{href:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",children:"SCS standards YAML"}),",\nthis standard establishes, by means of a YAML file, a mechanism with the following main objectives:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"to maintain a list of mandatory, recommended, and optional images, which also fixes the source location,"}),"\n",(0,s.jsx)(n.li,{children:"to provide a machine-readable document for further processing (e.g. for a compliance tool suite or continuous integration)."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"uploading-custom-images",children:"Uploading custom images"}),"\n",(0,s.jsx)(n.p,{children:"Image upload via Glance MUST be allowed based on a fair-use policy."}),"\n",(0,s.jsx)(n.h2,{id:"standard-images-yaml",children:"Standard images YAML"}),"\n",(0,s.jsxs)(n.p,{children:["The YAML file MUST contain the key ",(0,s.jsx)(n.code,{children:"images"}),", whose value is a list of objects. Each object has one of two forms, as described below."]}),"\n",(0,s.jsx)(n.h3,{id:"image-specification-single-image",children:"Image specification, single image"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Key"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"}),(0,s.jsx)(n.th,{children:"Example"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"name"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Name of the image"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:'"Debian 12"'})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"status"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.em,{children:"optional"}),": either ",(0,s.jsx)(n.code,{children:"mandatory"})," or ",(0,s.jsx)(n.code,{children:"recommended"})]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:'"recommended"'})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"source"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Prefix of the source URL"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:'"https://cloud.debian.org/images/cloud/bookworm/"'})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"OR: List of strings"}),(0,s.jsx)(n.td,{children:"multiple possible prefixes"}),(0,s.jsx)(n.td,{children:"(see full example below)"})]})]})]}),"\n",(0,s.jsx)(n.p,{children:"The meaning of this specification is as follows."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["If the status is ",(0,s.jsx)(n.code,{children:"mandatory"}),", then the image MUST be present."]}),"\n",(0,s.jsxs)(n.li,{children:["If an image by the name given is present, then its ",(0,s.jsx)(n.code,{children:"image_source"})," property\n(as described in the ",(0,s.jsx)(n.a,{href:"/standards/scs-0102-v1-image-metadata",children:"Image Metadata standard"}),")\nMUST start with one of the prefixes given via ",(0,s.jsx)(n.code,{children:"source"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"image-specification-class-of-images",children:"Image specification, class of images"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Key"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"}),(0,s.jsx)(n.th,{children:"Example"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"name"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Name of the class of images"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:'"ubuntu-2204-kube"'})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"name_scheme"})}),(0,s.jsx)(n.td,{children:"String (regex)"}),(0,s.jsx)(n.td,{children:"Regular expression for the image name"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:'"ubuntu-2204-kube-v[0-9].[0-9]+(.[0-9]+)?"'})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"status"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.em,{children:"optional"}),": either ",(0,s.jsx)(n.code,{children:"mandatory"})," or ",(0,s.jsx)(n.code,{children:"recommended"})]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:'"recommended"'})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"source"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Prefix of the source URL"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:'"https://swift.services.a.regiocloud.tech"'})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{}),(0,s.jsx)(n.td,{children:"OR: List of strings"}),(0,s.jsx)(n.td,{children:"multiple possible prefixes"}),(0,s.jsx)(n.td,{children:"(see full example below)"})]})]})]}),"\n",(0,s.jsx)(n.p,{children:"The meaning of this specification is as follows:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["If the status is ",(0,s.jsx)(n.code,{children:"mandatory"}),", then at least one image MUST be present whose name\nmatches the regular expression given via ",(0,s.jsx)(n.code,{children:"name_scheme"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["For any image whose name matches the regular expression given via ",(0,s.jsx)(n.code,{children:"name_scheme"}),",\nits ",(0,s.jsx)(n.code,{children:"image_source"})," property MUST start with one of the prefixes given via ",(0,s.jsx)(n.code,{children:"source"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"full-example",children:"Full example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'images:\n- name: "Ubuntu 22.04"\n source:\n - https://cloud-images.ubuntu.com/releases/jammy/\n - https://cloud-images.ubuntu.com/jammy/\n status: mandatory\n- name: "ubuntu-capi-image"\n name_scheme: "ubuntu-capi-image-v[0-9].[0-9]+(.[0-9]+)?"\n source: https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-k8s-capi-images/ubuntu-2204-kube\n status: recommended\n- name: "Ubuntu 20.04"\n source:\n - https://cloud-images.ubuntu.com/releases/focal/\n - https://cloud-images.ubuntu.com/focal/\n- name: "Debian 12"\n source:\n - https://cloud.debian.org/images/cloud/bookworm/\n - https://cdimage.debian.org/cdimage/cloud/bookworm/\n- name: "Debian 11"\n source:\n - https://cloud.debian.org/images/cloud/bullseye/\n - https://cdimage.debian.org/cdimage/cloud/bullseye/\n'})}),"\n",(0,s.jsx)(n.p,{children:"This example provides allowable source prefixes for two Debian versions, two Ubuntu\nversions, and for any version of the Kubernetes cloud API provider. Only the latter is\nrecommended, while only Ubuntu 22.04 is mandatory."}),"\n",(0,s.jsx)(n.h2,{id:"lifecycle-considerations",children:"Lifecycle considerations"}),"\n",(0,s.jsx)(n.h3,{id:"yaml-lifecycle",children:"YAML lifecycle"}),"\n",(0,s.jsxs)(n.p,{children:["The YAML file is generally located under\n",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/",children:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Any change that could render existing installations non-conformant (i.e., when new\nspecifications are added, when the name scheme of a specification is changed so as to\nmatch more names than before, when the status of an existing specification changes to\nmandatory, or when some source prefix is removed) requires a new YAML file to be created.\nAs a consequence, any currently valid certificates stay valid; the change can only take\neffect in a new version of the certificate in question, if so desired."}),"\n",(0,s.jsx)(n.h3,{id:"image-lifecycle",children:"Image lifecycle"}),"\n",(0,s.jsx)(n.p,{children:"It is important to note that this standard does not prohibit any images, and neither\ndoes it preclude the operator from providing any and all optional images."}),"\n",(0,s.jsx)(n.p,{children:"It is possible that a specification is mandatory in one version and non-mandatory in the\nnext version. This standard makes no statement as to what is supposed to happen to the\ncorresponding images in a live cloud environment. It is recommended to keep the\nonce-mandatory images in the live environment. As for new environments, it is up to the\noperator whether to provide any or all of these images, as stated above."}),"\n",(0,s.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,s.jsxs)(n.p,{children:["The script ",(0,s.jsx)(n.code,{children:"images-openstack.py"})," will read the lists of mandatory and recommended images\nfrom a yaml file provided as command-line argument, connect to an OpenStack installation,\nand check whether the images are present. Missing images will be reported on various\nlogging channels: error for mandatory, info for recommended images. Additionally, images\nwhose ",(0,s.jsx)(n.code,{children:"image_source"})," does not conform with the specifications will be reported on the\nerror channel. The return code will be non-zero if the test could not be performed or\nif any errors have been reported."]}),"\n",(0,s.jsx)(n.h2,{id:"operational-tooling",children:"Operational tooling"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://github.com/osism/openstack-image-manager",children:"openstack-image-manager"})," is able to\ncreate all standard, mandatory SCS images for you given image definitions from a YAML file."]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>r});var s=i(96540);const a={},t=s.createContext(a);function o(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a489f3d8.ba23aa58.js b/assets/js/a489f3d8.ba23aa58.js new file mode 100644 index 0000000000..bcf51a42f2 --- /dev/null +++ b/assets/js/a489f3d8.ba23aa58.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8128],{92558:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var o=t(74848),s=t(28453);const i={sidebar_label:"Migrate from VMware ESXi to OpenStack"},a="Migrate from VMware ESXi to OpenStack",r={id:"iaas/guides/user-guide/migration-vmware-esix",title:"Migrate from VMware ESXi to OpenStack",description:"This guide is an example of how to perform a manual migration from a VMware ESXi host to OpenStack.",source:"@site/docs/02-iaas/guides/user-guide/migration-vmware-esix.md",sourceDirName:"02-iaas/guides/user-guide",slug:"/iaas/guides/user-guide/migration-vmware-esix",permalink:"/docs/iaas/guides/user-guide/migration-vmware-esix",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/migration-vmware-esix.md",tags:[],version:"current",frontMatter:{sidebar_label:"Migrate from VMware ESXi to OpenStack"},sidebar:"docs",previous:{title:"User Guide",permalink:"/docs/iaas/guides/user-guide/"},next:{title:"OpenStack",permalink:"/docs/iaas/guides/user-guide/openstack/"}},c={},d=[{value:"Scenario",id:"scenario",level:2},{value:"Requirements",id:"requirements",level:2},{value:"Prechecks",id:"prechecks",level:2},{value:"Migration",id:"migration",level:2},{value:"How to copy vmdk images",id:"how-to-copy-vmdk-images",level:3},{value:"How to convert vmdk to raw",id:"how-to-convert-vmdk-to-raw",level:3},{value:"Edit the raw Images (optional)",id:"edit-the-raw-images-optional",level:3},{value:"How to import Images",id:"how-to-import-images",level:3},{value:"How to create your server",id:"how-to-create-your-server",level:3},{value:"Show your new server",id:"show-your-new-server",level:3},{value:"How to access the VNC console",id:"how-to-access-the-vnc-console",level:3},{value:"Last words",id:"last-words",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"migrate-from-vmware-esxi-to-openstack",children:"Migrate from VMware ESXi to OpenStack"}),"\n",(0,o.jsx)(n.p,{children:"This guide is an example of how to perform a manual migration from a VMware ESXi host to OpenStack.\nMigration to OpenStack always depends very much on the use case. It is not possible to document an\napproach or to write a tool that works for all use cases. This guide shows one possible way. There are many ways to\nperform a migration. A migration must always be carefully prepared and tested in advance."}),"\n",(0,o.jsxs)(n.p,{children:["At this point, we would also like to point out the open source project\n",(0,o.jsx)(n.a,{href:"https://github.com/cloudbase/coriolis",children:"cloudbase/coriolis"})," from Cloudbase. There are also commercial\nproviders that perform migration from VMware ESXi to OpenStack. One of the offerings is\n",(0,o.jsx)(n.a,{href:"https://hystax.com/cloud-migration/",children:"Hystax Acura Live Cloud Migration"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"scenario",children:"Scenario"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Source: ESXi 7.0 host"}),"\n",(0,o.jsx)(n.li,{children:"Destination: OpenStack"}),"\n",(0,o.jsxs)(n.li,{children:["a security group (",(0,o.jsx)(n.code,{children:"web_ssh"}),") is already available at the destination"]}),"\n",(0,o.jsx)(n.li,{children:"a Linux converter host is installed and ready, we also have root access to it"}),"\n",(0,o.jsxs)(n.li,{children:["an IPv4 address (",(0,o.jsx)(n.code,{children:"10.50.40.230"}),") will be given manually out of a preconfigured network"]}),"\n",(0,o.jsx)(n.li,{children:"we migrate one host with a kernel newer then 2.6.25 with two scsi harddrives attached and one networkcard"}),"\n",(0,o.jsx)(n.li,{children:"destination openstack using Libvirt/KVM as virtualisation"}),"\n",(0,o.jsx)(n.li,{children:"the converter host has access to ESXi and the OpenStack environment over IP network"}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"VMware credentials"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"SSH enabled on ESXi host"}),"\n",(0,o.jsx)(n.li,{children:"access to the webinterface of the ESXi host"}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"OpenStack credentials"}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Linux packages installed on the coverter, in this case it is an Ubuntu 22.04"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"apt-get install qemu-utils python3-openstackclient\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"twice the space of the largest vmdk disc image on the converter or nfs access to the image files with enough storage"}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"prechecks",children:"Prechecks"}),"\n",(0,o.jsxs)(n.p,{children:["Check the ",(0,o.jsx)(n.code,{children:"/etc/fstab"})," file of your VMware ESXi host you want to move. See how all the discs or paritions are mounted.\nIf they are all mounted by LVM or UUID you do not need to change anything."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-txt",metastring:'title="cat /etc/fstab"',children:"/dev/mapper/vg00-lvroot / ext4 errors=remount-ro 0 1\n/dev/mapper/vg00-lvboot /boot ext2 defaults 0 2\n/dev/mapper/vg00-lvhome /home ext4 defaults 0 2\n/dev/mapper/vg00-lvvar /var ext4 defaults 0 2\n/dev/mapper/vg00-lvswap none swap sw 0 0\n/dev/mapper/vgdata-lvsrv /srv ext4 defaults 0 2\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If they are mounted like ",(0,o.jsx)(n.code,{children:"/dev/sda"})," it is better to change the ",(0,o.jsx)(n.code,{children:"/etc/fstab"})," to UUID mounting using ",(0,o.jsx)(n.code,{children:"blkid"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Replace these entries with ",(0,o.jsx)(n.code,{children:"UUID=filesystems_uuid"})," and add the rest of the line same as with the devicenames."]}),"\n",(0,o.jsx)(n.p,{children:"Example:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-txt",metastring:'title="example devicename fstab"',children:"/dev/sda1 /boot ext2 defaults 0 2\n/dev/sda2 / ext4 errors=remount-ro 0 1\n"})}),"\n",(0,o.jsx)(n.p,{children:"Change it to something like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-txt",metastring:'title="example uuid fstab"',children:"UUID=574c96bf-f2cb-49b8-9196-232a24047f94 /boot ext2 defaults 0 2\nUUID=93cc3b34-36c3-422e-b7a6-c80439e8f431 / ext4 errors=remount-ro 0 1\n"})}),"\n",(0,o.jsx)(n.admonition,{type:"caution",children:(0,o.jsxs)(n.p,{children:["When creating a new server, OpenStack uses ",(0,o.jsx)(n.code,{children:"/dev/vd*"})," or ",(0,o.jsx)(n.code,{children:"/dev/sd*"})," as devices for volumes.\nUsing UUID/LVM mounts will ensure that the kernel will find your devices while booting.\nUsing old device names may lead to the boot sequence to get stuck, due to missing devices."]})}),"\n",(0,o.jsx)(n.p,{children:"Also check your NIC interface configuration as the devicenames can change to a new devicename."}),"\n",(0,o.jsx)(n.p,{children:"This depends on the udev or systemd setup of your specific system."}),"\n",(0,o.jsx)(n.p,{children:"It needs to be changed to either DCHP if you want to use floating IPs or static IP of the new network."}),"\n",(0,o.jsx)(n.h2,{id:"migration",children:"Migration"}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsx)(n.p,{children:"Shutdown the host in VMware as the movement is only possible while the host is offline.\nOtherwise you will get corrupted disc files."})}),"\n",(0,o.jsxs)(n.p,{children:["You can use either the webinterface or SSH to identify and copy the ",(0,o.jsx)(n.code,{children:"*.vmdk"})," files of your VMware ESXi host."]}),"\n",(0,o.jsx)(n.p,{children:"While using the web interface you need to locate the datastore and the directoy where the disc files are\nlocated and start downloading all vmdk files. You will always get files files for a disc, a smaller and a\nlarger one, both are required."}),"\n",(0,o.jsxs)(n.p,{children:["When using SSh, please also copy both vmdk files for the disc to the converter host. Start looking up your\nfiles under ",(0,o.jsx)(n.code,{children:"/vmfs/volumes/"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"how-to-copy-vmdk-images",children:"How to copy vmdk images"}),"\n",(0,o.jsx)(n.p,{children:"Example SSH copy and path of all vmdk files to the converter host using the scp command for our testing-host:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"scp user@vmhost:/vmfs/volumes/datastore1/testing-host/*.vmdk .\n"})}),"\n",(0,o.jsx)(n.p,{children:"After copying is finished, we find several vmdk files in our directory.\nWe copied two disc images:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"testing-host-disc0-flat.vmdk testing-host-disc1.vmdk\ntesting-host-disc0.vmdk testing-host-disc1-flat.vmdk\n"})}),"\n",(0,o.jsx)(n.h3,{id:"how-to-convert-vmdk-to-raw",children:"How to convert vmdk to raw"}),"\n",(0,o.jsxs)(n.admonition,{type:"note",children:[(0,o.jsx)(n.p,{children:"Now convert those vmdk files into raw images with the following flags:"}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"-p show progress (optional) \n-f Input Format \n-O Output Format \n"})}),(0,o.jsx)(n.p,{children:"Raw files are required to import images into OpenStack."})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"qemu-img convert -p -f vmdk -O raw testing-host-disc0.vmdk testing-host-disc0.raw\n"})}),"\n",(0,o.jsx)(n.p,{children:"Repeat this step for each disc image you need to convert."}),"\n",(0,o.jsx)(n.h3,{id:"edit-the-raw-images-optional",children:"Edit the raw Images (optional)"}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsx)(n.p,{children:"This step is completely optional and you should have some Linux knowledge to do this."})}),"\n",(0,o.jsx)(n.p,{children:"After converting the images of a Linux host, you now have the possibilty to edit some settings offline before importing the images into OpenStack."}),"\n",(0,o.jsx)(n.p,{children:"By mounting the raw image files you can edit the configuration files to, e.g.:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"disable mountpoints at the fstab, like nfs server"}),"\n",(0,o.jsx)(n.li,{children:"change the ip config of the networkcard to dhcp or fixed ip"}),"\n",(0,o.jsx)(n.li,{children:"adjust resolv.conf"}),"\n",(0,o.jsx)(n.li,{children:"adjust routing"}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"On Ubuntu you can use losetup to mount the raw image as a loopdevice to mount it somewhere you have access to."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-txt",metastring:"example of mounting and raw image",children:"losetup -f -P testing-host-disc0.raw\nlosetup -l\n\nmount /dev/loop0p1 /mnt/test/ \nor\nlvscan and mount the lvm volume\n"})}),"\n",(0,o.jsx)(n.h3,{id:"how-to-import-images",children:"How to import Images"}),"\n",(0,o.jsxs)(n.p,{children:["First of all you need your OpenStack credentials, having them in an ",(0,o.jsx)(n.code,{children:"my-project-openrc.sh"})," file and source them to your shell."]}),"\n",(0,o.jsx)(n.p,{children:"The openstack cli client is now able to connect to the cloud environment and do all the following steps."}),"\n",(0,o.jsx)(n.p,{children:"To get your credentials please check with your OpenStack provider."}),"\n",(0,o.jsxs)(n.p,{children:["If you want to preserve the ",(0,o.jsx)(n.code,{children:"/dev/sd*"})," device names of the mountpoints, you must inject the new image and add some properties while uploading it into the OpenStack environment or add them later on to the images with Horzion web interface or openstack cli client."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack image create --progress --property hw_disk_bus=scsi --property hw_scsi_model=virtio-scsi --property hw_watchdog_action=reset --disk-format raw --private --file testing-host-disc0.raw testing-host-image-disc0\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack image list\n+--------------------------------------+------------------------------+--------+\n| ID | Name | Status |\n+--------------------------------------+------------------------------+--------+\n| 2a12b545-5d09-4ca1-9a76-b57f8d2489be | testing-host-disc0 | active |\n| b34744f7-6ef6-4282-a001-08a06812e381 | testing-host-disc1 | active |\n+--------------------------------------+------------------------------+--------+\n"})}),"\n",(0,o.jsx)(n.h3,{id:"how-to-create-your-server",children:"How to create your server"}),"\n",(0,o.jsx)(n.p,{children:"The previously imported images need to be copied to a volume so the server is also able to evict to other hosts in the cluster,\nso lets create and start our server in OpenStack."}),"\n",(0,o.jsxs)(n.p,{children:["Select one flavor for the host, in this case ",(0,o.jsx)(n.code,{children:"SCS-8V-16"}),", which means 8 Virtual CPUs and 16GB of RAM, get a list of all your available flavors by executing\n",(0,o.jsx)(n.code,{children:"openstack flavor list"})," and select the best matching one."]}),"\n",(0,o.jsx)(n.p,{children:"As the images are 20GB, you tell openstack that you need a boot volume with a size of 20 and a block-device for the additional device also with a size of 20GB."}),"\n",(0,o.jsx)(n.p,{children:"In this guide there is already a security group which fits our needs, if not, create one or you will not be able to communicate with your new host."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack security group list\n+--------------------------------------+-----------------+------------------------------+----------------------------------+------+\n| ID | Name | Description | Project | Tags |\n+--------------------------------------+-----------------+------------------------------+----------------------------------+------+\n| 4fd1d060-bf1d-4f5a-8e80-fde975d41f5f | default | Default security group | c9aa53cc3c654692b14a8f81a88cfa2f | [] |\n| 73967e73-e8d5-4318-b621-a06e7496fec3 | web_ssh | Webserver security group | c9aa53cc3c654692b14a8f81a88cfa2f | [] |\n+--------------------------------------+-----------------+------------------------------+----------------------------------+------+\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"web_ssh"})," group will be attached to the server."]}),"\n",(0,o.jsx)(n.p,{children:"Now you need to tell which network you want to deploy your host on, optionally including a fixed IPv4 address."}),"\n",(0,o.jsxs)(n.p,{children:["You can repeat the ",(0,o.jsx)(n.code,{children:"--nic"})," for additional nics in your server, in this guide it's the my_corp_net."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack network list\n+--------------------------------------+-------------------+--------------------------------------+\n| ID | Name | Subnets |\n+--------------------------------------+-------------------+--------------------------------------+\n| 9688192e-11dd-4618-a18c-99d3267f630a | my_corp_net | 0d502fdb-be73-457a-8678-79eb6088a9a1 |\n| 98842b77-c070-4532-a2a9-99d588c4e947 | internet | 2dfc3916-972f-44d1-afdb-6f89488ef3a4 |\n| c846238a-b00a-4c73-87e3-3614d94f46fd | my_other_corp_net | b8210b4e-5d91-425a-b05c-ca5d4bf8329a |\n+--------------------------------------+-------------------+--------------------------------------+\n"})}),"\n",(0,o.jsx)(n.p,{children:"As last parameter, you give the server name of your migrated system."}),"\n",(0,o.jsx)(n.p,{children:"As we are starting an already configured system we do not need to inject SSH keys or passwords as they should already be present on the host."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack server create --flavor SCS-8V-16 \\\n --image 2a12b545-5d09-4ca1-9a76-b57f8d2489be --boot-from-volume 20 \\\n --security-group 73967e73-e8d5-4318-b621-a06e7496fec3 \\\n --nic net-id=9688192e-11dd-4618-a18c-99d3267f630a,v4-fixed-ip=10.50.40.230 \\ \n --block-device uuid=b34744f7-6ef6-4282-a001-08a06812e381,source_type=image,destination_type=volume,volume_size=20 \\\n --os-compute-api-version 2.90 testing-host\n"})}),"\n",(0,o.jsx)(n.h3,{id:"show-your-new-server",children:"Show your new server"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack server list\n+--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+\n| ID | Name | Status | Networks | Image | Flavor |\n+--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+\n| 71a8b930-4212-434a-8891-afdeeb1802dc | testing-host | ACTIVE | my_network=10.50.40.230 | N/A (booted from volume) | SCS-8V-16 |\n+--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+\n"})}),"\n",(0,o.jsx)(n.p,{children:"To see the attached volumes and their mountpoints:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack server volume list 71a8b930-4212-434a-8891-afdeeb1802dc \n+----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+\n| Device | Server ID | Volume ID | Tag | Delete On Termination? | Attachment ID | BlockDeviceMapping UUID |\n+----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+\n| /dev/sda | 71a8b930-4212-434a-8891-afdeeb1802dc | 71902b03-48ea-483c-a6a3-6c47b9d8537b | None | False | 3cd241ff-5296-4bb1-9ba0-d743cb8c8f31 | 2d08e835-156f-4f71-8c95-7ff828230b8e |\n| /dev/sdb | 71a8b930-4212-434a-8891-afdeeb1802dc | 15a835a3-5149-49a8-8e2b-a81ef8097c35 | None | False | 9deeb06b-718b-49d4-84a4-87dabc34ba56 | 04483f95-0333-4b37-92e6-db604e4ddc7c |\n+----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+\n"})}),"\n",(0,o.jsx)(n.h3,{id:"how-to-access-the-vnc-console",children:"How to access the VNC console"}),"\n",(0,o.jsx)(n.p,{children:"To get the VNC URL for console login use:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack console url show 71a8b930-4212-434a-8891-afdeeb1802dc\n+----------+-------------------------------------------------------------------------------------------+\n| Field | Value |\n+----------+-------------------------------------------------------------------------------------------+\n| protocol | vnc |\n| type | novnc |\n| url | https://vnc.your.cloud/vnc_lite.html?path=%3Ftoken%3Db9b6920d-e533-4728-8132-a5a0adfc24e5 |\n+----------+-------------------------------------------------------------------------------------------+\n"})}),"\n",(0,o.jsx)(n.p,{children:"This will print out the VNC URL for the videoconsole connection to your host."}),"\n",(0,o.jsx)(n.p,{children:"Now the server will boot and be available."}),"\n",(0,o.jsx)(n.p,{children:"Maybe you need to tweak the network setup if it is still not accessible.\nTo do this, you could use the VNC console of the OpenStack host:"}),"\n",(0,o.jsx)(n.p,{children:"Login and then setup the network card if you have not already done that before host had been shutdown."}),"\n",(0,o.jsx)(n.p,{children:"You now can remove the imported images, as they are no longer required - except you want to generate\nanother host with the same images."}),"\n",(0,o.jsx)(n.h2,{id:"last-words",children:"Last words"}),"\n",(0,o.jsx)(n.p,{children:"In this little guide, we only can give a sneak peak of what you need to do with a simple VMware ESXi host.\nMore complex setups needs consulting, planning and testing as there a several scenarios out there which\ncannot be handled like this.\nEspecially if you have terrabytes of data to move or graphics- or AIcards in you VMware ESXi hosts."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var o=t(96540);const s={},i=o.createContext(s);function a(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a51c5cdb.5f154dac.js b/assets/js/a51c5cdb.5f154dac.js new file mode 100644 index 0000000000..f4e316db8e --- /dev/null +++ b/assets/js/a51c5cdb.5f154dac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[603],{7149:(e,d,r)=>{r.r(d),r.d(d,{assets:()=>l,contentTitle:()=>t,default:()=>x,frontMatter:()=>c,metadata:()=>i,toc:()=>o});var s=r(74848),n=r(28453);const c={},t="Configuration",i={id:"container/components/k8s-cluster-api-provider/doc/configuration",title:"Configuration",description:"Supported k8s versions",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/configuration.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc",slug:"/container/components/k8s-cluster-api-provider/doc/configuration",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/configuration",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/configuration.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Application Credentials",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/application-credentials"},next:{title:"Maintenance and Troubleshooting Guide for SCS k8s-cluster-api-provider",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting"}},l={},o=[{value:"Supported k8s versions",id:"supported-k8s-versions",level:2},{value:"Overview over the parameters in clusterctl.yaml and environment-XXX.tfvars",id:"overview-over-the-parameters-in-clusterctlyaml-and-environment-xxxtfvars",level:2},{value:"Parameters CAPI management server",id:"parameters-capi-management-server",level:3},{value:"Common parameters management server and clusters",id:"common-parameters-management-server-and-clusters",level:3},{value:"Parameters clusters",id:"parameters-clusters",level:3}];function h(e){const d={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(d.h1,{id:"configuration",children:"Configuration"}),"\n",(0,s.jsx)(d.h2,{id:"supported-k8s-versions",children:"Supported k8s versions"}),"\n",(0,s.jsx)(d.p,{children:"As of R6, our tests cover 1.25.latest ... 1.28.latest.\nAll of them pass the sonobuoy CNCF conformance tests."}),"\n",(0,s.jsx)(d.h2,{id:"overview-over-the-parameters-in-clusterctlyaml-and-environment-xxxtfvars",children:"Overview over the parameters in clusterctl.yaml and environment-XXX.tfvars"}),"\n",(0,s.jsx)(d.p,{children:"The provenance capo means that this setting comes from the templates used by\nthe cluster-api-provider-openstack, while SCS denotes that this setting has\nbeen added by the SCS project."}),"\n",(0,s.jsx)(d.h3,{id:"parameters-capi-management-server",children:"Parameters CAPI management server"}),"\n",(0,s.jsx)(d.p,{children:"Parameters controlling the Cluster-API management server (capi management server) creation:"}),"\n",(0,s.jsxs)(d.table,{children:[(0,s.jsx)(d.thead,{children:(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.th,{children:"environment"}),(0,s.jsx)(d.th,{children:"clusterctl.yaml"}),(0,s.jsx)(d.th,{children:"provenance"}),(0,s.jsx)(d.th,{children:"default"}),(0,s.jsx)(d.th,{children:"meaning"})]})}),(0,s.jsxs)(d.tbody,{children:[(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"prefix"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"capi"})}),(0,s.jsx)(d.td,{children:"Prefix used for OpenStack resources for the capi mgmt node"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"kind_flavor"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"SCS-2V-4"})}),(0,s.jsx)(d.td,{children:"Flavor to be used for the k8s capi mgmt server"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"image"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"Ubuntu 22.04"})}),(0,s.jsxs)(d.td,{children:["Image for the capi mgmt server. Use ",(0,s.jsx)(d.code,{children:"Ubuntu 22.04"})," or ",(0,s.jsx)(d.code,{children:"Debian 12"}),". Check also the ",(0,s.jsx)(d.code,{children:"ssh_username"})," parameter"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"ssh_username"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"ubuntu"})}),(0,s.jsxs)(d.td,{children:["Name of the default user for the ",(0,s.jsx)(d.code,{children:"image"})]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"clusterapi_version"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsxs)(d.td,{children:[(0,s.jsx)(d.code,{children:"1.6.3"})," "]}),(0,s.jsxs)(d.td,{children:["Version of the cluster-API incl. ",(0,s.jsx)(d.code,{children:"clusterctl"})]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"capi_openstack_version"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsxs)(d.td,{children:[(0,s.jsx)(d.code,{children:"0.9.0"})," "]}),(0,s.jsx)(d.td,{children:"Version of the cluster-api-provider-openstack (needs to fit the CAPI version)"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"cilium_binaries"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"v0.15.23;v0.13.0"})}),(0,s.jsx)(d.td,{children:"Versions of the cilium and hubble CLI in the vA.B.C;vX.Y.Z format"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"restrict_mgmt_server"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:'["0.0.0.0/0"]'})}),(0,s.jsx)(d.td,{children:"Allows restricting access to the management server by the given list of CIDRs. Empty value (default) means public."})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"mgmt_cidr"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"10.0.0.0/24"})}),(0,s.jsx)(d.td,{children:"IPv4 address range (CIDR notation) for management cluster"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"mgmt_ip_range"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:'{start:"10.0.0.11", end:"10.0.0.254"}'})}),(0,s.jsxs)(d.td,{children:["IP range from defined ",(0,s.jsx)(d.code,{children:"mgmt_cidr"})," variable for management cluster. It is recommended to reserve the first 10 IPs."]})]})]})]}),"\n",(0,s.jsx)(d.h3,{id:"common-parameters-management-server-and-clusters",children:"Common parameters management server and clusters"}),"\n",(0,s.jsx)(d.p,{children:"Parameters controlling both management server creation and cluster creation:"}),"\n",(0,s.jsxs)(d.table,{children:[(0,s.jsx)(d.thead,{children:(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.th,{children:"environment"}),(0,s.jsx)(d.th,{children:"clusterctl.yaml"}),(0,s.jsx)(d.th,{children:"provenance"}),(0,s.jsx)(d.th,{children:"default"}),(0,s.jsx)(d.th,{children:"meaning"})]})}),(0,s.jsxs)(d.tbody,{children:[(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"cloud_provider"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_CLOUD"})}),(0,s.jsx)(d.td,{children:"capo"}),(0,s.jsx)(d.td,{}),(0,s.jsxs)(d.td,{children:[(0,s.jsx)(d.code,{children:"OS_CLOUD"})," name in clouds.yaml"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsxs)(d.td,{children:[(0,s.jsx)(d.code,{children:"external"}),"/",(0,s.jsx)(d.code,{children:"external_id"})]}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_EXTERNAL_NETWORK_ID"})}),(0,s.jsx)(d.td,{children:"capo"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:'""'})}),(0,s.jsx)(d.td,{children:'Name/ID of the external (public) OpenStack network, default "" uses the detected external network (for clouds with one external network). Required for clouds with more than one external network'})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"dns_nameservers"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_DNS_NAMESERVERS"})}),(0,s.jsx)(d.td,{children:"capo"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:'[ "5.1.66.255", "185.150.99.255" ]'})}),(0,s.jsx)(d.td,{children:"Array of nameservers for capi mgmt server and for cluster nodes, replace the FF MUC defaults with local servers if available"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"availability_zone"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_FAILURE_DOMAIN"})}),(0,s.jsx)(d.td,{children:"capo"}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"Availability Zone(s) for the mgmt node / workload clusters"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"kind_mtu"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"MTU_VALUE"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"0"})}),(0,s.jsx)(d.td,{children:"MTU for the mgmt server; Calico is set 50 bytes smaller; 0 means autodetection"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"http_proxy"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{}),(0,s.jsxs)(d.td,{children:["Global setting for HTTP Proxy is set on the management host including all cluster-api components running in the bootstrap-cluster. Specify with protocol: e.g ",(0,s.jsx)(d.code,{children:"http://10.10.10.10:3128"})]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"no_proxy"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{}),(0,s.jsxs)(d.td,{children:["Global setting for HTTP Proxy exception list. If ",(0,s.jsx)(d.code,{children:"http_proxy"})," is not set this setting has no effect. If ",(0,s.jsx)(d.code,{children:"http_proxy"})," is set, the default value for the ",(0,s.jsx)(d.code,{children:"NO_PROXY"})," environment variable on all affected components is set to ",(0,s.jsx)(d.code,{children:".svc,.svc.cluster,.svc.cluster.local,127.0.0.0/8,169.254.169.254/32,fd00:ec2::254/128,${var.node_cidr},${var.pod_cidr},${var.service_cidr}"}),". The content of ",(0,s.jsx)(d.code,{children:"no_proxy"})," is appended to this list. This setting has no effect on apt and snap commands, the way ",(0,s.jsx)(d.code,{children:"http_proxy"})," is set for apt and snap does not allow the configuration of proxy exceptions."]})]})]})]}),"\n",(0,s.jsx)(d.h3,{id:"parameters-clusters",children:"Parameters clusters"}),"\n",(0,s.jsx)(d.p,{children:"Parameters controlling the cluster creation:"}),"\n",(0,s.jsxs)(d.table,{children:[(0,s.jsx)(d.thead,{children:(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.th,{children:"environment"}),(0,s.jsx)(d.th,{children:"clusterctl.yaml"}),(0,s.jsx)(d.th,{children:"provenance"}),(0,s.jsx)(d.th,{children:"default"}),(0,s.jsx)(d.th,{children:"meaning"})]})}),(0,s.jsxs)(d.tbody,{children:[(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"node_cidr"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"NODE_CIDR"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"10.8.0.0/20"})}),(0,s.jsx)(d.td,{children:"IPv4 address range (CIDR notation) for workload nodes"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"pod_cidr"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"POD_CIDR"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"192.168.0.0/16"})}),(0,s.jsx)(d.td,{children:"IPv4 address range (CIDR notation) for pods"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"service_cidr"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"SERVICE_CIDR"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"10.96.0.0/12"})}),(0,s.jsx)(d.td,{children:"IPv4 address range (CIDR notation) for services"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"use_cilium"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"USE_CILIUM"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"true"})}),(0,s.jsxs)(d.td,{children:["Use cilium as CNI instead of calico, it can be set to vX.Y.Z and ",(0,s.jsx)(d.code,{children:"true"})," results in ",(0,s.jsx)(d.code,{children:"v1.15.1"}),", also see ",(0,s.jsx)(d.code,{children:"cilium_binaries"})]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"calico_version"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"CALICO_VERSION"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsxs)(d.td,{children:[(0,s.jsx)(d.code,{children:"v3.27.3"})," "]}),(0,s.jsxs)(d.td,{children:["Version of the Calico CNI provider (ignored if ",(0,s.jsx)(d.code,{children:"use_cilium"})," is set)"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"kubernetes_version"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"KUBERNETES_VERSION"})}),(0,s.jsx)(d.td,{children:"capo"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"v1.28.x"})}),(0,s.jsxs)(d.td,{children:["Kubernetes version deployed into workload cluster (",(0,s.jsx)(d.code,{children:".x"})," means latest patch release)"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:"``"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_IMAGE_NAME"})}),(0,s.jsx)(d.td,{children:"capo"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"ubuntu-capi-image-${KUBERNETES_VERION}"})}),(0,s.jsx)(d.td,{children:"Image name for k8s controller and worker nodes. Ubuntu 22.04 image is used for k8s versions >= 1.27.3, 1.26.6, 1.25.11, Ubuntu 20.04 otherwise."})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"kube_image_raw"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_IMAGE_RAW"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"true"})}),(0,s.jsx)(d.td,{children:"Register images in raw format (instead of qcow2), good for ceph COW"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"image_registration_extra_flags"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_IMAGE_REGISTATION_EXTRA_FLAGS"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:'""'})}),(0,s.jsx)(d.td,{children:"Extra flags passed during image registration"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:"``"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_SSH_KEY_NAME"})}),(0,s.jsx)(d.td,{children:"capo"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"${prefix}-keypair"})}),(0,s.jsx)(d.td,{children:"SSH key name generated and used to connect to workload cluster nodes"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"controller_flavor"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_CONTROL_PLANE_MACHINE_FLAVOR"})}),(0,s.jsx)(d.td,{children:"capo"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"SCS-2V-4-20s"})}),(0,s.jsx)(d.td,{children:"Flavor to be used for control plane nodes"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"worker_flavor"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_NODE_MACHINE_FLAVOR"})}),(0,s.jsx)(d.td,{children:"capo"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"SCS-2V-4-20s"})}),(0,s.jsx)(d.td,{children:"Flavor to be used for worker nodes"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"controller_count"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"CONTROL_PLANE_MACHINE_COUNT"})}),(0,s.jsx)(d.td,{children:"capo"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"1"})}),(0,s.jsx)(d.td,{children:"Number of control plane nodes in testcluster (0 skips testcluster creation)"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:"``"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"CONTROL_PLANE_MACHINE_GEN"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"genc01"})}),(0,s.jsx)(d.td,{children:"Suffix for control plane node resources, to be changed for rolling upgrades"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"worker_count"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"WORKER_MACHINE_COUNT"})}),(0,s.jsx)(d.td,{children:"capo"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"3"})}),(0,s.jsx)(d.td,{children:"Number of worker nodes in testcluster"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:"``"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"WORKER_MACHINE_GEN"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"genw01"})}),(0,s.jsx)(d.td,{children:"Suffix for worker node resources, to be changed for rolling upgrades"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:"``"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"CONTROL_PLANE_ROOT_DISKSIZE"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"20"})}),(0,s.jsxs)(d.td,{children:[(0,s.jsx)(d.em,{children:"If"})," diskless flavors are used for control plane nodes, this is the allocated root volume disk size (in GB)"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:"``"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"WORKER_ROOT_DISKSIZE"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"20"})}),(0,s.jsxs)(d.td,{children:[(0,s.jsx)(d.em,{children:"If"})," diskless flavors are used for worker nodes, this is the allocated root volume disk size (in GB)"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"anti_affinity"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_ANTI_AFFINITY"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"true"})}),(0,s.jsx)(d.td,{children:"Use anti-affinity server groups to prevent k8s nodes on same host (soft for workers, hard for controllers)"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:"``"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_SRVGRP_CONTROLLER"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"nonono"})}),(0,s.jsxs)(d.td,{children:["Autogenerated if ",(0,s.jsx)(d.code,{children:"anti_affinity"})," is ",(0,s.jsx)(d.code,{children:"true"}),", eliminated otherwise"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:"``"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_SRVGRP_WORKER"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"nonono"})}),(0,s.jsxs)(d.td,{children:["Autogenerated if ",(0,s.jsx)(d.code,{children:"anti_affinity"})," is ",(0,s.jsx)(d.code,{children:"true"}),", eliminated otherwise"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"deploy_occm"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"DEPLOY_OCCM"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"true"})}),(0,s.jsxs)(d.td,{children:["Deploy the given version of OCCM into the cluster. ",(0,s.jsx)(d.code,{children:"true"})," (default) chooses the latest version matching the k8s version. You can specify ",(0,s.jsx)(d.code,{children:"master"})," to chose the upstream master branch. Don't disable this."]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"deploy_cindercsi"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"DEPLOY_CINDERCSI"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"true"})}),(0,s.jsx)(d.td,{children:"Deploy the given (or latest matching for the default true value) of cinder CSI."})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"etcd_unsafe_fs"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"ETCD_UNSAFE_FS"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"false"})}),(0,s.jsxs)(d.td,{children:["Use ",(0,s.jsx)(d.code,{children:"barrier=0"})," for filesystem on control nodes to avoid storage latency. Use for multi-controller clusters on slow/networked storage, otherwise not recommended."]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"testcluster_name"})}),(0,s.jsx)(d.td,{children:"(cmd line)"}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"testcluster"})}),(0,s.jsxs)(d.td,{children:["Allows setting the default cluster name, created at bootstrap (if ",(0,s.jsx)(d.code,{children:"controller_count"})," is larger than 0)"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"restrict_kubeapi"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"RESTRICT_KUBEAPI"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"[ ]"})}),(0,s.jsxs)(d.td,{children:["Allows restricting access to kubernetes API by list of CIDRs. Empty list (default) means public, ",(0,s.jsx)(d.code,{children:'[ "none" ]'})," means internal access only."]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:"``"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"OPENSTACK_CLUSTER_GEN"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"geno01"})}),(0,s.jsx)(d.td,{children:"Generation counter for the OpenStackClusterTemplate resource. Increase, when changing restrict_kubeapi or other OC settings"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"capo_instance_create_timeout"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"CLUSTER_API_OPENSTACK_INSTANCE_CREATE_TIMEOUT"})}),(0,s.jsx)(d.td,{children:"capo"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"5"})}),(0,s.jsx)(d.td,{children:"Time to wait for an OpenStack machine to be created (in minutes)"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"containerd_registry_files"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:'{"hosts":["./files/containerd/docker.io"], "certs":[]}'})}),(0,s.jsxs)(d.td,{children:["Containerd registry hosts config files, see related ",(0,s.jsx)(d.a,{href:"/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration",children:"docs"})," for details."]})]})]})]}),"\n",(0,s.jsx)(d.p,{children:"Optional services deployed to cluster:"}),"\n",(0,s.jsxs)(d.table,{children:[(0,s.jsx)(d.thead,{children:(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.th,{children:"environment"}),(0,s.jsx)(d.th,{children:"clusterctl.yaml"}),(0,s.jsx)(d.th,{children:"provenance"}),(0,s.jsx)(d.th,{children:"default"}),(0,s.jsx)(d.th,{children:"script"}),(0,s.jsx)(d.th,{children:"meaning"})]})}),(0,s.jsxs)(d.tbody,{children:[(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"deploy_metrics"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"DEPLOY_METRICS"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"true"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"apply_metrics.sh"})}),(0,s.jsxs)(d.td,{children:["Deploy metrics service to nodes to make ",(0,s.jsx)(d.code,{children:"kubectl top"})," work"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"deploy_nginx_ingress"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"DEPLOY_NGINX_INGRESS"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"true"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"apply_nginx_ingress.sh"})}),(0,s.jsxs)(d.td,{children:["Deploy NGINX ingress controller (this spawns an OpenStack Loadbalancer), pass version to explicitly choose the version, ",(0,s.jsx)(d.code,{children:"true"})," results in ",(0,s.jsx)(d.code,{children:"v1.9.6"})," (supported k8s >= 1.25)"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:"``"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"NGINX_INGRESS_PROXY"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"true"})}),(0,s.jsx)(d.td,{children:"(dito)"}),(0,s.jsx)(d.td,{children:"Configure LB and nginx to get real IP via PROXY protocol; trouble for pod to LB connections has been resolved by setting hostname"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"use_ovn_lb_provider"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"USE_OVN_LB_PROVIDER"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"false"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"apply_nginx_ingress.sh"})}),(0,s.jsxs)(d.td,{children:["Clouds using OVN networking can deploy the OVN provider that has low overhead (L3) and makes real client IPs visible without proxy protocol hacks. Set to ",(0,s.jsx)(d.code,{children:"auto"})," to enable."]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"deploy_gateway_api"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"DEPLOY_GATEWAY_API"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"false"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"create_cluster.sh"})}),(0,s.jsx)(d.td,{children:'Deploy Gateway APIs CRDs and enable ciliums Gateway API implementation. This only works in conjunction with USE_CILIUM=true. Also this will break at least one CNCF conformance test. This feature is considered a tech-review. Keep in mind that Gateway API itself is under development and not GA. Also note that ciliums implementation of Gateway API is considered "beta".'})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"deploy_cert_manager"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"DEPLOY_CERT_MANAGER"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"false"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"apply_cert_manager.sh"})}),(0,s.jsxs)(d.td,{children:["Deploy cert-manager, pass version (e.g. ",(0,s.jsx)(d.code,{children:"v1.14.2"}),") to explicitly choose a version"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"deploy_flux"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"DEPLOY_FLUX"})}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"false"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"create_cluster.sh"})}),(0,s.jsx)(d.td,{children:"Deploy flux2 into the cluster"})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"deploy_harbor"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"false"})}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"deploy_harbor.sh"})}),(0,s.jsxs)(d.td,{children:["Deploy harbor into the cluster. When enabled, it will overwrite the settings above. Harbor forces deployment of ",(0,s.jsx)(d.code,{children:"flux"})," and based on config, it can force deployment of other dependencies (",(0,s.jsx)(d.code,{children:"cert-manager"}),", ",(0,s.jsx)(d.code,{children:"ingress-nginx"})," and ",(0,s.jsx)(d.code,{children:"Cinder CSI"}),")"]})]}),(0,s.jsxs)(d.tr,{children:[(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:"harbor_config"})}),(0,s.jsx)(d.td,{}),(0,s.jsx)(d.td,{children:"SCS"}),(0,s.jsx)(d.td,{children:(0,s.jsx)(d.code,{children:'{domain_name:"", issuer_email:"", persistence:false, database_size:"1Gi", redis_size:"1Gi", trivy_size:"5Gi"}'})}),(0,s.jsx)(d.td,{children:"(dito)"}),(0,s.jsxs)(d.td,{children:["Harbor container registry configuration options, see related ",(0,s.jsx)(d.a,{href:"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor",children:"docs"})," for details."]})]})]})]})]})}function x(e={}){const{wrapper:d}={...(0,n.R)(),...e.components};return d?(0,s.jsx)(d,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,d,r)=>{r.d(d,{R:()=>t,x:()=>i});var s=r(96540);const n={},c=s.createContext(n);function t(e){const d=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(d):{...d,...e}}),[d,e])}function i(e){let d;return d=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:t(e.components),s.createElement(c.Provider,{value:d},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a51f78bf.00caed35.js b/assets/js/a51f78bf.00caed35.js new file mode 100644 index 0000000000..de44e4747b --- /dev/null +++ b/assets/js/a51f78bf.00caed35.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[825],{32812:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>c,default:()=>m,frontMatter:()=>s,metadata:()=>l,toc:()=>d});var i=n(74848),o=n(28453);const s={sidebar_label:"Timezone"},c="Timezone",l={id:"iaas/guides/configuration-guide/commons/timezone",title:"Timezone",description:"With the osism.commons.timezone role, it is possible to manage the used timezone on a node.",source:"@site/docs/02-iaas/guides/configuration-guide/commons/timezone.md",sourceDirName:"02-iaas/guides/configuration-guide/commons",slug:"/iaas/guides/configuration-guide/commons/timezone",permalink:"/docs/iaas/guides/configuration-guide/commons/timezone",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/timezone.md",tags:[],version:"current",frontMatter:{sidebar_label:"Timezone"},sidebar:"docs",previous:{title:"Sysctl",permalink:"/docs/iaas/guides/configuration-guide/commons/sysctl"},next:{title:"User",permalink:"/docs/iaas/guides/configuration-guide/commons/user"}},r={},d=[];function a(e){const t={a:"a",code:"code",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"timezone",children:"Timezone"}),"\n",(0,i.jsxs)(t.p,{children:["With the ",(0,i.jsx)(t.code,{children:"osism.commons.timezone"})," role, it is possible to manage the used timezone on a node."]}),"\n",(0,i.jsxs)(t.p,{children:["This role is just a wrapper for the ",(0,i.jsx)(t.a,{href:"https://docs.ansible.com/ansible/latest/collections/community/general/timezone_module.html",children:"community.general.timezone"}),"\nmodule. The role also installs the ",(0,i.jsx)(t.code,{children:"tzdata"})," package."]}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{style:{textAlign:"left"},children:"Parameter"}),(0,i.jsx)(t.th,{style:{textAlign:"left"},children:"Default"}),(0,i.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"timezone_hwclock"})}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"UTC"})}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Whether the hardware clock is in UTC or in local timezone."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"timezone_name"})}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:(0,i.jsx)(t.code,{children:"UTC"})}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Name of the timezone for the system clock."})]})]})]})]})}function m(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>l});var i=n(96540);const o={},s=i.createContext(o);function c(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a52c62d4.0205f572.js b/assets/js/a52c62d4.0205f572.js new file mode 100644 index 0000000000..48509ede63 --- /dev/null +++ b/assets/js/a52c62d4.0205f572.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5568],{45095:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var a=n(74848),o=n(28453);const i={},r="SIG Standardization",s={id:"collaboration/sig-standardization",title:"SIG Standardization",description:"In this Special Interest Group, we discuss and align our activities and approach to standardization and certification. That is to say, we devise and refine the relevant concepts and processes; we work on a roadmap for new certificate versions; and we align on which standards are desireable for each certificate subject. We then work with the teams to align on existing or new standards.",source:"@site/community/collaboration/sig-standardization.md",sourceDirName:"collaboration",slug:"/collaboration/sig-standardization",permalink:"/community/collaboration/sig-standardization",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"SIG Monitoring",permalink:"/community/collaboration/sig-monitoring"},next:{title:"Tools",permalink:"/community/category/tools"}},c={},d=[];function l(e){const t={h1:"h1",p:"p",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h1,{id:"sig-standardization",children:"SIG Standardization"}),"\n",(0,a.jsx)(t.p,{children:"In this Special Interest Group, we discuss and align our activities and approach to standardization and certification. That is to say, we devise and refine the relevant concepts and processes; we work on a roadmap for new certificate versions; and we align on which standards are desireable for each certificate subject. We then work with the teams to align on existing or new standards."}),"\n",(0,a.jsx)(t.p,{children:"Besides aspects of openness and sovereignty, the main goal of our standards is interoperability. We should take the user perspective: As a member of a DevOps team developing a service (think SaaS or PaaS) for SCS, I need XYZ. Every standard should be abstract enough to work regardless of the SCS reference implementation."})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>s});var a=n(96540);const o={},i=a.createContext(o);function r(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a52f8495.c6f0d514.js b/assets/js/a52f8495.c6f0d514.js new file mode 100644 index 0000000000..c6244921b2 --- /dev/null +++ b/assets/js/a52f8495.c6f0d514.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9691],{43642:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>d,toc:()=>o});var n=s(74848),r=s(28453);const c={},a="scs-0400: Status Page create decision",d={id:"ops/scs-0400",title:"scs-0400: Status Page create decision",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/ops/scs-0400.md",sourceDirName:"ops",slug:"/ops/scs-0400",permalink:"/standards/ops/scs-0400",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Ops Standards",permalink:"/standards/ops/"},next:{title:"Status Page create decision",permalink:"/standards/scs-0400-v1-status-page-create-decision"}},i={},o=[];function l(e){const t={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"scs-0400-status-page-create-decision",children:"scs-0400: Status Page create decision"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Version"}),(0,n.jsx)(t.th,{children:"Type"}),(0,n.jsx)(t.th,{children:"State"}),(0,n.jsx)(t.th,{children:"stabilized"}),(0,n.jsx)(t.th,{children:"deprecated"})]})}),(0,n.jsx)(t.tbody,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/standards/scs-0400-v1-status-page-create-decision",children:"scs-0400-v1"})}),(0,n.jsx)(t.td,{children:"Decision Record"}),(0,n.jsx)(t.td,{children:"Draft"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>d});var n=s(96540);const r={},c=n.createContext(r);function a(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a63812ab.92e0cba0.js b/assets/js/a63812ab.92e0cba0.js new file mode 100644 index 0000000000..f45de94017 --- /dev/null +++ b/assets/js/a63812ab.92e0cba0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6147],{80510:(t,o,e)=>{e.r(o),e.d(o,{assets:()=>s,contentTitle:()=>a,default:()=>l,frontMatter:()=>r,metadata:()=>c,toc:()=>u});var n=e(74848),i=e(28453);const r={title:"SIG Documentation",operator:"Max Wolfs",time:"bi-weekly mondays 11-12 CET"},a=void 0,c={id:"collaboration/sig-documentation",title:"SIG Documentation",description:"We curate and enhance the SCS Documentation, focusing on refining its information architecture for optimal usability. Our objective is to facilitate straightforward contributions from community developers and to provide operators with a clear, quick reference guide that accelerates the initiation of an SCS deployment.",source:"@site/community/collaboration/sig-documentation.md",sourceDirName:"collaboration",slug:"/collaboration/sig-documentation",permalink:"/community/collaboration/sig-documentation",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SIG Documentation",operator:"Max Wolfs",time:"bi-weekly mondays 11-12 CET"},sidebar:"community",previous:{title:"SIG Community",permalink:"/community/collaboration/sig-community"},next:{title:"SIG Monitoring",permalink:"/community/collaboration/sig-monitoring"}},s={},u=[];function m(t){const o={p:"p",...(0,i.R)(),...t.components};return(0,n.jsx)(o.p,{children:"We curate and enhance the SCS Documentation, focusing on refining its information architecture for optimal usability. Our objective is to facilitate straightforward contributions from community developers and to provide operators with a clear, quick reference guide that accelerates the initiation of an SCS deployment."})}function l(t={}){const{wrapper:o}={...(0,i.R)(),...t.components};return o?(0,n.jsx)(o,{...t,children:(0,n.jsx)(m,{...t})}):m(t)}},28453:(t,o,e)=>{e.d(o,{R:()=>a,x:()=>c});var n=e(96540);const i={},r=n.createContext(i);function a(t){const o=n.useContext(r);return n.useMemo((function(){return"function"==typeof t?t(o):{...o,...t}}),[o,t])}function c(t){let o;return o=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:a(t.components),n.createElement(r.Provider,{value:o},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/a6aa9e1f.4145c44f.js b/assets/js/a6aa9e1f.4145c44f.js new file mode 100644 index 0000000000..8977cb011c --- /dev/null +++ b/assets/js/a6aa9e1f.4145c44f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7643],{35124:(e,t,a)=>{a.r(t),a.d(t,{default:()=>f});a(96540);var n=a(18215),i=a(44586),r=a(61213),o=a(17559),s=a(26535),l=a(47713),d=a(41463),c=a(33892),g=a(5260),p=a(6676),u=a(74848);function m(e){const t=(0,p.k)(e);return(0,u.jsx)(g.A,{children:(0,u.jsx)("script",{type:"application/ld+json",children:JSON.stringify(t)})})}function h(e){const{metadata:t}=e,{siteConfig:{title:a}}=(0,i.A)(),{blogDescription:n,blogTitle:o,permalink:s}=t,l="/"===s?a:o;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(r.be,{title:l,description:n}),(0,u.jsx)(d.A,{tag:"blog_posts_list"})]})}function b(e){const{metadata:t,items:a,sidebar:n}=e;return(0,u.jsxs)(s.A,{sidebar:n,children:[(0,u.jsx)(c.A,{items:a}),(0,u.jsx)(l.A,{metadata:t})]})}function f(e){return(0,u.jsxs)(r.e3,{className:(0,n.A)(o.G.wrapper.blogPages,o.G.page.blogListPage),children:[(0,u.jsx)(h,{...e}),(0,u.jsx)(m,{...e}),(0,u.jsx)(b,{...e})]})}},47713:(e,t,a)=>{a.d(t,{A:()=>o});a(96540);var n=a(21312),i=a(39022),r=a(74848);function o(e){const{metadata:t}=e,{previousPage:a,nextPage:o}=t;return(0,r.jsxs)("nav",{className:"pagination-nav","aria-label":(0,n.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[a&&(0,r.jsx)(i.A,{permalink:a,title:(0,r.jsx)(n.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer Entries"})}),o&&(0,r.jsx)(i.A,{permalink:o,title:(0,r.jsx)(n.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older Entries"}),isNext:!0})]})}},33892:(e,t,a)=>{a.d(t,{A:()=>o});a(96540);var n=a(7131),i=a(24651),r=a(74848);function o(e){let{items:t,component:a=i.A}=e;return(0,r.jsx)(r.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,r.jsx)(n.i,{content:t,children:(0,r.jsx)(a,{children:(0,r.jsx)(t,{})})},t.metadata.permalink)}))})}},6676:(e,t,a)=>{a.d(t,{k:()=>c,J:()=>g});var n=a(86025),i=a(44586),r=a(36803);var o=a(7131);const s=e=>new Date(e).toISOString();function l(e){const t=e.map(p);return{author:1===t.length?t[0]:t}}function d(e,t,a){return e?{image:u({imageUrl:t(e,{absolute:!0}),caption:`title image for the blog post: ${a}`})}:{}}function c(e){const{siteConfig:t}=(0,i.A)(),{withBaseUrl:a}=(0,n.h)(),{metadata:{blogDescription:r,blogTitle:o,permalink:c}}=e,g=`${t.url}${c}`;return{"@context":"https://schema.org","@type":"Blog","@id":g,mainEntityOfPage:g,headline:o,description:r,blogPost:e.items.map((e=>function(e,t,a){const{assets:n,frontMatter:i,metadata:r}=e,{date:o,title:c,description:g,lastUpdatedAt:p}=r,u=n.image??i.image,m=i.keywords??[],h=`${t.url}${r.permalink}`,b=p?s(p):void 0;return{"@type":"BlogPosting","@id":h,mainEntityOfPage:h,url:h,headline:c,name:c,description:g,datePublished:o,...b?{dateModified:b}:{},...l(r.authors),...d(u,a,c),...m?{keywords:m}:{}}}(e.content,t,a)))}}function g(){const e=function(){const e=(0,r.A)(),t=e?.data?.blogMetadata;if(!t)throw new Error("useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context");return t}(),{assets:t,metadata:a}=(0,o.e)(),{siteConfig:c}=(0,i.A)(),{withBaseUrl:g}=(0,n.h)(),{date:p,title:u,description:m,frontMatter:h,lastUpdatedAt:b}=a,f=t.image??h.image,x=h.keywords??[],j=b?s(b):void 0,A=`${c.url}${a.permalink}`;return{"@context":"https://schema.org","@type":"BlogPosting","@id":A,mainEntityOfPage:A,url:A,headline:u,name:u,description:m,datePublished:p,...j?{dateModified:j}:{},...l(a.authors),...d(f,g,u),...x?{keywords:x}:{},isPartOf:{"@type":"Blog","@id":`${c.url}${e.blogBasePath}`,name:e.blogTitle}}}function p(e){return{"@type":"Person",...e.name?{name:e.name}:{},...e.title?{description:e.title}:{},...e.url?{url:e.url}:{},...e.email?{email:e.email}:{},...e.imageURL?{image:e.imageURL}:{}}}function u(e){let{imageUrl:t,caption:a}=e;return{"@type":"ImageObject","@id":t,url:t,contentUrl:t,caption:a}}}}]); \ No newline at end of file diff --git a/assets/js/a7023ddc.6dc95e53.js b/assets/js/a7023ddc.6dc95e53.js new file mode 100644 index 0000000000..7f62a72e23 --- /dev/null +++ b/assets/js/a7023ddc.6dc95e53.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9267],{28289:o=>{o.exports=JSON.parse('[{"label":"community","permalink":"/blog/tags/community","count":1},{"label":"howto","permalink":"/blog/tags/howto","count":1}]')}}]); \ No newline at end of file diff --git a/assets/js/a708848c.45ed87c9.js b/assets/js/a708848c.45ed87c9.js new file mode 100644 index 0000000000..6c3ece17d9 --- /dev/null +++ b/assets/js/a708848c.45ed87c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7980],{79716:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var o=a(74848),i=a(28453);const t={sidebar_label:"Project Manager",sidebar_position:53},s="Project Manager",r={id:"iaas/components/project-manager",title:"Project Manager",description:"Overview",source:"@site/docs/02-iaas/components/project-manager.md",sourceDirName:"02-iaas/components",slug:"/iaas/components/project-manager",permalink:"/docs/iaas/components/project-manager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/project-manager.md",tags:[],version:"current",sidebarPosition:53,frontMatter:{sidebar_label:"Project Manager",sidebar_position:53}},c={},d=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Defaults",id:"defaults",level:2},{value:"create.py",id:"createpy",level:3},{value:"manage.py",id:"managepy",level:3},{value:"Usage",id:"usage",level:2},{value:"create.py",id:"createpy-1",level:3},{value:"Create a Domain and inital project",id:"create-a-domain-and-inital-project",level:4},{value:"Create a User for a project",id:"create-a-user-for-a-project",level:4},{value:"Create additional project with unlimited quota",id:"create-additional-project-with-unlimited-quota",level:4},{value:"Set quotas for a project",id:"set-quotas-for-a-project",level:4},{value:"Special project: images",id:"special-project-images",level:4},{value:"Special project: service",id:"special-project-service",level:4},{value:"manage.py",id:"managepy-1",level:3},{value:"Manage a specific domain only",id:"manage-a-specific-domain-only",level:4},{value:"Config files",id:"config-files",level:2},{value:"Quota Templates",id:"quota-templates",level:2},{value:"Setup Endpoints",id:"setup-endpoints",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"project-manager",children:"Project Manager"}),"\n",(0,o.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,o.jsx)(n.p,{children:"The OpenStack Project Manager manages the creation of Openstack Domains, Projects and Users."}),"\n",(0,o.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,o.jsx)(n.p,{children:"Prepare to use the Openstack Project Manager."}),"\n",(0,o.jsx)(n.p,{children:"During installation, ldap libraries are required under Linux; you should install libldap2-dev and libsasl2-dev beforehand."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"git clone https://github.com/osism/openstack-project-manager\ncd openstack-project-manager\npipenv install\npipenv shell\n"})}),"\n",(0,o.jsx)(n.h2,{id:"defaults",children:"Defaults"}),"\n",(0,o.jsx)(n.h3,{id:"createpy",children:"create.py"}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"create.py"})," command and his default options while executing the command."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:" --admin-domain default\n --assign-admin-user true\n --cloud admin\n --create-admin-user true\n --create-domain false\n --create-user false\n --domain-name-prefix true\n --has-service-network false\n --has-public-network true\n --has-shared-images true\n --internal-id unset\n --random false\n --managed-network-resources false\n --name sandbox\n --owner unset\n --password unset\n --password-length 16\n --public-network public\n --quota-class basic\n --service-network-cidr unset\n --quota-multiplier 1\n --quota-multiplier-compute unset\n --quota-multiplier-network unset\n --quota-multiplier-storage unset\n --quota-router 1\n"})}),"\n",(0,o.jsx)(n.h3,{id:"managepy",children:"manage.py"}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"manage.py"})," has also some defaults while executing and will touch all projects in your Openstack Cluster, if not --domain is used."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:" --admin-domain default\n --assign-admin-user false\n --classes etc/classes.yml\n --domain unset\n --dry-run false\n --endpoints etc/endpoints.yml\n --manage-endpoints false\n --manage-homeprojects false\n --name unset\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Default Openstack Roles to users are set to ",(0,o.jsx)(n.code,{children:"member"})," and ",(0,o.jsx)(n.code,{children:"load-balancer_member"})," at this time, the behavior can only be changed in the code."]}),"\n",(0,o.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,o.jsxs)(n.p,{children:["There must be a ",(0,o.jsx)(n.code,{children:"clouds.yml"})," and a ",(0,o.jsx)(n.code,{children:"secure.yml"})," file in the directory where the OpenStack Project Manager will be executed, examples are provided within the git repository."]}),"\n",(0,o.jsx)(n.p,{children:"The cloud profile to be used can be specified via the optional --cloud parameter. By default the cloud profile with the name admin is used. It has to be and admin account, to create and modify domains, projects, users and quotas."}),"\n",(0,o.jsxs)(n.p,{children:["The Openstack Project Manager essentially consists of two parts, the ",(0,o.jsx)(n.code,{children:"create.py"})," and the ",(0,o.jsx)(n.code,{children:"manage.py"}),", there are more scripts for handling users using ldap which needs more configuration setup."]}),"\n",(0,o.jsx)(n.h3,{id:"createpy-1",children:"create.py"}),"\n",(0,o.jsx)(n.p,{children:"This command is used to create and modify domains, projects, users and quotas. As default the domain is used as prefix for all projects and users created for easy alloction in Openstack."}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsx)(n.p,{children:"create.py can't delete once created objects, this must be done using Openstack commands to remove a project or domain."})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"python src/create.py -h\nusage: create [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--create-admin-user] [--create-domain] [--create-user]\n [--domain DOMAIN] [--domain-name-prefix] [--has-public-network] [--has-service-network] [--has-shared-images] [--internal-id INTERNAL_ID] [--managed-network-resources] [--name NAME]\n [--noassign-admin-user] [--nocreate-admin-user] [--nocreate-domain] [--nocreate-user] [--nodomain-name-prefix] [--nohas-public-network] [--nohas-service-network]\n [--nohas-shared-images] [--nomanaged-network-resources] [--norandom] [--owner OWNER] [--password PASSWORD] [--password-length PASSWORD_LENGTH] [--public-network PUBLIC_NETWORK]\n [--quota-class QUOTA_CLASS] [--quota-multiplier QUOTA_MULTIPLIER] [--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE] [--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK]\n [--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE] [--quota-router QUOTA_ROUTER] [--random] [--service-network-cidr SERVICE_NETWORK_CIDR]\n\noptions:\n -h, --help show this help message and exit\n --admin-domain ADMIN_DOMAIN\n Admin domain\n --assign-admin-user Assign admin user\n --cloud CLOUD Managed cloud\n --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set\n is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the\n command-line.\n --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the\n command-line.\n --create-admin-user Create admin user\n --create-domain Create domain only\n --create-user Create user\n --domain DOMAIN Domain\n --domain-name-prefix Add domain name as prefix to the project name\n --has-public-network Has public network infrastructure\n --has-service-network\n Has service network infrastructure\n --has-shared-images Has shared images\n --internal-id INTERNAL_ID\n Internal ID\n --managed-network-resources\n Manage the network resources\n --name NAME Projectname\n --noassign-admin-user\n The inverse of --assign-admin-user\n --nocreate-admin-user\n The inverse of --create-admin-user\n --nocreate-domain The inverse of --create-domain\n --nocreate-user The inverse of --create-user\n --nodomain-name-prefix\n The inverse of --domain-name-prefix\n --nohas-public-network\n The inverse of --has-public-network\n --nohas-service-network\n The inverse of --has-service-network\n --nohas-shared-images\n The inverse of --has-shared-images\n --nomanaged-network-resources\n The inverse of --managed-network-resources\n --norandom The inverse of --random\n --owner OWNER Owner of the project\n --password PASSWORD Password\n --password-length PASSWORD_LENGTH\n Password length\n --public-network PUBLIC_NETWORK\n Public network\n --quota-class QUOTA_CLASS\n Quota class\n --quota-multiplier QUOTA_MULTIPLIER\n Quota multiplier\n --quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE\n Quota multiplier compute\n --quota-multiplier-network QUOTA_MULTIPLIER_NETWORK\n Quota multiplier network\n --quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE\n Quota multiplier storage\n --quota-router QUOTA_ROUTER\n Quota router\n --random Generate random names\n --service-network-cidr SERVICE_NETWORK_CIDR\n Service network CIDR\n"})}),"\n",(0,o.jsx)(n.h4,{id:"create-a-domain-and-inital-project",children:"Create a Domain and inital project"}),"\n",(0,o.jsxs)(n.p,{children:["When executing the ",(0,o.jsx)(n.code,{children:"create.py"})," command, the first time with ",(0,o.jsx)(n.code,{children:"--domain"}),", it will create a new domain, an admin account and the first project ",(0,o.jsx)(n.code,{children:"webshop"}),". The admin account will be created in the default Domain of Openstack and can be used for the Service Provider to manager the complete domain."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name webshop\n+----------------+----------------------+----------------------------------+\n| name | value | id |\n|----------------+----------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-webshop | 645538bf67664cfeaed32476d58f95fb |\n| admin | democompany-admin | cc8d6bf7b61d4199ba5a4230c4ec6d62 |\n| admin_password | qawsEdfg2d45Fsxc | |\n+----------------+----------------------+----------------------------------+\n"})}),"\n",(0,o.jsx)(n.h4,{id:"create-a-user-for-a-project",children:"Create a User for a project"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name webshopuser --create-user \n+----------+-------------------------+----------------------------------+\n| name | value | id |\n|----------+-------------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-webshop | 5752b6701026478f9cac122fc54eb9cb |\n| user | democompany-webshopuser | ce213655559d47d7800501124fed4d02 |\n| password | vEvM9vgRESdffWE2 | |\n+----------+-------------------------+----------------------------------+\n"})}),"\n",(0,o.jsx)(n.h4,{id:"create-additional-project-with-unlimited-quota",children:"Create additional project with unlimited quota"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name styles --quota-class unlimited\n+----------+--------------------+----------------------------------+\n| name | value | id |\n|----------+--------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-styles | 666097e396fd4f9392d6aa55c76d8267 |\n+----------+--------------------+----------------------------------+\n"})}),"\n",(0,o.jsx)(n.h4,{id:"set-quotas-for-a-project",children:"Set quotas for a project"}),"\n",(0,o.jsxs)(n.p,{children:["All quota information must be set as a property to the Openstack project within your Openstack Cluster, if no property is set, the ",(0,o.jsx)(n.code,{children:"basic"})," quotaclass of ",(0,o.jsx)(n.code,{children:"etc/classes.yml"})," will be applied.\nIt is possible to set a quota multiplier for any project."]}),"\n",(0,o.jsx)(n.p,{children:"The following command you set a multiplier of 256 of the basic quota:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ openstack project set --property quotamultiplier=256 democompany-webshop\n"})}),"\n",(0,o.jsx)(n.p,{children:"Adjusting gigabyte quota for storage with a multiplier of 20 of the basic quota for a project:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ openstack project set --property quotamultiplier_storage=20 democompany-webshop\n"})}),"\n",(0,o.jsx)(n.p,{children:"This will override the general quotamultiplier only for storage."}),"\n",(0,o.jsxs)(n.p,{children:["Other possible multiplier which can be set individually are: ",(0,o.jsx)(n.code,{children:"quotamultiplier_compute"}),", ",(0,o.jsx)(n.code,{children:"quotamultiplier_network"}),", ",(0,o.jsx)(n.code,{children:"quota_router"})]}),"\n",(0,o.jsxs)(n.p,{children:["To change the quotaclass to unlimited from the ",(0,o.jsx)(n.code,{children:"etc/classes.yaml"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ openstack project set --property quotaclass=unlimited democompany-webshop\n"})}),"\n",(0,o.jsx)(n.h4,{id:"special-project-images",children:"Special project: images"}),"\n",(0,o.jsxs)(n.p,{children:["With this special Project you can share all images uploaded into this project to all other project in your domain which has set the property ",(0,o.jsx)(n.code,{children:"has-shared-images"}),", which is by default set.\nAlsoi only the domain-admin user has access to this project, other domain users won't see this, they will find the uploaded images in their projects.\nIf you want your grant other domain users also access to upload some images, you need to give them access to the images Project in Openstack."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name images\n+---------+---------------------+----------------------------------+\n| name | value | id |\n|---------+---------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-images | 6d57f39aacbe485d87733865b1e79d03 |\n+---------+---------------------+----------------------------------+\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Additionally you need to add the domain and domain-admin user to the ",(0,o.jsx)(n.code,{children:"clouds.yaml"}),", it is always named ",(0,o.jsx)(n.code,{children:"opm-domainname-admin:"})," so the manage.py can setup permissions to the projects later on and users are able to find the images."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:" opm-democompany-admin:\n auth:\n auth_url: https://keystone.my.cloud:5000/v3\n username: democompany-admin\n password: yourpassword\n user_domain_name: Default\n project_domain_name: democompany \n identity_api_version: 3\n"})}),"\n",(0,o.jsx)(n.h4,{id:"special-project-service",children:"Special project: service"}),"\n",(0,o.jsx)(n.p,{children:"With this special project you can share installed services, like a harbor, to all other projects in your domain. Per default, only the domain admin has access to this project."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ python3 src/create.py --domain democompany --name service\n+---------+---------------------+----------------------------------+\n| name | value | id |\n|---------+---------------------+----------------------------------|\n| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |\n| project | democompany-service | a5558f7338f94adea5f41858636256b5 |\n+---------+---------------------+----------------------------------+\n"})}),"\n",(0,o.jsx)(n.h3,{id:"managepy-1",children:"manage.py"}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsxs)(n.p,{children:["This command applies quotas, networks and routers to ",(0,o.jsx)(n.strong,{children:"all"})," projects in the Openstack Cluster, not only to those have been configured previously with the ",(0,o.jsx)(n.code,{children:"create.py"})," or ",(0,o.jsx)(n.code,{children:"openstack project set --property"})," commands."]})}),"\n",(0,o.jsx)(n.p,{children:"Best is to run this command by cron, every hour to apply all pending changes, it is also possible to run this at the command line to apply changes immediately."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"python3 src/manage.py -h\nusage: manage [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--classes CLASSES] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--domain DOMAIN] [--dry-run]\n [--endpoints ENDPOINTS] [--manage-endpoints] [--manage-homeprojects] [--name NAME] [--noassign-admin-user] [--nodry-run] [--nomanage-endpoints] [--nomanage-homeprojects]\n\noptions:\n -h, --help show this help message and exit\n --admin-domain ADMIN_DOMAIN\n Admin domain\n --assign-admin-user Assign admin user\n --classes CLASSES Path to the classes.yml file\n --cloud CLOUD Cloud name in clouds.yaml\n --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set\n is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the\n command-line.\n --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the\n command-line.\n --domain DOMAIN Domain to be managed\n --dry-run Do not really do anything\n --endpoints ENDPOINTS\n Path to the endpoints.yml file\n --manage-endpoints Manage endpoints\n --manage-homeprojects\n Manage home projects\n --name NAME Project to be managed\n --noassign-admin-user\n The inverse of --assign-admin-user\n --nodry-run The inverse of --dry-run\n --nomanage-endpoints The inverse of --manage-endpoints\n --nomanage-homeprojects\n The inverse of --manage-homeprojects\n"})}),"\n",(0,o.jsx)(n.h4,{id:"manage-a-specific-domain-only",children:"Manage a specific domain only"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"$ python3 src/manage.py --domain democompany\n\n2024-04-19 14:24:02.873 | INFO | democompany - domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03\n2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03, domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:04.953 | INFO | democompany-images - quotaclass {'compute': {'cores': 0, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 0, 'key_pairs': 0, 'metadata_items': 128, 'ram': 0, 'server_group_members': 0, 'server_groups': 0}, 'network': {'floatingip': 0, 'network': 0, 'port': 0, 'rbac_policy': 0, 'router': 0, 'security_group': 0, 'security_group_rule': 0, 'subnet': 0, 'subnetpool': 0}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 1000, 'per_volume_gigabytes': 25, 'snapshots': 0, 'volumes': 100}, 'parent': 'default'}\n2024-04-19 14:24:04.953 | INFO | democompany-images - check network quota\n2024-04-19 14:24:05.048 | INFO | democompany-images - check compute quota\n2024-04-19 14:24:05.175 | INFO | democompany-images - check volume quota\n2024-04-19 14:24:05.286 | INFO | democompany-images - check if external rbac policy must be deleted (public)\n2024-04-19 14:24:05.349 | INFO | democompany-images - check if service rbac policy must be deleted (democompany-service)\n2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5\n2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5, domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:06.131 | INFO | democompany-service - quotaclass {'compute': {'cores': 256, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 256, 'key_pairs': 256, 'metadata_items': 128, 'ram': 262144, 'server_group_members': 256, 'server_groups': 256}, 'network': {'floatingip': 256, 'network': 256, 'port': 256, 'rbac_policy': 1024, 'router': 256, 'security_group': 256, 'security_group_rule': 1024, 'subnet': 256, 'subnetpool': 256}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 0, 'per_volume_gigabytes': 0, 'snapshots': 0, 'volumes': 0}, 'parent': 'default'}\n2024-04-19 14:24:06.131 | INFO | democompany-service - check network quota\n2024-04-19 14:24:06.212 | INFO | democompany-service - check compute quota\n2024-04-19 14:24:06.330 | INFO | democompany-service - check volume quota\n2024-04-19 14:24:06.467 | INFO | democompany-service - check if external rbac policy must be created (public)\n2024-04-19 14:24:06.589 | INFO | democompany-service - check if service rbac policy must be deleted (democompany-service)\n2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb\n2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb, domain_id = a8549ef5d3d14f938b127a1cdefe3788\n2024-04-19 14:24:06.915 | INFO | democompany-webshop - quotaclass {'compute': {'cores': 4, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': -1, 'key_pairs': 4, 'metadata_items': 128, 'ram': 8192, 'server_group_members': 4, 'server_groups': 4}, 'network': {'floatingip': 4, 'network': 1, 'port': 20, 'rbac_policy': 10, 'router': 0, 'security_group': 5, 'security_group_rule': 20, 'subnet': 2, 'subnetpool': 1}, 'volume': {'backup_gigabytes': 40, 'backups': 8, 'gigabytes': 20, 'per_volume_gigabytes': 200, 'snapshots': 4, 'volumes': 4}, 'parent': 'default'}\n2024-04-19 14:24:06.915 | INFO | democompany-webshop - check network quota\n2024-04-19 14:24:06.993 | INFO | democompany-webshop - check compute quota\n2024-04-19 14:24:07.114 | INFO | democompany-webshop - check volume quota\n2024-04-19 14:24:07.254 | INFO | democompany-webshop - check if external rbac policy must be created (public)\n2024-04-19 14:24:07.334 | INFO | democompany-webshop - check if service rbac policy must be deleted (democompany-service)\n"})}),"\n",(0,o.jsx)(n.h2,{id:"config-files",children:"Config files"}),"\n",(0,o.jsxs)(n.p,{children:["The config files which can be used for ",(0,o.jsx)(n.code,{children:"create.py"})," and ",(0,o.jsx)(n.code,{children:"manage.py"})," are using the ",(0,o.jsx)(n.a,{href:"https://docs.openstack.org/oslo.config/latest/configuration/quickstart.html",children:"oslo.config format"}),", you can set the command line options as ",(0,o.jsx)(n.code,{children:"key = value pair"})," and create your own config files matching your setup."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="democompany.conf"',children:"[DEFAULT]\ncloud = admin\ndomain = democompany\n"})}),"\n",(0,o.jsx)(n.h2,{id:"quota-templates",children:"Quota Templates"}),"\n",(0,o.jsxs)(n.p,{children:["Edit the ",(0,o.jsx)(n.code,{children:"etc/classes.yml"})," file if you want to change or add new quota templates"]}),"\n",(0,o.jsx)(n.h2,{id:"setup-endpoints",children:"Setup Endpoints"}),"\n",(0,o.jsxs)(n.p,{children:["Edit the ",(0,o.jsx)(n.code,{children:"etc/endpoints.yml"})," file to fit your available endpoints"]})]})}function m(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>r});var o=a(96540);const i={},t=o.createContext(i);function s(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a70dabb3.321321ab.js b/assets/js/a70dabb3.321321ab.js new file mode 100644 index 0000000000..32ae1725b6 --- /dev/null +++ b/assets/js/a70dabb3.321321ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5075],{67821:(s,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>i});var e=n(74848),d=n(28453);const r={},a="scs-0002: Standards, Docs and Organisation",c={id:"global/scs-0002",title:"scs-0002: Standards, Docs and Organisation",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/global/scs-0002.md",sourceDirName:"global",slug:"/global/scs-0002",permalink:"/standards/global/scs-0002",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Sovereign Cloud Standards",permalink:"/standards/scs-0001-v1-sovereign-cloud-standards"},next:{title:"Standards, Docs and Organisation",permalink:"/standards/scs-0002-v1-standards-docs-org"}},o={},i=[];function l(s){const t={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...s.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(t.h1,{id:"scs-0002-standards-docs-and-organisation",children:"scs-0002: Standards, Docs and Organisation"}),"\n",(0,e.jsxs)(t.table,{children:[(0,e.jsx)(t.thead,{children:(0,e.jsxs)(t.tr,{children:[(0,e.jsx)(t.th,{children:"Version"}),(0,e.jsx)(t.th,{children:"Type"}),(0,e.jsx)(t.th,{children:"State"}),(0,e.jsx)(t.th,{children:"stabilized"}),(0,e.jsx)(t.th,{children:"deprecated"})]})}),(0,e.jsxs)(t.tbody,{children:[(0,e.jsxs)(t.tr,{children:[(0,e.jsx)(t.td,{children:(0,e.jsx)(t.a,{href:"/standards/scs-0002-v1-standards-docs-org",children:"scs-0002-v1"})}),(0,e.jsx)(t.td,{children:"Procedural"}),(0,e.jsx)(t.td,{children:"Stable"}),(0,e.jsx)(t.td,{children:"2023-02-06"}),(0,e.jsx)(t.td,{children:"-"})]}),(0,e.jsxs)(t.tr,{children:[(0,e.jsx)(t.td,{children:(0,e.jsx)(t.a,{href:"/standards/scs-0002-v2-standards-docs-org",children:"scs-0002-v2"})}),(0,e.jsx)(t.td,{children:"Procedural"}),(0,e.jsx)(t.td,{children:"Draft"}),(0,e.jsx)(t.td,{children:"-"}),(0,e.jsx)(t.td,{children:"-"})]})]})]})]})}function h(s={}){const{wrapper:t}={...(0,d.R)(),...s.components};return t?(0,e.jsx)(t,{...s,children:(0,e.jsx)(l,{...s})}):l(s)}},28453:(s,t,n)=>{n.d(t,{R:()=>a,x:()=>c});var e=n(96540);const d={},r=e.createContext(d);function a(s){const t=e.useContext(r);return e.useMemo((function(){return"function"==typeof s?s(t):{...t,...s}}),[t,s])}function c(s){let t;return t=s.disableParentContext?"function"==typeof s.components?s.components(d):s.components||d:a(s.components),e.createElement(r.Provider,{value:t},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/a7434565.d434193e.js b/assets/js/a7434565.d434193e.js new file mode 100644 index 0000000000..d8a42dacd1 --- /dev/null +++ b/assets/js/a7434565.d434193e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1678],{4061:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-pages","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/a7bd4aaa.cd50302a.js b/assets/js/a7bd4aaa.cd50302a.js new file mode 100644 index 0000000000..91e3353fa4 --- /dev/null +++ b/assets/js/a7bd4aaa.cd50302a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7098],{74532:(n,e,s)=>{s.r(e),s.d(e,{default:()=>d});s(96540);var r=s(61213),o=s(2967),t=s(32252),c=s(22831),i=s(41463),u=s(74848);function a(n){const{version:e}=n;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(i.A,{version:e.version,tag:(0,o.tU)(e.pluginId,e.version)}),(0,u.jsx)(r.be,{children:e.noIndex&&(0,u.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})]})}function l(n){const{version:e,route:s}=n;return(0,u.jsx)(r.e3,{className:e.className,children:(0,u.jsx)(t.n,{version:e,children:(0,c.v)(s.routes)})})}function d(n){return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(a,{...n}),(0,u.jsx)(l,{...n})]})}}}]); \ No newline at end of file diff --git a/assets/js/a8ea16f4.a91fb1ee.js b/assets/js/a8ea16f4.a91fb1ee.js new file mode 100644 index 0000000000..580f086c5a --- /dev/null +++ b/assets/js/a8ea16f4.a91fb1ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6217],{40032:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=n(74848),o=n(28453);const r={},i="Overview",a={id:"container/components/k8s-cluster-api-provider/doc/overview",title:"Overview",description:"Creating and scaling k8s clusters on demand is providing a lot of flexibility to DevOps teams that develop, test, deploy and operate services and applications.",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/overview.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc",slug:"/container/components/k8s-cluster-api-provider/doc/overview",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/overview",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/overview.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"K8s Cluster API Provider",permalink:"/docs/category/k8s-cluster-api-provider"},next:{title:"Requirements",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/requirements"}},c={},l=[];function d(e){const t={a:"a",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"overview",children:"Overview"}),"\n",(0,s.jsx)(t.p,{children:"Creating and scaling k8s clusters on demand is providing a lot of flexibility to DevOps teams that develop, test, deploy and operate services and applications."}),"\n",(0,s.jsx)(t.p,{children:"We expect the functionality to be mainly consumed in two scenarios:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Self-service: The DevOps team leverages the code provided from this repository to create their own capi management server and use it then to manage a number of k8s clusters for their own needs."}),"\n",(0,s.jsx)(t.li,{children:"Managed k8s: The Operator's service team creates the capi management server and uses it to provide managed k8s clusters for their clients."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Note that we have an intermediate model in mind -- a model where a one-click / one-API call interface would allow the management server to be created on behalf of a user and then serve as an API endpoint to that user's k8s CAPI needs. Ideally with some dashboard or GUI that would shield less experienced users from all the YAML."}),"\n",(0,s.jsx)(t.p,{children:"Once we as the SCS Community have the gitops style cluster control working, the self-service model will become more convenient to use."}),"\n",(0,s.jsx)(t.p,{children:"The provided solution covers the following two main topics:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Automation (opentofu, Makefile) to bootstrap a cluster-API management server by installing kind on a vanilla Ubuntu image and deploying some tools on this node (",(0,s.jsx)(t.a,{href:"https://kubernetes.io/docs/reference/kubectl/overview/",children:"kubectl"}),", ",(0,s.jsx)(t.a,{href:"https://docs.openstack.org/newton/user-guide/common/cli-install-openstack-command-line-clients.html",children:"openstack CLI tools"}),", ",(0,s.jsx)(t.a,{href:"https://github.com/derailed/k9s",children:"k9s"}),", ",(0,s.jsx)(t.a,{href:"https://cilium.io/",children:"cilium"}),", ",(0,s.jsx)(t.a,{href:"https://www.tigera.io/tigera-products/calico/",children:"calico"}),", ",(0,s.jsx)(t.a,{href:"https://helm.sh/",children:"helm"}),", ",(0,s.jsx)(t.a,{href:"https://fluxcd.io/",children:"flux"})," ...) and deploying ",(0,s.jsx)(t.a,{href:"https://cluster-api.sigs.k8s.io/",children:"cluster-API"})," (clusterctl) and the ",(0,s.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/cluster-api-provider-openstack",children:"OpenStack cluster-api provider"})," along with suitable credentials. The opentofu automation is driven by a Makefile for convenience. The tooling also contains all the logic to clean up again. The newly deployed node clones this git repository early in the bootstrap process and uses the thus received files to set up the management cluster and scripts."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["This node can be connected to via ssh and the deployed scripts there can be used to manage workload clusters and then deploy various standardized tools (such as e.g. ",(0,s.jsx)(t.a,{href:"https://github.com/kubernetes/cloud-provider-openstack",children:"OpenStack Cloud Controller Manager"}),"(OCCM), ",(0,s.jsx)(t.a,{href:"https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/cinder-csi-plugin/using-cinder-csi-plugin.md",children:"cinder CSI"}),", calico or cilium CNI, ",(0,s.jsx)(t.a,{href:"https://kubernetes.github.io/ingress-nginx/",children:"nginx ingress controller"}),", ",(0,s.jsx)(t.a,{href:"https://cert-manager.io/",children:"cert-manager"}),", ...) and run tests (e.g. CNCF conformance with ",(0,s.jsx)(t.a,{href:"https://sonobuoy.io/",children:"sonobuoy"}),"). The tools and artifacts can be updated via ",(0,s.jsx)(t.code,{children:"git pull"})," at any time and the updated settings rolled out to the workload clusters. Note that the script collection will eventually be superseded by the ",(0,s.jsx)(t.a,{href:"https://github.com/stackhpc/capi-helm-charts",children:"capi-helm-charts"}),". The medium-term goal is to actually create a reconciliation loop here that would perform life-cycle-management for clusters according to the cluster configuration stored in an enhanced ",(0,s.jsx)(t.a,{href:"https://cluster-api.sigs.k8s.io/clusterctl/configuration.html",children:"cluster-api style"})," clusterctl.yaml from git repositories and thus allow a pure ",(0,s.jsx)(t.a,{href:"https://www.weave.works/technologies/gitops/",children:"gitops"})," style cluster management without ever ssh'ing to the management server."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var s=n(96540);const o={},r=s.createContext(o);function i(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a8f67d60.2dd1c83c.js b/assets/js/a8f67d60.2dd1c83c.js new file mode 100644 index 0000000000..59704c1f26 --- /dev/null +++ b/assets/js/a8f67d60.2dd1c83c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8463],{90478:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>d,default:()=>h,frontMatter:()=>c,metadata:()=>r,toc:()=>l});var i=t(74848),o=t(28453);const c={},d="Adding Docs Guide",r={id:"contribute/adding-docs-guide",title:"Adding Docs Guide",description:"In this Guide you will learn how to integrate your documentation to the SCS documentation, which you will find on docs.scs.community.",source:"@site/community/contribute/adding-docs-guide.md",sourceDirName:"contribute",slug:"/contribute/adding-docs-guide",permalink:"/community/contribute/adding-docs-guide",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Contribute to Docs",permalink:"/community/category/contribute-to-docs"},next:{title:"Documentation Files Structure",permalink:"/community/contribute/doc-files-structure-guide"}},s={},l=[{value:"Step 1 \u2013 Documentation type",id:"step-1--documentation-type",level:2},{value:"1. Technical Documentation",id:"1-technical-documentation",level:2},{value:"Step 1 \u2013 Checklist",id:"step-1--checklist",level:3},{value:"Step 2 \u2013 Adding your repo to the docs.json",id:"step-2--adding-your-repo-to-the-docsjson",level:3},{value:"2. Operational documentation",id:"2-operational-documentation",level:2},{value:"3. Community documentation",id:"3-community-documentation",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"adding-docs-guide",children:"Adding Docs Guide"}),"\n",(0,i.jsxs)(n.p,{children:["In this Guide you will learn how to integrate your documentation to the SCS documentation, which you will find on ",(0,i.jsx)(n.a,{href:"https://docs.scs.community",children:"docs.scs.community"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"step-1--documentation-type",children:"Step 1 \u2013 Documentation type"}),"\n",(0,i.jsx)(n.p,{children:"Determine the type of your documentation and click to continue."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#1-technical-documentation",children:"Technical documentation"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#2-operational-documentation",children:"Operational documentation"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#3-community-documentation",children:"Community documentation"})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If unsure don't hestitate to ask us at ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/communication/matrix.md",children:"Matrix"})]}),"\n",(0,i.jsx)(n.h2,{id:"1-technical-documentation",children:"1. Technical Documentation"}),"\n",(0,i.jsx)(n.h3,{id:"step-1--checklist",children:"Step 1 \u2013 Checklist"}),"\n",(0,i.jsx)(n.p,{children:"Your repository containing the documentation has to..."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"be a public repository"}),"\n",(0,i.jsxs)(n.li,{children:["contain a directory named ",(0,i.jsx)(n.code,{children:"/doc"})," or ",(0,i.jsx)(n.code,{children:"/docs"})," within root, containing the documentation files"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The documentation files have to be in markdown format and..."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["comply ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/github/dco-and-licenses.md",children:"SCS licensing guidelines"})]}),"\n",(0,i.jsxs)(n.li,{children:["match our","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/contribute/doc-files-structure-guide.md",children:"markdown file structure guideline"})}),"\n",(0,i.jsx)(n.li,{children:"linting Rules"}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/contribute/styleguide.md",children:"styleguide"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"step-2--adding-your-repo-to-the-docsjson",children:"Step 2 \u2013 Adding your repo to the docs.json"}),"\n",(0,i.jsxs)(n.p,{children:["File a Pull Request within the ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs-page",children:"docs-page"})," repository and add your repo to the docs.package.json:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'[\n {\n "repo": "demo-organisation/demo-repository",\n "source": "doc/*.md",\n "target": "docs",\n "label": "demo-repository-label"\n }\n]\n'})}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"key"}),(0,i.jsx)(n.th,{children:"description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"repo"}),(0,i.jsx)(n.td,{children:"reference to github organisation and repository"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"source"}),(0,i.jsx)(n.td,{children:"path to content to copy: Either glob matching individual markdown files OR the path of a single directory"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"target"}),(0,i.jsx)(n.td,{children:"directory where the files should be copied to within the docs-page repo"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"label"}),(0,i.jsx)(n.td,{children:"label for directory. only mandatory if source file is set to copy only *.md files and not the complete directory"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["Once it is approved and merged, a postinstall script will be triggered within the build process. This initiates downloading, copy and distilling which results in this static generated ",(0,i.jsx)(n.a,{href:"https://docs.scs.community",children:"documentation"})," page \u2013 now with your content."]}),"\n",(0,i.jsxs)(n.p,{children:["An explanation on how the sync & distill workflow and a guide on how to test it in a local development environment you will find ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/contribute/docs-workflow-explanation.md",children:"here"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"2-operational-documentation",children:"2. Operational documentation"}),"\n",(0,i.jsx)(n.p,{children:"Your doc files contain operational knowledge. Which layer in the stack do they belong to?"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"iaas"}),"\n",(0,i.jsx)(n.li,{children:"iam"}),"\n",(0,i.jsx)(n.li,{children:"kaas"}),"\n",(0,i.jsx)(n.li,{children:"operations"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["File a Pull Request within the ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs",children:"docs"})," repository and add your markdown files to the fitting directory."]}),"\n",(0,i.jsx)(n.h2,{id:"3-community-documentation",children:"3. Community documentation"}),"\n",(0,i.jsxs)(n.p,{children:["Your doc files contain knowledge regarding our community? Choose the right directory. If unsure don't hestitate to ask us at ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs/blob/main/community/communication/matrix.md",children:"Matrix"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["File a Pull Request within the ",(0,i.jsx)(n.code,{children:"docs"})," repository and add your markdown files to the fitting directory."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>r});var i=t(96540);const o={},c=i.createContext(o);function d(e){const n=i.useContext(c);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:d(e.components),i.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a94703ab.1764b2a4.js b/assets/js/a94703ab.1764b2a4.js new file mode 100644 index 0000000000..a5a95c6787 --- /dev/null +++ b/assets/js/a94703ab.1764b2a4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9048],{92559:(e,t,n)=>{n.r(t),n.d(t,{default:()=>be});var a=n(96540),o=n(18215),i=n(61213),s=n(17559),l=n(84142),r=n(26588),c=n(21312),d=n(23104),u=n(75062);const m={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var b=n(74848);function h(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,o]=(0,a.useState)(!1),i=(0,a.useRef)(!1),{startScroll:s,cancelScroll:l}=(0,d.gk)();return(0,d.Mq)(((e,n)=>{let{scrollY:a}=e;const s=n?.scrollY;s&&(i.current?i.current=!1:a>=s?(l(),o(!1)):a<t?o(!1):a+window.innerHeight<document.documentElement.scrollHeight&&o(!0))})),(0,u.$)((e=>{e.location.hash&&(i.current=!0,o(!1))})),{shown:n,scrollToTop:()=>s(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,c.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,o.A)("clean-btn",s.G.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(53109),x=n(56347),j=n(24581),f=n(6342),v=n(23465);function _(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const A={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function g(e){let{onClick:t}=e;return(0,b.jsx)("button",{type:"button",title:(0,c.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,o.A)("button button--secondary button--outline",A.collapseSidebarButton),onClick:t,children:(0,b.jsx)(_,{className:A.collapseSidebarButtonIcon})})}var k=n(65041),C=n(89532);const S=Symbol("EmptyContext"),T=a.createContext(S);function N(e){let{children:t}=e;const[n,o]=(0,a.useState)(null),i=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:o})),[n]);return(0,b.jsx)(T.Provider,{value:i,children:t})}var I=n(41422),B=n(99169),y=n(28774),w=n(92303);function L(e){let{collapsed:t,categoryLabel:n,onClick:a}=e;return(0,b.jsx)("button",{"aria-label":t?(0,c.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:n}):(0,c.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:n}),"aria-expanded":!t,type:"button",className:"clean-btn menu__caret",onClick:a})}function E(e){let{item:t,onItemClick:n,activePath:i,level:r,index:c,...d}=e;const{items:u,label:m,collapsible:h,className:p,href:x}=t,{docs:{sidebar:{autoCollapseCategories:j}}}=(0,f.p)(),v=function(e){const t=(0,w.A)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.Nr)(e):void 0),[e,t])}(t),_=(0,l.w8)(t,i),A=(0,B.ys)(x,i),{collapsed:g,setCollapsed:k}=(0,I.u)({initialState:()=>!!h&&(!_&&t.collapsed)}),{expandedItem:N,setExpandedItem:E}=function(){const e=(0,a.useContext)(T);if(e===S)throw new C.dV("DocSidebarItemsExpandedStateProvider");return e}(),M=function(e){void 0===e&&(e=!g),E(e?null:c),k(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:o}=e;const i=(0,C.ZC)(t);(0,a.useEffect)((()=>{t&&!i&&n&&o(!1)}),[t,i,n,o])}({isActive:_,collapsed:g,updateCollapsed:M}),(0,a.useEffect)((()=>{h&&null!=N&&N!==c&&j&&k(!0)}),[h,N,c,k,j]),(0,b.jsxs)("li",{className:(0,o.A)(s.G.docs.docSidebarItemCategory,s.G.docs.docSidebarItemCategoryLevel(r),"menu__list-item",{"menu__list-item--collapsed":g},p),children:[(0,b.jsxs)("div",{className:(0,o.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":A}),children:[(0,b.jsx)(y.A,{className:(0,o.A)("menu__link",{"menu__link--sublist":h,"menu__link--sublist-caret":!x&&h,"menu__link--active":_}),onClick:h?e=>{n?.(t),x?M(!1):(e.preventDefault(),M())}:()=>{n?.(t)},"aria-current":A?"page":void 0,role:h&&!x?"button":void 0,"aria-expanded":h&&!x?!g:void 0,href:h?v??"#":v,...d,children:m}),x&&h&&(0,b.jsx)(L,{collapsed:g,categoryLabel:m,onClick:e=>{e.preventDefault(),M()}})]}),(0,b.jsx)(I.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:g,children:(0,b.jsx)(U,{items:u,tabIndex:g?-1:0,onItemClick:n,activePath:i,level:r+1})})]})}var M=n(16654),H=n(43186);const G={menuExternalLink:"menuExternalLink_NmtK"};function W(e){let{item:t,onItemClick:n,activePath:a,level:i,index:r,...c}=e;const{href:d,label:u,className:m,autoAddBaseUrl:h}=t,p=(0,l.w8)(t,a),x=(0,M.A)(d);return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(i),"menu__list-item",m),children:(0,b.jsxs)(y.A,{className:(0,o.A)("menu__link",!x&&G.menuExternalLink,{"menu__link--active":p}),autoAddBaseUrl:h,"aria-current":p?"page":void 0,to:d,...x&&{onClick:n?()=>n(t):void 0},...c,children:[u,!x&&(0,b.jsx)(H.A,{})]})},u)}const P={menuHtmlItem:"menuHtmlItem_M9Kj"};function R(e){let{item:t,level:n,index:a}=e;const{value:i,defaultStyle:l,className:r}=t;return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(n),l&&[P.menuHtmlItem,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:i}},a)}function D(e){let{item:t,...n}=e;switch(t.type){case"category":return(0,b.jsx)(E,{item:t,...n});case"html":return(0,b.jsx)(R,{item:t,...n});default:return(0,b.jsx)(W,{item:t,...n})}}function F(e){let{items:t,...n}=e;const a=(0,l.Y)(t,n.activePath);return(0,b.jsx)(N,{children:a.map(((e,t)=>(0,b.jsx)(D,{item:e,index:t,...n},t)))})}const U=(0,a.memo)(F),V={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function Y(e){let{path:t,sidebar:n,className:i}=e;const l=function(){const{isActive:e}=(0,k.Mj)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,c.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,o.A)("menu thin-scrollbar",V.menu,l&&V.menuWithAnnouncementBar,i),children:(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:n,activePath:t,level:1})})})}const K="sidebar_njMd",z="sidebarWithHideableNavbar_wUlq",q="sidebarHidden_VK0M",O="sidebarLogo_isFc";function J(e){let{path:t,sidebar:n,onCollapse:a,isHidden:i}=e;const{navbar:{hideOnScroll:s},docs:{sidebar:{hideable:l}}}=(0,f.p)();return(0,b.jsxs)("div",{className:(0,o.A)(K,s&&z,i&&q),children:[s&&(0,b.jsx)(v.A,{tabIndex:-1,className:O}),(0,b.jsx)(Y,{path:t,sidebar:n}),l&&(0,b.jsx)(g,{onClick:a})]})}const Q=a.memo(J);var X=n(75600),Z=n(22069);const $=e=>{let{sidebar:t,path:n}=e;const a=(0,Z.M)();return(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&a.toggle(),"link"===e.type&&a.toggle()},level:1})})};function ee(e){return(0,b.jsx)(X.GX,{component:$,props:e})}const te=a.memo(ee);function ne(e){const t=(0,j.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(Q,{...e}),a&&(0,b.jsx)(te,{...e})]})}const ae={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function oe(e){let{toggleSidebar:t}=e;return(0,b.jsx)("div",{className:ae.expandButton,title:(0,c.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t,children:(0,b.jsx)(_,{className:ae.expandButtonIcon})})}const ie={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function se(e){let{children:t}=e;const n=(0,r.t)();return(0,b.jsx)(a.Fragment,{children:t},n?.name??"noSidebar")}function le(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:i}=e;const{pathname:l}=(0,x.zy)(),[r,c]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.O)()&&c(!0),i((e=>!e))}),[i,r]);return(0,b.jsx)("aside",{className:(0,o.A)(s.G.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&c(!0)},children:(0,b.jsx)(se,{children:(0,b.jsxs)("div",{className:(0,o.A)(ie.sidebarViewport,r&&ie.sidebarViewportHidden),children:[(0,b.jsx)(ne,{sidebar:t,path:l,onCollapse:d,isHidden:r}),r&&(0,b.jsx)(oe,{toggleSidebar:d})]})})})}const re={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ce(e){let{hiddenSidebarContainer:t,children:n}=e;const a=(0,r.t)();return(0,b.jsx)("main",{className:(0,o.A)(re.docMainContainer,(t||!a)&&re.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,o.A)("container padding-top--md padding-bottom--lg",re.docItemWrapper,t&&re.docItemWrapperEnhanced),children:n})})}const de={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function ue(e){let{children:t}=e;const n=(0,r.t)(),[o,i]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:de.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:de.docRoot,children:[n&&(0,b.jsx)(le,{sidebar:n.items,hiddenSidebarContainer:o,setHiddenSidebarContainer:i}),(0,b.jsx)(ce,{hiddenSidebarContainer:o,children:t})]})]})}var me=n(23363);function be(e){const t=(0,l.B5)(e);if(!t)return(0,b.jsx)(me.A,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,b.jsx)(i.e3,{className:(0,o.A)(s.G.page.docsDocPage),children:(0,b.jsx)(r.V,{name:a,items:c,children:(0,b.jsx)(ue,{children:n})})})}},23363:(e,t,n)=>{n.d(t,{A:()=>l});n(96540);var a=n(18215),o=n(21312),i=n(51107),s=n(74848);function l(e){let{className:t}=e;return(0,s.jsx)("main",{className:(0,a.A)("container margin-vert--xl",t),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(i.A,{as:"h1",className:"hero__title",children:(0,s.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/assets/js/a94c36cd.721ebba8.js b/assets/js/a94c36cd.721ebba8.js new file mode 100644 index 0000000000..644f4e41a9 --- /dev/null +++ b/assets/js/a94c36cd.721ebba8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1548],{99311:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>u});var r=n(74848),c=n(28453);const o={},i="Architecture",s={id:"container/overview/architecture",title:"Architecture",description:"TODO",source:"@site/docs/03-container/overview/architecture.md",sourceDirName:"03-container/overview",slug:"/container/overview/architecture",permalink:"/docs/container/overview/architecture",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/overview/architecture.md",tags:[],version:"current",frontMatter:{}},a={},u=[];function d(e){const t={h1:"h1",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"architecture",children:"Architecture"}),"\n",(0,r.jsx)(t.p,{children:"TODO"})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var r=n(96540);const c={},o=r.createContext(c);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a9f40339.add3d305.js b/assets/js/a9f40339.add3d305.js new file mode 100644 index 0000000000..e06cb2ec4b --- /dev/null +++ b/assets/js/a9f40339.add3d305.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6164],{14978:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>m,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var c=t(74848),o=t(28453);const s={},r="Overview",i={id:"operating-scs/lifecycle-management/index",title:"Overview",description:"TODO",source:"@site/docs/04-operating-scs/05-lifecycle-management/index.md",sourceDirName:"04-operating-scs/05-lifecycle-management",slug:"/operating-scs/lifecycle-management/",permalink:"/docs/operating-scs/lifecycle-management/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/05-lifecycle-management/index.md",tags:[],version:"current",frontMatter:{}},a={},l=[];function d(e){const n={h1:"h1",p:"p",...(0,o.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.h1,{id:"overview",children:"Overview"}),"\n",(0,c.jsx)(n.p,{children:"TODO"})]})}function m(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var c=t(96540);const o={},s=c.createContext(o);function r(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/abb47370.bffd9785.js b/assets/js/abb47370.bffd9785.js new file mode 100644 index 0000000000..4202cae5be --- /dev/null +++ b/assets/js/abb47370.bffd9785.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7456],{95455:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>a,toc:()=>o});var t=n(74848),r=n(28453);const d={},i="IAM Standards",a={id:"iam/index",title:"IAM Standards",description:"This track revolves around Identity and Access Management (IAM) standards, providing guidelines for ensuring secure and efficient user authentication, authorization, and administration. It addresses issues related to user identity, permissions, roles, and policies, aiming to safeguard and streamline access to cloud resources and services.",source:"@site/standards/iam/index.md",sourceDirName:"iam",slug:"/iam/",permalink:"/standards/iam/",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Container registry for SCS standard implementation",permalink:"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation"},next:{title:"scs-0300: Requirements for SSO identity federation",permalink:"/standards/iam/scs-0300"}},c={},o=[];function l(e){const s={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h1,{id:"iam-standards",children:"IAM Standards"}),"\n",(0,t.jsx)(s.p,{children:"This track revolves around Identity and Access Management (IAM) standards, providing guidelines for ensuring secure and efficient user authentication, authorization, and administration. It addresses issues related to user identity, permissions, roles, and policies, aiming to safeguard and streamline access to cloud resources and services."}),"\n",(0,t.jsx)(s.p,{children:"*Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective)."}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Standard"}),(0,t.jsx)(s.th,{children:"Description"}),(0,t.jsx)(s.th,{children:"Draft"}),(0,t.jsx)(s.th,{children:"Stable*"}),(0,t.jsx)(s.th,{children:"Effective"}),(0,t.jsx)(s.th,{children:"Deprecated*"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.a,{href:"/standards/iam/scs-0300",children:"scs-0300"})}),(0,t.jsx)(s.td,{children:"Requirements for SSO identity federation"}),(0,t.jsx)(s.td,{children:"-"}),(0,t.jsx)(s.td,{children:"-"}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.a,{href:"/standards/scs-0300-v1-requirements-for-sso-identity-federation",children:"v1"})}),(0,t.jsx)(s.td,{children:"-"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.a,{href:"/standards/iam/scs-0301",children:"scs-0301"})}),(0,t.jsx)(s.td,{children:"Naming for domains/groups/roles/project when onboarding new customers"}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.a,{href:"/standards/scs-0301-v1-naming-conventions",children:"v1"})}),(0,t.jsx)(s.td,{children:"-"}),(0,t.jsx)(s.td,{children:"-"}),(0,t.jsx)(s.td,{children:"-"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.a,{href:"/standards/iam/scs-0302",children:"scs-0302"})}),(0,t.jsx)(s.td,{children:"Domain Manager configuration for Keystone"}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.a,{href:"/standards/scs-0302-v1-domain-manager-role",children:"v1"})}),(0,t.jsx)(s.td,{children:"-"}),(0,t.jsx)(s.td,{children:"-"}),(0,t.jsx)(s.td,{children:"-"})]})]})]})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>i,x:()=>a});var t=n(96540);const r={},d=t.createContext(r);function i(e){const s=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(d.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/abd7a988.03788a57.js b/assets/js/abd7a988.03788a57.js new file mode 100644 index 0000000000..c1b02cfbf1 --- /dev/null +++ b/assets/js/abd7a988.03788a57.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2747],{62834:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var r=s(74848),t=s(28453);const i={},l="HA deployment",o={id:"container/components/container-registry/docs/ha-deployment",title:"HA deployment",description:"Prerequisites",source:"@site/docs/03-container/components/container-registry/docs/ha-deployment.md",sourceDirName:"03-container/components/container-registry/docs",slug:"/container/components/container-registry/docs/ha-deployment",permalink:"/docs/container/components/container-registry/docs/ha-deployment",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/ha-deployment.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Persistence",permalink:"/docs/container/components/container-registry/docs/persistence"},next:{title:"Operating SCS",permalink:"/docs/category/operating-scs"}},a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install and wait for operators",id:"install-and-wait-for-operators",level:2},{value:"Create redis and postgres clusters",id:"create-redis-and-postgres-clusters",level:2},{value:"Install Harbor",id:"install-harbor",level:2},{value:"All in one installation using FluxCD Kustomization and GitRepository reconciliation",id:"all-in-one-installation-using-fluxcd-kustomization-and-gitrepository-reconciliation",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"ha-deployment",children:"HA deployment"}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Kubernetes cluster v1.20+","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Use existing cluster","\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"export KUBECONFIG=/path/to/kubeconfig\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Alternatively, spawn some dev cluster, e.g. using ",(0,r.jsx)(n.a,{href:"https://kind.sigs.k8s.io/docs/user/quick-start/",children:"KinD"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"kind create cluster\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["Flux CLI","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Installation documentation: ",(0,r.jsx)(n.a,{href:"https://fluxcd.io/flux/installation/#install-the-flux-cli",children:"https://fluxcd.io/flux/installation/#install-the-flux-cli"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s https://fluxcd.io/install.sh | sudo FLUX_VERSION=2.2.3 bash\nflux install\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"install-and-wait-for-operators",children:"Install and wait for operators"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"$ kubectl apply -k operators/\n$ flux get helmrelease -n default\nNAME REVISION SUSPENDED READY MESSAGE\ncert-manager v1.11.0 False True Release reconciliation succeeded\ningress-nginx 4.5.2 False True Release reconciliation succeeded\npostgres-operator 1.9.0 False True Release reconciliation succeeded\nredis-operator 3.2.7 False True Release reconciliation succeeded\n"})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:"Note: Install separate operators by e.g.:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"kubectl apply -k operators/redis/\nkubectl apply -k operators/postgres/\n"})}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"create-redis-and-postgres-clusters",children:"Create redis and postgres clusters"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"envs/public-ha/redis/redis-secret.bash # pwgen needs to be installed\nkubectl apply -k envs/public-ha/redis/\nkubectl apply -k envs/public-ha/postgres/\n"})}),"\n",(0,r.jsx)(n.h2,{id:"install-harbor",children:"Install Harbor"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Replace the ",(0,r.jsx)(n.code,{children:"example.com"})," URL in the ",(0,r.jsx)(n.code,{children:"harbor-config.yaml"})," file with the desired one."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Take ",(0,r.jsx)(n.em,{children:"ingress-nginx-controller"})," LoadBalancer IP address and create DNS record for Harbor."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"kubectl get svc -n ingress-nginx\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\ningress-nginx-controller LoadBalancer 100.92.14.168 81.163.194.219 80:30799/TCP,443:32482/TCP 2m51s\ningress-nginx-controller-admission ClusterIP 100.88.40.231 <none> 443/TCP 2m51s\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Generate secrets and install Harbor:"}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["It is recommended to replace ",(0,r.jsx)(n.code,{children:"admin@example.com"})," email address in ",(0,r.jsx)(n.code,{children:"issuer.yaml"})," with your own.\nLet's Encrypt will use this to contact you about expiring certificates, and issues related to your account."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"base/harbor-secrets.bash # pwgen and htpasswd need to be installed\nenvs/public-ha/swift-secret.bash <username> <password>\nkubectl apply -k envs/public-ha/\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"all-in-one-installation-using-fluxcd-kustomization-and-gitrepository-reconciliation",children:"All in one installation using FluxCD Kustomization and GitRepository reconciliation"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"envs/public-ha/redis/redis-secret.bash\nbase/harbor-secrets.bash\nenvs/public-ha/swift-secret.bash <username> <password>\n# --branch/tag can be specified, default to master\nflux create source git k8s-harbor --url=https://github.com/SovereignCloudStack/k8s-harbor --interval=5m\nkubectl apply -f envs/public-ha/public-ha.yaml\n"})})]})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>o});var r=s(96540);const t={},i=r.createContext(t);function l(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/abecca15.82183737.js b/assets/js/abecca15.82183737.js new file mode 100644 index 0000000000..aecc3e8572 --- /dev/null +++ b/assets/js/abecca15.82183737.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7560],{21674:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>g,frontMatter:()=>r,metadata:()=>d,toc:()=>c});var o=i(74848),s=i(28453);const r={sidebar_label:"Logging & Monitoring",sidebar_position:40},t="Logging & Monitoring",d={id:"iaas/guides/deploy-guide/services/logging-monitoring",title:"Logging & Monitoring",description:"Common issues with deploying logging & monitoring services provided by Kolla",source:"@site/docs/02-iaas/guides/deploy-guide/services/logging-monitoring.md",sourceDirName:"02-iaas/guides/deploy-guide/services",slug:"/iaas/guides/deploy-guide/services/logging-monitoring",permalink:"/docs/iaas/guides/deploy-guide/services/logging-monitoring",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/logging-monitoring.md",tags:[],version:"current",sidebarPosition:40,frontMatter:{sidebar_label:"Logging & Monitoring",sidebar_position:40},sidebar:"docs",previous:{title:"Network",permalink:"/docs/iaas/guides/deploy-guide/services/network"},next:{title:"Ceph",permalink:"/docs/iaas/guides/deploy-guide/services/ceph"}},l={},c=[];function a(e){const n={a:"a",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"logging--monitoring",children:"Logging & Monitoring"}),"\n",(0,o.jsxs)(n.p,{children:["Common issues with deploying logging & monitoring services provided by Kolla\nare documented in the ",(0,o.jsx)(n.a,{href:"../../troubleshooting-guide/openstack",children:"OpenStack Troubleshooting Guide"}),"."]}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"OpenSearch"}),"\n",(0,o.jsxs)(n.p,{children:["OpenSearch dashboards is also deployed with the ",(0,o.jsx)(n.code,{children:"opensearch"})," role."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply -a pull opensearch\nosism apply opensearch\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Prometheus"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply -a pull prometheus\nosism apply prometheus\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Grafana"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply -a pull grafana\nosism apply grafana\n"})}),"\n"]}),"\n"]})]})}function g(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>t,x:()=>d});var o=i(96540);const s={},r=o.createContext(s);function t(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/abfb0638.6b373363.js b/assets/js/abfb0638.6b373363.js new file mode 100644 index 0000000000..9625fca7c0 --- /dev/null +++ b/assets/js/abfb0638.6b373363.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6793],{33276:(e,a,n)=>{n.r(a),n.d(a,{assets:()=>r,contentTitle:()=>t,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var l=n(74848),o=n(28453);const i={sidebar_label:"Apply"},t="Apply",s={id:"iaas/guides/operations-guide/manager/apply",title:"Apply",description:"List all available plays",source:"@site/docs/02-iaas/guides/operations-guide/manager/apply.md",sourceDirName:"02-iaas/guides/operations-guide/manager",slug:"/iaas/guides/operations-guide/manager/apply",permalink:"/docs/iaas/guides/operations-guide/manager/apply",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/manager/apply.md",tags:[],version:"current",frontMatter:{sidebar_label:"Apply"},sidebar:"docs",previous:{title:"Manager",permalink:"/docs/iaas/guides/operations-guide/manager/"},next:{title:"Console",permalink:"/docs/iaas/guides/operations-guide/manager/console"}},r={},c=[{value:"List all available plays",id:"list-all-available-plays",level:2}];function d(e){const a={code:"code",h1:"h1",h2:"h2",pre:"pre",...(0,o.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(a.h1,{id:"apply",children:"Apply"}),"\n",(0,l.jsx)(a.h2,{id:"list-all-available-plays",children:"List all available plays"}),"\n",(0,l.jsx)(a.pre,{children:(0,l.jsx)(a.code,{children:"$ osism apply\n2023-09-30 10:09:25 | INFO | No role given for execution. The roles listed in the table can be used.\n+------------------------------------------------------------------+----------------+\n| Role | Environment |\n|------------------------------------------------------------------+----------------|\n| aodh | kolla |\n| barbican | kolla |\n| bifrost | kolla |\n| bifrost-keypair | kolla |\n| ceilometer | kolla |\n| certificates | generic |\n| cinder | kolla |\n| cloudkitty | kolla |\n| collectd | kolla |\n| common | kolla |\n| designate | kolla |\n| elasticsearch | kolla |\n| etcd | kolla |\n| glance | kolla |\n| gnocchi | kolla |\n| grafana | kolla |\n| heat | kolla |\n| horizon | kolla |\n| ironic | kolla |\n| iscsi | kolla |\n...\n"})})]})}function p(e={}){const{wrapper:a}={...(0,o.R)(),...e.components};return a?(0,l.jsx)(a,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}},28453:(e,a,n)=>{n.d(a,{R:()=>t,x:()=>s});var l=n(96540);const o={},i=l.createContext(o);function t(e){const a=l.useContext(i);return l.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function s(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),l.createElement(i.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ac087500.442bc6d0.js b/assets/js/ac087500.442bc6d0.js new file mode 100644 index 0000000000..fc4bba32a5 --- /dev/null +++ b/assets/js/ac087500.442bc6d0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8411],{33606:(e,o,i)=>{i.r(o),i.d(o,{assets:()=>d,contentTitle:()=>r,default:()=>l,frontMatter:()=>n,metadata:()=>u,toc:()=>a});var t=i(74848),s=i(28453);const n={sidebar_label:"Troubleshooting Guide",sidebar_position:40},r="Troubleshooting Guide",u={id:"iaas/guides/troubleshooting-guide/index",title:"Troubleshooting Guide",description:"\ud83d\udca1 The Troubleshooting Guide describe how to solve issues.",source:"@site/docs/02-iaas/guides/troubleshooting-guide/index.md",sourceDirName:"02-iaas/guides/troubleshooting-guide",slug:"/iaas/guides/troubleshooting-guide/",permalink:"/docs/iaas/guides/troubleshooting-guide/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/troubleshooting-guide/index.md",tags:[],version:"current",sidebarPosition:40,frontMatter:{sidebar_label:"Troubleshooting Guide",sidebar_position:40},sidebar:"docs",previous:{title:"Octavia",permalink:"/docs/iaas/guides/operations-guide/openstack/octavia"},next:{title:"Manager",permalink:"/docs/iaas/guides/troubleshooting-guide/manager"}},d={},a=[];function c(e){const o={h1:"h1",p:"p",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.h1,{id:"troubleshooting-guide",children:"Troubleshooting Guide"}),"\n",(0,t.jsx)(o.p,{children:"\ud83d\udca1 The Troubleshooting Guide describe how to solve issues."})]})}function l(e={}){const{wrapper:o}={...(0,s.R)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,o,i)=>{i.d(o,{R:()=>r,x:()=>u});var t=i(96540);const s={},n=t.createContext(s);function r(e){const o=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function u(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(n.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/acecf23e.92dddac5.js b/assets/js/acecf23e.92dddac5.js new file mode 100644 index 0000000000..251c76b68a --- /dev/null +++ b/assets/js/acecf23e.92dddac5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1903],{1912:s=>{s.exports=JSON.parse('{"blogBasePath":"/blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/ad1cb202.3cbe03e8.js b/assets/js/ad1cb202.3cbe03e8.js new file mode 100644 index 0000000000..efbcc99d32 --- /dev/null +++ b/assets/js/ad1cb202.3cbe03e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3086],{21363:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var t=s(74848),r=s(28453);const i={},a="Gardener",o={id:"iaas/guides/concept-guide/components/gardener",title:"Gardener",description:"Kubernetes as a Service (KaaS) simplifies the deployment, management, and scaling of",source:"@site/docs/02-iaas/guides/concept-guide/components/gardener.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/gardener",permalink:"/docs/iaas/guides/concept-guide/components/gardener",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/gardener.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Cluster API",permalink:"/docs/iaas/guides/concept-guide/components/clusterapi"},next:{title:"Ironic",permalink:"/docs/iaas/guides/concept-guide/components/ironic"}},c={},l=[{value:"Lifecycle Management of Gardener in OSISM",id:"lifecycle-management-of-gardener-in-osism",level:2}];function d(e){const n={h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"gardener",children:"Gardener"}),"\n",(0,t.jsx)(n.p,{children:"Kubernetes as a Service (KaaS) simplifies the deployment, management, and scaling of\nKubernetes clusters by abstracting the underlying infrastructure. Gardener by SAP is\nan advanced KaaS solution that leverages a Kubernetes-native approach to manage\nKubernetes clusters at scale. Gardener is designed to provide consistent and efficient\ncluster management across various cloud environments and on-premises data centers."}),"\n",(0,t.jsx)(n.p,{children:"Key benefits of Gardener include:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Kubernetes-Native Design: Gardener operates by treating Kubernetes clusters as first-class\ncitizens. It uses Kubernetes itself to orchestrate the deployment and management of other\nKubernetes clusters, ensuring that all operations are consistent and follow Kubernetes best\npractices."}),"\n",(0,t.jsxs)(n.li,{children:["Shoot, Seed, and Garden Clusters:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Shoot Clusters: These are the user clusters managed by Gardener, running the workloads."}),"\n",(0,t.jsx)(n.li,{children:"Seed Clusters: These clusters host the control planes of shoot clusters and are managed by\nthe Gardener infrastructure."}),"\n",(0,t.jsx)(n.li,{children:"Garden Cluster: This is the central cluster where the Gardener components run and from which\nall other clusters (seed and shoot) are managed."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.li,{children:"Multi-Cloud and Hybrid Cloud Support: Gardener supports deployment across various cloud providers,\nincluding AWS, Azure, Google Cloud, and OpenStack, as well as on-premises environments.\nThis multi-cloud capability allows for a consistent Kubernetes experience regardless of the\nunderlying infrastructure."}),"\n",(0,t.jsx)(n.li,{children:"Automated Cluster Management: Gardener automates the lifecycle management of Kubernetes clusters,\nincluding provisioning, scaling, upgrading, and healing. This automation reduces operational\noverhead and ensures clusters are always running optimally."}),"\n",(0,t.jsx)(n.li,{children:"High Availability and Resilience: Gardener ensures high availability by distributing control\nplanes across multiple seed clusters and leveraging cloud provider features to enhance resilience.\nThis design minimizes downtime and enhances the reliability of managed clusters."}),"\n",(0,t.jsx)(n.li,{children:"Extensibility and Customization: Gardener\u2019s architecture allows for customization and extensibility\nthrough extensions and webhooks. This flexibility enables organizations to tailor the solution to\nmeet specific requirements and integrate with existing tools and processes."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"By using Gardener by SAP for Kubernetes as a Service, organisations can achieve a scalable,\nautomated and consistent approach to managing Kubernetes clusters across multiple environments.\nThis allows them to focus on delivering business value through their applications, rather\nthan dealing with the complexities of cluster management."}),"\n",(0,t.jsx)(n.h2,{id:"lifecycle-management-of-gardener-in-osism",children:"Lifecycle Management of Gardener in OSISM"})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>o});var t=s(96540);const r={},i=t.createContext(r);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad39e84b.3bccaa94.js b/assets/js/ad39e84b.3bccaa94.js new file mode 100644 index 0000000000..719a940c03 --- /dev/null +++ b/assets/js/ad39e84b.3bccaa94.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4657],{48442:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>c});var t=n(74848),s=n(28453);const a={title:"SCS Image Metadata Standard",type:"Standard",stabilized_at:new Date("2022-10-31T00:00:00.000Z"),status:"Stable",track:"IaaS",replaces:"Image-Metadata-Spec.md",description:"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating\nsystem images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements,\nimage handling protocols including updating and origin, and licensing/support details. These guidelines ensure\nthat users can understand, access, and utilize OS images effectively, with clear information on features, updates,\nand licensing provided through well-defined metadata properties.\n"},d=void 0,r={id:"scs-0102-v1-image-metadata",title:"SCS Image Metadata Standard",description:"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating\nsystem images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements,\nimage handling protocols including updating and origin, and licensing/support details. These guidelines ensure\nthat users can understand, access, and utilize OS images effectively, with clear information on features, updates,\nand licensing provided through well-defined metadata properties.\n",source:"@site/standards/scs-0102-v1-image-metadata.md",sourceDirName:".",slug:"/scs-0102-v1-image-metadata",permalink:"/standards/scs-0102-v1-image-metadata",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS Image Metadata Standard",type:"Standard",stabilized_at:"2022-10-31T00:00:00.000Z",status:"Stable",track:"IaaS",replaces:"Image-Metadata-Spec.md",description:"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating\nsystem images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements,\nimage handling protocols including updating and origin, and licensing/support details. These guidelines ensure\nthat users can understand, access, and utilize OS images effectively, with clear information on features, updates,\nand licensing provided through well-defined metadata properties.\n"},sidebar:"standards",previous:{title:"scs-0102: SCS Image Metadata Standard",permalink:"/standards/iaas/scs-0102"},next:{title:"scs-0103: SCS Standard Flavors and Properties",permalink:"/standards/iaas/scs-0103"}},o={},c=[{value:"Motivation",id:"motivation",level:2},{value:"Overview",id:"overview",level:2},{value:"Naming",id:"naming",level:2},{value:"Technical requirements and features",id:"technical-requirements-and-features",level:2},{value:"Image handling",id:"image-handling",level:2},{value:"Image updating",id:"image-updating",level:3},{value:"Example",id:"example",level:4},{value:"Image Origin",id:"image-origin",level:3},{value:"Image build info",id:"image-build-info",level:3},{value:"Licensing / Maintenance subscription / Support",id:"licensing--maintenance-subscription--support",level:3},{value:"Conformance Tests",id:"conformance-tests",level:3}];function l(e){const i={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.h2,{id:"motivation",children:"Motivation"}),"\n",(0,t.jsx)(i.p,{children:"Many clouds offer standard Operating System images for their users' convenience.\nTo make them really useful, they should contain meta data (properties) to allow\nusers to understand what they can expect using these images."}),"\n",(0,t.jsx)(i.p,{children:"The specification is targeting images that are managed by the service provider,\nprovided for public consumption. The spec or parts of it however might turn out\nto be useful whenever someone manages images for somebody else's consumption."}),"\n",(0,t.jsx)(i.h2,{id:"overview",children:"Overview"}),"\n",(0,t.jsx)(i.p,{children:"We categorize the image properties into a few buckets"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"Technical requirements and features"}),"\n",(0,t.jsx)(i.li,{children:"Image handling aspects"}),"\n",(0,t.jsx)(i.li,{children:"Licensing/Maintenance/Support aspects"}),"\n"]}),"\n",(0,t.jsx)(i.h2,{id:"naming",children:"Naming"}),"\n",(0,t.jsx)(i.p,{children:'We suggest plain OS images to be named "Distribution Version",\ne.g. "openSUSE Leap 15.3" or "Ubuntu 20.04" or "CentOS 8", "Windows Server 2012R2".\nWe do not normally recommend to add more detailed patch levels into the name.'}),"\n",(0,t.jsx)(i.p,{children:'Special variants that include specific non-standard features should be named\n"Distribution Version Feature1 Feature2".'}),"\n",(0,t.jsx)(i.p,{children:"There are several policies possible to provide updated images to include the latest\nbug- and security fixes. This is outlined in update policy description below."}),"\n",(0,t.jsx)(i.h2,{id:"technical-requirements-and-features",children:"Technical requirements and features"}),"\n",(0,t.jsx)(i.p,{children:"This is dependent on whether we deal with VM images or container images."}),"\n",(0,t.jsxs)(i.p,{children:["For VM images (OpenStack), we recommend to use the properties as described\nin the ",(0,t.jsx)(i.a,{href:"https://docs.openstack.org/glance/latest//admin/useful-image-properties",children:"OpenStack Image documentation"}),"."]}),"\n",(0,t.jsx)(i.p,{children:"The following properties are considered mandatory:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"architecture"}),", ",(0,t.jsx)(i.code,{children:"hypervisor_type"})]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"min_disk_size"})," (in GiB), ",(0,t.jsx)(i.code,{children:"min_ram"})," (in MiB)"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"os_version"}),", ",(0,t.jsx)(i.code,{children:"os_distro"})]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"hw_rng_model"}),", ",(0,t.jsx)(i.code,{children:"hw_disk_bus"})," (",(0,t.jsx)(i.code,{children:"scsi"})," recommended, and then setting ",(0,t.jsx)(i.code,{children:"hw_scsi_model"})," is also recommended)"]}),"\n"]}),"\n",(0,t.jsxs)(i.p,{children:[(0,t.jsx)(i.strong,{children:"Note"}),": Disk sizes tend to be measured in GB = 10^9 and not GiB = 2^30 in the disk industry, but OpenStack uses GiB."]}),"\n",(0,t.jsx)(i.p,{children:"The following properties are recommended (if the features are supported):"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"os_secure_boot"}),", ",(0,t.jsx)(i.code,{children:"hw_firmware_type"})]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"hw_watchdog_action"}),", ",(0,t.jsx)(i.code,{children:"hw_mem_encryption"}),", ",(0,t.jsx)(i.code,{children:"hw_pmu"}),", ",(0,t.jsx)(i.code,{children:"hw_video_ram"}),", ",(0,t.jsx)(i.code,{children:"hw_vif_multiqueue_enabled"})]}),"\n"]}),"\n",(0,t.jsxs)(i.p,{children:["The ",(0,t.jsx)(i.code,{children:"trait:XXX=required"})," property can be used to indicate that certain virtual hardware\nfeatures ",(0,t.jsx)(i.code,{children:"XXX"})," are required."]}),"\n",(0,t.jsx)(i.h2,{id:"image-handling",children:"Image handling"}),"\n",(0,t.jsx)(i.h3,{id:"image-updating",children:"Image updating"}),"\n",(0,t.jsxs)(i.p,{children:["It is recommended that provider managed images are regularly updated.\nThis means that users referencing an image ",(0,t.jsx)(i.em,{children:"by name"})," will always get the latest image for the\noperating system indicated by that name (which includes a version number, but not the patch\nlevel)."]}),"\n",(0,t.jsxs)(i.p,{children:["Technically, the thus updated image is a new image and will thus carry a new UUID.\nIt is recommended that the old image gets renamed (e.g. build date or patch level attached)\nand hidden (",(0,t.jsx)(i.code,{children:"os_hidden=true"}),"), but remains accessible via its (unchanged) UUID for some\ntime."]}),"\n",(0,t.jsxs)(i.p,{children:["The update handling by the provider is described via the properties ",(0,t.jsx)(i.code,{children:"replace_frequency"}),",\n",(0,t.jsx)(i.code,{children:"uuid_validity"}),", ",(0,t.jsx)(i.code,{children:"provided_until"}),", and ",(0,t.jsx)(i.code,{children:"hotfix_hours"}),"."]}),"\n",(0,t.jsxs)(i.p,{children:["The ",(0,t.jsx)(i.code,{children:"replace_frequency"}),", ",(0,t.jsx)(i.code,{children:"provided_until"}),", and ",(0,t.jsx)(i.code,{children:"hotfix_hours"})," fields reference to the image\nas referenced by its name."]}),"\n",(0,t.jsxs)(i.table,{children:[(0,t.jsx)(i.thead,{children:(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.th,{children:(0,t.jsx)(i.code,{children:"replace_frequency"})}),(0,t.jsx)(i.th,{children:"meaning"})]})}),(0,t.jsxs)(i.tbody,{children:[(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"yearly"})}),(0,t.jsxs)(i.td,{children:["the image will get replaced ",(0,t.jsx)(i.em,{children:"at least"})," once per year"]})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"quarterly"})}),(0,t.jsxs)(i.td,{children:["the image will get replaced ",(0,t.jsx)(i.em,{children:"at least"})," once per quarter"]})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"monthly"})}),(0,t.jsxs)(i.td,{children:["the image will get replaced ",(0,t.jsx)(i.em,{children:"at least"})," once per month"]})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"weekly"})}),(0,t.jsxs)(i.td,{children:["the image will get replaced ",(0,t.jsx)(i.em,{children:"at least"})," once per week"]})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"daily"})}),(0,t.jsxs)(i.td,{children:["the image will get replaced ",(0,t.jsx)(i.em,{children:"at least"})," once per day"]})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"critical_bug"})}),(0,t.jsx)(i.td,{children:"the image will get replaced for critical issues only"})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"never"})}),(0,t.jsxs)(i.td,{children:["the image referenced by name will never change (until the date ",(0,t.jsx)(i.code,{children:"provided_until"}),")"]})]})]})]}),"\n",(0,t.jsxs)(i.p,{children:["Note the ",(0,t.jsx)(i.em,{children:"at least"})," wording: Providers can replace images more often.\nThe frequency is starting from the first release; so an image published on 2021-04-14 with an\nupdate frequency of ",(0,t.jsx)(i.code,{children:"monthly"}),", should be replaced no later than 2021-05-14. Due to weekends\netc., up to 3 days later is not considered a violation of this policy. So a valid sequence\nfrom an image with ",(0,t.jsx)(i.code,{children:"monthly"})," update frequency might be 2021-04-14, 2021-05-14, 2021-06-15,\n2021-07-14, 2021-07-27 (hotfix), 2021-08-13 ..."]}),"\n",(0,t.jsx)(i.p,{children:"Promises to update the registered public images typically depend on upstream image providers\n(Linux distributors, OS vendors) keeping their promises to build and provide updated images.\nFailures from upstream are not a reason to claim the cloud provider to be in violation of his\npromises. However, if the provider observes massive upstream failures (which can e.g. cause\nincreased security risks), we advise the provider to inform the users."}),"\n",(0,t.jsx)(i.p,{children:"We recommend updating images at least monthly."}),"\n",(0,t.jsxs)(i.p,{children:["The ",(0,t.jsx)(i.code,{children:"hotfix_hours"})," field indicates how providers deal with critical security issues\nthat affect the images; it is an optional field that contains a numerical value, indicating\nhow quickly (in hours) a new image is provided ",(0,t.jsx)(i.em,{children:"after the latter of the points in time that\nthe issue becomes public and a tested fix is available as maintenance update from the upstream\ndistribution"}),". A value of 0 indicates a best-effort approach without firm SLAs; the field not\nbeing present indicates no commitment. A value of 48 would indicate that the provider\ncommits to a new image within 48hrs. A critical issue is defined as a security vulnerability\nwith a CVSS score of 9.0 or higher that affects a package that is included in the image."]}),"\n",(0,t.jsxs)(i.p,{children:["The ",(0,t.jsx)(i.code,{children:"provided_until"})," field is supposed to contain a date in ",(0,t.jsx)(i.code,{children:"YYYY-MM-DD"})," format that\nindicates until when an image under this name will be provided and (according to the\n",(0,t.jsx)(i.code,{children:"replace_frequency"}),") updated at least. (Providers are free to provide updates for\nlonger or leave the non-updated image visible for longer.)\nIf this field is set to ",(0,t.jsx)(i.code,{children:"none"}),", no promises are made, if it is set to ",(0,t.jsx)(i.code,{children:"notice"}),", updates\nwill be provided until a deprecation notice is published. (The values are the same as\nfor below ",(0,t.jsx)(i.code,{children:"uuid_validity"}),", except that ",(0,t.jsx)(i.code,{children:"forever"})," and ",(0,t.jsx)(i.code,{children:"last-N"})," don't make any sense.)"]}),"\n",(0,t.jsxs)(i.p,{children:["The ",(0,t.jsx)(i.code,{children:"uuid_validity"})," field indicates how long the public image will be referencable\nby its UUID."]}),"\n",(0,t.jsxs)(i.table,{children:[(0,t.jsx)(i.thead,{children:(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.th,{children:(0,t.jsx)(i.code,{children:"uuid_validity"})}),(0,t.jsx)(i.th,{children:"meaning"})]})}),(0,t.jsxs)(i.tbody,{children:[(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"none"})}),(0,t.jsx)(i.td,{children:"UUID will only be valid as long as the content does not change"})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"last-N"})}),(0,t.jsx)(i.td,{children:"The last N images for newer replacement will remain accessible via UUID"})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"YYYY-MM-DD"})}),(0,t.jsx)(i.td,{children:"UUID will be valid until at least the date YYYY-MM-DD"})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"notice"})}),(0,t.jsx)(i.td,{children:"UUID will remain valid until a deprecation notice will be published"})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:(0,t.jsx)(i.code,{children:"forever"})}),(0,t.jsx)(i.td,{children:"UUID will remain valid for as long as the cloud operates"})]})]})]}),"\n",(0,t.jsxs)(i.p,{children:["Note that the old images must be hidden from the image catalogue or renamed (or both)\nto avoid failing referencing by name. Note that ",(0,t.jsx)(i.code,{children:"last-N"})," may be limited by the ",(0,t.jsx)(i.code,{children:"provided_until"}),"\ndate."]}),"\n",(0,t.jsxs)(i.p,{children:["The three properties ",(0,t.jsx)(i.code,{children:"uuid_validity"}),", ",(0,t.jsx)(i.code,{children:"provided_until"})," and ",(0,t.jsx)(i.code,{children:"replace_frequency"})," are mandatory;\nthe field ",(0,t.jsx)(i.code,{children:"hotfix_hours"})," is optional."]}),"\n",(0,t.jsx)(i.p,{children:"All dates are in UTC."}),"\n",(0,t.jsx)(i.h4,{id:"example",children:"Example"}),"\n",(0,t.jsxs)(i.p,{children:["Providing an image with name ",(0,t.jsx)(i.code,{children:"OPSYS MAJ.MIN"})," with\n",(0,t.jsx)(i.code,{children:"replace_frequency=monthly"}),", ",(0,t.jsx)(i.code,{children:"provided_until=2022-09-30"}),", ",(0,t.jsx)(i.code,{children:"uuid_validity=2022-12-31"}),",\n",(0,t.jsx)(i.code,{children:"hotfix_hours=0"}),"\nmeans that we will have a new image with this name at least once per month (starting from\nthe initial release) until the end of September 2022. Old images will be hidden and/or\nrenamed, but remain accessible via their UUID until at least the end of 2022 (in Universal Time).\nThe provider makes an effort to replace images upon critical security issues out of order."]}),"\n",(0,t.jsx)(i.h3,{id:"image-origin",children:"Image Origin"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:["\n",(0,t.jsxs)(i.p,{children:["Mandatory: ",(0,t.jsx)(i.code,{children:"image_source"}),' needs to be a URL to point to a place from which the image can be downloaded.\n(Note: This may be set to the string "private" to indicate that the image can not be freely\ndownloaded.)']}),"\n"]}),"\n",(0,t.jsxs)(i.li,{children:["\n",(0,t.jsxs)(i.p,{children:["Mandatory: ",(0,t.jsx)(i.code,{children:"image_description"})," needs to be an URL (or text) with release notes and other human readable\ndata about the image."]}),"\n"]}),"\n",(0,t.jsxs)(i.li,{children:["\n",(0,t.jsxs)(i.p,{children:["Recommended ",(0,t.jsx)(i.em,{children:"tag"}),": ",(0,t.jsx)(i.code,{children:"managed_by_VENDOR"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(i.p,{children:["Note that for most images that come straight from an upstream source, ",(0,t.jsx)(i.code,{children:"image_description"})," should point\nto a an upstream web page where these images are described. If download links are available as well\non that page, ",(0,t.jsx)(i.code,{children:"image_source"})," can point to the same page, otherwise a more direct link to the image\nshould be used, e.g. directly linking the ",(0,t.jsx)(i.code,{children:".qcow2"})," or ",(0,t.jsx)(i.code,{children:".img"})," file.\nIf providers have their own image building machinery or do some post-processing on top of\nupstream images, they should point to the place where they document and offer these images."]}),"\n",(0,t.jsx)(i.h3,{id:"image-build-info",children:"Image build info"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:["\n",(0,t.jsxs)(i.p,{children:["Mandatory: ",(0,t.jsx)(i.code,{children:"image_build_date"})," needs to be ",(0,t.jsx)(i.code,{children:"YYYY-MM-DD"})," or ",(0,t.jsx)(i.code,{children:"YYYY-MM-DD hh:mm[:ss]"})," (time in UTC,\n24hrs clock).\nAll publicly released and generally recommended patches before this date must be included in the\nimage build. If the cutoff date is earlier, this cutoff date needs to be set instead, even\nif the actual build happens significantly after the cutoff date. If not all patches can be\nincluded for a good reason, then the ",(0,t.jsx)(i.code,{children:"patchlevel"})," field (see below) must be used to describe\nthe patch status."]}),"\n"]}),"\n",(0,t.jsxs)(i.li,{children:["\n",(0,t.jsxs)(i.p,{children:["Mandatory: ",(0,t.jsx)(i.code,{children:"image_original_user"})," is the default login user for the operating system which can connect\nto the image via the injected SSH key or provided password. (This can be set to ",(0,t.jsx)(i.code,{children:"none"})," if no default\nuser name exists for the operating system.)"]}),"\n"]}),"\n",(0,t.jsxs)(i.li,{children:["\n",(0,t.jsxs)(i.p,{children:["Optional: ",(0,t.jsx)(i.code,{children:"patchlevel"})," can be set to an operating specific patch level that describes the\npatch status \u2014 typically we would expect the ",(0,t.jsx)(i.code,{children:"image_build_date"})," to be sufficient."]}),"\n"]}),"\n",(0,t.jsxs)(i.li,{children:["\n",(0,t.jsxs)(i.p,{children:["Recommended: ",(0,t.jsx)(i.code,{children:"os_hash_algo"})," and ",(0,t.jsx)(i.code,{children:"os_hash_value"}),": The sha256 or sha512 hash\nfor the image file. (This references the image file in the format it is stored in, we\nrecommend raw over qcow2 for systems that use ceph.) Note that these values are\ntypically generated automatically upon image registration."]}),"\n"]}),"\n",(0,t.jsxs)(i.li,{children:["\n",(0,t.jsxs)(i.p,{children:["Recommended ",(0,t.jsx)(i.em,{children:"tag"}),": ",(0,t.jsx)(i.code,{children:"os:OPERATINGSYSTEM"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(i.h3,{id:"licensing--maintenance-subscription--support",children:"Licensing / Maintenance subscription / Support"}),"\n",(0,t.jsxs)(i.p,{children:["Some images require a license; in many cases the cloud providers include the license cost\nby a per-use (e.g. hourly) fee. However, it is also possible sometimes that customers\nuse their own license agreements with the OS vendor with a bring-your-own-license (BYOL)\nprogram. These properties may be attached to the image. Note that free Linux images\nmight not use any of these properties, except maybe ",(0,t.jsx)(i.code,{children:"maintained_until"}),". Note that\nWindows images would typically require ",(0,t.jsx)(i.code,{children:"license_included"}),", ",(0,t.jsx)(i.code,{children:"subscription_included"}),".\nA boolean property that is not present is considered to be ",(0,t.jsx)(i.code,{children:"false"}),"."]}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:["Optional: ",(0,t.jsx)(i.code,{children:"license_included"})," (boolean) indicates whether or not the flavor fee\nincludes the licenses required to use this image. This field is mandatory for\nimages that contain software that requires commercial licenses."]}),"\n",(0,t.jsxs)(i.li,{children:["Optional: ",(0,t.jsx)(i.code,{children:"license_required"})," (boolean) indicates whether or not a customer must bring\nits own license to be license compliant. This can not be true at the same time as the\nprevious setting. This field is mandatory IF customers need to bring their own\nlicense to use the image."]}),"\n",(0,t.jsxs)(i.li,{children:["Optional: ",(0,t.jsx)(i.code,{children:"subscription_included"})," (boolean) indicates that the image contains already\na maintenance subscription which typically gives access to bug fixes, security\nfixes and (minor) function updates. If a subscription is included, the CSP should\nhave prepared the image to also receive the provided maintenance updates from the\nvendor (optionally via a mirror)."]}),"\n",(0,t.jsxs)(i.li,{children:["Optional: ",(0,t.jsx)(i.code,{children:"subscription_required"})," (boolean) indicates that the customer requires\na maintenance subscription from the OS vendor in order to receive fixes\n(which is often also a prerequisite to be eligible for support)."]}),"\n",(0,t.jsxs)(i.li,{children:["Optional: ",(0,t.jsx)(i.code,{children:"maintained_until: YYYY-MM-DD"})," promises maintenance from the OS vendor\nuntil at least this date (in UTC)."]}),"\n",(0,t.jsxs)(i.li,{children:["Optional: ",(0,t.jsx)(i.code,{children:"l1_support_contact"})," contains a URI that provides customer support\ncontact for issues with this image. Note that this field must only be set if the\nservice provider does provide support for this image included in the image/flavor\npricing (but it might be provided by a contracted 3rd party, e.g. the OS vendor)."]}),"\n"]}),"\n",(0,t.jsx)(i.h3,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,t.jsxs)(i.p,{children:["The script ",(0,t.jsx)(i.code,{children:"image-md-check.py"})," retrieves the\nimage list from a configured cloud and checks each image for the\ncompleteness and consistency of mandatory properties."]})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>d,x:()=>r});var t=n(96540);const s={},a=t.createContext(s);function d(e){const i=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),t.createElement(a.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aed2f698.5cb1fd01.js b/assets/js/aed2f698.5cb1fd01.js new file mode 100644 index 0000000000..37f03667f2 --- /dev/null +++ b/assets/js/aed2f698.5cb1fd01.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5612],{7395:(e,r,s)=>{s.r(r),s.d(r,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>n,metadata:()=>a,toc:()=>u});var t=s(74848),i=s(28453);const n={sidebar_label:"Security groups"},o="How to configure and use security groups",a={id:"iaas/guides/user-guide/openstack/security-groups",title:"How to configure and use security groups",description:"Security groups in OpenStack are part of the network security mechanisms provided for the users.",source:"@site/docs/02-iaas/guides/user-guide/openstack/security-groups.md",sourceDirName:"02-iaas/guides/user-guide/openstack",slug:"/iaas/guides/user-guide/openstack/security-groups",permalink:"/docs/iaas/guides/user-guide/openstack/security-groups",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/openstack/security-groups.md",tags:[],version:"current",frontMatter:{sidebar_label:"Security groups"},sidebar:"docs",previous:{title:"OpenStack",permalink:"/docs/iaas/guides/user-guide/openstack/"},next:{title:"User Data Backups",permalink:"/docs/iaas/guides/user-guide/openstack/user-data-backups"}},c={},u=[{value:"Identify the requirements of your setup",id:"identify-the-requirements-of-your-setup",level:2},{value:"Further security considerations",id:"further-security-considerations",level:3},{value:"How to create security groups",id:"how-to-create-security-groups",level:2},{value:"Default security group",id:"default-security-group",level:3},{value:"Recommended security groups",id:"recommended-security-groups",level:3},{value:"How to use security groups",id:"how-to-use-security-groups",level:2}];function l(e){const r={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.h1,{id:"how-to-configure-and-use-security-groups",children:"How to configure and use security groups"}),"\n",(0,t.jsx)(r.p,{children:"Security groups in OpenStack are part of the network security mechanisms provided for the users.\nThey resemble sets of simple firewall rules allowing specific network traffic at a Port of a VM that connects it to a network.\nThe rules allow specific network port numbers and protocols while also differentiating between ingress and egress directions.\nUsually security groups are assigned to the Port(s) when a virtual machine is created, but assignments can also be changed at runtime later on.\nMultiple security groups can be assigned to a VM or Port simultaneously and in such case they will be combined as the union of all their rules."}),"\n",(0,t.jsx)(r.admonition,{type:"caution",children:(0,t.jsxs)(r.p,{children:["Security groups are mutable resources.\nTheir rules can be adjusted at any time after creation.\n",(0,t.jsx)(r.strong,{children:"Changing the rules of a security group will immediately apply the changes to all Ports or VMs it is assigned to."}),"\nIt is advisable to always review resources which use a security group before making changes to it."]})}),"\n",(0,t.jsx)(r.h2,{id:"identify-the-requirements-of-your-setup",children:"Identify the requirements of your setup"}),"\n",(0,t.jsx)(r.p,{children:"Every virtual machine that is created may need different firewall rules.\nThese requirements can also change over time.\nAdding or removing security groups will allow users to adapt the firewall rules specifically to their virtual machines."}),"\n",(0,t.jsx)(r.p,{children:"To harden the firewall settings for your virtual machine you may follow these steps:"}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"Before creating a virtual machine its purpose is usually already known. Use this information to identify all incoming and outgoing traffic rules that will be needed based on the communication patterns of the services it is meant to deploy. This includes communication protocols, port numbers, communication directions and optionally target/source address ranges."}),"\n",(0,t.jsx)(r.li,{children:"Look through already existing security groups and their rules. If a security group allows more traffic than needed it SHOULD NOT be used. If a security group contains only a subset of the required rules it MAY be used in combination with other security groups that contain rules which fulfill the remaining required traffic rules from point 1."}),"\n",(0,t.jsx)(r.li,{children:"If you were not successful in finding an appropriate combination of existing security groups or you need additional specific rules to cover all requirements, you MAY create one or more new Security Groups in which you can add the required rules."}),"\n",(0,t.jsx)(r.li,{children:"After ensuring the existence of one or more security groups that fulfill your requirements, you can create the VM with those security groups already specified in the creation command."}),"\n"]}),"\n",(0,t.jsx)(r.h3,{id:"further-security-considerations",children:"Further security considerations"}),"\n",(0,t.jsx)(r.p,{children:"When implementing network security requirements, firewall rules alone are not always sufficient and might need to be augmented with additional configuration or time-based constraints. Notable examples are:"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"SSH"}),"\nSSH is needed on many virtual machines to operate their guest operating system.\nIn a security group the port 22 can be opened for the TCP protocol to allow incoming SSH connections.\nBut that only should be done while also restricting the SSH configuration to public key authentication only (the recommended way) or having a strong username and password policy already applied to the operating system of the virtual machine.\nOtherwise default usernames and passwords which are often preconfigured in system images may be exploited through the exposed SSH port which enables attackers to compromise the virtual machine."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"ICMP"}),"\nIt might be useful to be able to ping a virtual machine or use other ICMP requests.\nBut for some virtual machine configurations this is either not necessary at all or only temporarily needed.\nOne benefit of security groups among other things is the ability to be easily added to and removed from existing virtual machines.\nSo a dedicated security group allowing ICMP could be added temporarily to a virtual machine for debugging purposes and removed from it afterwards."]}),"\n",(0,t.jsx)(r.h2,{id:"how-to-create-security-groups",children:"How to create security groups"}),"\n",(0,t.jsx)(r.p,{children:"Security groups are managed within a project.\nSo every project will have a different set of security groups.\nThey can be added dynamically to each virtual machine, during their creation or afterwards.\nAdditionally, they may also be removed from VMs at any point."}),"\n",(0,t.jsx)(r.p,{children:"Every project has its own default security group, which rules can be edited.\nAdditionally other security groups can be added until the project's quota is exhausted.\nTo add a security group, use the following command:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group create $SECURITY_GROUP\n"})}),"\n",(0,t.jsx)(r.p,{children:"Within every security group rules can be added up unto a defined maximum of rules, that usually is about 100.\nRules can be added to security groups with the following command:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group rule create [...] $SECURITY_GROUP\n"})}),"\n",(0,t.jsx)(r.p,{children:"To delete rules from a security group, the rule id has to be used.\nIt is listed in the details of the rules section of the security group."}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group rule delete $RULE_ID\n"})}),"\n",(0,t.jsx)(r.h3,{id:"default-security-group",children:"Default security group"}),"\n",(0,t.jsx)(r.p,{children:"Unless specified otherwise, the default security group is assigned to all VMs or Ports at creation.\nTo use any other than the default security group at creation it is necessary to specify the desired security group(s) during the creation process."}),"\n",(0,t.jsx)(r.p,{children:"To review which rules are defined in a security group, the following command can be used:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group show default\n"})}),"\n",(0,t.jsx)(r.h3,{id:"recommended-security-groups",children:"Recommended security groups"}),"\n",(0,t.jsx)(r.p,{children:"While projects can use very different aspects in security group rules and thus the security groups will always differ between projects, there are some security groups that are widely used.\nThrough the nature of security groups being seen as a set of rules that can be combined, having some basic security groups that allow basic protocols is a commonly used setup.\nThis section will demonstrate how to create some security groups for commonly used protocols and ports."}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"A security groups, that allows incoming SSH traffic:"}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group create ssh\nopenstack security group rule create --ingress --protocol tcp --dst-port 22 ssh\n"})}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"A security group, that allows incoming HTTP requests:"}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group create http\nopenstack security group rule create --ingress --protocol tcp --dst-port 80 http\n"})}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"A security group, that allows incoming HTTPS requests:"}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group create https\nopenstack security group rule create --ingress --protocol tcp --dst-port 443 https\n"})}),"\n",(0,t.jsxs)(r.ol,{children:["\n",(0,t.jsx)(r.li,{children:"A security group, that allows incoming ICMP requests:"}),"\n"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack security group create icmp\nopenstack security group rule create --protocol icmp icmp\n"})}),"\n",(0,t.jsx)(r.h2,{id:"how-to-use-security-groups",children:"How to use security groups"}),"\n",(0,t.jsx)(r.admonition,{type:"info",children:(0,t.jsx)(r.p,{children:"Security groups can be assigned to multiple resources simultaneously (such as VMs or Ports).\nThis means that security groups are reusable and don't need to be recreated for each applicable resource individually."})}),"\n",(0,t.jsxs)(r.p,{children:["Usually, initial security groups are added at the time of the creation of a VM.\nDuring creation, multiple security groups can also be added at the same time by repeating the ",(0,t.jsx)(r.code,{children:"--security-group"})," argument:"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack server create [...] --security-group $SECURITY_GROUP_1 --security-group $SECURITY_GROUP_2 $SERVER_NAME\n"})}),"\n",(0,t.jsx)(r.p,{children:"To add a security group to an existing VM, the following command can be used:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack server add security group $SERVER_NAME $SECURITY_GROUP\n"})}),"\n",(0,t.jsx)(r.p,{children:"To remove a security group from a VM, the following command can be used:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-bash",children:"openstack server remove security group $SERVER_NAME $SECURITY_GROUP\n"})}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsxs)(r.em,{children:["The source of this document can be found in the ",(0,t.jsx)(r.a,{href:"https://raw.githubusercontent.com/SovereignCloudStack/docs/main/docs/02-iaas/guides/user-guide/security-groups/security-groups.md",children:"SovereignCloudStack/docs"})," repository."]})}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.em,{children:"Author: SCS Community, License: CC by Attribution 4.0 International"})})]})}function d(e={}){const{wrapper:r}={...(0,i.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,r,s)=>{s.d(r,{R:()=>o,x:()=>a});var t=s(96540);const i={},n=t.createContext(i);function o(e){const r=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(n.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/afaff11a.f597fe7b.js b/assets/js/afaff11a.f597fe7b.js new file mode 100644 index 0000000000..62cf80455c --- /dev/null +++ b/assets/js/afaff11a.f597fe7b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1734],{77588:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/community","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/b08c16de.35c78cc2.js b/assets/js/b08c16de.35c78cc2.js new file mode 100644 index 0000000000..c3bf8b7f23 --- /dev/null +++ b/assets/js/b08c16de.35c78cc2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9390],{87333:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>a,toc:()=>d});var t=s(74848),i=s(28453);const l={},o="Ansible Style Guide",a={id:"contribute/styleguides/ansible_styleguide",title:"Ansible Style Guide",description:"We use nearly all default rules of ansible lint. A listing of all these rules can be found in the Ansible Lint documentation:",source:"@site/community/contribute/styleguides/ansible_styleguide.md",sourceDirName:"contribute/styleguides",slug:"/contribute/styleguides/ansible_styleguide",permalink:"/community/contribute/styleguides/ansible_styleguide",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{}},r={},d=[{value:"Task naming",id:"task-naming",level:2},{value:"Key Order",id:"key-order",level:2},{value:"Positioning and use of the become directive",id:"positioning-and-use-of-the-become-directive",level:3},{value:"Position of the when condition",id:"position-of-the-when-condition",level:3},{value:"Usage of collections",id:"usage-of-collections",level:2},{value:"Usage of roles from other collections",id:"usage-of-roles-from-other-collections",level:2},{value:"Parameters that offer lists",id:"parameters-that-offer-lists",level:2},{value:"Usage of changed_when",id:"usage-of-changed_when",level:2},{value:"Disable linting rules",id:"disable-linting-rules",level:2}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"ansible-style-guide",children:"Ansible Style Guide"}),"\n",(0,t.jsxs)(n.p,{children:["We use nearly all default rules of ansible lint. A listing of all these rules can be found in the Ansible Lint documentation:\n",(0,t.jsx)(n.a,{href:"https://ansible.readthedocs.io/projects/lint/rules/",children:"https://ansible.readthedocs.io/projects/lint/rules/"}),".\nPlease always use the ansible linting to check if the code complies with the default linting rules.\nHowever, since in most cases we always use the latest version of packages and Ansible lint does not provide this, we decided to\ndisable the package_latest rule."]}),"\n",(0,t.jsx)(n.h2,{id:"task-naming",children:"Task naming"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Tasks must always have names. The only exception allowed is for forked playbooks."}),"\n",(0,t.jsx)(n.li,{children:"A name never starts with a small letter"}),"\n",(0,t.jsx)(n.li,{children:"Names are written in present tense"}),"\n",(0,t.jsx)(n.li,{children:"No punctuation is used in names"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"key-order",children:"Key Order"}),"\n",(0,t.jsxs)(n.p,{children:["To check the key order we use our own rule. This can be found ",(0,t.jsx)(n.a,{href:"https://github.com/osism/zuul-jobs/tree/main/roles/ansible-lint/files",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"positioning-and-use-of-the-become-directive",children:"Positioning and use of the become directive"}),"\n",(0,t.jsx)(n.p,{children:"The become directive is only set when needed and is always set explicitly for each task that needs it."}),"\n",(0,t.jsx)(n.p,{children:"Blocks, roles or playbooks are never executed in a privileged mode."}),"\n",(0,t.jsxs)(n.p,{children:["We always insert the become directive between the name of a task and the task itself. This also applies to related directives\nlike ",(0,t.jsx)(n.em,{children:"become_user"})," or ",(0,t.jsx)(n.em,{children:"become_flags"}),". This is for better visibility if a task is privileged or not."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'- name: Copy hddtemp configuration file\n become: true\n ansible.builtin.copy:\n src: "{{ ansible_os_family }}/hddtemp"\n dest: "{{ hddtemp_conf_file }}"\n owner: root\n group: root\n mode: 0644\n notify: Restart hddtemp service\n'})}),"\n",(0,t.jsx)(n.h3,{id:"position-of-the-when-condition",children:"Position of the when condition"}),"\n",(0,t.jsx)(n.p,{children:"If you need to use the when condition please add this at the end-section from the task where it is needed. This makes the code\neasier to understand for others. Ansible lint provides the when condition under the task name for blocks. To keep the code clear\nwe decided against it. Please disable this with a noqa if necessary. For example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'- name: "Archive existing {{ resolvconf_file }} file"\n become: true\n ansible.posix.synchronize:\n src: "/etc/resolv.conf"\n dest: "/etc/resolv.conf.{{ ansible_date_time.date }}"\n archive: true\n delegate_to: "{{ inventory_hostname }}"\n when: stat_resolvconf_file.stat.islnk is defined and not stat_resolvconf_file.stat.islnk\n'})}),"\n",(0,t.jsx)(n.h2,{id:"usage-of-collections",children:"Usage of collections"}),"\n",(0,t.jsx)(n.p,{children:"Collections are always defined as in the following example."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"netbox.netbox"})," is here the collection that is used."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"- name: Configure netbox manufacturers\n netbox.netbox.netbox_manufacturer:\n netbox_url: '{{ netbox_url }}'\n netbox_token: '{{ netbox_token }}'\n data:\n name: '{{ item.value.name }}'\n slug: '{{ item.value.slug }}'\n description: \"{{ item.value.description | default('') }}\"\n state: present\n with_dict: '{{ netbox_data_manufacturers }}'\n"})}),"\n",(0,t.jsx)(n.p,{children:"Please don\xb4t declare it in this way!:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'collections:\n - netbox.netbox\n\n tasks:\n - name: Manage Discworld site\n netbox_site:\n netbox_url: "{{ netbox_url }}"\n netbox_token: "{{ netbox_token }}"\n validate_certs: false\n data:\n name: Discworld\n slug: discworld\n state: present\n'})}),"\n",(0,t.jsx)(n.p,{children:"If you have to use collections please define them in a requirements.yml."}),"\n",(0,t.jsx)(n.p,{children:"Example yaml:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"roles:\n - name: geerlingguy.certbot\n version: master\n type: git\n src: git+https://github.com/geerlingguy/ansible-role-certbot.git\n---\ncollections:\n - name: ansible.netcommon\n source: https://galaxy.ansible.com\n\n - name: https://github.com/ansible-collections/ansible.posix.git\n type: git\n version: main\n"})}),"\n",(0,t.jsx)(n.h2,{id:"usage-of-roles-from-other-collections",children:"Usage of roles from other collections"}),"\n",(0,t.jsx)(n.p,{children:"If you want to reuse roles please do it in the following way:"}),"\n",(0,t.jsx)(n.p,{children:"First you have to declare the role or collection in the requirements.yml like shown in the example before."}),"\n",(0,t.jsx)(n.p,{children:"Than you can use it in playbooks like this"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"roles:\n - role: osism.services.auditd\n"})}),"\n",(0,t.jsx)(n.h2,{id:"parameters-that-offer-lists",children:"Parameters that offer lists"}),"\n",(0,t.jsx)(n.p,{children:"Parameters that provide a list are always defined as in the following example."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"docker_hosts_defaults"})," sets the defaults in the role. Overriding is only possible with the ",(0,t.jsx)(n.strong,{children:"ansible-defaults"})," repository."]}),"\n",(0,t.jsx)(n.p,{children:"In the configuration repository, docker_hosts_extra is then used to add additional items to the list."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"docker_hosts"})," itself is never modified from the outside."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"docker_hosts_defaults:\n - 'unix:///var/run/docker.sock'\ndocker_hosts_extra: []\ndocker_hosts: '{{ docker_hosts_defaults + docker_hosts_extra }}'\n"})}),"\n",(0,t.jsx)(n.h2,{id:"usage-of-changed_when",children:"Usage of changed_when"}),"\n",(0,t.jsx)(n.p,{children:"Please think twice before turning off changed_when. It's a fairly simple yet safety-relevant linting rule and is quite easy to\nimplement."}),"\n",(0,t.jsx)(n.h2,{id:"disable-linting-rules",children:"Disable linting rules"}),"\n",(0,t.jsxs)(n.p,{children:["In principle, it is only allowed to disable rules if there is really no other possibility.\nPlease do not disable rules in general but only in individual cases via Noqa. Please use in this case the full rulename and not\nthe numbers, because them are depricated. If it makes sense to ignore a rule, please open up an issue in the\n",(0,t.jsx)(n.a,{href:"https://github.com/osism/issues",children:"https://github.com/osism/issues"})," repository with a label discussion."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const i={},l=t.createContext(i);function o(e){const n=t.useContext(l);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b0ccdb87.0ff93353.js b/assets/js/b0ccdb87.0ff93353.js new file mode 100644 index 0000000000..42fddffc26 --- /dev/null +++ b/assets/js/b0ccdb87.0ff93353.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6646],{48647:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var s=t(74848),i=t(28453);const o={},r="Overview",a={id:"operating-scs/components/central-api/overview",title:"Overview",description:"Premise",source:"@site/docs/04-operating-scs/components/central-api/overview.md",sourceDirName:"04-operating-scs/components/central-api",slug:"/operating-scs/components/central-api/overview",permalink:"/docs/operating-scs/components/central-api/overview",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/central-api/overview.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Central API",permalink:"/docs/category/central-api"},next:{title:"Central API MVP",permalink:"/docs/operating-scs/components/central-api/poc-setup"}},c={},l=[{value:"Premise",id:"premise",level:2},{value:"Challenge",id:"challenge",level:2},{value:"The chosen approach to pursue",id:"the-chosen-approach-to-pursue",level:2},{value:"Kubernetes API",id:"kubernetes-api",level:3},{value:"Crossplane tooling",id:"crossplane-tooling",level:3},{value:"Cluster stacks / Cluster API",id:"cluster-stacks--cluster-api",level:3},{value:"Implementation",id:"implementation",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",mermaid:"mermaid",ol:"ol",p:"p",section:"section",strong:"strong",sup:"sup",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"overview",children:"Overview"}),"\n",(0,s.jsx)(n.h2,{id:"premise",children:"Premise"}),"\n",(0,s.jsx)(n.p,{children:"By embracing existing open source solutions and bundling them, SCS provides a viable\nalternative to widely adopted proprietary cloud offerings, including\nInfrastructure-as-a-Service offerings, Kubernetes-as-a-Service offerings and other\nX-as-a-Service offerings."}),"\n",(0,s.jsx)(n.p,{children:"The choice to embrace existing technology has huge advantages over starting from\nscratch.\nBy not reinventing wheels, a lot of effort is saved and existing communities are\nstrengthened. The adoption of existing open standards is supported, reducing\nmarket fragmentation and increasing interoperability."}),"\n",(0,s.jsx)(n.h2,{id:"challenge",children:"Challenge"}),"\n",(0,s.jsx)(n.p,{children:"The challenge: Using popular open source components at cloud service providers\ndoes not result in a consistent experience for their users, yet."}),"\n",(0,s.jsxs)(n.p,{children:["Each part of the stack is consistent within its own scope: E.g. The\n",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/api-ref/network/v2/",children:"OpenStack Networking API"})," is sort of\nconsistent with the\n",(0,s.jsx)(n.a,{href:"https://docs.openstack.org/api-ref/load-balancer/v2/",children:"OpenStack Load Balancer API"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The OpenStack API's share API idioms like the used AuthN/AuthZ\n(Authentication/Authorization) mechanisms. But these are not applicable beyond\nOpenStack services."}),"\n",(0,s.jsxs)(n.p,{children:["Entering general IAM (Identity and Access Management), Keycloak has its own set of\nAPI endpoints and authentication flows.\nEntering Kubernetes, CAPI (",(0,s.jsx)(n.a,{href:"https://cluster-api.sigs.k8s.io/",children:"Kubernetes Cluster API"}),")\nuses the Kubernetes API with its own authentication configuration, RBAC (Role Based\nAccess Control) and opinionated resource management idioms."]}),"\n",(0,s.jsx)(n.p,{children:"So, without a central API harmonizing at least the semantics of AuthN/AuthZ and\nresource management, users are left with a bunch of semantically incompatible API's.\nIf resources in different API's are somehow interconnected, the users have to take\ncare of bridging these differences themselves."}),"\n",(0,s.jsx)(n.p,{children:"Providing a consistent API across many different offerings with sort of consistent\nAPI idioms is something that primarily the big proprietary cloud providers manage to\ndo. And while that serves users well in that regard, it also serves as an effective\nvendor lock-in feature."}),"\n",(0,s.jsx)(n.h2,{id:"the-chosen-approach-to-pursue",children:"The chosen approach to pursue"}),"\n",(0,s.jsx)(n.mermaid,{value:'flowchart TB\n subgraph "With central API (simplified)"\n User2{"User"}\n subgraph "provider responsibility"\n CentralAPI["Central API"]\n OpenStack2["OpenStack API"]\n Keycloak2["Keycloak API"]\n CAPI2["Cluster API"]\n end\n\n User2\n -- uses --\x3e K8sTooling2["kubectl/\\nargocd/flux/..."]\n K8sTooling2 -- calls --\x3e CentralAPI\n CentralAPI -- calls --\x3e OpenStack2\n CentralAPI -- calls --\x3e Keycloak2\n CentralAPI -- calls --\x3e CAPI2\n end\n subgraph "Without central API (simplified)"\n User1{"User"}\n subgraph "provider responsibility"\n OpenStack1["OpenStack API"]\n Keycloak1["Keycloak API"]\n end\n CAPI1["Cluster API"]\n\n User1\n -- uses --\x3e OpenStackCLI1["OpenStackCLI/OpenStackUI/\\nTerraform/Ansible/..."]\n -- calls --\x3e OpenStack1\n User1\n -- uses --\x3e KeycloakCLI1["KeycloakCLI/KeycloakUI/\\nTerraform/Ansible/..."]\n -- calls --\x3e Keycloak1\n User1\n -- uses --\x3e K8sTooling1["kubectl/\\nargocd/flux/..."]\n -- calls --\x3e CAPI1\n end'}),"\n",(0,s.jsxs)(n.p,{children:["Goal: ",(0,s.jsx)(n.strong,{children:'Provide a "semantically" consistent API modelling most cloud resources\nthat are in scope for SCS'}),"."]}),"\n",(0,s.jsx)(n.p,{children:"In other words: Bring each cloud resource type - as it is - into the central API."}),"\n",(0,s.jsxs)(n.p,{children:["An ",(0,s.jsx)(n.code,{children:"OpenStack Compute Instance"})," continues to be as-is with all of its usual\nproperties and implementation details.\nA ",(0,s.jsx)(n.code,{children:"Keycloak Realm"})," continues to be as-is with all of its usual properties\nand implementation details."]}),"\n",(0,s.jsxs)(n.p,{children:["That is not to say that abstractions are absolutely not planned as further steps.\nThere were discussions happening about that already: Regarding IAM management ",(0,s.jsx)(n.sup,{children:(0,s.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),"\nand Kubernetes management ",(0,s.jsx)(n.sup,{children:(0,s.jsx)(n.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["However, the ",(0,s.jsx)(n.strong,{children:"main"})," benefit is that all offered API objects can be managed\nusing the same API idioms (AuthN/AuthZ/REST) with the same client tooling ",(0,s.jsx)(n.sup,{children:(0,s.jsx)(n.a,{href:"#user-content-fn-3",id:"user-content-fnref-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"kubernetes-api",children:"Kubernetes API"}),"\n",(0,s.jsx)(n.p,{children:'Instead of creating SCS-specific API idioms and building the implementation\nfrom scratch, the Kubernetes API will be "reused". Essentially, the Kubernetes\nAPI is just an opinionated REST API which has opinions on how a resource\nis defined, how it looks like, how it is reconciled/handled, how AuthN/AuthZ\ncan be implemented. The Kubernetes ecosystem provides much tooling for working\nwith such (custom) resource definitions: For creating the definitions\nthemselves, building controllers, making them discoverable and deployable.'}),"\n",(0,s.jsx)(n.p,{children:"As such, Kubernetes is a great choice for building any sort of resource\nmanagement API - with some caveats regarding its deployment and the legacy\nof starting off as container orchestration tooling."}),"\n",(0,s.jsx)(n.h3,{id:"crossplane-tooling",children:"Crossplane tooling"}),"\n",(0,s.jsxs)(n.p,{children:['Crossplane even extends the Kubernetes API with\n"',(0,s.jsx)(n.a,{href:"https://docs.crossplane.io/v1.14/concepts/compositions/",children:"Compositions"}),'" and\n"',(0,s.jsx)(n.a,{href:"https://docs.crossplane.io/v1.14/concepts/composite-resource-definitions/",children:"Composite Resource Definitions"}),'"\n(XRD) to make Kubernetes the base for platform engineering within organizations.']}),"\n",(0,s.jsx)(n.p,{children:'Secondly, it provides an API machinery to bring any cloud resource into Kubernetes\nusing backend-specific "providers" (roughly comparable with Terraform providers).\nAs such, Crossplane with its provider ecosystem actually already did most of\nthe heavy lifting for providing e.g. OpenStack or Keycloak resources inside of Kubernetes.'}),"\n",(0,s.jsxs)(n.p,{children:["On top, the platform engineering concepts in Crossplane make building multi-tenancy\nsystems pretty straight-forward, even for\n",(0,s.jsx)(n.a,{href:"https://docs.crossplane.io/knowledge-base/guides/multi-tenant/#single-cluster-multi-tenancy",children:"single clusters"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Alright. Crossplane takes care of exposing OpenStack resources and does some\nfancy stuff regarding multi-tenancy. What about providing actual Kubernetes\n",(0,s.jsx)(n.strong,{children:"workload"})," clusters?"]}),"\n",(0,s.jsx)(n.h3,{id:"cluster-stacks--cluster-api",children:"Cluster stacks / Cluster API"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks",children:"Cluster stacks"})," do\n",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/cluster-stack-operator/blob/adb648ceaebddca04a015fbea0319110ca99a5cc/docs/architecture/user-flow.md#recap---how-do-cluster-api-and-cluster-stacks-work-together",children:"not replace the use of Cluster API"}),".\nInstead, they are complementing Cluster API by providing ",(0,s.jsx)(n.code,{children:"ClusterClasses"}),", node\nimages (if required) and workload cluster addons."]}),"\n",(0,s.jsx)(n.p,{children:"It is still to be determined how to bring multi-tenancy concepts from Crossplane\ninto ClusterStacks/CAPI, if even required."}),"\n",(0,s.jsxs)(n.p,{children:["Should the provider be responsible for creating ",(0,s.jsx)(n.code,{children:"ClusterClasses"}),"?\nIf yes, enforcing some parameters inside via a ",(0,s.jsx)(n.code,{children:"ClusterClass"})," may be enough\nto provide multi-tenancy, already. That is to be determined, though."]}),"\n",(0,s.jsx)(n.h2,{id:"implementation",children:"Implementation"}),"\n",(0,s.jsxs)(n.p,{children:["Disregarding any potential further abstractions, most work in automation for\nthe providers will be about installing the central API and securely distributing\ncredentials for backing services like OpenStack or Keycloak.\nFor that, there is no production implementation yet. See\n",(0,s.jsx)(n.a,{href:"/docs/operating-scs/components/central-api/poc-setup",children:"the POC for inspiration"})," for now. It includes access to an OpenStack API\nthrough Kubernetes/Crossplane."]}),"\n","\n",(0,s.jsxs)(n.section,{"data-footnotes":!0,className:"footnotes",children:[(0,s.jsx)(n.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{id:"user-content-fn-1",children:["\n",(0,s.jsxs)(n.p,{children:['There were discussions to build a generic SCS API to support\nSCS installations powered by Zitadel. Approaching the issue a little\nbit like the "Abstract all the things!" consideration above, but focusing\non two basic use cases (Firstly, setting up an identity federation to some\nexisting identity provider; Secondly, managing users without remote identity\nprovider). While not in scope for the first steps, this probably could be\nelegantly implemented as one generic Crossplane "Composite Resource Definition"\nbacked by a Crossplane "Composition" defining either Keycloak objects OR\nZitadel objects (given that Zitadel gets a Crossplane provider or a similar\nKubernetes controller before). ',(0,s.jsx)(n.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{id:"user-content-fn-2",children:["\n",(0,s.jsxs)(n.p,{children:['In order to cover providers that use Gardnener, a generic Crossplane\n"Composite Resource Definition" like in ',(0,s.jsx)(n.sup,{children:(0,s.jsx)(n.a,{href:"#user-content-fn-1",id:"user-content-fnref-1-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})}),' may be created. Alternatively,\nGardnener CRD\'s could maybe just be mirrored in their Central API instance,\nstill creating an interoperability benefit through "semantic" compatibility. ',(0,s.jsx)(n.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{id:"user-content-fn-3",children:["\n",(0,s.jsxs)(n.p,{children:["Which is also not to say that it will be suggested to providers to disable\ntheir public OpenStack/Keycloak/... API's, preventing use of native\nOpenStack/Keycloak/... tooling and breaking existing solutions.\nExtensively using these API's together with the central API may compromise\nthe benefits of its uniform AuthZ, though. ",(0,s.jsx)(n.a,{href:"#user-content-fnref-3","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b12ed0df.7d9631b4.js b/assets/js/b12ed0df.7d9631b4.js new file mode 100644 index 0000000000..4e23fe3049 --- /dev/null +++ b/assets/js/b12ed0df.7d9631b4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[801],{45669:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"standards"}')}}]); \ No newline at end of file diff --git a/assets/js/b191927f.365feba3.js b/assets/js/b191927f.365feba3.js new file mode 100644 index 0000000000..419b0ab42f --- /dev/null +++ b/assets/js/b191927f.365feba3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6452],{79704:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>a,contentTitle:()=>r,default:()=>x,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var n=s(74848),l=s(28453);const i={},r="SCS Compatible IaaS",d={id:"scs-compatible-iaas",title:"SCS Compatible IaaS",description:"Note that the state Stable is shown here if stabilized at is in the future, whereas Effective is shown here if stabilized at is in the past and deprecated at is unset or in the future.",source:"@site/standards/scs-compatible-iaas.md",sourceDirName:".",slug:"/scs-compatible-iaas",permalink:"/standards/scs-compatible-iaas",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Scopes and versions",permalink:"/standards/certification/scopes-versions"},next:{title:"SCS Compatible KaaS",permalink:"/standards/scs-compatible-kaas"}},a={},c=[];function h(t){const e={a:"a",em:"em",h1:"h1",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,l.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"scs-compatible-iaas",children:"SCS Compatible IaaS"}),"\n",(0,n.jsxs)(e.p,{children:["Note that the state ",(0,n.jsx)(e.em,{children:"Stable"})," is shown here if ",(0,n.jsx)(e.em,{children:"stabilized at"})," is in the future, whereas ",(0,n.jsx)(e.em,{children:"Effective"})," is shown here if ",(0,n.jsx)(e.em,{children:"stabilized at"})," is in the past and ",(0,n.jsx)(e.em,{children:"deprecated at"})," is unset or in the future."]}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"Scope versions ->"}),(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"v3"}),(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"v4"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"State"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"Deprecated"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"Effective"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"Stabilized at"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"2023-06-15"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"2024-02-28"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"Deprecated at"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"2024-04-30"}),(0,n.jsx)(e.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.strong,{children:"Standards"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"OpenStack Powered Compute"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://opendev.org/openinfra/interop/src/branch/master/guidelines/2022.11.json",children:"v2022.11"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://opendev.org/openinfra/interop/src/branch/master/guidelines/2022.11.json",children:"v2022.11"})})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"scs-0100: Flavor naming"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"v3"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"v3"})})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"scs-0101: Entropy"}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"/standards/scs-0101-v1-entropy",children:"v1"})})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"scs-0102: Image metadata"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"/standards/scs-0102-v1-image-metadata",children:"v1"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"/standards/scs-0102-v1-image-metadata",children:"v1"})})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"scs-0103: Standard flavors"}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"/standards/scs-0103-v1-standard-flavors",children:"v1"})})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"scs-0104: Standard images"}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"/standards/scs-0104-v1-standard-images",children:"v1"})})]})]})]})]})}function x(t={}){const{wrapper:e}={...(0,l.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(h,{...t})}):h(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>r,x:()=>d});var n=s(96540);const l={},i=n.createContext(l);function r(t){const e=n.useContext(i);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function d(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(l):t.components||l:r(t.components),n.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/b1eed1ab.02c0bb47.js b/assets/js/b1eed1ab.02c0bb47.js new file mode 100644 index 0000000000..182b27123b --- /dev/null +++ b/assets/js/b1eed1ab.02c0bb47.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7362],{76309:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>c,contentTitle:()=>d,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>o});var n=s(74848),i=s(28453);const r={},d="scs-0214: Kubernetes Node Distribution and Availability",a={id:"kaas/scs-0214",title:"scs-0214: Kubernetes Node Distribution and Availability",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/kaas/scs-0214.md",sourceDirName:"kaas",slug:"/kaas/scs-0214",permalink:"/standards/kaas/scs-0214",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Kubernetes Nodes Anti Affinity",permalink:"/standards/scs-0213-v1-k8s-nodes-anti-affinity"},next:{title:"Kubernetes Node Distribution and Availability",permalink:"/standards/scs-0214-v1-k8s-node-distribution"}},c={},o=[];function l(t){const e={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"scs-0214-kubernetes-node-distribution-and-availability",children:"scs-0214: Kubernetes Node Distribution and Availability"}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:"Version"}),(0,n.jsx)(e.th,{children:"Type"}),(0,n.jsx)(e.th,{children:"State"}),(0,n.jsx)(e.th,{children:"stabilized"}),(0,n.jsx)(e.th,{children:"deprecated"})]})}),(0,n.jsx)(e.tbody,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0214-v1-k8s-node-distribution",children:"scs-0214-v1"})}),(0,n.jsx)(e.td,{children:"Standard"}),(0,n.jsx)(e.td,{children:"Stable"}),(0,n.jsx)(e.td,{children:"2024-02-08"}),(0,n.jsx)(e.td,{children:"-"})]})})]})]})}function u(t={}){const{wrapper:e}={...(0,i.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(l,{...t})}):l(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>d,x:()=>a});var n=s(96540);const i={},r=n.createContext(i);function d(t){const e=n.useContext(r);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:d(t.components),n.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/b1fd1705.a2e6f9d5.js b/assets/js/b1fd1705.a2e6f9d5.js new file mode 100644 index 0000000000..a3d6ed814b --- /dev/null +++ b/assets/js/b1fd1705.a2e6f9d5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8215],{22544:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var o=t(74848),s=t(28453);const i={},a="Guide: Setting up openstack-health-monitor on Debian 12",r={id:"operating-scs/guides/openstack-health-monitor/Debian12-Install",title:"Guide: Setting up openstack-health-monitor on Debian 12",description:"Kurt Garloff, 2024-02-20",source:"@site/docs/04-operating-scs/01-guides/openstack-health-monitor/Debian12-Install.md",sourceDirName:"04-operating-scs/01-guides/openstack-health-monitor",slug:"/operating-scs/guides/openstack-health-monitor/Debian12-Install",permalink:"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/01-guides/openstack-health-monitor/Debian12-Install.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Guides",permalink:"/docs/category/guides-1"},next:{title:"Metering",permalink:"/docs/category/metering"}},l={},d=[{value:"Intro",id:"intro",level:2},{value:"Setting up the driver VM",id:"setting-up-the-driver-vm",level:2},{value:"Internal vs external monitoring",id:"internal-vs-external-monitoring",level:3},{value:"Unprivileged operation",id:"unprivileged-operation",level:3},{value:"Driver VM via openstack CLI",id:"driver-vm-via-openstack-cli",level:3},{value:"Configuring openstack CLI on the driver VM",id:"configuring-openstack-cli-on-the-driver-vm",level:3},{value:"Custom CA",id:"custom-ca",level:3},{value:"Your first <code>api_monitor.sh</code> iteration",id:"your-first-api_monitorsh-iteration",level:2},{value:"Resource impact and charging",id:"resource-impact-and-charging",level:3},{value:"Automating startup and cleanup",id:"automating-startup-and-cleanup",level:2},{value:"Changing parameters and restarting",id:"changing-parameters-and-restarting",level:3},{value:"Multiple instances",id:"multiple-instances",level:3},{value:"Alarming and Logs",id:"alarming-and-logs",level:2},{value:"eMail",id:"email",level:3},{value:"Log files",id:"log-files",level:3},{value:"Data collection and dashboard",id:"data-collection-and-dashboard",level:2},{value:"telegraf",id:"telegraf",level:3},{value:"influxdb",id:"influxdb",level:3},{value:"Add <code>-S CLOUDNAME</code> to your <code>run_CLOUDNAME.sh</code> script",id:"add--s-cloudname-to-your-run_cloudnamesh-script",level:3},{value:"grafana",id:"grafana",level:3},{value:"Basic config",id:"basic-config",level:4},{value:"Enable influx database in grafana",id:"enable-influx-database-in-grafana",level:4},{value:"Importing the dashboard",id:"importing-the-dashboard",level:4},{value:"No data displayed?",id:"no-data-displayed",level:4},{value:"Dashboard features",id:"dashboard-features",level:4},{value:"github OIDC integration",id:"github-oidc-integration",level:4},{value:"Alternative approach to install and configure the dashboard behind a reverse proxy",id:"alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy",level:2},{value:"Maintenance",id:"maintenance",level:2},{value:"Unattended upgrades",id:"unattended-upgrades",level:3},{value:"Updating openstack-health-monitor",id:"updating-openstack-health-monitor",level:3},{value:"Backup",id:"backup",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Debugging issues",id:"debugging-issues",level:3},{value:"Analyzing failures",id:"analyzing-failures",level:3},{value:"Cleaning things up",id:"cleaning-things-up",level:3}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"guide-setting-up-openstack-health-monitor-on-debian-12",children:"Guide: Setting up openstack-health-monitor on Debian 12"}),"\n",(0,o.jsx)(n.p,{children:"Kurt Garloff, 2024-02-20"}),"\n",(0,o.jsx)(n.h2,{id:"intro",children:"Intro"}),"\n",(0,o.jsxs)(n.p,{children:["The development of ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/",children:"openstack-health-monitor"})," was done on ",(0,o.jsx)(n.a,{href:"https://kfg.images.obs-website.eu-de.otc.t-systems.com/",children:"openSUSE 15.x images"}),", just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution."]}),"\n",(0,o.jsx)(n.p,{children:"Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here."}),"\n",(0,o.jsxs)(n.p,{children:["Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/scs-health-monitor",children:"successor project"})," for the increasingly hard to maintain shell code, this may not be worth the trouble."]}),"\n",(0,o.jsxs)(n.p,{children:["openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested.\nThe scenario is described in a bit more detail in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"repository's README.md"})," file."]}),"\n",(0,o.jsxs)(n.p,{children:["The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the ",(0,o.jsx)(n.a,{href:"https://docs.scs.community/docs/category/monitoring",children:"monitoring section"})," of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up."]}),"\n",(0,o.jsx)(n.h2,{id:"setting-up-the-driver-vm",children:"Setting up the driver VM"}),"\n",(0,o.jsxs)(n.p,{children:["So we start a ",(0,o.jsx)(n.code,{children:"Debian 12"})," image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard;\nthe instructions use flavor names and image names from the SCS standards.\nFor many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack)."]}),"\n",(0,o.jsx)(n.h3,{id:"internal-vs-external-monitoring",children:"Internal vs external monitoring"}),"\n",(0,o.jsx)(n.p,{children:"There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor."}),"\n",(0,o.jsx)(n.p,{children:"The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems."}),"\n",(0,o.jsx)(n.h3,{id:"unprivileged-operation",children:"Unprivileged operation"}),"\n",(0,o.jsx)(n.p,{children:"Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own."}),"\n",(0,o.jsxs)(n.p,{children:["If ",(0,o.jsx)(n.code,{children:"openstack availability zone list --compute"})," fails for you without admin rights, please fix your openstack client. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Healh-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)"]}),"\n",(0,o.jsx)(n.h3,{id:"driver-vm-via-openstack-cli",children:"Driver VM via openstack CLI"}),"\n",(0,o.jsxs)(n.p,{children:["The author prefers to setup the VM via ",(0,o.jsx)(n.code,{children:"openstack"})," CLI tooling. He has working entries for all clouds he uses in his ",(0,o.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})," and ",(0,o.jsx)(n.code,{children:"secure.yaml"})," and has exported the ",(0,o.jsx)(n.code,{children:"OS_CLOUD"})," environment variable to point to the cloud he is working on to set up the driver VM. The author uses the ",(0,o.jsx)(n.code,{children:"bash"})," shell. All of this of course could be scripted."]}),"\n",(0,o.jsx)(n.p,{children:"So here we go"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["Create the network setup for a VM in a network ",(0,o.jsx)(n.code,{children:"oshm-network"})," with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network."]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"PUBLIC=$(openstack network list --external -f value -c Name)\nopenstack router create oshm-router\nopenstack router set --external-gateway $PUBLIC oshm-driver-router\nopenstack network create oshm-network\nopenstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet\nopenstack router add subnet oshm-router oshm-subnet\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"2",children:["\n",(0,o.jsx)(n.li,{children:"Create a security group that allows ssh and ping access"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack security group create sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping\nopenstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"3",children:["\n",(0,o.jsx)(n.li,{children:"Being at it, we also create the security group for grafana"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack security group create grafana\nopenstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"4",children:["\n",(0,o.jsx)(n.li,{children:"To connect to the VM via ssh later, we create an SSH keypair"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key\nchmod og-r ~/.ssh/oshm-key.pem \n"})}),"\n",(0,o.jsxs)(n.p,{children:["Rather than creating a new key (and storing and protecting the private key), we could have passed ",(0,o.jsx)(n.code,{children:"--public-key"})," and used an existing keypair."]}),"\n",(0,o.jsxs)(n.ol,{start:"5",children:["\n",(0,o.jsx)(n.li,{children:"Look up Debian 12 image UUID."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"IMGUUID=$(openstack image list --name \"Debian 12\" -f value -c ID | tr -d '\\r')\necho $IMGUUID\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Sidenote: The ",(0,o.jsx)(n.code,{children:"tr"})," command is there to handle broken tooling that embeds a trailing ",(0,o.jsx)(n.code,{children:"\\r"})," in the output."]}),"\n",(0,o.jsxs)(n.ol,{start:"6",children:["\n",(0,o.jsx)(n.li,{children:"Boot the driver VM"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing ",(0,o.jsx)(n.code,{children:"--block-device"}),". See ",(0,o.jsx)(n.a,{href:"https://scs.community/2023/08/21/diskless-flavors/",children:"diskless flavor blog article"}),". For flavors with local root disks, you could have used the ",(0,o.jsx)(n.code,{children:"--image $IMGUUID"})," parameter instead."]}),"\n",(0,o.jsxs)(n.ol,{start:"7",children:["\n",(0,o.jsxs)(n.li,{children:["Wait for it to boot (optional)\nYou can look at the boot log with ",(0,o.jsx)(n.code,{children:"openstack console log show oshm-driver"})," or connect to it via VNC at the URL given by ",(0,o.jsx)(n.code,{children:"openstack console url show oshm-driver"}),". You can of course also query openstack on the status ",(0,o.jsx)(n.code,{children:"openstack server list"})," or ",(0,o.jsx)(n.code,{children:"openstack server show oshm-driver"}),". You can also just create a simple loop:"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'declare -i ctr=0 RC=0\nwhile [ $ctr -le 120 ]; do\n STATUS="$(openstack server list --name oshm-driver -f value -c Status)"\n if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi \n if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi\n if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi\n sleep 2\n let ctr+=1\ndone\n# return $RC\nif [ $RC != 0 ]; then false; fi\n'})}),"\n",(0,o.jsxs)(n.ol,{start:"8",children:["\n",(0,o.jsx)(n.li,{children:"Attach a floating IP so it's reachable from the outside."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks | sed "s@^[^:]*:[^\']*\'\\([0-9\\.]*\\)\'.*\\$@\\1@")\nFIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)\necho $FIXEDIP $FIXEDPORT\nopenstack floating ip create --port $FIXEDPORT $PUBLIC\nFLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")\necho "Floating IP: $FLOATINGIP"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Remember this floating IP address."}),"\n",(0,o.jsxs)(n.ol,{start:"9",children:["\n",(0,o.jsx)(n.li,{children:"Connect to it via ssh"}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP\n"})}),"\n",(0,o.jsx)(n.p,{children:"On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"All the following commands are performed on the newly started driver VM."})}),"\n",(0,o.jsx)(n.h3,{id:"configuring-openstack-cli-on-the-driver-vm",children:"Configuring openstack CLI on the driver VM"}),"\n",(0,o.jsx)(n.p,{children:"We need to install the openstack client utilities."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo apt-get update\nsudo apt-get install python3-openstackclient\nsudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Configure your cloud access in ",(0,o.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n interface: public\n identity-api-version: 3\n #region_name: REGION\n auth:\n auth_url: KEYSTONE_ENDPOINT\n project_id: PROJECT_UUID\n #alternatively project_name and project_domain_name\n user_domain_name: default\n # change to your real domain\n"})}),"\n",(0,o.jsxs)(n.p,{children:["and ",(0,o.jsx)(n.code,{children:"secure.yaml"})," (in the same directory)"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"clouds:\n CLOUDNAME:\n auth:\n username: USERNAME\n password: PASSWORD\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"CLOUDNAME"})," can be freely chosen. This is the value passed to the openstack CLI with ",(0,o.jsx)(n.code,{children:"--os-cloud"})," or exported to your environment in ",(0,o.jsx)(n.code,{children:"OS_CLOUD"}),". The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample ",(0,o.jsx)(n.code,{children:"clouds.yaml"})," file that works (but lacks the password)."]}),"\n",(0,o.jsxs)(n.p,{children:["Protect your ",(0,o.jsx)(n.code,{children:"secure.yaml"})," from being read by others: ",(0,o.jsx)(n.code,{children:"chmod 0600 ~/.config/openstack/secure.yaml"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["If you are using application credentials instead of username, password to authenticate, you don't need to specify ",(0,o.jsx)(n.code,{children:"project_id"})," nor project's nor user's domain names in ",(0,o.jsx)(n.code,{children:"clouds.yaml"}),". Just (in ",(0,o.jsx)(n.code,{children:"secure.yaml"}),"):"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'clouds:\n CLOUDNAME:\n auth_type: v3applicationcredential\n auth:\n application_credential_id: APPCRED_ID\n application_credential_secret: "APPCRED_SECRET"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Configure this to be your default cloud:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"export OS_CLOUD=CLOUDNAME\n"})}),"\n",(0,o.jsxs)(n.p,{children:["You might consider adding this to your ",(0,o.jsx)(n.code,{children:"~/.bashrc"})," for convenience. Being at it, you might want to add ",(0,o.jsx)(n.code,{children:"export CLIFF_FIT_WIDTH=1"})," there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste)."]}),"\n",(0,o.jsx)(n.p,{children:"Verify that your openstack CLI works:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"openstack catalog list\nopenstack server list\n"})}),"\n",(0,o.jsx)(n.p,{children:"You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases."}),"\n",(0,o.jsx)(n.h3,{id:"custom-ca",children:"Custom CA"}),"\n",(0,o.jsxs)(n.p,{children:["If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in ",(0,o.jsx)(n.code,{children:"/etc/ssl/certs/ca-certificates.crt"}),". You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the ",(0,o.jsx)(n.code,{children:"debian"})," user."]}),"\n",(0,o.jsxs)(n.p,{children:["Add it to your ",(0,o.jsx)(n.code,{children:"clouds.yaml"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"clouds:\n CLOUDNAME:\n cacert: /PATH/TO/CACERT.CRT\n [...]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If you want to allow ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"export OS_CACERT=/PATH/TO/CACERT.CRT\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Consider adding this to your ",(0,o.jsx)(n.code,{children:"~/.bashrc"})," as well."]}),"\n",(0,o.jsxs)(n.h2,{id:"your-first-api_monitorsh-iteration",children:["Your first ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," iteration"]}),"\n",(0,o.jsx)(n.p,{children:"Checkout openstack-health-monitor:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install git bc jq netcat-traditional tmux zstd\ngit clone https://github.com/SovereignCloudStack/openstack-health-monitor\ncd openstack-health-monitor\n"})}),"\n",(0,o.jsxs)(n.p,{children:["You may want to start a ",(0,o.jsx)(n.code,{children:"tmux"})," (or ",(0,o.jsx)(n.code,{children:"screen"}),") session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect."]}),"\n",(0,o.jsxs)(n.p,{children:["The script ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"})," file."]}),"\n",(0,o.jsxs)(n.p,{children:["It is good practice to use ",(0,o.jsx)(n.code,{children:"tmux"}),". This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to ",(0,o.jsx)(n.code,{children:"screen"})," over ",(0,o.jsx)(n.code,{children:"tmux"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'export IMG="Debian 12"\nexport JHIMG="Debian 12"\n./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Leave out the ",(0,o.jsx)(n.code,{children:"-LL"})," if you don't have a working loadbalancer service or replace ",(0,o.jsx)(n.code,{children:"-LL"})," with ",(0,o.jsx)(n.code,{children:"-LO"})," if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources)."]}),"\n",(0,o.jsxs)(n.p,{children:["Feel free to study the meaning of all the command line parameters by looking at the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/README.md",children:"README.md"}),". (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)"]}),"\n",(0,o.jsxs)(n.p,{children:["This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs ",(0,o.jsx)(n.code,{children:"DOWN"}),", ",(0,o.jsx)(n.code,{children:"BUILD"}),", ",(0,o.jsx)(n.code,{children:"creating"})," are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual ",(0,o.jsx)(n.code,{children:"openstack RESOURCE list"})," and ",(0,o.jsx)(n.code,{children:"openstack RESOURCE show NAME"})," and ",(0,o.jsx)(n.code,{children:"RESOURCE"})," being something like ",(0,o.jsx)(n.code,{children:"router"}),", ",(0,o.jsx)(n.code,{children:"network"}),", ",(0,o.jsx)(n.code,{children:"subnet"}),", ",(0,o.jsx)(n.code,{children:"port"}),", ",(0,o.jsx)(n.code,{children:"volume"}),", ",(0,o.jsx)(n.code,{children:"server"}),", ",(0,o.jsx)(n.code,{children:"floating ip"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer pool"}),", ",(0,o.jsx)(n.code,{children:"loadbalancer listener"}),", ",(0,o.jsx)(n.code,{children:"security group"}),", ",(0,o.jsx)(n.code,{children:"keypair"}),", ",(0,o.jsx)(n.code,{children:"image"}),", ...)"]}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," uses and ",(0,o.jsx)(n.code,{children:"APIMonitor_TIMESTAMP"})," prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong.\n",(0,o.jsx)(n.code,{children:"TIMESTAMP"})," is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time)."]}),"\n",(0,o.jsxs)(n.p,{children:["This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least ",(0,o.jsx)(n.code,{children:"-N 2"})," to test the ability of the router to route traffic between networks. So expect ",(0,o.jsx)(n.code,{children:"-n 6"})," to become ",(0,o.jsx)(n.code,{children:"-N 2 -n 6"})," for a very small single-AZ cloud or ",(0,o.jsx)(n.code,{children:"-n 12"})," for a large 3 AZ cloud region. So, re-run the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," with the target sizing."]}),"\n",(0,o.jsx)(n.h3,{id:"resource-impact-and-charging",children:"Resource impact and charging"}),"\n",(0,o.jsxs)(n.p,{children:["Note that ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," uses small flavors (",(0,o.jsx)(n.code,{children:"SCS-1V-2"})," for the N jump hosts and ",(0,o.jsx)(n.code,{children:"SCS-1L-1"})," for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors."]}),"\n",(0,o.jsxs)(n.p,{children:["If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," in a loop (which you will) with say 10 VMs (e.g. ",(0,o.jsx)(n.code,{children:"-N 2 -n 8"}),") in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference."]}),"\n",(0,o.jsxs)(n.p,{children:["Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of ",(0,o.jsx)(n.code,{children:"openstack volume list"}),", ",(0,o.jsx)(n.code,{children:"openstack volume show BROKEN_VOLUME"}),", ",(0,o.jsx)(n.code,{children:"openstack loadbalancer list"}),", ",(0,o.jsx)(n.code,{children:"openstack loadbalancer show BROKEN_LB"}),".)"]}),"\n",(0,o.jsxs)(n.p,{children:["Using ",(0,o.jsx)(n.code,{children:"-w -1"})," makes ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," wait for interactive input whenever an error occurs; this can be convenient for debugging."]}),"\n",(0,o.jsx)(n.p,{children:"Once you have single iterations working nicely, we can proceed."}),"\n",(0,o.jsx)(n.h2,{id:"automating-startup-and-cleanup",children:"Automating startup and cleanup"}),"\n",(0,o.jsxs)(n.p,{children:["Typically, we run ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'#!/bin/bash\n# run_CLOUDNAME.sh\n# Do some global settings\nexport IMG="Debian 12"\nexport JHIMG="Debian 12"\n#export OS_CACERT=/home/debian/ca-certificates.pem\n# Additional settings to override flavors or to\n# configure email addresses for sending alarms can be set here\n\n# Does openstack CLI work?\nopenstack server list >/dev/null || exit 1\n# Upload log files to this swift container (which you need to create)\n#export SWIFTCONTAINER=OS-HM-Logfiles\n\n# CLEANUP\necho "Finding resources from previous runs to clean up ..."\n# Find Floating IPs\nFIPLIST=""\nFIPS=$(openstack floating ip list -f value -c ID)\nfor fip in $FIPS; do\n FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")\n if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_\n"; fi\ndone\nFIPLIST=$(echo "$FIPLIST" | grep -v \'^$\' | sort -u)\n# Cleanup previous interrupted runs\nSERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nKEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nVOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nNETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nLOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)\nSECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)\necho CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS\nfor ENV in $FIPLIST; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV\n echo "******************************"\ndone\nTOCLEAN=$(echo "$SERVERS\n$KEYPAIR\n$VOLUMES\n$NETWORK\n$LOADBAL\n$ROUTERS\n$SECGRPS\n" | grep -v \'^$\' | sort -u)\nfor ENV in $TOCLEAN; do\n echo "******************************"\n echo "CLEAN $ENV"\n bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV\n echo "******************************"\ndone\n\n# Now run the monitor\n#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"\nexec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Compared to the previous run, we have explicitly set two networks here ",(0,o.jsx)(n.code,{children:"-N 2"})," and rely on the iterations being passed in as command line arguments. Add parameter ",(0,o.jsx)(n.code,{children:"-t"})," if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (",(0,o.jsx)(n.code,{children:"-LO"}),") in this example rather than the amphora based one (",(0,o.jsx)(n.code,{children:"-LL"}),")."]}),"\n",(0,o.jsxs)(n.p,{children:["You may use one of the existing ",(0,o.jsx)(n.code,{children:"run_XXXX.sh"})," scripts as example. Beware: eMail alerting with ",(0,o.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESS"})," and ",(0,o.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESS"})," (and limiting with ",(0,o.jsx)(n.code,{children:"-a"})," and ",(0,o.jsx)(n.code,{children:"-R"})," ) and reporting data to telegraf (option ",(0,o.jsx)(n.code,{children:"-S"}),") may be present in the samples. Make this script executable (",(0,o.jsx)(n.code,{children:"chmod +x run_CLOUDNAME.sh"}),")."]}),"\n",(0,o.jsxs)(n.p,{children:["We wrap a loop around this in ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'#!/bin/bash\n# run_in_loop.sh\nrm stop-os-hm 2>/dev/null\nwhile true; do\n ./run_CLOUDNAME.sh -i 200\n if test -e stop-os-hm; then break; fi\n echo -n "Hit ^C to abort ..."\n sleep 15; echo\ndone\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Also make this executable (",(0,o.jsx)(n.code,{children:"chmod +x run_in_loop.sh"}),").\nTo run this automatically in a tmux window whenever the system starts, we follow the steps in the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/startup/README.md",children:"startup README.md"})]}),"\n",(0,o.jsxs)(n.p,{children:["Change ",(0,o.jsx)(n.code,{children:"OS_CLOUD"})," in ",(0,o.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"}),". (If you need to set ",(0,o.jsx)(n.code,{children:"OS_CACERT"}),", also add it in this file and pass it into the windows.)"]}),"\n",(0,o.jsx)(n.p,{children:"Activate everything:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"mkdir -p ~/.config/systemd/user/\ncp -p startup/apimon.service ~/.config/systemd/user/\nsystemctl --user enable apimon\nsystemctl --user start apimon\nsudo loginctl enable-linger debian\ntmux attach oshealthmon\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This assumes that you are using the user ",(0,o.jsx)(n.code,{children:"debian"})," for this monitoring and have checked out the repository at ",(0,o.jsx)(n.code,{children:"~/openstack-health-monitor/"}),". Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)"]}),"\n",(0,o.jsx)(n.h3,{id:"changing-parameters-and-restarting",children:"Changing parameters and restarting"}),"\n",(0,o.jsxs)(n.p,{children:["If you want to change the parameters passed to ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),", you best do this by editing ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),", potentially after testing it with one iteration before."]}),"\n",(0,o.jsxs)(n.p,{children:["To make the change effective, you can wait until the current 200 iterations are completed and the ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"})," calls ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," again. You can also hit ",(0,o.jsx)(n.code,{children:"^C"})," in the tmux window that has",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ",(0,o.jsx)(n.code,{children:"^C"})," during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ",(0,o.jsx)(n.code,{children:"^C"})," twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ",(0,o.jsx)(n.code,{children:"./run_in_loop.sh"})," again."]}),"\n",(0,o.jsxs)(n.p,{children:["You can also issue the ",(0,o.jsx)(n.code,{children:"systemctl --user stop apimon"})," command; it will basically do the same thing: Send ",(0,o.jsx)(n.code,{children:"^C"})," and then wait for everything to be completed and tear down the tmux session.\nAfter waiting for that to complete, you can start it again with ",(0,o.jsx)(n.code,{children:"systemctl --user start apimon"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"multiple-instances",children:"Multiple instances"}),"\n",(0,o.jsxs)(n.p,{children:["You can run multiple instances of ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," on the same driver VM. In this case, you should rename ",(0,o.jsx)(n.code,{children:"run_in_loop.sh"})," to e.g. ",(0,o.jsx)(n.code,{children:"run_in_loop_CLOUDNAME1.sh"})," and call ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME1.sh"})," from there. Don't forget to adjust ",(0,o.jsx)(n.code,{children:"startup/run-apimon-in-tmux.sh"})," and ",(0,o.jsx)(n.code,{children:"startup/kill-apimon-in-tmux.sh"})," to start more windows."]}),"\n",(0,o.jsxs)(n.p,{children:["It is not recommended to run multiple instances against the same OpenStack project however. While the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations."]}),"\n",(0,o.jsx)(n.h2,{id:"alarming-and-logs",children:"Alarming and Logs"}),"\n",(0,o.jsx)(n.h3,{id:"email",children:"eMail"}),"\n",(0,o.jsxs)(n.p,{children:["If wanted, the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the ",(0,o.jsx)(n.code,{children:"-a N"})," and ",(0,o.jsx)(n.code,{children:"-R"})," options. In order to enable sending emails from the driver VM, it needs to have ",(0,o.jsx)(n.code,{children:"postfix"})," (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly."]}),"\n",(0,o.jsxs)(n.p,{children:["Once you have configured ",(0,o.jsx)(n.code,{children:"postfix"}),", you can enable eMail notifications using the option ",(0,o.jsx)(n.code,{children:"-e"}),". Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ",(0,o.jsx)(n.code,{children:"ALARM_EMAIL_ADDRESSES"})," and ",(0,o.jsx)(n.code,{children:"NOTE_EMAIL_ADDRESSES"})," environment variables to ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),", e.g. by setting it in the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"log-files",children:"Log files"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"api_monitor.sh"})," writes a log file with the name ",(0,o.jsx)(n.code,{children:"APIMonitor_TIMESTAMP.log"}),". It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (",(0,o.jsx)(n.code,{children:"TIMESTAMP"})," is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)"]}),"\n",(0,o.jsxs)(n.p,{children:["Note that ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties."]}),"\n",(0,o.jsxs)(n.p,{children:["The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable ",(0,o.jsx)(n.code,{children:"SWIFTCONTAINER"})," has been set (in ",(0,o.jsx)(n.code,{children:"run_COULDNAME.sh"}),") when starting ",(0,o.jsx)(n.code,{children:"api_monitor.sh"}),". the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: ",(0,o.jsx)(n.code,{children:"export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER"})]}),"\n",(0,o.jsxs)(n.p,{children:["After the 200 iterations, a ",(0,o.jsx)(n.code,{children:".psv"})," file (pipe-separated values) is created ",(0,o.jsx)(n.code,{children:"Stats.STARTTIME-ENDTIME.psv"})," (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured)."]}),"\n",(0,o.jsx)(n.h2,{id:"data-collection-and-dashboard",children:"Data collection and dashboard"}),"\n",(0,o.jsxs)(n.p,{children:["See ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md",children:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md"})]}),"\n",(0,o.jsx)(n.h3,{id:"telegraf",children:"telegraf"}),"\n",(0,o.jsx)(n.p,{children:"To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:'sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key\necho "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list\nsudo apt update\nsudo apt -y install telegraf\n'})}),"\n",(0,o.jsxs)(n.p,{children:["In the config file ",(0,o.jsx)(n.code,{children:"/etc/telegraf/telegraf.conf"}),", we enable"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'[[inputs.influxdb_listener]]\n service_address = ":8186"\n\n[[outputs.influxdb]]\n urls = ["http://127.0.0.1:8086"]\n'})}),"\n",(0,o.jsxs)(n.p,{children:["and restart the service (",(0,o.jsx)(n.code,{children:"sudo systemctl restart telegraf"}),").\nEnable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable telegraf"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"influxdb",children:"influxdb"}),"\n",(0,o.jsx)(n.p,{children:"We proceed to influxdb:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo apt-get install influxdb\n"})}),"\n",(0,o.jsxs)(n.p,{children:["In the configuration file ",(0,o.jsx)(n.code,{children:"/etc/influxdb/influxdb.conf"}),", ensure that the http interface on port 8086 is enabled."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'[http]\n enabled = true\n bind-address = ":8086"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Restart influxdb as needed with ",(0,o.jsx)(n.code,{children:"sudo systemctl restart influxdb"}),".\nAlso enable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable influxdb"}),"."]}),"\n",(0,o.jsxs)(n.h3,{id:"add--s-cloudname-to-your-run_cloudnamesh-script",children:["Add ",(0,o.jsx)(n.code,{children:"-S CLOUDNAME"})," to your ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script"]}),"\n",(0,o.jsxs)(n.p,{children:["You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter ",(0,o.jsx)(n.code,{children:"-S CLOUDNAME"})," to the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," call in ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"}),". Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete)."]}),"\n",(0,o.jsx)(n.h3,{id:"grafana",children:"grafana"}),"\n",(0,o.jsx)(n.h4,{id:"basic-config",children:"Basic config"}),"\n",(0,o.jsxs)(n.p,{children:["Finally grafana: We (still as root) follow ",(0,o.jsx)(n.a,{href:"https://www.server-world.info/en/note?os=Debian_12&p=grafana",children:"https://www.server-world.info/en/note?os=Debian_12&p=grafana"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:'sudo wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key\necho "deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list\nsudo apt update\nsudo apt -y install grafana\n'})}),"\n",(0,o.jsxs)(n.p,{children:["The config file ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," needs some adjustments:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Set the hostname in ",(0,o.jsx)(n.code,{children:"[server]"})," section: ",(0,o.jsx)(n.code,{children:"domain = health.YOURCLOUD.sovereignit.cloud"}),". Set the ",(0,o.jsx)(n.code,{children:"protocol = https"})," if not enabled by default.\nYou can use a hostname of your liking, but we will need to create TLS certificates for this host. So we should have control over DNS TXT records for this domain if we want to use Let's Encrypt with DNSAUTH. The ",(0,o.jsx)(n.code,{children:"sovereignit.cloud"})," domain is controlled by the SCS project team and has been used for a number of health mon instances.\nIn this same section, set ",(0,o.jsx)(n.code,{children:"cert_file = /etc/grafana/health-fullchain.pem"})," and ",(0,o.jsx)(n.code,{children:"cert_key = /etc/grafana/health-key.pem"}),". Ensure that both files are readable by ",(0,o.jsx)(n.code,{children:"root:grafana"})," and that the key file is ",(0,o.jsx)(n.em,{children:"not"})," world-readable."]}),"\n",(0,o.jsxs)(n.li,{children:["Configure the admin access. In section ",(0,o.jsx)(n.code,{children:"[security]"}),", set the ",(0,o.jsx)(n.code,{children:"admin_user = admin"})," and ",(0,o.jsx)(n.code,{children:"admin_password = SOME_SECRET_PASS"})," which you keep private."]}),"\n",(0,o.jsxs)(n.li,{children:["Allow local data sources (same section): ",(0,o.jsx)(n.code,{children:"data_source_proxy_whitelist = localhost:8088 localhost:8086"})]}),"\n",(0,o.jsxs)(n.li,{children:["Let's disallow user signup (in section ",(0,o.jsx)(n.code,{children:"[users]"}),"): ",(0,o.jsx)(n.code,{children:"allow_sign_up = false"})," and ",(0,o.jsx)(n.code,{children:"allow_org_create = false"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["We do the OIDC connection with ",(0,o.jsx)(n.code,{children:"[auth.github]"})," later."]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["We can now restart the service: ",(0,o.jsx)(n.code,{children:"sudo systemctl restart grafana-server"}),".\nBeing at it, also enable it on system startup: ",(0,o.jsx)(n.code,{children:"sudo systemctl enable grafana-server"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["You should now be able to access your dashboard on ",(0,o.jsx)(n.code,{children:"https://health.YOURCLOUD.sovereignit.de:3000"})," and log in via the configured username ",(0,o.jsx)(n.code,{children:"admin"})," and your ",(0,o.jsx)(n.code,{children:"SOME_SECRET_PASS"})," password."]}),"\n",(0,o.jsx)(n.h4,{id:"enable-influx-database-in-grafana",children:"Enable influx database in grafana"}),"\n",(0,o.jsxs)(n.p,{children:["In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to ",(0,o.jsx)(n.code,{children:"http://localhost:8086"})," (despite this being the suggestion). Set the database name to ",(0,o.jsx)(n.code,{children:"telegraf"}),". Save&test should succeed."]}),"\n",(0,o.jsx)(n.h4,{id:"importing-the-dashboard",children:"Importing the dashboard"}),"\n",(0,o.jsxs)(n.p,{children:["Go to Home, Dashboards, New, Import.\nUpload the dashboard ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard.json",children:".json file"})," from the repository, user the ",(0,o.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/openstack-health-dashboard-10.json",children:"Grafana-10 variant"})," if you use Grafana 10 or newer."]}),"\n",(0,o.jsx)(n.p,{children:"In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.)\nSave."}),"\n",(0,o.jsx)(n.p,{children:"Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable)."}),"\n",(0,o.jsx)(n.h4,{id:"no-data-displayed",children:"No data displayed?"}),"\n",(0,o.jsx)(n.p,{children:'Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.'}),"\n",(0,o.jsx)(n.p,{children:"One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved."}),"\n",(0,o.jsx)(n.h4,{id:"dashboard-features",children:"Dashboard features"}),"\n",(0,o.jsx)(n.p,{children:"Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended."}),"\n",(0,o.jsx)(n.p,{children:"The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously."}),"\n",(0,o.jsx)(n.p,{children:"You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term."}),"\n",(0,o.jsx)(n.h4,{id:"github-oidc-integration",children:"github OIDC integration"}),"\n",(0,o.jsxs)(n.p,{children:["The SCS providers do allow all github users that belong to the SovereignCloudStack organization to get Viewer access to the dashboards by adding a ",(0,o.jsx)(n.code,{children:"client_id"})," and ",(0,o.jsx)(n.code,{children:"client_secret"})," in the ",(0,o.jsx)(n.code,{children:"[github.auth]"})," section that you request from the SCS github admins (github's oauth auth). This allows to exchange experience and to get a feeling for the achievable stability. (Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)"]}),"\n",(0,o.jsx)(n.h2,{id:"alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy",children:"Alternative approach to install and configure the dashboard behind a reverse proxy"}),"\n",(0,o.jsxs)(n.p,{children:["Install influxdb via apt: ",(0,o.jsx)(n.a,{href:"https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss",children:"https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss"}),"\nInstall telegraf (same apt repo as influxdb): ",(0,o.jsx)(n.code,{children:"sudo apt update && sudo apt install telegraf"}),"\nInstall grafana: ",(0,o.jsx)(n.a,{href:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository",children:"https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository"})]}),"\n",(0,o.jsx)(n.p,{children:"Prepare configuration by using the config files from the repository as an alternative to doing the changes manually (as described above):"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo cp dashboard/telegraf.conf /etc/telegraf && sudo chown root:root /etc/telegraf/telegraf.conf && sudo chmod 0644 /etc/telegraf/telegraf.conf\nsudo cp dashboard/config.toml /etc/influxdb && sudo chown root:influxdb /etc/influxdb/config.toml && sudo chmod 0640 /etc/influxdb/config.toml\nsudo cp dashboard/grafana.ini /etc/grafana && sudo chown root:grafana /etc/grafana/grafana.ini && sudo chmod 0640 /etc/grafana/grafana.ini\n"})}),"\n",(0,o.jsx)(n.p,{children:"These config files should work as long as the versions of telegraf, influxdb and grafana don't evolve too far from the ones used in the repository. (Otherwise refer to above instructions how to tweak the default config files.)"}),"\n",(0,o.jsxs)(n.p,{children:["Changes to ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," as we do tls termination at the reverse proxy:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["set ",(0,o.jsx)(n.code,{children:"protocol = http"})]}),"\n",(0,o.jsxs)(n.li,{children:["comment out ",(0,o.jsx)(n.code,{children:"domain"})," option (? FIXME) or set it to the hostname"]}),"\n",(0,o.jsxs)(n.li,{children:["comment out ",(0,o.jsx)(n.code,{children:"cert_*"})," options"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Also change the admin password in ",(0,o.jsx)(n.code,{children:"grafana.ini"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Changes to ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," if github auth should not be used yet:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["comment out whole ",(0,o.jsx)(n.code,{children:"[auth.github]"})," section for now (can be enabled later)"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Restart services: ",(0,o.jsx)(n.code,{children:"sudo systemctl restart telegraf && sudo systemctl restart influxdb && sudo systemctl restart grafana-server"})]}),"\n",(0,o.jsx)(n.p,{children:"Configuration in grafana web gui:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Login to grafana ",(0,o.jsx)(n.code,{children:"http(s)://<domain>:3000"})," with user admin and default password from ",(0,o.jsx)(n.code,{children:"/etc/grafana/grafana.ini"})," and change password."]}),"\n",(0,o.jsxs)(n.li,{children:["Create influxdb datasource with url ",(0,o.jsx)(n.code,{children:"http://localhost:8086"})," and database name ",(0,o.jsx)(n.code,{children:"telegraf"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["Finally import dashboard ",(0,o.jsx)(n.code,{children:"dashboard/openstack-health-dashboard.json"})," to grafana."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"TODO:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Reverse proxy (aka ingress) with Let's Encrypt cert"}),"\n",(0,o.jsx)(n.li,{children:"Github auth as described above"}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"maintenance",children:"Maintenance"}),"\n",(0,o.jsx)(n.p,{children:"The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained."}),"\n",(0,o.jsx)(n.h3,{id:"unattended-upgrades",children:"Unattended upgrades"}),"\n",(0,o.jsxs)(n.p,{children:["It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See ",(0,o.jsx)(n.a,{href:"https://wiki.debian.org/UnattendedUpgrades",children:"https://wiki.debian.org/UnattendedUpgrades"}),". If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and grafana (port 3000)."]}),"\n",(0,o.jsx)(n.h3,{id:"updating-openstack-health-monitor",children:"Updating openstack-health-monitor"}),"\n",(0,o.jsxs)(n.p,{children:["You can just do a ",(0,o.jsx)(n.code,{children:"git update"})," in the ",(0,o.jsx)(n.code,{children:"openstack-health-monitor"})," directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ",(0,o.jsx)(n.code,{children:"^C"}),", see above in the restart section."]}),"\n",(0,o.jsx)(n.h3,{id:"backup",children:"Backup"}),"\n",(0,o.jsxs)(n.p,{children:["The system holds two things that you might consider valuable for long-term storage:\n(1) The log files. These are compressed and uploaded to object storage if you enable the ",(0,o.jsx)(n.code,{children:"SWIFTCONTAINER"})," setting, which probably means that these do not need any additional backing up then.\n(2) The influx time series data. Back up the data in ",(0,o.jsx)(n.code,{children:"/var/lib/influxdb"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, ",(0,o.jsx)(n.code,{children:"clouds.yaml"}),", etc. Be careful not to expose sensitive data by granting too generous access to your backed up files."]}),"\n",(0,o.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsx)(n.h3,{id:"debugging-issues",children:"Debugging issues"}),"\n",(0,o.jsx)(n.p,{children:"In case there is trouble with your cloud, the normal course of action to analyze is as follows:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Look at the dashboard (see above)"}),"\n",(0,o.jsxs)(n.li,{children:["Connect to the driver VM and attach to the tmux session and look at the console output of ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})]}),"\n",(0,o.jsx)(n.li,{children:"Analyze the logfile (locally on the driver VM or grab it from the object storage)"}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"analyzing-failures",children:"Analyzing failures"}),"\n",(0,o.jsxs)(n.p,{children:["When VM instances are created successfully, but then end up in ",(0,o.jsx)(n.code,{children:"ERROR"})," state, the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," does an explicit ",(0,o.jsx)(n.code,{children:"openstack server show"}),", so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files."]}),"\n",(0,o.jsxs)(n.p,{children:["Sometimes the VMs end up being ",(0,o.jsx)(n.code,{children:"ACTIVE"})," as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail."]}),"\n",(0,o.jsxs)(n.p,{children:["To gather more details, you can look at the console output ",(0,o.jsx)(n.code,{children:"openstack console log show VM"})," (where ",(0,o.jsx)(n.code,{children:"VM"})," is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ",(0,o.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_JH.pem debian@FIP"}),", whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ",(0,o.jsx)(n.code,{children:"ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP"}),". Replace ",(0,o.jsx)(n.code,{children:"XXXXX"})," with the number in your current APIMonitor prefix, ",(0,o.jsx)(n.code,{children:"FIP"})," with the floating IP address of the responsible JumpHost and ",(0,o.jsx)(n.code,{children:"debian"})," with the user name used by the images you boot. Use ",(0,o.jsx)(n.code,{children:"223"})," to connect to the second VM in the network, ",(0,o.jsx)(n.code,{children:"224"})," the third etc."]}),"\n",(0,o.jsxs)(n.p,{children:["When logged in, look at ",(0,o.jsx)(n.code,{children:"/var/log/cloud-init-output.log"})," and ",(0,o.jsx)(n.code,{children:"/var/log/cloud-init.log"}),". You can find the metadata in ",(0,o.jsx)(n.code,{children:"/var/lib/cloud/instance/"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["You will not have much time to look around -- the still running ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," script does continue and clean things up again. So you might want to suspend it with ",(0,o.jsx)(n.code,{children:"^Z"})," (and continue it later with ",(0,o.jsx)(n.code,{children:"fg"}),"). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the ",(0,o.jsx)(n.code,{children:"run_CLOUDNAME.sh"})," script as it would do cleanup against the running instance, but rather copy the ",(0,o.jsx)(n.code,{children:"api_monitor.sh"})," command line from the bottom (without the ",(0,o.jsx)(n.code,{children:"exec"}),"), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach ",(0,o.jsx)(n.code,{children:"-w -1"})," to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work."]}),"\n",(0,o.jsx)(n.h3,{id:"cleaning-things-up",children:"Cleaning things up"}),"\n",(0,o.jsx)(n.p,{children:"If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard)."}),"\n",(0,o.jsx)(n.p,{children:"There are a few things that may need support from a cloud admin:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Volumes may end up permanently in a ",(0,o.jsx)(n.code,{children:"deleting"})," or ",(0,o.jsx)(n.code,{children:"reserved"})," state or may be ",(0,o.jsx)(n.code,{children:"in-use"}),", attached to a VM that has long gone. The admin needs to set the state to ",(0,o.jsx)(n.code,{children:"error"})," and then delete them."]}),"\n",(0,o.jsxs)(n.li,{children:["Loadbalancers may end up in a ",(0,o.jsx)(n.code,{children:"PENDING_XXX"})," state (",(0,o.jsx)(n.code,{children:"XXX"})," being ",(0,o.jsx)(n.code,{children:"CREATE"}),", ",(0,o.jsx)(n.code,{children:"UPDATE"})," or ",(0,o.jsx)(n.code,{children:"DELETE"}),") without ever changing. This also needs the cloud admin to set the status to ",(0,o.jsx)(n.code,{children:"ERROR"}),", so it can be cleaned up. amphorae are more prone to this than ovn LBs."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var o=t(96540);const s={},i=o.createContext(s);function a(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b262b314.06be2c4f.js b/assets/js/b262b314.06be2c4f.js new file mode 100644 index 0000000000..01945065ab --- /dev/null +++ b/assets/js/b262b314.06be2c4f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3681],{65329:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var t=i(74848),s=i(28453);const o={title:"Requirements for testing cluster-stacks",type:"Decision Record",status:"Draft",track:"KaaS"},r=void 0,a={id:"scs-0216-v1-requirements-for-testing-cluster-stacks",title:"Requirements for testing cluster-stacks",description:"Introduction",source:"@site/standards/scs-0216-v1-requirements-for-testing-cluster-stacks.md",sourceDirName:".",slug:"/scs-0216-v1-requirements-for-testing-cluster-stacks",permalink:"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Requirements for testing cluster-stacks",type:"Decision Record",status:"Draft",track:"KaaS"},sidebar:"standards",previous:{title:"scs-0216: Requirements for testing cluster-stacks",permalink:"/standards/kaas/scs-0216"},next:{title:"scs-0217: Kubernetes cluster baseline security",permalink:"/standards/kaas/scs-0217"}},l={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Required Features",id:"required-features",level:2},{value:"Pros and Cons of Different Approaches",id:"pros-and-cons-of-different-approaches",level:2},{value:"IaaS Provider (OpenStack, Hetzner, AWS)",id:"iaas-provider-openstack-hetzner-aws",level:3},{value:"Pros",id:"pros",level:4},{value:"Cons",id:"cons",level:4},{value:"Local Environment (Docker, Kubevirt)",id:"local-environment-docker-kubevirt",level:3},{value:"Pros",id:"pros-1",level:4},{value:"Cons",id:"cons-1",level:4},{value:"Beyond Docker: Virtual Machine based Approach",id:"beyond-docker-virtual-machine-based-approach",level:2},{value:"Virtual Machine Based Approach",id:"virtual-machine-based-approach",level:3},{value:"Pros",id:"pros-2",level:4},{value:"Cons",id:"cons-2",level:4},{value:"Proposed Path Forward",id:"proposed-path-forward",level:2},{value:"Conclusion",id:"conclusion",level:2}];function d(e){const n={h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsx)(n.p,{children:"In this proposal, we discuss the necessity and design considerations of a lightweight solution for testing cluster-stacks. The purpose is to address the challenges associated with testing on an Infrastructure as a Service (IaaS) provider and the limitations of using Docker as the primary containerization tool for testing. This proposal will elaborate on why we need to test in a local environment, specifically a laptop, and the benefits and drawbacks associated with it. We aim to make an informed decision for testing cluster stacks to cater to both the organizational and technical perspectives of our stakeholders."}),"\n",(0,t.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,t.jsx)(n.p,{children:"From an organization's point of view, it is crucial to lower the entry barrier for testing. This action will make it possible for anyone, including external contributors, to easily participate in the testing process without needing an account with the IaaS provider. It is also necessary to overcome the hurdles associated with maintaining a balance in the provider account and managing sponsorships to fund the testing."}),"\n",(0,t.jsx)(n.p,{children:"From a technical standpoint, there are multiple reasons to favor a local environment for testing. Among them is the ability to test without internet, finish tests in a shorter timeframe, and incur no cost. The provider independence of Cluster Stacks makes it nonsensical to test with a specific provider due to the varied behaviors of different providers. There are also challenges in monitoring and debugging tests run on IaaS providers and dealing with their downtime and limitations on concurrent testing."}),"\n",(0,t.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Lightweight Solution"}),"\nThe testing solution should be lightweight and easy to use in a local environment, such as a laptop. This lightweight solution should minimize dependencies and resource usage while maximizing speed and efficiency of the tests. It should be capable of handling the cluster-stack testing requirements without necessitating a bulky or resource-intensive setup."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Independence from Specific Providers"}),"\nThe solution should be generalized and not bound to any specific provider. This consideration ensures that the solution can be applied to any provider, guaranteeing its versatility and broad applicability."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Offline Testing"}),"\nThe testing solution should support testing without internet connection, which will enable more robust and flexible testing scenarios. It should be possible to run the tests even in cases of limited or disrupted internet access."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Fast Execution Time"}),"\nThe tests should execute within a reasonably short amount of time. The solution must be optimized to ensure quick testing cycles, which can help increase productivity and shorten development cycles."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"No-Cost Solution"}),"\nThe solution should not impose any additional costs on the organization or individual testers. This characteristic is crucial to enable widespread adoption of the testing process and to lower the entry barrier for contributors."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Easy Monitoring and Debugging"}),"\nThe solution should provide easy monitoring and debugging capabilities. It should allow developers to quickly identify, diagnose, and fix issues that arise during testing, without requiring access to any external logs or monitoring tools."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Concurrent Testing"}),"\nThe solution should support the ability to run concurrent tests without causing any disruption or downtime. This ability can improve the efficiency and speed of the testing process."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"required-features",children:"Required Features"}),"\n",(0,t.jsx)(n.p,{children:"The proposed solution should meet the following feature requirements:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Local Environment: The solution should support a local testing environment that allows developers to test cluster stacks on their local machines, reducing dependencies on external providers."}),"\n",(0,t.jsx)(n.li,{children:"Compatibility: The solution should be compatible with various operating systems and platforms, ensuring its usability across diverse environments."}),"\n",(0,t.jsx)(n.li,{children:"Performance: The solution should offer high-performance testing capabilities, allowing fast execution of tests."}),"\n",(0,t.jsx)(n.li,{children:"Offline Support: The solution should allow testing in offline mode, ensuring tests can be performed even without an internet connection."}),"\n",(0,t.jsx)(n.li,{children:"Concurrency: The solution should support running multiple tests concurrently without causing disruptions or conflicts."}),"\n",(0,t.jsx)(n.li,{children:"Monitoring & Debugging: The solution should provide easy-to-use tools for monitoring test progress and debugging issues."}),"\n",(0,t.jsx)(n.li,{children:"Cost-effectiveness: The solution should not require any financial investment from the testers or the organization, promoting broad accessibility and usage."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"pros-and-cons-of-different-approaches",children:"Pros and Cons of Different Approaches"}),"\n",(0,t.jsx)(n.p,{children:"Two potential approaches for testing cluster stacks are the use of an IaaS provider and the use of a local environment. Here we discuss the pros and cons of these two approaches."}),"\n",(0,t.jsx)(n.h3,{id:"iaas-provider-openstack-hetzner-aws",children:"IaaS Provider (OpenStack, Hetzner, AWS)"}),"\n",(0,t.jsx)(n.h4,{id:"pros",children:"Pros"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Comprehensive testing environment with advanced capabilities."}),"\n",(0,t.jsx)(n.li,{children:"Possibility to mimic real-world production environments closely."}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"cons",children:"Cons"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Requires signing up and account management, which can be a barrier for some testers."}),"\n",(0,t.jsx)(n.li,{children:"Requires maintaining a balance in the provider account, which can pose financial burdens."}),"\n",(0,t.jsx)(n.li,{children:"Internet dependency for testing."}),"\n",(0,t.jsx)(n.li,{children:"Potential for prolonged testing time due to various dependencies."}),"\n",(0,t.jsx)(n.li,{children:"Challenges with monitoring and debugging."}),"\n",(0,t.jsx)(n.li,{children:"Potential downtime and difficulty in running concurrent tests."}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"local-environment-docker-kubevirt",children:"Local Environment (Docker, Kubevirt)"}),"\n",(0,t.jsx)(n.h4,{id:"pros-1",children:"Pros"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Faster test execution with no downtime."}),"\n",(0,t.jsx)(n.li,{children:"Ability to test without internet."}),"\n",(0,t.jsx)(n.li,{children:"Independent of any provider knowledge."}),"\n",(0,t.jsx)(n.li,{children:"Cost-free testing."}),"\n",(0,t.jsx)(n.li,{children:"Easier integration into CI/CD."}),"\n",(0,t.jsx)(n.li,{children:"Simplified monitoring and debugging."}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"cons-1",children:"Cons"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Limited systemd support and containerd support for kubeadm in Docker."}),"\n",(0,t.jsx)(n.li,{children:"Inability to mimic the exact real-world production environments."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"beyond-docker-virtual-machine-based-approach",children:"Beyond Docker: Virtual Machine based Approach"}),"\n",(0,t.jsx)(n.p,{children:"While Docker provides significant benefits for local environment testing, it's important to recognize its limitations. Docker containers, by design, are lightweight and don't contain a full operating system which can lead to challenges when trying to mimic real-world production environments. Also, Docker containers lack some necessary features like systemd which is used in many production environments for initializing and managing services."}),"\n",(0,t.jsx)(n.p,{children:"One major aspect that Docker lacks is the ability to mimic real-world production environments effectively. This is primarily due to its nature as a containerization tool, operating within the host OS, and sharing resources among its containers. This might create disparities in behavior when comparing to deployments on real, isolated systems, which could be problematic in some scenarios."}),"\n",(0,t.jsx)(n.p,{children:"Furthermore, Docker utilizes a Union File System for its images, leading to the creation of layers. This approach can lead to some complexities when dealing with node-images which comprise a significant chunk of our layers. Handling such situations might require workarounds that could add additional complexity and potential points of failure. This creates a blind spot, as real providers won't require these workarounds, which might lead to disparities in results when comparing testing in local and actual production environments."}),"\n",(0,t.jsx)(n.p,{children:"Therefore, to achieve a more accurate representation of real-world environments, we propose a solution that utilizes a virtual machine based approach for local testing. This approach could leverage tools like KubeVirt, Vagrant, or VirtualBox to create and manage virtual machines on the local environment. This strategy would provide a more robust and realistic environment for testing, as it can better emulate the behavior of a full-fledged operating system and thereby more closely mimic a real-world production environment."}),"\n",(0,t.jsx)(n.h3,{id:"virtual-machine-based-approach",children:"Virtual Machine Based Approach"}),"\n",(0,t.jsx)(n.h4,{id:"pros-2",children:"Pros"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Provides a more accurate representation of real-world production environments."}),"\n",(0,t.jsx)(n.li,{children:"Allows for full operating system emulation, including features like systemd."}),"\n",(0,t.jsx)(n.li,{children:"Can create isolated environments, thereby mimicking actual deployments better than containers."}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"cons-2",children:"Cons"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Potentially more resource-intensive than container-based solutions."}),"\n",(0,t.jsx)(n.li,{children:"Increased complexity due to the need for managing full virtual machines rather than lightweight containers."}),"\n",(0,t.jsx)(n.li,{children:"Initial setup might be more complicated compared to a Docker-based solution."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"proposed-path-forward",children:"Proposed Path Forward"}),"\n",(0,t.jsx)(n.p,{children:"Given the limitations of Docker and the potential advantages of a virtual machine based approach, we propose to investigate further into this strategy. The exact tool or set of tools used can be determined based on a thorough evaluation of the available options."}),"\n",(0,t.jsx)(n.p,{children:"Although there might be some initial complexity and potentially higher resource usage compared to Docker, we believe that the benefits of more accurate testing and better emulation of real-world environments outweigh these potential disadvantages."}),"\n",(0,t.jsx)(n.p,{children:"The proposed solution should meet all the requirements mentioned in the previous sections of the proposal, in addition to providing the benefits of a virtual machine based approach. By doing so, we aim to establish a robust, reliable, and realistic testing environment for cluster stacks that mimics real-world production environments as closely as possible."}),"\n",(0,t.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,t.jsx)(n.p,{children:"After thoroughly examining the organizational needs, technical requirements, and potential testing approaches, it is evident that testing cluster stacks in a local environment provides significant advantages over using an Infrastructure as a Service (IaaS) provider. A local environment minimizes financial constraints, reduces testing time, offers offline capabilities, and enables greater tester participation without the need for specialized IaaS knowledge."}),"\n",(0,t.jsx)(n.p,{children:"While Docker stands out for its broad adoption, cost-effectiveness, and impressive containerization benefits, it also presents some limitations that cannot be overlooked. The lack of full operating system emulation and certain system features like systemd pose challenges to mimic real-world production environments accurately."}),"\n",(0,t.jsx)(n.p,{children:"Given Docker's limitations and the need to reproduce realistic testing scenarios, we propose moving beyond Docker to a virtual machine-based approach. Even though this approach may introduce initial complexity and potentially higher resource usage, it promises a more accurate representation of real-world environments, thereby ensuring more reliable and robust test results."}),"\n",(0,t.jsx)(n.p,{children:"Tools such as KubeVirt, Vagrant, or VirtualBox could potentially fulfill our requirements, offering benefits such as full operating system emulation and isolated environments. However, an in-depth evaluation of these and possibly other tools is necessary to determine the best path forward."}),"\n",(0,t.jsx)(n.p,{children:"In conclusion, our goal is to design a robust, reliable, and realistic testing environment for cluster stacks that closely mimics real-world production environments, aligns with our organizational and technical perspectives, and ensures a low entry barrier for all testers. Embracing a virtual machine-based approach for local environment testing represents a promising strategy to achieve this objective, paving the way for more efficient and reliable cluster stack testing."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>a});var t=i(96540);const s={},o=t.createContext(s);function r(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b2b675dd.ed31b25c.js b/assets/js/b2b675dd.ed31b25c.js new file mode 100644 index 0000000000..f4d2dbf2ad --- /dev/null +++ b/assets/js/b2b675dd.ed31b25c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1991],{29775:e=>{e.exports=JSON.parse('{"permalink":"/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/b2f554cd.a5e6b8a9.js b/assets/js/b2f554cd.a5e6b8a9.js new file mode 100644 index 0000000000..946ff2ae1b --- /dev/null +++ b/assets/js/b2f554cd.a5e6b8a9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5894],{76042:t=>{t.exports=JSON.parse('{"blogPosts":[{"id":"first-blog-post","metadata":{"permalink":"/blog/first-blog-post","editUrl":"https://github.com/SovereignCloudStack/docs/tree/main/blog/2022-10-28-first-blog-post.md","source":"@site/blog/2022-10-28-first-blog-post.md","title":"First Blog Post","description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet","date":"2022-10-28T00:00:00.000Z","tags":[{"label":"community","permalink":"/blog/tags/community"},{"label":"howto","permalink":"/blog/tags/howto"}],"readingTime":0.12,"hasTruncateMarker":false,"authors":[{"name":"Eduard Itrich","title":"Community Manager @ SCS","url":"https://github.com/itrich","imageURL":"https://github.com/itrich.png","key":"itrich"}],"frontMatter":{"slug":"first-blog-post","title":"First Blog Post","authors":"itrich","tags":["community","howto"]},"unlisted":false},"content":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}]}')}}]); \ No newline at end of file diff --git a/assets/js/b501f8e8.eb253035.js b/assets/js/b501f8e8.eb253035.js new file mode 100644 index 0000000000..c3fdf9efdf --- /dev/null +++ b/assets/js/b501f8e8.eb253035.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1528],{20145:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var o=n(74848),a=n(28453);const r={},i="Team Container",c={id:"collaboration/team-container",title:"Team Container",description:"The Team Container deals with all topics around Containers and Kubernetes.",source:"@site/community/collaboration/team-container.md",sourceDirName:"collaboration",slug:"/collaboration/team-container",permalink:"/community/collaboration/team-container",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Team IAM",permalink:"/community/collaboration/team-iam"},next:{title:"Team Ops",permalink:"/community/collaboration/team-ops"}},s={},l=[];function m(e){const t={h1:"h1",p:"p",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"team-container",children:"Team Container"}),"\n",(0,o.jsx)(t.p,{children:"The Team Container deals with all topics around Containers and Kubernetes."}),"\n",(0,o.jsx)(t.p,{children:"at the moment: Kubernetes Deployments via ClusterAPI\nin the future deployments via ClusterStacks\nKaaS Standard"})]})}function u(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(m,{...e})}):m(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var o=n(96540);const a={},r=o.createContext(a);function i(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b5a6d29b.e79829b4.js b/assets/js/b5a6d29b.e79829b4.js new file mode 100644 index 0000000000..92e19086e7 --- /dev/null +++ b/assets/js/b5a6d29b.e79829b4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8226],{21561:(e,a,n)=>{n.r(a),n.d(a,{assets:()=>t,contentTitle:()=>d,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>i});var c=n(74848),r=n(28453);const o={sidebar_label:"Resource Manager",sidebar_position:52},d="Resource Manager",s={id:"iaas/guides/operations-guide/openstack/tools/resource-manager",title:"Resource Manager",description:"Preparations",source:"@site/docs/02-iaas/guides/operations-guide/openstack/tools/resource-manager.md",sourceDirName:"02-iaas/guides/operations-guide/openstack/tools",slug:"/iaas/guides/operations-guide/openstack/tools/resource-manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/resource-manager.md",tags:[],version:"current",sidebarPosition:52,frontMatter:{sidebar_label:"Resource Manager",sidebar_position:52},sidebar:"docs",previous:{title:"Flavor Manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager"},next:{title:"Project Manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/project-manager"}},t={},i=[{value:"Preparations",id:"preparations",level:2},{value:"Nova",id:"nova",level:2},{value:"Live migration",id:"live-migration",level:3},{value:"Evacuation",id:"evacuation",level:3},{value:"Octavia",id:"octavia",level:2},{value:"Amphora rotation",id:"amphora-rotation",level:3},{value:"Cinder",id:"cinder",level:2},{value:"Orphans",id:"orphans",level:2}];function l(e){const a={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(a.h1,{id:"resource-manager",children:"Resource Manager"}),"\n",(0,c.jsx)(a.h2,{id:"preparations",children:"Preparations"}),"\n",(0,c.jsx)(a.p,{children:"Prepare use of the OpenStack Resource Manager."}),"\n",(0,c.jsx)(a.pre,{children:(0,c.jsx)(a.code,{className:"language-bash",children:"git clone https://github.com/osism/openstack-resource-manager\ncd openstack-resource-manager\npipenv install\npipenv shell\n"})}),"\n",(0,c.jsxs)(a.p,{children:["Prepare cloud profile ",(0,c.jsx)(a.code,{children:"admin"})," in ",(0,c.jsx)(a.code,{children:"clouds.yml"})," and ",(0,c.jsx)(a.code,{children:"secure.yml"})," (use ",(0,c.jsx)(a.code,{children:"clouds.yml.sample"})," and ",(0,c.jsx)(a.code,{children:"secure.yml.sample"}),"\nin the ",(0,c.jsx)(a.a,{href:"https://github.com/osism/openstack-resource-manager",children:"openstack-resource-manager"})," repository as sample files)."]}),"\n",(0,c.jsx)(a.h2,{id:"nova",children:"Nova"}),"\n",(0,c.jsx)(a.h3,{id:"live-migration",children:"Live migration"}),"\n",(0,c.jsxs)(a.p,{children:["Live migrate all instances from compute node ",(0,c.jsx)(a.code,{children:"SOURCE"})," to compute node ",(0,c.jsx)(a.code,{children:"TARGET"}),"."]}),"\n",(0,c.jsx)(a.pre,{children:(0,c.jsx)(a.code,{className:"language-bash",children:"python3 src/host-action.py --yes --disable --action live-migrate --host SOURCE --input TARGET\n"})}),"\n",(0,c.jsx)(a.h3,{id:"evacuation",children:"Evacuation"}),"\n",(0,c.jsxs)(a.p,{children:["Evacuate all instances from compute node ",(0,c.jsx)(a.code,{children:"SOURCE"})," to compute node ",(0,c.jsx)(a.code,{children:"TARGET"}),"."]}),"\n",(0,c.jsx)(a.pre,{children:(0,c.jsx)(a.code,{className:"language-bash",children:"python3 src/host-action.py --yes --action evacutate --host SOURCE --input TARGET\n"})}),"\n",(0,c.jsx)(a.h2,{id:"octavia",children:"Octavia"}),"\n",(0,c.jsx)(a.h3,{id:"amphora-rotation",children:"Amphora rotation"}),"\n",(0,c.jsx)(a.p,{children:"Rotation of amphorae older than 30 days."}),"\n",(0,c.jsx)(a.pre,{children:(0,c.jsx)(a.code,{className:"language-bash",children:"$ python3 src/amphora.py --rotate\n2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa is older than 30 days\n2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa of loadbalancer 9008d3d7-f593-4bc3-941c-a740c178148d is rotated by a loadbalancer failover\n"})}),"\n",(0,c.jsx)(a.h2,{id:"cinder",children:"Cinder"}),"\n",(0,c.jsx)(a.pre,{children:(0,c.jsx)(a.code,{className:"language-bash",children:"$ python3 src/volume.py\n2023-12-11 23:09:44 | INFO | Volume ad848454-ba1f-4c28-b9a8-edada17948b0 hangs in CREATING status for more than 2 hours\nDelete volume ad848454-ba1f-4c28-b9a8-edada17948b0 [yes/no]:\n"})}),"\n",(0,c.jsx)(a.h2,{id:"orphans",children:"Orphans"}),"\n",(0,c.jsx)(a.pre,{children:(0,c.jsx)(a.code,{className:"language-bash",children:"$ python3 src/orphan.py\n2023-12-11 23:11:16 | INFO | Checking nova / server\n2023-12-11 23:11:21 | INFO | Checking neutron / port\n2023-12-11 23:11:23 | INFO | Checking neutron / router\n2023-12-11 23:11:23 | INFO | Checking neutron / network\n2023-12-11 23:11:24 | INFO | Checking neutron / subnet\n2023-12-11 23:11:24 | INFO | Checking neutron / floatingip\n2023-12-11 23:11:24 | INFO | Checking neutron / rbacpolicy\n2023-12-11 23:11:24 | INFO | Checking neutron / securitygroup\n2023-12-11 23:11:26 | INFO | Checking neutron / securitygrouprule\n2023-12-11 23:11:27 | INFO | Checking glance / image\n2023-12-11 23:11:30 | INFO | Checking glance / imagemember\n[...]\n+---------------+-------------------+--------------------------------------+----------------------------------+\n| servicename | resourcename | resource_id | project_id |\n|---------------+-------------------+--------------------------------------+----------------------------------|\n| neutron | port | 561f8f76-18b0-470a-92cd-4336346b4b18 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | port | 6d1986e4-1e6d-4d4a-961d-97d372945bb1 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | port | 74f9bddc-9bfa-4d06-a147-ca87127e501e | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | port | f630a66b-7725-4a68-868b-caebbaf1c003 | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | router | c0c4e4aa-53ee-4fd1-8f53-84d52cf6c60b | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | router | c8f9a13b-adcd-4a8e-942b-338bcf4dde7c | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | network | 62d6ad2a-0cda-4d45-9325-963b8eb67000 | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | network | 63b8fea6-7d7b-40c3-9c31-bee4404a92d6 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | subnet | 0cd16262-330a-44ad-9160-daef84aded2d | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | subnet | 690dee14-ac12-464d-a911-a873c27ec818 | d33b0d15fd474131a335207216297a2a |\n| neutron | subnet | 854e7c55-62e2-4679-9b18-805460b998ce | 8268b05ef24b41d8806c0fe417576610 |\n| neutron | rbacpolicy | 00d7c2a2-6674-4f40-9f95-176a7858fcca | c8e4393b6d064a26a31014f82939172f |\n| neutron | rbacpolicy | 0608c701-5b81-4712-989b-ba03cdcc255d | c8e4393b6d064a26a31014f82939172f |\n[...]\n| neutron | securitygrouprule | fd3c553f-168e-4c24-ab40-09aa934bab86 | 3a96207b719643ae9ea9a81d95116e9e |\n| neutron | securitygrouprule | fdf337be-971c-4d5d-88ca-d90cdb468e88 | 3cfa8679f5d8429382b95d4d2dd80f79 |\n| neutron | securitygrouprule | ff8162fe-f053-49c9-8659-078061ce3e23 | d0b0add9ede0452791f71cb900e35242 |\n| glance | imagemember | c7f2cb0c25d34c5d886ecaf483e5fda6 | c7f2cb0c25d34c5d886ecaf483e5fda6 |\n| glance | imagemember | d4d0a161f9024fc8b517b0375eb97c89 | d4d0a161f9024fc8b517b0375eb97c89 |\n| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |\n| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |\n| glance | imagemember | d33b0d15fd474131a335207216297a2a | d33b0d15fd474131a335207216297a2a |\n| cinder | volume | e7c4b05c-b76a-40cc-8381-03262e57eb94 | 9b5f7f8ed70d410c81e3f45bf4e36498 |\n+---------------+-------------------+--------------------------------------+----------------------------------+\n"})})]})}function u(e={}){const{wrapper:a}={...(0,r.R)(),...e.components};return a?(0,c.jsx)(a,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},28453:(e,a,n)=>{n.d(a,{R:()=>d,x:()=>s});var c=n(96540);const r={},o=c.createContext(r);function d(e){const a=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function s(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),c.createElement(o.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b65fe363.6eb913dc.js b/assets/js/b65fe363.6eb913dc.js new file mode 100644 index 0000000000..0015a0c139 --- /dev/null +++ b/assets/js/b65fe363.6eb913dc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3475],{84863:(n,i,e)=>{e.r(i),e.d(i,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var o=e(74848),t=e(28453);const s={sidebar_label:"Ironic"},c="Ironic",r={id:"iaas/guides/configuration-guide/openstack/ironic",title:"Ironic",description:"* Ironic admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/ironic.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/ironic",permalink:"/docs/iaas/guides/configuration-guide/openstack/ironic",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/ironic.md",tags:[],version:"current",frontMatter:{sidebar_label:"Ironic"},sidebar:"docs",previous:{title:"Horizon",permalink:"/docs/iaas/guides/configuration-guide/openstack/horizon"},next:{title:"Keystone",permalink:"/docs/iaas/guides/configuration-guide/openstack/keystone"}},a={},d=[];function u(n){const i={a:"a",h1:"h1",li:"li",ul:"ul",...(0,t.R)(),...n.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(i.h1,{id:"ironic",children:"Ironic"}),"\n",(0,o.jsxs)(i.ul,{children:["\n",(0,o.jsx)(i.li,{children:(0,o.jsx)(i.a,{href:"https://docs.openstack.org/ironic/latest/admin/index.html",children:"Ironic admin guide"})}),"\n",(0,o.jsx)(i.li,{children:(0,o.jsx)(i.a,{href:"https://docs.openstack.org/ironic/latest/configuration/index.html",children:"Ironic configuration reference"})}),"\n"]})]})}function l(n={}){const{wrapper:i}={...(0,t.R)(),...n.components};return i?(0,o.jsx)(i,{...n,children:(0,o.jsx)(u,{...n})}):u(n)}},28453:(n,i,e)=>{e.d(i,{R:()=>c,x:()=>r});var o=e(96540);const t={},s=o.createContext(t);function c(n){const i=o.useContext(s);return o.useMemo((function(){return"function"==typeof n?n(i):{...i,...n}}),[i,n])}function r(n){let i;return i=n.disableParentContext?"function"==typeof n.components?n.components(t):n.components||t:c(n.components),o.createElement(s.Provider,{value:i},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/b74e5806.bdab4d88.js b/assets/js/b74e5806.bdab4d88.js new file mode 100644 index 0000000000..186ffcec4a --- /dev/null +++ b/assets/js/b74e5806.bdab4d88.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4730],{37155:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>d,toc:()=>a});var t=s(74848),r=s(28453);const o={},i="scs-0301: Naming for domains/groups/roles/project when onboarding new customers",d={id:"iam/scs-0301",title:"scs-0301: Naming for domains/groups/roles/project when onboarding new customers",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/iam/scs-0301.md",sourceDirName:"iam",slug:"/iam/scs-0301",permalink:"/standards/iam/scs-0301",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Requirements for SSO identity federation",permalink:"/standards/scs-0300-v1-requirements-for-sso-identity-federation"},next:{title:"Naming for domains/groups/roles/project when onboarding new customers",permalink:"/standards/scs-0301-v1-naming-conventions"}},c={},a=[];function l(e){const n={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"scs-0301-naming-for-domainsgroupsrolesproject-when-onboarding-new-customers",children:"scs-0301: Naming for domains/groups/roles/project when onboarding new customers"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Version"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"State"}),(0,t.jsx)(n.th,{children:"stabilized"}),(0,t.jsx)(n.th,{children:"deprecated"})]})}),(0,t.jsx)(n.tbody,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/standards/scs-0301-v1-naming-conventions",children:"scs-0301-v1"})}),(0,t.jsx)(n.td,{children:"Decision Record"}),(0,t.jsx)(n.td,{children:"Draft"}),(0,t.jsx)(n.td,{children:"-"}),(0,t.jsx)(n.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>d});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b77ceb62.56e89464.js b/assets/js/b77ceb62.56e89464.js new file mode 100644 index 0000000000..c5ba6607c1 --- /dev/null +++ b/assets/js/b77ceb62.56e89464.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9689],{57794:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>l,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var n=i(74848),o=i(28453);const r={sidebar_label:"Ceilometer"},s="Ceilometer",c={id:"iaas/guides/configuration-guide/openstack/ceilometer",title:"Ceilometer",description:"* Ceilometer admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/ceilometer.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/ceilometer",permalink:"/docs/iaas/guides/configuration-guide/openstack/ceilometer",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/ceilometer.md",tags:[],version:"current",frontMatter:{sidebar_label:"Ceilometer"},sidebar:"docs",previous:{title:"Barbican",permalink:"/docs/iaas/guides/configuration-guide/openstack/barbican"},next:{title:"Cinder",permalink:"/docs/iaas/guides/configuration-guide/openstack/cinder"}},a={},d=[];function u(e){const t={a:"a",h1:"h1",li:"li",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"ceilometer",children:"Ceilometer"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://docs.openstack.org/ceilometer/latest/admin/index.html",children:"Ceilometer admin guide"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://docs.openstack.org/ceilometer/latest/configuration/index.html",children:"Ceilometer configuration reference"})}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>c});var n=i(96540);const o={},r=n.createContext(o);function s(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b7cec31e.cb1af7da.js b/assets/js/b7cec31e.cb1af7da.js new file mode 100644 index 0000000000..e75dbe5483 --- /dev/null +++ b/assets/js/b7cec31e.cb1af7da.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7938],{46781:(t,n,e)=>{e.r(n),e.d(n,{assets:()=>m,contentTitle:()=>r,default:()=>l,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var o=e(74848),i=e(28453);const a={},r="SIG Community",c={id:"collaboration/sig-community",title:"SIG Community",description:"In this meeting, we come together to shape our community strategy and coordinate collaborative efforts within our community. Our goal is to cultivate an open and welcoming community where we can share the message of SCS. We plan engaging community events, strive to make this open-source community even more inclusive, and aim to keep it informative, inspiring, and captivating. We warmly invite you to join us in our mission and become a part of this exciting journey!",source:"@site/community/collaboration/sig-community.md",sourceDirName:"collaboration",slug:"/collaboration/sig-community",permalink:"/community/collaboration/sig-community",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"SIG Central API",permalink:"/community/collaboration/sig-central-api"},next:{title:"SIG Documentation",permalink:"/community/collaboration/sig-documentation"}},m={},s=[];function u(t){const n={h1:"h1",p:"p",...(0,i.R)(),...t.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"sig-community",children:"SIG Community"}),"\n",(0,o.jsx)(n.p,{children:"In this meeting, we come together to shape our community strategy and coordinate collaborative efforts within our community. Our goal is to cultivate an open and welcoming community where we can share the message of SCS. We plan engaging community events, strive to make this open-source community even more inclusive, and aim to keep it informative, inspiring, and captivating. We warmly invite you to join us in our mission and become a part of this exciting journey!"})]})}function l(t={}){const{wrapper:n}={...(0,i.R)(),...t.components};return n?(0,o.jsx)(n,{...t,children:(0,o.jsx)(u,{...t})}):u(t)}},28453:(t,n,e)=>{e.d(n,{R:()=>r,x:()=>c});var o=e(96540);const i={},a=o.createContext(i);function r(t){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof t?t(n):{...n,...t}}),[n,t])}function c(t){let n;return n=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:r(t.components),o.createElement(a.Provider,{value:n},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/b840bdcc.41fc9292.js b/assets/js/b840bdcc.41fc9292.js new file mode 100644 index 0000000000..cb5cba59e7 --- /dev/null +++ b/assets/js/b840bdcc.41fc9292.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1489],{44111:e=>{e.exports=JSON.parse('{"title":"Metering","slug":"/category/metering","permalink":"/docs/category/metering","navigation":{"previous":{"title":"Guide: Setting up openstack-health-monitor on Debian 12","permalink":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install"},"next":{"title":"Metering Configuration","permalink":"/docs/operating-scs/metering/meter_configuration"}}}')}}]); \ No newline at end of file diff --git a/assets/js/b8c7b97f.d8b02d92.js b/assets/js/b8c7b97f.d8b02d92.js new file mode 100644 index 0000000000..ba330c6847 --- /dev/null +++ b/assets/js/b8c7b97f.d8b02d92.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6443],{81084:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var i=t(74848),o=t(28453);const s={},a="Introduction on Identity Management and Federation in SCS",r={id:"iam/index",title:"Introduction on Identity Management and Federation in SCS",description:"Sovereign Cloud Stack wants to make it possible for operators to delegate",source:"@site/docs/05-iam/index.md",sourceDirName:"05-iam",slug:"/iam/",permalink:"/docs/iam/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/05-iam/index.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Metering Configuration",permalink:"/docs/operating-scs/metering/meter_configuration"},next:{title:"Guides",permalink:"/docs/category/guides-2"}},l={},d=[{value:"Deployment",id:"deployment",level:2},{value:"Accessing Keycloak",id:"accessing-keycloak",level:2},{value:"Identity Mapping",id:"identity-mapping",level:2},{value:"SCS to SCS federation",id:"scs-to-scs-federation",level:2},{value:"Prerequisites and Requirements",id:"prerequisites-and-requirements",level:3},{value:"Features",id:"features",level:3},{value:"Limitations",id:"limitations",level:3},{value:"Current state and future Outlook",id:"current-state-and-future-outlook",level:3}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"introduction-on-identity-management-and-federation-in-scs",children:"Introduction on Identity Management and Federation in SCS"}),"\n",(0,i.jsx)(n.p,{children:"Sovereign Cloud Stack wants to make it possible for operators to delegate\nadministration of user identities to the organizational entities that the\nusers are part of. Usually that's customer organizations but it could also\nbe the operator itself. Federation protocols like OpenID Connect can be used\nto achieve that goal. To simplify connecting the different parts of SCS\nto customer owned IAM solutions, the SCS reference implementation offers\nKeycloak as central Identity Provider (IdP) service."}),"\n",(0,i.jsx)(n.h2,{id:"deployment",children:"Deployment"}),"\n",(0,i.jsx)(n.p,{children:"Keycloak can be deployed by running"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply keycloak\n"})}),"\n",(0,i.jsx)(n.p,{children:"The required Keycloak client configuration that allows Keystone to obtain\nOIDC token from Keycloak needs to be deployed by running"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply keycloak-oidc-client-config\n"})}),"\n",(0,i.jsxs)(n.p,{children:["After these steps Keystone should be able to obtain token using the\nDevice Authorization Grant with PKCE, which is configured by default in the\n",(0,i.jsx)(n.code,{children:"wsgi-keystone.conf"})," deployed in SCS."]}),"\n",(0,i.jsx)(n.h2,{id:"accessing-keycloak",children:"Accessing Keycloak"}),"\n",(0,i.jsxs)(n.p,{children:["Currently deployed on the manager node, by default under ",(0,i.jsx)(n.code,{children:"https://keycloak.<yourdomain>"}),".\nDetails TODO."]}),"\n",(0,i.jsx)(n.h2,{id:"identity-mapping",children:"Identity Mapping"}),"\n",(0,i.jsxs)(n.p,{children:["The idea is that customer can create groups with specific names in their own IAM.\nThese shall be mapped to a claim ",(0,i.jsx)(n.code,{children:"groups"})," to be included in the OIDC token.\nVia the Keystone ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/keystone/latest/admin/federation/mapping_combinations.html",children:"mapping"}),"\nthey shall be mapped to roles on OpenStack projects.\n",(0,i.jsx)(n.a,{href:"https://docs.scs.community/contributor-docs/operations/iam/identity-federation-in-scs",children:"The corresponding section for Developers"})," may be interesting for more technical details.\nPlease be aware that currently there are still some technical challenges to be solved\nwithin the OpenStack Keystone mapping engine and the mapping rules to make this work\nseamlessly."]}),"\n",(0,i.jsx)(n.h2,{id:"scs-to-scs-federation",children:"SCS to SCS federation"}),"\n",(0,i.jsxs)(n.p,{children:["Federation between separate deployments of SCS is possible via the IdP by\nmeans of OpenID Connect.\nThe section on ",(0,i.jsx)(n.a,{href:"https://docs.scs.community/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations",children:"inter SCS federation setup"})," explains the required steps in some detail."]}),"\n",(0,i.jsx)(n.h3,{id:"prerequisites-and-requirements",children:"Prerequisites and Requirements"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Knowledge: Familiarity with Keycloak, OIDC federation, and basic SSL and web security principles is pivotal."}),"\n",(0,i.jsx)(n.li,{children:"Software: The core software component is the OpenID-Connect identity provider, configured to function optimally with OpenStack environments. While the SCS reference implementation focusses on Keycloak as IdP, with appropriate configuration adjustments any OAuth 2.0 compliant IdP should be suitable as an alternative. Each implemntation may have its own pros and cons."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"features",children:"Features"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Horizon Web SSO"}),"\n",(0,i.jsx)(n.li,{children:"OpenStack CLI use via the Device Authorization Grant"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"limitations",children:"Limitations"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Keystone currently still has limitations in its mapping engine, which are addressed by the SCS development team as we\nsee possibilities and alignement with upstream OpenDev development plans. Automatically creating ",(0,i.jsx)(n.code,{children:"ephemeral"})," users in\ntheir specific OpenStack domains, as specified in their OIDC token is one example, currently beeing worked on. Please\ncheck carefully if the technical results meet the security demands of your specific environment."]}),"\n",(0,i.jsxs)(n.li,{children:["Keystone currently has another limitation which is being addressed by the SCS development team aligned\nwith upstream OpenDev development plans: The roles for federated users are stored on the database for the ",(0,i.jsx)(n.code,{children:"ephemeral"})," users\ncreated during a federated login. This limits the ability to modify users roles from the identity source directly, as roles of\nthe ",(0,i.jsx)(n.code,{children:"epehemeral"})," users do not get cleaned up or updated based on changes in the claims contained in the OpenID-Connect token."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"current-state-and-future-outlook",children:"Current state and future Outlook"}),"\n",(0,i.jsx)(n.p,{children:"Currently SCS exemplifies deploying Keycloak on the management plane. This shall be moved to a Kubernetes based\nmanagement plane to improve scalability and architecture."}),"\n",(0,i.jsx)(n.p,{children:"In the near future, the Container layer shall be able to make use of the IdP to allow federated users to access Kubernetes.\nIn the mid term, workloads on Kubernetes shall be able to make use of OAuth tokens to access resources on the IaaS layer."})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var i=t(96540);const o={},s=i.createContext(o);function a(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b8fd74b5.e8238985.js b/assets/js/b8fd74b5.e8238985.js new file mode 100644 index 0000000000..4303e318e2 --- /dev/null +++ b/assets/js/b8fd74b5.e8238985.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3153],{14158:(n,e,o)=>{o.r(e),o.d(e,{assets:()=>i,contentTitle:()=>r,default:()=>u,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var a=o(74848),t=o(28453);const s={sidebar_label:"Sandbox Manager",sidebar_position:54},r="Sandbox Manager",c={id:"iaas/components/sandbox-manager",title:"Sandbox Manager",description:"",source:"@site/docs/02-iaas/components/sandbox-manager.md",sourceDirName:"02-iaas/components",slug:"/iaas/components/sandbox-manager",permalink:"/docs/iaas/components/sandbox-manager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/sandbox-manager.md",tags:[],version:"current",sidebarPosition:54,frontMatter:{sidebar_label:"Sandbox Manager",sidebar_position:54}},i={},d=[];function m(n){const e={h1:"h1",...(0,t.R)(),...n.components};return(0,a.jsx)(e.h1,{id:"sandbox-manager",children:"Sandbox Manager"})}function u(n={}){const{wrapper:e}={...(0,t.R)(),...n.components};return e?(0,a.jsx)(e,{...n,children:(0,a.jsx)(m,{...n})}):m(n)}},28453:(n,e,o)=>{o.d(e,{R:()=>r,x:()=>c});var a=o(96540);const t={},s=a.createContext(t);function r(n){const e=a.useContext(s);return a.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(t):n.components||t:r(n.components),a.createElement(s.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/bccb1b42.a2dde942.js b/assets/js/bccb1b42.a2dde942.js new file mode 100644 index 0000000000..1a5e2f4255 --- /dev/null +++ b/assets/js/bccb1b42.a2dde942.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6986],{19075:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var t=r(74848),s=r(28453);const o={},i="Migration",a={id:"container/components/container-registry/docs/migration",title:"Migration",description:"harbormigration.png",source:"@site/docs/03-container/components/container-registry/docs/migration.md",sourceDirName:"03-container/components/container-registry/docs",slug:"/container/components/container-registry/docs/migration",permalink:"/docs/container/components/container-registry/docs/migration",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/migration.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Backup and restore",permalink:"/docs/container/components/container-registry/docs/backup_and_restore"},next:{title:"Persistence",permalink:"/docs/container/components/container-registry/docs/persistence"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Kubernetes clusters",id:"kubernetes-clusters",level:3},{value:"S3 bucket and EC2 credentials",id:"s3-bucket-and-ec2-credentials",level:3},{value:"Velero client",id:"velero-client",level:3},{value:"Velero server",id:"velero-server",level:3},{value:"Migration",id:"migration-1",level:2}];function d(e){const n={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"migration",children:"Migration"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"harbor_migration.png",src:r(26763).A+"",width:"721",height:"243"})}),"\n",(0,t.jsxs)(n.p,{children:["This page aims at providing a step-by-step guide for lift and shift migration of ",(0,t.jsx)(n.a,{href:"https://goharbor.io/",children:"Harbor"}),"\ncontainer registry, which operates in the Kubernetes environment and is deployed with Helm.\nThis migration scenario uses ",(0,t.jsx)(n.a,{href:"https://velero.io/",children:"Velero"})," tool which\nenables moving your Harbor instance as-is from one Kubernetes environment to another\nKubernetes environment. The motivation behind this could be e.g. migration\nfrom one cloud provider to another, an outdated Kubernetes environment of your Harbor\ninstance or avoiding the Harbor in-place upgrade."]}),"\n",(0,t.jsxs)(n.p,{children:["Note that the official Harbor's documentation contains an \"",(0,t.jsx)(n.a,{href:"https://goharbor.io/docs/main/administration/upgrade/",children:"Upgrade Harbor and Migrate Data"}),'" page\nthat instructs users on how to upgrade and migrate Harbor data from one instance to\nanother. This tutorial supports only deployments that have been installed by ',(0,t.jsx)(n.a,{href:"https://goharbor.io/docs/main/install-config/download-installer/",children:"Harbor installer"})," script.\nHence, Harbor instances running in docker containers and spawned by docker-compose."]}),"\n",(0,t.jsxs)(n.p,{children:["Note that this guide is not limited to Harbor deployments that utilize SCS environments.\nVisit the ",(0,t.jsx)(n.a,{href:"#prerequisites",children:"prerequisites"})," section to see what is required for a successful\nmigration. These prerequisites come out of the box when the SCS infrastructure and KaaS\nare used for Harbor deployment, hence it is convenient to use them."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.p,{children:["As this scenario uses a backup and restore procedure for the migration process, this section\nrefers to the prerequisites section in ",(0,t.jsx)(n.a,{href:"/docs/container/components/container-registry/docs/backup_and_restore#prerequisites",children:"Harbor - backup and restore"}),"\ndocs page."]}),"\n",(0,t.jsx)(n.h3,{id:"kubernetes-clusters",children:"Kubernetes clusters"}),"\n",(0,t.jsx)(n.p,{children:"This migration scenario expects that you want to migrate your Harbor instance\nbetween different Kubernetes clusters that could live in different environments (e.g.\nOpenStack projects) or even in different cloud providers. Let's call them Cluster_A and\nCluster_B. Cluster_A represents the Kubernetes cluster where your Harbor currently operates and\nCluster_B represents the target Kubernetes cluster to which you want to migrate your Harbor."}),"\n",(0,t.jsxs)(n.p,{children:["As Cluster_A and Cluster_B do not have to share the same infrastructure it is convenient to\nuse a full Harbor data backup (not a snapshot) using ",(0,t.jsx)(n.a,{href:"https://restic.net/",children:"Restic"}),"\nintegration in Velero. In this case, Cluster_A and Cluster_B should have\nKubernetes version ",(0,t.jsx)(n.strong,{children:"1.16"})," or greater.\nFor further details about Restic-Velero integration refer to the",(0,t.jsx)(n.br,{}),"\n","related ",(0,t.jsx)(n.a,{href:"https://velero.io/docs/main/file-system-backup/",children:"Velero docs"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Kubernetes versions of Cluster_A and Cluster_B may differ. In this case, it is\nnot unusual to see the Kubernetes API group versions differing between clusters. This\nincompatibility may cause issues during the migration of your Harbor instance. By default,\nVelero only backs up resources that use the preferred version of the Kubernetes API.\nHowever, Velero also includes a feature, ",(0,t.jsx)(n.a,{href:"https://velero.io/docs/main/enable-api-group-versions-feature/",children:"Enable API Group Versions"}),",\nthat overcomes this limitation and backup all Kubernetes API group versions that are\nsupported on the source Cluster_A. Then, if this feature is also enabled on the Cluster_B,\nVelero will make the best choice of Kubernetes API version which is defined in the group\nname of both source Cluster_A and target Cluster_B based on API group version priority order,\nread ",(0,t.jsx)(n.a,{href:"https://velero.io/docs/main/enable-api-group-versions-feature/",children:"docs"})," for further details.\nIf the above is the case consider installing Velero on both clusters\nwith a feature flag ",(0,t.jsx)(n.code,{children:"--features=EnableAPIGroupVersions"}),". Note that this feature is still in beta."]}),"\n",(0,t.jsx)(n.h3,{id:"s3-bucket-and-ec2-credentials",children:"S3 bucket and EC2 credentials"}),"\n",(0,t.jsxs)(n.p,{children:["This guide assumes that the public cloud's object store with S3-compatible API is available as\nthe storage backend for Velero. Refer to the ",(0,t.jsx)(n.a,{href:"/docs/container/components/container-registry/docs/backup_and_restore#s3-bucket-and-ec2-credentials",children:"S3 bucket and EC2 credentials"}),"\nsection in the backup and restore docs and create a bucket that will be later used for\nthe migration."]}),"\n",(0,t.jsx)(n.h3,{id:"velero-client",children:"Velero client"}),"\n",(0,t.jsxs)(n.p,{children:["Install the Velero client on your local environment, refer to ",(0,t.jsx)(n.a,{href:"/docs/container/components/container-registry/docs/backup_and_restore#velero-client",children:"Velero client"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"velero-server",children:"Velero server"}),"\n",(0,t.jsxs)(n.p,{children:["Install Velero server components along with the appropriate plugins, into the both\n(Cluster_A and Cluster_B) clusters. Keep in mind that we will use Restic uploader in\nVelero, hence follows interactions on how to do that in the related docs section ",(0,t.jsx)(n.a,{href:"/docs/container/components/container-registry/docs/backup_and_restore#velero-server",children:"Velero server"}),".\nDo not forget to add ",(0,t.jsx)(n.code,{children:"--kubeconfig"})," argument to install Velero server components\nto the Cluster_A and then to the Cluster_B. The rest of arguments should be the same:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'velero install \\\n --kubeconfig <path to the kubeconfig file of Cluster_[A,B]> \\ \n --provider aws \\\n --plugins velero/velero-plugin-for-aws:v1.6.1 \\\n --bucket velero-backup \\\n --secret-file ~/.aws/credentials \\\n --use-volume-snapshots=false \\\n --uploader-type=restic \\\n --use-node-agent \\\n --backup-location-config region=RegionOne,s3ForcePathStyle="true",s3Url=https://api.gx-scs.sovereignit.cloud:8080\n'})}),"\n",(0,t.jsxs)(n.p,{children:["It is a good practice to configure the backup location in the Cluster_B as read-only.\nThis will make sure that the backup created from Cluster_A is not deleted from the object\nstore by mistake during the restore to Cluster_B. To do this you can just edit the ",(0,t.jsx)(n.code,{children:"default"}),"\nBackupStorageLocation resource in Cluster_B."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ kubectl -n velero --kubeconfig <path of Cluster_B kubeconfig> edit backupstoragelocations default\n# Set the `accessMode` to `ReadOnly`\n# spec:\n# accessMode: ReadOnly\n"})}),"\n",(0,t.jsx)(n.h2,{id:"migration-1",children:"Migration"}),"\n",(0,t.jsxs)(n.p,{children:["Before we start to migrate Harbor instance from one environment to another go through the\n",(0,t.jsx)(n.a,{href:"/docs/container/components/container-registry/docs/backup_and_restore#backup-and-restore",children:"Backup and restore"})," section and read\nvarious limitations of the backup/restore process to be aware of the potential impact on\nyour Harbor instance."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Backup Harbor instance in Cluster_A","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsxs)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#set-harbor-to-readonly",children:["Set Harbor to the ",(0,t.jsx)(n.code,{children:"ReadOnly"})," mode"]})}),"\n",(0,t.jsxs)(n.li,{children:["Exclude the volume of Redis in backup in Cluster_A","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# replace the namespace and pod name with yours\nkubectl -n default --kubeconfig <path of Cluster_A kubeconfig> annotate pod/harbor-harbor-redis-0 backup.velero.io/backup-volumes-excludes=data\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Back up Harbor in Cluster_A","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"velero backup create harbor-backup --kubeconfig <path of Cluster_A kubeconfig> --include-namespaces default --default-volumes-to-fs-backup --wait\n"})}),"\n","This creates a full backup of all resources in the given namespace including their\npersistent storages (besides Redis PV)."]}),"\n",(0,t.jsxs)(n.li,{children:["Optionally: ",(0,t.jsxs)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#unset-readonly",children:["Unset Harbor from the ",(0,t.jsx)(n.code,{children:"ReadOnly"})," mode"]}),".\nKeep in mind that the ",(0,t.jsx)(n.code,{children:"ReadOnly"})," mode protects your Harbor instance from deleting\nrepository, artifact, tag, and pushing images. This ensures that the Harbor instance\nin Cluster_A will be in sync with the Harbor instance in Cluster_B after you restored\nHarbor instance from the backup in Cluster_B. Therefore, it is recommended to ",(0,t.jsx)(n.strong,{children:"not"}),"\nunset Harbor from the ",(0,t.jsx)(n.code,{children:"ReadOnly"})," mode in Cluster_A."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Restore Harbor instance in Cluster_B","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Restore from the Backup","\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# replace the backup and restore names with yours\nvelero restore create harbor-restore --from-backup harbor-backup --kubeconfig <path of Cluster_B kubeconfig> --wait \n"})}),"\n","Velero backed up the whole namespace where the Harbor instance lives in Cluster_A,\ntherefore the restored namespace in Cluster_B may contain resources (e.g. service,\ningress, TLS certificates) that expose Harbor instance in the same way as in\nCluster_A. It is a good practice to test this Cluster_B instance before you allow\nusers to use it."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsxs)(n.a,{href:"https://goharbor.io/docs/main/administration/backup-restore/#unset-readonly",children:["Unset Harbor from the ",(0,t.jsx)(n.code,{children:"ReadOnly"})," mode"]}),".\nAs we set Harbor in Cluster_A to ReadOnly when doing the backup, the instance is\nstill in ReadOnly mode after restoring. Unset Harbor from the ReadOnly mode after\nyou check its functionality."]}),"\n"]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},26763:(e,n,r)=>{r.d(n,{A:()=>t});const t=r.p+"assets/images/harbor_migration-15d83bf7e5b37c0bdcb698280dde0684.png"},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>a});var t=r(96540);const s={},o=t.createContext(s);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bceb927f.11b77b9d.js b/assets/js/bceb927f.11b77b9d.js new file mode 100644 index 0000000000..500a4dd678 --- /dev/null +++ b/assets/js/bceb927f.11b77b9d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8081],{90594:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>r,metadata:()=>a,toc:()=>u});var i=t(74848),o=t(28453);const r={sidebar_label:"Neutron"},s="Neutron",a={id:"iaas/guides/configuration-guide/openstack/neutron",title:"Neutron",description:"* Neutron admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/neutron.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/neutron",permalink:"/docs/iaas/guides/configuration-guide/openstack/neutron",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/neutron.md",tags:[],version:"current",frontMatter:{sidebar_label:"Neutron"},sidebar:"docs",previous:{title:"Manila",permalink:"/docs/iaas/guides/configuration-guide/openstack/manila"},next:{title:"Nova",permalink:"/docs/iaas/guides/configuration-guide/openstack/nova"}},c={},u=[{value:"MTU Considerations",id:"mtu-considerations",level:2}];function d(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,o.R)(),...n.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h1,{id:"neutron",children:"Neutron"}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:"https://docs.openstack.org/neutron/latest/admin/index.html",children:"Neutron admin guide"})}),"\n",(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:"https://docs.openstack.org/neutron/latest/configuration/index.html",children:"Neutron configuration guide"})}),"\n",(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:"https://docs.openstack.org/neutron/latest/configuration/config.html",children:"Neutron configuration reference"})}),"\n"]}),"\n",(0,i.jsx)(e.p,{children:"Neutron-Dynamic-Routing:"}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:"https://docs.openstack.org/neutron-dynamic-routing/latest/admin/index.html",children:"Neutron-Dynamic-Routing admin guide"})}),"\n",(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:"https://docs.openstack.org/neutron-dynamic-routing/latest/configuration/index.html",children:"Neutron-Dynamic-Routing configuration guide"})}),"\n",(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:"https://docs.openstack.org/neutron-dynamic-routing/latest/configuration/bgp_dragent.html",children:"Neutron-Dynamic-Routing configuration reference"})}),"\n"]}),"\n",(0,i.jsx)(e.p,{children:"Neutron-VPNaaS:"}),"\n",(0,i.jsxs)(e.ul,{children:["\n",(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:"https://docs.openstack.org/neutron-vpnaas/latest/admin/index.html",children:"Neutron-VPNaaS admin guide"})}),"\n",(0,i.jsx)(e.li,{children:(0,i.jsx)(e.a,{href:"https://docs.openstack.org/neutron-vpnaas/latest/configuration/index.html",children:"Neutron-VPNaaS configuration guide"})}),"\n"]}),"\n",(0,i.jsx)(e.h2,{id:"mtu-considerations",children:"MTU Considerations"}),"\n",(0,i.jsx)(e.p,{children:"Neutron uses the MTU of the underlying physical network to calculate the MTU for virtual network\ncomponents including instance network interfaces. By default, it assumes a standard 1500-byte MTU\nfor the underlying physical network."}),"\n",(0,i.jsx)(e.p,{children:"Neutron only references the underlying physical network MTU. Changing the underlying physical network\ndevice MTU requires configuration of physical network devices such as switches and routers."}),"\n",(0,i.jsxs)(e.p,{children:["The configuration is described in the ",(0,i.jsx)(e.a,{href:"https://docs.openstack.org/neutron/latest/admin/config-mtu.html",children:"Neutron admin guide"}),".\nThe configuration files are placed under ",(0,i.jsx)(e.code,{children:"environments/kolla/files/overlays/neutron/ml2_conf.ini"}),"\nand ",(0,i.jsx)(e.code,{children:"environments/kolla/files/overlays/neutron.conf"}),"."]})]})}function l(n={}){const{wrapper:e}={...(0,o.R)(),...n.components};return e?(0,i.jsx)(e,{...n,children:(0,i.jsx)(d,{...n})}):d(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>s,x:()=>a});var i=t(96540);const o={},r=i.createContext(o);function s(n){const e=i.useContext(r);return i.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function a(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(o):n.components||o:s(n.components),i.createElement(r.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/bd319452.482f2c1c.js b/assets/js/bd319452.482f2c1c.js new file mode 100644 index 0000000000..bf7db455d0 --- /dev/null +++ b/assets/js/bd319452.482f2c1c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6971],{2554:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>r,contentTitle:()=>o,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var n=s(74848),d=s(28453);const i={sidebar_label:"Testbed"},o="Testbed",a={id:"iaas/guides/deploy-guide/examples/testbed",title:"Testbed",description:"This section has moved. You can now find the content in the",source:"@site/docs/02-iaas/guides/deploy-guide/examples/testbed.md",sourceDirName:"02-iaas/guides/deploy-guide/examples",slug:"/iaas/guides/deploy-guide/examples/testbed",permalink:"/docs/iaas/guides/deploy-guide/examples/testbed",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/examples/testbed.md",tags:[],version:"current",frontMatter:{sidebar_label:"Testbed"},sidebar:"docs",previous:{title:"Cloud in a Box",permalink:"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box"},next:{title:"Upgrade Guide",permalink:"/docs/iaas/guides/upgrade-guide/"}},r={},c=[];function u(e){const t={a:"a",h1:"h1",p:"p",...(0,d.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"testbed",children:"Testbed"}),"\n",(0,n.jsxs)(t.p,{children:["This section has moved. You can now find the content in the\n",(0,n.jsx)(t.a,{href:"../../other-guides",children:"Other Guides"})," as\n",(0,n.jsx)(t.a,{href:"../../other-guides/testbed",children:"Testbed Guide"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,d.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>a});var n=s(96540);const d={},i=n.createContext(d);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bd8a0ffe.c55b522d.js b/assets/js/bd8a0ffe.c55b522d.js new file mode 100644 index 0000000000..a635c14807 --- /dev/null +++ b/assets/js/bd8a0ffe.c55b522d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4497],{36910:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var s=t(74848),a=t(28453);const i={title:"SCS Entropy: Implementation and Testing Notes",type:"Supplement",track:"IaaS",status:"Proposal",supplements:["scs-0101-v1-entropy.md"]},r=void 0,o={id:"scs-0101-w1-entropy-implementation-testing",title:"SCS Entropy: Implementation and Testing Notes",description:"Implementation",source:"@site/standards/scs-0101-w1-entropy-implementation-testing.md",sourceDirName:".",slug:"/scs-0101-w1-entropy-implementation-testing",permalink:"/standards/scs-0101-w1-entropy-implementation-testing",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS Entropy: Implementation and Testing Notes",type:"Supplement",track:"IaaS",status:"Proposal",supplements:["scs-0101-v1-entropy.md"]},sidebar:"standards",previous:{title:"SCS Entropy",permalink:"/standards/scs-0101-v1-entropy"},next:{title:"scs-0102: SCS Image Metadata Standard",permalink:"/standards/iaas/scs-0102"}},l={},d=[{value:"Implementation",id:"implementation",level:2},{value:"Automated Tests",id:"automated-tests",level:2},{value:"Images Sample",id:"images-sample",level:3},{value:"Errors",id:"errors",level:3},{value:"Warnings",id:"warnings",level:3},{value:"Implementation",id:"implementation-1",level:3},{value:"Manual Tests",id:"manual-tests",level:2}];function c(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"implementation",children:"Implementation"}),"\n",(0,s.jsx)(n.p,{children:"We presume that almost nothing has to be done (or indeed can be done), as\nlong as the CPUs and VM images are reasonably recent; only the flavor and\nimage attributes have to be set:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["flavor: ",(0,s.jsx)(n.code,{children:"hw_rng:allowed=True"})," ,"]}),"\n",(0,s.jsxs)(n.li,{children:["image: ",(0,s.jsx)(n.code,{children:"hw_rng_model: virtio"})," ."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"automated-tests",children:"Automated Tests"}),"\n",(0,s.jsx)(n.h3,{id:"images-sample",children:"Images Sample"}),"\n",(0,s.jsx)(n.p,{children:"Some checks need to be performed on a live instance. For these checks, it is\nnecessary to choose a sample of VM images to test on."}),"\n",(0,s.jsx)(n.p,{children:"For the time being, the sample MUST contain at least one public image reported\nby OpenStack. This may be extended in the future."}),"\n",(0,s.jsx)(n.h3,{id:"errors",children:"Errors"}),"\n",(0,s.jsx)(n.p,{children:"For every image in the chosen sample, the following items MUST be detected and\nreported as an error:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["the service ",(0,s.jsx)(n.code,{children:"rngd"})," is not running,"]}),"\n",(0,s.jsxs)(n.li,{children:["the special file ",(0,s.jsx)(n.code,{children:"/proc/sys/kernel/random/entropy_avail"})," does not contain\nthe value 256 (pinned since kernel 5.18),"]}),"\n",(0,s.jsxs)(n.li,{children:["the number of FIPS 140-2 failures exceeds 3 out of 1000 blocks\ntested, as determined by ",(0,s.jsx)(n.code,{children:"cat /dev/random | rngtest -c 1000"})," ."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Note: The latter two items act as surrogates for the following item, which\ncannot be detected directly:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"CPU instructions for accessing entropy are not available to the VMs."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"warnings",children:"Warnings"}),"\n",(0,s.jsx)(n.p,{children:"The following items MUST be detected and reported as a warning:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["any flavor missing the attribute ",(0,s.jsx)(n.code,{children:"hw_rng:allowed=True"}),","]}),"\n",(0,s.jsxs)(n.li,{children:["any image missing the attribute ",(0,s.jsx)(n.code,{children:"hw_rng_model: virtio"}),","]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Note that the requirement regarding the kernel patch level will not be\nchecked, because of two reasons: (a) we already check the file ",(0,s.jsx)(n.code,{children:"entropy_avail"}),"\n(see subsection on Errors), and (b) users can always choose a recent image,\nas ensured by the image metadata standard."]}),"\n",(0,s.jsx)(n.h3,{id:"implementation-1",children:"Implementation"}),"\n",(0,s.jsxs)(n.p,{children:["The script ",(0,s.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/entropy/entropy-check.py",children:(0,s.jsx)(n.code,{children:"entropy-check.py"})}),"\nconnects to OpenStack and performs the checks described in this section."]}),"\n",(0,s.jsx)(n.h2,{id:"manual-tests",children:"Manual Tests"}),"\n",(0,s.jsx)(n.p,{children:"None."})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var s=t(96540);const a={},i=s.createContext(a);function r(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bd8a97c5.9b5f1b3b.js b/assets/js/bd8a97c5.9b5f1b3b.js new file mode 100644 index 0000000000..ac8ce4b070 --- /dev/null +++ b/assets/js/bd8a97c5.9b5f1b3b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3536],{8942:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>p,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var t=o(74848),i=o(28453);const r={sidebar_label:"Proxy",sidebar_position:15},s="Proxy",a={id:"iaas/guides/configuration-guide/proxy",title:"Proxy",description:"In the following examples, it is assumed that the Squid proxy integrated by OSISM",source:"@site/docs/02-iaas/guides/configuration-guide/proxy.md",sourceDirName:"02-iaas/guides/configuration-guide",slug:"/iaas/guides/configuration-guide/proxy",permalink:"/docs/iaas/guides/configuration-guide/proxy",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/proxy.md",tags:[],version:"current",sidebarPosition:15,frontMatter:{sidebar_label:"Proxy",sidebar_position:15},sidebar:"docs",previous:{title:"Network",permalink:"/docs/iaas/guides/configuration-guide/network"},next:{title:"Loadbalancer",permalink:"/docs/iaas/guides/configuration-guide/loadbalancer"}},d={},c=[{value:"Docker",id:"docker",level:2},{value:"APT",id:"apt",level:2},{value:"Kolla",id:"kolla",level:2}];function l(e){const n={code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"proxy",children:"Proxy"}),"\n",(0,t.jsx)(n.p,{children:"In the following examples, it is assumed that the Squid proxy integrated by OSISM\nis used on the first manager node. Any other proxy accessible from the nodes can\nalso be used here."}),"\n",(0,t.jsx)(n.p,{children:"The Squid service can be deployed on the first manager. This is useful if no proxy\ncan be used in the environment. The first manager node is then used by all other nodes\nas a pass-through node. Please note that this is not a caching proxy or even an air gap.\nThis is also possible with OSISM, but not with the help of the Squid service."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply squid\n"})}),"\n",(0,t.jsx)(n.h2,{id:"docker",children:"Docker"}),"\n",(0,t.jsx)(n.p,{children:"This allows Docker images to be pulled via a proxy."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:'##########################################################\n# proxy\n\ndocker_configure_proxy: true\ndocker_proxy_http: "http://{{ groups[\'manager\'][0] }}:3128"\ndocker_proxy_https: "{{ docker_proxy_http }}"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"apt",children:"APT"}),"\n",(0,t.jsx)(n.p,{children:"This allows APT packages to be downloaded via a proxy."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/configuration.yml"',children:"##########################################################\n# proxy\n\nproxy_proxies:\n http: \"http://{{ groups['manager'][0] }}:3128\"\n https: \"http://{{ groups['manager'][0] }}:3128\"\n"})}),"\n",(0,t.jsx)(n.h2,{id:"kolla",children:"Kolla"}),"\n",(0,t.jsx)(n.p,{children:"Proxy settings for containers such as magnum that need internet access."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'##########################################################\n# proxy\n\ncontainer_http_proxy: "http://{{ groups[\'manager\'][0] }}:3128"\ncontainer_https_proxy: "http://{{ groups[\'manager\'][0] }}:3128"\ncontainer_no_proxy: "localhost,127.0.0.1"\n'})})]})}function p(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>s,x:()=>a});var t=o(96540);const i={},r=t.createContext(i);function s(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bdaaff35.5ff36000.js b/assets/js/bdaaff35.5ff36000.js new file mode 100644 index 0000000000..1cf0d5c349 --- /dev/null +++ b/assets/js/bdaaff35.5ff36000.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9063],{47022:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>r,toc:()=>u});var n=s(74848),i=s(28453);const o={sidebar_label:"OpenStack"},a="OpenStack",r={id:"iaas/guides/user-guide/openstack/index",title:"OpenStack",description:"",source:"@site/docs/02-iaas/guides/user-guide/openstack/index.md",sourceDirName:"02-iaas/guides/user-guide/openstack",slug:"/iaas/guides/user-guide/openstack/",permalink:"/docs/iaas/guides/user-guide/openstack/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/openstack/index.md",tags:[],version:"current",frontMatter:{sidebar_label:"OpenStack"},sidebar:"docs",previous:{title:"Migrate from VMware ESXi to OpenStack",permalink:"/docs/iaas/guides/user-guide/migration-vmware-esix"},next:{title:"Security groups",permalink:"/docs/iaas/guides/user-guide/openstack/security-groups"}},c={},u=[];function d(e){const t={h1:"h1",...(0,i.R)(),...e.components};return(0,n.jsx)(t.h1,{id:"openstack",children:"OpenStack"})}function p(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>r});var n=s(96540);const i={},o=n.createContext(i);function a(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bdcb5fea.edcff60b.js b/assets/js/bdcb5fea.edcff60b.js new file mode 100644 index 0000000000..805b03958c --- /dev/null +++ b/assets/js/bdcb5fea.edcff60b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[462],{53208:e=>{e.exports=JSON.parse('{"title":"Guides","slug":"/category/guides-2","permalink":"/docs/category/guides-2","navigation":{"previous":{"title":"Introduction on Identity Management and Federation in SCS","permalink":"/docs/iam/"},"next":{"title":"Domain Manager setup and usage","permalink":"/docs/iam/domain-manager-setup-and-usage"}}}')}}]); \ No newline at end of file diff --git a/assets/js/be01f2a0.c8c515a3.js b/assets/js/be01f2a0.c8c515a3.js new file mode 100644 index 0000000000..d76f50a30f --- /dev/null +++ b/assets/js/be01f2a0.c8c515a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9954],{84789:(e,a,n)=>{n.r(a),n.d(a,{assets:()=>s,contentTitle:()=>o,default:()=>l,frontMatter:()=>d,metadata:()=>t,toc:()=>m});var r=n(74848),i=n(28453);const d={sidebar_label:"Keystone"},o="Keystone",t={id:"iaas/guides/configuration-guide/openstack/keystone",title:"Keystone",description:"* Keystone admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/keystone.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/keystone",permalink:"/docs/iaas/guides/configuration-guide/openstack/keystone",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/keystone.md",tags:[],version:"current",frontMatter:{sidebar_label:"Keystone"},sidebar:"docs",previous:{title:"Ironic",permalink:"/docs/iaas/guides/configuration-guide/openstack/ironic"},next:{title:"Magnum",permalink:"/docs/iaas/guides/configuration-guide/openstack/magnum"}},s={},m=[{value:"Domain manager policy",id:"domain-manager-policy",level:2},{value:"OIDC Federation",id:"oidc-federation",level:2}];function _(e){const a={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(a.h1,{id:"keystone",children:"Keystone"}),"\n",(0,r.jsxs)(a.ul,{children:["\n",(0,r.jsx)(a.li,{children:(0,r.jsx)(a.a,{href:"https://docs.openstack.org/keystone/latest/admin/index.html",children:"Keystone admin guide"})}),"\n",(0,r.jsx)(a.li,{children:(0,r.jsx)(a.a,{href:"https://docs.openstack.org/keystone/latest/configuration/index.html",children:"Keystone configuration reference"})}),"\n"]}),"\n",(0,r.jsx)(a.h2,{id:"domain-manager-policy",children:"Domain manager policy"}),"\n",(0,r.jsx)(a.p,{children:(0,r.jsx)(a.strong,{children:"This policy is currently still in draft status. Its use in production is currently not recommended."})}),"\n",(0,r.jsxs)(a.table,{children:[(0,r.jsx)(a.thead,{children:(0,r.jsxs)(a.tr,{children:[(0,r.jsx)(a.th,{style:{textAlign:"left"},children:"SCS Standard Track"}),(0,r.jsx)(a.th,{style:{textAlign:"left"},children:"SCS Standard"}),(0,r.jsx)(a.th,{style:{textAlign:"left"},children:"SCS Documentation"})]})}),(0,r.jsx)(a.tbody,{children:(0,r.jsxs)(a.tr,{children:[(0,r.jsx)(a.td,{style:{textAlign:"left"},children:(0,r.jsx)(a.a,{href:"https://docs.scs.community/standards/iam/",children:"IAM"})}),(0,r.jsx)(a.td,{style:{textAlign:"left"},children:(0,r.jsx)(a.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0302-v1-domain-manager-role.md",children:"scs-0302"})}),(0,r.jsx)(a.td,{style:{textAlign:"left"},children:(0,r.jsx)(a.a,{href:"https://docs.scs.community/standards/scs-0302-v1-domain-manager-role/",children:"Domain Manager configuration for Keystone"})})]})})]}),"\n",(0,r.jsxs)(a.p,{children:["To configure and use the domain manager role from the SCS project, the\n",(0,r.jsx)(a.code,{children:"environments/kolla/files/overlays/keystone/policy.yaml"})," file is created\nin the configuration repository. The deployment and upgrade of the Keystone\nservice itself is then done as usual."]}),"\n",(0,r.jsx)(a.pre,{children:(0,r.jsx)(a.code,{className:"language-yaml",metastring:'title="environments/kolla/files/overlays/keystone/policy.yaml"',children:'---\n# SCS Domain Manager policy configuration\n\n# Section A: OpenStack base definitons\n# The entries beginning with "base_<rule>" should be exact copies of the\n# default "identity:<rule>" definitions for the target OpenStack release.\n# They will be extended upon for the domain manager role below this section.\n"base_get_domain": "(role:reader and system_scope:all) or token.domain.id:%(target.domain.id)s or token.project.domain.id:%(target.domain.id)s"\n"base_list_domains": "(role:reader and system_scope:all)"\n"base_list_roles": "(role:reader and system_scope:all)"\n"base_get_role": "(role:reader and system_scope:all)"\n"base_list_users": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"\n"base_get_user": "(role:reader and system_scope:all) or (role:reader and token.domain.id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"\n"base_create_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"\n"base_update_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"\n"base_delete_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"\n"base_list_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"\n"base_get_project": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.project.domain_id)s) or project_id:%(target.project.id)s"\n"base_create_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"\n"base_update_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"\n"base_delete_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"\n"base_list_user_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"\n"base_check_grant": "(role:reader and system_scope:all) or ((role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"\n"base_list_grants": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)"\n"base_create_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"\n"base_revoke_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"\n"base_list_role_assignments": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"\n"base_list_groups": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"\n"base_get_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"\n"base_create_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"\n"base_update_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"\n"base_delete_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"\n"base_list_groups_for_user": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(user_id)s"\n"base_list_users_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"\n"base_remove_user_from_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"\n"base_check_user_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"\n"base_add_user_to_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"\n\n# Section B: Domain Manager Extensions\n\n# classify domain managers with a special role\n"is_domain_manager": "role:manager"\n\n# specify a rule that whitelists roles which domain admins are permitted\n# to assign and revoke within their domain\n"is_domain_managed_role": "\'member\':%(target.role.name)s or \'load-balancer_member\':%(target.role.name)s or \'creator\':%(target.role.name)s"\n\n# allow domain admins to retrieve their own domain (does not need changes)\n"identity:get_domain": "rule:base_get_domain or rule:admin_required"\n\n# list_domains is needed for GET /v3/domains?name=... requests\n# this is mandatory for things like\n# `create user --domain $DOMAIN_NAME $USER_NAME` to correctly discover\n# domains by name\n"identity:list_domains": "rule:is_domain_manager or rule:base_list_domains or rule:admin_required"\n\n# list_roles is needed for GET /v3/roles?name=... requests\n# this is mandatory for things like `role add ... $ROLE_NAME`` to correctly\n# discover roles by name\n"identity:list_roles": "rule:is_domain_manager or rule:base_list_roles or rule:admin_required"\n\n# get_role is needed for GET /v3/roles/{role_id} requests\n# this is mandatory for the OpenStack SDK to properly process role assignments\n# which are issued by role id instead of name\n"identity:get_role": "(rule:is_domain_manager and rule:is_domain_managed_role) or rule:base_get_role or rule:admin_required"\n\n# allow domain admins to manage users within their domain\n"identity:list_users": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_users or rule:admin_required"\n"identity:get_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_get_user or rule:admin_required"\n"identity:create_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_create_user or rule:admin_required"\n"identity:update_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_update_user or rule:admin_required"\n"identity:delete_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_delete_user or rule:admin_required"\n\n# allow domain admins to manage projects within their domain\n"identity:list_projects": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_projects or rule:admin_required"\n"identity:get_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_get_project or rule:admin_required"\n"identity:create_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_create_project or rule:admin_required"\n"identity:update_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_update_project or rule:admin_required"\n"identity:delete_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_delete_project or rule:admin_required"\n"identity:list_user_projects": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_user_projects or rule:admin_required"\n\n# allow domain managers to manage role assignments within their domain\n# (restricted to specific roles by the \'is_domain_managed_role\' rule)\n#\n# project-level role assignment to user within domain\n"is_domain_user_project_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s"\n# project-level role assignment to group within domain\n"is_domain_group_project_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.project.domain_id)s"\n# domain-level role assignment to group\n"is_domain_level_group_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.domain.id)s"\n# domain-level role assignment to user\n"is_domain_level_user_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.domain.id)s"\n"domain_manager_grant": "rule:is_domain_manager and (rule:is_domain_user_project_grant or rule:is_domain_group_project_grant or rule:is_domain_level_group_grant or rule:is_domain_level_user_grant)"\n"identity:check_grant": "rule:domain_manager_grant or rule:base_check_grant or rule:admin_required"\n"identity:list_grants": "rule:domain_manager_grant or rule:base_list_grants or rule:admin_required"\n"identity:create_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_create_grant or rule:admin_required"\n"identity:revoke_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_revoke_grant or rule:admin_required"\n"identity:list_role_assignments": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_role_assignments or rule:admin_required"\n\n\n# allow domain managers to manage groups within their domain\n"identity:list_groups": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_list_groups or rule:admin_required"\n"identity:get_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_get_group or rule:admin_required"\n"identity:create_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_create_group or rule:admin_required"\n"identity:update_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_update_group or rule:admin_required"\n"identity:delete_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_delete_group or rule:admin_required"\n"identity:list_groups_for_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_groups_for_user or rule:admin_required"\n"identity:list_users_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_list_users_in_group or rule:admin_required"\n"identity:remove_user_from_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_remove_user_from_group or rule:admin_required"\n"identity:check_user_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_check_user_in_group or rule:admin_required"\n"identity:add_user_to_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_add_user_to_group or rule:admin_required"\n'})}),"\n",(0,r.jsxs)(a.p,{children:["The role ",(0,r.jsx)(a.code,{children:"manager"})," is created using the OpenStack CLI. Alternatively, the role can\nbe added using Ansible or other tools."]}),"\n",(0,r.jsx)(a.pre,{children:(0,r.jsx)(a.code,{children:'$ openstack --os-cloud admin \\\n role create \\\n --or-show \\\n --description "Domain Manager Role" \\\n manager\n+-------------+----------------------------------+\n| Field | Value |\n+-------------+----------------------------------+\n| description | Domain Manager Role |\n| domain_id | None |\n| id | 9b7140bfe628468ab9b86b365f9ac4c2 |\n| name | manager |\n| options | {} |\n+-------------+----------------------------------+\n'})}),"\n",(0,r.jsx)(a.p,{children:"A user can then be made a domain manager for a particular domain by assigning this role."}),"\n",(0,r.jsx)(a.pre,{children:(0,r.jsx)(a.code,{children:"$ openstack --os-cloud admin \\\n role add \\\n --user test \\\n --domain test \\\n manager\n"})}),"\n",(0,r.jsx)(a.h2,{id:"oidc-federation",children:"OIDC Federation"})]})}function l(e={}){const{wrapper:a}={...(0,i.R)(),...e.components};return a?(0,r.jsx)(a,{...e,children:(0,r.jsx)(_,{...e})}):_(e)}},28453:(e,a,n)=>{n.d(a,{R:()=>o,x:()=>t});var r=n(96540);const i={},d=r.createContext(i);function o(e){const a=r.useContext(d);return r.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function t(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(d.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/befb6565.9fd54aac.js b/assets/js/befb6565.9fd54aac.js new file mode 100644 index 0000000000..c1f276c64d --- /dev/null +++ b/assets/js/befb6565.9fd54aac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7020],{73607:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>s,default:()=>l,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var i=n(74848),a=n(28453);const o={sidebar_label:"Heat"},s="Heat",c={id:"iaas/guides/configuration-guide/openstack/heat",title:"Heat",description:"* Heat admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/heat.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/heat",permalink:"/docs/iaas/guides/configuration-guide/openstack/heat",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/heat.md",tags:[],version:"current",frontMatter:{sidebar_label:"Heat"},sidebar:"docs",previous:{title:"Glance",permalink:"/docs/iaas/guides/configuration-guide/openstack/glance"},next:{title:"Horizon",permalink:"/docs/iaas/guides/configuration-guide/openstack/horizon"}},r={},d=[];function u(e){const t={a:"a",h1:"h1",li:"li",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"heat",children:"Heat"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://docs.openstack.org/heat/latest/admin/index.html",children:"Heat admin guide"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://docs.openstack.org/heat/latest/configuration/index.html",children:"Heat configuration reference"})}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var i=n(96540);const a={},o=i.createContext(a);function s(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c0cd111c.b093c63e.js b/assets/js/c0cd111c.b093c63e.js new file mode 100644 index 0000000000..c34a174428 --- /dev/null +++ b/assets/js/c0cd111c.b093c63e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8477],{88549:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>l,frontMatter:()=>s,metadata:()=>c,toc:()=>u});var n=o(74848),r=o(28453);const s={},a="Storage",c={id:"iaas/overview/storage",title:"Storage",description:"TODO",source:"@site/docs/02-iaas/overview/storage.md",sourceDirName:"02-iaas/overview",slug:"/iaas/overview/storage",permalink:"/docs/iaas/overview/storage",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/overview/storage.md",tags:[],version:"current",frontMatter:{}},i={},u=[];function d(e){const t={h1:"h1",p:"p",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"storage",children:"Storage"}),"\n",(0,n.jsx)(t.p,{children:"TODO"})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,o)=>{o.d(t,{R:()=>a,x:()=>c});var n=o(96540);const r={},s=n.createContext(r);function a(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c0e025b3.ecc43a90.js b/assets/js/c0e025b3.ecc43a90.js new file mode 100644 index 0000000000..6d354b1659 --- /dev/null +++ b/assets/js/c0e025b3.ecc43a90.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2179],{23401:(e,t,l)=>{l.r(t),l.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>x,frontMatter:()=>n,metadata:()=>d,toc:()=>o});var i=l(74848),s=l(28453);const n={sidebar_label:"Tuned"},r="Tuned",d={id:"iaas/guides/configuration-guide/services/tuned",title:"Tuned",description:"The roller can be applied with osism apply tuned. The role is applied to all",source:"@site/docs/02-iaas/guides/configuration-guide/services/tuned.md",sourceDirName:"02-iaas/guides/configuration-guide/services",slug:"/iaas/guides/configuration-guide/services/tuned",permalink:"/docs/iaas/guides/configuration-guide/services/tuned",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/services/tuned.md",tags:[],version:"current",frontMatter:{sidebar_label:"Tuned"},sidebar:"docs",previous:{title:"Docker",permalink:"/docs/iaas/guides/configuration-guide/services/docker"},next:{title:"Validations",permalink:"/docs/iaas/guides/configuration-guide/validations/"}},c={},o=[];function a(e){const t={code:"code",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"tuned",children:"Tuned"}),"\n",(0,i.jsxs)(t.p,{children:["The roller can be applied with ",(0,i.jsx)(t.code,{children:"osism apply tuned"}),". The role is applied to all\ncompute nodes by default. This can be changed via the ",(0,i.jsx)(t.code,{children:"hosts_tuned"})," parameter."]}),"\n",(0,i.jsxs)(t.p,{children:["The profile to be used can be set via ",(0,i.jsx)(t.code,{children:"tuned_profile"}),". By default, ",(0,i.jsx)(t.code,{children:"virtual-host"}),"\nis used."]}),"\n",(0,i.jsx)(t.p,{children:"The following profiles are available:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{style:{textAlign:"left"},children:"Profile"}),(0,i.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"accelerator-performance"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Throughput performance based tuning with disabled higher latency STOP states"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"atomic-guest"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize virtual guests based on the Atomic variant"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"atomic-host"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize bare metal systems running the Atomic variant"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"balanced"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"General non-specialized tuned profile"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"cpu-partitioning"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for CPU partitioning"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"default"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Legacy default tuned profile"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"desktop"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for the desktop use-case"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"desktop-powersave"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optmize for the desktop use-case with power saving"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"enterprise-storage"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Legacy profile for RHEL6, for RHEL7, please use throughput-performance profile"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"hpc-compute"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for HPC compute workloads"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"intel-sst"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Configure for Intel Speed Select Base Frequency"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"laptop-ac-powersave"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for laptop with power savings"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"laptop-battery-powersave"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize laptop profile with more aggressive power saving"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"latency-performance"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for deterministic performance at the cost of increased power consumption"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"mssql"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for MS SQL Server"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"network-latency"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for deterministic performance at the cost of increased power consumption, focused on low latency network performance"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"network-throughput"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for streaming network throughput, generally only necessary on older CPUs or 40G+ networks"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"optimize-serial-console"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for serial console use."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"oracle"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for Oracle RDBMS"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"postgresql"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for PostgreSQL server"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"powersave"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for low power consumption"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"realtime"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for realtime workloads"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"sap-hana"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for SAP HANA"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"sap-netweaver"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for SAP NetWeaver"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"server-powersave"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for server power savings"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"spectrumscale-ece"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimized for Spectrum Scale Erasure Code Edition Servers"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"spindown-disk"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for power saving by spinning-down rotational disks"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"throughput-performance"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Broadly applicable tuning that provides excellent performance across a variety of common server workloads"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"virtual-guest"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for running inside a virtual guest"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"virtual-host"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"Optimize for running KVM guests"})]})]})]})]})}function x(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,t,l)=>{l.d(t,{R:()=>r,x:()=>d});var i=l(96540);const s={},n=i.createContext(s);function r(e){const t=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c2f44c5f.78af2a24.js b/assets/js/c2f44c5f.78af2a24.js new file mode 100644 index 0000000000..c8232b48da --- /dev/null +++ b/assets/js/c2f44c5f.78af2a24.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[660],{98262:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var o=n(74848),s=n(28453);const a={sidebar_label:"OpenStack",sidebar_position:40},i="OpenStack",r={id:"iaas/guides/troubleshooting-guide/openstack",title:"OpenStack",description:"Database creation fails",source:"@site/docs/02-iaas/guides/troubleshooting-guide/openstack.md",sourceDirName:"02-iaas/guides/troubleshooting-guide",slug:"/iaas/guides/troubleshooting-guide/openstack",permalink:"/docs/iaas/guides/troubleshooting-guide/openstack",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/troubleshooting-guide/openstack.md",tags:[],version:"current",sidebarPosition:40,frontMatter:{sidebar_label:"OpenStack",sidebar_position:40},sidebar:"docs",previous:{title:"Manager",permalink:"/docs/iaas/guides/troubleshooting-guide/manager"},next:{title:"Ceph",permalink:"/docs/iaas/guides/troubleshooting-guide/ceph"}},c={},d=[{value:"Database creation fails",id:"database-creation-fails",level:2}];function l(e){const t={code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"openstack",children:"OpenStack"}),"\n",(0,o.jsx)(t.h2,{id:"database-creation-fails",children:"Database creation fails"}),"\n",(0,o.jsx)(t.p,{children:"Problem:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{children:"TASK [keystone : Creating keystone database] ***********************************\nfatal: [testbed-node-0]: FAILED! => changed=false\n action: mysql_db\n msg: 'unable to find /var/lib/ansible/.my.cnf. Exception message: (2003, \"Can''t connect to MySQL server on ''api-int.local'' ([Errno 111] Connection refused)\")'\n"})}),"\n",(0,o.jsx)(t.p,{children:"Solution:"}),"\n",(0,o.jsxs)(t.p,{children:["Restart the ",(0,o.jsx)(t.code,{children:"kolla_toolbox"})," container. in this case on the node ",(0,o.jsx)(t.code,{children:"testbed-node-0"}),"."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{children:"$ osism console testbed-node-0/\ntestbed-node-0>>> restart kolla_toolbox\nkolla_toolbox\ntestbed-node-0>>>\n"})})]})}function u(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var o=n(96540);const s={},a=o.createContext(s);function i(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c3529e0a.3b179dfc.js b/assets/js/c3529e0a.3b179dfc.js new file mode 100644 index 0000000000..36dd8f7d53 --- /dev/null +++ b/assets/js/c3529e0a.3b179dfc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6871],{72270:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>h,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var n=s(74848),o=s(28453);const r={title:"Using Sonobuoy for KaaS conformance tests",type:"Decision Record",status:"Draft",track:"KaaS"},i=void 0,a={id:"scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests",title:"Using Sonobuoy for KaaS conformance tests",description:"Motivation",source:"@site/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests.md",sourceDirName:".",slug:"/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests",permalink:"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Using Sonobuoy for KaaS conformance tests",type:"Decision Record",status:"Draft",track:"KaaS"},sidebar:"standards",previous:{title:"scs-0200: Using Sonobuoy for KaaS conformance tests",permalink:"/standards/kaas/scs-0200"},next:{title:"scs-0210: SCS K8S Version Policy",permalink:"/standards/kaas/scs-0210"}},h={},c=[{value:"Motivation",id:"motivation",level:2},{value:"Short Sonobuoy Introduction",id:"short-sonobuoy-introduction",level:3},{value:"Design Considerations",id:"design-considerations",level:2},{value:"<em>Option 1</em> Golang based approach 1: Pick a framework from the Sonobuoy plugin examples",id:"option-1-golang-based-approach-1-pick-a-framework-from-the-sonobuoy-plugin-examples",level:3},{value:"<em>Option 2</em> Golang based approach 2: Reuse the Kubernetes own e2e test infrastructure and framework",id:"option-2-golang-based-approach-2-reuse-the-kubernetes-own-e2e-test-infrastructure-and-framework",level:3},{value:"<em>Option 3</em> Write Python scripts for tests",id:"option-3-write-python-scripts-for-tests",level:3},{value:"Approaches to providing a Sonobuoy plugin image",id:"approaches-to-providing-a-sonobuoy-plugin-image",level:2},{value:"<em>Option 1</em> Public container registry",id:"option-1-public-container-registry",level:3},{value:"<em>Option 2</em> Local image upload",id:"option-2-local-image-upload",level:3},{value:"Decision",id:"decision",level:2}];function l(e){const t={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,n.jsxs)(t.p,{children:["With the ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"k8s-cluster-api-provider"}),", the SCS provides a tool to generate\nand manage k8s clusters on top of its IaaS infrastructure. As part of\nthe application, ",(0,n.jsx)(t.a,{href:"https://sonobuoy.io/",children:"Sonobuoy"})," is used as a test suite to execute the\nofficial ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes e2e tests"}),".\nWe expect that current and future tests derived from SCS standards\nwill benefit from (or even require) the testing mechanisms that Sonobuoy provides."]}),"\n",(0,n.jsxs)(t.p,{children:["Apart from running the Kubernetes e2e tests, Sonobuoy also allows users to write\ntheir own tests and apply them as a self-managed ",(0,n.jsx)(t.a,{href:"https://sonobuoy.io/docs/main/plugins/",children:"plugin"}),".\nAll tests not provided by the ",(0,n.jsx)(t.a,{href:"https://sonobuoy.io/docs/main/e2eplugin/",children:"e2e test plugin"})," could therefore\nbe written by the respective SCS teams responsible for the standards or tests and\nthen be made executable with Sonobuoy. Hence, Sonobuoy could provide both a pre-done\ntest suite and a framework to write additional conformance tests required for SCS."]}),"\n",(0,n.jsx)(t.h3,{id:"short-sonobuoy-introduction",children:"Short Sonobuoy Introduction"}),"\n",(0,n.jsxs)(t.p,{children:["The main objective of ",(0,n.jsx)(t.a,{href:"https://sonobuoy.io/docs/main/plugins/",children:"Sonobuoy plugins"}),' is to present test\nresults in a consolidated way. To do this, Sonobuoy integrates the test into a pod,\nwhich is then applied to the K8s cluster under test. A Sonobuoy worker supervises\nthis pod and forwards all test results to the aggregator module. It does this by\nwaiting for a specific "Done" file to be created. Once this file is recognized,\nthe worker forwards the results to the aggregator, using a predefined location\nfor the results file within a folder, as seen in following image:\n',(0,n.jsx)(t.img,{src:"https://sonobuoy.io/img/plugin-contract.png",alt:"image search api"})]}),"\n",(0,n.jsx)(t.p,{children:"In order to use the existing conformance tests as a Sonobuoy plugin, a wrapper\naround the individual test scripts would be required. This wrapper would need to\nhave the following effects:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"gathers all test results and provides them in the results file"}),"\n",(0,n.jsx)(t.li,{children:'run tests in sequence and signal the worker when it\'s finished by generating a "Done" file'}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"Apart from providing the test results, a plugin container must also forward the\nstatus of each test by setting a status flag in the results file.\nAdditionally, the tests would need to be able to run inside a pod in the K8s cluster under test."}),"\n",(0,n.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,n.jsx)(t.p,{children:"There are different approaches to create a Sonobuoy plugin, which are discussed\nbelow in order to find a best practice for the SCS project. The documented approaches\nshow one example each in order to give a better representation to the reader."}),"\n",(0,n.jsxs)(t.p,{children:["Sonobuoy provides plugin examples in the ",(0,n.jsx)(t.a,{href:"https://github.com/vmware-tanzu/sonobuoy-plugins",children:"plugins repository"}),",\nwhich are referenced throughout this section."]}),"\n",(0,n.jsxs)(t.h3,{id:"option-1-golang-based-approach-1-pick-a-framework-from-the-sonobuoy-plugin-examples",children:[(0,n.jsx)(t.em,{children:"Option 1"})," Golang based approach 1: Pick a framework from the Sonobuoy plugin examples"]}),"\n",(0,n.jsxs)(t.p,{children:["The seemingly most interesting plugin is the ",(0,n.jsx)(t.a,{href:"https://github.com/vmware-tanzu/sonobuoy-plugins/tree/main/examples/e2e-skeleton",children:"e2e-skeleton"}),", which uses\nthe ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework",children:"kubernetes-sigs/e2e-framework"}),". The ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework",children:"kubernetes-sigs/e2e-framework"}),"\nis a stand-alone project that is separate from the official ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes e2e tests"}),'.\nThe framework provides proper documentation as well as helper functions that abstract\nclient functionalities, similar to those found in "kubernetes/kubernetes/test/e2e/framework" repository.']}),"\n",(0,n.jsxs)(t.p,{children:["As mentioned in the ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework/blob/main/docs/design/README.md#motivations",children:"motivation"})," of the ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework",children:"e2e-framework"}),",\nthe project was created to circumvent the disadvantages of ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes' own e2e-tests"}),",\nwhich are described in more detail in the ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework/blob/main/docs/design/README.md#goals",children:"goals"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"PROS:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["arguments in favor of this framework can also be found under the ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework/blob/main/docs/design/README.md#goals",children:"goals description"})," of the documentation"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework",children:"e2e-framework"})," is a well-defined framework, that allows the handling of resource creation and deletion"]}),"\n",(0,n.jsx)(t.li,{children:'official framework provided by "Kubernetes-sigs"'}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"CONS:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["arguments not in favor of this framework can be derived from the ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework/blob/main/docs/design/README.md#non-goals",children:"Non-Goals"})," description of the documentation:","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:'"no responsibility for bootstrapping or the execution of the tests themselves" can be ignored, as this is partly taken over by Sonobuoy'}),"\n",(0,n.jsx)(t.li,{children:'"no mock or fake cluster components" can be ignored, since the e2e tests of SCS should be used to test real clusters and their functionality'}),"\n",(0,n.jsx)(t.li,{children:"for this test procedure, the Sonobuoy e2e plugin should be run in addition to the SCS KaaS conformance tests"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsxs)(t.p,{children:["proof of concept: ",(0,n.jsx)(t.code,{children:"../Tests/kaas/kaas-sonobuoy-go-example-e2e-framework/"})]}),"\n"]}),"\n",(0,n.jsxs)(t.h3,{id:"option-2-golang-based-approach-2-reuse-the-kubernetes-own-e2e-test-infrastructure-and-framework",children:[(0,n.jsx)(t.em,{children:"Option 2"})," Golang based approach 2: Reuse the Kubernetes own e2e test infrastructure and framework"]}),"\n",(0,n.jsx)(t.p,{children:"The existing Sonobuoy e2e plugin already provides a vast number of tests that could\nbe adapted or reused for the SCS project."}),"\n",(0,n.jsxs)(t.p,{children:["If these e2e tests are to be reused in a customized structure, a framework like ",(0,n.jsx)(t.a,{href:"https://onsi.github.io/ginkgo/",children:"ginkgo"}),"\nmust be used as it is used by the Kubernetes e2e test infrastructure.\nThis could use the implementation of the build process responsible for the Docker\nimage containing the e2e tests. The setup could be copied from ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/conformance/image",children:"kubernetes/test/conformance/image"}),"\nand adapted to the projects requirements. The mentioned build process must use the\nfiles of the following directories from the Kubernetes repository:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/cluster",children:"kubernetes/cluster"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"kubernetes/test/e2e/framework"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/conformance/image/go-runner",children:"kubernetes/test/conformance/image/go-runner"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/hack/conformance",children:"kubernetes/hack/conformance"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/hack/make-rules",children:"kubernetes/hack/make-rules"})}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"PROS:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes' own e2e tests"})," already provide a vast amount of examples, which could be reused to develop specific SCS tests"]}),"\n",(0,n.jsxs)(t.li,{children:["compared to ",(0,n.jsx)(t.em,{children:"option 1"}),", the ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework/blob/main/docs/design/README.md#non-goals",children:"non-goals"})," of the ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework",children:"e2e-framework"})," can be seen as the advantages of using ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes' own e2e-tests"}),"."]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"CONS:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"not easy to implement, as we would have to copy part of the Kubernetes repository and track the changes from the upstream"}),"\n",(0,n.jsxs)(t.li,{children:["according to ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/cluster#readme",children:"README.md"}),", part of it seems to be outdated and might change with a future version","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["compared to ",(0,n.jsx)(t.em,{children:"option 1"}),", the ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework/blob/main/docs/design/README.md#goals",children:"goals"})," of the ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes-sigs/e2e-framework",children:"e2e-framework"})," can be seen as the disadvantages of using ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes' own e2e-tests"}),"."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsxs)(t.p,{children:["TODO: provide proof of concept: ",(0,n.jsx)(t.em,{children:"kaas-sonobuoy-go-example-k8s-e2e"})]}),"\n"]}),"\n",(0,n.jsxs)(t.h3,{id:"option-3-write-python-scripts-for-tests",children:[(0,n.jsx)(t.em,{children:"Option 3"})," Write Python scripts for tests"]}),"\n",(0,n.jsx)(t.p,{children:"Sonobuoy makes it possible to write tests in Python and execute them like other\ntests in a pod on the K8s cluster. It would therefore be possible to keep on writing\nconformance tests in Python."}),"\n",(0,n.jsx)(t.p,{children:'This option would require a wrapper in order to make the tests scripts executable\nas Sonobuoy plugins. This wrapper, as mentioned earlier, would need to capture\nthe collection of test results as well as the generation of the "Done" file after\nthe test execution is finished. This could be managed by executing each test script\nin a sequential order.'}),"\n",(0,n.jsx)(t.p,{children:"The wrapper as well as the python tests and test framework could then be stored\nin a container image and uploaded to a registry in order to be usable by Sonobuoy\nwithin the k8s-cluster-api-provider."}),"\n",(0,n.jsx)(t.p,{children:"This approach also leaves the decision open as to which test framework should be\nused for Python, which should be decided in a secondary Decision Record."}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsxs)(t.p,{children:["proof of work: ",(0,n.jsx)(t.code,{children:"../Tests/kaas/k8s-default-storage-class"})]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"PROS:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["continue using the already available Python tests","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"only a small number of tests is implemented thus far"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"CONS:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:'no "native" support in Sonobuoy, a wrapper is needed'}),"\n",(0,n.jsx)(t.li,{children:"decision for a framework is still not done"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"approaches-to-providing-a-sonobuoy-plugin-image",children:"Approaches to providing a Sonobuoy plugin image"}),"\n",(0,n.jsxs)(t.p,{children:["The following section showcases both ways to provide a Sonobuoy plugin image.\n",(0,n.jsx)(t.em,{children:"Option 1"})," would most likely be used, if an image is published to be used by an end user.\n",(0,n.jsx)(t.em,{children:"Option 2"})," is the expected way for local development and testing."]}),"\n",(0,n.jsxs)(t.h3,{id:"option-1-public-container-registry",children:[(0,n.jsx)(t.em,{children:"Option 1"})," Public container registry"]}),"\n",(0,n.jsx)(t.p,{children:"The image can be made available via a public container registry, which would require\na regular job (e.g. CI/CD) to build and publish the image."}),"\n",(0,n.jsxs)(t.h3,{id:"option-2-local-image-upload",children:[(0,n.jsx)(t.em,{children:"Option 2"})," Local image upload"]}),"\n",(0,n.jsx)(t.p,{children:'Create the image locally on the "clusterctl admin control node" and then upload\nit manually to the Kubernetes cluster under test.'}),"\n",(0,n.jsx)(t.p,{children:'Both approaches are useful in different ways. While the usage of a container registry\nallows easy distribution of tests and guarantees new images through the usage of a\nCI/CD job, it also makes it harder to test changes quickly, since a wait time could be\nnecessary to let the CI/CD job run through and access the image. This can be solved\nby using the "Local image upload" or a combination of both approaches.'}),"\n",(0,n.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,n.jsx)(t.p,{children:"The KaaS conformance test MUST be provided as a test suite holding the\ntest cases for the Kubernetes clusters to be checked.\nFurthermore, the test cases themselves MUST be wrapped by a test framework to:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"handle the creation and deletion of resources"}),"\n",(0,n.jsx)(t.li,{children:"collect and present results"}),"\n",(0,n.jsx)(t.li,{children:"consolidate redundant code across test cases"}),"\n",(0,n.jsx)(t.li,{children:"support the creation of test cases through predefined structures"}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["As with the ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"k8s-cluster-api-provider"})," the SCS provides a tooling to generate\nits KaaS infrastructure. Part of the ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"k8s-cluster-api-provider"})," is the usage\nof Sonobuoy as a test suite to execute the ",(0,n.jsx)(t.a,{href:"https://github.com/kubernetes/kubernetes/tree/master/test/e2e",children:"Kubernetes own e2e tests"}),".\nInvestigating those e2e test lead to the conclusion that they are not always reusable.\nThe main purpose of Kubernetes own e2e tests is to test the functionality of\nthe Kubernetes code itself and not the resources and setup of a specific KaaS infrastructure\nas it is the aim of the SCS KaaS conformance test."]}),"\n",(0,n.jsx)(t.p,{children:"However, considering that the SCS has an ongoing process of defining standards and\nimplementing test cases to check their compliance, that means in some cases future standards\nmight already be covered by the e2e test inside the Kubernetes repository.\nHence, before writing tests, a developer SHOULD check the Kubernetes e2e tests for\nexisting test cases that might cover conformance of a standard currently being worked on."}),"\n",(0,n.jsx)(t.p,{children:"As described above, Sonobuoy offers the possibility to generate custom plugins\nthat provide self-created test cases. Therefore, future conformance tests MUST\nbe executable by Sonobuoy by wrapping them in a Sonobuoy plugin.\nMoreover, three options for the implementation of the SCS KaaS compliance test\ncases are described above so that it can be decided within this decision record which\noptions should be used."}),"\n",(0,n.jsxs)(t.p,{children:['As a first decision, "',(0,n.jsx)(t.em,{children:"Option 2"})," Go Approach 2: Reuse Kubernetes' own e2e test infrastructure and framework\"\nis the least viable, as it would mean copying almost all the files used from\nthe Kubernetes e2e tests. This framework is closely linked to the development of\nthe Kubernetes code. Therefore, changes to its structure mainly are in line with its usage\nin the Kubernetes repository itself and is most likely not relevant for other parties.\nChanges in the framework cloud have a greater impact on our side as they are\npredictable. The development effort gained by reusing these examples could be\noutweighed by the investment necessary to adapt tests to the corresponding framework changes."]}),"\n",(0,n.jsxs)(t.p,{children:['This leaves "',(0,n.jsx)(t.em,{children:"Option 1"}),' Go approach 1: Pick framework from the Sonobuoy plugin examples"\nand "',(0,n.jsx)(t.em,{children:"Option 3"})," Write Python scripts for tests\" as methods for implementing test cases.\nIt is possible to use both approaches in parallel, which would enable usage of both Python\nand Go code. This could possibly generate two Sonobuoy plugins, but this isn't a necessity."]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>a});var n=s(96540);const o={},r=n.createContext(o);function i(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c49f9378.e0e556db.js b/assets/js/c49f9378.e0e556db.js new file mode 100644 index 0000000000..c6aba1af7d --- /dev/null +++ b/assets/js/c49f9378.e0e556db.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[126],{49822:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>f,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var i=s(74848),t=s(28453);const r={sidebar_label:"Simple Stress",sidebar_position:55},o="Simple Stress",a={id:"iaas/components/simple-stress",title:"Simple Stress",description:"Overview",source:"@site/docs/02-iaas/components/simple-stress.md",sourceDirName:"02-iaas/components",slug:"/iaas/components/simple-stress",permalink:"/docs/iaas/components/simple-stress",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/components/simple-stress.md",tags:[],version:"current",sidebarPosition:55,frontMatter:{sidebar_label:"Simple Stress",sidebar_position:55}},l={},d=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Defaults",id:"defaults",level:2},{value:"Usage",id:"usage",level:2},{value:"Config files",id:"config-files",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"simple-stress",children:"Simple Stress"}),"\n",(0,i.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(n.p,{children:"The OpenStack Simple Stress is a small stress test for your Openstack Cluster. You can use it for burnin tests or if you want to monitor your cluster perfomance.\nIt is able to start a predefined amount of Servers in specific networks in parallel and serial and removes them afterwards, so you can test your environment to the limits."}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsx)(n.p,{children:"Prepare to use the Openstack Simple Stress."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"git clone https://github.com/osism/openstack-simple-stress\ncd openstack-simple-stress\npipenv install\npipenv shell\n"})}),"\n",(0,i.jsx)(n.h2,{id:"defaults",children:"Defaults"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"main.py"})," command and his default options while executing the command."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:" --cleanup true\n --cloud simple-stress\n --compute-zone nova\n --debug false\n --delete true\n --flavor SCS-2V-8\n --floating false\n --image Ubuntu 22.04\n --interval 10 (seconds)\n --keypair unset\n --network simple-stress\n --network-zone nova\n --number 1\n --parallel 1\n --prefix simple-stress\n --storage-zone simple-stress\n --timeout 600 (seconds)\n --volume false\n --volume-number 1\n --volume-size 1 (gigabyte)\n --wait true\n"})}),"\n",(0,i.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsxs)(n.p,{children:["There must be a ",(0,i.jsx)(n.code,{children:"clouds.yml"})," and a ",(0,i.jsx)(n.code,{children:"secure.yml"})," file in the directory where the OpenStack Simple Stress will be executed, examples are provided within the git repository."]}),"\n",(0,i.jsx)(n.p,{children:"The cloud profile to be used can be specified via the optional --cloud parameter. By default, the cloud profile with the name simple-stress is used."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python src/main.py -h\nusage: main [-h] [--cleanup] [--cloud CLOUD] [--compute-zone COMPUTE_ZONE] [--config-dir DIR]\n [--config-file PATH] [--debug] [--delete] [--flavor FLAVOR] [--floating] [--image IMAGE]\n [--interval INTERVAL] [--keypair KEYPAIR] [--network NETWORK] [--network-zone NETWORK_ZONE]\n [--nocleanup] [--nodebug] [--nodelete] [--nofloating] [--novolume] [--nowait]\n [--number NUMBER] [--parallel PARALLEL] [--prefix PREFIX] [--storage-zone STORAGE_ZONE]\n [--timeout TIMEOUT] [--volume] [--volume-number VOLUME_NUMBER] [--volume-size VOLUME_SIZE]\n [--wait]\n\noptions:\n -h, --help show this help message and exit\n --cleanup\n --cloud CLOUD Cloud name\n --compute-zone COMPUTE_ZONE\n Compute availability zone to use\n --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted,\n so as to provide a predictable parse order if individual options are over-\n ridden. The set is parsed after the file(s) specified via previous --config-\n file, arguments hence over-ridden options in the directory take precedence. This\n option must be set from the command-line.\n --config-file PATH Path to a config file to use. Multiple config files can be specified, with\n values in later files taking precedence. Defaults to None. This option must be\n set from the command-line.\n --debug\n --delete\n --flavor FLAVOR\n --floating\n --image IMAGE\n --interval INTERVAL\n --keypair KEYPAIR\n --network NETWORK\n --network-zone NETWORK_ZONE\n Network availability zone to use\n --nocleanup The inverse of --cleanup\n --nodebug The inverse of --debug\n --nodelete The inverse of --delete\n --nofloating The inverse of --floating\n --novolume The inverse of --volume\n --nowait The inverse of --wait\n --number NUMBER\n --parallel PARALLEL\n --prefix PREFIX\n --storage-zone STORAGE_ZONE\n Storage availability zone to use\n --timeout TIMEOUT\n --volume\n --volume-number VOLUME_NUMBER\n --volume-size VOLUME_SIZE\n --wait\n"})}),"\n",(0,i.jsx)(n.p,{children:"Running a small and simple test on your Openstack environment, using Ubuntu_22.04 image with the flavor of 2VCPUs and 8Gigabytes of RAM, starting 6 servers, 2 parallel each with a volume size of 20Gigabytes."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"$ python src/main.py --network test-net --flavor SCS-2V-8 --image Ubuntu_22.04 --number 6 --parallel 2 --volume-size 20\n2024-04-23 11:47:16 | INFO | Checking flavor SCS-2V-8\n2024-04-23 11:47:17 | INFO | flavor.id = 926f952f-0714-4c55-92c2-7514191fecce\n2024-04-23 11:47:17 | INFO | Checking image Ubuntu_22.04\n2024-04-23 11:47:17 | INFO | image.id = 667649d6-e828-403b-8871-15dde7b9ce85\n2024-04-23 11:47:17 | INFO | Checking network test-net\n2024-04-23 11:47:18 | INFO | network.id = 9688192e-11dd-4618-a18c-99d3267f630a\n2024-04-23 11:47:18 | INFO | Creating server simple-stress-0\n2024-04-23 11:47:18 | INFO | Creating server simple-stress-1\n2024-04-23 11:47:18 | INFO | Waiting for server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:18 | INFO | Waiting for server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:28 | INFO | Waiting for boot / test results of 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:29 | INFO | Waiting for boot / test results of e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:39 | INFO | Deleting server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:39 | INFO | Waiting for deletion of server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:39 | INFO | Deleting server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:40 | INFO | Waiting for deletion of server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:49 | INFO | Creating server simple-stress-2\n2024-04-23 11:47:50 | INFO | Creating server simple-stress-3\n2024-04-23 11:47:50 | INFO | Waiting for server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:47:51 | INFO | Waiting for server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:00 | INFO | Waiting for boot / test results of 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:48:01 | INFO | Waiting for boot / test results of a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:11 | INFO | Deleting server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:12 | INFO | Waiting for deletion of server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:12 | INFO | Deleting server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:48:12 | INFO | Waiting for deletion of server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:48:22 | INFO | Creating server simple-stress-4\n2024-04-23 11:48:22 | INFO | Waiting for server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:22 | INFO | Creating server simple-stress-5\n2024-04-23 11:48:23 | INFO | Waiting for server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:48:55 | INFO | Deleting server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:55 | INFO | Deleting server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:48:55 | INFO | Waiting for deletion of server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:55 | INFO | Waiting for deletion of server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:49:05 | INFO | Server 049bf974-b0fd-467f-aabd-3593b2a409a4 finished\n2024-04-23 11:49:05 | INFO | Server e485697f-feae-458c-952d-000072374c3f finished\n2024-04-23 11:49:05 | INFO | Server a098cc12-94ff-4036-bf42-4fc08287809f finished\n2024-04-23 11:49:05 | INFO | Server 26595dd3-09d4-4758-8d1f-58a40b681d11 finished\n2024-04-23 11:49:05 | INFO | Server 05b9f996-5a06-4359-b495-3463cc7b81e0 finished\n2024-04-23 11:49:05 | INFO | Server 8d372de6-ca07-4afb-9e80-1589fd5242e8 finished\n2024-04-23 11:49:05 | INFO | Runtime: 107.4460s\n"})}),"\n",(0,i.jsx)(n.p,{children:"Using a config directory with configfiles to run the test."}),"\n",(0,i.jsxs)(n.p,{children:["Path to a config directory to pull ",(0,i.jsx)(n.code,{children:"*.conf"})," files from. This file set is sorted,\nso as to provide a predictable parse order if individual options are over-ridden.\nThe set is parsed after the file(s) specified via previous --config file,\narguments hence over-ridden options in the directory take precedence. This\noption must be set from the command-line."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"python src/main.py --config-dir /path/to/config-dir\n"})}),"\n",(0,i.jsx)(n.h2,{id:"config-files",children:"Config files"}),"\n",(0,i.jsxs)(n.p,{children:["The config files which can be used for ",(0,i.jsx)(n.code,{children:"main.py"})," are using the ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/oslo.config/latest/configuration/quickstart.html",children:"oslo.config format"}),", you can set the command line options as ",(0,i.jsx)(n.code,{children:"key = value pair"})," and create your own config files matching your setup."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="mytest.conf"',children:"[DEFAULT]\ncloud = simple-stress\nnetwork = test-net\nnumber = 6\nparallel = 2\nflavor = SCS-2V-8\nimage = Ubuntu_22.04\nvolume-size = 20\n"})})]})}function f(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c5479f59.125dae58.js b/assets/js/c5479f59.125dae58.js new file mode 100644 index 0000000000..6f912faac1 --- /dev/null +++ b/assets/js/c5479f59.125dae58.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2283],{34985:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var i=t(74848),r=t(28453);const o={},s="Rate limit",a={id:"container/components/container-registry/docs/rate_limit",title:"Rate limit",description:"This page describes how the rate limiting can be set up for the Harbor container registry.",source:"@site/docs/03-container/components/container-registry/docs/rate_limit.md",sourceDirName:"03-container/components/container-registry/docs",slug:"/container/components/container-registry/docs/rate_limit",permalink:"/docs/container/components/container-registry/docs/rate_limit",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/container-registry/docs/rate_limit.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"SCS deployment",permalink:"/docs/container/components/container-registry/docs/scs-deployment"},next:{title:"Upgrade",permalink:"/docs/container/components/container-registry/docs/upgrade"}},c={},l=[];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"rate-limit",children:"Rate limit"}),"\n",(0,i.jsx)(n.p,{children:"This page describes how the rate limiting can be set up for the Harbor container registry."}),"\n",(0,i.jsxs)(n.p,{children:["Harbor itself doesn't support rate limit protection yet, see open ",(0,i.jsx)(n.a,{href:"https://github.com/goharbor/harbor/issues/3419",children:"issue"}),".\nTherefore, we can take advantage of the ingress controller in front of the Harbor. In our case Nginx."]}),"\n",(0,i.jsxs)(n.p,{children:["In the ingress-nginx controller, the rate-limiting options can be specified via ",(0,i.jsx)(n.a,{href:"https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#rate-limiting",children:"annotations"}),".\nE.g. ",(0,i.jsx)(n.code,{children:'nginx.ingress.kubernetes.io/limit-rps: "1"'})," means that ingress will allow only 1 request from a given IP per second.\nClient IP is set based on the use of ",(0,i.jsx)(n.code,{children:"PROXY protocol"})," or from the ",(0,i.jsx)(n.code,{children:"X-Forwarded-For"})," header value.\nIn the SCS reference implementation, proxy protocol for ingress nginx is ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/Release-Notes-R4.md#enabling-the-proxy-protocol-for-nginx-ingress-and-preliminary-support-for-ovn-lb-325",children:"enabled by default"}),".\nThis rate-limit annotation is ideal for ",(0,i.jsx)(n.em,{children:"DDoS attacks"})," mitigation. When clients exceed this limit\n",(0,i.jsx)(n.strong,{children:"503"})," status code is returned. This status code can be changed via nginx ingress controller configmap:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ kubectl edit cm -n ingress-nginx ingress-nginx-controller\n# data:\n# limit-req-status-code: "429"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["There are other useful annotations, such as limit concurrent connections, number of kilobytes per second or limit burst requests.\nE.g. bursts can be configured via ",(0,i.jsx)(n.code,{children:"nginx.ingress.kubernetes.io/limit-burst-multiplier"}),", which is by default ",(0,i.jsx)(n.em,{children:"5"}),".\nIt means that ",(0,i.jsx)(n.a,{href:"http://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req",children:"burst"}),"\nwill be set in this case to ",(0,i.jsx)(n.code,{children:"limit-rps * limit-burst-multiplier = 1 * 5 = 5"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["More information about nginx rate-limiting and real-world examples can be seen in this nginx ",(0,i.jsx)(n.a,{href:"https://www.nginx.com/blog/rate-limiting-nginx/",children:"blog"}),".\nAlso, there is a second option for how the rate limiting can be configured called ",(0,i.jsx)(n.a,{href:"https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#global-rate-limiting",children:"global rate limiting"}),".\nDetailed research and comparison are done in this ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-harbor/issues/38#issuecomment-1570181044",children:"issue"}),".\nFurthermore, see this ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-harbor/pull/42",children:"PR"}),",\nwhich adds a rate limit for the public(registry.scs.community) environment."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>a});var i=t(96540);const r={},o=i.createContext(r);function s(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c5533f5e.ec9312a9.js b/assets/js/c5533f5e.ec9312a9.js new file mode 100644 index 0000000000..13c2be4eb6 --- /dev/null +++ b/assets/js/c5533f5e.ec9312a9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9346],{2610:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var n=s(74848),r=s(28453);const i={title:"SCS K8S Version Policy for new Kubernetes versions",type:"Standard",stabilized_at:new Date("2023-02-07T00:00:00.000Z"),deprecated_at:new Date("2024-02-08T00:00:00.000Z"),status:"Deprecated",track:"KaaS",description:"The SCS-0210 standard outlines the expected pace at which providers should adopt new Kubernetes versions, aiming\nfor alignment with the rapid development cycle of Kubernetes. Providers must offer the latest minor version within\nfour months of its release and the newest patch version within a week, ensuring users have timely access to security\nupdates, bug fixes, and features. The standard emphasizes the need for expedited updates for critical CVEs and\nexpects providers to thoroughly test new versions before deployment.\n"},o=void 0,a={id:"scs-0210-v1-k8s-new-version-policy",title:"SCS K8S Version Policy for new Kubernetes versions",description:"The SCS-0210 standard outlines the expected pace at which providers should adopt new Kubernetes versions, aiming\nfor alignment with the rapid development cycle of Kubernetes. Providers must offer the latest minor version within\nfour months of its release and the newest patch version within a week, ensuring users have timely access to security\nupdates, bug fixes, and features. The standard emphasizes the need for expedited updates for critical CVEs and\nexpects providers to thoroughly test new versions before deployment.\n",source:"@site/standards/scs-0210-v1-k8s-new-version-policy.md",sourceDirName:".",slug:"/scs-0210-v1-k8s-new-version-policy",permalink:"/standards/scs-0210-v1-k8s-new-version-policy",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS K8S Version Policy for new Kubernetes versions",type:"Standard",stabilized_at:"2023-02-07T00:00:00.000Z",deprecated_at:"2024-02-08T00:00:00.000Z",status:"Deprecated",track:"KaaS",description:"The SCS-0210 standard outlines the expected pace at which providers should adopt new Kubernetes versions, aiming\nfor alignment with the rapid development cycle of Kubernetes. Providers must offer the latest minor version within\nfour months of its release and the newest patch version within a week, ensuring users have timely access to security\nupdates, bug fixes, and features. The standard emphasizes the need for expedited updates for critical CVEs and\nexpects providers to thoroughly test new versions before deployment.\n"},sidebar:"standards",previous:{title:"scs-0210: SCS K8S Version Policy",permalink:"/standards/kaas/scs-0210"},next:{title:"SCS K8S Version Policy",permalink:"/standards/scs-0210-v2-k8s-version-policy"}},d={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function l(e){const t={a:"a",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsx)(t.p,{children:"Here we will describe how fast providers need to keep up with the upstream Kubernetes version."}),"\n",(0,n.jsx)(t.p,{children:"To create a informed decision we summarize here the Kubernetes rules regarding versioning at the time of writing (2023-01-16):"}),"\n",(0,n.jsxs)(t.p,{children:["Kubernetes usually provides about ",(0,n.jsx)(t.strong,{children:"3 minor"})," releases per year (see ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/releases/release/#the-release-cycle",children:"Kubernetes Release Cycle"}),")."]}),"\n",(0,n.jsxs)(t.p,{children:["Patch release cadence is typically monthly. However, the first patches after the first minor release usually arrive 1-2 weeks after the first minor release\n(see ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/releases/patch-releases/#cadence",children:"Patch Release Cadence"}),")."]}),"\n",(0,n.jsxs)(t.p,{children:["As stated in ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/releases/patch-releases/#support-period",children:"Kubernetes Support Period"}),", in general the latest 3 minor versions are maintained by the Kubernetes project.\nEvery release will be maintained for about 14 months.\nThe first 12 months are the standard support period.\nThe remaining 2 months are only for:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"CVEs (under the advisement of the Security Response Committee)"}),"\n",(0,n.jsx)(t.li,{children:"dependency issues (including base image updates)"}),"\n",(0,n.jsx)(t.li,{children:"critical core component issues"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,n.jsx)(t.p,{children:"Kubernetes is a fast-paced project.\nWe want to achieve that providers keep up to date with upstream and do not fall behind Kubernetes releases.\nThis ensures that users are able to upgrade their clusters to address security issues, bug fixes and new features when using SCS compliant clusters in regards of Kubernetes.\nHowever, providers should have reasonable time to implement the new Kubernetes versions and test them."}),"\n",(0,n.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Must provide latest minor version no later than 4 months after release"}),"\n",(0,n.jsx)(t.li,{children:"Must provide latest patch version no later than a week after release"}),"\n",(0,n.jsx)(t.li,{children:"Should be faster for critical CVEs (CVSS >= 8)"}),"\n",(0,n.jsx)(t.li,{children:"Should be tested"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,n.jsxs)(t.p,{children:["All important documents regarding versioning, releases, etc. for the official Kubernetes project can be found on the ",(0,n.jsx)(t.a,{href:"https://kubernetes.io/releases/",children:"Kubernetes Releases page"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,n.jsx)(t.p,{children:"The conformance test is written in the 'k8s-version-recency-check.py' script. The script requires the path to a valid\nkubeconfig file, which should describe the k8s cluster under test. This can either be done by creating a config from\nthe also provided 'config.yaml.template' or by calling the test script with its cli arguments."})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>a});var n=s(96540);const r={},i=n.createContext(r);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c6e1beb6.39ef61f2.js b/assets/js/c6e1beb6.39ef61f2.js new file mode 100644 index 0000000000..0dc5ad88b5 --- /dev/null +++ b/assets/js/c6e1beb6.39ef61f2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7085],{27042:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>m});var o=n(74848),r=n(28453);const a={},i="Alertmanager notifications in Matrix chat",s={id:"operating-scs/components/monitoring/docs/alertmanager",title:"Alertmanager notifications in Matrix chat",description:"This page contains instructions on how to enable the Alertmanager to Matrix chat notifications in the Observer solution.",source:"@site/docs/04-operating-scs/components/monitoring/docs/alertmanager.md",sourceDirName:"04-operating-scs/components/monitoring/docs",slug:"/operating-scs/components/monitoring/docs/alertmanager",permalink:"/docs/operating-scs/components/monitoring/docs/alertmanager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/alertmanager.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Zuul monitoring",permalink:"/docs/operating-scs/components/monitoring/docs/zuul"},next:{title:"OAUTH",permalink:"/docs/operating-scs/components/monitoring/docs/oauth"}},c={},m=[];function l(e){const t={a:"a",code:"code",h1:"h1",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"alertmanager-notifications-in-matrix-chat",children:"Alertmanager notifications in Matrix chat"}),"\n",(0,o.jsx)(t.p,{children:"This page contains instructions on how to enable the Alertmanager to Matrix chat notifications in the Observer solution."}),"\n",(0,o.jsxs)(t.p,{children:["Project ",(0,o.jsx)(t.a,{href:"https://github.com/metio/matrix-alertmanager-receiver",children:"https://github.com/metio/matrix-alertmanager-receiver"})," is used for forwarding alerts to a Matrix room."]}),"\n",(0,o.jsxs)(t.p,{children:["To use it, fill your matrix credentials in ",(0,o.jsx)(t.code,{children:"matrix-alertmanager/matrix-alertmanager-receiver.yaml"})," ConfigMap and deploy it:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"kubectl apply -f matrix-alertmanager/matrix-alertmanager-receiver.yaml\n"})}),"\n",(0,o.jsxs)(t.p,{children:["You can modify other settings according to the mentioned project ",(0,o.jsx)(t.a,{href:"https://github.com/metio/matrix-alertmanager-receiver",children:"docs"}),"\nin the ConfigMap."]}),"\n",(0,o.jsxs)(t.p,{children:["You have to also uncomment a related section in ",(0,o.jsx)(t.code,{children:"values-observer.yaml"})," alertmanager section.\nThe sections related to Alertmanager notifications in the ",(0,o.jsx)(t.code,{children:"values-observer-scs.yaml"})," values file are already uncommented."]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var o=n(96540);const r={},a=o.createContext(r);function i(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c75320ff.3a258087.js b/assets/js/c75320ff.3a258087.js new file mode 100644 index 0000000000..70d9619380 --- /dev/null +++ b/assets/js/c75320ff.3a258087.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1407],{13144:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>l,frontMatter:()=>r,metadata:()=>a,toc:()=>g});var o=i(74848),s=i(28453);const r={sidebar_label:"Logging & Monitoring",sidebar_position:40},t="Logging & Monitoring",a={id:"iaas/guides/upgrade-guide/logging-monitoring",title:"Logging & Monitoring",description:"1. OpenSearch",source:"@site/docs/02-iaas/guides/upgrade-guide/logging-monitoring.md",sourceDirName:"02-iaas/guides/upgrade-guide",slug:"/iaas/guides/upgrade-guide/logging-monitoring",permalink:"/docs/iaas/guides/upgrade-guide/logging-monitoring",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/logging-monitoring.md",tags:[],version:"current",sidebarPosition:40,frontMatter:{sidebar_label:"Logging & Monitoring",sidebar_position:40},sidebar:"docs",previous:{title:"Infrastructure",permalink:"/docs/iaas/guides/upgrade-guide/infrastructure"},next:{title:"OpenStack",permalink:"/docs/iaas/guides/upgrade-guide/openstack"}},d={},g=[];function c(e){const n={code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"logging--monitoring",children:"Logging & Monitoring"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"OpenSearch"}),"\n",(0,o.jsxs)(n.p,{children:["OpenSearch dashboards is also upgraded with the ",(0,o.jsx)(n.code,{children:"opensearch"})," role."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply -a pull opensearch\nosism apply -a upgrade opensearch\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Prometheus"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply -a pull prometheus\nosism apply prometheus\n"})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Grafana"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"osism apply -a pull grafana\nosism apply -a upgrade grafana\n"})}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>t,x:()=>a});var o=i(96540);const s={},r=o.createContext(s);function t(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c7e8a920.cc23dc14.js b/assets/js/c7e8a920.cc23dc14.js new file mode 100644 index 0000000000..34dd547596 --- /dev/null +++ b/assets/js/c7e8a920.cc23dc14.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1542],{89343:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>l});var n=i(74848),a=i(28453);const s={title:"Regulations for achieving SCS-compatible certification",type:"Procedural",status:"Draft",track:"Global"},o=void 0,r={id:"scs-0004-v1-achieving-certification",title:"Regulations for achieving SCS-compatible certification",description:"Introduction",source:"@site/standards/scs-0004-v1-achieving-certification.md",sourceDirName:".",slug:"/scs-0004-v1-achieving-certification",permalink:"/standards/scs-0004-v1-achieving-certification",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Regulations for achieving SCS-compatible certification",type:"Procedural",status:"Draft",track:"Global"},sidebar:"standards",previous:{title:"scs-0004: Regulations for achieving SCS-compatible certification",permalink:"/standards/global/scs-0004"},next:{title:"scs-0112: SONiC Support in SCS",permalink:"/standards/global/scs-0112"}},c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Regulations",id:"regulations",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Open Questions",id:"open-questions",level:2},{value:"Related Documents",id:"related-documents",level:2}];function d(e){const t={a:"a",em:"em",h2:"h2",li:"li",ol:"ol",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsxs)(t.p,{children:["The Sovereign Cloud Stack (SCS) issues certificates with various scopes, among them ",(0,n.jsx)(t.em,{children:"SCS-compatible IaaS"})," (infrastructure as a service) and ",(0,n.jsx)(t.em,{children:"SCS-compatible KaaS"})," (Kubernetes as a service)."]}),"\n",(0,n.jsx)(t.p,{children:"This document details how a cloud service provider (henceforth also called operator) can attain such a certificate for one of their clouds."}),"\n",(0,n.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,n.jsx)(t.p,{children:"As operator, I want to obtain a certificate with the scope SCS-compatible IaaS or SCS-compatible KaaS."}),"\n",(0,n.jsx)(t.h2,{id:"regulations",children:"Regulations"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Each certificate issued pertains to a given cloud, a given scope, and a given version of that scope with a fixed expiry date. The certificate is only valid for that cloud and for the time frame that ends on that expiry date."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["The operator MUST include the official ",(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Tests",children:"SCS compliance test suite"})," (which does not require admin privileges) in their continuous test infrastructure (e.g., Zuul). The tests MUST be run at given intervals, depending on their resource-usage classification:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.em,{children:"light"}),": at least nightly,"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.em,{children:"medium"}),": at least weekly,"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.em,{children:"heavy"}),": at least monthly."]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"For public clouds, it is recommended to offer the SCS project access to the infrastructure so the test suite runs can be triggered continuously by the SCS team."}),"\n",(0,n.jsx)(t.p,{children:"Alternatively, and for non-public clouds, the results (log files) MUST be submitted to SCS (by a mechanism of SCS' choice) at least weekly, and they need to be reproduced again on request by SCS."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"If the desired certificate requires manual checks, then the operator MUST offer the SCS project suitable access. Manual checks MUST be repeated once every quarter."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:["Details on the standards achieved, as well as the current state and the history of all test and check results of the past 18 months will be displayed on a public webpage (henceforth, ",(0,n.jsx)(t.em,{children:"certificate status page"}),") owned by SCS."]}),"\n",(0,n.jsx)(t.p,{children:"The page will be kept online for the duration of the certificate's validity, plus at least 3 months; afterwards, it can be taken offline, either upon request or in the course of maintenance cleanup. However, the page's content won't be deleted until 12 months after the certificate's expiration, for the page will be reanimated and reused if, within this timeframe, a new certificate is issued for the same scope and the same cloud."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"The SCS certification assessment body (initially the SCS project in the OSB Alliance e.V., possibly further entities empowered to do so by the SCS trademark owner, currently the OSB Alliance e.V.) WILL review the certification application and either grant the certification, reject it or ask for further measures or information."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:'Once the certificate is granted by the SCS certification assessment body, the operator SHOULD use the corresponding logo and publicly state the certified "SCS compatibility" on the respective layer for the time of the validity of the certification. In case of a public cloud, this public display is even REQUIRED. In any case, the logo MUST be accompanied by a hyperlink (a QR code for printed assets) to the respective certificate status page.'}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"If the certificate is to be revoked for any reason, it will be included in a publicly available Certificate Revokation List (CRL). This fact will also be reflected in the certificate status page."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"If any of the automated tests or manual checks fail after the certificate has been issued, the certificate is not immediately revoked. Rather, the automated tests MUST pass 99.x % of the runs, and the operator SHALL be notified at the second failed attempt in a row at the latest. In case a manual check fails, it has to be repeated at a date to be negotiated with SCS. It MAY NOT fail more than two times in a row."}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,n.jsx)(t.h2,{id:"open-questions",children:"Open Questions"}),"\n",(0,n.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,n.jsxs)(t.p,{children:["As of now, this document pertains to the certificate scopes on the certification level ",(0,n.jsx)(t.em,{children:"SCS-compatible"})," only. It will be extended to cover the remaining levels as they become relevant, either directly or by way of referring to additional documents."]}),"\n",(0,n.jsxs)(t.p,{children:["For details on our mechanisms for developing, denoting, and versioning the certificate scopes, we refer to the document ",(0,n.jsx)(t.a,{href:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",children:"scs-0003-v1"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>o,x:()=>r});var n=i(96540);const a={},s=n.createContext(a);function o(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c8b68b4a.a4351b5b.js b/assets/js/c8b68b4a.a4351b5b.js new file mode 100644 index 0000000000..a29e01603e --- /dev/null +++ b/assets/js/c8b68b4a.a4351b5b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9565],{85163:s=>{s.exports=JSON.parse('{"title":"Cluster Stacks","slug":"/category/cluster-stacks","permalink":"/docs/category/cluster-stacks","navigation":{"previous":{"title":"Migration to ClusterClass","permalink":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class"},"next":{"title":"Overview","permalink":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview"}}}')}}]); \ No newline at end of file diff --git a/assets/js/c8d5479b.8ad6fee8.js b/assets/js/c8d5479b.8ad6fee8.js new file mode 100644 index 0000000000..2c1f3c70a9 --- /dev/null +++ b/assets/js/c8d5479b.8ad6fee8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9289],{23466:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var s=t(74848),r=t(28453);const a={},o="scs-0302: Domain Manager configuration for Keystone",i={id:"iam/scs-0302",title:"scs-0302: Domain Manager configuration for Keystone",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/iam/scs-0302.md",sourceDirName:"iam",slug:"/iam/scs-0302",permalink:"/standards/iam/scs-0302",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Naming for domains/groups/roles/project when onboarding new customers",permalink:"/standards/scs-0301-v1-naming-conventions"},next:{title:"Domain Manager configuration for Keystone",permalink:"/standards/scs-0302-v1-domain-manager-role"}},c={},d=[];function l(e){const n={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"scs-0302-domain-manager-configuration-for-keystone",children:"scs-0302: Domain Manager configuration for Keystone"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Version"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"State"}),(0,s.jsx)(n.th,{children:"stabilized"}),(0,s.jsx)(n.th,{children:"deprecated"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/standards/scs-0302-v1-domain-manager-role",children:"scs-0302-v1"})}),(0,s.jsx)(n.td,{children:"Standard"}),(0,s.jsx)(n.td,{children:"Draft"}),(0,s.jsx)(n.td,{children:"-"}),(0,s.jsx)(n.td,{children:"-"})]})})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>i});var s=t(96540);const r={},a=s.createContext(r);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9581477.346dbb98.js b/assets/js/c9581477.346dbb98.js new file mode 100644 index 0000000000..2ab56fe3b1 --- /dev/null +++ b/assets/js/c9581477.346dbb98.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6293],{41195:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>c});var t=o(74848),s=o(28453);const i={sidebar_label:"Nova"},a="Nova",r={id:"iaas/guides/configuration-guide/openstack/nova",title:"Nova",description:"* Nova admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/nova.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/nova",permalink:"/docs/iaas/guides/configuration-guide/openstack/nova",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/nova.md",tags:[],version:"current",frontMatter:{sidebar_label:"Nova"},sidebar:"docs",previous:{title:"Neutron",permalink:"/docs/iaas/guides/configuration-guide/openstack/neutron"},next:{title:"Octavia",permalink:"/docs/iaas/guides/configuration-guide/openstack/octavia"}},d={},c=[{value:"Nested virtualisation",id:"nested-virtualisation",level:2},{value:"AMD",id:"amd",level:3},{value:"Intel",id:"intel",level:3},{value:"Reserve compute node resources",id:"reserve-compute-node-resources",level:2},{value:"Host memory",id:"host-memory",level:3},{value:"Host CPUs",id:"host-cpus",level:3},{value:"Local SSD storage",id:"local-ssd-storage",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"nova",children:"Nova"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/admin/index.html",children:"Nova admin guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/index.html",children:"Nova configuration guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/config.html",children:"Nova configuration reference"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"nested-virtualisation",children:"Nested virtualisation"}),"\n",(0,t.jsx)(n.h3,{id:"amd",children:"AMD"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'echo "options kvm-amd nested=y" | sudo tee /etc/modprobe.d/kvm-nested-virtualization.conf\nsudo modprobe -r kvm_amd\nsudo modprobe kvm_amd\ncat /sys/module/kvm_amd/parameters/nested\nY\ndocker restart nova_libvirt\n'})}),"\n",(0,t.jsx)(n.h3,{id:"intel",children:"Intel"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'echo "options kvm-intel nested=y" | sudo tee /etc/modprobe.d/kvm-nested-virtualization.conf\nsudo modprobe -r kvm_intel\nsudo modprobe kvm_intel\ncat /sys/module/kvm_intel/parameters/nested\nY\ndocker restart nova_libvirt\n'})}),"\n",(0,t.jsx)(n.h2,{id:"reserve-compute-node-resources",children:"Reserve compute node resources"}),"\n",(0,t.jsx)(n.p,{children:"How many resources you want to reserve on a compute node depends very much on which additional\nservices are running on the compute node."}),"\n",(0,t.jsx)(n.h3,{id:"host-memory",children:"Host memory"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.reserved_host_memory_mb",children:"https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.reserved_host_memory_mb"})}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="environments/kolla/files/overlays/nova/nova-compute.conf"',children:"[DEFAULT]\nreserved_host_memory_mb = 32768\n"})}),"\n",(0,t.jsx)(n.h3,{id:"host-cpus",children:"Host CPUs"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.reserved_host_cpus",children:"https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.reserved_host_cpus"})}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="environments/kolla/files/overlays/nova/nova-compute.conf"',children:"[DEFAULT]\nreserved_host_cpus = 4\n"})}),"\n",(0,t.jsx)(n.h2,{id:"local-ssd-storage",children:"Local SSD storage"}),"\n",(0,t.jsxs)(n.p,{children:["In this example, a local SSD is provided for use on compute node ",(0,t.jsx)(n.code,{children:"testbed-node-0"}),".\nBy default, Nova accesses the local storage on a file basis."]}),"\n",(0,t.jsxs)(n.p,{children:["It is also possible to work with logical volumes instead. However, this is not\nrecommended or supported by OSISM. More details in the\n",(0,t.jsx)(n.a,{href:"https://docs.openstack.org/nova/latest/admin/configuration/index.html",children:"Nova Configuration Guide"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["On the compute node, the local SSD to be used is formatted with a file system of\nyour choice and mounted to ",(0,t.jsx)(n.code,{children:"/var/lib/nova"}),". When using more than one local SSD, a\nsoftware RAID 1 should be used It is recommended to automate the creation of the\nfile system and the creation of the mount point with a custom playbook."]}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.code,{children:"nova.conf"})," configuration file is created as an overlay file for the compute node\n",(0,t.jsx)(n.code,{children:"testbed-node-0"}),". The name of the directory must match the name of the host in the\ninventory. If the compute node has a file with the name ",(0,t.jsx)(n.code,{children:"testbed-node-0.yml"})," in the\n",(0,t.jsx)(n.code,{children:"host_vars"})," directory in the inventory, then the name of the directory\nin the overlays is ",(0,t.jsx)(n.code,{children:"testbed-node-0"})," accordingly. If the file name there were\n",(0,t.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz.yml"})," then the name of the directory would be\n",(0,t.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="environments/kolla/files/overlays/nova/testbed-node-0/nova.conf"',children:"[libvirt]\nimages_type = raw\n\n[glance]\nenable_rbd_download = true\n"})}),"\n",(0,t.jsxs)(n.p,{children:["As Ceph is still used as the storage backend for Glance and Cinder, the image type is\nset to ",(0,t.jsx)(n.code,{children:"raw"}),". To allow to download and cache images from Ceph via rbd rather than the\nGlance API via http ",(0,t.jsx)(n.code,{children:"enable_rbd_download"})," is set to ",(0,t.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Parameters must also be added in the inventory. This differs depending on the OSISM\nversion used."}),"\n",(0,t.jsx)(n.p,{children:"Up to OSISM 6 it looks like this:"}),"\n",(0,t.jsxs)(n.p,{children:["In the inventory, the parameter ",(0,t.jsx)(n.code,{children:"nova_instance_datadir_volume"}),"\nis added in the section for the ",(0,t.jsx)(n.code,{children:"kolla"})," environment."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/testbed-node-0.yml"',children:"##########################################################\n# kolla\n\nnova_instance_datadir_volume: /var/lib/nova\n"})}),"\n",(0,t.jsx)(n.p,{children:"Starting with OSISM 7, it looks like this:"}),"\n",(0,t.jsxs)(n.p,{children:["In the inventory, the parameters ",(0,t.jsx)(n.code,{children:"nova_instance_datadir_volume"})," and ",(0,t.jsx)(n.code,{children:"nova_backend"}),",\nare added in the section for the ",(0,t.jsx)(n.code,{children:"kolla"})," environment."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="inventory/host_vars/testbed-node-0.yml"',children:"##########################################################\n# kolla\n\nnova_instance_datadir_volume: /var/lib/nova\nnova_backend: default\n"})}),"\n",(0,t.jsx)(n.p,{children:"It is currently not possible to completely deactivate the Ceph integration with Nova.\nSo if you have all compute nodes with local storage, you still have to do the Ceph\nintegration for Nova itself and convert each compute node specifically to local storage.\nIf this is not done, errors will occur when deploying Nova."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>a,x:()=>r});var t=o(96540);const s={},i=t.createContext(s);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9b16325.31b26ab4.js b/assets/js/c9b16325.31b26ab4.js new file mode 100644 index 0000000000..8fd5722760 --- /dev/null +++ b/assets/js/c9b16325.31b26ab4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2798],{98056:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>p,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var n=o(74848),r=o(28453);const c={},s="Developer documentation",i={id:"development/index",title:"Developer documentation",description:"Welcome to the developer section of the contributor docs. Here you will find",source:"@site/contributor-docs/development/index.md",sourceDirName:"development",slug:"/development/",permalink:"/contributor-docs/development/",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"devDocs",next:{title:"SCS RFC2119 Keyword Test Guide",permalink:"/contributor-docs/development/tests/rfc2119-keyword-test-guide"}},d={},l=[];function u(e){const t={h1:"h1",p:"p",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"developer-documentation",children:"Developer documentation"}),"\n",(0,n.jsx)(t.p,{children:"Welcome to the developer section of the contributor docs. Here you will find\nguidelines for the implementation of tooling such as the SCS conformance tests."})]})}function p(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,o)=>{o.d(t,{R:()=>s,x:()=>i});var n=o(96540);const r={},c=n.createContext(r);function s(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/caeeb51c.4b40ede3.js b/assets/js/caeeb51c.4b40ede3.js new file mode 100644 index 0000000000..194ddec835 --- /dev/null +++ b/assets/js/caeeb51c.4b40ede3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5162],{37651:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>t,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var i=r(74848),s=r(28453);const a={sidebar_label:"Concept Guide",sidebar_position:10},t="Concept Guide",l={id:"iaas/guides/concept-guide/index",title:"Concept Guide",description:"Highlevel Overview",source:"@site/docs/02-iaas/guides/concept-guide/index.md",sourceDirName:"02-iaas/guides/concept-guide",slug:"/iaas/guides/concept-guide/",permalink:"/docs/iaas/guides/concept-guide/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/index.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Concept Guide",sidebar_position:10},sidebar:"docs",previous:{title:"IaaS Layer",permalink:"/docs/category/iaas-layer"},next:{title:"Components",permalink:"/docs/iaas/guides/concept-guide/components/"}},c={},d=[{value:"Highlevel Overview",id:"highlevel-overview",level:2},{value:"Components in a cluster",id:"components-in-a-cluster",level:2},{value:"Requirements",id:"requirements",level:2},{value:"Layers in a cluster",id:"layers-in-a-cluster",level:2},{value:"Cluster design",id:"cluster-design",level:2},{value:"Use cases",id:"use-cases",level:2},{value:"Hardware Bill of Materials",id:"hardware-bill-of-materials",level:2}];function o(e){const n={a:"a",h1:"h1",h2:"h2",img:"img",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"concept-guide",children:"Concept Guide"}),"\n",(0,i.jsx)(n.h2,{id:"highlevel-overview",children:"Highlevel Overview"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"OSISM overview",src:r(70750).A+"",width:"572",height:"543"})}),"\n",(0,i.jsx)(n.h2,{id:"components-in-a-cluster",children:"Components in a cluster"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./components/openstack",children:"Infrastructure as a Service (IaaS) with OpenStack"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./components/ceph",children:"Software Defined Storage (SDS) with Ceph"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./components/ironic",children:"Bare Metal as a Service (BMaaS) with Ironic"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./components/sonic",children:"Software Defined Networking (SDN) with SONiC & OVN"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./components/k3s",children:"Kubernetes (K8s) with K3S"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./components/gardener",children:"Kubernetes as a Service (KaaS) with Gardener"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./components/clusterapi",children:"Kubernetes as a Service (KaaS) with Cluster API"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./components/keycloak",children:"Identity & Access Management with Keycloak"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./components/teleport",children:"Privileged Access Management (PAM) to all infrastructure with Teleport"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./components/prometheus",children:"Logging, Monitoring & Telemetry with Prometheus & Grafana"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./components/netdata",children:"Realtime insights with Netdata"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./components/proxmox",children:"Simple virtualization & containerization with Proxmox VE"})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,i.jsx)(n.h2,{id:"layers-in-a-cluster",children:"Layers in a cluster"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./layers#compute-plane",children:"Compute Plane"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./layers#control-plane",children:"Control Plane"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./layers#data-plane",children:"Data Plane"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./layers#management-plane",children:"Management Plane"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./layers#monitoring-plane",children:"Monitoring Plane"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./layers#network-plane",children:"Network Plane"})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"cluster-design",children:"Cluster design"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./design#compute-architecture",children:"Compute architecture"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./design#storage-architecture",children:"Storage architecture"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./design#network-architecture",children:"Network architecture"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./design#identity-architecture",children:"Identity architecture"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./design#control-plane-architecture",children:"Control plane architecture"})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"use-cases",children:"Use cases"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./use-cases#hyper-converged-infrastructure-hci",children:"Hyper-converged infrastructure (HCI)"})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"hardware-bill-of-materials",children:"Hardware Bill of Materials"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./hardware-bom#control-nodes",children:"Control nodes"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./hardware-bom#compute-nodes",children:"Compute nodes"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./hardware-bom#storage-nodes",children:"Storage nodes"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./hardware-bom#network-nodes",children:"Network nodes"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./hardware-bom#manager-nodes",children:"Manager nodes"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./hardware-bom#switches",children:"Switches"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"./hardware-bom#network-interface-cards",children:"Network interface cards"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(o,{...e})}):o(e)}},70750:(e,n,r)=>{r.d(n,{A:()=>i});const i=r.p+"assets/images/overview.drawio-f6a92d48381c9de5fcbbd5205e022b0a.png"},28453:(e,n,r)=>{r.d(n,{R:()=>t,x:()=>l});var i=r(96540);const s={},a=i.createContext(s);function t(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cbf20d25.d6fa266e.js b/assets/js/cbf20d25.d6fa266e.js new file mode 100644 index 0000000000..87fcc72eac --- /dev/null +++ b/assets/js/cbf20d25.d6fa266e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5575],{27786:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var s=n(74848),i=n(28453);const o={title:"SCS Conformance Test Implementation Guide",type:null,status:"Draft",track:"Global"},r=void 0,a={id:"development/tests/test-implementation-guide",title:"SCS Conformance Test Implementation Guide",description:"SovereignCloudStack (SCS) uses conformance tests to certify",source:"@site/contributor-docs/development/tests/test-implementation-guide.md",sourceDirName:"development/tests",slug:"/development/tests/test-implementation-guide",permalink:"/contributor-docs/development/tests/test-implementation-guide",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS Conformance Test Implementation Guide",type:null,status:"Draft",track:"Global"},sidebar:"devDocs",previous:{title:"SCS RFC2119 Keyword Test Guide",permalink:"/contributor-docs/development/tests/rfc2119-keyword-test-guide"},next:{title:"Documentation for SCS Contributors",permalink:"/contributor-docs/"}},c={},l=[{value:"1. Mapping of RFC2119 Keywords",id:"1-mapping-of-rfc2119-keywords",level:2},{value:"2. Unit and Regression Tests",id:"2-unit-and-regression-tests",level:2},{value:"Naming Conventions",id:"naming-conventions",level:3},{value:"Write Testable Conformance Tests",id:"write-testable-conformance-tests",level:3},{value:"Pytest Test Example",id:"pytest-test-example",level:3},{value:"3. Conformance Tests Shouldn't Require Admin Privileges",id:"3-conformance-tests-shouldnt-require-admin-privileges",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(t.p,{children:["SovereignCloudStack (SCS) uses ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Tests",children:"conformance tests"})," to certify\ncompliance of a given cloud offering with respect to a given ",(0,s.jsx)(t.a,{href:"https://docs.scs.community/standards/certification/scopes-versions",children:"certificate\nscope"})," such as ",(0,s.jsx)(t.em,{children:"SCS Compatible IaaS v4"}),".\nOur aim is that these tests are reliable, consistent and comprehensible for\nthe users.\nThis document is a guideline for conformance test authors and summarizes the\ncurrent best practices to achieve this goal."]}),"\n",(0,s.jsx)(t.h2,{id:"1-mapping-of-rfc2119-keywords",children:"1. Mapping of RFC2119 Keywords"}),"\n",(0,s.jsxs)(t.p,{children:["Test authors working on new and existing conformance tests for an SCS standard\nmust implement the keywords such as MUST and SHOULD according to the ",(0,s.jsx)(t.a,{href:"https://docs.scs.community/contributor-docs/operations/tests/rfc2119-keyword-test-guide",children:"SCS\nRFC2119 Keyword Test Guide"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"2-unit-and-regression-tests",children:"2. Unit and Regression Tests"}),"\n",(0,s.jsxs)(t.p,{children:["Test authors are ",(0,s.jsx)(t.em,{children:"strongly"})," encouraged to include unit and regression tests for\nthe conformance test's logic.\nConformance tests will inevitably contain some non-trivial algorithms, be it for\nparsing flavor names or evaluating CVE vulnerability reports.\nTesting them automatically and regularly against valid and invalid inputs helps\ntest authors to find programming mistakes early on.\nAs a bonus, a well written unit test also makes it easier for reviewers to cross\ncheck a given pull request with new, enhanced or refactored conformance tests."]}),"\n",(0,s.jsxs)(t.p,{children:["In general, unit and regression tests for the conformance tests are located in\nthe same location as the conformance tests, that is, the ",(0,s.jsx)(t.code,{children:"Tests/"})," directory of\nthe ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/",children:"SCS standards repository"}),".\nSetup and development of the unit tests is described in the ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/README.md",children:"SCS conformance\ntests README"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"naming-conventions",children:"Naming Conventions"}),"\n",(0,s.jsxs)(t.p,{children:["Any module that ends in ",(0,s.jsx)(t.code,{children:"_test"})," will be picked up as a unit test module by\npytest in our CI pipeline (in other words, all files matched by the pattern\n",(0,s.jsx)(t.code,{children:"Tests/**/*_test.py"}),").\nPytest will execute any function prefixed with ",(0,s.jsx)(t.code,{children:"test_"})," as a test function, or,\nalternatively, tests based on the ",(0,s.jsx)(t.code,{children:"unittest"})," module from the Python standard\nlibrary."]}),"\n",(0,s.jsx)(t.p,{children:"Follow these naming rules:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The name of a unit test module is constructed from the module to be unit\ntested and the ",(0,s.jsx)(t.code,{children:"_test"})," suffix. For example, unit tests for ",(0,s.jsx)(t.code,{children:"flavor_names.py"}),"\nshould reside in ",(0,s.jsx)(t.code,{children:"flavor_names_test.py"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The name of a Python module in general should be a valid ",(0,s.jsx)(t.a,{href:"https://docs.python.org/3/reference/lexical_analysis.html#identifiers",children:"Python\nidentifier"}),", to allow imports via the ",(0,s.jsx)(t.code,{children:"import"})," statement.\nFor example, use ",(0,s.jsx)(t.code,{children:"flavor_names.py"})," instead of ",(0,s.jsx)(t.code,{children:"flavor-names.py"}),"."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"write-testable-conformance-tests",children:"Write Testable Conformance Tests"}),"\n",(0,s.jsx)(t.p,{children:"Software design fills complete book shelves and this section can only cover some\nbasic best practices.\nAs a general rule of thumb, the earlier you begin writing unit tests, the better\n\u2013 it will force you to write modules that are easy to test."}),"\n",(0,s.jsxs)(t.p,{children:["Divide conformance tests scripts into smaller, loosely coupled units, i.e.,\nfunctions that serve one purpose each.\nUse the ",(0,s.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Dependency_injection",children:(0,s.jsx)(t.em,{children:"dependency injection"})})," technique, i.e., pass externally\nretrieved data as function arguments instead of hardcoding the calls to the\nretrieval functions inside a function.\nAvoid logging calls deep down in the call hierarchy and use explicit return\nvalues or raise exceptions, instead.\nHere is an abstract example of a conformance test which does exactly that:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-python",children:'# property_compliance.py\n\ndef retrieve(location):\n """Retrieve raw data via network."""\n ...\n\ndef parse(data):\n """Parse raw data and return a dict."""\n ...\n\ndef handle(...):\n """Evaluate parsed data."""\n ...\n\ndef main(args):\n ...\n data = retrieve(location)\n parsed = parse(data)\n result = handle(parsed)\n ...\n if result.some_prop != expected_value:\n logging.warn("some_prop is not as expected: %s (vs. %s)", result.some_prop, expected_value)\n ...\n return result.success\n\nif __name__ == "__main__":\n # using sys.exit(\u2026) only here makes it possible to unit test main(\u2026)\n sys.exit(main(sys.argv))\n'})}),"\n",(0,s.jsx)(t.p,{children:"Adhering to this style makes it easier to test an algorithm in isolation,\nwithout actually making a call to some external service."}),"\n",(0,s.jsx)(t.h3,{id:"pytest-test-example",children:"Pytest Test Example"}),"\n",(0,s.jsxs)(t.p,{children:["Assuming we want to unit test some members of the module ",(0,s.jsx)(t.code,{children:"property_compliance"}),"\nfrom the previous section, we would create a file ",(0,s.jsx)(t.code,{children:"property_compliance_test.py"}),"\nwith the following content as a starting point:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-python",children:'"""Unit tests for property_compliance.\n\n(c) Your Name <your.name@example.com>, 4/2024\nSPDX-License-Identifier: CC-BY-SA-4.0\n"""\n\nimport pytest\n\nfrom property_compliance import parse\n\n\ndef test_success():\n assert parse("some valid input") == "expected output"\n\n\ndef test_failure():\n with pytest.raises(ValueError):\n parse("invalid input")\n'})}),"\n",(0,s.jsx)(t.h2,{id:"3-conformance-tests-shouldnt-require-admin-privileges",children:"3. Conformance Tests Shouldn't Require Admin Privileges"}),"\n",(0,s.jsxs)(t.p,{children:["Conformance tests are expected to be executable without admin privileges (see \xa72 of\n",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Standards/scs-0004-v1-achieving-certification.md",children:"Regulations for achieving SCS-compatible certification"}),").\nIn particular, this means:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The cloud credentials (e.g., kubeconfig and OpenStack ",(0,s.jsx)(t.code,{children:"clouds.yaml"}),") passed to\nthe scripts are non-admin credentials."]}),"\n",(0,s.jsx)(t.li,{children:"Conformance tests scripts should not require root privileges, except for the\ninstallation of operating system prerequisites (e.g., a Python interpreter)."}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var s=n(96540);const i={},o=s.createContext(i);function r(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ccc49370.2a272f26.js b/assets/js/ccc49370.2a272f26.js new file mode 100644 index 0000000000..e9fc8b65c1 --- /dev/null +++ b/assets/js/ccc49370.2a272f26.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3249],{73858:(e,t,n)=>{n.r(t),n.d(t,{default:()=>j});n(96540);var i=n(18215),a=n(61213),o=n(17559),r=n(7131),s=n(26535),l=n(24651),c=n(21312),d=n(39022),u=n(74848);function m(e){const{nextItem:t,prevItem:n}=e;return(0,u.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,c.T)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"}),children:[n&&(0,u.jsx)(d.A,{...n,subLabel:(0,u.jsx)(c.A,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post",children:"Newer Post"})}),t&&(0,u.jsx)(d.A,{...t,subLabel:(0,u.jsx)(c.A,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post",children:"Older Post"}),isNext:!0})]})}function g(){const{assets:e,metadata:t}=(0,r.e)(),{title:n,description:i,date:o,tags:s,authors:l,frontMatter:c}=t,{keywords:d}=c,m=e.image??c.image;return(0,u.jsxs)(a.be,{title:n,description:i,keywords:d,image:m,children:[(0,u.jsx)("meta",{property:"og:type",content:"article"}),(0,u.jsx)("meta",{property:"article:published_time",content:o}),l.some((e=>e.url))&&(0,u.jsx)("meta",{property:"article:author",content:l.map((e=>e.url)).filter(Boolean).join(",")}),s.length>0&&(0,u.jsx)("meta",{property:"article:tag",content:s.map((e=>e.label)).join(",")})]})}var h=n(5260),f=n(6676);function p(){const e=(0,f.J)();return(0,u.jsx)(h.A,{children:(0,u.jsx)("script",{type:"application/ld+json",children:JSON.stringify(e)})})}var v=n(67763),x=n(50996);function b(e){let{sidebar:t,children:n}=e;const{metadata:i,toc:a}=(0,r.e)(),{nextItem:o,prevItem:c,frontMatter:d,unlisted:g}=i,{hide_table_of_contents:h,toc_min_heading_level:f,toc_max_heading_level:p}=d;return(0,u.jsxs)(s.A,{sidebar:t,toc:!h&&a.length>0?(0,u.jsx)(v.A,{toc:a,minHeadingLevel:f,maxHeadingLevel:p}):void 0,children:[g&&(0,u.jsx)(x.A,{}),(0,u.jsx)(l.A,{children:n}),(o||c)&&(0,u.jsx)(m,{nextItem:o,prevItem:c})]})}function j(e){const t=e.content;return(0,u.jsx)(r.i,{content:e.content,isBlogPostPage:!0,children:(0,u.jsxs)(a.e3,{className:(0,i.A)(o.G.wrapper.blogPages,o.G.page.blogPostPage),children:[(0,u.jsx)(g,{}),(0,u.jsx)(p,{}),(0,u.jsx)(b,{sidebar:e.sidebar,children:(0,u.jsx)(t,{})})]})})}},67763:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var i=n(18215),a=n(65195);const o={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var r=n(74848);const s="table-of-contents__link toc-highlight",l="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,r.jsx)("div",{className:(0,i.A)(o.tableOfContents,"thin-scrollbar",t),children:(0,r.jsx)(a.A,{...n,linkClassName:s,linkActiveClassName:l})})}},65195:(e,t,n)=>{n.d(t,{A:()=>f});var i=n(96540),a=n(6342);function o(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const i=n.slice(2,e.level);e.parentIndex=Math.max(...i),n[e.level]=t}));const i=[];return t.forEach((e=>{const{parentIndex:n,...a}=e;n>=0?t[n].children.push(a):i.push(a)})),i}function r(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:i}=e;return t.flatMap((e=>{const t=r({toc:e.children,minHeadingLevel:n,maxHeadingLevel:i});return function(e){return e.level>=n&&e.level<=i}(e)?[{...e,children:t}]:t}))}function s(e){const t=e.getBoundingClientRect();return t.top===t.bottom?s(e.parentNode):t}function l(e,t){let{anchorTopOffset:n}=t;const i=e.find((e=>s(e).top>=n));if(i){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(s(i))?i:e[e.indexOf(i)-1]??null}return e[e.length-1]??null}function c(){const e=(0,i.useRef)(0),{navbar:{hideOnScroll:t}}=(0,a.p)();return(0,i.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,i.useRef)(void 0),n=c();(0,i.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:i,linkActiveClassName:a,minHeadingLevel:o,maxHeadingLevel:r}=e;function s(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(i),s=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const i=[];for(let a=t;a<=n;a+=1)i.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(i.join()))}({minHeadingLevel:o,maxHeadingLevel:r}),c=l(s,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(a),e.classList.add(a),t.current=e):e.classList.remove(a)}(e,e===d)}))}return document.addEventListener("scroll",s),document.addEventListener("resize",s),s(),()=>{document.removeEventListener("scroll",s),document.removeEventListener("resize",s)}}),[e,n])}var u=n(28774),m=n(74848);function g(e){let{toc:t,className:n,linkClassName:i,isChild:a}=e;return t.length?(0,m.jsx)("ul",{className:a?void 0:n,children:t.map((e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.A,{to:`#${e.id}`,className:i??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(g,{isChild:!0,toc:e.children,className:n,linkClassName:i})]},e.id)))}):null}const h=i.memo(g);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:s="table-of-contents__link",linkActiveClassName:l,minHeadingLevel:c,maxHeadingLevel:u,...g}=e;const f=(0,a.p)(),p=c??f.tableOfContents.minHeadingLevel,v=u??f.tableOfContents.maxHeadingLevel,x=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,i.useMemo)((()=>r({toc:o(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:p,maxHeadingLevel:v});return d((0,i.useMemo)((()=>{if(s&&l)return{linkClassName:s,linkActiveClassName:l,minHeadingLevel:p,maxHeadingLevel:v}}),[s,l,p,v])),(0,m.jsx)(h,{toc:x,className:n,linkClassName:s,...g})}},50996:(e,t,n)=>{n.d(t,{A:()=>g});n(96540);var i=n(18215),a=n(21312),o=n(5260),r=n(74848);function s(){return(0,r.jsx)(a.A,{id:"theme.unlistedContent.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,r.jsx)(a.A,{id:"theme.unlistedContent.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,r.jsx)(o.A,{children:(0,r.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}var d=n(17559),u=n(27293);function m(e){let{className:t}=e;return(0,r.jsx)(u.A,{type:"caution",title:(0,r.jsx)(s,{}),className:(0,i.A)(t,d.G.common.unlistedBanner),children:(0,r.jsx)(l,{})})}function g(e){return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(c,{}),(0,r.jsx)(m,{...e})]})}},6676:(e,t,n)=>{n.d(t,{k:()=>d,J:()=>u});var i=n(86025),a=n(44586),o=n(36803);var r=n(7131);const s=e=>new Date(e).toISOString();function l(e){const t=e.map(m);return{author:1===t.length?t[0]:t}}function c(e,t,n){return e?{image:g({imageUrl:t(e,{absolute:!0}),caption:`title image for the blog post: ${n}`})}:{}}function d(e){const{siteConfig:t}=(0,a.A)(),{withBaseUrl:n}=(0,i.h)(),{metadata:{blogDescription:o,blogTitle:r,permalink:d}}=e,u=`${t.url}${d}`;return{"@context":"https://schema.org","@type":"Blog","@id":u,mainEntityOfPage:u,headline:r,description:o,blogPost:e.items.map((e=>function(e,t,n){const{assets:i,frontMatter:a,metadata:o}=e,{date:r,title:d,description:u,lastUpdatedAt:m}=o,g=i.image??a.image,h=a.keywords??[],f=`${t.url}${o.permalink}`,p=m?s(m):void 0;return{"@type":"BlogPosting","@id":f,mainEntityOfPage:f,url:f,headline:d,name:d,description:u,datePublished:r,...p?{dateModified:p}:{},...l(o.authors),...c(g,n,d),...h?{keywords:h}:{}}}(e.content,t,n)))}}function u(){const e=function(){const e=(0,o.A)(),t=e?.data?.blogMetadata;if(!t)throw new Error("useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context");return t}(),{assets:t,metadata:n}=(0,r.e)(),{siteConfig:d}=(0,a.A)(),{withBaseUrl:u}=(0,i.h)(),{date:m,title:g,description:h,frontMatter:f,lastUpdatedAt:p}=n,v=t.image??f.image,x=f.keywords??[],b=p?s(p):void 0,j=`${d.url}${n.permalink}`;return{"@context":"https://schema.org","@type":"BlogPosting","@id":j,mainEntityOfPage:j,url:j,headline:g,name:g,description:h,datePublished:m,...b?{dateModified:b}:{},...l(n.authors),...c(v,u,g),...x?{keywords:x}:{},isPartOf:{"@type":"Blog","@id":`${d.url}${e.blogBasePath}`,name:e.blogTitle}}}function m(e){return{"@type":"Person",...e.name?{name:e.name}:{},...e.title?{description:e.title}:{},...e.url?{url:e.url}:{},...e.email?{email:e.email}:{},...e.imageURL?{image:e.imageURL}:{}}}function g(e){let{imageUrl:t,caption:n}=e;return{"@type":"ImageObject","@id":t,url:t,contentUrl:t,caption:n}}}}]); \ No newline at end of file diff --git a/assets/js/cd0ad4f0.5cf16ef4.js b/assets/js/cd0ad4f0.5cf16ef4.js new file mode 100644 index 0000000000..5abdd95dfd --- /dev/null +++ b/assets/js/cd0ad4f0.5cf16ef4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4625],{5500:(t,n,e)=>{e.r(n),e.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var o=e(74848),i=e(28453);const r={sidebar:3},s="Containerization",a={id:"getting-started/containerization",title:"Containerization",description:"TODO",source:"@site/docs/01-getting-started/containerization.md",sourceDirName:"01-getting-started",slug:"/getting-started/containerization",permalink:"/docs/getting-started/containerization",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/01-getting-started/containerization.md",tags:[],version:"current",frontMatter:{sidebar:3}},c={},d=[];function u(t){const n={h1:"h1",p:"p",...(0,i.R)(),...t.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"containerization",children:"Containerization"}),"\n",(0,o.jsx)(n.p,{children:"TODO"})]})}function l(t={}){const{wrapper:n}={...(0,i.R)(),...t.components};return n?(0,o.jsx)(n,{...t,children:(0,o.jsx)(u,{...t})}):u(t)}},28453:(t,n,e)=>{e.d(n,{R:()=>s,x:()=>a});var o=e(96540);const i={},r=o.createContext(i);function s(t){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof t?t(n):{...n,...t}}),[n,t])}function a(t){let n;return n=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:s(t.components),o.createElement(r.Provider,{value:n},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/cd4fb20e.7c85fa2a.js b/assets/js/cd4fb20e.7c85fa2a.js new file mode 100644 index 0000000000..2e73a5f525 --- /dev/null +++ b/assets/js/cd4fb20e.7c85fa2a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6165],{47287:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>a});var i=s(74848),t=s(28453);const r={title:"SCS Flavor Naming Standard",type:"Standard",status:"Deprecated",track:"IaaS",replaces:"scs-0100-v1-flavor-naming.md",stabilized_at:new Date("2023-02-21T00:00:00.000Z"),deprecated_at:new Date("2023-11-30T00:00:00.000Z")},d=void 0,l={id:"scs-0100-v2-flavor-naming",title:"SCS Flavor Naming Standard",description:"Introduction",source:"@site/standards/scs-0100-v2-flavor-naming.md",sourceDirName:".",slug:"/scs-0100-v2-flavor-naming",permalink:"/standards/scs-0100-v2-flavor-naming",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS Flavor Naming Standard",type:"Standard",status:"Deprecated",track:"IaaS",replaces:"scs-0100-v1-flavor-naming.md",stabilized_at:"2023-02-21T00:00:00.000Z",deprecated_at:"2023-11-30T00:00:00.000Z"},sidebar:"standards",previous:{title:"SCS Flavor Naming Standard",permalink:"/standards/scs-0100-v1-flavor-naming"},next:{title:"SCS Flavor Naming Standard",permalink:"/standards/scs-0100-v3-flavor-naming"}},o={},a=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Type of information included",id:"type-of-information-included",level:3},{value:"Complete Proposal for systematic flavor naming",id:"complete-proposal-for-systematic-flavor-naming",level:2},{value:"Proposal Details",id:"proposal-details",level:2},{value:"[REQUIRED] CPU Suffixes",id:"required-cpu-suffixes",level:3},{value:"Baseline",id:"baseline",level:4},{value:"Higher oversubscription",id:"higher-oversubscription",level:4},{value:"Insufficient microcode",id:"insufficient-microcode",level:4},{value:"Examples",id:"examples",level:4},{value:"[REQUIRED] Memory",id:"required-memory",level:3},{value:"Baseline",id:"baseline-1",level:4},{value:"No ECC",id:"no-ecc",level:4},{value:"Enabled Oversubscription",id:"enabled-oversubscription",level:4},{value:"Examples",id:"examples-1",level:4},{value:"[OPTIONAL] Disk sizes and types",id:"optional-disk-sizes-and-types",level:3},{value:"Baseline",id:"baseline-2",level:4},{value:"Multi-provisioned Disk",id:"multi-provisioned-disk",level:4},{value:"Examples",id:"examples-2",level:4},{value:"Standard SCS flavors",id:"standard-scs-flavors",level:2},{value:"Naming policy compliance",id:"naming-policy-compliance",level:2},{value:"Validation",id:"validation",level:2},{value:"Operational tooling",id:"operational-tooling",level:2},{value:"Extensions",id:"extensions",level:2},{value:"[OPTIONAL] Hypervisor",id:"optional-hypervisor",level:3},{value:"Examples",id:"examples-3",level:4},{value:"[OPTIONAL] Hardware virtualization / Nested virtualization",id:"optional-hardware-virtualization--nested-virtualization",level:3},{value:"Examples",id:"examples-4",level:4},{value:"[OPTIONAL] CPU Architecture Details",id:"optional-cpu-architecture-details",level:3},{value:"Generation and Vendor",id:"generation-and-vendor",level:4},{value:"Frequency Suffixes",id:"frequency-suffixes",level:4},{value:"Examples",id:"examples-5",level:4},{value:"[OPTIONAL] GPU support",id:"optional-gpu-support",level:3},{value:"[OPTIONAL] Infiniband",id:"optional-infiniband",level:3},{value:"Naming options advice",id:"naming-options-advice",level:3},{value:"Proposal Examples",id:"proposal-examples",level:2},{value:"Previous standard versions",id:"previous-standard-versions",level:2},{value:"Beyond SCS",id:"beyond-scs",level:2}];function c(e){const n={a:"a",code:"code",del:"del",div:"div",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"This is the standard v2.1 for SCS Release 4.\nNote that we intend to only extend it (so it's always backwards compatible),\nbut try to avoid changing in incompatible ways.\n(See at the end for the v1 to v2 transition where we have not met that\ngoal, but at least managed to have a 1:1 relationship between v1 and v2 names.)"}),"\n",(0,i.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(n.p,{children:"In OpenStack environments there is a need to define different flavors for instances.\nThe flavors are pre-defined by the operator, the customer can not change these.\nOpenStack providers thus typically offer a large selection of flavors."}),"\n",(0,i.jsxs)(n.p,{children:["While flavors can be discovered (",(0,i.jsx)(n.code,{children:"openstack flavor list"}),"), it is helpful for users (DevOps teams),\nto have"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere."}),"\n",(0,i.jsx)(n.li,{children:"Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"While not all details will be encoded in the name, the key features should be obvious:\nNumber of vCPUs, RAM, Root Disk.\nExtra features are important as well: There will be flavors with GPU support, fast disks for databases,\nmemory-heavy applications, and other useful aspects of an instance."}),"\n",(0,i.jsx)(n.p,{children:"It may also be important to make the CPU generation clearly recognizable, as this is always a topic in\ndiscussions with customers."}),"\n",(0,i.jsx)(n.p,{children:"Note that not all relevant properties of flavors can be discovered; creating a specification\nto address this is a separate but related effort to the name standardization.\nCommonly used infrastructure-as-code tools do not provide a way to use discoverability\nfeatures to express something like \"I want a flavor with 2 vCPUs, 8GiB of RAM, a local\n20GB SSD disk and Infiniband support but I don't care whether it's AMD or intel\" in a\nreasonable manner. Using flavor names to express this will thus continue to be useful\nand we don't expect the need for standardization of flavor names to go away until\nthe commonly used IaC tools work on a higher abstraction layer than they currently do."}),"\n",(0,i.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsx)(n.h3,{id:"type-of-information-included",children:"Type of information included"}),"\n",(0,i.jsx)(n.p,{children:"From discussions of our operators with their customers we learned that\nthe following characteristics are important in a flavor description:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Type"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Generation"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"CPU Generation"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Number of CPU"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Number of vCPUs - suffixed by L,V,T,C (see below)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Amount of RAM"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Amount of memory available for the VM"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Performance Class"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Ability to label high-performance CPUs, disks, network"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"CPU Type"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"X86-intel, X86-amd, ARM, RISC-V, Generic"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:'"bms"'}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Bare Metal System (no virtualization/hypervisor)"})]})]})]}),"\n",(0,i.jsx)(n.p,{children:"This list is likely not comprehensive and will grow over time."}),"\n",(0,i.jsxs)(n.p,{children:["Rather than using random names ",(0,i.jsx)(n.code,{children:"s5a.medium"})," and assigning a discrete set of properties\nto them, we wanted to come up with a scheme that allows to systematically derive\nnames from properties and vice versa. The scheme allows for short names (by not\nencoding all details) as well as very detailed longer names."]}),"\n",(0,i.jsx)(n.h2,{id:"complete-proposal-for-systematic-flavor-naming",children:"Complete Proposal for systematic flavor naming"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Prefix"}),(0,i.jsx)(n.th,{children:"CPUs & Suffix"}),(0,i.jsx)(n.th,{children:"RAM[GiB]"}),(0,i.jsx)(n.th,{children:"optional: Disk[GB]&type"}),(0,i.jsx)(n.th,{children:"opt: extensions"})]})}),(0,i.jsx)(n.tbody,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"SCS-"})}),(0,i.jsxs)(n.td,{children:["N",(0,i.jsx)(n.code,{children:"L/V/T/C"}),"[",(0,i.jsx)(n.code,{children:"i"}),"]"]}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"-"}),"N[",(0,i.jsx)(n.code,{children:"u"}),"][",(0,i.jsx)(n.code,{children:"o"}),"]"]}),(0,i.jsxs)(n.td,{children:["[",(0,i.jsx)(n.code,{children:"-"}),"[M",(0,i.jsx)(n.code,{children:"x"}),"]N[",(0,i.jsx)(n.code,{children:"n/s/l/p"}),"]]"]}),(0,i.jsxs)(n.td,{children:["[",(0,i.jsx)(n.code,{children:"_"}),"EXT]"]})]})})]}),"\n",(0,i.jsxs)(n.p,{children:["Note that ",(0,i.jsx)(n.code,{children:"N"})," and ",(0,i.jsx)(n.code,{children:"M"})," are placeholders for numbers here.\nThe optional fields are denoted in brackets (and have opt: in the header.\nSee below for extensions."]}),"\n",(0,i.jsx)(n.p,{children:"Note that all letters are case-sensitive."}),"\n",(0,i.jsxs)(n.p,{children:["Typical flavor names look like ",(0,i.jsx)(n.code,{children:"SCS-4V-16-50"})," for a flavor with 4vCPUs (with limited\noversubscription), 16GiB RAM and a 50GB disk (of unspecified type)."]}),"\n",(0,i.jsx)(n.h2,{id:"proposal-details",children:"Proposal Details"}),"\n",(0,i.jsx)(n.h3,{id:"required-cpu-suffixes",children:"[REQUIRED] CPU Suffixes"}),"\n",(0,i.jsx)(n.p,{children:"Next to the number of vCPUs, these vCPUs need to be characterized ti describe their nature."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Suffix"}),(0,i.jsx)(n.th,{children:"Meaning"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"C"}),(0,i.jsx)(n.td,{children:"dedicated Core"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"T"}),(0,i.jsx)(n.td,{children:"dedicated Thread (SMT)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V"}),(0,i.jsx)(n.td,{children:"vCPU (oversubscribed)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"L"}),(0,i.jsx)(n.td,{children:"vCPU (heavily oversubscribed)"})]})]})]}),"\n",(0,i.jsx)(n.h4,{id:"baseline",children:"Baseline"}),"\n",(0,i.jsxs)(n.p,{children:["Note that vCPU oversubscription for a ",(0,i.jsx)(n.code,{children:"V"})," vCPU should be implemented such, that we\ncan guarantee ",(0,i.jsx)(n.em,{children:"at least 20% of a core in >99% of the time"}),"; this can be achieved by\nlimiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled)\nor by more advanced workload management logic. Otherwise ",(0,i.jsx)(n.code,{children:"L"})," (low performance) instead\nof ",(0,i.jsx)(n.code,{children:"V"})," must be used. The >99% is measured over a month (1% is 7.2h/month)."]}),"\n",(0,i.jsx)(n.p,{children:"Note that CPUs should use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.).\nMicrocode must be updated within less than a month of a new release; for CVSS scores above 8,\nproviders should do it in less than a week.\nThe provider should enable at least all mitigations that are enabled by default in the Linux kernel and the\nKVM hypervisor. CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) should switch off hyperthreading\nOR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team."}),"\n",(0,i.jsxs)(n.p,{children:["If microcode updates needed for mitigation are lacking for longer than a month, default kernel/hypervisor\nmitigations are disabled or hyperthreading is enabled despite the CPU being susceptible to L1TF, the\nflavors must declare themselves insecure with the ",(0,i.jsx)(n.code,{children:"i"})," suffix (see below)."]}),"\n",(0,i.jsx)(n.h4,{id:"higher-oversubscription",children:"Higher oversubscription"}),"\n",(0,i.jsxs)(n.p,{children:["Must be indicated with a ",(0,i.jsx)(n.code,{children:"L"})," vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and\nthe lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month)."]}),"\n",(0,i.jsx)(n.h4,{id:"insufficient-microcode",children:"Insufficient microcode"}),"\n",(0,i.jsxs)(n.p,{children:["Not using these mitigations must be indicated by an additional ",(0,i.jsx)(n.code,{children:"i"})," suffix for insecure\n(weak protection against CPU vulns through insufficient microcode, lack of disabled hyperthreading\non L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor)."]}),"\n",(0,i.jsx)(n.h4,{id:"examples",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2C"}),"-4-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2T"}),"-4-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2V"}),"-4-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2L"}),"-4-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2Li"}),"-4-10n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2"}),"-**4-10n"]})," - CPU suffix missing"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-",(0,i.jsx)(n.strong,{children:"2iT"}),"-4-10n"]})," - This order is forbidden"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"required-memory",children:"[REQUIRED] Memory"}),"\n",(0,i.jsx)(n.h4,{id:"baseline-1",children:"Baseline"}),"\n",(0,i.jsx)(n.p,{children:"Cloud providers should use ECC memory.\nMemory oversubscription should not be used.\nIt is allowed to specify half GiBs (e.g. 3.5), though this is should not be done for larger memory sizes (>= 10GiB)."}),"\n",(0,i.jsx)(n.h4,{id:"no-ecc",children:"No ECC"}),"\n",(0,i.jsxs)(n.p,{children:["If no ECC is used, the ",(0,i.jsx)(n.code,{children:"u"})," suffix must indicate this."]}),"\n",(0,i.jsx)(n.h4,{id:"enabled-oversubscription",children:"Enabled Oversubscription"}),"\n",(0,i.jsxs)(n.p,{children:["If memory is oversubscribed, you must expose this with the ",(0,i.jsx)(n.code,{children:"o"})," suffix."]}),"\n",(0,i.jsx)(n.h4,{id:"examples-1",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["SCS-2C-",(0,i.jsx)(n.strong,{children:"4"}),"-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-",(0,i.jsx)(n.strong,{children:"3.5"}),"-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-",(0,i.jsx)(n.strong,{children:"4u"}),"-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-",(0,i.jsx)(n.strong,{children:"4o"}),"-10n"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-",(0,i.jsx)(n.strong,{children:"4uo"}),"-10n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-2C-",(0,i.jsx)(n.strong,{children:"4ou"}),"-10n"]})," - This order is forbidden"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-disk-sizes-and-types",children:"[OPTIONAL] Disk sizes and types"}),"\n",(0,i.jsx)(n.p,{children:"Disk sizes (in GB) should use sizes 5, 10, 20, 50, 100, 200, 500, 1000."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Disk type"}),(0,i.jsx)(n.th,{children:"Meaning"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"n"}),(0,i.jsx)(n.td,{children:"Network shared storage (ceph/cinder)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"h"}),(0,i.jsx)(n.td,{children:"Local disk (HDD: SATA/SAS class)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"s"}),(0,i.jsx)(n.td,{children:"Local SSD disk"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"p"}),(0,i.jsx)(n.td,{children:"Local high-perf NVMe"})]})]})]}),"\n",(0,i.jsx)(n.h4,{id:"baseline-2",children:"Baseline"}),"\n",(0,i.jsx)(n.p,{children:"Note that disk type might be omitted \u2014 the user then can not take any assumptions\non what storage is provided for the root disk (that the image gets provisioned to)."}),"\n",(0,i.jsxs)(n.p,{children:["It does make sense for ",(0,i.jsx)(n.code,{children:"n"})," to be requested explicitly to allow for smooth live migration.\n",(0,i.jsx)(n.code,{children:"h"})," typically provides latency advantages vs ",(0,i.jsx)(n.code,{children:"n"})," (but not necessarily bandwidth and\nalso is more likely to fail), ",(0,i.jsx)(n.code,{children:"s"})," and ",(0,i.jsx)(n.code,{children:"p"})," are for applications that need low\nlatency (high IOPS) and bandwidth disk I/O. ",(0,i.jsx)(n.code,{children:"n"})," storage is expected to survive\nsingle-disk and single-node failure."]}),"\n",(0,i.jsxs)(n.p,{children:["If the disk size is left out, the cloud is expected to allocate a disk (network or local)\nthat is large enough to fit the root file system (",(0,i.jsx)(n.code,{children:"min_disk"})," in image). This automatic\nallocation is indicated with ",(0,i.jsx)(n.code,{children:"-"})," without a disk size.\nIf the ",(0,i.jsx)(n.code,{children:"-"})," is left out completely, the user must create a boot volume manually and\ntell the instance to boot from it or use the\n",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/api-ref/compute/?expanded=create-server-detail#create-server",children:(0,i.jsx)(n.code,{children:"block_device_mapping_v2"})}),"\nmechanism explicitly to create the boot volume from an image."]}),"\n",(0,i.jsx)(n.h4,{id:"multi-provisioned-disk",children:"Multi-provisioned Disk"}),"\n",(0,i.jsxs)(n.p,{children:["The disk size can be prefixed with ",(0,i.jsx)(n.code,{children:"Mx prefix"}),", where M is an integer specifying that the disk\nis provisioned M times. Multiple disks provided this way should be independent storage media,\nso users can expect some level of parallelism and independence."]}),"\n",(0,i.jsx)(n.h4,{id:"examples-2",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"10n"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"10s"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"10s"}),"_bms_z3"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"3x10s"})," - Cloud creates three 10GB SSDs"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"3x10s"}),"_bms_z3"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"10"})," - Cloud decides disk type"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"10"}),"_bms_z3"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"n"})," - Cloud decides disk size (min_disk from image or larger)"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"n"}),"_bms_3"]}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4- - Cloud decides disk type and size"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-_bms_z3"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-_bms_z3h_GNa-64_ib"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-_ib"}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4 - You need to specify a boot volume yourself (boot from volume, or use ",(0,i.jsx)(n.code,{children:"block_device_mapping_v2"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4_bms_z3"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-3x- - Cloud decides disk type and size and creates three of them (FIXME: Is this useful?)"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-3xs - Cloud decides size and creates three local SSD volumes (FIXME: useful?)"}),"\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-3x10 - Cloud decides type and creates three 10GB volumes"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-2C-4-",(0,i.jsx)(n.strong,{children:"1.5n"})]})," - You must not specify disk sizes which are not in full GiBs"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"standard-scs-flavors",children:"Standard SCS flavors"}),"\n",(0,i.jsx)(n.p,{children:"These are flavors that must exist on standard SCS clouds (x86-64)."}),"\n",(0,i.jsxs)(n.p,{children:["We expect disk sizes to be 5, 10, 20, 50, 100, 200, 500, 1000GB, 2000GB.\nWe expect a typical CPU",(0,i.jsx)(n.div,{children:"GiB"})," ratio of 1:4."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsxs)(n.th,{children:["vCPU",":RAM"," ratio"]}),(0,i.jsx)(n.th,{children:"Mandatory Flavors"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"1:4"}),(0,i.jsx)(n.td,{children:"SCS-1V-4, SCS-1V-4-10"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"2:8"}),(0,i.jsx)(n.td,{children:"SCS-2V-8, SCS-2V-8-20"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"4:16"}),(0,i.jsx)(n.td,{children:"SCS-4V-16, SCS-4V-16-50"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"8:32"}),(0,i.jsx)(n.td,{children:"SCS-8V-32, SCS-8V-32-100"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"1:2"}),(0,i.jsx)(n.td,{children:"SCS-1V-2, SCS-1V-2-5"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"2:4"}),(0,i.jsx)(n.td,{children:"SCS-2V-4, SCS-2V-4-10"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"4:8"}),(0,i.jsx)(n.td,{children:"SCS-4V-8, SCS-4V-8-20"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"8:16"}),(0,i.jsx)(n.td,{children:"SCS-8V-16, SCS-8V-16-50"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"16:32"}),(0,i.jsx)(n.td,{children:"SCS-16V-32, SCS-16V-32-100"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"1:8"}),(0,i.jsx)(n.td,{children:"SCS-1V-8, SCS-1V-8-20"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"2:16"}),(0,i.jsx)(n.td,{children:"SCS-2V-16, SCS-2V-16-50"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"4:32"}),(0,i.jsx)(n.td,{children:"SCS-4V-32, SCS-4V-32-100"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"1:1"}),(0,i.jsx)(n.td,{children:"SCS-1L-1, SCS-1L-1-5"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["Note that all vCPUs of SCS standard flavors are oversubscribed \u2014 the smallest ",(0,i.jsx)(n.code,{children:"1L-1"}),"\nflavor allows for heavy oversubscription (note the ",(0,i.jsx)(n.code,{children:"L"}),"), and thus can be offered very\ncheaply \u2014 imagine jump hosts ...\nDisks types are not specified (and expected to be n or h typically)."]}),"\n",(0,i.jsx)(n.p,{children:"The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM\ncompute hosts) to offer all flavors."}),"\n",(0,i.jsxs)(n.p,{children:["Note: Compared to previous drafts, we have heavily reduced the variations\non disk sizes \u2014 this reflects that for the standard networked cinder\ndisks, you can pass ",(0,i.jsx)(n.code,{children:"block_device_mapping_v2"})," on server (VM) creation to\nallocate a boot disk of any size you desire. We have scaled the few\nmandatory disk sizes with the amount of RAM. For each flavor there is\nalso one ",(0,i.jsx)(n.em,{children:"without"})," a pre-attached disk \u2014 these are meant to be used\nto boot from a volume (either created beforehand or allocated on-the-fly\nwith ",(0,i.jsx)(n.code,{children:"block_device_mapping_v2"}),", e.g.\n",(0,i.jsx)(n.code,{children:"openstack server create --flavor SCS-1V:2 --block-device-mapping sda=IMGUUID:image:12:true"}),"\nto create a bootable 12G cinder volume from image ",(0,i.jsx)(n.code,{children:"IMGUUID"})," that gets tied to the VM\ninstance life cycle.)"]}),"\n",(0,i.jsx)(n.h2,{id:"naming-policy-compliance",children:"Naming policy compliance"}),"\n",(0,i.jsx)(n.p,{children:"To be certified as an SCS compliant x86-64 IaaS platform, you must offer all standard SCS flavors\naccording to the previous section. (We may define a mechanism that allows exceptions to be\ngranted in a way that makes this very transparent and visible to clients.)"}),"\n",(0,i.jsx)(n.p,{children:"You are allowed to understate your performance; you may implement a SCS-1V-1-5 flavor with\na flavor that actually implements SCS-1T-1-5n (i.e. you dedicate a dedicated hyperthread instead\nof higher oversubscription) or even SCS-1D-1.5-8s (1 dedicated core, 50% more RAM and a 8GiB SSD)."}),"\n",(0,i.jsxs)(n.p,{children:["Flavor names indicating certain capabilities must ",(0,i.jsx)(n.em,{children:"at least"})," provide these, otherwise they\nare in violation of the SCS specification and prevent SCS compliance."]}),"\n",(0,i.jsx)(n.p,{children:"We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V-32-100).\nLarger providers that offer more details (using the extension below) are expected to still also\noffer the short variants for usability and easier portability, even beyond the mandated flavors."}),"\n",(0,i.jsxs)(n.p,{children:["You must be very careful to expose low vCPU guarantees (",(0,i.jsx)(n.code,{children:"L"})," instead of ",(0,i.jsx)(n.code,{children:"V"}),"), insecure\nhyperthreading/microcode ",(0,i.jsx)(n.code,{children:"i"}),", non-ECC-RAM ",(0,i.jsx)(n.code,{children:"u"}),", memory oversubscription ",(0,i.jsx)(n.code,{children:"o"}),". Note that omitting these qualifiers is\noverstating your security, reliability or performance properties and may be reason for\nclients to feel betrayed or claim damages. This would prevent SCS compliance and certification;\nin extreme cases, the SCS project might be forced to work with public statements."]}),"\n",(0,i.jsxs)(n.p,{children:["You may offer additional ",(0,i.jsx)(n.code,{children:"SCS-"})," flavors, following the naming scheme and rules outlined here."]}),"\n",(0,i.jsxs)(n.p,{children:["You may offer additional flavors, not following above scheme and not starting with ",(0,i.jsx)(n.code,{children:"SCS-"})]}),"\n",(0,i.jsxs)(n.p,{children:["You must not offer flavors with the ",(0,i.jsx)(n.code,{children:"SCS-"})," prefix which do not follow this naming scheme.\nYou must not extend the SCS naming scheme with your own suffices; you are encouraged however\nto suggest extensions that we can discuss and add to the official scheme."]}),"\n",(0,i.jsx)(n.h2,{id:"validation",children:"Validation"}),"\n",(0,i.jsxs)(n.p,{children:["There is a script in ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/flavor-naming/flavor-name-check.py",children:(0,i.jsx)(n.code,{children:"flavor_name_check.py"})}),"\nwhich can be used to decode, validate and construct flavor names.\nThis script must stay in sync with the specification text."]}),"\n",(0,i.jsxs)(n.p,{children:["Ensure you have your OpenStack tooling (",(0,i.jsx)(n.code,{children:"python3-openstackclient"}),", ",(0,i.jsx)(n.code,{children:"OS_CLOUD"}),") setup and call\n",(0,i.jsx)(n.code,{children:"tools/flavor-name-check.py -c $(openstack flavor list -f value -c Name)"})," to get a report\non the flavor list compliance of the cloud environment."]}),"\n",(0,i.jsxs)(n.p,{children:["The script ",(0,i.jsx)(n.code,{children:"flavor-names-openstack.py"})," talks to the OpenStack API of the\ncloud specified by the ",(0,i.jsx)(n.code,{children:"OS_CLOUD"})," environment and queries properties and checks\nthe names for standards compliance and completeness w.r.t. the mandatory\nflavor list. It goes beyond the above example in checking that the discoverable\nfeatures of flavors (vCPUs, RAM, Disk) match what the flavor names claim."]}),"\n",(0,i.jsx)(n.h2,{id:"operational-tooling",children:"Operational tooling"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"https://github.com/osism/openstack-flavor-manager",children:"openstack-flavor-manager"})," is able to\ncreate all standard, mandatory SCS flavors for you."]}),"\n",(0,i.jsx)(n.h2,{id:"extensions",children:"Extensions"}),"\n",(0,i.jsx)(n.p,{children:"Extensions provide a possibility for providers that offer a very differentiated set\nof flavors to indicate hypervisors, support for hardware/nested virtuatlization,\nCPU types and generations, high-frequency models, GPU support and GPU types as\nwell as Inifiniband support. (More extensions may be appended in the future.)"}),"\n",(0,i.jsx)(n.p,{children:"Using the systematic naming approach ensures that two providers that offer flavors\nwith the same specific features will use the same name for them, thus simplifying\nlife for their customers when consuming these flavors."}),"\n",(0,i.jsxs)(n.p,{children:["Note that there is no need to indicate all details and extra features this way.\nFlavors may always perform better or have more features than indicated in a name.\nUnderperformance (CPU suffices ",(0,i.jsx)(n.code,{children:"L"})," or ",(0,i.jsx)(n.code,{children:"i"})," or memory suffices ",(0,i.jsx)(n.code,{children:"o"})," and ",(0,i.jsx)(n.code,{children:"u"}),") on the other\nhand MUST be indicated in the name; this happens rarely in practice."]}),"\n",(0,i.jsx)(n.p,{children:"For smaller providers, the ability to e.g. differentiate between an AMD Milan and an intel\nIceLake and exposed the slightly different feature set to customers and have slightly\ndifferent price points is often not worth the extra effort. This is because having\nthis extra differentiation causes fragmentation of the machines (host aggregates)\nthat can offer these flavors, thus resulting in a lower utilization (as the capacity\nmanagement will need to have a certain amount of headroom per machine pool to avoid\nrunning out of capacity)."}),"\n",(0,i.jsx)(n.p,{children:"Note that it possible for providers to register both the generic short names and the\nlonger, more detailed names and allow them to use the same set of machines (host aggregates).\nNote that machines (hypervisors) can be part of more than one host aggregate."}),"\n",(0,i.jsx)(n.p,{children:"The extensions have the format:"}),"\n",(0,i.jsxs)(n.p,{children:["[",(0,i.jsx)(n.code,{children:"_"}),"hyp][",(0,i.jsx)(n.code,{children:"_hwv"}),"][",(0,i.jsx)(n.code,{children:"_"}),"[arch[N][",(0,i.jsx)(n.code,{children:"h"}),"][",(0,i.jsx)(n.code,{children:"_"}),"[",(0,i.jsx)(n.code,{children:"G/g"}),"]X[N][",(0,i.jsx)(n.code,{children:"-"}),"M[",(0,i.jsx)(n.code,{children:"h"}),"]]][",(0,i.jsx)(n.code,{children:"_ib"}),"]"]}),"\n",(0,i.jsx)(n.p,{children:"Remember that letters are case-sensitive.\nIn case you wonder: Feature indicators are capitalized, modifiers are lower case.\n(An exception is the uppercase -G for a pass-through GPU vs. lowercase -g for vGPU.)"}),"\n",(0,i.jsx)(n.h3,{id:"optional-hypervisor",children:"[OPTIONAL] Hypervisor"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.em,{children:"default Hypervisor"})," is assumed to be ",(0,i.jsx)(n.code,{children:"KVM"}),". Clouds, that offer different hypervisors\nor Bare Metal Systems should indicate the Hypervisor according to the following table:"]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"hyp"}),(0,i.jsx)(n.th,{children:"Meaning"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"kvm"}),(0,i.jsx)(n.td,{children:"KVM"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"xen"}),(0,i.jsx)(n.td,{children:"Xen"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"vmw"}),(0,i.jsx)(n.td,{children:"VMware"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"hyv"}),(0,i.jsx)(n.td,{children:"Hyper-V"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"bms"}),(0,i.jsx)(n.td,{children:"Bare Metal System"})]})]})]}),"\n",(0,i.jsx)(n.h4,{id:"examples-3",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-10n"}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,i.jsx)(n.strong,{children:"bms"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,i.jsx)(n.strong,{children:"bms"}),"_z3h"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-hardware-virtualization--nested-virtualization",children:"[OPTIONAL] Hardware virtualization / Nested virtualization"}),"\n",(0,i.jsxs)(n.p,{children:["If the instances that are created with this flavor support hardware-accelerated\nvirtualization, this can be reflected with the ",(0,i.jsx)(n.code,{children:"_hwv"})," flag (after the optional\nHypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel)\nor svm (AMD) is available. This will be the case on Bare Metal flavors on almost\nall non-ancient x86 CPUs or if your virtualization hypervisor is configured to\nsupport nested virtualization.\nFlavors without the ",(0,i.jsx)(n.code,{children:"_hwv"})," flag may or may not support hardware virtualization (as we\nrecommend enabling nesting, but don't require flavor names to reflect all\ncapabilities. Flavors may over-deliver ...)"]}),"\n",(0,i.jsx)(n.h4,{id:"examples-4",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-10 - may or may not support HW virtualization in VMs"}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10_kvm_",(0,i.jsx)(n.strong,{children:"hwv"})," - kvm with enabled nested virtualization"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10_",(0,i.jsx)(n.strong,{children:"hwv"})," - not recommended, but allowed"]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10_bms_",(0,i.jsx)(n.strong,{children:"hwv"})," - better: bare metal with HW virt support (VMX on intel, SVM on AMD, ...)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.del,{children:["SCS-2C-4-10_",(0,i.jsx)(n.strong,{children:"hwv"}),"_xen"]})," - illegal, wrong ordering"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-cpu-architecture-details",children:"[OPTIONAL] CPU Architecture Details"}),"\n",(0,i.jsx)(n.p,{children:"Arch details provide more details on the specific CPU:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Vendor"}),"\n",(0,i.jsx)(n.li,{children:"Generation"}),"\n",(0,i.jsx)(n.li,{children:"Frequency"}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"generation-and-vendor",children:"Generation and Vendor"}),"\n",(0,i.jsxs)(n.p,{children:["The generations are vendor specific and can be left out.\nNot specifying arch means that we have a generic CPU (",(0,i.jsx)(n.strong,{children:"x86-64"}),").\nThe letters ",(0,i.jsx)(n.code,{children:"i"}),", ",(0,i.jsx)(n.code,{children:"z"}),", ",(0,i.jsx)(n.code,{children:"a"})," and ",(0,i.jsx)(n.code,{children:"r"})," specify the vendors Intel,\nAMD (",(0,i.jsx)(n.code,{children:"z"})," like in Zen), ARM v8+, RISC-V."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Generation"}),(0,i.jsx)(n.th,{children:"i (Intel x86-64)"}),(0,i.jsx)(n.th,{children:"z (AMD x86-64)"}),(0,i.jsx)(n.th,{children:"\xa0a (AArch64)"}),(0,i.jsx)(n.th,{children:"r (RISC-V)"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"0"}),(0,i.jsx)(n.td,{children:"pre Skylake"}),(0,i.jsx)(n.td,{children:"pre Zen"}),(0,i.jsx)(n.td,{children:"pre Cortex A76"}),(0,i.jsx)(n.td,{children:"TBD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"1"}),(0,i.jsx)(n.td,{children:"Skylake"}),(0,i.jsx)(n.td,{children:"Zen-1 (Naples)"}),(0,i.jsx)(n.td,{children:"A76/NeoN1 class"}),(0,i.jsx)(n.td,{children:"TBD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"2"}),(0,i.jsx)(n.td,{children:"Cascade Lake"}),(0,i.jsx)(n.td,{children:"Zen-2 (Rome)"}),(0,i.jsx)(n.td,{children:"A78/x1/NeoV1 class"}),(0,i.jsx)(n.td,{children:"TBD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"3"}),(0,i.jsx)(n.td,{children:"Ice Lake"}),(0,i.jsx)(n.td,{children:"Zen-3 (Milan)"}),(0,i.jsx)(n.td,{children:"A71x/NeoN2 (ARMv9)"}),(0,i.jsx)(n.td,{children:"TBD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"4"}),(0,i.jsx)(n.td,{children:"Sapphire Rapids"}),(0,i.jsx)(n.td,{children:"Zen-4 (Genoa)"}),(0,i.jsx)(n.td,{}),(0,i.jsx)(n.td,{children:"TBD"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["It is recommended to leave out the ",(0,i.jsx)(n.code,{children:"0"}),' when specifying the old generation; this will\nhelp the parser tool, which assumes 0 for an unspecified value and does leave it\nout when generating the name for comparison. In other words: 0 has a meaning of\n"rather old or unspecified".']}),"\n",(0,i.jsx)(n.h4,{id:"frequency-suffixes",children:"Frequency Suffixes"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Suffix"}),(0,i.jsx)(n.th,{children:"Meaning"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"h"}),(0,i.jsx)(n.td,{children:">2.75GHz all-core"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"hh"}),(0,i.jsx)(n.td,{children:">3.25GHz all-core"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"hhh"}),(0,i.jsx)(n.td,{children:">3.75GHz all-core"})]})]})]}),"\n",(0,i.jsx)(n.h4,{id:"examples-5",children:"Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"SCS-2C-4-10n"}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,i.jsx)(n.strong,{children:"z"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,i.jsx)(n.strong,{children:"z3"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,i.jsx)(n.strong,{children:"z3h"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_",(0,i.jsx)(n.strong,{children:"z3hh"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,i.jsx)(n.strong,{children:"z"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,i.jsx)(n.strong,{children:"z3"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,i.jsx)(n.strong,{children:"z3"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,i.jsx)(n.strong,{children:"z3h"})]}),"\n",(0,i.jsxs)(n.li,{children:["SCS-2C-4-10n_bms_",(0,i.jsx)(n.strong,{children:"z3hh"})," - Bare Metal, Intel Ice Lake with > 3.25GHz all core freq"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"optional-gpu-support",children:"[OPTIONAL] GPU support"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"_G"}),"X[N][",(0,i.jsx)(n.code,{children:"-"}),"M[",(0,i.jsx)(n.code,{children:"h"}),"]] indicates a Pass-Through GPU from vendor X of gen N with M compute units / SMs / EUs exposed.\n",(0,i.jsx)(n.code,{children:"_g"}),"X[N][",(0,i.jsx)(n.code,{children:"-"}),"M[",(0,i.jsx)(n.code,{children:"h"}),"]] indicates a vGPU from vendor X of gen N with M compute units / SMs / EUs assigned."]}),"\n",(0,i.jsx)(n.p,{children:"Note that the vendor letter X is mandatory, generation and compute units are optional."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"GPU"}),(0,i.jsx)(n.th,{children:"Vendor"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"N"}),(0,i.jsx)(n.td,{children:"nVidia"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"A"}),(0,i.jsx)(n.td,{children:"AMD"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"I"}),(0,i.jsx)(n.td,{children:"Intel"})]})]})]}),"\n",(0,i.jsx)(n.p,{children:"For nVidia, the generation N can be f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, l=Ada Lovelace, ...,\nfor AMD GCN-x=0.x, RDNA1=1, RDNA2=2, RDNA3=3, for intel Gen9=0.9, Xe(12.1)=1, ...\n(Note: This may need further work to properly reflect what's out there.)"}),"\n",(0,i.jsxs)(n.p,{children:["The optional ",(0,i.jsx)(n.code,{children:"h"})," suffix to the compute unit count indicates high-performance (e.g. high freq or special\nhigh bandwidth gfx memory such as HBM);\n",(0,i.jsx)(n.code,{children:"h"})," can be duplicated for even higher performance."]}),"\n",(0,i.jsx)(n.h3,{id:"optional-infiniband",children:"[OPTIONAL] Infiniband"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"_ib"})," indicates Infiniband networking."]}),"\n",(0,i.jsx)(n.p,{children:"More extensions may be forthcoming and appended in a later revision of this spec."}),"\n",(0,i.jsx)(n.p,{children:"Extensions need to be specified in the above mentioned order."}),"\n",(0,i.jsx)(n.h3,{id:"naming-options-advice",children:"Naming options advice"}),"\n",(0,i.jsx)(n.p,{children:"Note that we expect most clouds to prefer short flavor names,\nnot indicating CPU details or hypervisor types. See above list\nof standard flavors to get a feeling."}),"\n",(0,i.jsxs)(n.p,{children:["However, more successful providers will often need to differentiate their\nofferings in response to customer demand and allow customers to request\nflavors with specific detailed properties. The goal of this proposal is to avoid\nproviders to invent their own names and then refer customers to (currently\nincompletely standardized) ",(0,i.jsx)(n.code,{children:"extra_specs"}),"\nor worse a non-machine-readable service descriptions to find out the details."]}),"\n",(0,i.jsxs)(n.p,{children:["So a cloud provider might well evolve from offering ",(0,i.jsx)(n.code,{children:"SCS-8T-16-50"})," to offering\n",(0,i.jsx)(n.code,{children:"SCS-8T-16-50n"}),", ",(0,i.jsx)(n.code,{children:"SCS-8T-16-50n_i2"})," and ",(0,i.jsx)(n.code,{children:"SCS-8T-16-50n_a2"})," to specify that he\nis using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome.\nWe would expect the cloud provider to still offer the generic flavor\n",(0,i.jsx)(n.code,{children:"SCS-8T-16-50"})," and allow the scheduler (placement service) to pick both more\nspecific types (or just one if e.g. capacity management considerations suggest\nso). Providers should in such cases make sure that the price does not depend\non scheduler decisions."]}),"\n",(0,i.jsxs)(n.p,{children:["We are looking into the ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/image-guide/introduction.html#metadata-definition-metadefs-service",children:"metadefs"}),"\nmechanism and ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/api-guide/compute/extra_specs_and_properties.html",children:"extra_specs"}),"\nto allow customers to ask for specific flavor properties without the need to\nencode all these flavor details into the flavor name, so the optional pieces\nmay not be needed much. However, there must be a way to request flavor\nproperties without encoding the need into an image \u2014 the indirection via\nan image is considered broken by the SCS team."]}),"\n",(0,i.jsx)(n.h2,{id:"proposal-examples",children:"Proposal Examples"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Example"}),(0,i.jsx)(n.th,{children:"Decoding"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-2C-4-10n"}),(0,i.jsx)(n.td,{children:"2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-8Ti-32-50p_i1"}),(0,i.jsx)(n.td,{children:"8 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-1L-1u-5"}),(0,i.jsx)(n.td,{children:"1 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-16T-64-200s_GNa-64_ib"}),(0,i.jsx)(n.td,{children:"16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 64 Passthrough nVidia Ampere SMs"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-4C-16-2x200p_a1"}),(0,i.jsx)(n.td,{children:"4 dedicated Arm64 cores (A76 class), 16GiB RAM, 2x200GB local NVMe drives"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"SCS-1V-0.5"}),(0,i.jsx)(n.td,{children:"1 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"previous-standard-versions",children:"Previous standard versions"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"/standards/scs-0100-v1-flavor-naming",children:"Version 1 of the standard"}),"\nused a slightly different naming syntax while the logic was exactly the same.\nWhat is a ",(0,i.jsx)(n.code,{children:"-"})," in v2 used to be a ",(0,i.jsx)(n.code,{children:":"}),"; ",(0,i.jsx)(n.code,{children:"_"})," used to be ",(0,i.jsx)(n.code,{children:"-"}),". The reason for\nthe change was certain Kubernetes tools using the flavor names as labels.\nLabels however are subject to stricter naming rules and in particular don't\nallow for a ",(0,i.jsx)(n.code,{children:":"}),". See ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/standards/issues/190",children:"PR #190"}),"\nfor a discussion."]}),"\n",(0,i.jsx)(n.p,{children:"Version 1 flavor names can be translated to v2 using the following transformation:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"NAMEV2=$(echo \"$NAMEV1\" | sed -e 's/\\-/_/g' -e 's/:/-/g' -e 's/^SCS_/SCS-/')\n"})}),"\n",(0,i.jsx)(n.p,{children:"and the way back can be done with"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"NAMEV1=$(echo \"$NAMEV2\" | sed -e 's/\\-/:/g' -e 's/_/-/g' -e 's/^SCS:/SCS-/')\n"})}),"\n",(0,i.jsx)(n.p,{children:"Considerations for how providers can ensure a smooth transition for their customers\nfrom v1 to v2 are written in a separate document."}),"\n",(0,i.jsxs)(n.p,{children:["For the time being, the validation tools still accept the old names with a warning\n(despite the unchanged ",(0,i.jsx)(n.code,{children:"SCS-"})," prefix) unless you pass option ",(0,i.jsx)(n.code,{children:"-2"})," to them. They will\nhowever not count v1 flavors towards fulfilling the needs against the corresponding\nv2 mandatory flavor list unless you pass the option ",(0,i.jsx)(n.code,{children:"-1"}),".\nIn other words: An IaaS infrastructure with the 26\nv1 mandatory flavors will produce 26 warnings (for using old flavors) and 26\nerrors (for missing the 26 mandatory v2 flavors) unless you pass ",(0,i.jsx)(n.code,{children:"-1"})," in which\ncase no errors and no warnings will be produced. Registering the 26 mandatory\nv2 flavor names in addition will result in passing the test with only 26\nwarnings \u2014 unless you specify ",(0,i.jsx)(n.code,{children:"-2"}),". If you do and want to pass you'll need\nto remove the old v1 names or rename them to no longer start with ",(0,i.jsx)(n.code,{children:"SCS-"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"beyond-scs",children:"Beyond SCS"}),"\n",(0,i.jsx)(n.p,{children:"The Gaia-X provider working group which could have created a superseding standard\ndoes no longer exist."}),"\n",(0,i.jsx)(n.p,{children:"However, we have been reaching out to the OpenStack Public Cloud SIG and the ALASCA\nmembers to seek further alignment."}),"\n",(0,i.jsx)(n.p,{children:"Getting upstream OpenStack support for flavor aliases would provide more flexibility\nand ease migrations between providers, also providers that don't offer the SCS-\nflavors."}),"\n",(0,i.jsxs)(n.p,{children:["We also would like to see upstream ",(0,i.jsx)(n.code,{children:"extra_specs"})," standardizing the discoverability of some\nproperties exposed via the SCS names and work on IaC tooling (terraform ...)\nto make use of these when selecting a flavor."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>l});var i=s(96540);const t={},r=i.createContext(t);function d(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cda5fe29.7460ccbb.js b/assets/js/cda5fe29.7460ccbb.js new file mode 100644 index 0000000000..e37d029067 --- /dev/null +++ b/assets/js/cda5fe29.7460ccbb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2840],{45464:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>d,toc:()=>l});var i=n(74848),t=n(28453);const r={sidebar_label:"Kubernetes",sidebar_position:12},o="Kubernetes",d={id:"iaas/guides/deploy-guide/services/kubernetes",title:"Kubernetes",description:"As of OSISM 7, it is possible to create a Kubernetes cluster on all nodes.",source:"@site/docs/02-iaas/guides/deploy-guide/services/kubernetes.md",sourceDirName:"02-iaas/guides/deploy-guide/services",slug:"/iaas/guides/deploy-guide/services/kubernetes",permalink:"/docs/iaas/guides/deploy-guide/services/kubernetes",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/kubernetes.md",tags:[],version:"current",sidebarPosition:12,frontMatter:{sidebar_label:"Kubernetes",sidebar_position:12},sidebar:"docs",previous:{title:"Infrastructure",permalink:"/docs/iaas/guides/deploy-guide/services/infrastructure"},next:{title:"Network",permalink:"/docs/iaas/guides/deploy-guide/services/network"}},c={},l=[{value:"Cluster API",id:"cluster-api",level:2}];function a(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h1,{id:"kubernetes",children:"Kubernetes"}),"\n",(0,i.jsx)(s.admonition,{type:"info",children:(0,i.jsx)(s.p,{children:"As of OSISM 7, it is possible to create a Kubernetes cluster on all nodes.\nAt the moment, this is still optional. In the future, it will be necessary\nto deploy this Kubernetes cluster."})}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["Deploy the ",(0,i.jsx)(s.a,{href:"https://k3s.io",children:"K3s"})," cluster."]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply kubernetes\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["Deploy the ",(0,i.jsx)(s.a,{href:"https://github.com/kubernetes/dashboard",children:"Kubernetes dashboard"}),":"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply kubernetes-dashboard\n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"cluster-api",children:"Cluster API"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["Deploy the ",(0,i.jsx)(s.a,{href:"https://cluster-api.sigs.k8s.io",children:"Cluster API"})," management cluster on the K3s cluster:"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply clusterapi\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["Add the ",(0,i.jsx)(s.code,{children:"kubeconfig"})," file to the configuration repository (required later by OpenStack\nMagnum Service):"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"osism apply copy-kubeconfig\n"})}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>d});var i=n(96540);const t={},r=i.createContext(t);function o(e){const s=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ce756c16.fc974905.js b/assets/js/ce756c16.fc974905.js new file mode 100644 index 0000000000..6570840837 --- /dev/null +++ b/assets/js/ce756c16.fc974905.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9807],{44047:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var i=t(74848),s=t(28453);const o={},r="License considerations for SCS",a={id:"license-considerations",title:"License considerations for SCS",description:"As Sovereign Cloud Stack (SCS), our mission is to provide Operators",source:"@site/community/license-considerations.md",sourceDirName:".",slug:"/license-considerations",permalink:"/community/license-considerations",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{}},c={},l=[{value:"Reciprocity",id:"reciprocity",level:2},{value:"Controversy",id:"controversy",level:2},{value:"Affero",id:"affero",level:2},{value:"Derived works and Strong vs. Weak Copyleft",id:"derived-works-and-strong-vs-weak-copyleft",level:2},{value:"Patents",id:"patents",level:2},{value:"Copyright Assignments and Contributor License Agreements",id:"copyright-assignments-and-contributor-license-agreements",level:2},{value:"License in = License out",id:"license-in--license-out",level:2},{value:"Further reading",id:"further-reading",level:2}];function h(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"license-considerations-for-scs",children:"License considerations for SCS"}),"\n",(0,i.jsxs)(n.p,{children:["As Sovereign Cloud Stack (",(0,i.jsx)(n.a,{href:"https://scs.community/",children:"SCS"}),"), our mission is to provide Operators\n(be it Cloud Service Providers or just internal IT departments) with a well working software\nstack, that avoids exposing them to legal risks or additional restrictions that limits the\nusefulness. Free software licenses have this intention but differ in how they achieve it and in\nwhat kind of protections they provide. In the first approximation, all ",(0,i.jsx)(n.a,{href:"https://opensource.org/licenses",children:"OSI"}),"-approved\nopen source licenses can be considered as valid options. As a matter of fact,\nwe do consider projects under such licenses as valid modules for SCS \u2014 where we\nuse such projects and adjust or extend them, we would provide our contributions\nunder the license terms of the respective project, so we can achieve our goal to feed back code\nupstream to the respective project, contribute to it and avoid fragmentation."]}),"\n",(0,i.jsx)(n.p,{children:"Where we do create independent code, we do have additional preferences, though."}),"\n",(0,i.jsxs)(n.p,{children:["For our own code, we do prefer the ",(0,i.jsx)(n.a,{href:"https://www.gnu.org/licenses/agpl-3.0.html",children:"Affero General Public License version 3"}),"\n(AGPLv3) as license. Likewise, for documentation, we prefer ",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/CC-BY-SA",children:"CC-BY-SA"}),".\nWhere we create standard libraries to interface with our software, we would\nconsider the ",(0,i.jsx)(n.a,{href:"https://www.gnu.de/documents/lgpl-3.0.en.html",children:"LGPLv3"})," for these,\nas we don't want interaction with our platform to be seen as requiring licensing\ncode."]}),"\n",(0,i.jsx)(n.h2,{id:"reciprocity",children:"Reciprocity"}),"\n",(0,i.jsxs)(n.p,{children:["The GPL family of licenses are reciprocal licenses \u2014 sometimes called ",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Copyleft",children:"copyleft"}),"\nlicenses \u2014 the recipient of the licensed code can make all sorts of modifications,\nbut if she uses the code to release software (GPL) or provide a networked service\n(AGPL) to others, then she must grant the same rights to the recipients \u2014 this\nincludes making the modifications available under the same terms as the received software.\nMicrosoft has infamously ",(0,i.jsx)(n.a,{href:"https://web.archive.org/web/20010615205548/http://suntimes.com/output/tech/cst-fin-micro01.html",children:"attacked"}),'\ncopyleft licenses (and specifically the GPL) as cancerous "viral" license.']}),"\n",(0,i.jsx)(n.p,{children:"Reciprocity has many advantages:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Code that has been created as free software will stay free. While GPL code can be\ncombined in a larger software collection with proprietary software, the code itself\nincluding its enhancements etc. (technically: all derived works, see below) will\nremain free."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:['The obligation to make the changes available avoids fragmentation. As changed and\n"improved" versions need to be made available, it is much easier to review and feed\nthose changes back and create a unified upstream codebase that reflects the needs of\nthe complete user base by including the needed changes. This was observed and\n',(0,i.jsx)(n.a,{href:"https://lwn.net/Articles/660428/",children:"reported"})," by Martin Fink (HP's former CTO)."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The hugely successful ",(0,i.jsx)(n.a,{href:"https://kernel.org/",children:"Linux kernel"})," project uses the GNU GPL;\nmany of the more traditional key projects in the open source world use copyleft licenses such as\nthe AGPL, GNU GPL, GNU LGPL, MPL or the ",(0,i.jsx)(n.a,{href:"https://opensource.org/licenses/OSL-3.0",children:"OSL"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"controversy",children:"Controversy"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Not fulfilling the license terms of a software license typically leads to the ability for the\nlicense owner to revoke the license \u2014 as it is relatively easy to not fulfill all obligations\nof the GPL out of sheer negligence, the revocation without prior warning seems\ndisproportionate \u2014 this is sometimes called the GPL death penalty. The open source community\nthough has a strong interest in bringing every licensee into compliance by giving violators a\nfair chance to correct their behavior. SCS explicitly supports the ",(0,i.jsx)(n.a,{href:"https://gplcc.github.io/gplcc/",children:"GPL Cooperation Commitment"}),"\nand the respective ",(0,i.jsx)(n.a,{href:"https://www.kernel.org/doc/html/v4.15/process/kernel-enforcement-statement.html",children:"document"}),"\nfrom the Linux kernel developers and pledges to give violators a warning and a chance to correct action\nby allowing for a cure period. This is a bit of a legacy issue \u2014 it is relevant to (L)GPLv2\ncode only \u2014 v3 of L/A/GPL does already contain language that has cure provisions, so it's\nclear by the licensing terms."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Many companies seem to be worried that they will inadvertently violate the GPL by negligence.\nAnd it is true that a company needs a tighter control of the usage of inbound source code\nwhich comes with a reciprocal license than the permissive BSD 3-clause or Apache Software (v2)\nlicenses. This advantage however quickly turns into a disadvantage as soon as the company does\nsignificant outbound open source contributions under a permissive license \u2014 they rarely want\nto give their competitors an opportunity to consume their contributions and then add\nproprietary changes to gain an advantage. In general, companies are well advised to have a\ndetailed understanding of all code that is being used and contributed and their respective\nlicense terms \u2014 for proprietary and open source code and for reciprocal and for permissive\nlicenses. Some companies have successfully installed license review boards or\n",(0,i.jsx)(n.a,{href:"https://www.linuxfoundation.org/resources/open-source-guides/using-open-source-code/",children:"open source review boards"}),"\nto create oversight, recommendations and policies to ease the governance."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Despite this, many of the recent open source projects, especially in the cloud world\nhave adopted permissive licenses, such as X11, BSD 3-clause, MIT and especially the popular\n",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Apache_License",children:"Apache software license"})," (ASL2), as it\nappears to allow for faster adoption by companies that may not have mature open source\npolicies in place or that simply have overly careful lawyers which may be influenced\nby the scare tactics some bad companies have built on top of copyleft licenses."]}),"\n",(0,i.jsx)(n.h2,{id:"affero",children:"Affero"}),"\n",(0,i.jsxs)(n.p,{children:["The reciprocity of the GNU GPL does not apply on the ",(0,i.jsx)(n.em,{children:"creation"})," of a derived work. A company\ncan consume GPL'ed code and change it to their own liking without ever making any the\nchanges available if only used in-house. The terms however do apply as soon as the derived\nwork is ",(0,i.jsx)(n.em,{children:"released"}),", i.e. the software is passed on to a third party."]}),"\n",(0,i.jsxs)(n.p,{children:["In modern times, software is often used to provide a ",(0,i.jsx)(n.em,{children:"networked service"})," (think SaaS) to third\nparties. Unlike the standard GPL, the Affero GPL (AGPL) does consider the act of making it\navailable in such a way as similar to releasing the software and does require that applied\nchanges to the software are being made available in this case."]}),"\n",(0,i.jsx)(n.p,{children:"The AGPL thus closes a shortcoming in the traditional non-Affero GPL for a world that\nincreasingly moves towards networked services."}),"\n",(0,i.jsxs)(n.p,{children:["The very successful ",(0,i.jsx)(n.a,{href:"https://nextcloud.com/",children:"Nextcloud"})," project uses the AGPLv3."]}),"\n",(0,i.jsx)(n.h2,{id:"derived-works-and-strong-vs-weak-copyleft",children:"Derived works and Strong vs. Weak Copyleft"}),"\n",(0,i.jsx)(n.p,{children:"What exactly constitutes derived work needs to be defined \u2014 it's one of the questions where\ncopyright law can get subtle. From a practical view, consuming (non-trivial) source code and\nbinary linking is typically considered creating derived works. Whereas interacting via a network\nAPI or starting another process is typically considered a copyright boundary. To avoid any\nunclarity, the Linux kernel community has explicitly called out using Linux system calls (which\nincludes using the interface definitions) is a copyright boundary and can thus be done by\napplications without any license implications."}),"\n",(0,i.jsx)(n.p,{children:"Considering linked code to be derived works (as is the case in the GPL and AGPL) and thus\nrequiring it under the same (or a compatible) copyleft license is considered a Strong Copyleft\nlicense."}),"\n",(0,i.jsxs)(n.p,{children:["Libraries are often providing implementations for standard services and helpers; it may not be\nreasonable to consider applications that want to use a library as derived works from that\nlibrary and requiring the application to thus be licensed under a (compatible) copyleft license.\nFor these libraries, a Weak Copyleft license (such as the ",(0,i.jsx)(n.a,{href:"https://www.gnu.org/licenses/lgpl-3.0.en.html",children:"LGPL"}),"\nor the ",(0,i.jsx)(n.a,{href:"https://www.eclipse.org/legal/epl-2.0/",children:"EPL"})," can be used. This would still require changes to\nthe library ",(0,i.jsx)(n.em,{children:"itself"})," to me made available under the copyleft license but would make binary\nlinking (including the use of interface definitions) a copyright barrier and thus allow for\nnon-copylefted code to be linked against a weakly copylefted library. This license is used by\nmany of the standard and system libraries in the Linux world and is often a good choice for\nlibraries of standardized services."]}),"\n",(0,i.jsx)(n.h2,{id:"patents",children:"Patents"}),"\n",(0,i.jsxs)(n.p,{children:["Free software licenses are intended to give users broad rights \u2014 the GNU GPL talks about the\n",(0,i.jsx)(n.a,{href:"https://fsfe.org/freesoftware/",children:"four freedoms"})," to use software for any purpose, to study and\nadjust the software (this needs source code access), to redistribute the software and to improve\nit and to make these improvements available."]}),"\n",(0,i.jsxs)(n.p,{children:["Software patents can significantly subvert the intended rights \u2014 the open source community in\ngeneral dislikes software patents for this and many other reasons that are discussed\n",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Software_patents_and_free_software",children:"elsewhere"})," .\nIn some countries, there are rules that prevent pure software from being patented, though ",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Software_patents_under_the_European_Patent_Convention",children:"not\nall patent offices are fully following these rules"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"As software patents are existing and a serious danger to the open source goals, there are a few\nattempts to improve the situation. The Apache Software License (a permissive license), requires\ncode contributors to grant a patent license to all downstream recipients of the code\nto use the contributed code by itself or in combination with the project that it was contributed\nto and makes a possible patent holder lose its license rights should he nevertheless try to\nassert a patent against the thus licensed use. The (A)GPLv3 has a similar clause."}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"https://www.openinventionnetwork.com/",children:"Open Invention Network"})," (OIN) has a meanwhile\nhuge patent pool that is cross-licensed between all participants and which can freely be used\nin a large list of covered open source software by everyone, except for those that raise patent\nviolation claims against any of the covered open source projects. This basically restricts\nthose patents to be only used defensively in the context of the covered open source projects."]}),"\n",(0,i.jsx)(n.p,{children:"Should SCS be in a position to make inventions that should be protected by a software patent,\nit pledges to contribute these to the OIN pool."}),"\n",(0,i.jsx)(n.h2,{id:"copyright-assignments-and-contributor-license-agreements",children:"Copyright Assignments and Contributor License Agreements"}),"\n",(0,i.jsx)(n.p,{children:"Very few Open Source projects require copyright assignment; the GNU projects are the\nonly commonly used ones that the author is aware of. This results in fully centralized\ncopyright ownership. This puts the FSF into a very\nstrong position \u2014 a position to enforce copyright, to change licenses etc. This requires\na lot of trust towards the copyright assigneed."}),"\n",(0,i.jsx)(n.p,{children:"Most open source projects prefer distributed copyright \u2014 the authors (or their\nemployers) retain the copyright to their works. They grant a license for the open\nsource project to use and integrate and redistribute the work \u2014 typically the\nlicense grant is extended to the public. In a sufficiently distributed copyright model,\nit is very hard to change a license, as all copyright holders would need to agree.\nThis can both be considered advantageous and disadvantageous."}),"\n",(0,i.jsxs)(n.p,{children:["Many software projects use ",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Contributor_License_Agreement",children:"Contributor License Agreements"}),"\n(CLAs), documenting that contributed code grants certain rights to the project\nowner (a foundation or sometimes a company). This ensures that the project owner\nhas all needed rights to use, protect, redistribute ... the code. If the CLA contains\n",(0,i.jsx)(n.em,{children:"copyright assignment"}),", it also allows the project to change the license or to\ncreate derived works under a different license."]}),"\n",(0,i.jsx)(n.p,{children:"While this is advantageous for the project owner, it is not necessarily advantageous for the\ncode contributor."}),"\n",(0,i.jsx)(n.p,{children:"Copyright enforcement does not require all copyrights to be held by a legal entity. Any holder\nof significant copyrights can actually enforce it against violators."}),"\n",(0,i.jsxs)(n.p,{children:["The Linux kernel and an increasing number of projects do not work with copyright assignments\nnor CLAs, but with ",(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Developer_Certificate_of_Origin",children:"Developer Certificates of Origin"}),"\n(DCO \u2014 the signed-off lines of kernel commits). This is deemed sufficient to document the origin and the authorization to\ncontribute code."]}),"\n",(0,i.jsx)(n.p,{children:"The SCS project will not change the license. There however might be cases, where potential users\ncan not consume AGPL'ed or LGPL'ed code (due to corporate policies, e.g. based on bad experience,\nimmature license governance practices or lawyers that panic). Our goal would be to ensure that our\nlicensing terms and all other pledges provide the assurance needed that users do not need to be\nafraid of the AGPL. The cure provisions from v3 of the GPL license family actually also help to\navoid unnecessary fear. However, unfortunately, some \"open source\" companies in the past have\nabused copyleft with a scare and sell a proprietary license tactics to make money, which has\nhurt copyleft acceptance significantly. We might thus not be successful and need to somehow\naccept not serving all users or come up with a relicensing scheme that can not corrupt\nourselves. We are following the copyleft-next discussion to work out how we can best achieve\nthis, but have not yet found the silver bullet. This might have an influence how we do DCOs,\nmaybe under a permissive license, or maybe need to use CLAs."}),"\n",(0,i.jsx)(n.h2,{id:"license-in--license-out",children:"License in = License out"}),"\n",(0,i.jsx)(n.p,{children:"It is best practice that open source projects grant their downstream users the same\nlicense rights as they received contributions under. Or worded the opposite direction:\nIt is best practice to require no more rights to be granted from upstream contributors\n(in the CLA or DCO) than the projects grants to downstream consumers of the project.\nSCS follows this best practice."}),"\n",(0,i.jsx)(n.h2,{id:"further-reading",children:"Further reading"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Comparison_of_free_and_open-source_software_licences",children:"https://en.wikipedia.org/wiki/Comparison_of_free_and_open-source_software_licences"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Software_patents_and_free_software",children:"https://en.wikipedia.org/wiki/Software_patents_and_free_software"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://joinup.ec.europa.eu/collection/eupl/matrix-eupl-compatible-open-source-licences",children:"https://joinup.ec.europa.eu/collection/eupl/matrix-eupl-compatible-open-source-licences"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://lwn.net/Articles/592503/",children:"https://lwn.net/Articles/592503/"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://sfconservancy.org/blog/2020/jan/06/copyleft-equality/",children:"https://sfconservancy.org/blog/2020/jan/06/copyleft-equality/"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://developercertificate.org",children:"https://developercertificate.org"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/",children:"https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/"})}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cf99a16e.19992781.js b/assets/js/cf99a16e.19992781.js new file mode 100644 index 0000000000..18cbd6e3c9 --- /dev/null +++ b/assets/js/cf99a16e.19992781.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4855],{11386:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>r,default:()=>f,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var i=n(74848),t=n(28453);const o={sidebar_label:"Simple Stress",sidebar_position:55},r="Simple Stress",a={id:"iaas/guides/operations-guide/openstack/tools/simple-stress",title:"Simple Stress",description:"Overview",source:"@site/docs/02-iaas/guides/operations-guide/openstack/tools/simple-stress.md",sourceDirName:"02-iaas/guides/operations-guide/openstack/tools",slug:"/iaas/guides/operations-guide/openstack/tools/simple-stress",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/tools/simple-stress.md",tags:[],version:"current",sidebarPosition:55,frontMatter:{sidebar_label:"Simple Stress",sidebar_position:55},sidebar:"docs",previous:{title:"Sandbox Manager",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager"},next:{title:"OpenStack Health Monitor",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor"}},l={},d=[{value:"Overview",id:"overview",level:2},{value:"Installation",id:"installation",level:2},{value:"Defaults",id:"defaults",level:2},{value:"Usage",id:"usage",level:2},{value:"Config files",id:"config-files",level:2}];function c(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.h1,{id:"simple-stress",children:"Simple Stress"}),"\n",(0,i.jsx)(s.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(s.p,{children:"The OpenStack Simple Stress is a small stress test for your Openstack Cluster. You can use it for burnin tests or if you want to monitor your cluster perfomance.\nIt is able to start a predefined amount of Servers in specific networks in parallel and serial and removes them afterwards, so you can test your environment to the limits."}),"\n",(0,i.jsx)(s.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsx)(s.p,{children:"Prepare to use the Openstack Simple Stress."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"git clone https://github.com/osism/openstack-simple-stress\ncd openstack-simple-stress\npipenv install\npipenv shell\n"})}),"\n",(0,i.jsx)(s.h2,{id:"defaults",children:"Defaults"}),"\n",(0,i.jsxs)(s.p,{children:["The ",(0,i.jsx)(s.code,{children:"main.py"})," command and his default options while executing the command."]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:" --cleanup true\n --cloud simple-stress\n --compute-zone nova\n --debug false\n --delete true\n --flavor SCS-2V-8\n --floating false\n --image Ubuntu 22.04\n --interval 10 (seconds)\n --keypair unset\n --network simple-stress\n --network-zone nova\n --number 1\n --parallel 1\n --prefix simple-stress\n --storage-zone simple-stress\n --timeout 600 (seconds)\n --volume false\n --volume-number 1\n --volume-size 1 (gigabyte)\n --wait true\n"})}),"\n",(0,i.jsx)(s.h2,{id:"usage",children:"Usage"}),"\n",(0,i.jsxs)(s.p,{children:["There must be a ",(0,i.jsx)(s.code,{children:"clouds.yml"})," and a ",(0,i.jsx)(s.code,{children:"secure.yml"})," file in the directory where the OpenStack Simple Stress will be executed, examples are provided within the git repository."]}),"\n",(0,i.jsx)(s.p,{children:"The cloud profile to be used can be specified via the optional --cloud parameter. By default, the cloud profile with the name simple-stress is used."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"$ python src/main.py -h\nusage: main [-h] [--cleanup] [--cloud CLOUD] [--compute-zone COMPUTE_ZONE] [--config-dir DIR]\n [--config-file PATH] [--debug] [--delete] [--flavor FLAVOR] [--floating] [--image IMAGE]\n [--interval INTERVAL] [--keypair KEYPAIR] [--network NETWORK] [--network-zone NETWORK_ZONE]\n [--nocleanup] [--nodebug] [--nodelete] [--nofloating] [--novolume] [--nowait]\n [--number NUMBER] [--parallel PARALLEL] [--prefix PREFIX] [--storage-zone STORAGE_ZONE]\n [--timeout TIMEOUT] [--volume] [--volume-number VOLUME_NUMBER] [--volume-size VOLUME_SIZE]\n [--wait]\n\noptions:\n -h, --help show this help message and exit\n --cleanup\n --cloud CLOUD Cloud name\n --compute-zone COMPUTE_ZONE\n Compute availability zone to use\n --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted,\n so as to provide a predictable parse order if individual options are over-\n ridden. The set is parsed after the file(s) specified via previous --config-\n file, arguments hence over-ridden options in the directory take precedence. This\n option must be set from the command-line.\n --config-file PATH Path to a config file to use. Multiple config files can be specified, with\n values in later files taking precedence. Defaults to None. This option must be\n set from the command-line.\n --debug\n --delete\n --flavor FLAVOR\n --floating\n --image IMAGE\n --interval INTERVAL\n --keypair KEYPAIR\n --network NETWORK\n --network-zone NETWORK_ZONE\n Network availability zone to use\n --nocleanup The inverse of --cleanup\n --nodebug The inverse of --debug\n --nodelete The inverse of --delete\n --nofloating The inverse of --floating\n --novolume The inverse of --volume\n --nowait The inverse of --wait\n --number NUMBER\n --parallel PARALLEL\n --prefix PREFIX\n --storage-zone STORAGE_ZONE\n Storage availability zone to use\n --timeout TIMEOUT\n --volume\n --volume-number VOLUME_NUMBER\n --volume-size VOLUME_SIZE\n --wait\n"})}),"\n",(0,i.jsx)(s.p,{children:"Running a small and simple test on your Openstack environment, using Ubuntu_22.04 image with the flavor of 2VCPUs and 8Gigabytes of RAM, starting 6 servers, 2 parallel each with a volume size of 20Gigabytes."}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"$ python src/main.py --network test-net --flavor SCS-2V-8 --image Ubuntu_22.04 --number 6 --parallel 2 --volume-size 20\n2024-04-23 11:47:16 | INFO | Checking flavor SCS-2V-8\n2024-04-23 11:47:17 | INFO | flavor.id = 926f952f-0714-4c55-92c2-7514191fecce\n2024-04-23 11:47:17 | INFO | Checking image Ubuntu_22.04\n2024-04-23 11:47:17 | INFO | image.id = 667649d6-e828-403b-8871-15dde7b9ce85\n2024-04-23 11:47:17 | INFO | Checking network test-net\n2024-04-23 11:47:18 | INFO | network.id = 9688192e-11dd-4618-a18c-99d3267f630a\n2024-04-23 11:47:18 | INFO | Creating server simple-stress-0\n2024-04-23 11:47:18 | INFO | Creating server simple-stress-1\n2024-04-23 11:47:18 | INFO | Waiting for server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:18 | INFO | Waiting for server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:28 | INFO | Waiting for boot / test results of 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:29 | INFO | Waiting for boot / test results of e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:39 | INFO | Deleting server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:39 | INFO | Waiting for deletion of server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)\n2024-04-23 11:47:39 | INFO | Deleting server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:40 | INFO | Waiting for deletion of server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)\n2024-04-23 11:47:49 | INFO | Creating server simple-stress-2\n2024-04-23 11:47:50 | INFO | Creating server simple-stress-3\n2024-04-23 11:47:50 | INFO | Waiting for server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:47:51 | INFO | Waiting for server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:00 | INFO | Waiting for boot / test results of 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:48:01 | INFO | Waiting for boot / test results of a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:11 | INFO | Deleting server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:12 | INFO | Waiting for deletion of server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)\n2024-04-23 11:48:12 | INFO | Deleting server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:48:12 | INFO | Waiting for deletion of server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)\n2024-04-23 11:48:22 | INFO | Creating server simple-stress-4\n2024-04-23 11:48:22 | INFO | Waiting for server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:22 | INFO | Creating server simple-stress-5\n2024-04-23 11:48:23 | INFO | Waiting for server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:48:55 | INFO | Deleting server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:55 | INFO | Deleting server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:48:55 | INFO | Waiting for deletion of server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)\n2024-04-23 11:48:55 | INFO | Waiting for deletion of server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)\n2024-04-23 11:49:05 | INFO | Server 049bf974-b0fd-467f-aabd-3593b2a409a4 finished\n2024-04-23 11:49:05 | INFO | Server e485697f-feae-458c-952d-000072374c3f finished\n2024-04-23 11:49:05 | INFO | Server a098cc12-94ff-4036-bf42-4fc08287809f finished\n2024-04-23 11:49:05 | INFO | Server 26595dd3-09d4-4758-8d1f-58a40b681d11 finished\n2024-04-23 11:49:05 | INFO | Server 05b9f996-5a06-4359-b495-3463cc7b81e0 finished\n2024-04-23 11:49:05 | INFO | Server 8d372de6-ca07-4afb-9e80-1589fd5242e8 finished\n2024-04-23 11:49:05 | INFO | Runtime: 107.4460s\n"})}),"\n",(0,i.jsx)(s.p,{children:"Using a config directory with configfiles to run the test."}),"\n",(0,i.jsxs)(s.p,{children:["Path to a config directory to pull ",(0,i.jsx)(s.code,{children:"*.conf"})," files from. This file set is sorted,\nso as to provide a predictable parse order if individual options are over-ridden.\nThe set is parsed after the file(s) specified via previous --config file,\narguments hence over-ridden options in the directory take precedence. This\noption must be set from the command-line."]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{children:"python src/main.py --config-dir /path/to/config-dir\n"})}),"\n",(0,i.jsx)(s.h2,{id:"config-files",children:"Config files"}),"\n",(0,i.jsxs)(s.p,{children:["The config files which can be used for ",(0,i.jsx)(s.code,{children:"main.py"})," are using the ",(0,i.jsx)(s.a,{href:"https://docs.openstack.org/oslo.config/latest/configuration/quickstart.html",children:"oslo.config format"}),", you can set the command line options as ",(0,i.jsx)(s.code,{children:"key = value pair"})," and create your own config files matching your setup."]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-yaml",metastring:'title="mytest.conf"',children:"[DEFAULT]\ncloud = simple-stress\nnetwork = test-net\nnumber = 6\nparallel = 2\nflavor = SCS-2V-8\nimage = Ubuntu_22.04\nvolume-size = 20\n"})})]})}function f(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>r,x:()=>a});var i=n(96540);const t={},o=i.createContext(t);function r(e){const s=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cffc493c.4c800dbc.js b/assets/js/cffc493c.4c800dbc.js new file mode 100644 index 0000000000..cf608fed53 --- /dev/null +++ b/assets/js/cffc493c.4c800dbc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[714],{47821:(e,o,n)=>{n.r(o),n.d(o,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var t=n(74848),r=n(28453);const i={},c="Documentation workflow explanation",s={id:"contribute/docs-workflow-explanation",title:"Documentation workflow explanation",description:"The aim within this documentation is to have a good developer experience and a low entry barrier to start with SCS. For this to achieve we think all docs that define the SCS stack and have been developed by the SCS community should be within this documentation framework.",source:"@site/community/contribute/docs-workflow-explanation.md",sourceDirName:"contribute",slug:"/contribute/docs-workflow-explanation",permalink:"/community/contribute/docs-workflow-explanation",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Documentation Files Structure",permalink:"/community/contribute/doc-files-structure-guide"},next:{title:"Linting Guide",permalink:"/community/contribute/linting-guide"}},a={},d=[{value:"Information Architecture",id:"information-architecture",level:2}];function l(e){const o={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.h1,{id:"documentation-workflow-explanation",children:"Documentation workflow explanation"}),"\n",(0,t.jsx)(o.p,{children:"The aim within this documentation is to have a good developer experience and a low entry barrier to start with SCS. For this to achieve we think all docs that define the SCS stack and have been developed by the SCS community should be within this documentation framework."}),"\n",(0,t.jsx)(o.h2,{id:"information-architecture",children:"Information Architecture"}),"\n",(0,t.jsxs)(o.ul,{children:["\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsxs)(o.p,{children:["All general docs are located within the ",(0,t.jsx)(o.a,{href:"https://github.com/SovereignCloudStack/docs",children:"SovereignCloudStack/docs"})," repository."]}),"\n"]}),"\n",(0,t.jsxs)(o.li,{children:["\n",(0,t.jsx)(o.p,{children:"Docs that explain, guide or contextualize specific modules such as the openstack-image-manager or the k8s-cluster-api-provider reside within their repository in a seperate docs directory."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(o.p,{children:["Both, the general docs and docs of the external repositories are combined into the one unified documentation collection that is being rendered in a static page on ",(0,t.jsx)(o.a,{href:"https://docs.scs.community",children:"https://docs.scs.community"}),". In order to make this work we have developed a workflow that syncs all doc repositories and distills only the relevant markdown files."]}),"\n",(0,t.jsxs)(o.p,{children:["The script is called ",(0,t.jsx)(o.code,{children:"getDocs"}),". It is a postinstall script and is executed after ",(0,t.jsx)(o.code,{children:"npm install"}),". This has the advantage to have the docs \u2013 coming from the cloud \u2013 in your local docusaurus development environment as well as in the build process."]}),"\n",(0,t.jsxs)(o.p,{children:["You'll find the script in the root directory of the ",(0,t.jsx)(o.a,{href:"https://github.com/SovereignCloudStack/docs-page",children:"SovereignCloudStack/docs-page"})," repository:"]}),"\n",(0,t.jsx)(o.pre,{children:(0,t.jsx)(o.code,{className:"language-js",metastring:'title="getDocs.js"',children:"const fs = require('fs')\nconst { execSync } = require('child_process')\n\n// Read the contents of the \"docs.package.json\" file and remove all whitespace\nconst reposJson = fs\n .readFileSync('./docs.package.json', 'utf8')\n .replace(/\\s/g, '')\n\n// Parse the JSON and create an array of repositories\nconst repos = JSON.parse(reposJson)\nconst ghUrl = 'https://github.com/'\n\n// Clone each repository, remove git folders and README files, and copy the docs to the target directory\nrepos.forEach((repo) => {\n const repoDir = `repo_to_be_edited/${repo.label}`\n\n // Clone the repository\n const cloneCommand = `git clone ${ghUrl + repo.repo} ${repoDir}`\n execSync(cloneCommand)\n\n // Remove git folders\n const removeGitCommand = `rm -rf ${repoDir}/.git`\n execSync(removeGitCommand)\n\n // Remove README files\n const removeReadmeCommand = `find ${repoDir} -name \"README.md\" | xargs rm -f`\n execSync(removeReadmeCommand)\n\n // Create the docusaurus subdirectory\n const subDirPath = `${repo.target}/${repo.label}`\n fs.mkdirSync(subDirPath, { recursive: true })\n\n // Copy docs content from A to B\n const copyDocsCommand = `cp -r ${repoDir}/${repo.source} ${subDirPath}`\n execSync(copyDocsCommand)\n\n // Remove the cloned repository\n const removeRepoCommand = 'rm -rf repo_to_be_edited'\n execSync(removeRepoCommand)\n})\n"})})]})}function h(e={}){const{wrapper:o}={...(0,r.R)(),...e.components};return o?(0,t.jsx)(o,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,o,n)=>{n.d(o,{R:()=>c,x:()=>s});var t=n(96540);const r={},i=t.createContext(r);function c(e){const o=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function s(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(i.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d0ee365b.cbfaa316.js b/assets/js/d0ee365b.cbfaa316.js new file mode 100644 index 0000000000..af221df7e8 --- /dev/null +++ b/assets/js/d0ee365b.cbfaa316.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6223],{14461:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>a});var i=t(74848),l=t(28453);const s={sidebar_label:"OpenStack",sidebar_position:30},r="OpenStack",o={id:"iaas/guides/configuration-guide/openstack/index",title:"OpenStack",description:"Image tags",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/index.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/",permalink:"/docs/iaas/guides/configuration-guide/openstack/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/index.md",tags:[],version:"current",sidebarPosition:30,frontMatter:{sidebar_label:"OpenStack",sidebar_position:30},sidebar:"docs",previous:{title:"Ceph",permalink:"/docs/iaas/guides/configuration-guide/ceph"},next:{title:"Aodh",permalink:"/docs/iaas/guides/configuration-guide/openstack/aodh"}},c={},a=[{value:"Image tags",id:"image-tags",level:2},{value:"Endpoints",id:"endpoints",level:2},{value:"Public endpoints",id:"public-endpoints",level:3},{value:"Example for the use of name-based endpoints",id:"example-for-the-use-of-name-based-endpoints",level:3},{value:"Network interfaces",id:"network-interfaces",level:2},{value:"Customization of the service configurations",id:"customization-of-the-service-configurations",level:2},{value:"How does the configuration get into services?",id:"how-does-the-configuration-get-into-services",level:2},{value:"Number of service workers",id:"number-of-service-workers",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,l.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"openstack",children:"OpenStack"}),"\n",(0,i.jsx)(n.h2,{id:"image-tags",children:"Image tags"}),"\n",(0,i.jsxs)(n.p,{children:["Sometimes it is necessary to specify the image tag to be used for a specific service or a specific image of a service.\nAll available images and tags are listed in the ",(0,i.jsx)(n.a,{href:"https://github.com/osism/defaults/blob/main/all/002-images-kolla.yml",children:"002-images-kolla.yml"}),"\nfile."]}),"\n",(0,i.jsxs)(n.p,{children:["The image tags can be set in the ",(0,i.jsx)(n.code,{children:"environments/kolla/images.yml"})," file."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Use a specific tag for all images of a service:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/images.yml"',children:'barbican_tag: "2023.1"\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Use a specific tag for a specific image of a service:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/images.yml"',children:'barbican_worker_tag: "2023.1"\n'})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"endpoints",children:"Endpoints"}),"\n",(0,i.jsx)(n.h3,{id:"public-endpoints",children:"Public endpoints"}),"\n",(0,i.jsxs)(n.p,{children:["The public endpoints used for the individual OpenStack services can be configured via the ",(0,i.jsx)(n.code,{children:"public_endpoint"})," parameters.\nThese are defined as follows."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Default value"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"aodh_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"aodh_external_fqdn | kolla_url(public_protocol, aodh_api_public_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"blazar_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"blazar_external_fqdn | kolla_url(public_protocol, blazar_api_public_port, '/v1')"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"ceph_rgw_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ceph_rgw_external_fqdn | kolla_url(public_protocol, ceph_rgw_public_port, ceph_rgw_endpoint_path)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"cinder_v3_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ cinder_public_base_endpoint }}/v3/%(tenant_id)s"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"cloudkitty_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"cloudkitty_external_fqdn | kolla_url(public_protocol, cloudkitty_api_public_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"cyborg_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"cyborg_external_fqdn | kolla_url(public_protocol, cyborg_api_port, '/v2')"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"gnocchi_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"gnocchi_external_fqdn | kolla_url(public_protocol, gnocchi_api_public_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"heat_cfn_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ heat_cfn_public_base_endpoint }}/v1"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"heat_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"heat_external_fqdn | kolla_url(public_protocol, heat_api_public_port, '/v1/%(tenant_id)s')"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"ironic_inspector_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ironic_inspector_external_fqdn | kolla_url(public_protocol, ironic_inspector_public_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"magnum_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"magnum_external_fqdn | kolla_url(public_protocol, magnum_api_public_port, '/v1')"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"manila_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ manila_public_base_endpoint }}/v1/%(tenant_id)s"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"manila_v2_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ manila_public_base_endpoint }}/v2"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"masakari_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"masakari_external_fqdn | kolla_url(public_protocol, masakari_api_public_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"mistral_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"mistral_external_fqdn | kolla_url(public_protocol, mistral_api_public_port, '/v2')"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"nova_legacy_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ nova_public_base_endpoint }}/v2/%(tenant_id)s"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"nova_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ nova_public_base_endpoint }}/v2.1"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"placement_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"placement_external_fqdn | kolla_url(public_protocol, placement_api_public_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"tacker_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"tacker_external_fqdn | kolla_url(public_protocol, tacker_server_public_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"trove_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"trove_external_fqdn | kolla_url(public_protocol, trove_api_public_port, '/v1.0/%(tenant_id)s')"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"venus_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"venus_external_fqdn | kolla_url(public_protocol, venus_api_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"watcher_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"watcher_external_fqdn | kolla_url(public_protocol, watcher_api_public_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"zun_public_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"zun_external_fqdn | kolla_url(public_protocol, zun_api_public_port, '/v1/')"})})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["Some of the previous default values refer to a ",(0,i.jsx)(n.code,{children:"public_base_endpoint parameter"}),". These are defined as follows."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Default value"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"cinder_public_base_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"cinder_external_fqdn | kolla_url(public_protocol, cinder_api_public_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"heat_cfn_public_base_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"heat_cfn_external_fqdn | kolla_url(public_protocol, heat_api_cfn_public_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"manila_public_base_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"manila_external_fqdn | kolla_url(public_protocol, manila_api_public_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"nova_public_base_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"nova_external_fqdn | kolla_url(public_protocol, nova_api_public_port)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"skyline_apiserver_public_base_endpoint"}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"skyline_apiserver_external_fqdn | kolla_url(public_protocol, skyline_apiserver_public_port)"})})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"example-for-the-use-of-name-based-endpoints",children:"Example for the use of name-based endpoints"}),"\n",(0,i.jsxs)(n.p,{children:["DNS records pointing to the ",(0,i.jsx)(n.code,{children:"kolla_external_vip_address"})," are created in advance."]}),"\n",(0,i.jsxs)(n.p,{children:["Additional configuration parameters to overwrite the public endpoints\nare added in the ",(0,i.jsx)(n.code,{children:"environments/kolla/configuration.yml"})," file. If certain services\nare not used, they are removed. If other services are used, these are added (see the\ntable above)."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:"barbican_public_endpoint: https://barbican.services.a.regiocloud.tech\ncinder_public_base_endpoint: https://cinder.services.a.regiocloud.tech\ndesignate_public_endpoint: https://designate.services.a.regiocloud.tech\nglance_public_endpoint: https://glance.services.a.regiocloud.tech\nironic_public_endpoint: https://ironic.services.a.regiocloud.tech\nkeystone_public_url: https://keystone.services.a.regiocloud.tech\nmanila_public_endpoint: https://manila.services.a.regiocloud.tech\nneutron_public_endpoint: https://neutron.services.a.regiocloud.tech\nnova_public_base_endpoint: https://nova.services.a.regiocloud.tech\noctavia_public_endpoint: https://octavia.services.a.regiocloud.tech\nplacement_public_endpoint: https://placement.services.a.regiocloud.tech\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Since we bind the ",(0,i.jsx)(n.code,{children:"name_based_external_front"})," frontend to the same ports as the\n",(0,i.jsx)(n.code,{children:"horizon_external_front"}),", the external Horizon frontend must be disabled. This is\nonly possible as of OSISM 7.0.6."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:"haproxy_enable_horizon_external: false\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Additional HAProxy configuration in ",(0,i.jsx)(n.code,{children:"haproxy/services.d/haproxy.cfg"})," is required to map\nthe DNS records to the correct backends. Here too, unused services are removed or\nadditional services are added."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-none",metastring:'title="environments/kolla/files/overlays/haproxy/services.d/haproxy.cfg"',children:"frontend name_based_external_front\n mode http\n http-request del-header X-Forwarded-Proto\n option httplog\n option forwardfor\n http-request set-header X-Forwarded-Proto https if { ssl_fc }\n bind {{ kolla_external_vip_address }}:80\n bind {{ kolla_external_vip_address }}:443 ssl crt /etc/haproxy/certificates/haproxy.pem\n default_backend horizon_back\n\n acl ACL_keystone.services.a.regiocloud.tech hdr(host) -i keystone.services.a.regiocloud.tech\n use_backend keystone_external_back if ACL_keystone.services.a.regiocloud.tech\n\n acl ACL_glance.services.a.regiocloud.tech hdr(host) -i glance.services.a.regiocloud.tech\n use_backend glance_api_external_back if ACL_glance.services.a.regiocloud.tech\n\n acl ACL_neutron.services.a.regiocloud.tech hdr(host) -i neutron.services.a.regiocloud.tech\n use_backend neutron_server_external_back if ACL_neutron.services.a.regiocloud.tech\n\n acl ACL_placement.services.a.regiocloud.tech hdr(host) -i placement.services.a.regiocloud.tech\n use_backend placement_api_external_back if ACL_placement.services.a.regiocloud.tech\n\n acl ACL_nova.services.a.regiocloud.tech hdr(host) -i nova.services.a.regiocloud.tech\n use_backend nova_api_external_back if ACL_nova.services.a.regiocloud.tech\n\n acl ACL_console.services.a.regiocloud.tech hdr(host) -i console.services.a.regiocloud.tech\n use_backend nova_novncproxy_external_back if ACL_console.services.a.regiocloud.tech\n\n acl ACL_designate.services.a.regiocloud.tech hdr(host) -i designate.services.a.regiocloud.tech\n use_backend designate_api_external_back if ACL_designate.services.a.regiocloud.tech\n\n acl ACL_cinder.services.a.regiocloud.tech hdr(host) -i cinder.services.a.regiocloud.tech\n use_backend cinder_api_external_back if ACL_cinder.services.a.regiocloud.tech\n\n acl ACL_octavia.services.a.regiocloud.tech hdr(host) -i octavia.services.a.regiocloud.tech\n use_backend octavia_api_external_back if ACL_octavia.services.a.regiocloud.tech\n\n acl ACL_swift.services.a.regiocloud.tech hdr(host) -i swift.services.a.regiocloud.tech\n use_backend swift_api_external_back if ACL_swift.services.a.regiocloud.tech\n\n acl ACL_ironic.services.a.regiocloud.tech hdr(host) -i ironic.services.a.regiocloud.tech\n use_backend ironic_api_external_back if ACL_ironic.services.a.regiocloud.tech\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Additional Nova configuration in ",(0,i.jsx)(n.code,{children:"nova.conf"})," is required to use the URL for the NoVNC service."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",metastring:'title="environments/kolla/files/overlays/nova.conf"',children:"[vnc]\nnovncproxy_base_url = https://console.services.a.regiocloud.tech/vnc_lite.html\n"})}),"\n",(0,i.jsx)(n.h2,{id:"network-interfaces",children:"Network interfaces"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Default"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"network_interface"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"eth0"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"neutron_external_interface"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ network_interface }}"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"kolla_external_vip_interface"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ network_interface }}"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"api_interface"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ network_interface }}"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"migration_interface"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ api_interface }}"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"tunnel_interface"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ network_interface }}"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"octavia_network_interface"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ 'o-hm0' if octavia_network_type == 'tenant' else api_interface }}"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"dns_interface"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ network_interface }}"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"dpdk_tunnel_interface"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ neutron_external_interface }}"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ironic_http_interface"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ api_interface }}"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"ironic_tftp_interface"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"{{ api_interface }}"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"}})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"customization-of-the-service-configurations",children:"Customization of the service configurations"}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["The following content is based on the ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/kolla-ansible/latest/admin/advanced-configuration.html#openstack-service-configuration-in-kolla",children:"kolla-ansible uptream documentation"}),"."]})}),"\n",(0,i.jsxs)(n.p,{children:["OSISM will generally look for files in ",(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/CONFIGFILE"}),",\n",(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/SERVICENAME/CONFIGFILE"})," or ",(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/SERVICENAME/HOSTNAME/CONFIGFILE"}),"\nin the configuration repository. These locations sometimes vary and you should check the config task in the appropriate\nAnsible role for a full list of supported locations. For example, in the case of ",(0,i.jsx)(n.code,{children:"nova.conf"})," the following locations are\nsupported, assuming that you have services using ",(0,i.jsx)(n.code,{children:"nova.conf"})," running on hosts called ctl1, ctl2 and ctl3:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/nova.conf"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/nova/ctl1/nova.conf"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/nova/ctl2/nova.conf"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/nova/ctl3/nova.conf"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/nova/nova-scheduler.conf"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Using this mechanism, overrides can be configured per-project (Nova), per-project-service (Nova scheduler service) or\nper-project-service-on-specified-host (Nova servies on ctl1)."}),"\n",(0,i.jsxs)(n.p,{children:["Overriding an option is as simple as setting the option under the relevant section. For example, to set\noverride ",(0,i.jsx)(n.code,{children:"scheduler_max_attempts"})," in the Nova scheduler service, the operator could create\n",(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/nova/nova-scheduler.conf"})," in the configuration repository with this content:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",children:"[DEFAULT]\nscheduler_max_attempts = 100\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the operator wants to configure the initial disk, cpu and ram allocation ratio on compute node ",(0,i.jsx)(n.code,{children:"com1"}),",\nthe operator needs to create the file ",(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/nova/com1/nova.conf"})," with this\ncontent:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",children:"[DEFAULT]\ninitial_cpu_allocation_ratio = 3.0\ninitial_ram_allocation_ratio = 1.0\ninitial_disk_allocation_ratio = 1.0\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Note that the numbers shown here with an ",(0,i.jsx)(n.code,{children:"initial_cpu_allocation_ratio"})," of 3.0 do match the requirements\nof the SCS-nV-* (moderate oversubscription) flavors. If you do not use SMT/hyperthreading, SCS would allow\n5.0 here (for the V flavors)."]}),"\n",(0,i.jsxs)(n.p,{children:["This method of merging configuration sections is supported for all services using ",(0,i.jsx)(n.a,{href:"https://docs.openstack.org/oslo.config/latest/",children:"oslo.config"}),",\nwhich includes the vast majority of OpenStack services, and in some cases for services using YAML configuration.\nSince the INI format is an informal standard, not all INI files can be merged in this way. In these cases OSISM supports\noverriding the entire config file."]}),"\n",(0,i.jsxs)(n.p,{children:["Additional flexibility can be introduced by using Jinja conditionals in the config files. For example, you may create\nNova cells which are homogeneous with respect to the hypervisor model. In each cell, you may wish to configure the\nhypervisors differently, for example the following override shows one way of setting the ",(0,i.jsx)(n.code,{children:"bandwidth_poll_interval"}),"\nvariable as a function of the cell:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",children:"[DEFAULT]\n{% if 'cell0001' in group_names %}\nbandwidth_poll_interval = 100\n{% elif 'cell0002' in group_names %}\nbandwidth_poll_interval = -1\n{% else %}\nbandwidth_poll_interval = 300\n{% endif %}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["An alternative to Jinja conditionals would be to define a variable for the ",(0,i.jsx)(n.code,{children:"bandwidth_poll_interval"})," and set\nit in according to your requirements in the inventory group or host vars:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",children:"[DEFAULT]\nbandwidth_poll_interval = {{ bandwidth_poll_interval }}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["OSISM allows the operator to override configuration globally for all services. It will look for a file\ncalled ",(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/global.conf"})," in the configuration repository."]}),"\n",(0,i.jsxs)(n.p,{children:["For example to modify database pool size connection for all services, the operator needs to create\n",(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/global.conf"})," in the configuration repository with this content:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ini",children:"[database]\nmax_pool_size = 100\n"})}),"\n",(0,i.jsx)(n.h2,{id:"how-does-the-configuration-get-into-services",children:"How does the configuration get into services?"}),"\n",(0,i.jsx)(n.p,{children:"It is explained with example of OpenSearch Service how the configuration for OpenSearch\nis created and gets into the container."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The task ",(0,i.jsx)(n.a,{href:"https://github.com/openstack/kolla-ansible/blob/master/ansible/roles/opensearch/tasks/config.yml",children:"Copying over opensearch service config file"}),"\nmerges the individual sources of the files."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="Copying over opensearch service config file task"',children:'- name: Copying over opensearch service config file\n merge_yaml:\n sources:\n # highlight-start\n - "{{ role_path }}/templates/opensearch.yml.j2"\n - "{{ node_custom_config }}/opensearch.yml"\n - "{{ node_custom_config }}/opensearch/opensearch.yml"\n - "{{ node_custom_config }}/opensearch/{{ inventory_hostname }}/opensearch.yml"\n # highlight-end\n dest: "{{ node_config_directory }}/opensearch/opensearch.yml"\n mode: "0660"\n become: true\n when:\n - inventory_hostname in groups[\'opensearch\']\n - opensearch_services[\'opensearch\'].enabled | bool\n notify:\n - Restart opensearch container\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["As a basis a template ",(0,i.jsx)(n.a,{href:"https://github.com/openstack/kolla-ansible/blob/master/ansible/roles/opensearch/templates/opensearch.yml.j2",children:"opensearch.yml.j2"}),"\nis used which is part of the OpenSearch service role."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="opensearch.yml.j2 template"',children:"{% set num_nodes = groups['opensearch'] | length %}\n{% set recover_after_nodes = (num_nodes * 2 / 3) | round(0, 'floor') | int if num_nodes > 1 else 1 %}\nplugins.security.disabled: \"true\"\n\nnode.name: \"{{ 'api' | kolla_address | put_address_in_context('url') }}\"\nnetwork.host: \"{{ 'api' | kolla_address | put_address_in_context('url') }}\"\n\ncluster.name: \"{{ opensearch_cluster_name }}\"\ncluster.initial_master_nodes: [{% for host in groups['opensearch'] %}\"{{ 'api' | kolla_address(host) }}\"{% if not loop.last %},{% endif %}{% endfor %}]\nnode.master: true\nnode.data: true\ndiscovery.seed_hosts: [{% for host in groups['opensearch'] %}\"{{ 'api' | kolla_address(host) | put_address_in_context('url') }}\"{% if not loop.last %},{% endif %}{% endfor %}]\n\nhttp.port: {{ opensearch_port }}\ngateway.expected_nodes: {{ num_nodes }}\ngateway.recover_after_time: \"5m\"\ngateway.recover_after_nodes: {{ recover_after_nodes }}\npath.data: \"/var/lib/opensearch/data\"\npath.logs: \"/var/log/kolla/opensearch\"\nindices.fielddata.cache.size: 40%\naction.auto_create_index: \"true\"\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"For OpenSearch, overlay files can additionally be stored in 3 places in the configuration repository."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/opensearch.yml"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/opensearch/opensearch.yml"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/opensearch/{{ inventory_hostname }}/opensearch.yml"})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["When merging files, the last file found has the most weight. If there is a parameter ",(0,i.jsx)(n.code,{children:"node.master: true"}),"\nin the service role template ",(0,i.jsx)(n.code,{children:"opensearch.yml.j2"})," of the OpenSearch service and you set e.g.\n",(0,i.jsx)(n.code,{children:"node.master: false"})," in ",(0,i.jsx)(n.code,{children:"environments/kolla/files/overlays/opensearch.yml"})," then accordingly in the finished ",(0,i.jsx)(n.code,{children:"opensearch.yml"}),"\n",(0,i.jsx)(n.code,{children:"node.master: false"})," is used."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["After the merge the task ",(0,i.jsx)(n.code,{children:"Copying over opensearch service config file"})," copies the content into the\nconfiguration directory ",(0,i.jsx)(n.code,{children:"/etc/kolla/opensearch"})," of the service."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="/etc/kolla/opensearch/opensearch.yml"',children:"action.auto_create_index: 'true'\ncluster.initial_master_nodes:\n- 192.168.16.10\ncluster.name: kolla_logging\ndiscovery.seed_hosts:\n- 192.168.16.10\ngateway.expected_nodes: 1\ngateway.recover_after_nodes: 1\ngateway.recover_after_time: 5m\nhttp.port: 9200\nindices.fielddata.cache.size: 40%\nnetwork.host: 192.168.16.10\nnode.data: true\nnode.master: true\nnode.name: 192.168.16.10\npath.data: /var/lib/opensearch/data\npath.logs: /var/log/kolla/opensearch\nplugins.security.disabled: 'true'\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["The configuration directory ",(0,i.jsx)(n.code,{children:"/etc/kolla/opensearch"})," is mounted in each container of the OpenSearch service\nto ",(0,i.jsx)(n.code,{children:"/var/lib/kolla/config_files"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",metastring:'title="Output of docker inspect opensearch"',children:'"Mounts": [\n {\n "Type": "bind",\n // highlight-start\n "Source": "/etc/kolla/opensearch",\n "Destination": "/var/lib/kolla/config_files",\n // highlight-end\n "Mode": "rw",\n "RW": true,\n "Propagation": "rprivate"\n },\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Entrypoint of a service is always ",(0,i.jsx)(n.a,{href:"https://github.com/openstack/kolla/blob/master/docker/base/start.sh",children:"kolla_start"}),".\nThis script calls a script ",(0,i.jsx)(n.a,{href:"https://github.com/openstack/kolla/blob/master/docker/base/set_configs.py",children:"set_configs.py"}),".\nThis script takes care of copying files from ",(0,i.jsx)(n.code,{children:"/var/lib/kolla/config_files"})," to the right place inside the container.\nFor this purpose, the container has a\n",(0,i.jsx)(n.a,{href:"https://github.com/openstack/kolla-ansible/blob/master/ansible/roles/opensearch/templates/opensearch.json.j2",children:"config.json"}),"\nin which the individual actions are configured."]}),"\n",(0,i.jsxs)(n.p,{children:["The file ",(0,i.jsx)(n.code,{children:"/var/lib/kolla/config_files/opensearch.yml"})," is copied to ",(0,i.jsx)(n.code,{children:"/etc/opensearch/opensearch.yml"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The permissions of ",(0,i.jsx)(n.code,{children:"/var/lib/opensearch"})," and ",(0,i.jsx)(n.code,{children:"/var/log/kolla/opensearch"})," are set accordingly."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",metastring:'title="/etc/kolla/opensearch/config.json"',children:'{\n "command": "/usr/share/opensearch/bin/opensearch",\n "config_files": [\n {\n // highlight-start\n "source": "/var/lib/kolla/config_files/opensearch.yml",\n "dest": "/etc/opensearch/opensearch.yml",\n "owner": "opensearch",\n "perm": "0600"\n // highlight-end\n }\n ],\n "permissions": [\n {\n // highlight-start\n "path": "/var/lib/opensearch",\n "owner": "opensearch:opensearch",\n "recurse": true\n // highlight-end\n },\n {\n // highlight-start\n "path": "/var/log/kolla/opensearch",\n "owner": "opensearch:opensearch",\n "recurse": true\n // highlight-end\n }\n ]\n}\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["In the ",(0,i.jsx)(n.code,{children:"config.json"})," of the service is also defined the command which will be executed after finishing the preparations.\nIn the case of OpenSearch this is ",(0,i.jsx)(n.code,{children:"/usr/share/opensearch/bin/opensearch"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",metastring:'title="/etc/kolla/opensearch/config.json"',children:'{\n // highlight-start\n "command": "/usr/share/opensearch/bin/opensearch",\n // highlight-end\n "config_files": [\n {\n "source": "/var/lib/kolla/config_files/opensearch.yml",\n "dest": "/etc/opensearch/opensearch.yml",\n "owner": "opensearch",\n "perm": "0600"\n }\n ],\n "permissions": [\n {\n "path": "/var/lib/opensearch",\n "owner": "opensearch:opensearch",\n "recurse": true\n },\n {\n "path": "/var/log/kolla/opensearch",\n "owner": "opensearch:opensearch",\n "recurse": true\n }\n ]\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"number-of-service-workers",children:"Number of service workers"}),"\n",(0,i.jsx)(n.p,{children:"The number of workers used for the individual services can generally be configured using two parameters."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'openstack_service_workers: "{{ [ansible_facts.processor_vcpus, 5] | min }}"\nopenstack_service_rpc_workers: "{{ [ansible_facts.processor_vcpus, 3] | min }}\u201c\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The default for ",(0,i.jsx)(n.code,{children:"openstack_service_workers"})," is set to ",(0,i.jsx)(n.code,{children:"5"})," when using the cookiecutter for the initial creation\nof the configuration."]}),"\n",(0,i.jsxs)(n.p,{children:["This value can be overwritten for individual services. The default for all parameters in the following table is\n",(0,i.jsx)(n.code,{children:"{{ openstack_service_workers }}"}),". The parameter ",(0,i.jsx)(n.code,{children:"aodh_api_workers"})," can then be used to explicitly set the\nnumber of workers for the AODH API, for example. A reconfigure must be made for the particular services in the\ncase of a change. ",(0,i.jsx)(n.code,{children:"osism apply -a reconfigure aodh"})," in this example."]}),"\n",(0,i.jsxs)(n.p,{children:["These parameters are all set in ",(0,i.jsx)(n.code,{children:"environments/kolla/configuration.yml"}),"."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"})})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"aodh_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"barbican_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"cinder_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"designate_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"designate_worker_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"designate_producer_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"designate_central_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"designate_sink_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"designate_mdns_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"glance_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"gnocchi_metricd_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"gnocchi_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"heat_api_cfn_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"heat_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"heat_engine_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"horizon_wsgi_processes"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"ironic_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"keystone_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"proxysql_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"magnum_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"magnum_conductor_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"manila_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"neutron_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"neutron_metadata_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"nova_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"nova_superconductor_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"nova_metadata_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"nova_scheduler_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"nova_cell_conductor_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"octavia_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"octavia_healthmanager_health_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"octavia_healthmanager_stats_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"placement_api_workers"})}),(0,i.jsx)(n.tr,{children:(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"skyline_gunicorn_workers"})})]})]})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var i=t(96540);const l={},s=i.createContext(l);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d14d7097.55a1c622.js b/assets/js/d14d7097.55a1c622.js new file mode 100644 index 0000000000..efabcef307 --- /dev/null +++ b/assets/js/d14d7097.55a1c622.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7919],{82916:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>u});var o=n(74848),s=n(28453);const i={sidebar_label:"Neutron"},r="Neutron",a={id:"iaas/guides/operations-guide/openstack/neutron",title:"Neutron",description:"Quality of Service (QoS)",source:"@site/docs/02-iaas/guides/operations-guide/openstack/neutron.md",sourceDirName:"02-iaas/guides/operations-guide/openstack",slug:"/iaas/guides/operations-guide/openstack/neutron",permalink:"/docs/iaas/guides/operations-guide/openstack/neutron",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/neutron.md",tags:[],version:"current",frontMatter:{sidebar_label:"Neutron"},sidebar:"docs",previous:{title:"Keystone",permalink:"/docs/iaas/guides/operations-guide/openstack/keystone"},next:{title:"Nova",permalink:"/docs/iaas/guides/operations-guide/openstack/nova"}},c={},u=[{value:"Quality of Service (QoS)",id:"quality-of-service-qos",level:2}];function d(e){const t={a:"a",h1:"h1",h2:"h2",li:"li",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"neutron",children:"Neutron"}),"\n",(0,o.jsx)(t.h2,{id:"quality-of-service-qos",children:"Quality of Service (QoS)"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://docs.openstack.org/neutron/latest/admin/config-qos.html",children:"https://docs.openstack.org/neutron/latest/admin/config-qos.html"})}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var o=n(96540);const s={},i=o.createContext(s);function r(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d1aa920e.0bf904c1.js b/assets/js/d1aa920e.0bf904c1.js new file mode 100644 index 0000000000..1d145d77c7 --- /dev/null +++ b/assets/js/d1aa920e.0bf904c1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3920],{66459:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>d});var t=s(74848),o=s(28453);const i={sidebar_label:"OpenStack"},r="OpenStack",l={id:"iaas/guides/operations-guide/openstack/index",title:"OpenStack",description:"Create an external network",source:"@site/docs/02-iaas/guides/operations-guide/openstack/index.md",sourceDirName:"02-iaas/guides/operations-guide/openstack",slug:"/iaas/guides/operations-guide/openstack/",permalink:"/docs/iaas/guides/operations-guide/openstack/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/index.md",tags:[],version:"current",frontMatter:{sidebar_label:"OpenStack"},sidebar:"docs",previous:{title:"Network",permalink:"/docs/iaas/guides/operations-guide/network"},next:{title:"Tools",permalink:"/docs/iaas/guides/operations-guide/openstack/tools/"}},c={},d=[{value:"Create an external network",id:"create-an-external-network",level:2},{value:"Reboot a compute node",id:"reboot-a-compute-node",level:2},{value:"Add a new compute node",id:"add-a-new-compute-node",level:2},{value:"Remove a compute node",id:"remove-a-compute-node",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"openstack",children:"OpenStack"}),"\n",(0,t.jsx)(n.h2,{id:"create-an-external-network",children:"Create an external network"}),"\n",(0,t.jsxs)(n.p,{children:["The play ",(0,t.jsx)(n.code,{children:"network-external"})," is available and usable as of OSISM 7.0.6."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply network-external\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Available parameters for the OpenStack Environment (",(0,t.jsx)(n.code,{children:"environments/openstack/configuration.yml"}),")."]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,t.jsx)(n.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_allocation_pool_end"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:'"192.168.112.200"'})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_allocation_pool_start"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:'"192.168.112.100"'})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_cidr"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:'"192.168.112.0/20"'})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_cloud"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"admin"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_gateway_ip"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:'"192.168.112.5"'})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_name"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"public"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_provider_network_type"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"flat"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_provider_physical_network"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"physnet1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"network_external_state"}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"present"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"reboot-a-compute-node",children:"Reboot a compute node"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Live migrate all instances running on the compute node\nwith the help of the ",(0,t.jsx)(n.a,{href:"./tools/resource-manager#live-migration",children:"OpenStack Resource Manager"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Ensure that no more instances are running on the compute node"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"ps ax | grep qemu\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Reboot the compute node"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply reboot -l NODE -e ireallymeanit=yes\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Wait for the compute node to reboot"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Re-enable the compute service"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'openstack --os-cloud admin compute service set --enable --disable-reason "" NODE nova-compute\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Check compute service"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"openstack --os-cloud admin compute service list --host NODE --service nova-compute\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"add-a-new-compute-node",children:"Add a new compute node"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Add the operater user"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply operator -u osism -l NODE\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Run the bootstrap"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply bootstrap -l NODE\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"When a routed network fabric is used deploy the FRR service (optional)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply frr -l NODE\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy logging service and Prometheus exporters"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply common -l NODE\nosism apply prometheus -l NODE\nosism apply scaphandre -l NODE\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy network services"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply openvswitch -l NODE\nosism apply ovn -l NODE\nosism apply neutron -l NODE\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you do not use the OVN SDN skip ",(0,t.jsx)(n.code,{children:"osism apply ovn -l NODE"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy compute services"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply nova -l NODE\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy telemetry services (optional)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply ceilometer -l NODE\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Deploy Netdata service (optional)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply netdata -l NODE\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Add compute node to Prometheus monitoring"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply prometheus -l monitoring\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Refresh the ",(0,t.jsx)(n.code,{children:"/etc/hosts"})," file"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply hosts\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Refresh the SSH client configuration file"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply sshconfig\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Add compute node to the known hosts file"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply known-hosts\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Containers that run on a compute node. Versions may differ. There is no ",(0,t.jsx)(n.code,{children:"ceilometer_compute"})," container\nif you have not deployed the optional OpenStack telemetry service."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'$ docker ps\nCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n559e5176695c quay.io/osism/nova-compute:27.1.1.20230919 "dumb-init --single-\u2026" 5 minutes ago Up 5 minutes (healthy) nova_compute\n31248d71ab7d quay.io/osism/nova-libvirt:8.0.0.20230919 "dumb-init --single-\u2026" 6 minutes ago Up 6 minutes (healthy) nova_libvirt\n9292030d706c quay.io/osism/nova-ssh:27.1.1.20230919 "dumb-init --single-\u2026" 6 minutes ago Up 6 minutes (healthy) nova_ssh\nfda4b6fb30c8 quay.io/osism/neutron-metadata-agent:22.0.3.20230919 "dumb-init --single-\u2026" 2 hours ago Up 2 hours (healthy) neutron_ovn_metadata_agent\n0e3ec450b668 quay.io/osism/ceilometer-compute:20.0.1.20230919 "dumb-init --single-\u2026" 6 hours ago Up 6 hours (healthy) ceilometer_compute\n25ff9702e0e5 quay.io/osism/prometheus-libvirt-exporter:6.0.0.20230919 "dumb-init --single-\u2026" 6 hours ago Up 6 hours prometheus_libvirt_exporter\n1bff2e29923b quay.io/osism/prometheus-cadvisor:0.45.0.20230919 "dumb-init --single-\u2026" 6 hours ago Up 6 hours prometheus_cadvisor\n602832daf237 quay.io/osism/prometheus-node-exporter:1.4.0.20230919 "dumb-init --single-\u2026" 6 hours ago Up 6 hours prometheus_node_exporter\nd4de2f32cdf8 quay.io/osism/ovn-controller:23.6.1.20230919 "dumb-init --single-\u2026" 6 hours ago Up 6 hours ovn_controller\n3bf43ae5a94f quay.io/osism/openvswitch-vswitchd:3.1.2.20230919 "dumb-init --single-\u2026" 7 hours ago Up 7 hours (healthy) openvswitch_vswitchd\nebc048b02ab2 quay.io/osism/openvswitch-db-server:3.1.2.20230919 "dumb-init --single-\u2026" 7 hours ago Up 7 hours (healthy) openvswitch_db\n4f33dfa66c14 hubblo/scaphandre:0.5.0 "scaphandre promethe\u2026" 7 hours ago Up 7 hours 10.10.129.64:9155->8080/tcp scaphandre\n9b1f6342dc60 quay.io/osism/cron:3.0.20230919 "dumb-init --single-\u2026" 7 hours ago Up 7 hours cron\n718aecaddde1 quay.io/osism/kolla-toolbox:16.1.1.20230919 "dumb-init --single-\u2026" 7 hours ago Up 7 hours kolla_toolbox\nf6f9422c1853 quay.io/osism/fluentd:4.5.1.20230919 "dumb-init --single-\u2026" 7 hours ago Up 7 hours fluentd\n'})}),"\n",(0,t.jsx)(n.h2,{id:"remove-a-compute-node",children:"Remove a compute node"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["In the configuration repository remove the compute node everywhere. Then update the configuration\nrepository on the manager with ",(0,t.jsx)(n.code,{children:"osism apply configuration"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Live migrate all instances running on the compute node\nwith the help of the ",(0,t.jsx)(n.a,{href:"./tools/resource-manager#live-migration",children:"OpenStack Resource Manager"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Evacuate all instances on the compute node\nwith the help of the ",(0,t.jsx)(n.a,{href:"./tools/resource-manager#evacutation",children:"OpenStack Resource Manager"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Ensure that no more instances are running on the compute node"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"ps ax | grep qemu\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Stop all OpenStack compute services on the compute node"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"systemctl stop kolla-nova_ssh-container.service\nsystemctl stop kolla-nova_libvirt-container.service\nsystemctl stop kolla-nova_compute-container.service\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Delete the compute service"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ openstack --os-cloud admin compute service list --host NODE\n+--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+\n| ID | Binary | Host | Zone | Status | State | Updated At |\n+--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+\n| 90345eb5-cf2f-47ef-becc-758ee36fb132 | nova-compute | NODE | nova | enabled | down | 2023-12-21T11:53:00.000000 |\n+--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ openstack --os-cloud admin compute service delete 90345eb5-cf2f-47ef-becc-758ee36fb132\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Stop all OpenStack network services on the compute node"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"systemctl stop kolla-neutron_ovn_metadata_agent-container.service\nsystemctl stop kolla-ovn_controller-container.service\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Delete the network services"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"$ openstack --os-cloud admin network agent list --host NODE\n+--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+\n| ID | Agent Type | Host | Availability Zone | Alive | State | Binary |\n+--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+\n| 0a5708ea-ba8b-5fde-8187-c6b24d3cf5ed | OVN Metadata agent | NODE | | :-) | UP | neutron-ovn-metadata-agent |\n| NODE | OVN Controller agent | NODE | | :-) | UP | ovn-controller |\n+--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+\n\n$ openstack --os-cloud admin network agent delete 0a5708ea-ba8b-5fde-8187-c6b24d3cf5ed\n$ openstack --os-cloud admin network agent delete NODE\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Refresh the facts"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply facts\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Refresh the ",(0,t.jsx)(n.code,{children:"/etc/hosts"})," file"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply hosts\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Refresh the SSH client configuration file"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply sshconfig\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Remove compute node from Prometheus monitoring"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply prometheus -l monitoring\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Remove compute node from the known hosts file"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply known-hosts\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d1c3b532.1a94fcfd.js b/assets/js/d1c3b532.1a94fcfd.js new file mode 100644 index 0000000000..d2768e9d7a --- /dev/null +++ b/assets/js/d1c3b532.1a94fcfd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8992],{60609:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>o,contentTitle:()=>t,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var s=r(74848),i=r(28453);const a={sidebar_label:"Infrastructure"},t="Infrastructure",c={id:"iaas/guides/operations-guide/infrastructure",title:"Infrastructure",description:"MariaDB",source:"@site/docs/02-iaas/guides/operations-guide/infrastructure.md",sourceDirName:"02-iaas/guides/operations-guide",slug:"/iaas/guides/operations-guide/infrastructure",permalink:"/docs/iaas/guides/operations-guide/infrastructure",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/infrastructure.md",tags:[],version:"current",frontMatter:{sidebar_label:"Infrastructure"},sidebar:"docs",previous:{title:"Ceph",permalink:"/docs/iaas/guides/operations-guide/ceph"},next:{title:"Network",permalink:"/docs/iaas/guides/operations-guide/network"}},o={},d=[{value:"MariaDB",id:"mariadb",level:2},{value:"Backup",id:"backup",level:3},{value:"Restore",id:"restore",level:3},{value:"Recovery",id:"recovery",level:3},{value:"Open Search",id:"open-search",level:2},{value:"Get all indices",id:"get-all-indices",level:3},{value:"Delete an index",id:"delete-an-index",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"infrastructure",children:"Infrastructure"}),"\n",(0,s.jsx)(n.h2,{id:"mariadb",children:"MariaDB"}),"\n",(0,s.jsx)(n.h3,{id:"backup",children:"Backup"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://mariadb.com/kb/en/mariabackup-overview/",children:"Mariabackup"})," is used to create backups\nof MariaDB."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Full backup"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply mariadb_backup\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Incremental backup (supported as of OSISM 7.0.6)"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply mariadb_backup -e mariadb_backup_type=incremental\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["There is a Docker volume ",(0,s.jsx)(n.code,{children:"mariadb_backup"})," on the 1st control node. The backups\nare stored in this volume."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ docker run --rm -v mariadb_backup:/backup -it ubuntu:22.04 bash -c 'ls -la /backup'\ntotal 9728\ndrwxr-xr-x 2 42434 42434 4096 Jun 3 18:46 .\ndrwxr-xr-x 1 root root 4096 Jun 3 18:47 ..\n-rw-r--r-- 1 42434 42434 4530618 Jun 3 18:46 incremental-18-mysqlbackup-03-06-2024-1717440409.qp.xbc.xbs.gz\n-rw-r--r-- 1 42434 42434 11 Jun 3 18:45 last_full_date\n-rw-r--r-- 1 42434 42434 5411763 Jun 3 18:45 mysqlbackup-03-06-2024-1717440342.qp.xbc.xbs.gz\n"})}),"\n",(0,s.jsx)(n.h3,{id:"restore",children:"Restore"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"https://docs.openstack.org/kolla-ansible/latest/admin/mariadb-backup-and-restore.html#restoring-backups",children:"https://docs.openstack.org/kolla-ansible/latest/admin/mariadb-backup-and-restore.html#restoring-backups"})}),"\n",(0,s.jsx)(n.h3,{id:"recovery",children:"Recovery"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply mariadb_recovery\n"})}),"\n",(0,s.jsx)(n.h2,{id:"open-search",children:"Open Search"}),"\n",(0,s.jsx)(n.h3,{id:"get-all-indices",children:"Get all indices"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ curl https://api-int.testbed.osism.xyz:9200/_cat/indices?v\nhealth status index uuid pri rep docs.count docs.deleted store.size pri.store.size\ngreen open flog-2024.04.17 1rCP3NpUQSS5wmulCn6Y5g 1 1 1657832 0 1gb 654.4mb\ngreen open .opensearch-observability UnS2gFb-QhC8oIefL3C52Q 1 2 0 0 624b 208b\ngreen open .plugins-ml-config hMdzW6ooRMGZ_0OGcdNSgA 1 1 1 0 7.8kb 3.9kb\ngreen open .opendistro-job-scheduler-lock fa_Io8bJQ8qfGII4DypxFg 1 1 1 3 51.1kb 35.1kb\ngreen open .kibana_1 v-aJ6ioSQsOwHQn_NNbeOg 1 1 0 0 416b 208b\n"})}),"\n",(0,s.jsx)(n.h3,{id:"delete-an-index",children:"Delete an index"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'$ curl -X DELETE https://api-int.testbed.osism.xyz:9200/flog-2024.04.17\n{"acknowledged":true}\n'})})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>t,x:()=>c});var s=r(96540);const i={},a=s.createContext(i);function t(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d5947e44.aa7d2742.js b/assets/js/d5947e44.aa7d2742.js new file mode 100644 index 0000000000..a09dcbc4d5 --- /dev/null +++ b/assets/js/d5947e44.aa7d2742.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7861],{51810:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>c});var s=t(74848),o=t(28453);const r={sidebar_label:"Network"},a="Network",i={id:"iaas/guides/operations-guide/network",title:"Network",description:"OpenStack, OVN, and Open vSwitch all really like UUIDs.",source:"@site/docs/02-iaas/guides/operations-guide/network.md",sourceDirName:"02-iaas/guides/operations-guide",slug:"/iaas/guides/operations-guide/network",permalink:"/docs/iaas/guides/operations-guide/network",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/network.md",tags:[],version:"current",frontMatter:{sidebar_label:"Network"},sidebar:"docs",previous:{title:"Infrastructure",permalink:"/docs/iaas/guides/operations-guide/infrastructure"},next:{title:"OpenStack",permalink:"/docs/iaas/guides/operations-guide/openstack/"}},d={},c=[{value:"Open vSwitch (OVS)",id:"open-vswitch-ovs",level:2},{value:"Open Virtual Network (OVN)",id:"open-virtual-network-ovn",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"network",children:"Network"}),"\n",(0,s.jsx)(n.p,{children:"OpenStack, OVN, and Open vSwitch all really like UUIDs."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ openstack --os-cloud admin image list -f yaml\n- ID: d64f0b9d-0ea1-40b0-b879-b98e46fc7bcf\n Name: Cirros 0.6.0\n Status: active\n- ID: ee842bc5-dd29-4de5-a5db-1c9be759fe85\n Name: Cirros 0.6.1\n Status: active\n- ID: cd28d95c-bd12-4e1e-8155-b9bf5ecbcb2f\n Name: Cirros 0.6.2\n Status: active\n"})}),"\n",(0,s.jsx)(n.p,{children:"These UUIDs are great for uniqueness, but 36-character strings are terrible\nfor readability. Statistically, just the first few characters are enough for\nuniqueness in small environments, so let\u2019s define a helper to make things more\nreadable:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"abbrev() { a='[0-9a-fA-F]' b=$a$a c=$b$b; sed \"s/$b-$c-$c-$c-$c$c$c//g\"; }\n"})}),"\n",(0,s.jsx)(n.p,{children:"You can use this as a filter to abbreviate UUIDs. For example, use it to abbreviate\nthe above image list:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ openstack --os-cloud admin image list -f yaml | abbrev\n- ID: d64f0b\n Name: Cirros 0.6.0\n Status: active\n- ID: ee842b\n Name: Cirros 0.6.1\n Status: active\n- ID: cd28d9\n Name: Cirros 0.6.2\n Status: active\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Source: ",(0,s.jsx)(n.a,{href:"https://docs.ovn.org/en/stable/tutorials/ovn-openstack.html#shortening-uuids",children:"https://docs.ovn.org/en/stable/tutorials/ovn-openstack.html#shortening-uuids"})]}),"\n",(0,s.jsx)(n.h2,{id:"open-vswitch-ovs",children:"Open vSwitch (OVS)"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://gist.github.com/djoreilly/c5ea44663c133b246dd9d42b921f7646",children:"https://gist.github.com/djoreilly/c5ea44663c133b246dd9d42b921f7646"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Open vSwitch on a network node with external network ",(0,s.jsx)(n.code,{children:"vxlan0"})," and integration\nwith the Octavia service via ",(0,s.jsx)(n.code,{children:"ohm0"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'$ docker exec -it openvswitch_vswitchd ovs-vsctl show\n2e6227aa-33f1-4762-8831-ab678ce7272d\n Bridge br-int\n fail_mode: secure\n datapath_type: system\n Port ovn-testbe-0\n Interface ovn-testbe-0\n type: geneve\n options: {csum="true", key=flow, remote_ip="192.168.16.12"}\n Port br-int\n Interface br-int\n type: internal\n Port ovn-testbe-1\n Interface ovn-testbe-1\n type: geneve\n options: {csum="true", key=flow, remote_ip="192.168.16.11"}\n Port tap8fe7d09b-90\n Interface tap8fe7d09b-90\n Port ohm0\n Interface ohm0\n type: internal\n Bridge br-ex\n Port vxlan0\n Interface vxlan0\n Port br-ex\n Interface br-ex\n type: internal\n'})}),"\n",(0,s.jsx)(n.h2,{id:"open-virtual-network-ovn",children:"Open Virtual Network (OVN)"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.ovn.org/en/stable/tutorials/ovn-openstack.html",children:"https://docs.ovn.org/en/stable/tutorials/ovn-openstack.html"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Get OVN NB and OVN SB connection information from the ",(0,s.jsx)(n.code,{children:"/etc/kolla/neutron-server/ml2_conf.ini"}),"\nfile."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'ovn_nb_connection=$(sudo grep -P -o -e "(?<=^ovn_nb_connection = ).*" "/etc/kolla/neutron-server/ml2_conf.ini")\novn_sb_connection=$(sudo grep -P -o -e "(?<=^ovn_sb_connection = ).*" "/etc/kolla/neutron-server/ml2_conf.ini")\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The following examples are from a fresh ",(0,s.jsx)(n.a,{href:"https://github.com/osism/testbed",children:"osism/testbed"}),"\ndeployment with no payload running yet."]}),"\n",(0,s.jsx)(n.p,{children:"OVN NB DB entries:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'$ docker exec ovn_northd ovn-nbctl --db "$ovn_nb_connection" show | abbrev\nswitch b5139b (neutron-8fe7d0) (aka lb-mgmt-net)\n port 45a49e\n type: localport\n addresses: ["fa:16:3e:fa:99:ea 10.1.0.2"]\n port 4d39a5 (aka octavia-listen-port-testbed-node-2)\n addresses: ["fa:16:3e:dc:11:e4 10.1.0.45"]\n port 8df1b7 (aka octavia-listen-port-testbed-node-0)\n addresses: ["fa:16:3e:4d:63:a9 10.1.0.43"]\n port ddb6aa (aka octavia-listen-port-testbed-node-1)\n addresses: ["fa:16:3e:67:f3:3d 10.1.0.40"]\n'})}),"\n",(0,s.jsx)(n.p,{children:"OVN SB DB entries:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'$ docker exec ovn_northd ovn-sbctl --db "$ovn_sb_connection" show | abbrev\nChassis testbed-node-0\n hostname: testbed-node-0\n Encap geneve\n ip: "192.168.16.10"\n options: {csum="true"}\n Port_Binding "8df1b7"\nChassis testbed-node-2\n hostname: testbed-node-2\n Encap geneve\n ip: "192.168.16.12"\n options: {csum="true"}\n Port_Binding "4d39a5"\nChassis testbed-node-1\n hostname: testbed-node-1\n Encap geneve\n ip: "192.168.16.11"\n options: {csum="true"}\n Port_Binding "ddb6aa\n'})}),"\n",(0,s.jsx)(n.p,{children:"OVN NB status:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ docker exec ovn_nb_db ovs-appctl -t /var/run/ovn/ovnnb_db.ctl cluster/status OVN_Northbound | abbrev\n6d15\nName: OVN_Northbound\nCluster ID: f5eb (f5ebd8)\nServer ID: 6d15 (6d159e)\nAddress: tcp:192.168.16.10:6643\nStatus: cluster member\nRole: follower\nTerm: 5\nLeader: 87d6\nVote: 87d6\n\nLast Election started 41049332 ms ago, reason: timeout\nElection timer: 1000\nLog: [2, 54]\nEntries not yet committed: 0\nEntries not yet applied: 0\nConnections: ->21d7 ->87d6 <-87d6 <-21d7\nDisconnections: 6\nServers:\n 6d15 (6d15 at tcp:192.168.16.10:6643) (self)\n 87d6 (87d6 at tcp:192.168.16.11:6643) last msg 266 ms ago\n 21d7 (21d7 at tcp:192.168.16.12:6643) last msg 41048563 ms ago\n"})}),"\n",(0,s.jsx)(n.p,{children:"OVN SB status:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ docker exec ovn_sb_db ovs-appctl -t /var/run/ovn/ovnsb_db.ctl cluster/status OVN_Southbound | abbrev\nbe29\nName: OVN_Southbound\nCluster ID: bd0c (bd0c26)\nServer ID: be29 (be2932)\nAddress: tcp:192.168.16.10:6644\nStatus: cluster member\nRole: follower\nTerm: 6\nLeader: dfdf\nVote: unknown\n\nLast Election started 41063820 ms ago, reason: timeout\nElection timer: 1000\nLog: [2, 62]\nEntries not yet committed: 0\nEntries not yet applied: 0\nConnections: ->dfdf ->085c <-dfdf <-085c\nDisconnections: 7\nServers:\n be29 (be29 at tcp:192.168.16.10:6644) (self)\n dfdf (dfdf at tcp:192.168.16.11:6644) last msg 146 ms ago\n 085c (085c at tcp:192.168.16.12:6644) last msg 41063293 ms ago\n"})})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var s=t(96540);const o={},r=s.createContext(o);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d59f7d52.36164d0d.js b/assets/js/d59f7d52.36164d0d.js new file mode 100644 index 0000000000..991aed6c0a --- /dev/null +++ b/assets/js/d59f7d52.36164d0d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5139],{33441:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var t=o(74848),s=o(28453);const r={title:"Naming for domains/groups/roles/project when onboarding new customers",type:"Decision Record",status:"Draft",track:"IAM"},i=void 0,a={id:"scs-0301-v1-naming-conventions",title:"Naming for domains/groups/roles/project when onboarding new customers",description:"\x3c!---",source:"@site/standards/scs-0301-v1-naming-conventions.md",sourceDirName:".",slug:"/scs-0301-v1-naming-conventions",permalink:"/standards/scs-0301-v1-naming-conventions",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Naming for domains/groups/roles/project when onboarding new customers",type:"Decision Record",status:"Draft",track:"IAM"},sidebar:"standards",previous:{title:"scs-0301: Naming for domains/groups/roles/project when onboarding new customers",permalink:"/standards/iam/scs-0301"},next:{title:"scs-0302: Domain Manager configuration for Keystone",permalink:"/standards/iam/scs-0302"}},c={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"PS approach to naming",id:"ps-approach-to-naming",level:4},{value:"<em>Option 2</em>",id:"option-2",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function l(e){const n={code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsx)(n.p,{children:"When CSPs try to enroll a new customer they encounter themselves in\na situation where they have to choose names for the openstack domain,\nproject and user."}),"\n",(0,t.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,t.jsx)(n.p,{children:"Create a naming convention to use during the provisioning of the users and\ngroups through an openstack domain."}),"\n",(0,t.jsx)(n.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,t.jsx)(n.p,{children:"OPTIONAL"}),"\n",(0,t.jsx)(n.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,t.jsx)(n.h4,{id:"ps-approach-to-naming",children:"PS approach to naming"}),"\n",(0,t.jsx)(n.p,{children:"For naming the customers the suggestion from PS is the following:"}),"\n",(0,t.jsx)(n.p,{children:"A prefix will be use to differenciate domain, project and user in\nthe openstack environment. The project name is also added as a sufix."}),"\n",(0,t.jsx)(n.p,{children:"So the onboaring tool will create the following structure for a new\ncustomer onboarded in the system."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-commandline",children:"domain: d<customer_id>\nproject: p<customer_id>-<project_name>\nuser: u<customer_id>-<user_name>\n"})}),"\n",(0,t.jsx)(n.p,{children:'For the customer also a domain admin group and a project admin group are\ncreated. Please note that, at the time of writing, PCO is not making any\nuse of OpenStack domains to isolate customers. So, for the scope of this\ndocument, the term "domain admin" is used in a conceptual way rather than\nreferring to the specific OpenStack implementation. For the scope of this\ndocument "domain admins" can do things like creating projects, creating\nusers and granting users access to some projects (within the domain of\ncourse). "Users" can create and view resources within the projects that\nthey have been granted access to by the "domain admin".\nThese groups use the prefix "gd" for domain group and "gp" for group project\nand are build like the following:'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-commandline",children:"domain admin group: gd<customer_id>-member\nproject admin group: gp<customer_id>-<project_name>-member\n"})}),"\n",(0,t.jsx)(n.p,{children:"For the creation of a domain a new domain admin group is created."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-commandline",children:"openstack domain create d000001\nopenstack group create gd000001-member\n"})}),"\n",(0,t.jsx)(n.p,{children:"When a project is created a new admin group for that project is created."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-commandline",children:"openstack project create p000001-scs_dev_project\nopenstack group create p000001-scs_dev_project-member\n"})}),"\n",(0,t.jsx)(n.p,{children:"After the creation of a project it is necessary to assign roles to the\nnew groups."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-commandline",children:"openstack role add --group gd000001-member --project p000001-scs_dev_project $role\nopenstack role add --group gp000001-scs_dev_project-member --project p000001-scs_dev_project $role\n"})}),"\n",(0,t.jsx)(n.p,{children:'For the creation of regular non admin users, the accounts will be added\nto the "domain admin" group to give them access to all projects within\nthe domain.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-commandline",children:"openstack user created u000001-user1\nopenstack group add user gd000001-member u000001-user1\n"})}),"\n",(0,t.jsx)(n.p,{children:'In the case of machine accounts, they are only added to the specific\n"project admin" groups.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-commandline",children:"openstack user created u000001-svc_user_project\nopenstack group add user gp000001-scs_dev_project-member u000001-svc_user_project\n"})}),"\n",(0,t.jsx)(n.p,{children:"In case of using federation, there are suggestions to the namings within Keycloak."}),"\n",(0,t.jsx)(n.p,{children:'The realms in Keycloak for each customer would be the same as the customer. e.g. The Keycloak realm for "Customer A"\nwill be called "Customer A".'}),"\n",(0,t.jsx)(n.p,{children:"There should be an OIDC client in each customer realm to allow the federation to the Proxy realm. Currently called OSISM\non the testbed."}),"\n",(0,t.jsxs)(n.p,{children:['On the proxy realm, it\'s needed to add this new customer realm as an idenity provider. During the creation of the identity\nprovider for "Customer A", the field "Alias" should be set to ',(0,t.jsx)(n.code,{children:"<customer-id>"}),'. This will make that the users federated from\nrealm "Customer A" to the proxy realm to be prefixed to avoid naming colisions, e.g. ',(0,t.jsx)(n.code,{children:"d${ALIAS}-${CLAIM.preferred_username}"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Also, on the identity federation there should be configured to store the ",(0,t.jsx)(n.code,{children:"<customer-id>"})," from that realm into the users. So it\ncan be send to Keystone mapping to use it as ",(0,t.jsx)(n.code,{children:"gd<customer-id>-member"})," and ",(0,t.jsx)(n.code,{children:"gp<customer-id>-<project_name>-member"}),". There is\nalso the necessity of a mapper to send the ",(0,t.jsx)(n.code,{children:"openstack-default-project"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Add the aditional mappings for roles and groups as necessary to get the attributes from the customer realm into the OIDC\nuserinfo that is put into the OIDC to the proxy realm and from there to Keystone."}),"\n",(0,t.jsx)(n.h4,{id:"option-2",children:(0,t.jsx)(n.em,{children:"Option 2"})}),"\n",(0,t.jsx)(n.p,{children:"Option 2 description"}),"\n",(0,t.jsx)(n.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,t.jsx)(n.p,{children:"RECOMMENDED"}),"\n",(0,t.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,t.jsx)(n.p,{children:"Decision"}),"\n",(0,t.jsx)(n.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,t.jsx)(n.p,{children:"Related Documents, OPTIONAL"}),"\n",(0,t.jsx)(n.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,t.jsx)(n.p,{children:"Conformance Tests, OPTIONAL"})]})}function m(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>i,x:()=>a});var t=o(96540);const s={},r=t.createContext(s);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d5ac8ed7.4c4ddfba.js b/assets/js/d5ac8ed7.4c4ddfba.js new file mode 100644 index 0000000000..def87ff66e --- /dev/null +++ b/assets/js/d5ac8ed7.4c4ddfba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1284],{60472:s=>{s.exports=JSON.parse('{"label":"howto","permalink":"/blog/tags/howto","allTagsPath":"/blog/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/d6a104fd.15cd917a.js b/assets/js/d6a104fd.15cd917a.js new file mode 100644 index 0000000000..41d3b99105 --- /dev/null +++ b/assets/js/d6a104fd.15cd917a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3637],{97625:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>l});var t=i(74848),r=i(28453);const s={},o="Container registry configuration",c={id:"container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration",title:"Container registry configuration",description:"Containerd as container runtime",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc/usage",slug:"/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Testing",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/testing"},next:{title:"Custom CA",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca"}},a={},l=[{value:"Tutorial: configure an existing cluster to use containerd registry configuration",id:"tutorial-configure-an-existing-cluster-to-use-containerd-registry-configuration",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"container-registry-configuration",children:"Container registry configuration"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://github.com/containerd/containerd",children:"Containerd"})," as container runtime\ninterface (CRI) used in the reference SCS KaaS implementation allows configuring its\nbehavior when it interacts with public or private container registry hosts. Container\nregistry hosts configuration options in containerd are well described in\nrelated ",(0,t.jsx)(n.a,{href:"https://github.com/containerd/containerd/blob/main/docs/hosts.md",children:"docs"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"This feature could be useful in various uses cases, e.g.:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Configure containerd to use a custom CA certificate when it interacts with a container\nregistry host that uses this CA"}),"\n",(0,t.jsx)(n.li,{children:"Configure containerd to use some container registry mirror host instead of the target public or private container\nregistry.\nThis could be useful when the target container registry somehow restricts its clients e.g.\nDockerHub's pull rate limit to 100 pulls per 6 hours per IP address"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["SCS KaaS reference implementation allows users to pass container registry host config\nfiles to configure containerd. Containerd configuration is applied cluster wide as it\nis CRI used in SCS KaaS clusters. Additional registry host config files for containerd\ncould be passed through the ",(0,t.jsx)(n.code,{children:"containerd_registry_files"})," opentofu variable. This variable\nexpects an object with two attributes:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"hosts"})," attribute defines additional registry host config files for containerd.\nThe filename should reference the registry host namespace. Files defined in this set\nwill be copied into the ",(0,t.jsx)(n.code,{children:"/etc/containerd/certs.d"})," directory on each workload cluster node"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"certs"})," attribute defines additional client and/or CA certificate files needed for\ncontainerd authentication against registries defined by ",(0,t.jsx)(n.code,{children:"hosts"}),". Files defined in this\nset will be copied into the ",(0,t.jsx)(n.code,{children:"/etc/containerd/certs"})," directory on each workload cluster node"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The default value of the ",(0,t.jsx)(n.code,{children:"containerd_registry_files"})," variable instructs containerd to use\n",(0,t.jsx)(n.code,{children:"registry.scs.community"})," container registry instance as a public mirror of DockerHub\ncontainer registry, see related\nissue ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/issues/417",children:"#417"}),".\nThe host config file used as a default is\ndefined ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/terraform/files/containerd/docker.io",children:"here"}),".\nThis should prevent issues with pull rate limiting from DockerHub public container registry,\ne.g. ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/issues/414",children:"#414"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The above default value could be overridden using any techniques that OpenTofu allows, e.g.\nvia environment variable:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'export TF_VAR_containerd_registry_files=\'{"hosts":["<path to the custom container registry host config>"], "certs":["<path to the custom CA or client certificate>"]}\'\n'})}),"\n",(0,t.jsxs)(n.p,{children:["SCS container registry reference installation ",(0,t.jsx)(n.a,{href:"https://registry.scs.community",children:"https://registry.scs.community"}),' contains\nseveral pre-configured "proxy-cache" projects. These projects allow you to use SCS\ncontainer registry reference installation to proxy and cache images from target public\nregistries. This may reduce the load of overused public container registries and/or helps\nto avoid rate limiting by individual public registries.\nCurrently, SCS container registry is set up to "proxy-cache" the following public container registries:']}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"docker.io"}),"\n",(0,t.jsx)(n.li,{children:"ghcr.io"}),"\n",(0,t.jsx)(n.li,{children:"quay.io"}),"\n",(0,t.jsx)(n.li,{children:"registry.gitlab.com"}),"\n",(0,t.jsx)(n.li,{children:"registry.k8s.io"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Find also a corresponding ",(0,t.jsx)(n.code,{children:"containerd"})," registry host config files\nin ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/tree/4dce164044a13b35a83690540088db2cd8457a8a/terraform/files/containerd",children:"./terraform/files/containerd"}),"\ndirectory. If you want to configure ",(0,t.jsx)(n.code,{children:"containerd"})," to use mentioned\npre-configured ",(0,t.jsx)(n.a,{href:"https://registry.scs.community",children:"SCS container registry"}),'\n"proxy cache" projects, feel free to do that e.g. as follows (path is relative to the ',(0,t.jsx)(n.code,{children:"terraform"})," directory):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'export TF_VAR_containerd_registry_files=\'{"hosts":["./files/containerd/docker.io", "./files/containerd/ghcr.io", "./files/containerd/quay.io", "./files/containerd/registry.gitlab.com", "./files/containerd/registry.k8s.io" ]}\'\n'})}),"\n",(0,t.jsxs)(n.p,{children:["If you did not find your preferred public container registry in the list of pre-configured\n",(0,t.jsx)(n.a,{href:"https://registry.scs.community",children:"SCS container registry"}),' "proxy cache" projects, and you would like to use\nthe ',(0,t.jsx)(n.a,{href:"https://registry.scs.community",children:"SCS container registry"}),"\nas a mirror for it, please open an issue in one of the following\nrepositories: ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider",children:"scs/k8s-cluster-api-provider"}),",\n",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-harbor",children:"scs/k8s-harbor"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"tutorial-configure-an-existing-cluster-to-use-containerd-registry-configuration",children:"Tutorial: configure an existing cluster to use containerd registry configuration"}),"\n",(0,t.jsx)(n.p,{children:"This tutorial is experimental and out of the usual release cycle. We recommend to\nupgrade existing environments (workload clusters) with stable releases which are properly\ntested."}),"\n",(0,t.jsx)(n.p,{children:'This tutorial instructs (advanced) users what needs to be done on the cluster management\ninstance without re-deploying it via OpenTofu. Patches described in this tutorial\nmodify existing environment with changes that have been developed within "containerd registry"-related PRs:'}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"PR#432"}),"\n",(0,t.jsx)(n.li,{children:"PR#447"}),"\n",(0,t.jsx)(n.li,{children:"PR#472"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Warning: This tutorial causes a rolling update (rolling re-deployment) of the control plane and worker nodes."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Log in to the cluster management instance, pull remote changes, and then checkout to relevant commit that\nincludes all mentioned PRs."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd k8s-cluster-api-provider/\ngit pull\ngit checkout b31a79db26c3956b473f026038e71e9aba7819b8\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Backup the config directory of an existing cluster."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd ..\ncp -R <CLUSTER_NAME> <CLUSTER_NAME>.bkp\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Ensure that the directory for containerd registry configs exists and create a default containerd registry\nconfig file that instructs containerd to use registry.scs.community container registry\ninstance as a public mirror of DockerHub.\nOptionally, create another containerd container registry host file in the ",(0,t.jsx)(n.code,{children:"containerd/hosts"})," directory.\nYou can find working examples of those files ",(0,t.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/tree/main/terraform/files/containerd",children:"here"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'cd <CLUSTER_NAME>\nmkdir -p containerd/hosts\ncat >containerd/hosts/docker.io <<EOF\nserver = "https://registry-1.docker.io"\n\n[host."https://registry.scs.community/v2/docker.io"]\n capabilities = ["pull"]\n override_path = true\nEOF\n# Optionally, create another containerd container registry host file here.\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Injects containerd registry host file(s) (from point 3.) into ",(0,t.jsx)(n.code,{children:"cluster-template.yaml"}),".\nScript ",(0,t.jsx)(n.code,{children:"configure_containerd.sh"})," does the injection."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"configure_containerd.sh cluster-template.yaml <CLUSTER_NAME>\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Inject containerd configuration in ",(0,t.jsx)(n.code,{children:"cluster-template.yaml"}),". This configuration allows\ncontainerd to discover registry host file(s)."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Create ",(0,t.jsx)(n.code,{children:"containerd_conf_append"})," temp file"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'cat >containerd_conf_append <<EOF\ncat <<EOT >> /etc/containerd/config.toml\n[plugins."io.containerd.grpc.v1.cri".registry]\n config_path = "/etc/containerd/certs.d"\nEOT\nEOF\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Inject temp file and ",(0,t.jsx)(n.code,{children:"systemctl restart containerd.service"})," line into the ",(0,t.jsx)(n.code,{children:"cluster-template.yaml"})," (inplace)"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'yq \'select(.kind == "KubeadmControlPlane").spec.kubeadmConfigSpec.preKubeadmCommands |= (\n (.[] | select(. == "apt-get install -y ca-certificates socat*") | key + 1) as $pos |\n .[:$pos] +\n [load_str("containerd_conf_append")] +\n .[$pos:])\' -i cluster-template.yaml\n\nyq \'select(.kind == "KubeadmControlPlane").spec.kubeadmConfigSpec.preKubeadmCommands |= (\n (.[] | select(. == "systemctl daemon-reload") | key + 1) as $pos |\n .[:$pos] +\n ["systemctl restart containerd.service"] +\n .[$pos:])\' -i cluster-template.yaml\n\nyq \'select(.kind == "KubeadmConfigTemplate").spec.template.spec.preKubeadmCommands |= (\n (.[] | select(. == "apt-get install -y ca-certificates socat*") | key + 1) as $pos |\n .[:$pos] +\n [load_str("containerd_conf_append")] +\n .[$pos:])\' -i cluster-template.yaml\n\nyq \'select(.kind == "KubeadmConfigTemplate").spec.template.spec.preKubeadmCommands |= (\n (.[] | select(. == "systemctl daemon-reload") | key + 1) as $pos |\n .[:$pos] +\n ["systemctl restart containerd.service"] +\n .[$pos:])\' -i cluster-template.yaml\n'})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["The above changes (when point 8. will be applied) of ",(0,t.jsx)(n.code,{children:"KubeadmControlPlane"})," will cause a rolling update of control plane nodes.\nAs the ",(0,t.jsx)(n.code,{children:"KubeadmConfigTemplate"})," has been adjusted we need to increase the generation\ncounter of worker machines to ensure that the worker nodes will be rolling updated as well."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sed -r 's/(^WORKER_MACHINE_GEN: genw)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i clusterctl.yaml\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Workaround: If your environment contains nginx ingress deployed via k8s-cluster-api-provider\n(variable DEPLOY_NGINX_INGRESS=true) disable its update. Nginx-ingress controller has\nbeen updated to version 1.8.0 in PR#440 and later to 1.8.1. This is a breaking change that includes updates\nof immutable fields. If the above is the case skip this update as follows:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sed 's/DEPLOY_NGINX_INGRESS: true/DEPLOY_NGINX_INGRESS: false/g' -i clusterctl.yaml\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Update the existing cluster."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"create_cluster.sh test1\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>c});var t=i(96540);const r={},s=t.createContext(r);function o(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d71eca41.b7d26cbd.js b/assets/js/d71eca41.b7d26cbd.js new file mode 100644 index 0000000000..3c23910b00 --- /dev/null +++ b/assets/js/d71eca41.b7d26cbd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[467],{43265:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var t=i(74848),s=i(28453);const r={sidebar_label:"Components",sidebar_position:10},c="Components",o={id:"iaas/guides/concept-guide/components/index",title:"Components",description:"* Infrastructure as a Service (IaaS) with OpenStack",source:"@site/docs/02-iaas/guides/concept-guide/components/index.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/",permalink:"/docs/iaas/guides/concept-guide/components/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/index.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Components",sidebar_position:10},sidebar:"docs",previous:{title:"Concept Guide",permalink:"/docs/iaas/guides/concept-guide/"},next:{title:"Ceph",permalink:"/docs/iaas/guides/concept-guide/components/ceph"}},a={},d=[];function l(e){const n={a:"a",h1:"h1",li:"li",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"components",children:"Components"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"./openstack",children:"Infrastructure as a Service (IaaS) with OpenStack"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"./ceph",children:"Software Defined Storage (SDS) with Ceph"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"./ironic",children:"Bare Metal as a Service (BMaaS) with Ironic"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"./sonic",children:"Software Defined Networking (SDN) with SONiC & OVN"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"./k3s",children:"Kubernetes (K8s) with K3S"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"./gardener",children:"Kubernetes as a Service (KaaS) with Gardener"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"./clusterapi",children:"Kubernetes as a Service (KaaS) with Cluster API"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"./keycloak",children:"Identity & Access Management with Keycloak"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"./teleport",children:"Privileged Access Management (PAM) to all infrastructure with Teleport"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"./prometheus",children:"Logging, Monitoring & Telemetry with Prometheus & Grafana"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"./netdata",children:"Realtime insights with Netdata"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"./proxmox",children:"Simple virtualization & containerization with Proxmox VE"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>c,x:()=>o});var t=i(96540);const s={},r=t.createContext(s);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d770ad8d.e8d173bf.js b/assets/js/d770ad8d.e8d173bf.js new file mode 100644 index 0000000000..b518f5a804 --- /dev/null +++ b/assets/js/d770ad8d.e8d173bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3934],{38436:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>l,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var r=t(74848),n=t(28453);const i={},l="Migration to ClusterClass",o={id:"container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class",title:"Migration to ClusterClass",description:"From #600, this repository uses CAPI",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc/usage",slug:"/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Harbor",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor"},next:{title:"Cluster Stacks",permalink:"/docs/category/cluster-stacks"}},a={},c=[{value:"Migration",id:"migration",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Steps",id:"steps",level:3}];function u(e){const s={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h1,{id:"migration-to-clusterclass",children:"Migration to ClusterClass"}),"\n",(0,r.jsxs)(s.p,{children:["From ",(0,r.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/pull/600",children:"#600"}),", this repository uses CAPI\n",(0,r.jsx)(s.a,{href:"https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/",children:"ClusterClass"})," feature for the creation of\nnew clusters, additionally see k8s ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/blog/2021/10/08/capi-clusterclass-and-managed-topologies/",children:"blog"}),".\nThis feature is also used e.g. in the SCS ",(0,r.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/cluster-stacks",children:"cluster-stacks"})," repository."]}),"\n",(0,r.jsxs)(s.blockquote,{children:["\n",(0,r.jsx)(s.p,{children:"Note: For now, ClusterClass is created per Cluster, which is not optimal and most likely it can be improved."}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["Therefore, existing clusters must be migrated from 'old' cluster templates to 'new' cluster class based templates.\nBased on ClusterClass ",(0,r.jsx)(s.a,{href:"https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20210526-cluster-class-and-managed-topologies.md#upgrade-strategy",children:"proposal"}),"\nof update strategy, we shouldn't be able to migrate, but in CAPI PR ",(0,r.jsx)(s.a,{href:"https://github.com/kubernetes-sigs/cluster-api/pull/6292",children:"#6292"}),"\nthe validation webhook was relaxed (via special Cluster annotation\n",(0,r.jsx)(s.strong,{children:"unsafe.topology.cluster.x-k8s.io/disable-update-class-name-check"}),") and manual migration is now possible."]}),"\n",(0,r.jsxs)(s.p,{children:["The script ",(0,r.jsx)(s.code,{children:"migrate-to-cluster-class.sh"})," uses that special annotation for migration. In the beginning, it patches\nCAPI and KCP deployments with the ",(0,r.jsx)(s.strong,{children:"ClusterTopology=true"})," container argument. Then creates new resources\n(",(0,r.jsx)(s.em,{children:"KubeadmControlPlaneTemplate"}),", ",(0,r.jsx)(s.em,{children:"OpenStackClusterTemplate"}),", ",(0,r.jsx)(s.em,{children:"ClusterClass"}),"). After that, annotates, labels and\npatches existing cluster resources. In the end, it patches the ",(0,r.jsx)(s.strong,{children:"Cluster"})," object with ",(0,r.jsx)(s.strong,{children:".spec.topology"})," and it's done."]}),"\n",(0,r.jsx)(s.h2,{id:"migration",children:"Migration"}),"\n",(0,r.jsx)(s.h3,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["CAPI >= v1.5.2 due to ",(0,r.jsx)(s.a,{href:"https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/write-clusterclass#clusterclass-with-custom-naming-strategies",children:"NamingStrategy"})," feature","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["upgrade can be performed as stated in upgrade ",(0,r.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/doc/Upgrade-Guide.md#updating-cluster-api-and-openstack-cluster-api-provider",children:"guide"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"steps",children:"Steps"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["Git pull/checkout new changes into the ",(0,r.jsx)(s.code,{children:"~/k8s-cluster-api-provider"})," directory"]}),"\n",(0,r.jsxs)(s.li,{children:["Run ",(0,r.jsx)(s.code,{children:"migrate-to-cluster-class.sh <CLUSTER_NAME>"})," (verify machines were not recreated)"]}),"\n",(0,r.jsxs)(s.li,{children:["Copy new templates for existing and new clusters (consider backup)","\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"cp ~/k8s-cluster-api-provider/terraform/files/template/cluster-template.yaml ~/<CLUSTER_NAME>/cluster-template.yaml\ncp ~/k8s-cluster-api-provider/terraform/files/template/cluster-template.yaml ~/cluster-defaults/cluster-template.yaml\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Add the newly introduced generation counter for the OpenStackClusterTemplate to the settings in ",(0,r.jsx)(s.code,{children:"clusterctl.yaml"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'echo "OPENSTACK_CLUSTER_GEN: geno01" >> ~/<CLUSTER_NAME>/clusterctl.yaml\necho "OPENSTACK_CLUSTER_GEN: geno01" >> ~/cluster-defaults/clusterctl.yaml\n'})}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["Next run of ",(0,r.jsx)(s.code,{children:"create_cluster.sh <CLUSTER_NAME>"})," should be idempotent"]}),"\n"]})]})}function d(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>l,x:()=>o});var r=t(96540);const n={},i=r.createContext(n);function l(e){const s=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:l(e.components),r.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d7951534.7b710812.js b/assets/js/d7951534.7b710812.js new file mode 100644 index 0000000000..56bd4b01b4 --- /dev/null +++ b/assets/js/d7951534.7b710812.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5213],{39865:e=>{e.exports=JSON.parse('{"title":"Guides","slug":"/category/guides-1","permalink":"/docs/category/guides-1","navigation":{"previous":{"title":"Tools Description","permalink":"/docs/operating-scs/components/automated-pentesting/tools"},"next":{"title":"Guide: Setting up openstack-health-monitor on Debian 12","permalink":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install"}}}')}}]); \ No newline at end of file diff --git a/assets/js/da1a5473.af5ff840.js b/assets/js/da1a5473.af5ff840.js new file mode 100644 index 0000000000..54d60e8de6 --- /dev/null +++ b/assets/js/da1a5473.af5ff840.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7125],{43619:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>h,contentTitle:()=>t,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var n=i(74848),o=i(28453);const r={sidebar_label:"Scripts",sidebar_position:20},t="Scripts",c={id:"iaas/guides/other-guides/developer-guide/scripts",title:"Scripts",description:"Scripts are included in container images to simplify development work and to enable",source:"@site/docs/02-iaas/guides/other-guides/developer-guide/scripts.md",sourceDirName:"02-iaas/guides/other-guides/developer-guide",slug:"/iaas/guides/other-guides/developer-guide/scripts",permalink:"/docs/iaas/guides/other-guides/developer-guide/scripts",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/developer-guide/scripts.md",tags:[],version:"current",sidebarPosition:20,frontMatter:{sidebar_label:"Scripts",sidebar_position:20},sidebar:"docs",previous:{title:"Releases",permalink:"/docs/iaas/guides/other-guides/developer-guide/releases"},next:{title:"Zuul CI",permalink:"/docs/iaas/guides/other-guides/developer-guide/zuul"}},h={},l=[];function a(e){const s={a:"a",code:"code",h1:"h1",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"scripts",children:"Scripts"}),"\n",(0,n.jsx)(s.p,{children:"Scripts are included in container images to simplify development work and to enable\ntesting and hotfixes in running environments. What scripts are available and how to\nuse them is described in this chapter."}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.code,{children:"change.sh"})," script may be used to update repositories to development branches. Different\ntargets may be passed as a first parameter and existing branch names as a second. The availability\nof targets depends on the container it is run in."]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["For the ",(0,n.jsx)(s.code,{children:"osismclient"})," container"]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh osism <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://github.com/osism/python-osism",children:"osism/python-osism"})," repository"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["For the ",(0,n.jsx)(s.code,{children:"inventory-reonciler"})," container"]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh osism <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://github.com/osism/python-osism",children:"osism/python-osism"})," repository"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh generics <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://github.com/osism/cfg-generics",children:"osism/cfg-generics"})," repository"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh defaults <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://github.com/osism/defaults",children:"osism/defaults"})," repository"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh release <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://github.com/osism/release",children:"osism/release"})," repository"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["For the ",(0,n.jsx)(s.code,{children:"osism-ansible"})," container"]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh osism <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://github.com/osism/python-osism",children:"osism/python-osism"})," repository"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh playbooks <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://github.com/osism/ansible-playbooks",children:"osism/ansible-playbooks"})," repository"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh [services|commons|validations] <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://github.com/osism/ansible-collection-services",children:"osism/ansible-collection-services"}),", ",(0,n.jsx)(s.a,{href:"https://github.com/osism/ansible-collection-commons",children:"osism/ansible-collection-commons"}),", and ",(0,n.jsx)(s.a,{href:"https://github.com/osism/ansible-collection-validations",children:"osism/ansible-collection-validations"})," repositories"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["For the ",(0,n.jsx)(s.code,{children:"ceph-ansible"})," container"]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh osism <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://github.com/osism/python-osism",children:"osism/python-osism"})," repository"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh operations <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://github.com/osism/kolla-operations",children:"osism/kolla-operations"})," repository"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["For the ",(0,n.jsx)(s.code,{children:"kolla-ansible"})," container"]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh osism <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://github.com/osism/python-osism",children:"osism/python-osism"})," repository"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh operations <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://github.com/osism/kolla-operations",children:"osism/kolla-operations"})," repository"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"/change.sh kolla-ansible <git branch>"})," for the ",(0,n.jsx)(s.a,{href:"https://opendev.org/openstack/kolla-ansible",children:"openstack/kolla-ansible"})," repository"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["In this example, the ",(0,n.jsx)(s.code,{children:"main"})," branch of ",(0,n.jsx)(s.a,{href:"https://github.com/osism/ansible-collection-services",children:"osism/ansible-collection-services"}),"\nis used in the ",(0,n.jsx)(s.code,{children:"osism-ansible"})," container."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"docker exec -u root -it osism-ansible /change.sh services main\n"})}),"\n",(0,n.jsx)(s.p,{children:"The respective container should always be restarted after a change."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"docker restart osism-ansible\n"})}),"\n",(0,n.jsx)(s.p,{children:"If something has been changed in the defaults and is to be tested, this must be\nchanged in the inventory reconciler service. Regardless of which of the Ansible services\nthe customised defaults are intended for."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{children:"docker exec -u root -it manager-inventory_reconciler-1 /change.sh defaults main\ndocker restart manager-inventory_reconciler-1\n"})})]})}function d(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(a,{...e})}):a(e)}},28453:(e,s,i)=>{i.d(s,{R:()=>t,x:()=>c});var n=i(96540);const o={},r=n.createContext(o);function t(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dbde4c02.e0c3d061.js b/assets/js/dbde4c02.e0c3d061.js new file mode 100644 index 0000000000..049e20411b --- /dev/null +++ b/assets/js/dbde4c02.e0c3d061.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[445],{49865:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>u,frontMatter:()=>a,metadata:()=>o,toc:()=>t});var r=s(74848),i=s(28453);const a={sidebar_label:"Infrastructure",sidebar_position:30},d="Infrastructure",o={id:"iaas/guides/upgrade-guide/infrastructure",title:"Infrastructure",description:"1. Kubernetes",source:"@site/docs/02-iaas/guides/upgrade-guide/infrastructure.md",sourceDirName:"02-iaas/guides/upgrade-guide",slug:"/iaas/guides/upgrade-guide/infrastructure",permalink:"/docs/iaas/guides/upgrade-guide/infrastructure",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/infrastructure.md",tags:[],version:"current",sidebarPosition:30,frontMatter:{sidebar_label:"Infrastructure",sidebar_position:30},sidebar:"docs",previous:{title:"Docker",permalink:"/docs/iaas/guides/upgrade-guide/docker"},next:{title:"Logging & Monitoring",permalink:"/docs/iaas/guides/upgrade-guide/logging-monitoring"}},c={},t=[];function l(e){const n={code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"infrastructure",children:"Infrastructure"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Kubernetes"}),"\n",(0,r.jsxs)(n.p,{children:["This is only necessary if the internal Kubernetes cluster has also been deployed.\nThis can be checked by executing ",(0,r.jsx)(n.code,{children:"kubectl get nodes"})," on the manager node."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"osism apply k3s-upgrade\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Cron, Fluentd & Kolla Toolbox"}),"\n",(0,r.jsxs)(n.p,{children:["The common role of Kolla is used to manage the services ",(0,r.jsx)(n.code,{children:"cron"}),", ",(0,r.jsx)(n.code,{children:"fluentd"}),"\nand ",(0,r.jsx)(n.code,{children:"kolla-toolbox"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["It is important to do this upgrade before any other upgrades in the Kolla\nenvironment, as parts of the other upgrades depend on the ",(0,r.jsx)(n.code,{children:"kolla-toolbox"}),"\nservice."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"osism apply -a pull common\nosism apply -a upgrade common\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Loadbalancer"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"osism apply -a pull loadbalancer\nosism apply -a upgrade loadbalancer\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Redis"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"osism apply -a pull redis\nosism apply -a upgrade redis\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Memcached"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"osism apply -a pull memcached\nosism apply -a upgrade memcached\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"RabbitMQ"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"osism apply -a pull rabbitmq\nosism apply -a upgrade rabbitmq\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"MariaDB"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"osism apply -a pull mariadb\nosism apply -a upgrade mariadb\n"})}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>o});var r=s(96540);const i={},a=r.createContext(i);function d(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dc09f893.7e2a0e7e.js b/assets/js/dc09f893.7e2a0e7e.js new file mode 100644 index 0000000000..d71a1329b2 --- /dev/null +++ b/assets/js/dc09f893.7e2a0e7e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3527],{45065:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>u,contentTitle:()=>o,default:()=>l,frontMatter:()=>r,metadata:()=>d,toc:()=>a});var t=i(74848),n=i(28453);const r={sidebar_label:"User Guide",sidebar_position:50},o="User Guide",d={id:"iaas/guides/user-guide/index",title:"User Guide",description:"",source:"@site/docs/02-iaas/guides/user-guide/index.md",sourceDirName:"02-iaas/guides/user-guide",slug:"/iaas/guides/user-guide/",permalink:"/docs/iaas/guides/user-guide/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/user-guide/index.md",tags:[],version:"current",sidebarPosition:50,frontMatter:{sidebar_label:"User Guide",sidebar_position:50},sidebar:"docs",previous:{title:"Guides",permalink:"/docs/iaas/guides/"},next:{title:"Migrate from VMware ESXi to OpenStack",permalink:"/docs/iaas/guides/user-guide/migration-vmware-esix"}},u={},a=[];function c(e){const s={h1:"h1",...(0,n.R)(),...e.components};return(0,t.jsx)(s.h1,{id:"user-guide",children:"User Guide"})}function l(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,s,i)=>{i.d(s,{R:()=>o,x:()=>d});var t=i(96540);const n={},r=t.createContext(n);function o(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dcbc8e94.d46906e1.js b/assets/js/dcbc8e94.d46906e1.js new file mode 100644 index 0000000000..e8a14dab8b --- /dev/null +++ b/assets/js/dcbc8e94.d46906e1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9495],{25154:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>d});var t=a(74848),o=a(28453);const i={sidebar_label:"Loadbalancer",sidebar_position:20},s="Loadbalancer",l={id:"iaas/guides/configuration-guide/loadbalancer",title:"Loadbalancer",description:"Second Loadbalancer",source:"@site/docs/02-iaas/guides/configuration-guide/loadbalancer.md",sourceDirName:"02-iaas/guides/configuration-guide",slug:"/iaas/guides/configuration-guide/loadbalancer",permalink:"/docs/iaas/guides/configuration-guide/loadbalancer",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/loadbalancer.md",tags:[],version:"current",sidebarPosition:20,frontMatter:{sidebar_label:"Loadbalancer",sidebar_position:20},sidebar:"docs",previous:{title:"Proxy",permalink:"/docs/iaas/guides/configuration-guide/proxy"},next:{title:"Self-signed certificates",permalink:"/docs/iaas/guides/configuration-guide/self-signed-certificates"}},r={},d=[{value:"Second Loadbalancer",id:"second-loadbalancer",level:2}];function c(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"loadbalancer",children:"Loadbalancer"}),"\n",(0,t.jsx)(n.h2,{id:"second-loadbalancer",children:"Second Loadbalancer"}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsx)(n.p,{children:"This feature is available from OSISM 7.0.5."})}),"\n",(0,t.jsxs)(n.p,{children:["With OSISM, it is possible to manage any number of independent loadbalancers via a single OSISM\nmanager service using sub-environments. A sub environment is basically nothing more than another directory\nbelow the ",(0,t.jsx)(n.code,{children:"environments"})," directory of the configuration repository with a special name."]}),"\n",(0,t.jsxs)(n.p,{children:["A sub-environment for an additional loadbalancer always has the name ",(0,t.jsx)(n.code,{children:"kolla.NAME"})," as the loadbalancer\nis provided as part of Kolla. The ",(0,t.jsx)(n.code,{children:"kolla.NAME"})," directory in the configuration repository then contains\nthe ",(0,t.jsx)(n.code,{children:"configuration.yml"}),", ",(0,t.jsx)(n.code,{children:"images.yml"})," and ",(0,t.jsx)(n.code,{children:"secrets.yml"})," files as usual."]}),"\n",(0,t.jsx)(n.p,{children:"The following directories and files are also required in a sub-environment for a loadbalancer."}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{style:{textAlign:"left"},children:"File"}),(0,t.jsx)(n.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:(0,t.jsx)(n.code,{children:"certificates/ca/custom.crt"})}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"The file is optional. If a custom CA is used, it must be added here."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:(0,t.jsx)(n.code,{children:"certificates/haproxy-internal.pem"})}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"SSL certificate to be used."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{style:{textAlign:"left"},children:(0,t.jsx)(n.code,{children:"files/overlays/haproxy/services.d/haproxy.cfg"})}),(0,t.jsx)(n.td,{style:{textAlign:"left"},children:"HAProxy configuration to be used on the loadbalancer."})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["In this example, a sub-environment ",(0,t.jsx)(n.code,{children:"kolla.external"})," is created, which is used for an outward facing\nloadbalancer that only offers certain API services."]}),"\n",(0,t.jsxs)(n.p,{children:["In comparison to the normal ",(0,t.jsx)(n.code,{children:"kolla"})," environment, the groups to be used must be overwritten for a\nKolla sub-environment. In this case, one group is defined: ",(0,t.jsx)(n.code,{children:"kolla.external.loadbalancer"}),". It is\nrecommended to base the name of the groups on the name of the sub-environments."]}),"\n",(0,t.jsxs)(n.p,{children:["The group ",(0,t.jsx)(n.code,{children:"kolla.external.loadbalancer"})," is added to the global inventory in the ",(0,t.jsx)(n.code,{children:"10-custom"})," file.\nIn this example, ",(0,t.jsx)(n.code,{children:"testbed-node-2.testbed.osism.xyz"})," is used for the second loadbalancer."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/10-custom"',children:"[kolla.external.loadbalancer]\ntestbed-node-2.testbed.osism.xyz\n"})}),"\n",(0,t.jsxs)(n.p,{children:["It is also important to ensure that the nodes used for the second loadbalancer are not included in\nthe ",(0,t.jsx)(n.code,{children:"loadbalancer"})," group. This can be checked with ",(0,t.jsx)(n.code,{children:"osism get hosts -l loadbalancer"}),". If the nodes of\nthe second loadbalancer are also listed there, the ",(0,t.jsx)(n.code,{children:"loadbalancer"})," group in the ",(0,t.jsx)(n.code,{children:"99-overwrite"})," file of\nthe global inventory must be overwritten. In this example, the ",(0,t.jsx)(n.code,{children:"loadbalaner"})," group is overwritten so\nthat only ",(0,t.jsx)(n.code,{children:"testbed-node-0.testbed.osism.xyz"})," and ",(0,t.jsx)(n.code,{children:"testbed-node-1.testbed.osism.xyz"})," are left in the\n",(0,t.jsx)(n.code,{children:"loadbalancer"})," group."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",metastring:'title="inventory/99-overwrite"',children:"[loadbalancer]\ntestbed-node-0.testbed.osism.xyz\ntestbed-node-1.testbed.osism.xyz\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Furthermore, in a Kolla sub-environment that is only used for a loadbalancer, only a few additional\nparameters are required in the ",(0,t.jsx)(n.code,{children:"configuration.yml"})," file."]}),"\n",(0,t.jsxs)(n.p,{children:["Don't get confused, only the ",(0,t.jsx)(n.code,{children:"kolla_*internal*"})," parameters and the ",(0,t.jsx)(n.code,{children:"haproxy-internal.pem"})," file are used\nhere in the example. This is because we only want to configure one virtual IP address on the external\nloadbalancer and the loadbalancer managed by Kolla has the internal IP address by default. It is therefore\nnot possible with Kolla to use only the ",(0,t.jsx)(n.code,{children:"kolla_*external*"})," parameters as an additional virtual IP address\nwith default values would then be configured by default."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla.external/configuration.yml"',children:'---\n##########################################################\n# hosts\n\nhosts_kolla_all: kolla.external.loadbalancer\nhosts_kolla_loadbalancer: kolla.external.loadbalancer\n\n##########################################################\n# docker\n\ndocker_namespace: osism\n\n##########################################################\n# loadbalancer\n\nkolla_internal_vip_address: 192.168.24.200\nkolla_internal_fqdn: api.testbed.osism.com\nkolla_enable_tls_internal: "yes"\n\n# Required if a custom CA is used.\nkolla_copy_ca_into_containers: "yes"\n'})}),"\n",(0,t.jsx)(n.p,{children:"At the moment it is only possible to deploy the loadbalancer itself with its own configuration. It is currently\nnot possible to use the integrated service configurations of Kolla itself (Nova, Cinder, ..) on an additional\nloadbalancer. This will be possible in the future."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism apply --sub external loadbalancer-without-service-config\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>l});var t=a(96540);const o={},i=t.createContext(o);function s(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dcf2f717.994920ad.js b/assets/js/dcf2f717.994920ad.js new file mode 100644 index 0000000000..d214bba24b --- /dev/null +++ b/assets/js/dcf2f717.994920ad.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8981],{76141:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>s,default:()=>l,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var o=t(74848),i=t(28453);const r={},s="Guide 1",c={id:"container/guides/guide1",title:"Guide 1",description:"TODO",source:"@site/docs/03-container/guides/guide1.md",sourceDirName:"03-container/guides",slug:"/container/guides/guide1",permalink:"/docs/container/guides/guide1",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/guides/guide1.md",tags:[],version:"current",frontMatter:{}},u={},d=[];function a(e){const n={h1:"h1",p:"p",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"guide-1",children:"Guide 1"}),"\n",(0,o.jsx)(n.p,{children:"TODO"})]})}function l(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>c});var o=t(96540);const i={},r=o.createContext(i);function s(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/de6833f9.aaec887b.js b/assets/js/de6833f9.aaec887b.js new file mode 100644 index 0000000000..4705512863 --- /dev/null +++ b/assets/js/de6833f9.aaec887b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2309],{84904:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var n=s(74848),i=s(28453);const t={sidebar_label:"Resolvconf"},c="Resolvconf",r={id:"iaas/guides/configuration-guide/commons/resolvconf",title:"Resolvconf",description:"With the osism.commons.resolvconf role, it is possible to manage the used DNS servers on a node.",source:"@site/docs/02-iaas/guides/configuration-guide/commons/resolvconf.md",sourceDirName:"02-iaas/guides/configuration-guide/commons",slug:"/iaas/guides/configuration-guide/commons/resolvconf",permalink:"/docs/iaas/guides/configuration-guide/commons/resolvconf",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/resolvconf.md",tags:[],version:"current",frontMatter:{sidebar_label:"Resolvconf"},sidebar:"docs",previous:{title:"Packages",permalink:"/docs/iaas/guides/configuration-guide/commons/packages"},next:{title:"Services",permalink:"/docs/iaas/guides/configuration-guide/commons/services"}},a={},d=[];function u(e){const o={code:"code",h1:"h1",p:"p",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.h1,{id:"resolvconf",children:"Resolvconf"}),"\n",(0,n.jsxs)(o.p,{children:["With the ",(0,n.jsx)(o.code,{children:"osism.commons.resolvconf"})," role, it is possible to manage the used DNS servers on a node."]})]})}function l(e={}){const{wrapper:o}={...(0,i.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,o,s)=>{s.d(o,{R:()=>c,x:()=>r});var n=s(96540);const i={},t=n.createContext(i);function c(e){const o=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function r(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),n.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/df35cf96.f061bf46.js b/assets/js/df35cf96.f061bf46.js new file mode 100644 index 0000000000..bfe4e58cdc --- /dev/null +++ b/assets/js/df35cf96.f061bf46.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6831],{57019:(e,s,i)=>{i.r(s),i.d(s,{assets:()=>a,contentTitle:()=>o,default:()=>l,frontMatter:()=>t,metadata:()=>c,toc:()=>d});var n=i(74848),r=i(28453);const t={sidebar_label:"Services"},o="Services",c={id:"iaas/guides/configuration-guide/commons/services",title:"Services",description:"With the osism.commons.services role, it is possible to manage services on a node",source:"@site/docs/02-iaas/guides/configuration-guide/commons/services.md",sourceDirName:"02-iaas/guides/configuration-guide/commons",slug:"/iaas/guides/configuration-guide/commons/services",permalink:"/docs/iaas/guides/configuration-guide/commons/services",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/services.md",tags:[],version:"current",frontMatter:{sidebar_label:"Services"},sidebar:"docs",previous:{title:"Resolvconf",permalink:"/docs/iaas/guides/configuration-guide/commons/resolvconf"},next:{title:"SSH Config",permalink:"/docs/iaas/guides/configuration-guide/commons/sshconfig"}},a={},d=[{value:"Start and enable required services",id:"start-and-enable-required-services",level:2},{value:"Note on services that should be deactivated",id:"note-on-services-that-should-be-deactivated",level:2}];function u(e){const s={admonition:"admonition",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"services",children:"Services"}),"\n",(0,n.jsxs)(s.p,{children:["With the ",(0,n.jsx)(s.code,{children:"osism.commons.services"})," role, it is possible to manage services on a node\nin a general form. This allows you to either activate any services or indicate that\nspecific services are running and should be deactivated."]}),"\n",(0,n.jsx)(s.h2,{id:"start-and-enable-required-services",children:"Start and enable required services"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:'services_required_default:\n - cron\nservices_required_extra: []\nservices_required: "{{ services_required_default + services_required_extra }}"\n'})}),"\n",(0,n.jsx)(s.admonition,{type:"note",children:(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.code,{children:"services_required"})," should not be overwritten. Use ",(0,n.jsx)(s.code,{children:"services_required_extra"})," to add extra services."]})}),"\n",(0,n.jsx)(s.h2,{id:"note-on-services-that-should-be-deactivated",children:"Note on services that should be deactivated"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:'services_warning_default:\n - nscd\nservices_warning_extra: []\nservices_warning: "{{ services_warning_default + services_warning_extra }}"\n'})}),"\n",(0,n.jsx)(s.admonition,{type:"note",children:(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.code,{children:"services_warning"})," should not be overwritten. Use ",(0,n.jsx)(s.code,{children:"services_warning_extra"})," to add extra services."]})})]})}function l(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,s,i)=>{i.d(s,{R:()=>o,x:()=>c});var n=i(96540);const r={},t=n.createContext(r);function o(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dfce392e.d2604902.js b/assets/js/dfce392e.d2604902.js new file mode 100644 index 0000000000..d8fdceb58b --- /dev/null +++ b/assets/js/dfce392e.d2604902.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4398],{35713:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var s=n(74848),a=n(28453);const i={title:"Status page reference implementation decision",type:"Decision Record",status:"Draft",track:"Ops"},o=void 0,r={id:"scs-0401-v1-status-page-reference-implementation-decision",title:"Status page reference implementation decision",description:"Introduction",source:"@site/standards/scs-0401-v1-status-page-reference-implementation-decision.md",sourceDirName:".",slug:"/scs-0401-v1-status-page-reference-implementation-decision",permalink:"/standards/scs-0401-v1-status-page-reference-implementation-decision",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Status page reference implementation decision",type:"Decision Record",status:"Draft",track:"Ops"},sidebar:"standards",previous:{title:"scs-0401: Status page reference implementation decision",permalink:"/standards/ops/scs-0401"},next:{title:"scs-0402: Status page OpenAPI decision",permalink:"/standards/ops/scs-0402"}},c={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Decision",id:"decision",level:2},{value:"Programming Language",id:"programming-language",level:3},{value:"Database",id:"database",level:3}];function l(e){const t={a:"a",h2:"h2",h3:"h3",p:"p",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(t.p,{children:["For the reference implementation of the status page API defined by the ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi",children:"OpenAPI spec"})," some decision should be made to which technlogy to be used and why."]}),"\n",(0,s.jsx)(t.p,{children:"A reference implementation should be of use to most of the intended group, but is not necsessarily applicable for every use case."}),"\n",(0,s.jsx)(t.h2,{id:"motivation",children:"Motivation"}),"\n",(0,s.jsx)(t.p,{children:"For a reference implementation to be of any use, some common and widely used technologies should be used, so it's useful to most of the intended user group."}),"\n",(0,s.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsx)(t.h3,{id:"programming-language",children:"Programming Language"}),"\n",(0,s.jsxs)(t.p,{children:["The status page application consists of an api server as well as a frontend. For implementing the ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-api",children:"api server"}),", which is generated from the ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi",children:"OpenAPI spec"}),", ",(0,s.jsx)(t.a,{href:"https://go.dev/",children:"Go"})," was chosen, because of maturity and wide spread usage as industry standard. Go, in particular, is a modern programming language and is commonly used in network and cloud computing environments."]}),"\n",(0,s.jsx)(t.h3,{id:"database",children:"Database"}),"\n",(0,s.jsxs)(t.p,{children:["As database, ",(0,s.jsx)(t.a,{href:"https://www.postgresql.org/",children:"PostgreSQL"})," was chosen, since it is a mature, well-known database. PostgreSQL can be run in various environments from small setups to scaled setups.\nFurthermore PostgreSQL is a very healthy project with an active community and a solid license. It easily passed the ",(0,s.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/blob/main/Drafts/OSS-Health.md",children:"SCS OSS health check"}),"."]})]})}function u(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var s=n(96540);const a={},i=s.createContext(a);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dfe27b1e.bf7b4d35.js b/assets/js/dfe27b1e.bf7b4d35.js new file mode 100644 index 0000000000..a1d9be30f6 --- /dev/null +++ b/assets/js/dfe27b1e.bf7b4d35.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5997],{8327:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var s=t(74848),c=t(28453);const r={},a="Managing many clusters",o={id:"container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters",title:"Managing many clusters",description:"While the scripts all use a default testcluster, they have",source:"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters.md",sourceDirName:"03-container/components/k8s-cluster-api-provider/doc/usage",slug:"/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Create a new cluster",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster"},next:{title:"Cluster Management on the capi management node",permalink:"/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node"}},i={},l=[];function d(e){const n={code:"code",h1:"h1",p:"p",...(0,c.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"managing-many-clusters",children:"Managing many clusters"}),"\n",(0,s.jsxs)(n.p,{children:["While the scripts all use a default ",(0,s.jsx)(n.code,{children:"testcluster"}),", they have\nbeen developed and tested to manage many clusters from a single management\nnode. Copy the ",(0,s.jsx)(n.code,{children:"~/cluster-defaults/clusterctl.yaml"})," file to\n",(0,s.jsx)(n.code,{children:"~/MYCLUSTER/clusterctl.yaml"}),"\nand edit the copy to describe the properties of the cluster to be created.\nUse ",(0,s.jsx)(n.code,{children:"./create_cluster.sh MYCLUSTER"})," then to create a workload cluster\nwith the name ",(0,s.jsx)(n.code,{children:"MYCLUSTER"}),". You will find the kubeconfig file in\n",(0,s.jsx)(n.code,{children:"~/MYCLUSTER/MYCLUSTER.yaml"}),", granting its owner admin access to that cluster.\nLikewise, ",(0,s.jsx)(n.code,{children:"delete_cluster.sh"})," and the ",(0,s.jsx)(n.code,{children:"apply_*.sh"})," scripts take a\ncluster name as parameter."]}),"\n",(0,s.jsx)(n.p,{children:"This way, dozens of clusters can be controlled from one management server."}),"\n",(0,s.jsxs)(n.p,{children:["You can add credentials from different projects into\n",(0,s.jsx)(n.code,{children:"~/.config/openstack/clouds.yaml"})," and reference them in the ",(0,s.jsx)(n.code,{children:"OPENSTACK_CLOUD"}),"\nsetting in ",(0,s.jsx)(n.code,{children:"clusterctl.yaml"}),", this way managing clusters in many different\nprojects and even clouds from one management server."]})]})}function u(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var s=t(96540);const c={},r=s.createContext(c);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e0c197a4.c3013477.js b/assets/js/e0c197a4.c3013477.js new file mode 100644 index 0000000000..fd1559e900 --- /dev/null +++ b/assets/js/e0c197a4.c3013477.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7051],{64947:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var a=i(74848),t=i(28453);const r={},o="Ironic",s={id:"iaas/guides/concept-guide/components/ironic",title:"Ironic",description:"OpenStack Ironic is a project that provides Baremetal as a Service (BMaaS), enabling the",source:"@site/docs/02-iaas/guides/concept-guide/components/ironic.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/ironic",permalink:"/docs/iaas/guides/concept-guide/components/ironic",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/ironic.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Gardener",permalink:"/docs/iaas/guides/concept-guide/components/gardener"},next:{title:"K3S",permalink:"/docs/iaas/guides/concept-guide/components/k3s"}},c={},l=[{value:"Lifecycle Management of Ironic in OSISM",id:"lifecycle-management-of-ironic-in-osism",level:2}];function d(e){const n={h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h1,{id:"ironic",children:"Ironic"}),"\n",(0,a.jsx)(n.p,{children:"OpenStack Ironic is a project that provides Baremetal as a Service (BMaaS), enabling the\nprovisioning and management of physical machines in a cloud-like manner. Unlike traditional\nvirtualization, where virtual machines run on top of a hypervisor, BMaaS allows users to\ndirectly manage and utilize physical hardware, offering the full performance and isolation\nof dedicated servers."}),"\n",(0,a.jsx)(n.p,{children:"Key benefits of OpenStack Ironic:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Hardware Provisioning: Ironic automates the provisioning of physical servers, including\nthe deployment of operating systems and configuration of hardware settings. This automation\nstreamlines the setup process, reducing the time and effort required to bring new servers\nonline."}),"\n",(0,a.jsx)(n.li,{children:"Integration with OpenStack: Ironic integrates seamlessly with other OpenStack services,\nsuch as Nova for compute management, Neutron for networking, and Glance for image services.\nThis integration allows users to manage both virtual and baremetal resources through a\nunified OpenStack dashboard."}),"\n",(0,a.jsx)(n.li,{children:"Support for Multiple Hardware Drivers: Ironic supports a wide range of hardware through\nvarious drivers, including IPMI, Redfish, and vendor-specific drivers. This flexibility\nensures compatibility with a diverse set of hardware platforms and management interfaces."}),"\n",(0,a.jsx)(n.li,{children:"Resource Management and Scheduling: Ironic leverages OpenStack\u2019s scheduling capabilities\nto manage the allocation of physical servers, ensuring optimal utilization of hardware\nresources. Users can request specific hardware configurations and Ironic will match these\nrequests with available resources."}),"\n",(0,a.jsx)(n.li,{children:"Provisioning States: Ironic manages the lifecycle of baremetal nodes through various\nprovisioning states, such as enroll, available, active, and maintenance. This state\nmanagement ensures that hardware is correctly tracked and managed throughout its lifecycle."}),"\n",(0,a.jsx)(n.li,{children:"Network Integration: Ironic integrates with Neutron to provide networking services for\nbaremetal nodes, including support for VLANs, flat networks, and more complex networking\nsetups. This integration ensures that baremetal nodes can be seamlessly integrated into\nexisting network topologies."}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"By utilizing OpenStack Ironic, organizations can leverage the benefits of BMaaS,\nproviding users with the performance and control of physical hardware while maintaining\nthe flexibility and scalability of cloud infrastructure. This approach is particularly\nbeneficial for workloads that require high performance, low latency, or specific hardware\nconfigurations that are not achievable with virtual machines."}),"\n",(0,a.jsx)(n.h2,{id:"lifecycle-management-of-ironic-in-osism",children:"Lifecycle Management of Ironic in OSISM"})]})}function u(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>s});var a=i(96540);const t={},r=a.createContext(t);function o(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e20b631f.5e57a496.js b/assets/js/e20b631f.5e57a496.js new file mode 100644 index 0000000000..72e3439f01 --- /dev/null +++ b/assets/js/e20b631f.5e57a496.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[272],{23641:(n,e,i)=>{i.r(e),i.d(e,{assets:()=>r,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>c,toc:()=>l});var a=i(74848),t=i(28453);const s={sidebar_label:"Manila"},o="Manila",c={id:"iaas/guides/configuration-guide/openstack/manila",title:"Manila",description:"* Manila admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/manila.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/manila",permalink:"/docs/iaas/guides/configuration-guide/openstack/manila",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/manila.md",tags:[],version:"current",frontMatter:{sidebar_label:"Manila"},sidebar:"docs",previous:{title:"Magnum",permalink:"/docs/iaas/guides/configuration-guide/openstack/magnum"},next:{title:"Neutron",permalink:"/docs/iaas/guides/configuration-guide/openstack/neutron"}},r={},l=[];function d(n){const e={a:"a",h1:"h1",li:"li",ul:"ul",...(0,t.R)(),...n.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.h1,{id:"manila",children:"Manila"}),"\n",(0,a.jsxs)(e.ul,{children:["\n",(0,a.jsx)(e.li,{children:(0,a.jsx)(e.a,{href:"https://docs.openstack.org/manila/latest/admin/index.html",children:"Manila admin guide"})}),"\n",(0,a.jsx)(e.li,{children:(0,a.jsx)(e.a,{href:"https://docs.openstack.org/manila/latest/configuration/index.html",children:"Manila configuration guide"})}),"\n",(0,a.jsx)(e.li,{children:(0,a.jsx)(e.a,{href:"https://docs.openstack.org/manila/latest/configuration/shared-file-systems/samples/manila.conf.html",children:"Manila configuration reference"})}),"\n"]})]})}function u(n={}){const{wrapper:e}={...(0,t.R)(),...n.components};return e?(0,a.jsx)(e,{...n,children:(0,a.jsx)(d,{...n})}):d(n)}},28453:(n,e,i)=>{i.d(e,{R:()=>o,x:()=>c});var a=i(96540);const t={},s=a.createContext(t);function o(n){const e=a.useContext(s);return a.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(t):n.components||t:o(n.components),a.createElement(s.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/e24c1f8d.2c71dde7.js b/assets/js/e24c1f8d.2c71dde7.js new file mode 100644 index 0000000000..cb071502a5 --- /dev/null +++ b/assets/js/e24c1f8d.2c71dde7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4480],{22701:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>d,contentTitle:()=>r,default:()=>a,frontMatter:()=>i,metadata:()=>c,toc:()=>o});var l=s(74848),n=s(28453);const i={sidebar_label:"Sysctl"},r="Sysctl",c={id:"iaas/guides/configuration-guide/commons/sysctl",title:"Sysctl",description:"With the osism.commons.sysctl role, it is possible to manage the attributes of the kernel",source:"@site/docs/02-iaas/guides/configuration-guide/commons/sysctl.md",sourceDirName:"02-iaas/guides/configuration-guide/commons",slug:"/iaas/guides/configuration-guide/commons/sysctl",permalink:"/docs/iaas/guides/configuration-guide/commons/sysctl",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/commons/sysctl.md",tags:[],version:"current",frontMatter:{sidebar_label:"Sysctl"},sidebar:"docs",previous:{title:"SSH Config",permalink:"/docs/iaas/guides/configuration-guide/commons/sshconfig"},next:{title:"Timezone",permalink:"/docs/iaas/guides/configuration-guide/commons/timezone"}},d={},o=[];function x(t){const e={a:"a",code:"code",h1:"h1",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...t.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(e.h1,{id:"sysctl",children:"Sysctl"}),"\n",(0,l.jsxs)(e.p,{children:["With the ",(0,l.jsx)(e.code,{children:"osism.commons.sysctl"})," role, it is possible to manage the attributes of the kernel\nvia ",(0,l.jsx)(e.a,{href:"https://en.wikipedia.org/wiki/Sysctl",children:"sysctl"})," on a node."]}),"\n",(0,l.jsxs)(e.p,{children:["The following defaults are set via the parameter ",(0,l.jsx)(e.code,{children:"sysctl_defaults"}),"."]}),"\n",(0,l.jsxs)(e.table,{children:[(0,l.jsx)(e.thead,{children:(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.th,{style:{textAlign:"left"},children:"Group"}),(0,l.jsx)(e.th,{style:{textAlign:"left"},children:"Attribute"}),(0,l.jsx)(e.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,l.jsxs)(e.tbody,{children:[(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"elasticsearch"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"vm.max_map_count"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"262144"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_keepalive_time"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"6"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_keepalive_intvl"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"3"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_keepalive_probes"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"3"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"net.core.wmem_max"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"16777216"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"net.core.rmem_max"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"16777216"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_fin_timeout"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"20"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_tw_reuse"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"1"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"net.core.somaxconn"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"4096"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_syncookies"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"0"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"rabbitmq"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"net.ipv4.tcp_max_syn_backlog"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"8192"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"generic"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"vm.swappiness"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"1"})]}),(0,l.jsxs)(e.tr,{children:[(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"compute"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"net.netfilter.nf_conntrack_max"}),(0,l.jsx)(e.td,{style:{textAlign:"left"},children:"1048576"})]})]})]}),"\n",(0,l.jsxs)(e.p,{children:["The ",(0,l.jsx)(e.code,{children:"sysctl_extra"})," parameter can be used to set your own parameters or overwrite existing\nparameters in the defaults."]}),"\n",(0,l.jsx)(e.pre,{children:(0,l.jsx)(e.code,{className:"language-yaml",metastring:'title="Set attribute fs.inotify.max_user_instances to 256 for all nodes in group generic"',children:"sysctl_extra:\n generic:\n - name: fs.inotify.max_user_instances\n value: 256\n"})})]})}function a(t={}){const{wrapper:e}={...(0,n.R)(),...t.components};return e?(0,l.jsx)(e,{...t,children:(0,l.jsx)(x,{...t})}):x(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>r,x:()=>c});var l=s(96540);const n={},i=l.createContext(n);function r(t){const e=l.useContext(i);return l.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(n):t.components||n:r(t.components),l.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/e2dcdabe.6abe1a01.js b/assets/js/e2dcdabe.6abe1a01.js new file mode 100644 index 0000000000..7492fb4e16 --- /dev/null +++ b/assets/js/e2dcdabe.6abe1a01.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1099],{96264:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>r,toc:()=>a});var s=n(74848),i=n(28453);const o={title:"_Descriptive title_",type:"Decision Record",status:"Draft",track:"Global"},c=void 0,r={id:"scs-XXXX-vN-decision-record-template",title:"_Descriptive title_",description:"\x3c!---",source:"@site/standards/scs-XXXX-vN-decision-record-template.md",sourceDirName:".",slug:"/scs-XXXX-vN-decision-record-template",permalink:"/standards/scs-XXXX-vN-decision-record-template",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"_Descriptive title_",type:"Decision Record",status:"Draft",track:"Global"}},d={},a=[{value:"Abstract",id:"abstract",level:2},{value:"Terminology",id:"terminology",level:2},{value:"Context",id:"context",level:2},{value:"Decision",id:"decision",level:2},{value:"Consequences",id:"consequences",level:2},{value:"Related Documents",id:"related-documents",level:2}];function l(e){const t={h2:"h2",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"abstract",children:"Abstract"}),"\n",(0,s.jsx)(t.p,{children:"Very short introduction about the topic of this document."}),"\n",(0,s.jsx)(t.h2,{id:"terminology",children:"Terminology"}),"\n",(0,s.jsx)(t.p,{children:"Example (abbr. Ex)\nThis is the description for an example terminology."}),"\n",(0,s.jsx)(t.h2,{id:"context",children:"Context"}),"\n",(0,s.jsx)(t.p,{children:"What is the issue that we're seeing that is motivating this decision or change?"}),"\n",(0,s.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,s.jsx)(t.p,{children:"What is the decision that we're proposing and/or doing?\nShould also include reasoning for this decision"}),"\n",(0,s.jsx)(t.h2,{id:"consequences",children:"Consequences"}),"\n",(0,s.jsx)(t.p,{children:"What becomes easier or more difficult to do because of this change?"}),"\n",(0,s.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,s.jsx)(t.p,{children:"Related Documents, OPTIONAL"})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>r});var s=n(96540);const i={},o=s.createContext(i);function c(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e34f30ed.22428f34.js b/assets/js/e34f30ed.22428f34.js new file mode 100644 index 0000000000..b85679a55d --- /dev/null +++ b/assets/js/e34f30ed.22428f34.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6211],{83941:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>c});var t=n(74848),o=n(28453);const r={},a="IaaS monitoring (experimental)",i={id:"operating-scs/components/monitoring/docs/iaas",title:"IaaS monitoring (experimental)",description:"This component is marked as experimental, and it is not part of the reference SCS installation available",source:"@site/docs/04-operating-scs/components/monitoring/docs/iaas.md",sourceDirName:"04-operating-scs/components/monitoring/docs",slug:"/operating-scs/components/monitoring/docs/iaas",permalink:"/docs/operating-scs/components/monitoring/docs/iaas",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/monitoring/docs/iaas.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Infrastructure service endpoints",permalink:"/docs/operating-scs/components/monitoring/docs/infrastructure_services"},next:{title:"KaaS monitoring (experimental)",permalink:"/docs/operating-scs/components/monitoring/docs/kaas"}},l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Local environment use case - KinD/K3s cluster deployed locally",id:"local-environment-use-case---kindk3s-cluster-deployed-locally",level:3},{value:"KinD",id:"kind",level:4},{value:"K3s",id:"k3s",level:4},{value:"OSISM use case - K3s cluster in OSISM deployment",id:"osism-use-case---k3s-cluster-in-osism-deployment",level:3},{value:"Deploy IaaS monitoring components",id:"deploy-iaas-monitoring-components",level:2},{value:"OpenStack",id:"openstack",level:3},{value:"Prometheus metrics and alerts",id:"prometheus-metrics-and-alerts",level:4},{value:"Grafana dashboards",id:"grafana-dashboards",level:4},{value:"Update the SCS monitoring deployment",id:"update-the-scs-monitoring-deployment",level:4},{value:"Access the OpenStack dashboard",id:"access-the-openstack-dashboard",level:4},{value:"Ceph",id:"ceph",level:3},{value:"Prometheus metrics and alerts",id:"prometheus-metrics-and-alerts-1",level:4},{value:"Grafana dashboards",id:"grafana-dashboards-1",level:4},{value:"Update the SCS monitoring deployment",id:"update-the-scs-monitoring-deployment-1",level:4}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h1,{id:"iaas-monitoring-experimental",children:"IaaS monitoring (experimental)"}),"\n",(0,t.jsxs)(s.p,{children:["This component is marked as experimental, and it is not part of the reference SCS installation available\nat ",(0,t.jsx)(s.a,{href:"https://monitoring.scs.community",children:"https://monitoring.scs.community"}),"."]}),"\n",(0,t.jsx)(s.p,{children:"IaaS monitoring currently integrates and is able to observe the following targets:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"#openstack",children:"OpenStack"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"#ceph",children:"Ceph"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(s.p,{children:"To test the Monitoring of the IaaS layer we expect running Kubernetes cluster that already contains\nSCS monitoring platform."}),"\n",(0,t.jsx)(s.h3,{id:"local-environment-use-case---kindk3s-cluster-deployed-locally",children:"Local environment use case - KinD/K3s cluster deployed locally"}),"\n",(0,t.jsx)(s.h4,{id:"kind",children:"KinD"}),"\n",(0,t.jsxs)(s.p,{children:["Install the SCS monitoring solution into the KinD Kubernetes cluster following the instructions provided in\nthe ",(0,t.jsx)(s.a,{href:"/docs/operating-scs/components/monitoring/docs/quickstart",children:"quickstart guide"}),"."]}),"\n",(0,t.jsx)(s.h4,{id:"k3s",children:"K3s"}),"\n",(0,t.jsxs)(s.p,{children:["Install the SCS monitoring solution into the K3s Kubernetes cluster following the instructions provided in\nthe ",(0,t.jsx)(s.a,{href:"/docs/operating-scs/components/monitoring/docs/k3s",children:"k3s guide"}),"."]}),"\n",(0,t.jsx)(s.h3,{id:"osism-use-case---k3s-cluster-in-osism-deployment",children:"OSISM use case - K3s cluster in OSISM deployment"}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://osism.tech/docs/guides/deploy-guide/services/kubernetes",children:"OSISM"})," utilizes the k3s distribution of Kubernetes\nas a management cluster for the OSISM IaaS platform. This management cluster is then used as a host for\nthe SCS monitoring solution. Subsequently, the management cluster becomes an Observer cluster as it hosts\nthe SCS monitoring solution.\nFrom that point, the Observer cluster observes itself (i.e., k3s cluster control plane components and nodes) and is used\nfor observing the IaaS layer around the k3s cluster."]}),"\n",(0,t.jsxs)(s.p,{children:["In the case of the existing ",(0,t.jsx)(s.a,{href:"https://osism.tech/docs/release-notes/osism-7#703",children:"OSISM IaaS deployment >= 7.0.3"})," on\nbaremetal, ",(0,t.jsx)(s.a,{href:"https://osism.tech/docs/guides/other-guides/testbed",children:"testbed"})," or ",(0,t.jsx)(s.a,{href:"https://osism.tech/docs/guides/other-guides/cloud-in-a-box",children:"cloud in the box"}),"\nwe expect a management k3s Kubernetes cluster with the deployed SCS monitoring platform.\nIf your OSISM installation does not meet the above requirements, apply the following plays:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"osism apply kubernetes\nosism apply kubernetes-monitoring\n"})}),"\n",(0,t.jsx)(s.h2,{id:"deploy-iaas-monitoring-components",children:"Deploy IaaS monitoring components"}),"\n",(0,t.jsx)(s.h3,{id:"openstack",children:"OpenStack"}),"\n",(0,t.jsx)(s.h4,{id:"prometheus-metrics-and-alerts",children:"Prometheus metrics and alerts"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"https://github.com/openstack-exporter",children:"OpenStack exporter for Prometheus"})," could be deployed using the SCS ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/openstack-exporter-helm-charts",children:"openstack-exporter-helm-chart"}),".\nThis exporter contains a bunch of ",(0,t.jsx)(s.a,{href:"https://github.com/SovereignCloudStack/openstack-exporter-helm-charts/blob/master/charts/prometheus-openstack-exporter/templates/prometheusrule.yaml",children:"Prometheus alerts and rules"}),"\nthat are deployed together with the exporter.\nVisit the ",(0,t.jsx)(s.code,{children:"iaas/openstack-exporter-values.yaml"})," file to validate the Helm configuration options.\nEnsure valid OpenStack API credentials are set under the ",(0,t.jsx)(s.code,{children:"clouds_yaml_config"})," section. This ",(0,t.jsx)(s.strong,{children:"MUST"})," be overridden!"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:'helm upgrade --install prometheus-openstack-exporter oci://registry.scs.community/openstack-exporter/prometheus-openstack-exporter \\\n --version 0.4.5 \\\n -f iaas/openstack-exporter-values.yaml # --set "endpoint_type=public" --set "serviceMonitor.scrapeTimeout=1m"\n'})}),"\n",(0,t.jsxs)(s.p,{children:["Tip: If you want to test the exporter basic functionality with ",(0,t.jsx)(s.strong,{children:"public"})," OpenStack API, configure ",(0,t.jsx)(s.code,{children:"endpoint_type"}),"\nto ",(0,t.jsx)(s.code,{children:"public"})," (",(0,t.jsx)(s.code,{children:'--set "endpoint_type=public"'}),"). Note that configuring ",(0,t.jsx)(s.code,{children:"endpoint_type"})," as ",(0,t.jsx)(s.code,{children:"public"})," will result in\nincomplete functionality for the Grafana dashboard."]}),"\n",(0,t.jsxs)(s.p,{children:["Tip: Requesting and collecting metrics from the OpenStack API can be time-consuming, especially if the API is not\nperforming well. In such cases, you may observe timeouts on the Prometheus server when it tries to fetch OpenStack\nmetrics. To mitigate this, consider increasing the scrape interval to e.g. 1 minute (",(0,t.jsx)(s.code,{children:'--set "serviceMonitor.scrapeTimeout=1m"'}),")."]}),"\n",(0,t.jsx)(s.h4,{id:"grafana-dashboards",children:"Grafana dashboards"}),"\n",(0,t.jsxs)(s.p,{children:["The Grafana dashboard designed to visualize metrics collected from an OpenStack cloud through the OpenStack exporter\nis publicly available at ",(0,t.jsx)(s.a,{href:"https://grafana.com/grafana/dashboards/21085",children:"https://grafana.com/grafana/dashboards/21085"}),". Its source code is located in the\n",(0,t.jsx)(s.code,{children:"iaas/dashboards"})," directory. Feel free to import it to the Grafana via its source or ID.\nFor automatic integration into the SCS monitoring solution proceed to the next step."]}),"\n",(0,t.jsx)(s.h4,{id:"update-the-scs-monitoring-deployment",children:"Update the SCS monitoring deployment"}),"\n",(0,t.jsx)(s.p,{children:"This step deploys the Grafana dashboards and instructs the monitoring stack to add the OpenStack exporter target into the Prometheus configuration:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack --reset-then-reuse-values -f iaas/values-observer-iaas.yaml\n"})}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["Note: The ",(0,t.jsx)(s.code,{children:"--reset-then-reuse-values"})," option requires Helm v3.14.0 or later. Alternatively, you can use the original values\nby applying ",(0,t.jsx)(s.code,{children:"-f values-observer.yaml"}),", see full command: ",(0,t.jsx)(s.code,{children:"helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml -f iaas/values-observer-iaas.yaml"})]}),"\n"]}),"\n",(0,t.jsx)(s.h4,{id:"access-the-openstack-dashboard",children:"Access the OpenStack dashboard"}),"\n",(0,t.jsx)(s.p,{children:"At this point, you should have the ability to access the Grafana UI, and OpenStack dashboard."}),"\n",(0,t.jsx)(s.p,{children:"Log in to the Grafana UI and find the OpenStack dashboard in IaaS directory:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"http://localhost:30000\n"})}),"\n",(0,t.jsx)(s.p,{children:"or directly access the OpenStack dashboard:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"http://localhost:30000/d/openstack-overview\n"})}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["Use the following credentials:","\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["username: ",(0,t.jsx)(s.code,{children:"admin"})]}),"\n",(0,t.jsxs)(s.li,{children:["password: ",(0,t.jsx)(s.code,{children:"pass"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"ceph",children:"Ceph"}),"\n",(0,t.jsxs)(s.p,{children:["The SCS IaaS reference implementation (OSISM) currently supports ",(0,t.jsx)(s.a,{href:"https://github.com/ceph/ceph-ansible",children:"ceph-ansible"}),"\nmethod for deploying Ceph. Support for the ",(0,t.jsx)(s.a,{href:"https://github.com/rook/rook",children:"rook operator"})," deployment method will be available ",(0,t.jsx)(s.a,{href:"https://github.com/osism/issues/issues/881",children:"soon"}),"."]}),"\n",(0,t.jsx)(s.p,{children:"This guide covers Ceph cluster monitoring for both deployment methods. While both expose the same metrics via the same\nendpoint, there are some differences in Prometheus configuration and alerts."}),"\n",(0,t.jsx)(s.h4,{id:"prometheus-metrics-and-alerts-1",children:"Prometheus metrics and alerts"}),"\n",(0,t.jsx)(s.p,{children:"Ceph contains 2 build-in sources of metrics a.k.a. exporters.\nThe Ceph exporter (introduced in Reef release of Ceph) is the main source of Ceph performance metrics. It runs as a\ndedicated daemon. This daemon runs on every Ceph cluster host and exposes a metrics end point where all the performance\ncounters exposed by all the Ceph daemons running in the host are published in the form of Prometheus metrics."}),"\n",(0,t.jsx)(s.p,{children:"The second source of metrics is the Prometheus manager module. It exposes metrics related to the whole cluster,\nbasically metrics that are not produced by individual Ceph daemons."}),"\n",(0,t.jsxs)(s.p,{children:["Read the related Ceph ",(0,t.jsx)(s.a,{href:"https://docs.ceph.com/en/reef/monitoring/#ceph-metrics",children:"docs"}),".\nSince these exporters are integrated with Ceph, deploying a third-party Ceph exporter is unnecessary."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.strong,{children:"Prometheus alerts"})}),"\n",(0,t.jsxs)(s.p,{children:["Both Ceph deployment strategies use the ceph-mixins project as a source of alerts. The ceph-ansible and rook projects\neach maintain a rendered version of these alerts, but the rook repository contains some differences, primarily because\nrook does not use the cephadm tool as a backend.\nTherefore, find and apply one of the following commands to create a custom observer rules values file for either the\nceph-ansible or ceph-rook deployment (",(0,t.jsx)(s.a,{href:"https://github.com/mikefarah/yq/#install",children:"yq"})," tool required):"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:'# ceph-ansible\ncurl -s https://raw.githubusercontent.com/ceph/ceph/main/monitoring/ceph-mixin/prometheus_alerts.yml | \\\n yq \'{"kube-prometheus-stack": {"additionalPrometheusRulesMap": {"ceph-ansible-rules": (. + {"additionalLabels": {"prometheus_rule": "1"}})}}}\' > iaas/values-observer-ceph-rules.yaml\n\n# rook\ncurl -s https://raw.githubusercontent.com/rook/rook/master/deploy/charts/rook-ceph-cluster/prometheus/localrules.yaml | \\\n yq \'{"kube-prometheus-stack": {"additionalPrometheusRulesMap": {"ceph-rook-rules": (. + {"additionalLabels": {"prometheus_rule": "1"}})}}}\' > iaas/values-observer-ceph-rules.yaml\n'})}),"\n",(0,t.jsx)(s.h4,{id:"grafana-dashboards-1",children:"Grafana dashboards"}),"\n",(0,t.jsx)(s.p,{children:"We've tested and could recommend 2 sources of Grafana dashboards that are suitable for both Ceph deployment strategies (ansible and rook):"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://rook.io/docs/rook/latest-release/Storage-Configuration/Monitoring/ceph-monitoring/?h=gra#grafana-dashboards",children:"dashboards linked in rook docs"})}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"https://github.com/ceph/ceph-mixins/tree/master/dashboards",children:"ceph-mixins dashboards"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["Built version of ceph-mixins dashboards could be found e.g. ",(0,t.jsx)(s.a,{href:"https://github.com/ceph/ceph/tree/main/monitoring/ceph-mixin/dashboards_out",children:"here"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(s.p,{children:["We consider the dashboards created within the Rook project as a solid starting point for Ceph metrics visualization.\nIf you want to see more detailed dashboards, uncomment and use the ceph-mixin dashboards in the ",(0,t.jsx)(s.code,{children:"values-observer-ceph-rook.yaml"}),"\nor ",(0,t.jsx)(s.code,{children:"values-observer-ceph-ansible.yaml"})," file. You can use both."]}),"\n",(0,t.jsx)(s.h4,{id:"update-the-scs-monitoring-deployment-1",children:"Update the SCS monitoring deployment"}),"\n",(0,t.jsxs)(s.p,{children:["This step deploys Grafana dashboards, Prometheus rules and instruct monitoring stack to add the Ceph exporter targets into the Prometheus configuration.\nEnsure that you add the monitoring targets' IPs and ports to ",(0,t.jsx)(s.code,{children:"values-observer-ceph-ansible.yaml"})," for Ceph-ansible deployment."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack --reset-then-reuse-values \\\n -f iaas/values-observer-ceph-rules.yaml \\\n -f iaas/values-observer-ceph-[rook|ansible].yaml # use values file for either the ceph-ansible or ceph-rook deployment\n"})}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["Note: The ",(0,t.jsx)(s.code,{children:"--reset-then-reuse-values"})," option requires Helm v3.14.0 or later. Alternatively, you can use the original values\nby applying ",(0,t.jsx)(s.code,{children:"-f values-observer.yaml"}),", see full command: ",(0,t.jsx)(s.code,{children:"helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml -f iaas/values-observer-ceph-rules.yaml -f iaas/values-observer-ceph-[rook|ansible].yaml"})]}),"\n"]})]})}function d(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>i});var t=n(96540);const o={},r=t.createContext(o);function a(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e44168e5.14af424f.js b/assets/js/e44168e5.14af424f.js new file mode 100644 index 0000000000..6018c474ff --- /dev/null +++ b/assets/js/e44168e5.14af424f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1909],{22864:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>u});var i=n(74848),r=n(28453);const o={sidebar:2},s="Virtualization",a={id:"getting-started/virtualization",title:"Virtualization",description:"TODO",source:"@site/docs/01-getting-started/virtualization.md",sourceDirName:"01-getting-started",slug:"/getting-started/virtualization",permalink:"/docs/getting-started/virtualization",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/01-getting-started/virtualization.md",tags:[],version:"current",frontMatter:{sidebar:2}},c={},u=[];function d(t){const e={h1:"h1",p:"p",...(0,r.R)(),...t.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.h1,{id:"virtualization",children:"Virtualization"}),"\n",(0,i.jsx)(e.p,{children:"TODO"})]})}function l(t={}){const{wrapper:e}={...(0,r.R)(),...t.components};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(d,{...t})}):d(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>s,x:()=>a});var i=n(96540);const r={},o=i.createContext(r);function s(t){const e=i.useContext(o);return i.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:s(t.components),i.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/e57b2c87.50198570.js b/assets/js/e57b2c87.50198570.js new file mode 100644 index 0000000000..6bca7b7b29 --- /dev/null +++ b/assets/js/e57b2c87.50198570.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4016],{90330:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>p,toc:()=>r});var s=t(74848),o=t(28453);const i={},a="Component Overview",p={id:"operating-scs/components/status-page/docs/component_overview",title:"Component Overview",description:"This represents a part of the decision process related to the overall structure the API wants to represent.",source:"@site/docs/04-operating-scs/components/status-page/docs/component_overview.md",sourceDirName:"04-operating-scs/components/status-page/docs",slug:"/operating-scs/components/status-page/docs/component_overview",permalink:"/docs/operating-scs/components/status-page/docs/component_overview",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/04-operating-scs/components/status-page/docs/component_overview.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Overview",permalink:"/docs/operating-scs/components/status-page/docs/overview"},next:{title:"Components",permalink:"/docs/operating-scs/components/status-page/docs/components"}},c={},r=[];function m(e){const n={h1:"h1",li:"li",mermaid:"mermaid",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"component-overview",children:"Component Overview"}),"\n",(0,s.jsx)(n.p,{children:"This represents a part of the decision process related to the overall structure the API wants to represent."}),"\n",(0,s.jsx)(n.mermaid,{value:'C4Component\n title status-page-openapi\n\n Container_Boundary(impacts, "Impacts") {\n Component(impactType, ImpactType, "ID, displayName, description")\n Component(impact, Impact, "type, reference, severity")\n Component(impactComponentList, ImpactComponentList, "[]Impact", "Impacts reference components")\n Component(impactIncidentList, ImpactIncidentList, "<<readonly>>[]Impact", "Impacts reference incidents")\n Component(severity, Severity,"name, value")\n\n Rel(impact, impactType, "has")\n Rel(impactComponentList, impact, "lists")\n Rel(impactIncidentList, impact, "lists")\n Rel(impact, severity, "has", "when used by ImpactIncidentList")\n\n UpdateElementStyle(impact, $bgColor="green")\n UpdateElementStyle(impactComponentList, $bgColor="green")\n UpdateElementStyle(impactIncidentList, $bgColor="green")\n UpdateElementStyle(severity, $bgColor="green")\n\n UpdateRelStyle(impact, impactType, "green", "green", $offsetY="-10")\n UpdateRelStyle(impactComponentList, impact, "green", "green", $offsetY="-15")\n UpdateRelStyle(impactIncidentList, impact, "green", "green")\n UpdateRelStyle(impact, severity, "green", "green")\n }\n\n Container_Boundary(incidents, "Incidents") {\n Component(incidentUpdate, IncidentUpdate, "order, displayName, description, createdAt")\n Component(incident, Incident, "ID, displayName, description, updates, affects, beganAt, endedAt, Phase")\n\n Rel(incident, incidentUpdate, "contains")\n }\n\n Container_Boundary(phases, "Phases") {\n Component(phaseReference, PhaseReference, "Phase, order, generation")\n Component(phase, Phase, "", "it is just a name")\n Component(phaseList, PhaseList, "generation, []Phase")\n\n Rel(phaseList, phase, "lists")\n Rel(phaseReference, phase, "references")\n Rel(phaseReference, phaseList, "references")\n\n UpdateElementStyle(phaseReference, $bgColor="green")\n UpdateElementStyle(phaseList, $bgColor="green")\n\n UpdateRelStyle(phaseList, phase, "green", "green", $offsetY="5")\n UpdateRelStyle(phaseReference, phase, "green", "green", $offsetX="-30", $offsetY="10")\n UpdateRelStyle(phaseReference, phaseList, "green", "green", $offsetY="5")\n\n }\n\n Container_Boundary(components, "Components") {\n Component(component, Component, "ID, displayName, Labels, activelyAffectedBy")\n Component(labels, Labels, "", "Key value pairs")\n\n Rel(component, labels, "contains")\n }\n\n %% global relations %%\n %% deprecated %%\n Rel(incident, impactType, "has")\n BiRel(component, incident, "affects / affected by")\n\n UpdateRelStyle(incident, impactType, "red", "red")\n UpdateRelStyle(component, incident, "red", "red", $offsetX="10")\n\n %% new %%\n Rel(incident, impactComponentList, "affects")\n Rel(component, impactIncidentList, "actively affected by", "only list active/open impacts")\n Rel(incident, phaseReference, "has")\n Rel(impact, component, "references", "from impactComponentList")\n Rel(impact, incident, "references", "from impactIncidentList")\n\n UpdateRelStyle(incident, impactComponentList, "green", "green")\n UpdateRelStyle(component, impactIncidentList, "green", "green", $offsetX="-180", $offsetY="-70")\n UpdateRelStyle(incident, phaseReference, "green", "green", $offsetX="-70", $offsetY="40")\n UpdateRelStyle(impact, component, "green", "green", $offsetX="-140")\n UpdateRelStyle(impact, incident, "green", "green", $offsetX="-100")\n'}),"\n",(0,s.jsx)(n.p,{children:"Color meaning:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Blue: Existing structure"}),"\n",(0,s.jsx)(n.li,{children:"Red: Deprecated / removed"}),"\n",(0,s.jsx)(n.li,{children:"Green: New"}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(m,{...e})}):m(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>p});var s=t(96540);const o={},i=s.createContext(o);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function p(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e6095437.218c6e9b.js b/assets/js/e6095437.218c6e9b.js new file mode 100644 index 0000000000..022c4eed85 --- /dev/null +++ b/assets/js/e6095437.218c6e9b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2546],{53874:e=>{e.exports=JSON.parse('{"title":"Automated Pentesting","slug":"/category/automated-pentesting","permalink":"/docs/category/automated-pentesting","navigation":{"previous":{"title":"Central API MVP","permalink":"/docs/operating-scs/components/central-api/poc-setup"},"next":{"title":"SCS automated pentesting","permalink":"/docs/operating-scs/components/automated-pentesting/overview"}}}')}}]); \ No newline at end of file diff --git a/assets/js/e747ec83.c7e4b16c.js b/assets/js/e747ec83.c7e4b16c.js new file mode 100644 index 0000000000..14d3e89807 --- /dev/null +++ b/assets/js/e747ec83.c7e4b16c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9432],{13340:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>c});var o=n(74848),a=n(28453);const i={},s="Glossary",r={id:"glossary",title:"Glossary",description:"This file serves as the central glossary within SCS. It is intended to clearly",source:"@site/docs/glossary.md",sourceDirName:".",slug:"/glossary",permalink:"/docs/glossary",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/glossary.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Frequently Asked Questions",permalink:"/docs/faq/"}},l={},c=[{value:"Definition of a Region",id:"definition-of-a-region",level:2},{value:"Definition of a Availability Zone",id:"definition-of-a-availability-zone",level:2},{value:"Definition of Host Aggregates",id:"definition-of-host-aggregates",level:2},{value:"Definition of a Cell",id:"definition-of-a-cell",level:2},{value:"Definition of a Control Plane",id:"definition-of-a-control-plane",level:2},{value:"Definition of Control Node",id:"definition-of-control-node",level:2},{value:"Definition of Compute Node",id:"definition-of-compute-node",level:2},{value:"Definition of Manager Node",id:"definition-of-manager-node",level:2},{value:"Definition of provider network",id:"definition-of-provider-network",level:2},{value:"Definition of API",id:"definition-of-api",level:2},{value:"Horizon",id:"horizon",level:2},{value:"Message Queue",id:"message-queue",level:2},{value:"Keystone",id:"keystone",level:2},{value:"Glance",id:"glance",level:2},{value:"OSISM",id:"osism",level:2},{value:"Ceph",id:"ceph",level:2},{value:"Nova",id:"nova",level:2},{value:"Neutron",id:"neutron",level:2},{value:"Cinder",id:"cinder",level:2},{value:"Swift",id:"swift",level:2},{value:"Ceph OSD",id:"ceph-osd",level:2},{value:"Personas",id:"personas",level:2}];function d(e){const t={h1:"h1",h2:"h2",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"glossary",children:"Glossary"}),"\n",(0,o.jsx)(t.p,{children:"This file serves as the central glossary within SCS. It is intended to clearly\ndefine terms used within SCS where there may be differing understandings. The\nglossary is not intended to evaluate or standardize specific terms."}),"\n",(0,o.jsx)(t.h2,{id:"definition-of-a-region",children:"Definition of a Region"}),"\n",(0,o.jsx)(t.p,{children:"An OpenStack/SCS region consists of at least one or more Availability Zones that share a Control Plane with their services. As a result, they share one API. Also a Control Plane can share one CEPH cluster over different fire departments or each Availbility Zone can have its own CEPH cluster. Within the region, any Layer 2 networks are available to the user. Availbility Zones which build a region are connected by redundant low-latency (< 2ms ) high-bandwidth (10s of Gbps) connections."}),"\n",(0,o.jsx)(t.p,{children:"Regions can be federated when the SCS code is ready."}),"\n",(0,o.jsx)(t.h2,{id:"definition-of-a-availability-zone",children:"Definition of a Availability Zone"}),"\n",(0,o.jsx)(t.p,{children:"An Availability Zone is a (physical) group of multiple compute nodes, controlled by the region's control plane that provides the API and interface."}),"\n",(0,o.jsx)(t.p,{children:"An Availability Zone allows OpenStack compute hosts to be divided into logical groups and provides a form of physical isolation and redundancy from other Availability Zones, for example by using a separate power supply or network devices."}),"\n",(0,o.jsx)(t.p,{children:"When users provision resources, they can specify in which Availability Zone their instances should be created. In this way, customers can ensure that their application resources are distributed across different failure domains to achieve high availability in the event of a hardware failure."}),"\n",(0,o.jsx)(t.h2,{id:"definition-of-host-aggregates",children:"Definition of Host Aggregates"}),"\n",(0,o.jsx)(t.p,{children:"Host aggregates are a mechanism for partitioning compute nodes which is not explicitly visible to users in an OpenStack/SCS cloud. Host aggregates are based on arbitrary characteristics such as server type, processor type, GPU, disk speed, etc.\nAdministrators assign flavors to host aggregates by specifying metadata on the host aggregate and customizing the extra specifications of the flavor. It is then up to the Nova scheduler to determine the best match for the user request. Compute nodes can also be in more than one host aggregate."}),"\n",(0,o.jsx)(t.p,{children:"Optionally, one can designate a host aggregate as an Availability Zone, e.g. for simplification reasons of the user selection of an availbility zone.\nAvailability Zones differ from Host Aggregates in that they are shown to the user as a Nova boot option, so Compute VMs can be started on them.\nCompute Nodes, however, can only be in a single Availability Zone. We can configure a default Availability Zone where instances will be scheduled if the user does not specify an Availability Zone."}),"\n",(0,o.jsx)(t.p,{children:"Info: A prerequisite for creating an Availability Zone is a host aggregate."}),"\n",(0,o.jsx)(t.h2,{id:"definition-of-a-cell",children:"Definition of a Cell"}),"\n",(0,o.jsx)(t.p,{children:"The Cells paradigm simplifies the handling of large Openstack deployments."}),"\n",(0,o.jsx)(t.p,{children:"Cells is an OpenStack Nova feature that improves scalability for Nova in OpenStack Platform. Each Cell has a separate database and message queue, which increases performance when scaling. One can provision additional Cells to handle large deployments, and compared to Regions, this allows access to a large number of compute nodes through a single API."}),"\n",(0,o.jsx)(t.p,{children:"Each Cell has its own Cell controllers running the database server and RabbitMQ along with the Nova Conductor services."}),"\n",(0,o.jsx)(t.p,{children:'Nova Conductor services, called "Super Conductor", continue to run on the main controller nodes.'}),"\n",(0,o.jsx)(t.p,{children:"The services in the Cell Controllers can still call placement APIs, but cannot access other API layer services via RPC, nor can they access global API databases on the control nodes."}),"\n",(0,o.jsx)(t.h2,{id:"definition-of-a-control-plane",children:"Definition of a Control Plane"}),"\n",(0,o.jsx)(t.p,{children:"In Openstack/SCS, a Control Plane consists of at least 5 hardware nodes, which together serve several Availability Zones and thus provide a common usable API for a region. The Control Plane also shares the network (Neutron), the Scheduler and the CEPH services."}),"\n",(0,o.jsx)(t.p,{children:"It includes the Controller Nodes (Galera Cluster, RabbitMQ) and the Manager Nodes, Maas,..."}),"\n",(0,o.jsx)(t.h2,{id:"definition-of-control-node",children:"Definition of Control Node"}),"\n",(0,o.jsx)(t.p,{children:"The Control Node runs the Identity Service, Image Service , management processes for compute nodes, management processes for networking, various networking agents, and the Dashboard. It also includes supporting services such as an SQL database, a message queue, and NTP."}),"\n",(0,o.jsx)(t.p,{children:"Optionally, the Controller Node runs parts of the Block Storage, Object Storage, Orchestration and Telemetry services."}),"\n",(0,o.jsx)(t.p,{children:"The Controller Node requires at least two network interfaces."}),"\n",(0,o.jsx)(t.h2,{id:"definition-of-compute-node",children:"Definition of Compute Node"}),"\n",(0,o.jsx)(t.p,{children:"A compute host runs the hypervisor part of compute that runs instances. By default, compute uses the KVM hypervisor. The compute host also runs a networking service agent that connects instances to virtual networks and provides firewall services to the instances through security groups."}),"\n",(0,o.jsx)(t.p,{children:"If you offer hyper-converged infrastructure, a compute host also serves the Ceph. This makes the storage dynamically scalable (horizontally and vertically). For the Ceph services, 1 CPU core and 4 GB of RAM are reserved per OSD to ensure appropriate performance."}),"\n",(0,o.jsx)(t.h2,{id:"definition-of-manager-node",children:"Definition of Manager Node"}),"\n",(0,o.jsx)(t.p,{children:"From here, the OSISM Ansible playbooks are applied to the environment. Furthermore, the following services often run here non-redundantly: Prometheus server,...."}),"\n",(0,o.jsx)(t.h2,{id:"definition-of-provider-network",children:"Definition of provider network"}),"\n",(0,o.jsx)(t.p,{children:'The provider network is the network that is "in front", i.e. at the output points of the openstack/SCS. This is usually a public network, but can also be a private network in individual cases. IPs from the provider network can be assigned to instances within the SCS. The same applies to load balancers, of course.'}),"\n",(0,o.jsx)(t.h2,{id:"definition-of-api",children:"Definition of API"}),"\n",(0,o.jsx)(t.p,{children:"The Rest API provides the core of openstack/SCS and can be addressed for a whole region. It accepts and responds to end-user API calls. The service supports the OpenStack Compute API, the Amazon EC2 API, and a special Admin API for privileged users to perform administrative actions. Policies are enforced and most orchestration actions can be started, such as launching an instance."}),"\n",(0,o.jsx)(t.h2,{id:"horizon",children:"Horizon"}),"\n",(0,o.jsx)(t.p,{children:"Horizon is openstack's preferred GUI for the end user, but also for the administrator for a quick overview. It runs on the controller node. Other GUIs are possible, also GUIs which replace the horizon interface"}),"\n",(0,o.jsx)(t.h2,{id:"message-queue",children:"Message Queue"}),"\n",(0,o.jsx)(t.p,{children:"Most OpenStack services communicate with each other through the message queue. For example, Compute communicates with Block Storage services and Network services via the message queue. RabbitMQ, Qpid, and Zeromq are popular choices for a message queue service. When the message queue fails or becomes inaccessible, the cluster generally comes to a halt and ends up in a read-only state where the information is stuck at the point where the last message was sent. Therefore, this is clustered. RabbitMQ has shown itself to be the most widespread and best supported variant in the OpenStack context, Qpid occurs occasionally, ZeroMQ lacks HA functionality to date"}),"\n",(0,o.jsx)(t.h2,{id:"keystone",children:"Keystone"}),"\n",(0,o.jsx)(t.p,{children:'( The OpenStack Identity module called Keystone is used as an authentication and rights system between the OpenStack components. Keystone divides access to projects in the cloud into so-called "tenants". A tenant is a tenant of the cloud and has at least one assigned user. It is possible to create multiple users per tenant with different rights. Keystone uses a token system for authorization and also supports the connection to other authentication options such as LDAP. (wikipedia) )'}),"\n",(0,o.jsx)(t.h2,{id:"glance",children:"Glance"}),"\n",(0,o.jsx)(t.p,{children:"The OpenStack Image Service, also called Glance, is a service that provides virtual machine images to OpenStack users. These images are used by Nova as a template to compile virtual machine instances. Both local hard disks and object storage solutions such as Swift or Ceph can be used as storage backends."}),"\n",(0,o.jsx)(t.p,{children:"In addition to the images, Glance can also store metadata such as the operating system used or the kernel version. Access to both this metadata and the images themselves is via a REST API. Glance supports a number of formats such as VHD, VMDK and qcow2."}),"\n",(0,o.jsx)(t.h2,{id:"osism",children:"OSISM"}),"\n",(0,o.jsx)(t.p,{children:"The Open Source Infrastructure & Service Manager is a powerful deployment framework for OpenStack and Ceph as well as required services such as a RabbitMQ broker or a MariaDB Galera cluster."}),"\n",(0,o.jsx)(t.h2,{id:"ceph",children:"Ceph"}),"\n",(0,o.jsx)(t.p,{children:"Ceph is an open source distributed storage solution. The core component is RADOS (Reliable Autonomic Distributed Object Store), an object store that can be distributed redundantly over any number of servers. Ceph offers the user three types of storage: An object store compatible with the Swift and S3 API (RADOS Gateway), virtual block devices (RADOS Block Devices) and CephFS, a distributed file system."}),"\n",(0,o.jsx)(t.h2,{id:"nova",children:"Nova"}),"\n",(0,o.jsx)(t.p,{children:"Nova is virtually a synonym for Compute. It is the part of the stack that can manage groups of virtual machines."}),"\n",(0,o.jsx)(t.p,{children:"The virtualized systems can be distributed over any number of so-called compute nodes. Hypervisors supported include KVM, Xen Hyper-V and ESXI. In the community, KVM is considered to be set and best supported (we use KVM), which is controlled via libvirt. ESXI and Hyper-V can be used, sometimes with limited functionality."}),"\n",(0,o.jsx)(t.h2,{id:"neutron",children:"Neutron"}),"\n",(0,o.jsx)(t.p,{children:'The OpenStack Networking module Neutron provides the networking service for OpenStack. Neutron can be used to manage networks, subnets, and IP addresses/floating IPs. A floating IP in OpenStack refers to an official IP that serves as an interface from the internal to the public network. In addition to a load balancer, HA proxy and health monitor, Neutron also supports techniques such as VLAN and VPN. To secure the networks, Neutron uses a firewall that allows versatile port rules, e.g. on a security group basis. For trademark reasons, the OpenStack networking module had to be renamed "Neutron". The previous name was "Quantum".'}),"\n",(0,o.jsx)(t.p,{children:"For the management of the data link layer, Neutron offers the possibility to use various already existing networking software such as Open vSwitch or the bridge functionality of the Linux kernel by means of plugins."}),"\n",(0,o.jsx)(t.p,{children:'In the OpenStack releases since Ussuri, the "OpenVirtualNetwork"(OVN) has established itself, it replaces many of the Neutron components, e.g. L3 and DHCP agent, so that Neutron only has to talk directly to OVN.'}),"\n",(0,o.jsx)(t.h2,{id:"cinder",children:"Cinder"}),"\n",(0,o.jsx)(t.p,{children:"OpenStack Block Storage or Cinder provides virtual block storage in the form of virtualized storage media (hard disks, CDs, etc.). The block storage can be attached to virtual machines. An API interface allows Cinder to connect to Swift so that block storage media can communicate with object storage. Meanwhile, many other storage backends are also fully or partially supported. There is also the option of defining multiple backends and creating a volume type for each backend, so that when a new volume is created, it can be selected on which storage backend the volume is created."}),"\n",(0,o.jsx)(t.h2,{id:"swift",children:"Swift"}),"\n",(0,o.jsx)(t.p,{children:"Swift is the so-called object storage that can be used by Nova. This is responsible for redundant data storage. Swift can also be used as a backend for Cinder or Glance. Objects are stored in so-called containers, which are primarily used to group objects and store metadata and in turn belong to individual accounts. Objects and containers are accessed via a REST API."}),"\n",(0,o.jsx)(t.h2,{id:"ceph-osd",children:"Ceph OSD"}),"\n",(0,o.jsx)(t.p,{children:"A Ceph OSD (Object Storage Daemon) logically represents a storage device in a Ceph cluster, which can logically be a hard disk, which is the ideal case. In other cases it can also be a raid, which however leads to considerable performance limitations due to caching or other raid optimization."}),"\n",(0,o.jsx)(t.h2,{id:"personas",children:"Personas"}),"\n",(0,o.jsxs)(t.table,{children:[(0,o.jsx)(t.thead,{children:(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.th,{children:"Persona"}),(0,o.jsx)(t.th,{children:"Description"})]})}),(0,o.jsxs)(t.tbody,{children:[(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"SCS Operator"}),(0,o.jsx)(t.td,{children:"The SCS Operator is the one who owns and operates a standardized cloud environment."})]}),(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"SCS Operations Team"}),(0,o.jsx)(t.td,{children:"The team at the SCS Operator which actually runs the cloud environment."})]}),(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"SCS Consumer"}),(0,o.jsx)(t.td,{children:"The SCS Consumer consumes a standardized SCS environment and operates and orchestrates applications on top of it. The SCS Consumer is typically a customer or user of the SCS Operator."})]}),(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"SCS Integrator"}),(0,o.jsx)(t.td,{children:"The SCS Integrator assists in or is building up a standardized cloud environment. The SCS Integrator can be 2nd or 3rd level support for the SCS Operator."})]}),(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"SCS Project"}),(0,o.jsx)(t.td,{children:"The SCS Project oversees the overall activities around the Sovereign Cloud Stack."})]}),(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"SCS Developer"}),(0,o.jsx)(t.td,{children:"The SCS Developer actively contributes to technical elements of the Sovereign Cloud Stack."})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>r});var o=n(96540);const a={},i=o.createContext(a);function s(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ea470413.f68b4421.js b/assets/js/ea470413.f68b4421.js new file mode 100644 index 0000000000..547bcbe670 --- /dev/null +++ b/assets/js/ea470413.f68b4421.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8730],{34648:(t,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var e=o(74848),i=o(28453);const r={},s="SIG Monitoring",a={id:"collaboration/sig-monitoring",title:"SIG Monitoring",description:"The Special Interest Group (SIG) Monitoring meets on a fortnightly base (alternating with the audit log WG) to discuss the monitoring needs of SCS Operators, Users and Integrators. Together we shape how monitoring and observability within the SCS landscape looks like.",source:"@site/community/collaboration/sig-monitoring.md",sourceDirName:"collaboration",slug:"/collaboration/sig-monitoring",permalink:"/community/collaboration/sig-monitoring",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"SIG Documentation",permalink:"/community/collaboration/sig-documentation"},next:{title:"SIG Standardization",permalink:"/community/collaboration/sig-standardization"}},c={},l=[];function u(t){const n={h1:"h1",p:"p",...(0,i.R)(),...t.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(n.h1,{id:"sig-monitoring",children:"SIG Monitoring"}),"\n",(0,e.jsx)(n.p,{children:"The Special Interest Group (SIG) Monitoring meets on a fortnightly base (alternating with the audit log WG) to discuss the monitoring needs of SCS Operators, Users and Integrators. Together we shape how monitoring and observability within the SCS landscape looks like."})]})}function m(t={}){const{wrapper:n}={...(0,i.R)(),...t.components};return n?(0,e.jsx)(n,{...t,children:(0,e.jsx)(u,{...t})}):u(t)}},28453:(t,n,o)=>{o.d(n,{R:()=>s,x:()=>a});var e=o(96540);const i={},r=e.createContext(i);function s(t){const n=e.useContext(r);return e.useMemo((function(){return"function"==typeof t?t(n):{...n,...t}}),[n,t])}function a(t){let n;return n=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:s(t.components),e.createElement(r.Provider,{value:n},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/eaf69a59.c5520334.js b/assets/js/eaf69a59.c5520334.js new file mode 100644 index 0000000000..40fc7e4140 --- /dev/null +++ b/assets/js/eaf69a59.c5520334.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7633],{8478:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>d,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var o=n(74848),s=n(28453);const c={},r="Troubleshooting",i={id:"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting",title:"Troubleshooting",description:"This guide explains general info on how to debug issues if a cluster creation fails.",source:"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting.md",sourceDirName:"03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs",slug:"/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting",permalink:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting.md",tags:[],version:"current",frontMatter:{}},a={},l=[{value:"providerClient authentication err",id:"providerclient-authentication-err",level:2}];function u(e){const t={code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,o.jsx)(t.p,{children:"This guide explains general info on how to debug issues if a cluster creation fails."}),"\n",(0,o.jsx)(t.h2,{id:"providerclient-authentication-err",children:"providerClient authentication err"}),"\n",(0,o.jsx)(t.p,{children:"If you are using https, and when you encounter issues like:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{children:'kubectl logs -n cspo-system -l control-plane=controller-manager\n...\n[manager] 2024-04-15T15:20:07Z\tDEBUG\tevents\tPost "https://10.0.3.15/identity/v3/auth/tokens": tls: failed to verify certificate: x509: certificate signed by unknown authority\t{"type": "Warning", "object": {"kind":"OpenStackNodeImageRelease","namespace":"cluster","name":"openstack-ferrol-1-27-ubuntu-capi-image-v1.27.8-v2","uid":"93d2c1c8-5a19-45f8-9f93-8e8bd5227ebf","apiVersion":"infrastructure.clusterstack.x-k8s.io/v1alpha1","resourceVersion":"3773"}, "reason": "OpenStackProviderClientNotSet"}\n...\n'})}),"\n",(0,o.jsx)(t.p,{children:"you must specify the CA certificate in your secret, which contains the access data to the OpenStack instance, then secret should look similar to this example:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:'apiVersion: v1\ndata:\n cacert: <PEM_ENCODED_CA_CERT>\n clouds.yaml: <ENCODED_CLOUDS_YAML>\nkind: Secret\nmetadata:\n labels:\n clusterctl.cluster.x-k8s.io/move: "true"\n name: "openstack"\n namespace: cluster\n'})})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>i});var o=n(96540);const s={},c=o.createContext(s);function r(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eb99bfed.6c5daf69.js b/assets/js/eb99bfed.6c5daf69.js new file mode 100644 index 0000000000..fcd66fbb0d --- /dev/null +++ b/assets/js/eb99bfed.6c5daf69.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6063],{37577:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var t=s(74848),i=s(28453);const a={sidebar_label:"Manager",sidebar_position:10},o="Manager",r={id:"iaas/guides/troubleshooting-guide/manager",title:"Manager",description:"Reset",source:"@site/docs/02-iaas/guides/troubleshooting-guide/manager.md",sourceDirName:"02-iaas/guides/troubleshooting-guide",slug:"/iaas/guides/troubleshooting-guide/manager",permalink:"/docs/iaas/guides/troubleshooting-guide/manager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/troubleshooting-guide/manager.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Manager",sidebar_position:10},sidebar:"docs",previous:{title:"Troubleshooting Guide",permalink:"/docs/iaas/guides/troubleshooting-guide/"},next:{title:"OpenStack",permalink:"/docs/iaas/guides/troubleshooting-guide/openstack"}},c={},l=[{value:"Reset",id:"reset",level:2}];function u(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"manager",children:"Manager"}),"\n",(0,t.jsx)(n.h2,{id:"reset",children:"Reset"}),"\n",(0,t.jsx)(n.p,{children:"Sometimes it is necessary to reset the entire manager service."}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsx)(n.p,{children:"This is a disruptive action. Data is lost in the process. For example, the database\nof the ARA service."})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Stop the manager service"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"sudo systemctl stop docker-compose@manager.service\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Files on the ",(0,t.jsx)(n.code,{children:"/share"})," volume are backed up in advance and restored after\nthe manager service is started."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"docker run --rm \\\n --mount source=manager_share,target=/share \\\n --volume $(pwd):/backup \\\n busybox \\\n tar -czvf /backup/manager-share-$(date +%Y%m%d).tar.gz /share\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Delete the manager service. ",(0,t.jsx)(n.strong,{children:"This is a disruptive action."})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"docker compose --project-directory /opt/manager down -v\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Start the manager service"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"sudo systemctl start docker-compose@manager.service\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Restore the files on the ",(0,t.jsx)(n.code,{children:"/share"})," volume."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"docker run --rm \\\n --mount source=manager_share,target=/share \\\n --volume $(pwd):/backup \\\n busybox \\\n tar -xzvf /backup/manager-share-$(date +%Y%m%d).tar.gz -C /\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Check that manager service is healthy"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"docker compose --project-directory /opt/manager ps\n"})}),"\n",(0,t.jsx)(n.p,{children:"Depending on what the manager service looks like, this output may vary."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS\nceph-ansible quay.io/osism/ceph-ansible:quincy "/entrypoint.sh osis\u2026" ceph-ansible About a minute ago Up About a minute (healthy)\nkolla-ansible quay.io/osism/kolla-ansible:2023.2 "/entrypoint.sh osis\u2026" kolla-ansible About a minute ago Up About a minute (healthy)\nmanager-api-1 quay.io/osism/osism:latest "osism service api" api About a minute ago Up About a minute (healthy) 192.168.16.5:8000->8000/tcp\nmanager-ara-server-1 quay.io/osism/ara-server:latest "sh -c \'/wait && /ru\u2026" ara-server About a minute ago Up About a minute (healthy) 8000/tcp\nmanager-beat-1 quay.io/osism/osism:latest "osism service beat" beat About a minute ago Up About a minute (healthy)\nmanager-conductor-1 quay.io/osism/osism:latest "osism worker conduc\u2026" conductor About a minute ago Up About a minute (healthy)\nmanager-flower-1 quay.io/osism/osism:latest "osism service flower" flower About a minute ago Up About a minute (healthy)\nmanager-inventory_reconciler-1 quay.io/osism/inventory-reconciler:latest "/sbin/tini -- /entr\u2026" inventory_reconciler About a minute ago Up About a minute (healthy)\nmanager-listener-1 quay.io/osism/osism:latest "osism service liste\u2026" listener About a minute ago Up About a minute (healthy)\nmanager-mariadb-1 index.docker.io/library/mariadb:11.3.2 "docker-entrypoint.s\u2026" mariadb About a minute ago Up About a minute (healthy) 3306/tcp\nmanager-netbox-1 quay.io/osism/osism-netbox:latest "osism worker netbox" netbox About a minute ago Up About a minute (healthy)\nmanager-openstack-1 quay.io/osism/osism:latest "osism worker openst\u2026" openstack About a minute ago Up About a minute (healthy)\nmanager-redis-1 index.docker.io/library/redis:7.2.4-alpine "docker-entrypoint.s\u2026" redis About a minute ago Up About a minute (healthy) 6379/tcp\nmanager-watchdog-1 quay.io/osism/osism:latest "osism service watch\u2026" watchdog About a minute ago Up About a minute (healthy)\nosism-ansible quay.io/osism/osism-ansible:latest "/entrypoint.sh osis\u2026" osism-ansible About a minute ago Up About a minute (healthy)\nosismclient quay.io/osism/osism:latest "sleep infinity" osismclient About a minute ago Up About a minute\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"When the manager service is healthy, the inventory and the fact cache\nmust be rebuilt."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"osism reconciler sync\nosism apply facts\n"})}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var t=s(96540);const i={},a=t.createContext(i);function o(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ebcea0bb.ed4e92bb.js b/assets/js/ebcea0bb.ed4e92bb.js new file mode 100644 index 0000000000..e265d9dca4 --- /dev/null +++ b/assets/js/ebcea0bb.ed4e92bb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1093],{45431:e=>{e.exports=JSON.parse('{"title":"Monitoring","slug":"/category/monitoring","permalink":"/docs/category/monitoring","navigation":{"previous":{"title":"\\"Levels of consensus\\"","permalink":"/docs/operating-scs/components/status-page/docs/levels_of_consensus"},"next":{"title":"Overview","permalink":"/docs/operating-scs/components/monitoring/docs/overview"}}}')}}]); \ No newline at end of file diff --git a/assets/js/ecbad217.b83bfb92.js b/assets/js/ecbad217.b83bfb92.js new file mode 100644 index 0000000000..6e310736ff --- /dev/null +++ b/assets/js/ecbad217.b83bfb92.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6454],{94773:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>u});var s=r(74848),t=r(28453),a=r(11470),i=r(19365);const o={sidebar_label:"Manager",sidebar_position:10},l="Manager",c={id:"iaas/guides/upgrade-guide/manager",title:"Manager",description:"Always read the release notes first to learn what has changed and what",source:"@site/docs/02-iaas/guides/upgrade-guide/manager.mdx",sourceDirName:"02-iaas/guides/upgrade-guide",slug:"/iaas/guides/upgrade-guide/manager",permalink:"/docs/iaas/guides/upgrade-guide/manager",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/manager.mdx",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Manager",sidebar_position:10},sidebar:"docs",previous:{title:"Upgrade Guide",permalink:"/docs/iaas/guides/upgrade-guide/"},next:{title:"Network",permalink:"/docs/iaas/guides/upgrade-guide/network"}},d={},u=[];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"manager",children:"Manager"}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["Always read the ",(0,s.jsx)(n.a,{href:"https://osism.tech/docs/release-notes/",children:"release notes"})," first to learn what has changed and what\nadjustments are necessary. Read the release notes even if you are only updating from e.g. 7.0.2 to 7.0.5."]})}),"\n",(0,s.jsx)(n.p,{children:"The update of a manager service with a stable release of OSISM is described here.\nIn the example, OSISM release 7.0.5 is used."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Change the OSISM release in the configuration repository."}),"\n",(0,s.jsx)(n.p,{children:"1.1. Set the new OSISM version in the configuration repository."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'MANAGER_VERSION=7.0.5\nsed -i -e "s/manager_version: .*/manager_version: ${MANAGER_VERSION}/g" environments/manager/configuration.yml\n'})}),"\n",(0,s.jsxs)(n.p,{children:["1.2. If ",(0,s.jsx)(n.code,{children:"openstack_version"})," or ",(0,s.jsx)(n.code,{children:"ceph_version"})," are set in ",(0,s.jsx)(n.code,{children:"environments/manager/configuration.yml"}),"\n(or anywhere else), they must be removed. If these are set, the stable release is not used for\nthese components."]}),"\n",(0,s.jsx)(n.p,{children:"1.3. Sync the image versions and files in the configuration repository."}),"\n",(0,s.jsxs)(a.A,{children:[(0,s.jsx)(i.A,{value:"osism-7",label:"OSISM >= 7.0.0",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"make sync\n"})})}),(0,s.jsxs)(i.A,{value:"osism-6",label:"OSISM < 7.0.0",children:[(0,s.jsxs)(n.p,{children:["If Gilt is not installed via the ",(0,s.jsx)(n.code,{children:"requirements.txt"})," of the manager environment it is\nimportant to use a version smaller v2. The v2 of Gilt is not yet usable."]}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"gilt overlay # you have to do this 2x, this is not a copy & paste error\ngilt overlay\n"})}),(0,s.jsxs)(n.p,{children:["Optionally, this is normally not necessary, it is possible to reference a specific tag of the\n",(0,s.jsx)(n.a,{href:"https://github.com/osism/cfg-generics",children:"osism/cfg-generics"})," repository. To do this, first\ncheck which version of osism/cfg-generics is used in a particular release. The version is\ndefined in ",(0,s.jsx)(n.code,{children:"generics_version"})," in the ",(0,s.jsx)(n.code,{children:"base.yml"})," file in the ",(0,s.jsx)(n.code,{children:"osism/release"})," repository. For OSISM 6.0.0,\nfor example, this is version ",(0,s.jsx)(n.a,{href:"https://github.com/osism/release/blob/main/6.0.0/base.yml#L6",children:"v0.20230919.0"}),".\nThis version is then added to the file ",(0,s.jsx)(n.code,{children:"gilt.yml"})," in the configuration repository instead of\n",(0,s.jsx)(n.code,{children:"main"})," at ",(0,s.jsx)(n.code,{children:"version"}),". This change must be made again after each execution of ",(0,s.jsx)(n.code,{children:"gilt overlay"})," as\nit is overwritten by the call of ",(0,s.jsx)(n.code,{children:"gilt overlay"}),". This cannot be realized differently in the\ncurrent implementation of ",(0,s.jsx)(n.a,{href:"https://github.com/retr0h/gilt",children:"Gilt"}),"."]})]})]}),"\n",(0,s.jsx)(n.p,{children:"1.4. Commit and push all changes in the configuration repository. Since everyone here has their own\nworkflows for changes to the configuration repository, only a generic example for Git."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'git commit -a -s -m "manager: use OSISM version 7.0.5"\ngit push\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Update the configuration repository on the manager node."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply configuration\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Update the manager service on the manager node."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism update manager\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If Ansible Vault was used to encrypt ",(0,s.jsx)(n.code,{children:"environments/manager/secrets.yml"}),", the parameter\n",(0,s.jsx)(n.code,{children:"--ask-vault-pass"})," is also appended. From OSISM >= 7.0.5 this is no longer necessary."]}),"\n",(0,s.jsxs)(n.li,{children:["If ",(0,s.jsx)(n.code,{children:"osism update manager"})," does not work yet, use ",(0,s.jsx)(n.code,{children:"osism-update-manager"})," instead."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Refresh the facts cache."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply facts\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["If Traefik is used on the manager node (",(0,s.jsx)(n.code,{children:"traefik_enable: true"})," in ",(0,s.jsx)(n.code,{children:"environments/infrastructure/configuration.yml"}),")\nthen Traefik should also be upgraded."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism apply traefik\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Finally, the Ansible vault password must be made known again."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"osism set vault password\n"})}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},19365:(e,n,r)=>{r.d(n,{A:()=>i});r(96540);var s=r(18215);const t={tabItem:"tabItem_Ymn6"};var a=r(74848);function i(e){let{children:n,hidden:r,className:i}=e;return(0,a.jsx)("div",{role:"tabpanel",className:(0,s.A)(t.tabItem,i),hidden:r,children:n})}},11470:(e,n,r)=>{r.d(n,{A:()=>w});var s=r(96540),t=r(18215),a=r(23104),i=r(56347),o=r(205),l=r(57485),c=r(31682),d=r(89466);function u(e){return s.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:n,children:r}=e;return(0,s.useMemo)((()=>{const e=n??function(e){return u(e).map((e=>{let{props:{value:n,label:r,attributes:s,default:t}}=e;return{value:n,label:r,attributes:s,default:t}}))}(r);return function(e){const n=(0,c.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,r])}function p(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:r}=e;const t=(0,i.W6)(),a=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,l.aZ)(a),(0,s.useCallback)((e=>{if(!a)return;const n=new URLSearchParams(t.location.search);n.set(a,e),t.replace({...t.location,search:n.toString()})}),[a,t])]}function f(e){const{defaultValue:n,queryString:r=!1,groupId:t}=e,a=h(e),[i,l]=(0,s.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!p({value:n,tabValues:r}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const s=r.find((e=>e.default))??r[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:a}))),[c,u]=m({queryString:r,groupId:t}),[f,g]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,a]=(0,d.Dv)(r);return[t,(0,s.useCallback)((e=>{r&&a.set(e)}),[r,a])]}({groupId:t}),x=(()=>{const e=c??f;return p({value:e,tabValues:a})?e:null})();(0,o.A)((()=>{x&&l(x)}),[x]);return{selectedValue:i,selectValue:(0,s.useCallback)((e=>{if(!p({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),g(e)}),[u,g,a]),tabValues:a}}var g=r(92303);const x={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=r(74848);function v(e){let{className:n,block:r,selectedValue:s,selectValue:i,tabValues:o}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,a.a_)(),d=e=>{const n=e.currentTarget,r=l.indexOf(n),t=o[r].value;t!==s&&(c(n),i(t))},u=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const r=l.indexOf(e.currentTarget)+1;n=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(e.currentTarget)-1;n=l[r]??l[l.length-1];break}}n?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":r},n),children:o.map((e=>{let{value:n,label:r,attributes:a}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,ref:e=>l.push(e),onKeyDown:u,onClick:d,...a,className:(0,t.A)("tabs__item",x.tabItem,a?.className,{"tabs__item--active":s===n}),children:r??n},n)}))})}function j(e){let{lazy:n,children:r,selectedValue:t}=e;const a=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=a.find((e=>e.props.value===t));return e?(0,s.cloneElement)(e,{className:"margin-top--md"}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:a.map(((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function y(e){const n=f(e);return(0,b.jsxs)("div",{className:(0,t.A)("tabs-container",x.tabList),children:[(0,b.jsx)(v,{...e,...n}),(0,b.jsx)(j,{...e,...n})]})}function w(e){const n=(0,g.A)();return(0,b.jsx)(y,{...e,children:u(e.children)},String(n))}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>o});var s=r(96540);const t={},a=s.createContext(t);function i(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/edc931f8.1792b3a0.js b/assets/js/edc931f8.1792b3a0.js new file mode 100644 index 0000000000..cded1289d9 --- /dev/null +++ b/assets/js/edc931f8.1792b3a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2526],{27034:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>m});var o=n(74848),i=n(28453);const r={sidebar_position:1,title:"Overview"},s=void 0,c={id:"index",title:"Overview",description:"Welcome to our SCS Community",source:"@site/community/index.md",sourceDirName:".",slug:"/",permalink:"/community/",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1,title:"Overview"},sidebar:"community",next:{title:"Mission Statement",permalink:"/community/mission-statement"}},a={},m=[{value:"Welcome to our SCS Community",id:"welcome-to-our-scs-community",level:2}];function u(e){const t={a:"a",h2:"h2",p:"p",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h2,{id:"welcome-to-our-scs-community",children:"Welcome to our SCS Community"}),"\n",(0,o.jsx)(t.p,{children:"Sovereign Cloud Stack is an open community of providers and end-users joining forces in defining, implementing and operating a fully open, federated, compatible platform. We actively encourage you to contribute either code, documentation or issues and to participate in the various discussions happening on GitHub or during our various meetings."}),"\n",(0,o.jsxs)(t.p,{children:["We have created an open community space on the ",(0,o.jsx)(t.a,{href:"https://matrix.to/#/#scs-community:matrix.org",children:"Matrix network"}),". Feel free to join the several channels and start interacting with the community. A good starting point is entering the ",(0,o.jsx)(t.a,{href:"https://matrix.to/#/#scs-general:matrix.org",children:"General & Announcements"})," and the ",(0,o.jsx)(t.a,{href:"https://matrix.to/#/#scs-tech:matrix.org",children:"Tech channel"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["Check out our ",(0,o.jsx)(t.a,{href:"/community/collaboration",children:"Community Calendar"})," to know when our several Teams and SIGs meet."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var o=n(96540);const i={},r=o.createContext(i);function s(e){const t=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eea6a18c.28e397b4.js b/assets/js/eea6a18c.28e397b4.js new file mode 100644 index 0000000000..cedc2e79e0 --- /dev/null +++ b/assets/js/eea6a18c.28e397b4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9245],{62222:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>o,frontMatter:()=>d,metadata:()=>l,toc:()=>c});var n=s(74848),i=s(28453);const d={title:"Status Page create decision",type:"Decision Record",status:"Draft",track:"Ops",enhances:"status-page-comparison.md"},r=void 0,l={id:"scs-0400-v1-status-page-create-decision",title:"Status Page create decision",description:"Introduction",source:"@site/standards/scs-0400-v1-status-page-create-decision.md",sourceDirName:".",slug:"/scs-0400-v1-status-page-create-decision",permalink:"/standards/scs-0400-v1-status-page-create-decision",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Status Page create decision",type:"Decision Record",status:"Draft",track:"Ops",enhances:"status-page-comparison.md"},sidebar:"standards",previous:{title:"scs-0400: Status Page create decision",permalink:"/standards/ops/scs-0400"},next:{title:"scs-0401: Status page reference implementation decision",permalink:"/standards/ops/scs-0401"}},a={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Existing Applications",id:"existing-applications",level:2},{value:"Decision",id:"decision",level:2},{value:"Status Page Requirements",id:"status-page-requirements",level:2},{value:"Comparison matrix",id:"comparison-matrix",level:3}];function h(e){const t={a:"a",h2:"h2",h3:"h3",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsxs)(t.p,{children:['Creating and maintaining IT infrastructure is a complex task.\nAny kind of consumer (e.g. operators, cutsomers) can\nbe supported by presenting the status of all possible parts of the\nserving infrastructure. Whether a service is not reachable or\nthe used hardware is having an outage we want the consumers to be easily informed\nby using a "Status Page" application. The need for a "Status Page"\ncame up early in the SCS project and the requirements a "Status Page" application\nhas to fulfill were defined and written down on 2022-06-02 as a\n',(0,n.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/issues/issues/123",children:"MVP-0 epic"}),'.\nThe upcoming research on existing solutions came to the conclusion that we want to\ncreate a new "Status Page" application.']}),"\n",(0,n.jsx)(t.h2,{id:"existing-applications",children:"Existing Applications"}),"\n",(0,n.jsx)(t.p,{children:'Since we want to use as much as possible from existing projects and contribute to\nupstream projects to support the community with our efforts, it was a hard\ndecision to create a new "Status Page" application.'}),"\n",(0,n.jsxs)(t.p,{children:["Before the decision was made some existing and known applications were tested\nand analyzed if they would fit to our use case. An overview of this\ncomparison can be found ",(0,n.jsx)(t.a,{href:"#comparison-matrix",children:"below in this document"}),"\nWhile this is not a complete list of all existing applications it did\ncapture the most promising ones from the ",(0,n.jsx)(t.a,{href:"https://github.com/ivbeg/awesome-status-pages",children:"awesome-status-page list"}),"\nin order to have base to decide upon."]}),"\n",(0,n.jsx)(t.p,{children:"Work on an existing project only makes sense if the project is healthy OR can be\nbrought into a healthy state. If upstream does not accept patches a fork is needed.\nThe fork however only makes sense if the underlying technology is worth to be maintained.\nThe possible candidates did not fulfill these conditions - in the cases where\ncontribution seemed possible the candidates looked abandoned and long existing CVEs weren't\nworked on."}),"\n",(0,n.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,n.jsx)(t.p,{children:"Based on the results the decision was made, that the effort is likely to be the same if\nwe pick up an existing project and try to get it in shape for our use case. It was not\n100% clear if this would even be possible or if we still would have to maintain our\nown additional patches."}),"\n",(0,n.jsx)(t.p,{children:"So there will be a reference implementation that will match the requirements we have.\nIn addition there will be an architecture design documentation. So if the reference\nimplementation may not fit to you, it will be possible to create your own application."}),"\n",(0,n.jsx)(t.h2,{id:"status-page-requirements",children:"Status Page Requirements"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"The status page application should be simplistic in software design and should not depend on a large\nvariety of services"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["simplistic, yet existing user management for write access (oauth? OIDC?)","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Simple RBAC (role based access control) is nice to have"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["support that components are only visible to a subset of users","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"implies that there is a role that is read-only"}),"\n",(0,n.jsx)(t.li,{children:"On-Prem use case might be handled by having an authenticating reverse proxy in front"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"The status page applicaton should allow for simple and easy theming"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Page = (Possibly simple) Web-UI"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"As a CSP, I want to have a status page that allows to"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"define locations and similar grouping (AZs, ...)"}),"\n",(0,n.jsx)(t.li,{children:"define components globally or per location\n_to ease maintenance I want to define per component where it belongs so that I only have\nto define a component once, but have it visible in several locations\n_ status per component should be allowed to be toggleable per location or overall * a component should allow for several statuses, that are defined by me"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Status, Status Items should be easy to extract"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"REST(less)-API to interact with\n_API should be versioned\n_ this allows for embedding status information in other applications, such as cloud\ndashboards\n_this also allows for submitting items from other tooling\n_ incoming webhooks (https POST) should be supported (e.g. for air-gapped setups) \u2013\ni.e. submitting a health beacon every x seconds\n_web-UI wanted for posting updates as well\n_ Token based Auth"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Configuration should be manageable with YAML files (imho this annoys me using Uptime Kuma)"}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"As a consumer of the status page, I'd like to subscribe to events on the status page via e-mail"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"for everything"}),"\n",(0,n.jsx)(t.li,{children:"for specific components"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"As a consumer of the status page, I'd like to subscribe to an RSS or atom feed"}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Allow for the ability to trigger webhooks upon certain events (to submit info to other systems via\nwebhooks, e.g. chat/messenger)"}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"As a CSP Operator, I want to be able to flag a component with a new status quick and easy"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"to minimize the probability of making errors, updating the status of a component should not be\nhard brainwork"}),"\n",(0,n.jsx)(t.li,{children:"updates can be both machine generated status changes (triggered e.g. by health monitoring)\nas well as updates from human operators"}),"\n",(0,n.jsx)(t.li,{children:"updating a status should allow the CSP Operator to do that in a fashion that either pushes\ninfos to the subscribers or just updates the status on the status page"}),"\n",(0,n.jsx)(t.li,{children:"updating the status can either be toggling the status of the component or can be\naccompanied by additional textual information."}),"\n",(0,n.jsx)(t.li,{children:"When updating a status with textual information the status page application should make it\neasy for me as the CSP Operator to do in a way that if different people submit infos over time\nthey are presented in a similar way (eg. the status page application should guide so that the\nresulting infos are presented in a identical way. Example: when updating infos of an incident\nover time the timeline should automatically be sorted by the status page application so that it\ndoes not depend on the Operator whether the newest info is on top or at the bottom. This is\ntypical thing that varies if several people update items"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Allow for templates for certain types of incidents"}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"User-specific monitoring (how are MY instances, load-balancers, ... doing?) is OUT OF SCOPE for\nthe status page."}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"But having it would be useful and if we have something like this, link it from the status page\n(and a link to horizon might be the default)"}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"Sidenote: External hosting is desired to avoid status page going down with infra"}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"With those requirements in mind the projects that initially were found, were evaluated."}),"\n",(0,n.jsx)(t.h3,{id:"comparison-matrix",children:"Comparison matrix"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{}),(0,n.jsx)(t.th,{children:"CachetHQ"}),(0,n.jsx)(t.th,{children:"ClearStatus"}),(0,n.jsx)(t.th,{children:"ciao"}),(0,n.jsx)(t.th,{children:"cState"}),(0,n.jsx)(t.th,{children:"Gatus"}),(0,n.jsx)(t.th,{children:"Issue Status"}),(0,n.jsx)(t.th,{children:"statusfy"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"CSP VIEW"}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"small dependency tree"}),(0,n.jsx)(t.td,{children:"\u274c Composer"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c ruby gems"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2047 helm chart"}),(0,n.jsx)(t.td,{children:"\u274c npm/github/zapier"}),(0,n.jsx)(t.td,{children:"\u274c npm dependencies very huge"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"easy themable"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"grouping (by location...)"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2047"}),(0,n.jsx)(t.td,{children:"\u2705"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"components definition ..."}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"... local or global"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2047"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"... easy flagging with new status"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2047"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"... push notification on update"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2047"}),(0,n.jsx)(t.td,{children:"\u2705"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"... updates with additional information"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2047"}),(0,n.jsx)(t.td,{children:"\u2047"}),(0,n.jsx)(t.td,{children:"\u2047"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"API Support ..."}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c read only"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705 GitHub API"}),(0,n.jsx)(t.td,{children:"\u274c"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"... versioned"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2047"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"... web ui for posting updates"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"... token based auth"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705 Auth managed by git provider"}),(0,n.jsx)(t.td,{children:"\u274c only basic auth"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c BUT OIDC!"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"manageable configuration"}),(0,n.jsx)(t.td,{children:"\u274c config depends on web server and initial install relies on env variables"}),(0,n.jsx)(t.td,{children:"\u274c based on hugo CMS"}),(0,n.jsx)(t.td,{children:"\u274c config by env variables"}),(0,n.jsx)(t.td,{children:"\u274c based on hugo CMS"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c no real config needed"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"templating support"}),(0,n.jsx)(t.td,{children:"\u2705 twig"}),(0,n.jsx)(t.td,{children:"\u274c Hugo itself uses GO template libraries"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"CUSTOMER VIEW"}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{}),(0,n.jsx)(t.td,{})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"subscription support ..."}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c only by git provider"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"... send by eMail"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"watchdog for status page support"}),(0,n.jsx)(t.td,{children:"\u2047"}),(0,n.jsx)(t.td,{children:"\u2047"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2047"}),(0,n.jsx)(t.td,{children:"\u274c"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"trigger webhook support"}),(0,n.jsx)(t.td,{children:"\u274c needs cachet-monitor"}),(0,n.jsx)(t.td,{children:"\u2047"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2047"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2047"}),(0,n.jsx)(t.td,{children:"\u274c"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"additional infos"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"basically a theme for hugo cms, depends on netlify cms"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"basically a theme for hugo cms, depends on netlify cms"}),(0,n.jsx)(t.td,{children:"-"}),(0,n.jsx)(t.td,{children:"It's highly optimized for github pages"}),(0,n.jsx)(t.td,{children:"SPA created with netlify"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"hidden components"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"user management"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705 by OIDC"}),(0,n.jsx)(t.td,{children:"\u2047 through github?"}),(0,n.jsx)(t.td,{children:"\u274c"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"different output format on notification"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"external hosting"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c looks like you are limited to github"}),(0,n.jsx)(t.td,{children:"\u2705"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"project healthy"}),(0,n.jsx)(t.td,{children:"\u274c last commit 17 months"}),(0,n.jsx)(t.td,{children:"\u274c last commit 3 years"}),(0,n.jsx)(t.td,{children:"\u274c last commit 5 months"}),(0,n.jsx)(t.td,{children:"\u2705 last commit 2 months"}),(0,n.jsx)(t.td,{children:"\u2705 recent activities"}),(0,n.jsx)(t.td,{children:"\u2705 recent activities"}),(0,n.jsx)(t.td,{children:"\u274c archived and abondend by the owner"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"documentation"}),(0,n.jsx)(t.td,{children:"\u2705 API \u274c User Documentation"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2047u"}),(0,n.jsx)(t.td,{children:"\u274c not reachable anymore"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"git based"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u274c"}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2047 a netlify based installation is able to communicate with github"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"project page"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"https://cachethq.io/",children:"project page"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"https://github.com/weeblrpress/clearstatus",children:"project page"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"https://www.brotandgames.com/ciao/",children:"project page"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"https://cstate.netlify.app/",children:"project page"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"https://gatus.io/",children:"project page"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"https://github.com/tadhglewis/issue-status",children:"project page"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"https://marquez.co/statusfy",children:"project page"})})]})]})]})]})}function o(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>l});var n=s(96540);const i={},d=n.createContext(i);function r(e){const t=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),n.createElement(d.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef682180.25ac95f0.js b/assets/js/ef682180.25ac95f0.js new file mode 100644 index 0000000000..71cf291daa --- /dev/null +++ b/assets/js/ef682180.25ac95f0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7731],{32534:(s,e,t)=>{t.r(e),t.d(e,{assets:()=>o,contentTitle:()=>d,default:()=>l,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var r=t(74848),n=t(28453);const a={},d="scs-0215: Robustness features for Kubernetes clusters",c={id:"kaas/scs-0215",title:"scs-0215: Robustness features for Kubernetes clusters",description:"| Version | Type | State | stabilized | deprecated |",source:"@site/standards/kaas/scs-0215.md",sourceDirName:"kaas",slug:"/kaas/scs-0215",permalink:"/standards/kaas/scs-0215",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Kubernetes Node Distribution and Availability",permalink:"/standards/scs-0214-v1-k8s-node-distribution"},next:{title:"Robustness features for Kubernetes clusters",permalink:"/standards/scs-0215-v1-robustness-features"}},o={},i=[];function u(s){const e={a:"a",h1:"h1",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.R)(),...s.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.h1,{id:"scs-0215-robustness-features-for-kubernetes-clusters",children:"scs-0215: Robustness features for Kubernetes clusters"}),"\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Version"}),(0,r.jsx)(e.th,{children:"Type"}),(0,r.jsx)(e.th,{children:"State"}),(0,r.jsx)(e.th,{children:"stabilized"}),(0,r.jsx)(e.th,{children:"deprecated"})]})}),(0,r.jsx)(e.tbody,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/standards/scs-0215-v1-robustness-features",children:"scs-0215-v1"})}),(0,r.jsx)(e.td,{children:"Standard"}),(0,r.jsx)(e.td,{children:"Draft"}),(0,r.jsx)(e.td,{children:"-"}),(0,r.jsx)(e.td,{children:"-"})]})})]})]})}function l(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,r.jsx)(e,{...s,children:(0,r.jsx)(u,{...s})}):u(s)}},28453:(s,e,t)=>{t.d(e,{R:()=>d,x:()=>c});var r=t(96540);const n={},a=r.createContext(n);function d(s){const e=r.useContext(a);return r.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function c(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:d(s.components),r.createElement(a.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef9d238d.72cad001.js b/assets/js/ef9d238d.72cad001.js new file mode 100644 index 0000000000..9f0a4b775d --- /dev/null +++ b/assets/js/ef9d238d.72cad001.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9864],{9221:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>a,metadata:()=>u,toc:()=>d});var r=t(74848),s=t(28453),l=t(11470),i=t(19365);const a={},o="Installation",u={id:"contribute/local-docusaurus-development-guide",title:"Installation",description:"This Guide shows you how to setup docusaurus on your local machine to run this docs in your local development enviroment.",source:"@site/community/contribute/local-docusaurus-development-guide.mdx",sourceDirName:"contribute",slug:"/contribute/local-docusaurus-development-guide",permalink:"/community/contribute/local-docusaurus-development-guide",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"community",previous:{title:"Linting Guide",permalink:"/community/contribute/linting-guide"},next:{title:"Styleguide",permalink:"/community/contribute/styleguide"}},c={},d=[{value:"Requirements",id:"requirements",level:2},{value:"Installation Guide",id:"installation-guide",level:2},{value:"Step 1 \u2013 Installing Node.js via nvm",id:"step-1--installing-nodejs-via-nvm",level:3},{value:"Step 2 \u2013\xa0Cloning the repository",id:"step-2-cloning-the-repository",level:3},{value:"Step 3 \u2013 Installing dependencies",id:"step-3--installing-dependencies",level:3},{value:"Step 4 \u2013 Starting the development server",id:"step-4--starting-the-development-server",level:3}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"installation",children:"Installation"}),"\n",(0,r.jsx)(n.p,{children:"This Guide shows you how to setup docusaurus on your local machine to run this docs in your local development enviroment."}),"\n",(0,r.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"git"}),"\n",(0,r.jsx)(n.li,{children:"Node.js v16"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"installation-guide",children:"Installation Guide"}),"\n",(0,r.jsx)(n.h3,{id:"step-1--installing-nodejs-via-nvm",children:"Step 1 \u2013 Installing Node.js via nvm"}),"\n",(0,r.jsx)(n.p,{children:"It is recommended to install Node.js via nvm \u2013 a node version manager \u2013 to have the possibility to switch between different node.js versions."}),"\n",(0,r.jsxs)(l.A,{groupId:"operating-systems",children:[(0,r.jsxs)(i.A,{value:"mac",label:"macOS",children:[(0,r.jsx)(n.p,{children:"You must have macOS desktop access with administrator privileges."}),(0,r.jsxs)(n.p,{children:["Login to the macOS desktop system and ",(0,r.jsx)(n.a,{href:"https://brew.sh/",children:"install Homebrew"})," on your system (if not already installed)."]}),(0,r.jsx)(n.p,{children:"Install nvm via homebrew:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"brew install nvm\n"})})]}),(0,r.jsx)(i.A,{value:"linux",label:"Linux",children:(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"https://github.com/nvm-sh/nvm#installing-and-updating",children:"this"})," installation guide on GitHub by nvm-sh for installing nvm."]})}),(0,r.jsx)(i.A,{value:"win",label:"Windows",children:(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/coreybutler/nvm-windows",children:"NVM for Windows"}),"\nruns in an Admin shell. You'll need to start powershell or Command Prompt as Administrator to use nvm-windows. Install NVM for Windows with an Installer provided by nvm-sh on their ",(0,r.jsx)(n.a,{href:"https://github.com/coreybutler/nvm-windows/releases",children:"release page"}),"."]})})]}),"\n",(0,r.jsx)(n.p,{children:"Once installed you can check the available versions with"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"nvm list\n"})}),"\n",(0,r.jsx)(n.p,{children:"If you have no other projects, where you need a different version, it is recommended to install the latest stable LTS version of node."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-console",children:"nvm install lts\n"})}),"\n",(0,r.jsx)(n.p,{children:"nvm has now installed the latest node.js version with its package manager npm. Check if the installation has been successfull by checking it:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-console",children:"node --version\n"})}),"\n",(0,r.jsx)(n.h3,{id:"step-2-cloning-the-repository",children:"Step 2 \u2013\xa0Cloning the repository"}),"\n",(0,r.jsxs)(n.p,{children:["Clone the ",(0,r.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/docs",children:"docs"})," repository via your favourite method:"]}),"\n",(0,r.jsxs)(l.A,{groupId:"cloning-",children:[(0,r.jsx)(i.A,{value:"https",label:"HTTPS",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-console",metastring:'title="HTTPS"',children:"git clone https://github.com/SovereignCloudStack/docs.git\n"})})}),(0,r.jsx)(i.A,{value:"ssh",label:"SSH",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-console",metastring:'title="SSH"',children:"git clone git@github.com:SovereignCloudStack/docs.git\n"})})})]}),"\n",(0,r.jsx)(n.h3,{id:"step-3--installing-dependencies",children:"Step 3 \u2013 Installing dependencies"}),"\n",(0,r.jsxs)(n.p,{children:["Change your working directory within your terminal to the root of the cloned repository ",(0,r.jsx)(n.code,{children:"/docs"})," and install all dependencies:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-console",children:"npm install\n"})}),"\n",(0,r.jsx)(n.h3,{id:"step-4--starting-the-development-server",children:"Step 4 \u2013 Starting the development server"}),"\n",(0,r.jsx)(n.p,{children:"You can now run the local development server from your terminal:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-console",children:"npm start\n"})}),"\n",(0,r.jsx)(n.p,{children:"Once the server is up and running, your terminal will show you the local URL which you can open with your browser to see the page."})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},19365:(e,n,t)=>{t.d(n,{A:()=>i});t(96540);var r=t(18215);const s={tabItem:"tabItem_Ymn6"};var l=t(74848);function i(e){let{children:n,hidden:t,className:i}=e;return(0,l.jsx)("div",{role:"tabpanel",className:(0,r.A)(s.tabItem,i),hidden:t,children:n})}},11470:(e,n,t)=>{t.d(n,{A:()=>w});var r=t(96540),s=t(18215),l=t(23104),i=t(56347),a=t(205),o=t(57485),u=t(31682),c=t(89466);function d(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??function(e){return d(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:s}}=e;return{value:n,label:t,attributes:r,default:s}}))}(t);return function(e){const n=(0,u.X)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function p(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:t}=e;const s=(0,i.W6)(),l=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,o.aZ)(l),(0,r.useCallback)((e=>{if(!l)return;const n=new URLSearchParams(s.location.search);n.set(l,e),s.replace({...s.location,search:n.toString()})}),[l,s])]}function v(e){const{defaultValue:n,queryString:t=!1,groupId:s}=e,l=h(e),[i,o]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!p({value:n,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:l}))),[u,d]=m({queryString:t,groupId:s}),[v,g]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[s,l]=(0,c.Dv)(t);return[s,(0,r.useCallback)((e=>{t&&l.set(e)}),[t,l])]}({groupId:s}),b=(()=>{const e=u??v;return p({value:e,tabValues:l})?e:null})();(0,a.A)((()=>{b&&o(b)}),[b]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!p({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);o(e),d(e),g(e)}),[d,g,l]),tabValues:l}}var g=t(92303);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var f=t(74848);function x(e){let{className:n,block:t,selectedValue:r,selectValue:i,tabValues:a}=e;const o=[],{blockElementScrollPositionUntilNextRender:u}=(0,l.a_)(),c=e=>{const n=e.currentTarget,t=o.indexOf(n),s=a[t].value;s!==r&&(u(n),i(s))},d=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const t=o.indexOf(e.currentTarget)+1;n=o[t]??o[0];break}case"ArrowLeft":{const t=o.indexOf(e.currentTarget)-1;n=o[t]??o[o.length-1];break}}n?.focus()};return(0,f.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.A)("tabs",{"tabs--block":t},n),children:a.map((e=>{let{value:n,label:t,attributes:l}=e;return(0,f.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>o.push(e),onKeyDown:d,onClick:c,...l,className:(0,s.A)("tabs__item",b.tabItem,l?.className,{"tabs__item--active":r===n}),children:t??n},n)}))})}function j(e){let{lazy:n,children:t,selectedValue:s}=e;const l=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=l.find((e=>e.props.value===s));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return(0,f.jsx)("div",{className:"margin-top--md",children:l.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==s})))})}function y(e){const n=v(e);return(0,f.jsxs)("div",{className:(0,s.A)("tabs-container",b.tabList),children:[(0,f.jsx)(x,{...e,...n}),(0,f.jsx)(j,{...e,...n})]})}function w(e){const n=(0,g.A)();return(0,f.jsx)(y,{...e,children:d(e.children)},String(n))}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var r=t(96540);const s={},l=r.createContext(s);function i(e){const n=r.useContext(l);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/efbcd183.416334ba.js b/assets/js/efbcd183.416334ba.js new file mode 100644 index 0000000000..9ba767599c --- /dev/null +++ b/assets/js/efbcd183.416334ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9093],{62334:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>l,metadata:()=>d,toc:()=>c});var n=s(74848),i=s(28453);const l={},r="SCS Compatible KaaS",d={id:"scs-compatible-kaas",title:"SCS Compatible KaaS",description:"Note that the state Stable is shown here if stabilized at is in the future, whereas Effective is shown here if stabilized at is in the past and deprecated at is unset or in the future.",source:"@site/standards/scs-compatible-kaas.md",sourceDirName:".",slug:"/scs-compatible-kaas",permalink:"/standards/scs-compatible-kaas",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"SCS Compatible IaaS",permalink:"/standards/scs-compatible-iaas"},next:{title:"Overview",permalink:"/standards/standards/overview"}},a={},c=[];function o(t){const e={a:"a",em:"em",h1:"h1",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"scs-compatible-kaas",children:"SCS Compatible KaaS"}),"\n",(0,n.jsxs)(e.p,{children:["Note that the state ",(0,n.jsx)(e.em,{children:"Stable"})," is shown here if ",(0,n.jsx)(e.em,{children:"stabilized at"})," is in the future, whereas ",(0,n.jsx)(e.em,{children:"Effective"})," is shown here if ",(0,n.jsx)(e.em,{children:"stabilized at"})," is in the past and ",(0,n.jsx)(e.em,{children:"deprecated at"})," is unset or in the future."]}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"Scope versions ->"}),(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"v1"}),(0,n.jsx)(e.th,{style:{textAlign:"left"},children:"v2"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"State"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"Draft"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"Draft"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"Stabilized at"}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"Deprecated at"}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.strong,{children:"Standards"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"}})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"CNCF Kubernetes conformance"}),(0,n.jsx)(e.td,{style:{textAlign:"left"}}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"https://github.com/cncf/k8s-conformance/tree/master",children:"\u2713"})})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"scs-0210: Kubernetes version policy"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"/standards/scs-0210-v2-k8s-version-policy",children:"v2"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"/standards/scs-0210-v2-k8s-version-policy",children:"v2"})})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{style:{textAlign:"left"},children:"scs-0214: Kubernetes node distribution and availability"}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"/standards/scs-0214-v1-k8s-node-distribution",children:"v1"})}),(0,n.jsx)(e.td,{style:{textAlign:"left"},children:(0,n.jsx)(e.a,{href:"/standards/scs-0214-v1-k8s-node-distribution",children:"v1"})})]})]})]})]})}function h(t={}){const{wrapper:e}={...(0,i.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(o,{...t})}):o(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>r,x:()=>d});var n=s(96540);const i={},l=n.createContext(i);function r(t){const e=n.useContext(l);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function d(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:r(t.components),n.createElement(l.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/f0b55dfe.9e8e6e39.js b/assets/js/f0b55dfe.9e8e6e39.js new file mode 100644 index 0000000000..fa4afe9f38 --- /dev/null +++ b/assets/js/f0b55dfe.9e8e6e39.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6370],{22819:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>r,toc:()=>c});var s=t(74848),n=t(28453);const l={sidebar_label:"Style Guide"},o="Style Guide",r={id:"iaas/guides/other-guides/style-guide",title:"Style Guide",description:"Ansible",source:"@site/docs/02-iaas/guides/other-guides/style-guide.md",sourceDirName:"02-iaas/guides/other-guides",slug:"/iaas/guides/other-guides/style-guide",permalink:"/docs/iaas/guides/other-guides/style-guide",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/other-guides/style-guide.md",tags:[],version:"current",frontMatter:{sidebar_label:"Style Guide"},sidebar:"docs",previous:{title:"Zuul CI",permalink:"/docs/iaas/guides/other-guides/developer-guide/zuul"},next:{title:"Testbed Guide",permalink:"/docs/iaas/guides/other-guides/testbed"}},d={},c=[{value:"Ansible",id:"ansible",level:2},{value:"Task names",id:"task-names",level:3},{value:"<code>become</code> directive",id:"become-directive",level:3},{value:"<code>when</code> directive",id:"when-directive",level:3},{value:"Lists as defaults",id:"lists-as-defaults",level:3},{value:"Containerfiles",id:"containerfiles",level:2},{value:"Commit messages",id:"commit-messages",level:2},{value:"Python",id:"python",level:2},{value:"Installation",id:"installation",level:3},{value:"Formatting a Single File",id:"formatting-a-single-file",level:3},{value:"Formatting Multiple Files and/or directories",id:"formatting-multiple-files-andor-directories",level:3},{value:"Formatting an Entire Project",id:"formatting-an-entire-project",level:3},{value:"Check Mode (Dry Run)",id:"check-mode-dry-run",level:3},{value:"Excluding Files or Directories",id:"excluding-files-or-directories",level:3},{value:"Integration with Code Editors",id:"integration-with-code-editors",level:3},{value:"Example of failed python-black Zuul job",id:"example-of-failed-python-black-zuul-job",level:3}];function a(e){const i={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,n.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h1,{id:"style-guide",children:"Style Guide"}),"\n",(0,s.jsx)(i.h2,{id:"ansible",children:"Ansible"}),"\n",(0,s.jsxs)(i.p,{children:["We implement all the default rules of Ansible Lint. All default rules can be found in the\n",(0,s.jsx)(i.a,{href:"https://ansible.readthedocs.io/projects/lint/rules/",children:"Ansible Lint documentation"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"task-names",children:"Task names"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Tasks must always have names. The only exception allowed is for forked playbooks."}),"\n",(0,s.jsx)(i.li,{children:"A name never starts with a small letter"}),"\n",(0,s.jsx)(i.li,{children:"Names are written in present tense"}),"\n",(0,s.jsx)(i.li,{children:"No punctuation is used in names"}),"\n"]}),"\n",(0,s.jsxs)(i.h3,{id:"become-directive",children:[(0,s.jsx)(i.code,{children:"become"})," directive"]}),"\n",(0,s.jsxs)(i.p,{children:["The ",(0,s.jsx)(i.code,{children:"become"})," directive is only set when needed and is always set explicitly for each task that needs it."]}),"\n",(0,s.jsx)(i.p,{children:"Blocks, roles, or playbooks are never executed in a privileged mode."}),"\n",(0,s.jsxs)(i.p,{children:["We always insert the ",(0,s.jsx)(i.code,{children:"become"})," directive between the name of a task and the task itself. This also applies\nto related directives like ",(0,s.jsx)(i.code,{children:"become_user"})," or ",(0,s.jsx)(i.code,{children:"become_flags"}),". This is for better visibility if a task is\nprivileged or not."]}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-yaml",children:'- name: Copy hddtemp configuration file\n become: true\n ansible.builtin.copy:\n src: "{{ ansible_os_family }}/hddtemp"\n dest: "{{ hddtemp_conf_file }}"\n owner: root\n group: root\n mode: 0644\n notify: Restart hddtemp service\n'})}),"\n",(0,s.jsxs)(i.h3,{id:"when-directive",children:[(0,s.jsx)(i.code,{children:"when"})," directive"]}),"\n",(0,s.jsxs)(i.p,{children:["If you need to use the ",(0,s.jsx)(i.code,{children:"when"})," directive add this at the end-section from the task where it is needed. This\nmakes the code easier to understand for others."]}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-yaml",children:'- name: "Archive existing {{ resolvconf_file }} file"\n become: true\n ansible.posix.synchronize:\n src: "/etc/resolv.conf"\n dest: "/etc/resolv.conf.{{ ansible_date_time.date }}"\n archive: true\n delegate_to: "{{ inventory_hostname }}"\n when: stat_resolvconf_file.stat.islnk is defined and not stat_resolvconf_file.stat.islnk\n'})}),"\n",(0,s.jsx)(i.h3,{id:"lists-as-defaults",children:"Lists as defaults"}),"\n",(0,s.jsx)(i.p,{children:"Defaults that provide a list are always defined as in the following example."}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"docker_hosts_defaults"})," sets the defaults in the role. Overriding is only possible with the ",(0,s.jsx)(i.code,{children:"defaults"})," repository."]}),"\n",(0,s.jsxs)(i.p,{children:["In the configuration repository, ",(0,s.jsx)(i.code,{children:"docker_hosts_extra"})," is then used to add additional items to the list."]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"docker_hosts"})," itself is never modified from the outside."]}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{className:"language-yaml",children:'docker_hosts_defaults:\n - "unix:///var/run/docker.sock"\ndocker_hosts_extra: []\ndocker_hosts: "{{ docker_hosts_defaults + docker_hosts_extra }}"\n'})}),"\n",(0,s.jsx)(i.h2,{id:"containerfiles",children:"Containerfiles"}),"\n",(0,s.jsx)(i.h2,{id:"commit-messages",children:"Commit messages"}),"\n",(0,s.jsx)(i.h2,{id:"python",children:"Python"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"https://github.com/psf/black",children:"Black"})," is a popular Python code formatter that automatically\nformats your code to adhere to a consistent style. We use it to automatically format the\nsyntax of Python. A job is running in the CI that checks, if Black has been applied. Therefore,\nformat the files with Black accordingly in advance."]}),"\n",(0,s.jsx)(i.h3,{id:"installation",children:"Installation"}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.code,{children:"pip install black"})}),"\n",(0,s.jsx)(i.h3,{id:"formatting-a-single-file",children:"Formatting a Single File"}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.code,{children:"black myfile.py"})}),"\n",(0,s.jsx)(i.h3,{id:"formatting-multiple-files-andor-directories",children:"Formatting Multiple Files and/or directories"}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.code,{children:"black file1.py file2.py dir/"})}),"\n",(0,s.jsx)(i.h3,{id:"formatting-an-entire-project",children:"Formatting an Entire Project"}),"\n",(0,s.jsx)(i.p,{children:"This command will format all Python files in the current directory and its subdirectories:"}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.code,{children:"black ."})}),"\n",(0,s.jsx)(i.h3,{id:"check-mode-dry-run",children:"Check Mode (Dry Run)"}),"\n",(0,s.jsxs)(i.p,{children:["Running Black with the ",(0,s.jsx)(i.code,{children:"--check"})," option performs a dry run and reports files that would be\nchanged without actually modifying them:"]}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.code,{children:"black --check myfile.py"})}),"\n",(0,s.jsx)(i.h3,{id:"excluding-files-or-directories",children:"Excluding Files or Directories"}),"\n",(0,s.jsxs)(i.p,{children:["You can exclude files or directories from formatting using the ",(0,s.jsx)(i.code,{children:"--exclude"})," option:"]}),"\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.code,{children:"black --exclude=dir_to_exclude/ ."})}),"\n",(0,s.jsx)(i.h3,{id:"integration-with-code-editors",children:"Integration with Code Editors"}),"\n",(0,s.jsx)(i.p,{children:"Many code editors have extensions or plugins that can automatically run Black on your code.\nFor example, if you're using VSCode or PyCharm, you can easily integrate it into your IDE."}),"\n",(0,s.jsx)(i.h3,{id:"example-of-failed-python-black-zuul-job",children:"Example of failed python-black Zuul job"}),"\n",(0,s.jsx)(i.p,{children:"job-output.txt:"}),"\n",(0,s.jsx)(i.pre,{children:(0,s.jsx)(i.code,{children:'[\u2026]\n2023-11-16 14:38:14.149756 | TASK [python-black : Install pip module black]\n2023-11-16 14:38:18.717886 | ubuntu-jammy | changed\n2023-11-16 14:38:18.723062 | \n2023-11-16 14:38:18.723137 | TASK [python-black : Format code with Black if there is nothing to exclude]\n2023-11-16 14:38:19.138060 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/adminer.py\n2023-11-16 14:38:19.151965 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/bird.py\n2023-11-16 14:38:19.163608 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/auditd.py\n2023-11-16 14:38:19.187772 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cephclient/package.py\n2023-11-16 14:38:19.192695 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cephclient/container.py\n2023-11-16 14:38:19.219694 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cgit.py\n2023-11-16 14:38:19.230577 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/dnsdist.py\n2023-11-16 14:38:19.275681 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/hddtemp/redhat.py\n2023-11-16 14:38:19.300350 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/homer.py\n2023-11-16 14:38:19.310641 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/lldpd.py\n2023-11-16 14:38:19.318096 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/docker.py\n2023-11-16 14:38:19.329099 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/osquery.py\n2023-11-16 14:38:19.344766 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/rsyslog.py\n2023-11-16 14:38:19.358190 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/smartd.py\n2023-11-16 14:38:19.363578 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/tuned.py\n2023-11-16 14:38:19.389205 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/util/util.py\n2023-11-16 14:38:19.406360 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_container_facts.py\n2023-11-16 14:38:19.415046 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/filter/address.py\n2023-11-16 14:38:19.473508 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_toolbox.py\n2023-11-16 14:38:19.908963 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_docker.py\n2023-11-16 14:38:19.914395 | ubuntu-jammy |\n2023-11-16 14:38:19.914412 | ubuntu-jammy | Oh no! \xf0\u0178\u2019\xa5 \xf0\u0178\u2019\u201d \xf0\u0178\u2019\xa5\n2023-11-16 14:38:19.914419 | ubuntu-jammy | 20 files would be reformatted, 18 files would be left unchanged.\n2023-11-16 14:38:20.249358 | ubuntu-jammy | ERROR\n2023-11-16 14:38:20.249501 | ubuntu-jammy | {\n2023-11-16 14:38:20.249533 | ubuntu-jammy | "delta": "0:00:01.053565",\n2023-11-16 14:38:20.249553 | ubuntu-jammy | "end": "2023-11-16 14:38:19.932073",\n2023-11-16 14:38:20.249571 | ubuntu-jammy | "msg": "non-zero return code",\n2023-11-16 14:38:20.249587 | ubuntu-jammy | "rc": 1,\n2023-11-16 14:38:20.249603 | ubuntu-jammy | "start": "2023-11-16 14:38:18.878508"\n2023-11-16 14:38:20.249618 | ubuntu-jammy | }\n[\u2026]\n'})})]})}function u(e={}){const{wrapper:i}={...(0,n.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,i,t)=>{t.d(i,{R:()=>o,x:()=>r});var s=t(96540);const n={},l=s.createContext(n);function o(e){const i=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),s.createElement(l.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f0e20cb6.b5360c37.js b/assets/js/f0e20cb6.b5360c37.js new file mode 100644 index 0000000000..48c732fb20 --- /dev/null +++ b/assets/js/f0e20cb6.b5360c37.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1479],{46382:(i,e,n)=>{n.r(e),n.d(e,{assets:()=>u,contentTitle:()=>r,default:()=>g,frontMatter:()=>s,metadata:()=>a,toc:()=>d});var o=n(74848),t=n(28453);const s={sidebar_label:"Configuration Guide",sidebar_position:30},r="Configuration Guide",a={id:"iaas/guides/configuration-guide/index",title:"Configuration Guide",description:"",source:"@site/docs/02-iaas/guides/configuration-guide/index.md",sourceDirName:"02-iaas/guides/configuration-guide",slug:"/iaas/guides/configuration-guide/",permalink:"/docs/iaas/guides/configuration-guide/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/index.md",tags:[],version:"current",sidebarPosition:30,frontMatter:{sidebar_label:"Configuration Guide",sidebar_position:30},sidebar:"docs",previous:{title:"OpenStack",permalink:"/docs/iaas/guides/upgrade-guide/openstack"},next:{title:"Configuration repository",permalink:"/docs/iaas/guides/configuration-guide/configuration-repository"}},u={},d=[];function c(i){const e={h1:"h1",...(0,t.R)(),...i.components};return(0,o.jsx)(e.h1,{id:"configuration-guide",children:"Configuration Guide"})}function g(i={}){const{wrapper:e}={...(0,t.R)(),...i.components};return e?(0,o.jsx)(e,{...i,children:(0,o.jsx)(c,{...i})}):c(i)}},28453:(i,e,n)=>{n.d(e,{R:()=>r,x:()=>a});var o=n(96540);const t={},s=o.createContext(t);function r(i){const e=o.useContext(s);return o.useMemo((function(){return"function"==typeof i?i(e):{...e,...i}}),[e,i])}function a(i){let e;return e=i.disableParentContext?"function"==typeof i.components?i.components(t):i.components||t:r(i.components),o.createElement(s.Provider,{value:e},i.children)}}}]); \ No newline at end of file diff --git a/assets/js/f14351c1.9a05821d.js b/assets/js/f14351c1.9a05821d.js new file mode 100644 index 0000000000..7c41857247 --- /dev/null +++ b/assets/js/f14351c1.9a05821d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7129],{51781:e=>{e.exports=JSON.parse('{"title":"Components","slug":"/category/components","permalink":"/docs/category/components","navigation":{"previous":{"title":"Testbed Guide","permalink":"/docs/iaas/guides/other-guides/testbed"},"next":{"title":"Image Manager","permalink":"/docs/iaas/components/image-manager/"}}}')}}]); \ No newline at end of file diff --git a/assets/js/f1715aef.7e1a6623.js b/assets/js/f1715aef.7e1a6623.js new file mode 100644 index 0000000000..ca62940a31 --- /dev/null +++ b/assets/js/f1715aef.7e1a6623.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6647],{42395:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var s=t(74848),a=t(28453);const r={},d="scs-0100: SCS Flavor Naming Standard",i={id:"iaas/scs-0100",title:"scs-0100: SCS Flavor Naming Standard",description:"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack",source:"@site/standards/iaas/scs-0100.md",sourceDirName:"iaas",slug:"/iaas/scs-0100",permalink:"/standards/iaas/scs-0100",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"IaaS Standards",permalink:"/standards/iaas/"},next:{title:"SCS Flavor Naming Standard",permalink:"/standards/scs-0100-v1-flavor-naming"}},c={},l=[{value:"Supplement: Implementation and Testing Notes",id:"supplement-implementation-and-testing-notes",level:2}];function o(n){const e={a:"a",h1:"h1",h2:"h2",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...n.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.h1,{id:"scs-0100-scs-flavor-naming-standard",children:"scs-0100: SCS Flavor Naming Standard"}),"\n",(0,s.jsx)(e.p,{children:"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack\nenvironments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM,\nand Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for\nusability and portability across all SCS flavors."}),"\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Version"}),(0,s.jsx)(e.th,{children:"Type"}),(0,s.jsx)(e.th,{children:"State"}),(0,s.jsx)(e.th,{children:"stabilized"}),(0,s.jsx)(e.th,{children:"deprecated"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:(0,s.jsx)(e.a,{href:"/standards/scs-0100-v1-flavor-naming",children:"scs-0100-v1"})}),(0,s.jsx)(e.td,{children:"Standard"}),(0,s.jsx)(e.td,{children:"Deprecated"}),(0,s.jsx)(e.td,{children:"2022-09-08"}),(0,s.jsx)(e.td,{children:"2023-10-31"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:(0,s.jsx)(e.a,{href:"/standards/scs-0100-v2-flavor-naming",children:"scs-0100-v2"})}),(0,s.jsx)(e.td,{children:"Standard"}),(0,s.jsx)(e.td,{children:"Deprecated"}),(0,s.jsx)(e.td,{children:"2023-02-21"}),(0,s.jsx)(e.td,{children:"2023-11-30"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:(0,s.jsx)(e.a,{href:"/standards/scs-0100-v3-flavor-naming",children:"scs-0100-v3"})}),(0,s.jsx)(e.td,{children:"Standard"}),(0,s.jsx)(e.td,{children:"Stable"}),(0,s.jsx)(e.td,{children:"2023-06-14"}),(0,s.jsx)(e.td,{children:"-"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"supplement-implementation-and-testing-notes",children:"Supplement: Implementation and Testing Notes"}),"\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Version"}),(0,s.jsx)(e.th,{children:"State"}),(0,s.jsx)(e.th,{children:"stabilized"}),(0,s.jsx)(e.th,{children:"deprecated"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:(0,s.jsx)(e.a,{href:"/standards/scs-0100-w1-flavor-naming-implementation-testing",children:"w1"})}),(0,s.jsx)(e.td,{children:"Proposal"}),(0,s.jsx)(e.td,{children:"-"}),(0,s.jsx)(e.td,{children:"-"})]})})]})]})}function h(n={}){const{wrapper:e}={...(0,a.R)(),...n.components};return e?(0,s.jsx)(e,{...n,children:(0,s.jsx)(o,{...n})}):o(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>d,x:()=>i});var s=t(96540);const a={},r=s.createContext(a);function d(n){const e=s.useContext(r);return s.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function i(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(a):n.components||a:d(n.components),s.createElement(r.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/f17f9c44.ffa3ee7d.js b/assets/js/f17f9c44.ffa3ee7d.js new file mode 100644 index 0000000000..043b507e35 --- /dev/null +++ b/assets/js/f17f9c44.ffa3ee7d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4979],{68081:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>p,frontMatter:()=>c,metadata:()=>l,toc:()=>i});var n=s(74848),o=s(28453);const c={},r="Controllers",l={id:"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers",title:"Controllers",description:"OpenStackClusterStackRelease controller",source:"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers.md",sourceDirName:"03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs",slug:"/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers",permalink:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Quickstart",permalink:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart"},next:{title:"Developer Guide",permalink:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop"}},a={},i=[{value:"OpenStackClusterStackRelease controller",id:"openstackclusterstackrelease-controller",level:2},{value:"OpenStackNodeImageRelease controller",id:"openstacknodeimagerelease-controller",level:2}];function d(e){const t={code:"code",h1:"h1",h2:"h2",img:"img",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"controllers",children:"Controllers"}),"\n",(0,n.jsx)(t.h2,{id:"openstackclusterstackrelease-controller",children:"OpenStackClusterStackRelease controller"}),"\n",(0,n.jsx)(t.p,{children:"The OpenStackClusterStackRelease controller\u2019s main responsibilities are:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Download release assets into the CSPO container"}),"\n",(0,n.jsxs)(t.li,{children:["Create OpenStackNodeImageRelease resources based on the required NodeImages defined in the downloaded release asset ",(0,n.jsx)(t.code,{children:"node-images.yaml"})]}),"\n",(0,n.jsx)(t.li,{children:"Set an OwnerReference on the existing OpenStackNodeImageRelease resources that could be utilized by the ClusterStack release (multiple versions of one ClusterStack could share an image)"}),"\n",(0,n.jsxs)(t.li,{children:["Update the OpenStackClusterStackRelease status to ",(0,n.jsx)(t.code,{children:"ready"})," once all related OpenStackNodeImageReleases are also ",(0,n.jsx)(t.code,{children:"ready"})]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"OSCSR controller",src:s(61779).A+"",title:"OSCSR controller",width:"825",height:"1572"})}),"\n",(0,n.jsx)(t.h2,{id:"openstacknodeimagerelease-controller",children:"OpenStackNodeImageRelease controller"}),"\n",(0,n.jsx)(t.p,{children:"The OpenStackNodeImageRelease controller\u2019s main responsibilities are:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Load the OpenStack Cloud configuration from the Secret referenced in ",(0,n.jsx)(t.code,{children:"spec.IdentityRef"})]}),"\n",(0,n.jsxs)(t.li,{children:["Create an Image as defined by ",(0,n.jsx)(t.code,{children:"spec.Image"})," if it does not already exist in the specified OpenStack project"]}),"\n",(0,n.jsx)(t.li,{children:"Instruct the OpenStack Glance service to import an Image from the provided URL"}),"\n",(0,n.jsxs)(t.li,{children:["Set the OpenStackNodeImageRelease status to ",(0,n.jsx)(t.code,{children:"ready"})," once the image achieves an Active status"]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"OSNIR controller",src:s(57678).A+"",title:"OSNIR controller",width:"1283",height:"1450"})})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},61779:(e,t,s)=>{s.d(t,{A:()=>n});const n=s.p+"assets/images/openstackclusterstackrelease-controller-392111d1162c59f4787aad5267f85e04.png"},57678:(e,t,s)=>{s.d(t,{A:()=>n});const n=s.p+"assets/images/openstacknodeimagerelease-controller-0b39df07c1e9d7a4e028f0795dd056d8.png"},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>l});var n=s(96540);const o={},c=n.createContext(o);function r(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f2a59390.71551bb2.js b/assets/js/f2a59390.71551bb2.js new file mode 100644 index 0000000000..f6831bd97b --- /dev/null +++ b/assets/js/f2a59390.71551bb2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2078],{42922:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>r,toc:()=>l});var i=s(74848),o=s(28453);const c={sidebar_label:"OpenStack",sidebar_position:60},a="OpenStack",r={id:"iaas/guides/deploy-guide/services/openstack",title:"OpenStack",description:"Common issues with deploying OpenStack services are documented in the",source:"@site/docs/02-iaas/guides/deploy-guide/services/openstack.md",sourceDirName:"02-iaas/guides/deploy-guide/services",slug:"/iaas/guides/deploy-guide/services/openstack",permalink:"/docs/iaas/guides/deploy-guide/services/openstack",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/deploy-guide/services/openstack.md",tags:[],version:"current",sidebarPosition:60,frontMatter:{sidebar_label:"OpenStack",sidebar_position:60},sidebar:"docs",previous:{title:"Ceph",permalink:"/docs/iaas/guides/deploy-guide/services/ceph"},next:{title:"Examples",permalink:"/docs/iaas/guides/deploy-guide/examples/"}},t={},l=[];function p(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"openstack",children:"OpenStack"}),"\n",(0,i.jsxs)(n.p,{children:["Common issues with deploying OpenStack services are documented in the\n",(0,i.jsx)(n.a,{href:"../../troubleshooting-guide/openstack",children:"OpenStack Troubleshooting Guide"}),"."]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["An OpenStack deployment contains a number of components providing APIs to access infrastructure resources.\nThe ",(0,i.jsx)(n.a,{href:"https://www.openstack.org/software/project-navigator/openstack-components#openstack-services",children:"OpenStack Components"}),"\npage lists the various services that can be deployed to provide such resources to cloud end users.\nUnfortunately, not all of the OpenStack projects listed there are still active.\nNot all of the services listed there are supported by OSISM."]})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"OpenStack client"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply openstackclient\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Keystone"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull keystone\nosism apply keystone\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Glance"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull glance\nosism apply glance\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Designate"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull designate\nosism apply designate\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Placement"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull placement\nosism apply placement\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Cinder"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull cinder\nosism apply cinder\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Neutron"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull neutron\nosism apply neutron\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Nova"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull nova\nosism apply nova\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Octavia"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull octavia\nosism apply octavia\n"})}),"\n",(0,i.jsx)(n.p,{children:"9.1. Manage amphora image"}),"\n",(0,i.jsx)(n.p,{children:"This step is only necessary if the Amphora Driver is used. If OVN is used as the driver,\nthis step is not necessary."}),"\n",(0,i.jsxs)(n.p,{children:["We provide regularly updated images for Octavia in\n",(0,i.jsx)(n.a,{href:"https://github.com/osism/openstack-octavia-amphora-image",children:"osism/openstack-octavia/amphora-image"}),".\nThe OSISM CLI can be used to upload the correct image depending on the OpenStack release\nused."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism manage image octavia\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Horizon"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull horizon\nosism apply horizon\n"})}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var i=s(96540);const o={},c=i.createContext(o);function a(e){const n=i.useContext(c);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f385820d.f66f48cd.js b/assets/js/f385820d.f66f48cd.js new file mode 100644 index 0000000000..2ce0c84af3 --- /dev/null +++ b/assets/js/f385820d.f66f48cd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7841],{5178:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>c});var o=i(74848),t=i(28453);const a={sidebar_label:"Horizon"},s="Horizon",r={id:"iaas/guides/configuration-guide/openstack/horizon",title:"Horizon",description:"* Horizon admin guide",source:"@site/docs/02-iaas/guides/configuration-guide/openstack/horizon.md",sourceDirName:"02-iaas/guides/configuration-guide/openstack",slug:"/iaas/guides/configuration-guide/openstack/horizon",permalink:"/docs/iaas/guides/configuration-guide/openstack/horizon",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/configuration-guide/openstack/horizon.md",tags:[],version:"current",frontMatter:{sidebar_label:"Horizon"},sidebar:"docs",previous:{title:"Heat",permalink:"/docs/iaas/guides/configuration-guide/openstack/heat"},next:{title:"Ironic",permalink:"/docs/iaas/guides/configuration-guide/openstack/ironic"}},l={},c=[{value:"Problems uploading machine images larger than 1 GiB",id:"problems-uploading-machine-images-larger-than-1-gib",level:2},{value:"Make clouds.yml file downloadable as an alternative to the RC file",id:"make-cloudsyml-file-downloadable-as-an-alternative-to-the-rc-file",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"horizon",children:"Horizon"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.openstack.org/horizon/latest/admin/index.html",children:"Horizon admin guide"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.openstack.org/horizon/latest/configuration/index.html",children:"Horizon configuration guide"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://docs.openstack.org/horizon/latest/configuration/settings.html",children:"Horizon configuration reference"})}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"problems-uploading-machine-images-larger-than-1-gib",children:"Problems uploading machine images larger than 1 GiB"}),"\n",(0,o.jsxs)(n.p,{children:["By default, the ",(0,o.jsx)(n.code,{children:"LimitRequestBody"})," is set to ",(0,o.jsx)(n.code,{children:"1073741824"})," (1 GiB).\nThis is a security feature (",(0,o.jsx)(n.a,{href:"https://access.redhat.com/security/cve/CVE-2022-29404",children:"CVE-2022-29404"}),")\nand not a bug. Further details in the\n",(0,o.jsx)(n.a,{href:"https://access.redhat.com/articles/6975397",children:"A new default for the LimitRequestBody directive in httpd configuration"}),"\narticle in the RedHat knowledgebase."]}),"\n",(0,o.jsxs)(n.p,{children:["This limit can be increased via the parameter ",(0,o.jsx)(n.code,{children:"horizon_httpd_limitrequestbody"}),"."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:"horizon_httpd_limitrequestbody: 2147483648 # 2 GiB\n"})}),"\n",(0,o.jsx)(n.h2,{id:"make-cloudsyml-file-downloadable-as-an-alternative-to-the-rc-file",children:"Make clouds.yml file downloadable as an alternative to the RC file"}),"\n",(0,o.jsxs)(n.p,{children:["By default, only the ",(0,o.jsx)(n.code,{children:"openrc"})," file is offered for download in Horizon. It makes sense to also add the\n",(0,o.jsx)(n.code,{children:"clouds.yaml"})," as a download. To do this, the menu is customised in the ",(0,o.jsx)(n.code,{children:"custom_local_settings"}),". The\nchange can be deployed with ",(0,o.jsx)(n.code,{children:"osism apply -a reconfigure horizon"}),"."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/files/overlays/horizon/custom_local_settings"',children:"SHOW_KEYSTONE_V2_RC = False\nUSER_MENU_LINKS = [\n {'name': _('OpenStack clouds.yml File'),\n 'icon_classes': ['fa-download', ],\n 'url': 'horizon:project:api_access:clouds.yaml',\n 'external': False,\n },\n {'name': _('OpenStack RC File v3'),\n 'icon_classes': ['fa-download', ],\n 'url': 'horizon:project:api_access:openrc',\n 'external': False,\n }\n]\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>s,x:()=>r});var o=i(96540);const t={},a=o.createContext(t);function s(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f40b2df0.37a8c2e3.js b/assets/js/f40b2df0.37a8c2e3.js new file mode 100644 index 0000000000..82d43ffd02 --- /dev/null +++ b/assets/js/f40b2df0.37a8c2e3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3639],{43596:(e,a,o)=>{o.r(a),o.d(a,{assets:()=>r,contentTitle:()=>i,default:()=>h,frontMatter:()=>n,metadata:()=>c,toc:()=>l});var t=o(74848),s=o(28453);const n={sidebar_label:"Octavia"},i="Octavia",c={id:"iaas/guides/operations-guide/openstack/octavia",title:"Octavia",description:"Cleanup of amphorae missing from the DB",source:"@site/docs/02-iaas/guides/operations-guide/openstack/octavia.md",sourceDirName:"02-iaas/guides/operations-guide/openstack",slug:"/iaas/guides/operations-guide/openstack/octavia",permalink:"/docs/iaas/guides/operations-guide/openstack/octavia",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/operations-guide/openstack/octavia.md",tags:[],version:"current",frontMatter:{sidebar_label:"Octavia"},sidebar:"docs",previous:{title:"Nova",permalink:"/docs/iaas/guides/operations-guide/openstack/nova"},next:{title:"Troubleshooting Guide",permalink:"/docs/iaas/guides/troubleshooting-guide/"}},r={},l=[{value:"Cleanup of amphorae missing from the DB",id:"cleanup-of-amphorae-missing-from-the-db",level:2},{value:"SSH access to amphorae",id:"ssh-access-to-amphorae",level:2}];function d(e){const a={code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(a.h1,{id:"octavia",children:"Octavia"}),"\n",(0,t.jsx)(a.h2,{id:"cleanup-of-amphorae-missing-from-the-db",children:"Cleanup of amphorae missing from the DB"}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{className:"language-none",metastring:'title="/var/log/kolla/octavia/octavia-health-manager.log"',children:"2023-10-25 16:43:52.547 22 WARNING octavia.amphorae.drivers.health.heartbeat_udp [-]\nThe amphora 2a33a889-4f9a-4340-84a5-e58a7a8af17e with IP 10.1.0.79 is missing from the\nDB, so it cannot be automatically deleted (the compute_id is unknown). An operator must\nmanually delete it from the compute service.\n"})}),"\n",(0,t.jsx)(a.h2,{id:"ssh-access-to-amphorae",children:"SSH access to amphorae"}),"\n",(0,t.jsxs)(a.ol,{children:["\n",(0,t.jsxs)(a.li,{children:["\n",(0,t.jsxs)(a.p,{children:["Get the local IP address (",(0,t.jsx)(a.code,{children:"lb_network_ip"}),") of the amphora you want to access via\n",(0,t.jsx)(a.code,{children:"openstack --os-cloud admin loadbalancer amphora list"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(a.li,{children:["\n",(0,t.jsx)(a.p,{children:"Connect to one of the nodes that you use for Octavia. Normally the control-\nor network nodes."}),"\n"]}),"\n",(0,t.jsxs)(a.li,{children:["\n",(0,t.jsxs)(a.p,{children:["You can now use SSH to access the amphora. The use of sudo is required here because\nyou cannot access ",(0,t.jsx)(a.code,{children:"/etc/kolla/octavia-worker/octavia_ssh_key"})," with the operator user\naccount. Replace ",(0,t.jsx)(a.code,{children:"lb_network_ip"})," with the local IP address of the amphora."]}),"\n",(0,t.jsx)(a.pre,{children:(0,t.jsx)(a.code,{children:"sudo ssh -i /etc/kolla/octavia-worker/octavia_ssh_key ubuntu@lb_network_ip\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:a}={...(0,s.R)(),...e.components};return a?(0,t.jsx)(a,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,a,o)=>{o.d(a,{R:()=>i,x:()=>c});var t=o(96540);const s={},n=t.createContext(s);function i(e){const a=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function c(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(n.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f4cdb2d9.a3048f4c.js b/assets/js/f4cdb2d9.a3048f4c.js new file mode 100644 index 0000000000..10c13d0f2b --- /dev/null +++ b/assets/js/f4cdb2d9.a3048f4c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2126],{90938:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>a});var o=t(74848),r=t(28453);const c={},s="Knowledge",i={id:"container/overview/knowledge",title:"Knowledge",description:"TODO",source:"@site/docs/03-container/overview/knowledge.md",sourceDirName:"03-container/overview",slug:"/container/overview/knowledge",permalink:"/docs/container/overview/knowledge",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/overview/knowledge.md",tags:[],version:"current",frontMatter:{}},d={},a=[];function l(e){const n={h1:"h1",p:"p",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"knowledge",children:"Knowledge"}),"\n",(0,o.jsx)(n.p,{children:"TODO"})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>i});var o=t(96540);const r={},c=o.createContext(r);function s(e){const n=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),o.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f5b4e375.b7e722cd.js b/assets/js/f5b4e375.b7e722cd.js new file mode 100644 index 0000000000..43bd8de189 --- /dev/null +++ b/assets/js/f5b4e375.b7e722cd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[778],{20584:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var t=n(74848),r=n(28453);const i={title:"SCS K8S Version Policy",type:"Standard",stabilized_at:new Date("2024-02-08T00:00:00.000Z"),status:"Stable",track:"KaaS"},o=void 0,a={id:"scs-0210-v2-k8s-version-policy",title:"SCS K8S Version Policy",description:"Introduction",source:"@site/standards/scs-0210-v2-k8s-version-policy.md",sourceDirName:".",slug:"/scs-0210-v2-k8s-version-policy",permalink:"/standards/scs-0210-v2-k8s-version-policy",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS K8S Version Policy",type:"Standard",stabilized_at:"2024-02-08T00:00:00.000Z",status:"Stable",track:"KaaS"},sidebar:"standards",previous:{title:"SCS K8S Version Policy for new Kubernetes versions",permalink:"/standards/scs-0210-v1-k8s-new-version-policy"},next:{title:"scs-0211: SCS KaaS default storage class",permalink:"/standards/kaas/scs-0211"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2}];function c(e){const s={a:"a",code:"code",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsx)(s.p,{children:"The Kubernetes project maintains multiple release versions including their patched versions.\nIn the project, the three most recent minor releases are actively maintained, with a fourth\nversion being in development. As soon as a new minor version is officially released,\nthe oldest version is dropped out of the support period.\nKubernetes supports its releases for around 14 months. 12 of these are the standard\nsupport period. The remaining 2 months are the end-of-life support period for things like:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"CVEs (under the advisement of the Security Response Committee)"}),"\n",(0,t.jsx)(s.li,{children:"dependency issues (including base image updates)"}),"\n",(0,t.jsx)(s.li,{children:"critical core component issues"}),"\n"]}),"\n",(0,t.jsx)(s.p,{children:"More information can be found under [Kubernetes Support Period]."}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"https://kubernetes.io/releases/release/#the-release-cycle",children:"Kubernetes release cycle"})," is set around 4 months, which\nusually results in about ",(0,t.jsx)(s.strong,{children:"3 minor"})," releases per year."]}),"\n",(0,t.jsxs)(s.p,{children:["Patches to these releases are provided monthly, with the exception of the first patch,\nwhich is usually provided 1-2 weeks after the initial release (see ",(0,t.jsx)(s.a,{href:"https://kubernetes.io/releases/patch-releases/#cadence",children:"Patch Release\nCadence"}),")."]}),"\n",(0,t.jsx)(s.h2,{id:"motivation",children:"Motivation"}),"\n",(0,t.jsx)(s.p,{children:"Kubernetes is a living, fast-paced project, which follows a pre-defined release cycle.\nThis enables forward planning with regards to releases and patches, but also implies a\nnecessity to upgrade to newer versions quickly, since these often include new features,\nimportant security updates or especially if a previous version falls out of the support\nperiod window."}),"\n",(0,t.jsx)(s.p,{children:"We want to achieve an up-to-date policy, meaning that providers should be mostly in\nsync with the upstream and don't fall behind the official Kubernetes releases.\nThis is achievable, since new versions are released periodical on a well communicated\nschedule, enabling providers and users to set up processes around it.\nBeing up to date ensures that security issues and bugs are addressed and new features\nare made available when using SCS compliant clusters."}),"\n",(0,t.jsx)(s.p,{children:"It is nevertheless important to at least support all Kubernetes versions that are still\ninside the support period, since users could depend on specific versions or may need\nlonger to upgrade their workloads to a newer version."}),"\n",(0,t.jsx)(s.p,{children:"The standard therefore should provide a version recency policy as well as a support\nwindow period."}),"\n",(0,t.jsx)(s.h2,{id:"decision",children:"Decision"}),"\n",(0,t.jsx)(s.p,{children:"In order to keep up-to-date with the latest Kubernetes features, bug fixes and security improvements,\nthe provided Kubernetes versions should be kept up-to-date with new upstream releases:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"The latest minor version MUST be provided no later than 4 months after release."}),"\n",(0,t.jsx)(s.li,{children:"The latest patch version MUST be provided no later than 1 week after release."}),"\n",(0,t.jsx)(s.li,{children:"This time period MUST be even shorter for patches that fix critical CVEs.\nIn this context, a critical CVE is a CVE with a CVSS base score >= 8 according\nto the CVSS version used in the original CVE record (e.g., CVSSv3.1).\nIt is RECOMMENDED to provide a new patch version in a 2 day time period after their release."}),"\n",(0,t.jsxs)(s.li,{children:["New versions MUST be tested before being rolled out on productive infrastructure;\nat least the ",(0,t.jsx)(s.a,{href:"https://github.com/cncf/k8s-conformance",children:"CNCF E2E tests"})," should be passed beforehand."]}),"\n"]}),"\n",(0,t.jsxs)(s.p,{children:["At the same time, providers must support Kubernetes versions at least as long as the\nofficial sources as described in ",(0,t.jsx)(s.a,{href:"https://kubernetes.io/releases/patch-releases/#support-period",children:"Kubernetes Support Period"}),":"]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["Kubernetes versions MUST be supported as long as the official sources support them\naccording to the ",(0,t.jsx)(s.a,{href:"https://kubernetes.io/releases/patch-releases/#support-period",children:"Kubernetes Support Period"})," and their end-of-life\ndate according to the ",(0,t.jsx)(s.a,{href:"https://kubernetes.io/releases/",children:"Kubernetes Releases page"}),"."]}),"\n",(0,t.jsx)(s.li,{children:"It is RECOMMENDED to not support versions after this period in order to not encourage\nusage of out-of-date versions."}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,t.jsxs)(s.p,{children:["All documents regarding versioning, releases, etc. for the official Kubernetes projects can\nbe found on the ",(0,t.jsx)(s.a,{href:"https://kubernetes.io/releases/",children:"Kubernetes Releases page"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,t.jsxs)(s.p,{children:["The script ",(0,t.jsx)(s.code,{children:"k8s_version_policy.py"})," requires a kubeconfig file with connection details for\na set of existing Kubernetes clusters that should be checked, with each of these clusters\nrepresenting one of the currently supported upstream Kubernetes releases.\nIt will check the encountered cluster versions according to the rules of this standard.\nRule violations will be reported on various logging channels: ERROR for mandatory rules\nand INFO for recommended rules.\nThe script will exit with a non-zero status if a mandatory rule has been violated or if\nthe test could not be performed."]})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var t=n(96540);const r={},i=t.createContext(r);function o(e){const s=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f68824be.2441b326.js b/assets/js/f68824be.2441b326.js new file mode 100644 index 0000000000..13d50b88d0 --- /dev/null +++ b/assets/js/f68824be.2441b326.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6070],{19122:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>c});var i=n(74848),s=n(28453);const o={title:"Requirements for SSO identity federation",type:"Decision Record",status:"Stable",stabilized_at:new Date("2023-06-21T00:00:00.000Z"),track:"IAM",description:"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign\nCloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed\nexternally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard\nfocuses on delegating authentication to external identity providers and mapping users to roles within SCS for\nauthorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity\nProvider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible.\n"},a=void 0,r={id:"scs-0300-v1-requirements-for-sso-identity-federation",title:"Requirements for SSO identity federation",description:"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign\nCloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed\nexternally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard\nfocuses on delegating authentication to external identity providers and mapping users to roles within SCS for\nauthorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity\nProvider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible.\n",source:"@site/standards/scs-0300-v1-requirements-for-sso-identity-federation.md",sourceDirName:".",slug:"/scs-0300-v1-requirements-for-sso-identity-federation",permalink:"/standards/scs-0300-v1-requirements-for-sso-identity-federation",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Requirements for SSO identity federation",type:"Decision Record",status:"Stable",stabilized_at:"2023-06-21T00:00:00.000Z",track:"IAM",description:"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign\nCloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed\nexternally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard\nfocuses on delegating authentication to external identity providers and mapping users to roles within SCS for\nauthorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity\nProvider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible.\n"},sidebar:"standards",previous:{title:"scs-0300: Requirements for SSO identity federation",permalink:"/standards/iam/scs-0300"},next:{title:"scs-0301: Naming for domains/groups/roles/project when onboarding new customers",permalink:"/standards/iam/scs-0301"}},d={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Motivation for this document",id:"motivation-for-this-document",level:2},{value:"Design Considerations",id:"design-considerations",level:2},{value:"Options considered",id:"options-considered",level:3},{value:"Keycloak",id:"keycloak",level:4},{value:"Zitadel",id:"zitadel",level:4},{value:"Open questions",id:"open-questions",level:2},{value:"Decision",id:"decision",level:2},{value:"Related Documents",id:"related-documents",level:2},{value:"Conformance Tests",id:"conformance-tests",level:2},{value:"Conformance Tests, OPTIONAL",id:"conformance-tests-optional",level:2}];function l(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"Our assumption is that there are use cases, where CSPs would like to be able to\nlet customers access their SCS based services by identifying themselves with\ncredentials that are stored and managed external to the CSP's SCS installation."}),"\n",(0,i.jsx)(t.p,{children:"This is based on the observation that prospective customers of an SCS based CSP\nsometimes already come equipped with an IAM solution of their choice, either on\npremises or e.g. as an external 3rd party cloud service. To ease onboarding of\ncustomer employees (or e.g. customer contracted 3rd party admin staff) as SCS\nusers, it would be good to be able to consume these external identities in SCS."}),"\n",(0,i.jsx)(t.p,{children:"For customers this avoids the neccessity to explicitly maintain an additional\ndedicated account in SCS and this also reduces what SCS needs to do with\nrespect to taking care of persisting user account information."}),"\n",(0,i.jsx)(t.p,{children:"To put it in other words, in SCS we would like to be able to delegate\nauthentication to external identity providers and map those users to roles in\nSCS that can be used for authorization decisions when users access SCS services."}),"\n",(0,i.jsx)(t.p,{children:'In addition to user identities there we also see the necessity to support the\nuse of "machine identites" (aka "workload identities" or "service accounts").\nThese will probably be SCS-local accounts and have for example the purpose\nto grant CaaS workload access to storage resources served by the infrastructure\nlayer. Exact architectural details for this are still in active discussion,\nbut it is anticipated that the IdP component should be very useful in\nfacilitating the integration.'}),"\n",(0,i.jsx)(t.h2,{id:"motivation-for-this-document",children:"Motivation for this document"}),"\n",(0,i.jsx)(t.p,{children:"SCS has multiple service layers, like IaaS and CaaS, both of which running their\nown technological stack with specific internal models of accounts and\nauthorization."}),"\n",(0,i.jsx)(t.p,{children:"One thing these services have in common, is that they are able\nto use SSO protocols like OAuth 2.0 or OpenID Connect (OIDC) on top of it to\ndelegate authentication. They are service providers (SAML terminology) and can\nbe relying parties (OIDC terminology) of a protocol compliant identity provider\n(IdP)."}),"\n",(0,i.jsx)(t.p,{children:"So the idea is, to run an SSO IdP as part of SCS to provide a dedicated point\nof entry for identites, which the SCS service layers can use as a common\ninterface to consume external user identities."}),"\n",(0,i.jsx)(t.p,{children:"The purpose of this document is to specify what requirements a specific\ntechnical IdP implementation (i.e. software solution) needs to fulfill\nin the context of SCS."}),"\n",(0,i.jsx)(t.h2,{id:"design-considerations",children:"Design Considerations"}),"\n",(0,i.jsx)(t.p,{children:"As a central service for identity handling, the IdP\nservice needs to be robust and reliable."}),"\n",(0,i.jsx)(t.p,{children:'Customers shall be able to access self service, so that\nthey can make reasonable adjustments e.g. to role mapping.\nAt the time of writing this document it\'s still undecided\nif SCS has the requirement of a dedicated "self service" service\nthat serves as a frontend to provision and re-configure\ncustomer specific data, abstracting e.g. from IdP specific\nuser interface particularities.'}),"\n",(0,i.jsx)(t.p,{children:'Keycloak is currently being deployed as part of the IaaS reference implementation.\nTechnically this IdP component shall be shifted from the management\nplane to be run on the basis of a "minimal" Kubernetes (e.g. K3S),\ne.g. to make use of the "self healing" and scaling features achievable\nwith that.'}),"\n",(0,i.jsx)(t.p,{children:"So one of the considerations is if the solution will work well on a\nK8S environment. The instances will need to share configuration\n(probably via the shared backend database) as well as session state.\nMaybe one is better prepared for horizontal scaling than the other."}),"\n",(0,i.jsx)(t.h3,{id:"options-considered",children:"Options considered"}),"\n",(0,i.jsx)(t.h4,{id:"keycloak",children:"Keycloak"}),"\n",(0,i.jsx)(t.p,{children:"Keycloak is a commonly used IdP solution implemented in Java.\nIt is developed as an open source community project.\nRed Hat uses it as upstream source for their Red Hat SSO product\nand is also listed as sponsor of the project.\nStarting with version 17 the default distribution is based on\nQuarkus instead of WildFly/JBoss."}),"\n",(0,i.jsxs)(t.p,{children:["The project maintains several means of community contributions\nas listed on the ",(0,i.jsx)(t.a,{href:"https://www.keycloak.org/community",children:"community section"}),"\nof the project website. It uses ",(0,i.jsx)(t.a,{href:"https://github.com/keycloak/keycloak/issues",children:"Github issues"}),"\nto track development."]}),"\n",(0,i.jsx)(t.p,{children:"It offers a REST API for administration and there's a separately maintained\n3rd party python module as well as ansible support for it. Both of these are\ndownstream of Keycloak itself and may thus not always be feature complete and\nsuffer latency with respect to getting adjusted to upstream changes."}),"\n",(0,i.jsx)(t.p,{children:'It offers support for commonly used SSO protocols and is "reasonably" fast\nin adopting to protocol standard changes and extensions. This has been\nobserved in the case of logout support (backend and frontend variants) in OIDC.'}),"\n",(0,i.jsx)(t.p,{children:'It offers a concept of "Identity Brokering", where Keycloak is not just IdP\nbut also "client" to other IdPs. This allows daisy chaining of identity\nfederation. In this configuration it can work as a point of protocol\ntransition between different supported SSO protocols (SAML, OAuth 2.0, etc.).'}),"\n",(0,i.jsx)(t.p,{children:"Beyond this capability of using other IdPs as identity sources, it also supports\nusing classic LDAP based IAM services as backend (OpenLDAP and Active Directory,\ne.g.)."}),"\n",(0,i.jsx)(t.p,{children:'Keycloak\'s implementation makes some design decisions, that are specific\nto it and have consequences for clients of the service. E.g. Keycloak\nhas a concept of management "Realms", which have their own specific\nset of HTTP API entrypoints, both for administration as well as for IdP\nrequests.'}),"\n",(0,i.jsx)(t.p,{children:'Commonly Keycloak realms can be used to map them 1:1 to user domains,\nbut since Keycloak supports configuring multiple backend IdPs in a\nrealm to be used for "Identity Brokering", there is always the\npossibility to create a kind of "proxy" realm to provide a single\nstandard set of HTTP API endpoints for SSO clients (service providers)\nto avoid the need to frequently extend/reduce client service configuration\nwhenever a new IdP federation needs to be added to Keycloak to onboard\na new customer. This is relevant for services like OpenStack Keystone,\nwhich currently cannot be easily reconfigured for new SSO endpoints\nwithout restarting the service, making the service unavailable for\na short span of time and increasing risk connected with service restarts.'}),"\n",(0,i.jsx)(t.p,{children:'Since version 17, Keycloak claims that it\'s capability for\n"cloud native" deployments on Kubernetes has improved.'}),"\n",(0,i.jsxs)(t.p,{children:["Keycloak is offering a ",(0,i.jsx)(t.a,{href:"https://www.keycloak.org/documentation",children:"documented REST API"}),"\nfor all aspects of its administration interface."]}),"\n",(0,i.jsx)(t.p,{children:"For storage of Keycloak configuration and local user metadata\n(e.g. from which external IdP a user account originally came from)\nKeycloak supports several SQL backends through JDBC. Thus\nit can be hooked up to a Postgres Database or to a\nMariaDB/Galera cluster e.g.."}),"\n",(0,i.jsx)(t.p,{children:"As of April 11, 2023, Keycloak joined the CNCF as an incubating project."}),"\n",(0,i.jsx)(t.h4,{id:"zitadel",children:"Zitadel"}),"\n",(0,i.jsx)(t.p,{children:"Zitadel is a newer implementation of an SSO IdP.\nIt is implemented in Go and under active development and maintained by ZITADEL."}),"\n",(0,i.jsxs)(t.p,{children:["The project is open for community ",(0,i.jsx)(t.a,{href:"https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md",children:"contributions"}),"\nto all parts of the eco system.\nFeature requests and bugs being tracked on ",(0,i.jsx)(t.a,{href:"https://github.com/orgs/zitadel/projects/2/views/5",children:"Github"})," for development.\nCommunity questions can be asked in the ",(0,i.jsx)(t.a,{href:"https://zitadel.com/chat",children:"public chat"})," or via ",(0,i.jsx)(t.a,{href:"https://github.com/zitadel/zitadel/discussions",children:"Github Discussions"}),".\nZITADEL offers support for the commonly used authentication and authorization protocols such as OIDC, OAuth2, SAML2.\nIt is a compliant and certified OpenID Connect provider with support for various Grant Types for both human users and machine users.\nCompared to Keycloak SPIs, ZITADEL offers Actions to customize and integrate (eg, calling external APIs, Webhooks, customizing pre-built workflows, customizing tokens)\nActions are executed at runtime and can be maintained independently of platform.\nIdentity brokering (OIDC, SAML, JWT) can be configured system-wide or for each organization with templates.\nUsers will be created just in time for audit purposes and linked to the external identity provider.\nUsers can have multiple identity providers linked to their profile."]}),"\n",(0,i.jsx)(t.p,{children:"It came to attention of the SCS project because it offers a\nfresh take of an organization focussed data model, which has\nthe potential to simplify IdP federation to SCS customer domains\nin the following areas:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"For client services (single set of HTTP API endpoints)."}),"\n",(0,i.jsxs)(t.li,{children:["For SCS operators for provisioning customer ",(0,i.jsx)(t.a,{href:"https://zitadel.com/docs/concepts/structure/organizations",children:"organizations"}),"\nand robust configuraton by using templated client, role and mapping\nconfiguration."]}),"\n",(0,i.jsx)(t.li,{children:"For SCS customers for a robust user experience for self servicing."}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["The concept for ",(0,i.jsx)(t.a,{href:"https://zitadel.com/docs/concepts/structure/organizations",children:"Delegated Access Management"}),"\nreduces the management overhead compared to isolated realms.\nProjects (Applications + Roles) can be maintained by one organization and delegated to be used by other Organizations.\nManagers that receive granted Projects can assign users permissions to use the project."]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.a,{href:"https://zitadel.com/docs/apis/introduction",children:"Zitadel is offering REST APIs"}),"\nfor multiple areas of use and configuration."]}),"\n",(0,i.jsxs)(t.p,{children:["It recently also added support for the ",(0,i.jsx)(t.a,{href:"https://github.com/zitadel/oidc/issues/141",children:"Device Authorization Grant"}),",\nwhich, at time of writing, is a feauture that is relevant\nfor SCS to be able use OpenStack CLI and APIs with federated\nidentities (",(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/issues/issues/221",children:"Device Authorization Grant"}),")."]}),"\n",(0,i.jsxs)(t.p,{children:["Support for consumption of LDAP backends is available since ",(0,i.jsx)(t.a,{href:"https://github.com/zitadel/zitadel/releases/tag/v2.23.0",children:"Zitadel v2.23.0"}),"\n(see ",(0,i.jsx)(t.a,{href:"https://zitadel.com/docs/guides/integrate/identity-providers/ldap",children:"this guide"}),")."]}),"\n",(0,i.jsx)(t.p,{children:"ZITADEL supported backend databases are CockroachDB and PostgreSQL."}),"\n",(0,i.jsxs)(t.p,{children:["For ",(0,i.jsx)(t.a,{href:"https://zitadel.com/docs/self-hosting/manage/production",children:"production setups"})," it is recommended\nto use Kubernetes (or similar like Knative) and CockroachDB."]}),"\n",(0,i.jsx)(t.p,{children:'At time of writing a PoC "spike" is done to assess and verify the hopes\nconnected with Zitadel in the context of the SCS testbed.'}),"\n",(0,i.jsxs)(t.p,{children:["Currently Zitadel is lacking the possibility to easily add custom claims.\nIt supports ",(0,i.jsx)(t.code,{children:"urn:zitadel:iam:user:metadata"}),", but that is more suitable\ntowards Kubernetes and cannot be parsed with the OpenStack mapping mechanism.\n",(0,i.jsx)(t.a,{href:"https://github.com/zitadel/zitadel/issues/3997",children:"There is work going on"})," which\nmay be suitable to resolve this issue.\nAn approach based on Zitadel actions is also currently evaluated.\nOpenStack currently makes use of custom claims to pass ",(0,i.jsx)(t.code,{children:"openstack-default-project"}),"\nfrom the IdP to OpenStack. Combined with federation to external customer managed IdPs\nthis should allow customers to manage settings like these in their own IAM."]}),"\n",(0,i.jsx)(t.h2,{id:"open-questions",children:"Open questions"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["How would we implement testbed deployment support for Zitadel?","\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["e.g. ",(0,i.jsx)(t.code,{children:"wsgi-keystone.conf"})," would need to look different. One template covering both options?"]}),"\n",(0,i.jsxs)(t.li,{children:["e.g. steps like ",(0,i.jsx)(t.code,{children:"openstack federation protocol create"})," would probably be different."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["Should we support both as options?","\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"What's the benefit?"}),"\n",(0,i.jsx)(t.li,{children:"How would we allow SCS operators to choose?"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.li,{children:"Do we need some kind of SWOT analysis to come to a decision?"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(t.p,{children:"SCS wants to make use of an IdP as part of the reference implementation.\nTo move forward with topics of configuration and mapping of roles in a\nOAuth2 federation scenario as well as questions of token lifecycles etc. across\nthe federation stack it makes sense to focus on one IdP implementation at a\ngiven time. Both considered options seem to be potentially viable, but ultimately,\na decision should be made, even if there are no strict/strong reasons for\ndismissing either option in particular."}),"\n",(0,i.jsx)(t.p,{children:"The project's current choice is Keycloak for the following reasons:\nKeycloak currently supports the OAuth 2.0 grants that SCS wants to make\nuse of (e.g. Device Authorization Grant). It is the implementation for\nwhich integration is currently documented in OpenStack and implemented\nin kolla-ansible. SCS currently deploys Keycloak and the IAM team has\nmost hands on expecience with it, e.g. when it comes to colletaral questions\nlike how to make TLS and signing certificates available to the IdP that shall\nbe used in federation to external domains."}),"\n",(0,i.jsx)(t.h2,{id:"related-documents",children:"Related Documents"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"https://github.com/SovereignCloudStack/standards/tree/main/Drafts/IAM-federation",children:"https://github.com/SovereignCloudStack/standards/tree/main/Drafts/IAM-federation"})}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"conformance-tests",children:"Conformance Tests"}),"\n",(0,i.jsx)(t.h2,{id:"conformance-tests-optional",children:"Conformance Tests, OPTIONAL"})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var i=n(96540);const s={},o=i.createContext(s);function a(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f793d2d5.b0d753df.js b/assets/js/f793d2d5.b0d753df.js new file mode 100644 index 0000000000..b3c9ed898e --- /dev/null +++ b/assets/js/f793d2d5.b0d753df.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6183],{2518:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"community"}')}}]); \ No newline at end of file diff --git a/assets/js/f8869d03.9188ac6a.js b/assets/js/f8869d03.9188ac6a.js new file mode 100644 index 0000000000..07b8a8afb5 --- /dev/null +++ b/assets/js/f8869d03.9188ac6a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5595],{59638:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>i,contentTitle:()=>a,default:()=>o,frontMatter:()=>d,metadata:()=>c,toc:()=>l});var n=r(74848),t=r(28453);const d={},a="KaaS Standards",c={id:"kaas/index",title:"KaaS Standards",description:"Standards in this track are concerned with Kubernetes as a Service layer, outlining norms and best practices for deploying, managing, and operating Kubernetes clusters. These standards aim to ensure that the orchestration of containers is streamlined, secure, and compatible across various cloud environments and platforms.",source:"@site/standards/kaas/index.md",sourceDirName:"kaas",slug:"/kaas/",permalink:"/standards/kaas/",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Default Rules for Security Groups",permalink:"/standards/scs-0115-v1-default-rules-for-security-groups"},next:{title:"scs-0200: Using Sonobuoy for KaaS conformance tests",permalink:"/standards/kaas/scs-0200"}},i={},l=[];function h(s){const e={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"kaas-standards",children:"KaaS Standards"}),"\n",(0,n.jsx)(e.p,{children:"Standards in this track are concerned with Kubernetes as a Service layer, outlining norms and best practices for deploying, managing, and operating Kubernetes clusters. These standards aim to ensure that the orchestration of containers is streamlined, secure, and compatible across various cloud environments and platforms."}),"\n",(0,n.jsx)(e.p,{children:"*Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective)."}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:"Standard"}),(0,n.jsx)(e.th,{children:"Description"}),(0,n.jsx)(e.th,{children:"Draft"}),(0,n.jsx)(e.th,{children:"Stable*"}),(0,n.jsx)(e.th,{children:"Effective"}),(0,n.jsx)(e.th,{children:"Deprecated*"})]})}),(0,n.jsxs)(e.tbody,{children:[(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/kaas/scs-0200",children:"scs-0200"})}),(0,n.jsx)(e.td,{children:"Using Sonobuoy for KaaS conformance tests"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/kaas/scs-0210",children:"scs-0210"})}),(0,n.jsx)(e.td,{children:"SCS K8S Version Policy"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0210-v2-k8s-version-policy",children:"v2"})}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0210-v1-k8s-new-version-policy",children:"v1"})})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/kaas/scs-0211",children:"scs-0211"})}),(0,n.jsx)(e.td,{children:"SCS KaaS default storage class"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0211-v1-kaas-default-storage-class",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/kaas/scs-0212",children:"scs-0212"})}),(0,n.jsx)(e.td,{children:"Requirements for container registries"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0212-v1-requirements-for-container-registries",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/kaas/scs-0213",children:"scs-0213"})}),(0,n.jsx)(e.td,{children:"Kubernetes Nodes Anti Affinity"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0213-v1-k8s-nodes-anti-affinity",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/kaas/scs-0214",children:"scs-0214"})}),(0,n.jsx)(e.td,{children:"Kubernetes Node Distribution and Availability"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0214-v1-k8s-node-distribution",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/kaas/scs-0215",children:"scs-0215"})}),(0,n.jsx)(e.td,{children:"Robustness features for Kubernetes clusters"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0215-v1-robustness-features",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/kaas/scs-0216",children:"scs-0216"})}),(0,n.jsx)(e.td,{children:"Requirements for testing cluster-stacks"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/kaas/scs-0217",children:"scs-0217"})}),(0,n.jsx)(e.td,{children:"Kubernetes cluster baseline security"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0217-v1-baseline-cluster-security",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]}),(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/kaas/scs-0218",children:"scs-0218"})}),(0,n.jsx)(e.td,{children:"Container registry for SCS standard implementation"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.a,{href:"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation",children:"v1"})}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"}),(0,n.jsx)(e.td,{children:"-"})]})]})]})]})}function o(s={}){const{wrapper:e}={...(0,t.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(h,{...s})}):h(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>a,x:()=>c});var n=r(96540);const t={},d=n.createContext(t);function a(s){const e=n.useContext(d);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function c(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(t):s.components||t:a(s.components),n.createElement(d.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/f91986bc.707058ad.js b/assets/js/f91986bc.707058ad.js new file mode 100644 index 0000000000..a8f1f82bd6 --- /dev/null +++ b/assets/js/f91986bc.707058ad.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9121],{65766:e=>{e.exports=JSON.parse('{"title":"Operating SCS","slug":"/category/operating-scs","permalink":"/docs/category/operating-scs","navigation":{"previous":{"title":"HA deployment","permalink":"/docs/container/components/container-registry/docs/ha-deployment"},"next":{"title":"Components","permalink":"/docs/category/components-2"}}}')}}]); \ No newline at end of file diff --git a/assets/js/f9ec068e.642d4808.js b/assets/js/f9ec068e.642d4808.js new file mode 100644 index 0000000000..91a97c829d --- /dev/null +++ b/assets/js/f9ec068e.642d4808.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[751],{32512:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>d,metadata:()=>o,toc:()=>i});var s=n(74848),r=n(28453);const d={},a="scs-0001: Sovereign Cloud Standards",o={id:"global/scs-0001",title:"scs-0001: Sovereign Cloud Standards",description:"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision",source:"@site/standards/global/scs-0001.md",sourceDirName:"global",slug:"/global/scs-0001",permalink:"/standards/global/scs-0001",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{},sidebar:"standards",previous:{title:"Global Standards",permalink:"/standards/global/"},next:{title:"Sovereign Cloud Standards",permalink:"/standards/scs-0001-v1-sovereign-cloud-standards"}},c={},i=[];function l(e){const t={a:"a",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"scs-0001-sovereign-cloud-standards",children:"scs-0001: Sovereign Cloud Standards"}),"\n",(0,s.jsx)(t.p,{children:"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision\nrecords within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in\nthe development and maintenance of interoperable and transparent cloud infrastructure standards."}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Version"}),(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"State"}),(0,s.jsx)(t.th,{children:"stabilized"}),(0,s.jsx)(t.th,{children:"deprecated"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/standards/scs-0001-v1-sovereign-cloud-standards",children:"scs-0001-v1"})}),(0,s.jsx)(t.td,{children:"Procedural"}),(0,s.jsx)(t.td,{children:"Stable"}),(0,s.jsx)(t.td,{children:"2022-11-28"}),(0,s.jsx)(t.td,{children:"-"})]})})]})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},d=s.createContext(r);function a(e){const t=s.useContext(d);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(d.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fa7c4c29.ea6333de.js b/assets/js/fa7c4c29.ea6333de.js new file mode 100644 index 0000000000..973e2bafec --- /dev/null +++ b/assets/js/fa7c4c29.ea6333de.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5122],{70666:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>d,toc:()=>c});var i=t(74848),s=t(28453);const o={sidebar_label:"Network",sidebar_position:15},r="Network",d={id:"iaas/guides/upgrade-guide/network",title:"Network",description:"1. Open vSwitch (OVS)",source:"@site/docs/02-iaas/guides/upgrade-guide/network.md",sourceDirName:"02-iaas/guides/upgrade-guide",slug:"/iaas/guides/upgrade-guide/network",permalink:"/docs/iaas/guides/upgrade-guide/network",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/network.md",tags:[],version:"current",sidebarPosition:15,frontMatter:{sidebar_label:"Network",sidebar_position:15},sidebar:"docs",previous:{title:"Manager",permalink:"/docs/iaas/guides/upgrade-guide/manager"},next:{title:"Ceph",permalink:"/docs/iaas/guides/upgrade-guide/ceph"}},a={},c=[];function l(e){const n={code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"network",children:"Network"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Open vSwitch (OVS)"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull openvswitch\nosism apply -a upgrade openvswitch\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Open Virtual Network (OVN)"}),"\n",(0,i.jsxs)(n.p,{children:["In ",(0,i.jsx)(n.code,{children:"environments/kolla/configuration.yml"})," the parameter ",(0,i.jsx)(n.code,{children:"neutron_plugin_agent"})," is set to\n",(0,i.jsx)(n.code,{children:"ovn"})," if OVN is used as a network plugin. The parameter is set to ",(0,i.jsx)(n.code,{children:"ovn"})," by default in the\nCookiecutter."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",metastring:'title="environments/kolla/configuration.yml"',children:'# neutron\nneutron_plugin_agent: "ovn"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Otherwise the network plugin is set to ",(0,i.jsx)(n.code,{children:"openvswitch"}),".\nIf the ",(0,i.jsx)(n.code,{children:"neutron_plugin_agent"})," is set to ",(0,i.jsx)(n.code,{children:"openvswitch"}),", this step does not need to be done."]}),"\n",(0,i.jsx)(n.p,{children:"Before the upgrade of OVN, the upgrade of Open vSwitch must already have been done."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"osism apply -a pull ovn\nosism apply -a upgrade ovn\n"})}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>d});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fd34a958.41b5a613.js b/assets/js/fd34a958.41b5a613.js new file mode 100644 index 0000000000..e1c9a22105 --- /dev/null +++ b/assets/js/fd34a958.41b5a613.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9049],{19740:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var i=t(74848),s=t(28453);const a={title:"Status page OpenAPI decision",type:"Decision Record",status:"Draft",track:"Ops"},r=void 0,o={id:"scs-0402-v1-status-page-openapi-spec-decision",title:"Status page OpenAPI decision",description:"Introduction",source:"@site/standards/scs-0402-v1-status-page-openapi-spec-decision.md",sourceDirName:".",slug:"/scs-0402-v1-status-page-openapi-spec-decision",permalink:"/standards/scs-0402-v1-status-page-openapi-spec-decision",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"Status page OpenAPI decision",type:"Decision Record",status:"Draft",track:"Ops"},sidebar:"standards",previous:{title:"scs-0402: Status page OpenAPI decision",permalink:"/standards/ops/scs-0402"},next:{title:"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer",permalink:"/standards/ops/scs-0403"}},d={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Requirements",id:"requirements",level:2},{value:"Motivation",id:"motivation",level:2},{value:"Decision",id:"decision",level:2},{value:"Common definitions",id:"common-definitions",level:3},{value:"Id",id:"id",level:4},{value:"Incremental",id:"incremental",level:4},{value:"Generation and order",id:"generation-and-order",level:4},{value:"SeverityValue",id:"severityvalue",level:4},{value:"API objects",id:"api-objects",level:3},{value:"API object fields",id:"api-object-fields",level:3},{value:"Endpoint naming",id:"endpoint-naming",level:3},{value:"Phase list",id:"phase-list",level:3},{value:"Labels",id:"labels",level:3},{value:"Impact",id:"impact",level:3},{value:"Severity",id:"severity",level:3},{value:"Component impacts",id:"component-impacts",level:3},{value:"Return of <code>POST</code> requests",id:"return-of-post-requests",level:3},{value:"Return of <code>PATCH</code> requestes",id:"return-of-patch-requestes",level:3},{value:"<code>PATCH</code> vs <code>PUT</code> for updating resources",id:"patch-vs-put-for-updating-resources",level:3},{value:"Authentication and authorization",id:"authentication-and-authorization",level:3}];function l(e){const n={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsxs)(n.p,{children:["While defining the ",(0,i.jsx)(n.a,{href:"https://github.com/SovereignCloudStack/status-page-openapi",children:"OpenAPI spec"})," some considerations and decisions are made and should be documented."]}),"\n",(0,i.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,i.jsxs)(n.p,{children:['The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in ',(0,i.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2119",children:"RFC 2119"}),"."]}),"\n",(0,i.jsx)(n.p,{children:'In addition, "FORBIDDEN" is to be interpreted equivalent to "MUST NOT".'}),"\n",(0,i.jsx)(n.h2,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(n.p,{children:"The spec should be as minimal as possible, while being as understandable as possible, so some choices to the design of API objects, requests and responses are made."}),"\n",(0,i.jsx)(n.h2,{id:"decision",children:"Decision"}),"\n",(0,i.jsx)(n.h3,{id:"common-definitions",children:"Common definitions"}),"\n",(0,i.jsx)(n.p,{children:"Some defined schemas are used as common types. These common definitions help to simplify the actual object definitions by providing meaningful names, and reduce duplication. A change of ID type for example only needs one change in the common definition, and not in any of the object definitions which include an ID."}),"\n",(0,i.jsx)(n.p,{children:"Special mentions:"}),"\n",(0,i.jsx)(n.h4,{id:"id",children:"Id"}),"\n",(0,i.jsx)(n.p,{children:"IDs are used for identification of resources, which can be retrieved by the API."}),"\n",(0,i.jsx)(n.p,{children:"UUIDs are used, to ensure uniqueness. Also, they can be visually recognized as identifier."}),"\n",(0,i.jsx)(n.h4,{id:"incremental",children:"Incremental"}),"\n",(0,i.jsxs)(n.p,{children:["An ",(0,i.jsx)(n.code,{children:"Incremental"})," is used in combination with other identifiers to identify a sub resource of any kind. ",(0,i.jsx)(n.code,{children:"Incremental"}),"s themselves are not globally unique, but unique for every sub resource of an unique resource."]}),"\n",(0,i.jsx)(n.h4,{id:"generation-and-order",children:"Generation and order"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Generation"})," and ",(0,i.jsx)(n.code,{children:"Order"})," are predefined objects which include a ",(0,i.jsx)(n.code,{children:"Incremental"})," typed field for the common usages of the ",(0,i.jsx)(n.code,{children:"Incremental"})," value."]}),"\n",(0,i.jsx)(n.h4,{id:"severityvalue",children:"SeverityValue"}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.code,{children:"SeverityValue"})," is an unsiged integer ranging from 0 to 100 inclusively. It MUST be utilized by an ",(0,i.jsx)(n.code,{children:"Impact"})," when referenced by a requested ",(0,i.jsx)(n.code,{children:"Component"})," to gauge the severity of the impact on that component. It MUST be added to an ",(0,i.jsx)(n.code,{children:"Impact"})," when refereced by an ",(0,i.jsx)(n.code,{children:"Incident"}),", when its created. While being described as an unsiged integer, implementing this value MAY not require it to be an uint data type in any form, because its range even fits in a signed int8 (byte) data type."]}),"\n",(0,i.jsx)(n.h3,{id:"api-objects",children:"API objects"}),"\n",(0,i.jsx)(n.p,{children:"All objects which are used as payload, either as request or response, are defined by schemas. This centralizes the maintanence of field names and types, for both requests and responses."}),"\n",(0,i.jsx)(n.h3,{id:"api-object-fields",children:"API object fields"}),"\n",(0,i.jsx)(n.p,{children:"Most fields of objects are not required. This allows usage as request and response payloads."}),"\n",(0,i.jsxs)(n.p,{children:["Responses of payload objects, which contain an ID or an ",(0,i.jsx)(n.code,{children:"Incremental"})," typed field, MUST fill the ID or ",(0,i.jsx)(n.code,{children:"Incremental"})," field to fully identify the (sub) resource."]}),"\n",(0,i.jsxs)(n.p,{children:["Requests on a single resource MUST contain the ID in the path parameters. Request on sub resources MUST contain the ID and ",(0,i.jsx)(n.code,{children:"Incremental"})," typed value as path parameters. The payload SHOULD NOT contain the ID or ",(0,i.jsx)(n.code,{children:"Incremental"})," typed field.\nIf it contains these fields as payload, they SHALL NOT change them."]}),"\n",(0,i.jsxs)(n.p,{children:["Requests to updating operations SHOULD contain the minimum of the changed fields, but MAY contain the full object. ID and ",(0,i.jsx)(n.code,{children:"Incremental"})," typed fields MUST follow the same rules as stated above."]}),"\n",(0,i.jsx)(n.h3,{id:"endpoint-naming",children:"Endpoint naming"}),"\n",(0,i.jsx)(n.p,{children:"The endpoints are named in plural form, even when handeling single objects, to keep uniform paths."}),"\n",(0,i.jsx)(n.h3,{id:"phase-list",children:"Phase list"}),"\n",(0,i.jsx)(n.p,{children:"The list of phases that an incident can go through has a crucial order. So it MUST be handled as the given list."}),"\n",(0,i.jsx)(n.p,{children:"Delete or update operations are FORBIDDEN."}),"\n",(0,i.jsx)(n.p,{children:'To "change" a phase list, a new one must be created. The old one must be kept. For this mechanic the lists are structured in generations. All references to phases MUST include their generation to ensure correct references.'}),"\n",(0,i.jsxs)(n.p,{children:["To reference a single phase a ",(0,i.jsx)(n.code,{children:"PhaseReference"})," MUST include a generation and an order field. This MAY be used to reference a single generation too."]}),"\n",(0,i.jsx)(n.h3,{id:"labels",children:"Labels"}),"\n",(0,i.jsx)(n.p,{children:"Labels are identifying metadata to components. They do not represent a resource or sub resource of any kind. They are designed as non system critical pieces of information, mainly intended for human consumption."}),"\n",(0,i.jsx)(n.p,{children:"Labels are simple key/value pairs attached to components, categorizing them dynamically."}),"\n",(0,i.jsx)(n.h3,{id:"impact",children:"Impact"}),"\n",(0,i.jsx)(n.p,{children:"An impact defines the relation between an incident and a component. A component can be affected by multiple incidents and an incident can affect multiple components. Each of these impacts can have a different type depending on the incident and component, like for example connectivity or performance issues."}),"\n",(0,i.jsx)(n.p,{children:"To reflect this, each component and incident can have a list of impacts, stating the type of impact and a reference to the incident or component, it refers to."}),"\n",(0,i.jsxs)(n.p,{children:["Furthermore, a ",(0,i.jsx)(n.code,{children:"SeverityValue"})," MUST be supplied to the ",(0,i.jsx)(n.code,{children:"Impact"})," when referenced by a ",(0,i.jsx)(n.code,{children:"Component"}),", to gauge the impact's severity on that component."]}),"\n",(0,i.jsx)(n.h3,{id:"severity",children:"Severity"}),"\n",(0,i.jsxs)(n.p,{children:["A severity contains a name, that MUST be unique and will be used as identifier. The ",(0,i.jsx)(n.code,{children:"SeverityValue"})," marks the upper boundary of the severity."]}),"\n",(0,i.jsxs)(n.p,{children:["The severity's value range is calculated by taking the previous severity's (",(0,i.jsx)(n.code,{children:"SeverityA"}),") value and adding 1 to obtain the starting point and taking the current severity's (SeverityB) value as the end point. These limits are inclusive."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-acsii",children:"0, ... , SeverityA.value, SeverityA.value, + 1, ... , SeverityB.value - 1, SeverityB.value, SeverityB.value + 1, ... , 100\n |<------------range of severity values for SeverityB-------------\x3e|\n"})}),"\n",(0,i.jsx)(n.p,{children:"Example:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'[\n {\n "displayName": "operational",\n "value": 25\n },\n {\n "displayName": "maintenance",\n "value": 50\n },\n {\n "displayName": "limited",\n "value": 75\n },\n {\n "displayName": "broken",\n "value": 100\n }\n]\n'})}),"\n",(0,i.jsx)(n.p,{children:"This means:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"operational from 0 to 25"}),"\n",(0,i.jsx)(n.li,{children:"maintenance from 26 to 50"}),"\n",(0,i.jsx)(n.li,{children:"limited from 51 to 75"}),"\n",(0,i.jsx)(n.li,{children:"broken from 76 to 100."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"A value of 100 is the maximum of the severity value."}),"\n",(0,i.jsxs)(n.p,{children:["A severity with the value of 100 MUST always be supplied. This is the highest severity for the system. If no severity with a value of 100 exists, e.g. the highest severity value is set at 90, an ",(0,i.jsx)(n.code,{children:"Impact"})," with a higher ",(0,i.jsx)(n.code,{children:"SeverityValue"})," WILL be considered to be an ",(0,i.jsx)(n.em,{children:"unkown"})," severity."]}),"\n",(0,i.jsx)(n.h3,{id:"component-impacts",children:"Component impacts"}),"\n",(0,i.jsx)(n.p,{children:"Components list their impacts, which they are affected by, as read only. Only an incident creates an impact on a component. Components MUST only list their currently active impacts."}),"\n",(0,i.jsxs)(n.h3,{id:"return-of-post-requests",children:["Return of ",(0,i.jsx)(n.code,{children:"POST"})," requests"]}),"\n",(0,i.jsxs)(n.p,{children:["Generally ",(0,i.jsx)(n.code,{children:"POST"})," requests create new resources. These endpoints do not return the new resource, but a unique identifier to the resource e.g. an UUID."]}),"\n",(0,i.jsx)(n.p,{children:"In most cases the new resource won't be used directly after creation. Most often list calls are used. If the new resource is used directly, it can be retrieved by the returned identifier."}),"\n",(0,i.jsxs)(n.p,{children:["Payloads to POST requests SHALL NOT include ID or ",(0,i.jsx)(n.code,{children:"Incremental"})," typed fields, it lies in the responsibility of the API server to assign IDs and ",(0,i.jsx)(n.code,{children:"Incremental"}),"s to objects."]}),"\n",(0,i.jsxs)(n.h3,{id:"return-of-patch-requestes",children:["Return of ",(0,i.jsx)(n.code,{children:"PATCH"})," requestes"]}),"\n",(0,i.jsxs)(n.p,{children:["Most commonly ",(0,i.jsx)(n.code,{children:"PATCH"})," requests are used to partially or fully change a resource. These requests do not respond with the changed resource, nor an identifier."]}),"\n",(0,i.jsx)(n.p,{children:"Both the old state as well as the new state are known on the client at that point in time and if they need to load the actual recent version from the server, the identifier is already known."}),"\n",(0,i.jsxs)(n.h3,{id:"patch-vs-put-for-updating-resources",children:[(0,i.jsx)(n.code,{children:"PATCH"})," vs ",(0,i.jsx)(n.code,{children:"PUT"})," for updating resources"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"PUT"})," requests is most commonly used to update full objects, whereas ",(0,i.jsx)(n.code,{children:"PATCH"})," is used for partial updates."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"PATCH"})," is used as the default method for updating resources because it does not require the full object for an update, but does not discourage the use of the complete object."]}),"\n",(0,i.jsx)(n.h3,{id:"authentication-and-authorization",children:"Authentication and authorization"}),"\n",(0,i.jsx)(n.p,{children:"The API spec does not include either authentication (AuthN) nor authorization (AuthZ) of any kind. The API server MUST be secured by an reverse/auth proxy."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var i=t(96540);const s={},a=i.createContext(s);function r(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fe5fac7c.330500c2.js b/assets/js/fe5fac7c.330500c2.js new file mode 100644 index 0000000000..acc9bd0a8f --- /dev/null +++ b/assets/js/fe5fac7c.330500c2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2479],{47492:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>l,frontMatter:()=>o,metadata:()=>c,toc:()=>i});var r=t(74848),a=t(28453);const o={},s="Hardware Requirements",c={id:"container/deployment-examples/a/hardware",title:"Hardware Requirements",description:"TODO",source:"@site/docs/03-container/deployment-examples/a/hardware.md",sourceDirName:"03-container/deployment-examples/a",slug:"/container/deployment-examples/a/hardware",permalink:"/docs/container/deployment-examples/a/hardware",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/03-container/deployment-examples/a/hardware.md",tags:[],version:"current",frontMatter:{}},d={},i=[];function m(e){const n={h1:"h1",p:"p",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"hardware-requirements",children:"Hardware Requirements"}),"\n",(0,r.jsx)(n.p,{children:"TODO"})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(m,{...e})}):m(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>c});var r=t(96540);const a={},o=r.createContext(a);function s(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ff45c01b.31043445.js b/assets/js/ff45c01b.31043445.js new file mode 100644 index 0000000000..6c4a10ee16 --- /dev/null +++ b/assets/js/ff45c01b.31043445.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6290],{41958:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var t=s(74848),r=s(28453);const i={title:"SCS RFC2119 Keyword Test Guide",type:null,status:"Draft",track:"Global"},o=void 0,a={id:"development/tests/rfc2119-keyword-test-guide",title:"SCS RFC2119 Keyword Test Guide",description:"Introduction",source:"@site/contributor-docs/development/tests/rfc2119-keyword-test-guide.md",sourceDirName:"development/tests",slug:"/development/tests/rfc2119-keyword-test-guide",permalink:"/contributor-docs/development/tests/rfc2119-keyword-test-guide",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{title:"SCS RFC2119 Keyword Test Guide",type:null,status:"Draft",track:"Global"},sidebar:"devDocs",previous:{title:"Developer documentation",permalink:"/contributor-docs/development/"},next:{title:"SCS Conformance Test Implementation Guide",permalink:"/contributor-docs/development/tests/test-implementation-guide"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"1. Understanding SCS Standards and RFC2119 Keywords",id:"1-understanding-scs-standards-and-rfc2119-keywords",level:2},{value:"2. Interpreting RFC2119 Keywords in the Context of SCS",id:"2-interpreting-rfc2119-keywords-in-the-context-of-scs",level:2},{value:"3. Channels for Output in Test Scripts",id:"3-channels-for-output-in-test-scripts",level:2},{value:"4. Compliance and Test Passing Criteria",id:"4-compliance-and-test-passing-criteria",level:2},{value:"Examples",id:"examples",level:2},{value:"5.1 Example: Standards Document using RFC2119 Keywords",id:"51-example-standards-document-using-rfc2119-keywords",level:3},{value:"Web Server Installation Standard",id:"web-server-installation-standard",level:3},{value:"Purpose",id:"purpose",level:4},{value:"Requirements",id:"requirements",level:4},{value:"Compliance",id:"compliance",level:4},{value:"5.2 Example: Test script using RFC2119 Keywords",id:"52-example-test-script-using-rfc2119-keywords",level:3}];function c(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsxs)(n.p,{children:["The development and validation of tests within the Sovereign Cloud Stack (SCS) is a critical endeavor aimed at ensuring that cloud technologies meet the highest standards of interoperability, security and sovereignty. This process is not only about aligning with the technical specifications and standards set by SCS but also about safeguarding the principles of open-source collaboration and the autonomy of cloud services. By thoroughly crafting tests that adhere to the stringent requirement levels as indicated by ",(0,t.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2119",children:"RFC2119 keywords"}),", we ensure that the infrastructure, services and their integrations within the SCS ecosystem are robust, secure and sovereign."]}),"\n",(0,t.jsx)(n.p,{children:"This detailed process is crucial for stakeholders seeking to develop or utilize sovereign cloud services that are reliable, compliant and capable of standing up to the demands of modern cloud computing. It serves as an indispensable guide for developers, operators and policymakers who are involved in the creation, deployment and governance of cloud services within SCS. By understanding and implementing the standards and tests defined by the SCS, professionals can contribute to a cloud infrastructure that is not only technologically advanced but also aligns with the core values of sovereignty and open-source ethics."}),"\n",(0,t.jsx)(n.p,{children:"Therefore, for individuals tasked with writing tests and defining standards within SCS, this document is particularly important. It serves as a base with guidelines on how to use and understand RFC2119 keywords in the context of SCS. Its insights are crucial for anyone from technical architects to regulatory bodies within the SCS ecosystem, underlining the foundational principles necessary for achieving a sovereign cloud environment."}),"\n",(0,t.jsx)(n.h2,{id:"1-understanding-scs-standards-and-rfc2119-keywords",children:"1. Understanding SCS Standards and RFC2119 Keywords"}),"\n",(0,t.jsx)(n.p,{children:"SCS standards use RFC2119 keywords like:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"MUST"})," (same as ",(0,t.jsx)(n.strong,{children:"REQUIRED"}),", ",(0,t.jsx)(n.strong,{children:"SHALL"}),"),"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"MUST NOT"})," (same as ",(0,t.jsx)(n.strong,{children:"SHALL NOT"}),"),"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"SHOULD"})," (same as ",(0,t.jsx)(n.strong,{children:"RECOMMENDED"}),"),"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"SHOULD NOT"})," (same as ",(0,t.jsx)(n.strong,{children:"NOT RECOMMENDED"}),"),"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"MAY"})," (same as ",(0,t.jsx)(n.strong,{children:"OPTIONAL"}),")"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"to define requirements for SCS-compatible IaaS and KaaS resources. These standards & tests are crucial for ensuring interoperability and sovereignty in cloud services, as they are built on open-source components such as Kubernetes and OpenStack."}),"\n",(0,t.jsxs)(n.p,{children:["To ensure readability and comprehensibility, only the main keywords ",(0,t.jsx)(n.strong,{children:"MUST"}),", ",(0,t.jsx)(n.strong,{children:"MUST NOT"}),", ",(0,t.jsx)(n.strong,{children:"SHOULD"}),", ",(0,t.jsx)(n.strong,{children:"SHOULD NOT"})," and ",(0,t.jsx)(n.strong,{children:"MAY"})," are referred to below."]}),"\n",(0,t.jsx)(n.h2,{id:"2-interpreting-rfc2119-keywords-in-the-context-of-scs",children:"2. Interpreting RFC2119 Keywords in the Context of SCS"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"MUST and MUST NOT"}),": These are binary and straightforward to test. Compliance or\nnon-compliance directly affects whether the standard is satisfied. For visualization, fulfilled\nrequirements could be marked in green, unfulfilled ones in red."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"SHOULD and SHOULD NOT"}),": These represent recommendations. While fulfilling these do\nnot directly affect standard compliance, it is advised for future-proofing against\npotential standard evolutions. Non-compliance could be visualized in yellow, possibly\nwith a valid reason for non-fulfillment."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"MAY"}),": This is more flexible and could be used to provide additional\ninformation or best practices. Their impact on compliance is not as direct as ",(0,t.jsx)(n.strong,{children:"MUST"})," or\n",(0,t.jsx)(n.strong,{children:"SHOULD"})," categories. These can be marked as blue."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"3-channels-for-output-in-test-scripts",children:"3. Channels for Output in Test Scripts"}),"\n",(0,t.jsx)(n.p,{children:"In test scripts, different channels are used to convey information of different importance to the user. These channels are based on the ubiquitous and de-facto standard logging levels of common logging libraries in scripting and programming languages, in particular Python: DEBUG, INFO, WARNING, ERROR and CRITICAL."}),"\n",(0,t.jsx)(n.p,{children:"Alignment of the RFC2119 keywords with specific channels in test scripts:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"MUST"})," and ",(0,t.jsx)(n.strong,{children:"MUST NOT"})," lead to the ERROR channel for failed tests"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"SHOULD"})," and ",(0,t.jsx)(n.strong,{children:"SHOULD NOT"})," lead to the WARNING channel, the test is still passed"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"MAY"})," leads to the INFO channel, the test is still passed"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"However, the CRITICAL level is not directly associated with any of the RFC2119 keywords; it is instead used to signify that a test was unable to complete or was interrupted due to various issues, such as runtime failures."}),"\n",(0,t.jsx)(n.h2,{id:"4-compliance-and-test-passing-criteria",children:"4. Compliance and Test Passing Criteria"}),"\n",(0,t.jsxs)(n.p,{children:["A test is considered to pass if and only if it doesn't produce any messages on the\nERROR nor the CRITICAL channel. The presence of warnings or informational items from\n",(0,t.jsx)(n.strong,{children:"SHOULD"})," and ",(0,t.jsx)(n.strong,{children:"MAY"})," categories do not directly impact the pass/fail status but is\nimportant for overall quality and compatibility with future standards."]}),"\n",(0,t.jsx)(n.p,{children:"That means a test can have one of three results:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"fail: if it has at least one message on ERROR"}),"\n",(0,t.jsx)(n.li,{children:"DNF (did not finish): if it has no message on ERROR, but at least one on CRITICAL"}),"\n",(0,t.jsx)(n.li,{children:"pass: otherwise"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["In addition, a test ",(0,t.jsx)(n.strong,{children:"MUST"})," exit with a non-zero exit code (e.g., via ",(0,t.jsx)(n.code,{children:"sys.exit(\u2026)"}),") if there are any ERROR or CRITICAL messages, thus signaling a failure to meet a standard."]}),"\n",(0,t.jsxs)(n.p,{children:["In test scripts it is a ",(0,t.jsx)(n.strong,{children:"MUST"})," to redirect all channel outputs to standard error (",(0,t.jsx)(n.strong,{children:"stderr"}),"), which aligns with Python's default logging behavior. The format which ",(0,t.jsx)(n.strong,{children:"MUST"})," be used is ",(0,t.jsx)(n.strong,{children:"CHANNEL: MESSAGE"}),", where ",(0,t.jsx)(n.strong,{children:"CHANNEL"})," represents the log level (e.g., DEBUG, INFO, WARNING, ERROR, CRITICAL) and ",(0,t.jsx)(n.strong,{children:"MESSAGE"})," encapsulates the actual log message."]}),"\n",(0,t.jsx)(n.p,{children:"For instance, when logging an INFO regarding a Kubernetes cluster, the format on the command line should be like this:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"INFO: Checking cluster specified by context 'my-cluster' in /path/to/.kube/config.\n"})}),"\n",(0,t.jsx)(n.p,{children:"This example adheres to our proposed format by clearly indicating the severity level (INFO) followed by the specific message intended for the user or developer."}),"\n",(0,t.jsx)(n.h2,{id:"examples",children:"Examples"}),"\n",(0,t.jsx)(n.h3,{id:"51-example-standards-document-using-rfc2119-keywords",children:"5.1 Example: Standards Document using RFC2119 Keywords"}),"\n",(0,t.jsx)(n.p,{children:'The following example of a fictitious document for a "Web Server Installation Standard"\nis intended to illustrate the use of RFC2119 keywords in connection with the creation of\nSCS-compliant standard documents.'}),"\n",(0,t.jsx)(n.h3,{id:"web-server-installation-standard",children:"Web Server Installation Standard"}),"\n",(0,t.jsx)(n.h4,{id:"purpose",children:"Purpose"}),"\n",(0,t.jsx)(n.p,{children:"This document provides a concise set of requirements for installing a secure web server."}),"\n",(0,t.jsx)(n.h4,{id:"requirements",children:"Requirements"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Web Server Software: Apache HTTP Server 2.4.x or Nginx 1.18.x ",(0,t.jsx)(n.strong,{children:"MUST"})," be installed. No\nother web server software versions or types are permitted."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Operating System: The server ",(0,t.jsx)(n.strong,{children:"MUST"})," run on an OS that receives current security updates.\nUnsupported versions ",(0,t.jsx)(n.strong,{children:"MUST NOT"})," be used."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["TLS Configuration: TLS 1.2 or higher ",(0,t.jsx)(n.strong,{children:"MUST"})," be enabled for all connections. SSL and\nearlier TLS versions ",(0,t.jsx)(n.strong,{children:"MUST NOT"})," be used."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Security Patches: The web server and OS ",(0,t.jsx)(n.strong,{children:"MUST"})," be kept up-to-date with security patches.\nCritical patches ",(0,t.jsx)(n.strong,{children:"SHOULD"})," be applied within 48 hours of release."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Firewall Setup: The firewall ",(0,t.jsx)(n.strong,{children:"SHOULD"})," be configured to allow only necessary ports,\nsuch as 80 (HTTP) and 443 (HTTPS). All unnecessary ports ",(0,t.jsx)(n.strong,{children:"SHOULD NOT"})," be open."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Backup Plan: Regular backups of the web server data ",(0,t.jsx)(n.strong,{children:"MAY"})," be performed, and it is\nrecommended that backup integrity checks are conducted to ensure recoverability."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"compliance",children:"Compliance"}),"\n",(0,t.jsx)(n.p,{children:"Failure to comply with these requirements results in the web server being\nconsidered non-compliant with the organization's security policies."}),"\n",(0,t.jsx)(n.h3,{id:"52-example-test-script-using-rfc2119-keywords",children:"5.2 Example: Test script using RFC2119 Keywords"}),"\n",(0,t.jsx)(n.p,{children:'The following example of a fictitious code for a test of "process_requirements"\nis intended to illustrate the use of RFC2119 keywords in connection with the\ncreation of SCS-compliant standard tests.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'\nimport logging\nlogging.basicConfig(level=logging.DEBUG)\nlogger = logging.getLogger(__name__)\n\ndef process_requirements(var1, var2):\n try:\n # debug log for input variables\n logger.debug(f"Received input var1: {var1}, var2: {var2}")\n\n # example of an error case (equivalent to MUST and MUST NOT)\n if var1 < 0:\n logger.error("var1 must be positive")\n elif var1 > 100:\n logger.error("var1 must not exceed 100")\n\n # add debug log to confirm evaluation of var1\n logger.debug(f"var1 evaluated: {var1 > 0 and var1 < 100}")\n\n # example of a warning case (equivalent to SHOULD and SHOULD NOT)\n if var2 < 10:\n logger.warning("var2 should be at least 10 for optimal performance")\n elif var2 > 50:\n logger.warning("var2 should not exceed 50 for optimal performance")\n\n # add debug log to confirm evaluation of var2\n logger.debug(f"var2 evaluated: {var2 > 10 and var2 < 50}")\n\n # example of an informative case (equivalent to MAY)\n if var1 + var2 < 100:\n logger.info("Combination is within recommended range")\n else:\n logger.info("Combination exceeds the recommended range but may still proceed")\n\n # debug log before completing the process\n logger.debug(f"Final evaluation before completion: var1 + var2 = {var1 + var2}")\n\n # success log\n logger.debug("Process completed successfully")\n\n except ValueError as e:\n # debug log before raising a critical error\n logger.debug("Encountered a critical error about to log", exc_info=True)\n logger.critical(f"Process failed: {e}", exc_info=True)\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": The DEBUG channel is used for additional information for developers to better understand a process and does not apply to RFC2119 keywords."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fff06078.cdcf3986.js b/assets/js/fff06078.cdcf3986.js new file mode 100644 index 0000000000..b81b2ea275 --- /dev/null +++ b/assets/js/fff06078.cdcf3986.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2710],{38186:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>i,default:()=>l,frontMatter:()=>c,metadata:()=>a,toc:()=>d});var o=t(74848),s=t(28453);const c={},i="K3S",a={id:"iaas/guides/concept-guide/components/k3s",title:"K3S",description:"Lifecycle Management of K3S in OSISM",source:"@site/docs/02-iaas/guides/concept-guide/components/k3s.md",sourceDirName:"02-iaas/guides/concept-guide/components",slug:"/iaas/guides/concept-guide/components/k3s",permalink:"/docs/iaas/guides/concept-guide/components/k3s",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/concept-guide/components/k3s.md",tags:[],version:"current",frontMatter:{},sidebar:"docs",previous:{title:"Ironic",permalink:"/docs/iaas/guides/concept-guide/components/ironic"},next:{title:"Keycloak",permalink:"/docs/iaas/guides/concept-guide/components/keycloak"}},r={},d=[{value:"Lifecycle Management of K3S in OSISM",id:"lifecycle-management-of-k3s-in-osism",level:2}];function u(e){const n={h1:"h1",h2:"h2",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"k3s",children:"K3S"}),"\n",(0,o.jsx)(n.h2,{id:"lifecycle-management-of-k3s-in-osism",children:"Lifecycle Management of K3S in OSISM"})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var o=t(96540);const s={},c=o.createContext(s);function i(e){const n=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fff9aecb.bf1dc315.js b/assets/js/fff9aecb.bf1dc315.js new file mode 100644 index 0000000000..0c4e80be3b --- /dev/null +++ b/assets/js/fff9aecb.bf1dc315.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3649],{93044:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>o,contentTitle:()=>r,default:()=>p,frontMatter:()=>d,metadata:()=>a,toc:()=>u});var s=t(74848),n=t(28453);const d={sidebar_label:"Upgrade Guide",sidebar_position:20},r="Upgrade Guide",a={id:"iaas/guides/upgrade-guide/index",title:"Upgrade Guide",description:"In the examples, the pull of images (if supported by a role) is always run first. While",source:"@site/docs/02-iaas/guides/upgrade-guide/index.md",sourceDirName:"02-iaas/guides/upgrade-guide",slug:"/iaas/guides/upgrade-guide/",permalink:"/docs/iaas/guides/upgrade-guide/",draft:!1,unlisted:!1,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/docs/02-iaas/guides/upgrade-guide/index.md",tags:[],version:"current",sidebarPosition:20,frontMatter:{sidebar_label:"Upgrade Guide",sidebar_position:20},sidebar:"docs",previous:{title:"Testbed",permalink:"/docs/iaas/guides/deploy-guide/examples/testbed"},next:{title:"Manager",permalink:"/docs/iaas/guides/upgrade-guide/manager"}},o={},u=[];function c(e){const i={h1:"h1",p:"p",...(0,n.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h1,{id:"upgrade-guide",children:"Upgrade Guide"}),"\n",(0,s.jsx)(i.p,{children:"In the examples, the pull of images (if supported by a role) is always run first. While\nthis is optional, it is recommended to speed up the execution of the upgrade action in\nthe second step. This significantly reduces the times required for the restart from a\nservice."})]})}function p(e={}){const{wrapper:i}={...(0,n.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,i,t)=>{t.d(i,{R:()=>r,x:()=>a});var s=t(96540);const n={},d=s.createContext(n);function r(e){const i=s.useContext(d);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),s.createElement(d.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/main.526c55e4.js b/assets/js/main.526c55e4.js new file mode 100644 index 0000000000..47848f7082 --- /dev/null +++ b/assets/js/main.526c55e4.js @@ -0,0 +1,2 @@ +/*! For license information please see main.526c55e4.js.LICENSE.txt */ +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[8792],{35947:(e,t,n)=>{"use strict";n.d(t,{A:()=>p});n(96540);var a=n(53259),o=n.n(a),s=n(84054);const r={"0047ab5d":[()=>n.e(5058).then(n.bind(n,4475)),"@site/docs/02-iaas/guides/configuration-guide/services/index.md",4475],"0050251a":[()=>n.e(1945).then(n.bind(n,55146)),"@site/contributor-docs/index.md",55146],"0121636f":[()=>n.e(5752).then(n.bind(n,95824)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/project-manager.md",95824],"012688b3":[()=>n.e(5251).then(n.bind(n,90669)),"@site/docs/02-iaas/guides/concept-guide/hardware-bom.md",90669],"013c29c1":[()=>n.e(923).then(n.bind(n,57919)),"@site/docs/04-operating-scs/components/monitoring/docs/zuul.md",57919],"01a85c17":[()=>Promise.all([n.e(1869),n.e(8209)]).then(n.bind(n,69158)),"@theme/BlogTagsListPage",69158],"03412b54":[()=>n.e(9382).then(n.bind(n,11179)),"@site/community/tools/github/dco-and-licenses.md",11179],"03babb4a":[()=>n.e(2294).then(n.bind(n,85657)),"@site/community/tools/github/tips-and-tricks.md",85657],"03c8668f":[()=>n.e(4507).then(n.bind(n,71141)),"@site/standards/ops/scs-0412.md",71141],"04437fec":[()=>n.e(9075).then(n.bind(n,90697)),"@site/standards/scs-0114-v1-volume-type-standard.md",90697],"0476f709":[()=>n.e(344).then(n.bind(n,698)),"@site/standards/scs-0215-v1-robustness-features.md",698],"04fe2bfd":[()=>n.e(2106).then(n.bind(n,9142)),"@site/blog/2022-10-28-first-blog-post.md?truncated=true",9142],"059c4264":[()=>n.e(7990).then(n.t.bind(n,80233,19)),"~docs/default/category-docs-docs-category-status-page-api-7a3.json",80233],"05e7973d":[()=>n.e(9823).then(n.bind(n,87699)),"@site/docs/02-iaas/guides/configuration-guide/commons/sshconfig.md",87699],"061d8128":[()=>n.e(1009).then(n.bind(n,6056)),"@site/standards/scs-0100-v3-flavor-naming.md",6056],"066abe51":[()=>n.e(1351).then(n.bind(n,25401)),"@site/docs/02-iaas/guides/concept-guide/components/sonic.md",25401],"0683500c":[()=>n.e(9866).then(n.bind(n,19378)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/application-credentials.md",19378],"070e71f0":[()=>n.e(7255).then(n.bind(n,32966)),"@site/docs/02-iaas/guides/upgrade-guide/ceph.md",32966],"07d3bac7":[()=>n.e(458).then(n.bind(n,16775)),"@site/standards/scs-0211-v1-kaas-default-storage-class.md",16775],"08602342":[()=>n.e(550).then(n.t.bind(n,82866,19)),"~docs/default/category-docs-docs-category-container-registry-6f4.json",82866],"093291a8":[()=>n.e(1276).then(n.bind(n,760)),"@site/standards/ops/scs-0411.md",760],"096c51c8":[()=>n.e(2544).then(n.bind(n,14886)),"@site/community/contribute/linting-guide.md",14886],"09adb968":[()=>n.e(6148).then(n.bind(n,38170)),"@site/docs/04-operating-scs/03-incident-management/index.md",38170],"09ba26e2":[()=>n.e(9244).then(n.bind(n,52181)),"@site/docs/02-iaas/guides/deploy-guide/index.md",52181],"09cf625e":[()=>n.e(3767).then(n.bind(n,90408)),"@site/docs/04-operating-scs/overview.md",90408],"0a757274":[()=>n.e(8296).then(n.bind(n,81400)),"@site/docs/02-iaas/overview/knowledge.md",81400],"0bb6d954":[()=>n.e(7479).then(n.bind(n,20462)),"@site/docs/02-iaas/guides/concept-guide/components/netdata.md",20462],"0bcc5672":[()=>n.e(1085).then(n.bind(n,2033)),"@site/docs/03-container/deployment-examples/a/software.md",2033],"0cb1d654":[()=>n.e(6182).then(n.bind(n,54896)),"@site/docs/04-operating-scs/components/monitoring/docs/overview.md",54896],"0d2860b1":[()=>n.e(7148).then(n.bind(n,60874)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/image-manager/update.md",60874],"0dfeccb2":[()=>n.e(4342).then(n.bind(n,24179)),"@site/standards/scs-0410-v1-gnocchi-as-metering-database.md",24179],"0e4c395f":[()=>n.e(3384).then(n.bind(n,75486)),"@site/docs/04-operating-scs/components/monitoring/docs/scs-deployment.md",75486],"0ea173ba":[()=>n.e(5341).then(n.bind(n,85377)),"@site/standards/certification/overview.md",85377],"0f0de498":[()=>n.e(5013).then(n.bind(n,47031)),"@site/docs/02-iaas/guides/configuration-guide/openstack/designate.md",47031],"1109f10b":[()=>n.e(3605).then(n.bind(n,91128)),"@site/standards/scs-0110-v1-ssd-flavors.md",91128],"119c53e5":[()=>n.e(8407).then(n.bind(n,91136)),"@site/docs/02-iaas/guides/configuration-guide/commons/user.md",91136],"1276f6ab":[()=>n.e(4684).then(n.bind(n,35458)),"@site/standards/scs-0411-v1-publishing_method_for_metering_data.md",35458],"14c1041d":[()=>n.e(5019).then(n.t.bind(n,38799,19)),"~blog/default/blog-tags-howto-248-list.json",38799],"14eb3368":[()=>Promise.all([n.e(1869),n.e(6969)]).then(n.bind(n,34136)),"@theme/DocCategoryGeneratedIndexPage",34136],15336817:[()=>n.e(5533).then(n.bind(n,31570)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/quickstart.md",31570],"15e4a743":[()=>n.e(5609).then(n.bind(n,23427)),"@site/docs/04-operating-scs/02-monitoring/index.md",23427],"16c50622":[()=>n.e(4712).then(n.bind(n,36661)),"@site/docs/02-iaas/guides/configuration-guide/validations/index.md",36661],"1722e234":[()=>n.e(1255).then(n.bind(n,94409)),"@site/community/cloud-resources/cloud-resources.md",94409],17896441:[()=>Promise.all([n.e(1869),n.e(3498),n.e(8401)]).then(n.bind(n,46011)),"@theme/DocItem",46011],"178df98e":[()=>n.e(8029).then(n.bind(n,12218)),"@site/standards/ops/index.md",12218],"184e5ead":[()=>n.e(988).then(n.bind(n,20737)),"@site/standards/iaas/scs-0102.md",20737],"193dc870":[()=>n.e(8220).then(n.bind(n,33046)),"@site/docs/02-iaas/guides/concept-guide/components/teleport.md",33046],"1967361e":[()=>n.e(4485).then(n.bind(n,41434)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/sandbox-manager.md",41434],"19afbcc8":[()=>n.e(4840).then(n.bind(n,75134)),"@site/docs/01-getting-started/overview.md",75134],"19cb43cd":[()=>n.e(1572).then(n.bind(n,88211)),"@site/docs/03-container/components/container-registry/docs/upgrade.md",88211],"19e9bde5":[()=>n.e(4175).then(n.bind(n,50594)),"@site/docs/04-operating-scs/components/monitoring/docs/quickstart.md",50594],"19f6a518":[()=>n.e(3444).then(n.bind(n,49476)),"@site/community/mission-statement.md",49476],"1a4e3797":[()=>Promise.all([n.e(1869),n.e(2138)]).then(n.bind(n,41283)),"@theme/SearchPage",41283],"1bc22123":[()=>n.e(4111).then(n.bind(n,78427)),"@site/docs/06-releases/ReleaseX.md",78427],"1c091541":[()=>n.e(1153).then(n.t.bind(n,52945,19)),"/home/runner/work/docs/docs/.docusaurus/docusaurus-plugin-content-blog/default/plugin-route-context-module-100.json",52945],"1c894279":[()=>n.e(1804).then(n.bind(n,67490)),"@site/standards/scs-0001-v1-sovereign-cloud-standards.md",67490],"1ca0f8e7":[()=>n.e(7810).then(n.bind(n,62654)),"@site/docs/03-container/components/container-registry/docs/scs-deployment.md",62654],"1df93b7f":[()=>Promise.all([n.e(1869),n.e(4583)]).then(n.bind(n,68198)),"@site/src/pages/index.tsx",68198],"1e818dbe":[()=>n.e(1335).then(n.bind(n,33168)),"@site/community/tools/nextcloud.md",33168],"1f34ee25":[()=>n.e(3894).then(n.bind(n,6031)),"@site/community/cloud-resources/wavestack.md",6031],"20da611c":[()=>n.e(7491).then(n.bind(n,57432)),"@site/docs/04-operating-scs/components/monitoring/docs/k3s.md",57432],"2163574d":[()=>n.e(9401).then(n.t.bind(n,85505,19)),"~docs/default/category-docs-docs-category-components-2-d21.json",85505],"22aa5ce0":[()=>n.e(6910).then(n.bind(n,34707)),"@site/standards/ops/scs-0403.md",34707],"23cd166f":[()=>n.e(1822).then(n.bind(n,95439)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster.md",95439],"23d0e2bb":[()=>n.e(6323).then(n.bind(n,17202)),"@site/standards/iaas/scs-0114.md",17202],"23e62f09":[()=>n.e(8966).then(n.bind(n,9324)),"@site/standards/iam/scs-0300.md",9324],"247783bb":[()=>n.e(5548).then(n.t.bind(n,61966,19)),"/home/runner/work/docs/docs/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",61966],"25cf6706":[()=>n.e(7104).then(n.bind(n,33166)),"@site/docs/02-iaas/guides/configuration-guide/openstack/octavia.md",33166],"26bc5a46":[()=>n.e(2914).then(n.bind(n,28114)),"@site/docs/02-iaas/guides/upgrade-guide/docker.md",28114],"26dd306b":[()=>n.e(2342).then(n.bind(n,31219)),"@site/docs/02-iaas/guides/other-guides/index.md",31219],"27f24dfd":[()=>n.e(4132).then(n.bind(n,12053)),"@site/standards/scs-0214-v1-k8s-node-distribution.md",12053],"287cd167":[()=>n.e(3043).then(n.bind(n,29239)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart.md",29239],"2886628e":[()=>n.e(7778).then(n.bind(n,88309)),"@site/community/tools/github/branchprotection.md",88309],"28d842ee":[()=>n.e(3405).then(n.bind(n,4368)),"@site/standards/scs-0112-v1-sonic.md",4368],29331985:[()=>n.e(1349).then(n.t.bind(n,47946,19)),"~docs/default/category-docs-docs-category-iaas-layer-373.json",47946],"29c2cfba":[()=>n.e(8547).then(n.bind(n,6361)),"@site/community/contribute/doc-files-structure-guide.md",6361],"2abb9c6f":[()=>n.e(6372).then(n.bind(n,12629)),"@site/docs/02-iaas/guides/concept-guide/components/prometheus.md",12629],"2cc9d448":[()=>n.e(3574).then(n.bind(n,3389)),"@site/docs/06-releases/Release6.md",3389],"2ce1dccd":[()=>n.e(1026).then(n.bind(n,48143)),"@site/docs/02-iaas/components/image-manager/index.md",48143],"2d071e49":[()=>n.e(953).then(n.bind(n,16539)),"@site/docs/04-operating-scs/components/monitoring/docs/kaas.md",16539],"2d3bf848":[()=>n.e(1468).then(n.t.bind(n,71761,19)),"~docs/community/category-community-community-category-contribute-to-docs-dbc.json",71761],"2ee7a08a":[()=>n.e(5658).then(n.bind(n,87815)),"@site/docs/02-iaas/guides/concept-guide/components/clusterapi.md",87815],"306a8c6c":[()=>n.e(3867).then(n.t.bind(n,8482,19)),"~docs/community/version-current-metadata-prop-751.json",8482],"320ccb30":[()=>n.e(7677).then(n.bind(n,60032)),"@site/docs/04-operating-scs/components/monitoring/docs/oauth.md",60032],"32227eef":[()=>n.e(3429).then(n.bind(n,40710)),"@site/standards/scs-0003-v1-sovereign-cloud-standards-yaml.md",40710],"32dcd940":[()=>n.e(86).then(n.bind(n,57446)),"@site/docs/02-iaas/guides/configuration-guide/openstack/placement.md",57446],"343a1afc":[()=>n.e(8965).then(n.bind(n,46486)),"@site/docs/04-operating-scs/06-logging/index.md",46486],"34c3e4b2":[()=>n.e(163).then(n.bind(n,10929)),"@site/standards/iaas/scs-0115.md",10929],"35b359a4":[()=>Promise.all([n.e(1869),n.e(7683)]).then(n.bind(n,94564)),"@site/docs/02-iaas/guides/other-guides/testbed.mdx",94564],"35fbae7a":[()=>n.e(1617).then(n.bind(n,82547)),"@site/community/cloud-resources/plusserver-gx-scs.md",82547],"36c47bdd":[()=>n.e(9766).then(n.bind(n,83554)),"@site/community/collaboration/team-ops.md",83554],"36f749d2":[()=>n.e(4602).then(n.bind(n,99819)),"@site/docs/04-operating-scs/04-audits/index.md",99819],"37a5cb6b":[()=>n.e(1384).then(n.bind(n,72444)),"@site/standards/ops/scs-0402.md",72444],"38b583d2":[()=>n.e(3012).then(n.bind(n,50510)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/Upgrade-Guide.md",50510],"38c9ef35":[()=>n.e(3131).then(n.bind(n,44945)),"@site/standards/global/index.md",44945],"3a1d878d":[()=>n.e(8031).then(n.bind(n,81813)),"@site/docs/02-iaas/guides/concept-guide/components/openstack.md",81813],"3ad2c61e":[()=>n.e(8384).then(n.bind(n,56313)),"@site/docs/02-iaas/guides/concept-guide/components/ceph.md",56313],"3bf9fbe6":[()=>n.e(3942).then(n.t.bind(n,9281,19)),"~docs/default/category-docs-docs-category-releases-ec0.json",9281],"3d19221e":[()=>n.e(3714).then(n.bind(n,70499)),"@site/docs/02-iaas/guides/configuration-guide/commons/index.md",70499],"3d23a943":[()=>n.e(1014).then(n.bind(n,60343)),"@site/standards/scs-0217-v1-baseline-cluster-security.md",60343],"3d9e0922":[()=>n.e(2069).then(n.bind(n,74463)),"@site/standards/ops/scs-0410.md",74463],"3e493f26":[()=>n.e(6029).then(n.bind(n,36278)),"@site/docs/02-iaas/overview/network.md",36278],"3f3928dc":[()=>n.e(3213).then(n.bind(n,44428)),"@site/standards/iaas/index.md",44428],"3ff13a62":[()=>n.e(5743).then(n.bind(n,24712)),"@site/docs/03-container/index.md",24712],"40d9468c":[()=>n.e(783).then(n.bind(n,63435)),"@site/docs/02-iaas/guides/other-guides/developer-guide/index.md",63435],"4129286c":[()=>n.e(9730).then(n.t.bind(n,81142,19)),"/home/runner/work/docs/docs/.docusaurus/@easyops-cn/docusaurus-search-local/default/plugin-route-context-module-100.json",81142],"41ab9761":[()=>n.e(5676).then(n.bind(n,579)),"@site/docs/04-operating-scs/07-metering/meter_configuration.md",579],"420452be":[()=>n.e(1911).then(n.bind(n,24449)),"@site/community/tools/matrix.md",24449],"42088e64":[()=>n.e(282).then(n.bind(n,40831)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments.md",40831],"421b5e65":[()=>n.e(9305).then(n.bind(n,21723)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal.md",21723],"422fff4b":[()=>n.e(6227).then(n.bind(n,60993)),"@site/standards/kaas/scs-0210.md",60993],"42b29c77":[()=>n.e(8767).then(n.bind(n,87855)),"@site/standards/global/scs-0112.md",87855],"431e6cfe":[()=>n.e(2932).then(n.bind(n,89027)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/continuous-integration.md",89027],"437bedbc":[()=>n.e(9745).then(n.bind(n,35959)),"@site/docs/06-releases/Release4.md",35959],"441ae8e9":[()=>n.e(2692).then(n.bind(n,32335)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting.md",32335],"441bd449":[()=>n.e(9851).then(n.bind(n,57660)),"@site/docs/02-iaas/guides/troubleshooting-guide/ceph.md",57660],"4468ebd1":[()=>n.e(8805).then(n.bind(n,45378)),"@site/blog/2022-10-28-first-blog-post.md",45378],"452be0ad":[()=>n.e(5546).then(n.bind(n,15225)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview.md",15225],"45bfeaeb":[()=>n.e(4257).then(n.bind(n,49648)),"@site/community/tools/zuul.md",49648],"45f4377b":[()=>n.e(1346).then(n.bind(n,94312)),"@site/docs/02-iaas/guides/deploy-guide/seed.md",94312],"477ed06d":[()=>n.e(3502).then(n.bind(n,64804)),"@site/standards/iaas/scs-0101.md",64804],49993131:[()=>n.e(8460).then(n.bind(n,3681)),"@site/docs/02-iaas/guides/other-guides/developer-guide/releases.md",3681],"49bc3785":[()=>n.e(8592).then(n.bind(n,47221)),"@site/community/hackathons/checklist.md",47221],"4a61a7c1":[()=>n.e(3705).then(n.bind(n,83252)),"@site/standards/kaas/scs-0200.md",83252],"4b015924":[()=>n.e(2076).then(n.bind(n,76480)),"@site/docs/02-iaas/guides/deploy-guide/services/network.md",76480],"4d571bd0":[()=>n.e(9226).then(n.bind(n,54209)),"@site/docs/02-iaas/guides/configuration-guide/openstack/aodh.md",54209],"4e607b99":[()=>n.e(2441).then(n.bind(n,59669)),"@site/community/tools/jitsi.md",59669],"4e6fa974":[()=>n.e(557).then(n.bind(n,36848)),"@site/standards/scs-0302-v1-domain-manager-role.md",36848],"4edc808e":[()=>Promise.all([n.e(1869),n.e(308)]).then(n.bind(n,92842)),"@site/docs/index.mdx",92842],"4f363fd8":[()=>n.e(4605).then(n.bind(n,18312)),"@site/docs/02-iaas/guides/configuration-guide/openstack/cinder.md",18312],"502adbf6":[()=>n.e(8561).then(n.bind(n,56306)),"@site/docs/02-iaas/guides/index.md",56306],50963409:[()=>n.e(8169).then(n.bind(n,18131)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/testing.md",18131],"5199876b":[()=>n.e(3008).then(n.bind(n,82756)),"@site/docs/02-iaas/guides/operations-guide/manager/get.md",82756],"526992cf":[()=>n.e(1475).then(n.bind(n,38249)),"@site/standards/scs-0103-v1-standard-flavors.md",38249],"52ac6bcf":[()=>n.e(7813).then(n.bind(n,70884)),"@site/standards/kaas/scs-0213.md",70884],"52e3f5ca":[()=>n.e(7157).then(n.t.bind(n,91177,19)),"~docs/standards/version-current-metadata-prop-751.json",91177],53596370:[()=>n.e(1421).then(n.bind(n,25552)),"@site/docs/04-operating-scs/components/status-page/docs/levels_of_consensus.md",25552],"53f25e30":[()=>n.e(332).then(n.bind(n,19995)),"@site/docs/04-operating-scs/components/monitoring/docs/infrastructure_services.md",19995],"5447d460":[()=>n.e(3881).then(n.bind(n,29181)),"@site/standards/certification/scopes-versions.md",29181],"5565c8ed":[()=>n.e(2016).then(n.bind(n,51152)),"@site/docs/02-iaas/guides/deploy-guide/examples/cloud-in-a-box.md",51152],"55e21dcd":[()=>n.e(1810).then(n.bind(n,60941)),"@site/docs/04-operating-scs/components/monitoring/docs/tracing.md",60941],"564eabfd":[()=>n.e(8752).then(n.bind(n,94181)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/harbor.md",94181],"57b63ae3":[()=>Promise.all([n.e(1869),n.e(9539)]).then(n.bind(n,53467)),"@site/docs/02-iaas/guides/configuration-guide/manager.mdx",53467],"5830dd0a":[()=>n.e(9176).then(n.bind(n,70589)),"@site/standards/standards/overview.md",70589],"589280f5":[()=>n.e(3530).then(n.bind(n,21435)),"@site/docs/02-iaas/guides/deploy-guide/services/infrastructure.md",21435],59307471:[()=>n.e(2637).then(n.bind(n,77378)),"@site/standards/kaas/scs-0211.md",77378],"5abd544f":[()=>n.e(9441).then(n.bind(n,67161)),"@site/standards/ops/scs-0401.md",67161],"5b235e06":[()=>n.e(8523).then(n.bind(n,31327)),"@site/docs/02-iaas/guides/other-guides/contributor-guide.md",31327],"5b402526":[()=>n.e(1001).then(n.bind(n,22185)),"@site/standards/scs-0002-v1-standards-docs-org.md",22185],"5b909c46":[()=>n.e(6707).then(n.bind(n,72762)),"@site/community/tools/mailinglists.md",72762],"5b9bf978":[()=>n.e(5773).then(n.bind(n,2872)),"@site/docs/02-iaas/guides/configuration-guide/self-signed-certificates.md",2872],"5bd7bc3b":[()=>n.e(643).then(n.bind(n,2380)),"@site/docs/02-iaas/guides/operations-guide/index.md",2380],"5c201b0a":[()=>n.e(2621).then(n.bind(n,95818)),"@site/docs/06-releases/Release3.md",95818],"5c2c818b":[()=>n.e(7153).then(n.bind(n,72619)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/image-manager/index.md",72619],"5cc619f0":[()=>Promise.all([n.e(1869),n.e(2049),n.e(9648)]).then(n.bind(n,41927)),"@site/community/collaboration/index.mdx",41927],"5d503a86":[()=>n.e(8777).then(n.bind(n,57946)),"@site/docs/04-operating-scs/components/automated-pentesting/overview.md",57946],"5d54de92":[()=>n.e(7299).then(n.bind(n,88366)),"@site/docs/02-iaas/guides/operations-guide/ceph.md",88366],"5e95c892":[()=>n.e(9647).then(n.bind(n,7121)),"@theme/DocsRoot",7121],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,4784)),"@generated/docusaurus.config",4784],"60fc342f":[()=>n.e(9525).then(n.bind(n,66290)),"@site/docs/02-iaas/guides/configuration-guide/commons/packages.md",66290],61171858:[()=>n.e(1400).then(n.bind(n,13943)),"@site/docs/02-iaas/guides/concept-guide/use-cases.md",13943],"62337dff":[()=>n.e(9376).then(n.bind(n,6851)),"@site/community/collaboration/team-iam.md",6851],"63c8fde6":[()=>n.e(4168).then(n.bind(n,97877)),"@site/standards/scs-0101-v1-entropy.md",97877],"640bb4cf":[()=>n.e(6358).then(n.bind(n,23243)),"@site/standards/scs-0100-w1-flavor-naming-implementation-testing.md",23243],"64f9507b":[()=>n.e(5790).then(n.bind(n,20454)),"@site/standards/iaas/scs-0110.md",20454],"653904f7":[()=>n.e(7653).then(n.bind(n,26093)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/custom-ca.md",26093],"65742e9f":[()=>n.e(5147).then(n.bind(n,96116)),"@site/docs/05-iam/SCS-example-setup-configuration-description.md",96116],"657efcba":[()=>n.e(1238).then(n.bind(n,18850)),"@site/docs/03-container/components/container-registry/docs/quickstart.md",18850],"65c1efe1":[()=>n.e(5663).then(n.bind(n,25179)),"@site/standards/kaas/scs-0212.md",25179],"65c90e53":[()=>n.e(5985).then(n.t.bind(n,69782,19)),"~docs/default/category-docs-docs-category-components-1-953.json",69782],"66dc81f9":[()=>n.e(3734).then(n.t.bind(n,61230,19)),"~docs/community/category-community-community-category-tools-e2a.json",61230],"670b12e1":[()=>n.e(3919).then(n.bind(n,22189)),"@site/docs/02-iaas/guides/operations-guide/manager/console.md",22189],67140352:[()=>n.e(3575).then(n.bind(n,12826)),"@site/docs/05-iam/domain-manager-setup-and-usage.md",12826],"67dad519":[()=>n.e(4980).then(n.bind(n,71028)),"@site/docs/02-iaas/guides/deploy-guide/provisioning.md",71028],"685813dc":[()=>n.e(1953).then(n.bind(n,73757)),"@site/docs/02-iaas/components/resource-manager.md",73757],"6875c492":[()=>Promise.all([n.e(1869),n.e(3498),n.e(5309),n.e(4813)]).then(n.bind(n,33069)),"@theme/BlogTagsPostsPage",33069],"699c0e5c":[()=>n.e(3725).then(n.bind(n,28052)),"@site/standards/scs-0111-v1-volume-type-decisions.md",28052],"69b09ea9":[()=>n.e(8462).then(n.t.bind(n,26677,19)),"~blog/default/blog-tags-community-d90.json",26677],"6a0c14a5":[()=>n.e(8834).then(n.bind(n,33285)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/flavor-manager.md",33285],"6ad9ab45":[()=>n.e(942).then(n.bind(n,20770)),"@site/standards/iaas/scs-0103.md",20770],"6bcd11f8":[()=>n.e(8502).then(n.bind(n,10332)),"@site/docs/02-iaas/guides/concept-guide/components/keycloak.md",10332],"6c33bb99":[()=>n.e(4810).then(n.bind(n,26132)),"@site/docs/02-iaas/guides/configuration-guide/ceph.md",26132],"6c4198a1":[()=>n.e(7638).then(n.bind(n,93083)),"@site/docs/02-iaas/guides/deploy-guide/bootstrap.md",93083],"6d32cafb":[()=>n.e(5978).then(n.bind(n,21052)),"@site/docs/02-iaas/guides/upgrade-guide/openstack.md",21052],"6d890b23":[()=>n.e(4331).then(n.bind(n,62699)),"@site/docs/02-iaas/guides/operations-guide/manager/task.md",62699],"6d8acf16":[()=>n.e(3374).then(n.bind(n,3938)),"@site/docs/04-operating-scs/components/monitoring/docs/tuning.md",3938],"6db2ece2":[()=>n.e(9356).then(n.bind(n,33426)),"@site/docs/02-iaas/guides/configuration-guide/inventory.md",33426],"6ddb698c":[()=>n.e(5679).then(n.bind(n,4584)),"@site/standards/kaas/scs-0217.md",4584],"6e45ed1a":[()=>n.e(4604).then(n.bind(n,20399)),"@site/docs/02-iaas/guides/configuration-guide/commons/certificates.md",20399],"6e5bfc33":[()=>n.e(2758).then(n.t.bind(n,84450,19)),"~docs/default/category-docs-docs-category-central-api-982.json",84450],"6f1c571c":[()=>n.e(8071).then(n.bind(n,28269)),"@site/docs/02-iaas/guides/deploy-guide/examples/index.md",28269],"6f4a06ca":[()=>n.e(2372).then(n.bind(n,36310)),"@site/docs/02-iaas/guides/deploy-guide/manager.md",36310],"7023f74c":[()=>n.e(4869).then(n.bind(n,398)),"@site/docs/02-iaas/components/image-manager/update.md",398],"70b53392":[()=>n.e(9110).then(n.bind(n,24139)),"@site/standards/scs-0403-v1-csp-kaas-observability-stack.md",24139],71499917:[()=>n.e(5e3).then(n.bind(n,10442)),"@site/docs/02-iaas/guides/other-guides/cloud-in-a-box.md",10442],"71acf54e":[()=>n.e(309).then(n.bind(n,87688)),"@site/docs/02-iaas/guides/concept-guide/design.md",87688],"7217b34c":[()=>n.e(6098).then(n.bind(n,67768)),"@site/docs/02-iaas/guides/configuration-guide/openstack/magnum.md",67768],"73512cb1":[()=>n.e(8897).then(n.bind(n,63259)),"@site/standards/scs-0218-v1-container-registry-for-scs-standard-implementation.md",63259],73956345:[()=>n.e(6083).then(n.bind(n,11009)),"@site/docs/02-iaas/overview/compute.md",11009],"739c0ae8":[()=>n.e(4807).then(n.bind(n,7084)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/gateway-api.md",7084],"742db51e":[()=>n.e(8781).then(n.bind(n,68777)),"@site/standards/kaas/scs-0218.md",68777],"748dce39":[()=>n.e(82).then(n.bind(n,41451)),"@site/docs/02-iaas/guides/operations-guide/openstack/keystone.md",41451],"755df717":[()=>n.e(5429).then(n.bind(n,48291)),"@site/docs/02-iaas/guides/configuration-guide/openstack/barbican.md",48291],"760c57f4":[()=>Promise.all([n.e(1869),n.e(4385)]).then(n.bind(n,83432)),"@site/docs/02-iaas/guides/deploy-guide/services/ceph.mdx",83432],"767805d3":[()=>n.e(8519).then(n.bind(n,63901)),"@site/docs/02-iaas/guides/configuration-guide/configuration-repository.md",63901],"7850b12c":[()=>n.e(675).then(n.bind(n,81008)),"@site/docs/03-container/components/container-registry/docs/persistence.md",81008],"7997867a":[()=>n.e(6985).then(n.bind(n,514)),"@site/docs/04-operating-scs/components/automated-pentesting/tools.md",514],"7aa8d561":[()=>n.e(1362).then(n.bind(n,54182)),"@site/standards/scs-0115-v1-default-rules-for-security-groups.md",54182],"7ace79c4":[()=>n.e(974).then(n.bind(n,27845)),"@site/standards/iaas/scs-0111.md",27845],"7b449e09":[()=>n.e(5123).then(n.bind(n,44222)),"@site/standards/scs-0002-v2-standards-docs-org.md",44222],"7b787d81":[()=>n.e(2257).then(n.bind(n,84387)),"@site/docs/06-releases/Release0.md",84387],"7bd33c3d":[()=>n.e(192).then(n.bind(n,98817)),"@site/community/cloud-resources/getting-started-openstack.md",98817],"7bed4829":[()=>n.e(4984).then(n.bind(n,20186)),"@site/docs/03-container/components/container-registry/docs/backup_and_restore.md",20186],"7cf96b3e":[()=>n.e(5770).then(n.bind(n,62305)),"@site/standards/scs-0113-v1-security-groups-decision-record.md",62305],"7d3935d1":[()=>n.e(2683).then(n.bind(n,69654)),"@site/docs/02-iaas/guides/user-guide/security-groups/security-groups.md",69654],"7e7cf0e4":[()=>n.e(4612).then(n.bind(n,57550)),"@site/standards/global/scs-0003.md",57550],"7ebec009":[()=>n.e(5564).then(n.bind(n,82592)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2.md",82592],"7f1a31c3":[()=>n.e(9464).then(n.bind(n,13257)),"@site/docs/06-releases/Release2.md",13257],"7fd33963":[()=>n.e(8526).then(n.bind(n,84367)),"@site/standards/kaas/scs-0216.md",84367],"8092c627":[()=>n.e(4880).then(n.bind(n,50561)),"@site/docs/02-iaas/guides/user-guide/user-data-backups.md",50561],"814f3328":[()=>n.e(7472).then(n.t.bind(n,55513,19)),"~blog/default/blog-post-list-prop-default.json",55513],83100446:[()=>n.e(3953).then(n.bind(n,87658)),"@site/docs/03-container/deployment-examples/a/index.md",87658],"8493ac52":[()=>n.e(5054).then(n.bind(n,8905)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop.md",8905],"853df457":[()=>n.e(4365).then(n.bind(n,51095)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/index.md",51095],"8679ddc4":[()=>n.e(6960).then(n.bind(n,38395)),"@site/docs/02-iaas/guides/configuration-guide/services/docker.md",38395],"86ee3414":[()=>n.e(3365).then(n.bind(n,37427)),"@site/docs/02-iaas/components/index.md",37427],87293620:[()=>n.e(4850).then(n.bind(n,58320)),"@site/community/collaboration/sig-central-api.md",58320],"88684b71":[()=>n.e(2151).then(n.bind(n,10665)),"@site/docs/02-iaas/components/flavor-manager.md",10665],"88f37d1b":[()=>n.e(6734).then(n.bind(n,87999)),"@site/docs/05-iam/intra-SCS-federation-setup-description-for-osism-doc-operations.md",87999],"89176cae":[()=>n.e(5673).then(n.bind(n,96169)),"@site/docs/07-standards/index.md",96169],"89ad43f4":[()=>n.e(2884).then(n.bind(n,56498)),"@site/docs/02-iaas/guides/deploy-guide/services/index.md",56498],"8a671cf8":[()=>n.e(4717).then(n.bind(n,92010)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node.md",92010],"8aade8b1":[()=>n.e(6305).then(n.bind(n,13637)),"@site/docs/02-iaas/guides/operations-guide/openstack/nova.md",13637],"8b8a137c":[()=>n.e(7074).then(n.bind(n,44748)),"@site/docs/02-iaas/guides/configuration-guide/network.md",44748],"8ba37aa2":[()=>n.e(3416).then(n.bind(n,13967)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/roadmap.md",13967],"8d25d5d4":[()=>n.e(4277).then(n.bind(n,81456)),"@site/contributor-docs/operations/iam/openstack-federation-via-oidc.md",81456],"8db05b07":[()=>n.e(3663).then(n.bind(n,92257)),"@site/docs/02-iaas/components/openstack-health-monitor.md",92257],"8e8909f7":[()=>n.e(9407).then(n.bind(n,98894)),"@site/docs/02-iaas/guides/configuration-guide/openstack/skyline.md",98894],"8fc094a7":[()=>n.e(6251).then(n.bind(n,79736)),"@site/docs/02-iaas/guides/operations-guide/manager/index.md",79736],"9099a3d2":[()=>n.e(6172).then(n.bind(n,73016)),"@site/community/central-services/plusserver-gx-scs.md",73016],"915e2cf4":[()=>n.e(9260).then(n.bind(n,45410)),"@site/docs/02-iaas/guides/user-guide/openstack/user-data-backups.md",45410],"9278f3d6":[()=>n.e(904).then(n.bind(n,22712)),"@site/standards/scs-0213-v1-k8s-nodes-anti-affinity.md",22712],"929c4e1b":[()=>n.e(3802).then(n.bind(n,86825)),"@site/standards/index.md",86825],"931040e8":[()=>n.e(7743).then(n.bind(n,42697)),"@site/community/contribute/styleguide.md",42697],"935f2afb":[()=>n.e(8581).then(n.t.bind(n,35610,19)),"~docs/default/version-current-metadata-prop-751.json",35610],"94298c6b":[()=>n.e(8612).then(n.t.bind(n,79844,19)),"/home/runner/work/docs/docs/.docusaurus/docusaurus-plugin-content-docs/contributor-docs/plugin-route-context-module-100.json",79844],"9490f32b":[()=>n.e(3874).then(n.bind(n,30405)),"@site/docs/02-iaas/guides/configuration-guide/openstack/glance.md",30405],"94b13e0d":[()=>n.e(9088).then(n.bind(n,27781)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/openstack-health-monitor.md",27781],"94f31572":[()=>n.e(9752).then(n.bind(n,36626)),"@site/docs/08-faq/index.mdx",36626],"950c7487":[()=>n.e(2456).then(n.bind(n,72512)),"@site/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide.md",72512],"95800b3e":[()=>n.e(5515).then(n.bind(n,76284)),"@site/docs/02-iaas/guides/concept-guide/layers.md",76284],95967863:[()=>n.e(8200).then(n.t.bind(n,13784,19)),"~docs/contributor-docs/version-current-metadata-prop-751.json",13784],"95d93785":[()=>n.e(4503).then(n.bind(n,30667)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/requirements.md",30667],"95fe5f6c":[()=>n.e(9850).then(n.bind(n,85728)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/usage.md",85728],"96f8fd49":[()=>n.e(667).then(n.bind(n,43878)),"@site/docs/02-iaas/guides/operations-guide/manager/log.md",43878],97630173:[()=>n.e(8533).then(n.bind(n,85102)),"@site/docs/02-iaas/guides/concept-guide/components/proxmox.md",85102],"97b1504a":[()=>n.e(4346).then(n.bind(n,1583)),"@site/standards/iaas/scs-0104.md",1583],"97ef9758":[()=>n.e(6529).then(n.bind(n,66034)),"@site/community/collaboration/team-iaas.md",66034],"9890ac63":[()=>n.e(1298).then(n.bind(n,74355)),"@site/standards/global/scs-0004.md",74355],"99b53e63":[()=>n.e(9579).then(n.bind(n,75861)),"@site/docs/04-operating-scs/components/status-page/docs/components.md",75861],"9a7c0197":[()=>n.e(3402).then(n.bind(n,41705)),"@site/contributor-docs/operations/iam/identity-federation-in-scs.md",41705],"9b5d9131":[()=>n.e(1427).then(n.bind(n,53321)),"@site/docs/04-operating-scs/components/central-api/poc-setup.md",53321],"9d1324c7":[()=>n.e(6568).then(n.bind(n,88862)),"@site/standards/scs-0100-v1-flavor-naming.md",88862],"9d187656":[()=>n.e(6805).then(n.bind(n,9930)),"@site/docs/04-operating-scs/components/status-page/docs/overview.md",9930],"9d49bc50":[()=>n.e(5875).then(n.bind(n,48963)),"@site/docs/02-iaas/guides/other-guides/developer-guide/zuul.md",48963],"9e4087bc":[()=>n.e(2711).then(n.bind(n,89331)),"@theme/BlogArchivePage",89331],"9f356e5b":[()=>n.e(1844).then(n.bind(n,24901)),"@site/docs/02-iaas/overview/architecture.md",24901],"9fb1f91e":[()=>n.e(6088).then(n.t.bind(n,18909,19)),"~docs/default/category-docs-docs-category-k-8-s-cluster-api-provider-7d5.json",18909],a0b1bbd7:[()=>n.e(7984).then(n.bind(n,64208)),"@site/docs/06-releases/Release5.md",64208],a12f05ab:[()=>n.e(3453).then(n.bind(n,71290)),"@site/docs/02-iaas/guides/operations-guide/openstack/cinder.md",71290],a15c4cb6:[()=>n.e(1290).then(n.bind(n,69149)),"@site/standards/scs-0412-v1-metering-json.md",69149],a2317717:[()=>n.e(3400).then(n.bind(n,74782)),"@site/docs/02-iaas/guides/configuration-guide/services/chrony.md",74782],a24f5044:[()=>n.e(9755).then(n.bind(n,45103)),"@site/standards/scs-XXXX-vN-standard-template.md",45103],a35d3433:[()=>n.e(123).then(n.bind(n,32451)),"@site/standards/scs-0212-v1-requirements-for-container-registries.md",32451],a38b6a75:[()=>n.e(3782).then(n.bind(n,7665)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/make-reference.md",7665],a3dd9468:[()=>n.e(6018).then(n.bind(n,57343)),"@site/standards/iaas/scs-0113.md",57343],a3e11933:[()=>n.e(9657).then(n.bind(n,20812)),"@site/docs/06-releases/Release1.md",20812],a4833b52:[()=>n.e(7753).then(n.bind(n,41639)),"@site/standards/scs-0104-v1-standard-images.md",41639],a489f3d8:[()=>n.e(8128).then(n.bind(n,92558)),"@site/docs/02-iaas/guides/user-guide/migration-vmware-esix.md",92558],a51c5cdb:[()=>n.e(603).then(n.bind(n,7149)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/configuration.md",7149],a51f78bf:[()=>n.e(825).then(n.bind(n,32812)),"@site/docs/02-iaas/guides/configuration-guide/commons/timezone.md",32812],a52c62d4:[()=>n.e(5568).then(n.bind(n,45095)),"@site/community/collaboration/sig-standardization.md",45095],a52f8495:[()=>n.e(9691).then(n.bind(n,43642)),"@site/standards/ops/scs-0400.md",43642],a63812ab:[()=>n.e(6147).then(n.bind(n,80510)),"@site/community/collaboration/sig-documentation.md",80510],a6aa9e1f:[()=>Promise.all([n.e(1869),n.e(3498),n.e(5309),n.e(7643)]).then(n.bind(n,35124)),"@theme/BlogListPage",35124],a7023ddc:[()=>n.e(9267).then(n.t.bind(n,28289,19)),"~blog/default/blog-tags-tags-4c2.json",28289],a708848c:[()=>n.e(7980).then(n.bind(n,79716)),"@site/docs/02-iaas/components/project-manager.md",79716],a70dabb3:[()=>n.e(5075).then(n.bind(n,67821)),"@site/standards/global/scs-0002.md",67821],a7434565:[()=>n.e(1678).then(n.t.bind(n,4061,19)),"/home/runner/work/docs/docs/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",4061],a7bd4aaa:[()=>n.e(7098).then(n.bind(n,74532)),"@theme/DocVersionRoot",74532],a8ea16f4:[()=>n.e(6217).then(n.bind(n,40032)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/overview.md",40032],a8f67d60:[()=>n.e(8463).then(n.bind(n,90478)),"@site/community/contribute/adding-docs-guide.md",90478],a94703ab:[()=>Promise.all([n.e(1869),n.e(9048)]).then(n.bind(n,92559)),"@theme/DocRoot",92559],a94c36cd:[()=>n.e(1548).then(n.bind(n,99311)),"@site/docs/03-container/overview/architecture.md",99311],a9f40339:[()=>n.e(6164).then(n.bind(n,14978)),"@site/docs/04-operating-scs/05-lifecycle-management/index.md",14978],abb47370:[()=>n.e(7456).then(n.bind(n,95455)),"@site/standards/iam/index.md",95455],abd7a988:[()=>n.e(2747).then(n.bind(n,62834)),"@site/docs/03-container/components/container-registry/docs/ha-deployment.md",62834],abecca15:[()=>n.e(7560).then(n.bind(n,21674)),"@site/docs/02-iaas/guides/deploy-guide/services/logging-monitoring.md",21674],abfb0638:[()=>n.e(6793).then(n.bind(n,33276)),"@site/docs/02-iaas/guides/operations-guide/manager/apply.md",33276],ac087500:[()=>n.e(8411).then(n.bind(n,33606)),"@site/docs/02-iaas/guides/troubleshooting-guide/index.md",33606],acecf23e:[()=>n.e(1903).then(n.t.bind(n,1912,19)),"~blog/default/blogMetadata-default.json",1912],ad1cb202:[()=>n.e(3086).then(n.bind(n,21363)),"@site/docs/02-iaas/guides/concept-guide/components/gardener.md",21363],ad39e84b:[()=>n.e(4657).then(n.bind(n,48442)),"@site/standards/scs-0102-v1-image-metadata.md",48442],aed2f698:[()=>n.e(5612).then(n.bind(n,7395)),"@site/docs/02-iaas/guides/user-guide/openstack/security-groups.md",7395],afaff11a:[()=>n.e(1734).then(n.t.bind(n,77588,19)),"~blog/default/blog-tags-community-d90-list.json",77588],b08c16de:[()=>n.e(9390).then(n.bind(n,87333)),"@site/community/contribute/styleguides/ansible_styleguide.md",87333],b0ccdb87:[()=>n.e(6646).then(n.bind(n,48647)),"@site/docs/04-operating-scs/components/central-api/overview.md",48647],b12ed0df:[()=>n.e(801).then(n.t.bind(n,45669,19)),"/home/runner/work/docs/docs/.docusaurus/docusaurus-plugin-content-docs/standards/plugin-route-context-module-100.json",45669],b191927f:[()=>n.e(6452).then(n.bind(n,79704)),"@site/standards/scs-compatible-iaas.md",79704],b1eed1ab:[()=>n.e(7362).then(n.bind(n,76309)),"@site/standards/kaas/scs-0214.md",76309],b1fd1705:[()=>n.e(8215).then(n.bind(n,22544)),"@site/docs/04-operating-scs/01-guides/openstack-health-monitor/Debian12-Install.md",22544],b262b314:[()=>n.e(3681).then(n.bind(n,65329)),"@site/standards/scs-0216-v1-requirements-for-testing-cluster-stacks.md",65329],b2b675dd:[()=>n.e(1991).then(n.t.bind(n,29775,19)),"~blog/default/blog-c06.json",29775],b2f554cd:[()=>n.e(5894).then(n.t.bind(n,76042,19)),"~blog/default/blog-archive-80c.json",76042],b501f8e8:[()=>n.e(1528).then(n.bind(n,20145)),"@site/community/collaboration/team-container.md",20145],b5a6d29b:[()=>n.e(8226).then(n.bind(n,21561)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/resource-manager.md",21561],b65fe363:[()=>n.e(3475).then(n.bind(n,84863)),"@site/docs/02-iaas/guides/configuration-guide/openstack/ironic.md",84863],b74e5806:[()=>n.e(4730).then(n.bind(n,37155)),"@site/standards/iam/scs-0301.md",37155],b77ceb62:[()=>n.e(9689).then(n.bind(n,57794)),"@site/docs/02-iaas/guides/configuration-guide/openstack/ceilometer.md",57794],b7cec31e:[()=>n.e(7938).then(n.bind(n,46781)),"@site/community/collaboration/sig-community.md",46781],b840bdcc:[()=>n.e(1489).then(n.t.bind(n,44111,19)),"~docs/default/category-docs-docs-category-metering-737.json",44111],b8c7b97f:[()=>n.e(6443).then(n.bind(n,81084)),"@site/docs/05-iam/index.md",81084],b8fd74b5:[()=>n.e(3153).then(n.bind(n,14158)),"@site/docs/02-iaas/components/sandbox-manager.md",14158],bccb1b42:[()=>n.e(6986).then(n.bind(n,19075)),"@site/docs/03-container/components/container-registry/docs/migration.md",19075],bceb927f:[()=>n.e(8081).then(n.bind(n,90594)),"@site/docs/02-iaas/guides/configuration-guide/openstack/neutron.md",90594],bd319452:[()=>n.e(6971).then(n.bind(n,2554)),"@site/docs/02-iaas/guides/deploy-guide/examples/testbed.md",2554],bd8a0ffe:[()=>n.e(4497).then(n.bind(n,36910)),"@site/standards/scs-0101-w1-entropy-implementation-testing.md",36910],bd8a97c5:[()=>n.e(3536).then(n.bind(n,8942)),"@site/docs/02-iaas/guides/configuration-guide/proxy.md",8942],bdaaff35:[()=>n.e(9063).then(n.bind(n,47022)),"@site/docs/02-iaas/guides/user-guide/openstack/index.md",47022],bdcb5fea:[()=>n.e(462).then(n.t.bind(n,53208,19)),"~docs/default/category-docs-docs-category-guides-1-94a.json",53208],be01f2a0:[()=>n.e(9954).then(n.bind(n,84789)),"@site/docs/02-iaas/guides/configuration-guide/openstack/keystone.md",84789],befb6565:[()=>n.e(7020).then(n.bind(n,73607)),"@site/docs/02-iaas/guides/configuration-guide/openstack/heat.md",73607],c0cd111c:[()=>n.e(8477).then(n.bind(n,88549)),"@site/docs/02-iaas/overview/storage.md",88549],c0e025b3:[()=>n.e(2179).then(n.bind(n,23401)),"@site/docs/02-iaas/guides/configuration-guide/services/tuned.md",23401],c2f44c5f:[()=>n.e(660).then(n.bind(n,98262)),"@site/docs/02-iaas/guides/troubleshooting-guide/openstack.md",98262],c3529e0a:[()=>n.e(6871).then(n.bind(n,72270)),"@site/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests.md",72270],c49f9378:[()=>n.e(126).then(n.bind(n,49822)),"@site/docs/02-iaas/components/simple-stress.md",49822],c5479f59:[()=>n.e(2283).then(n.bind(n,34985)),"@site/docs/03-container/components/container-registry/docs/rate_limit.md",34985],c5533f5e:[()=>n.e(9346).then(n.bind(n,2610)),"@site/standards/scs-0210-v1-k8s-new-version-policy.md",2610],c6e1beb6:[()=>n.e(7085).then(n.bind(n,27042)),"@site/docs/04-operating-scs/components/monitoring/docs/alertmanager.md",27042],c75320ff:[()=>n.e(1407).then(n.bind(n,13144)),"@site/docs/02-iaas/guides/upgrade-guide/logging-monitoring.md",13144],c7e8a920:[()=>n.e(1542).then(n.bind(n,89343)),"@site/standards/scs-0004-v1-achieving-certification.md",89343],c8b68b4a:[()=>n.e(9565).then(n.t.bind(n,85163,19)),"~docs/default/category-docs-docs-category-cluster-stacks-1b3.json",85163],c8d5479b:[()=>n.e(9289).then(n.bind(n,23466)),"@site/standards/iam/scs-0302.md",23466],c9581477:[()=>n.e(6293).then(n.bind(n,41195)),"@site/docs/02-iaas/guides/configuration-guide/openstack/nova.md",41195],c9b16325:[()=>n.e(2798).then(n.bind(n,98056)),"@site/contributor-docs/development/index.md",98056],caeeb51c:[()=>n.e(5162).then(n.bind(n,37651)),"@site/docs/02-iaas/guides/concept-guide/index.md",37651],cbf20d25:[()=>n.e(5575).then(n.bind(n,27786)),"@site/contributor-docs/development/tests/test-implementation-guide.md",27786],ccc49370:[()=>Promise.all([n.e(1869),n.e(3498),n.e(5309),n.e(3249)]).then(n.bind(n,73858)),"@theme/BlogPostPage",73858],cd0ad4f0:[()=>n.e(4625).then(n.bind(n,5500)),"@site/docs/01-getting-started/containerization.md",5500],cd4fb20e:[()=>n.e(6165).then(n.bind(n,47287)),"@site/standards/scs-0100-v2-flavor-naming.md",47287],cda5fe29:[()=>n.e(2840).then(n.bind(n,45464)),"@site/docs/02-iaas/guides/deploy-guide/services/kubernetes.md",45464],ce756c16:[()=>n.e(9807).then(n.bind(n,44047)),"@site/community/license-considerations.md",44047],cf99a16e:[()=>n.e(4855).then(n.bind(n,11386)),"@site/docs/02-iaas/guides/operations-guide/openstack/tools/simple-stress.md",11386],cffc493c:[()=>n.e(714).then(n.bind(n,47821)),"@site/community/contribute/docs-workflow-explanation.md",47821],d0ee365b:[()=>n.e(6223).then(n.bind(n,14461)),"@site/docs/02-iaas/guides/configuration-guide/openstack/index.md",14461],d14d7097:[()=>n.e(7919).then(n.bind(n,82916)),"@site/docs/02-iaas/guides/operations-guide/openstack/neutron.md",82916],d1aa920e:[()=>n.e(3920).then(n.bind(n,66459)),"@site/docs/02-iaas/guides/operations-guide/openstack/index.md",66459],d1c3b532:[()=>n.e(8992).then(n.bind(n,60609)),"@site/docs/02-iaas/guides/operations-guide/infrastructure.md",60609],d5947e44:[()=>n.e(7861).then(n.bind(n,51810)),"@site/docs/02-iaas/guides/operations-guide/network.md",51810],d59f7d52:[()=>n.e(5139).then(n.bind(n,33441)),"@site/standards/scs-0301-v1-naming-conventions.md",33441],d5ac8ed7:[()=>n.e(1284).then(n.t.bind(n,60472,19)),"~blog/default/blog-tags-howto-248.json",60472],d6a104fd:[()=>n.e(3637).then(n.bind(n,97625)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration.md",97625],d71eca41:[()=>n.e(467).then(n.bind(n,43265)),"@site/docs/02-iaas/guides/concept-guide/components/index.md",43265],d770ad8d:[()=>n.e(3934).then(n.bind(n,38436)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class.md",38436],d7951534:[()=>n.e(5213).then(n.t.bind(n,39865,19)),"~docs/default/category-docs-docs-category-guides-e3e.json",39865],da1a5473:[()=>n.e(7125).then(n.bind(n,43619)),"@site/docs/02-iaas/guides/other-guides/developer-guide/scripts.md",43619],dbde4c02:[()=>n.e(445).then(n.bind(n,49865)),"@site/docs/02-iaas/guides/upgrade-guide/infrastructure.md",49865],dc09f893:[()=>n.e(3527).then(n.bind(n,45065)),"@site/docs/02-iaas/guides/user-guide/index.md",45065],dcbc8e94:[()=>n.e(9495).then(n.bind(n,25154)),"@site/docs/02-iaas/guides/configuration-guide/loadbalancer.md",25154],dcf2f717:[()=>n.e(8981).then(n.bind(n,76141)),"@site/docs/03-container/guides/guide1.md",76141],de6833f9:[()=>n.e(2309).then(n.bind(n,84904)),"@site/docs/02-iaas/guides/configuration-guide/commons/resolvconf.md",84904],df35cf96:[()=>n.e(6831).then(n.bind(n,57019)),"@site/docs/02-iaas/guides/configuration-guide/commons/services.md",57019],dfce392e:[()=>n.e(4398).then(n.bind(n,35713)),"@site/standards/scs-0401-v1-status-page-reference-implementation-decision.md",35713],dfe27b1e:[()=>n.e(5997).then(n.bind(n,8327)),"@site/docs/03-container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters.md",8327],e0c197a4:[()=>n.e(7051).then(n.bind(n,64947)),"@site/docs/02-iaas/guides/concept-guide/components/ironic.md",64947],e20b631f:[()=>n.e(272).then(n.bind(n,23641)),"@site/docs/02-iaas/guides/configuration-guide/openstack/manila.md",23641],e24c1f8d:[()=>n.e(4480).then(n.bind(n,22701)),"@site/docs/02-iaas/guides/configuration-guide/commons/sysctl.md",22701],e2dcdabe:[()=>n.e(1099).then(n.bind(n,96264)),"@site/standards/scs-XXXX-vN-decision-record-template.md",96264],e34f30ed:[()=>n.e(6211).then(n.bind(n,83941)),"@site/docs/04-operating-scs/components/monitoring/docs/iaas.md",83941],e44168e5:[()=>n.e(1909).then(n.bind(n,22864)),"@site/docs/01-getting-started/virtualization.md",22864],e57b2c87:[()=>n.e(4016).then(n.bind(n,90330)),"@site/docs/04-operating-scs/components/status-page/docs/component_overview.md",90330],e6095437:[()=>n.e(2546).then(n.t.bind(n,53874,19)),"~docs/default/category-docs-docs-category-automated-pentesting-e02.json",53874],e747ec83:[()=>n.e(9432).then(n.bind(n,13340)),"@site/docs/glossary.md",13340],ea470413:[()=>n.e(8730).then(n.bind(n,34648)),"@site/community/collaboration/sig-monitoring.md",34648],eaf69a59:[()=>n.e(7633).then(n.bind(n,8478)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting.md",8478],eb99bfed:[()=>n.e(6063).then(n.bind(n,37577)),"@site/docs/02-iaas/guides/troubleshooting-guide/manager.md",37577],ebcea0bb:[()=>n.e(1093).then(n.t.bind(n,45431,19)),"~docs/default/category-docs-docs-category-monitoring-918.json",45431],ecbad217:[()=>Promise.all([n.e(1869),n.e(6454)]).then(n.bind(n,94773)),"@site/docs/02-iaas/guides/upgrade-guide/manager.mdx",94773],edc931f8:[()=>n.e(2526).then(n.bind(n,27034)),"@site/community/index.md",27034],eea6a18c:[()=>n.e(9245).then(n.bind(n,62222)),"@site/standards/scs-0400-v1-status-page-create-decision.md",62222],ef682180:[()=>n.e(7731).then(n.bind(n,32534)),"@site/standards/kaas/scs-0215.md",32534],ef9d238d:[()=>Promise.all([n.e(1869),n.e(9864)]).then(n.bind(n,9221)),"@site/community/contribute/local-docusaurus-development-guide.mdx",9221],efbcd183:[()=>n.e(9093).then(n.bind(n,62334)),"@site/standards/scs-compatible-kaas.md",62334],f0b55dfe:[()=>n.e(6370).then(n.bind(n,22819)),"@site/docs/02-iaas/guides/other-guides/style-guide.md",22819],f0e20cb6:[()=>n.e(1479).then(n.bind(n,46382)),"@site/docs/02-iaas/guides/configuration-guide/index.md",46382],f14351c1:[()=>n.e(7129).then(n.t.bind(n,51781,19)),"~docs/default/category-docs-docs-category-components-a98.json",51781],f1715aef:[()=>n.e(6647).then(n.bind(n,42395)),"@site/standards/iaas/scs-0100.md",42395],f17f9c44:[()=>n.e(4979).then(n.bind(n,68081)),"@site/docs/03-container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers.md",68081],f2a59390:[()=>n.e(2078).then(n.bind(n,42922)),"@site/docs/02-iaas/guides/deploy-guide/services/openstack.md",42922],f385820d:[()=>n.e(7841).then(n.bind(n,5178)),"@site/docs/02-iaas/guides/configuration-guide/openstack/horizon.md",5178],f40b2df0:[()=>n.e(3639).then(n.bind(n,43596)),"@site/docs/02-iaas/guides/operations-guide/openstack/octavia.md",43596],f4cdb2d9:[()=>n.e(2126).then(n.bind(n,90938)),"@site/docs/03-container/overview/knowledge.md",90938],f5b4e375:[()=>n.e(778).then(n.bind(n,20584)),"@site/standards/scs-0210-v2-k8s-version-policy.md",20584],f68824be:[()=>n.e(6070).then(n.bind(n,19122)),"@site/standards/scs-0300-v1-requirements-for-sso-identity-federation.md",19122],f793d2d5:[()=>n.e(6183).then(n.t.bind(n,2518,19)),"/home/runner/work/docs/docs/.docusaurus/docusaurus-plugin-content-docs/community/plugin-route-context-module-100.json",2518],f8869d03:[()=>n.e(5595).then(n.bind(n,59638)),"@site/standards/kaas/index.md",59638],f91986bc:[()=>n.e(9121).then(n.t.bind(n,65766,19)),"~docs/default/category-docs-docs-category-operating-scs-4c9.json",65766],f9ec068e:[()=>n.e(751).then(n.bind(n,32512)),"@site/standards/global/scs-0001.md",32512],fa7c4c29:[()=>n.e(5122).then(n.bind(n,70666)),"@site/docs/02-iaas/guides/upgrade-guide/network.md",70666],fd34a958:[()=>n.e(9049).then(n.bind(n,19740)),"@site/standards/scs-0402-v1-status-page-openapi-spec-decision.md",19740],fe5fac7c:[()=>n.e(2479).then(n.bind(n,47492)),"@site/docs/03-container/deployment-examples/a/hardware.md",47492],ff45c01b:[()=>n.e(6290).then(n.bind(n,41958)),"@site/contributor-docs/development/tests/rfc2119-keyword-test-guide.md",41958],fff06078:[()=>n.e(2710).then(n.bind(n,38186)),"@site/docs/02-iaas/guides/concept-guide/components/k3s.md",38186],fff9aecb:[()=>n.e(3649).then(n.bind(n,93044)),"@site/docs/02-iaas/guides/upgrade-guide/index.md",93044]};var i=n(74848);function c(e){let{error:t,retry:n,pastDelay:a}=e;return t?(0,i.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,i.jsx)("p",{children:String(t)}),(0,i.jsx)("div",{children:(0,i.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):a?(0,i.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,i.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,i.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,i.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,i.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,i.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,i.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,i.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,i.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var d=n(86921),u=n(53102);function l(e,t){if("*"===e)return o()({loading:c,loader:()=>n.e(2237).then(n.bind(n,82237)),modules:["@theme/NotFound"],webpack:()=>[82237],render(e,t){const n=e.default;return(0,i.jsx)(u.W,{value:{plugin:{name:"native",id:"default"}},children:(0,i.jsx)(n,{...t})})}});const a=s[`${e}-${t}`],l={},p=[],g=[],m=(0,d.A)(a);return Object.entries(m).forEach((e=>{let[t,n]=e;const a=r[n];a&&(l[t]=a[0],p.push(a[1]),g.push(a[2]))})),o().Map({loading:c,loader:l,modules:p,webpack:()=>g,render(t,n){const o=JSON.parse(JSON.stringify(a));Object.entries(t).forEach((t=>{let[n,a]=t;const s=a.default;if(!s)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof s&&"function"!=typeof s||Object.keys(a).filter((e=>"default"!==e)).forEach((e=>{s[e]=a[e]}));let r=o;const i=n.split(".");i.slice(0,-1).forEach((e=>{r=r[e]})),r[i[i.length-1]]=s}));const s=o.__comp;delete o.__comp;const r=o.__context;return delete o.__context,(0,i.jsx)(u.W,{value:r,children:(0,i.jsx)(s,{...o,...n})})}})}const p=[{path:"/blog",component:l("/blog","9f2"),exact:!0},{path:"/blog/archive",component:l("/blog/archive","d5c"),exact:!0},{path:"/blog/first-blog-post",component:l("/blog/first-blog-post","c31"),exact:!0},{path:"/blog/tags",component:l("/blog/tags","e00"),exact:!0},{path:"/blog/tags/community",component:l("/blog/tags/community","928"),exact:!0},{path:"/blog/tags/howto",component:l("/blog/tags/howto","1c2"),exact:!0},{path:"/search",component:l("/search","ae7"),exact:!0},{path:"/community",component:l("/community","8d1"),routes:[{path:"/community",component:l("/community","983"),routes:[{path:"/community",component:l("/community","3f5"),routes:[{path:"/community/",component:l("/community/","067"),exact:!0,sidebar:"community"},{path:"/community/category/contribute-to-docs",component:l("/community/category/contribute-to-docs","b6e"),exact:!0,sidebar:"community"},{path:"/community/category/tools",component:l("/community/category/tools","708"),exact:!0,sidebar:"community"},{path:"/community/central-services/plusserver-gx-scs",component:l("/community/central-services/plusserver-gx-scs","8a6"),exact:!0},{path:"/community/cloud-resources/",component:l("/community/cloud-resources/","8ee"),exact:!0,sidebar:"community"},{path:"/community/cloud-resources/getting-started-openstack",component:l("/community/cloud-resources/getting-started-openstack","963"),exact:!0,sidebar:"community"},{path:"/community/cloud-resources/plusserver-gx-scs",component:l("/community/cloud-resources/plusserver-gx-scs","ec9"),exact:!0,sidebar:"community"},{path:"/community/cloud-resources/wavestack",component:l("/community/cloud-resources/wavestack","a83"),exact:!0,sidebar:"community"},{path:"/community/collaboration/",component:l("/community/collaboration/","147"),exact:!0,sidebar:"community"},{path:"/community/collaboration/sig-central-api",component:l("/community/collaboration/sig-central-api","b3d"),exact:!0,sidebar:"community"},{path:"/community/collaboration/sig-community",component:l("/community/collaboration/sig-community","c49"),exact:!0,sidebar:"community"},{path:"/community/collaboration/sig-documentation",component:l("/community/collaboration/sig-documentation","b1a"),exact:!0,sidebar:"community"},{path:"/community/collaboration/sig-monitoring",component:l("/community/collaboration/sig-monitoring","7fc"),exact:!0,sidebar:"community"},{path:"/community/collaboration/sig-standardization",component:l("/community/collaboration/sig-standardization","177"),exact:!0,sidebar:"community"},{path:"/community/collaboration/team-container",component:l("/community/collaboration/team-container","7b3"),exact:!0,sidebar:"community"},{path:"/community/collaboration/team-iaas",component:l("/community/collaboration/team-iaas","c05"),exact:!0,sidebar:"community"},{path:"/community/collaboration/team-iam",component:l("/community/collaboration/team-iam","202"),exact:!0,sidebar:"community"},{path:"/community/collaboration/team-ops",component:l("/community/collaboration/team-ops","960"),exact:!0,sidebar:"community"},{path:"/community/contribute/adding-docs-guide",component:l("/community/contribute/adding-docs-guide","cc6"),exact:!0,sidebar:"community"},{path:"/community/contribute/doc-files-structure-guide",component:l("/community/contribute/doc-files-structure-guide","195"),exact:!0,sidebar:"community"},{path:"/community/contribute/docs-workflow-explanation",component:l("/community/contribute/docs-workflow-explanation","d63"),exact:!0,sidebar:"community"},{path:"/community/contribute/linting-guide",component:l("/community/contribute/linting-guide","088"),exact:!0,sidebar:"community"},{path:"/community/contribute/local-docusaurus-development-guide",component:l("/community/contribute/local-docusaurus-development-guide","83e"),exact:!0,sidebar:"community"},{path:"/community/contribute/styleguide",component:l("/community/contribute/styleguide","a62"),exact:!0,sidebar:"community"},{path:"/community/contribute/styleguides/ansible_styleguide",component:l("/community/contribute/styleguides/ansible_styleguide","e67"),exact:!0},{path:"/community/hackathons/checklist",component:l("/community/hackathons/checklist","592"),exact:!0},{path:"/community/license-considerations",component:l("/community/license-considerations","f35"),exact:!0},{path:"/community/mission-statement",component:l("/community/mission-statement","532"),exact:!0,sidebar:"community"},{path:"/community/tools/github/branchprotection",component:l("/community/tools/github/branchprotection","f89"),exact:!0,sidebar:"community"},{path:"/community/tools/github/dco-and-licenses",component:l("/community/tools/github/dco-and-licenses","276"),exact:!0,sidebar:"community"},{path:"/community/tools/github/tips-and-tricks",component:l("/community/tools/github/tips-and-tricks","923"),exact:!0,sidebar:"community"},{path:"/community/tools/jitsi",component:l("/community/tools/jitsi","a31"),exact:!0,sidebar:"community"},{path:"/community/tools/mailinglists",component:l("/community/tools/mailinglists","85e"),exact:!0,sidebar:"community"},{path:"/community/tools/matrix",component:l("/community/tools/matrix","9e6"),exact:!0,sidebar:"community"},{path:"/community/tools/nextcloud",component:l("/community/tools/nextcloud","f9d"),exact:!0,sidebar:"community"},{path:"/community/tools/zuul",component:l("/community/tools/zuul","faa"),exact:!0,sidebar:"community"}]}]}]},{path:"/contributor-docs",component:l("/contributor-docs","8dc"),routes:[{path:"/contributor-docs",component:l("/contributor-docs","cba"),routes:[{path:"/contributor-docs",component:l("/contributor-docs","98b"),routes:[{path:"/contributor-docs/",component:l("/contributor-docs/","5c4"),exact:!0,sidebar:"devDocs"},{path:"/contributor-docs/development/",component:l("/contributor-docs/development/","b39"),exact:!0,sidebar:"devDocs"},{path:"/contributor-docs/development/tests/rfc2119-keyword-test-guide",component:l("/contributor-docs/development/tests/rfc2119-keyword-test-guide","017"),exact:!0,sidebar:"devDocs"},{path:"/contributor-docs/development/tests/test-implementation-guide",component:l("/contributor-docs/development/tests/test-implementation-guide","8a6"),exact:!0,sidebar:"devDocs"},{path:"/contributor-docs/operations/iam/identity-federation-in-scs",component:l("/contributor-docs/operations/iam/identity-federation-in-scs","b16"),exact:!0,sidebar:"devDocs"},{path:"/contributor-docs/operations/iam/openstack-federation-via-oidc",component:l("/contributor-docs/operations/iam/openstack-federation-via-oidc","377"),exact:!0,sidebar:"devDocs"},{path:"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide",component:l("/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","ec0"),exact:!0,sidebar:"devDocs"}]}]}]},{path:"/docs",component:l("/docs","65a"),routes:[{path:"/docs",component:l("/docs","9d9"),routes:[{path:"/docs",component:l("/docs","6a2"),routes:[{path:"/docs/",component:l("/docs/","6df"),exact:!0,sidebar:"docs"},{path:"/docs/category/automated-pentesting",component:l("/docs/category/automated-pentesting","8e9"),exact:!0,sidebar:"docs"},{path:"/docs/category/central-api",component:l("/docs/category/central-api","93f"),exact:!0,sidebar:"docs"},{path:"/docs/category/cluster-stacks",component:l("/docs/category/cluster-stacks","6ae"),exact:!0,sidebar:"docs"},{path:"/docs/category/components",component:l("/docs/category/components","f2e"),exact:!0,sidebar:"docs"},{path:"/docs/category/components-1",component:l("/docs/category/components-1","f0f"),exact:!0,sidebar:"docs"},{path:"/docs/category/components-2",component:l("/docs/category/components-2","781"),exact:!0,sidebar:"docs"},{path:"/docs/category/container-registry",component:l("/docs/category/container-registry","fc7"),exact:!0,sidebar:"docs"},{path:"/docs/category/guides-1",component:l("/docs/category/guides-1","62f"),exact:!0,sidebar:"docs"},{path:"/docs/category/guides-2",component:l("/docs/category/guides-2","408"),exact:!0,sidebar:"docs"},{path:"/docs/category/iaas-layer",component:l("/docs/category/iaas-layer","429"),exact:!0,sidebar:"docs"},{path:"/docs/category/k8s-cluster-api-provider",component:l("/docs/category/k8s-cluster-api-provider","de7"),exact:!0,sidebar:"docs"},{path:"/docs/category/metering",component:l("/docs/category/metering","c3e"),exact:!0,sidebar:"docs"},{path:"/docs/category/monitoring",component:l("/docs/category/monitoring","5b5"),exact:!0,sidebar:"docs"},{path:"/docs/category/operating-scs",component:l("/docs/category/operating-scs","b51"),exact:!0,sidebar:"docs"},{path:"/docs/category/releases",component:l("/docs/category/releases","d6f"),exact:!0,sidebar:"docs"},{path:"/docs/category/status-page-api",component:l("/docs/category/status-page-api","18b"),exact:!0,sidebar:"docs"},{path:"/docs/container/",component:l("/docs/container/","6db"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","2fa"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","057"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","ae8"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","408"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting",component:l("/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","d6e"),exact:!0},{path:"/docs/container/components/container-registry/docs/backup_and_restore",component:l("/docs/container/components/container-registry/docs/backup_and_restore","8f9"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/ha-deployment",component:l("/docs/container/components/container-registry/docs/ha-deployment","799"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/migration",component:l("/docs/container/components/container-registry/docs/migration","33a"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/persistence",component:l("/docs/container/components/container-registry/docs/persistence","90e"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/quickstart",component:l("/docs/container/components/container-registry/docs/quickstart","772"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/rate_limit",component:l("/docs/container/components/container-registry/docs/rate_limit","017"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/scs-deployment",component:l("/docs/container/components/container-registry/docs/scs-deployment","5f3"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/container-registry/docs/upgrade",component:l("/docs/container/components/container-registry/docs/upgrade","e27"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/application-credentials",component:l("/docs/container/components/k8s-cluster-api-provider/doc/application-credentials","002"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/configuration",component:l("/docs/container/components/k8s-cluster-api-provider/doc/configuration","45e"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration",component:l("/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","67e"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal",component:l("/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","2b9"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting",component:l("/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","9b1"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/make-reference",component:l("/docs/container/components/k8s-cluster-api-provider/doc/make-reference","8be"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/overview",component:l("/docs/container/components/k8s-cluster-api-provider/doc/overview","86b"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/quickstart",component:l("/docs/container/components/k8s-cluster-api-provider/doc/quickstart","c83"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/requirements",component:l("/docs/container/components/k8s-cluster-api-provider/doc/requirements","ccd"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/roadmap",component:l("/docs/container/components/k8s-cluster-api-provider/doc/roadmap","11b"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide",component:l("/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","dff"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/usage/",component:l("/docs/container/components/k8s-cluster-api-provider/doc/usage/","698"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node",component:l("/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node","d52"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration",component:l("/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration","90a"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster",component:l("/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster","d6f"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca",component:l("/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca","4ad"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api",component:l("/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api","782"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor",component:l("/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor","216"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters",component:l("/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters","336"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class",component:l("/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class","257"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2",component:l("/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2","994"),exact:!0},{path:"/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments",component:l("/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments","403"),exact:!0,sidebar:"docs"},{path:"/docs/container/components/k8s-cluster-api-provider/doc/usage/testing",component:l("/docs/container/components/k8s-cluster-api-provider/doc/usage/testing","19d"),exact:!0,sidebar:"docs"},{path:"/docs/container/deployment-examples/a/",component:l("/docs/container/deployment-examples/a/","eab"),exact:!0},{path:"/docs/container/deployment-examples/a/hardware",component:l("/docs/container/deployment-examples/a/hardware","c9f"),exact:!0},{path:"/docs/container/deployment-examples/a/software",component:l("/docs/container/deployment-examples/a/software","4b1"),exact:!0},{path:"/docs/container/guides/guide1",component:l("/docs/container/guides/guide1","fe9"),exact:!0},{path:"/docs/container/overview/architecture",component:l("/docs/container/overview/architecture","96d"),exact:!0},{path:"/docs/container/overview/knowledge",component:l("/docs/container/overview/knowledge","b1b"),exact:!0},{path:"/docs/faq/",component:l("/docs/faq/","ab5"),exact:!0,sidebar:"docs"},{path:"/docs/getting-started/containerization",component:l("/docs/getting-started/containerization","6c3"),exact:!0},{path:"/docs/getting-started/overview",component:l("/docs/getting-started/overview","4b2"),exact:!0},{path:"/docs/getting-started/virtualization",component:l("/docs/getting-started/virtualization","01b"),exact:!0},{path:"/docs/glossary",component:l("/docs/glossary","c6d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/components/",component:l("/docs/iaas/components/","d45"),exact:!0},{path:"/docs/iaas/components/flavor-manager",component:l("/docs/iaas/components/flavor-manager","8e8"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/components/image-manager/",component:l("/docs/iaas/components/image-manager/","ceb"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/components/image-manager/update",component:l("/docs/iaas/components/image-manager/update","d83"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/components/openstack-health-monitor",component:l("/docs/iaas/components/openstack-health-monitor","d38"),exact:!0},{path:"/docs/iaas/components/project-manager",component:l("/docs/iaas/components/project-manager","b8e"),exact:!0},{path:"/docs/iaas/components/resource-manager",component:l("/docs/iaas/components/resource-manager","a61"),exact:!0},{path:"/docs/iaas/components/sandbox-manager",component:l("/docs/iaas/components/sandbox-manager","941"),exact:!0},{path:"/docs/iaas/components/simple-stress",component:l("/docs/iaas/components/simple-stress","9d1"),exact:!0},{path:"/docs/iaas/guides/",component:l("/docs/iaas/guides/","df7"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/",component:l("/docs/iaas/guides/concept-guide/","879"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/",component:l("/docs/iaas/guides/concept-guide/components/","631"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/ceph",component:l("/docs/iaas/guides/concept-guide/components/ceph","7ba"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/clusterapi",component:l("/docs/iaas/guides/concept-guide/components/clusterapi","e03"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/gardener",component:l("/docs/iaas/guides/concept-guide/components/gardener","ab9"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/ironic",component:l("/docs/iaas/guides/concept-guide/components/ironic","4b7"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/k3s",component:l("/docs/iaas/guides/concept-guide/components/k3s","481"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/keycloak",component:l("/docs/iaas/guides/concept-guide/components/keycloak","7d2"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/netdata",component:l("/docs/iaas/guides/concept-guide/components/netdata","071"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/openstack",component:l("/docs/iaas/guides/concept-guide/components/openstack","5e1"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/prometheus",component:l("/docs/iaas/guides/concept-guide/components/prometheus","402"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/proxmox",component:l("/docs/iaas/guides/concept-guide/components/proxmox","0f3"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/sonic",component:l("/docs/iaas/guides/concept-guide/components/sonic","133"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/components/teleport",component:l("/docs/iaas/guides/concept-guide/components/teleport","bef"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/design",component:l("/docs/iaas/guides/concept-guide/design","99a"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/hardware-bom",component:l("/docs/iaas/guides/concept-guide/hardware-bom","98f"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/layers",component:l("/docs/iaas/guides/concept-guide/layers","d21"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/concept-guide/use-cases",component:l("/docs/iaas/guides/concept-guide/use-cases","fcd"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/",component:l("/docs/iaas/guides/configuration-guide/","2af"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/ceph",component:l("/docs/iaas/guides/configuration-guide/ceph","19e"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/",component:l("/docs/iaas/guides/configuration-guide/commons/","25b"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/certificates",component:l("/docs/iaas/guides/configuration-guide/commons/certificates","d0a"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/packages",component:l("/docs/iaas/guides/configuration-guide/commons/packages","3a4"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/resolvconf",component:l("/docs/iaas/guides/configuration-guide/commons/resolvconf","d42"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/services",component:l("/docs/iaas/guides/configuration-guide/commons/services","97a"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/sshconfig",component:l("/docs/iaas/guides/configuration-guide/commons/sshconfig","505"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/sysctl",component:l("/docs/iaas/guides/configuration-guide/commons/sysctl","635"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/timezone",component:l("/docs/iaas/guides/configuration-guide/commons/timezone","4b5"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/commons/user",component:l("/docs/iaas/guides/configuration-guide/commons/user","8d4"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/configuration-repository",component:l("/docs/iaas/guides/configuration-guide/configuration-repository","b47"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/inventory",component:l("/docs/iaas/guides/configuration-guide/inventory","559"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/loadbalancer",component:l("/docs/iaas/guides/configuration-guide/loadbalancer","f93"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/manager",component:l("/docs/iaas/guides/configuration-guide/manager","3a7"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/network",component:l("/docs/iaas/guides/configuration-guide/network","7d8"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/",component:l("/docs/iaas/guides/configuration-guide/openstack/","318"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/aodh",component:l("/docs/iaas/guides/configuration-guide/openstack/aodh","9b8"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/barbican",component:l("/docs/iaas/guides/configuration-guide/openstack/barbican","d39"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/ceilometer",component:l("/docs/iaas/guides/configuration-guide/openstack/ceilometer","910"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/cinder",component:l("/docs/iaas/guides/configuration-guide/openstack/cinder","e9b"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/designate",component:l("/docs/iaas/guides/configuration-guide/openstack/designate","14f"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/glance",component:l("/docs/iaas/guides/configuration-guide/openstack/glance","c89"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/heat",component:l("/docs/iaas/guides/configuration-guide/openstack/heat","e58"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/horizon",component:l("/docs/iaas/guides/configuration-guide/openstack/horizon","f63"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/ironic",component:l("/docs/iaas/guides/configuration-guide/openstack/ironic","7b4"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/keystone",component:l("/docs/iaas/guides/configuration-guide/openstack/keystone","5bb"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/magnum",component:l("/docs/iaas/guides/configuration-guide/openstack/magnum","9df"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/manila",component:l("/docs/iaas/guides/configuration-guide/openstack/manila","2b1"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/neutron",component:l("/docs/iaas/guides/configuration-guide/openstack/neutron","efe"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/nova",component:l("/docs/iaas/guides/configuration-guide/openstack/nova","88d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/octavia",component:l("/docs/iaas/guides/configuration-guide/openstack/octavia","493"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/placement",component:l("/docs/iaas/guides/configuration-guide/openstack/placement","d48"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/openstack/skyline",component:l("/docs/iaas/guides/configuration-guide/openstack/skyline","f6d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/proxy",component:l("/docs/iaas/guides/configuration-guide/proxy","f21"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/self-signed-certificates",component:l("/docs/iaas/guides/configuration-guide/self-signed-certificates","70f"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/services/",component:l("/docs/iaas/guides/configuration-guide/services/","4fe"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/services/chrony",component:l("/docs/iaas/guides/configuration-guide/services/chrony","6aa"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/services/docker",component:l("/docs/iaas/guides/configuration-guide/services/docker","bba"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/services/tuned",component:l("/docs/iaas/guides/configuration-guide/services/tuned","3ce"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/configuration-guide/validations/",component:l("/docs/iaas/guides/configuration-guide/validations/","36a"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/",component:l("/docs/iaas/guides/deploy-guide/","0d0"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/bootstrap",component:l("/docs/iaas/guides/deploy-guide/bootstrap","4b5"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/examples/",component:l("/docs/iaas/guides/deploy-guide/examples/","d9c"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box",component:l("/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box","449"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/examples/testbed",component:l("/docs/iaas/guides/deploy-guide/examples/testbed","50d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/manager",component:l("/docs/iaas/guides/deploy-guide/manager","3b6"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/provisioning",component:l("/docs/iaas/guides/deploy-guide/provisioning","d32"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/seed",component:l("/docs/iaas/guides/deploy-guide/seed","159"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/",component:l("/docs/iaas/guides/deploy-guide/services/","38d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/ceph",component:l("/docs/iaas/guides/deploy-guide/services/ceph","daa"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/infrastructure",component:l("/docs/iaas/guides/deploy-guide/services/infrastructure","a32"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/kubernetes",component:l("/docs/iaas/guides/deploy-guide/services/kubernetes","22e"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/logging-monitoring",component:l("/docs/iaas/guides/deploy-guide/services/logging-monitoring","305"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/network",component:l("/docs/iaas/guides/deploy-guide/services/network","87b"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/deploy-guide/services/openstack",component:l("/docs/iaas/guides/deploy-guide/services/openstack","ff3"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/",component:l("/docs/iaas/guides/operations-guide/","a65"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/ceph",component:l("/docs/iaas/guides/operations-guide/ceph","205"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/infrastructure",component:l("/docs/iaas/guides/operations-guide/infrastructure","4a9"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/manager/",component:l("/docs/iaas/guides/operations-guide/manager/","be8"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/manager/apply",component:l("/docs/iaas/guides/operations-guide/manager/apply","a48"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/manager/console",component:l("/docs/iaas/guides/operations-guide/manager/console","99f"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/manager/get",component:l("/docs/iaas/guides/operations-guide/manager/get","831"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/manager/log",component:l("/docs/iaas/guides/operations-guide/manager/log","be6"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/manager/task",component:l("/docs/iaas/guides/operations-guide/manager/task","78e"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/network",component:l("/docs/iaas/guides/operations-guide/network","061"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/",component:l("/docs/iaas/guides/operations-guide/openstack/","b4a"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/cinder",component:l("/docs/iaas/guides/operations-guide/openstack/cinder","186"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/keystone",component:l("/docs/iaas/guides/operations-guide/openstack/keystone","7d7"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/neutron",component:l("/docs/iaas/guides/operations-guide/openstack/neutron","675"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/nova",component:l("/docs/iaas/guides/operations-guide/openstack/nova","373"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/octavia",component:l("/docs/iaas/guides/operations-guide/openstack/octavia","639"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/",component:l("/docs/iaas/guides/operations-guide/openstack/tools/","cda"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager",component:l("/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","4fc"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/",component:l("/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","54e"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update",component:l("/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","3ac"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor",component:l("/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","049"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/project-manager",component:l("/docs/iaas/guides/operations-guide/openstack/tools/project-manager","87d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager",component:l("/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","b80"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager",component:l("/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager","849"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress",component:l("/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","144"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/",component:l("/docs/iaas/guides/other-guides/","895"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/cloud-in-a-box",component:l("/docs/iaas/guides/other-guides/cloud-in-a-box","9e1"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/contributor-guide",component:l("/docs/iaas/guides/other-guides/contributor-guide","815"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/developer-guide/",component:l("/docs/iaas/guides/other-guides/developer-guide/","6cc"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/developer-guide/releases",component:l("/docs/iaas/guides/other-guides/developer-guide/releases","f04"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/developer-guide/scripts",component:l("/docs/iaas/guides/other-guides/developer-guide/scripts","7e2"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/developer-guide/zuul",component:l("/docs/iaas/guides/other-guides/developer-guide/zuul","30c"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/style-guide",component:l("/docs/iaas/guides/other-guides/style-guide","b41"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/other-guides/testbed",component:l("/docs/iaas/guides/other-guides/testbed","5a6"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/troubleshooting-guide/",component:l("/docs/iaas/guides/troubleshooting-guide/","b72"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/troubleshooting-guide/ceph",component:l("/docs/iaas/guides/troubleshooting-guide/ceph","23b"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/troubleshooting-guide/manager",component:l("/docs/iaas/guides/troubleshooting-guide/manager","558"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/troubleshooting-guide/openstack",component:l("/docs/iaas/guides/troubleshooting-guide/openstack","ea9"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/",component:l("/docs/iaas/guides/upgrade-guide/","f35"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/ceph",component:l("/docs/iaas/guides/upgrade-guide/ceph","29d"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/docker",component:l("/docs/iaas/guides/upgrade-guide/docker","9f3"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/infrastructure",component:l("/docs/iaas/guides/upgrade-guide/infrastructure","12a"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/logging-monitoring",component:l("/docs/iaas/guides/upgrade-guide/logging-monitoring","ed7"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/manager",component:l("/docs/iaas/guides/upgrade-guide/manager","45f"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/network",component:l("/docs/iaas/guides/upgrade-guide/network","f8c"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/upgrade-guide/openstack",component:l("/docs/iaas/guides/upgrade-guide/openstack","9bc"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/",component:l("/docs/iaas/guides/user-guide/","fa4"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/migration-vmware-esix",component:l("/docs/iaas/guides/user-guide/migration-vmware-esix","633"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/openstack/",component:l("/docs/iaas/guides/user-guide/openstack/","b9e"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/openstack/security-groups",component:l("/docs/iaas/guides/user-guide/openstack/security-groups","ae9"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/openstack/user-data-backups",component:l("/docs/iaas/guides/user-guide/openstack/user-data-backups","5cd"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/security-groups/",component:l("/docs/iaas/guides/user-guide/security-groups/","486"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/guides/user-guide/user-data-backups",component:l("/docs/iaas/guides/user-guide/user-data-backups","a9b"),exact:!0,sidebar:"docs"},{path:"/docs/iaas/overview/architecture",component:l("/docs/iaas/overview/architecture","74b"),exact:!0},{path:"/docs/iaas/overview/compute",component:l("/docs/iaas/overview/compute","d18"),exact:!0},{path:"/docs/iaas/overview/knowledge",component:l("/docs/iaas/overview/knowledge","a22"),exact:!0},{path:"/docs/iaas/overview/network",component:l("/docs/iaas/overview/network","abc"),exact:!0},{path:"/docs/iaas/overview/storage",component:l("/docs/iaas/overview/storage","187"),exact:!0},{path:"/docs/iam/",component:l("/docs/iam/","a74"),exact:!0,sidebar:"docs"},{path:"/docs/iam/domain-manager-setup-and-usage",component:l("/docs/iam/domain-manager-setup-and-usage","c6a"),exact:!0,sidebar:"docs"},{path:"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations",component:l("/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","e86"),exact:!0,sidebar:"docs"},{path:"/docs/iam/SCS-example-setup-configuration-description",component:l("/docs/iam/SCS-example-setup-configuration-description","fa9"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/audits/",component:l("/docs/operating-scs/audits/","bcc"),exact:!0},{path:"/docs/operating-scs/components/automated-pentesting/overview",component:l("/docs/operating-scs/components/automated-pentesting/overview","5b4"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/automated-pentesting/tools",component:l("/docs/operating-scs/components/automated-pentesting/tools","c74"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/central-api/overview",component:l("/docs/operating-scs/components/central-api/overview","b4c"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/central-api/poc-setup",component:l("/docs/operating-scs/components/central-api/poc-setup","647"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/alertmanager",component:l("/docs/operating-scs/components/monitoring/docs/alertmanager","4f0"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/iaas",component:l("/docs/operating-scs/components/monitoring/docs/iaas","27c"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/infrastructure_services",component:l("/docs/operating-scs/components/monitoring/docs/infrastructure_services","b85"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/k3s",component:l("/docs/operating-scs/components/monitoring/docs/k3s","4af"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/kaas",component:l("/docs/operating-scs/components/monitoring/docs/kaas","819"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/oauth",component:l("/docs/operating-scs/components/monitoring/docs/oauth","e21"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/overview",component:l("/docs/operating-scs/components/monitoring/docs/overview","961"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/quickstart",component:l("/docs/operating-scs/components/monitoring/docs/quickstart","a9d"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/scs-deployment",component:l("/docs/operating-scs/components/monitoring/docs/scs-deployment","8be"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/tracing",component:l("/docs/operating-scs/components/monitoring/docs/tracing","207"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/tuning",component:l("/docs/operating-scs/components/monitoring/docs/tuning","374"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/monitoring/docs/zuul",component:l("/docs/operating-scs/components/monitoring/docs/zuul","6c6"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page/docs/component_overview",component:l("/docs/operating-scs/components/status-page/docs/component_overview","8d2"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page/docs/components",component:l("/docs/operating-scs/components/status-page/docs/components","9ea"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page/docs/levels_of_consensus",component:l("/docs/operating-scs/components/status-page/docs/levels_of_consensus","eae"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/components/status-page/docs/overview",component:l("/docs/operating-scs/components/status-page/docs/overview","60c"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install",component:l("/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","ec3"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/incident-management/",component:l("/docs/operating-scs/incident-management/","8c0"),exact:!0},{path:"/docs/operating-scs/lifecycle-management/",component:l("/docs/operating-scs/lifecycle-management/","88c"),exact:!0},{path:"/docs/operating-scs/logging/",component:l("/docs/operating-scs/logging/","ee2"),exact:!0},{path:"/docs/operating-scs/metering/meter_configuration",component:l("/docs/operating-scs/metering/meter_configuration","124"),exact:!0,sidebar:"docs"},{path:"/docs/operating-scs/monitoring/",component:l("/docs/operating-scs/monitoring/","799"),exact:!0},{path:"/docs/operating-scs/overview",component:l("/docs/operating-scs/overview","061"),exact:!0},{path:"/docs/releases/Release0",component:l("/docs/releases/Release0","984"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release1",component:l("/docs/releases/Release1","1b3"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release2",component:l("/docs/releases/Release2","9c9"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release3",component:l("/docs/releases/Release3","e73"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release4",component:l("/docs/releases/Release4","9d8"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release5",component:l("/docs/releases/Release5","cb2"),exact:!0,sidebar:"docs"},{path:"/docs/releases/Release6",component:l("/docs/releases/Release6","b81"),exact:!0,sidebar:"docs"},{path:"/docs/releases/ReleaseX",component:l("/docs/releases/ReleaseX","7e5"),exact:!0},{path:"/docs/standards/",component:l("/docs/standards/","109"),exact:!0}]}]}]},{path:"/standards",component:l("/standards","966"),routes:[{path:"/standards",component:l("/standards","d52"),routes:[{path:"/standards",component:l("/standards","d9f"),routes:[{path:"/standards/",component:l("/standards/","9e3"),exact:!0,sidebar:"standards"},{path:"/standards/certification/overview",component:l("/standards/certification/overview","9ab"),exact:!0,sidebar:"standards"},{path:"/standards/certification/scopes-versions",component:l("/standards/certification/scopes-versions","ede"),exact:!0,sidebar:"standards"},{path:"/standards/global/",component:l("/standards/global/","f4a"),exact:!0,sidebar:"standards"},{path:"/standards/global/scs-0001",component:l("/standards/global/scs-0001","6bf"),exact:!0,sidebar:"standards"},{path:"/standards/global/scs-0002",component:l("/standards/global/scs-0002","08f"),exact:!0,sidebar:"standards"},{path:"/standards/global/scs-0003",component:l("/standards/global/scs-0003","9d4"),exact:!0,sidebar:"standards"},{path:"/standards/global/scs-0004",component:l("/standards/global/scs-0004","3df"),exact:!0,sidebar:"standards"},{path:"/standards/global/scs-0112",component:l("/standards/global/scs-0112","f1d"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/",component:l("/standards/iaas/","804"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0100",component:l("/standards/iaas/scs-0100","933"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0101",component:l("/standards/iaas/scs-0101","42d"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0102",component:l("/standards/iaas/scs-0102","78a"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0103",component:l("/standards/iaas/scs-0103","2e0"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0104",component:l("/standards/iaas/scs-0104","018"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0110",component:l("/standards/iaas/scs-0110","edb"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0111",component:l("/standards/iaas/scs-0111","fa3"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0113",component:l("/standards/iaas/scs-0113","819"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0114",component:l("/standards/iaas/scs-0114","514"),exact:!0,sidebar:"standards"},{path:"/standards/iaas/scs-0115",component:l("/standards/iaas/scs-0115","eb1"),exact:!0,sidebar:"standards"},{path:"/standards/iam/",component:l("/standards/iam/","ac3"),exact:!0,sidebar:"standards"},{path:"/standards/iam/scs-0300",component:l("/standards/iam/scs-0300","171"),exact:!0,sidebar:"standards"},{path:"/standards/iam/scs-0301",component:l("/standards/iam/scs-0301","e8e"),exact:!0,sidebar:"standards"},{path:"/standards/iam/scs-0302",component:l("/standards/iam/scs-0302","469"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/",component:l("/standards/kaas/","a87"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0200",component:l("/standards/kaas/scs-0200","316"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0210",component:l("/standards/kaas/scs-0210","03c"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0211",component:l("/standards/kaas/scs-0211","a83"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0212",component:l("/standards/kaas/scs-0212","4a5"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0213",component:l("/standards/kaas/scs-0213","922"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0214",component:l("/standards/kaas/scs-0214","952"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0215",component:l("/standards/kaas/scs-0215","fcf"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0216",component:l("/standards/kaas/scs-0216","090"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0217",component:l("/standards/kaas/scs-0217","a99"),exact:!0,sidebar:"standards"},{path:"/standards/kaas/scs-0218",component:l("/standards/kaas/scs-0218","c81"),exact:!0,sidebar:"standards"},{path:"/standards/ops/",component:l("/standards/ops/","234"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0400",component:l("/standards/ops/scs-0400","24b"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0401",component:l("/standards/ops/scs-0401","a98"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0402",component:l("/standards/ops/scs-0402","b21"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0403",component:l("/standards/ops/scs-0403","425"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0410",component:l("/standards/ops/scs-0410","529"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0411",component:l("/standards/ops/scs-0411","44d"),exact:!0,sidebar:"standards"},{path:"/standards/ops/scs-0412",component:l("/standards/ops/scs-0412","8c6"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0001-v1-sovereign-cloud-standards",component:l("/standards/scs-0001-v1-sovereign-cloud-standards","695"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0002-v1-standards-docs-org",component:l("/standards/scs-0002-v1-standards-docs-org","0d6"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0002-v2-standards-docs-org",component:l("/standards/scs-0002-v2-standards-docs-org","33f"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0003-v1-sovereign-cloud-standards-yaml",component:l("/standards/scs-0003-v1-sovereign-cloud-standards-yaml","27f"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0004-v1-achieving-certification",component:l("/standards/scs-0004-v1-achieving-certification","a54"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0100-v1-flavor-naming",component:l("/standards/scs-0100-v1-flavor-naming","678"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0100-v2-flavor-naming",component:l("/standards/scs-0100-v2-flavor-naming","c10"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0100-v3-flavor-naming",component:l("/standards/scs-0100-v3-flavor-naming","96d"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0100-w1-flavor-naming-implementation-testing",component:l("/standards/scs-0100-w1-flavor-naming-implementation-testing","6c8"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0101-v1-entropy",component:l("/standards/scs-0101-v1-entropy","474"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0101-w1-entropy-implementation-testing",component:l("/standards/scs-0101-w1-entropy-implementation-testing","bff"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0102-v1-image-metadata",component:l("/standards/scs-0102-v1-image-metadata","173"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0103-v1-standard-flavors",component:l("/standards/scs-0103-v1-standard-flavors","495"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0104-v1-standard-images",component:l("/standards/scs-0104-v1-standard-images","cd2"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0110-v1-ssd-flavors",component:l("/standards/scs-0110-v1-ssd-flavors","26f"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0111-v1-volume-type-decisions",component:l("/standards/scs-0111-v1-volume-type-decisions","8a3"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0112-v1-sonic",component:l("/standards/scs-0112-v1-sonic","a8a"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0113-v1-security-groups-decision-record",component:l("/standards/scs-0113-v1-security-groups-decision-record","148"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0114-v1-volume-type-standard",component:l("/standards/scs-0114-v1-volume-type-standard","161"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0115-v1-default-rules-for-security-groups",component:l("/standards/scs-0115-v1-default-rules-for-security-groups","e17"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests",component:l("/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","7f6"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0210-v1-k8s-new-version-policy",component:l("/standards/scs-0210-v1-k8s-new-version-policy","267"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0210-v2-k8s-version-policy",component:l("/standards/scs-0210-v2-k8s-version-policy","76e"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0211-v1-kaas-default-storage-class",component:l("/standards/scs-0211-v1-kaas-default-storage-class","70e"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0212-v1-requirements-for-container-registries",component:l("/standards/scs-0212-v1-requirements-for-container-registries","6e1"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0213-v1-k8s-nodes-anti-affinity",component:l("/standards/scs-0213-v1-k8s-nodes-anti-affinity","8e6"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0214-v1-k8s-node-distribution",component:l("/standards/scs-0214-v1-k8s-node-distribution","317"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0215-v1-robustness-features",component:l("/standards/scs-0215-v1-robustness-features","38c"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks",component:l("/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","a90"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0217-v1-baseline-cluster-security",component:l("/standards/scs-0217-v1-baseline-cluster-security","b32"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation",component:l("/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","288"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0300-v1-requirements-for-sso-identity-federation",component:l("/standards/scs-0300-v1-requirements-for-sso-identity-federation","34f"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0301-v1-naming-conventions",component:l("/standards/scs-0301-v1-naming-conventions","6f1"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0302-v1-domain-manager-role",component:l("/standards/scs-0302-v1-domain-manager-role","b43"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0400-v1-status-page-create-decision",component:l("/standards/scs-0400-v1-status-page-create-decision","279"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0401-v1-status-page-reference-implementation-decision",component:l("/standards/scs-0401-v1-status-page-reference-implementation-decision","cc0"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0402-v1-status-page-openapi-spec-decision",component:l("/standards/scs-0402-v1-status-page-openapi-spec-decision","191"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0403-v1-csp-kaas-observability-stack",component:l("/standards/scs-0403-v1-csp-kaas-observability-stack","bb8"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0410-v1-gnocchi-as-metering-database",component:l("/standards/scs-0410-v1-gnocchi-as-metering-database","44a"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0411-v1-publishing_method_for_metering_data",component:l("/standards/scs-0411-v1-publishing_method_for_metering_data","dbc"),exact:!0,sidebar:"standards"},{path:"/standards/scs-0412-v1-metering-json",component:l("/standards/scs-0412-v1-metering-json","3cc"),exact:!0,sidebar:"standards"},{path:"/standards/scs-compatible-iaas",component:l("/standards/scs-compatible-iaas","d6e"),exact:!0,sidebar:"standards"},{path:"/standards/scs-compatible-kaas",component:l("/standards/scs-compatible-kaas","dc7"),exact:!0,sidebar:"standards"},{path:"/standards/scs-XXXX-vN-decision-record-template",component:l("/standards/scs-XXXX-vN-decision-record-template","7f7"),exact:!0},{path:"/standards/scs-XXXX-vN-standard-template",component:l("/standards/scs-XXXX-vN-standard-template","a6a"),exact:!0},{path:"/standards/standards/overview",component:l("/standards/standards/overview","1dc"),exact:!0,sidebar:"standards"}]}]}]},{path:"/",component:l("/","6ae"),exact:!0},{path:"*",component:l("*")}]},6125:(e,t,n)=>{"use strict";n.d(t,{o:()=>s,x:()=>r});var a=n(96540),o=n(74848);const s=a.createContext(!1);function r(e){let{children:t}=e;const[n,r]=(0,a.useState)(!1);return(0,a.useEffect)((()=>{r(!0)}),[]),(0,o.jsx)(s.Provider,{value:n,children:t})}},38536:(e,t,n)=>{"use strict";var a=n(96540),o=n(5338),s=n(54625),r=n(80545),i=n(38193);const c=[n(10119),n(26134),n(76294),n(51043),n(45477)];var d=n(35947),u=n(56347),l=n(22831),p=n(74848);function g(e){let{children:t}=e;return(0,p.jsx)(p.Fragment,{children:t})}var m=n(5260),f=n(44586),h=n(86025),b=n(6342),y=n(61213),v=n(32131),k=n(14090),x=n(2967),w=n(70440),_=n(41463);function S(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,f.A)(),a=(0,v.o)(),o=n[e].htmlLang,s=e=>e.replace("-","_");return(0,p.jsxs)(m.A,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,p.jsx)("link",{rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,p.jsx)("link",{rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:s(o)}),Object.values(n).filter((e=>o!==e.htmlLang)).map((e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:s(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function E(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,f.A)(),a=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,f.A)(),{pathname:a}=(0,u.zy)();return e+(0,w.applyTrailingSlash)((0,h.A)(a),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:a;return(0,p.jsxs)(m.A,{children:[(0,p.jsx)("meta",{property:"og:url",content:o}),(0,p.jsx)("link",{rel:"canonical",href:o})]})}function C(){const{i18n:{currentLocale:e}}=(0,f.A)(),{metadata:t,image:n}=(0,b.p)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(m.A,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:k.w})]}),n&&(0,p.jsx)(y.be,{image:n}),(0,p.jsx)(E,{}),(0,p.jsx)(S,{}),(0,p.jsx)(_.A,{tag:x.Cy,locale:e}),(0,p.jsx)(m.A,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const T=new Map;function A(e){if(T.has(e.pathname))return{...e,pathname:T.get(e.pathname)};if((0,l.u)(d.A,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return T.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),{...e,pathname:t}}var j=n(6125),L=n(26988),P=n(205);function N(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),a=1;a<t;a++)n[a-1]=arguments[a];const o=c.map((t=>{const a=t.default?.[e]??t[e];return a?.(...n)}));return()=>o.forEach((e=>e?.()))}const R=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,P.A)((()=>{a!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const a=t.pathname===n.pathname,o=t.hash===n.hash,s=t.search===n.search;if(a&&o&&!s)return;const{hash:r}=t;if(r){const e=decodeURIComponent(r.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:a}),N("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,l.u)(d.A,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class I extends a.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=i.A.canUseDOM?N("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=N("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),O(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(R,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(u.qh,{location:t,render:()=>e})})}}const F=I,D="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",z="__docusaurus-base-url-issue-banner-suggestion-container";function B(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${D}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="${M}" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${z}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n document.body.prepend(bannerContainer);\n var suggestionContainer = document.getElementById('${z}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function $(){const{siteConfig:{baseUrl:e}}=(0,f.A)();return(0,p.jsx)(p.Fragment,{children:!i.A.canUseDOM&&(0,p.jsx)(m.A,{children:(0,p.jsx)("script",{children:B(e)})})})}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,f.A)(),{pathname:n}=(0,u.zy)();return t&&n===e?(0,p.jsx)($,{}):null}function Q(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:o}}=(0,f.A)(),s=(0,h.A)(e),{htmlLang:r,direction:i}=o[a];return(0,p.jsxs)(m.A,{children:[(0,p.jsx)("html",{lang:r,dir:i}),(0,p.jsx)("title",{children:t}),(0,p.jsx)("meta",{property:"og:title",content:t}),(0,p.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&(0,p.jsx)("meta",{name:"robots",content:"noindex, nofollow"}),e&&(0,p.jsx)("link",{rel:"icon",href:s})]})}var V=n(67489),H=n(92303);function W(){const e=(0,H.A)();return(0,p.jsx)(m.A,{children:(0,p.jsx)("html",{"data-has-hydrated":e})})}function q(){const e=(0,l.v)(d.A),t=(0,u.zy)();return(0,p.jsx)(V.A,{children:(0,p.jsx)(L.l,{children:(0,p.jsxs)(j.x,{children:[(0,p.jsxs)(g,{children:[(0,p.jsx)(Q,{}),(0,p.jsx)(C,{}),(0,p.jsx)(U,{}),(0,p.jsx)(F,{location:A(t),children:e})]}),(0,p.jsx)(W,{})]})})})}var G=n(84054);const X=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const a=document.createElement("link");a.setAttribute("rel","prefetch"),a.setAttribute("href",e),a.onload=()=>t(),a.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(a)}))}:function(e){return new Promise(((t,n)=>{const a=new XMLHttpRequest;a.open("GET",e,!0),a.withCredentials=!0,a.onload=()=>{200===a.status?t():n()},a.send(null)}))};var K=n(86921);const Y=new Set,Z=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch(e){if(!(e=>!J()&&!Z.has(e)&&!Y.has(e))(e))return!1;Y.add(e);const t=(0,l.u)(d.A,e).flatMap((e=>{return t=e.route.path,Object.entries(G).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,K.A)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?X(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!Z.has(e))(e)&&(Z.add(e),O(e))},te=Object.freeze(ee),ne=Boolean(!0);if(i.A.canUseDOM){window.docusaurus=te;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(r.vd,{children:(0,p.jsx)(s.Kd,{children:(0,p.jsx)(q,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},i=()=>{if(ne)a.startTransition((()=>{o.hydrateRoot(e,t,{onRecoverableError:n})}));else{const s=o.createRoot(e,{onRecoverableError:n});a.startTransition((()=>{s.render(t)}))}};O(window.location.pathname).then(i)}},26988:(e,t,n)=>{"use strict";n.d(t,{o:()=>l,l:()=>p});var a=n(96540),o=n(4784);const s=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"index","docs":[{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","path":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","path":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","path":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","path":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","sidebar":"docs"},{"id":"container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","path":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting"},{"id":"container/components/container-registry/docs/backup_and_restore","path":"/docs/container/components/container-registry/docs/backup_and_restore","sidebar":"docs"},{"id":"container/components/container-registry/docs/ha-deployment","path":"/docs/container/components/container-registry/docs/ha-deployment","sidebar":"docs"},{"id":"container/components/container-registry/docs/migration","path":"/docs/container/components/container-registry/docs/migration","sidebar":"docs"},{"id":"container/components/container-registry/docs/persistence","path":"/docs/container/components/container-registry/docs/persistence","sidebar":"docs"},{"id":"container/components/container-registry/docs/quickstart","path":"/docs/container/components/container-registry/docs/quickstart","sidebar":"docs"},{"id":"container/components/container-registry/docs/rate_limit","path":"/docs/container/components/container-registry/docs/rate_limit","sidebar":"docs"},{"id":"container/components/container-registry/docs/scs-deployment","path":"/docs/container/components/container-registry/docs/scs-deployment","sidebar":"docs"},{"id":"container/components/container-registry/docs/upgrade","path":"/docs/container/components/container-registry/docs/upgrade","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/application-credentials","path":"/docs/container/components/k8s-cluster-api-provider/doc/application-credentials","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/configuration","path":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/continuous-integration","path":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","path":"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","path":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/make-reference","path":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/overview","path":"/docs/container/components/k8s-cluster-api-provider/doc/overview","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/quickstart","path":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/requirements","path":"/docs/container/components/k8s-cluster-api-provider/doc/requirements","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/roadmap","path":"/docs/container/components/k8s-cluster-api-provider/doc/roadmap","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","path":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node","path":"/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration","path":"/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster","path":"/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/usage/custom-ca","path":"/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/usage/gateway-api","path":"/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/usage/harbor","path":"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters","path":"/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class","path":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2","path":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2"},{"id":"container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments","path":"/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/usage/testing","path":"/docs/container/components/k8s-cluster-api-provider/doc/usage/testing","sidebar":"docs"},{"id":"container/components/k8s-cluster-api-provider/doc/usage/usage","path":"/docs/container/components/k8s-cluster-api-provider/doc/usage/","sidebar":"docs"},{"id":"container/deployment-examples/a/hardware","path":"/docs/container/deployment-examples/a/hardware"},{"id":"container/deployment-examples/a/index","path":"/docs/container/deployment-examples/a/"},{"id":"container/deployment-examples/a/software","path":"/docs/container/deployment-examples/a/software"},{"id":"container/guides/guide1","path":"/docs/container/guides/guide1"},{"id":"container/index","path":"/docs/container/","sidebar":"docs"},{"id":"container/overview/architecture","path":"/docs/container/overview/architecture"},{"id":"container/overview/knowledge","path":"/docs/container/overview/knowledge"},{"id":"faq/index","path":"/docs/faq/","sidebar":"docs"},{"id":"getting-started/containerization","path":"/docs/getting-started/containerization"},{"id":"getting-started/overview","path":"/docs/getting-started/overview"},{"id":"getting-started/virtualization","path":"/docs/getting-started/virtualization"},{"id":"glossary","path":"/docs/glossary","sidebar":"docs"},{"id":"iaas/components/flavor-manager","path":"/docs/iaas/components/flavor-manager","sidebar":"docs"},{"id":"iaas/components/image-manager/index","path":"/docs/iaas/components/image-manager/","sidebar":"docs"},{"id":"iaas/components/image-manager/update","path":"/docs/iaas/components/image-manager/update","sidebar":"docs"},{"id":"iaas/components/index","path":"/docs/iaas/components/"},{"id":"iaas/components/openstack-health-monitor","path":"/docs/iaas/components/openstack-health-monitor"},{"id":"iaas/components/project-manager","path":"/docs/iaas/components/project-manager"},{"id":"iaas/components/resource-manager","path":"/docs/iaas/components/resource-manager"},{"id":"iaas/components/sandbox-manager","path":"/docs/iaas/components/sandbox-manager"},{"id":"iaas/components/simple-stress","path":"/docs/iaas/components/simple-stress"},{"id":"iaas/guides/concept-guide/components/ceph","path":"/docs/iaas/guides/concept-guide/components/ceph","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/clusterapi","path":"/docs/iaas/guides/concept-guide/components/clusterapi","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/gardener","path":"/docs/iaas/guides/concept-guide/components/gardener","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/index","path":"/docs/iaas/guides/concept-guide/components/","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/ironic","path":"/docs/iaas/guides/concept-guide/components/ironic","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/k3s","path":"/docs/iaas/guides/concept-guide/components/k3s","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/keycloak","path":"/docs/iaas/guides/concept-guide/components/keycloak","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/netdata","path":"/docs/iaas/guides/concept-guide/components/netdata","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/openstack","path":"/docs/iaas/guides/concept-guide/components/openstack","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/prometheus","path":"/docs/iaas/guides/concept-guide/components/prometheus","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/proxmox","path":"/docs/iaas/guides/concept-guide/components/proxmox","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/sonic","path":"/docs/iaas/guides/concept-guide/components/sonic","sidebar":"docs"},{"id":"iaas/guides/concept-guide/components/teleport","path":"/docs/iaas/guides/concept-guide/components/teleport","sidebar":"docs"},{"id":"iaas/guides/concept-guide/design","path":"/docs/iaas/guides/concept-guide/design","sidebar":"docs"},{"id":"iaas/guides/concept-guide/hardware-bom","path":"/docs/iaas/guides/concept-guide/hardware-bom","sidebar":"docs"},{"id":"iaas/guides/concept-guide/index","path":"/docs/iaas/guides/concept-guide/","sidebar":"docs"},{"id":"iaas/guides/concept-guide/layers","path":"/docs/iaas/guides/concept-guide/layers","sidebar":"docs"},{"id":"iaas/guides/concept-guide/use-cases","path":"/docs/iaas/guides/concept-guide/use-cases","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/ceph","path":"/docs/iaas/guides/configuration-guide/ceph","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/certificates","path":"/docs/iaas/guides/configuration-guide/commons/certificates","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/index","path":"/docs/iaas/guides/configuration-guide/commons/","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/packages","path":"/docs/iaas/guides/configuration-guide/commons/packages","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/resolvconf","path":"/docs/iaas/guides/configuration-guide/commons/resolvconf","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/services","path":"/docs/iaas/guides/configuration-guide/commons/services","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/sshconfig","path":"/docs/iaas/guides/configuration-guide/commons/sshconfig","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/sysctl","path":"/docs/iaas/guides/configuration-guide/commons/sysctl","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/timezone","path":"/docs/iaas/guides/configuration-guide/commons/timezone","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/commons/user","path":"/docs/iaas/guides/configuration-guide/commons/user","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/configuration-repository","path":"/docs/iaas/guides/configuration-guide/configuration-repository","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/index","path":"/docs/iaas/guides/configuration-guide/","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/inventory","path":"/docs/iaas/guides/configuration-guide/inventory","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/loadbalancer","path":"/docs/iaas/guides/configuration-guide/loadbalancer","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/manager","path":"/docs/iaas/guides/configuration-guide/manager","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/network","path":"/docs/iaas/guides/configuration-guide/network","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/aodh","path":"/docs/iaas/guides/configuration-guide/openstack/aodh","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/barbican","path":"/docs/iaas/guides/configuration-guide/openstack/barbican","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/ceilometer","path":"/docs/iaas/guides/configuration-guide/openstack/ceilometer","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/cinder","path":"/docs/iaas/guides/configuration-guide/openstack/cinder","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/designate","path":"/docs/iaas/guides/configuration-guide/openstack/designate","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/glance","path":"/docs/iaas/guides/configuration-guide/openstack/glance","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/heat","path":"/docs/iaas/guides/configuration-guide/openstack/heat","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/horizon","path":"/docs/iaas/guides/configuration-guide/openstack/horizon","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/index","path":"/docs/iaas/guides/configuration-guide/openstack/","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/ironic","path":"/docs/iaas/guides/configuration-guide/openstack/ironic","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/keystone","path":"/docs/iaas/guides/configuration-guide/openstack/keystone","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/magnum","path":"/docs/iaas/guides/configuration-guide/openstack/magnum","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/manila","path":"/docs/iaas/guides/configuration-guide/openstack/manila","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/neutron","path":"/docs/iaas/guides/configuration-guide/openstack/neutron","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/nova","path":"/docs/iaas/guides/configuration-guide/openstack/nova","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/octavia","path":"/docs/iaas/guides/configuration-guide/openstack/octavia","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/placement","path":"/docs/iaas/guides/configuration-guide/openstack/placement","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/openstack/skyline","path":"/docs/iaas/guides/configuration-guide/openstack/skyline","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/proxy","path":"/docs/iaas/guides/configuration-guide/proxy","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/self-signed-certificates","path":"/docs/iaas/guides/configuration-guide/self-signed-certificates","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/services/chrony","path":"/docs/iaas/guides/configuration-guide/services/chrony","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/services/docker","path":"/docs/iaas/guides/configuration-guide/services/docker","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/services/index","path":"/docs/iaas/guides/configuration-guide/services/","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/services/tuned","path":"/docs/iaas/guides/configuration-guide/services/tuned","sidebar":"docs"},{"id":"iaas/guides/configuration-guide/validations/index","path":"/docs/iaas/guides/configuration-guide/validations/","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/bootstrap","path":"/docs/iaas/guides/deploy-guide/bootstrap","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/examples/cloud-in-a-box","path":"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/examples/index","path":"/docs/iaas/guides/deploy-guide/examples/","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/examples/testbed","path":"/docs/iaas/guides/deploy-guide/examples/testbed","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/index","path":"/docs/iaas/guides/deploy-guide/","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/manager","path":"/docs/iaas/guides/deploy-guide/manager","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/provisioning","path":"/docs/iaas/guides/deploy-guide/provisioning","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/seed","path":"/docs/iaas/guides/deploy-guide/seed","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/ceph","path":"/docs/iaas/guides/deploy-guide/services/ceph","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/index","path":"/docs/iaas/guides/deploy-guide/services/","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/infrastructure","path":"/docs/iaas/guides/deploy-guide/services/infrastructure","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/kubernetes","path":"/docs/iaas/guides/deploy-guide/services/kubernetes","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/logging-monitoring","path":"/docs/iaas/guides/deploy-guide/services/logging-monitoring","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/network","path":"/docs/iaas/guides/deploy-guide/services/network","sidebar":"docs"},{"id":"iaas/guides/deploy-guide/services/openstack","path":"/docs/iaas/guides/deploy-guide/services/openstack","sidebar":"docs"},{"id":"iaas/guides/index","path":"/docs/iaas/guides/","sidebar":"docs"},{"id":"iaas/guides/operations-guide/ceph","path":"/docs/iaas/guides/operations-guide/ceph","sidebar":"docs"},{"id":"iaas/guides/operations-guide/index","path":"/docs/iaas/guides/operations-guide/","sidebar":"docs"},{"id":"iaas/guides/operations-guide/infrastructure","path":"/docs/iaas/guides/operations-guide/infrastructure","sidebar":"docs"},{"id":"iaas/guides/operations-guide/manager/apply","path":"/docs/iaas/guides/operations-guide/manager/apply","sidebar":"docs"},{"id":"iaas/guides/operations-guide/manager/console","path":"/docs/iaas/guides/operations-guide/manager/console","sidebar":"docs"},{"id":"iaas/guides/operations-guide/manager/get","path":"/docs/iaas/guides/operations-guide/manager/get","sidebar":"docs"},{"id":"iaas/guides/operations-guide/manager/index","path":"/docs/iaas/guides/operations-guide/manager/","sidebar":"docs"},{"id":"iaas/guides/operations-guide/manager/log","path":"/docs/iaas/guides/operations-guide/manager/log","sidebar":"docs"},{"id":"iaas/guides/operations-guide/manager/task","path":"/docs/iaas/guides/operations-guide/manager/task","sidebar":"docs"},{"id":"iaas/guides/operations-guide/network","path":"/docs/iaas/guides/operations-guide/network","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/cinder","path":"/docs/iaas/guides/operations-guide/openstack/cinder","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/index","path":"/docs/iaas/guides/operations-guide/openstack/","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/keystone","path":"/docs/iaas/guides/operations-guide/openstack/keystone","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/neutron","path":"/docs/iaas/guides/operations-guide/openstack/neutron","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/nova","path":"/docs/iaas/guides/operations-guide/openstack/nova","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/octavia","path":"/docs/iaas/guides/operations-guide/openstack/octavia","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/flavor-manager","path":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/image-manager/index","path":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/image-manager/update","path":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/index","path":"/docs/iaas/guides/operations-guide/openstack/tools/","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","path":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/project-manager","path":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/resource-manager","path":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/sandbox-manager","path":"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager","sidebar":"docs"},{"id":"iaas/guides/operations-guide/openstack/tools/simple-stress","path":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","sidebar":"docs"},{"id":"iaas/guides/other-guides/cloud-in-a-box","path":"/docs/iaas/guides/other-guides/cloud-in-a-box","sidebar":"docs"},{"id":"iaas/guides/other-guides/contributor-guide","path":"/docs/iaas/guides/other-guides/contributor-guide","sidebar":"docs"},{"id":"iaas/guides/other-guides/developer-guide/index","path":"/docs/iaas/guides/other-guides/developer-guide/","sidebar":"docs"},{"id":"iaas/guides/other-guides/developer-guide/releases","path":"/docs/iaas/guides/other-guides/developer-guide/releases","sidebar":"docs"},{"id":"iaas/guides/other-guides/developer-guide/scripts","path":"/docs/iaas/guides/other-guides/developer-guide/scripts","sidebar":"docs"},{"id":"iaas/guides/other-guides/developer-guide/zuul","path":"/docs/iaas/guides/other-guides/developer-guide/zuul","sidebar":"docs"},{"id":"iaas/guides/other-guides/index","path":"/docs/iaas/guides/other-guides/","sidebar":"docs"},{"id":"iaas/guides/other-guides/style-guide","path":"/docs/iaas/guides/other-guides/style-guide","sidebar":"docs"},{"id":"iaas/guides/other-guides/testbed","path":"/docs/iaas/guides/other-guides/testbed","sidebar":"docs"},{"id":"iaas/guides/troubleshooting-guide/ceph","path":"/docs/iaas/guides/troubleshooting-guide/ceph","sidebar":"docs"},{"id":"iaas/guides/troubleshooting-guide/index","path":"/docs/iaas/guides/troubleshooting-guide/","sidebar":"docs"},{"id":"iaas/guides/troubleshooting-guide/manager","path":"/docs/iaas/guides/troubleshooting-guide/manager","sidebar":"docs"},{"id":"iaas/guides/troubleshooting-guide/openstack","path":"/docs/iaas/guides/troubleshooting-guide/openstack","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/ceph","path":"/docs/iaas/guides/upgrade-guide/ceph","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/docker","path":"/docs/iaas/guides/upgrade-guide/docker","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/index","path":"/docs/iaas/guides/upgrade-guide/","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/infrastructure","path":"/docs/iaas/guides/upgrade-guide/infrastructure","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/logging-monitoring","path":"/docs/iaas/guides/upgrade-guide/logging-monitoring","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/manager","path":"/docs/iaas/guides/upgrade-guide/manager","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/network","path":"/docs/iaas/guides/upgrade-guide/network","sidebar":"docs"},{"id":"iaas/guides/upgrade-guide/openstack","path":"/docs/iaas/guides/upgrade-guide/openstack","sidebar":"docs"},{"id":"iaas/guides/user-guide/index","path":"/docs/iaas/guides/user-guide/","sidebar":"docs"},{"id":"iaas/guides/user-guide/migration-vmware-esix","path":"/docs/iaas/guides/user-guide/migration-vmware-esix","sidebar":"docs"},{"id":"iaas/guides/user-guide/openstack/index","path":"/docs/iaas/guides/user-guide/openstack/","sidebar":"docs"},{"id":"iaas/guides/user-guide/openstack/security-groups","path":"/docs/iaas/guides/user-guide/openstack/security-groups","sidebar":"docs"},{"id":"iaas/guides/user-guide/openstack/user-data-backups","path":"/docs/iaas/guides/user-guide/openstack/user-data-backups","sidebar":"docs"},{"id":"iaas/guides/user-guide/security-groups/security-groups","path":"/docs/iaas/guides/user-guide/security-groups/","sidebar":"docs"},{"id":"iaas/guides/user-guide/user-data-backups","path":"/docs/iaas/guides/user-guide/user-data-backups","sidebar":"docs"},{"id":"iaas/overview/architecture","path":"/docs/iaas/overview/architecture"},{"id":"iaas/overview/compute","path":"/docs/iaas/overview/compute"},{"id":"iaas/overview/knowledge","path":"/docs/iaas/overview/knowledge"},{"id":"iaas/overview/network","path":"/docs/iaas/overview/network"},{"id":"iaas/overview/storage","path":"/docs/iaas/overview/storage"},{"id":"iam/domain-manager-setup-and-usage","path":"/docs/iam/domain-manager-setup-and-usage","sidebar":"docs"},{"id":"iam/index","path":"/docs/iam/","sidebar":"docs"},{"id":"iam/intra-SCS-federation-setup-description-for-osism-doc-operations","path":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","sidebar":"docs"},{"id":"iam/SCS-example-setup-configuration-description","path":"/docs/iam/SCS-example-setup-configuration-description","sidebar":"docs"},{"id":"index","path":"/docs/","sidebar":"docs"},{"id":"operating-scs/audits/index","path":"/docs/operating-scs/audits/"},{"id":"operating-scs/components/automated-pentesting/overview","path":"/docs/operating-scs/components/automated-pentesting/overview","sidebar":"docs"},{"id":"operating-scs/components/automated-pentesting/tools","path":"/docs/operating-scs/components/automated-pentesting/tools","sidebar":"docs"},{"id":"operating-scs/components/central-api/overview","path":"/docs/operating-scs/components/central-api/overview","sidebar":"docs"},{"id":"operating-scs/components/central-api/poc-setup","path":"/docs/operating-scs/components/central-api/poc-setup","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/alertmanager","path":"/docs/operating-scs/components/monitoring/docs/alertmanager","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/iaas","path":"/docs/operating-scs/components/monitoring/docs/iaas","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/infrastructure_services","path":"/docs/operating-scs/components/monitoring/docs/infrastructure_services","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/k3s","path":"/docs/operating-scs/components/monitoring/docs/k3s","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/kaas","path":"/docs/operating-scs/components/monitoring/docs/kaas","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/oauth","path":"/docs/operating-scs/components/monitoring/docs/oauth","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/overview","path":"/docs/operating-scs/components/monitoring/docs/overview","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/quickstart","path":"/docs/operating-scs/components/monitoring/docs/quickstart","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/scs-deployment","path":"/docs/operating-scs/components/monitoring/docs/scs-deployment","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/tracing","path":"/docs/operating-scs/components/monitoring/docs/tracing","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/tuning","path":"/docs/operating-scs/components/monitoring/docs/tuning","sidebar":"docs"},{"id":"operating-scs/components/monitoring/docs/zuul","path":"/docs/operating-scs/components/monitoring/docs/zuul","sidebar":"docs"},{"id":"operating-scs/components/status-page/docs/component_overview","path":"/docs/operating-scs/components/status-page/docs/component_overview","sidebar":"docs"},{"id":"operating-scs/components/status-page/docs/components","path":"/docs/operating-scs/components/status-page/docs/components","sidebar":"docs"},{"id":"operating-scs/components/status-page/docs/levels_of_consensus","path":"/docs/operating-scs/components/status-page/docs/levels_of_consensus","sidebar":"docs"},{"id":"operating-scs/components/status-page/docs/overview","path":"/docs/operating-scs/components/status-page/docs/overview","sidebar":"docs"},{"id":"operating-scs/guides/openstack-health-monitor/Debian12-Install","path":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","sidebar":"docs"},{"id":"operating-scs/incident-management/index","path":"/docs/operating-scs/incident-management/"},{"id":"operating-scs/lifecycle-management/index","path":"/docs/operating-scs/lifecycle-management/"},{"id":"operating-scs/logging/index","path":"/docs/operating-scs/logging/"},{"id":"operating-scs/metering/meter_configuration","path":"/docs/operating-scs/metering/meter_configuration","sidebar":"docs"},{"id":"operating-scs/monitoring/index","path":"/docs/operating-scs/monitoring/"},{"id":"operating-scs/overview","path":"/docs/operating-scs/overview"},{"id":"releases/Release0","path":"/docs/releases/Release0","sidebar":"docs"},{"id":"releases/Release1","path":"/docs/releases/Release1","sidebar":"docs"},{"id":"releases/Release2","path":"/docs/releases/Release2","sidebar":"docs"},{"id":"releases/Release3","path":"/docs/releases/Release3","sidebar":"docs"},{"id":"releases/Release4","path":"/docs/releases/Release4","sidebar":"docs"},{"id":"releases/Release5","path":"/docs/releases/Release5","sidebar":"docs"},{"id":"releases/Release6","path":"/docs/releases/Release6","sidebar":"docs"},{"id":"releases/ReleaseX","path":"/docs/releases/ReleaseX"},{"id":"standards/index","path":"/docs/standards/"},{"id":"/category/iaas-layer","path":"/docs/category/iaas-layer","sidebar":"docs"},{"id":"/category/components","path":"/docs/category/components","sidebar":"docs"},{"id":"/category/components-1","path":"/docs/category/components-1","sidebar":"docs"},{"id":"/category/k8s-cluster-api-provider","path":"/docs/category/k8s-cluster-api-provider","sidebar":"docs"},{"id":"/category/cluster-stacks","path":"/docs/category/cluster-stacks","sidebar":"docs"},{"id":"/category/container-registry","path":"/docs/category/container-registry","sidebar":"docs"},{"id":"/category/operating-scs","path":"/docs/category/operating-scs","sidebar":"docs"},{"id":"/category/components-2","path":"/docs/category/components-2","sidebar":"docs"},{"id":"/category/status-page-api","path":"/docs/category/status-page-api","sidebar":"docs"},{"id":"/category/monitoring","path":"/docs/category/monitoring","sidebar":"docs"},{"id":"/category/central-api","path":"/docs/category/central-api","sidebar":"docs"},{"id":"/category/automated-pentesting","path":"/docs/category/automated-pentesting","sidebar":"docs"},{"id":"/category/guides-1","path":"/docs/category/guides-1","sidebar":"docs"},{"id":"/category/metering","path":"/docs/category/metering","sidebar":"docs"},{"id":"/category/guides-2","path":"/docs/category/guides-2","sidebar":"docs"},{"id":"/category/releases","path":"/docs/category/releases","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/","label":"index"}}}}],"breadcrumbs":true},"community":{"path":"/community","versions":[{"name":"current","label":"Next","isLast":true,"path":"/community","mainDocId":"index","docs":[{"id":"central-services/plusserver-gx-scs","path":"/community/central-services/plusserver-gx-scs"},{"id":"cloud-resources/cloud-resources","path":"/community/cloud-resources/","sidebar":"community"},{"id":"cloud-resources/getting-started-openstack","path":"/community/cloud-resources/getting-started-openstack","sidebar":"community"},{"id":"cloud-resources/plusserver-gx-scs","path":"/community/cloud-resources/plusserver-gx-scs","sidebar":"community"},{"id":"cloud-resources/wavestack","path":"/community/cloud-resources/wavestack","sidebar":"community"},{"id":"collaboration/index","path":"/community/collaboration/","sidebar":"community"},{"id":"collaboration/sig-central-api","path":"/community/collaboration/sig-central-api","sidebar":"community"},{"id":"collaboration/sig-community","path":"/community/collaboration/sig-community","sidebar":"community"},{"id":"collaboration/sig-documentation","path":"/community/collaboration/sig-documentation","sidebar":"community"},{"id":"collaboration/sig-monitoring","path":"/community/collaboration/sig-monitoring","sidebar":"community"},{"id":"collaboration/sig-standardization","path":"/community/collaboration/sig-standardization","sidebar":"community"},{"id":"collaboration/team-container","path":"/community/collaboration/team-container","sidebar":"community"},{"id":"collaboration/team-iaas","path":"/community/collaboration/team-iaas","sidebar":"community"},{"id":"collaboration/team-iam","path":"/community/collaboration/team-iam","sidebar":"community"},{"id":"collaboration/team-ops","path":"/community/collaboration/team-ops","sidebar":"community"},{"id":"contribute/adding-docs-guide","path":"/community/contribute/adding-docs-guide","sidebar":"community"},{"id":"contribute/doc-files-structure-guide","path":"/community/contribute/doc-files-structure-guide","sidebar":"community"},{"id":"contribute/docs-workflow-explanation","path":"/community/contribute/docs-workflow-explanation","sidebar":"community"},{"id":"contribute/linting-guide","path":"/community/contribute/linting-guide","sidebar":"community"},{"id":"contribute/local-docusaurus-development-guide","path":"/community/contribute/local-docusaurus-development-guide","sidebar":"community"},{"id":"contribute/styleguide","path":"/community/contribute/styleguide","sidebar":"community"},{"id":"contribute/styleguides/ansible_styleguide","path":"/community/contribute/styleguides/ansible_styleguide"},{"id":"hackathons/checklist","path":"/community/hackathons/checklist"},{"id":"index","path":"/community/","sidebar":"community"},{"id":"license-considerations","path":"/community/license-considerations"},{"id":"mission-statement","path":"/community/mission-statement","sidebar":"community"},{"id":"tools/github/branchprotection","path":"/community/tools/github/branchprotection","sidebar":"community"},{"id":"tools/github/dco-and-licenses","path":"/community/tools/github/dco-and-licenses","sidebar":"community"},{"id":"tools/github/tips-and-tricks","path":"/community/tools/github/tips-and-tricks","sidebar":"community"},{"id":"tools/jitsi","path":"/community/tools/jitsi","sidebar":"community"},{"id":"tools/mailinglists","path":"/community/tools/mailinglists","sidebar":"community"},{"id":"tools/matrix","path":"/community/tools/matrix","sidebar":"community"},{"id":"tools/nextcloud","path":"/community/tools/nextcloud","sidebar":"community"},{"id":"tools/zuul","path":"/community/tools/zuul","sidebar":"community"},{"id":"/category/tools","path":"/community/category/tools","sidebar":"community"},{"id":"/category/contribute-to-docs","path":"/community/category/contribute-to-docs","sidebar":"community"}],"draftIds":[],"sidebars":{"community":{"link":{"path":"/community/","label":"index"}}}}],"breadcrumbs":true},"contributor-docs":{"path":"/contributor-docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/contributor-docs","mainDocId":"index","docs":[{"id":"development/index","path":"/contributor-docs/development/","sidebar":"devDocs"},{"id":"development/tests/rfc2119-keyword-test-guide","path":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","sidebar":"devDocs"},{"id":"development/tests/test-implementation-guide","path":"/contributor-docs/development/tests/test-implementation-guide","sidebar":"devDocs"},{"id":"index","path":"/contributor-docs/","sidebar":"devDocs"},{"id":"operations/iam/identity-federation-in-scs","path":"/contributor-docs/operations/iam/identity-federation-in-scs","sidebar":"devDocs"},{"id":"operations/iam/openstack-federation-via-oidc","path":"/contributor-docs/operations/iam/openstack-federation-via-oidc","sidebar":"devDocs"},{"id":"operations/operations/zuul-ci-cd-quickstart-user-guide","path":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","sidebar":"devDocs"}],"draftIds":[],"sidebars":{"devDocs":{"link":{"path":"/contributor-docs/development/","label":"Developer documentation"}}}}],"breadcrumbs":true},"standards":{"path":"/standards","versions":[{"name":"current","label":"Next","isLast":true,"path":"/standards","mainDocId":"index","docs":[{"id":"certification/overview","path":"/standards/certification/overview","sidebar":"standards"},{"id":"certification/scopes-versions","path":"/standards/certification/scopes-versions","sidebar":"standards"},{"id":"global/index","path":"/standards/global/","sidebar":"standards"},{"id":"global/scs-0001","path":"/standards/global/scs-0001","sidebar":"standards"},{"id":"global/scs-0002","path":"/standards/global/scs-0002","sidebar":"standards"},{"id":"global/scs-0003","path":"/standards/global/scs-0003","sidebar":"standards"},{"id":"global/scs-0004","path":"/standards/global/scs-0004","sidebar":"standards"},{"id":"global/scs-0112","path":"/standards/global/scs-0112","sidebar":"standards"},{"id":"iaas/index","path":"/standards/iaas/","sidebar":"standards"},{"id":"iaas/scs-0100","path":"/standards/iaas/scs-0100","sidebar":"standards"},{"id":"iaas/scs-0101","path":"/standards/iaas/scs-0101","sidebar":"standards"},{"id":"iaas/scs-0102","path":"/standards/iaas/scs-0102","sidebar":"standards"},{"id":"iaas/scs-0103","path":"/standards/iaas/scs-0103","sidebar":"standards"},{"id":"iaas/scs-0104","path":"/standards/iaas/scs-0104","sidebar":"standards"},{"id":"iaas/scs-0110","path":"/standards/iaas/scs-0110","sidebar":"standards"},{"id":"iaas/scs-0111","path":"/standards/iaas/scs-0111","sidebar":"standards"},{"id":"iaas/scs-0113","path":"/standards/iaas/scs-0113","sidebar":"standards"},{"id":"iaas/scs-0114","path":"/standards/iaas/scs-0114","sidebar":"standards"},{"id":"iaas/scs-0115","path":"/standards/iaas/scs-0115","sidebar":"standards"},{"id":"iam/index","path":"/standards/iam/","sidebar":"standards"},{"id":"iam/scs-0300","path":"/standards/iam/scs-0300","sidebar":"standards"},{"id":"iam/scs-0301","path":"/standards/iam/scs-0301","sidebar":"standards"},{"id":"iam/scs-0302","path":"/standards/iam/scs-0302","sidebar":"standards"},{"id":"index","path":"/standards/","sidebar":"standards"},{"id":"kaas/index","path":"/standards/kaas/","sidebar":"standards"},{"id":"kaas/scs-0200","path":"/standards/kaas/scs-0200","sidebar":"standards"},{"id":"kaas/scs-0210","path":"/standards/kaas/scs-0210","sidebar":"standards"},{"id":"kaas/scs-0211","path":"/standards/kaas/scs-0211","sidebar":"standards"},{"id":"kaas/scs-0212","path":"/standards/kaas/scs-0212","sidebar":"standards"},{"id":"kaas/scs-0213","path":"/standards/kaas/scs-0213","sidebar":"standards"},{"id":"kaas/scs-0214","path":"/standards/kaas/scs-0214","sidebar":"standards"},{"id":"kaas/scs-0215","path":"/standards/kaas/scs-0215","sidebar":"standards"},{"id":"kaas/scs-0216","path":"/standards/kaas/scs-0216","sidebar":"standards"},{"id":"kaas/scs-0217","path":"/standards/kaas/scs-0217","sidebar":"standards"},{"id":"kaas/scs-0218","path":"/standards/kaas/scs-0218","sidebar":"standards"},{"id":"ops/index","path":"/standards/ops/","sidebar":"standards"},{"id":"ops/scs-0400","path":"/standards/ops/scs-0400","sidebar":"standards"},{"id":"ops/scs-0401","path":"/standards/ops/scs-0401","sidebar":"standards"},{"id":"ops/scs-0402","path":"/standards/ops/scs-0402","sidebar":"standards"},{"id":"ops/scs-0403","path":"/standards/ops/scs-0403","sidebar":"standards"},{"id":"ops/scs-0410","path":"/standards/ops/scs-0410","sidebar":"standards"},{"id":"ops/scs-0411","path":"/standards/ops/scs-0411","sidebar":"standards"},{"id":"ops/scs-0412","path":"/standards/ops/scs-0412","sidebar":"standards"},{"id":"scs-0001-v1-sovereign-cloud-standards","path":"/standards/scs-0001-v1-sovereign-cloud-standards","sidebar":"standards"},{"id":"scs-0002-v1-standards-docs-org","path":"/standards/scs-0002-v1-standards-docs-org","sidebar":"standards"},{"id":"scs-0002-v2-standards-docs-org","path":"/standards/scs-0002-v2-standards-docs-org","sidebar":"standards"},{"id":"scs-0003-v1-sovereign-cloud-standards-yaml","path":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","sidebar":"standards"},{"id":"scs-0004-v1-achieving-certification","path":"/standards/scs-0004-v1-achieving-certification","sidebar":"standards"},{"id":"scs-0100-v1-flavor-naming","path":"/standards/scs-0100-v1-flavor-naming","sidebar":"standards"},{"id":"scs-0100-v2-flavor-naming","path":"/standards/scs-0100-v2-flavor-naming","sidebar":"standards"},{"id":"scs-0100-v3-flavor-naming","path":"/standards/scs-0100-v3-flavor-naming","sidebar":"standards"},{"id":"scs-0100-w1-flavor-naming-implementation-testing","path":"/standards/scs-0100-w1-flavor-naming-implementation-testing","sidebar":"standards"},{"id":"scs-0101-v1-entropy","path":"/standards/scs-0101-v1-entropy","sidebar":"standards"},{"id":"scs-0101-w1-entropy-implementation-testing","path":"/standards/scs-0101-w1-entropy-implementation-testing","sidebar":"standards"},{"id":"scs-0102-v1-image-metadata","path":"/standards/scs-0102-v1-image-metadata","sidebar":"standards"},{"id":"scs-0103-v1-standard-flavors","path":"/standards/scs-0103-v1-standard-flavors","sidebar":"standards"},{"id":"scs-0104-v1-standard-images","path":"/standards/scs-0104-v1-standard-images","sidebar":"standards"},{"id":"scs-0110-v1-ssd-flavors","path":"/standards/scs-0110-v1-ssd-flavors","sidebar":"standards"},{"id":"scs-0111-v1-volume-type-decisions","path":"/standards/scs-0111-v1-volume-type-decisions","sidebar":"standards"},{"id":"scs-0112-v1-sonic","path":"/standards/scs-0112-v1-sonic","sidebar":"standards"},{"id":"scs-0113-v1-security-groups-decision-record","path":"/standards/scs-0113-v1-security-groups-decision-record","sidebar":"standards"},{"id":"scs-0114-v1-volume-type-standard","path":"/standards/scs-0114-v1-volume-type-standard","sidebar":"standards"},{"id":"scs-0115-v1-default-rules-for-security-groups","path":"/standards/scs-0115-v1-default-rules-for-security-groups","sidebar":"standards"},{"id":"scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","path":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","sidebar":"standards"},{"id":"scs-0210-v1-k8s-new-version-policy","path":"/standards/scs-0210-v1-k8s-new-version-policy","sidebar":"standards"},{"id":"scs-0210-v2-k8s-version-policy","path":"/standards/scs-0210-v2-k8s-version-policy","sidebar":"standards"},{"id":"scs-0211-v1-kaas-default-storage-class","path":"/standards/scs-0211-v1-kaas-default-storage-class","sidebar":"standards"},{"id":"scs-0212-v1-requirements-for-container-registries","path":"/standards/scs-0212-v1-requirements-for-container-registries","sidebar":"standards"},{"id":"scs-0213-v1-k8s-nodes-anti-affinity","path":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","sidebar":"standards"},{"id":"scs-0214-v1-k8s-node-distribution","path":"/standards/scs-0214-v1-k8s-node-distribution","sidebar":"standards"},{"id":"scs-0215-v1-robustness-features","path":"/standards/scs-0215-v1-robustness-features","sidebar":"standards"},{"id":"scs-0216-v1-requirements-for-testing-cluster-stacks","path":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","sidebar":"standards"},{"id":"scs-0217-v1-baseline-cluster-security","path":"/standards/scs-0217-v1-baseline-cluster-security","sidebar":"standards"},{"id":"scs-0218-v1-container-registry-for-scs-standard-implementation","path":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","sidebar":"standards"},{"id":"scs-0300-v1-requirements-for-sso-identity-federation","path":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","sidebar":"standards"},{"id":"scs-0301-v1-naming-conventions","path":"/standards/scs-0301-v1-naming-conventions","sidebar":"standards"},{"id":"scs-0302-v1-domain-manager-role","path":"/standards/scs-0302-v1-domain-manager-role","sidebar":"standards"},{"id":"scs-0400-v1-status-page-create-decision","path":"/standards/scs-0400-v1-status-page-create-decision","sidebar":"standards"},{"id":"scs-0401-v1-status-page-reference-implementation-decision","path":"/standards/scs-0401-v1-status-page-reference-implementation-decision","sidebar":"standards"},{"id":"scs-0402-v1-status-page-openapi-spec-decision","path":"/standards/scs-0402-v1-status-page-openapi-spec-decision","sidebar":"standards"},{"id":"scs-0403-v1-csp-kaas-observability-stack","path":"/standards/scs-0403-v1-csp-kaas-observability-stack","sidebar":"standards"},{"id":"scs-0410-v1-gnocchi-as-metering-database","path":"/standards/scs-0410-v1-gnocchi-as-metering-database","sidebar":"standards"},{"id":"scs-0411-v1-publishing_method_for_metering_data","path":"/standards/scs-0411-v1-publishing_method_for_metering_data","sidebar":"standards"},{"id":"scs-0412-v1-metering-json","path":"/standards/scs-0412-v1-metering-json","sidebar":"standards"},{"id":"scs-compatible-iaas","path":"/standards/scs-compatible-iaas","sidebar":"standards"},{"id":"scs-compatible-kaas","path":"/standards/scs-compatible-kaas","sidebar":"standards"},{"id":"scs-XXXX-vN-decision-record-template","path":"/standards/scs-XXXX-vN-decision-record-template"},{"id":"scs-XXXX-vN-standard-template","path":"/standards/scs-XXXX-vN-standard-template"},{"id":"standards/overview","path":"/standards/standards/overview","sidebar":"standards"}],"draftIds":[],"sidebars":{"standards":{"link":{"path":"/standards/","label":"index"}}}}],"breadcrumbs":true}},"global-data-plugin":{"default":{"architecturalOverviewData":{"ops":[{"title":"Ops Layer","body":"Tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.","url":"/docs/category/operating-scs","buttonText":"Learn More","components":[{"title":"Status Page","url":"/docs/operating-scs/components/status-page/docs/overview","mandatory":"true","stable":"true"},{"title":"Monitoring","url":"/docs/category/monitoring","mandatory":"false","stable":"true"},{"title":"Central API","url":"/docs/operating-scs/components/central-api/overview","mandatory":"true","stable":"true"},{"title":"Automated Pentesting","url":"/docs/operating-scs/components/automated-pentesting/overview","mandatory":"true","stable":"true"}]}],"container":[{"title":"Container Layer","body":"SCS offers a robust solution for managing container workloads on a Kubernetes infrastructure.","url":"/docs/container","buttonText":"Learn More","components":[{"title":"KaaS V1: K8s Cluster API Provider","url":"/docs/category/k8s-cluster-api-provider","mandatory":"false","stable":"true"},{"title":"KaaS V2: Cluster Stacks","url":"/docs/category/cluster-stacks","mandatory":"false","stable":"true"},{"title":"Container Registry","url":"/docs/category/container-registry","mandatory":"false","stable":"true"}]}],"iaas":[{"title":"IaaS Layer","body":"SCS offers OpenStack infrastructure solutions based on KVM virtualization to deploy VM workloads and enabling the container layer optionally.","url":"/docs/category/iaas-layer","buttonText":"Learn More","components":[{"title":"Image Manager","url":"/docs/iaas/components/image-manager","mandatory":"true","stable":"true"},{"title":"Flavor Manager","url":"/docs/iaas/components/flavor-manager","mandatory":"true","stable":"true"}]}],"iam":[{"title":"IAM Layer","body":"Working on Keycloak federated identity provider within our Team IAM.","url":"/docs/iam","buttonText":"Learn More","components":[{"title":"Keycloak","url":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","mandatory":"false","stable":"true"}]}]},"additionalResourcesData":[{"title":"Get in touch","body":"Come into our Matrix Chat in the SCS | Tech Room.","url":"https://matrix.to/#/#scs-tech:matrix.org","buttonText":"Join Now"},{"title":"Come to our Meet-Ups","body":"Our working groups and special interest groups meet weekly or biweekly. When? Find out within our public community calendar.","url":"/community/collaboration","buttonText":"Learn More"},{"title":"Standardization in progress","body":"Get to know our current Decision Records and Standards.","url":"/standards","buttonText":"Start Now"},{"title":"Deployment Examples","body":"Get to know different ways to deploy SCS with cloud resources or on bare metal.","url":"/docs/iaas/guides/deploy-guide/examples","buttonText":"Explore Cases"}],"featureContentData":[{"title":"Introduction to SCS","body":"Get to know SCS better and learn about the background.","url":"/docs","buttonText":"Get Started"},{"title":"Releases","body":"SCS is currently in Release 6. Check out the latest Release Notes.","url":"/docs/releases/Release6","buttonText":"Learn More"},{"title":"Frequently Asked Questions","body":"You are curious what SCS is all about, what it can do and what it can\'t?","url":"/docs/faq","buttonText":"Get Answers"},{"title":"Existing Public Clouds","body":"There are SCS compliant public clouds in production.","url":"/standards/certification/overview#compliant-cloud-environments","buttonText":"Test Them"}]}}}'),r=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var i=n(22654);const c=JSON.parse('{"docusaurusVersion":"3.2.1","siteVersion":"1.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.2.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.2.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.2.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.2.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.2.1"},"docusaurus-plugin-client-redirects":{"type":"package","name":"@docusaurus/plugin-client-redirects","version":"3.2.1"},"docusaurus-plugin-matomo-analytics":{"type":"project"},"global-data-plugin":{"type":"project"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"3.2.1"},"@easyops-cn/docusaurus-search-local":{"type":"package","name":"@easyops-cn/docusaurus-search-local","version":"0.40.1"}}}');var d=n(74848);const u={siteConfig:o.default,siteMetadata:c,globalData:s,i18n:r,codeTranslations:i},l=a.createContext(u);function p(e){let{children:t}=e;return(0,d.jsx)(l.Provider,{value:u,children:t})}},67489:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});var a=n(96540),o=n(38193),s=n(5260),r=n(70440),i=n(72415),c=n(53102),d=n(74848);function u(e){let{error:t,tryAgain:n}=e;return(0,d.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,d.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,d.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,d.jsx)(l,{error:t})]})}function l(e){let{error:t}=e;const n=(0,r.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,d.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function p(e){let{children:t}=e;return(0,d.jsx)(c.W,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:t})}function g(e){let{error:t,tryAgain:n}=e;return(0,d.jsx)(p,{children:(0,d.jsxs)(f,{fallback:()=>(0,d.jsx)(u,{error:t,tryAgain:n}),children:[(0,d.jsx)(s.A,{children:(0,d.jsx)("title",{children:"Page Error"})}),(0,d.jsx)(i.A,{children:(0,d.jsx)(u,{error:t,tryAgain:n})})]})})}const m=e=>(0,d.jsx)(g,{...e});class f extends a.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??m)(e)}return e??null}}},38193:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const a="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:a,canUseEventListeners:a&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:a&&"IntersectionObserver"in window,canUseViewport:a&&"screen"in window}},5260:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});n(96540);var a=n(80545),o=n(74848);function s(e){return(0,o.jsx)(a.mg,{...e})}},28774:(e,t,n)=>{"use strict";n.d(t,{A:()=>g});var a=n(96540),o=n(54625),s=n(70440),r=n(44586),i=n(16654),c=n(38193),d=n(63427),u=n(86025),l=n(74848);function p(e,t){let{isNavLink:n,to:p,href:g,activeClassName:m,isActive:f,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:{trailingSlash:v,baseUrl:k}}=(0,r.A)(),{withBaseUrl:x}=(0,u.h)(),w=(0,d.A)(),_=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>_.current));const S=p||g;const E=(0,i.A)(S),C=S?.replace("pathname://","");let T=void 0!==C?(A=C,b&&(e=>e.startsWith("/"))(A)?x(A):A):void 0;var A;T&&E&&(T=(0,s.applyTrailingSlash)(T,{trailingSlash:v,baseUrl:k}));const j=(0,a.useRef)(!1),L=n?o.k2:o.N_,P=c.A.canUseIntersectionObserver,N=(0,a.useRef)(),R=()=>{j.current||null==T||(window.docusaurus.preload(T),j.current=!0)};(0,a.useEffect)((()=>(!P&&E&&null!=T&&window.docusaurus.prefetch(T),()=>{P&&N.current&&N.current.disconnect()})),[N,T,P,E]);const O=T?.startsWith("#")??!1,I=!y.target||"_self"===y.target,F=!T||!E||!I||O;return h||!O&&F||w.collectLink(T),y.id&&w.collectAnchor(y.id),F?(0,l.jsx)("a",{ref:_,href:T,...S&&!E&&{target:"_blank",rel:"noopener noreferrer"},...y}):(0,l.jsx)(L,{...y,onMouseEnter:R,onTouchStart:R,innerRef:e=>{_.current=e,P&&e&&E&&(N.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(N.current.unobserve(e),N.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),N.current.observe(e))},to:T,...n&&{isActive:f,activeClassName:m}})}const g=a.forwardRef(p)},21312:(e,t,n)=>{"use strict";n.d(t,{A:()=>d,T:()=>c});var a=n(96540),o=n(74848);function s(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,a.isValidElement)(e)))?n.map(((e,t)=>(0,a.isValidElement)(e)?a.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var r=n(22654);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return r[t??n]??n??t}function c(e,t){let{message:n,id:a}=e;return s(i({message:n,id:a}),t)}function d(e){let{children:t,id:n,values:a}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const r=i({message:t,id:n});return(0,o.jsx)(o.Fragment,{children:s(r,a)})}},17065:(e,t,n)=>{"use strict";n.d(t,{W:()=>a});const a="default"},16654:(e,t,n)=>{"use strict";function a(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!a(e)}n.d(t,{A:()=>o,z:()=>a})},86025:(e,t,n)=>{"use strict";n.d(t,{A:()=>i,h:()=>r});var a=n(96540),o=n(44586),s=n(16654);function r(){const{siteConfig:{baseUrl:e,url:t}}=(0,o.A)(),n=(0,a.useCallback)(((n,a)=>function(e,t,n,a){let{forcePrependBaseUrl:o=!1,absolute:r=!1}=void 0===a?{}:a;if(!n||n.startsWith("#")||(0,s.z)(n))return n;if(o)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const i=n.startsWith(t)?n:t+n.replace(/^\//,"");return r?e+i:i}(t,e,n,a)),[t,e]);return{withBaseUrl:n}}function i(e,t){void 0===t&&(t={});const{withBaseUrl:n}=r();return n(e,t)}},63427:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});var a=n(96540);n(74848);const o=a.createContext({collectAnchor:()=>{},collectLink:()=>{}}),s=()=>(0,a.useContext)(o);function r(){return s()}},44586:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var a=n(96540),o=n(26988);function s(){return(0,a.useContext)(o.o)}},92303:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var a=n(96540),o=n(6125);function s(){return(0,a.useContext)(o.o)}},205:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var a=n(96540);const o=n(38193).A.canUseDOM?a.useLayoutEffect:a.useEffect},36803:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var a=n(96540),o=n(53102);function s(){const e=a.useContext(o.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}},86921:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const a=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach((n=>{let[s,r]=n;const i=o?`${o}.${s}`:s;a(r)?e(r,i):t[i]=r}))}(e),t}},53102:(e,t,n)=>{"use strict";n.d(t,{W:()=>r,o:()=>s});var a=n(96540),o=n(74848);const s=a.createContext(null);function r(e){let{children:t,value:n}=e;const r=a.useContext(s),i=(0,a.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const a={...t.data,...n?.data};return{plugin:t.plugin,data:a}}({parent:r,value:n})),[r,n]);return(0,o.jsx)(s.Provider,{value:i,children:t})}},44070:(e,t,n)=>{"use strict";n.d(t,{zK:()=>f,vT:()=>p,Gy:()=>u,HW:()=>h,ht:()=>l,r7:()=>m,jh:()=>g});var a=n(56347),o=n(44586),s=n(17065);function r(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const i=e=>e.versions.find((e=>e.isLast));function c(e,t){const n=function(e,t){const n=i(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,a.B6)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),o=n?.docs.find((e=>!!(0,a.B6)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((a=>{a.id===t&&(n[e.name]=a)}))})),n}(o.id):{}}}const d={},u=()=>r("docusaurus-plugin-content-docs")??d,l=e=>{try{return function(e,t,n){void 0===t&&(t=s.W),void 0===n&&(n={});const a=r(e),o=a?.[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function p(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,a.zy)();return function(e,t,n){void 0===n&&(n={});const o=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,a.B6)(t,{path:n.path,exact:!1,strict:!1})})),s=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!s&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return s}(t,n,e)}function g(e){return l(e).versions}function m(e){const t=l(e);return i(t)}function f(e){const t=l(e),{pathname:n}=(0,a.zy)();return c(t,n)}function h(e){const t=l(e),{pathname:n}=(0,a.zy)();return function(e,t){const n=i(e);return{latestDocSuggestion:c(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},76294:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var a=n(5947),o=n.n(a);o().configure({showSpinner:!1});const s={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},26134:(e,t,n)=>{"use strict";n.r(t);var a=n(78181),o=n(4784);!function(e){const{themeConfig:{prism:t}}=o.default,{additionalLanguages:a}=t;globalThis.Prism=e,a.forEach((e=>{"php"===e&&n(19700),n(75430)(`./prism-${e}`)})),delete globalThis.Prism}(a.My)},51107:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(96540);var a=n(18215),o=n(21312),s=n(6342),r=n(28774),i=n(63427);const c={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var d=n(74848);function u(e){let{as:t,id:n,...u}=e;const l=(0,i.A)(),{navbar:{hideOnScroll:p}}=(0,s.p)();if("h1"===t||!n)return(0,d.jsx)(t,{...u,id:void 0});l.collectAnchor(n);const g=(0,o.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return(0,d.jsxs)(t,{...u,className:(0,a.A)("anchor",p?c.anchorWithHideOnScrollNavbar:c.anchorWithStickyNavbar,u.className),id:n,children:[u.children,(0,d.jsx)(r.A,{className:"hash-link",to:`#${n}`,"aria-label":g,title:g,children:"\u200b"})]})}},43186:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});n(96540);const a={iconExternalLink:"iconExternalLink_nPIU"};var o=n(74848);function s(e){let{width:t=13.5,height:n=13.5}=e;return(0,o.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink,children:(0,o.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},72415:(e,t,n)=>{"use strict";n.d(t,{A:()=>Pt});var a=n(96540),o=n(18215),s=n(67489),r=n(61213),i=n(56347),c=n(21312),d=n(75062),u=n(74848);const l="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function g(){const e=(0,a.useRef)(null),{action:t}=(0,i.W6)(),n=(0,a.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(l);t&&p(t)}),[]);return(0,d.$)((n=>{let{location:a}=n;e.current&&!a.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const m=(0,c.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function f(e){const t=e.children??m,{containerRef:n,onClick:a}=g();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":m,children:(0,u.jsx)("a",{...e,href:`#${l}`,onClick:a,children:t})})}var h=n(17559),b=n(14090);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(f,{className:y.skipToContent})}var k=n(6342),x=n(65041);function w(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:o=1.2,className:s,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...r,children:(0,u.jsx)("g",{stroke:a,strokeWidth:o,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const _={closeButton:"closeButton_CVFx"};function S(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,c.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.A)("clean-btn close",_.closeButton,e.className),children:(0,u.jsx)(w,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,k.p)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,o.A)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function A(){const{announcementBar:e}=(0,k.p)(),{isActive:t,close:n}=(0,x.Mj)();if(!t)return null;const{backgroundColor:a,textColor:o,isCloseable:s}=e;return(0,u.jsxs)("div",{className:T.announcementBar,style:{backgroundColor:a,color:o},role:"banner",children:[s&&(0,u.jsx)("div",{className:T.announcementBarPlaceholder}),(0,u.jsx)(C,{className:T.announcementBarContent}),s&&(0,u.jsx)(S,{onClick:n,className:T.announcementBarClose})]})}var j=n(22069),L=n(23104);var P=n(89532),N=n(75600);const R=a.createContext(null);function O(e){let{children:t}=e;const n=function(){const e=(0,j.M)(),t=(0,N.YL)(),[n,o]=(0,a.useState)(!1),s=null!==t.component,r=(0,P.ZC)(s);return(0,a.useEffect)((()=>{s&&!r&&o(!0)}),[s,r]),(0,a.useEffect)((()=>{s?e.shown||o(!0):o(!1)}),[e.shown,s]),(0,a.useMemo)((()=>[n,o]),[n])}();return(0,u.jsx)(R.Provider,{value:n,children:t})}function I(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function F(){const e=(0,a.useContext)(R);if(!e)throw new P.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,a.useCallback)((()=>n(!1)),[n]),s=(0,N.YL)();return(0,a.useMemo)((()=>({shown:t,hide:o,content:I(s)})),[o,s,t])}function D(e){let{header:t,primaryMenu:n,secondaryMenu:a}=e;const{shown:s}=F();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,o.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":s}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:a})]})]})}var M=n(95293),z=n(92303);function B(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function Q(e){let{className:t,buttonClassName:n,value:a,onChange:s}=e;const r=(0,z.A)(),i=(0,c.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===a?(0,c.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,o.A)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,o.A)("clean-btn",U.toggleButton,!r&&U.toggleButtonDisabled,n),type:"button",onClick:()=>s("dark"===a?"light":"dark"),disabled:!r,title:i,"aria-label":i,"aria-live":"polite",children:[(0,u.jsx)(B,{className:(0,o.A)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)($,{className:(0,o.A)(U.toggleIcon,U.darkToggleIcon)})]})})}const V=a.memo(Q),H={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function W(e){let{className:t}=e;const n=(0,k.p)().navbar.style,a=(0,k.p)().colorMode.disableSwitch,{colorMode:o,setColorMode:s}=(0,M.G)();return a?null:(0,u.jsx)(V,{className:t,buttonClassName:"dark"===n?H.darkNavbarColorModeToggle:void 0,value:o,onChange:s})}var q=n(23465);function G(){return(0,u.jsx)(q.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function X(){const e=(0,j.M)();return(0,u.jsx)("button",{type:"button","aria-label":(0,c.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(w,{color:"var(--ifm-color-emphasis-600)"})})}function K(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(G,{}),(0,u.jsx)(W,{className:"margin-right--md"}),(0,u.jsx)(X,{})]})}var Y=n(28774),Z=n(86025),J=n(16654);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(43186);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:o,label:s,html:r,isDropdownLink:i,prependBaseUrlToHref:c,...d}=e;const l=(0,Z.A)(a),p=(0,Z.A)(t),g=(0,Z.A)(o,{forcePrependBaseUrl:!0}),m=s&&o&&!(0,J.A)(o),f=r?{dangerouslySetInnerHTML:{__html:r}}:{children:(0,u.jsxs)(u.Fragment,{children:[s,m&&(0,u.jsx)(te.A,{...i&&{width:12,height:12}})]})};return o?(0,u.jsx)(Y.A,{href:c?g:o,...d,...f}):(0,u.jsx)(Y.A,{to:l,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(p)},...d,...f})}function ae(e){let{className:t,isDropdownItem:n=!1,...a}=e;const s=(0,u.jsx)(ne,{className:(0,o.A)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...a});return n?(0,u.jsx)("li",{children:s}):s}function oe(e){let{className:t,isDropdownItem:n,...a}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,o.A)("menu__link",t),...a})})}function se(e){let{mobile:t=!1,position:n,...a}=e;const o=t?oe:ae;return(0,u.jsx)(o,{...a,activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var re=n(41422),ie=n(99169),ce=n(44586);const de={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ue(e,t){return e.some((e=>function(e,t){return!!(0,ie.ys)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function le(e){let{items:t,position:n,className:s,onClick:r,...i}=e;const c=(0,a.useRef)(null),[d,l]=(0,a.useState)(!1);return(0,a.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&l(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),(0,u.jsxs)("div",{ref:c,className:(0,o.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":d}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":d,role:"button",href:i.to?void 0:"#",className:(0,o.A)("navbar__link",s),...i,onClick:i.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),l(!d))},children:i.children??i.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,a.createElement)(qe,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function pe(e){let{items:t,className:n,position:s,onClick:r,...c}=e;const d=function(){const{siteConfig:{baseUrl:e}}=(0,ce.A)(),{pathname:t}=(0,i.zy)();return t.replace(e,"/")}(),l=ue(t,d),{collapsed:p,toggleCollapsed:g,setCollapsed:m}=(0,re.u)({initialState:()=>!l});return(0,a.useEffect)((()=>{l&&m(!l)}),[d,l,m]),(0,u.jsxs)("li",{className:(0,o.A)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,u.jsx)(ne,{role:"button",className:(0,o.A)(de.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...c,onClick:e=>{e.preventDefault(),g()},children:c.children??c.label}),(0,u.jsx)(re.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,a.createElement)(qe,{mobile:!0,isDropdownItem:!0,onClick:r,activeClassName:"menu__link--active",...e,key:t})))})]})}function ge(e){let{mobile:t=!1,...n}=e;const a=t?pe:le;return(0,u.jsx)(a,{...n})}var me=n(32131);function fe(e){let{width:t=20,height:n=20,...a}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...a,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const he="iconLanguage_nlXk";var be=n(11088),ye=n(20053),ve=n(55597),ke=n(44070),xe=n(5891),we=n(32384),_e=n(4471),Se=n(27674),Ee=n(86841),Ce=n(43810);const Te='<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17 6v12c0 .52-.2 1-1 1H4c-.7 0-1-.33-1-1V2c0-.55.42-1 1-1h8l5 5zM14 8h-3.13c-.51 0-.87-.34-.87-.87V4" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linejoin="round"></path></svg>',Ae='<svg width="20" height="20" viewBox="0 0 20 20"><path d="M13 13h4-4V8H7v5h6v4-4H7V8H3h4V3v5h6V3v5h4-4v5zm-6 0v4-4H3h4z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg>',je='<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17 5H3h14zm0 5H3h14zm0 5H3h14z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linejoin="round"></path></svg>',Le='<svg width="20" height="20" viewBox="0 0 20 20"><g stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><path d="M18 3v4c0 2-2 4-4 4H2"></path><path d="M8 17l-6-6 6-6"></path></g></svg>',Pe='<svg width="40" height="40" viewBox="0 0 20 20" fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M15.5 4.8c2 3 1.7 7-1 9.7h0l4.3 4.3-4.3-4.3a7.8 7.8 0 01-9.8 1m-2.2-2.2A7.8 7.8 0 0113.2 2.4M2 18L18 2"></path></svg>',Ne='<svg viewBox="0 0 24 54"><g stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6v42M20 27H8.3"></path></g></svg>',Re='<svg viewBox="0 0 24 54"><g stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6v21M20 27H8.3"></path></g></svg>',Oe={searchBar:"searchBar_RVTs",dropdownMenu:"dropdownMenu_qbY6",searchBarLeft:"searchBarLeft_MXDe",suggestion:"suggestion_fB_2",cursor:"cursor_eG29",hitTree:"hitTree_kk6K",hitIcon:"hitIcon_a7Zy",hitPath:"hitPath_ieM4",noResultsIcon:"noResultsIcon_EBY5",hitFooter:"hitFooter_E9YW",hitWrapper:"hitWrapper_sAK8",hitTitle:"hitTitle_vyVt",hitAction:"hitAction_NqkB",hideAction:"hideAction_vcyE",noResults:"noResults_l6Q3",searchBarContainer:"searchBarContainer_NW3z",searchBarLoadingRing:"searchBarLoadingRing_YnHq",searchClearButton:"searchClearButton_qk4g",searchIndexLoading:"searchIndexLoading_EJ1f",searchHintContainer:"searchHintContainer_Pkmr",searchHint:"searchHint_iIMx",focused:"focused_OWtg",input:"input_FOTf",hint:"hint_URu1",suggestions:"suggestions_X8XU",dataset:"dataset_QiCy",empty:"empty_eITn"};function Ie(e){let{document:t,type:n,page:a,metadata:o,tokens:s,isInterOfTree:r,isLastOfTree:i}=e;const c=0===n,d=1===n,u=[];r?u.push(Ne):i&&u.push(Re);const l=u.map((e=>`<span class="${Oe.hitTree}">${e}</span>`)),p=`<span class="${Oe.hitIcon}">${c?Te:d?Ae:je}</span>`,g=[`<span class="${Oe.hitTitle}">${(0,Ce.C)(t.t,(0,Se.g)(o,"t"),s)}</span>`];if(!r&&!i&&be.tb){const e=a?(a.b??[]).concat(a.t).concat(t.s&&t.s!==a.t?t.s:[]):t.b;g.push(`<span class="${Oe.hitPath}">${(0,_e.$)(e??[])}</span>`)}else c||g.push(`<span class="${Oe.hitPath}">${(0,Ee.Z)(a.t||(t.u.startsWith("/docs/api-reference/")?"API Reference":""),s)}</span>`);const m=`<span class="${Oe.hitAction}">${Le}</span>`;return[...l,p,`<span class="${Oe.hitWrapper}">`,...g,"</span>",m].join("")}function Fe(){return`<span class="${Oe.noResults}"><span class="${Oe.noResultsIcon}">${Pe}</span><span>${(0,c.T)({id:"theme.SearchBar.noResultsText",message:"No results"})}</span></span>`}var De=n(2849),Me=n(43385);async function ze(){const e=await Promise.all([n.e(489),n.e(5741)]).then(n.t.bind(n,90489,23)),t=e.default;return t.noConflict?t.noConflict():e.noConflict&&e.noConflict(),t}const Be="_highlight";const $e=function(e){let{handleSearchBarToggle:t}=e;const n=(0,z.A)(),{siteConfig:{baseUrl:o},i18n:{currentLocale:s}}=(0,ce.A)(),r=(0,ke.vT)();let d=o;try{const{preferredVersion:e}=(0,ve.g1)(r?.pluginId??be.UB);e&&!e.isLast&&(d=e.path+"/")}catch(D){if(be.I$&&!(D instanceof P.dV))throw D}const l=(0,i.W6)(),p=(0,i.zy)(),g=(0,a.useRef)(null),m=(0,a.useRef)(new Map),f=(0,a.useRef)(!1),[h,b]=(0,a.useState)(!1),[y,v]=(0,a.useState)(!1),[k,x]=(0,a.useState)(""),w=(0,a.useRef)(null),_=(0,a.useRef)(""),[S,E]=(0,a.useState)("");(0,a.useEffect)((()=>{if(!Array.isArray(be.Hg))return;let e="";if(p.pathname.startsWith(d)){const t=p.pathname.substring(d.length);let n;for(const e of be.Hg){const a="string"==typeof e?e:e.path;if(t===a||t.startsWith(`${a}/`)){n=a;break}}n&&(e=n)}_.current!==e&&(m.current.delete(e),_.current=e),E(e)}),[p.pathname,d]);const C=!!be.O6&&Array.isArray(be.Hg)&&""===S,T=(0,a.useCallback)((async()=>{if(C||m.current.get(S))return;m.current.set(S,"loading"),w.current?.autocomplete.destroy(),b(!0);const[{wrappedIndexes:e,zhDictionary:t},n]=await Promise.all([(0,xe.Z)(d,S),ze()]);if(w.current=n(g.current,{hint:!1,autoselect:!0,openOnFocus:!0,cssClasses:{root:(0,ye.A)(Oe.searchBar,{[Oe.searchBarLeft]:"left"===be.ZG}),noPrefix:!0,dropdownMenu:Oe.dropdownMenu,input:Oe.input,hint:Oe.hint,suggestions:Oe.suggestions,suggestion:Oe.suggestion,cursor:Oe.cursor,dataset:Oe.dataset,empty:Oe.empty}},[{source:(0,we.m)(e,t,be.AT),templates:{suggestion:Ie,empty:Fe,footer:e=>{let{query:t,isEmpty:n}=e;if(n&&(!S||!be.dz))return;const a=(e=>{let{query:t,isEmpty:n}=e;const a=document.createElement("a"),r=new URLSearchParams;let i;if(r.set("q",t),S){const e=S&&Array.isArray(be.Hg)?be.Hg.find((e=>"string"==typeof e?e===S:e.path===S)):S,t=e?(0,Me.p)(e,s).label:S;i=be.dz&&n?(0,c.T)({id:"theme.SearchBar.seeAllOutsideContext",message:"See results outside {context}"},{context:t}):(0,c.T)({id:"theme.SearchBar.searchInContext",message:"See all results in {context}"},{context:t})}else i=(0,c.T)({id:"theme.SearchBar.seeAll",message:"See all results"});if(!S||!Array.isArray(be.Hg)||be.dz&&n||r.set("ctx",S),d!==o){if(!d.startsWith(o))throw new Error(`Version url '${d}' does not start with base url '${o}', this is a bug of \`@easyops-cn/docusaurus-search-local\`, please report it.`);r.set("version",d.substring(o.length))}const u=`${o}search?${r.toString()}`;return a.href=u,a.textContent=i,a.addEventListener("click",(e=>{e.ctrlKey||e.metaKey||(e.preventDefault(),w.current?.autocomplete.close(),l.push(u))})),a})({query:t,isEmpty:n}),r=document.createElement("div");return r.className=Oe.hitFooter,r.appendChild(a),r}}}]).on("autocomplete:selected",(function(e,t){let{document:{u:n,h:a},tokens:o}=t;g.current?.blur();let s=n;if(be.CU&&o.length>0){const e=new URLSearchParams;for(const t of o)e.append(Be,t);s+=`?${e.toString()}`}a&&(s+=a),l.push(s)})).on("autocomplete:closed",(()=>{g.current?.blur()})),m.current.set(S,"done"),b(!1),f.current){const e=g.current;e.value&&w.current?.autocomplete.open(),e.focus()}}),[C,S,d,o,l]);(0,a.useEffect)((()=>{if(!be.CU)return;const e=n?new URLSearchParams(p.search).getAll(Be):[];setTimeout((()=>{const t=document.querySelector("article");if(!t)return;const n=new be.CU(t);n.unmark(),0!==e.length&&n.mark(e),x(e.join(" ")),w.current?.autocomplete.setVal(e.join(" "))}))}),[n,p.search,p.pathname]);const[A,j]=(0,a.useState)(!1),L=(0,a.useCallback)((()=>{f.current=!0,T(),j(!0),t?.(!0)}),[t,T]),N=(0,a.useCallback)((()=>{j(!1),t?.(!1)}),[t]),R=(0,a.useCallback)((()=>{T()}),[T]),O=(0,a.useCallback)((e=>{x(e.target.value),e.target.value&&v(!0)}),[]),I=!!n&&/mac/i.test(navigator.userAgentData?.platform??navigator.platform);(0,a.useEffect)((()=>{if(!be.WW)return;const e=e=>{!(I?e.metaKey:e.ctrlKey)||"k"!==e.key&&"K"!==e.key||(e.preventDefault(),g.current?.focus(),L())};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}}),[I,L]);const F=(0,a.useCallback)((()=>{const e=new URLSearchParams(p.search);e.delete(Be);const t=e.toString(),n=p.pathname+(""!=t?`?${t}`:"")+p.hash;n!=p.pathname+p.search+p.hash&&l.push(n),x(""),w.current?.autocomplete.setVal("")}),[p.pathname,p.search,p.hash,l]);return(0,u.jsxs)("div",{className:(0,ye.A)("navbar__search",Oe.searchBarContainer,{[Oe.searchIndexLoading]:h&&y,[Oe.focused]:A}),hidden:C,children:[(0,u.jsx)("input",{placeholder:(0,c.T)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),"aria-label":"Search",className:"navbar__search-input",onMouseEnter:R,onFocus:L,onBlur:N,onChange:O,ref:g,value:k}),(0,u.jsx)(De.A,{className:Oe.searchBarLoadingRing}),be.WW&&be.pk&&(""!==k?(0,u.jsx)("button",{className:Oe.searchClearButton,onClick:F,children:"\u2715"}):n&&(0,u.jsxs)("div",{className:Oe.searchHintContainer,children:[(0,u.jsx)("kbd",{className:Oe.searchHint,children:I?"\u2318":"ctrl"}),(0,u.jsx)("kbd",{className:Oe.searchHint,children:"K"})]}))]})},Ue={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Qe(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,o.A)(n,Ue.navbarSearchContainer),children:t})}var Ve=n(84142);const He=e=>e.docs.find((t=>t.id===e.mainDocId));const We={default:se,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,queryString:o="",...s}=e;const{i18n:{currentLocale:r,locales:d,localeConfigs:l}}=(0,ce.A)(),p=(0,me.o)(),{search:g,hash:m}=(0,i.zy)(),f=[...n,...d.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${g}${m}${o}`;return{label:l[e].label,lang:l[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===r?t?"menu__link--active":"dropdown__link--active":""}})),...a],h=t?(0,c.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):l[r].label;return(0,u.jsx)(ge,{...s,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(fe,{className:he}),h]}),items:f})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(Qe,{className:n,children:(0,u.jsx)($e,{})})},dropdown:ge,html:function(e){let{value:t,className:n,mobile:a=!1,isDropdownItem:s=!1}=e;const r=s?"li":"div";return(0,u.jsx)(r,{className:(0,o.A)({navbar__item:!a&&!s,"menu__list-item":a},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:s}=(0,ke.zK)(a),r=(0,Ve.QB)(t,a),i=s?.path===r?.path;return null===r||r.unlisted&&!i?null:(0,u.jsx)(se,{exact:!0,...o,isActive:()=>i||!!s?.sidebar&&s.sidebar===r.sidebar,label:n??r.id,to:r.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:s}=(0,ke.zK)(a),r=(0,Ve.fW)(t,a).link;if(!r)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(se,{exact:!0,...o,isActive:()=>s?.sidebar===t,label:n??r.label,to:r.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...o}=e;const s=(0,Ve.Vd)(a)[0],r=t??s.label,i=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(s).path;return(0,u.jsx)(se,{...o,label:r,to:i})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:o,dropdownItemsAfter:s,...r}=e;const{search:d,hash:l}=(0,i.zy)(),p=(0,ke.zK)(n),g=(0,ke.jh)(n),{savePreferredVersionName:m}=(0,ve.g1)(n),f=[...o,...g.map((e=>{const t=p.alternateDocVersions[e.name]??He(e);return{label:e.label,to:`${t.path}${d}${l}`,isActive:()=>e===p.activeVersion,onClick:()=>m(e.name)}})),...s],h=(0,Ve.Vd)(n)[0],b=t&&f.length>1?(0,c.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):h.label,y=t&&f.length>1?void 0:He(h).path;return f.length<=1?(0,u.jsx)(se,{...r,mobile:t,label:b,to:y,isActive:a?()=>!1:void 0}):(0,u.jsx)(ge,{...r,mobile:t,label:b,to:y,items:f,isActive:a?()=>!1:void 0})}};function qe(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=We[a];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(o,{...n})}function Ge(){const e=(0,j.M)(),t=(0,k.p)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,a.createElement)(qe,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Xe(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(c.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Ke(){const e=0===(0,k.p)().navbar.items.length,t=F();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Xe,{onClick:()=>t.hide()}),t.content]})}function Ye(){const e=(0,j.M)();var t;return void 0===(t=e.shown)&&(t=!0),(0,a.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(D,{header:(0,u.jsx)(K,{}),primaryMenu:(0,u.jsx)(Ge,{}),secondaryMenu:(0,u.jsx)(Ke,{})}):null}const Ze={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Je(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,o.A)("navbar-sidebar__backdrop",e.className)})}function et(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:s}}=(0,k.p)(),r=(0,j.M)(),{navbarRef:i,isNavbarVisible:l}=function(e){const[t,n]=(0,a.useState)(e),o=(0,a.useRef)(!1),s=(0,a.useRef)(0),r=(0,a.useCallback)((e=>{null!==e&&(s.current=e.getBoundingClientRect().height)}),[]);return(0,L.Mq)(((t,a)=>{let{scrollY:r}=t;if(!e)return;if(r<s.current)return void n(!0);if(o.current)return void(o.current=!1);const i=a?.scrollY,c=document.documentElement.scrollHeight-s.current,d=window.innerHeight;i&&r>=i?n(!1):r+d<c&&n(!0)})),(0,d.$)((t=>{if(!e)return;const a=t.location.hash;if(a?document.getElementById(a.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:r,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:i,"aria-label":(0,c.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.A)("navbar","navbar--fixed-top",n&&[Ze.navbarHideable,!l&&Ze.navbarHidden],{"navbar--dark":"dark"===s,"navbar--primary":"primary"===s,"navbar-sidebar--show":r.shown}),children:[t,(0,u.jsx)(Je,{onClick:r.toggle}),(0,u.jsx)(Ye,{})]})}var tt=n(12181);const nt="right";function at(e){let{width:t=30,height:n=30,className:a,...o}=e;return(0,u.jsx)("svg",{className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function ot(){const{toggle:e,shown:t}=(0,j.M)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,c.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(at,{})})}const st={colorModeToggle:"colorModeToggle_DEke"};function rt(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(tt.k2,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(qe,{...e})},t)))})}function it(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function ct(){const e=(0,j.M)(),t=(0,k.p)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??nt)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,u.jsx)(it,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(ot,{}),(0,u.jsx)(G,{}),(0,u.jsx)(rt,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(rt,{items:a}),(0,u.jsx)(W,{className:st.colorModeToggle}),!o&&(0,u.jsx)(Qe,{children:(0,u.jsx)($e,{})})]})})}function dt(){return(0,u.jsx)(et,{children:(0,u.jsx)(ct,{})})}function ut(e){let{item:t}=e;const{to:n,href:a,label:o,prependBaseUrlToHref:s,...r}=t,i=(0,Z.A)(n),c=(0,Z.A)(a,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Y.A,{className:"footer__link-item",...a?{href:s?c:a}:{to:i},...r,children:[o,a&&!(0,J.A)(a)&&(0,u.jsx)(te.A,{})]})}function lt(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(ut,{item:t})},t.href??t.to)}function pt(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(lt,{item:e},t)))})]})}function gt(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(pt,{column:e},t)))})}function mt(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function ft(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(ut,{item:t})}function ht(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(a.Fragment,{children:[(0,u.jsx)(ft,{item:e}),t.length!==n+1&&(0,u.jsx)(mt,{})]},n)))})})}function bt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(gt,{columns:t}):(0,u.jsx)(ht,{links:t})}var yt=n(21122);const vt={footerLogoLink:"footerLogoLink_BH7S"};function kt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,Z.h)(),a={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(yt.A,{className:(0,o.A)("footer__logo",t.className),alt:t.alt,sources:a,width:t.width,height:t.height,style:t.style})}function xt(e){let{logo:t}=e;return t.href?(0,u.jsx)(Y.A,{href:t.href,className:vt.footerLogoLink,target:t.target,children:(0,u.jsx)(kt,{logo:t})}):(0,u.jsx)(kt,{logo:t})}function wt(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function _t(e){let{style:t,links:n,logo:a,copyright:s}=e;return(0,u.jsx)("footer",{className:(0,o.A)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(a||s)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[a&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:a}),s]})]})})}function St(){const{footer:e}=(0,k.p)();if(!e)return null;const{copyright:t,links:n,logo:a,style:o}=e;return(0,u.jsx)(_t,{style:o,links:n&&n.length>0&&(0,u.jsx)(bt,{links:n}),logo:a&&(0,u.jsx)(xt,{logo:a}),copyright:t&&(0,u.jsx)(wt,{copyright:t})})}const Et=a.memo(St),Ct=(0,P.fM)([M.a,x.oq,L.Tv,ve.VQ,r.Jx,function(e){let{children:t}=e;return(0,u.jsx)(N.y_,{children:(0,u.jsx)(j.e,{children:(0,u.jsx)(O,{children:t})})})}]);function Tt(e){let{children:t}=e;return(0,u.jsx)(Ct,{children:t})}var At=n(51107);function jt(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(At.A,{as:"h1",className:"hero__title",children:(0,u.jsx)(c.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(tt.a2,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(tt.bq,{error:t})})]})})})}const Lt={mainWrapper:"mainWrapper_z2l0"};function Pt(e){const{children:t,noFooter:n,wrapperClassName:a,title:i,description:c}=e;return(0,b.J)(),(0,u.jsxs)(Tt,{children:[(0,u.jsx)(r.be,{title:i,description:c}),(0,u.jsx)(v,{}),(0,u.jsx)(A,{}),(0,u.jsx)(dt,{}),(0,u.jsx)("div",{id:l,className:(0,o.A)(h.G.wrapper.main,Lt.mainWrapper,a),children:(0,u.jsx)(s.A,{fallback:e=>(0,u.jsx)(jt,{...e}),children:t})}),!n&&(0,u.jsx)(Et,{})]})}},23465:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(96540);var a=n(28774),o=n(86025),s=n(44586),r=n(6342),i=n(21122),c=n(74848);function d(e){let{logo:t,alt:n,imageClassName:a}=e;const s={light:(0,o.A)(t.src),dark:(0,o.A)(t.srcDark||t.src)},r=(0,c.jsx)(i.A,{className:t.className,sources:s,height:t.height,width:t.width,alt:n,style:t.style});return a?(0,c.jsx)("div",{className:a,children:r}):r}function u(e){const{siteConfig:{title:t}}=(0,s.A)(),{navbar:{title:n,logo:i}}=(0,r.p)(),{imageClassName:u,titleClassName:l,...p}=e,g=(0,o.A)(i?.href||"/"),m=n?"":t,f=i?.alt??m;return(0,c.jsxs)(a.A,{to:g,...p,...i?.target&&{target:i.target},children:[i&&(0,c.jsx)(d,{logo:i,alt:f,imageClassName:u}),null!=n&&(0,c.jsx)("b",{className:l,children:n})]})}},41463:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});n(96540);var a=n(5260),o=n(74848);function s(e){let{locale:t,version:n,tag:s}=e;const r=t;return(0,o.jsxs)(a.A,{children:[t&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_version",content:n}),s&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:s}),r&&(0,o.jsx)("meta",{name:"docsearch:language",content:r}),n&&(0,o.jsx)("meta",{name:"docsearch:version",content:n}),s&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:s})]})}},21122:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});var a=n(96540),o=n(15066),s=n(92303),r=n(95293);const i={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var c=n(74848);function d(e){let{className:t,children:n}=e;const d=(0,s.A)(),{colorMode:u}=(0,r.G)();return(0,c.jsx)(c.Fragment,{children:(d?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const s=n({theme:e,className:(0,o.A)(t,i.themedComponent,i[`themedComponent--${e}`])});return(0,c.jsx)(a.Fragment,{children:s},e)}))})}function u(e){const{sources:t,className:n,alt:a,...o}=e;return(0,c.jsx)(d,{className:n,children:e=>{let{theme:n,className:s}=e;return(0,c.jsx)("img",{src:t[n],alt:a,className:s,...o})}})}},41422:(e,t,n)=>{"use strict";n.d(t,{N:()=>b,u:()=>d});var a=n(96540),o=n(38193),s=n(205),r=n(53109),i=n(74848);const c="ease-in-out";function d(e){let{initialState:t}=e;const[n,o]=(0,a.useState)(t??!1),s=(0,a.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:n,setCollapsed:o,toggleCollapsed:s}}const u={display:"none",overflow:"hidden",height:"0px"},l={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?u:l;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function g(e){let{collapsibleRef:t,collapsed:n,animation:o}=e;const s=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=o?.duration??function(e){if((0,r.O)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${o?.easing??c}`,height:`${t}px`}}function i(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!s.current)return p(e,n),void(s.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(i(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{i()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function m(e){if(!o.A.canUseDOM)return e?u:l}function f(e){let{as:t="div",collapsed:n,children:o,animation:s,onCollapseTransitionEnd:r,className:c,disableSSRStyle:d}=e;const u=(0,a.useRef)(null);return g({collapsibleRef:u,collapsed:n,animation:s}),(0,i.jsx)(t,{ref:u,style:d?void 0:m(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(u.current,n),r?.(n))},className:c,children:o})}function h(e){let{collapsed:t,...n}=e;const[o,r]=(0,a.useState)(!t),[c,d]=(0,a.useState)(t);return(0,s.A)((()=>{t||r(!0)}),[t]),(0,s.A)((()=>{o&&d(t)}),[o,t]),o?(0,i.jsx)(f,{...n,collapsed:c}):null}function b(e){let{lazy:t,...n}=e;const a=t?h:f;return(0,i.jsx)(a,{...n})}},65041:(e,t,n)=>{"use strict";n.d(t,{Mj:()=>f,oq:()=>m});var a=n(96540),o=n(92303),s=n(89466),r=n(89532),i=n(6342),c=n(74848);const d=(0,s.Wf)("docusaurus.announcement.dismiss"),u=(0,s.Wf)("docusaurus.announcement.id"),l=()=>"true"===d.get(),p=e=>d.set(String(e)),g=a.createContext(null);function m(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,i.p)(),t=(0,o.A)(),[n,s]=(0,a.useState)((()=>!!t&&l()));(0,a.useEffect)((()=>{s(l())}),[]);const r=(0,a.useCallback)((()=>{p(!0),s(!0)}),[]);return(0,a.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const a=t!==n;u.set(t),a&&p(!1),!a&&l()||s(!1)}),[e]),(0,a.useMemo)((()=>({isActive:!!e&&!n,close:r})),[e,n,r])}();return(0,c.jsx)(g.Provider,{value:n,children:t})}function f(){const e=(0,a.useContext)(g);if(!e)throw new r.dV("AnnouncementBarProvider");return e}},95293:(e,t,n)=>{"use strict";n.d(t,{G:()=>b,a:()=>h});var a=n(96540),o=n(38193),s=n(89532),r=n(89466),i=n(6342),c=n(74848);const d=a.createContext(void 0),u="theme",l=(0,r.Wf)(u),p={light:"light",dark:"dark"},g=e=>e===p.dark?p.dark:p.light,m=e=>o.A.canUseDOM?g(document.documentElement.getAttribute("data-theme")):g(e),f=e=>{l.set(g(e))};function h(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,i.p)(),[o,s]=(0,a.useState)(m(e));(0,a.useEffect)((()=>{t&&l.del()}),[t]);const r=(0,a.useCallback)((function(t,a){void 0===a&&(a={});const{persist:o=!0}=a;t?(s(t),o&&f(t)):(s(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),l.del())}),[n,e]);(0,a.useEffect)((()=>{document.documentElement.setAttribute("data-theme",g(o))}),[o]),(0,a.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=l.get();null!==t&&r(g(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,r]);const c=(0,a.useRef)(!1);return(0,a.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),a=()=>{window.matchMedia("print").matches||c.current?c.current=window.matchMedia("print").matches:r(null)};return e.addListener(a),()=>e.removeListener(a)}),[r,t,n]),(0,a.useMemo)((()=>({colorMode:o,setColorMode:r,get isDarkTheme(){return o===p.dark},setLightTheme(){r(p.light)},setDarkTheme(){r(p.dark)}})),[o,r])}();return(0,c.jsx)(d.Provider,{value:n,children:t})}function b(){const e=(0,a.useContext)(d);if(null==e)throw new s.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},55597:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>b,g1:()=>v});var a=n(96540),o=n(44070),s=n(17065),r=n(6342),i=n(84142),c=n(89532),d=n(89466),u=n(74848);const l=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,d.Wf)(l(e),{persistence:t}).set(n)},read:(e,t)=>(0,d.Wf)(l(e),{persistence:t}).get(),clear:(e,t)=>{(0,d.Wf)(l(e),{persistence:t}).del()}},g=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const m=a.createContext(null);function f(){const e=(0,o.Gy)(),t=(0,r.p)().docs.versionPersistence,n=(0,a.useMemo)((()=>Object.keys(e)),[e]),[s,i]=(0,a.useState)((()=>g(n)));(0,a.useEffect)((()=>{i(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:a}=e;function o(e){const t=p.read(e,n);return a[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[s,(0,a.useMemo)((()=>({savePreferredVersion:function(e,n){p.save(e,t,n),i((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function h(e){let{children:t}=e;const n=f();return(0,u.jsx)(m.Provider,{value:n,children:t})}function b(e){let{children:t}=e;return i.C5?(0,u.jsx)(h,{children:t}):(0,u.jsx)(u.Fragment,{children:t})}function y(){const e=(0,a.useContext)(m);if(!e)throw new c.dV("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=s.W);const t=(0,o.ht)(e),[n,r]=y(),{preferredVersionName:i}=n[e];return{preferredVersion:t.versions.find((e=>e.name===i))??null,savePreferredVersionName:(0,a.useCallback)((t=>{r.savePreferredVersion(e,t)}),[r,e])}}},26588:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,t:()=>d});var a=n(96540),o=n(89532),s=n(74848);const r=Symbol("EmptyContext"),i=a.createContext(r);function c(e){let{children:t,name:n,items:o}=e;const r=(0,a.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return(0,s.jsx)(i.Provider,{value:r,children:t})}function d(){const e=(0,a.useContext)(i);if(e===r)throw new o.dV("DocsSidebarProvider");return e}},32252:(e,t,n)=>{"use strict";n.d(t,{n:()=>i,r:()=>c});var a=n(96540),o=n(89532),s=n(74848);const r=a.createContext(null);function i(e){let{children:t,version:n}=e;return(0,s.jsx)(r.Provider,{value:n,children:t})}function c(){const e=(0,a.useContext)(r);if(null===e)throw new o.dV("DocsVersionProvider");return e}},22069:(e,t,n)=>{"use strict";n.d(t,{M:()=>g,e:()=>p});var a=n(96540),o=n(75600),s=n(24581),r=n(57485),i=n(6342),c=n(89532),d=n(74848);const u=a.createContext(void 0);function l(){const e=function(){const e=(0,o.YL)(),{items:t}=(0,i.p)().navbar;return 0===t.length&&!e.component}(),t=(0,s.l)(),n=!e&&"mobile"===t,[c,d]=(0,a.useState)(!1);(0,r.$Z)((()=>{if(c)return d(!1),!1}));const u=(0,a.useCallback)((()=>{d((e=>!e))}),[]);return(0,a.useEffect)((()=>{"desktop"===t&&d(!1)}),[t]),(0,a.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:c})),[e,n,u,c])}function p(e){let{children:t}=e;const n=l();return(0,d.jsx)(u.Provider,{value:n,children:t})}function g(){const e=a.useContext(u);if(void 0===e)throw new c.dV("NavbarMobileSidebarProvider");return e}},75600:(e,t,n)=>{"use strict";n.d(t,{GX:()=>d,YL:()=>c,y_:()=>i});var a=n(96540),o=n(89532),s=n(74848);const r=a.createContext(null);function i(e){let{children:t}=e;const n=(0,a.useState)({component:null,props:null});return(0,s.jsx)(r.Provider,{value:n,children:t})}function c(){const e=(0,a.useContext)(r);if(!e)throw new o.dV("NavbarSecondaryMenuContentProvider");return e[0]}function d(e){let{component:t,props:n}=e;const s=(0,a.useContext)(r);if(!s)throw new o.dV("NavbarSecondaryMenuContentProvider");const[,i]=s,c=(0,o.Be)(n);return(0,a.useEffect)((()=>{i({component:t,props:c})}),[i,t,c]),(0,a.useEffect)((()=>()=>i({component:null,props:null})),[i]),null}},14090:(e,t,n)=>{"use strict";n.d(t,{w:()=>o,J:()=>s});var a=n(96540);const o="navigation-with-keyboard";function s(){(0,a.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},24581:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var a=n(96540),o=n(38193);const s={desktop:"desktop",mobile:"mobile",ssr:"ssr"},r=996;function i(e){let{desktopBreakpoint:t=r}=void 0===e?{}:e;const[n,i]=(0,a.useState)((()=>"ssr"));return(0,a.useEffect)((()=>{function e(){i(function(e){if(!o.A.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?s.desktop:s.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},17559:(e,t,n)=>{"use strict";n.d(t,{G:()=>a});const a={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"}}},53109:(e,t,n)=>{"use strict";function a(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>a})},84142:(e,t,n)=>{"use strict";n.d(t,{$S:()=>f,B5:()=>C,C5:()=>p,Nr:()=>m,OF:()=>w,QB:()=>E,Vd:()=>_,Y:()=>k,cC:()=>g,d1:()=>T,fW:()=>S,w8:()=>y});var a=n(96540),o=n(56347),s=n(22831),r=n(44070),i=n(55597),c=n(32252),d=n(26588),u=n(31682),l=n(99169);const p=!!r.Gy;function g(e){const t=(0,c.r)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function m(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=m(t);if(e)return e}}(e):void 0:e.href}function f(){const{pathname:e}=(0,o.zy)(),t=(0,d.t)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=x({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const h=(e,t)=>void 0!==e&&(0,l.ys)(e,t),b=(e,t)=>e.some((e=>y(e,t)));function y(e,t){return"link"===e.type?h(e.href,t):"category"===e.type&&(h(e.href,t)||b(e.items,t))}function v(e,t){switch(e.type){case"category":return y(e,t)||e.items.some((e=>v(e,t)));case"link":return!e.unlisted||y(e,t);default:return!0}}function k(e,t){return(0,a.useMemo)((()=>e.filter((e=>v(e,t)))),[e,t])}function x(e){let{sidebarItems:t,pathname:n,onlyCategories:a=!1}=e;const o=[];return function e(t){for(const s of t)if("category"===s.type&&((0,l.ys)(s.href,n)||e(s.items))||"link"===s.type&&(0,l.ys)(s.href,n)){return a&&"category"!==s.type||o.unshift(s),!0}return!1}(t),o}function w(){const e=(0,d.t)(),{pathname:t}=(0,o.zy)(),n=(0,r.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?x({sidebarItems:e.items,pathname:t}):null}function _(e){const{activeVersion:t}=(0,r.zK)(e),{preferredVersion:n}=(0,i.g1)(e),o=(0,r.r7)(e);return(0,a.useMemo)((()=>(0,u.s)([t,n,o].filter(Boolean))),[t,n,o])}function S(e,t){const n=_(t);return(0,a.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),a=t.find((t=>t[0]===e));if(!a)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return a[1]}),[e,n])}function E(e,t){const n=_(t);return(0,a.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),a=t.find((t=>t.id===e));if(!a){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,u.s)(t.map((e=>e.id))).join("\n- ")}`)}return a}),[e,n])}function C(e){let{route:t}=e;const n=(0,o.zy)(),a=(0,c.r)(),r=t.routes,i=r.find((e=>(0,o.B6)(n.pathname,e)));if(!i)return null;const d=i.sidebar,u=d?a.docsSidebars[d]:void 0;return{docElement:(0,s.v)(r),sidebarName:d,sidebarItems:u}}function T(e){return e.filter((e=>!("category"===e.type||"link"===e.type)||!!m(e)))}},12181:(e,t,n)=>{"use strict";n.d(t,{bq:()=>u,MN:()=>d,a2:()=>c,k2:()=>l});var a=n(96540),o=n(21312),s=n(70440);const r={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};var i=n(74848);function c(e){return(0,i.jsx)("button",{type:"button",...e,children:(0,i.jsx)(o.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function d(e){let{error:t,tryAgain:n}=e;return(0,i.jsxs)("div",{className:r.errorBoundaryFallback,children:[(0,i.jsx)("p",{children:t.message}),(0,i.jsx)(c,{onClick:n})]})}function u(e){let{error:t}=e;const n=(0,s.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,i.jsx)("p",{className:r.errorBoundaryError,children:n})}class l extends a.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}},57485:(e,t,n)=>{"use strict";n.d(t,{$Z:()=>r,aZ:()=>i});var a=n(96540),o=n(56347),s=n(89532);function r(e){!function(e){const t=(0,o.W6)(),n=(0,s._q)(e);(0,a.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function i(e){return function(e){const t=(0,o.W6)();return(0,a.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}},31682:(e,t,n)=>{"use strict";function a(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,a)=>e.findIndex((e=>t(e,n)))!==a))}function o(e){return Array.from(new Set(e))}n.d(t,{X:()=>a,s:()=>o})},61213:(e,t,n)=>{"use strict";n.d(t,{e3:()=>p,be:()=>u,Jx:()=>g});var a=n(96540),o=n(15066),s=n(5260),r=n(36803),i=n(86025),c=n(44586);var d=n(74848);function u(e){let{title:t,description:n,keywords:a,image:o,children:r}=e;const u=function(e){const{siteConfig:t}=(0,c.A)(),{title:n,titleDelimiter:a}=t;return e?.trim().length?`${e.trim()} ${a} ${n}`:n}(t),{withBaseUrl:l}=(0,i.h)(),p=o?l(o,{absolute:!0}):void 0;return(0,d.jsxs)(s.A,{children:[t&&(0,d.jsx)("title",{children:u}),t&&(0,d.jsx)("meta",{property:"og:title",content:u}),n&&(0,d.jsx)("meta",{name:"description",content:n}),n&&(0,d.jsx)("meta",{property:"og:description",content:n}),a&&(0,d.jsx)("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),p&&(0,d.jsx)("meta",{property:"og:image",content:p}),p&&(0,d.jsx)("meta",{name:"twitter:image",content:p}),r]})}const l=a.createContext(void 0);function p(e){let{className:t,children:n}=e;const r=a.useContext(l),i=(0,o.A)(r,t);return(0,d.jsxs)(l.Provider,{value:i,children:[(0,d.jsx)(s.A,{children:(0,d.jsx)("html",{className:i})}),n]})}function g(e){let{children:t}=e;const n=(0,r.A)(),a=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const s=`plugin-id-${n.plugin.id}`;return(0,d.jsx)(p,{className:(0,o.A)(a,s),children:t})}},89532:(e,t,n)=>{"use strict";n.d(t,{Be:()=>d,ZC:()=>i,_q:()=>r,dV:()=>c,fM:()=>u});var a=n(96540),o=n(205),s=n(74848);function r(e){const t=(0,a.useRef)(e);return(0,o.A)((()=>{t.current=e}),[e]),(0,a.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,a.useRef)();return(0,o.A)((()=>{t.current=e})),t.current}class c extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function d(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,a.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,s.jsx)(s.Fragment,{children:e.reduceRight(((e,t)=>(0,s.jsx)(t,{children:e})),n)})}}},99169:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>i,ys:()=>r});var a=n(96540),o=n(35947),s=n(44586);function r(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function i(){const{baseUrl:e}=(0,s.A)().siteConfig;return(0,a.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function a(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(a)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.A,baseUrl:e})),[e])}},23104:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>g,Tv:()=>u,a_:()=>m,gk:()=>f});var a=n(96540),o=n(38193),s=n(92303),r=n(205),i=n(89532),c=n(74848);const d=a.createContext(void 0);function u(e){let{children:t}=e;const n=function(){const e=(0,a.useRef)(!0);return(0,a.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,c.jsx)(d.Provider,{value:n,children:t})}function l(){const e=(0,a.useContext)(d);if(null==e)throw new i.dV("ScrollControllerProvider");return e}const p=()=>o.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function g(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=l(),o=(0,a.useRef)(p()),s=(0,i._q)(e);(0,a.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=p();s(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[s,n,...t])}function m(){const e=l(),t=function(){const e=(0,a.useRef)({elem:null,top:0}),t=(0,a.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,a.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const a=t.getBoundingClientRect().top-n;return a&&window.scrollBy({left:0,top:a}),e.current={elem:null,top:0},{restored:0!==a}}),[]);return(0,a.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,a.useRef)(void 0),o=(0,a.useCallback)((a=>{t.save(a),e.disableScrollEvents(),n.current=()=>{const{restored:a}=t.restore();if(n.current=void 0,a){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,r.A)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:o}}function f(){const e=(0,a.useRef)(null),t=(0,s.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function a(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&o<e)&&(t=requestAnimationFrame(a),window.scrollTo(0,Math.floor(.85*(o-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},2967:(e,t,n)=>{"use strict";n.d(t,{Cy:()=>a,tU:()=>o});n(44586);const a="default";function o(e,t){return`docs-${e}-${t}`}},89466:(e,t,n)=>{"use strict";n.d(t,{Dv:()=>u,Wf:()=>d});var a=n(96540);const o="localStorage";function s(e){let{key:t,oldValue:n,newValue:a,storage:o}=e;if(n===a)return;const s=document.createEvent("StorageEvent");s.initStorageEvent("storage",!1,!1,t,n,a,window.location.href,o),window.dispatchEvent(s)}function r(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const c={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function d(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=r(t?.persistence);return null===n?c:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const a=n.getItem(e);n.setItem(e,t),s({key:e,oldValue:a,newValue:t,storage:n})}catch(a){console.error(`Docusaurus storage error, can't set ${e}=${t}`,a)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),s({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const a=a=>{a.storageArea===n&&a.key===e&&t(a)};return window.addEventListener("storage",a),()=>window.removeEventListener("storage",a)}catch(a){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,a),()=>{}}}}}function u(e,t){const n=(0,a.useRef)((()=>null===e?c:d(e,t))).current(),o=(0,a.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,a.useSyncExternalStore)(o,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},32131:(e,t,n)=>{"use strict";n.d(t,{o:()=>r});var a=n(44586),o=n(56347),s=n(70440);function r(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:r,currentLocale:i}}=(0,a.A)(),{pathname:c}=(0,o.zy)(),d=(0,s.applyTrailingSlash)(c,{trailingSlash:n,baseUrl:e}),u=i===r?e:e.replace(`/${i}/`,"/"),l=d.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:a}=e;return`${a?t:""}${function(e){return e===r?`${u}`:`${u}${e}/`}(n)}${l}`}}}},75062:(e,t,n)=>{"use strict";n.d(t,{$:()=>r});var a=n(96540),o=n(56347),s=n(89532);function r(e){const t=(0,o.zy)(),n=(0,s.ZC)(t),r=(0,s._q)(e);(0,a.useEffect)((()=>{n&&t!==n&&r({location:t,previousLocation:n})}),[r,t,n])}},6342:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var a=n(44586);function o(){return(0,a.A)().siteConfig.themeConfig}},12983:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.removeTrailingSlash=t.addLeadingSlash=t.addTrailingSlash=void 0;const a=n(42566);function o(e){return e.endsWith("/")?e:`${e}/`}function s(e){return(0,a.removeSuffix)(e,"/")}t.addTrailingSlash=o,t.default=function(e,t){const{trailingSlash:n,baseUrl:a}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[r]=e.split(/[#?]/),i="/"===r||r===a?r:(c=r,n?o(c):s(c));var c;return e.replace(r,i)},t.addLeadingSlash=function(e){return(0,a.addPrefix)(e,"/")},t.removeTrailingSlash=s},80253:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},70440:function(e,t,n){"use strict";var a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.removePrefix=t.addSuffix=t.removeSuffix=t.addPrefix=t.removeTrailingSlash=t.addLeadingSlash=t.addTrailingSlash=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var o=n(12983);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return a(o).default}}),Object.defineProperty(t,"addTrailingSlash",{enumerable:!0,get:function(){return o.addTrailingSlash}}),Object.defineProperty(t,"addLeadingSlash",{enumerable:!0,get:function(){return o.addLeadingSlash}}),Object.defineProperty(t,"removeTrailingSlash",{enumerable:!0,get:function(){return o.removeTrailingSlash}});var s=n(42566);Object.defineProperty(t,"addPrefix",{enumerable:!0,get:function(){return s.addPrefix}}),Object.defineProperty(t,"removeSuffix",{enumerable:!0,get:function(){return s.removeSuffix}}),Object.defineProperty(t,"addSuffix",{enumerable:!0,get:function(){return s.addSuffix}}),Object.defineProperty(t,"removePrefix",{enumerable:!0,get:function(){return s.removePrefix}});var r=n(80253);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return r.getErrorCausalChain}})},42566:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.removePrefix=t.addSuffix=t.removeSuffix=t.addPrefix=void 0,t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){return""===t?e:e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},2849:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});n(96540);var a=n(20053);const o={loadingRing:"loadingRing_RJI3","loading-ring":"loading-ring_FB5o"};var s=n(74848);function r(e){let{className:t}=e;return(0,s.jsxs)("div",{className:(0,a.A)(o.loadingRing,t),children:[(0,s.jsx)("div",{}),(0,s.jsx)("div",{}),(0,s.jsx)("div",{}),(0,s.jsx)("div",{})]})}},5891:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var a=n(58291),o=n.n(a),s=n(11088);const r=new Map;function i(e,t){const n=`${e}${t}`;let a=r.get(n);return a||(a=async function(e,t){{const n=`${e}${s.IH.replace("{dir}",t?`-${t.replace(/\//g,"-")}`:"")}`;if(new URL(n,location.origin).origin!==location.origin)throw new Error("Unexpected version url");const a=await(await fetch(n)).json(),r=a.map(((e,t)=>{let{documents:n,index:a}=e;return{type:t,documents:n,index:o().Index.load(a)}})),i=a.reduce(((e,t)=>{for(const n of t.index.invertedIndex)/\p{Unified_Ideograph}/u.test(n[0][0])&&e.add(n[0]);return e}),new Set);return{wrappedIndexes:r,zhDictionary:Array.from(i)}}return{wrappedIndexes:[],zhDictionary:[]}}(e,t),r.set(n,a)),a}},32384:(e,t,n)=>{"use strict";n.d(t,{m:()=>c});var a=n(58291),o=n.n(a);var s=n(11088);function r(e){return i(e).concat(i(e.filter((e=>{const t=e[e.length-1];return!t.trailing&&t.maybeTyping})),!0))}function i(e,t){return e.map((e=>({tokens:e.map((e=>e.value)),term:e.map((e=>({value:e.value,presence:o().Query.presence.REQUIRED,wildcard:(t?e.trailing||e.maybeTyping:e.trailing)?o().Query.wildcard.TRAILING:o().Query.wildcard.NONE})))})))}function c(e,t,n){return function(a,i){const c=function(e,t){if(1===t.length&&["ja","jp","th"].includes(t[0]))return o()[t[0]].tokenizer(e).map((e=>e.toString()));let n=/[^-\s]+/g;return t.includes("zh")&&(n=/\w+|\p{Unified_Ideograph}+/gu),e.toLowerCase().match(n)||[]}(a,s.BH);if(0===c.length)return void i([]);const d=function(e,t){const n=function(e,t){const n=[];return function e(a,o){if(0===a.length)return void n.push(o);const s=a[0];if(/\p{Unified_Ideograph}/u.test(s)){const n=function(e,t){const n=[];return function e(a,o){let s=0,r=!1;for(const i of t)if(a.substr(0,i.length)===i){const t={missed:o.missed,term:o.term.concat({value:i})};a.length>i.length?e(a.substr(i.length),t):n.push(t),r=!0}else for(let t=i.length-1;t>s;t-=1){const c=i.substr(0,t);if(a.substr(0,t)===c){s=t;const i={missed:o.missed,term:o.term.concat({value:c,trailing:!0})};a.length>t?e(a.substr(t),i):n.push(i),r=!0;break}}r||(a.length>0?e(a.substr(1),{missed:o.missed+1,term:o.term}):o.term.length>0&&n.push(o))}(e,{missed:0,term:[]}),n.sort(((e,t)=>{const n=e.missed>0?1:0,a=t.missed>0?1:0;return n!==a?n-a:e.term.length-t.term.length})).map((e=>e.term))}(s,t);for(const t of n){const n=o.concat(...t);e(a.slice(1),n)}}else{const t=o.concat({value:s});e(a.slice(1),t)}}(e,[]),n}(e,t);if(0===n.length)return[{tokens:e,term:e.map((e=>({value:e,presence:o().Query.presence.REQUIRED,wildcard:o().Query.wildcard.LEADING|o().Query.wildcard.TRAILING})))}];for(const o of n)o[o.length-1].maybeTyping=!0;const a=[];for(const r of s.BH)if("en"===r)s.sx||a.unshift(o().stopWordFilter);else{const e=o()[r];e.stopWordFilter&&a.unshift(e.stopWordFilter)}let i;if(a.length>0){const e=e=>a.reduce(((e,t)=>e.filter((e=>t(e.value)))),e);i=[];const t=[];for(const a of n){const n=e(a);i.push(n),n.length<a.length&&n.length>0&&t.push(n)}n.push(...t)}else i=n.slice();const c=[];for(const o of i)if(o.length>2)for(let e=o.length-1;e>=0;e-=1)c.push(o.slice(0,e).concat(o.slice(e+1)));return r(n).concat(r(c))}(c,t),u=[];e:for(const{term:t,tokens:o}of d)for(const{documents:a,index:s,type:r}of e)if(u.push(...s.query((e=>{for(const n of t)e.term(n.value,{wildcard:n.wildcard,presence:n.presence})})).slice(0,n).filter((e=>!u.some((t=>t.document.i.toString()===e.ref)))).slice(0,n-u.length).map((t=>{const n=a.find((e=>e.i.toString()===t.ref));return{document:n,type:r,page:0!==r&&e[0].documents.find((e=>e.i===n.p)),metadata:t.matchData.metadata,tokens:o,score:t.score}}))),u.length>=n)break e;!function(e){e.forEach(((e,t)=>{e.index=t})),e.sort(((t,n)=>{let a=t.type>0&&t.page?e.findIndex((e=>e.document===t.page)):t.index,o=n.type>0&&n.page?e.findIndex((e=>e.document===n.page)):n.index;return-1===a&&(a=t.index),-1===o&&(o=n.index),a===o?0===t.type?-1:0===n.type?1:t.index-n.index:a-o}))}(u),function(e){e.forEach(((t,n)=>{n>0&&t.page&&e.some((e=>e.document===t.page))&&(n<e.length-1&&e[n+1].page===t.page?t.isInterOfTree=!0:t.isLastOfTree=!0)}))}(u),i(u)}}},4471:(e,t,n)=>{"use strict";function a(e){return e.join(" \u203a ")}n.d(t,{$:()=>a})},53103:(e,t,n)=>{"use strict";function a(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}n.d(t,{Z:()=>a})},27674:(e,t,n)=>{"use strict";function a(e,t){const n=[];for(const a of Object.values(e))a[t]&&n.push(...a[t].position);return n.sort(((e,t)=>e[0]-t[0]||t[1]-e[1]))}n.d(t,{g:()=>a})},86841:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var a=n(53103);function o(e,t,n){const s=[];for(const r of t){const n=e.toLowerCase().indexOf(r);if(n>=0){n>0&&s.push(o(e.substr(0,n),t)),s.push(`<mark>${(0,a.Z)(e.substr(n,r.length))}</mark>`);const i=n+r.length;i<e.length&&s.push(o(e.substr(i),t));break}}return 0===s.length?n?`<mark>${(0,a.Z)(e)}</mark>`:(0,a.Z)(e):s.join("")}},43810:(e,t,n)=>{"use strict";n.d(t,{C:()=>c});var a=n(53103),o=n(86841);const s=/\w+|\p{Unified_Ideograph}/u;function r(e){const t=[];let n=0,a=e;for(;a.length>0;){const o=a.match(s);if(!o){t.push(a);break}o.index>0&&t.push(a.substring(0,o.index)),t.push(o[0]),n+=o.index+o[0].length,a=e.substring(n)}return t}var i=n(11088);function c(e,t,n,s){void 0===s&&(s=i.rG);const{chunkIndex:c,chunks:d}=function(e,t,n){const s=[];let i=0,c=0,d=-1;for(;i<t.length;){const[u,l]=t[i];if(i+=1,!(u<c)){if(u>c){const t=r(e.substring(c,u)).map((e=>({html:(0,a.Z)(e),textLength:e.length})));for(const e of t)s.push(e)}-1===d&&(d=s.length),c=u+l,s.push({html:(0,o.Z)(e.substring(u,c),n,!0),textLength:l})}}if(c<e.length){const t=r(e.substring(c)).map((e=>({html:(0,a.Z)(e),textLength:e.length})));for(const e of t)s.push(e)}return{chunkIndex:d,chunks:s}}(e,t,n),u=d.slice(0,c),l=d[c],p=[l.html],g=d.slice(c+1);let m=l.textLength,f=0,h=0,b=!1,y=!1;for(;m<s;)if((f<=h||0===g.length)&&u.length>0){const e=u.pop();m+e.textLength<=s?(p.unshift(e.html),f+=e.textLength,m+=e.textLength):(b=!0,u.length=0)}else{if(!(g.length>0))break;{const e=g.shift();m+e.textLength<=s?(p.push(e.html),h+=e.textLength,m+=e.textLength):(y=!0,g.length=0)}}return(b||u.length>0)&&p.unshift("\u2026"),(y||g.length>0)&&p.push("\u2026"),p.join("")}},43385:(e,t,n)=>{"use strict";function a(e,t){if("string"==typeof e)return{label:e,path:e};{const{label:n,path:a}=e;return"string"==typeof n?{label:n,path:a}:Object.prototype.hasOwnProperty.call(n,t)?{label:n[t],path:a}:{label:a,path:a}}}n.d(t,{p:()=>a})},11088:(e,t,n)=>{"use strict";n.d(t,{CU:()=>s,UB:()=>g,tb:()=>d,O6:()=>h,I$:()=>m,BH:()=>a,sx:()=>o,ZG:()=>p,WW:()=>u,pk:()=>l,Hg:()=>f,IH:()=>r,rG:()=>c,AT:()=>i,dz:()=>b});n(58291);const a=["en"],o=!1,s=null,r="search-index{dir}.json?_=38164efd",i=8,c=50,d=!1,u=!0,l=!0,p="right",g=void 0,m=!0,f=null,h=!1,b=!1},45477:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});const a=n(38193).A.canUseDOM?{onRouteUpdate(e){let{location:t}=e;_paq.push(["setCustomUrl",t.pathname]),_paq.push(["setDocumentTitle",document.title]),_paq.push(["trackPageView"])}}:null},20053:(e,t,n)=>{"use strict";function a(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=a(e[t]))&&(o&&(o+=" "),o+=n);else for(t in e)e[t]&&(o&&(o+=" "),o+=t);return o}n.d(t,{A:()=>o});const o=function(){for(var e,t,n=0,o="";n<arguments.length;)(e=arguments[n++])&&(t=a(e))&&(o&&(o+=" "),o+=t);return o}},31513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>k,TM:()=>C,yJ:()=>g,sC:()=>A,AO:()=>p});var a=n(58168);function o(e){return"/"===e.charAt(0)}function s(e,t){for(var n=t,a=n+1,o=e.length;a<o;n+=1,a+=1)e[n]=e[a];e.pop()}const r=function(e,t){void 0===t&&(t="");var n,a=e&&e.split("/")||[],r=t&&t.split("/")||[],i=e&&o(e),c=t&&o(t),d=i||c;if(e&&o(e)?r=a:a.length&&(r.pop(),r=r.concat(a)),!r.length)return"/";if(r.length){var u=r[r.length-1];n="."===u||".."===u||""===u}else n=!1;for(var l=0,p=r.length;p>=0;p--){var g=r[p];"."===g?s(r,p):".."===g?(s(r,p),l++):l&&(s(r,p),l--)}if(!d)for(;l--;l)r.unshift("..");!d||""===r[0]||r[0]&&o(r[0])||r.unshift("");var m=r.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var i=n(11561);function c(e){return"/"===e.charAt(0)?e:"/"+e}function d(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function l(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,a=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),a&&"#"!==a&&(o+="#"===a.charAt(0)?a:"#"+a),o}function g(e,t,n,o){var s;"string"==typeof e?(s=function(e){var t=e||"/",n="",a="",o=t.indexOf("#");-1!==o&&(a=t.substr(o),t=t.substr(0,o));var s=t.indexOf("?");return-1!==s&&(n=t.substr(s),t=t.substr(0,s)),{pathname:t,search:"?"===n?"":n,hash:"#"===a?"":a}}(e),s.state=t):(void 0===(s=(0,a.A)({},e)).pathname&&(s.pathname=""),s.search?"?"!==s.search.charAt(0)&&(s.search="?"+s.search):s.search="",s.hash?"#"!==s.hash.charAt(0)&&(s.hash="#"+s.hash):s.hash="",void 0!==t&&void 0===s.state&&(s.state=t));try{s.pathname=decodeURI(s.pathname)}catch(i){throw i instanceof URIError?new URIError('Pathname "'+s.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):i}return n&&(s.key=n),o?s.pathname?"/"!==s.pathname.charAt(0)&&(s.pathname=r(s.pathname,o.pathname)):s.pathname=o.pathname:s.pathname||(s.pathname="/"),s}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,a,o){if(null!=e){var s="function"==typeof e?e(t,n):e;"string"==typeof s?"function"==typeof a?a(s,o):o(!0):o(!1!==s)}else o(!0)},appendListener:function(e){var n=!0;function a(){n&&e.apply(void 0,arguments)}return t.push(a),function(){n=!1,t=t.filter((function(e){return e!==a}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),a=0;a<e;a++)n[a]=arguments[a];t.forEach((function(e){return e.apply(void 0,n)}))}}}var f=!("undefined"==typeof window||!window.document||!window.document.createElement);function h(e,t){t(window.confirm(e))}var b="popstate",y="hashchange";function v(){try{return window.history.state||{}}catch(e){return{}}}function k(e){void 0===e&&(e={}),f||(0,i.A)(!1);var t,n=window.history,o=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,s=!(-1===window.navigator.userAgent.indexOf("Trident")),r=e,d=r.forceRefresh,k=void 0!==d&&d,x=r.getUserConfirmation,w=void 0===x?h:x,_=r.keyLength,S=void 0===_?6:_,E=e.basename?l(c(e.basename)):"";function C(e){var t=e||{},n=t.key,a=t.state,o=window.location,s=o.pathname+o.search+o.hash;return E&&(s=u(s,E)),g(s,a,n)}function T(){return Math.random().toString(36).substr(2,S)}var A=m();function j(e){(0,a.A)($,e),$.length=n.length,A.notifyListeners($.location,$.action)}function L(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||R(C(e.state))}function P(){R(C(v()))}var N=!1;function R(e){if(N)N=!1,j();else{A.confirmTransitionTo(e,"POP",w,(function(t){t?j({action:"POP",location:e}):function(e){var t=$.location,n=I.indexOf(t.key);-1===n&&(n=0);var a=I.indexOf(e.key);-1===a&&(a=0);var o=n-a;o&&(N=!0,D(o))}(e)}))}}var O=C(v()),I=[O.key];function F(e){return E+p(e)}function D(e){n.go(e)}var M=0;function z(e){1===(M+=e)&&1===e?(window.addEventListener(b,L),s&&window.addEventListener(y,P)):0===M&&(window.removeEventListener(b,L),s&&window.removeEventListener(y,P))}var B=!1;var $={length:n.length,action:"POP",location:O,createHref:F,push:function(e,t){var a="PUSH",s=g(e,t,T(),$.location);A.confirmTransitionTo(s,a,w,(function(e){if(e){var t=F(s),r=s.key,i=s.state;if(o)if(n.pushState({key:r,state:i},null,t),k)window.location.href=t;else{var c=I.indexOf($.location.key),d=I.slice(0,c+1);d.push(s.key),I=d,j({action:a,location:s})}else window.location.href=t}}))},replace:function(e,t){var a="REPLACE",s=g(e,t,T(),$.location);A.confirmTransitionTo(s,a,w,(function(e){if(e){var t=F(s),r=s.key,i=s.state;if(o)if(n.replaceState({key:r,state:i},null,t),k)window.location.replace(t);else{var c=I.indexOf($.location.key);-1!==c&&(I[c]=s.key),j({action:a,location:s})}else window.location.replace(t)}}))},go:D,goBack:function(){D(-1)},goForward:function(){D(1)},block:function(e){void 0===e&&(e=!1);var t=A.setPrompt(e);return B||(z(1),B=!0),function(){return B&&(B=!1,z(-1)),t()}},listen:function(e){var t=A.appendListener(e);return z(1),function(){z(-1),t()}}};return $}var x="hashchange",w={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+d(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:d,decodePath:c},slash:{encodePath:c,decodePath:c}};function _(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function S(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function E(e){window.location.replace(_(window.location.href)+"#"+e)}function C(e){void 0===e&&(e={}),f||(0,i.A)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),o=n.getUserConfirmation,s=void 0===o?h:o,r=n.hashType,d=void 0===r?"slash":r,b=e.basename?l(c(e.basename)):"",y=w[d],v=y.encodePath,k=y.decodePath;function C(){var e=k(S());return b&&(e=u(e,b)),g(e)}var T=m();function A(e){(0,a.A)(B,e),B.length=t.length,T.notifyListeners(B.location,B.action)}var j=!1,L=null;function P(){var e,t,n=S(),a=v(n);if(n!==a)E(a);else{var o=C(),r=B.location;if(!j&&(t=o,(e=r).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(L===p(o))return;L=null,function(e){if(j)j=!1,A();else{var t="POP";T.confirmTransitionTo(e,t,s,(function(n){n?A({action:t,location:e}):function(e){var t=B.location,n=I.lastIndexOf(p(t));-1===n&&(n=0);var a=I.lastIndexOf(p(e));-1===a&&(a=0);var o=n-a;o&&(j=!0,F(o))}(e)}))}}(o)}}var N=S(),R=v(N);N!==R&&E(R);var O=C(),I=[p(O)];function F(e){t.go(e)}var D=0;function M(e){1===(D+=e)&&1===e?window.addEventListener(x,P):0===D&&window.removeEventListener(x,P)}var z=!1;var B={length:t.length,action:"POP",location:O,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=_(window.location.href)),n+"#"+v(b+p(e))},push:function(e,t){var n="PUSH",a=g(e,void 0,void 0,B.location);T.confirmTransitionTo(a,n,s,(function(e){if(e){var t=p(a),o=v(b+t);if(S()!==o){L=t,function(e){window.location.hash=e}(o);var s=I.lastIndexOf(p(B.location)),r=I.slice(0,s+1);r.push(t),I=r,A({action:n,location:a})}else A()}}))},replace:function(e,t){var n="REPLACE",a=g(e,void 0,void 0,B.location);T.confirmTransitionTo(a,n,s,(function(e){if(e){var t=p(a),o=v(b+t);S()!==o&&(L=t,E(o));var s=I.indexOf(p(B.location));-1!==s&&(I[s]=t),A({action:n,location:a})}}))},go:F,goBack:function(){F(-1)},goForward:function(){F(1)},block:function(e){void 0===e&&(e=!1);var t=T.setPrompt(e);return z||(M(1),z=!0),function(){return z&&(z=!1,M(-1)),t()}},listen:function(e){var t=T.appendListener(e);return M(1),function(){M(-1),t()}}};return B}function T(e,t,n){return Math.min(Math.max(e,t),n)}function A(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,o=t.initialEntries,s=void 0===o?["/"]:o,r=t.initialIndex,i=void 0===r?0:r,c=t.keyLength,d=void 0===c?6:c,u=m();function l(e){(0,a.A)(k,e),k.length=k.entries.length,u.notifyListeners(k.location,k.action)}function f(){return Math.random().toString(36).substr(2,d)}var h=T(i,0,s.length-1),b=s.map((function(e){return g(e,void 0,"string"==typeof e?f():e.key||f())})),y=p;function v(e){var t=T(k.index+e,0,k.entries.length-1),a=k.entries[t];u.confirmTransitionTo(a,"POP",n,(function(e){e?l({action:"POP",location:a,index:t}):l()}))}var k={length:b.length,action:"POP",location:b[h],index:h,entries:b,createHref:y,push:function(e,t){var a="PUSH",o=g(e,t,f(),k.location);u.confirmTransitionTo(o,a,n,(function(e){if(e){var t=k.index+1,n=k.entries.slice(0);n.length>t?n.splice(t,n.length-t,o):n.push(o),l({action:a,location:o,index:t,entries:n})}}))},replace:function(e,t){var a="REPLACE",o=g(e,t,f(),k.location);u.confirmTransitionTo(o,a,n,(function(e){e&&(k.entries[k.index]=o,l({action:a,location:o}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=k.index+e;return t>=0&&t<k.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return k}},4146:(e,t,n)=>{"use strict";var a=n(44363),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},s={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},r={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},i={};function c(e){return a.isMemo(e)?r:i[e.$$typeof]||o}i[a.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},i[a.Memo]=r;var d=Object.defineProperty,u=Object.getOwnPropertyNames,l=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,g=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,a){if("string"!=typeof n){if(m){var o=g(n);o&&o!==m&&e(t,o,a)}var r=u(n);l&&(r=r.concat(l(n)));for(var i=c(t),f=c(n),h=0;h<r.length;++h){var b=r[h];if(!(s[b]||a&&a[b]||f&&f[b]||i&&i[b])){var y=p(n,b);try{d(t,b,y)}catch(v){}}}}return t}},20311:e=>{"use strict";e.exports=function(e,t,n,a,o,s,r,i){if(!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var d=[n,a,o,s,r,i],u=0;(c=new Error(t.replace(/%s/g,(function(){return d[u++]})))).name="Invariant Violation"}throw c.framesToPop=1,c}}},64634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},58291:(e,t,n)=>{var a,o;!function(){var s,r,i,c,d,u,l,p,g,m,f,h,b,y,v,k,x,w,_,S,E,C,T,A,j,L,P,N,R,O,I=function(e){var t=new I.Builder;return t.pipeline.add(I.trimmer,I.stopWordFilter,I.stemmer),t.searchPipeline.add(I.stemmer),e.call(t,t),t.build()};I.version="2.3.9",I.utils={},I.utils.warn=(s=this,function(e){s.console&&console.warn&&console.warn(e)}),I.utils.asString=function(e){return null==e?"":e.toString()},I.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),a=0;a<n.length;a++){var o=n[a],s=e[o];if(Array.isArray(s))t[o]=s.slice();else{if("string"!=typeof s&&"number"!=typeof s&&"boolean"!=typeof s)throw new TypeError("clone is not deep and does not support nested objects");t[o]=s}}return t},I.FieldRef=function(e,t,n){this.docRef=e,this.fieldName=t,this._stringValue=n},I.FieldRef.joiner="/",I.FieldRef.fromString=function(e){var t=e.indexOf(I.FieldRef.joiner);if(-1===t)throw"malformed field ref string";var n=e.slice(0,t),a=e.slice(t+1);return new I.FieldRef(a,n,e)},I.FieldRef.prototype.toString=function(){return null==this._stringValue&&(this._stringValue=this.fieldName+I.FieldRef.joiner+this.docRef),this._stringValue},I.Set=function(e){if(this.elements=Object.create(null),e){this.length=e.length;for(var t=0;t<this.length;t++)this.elements[e[t]]=!0}else this.length=0},I.Set.complete={intersect:function(e){return e},union:function(){return this},contains:function(){return!0}},I.Set.empty={intersect:function(){return this},union:function(e){return e},contains:function(){return!1}},I.Set.prototype.contains=function(e){return!!this.elements[e]},I.Set.prototype.intersect=function(e){var t,n,a,o=[];if(e===I.Set.complete)return this;if(e===I.Set.empty)return e;this.length<e.length?(t=this,n=e):(t=e,n=this),a=Object.keys(t.elements);for(var s=0;s<a.length;s++){var r=a[s];r in n.elements&&o.push(r)}return new I.Set(o)},I.Set.prototype.union=function(e){return e===I.Set.complete?I.Set.complete:e===I.Set.empty?this:new I.Set(Object.keys(this.elements).concat(Object.keys(e.elements)))},I.idf=function(e,t){var n=0;for(var a in e)"_index"!=a&&(n+=Object.keys(e[a]).length);var o=(t-n+.5)/(n+.5);return Math.log(1+Math.abs(o))},I.Token=function(e,t){this.str=e||"",this.metadata=t||{}},I.Token.prototype.toString=function(){return this.str},I.Token.prototype.update=function(e){return this.str=e(this.str,this.metadata),this},I.Token.prototype.clone=function(e){return e=e||function(e){return e},new I.Token(e(this.str,this.metadata),this.metadata)},I.tokenizer=function(e,t){if(null==e||null==e)return[];if(Array.isArray(e))return e.map((function(e){return new I.Token(I.utils.asString(e).toLowerCase(),I.utils.clone(t))}));for(var n=e.toString().toLowerCase(),a=n.length,o=[],s=0,r=0;s<=a;s++){var i=s-r;if(n.charAt(s).match(I.tokenizer.separator)||s==a){if(i>0){var c=I.utils.clone(t)||{};c.position=[r,i],c.index=o.length,o.push(new I.Token(n.slice(r,s),c))}r=s+1}}return o},I.tokenizer.separator=/[\s\-]+/,I.Pipeline=function(){this._stack=[]},I.Pipeline.registeredFunctions=Object.create(null),I.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&I.utils.warn("Overwriting existing registered function: "+t),e.label=t,I.Pipeline.registeredFunctions[e.label]=e},I.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||I.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},I.Pipeline.load=function(e){var t=new I.Pipeline;return e.forEach((function(e){var n=I.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)})),t},I.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach((function(e){I.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},I.Pipeline.prototype.after=function(e,t){I.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},I.Pipeline.prototype.before=function(e,t){I.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},I.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},I.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n<t;n++){for(var a=this._stack[n],o=[],s=0;s<e.length;s++){var r=a(e[s],s,e);if(null!=r&&""!==r)if(Array.isArray(r))for(var i=0;i<r.length;i++)o.push(r[i]);else o.push(r)}e=o}return e},I.Pipeline.prototype.runString=function(e,t){var n=new I.Token(e,t);return this.run([n]).map((function(e){return e.toString()}))},I.Pipeline.prototype.reset=function(){this._stack=[]},I.Pipeline.prototype.toJSON=function(){return this._stack.map((function(e){return I.Pipeline.warnIfFunctionNotRegistered(e),e.label}))},I.Vector=function(e){this._magnitude=0,this.elements=e||[]},I.Vector.prototype.positionForIndex=function(e){if(0==this.elements.length)return 0;for(var t=0,n=this.elements.length/2,a=n-t,o=Math.floor(a/2),s=this.elements[2*o];a>1&&(s<e&&(t=o),s>e&&(n=o),s!=e);)a=n-t,o=t+Math.floor(a/2),s=this.elements[2*o];return s==e||s>e?2*o:s<e?2*(o+1):void 0},I.Vector.prototype.insert=function(e,t){this.upsert(e,t,(function(){throw"duplicate index"}))},I.Vector.prototype.upsert=function(e,t,n){this._magnitude=0;var a=this.positionForIndex(e);this.elements[a]==e?this.elements[a+1]=n(this.elements[a+1],t):this.elements.splice(a,0,e,t)},I.Vector.prototype.magnitude=function(){if(this._magnitude)return this._magnitude;for(var e=0,t=this.elements.length,n=1;n<t;n+=2){var a=this.elements[n];e+=a*a}return this._magnitude=Math.sqrt(e)},I.Vector.prototype.dot=function(e){for(var t=0,n=this.elements,a=e.elements,o=n.length,s=a.length,r=0,i=0,c=0,d=0;c<o&&d<s;)(r=n[c])<(i=a[d])?c+=2:r>i?d+=2:r==i&&(t+=n[c+1]*a[d+1],c+=2,d+=2);return t},I.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},I.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t<this.elements.length;t+=2,n++)e[n]=this.elements[t];return e},I.Vector.prototype.toJSON=function(){return this.elements},I.stemmer=(r={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},i={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},l="^("+(d="[^aeiou][^aeiouy]*")+")?"+(u=(c="[aeiouy]")+"[aeiou]*")+d+"("+u+")?$",p="^("+d+")?"+u+d+u+d,g="^("+d+")?"+c,m=new RegExp("^("+d+")?"+u+d),f=new RegExp(p),h=new RegExp(l),b=new RegExp(g),y=/^(.+?)(ss|i)es$/,v=/^(.+?)([^s])s$/,k=/^(.+?)eed$/,x=/^(.+?)(ed|ing)$/,w=/.$/,_=/(at|bl|iz)$/,S=new RegExp("([^aeiouylsz])\\1$"),E=new RegExp("^"+d+c+"[^aeiouwxy]$"),C=/^(.+?[^aeiou])y$/,T=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,A=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,j=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,L=/^(.+?)(s|t)(ion)$/,P=/^(.+?)e$/,N=/ll$/,R=new RegExp("^"+d+c+"[^aeiouwxy]$"),O=function(e){var t,n,a,o,s,c,d;if(e.length<3)return e;if("y"==(a=e.substr(0,1))&&(e=a.toUpperCase()+e.substr(1)),s=v,(o=y).test(e)?e=e.replace(o,"$1$2"):s.test(e)&&(e=e.replace(s,"$1$2")),s=x,(o=k).test(e)){var u=o.exec(e);(o=m).test(u[1])&&(o=w,e=e.replace(o,""))}else s.test(e)&&(t=(u=s.exec(e))[1],(s=b).test(t)&&(c=S,d=E,(s=_).test(e=t)?e+="e":c.test(e)?(o=w,e=e.replace(o,"")):d.test(e)&&(e+="e")));return(o=C).test(e)&&(e=(t=(u=o.exec(e))[1])+"i"),(o=T).test(e)&&(t=(u=o.exec(e))[1],n=u[2],(o=m).test(t)&&(e=t+r[n])),(o=A).test(e)&&(t=(u=o.exec(e))[1],n=u[2],(o=m).test(t)&&(e=t+i[n])),s=L,(o=j).test(e)?(t=(u=o.exec(e))[1],(o=f).test(t)&&(e=t)):s.test(e)&&(t=(u=s.exec(e))[1]+u[2],(s=f).test(t)&&(e=t)),(o=P).test(e)&&(t=(u=o.exec(e))[1],s=h,c=R,((o=f).test(t)||s.test(t)&&!c.test(t))&&(e=t)),s=f,(o=N).test(e)&&s.test(e)&&(o=w,e=e.replace(o,"")),"y"==a&&(e=a.toLowerCase()+e.substr(1)),e},function(e){return e.update(O)}),I.Pipeline.registerFunction(I.stemmer,"stemmer"),I.generateStopWordFilter=function(e){var t=e.reduce((function(e,t){return e[t]=t,e}),{});return function(e){if(e&&t[e.toString()]!==e.toString())return e}},I.stopWordFilter=I.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),I.Pipeline.registerFunction(I.stopWordFilter,"stopWordFilter"),I.trimmer=function(e){return e.update((function(e){return e.replace(/^\W+/,"").replace(/\W+$/,"")}))},I.Pipeline.registerFunction(I.trimmer,"trimmer"),I.TokenSet=function(){this.final=!1,this.edges={},this.id=I.TokenSet._nextId,I.TokenSet._nextId+=1},I.TokenSet._nextId=1,I.TokenSet.fromArray=function(e){for(var t=new I.TokenSet.Builder,n=0,a=e.length;n<a;n++)t.insert(e[n]);return t.finish(),t.root},I.TokenSet.fromClause=function(e){return"editDistance"in e?I.TokenSet.fromFuzzyString(e.term,e.editDistance):I.TokenSet.fromString(e.term)},I.TokenSet.fromFuzzyString=function(e,t){for(var n=new I.TokenSet,a=[{node:n,editsRemaining:t,str:e}];a.length;){var o=a.pop();if(o.str.length>0){var s,r=o.str.charAt(0);r in o.node.edges?s=o.node.edges[r]:(s=new I.TokenSet,o.node.edges[r]=s),1==o.str.length&&(s.final=!0),a.push({node:s,editsRemaining:o.editsRemaining,str:o.str.slice(1)})}if(0!=o.editsRemaining){if("*"in o.node.edges)var i=o.node.edges["*"];else{i=new I.TokenSet;o.node.edges["*"]=i}if(0==o.str.length&&(i.final=!0),a.push({node:i,editsRemaining:o.editsRemaining-1,str:o.str}),o.str.length>1&&a.push({node:o.node,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)}),1==o.str.length&&(o.node.final=!0),o.str.length>=1){if("*"in o.node.edges)var c=o.node.edges["*"];else{c=new I.TokenSet;o.node.edges["*"]=c}1==o.str.length&&(c.final=!0),a.push({node:c,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)})}if(o.str.length>1){var d,u=o.str.charAt(0),l=o.str.charAt(1);l in o.node.edges?d=o.node.edges[l]:(d=new I.TokenSet,o.node.edges[l]=d),1==o.str.length&&(d.final=!0),a.push({node:d,editsRemaining:o.editsRemaining-1,str:u+o.str.slice(2)})}}}return n},I.TokenSet.fromString=function(e){for(var t=new I.TokenSet,n=t,a=0,o=e.length;a<o;a++){var s=e[a],r=a==o-1;if("*"==s)t.edges[s]=t,t.final=r;else{var i=new I.TokenSet;i.final=r,t.edges[s]=i,t=i}}return n},I.TokenSet.prototype.toArray=function(){for(var e=[],t=[{prefix:"",node:this}];t.length;){var n=t.pop(),a=Object.keys(n.node.edges),o=a.length;n.node.final&&(n.prefix.charAt(0),e.push(n.prefix));for(var s=0;s<o;s++){var r=a[s];t.push({prefix:n.prefix.concat(r),node:n.node.edges[r]})}}return e},I.TokenSet.prototype.toString=function(){if(this._str)return this._str;for(var e=this.final?"1":"0",t=Object.keys(this.edges).sort(),n=t.length,a=0;a<n;a++){var o=t[a];e=e+o+this.edges[o].id}return e},I.TokenSet.prototype.intersect=function(e){for(var t=new I.TokenSet,n=void 0,a=[{qNode:e,output:t,node:this}];a.length;){n=a.pop();for(var o=Object.keys(n.qNode.edges),s=o.length,r=Object.keys(n.node.edges),i=r.length,c=0;c<s;c++)for(var d=o[c],u=0;u<i;u++){var l=r[u];if(l==d||"*"==d){var p=n.node.edges[l],g=n.qNode.edges[d],m=p.final&&g.final,f=void 0;l in n.output.edges?(f=n.output.edges[l]).final=f.final||m:((f=new I.TokenSet).final=m,n.output.edges[l]=f),a.push({qNode:g,output:f,node:p})}}}return t},I.TokenSet.Builder=function(){this.previousWord="",this.root=new I.TokenSet,this.uncheckedNodes=[],this.minimizedNodes={}},I.TokenSet.Builder.prototype.insert=function(e){var t,n=0;if(e<this.previousWord)throw new Error("Out of order word insertion");for(var a=0;a<e.length&&a<this.previousWord.length&&e[a]==this.previousWord[a];a++)n++;this.minimize(n),t=0==this.uncheckedNodes.length?this.root:this.uncheckedNodes[this.uncheckedNodes.length-1].child;for(a=n;a<e.length;a++){var o=new I.TokenSet,s=e[a];t.edges[s]=o,this.uncheckedNodes.push({parent:t,char:s,child:o}),t=o}t.final=!0,this.previousWord=e},I.TokenSet.Builder.prototype.finish=function(){this.minimize(0)},I.TokenSet.Builder.prototype.minimize=function(e){for(var t=this.uncheckedNodes.length-1;t>=e;t--){var n=this.uncheckedNodes[t],a=n.child.toString();a in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[a]:(n.child._str=a,this.minimizedNodes[a]=n.child),this.uncheckedNodes.pop()}},I.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},I.Index.prototype.search=function(e){return this.query((function(t){new I.QueryParser(e,t).parse()}))},I.Index.prototype.query=function(e){for(var t=new I.Query(this.fields),n=Object.create(null),a=Object.create(null),o=Object.create(null),s=Object.create(null),r=Object.create(null),i=0;i<this.fields.length;i++)a[this.fields[i]]=new I.Vector;e.call(t,t);for(i=0;i<t.clauses.length;i++){var c=t.clauses[i],d=null,u=I.Set.empty;d=c.usePipeline?this.pipeline.runString(c.term,{fields:c.fields}):[c.term];for(var l=0;l<d.length;l++){var p=d[l];c.term=p;var g=I.TokenSet.fromClause(c),m=this.tokenSet.intersect(g).toArray();if(0===m.length&&c.presence===I.Query.presence.REQUIRED){for(var f=0;f<c.fields.length;f++){s[P=c.fields[f]]=I.Set.empty}break}for(var h=0;h<m.length;h++){var b=m[h],y=this.invertedIndex[b],v=y._index;for(f=0;f<c.fields.length;f++){var k=y[P=c.fields[f]],x=Object.keys(k),w=b+"/"+P,_=new I.Set(x);if(c.presence==I.Query.presence.REQUIRED&&(u=u.union(_),void 0===s[P]&&(s[P]=I.Set.complete)),c.presence!=I.Query.presence.PROHIBITED){if(a[P].upsert(v,c.boost,(function(e,t){return e+t})),!o[w]){for(var S=0;S<x.length;S++){var E,C=x[S],T=new I.FieldRef(C,P),A=k[C];void 0===(E=n[T])?n[T]=new I.MatchData(b,P,A):E.add(b,P,A)}o[w]=!0}}else void 0===r[P]&&(r[P]=I.Set.empty),r[P]=r[P].union(_)}}}if(c.presence===I.Query.presence.REQUIRED)for(f=0;f<c.fields.length;f++){s[P=c.fields[f]]=s[P].intersect(u)}}var j=I.Set.complete,L=I.Set.empty;for(i=0;i<this.fields.length;i++){var P;s[P=this.fields[i]]&&(j=j.intersect(s[P])),r[P]&&(L=L.union(r[P]))}var N=Object.keys(n),R=[],O=Object.create(null);if(t.isNegated()){N=Object.keys(this.fieldVectors);for(i=0;i<N.length;i++){T=N[i];var F=I.FieldRef.fromString(T);n[T]=new I.MatchData}}for(i=0;i<N.length;i++){var D=(F=I.FieldRef.fromString(N[i])).docRef;if(j.contains(D)&&!L.contains(D)){var M,z=this.fieldVectors[F],B=a[F.fieldName].similarity(z);if(void 0!==(M=O[D]))M.score+=B,M.matchData.combine(n[F]);else{var $={ref:D,score:B,matchData:n[F]};O[D]=$,R.push($)}}}return R.sort((function(e,t){return t.score-e.score}))},I.Index.prototype.toJSON=function(){var e=Object.keys(this.invertedIndex).sort().map((function(e){return[e,this.invertedIndex[e]]}),this),t=Object.keys(this.fieldVectors).map((function(e){return[e,this.fieldVectors[e].toJSON()]}),this);return{version:I.version,fields:this.fields,fieldVectors:t,invertedIndex:e,pipeline:this.pipeline.toJSON()}},I.Index.load=function(e){var t={},n={},a=e.fieldVectors,o=Object.create(null),s=e.invertedIndex,r=new I.TokenSet.Builder,i=I.Pipeline.load(e.pipeline);e.version!=I.version&&I.utils.warn("Version mismatch when loading serialised index. Current version of lunr '"+I.version+"' does not match serialized index '"+e.version+"'");for(var c=0;c<a.length;c++){var d=(l=a[c])[0],u=l[1];n[d]=new I.Vector(u)}for(c=0;c<s.length;c++){var l,p=(l=s[c])[0],g=l[1];r.insert(p),o[p]=g}return r.finish(),t.fields=e.fields,t.fieldVectors=n,t.invertedIndex=o,t.tokenSet=r.root,t.pipeline=i,new I.Index(t)},I.Builder=function(){this._ref="id",this._fields=Object.create(null),this._documents=Object.create(null),this.invertedIndex=Object.create(null),this.fieldTermFrequencies={},this.fieldLengths={},this.tokenizer=I.tokenizer,this.pipeline=new I.Pipeline,this.searchPipeline=new I.Pipeline,this.documentCount=0,this._b=.75,this._k1=1.2,this.termIndex=0,this.metadataWhitelist=[]},I.Builder.prototype.ref=function(e){this._ref=e},I.Builder.prototype.field=function(e,t){if(/\//.test(e))throw new RangeError("Field '"+e+"' contains illegal character '/'");this._fields[e]=t||{}},I.Builder.prototype.b=function(e){this._b=e<0?0:e>1?1:e},I.Builder.prototype.k1=function(e){this._k1=e},I.Builder.prototype.add=function(e,t){var n=e[this._ref],a=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var o=0;o<a.length;o++){var s=a[o],r=this._fields[s].extractor,i=r?r(e):e[s],c=this.tokenizer(i,{fields:[s]}),d=this.pipeline.run(c),u=new I.FieldRef(n,s),l=Object.create(null);this.fieldTermFrequencies[u]=l,this.fieldLengths[u]=0,this.fieldLengths[u]+=d.length;for(var p=0;p<d.length;p++){var g=d[p];if(null==l[g]&&(l[g]=0),l[g]+=1,null==this.invertedIndex[g]){var m=Object.create(null);m._index=this.termIndex,this.termIndex+=1;for(var f=0;f<a.length;f++)m[a[f]]=Object.create(null);this.invertedIndex[g]=m}null==this.invertedIndex[g][s][n]&&(this.invertedIndex[g][s][n]=Object.create(null));for(var h=0;h<this.metadataWhitelist.length;h++){var b=this.metadataWhitelist[h],y=g.metadata[b];null==this.invertedIndex[g][s][n][b]&&(this.invertedIndex[g][s][n][b]=[]),this.invertedIndex[g][s][n][b].push(y)}}}},I.Builder.prototype.calculateAverageFieldLengths=function(){for(var e=Object.keys(this.fieldLengths),t=e.length,n={},a={},o=0;o<t;o++){var s=I.FieldRef.fromString(e[o]),r=s.fieldName;a[r]||(a[r]=0),a[r]+=1,n[r]||(n[r]=0),n[r]+=this.fieldLengths[s]}var i=Object.keys(this._fields);for(o=0;o<i.length;o++){var c=i[o];n[c]=n[c]/a[c]}this.averageFieldLength=n},I.Builder.prototype.createFieldVectors=function(){for(var e={},t=Object.keys(this.fieldTermFrequencies),n=t.length,a=Object.create(null),o=0;o<n;o++){for(var s=I.FieldRef.fromString(t[o]),r=s.fieldName,i=this.fieldLengths[s],c=new I.Vector,d=this.fieldTermFrequencies[s],u=Object.keys(d),l=u.length,p=this._fields[r].boost||1,g=this._documents[s.docRef].boost||1,m=0;m<l;m++){var f,h,b,y=u[m],v=d[y],k=this.invertedIndex[y]._index;void 0===a[y]?(f=I.idf(this.invertedIndex[y],this.documentCount),a[y]=f):f=a[y],h=f*((this._k1+1)*v)/(this._k1*(1-this._b+this._b*(i/this.averageFieldLength[r]))+v),h*=p,h*=g,b=Math.round(1e3*h)/1e3,c.insert(k,b)}e[s]=c}this.fieldVectors=e},I.Builder.prototype.createTokenSet=function(){this.tokenSet=I.TokenSet.fromArray(Object.keys(this.invertedIndex).sort())},I.Builder.prototype.build=function(){return this.calculateAverageFieldLengths(),this.createFieldVectors(),this.createTokenSet(),new I.Index({invertedIndex:this.invertedIndex,fieldVectors:this.fieldVectors,tokenSet:this.tokenSet,fields:Object.keys(this._fields),pipeline:this.searchPipeline})},I.Builder.prototype.use=function(e){var t=Array.prototype.slice.call(arguments,1);t.unshift(this),e.apply(this,t)},I.MatchData=function(e,t,n){for(var a=Object.create(null),o=Object.keys(n||{}),s=0;s<o.length;s++){var r=o[s];a[r]=n[r].slice()}this.metadata=Object.create(null),void 0!==e&&(this.metadata[e]=Object.create(null),this.metadata[e][t]=a)},I.MatchData.prototype.combine=function(e){for(var t=Object.keys(e.metadata),n=0;n<t.length;n++){var a=t[n],o=Object.keys(e.metadata[a]);null==this.metadata[a]&&(this.metadata[a]=Object.create(null));for(var s=0;s<o.length;s++){var r=o[s],i=Object.keys(e.metadata[a][r]);null==this.metadata[a][r]&&(this.metadata[a][r]=Object.create(null));for(var c=0;c<i.length;c++){var d=i[c];null==this.metadata[a][r][d]?this.metadata[a][r][d]=e.metadata[a][r][d]:this.metadata[a][r][d]=this.metadata[a][r][d].concat(e.metadata[a][r][d])}}}},I.MatchData.prototype.add=function(e,t,n){if(!(e in this.metadata))return this.metadata[e]=Object.create(null),void(this.metadata[e][t]=n);if(t in this.metadata[e])for(var a=Object.keys(n),o=0;o<a.length;o++){var s=a[o];s in this.metadata[e][t]?this.metadata[e][t][s]=this.metadata[e][t][s].concat(n[s]):this.metadata[e][t][s]=n[s]}else this.metadata[e][t]=n},I.Query=function(e){this.clauses=[],this.allFields=e},I.Query.wildcard=new String("*"),I.Query.wildcard.NONE=0,I.Query.wildcard.LEADING=1,I.Query.wildcard.TRAILING=2,I.Query.presence={OPTIONAL:1,REQUIRED:2,PROHIBITED:3},I.Query.prototype.clause=function(e){return"fields"in e||(e.fields=this.allFields),"boost"in e||(e.boost=1),"usePipeline"in e||(e.usePipeline=!0),"wildcard"in e||(e.wildcard=I.Query.wildcard.NONE),e.wildcard&I.Query.wildcard.LEADING&&e.term.charAt(0)!=I.Query.wildcard&&(e.term="*"+e.term),e.wildcard&I.Query.wildcard.TRAILING&&e.term.slice(-1)!=I.Query.wildcard&&(e.term=e.term+"*"),"presence"in e||(e.presence=I.Query.presence.OPTIONAL),this.clauses.push(e),this},I.Query.prototype.isNegated=function(){for(var e=0;e<this.clauses.length;e++)if(this.clauses[e].presence!=I.Query.presence.PROHIBITED)return!1;return!0},I.Query.prototype.term=function(e,t){if(Array.isArray(e))return e.forEach((function(e){this.term(e,I.utils.clone(t))}),this),this;var n=t||{};return n.term=e.toString(),this.clause(n),this},I.QueryParseError=function(e,t,n){this.name="QueryParseError",this.message=e,this.start=t,this.end=n},I.QueryParseError.prototype=new Error,I.QueryLexer=function(e){this.lexemes=[],this.str=e,this.length=e.length,this.pos=0,this.start=0,this.escapeCharPositions=[]},I.QueryLexer.prototype.run=function(){for(var e=I.QueryLexer.lexText;e;)e=e(this)},I.QueryLexer.prototype.sliceString=function(){for(var e=[],t=this.start,n=this.pos,a=0;a<this.escapeCharPositions.length;a++)n=this.escapeCharPositions[a],e.push(this.str.slice(t,n)),t=n+1;return e.push(this.str.slice(t,this.pos)),this.escapeCharPositions.length=0,e.join("")},I.QueryLexer.prototype.emit=function(e){this.lexemes.push({type:e,str:this.sliceString(),start:this.start,end:this.pos}),this.start=this.pos},I.QueryLexer.prototype.escapeCharacter=function(){this.escapeCharPositions.push(this.pos-1),this.pos+=1},I.QueryLexer.prototype.next=function(){if(this.pos>=this.length)return I.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},I.QueryLexer.prototype.width=function(){return this.pos-this.start},I.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},I.QueryLexer.prototype.backup=function(){this.pos-=1},I.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=I.QueryLexer.EOS&&this.backup()},I.QueryLexer.prototype.more=function(){return this.pos<this.length},I.QueryLexer.EOS="EOS",I.QueryLexer.FIELD="FIELD",I.QueryLexer.TERM="TERM",I.QueryLexer.EDIT_DISTANCE="EDIT_DISTANCE",I.QueryLexer.BOOST="BOOST",I.QueryLexer.PRESENCE="PRESENCE",I.QueryLexer.lexField=function(e){return e.backup(),e.emit(I.QueryLexer.FIELD),e.ignore(),I.QueryLexer.lexText},I.QueryLexer.lexTerm=function(e){if(e.width()>1&&(e.backup(),e.emit(I.QueryLexer.TERM)),e.ignore(),e.more())return I.QueryLexer.lexText},I.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(I.QueryLexer.EDIT_DISTANCE),I.QueryLexer.lexText},I.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(I.QueryLexer.BOOST),I.QueryLexer.lexText},I.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(I.QueryLexer.TERM)},I.QueryLexer.termSeparator=I.tokenizer.separator,I.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==I.QueryLexer.EOS)return I.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return I.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(I.QueryLexer.TERM),I.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(I.QueryLexer.TERM),I.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(I.QueryLexer.PRESENCE),I.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(I.QueryLexer.PRESENCE),I.QueryLexer.lexText;if(t.match(I.QueryLexer.termSeparator))return I.QueryLexer.lexTerm}else e.escapeCharacter()}},I.QueryParser=function(e,t){this.lexer=new I.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},I.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=I.QueryParser.parseClause;e;)e=e(this);return this.query},I.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},I.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},I.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},I.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case I.QueryLexer.PRESENCE:return I.QueryParser.parsePresence;case I.QueryLexer.FIELD:return I.QueryParser.parseField;case I.QueryLexer.TERM:return I.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new I.QueryParseError(n,t.start,t.end)}},I.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=I.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=I.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new I.QueryParseError(n,t.start,t.end)}var a=e.peekLexeme();if(null==a){n="expecting term or field, found nothing";throw new I.QueryParseError(n,t.start,t.end)}switch(a.type){case I.QueryLexer.FIELD:return I.QueryParser.parseField;case I.QueryLexer.TERM:return I.QueryParser.parseTerm;default:n="expecting term or field, found '"+a.type+"'";throw new I.QueryParseError(n,a.start,a.end)}}},I.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),a="unrecognised field '"+t.str+"', possible fields: "+n;throw new I.QueryParseError(a,t.start,t.end)}e.currentClause.fields=[t.str];var o=e.peekLexeme();if(null==o){a="expecting term, found nothing";throw new I.QueryParseError(a,t.start,t.end)}if(o.type===I.QueryLexer.TERM)return I.QueryParser.parseTerm;a="expecting term, found '"+o.type+"'";throw new I.QueryParseError(a,o.start,o.end)}},I.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case I.QueryLexer.TERM:return e.nextClause(),I.QueryParser.parseTerm;case I.QueryLexer.FIELD:return e.nextClause(),I.QueryParser.parseField;case I.QueryLexer.EDIT_DISTANCE:return I.QueryParser.parseEditDistance;case I.QueryLexer.BOOST:return I.QueryParser.parseBoost;case I.QueryLexer.PRESENCE:return e.nextClause(),I.QueryParser.parsePresence;default:var a="Unexpected lexeme type '"+n.type+"'";throw new I.QueryParseError(a,n.start,n.end)}else e.nextClause()}},I.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var a="edit distance must be numeric";throw new I.QueryParseError(a,t.start,t.end)}e.currentClause.editDistance=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case I.QueryLexer.TERM:return e.nextClause(),I.QueryParser.parseTerm;case I.QueryLexer.FIELD:return e.nextClause(),I.QueryParser.parseField;case I.QueryLexer.EDIT_DISTANCE:return I.QueryParser.parseEditDistance;case I.QueryLexer.BOOST:return I.QueryParser.parseBoost;case I.QueryLexer.PRESENCE:return e.nextClause(),I.QueryParser.parsePresence;default:a="Unexpected lexeme type '"+o.type+"'";throw new I.QueryParseError(a,o.start,o.end)}else e.nextClause()}},I.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var a="boost must be numeric";throw new I.QueryParseError(a,t.start,t.end)}e.currentClause.boost=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case I.QueryLexer.TERM:return e.nextClause(),I.QueryParser.parseTerm;case I.QueryLexer.FIELD:return e.nextClause(),I.QueryParser.parseField;case I.QueryLexer.EDIT_DISTANCE:return I.QueryParser.parseEditDistance;case I.QueryLexer.BOOST:return I.QueryParser.parseBoost;case I.QueryLexer.PRESENCE:return e.nextClause(),I.QueryParser.parsePresence;default:a="Unexpected lexeme type '"+o.type+"'";throw new I.QueryParseError(a,o.start,o.end)}else e.nextClause()}},void 0===(o="function"==typeof(a=function(){return I})?a.call(t,n,t,e):a)||(e.exports=o)}()},10119:(e,t,n)=>{"use strict";n.r(t)},51043:(e,t,n)=>{"use strict";n.r(t)},5947:function(e,t,n){var a,o;a=function(){var e,t,n={version:"0.2.0"},a=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function o(e,t,n){return e<t?t:e>n?n:e}function s(e){return 100*(-1+e)}function r(e,t,n){var o;return(o="translate3d"===a.positionUsing?{transform:"translate3d("+s(e)+"%,0,0)"}:"translate"===a.positionUsing?{transform:"translate("+s(e)+"%,0)"}:{"margin-left":s(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(a[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,a.minimum,1),n.status=1===e?null:e;var s=n.render(!t),d=s.querySelector(a.barSelector),u=a.speed,l=a.easing;return s.offsetWidth,i((function(t){""===a.positionUsing&&(a.positionUsing=n.getPositioningCSS()),c(d,r(e,u,l)),1===e?(c(s,{transition:"none",opacity:1}),s.offsetWidth,setTimeout((function(){c(s,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),a.trickleSpeed)};return a.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*a.trickleRate)},e=0,t=0,n.promise=function(a){return a&&"resolved"!==a.state()?(0===t&&n.start(),e++,t++,a.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=a.template;var o,r=t.querySelector(a.barSelector),i=e?"-100":s(n.status||0),d=document.querySelector(a.parent);return c(r,{transition:"all 0 linear",transform:"translate3d("+i+"%,0,0)"}),a.showSpinner||(o=t.querySelector(a.spinnerSelector))&&g(o),d!=document.body&&u(d,"nprogress-custom-parent"),d.appendChild(t),t},n.remove=function(){l(document.documentElement,"nprogress-busy"),l(document.querySelector(a.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&g(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var i=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),c=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function a(t){var n=document.body.style;if(t in n)return t;for(var a,o=e.length,s=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((a=e[o]+s)in n)return a;return t}function o(e){return e=n(e),t[e]||(t[e]=a(e))}function s(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,a,o=arguments;if(2==o.length)for(n in t)void 0!==(a=t[n])&&t.hasOwnProperty(n)&&s(e,n,a);else s(e,o[1],o[2])}}();function d(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),a=n+t;d(n,t)||(e.className=a.substring(1))}function l(e,t){var n,a=p(e);d(e,t)&&(n=a.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function g(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof a?a.call(t,n,t,e):a)||(e.exports=o)},35302:(e,t,n)=>{var a=n(64634);e.exports=g,e.exports.parse=s,e.exports.compile=function(e,t){return i(s(e,t),t)},e.exports.tokensToFunction=i,e.exports.tokensToRegExp=p;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function s(e,t){for(var n,a=[],s=0,r=0,i="",u=t&&t.delimiter||"/";null!=(n=o.exec(e));){var l=n[0],p=n[1],g=n.index;if(i+=e.slice(r,g),r=g+l.length,p)i+=p[1];else{var m=e[r],f=n[2],h=n[3],b=n[4],y=n[5],v=n[6],k=n[7];i&&(a.push(i),i="");var x=null!=f&&null!=m&&m!==f,w="+"===v||"*"===v,_="?"===v||"*"===v,S=n[2]||u,E=b||y;a.push({name:h||s++,prefix:f||"",delimiter:S,optional:_,repeat:w,partial:x,asterisk:!!k,pattern:E?d(E):k?".*":"[^"+c(S)+"]+?"})}}return r<e.length&&(i+=e.substr(r)),i&&a.push(i),a}function r(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function i(e,t){for(var n=new Array(e.length),o=0;o<e.length;o++)"object"==typeof e[o]&&(n[o]=new RegExp("^(?:"+e[o].pattern+")$",l(t)));return function(t,o){for(var s="",i=t||{},c=(o||{}).pretty?r:encodeURIComponent,d=0;d<e.length;d++){var u=e[d];if("string"!=typeof u){var l,p=i[u.name];if(null==p){if(u.optional){u.partial&&(s+=u.prefix);continue}throw new TypeError('Expected "'+u.name+'" to be defined')}if(a(p)){if(!u.repeat)throw new TypeError('Expected "'+u.name+'" to not repeat, but received `'+JSON.stringify(p)+"`");if(0===p.length){if(u.optional)continue;throw new TypeError('Expected "'+u.name+'" to not be empty')}for(var g=0;g<p.length;g++){if(l=c(p[g]),!n[d].test(l))throw new TypeError('Expected all "'+u.name+'" to match "'+u.pattern+'", but received `'+JSON.stringify(l)+"`");s+=(0===g?u.prefix:u.delimiter)+l}}else{if(l=u.asterisk?encodeURI(p).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):c(p),!n[d].test(l))throw new TypeError('Expected "'+u.name+'" to match "'+u.pattern+'", but received "'+l+'"');s+=u.prefix+l}}else s+=u}return s}}function c(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function d(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function u(e,t){return e.keys=t,e}function l(e){return e&&e.sensitive?"":"i"}function p(e,t,n){a(t)||(n=t||n,t=[]);for(var o=(n=n||{}).strict,s=!1!==n.end,r="",i=0;i<e.length;i++){var d=e[i];if("string"==typeof d)r+=c(d);else{var p=c(d.prefix),g="(?:"+d.pattern+")";t.push(d),d.repeat&&(g+="(?:"+p+g+")*"),r+=g=d.optional?d.partial?p+"("+g+")?":"(?:"+p+"("+g+"))?":p+"("+g+")"}}var m=c(n.delimiter||"/"),f=r.slice(-m.length)===m;return o||(r=(f?r.slice(0,-m.length):r)+"(?:"+m+"(?=$))?"),r+=s?"$":o&&f?"":"(?="+m+"|$)",u(new RegExp("^"+r,l(n)),t)}function g(e,t,n){return a(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var a=0;a<n.length;a++)t.push({name:a,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return u(e,t)}(e,t):a(e)?function(e,t,n){for(var a=[],o=0;o<e.length;o++)a.push(g(e[o],t,n).source);return u(new RegExp("(?:"+a.join("|")+")",l(n)),t)}(e,t,n):function(e,t,n){return p(s(e,n),t,n)}(e,t,n)}},19700:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,a,o,s){if(n.language===a){var r=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof s&&!s(e))return e;for(var o,i=r.length;-1!==n.code.indexOf(o=t(a,i));)++i;return r[i]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,a){if(n.language===a&&n.tokenStack){n.grammar=e.languages[a];var o=0,s=Object.keys(n.tokenStack);!function r(i){for(var c=0;c<i.length&&!(o>=s.length);c++){var d=i[c];if("string"==typeof d||d.content&&"string"==typeof d.content){var u=s[o],l=n.tokenStack[u],p="string"==typeof d?d:d.content,g=t(a,u),m=p.indexOf(g);if(m>-1){++o;var f=p.substring(0,m),h=new e.Token(a,e.tokenize(l,n.grammar),"language-"+a,l),b=p.substring(m+g.length),y=[];f&&y.push.apply(y,r([f])),y.push(h),b&&y.push.apply(y,r([b])),"string"==typeof d?i.splice.apply(i,[c,1].concat(y)):d.content=y}}else d.content&&r(d.content)}return i}(n.tokens)}}}})}(Prism)},30905:()=>{!function(e){var t=e.languages.powershell={comment:[{pattern:/(^|[^`])<#[\s\S]*?#>/,lookbehind:!0},{pattern:/(^|[^`])#.*/,lookbehind:!0}],string:[{pattern:/"(?:`[\s\S]|[^`"])*"/,greedy:!0,inside:null},{pattern:/'(?:[^']|'')*'/,greedy:!0}],namespace:/\[[a-z](?:\[(?:\[[^\]]*\]|[^\[\]])*\]|[^\[\]])*\]/i,boolean:/\$(?:false|true)\b/i,variable:/\$\w+\b/,function:[/\b(?:Add|Approve|Assert|Backup|Block|Checkpoint|Clear|Close|Compare|Complete|Compress|Confirm|Connect|Convert|ConvertFrom|ConvertTo|Copy|Debug|Deny|Disable|Disconnect|Dismount|Edit|Enable|Enter|Exit|Expand|Export|Find|ForEach|Format|Get|Grant|Group|Hide|Import|Initialize|Install|Invoke|Join|Limit|Lock|Measure|Merge|Move|New|Open|Optimize|Out|Ping|Pop|Protect|Publish|Push|Read|Receive|Redo|Register|Remove|Rename|Repair|Request|Reset|Resize|Resolve|Restart|Restore|Resume|Revoke|Save|Search|Select|Send|Set|Show|Skip|Sort|Split|Start|Step|Stop|Submit|Suspend|Switch|Sync|Tee|Test|Trace|Unblock|Undo|Uninstall|Unlock|Unprotect|Unpublish|Unregister|Update|Use|Wait|Watch|Where|Write)-[a-z]+\b/i,/\b(?:ac|cat|chdir|clc|cli|clp|clv|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|ebp|echo|epal|epcsv|epsn|erase|fc|fl|ft|fw|gal|gbp|gc|gci|gcs|gdr|gi|gl|gm|gp|gps|group|gsv|gu|gv|gwmi|iex|ii|ipal|ipcsv|ipsn|irm|iwmi|iwr|kill|lp|ls|measure|mi|mount|move|mp|mv|nal|ndr|ni|nv|ogv|popd|ps|pushd|pwd|rbp|rd|rdr|ren|ri|rm|rmdir|rni|rnp|rp|rv|rvpa|rwmi|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spps|spsv|start|sv|swmi|tee|trcm|type|write)\b/i],keyword:/\b(?:Begin|Break|Catch|Class|Continue|Data|Define|Do|DynamicParam|Else|ElseIf|End|Exit|Filter|Finally|For|ForEach|From|Function|If|InlineScript|Parallel|Param|Process|Return|Sequence|Switch|Throw|Trap|Try|Until|Using|Var|While|Workflow)\b/i,operator:{pattern:/(^|\W)(?:!|-(?:b?(?:and|x?or)|as|(?:Not)?(?:Contains|In|Like|Match)|eq|ge|gt|is(?:Not)?|Join|le|lt|ne|not|Replace|sh[lr])\b|-[-=]?|\+[+=]?|[*\/%]=?)/i,lookbehind:!0},punctuation:/[|{}[\];(),.]/};t.string[0].inside={function:{pattern:/(^|[^`])\$\((?:\$\([^\r\n()]*\)|(?!\$\()[^\r\n)])*\)/,lookbehind:!0,inside:t},boolean:t.boolean,variable:t.variable}}(Prism)},41648:()=>{!function(e){e.languages.ruby=e.languages.extend("clike",{comment:{pattern:/#.*|^=begin\s[\s\S]*?^=end/m,greedy:!0},"class-name":{pattern:/(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,operator:/\.{2,3}|&\.|===|<?=>|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),e.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var t={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:e.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete e.languages.ruby.function;var n="(?:"+[/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,/\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,/<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source].join("|")+")",a=/(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;e.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp(/%r/.source+n+/[egimnosux]{0,6}/.source),greedy:!0,inside:{interpolation:t,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:t,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp(/(^|[^:]):/.source+a),lookbehind:!0,greedy:!0},{pattern:RegExp(/([\r\n{(,][ \t]*)/.source+a+/(?=:(?!:))/.source),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),e.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp(/%[qQiIwWs]?/.source+n),greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:t,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp(/%x/.source+n),greedy:!0,inside:{interpolation:t,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:t,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete e.languages.ruby.string,e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),e.languages.rb=e.languages.ruby}(Prism)},75430:(e,t,n)=>{var a={"./prism-powershell":30905,"./prism-ruby":41648};function o(e){var t=s(e);return n(t)}function s(e){if(!n.o(a,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return a[e]}o.keys=function(){return Object.keys(a)},o.resolve=s,e.exports=o,o.id=75430},2694:(e,t,n)=>{"use strict";var a=n(6925);function o(){}function s(){}s.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,s,r){if(r!==a){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:s,resetWarningCache:o};return n.PropTypes=n,n}},5556:(e,t,n)=>{e.exports=n(2694)()},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},22551:(e,t,n)=>{"use strict";var a=n(96540),o=n(69982);function s(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var r=new Set,i={};function c(e,t){d(e,t),d(e+"Capture",t)}function d(e,t){for(i[e]=t,e=0;e<t.length;e++)r.add(t[e])}var u=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),l=Object.prototype.hasOwnProperty,p=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,g={},m={};function f(e,t,n,a,o,s,r){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=a,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=s,this.removeEmptyString=r}var h={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){h[e]=new f(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];h[t]=new f(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){h[e]=new f(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){h[e]=new f(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){h[e]=new f(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){h[e]=new f(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){h[e]=new f(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){h[e]=new f(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){h[e]=new f(e,5,!1,e.toLowerCase(),null,!1,!1)}));var b=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function v(e,t,n,a){var o=h.hasOwnProperty(t)?h[t]:null;(null!==o?0!==o.type:a||!(2<t.length)||"o"!==t[0]&&"O"!==t[0]||"n"!==t[1]&&"N"!==t[1])&&(function(e,t,n,a){if(null==t||function(e,t,n,a){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!a&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,a))return!0;if(a)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,o,a)&&(n=null),a||null===o?function(e){return!!l.call(m,e)||!l.call(g,e)&&(p.test(e)?m[e]=!0:(g[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):o.mustUseProperty?e[o.propertyName]=null===n?3!==o.type&&"":n:(t=o.attributeName,a=o.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(o=o.type)||4===o&&!0===n?"":""+n,a?e.setAttributeNS(a,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(b,y);h[t]=new f(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(b,y);h[t]=new f(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(b,y);h[t]=new f(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){h[e]=new f(e,1,!1,e.toLowerCase(),null,!1,!1)})),h.xlinkHref=new f("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){h[e]=new f(e,1,!1,e.toLowerCase(),null,!0,!0)}));var k=a.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,x=Symbol.for("react.element"),w=Symbol.for("react.portal"),_=Symbol.for("react.fragment"),S=Symbol.for("react.strict_mode"),E=Symbol.for("react.profiler"),C=Symbol.for("react.provider"),T=Symbol.for("react.context"),A=Symbol.for("react.forward_ref"),j=Symbol.for("react.suspense"),L=Symbol.for("react.suspense_list"),P=Symbol.for("react.memo"),N=Symbol.for("react.lazy");Symbol.for("react.scope"),Symbol.for("react.debug_trace_mode");var R=Symbol.for("react.offscreen");Symbol.for("react.legacy_hidden"),Symbol.for("react.cache"),Symbol.for("react.tracing_marker");var O=Symbol.iterator;function I(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=O&&e[O]||e["@@iterator"])?e:null}var F,D=Object.assign;function M(e){if(void 0===F)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);F=t&&t[1]||""}return"\n"+F+e}var z=!1;function B(e,t){if(!e||z)return"";z=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(d){var a=d}Reflect.construct(e,[],t)}else{try{t.call()}catch(d){a=d}e.call(t.prototype)}else{try{throw Error()}catch(d){a=d}e()}}catch(d){if(d&&a&&"string"==typeof d.stack){for(var o=d.stack.split("\n"),s=a.stack.split("\n"),r=o.length-1,i=s.length-1;1<=r&&0<=i&&o[r]!==s[i];)i--;for(;1<=r&&0<=i;r--,i--)if(o[r]!==s[i]){if(1!==r||1!==i)do{if(r--,0>--i||o[r]!==s[i]){var c="\n"+o[r].replace(" at new "," at ");return e.displayName&&c.includes("<anonymous>")&&(c=c.replace("<anonymous>",e.displayName)),c}}while(1<=r&&0<=i);break}}}finally{z=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?M(e):""}function $(e){switch(e.tag){case 5:return M(e.type);case 16:return M("Lazy");case 13:return M("Suspense");case 19:return M("SuspenseList");case 0:case 2:case 15:return e=B(e.type,!1);case 11:return e=B(e.type.render,!1);case 1:return e=B(e.type,!0);default:return""}}function U(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case _:return"Fragment";case w:return"Portal";case E:return"Profiler";case S:return"StrictMode";case j:return"Suspense";case L:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case T:return(e.displayName||"Context")+".Consumer";case C:return(e._context.displayName||"Context")+".Provider";case A:var t=e.render;return(e=e.displayName)||(e=""!==(e=t.displayName||t.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case P:return null!==(t=e.displayName||null)?t:U(e.type)||"Memo";case N:t=e._payload,e=e._init;try{return U(e(t))}catch(n){}}return null}function Q(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=(e=t.render).displayName||e.name||"",t.displayName||(""!==e?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return U(t);case 8:return t===S?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"==typeof t)return t.displayName||t.name||null;if("string"==typeof t)return t}return null}function V(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":case"object":return e;default:return""}}function H(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function W(e){e._valueTracker||(e._valueTracker=function(e){var t=H(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),a=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var o=n.get,s=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(e){a=""+e,s.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return a},setValue:function(e){a=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function q(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),a="";return e&&(a=H(e)?e.checked?"true":"false":e.value),(e=a)!==n&&(t.setValue(e),!0)}function G(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function X(e,t){var n=t.checked;return D({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function K(e,t){var n=null==t.defaultValue?"":t.defaultValue,a=null!=t.checked?t.checked:t.defaultChecked;n=V(null!=t.value?t.value:n),e._wrapperState={initialChecked:a,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function Y(e,t){null!=(t=t.checked)&&v(e,"checked",t,!1)}function Z(e,t){Y(e,t);var n=V(t.value),a=t.type;if(null!=n)"number"===a?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===a||"reset"===a)return void e.removeAttribute("value");t.hasOwnProperty("value")?ee(e,t.type,n):t.hasOwnProperty("defaultValue")&&ee(e,t.type,V(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function J(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var a=t.type;if(!("submit"!==a&&"reset"!==a||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function ee(e,t,n){"number"===t&&G(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var te=Array.isArray;function ne(e,t,n,a){if(e=e.options,t){t={};for(var o=0;o<n.length;o++)t["$"+n[o]]=!0;for(n=0;n<e.length;n++)o=t.hasOwnProperty("$"+e[n].value),e[n].selected!==o&&(e[n].selected=o),o&&a&&(e[n].defaultSelected=!0)}else{for(n=""+V(n),t=null,o=0;o<e.length;o++){if(e[o].value===n)return e[o].selected=!0,void(a&&(e[o].defaultSelected=!0));null!==t||e[o].disabled||(t=e[o])}null!==t&&(t.selected=!0)}}function ae(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(s(91));return D({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function oe(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(s(92));if(te(n)){if(1<n.length)throw Error(s(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:V(n)}}function se(e,t){var n=V(t.value),a=V(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=a&&(e.defaultValue=""+a)}function re(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}function ie(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function ce(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?ie(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var de,ue,le=(ue=function(e,t){if("http://www.w3.org/2000/svg"!==e.namespaceURI||"innerHTML"in e)e.innerHTML=t;else{for((de=de||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=de.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,a){MSApp.execUnsafeLocalFunction((function(){return ue(e,t)}))}:ue);function pe(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var ge={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},me=["Webkit","ms","Moz","O"];function fe(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||ge.hasOwnProperty(e)&&ge[e]?(""+t).trim():t+"px"}function he(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var a=0===n.indexOf("--"),o=fe(n,t[n],a);"float"===n&&(n="cssFloat"),a?e.setProperty(n,o):e[n]=o}}Object.keys(ge).forEach((function(e){me.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),ge[t]=ge[e]}))}));var be=D({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ye(e,t){if(t){if(be[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(s(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(s(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(s(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(s(62))}}function ve(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var ke=null;function xe(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var we=null,_e=null,Se=null;function Ee(e){if(e=ko(e)){if("function"!=typeof we)throw Error(s(280));var t=e.stateNode;t&&(t=wo(t),we(e.stateNode,e.type,t))}}function Ce(e){_e?Se?Se.push(e):Se=[e]:_e=e}function Te(){if(_e){var e=_e,t=Se;if(Se=_e=null,Ee(e),t)for(e=0;e<t.length;e++)Ee(t[e])}}function Ae(e,t){return e(t)}function je(){}var Le=!1;function Pe(e,t,n){if(Le)return e(t,n);Le=!0;try{return Ae(e,t,n)}finally{Le=!1,(null!==_e||null!==Se)&&(je(),Te())}}function Ne(e,t){var n=e.stateNode;if(null===n)return null;var a=wo(n);if(null===a)return null;n=a[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(a=!a.disabled)||(a=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!a;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(s(231,t,typeof n));return n}var Re=!1;if(u)try{var Oe={};Object.defineProperty(Oe,"passive",{get:function(){Re=!0}}),window.addEventListener("test",Oe,Oe),window.removeEventListener("test",Oe,Oe)}catch(ue){Re=!1}function Ie(e,t,n,a,o,s,r,i,c){var d=Array.prototype.slice.call(arguments,3);try{t.apply(n,d)}catch(u){this.onError(u)}}var Fe=!1,De=null,Me=!1,ze=null,Be={onError:function(e){Fe=!0,De=e}};function $e(e,t,n,a,o,s,r,i,c){Fe=!1,De=null,Ie.apply(Be,arguments)}function Ue(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{!!(4098&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Qe(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function Ve(e){if(Ue(e)!==e)throw Error(s(188))}function He(e){return null!==(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ue(e)))throw Error(s(188));return t!==e?null:e}for(var n=e,a=t;;){var o=n.return;if(null===o)break;var r=o.alternate;if(null===r){if(null!==(a=o.return)){n=a;continue}break}if(o.child===r.child){for(r=o.child;r;){if(r===n)return Ve(o),e;if(r===a)return Ve(o),t;r=r.sibling}throw Error(s(188))}if(n.return!==a.return)n=o,a=r;else{for(var i=!1,c=o.child;c;){if(c===n){i=!0,n=o,a=r;break}if(c===a){i=!0,a=o,n=r;break}c=c.sibling}if(!i){for(c=r.child;c;){if(c===n){i=!0,n=r,a=o;break}if(c===a){i=!0,a=r,n=o;break}c=c.sibling}if(!i)throw Error(s(189))}}if(n.alternate!==a)throw Error(s(190))}if(3!==n.tag)throw Error(s(188));return n.stateNode.current===n?e:t}(e))?We(e):null}function We(e){if(5===e.tag||6===e.tag)return e;for(e=e.child;null!==e;){var t=We(e);if(null!==t)return t;e=e.sibling}return null}var qe=o.unstable_scheduleCallback,Ge=o.unstable_cancelCallback,Xe=o.unstable_shouldYield,Ke=o.unstable_requestPaint,Ye=o.unstable_now,Ze=o.unstable_getCurrentPriorityLevel,Je=o.unstable_ImmediatePriority,et=o.unstable_UserBlockingPriority,tt=o.unstable_NormalPriority,nt=o.unstable_LowPriority,at=o.unstable_IdlePriority,ot=null,st=null;var rt=Math.clz32?Math.clz32:function(e){return e>>>=0,0===e?32:31-(it(e)/ct|0)|0},it=Math.log,ct=Math.LN2;var dt=64,ut=4194304;function lt(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return 4194240&e;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return 130023424&e;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function pt(e,t){var n=e.pendingLanes;if(0===n)return 0;var a=0,o=e.suspendedLanes,s=e.pingedLanes,r=268435455&n;if(0!==r){var i=r&~o;0!==i?a=lt(i):0!==(s&=r)&&(a=lt(s))}else 0!==(r=n&~o)?a=lt(r):0!==s&&(a=lt(s));if(0===a)return 0;if(0!==t&&t!==a&&!(t&o)&&((o=a&-a)>=(s=t&-t)||16===o&&4194240&s))return t;if(4&a&&(a|=16&n),0!==(t=e.entangledLanes))for(e=e.entanglements,t&=a;0<t;)o=1<<(n=31-rt(t)),a|=e[n],t&=~o;return a}function gt(e,t){switch(e){case 1:case 2:case 4:return t+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;default:return-1}}function mt(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function ft(){var e=dt;return!(4194240&(dt<<=1))&&(dt=64),e}function ht(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function bt(e,t,n){e.pendingLanes|=t,536870912!==t&&(e.suspendedLanes=0,e.pingedLanes=0),(e=e.eventTimes)[t=31-rt(t)]=n}function yt(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var a=31-rt(n),o=1<<a;o&t|e[a]&t&&(e[a]|=t),n&=~o}}var vt=0;function kt(e){return 1<(e&=-e)?4<e?268435455&e?16:536870912:4:1}var xt,wt,_t,St,Et,Ct=!1,Tt=[],At=null,jt=null,Lt=null,Pt=new Map,Nt=new Map,Rt=[],Ot="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function It(e,t){switch(e){case"focusin":case"focusout":At=null;break;case"dragenter":case"dragleave":jt=null;break;case"mouseover":case"mouseout":Lt=null;break;case"pointerover":case"pointerout":Pt.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":Nt.delete(t.pointerId)}}function Ft(e,t,n,a,o,s){return null===e||e.nativeEvent!==s?(e={blockedOn:t,domEventName:n,eventSystemFlags:a,nativeEvent:s,targetContainers:[o]},null!==t&&(null!==(t=ko(t))&&wt(t)),e):(e.eventSystemFlags|=a,t=e.targetContainers,null!==o&&-1===t.indexOf(o)&&t.push(o),e)}function Dt(e){var t=vo(e.target);if(null!==t){var n=Ue(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Qe(n)))return e.blockedOn=t,void Et(e.priority,(function(){_t(n)}))}else if(3===t&&n.stateNode.current.memoizedState.isDehydrated)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function Mt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Xt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=ko(n))&&wt(t),e.blockedOn=n,!1;var a=new(n=e.nativeEvent).constructor(n.type,n);ke=a,n.target.dispatchEvent(a),ke=null,t.shift()}return!0}function zt(e,t,n){Mt(e)&&n.delete(t)}function Bt(){Ct=!1,null!==At&&Mt(At)&&(At=null),null!==jt&&Mt(jt)&&(jt=null),null!==Lt&&Mt(Lt)&&(Lt=null),Pt.forEach(zt),Nt.forEach(zt)}function $t(e,t){e.blockedOn===t&&(e.blockedOn=null,Ct||(Ct=!0,o.unstable_scheduleCallback(o.unstable_NormalPriority,Bt)))}function Ut(e){function t(t){return $t(t,e)}if(0<Tt.length){$t(Tt[0],e);for(var n=1;n<Tt.length;n++){var a=Tt[n];a.blockedOn===e&&(a.blockedOn=null)}}for(null!==At&&$t(At,e),null!==jt&&$t(jt,e),null!==Lt&&$t(Lt,e),Pt.forEach(t),Nt.forEach(t),n=0;n<Rt.length;n++)(a=Rt[n]).blockedOn===e&&(a.blockedOn=null);for(;0<Rt.length&&null===(n=Rt[0]).blockedOn;)Dt(n),null===n.blockedOn&&Rt.shift()}var Qt=k.ReactCurrentBatchConfig,Vt=!0;function Ht(e,t,n,a){var o=vt,s=Qt.transition;Qt.transition=null;try{vt=1,qt(e,t,n,a)}finally{vt=o,Qt.transition=s}}function Wt(e,t,n,a){var o=vt,s=Qt.transition;Qt.transition=null;try{vt=4,qt(e,t,n,a)}finally{vt=o,Qt.transition=s}}function qt(e,t,n,a){if(Vt){var o=Xt(e,t,n,a);if(null===o)Va(e,t,a,Gt,n),It(e,a);else if(function(e,t,n,a,o){switch(t){case"focusin":return At=Ft(At,e,t,n,a,o),!0;case"dragenter":return jt=Ft(jt,e,t,n,a,o),!0;case"mouseover":return Lt=Ft(Lt,e,t,n,a,o),!0;case"pointerover":var s=o.pointerId;return Pt.set(s,Ft(Pt.get(s)||null,e,t,n,a,o)),!0;case"gotpointercapture":return s=o.pointerId,Nt.set(s,Ft(Nt.get(s)||null,e,t,n,a,o)),!0}return!1}(o,e,t,n,a))a.stopPropagation();else if(It(e,a),4&t&&-1<Ot.indexOf(e)){for(;null!==o;){var s=ko(o);if(null!==s&&xt(s),null===(s=Xt(e,t,n,a))&&Va(e,t,a,Gt,n),s===o)break;o=s}null!==o&&a.stopPropagation()}else Va(e,t,a,null,n)}}var Gt=null;function Xt(e,t,n,a){if(Gt=null,null!==(e=vo(e=xe(a))))if(null===(t=Ue(e)))e=null;else if(13===(n=t.tag)){if(null!==(e=Qe(t)))return e;e=null}else if(3===n){if(t.stateNode.current.memoizedState.isDehydrated)return 3===t.tag?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null);return Gt=e,null}function Kt(e){switch(e){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch(Ze()){case Je:return 1;case et:return 4;case tt:case nt:return 16;case at:return 536870912;default:return 16}default:return 16}}var Yt=null,Zt=null,Jt=null;function en(){if(Jt)return Jt;var e,t,n=Zt,a=n.length,o="value"in Yt?Yt.value:Yt.textContent,s=o.length;for(e=0;e<a&&n[e]===o[e];e++);var r=a-e;for(t=1;t<=r&&n[a-t]===o[s-t];t++);return Jt=o.slice(e,1<t?1-t:void 0)}function tn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function nn(){return!0}function an(){return!1}function on(e){function t(t,n,a,o,s){for(var r in this._reactName=t,this._targetInst=a,this.type=n,this.nativeEvent=o,this.target=s,this.currentTarget=null,e)e.hasOwnProperty(r)&&(t=e[r],this[r]=t?t(o):o[r]);return this.isDefaultPrevented=(null!=o.defaultPrevented?o.defaultPrevented:!1===o.returnValue)?nn:an,this.isPropagationStopped=an,this}return D(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=nn)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=nn)},persist:function(){},isPersistent:nn}),t}var sn,rn,cn,dn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},un=on(dn),ln=D({},dn,{view:0,detail:0}),pn=on(ln),gn=D({},ln,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:En,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==cn&&(cn&&"mousemove"===e.type?(sn=e.screenX-cn.screenX,rn=e.screenY-cn.screenY):rn=sn=0,cn=e),sn)},movementY:function(e){return"movementY"in e?e.movementY:rn}}),mn=on(gn),fn=on(D({},gn,{dataTransfer:0})),hn=on(D({},ln,{relatedTarget:0})),bn=on(D({},dn,{animationName:0,elapsedTime:0,pseudoElement:0})),yn=D({},dn,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),vn=on(yn),kn=on(D({},dn,{data:0})),xn={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},wn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},_n={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Sn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=_n[e])&&!!t[e]}function En(){return Sn}var Cn=D({},ln,{key:function(e){if(e.key){var t=xn[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=tn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?wn[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:En,charCode:function(e){return"keypress"===e.type?tn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?tn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),Tn=on(Cn),An=on(D({},gn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),jn=on(D({},ln,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:En})),Ln=on(D({},dn,{propertyName:0,elapsedTime:0,pseudoElement:0})),Pn=D({},gn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Nn=on(Pn),Rn=[9,13,27,32],On=u&&"CompositionEvent"in window,In=null;u&&"documentMode"in document&&(In=document.documentMode);var Fn=u&&"TextEvent"in window&&!In,Dn=u&&(!On||In&&8<In&&11>=In),Mn=String.fromCharCode(32),zn=!1;function Bn(e,t){switch(e){case"keyup":return-1!==Rn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function $n(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var Un=!1;var Qn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Vn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Qn[e.type]:"textarea"===t}function Hn(e,t,n,a){Ce(a),0<(t=Wa(t,"onChange")).length&&(n=new un("onChange","change",null,n,a),e.push({event:n,listeners:t}))}var Wn=null,qn=null;function Gn(e){Ma(e,0)}function Xn(e){if(q(xo(e)))return e}function Kn(e,t){if("change"===e)return t}var Yn=!1;if(u){var Zn;if(u){var Jn="oninput"in document;if(!Jn){var ea=document.createElement("div");ea.setAttribute("oninput","return;"),Jn="function"==typeof ea.oninput}Zn=Jn}else Zn=!1;Yn=Zn&&(!document.documentMode||9<document.documentMode)}function ta(){Wn&&(Wn.detachEvent("onpropertychange",na),qn=Wn=null)}function na(e){if("value"===e.propertyName&&Xn(qn)){var t=[];Hn(t,qn,e,xe(e)),Pe(Gn,t)}}function aa(e,t,n){"focusin"===e?(ta(),qn=n,(Wn=t).attachEvent("onpropertychange",na)):"focusout"===e&&ta()}function oa(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Xn(qn)}function sa(e,t){if("click"===e)return Xn(t)}function ra(e,t){if("input"===e||"change"===e)return Xn(t)}var ia="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t};function ca(e,t){if(ia(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),a=Object.keys(t);if(n.length!==a.length)return!1;for(a=0;a<n.length;a++){var o=n[a];if(!l.call(t,o)||!ia(e[o],t[o]))return!1}return!0}function da(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function ua(e,t){var n,a=da(e);for(e=0;a;){if(3===a.nodeType){if(n=e+a.textContent.length,e<=t&&n>=t)return{node:a,offset:t-e};e=n}e:{for(;a;){if(a.nextSibling){a=a.nextSibling;break e}a=a.parentNode}a=void 0}a=da(a)}}function la(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?la(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function pa(){for(var e=window,t=G();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(a){n=!1}if(!n)break;t=G((e=t.contentWindow).document)}return t}function ga(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}function ma(e){var t=pa(),n=e.focusedElem,a=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&la(n.ownerDocument.documentElement,n)){if(null!==a&&ga(n))if(t=a.start,void 0===(e=a.end)&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if((e=(t=n.ownerDocument||document)&&t.defaultView||window).getSelection){e=e.getSelection();var o=n.textContent.length,s=Math.min(a.start,o);a=void 0===a.end?s:Math.min(a.end,o),!e.extend&&s>a&&(o=a,a=s,s=o),o=ua(n,s);var r=ua(n,a);o&&r&&(1!==e.rangeCount||e.anchorNode!==o.node||e.anchorOffset!==o.offset||e.focusNode!==r.node||e.focusOffset!==r.offset)&&((t=t.createRange()).setStart(o.node,o.offset),e.removeAllRanges(),s>a?(e.addRange(t),e.extend(r.node,r.offset)):(t.setEnd(r.node,r.offset),e.addRange(t)))}for(t=[],e=n;e=e.parentNode;)1===e.nodeType&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for("function"==typeof n.focus&&n.focus(),n=0;n<t.length;n++)(e=t[n]).element.scrollLeft=e.left,e.element.scrollTop=e.top}}var fa=u&&"documentMode"in document&&11>=document.documentMode,ha=null,ba=null,ya=null,va=!1;function ka(e,t,n){var a=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;va||null==ha||ha!==G(a)||("selectionStart"in(a=ha)&&ga(a)?a={start:a.selectionStart,end:a.selectionEnd}:a={anchorNode:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset},ya&&ca(ya,a)||(ya=a,0<(a=Wa(ba,"onSelect")).length&&(t=new un("onSelect","select",null,t,n),e.push({event:t,listeners:a}),t.target=ha)))}function xa(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var wa={animationend:xa("Animation","AnimationEnd"),animationiteration:xa("Animation","AnimationIteration"),animationstart:xa("Animation","AnimationStart"),transitionend:xa("Transition","TransitionEnd")},_a={},Sa={};function Ea(e){if(_a[e])return _a[e];if(!wa[e])return e;var t,n=wa[e];for(t in n)if(n.hasOwnProperty(t)&&t in Sa)return _a[e]=n[t];return e}u&&(Sa=document.createElement("div").style,"AnimationEvent"in window||(delete wa.animationend.animation,delete wa.animationiteration.animation,delete wa.animationstart.animation),"TransitionEvent"in window||delete wa.transitionend.transition);var Ca=Ea("animationend"),Ta=Ea("animationiteration"),Aa=Ea("animationstart"),ja=Ea("transitionend"),La=new Map,Pa="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Na(e,t){La.set(e,t),c(t,[e])}for(var Ra=0;Ra<Pa.length;Ra++){var Oa=Pa[Ra];Na(Oa.toLowerCase(),"on"+(Oa[0].toUpperCase()+Oa.slice(1)))}Na(Ca,"onAnimationEnd"),Na(Ta,"onAnimationIteration"),Na(Aa,"onAnimationStart"),Na("dblclick","onDoubleClick"),Na("focusin","onFocus"),Na("focusout","onBlur"),Na(ja,"onTransitionEnd"),d("onMouseEnter",["mouseout","mouseover"]),d("onMouseLeave",["mouseout","mouseover"]),d("onPointerEnter",["pointerout","pointerover"]),d("onPointerLeave",["pointerout","pointerover"]),c("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),c("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),c("onBeforeInput",["compositionend","keypress","textInput","paste"]),c("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Ia="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Fa=new Set("cancel close invalid load scroll toggle".split(" ").concat(Ia));function Da(e,t,n){var a=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,a,o,r,i,c,d){if($e.apply(this,arguments),Fe){if(!Fe)throw Error(s(198));var u=De;Fe=!1,De=null,Me||(Me=!0,ze=u)}}(a,t,void 0,e),e.currentTarget=null}function Ma(e,t){t=!!(4&t);for(var n=0;n<e.length;n++){var a=e[n],o=a.event;a=a.listeners;e:{var s=void 0;if(t)for(var r=a.length-1;0<=r;r--){var i=a[r],c=i.instance,d=i.currentTarget;if(i=i.listener,c!==s&&o.isPropagationStopped())break e;Da(o,i,d),s=c}else for(r=0;r<a.length;r++){if(c=(i=a[r]).instance,d=i.currentTarget,i=i.listener,c!==s&&o.isPropagationStopped())break e;Da(o,i,d),s=c}}}if(Me)throw e=ze,Me=!1,ze=null,e}function za(e,t){var n=t[ho];void 0===n&&(n=t[ho]=new Set);var a=e+"__bubble";n.has(a)||(Qa(t,e,2,!1),n.add(a))}function Ba(e,t,n){var a=0;t&&(a|=4),Qa(n,e,a,t)}var $a="_reactListening"+Math.random().toString(36).slice(2);function Ua(e){if(!e[$a]){e[$a]=!0,r.forEach((function(t){"selectionchange"!==t&&(Fa.has(t)||Ba(t,!1,e),Ba(t,!0,e))}));var t=9===e.nodeType?e:e.ownerDocument;null===t||t[$a]||(t[$a]=!0,Ba("selectionchange",!1,t))}}function Qa(e,t,n,a){switch(Kt(t)){case 1:var o=Ht;break;case 4:o=Wt;break;default:o=qt}n=o.bind(null,t,n,e),o=void 0,!Re||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(o=!0),a?void 0!==o?e.addEventListener(t,n,{capture:!0,passive:o}):e.addEventListener(t,n,!0):void 0!==o?e.addEventListener(t,n,{passive:o}):e.addEventListener(t,n,!1)}function Va(e,t,n,a,o){var s=a;if(!(1&t||2&t||null===a))e:for(;;){if(null===a)return;var r=a.tag;if(3===r||4===r){var i=a.stateNode.containerInfo;if(i===o||8===i.nodeType&&i.parentNode===o)break;if(4===r)for(r=a.return;null!==r;){var c=r.tag;if((3===c||4===c)&&((c=r.stateNode.containerInfo)===o||8===c.nodeType&&c.parentNode===o))return;r=r.return}for(;null!==i;){if(null===(r=vo(i)))return;if(5===(c=r.tag)||6===c){a=s=r;continue e}i=i.parentNode}}a=a.return}Pe((function(){var a=s,o=xe(n),r=[];e:{var i=La.get(e);if(void 0!==i){var c=un,d=e;switch(e){case"keypress":if(0===tn(n))break e;case"keydown":case"keyup":c=Tn;break;case"focusin":d="focus",c=hn;break;case"focusout":d="blur",c=hn;break;case"beforeblur":case"afterblur":c=hn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":c=mn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":c=fn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":c=jn;break;case Ca:case Ta:case Aa:c=bn;break;case ja:c=Ln;break;case"scroll":c=pn;break;case"wheel":c=Nn;break;case"copy":case"cut":case"paste":c=vn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":c=An}var u=!!(4&t),l=!u&&"scroll"===e,p=u?null!==i?i+"Capture":null:i;u=[];for(var g,m=a;null!==m;){var f=(g=m).stateNode;if(5===g.tag&&null!==f&&(g=f,null!==p&&(null!=(f=Ne(m,p))&&u.push(Ha(m,f,g)))),l)break;m=m.return}0<u.length&&(i=new c(i,d,null,n,o),r.push({event:i,listeners:u}))}}if(!(7&t)){if(c="mouseout"===e||"pointerout"===e,(!(i="mouseover"===e||"pointerover"===e)||n===ke||!(d=n.relatedTarget||n.fromElement)||!vo(d)&&!d[fo])&&(c||i)&&(i=o.window===o?o:(i=o.ownerDocument)?i.defaultView||i.parentWindow:window,c?(c=a,null!==(d=(d=n.relatedTarget||n.toElement)?vo(d):null)&&(d!==(l=Ue(d))||5!==d.tag&&6!==d.tag)&&(d=null)):(c=null,d=a),c!==d)){if(u=mn,f="onMouseLeave",p="onMouseEnter",m="mouse","pointerout"!==e&&"pointerover"!==e||(u=An,f="onPointerLeave",p="onPointerEnter",m="pointer"),l=null==c?i:xo(c),g=null==d?i:xo(d),(i=new u(f,m+"leave",c,n,o)).target=l,i.relatedTarget=g,f=null,vo(o)===a&&((u=new u(p,m+"enter",d,n,o)).target=g,u.relatedTarget=l,f=u),l=f,c&&d)e:{for(p=d,m=0,g=u=c;g;g=qa(g))m++;for(g=0,f=p;f;f=qa(f))g++;for(;0<m-g;)u=qa(u),m--;for(;0<g-m;)p=qa(p),g--;for(;m--;){if(u===p||null!==p&&u===p.alternate)break e;u=qa(u),p=qa(p)}u=null}else u=null;null!==c&&Ga(r,i,c,u,!1),null!==d&&null!==l&&Ga(r,l,d,u,!0)}if("select"===(c=(i=a?xo(a):window).nodeName&&i.nodeName.toLowerCase())||"input"===c&&"file"===i.type)var h=Kn;else if(Vn(i))if(Yn)h=ra;else{h=oa;var b=aa}else(c=i.nodeName)&&"input"===c.toLowerCase()&&("checkbox"===i.type||"radio"===i.type)&&(h=sa);switch(h&&(h=h(e,a))?Hn(r,h,n,o):(b&&b(e,i,a),"focusout"===e&&(b=i._wrapperState)&&b.controlled&&"number"===i.type&&ee(i,"number",i.value)),b=a?xo(a):window,e){case"focusin":(Vn(b)||"true"===b.contentEditable)&&(ha=b,ba=a,ya=null);break;case"focusout":ya=ba=ha=null;break;case"mousedown":va=!0;break;case"contextmenu":case"mouseup":case"dragend":va=!1,ka(r,n,o);break;case"selectionchange":if(fa)break;case"keydown":case"keyup":ka(r,n,o)}var y;if(On)e:{switch(e){case"compositionstart":var v="onCompositionStart";break e;case"compositionend":v="onCompositionEnd";break e;case"compositionupdate":v="onCompositionUpdate";break e}v=void 0}else Un?Bn(e,n)&&(v="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(v="onCompositionStart");v&&(Dn&&"ko"!==n.locale&&(Un||"onCompositionStart"!==v?"onCompositionEnd"===v&&Un&&(y=en()):(Zt="value"in(Yt=o)?Yt.value:Yt.textContent,Un=!0)),0<(b=Wa(a,v)).length&&(v=new kn(v,e,null,n,o),r.push({event:v,listeners:b}),y?v.data=y:null!==(y=$n(n))&&(v.data=y))),(y=Fn?function(e,t){switch(e){case"compositionend":return $n(t);case"keypress":return 32!==t.which?null:(zn=!0,Mn);case"textInput":return(e=t.data)===Mn&&zn?null:e;default:return null}}(e,n):function(e,t){if(Un)return"compositionend"===e||!On&&Bn(e,t)?(e=en(),Jt=Zt=Yt=null,Un=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return Dn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(a=Wa(a,"onBeforeInput")).length&&(o=new kn("onBeforeInput","beforeinput",null,n,o),r.push({event:o,listeners:a}),o.data=y))}Ma(r,t)}))}function Ha(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Wa(e,t){for(var n=t+"Capture",a=[];null!==e;){var o=e,s=o.stateNode;5===o.tag&&null!==s&&(o=s,null!=(s=Ne(e,n))&&a.unshift(Ha(e,s,o)),null!=(s=Ne(e,t))&&a.push(Ha(e,s,o))),e=e.return}return a}function qa(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Ga(e,t,n,a,o){for(var s=t._reactName,r=[];null!==n&&n!==a;){var i=n,c=i.alternate,d=i.stateNode;if(null!==c&&c===a)break;5===i.tag&&null!==d&&(i=d,o?null!=(c=Ne(n,s))&&r.unshift(Ha(n,c,i)):o||null!=(c=Ne(n,s))&&r.push(Ha(n,c,i))),n=n.return}0!==r.length&&e.push({event:t,listeners:r})}var Xa=/\r\n?/g,Ka=/\u0000|\uFFFD/g;function Ya(e){return("string"==typeof e?e:""+e).replace(Xa,"\n").replace(Ka,"")}function Za(e,t,n){if(t=Ya(t),Ya(e)!==t&&n)throw Error(s(425))}function Ja(){}var eo=null,to=null;function no(e,t){return"textarea"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var ao="function"==typeof setTimeout?setTimeout:void 0,oo="function"==typeof clearTimeout?clearTimeout:void 0,so="function"==typeof Promise?Promise:void 0,ro="function"==typeof queueMicrotask?queueMicrotask:void 0!==so?function(e){return so.resolve(null).then(e).catch(io)}:ao;function io(e){setTimeout((function(){throw e}))}function co(e,t){var n=t,a=0;do{var o=n.nextSibling;if(e.removeChild(n),o&&8===o.nodeType)if("/$"===(n=o.data)){if(0===a)return e.removeChild(o),void Ut(t);a--}else"$"!==n&&"$?"!==n&&"$!"!==n||a++;n=o}while(n);Ut(t)}function uo(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break;if(8===t){if("$"===(t=e.data)||"$!"===t||"$?"===t)break;if("/$"===t)return null}}return e}function lo(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var po=Math.random().toString(36).slice(2),go="__reactFiber$"+po,mo="__reactProps$"+po,fo="__reactContainer$"+po,ho="__reactEvents$"+po,bo="__reactListeners$"+po,yo="__reactHandles$"+po;function vo(e){var t=e[go];if(t)return t;for(var n=e.parentNode;n;){if(t=n[fo]||n[go]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=lo(e);null!==e;){if(n=e[go])return n;e=lo(e)}return t}n=(e=n).parentNode}return null}function ko(e){return!(e=e[go]||e[fo])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function xo(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(s(33))}function wo(e){return e[mo]||null}var _o=[],So=-1;function Eo(e){return{current:e}}function Co(e){0>So||(e.current=_o[So],_o[So]=null,So--)}function To(e,t){So++,_o[So]=e.current,e.current=t}var Ao={},jo=Eo(Ao),Lo=Eo(!1),Po=Ao;function No(e,t){var n=e.type.contextTypes;if(!n)return Ao;var a=e.stateNode;if(a&&a.__reactInternalMemoizedUnmaskedChildContext===t)return a.__reactInternalMemoizedMaskedChildContext;var o,s={};for(o in n)s[o]=t[o];return a&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=s),s}function Ro(e){return null!=(e=e.childContextTypes)}function Oo(){Co(Lo),Co(jo)}function Io(e,t,n){if(jo.current!==Ao)throw Error(s(168));To(jo,t),To(Lo,n)}function Fo(e,t,n){var a=e.stateNode;if(t=t.childContextTypes,"function"!=typeof a.getChildContext)return n;for(var o in a=a.getChildContext())if(!(o in t))throw Error(s(108,Q(e)||"Unknown",o));return D({},n,a)}function Do(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Ao,Po=jo.current,To(jo,e),To(Lo,Lo.current),!0}function Mo(e,t,n){var a=e.stateNode;if(!a)throw Error(s(169));n?(e=Fo(e,t,Po),a.__reactInternalMemoizedMergedChildContext=e,Co(Lo),Co(jo),To(jo,e)):Co(Lo),To(Lo,n)}var zo=null,Bo=!1,$o=!1;function Uo(e){null===zo?zo=[e]:zo.push(e)}function Qo(){if(!$o&&null!==zo){$o=!0;var e=0,t=vt;try{var n=zo;for(vt=1;e<n.length;e++){var a=n[e];do{a=a(!0)}while(null!==a)}zo=null,Bo=!1}catch(o){throw null!==zo&&(zo=zo.slice(e+1)),qe(Je,Qo),o}finally{vt=t,$o=!1}}return null}var Vo=[],Ho=0,Wo=null,qo=0,Go=[],Xo=0,Ko=null,Yo=1,Zo="";function Jo(e,t){Vo[Ho++]=qo,Vo[Ho++]=Wo,Wo=e,qo=t}function es(e,t,n){Go[Xo++]=Yo,Go[Xo++]=Zo,Go[Xo++]=Ko,Ko=e;var a=Yo;e=Zo;var o=32-rt(a)-1;a&=~(1<<o),n+=1;var s=32-rt(t)+o;if(30<s){var r=o-o%5;s=(a&(1<<r)-1).toString(32),a>>=r,o-=r,Yo=1<<32-rt(t)+o|n<<o|a,Zo=s+e}else Yo=1<<s|n<<o|a,Zo=e}function ts(e){null!==e.return&&(Jo(e,1),es(e,1,0))}function ns(e){for(;e===Wo;)Wo=Vo[--Ho],Vo[Ho]=null,qo=Vo[--Ho],Vo[Ho]=null;for(;e===Ko;)Ko=Go[--Xo],Go[Xo]=null,Zo=Go[--Xo],Go[Xo]=null,Yo=Go[--Xo],Go[Xo]=null}var as=null,os=null,ss=!1,rs=null;function is(e,t){var n=Nd(5,null,null,0);n.elementType="DELETED",n.stateNode=t,n.return=e,null===(t=e.deletions)?(e.deletions=[n],e.flags|=16):t.push(n)}function cs(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,as=e,os=uo(t.firstChild),!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,as=e,os=null,!0);case 13:return null!==(t=8!==t.nodeType?null:t)&&(n=null!==Ko?{id:Yo,overflow:Zo}:null,e.memoizedState={dehydrated:t,treeContext:n,retryLane:1073741824},(n=Nd(18,null,null,0)).stateNode=t,n.return=e,e.child=n,as=e,os=null,!0);default:return!1}}function ds(e){return!(!(1&e.mode)||128&e.flags)}function us(e){if(ss){var t=os;if(t){var n=t;if(!cs(e,t)){if(ds(e))throw Error(s(418));t=uo(n.nextSibling);var a=as;t&&cs(e,t)?is(a,n):(e.flags=-4097&e.flags|2,ss=!1,as=e)}}else{if(ds(e))throw Error(s(418));e.flags=-4097&e.flags|2,ss=!1,as=e}}}function ls(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;as=e}function ps(e){if(e!==as)return!1;if(!ss)return ls(e),ss=!0,!1;var t;if((t=3!==e.tag)&&!(t=5!==e.tag)&&(t="head"!==(t=e.type)&&"body"!==t&&!no(e.type,e.memoizedProps)),t&&(t=os)){if(ds(e))throw gs(),Error(s(418));for(;t;)is(e,t),t=uo(t.nextSibling)}if(ls(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(s(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){os=uo(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}os=null}}else os=as?uo(e.stateNode.nextSibling):null;return!0}function gs(){for(var e=os;e;)e=uo(e.nextSibling)}function ms(){os=as=null,ss=!1}function fs(e){null===rs?rs=[e]:rs.push(e)}var hs=k.ReactCurrentBatchConfig;function bs(e,t){if(e&&e.defaultProps){for(var n in t=D({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}var ys=Eo(null),vs=null,ks=null,xs=null;function ws(){xs=ks=vs=null}function _s(e){var t=ys.current;Co(ys),e._currentValue=t}function Ss(e,t,n){for(;null!==e;){var a=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,null!==a&&(a.childLanes|=t)):null!==a&&(a.childLanes&t)!==t&&(a.childLanes|=t),e===n)break;e=e.return}}function Es(e,t){vs=e,xs=ks=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(!!(e.lanes&t)&&(ki=!0),e.firstContext=null)}function Cs(e){var t=e._currentValue;if(xs!==e)if(e={context:e,memoizedValue:t,next:null},null===ks){if(null===vs)throw Error(s(308));ks=e,vs.dependencies={lanes:0,firstContext:e}}else ks=ks.next=e;return t}var Ts=null;function As(e){null===Ts?Ts=[e]:Ts.push(e)}function js(e,t,n,a){var o=t.interleaved;return null===o?(n.next=n,As(t)):(n.next=o.next,o.next=n),t.interleaved=n,Ls(e,a)}function Ls(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}var Ps=!1;function Ns(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Rs(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Os(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function Is(e,t,n){var a=e.updateQueue;if(null===a)return null;if(a=a.shared,2&jc){var o=a.pending;return null===o?t.next=t:(t.next=o.next,o.next=t),a.pending=t,Ls(e,n)}return null===(o=a.interleaved)?(t.next=t,As(a)):(t.next=o.next,o.next=t),a.interleaved=t,Ls(e,n)}function Fs(e,t,n){if(null!==(t=t.updateQueue)&&(t=t.shared,4194240&n)){var a=t.lanes;n|=a&=e.pendingLanes,t.lanes=n,yt(e,n)}}function Ds(e,t){var n=e.updateQueue,a=e.alternate;if(null!==a&&n===(a=a.updateQueue)){var o=null,s=null;if(null!==(n=n.firstBaseUpdate)){do{var r={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===s?o=s=r:s=s.next=r,n=n.next}while(null!==n);null===s?o=s=t:s=s.next=t}else o=s=t;return n={baseState:a.baseState,firstBaseUpdate:o,lastBaseUpdate:s,shared:a.shared,effects:a.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Ms(e,t,n,a){var o=e.updateQueue;Ps=!1;var s=o.firstBaseUpdate,r=o.lastBaseUpdate,i=o.shared.pending;if(null!==i){o.shared.pending=null;var c=i,d=c.next;c.next=null,null===r?s=d:r.next=d,r=c;var u=e.alternate;null!==u&&((i=(u=u.updateQueue).lastBaseUpdate)!==r&&(null===i?u.firstBaseUpdate=d:i.next=d,u.lastBaseUpdate=c))}if(null!==s){var l=o.baseState;for(r=0,u=d=c=null,i=s;;){var p=i.lane,g=i.eventTime;if((a&p)===p){null!==u&&(u=u.next={eventTime:g,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var m=e,f=i;switch(p=t,g=n,f.tag){case 1:if("function"==typeof(m=f.payload)){l=m.call(g,l,p);break e}l=m;break e;case 3:m.flags=-65537&m.flags|128;case 0:if(null==(p="function"==typeof(m=f.payload)?m.call(g,l,p):m))break e;l=D({},l,p);break e;case 2:Ps=!0}}null!==i.callback&&0!==i.lane&&(e.flags|=64,null===(p=o.effects)?o.effects=[i]:p.push(i))}else g={eventTime:g,lane:p,tag:i.tag,payload:i.payload,callback:i.callback,next:null},null===u?(d=u=g,c=l):u=u.next=g,r|=p;if(null===(i=i.next)){if(null===(i=o.shared.pending))break;i=(p=i).next,p.next=null,o.lastBaseUpdate=p,o.shared.pending=null}}if(null===u&&(c=l),o.baseState=c,o.firstBaseUpdate=d,o.lastBaseUpdate=u,null!==(t=o.shared.interleaved)){o=t;do{r|=o.lane,o=o.next}while(o!==t)}else null===s&&(o.shared.lanes=0);Dc|=r,e.lanes=r,e.memoizedState=l}}function zs(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var a=e[t],o=a.callback;if(null!==o){if(a.callback=null,a=n,"function"!=typeof o)throw Error(s(191,o));o.call(a)}}}var Bs=(new a.Component).refs;function $s(e,t,n,a){n=null==(n=n(a,t=e.memoizedState))?t:D({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var Us={isMounted:function(e){return!!(e=e._reactInternals)&&Ue(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var a=td(),o=nd(e),s=Os(a,o);s.payload=t,null!=n&&(s.callback=n),null!==(t=Is(e,s,o))&&(ad(t,e,o,a),Fs(t,e,o))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var a=td(),o=nd(e),s=Os(a,o);s.tag=1,s.payload=t,null!=n&&(s.callback=n),null!==(t=Is(e,s,o))&&(ad(t,e,o,a),Fs(t,e,o))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=td(),a=nd(e),o=Os(n,a);o.tag=2,null!=t&&(o.callback=t),null!==(t=Is(e,o,a))&&(ad(t,e,a,n),Fs(t,e,a))}};function Qs(e,t,n,a,o,s,r){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(a,s,r):!t.prototype||!t.prototype.isPureReactComponent||(!ca(n,a)||!ca(o,s))}function Vs(e,t,n){var a=!1,o=Ao,s=t.contextType;return"object"==typeof s&&null!==s?s=Cs(s):(o=Ro(t)?Po:jo.current,s=(a=null!=(a=t.contextTypes))?No(e,o):Ao),t=new t(n,s),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=Us,e.stateNode=t,t._reactInternals=e,a&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=o,e.__reactInternalMemoizedMaskedChildContext=s),t}function Hs(e,t,n,a){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,a),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,a),t.state!==e&&Us.enqueueReplaceState(t,t.state,null)}function Ws(e,t,n,a){var o=e.stateNode;o.props=n,o.state=e.memoizedState,o.refs=Bs,Ns(e);var s=t.contextType;"object"==typeof s&&null!==s?o.context=Cs(s):(s=Ro(t)?Po:jo.current,o.context=No(e,s)),o.state=e.memoizedState,"function"==typeof(s=t.getDerivedStateFromProps)&&($s(e,t,s,n),o.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof o.getSnapshotBeforeUpdate||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||(t=o.state,"function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),t!==o.state&&Us.enqueueReplaceState(o,o.state,null),Ms(e,n,o,a),o.state=e.memoizedState),"function"==typeof o.componentDidMount&&(e.flags|=4194308)}function qs(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(s(309));var a=n.stateNode}if(!a)throw Error(s(147,e));var o=a,r=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===r?t.ref:(t=function(e){var t=o.refs;t===Bs&&(t=o.refs={}),null===e?delete t[r]:t[r]=e},t._stringRef=r,t)}if("string"!=typeof e)throw Error(s(284));if(!n._owner)throw Error(s(290,e))}return e}function Gs(e,t){throw e=Object.prototype.toString.call(t),Error(s(31,"[object Object]"===e?"object with keys {"+Object.keys(t).join(", ")+"}":e))}function Xs(e){return(0,e._init)(e._payload)}function Ks(e){function t(t,n){if(e){var a=t.deletions;null===a?(t.deletions=[n],t.flags|=16):a.push(n)}}function n(n,a){if(!e)return null;for(;null!==a;)t(n,a),a=a.sibling;return null}function a(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function o(e,t){return(e=Od(e,t)).index=0,e.sibling=null,e}function r(t,n,a){return t.index=a,e?null!==(a=t.alternate)?(a=a.index)<n?(t.flags|=2,n):a:(t.flags|=2,n):(t.flags|=1048576,n)}function i(t){return e&&null===t.alternate&&(t.flags|=2),t}function c(e,t,n,a){return null===t||6!==t.tag?((t=Md(n,e.mode,a)).return=e,t):((t=o(t,n)).return=e,t)}function d(e,t,n,a){var s=n.type;return s===_?l(e,t,n.props.children,a,n.key):null!==t&&(t.elementType===s||"object"==typeof s&&null!==s&&s.$$typeof===N&&Xs(s)===t.type)?((a=o(t,n.props)).ref=qs(e,t,n),a.return=e,a):((a=Id(n.type,n.key,n.props,null,e.mode,a)).ref=qs(e,t,n),a.return=e,a)}function u(e,t,n,a){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=zd(n,e.mode,a)).return=e,t):((t=o(t,n.children||[])).return=e,t)}function l(e,t,n,a,s){return null===t||7!==t.tag?((t=Fd(n,e.mode,a,s)).return=e,t):((t=o(t,n)).return=e,t)}function p(e,t,n){if("string"==typeof t&&""!==t||"number"==typeof t)return(t=Md(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case x:return(n=Id(t.type,t.key,t.props,null,e.mode,n)).ref=qs(e,null,t),n.return=e,n;case w:return(t=zd(t,e.mode,n)).return=e,t;case N:return p(e,(0,t._init)(t._payload),n)}if(te(t)||I(t))return(t=Fd(t,e.mode,n,null)).return=e,t;Gs(e,t)}return null}function g(e,t,n,a){var o=null!==t?t.key:null;if("string"==typeof n&&""!==n||"number"==typeof n)return null!==o?null:c(e,t,""+n,a);if("object"==typeof n&&null!==n){switch(n.$$typeof){case x:return n.key===o?d(e,t,n,a):null;case w:return n.key===o?u(e,t,n,a):null;case N:return g(e,t,(o=n._init)(n._payload),a)}if(te(n)||I(n))return null!==o?null:l(e,t,n,a,null);Gs(e,n)}return null}function m(e,t,n,a,o){if("string"==typeof a&&""!==a||"number"==typeof a)return c(t,e=e.get(n)||null,""+a,o);if("object"==typeof a&&null!==a){switch(a.$$typeof){case x:return d(t,e=e.get(null===a.key?n:a.key)||null,a,o);case w:return u(t,e=e.get(null===a.key?n:a.key)||null,a,o);case N:return m(e,t,n,(0,a._init)(a._payload),o)}if(te(a)||I(a))return l(t,e=e.get(n)||null,a,o,null);Gs(t,a)}return null}function f(o,s,i,c){for(var d=null,u=null,l=s,f=s=0,h=null;null!==l&&f<i.length;f++){l.index>f?(h=l,l=null):h=l.sibling;var b=g(o,l,i[f],c);if(null===b){null===l&&(l=h);break}e&&l&&null===b.alternate&&t(o,l),s=r(b,s,f),null===u?d=b:u.sibling=b,u=b,l=h}if(f===i.length)return n(o,l),ss&&Jo(o,f),d;if(null===l){for(;f<i.length;f++)null!==(l=p(o,i[f],c))&&(s=r(l,s,f),null===u?d=l:u.sibling=l,u=l);return ss&&Jo(o,f),d}for(l=a(o,l);f<i.length;f++)null!==(h=m(l,o,f,i[f],c))&&(e&&null!==h.alternate&&l.delete(null===h.key?f:h.key),s=r(h,s,f),null===u?d=h:u.sibling=h,u=h);return e&&l.forEach((function(e){return t(o,e)})),ss&&Jo(o,f),d}function h(o,i,c,d){var u=I(c);if("function"!=typeof u)throw Error(s(150));if(null==(c=u.call(c)))throw Error(s(151));for(var l=u=null,f=i,h=i=0,b=null,y=c.next();null!==f&&!y.done;h++,y=c.next()){f.index>h?(b=f,f=null):b=f.sibling;var v=g(o,f,y.value,d);if(null===v){null===f&&(f=b);break}e&&f&&null===v.alternate&&t(o,f),i=r(v,i,h),null===l?u=v:l.sibling=v,l=v,f=b}if(y.done)return n(o,f),ss&&Jo(o,h),u;if(null===f){for(;!y.done;h++,y=c.next())null!==(y=p(o,y.value,d))&&(i=r(y,i,h),null===l?u=y:l.sibling=y,l=y);return ss&&Jo(o,h),u}for(f=a(o,f);!y.done;h++,y=c.next())null!==(y=m(f,o,h,y.value,d))&&(e&&null!==y.alternate&&f.delete(null===y.key?h:y.key),i=r(y,i,h),null===l?u=y:l.sibling=y,l=y);return e&&f.forEach((function(e){return t(o,e)})),ss&&Jo(o,h),u}return function e(a,s,r,c){if("object"==typeof r&&null!==r&&r.type===_&&null===r.key&&(r=r.props.children),"object"==typeof r&&null!==r){switch(r.$$typeof){case x:e:{for(var d=r.key,u=s;null!==u;){if(u.key===d){if((d=r.type)===_){if(7===u.tag){n(a,u.sibling),(s=o(u,r.props.children)).return=a,a=s;break e}}else if(u.elementType===d||"object"==typeof d&&null!==d&&d.$$typeof===N&&Xs(d)===u.type){n(a,u.sibling),(s=o(u,r.props)).ref=qs(a,u,r),s.return=a,a=s;break e}n(a,u);break}t(a,u),u=u.sibling}r.type===_?((s=Fd(r.props.children,a.mode,c,r.key)).return=a,a=s):((c=Id(r.type,r.key,r.props,null,a.mode,c)).ref=qs(a,s,r),c.return=a,a=c)}return i(a);case w:e:{for(u=r.key;null!==s;){if(s.key===u){if(4===s.tag&&s.stateNode.containerInfo===r.containerInfo&&s.stateNode.implementation===r.implementation){n(a,s.sibling),(s=o(s,r.children||[])).return=a,a=s;break e}n(a,s);break}t(a,s),s=s.sibling}(s=zd(r,a.mode,c)).return=a,a=s}return i(a);case N:return e(a,s,(u=r._init)(r._payload),c)}if(te(r))return f(a,s,r,c);if(I(r))return h(a,s,r,c);Gs(a,r)}return"string"==typeof r&&""!==r||"number"==typeof r?(r=""+r,null!==s&&6===s.tag?(n(a,s.sibling),(s=o(s,r)).return=a,a=s):(n(a,s),(s=Md(r,a.mode,c)).return=a,a=s),i(a)):n(a,s)}}var Ys=Ks(!0),Zs=Ks(!1),Js={},er=Eo(Js),tr=Eo(Js),nr=Eo(Js);function ar(e){if(e===Js)throw Error(s(174));return e}function or(e,t){switch(To(nr,t),To(tr,e),To(er,Js),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:ce(null,"");break;default:t=ce(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}Co(er),To(er,t)}function sr(){Co(er),Co(tr),Co(nr)}function rr(e){ar(nr.current);var t=ar(er.current),n=ce(t,e.type);t!==n&&(To(tr,e),To(er,n))}function ir(e){tr.current===e&&(Co(er),Co(tr))}var cr=Eo(0);function dr(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(128&t.flags)return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var ur=[];function lr(){for(var e=0;e<ur.length;e++)ur[e]._workInProgressVersionPrimary=null;ur.length=0}var pr=k.ReactCurrentDispatcher,gr=k.ReactCurrentBatchConfig,mr=0,fr=null,hr=null,br=null,yr=!1,vr=!1,kr=0,xr=0;function wr(){throw Error(s(321))}function _r(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!ia(e[n],t[n]))return!1;return!0}function Sr(e,t,n,a,o,r){if(mr=r,fr=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,pr.current=null===e||null===e.memoizedState?ii:ci,e=n(a,o),vr){r=0;do{if(vr=!1,kr=0,25<=r)throw Error(s(301));r+=1,br=hr=null,t.updateQueue=null,pr.current=di,e=n(a,o)}while(vr)}if(pr.current=ri,t=null!==hr&&null!==hr.next,mr=0,br=hr=fr=null,yr=!1,t)throw Error(s(300));return e}function Er(){var e=0!==kr;return kr=0,e}function Cr(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===br?fr.memoizedState=br=e:br=br.next=e,br}function Tr(){if(null===hr){var e=fr.alternate;e=null!==e?e.memoizedState:null}else e=hr.next;var t=null===br?fr.memoizedState:br.next;if(null!==t)br=t,hr=e;else{if(null===e)throw Error(s(310));e={memoizedState:(hr=e).memoizedState,baseState:hr.baseState,baseQueue:hr.baseQueue,queue:hr.queue,next:null},null===br?fr.memoizedState=br=e:br=br.next=e}return br}function Ar(e,t){return"function"==typeof t?t(e):t}function jr(e){var t=Tr(),n=t.queue;if(null===n)throw Error(s(311));n.lastRenderedReducer=e;var a=hr,o=a.baseQueue,r=n.pending;if(null!==r){if(null!==o){var i=o.next;o.next=r.next,r.next=i}a.baseQueue=o=r,n.pending=null}if(null!==o){r=o.next,a=a.baseState;var c=i=null,d=null,u=r;do{var l=u.lane;if((mr&l)===l)null!==d&&(d=d.next={lane:0,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null}),a=u.hasEagerState?u.eagerState:e(a,u.action);else{var p={lane:l,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null};null===d?(c=d=p,i=a):d=d.next=p,fr.lanes|=l,Dc|=l}u=u.next}while(null!==u&&u!==r);null===d?i=a:d.next=c,ia(a,t.memoizedState)||(ki=!0),t.memoizedState=a,t.baseState=i,t.baseQueue=d,n.lastRenderedState=a}if(null!==(e=n.interleaved)){o=e;do{r=o.lane,fr.lanes|=r,Dc|=r,o=o.next}while(o!==e)}else null===o&&(n.lanes=0);return[t.memoizedState,n.dispatch]}function Lr(e){var t=Tr(),n=t.queue;if(null===n)throw Error(s(311));n.lastRenderedReducer=e;var a=n.dispatch,o=n.pending,r=t.memoizedState;if(null!==o){n.pending=null;var i=o=o.next;do{r=e(r,i.action),i=i.next}while(i!==o);ia(r,t.memoizedState)||(ki=!0),t.memoizedState=r,null===t.baseQueue&&(t.baseState=r),n.lastRenderedState=r}return[r,a]}function Pr(){}function Nr(e,t){var n=fr,a=Tr(),o=t(),r=!ia(a.memoizedState,o);if(r&&(a.memoizedState=o,ki=!0),a=a.queue,Vr(Ir.bind(null,n,a,e),[e]),a.getSnapshot!==t||r||null!==br&&1&br.memoizedState.tag){if(n.flags|=2048,zr(9,Or.bind(null,n,a,o,t),void 0,null),null===Lc)throw Error(s(349));30&mr||Rr(n,t,o)}return o}function Rr(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},null===(t=fr.updateQueue)?(t={lastEffect:null,stores:null},fr.updateQueue=t,t.stores=[e]):null===(n=t.stores)?t.stores=[e]:n.push(e)}function Or(e,t,n,a){t.value=n,t.getSnapshot=a,Fr(t)&&Dr(e)}function Ir(e,t,n){return n((function(){Fr(t)&&Dr(e)}))}function Fr(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!ia(e,n)}catch(a){return!0}}function Dr(e){var t=Ls(e,1);null!==t&&ad(t,e,1,-1)}function Mr(e){var t=Cr();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:Ar,lastRenderedState:e},t.queue=e,e=e.dispatch=ni.bind(null,fr,e),[t.memoizedState,e]}function zr(e,t,n,a){return e={tag:e,create:t,destroy:n,deps:a,next:null},null===(t=fr.updateQueue)?(t={lastEffect:null,stores:null},fr.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(a=n.next,n.next=e,e.next=a,t.lastEffect=e),e}function Br(){return Tr().memoizedState}function $r(e,t,n,a){var o=Cr();fr.flags|=e,o.memoizedState=zr(1|t,n,void 0,void 0===a?null:a)}function Ur(e,t,n,a){var o=Tr();a=void 0===a?null:a;var s=void 0;if(null!==hr){var r=hr.memoizedState;if(s=r.destroy,null!==a&&_r(a,r.deps))return void(o.memoizedState=zr(t,n,s,a))}fr.flags|=e,o.memoizedState=zr(1|t,n,s,a)}function Qr(e,t){return $r(8390656,8,e,t)}function Vr(e,t){return Ur(2048,8,e,t)}function Hr(e,t){return Ur(4,2,e,t)}function Wr(e,t){return Ur(4,4,e,t)}function qr(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function Gr(e,t,n){return n=null!=n?n.concat([e]):null,Ur(4,4,qr.bind(null,t,e),n)}function Xr(){}function Kr(e,t){var n=Tr();t=void 0===t?null:t;var a=n.memoizedState;return null!==a&&null!==t&&_r(t,a[1])?a[0]:(n.memoizedState=[e,t],e)}function Yr(e,t){var n=Tr();t=void 0===t?null:t;var a=n.memoizedState;return null!==a&&null!==t&&_r(t,a[1])?a[0]:(e=e(),n.memoizedState=[e,t],e)}function Zr(e,t,n){return 21&mr?(ia(n,t)||(n=ft(),fr.lanes|=n,Dc|=n,e.baseState=!0),t):(e.baseState&&(e.baseState=!1,ki=!0),e.memoizedState=n)}function Jr(e,t){var n=vt;vt=0!==n&&4>n?n:4,e(!0);var a=gr.transition;gr.transition={};try{e(!1),t()}finally{vt=n,gr.transition=a}}function ei(){return Tr().memoizedState}function ti(e,t,n){var a=nd(e);if(n={lane:a,action:n,hasEagerState:!1,eagerState:null,next:null},ai(e))oi(t,n);else if(null!==(n=js(e,t,n,a))){ad(n,e,a,td()),si(n,t,a)}}function ni(e,t,n){var a=nd(e),o={lane:a,action:n,hasEagerState:!1,eagerState:null,next:null};if(ai(e))oi(t,o);else{var s=e.alternate;if(0===e.lanes&&(null===s||0===s.lanes)&&null!==(s=t.lastRenderedReducer))try{var r=t.lastRenderedState,i=s(r,n);if(o.hasEagerState=!0,o.eagerState=i,ia(i,r)){var c=t.interleaved;return null===c?(o.next=o,As(t)):(o.next=c.next,c.next=o),void(t.interleaved=o)}}catch(d){}null!==(n=js(e,t,o,a))&&(ad(n,e,a,o=td()),si(n,t,a))}}function ai(e){var t=e.alternate;return e===fr||null!==t&&t===fr}function oi(e,t){vr=yr=!0;var n=e.pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function si(e,t,n){if(4194240&n){var a=t.lanes;n|=a&=e.pendingLanes,t.lanes=n,yt(e,n)}}var ri={readContext:Cs,useCallback:wr,useContext:wr,useEffect:wr,useImperativeHandle:wr,useInsertionEffect:wr,useLayoutEffect:wr,useMemo:wr,useReducer:wr,useRef:wr,useState:wr,useDebugValue:wr,useDeferredValue:wr,useTransition:wr,useMutableSource:wr,useSyncExternalStore:wr,useId:wr,unstable_isNewReconciler:!1},ii={readContext:Cs,useCallback:function(e,t){return Cr().memoizedState=[e,void 0===t?null:t],e},useContext:Cs,useEffect:Qr,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,$r(4194308,4,qr.bind(null,t,e),n)},useLayoutEffect:function(e,t){return $r(4194308,4,e,t)},useInsertionEffect:function(e,t){return $r(4,2,e,t)},useMemo:function(e,t){var n=Cr();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var a=Cr();return t=void 0!==n?n(t):t,a.memoizedState=a.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},a.queue=e,e=e.dispatch=ti.bind(null,fr,e),[a.memoizedState,e]},useRef:function(e){return e={current:e},Cr().memoizedState=e},useState:Mr,useDebugValue:Xr,useDeferredValue:function(e){return Cr().memoizedState=e},useTransition:function(){var e=Mr(!1),t=e[0];return e=Jr.bind(null,e[1]),Cr().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var a=fr,o=Cr();if(ss){if(void 0===n)throw Error(s(407));n=n()}else{if(n=t(),null===Lc)throw Error(s(349));30&mr||Rr(a,t,n)}o.memoizedState=n;var r={value:n,getSnapshot:t};return o.queue=r,Qr(Ir.bind(null,a,r,e),[e]),a.flags|=2048,zr(9,Or.bind(null,a,r,n,t),void 0,null),n},useId:function(){var e=Cr(),t=Lc.identifierPrefix;if(ss){var n=Zo;t=":"+t+"R"+(n=(Yo&~(1<<32-rt(Yo)-1)).toString(32)+n),0<(n=kr++)&&(t+="H"+n.toString(32)),t+=":"}else t=":"+t+"r"+(n=xr++).toString(32)+":";return e.memoizedState=t},unstable_isNewReconciler:!1},ci={readContext:Cs,useCallback:Kr,useContext:Cs,useEffect:Vr,useImperativeHandle:Gr,useInsertionEffect:Hr,useLayoutEffect:Wr,useMemo:Yr,useReducer:jr,useRef:Br,useState:function(){return jr(Ar)},useDebugValue:Xr,useDeferredValue:function(e){return Zr(Tr(),hr.memoizedState,e)},useTransition:function(){return[jr(Ar)[0],Tr().memoizedState]},useMutableSource:Pr,useSyncExternalStore:Nr,useId:ei,unstable_isNewReconciler:!1},di={readContext:Cs,useCallback:Kr,useContext:Cs,useEffect:Vr,useImperativeHandle:Gr,useInsertionEffect:Hr,useLayoutEffect:Wr,useMemo:Yr,useReducer:Lr,useRef:Br,useState:function(){return Lr(Ar)},useDebugValue:Xr,useDeferredValue:function(e){var t=Tr();return null===hr?t.memoizedState=e:Zr(t,hr.memoizedState,e)},useTransition:function(){return[Lr(Ar)[0],Tr().memoizedState]},useMutableSource:Pr,useSyncExternalStore:Nr,useId:ei,unstable_isNewReconciler:!1};function ui(e,t){try{var n="",a=t;do{n+=$(a),a=a.return}while(a);var o=n}catch(s){o="\nError generating stack: "+s.message+"\n"+s.stack}return{value:e,source:t,stack:o,digest:null}}function li(e,t,n){return{value:e,source:null,stack:null!=n?n:null,digest:null!=t?t:null}}function pi(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}var gi="function"==typeof WeakMap?WeakMap:Map;function mi(e,t,n){(n=Os(-1,n)).tag=3,n.payload={element:null};var a=t.value;return n.callback=function(){Hc||(Hc=!0,Wc=a),pi(0,t)},n}function fi(e,t,n){(n=Os(-1,n)).tag=3;var a=e.type.getDerivedStateFromError;if("function"==typeof a){var o=t.value;n.payload=function(){return a(o)},n.callback=function(){pi(0,t)}}var s=e.stateNode;return null!==s&&"function"==typeof s.componentDidCatch&&(n.callback=function(){pi(0,t),"function"!=typeof a&&(null===qc?qc=new Set([this]):qc.add(this));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}function hi(e,t,n){var a=e.pingCache;if(null===a){a=e.pingCache=new gi;var o=new Set;a.set(t,o)}else void 0===(o=a.get(t))&&(o=new Set,a.set(t,o));o.has(n)||(o.add(n),e=Cd.bind(null,e,t,n),t.then(e,e))}function bi(e){do{var t;if((t=13===e.tag)&&(t=null===(t=e.memoizedState)||null!==t.dehydrated),t)return e;e=e.return}while(null!==e);return null}function yi(e,t,n,a,o){return 1&e.mode?(e.flags|=65536,e.lanes=o,e):(e===t?e.flags|=65536:(e.flags|=128,n.flags|=131072,n.flags&=-52805,1===n.tag&&(null===n.alternate?n.tag=17:((t=Os(-1,1)).tag=2,Is(n,t,1))),n.lanes|=1),e)}var vi=k.ReactCurrentOwner,ki=!1;function xi(e,t,n,a){t.child=null===e?Zs(t,null,n,a):Ys(t,e.child,n,a)}function wi(e,t,n,a,o){n=n.render;var s=t.ref;return Es(t,o),a=Sr(e,t,n,a,s,o),n=Er(),null===e||ki?(ss&&n&&ts(t),t.flags|=1,xi(e,t,a,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,Hi(e,t,o))}function _i(e,t,n,a,o){if(null===e){var s=n.type;return"function"!=typeof s||Rd(s)||void 0!==s.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Id(n.type,null,a,t,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=s,Si(e,t,s,a,o))}if(s=e.child,!(e.lanes&o)){var r=s.memoizedProps;if((n=null!==(n=n.compare)?n:ca)(r,a)&&e.ref===t.ref)return Hi(e,t,o)}return t.flags|=1,(e=Od(s,a)).ref=t.ref,e.return=t,t.child=e}function Si(e,t,n,a,o){if(null!==e){var s=e.memoizedProps;if(ca(s,a)&&e.ref===t.ref){if(ki=!1,t.pendingProps=a=s,!(e.lanes&o))return t.lanes=e.lanes,Hi(e,t,o);131072&e.flags&&(ki=!0)}}return Ti(e,t,n,a,o)}function Ei(e,t,n){var a=t.pendingProps,o=a.children,s=null!==e?e.memoizedState:null;if("hidden"===a.mode)if(1&t.mode){if(!(1073741824&n))return e=null!==s?s.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,To(Oc,Rc),Rc|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},a=null!==s?s.baseLanes:n,To(Oc,Rc),Rc|=a}else t.memoizedState={baseLanes:0,cachePool:null,transitions:null},To(Oc,Rc),Rc|=n;else null!==s?(a=s.baseLanes|n,t.memoizedState=null):a=n,To(Oc,Rc),Rc|=a;return xi(e,t,o,n),t.child}function Ci(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function Ti(e,t,n,a,o){var s=Ro(n)?Po:jo.current;return s=No(t,s),Es(t,o),n=Sr(e,t,n,a,s,o),a=Er(),null===e||ki?(ss&&a&&ts(t),t.flags|=1,xi(e,t,n,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,Hi(e,t,o))}function Ai(e,t,n,a,o){if(Ro(n)){var s=!0;Do(t)}else s=!1;if(Es(t,o),null===t.stateNode)Vi(e,t),Vs(t,n,a),Ws(t,n,a,o),a=!0;else if(null===e){var r=t.stateNode,i=t.memoizedProps;r.props=i;var c=r.context,d=n.contextType;"object"==typeof d&&null!==d?d=Cs(d):d=No(t,d=Ro(n)?Po:jo.current);var u=n.getDerivedStateFromProps,l="function"==typeof u||"function"==typeof r.getSnapshotBeforeUpdate;l||"function"!=typeof r.UNSAFE_componentWillReceiveProps&&"function"!=typeof r.componentWillReceiveProps||(i!==a||c!==d)&&Hs(t,r,a,d),Ps=!1;var p=t.memoizedState;r.state=p,Ms(t,a,r,o),c=t.memoizedState,i!==a||p!==c||Lo.current||Ps?("function"==typeof u&&($s(t,n,u,a),c=t.memoizedState),(i=Ps||Qs(t,n,i,a,p,c,d))?(l||"function"!=typeof r.UNSAFE_componentWillMount&&"function"!=typeof r.componentWillMount||("function"==typeof r.componentWillMount&&r.componentWillMount(),"function"==typeof r.UNSAFE_componentWillMount&&r.UNSAFE_componentWillMount()),"function"==typeof r.componentDidMount&&(t.flags|=4194308)):("function"==typeof r.componentDidMount&&(t.flags|=4194308),t.memoizedProps=a,t.memoizedState=c),r.props=a,r.state=c,r.context=d,a=i):("function"==typeof r.componentDidMount&&(t.flags|=4194308),a=!1)}else{r=t.stateNode,Rs(e,t),i=t.memoizedProps,d=t.type===t.elementType?i:bs(t.type,i),r.props=d,l=t.pendingProps,p=r.context,"object"==typeof(c=n.contextType)&&null!==c?c=Cs(c):c=No(t,c=Ro(n)?Po:jo.current);var g=n.getDerivedStateFromProps;(u="function"==typeof g||"function"==typeof r.getSnapshotBeforeUpdate)||"function"!=typeof r.UNSAFE_componentWillReceiveProps&&"function"!=typeof r.componentWillReceiveProps||(i!==l||p!==c)&&Hs(t,r,a,c),Ps=!1,p=t.memoizedState,r.state=p,Ms(t,a,r,o);var m=t.memoizedState;i!==l||p!==m||Lo.current||Ps?("function"==typeof g&&($s(t,n,g,a),m=t.memoizedState),(d=Ps||Qs(t,n,d,a,p,m,c)||!1)?(u||"function"!=typeof r.UNSAFE_componentWillUpdate&&"function"!=typeof r.componentWillUpdate||("function"==typeof r.componentWillUpdate&&r.componentWillUpdate(a,m,c),"function"==typeof r.UNSAFE_componentWillUpdate&&r.UNSAFE_componentWillUpdate(a,m,c)),"function"==typeof r.componentDidUpdate&&(t.flags|=4),"function"==typeof r.getSnapshotBeforeUpdate&&(t.flags|=1024)):("function"!=typeof r.componentDidUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof r.getSnapshotBeforeUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),t.memoizedProps=a,t.memoizedState=m),r.props=a,r.state=m,r.context=c,a=d):("function"!=typeof r.componentDidUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof r.getSnapshotBeforeUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),a=!1)}return ji(e,t,n,a,s,o)}function ji(e,t,n,a,o,s){Ci(e,t);var r=!!(128&t.flags);if(!a&&!r)return o&&Mo(t,n,!1),Hi(e,t,s);a=t.stateNode,vi.current=t;var i=r&&"function"!=typeof n.getDerivedStateFromError?null:a.render();return t.flags|=1,null!==e&&r?(t.child=Ys(t,e.child,null,s),t.child=Ys(t,null,i,s)):xi(e,t,i,s),t.memoizedState=a.state,o&&Mo(t,n,!0),t.child}function Li(e){var t=e.stateNode;t.pendingContext?Io(0,t.pendingContext,t.pendingContext!==t.context):t.context&&Io(0,t.context,!1),or(e,t.containerInfo)}function Pi(e,t,n,a,o){return ms(),fs(o),t.flags|=256,xi(e,t,n,a),t.child}var Ni,Ri,Oi,Ii,Fi={dehydrated:null,treeContext:null,retryLane:0};function Di(e){return{baseLanes:e,cachePool:null,transitions:null}}function Mi(e,t,n){var a,o=t.pendingProps,r=cr.current,i=!1,c=!!(128&t.flags);if((a=c)||(a=(null===e||null!==e.memoizedState)&&!!(2&r)),a?(i=!0,t.flags&=-129):null!==e&&null===e.memoizedState||(r|=1),To(cr,1&r),null===e)return us(t),null!==(e=t.memoizedState)&&null!==(e=e.dehydrated)?(1&t.mode?"$!"===e.data?t.lanes=8:t.lanes=1073741824:t.lanes=1,null):(c=o.children,e=o.fallback,i?(o=t.mode,i=t.child,c={mode:"hidden",children:c},1&o||null===i?i=Dd(c,o,0,null):(i.childLanes=0,i.pendingProps=c),e=Fd(e,o,n,null),i.return=t,e.return=t,i.sibling=e,t.child=i,t.child.memoizedState=Di(n),t.memoizedState=Fi,e):zi(t,c));if(null!==(r=e.memoizedState)&&null!==(a=r.dehydrated))return function(e,t,n,a,o,r,i){if(n)return 256&t.flags?(t.flags&=-257,Bi(e,t,i,a=li(Error(s(422))))):null!==t.memoizedState?(t.child=e.child,t.flags|=128,null):(r=a.fallback,o=t.mode,a=Dd({mode:"visible",children:a.children},o,0,null),(r=Fd(r,o,i,null)).flags|=2,a.return=t,r.return=t,a.sibling=r,t.child=a,1&t.mode&&Ys(t,e.child,null,i),t.child.memoizedState=Di(i),t.memoizedState=Fi,r);if(!(1&t.mode))return Bi(e,t,i,null);if("$!"===o.data){if(a=o.nextSibling&&o.nextSibling.dataset)var c=a.dgst;return a=c,Bi(e,t,i,a=li(r=Error(s(419)),a,void 0))}if(c=!!(i&e.childLanes),ki||c){if(null!==(a=Lc)){switch(i&-i){case 4:o=2;break;case 16:o=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:o=32;break;case 536870912:o=268435456;break;default:o=0}0!==(o=o&(a.suspendedLanes|i)?0:o)&&o!==r.retryLane&&(r.retryLane=o,Ls(e,o),ad(a,e,o,-1))}return hd(),Bi(e,t,i,a=li(Error(s(421))))}return"$?"===o.data?(t.flags|=128,t.child=e.child,t=Ad.bind(null,e),o._reactRetry=t,null):(e=r.treeContext,os=uo(o.nextSibling),as=t,ss=!0,rs=null,null!==e&&(Go[Xo++]=Yo,Go[Xo++]=Zo,Go[Xo++]=Ko,Yo=e.id,Zo=e.overflow,Ko=t),t=zi(t,a.children),t.flags|=4096,t)}(e,t,c,o,a,r,n);if(i){i=o.fallback,c=t.mode,a=(r=e.child).sibling;var d={mode:"hidden",children:o.children};return 1&c||t.child===r?(o=Od(r,d)).subtreeFlags=14680064&r.subtreeFlags:((o=t.child).childLanes=0,o.pendingProps=d,t.deletions=null),null!==a?i=Od(a,i):(i=Fd(i,c,n,null)).flags|=2,i.return=t,o.return=t,o.sibling=i,t.child=o,o=i,i=t.child,c=null===(c=e.child.memoizedState)?Di(n):{baseLanes:c.baseLanes|n,cachePool:null,transitions:c.transitions},i.memoizedState=c,i.childLanes=e.childLanes&~n,t.memoizedState=Fi,o}return e=(i=e.child).sibling,o=Od(i,{mode:"visible",children:o.children}),!(1&t.mode)&&(o.lanes=n),o.return=t,o.sibling=null,null!==e&&(null===(n=t.deletions)?(t.deletions=[e],t.flags|=16):n.push(e)),t.child=o,t.memoizedState=null,o}function zi(e,t){return(t=Dd({mode:"visible",children:t},e.mode,0,null)).return=e,e.child=t}function Bi(e,t,n,a){return null!==a&&fs(a),Ys(t,e.child,null,n),(e=zi(t,t.pendingProps.children)).flags|=2,t.memoizedState=null,e}function $i(e,t,n){e.lanes|=t;var a=e.alternate;null!==a&&(a.lanes|=t),Ss(e.return,t,n)}function Ui(e,t,n,a,o){var s=e.memoizedState;null===s?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:a,tail:n,tailMode:o}:(s.isBackwards=t,s.rendering=null,s.renderingStartTime=0,s.last=a,s.tail=n,s.tailMode=o)}function Qi(e,t,n){var a=t.pendingProps,o=a.revealOrder,s=a.tail;if(xi(e,t,a.children,n),2&(a=cr.current))a=1&a|2,t.flags|=128;else{if(null!==e&&128&e.flags)e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&$i(e,n,t);else if(19===e.tag)$i(e,n,t);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}a&=1}if(To(cr,a),1&t.mode)switch(o){case"forwards":for(n=t.child,o=null;null!==n;)null!==(e=n.alternate)&&null===dr(e)&&(o=n),n=n.sibling;null===(n=o)?(o=t.child,t.child=null):(o=n.sibling,n.sibling=null),Ui(t,!1,o,n,s);break;case"backwards":for(n=null,o=t.child,t.child=null;null!==o;){if(null!==(e=o.alternate)&&null===dr(e)){t.child=o;break}e=o.sibling,o.sibling=n,n=o,o=e}Ui(t,!0,n,null,s);break;case"together":Ui(t,!1,null,null,void 0);break;default:t.memoizedState=null}else t.memoizedState=null;return t.child}function Vi(e,t){!(1&t.mode)&&null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2)}function Hi(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Dc|=t.lanes,!(n&t.childLanes))return null;if(null!==e&&t.child!==e.child)throw Error(s(153));if(null!==t.child){for(n=Od(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Od(e,e.pendingProps)).return=t;n.sibling=null}return t.child}function Wi(e,t){if(!ss)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var a=null;null!==n;)null!==n.alternate&&(a=n),n=n.sibling;null===a?t||null===e.tail?e.tail=null:e.tail.sibling=null:a.sibling=null}}function qi(e){var t=null!==e.alternate&&e.alternate.child===e.child,n=0,a=0;if(t)for(var o=e.child;null!==o;)n|=o.lanes|o.childLanes,a|=14680064&o.subtreeFlags,a|=14680064&o.flags,o.return=e,o=o.sibling;else for(o=e.child;null!==o;)n|=o.lanes|o.childLanes,a|=o.subtreeFlags,a|=o.flags,o.return=e,o=o.sibling;return e.subtreeFlags|=a,e.childLanes=n,t}function Gi(e,t,n){var a=t.pendingProps;switch(ns(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return qi(t),null;case 1:case 17:return Ro(t.type)&&Oo(),qi(t),null;case 3:return a=t.stateNode,sr(),Co(Lo),Co(jo),lr(),a.pendingContext&&(a.context=a.pendingContext,a.pendingContext=null),null!==e&&null!==e.child||(ps(t)?t.flags|=4:null===e||e.memoizedState.isDehydrated&&!(256&t.flags)||(t.flags|=1024,null!==rs&&(id(rs),rs=null))),Ri(e,t),qi(t),null;case 5:ir(t);var o=ar(nr.current);if(n=t.type,null!==e&&null!=t.stateNode)Oi(e,t,n,a,o),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!a){if(null===t.stateNode)throw Error(s(166));return qi(t),null}if(e=ar(er.current),ps(t)){a=t.stateNode,n=t.type;var r=t.memoizedProps;switch(a[go]=t,a[mo]=r,e=!!(1&t.mode),n){case"dialog":za("cancel",a),za("close",a);break;case"iframe":case"object":case"embed":za("load",a);break;case"video":case"audio":for(o=0;o<Ia.length;o++)za(Ia[o],a);break;case"source":za("error",a);break;case"img":case"image":case"link":za("error",a),za("load",a);break;case"details":za("toggle",a);break;case"input":K(a,r),za("invalid",a);break;case"select":a._wrapperState={wasMultiple:!!r.multiple},za("invalid",a);break;case"textarea":oe(a,r),za("invalid",a)}for(var c in ye(n,r),o=null,r)if(r.hasOwnProperty(c)){var d=r[c];"children"===c?"string"==typeof d?a.textContent!==d&&(!0!==r.suppressHydrationWarning&&Za(a.textContent,d,e),o=["children",d]):"number"==typeof d&&a.textContent!==""+d&&(!0!==r.suppressHydrationWarning&&Za(a.textContent,d,e),o=["children",""+d]):i.hasOwnProperty(c)&&null!=d&&"onScroll"===c&&za("scroll",a)}switch(n){case"input":W(a),J(a,r,!0);break;case"textarea":W(a),re(a);break;case"select":case"option":break;default:"function"==typeof r.onClick&&(a.onclick=Ja)}a=o,t.updateQueue=a,null!==a&&(t.flags|=4)}else{c=9===o.nodeType?o:o.ownerDocument,"http://www.w3.org/1999/xhtml"===e&&(e=ie(n)),"http://www.w3.org/1999/xhtml"===e?"script"===n?((e=c.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof a.is?e=c.createElement(n,{is:a.is}):(e=c.createElement(n),"select"===n&&(c=e,a.multiple?c.multiple=!0:a.size&&(c.size=a.size))):e=c.createElementNS(e,n),e[go]=t,e[mo]=a,Ni(e,t,!1,!1),t.stateNode=e;e:{switch(c=ve(n,a),n){case"dialog":za("cancel",e),za("close",e),o=a;break;case"iframe":case"object":case"embed":za("load",e),o=a;break;case"video":case"audio":for(o=0;o<Ia.length;o++)za(Ia[o],e);o=a;break;case"source":za("error",e),o=a;break;case"img":case"image":case"link":za("error",e),za("load",e),o=a;break;case"details":za("toggle",e),o=a;break;case"input":K(e,a),o=X(e,a),za("invalid",e);break;case"option":default:o=a;break;case"select":e._wrapperState={wasMultiple:!!a.multiple},o=D({},a,{value:void 0}),za("invalid",e);break;case"textarea":oe(e,a),o=ae(e,a),za("invalid",e)}for(r in ye(n,o),d=o)if(d.hasOwnProperty(r)){var u=d[r];"style"===r?he(e,u):"dangerouslySetInnerHTML"===r?null!=(u=u?u.__html:void 0)&&le(e,u):"children"===r?"string"==typeof u?("textarea"!==n||""!==u)&&pe(e,u):"number"==typeof u&&pe(e,""+u):"suppressContentEditableWarning"!==r&&"suppressHydrationWarning"!==r&&"autoFocus"!==r&&(i.hasOwnProperty(r)?null!=u&&"onScroll"===r&&za("scroll",e):null!=u&&v(e,r,u,c))}switch(n){case"input":W(e),J(e,a,!1);break;case"textarea":W(e),re(e);break;case"option":null!=a.value&&e.setAttribute("value",""+V(a.value));break;case"select":e.multiple=!!a.multiple,null!=(r=a.value)?ne(e,!!a.multiple,r,!1):null!=a.defaultValue&&ne(e,!!a.multiple,a.defaultValue,!0);break;default:"function"==typeof o.onClick&&(e.onclick=Ja)}switch(n){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break e;case"img":a=!0;break e;default:a=!1}}a&&(t.flags|=4)}null!==t.ref&&(t.flags|=512,t.flags|=2097152)}return qi(t),null;case 6:if(e&&null!=t.stateNode)Ii(e,t,e.memoizedProps,a);else{if("string"!=typeof a&&null===t.stateNode)throw Error(s(166));if(n=ar(nr.current),ar(er.current),ps(t)){if(a=t.stateNode,n=t.memoizedProps,a[go]=t,(r=a.nodeValue!==n)&&null!==(e=as))switch(e.tag){case 3:Za(a.nodeValue,n,!!(1&e.mode));break;case 5:!0!==e.memoizedProps.suppressHydrationWarning&&Za(a.nodeValue,n,!!(1&e.mode))}r&&(t.flags|=4)}else(a=(9===n.nodeType?n:n.ownerDocument).createTextNode(a))[go]=t,t.stateNode=a}return qi(t),null;case 13:if(Co(cr),a=t.memoizedState,null===e||null!==e.memoizedState&&null!==e.memoizedState.dehydrated){if(ss&&null!==os&&1&t.mode&&!(128&t.flags))gs(),ms(),t.flags|=98560,r=!1;else if(r=ps(t),null!==a&&null!==a.dehydrated){if(null===e){if(!r)throw Error(s(318));if(!(r=null!==(r=t.memoizedState)?r.dehydrated:null))throw Error(s(317));r[go]=t}else ms(),!(128&t.flags)&&(t.memoizedState=null),t.flags|=4;qi(t),r=!1}else null!==rs&&(id(rs),rs=null),r=!0;if(!r)return 65536&t.flags?t:null}return 128&t.flags?(t.lanes=n,t):((a=null!==a)!==(null!==e&&null!==e.memoizedState)&&a&&(t.child.flags|=8192,1&t.mode&&(null===e||1&cr.current?0===Ic&&(Ic=3):hd())),null!==t.updateQueue&&(t.flags|=4),qi(t),null);case 4:return sr(),Ri(e,t),null===e&&Ua(t.stateNode.containerInfo),qi(t),null;case 10:return _s(t.type._context),qi(t),null;case 19:if(Co(cr),null===(r=t.memoizedState))return qi(t),null;if(a=!!(128&t.flags),null===(c=r.rendering))if(a)Wi(r,!1);else{if(0!==Ic||null!==e&&128&e.flags)for(e=t.child;null!==e;){if(null!==(c=dr(e))){for(t.flags|=128,Wi(r,!1),null!==(a=c.updateQueue)&&(t.updateQueue=a,t.flags|=4),t.subtreeFlags=0,a=n,n=t.child;null!==n;)e=a,(r=n).flags&=14680066,null===(c=r.alternate)?(r.childLanes=0,r.lanes=e,r.child=null,r.subtreeFlags=0,r.memoizedProps=null,r.memoizedState=null,r.updateQueue=null,r.dependencies=null,r.stateNode=null):(r.childLanes=c.childLanes,r.lanes=c.lanes,r.child=c.child,r.subtreeFlags=0,r.deletions=null,r.memoizedProps=c.memoizedProps,r.memoizedState=c.memoizedState,r.updateQueue=c.updateQueue,r.type=c.type,e=c.dependencies,r.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return To(cr,1&cr.current|2),t.child}e=e.sibling}null!==r.tail&&Ye()>Qc&&(t.flags|=128,a=!0,Wi(r,!1),t.lanes=4194304)}else{if(!a)if(null!==(e=dr(c))){if(t.flags|=128,a=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),Wi(r,!0),null===r.tail&&"hidden"===r.tailMode&&!c.alternate&&!ss)return qi(t),null}else 2*Ye()-r.renderingStartTime>Qc&&1073741824!==n&&(t.flags|=128,a=!0,Wi(r,!1),t.lanes=4194304);r.isBackwards?(c.sibling=t.child,t.child=c):(null!==(n=r.last)?n.sibling=c:t.child=c,r.last=c)}return null!==r.tail?(t=r.tail,r.rendering=t,r.tail=t.sibling,r.renderingStartTime=Ye(),t.sibling=null,n=cr.current,To(cr,a?1&n|2:1&n),t):(qi(t),null);case 22:case 23:return pd(),a=null!==t.memoizedState,null!==e&&null!==e.memoizedState!==a&&(t.flags|=8192),a&&1&t.mode?!!(1073741824&Rc)&&(qi(t),6&t.subtreeFlags&&(t.flags|=8192)):qi(t),null;case 24:case 25:return null}throw Error(s(156,t.tag))}function Xi(e,t){switch(ns(t),t.tag){case 1:return Ro(t.type)&&Oo(),65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 3:return sr(),Co(Lo),Co(jo),lr(),65536&(e=t.flags)&&!(128&e)?(t.flags=-65537&e|128,t):null;case 5:return ir(t),null;case 13:if(Co(cr),null!==(e=t.memoizedState)&&null!==e.dehydrated){if(null===t.alternate)throw Error(s(340));ms()}return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 19:return Co(cr),null;case 4:return sr(),null;case 10:return _s(t.type._context),null;case 22:case 23:return pd(),null;default:return null}}Ni=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Ri=function(){},Oi=function(e,t,n,a){var o=e.memoizedProps;if(o!==a){e=t.stateNode,ar(er.current);var s,r=null;switch(n){case"input":o=X(e,o),a=X(e,a),r=[];break;case"select":o=D({},o,{value:void 0}),a=D({},a,{value:void 0}),r=[];break;case"textarea":o=ae(e,o),a=ae(e,a),r=[];break;default:"function"!=typeof o.onClick&&"function"==typeof a.onClick&&(e.onclick=Ja)}for(u in ye(n,a),n=null,o)if(!a.hasOwnProperty(u)&&o.hasOwnProperty(u)&&null!=o[u])if("style"===u){var c=o[u];for(s in c)c.hasOwnProperty(s)&&(n||(n={}),n[s]="")}else"dangerouslySetInnerHTML"!==u&&"children"!==u&&"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&"autoFocus"!==u&&(i.hasOwnProperty(u)?r||(r=[]):(r=r||[]).push(u,null));for(u in a){var d=a[u];if(c=null!=o?o[u]:void 0,a.hasOwnProperty(u)&&d!==c&&(null!=d||null!=c))if("style"===u)if(c){for(s in c)!c.hasOwnProperty(s)||d&&d.hasOwnProperty(s)||(n||(n={}),n[s]="");for(s in d)d.hasOwnProperty(s)&&c[s]!==d[s]&&(n||(n={}),n[s]=d[s])}else n||(r||(r=[]),r.push(u,n)),n=d;else"dangerouslySetInnerHTML"===u?(d=d?d.__html:void 0,c=c?c.__html:void 0,null!=d&&c!==d&&(r=r||[]).push(u,d)):"children"===u?"string"!=typeof d&&"number"!=typeof d||(r=r||[]).push(u,""+d):"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&(i.hasOwnProperty(u)?(null!=d&&"onScroll"===u&&za("scroll",e),r||c===d||(r=[])):(r=r||[]).push(u,d))}n&&(r=r||[]).push("style",n);var u=r;(t.updateQueue=u)&&(t.flags|=4)}},Ii=function(e,t,n,a){n!==a&&(t.flags|=4)};var Ki=!1,Yi=!1,Zi="function"==typeof WeakSet?WeakSet:Set,Ji=null;function ec(e,t){var n=e.ref;if(null!==n)if("function"==typeof n)try{n(null)}catch(a){Ed(e,t,a)}else n.current=null}function tc(e,t,n){try{n()}catch(a){Ed(e,t,a)}}var nc=!1;function ac(e,t,n){var a=t.updateQueue;if(null!==(a=null!==a?a.lastEffect:null)){var o=a=a.next;do{if((o.tag&e)===e){var s=o.destroy;o.destroy=void 0,void 0!==s&&tc(t,n,s)}o=o.next}while(o!==a)}}function oc(e,t){if(null!==(t=null!==(t=t.updateQueue)?t.lastEffect:null)){var n=t=t.next;do{if((n.tag&e)===e){var a=n.create;n.destroy=a()}n=n.next}while(n!==t)}}function sc(e){var t=e.ref;if(null!==t){var n=e.stateNode;e.tag,e=n,"function"==typeof t?t(e):t.current=e}}function rc(e){var t=e.alternate;null!==t&&(e.alternate=null,rc(t)),e.child=null,e.deletions=null,e.sibling=null,5===e.tag&&(null!==(t=e.stateNode)&&(delete t[go],delete t[mo],delete t[ho],delete t[bo],delete t[yo])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function ic(e){return 5===e.tag||3===e.tag||4===e.tag}function cc(e){e:for(;;){for(;null===e.sibling;){if(null===e.return||ic(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;5!==e.tag&&6!==e.tag&&18!==e.tag;){if(2&e.flags)continue e;if(null===e.child||4===e.tag)continue e;e.child.return=e,e=e.child}if(!(2&e.flags))return e.stateNode}}function dc(e,t,n){var a=e.tag;if(5===a||6===a)e=e.stateNode,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Ja));else if(4!==a&&null!==(e=e.child))for(dc(e,t,n),e=e.sibling;null!==e;)dc(e,t,n),e=e.sibling}function uc(e,t,n){var a=e.tag;if(5===a||6===a)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==a&&null!==(e=e.child))for(uc(e,t,n),e=e.sibling;null!==e;)uc(e,t,n),e=e.sibling}var lc=null,pc=!1;function gc(e,t,n){for(n=n.child;null!==n;)mc(e,t,n),n=n.sibling}function mc(e,t,n){if(st&&"function"==typeof st.onCommitFiberUnmount)try{st.onCommitFiberUnmount(ot,n)}catch(i){}switch(n.tag){case 5:Yi||ec(n,t);case 6:var a=lc,o=pc;lc=null,gc(e,t,n),pc=o,null!==(lc=a)&&(pc?(e=lc,n=n.stateNode,8===e.nodeType?e.parentNode.removeChild(n):e.removeChild(n)):lc.removeChild(n.stateNode));break;case 18:null!==lc&&(pc?(e=lc,n=n.stateNode,8===e.nodeType?co(e.parentNode,n):1===e.nodeType&&co(e,n),Ut(e)):co(lc,n.stateNode));break;case 4:a=lc,o=pc,lc=n.stateNode.containerInfo,pc=!0,gc(e,t,n),lc=a,pc=o;break;case 0:case 11:case 14:case 15:if(!Yi&&(null!==(a=n.updateQueue)&&null!==(a=a.lastEffect))){o=a=a.next;do{var s=o,r=s.destroy;s=s.tag,void 0!==r&&(2&s||4&s)&&tc(n,t,r),o=o.next}while(o!==a)}gc(e,t,n);break;case 1:if(!Yi&&(ec(n,t),"function"==typeof(a=n.stateNode).componentWillUnmount))try{a.props=n.memoizedProps,a.state=n.memoizedState,a.componentWillUnmount()}catch(i){Ed(n,t,i)}gc(e,t,n);break;case 21:gc(e,t,n);break;case 22:1&n.mode?(Yi=(a=Yi)||null!==n.memoizedState,gc(e,t,n),Yi=a):gc(e,t,n);break;default:gc(e,t,n)}}function fc(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new Zi),t.forEach((function(t){var a=jd.bind(null,e,t);n.has(t)||(n.add(t),t.then(a,a))}))}}function hc(e,t){var n=t.deletions;if(null!==n)for(var a=0;a<n.length;a++){var o=n[a];try{var r=e,i=t,c=i;e:for(;null!==c;){switch(c.tag){case 5:lc=c.stateNode,pc=!1;break e;case 3:case 4:lc=c.stateNode.containerInfo,pc=!0;break e}c=c.return}if(null===lc)throw Error(s(160));mc(r,i,o),lc=null,pc=!1;var d=o.alternate;null!==d&&(d.return=null),o.return=null}catch(u){Ed(o,t,u)}}if(12854&t.subtreeFlags)for(t=t.child;null!==t;)bc(t,e),t=t.sibling}function bc(e,t){var n=e.alternate,a=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(hc(t,e),yc(e),4&a){try{ac(3,e,e.return),oc(3,e)}catch(h){Ed(e,e.return,h)}try{ac(5,e,e.return)}catch(h){Ed(e,e.return,h)}}break;case 1:hc(t,e),yc(e),512&a&&null!==n&&ec(n,n.return);break;case 5:if(hc(t,e),yc(e),512&a&&null!==n&&ec(n,n.return),32&e.flags){var o=e.stateNode;try{pe(o,"")}catch(h){Ed(e,e.return,h)}}if(4&a&&null!=(o=e.stateNode)){var r=e.memoizedProps,i=null!==n?n.memoizedProps:r,c=e.type,d=e.updateQueue;if(e.updateQueue=null,null!==d)try{"input"===c&&"radio"===r.type&&null!=r.name&&Y(o,r),ve(c,i);var u=ve(c,r);for(i=0;i<d.length;i+=2){var l=d[i],p=d[i+1];"style"===l?he(o,p):"dangerouslySetInnerHTML"===l?le(o,p):"children"===l?pe(o,p):v(o,l,p,u)}switch(c){case"input":Z(o,r);break;case"textarea":se(o,r);break;case"select":var g=o._wrapperState.wasMultiple;o._wrapperState.wasMultiple=!!r.multiple;var m=r.value;null!=m?ne(o,!!r.multiple,m,!1):g!==!!r.multiple&&(null!=r.defaultValue?ne(o,!!r.multiple,r.defaultValue,!0):ne(o,!!r.multiple,r.multiple?[]:"",!1))}o[mo]=r}catch(h){Ed(e,e.return,h)}}break;case 6:if(hc(t,e),yc(e),4&a){if(null===e.stateNode)throw Error(s(162));o=e.stateNode,r=e.memoizedProps;try{o.nodeValue=r}catch(h){Ed(e,e.return,h)}}break;case 3:if(hc(t,e),yc(e),4&a&&null!==n&&n.memoizedState.isDehydrated)try{Ut(t.containerInfo)}catch(h){Ed(e,e.return,h)}break;case 4:default:hc(t,e),yc(e);break;case 13:hc(t,e),yc(e),8192&(o=e.child).flags&&(r=null!==o.memoizedState,o.stateNode.isHidden=r,!r||null!==o.alternate&&null!==o.alternate.memoizedState||(Uc=Ye())),4&a&&fc(e);break;case 22:if(l=null!==n&&null!==n.memoizedState,1&e.mode?(Yi=(u=Yi)||l,hc(t,e),Yi=u):hc(t,e),yc(e),8192&a){if(u=null!==e.memoizedState,(e.stateNode.isHidden=u)&&!l&&1&e.mode)for(Ji=e,l=e.child;null!==l;){for(p=Ji=l;null!==Ji;){switch(m=(g=Ji).child,g.tag){case 0:case 11:case 14:case 15:ac(4,g,g.return);break;case 1:ec(g,g.return);var f=g.stateNode;if("function"==typeof f.componentWillUnmount){a=g,n=g.return;try{t=a,f.props=t.memoizedProps,f.state=t.memoizedState,f.componentWillUnmount()}catch(h){Ed(a,n,h)}}break;case 5:ec(g,g.return);break;case 22:if(null!==g.memoizedState){wc(p);continue}}null!==m?(m.return=g,Ji=m):wc(p)}l=l.sibling}e:for(l=null,p=e;;){if(5===p.tag){if(null===l){l=p;try{o=p.stateNode,u?"function"==typeof(r=o.style).setProperty?r.setProperty("display","none","important"):r.display="none":(c=p.stateNode,i=null!=(d=p.memoizedProps.style)&&d.hasOwnProperty("display")?d.display:null,c.style.display=fe("display",i))}catch(h){Ed(e,e.return,h)}}}else if(6===p.tag){if(null===l)try{p.stateNode.nodeValue=u?"":p.memoizedProps}catch(h){Ed(e,e.return,h)}}else if((22!==p.tag&&23!==p.tag||null===p.memoizedState||p===e)&&null!==p.child){p.child.return=p,p=p.child;continue}if(p===e)break e;for(;null===p.sibling;){if(null===p.return||p.return===e)break e;l===p&&(l=null),p=p.return}l===p&&(l=null),p.sibling.return=p.return,p=p.sibling}}break;case 19:hc(t,e),yc(e),4&a&&fc(e);case 21:}}function yc(e){var t=e.flags;if(2&t){try{e:{for(var n=e.return;null!==n;){if(ic(n)){var a=n;break e}n=n.return}throw Error(s(160))}switch(a.tag){case 5:var o=a.stateNode;32&a.flags&&(pe(o,""),a.flags&=-33),uc(e,cc(e),o);break;case 3:case 4:var r=a.stateNode.containerInfo;dc(e,cc(e),r);break;default:throw Error(s(161))}}catch(i){Ed(e,e.return,i)}e.flags&=-3}4096&t&&(e.flags&=-4097)}function vc(e,t,n){Ji=e,kc(e,t,n)}function kc(e,t,n){for(var a=!!(1&e.mode);null!==Ji;){var o=Ji,s=o.child;if(22===o.tag&&a){var r=null!==o.memoizedState||Ki;if(!r){var i=o.alternate,c=null!==i&&null!==i.memoizedState||Yi;i=Ki;var d=Yi;if(Ki=r,(Yi=c)&&!d)for(Ji=o;null!==Ji;)c=(r=Ji).child,22===r.tag&&null!==r.memoizedState?_c(o):null!==c?(c.return=r,Ji=c):_c(o);for(;null!==s;)Ji=s,kc(s,t,n),s=s.sibling;Ji=o,Ki=i,Yi=d}xc(e)}else 8772&o.subtreeFlags&&null!==s?(s.return=o,Ji=s):xc(e)}}function xc(e){for(;null!==Ji;){var t=Ji;if(8772&t.flags){var n=t.alternate;try{if(8772&t.flags)switch(t.tag){case 0:case 11:case 15:Yi||oc(5,t);break;case 1:var a=t.stateNode;if(4&t.flags&&!Yi)if(null===n)a.componentDidMount();else{var o=t.elementType===t.type?n.memoizedProps:bs(t.type,n.memoizedProps);a.componentDidUpdate(o,n.memoizedState,a.__reactInternalSnapshotBeforeUpdate)}var r=t.updateQueue;null!==r&&zs(t,r,a);break;case 3:var i=t.updateQueue;if(null!==i){if(n=null,null!==t.child)switch(t.child.tag){case 5:case 1:n=t.child.stateNode}zs(t,i,n)}break;case 5:var c=t.stateNode;if(null===n&&4&t.flags){n=c;var d=t.memoizedProps;switch(t.type){case"button":case"input":case"select":case"textarea":d.autoFocus&&n.focus();break;case"img":d.src&&(n.src=d.src)}}break;case 6:case 4:case 12:case 19:case 17:case 21:case 22:case 23:case 25:break;case 13:if(null===t.memoizedState){var u=t.alternate;if(null!==u){var l=u.memoizedState;if(null!==l){var p=l.dehydrated;null!==p&&Ut(p)}}}break;default:throw Error(s(163))}Yi||512&t.flags&&sc(t)}catch(g){Ed(t,t.return,g)}}if(t===e){Ji=null;break}if(null!==(n=t.sibling)){n.return=t.return,Ji=n;break}Ji=t.return}}function wc(e){for(;null!==Ji;){var t=Ji;if(t===e){Ji=null;break}var n=t.sibling;if(null!==n){n.return=t.return,Ji=n;break}Ji=t.return}}function _c(e){for(;null!==Ji;){var t=Ji;try{switch(t.tag){case 0:case 11:case 15:var n=t.return;try{oc(4,t)}catch(c){Ed(t,n,c)}break;case 1:var a=t.stateNode;if("function"==typeof a.componentDidMount){var o=t.return;try{a.componentDidMount()}catch(c){Ed(t,o,c)}}var s=t.return;try{sc(t)}catch(c){Ed(t,s,c)}break;case 5:var r=t.return;try{sc(t)}catch(c){Ed(t,r,c)}}}catch(c){Ed(t,t.return,c)}if(t===e){Ji=null;break}var i=t.sibling;if(null!==i){i.return=t.return,Ji=i;break}Ji=t.return}}var Sc,Ec=Math.ceil,Cc=k.ReactCurrentDispatcher,Tc=k.ReactCurrentOwner,Ac=k.ReactCurrentBatchConfig,jc=0,Lc=null,Pc=null,Nc=0,Rc=0,Oc=Eo(0),Ic=0,Fc=null,Dc=0,Mc=0,zc=0,Bc=null,$c=null,Uc=0,Qc=1/0,Vc=null,Hc=!1,Wc=null,qc=null,Gc=!1,Xc=null,Kc=0,Yc=0,Zc=null,Jc=-1,ed=0;function td(){return 6&jc?Ye():-1!==Jc?Jc:Jc=Ye()}function nd(e){return 1&e.mode?2&jc&&0!==Nc?Nc&-Nc:null!==hs.transition?(0===ed&&(ed=ft()),ed):0!==(e=vt)?e:e=void 0===(e=window.event)?16:Kt(e.type):1}function ad(e,t,n,a){if(50<Yc)throw Yc=0,Zc=null,Error(s(185));bt(e,n,a),2&jc&&e===Lc||(e===Lc&&(!(2&jc)&&(Mc|=n),4===Ic&&cd(e,Nc)),od(e,a),1===n&&0===jc&&!(1&t.mode)&&(Qc=Ye()+500,Bo&&Qo()))}function od(e,t){var n=e.callbackNode;!function(e,t){for(var n=e.suspendedLanes,a=e.pingedLanes,o=e.expirationTimes,s=e.pendingLanes;0<s;){var r=31-rt(s),i=1<<r,c=o[r];-1===c?i&n&&!(i&a)||(o[r]=gt(i,t)):c<=t&&(e.expiredLanes|=i),s&=~i}}(e,t);var a=pt(e,e===Lc?Nc:0);if(0===a)null!==n&&Ge(n),e.callbackNode=null,e.callbackPriority=0;else if(t=a&-a,e.callbackPriority!==t){if(null!=n&&Ge(n),1===t)0===e.tag?function(e){Bo=!0,Uo(e)}(dd.bind(null,e)):Uo(dd.bind(null,e)),ro((function(){!(6&jc)&&Qo()})),n=null;else{switch(kt(a)){case 1:n=Je;break;case 4:n=et;break;case 16:default:n=tt;break;case 536870912:n=at}n=Ld(n,sd.bind(null,e))}e.callbackPriority=t,e.callbackNode=n}}function sd(e,t){if(Jc=-1,ed=0,6&jc)throw Error(s(327));var n=e.callbackNode;if(_d()&&e.callbackNode!==n)return null;var a=pt(e,e===Lc?Nc:0);if(0===a)return null;if(30&a||a&e.expiredLanes||t)t=bd(e,a);else{t=a;var o=jc;jc|=2;var r=fd();for(Lc===e&&Nc===t||(Vc=null,Qc=Ye()+500,gd(e,t));;)try{vd();break}catch(c){md(e,c)}ws(),Cc.current=r,jc=o,null!==Pc?t=0:(Lc=null,Nc=0,t=Ic)}if(0!==t){if(2===t&&(0!==(o=mt(e))&&(a=o,t=rd(e,o))),1===t)throw n=Fc,gd(e,0),cd(e,a),od(e,Ye()),n;if(6===t)cd(e,a);else{if(o=e.current.alternate,!(30&a||function(e){for(var t=e;;){if(16384&t.flags){var n=t.updateQueue;if(null!==n&&null!==(n=n.stores))for(var a=0;a<n.length;a++){var o=n[a],s=o.getSnapshot;o=o.value;try{if(!ia(s(),o))return!1}catch(i){return!1}}}if(n=t.child,16384&t.subtreeFlags&&null!==n)n.return=t,t=n;else{if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}(o)||(t=bd(e,a),2===t&&(r=mt(e),0!==r&&(a=r,t=rd(e,r))),1!==t)))throw n=Fc,gd(e,0),cd(e,a),od(e,Ye()),n;switch(e.finishedWork=o,e.finishedLanes=a,t){case 0:case 1:throw Error(s(345));case 2:case 5:wd(e,$c,Vc);break;case 3:if(cd(e,a),(130023424&a)===a&&10<(t=Uc+500-Ye())){if(0!==pt(e,0))break;if(((o=e.suspendedLanes)&a)!==a){td(),e.pingedLanes|=e.suspendedLanes&o;break}e.timeoutHandle=ao(wd.bind(null,e,$c,Vc),t);break}wd(e,$c,Vc);break;case 4:if(cd(e,a),(4194240&a)===a)break;for(t=e.eventTimes,o=-1;0<a;){var i=31-rt(a);r=1<<i,(i=t[i])>o&&(o=i),a&=~r}if(a=o,10<(a=(120>(a=Ye()-a)?120:480>a?480:1080>a?1080:1920>a?1920:3e3>a?3e3:4320>a?4320:1960*Ec(a/1960))-a)){e.timeoutHandle=ao(wd.bind(null,e,$c,Vc),a);break}wd(e,$c,Vc);break;default:throw Error(s(329))}}}return od(e,Ye()),e.callbackNode===n?sd.bind(null,e):null}function rd(e,t){var n=Bc;return e.current.memoizedState.isDehydrated&&(gd(e,t).flags|=256),2!==(e=bd(e,t))&&(t=$c,$c=n,null!==t&&id(t)),e}function id(e){null===$c?$c=e:$c.push.apply($c,e)}function cd(e,t){for(t&=~zc,t&=~Mc,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-rt(t),a=1<<n;e[n]=-1,t&=~a}}function dd(e){if(6&jc)throw Error(s(327));_d();var t=pt(e,0);if(!(1&t))return od(e,Ye()),null;var n=bd(e,t);if(0!==e.tag&&2===n){var a=mt(e);0!==a&&(t=a,n=rd(e,a))}if(1===n)throw n=Fc,gd(e,0),cd(e,t),od(e,Ye()),n;if(6===n)throw Error(s(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,wd(e,$c,Vc),od(e,Ye()),null}function ud(e,t){var n=jc;jc|=1;try{return e(t)}finally{0===(jc=n)&&(Qc=Ye()+500,Bo&&Qo())}}function ld(e){null!==Xc&&0===Xc.tag&&!(6&jc)&&_d();var t=jc;jc|=1;var n=Ac.transition,a=vt;try{if(Ac.transition=null,vt=1,e)return e()}finally{vt=a,Ac.transition=n,!(6&(jc=t))&&Qo()}}function pd(){Rc=Oc.current,Co(Oc)}function gd(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,oo(n)),null!==Pc)for(n=Pc.return;null!==n;){var a=n;switch(ns(a),a.tag){case 1:null!=(a=a.type.childContextTypes)&&Oo();break;case 3:sr(),Co(Lo),Co(jo),lr();break;case 5:ir(a);break;case 4:sr();break;case 13:case 19:Co(cr);break;case 10:_s(a.type._context);break;case 22:case 23:pd()}n=n.return}if(Lc=e,Pc=e=Od(e.current,null),Nc=Rc=t,Ic=0,Fc=null,zc=Mc=Dc=0,$c=Bc=null,null!==Ts){for(t=0;t<Ts.length;t++)if(null!==(a=(n=Ts[t]).interleaved)){n.interleaved=null;var o=a.next,s=n.pending;if(null!==s){var r=s.next;s.next=o,a.next=r}n.pending=a}Ts=null}return e}function md(e,t){for(;;){var n=Pc;try{if(ws(),pr.current=ri,yr){for(var a=fr.memoizedState;null!==a;){var o=a.queue;null!==o&&(o.pending=null),a=a.next}yr=!1}if(mr=0,br=hr=fr=null,vr=!1,kr=0,Tc.current=null,null===n||null===n.return){Ic=1,Fc=t,Pc=null;break}e:{var r=e,i=n.return,c=n,d=t;if(t=Nc,c.flags|=32768,null!==d&&"object"==typeof d&&"function"==typeof d.then){var u=d,l=c,p=l.tag;if(!(1&l.mode||0!==p&&11!==p&&15!==p)){var g=l.alternate;g?(l.updateQueue=g.updateQueue,l.memoizedState=g.memoizedState,l.lanes=g.lanes):(l.updateQueue=null,l.memoizedState=null)}var m=bi(i);if(null!==m){m.flags&=-257,yi(m,i,c,0,t),1&m.mode&&hi(r,u,t),d=u;var f=(t=m).updateQueue;if(null===f){var h=new Set;h.add(d),t.updateQueue=h}else f.add(d);break e}if(!(1&t)){hi(r,u,t),hd();break e}d=Error(s(426))}else if(ss&&1&c.mode){var b=bi(i);if(null!==b){!(65536&b.flags)&&(b.flags|=256),yi(b,i,c,0,t),fs(ui(d,c));break e}}r=d=ui(d,c),4!==Ic&&(Ic=2),null===Bc?Bc=[r]:Bc.push(r),r=i;do{switch(r.tag){case 3:r.flags|=65536,t&=-t,r.lanes|=t,Ds(r,mi(0,d,t));break e;case 1:c=d;var y=r.type,v=r.stateNode;if(!(128&r.flags||"function"!=typeof y.getDerivedStateFromError&&(null===v||"function"!=typeof v.componentDidCatch||null!==qc&&qc.has(v)))){r.flags|=65536,t&=-t,r.lanes|=t,Ds(r,fi(r,c,t));break e}}r=r.return}while(null!==r)}xd(n)}catch(k){t=k,Pc===n&&null!==n&&(Pc=n=n.return);continue}break}}function fd(){var e=Cc.current;return Cc.current=ri,null===e?ri:e}function hd(){0!==Ic&&3!==Ic&&2!==Ic||(Ic=4),null===Lc||!(268435455&Dc)&&!(268435455&Mc)||cd(Lc,Nc)}function bd(e,t){var n=jc;jc|=2;var a=fd();for(Lc===e&&Nc===t||(Vc=null,gd(e,t));;)try{yd();break}catch(o){md(e,o)}if(ws(),jc=n,Cc.current=a,null!==Pc)throw Error(s(261));return Lc=null,Nc=0,Ic}function yd(){for(;null!==Pc;)kd(Pc)}function vd(){for(;null!==Pc&&!Xe();)kd(Pc)}function kd(e){var t=Sc(e.alternate,e,Rc);e.memoizedProps=e.pendingProps,null===t?xd(e):Pc=t,Tc.current=null}function xd(e){var t=e;do{var n=t.alternate;if(e=t.return,32768&t.flags){if(null!==(n=Xi(n,t)))return n.flags&=32767,void(Pc=n);if(null===e)return Ic=6,void(Pc=null);e.flags|=32768,e.subtreeFlags=0,e.deletions=null}else if(null!==(n=Gi(n,t,Rc)))return void(Pc=n);if(null!==(t=t.sibling))return void(Pc=t);Pc=t=e}while(null!==t);0===Ic&&(Ic=5)}function wd(e,t,n){var a=vt,o=Ac.transition;try{Ac.transition=null,vt=1,function(e,t,n,a){do{_d()}while(null!==Xc);if(6&jc)throw Error(s(327));n=e.finishedWork;var o=e.finishedLanes;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(s(177));e.callbackNode=null,e.callbackPriority=0;var r=n.lanes|n.childLanes;if(function(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var a=e.eventTimes;for(e=e.expirationTimes;0<n;){var o=31-rt(n),s=1<<o;t[o]=0,a[o]=-1,e[o]=-1,n&=~s}}(e,r),e===Lc&&(Pc=Lc=null,Nc=0),!(2064&n.subtreeFlags)&&!(2064&n.flags)||Gc||(Gc=!0,Ld(tt,(function(){return _d(),null}))),r=!!(15990&n.flags),!!(15990&n.subtreeFlags)||r){r=Ac.transition,Ac.transition=null;var i=vt;vt=1;var c=jc;jc|=4,Tc.current=null,function(e,t){if(eo=Vt,ga(e=pa())){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{var a=(n=(n=e.ownerDocument)&&n.defaultView||window).getSelection&&n.getSelection();if(a&&0!==a.rangeCount){n=a.anchorNode;var o=a.anchorOffset,r=a.focusNode;a=a.focusOffset;try{n.nodeType,r.nodeType}catch(x){n=null;break e}var i=0,c=-1,d=-1,u=0,l=0,p=e,g=null;t:for(;;){for(var m;p!==n||0!==o&&3!==p.nodeType||(c=i+o),p!==r||0!==a&&3!==p.nodeType||(d=i+a),3===p.nodeType&&(i+=p.nodeValue.length),null!==(m=p.firstChild);)g=p,p=m;for(;;){if(p===e)break t;if(g===n&&++u===o&&(c=i),g===r&&++l===a&&(d=i),null!==(m=p.nextSibling))break;g=(p=g).parentNode}p=m}n=-1===c||-1===d?null:{start:c,end:d}}else n=null}n=n||{start:0,end:0}}else n=null;for(to={focusedElem:e,selectionRange:n},Vt=!1,Ji=t;null!==Ji;)if(e=(t=Ji).child,1028&t.subtreeFlags&&null!==e)e.return=t,Ji=e;else for(;null!==Ji;){t=Ji;try{var f=t.alternate;if(1024&t.flags)switch(t.tag){case 0:case 11:case 15:case 5:case 6:case 4:case 17:break;case 1:if(null!==f){var h=f.memoizedProps,b=f.memoizedState,y=t.stateNode,v=y.getSnapshotBeforeUpdate(t.elementType===t.type?h:bs(t.type,h),b);y.__reactInternalSnapshotBeforeUpdate=v}break;case 3:var k=t.stateNode.containerInfo;1===k.nodeType?k.textContent="":9===k.nodeType&&k.documentElement&&k.removeChild(k.documentElement);break;default:throw Error(s(163))}}catch(x){Ed(t,t.return,x)}if(null!==(e=t.sibling)){e.return=t.return,Ji=e;break}Ji=t.return}f=nc,nc=!1}(e,n),bc(n,e),ma(to),Vt=!!eo,to=eo=null,e.current=n,vc(n,e,o),Ke(),jc=c,vt=i,Ac.transition=r}else e.current=n;if(Gc&&(Gc=!1,Xc=e,Kc=o),r=e.pendingLanes,0===r&&(qc=null),function(e){if(st&&"function"==typeof st.onCommitFiberRoot)try{st.onCommitFiberRoot(ot,e,void 0,!(128&~e.current.flags))}catch(t){}}(n.stateNode),od(e,Ye()),null!==t)for(a=e.onRecoverableError,n=0;n<t.length;n++)o=t[n],a(o.value,{componentStack:o.stack,digest:o.digest});if(Hc)throw Hc=!1,e=Wc,Wc=null,e;!!(1&Kc)&&0!==e.tag&&_d(),r=e.pendingLanes,1&r?e===Zc?Yc++:(Yc=0,Zc=e):Yc=0,Qo()}(e,t,n,a)}finally{Ac.transition=o,vt=a}return null}function _d(){if(null!==Xc){var e=kt(Kc),t=Ac.transition,n=vt;try{if(Ac.transition=null,vt=16>e?16:e,null===Xc)var a=!1;else{if(e=Xc,Xc=null,Kc=0,6&jc)throw Error(s(331));var o=jc;for(jc|=4,Ji=e.current;null!==Ji;){var r=Ji,i=r.child;if(16&Ji.flags){var c=r.deletions;if(null!==c){for(var d=0;d<c.length;d++){var u=c[d];for(Ji=u;null!==Ji;){var l=Ji;switch(l.tag){case 0:case 11:case 15:ac(8,l,r)}var p=l.child;if(null!==p)p.return=l,Ji=p;else for(;null!==Ji;){var g=(l=Ji).sibling,m=l.return;if(rc(l),l===u){Ji=null;break}if(null!==g){g.return=m,Ji=g;break}Ji=m}}}var f=r.alternate;if(null!==f){var h=f.child;if(null!==h){f.child=null;do{var b=h.sibling;h.sibling=null,h=b}while(null!==h)}}Ji=r}}if(2064&r.subtreeFlags&&null!==i)i.return=r,Ji=i;else e:for(;null!==Ji;){if(2048&(r=Ji).flags)switch(r.tag){case 0:case 11:case 15:ac(9,r,r.return)}var y=r.sibling;if(null!==y){y.return=r.return,Ji=y;break e}Ji=r.return}}var v=e.current;for(Ji=v;null!==Ji;){var k=(i=Ji).child;if(2064&i.subtreeFlags&&null!==k)k.return=i,Ji=k;else e:for(i=v;null!==Ji;){if(2048&(c=Ji).flags)try{switch(c.tag){case 0:case 11:case 15:oc(9,c)}}catch(w){Ed(c,c.return,w)}if(c===i){Ji=null;break e}var x=c.sibling;if(null!==x){x.return=c.return,Ji=x;break e}Ji=c.return}}if(jc=o,Qo(),st&&"function"==typeof st.onPostCommitFiberRoot)try{st.onPostCommitFiberRoot(ot,e)}catch(w){}a=!0}return a}finally{vt=n,Ac.transition=t}}return!1}function Sd(e,t,n){e=Is(e,t=mi(0,t=ui(n,t),1),1),t=td(),null!==e&&(bt(e,1,t),od(e,t))}function Ed(e,t,n){if(3===e.tag)Sd(e,e,n);else for(;null!==t;){if(3===t.tag){Sd(t,e,n);break}if(1===t.tag){var a=t.stateNode;if("function"==typeof t.type.getDerivedStateFromError||"function"==typeof a.componentDidCatch&&(null===qc||!qc.has(a))){t=Is(t,e=fi(t,e=ui(n,e),1),1),e=td(),null!==t&&(bt(t,1,e),od(t,e));break}}t=t.return}}function Cd(e,t,n){var a=e.pingCache;null!==a&&a.delete(t),t=td(),e.pingedLanes|=e.suspendedLanes&n,Lc===e&&(Nc&n)===n&&(4===Ic||3===Ic&&(130023424&Nc)===Nc&&500>Ye()-Uc?gd(e,0):zc|=n),od(e,t)}function Td(e,t){0===t&&(1&e.mode?(t=ut,!(130023424&(ut<<=1))&&(ut=4194304)):t=1);var n=td();null!==(e=Ls(e,t))&&(bt(e,t,n),od(e,n))}function Ad(e){var t=e.memoizedState,n=0;null!==t&&(n=t.retryLane),Td(e,n)}function jd(e,t){var n=0;switch(e.tag){case 13:var a=e.stateNode,o=e.memoizedState;null!==o&&(n=o.retryLane);break;case 19:a=e.stateNode;break;default:throw Error(s(314))}null!==a&&a.delete(t),Td(e,n)}function Ld(e,t){return qe(e,t)}function Pd(e,t,n,a){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=a,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Nd(e,t,n,a){return new Pd(e,t,n,a)}function Rd(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Od(e,t){var n=e.alternate;return null===n?((n=Nd(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=14680064&e.flags,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Id(e,t,n,a,o,r){var i=2;if(a=e,"function"==typeof e)Rd(e)&&(i=1);else if("string"==typeof e)i=5;else e:switch(e){case _:return Fd(n.children,o,r,t);case S:i=8,o|=8;break;case E:return(e=Nd(12,n,t,2|o)).elementType=E,e.lanes=r,e;case j:return(e=Nd(13,n,t,o)).elementType=j,e.lanes=r,e;case L:return(e=Nd(19,n,t,o)).elementType=L,e.lanes=r,e;case R:return Dd(n,o,r,t);default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case C:i=10;break e;case T:i=9;break e;case A:i=11;break e;case P:i=14;break e;case N:i=16,a=null;break e}throw Error(s(130,null==e?e:typeof e,""))}return(t=Nd(i,n,t,o)).elementType=e,t.type=a,t.lanes=r,t}function Fd(e,t,n,a){return(e=Nd(7,e,a,t)).lanes=n,e}function Dd(e,t,n,a){return(e=Nd(22,e,a,t)).elementType=R,e.lanes=n,e.stateNode={isHidden:!1},e}function Md(e,t,n){return(e=Nd(6,e,null,t)).lanes=n,e}function zd(e,t,n){return(t=Nd(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Bd(e,t,n,a,o){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=ht(0),this.expirationTimes=ht(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=ht(0),this.identifierPrefix=a,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function $d(e,t,n,a,o,s,r,i,c){return e=new Bd(e,t,n,i,c),1===t?(t=1,!0===s&&(t|=8)):t=0,s=Nd(3,null,null,t),e.current=s,s.stateNode=e,s.memoizedState={element:a,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Ns(s),e}function Ud(e){if(!e)return Ao;e:{if(Ue(e=e._reactInternals)!==e||1!==e.tag)throw Error(s(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(Ro(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(null!==t);throw Error(s(171))}if(1===e.tag){var n=e.type;if(Ro(n))return Fo(e,n,t)}return t}function Qd(e,t,n,a,o,s,r,i,c){return(e=$d(n,a,!0,e,0,s,0,i,c)).context=Ud(null),n=e.current,(s=Os(a=td(),o=nd(n))).callback=null!=t?t:null,Is(n,s,o),e.current.lanes=o,bt(e,o,a),od(e,a),e}function Vd(e,t,n,a){var o=t.current,s=td(),r=nd(o);return n=Ud(n),null===t.context?t.context=n:t.pendingContext=n,(t=Os(s,r)).payload={element:e},null!==(a=void 0===a?null:a)&&(t.callback=a),null!==(e=Is(o,t,r))&&(ad(e,o,r,s),Fs(e,o,r)),r}function Hd(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function Wd(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function qd(e,t){Wd(e,t),(e=e.alternate)&&Wd(e,t)}Sc=function(e,t,n){if(null!==e)if(e.memoizedProps!==t.pendingProps||Lo.current)ki=!0;else{if(!(e.lanes&n||128&t.flags))return ki=!1,function(e,t,n){switch(t.tag){case 3:Li(t),ms();break;case 5:rr(t);break;case 1:Ro(t.type)&&Do(t);break;case 4:or(t,t.stateNode.containerInfo);break;case 10:var a=t.type._context,o=t.memoizedProps.value;To(ys,a._currentValue),a._currentValue=o;break;case 13:if(null!==(a=t.memoizedState))return null!==a.dehydrated?(To(cr,1&cr.current),t.flags|=128,null):n&t.child.childLanes?Mi(e,t,n):(To(cr,1&cr.current),null!==(e=Hi(e,t,n))?e.sibling:null);To(cr,1&cr.current);break;case 19:if(a=!!(n&t.childLanes),128&e.flags){if(a)return Qi(e,t,n);t.flags|=128}if(null!==(o=t.memoizedState)&&(o.rendering=null,o.tail=null,o.lastEffect=null),To(cr,cr.current),a)break;return null;case 22:case 23:return t.lanes=0,Ei(e,t,n)}return Hi(e,t,n)}(e,t,n);ki=!!(131072&e.flags)}else ki=!1,ss&&1048576&t.flags&&es(t,qo,t.index);switch(t.lanes=0,t.tag){case 2:var a=t.type;Vi(e,t),e=t.pendingProps;var o=No(t,jo.current);Es(t,n),o=Sr(null,t,a,e,o,n);var r=Er();return t.flags|=1,"object"==typeof o&&null!==o&&"function"==typeof o.render&&void 0===o.$$typeof?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Ro(a)?(r=!0,Do(t)):r=!1,t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,Ns(t),o.updater=Us,t.stateNode=o,o._reactInternals=t,Ws(t,a,e,n),t=ji(null,t,a,!0,r,n)):(t.tag=0,ss&&r&&ts(t),xi(null,t,o,n),t=t.child),t;case 16:a=t.elementType;e:{switch(Vi(e,t),e=t.pendingProps,a=(o=a._init)(a._payload),t.type=a,o=t.tag=function(e){if("function"==typeof e)return Rd(e)?1:0;if(null!=e){if((e=e.$$typeof)===A)return 11;if(e===P)return 14}return 2}(a),e=bs(a,e),o){case 0:t=Ti(null,t,a,e,n);break e;case 1:t=Ai(null,t,a,e,n);break e;case 11:t=wi(null,t,a,e,n);break e;case 14:t=_i(null,t,a,bs(a.type,e),n);break e}throw Error(s(306,a,""))}return t;case 0:return a=t.type,o=t.pendingProps,Ti(e,t,a,o=t.elementType===a?o:bs(a,o),n);case 1:return a=t.type,o=t.pendingProps,Ai(e,t,a,o=t.elementType===a?o:bs(a,o),n);case 3:e:{if(Li(t),null===e)throw Error(s(387));a=t.pendingProps,o=(r=t.memoizedState).element,Rs(e,t),Ms(t,a,null,n);var i=t.memoizedState;if(a=i.element,r.isDehydrated){if(r={element:a,isDehydrated:!1,cache:i.cache,pendingSuspenseBoundaries:i.pendingSuspenseBoundaries,transitions:i.transitions},t.updateQueue.baseState=r,t.memoizedState=r,256&t.flags){t=Pi(e,t,a,n,o=ui(Error(s(423)),t));break e}if(a!==o){t=Pi(e,t,a,n,o=ui(Error(s(424)),t));break e}for(os=uo(t.stateNode.containerInfo.firstChild),as=t,ss=!0,rs=null,n=Zs(t,null,a,n),t.child=n;n;)n.flags=-3&n.flags|4096,n=n.sibling}else{if(ms(),a===o){t=Hi(e,t,n);break e}xi(e,t,a,n)}t=t.child}return t;case 5:return rr(t),null===e&&us(t),a=t.type,o=t.pendingProps,r=null!==e?e.memoizedProps:null,i=o.children,no(a,o)?i=null:null!==r&&no(a,r)&&(t.flags|=32),Ci(e,t),xi(e,t,i,n),t.child;case 6:return null===e&&us(t),null;case 13:return Mi(e,t,n);case 4:return or(t,t.stateNode.containerInfo),a=t.pendingProps,null===e?t.child=Ys(t,null,a,n):xi(e,t,a,n),t.child;case 11:return a=t.type,o=t.pendingProps,wi(e,t,a,o=t.elementType===a?o:bs(a,o),n);case 7:return xi(e,t,t.pendingProps,n),t.child;case 8:case 12:return xi(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(a=t.type._context,o=t.pendingProps,r=t.memoizedProps,i=o.value,To(ys,a._currentValue),a._currentValue=i,null!==r)if(ia(r.value,i)){if(r.children===o.children&&!Lo.current){t=Hi(e,t,n);break e}}else for(null!==(r=t.child)&&(r.return=t);null!==r;){var c=r.dependencies;if(null!==c){i=r.child;for(var d=c.firstContext;null!==d;){if(d.context===a){if(1===r.tag){(d=Os(-1,n&-n)).tag=2;var u=r.updateQueue;if(null!==u){var l=(u=u.shared).pending;null===l?d.next=d:(d.next=l.next,l.next=d),u.pending=d}}r.lanes|=n,null!==(d=r.alternate)&&(d.lanes|=n),Ss(r.return,n,t),c.lanes|=n;break}d=d.next}}else if(10===r.tag)i=r.type===t.type?null:r.child;else if(18===r.tag){if(null===(i=r.return))throw Error(s(341));i.lanes|=n,null!==(c=i.alternate)&&(c.lanes|=n),Ss(i,n,t),i=r.sibling}else i=r.child;if(null!==i)i.return=r;else for(i=r;null!==i;){if(i===t){i=null;break}if(null!==(r=i.sibling)){r.return=i.return,i=r;break}i=i.return}r=i}xi(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,a=t.pendingProps.children,Es(t,n),a=a(o=Cs(o)),t.flags|=1,xi(e,t,a,n),t.child;case 14:return o=bs(a=t.type,t.pendingProps),_i(e,t,a,o=bs(a.type,o),n);case 15:return Si(e,t,t.type,t.pendingProps,n);case 17:return a=t.type,o=t.pendingProps,o=t.elementType===a?o:bs(a,o),Vi(e,t),t.tag=1,Ro(a)?(e=!0,Do(t)):e=!1,Es(t,n),Vs(t,a,o),Ws(t,a,o,n),ji(null,t,a,!0,e,n);case 19:return Qi(e,t,n);case 22:return Ei(e,t,n)}throw Error(s(156,t.tag))};var Gd="function"==typeof reportError?reportError:function(e){console.error(e)};function Xd(e){this._internalRoot=e}function Kd(e){this._internalRoot=e}function Yd(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType)}function Zd(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function Jd(){}function eu(e,t,n,a,o){var s=n._reactRootContainer;if(s){var r=s;if("function"==typeof o){var i=o;o=function(){var e=Hd(r);i.call(e)}}Vd(t,r,e,o)}else r=function(e,t,n,a,o){if(o){if("function"==typeof a){var s=a;a=function(){var e=Hd(r);s.call(e)}}var r=Qd(t,a,e,0,null,!1,0,"",Jd);return e._reactRootContainer=r,e[fo]=r.current,Ua(8===e.nodeType?e.parentNode:e),ld(),r}for(;o=e.lastChild;)e.removeChild(o);if("function"==typeof a){var i=a;a=function(){var e=Hd(c);i.call(e)}}var c=$d(e,0,!1,null,0,!1,0,"",Jd);return e._reactRootContainer=c,e[fo]=c.current,Ua(8===e.nodeType?e.parentNode:e),ld((function(){Vd(t,c,n,a)})),c}(n,t,e,o,a);return Hd(r)}Kd.prototype.render=Xd.prototype.render=function(e){var t=this._internalRoot;if(null===t)throw Error(s(409));Vd(e,t,null,null)},Kd.prototype.unmount=Xd.prototype.unmount=function(){var e=this._internalRoot;if(null!==e){this._internalRoot=null;var t=e.containerInfo;ld((function(){Vd(null,e,null,null)})),t[fo]=null}},Kd.prototype.unstable_scheduleHydration=function(e){if(e){var t=St();e={blockedOn:null,target:e,priority:t};for(var n=0;n<Rt.length&&0!==t&&t<Rt[n].priority;n++);Rt.splice(n,0,e),0===n&&Dt(e)}},xt=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var n=lt(t.pendingLanes);0!==n&&(yt(t,1|n),od(t,Ye()),!(6&jc)&&(Qc=Ye()+500,Qo()))}break;case 13:ld((function(){var t=Ls(e,1);if(null!==t){var n=td();ad(t,e,1,n)}})),qd(e,1)}},wt=function(e){if(13===e.tag){var t=Ls(e,134217728);if(null!==t)ad(t,e,134217728,td());qd(e,134217728)}},_t=function(e){if(13===e.tag){var t=nd(e),n=Ls(e,t);if(null!==n)ad(n,e,t,td());qd(e,t)}},St=function(){return vt},Et=function(e,t){var n=vt;try{return vt=e,t()}finally{vt=n}},we=function(e,t,n){switch(t){case"input":if(Z(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var a=n[t];if(a!==e&&a.form===e.form){var o=wo(a);if(!o)throw Error(s(90));q(a),Z(a,o)}}}break;case"textarea":se(e,n);break;case"select":null!=(t=n.value)&&ne(e,!!n.multiple,t,!1)}},Ae=ud,je=ld;var tu={usingClientEntryPoint:!1,Events:[ko,xo,wo,Ce,Te,ud]},nu={findFiberByHostInstance:vo,bundleType:0,version:"18.2.0",rendererPackageName:"react-dom"},au={bundleType:nu.bundleType,version:nu.version,rendererPackageName:nu.rendererPackageName,rendererConfig:nu.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:k.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=He(e))?null:e.stateNode},findFiberByHostInstance:nu.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.2.0-next-9e3b772b8-20220608"};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var ou=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!ou.isDisabled&&ou.supportsFiber)try{ot=ou.inject(au),st=ou}catch(ue){}}t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=tu,t.createPortal=function(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!Yd(t))throw Error(s(200));return function(e,t,n){var a=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:w,key:null==a?null:""+a,children:e,containerInfo:t,implementation:n}}(e,t,null,n)},t.createRoot=function(e,t){if(!Yd(e))throw Error(s(299));var n=!1,a="",o=Gd;return null!=t&&(!0===t.unstable_strictMode&&(n=!0),void 0!==t.identifierPrefix&&(a=t.identifierPrefix),void 0!==t.onRecoverableError&&(o=t.onRecoverableError)),t=$d(e,1,!1,null,0,n,0,a,o),e[fo]=t.current,Ua(8===e.nodeType?e.parentNode:e),new Xd(t)},t.findDOMNode=function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternals;if(void 0===t){if("function"==typeof e.render)throw Error(s(188));throw e=Object.keys(e).join(","),Error(s(268,e))}return e=null===(e=He(t))?null:e.stateNode},t.flushSync=function(e){return ld(e)},t.hydrate=function(e,t,n){if(!Zd(t))throw Error(s(200));return eu(null,e,t,!0,n)},t.hydrateRoot=function(e,t,n){if(!Yd(e))throw Error(s(405));var a=null!=n&&n.hydratedSources||null,o=!1,r="",i=Gd;if(null!=n&&(!0===n.unstable_strictMode&&(o=!0),void 0!==n.identifierPrefix&&(r=n.identifierPrefix),void 0!==n.onRecoverableError&&(i=n.onRecoverableError)),t=Qd(t,null,e,1,null!=n?n:null,o,0,r,i),e[fo]=t.current,Ua(e),a)for(e=0;e<a.length;e++)o=(o=(n=a[e])._getVersion)(n._source),null==t.mutableSourceEagerHydrationData?t.mutableSourceEagerHydrationData=[n,o]:t.mutableSourceEagerHydrationData.push(n,o);return new Kd(t)},t.render=function(e,t,n){if(!Zd(t))throw Error(s(200));return eu(null,e,t,!1,n)},t.unmountComponentAtNode=function(e){if(!Zd(e))throw Error(s(40));return!!e._reactRootContainer&&(ld((function(){eu(null,null,e,!1,(function(){e._reactRootContainer=null,e[fo]=null}))})),!0)},t.unstable_batchedUpdates=ud,t.unstable_renderSubtreeIntoContainer=function(e,t,n,a){if(!Zd(n))throw Error(s(200));if(null==e||void 0===e._reactInternals)throw Error(s(38));return eu(e,t,n,!1,a)},t.version="18.2.0-next-9e3b772b8-20220608"},5338:(e,t,n)=>{"use strict";var a=n(40961);t.createRoot=a.createRoot,t.hydrateRoot=a.hydrateRoot},40961:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(22551)},30115:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,a="function"==typeof Set,o="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function s(e,r){if(e===r)return!0;if(e&&r&&"object"==typeof e&&"object"==typeof r){if(e.constructor!==r.constructor)return!1;var i,c,d,u;if(Array.isArray(e)){if((i=e.length)!=r.length)return!1;for(c=i;0!=c--;)if(!s(e[c],r[c]))return!1;return!0}if(n&&e instanceof Map&&r instanceof Map){if(e.size!==r.size)return!1;for(u=e.entries();!(c=u.next()).done;)if(!r.has(c.value[0]))return!1;for(u=e.entries();!(c=u.next()).done;)if(!s(c.value[1],r.get(c.value[0])))return!1;return!0}if(a&&e instanceof Set&&r instanceof Set){if(e.size!==r.size)return!1;for(u=e.entries();!(c=u.next()).done;)if(!r.has(c.value[0]))return!1;return!0}if(o&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(r)){if((i=e.length)!=r.length)return!1;for(c=i;0!=c--;)if(e[c]!==r[c])return!1;return!0}if(e.constructor===RegExp)return e.source===r.source&&e.flags===r.flags;if(e.valueOf!==Object.prototype.valueOf&&"function"==typeof e.valueOf&&"function"==typeof r.valueOf)return e.valueOf()===r.valueOf();if(e.toString!==Object.prototype.toString&&"function"==typeof e.toString&&"function"==typeof r.toString)return e.toString()===r.toString();if((i=(d=Object.keys(e)).length)!==Object.keys(r).length)return!1;for(c=i;0!=c--;)if(!Object.prototype.hasOwnProperty.call(r,d[c]))return!1;if(t&&e instanceof Element)return!1;for(c=i;0!=c--;)if(("_owner"!==d[c]&&"__v"!==d[c]&&"__o"!==d[c]||!e.$$typeof)&&!s(e[d[c]],r[d[c]]))return!1;return!0}return e!=e&&r!=r}e.exports=function(e,t){try{return s(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},80545:(e,t,n)=>{"use strict";n.d(t,{mg:()=>J,vd:()=>H});var a=n(96540),o=n(5556),s=n.n(o),r=n(30115),i=n.n(r),c=n(20311),d=n.n(c),u=n(2833),l=n.n(u);function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e},p.apply(this,arguments)}function g(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,m(e,t)}function m(e,t){return m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},m(e,t)}function f(e,t){if(null==e)return{};var n,a,o={},s=Object.keys(e);for(a=0;a<s.length;a++)t.indexOf(n=s[a])>=0||(o[n]=e[n]);return o}var h={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},y={type:["application/ld+json"]},v={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},k=Object.keys(h).map((function(e){return h[e]})),x={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},w=Object.keys(x).reduce((function(e,t){return e[x[t]]=t,e}),{}),_=function(e,t){for(var n=e.length-1;n>=0;n-=1){var a=e[n];if(Object.prototype.hasOwnProperty.call(a,t))return a[t]}return null},S=function(e){var t=_(e,h.TITLE),n=_(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var a=_(e,"defaultTitle");return t||a||void 0},E=function(e){return _(e,"onChangeClientState")||function(){}},C=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return p({},e,t)}),{})},T=function(e,t){return t.filter((function(e){return void 0!==e[h.BASE]})).map((function(e){return e[h.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var a=Object.keys(n),o=0;o<a.length;o+=1){var s=a[o].toLowerCase();if(-1!==e.indexOf(s)&&n[s])return t.concat(n)}return t}),[])},A=function(e,t,n){var a={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var o={};n.filter((function(e){for(var n,s=Object.keys(e),r=0;r<s.length;r+=1){var i=s[r],c=i.toLowerCase();-1===t.indexOf(c)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===c&&"stylesheet"===e[c].toLowerCase()||(n=c),-1===t.indexOf(i)||"innerHTML"!==i&&"cssText"!==i&&"itemprop"!==i||(n=i)}if(!n||!e[n])return!1;var d=e[n].toLowerCase();return a[n]||(a[n]={}),o[n]||(o[n]={}),!a[n][d]&&(o[n][d]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var s=Object.keys(o),r=0;r<s.length;r+=1){var i=s[r],c=p({},a[i],o[i]);a[i]=c}return e}),[]).reverse()},j=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},L=function(e){return Array.isArray(e)?e.join(""):e},P=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),a=0;a<n.length;a+=1)if(t[n[a]]&&t[n[a]].includes(e[n[a]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},N=function(e,t){var n;return p({},e,((n={})[t]=void 0,n))},R=[h.NOSCRIPT,h.SCRIPT,h.STYLE],O=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},I=function(e){return Object.keys(e).reduce((function(t,n){var a=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+a:a}),"")},F=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[x[n]||n]=e[n],t}),t)},D=function(e,t){return t.map((function(t,n){var o,s=((o={key:n})["data-rh"]=!0,o);return Object.keys(t).forEach((function(e){var n=x[e]||e;"innerHTML"===n||"cssText"===n?s.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:s[n]=t[e]})),a.createElement(e,s)}))},M=function(e,t,n){switch(e){case h.TITLE:return{toComponent:function(){return n=t.titleAttributes,(o={key:e=t.title})["data-rh"]=!0,s=F(n,o),[a.createElement(h.TITLE,s,e)];var e,n,o,s},toString:function(){return function(e,t,n,a){var o=I(n),s=L(t);return o?"<"+e+' data-rh="true" '+o+">"+O(s,a)+"</"+e+">":"<"+e+' data-rh="true">'+O(s,a)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return F(t)},toString:function(){return I(t)}};default:return{toComponent:function(){return D(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,a){var o=Object.keys(a).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var o=void 0===a[t]?t:t+'="'+O(a[t],n)+'"';return e?e+" "+o:o}),""),s=a.innerHTML||a.cssText||"",r=-1===R.indexOf(e);return t+"<"+e+' data-rh="true" '+o+(r?"/>":">"+s+"</"+e+">")}),"")}(e,t,n)}}}},z=function(e){var t=e.baseTag,n=e.bodyAttributes,a=e.encode,o=e.htmlAttributes,s=e.noscriptTags,r=e.styleTags,i=e.title,c=void 0===i?"":i,d=e.titleAttributes,u=e.linkTags,l=e.metaTags,p=e.scriptTags,g={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var m=function(e){var t=e.linkTags,n=e.scriptTags,a=e.encode,o=P(e.metaTags,v),s=P(t,b),r=P(n,y);return{priorityMethods:{toComponent:function(){return[].concat(D(h.META,o.priority),D(h.LINK,s.priority),D(h.SCRIPT,r.priority))},toString:function(){return M(h.META,o.priority,a)+" "+M(h.LINK,s.priority,a)+" "+M(h.SCRIPT,r.priority,a)}},metaTags:o.default,linkTags:s.default,scriptTags:r.default}}(e);g=m.priorityMethods,u=m.linkTags,l=m.metaTags,p=m.scriptTags}return{priority:g,base:M(h.BASE,t,a),bodyAttributes:M("bodyAttributes",n,a),htmlAttributes:M("htmlAttributes",o,a),link:M(h.LINK,u,a),meta:M(h.META,l,a),noscript:M(h.NOSCRIPT,s,a),script:M(h.SCRIPT,p,a),style:M(h.STYLE,r,a),title:M(h.TITLE,{title:c,titleAttributes:d},a)}},B=[],$=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?B:n.instances},add:function(e){(n.canUseDOM?B:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?B:n.instances).indexOf(e);(n.canUseDOM?B:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=z({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},U=a.createContext({}),Q=s().shape({setHelmet:s().func,helmetInstances:s().shape({get:s().func,add:s().func,remove:s().func})}),V="undefined"!=typeof document,H=function(e){function t(n){var a;return(a=e.call(this,n)||this).helmetData=new $(a.props.context,t.canUseDOM),a}return g(t,e),t.prototype.render=function(){return a.createElement(U.Provider,{value:this.helmetData.value},this.props.children)},t}(a.Component);H.canUseDOM=V,H.propTypes={context:s().shape({helmet:s().shape()}),children:s().node.isRequired},H.defaultProps={context:{}},H.displayName="HelmetProvider";var W=function(e,t){var n,a=document.head||document.querySelector(h.HEAD),o=a.querySelectorAll(e+"[data-rh]"),s=[].slice.call(o),r=[];return t&&t.length&&t.forEach((function(t){var a=document.createElement(e);for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&("innerHTML"===o?a.innerHTML=t.innerHTML:"cssText"===o?a.styleSheet?a.styleSheet.cssText=t.cssText:a.appendChild(document.createTextNode(t.cssText)):a.setAttribute(o,void 0===t[o]?"":t[o]));a.setAttribute("data-rh","true"),s.some((function(e,t){return n=t,a.isEqualNode(e)}))?s.splice(n,1):r.push(a)})),s.forEach((function(e){return e.parentNode.removeChild(e)})),r.forEach((function(e){return a.appendChild(e)})),{oldTags:s,newTags:r}},q=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var a=n.getAttribute("data-rh"),o=a?a.split(","):[],s=[].concat(o),r=Object.keys(t),i=0;i<r.length;i+=1){var c=r[i],d=t[c]||"";n.getAttribute(c)!==d&&n.setAttribute(c,d),-1===o.indexOf(c)&&o.push(c);var u=s.indexOf(c);-1!==u&&s.splice(u,1)}for(var l=s.length-1;l>=0;l-=1)n.removeAttribute(s[l]);o.length===s.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==r.join(",")&&n.setAttribute("data-rh",r.join(","))}},G=function(e,t){var n=e.baseTag,a=e.htmlAttributes,o=e.linkTags,s=e.metaTags,r=e.noscriptTags,i=e.onChangeClientState,c=e.scriptTags,d=e.styleTags,u=e.title,l=e.titleAttributes;q(h.BODY,e.bodyAttributes),q(h.HTML,a),function(e,t){void 0!==e&&document.title!==e&&(document.title=L(e)),q(h.TITLE,t)}(u,l);var p={baseTag:W(h.BASE,n),linkTags:W(h.LINK,o),metaTags:W(h.META,s),noscriptTags:W(h.NOSCRIPT,r),scriptTags:W(h.SCRIPT,c),styleTags:W(h.STYLE,d)},g={},m={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,a=t.oldTags;n.length&&(g[e]=n),a.length&&(m[e]=p[e].oldTags)})),t&&t(),i(e,g,m)},X=null,K=function(e){function t(){for(var t,n=arguments.length,a=new Array(n),o=0;o<n;o++)a[o]=arguments[o];return(t=e.call.apply(e,[this].concat(a))||this).rendered=!1,t}g(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!l()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,a=n.setHelmet,o=null,s=(e=n.helmetInstances.get().map((function(e){var t=p({},e.props);return delete t.context,t})),{baseTag:T(["href"],e),bodyAttributes:C("bodyAttributes",e),defer:_(e,"defer"),encode:_(e,"encodeSpecialCharacters"),htmlAttributes:C("htmlAttributes",e),linkTags:A(h.LINK,["rel","href"],e),metaTags:A(h.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:A(h.NOSCRIPT,["innerHTML"],e),onChangeClientState:E(e),scriptTags:A(h.SCRIPT,["src","innerHTML"],e),styleTags:A(h.STYLE,["cssText"],e),title:S(e),titleAttributes:C("titleAttributes",e),prioritizeSeoTags:j(e,"prioritizeSeoTags")});H.canUseDOM?(t=s,X&&cancelAnimationFrame(X),t.defer?X=requestAnimationFrame((function(){G(t,(function(){X=null}))})):(G(t),X=null)):z&&(o=z(s)),a(o)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(a.Component);K.propTypes={context:Q.isRequired},K.displayName="HelmetDispatcher";var Y=["children"],Z=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}g(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!i()(N(this.props,"helmetData"),N(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case h.SCRIPT:case h.NOSCRIPT:return{innerHTML:t};case h.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,a=e.arrayTypeChildren;return p({},a,((t={})[n.type]=[].concat(a[n.type]||[],[p({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,a=e.child,o=e.newProps,s=e.newChildProps,r=e.nestedChildren;switch(a.type){case h.TITLE:return p({},o,((t={})[a.type]=r,t.titleAttributes=p({},s),t));case h.BODY:return p({},o,{bodyAttributes:p({},s)});case h.HTML:return p({},o,{htmlAttributes:p({},s)});default:return p({},o,((n={})[a.type]=p({},s),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=p({},t);return Object.keys(e).forEach((function(t){var a;n=p({},n,((a={})[t]=e[t],a))})),n},n.warnOnInvalidChildren=function(e,t){return d()(k.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+k.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),d()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,o={};return a.Children.forEach(e,(function(e){if(e&&e.props){var a=e.props,s=a.children,r=f(a,Y),i=Object.keys(r).reduce((function(e,t){return e[w[t]||t]=r[t],e}),{}),c=e.type;switch("symbol"==typeof c?c=c.toString():n.warnOnInvalidChildren(e,s),c){case h.FRAGMENT:t=n.mapChildrenToProps(s,t);break;case h.LINK:case h.META:case h.NOSCRIPT:case h.SCRIPT:case h.STYLE:o=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:o,newChildProps:i,nestedChildren:s});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:i,nestedChildren:s})}}})),this.mapArrayTypeChildrenToProps(o,t)},n.render=function(){var e=this.props,t=e.children,n=f(e,Z),o=p({},n),s=n.helmetData;return t&&(o=this.mapChildrenToProps(t,o)),!s||s instanceof $||(s=new $(s.context,s.instances)),s?a.createElement(K,p({},o,{context:s.value,helmetData:void 0})):a.createElement(U.Consumer,null,(function(e){return a.createElement(K,p({},o,{context:e}))}))},t}(a.Component);J.propTypes={base:s().object,bodyAttributes:s().object,children:s().oneOfType([s().arrayOf(s().node),s().node]),defaultTitle:s().string,defer:s().bool,encodeSpecialCharacters:s().bool,htmlAttributes:s().object,link:s().arrayOf(s().object),meta:s().arrayOf(s().object),noscript:s().arrayOf(s().object),onChangeClientState:s().func,script:s().arrayOf(s().object),style:s().arrayOf(s().object),title:s().string,titleAttributes:s().object,titleTemplate:s().string,prioritizeSeoTags:s().bool,helmetData:s().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},22799:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,a=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,s=n?Symbol.for("react.fragment"):60107,r=n?Symbol.for("react.strict_mode"):60108,i=n?Symbol.for("react.profiler"):60114,c=n?Symbol.for("react.provider"):60109,d=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,l=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,g=n?Symbol.for("react.suspense"):60113,m=n?Symbol.for("react.suspense_list"):60120,f=n?Symbol.for("react.memo"):60115,h=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,y=n?Symbol.for("react.fundamental"):60117,v=n?Symbol.for("react.responder"):60118,k=n?Symbol.for("react.scope"):60119;function x(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case a:switch(e=e.type){case u:case l:case s:case i:case r:case g:return e;default:switch(e=e&&e.$$typeof){case d:case p:case h:case f:case c:return e;default:return t}}case o:return t}}}function w(e){return x(e)===l}t.AsyncMode=u,t.ConcurrentMode=l,t.ContextConsumer=d,t.ContextProvider=c,t.Element=a,t.ForwardRef=p,t.Fragment=s,t.Lazy=h,t.Memo=f,t.Portal=o,t.Profiler=i,t.StrictMode=r,t.Suspense=g,t.isAsyncMode=function(e){return w(e)||x(e)===u},t.isConcurrentMode=w,t.isContextConsumer=function(e){return x(e)===d},t.isContextProvider=function(e){return x(e)===c},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===a},t.isForwardRef=function(e){return x(e)===p},t.isFragment=function(e){return x(e)===s},t.isLazy=function(e){return x(e)===h},t.isMemo=function(e){return x(e)===f},t.isPortal=function(e){return x(e)===o},t.isProfiler=function(e){return x(e)===i},t.isStrictMode=function(e){return x(e)===r},t.isSuspense=function(e){return x(e)===g},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===s||e===l||e===i||e===r||e===g||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===h||e.$$typeof===f||e.$$typeof===c||e.$$typeof===d||e.$$typeof===p||e.$$typeof===y||e.$$typeof===v||e.$$typeof===k||e.$$typeof===b)},t.typeOf=x},44363:(e,t,n)=>{"use strict";e.exports=n(22799)},53259:(e,t,n)=>{"use strict";function a(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function o(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(){return r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e},r.apply(this,arguments)}var i=n(96540),c=n(5556),d=[],u=[];function l(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function p(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(a){var o=l(e[a]);o.loading?t.loading=!0:(t.loaded[a]=o.loaded,t.error=o.error),n.push(o.promise),o.promise.then((function(e){t.loaded[a]=e})).catch((function(e){t.error=e}))}))}catch(a){t.error=a}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function g(e,t){return i.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function m(e,t){var l,p;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var m=r({loader:null,loading:null,delay:200,timeout:null,render:g,webpack:null,modules:null},t),f=null;function h(){return f||(f=e(m.loader)),f.promise}return d.push(h),"function"==typeof m.webpack&&u.push((function(){if((0,m.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return h()})),p=l=function(t){function n(n){var a;return s(o(o(a=t.call(this,n)||this)),"retry",(function(){a.setState({error:null,loading:!0,timedOut:!1}),f=e(m.loader),a._loadModule()})),h(),a.state={error:f.error,pastDelay:!1,timedOut:!1,loading:f.loading,loaded:f.loaded},a}a(n,t),n.preload=function(){return h()};var r=n.prototype;return r.UNSAFE_componentWillMount=function(){this._loadModule()},r.componentDidMount=function(){this._mounted=!0},r._loadModule=function(){var e=this;if(this.context.loadable&&Array.isArray(m.modules)&&m.modules.forEach((function(t){e.context.loadable.report(t)})),f.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof m.delay&&(0===m.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),m.delay)),"number"==typeof m.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),m.timeout));var n=function(){t({error:f.error,loaded:f.loaded,loading:f.loading}),e._clearTimeouts()};f.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},r.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},r._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},r.render=function(){return this.state.loading||this.state.error?i.createElement(m.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?m.render(this.state.loaded,this.props):null},n}(i.Component),s(l,"contextTypes",{loadable:c.shape({report:c.func.isRequired})}),p}function f(e){return m(l,e)}f.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return m(p,e)};var h=function(e){function t(){return e.apply(this,arguments)||this}a(t,e);var n=t.prototype;return n.getChildContext=function(){return{loadable:{report:this.props.report}}},n.render=function(){return i.Children.only(this.props.children)},t}(i.Component);function b(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return b(e)}))}s(h,"propTypes",{report:c.func.isRequired}),s(h,"childContextTypes",{loadable:c.shape({report:c.func.isRequired}).isRequired}),f.Capture=h,f.preloadAll=function(){return new Promise((function(e,t){b(d).then(e,t)}))},f.preloadReady=function(){return new Promise((function(e,t){b(u).then(e,e)}))},e.exports=f},22831:(e,t,n)=>{"use strict";n.d(t,{u:()=>r,v:()=>i});var a=n(56347),o=n(58168),s=n(96540);function r(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var o=e.path?(0,a.B6)(t,e):n.length?n[n.length-1].match:a.Ix.computeRootMatch(t);return o&&(n.push({route:e,match:o}),e.routes&&r(e.routes,t,n)),o})),n}function i(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?s.createElement(a.dO,n,e.map((function(e,n){return s.createElement(a.qh,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,o.A)({},n,{},t,{route:e})):s.createElement(e.component,(0,o.A)({},n,t,{route:e}))}})}))):null}},54625:(e,t,n)=>{"use strict";n.d(t,{Kd:()=>u,N_:()=>h,k2:()=>v});var a=n(56347),o=n(42892),s=n(96540),r=n(31513),i=n(58168),c=n(98587),d=n(11561),u=function(e){function t(){for(var t,n=arguments.length,a=new Array(n),o=0;o<n;o++)a[o]=arguments[o];return(t=e.call.apply(e,[this].concat(a))||this).history=(0,r.zR)(t.props),t}return(0,o.A)(t,e),t.prototype.render=function(){return s.createElement(a.Ix,{history:this.history,children:this.props.children})},t}(s.Component);s.Component;var l=function(e,t){return"function"==typeof e?e(t):e},p=function(e,t){return"string"==typeof e?(0,r.yJ)(e,null,null,t):e},g=function(e){return e},m=s.forwardRef;void 0===m&&(m=g);var f=m((function(e,t){var n=e.innerRef,a=e.navigate,o=e.onClick,r=(0,c.A)(e,["innerRef","navigate","onClick"]),d=r.target,u=(0,i.A)({},r,{onClick:function(e){try{o&&o(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||d&&"_self"!==d||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),a())}});return u.ref=g!==m&&t||n,s.createElement("a",u)}));var h=m((function(e,t){var n=e.component,o=void 0===n?f:n,u=e.replace,h=e.to,b=e.innerRef,y=(0,c.A)(e,["component","replace","to","innerRef"]);return s.createElement(a.XZ.Consumer,null,(function(e){e||(0,d.A)(!1);var n=e.history,a=p(l(h,e.location),e.location),c=a?n.createHref(a):"",f=(0,i.A)({},y,{href:c,navigate:function(){var t=l(h,e.location),a=(0,r.AO)(e.location)===(0,r.AO)(p(t));(u||a?n.replace:n.push)(t)}});return g!==m?f.ref=t||b:f.innerRef=b,s.createElement(o,f)}))})),b=function(e){return e},y=s.forwardRef;void 0===y&&(y=b);var v=y((function(e,t){var n=e["aria-current"],o=void 0===n?"page":n,r=e.activeClassName,u=void 0===r?"active":r,g=e.activeStyle,m=e.className,f=e.exact,v=e.isActive,k=e.location,x=e.sensitive,w=e.strict,_=e.style,S=e.to,E=e.innerRef,C=(0,c.A)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return s.createElement(a.XZ.Consumer,null,(function(e){e||(0,d.A)(!1);var n=k||e.location,r=p(l(S,n),n),c=r.pathname,T=c&&c.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),A=T?(0,a.B6)(n.pathname,{path:T,exact:f,sensitive:x,strict:w}):null,j=!!(v?v(A,n):A),L="function"==typeof m?m(j):m,P="function"==typeof _?_(j):_;j&&(L=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(L,u),P=(0,i.A)({},P,g));var N=(0,i.A)({"aria-current":j&&o||null,className:L,style:P,to:r},C);return b!==y?N.ref=t||E:N.innerRef=E,s.createElement(h,N)}))}))},56347:(e,t,n)=>{"use strict";n.d(t,{B6:()=>_,Ix:()=>v,W6:()=>N,XZ:()=>y,dO:()=>L,qh:()=>S,zy:()=>R});var a=n(42892),o=n(96540),s=n(5556),r=n.n(s),i=n(31513),c=n(11561),d=n(58168),u=n(35302),l=n.n(u),p=(n(44363),n(98587)),g=(n(4146),1073741823),m="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var f=o.createContext||function(e,t){var n,s,i="__create-react-context-"+function(){var e="__global_unique_id__";return m[e]=(m[e]||0)+1}()+"__",c=function(e){function n(){for(var t,n,a,o=arguments.length,s=new Array(o),r=0;r<o;r++)s[r]=arguments[r];return(t=e.call.apply(e,[this].concat(s))||this).emitter=(n=t.props.value,a=[],{on:function(e){a.push(e)},off:function(e){a=a.filter((function(t){return t!==e}))},get:function(){return n},set:function(e,t){n=e,a.forEach((function(e){return e(n,t)}))}}),t}(0,a.A)(n,e);var o=n.prototype;return o.getChildContext=function(){var e;return(e={})[i]=this.emitter,e},o.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,a=this.props.value,o=e.value;((s=a)===(r=o)?0!==s||1/s==1/r:s!=s&&r!=r)?n=0:(n="function"==typeof t?t(a,o):g,0!==(n|=0)&&this.emitter.set(e.value,n))}var s,r},o.render=function(){return this.props.children},n}(o.Component);c.childContextTypes=((n={})[i]=r().object.isRequired,n);var d=function(t){function n(){for(var e,n=arguments.length,a=new Array(n),o=0;o<n;o++)a[o]=arguments[o];return(e=t.call.apply(t,[this].concat(a))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){(0|e.observedBits)&n&&e.setState({value:e.getValue()})},e}(0,a.A)(n,t);var o=n.prototype;return o.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?g:t},o.componentDidMount=function(){this.context[i]&&this.context[i].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?g:e},o.componentWillUnmount=function(){this.context[i]&&this.context[i].off(this.onUpdate)},o.getValue=function(){return this.context[i]?this.context[i].get():e},o.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(o.Component);return d.contextTypes=((s={})[i]=r().object,s),{Provider:c,Consumer:d}},h=function(e){var t=f();return t.displayName=e,t},b=h("Router-History"),y=h("Router"),v=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,a.A)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return o.createElement(y.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},o.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(o.Component);o.Component;o.Component;var k={},x=1e4,w=0;function _(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,a=n.path,o=n.exact,s=void 0!==o&&o,r=n.strict,i=void 0!==r&&r,c=n.sensitive,d=void 0!==c&&c;return[].concat(a).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var a=function(e,t){var n=""+t.end+t.strict+t.sensitive,a=k[n]||(k[n]={});if(a[e])return a[e];var o=[],s={regexp:l()(e,o,t),keys:o};return w<x&&(a[e]=s,w++),s}(n,{end:s,strict:i,sensitive:d}),o=a.regexp,r=a.keys,c=o.exec(e);if(!c)return null;var u=c[0],p=c.slice(1),g=e===u;return s&&!g?null:{path:n,url:"/"===n&&""===u?"/":u,isExact:g,params:r.reduce((function(e,t,n){return e[t.name]=p[n],e}),{})}}),null)}var S=function(e){function t(){return e.apply(this,arguments)||this}return(0,a.A)(t,e),t.prototype.render=function(){var e=this;return o.createElement(y.Consumer,null,(function(t){t||(0,c.A)(!1);var n=e.props.location||t.location,a=e.props.computedMatch?e.props.computedMatch:e.props.path?_(n.pathname,e.props):t.match,s=(0,d.A)({},t,{location:n,match:a}),r=e.props,i=r.children,u=r.component,l=r.render;return Array.isArray(i)&&function(e){return 0===o.Children.count(e)}(i)&&(i=null),o.createElement(y.Provider,{value:s},s.match?i?"function"==typeof i?i(s):i:u?o.createElement(u,s):l?l(s):null:"function"==typeof i?i(s):null)}))},t}(o.Component);function E(e){return"/"===e.charAt(0)?e:"/"+e}function C(e,t){if(!e)return t;var n=E(e);return 0!==t.pathname.indexOf(n)?t:(0,d.A)({},t,{pathname:t.pathname.substr(n.length)})}function T(e){return"string"==typeof e?e:(0,i.AO)(e)}function A(e){return function(){(0,c.A)(!1)}}function j(){}o.Component;var L=function(e){function t(){return e.apply(this,arguments)||this}return(0,a.A)(t,e),t.prototype.render=function(){var e=this;return o.createElement(y.Consumer,null,(function(t){t||(0,c.A)(!1);var n,a,s=e.props.location||t.location;return o.Children.forEach(e.props.children,(function(e){if(null==a&&o.isValidElement(e)){n=e;var r=e.props.path||e.props.from;a=r?_(s.pathname,(0,d.A)({},e.props,{path:r})):t.match}})),a?o.cloneElement(n,{location:s,computedMatch:a}):null}))},t}(o.Component);var P=o.useContext;function N(){return P(b)}function R(){return P(y).location}},21020:(e,t,n)=>{"use strict";var a=n(96540),o=Symbol.for("react.element"),s=Symbol.for("react.fragment"),r=Object.prototype.hasOwnProperty,i=a.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,c={key:!0,ref:!0,__self:!0,__source:!0};function d(e,t,n){var a,s={},d=null,u=null;for(a in void 0!==n&&(d=""+n),void 0!==t.key&&(d=""+t.key),void 0!==t.ref&&(u=t.ref),t)r.call(t,a)&&!c.hasOwnProperty(a)&&(s[a]=t[a]);if(e&&e.defaultProps)for(a in t=e.defaultProps)void 0===s[a]&&(s[a]=t[a]);return{$$typeof:o,type:e,key:d,ref:u,props:s,_owner:i.current}}t.Fragment=s,t.jsx=d,t.jsxs=d},15287:(e,t)=>{"use strict";var n=Symbol.for("react.element"),a=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),r=Symbol.for("react.profiler"),i=Symbol.for("react.provider"),c=Symbol.for("react.context"),d=Symbol.for("react.forward_ref"),u=Symbol.for("react.suspense"),l=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),g=Symbol.iterator;var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},f=Object.assign,h={};function b(e,t,n){this.props=e,this.context=t,this.refs=h,this.updater=n||m}function y(){}function v(e,t,n){this.props=e,this.context=t,this.refs=h,this.updater=n||m}b.prototype.isReactComponent={},b.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},b.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},y.prototype=b.prototype;var k=v.prototype=new y;k.constructor=v,f(k,b.prototype),k.isPureReactComponent=!0;var x=Array.isArray,w=Object.prototype.hasOwnProperty,_={current:null},S={key:!0,ref:!0,__self:!0,__source:!0};function E(e,t,a){var o,s={},r=null,i=null;if(null!=t)for(o in void 0!==t.ref&&(i=t.ref),void 0!==t.key&&(r=""+t.key),t)w.call(t,o)&&!S.hasOwnProperty(o)&&(s[o]=t[o]);var c=arguments.length-2;if(1===c)s.children=a;else if(1<c){for(var d=Array(c),u=0;u<c;u++)d[u]=arguments[u+2];s.children=d}if(e&&e.defaultProps)for(o in c=e.defaultProps)void 0===s[o]&&(s[o]=c[o]);return{$$typeof:n,type:e,key:r,ref:i,props:s,_owner:_.current}}function C(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}var T=/\/+/g;function A(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function j(e,t,o,s,r){var i=typeof e;"undefined"!==i&&"boolean"!==i||(e=null);var c=!1;if(null===e)c=!0;else switch(i){case"string":case"number":c=!0;break;case"object":switch(e.$$typeof){case n:case a:c=!0}}if(c)return r=r(c=e),e=""===s?"."+A(c,0):s,x(r)?(o="",null!=e&&(o=e.replace(T,"$&/")+"/"),j(r,t,o,"",(function(e){return e}))):null!=r&&(C(r)&&(r=function(e,t){return{$$typeof:n,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(r,o+(!r.key||c&&c.key===r.key?"":(""+r.key).replace(T,"$&/")+"/")+e)),t.push(r)),1;if(c=0,s=""===s?".":s+":",x(e))for(var d=0;d<e.length;d++){var u=s+A(i=e[d],d);c+=j(i,t,o,u,r)}else if(u=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=g&&e[g]||e["@@iterator"])?e:null}(e),"function"==typeof u)for(e=u.call(e),d=0;!(i=e.next()).done;)c+=j(i=i.value,t,o,u=s+A(i,d++),r);else if("object"===i)throw t=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.");return c}function L(e,t,n){if(null==e)return e;var a=[],o=0;return j(e,a,"","",(function(e){return t.call(n,e,o++)})),a}function P(e){if(-1===e._status){var t=e._result;(t=t()).then((function(t){0!==e._status&&-1!==e._status||(e._status=1,e._result=t)}),(function(t){0!==e._status&&-1!==e._status||(e._status=2,e._result=t)})),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var N={current:null},R={transition:null},O={ReactCurrentDispatcher:N,ReactCurrentBatchConfig:R,ReactCurrentOwner:_};t.Children={map:L,forEach:function(e,t,n){L(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return L(e,(function(){t++})),t},toArray:function(e){return L(e,(function(e){return e}))||[]},only:function(e){if(!C(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},t.Component=b,t.Fragment=o,t.Profiler=r,t.PureComponent=v,t.StrictMode=s,t.Suspense=u,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=O,t.cloneElement=function(e,t,a){if(null==e)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var o=f({},e.props),s=e.key,r=e.ref,i=e._owner;if(null!=t){if(void 0!==t.ref&&(r=t.ref,i=_.current),void 0!==t.key&&(s=""+t.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(d in t)w.call(t,d)&&!S.hasOwnProperty(d)&&(o[d]=void 0===t[d]&&void 0!==c?c[d]:t[d])}var d=arguments.length-2;if(1===d)o.children=a;else if(1<d){c=Array(d);for(var u=0;u<d;u++)c[u]=arguments[u+2];o.children=c}return{$$typeof:n,type:e.type,key:s,ref:r,props:o,_owner:i}},t.createContext=function(e){return(e={$$typeof:c,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null}).Provider={$$typeof:i,_context:e},e.Consumer=e},t.createElement=E,t.createFactory=function(e){var t=E.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:d,render:e}},t.isValidElement=C,t.lazy=function(e){return{$$typeof:p,_payload:{_status:-1,_result:e},_init:P}},t.memo=function(e,t){return{$$typeof:l,type:e,compare:void 0===t?null:t}},t.startTransition=function(e){var t=R.transition;R.transition={};try{e()}finally{R.transition=t}},t.unstable_act=function(){throw Error("act(...) is not supported in production builds of React.")},t.useCallback=function(e,t){return N.current.useCallback(e,t)},t.useContext=function(e){return N.current.useContext(e)},t.useDebugValue=function(){},t.useDeferredValue=function(e){return N.current.useDeferredValue(e)},t.useEffect=function(e,t){return N.current.useEffect(e,t)},t.useId=function(){return N.current.useId()},t.useImperativeHandle=function(e,t,n){return N.current.useImperativeHandle(e,t,n)},t.useInsertionEffect=function(e,t){return N.current.useInsertionEffect(e,t)},t.useLayoutEffect=function(e,t){return N.current.useLayoutEffect(e,t)},t.useMemo=function(e,t){return N.current.useMemo(e,t)},t.useReducer=function(e,t,n){return N.current.useReducer(e,t,n)},t.useRef=function(e){return N.current.useRef(e)},t.useState=function(e){return N.current.useState(e)},t.useSyncExternalStore=function(e,t,n){return N.current.useSyncExternalStore(e,t,n)},t.useTransition=function(){return N.current.useTransition()},t.version="18.2.0"},96540:(e,t,n)=>{"use strict";e.exports=n(15287)},74848:(e,t,n)=>{"use strict";e.exports=n(21020)},7463:(e,t)=>{"use strict";function n(e,t){var n=e.length;e.push(t);e:for(;0<n;){var a=n-1>>>1,o=e[a];if(!(0<s(o,t)))break e;e[a]=t,e[n]=o,n=a}}function a(e){return 0===e.length?null:e[0]}function o(e){if(0===e.length)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;e:for(var a=0,o=e.length,r=o>>>1;a<r;){var i=2*(a+1)-1,c=e[i],d=i+1,u=e[d];if(0>s(c,n))d<o&&0>s(u,c)?(e[a]=u,e[d]=n,a=d):(e[a]=c,e[i]=n,a=i);else{if(!(d<o&&0>s(u,n)))break e;e[a]=u,e[d]=n,a=d}}}return t}function s(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if("object"==typeof performance&&"function"==typeof performance.now){var r=performance;t.unstable_now=function(){return r.now()}}else{var i=Date,c=i.now();t.unstable_now=function(){return i.now()-c}}var d=[],u=[],l=1,p=null,g=3,m=!1,f=!1,h=!1,b="function"==typeof setTimeout?setTimeout:null,y="function"==typeof clearTimeout?clearTimeout:null,v="undefined"!=typeof setImmediate?setImmediate:null;function k(e){for(var t=a(u);null!==t;){if(null===t.callback)o(u);else{if(!(t.startTime<=e))break;o(u),t.sortIndex=t.expirationTime,n(d,t)}t=a(u)}}function x(e){if(h=!1,k(e),!f)if(null!==a(d))f=!0,R(w);else{var t=a(u);null!==t&&O(x,t.startTime-e)}}function w(e,n){f=!1,h&&(h=!1,y(C),C=-1),m=!0;var s=g;try{for(k(n),p=a(d);null!==p&&(!(p.expirationTime>n)||e&&!j());){var r=p.callback;if("function"==typeof r){p.callback=null,g=p.priorityLevel;var i=r(p.expirationTime<=n);n=t.unstable_now(),"function"==typeof i?p.callback=i:p===a(d)&&o(d),k(n)}else o(d);p=a(d)}if(null!==p)var c=!0;else{var l=a(u);null!==l&&O(x,l.startTime-n),c=!1}return c}finally{p=null,g=s,m=!1}}"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var _,S=!1,E=null,C=-1,T=5,A=-1;function j(){return!(t.unstable_now()-A<T)}function L(){if(null!==E){var e=t.unstable_now();A=e;var n=!0;try{n=E(!0,e)}finally{n?_():(S=!1,E=null)}}else S=!1}if("function"==typeof v)_=function(){v(L)};else if("undefined"!=typeof MessageChannel){var P=new MessageChannel,N=P.port2;P.port1.onmessage=L,_=function(){N.postMessage(null)}}else _=function(){b(L,0)};function R(e){E=e,S||(S=!0,_())}function O(e,n){C=b((function(){e(t.unstable_now())}),n)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){f||m||(f=!0,R(w))},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):T=0<e?Math.floor(1e3/e):5},t.unstable_getCurrentPriorityLevel=function(){return g},t.unstable_getFirstCallbackNode=function(){return a(d)},t.unstable_next=function(e){switch(g){case 1:case 2:case 3:var t=3;break;default:t=g}var n=g;g=t;try{return e()}finally{g=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=function(){},t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=g;g=e;try{return t()}finally{g=n}},t.unstable_scheduleCallback=function(e,o,s){var r=t.unstable_now();switch("object"==typeof s&&null!==s?s="number"==typeof(s=s.delay)&&0<s?r+s:r:s=r,e){case 1:var i=-1;break;case 2:i=250;break;case 5:i=1073741823;break;case 4:i=1e4;break;default:i=5e3}return e={id:l++,callback:o,priorityLevel:e,startTime:s,expirationTime:i=s+i,sortIndex:-1},s>r?(e.sortIndex=s,n(u,e),null===a(d)&&e===a(u)&&(h?(y(C),C=-1):h=!0,O(x,s-r))):(e.sortIndex=i,n(d,e),f||m||(f=!0,R(w))),e},t.unstable_shouldYield=j,t.unstable_wrapCallback=function(e){var t=g;return function(){var n=g;g=t;try{return e.apply(this,arguments)}finally{g=n}}}},69982:(e,t,n)=>{"use strict";e.exports=n(7463)},2833:e=>{e.exports=function(e,t,n,a){var o=n?n.call(a,e,t):void 0;if(void 0!==o)return!!o;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var s=Object.keys(e),r=Object.keys(t);if(s.length!==r.length)return!1;for(var i=Object.prototype.hasOwnProperty.bind(t),c=0;c<s.length;c++){var d=s[c];if(!i(d))return!1;var u=e[d],l=t[d];if(!1===(o=n?n.call(a,u,l,d):void 0)||void 0===o&&u!==l)return!1}return!0}},4784:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});const a={title:"One platform \u2014 standardized, built and operated by many.",tagline:"Documentation and Community Platform for the Sovereign Cloud Stack",url:"https://docs.scs.community",baseUrl:"/",onBrokenLinks:"throw",onBrokenMarkdownLinks:"warn",favicon:"img/favicon.ico",markdown:{mermaid:!0,format:"mdx",mdx1Compat:{comments:!0,admonitions:!0,headingIds:!0}},organizationName:"SovereignCloudStack",projectName:"docs",i18n:{defaultLocale:"en",locales:["en"],path:"i18n",localeConfigs:{}},presets:[["classic",{docs:{sidebarPath:"/home/runner/work/docs/docs/sidebarsDocs.js",editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/"},blog:{showReadingTime:!0,editUrl:"https://github.com/SovereignCloudStack/docs/tree/main/"},theme:{customCss:["/home/runner/work/docs/docs/src/css/custom.css"]}}]],plugins:[["@docusaurus/plugin-client-redirects",{redirects:[]}],["@docusaurus/plugin-content-docs",{id:"community",path:"community",routeBasePath:"community",sidebarPath:"/home/runner/work/docs/docs/sidebarsCommunity.js"}],["@docusaurus/plugin-content-docs",{id:"contributor-docs",path:"contributor-docs",routeBasePath:"contributor-docs",sidebarPath:"/home/runner/work/docs/docs/sidebarsContributorDocs.js"}],["@docusaurus/plugin-content-docs",{id:"standards",path:"standards",routeBasePath:"standards",sidebarPath:"/home/runner/work/docs/docs/sidebarsStandards.js"}],"./src/plugins/docusaurus-plugin-matomo-analytics/index.js","./src/plugins/docusaurus-plugin-global-data/index.js"],themeConfig:{metadata:[{title:"One platform \u2014 standardized, built and operated by many.",description:"Documentation and Community Platform for the Sovereign Cloud Stack"}],image:"img/summit-social.png",navbar:{title:"",logo:{alt:"SCS",src:"img/logo.svg"},items:[{to:"/standards",label:"Standards",position:"left"},{to:"/docs",label:"For Operators",position:"left"},{to:"/contributor-docs",label:"For Contributors",position:"left"},{to:"/community",label:"Community",position:"left"},{to:"/docs/faq",label:"FAQ",position:"left"},{href:"https://github.com/SovereignCloudStack/docs",label:"GitHub",position:"right"}],hideOnScroll:!1},footer:{style:"light",links:[{title:"Docs",items:[{label:"Contribute",to:"/docs"}]},{title:"Community",items:[{label:"Matrix",href:"https://matrix.to/#/!TiDqlLmEUaXqTemaLc:matrix.org?via=matrix.org"},{label:"Mastodon",href:"https://fosstodon.org/@sovereigncloudstack"}]},{title:"More",items:[{label:"GitHub",href:"https://github.com/SovereignCloudStack/docs"}]}],copyright:"Sovereign Cloud Stack, SCS and the logo are registered trademarks of the Open Source Business Alliance e.V. \u2014 Other trademarks are property of their respective owners."},prism:{theme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:["powershell","ruby"],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},matomoAnalytics:{matomoUrl:"https://matomo.scs.community/",siteId:"2",phpLoader:"matomo.php",jsLoader:"matomo.js",disableCookies:!0},colorMode:{defaultMode:"light",disableSwitch:!1,respectPrefersColorScheme:!1},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3},mermaid:{theme:{dark:"dark",light:"default"},options:{}}},themes:["@docusaurus/theme-mermaid",["@easyops-cn/docusaurus-search-local",{hashed:!0,docsDir:["docs","community","standards","contributor-docs"],docsRouteBasePath:["docs","community","standards","contributor-docs"]}]],baseUrlIssueBanner:!0,onBrokenAnchors:"warn",onDuplicateRoutes:"warn",staticDirectories:["static"],customFields:{},scripts:[],headTags:[],stylesheets:[],clientModules:[],titleDelimiter:"|",noIndex:!1}},58168:(e,t,n)=>{"use strict";function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e},a.apply(this,arguments)}n.d(t,{A:()=>a})},42892:(e,t,n)=>{"use strict";function a(e,t){return a=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},a(e,t)}function o(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,a(e,t)}n.d(t,{A:()=>o})},98587:(e,t,n)=>{"use strict";function a(e,t){if(null==e)return{};var n,a,o={},s=Object.keys(e);for(a=0;a<s.length;a++)n=s[a],t.indexOf(n)>=0||(o[n]=e[n]);return o}n.d(t,{A:()=>a})},18215:(e,t,n)=>{"use strict";function a(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e)){var s=e.length;for(t=0;t<s;t++)e[t]&&(n=a(e[t]))&&(o&&(o+=" "),o+=n)}else for(n in e)e[n]&&(o&&(o+=" "),o+=n);return o}n.d(t,{A:()=>o});const o=function(){for(var e,t,n=0,o="",s=arguments.length;n<s;n++)(e=arguments[n])&&(t=a(e))&&(o&&(o+=" "),o+=t);return o}},15066:(e,t,n)=>{"use strict";function a(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e)){var s=e.length;for(t=0;t<s;t++)e[t]&&(n=a(e[t]))&&(o&&(o+=" "),o+=n)}else for(n in e)e[n]&&(o&&(o+=" "),o+=n);return o}n.d(t,{A:()=>o});const o=function(){for(var e,t,n=0,o="",s=arguments.length;n<s;n++)(e=arguments[n])&&(t=a(e))&&(o&&(o+=" "),o+=t);return o}},78181:(e,t,n)=>{"use strict";n.d(t,{f4:()=>J,My:()=>C});var a=n(96540);function o(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e)){var s=e.length;for(t=0;t<s;t++)e[t]&&(n=o(e[t]))&&(a&&(a+=" "),a+=n)}else for(n in e)e[n]&&(a&&(a+=" "),a+=n);return a}const s=function(){for(var e,t,n=0,a="",s=arguments.length;n<s;n++)(e=arguments[n])&&(t=o(e))&&(a&&(a+=" "),a+=t);return a};var r,i,c,d,u,l=Object.create,p=Object.defineProperty,g=Object.defineProperties,m=Object.getOwnPropertyDescriptor,f=Object.getOwnPropertyDescriptors,h=Object.getOwnPropertyNames,b=Object.getOwnPropertySymbols,y=Object.getPrototypeOf,v=Object.prototype.hasOwnProperty,k=Object.prototype.propertyIsEnumerable,x=(e,t,n)=>t in e?p(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,w=(e,t)=>{for(var n in t||(t={}))v.call(t,n)&&x(e,n,t[n]);if(b)for(var n of b(t))k.call(t,n)&&x(e,n,t[n]);return e},_=(e,t)=>g(e,f(t)),S=(e,t)=>{var n={};for(var a in e)v.call(e,a)&&t.indexOf(a)<0&&(n[a]=e[a]);if(null!=e&&b)for(var a of b(e))t.indexOf(a)<0&&k.call(e,a)&&(n[a]=e[a]);return n},E=(r={"../../node_modules/.pnpm/prismjs@1.29.0_patch_hash=vrxx3pzkik6jpmgpayxfjunetu/node_modules/prismjs/prism.js"(e,t){var n=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},a={util:{encode:function e(t){return t instanceof o?new o(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var o,s;switch(n=n||{},a.util.type(t)){case"Object":if(s=a.util.objId(t),n[s])return n[s];for(var r in o={},n[s]=o,t)t.hasOwnProperty(r)&&(o[r]=e(t[r],n));return o;case"Array":return s=a.util.objId(t),n[s]?n[s]:(o=[],n[s]=o,t.forEach((function(t,a){o[a]=e(t,n)})),o);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var a="no-"+t;e;){var o=e.classList;if(o.contains(t))return!0;if(o.contains(a))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=a.util.clone(a.languages[e]);for(var o in t)n[o]=t[o];return n},insertBefore:function(e,t,n,o){var s=(o=o||a.languages)[e],r={};for(var i in s)if(s.hasOwnProperty(i)){if(i==t)for(var c in n)n.hasOwnProperty(c)&&(r[c]=n[c]);n.hasOwnProperty(i)||(r[i]=s[i])}var d=o[e];return o[e]=r,a.languages.DFS(a.languages,(function(t,n){n===d&&t!=e&&(this[t]=r)})),r},DFS:function e(t,n,o,s){s=s||{};var r=a.util.objId;for(var i in t)if(t.hasOwnProperty(i)){n.call(t,i,t[i],o||i);var c=t[i],d=a.util.type(c);"Object"!==d||s[r(c)]?"Array"!==d||s[r(c)]||(s[r(c)]=!0,e(c,n,i,s)):(s[r(c)]=!0,e(c,n,null,s))}}},plugins:{},highlight:function(e,t,n){var s={code:e,grammar:t,language:n};if(a.hooks.run("before-tokenize",s),!s.grammar)throw new Error('The language "'+s.language+'" has no grammar.');return s.tokens=a.tokenize(s.code,s.grammar),a.hooks.run("after-tokenize",s),o.stringify(a.util.encode(s.tokens),s.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var a in n)t[a]=n[a];delete t.rest}var o=new i;return c(o,o.head,e),r(e,o,t,o.head,0),function(e){for(var t=[],n=e.head.next;n!==e.tail;)t.push(n.value),n=n.next;return t}(o)},hooks:{all:{},add:function(e,t){var n=a.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=a.hooks.all[e];if(n&&n.length)for(var o,s=0;o=n[s++];)o(t)}},Token:o};function o(e,t,n,a){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length}function s(e,t,n,a){e.lastIndex=t;var o=e.exec(n);if(o&&a&&o[1]){var s=o[1].length;o.index+=s,o[0]=o[0].slice(s)}return o}function r(e,t,n,i,u,l){for(var p in n)if(n.hasOwnProperty(p)&&n[p]){var g=n[p];g=Array.isArray(g)?g:[g];for(var m=0;m<g.length;++m){if(l&&l.cause==p+","+m)return;var f=g[m],h=f.inside,b=!!f.lookbehind,y=!!f.greedy,v=f.alias;if(y&&!f.pattern.global){var k=f.pattern.toString().match(/[imsuy]*$/)[0];f.pattern=RegExp(f.pattern.source,k+"g")}for(var x=f.pattern||f,w=i.next,_=u;w!==t.tail&&!(l&&_>=l.reach);_+=w.value.length,w=w.next){var S=w.value;if(t.length>e.length)return;if(!(S instanceof o)){var E,C=1;if(y){if(!(E=s(x,_,e,b))||E.index>=e.length)break;var T=E.index,A=E.index+E[0].length,j=_;for(j+=w.value.length;T>=j;)j+=(w=w.next).value.length;if(_=j-=w.value.length,w.value instanceof o)continue;for(var L=w;L!==t.tail&&(j<A||"string"==typeof L.value);L=L.next)C++,j+=L.value.length;C--,S=e.slice(_,j),E.index-=_}else if(!(E=s(x,0,S,b)))continue;T=E.index;var P=E[0],N=S.slice(0,T),R=S.slice(T+P.length),O=_+S.length;l&&O>l.reach&&(l.reach=O);var I=w.prev;if(N&&(I=c(t,I,N),_+=N.length),d(t,I,C),w=c(t,I,new o(p,h?a.tokenize(P,h):P,v,P)),R&&c(t,w,R),C>1){var F={cause:p+","+m,reach:O};r(e,t,n,w.prev,_,F),l&&F.reach>l.reach&&(l.reach=F.reach)}}}}}}function i(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function c(e,t,n){var a=t.next,o={value:n,prev:t,next:a};return t.next=o,a.prev=o,e.length++,o}function d(e,t,n){for(var a=t.next,o=0;o<n&&a!==e.tail;o++)a=a.next;t.next=a,a.prev=t,e.length-=o}return o.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var o="";return t.forEach((function(t){o+=e(t,n)})),o}var s={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},r=t.alias;r&&(Array.isArray(r)?Array.prototype.push.apply(s.classes,r):s.classes.push(r)),a.hooks.run("wrap",s);var i="";for(var c in s.attributes)i+=" "+c+'="'+(s.attributes[c]||"").replace(/"/g,""")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'"'+i+">"+s.content+"</"+s.tag+">"},a}();t.exports=n,n.default=n}},function(){return i||(0,r[h(r)[0]])((i={exports:{}}).exports,i),i.exports}),C=((e,t,n)=>(n=null!=e?l(y(e)):{},((e,t,n,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let o of h(t))v.call(e,o)||o===n||p(e,o,{get:()=>t[o],enumerable:!(a=m(t,o))||a.enumerable});return e})(!t&&e&&e.__esModule?n:p(n,"default",{value:e,enumerable:!0}),e)))(E());C.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},C.languages.markup.tag.inside["attr-value"].inside.entity=C.languages.markup.entity,C.languages.markup.doctype.inside["internal-subset"].inside=C.languages.markup,C.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(C.languages.markup.tag,"addInlined",{value:function(e,t){var n;(t=((n=((n={})["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:C.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i,{"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}}))["language-"+t]={pattern:/[\s\S]+/,inside:C.languages[t]},{}))[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:n},C.languages.insertBefore("markup","cdata",t)}}),Object.defineProperty(C.languages.markup.tag,"addAttribute",{value:function(e,t){C.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:C.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),C.languages.html=C.languages.markup,C.languages.mathml=C.languages.markup,C.languages.svg=C.languages.markup,C.languages.xml=C.languages.extend("markup",{}),C.languages.ssml=C.languages.xml,C.languages.atom=C.languages.xml,C.languages.rss=C.languages.xml,function(e){var t={pattern:/\\[\\(){}[\]^$+*?|.]/,alias:"escape"},n=/\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|0[0-7]{0,2}|[123][0-7]{2}|c[a-zA-Z]|.)/,a="(?:[^\\\\-]|"+n.source+")",o=(a=RegExp(a+"-"+a),{pattern:/(<|')[^<>']+(?=[>']$)/,lookbehind:!0,alias:"variable"});e.languages.regex={"char-class":{pattern:/((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,lookbehind:!0,inside:{"char-class-negation":{pattern:/(^\[)\^/,lookbehind:!0,alias:"operator"},"char-class-punctuation":{pattern:/^\[|\]$/,alias:"punctuation"},range:{pattern:a,inside:{escape:n,"range-punctuation":{pattern:/-/,alias:"operator"}}},"special-escape":t,"char-set":{pattern:/\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},escape:n}},"special-escape":t,"char-set":{pattern:/\.|\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},backreference:[{pattern:/\\(?![123][0-7]{2})[1-9]/,alias:"keyword"},{pattern:/\\k<[^<>']+>/,alias:"keyword",inside:{"group-name":o}}],anchor:{pattern:/[$^]|\\[ABbGZz]/,alias:"function"},escape:n,group:[{pattern:/\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|<?[=!]|[idmnsuxU]+(?:-[idmnsuxU]+)?:?))?/,alias:"punctuation",inside:{"group-name":o}},{pattern:/\)/,alias:"punctuation"}],quantifier:{pattern:/(?:[+*?]|\{\d+(?:,\d*)?\})[?+]?/,alias:"number"},alternation:{pattern:/\|/,alias:"keyword"}}}(C),C.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},C.languages.javascript=C.languages.extend("clike",{"class-name":[C.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),C.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,C.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:C.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:C.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:C.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:C.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:C.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),C.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:C.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),C.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),C.languages.markup&&(C.languages.markup.tag.addInlined("script","javascript"),C.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),C.languages.js=C.languages.javascript,C.languages.actionscript=C.languages.extend("javascript",{keyword:/\b(?:as|break|case|catch|class|const|default|delete|do|dynamic|each|else|extends|final|finally|for|function|get|if|implements|import|in|include|instanceof|interface|internal|is|namespace|native|new|null|override|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|use|var|void|while|with)\b/,operator:/\+\+|--|(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=?)=?|[~?@]/}),C.languages.actionscript["class-name"].alias="function",delete C.languages.actionscript.parameter,delete C.languages.actionscript["literal-property"],C.languages.markup&&C.languages.insertBefore("actionscript","string",{xml:{pattern:/(^|[^.])<\/?\w+(?:\s+[^\s>\/=]+=("|')(?:\\[\s\S]|(?!\2)[^\\])*\2)*\s*\/?>/,lookbehind:!0,inside:C.languages.markup}}),d=/#(?!\{).+/,u={pattern:/#\{[^}]+\}/,alias:"variable"},(c=C).languages.coffeescript=c.languages.extend("javascript",{comment:d,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:u}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),c.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:d,interpolation:u}}}),c.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:c.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:u}}]}),c.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete c.languages.coffeescript["template-string"],c.languages.coffee=c.languages.coffeescript,function(e){var t=e.languages.javadoclike={parameter:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*@(?:arg|arguments|param)\s+)\w+/m,lookbehind:!0},keyword:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*|\{)@[a-z][a-zA-Z-]+\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(t,"addSupport",{value:function(t,n){(t="string"==typeof t?[t]:t).forEach((function(t){var a=function(e){e.inside||(e.inside={}),e.inside.rest=n},o="doc-comment";if(s=e.languages[t]){var s,r=s[o];if((r=r||(s=e.languages.insertBefore(t,"comment",{"doc-comment":{pattern:/(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,lookbehind:!0,alias:"comment"}}))[o])instanceof RegExp&&(r=s[o]={pattern:r}),Array.isArray(r))for(var i=0,c=r.length;i<c;i++)r[i]instanceof RegExp&&(r[i]={pattern:r[i]}),a(r[i]);else a(r)}}))}}),t.addSupport(["java","javascript","php"],t)}(C),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;(t=(e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css,e.languages.markup))&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(C),function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,n=(t=(e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+t.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[t,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}}),{pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0}),{pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0});e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|RebeccaPurple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,number:n})}(C),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,a="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),s=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function r(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return a})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return a}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return a})).replace(/<<key>>/g,(function(){return"(?:"+o+"|"+s+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:r(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:r(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:r(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:r(s),lookbehind:!0,greedy:!0},number:{pattern:r(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(C),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var a=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,o=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return a})),s=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source,r=(e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+o+s+"(?:"+o+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+o+s+")(?:"+o+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(a),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+o+")"+s+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+o+"$"),inside:{"table-header":{pattern:RegExp(a),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,a=t.length;n<a;n++){var o,s=t[n];"code"!==s.type?e(s.content):(o=s.content[1],s=s.content[3],o&&s&&"code-language"===o.type&&"code-block"===s.type&&"string"==typeof o.content&&(o=o.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),o="language-"+(o=(/[a-z][\w-]*/i.exec(o)||[""])[0].toLowerCase()),s.alias?"string"==typeof s.alias?s.alias=[s.alias,o]:s.alias.push(o):s.alias=[o]))}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",a=0,o=t.classes.length;a<o;a++){var s=t.classes[a];if(s=/language-(.+)/.exec(s)){n=s[1];break}}var d,u=e.languages[n];u?t.content=e.highlight(t.content.replace(r,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;return"#"===(t=t.toLowerCase())[0]?(n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),c(n)):i[t]||e})),u,n):n&&"none"!==n&&e.plugins.autoloader&&(d="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random()),t.attributes.id=d,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(d);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))})))}})),RegExp(e.languages.markup.tag.pattern.source,"gi")),i={amp:"&",lt:"<",gt:">",quot:'"'},c=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(C),C.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:C.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},C.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var a=t[n++];if("keyword"===a.type&&"mutation"===a.content){var o=[];if(l(["definition-mutation","punctuation"])&&"("===u(1).content){n+=2;var s=p(/^\($/,/^\)$/);if(-1===s)continue;for(;n<s;n++){var r=u(0);"variable"===r.type&&(g(r,"variable-input"),o.push(r.content))}n=s+1}if(l(["punctuation","property-query"])&&"{"===u(0).content&&(n++,g(u(0),"property-mutation"),0<o.length)){var i=p(/^\{$/,/^\}$/);if(-1!==i)for(var c=n;c<i;c++){var d=t[c];"variable"===d.type&&0<=o.indexOf(d.content)&&g(d,"variable-input")}}}}function u(e){return t[n+e]}function l(e,t){t=t||0;for(var n=0;n<e.length;n++){var a=u(n+t);if(!a||a.type!==e[n])return}return 1}function p(e,a){for(var o=1,s=n;s<t.length;s++){var r=t[s],i=r.content;if("punctuation"===r.type&&"string"==typeof i)if(e.test(i))o++;else if(a.test(i)&&0==--o)return s}return-1}function g(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),C.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,a=t.inside.interpolation,o=a.inside["interpolation-punctuation"],s=a.pattern.source;function r(t,a){if(e.languages[t])return{pattern:RegExp("((?:"+a+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function i(t,n,a){return t={code:t,grammar:n,language:a},e.hooks.run("before-tokenize",t),t.tokens=e.tokenize(t.code,t.grammar),e.hooks.run("after-tokenize",t),t.tokens}function c(t,n,r){var c=e.tokenize(t,{interpolation:{pattern:RegExp(s),lookbehind:!0}}),d=0,u={},l=(c=i(c.map((function(e){if("string"==typeof e)return e;var n,a;for(e=e.content;-1!==t.indexOf((a=d++,n="___"+r.toUpperCase()+"_"+a+"___")););return u[n]=e,n})).join(""),n,r),Object.keys(u));return d=0,function t(n){for(var s=0;s<n.length;s++){if(d>=l.length)return;var r,c,p,g,m,f,h,b=n[s];"string"==typeof b||"string"==typeof b.content?(r=l[d],-1!==(h=(f="string"==typeof b?b:b.content).indexOf(r))&&(++d,c=f.substring(0,h),m=u[r],p=void 0,(g={})["interpolation-punctuation"]=o,3===(g=e.tokenize(m,g)).length&&((p=[1,1]).push.apply(p,i(g[1],e.languages.javascript,"javascript")),g.splice.apply(g,p)),p=new e.Token("interpolation",g,a.alias,m),g=f.substring(h+r.length),m=[],c&&m.push(c),m.push(p),g&&(t(f=[g]),m.push.apply(m,f)),"string"==typeof b?(n.splice.apply(n,[s,1].concat(m)),s+=m.length-1):b.content=m)):(h=b.content,Array.isArray(h)?t(h):t([h]))}}(c),new e.Token(r,c,"language-"+r,t)}e.languages.javascript["template-string"]=[r("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),r("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),r("svg",/\bsvg/.source),r("markdown",/\b(?:markdown|md)/.source),r("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),r("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function u(e){return"string"==typeof e?e:Array.isArray(e)?e.map(u).join(""):u(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var a=0,o=n.length;a<o;a++){var s,r,i,d=n[a];"string"!=typeof d&&(s=d.content,Array.isArray(s)?"template-string"===d.type?(d=s[1],3===s.length&&"string"!=typeof d&&"embedded-code"===d.type&&(r=u(d),d=d.alias,d=Array.isArray(d)?d[0]:d,i=e.languages[d])&&(s[1]=c(r,i,d))):t(s):"string"!=typeof s&&t([s]))}}(t.tokens)}))}(C),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(C),function(e){var t=e.languages.javascript,n=/\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})+\}/.source,a="(@(?:arg|argument|param|property)\\s+(?:"+n+"\\s+)?)";e.languages.jsdoc=e.languages.extend("javadoclike",{parameter:{pattern:RegExp(a+/(?:(?!\s)[$\w\xA0-\uFFFF.])+(?=\s|$)/.source),lookbehind:!0,inside:{punctuation:/\./}}}),e.languages.insertBefore("jsdoc","keyword",{"optional-parameter":{pattern:RegExp(a+/\[(?:(?!\s)[$\w\xA0-\uFFFF.])+(?:=[^[\]]+)?\](?=\s|$)/.source),lookbehind:!0,inside:{parameter:{pattern:/(^\[)[$\w\xA0-\uFFFF\.]+/,lookbehind:!0,inside:{punctuation:/\./}},code:{pattern:/(=)[\s\S]*(?=\]$)/,lookbehind:!0,inside:t,alias:"language-javascript"},punctuation:/[=[\]]/}},"class-name":[{pattern:RegExp(/(@(?:augments|class|extends|interface|memberof!?|template|this|typedef)\s+(?:<TYPE>\s+)?)[A-Z]\w*(?:\.[A-Z]\w*)*/.source.replace(/<TYPE>/g,(function(){return n}))),lookbehind:!0,inside:{punctuation:/\./}},{pattern:RegExp("(@[a-z]+\\s+)"+n),lookbehind:!0,inside:{string:t.string,number:t.number,boolean:t.boolean,keyword:e.languages.typescript.keyword,operator:/=>|\.\.\.|[&|?:*]/,punctuation:/[.,;=<>{}()[\]]/}}],example:{pattern:/(@example\s+(?!\s))(?:[^@\s]|\s+(?!\s))+?(?=\s*(?:\*\s*)?(?:@\w|\*\/))/,lookbehind:!0,inside:{code:{pattern:/^([\t ]*(?:\*\s*)?)\S.*$/m,lookbehind:!0,inside:t,alias:"language-javascript"}}}}),e.languages.javadoclike.addSupport("javascript",e.languages.jsdoc)}(C),function(e){e.languages.flow=e.languages.extend("javascript",{}),e.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Bb]oolean|Function|[Nn]umber|[Ss]tring|[Ss]ymbol|any|mixed|null|void)\b/,alias:"class-name"}]}),e.languages.flow["function-variable"].pattern=/(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/i,delete e.languages.flow.parameter,e.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),Array.isArray(e.languages.flow.keyword)||(e.languages.flow.keyword=[e.languages.flow.keyword]),e.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:Class|declare|opaque|type)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:Diff|Enum|Exact|Keys|ObjMap|PropertyType|Record|Shape|Subtype|Supertype|await)\b(?!\$)/,lookbehind:!0})}(C),C.languages.n4js=C.languages.extend("javascript",{keyword:/\b(?:Array|any|boolean|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|module|new|null|number|package|private|protected|public|return|set|static|string|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/}),C.languages.insertBefore("n4js","constant",{annotation:{pattern:/@+\w+/,alias:"operator"}}),C.languages.n4jsd=C.languages.n4js,function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],a=0;a<n.length;a++){var o=n[a],s=e.languages.javascript[o];o=(s="RegExp"===e.util.type(s)?e.languages.javascript[o]={pattern:s}:s).inside||{};(s.inside=o)["maybe-class-name"]=/^[A-Z][\s\S]*/}}(C),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,a=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,o=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function s(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return a})).replace(/<SPREAD>/g,(function(){return o})),RegExp(e,t)}function r(t){for(var n=[],a=0;a<t.length;a++){var o=t[a],s=!1;"string"!=typeof o&&("tag"===o.type&&o.content[0]&&"tag"===o.content[0].type?"</"===o.content[0].content[0].content?0<n.length&&n[n.length-1].tagName===i(o.content[0].content[1])&&n.pop():"/>"!==o.content[o.content.length-1].content&&n.push({tagName:i(o.content[0].content[1]),openedBraces:0}):0<n.length&&"punctuation"===o.type&&"{"===o.content?n[n.length-1].openedBraces++:0<n.length&&0<n[n.length-1].openedBraces&&"punctuation"===o.type&&"}"===o.content?n[n.length-1].openedBraces--:s=!0),(s||"string"==typeof o)&&0<n.length&&0===n[n.length-1].openedBraces&&(s=i(o),a<t.length-1&&("string"==typeof t[a+1]||"plain-text"===t[a+1].type)&&(s+=i(t[a+1]),t.splice(a+1,1)),0<a&&("string"==typeof t[a-1]||"plain-text"===t[a-1].type)&&(s=i(t[a-1])+s,t.splice(a-1,1),a--),t[a]=new e.Token("plain-text",s,null,s)),o.content&&"string"!=typeof o.content&&r(o.content)}}o=s(o).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=s(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:s(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:s(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||r(e.tokens)}))}(C),function(e){var t=e.util.clone(e.languages.typescript);(t=(e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"],e.languages.tsx.tag)).pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(C),C.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+/(?:elseif|if)\b/.source+"(?:[ \t]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},C.languages.swift["string-literal"].forEach((function(e){e.inside.interpolation.inside=C.languages.swift})),function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(C),C.languages.c=C.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),C.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),C.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},C.languages.c.string],char:C.languages.c.char,comment:C.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:C.languages.c}}}}),C.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete C.languages.c.boolean,C.languages.objectivec=C.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete C.languages.objectivec["class-name"],C.languages.objc=C.languages.objectivec,C.languages.reason=C.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),C.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete C.languages.reason.function,function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source,n=0;n<2;n++)t=t.replace(/<self>/g,(function(){return t}));t=t.replace(/<self>/g,(function(){return/[^\s\S]/.source})),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(C),C.languages.go=C.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),C.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete C.languages.go["class-name"],function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(C),C.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},C.languages.python["string-interpolation"].inside.interpolation.inside.rest=C.languages.python,C.languages.py=C.languages.python;((e,t)=>{for(var n in t)p(e,n,{get:t[n],enumerable:!0})})({},{dracula:()=>T,duotoneDark:()=>A,duotoneLight:()=>j,github:()=>L,jettwaveDark:()=>Q,jettwaveLight:()=>V,nightOwl:()=>P,nightOwlLight:()=>N,oceanicNext:()=>I,okaidia:()=>F,oneDark:()=>H,oneLight:()=>W,palenight:()=>D,shadesOfPurple:()=>M,synthwave84:()=>z,ultramin:()=>B,vsDark:()=>$,vsLight:()=>U});var T={plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},A={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]},j={plain:{backgroundColor:"#faf8f5",color:"#728fcb"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#b6ad9a"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#063289"}},{types:["property","function"],style:{color:"#b29762"}},{types:["tag-id","selector","atrule-id"],style:{color:"#2d2006"}},{types:["attr-name"],style:{color:"#896724"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule"],style:{color:"#728fcb"}},{types:["placeholder","variable"],style:{color:"#93abdc"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#896724"}}]},L={plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},P={plain:{color:"#d6deeb",backgroundColor:"#011627"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(99, 119, 119)",fontStyle:"italic"}},{types:["string","url"],style:{color:"rgb(173, 219, 103)"}},{types:["variable"],style:{color:"rgb(214, 222, 235)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation"],style:{color:"rgb(199, 146, 234)"}},{types:["selector","doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(255, 203, 139)"}},{types:["tag","operator","keyword"],style:{color:"rgb(127, 219, 202)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["property"],style:{color:"rgb(128, 203, 196)"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}}]},N={plain:{color:"#403f53",backgroundColor:"#FBFBFB"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(72, 118, 214)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(152, 159, 177)",fontStyle:"italic"}},{types:["string","builtin","char","constant","url"],style:{color:"rgb(72, 118, 214)"}},{types:["variable"],style:{color:"rgb(201, 103, 101)"}},{types:["number"],style:{color:"rgb(170, 9, 130)"}},{types:["punctuation"],style:{color:"rgb(153, 76, 195)"}},{types:["function","selector","doctype"],style:{color:"rgb(153, 76, 195)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(17, 17, 17)"}},{types:["tag"],style:{color:"rgb(153, 76, 195)"}},{types:["operator","property","keyword","namespace"],style:{color:"rgb(12, 150, 155)"}},{types:["boolean"],style:{color:"rgb(188, 84, 84)"}}]},R="#c5a5c5",O="#8dc891",I={plain:{backgroundColor:"#282c34",color:"#ffffff"},styles:[{types:["attr-name"],style:{color:R}},{types:["attr-value"],style:{color:O}},{types:["comment","block-comment","prolog","doctype","cdata","shebang"],style:{color:"#999999"}},{types:["property","number","function-name","constant","symbol","deleted"],style:{color:"#5a9bcf"}},{types:["boolean"],style:{color:"#ff8b50"}},{types:["tag"],style:{color:"#fc929e"}},{types:["string"],style:{color:O}},{types:["punctuation"],style:{color:O}},{types:["selector","char","builtin","inserted"],style:{color:"#D8DEE9"}},{types:["function"],style:{color:"#79b6f2"}},{types:["operator","entity","url","variable"],style:{color:"#d7deea"}},{types:["keyword"],style:{color:R}},{types:["atrule","class-name"],style:{color:"#FAC863"}},{types:["important"],style:{fontWeight:"400"}},{types:["bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}}]},F={plain:{color:"#f8f8f2",backgroundColor:"#272822"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"#f92672",fontStyle:"italic"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"#8292a2",fontStyle:"italic"}},{types:["string","url"],style:{color:"#a6e22e"}},{types:["variable"],style:{color:"#f8f8f2"}},{types:["number"],style:{color:"#ae81ff"}},{types:["builtin","char","constant","function","class-name"],style:{color:"#e6db74"}},{types:["punctuation"],style:{color:"#f8f8f2"}},{types:["selector","doctype"],style:{color:"#a6e22e",fontStyle:"italic"}},{types:["tag","operator","keyword"],style:{color:"#66d9ef"}},{types:["boolean"],style:{color:"#ae81ff"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)",opacity:.7}},{types:["tag","property"],style:{color:"#f92672"}},{types:["attr-name"],style:{color:"#a6e22e !important"}},{types:["doctype"],style:{color:"#8292a2"}},{types:["rule"],style:{color:"#e6db74"}}]},D={plain:{color:"#bfc7d5",backgroundColor:"#292d3e"},styles:[{types:["comment"],style:{color:"rgb(105, 112, 152)",fontStyle:"italic"}},{types:["string","inserted"],style:{color:"rgb(195, 232, 141)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation","selector"],style:{color:"rgb(199, 146, 234)"}},{types:["variable"],style:{color:"rgb(191, 199, 213)"}},{types:["class-name","attr-name"],style:{color:"rgb(255, 203, 107)"}},{types:["tag","deleted"],style:{color:"rgb(255, 85, 114)"}},{types:["operator"],style:{color:"rgb(137, 221, 255)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["keyword"],style:{fontStyle:"italic"}},{types:["doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}},{types:["url"],style:{color:"rgb(221, 221, 221)"}}]},M={plain:{color:"#9EFEFF",backgroundColor:"#2D2A55"},styles:[{types:["changed"],style:{color:"rgb(255, 238, 128)"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)"}},{types:["comment"],style:{color:"rgb(179, 98, 255)",fontStyle:"italic"}},{types:["punctuation"],style:{color:"rgb(255, 255, 255)"}},{types:["constant"],style:{color:"rgb(255, 98, 140)"}},{types:["string","url"],style:{color:"rgb(165, 255, 144)"}},{types:["variable"],style:{color:"rgb(255, 238, 128)"}},{types:["number","boolean"],style:{color:"rgb(255, 98, 140)"}},{types:["attr-name"],style:{color:"rgb(255, 180, 84)"}},{types:["keyword","operator","property","namespace","tag","selector","doctype"],style:{color:"rgb(255, 157, 0)"}},{types:["builtin","char","constant","function","class-name"],style:{color:"rgb(250, 208, 0)"}}]},z={plain:{backgroundColor:"linear-gradient(to bottom, #2a2139 75%, #34294f)",backgroundImage:"#34294f",color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"},styles:[{types:["comment","block-comment","prolog","doctype","cdata"],style:{color:"#495495",fontStyle:"italic"}},{types:["punctuation"],style:{color:"#ccc"}},{types:["tag","attr-name","namespace","number","unit","hexcode","deleted"],style:{color:"#e2777a"}},{types:["property","selector"],style:{color:"#72f1b8",textShadow:"0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475"}},{types:["function-name"],style:{color:"#6196cc"}},{types:["boolean","selector-id","function"],style:{color:"#fdfdfd",textShadow:"0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975"}},{types:["class-name","maybe-class-name","builtin"],style:{color:"#fff5f6",textShadow:"0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75"}},{types:["constant","symbol"],style:{color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"}},{types:["important","atrule","keyword","selector-class"],style:{color:"#f4eee4",textShadow:"0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575"}},{types:["string","char","attr-value","regex","variable"],style:{color:"#f87c32"}},{types:["parameter"],style:{fontStyle:"italic"}},{types:["entity","url"],style:{color:"#67cdcc"}},{types:["operator"],style:{color:"ffffffee"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["entity"],style:{cursor:"help"}},{types:["inserted"],style:{color:"green"}}]},B={plain:{color:"#282a2e",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(197, 200, 198)"}},{types:["string","number","builtin","variable"],style:{color:"rgb(150, 152, 150)"}},{types:["class-name","function","tag","attr-name"],style:{color:"rgb(40, 42, 46)"}}]},$={plain:{color:"#9CDCFE",backgroundColor:"#1E1E1E"},styles:[{types:["prolog"],style:{color:"rgb(0, 0, 128)"}},{types:["comment"],style:{color:"rgb(106, 153, 85)"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"rgb(86, 156, 214)"}},{types:["number","inserted"],style:{color:"rgb(181, 206, 168)"}},{types:["constant"],style:{color:"rgb(100, 102, 149)"}},{types:["attr-name","variable"],style:{color:"rgb(156, 220, 254)"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"rgb(206, 145, 120)"}},{types:["selector"],style:{color:"rgb(215, 186, 125)"}},{types:["tag"],style:{color:"rgb(78, 201, 176)"}},{types:["tag"],languages:["markup"],style:{color:"rgb(86, 156, 214)"}},{types:["punctuation","operator"],style:{color:"rgb(212, 212, 212)"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"rgb(220, 220, 170)"}},{types:["class-name"],style:{color:"rgb(78, 201, 176)"}},{types:["char"],style:{color:"rgb(209, 105, 105)"}}]},U={plain:{color:"#000000",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},Q={plain:{color:"#f8fafc",backgroundColor:"#011627"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#569CD6"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#f8fafc"}},{types:["attr-name","variable"],style:{color:"#9CDCFE"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#cbd5e1"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#D4D4D4"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#7dd3fc"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},V={plain:{color:"#0f172a",backgroundColor:"#f1f5f9"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#0c4a6e"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#0f172a"}},{types:["attr-name","variable"],style:{color:"#0c4a6e"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#64748b"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#475569"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#0e7490"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},H={plain:{backgroundColor:"hsl(220, 13%, 18%)",color:"hsl(220, 14%, 71%)",textShadow:"0 1px rgba(0, 0, 0, 0.3)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(220, 10%, 40%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(220, 14%, 71%)"}},{types:["attr-name","class-name","maybe-class-name","boolean","constant","number","atrule"],style:{color:"hsl(29, 54%, 61%)"}},{types:["keyword"],style:{color:"hsl(286, 60%, 67%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(355, 65%, 65%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value"],style:{color:"hsl(95, 38%, 62%)"}},{types:["variable","operator","function"],style:{color:"hsl(207, 82%, 66%)"}},{types:["url"],style:{color:"hsl(187, 47%, 55%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(220, 14%, 71%)"}}]},W={plain:{backgroundColor:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(230, 4%, 64%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(230, 8%, 24%)"}},{types:["attr-name","class-name","boolean","constant","number","atrule"],style:{color:"hsl(35, 99%, 36%)"}},{types:["keyword"],style:{color:"hsl(301, 63%, 40%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(5, 74%, 59%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value","punctuation"],style:{color:"hsl(119, 34%, 47%)"}},{types:["variable","operator","function"],style:{color:"hsl(221, 87%, 60%)"}},{types:["url"],style:{color:"hsl(198, 99%, 37%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(230, 8%, 24%)"}}]},q=(e,t)=>{const{plain:n}=e,a=e.styles.reduce(((e,n)=>{const{languages:a,style:o}=n;return a&&!a.includes(t)||n.types.forEach((t=>{const n=w(w({},e[t]),o);e[t]=n})),e}),{});return a.root=n,a.plain=_(w({},n),{backgroundColor:void 0}),a},G=/\r\n|\r|\n/,X=e=>{0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},K=(e,t)=>{const n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)},Y=e=>{const t=[[]],n=[e],a=[0],o=[e.length];let s=0,r=0,i=[];const c=[i];for(;r>-1;){for(;(s=a[r]++)<o[r];){let e,d=t[r];const u=n[r][s];if("string"==typeof u?(d=r>0?d:["plain"],e=u):(d=K(d,u.type),u.alias&&(d=K(d,u.alias)),e=u.content),"string"!=typeof e){r++,t.push(d),n.push(e),a.push(0),o.push(e.length);continue}const l=e.split(G),p=l.length;i.push({types:d,content:l[0]});for(let t=1;t<p;t++)X(i),c.push(i=[]),i.push({types:d,content:l[t]})}r--,t.pop(),n.pop(),a.pop(),o.pop()}return X(i),c},Z=({children:e,language:t,code:n,theme:o,prism:r})=>{const i=t.toLowerCase(),c=((e,t)=>{const[n,o]=(0,a.useState)(q(t,e)),s=(0,a.useRef)(),r=(0,a.useRef)();return(0,a.useEffect)((()=>{t===s.current&&e===r.current||(s.current=t,r.current=e,o(q(t,e)))}),[e,t]),n})(i,o),d=(e=>(0,a.useCallback)((t=>{var n=t,{className:a,style:o,line:r}=n,i=S(n,["className","style","line"]);const c=_(w({},i),{className:s("token-line",a)});return"object"==typeof e&&"plain"in e&&(c.style=e.plain),"object"==typeof o&&(c.style=w(w({},c.style||{}),o)),c}),[e]))(c),u=(e=>{const t=(0,a.useCallback)((({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map((t=>e[t])))}),[e]);return(0,a.useCallback)((e=>{var n=e,{token:a,className:o,style:r}=n,i=S(n,["token","className","style"]);const c=_(w({},i),{className:s("token",...a.types,o),children:a.content,style:t(a)});return null!=r&&(c.style=w(w({},c.style||{}),r)),c}),[t])})(c),l=(({prism:e,code:t,grammar:n,language:o})=>{const s=(0,a.useRef)(e);return(0,a.useMemo)((()=>{if(null==n)return Y([t]);const e={code:t,grammar:n,language:o,tokens:[]};return s.current.hooks.run("before-tokenize",e),e.tokens=s.current.tokenize(t,n),s.current.hooks.run("after-tokenize",e),Y(e.tokens)}),[t,n,o])})({prism:r,language:i,code:n,grammar:r.languages[i]});return e({tokens:l,className:`prism-code language-${i}`,style:null!=c?c.root:{},getLineProps:d,getTokenProps:u})},J=e=>(0,a.createElement)(Z,_(w({},e),{prism:e.prism||C,theme:e.theme||$,code:e.code,language:e.language}))},11561:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var a=!0,o="Invariant failed";function s(e,t){if(!e){if(a)throw new Error(o);var n="function"==typeof t?t():t,s=n?"".concat(o,": ").concat(n):o;throw new Error(s)}}},22654:e=>{"use strict";e.exports={}},84054:e=>{"use strict";e.exports=JSON.parse('{"/blog-9f2":{"__comp":"a6aa9e1f","__context":{"plugin":"1c091541"},"sidebar":"814f3328","items":[{"content":"04fe2bfd"}],"metadata":"b2b675dd"},"/blog/archive-d5c":{"__comp":"9e4087bc","__context":{"plugin":"1c091541"},"archive":"b2f554cd"},"/blog/first-blog-post-c31":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"1c091541"},"sidebar":"814f3328","content":"4468ebd1"},"/blog/tags-e00":{"__comp":"01a85c17","__context":{"plugin":"1c091541"},"sidebar":"814f3328","tags":"a7023ddc"},"/blog/tags/community-928":{"__comp":"6875c492","__context":{"plugin":"1c091541"},"sidebar":"814f3328","items":[{"content":"04fe2bfd"}],"tag":"69b09ea9","listMetadata":"afaff11a"},"/blog/tags/howto-1c2":{"__comp":"6875c492","__context":{"plugin":"1c091541"},"sidebar":"814f3328","items":[{"content":"04fe2bfd"}],"tag":"d5ac8ed7","listMetadata":"14c1041d"},"/search-ae7":{"__comp":"1a4e3797","__context":{"plugin":"4129286c"}},"/community-8d1":{"__comp":"5e95c892","__context":{"plugin":"f793d2d5"}},"/community-983":{"__comp":"a7bd4aaa","version":"306a8c6c"},"/community-3f5":{"__comp":"a94703ab"},"/community/-067":{"__comp":"17896441","content":"edc931f8"},"/community/category/contribute-to-docs-b6e":{"__comp":"14eb3368","categoryGeneratedIndex":"2d3bf848"},"/community/category/tools-708":{"__comp":"14eb3368","categoryGeneratedIndex":"66dc81f9"},"/community/central-services/plusserver-gx-scs-8a6":{"__comp":"17896441","content":"9099a3d2"},"/community/cloud-resources/-8ee":{"__comp":"17896441","content":"1722e234"},"/community/cloud-resources/getting-started-openstack-963":{"__comp":"17896441","content":"7bd33c3d"},"/community/cloud-resources/plusserver-gx-scs-ec9":{"__comp":"17896441","content":"35fbae7a"},"/community/cloud-resources/wavestack-a83":{"__comp":"17896441","content":"1f34ee25"},"/community/collaboration/-147":{"__comp":"17896441","content":"5cc619f0"},"/community/collaboration/sig-central-api-b3d":{"__comp":"17896441","content":"87293620"},"/community/collaboration/sig-community-c49":{"__comp":"17896441","content":"b7cec31e"},"/community/collaboration/sig-documentation-b1a":{"__comp":"17896441","content":"a63812ab"},"/community/collaboration/sig-monitoring-7fc":{"__comp":"17896441","content":"ea470413"},"/community/collaboration/sig-standardization-177":{"__comp":"17896441","content":"a52c62d4"},"/community/collaboration/team-container-7b3":{"__comp":"17896441","content":"b501f8e8"},"/community/collaboration/team-iaas-c05":{"__comp":"17896441","content":"97ef9758"},"/community/collaboration/team-iam-202":{"__comp":"17896441","content":"62337dff"},"/community/collaboration/team-ops-960":{"__comp":"17896441","content":"36c47bdd"},"/community/contribute/adding-docs-guide-cc6":{"__comp":"17896441","content":"a8f67d60"},"/community/contribute/doc-files-structure-guide-195":{"__comp":"17896441","content":"29c2cfba"},"/community/contribute/docs-workflow-explanation-d63":{"__comp":"17896441","content":"cffc493c"},"/community/contribute/linting-guide-088":{"__comp":"17896441","content":"096c51c8"},"/community/contribute/local-docusaurus-development-guide-83e":{"__comp":"17896441","content":"ef9d238d"},"/community/contribute/styleguide-a62":{"__comp":"17896441","content":"931040e8"},"/community/contribute/styleguides/ansible_styleguide-e67":{"__comp":"17896441","content":"b08c16de"},"/community/hackathons/checklist-592":{"__comp":"17896441","content":"49bc3785"},"/community/license-considerations-f35":{"__comp":"17896441","content":"ce756c16"},"/community/mission-statement-532":{"__comp":"17896441","content":"19f6a518"},"/community/tools/github/branchprotection-f89":{"__comp":"17896441","content":"2886628e"},"/community/tools/github/dco-and-licenses-276":{"__comp":"17896441","content":"03412b54"},"/community/tools/github/tips-and-tricks-923":{"__comp":"17896441","content":"03babb4a"},"/community/tools/jitsi-a31":{"__comp":"17896441","content":"4e607b99"},"/community/tools/mailinglists-85e":{"__comp":"17896441","content":"5b909c46"},"/community/tools/matrix-9e6":{"__comp":"17896441","content":"420452be"},"/community/tools/nextcloud-f9d":{"__comp":"17896441","content":"1e818dbe"},"/community/tools/zuul-faa":{"__comp":"17896441","content":"45bfeaeb"},"/contributor-docs-8dc":{"__comp":"5e95c892","__context":{"plugin":"94298c6b"}},"/contributor-docs-cba":{"__comp":"a7bd4aaa","version":"95967863"},"/contributor-docs-98b":{"__comp":"a94703ab"},"/contributor-docs/-5c4":{"__comp":"17896441","content":"0050251a"},"/contributor-docs/development/-b39":{"__comp":"17896441","content":"c9b16325"},"/contributor-docs/development/tests/rfc2119-keyword-test-guide-017":{"__comp":"17896441","content":"ff45c01b"},"/contributor-docs/development/tests/test-implementation-guide-8a6":{"__comp":"17896441","content":"cbf20d25"},"/contributor-docs/operations/iam/identity-federation-in-scs-b16":{"__comp":"17896441","content":"9a7c0197"},"/contributor-docs/operations/iam/openstack-federation-via-oidc-377":{"__comp":"17896441","content":"8d25d5d4"},"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide-ec0":{"__comp":"17896441","content":"950c7487"},"/docs-65a":{"__comp":"5e95c892","__context":{"plugin":"247783bb"}},"/docs-9d9":{"__comp":"a7bd4aaa","version":"935f2afb"},"/docs-6a2":{"__comp":"a94703ab"},"/docs/-6df":{"__comp":"17896441","content":"4edc808e"},"/docs/category/automated-pentesting-8e9":{"__comp":"14eb3368","categoryGeneratedIndex":"e6095437"},"/docs/category/central-api-93f":{"__comp":"14eb3368","categoryGeneratedIndex":"6e5bfc33"},"/docs/category/cluster-stacks-6ae":{"__comp":"14eb3368","categoryGeneratedIndex":"c8b68b4a"},"/docs/category/components-f2e":{"__comp":"14eb3368","categoryGeneratedIndex":"f14351c1"},"/docs/category/components-1-f0f":{"__comp":"14eb3368","categoryGeneratedIndex":"65c90e53"},"/docs/category/components-2-781":{"__comp":"14eb3368","categoryGeneratedIndex":"2163574d"},"/docs/category/container-registry-fc7":{"__comp":"14eb3368","categoryGeneratedIndex":"08602342"},"/docs/category/guides-1-62f":{"__comp":"14eb3368","categoryGeneratedIndex":"d7951534"},"/docs/category/guides-2-408":{"__comp":"14eb3368","categoryGeneratedIndex":"bdcb5fea"},"/docs/category/iaas-layer-429":{"__comp":"14eb3368","categoryGeneratedIndex":"29331985"},"/docs/category/k8s-cluster-api-provider-de7":{"__comp":"14eb3368","categoryGeneratedIndex":"9fb1f91e"},"/docs/category/metering-c3e":{"__comp":"14eb3368","categoryGeneratedIndex":"b840bdcc"},"/docs/category/monitoring-5b5":{"__comp":"14eb3368","categoryGeneratedIndex":"ebcea0bb"},"/docs/category/operating-scs-b51":{"__comp":"14eb3368","categoryGeneratedIndex":"f91986bc"},"/docs/category/releases-d6f":{"__comp":"14eb3368","categoryGeneratedIndex":"3bf9fbe6"},"/docs/category/status-page-api-18b":{"__comp":"14eb3368","categoryGeneratedIndex":"059c4264"},"/docs/container/-6db":{"__comp":"17896441","content":"3ff13a62"},"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers-2fa":{"__comp":"17896441","content":"f17f9c44"},"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop-057":{"__comp":"17896441","content":"8493ac52"},"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview-ae8":{"__comp":"17896441","content":"452be0ad"},"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart-408":{"__comp":"17896441","content":"287cd167"},"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting-d6e":{"__comp":"17896441","content":"eaf69a59"},"/docs/container/components/container-registry/docs/backup_and_restore-8f9":{"__comp":"17896441","content":"7bed4829"},"/docs/container/components/container-registry/docs/ha-deployment-799":{"__comp":"17896441","content":"abd7a988"},"/docs/container/components/container-registry/docs/migration-33a":{"__comp":"17896441","content":"bccb1b42"},"/docs/container/components/container-registry/docs/persistence-90e":{"__comp":"17896441","content":"7850b12c"},"/docs/container/components/container-registry/docs/quickstart-772":{"__comp":"17896441","content":"657efcba"},"/docs/container/components/container-registry/docs/rate_limit-017":{"__comp":"17896441","content":"c5479f59"},"/docs/container/components/container-registry/docs/scs-deployment-5f3":{"__comp":"17896441","content":"1ca0f8e7"},"/docs/container/components/container-registry/docs/upgrade-e27":{"__comp":"17896441","content":"19cb43cd"},"/docs/container/components/k8s-cluster-api-provider/doc/application-credentials-002":{"__comp":"17896441","content":"0683500c"},"/docs/container/components/k8s-cluster-api-provider/doc/configuration-45e":{"__comp":"17896441","content":"a51c5cdb"},"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration-67e":{"__comp":"17896441","content":"431e6cfe"},"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal-2b9":{"__comp":"17896441","content":"421b5e65"},"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting-9b1":{"__comp":"17896441","content":"441ae8e9"},"/docs/container/components/k8s-cluster-api-provider/doc/make-reference-8be":{"__comp":"17896441","content":"a38b6a75"},"/docs/container/components/k8s-cluster-api-provider/doc/overview-86b":{"__comp":"17896441","content":"a8ea16f4"},"/docs/container/components/k8s-cluster-api-provider/doc/quickstart-c83":{"__comp":"17896441","content":"15336817"},"/docs/container/components/k8s-cluster-api-provider/doc/requirements-ccd":{"__comp":"17896441","content":"95d93785"},"/docs/container/components/k8s-cluster-api-provider/doc/roadmap-11b":{"__comp":"17896441","content":"8ba37aa2"},"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide-dff":{"__comp":"17896441","content":"38b583d2"},"/docs/container/components/k8s-cluster-api-provider/doc/usage/-698":{"__comp":"17896441","content":"95fe5f6c"},"/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node-d52":{"__comp":"17896441","content":"8a671cf8"},"/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration-90a":{"__comp":"17896441","content":"d6a104fd"},"/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster-d6f":{"__comp":"17896441","content":"23cd166f"},"/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca-4ad":{"__comp":"17896441","content":"653904f7"},"/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api-782":{"__comp":"17896441","content":"739c0ae8"},"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor-216":{"__comp":"17896441","content":"564eabfd"},"/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters-336":{"__comp":"17896441","content":"dfe27b1e"},"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class-257":{"__comp":"17896441","content":"d770ad8d"},"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2-994":{"__comp":"17896441","content":"7ebec009"},"/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments-403":{"__comp":"17896441","content":"42088e64"},"/docs/container/components/k8s-cluster-api-provider/doc/usage/testing-19d":{"__comp":"17896441","content":"50963409"},"/docs/container/deployment-examples/a/-eab":{"__comp":"17896441","content":"83100446"},"/docs/container/deployment-examples/a/hardware-c9f":{"__comp":"17896441","content":"fe5fac7c"},"/docs/container/deployment-examples/a/software-4b1":{"__comp":"17896441","content":"0bcc5672"},"/docs/container/guides/guide1-fe9":{"__comp":"17896441","content":"dcf2f717"},"/docs/container/overview/architecture-96d":{"__comp":"17896441","content":"a94c36cd"},"/docs/container/overview/knowledge-b1b":{"__comp":"17896441","content":"f4cdb2d9"},"/docs/faq/-ab5":{"__comp":"17896441","content":"94f31572"},"/docs/getting-started/containerization-6c3":{"__comp":"17896441","content":"cd0ad4f0"},"/docs/getting-started/overview-4b2":{"__comp":"17896441","content":"19afbcc8"},"/docs/getting-started/virtualization-01b":{"__comp":"17896441","content":"e44168e5"},"/docs/glossary-c6d":{"__comp":"17896441","content":"e747ec83"},"/docs/iaas/components/-d45":{"__comp":"17896441","content":"86ee3414"},"/docs/iaas/components/flavor-manager-8e8":{"__comp":"17896441","content":"88684b71"},"/docs/iaas/components/image-manager/-ceb":{"__comp":"17896441","content":"2ce1dccd"},"/docs/iaas/components/image-manager/update-d83":{"__comp":"17896441","content":"7023f74c"},"/docs/iaas/components/openstack-health-monitor-d38":{"__comp":"17896441","content":"8db05b07"},"/docs/iaas/components/project-manager-b8e":{"__comp":"17896441","content":"a708848c"},"/docs/iaas/components/resource-manager-a61":{"__comp":"17896441","content":"685813dc"},"/docs/iaas/components/sandbox-manager-941":{"__comp":"17896441","content":"b8fd74b5"},"/docs/iaas/components/simple-stress-9d1":{"__comp":"17896441","content":"c49f9378"},"/docs/iaas/guides/-df7":{"__comp":"17896441","content":"502adbf6"},"/docs/iaas/guides/concept-guide/-879":{"__comp":"17896441","content":"caeeb51c"},"/docs/iaas/guides/concept-guide/components/-631":{"__comp":"17896441","content":"d71eca41"},"/docs/iaas/guides/concept-guide/components/ceph-7ba":{"__comp":"17896441","content":"3ad2c61e"},"/docs/iaas/guides/concept-guide/components/clusterapi-e03":{"__comp":"17896441","content":"2ee7a08a"},"/docs/iaas/guides/concept-guide/components/gardener-ab9":{"__comp":"17896441","content":"ad1cb202"},"/docs/iaas/guides/concept-guide/components/ironic-4b7":{"__comp":"17896441","content":"e0c197a4"},"/docs/iaas/guides/concept-guide/components/k3s-481":{"__comp":"17896441","content":"fff06078"},"/docs/iaas/guides/concept-guide/components/keycloak-7d2":{"__comp":"17896441","content":"6bcd11f8"},"/docs/iaas/guides/concept-guide/components/netdata-071":{"__comp":"17896441","content":"0bb6d954"},"/docs/iaas/guides/concept-guide/components/openstack-5e1":{"__comp":"17896441","content":"3a1d878d"},"/docs/iaas/guides/concept-guide/components/prometheus-402":{"__comp":"17896441","content":"2abb9c6f"},"/docs/iaas/guides/concept-guide/components/proxmox-0f3":{"__comp":"17896441","content":"97630173"},"/docs/iaas/guides/concept-guide/components/sonic-133":{"__comp":"17896441","content":"066abe51"},"/docs/iaas/guides/concept-guide/components/teleport-bef":{"__comp":"17896441","content":"193dc870"},"/docs/iaas/guides/concept-guide/design-99a":{"__comp":"17896441","content":"71acf54e"},"/docs/iaas/guides/concept-guide/hardware-bom-98f":{"__comp":"17896441","content":"012688b3"},"/docs/iaas/guides/concept-guide/layers-d21":{"__comp":"17896441","content":"95800b3e"},"/docs/iaas/guides/concept-guide/use-cases-fcd":{"__comp":"17896441","content":"61171858"},"/docs/iaas/guides/configuration-guide/-2af":{"__comp":"17896441","content":"f0e20cb6"},"/docs/iaas/guides/configuration-guide/ceph-19e":{"__comp":"17896441","content":"6c33bb99"},"/docs/iaas/guides/configuration-guide/commons/-25b":{"__comp":"17896441","content":"3d19221e"},"/docs/iaas/guides/configuration-guide/commons/certificates-d0a":{"__comp":"17896441","content":"6e45ed1a"},"/docs/iaas/guides/configuration-guide/commons/packages-3a4":{"__comp":"17896441","content":"60fc342f"},"/docs/iaas/guides/configuration-guide/commons/resolvconf-d42":{"__comp":"17896441","content":"de6833f9"},"/docs/iaas/guides/configuration-guide/commons/services-97a":{"__comp":"17896441","content":"df35cf96"},"/docs/iaas/guides/configuration-guide/commons/sshconfig-505":{"__comp":"17896441","content":"05e7973d"},"/docs/iaas/guides/configuration-guide/commons/sysctl-635":{"__comp":"17896441","content":"e24c1f8d"},"/docs/iaas/guides/configuration-guide/commons/timezone-4b5":{"__comp":"17896441","content":"a51f78bf"},"/docs/iaas/guides/configuration-guide/commons/user-8d4":{"__comp":"17896441","content":"119c53e5"},"/docs/iaas/guides/configuration-guide/configuration-repository-b47":{"__comp":"17896441","content":"767805d3"},"/docs/iaas/guides/configuration-guide/inventory-559":{"__comp":"17896441","content":"6db2ece2"},"/docs/iaas/guides/configuration-guide/loadbalancer-f93":{"__comp":"17896441","content":"dcbc8e94"},"/docs/iaas/guides/configuration-guide/manager-3a7":{"__comp":"17896441","content":"57b63ae3"},"/docs/iaas/guides/configuration-guide/network-7d8":{"__comp":"17896441","content":"8b8a137c"},"/docs/iaas/guides/configuration-guide/openstack/-318":{"__comp":"17896441","content":"d0ee365b"},"/docs/iaas/guides/configuration-guide/openstack/aodh-9b8":{"__comp":"17896441","content":"4d571bd0"},"/docs/iaas/guides/configuration-guide/openstack/barbican-d39":{"__comp":"17896441","content":"755df717"},"/docs/iaas/guides/configuration-guide/openstack/ceilometer-910":{"__comp":"17896441","content":"b77ceb62"},"/docs/iaas/guides/configuration-guide/openstack/cinder-e9b":{"__comp":"17896441","content":"4f363fd8"},"/docs/iaas/guides/configuration-guide/openstack/designate-14f":{"__comp":"17896441","content":"0f0de498"},"/docs/iaas/guides/configuration-guide/openstack/glance-c89":{"__comp":"17896441","content":"9490f32b"},"/docs/iaas/guides/configuration-guide/openstack/heat-e58":{"__comp":"17896441","content":"befb6565"},"/docs/iaas/guides/configuration-guide/openstack/horizon-f63":{"__comp":"17896441","content":"f385820d"},"/docs/iaas/guides/configuration-guide/openstack/ironic-7b4":{"__comp":"17896441","content":"b65fe363"},"/docs/iaas/guides/configuration-guide/openstack/keystone-5bb":{"__comp":"17896441","content":"be01f2a0"},"/docs/iaas/guides/configuration-guide/openstack/magnum-9df":{"__comp":"17896441","content":"7217b34c"},"/docs/iaas/guides/configuration-guide/openstack/manila-2b1":{"__comp":"17896441","content":"e20b631f"},"/docs/iaas/guides/configuration-guide/openstack/neutron-efe":{"__comp":"17896441","content":"bceb927f"},"/docs/iaas/guides/configuration-guide/openstack/nova-88d":{"__comp":"17896441","content":"c9581477"},"/docs/iaas/guides/configuration-guide/openstack/octavia-493":{"__comp":"17896441","content":"25cf6706"},"/docs/iaas/guides/configuration-guide/openstack/placement-d48":{"__comp":"17896441","content":"32dcd940"},"/docs/iaas/guides/configuration-guide/openstack/skyline-f6d":{"__comp":"17896441","content":"8e8909f7"},"/docs/iaas/guides/configuration-guide/proxy-f21":{"__comp":"17896441","content":"bd8a97c5"},"/docs/iaas/guides/configuration-guide/self-signed-certificates-70f":{"__comp":"17896441","content":"5b9bf978"},"/docs/iaas/guides/configuration-guide/services/-4fe":{"__comp":"17896441","content":"0047ab5d"},"/docs/iaas/guides/configuration-guide/services/chrony-6aa":{"__comp":"17896441","content":"a2317717"},"/docs/iaas/guides/configuration-guide/services/docker-bba":{"__comp":"17896441","content":"8679ddc4"},"/docs/iaas/guides/configuration-guide/services/tuned-3ce":{"__comp":"17896441","content":"c0e025b3"},"/docs/iaas/guides/configuration-guide/validations/-36a":{"__comp":"17896441","content":"16c50622"},"/docs/iaas/guides/deploy-guide/-0d0":{"__comp":"17896441","content":"09ba26e2"},"/docs/iaas/guides/deploy-guide/bootstrap-4b5":{"__comp":"17896441","content":"6c4198a1"},"/docs/iaas/guides/deploy-guide/examples/-d9c":{"__comp":"17896441","content":"6f1c571c"},"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box-449":{"__comp":"17896441","content":"5565c8ed"},"/docs/iaas/guides/deploy-guide/examples/testbed-50d":{"__comp":"17896441","content":"bd319452"},"/docs/iaas/guides/deploy-guide/manager-3b6":{"__comp":"17896441","content":"6f4a06ca"},"/docs/iaas/guides/deploy-guide/provisioning-d32":{"__comp":"17896441","content":"67dad519"},"/docs/iaas/guides/deploy-guide/seed-159":{"__comp":"17896441","content":"45f4377b"},"/docs/iaas/guides/deploy-guide/services/-38d":{"__comp":"17896441","content":"89ad43f4"},"/docs/iaas/guides/deploy-guide/services/ceph-daa":{"__comp":"17896441","content":"760c57f4"},"/docs/iaas/guides/deploy-guide/services/infrastructure-a32":{"__comp":"17896441","content":"589280f5"},"/docs/iaas/guides/deploy-guide/services/kubernetes-22e":{"__comp":"17896441","content":"cda5fe29"},"/docs/iaas/guides/deploy-guide/services/logging-monitoring-305":{"__comp":"17896441","content":"abecca15"},"/docs/iaas/guides/deploy-guide/services/network-87b":{"__comp":"17896441","content":"4b015924"},"/docs/iaas/guides/deploy-guide/services/openstack-ff3":{"__comp":"17896441","content":"f2a59390"},"/docs/iaas/guides/operations-guide/-a65":{"__comp":"17896441","content":"5bd7bc3b"},"/docs/iaas/guides/operations-guide/ceph-205":{"__comp":"17896441","content":"5d54de92"},"/docs/iaas/guides/operations-guide/infrastructure-4a9":{"__comp":"17896441","content":"d1c3b532"},"/docs/iaas/guides/operations-guide/manager/-be8":{"__comp":"17896441","content":"8fc094a7"},"/docs/iaas/guides/operations-guide/manager/apply-a48":{"__comp":"17896441","content":"abfb0638"},"/docs/iaas/guides/operations-guide/manager/console-99f":{"__comp":"17896441","content":"670b12e1"},"/docs/iaas/guides/operations-guide/manager/get-831":{"__comp":"17896441","content":"5199876b"},"/docs/iaas/guides/operations-guide/manager/log-be6":{"__comp":"17896441","content":"96f8fd49"},"/docs/iaas/guides/operations-guide/manager/task-78e":{"__comp":"17896441","content":"6d890b23"},"/docs/iaas/guides/operations-guide/network-061":{"__comp":"17896441","content":"d5947e44"},"/docs/iaas/guides/operations-guide/openstack/-b4a":{"__comp":"17896441","content":"d1aa920e"},"/docs/iaas/guides/operations-guide/openstack/cinder-186":{"__comp":"17896441","content":"a12f05ab"},"/docs/iaas/guides/operations-guide/openstack/keystone-7d7":{"__comp":"17896441","content":"748dce39"},"/docs/iaas/guides/operations-guide/openstack/neutron-675":{"__comp":"17896441","content":"d14d7097"},"/docs/iaas/guides/operations-guide/openstack/nova-373":{"__comp":"17896441","content":"8aade8b1"},"/docs/iaas/guides/operations-guide/openstack/octavia-639":{"__comp":"17896441","content":"f40b2df0"},"/docs/iaas/guides/operations-guide/openstack/tools/-cda":{"__comp":"17896441","content":"853df457"},"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager-4fc":{"__comp":"17896441","content":"6a0c14a5"},"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/-54e":{"__comp":"17896441","content":"5c2c818b"},"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update-3ac":{"__comp":"17896441","content":"0d2860b1"},"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor-049":{"__comp":"17896441","content":"94b13e0d"},"/docs/iaas/guides/operations-guide/openstack/tools/project-manager-87d":{"__comp":"17896441","content":"0121636f"},"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager-b80":{"__comp":"17896441","content":"b5a6d29b"},"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager-849":{"__comp":"17896441","content":"1967361e"},"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress-144":{"__comp":"17896441","content":"cf99a16e"},"/docs/iaas/guides/other-guides/-895":{"__comp":"17896441","content":"26dd306b"},"/docs/iaas/guides/other-guides/cloud-in-a-box-9e1":{"__comp":"17896441","content":"71499917"},"/docs/iaas/guides/other-guides/contributor-guide-815":{"__comp":"17896441","content":"5b235e06"},"/docs/iaas/guides/other-guides/developer-guide/-6cc":{"__comp":"17896441","content":"40d9468c"},"/docs/iaas/guides/other-guides/developer-guide/releases-f04":{"__comp":"17896441","content":"49993131"},"/docs/iaas/guides/other-guides/developer-guide/scripts-7e2":{"__comp":"17896441","content":"da1a5473"},"/docs/iaas/guides/other-guides/developer-guide/zuul-30c":{"__comp":"17896441","content":"9d49bc50"},"/docs/iaas/guides/other-guides/style-guide-b41":{"__comp":"17896441","content":"f0b55dfe"},"/docs/iaas/guides/other-guides/testbed-5a6":{"__comp":"17896441","content":"35b359a4"},"/docs/iaas/guides/troubleshooting-guide/-b72":{"__comp":"17896441","content":"ac087500"},"/docs/iaas/guides/troubleshooting-guide/ceph-23b":{"__comp":"17896441","content":"441bd449"},"/docs/iaas/guides/troubleshooting-guide/manager-558":{"__comp":"17896441","content":"eb99bfed"},"/docs/iaas/guides/troubleshooting-guide/openstack-ea9":{"__comp":"17896441","content":"c2f44c5f"},"/docs/iaas/guides/upgrade-guide/-f35":{"__comp":"17896441","content":"fff9aecb"},"/docs/iaas/guides/upgrade-guide/ceph-29d":{"__comp":"17896441","content":"070e71f0"},"/docs/iaas/guides/upgrade-guide/docker-9f3":{"__comp":"17896441","content":"26bc5a46"},"/docs/iaas/guides/upgrade-guide/infrastructure-12a":{"__comp":"17896441","content":"dbde4c02"},"/docs/iaas/guides/upgrade-guide/logging-monitoring-ed7":{"__comp":"17896441","content":"c75320ff"},"/docs/iaas/guides/upgrade-guide/manager-45f":{"__comp":"17896441","content":"ecbad217"},"/docs/iaas/guides/upgrade-guide/network-f8c":{"__comp":"17896441","content":"fa7c4c29"},"/docs/iaas/guides/upgrade-guide/openstack-9bc":{"__comp":"17896441","content":"6d32cafb"},"/docs/iaas/guides/user-guide/-fa4":{"__comp":"17896441","content":"dc09f893"},"/docs/iaas/guides/user-guide/migration-vmware-esix-633":{"__comp":"17896441","content":"a489f3d8"},"/docs/iaas/guides/user-guide/openstack/-b9e":{"__comp":"17896441","content":"bdaaff35"},"/docs/iaas/guides/user-guide/openstack/security-groups-ae9":{"__comp":"17896441","content":"aed2f698"},"/docs/iaas/guides/user-guide/openstack/user-data-backups-5cd":{"__comp":"17896441","content":"915e2cf4"},"/docs/iaas/guides/user-guide/security-groups/-486":{"__comp":"17896441","content":"7d3935d1"},"/docs/iaas/guides/user-guide/user-data-backups-a9b":{"__comp":"17896441","content":"8092c627"},"/docs/iaas/overview/architecture-74b":{"__comp":"17896441","content":"9f356e5b"},"/docs/iaas/overview/compute-d18":{"__comp":"17896441","content":"73956345"},"/docs/iaas/overview/knowledge-a22":{"__comp":"17896441","content":"0a757274"},"/docs/iaas/overview/network-abc":{"__comp":"17896441","content":"3e493f26"},"/docs/iaas/overview/storage-187":{"__comp":"17896441","content":"c0cd111c"},"/docs/iam/-a74":{"__comp":"17896441","content":"b8c7b97f"},"/docs/iam/domain-manager-setup-and-usage-c6a":{"__comp":"17896441","content":"67140352"},"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations-e86":{"__comp":"17896441","content":"88f37d1b"},"/docs/iam/SCS-example-setup-configuration-description-fa9":{"__comp":"17896441","content":"65742e9f"},"/docs/operating-scs/audits/-bcc":{"__comp":"17896441","content":"36f749d2"},"/docs/operating-scs/components/automated-pentesting/overview-5b4":{"__comp":"17896441","content":"5d503a86"},"/docs/operating-scs/components/automated-pentesting/tools-c74":{"__comp":"17896441","content":"7997867a"},"/docs/operating-scs/components/central-api/overview-b4c":{"__comp":"17896441","content":"b0ccdb87"},"/docs/operating-scs/components/central-api/poc-setup-647":{"__comp":"17896441","content":"9b5d9131"},"/docs/operating-scs/components/monitoring/docs/alertmanager-4f0":{"__comp":"17896441","content":"c6e1beb6"},"/docs/operating-scs/components/monitoring/docs/iaas-27c":{"__comp":"17896441","content":"e34f30ed"},"/docs/operating-scs/components/monitoring/docs/infrastructure_services-b85":{"__comp":"17896441","content":"53f25e30"},"/docs/operating-scs/components/monitoring/docs/k3s-4af":{"__comp":"17896441","content":"20da611c"},"/docs/operating-scs/components/monitoring/docs/kaas-819":{"__comp":"17896441","content":"2d071e49"},"/docs/operating-scs/components/monitoring/docs/oauth-e21":{"__comp":"17896441","content":"320ccb30"},"/docs/operating-scs/components/monitoring/docs/overview-961":{"__comp":"17896441","content":"0cb1d654"},"/docs/operating-scs/components/monitoring/docs/quickstart-a9d":{"__comp":"17896441","content":"19e9bde5"},"/docs/operating-scs/components/monitoring/docs/scs-deployment-8be":{"__comp":"17896441","content":"0e4c395f"},"/docs/operating-scs/components/monitoring/docs/tracing-207":{"__comp":"17896441","content":"55e21dcd"},"/docs/operating-scs/components/monitoring/docs/tuning-374":{"__comp":"17896441","content":"6d8acf16"},"/docs/operating-scs/components/monitoring/docs/zuul-6c6":{"__comp":"17896441","content":"013c29c1"},"/docs/operating-scs/components/status-page/docs/component_overview-8d2":{"__comp":"17896441","content":"e57b2c87"},"/docs/operating-scs/components/status-page/docs/components-9ea":{"__comp":"17896441","content":"99b53e63"},"/docs/operating-scs/components/status-page/docs/levels_of_consensus-eae":{"__comp":"17896441","content":"53596370"},"/docs/operating-scs/components/status-page/docs/overview-60c":{"__comp":"17896441","content":"9d187656"},"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install-ec3":{"__comp":"17896441","content":"b1fd1705"},"/docs/operating-scs/incident-management/-8c0":{"__comp":"17896441","content":"09adb968"},"/docs/operating-scs/lifecycle-management/-88c":{"__comp":"17896441","content":"a9f40339"},"/docs/operating-scs/logging/-ee2":{"__comp":"17896441","content":"343a1afc"},"/docs/operating-scs/metering/meter_configuration-124":{"__comp":"17896441","content":"41ab9761"},"/docs/operating-scs/monitoring/-799":{"__comp":"17896441","content":"15e4a743"},"/docs/operating-scs/overview-061":{"__comp":"17896441","content":"09cf625e"},"/docs/releases/Release0-984":{"__comp":"17896441","content":"7b787d81"},"/docs/releases/Release1-1b3":{"__comp":"17896441","content":"a3e11933"},"/docs/releases/Release2-9c9":{"__comp":"17896441","content":"7f1a31c3"},"/docs/releases/Release3-e73":{"__comp":"17896441","content":"5c201b0a"},"/docs/releases/Release4-9d8":{"__comp":"17896441","content":"437bedbc"},"/docs/releases/Release5-cb2":{"__comp":"17896441","content":"a0b1bbd7"},"/docs/releases/Release6-b81":{"__comp":"17896441","content":"2cc9d448"},"/docs/releases/ReleaseX-7e5":{"__comp":"17896441","content":"1bc22123"},"/docs/standards/-109":{"__comp":"17896441","content":"89176cae"},"/standards-966":{"__comp":"5e95c892","__context":{"plugin":"b12ed0df"}},"/standards-d52":{"__comp":"a7bd4aaa","version":"52e3f5ca"},"/standards-d9f":{"__comp":"a94703ab"},"/standards/-9e3":{"__comp":"17896441","content":"929c4e1b"},"/standards/certification/overview-9ab":{"__comp":"17896441","content":"0ea173ba"},"/standards/certification/scopes-versions-ede":{"__comp":"17896441","content":"5447d460"},"/standards/global/-f4a":{"__comp":"17896441","content":"38c9ef35"},"/standards/global/scs-0001-6bf":{"__comp":"17896441","content":"f9ec068e"},"/standards/global/scs-0002-08f":{"__comp":"17896441","content":"a70dabb3"},"/standards/global/scs-0003-9d4":{"__comp":"17896441","content":"7e7cf0e4"},"/standards/global/scs-0004-3df":{"__comp":"17896441","content":"9890ac63"},"/standards/global/scs-0112-f1d":{"__comp":"17896441","content":"42b29c77"},"/standards/iaas/-804":{"__comp":"17896441","content":"3f3928dc"},"/standards/iaas/scs-0100-933":{"__comp":"17896441","content":"f1715aef"},"/standards/iaas/scs-0101-42d":{"__comp":"17896441","content":"477ed06d"},"/standards/iaas/scs-0102-78a":{"__comp":"17896441","content":"184e5ead"},"/standards/iaas/scs-0103-2e0":{"__comp":"17896441","content":"6ad9ab45"},"/standards/iaas/scs-0104-018":{"__comp":"17896441","content":"97b1504a"},"/standards/iaas/scs-0110-edb":{"__comp":"17896441","content":"64f9507b"},"/standards/iaas/scs-0111-fa3":{"__comp":"17896441","content":"7ace79c4"},"/standards/iaas/scs-0113-819":{"__comp":"17896441","content":"a3dd9468"},"/standards/iaas/scs-0114-514":{"__comp":"17896441","content":"23d0e2bb"},"/standards/iaas/scs-0115-eb1":{"__comp":"17896441","content":"34c3e4b2"},"/standards/iam/-ac3":{"__comp":"17896441","content":"abb47370"},"/standards/iam/scs-0300-171":{"__comp":"17896441","content":"23e62f09"},"/standards/iam/scs-0301-e8e":{"__comp":"17896441","content":"b74e5806"},"/standards/iam/scs-0302-469":{"__comp":"17896441","content":"c8d5479b"},"/standards/kaas/-a87":{"__comp":"17896441","content":"f8869d03"},"/standards/kaas/scs-0200-316":{"__comp":"17896441","content":"4a61a7c1"},"/standards/kaas/scs-0210-03c":{"__comp":"17896441","content":"422fff4b"},"/standards/kaas/scs-0211-a83":{"__comp":"17896441","content":"59307471"},"/standards/kaas/scs-0212-4a5":{"__comp":"17896441","content":"65c1efe1"},"/standards/kaas/scs-0213-922":{"__comp":"17896441","content":"52ac6bcf"},"/standards/kaas/scs-0214-952":{"__comp":"17896441","content":"b1eed1ab"},"/standards/kaas/scs-0215-fcf":{"__comp":"17896441","content":"ef682180"},"/standards/kaas/scs-0216-090":{"__comp":"17896441","content":"7fd33963"},"/standards/kaas/scs-0217-a99":{"__comp":"17896441","content":"6ddb698c"},"/standards/kaas/scs-0218-c81":{"__comp":"17896441","content":"742db51e"},"/standards/ops/-234":{"__comp":"17896441","content":"178df98e"},"/standards/ops/scs-0400-24b":{"__comp":"17896441","content":"a52f8495"},"/standards/ops/scs-0401-a98":{"__comp":"17896441","content":"5abd544f"},"/standards/ops/scs-0402-b21":{"__comp":"17896441","content":"37a5cb6b"},"/standards/ops/scs-0403-425":{"__comp":"17896441","content":"22aa5ce0"},"/standards/ops/scs-0410-529":{"__comp":"17896441","content":"3d9e0922"},"/standards/ops/scs-0411-44d":{"__comp":"17896441","content":"093291a8"},"/standards/ops/scs-0412-8c6":{"__comp":"17896441","content":"03c8668f"},"/standards/scs-0001-v1-sovereign-cloud-standards-695":{"__comp":"17896441","content":"1c894279"},"/standards/scs-0002-v1-standards-docs-org-0d6":{"__comp":"17896441","content":"5b402526"},"/standards/scs-0002-v2-standards-docs-org-33f":{"__comp":"17896441","content":"7b449e09"},"/standards/scs-0003-v1-sovereign-cloud-standards-yaml-27f":{"__comp":"17896441","content":"32227eef"},"/standards/scs-0004-v1-achieving-certification-a54":{"__comp":"17896441","content":"c7e8a920"},"/standards/scs-0100-v1-flavor-naming-678":{"__comp":"17896441","content":"9d1324c7"},"/standards/scs-0100-v2-flavor-naming-c10":{"__comp":"17896441","content":"cd4fb20e"},"/standards/scs-0100-v3-flavor-naming-96d":{"__comp":"17896441","content":"061d8128"},"/standards/scs-0100-w1-flavor-naming-implementation-testing-6c8":{"__comp":"17896441","content":"640bb4cf"},"/standards/scs-0101-v1-entropy-474":{"__comp":"17896441","content":"63c8fde6"},"/standards/scs-0101-w1-entropy-implementation-testing-bff":{"__comp":"17896441","content":"bd8a0ffe"},"/standards/scs-0102-v1-image-metadata-173":{"__comp":"17896441","content":"ad39e84b"},"/standards/scs-0103-v1-standard-flavors-495":{"__comp":"17896441","content":"526992cf"},"/standards/scs-0104-v1-standard-images-cd2":{"__comp":"17896441","content":"a4833b52"},"/standards/scs-0110-v1-ssd-flavors-26f":{"__comp":"17896441","content":"1109f10b"},"/standards/scs-0111-v1-volume-type-decisions-8a3":{"__comp":"17896441","content":"699c0e5c"},"/standards/scs-0112-v1-sonic-a8a":{"__comp":"17896441","content":"28d842ee"},"/standards/scs-0113-v1-security-groups-decision-record-148":{"__comp":"17896441","content":"7cf96b3e"},"/standards/scs-0114-v1-volume-type-standard-161":{"__comp":"17896441","content":"04437fec"},"/standards/scs-0115-v1-default-rules-for-security-groups-e17":{"__comp":"17896441","content":"7aa8d561"},"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests-7f6":{"__comp":"17896441","content":"c3529e0a"},"/standards/scs-0210-v1-k8s-new-version-policy-267":{"__comp":"17896441","content":"c5533f5e"},"/standards/scs-0210-v2-k8s-version-policy-76e":{"__comp":"17896441","content":"f5b4e375"},"/standards/scs-0211-v1-kaas-default-storage-class-70e":{"__comp":"17896441","content":"07d3bac7"},"/standards/scs-0212-v1-requirements-for-container-registries-6e1":{"__comp":"17896441","content":"a35d3433"},"/standards/scs-0213-v1-k8s-nodes-anti-affinity-8e6":{"__comp":"17896441","content":"9278f3d6"},"/standards/scs-0214-v1-k8s-node-distribution-317":{"__comp":"17896441","content":"27f24dfd"},"/standards/scs-0215-v1-robustness-features-38c":{"__comp":"17896441","content":"0476f709"},"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks-a90":{"__comp":"17896441","content":"b262b314"},"/standards/scs-0217-v1-baseline-cluster-security-b32":{"__comp":"17896441","content":"3d23a943"},"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation-288":{"__comp":"17896441","content":"73512cb1"},"/standards/scs-0300-v1-requirements-for-sso-identity-federation-34f":{"__comp":"17896441","content":"f68824be"},"/standards/scs-0301-v1-naming-conventions-6f1":{"__comp":"17896441","content":"d59f7d52"},"/standards/scs-0302-v1-domain-manager-role-b43":{"__comp":"17896441","content":"4e6fa974"},"/standards/scs-0400-v1-status-page-create-decision-279":{"__comp":"17896441","content":"eea6a18c"},"/standards/scs-0401-v1-status-page-reference-implementation-decision-cc0":{"__comp":"17896441","content":"dfce392e"},"/standards/scs-0402-v1-status-page-openapi-spec-decision-191":{"__comp":"17896441","content":"fd34a958"},"/standards/scs-0403-v1-csp-kaas-observability-stack-bb8":{"__comp":"17896441","content":"70b53392"},"/standards/scs-0410-v1-gnocchi-as-metering-database-44a":{"__comp":"17896441","content":"0dfeccb2"},"/standards/scs-0411-v1-publishing_method_for_metering_data-dbc":{"__comp":"17896441","content":"1276f6ab"},"/standards/scs-0412-v1-metering-json-3cc":{"__comp":"17896441","content":"a15c4cb6"},"/standards/scs-compatible-iaas-d6e":{"__comp":"17896441","content":"b191927f"},"/standards/scs-compatible-kaas-dc7":{"__comp":"17896441","content":"efbcd183"},"/standards/scs-XXXX-vN-decision-record-template-7f7":{"__comp":"17896441","content":"e2dcdabe"},"/standards/scs-XXXX-vN-standard-template-a6a":{"__comp":"17896441","content":"a24f5044"},"/standards/standards/overview-1dc":{"__comp":"17896441","content":"5830dd0a"},"/-6ae":{"__comp":"1df93b7f","__context":{"plugin":"a7434565"},"config":"5e9f5e1a"}}')}},e=>{e.O(0,[1869],(()=>{return t=38536,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/assets/js/main.526c55e4.js.LICENSE.txt b/assets/js/main.526c55e4.js.LICENSE.txt new file mode 100644 index 0000000000..5b49ae6363 --- /dev/null +++ b/assets/js/main.526c55e4.js.LICENSE.txt @@ -0,0 +1,126 @@ +/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT */ + +/*! + * lunr.Builder + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Set + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.TokenSet + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Vector + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.stemmer + * Copyright (C) 2020 Oliver Nightingale + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + */ + +/*! + * lunr.stopWordFilter + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.tokenizer + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.trimmer + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! Bundled license information: + +prismjs/prism.js: + (** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT <https://opensource.org/licenses/MIT> + * @author Lea Verou <https://lea.verou.me> + * @namespace + * @public + *) +*/ + +/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @license React + * react-jsx-runtime.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @license React + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */ + +/** @license React v16.13.1 + * react-is.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ diff --git a/assets/js/runtime~main.6c649f46.js b/assets/js/runtime~main.6c649f46.js new file mode 100644 index 0000000000..f14bc39d34 --- /dev/null +++ b/assets/js/runtime~main.6c649f46.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,c,f,b,d,a={},t={};function r(e){var c=t[e];if(void 0!==c)return c.exports;var f=t[e]={exports:{}};return a[e].call(f.exports,f,f.exports,r),f.exports}r.m=a,e=[],r.O=(c,f,b,d)=>{if(!f){var a=1/0;for(i=0;i<e.length;i++){f=e[i][0],b=e[i][1],d=e[i][2];for(var t=!0,o=0;o<f.length;o++)(!1&d||a>=d)&&Object.keys(r.O).every((e=>r.O[e](f[o])))?f.splice(o--,1):(t=!1,d<a&&(a=d));if(t){e.splice(i--,1);var n=b();void 0!==n&&(c=n)}}return c}d=d||0;for(var i=e.length;i>0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[f,b,d]},r.n=e=>{var c=e&&e.__esModule?()=>e.default:()=>e;return r.d(c,{a:c}),c},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,b){if(1&b&&(e=this(e)),8&b)return e;if("object"==typeof e&&e){if(4&b&&e.__esModule)return e;if(16&b&&"function"==typeof e.then)return e}var d=Object.create(null);r.r(d);var a={};c=c||[null,f({}),f([]),f(f)];for(var t=2&b&&e;"object"==typeof t&&!~c.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((c=>a[c]=()=>e[c]));return a.default=()=>e,r.d(d,a),d},r.d=(e,c)=>{for(var f in c)r.o(c,f)&&!r.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:c[f]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((c,f)=>(r.f[f](e,c),c)),[])),r.u=e=>"assets/js/"+({82:"748dce39",86:"32dcd940",123:"a35d3433",126:"c49f9378",163:"34c3e4b2",192:"7bd33c3d",272:"e20b631f",282:"42088e64",308:"4edc808e",309:"71acf54e",332:"53f25e30",344:"0476f709",445:"dbde4c02",458:"07d3bac7",462:"bdcb5fea",467:"d71eca41",550:"08602342",557:"4e6fa974",603:"a51c5cdb",643:"5bd7bc3b",660:"c2f44c5f",667:"96f8fd49",675:"7850b12c",714:"cffc493c",751:"f9ec068e",778:"f5b4e375",783:"40d9468c",801:"b12ed0df",825:"a51f78bf",904:"9278f3d6",923:"013c29c1",942:"6ad9ab45",953:"2d071e49",974:"7ace79c4",988:"184e5ead",1001:"5b402526",1009:"061d8128",1014:"3d23a943",1026:"2ce1dccd",1085:"0bcc5672",1093:"ebcea0bb",1099:"e2dcdabe",1153:"1c091541",1238:"657efcba",1255:"1722e234",1276:"093291a8",1284:"d5ac8ed7",1290:"a15c4cb6",1298:"9890ac63",1335:"1e818dbe",1346:"45f4377b",1349:"29331985",1351:"066abe51",1362:"7aa8d561",1384:"37a5cb6b",1400:"61171858",1407:"c75320ff",1421:"53596370",1427:"9b5d9131",1468:"2d3bf848",1475:"526992cf",1479:"f0e20cb6",1489:"b840bdcc",1528:"b501f8e8",1542:"c7e8a920",1548:"a94c36cd",1572:"19cb43cd",1617:"35fbae7a",1678:"a7434565",1734:"afaff11a",1804:"1c894279",1810:"55e21dcd",1822:"23cd166f",1844:"9f356e5b",1903:"acecf23e",1909:"e44168e5",1911:"420452be",1945:"0050251a",1953:"685813dc",1991:"b2b675dd",2016:"5565c8ed",2069:"3d9e0922",2076:"4b015924",2078:"f2a59390",2106:"04fe2bfd",2126:"f4cdb2d9",2138:"1a4e3797",2151:"88684b71",2179:"c0e025b3",2257:"7b787d81",2283:"c5479f59",2294:"03babb4a",2309:"de6833f9",2342:"26dd306b",2372:"6f4a06ca",2441:"4e607b99",2456:"950c7487",2479:"fe5fac7c",2526:"edc931f8",2544:"096c51c8",2546:"e6095437",2621:"5c201b0a",2637:"59307471",2683:"7d3935d1",2692:"441ae8e9",2710:"fff06078",2711:"9e4087bc",2747:"abd7a988",2758:"6e5bfc33",2798:"c9b16325",2840:"cda5fe29",2884:"89ad43f4",2914:"26bc5a46",2932:"431e6cfe",3008:"5199876b",3012:"38b583d2",3043:"287cd167",3086:"ad1cb202",3131:"38c9ef35",3153:"b8fd74b5",3213:"3f3928dc",3249:"ccc49370",3365:"86ee3414",3374:"6d8acf16",3384:"0e4c395f",3400:"a2317717",3402:"9a7c0197",3405:"28d842ee",3416:"8ba37aa2",3429:"32227eef",3444:"19f6a518",3453:"a12f05ab",3475:"b65fe363",3502:"477ed06d",3527:"dc09f893",3530:"589280f5",3536:"bd8a97c5",3574:"2cc9d448",3575:"67140352",3605:"1109f10b",3637:"d6a104fd",3639:"f40b2df0",3649:"fff9aecb",3663:"8db05b07",3681:"b262b314",3705:"4a61a7c1",3714:"3d19221e",3725:"699c0e5c",3734:"66dc81f9",3767:"09cf625e",3782:"a38b6a75",3802:"929c4e1b",3867:"306a8c6c",3874:"9490f32b",3881:"5447d460",3894:"1f34ee25",3919:"670b12e1",3920:"d1aa920e",3934:"d770ad8d",3942:"3bf9fbe6",3953:"83100446",4016:"e57b2c87",4111:"1bc22123",4132:"27f24dfd",4168:"63c8fde6",4175:"19e9bde5",4257:"45bfeaeb",4277:"8d25d5d4",4331:"6d890b23",4342:"0dfeccb2",4346:"97b1504a",4365:"853df457",4385:"760c57f4",4398:"dfce392e",4480:"e24c1f8d",4485:"1967361e",4497:"bd8a0ffe",4503:"95d93785",4507:"03c8668f",4583:"1df93b7f",4602:"36f749d2",4604:"6e45ed1a",4605:"4f363fd8",4612:"7e7cf0e4",4625:"cd0ad4f0",4657:"ad39e84b",4684:"1276f6ab",4712:"16c50622",4717:"8a671cf8",4730:"b74e5806",4807:"739c0ae8",4810:"6c33bb99",4813:"6875c492",4840:"19afbcc8",4850:"87293620",4855:"cf99a16e",4869:"7023f74c",4880:"8092c627",4979:"f17f9c44",4980:"67dad519",4984:"7bed4829",5e3:"71499917",5013:"0f0de498",5019:"14c1041d",5054:"8493ac52",5058:"0047ab5d",5075:"a70dabb3",5122:"fa7c4c29",5123:"7b449e09",5139:"d59f7d52",5147:"65742e9f",5162:"caeeb51c",5213:"d7951534",5251:"012688b3",5341:"0ea173ba",5429:"755df717",5515:"95800b3e",5533:"15336817",5546:"452be0ad",5548:"247783bb",5564:"7ebec009",5568:"a52c62d4",5575:"cbf20d25",5595:"f8869d03",5609:"15e4a743",5612:"aed2f698",5658:"2ee7a08a",5663:"65c1efe1",5673:"89176cae",5676:"41ab9761",5679:"6ddb698c",5743:"3ff13a62",5752:"0121636f",5770:"7cf96b3e",5773:"5b9bf978",5790:"64f9507b",5875:"9d49bc50",5894:"b2f554cd",5978:"6d32cafb",5985:"65c90e53",5997:"dfe27b1e",6018:"a3dd9468",6029:"3e493f26",6063:"eb99bfed",6070:"f68824be",6083:"73956345",6088:"9fb1f91e",6098:"7217b34c",6147:"a63812ab",6148:"09adb968",6164:"a9f40339",6165:"cd4fb20e",6172:"9099a3d2",6182:"0cb1d654",6183:"f793d2d5",6211:"e34f30ed",6217:"a8ea16f4",6223:"d0ee365b",6227:"422fff4b",6251:"8fc094a7",6290:"ff45c01b",6293:"c9581477",6305:"8aade8b1",6323:"23d0e2bb",6358:"640bb4cf",6370:"f0b55dfe",6372:"2abb9c6f",6443:"b8c7b97f",6452:"b191927f",6454:"ecbad217",6529:"97ef9758",6568:"9d1324c7",6646:"b0ccdb87",6647:"f1715aef",6707:"5b909c46",6734:"88f37d1b",6793:"abfb0638",6805:"9d187656",6831:"df35cf96",6871:"c3529e0a",6910:"22aa5ce0",6960:"8679ddc4",6969:"14eb3368",6971:"bd319452",6985:"7997867a",6986:"bccb1b42",7020:"befb6565",7051:"e0c197a4",7074:"8b8a137c",7085:"c6e1beb6",7098:"a7bd4aaa",7104:"25cf6706",7125:"da1a5473",7129:"f14351c1",7148:"0d2860b1",7153:"5c2c818b",7157:"52e3f5ca",7255:"070e71f0",7299:"5d54de92",7362:"b1eed1ab",7456:"abb47370",7472:"814f3328",7479:"0bb6d954",7491:"20da611c",7560:"abecca15",7633:"eaf69a59",7638:"6c4198a1",7643:"a6aa9e1f",7653:"653904f7",7677:"320ccb30",7683:"35b359a4",7731:"ef682180",7743:"931040e8",7753:"a4833b52",7778:"2886628e",7810:"1ca0f8e7",7813:"52ac6bcf",7841:"f385820d",7861:"d5947e44",7919:"d14d7097",7938:"b7cec31e",7980:"a708848c",7984:"a0b1bbd7",7990:"059c4264",8029:"178df98e",8031:"3a1d878d",8071:"6f1c571c",8081:"bceb927f",8128:"a489f3d8",8169:"50963409",8200:"95967863",8209:"01a85c17",8215:"b1fd1705",8220:"193dc870",8226:"b5a6d29b",8296:"0a757274",8384:"3ad2c61e",8401:"17896441",8407:"119c53e5",8411:"ac087500",8460:"49993131",8462:"69b09ea9",8463:"a8f67d60",8477:"c0cd111c",8502:"6bcd11f8",8519:"767805d3",8523:"5b235e06",8526:"7fd33963",8533:"97630173",8547:"29c2cfba",8561:"502adbf6",8581:"935f2afb",8592:"49bc3785",8612:"94298c6b",8730:"ea470413",8752:"564eabfd",8767:"42b29c77",8777:"5d503a86",8781:"742db51e",8805:"4468ebd1",8834:"6a0c14a5",8897:"73512cb1",8965:"343a1afc",8966:"23e62f09",8981:"dcf2f717",8992:"d1c3b532",9048:"a94703ab",9049:"fd34a958",9063:"bdaaff35",9075:"04437fec",9088:"94b13e0d",9093:"efbcd183",9110:"70b53392",9121:"f91986bc",9176:"5830dd0a",9226:"4d571bd0",9244:"09ba26e2",9245:"eea6a18c",9260:"915e2cf4",9267:"a7023ddc",9289:"c8d5479b",9305:"421b5e65",9346:"c5533f5e",9356:"6db2ece2",9376:"62337dff",9382:"03412b54",9390:"b08c16de",9401:"2163574d",9407:"8e8909f7",9432:"e747ec83",9441:"5abd544f",9464:"7f1a31c3",9495:"dcbc8e94",9525:"60fc342f",9539:"57b63ae3",9565:"c8b68b4a",9579:"99b53e63",9647:"5e95c892",9648:"5cc619f0",9657:"a3e11933",9689:"b77ceb62",9691:"a52f8495",9730:"4129286c",9745:"437bedbc",9752:"94f31572",9755:"a24f5044",9766:"36c47bdd",9807:"ce756c16",9823:"05e7973d",9850:"95fe5f6c",9851:"441bd449",9864:"ef9d238d",9866:"0683500c",9954:"be01f2a0"}[e]||e)+"."+{4:"b946d741",82:"aedc43d8",86:"0e700c54",123:"13bf18b8",126:"e0e556db",163:"940ac935",192:"3e0ed241",272:"5e57a496",282:"c457a555",308:"11fb0f02",309:"fc90ca36",332:"9e4b9bb0",344:"806a849f",445:"e0c3d061",458:"95a25b7b",462:"edcff60b",467:"b7d26cbd",489:"79124cfe",550:"06e535ee",557:"c357784d",603:"5f154dac",643:"65e12fbc",660:"78af2a24",667:"68f0f7ba",675:"088a57d9",714:"4c800dbc",751:"642d4808",778:"b7e722cd",783:"b9fc055a",801:"7d9631b4",825:"00caed35",904:"4c9c2f47",923:"c2633f9c",942:"c14e6bfd",953:"d7c0dd51",974:"595aface",988:"35bcfc20",1001:"3e7c75e7",1009:"ad00fbf8",1014:"69553362",1026:"a0c204ee",1085:"a424e230",1093:"ed4e92bb",1099:"6abe1a01",1153:"6bb09c75",1169:"d139adc3",1176:"dc521de4",1238:"61d46c3f",1255:"73593b86",1276:"3c7f3f62",1284:"4c4ddfba",1290:"0ac7da5c",1298:"5c6d014d",1335:"234b8edf",1346:"45d54f9b",1349:"aac2af9c",1351:"ac412564",1362:"db98d47a",1384:"472dae82",1400:"74c41916",1407:"3a258087",1421:"541b1a61",1427:"f81de50f",1468:"b2f53ccd",1475:"7b421abc",1479:"b5360c37",1489:"41fc9292",1528:"eb253035",1542:"cc23dc14",1548:"721ebba8",1555:"5c3ca885",1572:"51059fbb",1617:"f798cb6d",1678:"d434193e",1734:"f597fe7b",1804:"f0b684a4",1810:"beb09bec",1822:"73436cd0",1844:"6a0bc2b3",1903:"92dddac5",1909:"14af424f",1911:"5b959566",1945:"1dccdf1d",1953:"efaf89c6",1991:"ed31b25c",2016:"630ca6bf",2049:"521b0348",2069:"7b202a02",2076:"270c4b17",2078:"71551bb2",2106:"0fd858a8",2126:"a3048f4c",2130:"4a68cd24",2138:"146bb652",2151:"5a5acb4c",2179:"ecc43a90",2235:"f5e36d9c",2237:"ac9ee37e",2257:"a054ef5e",2283:"125dae58",2294:"4f8df050",2309:"aaec887b",2317:"dcc57e24",2342:"b508ea24",2372:"20889c99",2441:"52488ba2",2456:"029c2414",2479:"330500c2",2526:"1792b3a0",2544:"35280a0c",2546:"218c6e9b",2621:"8fe0e868",2637:"5752c851",2683:"75c6af94",2692:"22b363c5",2710:"cdcf3986",2711:"a8acb5d3",2746:"313ca11d",2747:"03788a57",2758:"ca3dd247",2798:"31b26ab4",2840:"7460ccbb",2884:"6d3b4c61",2914:"0e03375d",2932:"c63ebe0e",3008:"3805c215",3012:"7eb273cc",3043:"bcb88876",3086:"3cbe03e8",3131:"3cdf3303",3132:"9308a2c3",3153:"e8238985",3213:"cf5405a4",3249:"2a272f26",3365:"b8446b41",3374:"1ce4a660",3384:"c529dc49",3400:"a9b8ac04",3402:"dc6369a8",3405:"2fe1a43e",3416:"c4cdbc29",3429:"33868d63",3444:"99481938",3453:"abcb42fa",3475:"6eb913dc",3498:"52731744",3502:"ed5b7321",3527:"7e2a0e7e",3530:"20dd2887",3536:"9b5f1b3b",3574:"d52aa333",3575:"7db3c496",3605:"ab17e07d",3637:"15cd917a",3639:"37a8c2e3",3649:"bf1dc315",3663:"24ad3227",3681:"06be2c4f",3705:"9963015b",3714:"ca825484",3725:"f4efe239",3734:"632aa600",3767:"f61956bd",3771:"46254ee5",3782:"17b79818",3802:"b628b7cf",3863:"e17ac104",3867:"152a5819",3874:"757e45e3",3881:"0014e23d",3894:"7b047a05",3919:"f150d3b8",3920:"0bf904c1",3934:"e8d173bf",3942:"456b5e1f",3953:"f32a0f06",4016:"50198570",4111:"ee840646",4132:"dd03ec43",4168:"f8e64bd7",4175:"ea612119",4257:"6bb0f898",4277:"a5124146",4331:"796ee042",4342:"6d504488",4346:"eb7eeb20",4365:"f1079892",4385:"e9dc72b5",4398:"d2604902",4480:"2c71dde7",4485:"967b6b8f",4497:"c55b522d",4503:"d32a37bc",4507:"54609418",4583:"6e5e7eaa",4602:"74efae0f",4604:"102bbdc2",4605:"020c221f",4612:"889e6837",4625:"5cf16ef4",4657:"3bccaa94",4684:"d252c887",4712:"a60a3434",4717:"3c6e95e1",4730:"bdab4d88",4807:"72f072ee",4810:"6d7973e3",4813:"fbd1a093",4840:"6a8cd82b",4850:"e6e8b3d7",4855:"19992781",4869:"bba7410f",4880:"c98f6819",4979:"ffa3ee7d",4980:"7de71521",4984:"f6c31600",5e3:"36aaf16a",5013:"c14704ce",5019:"5375728f",5054:"0281f0fe",5058:"234fa37c",5075:"321321ab",5122:"ea6333de",5123:"d5ac906f",5139:"36164d0d",5147:"9bf832bd",5162:"4b40ede3",5213:"7b710812",5251:"b692a51a",5309:"a831c364",5341:"3011feb1",5429:"5f5b8d3a",5515:"192dcdf0",5533:"730364fd",5546:"f9df0f84",5548:"1565db2f",5564:"418e9656",5568:"0205f572",5575:"d6fa266e",5595:"9188ac6a",5609:"23ea2fbb",5612:"5cb1fd01",5642:"33e06e4a",5658:"d998810b",5663:"e11b1659",5673:"79fc0195",5676:"3c032c6d",5679:"87b117c5",5688:"e3378d6d",5741:"7580ffe7",5743:"f29e7019",5752:"45072d36",5770:"a51eef9c",5773:"bacb2041",5790:"1afbc06e",5829:"bd6e68ee",5875:"b55b5ac4",5894:"a5e6b8a9",5978:"ffa189f3",5985:"2b1ac8ca",5997:"bf7b4d35",6018:"2b30eec9",6029:"445fd139",6063:"6c5daf69",6070:"2441b326",6083:"5376df3f",6088:"4f451039",6098:"ddce5803",6147:"92e0cba0",6148:"8b72dde4",6164:"add3d305",6165:"7c85fa2a",6172:"aa79434b",6182:"f5b017f6",6183:"b0d753df",6211:"22428f34",6216:"176d45ea",6217:"a91fb1ee",6223:"cbfaa316",6227:"628ec50d",6251:"8dc38e73",6290:"31043445",6292:"394c3d84",6293:"346dbb98",6305:"61ea1937",6323:"f150b016",6358:"0cfb36a2",6370:"9e8e6e39",6372:"1841fc9f",6443:"d8b02d92",6452:"365feba3",6454:"b83bfb92",6506:"4add14f3",6529:"97b043ea",6568:"ef1eeb3a",6646:"0ff93353",6647:"7e1a6623",6707:"c91cf602",6734:"5268da7b",6793:"6b373363",6805:"62ab2c10",6831:"f061bf46",6871:"3b179dfc",6910:"7a834602",6960:"81b643e4",6969:"09aca591",6971:"482f2c1c",6985:"3ab5cf09",6986:"a2dde942",7020:"9fd54aac",7051:"c3013477",7074:"b2b371d7",7085:"39ef61f2",7098:"cd50302a",7104:"68184cdc",7121:"d558c084",7125:"af5ff840",7129:"9a05821d",7147:"af638f0b",7148:"8cb35890",7153:"3ee91200",7157:"f927ba35",7200:"2d36d6d5",7211:"cad29de9",7255:"abcbc390",7299:"3925fe91",7308:"95db45a6",7362:"02c0bb47",7440:"1c1d16a2",7456:"bffd9785",7472:"48ccac70",7479:"1f11afbc",7491:"b1d46624",7560:"82183737",7633:"c5520334",7638:"9e743a10",7643:"4145c44f",7653:"8ecb6807",7677:"348a2cf8",7683:"3bb7526f",7731:"25ac95f0",7743:"b02c7073",7753:"9c1ac905",7778:"9895b216",7810:"53b97c85",7813:"23b059f0",7841:"f66f48cd",7861:"aa7d2742",7919:"55a1c622",7938:"cb1af7da",7980:"45ed87c9",7984:"81d4ebbc",7990:"bb649876",8029:"f5c2a862",8031:"8acba785",8071:"6cc3f4b2",8081:"11b77b9d",8128:"ba23aa58",8159:"d20bf7bf",8169:"9df6f406",8200:"b925d6f1",8209:"8945e087",8215:"a2e6f9d5",8220:"7589d2a8",8226:"e79829b4",8296:"4eb45089",8327:"fc19b891",8384:"4f252055",8401:"c03dac50",8407:"1c68010a",8411:"442bc6d0",8444:"e056eb00",8460:"9f0a6e53",8462:"8e83441e",8463:"2dd1c83c",8477:"b093c63e",8502:"4dfd4edc",8519:"e8fd2720",8523:"b07b499e",8526:"feca781d",8533:"b98d5be3",8547:"867c3231",8561:"6527a76e",8581:"3d5daa2c",8592:"f3702487",8609:"ef47321b",8612:"4f435156",8730:"f68b4421",8747:"d998ad87",8752:"0c7dcb95",8767:"5eb8c03c",8777:"a360d6a7",8781:"eadccafc",8805:"a0f8510c",8834:"07eefbbf",8897:"66b7c61b",8947:"26a7a172",8965:"2754cdd5",8966:"feb0beea",8981:"994920ad",8992:"1a94fcfd",9048:"1764b2a4",9049:"41b5a613",9063:"5ff36000",9075:"213a5ef8",9088:"a2fb603b",9093:"416334ba",9110:"96f3eb66",9121:"707058ad",9176:"4ff1620e",9226:"7f888589",9244:"743ba604",9245:"28e397b4",9260:"5887122e",9267:"6dc95e53",9289:"8ad6fee8",9305:"1d4e25e2",9346:"ec9312a9",9356:"066950d7",9376:"5679955b",9382:"4e252d50",9390:"35c78cc2",9401:"ef5efc13",9407:"62db56cb",9432:"c7e4b16c",9441:"66cd3a76",9464:"1c30dcee",9469:"9cb41622",9495:"d46906e1",9525:"07f52dea",9539:"4f733c75",9565:"a4351b5b",9579:"822f2b46",9647:"2c202730",9648:"afd68d1a",9657:"b1d84099",9688:"2bdfb4b9",9689:"56e89464",9691:"c6f0d514",9730:"fcb59d86",9745:"8d085187",9752:"7a306872",9755:"95e7fbd3",9766:"ae03502f",9807:"fc974905",9823:"e7395588",9850:"1582ab24",9851:"a4f3568e",9864:"72cad001",9866:"5562918c",9954:"c8c515a3"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,c)=>Object.prototype.hasOwnProperty.call(e,c),b={},d="docs:",r.l=(e,c,f,a)=>{if(b[e])b[e].push(c);else{var t,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var u=n[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==d+f){t=u;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",d+f),t.src=e),b[e]=[c];var l=(c,f)=>{t.onerror=t.onload=null,clearTimeout(s);var d=b[e];if(delete b[e],t.parentNode&&t.parentNode.removeChild(t),d&&d.forEach((e=>e(f))),c)return c(f)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={15336817:"5533",17896441:"8401",29331985:"1349",49993131:"8460",50963409:"8169",53596370:"1421",59307471:"2637",61171858:"1400",67140352:"3575",71499917:"5000",73956345:"6083",83100446:"3953",87293620:"4850",95967863:"8200",97630173:"8533","748dce39":"82","32dcd940":"86",a35d3433:"123",c49f9378:"126","34c3e4b2":"163","7bd33c3d":"192",e20b631f:"272","42088e64":"282","4edc808e":"308","71acf54e":"309","53f25e30":"332","0476f709":"344",dbde4c02:"445","07d3bac7":"458",bdcb5fea:"462",d71eca41:"467","08602342":"550","4e6fa974":"557",a51c5cdb:"603","5bd7bc3b":"643",c2f44c5f:"660","96f8fd49":"667","7850b12c":"675",cffc493c:"714",f9ec068e:"751",f5b4e375:"778","40d9468c":"783",b12ed0df:"801",a51f78bf:"825","9278f3d6":"904","013c29c1":"923","6ad9ab45":"942","2d071e49":"953","7ace79c4":"974","184e5ead":"988","5b402526":"1001","061d8128":"1009","3d23a943":"1014","2ce1dccd":"1026","0bcc5672":"1085",ebcea0bb:"1093",e2dcdabe:"1099","1c091541":"1153","657efcba":"1238","1722e234":"1255","093291a8":"1276",d5ac8ed7:"1284",a15c4cb6:"1290","9890ac63":"1298","1e818dbe":"1335","45f4377b":"1346","066abe51":"1351","7aa8d561":"1362","37a5cb6b":"1384",c75320ff:"1407","9b5d9131":"1427","2d3bf848":"1468","526992cf":"1475",f0e20cb6:"1479",b840bdcc:"1489",b501f8e8:"1528",c7e8a920:"1542",a94c36cd:"1548","19cb43cd":"1572","35fbae7a":"1617",a7434565:"1678",afaff11a:"1734","1c894279":"1804","55e21dcd":"1810","23cd166f":"1822","9f356e5b":"1844",acecf23e:"1903",e44168e5:"1909","420452be":"1911","0050251a":"1945","685813dc":"1953",b2b675dd:"1991","5565c8ed":"2016","3d9e0922":"2069","4b015924":"2076",f2a59390:"2078","04fe2bfd":"2106",f4cdb2d9:"2126","1a4e3797":"2138","88684b71":"2151",c0e025b3:"2179","7b787d81":"2257",c5479f59:"2283","03babb4a":"2294",de6833f9:"2309","26dd306b":"2342","6f4a06ca":"2372","4e607b99":"2441","950c7487":"2456",fe5fac7c:"2479",edc931f8:"2526","096c51c8":"2544",e6095437:"2546","5c201b0a":"2621","7d3935d1":"2683","441ae8e9":"2692",fff06078:"2710","9e4087bc":"2711",abd7a988:"2747","6e5bfc33":"2758",c9b16325:"2798",cda5fe29:"2840","89ad43f4":"2884","26bc5a46":"2914","431e6cfe":"2932","5199876b":"3008","38b583d2":"3012","287cd167":"3043",ad1cb202:"3086","38c9ef35":"3131",b8fd74b5:"3153","3f3928dc":"3213",ccc49370:"3249","86ee3414":"3365","6d8acf16":"3374","0e4c395f":"3384",a2317717:"3400","9a7c0197":"3402","28d842ee":"3405","8ba37aa2":"3416","32227eef":"3429","19f6a518":"3444",a12f05ab:"3453",b65fe363:"3475","477ed06d":"3502",dc09f893:"3527","589280f5":"3530",bd8a97c5:"3536","2cc9d448":"3574","1109f10b":"3605",d6a104fd:"3637",f40b2df0:"3639",fff9aecb:"3649","8db05b07":"3663",b262b314:"3681","4a61a7c1":"3705","3d19221e":"3714","699c0e5c":"3725","66dc81f9":"3734","09cf625e":"3767",a38b6a75:"3782","929c4e1b":"3802","306a8c6c":"3867","9490f32b":"3874","5447d460":"3881","1f34ee25":"3894","670b12e1":"3919",d1aa920e:"3920",d770ad8d:"3934","3bf9fbe6":"3942",e57b2c87:"4016","1bc22123":"4111","27f24dfd":"4132","63c8fde6":"4168","19e9bde5":"4175","45bfeaeb":"4257","8d25d5d4":"4277","6d890b23":"4331","0dfeccb2":"4342","97b1504a":"4346","853df457":"4365","760c57f4":"4385",dfce392e:"4398",e24c1f8d:"4480","1967361e":"4485",bd8a0ffe:"4497","95d93785":"4503","03c8668f":"4507","1df93b7f":"4583","36f749d2":"4602","6e45ed1a":"4604","4f363fd8":"4605","7e7cf0e4":"4612",cd0ad4f0:"4625",ad39e84b:"4657","1276f6ab":"4684","16c50622":"4712","8a671cf8":"4717",b74e5806:"4730","739c0ae8":"4807","6c33bb99":"4810","6875c492":"4813","19afbcc8":"4840",cf99a16e:"4855","7023f74c":"4869","8092c627":"4880",f17f9c44:"4979","67dad519":"4980","7bed4829":"4984","0f0de498":"5013","14c1041d":"5019","8493ac52":"5054","0047ab5d":"5058",a70dabb3:"5075",fa7c4c29:"5122","7b449e09":"5123",d59f7d52:"5139","65742e9f":"5147",caeeb51c:"5162",d7951534:"5213","012688b3":"5251","0ea173ba":"5341","755df717":"5429","95800b3e":"5515","452be0ad":"5546","247783bb":"5548","7ebec009":"5564",a52c62d4:"5568",cbf20d25:"5575",f8869d03:"5595","15e4a743":"5609",aed2f698:"5612","2ee7a08a":"5658","65c1efe1":"5663","89176cae":"5673","41ab9761":"5676","6ddb698c":"5679","3ff13a62":"5743","0121636f":"5752","7cf96b3e":"5770","5b9bf978":"5773","64f9507b":"5790","9d49bc50":"5875",b2f554cd:"5894","6d32cafb":"5978","65c90e53":"5985",dfe27b1e:"5997",a3dd9468:"6018","3e493f26":"6029",eb99bfed:"6063",f68824be:"6070","9fb1f91e":"6088","7217b34c":"6098",a63812ab:"6147","09adb968":"6148",a9f40339:"6164",cd4fb20e:"6165","9099a3d2":"6172","0cb1d654":"6182",f793d2d5:"6183",e34f30ed:"6211",a8ea16f4:"6217",d0ee365b:"6223","422fff4b":"6227","8fc094a7":"6251",ff45c01b:"6290",c9581477:"6293","8aade8b1":"6305","23d0e2bb":"6323","640bb4cf":"6358",f0b55dfe:"6370","2abb9c6f":"6372",b8c7b97f:"6443",b191927f:"6452",ecbad217:"6454","97ef9758":"6529","9d1324c7":"6568",b0ccdb87:"6646",f1715aef:"6647","5b909c46":"6707","88f37d1b":"6734",abfb0638:"6793","9d187656":"6805",df35cf96:"6831",c3529e0a:"6871","22aa5ce0":"6910","8679ddc4":"6960","14eb3368":"6969",bd319452:"6971","7997867a":"6985",bccb1b42:"6986",befb6565:"7020",e0c197a4:"7051","8b8a137c":"7074",c6e1beb6:"7085",a7bd4aaa:"7098","25cf6706":"7104",da1a5473:"7125",f14351c1:"7129","0d2860b1":"7148","5c2c818b":"7153","52e3f5ca":"7157","070e71f0":"7255","5d54de92":"7299",b1eed1ab:"7362",abb47370:"7456","814f3328":"7472","0bb6d954":"7479","20da611c":"7491",abecca15:"7560",eaf69a59:"7633","6c4198a1":"7638",a6aa9e1f:"7643","653904f7":"7653","320ccb30":"7677","35b359a4":"7683",ef682180:"7731","931040e8":"7743",a4833b52:"7753","2886628e":"7778","1ca0f8e7":"7810","52ac6bcf":"7813",f385820d:"7841",d5947e44:"7861",d14d7097:"7919",b7cec31e:"7938",a708848c:"7980",a0b1bbd7:"7984","059c4264":"7990","178df98e":"8029","3a1d878d":"8031","6f1c571c":"8071",bceb927f:"8081",a489f3d8:"8128","01a85c17":"8209",b1fd1705:"8215","193dc870":"8220",b5a6d29b:"8226","0a757274":"8296","3ad2c61e":"8384","119c53e5":"8407",ac087500:"8411","69b09ea9":"8462",a8f67d60:"8463",c0cd111c:"8477","6bcd11f8":"8502","767805d3":"8519","5b235e06":"8523","7fd33963":"8526","29c2cfba":"8547","502adbf6":"8561","935f2afb":"8581","49bc3785":"8592","94298c6b":"8612",ea470413:"8730","564eabfd":"8752","42b29c77":"8767","5d503a86":"8777","742db51e":"8781","4468ebd1":"8805","6a0c14a5":"8834","73512cb1":"8897","343a1afc":"8965","23e62f09":"8966",dcf2f717:"8981",d1c3b532:"8992",a94703ab:"9048",fd34a958:"9049",bdaaff35:"9063","04437fec":"9075","94b13e0d":"9088",efbcd183:"9093","70b53392":"9110",f91986bc:"9121","5830dd0a":"9176","4d571bd0":"9226","09ba26e2":"9244",eea6a18c:"9245","915e2cf4":"9260",a7023ddc:"9267",c8d5479b:"9289","421b5e65":"9305",c5533f5e:"9346","6db2ece2":"9356","62337dff":"9376","03412b54":"9382",b08c16de:"9390","2163574d":"9401","8e8909f7":"9407",e747ec83:"9432","5abd544f":"9441","7f1a31c3":"9464",dcbc8e94:"9495","60fc342f":"9525","57b63ae3":"9539",c8b68b4a:"9565","99b53e63":"9579","5e95c892":"9647","5cc619f0":"9648",a3e11933:"9657",b77ceb62:"9689",a52f8495:"9691","4129286c":"9730","437bedbc":"9745","94f31572":"9752",a24f5044:"9755","36c47bdd":"9766",ce756c16:"9807","05e7973d":"9823","95fe5f6c":"9850","441bd449":"9851",ef9d238d:"9864","0683500c":"9866",be01f2a0:"9954"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(c,f)=>{var b=r.o(e,c)?e[c]:void 0;if(0!==b)if(b)f.push(b[2]);else if(/^(1869|5354)$/.test(c))e[c]=0;else{var d=new Promise(((f,d)=>b=e[c]=[f,d]));f.push(b[2]=d);var a=r.p+r.u(c),t=new Error;r.l(a,(f=>{if(r.o(e,c)&&(0!==(b=e[c])&&(e[c]=void 0),b)){var d=f&&("load"===f.type?"missing":f.type),a=f&&f.target&&f.target.src;t.message="Loading chunk "+c+" failed.\n("+d+": "+a+")",t.name="ChunkLoadError",t.type=d,t.request=a,b[1](t)}}),"chunk-"+c,c)}},r.O.j=c=>0===e[c];var c=(c,f)=>{var b,d,a=f[0],t=f[1],o=f[2],n=0;if(a.some((c=>0!==e[c]))){for(b in t)r.o(t,b)&&(r.m[b]=t[b]);if(o)var i=o(r)}for(c&&c(f);n<a.length;n++)d=a[n],r.o(e,d)&&e[d]&&e[d][0](),e[d]=0;return r.O(i)},f=self.webpackChunkdocs=self.webpackChunkdocs||[];f.forEach(c.bind(null,0)),f.push=c.bind(null,f.push.bind(f))})()})(); \ No newline at end of file diff --git a/blog/archive/index.html b/blog/archive/index.html new file mode 100644 index 0000000000..610e0ff667 --- /dev/null +++ b/blog/archive/index.html @@ -0,0 +1,23 @@ +<!doctype html> +<html lang="en" dir="ltr" class="plugin-blog plugin-id-default" data-has-hydrated="false"> +<head> +<meta charset="UTF-8"> +<meta name="generator" content="Docusaurus v3.2.1"> +<title data-rh="true">Archive | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/blog/atom.xml b/blog/atom.xml new file mode 100644 index 0000000000..c9173ab19a --- /dev/null +++ b/blog/atom.xml @@ -0,0 +1,24 @@ + + + https://docs.scs.community/blog + One platform — standardized, built and operated by many. Blog + 2022-10-28T00:00:00.000Z + https://github.com/jpmonette/feed + + One platform — standardized, built and operated by many. Blog + https://docs.scs.community/img/favicon.ico + + <![CDATA[First Blog Post]]> + https://docs.scs.community/blog/first-blog-post + + 2022-10-28T00:00:00.000Z + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

]]>
+ + Eduard Itrich + https://github.com/itrich + + + +
+
\ No newline at end of file diff --git a/blog/first-blog-post/index.html b/blog/first-blog-post/index.html new file mode 100644 index 0000000000..82cc4e9674 --- /dev/null +++ b/blog/first-blog-post/index.html @@ -0,0 +1,23 @@ + + + + + +First Blog Post | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

First Blog Post

· One min read
Eduard Itrich
Community Manager @ SCS

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

+ + \ No newline at end of file diff --git a/blog/index.html b/blog/index.html new file mode 100644 index 0000000000..2522e2382c --- /dev/null +++ b/blog/index.html @@ -0,0 +1,23 @@ + + + + + +Blog | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

First Blog Post

· One min read
Eduard Itrich
Community Manager @ SCS

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

+ + \ No newline at end of file diff --git a/blog/rss.xml b/blog/rss.xml new file mode 100644 index 0000000000..5a7a65d46d --- /dev/null +++ b/blog/rss.xml @@ -0,0 +1,22 @@ + + + + One platform — standardized, built and operated by many. Blog + https://docs.scs.community/blog + One platform — standardized, built and operated by many. Blog + Fri, 28 Oct 2022 00:00:00 GMT + https://validator.w3.org/feed/docs/rss2.html + https://github.com/jpmonette/feed + en + + <![CDATA[First Blog Post]]> + https://docs.scs.community/blog/first-blog-post + https://docs.scs.community/blog/first-blog-post + Fri, 28 Oct 2022 00:00:00 GMT + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

]]>
+ community + howto +
+
+
\ No newline at end of file diff --git a/blog/tags/community/community/index.html b/blog/tags/community/community/index.html new file mode 100644 index 0000000000..fe04b1108a --- /dev/null +++ b/blog/tags/community/community/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/blog/tags/community/index.html b/blog/tags/community/index.html new file mode 100644 index 0000000000..d961ca8cef --- /dev/null +++ b/blog/tags/community/index.html @@ -0,0 +1,23 @@ + + + + + +One post tagged with "community" | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

One post tagged with "community"

View All Tags

First Blog Post

· One min read
Eduard Itrich
Community Manager @ SCS

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

+ + \ No newline at end of file diff --git a/blog/tags/howto/index.html b/blog/tags/howto/index.html new file mode 100644 index 0000000000..0b3943e3c5 --- /dev/null +++ b/blog/tags/howto/index.html @@ -0,0 +1,23 @@ + + + + + +One post tagged with "howto" | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

One post tagged with "howto"

View All Tags

First Blog Post

· One min read
Eduard Itrich
Community Manager @ SCS

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

+ + \ No newline at end of file diff --git a/blog/tags/index.html b/blog/tags/index.html new file mode 100644 index 0000000000..a10225ea61 --- /dev/null +++ b/blog/tags/index.html @@ -0,0 +1,23 @@ + + + + + +Tags | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/community/category/contribute-to-docs/index.html b/community/category/contribute-to-docs/index.html new file mode 100644 index 0000000000..eeda492d3c --- /dev/null +++ b/community/category/contribute-to-docs/index.html @@ -0,0 +1,23 @@ + + + + + +Contribute to Docs | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/community/category/tools/index.html b/community/category/tools/index.html new file mode 100644 index 0000000000..b1bab80bea --- /dev/null +++ b/community/category/tools/index.html @@ -0,0 +1,23 @@ + + + + + +Tools | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/community/central-services/plusserver-gx-scs/index.html b/community/central-services/plusserver-gx-scs/index.html new file mode 100644 index 0000000000..f5e6145721 --- /dev/null +++ b/community/central-services/plusserver-gx-scs/index.html @@ -0,0 +1,102 @@ + + + + + +Central services | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Central services

+

This document gives an overview of what SCS central services are deployed and who is responsible for them in plusserver gx-scs infrastructure.

+

Project p500924-harbor

+

K8s clusters

+

Harbor

+

Responsibility: @SovereignCloudStack/vp06c

+

Services:

+ +

Utilization:

+
    +
  • Instances: 7
  • +
  • VCPUs: 32
  • +
  • RAM: 64GB
  • +
+

Spec:

+
    +
  • version: v7.0.0 - R6
  • +
  • management cluster: +
      +
    • 1 instance: SCS-2V:4:20
    • +
    • image: Ubuntu 22.04 (20230416)
    • +
    • k8s: v1.25.3 - KinD
    • +
    +
  • +
  • workload cluster: +
      +
    • 6 instances: +
        +
      • 3 control-planes: SCS-2V:4:20
      • +
      • 3 workers: SCS-8V:16:100
      • +
      +
    • +
    • image: ubuntu-capi-image-v1.28.7
    • +
    • k8s: v1.28.7
    • +
    +
  • +
+

Project p500924-sig-monitoring1

+

K8s clusters

+

Monitoring

+

Responsibility: @SovereignCloudStack/vp06c

+

Services:

+ +

Utilization:

+
    +
  • Instances: 7
  • +
  • VCPUs: 32
  • +
  • RAM: 64GB
  • +
+

Spec:

+
    +
  • version: v6.0.0 - R5
  • +
  • management cluster: +
      +
    • 1 instance: SCS-2V:4:20
    • +
    • image: Ubuntu 22.04 (20231211)
    • +
    • k8s: v1.27.3 - KinD
    • +
    +
  • +
  • workload cluster: +
      +
    • 6 instances: +
        +
      • 3 control-planes: SCS-2V:4:20
      • +
      • 3 workers: SCS-8V:16:100
      • +
      +
    • +
    • image: ubuntu-capi-image-v1.27.5
    • +
    • k8s: v1.27.5
    • +
    +
  • +
+ + \ No newline at end of file diff --git a/community/cloud-resources/getting-started-openstack/index.html b/community/cloud-resources/getting-started-openstack/index.html new file mode 100644 index 0000000000..780f52975d --- /dev/null +++ b/community/cloud-resources/getting-started-openstack/index.html @@ -0,0 +1,86 @@ + + + + + +Getting Started with OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Getting Started with OpenStack

Getting Started with OpenStack CLI

+

OpenStackClient (CLI)

+

The OpenStackClient is installable via all major Linux Distributions:

+

for debian and ubuntu with apt:

+
sudo apt install python3-openstackclient
+

for ubuntu with snap openstack CLI is installable too:

+
sudo snap install openstackclients
+
+

[!NOTE] +Versions from Linux repository could be in a stable but old state.

+
+

Install it directly via pypi +from upstream is the recommend way.

+

Here for example RHEL:

+
sudo dnf install python3 python3-devel gcc python3-pip
+

Here for example Debian and Ubuntu:

+
sudo apt install python3-minimal python3-pip python3-venv python3-dev build-essential
+

Here as example for SUSE

+
sudo zypper in python3-pip python3-venv python3-dev
+

Here for example with Apple's MacOS

+
brew install python3
+
+

[!NOTE] +Python installation for windows systems please use the python installation guide +or recommend use the Linux Subsystem WSL

+
+

Python Virtualenv

+

It is also recommended to use virtual environments, here as an example for +Linux and MacOS:

+
python3 -m venv oscli
source oscli/bin/activate
pip install --upgrade pip
pip install python-openstackclient \
python-cinderclient \
python-designateclient \
python-glanceclient \
python-neutronclient \
python-novaclient \
python-octaviaclient \
python-barbicanclient

+

For further Information see the OpenStack Project upstream website +python-openstackclient.

+

This repo holds examples for clouds-public.yaml + clouds.yaml.

+

Alternatively you can download an OpenRC Environment file when you're logged +in to Horizon:

+
    +
  • upper right side ➡️ <your login name>
  • +
  • OpenStack RC File
  • +
+
$ source ./<$yourfile>-openrc.sh
Please enter your OpenStack Password for project XXX as user YYY:
+
openstack --help
+

when you're using clouds.yaml you can specify multiple endpoints and +select the specific endpoint by passing --os-cloud= to the +openstack cmdline or setting OS_CLOUD.

+
openstack --os-cloud MYCLOUD
+

or

+
export OS_CLOUD=MYCLOUD
openstack
+

OpenStack Client in action inside of the OSISM testbed: +Example OpenStackClient in testbed

+

Object Storage (S3)

+

Create AWS like credentials with openstack ec2 credentials create. +If you use libs3, store the access field in S3_ACCESS_KEY_ID and the secret +field inS3_SECRET_ACCESS_KEY and set S3_HOSTNAME=<Object Storage endpoint>. +You will see the same buckets (containers) and objects whether you access your +object store via the swift or via the s3 protocol.

+

References

+
+ + \ No newline at end of file diff --git a/community/cloud-resources/index.html b/community/cloud-resources/index.html new file mode 100644 index 0000000000..19f62a3e2d --- /dev/null +++ b/community/cloud-resources/index.html @@ -0,0 +1,52 @@ + + + + + +Test and development cloud resources | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Test and development cloud resources

+

This document gives an overview of the test and development cloud resources currently provided by our partners.

+

How to request cloud resources

+

To request access to an existing project, please contact the responsible community member. To apply for a new project, please create a pull request against this document (leave Unique Identifier blank) and assign it to the particular CSP team (e.g. @SovereignCloudStack/plusserver, @SovereignCloudStack/wavecon, ...)

+

plusserver

+

Usage

+

A brief guide on how to use the resources provided by plusserver GmbH can be found here

+

Users

+

As suggested in #155 the username for non-"service users" will contain the users github handle and are prefixed with a plusserver default. +prefix-<$github handle>

+
+

Note +ATM this is not directly connected to the SovereignCloudStack github org membership, accounts will be created manually for now.

+
+

Example:

+
github handleplusserver login
frosty-geeku500924-frosty-geek
fkru500924-fkr
+
+

Note +To easy collaboration & transparency within the SCS team all users will have their default_project_id set to p500924-scs-community by default and will have full access on all projects listed below.

+
+

Service Users

+

Service users will have their default_project_id set to a specific project and will NOT be granted full access to other projects by default.

+
Unique IdentifierService User NameFull Access onCommunity ContactDescriptionNeeded until
9a1576af59644a2dbbace773ad17158du500924-svc-sig-monitoringp500924-sig-monitoring1fkrService User - SIG Monitoring31.12.2023
4925967416894fd78be6701689059653u500924-svc-cloudmonp500924-cloudmon-targetErik-Kostelansky-dNationService User - VP12 Test Project31.12.2024
f89b3d64ddff4d9d8cadb5e06fa22299u500924-svc-healthmonitorp500924-scs-healthmonitorgarloffService User - SCS Health Monitor
49cc3d72fbdf41fe8dc407f57f026dbfu500924-svc-standardsp500924-scs-healthmonitorgarloffService User - SCS Standards Compliance Check
1b6bb583fc5e40e49f2a7e9b4301de65u500924-svc-zuulp500924-scs-zuulo-otteService User - SCS Zuul30.11.2024
+

Projects

+
Unique IdentifierProject NameCommunity ContactDescriptionNeeded until
2237c767cf5f456da19359ed31c1c16bp500924-scs-communityfkrSCS Community Project
b43cfafbcf1f4eb08865b2886c29e09bp500924-cluster-api-sessiongarloffcluster-api hands on session
9b7a73e516be4cd1acbd63d543985c52p500924-gonicus-devo-otteGONICUS GmbH
3829cc7c8f034fc985f5055a1df6f247p500924-scs-healthmonitorgarloffSCS Health Monitor
b97d38bf128b4479981c4dbe2ef70cd5p500924-SIG-IAMfkrSIG IAM and VP08
9de7d8dc2d674e52be44904d6b338b0bp500924-cloudmonErik-Kostelansky-dNationVP12 Test Project31.12.2024
2c9e0e4ef8d44c36807df50b06b3c81dp500924-cloudmon-targetErik-Kostelansky-dNationTarget project for VP12 tests31.12.2024
3501db829014406884990a1016f3e25dp500924-sig-monitoring1fkrSIG Monitoring - cloudmon target
602778bad3d3470cbe58c4f7611e8eb7p500924-dnationchess-knightdNation dev for VP06c
91091d4039a6457db27d48d58bb1b4e4p500924-jschoonejschooneKaaS dev and evaluation
93956190702b4a7d8a8886806d57713fp500924-meteringcah-linkDev Environment for VP1331.12.2023
abbe6561cf6248b6af395334aa09af85p500924-harborchess-knightSCS Harbor for VP06c
e7622c1048ac4520a2d050ae141e826bp500924-tender-6amxmxchereDev Environment for VP06a
eeed7e0ad33f42f189fb4165116f5a1bp500924-dnation-k8smatofederdNation dev for VP06c
b342f37804f14459bdf703573169bf79p500924-minery90n20Testbed env for Pentesting30.11.2024
0fa3c3559f0d4f39ba7aa70c7f7188cap500924-tender-10-3tonifingerDev Environment for VP10-3
b682eb90fb834278afb1182018dd2133p500924-scoopexscoopexMarc's gx-scs project
021af0688c594bf88ed675b942d3bea8p500924-gx-cred-generatoranjastrunkSCS Gaia-X Self-Description Generator
a07c811315ad40f585945b2939ef12ddp500924-scs-zuulo-otteSCS Zuul30.11.2024
1846709967a744b69f9eb48cac89bb04p500924-scs-k8s-e2echess-knightE2E-Test for KaaS
6ee4b373cb6d42a5bb59d5080987b70dp500924-bitkeksbitkeksCluster Stacks and Sec
4ea22ba875474d039cb57d20b7f710b5p500924-kaas-playground0jschoonePlayground0 for Hackathon30.09.2024
476672f1023b4bac8837f95a76881757p500924-kaas-playground1jschoonePlayground1 for Hackathon30.09.2024
04dac2927f744479a5d4c23dd0a3c378p500924-kaas-playground2jschoonePlayground2 for Hackathon30.09.2024
75279777029847ab9b399390c0dd6042p500924-kaas-playground3jschoonePlayground3 for Hackathon30.09.2024
0b3c75f80b6743778daccec0da423465p500924-kaas-playground4jschoonePlayground4 for Hackathon30.09.2024
2340a73644ca47189329061e9c2a0bfep500924-kaas-playground5jschoonePlayground5 for Hackathon30.09.2024
3c5bae4a233c4a9d8ae2e4b799d757c9p500924-kaas-playground6jschoonePlayground6 for Hackathon30.09.2024
03783b4952344c849af37d26818d19f0p500924-kaas-playground7jschoonePlayground7 for Hackathon30.09.2024
5c6d4d7183834eafbc20108ad647a9c0p500924-kaas-playground8jschoonePlayground8 for Hackathon30.09.2024
7e18881932f749baa7d547ebd407b8d8p500924-kaas-playground9jschoonePlayground9 for Hackathon30.09.2024
d9dc2f33e76240219db484526e9f601dp500924-akafazovakafazovakafazov Testbed30.04.2024
b07ad6a84982471b9a344ef9947f0e0fp500924-gtemagtemaTestbed for gtema
e89ac8c9f66f46b5a983b2a05d2a66ecp500924-zuse-z3zuse-z3Josefine's gx-scs project
fc1f7a0e10a64d6083dcdbcb7ccf6ff4p500924-compliance-monitormbuechseSCS Compliance Monitor Deployment
+

Wavecon

+

Service Users

+
Unique IdentifierService User NameFull Access onCommunity ContactDescriptionNeeded until
df4af5376bbd4de587c4335622149be7scs-standardsscs-standardsitrichService User - SCS Standards Compliance Check
+

Projects

+
Unique IdentifierProject NameCommunity ContactDescriptionNeeded until
718964b4b87446688ac04b151519fb51scsgarloffSCS Health Monitor
c46ccc9e695c4b23bacee2ad11145d9ascs-health-monitorgarloffSCS Health Monitor
00de553df86949b49365baee6375fb5ascs-standardsitrichSCS Health Monitor
+ + \ No newline at end of file diff --git a/community/cloud-resources/plusserver-gx-scs/index.html b/community/cloud-resources/plusserver-gx-scs/index.html new file mode 100644 index 0000000000..6318f24bdd --- /dev/null +++ b/community/cloud-resources/plusserver-gx-scs/index.html @@ -0,0 +1,38 @@ + + + + + +Getting Started Gaia-X Demonstrator @ plusserver | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Getting Started Gaia-X Demonstrator @ plusserver

Getting Started for the Gaia-X Demonstrator @ plusserver

+

URLs for access

+ +

Authentication (UI)

+

For your login you will need:

+
    +
  • Username (u500924-<$github-handle>)
  • +
  • Password
  • +
  • Domain (d500924)
  • +
+

Getting Started with OpenStack

+

See Getting Started with OpenStack

+ + \ No newline at end of file diff --git a/community/cloud-resources/wavestack/index.html b/community/cloud-resources/wavestack/index.html new file mode 100644 index 0000000000..abefde6592 --- /dev/null +++ b/community/cloud-resources/wavestack/index.html @@ -0,0 +1,38 @@ + + + + + +Getting Started with Wavestack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/community/collaboration/index.html b/community/collaboration/index.html new file mode 100644 index 0000000000..1946ef11aa --- /dev/null +++ b/community/collaboration/index.html @@ -0,0 +1,62 @@ + + + + + +Collaboration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Collaboration

+

We’re an open community

+

Our meetings are publicly announced and we are happy to welcome both newcomers and established members alike. You can navigate either through the calendar below or subscribe with your favorite client to https://sovereigncloudstack.github.io/calendar/scs.ics. The calendar is collaboratively maintained on GitHub and new entries, such as a lightning talk, are highly appreciated!

+
+

Collaborating with issues and pull requests

+

We use the GitHub flow to track and discuss changes in issues, then propose and +review changes in pull requests. See the +GitHub documentation +for more details.

+

Meetings

+

Project updates

+
    +
  • Weekly with all teams on Thursday at 15:05 CEST (40 mins)
  • +
  • In some weeks we schedule an additional lightning talk at 15:40 CEST
  • +
+

Sprint review/Backlog refinement/Sprint planning meetings

+
    +
  • Weekly Team meetings (~1hr) for currently 4 teams: +
      +
    • Team IaaS
    • +
    • Team Container
    • +
    • Team IAM & Security
    • +
    • Team Operations
    • +
    +
  • +
  • Please refer to the public calendar above for details.
  • +
+

Special interest groups (SIGs) and hacking sessions

+
    +
  • There are a number of SIG meetings and hacking sessions that meet weekly or bi-weekly +
      +
    • SIG Monitoring and Logging
    • +
    • SIG Standardization and Certification
    • +
    • SIG Documentation
    • +
    • SIG Community
    • +
    • SIG Central API
    • +
    +
  • +
  • Please refer to the public calendar above for details.
  • +
+ + \ No newline at end of file diff --git a/community/collaboration/sig-central-api/index.html b/community/collaboration/sig-central-api/index.html new file mode 100644 index 0000000000..b3f9117a90 --- /dev/null +++ b/community/collaboration/sig-central-api/index.html @@ -0,0 +1,28 @@ + + + + + +SIG Central API | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SIG Central API

+

For defining a Common and Central interface for the Customers of SCS cloud to manage the Infrastructure cloud resources open stack and Kubernetes and identity and Access management.

+

We want to define a single point of managment with consistent experience for managing the entire infrastructure.

+

We aim to establish an unified and central interface that provides customers +of the SCS clouds with the ability to manage cloud resources and/or services.

+

SIG explores the possibilities for a central API by creating a MVP.

+ + \ No newline at end of file diff --git a/community/collaboration/sig-community/index.html b/community/collaboration/sig-community/index.html new file mode 100644 index 0000000000..57ab13337d --- /dev/null +++ b/community/collaboration/sig-community/index.html @@ -0,0 +1,24 @@ + + + + + +SIG Community | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SIG Community

+

In this meeting, we come together to shape our community strategy and coordinate collaborative efforts within our community. Our goal is to cultivate an open and welcoming community where we can share the message of SCS. We plan engaging community events, strive to make this open-source community even more inclusive, and aim to keep it informative, inspiring, and captivating. We warmly invite you to join us in our mission and become a part of this exciting journey!

+ + \ No newline at end of file diff --git a/community/collaboration/sig-documentation/index.html b/community/collaboration/sig-documentation/index.html new file mode 100644 index 0000000000..90f3d81b6b --- /dev/null +++ b/community/collaboration/sig-documentation/index.html @@ -0,0 +1,23 @@ + + + + + +SIG Documentation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SIG Documentation

We curate and enhance the SCS Documentation, focusing on refining its information architecture for optimal usability. Our objective is to facilitate straightforward contributions from community developers and to provide operators with a clear, quick reference guide that accelerates the initiation of an SCS deployment.

+ + \ No newline at end of file diff --git a/community/collaboration/sig-monitoring/index.html b/community/collaboration/sig-monitoring/index.html new file mode 100644 index 0000000000..5945c7d8c9 --- /dev/null +++ b/community/collaboration/sig-monitoring/index.html @@ -0,0 +1,24 @@ + + + + + +SIG Monitoring | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SIG Monitoring

+

The Special Interest Group (SIG) Monitoring meets on a fortnightly base (alternating with the audit log WG) to discuss the monitoring needs of SCS Operators, Users and Integrators. Together we shape how monitoring and observability within the SCS landscape looks like.

+ + \ No newline at end of file diff --git a/community/collaboration/sig-standardization/index.html b/community/collaboration/sig-standardization/index.html new file mode 100644 index 0000000000..8f75b7631f --- /dev/null +++ b/community/collaboration/sig-standardization/index.html @@ -0,0 +1,25 @@ + + + + + +SIG Standardization | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SIG Standardization

+

In this Special Interest Group, we discuss and align our activities and approach to standardization and certification. That is to say, we devise and refine the relevant concepts and processes; we work on a roadmap for new certificate versions; and we align on which standards are desireable for each certificate subject. We then work with the teams to align on existing or new standards.

+

Besides aspects of openness and sovereignty, the main goal of our standards is interoperability. We should take the user perspective: As a member of a DevOps team developing a service (think SaaS or PaaS) for SCS, I need XYZ. Every standard should be abstract enough to work regardless of the SCS reference implementation.

+ + \ No newline at end of file diff --git a/community/collaboration/team-container/index.html b/community/collaboration/team-container/index.html new file mode 100644 index 0000000000..dc448ffd7b --- /dev/null +++ b/community/collaboration/team-container/index.html @@ -0,0 +1,27 @@ + + + + + +Team Container | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Team Container

+

The Team Container deals with all topics around Containers and Kubernetes.

+

at the moment: Kubernetes Deployments via ClusterAPI +in the future deployments via ClusterStacks +KaaS Standard

+ + \ No newline at end of file diff --git a/community/collaboration/team-iaas/index.html b/community/collaboration/team-iaas/index.html new file mode 100644 index 0000000000..71750d82f6 --- /dev/null +++ b/community/collaboration/team-iaas/index.html @@ -0,0 +1,24 @@ + + + + + +Team Iaas | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/community/collaboration/team-iam/index.html b/community/collaboration/team-iam/index.html new file mode 100644 index 0000000000..c8f5914265 --- /dev/null +++ b/community/collaboration/team-iam/index.html @@ -0,0 +1,26 @@ + + + + + +Team IAM | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Team IAM

+

The Team IAM deals with topics around Identity and Access Management.

+

Users that access cloud and container infrastructure need to authenticate themselves and then authorizations to see and access resources from the infrastructure are derived from the identity of the users as they belong to groups and are roles are assigned to them (or the groups they belong to).

+

Sovereign Cloud Stack has the goal that user identities can used across several layers in the stack (most importantly IaaS and Container layer), that user management should be a self-service capability and that user identities can be federated, i.e. user identities and authentication from one SCS cloud (or from one standards-compliant Identity Provider) can be used in other SCS clouds. Federation is an imporant principle in SCS.

+ + \ No newline at end of file diff --git a/community/collaboration/team-ops/index.html b/community/collaboration/team-ops/index.html new file mode 100644 index 0000000000..ea6345516b --- /dev/null +++ b/community/collaboration/team-ops/index.html @@ -0,0 +1,24 @@ + + + + + +Team Ops | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/community/community/category/contribute-to-docs/index.html b/community/community/category/contribute-to-docs/index.html new file mode 100644 index 0000000000..086e5958ca --- /dev/null +++ b/community/community/category/contribute-to-docs/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/category/tools/index.html b/community/community/category/tools/index.html new file mode 100644 index 0000000000..9d5452e9a9 --- /dev/null +++ b/community/community/category/tools/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/central-services/plusserver-gx-scs/index.html b/community/community/central-services/plusserver-gx-scs/index.html new file mode 100644 index 0000000000..ec337d67ad --- /dev/null +++ b/community/community/central-services/plusserver-gx-scs/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/cloud-resources/getting-started-openstack/index.html b/community/community/cloud-resources/getting-started-openstack/index.html new file mode 100644 index 0000000000..fc40aed3a6 --- /dev/null +++ b/community/community/cloud-resources/getting-started-openstack/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/cloud-resources/index.html b/community/community/cloud-resources/index.html new file mode 100644 index 0000000000..2e9f439d9b --- /dev/null +++ b/community/community/cloud-resources/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/cloud-resources/plusserver-gx-scs/index.html b/community/community/cloud-resources/plusserver-gx-scs/index.html new file mode 100644 index 0000000000..32216711a6 --- /dev/null +++ b/community/community/cloud-resources/plusserver-gx-scs/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/cloud-resources/wavestack/index.html b/community/community/cloud-resources/wavestack/index.html new file mode 100644 index 0000000000..b13d66f100 --- /dev/null +++ b/community/community/cloud-resources/wavestack/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/index.html b/community/community/collaboration/index.html new file mode 100644 index 0000000000..5bb45e6905 --- /dev/null +++ b/community/community/collaboration/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/sig-central-api/index.html b/community/community/collaboration/sig-central-api/index.html new file mode 100644 index 0000000000..96f1798e92 --- /dev/null +++ b/community/community/collaboration/sig-central-api/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/sig-community/index.html b/community/community/collaboration/sig-community/index.html new file mode 100644 index 0000000000..5d208ece86 --- /dev/null +++ b/community/community/collaboration/sig-community/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/sig-documentation/index.html b/community/community/collaboration/sig-documentation/index.html new file mode 100644 index 0000000000..5c60f11ec9 --- /dev/null +++ b/community/community/collaboration/sig-documentation/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/sig-monitoring/index.html b/community/community/collaboration/sig-monitoring/index.html new file mode 100644 index 0000000000..6ce28e5fae --- /dev/null +++ b/community/community/collaboration/sig-monitoring/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/sig-standardization/index.html b/community/community/collaboration/sig-standardization/index.html new file mode 100644 index 0000000000..9a6d34fe89 --- /dev/null +++ b/community/community/collaboration/sig-standardization/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/team-container/index.html b/community/community/collaboration/team-container/index.html new file mode 100644 index 0000000000..d6c30e0e5e --- /dev/null +++ b/community/community/collaboration/team-container/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/team-iaas/index.html b/community/community/collaboration/team-iaas/index.html new file mode 100644 index 0000000000..3b605c604a --- /dev/null +++ b/community/community/collaboration/team-iaas/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/team-iam/index.html b/community/community/collaboration/team-iam/index.html new file mode 100644 index 0000000000..5dd0756ef0 --- /dev/null +++ b/community/community/collaboration/team-iam/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/collaboration/team-ops/index.html b/community/community/collaboration/team-ops/index.html new file mode 100644 index 0000000000..f7d24b9774 --- /dev/null +++ b/community/community/collaboration/team-ops/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/adding-docs-guide/index.html b/community/community/contribute/adding-docs-guide/index.html new file mode 100644 index 0000000000..706521ab60 --- /dev/null +++ b/community/community/contribute/adding-docs-guide/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/doc-files-structure-guide/index.html b/community/community/contribute/doc-files-structure-guide/index.html new file mode 100644 index 0000000000..81f157bc94 --- /dev/null +++ b/community/community/contribute/doc-files-structure-guide/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/docs-workflow-explanation/index.html b/community/community/contribute/docs-workflow-explanation/index.html new file mode 100644 index 0000000000..5009c317ac --- /dev/null +++ b/community/community/contribute/docs-workflow-explanation/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/linting-guide/index.html b/community/community/contribute/linting-guide/index.html new file mode 100644 index 0000000000..bf183e9f0b --- /dev/null +++ b/community/community/contribute/linting-guide/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/local-docusaurus-development-guide/index.html b/community/community/contribute/local-docusaurus-development-guide/index.html new file mode 100644 index 0000000000..9a044694f1 --- /dev/null +++ b/community/community/contribute/local-docusaurus-development-guide/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/styleguide/index.html b/community/community/contribute/styleguide/index.html new file mode 100644 index 0000000000..ba4e409a70 --- /dev/null +++ b/community/community/contribute/styleguide/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/contribute/styleguides/ansible_styleguide/index.html b/community/community/contribute/styleguides/ansible_styleguide/index.html new file mode 100644 index 0000000000..5234f1b100 --- /dev/null +++ b/community/community/contribute/styleguides/ansible_styleguide/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/hackathons/checklist/index.html b/community/community/hackathons/checklist/index.html new file mode 100644 index 0000000000..984523b3b9 --- /dev/null +++ b/community/community/hackathons/checklist/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/index.html b/community/community/index.html new file mode 100644 index 0000000000..43e45251f4 --- /dev/null +++ b/community/community/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/license-considerations/index.html b/community/community/license-considerations/index.html new file mode 100644 index 0000000000..88c63d3a58 --- /dev/null +++ b/community/community/license-considerations/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/mission-statement/index.html b/community/community/mission-statement/index.html new file mode 100644 index 0000000000..506b9afa59 --- /dev/null +++ b/community/community/mission-statement/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/github/branchprotection/index.html b/community/community/tools/github/branchprotection/index.html new file mode 100644 index 0000000000..ff9b117386 --- /dev/null +++ b/community/community/tools/github/branchprotection/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/github/dco-and-licenses/index.html b/community/community/tools/github/dco-and-licenses/index.html new file mode 100644 index 0000000000..9942300782 --- /dev/null +++ b/community/community/tools/github/dco-and-licenses/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/github/tips-and-tricks/index.html b/community/community/tools/github/tips-and-tricks/index.html new file mode 100644 index 0000000000..c83b1e2cc9 --- /dev/null +++ b/community/community/tools/github/tips-and-tricks/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/jitsi/index.html b/community/community/tools/jitsi/index.html new file mode 100644 index 0000000000..ad0d005f35 --- /dev/null +++ b/community/community/tools/jitsi/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/mailinglists/index.html b/community/community/tools/mailinglists/index.html new file mode 100644 index 0000000000..0e774e97be --- /dev/null +++ b/community/community/tools/mailinglists/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/matrix/index.html b/community/community/tools/matrix/index.html new file mode 100644 index 0000000000..b94ffe4852 --- /dev/null +++ b/community/community/tools/matrix/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/nextcloud/index.html b/community/community/tools/nextcloud/index.html new file mode 100644 index 0000000000..34888d5e22 --- /dev/null +++ b/community/community/tools/nextcloud/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/community/tools/zuul/index.html b/community/community/tools/zuul/index.html new file mode 100644 index 0000000000..78e2d138db --- /dev/null +++ b/community/community/tools/zuul/index.html @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/community/contribute/adding-docs-guide/index.html b/community/contribute/adding-docs-guide/index.html new file mode 100644 index 0000000000..4aba93c998 --- /dev/null +++ b/community/contribute/adding-docs-guide/index.html @@ -0,0 +1,68 @@ + + + + + +Adding Docs Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Adding Docs Guide

+

In this Guide you will learn how to integrate your documentation to the SCS documentation, which you will find on docs.scs.community.

+

Step 1 – Documentation type

+

Determine the type of your documentation and click to continue.

+
    +
  1. Technical documentation
  2. +
  3. Operational documentation
  4. +
  5. Community documentation
  6. +
+

If unsure don't hestitate to ask us at Matrix

+

1. Technical Documentation

+

Step 1 – Checklist

+

Your repository containing the documentation has to...

+
    +
  • be a public repository
  • +
  • contain a directory named /doc or /docs within root, containing the documentation files
  • +
+

The documentation files have to be in markdown format and...

+ +

Step 2 – Adding your repo to the docs.json

+

File a Pull Request within the docs-page repository and add your repo to the docs.package.json:

+
[
{
"repo": "demo-organisation/demo-repository",
"source": "doc/*.md",
"target": "docs",
"label": "demo-repository-label"
}
]
+
keydescription
reporeference to github organisation and repository
sourcepath to content to copy: Either glob matching individual markdown files OR the path of a single directory
targetdirectory where the files should be copied to within the docs-page repo
labellabel for directory. only mandatory if source file is set to copy only *.md files and not the complete directory
+

Once it is approved and merged, a postinstall script will be triggered within the build process. This initiates downloading, copy and distilling which results in this static generated documentation page – now with your content.

+

An explanation on how the sync & distill workflow and a guide on how to test it in a local development environment you will find here.

+

2. Operational documentation

+

Your doc files contain operational knowledge. Which layer in the stack do they belong to?

+
    +
  1. iaas
  2. +
  3. iam
  4. +
  5. kaas
  6. +
  7. operations
  8. +
+

File a Pull Request within the docs repository and add your markdown files to the fitting directory.

+

3. Community documentation

+

Your doc files contain knowledge regarding our community? Choose the right directory. If unsure don't hestitate to ask us at Matrix.

+

File a Pull Request within the docs repository and add your markdown files to the fitting directory.

+ + \ No newline at end of file diff --git a/community/contribute/doc-files-structure-guide/index.html b/community/contribute/doc-files-structure-guide/index.html new file mode 100644 index 0000000000..b36aad0c33 --- /dev/null +++ b/community/contribute/doc-files-structure-guide/index.html @@ -0,0 +1,58 @@ + + + + + +Documentation Files Structure | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Documentation Files Structure

+

Structure Best Practice

+

Overview - mandatory

+
    +
  • What is it and for what do I need this? What benefits does it have for users?
  • +
  • What organization/company does this belong to? (Link to company/organization)
  • +
  • Where am I – as module – within the bigger context of SCS?
  • +
+

Requirements - mandatory

+
    +
  • What minimal requirements do i need to quickstart?
  • +
+

Quickstart - optional. If it is possible, then mandatory

+
    +
  • Link to requirements
  • +
  • What is the aim of this quickstart guide?
  • +
  • Caution: only for testing, not for production
  • +
  • Rule: one line per command for easy copy&paste and one line for description where possible
  • +
  • Rule: only one working path for installation!
  • +
+

Getting Started - mandatory

+
    +
  • Aim is a production ready installation
  • +
+

Configuration – mandatory

+
    +
  • Showing all possible config options
  • +
+

Contribute – mandatory

+
    +
  • Description for how can i contribute with Link to Github repository
  • +
+

FAQ`s – optional

+
    +
  • Roadmap - optional
  • +
+ + \ No newline at end of file diff --git a/community/contribute/docs-workflow-explanation/index.html b/community/contribute/docs-workflow-explanation/index.html new file mode 100644 index 0000000000..cfd486619a --- /dev/null +++ b/community/contribute/docs-workflow-explanation/index.html @@ -0,0 +1,37 @@ + + + + + +Documentation workflow explanation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Documentation workflow explanation

+

The aim within this documentation is to have a good developer experience and a low entry barrier to start with SCS. For this to achieve we think all docs that define the SCS stack and have been developed by the SCS community should be within this documentation framework.

+

Information Architecture

+
    +
  • +

    All general docs are located within the SovereignCloudStack/docs repository.

    +
  • +
  • +

    Docs that explain, guide or contextualize specific modules such as the openstack-image-manager or the k8s-cluster-api-provider reside within their repository in a seperate docs directory.

    +
  • +
+

Both, the general docs and docs of the external repositories are combined into the one unified documentation collection that is being rendered in a static page on https://docs.scs.community. In order to make this work we have developed a workflow that syncs all doc repositories and distills only the relevant markdown files.

+

The script is called getDocs. It is a postinstall script and is executed after npm install. This has the advantage to have the docs – coming from the cloud – in your local docusaurus development environment as well as in the build process.

+

You'll find the script in the root directory of the SovereignCloudStack/docs-page repository:

+
getDocs.js
const fs = require('fs')
const { execSync } = require('child_process')

// Read the contents of the "docs.package.json" file and remove all whitespace
const reposJson = fs
.readFileSync('./docs.package.json', 'utf8')
.replace(/\s/g, '')

// Parse the JSON and create an array of repositories
const repos = JSON.parse(reposJson)
const ghUrl = 'https://github.com/'

// Clone each repository, remove git folders and README files, and copy the docs to the target directory
repos.forEach((repo) => {
const repoDir = `repo_to_be_edited/${repo.label}`

// Clone the repository
const cloneCommand = `git clone ${ghUrl + repo.repo} ${repoDir}`
execSync(cloneCommand)

// Remove git folders
const removeGitCommand = `rm -rf ${repoDir}/.git`
execSync(removeGitCommand)

// Remove README files
const removeReadmeCommand = `find ${repoDir} -name "README.md" | xargs rm -f`
execSync(removeReadmeCommand)

// Create the docusaurus subdirectory
const subDirPath = `${repo.target}/${repo.label}`
fs.mkdirSync(subDirPath, { recursive: true })

// Copy docs content from A to B
const copyDocsCommand = `cp -r ${repoDir}/${repo.source} ${subDirPath}`
execSync(copyDocsCommand)

// Remove the cloned repository
const removeRepoCommand = 'rm -rf repo_to_be_edited'
execSync(removeRepoCommand)
})
+ + \ No newline at end of file diff --git a/community/contribute/linting-guide/index.html b/community/contribute/linting-guide/index.html new file mode 100644 index 0000000000..efe02701cb --- /dev/null +++ b/community/contribute/linting-guide/index.html @@ -0,0 +1,47 @@ + + + + + +Linting Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Linting Guide

+

In order to have a clean content repository regarding all markdown files we enforce linting on:

+
    +
  1. all staged files prior committing
  2. +
  3. all Pull Requests
  4. +
+

Pre Commit

+

Run markdownlint against staged git files with Husky git hook:

+
    +
  1. lint-staged
  2. +
  3. husky
  4. +
+

The rules are enforced on markdown files, for which we use:

+
    +
  1. markdownlint-cli2 for markdownlint
  2. +
  3. prettier for code formatting
  4. +
+

The markdownlint rules are defined in the configuration file .markdownlint-cli2.jsonc

+

Additionally we use markdownlint-rule-search-replace for fixing

+

Github Workflows

+

There are two actions running on every Pull Request on the main branch.

+
    +
  1. link-validator.ymlis checking every link in markdown files.
  2. +
  3. pr-markdownlint.ymlis checking all markdown files regarding to the rules defined within .markdownlint-cli2.jsonc
  4. +
+ + \ No newline at end of file diff --git a/community/contribute/local-docusaurus-development-guide/index.html b/community/contribute/local-docusaurus-development-guide/index.html new file mode 100644 index 0000000000..77364922e9 --- /dev/null +++ b/community/contribute/local-docusaurus-development-guide/index.html @@ -0,0 +1,50 @@ + + + + + +Installation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Installation

+

This Guide shows you how to setup docusaurus on your local machine to run this docs in your local development enviroment.

+

Requirements

+
    +
  • git
  • +
  • Node.js v16
  • +
+

Installation Guide

+

Step 1 – Installing Node.js via nvm

+

It is recommended to install Node.js via nvm – a node version manager – to have the possibility to switch between different node.js versions.

+

You must have macOS desktop access with administrator privileges.

Login to the macOS desktop system and install Homebrew on your system (if not already installed).

Install nvm via homebrew:

brew install nvm
+

Once installed you can check the available versions with

+
nvm list
+

If you have no other projects, where you need a different version, it is recommended to install the latest stable LTS version of node.

+
nvm install lts
+

nvm has now installed the latest node.js version with its package manager npm. Check if the installation has been successfull by checking it:

+
node --version
+

Step 2 – Cloning the repository

+

Clone the docs repository via your favourite method:

+
HTTPS
git clone https://github.com/SovereignCloudStack/docs.git
+

Step 3 – Installing dependencies

+

Change your working directory within your terminal to the root of the cloned repository /docs and install all dependencies:

+
npm install
+

Step 4 – Starting the development server

+

You can now run the local development server from your terminal:

+
npm start
+

Once the server is up and running, your terminal will show you the local URL which you can open with your browser to see the page.

+ + \ No newline at end of file diff --git a/community/contribute/styleguide/index.html b/community/contribute/styleguide/index.html new file mode 100644 index 0000000000..926d4913de --- /dev/null +++ b/community/contribute/styleguide/index.html @@ -0,0 +1,50 @@ + + + + + +Styleguide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Styleguide

+

Admonitions

+

We adopt the default Admonition colors for Note, Tip, Info, Caution, Danger by docusaurus:

+

Docusaurus Admonitons

+
note

Some content with Markdown syntax.

+
tip

Some content with Markdown syntax.

+
info

Some content with Markdown syntax.

+
caution

Some content with Markdown syntax.

+
danger

Some content with Markdown syntax.

+

Blockquotes

+

Blockquotes should be handled with standard markdown >

+

Example Blockquote:

+
+

The raw data format is really the only sensible format option to use with RBD. asdasdasdasd asd asd a +Technically, you could use other QEMU-supported formats +(such as qcow2 or vmdk), but doing so would add additional overhead, and would +also render the volume unsafe for virtual machine live +migration when caching (see below) is enabled.

+
+

Codeblocks

+

We support markdown language features for Codeblocks. +It is mandatory to define the language to be quoted, when using codeblocks. +Syntax Highlighting is also supported by Docusaurus via Prism. +We are using the GitHub language themeing as default.

+
Python example
def code_block():
# Everything in this function is part of the same code block
print (1)
print (2)

for i in range(4):
# Everyting in this loop is part of the same code block
print (i)
+
Javascript example
const code_block = () => {
console.log('inside code_block')
}
+
YAML example
---
doe: 'a deer, a female deer'
ray: 'a drop of golden sun'
pi: 3.14159
xmas: true
french-hens: 3
calling-birds:
- huey
- dewey
- louie
- fred
+
Ruby example
require 'redcarpet'
markdown = Redcarpet.new("Hello World!")
puts markdown.to_html
+ + \ No newline at end of file diff --git a/community/contribute/styleguides/ansible_styleguide/index.html b/community/contribute/styleguides/ansible_styleguide/index.html new file mode 100644 index 0000000000..6e44d6650c --- /dev/null +++ b/community/contribute/styleguides/ansible_styleguide/index.html @@ -0,0 +1,76 @@ + + + + + +Ansible Style Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Ansible Style Guide

+

We use nearly all default rules of ansible lint. A listing of all these rules can be found in the Ansible Lint documentation: +https://ansible.readthedocs.io/projects/lint/rules/. +Please always use the ansible linting to check if the code complies with the default linting rules. +However, since in most cases we always use the latest version of packages and Ansible lint does not provide this, we decided to +disable the package_latest rule.

+

Task naming

+
    +
  • Tasks must always have names. The only exception allowed is for forked playbooks.
  • +
  • A name never starts with a small letter
  • +
  • Names are written in present tense
  • +
  • No punctuation is used in names
  • +
+

Key Order

+

To check the key order we use our own rule. This can be found here.

+

Positioning and use of the become directive

+

The become directive is only set when needed and is always set explicitly for each task that needs it.

+

Blocks, roles or playbooks are never executed in a privileged mode.

+

We always insert the become directive between the name of a task and the task itself. This also applies to related directives +like become_user or become_flags. This is for better visibility if a task is privileged or not.

+
- name: Copy hddtemp configuration file
become: true
ansible.builtin.copy:
src: "{{ ansible_os_family }}/hddtemp"
dest: "{{ hddtemp_conf_file }}"
owner: root
group: root
mode: 0644
notify: Restart hddtemp service
+

Position of the when condition

+

If you need to use the when condition please add this at the end-section from the task where it is needed. This makes the code +easier to understand for others. Ansible lint provides the when condition under the task name for blocks. To keep the code clear +we decided against it. Please disable this with a noqa if necessary. For example:

+
- name: "Archive existing {{ resolvconf_file }} file"
become: true
ansible.posix.synchronize:
src: "/etc/resolv.conf"
dest: "/etc/resolv.conf.{{ ansible_date_time.date }}"
archive: true
delegate_to: "{{ inventory_hostname }}"
when: stat_resolvconf_file.stat.islnk is defined and not stat_resolvconf_file.stat.islnk
+

Usage of collections

+

Collections are always defined as in the following example.

+

netbox.netbox is here the collection that is used.

+
- name: Configure netbox manufacturers
netbox.netbox.netbox_manufacturer:
netbox_url: '{{ netbox_url }}'
netbox_token: '{{ netbox_token }}'
data:
name: '{{ item.value.name }}'
slug: '{{ item.value.slug }}'
description: "{{ item.value.description | default('') }}"
state: present
with_dict: '{{ netbox_data_manufacturers }}'
+

Please don´t declare it in this way!:

+
collections:
- netbox.netbox

tasks:
- name: Manage Discworld site
netbox_site:
netbox_url: "{{ netbox_url }}"
netbox_token: "{{ netbox_token }}"
validate_certs: false
data:
name: Discworld
slug: discworld
state: present
+

If you have to use collections please define them in a requirements.yml.

+

Example yaml:

+
roles:
- name: geerlingguy.certbot
version: master
type: git
src: git+https://github.com/geerlingguy/ansible-role-certbot.git
---
collections:
- name: ansible.netcommon
source: https://galaxy.ansible.com

- name: https://github.com/ansible-collections/ansible.posix.git
type: git
version: main
+

Usage of roles from other collections

+

If you want to reuse roles please do it in the following way:

+

First you have to declare the role or collection in the requirements.yml like shown in the example before.

+

Than you can use it in playbooks like this

+
roles:
- role: osism.services.auditd
+

Parameters that offer lists

+

Parameters that provide a list are always defined as in the following example.

+

docker_hosts_defaults sets the defaults in the role. Overriding is only possible with the ansible-defaults repository.

+

In the configuration repository, docker_hosts_extra is then used to add additional items to the list.

+

docker_hosts itself is never modified from the outside.

+
docker_hosts_defaults:
- 'unix:///var/run/docker.sock'
docker_hosts_extra: []
docker_hosts: '{{ docker_hosts_defaults + docker_hosts_extra }}'
+

Usage of changed_when

+

Please think twice before turning off changed_when. It's a fairly simple yet safety-relevant linting rule and is quite easy to +implement.

+

Disable linting rules

+

In principle, it is only allowed to disable rules if there is really no other possibility. +Please do not disable rules in general but only in individual cases via Noqa. Please use in this case the full rulename and not +the numbers, because them are depricated. If it makes sense to ignore a rule, please open up an issue in the +https://github.com/osism/issues repository with a label discussion.

+ + \ No newline at end of file diff --git a/community/hackathons/checklist/index.html b/community/hackathons/checklist/index.html new file mode 100644 index 0000000000..30ba33cf71 --- /dev/null +++ b/community/hackathons/checklist/index.html @@ -0,0 +1,147 @@ + + + + + +Hackathon planning checklist | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Hackathon planning checklist

+

This checklist is designed to simplify the planning of hackathons and meetups. All items are suggestions and optionally adaptable +to the situation.

+

Checklist 6 months before Hackathon

+
DateTask
  • - [ ]
Clarify sponsorship
  • - [ ]
Clarify who is responsible for planning. Contact persons of the companies involved. These should then also be present at the hackathon.
  • - [ ]
Set a specific date.
  • - [ ]
Clarify responsibilities.
  • - [ ]
First advertising in form of advertising in meetings, LinkedIn post, mailing list or similar.
  • - [ ]
Clarify which advertising measures are required (see checklist advertising).
  • - [ ]
Determine venue.
  • - [ ]
Set the theme for the hackathon and apply it to the design.
+

Checklist advertising

+
TopicTask
  • - [ ]
Social MediaCreate content plan.
  • - [ ]
Which accounts/people/companies have to be mentioned as well.
  • - [ ]
Which persons must agree to a publication.
  • - [ ]
Should hashtags be used, if yes which ones.
  • - [ ]
NewsletterCreate content plan with possible content and frequency.
  • - [ ]
WebsiteContent plan: Blogposts.
  • - [ ]
Info landing page.
  • - [ ]
Registration page.
  • - [ ]
Special newsletter or just regular.
  • - [ ]
Other placementsSpread the word in meetings or at other events.
  • - [ ]
MediaShould be changeable, specify target audience, language, sources.
  • - [ ]
Media suggestionsVideo, images, PDF, texts, merch, graphics. Everything should be planned in advance precisely date, type, releases, scope, size, etc.
  • - [ ]
GraphicsSet design motto.
  • - [ ]
Key metricsShould the success be tracked by key metrics, if so which ones.
+

Checklist 5 months before Hackathon

+
DateTask
  • - [ ]
Clarify if extra merch is desired and start looking for vendors. Order samples.
  • - [ ]
Discuss concrete advertising measures.
  • - [ ]
Check hotels (see checklist hotel).
+

Checklist hotel

+

Iportant things

+
    +
  • Availabilities in the period.
  • +
  • Way from the hotel to the hackathon.
  • +
  • Parking at the hotel.
  • +
  • Way from train station to hotel.
  • +
  • Checkin / Checkout times.
  • +
  • Check barrier-free accessibility.
  • +
+

Nice-to-have things

+
    +
  • Bar in the hotel, for relaxed sitting together in the evening.
  • +
  • Clarify whether employees from on site are also allowed in the bar.
  • +
  • Clarify whether reservations must be made in the bar, if so, reserve for the evening before.
  • +
  • Possibility of contingent reservation.
  • +
+

Checklist 4 months before Hackathon

+
DateTask
  • - [ ]
Determine hotel final and make recommendation. Possibly reserve contingent if the hotel offers it.
  • - [ ]
Find the location for the evening before (see checklist for evening before location).
  • - [ ]
Start organizing venue. (See checklist rooms 1).
  • - [ ]
Roughly plan evening event (consider volume level and space available).
  • - [ ]
Promotional drumbeat. Social media, website, meetings, newsletter.
  • - [ ]
Order special merch.
  • - [ ]
Organize merch in general (see merch checklist).
  • - [ ]
Start collecting statements that need to be sent around. (Privacy statements, photo statements, data center statements, security statements).
  • - [ ]
Rough sequence of events to be able to plan more precisely at a later date.
+

Checklist for evening before location

+
    +
  • Volume level.
  • +
  • Consider food possibilities.
  • +
  • Enough space.
  • +
  • Availability.
  • +
  • If intermediate change from A to B, then plan and include firmly in the plan.
  • +
  • If it is necessary to choose two locations because of food, drink, coziness, distance to the hotel: plan both, ask for and book them.
  • +
  • Ask for flexibility in the reservation. If more people come as registered.
  • +
  • Plan times.
  • +
  • Price / performance ratio should fit.
  • +
  • Way from the hotel to the evening before location.
  • +
+

Checklist rooms 1

+
    +
  • Space available (Enough space available for: Work area, meet-up area, no-photo area, break room, restrooms?).
  • +
  • Provisional room plan.
  • +
  • How long are the rooms available?
  • +
  • Are there any legal/corporate issues to consider?
  • +
  • Do declarations need to be signed to enter the premises?
  • +
  • List what hackathon relevant equipment is on site and if anything needs to be organized. For example, screens, whiteboards, power sockets if necessary, +tables, chairs, wi-fi, etc.
  • +
+

Checklist merch (examples)

+
    +
  • Ballpens
  • +
  • Lanyards
  • +
  • Notepads
  • +
  • Stickers
  • +
  • ID card / name badge covers
  • +
  • Name badges
  • +
  • Snacks
  • +
+

Checklist 3 months before Hackathon

+
DateTask
  • - [ ]
Required declarations (photo/video usage rights, data center, premises, etc.) are available as a form. Have a look if you can have
them confirmed with the registration. Otherwise as a circular email to all who register with the registration confirmation. Well
visible. For the photo/video declaration: Give the option of refusing and explain the variant with the no-photo dot.
  • - [ ]
Promote again: Website, social media, newsletter, meetings, circular email, etc....
  • - [ ]
Make reservations for pre-evening event.
  • - [ ]
Plan evening event and reserve location / tables (see checklist evening event).
  • - [ ]
Create a provisional schedule.
  • - [ ]
Eventually invite people separately. (Special guests).
  • - [ ]
Schedule start time and arrival time. Allow enough time for everyone to arrive.
  • - [ ]
Set presentation time and end time.
  • - [ ]
Define arrival time evening event. Leave enough time to change, but also do not define too long.
  • - [ ]
Schedule a fixed cleanup time.
  • - [ ]
Plan break time.
  • - [ ]
Activate login page.
+

Checklist evening event

+
    +
  • Volume level (It should be possible to have relaxed conversations)
  • +
  • Available space
  • +
  • Price / performance ratio should be suitable
  • +
  • Check availabilities
  • +
  • Snacks should be possible
  • +
  • Request flexibility with reservation (number of participants)
  • +
  • Actions would be a nice-to-have, everyone has been sitting and working all day, so it's good to have a change.
  • +
  • Way from the hotel to the evening location.
  • +
+

Checklist 2 months before Hackathon

+
DateTask
  • - [ ]
Start collecting goals and topics.
  • - [ ]
Work out goals and topics yourself.
  • - [ ]
Check results from the checklist rooms 1 again.
  • - [ ]
Go through checklist rooms 2.
  • - [ ]
Advertising (social media, mailing list, website, blog post, newsletter, room plan video, etc).
  • - [ ]
Go through checklists again in general, was anything forgotten?
  • - [ ]
Plan food for the break.
  • - [ ]
Plan snacks / breakfast (See snacks checklist).
+

Snacks checklist

+

Breakfast examples

+
    +
  • Sandwiches (rolls)
  • +
  • Pretzel sandwiches
  • +
  • Sandwiches (toast)
  • +
  • Cocktail tomatoes
  • +
+

Snack exemples

+
    +
  • "Kinder Schokobons"
  • +
  • "Kinder Schokoriegel"
  • +
  • "Kinder Duplo"
  • +
  • Hanuta
  • +
  • Gummy bears
  • +
  • Apples
  • +
  • Bananas
  • +
  • Nuts
  • +
  • Grapes
  • +
  • Dried fruits
  • +
  • Salted sticks
  • +
  • Salted pretzels
  • +
+

Vegan snack examples

+
    +
  • "Katjes Fruchtgummi"
  • +
  • "Katjes Lakritz"
  • +
+

Checklist rooms 2

+
    +
  • Create a room plan for publication. In it, work areas, break areas, no-photo area, meet-up places should be clearly +visible. Gladly also again as a video.
  • +
  • If necessary route map.
  • +
  • Is wifi available without any problems?
  • +
  • Where will drinks be located?
  • +
  • Where to set up snacks?
  • +
  • Where the food for the break?
  • +
  • Are there enough plates, cups, glasses, cutlery, napkins, and bowls for snacks?
  • +
+

Checklist 1 month before Hackathon

+
DateTask
  • - [ ]
Fix and publish the agenda.
  • - [ ]
Check the declarations once again, has every declaration been send, have any answered yet?
  • - [ ]
Check reservations, expand if necessary.
  • - [ ]
Check whether all possible special features have been observed (location etc).
  • - [ ]
Pre-order food for in-between meals and for the lunch break.
  • - [ ]
Plan drinks, type and quantity (don't forget coffee, tea, milk, sugar).
+

Checklist 1 week before Hackathon

+
DateTask
  • - [ ]
Print statements and forms.
  • - [ ]
Advertise again.
  • - [ ]
Make a list for the snacks (See for inspiration checklist snacks).
  • - [ ]
Pre-order the food, if necessary, check whether the quantity still fits with the registrations.
Depending on expand. Firmly plan transport / pickup / delivery.
  • - [ ]
Create a room plan with the topics, where, when, what takes place.
  • - [ ]
Organize drinks.
  • - [ ]
Determine the time when the helpers / organizers meet.
  • - [ ]
If necessary create / organize lists and visitor cards.
+

Checklist one day before Hackathon

+
DateTask
  • - [ ]
Buy snacks.
  • - [ ]
Contact food supplier again if the delivery date is suitable.
  • - [ ]
Check technology for functionality.
  • - [ ]
Send around the room plan with the topics by email.
  • - [ ]
Prepare rooms if necessary / possible.
  • - [ ]
Put drinks in the refrigerator.
  • - [ ]
Provide coffee machine.
  • - [ ]
Provide dishes.
  • - [ ]
Label rooms.
  • - [ ]
Check visitor cards and lists for completeness.
+

Checklist Hackathon Day X

+
TimeTask
  • - [ ]
Place snacks on the tables in small bowls or similar.
  • - [ ]
Distribute merchandise.
  • - [ ]
Have declarations and forms ready for late deciders.
  • - [ ]
Have lists and visitor cards ready if necessary.
  • - [ ]
Check drinks in an interval.
  • - [ ]
Make coffee if necessary.
  • - [ ]
Provide tea, coffee, milk, sugar.
  • - [ ]
Provide breakfast / snacks.
  • - [ ]
Pick up lunch.
  • - [ ]
Lunch "build up"
  • - [ ]
Cleanup
  • - [ ]
Keep an eye on the process (keep times a little bit).
  • - [ ]
See if everyone feels picked up, no one is bored.
  • - [ ]
Makes Photos.
+

Checklist after Hackathon

+
DateTask
  • - [ ]
Collect photos and provide them in a link for review and approval.
  • - [ ]
Create and send feedback sheet.
  • - [ ]
Create Blog Post Article.
  • - [ ]
Eventually create retro video.
  • - [ ]
Create social media posts. (After all approvals).
  • - [ ]
Prepare debriefing.
  • - [ ]
Summarize and process feedback.
+ + \ No newline at end of file diff --git a/community/index.html b/community/index.html new file mode 100644 index 0000000000..3b55aa1c85 --- /dev/null +++ b/community/index.html @@ -0,0 +1,26 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Overview

Welcome to our SCS Community

+

Sovereign Cloud Stack is an open community of providers and end-users joining forces in defining, implementing and operating a fully open, federated, compatible platform. We actively encourage you to contribute either code, documentation or issues and to participate in the various discussions happening on GitHub or during our various meetings.

+

We have created an open community space on the Matrix network. Feel free to join the several channels and start interacting with the community. A good starting point is entering the General & Announcements and the Tech channel.

+

Check out our Community Calendar to know when our several Teams and SIGs meet.

+ + \ No newline at end of file diff --git a/community/license-considerations/index.html b/community/license-considerations/index.html new file mode 100644 index 0000000000..419954fa55 --- /dev/null +++ b/community/license-considerations/index.html @@ -0,0 +1,213 @@ + + + + + +License considerations for SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

License considerations for SCS

+

As Sovereign Cloud Stack (SCS), our mission is to provide Operators +(be it Cloud Service Providers or just internal IT departments) with a well working software +stack, that avoids exposing them to legal risks or additional restrictions that limits the +usefulness. Free software licenses have this intention but differ in how they achieve it and in +what kind of protections they provide. In the first approximation, all OSI-approved +open source licenses can be considered as valid options. As a matter of fact, +we do consider projects under such licenses as valid modules for SCS — where we +use such projects and adjust or extend them, we would provide our contributions +under the license terms of the respective project, so we can achieve our goal to feed back code +upstream to the respective project, contribute to it and avoid fragmentation.

+

Where we do create independent code, we do have additional preferences, though.

+

For our own code, we do prefer the Affero General Public License version 3 +(AGPLv3) as license. Likewise, for documentation, we prefer CC-BY-SA. +Where we create standard libraries to interface with our software, we would +consider the LGPLv3 for these, +as we don't want interaction with our platform to be seen as requiring licensing +code.

+

Reciprocity

+

The GPL family of licenses are reciprocal licenses — sometimes called copyleft +licenses — the recipient of the licensed code can make all sorts of modifications, +but if she uses the code to release software (GPL) or provide a networked service +(AGPL) to others, then she must grant the same rights to the recipients — this +includes making the modifications available under the same terms as the received software. +Microsoft has infamously attacked +copyleft licenses (and specifically the GPL) as cancerous "viral" license.

+

Reciprocity has many advantages:

+
    +
  • +

    Code that has been created as free software will stay free. While GPL code can be +combined in a larger software collection with proprietary software, the code itself +including its enhancements etc. (technically: all derived works, see below) will +remain free.

    +
  • +
  • +

    The obligation to make the changes available avoids fragmentation. As changed and +"improved" versions need to be made available, it is much easier to review and feed +those changes back and create a unified upstream codebase that reflects the needs of +the complete user base by including the needed changes. This was observed and +reported by Martin Fink (HP's former CTO).

    +
  • +
+

The hugely successful Linux kernel project uses the GNU GPL; +many of the more traditional key projects in the open source world use copyleft licenses such as +the AGPL, GNU GPL, GNU LGPL, MPL or the OSL.

+

Controversy

+
    +
  • +

    Not fulfilling the license terms of a software license typically leads to the ability for the +license owner to revoke the license — as it is relatively easy to not fulfill all obligations +of the GPL out of sheer negligence, the revocation without prior warning seems +disproportionate — this is sometimes called the GPL death penalty. The open source community +though has a strong interest in bringing every licensee into compliance by giving violators a +fair chance to correct their behavior. SCS explicitly supports the GPL Cooperation Commitment +and the respective document +from the Linux kernel developers and pledges to give violators a warning and a chance to correct action +by allowing for a cure period. This is a bit of a legacy issue — it is relevant to (L)GPLv2 +code only — v3 of L/A/GPL does already contain language that has cure provisions, so it's +clear by the licensing terms.

    +
  • +
  • +

    Many companies seem to be worried that they will inadvertently violate the GPL by negligence. +And it is true that a company needs a tighter control of the usage of inbound source code +which comes with a reciprocal license than the permissive BSD 3-clause or Apache Software (v2) +licenses. This advantage however quickly turns into a disadvantage as soon as the company does +significant outbound open source contributions under a permissive license — they rarely want +to give their competitors an opportunity to consume their contributions and then add +proprietary changes to gain an advantage. In general, companies are well advised to have a +detailed understanding of all code that is being used and contributed and their respective +license terms — for proprietary and open source code and for reciprocal and for permissive +licenses. Some companies have successfully installed license review boards or +open source review boards +to create oversight, recommendations and policies to ease the governance.

    +
  • +
+

Despite this, many of the recent open source projects, especially in the cloud world +have adopted permissive licenses, such as X11, BSD 3-clause, MIT and especially the popular +Apache software license (ASL2), as it +appears to allow for faster adoption by companies that may not have mature open source +policies in place or that simply have overly careful lawyers which may be influenced +by the scare tactics some bad companies have built on top of copyleft licenses.

+

Affero

+

The reciprocity of the GNU GPL does not apply on the creation of a derived work. A company +can consume GPL'ed code and change it to their own liking without ever making any the +changes available if only used in-house. The terms however do apply as soon as the derived +work is released, i.e. the software is passed on to a third party.

+

In modern times, software is often used to provide a networked service (think SaaS) to third +parties. Unlike the standard GPL, the Affero GPL (AGPL) does consider the act of making it +available in such a way as similar to releasing the software and does require that applied +changes to the software are being made available in this case.

+

The AGPL thus closes a shortcoming in the traditional non-Affero GPL for a world that +increasingly moves towards networked services.

+

The very successful Nextcloud project uses the AGPLv3.

+

Derived works and Strong vs. Weak Copyleft

+

What exactly constitutes derived work needs to be defined — it's one of the questions where +copyright law can get subtle. From a practical view, consuming (non-trivial) source code and +binary linking is typically considered creating derived works. Whereas interacting via a network +API or starting another process is typically considered a copyright boundary. To avoid any +unclarity, the Linux kernel community has explicitly called out using Linux system calls (which +includes using the interface definitions) is a copyright boundary and can thus be done by +applications without any license implications.

+

Considering linked code to be derived works (as is the case in the GPL and AGPL) and thus +requiring it under the same (or a compatible) copyleft license is considered a Strong Copyleft +license.

+

Libraries are often providing implementations for standard services and helpers; it may not be +reasonable to consider applications that want to use a library as derived works from that +library and requiring the application to thus be licensed under a (compatible) copyleft license. +For these libraries, a Weak Copyleft license (such as the LGPL +or the EPL can be used. This would still require changes to +the library itself to me made available under the copyleft license but would make binary +linking (including the use of interface definitions) a copyright barrier and thus allow for +non-copylefted code to be linked against a weakly copylefted library. This license is used by +many of the standard and system libraries in the Linux world and is often a good choice for +libraries of standardized services.

+

Patents

+

Free software licenses are intended to give users broad rights — the GNU GPL talks about the +four freedoms to use software for any purpose, to study and +adjust the software (this needs source code access), to redistribute the software and to improve +it and to make these improvements available.

+

Software patents can significantly subvert the intended rights — the open source community in +general dislikes software patents for this and many other reasons that are discussed +elsewhere . +In some countries, there are rules that prevent pure software from being patented, though not +all patent offices are fully following these rules.

+

As software patents are existing and a serious danger to the open source goals, there are a few +attempts to improve the situation. The Apache Software License (a permissive license), requires +code contributors to grant a patent license to all downstream recipients of the code +to use the contributed code by itself or in combination with the project that it was contributed +to and makes a possible patent holder lose its license rights should he nevertheless try to +assert a patent against the thus licensed use. The (A)GPLv3 has a similar clause.

+

The Open Invention Network (OIN) has a meanwhile +huge patent pool that is cross-licensed between all participants and which can freely be used +in a large list of covered open source software by everyone, except for those that raise patent +violation claims against any of the covered open source projects. This basically restricts +those patents to be only used defensively in the context of the covered open source projects.

+

Should SCS be in a position to make inventions that should be protected by a software patent, +it pledges to contribute these to the OIN pool.

+ +

Very few Open Source projects require copyright assignment; the GNU projects are the +only commonly used ones that the author is aware of. This results in fully centralized +copyright ownership. This puts the FSF into a very +strong position — a position to enforce copyright, to change licenses etc. This requires +a lot of trust towards the copyright assigneed.

+

Most open source projects prefer distributed copyright — the authors (or their +employers) retain the copyright to their works. They grant a license for the open +source project to use and integrate and redistribute the work — typically the +license grant is extended to the public. In a sufficiently distributed copyright model, +it is very hard to change a license, as all copyright holders would need to agree. +This can both be considered advantageous and disadvantageous.

+

Many software projects use Contributor License Agreements +(CLAs), documenting that contributed code grants certain rights to the project +owner (a foundation or sometimes a company). This ensures that the project owner +has all needed rights to use, protect, redistribute ... the code. If the CLA contains +copyright assignment, it also allows the project to change the license or to +create derived works under a different license.

+

While this is advantageous for the project owner, it is not necessarily advantageous for the +code contributor.

+

Copyright enforcement does not require all copyrights to be held by a legal entity. Any holder +of significant copyrights can actually enforce it against violators.

+

The Linux kernel and an increasing number of projects do not work with copyright assignments +nor CLAs, but with Developer Certificates of Origin +(DCO — the signed-off lines of kernel commits). This is deemed sufficient to document the origin and the authorization to +contribute code.

+

The SCS project will not change the license. There however might be cases, where potential users +can not consume AGPL'ed or LGPL'ed code (due to corporate policies, e.g. based on bad experience, +immature license governance practices or lawyers that panic). Our goal would be to ensure that our +licensing terms and all other pledges provide the assurance needed that users do not need to be +afraid of the AGPL. The cure provisions from v3 of the GPL license family actually also help to +avoid unnecessary fear. However, unfortunately, some "open source" companies in the past have +abused copyleft with a scare and sell a proprietary license tactics to make money, which has +hurt copyleft acceptance significantly. We might thus not be successful and need to somehow +accept not serving all users or come up with a relicensing scheme that can not corrupt +ourselves. We are following the copyleft-next discussion to work out how we can best achieve +this, but have not yet found the silver bullet. This might have an influence how we do DCOs, +maybe under a permissive license, or maybe need to use CLAs.

+

License in = License out

+

It is best practice that open source projects grant their downstream users the same +license rights as they received contributions under. Or worded the opposite direction: +It is best practice to require no more rights to be granted from upstream contributors +(in the CLA or DCO) than the projects grants to downstream consumers of the project. +SCS follows this best practice.

+

Further reading

+
+ + \ No newline at end of file diff --git a/community/mission-statement/index.html b/community/mission-statement/index.html new file mode 100644 index 0000000000..d38d2a8034 --- /dev/null +++ b/community/mission-statement/index.html @@ -0,0 +1,75 @@ + + + + + +Mission Statement | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Mission Statement

+

Sovereign Cloud Stack (SCS) offers more than just a software stack — it's the embodiment of a collaborative open-source spirit, united by the aim of achieving digital sovereignty. At the heart of this initiative is a foundational pillar: the community.

+

Open Source technology has become increasingly mature. However, the greatest software is useless if it cannot be developed and operated with full confidence. For this to happen, it is imperative that skills and knowledge be built up, fostered, and retained. In an increasingly competitive market for skilled people and complex IT systems, this is becoming an ever greater challenge for governments, institutions, and companies. How can we operate digital offerings in a self-determined, secure, and excellent manner?

+

The answer to this must be the collectivization of operational knowledge, just as it has been practiced for many years with software development.

+

In essence, the community is the core of the Sovereign Cloud Stack. It not only propels its evolution but also ensures its relevance, reliability, and resilience in an ever-evolving digital landscape.

+

Read our open operations manifesto or join our Community either by joining our team meetings or by joining our matrix channel.

+

Check out the different meetings and working topics within our team and SIG introductions.

+

Values of our collaboration

+

4+1 Open

+

For us as a community, the "Four Open" are more than a philosophy; rather, we see them as fundamental values that are essential for working collaborativly.

+

The Four Opens give us the frame to develop SCS as a community that can be considered an important cornerstone tomorrow. We can also contribute to future developments and play an active role in shaping them.

+

The 'Four Open"

+
    +
  • Open Source: source code - open software that can be modified without restriction, on the condition that it is not limited in functionality or performance
  • +
  • Open Design: the open process for designing the software
  • +
  • Open Development: the opportunity to participate in the transparent development process on an equal footing
  • +
  • Open Community: an equal community where everyone can be heard
  • +
+

+1 Open

+

For us, the 5th Open is the Open Operation. At its core, the manifesto encompasses the collective, transparent exchange of knowledge. It describes the way to encourage everyone - regardless of their level of knowledge - to contribute to the community. The 5th Open has the principle that we can only learn from mistakes and therefore has an open and friendly mistake tolerance.

+

Our SCS '5-Open' community is just as open as described above - join us and leave your mark on the technologies of tomorrow. Join our Open Operations Meetup.

+

Code of Conduct

+

Sovereign Cloud Stack Community

+

Sovereign Cloud Stack (SCS) is a network of organizations and individuals: providers, integrators, contributors, users, developers, operators, and associates of standardized sovereign cloud infrastructure. We join forces in defining, implementing and operating a fully open, federated, compatible, interoperable cloud infrastructure and platform.

+

We are committed to "The Four Opens" of the Open Infrastructure Foundation and align our actions according to these four non-negotiable core principles of open collaboration. To include the whole DevOps approach we added the fifth open: Open Operations.

+

We do believe that an open and welcoming environment is essential for an active and engaged community. As contributors and maintainers we pledge to make participation in our project and our community a harassment-free experience for everyone.

+

No list is ever exhaustive, so we encourage members of the SCS community to adhere to the spirit, rather than the letter, of this code, as that is how it will be enforced. Places where this code may be particularly applicable are GitHub issues and pull requests, chat, mailing lists, team meetings, discussions on social networks broadly directed at or between members of the community, and other direct interactions within the community. Violations may lead to verbal or even public warnings or - especially in case of continued or flagrant offenses - may affect an individual's (or organization's) ability to participate within the SCS community.

+

We encourage you to confront someone or a group of people that you observe to be in violation of the CoC (whether in letter or in spirit) with your observation, so that the person(s) can correct his/her/their behavior. If this is not successful or it is difficult for you to confront the people and you seek support for this, you may contact the SCS project lead at project-lead(at)lists.scs.community

+

A large fraction of SCS consists of contributions to upstream projects. All SCS contributors are expected to adhere to the respective upstream Codes of Conduct when interacting with such projects, or developing code intended for upstreaming.

+

Our Standards

+

We ask you to please adhere to the following basic rules:

+
    +
  • Be friendly and patient. We were all new or lacked knowledge at various points in time. Please try to remember what it felt like to be on that end, and treat people accordingly.
  • +
  • Use welcoming and inclusive language. We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, organization, color, immigration status, social and economic status, educational level, level of experience, sex characteristics, gender identity and expression, sexual orientation, gender identity and expression, age, body size and personal appearance, disability, family status, political belief, religion, and mental and physical ability.
  • +
  • Be helpful. By helping others to learn our entire ecosystem is enriched. We encourage members of the SCS community to mentor each other and help to raise the general level of knowledge in the community whenever possible.
  • +
  • Choose words that shows respect, empathy and promote constructive dialogue. We are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable. This includes, but is not limited to: +
      +
    • Violent threats or language directed against another person.
    • +
    • Discriminatory jokes and language.
    • +
    • Posting sexually explicit or violent material.
    • +
    • Posting (or threatening to post) other people's personally identifying information ("doxing"), regardless of whether it is publicly available.
    • +
    • Personal insults, especially those using racist, sexist, or otherwise discriminatory terms.
    • +
    • Deliberately referring to others by names or pronouns counter to their identity.
    • +
    • Unwelcome sexual attention.
    • +
    • Repeated harassment of others, e.g. not stopping behavior when someone asks you to stop.
    • +
    • Advocating for, or encouraging, any of the above behavior.
    • +
    +
  • +
  • Be respectful, accept differing viewpoints and focus on what is best for the community. Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It's important to remember that a community where people feel uncomfortable or threatened is not a productive one. Members of the SCS community should be respectful when dealing with other members as well as with people outside the SCS community.
  • +
  • When we disagree, try to understand why. Disagreements, both social and technical, happen all the time and SCS is no exception. It is important that we resolve disagreements and differing views constructively. Remember that we're different. The strength of SCS comes from its broad community, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn't mean that they're wrong. Don't forget that it is human to err and blaming each other doesn't get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes.
  • +
+

Attribution

+

This Code of Conduct is mainly adapted from the Asahi Linux Code of Conduct and the Contributor Covenant Code of Conduct.

+ + \ No newline at end of file diff --git a/community/tools/github/branchprotection/index.html b/community/tools/github/branchprotection/index.html new file mode 100644 index 0000000000..0ec2d762ba --- /dev/null +++ b/community/tools/github/branchprotection/index.html @@ -0,0 +1,45 @@ + + + + + +Branch Protection Rules | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Branch Protection Rules

+

To protect our source code from unwanted changes, we enforce the following branch protection rules for all repositories within our GitHub organization:

+
    +
  • Require a pull request before merging into our default branch main. +
      +
    • Require at least one approval before pull requests can be merged.
    • +
    • Dismiss stale pull request approvals when new commits are pushed
    • +
    +
  • +
  • Require status checks to pass before merging +
      +
    • Require branches to be up to date before merging
    • +
    • Status checks that are required: + +
    • +
    +
  • +
  • Do not allow bypassing the above settings
  • +
+

The branch protection rules are rolled out by our github-manager to ensure that all repositories use a consistent set of rules. Should you intend to propose changes to the above rules, please open a pull request against orgs/SovereignCloudStack/data.yaml.

+

Some repositories however do allow that the above rules are bypassed by the organization's owners, especially repositories that are used for public resources such as the website or the weekly digest.

+ + \ No newline at end of file diff --git a/community/tools/github/dco-and-licenses/index.html b/community/tools/github/dco-and-licenses/index.html new file mode 100644 index 0000000000..434011b0e9 --- /dev/null +++ b/community/tools/github/dco-and-licenses/index.html @@ -0,0 +1,47 @@ + + + + + +Developer Certificate of Origin + Licenses | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Developer Certificate of Origin + Licenses

+

The Developer Certificate of Origin (DCO) is a lightweight way for contributors +to certify that they wrote or otherwise have the right to submit the code they +are contributing to the Sovereign Cloud Stack.

+
By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or

(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or

(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.

(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
+

All contributions to the Sovereign Cloud Stack are licensed under the +(OSI approved) open source license of the upstream project being used therein +(very often this is the Apache Software License v2).

+

Where we create independent code, we prefer to use the GNU Affero General Public License 3, +except for interface code which we would put under LGPL-3 (weak copyleft). +Own documentation content is licensed under Creative Commons BY-SA 4.0.

+

Contributors sign-off that they adhere to these requirements by adding a Signed-off-by +line to commit messages.

+
My fancy commit message

Signed-off-by: Christian Berendt <berendt@osism.tech>
+

Git has a -s command line option to append this automatically to your commit message:

+
git commit -s -m 'My fancy commit message'
+

The status of a pull request is set to failed if commits do not contain a valid Signed-off-by line.

+

Failed DCO in GitHub

+

Considerations behind the choice of AGPLv3, CC-BY-SA and the usage of the DCO can be found license-considerations.md.

+

Further reading

+
+ + \ No newline at end of file diff --git a/community/tools/github/tips-and-tricks/index.html b/community/tools/github/tips-and-tricks/index.html new file mode 100644 index 0000000000..3e669457cb --- /dev/null +++ b/community/tools/github/tips-and-tricks/index.html @@ -0,0 +1,31 @@ + + + + + +Tips and Tricks | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Tips and Tricks

+

Octo Reminder - your friendly assistant

+

Are you tired of keeping track of planned changes or issues you scheduled for the future? Our Octo Reminder is here to safe you from unneeded cognitive load!

+

The app configuration is stored in our .github repository. Using the bot is fairly simple:

+
    +
  • To schedule a reminder, simply comment with /remind-me [date] [message] on an issue or pull request. The bot will answer and mention you in the particular issue/pull request upon reaching the configured date.
  • +
  • If you don't specify a time for the reminder, the bot will use 9:00 CET as default reminder time.
  • +
  • The date and time can be anything that momentjs understands, e.g. an ISO 8601 string or a relative string such as tomorrow or next week.
  • +
+ + \ No newline at end of file diff --git a/community/tools/jitsi/index.html b/community/tools/jitsi/index.html new file mode 100644 index 0000000000..8f3f3a6f95 --- /dev/null +++ b/community/tools/jitsi/index.html @@ -0,0 +1,42 @@ + + + + + +Jitsi | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Jitsi

+

We use a self-hosted Jitsi Meet instance for video conferencing. +Thanks go to Cleura for providing the server for it.

+

The server uses an automated deployment based on the +heat-docker-jitsi-meet project.

+

Configuration is such everyone who knows the room can connect, unless the moderator +sets a password/PIN. Opening a new room requires authentication. (Contact Kurt if +you need a password.)

+

Links to the meeting room (as well as dial-in information) are in the appointments +in the public calendar.

+

Usage

+

Connect with a desktop browser (Chrome/Chromium or other blink based browser +recommended due to superior WebRTC implementation with SimulCast/SVC for VP8/VP9 -- +Safari & Firefox work, but cause higher data traffic). For mobile devices use +the Jitsi Meet App.

+

Use the little arrows in the control bar at the bottom to select speaker, microphone +and camera in case you lack audio/video. Occasionally, you can not hear all but +one participant; in this case reconnecting typically helps.

+

We have an asterisk connected to some conference rooms to provide dial-in capabilities +for folks that lack internet connectivity (but have a working phone connection).

+ + \ No newline at end of file diff --git a/community/tools/mailinglists/index.html b/community/tools/mailinglists/index.html new file mode 100644 index 0000000000..333656132f --- /dev/null +++ b/community/tools/mailinglists/index.html @@ -0,0 +1,26 @@ + + + + + +Mailing Lists | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Mailing Lists

+

We have an announcements mailing list there announce@lists.scs.community and you +can subscribe via the mailman3 frontend +also without the SCS nextcloud account if you prefer.

+ + \ No newline at end of file diff --git a/community/tools/matrix/index.html b/community/tools/matrix/index.html new file mode 100644 index 0000000000..e456775f7e --- /dev/null +++ b/community/tools/matrix/index.html @@ -0,0 +1,26 @@ + + + + + +Matrix | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Matrix

+

We have created an open community space on the Matrix federation. Feel free to join the several channels and start chatting with our community. A good starting point is entering the General & Announcements and the Tech channel.

+

Client and Registration

+

To connect to the Matrix federation, you will need an account on a federated homeserver and a client. The easiest way to join us is register on the popular matrix.org homeserver via the Element web client: https://app.element.io/#/register. A list of curated Matrix clients is collected on the official Matrix website: https://matrix.org/clients/

+ + \ No newline at end of file diff --git a/community/tools/nextcloud/index.html b/community/tools/nextcloud/index.html new file mode 100644 index 0000000000..60235ed520 --- /dev/null +++ b/community/tools/nextcloud/index.html @@ -0,0 +1,32 @@ + + + + + +Nextcloud | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Nextcloud

+

We have a Nextcloud +instance for sharing files, doing polls, ... +setup for things that are not public.

+

You can contribute to SCS via the github workflows, asking questions there (via +opening issues against the issues repository), submitting pull requests, ... +If you want to contribute on a regular basis, we are happy to also onboard you +to the nextcloud and do an onboarding call. Nextcloud onboarding also adds you +to the scs-member@lists.scs.community mailing list which also add you to the +announcement list (described in the next paragraph).

+ + \ No newline at end of file diff --git a/community/tools/zuul/index.html b/community/tools/zuul/index.html new file mode 100644 index 0000000000..f1238b4aec --- /dev/null +++ b/community/tools/zuul/index.html @@ -0,0 +1,55 @@ + + + + + +Zuul | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Zuul

+

Zuul CI/CD pipelines and project gating

+

Since we are expecting a lot of pipelines beeing created and used GitHub actions won't keep up +well. We also expect cross-repository and even cross-project dependencies. Therefore we decided to +use Zuul as our main pipeline solution.

+

How to make a repo use Zuul

+
    +
  • Make Zuul aware of your repository in this repo
  • +
  • Create a file .zuul.yaml +
      +
    • An example can be found here
    • +
    • You can have a job section containing self-defined jobs which you need to write on your own
    • +
    • You have to have a project section containing +
        +
      • the default-branch name
      • +
      • the merge-mode which should be used to auto-merge
      • +
      • the jobs to run in each pipeline (gh_check, gh_gate, gh_post, gh_tag)
      • +
      • these pipelines are triggered by events which can be looked up here
      • +
      • some default jobs can be found here
      • +
      +
    • +
    +
  • +
  • If you have self-defined jobs, you need to create a folder .playbooks +
      +
    • this folder containers ansible playbooks which will be triggered
    • +
    +
  • +
+

General information about Zuul

+

Zuul does not take anything for granted. If you need to have something installed, +you should install it via ansible. Our test-machines are basically pimped +docker-containers, so we might run into issues some time. But for now, things work pretty good.

+ + \ No newline at end of file diff --git a/contributor-docs/development/index.html b/contributor-docs/development/index.html new file mode 100644 index 0000000000..d19571ab18 --- /dev/null +++ b/contributor-docs/development/index.html @@ -0,0 +1,25 @@ + + + + + +Developer documentation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Developer documentation

+

Welcome to the developer section of the contributor docs. Here you will find +guidelines for the implementation of tooling such as the SCS conformance tests.

+ + \ No newline at end of file diff --git a/contributor-docs/development/tests/rfc2119-keyword-test-guide/index.html b/contributor-docs/development/tests/rfc2119-keyword-test-guide/index.html new file mode 100644 index 0000000000..91fade1109 --- /dev/null +++ b/contributor-docs/development/tests/rfc2119-keyword-test-guide/index.html @@ -0,0 +1,119 @@ + + + + + +SCS RFC2119 Keyword Test Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS RFC2119 Keyword Test Guide

Introduction

+

The development and validation of tests within the Sovereign Cloud Stack (SCS) is a critical endeavor aimed at ensuring that cloud technologies meet the highest standards of interoperability, security and sovereignty. This process is not only about aligning with the technical specifications and standards set by SCS but also about safeguarding the principles of open-source collaboration and the autonomy of cloud services. By thoroughly crafting tests that adhere to the stringent requirement levels as indicated by RFC2119 keywords, we ensure that the infrastructure, services and their integrations within the SCS ecosystem are robust, secure and sovereign.

+

This detailed process is crucial for stakeholders seeking to develop or utilize sovereign cloud services that are reliable, compliant and capable of standing up to the demands of modern cloud computing. It serves as an indispensable guide for developers, operators and policymakers who are involved in the creation, deployment and governance of cloud services within SCS. By understanding and implementing the standards and tests defined by the SCS, professionals can contribute to a cloud infrastructure that is not only technologically advanced but also aligns with the core values of sovereignty and open-source ethics.

+

Therefore, for individuals tasked with writing tests and defining standards within SCS, this document is particularly important. It serves as a base with guidelines on how to use and understand RFC2119 keywords in the context of SCS. Its insights are crucial for anyone from technical architects to regulatory bodies within the SCS ecosystem, underlining the foundational principles necessary for achieving a sovereign cloud environment.

+

1. Understanding SCS Standards and RFC2119 Keywords

+

SCS standards use RFC2119 keywords like:

+
    +
  • MUST (same as REQUIRED, SHALL),
  • +
  • MUST NOT (same as SHALL NOT),
  • +
  • SHOULD (same as RECOMMENDED),
  • +
  • SHOULD NOT (same as NOT RECOMMENDED),
  • +
  • MAY (same as OPTIONAL)
  • +
+

to define requirements for SCS-compatible IaaS and KaaS resources. These standards & tests are crucial for ensuring interoperability and sovereignty in cloud services, as they are built on open-source components such as Kubernetes and OpenStack.

+

To ensure readability and comprehensibility, only the main keywords MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are referred to below.

+

2. Interpreting RFC2119 Keywords in the Context of SCS

+
    +
  • MUST and MUST NOT: These are binary and straightforward to test. Compliance or +non-compliance directly affects whether the standard is satisfied. For visualization, fulfilled +requirements could be marked in green, unfulfilled ones in red.
  • +
  • SHOULD and SHOULD NOT: These represent recommendations. While fulfilling these do +not directly affect standard compliance, it is advised for future-proofing against +potential standard evolutions. Non-compliance could be visualized in yellow, possibly +with a valid reason for non-fulfillment.
  • +
  • MAY: This is more flexible and could be used to provide additional +information or best practices. Their impact on compliance is not as direct as MUST or +SHOULD categories. These can be marked as blue.
  • +
+

3. Channels for Output in Test Scripts

+

In test scripts, different channels are used to convey information of different importance to the user. These channels are based on the ubiquitous and de-facto standard logging levels of common logging libraries in scripting and programming languages, in particular Python: DEBUG, INFO, WARNING, ERROR and CRITICAL.

+

Alignment of the RFC2119 keywords with specific channels in test scripts:

+
    +
  • MUST and MUST NOT lead to the ERROR channel for failed tests
  • +
  • SHOULD and SHOULD NOT lead to the WARNING channel, the test is still passed
  • +
  • MAY leads to the INFO channel, the test is still passed
  • +
+

However, the CRITICAL level is not directly associated with any of the RFC2119 keywords; it is instead used to signify that a test was unable to complete or was interrupted due to various issues, such as runtime failures.

+

4. Compliance and Test Passing Criteria

+

A test is considered to pass if and only if it doesn't produce any messages on the +ERROR nor the CRITICAL channel. The presence of warnings or informational items from +SHOULD and MAY categories do not directly impact the pass/fail status but is +important for overall quality and compatibility with future standards.

+

That means a test can have one of three results:

+
    +
  • fail: if it has at least one message on ERROR
  • +
  • DNF (did not finish): if it has no message on ERROR, but at least one on CRITICAL
  • +
  • pass: otherwise
  • +
+

In addition, a test MUST exit with a non-zero exit code (e.g., via sys.exit(…)) if there are any ERROR or CRITICAL messages, thus signaling a failure to meet a standard.

+

In test scripts it is a MUST to redirect all channel outputs to standard error (stderr), which aligns with Python's default logging behavior. The format which MUST be used is CHANNEL: MESSAGE, where CHANNEL represents the log level (e.g., DEBUG, INFO, WARNING, ERROR, CRITICAL) and MESSAGE encapsulates the actual log message.

+

For instance, when logging an INFO regarding a Kubernetes cluster, the format on the command line should be like this:

+
INFO: Checking cluster specified by context 'my-cluster' in /path/to/.kube/config.
+

This example adheres to our proposed format by clearly indicating the severity level (INFO) followed by the specific message intended for the user or developer.

+

Examples

+

5.1 Example: Standards Document using RFC2119 Keywords

+

The following example of a fictitious document for a "Web Server Installation Standard" +is intended to illustrate the use of RFC2119 keywords in connection with the creation of +SCS-compliant standard documents.

+

Web Server Installation Standard

+

Purpose

+

This document provides a concise set of requirements for installing a secure web server.

+

Requirements

+
    +
  • +

    Web Server Software: Apache HTTP Server 2.4.x or Nginx 1.18.x MUST be installed. No +other web server software versions or types are permitted.

    +
  • +
  • +

    Operating System: The server MUST run on an OS that receives current security updates. +Unsupported versions MUST NOT be used.

    +
  • +
  • +

    TLS Configuration: TLS 1.2 or higher MUST be enabled for all connections. SSL and +earlier TLS versions MUST NOT be used.

    +
  • +
  • +

    Security Patches: The web server and OS MUST be kept up-to-date with security patches. +Critical patches SHOULD be applied within 48 hours of release.

    +
  • +
  • +

    Firewall Setup: The firewall SHOULD be configured to allow only necessary ports, +such as 80 (HTTP) and 443 (HTTPS). All unnecessary ports SHOULD NOT be open.

    +
  • +
  • +

    Backup Plan: Regular backups of the web server data MAY be performed, and it is +recommended that backup integrity checks are conducted to ensure recoverability.

    +
  • +
+

Compliance

+

Failure to comply with these requirements results in the web server being +considered non-compliant with the organization's security policies.

+

5.2 Example: Test script using RFC2119 Keywords

+

The following example of a fictitious code for a test of "process_requirements" +is intended to illustrate the use of RFC2119 keywords in connection with the +creation of SCS-compliant standard tests.

+

import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

def process_requirements(var1, var2):
try:
# debug log for input variables
logger.debug(f"Received input var1: {var1}, var2: {var2}")

# example of an error case (equivalent to MUST and MUST NOT)
if var1 < 0:
logger.error("var1 must be positive")
elif var1 > 100:
logger.error("var1 must not exceed 100")

# add debug log to confirm evaluation of var1
logger.debug(f"var1 evaluated: {var1 > 0 and var1 < 100}")

# example of a warning case (equivalent to SHOULD and SHOULD NOT)
if var2 < 10:
logger.warning("var2 should be at least 10 for optimal performance")
elif var2 > 50:
logger.warning("var2 should not exceed 50 for optimal performance")

# add debug log to confirm evaluation of var2
logger.debug(f"var2 evaluated: {var2 > 10 and var2 < 50}")

# example of an informative case (equivalent to MAY)
if var1 + var2 < 100:
logger.info("Combination is within recommended range")
else:
logger.info("Combination exceeds the recommended range but may still proceed")

# debug log before completing the process
logger.debug(f"Final evaluation before completion: var1 + var2 = {var1 + var2}")

# success log
logger.debug("Process completed successfully")

except ValueError as e:
# debug log before raising a critical error
logger.debug("Encountered a critical error about to log", exc_info=True)
logger.critical(f"Process failed: {e}", exc_info=True)

+

Note: The DEBUG channel is used for additional information for developers to better understand a process and does not apply to RFC2119 keywords.

+ + \ No newline at end of file diff --git a/contributor-docs/development/tests/test-implementation-guide/index.html b/contributor-docs/development/tests/test-implementation-guide/index.html new file mode 100644 index 0000000000..639873be61 --- /dev/null +++ b/contributor-docs/development/tests/test-implementation-guide/index.html @@ -0,0 +1,94 @@ + + + + + +SCS Conformance Test Implementation Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Conformance Test Implementation Guide

SovereignCloudStack (SCS) uses conformance tests to certify +compliance of a given cloud offering with respect to a given certificate +scope such as SCS Compatible IaaS v4. +Our aim is that these tests are reliable, consistent and comprehensible for +the users. +This document is a guideline for conformance test authors and summarizes the +current best practices to achieve this goal.

+

1. Mapping of RFC2119 Keywords

+

Test authors working on new and existing conformance tests for an SCS standard +must implement the keywords such as MUST and SHOULD according to the SCS +RFC2119 Keyword Test Guide.

+

2. Unit and Regression Tests

+

Test authors are strongly encouraged to include unit and regression tests for +the conformance test's logic. +Conformance tests will inevitably contain some non-trivial algorithms, be it for +parsing flavor names or evaluating CVE vulnerability reports. +Testing them automatically and regularly against valid and invalid inputs helps +test authors to find programming mistakes early on. +As a bonus, a well written unit test also makes it easier for reviewers to cross +check a given pull request with new, enhanced or refactored conformance tests.

+

In general, unit and regression tests for the conformance tests are located in +the same location as the conformance tests, that is, the Tests/ directory of +the SCS standards repository. +Setup and development of the unit tests is described in the SCS conformance +tests README.

+

Naming Conventions

+

Any module that ends in _test will be picked up as a unit test module by +pytest in our CI pipeline (in other words, all files matched by the pattern +Tests/**/*_test.py). +Pytest will execute any function prefixed with test_ as a test function, or, +alternatively, tests based on the unittest module from the Python standard +library.

+

Follow these naming rules:

+
    +
  • The name of a unit test module is constructed from the module to be unit +tested and the _test suffix. For example, unit tests for flavor_names.py +should reside in flavor_names_test.py.
  • +
  • The name of a Python module in general should be a valid Python +identifier, to allow imports via the import statement. +For example, use flavor_names.py instead of flavor-names.py.
  • +
+

Write Testable Conformance Tests

+

Software design fills complete book shelves and this section can only cover some +basic best practices. +As a general rule of thumb, the earlier you begin writing unit tests, the better +– it will force you to write modules that are easy to test.

+

Divide conformance tests scripts into smaller, loosely coupled units, i.e., +functions that serve one purpose each. +Use the dependency injection technique, i.e., pass externally +retrieved data as function arguments instead of hardcoding the calls to the +retrieval functions inside a function. +Avoid logging calls deep down in the call hierarchy and use explicit return +values or raise exceptions, instead. +Here is an abstract example of a conformance test which does exactly that:

+
# property_compliance.py

def retrieve(location):
"""Retrieve raw data via network."""
...

def parse(data):
"""Parse raw data and return a dict."""
...

def handle(...):
"""Evaluate parsed data."""
...

def main(args):
...
data = retrieve(location)
parsed = parse(data)
result = handle(parsed)
...
if result.some_prop != expected_value:
logging.warn("some_prop is not as expected: %s (vs. %s)", result.some_prop, expected_value)
...
return result.success

if __name__ == "__main__":
# using sys.exit(…) only here makes it possible to unit test main(…)
sys.exit(main(sys.argv))
+

Adhering to this style makes it easier to test an algorithm in isolation, +without actually making a call to some external service.

+

Pytest Test Example

+

Assuming we want to unit test some members of the module property_compliance +from the previous section, we would create a file property_compliance_test.py +with the following content as a starting point:

+
"""Unit tests for property_compliance.

(c) Your Name <your.name@example.com>, 4/2024
SPDX-License-Identifier: CC-BY-SA-4.0
"""

import pytest

from property_compliance import parse


def test_success():
assert parse("some valid input") == "expected output"


def test_failure():
with pytest.raises(ValueError):
parse("invalid input")
+

3. Conformance Tests Shouldn't Require Admin Privileges

+

Conformance tests are expected to be executable without admin privileges (see §2 of +Regulations for achieving SCS-compatible certification). +In particular, this means:

+
    +
  • The cloud credentials (e.g., kubeconfig and OpenStack clouds.yaml) passed to +the scripts are non-admin credentials.
  • +
  • Conformance tests scripts should not require root privileges, except for the +installation of operating system prerequisites (e.g., a Python interpreter).
  • +
+ + \ No newline at end of file diff --git a/contributor-docs/index.html b/contributor-docs/index.html new file mode 100644 index 0000000000..2e23cbff26 --- /dev/null +++ b/contributor-docs/index.html @@ -0,0 +1,25 @@ + + + + + +Documentation for SCS Contributors | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Documentation for SCS Contributors

+

Welcome to the Contributor Docs. This section is primarily for SCS Contributors and will contain documentation regarding the Development and Architecture of the Sovereign Cloud Stack and its components. You will find documents, explanations and guides regarding the tooling necessary for the development of SCS.

+

If you want to contribute you can reach out to us via our Matrix Channel.

+ + \ No newline at end of file diff --git a/contributor-docs/operations/iam/identity-federation-in-scs/index.html b/contributor-docs/operations/iam/identity-federation-in-scs/index.html new file mode 100644 index 0000000000..18bebf4cf7 --- /dev/null +++ b/contributor-docs/operations/iam/identity-federation-in-scs/index.html @@ -0,0 +1,42 @@ + + + + + +Identity Federation in SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Identity Federation in SCS

SovereignCloudStack wants to make it possible for operators to delegate +administration of user identities to the organizational entities that the +users are part of. Usually that's customer organizations but it could also +be the operator itself. Federation protocols like OpenID Connect can be used +to achieve that goal. To simplify connecting the different parts of SCS +to customer owned IAM solutions, SCS deploys Keycloak as central Identity +Provider (IdP) service.

+

Currently this is deployed automatically only in the osism/testbed, +which provides its own documentation for authentication with OIDC.

+

The following sections describe how this is done.

+

1. IaaS / OpenStack

+

To provide Infrastrucure as a Service SCS builds upon +OpenStack. See section OpenStack Federation via OpenID-Connect +for more details on identity federation for OpenStack.

+

2. CaaS

+

To provide Container as a Service SCS builds upon +Kubernetes. There is +work in progress +to optionally connect Kubernetes to Keycloak and to +map authorization decisions based on claims via cluster role bindings.

+ + \ No newline at end of file diff --git a/contributor-docs/operations/iam/openstack-federation-via-oidc/index.html b/contributor-docs/operations/iam/openstack-federation-via-oidc/index.html new file mode 100644 index 0000000000..bfc8d584af --- /dev/null +++ b/contributor-docs/operations/iam/openstack-federation-via-oidc/index.html @@ -0,0 +1,88 @@ + + + + + +OpenStack Federation via OpenID-Connect | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

OpenStack Federation via OpenID-Connect

Keystone supports federating authentication and authorization decisions via several mechanisms +as documented by the project.

+

In SCS OpenID Connect is used for federation between Keystone and the IdP, which is +currently provided by Keycloak +in SCS.

+

The following sections describe the setup.

+

1. Keystone

+

Keystone supports federated identities. +To allow SCS to consume identities managed in external IAM solutions, +federation protocols like OpenID Connect or SAML can be used. +Keystone currently makes use of third party apache modules like +mod_auth_openidc, +mod_oauth2 and +mod_auth_mellon to delegate +authentication to a SSO IdP (i.e. SAML IdP or OpenID Connect provider).

+

In OpenStack the apache modules are configured using the +wsgi-keystone.conf template.

+

In SCS we make use of the OAuth 2.0 Authorization Code Grant flow between Keystone and Keycloak +and use PKCE (RFC 7636) with the S256 challenge method.

+

In addition to the usual SSL CA of the environment, Keycloak uses separate certificates to sign the OIDC tokens.

+

Due to the way the Keystone container image runs apache (in the foreground) and keystone itself (as WSGI module), +reconfiguring the apache URL locations on the fly is not possible currently without a downtime of several seconds. +That is the reason why SCS currently makes use of a single central proxy realm in Keycloak, to which Keystone +connects.

+

1.1 Keycloak IdP realm discovery

+

Keycloak offers standard OIDC service discovery via .well-known documents to advertise its endpoints.

+

In SCS we want to represent each customer by a separate dedicated Keycloak realm, which can enventually be used +for customer self service and to federate out to customer owned IAM external solutions.

+

In the SCS testbed we currently experiment with the implications of using a single central proxy realm in Keycloak +and chaining federation from there to customer specific realms, also hosted in the same Keycloak instance. +To make this usable, SCS makes use of the +Keycloak Home IdP Discovery +extension.

+

1.2 Keystone mapping of token claims

+

Upon login of a user Keystone evaluates the credentials obtained from the ID token that the IdP issued. +These include group memberships and roles, which can be used to assign the user to a certain project. +Keystone maps these external identities to internal (shadow) users. +It can either attempt to map the obtained information to a local type user, which needs to be +provisioned before authentication by external tooling, or it can be instructed via the mapping to +generate an ephemeral type user. ephemeral users are cleaned up automatically after some time +of inactivity and with that, they lose access to projects, iff the access is granted indirectly +via group membership rather than directly to the user itself.

+

Group memberships for ephemeral users are only represented via their tokens, but not stored in the +Keystone backend database.

+

After successful authorization Keystone issues an OpenStack specific fernet token to the user, +which is the currency that is understood by other OpenStack services and can be used to access them.

+

In SCS we want to represent each customer by a sepatate dedicated OpenStack domain to host +their projects and (shadow) user accounts.

+

The processing of information from the OIDC tokens is configured by two parts. The first part is the +rules.json mapping which is described in the +OpenStack federation mapping combinations +document. This file is used to configure Keystones internal mapping engine +and it needs to be attached to some OpenStack domain, which is named keycloak by default in SCS.

+

The second (static) part is the [auth] and [mapped] sections in keystone.conf (see e.g. +the overlays currently used in the OSISM testbed +).

+

1.3 Horizon WebSSO for federated users

+

The Horizon dashboard supports login via OpenID Connect via Keystone endpoint. +SCS adjusted the logout behavior to invalidate both, the OpenID Connect session +with the IdP and the Keystone token.

+

1.4 OpenStack CLI and API access for federated users

+

To support OpenStack CLI and API access, SCS implemented support for the OIDC Device Authorization Grant +in Keystone. On top we added support for PKCE (RFC 7636) in combination with that.

+

1.5 SSO Federation between to SCS deployments

+

To show the potential of this approach to federation SCS created a +Howto for OIDC federation between SCS deployments.

+ + \ No newline at end of file diff --git a/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide/index.html b/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide/index.html new file mode 100644 index 0000000000..66db629ee0 --- /dev/null +++ b/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide/index.html @@ -0,0 +1,244 @@ + + + + + +Zuul users guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Zuul users guide

+

Prerequisites

+
    +
  1. Repository is known by SCS Zuul
  2. +
  3. Basic ansible knowledge
  4. +
  5. Basic yaml knowledge
  6. +
  7. zuul-client installed (Only if you want to create secrets. See also)
  8. +
+

Check SCS Zuul projects for your repository to +be available. If it is missing you need an administrator to get your repository +configured to Zuul.

+

Who is it for?

+

You may have heard about Zuul and may ask yourself if it is capable to support you. +Basically everything you use ansible for can be done using Zuul. That is not always +a good thing since you may get careless and your workload will exceed the CI/CD concept.

+

If you find yourself doing things under the following list you are at the right place.

+
    +
  1. Code testing
  2. +
  3. Deployment tests using IaC
  4. +
+

If you want to, let's say, monitor something using Zuul, that is possible but not the +intended use case.

+

Where do I start?

+

Right in your project's repository! The only prerequisite is that +your repository you want Zuul to work on is known by Zuul. This is done by the Zuul's +tenant configuration. To update this configuration you need access to the Zuul instance +or ask an administrator for help.

+

We assume that Zuul knows about your repository so we can get started. There are three +topics that you should know about. To get jobs running you need the "job" itself. Jobs run +within a "pipeline". The third important thing is to provide a "project" definition.

+

Where to save the Zuul relevant data?

+

Zuul will parse all branches of the untrusted repositories that Zuul knows about. +Your repository is most likely an untrusted one since only the configuration repositories should +have the "trusted" state. +So it doesn't matter whether you have just one branch containing Zuul files or all branches. Zuul +is looking for the following pathes on your repositories root.

+
./zuul.yaml # everything is in here

./.zuul.yaml # ... or here

./zuul.d/ # use directory style to get a bit of a structure
├── jobs.yaml
└── project.yaml

./.zuul.d/ # the same as before just hidden
├── jobs.yaml
└── project.yaml
+

Just use exactly one of the four possibilities.

+

If using the directory style configuration all yaml files within this directory will be +processed. If your projects configuration is small enough you may put all information in +a single file called zuul.yaml. It is also possible to create the file or the directory +with a leading dot to hide them for non zuul related work within the repository.

+

Projects

+

If Zuul is configured to observe your repository it will have a look at your projects +definition. Minimal example:

+
- project:
name: my-org/my-repo
default-branch: main
merge-mode: "squash-merge"
my_pipeline1:
jobs:
- my_job1
- my_job2
......
my_pipeline2:
jobs:
- my_jobs
...

+

By default Zuul will observe all branches for such files. We have to set the repository name +that have to match the exact value that was set for Zuul. Set a default-branch where actions +that don't match an explicit branch are executed on. Set the merge-mode that Zuul has to use. +But beware that not all issue tracker support all methods. For github squash-merge will work.

+

After these three properties add the pipelines you want to use to the project definition. +With the jobs list you define which jobs to run in which pipeline.

+

See official documentation

+

Pipelines

+

Every Zuul instance will have at least one repository that is used for configuration. There +you will find the available pipelines. Pipelines are used to run your jobs on a periodic or +event driven base. Pipelines can be used to run other pipelines and to keep your jobs in a +defined order if you need this.

+

Have a look at the configuration repository to utilize the pipelines for your repository. +See available pipelines for SCS. +You are not able to define new pipelines outside of a so called "configuration" repository. Since, +by default your repo is considered "untrusted". So in the first place you don't need to +think about, how to create a pipeline. Just use one that fits your needs as close as possible. Next you will +find an enumeration and a small description about the available pipelines in SCS Zuul.

+

Pipelines available in SCS Zuul:

+

1. check

+
    +
  • event driven pipeline
  • +
  • runs if a pull request is created, changed or reopened
  • +
  • re-runs if a comment contains recheck
  • +
+

2. gate

+
    +
  • event driven pipeline
  • +
  • trigger events: pull_request_review, pull_request, check_run
  • +
+

3. post

+
    +
  • event driven pipeline
  • +
  • trigger event: post
  • +
+

4. tag

+
    +
  • event driven pipeline
  • +
  • trigger event: push
  • +
+

5. e2e-test

+
    +
  • event driven pipeline
  • +
  • trigger event: pull_request
  • +
+

6. e2e-quick-test

+
    +
  • event driven pipeline
  • +
  • trigger event: pull_request
  • +
+

7. unlabel-on-update-e2e-test

+
    +
  • event driven pipeline
  • +
  • trigger event: pull_request
  • +
+

8. unlabel-on-update-e2e-quick-test

+
    +
  • event driven pipeline
  • +
  • trigger event: pull_request
  • +
+

9. periodic-hourly

+
    +
  • time based pipeline that runs every hour
  • +
+

10. periodic-daily

+
    +
  • time based pipeline that runs every day at 3 o'clock am.
  • +
+

11. compliance_check

+
    +
  • time based pipeline that runs every 15 minutes
  • +
+

If you want to know more about pipelines: See official documentation

+

Reports

+

The SCS Zuul instance can transmit build reports through an MQTT connection +to the dedicated Matrix chat room SCS | Zuul Reports. Currently, this MQTT reporting +feature is activated for periodic pipelines (periodic-hourly, periodic-daily, +compliance_check), and reports are dispatched solely in the event of +failures occurring in builds triggered by the mentioned pipelines.

+

See an example pipeline that reports failed result to the SCS | Zuul Reports Matrix room:

+
- pipeline:
name: pipeline-that-reports-to-matrix
description: |
In the event of a failure, this pipeline transmits reports to
the SCS | Zuul Reports Matrix chat room.
failure:
mqtt:
topic: "zuul/{pipeline}/{project}/{branch}/{change}"
+

Visit the official Zuul documentation +and explore the configuration options available for Zuul's reporters.

+

Jobs

+

All jobs that your Zuul instances knows of can be used for your own purposes. +Call them directly or implement a job that uses an existing job as parent. +Didn't find the right job? Than we have to create a new one. Existing jobs +can be found in the web ui of your Zuul instance: Example

+

First have a look on a basic job example:

+
- job:
name: base
parent: null
description: |
The recommended base job.

All jobs ultimately inherit from this. It runs a pre-playbook
which copies all of the job's prepared git repos on to all of
the nodes in the nodeset.

It also sets a default timeout value (which may be overidden).
pre-run: playbooks/base/pre.yaml
post-run:
- playbooks/base/post.yaml
- playbooks/base/post-logs.yaml
roles:
- zuul: zuul/zuul-jobs
timeout: 1800
nodeset:
nodes:
- name: ubuntu-jammy
label: ubuntu-jammy
+

Each job needs a name that has to be unique within the whole tenant. +A useful convention to achieve this is to prepend the name of the repository. +Each job need to define whether there is parent job or not. +Jobs without a parent are called "base" jobs. Usually you don't want to implement base jobs since +there are already some base jobs that implement often used stuff. A description may not be mandatory +but is obviously useful.

+

Necessary for Zuul to do anything you just need to add a run or roles property. Within a job that is +like a noop job or just printing something to stdout that is everything you need to run your first job. +Since anything we want to do requires a little bit more you have to define a nodeset. The nodes +are used to run your playbooks on. In 99,9% you will need this too.

+

The properties pre-run and post-run are useful for bootstrap and cleanup. If your actual job wants to create +bootstrap some infrastructure you can to this in the pre-run. Using an cloud provider you want to release +no longer used resources. That can be done in the post-run. If you are using a parent job it is likely +that the parent job may has pre- and post-run playbooks. In this case your pre- and post-run playbooks are +"nested". Example:

+
    +
  1. pre-run parent
  2. +
  3. pre-run my job
  4. +
  5. post-run my job
  6. +
  7. post-run parent
  8. +
+

If your job exceeds the defined timeout, the job is considered as failed.

+

See official documentation

+

What about secrets?

+

Right now you should be able to run basic tasks. But what if you try to test something +that needs credentials to connect to an outside service? Or you have to address additional +ressources in an openstack environment and you have to use something like app credentials?

+

That is where job secrets are used. Example:

+
- job:
name: SOME_JOB
parent: base
description: |
A job basic job used as example
secrets:
- name: clouds_conf
secret: app_credential_cloud_conf
run: playbooks/my-playbook.yaml
+

Secrets for a job are simply defined by the keyword secrets. +Each secret needs a name that can be used in your playbooks. +The property secret references the secret that is defined within your project.

+

ATTENTION! If your job is using a secret job.post-review is automatically +set to true. For untrusted projects, that means that your job is only called +in piplines that have the pipeline.post-review flag set to true. In SCS context +that means you may run these jobs only with the pipelines tag and post.

+

If you want to run jobs on pipelines that have post-review set to false, which +is default, and your job needs a secret, the secret may be defined in the zuul-config repository.

+

Example:

+
- secret:
name: app_credential_cloud_conf
data:
credentials: my-secret-value
+

Within my-playbook.yaml you can reference the secret value using "{{ clouds_conf.credentials }}". +In this example my-secret-value is clear readable text. That is not something we want to keep +secrets. But how do you encrypt secrets in a way that they are secure and also can be decrypted by +Zuul?

+

For this purpose Zuul creates its own public/private key pair for each project. Everyone may use the +public key to create secrets. But only Zuul will be able to decrypt these values. To avoid the user +to be responsible for the correct encryption there is an zuul-client tool that will do this for you.

+

Example (reading from stdin and writing to stdout):

+
zuul-client --zuul-url ZUUL_URL encrypt --tenant SCS --project SovereignCloudStack/REPO
+

Add --infile INFILE or --outfile OUTFILE if you prefer to work with files directly.

+

The output might look like this:

+
- secret:
name: <name>
data:
<fieldname>: !encrypted/pkcs1-oaep
- IGZ2Wu47R9mEY4fjetbxSAUGNaz4HR1mjk9lCLq3HsUMjHGj9YPlb2MvnPQw1LCJSvpaK
ogth7hi2zYwrs5tNAik/qlVSB7AM+LQRP7lmlM4JmD6WOyR7DisHu7oMD1Gqem2ZuMggA
DIBn5+DeBIvnwihDOcS+BKPTVMEtXOJNkuObZHE8DweB/RQIGUvjyeq5yoAmz/y+qGVqe
0Vk4pTYFIBgk5DMzwVnDzDkqs/QokoOupMUoBcpapmM11do4ymjbDpeINjayoro6VXTtX
Mkk9fDv9wuJIQTuyHAOfMD+UYS/HqVSF/Hm9ScUvfhw02gTdzKCxliWhFHJOj7RbdUUMK
OYYcUkNp5cXZUYFnflMhxVEnzREbdAIklNPfoHOizsxLPaUZ9yk6XcFRflFfMvqBtUS00
LCx0Uh906NwdaEUrv2ZdrN123rwfwfw4333232rDFDFfsdfddsfdDFSFSdqrrtwms5Mi0
szUBaM4j+Mayep+41vl0cpsLU91GzXEATWMaPIN8OnEHF6qQIv0wB6VaKd5aeAyERisb3
wFdjEo4faLO70RWzR33k+4xqAYNIIFyTMpWJz21CUSfoYG8ygL6t7RJGgyjA+0KsVEyj+
ewEtiaUOLYyD7pXtqdw1HgzjqiXnfxk+wSv/y5y/TGGYpQj8zU76jS7Zj0ft/0=
+

You may use this content or the file to provide it as a secret. You just have to update the <name> and the +<fieldname> part.

+

The secret name has to be unique across all projects. Because of this, we have a naming convention in the +SovereignCloudStack organisation that ensures that a secret has a unique name.

+

Our convention is as follows. There is only one secret per Zuul configuration per project (for exceptions, +see below). This secret always has a name in the form +SECRET_REPOSITORY_NAME. For instance, if a secret in the SovereignCloudStack/k8s-cluster-api-provider +repository is +to be used, it is given the name SECRET_K8S_CLUSTER_API_PROVIDER. The name of the repository is +always written in capital letters. A dash is replaced with an underscore. Any number of values +(<fieldname>: !encrypted/pkcs1-oaep) can then be assigned to this one secret.

+

In certain cases, it can be undesireable to expose all secret information to all jobs in a project. +Then additional secrets may be used, whose names have to be formed by appending an underscore and some +upper-case prefix to the name of the primary secret. For instance, we might use the +name SECRET_REPOSITORY_NAME_FOOBAR.

+

Official documentation:

+
    +
  1. Secrets documentation
  2. +
  3. Encryption documentation
  4. +
+

Let's put it all together

+

For a basic but working example the following content may be written into a zuul.yaml file.

+
# zuul.yaml content
---
- secret:
name: SECRET_REPOSITORY_NAME
data:
secretValue1: !encrypted/pkcs1-oaep
- <ENCRYPTED_DATA>
secretValue2: !encrypted/pkcs1-oaep
- <ENCRYPTED_DATA>
secretValue3: !encrypted/pkcs1-oaep
- <ENCRYPTED_DATA>

- job:
name: myFirstTestJob
parent: base
secrets:
- name: secretName # The name of the secret that is used within "playbooks/testPlaybook.yaml"
secret: SECRET_REPOSITORY_NAME
run: playbooks/testPlaybook.yaml

- job:
name: mySecondTestJob
parent: base
run: playbooks/testPlaybookTwo.yaml

- project:
tag:
jobs:
- myFirstTestJob
check:
jobs:
- mySecondTestJob
+

This will run the job myFirstTestJob whenever the tag pipeline is triggered, and +mySecondTestJob whenever check is triggered.

+

Within SCS the check pipeline is always triggered if you open, change or reopen a pull request. +This pipeline can also be triggered manually if you write a comment on an already +existing pull request and place the string recheck in it.

+

Recall that the first test job cannot run on the same pipeline because it uses a secret. +The tag pipeline is run whenever a new tag is created.

+

The path to you playbook is always the full path within the repository. The playbook +contains the tasks you actually want to run on all or a specific subset of nodes. +Example playbook:

+
# playbooks/testPlaybook.yaml content
---
- hosts: all
tasks:
- debug:
msg: 'Debug print my secrets! {{ secretName.secretValue1 }}' # do not do this as it will expose your secrets
+ + \ No newline at end of file diff --git a/data/additionalResourcesData.json b/data/additionalResourcesData.json new file mode 100644 index 0000000000..da4c7b85f9 --- /dev/null +++ b/data/additionalResourcesData.json @@ -0,0 +1,26 @@ +[ + { + "title": "Get in touch", + "body": "Come into our Matrix Chat in the SCS | Tech Room.", + "url": "https://matrix.to/#/#scs-tech:matrix.org", + "buttonText": "Join Now" + }, + { + "title": "Come to our Meet-Ups", + "body": "Our working groups and special interest groups meet weekly or biweekly. When? Find out within our public community calendar.", + "url": "/community/collaboration", + "buttonText": "Learn More" + }, + { + "title": "Standardization in progress", + "body": "Get to know our current Decision Records and Standards.", + "url": "/standards", + "buttonText": "Start Now" + }, + { + "title": "Deployment Examples", + "body": "Get to know different ways to deploy SCS with cloud resources or on bare metal.", + "url": "/docs/iaas/guides/deploy-guide/examples", + "buttonText": "Explore Cases" + } +] diff --git a/data/architecturalOverviewData.json b/data/architecturalOverviewData.json new file mode 100644 index 0000000000..2fcbc8d9a0 --- /dev/null +++ b/data/architecturalOverviewData.json @@ -0,0 +1,102 @@ +{ + "ops": [ + { + "title": "Ops Layer", + "body": "Tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.", + "url": "/docs/category/operating-scs", + "buttonText": "Learn More", + "components": [ + { + "title": "Status Page", + "url": "/docs/operating-scs/components/status-page/docs/overview", + "mandatory": "true", + "stable": "true" + }, + { + "title": "Monitoring", + "url": "/docs/category/monitoring", + "mandatory": "false", + "stable": "true" + }, + { + "title": "Central API", + "url": "/docs/operating-scs/components/central-api/overview", + "mandatory": "true", + "stable": "true" + }, + { + "title": "Automated Pentesting", + "url": "/docs/operating-scs/components/automated-pentesting/overview", + "mandatory": "true", + "stable": "true" + } + ] + } + ], + "container": [ + { + "title": "Container Layer", + "body": "SCS offers a robust solution for managing container workloads on a Kubernetes infrastructure.", + "url": "/docs/container", + "buttonText": "Learn More", + "components": [ + { + "title": "KaaS V1: K8s Cluster API Provider", + "url": "/docs/category/k8s-cluster-api-provider", + "mandatory": "false", + "stable": "true" + }, + { + "title": "KaaS V2: Cluster Stacks", + "url": "/docs/category/cluster-stacks", + "mandatory": "false", + "stable": "true" + }, + { + "title": "Container Registry", + "url": "/docs/category/container-registry", + "mandatory": "false", + "stable": "true" + } + ] + } + ], + "iaas": [ + { + "title": "IaaS Layer", + "body": "SCS offers OpenStack infrastructure solutions based on KVM virtualization to deploy VM workloads and enabling the container layer optionally.", + "url": "/docs/category/iaas-layer", + "buttonText": "Learn More", + "components": [ + { + "title": "Image Manager", + "url": "/docs/iaas/components/image-manager", + "mandatory": "true", + "stable": "true" + }, + { + "title": "Flavor Manager", + "url": "/docs/iaas/components/flavor-manager", + "mandatory": "true", + "stable": "true" + } + ] + } + ], + "iam": [ + { + "title": "IAM Layer", + "body": "Working on Keycloak federated identity provider within our Team IAM.", + "url": "/docs/iam", + "buttonText": "Learn More", + "components": [ + { + "title": "Keycloak", + "url": "/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations", + "mandatory": "false", + "stable": "true" + } + ] + } + ] +} diff --git a/data/featureContentData.json b/data/featureContentData.json new file mode 100644 index 0000000000..8c309c0612 --- /dev/null +++ b/data/featureContentData.json @@ -0,0 +1,26 @@ +[ + { + "title": "Introduction to SCS", + "body": "Get to know SCS better and learn about the background.", + "url": "/docs", + "buttonText": "Get Started" + }, + { + "title": "Releases", + "body": "SCS is currently in Release 6. Check out the latest Release Notes.", + "url": "/docs/releases/Release6", + "buttonText": "Learn More" + }, + { + "title": "Frequently Asked Questions", + "body": "You are curious what SCS is all about, what it can do and what it can't?", + "url": "/docs/faq", + "buttonText": "Get Answers" + }, + { + "title": "Existing Public Clouds", + "body": "There are SCS compliant public clouds in production.", + "url": "/standards/certification/overview#compliant-cloud-environments", + "buttonText": "Test Them" + } +] diff --git a/docs/category/automated-pentesting/index.html b/docs/category/automated-pentesting/index.html new file mode 100644 index 0000000000..2010e166d0 --- /dev/null +++ b/docs/category/automated-pentesting/index.html @@ -0,0 +1,23 @@ + + + + + +Automated Pentesting | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/central-api/index.html b/docs/category/central-api/index.html new file mode 100644 index 0000000000..177b5b8edd --- /dev/null +++ b/docs/category/central-api/index.html @@ -0,0 +1,23 @@ + + + + + +Central API | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/cluster-stacks/index.html b/docs/category/cluster-stacks/index.html new file mode 100644 index 0000000000..ea1c6450b4 --- /dev/null +++ b/docs/category/cluster-stacks/index.html @@ -0,0 +1,23 @@ + + + + + +Cluster Stacks | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/components-1/index.html b/docs/category/components-1/index.html new file mode 100644 index 0000000000..19eea57a30 --- /dev/null +++ b/docs/category/components-1/index.html @@ -0,0 +1,23 @@ + + + + + +Components | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/components-2/index.html b/docs/category/components-2/index.html new file mode 100644 index 0000000000..3b341acc88 --- /dev/null +++ b/docs/category/components-2/index.html @@ -0,0 +1,23 @@ + + + + + +Components | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/components/index.html b/docs/category/components/index.html new file mode 100644 index 0000000000..985fea0e55 --- /dev/null +++ b/docs/category/components/index.html @@ -0,0 +1,23 @@ + + + + + +Components | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/container-registry/index.html b/docs/category/container-registry/index.html new file mode 100644 index 0000000000..27530289b3 --- /dev/null +++ b/docs/category/container-registry/index.html @@ -0,0 +1,23 @@ + + + + + +Container Registry | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/guides-1/index.html b/docs/category/guides-1/index.html new file mode 100644 index 0000000000..40925c9096 --- /dev/null +++ b/docs/category/guides-1/index.html @@ -0,0 +1,23 @@ + + + + + +Guides | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/guides-2/index.html b/docs/category/guides-2/index.html new file mode 100644 index 0000000000..873d02af09 --- /dev/null +++ b/docs/category/guides-2/index.html @@ -0,0 +1,23 @@ + + + + + +Guides | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/iaas-layer/index.html b/docs/category/iaas-layer/index.html new file mode 100644 index 0000000000..5bcc8ad089 --- /dev/null +++ b/docs/category/iaas-layer/index.html @@ -0,0 +1,23 @@ + + + + + +IaaS Layer | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/k8s-cluster-api-provider/index.html b/docs/category/k8s-cluster-api-provider/index.html new file mode 100644 index 0000000000..dd96d753c8 --- /dev/null +++ b/docs/category/k8s-cluster-api-provider/index.html @@ -0,0 +1,23 @@ + + + + + +K8s Cluster API Provider | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/category/metering/index.html b/docs/category/metering/index.html new file mode 100644 index 0000000000..f853f796d0 --- /dev/null +++ b/docs/category/metering/index.html @@ -0,0 +1,23 @@ + + + + + +Metering | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/monitoring/index.html b/docs/category/monitoring/index.html new file mode 100644 index 0000000000..1eeab86dd7 --- /dev/null +++ b/docs/category/monitoring/index.html @@ -0,0 +1,23 @@ + + + + + +Monitoring | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Monitoring

+ + \ No newline at end of file diff --git a/docs/category/operating-scs/index.html b/docs/category/operating-scs/index.html new file mode 100644 index 0000000000..54618c0fd0 --- /dev/null +++ b/docs/category/operating-scs/index.html @@ -0,0 +1,23 @@ + + + + + +Operating SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/releases/index.html b/docs/category/releases/index.html new file mode 100644 index 0000000000..910eb97e2d --- /dev/null +++ b/docs/category/releases/index.html @@ -0,0 +1,23 @@ + + + + + +Releases | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/category/status-page-api/index.html b/docs/category/status-page-api/index.html new file mode 100644 index 0000000000..339ed909c2 --- /dev/null +++ b/docs/category/status-page-api/index.html @@ -0,0 +1,23 @@ + + + + + +Status Page API | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers/index.html new file mode 100644 index 0000000000..37526bbafc --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers/index.html @@ -0,0 +1,41 @@ + + + + + +Controllers | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Controllers

+

OpenStackClusterStackRelease controller

+

The OpenStackClusterStackRelease controller’s main responsibilities are:

+
    +
  • Download release assets into the CSPO container
  • +
  • Create OpenStackNodeImageRelease resources based on the required NodeImages defined in the downloaded release asset node-images.yaml
  • +
  • Set an OwnerReference on the existing OpenStackNodeImageRelease resources that could be utilized by the ClusterStack release (multiple versions of one ClusterStack could share an image)
  • +
  • Update the OpenStackClusterStackRelease status to ready once all related OpenStackNodeImageReleases are also ready
  • +
+

OSCSR controller

+

OpenStackNodeImageRelease controller

+

The OpenStackNodeImageRelease controller’s main responsibilities are:

+
    +
  • Load the OpenStack Cloud configuration from the Secret referenced in spec.IdentityRef
  • +
  • Create an Image as defined by spec.Image if it does not already exist in the specified OpenStack project
  • +
  • Instruct the OpenStack Glance service to import an Image from the provided URL
  • +
  • Set the OpenStackNodeImageRelease status to ready once the image achieves an Active status
  • +
+

OSNIR controller

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop/index.html new file mode 100644 index 0000000000..b90c6a6004 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop/index.html @@ -0,0 +1,81 @@ + + + + + +Developer Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Developer Guide

+

Developing Cluster Stack Provider OpenStack operator is quite straightforward. First, you need to install some basic prerequisites:

+
    +
  • Docker
  • +
  • Go
  • +
+

Next, configure your environment variables. Once that's done, you can initiate development using the local Kind cluster and the Tilt UI to create a workload cluster that comes pre-configured.

+

Setting Tilt up

+
    +
  1. Install Docker and Go. We expect you to run on a Linux OS.
  2. +
  3. Create an .envrc file and specify the values you need. See the .envrc.sample for details.
  4. +
+

Developing with Tilt

+

tilt

+

Operator development requires a lot of iteration, and the “build, tag, push, update deployment” workflow can be very tedious. Tilt makes this process much simpler by watching for updates and automatically building and deploying them. To build a kind cluster and to start Tilt, run:

+
make tilt-up
+
+

To access the Tilt UI please go to: http://localhost:10351

+
+

You should make sure that everything in the UI looks green. If not, you can trigger the Tilt workflow again.

+

Applying ClusterStack

+

When you start your tilt setup then the ClusterStack manifest gets copied from config/cspo directory to root of your repository. In order to apply the ClusterStack to the running local development cluster, you can click on the tilt UI. There should a click on the top-right hand side that is named as apply-clusterstack if you hover over it. +Once the ClusterStack is applied wait for the ClusterStack and ClusterStackRelease object to be ready. In case your ClusterStack shows that it is ready, you can deploy a workload cluster.

+

Creating workload cluster

+

This could be done through the Tilt UI, by pressing the button in the top right corner Create Workload Cluster. This triggers the make create-workload-cluster-openstack, which uses the environment variables and the cluster-template.

+

To interact with your freshly created workload cluster, you can use these commands:

+
make get-kubeconfig-workload-cluster #KUBECONFIG for the workload cluster is placed here: ".workload-cluster-kubeconfig.yaml"
export KUBECONFIG=$PWD/.workload-cluster-kubeconfig.yaml
+

In case you want to change some code, you can do so and see that Tilt triggers on save. It will update the container of the operator automatically.

+

If you want to change something in your ClusterStack or Cluster custom resources, you can have a look at .cluster.yaml and .clusterstack.yaml, which Tilt uses.

+

To delete the ClusterStack you can click on the delete-clusterstack button in the tilt UI.

+

To tear down the workload cluster, click on the Delete Workload Cluster button in the top right corner of the Tilt UI. This action triggers the execution of make delete-workload-cluster-openstack. After a few minutes, the resources should be successfully deleted.

+

To tear down the kind cluster, use:

+
make delete-bootstrap-cluster
+

If you have any trouble finding the right command, then you can use make help to get a list of all available make targets.

+

Toggle between local_mode and remote mode

+

We can retrieve cluster-stacks in two modes. One way is to let the controller fetch it from GitHub which is remote mode and other is we mount the cluster-stacks inside the container at /tmp/downloads/cluster-stacks directory.

+
+

[!NOTE]
+Using remote mode is the default behavior.

+
+

Switching between both modes is relatively simple if you're using Tilt. There is a file at the root of the repo tilt-settings.yaml.example +Make a copy of that file with the name of tilt-settings.yaml

+
cp tilt-settings.yaml.example tilt-settings.yaml
+

Now, open the file and set the local_mode to true to use cluster-stacks in local_mode. It should look the following content wise.

+
local_mode: true
+
+

[!NOTE] +In this mode you need to have cluster-stacks present locally.

+
+

Downloading cluster-stacks can be achieved by many ways but below is a simple way to download it quickly.

+
mkdir -p .release/openstack-scs-1-27-v1/
cd .release/openstack-scs-1-27-v1
gh release download --repo SovereignCloudStack/cluster-stacks openstack-scs-1-27-v1
+

Change the repo and tag as per the requirement. You can also download it directly from browser and move it to .release directory.

+

Please make sure the directory structure remains the same otherwise you'll not be able to start the tilt setup. Here's an example of structuring openstack-scs-1-27-v1 cluster-stack.

+
$ tree .release/openstack-scs-1-27-v1/
.release/openstack-scs-1-27-v1/
├── clusterstack.yaml
├── metadata.yaml
└── openstack-scs-1-27-cluster-class-v1.tgz
+
+

[!IMPORTANT] +There's an alternative way to get clusterstacks using csctl. You can follow the README of csctl for specific instructions and a good quickstart.

+
+

You can use csctl create subcommand to create clusterstack locally. You'll need a csctl.yaml file in the cluster-stack configuration directory. Please read more about creating configuration file for csctl in the csctl docs.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview/index.html new file mode 100644 index 0000000000..c74e2f44d2 --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview/index.html @@ -0,0 +1,26 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Overview

+

The Cluster Stack Provider OpenStack (CSPO) works with the Cluster Stack Operator (CSO) and Cluster Stacks, enabling the creation of Kubernetes clusters in a Cluster-API-native (CAPI) fashion.

+

The primary goal of the CSPO is to facilitate the import of node images in a manner specific to OpenStack. These images are then used to create Kubernetes workload clusters on top of the OpenStack infrastructure.

+

To gain a comprehensive understanding of the entire concept, we recommend familiarizing yourself with the fundamental concepts and architecture outlined in CSO and Cluster Stacks.

+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart/index.html new file mode 100644 index 0000000000..e719ae1e1b --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart/index.html @@ -0,0 +1,25 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting/index.html b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting/index.html new file mode 100644 index 0000000000..d287f4fdde --- /dev/null +++ b/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting/index.html @@ -0,0 +1,29 @@ + + + + + +Troubleshooting | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Troubleshooting

+

This guide explains general info on how to debug issues if a cluster creation fails.

+

providerClient authentication err

+

If you are using https, and when you encounter issues like:

+
kubectl logs -n cspo-system -l control-plane=controller-manager
...
[manager] 2024-04-15T15:20:07Z DEBUG events Post "https://10.0.3.15/identity/v3/auth/tokens": tls: failed to verify certificate: x509: certificate signed by unknown authority {"type": "Warning", "object": {"kind":"OpenStackNodeImageRelease","namespace":"cluster","name":"openstack-ferrol-1-27-ubuntu-capi-image-v1.27.8-v2","uid":"93d2c1c8-5a19-45f8-9f93-8e8bd5227ebf","apiVersion":"infrastructure.clusterstack.x-k8s.io/v1alpha1","resourceVersion":"3773"}, "reason": "OpenStackProviderClientNotSet"}
...
+

you must specify the CA certificate in your secret, which contains the access data to the OpenStack instance, then secret should look similar to this example:

+
apiVersion: v1
data:
cacert: <PEM_ENCODED_CA_CERT>
clouds.yaml: <ENCODED_CLOUDS_YAML>
kind: Secret
metadata:
labels:
clusterctl.cluster.x-k8s.io/move: "true"
name: "openstack"
namespace: cluster
+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/backup_and_restore/index.html b/docs/container/components/container-registry/docs/backup_and_restore/index.html new file mode 100644 index 0000000000..b6486c9f87 --- /dev/null +++ b/docs/container/components/container-registry/docs/backup_and_restore/index.html @@ -0,0 +1,193 @@ + + + + + +Backup and restore | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Backup and restore

+

This page aims at providing a step-by-step guide for backup and restore Harbor +container registry using Velero tool. +It extends the official Harbor backup-restore docs page +with up-to-date commands, explanations, and an extensive prerequisites section. This +guide references and uses Velero in v1.10.2 +as this is the latest stable version at the time of writing this guide.

+

It provides guidance and commands that readers are encouraged to try out by themselves +on Harbor deployment as described in the next sections. It does not aim at providing an +exhaustive list of commands nor all the possible ways how to use them.

+

The guide covers two strategies to save Harbor data:

+
    +
  • Backup: a regular backup created by the restic integration in Velero as described in the related docs
  • +
  • Snapshot: a point-in-time snapshot be the Container Storage Interface (CSI) snapshot support in Velero as described in the related docs
  • +
+

Before you choose the right strategy for your Harbor deployment backup, make sure that you understand +differences between the backup and snapshot. +In general, for long-term protection of Harbor data, you may use backup and for +temporary protection of data (e.g. before Harbor upgrade) you may use snapshot.

+

Note that this guide is not limited to Harbor deployments that utilize SCS environments, +but it is required to have a set of tools and services (e.g. Kubernetes CSI plugin with volume snapshot +support, S3 compatible object store for backups) for successful backup and restore procedure +(see the prerequisites section). These tools and services come out of +the box when the SCS infrastructure and KaaS are used for Harbor deployment, hence it is +convenient to use them.

+

Prerequisites

+

Kubernetes cluster

+

If you want to use snapshot to back up Harbor data ensure the following:

+
    +
  • Your cluster is Kubernetes version 1.20 or greater
  • +
  • Your cluster is running a CSI driver +capable of support volume snapshots at the v1 API level. +To enable creating volume snapshots, the snapshot-controller +and its CRDs should be deployed in the Kubernetes cluster as well. The snapshot-controller +is independent of any CSI Driver. These prerequisites come out of the box with the SCS KaaS solution.
  • +
+

If you want to create Harbor backup ensure the following:

+
    +
  • Your cluster is Kubernetes version 1.16 or greater
  • +
+

If your cluster meets the above, export its kubeconfig path in env. variable KUBECONFIG:

+
export KUBECONFIG=/path/to/kubeconfig
+

S3 bucket and EC2 credentials

+

This guide assumes that the public cloud's object store with S3-compatible API is available as +the storage backend for Velero. In this guide, we are using OpenStack Swift which +offers S3-compatible API. Let's create an S3 bucket on Swift object storage and EC2 credentials +that will be later used by Velero.

+

You should have access to your OpenStack project, and the OpenStack RC file that contains access +values. Set the environment variables by sourcing the OpenStack RC file:

+
source <project>-openrc.sh
+

Swift object store service does not support application credentials authentication +to access S3 API. To authenticate in S3 API, you should generate and use the EC2 credentials +mechanism. +Note that EC2 credentials are associated with a user and are scoped only to a specific project. +EC2 credentials are not protected by limited roles, expiration time, or +access rules, therefore they have the same access as the user who created them. If you +want to restrict EC2 credentials you could use application credentials for their creation, +then EC2 credentials should inherit a (potentially) limited subset of roles that creator +owns (see this for details).

+

You can generate EC2 credentials as follows:

+
$ openstack ec2 credentials create
+------------+----------------------------------------------------------------------------------------------------------+
| Field | Value |
+------------+----------------------------------------------------------------------------------------------------------+
| access | <aws_access_key_id> |
| links | {'self': 'https://api.gx-scs.sovereignit.cloud:5000/v3/users/<user_id>/credentials/OS-EC2/<project_id>'} |
| project_id | <project_id> |
| secret | <aws_secret_access_key> |
| trust_id | None |
| user_id | <user_id> |
+------------+----------------------------------------------------------------------------------------------------------+
+

Write down aws_access_key_id and aws_secret_access_key values from the output of openstack ec2 credentials create +command and store them in the ~/.aws/credentials file as follows:

+
mkdir ~/.aws
cat >~/.aws/credentials <<EOF
[default]
aws_access_key_id = <aws_access_key_id>
aws_secret_access_key = <aws_secret_access_key>
EOF
+

This credential file is then used as an access and secret source for AWS CLI tool and also +as a source for Velero. If your environment does not have AWS CLI installed, install it as follows:

+
pip3 install awscli awscli-plugin-endpoint
+

Finally, create a new bucket. Note that the following command contains endpoint-url +argument that points AWS CLI to the GX-SCS OpenStack Swift object store API.

+
aws --endpoint-url https://api.gx-scs.sovereignit.cloud:8080 s3 mb s3://velero-backup
+

Velero client

+

In this guide, we are using Velero to back up and restore a Harbor instance. +Velero is an open source tool to safely back up and restore, perform disaster recovery, +and migrate Kubernetes cluster resources.

+

Go through the official docs and +install the Velero client on your desired environment. If your environment is Linux distribution +you can use the following steps and install the Velero client from the GitHub release binaries:

+
wget https://github.com/vmware-tanzu/velero/releases/download/v1.10.2/velero-v1.10.2-linux-amd64.tar.gz 
tar -zxvf velero-v1.10.2-linux-amd64.tar.gz
sudo mv velero-v1.10.2-linux-amd64/velero /usr/local/bin/
+

Velero server

+

Install Velero server components along with the appropriate plugins, into the Kubernetes cluster. +This will create a namespace called velero, and place a deployment named velero in it. +Note that the installation command sets the bucket velero-backup that has been created a few steps +earlier as well as EC2 credentials located in ~/.aws/credentials file. Also note that +the region and s3Url parameters are GX-SCS specific. For further details about installation +options, supported storage providers, and more visit the official Velero docs.

+
    +
  • If you want to use snapshot to back up Harbor data: +
      +
    • Install Velero:
    • +
    +
     velero install \
    --features=EnableCSI \
    --provider aws \
    --plugins velero/velero-plugin-for-aws:v1.6.1,velero/velero-plugin-for-csi:v0.4.2 \
    --bucket velero-backup \
    --secret-file ~/.aws/credentials \
    --backup-location-config region=RegionOne,s3ForcePathStyle="true",s3Url=https://api.gx-scs.sovereignit.cloud:8080 \
    --snapshot-location-config region=RegionOne,enableSharedConfig=true
    +
      +
    • In order to allow Velero to do Volume Snapshots, we need to deploy a new VolumeSnapshotClass. Create a velero-snapclass.yaml file as follows:
    • +
    +
    cat > velero-snapclass.yaml << EOF
    apiVersion: snapshot.storage.k8s.io/v1
    deletionPolicy: Delete
    driver: cinder.csi.openstack.org
    kind: VolumeSnapshotClass
    metadata:
    name: csi-cinder-snapclass-in-use-v1-velero
    labels:
    velero.io/csi-volumesnapshot-class: "true"
    parameters:
    force-create: "true"
    EOF
    +
      +
    • Apply the new class:
    • +
    +
    kubectl apply -f velero-snapclass.yaml
    +
  • +
  • If you want to create Harbor backup with Restic: +
      +
    • Install Velero:
    • +
    +
    velero install \
    --provider aws \
    --plugins velero/velero-plugin-for-aws:v1.6.1 \
    --bucket velero-backup \
    --secret-file ~/.aws/credentials \
    --use-volume-snapshots=false \
    --uploader-type=restic \
    --use-node-agent \
    --backup-location-config region=RegionOne,s3ForcePathStyle="true",s3Url=https://api.gx-scs.sovereignit.cloud:8080
    +
  • +
+

Backup and restore

+

Note that the following backup steps mainly point to actions from an official Backup And Restore Harbor With Velero tutorial. +In this guide, find the added value from additional explanations/hints and up-to-date commands.

+

Harbor, by design, consists of multiple (micro)services that could store their data +variously, based on the Harbor configuration. See the Harbor persistence +docs for further information regarding the Harbor persistence layer. The following steps cover +cases when Harbor persistence is enabled and the "internal" databases (PostgreSQL and Redis) +are used.

+

Note that Redis key-value database is not backed up in both cases, i.e. when "internal" +or "external" Redis instance is used. As a result, the user sessions of logged users +that are stored in Redis will be lost. Hence, after the restore, users should log in +again. This data loss should be a low impact on your restored Harbor instance.

+

PostgreSQL database should be backed up as it stores important metadata of Harbor models, +like projects, users, roles, etc. The backup and restore of "internal" PostgreSQL instance +is covered by this guide. The "external" PostgreSQL backup is not supported by the +official tutorial and is out of the scope of this guide as well.

+

Also, keep an eye on the official backup and restore limitations +section to be aware of the potential impact on your Harbor instance. The limitation: +The upload purging process may cause backup failure mentioned that it is better to +increase registry upload purging interval (it is a background process that periodically +removes orphaned files from the upload directories of the registry, see the docs). +This interval is by default +set to 24h (helm value: registry.upload_purging.interval). If you do not want to change +the registry configuration at all you should ensure that the backup will be performed in +the middle of two rounds of purging. This background process starts when the registry +container is initialized, therefore is a good idea to check logs of the registry container +and determine when is a good time to do a backup, e.g. as follows:

+
$ kubectl logs -l component=registry -c registry --tail -1 | grep -i purge
time="2023-04-17T09:02:08.320514706Z" level=info msg="Starting upload purge in 24h0m0s" go.version=go1.15.6 instance.id=xxx service=registry version=v2.7.1.m
time="2023-04-17T09:09:08.321004645Z" level=info msg="PurgeUploads starting: olderThan=2023-04-10 09:09:08.320738572 +0000 UTC m=-604379.969424455, actuallyDelete=true"
time="2023-04-17T09:09:08.331433127Z" level=info msg="Purge uploads finished. Num deleted=0, num errors=0"
...
+

Backup Harbor Instance

+
    +
  1. +

    Set Harbor to the ReadOnly mode

    +
  2. +
  3. +

    Backup Harbor:

    +
      +
    • Using snapshot to back up Harbor data: +
        +
      • Exclude the volume of Redis in backup, we need to label the Redis pod, PVC and PV with specific label: +
        # label the Pod of Redis, replace the namespace and Pod name with yours
        kubectl -n default label pod/harbor-harbor-redis-0 velero.io/exclude-from-backup=true
        # label the PVC of Redis, replace the namespace and PVC name with yours
        kubectl -n default label pvc/data-harbor-harbor-redis-0 velero.io/exclude-from-backup=true
        # get the name of Redis PV, replace the namespace and PVC name with yours
        kubectl -n default get pvc data-harbor-harbor-redis-0 --template={{.spec.volumeName}}
        # label the PV of Redis, replace the pv-name with the one get from last command
        kubectl label pv/pv-name velero.io/exclude-from-backup=true
        +
      • +
      • Back up Harbor +
        # replace the namespace and backup name with yours
        velero backup create harbor-backup --include-namespaces default --snapshot-volumes --wait
        +
      • +
      +
    • +
    • Using Restic to back up Harbor data: +
        +
      • Exclude the volume of Redis in backup +
        # replace the namespace and pod name with yours
        kubectl -n default annotate pod/harbor-harbor-redis-0 backup.velero.io/backup-volumes-excludes=data
        +
      • +
      • Back up Harbor +
        velero backup create harbor-backup --include-namespaces default --default-volumes-to-fs-backup --wait
        +
      • +
      +
    • +
    +
  4. +
  5. +

    Unset Harbor from the ReadOnly mode

    +
  6. +
+

Restore Harbor Instance

+

Restore Harbor Instance

+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/ha-deployment/index.html b/docs/container/components/container-registry/docs/ha-deployment/index.html new file mode 100644 index 0000000000..a9deb62aff --- /dev/null +++ b/docs/container/components/container-registry/docs/ha-deployment/index.html @@ -0,0 +1,71 @@ + + + + + +HA deployment | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

HA deployment

+

Prerequisites

+
    +
  • Kubernetes cluster v1.20+ +
      +
    • Use existing cluster +
      export KUBECONFIG=/path/to/kubeconfig
      +
    • +
    • Alternatively, spawn some dev cluster, e.g. using KinD +
      kind create cluster
      +
    • +
    +
  • +
  • Flux CLI + +
  • +
+

Install and wait for operators

+
$ kubectl apply -k operators/
$ flux get helmrelease -n default
NAME REVISION SUSPENDED READY MESSAGE
cert-manager v1.11.0 False True Release reconciliation succeeded
ingress-nginx 4.5.2 False True Release reconciliation succeeded
postgres-operator 1.9.0 False True Release reconciliation succeeded
redis-operator 3.2.7 False True Release reconciliation succeeded
+
+

Note: Install separate operators by e.g.:

+
kubectl apply -k operators/redis/
kubectl apply -k operators/postgres/
+
+

Create redis and postgres clusters

+
envs/public-ha/redis/redis-secret.bash # pwgen needs to be installed
kubectl apply -k envs/public-ha/redis/
kubectl apply -k envs/public-ha/postgres/
+

Install Harbor

+
    +
  • +

    Replace the example.com URL in the harbor-config.yaml file with the desired one.

    +
  • +
  • +

    Take ingress-nginx-controller LoadBalancer IP address and create DNS record for Harbor.

    +
    kubectl get svc -n ingress-nginx
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    ingress-nginx-controller LoadBalancer 100.92.14.168 81.163.194.219 80:30799/TCP,443:32482/TCP 2m51s
    ingress-nginx-controller-admission ClusterIP 100.88.40.231 <none> 443/TCP 2m51s
    +
  • +
  • +

    Generate secrets and install Harbor:

    +
  • +
  • +

    It is recommended to replace admin@example.com email address in issuer.yaml with your own. +Let's Encrypt will use this to contact you about expiring certificates, and issues related to your account.

    +
    base/harbor-secrets.bash # pwgen and htpasswd need to be installed
    envs/public-ha/swift-secret.bash <username> <password>
    kubectl apply -k envs/public-ha/
    +
  • +
+

All in one installation using FluxCD Kustomization and GitRepository reconciliation

+
envs/public-ha/redis/redis-secret.bash
base/harbor-secrets.bash
envs/public-ha/swift-secret.bash <username> <password>
# --branch/tag can be specified, default to master
flux create source git k8s-harbor --url=https://github.com/SovereignCloudStack/k8s-harbor --interval=5m
kubectl apply -f envs/public-ha/public-ha.yaml
+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/migration/index.html b/docs/container/components/container-registry/docs/migration/index.html new file mode 100644 index 0000000000..68beff69a6 --- /dev/null +++ b/docs/container/components/container-registry/docs/migration/index.html @@ -0,0 +1,126 @@ + + + + + +Migration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Migration

+

harbor_migration.png

+

This page aims at providing a step-by-step guide for lift and shift migration of Harbor +container registry, which operates in the Kubernetes environment and is deployed with Helm. +This migration scenario uses Velero tool which +enables moving your Harbor instance as-is from one Kubernetes environment to another +Kubernetes environment. The motivation behind this could be e.g. migration +from one cloud provider to another, an outdated Kubernetes environment of your Harbor +instance or avoiding the Harbor in-place upgrade.

+

Note that the official Harbor's documentation contains an "Upgrade Harbor and Migrate Data" page +that instructs users on how to upgrade and migrate Harbor data from one instance to +another. This tutorial supports only deployments that have been installed by Harbor installer script. +Hence, Harbor instances running in docker containers and spawned by docker-compose.

+

Note that this guide is not limited to Harbor deployments that utilize SCS environments. +Visit the prerequisites section to see what is required for a successful +migration. These prerequisites come out of the box when the SCS infrastructure and KaaS +are used for Harbor deployment, hence it is convenient to use them.

+

Prerequisites

+

As this scenario uses a backup and restore procedure for the migration process, this section +refers to the prerequisites section in Harbor - backup and restore +docs page.

+

Kubernetes clusters

+

This migration scenario expects that you want to migrate your Harbor instance +between different Kubernetes clusters that could live in different environments (e.g. +OpenStack projects) or even in different cloud providers. Let's call them Cluster_A and +Cluster_B. Cluster_A represents the Kubernetes cluster where your Harbor currently operates and +Cluster_B represents the target Kubernetes cluster to which you want to migrate your Harbor.

+

As Cluster_A and Cluster_B do not have to share the same infrastructure it is convenient to +use a full Harbor data backup (not a snapshot) using Restic +integration in Velero. In this case, Cluster_A and Cluster_B should have +Kubernetes version 1.16 or greater. +For further details about Restic-Velero integration refer to the
+related Velero docs.

+

Kubernetes versions of Cluster_A and Cluster_B may differ. In this case, it is +not unusual to see the Kubernetes API group versions differing between clusters. This +incompatibility may cause issues during the migration of your Harbor instance. By default, +Velero only backs up resources that use the preferred version of the Kubernetes API. +However, Velero also includes a feature, Enable API Group Versions, +that overcomes this limitation and backup all Kubernetes API group versions that are +supported on the source Cluster_A. Then, if this feature is also enabled on the Cluster_B, +Velero will make the best choice of Kubernetes API version which is defined in the group +name of both source Cluster_A and target Cluster_B based on API group version priority order, +read docs for further details. +If the above is the case consider installing Velero on both clusters +with a feature flag --features=EnableAPIGroupVersions. Note that this feature is still in beta.

+

S3 bucket and EC2 credentials

+

This guide assumes that the public cloud's object store with S3-compatible API is available as +the storage backend for Velero. Refer to the S3 bucket and EC2 credentials +section in the backup and restore docs and create a bucket that will be later used for +the migration.

+

Velero client

+

Install the Velero client on your local environment, refer to Velero client.

+

Velero server

+

Install Velero server components along with the appropriate plugins, into the both +(Cluster_A and Cluster_B) clusters. Keep in mind that we will use Restic uploader in +Velero, hence follows interactions on how to do that in the related docs section Velero server. +Do not forget to add --kubeconfig argument to install Velero server components +to the Cluster_A and then to the Cluster_B. The rest of arguments should be the same:

+
velero install \
--kubeconfig <path to the kubeconfig file of Cluster_[A,B]> \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.6.1 \
--bucket velero-backup \
--secret-file ~/.aws/credentials \
--use-volume-snapshots=false \
--uploader-type=restic \
--use-node-agent \
--backup-location-config region=RegionOne,s3ForcePathStyle="true",s3Url=https://api.gx-scs.sovereignit.cloud:8080
+

It is a good practice to configure the backup location in the Cluster_B as read-only. +This will make sure that the backup created from Cluster_A is not deleted from the object +store by mistake during the restore to Cluster_B. To do this you can just edit the default +BackupStorageLocation resource in Cluster_B.

+
$ kubectl -n velero --kubeconfig <path of Cluster_B kubeconfig> edit backupstoragelocations default
# Set the `accessMode` to `ReadOnly`
# spec:
# accessMode: ReadOnly
+

Migration

+

Before we start to migrate Harbor instance from one environment to another go through the +Backup and restore section and read +various limitations of the backup/restore process to be aware of the potential impact on +your Harbor instance.

+
    +
  1. Backup Harbor instance in Cluster_A +
      +
    • Set Harbor to the ReadOnly mode
    • +
    • Exclude the volume of Redis in backup in Cluster_A +
      # replace the namespace and pod name with yours
      kubectl -n default --kubeconfig <path of Cluster_A kubeconfig> annotate pod/harbor-harbor-redis-0 backup.velero.io/backup-volumes-excludes=data
      +
    • +
    • Back up Harbor in Cluster_A +
      velero backup create harbor-backup --kubeconfig <path of Cluster_A kubeconfig> --include-namespaces default --default-volumes-to-fs-backup --wait
      +This creates a full backup of all resources in the given namespace including their +persistent storages (besides Redis PV).
    • +
    • Optionally: Unset Harbor from the ReadOnly mode. +Keep in mind that the ReadOnly mode protects your Harbor instance from deleting +repository, artifact, tag, and pushing images. This ensures that the Harbor instance +in Cluster_A will be in sync with the Harbor instance in Cluster_B after you restored +Harbor instance from the backup in Cluster_B. Therefore, it is recommended to not +unset Harbor from the ReadOnly mode in Cluster_A.
    • +
    +
  2. +
  3. Restore Harbor instance in Cluster_B +
      +
    • Restore from the Backup +
      # replace the backup and restore names with yours
      velero restore create harbor-restore --from-backup harbor-backup --kubeconfig <path of Cluster_B kubeconfig> --wait
      +Velero backed up the whole namespace where the Harbor instance lives in Cluster_A, +therefore the restored namespace in Cluster_B may contain resources (e.g. service, +ingress, TLS certificates) that expose Harbor instance in the same way as in +Cluster_A. It is a good practice to test this Cluster_B instance before you allow +users to use it.
    • +
    • Unset Harbor from the ReadOnly mode. +As we set Harbor in Cluster_A to ReadOnly when doing the backup, the instance is +still in ReadOnly mode after restoring. Unset Harbor from the ReadOnly mode after +you check its functionality.
    • +
    +
  4. +
+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/persistence/index.html b/docs/container/components/container-registry/docs/persistence/index.html new file mode 100644 index 0000000000..275dc8ed9d --- /dev/null +++ b/docs/container/components/container-registry/docs/persistence/index.html @@ -0,0 +1,146 @@ + + + + + +Persistence | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Persistence

+

This page briefly describes and provides pointers on how Harbor persists data when it is +deployed in a Kubernetes cluster environment. It points out the default persistence settings +of Harbor helm chart as well as available options.

+

Harbor, by design, consists of multiple (micro)services that could store their data +variously, based on the Harbor configuration, see the Architecture Overview of Harbor.

+

Data Access Layer

+

Redis

+
    +
  • Usage +
      +
    • Key value storage used as a login session cache, a registry manifest cache, and a queue for the jobservice (e.g. see Trivy)
    • +
    +
  • +
  • Default settings +
      +
    • Deployed as an "internal" single node database into the same Kubernetes cluster as Harbor (helm value: redis.type.internal)
    • +
    • Deployed as a StatefulSet with 1 replica
    • +
    • PV persistence is enabled by default (helm value: persistence.enabled.true), Redis POD mounts PV into the /var/lib/redis directory
    • +
    +
  • +
  • Additional settings +
      +
    • Harbor could be pointed to the "external" Redis (or Redis Sentinel) database (helm value: redis.type.external)
    • +
    • "Internal" Redis could be deployed without any persistence, i.e. it could use emptyDir (helm value: persistence.enabled.false)
    • +
    +
  • +
  • Notes + +
  • +
+

Database (PostgreSQL)

+
    +
  • Usage +
      +
    • Stores the related metadata of Harbor models, like projects, users, roles, replication policies, tag retention policies, scanners, charts, and images
    • +
    • Could store JobService logs (helm value: jobservice.jobLoggers.[database])
    • +
    +
  • +
  • Default settings +
      +
    • Deployed as an "internal" single node database into the same Kubernetes cluster as Harbor (helm value: database.type.internal)
    • +
    • Deployed as a StatefulSet with 1 replica
    • +
    • PV persistence is enabled by default (helm value: persistence.enabled.true), PostgreSQL POD mounts PV into the /var/lib/postgresql/data directory
    • +
    +
  • +
  • Additional settings +
      +
    • Harbor could be pointed to the "external" database (PostgreSQL) (helm value: database.type.external)
    • +
    • "Internal" database could be deployed without any persistence, i.e. it could use emptyDir (helm value: persistence.enabled.false)
    • +
    +
  • +
+

OCI Distribution Registry

+
    +
  • Usage +
      +
    • Backend storage of container images and charts
    • +
    +
  • +
  • Default settings +
      +
    • Images and charts are stored in registry POD filesystem directory /storage (helm value: persistence.imageChartStorage.type.filesystem), this directory is mounted to the PV
    • +
    +
  • +
  • Additional settings +
      +
    • Various object storage backends: "azure", "gcs", "s3", "swift", "oss" (helm value: persistence.imageChartStorage.type.<backend>)
    • +
    • Backend storage could beemptyDir (helm value: persistence.enabled.false)
    • +
    +
  • +
+

Fundamental Services

+

Proxy, Core, Web Portal

+
    +
  • These Harbor services are stateless
  • +
+

Trivy

+
    +
  • Usage +
      +
    • A 3rd party vulnerability scanner provided by Aqua Security
    • +
    +
  • +
  • Default settings +
      +
    • Deployed as a StatefulSet with 1 replica
    • +
    • PV persistence is enabled by default (helm value: persistence.enabled.true), Trivy POD mounts PV into the /home/scanner/.cache directory
    • +
    +
  • +
  • Additional settings +
      +
    • Trivy could be deployed without any persistence, i.e. it could use emptyDir (helm value: persistence.enabled.false)
    • +
    +
  • +
  • Notes + +
  • +
+

JobService

+
    +
  • Usage +
      +
    • General job execution queue service to let other components/services submit requests of running asynchronous tasks concurrently
    • +
    +
  • +
  • Default settings +
      +
    • Deployed as a Deployment with 1 replica
    • +
    • Store logs in the POD filesystem directory /var/log/jobs (helm value: jobservice.jobLoggers.[file]), this directory is mounted to the PV
    • +
    +
  • +
  • Additional settings +
      +
    • JobService could be deployed without any persistence, i.e. it could use emptyDir (helm value: persistence.enabled.false)
    • +
    • Logs could be stored in Harbor database (helm value: jobservice.jobLoggers.[database]) or just printed to the STDOUT (helm value: jobservice.jobLoggers.[stdout])
    • +
    +
  • +
+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/quickstart/index.html b/docs/container/components/container-registry/docs/quickstart/index.html new file mode 100644 index 0000000000..541c0113e4 --- /dev/null +++ b/docs/container/components/container-registry/docs/quickstart/index.html @@ -0,0 +1,55 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Quickstart

+

This guide shows you how to set up a working Harbor Container Registry that utilizes a Kubernetes cluster.

+

Prerequisites

+
    +
  • Kubernetes cluster v1.20+ +
      +
    • Use existing cluster +
      export KUBECONFIG=/path/to/kubeconfig
      +
    • +
    • Alternatively, spawn some dev cluster, e.g. using KinD +
      kind create cluster
      +
    • +
    +
  • +
  • Flux CLI + +
  • +
+

Install Harbor container registry

+

Apply kustomization manifest in envs/dev directory:

+
kubectl apply -k envs/dev/
+

Port-forward the Harbor container registry service:

+
kubectl port-forward svc/harbor 8080:80
+

Access the Harbor container registry UI and use Harbor's default credentials

+
    +
  • username: admin
  • +
  • password: Harbor12345
  • +
+
http://localhost:8080
+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/rate_limit/index.html b/docs/container/components/container-registry/docs/rate_limit/index.html new file mode 100644 index 0000000000..0789ccbb25 --- /dev/null +++ b/docs/container/components/container-registry/docs/rate_limit/index.html @@ -0,0 +1,42 @@ + + + + + +Rate limit | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Rate limit

+

This page describes how the rate limiting can be set up for the Harbor container registry.

+

Harbor itself doesn't support rate limit protection yet, see open issue. +Therefore, we can take advantage of the ingress controller in front of the Harbor. In our case Nginx.

+

In the ingress-nginx controller, the rate-limiting options can be specified via annotations. +E.g. nginx.ingress.kubernetes.io/limit-rps: "1" means that ingress will allow only 1 request from a given IP per second. +Client IP is set based on the use of PROXY protocol or from the X-Forwarded-For header value. +In the SCS reference implementation, proxy protocol for ingress nginx is enabled by default. +This rate-limit annotation is ideal for DDoS attacks mitigation. When clients exceed this limit +503 status code is returned. This status code can be changed via nginx ingress controller configmap:

+
$ kubectl edit cm -n ingress-nginx ingress-nginx-controller
# data:
# limit-req-status-code: "429"
+

There are other useful annotations, such as limit concurrent connections, number of kilobytes per second or limit burst requests. +E.g. bursts can be configured via nginx.ingress.kubernetes.io/limit-burst-multiplier, which is by default 5. +It means that burst +will be set in this case to limit-rps * limit-burst-multiplier = 1 * 5 = 5.

+

More information about nginx rate-limiting and real-world examples can be seen in this nginx blog. +Also, there is a second option for how the rate limiting can be configured called global rate limiting. +Detailed research and comparison are done in this issue. +Furthermore, see this PR, +which adds a rate limit for the public(registry.scs.community) environment.

+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/scs-deployment/index.html b/docs/container/components/container-registry/docs/scs-deployment/index.html new file mode 100644 index 0000000000..52956dcaf1 --- /dev/null +++ b/docs/container/components/container-registry/docs/scs-deployment/index.html @@ -0,0 +1,54 @@ + + + + + +SCS deployment | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS deployment

+

The following steps were utilized for deploying the SCS reference installation of the Harbor container registry, +which is available at https://registry.scs.community.

+

Prerequisites

+
    +
  • Kubernetes cluster v1.20+ +
      +
    • We used the R5 version of SCS KaaS V1, which includes an ingress controller and cert manager +
      export KUBECONFIG=/path/to/kubeconfig
      +
    • +
    +
  • +
  • Flux CLI (it is part of SCS KaaS V1) + +
  • +
  • kubectl
  • +
+

Install Harbor

+
    +
  • +

    Take ingress-nginx-controller LoadBalancer IP address and create DNS record for Harbor.

    +
    kubectl get svc -n ingress-nginx
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    ingress-nginx-controller LoadBalancer 100.92.14.168 81.163.194.219 80:30799/TCP,443:32482/TCP 2m51s
    ingress-nginx-controller-admission ClusterIP 100.88.40.231 <none> 443/TCP 2m51s
    +
  • +
  • +

    Generate secrets and install Harbor:

    +
    base/harbor-secrets.bash # pwgen and htpasswd need to be installed
    envs/public/s3-credentials.bash <accesskey> <secretkey>
    kubectl apply -k envs/public/
    +
  • +
+ + \ No newline at end of file diff --git a/docs/container/components/container-registry/docs/upgrade/index.html b/docs/container/components/container-registry/docs/upgrade/index.html new file mode 100644 index 0000000000..c8d44509cb --- /dev/null +++ b/docs/container/components/container-registry/docs/upgrade/index.html @@ -0,0 +1,38 @@ + + + + + +Upgrade | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Upgrade

+

This page aims at providing additional information for upgrading Harbor +container registry, which operates in the Kubernetes environment and is deployed with Helm. +It extends the official Upgrading Harbor Deployed with Helm page, +where the upgrade process is well described. See the following upgrade hints:

+
    +
  • Always backup your Harbor instance before upgrade
  • +
  • Normally Harbor helm upgrade from 2 minor versions lower should be tested, but always +validate your planned upgrade path with recommendations in the official docs.
  • +
  • The step-by-step upgrade is needed because of possible DDL changes in the Harbor database. +Harbor core service executes the migrations scripts automatically. +The helm upgrade process may fail in the case of the failure of migration scripts. +Hence, it is a good idea to run migration scripts with a pre-upgrade job. Harbor Helm +has an option enableMigrateHelmHook which separates the database migration from Harbor core +and runs the migration job as a pre-upgrade hook.
  • +
+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal/index.html b/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal/index.html new file mode 100644 index 0000000000..ea08f11270 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal/index.html @@ -0,0 +1,97 @@ + + + + + +Ingress with externalTrafficPolicy: local | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Ingress with externalTrafficPolicy: local

+

Setting up the nginx ingress controller from the upstream deployment templates +using the externalTrafficPolicy: local setting and -- without any special +treatment -- results in a service that is only partially working: Only requests +that the LoadBalancer happens to route at the node where the nginx container is +running get a response.

+

nginx could just use the cluster setting instead and kube-proxy would forward +the network packets. There are two reasons for nginx not to do that

+
    +
  1. +

    Having a load-balancer balance the traffic to a node that is not active just +to have kube-proxy forward it to the active node does not make much sense. +It creates an unnecessary hop and makes the LoadBalancer pretty useless.

    +
  2. +
  3. +

    Packets forwarded by kube-proxy do not carry the original client IP, so any +source IP dependant handling in nginx (filtering, QoS, ...) will not be +possible.

    +
  4. +
+

Getting it to work for managed ingress

+

There does not seem to be a standard mechanism where k8s tells the LoadBalancer (LB) +which backend members are active, but the load-balancer can find this out by using +a health-monitor that probes for the availability of the service and then takes +the inactive nodes out of the rotation. Should the container be rescheduled on +some other node, the health-monitor will adapt within a few seconds.

+

Since SCS R2, the deployed nginx-ingress deployment is patched to carry a service +annotation (a behavior specifically needed by OpenStack) that enables the health-monitor for the LB in +front of the ingress. This results in traffic to flow.

+

This covers the nginx ingress controller that is deployed by setting +DEPLOY_NGINX_INGRESS: true with the create_cluster.sh or apply_nginx_ingress.sh. +That the ingress we call the "managed ingress".

+

For the ingress service to see the client IPs, more is needed. The Octavia LB +as well as the nginx service both support the proxy protocol, which can be used to +communicate the real client IP. We had plumbing included which we disabled by +default prior to releasing R2, because it broke the access to ingress from +software that runs inside the cluster.

+

A workaround for this has been implemented, so the default is +NGINX_USE_PROXY: true as of R4. So the managed nginx ingress service +does work reliably and gets the client IPs.

+

Getting it to work in general

+

Users that deploy their own nginx or other services with externalTrafficPolicy: local +won't be helped by the annotations done by the SCS cluster management. They will +have to do similar custom patching or revert to a cluster policy and forego the +visibility on real client IPs.

+

A generic solution to this would be a different kind of LB that does work at the +networking layer 3 (routing), so the (TCP) connections are not terminated at the +LB and then data being forwarded on a new connection to the backend member, but +the routing would create a direct connection. Google (with Direct Server Return, DSR) +and Azure support such LB modes.

+

As it turns out, on OpenStack clouds that use OVN as networking (SDN) layer, the OVN +loadbalancer does almost deliver what's needed.

+

OVN provider LoadBalancer

+

The OVN provider for the load-balancer does create direct flows to the chosen backend +member, so no proxy protocol (or similar hacks) are needed to make the backend service +see the client IPs. This has been validated (and can even be monitored by openstack-health-monitor) +on SCS clouds that use OVN.

+

A health-monitor is still needed to ensure that only active members receive requests. +Health monitors for the ovn provider are only supported on OpenStack Wallaby and later. +See also occm docs.

+

OVN LoadBalancer can be enabled by setting use_ovn_lb_provider = "true" or use_ovn_lb_provider = "auto".

+

Note that the use_ovn_lb_provider does not affect the LB in front of the kube API. +That one is created by capo and requires other settings. Also note that it would +not yet support the CIDR filtering +with restrict_kubeapi setting.

+

Disabled health-monitor by default

+

We could enable a health-monitor by default for load-balancers created from OCCM +in the k8s clusters. This would make services with externalTrafficPolicy: local +work, as the traffic would be routed exclusively to active members. But the +other goal would not be achieved: Getting the real client IPs. +We decided against turning on the health-monitor by default, as this might result +in the wrong impression that local fully works. Rather break and then have users take +a decision to go for cluster, to enable health-monitoring to get it half-working +or to do health-monitoring plus some extra plumbing for proxy protocol (or similar) +to get all aspects working.

+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting/index.html b/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting/index.html new file mode 100644 index 0000000000..8ae672c789 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting/index.html @@ -0,0 +1,156 @@ + + + + + +Maintenance and Troubleshooting Guide for SCS k8s-cluster-api-provider | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Maintenance and Troubleshooting Guide for SCS k8s-cluster-api-provider

+

Client Certificates in Kubernetes expire after one year

+

What does a provider need to do in order to NOT run into a certificate issue?

+
    +
  1. +

    Update the cluster at least once a year to rotate certificates automatically

    +
      +
    • Automatic certificate renewal for cluster upgrades
    • +
    • +
      +

      kubeadm renews all the certificates during control plane +upgrade. +This feature is designed for addressing the simplest use cases; if you don't have specific +requirements on certificate renewal and perform Kubernetes version upgrades regularly +(less than 1 year in between each upgrade), kubeadm will take care of keeping your +cluster up to date and reasonably secure.

      +
      +
    • +
    +
  2. +
  3. +

    Renew all certificates with kubeadm certs renew all

    + +
  4. +
+

Certificate Authority expires

+

Another problem is that the CA might expire as well (normally after 10 years)

+
    +
  • kubeadm does not have any tooling for this at the time of writing
  • +
  • There is documentation for +Manual Rotation of CA Certifcates
  • +
  • On the management node, there is a signer.sh that can be used to sign server certificates +after checking that they belong to the server.
  • +
+

Failed cluster deployment debugging

+

NOTE: The following kubectl and clusterctl commands should be executed against +the management Kubernetes cluster API. Keep in mind that these tools and the +kubeconfig to access the management Kubernetes cluster are available in the management +host, hence it is convenient to execute the following commands from the management host.

+

Ask Kubernetes what went wrong:

+
kubectl describe cluster <CLUSTER_NAME>
+

The status and the events may give you a clue what happened. The healthy cluster should +be in the phase: Provisioned

+
$ kubectl describe cluster <CLUSTER_NAME> | yq .Status.Phase
Provisioned
+

You can also have a look at the openstackcluster object and see OpenStack related +statuses and events. The healthy cluster should be ready:

+
$ kubectl describe openstackcluster <CLUSTER_NAME> | yq .Status.Ready
true
+

Note that you can instead execute kubectl get cluster <CLUSTER_NAME> -ojsonpath='{ .status.phase }' +and kubectl get openstackcluster <CLUSTER_NAME> -ojsonpath='{ .status.ready }' +if you don't have yq at hand.

+

A handy command for cluster health investigation is clusterctl describe cluster <CLUSTER_NAME>. +This prints infrastructure/control plane/workers readiness status and other relevant +information like a failure reason. The healthy cluster output is similar to this:

+
$ clusterctl describe cluster <CLUSTER_NAME>
NAME READY SEVERITY REASON SINCE MESSAGE
Cluster/testcluster True 21m
├─ClusterInfrastructure - OpenStackCluster/testcluster
├─ControlPlane - KubeadmControlPlane/testcluster-control-plane True 23m
│ └─3 Machines... True 21m See testcluster-control-plane-5ftjs, testcluster-control-plane-62cdj, ...

└─Workers
└─MachineDeployment/capi-testcluster-md-0-no1 True 22m
└─3 Machines... True 21m See capi-testcluster-md-0-no1-84dd86f598-bhxfd, capi-testcluster-md-0-no1-84dd86f598-f6pnl, ...
+

The logs of the capi pod and especially the capo pod are a good source of information. +To find out in which condition the deployment status is, you can use the following way:

+
kubectl logs -n capo-system -l control-plane=capo-controller-manager -c manager
+

Successful cluster creation will log Reconciled Machine create successfully for +successfully created nodes.

+
kubectl logs -n capi-system -l control-plane=controller-manager -c manager
+

In some cases could be a good idea to go through the official [capi] +(https://cluster-api.sigs.k8s.io/user/troubleshooting.html) and capo +troubleshooting guides or check whether you hit some known bug already reported in +capi +or capo projects.

+

You can also check the OpenStack layer. A cluster deployment should result in a +router,a network, a subnet, a loadbalancer (in front of kubeapi) and a number of servers (VMs) +for the control-plane and worker nodes. Have you run out of quota?

+

Cluster state

+

Have a look at the pods that run: +kubectl --context=<CLUSTER_NAME>-admin@<CLUSTER_NAME> get pods -A

+

or have a look at the nodes: +kubectl --context=<CLUSTER_NAME>-admin@<CLUSTER_NAME> get nodes -o wide

+

If you fall into some Kubernetes specific issues after a successful cluster +creation, go through the official Kubernetes +troubleshooting guide.

+

Etcd maintenance

+

Etcd is a highly-available key value store used as Kubernetes' +backing store for all cluster data. This section contains etcd related maintenance +notes from SCS k8s-cluster-api-provider project perspective.

+

For further information about etcd maintenance visit an official etcd maintenance guide +and/or Kubernetes etcd operating guide.

+

Defragmentation and backup

+

Etcd storage can become fragmented over time, for this, we have included a +maintenance script that regularly defragments and then also backups the database. +The script, called etcd-defrag.sh is located in each control plane node's /root +directory . It is executed through the systemd service unit file etcd-defrag.service +and scheduled to run each day at 02:30:00 using the etcd-defrag.timer systemd timer.

+

The defragmentation strategy is inspired by the etcd-defrag-cronjob and +practices recommended by the OpenShift project. +Note that the proposed strategy could be changed in a future version based on results from +related upstream issue #15477 which wants to define +an official solution on how to defragment etcd cluster.

+

The etcd-defrag.sh script checks multiple conditions before the actual defragmentation as +follows:

+
    +
  • The script should not be executed on non leader etcd member
  • +
  • The script should not be executed on etcd cluster with some unhealthy member
  • +
  • The script should not be executed on single member etcd cluster
  • +
+

These pre-flight checks should ensure, that the defragmentation does not cause temporary +etcd cluster failures and/or unwanted etcd leader changes. They also prevent executing +the script on a single control-plane node cluster. Single-node etcd clusters are not +made for long-term operation. As a workaround, however, you can scale up to three +control-plane nodes overnight from time to time.

+

After all pre-flight checks passed the etcd cluster defragmentation is performed as follows:

+
    +
  • Defragment the non leader etcd members first
  • +
  • Change the leadership to the randomly selected and defragmentation completed etcd member
  • +
  • Defragment the local (ex-leader) etcd member
  • +
+

At the end of the defragmentation script, the local (ex-leader) etcd member is backed up +and trimmed. Backup is saved and then compressed in the control plane /root directory. +You can find it here: /root/etcd-backup.xz. File system trim is performed by the fstrim +command that discards unused blocks on a filesystem which could increase write performance +on the long run and also release unused storage. Cluster admins are not supposed to log +in to the cluster nodes (neither control plane nor workers) and thus won't access or use +these backup files. The local backups on these nodes however can prove useful however +in a disaster recovery scenario.

+

All mentioned pre-flight checks could be skipped by the optional arguments that force +defragmentation despite potential failures. Optional arguments are:

+
    +
  • --force-single (allows to execute defragmentation on single member etcd cluster)
  • +
  • --force-unhealthy (allows to execute defragmentation on unhealthy etcd member)
  • +
  • --force-nonleader (allows to execute defragmentation on non leader etcd member)
  • +
+

We do not recommend to log in to the cluster nodes let alone executing manual +defragmentation using the optional arguments above. If you are aware of potential +issues, you can access the control plane node and execute the defragmentation script +manually as follows:

+
/root/etcd-defrag.sh [--force-single] [--force-unhealthy] [--force-nonleader]
+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide/index.html b/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide/index.html new file mode 100644 index 0000000000..5260e72fdc --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide/index.html @@ -0,0 +1,384 @@ + + + + + +SCS k8s-cluster-api-provider upgrade guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS k8s-cluster-api-provider upgrade guide

SCS k8s-cluster-api-provider upgrade guide

+

This document explains the steps to upgrade the SCS Kubernetes cluster-API +based cluster management solution as follows:

+
    +
  • from the R2 (2022-03) to the R3 (2022-09) state
  • +
  • from the R3 (2022-09) to the R4 (2023-03) state
  • +
  • from the R4 (2023-03) to the R5 (2023-09) state
  • +
  • from the R5 (2023-09) to the R6 (2024-03) state
  • +
+

The document explains how the management cluster and the workload clusters can be +upgraded without disruption. It is highly recommended to do a step-by-step upgrade +across major releases i.e. upgrade from R2 to R3 and then to R4 in the case of +upgrade from the R2 to the R4. Upgrades across major releases without step-by-step +process is not recommended and could lead to undocumented issues.

+

The various steps are not very complicated, but there are numerous steps to +take, and it is advisable that cluster operators get some experience with +this kind of cluster management before applying this to customer clusters +that carry important workloads.

+

Note that while the detailed steps are tested and targeted to an R2 -> R3 move, +R3 -> R4 move, R4 -> R5 move or R5 -> R6 move, many of the steps are a generic approach that will apply also for other +upgrades, so expect a lot of similar steps when moving beyond R6.

+

Upgrades from cluster management prior to R2 are difficult; many changes before +R2 assumed that you would redeploy the management cluster. Redeploying the +management cluster can of course always be done, but it's typically disruptive +to your workload clusters, unless you move your cluster management state into +a new management cluster with clusterctl move.

+

Management host (cluster) vs. Workload clusters

+

When you initially deployed the SCS k8s-cluster-api-provider, you created a +VM with a kind cluster inside and a number of +templates, scripts and binaries that are then used to do the cluster management. +This is your management host (or more precisely your single-host management +cluster). Currently, all cluster management including upgrading etc. is done +by connecting to this host via ssh and performing commands there. (You don't +need root privileges to do cluster management there, the normal ubuntu user +rights are sufficient; there are obviously host management tasks such as +installing package updates that do require root power and the user has the +sudo rights to do so.)

+

When you create the management host, you have the option to create your +first workload cluster. This cluster is no different from other workload +clusters that you create by calling commands on the management host, so you +can manage it there. (The default name of this cluster is typically +testcluster, though that can be changed since a while, #264).

+

On the management host, you have the openstack and kubernetes tools +installed and configured, so you can nicely manage all aspects of your +CaaS setups as well as the underlying IaaS. The kubectl configuration +is in ~/.kube/config while you will find the OpenStack configuration +in ~/.config/openstack/clouds.yaml. These files are automatically +managed; you can add entries to the files though, and they should +persist.

+

Updating the management host

+

There are two different possibilities to upgrade the management host.

+
    +
  1. You do a component-wise in-place upgrade of it.
  2. +
  3. You deploy a new management host and clusterctl move the resources +over to it from the old one. (Note: Config state in ~/CLUSTER_NAME/)
  4. +
+

TODO: Advice when to do what, risks, limitations

+

In-place upgrade

+

Operating system

+

You should keep the host up-to-date with respect to normal operating system +upgrades, so perform your normal sudo apt-get update && sudo apt-get upgrade. +kubectl, kustomize, yq, lxd and a few other tools are installed as +snaps, so you may want to upgrade these as well: sudo snap refresh. +From R5 sudo apt-get install -y jq is also required as this is used by the diskless flavors feature, #424. +Default operating system image was changed from Ubuntu 20.04 to Ubuntu 22.04 in R4.

+

k8s-cluster-api-provider git

+

The automation is deployed on the management host by cloning the relevant +git repository. +into the k8s-cluster-api-provider directory. Note that the checked out +branch will be the one that has been used when creating the management host, +and you might want to change branches from maintained/v3.x to maintained/v4.x +in case of R2 to R3 upgrade, maintained/v5.x for R3 to R4 upgrade, maintained/v6.x +for R4 to R5 upgrade or maintained/v7.x for R5 to R6 upgrade. +Use git branch -rl to see available branches in the k8s-cluster-api-provider +repository.

+

You can update the scripts and templates by checking out the relevant branch +main, maintained/v4.x, maintained/v5.x, maintained/v6.x or maintained/v7.x +and using a git pull to ensure the latest content is retrieved. +Once you do that, the cluster-management scripts will be up-to-date. +(The ~/bin directory in your search PATH is symlinked to the check-ed out scripts.)

+

Note however that the binaries and used templates are NOT automatically updated. +This should not normally result in problems -- when new features are introduced +in the management scripts, they ensure to continue to support older templates.

+

Updating cluster-API and openstack cluster-API provider

+

To get the latest version of cluster-API, you can download a new clusterctl +binary from https://github.com/kubernetes-sigs/cluster-api/releases, +make it executable chmod +x clusterctl and install it to /usr/local/bin/, +possibly saving the old binary by renaming it. clusterctl version should now +display the current version number (v1.6.2 at the time of this writing).

+

You can now issue the command clusterctl upgrade plan and clusterctl will +list the components in your (kind) management cluster that can be upgraded. +Here's an example output:

+
ubuntu@capi-old-mgmtcluster:~ [0]$ clusterctl upgrade plan
Checking cert-manager version...
Cert-Manager is already up to date

Checking new release availability...

Latest release available for the v1beta1 API Version of Cluster API (contract):

NAME NAMESPACE TYPE CURRENT VERSION NEXT VERSION
bootstrap-kubeadm capi-kubeadm-bootstrap-system BootstrapProvider v1.5.1 v1.6.2
control-plane-kubeadm capi-kubeadm-control-plane-system ControlPlaneProvider v1.5.1 v1.6.2
cluster-api capi-system CoreProvider v1.5.1 v1.6.2
infrastructure-openstack capo-system InfrastructureProvider v0.7.3 v0.9.0

You can now apply the upgrade by executing the following command:

clusterctl upgrade apply --contract v1beta1
+

You can then upgrade the components:

+
    +
  1. export CLUSTER_TOPOLOGY=true - this is needed from R5 to R6 upgrade due to ClusterClass feature #600
  2. +
  3. Upgrade components +
      +
    • You can do them one-by-one, e.g.: +
      clusterctl upgrade apply --infrastructure capo-system/openstack:v0.9.0 --core capi-system/cluster-api:v1.6.2 -b capi-kubeadm-bootstrap-system/kubeadm:v1.6.2 -c capi-kubeadm-control-plane-system/kubeadm:v1.6.2
      +
    • +
    • Or simply do clusterctl upgrade apply --contract v1beta1
    • +
    +
  4. +
+

New templates

+

The cluster-template.yaml template used for the workload clusters is located in +~/k8s-cluster-api-provider/terraform/files/template/ and copied from there into +~/cluster-defaults/. Then workload clusters are created, they will also have a +copy of it in ~/${CLUSTER_NAME}/. If you have not changed it manually, you can +copy it over the old templates. (Consider backing up the old one though.)

+

The next create_cluster.sh <CLUSTER_NAME> run will then use the new template. +Note that create_cluster.sh is idempotent -- it will not perform any changes +on the cluster unless you have changed its configuration by tweaking +cluster-template.yaml (which you almost never do!) or clusterctl.yaml +(which you do often).

+

The other template file that changed -- however, some opentofu logic is used to +prefill it with values. So you can't copy it from git.

+
R2 to R3
+

For going from R2 to R3, there is just one real change that you want +to apply: Add the variables CONTROL_PLANE_MACHINE_GEN: genc01 and +WORKER_MACHINE_GEN: genw01 to it. If you have copied over the new +cluster-template.yaml as described above, then you're done. Otherwise +you can use the script update-R2-R3.sh <CLUSTER_NAME> +to tweak both clusterctl.yaml and cluster-template.yaml for the +relevant cluster. (You can use cluster-defaults to change the templates +in ~/cluster-defaults/ which get used when creating new clusters.)

+
R3 to R4
+

In the R3 to R4, CALICO_VERSION was moved from .capi-settings to clusterctl.yaml. So +before upgrading workload clusters, you must add it also to the ~/${CLUSTER_NAME}/clusterctl.yaml.

+
echo "CALICO_VERSION: v3.25.0" >> ~/cluster-defaults/clusterctl.yaml
echo "CALICO_VERSION: v3.25.0" >> ~/testcluster/clusterctl.yaml
+

In the R3 to R4 upgrade process, cluster-template.yaml changed etcd defrag process in the +kubeadm control-planes and also security group names by adding ${PREFIX}- to them, so it +has to be changed also in openstack project e.g. (PREFIX=capi):

+
openstack security group set --name capi-allow-ssh allow-ssh
openstack security group set --name capi-allow-icmp allow-icmp
+

We changed immutable fields in the Cluster API templates, so before running +create_cluster.sh to upgrade existing workload cluster the CONTROL_PLANE_MACHINE_GEN +and WORKER_MACHINE_GEN needs to be incremented in cluster specific clusterctl.yaml.

+

In the R3 to R4 process, also cloud.conf added enable-ingress-hostname=true to the +LoadBalancer section. It is due to NGINX_INGRESS_PROXY defaulting to true now. So if +you want to use, or you are already using this proxy functionality we recommend you to +add this line to your cloud.conf, e.g.:

+
echo "enable-ingress-hostname=true" >> ~/cluster-defaults/cloud.conf
echo "enable-ingress-hostname=true" >> ~/testcluster/cloud.conf
+

Then, before upgrading workload cluster by create_cluster.sh, +you should delete cloud-config secret in the kube-system namespace, so it can be recreated. E.g.: +kubectl delete secret cloud-config -n kube-system --kubeconfig=testcluster/testcluster.yaml

+

Also, the default nginx-ingress version has changed, so we recommend before upgrading cluster +to delete ingress-nginx jobs, so new job with new image can be created in the update process.

+
kubectl delete job ingress-nginx-admission-create -n ingress-nginx --kubeconfig=testcluster/testcluster.yaml
kubectl delete job ingress-nginx-admission-patch -n ingress-nginx --kubeconfig=testcluster/testcluster.yaml
+
R4 to R5
+

In R4 to R5, the cluster-template.yaml and clusterctl.yaml changed (see release notes). +You can use script update-R4-to-R5.sh to update the cluster's cluster-template.yaml and clusterctl.yaml from +R4 to R5. This script could update an existing Kubernetes cluster configuration files +as well as cluster-defaults files that could be used for spawning new R5 clusters.

+

If you want to update an existing cluster configuration files from R4 to R5, just use script as follows:

+
update-R4-to-R5.sh <CLUSTER_NAME>
+

After you executed the above you will find that e.g. Calico version has been bumped from +v3.25.0 to v3.26.1. Note that some software versions are not configurable and are not +directly mentioned in the cluster configuration files, but they are hardcoded +in R5 scripts (e.g. ingress nginx controller, metrics server), see new-defaults section. +Note that the Kubernetes version was not updated as well the default CNI is not the Cilium yet. +This two R5 features are out of scope this script when it is applied on the existing cluster +configuration files as this features require advanced action such as CNI migration +and step-by-step Kubernetes upgrade of +2 minor releases.

+

If you want to update cluster-defaults configuration files from R4 to R5, just use script as follows:

+
update-R4-to-R5.sh cluster-defaults
+

The above action updates a cluster-defaults configuration file, which is almost similar +to updating an existing cluster configuration file described above. The distinction lies +in the fact that both the Kubernetes version and the default CNI are also updated, specifically +to Kubernetes version v1.27.5 and Cilium as a default CNI.

+
R5 to R6
+

In R5 to R6, the cluster-template.yaml and clusterctl.yaml changed (see release notes). +You can use script update-R5-to-R6.sh to update the cluster's cluster-template.yaml and clusterctl.yaml from +R5 to R6. This script could update an existing Kubernetes cluster configuration files +as well as cluster-defaults files that could be used for spawning new R6 clusters.

+

If you want to update an existing cluster configuration files from R5 to R6, just use script as follows:

+
update-R5-to-R6.sh <CLUSTER_NAME>
+

After you executed the above you will find that e.g. Calico version has been bumped from +v3.26.1 to v3.27.2 or Kubernetes version bumped from v1.27.5 to v1.28.7. +Note that some software versions are not configurable and are not directly mentioned +in the cluster configuration files, but they are hardcoded +in R6 scripts (e.g. ingress nginx controller, metrics server, cilium), see new-defaults section.

+

If you want to update cluster-defaults configuration files from R5 to R6, just use script as follows:

+
update-R5-to-R6.sh cluster-defaults
+

If you are curious: In R2, doing rolling upgrades of k8s versions required +edits in cluster-template.yaml -- this is no longer the case in R3, R4, R5 and R6. +Just increase the generation counter for node and control plane nodes if you +upgrade k8s versions -- or otherwise change the worker or control plane +node specs, such as e.g. using a different flavor.

+

New defaults

+

You deploy a CNI (calico or cilium), the OpenStack Cloud Controller +Manager (OCCM), the cinder CSI driver to clusters; optionally also a +metrics server (default is true), a nginx ingress controller (also +defaulting to true), the flux2 controller, the cert-manager. +Some of these tools come with binaries that you can use for management +purposes and which get installed on the management host in /usr/local/bin/.

+

The scripts that deploy these components into your workload clusters +download the manifests into ~/kubernetes-manifests.d/ with a version +specific name. If you request a new version, a new download will happen; +already existing versions will not be re-downloaded.

+

Most binaries in /usr/local/bin/ are not stored under a version-specific +name. You need to rename them to case a re-download of a newer version. +(The reason for not having version specific names is that this would +break scripts from users that assume the unversioned names; the good +news is that most of these binaries have no trouble managing somewhat +older deployments, so you can typically work with the latest binary +tool even if you have a variety of versions deployed into various +clusters.)

+

The defaults have changed as follows:

+
R2R3R4R5R6
kindv0.14.0v0.14.0v0.17.0v0.20.0v0.20.0
capiv1.0.5v1.2.2v1.3.5v1.5.1v1.6.2
capov0.5.3v0.6.3v0.7.1v0.7.3v0.9.0
helmv3.8.1v3.9.4v3.11.1v3.12.3v3.14.1
sonobuoyv0.56.2v0.56.10v0.56.16v0.56.17v0.57.1
k9sunversionedunversionedunversionedv0.27.4v0.31.9
calicov3.22.1v3.24.1v3.25.0v3.26.1v3.27.2
calico CLIv3.22.1v3.24.1v3.25.0v3.26.1v3.27.2
ciliumunversionedunversionedv1.13.0v1.14.1v1.15.1
cilium CLIunversionedunversionedv0.13.1v0.15.7v0.15.23
hubble CLIunversionedunversionedv0.11.2v0.12.0v0.13.0
nginx-ingressv1.1.2v1.3.0v1.6.4v1.8.1v1.9.6
flux2unversionedunversionedv0.40.2v2.1.0v2.2.3
cert-managerv1.7.1v1.9.1v1.11.0v1.12.4v1.14.2
metrics-serverv0.6.1v0.6.1v0.6.1v0.6.4v0.7.0
kubectxv0.9.5
kube-ps1v0.8.0
+

The clusterctl move approach

+

To be written

+
    +
  1. Create new management host in same project -- avoid name conflicts +with different prefix, to be tweaked later. Avoid testcluster creation
  2. +
  3. Ensure it's up and running ...
  4. +
  5. Tweak prefix
  6. +
  7. Copy over configs (and a bit of state though that's uncritical) by using +the directories
  8. +
  9. Copy over the openstack credentials clouds.yaml and the kubectl config
  10. +
  11. clusterctl move
  12. +
+

Updating workload clusters

+

k8s version upgrade

+

On R2 clusters

+

The old way: Editing cluster-template.yaml. Or better use the +update-R2-to-R3.sh script to convert first.

+

On R3 and R4 clusters

+

Edit ~/<CLUSTER_NAME>/clusterctl.yaml and put the wanted version into the +fields KUBERNETES_VERSION and OPENSTACK_IMAGE_NAME. The node image will +be downloaded from https://minio.services.osism.tech/openstack-k8s-capi-images +and registered if needed. (If you have updated the k8s-cluster-api-provider repo, +you can use a version v1.NN.x, where you fill in NN with the wanted k8s version, +but leave a literal .x which will get translated to the newest tested version.)

+

In the same file, increase the generation counters for CONTROL_PLANE_MACHINE_GEN +and WORKER_MACHINE_GEN.

+

Now do the normal create_cluster.sh <CLUSTER_NAME> and watch cluster-api +replace your worker nodes and doing a rolling upgrade of your control plane. +If you used a 3-node (or 5 or higher) control plane node setup, you will have +uninterrupted access not just to your workloads but also the workload's cluster +control plane. Use clusterctl describe cluster <CLUSTER_NAME> or simply +kubectl --context <CLUSTER_NAME>-admin@<CLUSTER_NAME> get nodes -o wide +to watch the progress of this.

+

On R5 clusters

+

If you decide to migrate your existing Kubernetes cluster from R4 to R5 be aware of the following:

+
    +
  • R5 features such as per cluster namespaces and Cilium as a default CNI are supported +only on new clusters and will not be migrated on the existing clusters
  • +
  • R4 default Kubernetes version v1.25.6 can not be directly migrated to the R5 default +Kubernetes version v1.27.5, because +2 minor Kubernetes version upgrade is not allowed. +See further migration steps below if you want to upgrade also Kubernetes version to R5
  • +
+

Follow the below steps if you want to migrate an existing cluster from R4 to R5:

+
    +
  1. Access your management node
  2. +
  3. Checkout R5 branch +
    cd k8s-cluster-api-provider
    git pull
    git checkout maintained/v6.x
    +
  4. +
  5. Backup an existing cluster configuration files (recommended) +
    cd ..
    cp -R <CLUSTER_NAME> <CLUSTER_NAME>-backup
    +
  6. +
  7. Update an existing cluster configuration files from R4 to R5 +
    update-R4-to-R5.sh <CLUSTER_NAME>
    +
  8. +
  9. Validate updated cluster configuration files. You will find that e.g. Calico version +has been bumped from v3.25.0 to v3.26.1. Note that some software versions are not configurable +and are not directly mentioned in the cluster configuration files, but they are hardcoded +in R5 scripts (e.g. ingress nginx controller, metrics server). Hence, read carefully the +R5 release notes too. Also see that Kubernetes version was not updated, and it is still v1.25.6.
  10. +
  11. Update an existing cluster (except Kubernetes version) +
    create_cluster.sh <CLUSTER_NAME>
    +
  12. +
  13. Update cluster-API and openstack cluster-API provider, see related section for details +
    clusterctl upgrade plan
    clusterctl upgrade apply --contract v1beta1
    +
  14. +
  15. Bump Kubernetes version +1 minor release (to v1.26.8) and increase the generation counter for node and control plane nodes +
    sed -i 's/^KUBERNETES_VERSION: v1.25.6/KUBERNETES_VERSION: v1.26.8/' <CLUSTER_NAME>/clusterctl.yaml
    sed -i 's/^OPENSTACK_IMAGE_NAME: ubuntu-capi-image-v1.25.6/OPENSTACK_IMAGE_NAME: ubuntu-capi-image-v1.26.8/' <CLUSTER_NAME>/clusterctl.yaml
    sed -r 's/(^CONTROL_PLANE_MACHINE_GEN: genc)([0-9][0-9])/printf "\1%02d" $((\2+1))/ge' -i <CLUSTER_NAME>/clusterctl.yaml
    sed -r 's/(^WORKER_MACHINE_GEN: genw)([0-9][0-9])/printf "\1%02d" $((\2+1))/ge' -i <CLUSTER_NAME>/clusterctl.yaml
    +
  16. +
  17. Update an existing cluster Kubernetes version to v1.26.8 +
    create_cluster.sh <CLUSTER_NAME>
    +
  18. +
  19. Bump Kubernetes version to R5 v1.27.5 and increase the generation counter for node and control plane nodes
  20. +
+
sed -i 's/^KUBERNETES_VERSION: v1.26.8/KUBERNETES_VERSION: v1.27.5/' <CLUSTER_NAME>/clusterctl.yaml
sed -i 's/^OPENSTACK_IMAGE_NAME: ubuntu-capi-image-v1.26.8/OPENSTACK_IMAGE_NAME: ubuntu-capi-image-v1.27.5/' <CLUSTER_NAME>/clusterctl.yaml
sed -r 's/(^CONTROL_PLANE_MACHINE_GEN: genc)([0-9][0-9])/printf "\1%02d" $((\2+1))/ge' -i <CLUSTER_NAME>/clusterctl.yaml
sed -r 's/(^WORKER_MACHINE_GEN: genw)([0-9][0-9])/printf "\1%02d" $((\2+1))/ge' -i <CLUSTER_NAME>/clusterctl.yaml
+
    +
  1. Update an existing cluster to the R5 Kubernetes version v1.27.5 +
    create_cluster.sh <CLUSTER_NAME>
    +
  2. +
+

On R6 clusters

+

If you decide to migrate your existing Kubernetes cluster from R5 to R6 be aware of the following:

+
    +
  • Kubernetes version will be upgraded from v1.27.5 to v1.28.7
  • +
  • You have to migrate from Cluster based templates to ClusterClass based templates
  • +
  • Upgrade of cilium needs to be done manually (for clusters with USE_CILIUM: true)
  • +
+

Follow the below steps if you want to migrate an existing cluster from R5 to R6:

+
    +
  1. Access your management node
  2. +
  3. Checkout R6 branch +
    cd k8s-cluster-api-provider
    git pull
    git checkout maintained/v7.x
    +
  4. +
  5. Backup an existing cluster configuration files (recommended) +
    cd ..
    cp -R <CLUSTER_NAME> <CLUSTER_NAME>-backup
    +
  6. +
  7. Update an existing cluster configuration files from R5 to R6 +
    update-R5-to-R6.sh <CLUSTER_NAME>
    +
  8. +
  9. Validate updated cluster configuration files. You will find that e.g. Calico version +has been bumped from v3.26.1 to v3.27.2 or Kubernetes version bumped from v1.27.5 to v1.28.7. +Note that some software versions are not configurable and are not directly mentioned in the +cluster configuration files, but they are hardcoded in R6 scripts (e.g. ingress nginx controller, +metrics server, cilium). Hence, read carefully the R6 release notes too.
  10. +
  11. Update cluster-API and openstack cluster-API provider, see related section for details +
    clusterctl upgrade plan
    export CLUSTER_TOPOLOGY=true
    clusterctl upgrade apply --contract v1beta1
    +
  12. +
  13. Migrate to ClusterClass +
    migrate-to-cluster-class.sh <CLUSTER_NAME>
    +
  14. +
  15. Increase the generation counter for worker and control plane nodes +
    sed -r 's/(^CONTROL_PLANE_MACHINE_GEN: genc)([0-9][0-9])/printf "\1%02d" $((\2+1))/ge' -i <CLUSTER_NAME>/clusterctl.yaml
    sed -r 's/(^WORKER_MACHINE_GEN: genw)([0-9][0-9])/printf "\1%02d" $((\2+1))/ge' -i <CLUSTER_NAME>/clusterctl.yaml
    +
  16. +
  17. Update an existing cluster to the R6 +
    create_cluster.sh <CLUSTER_NAME>
    +
    +

    Note: You will probably experience a double rollout of nodes because +the k8s version and templates are changed concurrently here. +See https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/operate-cluster#effects-of-concurrent-changes

    +
    +
  18. +
  19. Upgrade cilium (for clusters with USE_CILIUM: true) +
    KUBECONFIG=<CLUSTER_NAME>/<CLUSTER_NAME>.yaml bash -c 'helm get values cilium -n kube-system -o yaml | cilium upgrade --version v1.15.1 -f -'
    +
  20. +
+

New versions for mandatory components

+

OCCM, CNI (calico/cilium), CSI

+

New versions for optional components

+

nginx, metrics server, cert-manager, flux

+

etcd leader changes

+

While testing clusters with >= 3 control nodes, we have observed occasional transient +error messages that reported an etcd leader change preventing a command from succeeding. +This could result in a dozen of random failed tests in a sonobuoy conformance run. +(Retrying the commands would let them succeed.)

+

Too frequent etcd leader changes are detrimental to your control plane performance and +can lead to transient failures. They are a sign that the infrastructure supporting your +cluster is introducing too high latencies.

+

We recommend to deploy the control nodes (which run etcd) on instances with local SSD +storage (which we reflect in the default flavor name) and recommend using flavors with +dedicated cores and that your network does not introduce latencies by significant packet drop.

+

We now always use slower heartbeat (250ms) and increase CPU and IO priority which used to be +controlled by ETCD_PRIO_BOOST. This is safe.

+

If you build multi-controller clusters and can not use a flavor with low latency local storage +(ideally SSD), you can also work around this with ETCD_UNSAFE_FS. ETCD_UNSAFE_FS is using +barrier=0 mount option, which violates filesystem ordering guarantees. +This works around storage latencies, but introduces the risk of inconsistent +filesystem state and inconsistent etcd data in case of an unclean shutdown. +You may be able to live with this risk in a multi-controller etcd setup. +If you don't have flavors that fulfill the requirements (low-latency +storage attached), your choice is between a single-controller cluster +(without ETCD_UNSAFE_FS) and a multi-controller cluster with +ETCD_UNSAFE_FS. Neither option is perfect, but we deem the +multi-controller cluster preferable in such a scenario.

+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/application-credentials/index.html b/docs/container/components/k8s-cluster-api-provider/doc/application-credentials/index.html new file mode 100644 index 0000000000..a144d39aad --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/application-credentials/index.html @@ -0,0 +1,32 @@ + + + + + +Application Credentials | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Application Credentials

+

OpenTofu creates an application credential that it passes into the created VM. This one is then used to authenticate the cluster API provider against the OpenStack API to allow it to create resources needed for the k8s cluster.

+

The AppCredential has a few advantages:

+
    +
  • We take out variance in how the authentication works -- we don't have to deal with a mixture of project_id, project_name, project_domain_name, user_domain_name, only a subset of which is needed depending on the cloud.
  • +
  • We do not leak the user credentials into the cluster, making any security breach easier to contain.
  • +
  • AppCreds are connected to one project and can be revoked.
  • +
+

We are using an unrestricted AppCred for the management server which can then create further AppCreds, so we can each cluster its own (restricted) credentials. In the case of breaches, these AppCreds can be revoked.

+

Note that you can have additional projects or clouds listed in your ~/.config/openstack/clouds.yaml (and secure.yaml) and reference them in the OPENSTACK_CLOUD setting of your clusterctl.yaml, so you can manage clusters in various projects and clouds from the same management server.

+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/configuration/index.html b/docs/container/components/k8s-cluster-api-provider/doc/configuration/index.html new file mode 100644 index 0000000000..80b2302b0f --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/configuration/index.html @@ -0,0 +1,41 @@ + + + + + +Configuration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Configuration

+

Supported k8s versions

+

As of R6, our tests cover 1.25.latest ... 1.28.latest. +All of them pass the sonobuoy CNCF conformance tests.

+

Overview over the parameters in clusterctl.yaml and environment-XXX.tfvars

+

The provenance capo means that this setting comes from the templates used by +the cluster-api-provider-openstack, while SCS denotes that this setting has +been added by the SCS project.

+

Parameters CAPI management server

+

Parameters controlling the Cluster-API management server (capi management server) creation:

+
environmentclusterctl.yamlprovenancedefaultmeaning
prefixSCScapiPrefix used for OpenStack resources for the capi mgmt node
kind_flavorSCSSCS-2V-4Flavor to be used for the k8s capi mgmt server
imageSCSUbuntu 22.04Image for the capi mgmt server. Use Ubuntu 22.04 or Debian 12. Check also the ssh_username parameter
ssh_usernameSCSubuntuName of the default user for the image
clusterapi_versionSCS1.6.3 Version of the cluster-API incl. clusterctl
capi_openstack_versionSCS0.9.0 Version of the cluster-api-provider-openstack (needs to fit the CAPI version)
cilium_binariesSCSv0.15.23;v0.13.0Versions of the cilium and hubble CLI in the vA.B.C;vX.Y.Z format
restrict_mgmt_serverSCS["0.0.0.0/0"]Allows restricting access to the management server by the given list of CIDRs. Empty value (default) means public.
mgmt_cidrSCS10.0.0.0/24IPv4 address range (CIDR notation) for management cluster
mgmt_ip_rangeSCS{start:"10.0.0.11", end:"10.0.0.254"}IP range from defined mgmt_cidr variable for management cluster. It is recommended to reserve the first 10 IPs.
+

Common parameters management server and clusters

+

Parameters controlling both management server creation and cluster creation:

+
environmentclusterctl.yamlprovenancedefaultmeaning
cloud_providerOPENSTACK_CLOUDcapoOS_CLOUD name in clouds.yaml
external/external_idOPENSTACK_EXTERNAL_NETWORK_IDcapo""Name/ID of the external (public) OpenStack network, default "" uses the detected external network (for clouds with one external network). Required for clouds with more than one external network
dns_nameserversOPENSTACK_DNS_NAMESERVERScapo[ "5.1.66.255", "185.150.99.255" ]Array of nameservers for capi mgmt server and for cluster nodes, replace the FF MUC defaults with local servers if available
availability_zoneOPENSTACK_FAILURE_DOMAINcapoAvailability Zone(s) for the mgmt node / workload clusters
kind_mtuMTU_VALUESCS0MTU for the mgmt server; Calico is set 50 bytes smaller; 0 means autodetection
http_proxySCSGlobal setting for HTTP Proxy is set on the management host including all cluster-api components running in the bootstrap-cluster. Specify with protocol: e.g http://10.10.10.10:3128
no_proxySCSGlobal setting for HTTP Proxy exception list. If http_proxy is not set this setting has no effect. If http_proxy is set, the default value for the NO_PROXY environment variable on all affected components is set to .svc,.svc.cluster,.svc.cluster.local,127.0.0.0/8,169.254.169.254/32,fd00:ec2::254/128,${var.node_cidr},${var.pod_cidr},${var.service_cidr}. The content of no_proxy is appended to this list. This setting has no effect on apt and snap commands, the way http_proxy is set for apt and snap does not allow the configuration of proxy exceptions.
+

Parameters clusters

+

Parameters controlling the cluster creation:

+
environmentclusterctl.yamlprovenancedefaultmeaning
node_cidrNODE_CIDRSCS10.8.0.0/20IPv4 address range (CIDR notation) for workload nodes
pod_cidrPOD_CIDRSCS192.168.0.0/16IPv4 address range (CIDR notation) for pods
service_cidrSERVICE_CIDRSCS10.96.0.0/12IPv4 address range (CIDR notation) for services
use_ciliumUSE_CILIUMSCStrueUse cilium as CNI instead of calico, it can be set to vX.Y.Z and true results in v1.15.1, also see cilium_binaries
calico_versionCALICO_VERSIONSCSv3.27.3 Version of the Calico CNI provider (ignored if use_cilium is set)
kubernetes_versionKUBERNETES_VERSIONcapov1.28.xKubernetes version deployed into workload cluster (.x means latest patch release)
``OPENSTACK_IMAGE_NAMEcapoubuntu-capi-image-${KUBERNETES_VERION}Image name for k8s controller and worker nodes. Ubuntu 22.04 image is used for k8s versions >= 1.27.3, 1.26.6, 1.25.11, Ubuntu 20.04 otherwise.
kube_image_rawOPENSTACK_IMAGE_RAWSCStrueRegister images in raw format (instead of qcow2), good for ceph COW
image_registration_extra_flagsOPENSTACK_IMAGE_REGISTATION_EXTRA_FLAGSSCS""Extra flags passed during image registration
``OPENSTACK_SSH_KEY_NAMEcapo${prefix}-keypairSSH key name generated and used to connect to workload cluster nodes
controller_flavorOPENSTACK_CONTROL_PLANE_MACHINE_FLAVORcapoSCS-2V-4-20sFlavor to be used for control plane nodes
worker_flavorOPENSTACK_NODE_MACHINE_FLAVORcapoSCS-2V-4-20sFlavor to be used for worker nodes
controller_countCONTROL_PLANE_MACHINE_COUNTcapo1Number of control plane nodes in testcluster (0 skips testcluster creation)
``CONTROL_PLANE_MACHINE_GENSCSgenc01Suffix for control plane node resources, to be changed for rolling upgrades
worker_countWORKER_MACHINE_COUNTcapo3Number of worker nodes in testcluster
``WORKER_MACHINE_GENSCSgenw01Suffix for worker node resources, to be changed for rolling upgrades
``CONTROL_PLANE_ROOT_DISKSIZESCS20If diskless flavors are used for control plane nodes, this is the allocated root volume disk size (in GB)
``WORKER_ROOT_DISKSIZESCS20If diskless flavors are used for worker nodes, this is the allocated root volume disk size (in GB)
anti_affinityOPENSTACK_ANTI_AFFINITYSCStrueUse anti-affinity server groups to prevent k8s nodes on same host (soft for workers, hard for controllers)
``OPENSTACK_SRVGRP_CONTROLLERSCSnononoAutogenerated if anti_affinity is true, eliminated otherwise
``OPENSTACK_SRVGRP_WORKERSCSnononoAutogenerated if anti_affinity is true, eliminated otherwise
deploy_occmDEPLOY_OCCMSCStrueDeploy the given version of OCCM into the cluster. true (default) chooses the latest version matching the k8s version. You can specify master to chose the upstream master branch. Don't disable this.
deploy_cindercsiDEPLOY_CINDERCSISCStrueDeploy the given (or latest matching for the default true value) of cinder CSI.
etcd_unsafe_fsETCD_UNSAFE_FSSCSfalseUse barrier=0 for filesystem on control nodes to avoid storage latency. Use for multi-controller clusters on slow/networked storage, otherwise not recommended.
testcluster_name(cmd line)SCStestclusterAllows setting the default cluster name, created at bootstrap (if controller_count is larger than 0)
restrict_kubeapiRESTRICT_KUBEAPISCS[ ]Allows restricting access to kubernetes API by list of CIDRs. Empty list (default) means public, [ "none" ] means internal access only.
``OPENSTACK_CLUSTER_GENSCSgeno01Generation counter for the OpenStackClusterTemplate resource. Increase, when changing restrict_kubeapi or other OC settings
capo_instance_create_timeoutCLUSTER_API_OPENSTACK_INSTANCE_CREATE_TIMEOUTcapo5Time to wait for an OpenStack machine to be created (in minutes)
containerd_registry_filesSCS{"hosts":["./files/containerd/docker.io"], "certs":[]}Containerd registry hosts config files, see related docs for details.
+

Optional services deployed to cluster:

+
environmentclusterctl.yamlprovenancedefaultscriptmeaning
deploy_metricsDEPLOY_METRICSSCStrueapply_metrics.shDeploy metrics service to nodes to make kubectl top work
deploy_nginx_ingressDEPLOY_NGINX_INGRESSSCStrueapply_nginx_ingress.shDeploy NGINX ingress controller (this spawns an OpenStack Loadbalancer), pass version to explicitly choose the version, true results in v1.9.6 (supported k8s >= 1.25)
``NGINX_INGRESS_PROXYSCStrue(dito)Configure LB and nginx to get real IP via PROXY protocol; trouble for pod to LB connections has been resolved by setting hostname
use_ovn_lb_providerUSE_OVN_LB_PROVIDERSCSfalseapply_nginx_ingress.shClouds using OVN networking can deploy the OVN provider that has low overhead (L3) and makes real client IPs visible without proxy protocol hacks. Set to auto to enable.
deploy_gateway_apiDEPLOY_GATEWAY_APISCSfalsecreate_cluster.shDeploy Gateway APIs CRDs and enable ciliums Gateway API implementation. This only works in conjunction with USE_CILIUM=true. Also this will break at least one CNCF conformance test. This feature is considered a tech-review. Keep in mind that Gateway API itself is under development and not GA. Also note that ciliums implementation of Gateway API is considered "beta".
deploy_cert_managerDEPLOY_CERT_MANAGERSCSfalseapply_cert_manager.shDeploy cert-manager, pass version (e.g. v1.14.2) to explicitly choose a version
deploy_fluxDEPLOY_FLUXSCSfalsecreate_cluster.shDeploy flux2 into the cluster
deploy_harborSCSfalsedeploy_harbor.shDeploy harbor into the cluster. When enabled, it will overwrite the settings above. Harbor forces deployment of flux and based on config, it can force deployment of other dependencies (cert-manager, ingress-nginx and Cinder CSI)
harbor_configSCS{domain_name:"", issuer_email:"", persistence:false, database_size:"1Gi", redis_size:"1Gi", trivy_size:"5Gi"}(dito)Harbor container registry configuration options, see related docs for details.
+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration/index.html b/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration/index.html new file mode 100644 index 0000000000..127e9b7831 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration/index.html @@ -0,0 +1,152 @@ + + + + + +Continuous integration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Continuous integration

+

Project k8s-cluster-api-provider uses SCS Zuul CI platform to +drive its continuous integration tests. The project is registered under the SCS tenant +and therefore is able to use a set of pre-defined pipelines, jobs, and ansible roles that +SCS Zuul instance defines and imports. If you want to explore currently available SCS pipelines, +visit the SCS zuul-config project. +If you want to see the full list of jobs that are available, visit the SCS Zuul UI. +And if you are looking for some handy ansible role that SCS Zuul imports, visit they source.

+

Refer to SCS Zuul users guide and/or +Zuul docs for further details on how to define and use Zuul +CI/CD pipelines and jobs.

+

Note (for geeks): If you are interested in Zuul CI platform and want to deploy your own development instance of it, +then read the official quick-start manual +or visit this tutorial which aims a connection +of Zuul CI platform with a GitHub organization.

+

Configuration

+

SCS Zuul automatically recognizes .zuul.yaml configuration file that is located in the +k8s-cluster-api-provider's root. This file informs Zuul about the project's default-branch and +preferred merge-mode. +It also references SCS Zuul pipelines and +their jobs used by the k8s-cluster-api-provider project. Then, jobs link Ansible playbooks that contain +tasks for actual CI testing.

+

See relevant CI configuration files:

+
├── .zuul.yaml
├── playbooks
│ ├── cleanup.yaml
│ ├── dependencies.yaml
│ ├── e2e.yaml
│ ├── templates
│ │ └── environment.tfvars.j2
+

Pipelines

+

This section describes an SCS Zuul pipelines that are used by the k8s-cluster-api-provider project.

+
    +
  • +

    e2e-test

    +
      +
    • It is triggered by the e2e-test label in the opened PR
    • +
    • It executes k8s-cluster-api-provider-e2e-conformance job
    • +
    • It applies the PR label successful-e2e-test and leaves an informative PR comment when the k8s-cluster-api-provider-e2e-conformance job succeeded
    • +
    • It applies the PR label failed-e2e-test and leaves an informative PR comment when the k8s-cluster-api-provider-e2e-conformance job failed
    • +
    • It applies the PR label cancelled-e2e-test and leaves an informative PR comment when the k8s-cluster-api-provider-e2e-conformance job is canceled
    • +
    +
  • +
  • +

    unlabel-on-update-e2e-test

    +
      +
    • It is triggered by the PR update only when PR contains the successful-e2e-test label
    • +
    • It ensures that any PR update invalidates a previous successful e2e test
    • +
    • It removes successful-e2e-test label from the PR
    • +
    +
  • +
  • +

    e2e-quick-test

    +
      +
    • It is triggered by the e2e-quick-test label in the opened PR
    • +
    • It executes k8s-cluster-api-provider-e2e-quick job
    • +
    • It applies the PR label successful-e2e-quick-test and leaves an informative PR comment when the k8s-cluster-api-provider-e2e-quick job succeeded
    • +
    • It applies the PR label failed-e2e-quick-test and leaves an informative PR comment when the k8s-cluster-api-provider-e2e-quick job failed
    • +
    • It applies the PR label cancelled-e2e-quick-test and leaves an informative PR comment when the k8s-cluster-api-provider-e2e-quick job is canceled
    • +
    +
  • +
  • +

    unlabel-on-update-e2e-quick-test

    +
      +
    • It is triggered by the PR update only when PR contains the successful-e2e-quick-test label
    • +
    • It ensures that any PR update invalidates a previous successful e2e test
    • +
    • It removes successful-e2e-quick-test label from the PR
    • +
    +
  • +
  • +

    periodic-daily

    +
      +
    • This pipeline runs jobs daily at 3AM
    • +
    • It executes k8s-cluster-api-provider-e2e-conformance job
    • +
    • The job overrides the git_reference variable to ensure that the e2e conformance testing is executed on a specific tag
    • +
    +
  • +
+

Jobs

+

This section describes Zuul jobs defined within the k8s-cluster-api-provider project and linked in the above pipelines.

+
    +
  • +

    k8s-cluster-api-provider-e2e-conformance

    +
      +
    • It runs a sonobuoy conformance test against Kubernetes cluster spawned by k8s-cluster-api-provider scripts
    • +
    • This job is a child job of openstack-access-base that ensures OpenStack credentials +availability in Zuul worker node. Parent job also defines a Zuul semaphore semaphore-openstack-access, +that ensures that a maximum of three openstack-access-base jobs (or their children) can run at a time
    • +
    • See a high level k8s-cluster-api-provider-e2e-conformance job steps: +
        +
      • Pre-run playbook dependencies.yaml installs project prerequisites, e.g. opentofu, yq, etc.
      • +
      • Main playbook e2e.yaml spawns a k8s cluster, runs sonobuoy conformance test, and cleans created infrastructure, all by k8s-cluster-api-provider scripts
      • +
      • Cleanup-run playbook cleanup.yaml runs ospurge, cleanup created application credentials and keypair to ensure that multiple e2e runs do not interfere
      • +
      +
    • +
    +
  • +
  • +

    k8s-cluster-api-provider-e2e-quick

    +
      +
    • It runs a sonobuoy quick test against Kubernetes cluster spawned by k8s-cluster-api-provider scripts
    • +
    • This job is a child job of openstack-access-base that ensures OpenStack credentials +availability in Zuul worker node. Parent job also defines a Zuul semaphore semaphore-openstack-access, +that ensures that a maximum of three openstack-access-base jobs (or their children) can run at a time
    • +
    • See a high level k8s-cluster-api-provider-e2e-quick job steps: +
        +
      • Pre-run playbook dependencies.yaml installs project prerequisites, e.g. opentofu, yq, etc.
      • +
      • Main playbook e2e.yaml spawns a k8s cluster, runs sonobuoy quick test, and cleans created infrastructure, all by k8s-cluster-api-provider scripts
      • +
      • Cleanup-run playbook cleanup.yaml runs ospurge, cleanup created application credentials and keypair to ensure that multiple e2e runs do not interfere
      • +
      +
    • +
    +
  • +
+

Secrets

+

The parent job openstack-access-base, from which e2e jobs inherit, defines secret variable openstack-application-credential. +This secret is stored directly in the SCS/zuul-config repository in an encrypted form. +It contains OpenStack application credentials to access the OpenStack project dedicated for CI testing.

+

This secret is encrypted by the SCS/zuul-config repository RSA key that has been generated by SCS Zuul instance. +So only SCS Zuul instance is able to decrypt it (read the docs).

+

If you want to re-generate the mentioned secret or add another one using SCS/zuul-config repository RSA key, follow the below instructions:

+
    +
  • Install zuul-client
  • +
+
pip install zuul-client
+
    +
  • Encrypt "super-secret" string by the SCS/zuul-config repository public key from SCS Zuul
  • +
+
echo -n "super-secret" | \
zuul-client --zuul-url https://zuul.scs.community encrypt \
--tenant SCS \
--project github.com/SovereignCloudStack/zuul-config
+

Job customization

+

In some cases you may want to change your environment.tfvars file before running the e2e test without changing +the environment.tfvars file in the repository. For example, you may want to change the image variable to test a different +system image without altering the default image used by the project.

+

To do so, you can in the body of the PR add the following text:

+
    ```ZUUL_CONFIG
image = "Ubuntu 20.04"
+

### FAQ

#### How do developers/reviewers should proceed if they want to CI test this project?

A developer initiates a PR as usual. If a reviewer deems that the PR requires e2e testing,
they can apply a specific label to the PR.
Currently, the following labels could be applied:

- `e2e-test` (for comprehensive e2e testing, including k8s cluster creation, execution of sonobuoy conformance tests, and cluster deletion)
- `e2e-quick-test` (for expedited e2e testing, involving k8s cluster creation, quick sonobuoy tests, and cluster deletion)

After the e2e test has completed, the reviewer can examine the test results and respond
accordingly, such as approving the PR if everything appears to be in order or requesting changes.
Sonobuoy test results, along with a link to the e2e logs, are conveyed back to the PR via a comment.
Additionally, the PR is labeled appropriately based on the overall e2e test result, using labels like
`successful-e2e-test`, `successful-e2e-quick-test`, `failed-e2e-test`, or `failed-e2e-quick-test`.

#### Why do we use PR `label` as an e2e pipeline trigger instead of e.g. PR `comment`?

We consider PR labels to be a more secure pipeline trigger compared to, for example, PR comments.
PR labels can only be applied by developers with [triage](https://docs.github.com/en/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization#permissions-for-each-role) repository access or higher.
In contrast, PR comments can be added by anyone with a GitHub account.

Members of the SCS GitHub organization are automatically granted 'write' access to SCS repositories.
Consequently, the PR label mechanism ensures that only SCS organization members can trigger e2e pipelines.

#### How do we ensure that any PR update invalidates a previous successful e2e test?

In fact, two mechanisms ensure the invalidation of a previously successful test when a PR is updated.

Firstly, the pipelines `unlabel-on-update-<e2e-test-name>` remove the `successful-<e2e-test-name>` label
from the PR when it's updated after a successful e2e test has finished.
If an e2e test is in progress and the PR is updated, the currently running e2e test is
canceled, the `successful-<e2e-test-name>` label is removed (if it exists), and the
`cancelled-<e2e-test-name>` label is applied along with an informative PR comment to
inform the reviewer about the situation.
+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/make-reference/index.html b/docs/container/components/k8s-cluster-api-provider/doc/make-reference/index.html new file mode 100644 index 0000000000..48b39a082f --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/make-reference/index.html @@ -0,0 +1,154 @@ + + + + + +Makefile reference | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Makefile reference

+

This is a reference to the Makefile targets.

+

Almost all targets require the ENVIRONMENT variable to be set to the name of the environment you want to use. +(See Environments in the requirements documentation for more information.)

+

General commands

+

make create

+

make create

+

To initiate the management server setup, various components are created. This includes the provisioning of networks, +security groups, and a virtual machine. An application credential is also generated for authentication purposes. Once +the virtual machine is up and running, it is bootstrapped by cloning the specified git repository. Additionally, +specific tools are installed to facilitate the process.

+

Next, a local Kubernetes cluster is deployed using kind. The cluster acts as a foundation for further operations. During +the setup, the Cluster API, as well as the Cluster API Provider (e.g. CAPO), are installed within the local cluster. This provider serves as the API server for +Kubernetes CAPI, enabling management and interaction with the cloud backends (e.g. OpenStack).

+

Finally, a test cluster is created utilizing Kubernetes CAPI. This test cluster allows for experimentation, validation, +and development within the CAPI environment.

+
+

Note that make create will not create a testcluster if you have set controller_count to zero in your +environment file (environment-<yourcloud>.tfvars).

+
+
+

Note that make create does not copy local files to the management server, only some files are templated there from the terraform/files/template directory. If you want to change any of the scripts +being copied to the management server, you need to commit, push your changes, and run make create again. +make create will pull the latest changes from the git repository.

+
+

make get-kubeconfig

+

make get-kubeconfig

+

This will get the kubeconfig of the testcluster and store it in the file testcluster.yaml.<yourcloud>.

+

make ssh

+

make ssh

+

This will ssh into the management server, using the username that was set in your environment-<yourcloud>.tfvarsfile. The default in the environment file is ubuntu.

+
+

Note: there is also an alias to this make login

+
+

make openstack

+

make openstack

+

This will run openstack cli.

+

make k9s

+

make k9s

+

This will run k9s on the management server.

+

make log

+

make log CONSOLE=capi-mgmtcluster

+

This will show openstack console log of the management server. You can specify the console log you want to see by +setting the CONSOLE variable. The default is capi-mgmtcluster.

+

make console

+

make console CONSOLE=capi-mgmtcluster

+

This will open openstack console of the management server in the browser using XDG-open. You can specify the console you +want to open by setting the CONSOLE variable. The default is capi-mgmtcluster.

+

make deploy-cso

+

make deploy-cso

+

This will deploy the cluster-stack-operator. The preconfigured repo to look for cluster-stacks is https://github.com/SovereignCloudStack/cluster-stacks/. +GIT_ACCESS_TOKEN can be specified.

+

make deploy-cspo

+

make deploy-cspo

+

This will deploy the cluster-stack-provider-openstack. The preconfigured repo to look for cluster-stacks is https://github.com/SovereignCloudStack/cluster-stacks/. +GIT_ACCESS_TOKEN can be specified.

+

Teardown

+
+

Note that clean and fullclean leave the ubuntu-capi-image-$KUBERNETES_VERSION image registered, +so it can be reused. +You need to manually unregister it, if you want your next deployment to register a new image with +the same kubernetes version number.

+
+

Make clean

+

make clean does ssh to the capi management server to clean up the created clusters prior +to opentofu cleaning up the resources it has created. This is sometimes insufficient to clean up +unfortunately, some error in the deployment may result in resources left around.

+

Make fullclean

+

make fullclean uses a custom script cleanup/cleanup.sh (using the openstack CLI) to clean up +everything while trying to not hit any resources not created by the CAPI or opentofu for +clusters from this management host. +It is the recommended way for doing cleanups if make clean fails. Watch out for leftover +floating IP addresses and persistent volumes, as these can not be easily traced back to the +Cluster API created resources and may thus be left. There is also a make forceclean variant +that hits unused floating IPs and all persistent volumes -- this is risky as there is no good +way to tell which PVCs belong to us unless we find them attached to cluster nodes in which +case we don't need the force options.

+

Make purge

+

You can purge the whole project via make purge. Be careful with that command as it will purge +all resources in the OpenStack project even those that have not been created through this +OpenTofu script or the Cluster API. +It requires the ospurge tool. +Install it with python3 -m pip install git+https://git.openstack.org/openstack/ospurge.

+

Testing commands

+

make check

+

make check SONOMODE=...

+

This will run tests of the configuration on testcluster using sonobuoy. It will also download the results and +print them to the console. Optionally you can also specify a mode by using for example SONOMODE="--mode quick"

+
+

Note: This runs over 5000 tests and takes a long time to complete (~ 2 hours).

+
+

make check-quick

+

make check-quick

+

This will run tests of the configuration on testcluster using sonobuoy with mode quick.

+

make check-conformance

+

make check-conformance

+

This will run tests of the configuration on testcluster using sonobuoy with mode conformance meaning it will test if the +cluster is conformant to the CNCF.

+

make check-storage

+

make check-storage

+

This will run tests of the configuration on testcluster using sonobuoy of the storage.

+

make check-csi

+

make check-csi

+

This will run tests of the configuration on testcluster using sonobuoy of the CSI.

+

OpenTofu commands

+

make init

+

make init

+

This will initialize opentofu. It will download the required providers and modules. +It will also select or create a new workspace for you. The workspace name is the same as the +ENVIROMENT variable.

+

make attach

+

make attach RESOURCE=<resource-id> PARAMS=...

+

This will attach a resource to the opentofu state. This is useful if you have created a resource outside of opentofu +and want to manage it with opentofu.

+

make detach

+

make detach RESOURCE=<resource-id> PARAMS=...

+

This will detach a resource from the opentofu state. This is useful if you have changed a resource outside of opentofu +or you no longer want to manage it with opentofu.

+

make state-push

+

make state-push

+

This will push the opentofu state to specified storage if set. This is useful if you don't want to store the state +locally.

+

make dry-run

+

make dry-run

+

This will run a dry-run of the opentofu apply command. This is useful if you want to see what opentofu will do before +actually doing it.

+

make show

+

make show

+

This will show the opentofu state. This is useful if you want to see what opentofu is managing.

+

make list

+

make list

+

This will list all the resources managed by opentofu. This is useful if you want to see what opentofu is managing.

+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/overview/index.html b/docs/container/components/k8s-cluster-api-provider/doc/overview/index.html new file mode 100644 index 0000000000..9287b0636b --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/overview/index.html @@ -0,0 +1,40 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Overview

+

Creating and scaling k8s clusters on demand is providing a lot of flexibility to DevOps teams that develop, test, deploy and operate services and applications.

+

We expect the functionality to be mainly consumed in two scenarios:

+
    +
  • Self-service: The DevOps team leverages the code provided from this repository to create their own capi management server and use it then to manage a number of k8s clusters for their own needs.
  • +
  • Managed k8s: The Operator's service team creates the capi management server and uses it to provide managed k8s clusters for their clients.
  • +
+

Note that we have an intermediate model in mind -- a model where a one-click / one-API call interface would allow the management server to be created on behalf of a user and then serve as an API endpoint to that user's k8s CAPI needs. Ideally with some dashboard or GUI that would shield less experienced users from all the YAML.

+

Once we as the SCS Community have the gitops style cluster control working, the self-service model will become more convenient to use.

+

The provided solution covers the following two main topics:

+
    +
  1. +

    Automation (opentofu, Makefile) to bootstrap a cluster-API management server by installing kind on a vanilla Ubuntu image and deploying some tools on this node (kubectl, openstack CLI tools, k9s, cilium, calico, helm, flux ...) and deploying cluster-API (clusterctl) and the OpenStack cluster-api provider along with suitable credentials. The opentofu automation is driven by a Makefile for convenience. The tooling also contains all the logic to clean up again. The newly deployed node clones this git repository early in the bootstrap process and uses the thus received files to set up the management cluster and scripts.

    +
  2. +
  3. +

    This node can be connected to via ssh and the deployed scripts there can be used to manage workload clusters and then deploy various standardized tools (such as e.g. OpenStack Cloud Controller Manager(OCCM), cinder CSI, calico or cilium CNI, nginx ingress controller, cert-manager, ...) and run tests (e.g. CNCF conformance with sonobuoy). The tools and artifacts can be updated via git pull at any time and the updated settings rolled out to the workload clusters. Note that the script collection will eventually be superseded by the capi-helm-charts. The medium-term goal is to actually create a reconciliation loop here that would perform life-cycle-management for clusters according to the cluster configuration stored in an enhanced cluster-api style clusterctl.yaml from git repositories and thus allow a pure gitops style cluster management without ever ssh'ing to the management server.

    +
  4. +
+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/quickstart/index.html b/docs/container/components/k8s-cluster-api-provider/doc/quickstart/index.html new file mode 100644 index 0000000000..3b9f8a9867 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/quickstart/index.html @@ -0,0 +1,55 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Quickstart

+

This guide shows you how to get working Kubernetes clusters on a SCS cloud +via cluster-api(CAPI).

+

Requirements

+
    +
  • make
  • +
  • kubectl
  • +
  • opentofu
  • +
  • yq
  • +
  • python3-openstackclient, python3-octaviaclient
  • +
+

Prepare the environment

+

You need access to an OpenStack project. +Copy the default environment and adjust the options according to your cloud.

+
cp terraform/environments/environment-{default,<YOURCLOUD>}.tfvars
+

Edit terraform/environments/environment-<YOURCLOUD>.tfvars with your favourite text editor. Every option without a +default value must be set. +Add +a clouds.yaml +inside the terraform dir, in ~/.config/openstack or /etc/openstack.

+

It is recommended to set the name of the cloud in the clouds.yml to the same value as the cloud_provider in +the environment-<YOURCLOUD>.tfvars, then you only have to specify the ENVIRONMENT or OS_CLOUD variable.

+

Create a test cluster

+
# Set the ENVIRONMENT to the name specified in the name of the file
# `cloud_provider` option has to be set in the environment file
# to the name of the cloud in the clouds.yaml
export ENVIRONMENT=<YOURCLOUD>

# Create your environment. This includes a management node as virtual machine
# in your OpenStack environment as well as a Kubernetes testcluster.
make create

# Get the kubeconfig of the testcluster
make get-kubeconfig

# Interact with the testcluster
kubectl --kubeconfig testcluster.yaml.<YOURCLOUD> get nodes
+

Teardown

+
make clean
+

If make clean fails to clean up completely, you can also use the fullclean target. +Review the Teardown section of the Makefile reference document for more details.

+

Beyond quickstart

+

This guide assumes you just create one test cluster directly when creating the +management server. +In a production setting, you would not use this test cluster but create clusters +via the management server. You can read more about this in the usage guide.

+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/requirements/index.html b/docs/container/components/k8s-cluster-api-provider/doc/requirements/index.html new file mode 100644 index 0000000000..f5ad6da8c0 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/requirements/index.html @@ -0,0 +1,80 @@ + + + + + +Requirements | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Requirements

+

Cluster API requires an existing Kubernetes cluster to operate. In our setup, we +utilize kind a tool for running Kubernetes clusters using Docker containers, to create +the initial management Kubernetes cluster in a single docker container. The OpenStack instance serves as the CAPI +management server or management cluster, responsible for overseeing the +management and operation of the created kubernetes clusters.

+

The provisioning of the CAPI management server is done on a deployment host, possibly a tiny jumphost style VM, or some +Linux/MacOS/WSL laptop.

+

Requirements for the deployment host:

+
    +
  • You need to have installed: +
      +
    • OpenTofu
    • +
    • yq (python3-yq or yq snap)
    • +
    • GNU make
    • +
    • openstack (python3-openstackclient) and plugin for octavia (python3-octaviaclient) Via pip or your distribution. +Needed only in case you want to clean the management server or interact with openstack directly.
    • +
    +
  • +
  • You must have credentials to access the cloud. OpenTofu will look for clouds.yaml and optionally secure.yaml in +the current working directory (terraform), in ~/.config/openstack/ or /etc/openstack (in this order), just like +the openstack client.
  • +
  • The API endpoints of the OpenStack cloud should have a certificate signed by a trusted CA. (Self-signed or custom CAs +need significant manual work -- this will be improved after R4.)
  • +
  • An Environment file for the cloud you want to use. See Environments below for more details.
  • +
+

Environments

+

To use a specific environment, you have to set the ENVIRONMENT variable (export ENVIRONMENT=<yourcloud>) or pass it +to the make command by using make <command> ENVIRONMENT=<yourcloud>. +You can also do the same by utilizing the OS_CLOUD (openstack native) variable. +The name of the environment is derived from the name of the file environments/environment-<yourcloud>.tfvars.

+

The name of the environment specified either via ENVIRONMENT or OS_CLOUD has to be equal the name of the +cloud (cloud_provider) as specified in your clouds.yaml.

+

In case you use plusserver community environment +or wavestack environment you can use the default environment file for +those directly or base your configuration on it. In case you need custom configuration +see Custom environment.

+

More information about the configuration options can be found in the configuration documentation.

+

Plusserver community environment

+

Using it directly: +export ENVIRONMENT=gx-scs

+

or insert inside of Makefile: +ENVIRONMENT=gx-scs

+

File: environments/environment-gx-scs.tfvars

+

The name of the cloud has to be gx-scs in the cloud.yaml file, otherwise you will need +to change the cloud_provider variable inside of terraform/environments/environment-gx-scs.tfvars file.

+

Wavestack environment

+

Using it directly: +export ENVIRONMENT=gx-wavestack

+

or insert inside of Makefile: +ENVIRONMENT=gx-wavestack

+

File: environments/environment-gx-wavestack.tfvars

+

The name of the cloud has to be gx-wavestack in the cloud.yaml file, otherwise you will need +to change the cloud_provider variable inside of terraform/environments/environment-gx-scs.tfvars file.

+

Custom environment

+

You can create your own environment file from the sample file environments/environment-default.tfvars and provide the +necessary information like machine flavor or machine image. You can comment out all lines where the defaults match your +needs.

+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/roadmap/index.html b/docs/container/components/k8s-cluster-api-provider/doc/roadmap/index.html new file mode 100644 index 0000000000..4f43920605 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/roadmap/index.html @@ -0,0 +1,27 @@ + + + + + +Roadmap | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Roadmap

+

Advanced cluster templating with helm (Technical Preview)

+

On the management server, we have not only helm installed, but also the repository https://github.com/stackhpc/capi-helm-charts checked out. Amongst other things, it automates the creation of new machine templates when needed and doing rolling updates on your k8s cluster with clusterctl. This allows for an easy adaptation of your cluster to +different requirements, new k8s versions etc.

+

Please note that this is currently evolving quickly and we have not completely assessed and tested the capabilities. We intend to do this after R2 and eventually recommend this as the standard way of managing clusters in production. At this point, it's included as a technical preview.

+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node/index.html b/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node/index.html new file mode 100644 index 0000000000..b404e6fb15 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node/index.html @@ -0,0 +1,106 @@ + + + + + +Cluster Management on the capi management node | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Cluster Management on the capi management node

+

You can use make ssh to log in to the capi management server. There you can issueclusterctl and kubectl (aliased +to k) commands. The context kind-kind +is used for the CAPI management while the context testcluster-admin@testcluster can +be used to control the workload cluster testcluster. You can of course create many +of them. There are management scripts on the management server:

+
    +
  • In the user's (ubuntu) home directory, create a subdirectory with the CLUSTERNAME +to hold your cluster's configuration data. Copy over the clusterctl.yaml file +from ~/cluster-defaults/ and edit it to meet your needs. Note that you can also +copy over cloud.conf and cluster-template.yaml and adjust them, but you don't +need to. (If you don't create the subdirectory, the create_cluster.sh script +will do so for you and use all defaults settings.)
  • +
  • create_cluster.sh CLUSTERNAME: Use this command to create a cluster with +the settings from ~/$CLUSTERNAME/clusterctl.yaml. More precisely, it uses the template +$CLUSTERNAME/cluster-template.yaml and fills in the settings from +$CLUSTERNAME/clusterctl.yaml to render a config file $CLUSTERNAME/$CLUSTERNAME-config.yaml +which will then be submitted to the capi server (kind-kind context) for creating +the control plane nodes and worker nodes. The script will also apply openstack integration, +cinder CSI, calico or cilium CNI, and optionally also metrics server, nginx ingress controller, +flux, cert-manager. (These can be controlled by DEPLOY_XXX variables, see below. +Defaults can be preconfigured from the environment.tfvars file during management server +creation.) +Note that CLUSTERNAME defaults to testcluster and must not contain +whitespace. +The script also makes sure that appropriate CAPI images are available (it grabs them +from OSISM +as needed and registers them with OpenStack, following the SCS image metadata +standard). +The script returns once the control plane is fully working (the worker +nodes might still be under construction). The kubectl file to talk to this +cluster (as admin) can be found in ~/$CLUSTERNAME/$CLUSTERNAME.yaml. Expect the cluster +creation to take ~8mins. (CLUSTERNAME defaults to testcluster.) You can pass +--context=${CLUSTERNAME}-admin@$CLUSTERNAME to kubectl (with the +default ~/.kubernetes/config config file) or export KUBECONFIG=$CLUSTERNAME.yaml
    +to talk to the workload cluster.
  • +
  • The subdirectory ~/$CLUSTERNAME/deployed-manifests.d/ will contain the +deployed manifests for reference (and in case of nginx-ingress also to facilitate +a full cleanup).
  • +
  • The clusterctl.yaml file can be edited the create_cluster.sh script +be called again to submit the changes. (If you have not done any changes, +re-running the script again is harmless.) Note that the create_cluster.sh +does not currently remove any of the previously deployed services/deployments +from the workload clusters -- this will be added later on with the appropriate +care and warnings. Also note that not all changes are allowed. You can easily +change the number of nodes or add k8s services to a cluster. For changing +machine flavors, machine images, kubernetes versions ... you will need to +also increase the CONTROL_PLANE_MACHINE_GEN or the WORKER_MACHINE_GEN +counter to add a different suffix to these read-only resources. This will +cause Cluster-API to orchestrate a rolling upgrade for you on rollout. +(This is solved more elegantly in the helm chart style cluster management, see below.)
  • +
  • The directory ~/k8s-cluster-api-provider/ contains a checked out git tree +from the SCS project. It can be updated (git pull) to receive the latest +fixes and improvements. This way, most incremental updates do not need the +recreation of the management server (and thus also not the recreation of your +managed workload clusters), but can be applied with calling create_cluster.sh +again to the workload clusters.
  • +
  • The installation of the openstack integration, cinder CSI, metrics server and +nginx ingress controller is done via the bin/apply_*.sh scripts that are called +from create_cluster.sh. You can manually call them as well -- they take +the cluster name as argument. (It's better to just call create_cluster.sh +again, though.) The applied yaml files are collected in +~/$CLUSTERNAME/deployed-manifests.d/. You can kubectl delete -f them +to remove the functionality again.
  • +
  • You can, of course, also delete the cluster and create a new one if that +level of disruption is fine for you. (See below in Advanced cluster templating +with helm to get an idea how we want to make this more convenient in the future.)
  • +
  • Use kubectl get clusters -A in the kind-kind context to see what clusters +exist. Use kubectl get all -A in the testcluster-admin@testcluster context +to get an overview over the state of your workload cluster. You can access the logs +from the capo controller in case you have trouble with cluster creation.
  • +
  • delete_cluster.sh [CLUSTERNAME]: Tell the capi management server to remove +the cluster $CLUSTERNAME. It will also remove persistent volume claims belonging +to the cluster. The script will return once the removal is done.
  • +
  • cleanup.sh: Remove all running clusters.
  • +
  • add_cluster-network.sh CLUSTERNAME adds the management server to the node network +of the cluster CLUSTERNAME, assuming that it runs on the same cloud (a region). +remove_cluster-network.sh undoes this again. This is useful for debugging +purposes.
  • +
+

For your convenience, k9s is installed on the management server as well +as calicoctl, cilium, hubble, cmctl, helm and sonobuoy. +These binaries can all be found in /usr/local/bin while the helper scripts +have been deployed to ~/bin/.

+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration/index.html b/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration/index.html new file mode 100644 index 0000000000..ef13db322e --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration/index.html @@ -0,0 +1,154 @@ + + + + + +Container registry configuration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Container registry configuration

+

Containerd as container runtime +interface (CRI) used in the reference SCS KaaS implementation allows configuring its +behavior when it interacts with public or private container registry hosts. Container +registry hosts configuration options in containerd are well described in +related docs.

+

This feature could be useful in various uses cases, e.g.:

+
    +
  • Configure containerd to use a custom CA certificate when it interacts with a container +registry host that uses this CA
  • +
  • Configure containerd to use some container registry mirror host instead of the target public or private container +registry. +This could be useful when the target container registry somehow restricts its clients e.g. +DockerHub's pull rate limit to 100 pulls per 6 hours per IP address
  • +
+

SCS KaaS reference implementation allows users to pass container registry host config +files to configure containerd. Containerd configuration is applied cluster wide as it +is CRI used in SCS KaaS clusters. Additional registry host config files for containerd +could be passed through the containerd_registry_files opentofu variable. This variable +expects an object with two attributes:

+
    +
  • hosts attribute defines additional registry host config files for containerd. +The filename should reference the registry host namespace. Files defined in this set +will be copied into the /etc/containerd/certs.d directory on each workload cluster node
  • +
  • certs attribute defines additional client and/or CA certificate files needed for +containerd authentication against registries defined by hosts. Files defined in this +set will be copied into the /etc/containerd/certs directory on each workload cluster node
  • +
+

The default value of the containerd_registry_files variable instructs containerd to use +registry.scs.community container registry instance as a public mirror of DockerHub +container registry, see related +issue #417. +The host config file used as a default is +defined here. +This should prevent issues with pull rate limiting from DockerHub public container registry, +e.g. #414.

+

The above default value could be overridden using any techniques that OpenTofu allows, e.g. +via environment variable:

+
export TF_VAR_containerd_registry_files='{"hosts":["<path to the custom container registry host config>"], "certs":["<path to the custom CA or client certificate>"]}'
+

SCS container registry reference installation https://registry.scs.community contains +several pre-configured "proxy-cache" projects. These projects allow you to use SCS +container registry reference installation to proxy and cache images from target public +registries. This may reduce the load of overused public container registries and/or helps +to avoid rate limiting by individual public registries. +Currently, SCS container registry is set up to "proxy-cache" the following public container registries:

+
    +
  • docker.io
  • +
  • ghcr.io
  • +
  • quay.io
  • +
  • registry.gitlab.com
  • +
  • registry.k8s.io
  • +
+

Find also a corresponding containerd registry host config files +in ./terraform/files/containerd +directory. If you want to configure containerd to use mentioned +pre-configured SCS container registry +"proxy cache" projects, feel free to do that e.g. as follows (path is relative to the terraform directory):

+
export TF_VAR_containerd_registry_files='{"hosts":["./files/containerd/docker.io", "./files/containerd/ghcr.io", "./files/containerd/quay.io", "./files/containerd/registry.gitlab.com", "./files/containerd/registry.k8s.io" ]}'
+

If you did not find your preferred public container registry in the list of pre-configured +SCS container registry "proxy cache" projects, and you would like to use +the SCS container registry +as a mirror for it, please open an issue in one of the following +repositories: scs/k8s-cluster-api-provider, +scs/k8s-harbor.

+

Tutorial: configure an existing cluster to use containerd registry configuration

+

This tutorial is experimental and out of the usual release cycle. We recommend to +upgrade existing environments (workload clusters) with stable releases which are properly +tested.

+

This tutorial instructs (advanced) users what needs to be done on the cluster management +instance without re-deploying it via OpenTofu. Patches described in this tutorial +modify existing environment with changes that have been developed within "containerd registry"-related PRs:

+
    +
  • PR#432
  • +
  • PR#447
  • +
  • PR#472
  • +
+

Warning: This tutorial causes a rolling update (rolling re-deployment) of the control plane and worker nodes.

+
    +
  1. +

    Log in to the cluster management instance, pull remote changes, and then checkout to relevant commit that +includes all mentioned PRs.

    +
    cd k8s-cluster-api-provider/
    git pull
    git checkout b31a79db26c3956b473f026038e71e9aba7819b8
    +
  2. +
  3. +

    Backup the config directory of an existing cluster.

    +
    cd ..
    cp -R <CLUSTER_NAME> <CLUSTER_NAME>.bkp
    +
  4. +
  5. +

    Ensure that the directory for containerd registry configs exists and create a default containerd registry +config file that instructs containerd to use registry.scs.community container registry +instance as a public mirror of DockerHub. +Optionally, create another containerd container registry host file in the containerd/hosts directory. +You can find working examples of those files here.

    +
    cd <CLUSTER_NAME>
    mkdir -p containerd/hosts
    cat >containerd/hosts/docker.io <<EOF
    server = "https://registry-1.docker.io"

    [host."https://registry.scs.community/v2/docker.io"]
    capabilities = ["pull"]
    override_path = true
    EOF
    # Optionally, create another containerd container registry host file here.
    +
  6. +
  7. +

    Injects containerd registry host file(s) (from point 3.) into cluster-template.yaml. +Script configure_containerd.sh does the injection.

    +
    configure_containerd.sh cluster-template.yaml <CLUSTER_NAME>
    +
  8. +
  9. +

    Inject containerd configuration in cluster-template.yaml. This configuration allows +containerd to discover registry host file(s).

    +
      +
    • +

      Create containerd_conf_append temp file

      +
      cat >containerd_conf_append <<EOF
      cat <<EOT >> /etc/containerd/config.toml
      [plugins."io.containerd.grpc.v1.cri".registry]
      config_path = "/etc/containerd/certs.d"
      EOT
      EOF
      +
    • +
    • +

      Inject temp file and systemctl restart containerd.service line into the cluster-template.yaml (inplace)

      +
      yq 'select(.kind == "KubeadmControlPlane").spec.kubeadmConfigSpec.preKubeadmCommands |= (
      (.[] | select(. == "apt-get install -y ca-certificates socat*") | key + 1) as $pos |
      .[:$pos] +
      [load_str("containerd_conf_append")] +
      .[$pos:])' -i cluster-template.yaml

      yq 'select(.kind == "KubeadmControlPlane").spec.kubeadmConfigSpec.preKubeadmCommands |= (
      (.[] | select(. == "systemctl daemon-reload") | key + 1) as $pos |
      .[:$pos] +
      ["systemctl restart containerd.service"] +
      .[$pos:])' -i cluster-template.yaml

      yq 'select(.kind == "KubeadmConfigTemplate").spec.template.spec.preKubeadmCommands |= (
      (.[] | select(. == "apt-get install -y ca-certificates socat*") | key + 1) as $pos |
      .[:$pos] +
      [load_str("containerd_conf_append")] +
      .[$pos:])' -i cluster-template.yaml

      yq 'select(.kind == "KubeadmConfigTemplate").spec.template.spec.preKubeadmCommands |= (
      (.[] | select(. == "systemctl daemon-reload") | key + 1) as $pos |
      .[:$pos] +
      ["systemctl restart containerd.service"] +
      .[$pos:])' -i cluster-template.yaml
      +
    • +
    +
  10. +
  11. +

    The above changes (when point 8. will be applied) of KubeadmControlPlane will cause a rolling update of control plane nodes. +As the KubeadmConfigTemplate has been adjusted we need to increase the generation +counter of worker machines to ensure that the worker nodes will be rolling updated as well.

    +
    sed -r 's/(^WORKER_MACHINE_GEN: genw)([0-9][0-9])/printf "\1%02d" $((\2+1))/ge' -i clusterctl.yaml
    +
  12. +
  13. +

    Workaround: If your environment contains nginx ingress deployed via k8s-cluster-api-provider +(variable DEPLOY_NGINX_INGRESS=true) disable its update. Nginx-ingress controller has +been updated to version 1.8.0 in PR#440 and later to 1.8.1. This is a breaking change that includes updates +of immutable fields. If the above is the case skip this update as follows:

    +
    sed 's/DEPLOY_NGINX_INGRESS: true/DEPLOY_NGINX_INGRESS: false/g' -i clusterctl.yaml
    +
  14. +
  15. +

    Update the existing cluster.

    +
    create_cluster.sh test1
    +
  16. +
+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster/index.html b/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster/index.html new file mode 100644 index 0000000000..16c3eb41e2 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster/index.html @@ -0,0 +1,39 @@ + + + + + +Create a new cluster | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Create a new cluster

+

On the management server (login with make ssh), create a directory (below the home of +the standard ubuntu user) with the name of your cluster. Copy over clusterctl.yaml from +~/cluster-defaults/ and edit it according to your needs. You can also copy over other +files from ~/cluster-defaults/ and adjust them, but this is only needed in exceptional +cases. +Now run create_cluster.sh <CLUSTER_NAME>

+

This will copy all missing defaults from ~/cluster-defaults/ into the directory with your +cluster name and then ask cluster-api to create the cluster. The scripts also take +care of security groups, anti-affinity, node image registration (if needed) and +of deploying CCM, CNI, CSI as well as optional services such as metrics or nginx-ingress +controller.

+

You can access the new cluster with kubectl --context clustername-admin@cluster +or KUBECONFIG=~/clustername/clustername.yaml kubectl.

+

The management cluster is in context kind-kind.

+

Note that you can always change clusterctl.yaml and re-run create_cluster.sh. The script is idempotent and running +it multiple times with the unchanged input file will result in no changes to the cluster.

+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca/index.html b/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca/index.html new file mode 100644 index 0000000000..5ad3e85138 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca/index.html @@ -0,0 +1,93 @@ + + + + + +Custom CA | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Custom CA

+

OpenStack provides public-facing API endpoints which protection by SSL/TLS certificates +is highly recommended in production environments. +These certificates are usually issued by public CA but also the custom or private CA could be used.

+

If the communication with OpenStack API is protected by the certificate issued by custom CA +the cacert setting needs to be provided inside clouds.yaml, e.g.:

+
clouds:
devstack:
cacert: ca-bundle.pem
auth:
auth_url: https://10.0.3.15/identity
project_domain_id: default
project_name: demo
user_domain_id: default
identity_api_version: 3
region_name: RegionOne
interface: public
+

Here the file ca-bundle.pem contains custom root CA and potentially intermediate CA(s).

+
+

The ca-bundle.pem file will be copied to the management server and used by CAPO +in the management cluster. Also, it will be copied to the workload cluster (control plane and worker nodes) +and mounted and used by OCCM and CCSI pods. +So provide only the necessary certificates in that file.

+
+

Steps of what happens with the custom cacert in k8s-cluster-api-provider:

+
    +
  1. +

    cacert setting is provided inside clouds.yaml

    +
  2. +
  3. +

    Cacert file referenced by cacert key (1.) is copied to the management server +directory ~/cluster-defaults/${cloud_provider}-cacert by OpenTofu

    +
  4. +
  5. +

    During the management server bootstrap process cacert is injected to +the ~/cluster-defaults/cluster-template.yaml to KubeadmControlPlane and KubeadmConfigTemplate files +as file with cacert content from already defined secret ${CLUSTER_NAME}-cloud-config and will be later +templated and copied to the workload cluster (control plane and worker nodes) provisioned by CAPO, e.g.:

    +
    files:
    - contentFrom:
    secret:
    key: cacert
    name: ${CLUSTER_NAME}-cloud-config
    owner: root:root
    path: /etc/ssl/certs/devstack-cacert
    permissions: "0644"
    +
  6. +
  7. +

    When the creation of the workload cluster (create_cluster.sh) starts, +~/cluster-defaults/cluster-template.yaml is copied into workload cluster directory (~/$CLUSTER_NAME/)

    +
  8. +
  9. +

    Then the cacert file content is base64 encoded and saved in OPENSTACK_CLOUD_CACERT_B64 variable +inside ~/$CLUSTER_NAME/clusterctl.yaml, so it can be used during +the workload cluster templating

    +
  10. +
  11. +

    Later, when the workload cluster templates are applied to the management cluster, +secret ${CLUSTER_NAME}-cloud-config with base64 encoded cacert is created and used by CAPO

    +
  12. +
  13. +

    CAPO will create workload cluster (thanks to steps 5. and 6.) and cacert is +transferred to the control plane and worker nodes (thanks to steps 3. and 4.)

    +
  14. +
  15. +

    OCCM and CCSI pods mount cacert via hostPath volume +and use it for e.g. creating load balancers or volumes

    +
  16. +
+

Rotation

+

When the custom CA expires or otherwise changes it needs to be rotated. +CAPO uses the custom CA certificate in the management cluster for creating the infrastructure +for the workload clusters and in the workload clusters by OCCM and CCSI for e.g. creating load balancers or volumes. +In both cases, cacert is provided via secret ${CLUSTER_NAME}-cloud-config and needs to be updated.

+

There are 3 steps in this rotation process:

+
    +
  1. Replace/append custom CA certificate in ~/cluster-defaults/${cloud_provider}-cacert
  2. +
  3. Increase generation counters CONTROL_PLANE_MACHINE_GEN and WORKER_MACHINE_GEN in ~/$CLUSTER_NAME/clusterctl.yaml
  4. +
  5. Run create_cluster.sh $CLUSTER_NAME and wait for the rolling update of your workload cluster
  6. +
+
+

In step 1, appending can be useful for avoiding downtime of your services. +Your cacert file will contain two CA certificates - old and new. +This should help with a smooth transition to a new certificate and later, the old one can be removed.

+

Steps 2 and 3 need to be done per workload cluster.

+

When step 2 is omitted, only cacert secret in the management cluster is updated and no rolling update of +the workload cluster in step 3 is started and existing nodes remain with the old certificate.

+
+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api/index.html b/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api/index.html new file mode 100644 index 0000000000..493c3bfe1b --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api/index.html @@ -0,0 +1,28 @@ + + + + + +Gateway-API | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Gateway-API

+

Starting with R5, this k8s-solution offers experimental kubernetes gateway API support. You need to set deploy_gateway_api to true in your environments configuration. Also you need to use cilium as your CNI (default since R5).

+

After deploying your cluster, you can use gateway API and deploy Gateways and HTTP-Routes. As a starting point you can deploy this example app:

+
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/bookinfo/platform/kube/bookinfo.yaml
+

and this example Gateway and HTTP-Route

+
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.15.1/examples/kubernetes/gateway/basic-http.yaml
+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor/index.html b/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor/index.html new file mode 100644 index 0000000000..ba5d6caf1e --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor/index.html @@ -0,0 +1,92 @@ + + + + + +Harbor | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Harbor

+

Project k8s-harbor is used for the SCS Harbor +container registry deployment https://registry.scs.community/.

+

With this project, it is possible to deploy Harbor in a similar way into the workload cluster. +If you want to deploy Harbor, set opentofu variable deploy_harbor = true. It will deploy +Harbor with default options. The recommended approach is to +set up also persistence and ingress with tls.

+
+

It automatically deploys flux as k8s-harbor requirement. +It also expects that the Swift object store is available in the targeting OpenStack project. S3 credentials +(openstack ec2 credentials create) are created and saved into ~/$CLUSTER_NAME/deployed-manifests.d/harbor/.ec2. +Bucket (openstack container create "$PREFIX-$CLUSTER_NAME-harbor-registry") for storing container images +is also automatically created in the openstack Swift object store.

+
+
+

Warning: Swift container and ec2 credentials are not removed when the workload cluster is deleted.

+
+

Default deployment

+

By default, Harbor will be deployed with these options:

+
harbor_config = {
domain_name: "",
issuer_email: "",
persistence: false,
database_size: "1Gi",
redis_size: "1Gi",
trivy_size: "5Gi"
}
+

These options are templated to the mgmt server and used as environment variables +during the creation of the workload cluster:

+
$ cat ~/cluster-defaults/harbor-settings
DEPLOY_HARBOR=true
HARBOR_DATABASE_SIZE=1Gi
HARBOR_DOMAIN_NAME=
HARBOR_ISSUER_EMAIL=
HARBOR_PERSISTENCE=false
HARBOR_REDIS_SIZE=1Gi
HARBOR_TRIVY_SIZE=5G
+

When the Harbor is deployed, you can check the status, e.g. by:

+
$ flux get helmrelease -n default
NAME REVISION SUSPENDED READY MESSAGE
harbor 1.12.4 False True Release reconciliation succeeded
+

or you can simply check if pods are running by kubectl get pods.

+

Harbor components are deployed as deployments and statefulsets:

+
$ kubectl get deploy,sts
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/harbor-core 2/2 2 2 11m
deployment.apps/harbor-exporter 1/1 1 1 11m
deployment.apps/harbor-jobservice 2/2 2 2 11m
deployment.apps/harbor-nginx 1/1 1 1 11m
deployment.apps/harbor-portal 2/2 2 2 11m
deployment.apps/harbor-registry 2/2 2 2 11m

NAME READY AGE
statefulset.apps/harbor-database 1/1 11m
statefulset.apps/harbor-redis 1/1 11m
statefulset.apps/harbor-trivy 2/2 11m
+

Default options deploy Harbor as clusterIP service without pvc persistence for database, redis and trivy. +See terraform/files/kubernetes-manifests.d/harbor/envs/clusterIP/ for further details. +You can access it via the k8s service harbor, for example, port-forward it and access it at http://localhost:8080:

+
$ kubectl get svc harbor -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
harbor ClusterIP 10.109.57.148 <none> 80/TCP 11m app=harbor,component=nginx,release=harbor
$ kubectl port-forward svc/harbor 8080:80
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
+

Admin username is admin and password can be obtained from the secret by:

+
kubectl get secret harbor-secrets -o jsonpath='{.data.values\.yaml}' | base64 -d | yq .harborAdminPassword
+

Configuration options

+

Persistence

+

By default, persistence is set to false. +When persistence is set to true, i.e. harbor_config = {persistence: true}, +Harbor components (database, redis, trivy) are deployed with PVCs:

+
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-harbor-redis-0 Bound pvc-982221c1-64cb-4d3e-a77d-1db5b4429a69 1Gi RWO cinder-default 6m12s
data-harbor-trivy-0 Bound pvc-8a2ad60c-c7bf-40e1-8593-0d00b3d40b4f 5Gi RWO cinder-default 6m12s
data-harbor-trivy-1 Bound pvc-734f9b6a-9cee-40e4-9e1c-b959d9f7b7cf 5Gi RWO cinder-default 5m11s
database-data-harbor-database-0 Bound pvc-c5c3a7e6-a99a-4f16-a5cc-792e9b3665d8 1Gi RWO cinder-default 6m12s
+

The size of PVCs can be configured by harbor_config = {<component>_size: "size"}. +Trivy has 2 replicas, i.e. 2 PVCs will be created.

+
+

When persistence is set to true, Cinder CSI is automatically deployed.

+
+

Ingress and TLS

+

If you want to deploy ingress in front of Harbor and secure it with SSL/TLS certificate, set the domain_name option. +Relevant files which will be deployed are located in terraform/files/kubernetes-manifests.d/harbor/envs/ingress/.

+
+

When domain_name is set, cert-manager and ingress-nginx are automatically deployed.

+
+

So, instead of default harbor clusterIP service and harbor-nginx deployment, harbor-ingress will be deployed:

+
$ kubectl get ing harbor-ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
harbor-ingress nginx harbor.example.com 213.131.230.203.nip.io 80, 443 13m
+

There will be also an additional cert-manager issuer letsencrypt deployed:

+
$ kubectl get issuers -o wide
NAME READY STATUS AGE
letsencrypt True The ACME account was registered with the ACME server 13m
+

This ACME issuer has an optional email field, which can be set by issuer_email option. +This is recommended option because it will be used to contact you in case of issues with your account or certificates, +including expiry notification emails.

+

Then, the settings can look like this:

+
harbor_config = {
domain_name: "harbor.example.com",
issuer_email: "email@example.com",
}
+

After the deployment, there is one mandatory step to set up proper TLS communication with this Harbor instance. +harbor-ingress has special annotation cert-manager.io/issuer: letsencrypt which instructs cert-manager +to create a certificate object:

+
$ kubectl get cert -o wide
NAME READY SECRET ISSUER STATUS AGE
harbor-crt False harbor-crt letsencrypt Issuing certificate as Secret does not exist 13m
+

The certificate is not ready, because it uses Let’s Encrypt standard ACME HTTP-01 challenge. +In this challenge, you need to take the IP address of the ingress load balancer and create a DNS record +for your domain_name. You can get an IP address (don't look on nip.io suffix) e.g. by this command:

+
$ kubectl -n ingress-nginx get svc ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress}'
[{"hostname":"213.131.230.203.nip.io"}]
+

And after a while, your cert is ready, and you can access harbor at https://harbor.example.com/:

+
$ kubectl get cert -o wide
NAME READY SECRET ISSUER STATUS AGE
harbor-crt True harbor-crt letsencrypt Certificate is up to date and has not expired 18m
+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/usage/index.html b/docs/container/components/k8s-cluster-api-provider/doc/usage/index.html new file mode 100644 index 0000000000..dca7faaacf --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/usage/index.html @@ -0,0 +1,33 @@ + + + + + +Usage | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Usage

+

The subsequent management of the cluster can best be done from the management server VM, as it has all the tools +deployed there and config files can be edited and resubmitted to the kubernetes kind cluster for reconciliation. To log +in to this management server via ssh, you can issue make ssh.

+

You can create and do life cycle management for many more clusters from this management server.

+

The kubeconfig with admin power for the created testcluster is named testcluster/testcluster.yaml ( +or $CLUSTER_NAME/$CLUSTER_NAME.yaml for all the other clusters) and can be handed out to users that should get full +administrative control over the cluster. You can also retrieve them +using make get-kubeconfig TESTCLUSTER=${CLUSTER_NAME} from the machines where you created the management server from, +and possibly create an encrypted .zip file for handing these out. (You can omit TESTCLUSTER=... for the +default testcluster.)

+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters/index.html b/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters/index.html new file mode 100644 index 0000000000..101525a140 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters/index.html @@ -0,0 +1,38 @@ + + + + + +Managing many clusters | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Managing many clusters

+

While the scripts all use a default testcluster, they have +been developed and tested to manage many clusters from a single management +node. Copy the ~/cluster-defaults/clusterctl.yaml file to +~/MYCLUSTER/clusterctl.yaml +and edit the copy to describe the properties of the cluster to be created. +Use ./create_cluster.sh MYCLUSTER then to create a workload cluster +with the name MYCLUSTER. You will find the kubeconfig file in +~/MYCLUSTER/MYCLUSTER.yaml, granting its owner admin access to that cluster. +Likewise, delete_cluster.sh and the apply_*.sh scripts take a +cluster name as parameter.

+

This way, dozens of clusters can be controlled from one management server.

+

You can add credentials from different projects into +~/.config/openstack/clouds.yaml and reference them in the OPENSTACK_CLOUD +setting in clusterctl.yaml, this way managing clusters in many different +projects and even clouds from one management server.

+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class/index.html b/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class/index.html new file mode 100644 index 0000000000..f0ba898020 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class/index.html @@ -0,0 +1,60 @@ + + + + + +Migration to ClusterClass | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Migration to ClusterClass

+

From #600, this repository uses CAPI +ClusterClass feature for the creation of +new clusters, additionally see k8s blog. +This feature is also used e.g. in the SCS cluster-stacks repository.

+
+

Note: For now, ClusterClass is created per Cluster, which is not optimal and most likely it can be improved.

+
+

Therefore, existing clusters must be migrated from 'old' cluster templates to 'new' cluster class based templates. +Based on ClusterClass proposal +of update strategy, we shouldn't be able to migrate, but in CAPI PR #6292 +the validation webhook was relaxed (via special Cluster annotation +unsafe.topology.cluster.x-k8s.io/disable-update-class-name-check) and manual migration is now possible.

+

The script migrate-to-cluster-class.sh uses that special annotation for migration. In the beginning, it patches +CAPI and KCP deployments with the ClusterTopology=true container argument. Then creates new resources +(KubeadmControlPlaneTemplate, OpenStackClusterTemplate, ClusterClass). After that, annotates, labels and +patches existing cluster resources. In the end, it patches the Cluster object with .spec.topology and it's done.

+

Migration

+

Prerequisites

+
    +
  • CAPI >= v1.5.2 due to NamingStrategy feature +
      +
    • upgrade can be performed as stated in upgrade guide
    • +
    +
  • +
+

Steps

+
    +
  1. Git pull/checkout new changes into the ~/k8s-cluster-api-provider directory
  2. +
  3. Run migrate-to-cluster-class.sh <CLUSTER_NAME> (verify machines were not recreated)
  4. +
  5. Copy new templates for existing and new clusters (consider backup) +
    cp ~/k8s-cluster-api-provider/terraform/files/template/cluster-template.yaml ~/<CLUSTER_NAME>/cluster-template.yaml
    cp ~/k8s-cluster-api-provider/terraform/files/template/cluster-template.yaml ~/cluster-defaults/cluster-template.yaml
    +
  6. +
  7. Add the newly introduced generation counter for the OpenStackClusterTemplate to the settings in clusterctl.yaml +
    echo "OPENSTACK_CLUSTER_GEN: geno01" >> ~/<CLUSTER_NAME>/clusterctl.yaml
    echo "OPENSTACK_CLUSTER_GEN: geno01" >> ~/cluster-defaults/clusterctl.yaml
    +
  8. +
  9. Next run of create_cluster.sh <CLUSTER_NAME> should be idempotent
  10. +
+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2/index.html b/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2/index.html new file mode 100644 index 0000000000..e0cc459036 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2/index.html @@ -0,0 +1,71 @@ + + + + + +Migration to KaaS v2 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Migration to KaaS v2

+

From R6, k8s-cluster-api-provider repository (SCS KaaS reference implementation v1) is deprecated +and should not be used for new deployments. We intend to remove it with the next release (R7).

+

Therefore, it is recommended to migrate to Cluster Stacks - SCS +KaaS reference implementation v2. For list of known issues and in restrictions KaaS v2 see SCS R6 Release Notes. +We will try to address most of the gaps during the next release cycle (R7).

+

Migration

+

In R6, we migrated to ClusterClass +feature to ease the migration to KaaS v2, because Cluster Classes are the main component there. So this guide will work +only on release >= R6 (use upgrade guide +first, when you are on release < R6).

+
+

Warning: This guide supports only cilium CNI (the only CNI Cluster Addon in KaaS v2)

+
+
+

Warning: After the migration, create_cluster.sh and other KaaS v1 scripts and features should not be used anymore

+
+

Steps

+
    +
  1. Deploy KaaS v1, e.g.: +
    cloud_provider    = "gx-scs"
    availability_zone = "nova"
    controller_flavor = "SCS-2V-4"
    worker_flavor = "SCS-2V-4"
    dns_nameservers = ["62.138.222.111", "62.138.222.222"]
    +
  2. +
  3. Deploy CSO and CSPO: +
      +
    • deploy with make (access token optional and recommended) +
      make deploy-cso GIT_ACCESS_TOKEN=<github-access-token>
      make deploy-cspo GIT_ACCESS_TOKEN=<github-access-token>
      +
    • +
    +
  4. +
  5. Export ${PREFIX} and ${CLUSTER_NAME}: +
    . ~/bin/cccfg.inc
    +
  6. +
  7. Patch secret with cloudName: +
    kubectl patch secret -n ${CLUSTER_NAME} ${CLUSTER_NAME}-cloud-config -p '{"stringData":{"cloudName":"'"${PREFIX}-${CLUSTER_NAME}"'"}}'
    +
  8. +
  9. Create Cluster Stack: +
    kubectl -n ${CLUSTER_NAME} apply -f - <<EOF
    apiVersion: clusterstack.x-k8s.io/v1alpha1
    kind: ClusterStack
    metadata:
    name: scs
    spec:
    provider: openstack
    name: scs
    kubernetesVersion: "1.28"
    channel: stable
    autoSubscribe: false
    providerRef:
    apiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1
    kind: OpenStackClusterStackReleaseTemplate
    name: cspotemplate
    versions:
    - v1
    ---
    apiVersion: infrastructure.clusterstack.x-k8s.io/v1alpha1
    kind: OpenStackClusterStackReleaseTemplate
    metadata:
    name: cspotemplate
    spec:
    template:
    spec:
    identityRef:
    kind: Secret
    name: ${CLUSTER_NAME}-cloud-config
    EOF
    +
    $ kubectl -n ${CLUSTER_NAME} get clusterstack
    NAME PROVIDER CLUSTERSTACK K8S CHANNEL AUTOSUBSCRIBE USABLE LATEST AGE REASON MESSAGE
    scs openstack scs 1.28 stable false v1 openstack-scs-1-28-v1 | v1.28.7 15m
    +
  10. +
  11. Migrate Cluster to KaaS v2: +
    cat << "EOF" | clusterctl generate yaml --config ~/${CLUSTER_NAME}/clusterctl.yaml | kubectl -n ${CLUSTER_NAME} apply -f -
    apiVersion: cluster.x-k8s.io/v1beta1
    kind: Cluster
    metadata:
    name: ${CLUSTER_NAME}
    spec:
    clusterNetwork:
    pods:
    cidrBlocks: ["${POD_CIDR}"]
    services:
    cidrBlocks: ["${SERVICE_CIDR}"]
    serviceDomain: "cluster.local"
    topology:
    variables:
    - name: dns_nameservers
    value: ${OPENSTACK_DNS_NAMESERVERS}
    - name: controller_flavor
    value: ${OPENSTACK_CONTROL_PLANE_MACHINE_FLAVOR}
    - name: worker_flavor
    value: ${OPENSTACK_NODE_MACHINE_FLAVOR}
    - name: controller_root_disk
    value: ${CONTROL_PLANE_ROOT_DISKSIZE}
    - name: worker_root_disk
    value: ${WORKER_ROOT_DISKSIZE}
    - name: external_id
    value: ${OPENSTACK_EXTERNAL_NETWORK_ID}
    - name: node_cidr
    value: ${NODE_CIDR}
    - name: openstack_security_groups
    value: [${PREFIX}-allow-ssh, ${PREFIX}-allow-icmp, ${PREFIX}-${CLUSTER_NAME}-cilium]
    - name: cloud_name
    value: ${OPENSTACK_CLOUD}
    - name: secret_name
    value: ${CLUSTER_NAME}-cloud-config
    - name: controller_server_group_id
    value: ${OPENSTACK_SRVGRP_CONTROLLER}
    - name: worker_server_group_id
    value: ${OPENSTACK_SRVGRP_WORKER}
    - name: ssh_key
    value: ${OPENSTACK_SSH_KEY_NAME}
    class: openstack-scs-1-28-v1
    version: ${KUBERNETES_VERSION}
    controlPlane:
    replicas: ${CONTROL_PLANE_MACHINE_COUNT}
    workers:
    machineDeployments:
    - class: openstack-scs-1-28-v1-md-0-no1
    name: "${PREFIX}-${CLUSTER_NAME}-md-0-no1"
    replicas: ${WORKER_MACHINE_COUNT}
    failureDomain: ${OPENSTACK_FAILURE_DOMAIN}
    EOF
    +
    +

    Note: If you are using flavors with a disk, comment controller_root_disk and worker_root_disk variables

    +
    +
  12. +
  13. Fix metrics-server Cluster Addon: +
    $ kubectl -n ${CLUSTER_NAME} get clusteraddon
    NAME CLUSTER READY AGE REASON MESSAGE
    cluster-addon-testcluster testcluster false 20m FailedToApplyObjects failed to successfully apply everything
    $ KUBECONFIG=~/${CLUSTER_NAME}/${CLUSTER_NAME}.yaml kubectl delete deployment -n kube-system metrics-server
    deployment.apps "metrics-server" deleted
    $ kubectl -n ${CLUSTER_NAME} get clusteraddon
    NAME CLUSTER READY AGE REASON MESSAGE
    cluster-addon-testcluster testcluster true 25m
    +
  14. +
+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments/index.html b/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments/index.html new file mode 100644 index 0000000000..621d11cd99 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments/index.html @@ -0,0 +1,31 @@ + + + + + +Multi-AZ and multi-cloud environments | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Multi-AZ and multi-cloud environments

+

The provided cluster-template.yaml assumes that all control nodes on one hand and all worker nodes on the other are +equal. They are in the same cloud within the same availability zone, using the same flavor. cluster API allows k8s +clusters to have varying flavors, span availability zones and even clouds. For this, you can create an advanced +cluster-template with more different machine descriptions and potentially several secrets. Depending on your changes, +the logic in create_cluster.sh might also need enhancements to handle this. Extending this is not hard and we're happy +to hear from your use cases and take patches.

+

However, we are currently investigating to use helm templating for anything beyond the simple use cases instead, see +next chapter.

+ + \ No newline at end of file diff --git a/docs/container/components/k8s-cluster-api-provider/doc/usage/testing/index.html b/docs/container/components/k8s-cluster-api-provider/doc/usage/testing/index.html new file mode 100644 index 0000000000..531d6c4d50 --- /dev/null +++ b/docs/container/components/k8s-cluster-api-provider/doc/usage/testing/index.html @@ -0,0 +1,55 @@ + + + + + +Testing | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Testing

+

To test the created k8s cluster, there are several tools available. +Apply all commands to the testcluster context (by passing the appropriate +--context setting to kubectl or by using the right KUBECONFIG +file).

+
    +
  • +

    Looking at all pods (kubectl get pods -A) to see that they all come +up (and don't suffer excessive restarts) is a good first check. +Look at the pod logs to investigate any failures.

    +
  • +
  • +

    You can create a very simple deployment with the provided kuard.yaml, which is +an example taken from the O'Reilly book from B. Burns, J. Beda, K. Hightower: +"Kubernetes Up & Running" enhanced to also use a persistent volume.

    +
  • +
  • +

    You can deploy Google's demo microservice application.

    +
  • +
  • +

    sonobuoy runs a subset of the k8s tests, providing a simple way to +filter the >5000 existing test cases to only run the CNCF conformance +tests or to restrict testing to non-disruptive tests. The sonobuoy.sh wrapper +helps with calling it. There are also Makefile targets check-* that +call various sonobuoy test sets. +This is how we call sonobuoy for our CI tests.

    +
  • +
  • +

    You can use cilium connectivity test to check whether your cilium +CNI is working properly. You might need to enable hubble to get +a fully successful result.

    +
  • +
+ + \ No newline at end of file diff --git a/docs/container/deployment-examples/a/hardware/index.html b/docs/container/deployment-examples/a/hardware/index.html new file mode 100644 index 0000000000..e2e2e4c2f2 --- /dev/null +++ b/docs/container/deployment-examples/a/hardware/index.html @@ -0,0 +1,24 @@ + + + + + +Hardware Requirements | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/deployment-examples/a/index.html b/docs/container/deployment-examples/a/index.html new file mode 100644 index 0000000000..c9e13ff637 --- /dev/null +++ b/docs/container/deployment-examples/a/index.html @@ -0,0 +1,24 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/deployment-examples/a/software/index.html b/docs/container/deployment-examples/a/software/index.html new file mode 100644 index 0000000000..250c8faa94 --- /dev/null +++ b/docs/container/deployment-examples/a/software/index.html @@ -0,0 +1,24 @@ + + + + + +Software Requirements | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/guides/guide1/index.html b/docs/container/guides/guide1/index.html new file mode 100644 index 0000000000..6b25de0746 --- /dev/null +++ b/docs/container/guides/guide1/index.html @@ -0,0 +1,24 @@ + + + + + +Guide 1 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/index.html b/docs/container/index.html new file mode 100644 index 0000000000..5cb5d790e3 --- /dev/null +++ b/docs/container/index.html @@ -0,0 +1,62 @@ + + + + + +Container Layer Introduction | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Container Layer Introduction

+

The container layer within the Sovereign Cloud Stack (SCS) offers a robust solution for managing container workloads on a Kubernetes infrastructure. It facilitates the on-demand creation and scaling of Kubernetes clusters, catering to various needs across development, testing, deployment, and operation of services and applications. While the container layer is versatile for a range of use cases, the most common ones include:

+
    +
  • Self-Service: Here, entities can empower their development teams with the autonomy to spawn and manage their clusters on demand, fostering a more agile and responsive development environment.
  • +
  • KaaS (Kubernetes as a Service): In this model, an SCS Cloud provider can offer their customers a managed Kubernetes service, abstracting much of the underlying operational complexity from their customers.
  • +
+

Target groups

+
    +
  • DevOps/SysOps Teams: They are the primary beneficiaries as the container layer promotes flexible, on-demand operations helpful for continuous development, testing, deployment, and service management.
  • +
  • Cloud Service Providers: By delivering a standardized container orchestration platform, they can provide more reliable and robust services to their customers, enhancing their product portfolio.
  • +
+

What is it not

+
    +
  • The container layer is not an alternative to Infrastructure as a Service (IaaS) but rather an extension that allows for more streamlined operation and management of containerized applications.
  • +
  • Although the container layer doesn't directly support Serverless Containers or Functions as a Service, these can be run on a Kubernetes cluster. However, as of now, the SCS container layer doesn't offer specialized tools for these use cases.
  • +
+

Prerequisites and Requirements

+
    +
  • Knowledge: Familiarity with Kubernetes, container orchestration, and basic cloud infrastructure principles is pivotal.
  • +
  • Software: The core software component is the K8s Cluster API Provider, crafted to function optimally on OpenStack environments. Although designed to run on the SCS IaaS layer, with minor configuration adjustments, it can operate on any OpenStack environment.
  • +
  • Hardware: Virtualization-enabled hardware capable of running OpenStack is essential if hosting the IaaS layer independently. For further details, refer to the IaaS layer documentation.
  • +
+

Features

+
    +
  • Automated Cluster Management: The K8s Cluster API Provider automates the process of creating, scaling, managing and updating Kubernetes clusters, thus significantly reducing the operational overhead.
  • +
  • Standardized Operations: Upholding SCS standards across various clusters ensures operational consistency and reliability.
  • +
  • Integration with OpenStack: The K8s Cluster API Provider is tailored to work seamlessly with SCS IaaS (OpenStack), thus offering a unified platform for managing both containers and the underlying infrastructure.
  • +
  • Container Registry Integration: The container layer has an integrated container registry, facilitating easy management and deployment of container images.
  • +
  • Certificate Managment: The kubernetes clusters can optionaly include a certbot allowing for ease of deployment of public facing services out of the box.
  • +
  • Preconfigured ingress: Certificate Management: Optional inclusion of Certbot in Kubernetes clusters facilitates straightforward deployment of publicly accessible services. +Preconfigured Ingress: Kubernetes clusters come with a preconfigured Nginx ingress, designed with OpenStack in mind, providing a ready-to-use ingress solution with enhancements like out-of-the-box client source IP visibility.
  • +
+

Limitations

+
    +
  • OpenStack Dependency: The current design primarily supports OpenStack environments, which could be a limitation for other infrastructure setups.
  • +
  • Serverless/Functions as a Service Support: Lack of direct support for serverless containers and Functions as a Service (FaaS) might require additional tools or platforms.
  • +
+

Current state and future Outlook

+

The container layer has matured with multiple cloud providers now offering Kubernetes as a Service using this layer to manage a multitude of clusters. It follows a half-yearly release schedule to ensure security and up-to-date Kubernetes clusters, alongside providing backports for significant features into older versions.

+

Looking ahead, a new version based on ClusterStacks is in the pipeline, currently in its Alpha state. This upcoming release aims to be backward compatible, facilitating smooth migration from existing setups, and further extending the capabilities of the SCS container layer.

+ + \ No newline at end of file diff --git a/docs/container/overview/architecture/index.html b/docs/container/overview/architecture/index.html new file mode 100644 index 0000000000..5ae1b55a10 --- /dev/null +++ b/docs/container/overview/architecture/index.html @@ -0,0 +1,24 @@ + + + + + +Architecture | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/container/overview/knowledge/index.html b/docs/container/overview/knowledge/index.html new file mode 100644 index 0000000000..3e396d09ba --- /dev/null +++ b/docs/container/overview/knowledge/index.html @@ -0,0 +1,24 @@ + + + + + +Knowledge | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/faq/index.html b/docs/faq/index.html new file mode 100644 index 0000000000..f72caba956 --- /dev/null +++ b/docs/faq/index.html @@ -0,0 +1,72 @@ + + + + + +Frequently Asked Questions | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Frequently Asked Questions

+

What does SCS stand for?

+

The Sovereign Cloud Stack (SCS) provides standards for a range of cloud infrastructure types. It strives for interoperable and sovereign cloud offerings which can be deployed and used by a wide range of organizations and individuals.

+

Who is SCS intended for?

+

SCS is a Software Stack to power data centers of different scale. It empowers public or private cloud service providers to offer resources to their endusers.

+

Who or what is behind SCS?

+

SCS is run by the SCS Project Team which is based at the Open Source Business Alliance e.V. and 100% funded by the German Ministry of Economics and Climate Action (BMWK). Public money means public code.

+

Why is there a need for a standardized cloud environment?

+

A standardized environment promotes interoperability, reduces vendor lock-in, and facilitates smoother transitions between providers. It gives individuals, companies and public institutions the freedom of choice.

+

Where can I find the SCS standards?

+

The SCS standards are available on the standards pages within our documentation page. Find them here

+

How is the SCS different from other cloud environments (e.g. AWS, Azure,...)?

+

Unlike proprietary clouds, SCS emphasizes standardization, ensuring interoperability and reduced dependency on one provider.

+

My company already has a cloud environment. Can we still use the SCS?

+

Yes, SCS can complement existing environments, enhancing standardization and interoperability.

+

What does reference implementation mean?

+

Reference implementation is a concrete example or blueprint of how the SCS standards can be implemented.

+

Do I need to use the reference implementation to be SCS compliant?

+

No, while the reference implementation is a guide, compliance requires adhering to SCS standards, not the exact blueprint of the reference implementation. Check the standards page on how to be SCS-compatible

+

Do I have to use all layers of the reference implementation (IaaS, CaaS)?

+

No, you can choose layers based on your needs and still be SCS compliant.

+

What does IaaS mean?

+

IaaS stands for Infrastructure as a Service, providing virtualized computing resources over the internet.

+

How is the IaaS layer structured?

+

IaaS typically comprises virtual machines, storage, and network resources, all offered as scalable services. Find the architecture here

+

What does CaaS mean? (Container Layer)

+

CaaS refers to Container as a Service, where providers offer container orchestration platforms.

+

I want to try out the SCS! Where do I start?

+

As a user:

+
    +
  • Existing SCS Clouds: Explore and test on any of the cloud providers offering SCS. Choose one from here
  • +
+

As a Cloud Service Provider:

+ +

I want to use an SCS Cloud! How do I get started?

+

As a user:

+ +

As a Cloud Service Provider:

+ +

I want to use the SCS in my company and build my own cloud! Where do I start?

+

Start by understanding SCS standards and then move on to the reference implementation. Link to guide.

+

I have a technical problem. Where can I find help?

+

Refer to our support section or check our community channels for assistance. Link to community.

+ + \ No newline at end of file diff --git a/docs/getting-started/containerization/index.html b/docs/getting-started/containerization/index.html new file mode 100644 index 0000000000..561b3fa9af --- /dev/null +++ b/docs/getting-started/containerization/index.html @@ -0,0 +1,24 @@ + + + + + +Containerization | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/getting-started/overview/index.html b/docs/getting-started/overview/index.html new file mode 100644 index 0000000000..a00af9d05f --- /dev/null +++ b/docs/getting-started/overview/index.html @@ -0,0 +1,24 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/getting-started/virtualization/index.html b/docs/getting-started/virtualization/index.html new file mode 100644 index 0000000000..ecbf19760c --- /dev/null +++ b/docs/getting-started/virtualization/index.html @@ -0,0 +1,24 @@ + + + + + +Virtualization | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/glossary/index.html b/docs/glossary/index.html new file mode 100644 index 0000000000..3553e4739e --- /dev/null +++ b/docs/glossary/index.html @@ -0,0 +1,90 @@ + + + + + +Glossary | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Glossary

+

This file serves as the central glossary within SCS. It is intended to clearly +define terms used within SCS where there may be differing understandings. The +glossary is not intended to evaluate or standardize specific terms.

+

Definition of a Region

+

An OpenStack/SCS region consists of at least one or more Availability Zones that share a Control Plane with their services. As a result, they share one API. Also a Control Plane can share one CEPH cluster over different fire departments or each Availbility Zone can have its own CEPH cluster. Within the region, any Layer 2 networks are available to the user. Availbility Zones which build a region are connected by redundant low-latency (< 2ms ) high-bandwidth (10s of Gbps) connections.

+

Regions can be federated when the SCS code is ready.

+

Definition of a Availability Zone

+

An Availability Zone is a (physical) group of multiple compute nodes, controlled by the region's control plane that provides the API and interface.

+

An Availability Zone allows OpenStack compute hosts to be divided into logical groups and provides a form of physical isolation and redundancy from other Availability Zones, for example by using a separate power supply or network devices.

+

When users provision resources, they can specify in which Availability Zone their instances should be created. In this way, customers can ensure that their application resources are distributed across different failure domains to achieve high availability in the event of a hardware failure.

+

Definition of Host Aggregates

+

Host aggregates are a mechanism for partitioning compute nodes which is not explicitly visible to users in an OpenStack/SCS cloud. Host aggregates are based on arbitrary characteristics such as server type, processor type, GPU, disk speed, etc. +Administrators assign flavors to host aggregates by specifying metadata on the host aggregate and customizing the extra specifications of the flavor. It is then up to the Nova scheduler to determine the best match for the user request. Compute nodes can also be in more than one host aggregate.

+

Optionally, one can designate a host aggregate as an Availability Zone, e.g. for simplification reasons of the user selection of an availbility zone. +Availability Zones differ from Host Aggregates in that they are shown to the user as a Nova boot option, so Compute VMs can be started on them. +Compute Nodes, however, can only be in a single Availability Zone. We can configure a default Availability Zone where instances will be scheduled if the user does not specify an Availability Zone.

+

Info: A prerequisite for creating an Availability Zone is a host aggregate.

+

Definition of a Cell

+

The Cells paradigm simplifies the handling of large Openstack deployments.

+

Cells is an OpenStack Nova feature that improves scalability for Nova in OpenStack Platform. Each Cell has a separate database and message queue, which increases performance when scaling. One can provision additional Cells to handle large deployments, and compared to Regions, this allows access to a large number of compute nodes through a single API.

+

Each Cell has its own Cell controllers running the database server and RabbitMQ along with the Nova Conductor services.

+

Nova Conductor services, called "Super Conductor", continue to run on the main controller nodes.

+

The services in the Cell Controllers can still call placement APIs, but cannot access other API layer services via RPC, nor can they access global API databases on the control nodes.

+

Definition of a Control Plane

+

In Openstack/SCS, a Control Plane consists of at least 5 hardware nodes, which together serve several Availability Zones and thus provide a common usable API for a region. The Control Plane also shares the network (Neutron), the Scheduler and the CEPH services.

+

It includes the Controller Nodes (Galera Cluster, RabbitMQ) and the Manager Nodes, Maas,...

+

Definition of Control Node

+

The Control Node runs the Identity Service, Image Service , management processes for compute nodes, management processes for networking, various networking agents, and the Dashboard. It also includes supporting services such as an SQL database, a message queue, and NTP.

+

Optionally, the Controller Node runs parts of the Block Storage, Object Storage, Orchestration and Telemetry services.

+

The Controller Node requires at least two network interfaces.

+

Definition of Compute Node

+

A compute host runs the hypervisor part of compute that runs instances. By default, compute uses the KVM hypervisor. The compute host also runs a networking service agent that connects instances to virtual networks and provides firewall services to the instances through security groups.

+

If you offer hyper-converged infrastructure, a compute host also serves the Ceph. This makes the storage dynamically scalable (horizontally and vertically). For the Ceph services, 1 CPU core and 4 GB of RAM are reserved per OSD to ensure appropriate performance.

+

Definition of Manager Node

+

From here, the OSISM Ansible playbooks are applied to the environment. Furthermore, the following services often run here non-redundantly: Prometheus server,....

+

Definition of provider network

+

The provider network is the network that is "in front", i.e. at the output points of the openstack/SCS. This is usually a public network, but can also be a private network in individual cases. IPs from the provider network can be assigned to instances within the SCS. The same applies to load balancers, of course.

+

Definition of API

+

The Rest API provides the core of openstack/SCS and can be addressed for a whole region. It accepts and responds to end-user API calls. The service supports the OpenStack Compute API, the Amazon EC2 API, and a special Admin API for privileged users to perform administrative actions. Policies are enforced and most orchestration actions can be started, such as launching an instance.

+

Horizon

+

Horizon is openstack's preferred GUI for the end user, but also for the administrator for a quick overview. It runs on the controller node. Other GUIs are possible, also GUIs which replace the horizon interface

+

Message Queue

+

Most OpenStack services communicate with each other through the message queue. For example, Compute communicates with Block Storage services and Network services via the message queue. RabbitMQ, Qpid, and Zeromq are popular choices for a message queue service. When the message queue fails or becomes inaccessible, the cluster generally comes to a halt and ends up in a read-only state where the information is stuck at the point where the last message was sent. Therefore, this is clustered. RabbitMQ has shown itself to be the most widespread and best supported variant in the OpenStack context, Qpid occurs occasionally, ZeroMQ lacks HA functionality to date

+

Keystone

+

( The OpenStack Identity module called Keystone is used as an authentication and rights system between the OpenStack components. Keystone divides access to projects in the cloud into so-called "tenants". A tenant is a tenant of the cloud and has at least one assigned user. It is possible to create multiple users per tenant with different rights. Keystone uses a token system for authorization and also supports the connection to other authentication options such as LDAP. (wikipedia) )

+

Glance

+

The OpenStack Image Service, also called Glance, is a service that provides virtual machine images to OpenStack users. These images are used by Nova as a template to compile virtual machine instances. Both local hard disks and object storage solutions such as Swift or Ceph can be used as storage backends.

+

In addition to the images, Glance can also store metadata such as the operating system used or the kernel version. Access to both this metadata and the images themselves is via a REST API. Glance supports a number of formats such as VHD, VMDK and qcow2.

+

OSISM

+

The Open Source Infrastructure & Service Manager is a powerful deployment framework for OpenStack and Ceph as well as required services such as a RabbitMQ broker or a MariaDB Galera cluster.

+

Ceph

+

Ceph is an open source distributed storage solution. The core component is RADOS (Reliable Autonomic Distributed Object Store), an object store that can be distributed redundantly over any number of servers. Ceph offers the user three types of storage: An object store compatible with the Swift and S3 API (RADOS Gateway), virtual block devices (RADOS Block Devices) and CephFS, a distributed file system.

+

Nova

+

Nova is virtually a synonym for Compute. It is the part of the stack that can manage groups of virtual machines.

+

The virtualized systems can be distributed over any number of so-called compute nodes. Hypervisors supported include KVM, Xen Hyper-V and ESXI. In the community, KVM is considered to be set and best supported (we use KVM), which is controlled via libvirt. ESXI and Hyper-V can be used, sometimes with limited functionality.

+

Neutron

+

The OpenStack Networking module Neutron provides the networking service for OpenStack. Neutron can be used to manage networks, subnets, and IP addresses/floating IPs. A floating IP in OpenStack refers to an official IP that serves as an interface from the internal to the public network. In addition to a load balancer, HA proxy and health monitor, Neutron also supports techniques such as VLAN and VPN. To secure the networks, Neutron uses a firewall that allows versatile port rules, e.g. on a security group basis. For trademark reasons, the OpenStack networking module had to be renamed "Neutron". The previous name was "Quantum".

+

For the management of the data link layer, Neutron offers the possibility to use various already existing networking software such as Open vSwitch or the bridge functionality of the Linux kernel by means of plugins.

+

In the OpenStack releases since Ussuri, the "OpenVirtualNetwork"(OVN) has established itself, it replaces many of the Neutron components, e.g. L3 and DHCP agent, so that Neutron only has to talk directly to OVN.

+

Cinder

+

OpenStack Block Storage or Cinder provides virtual block storage in the form of virtualized storage media (hard disks, CDs, etc.). The block storage can be attached to virtual machines. An API interface allows Cinder to connect to Swift so that block storage media can communicate with object storage. Meanwhile, many other storage backends are also fully or partially supported. There is also the option of defining multiple backends and creating a volume type for each backend, so that when a new volume is created, it can be selected on which storage backend the volume is created.

+

Swift

+

Swift is the so-called object storage that can be used by Nova. This is responsible for redundant data storage. Swift can also be used as a backend for Cinder or Glance. Objects are stored in so-called containers, which are primarily used to group objects and store metadata and in turn belong to individual accounts. Objects and containers are accessed via a REST API.

+

Ceph OSD

+

A Ceph OSD (Object Storage Daemon) logically represents a storage device in a Ceph cluster, which can logically be a hard disk, which is the ideal case. In other cases it can also be a raid, which however leads to considerable performance limitations due to caching or other raid optimization.

+

Personas

+
PersonaDescription
SCS OperatorThe SCS Operator is the one who owns and operates a standardized cloud environment.
SCS Operations TeamThe team at the SCS Operator which actually runs the cloud environment.
SCS ConsumerThe SCS Consumer consumes a standardized SCS environment and operates and orchestrates applications on top of it. The SCS Consumer is typically a customer or user of the SCS Operator.
SCS IntegratorThe SCS Integrator assists in or is building up a standardized cloud environment. The SCS Integrator can be 2nd or 3rd level support for the SCS Operator.
SCS ProjectThe SCS Project oversees the overall activities around the Sovereign Cloud Stack.
SCS DeveloperThe SCS Developer actively contributes to technical elements of the Sovereign Cloud Stack.
+ + \ No newline at end of file diff --git a/docs/iaas/components/flavor-manager/index.html b/docs/iaas/components/flavor-manager/index.html new file mode 100644 index 0000000000..8894d5a69a --- /dev/null +++ b/docs/iaas/components/flavor-manager/index.html @@ -0,0 +1,74 @@ + + + + + +Flavor Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Flavor Manager

+

Overview

+

The OpenStack Flavor Manager manages the creation, modification, and removal of flavors. +It operates as a facilitator that orchestrates compute flavors in alignment +with the standard SCS-0100: Flavor Naming +by utilizing YAML files provided by the SCS project.

+

Installation

+

The OpenStack Flavor Manager can be used via the OSISM CLI. This is the preferred way to use it. +No installation is then required. It is used via osism manage flavors.

+

For use independent of OSISM install the openstack-flavor-manager package with pip. It is likely +that additional dependencies such as pkg-config or libssl-dev must be installed in advance.

+
$ pip install openstack-flavor-manager
+

Or clone the repository osism/openstack-flavor-manager +and use the OpenStack Flavor Manager from source with tox.

+
$ tox -- --help
+

Usage

+

There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Flavor Manager +will be executed. When using the OSISM CLI, the files are expected in environments/openstack +in your configuration repository.

+

The cloud profile to be used can be specified via the optional --cloud parameter. +By default the cloud profile with the name admin is used. It must be possible to create and delete +flavors with the used cloud credentials.

+
$ openstack-flavor-manager --help

Usage: openstack-flavor-manager [OPTIONS]

╭─ Options ────────────────────────────────────────────────────────────────────────────────────╮
│ --name TEXT Name of flavor definitions. [default: scs] │
│ --debug Enable debug logging. │
│ --cloud TEXT Cloud name in clouds.yaml. [default: admin] │
│ --recommended Create recommended flavors. │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────╯
+

To create the mandatory flavors by the SCS-0100: Flavor Naming +standard, you run:

+
$ openstack-flavor-manager
+

To create the recommended flavors by the SCS Flavor Naming Standard, you run:

+
$ openstack-flavor-manager --recommended
+

The output should look like this:

+
2023-09-20 13:03:14 | INFO     | Flavor SCS-1V-4 created
2023-09-20 13:03:14 | INFO | Flavor SCS-2V-8 created
2023-09-20 13:03:14 | INFO | Flavor SCS-4V-16 created
2023-09-20 13:03:14 | INFO | Flavor SCS-8V-32 created
...
+

All recommended flavors are now be available in your OpenStack environment. +Check yourself by running:

+
$ openstack --os-cloud admin flavor list
+
$ openstack --os-cloud admin flavor show SCS-2V-4-20s
+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 0 |
| access_project_ids | None |
| description | None |
| disk | 20 |
| id | 652e3a6c-330e-4ee3-922b-b49c3c093062 |
| name | SCS-2V-4-20s |
| os-flavor-access:is_public | True |
| properties | hw_rng:allowed='true', scs:cpu-type='shared-core', scs:disk0-type='ssd', scs:name-v1='SCS-2V:4:20s', scs:name-v2='SCS-2V-4-20s' |
| ram | 4096 |
| rxtx_factor | 1.0 |
| swap | 0 |
| vcpus | 2 |
+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+
+

Definitions

+

There are two flavor definitions available by default. One for +SCS +and one for OSISM. +Each definition has its own set of mandatory and recommended flavors. The definition of OSISM contains +all definitions of SCS as well as some others.

+

To run the OpenStack Flavor Manager with a specific definition, either scs or osism, +use the optional --name parameter. By default the SCS-0100: Flavor Naming +standard definition will be used.

+
$ openstack-flavor-manager --name osism
+

Name parser and generator

+

A generator and parser for flavor names according to the SCS standard is available on +flavors.scs.community.

+

The flavor name SCS-2V-4-20s is inserted in field Flavor name:

+ +

The flavor SCS-2V-4-20s translated is +2 generic x86-64 vCPUs with 4.0 GiB RAM and SSD 20GB root volume:

+
+ + \ No newline at end of file diff --git a/docs/iaas/components/image-manager/index.html b/docs/iaas/components/image-manager/index.html new file mode 100644 index 0000000000..360a210d67 --- /dev/null +++ b/docs/iaas/components/image-manager/index.html @@ -0,0 +1,164 @@ + + + + + +Image Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Image Manager

+

The OpenStack Image Manager is a tool for managing all +images on an OpenStack environment

+

Requirements

+

This information is only relevant for the operator of an OpenStack environment. You can skip this section if +you want to use OpenStack Image Manager as a normal user and you are not an operator of an openStack environment.

+

OpenStack Image Service (Glance)

+

The OpenStack Image Service (Glance) is required to upload and discover data assets that are used by other +services.

+

Since this script stores many images in a single project, the Glance quota must be set accordingly high or to unlimited.

+
[DEFAULT]
user_storage_quota = 1TB
+

With most storage backends it makes sense to convert the imported images directly to RAW. So it is required for using Ceph and it's +features too. Recited from the Ceph documentation QEMU and block devices and +Block devices and OpenStack.

+
info

The raw data format is really the only sensible format option to use with RBD. Technically, you could use other QEMU-supported formats +(such as qcow2 or vmdk), but doing so would add additional overhead, and would also render the volume unsafe for virtual machine live +migration when caching (see below) is enabled.

Important Ceph doesn't support QCOW2 for hosting a virtual machine disk. Thus if you want to boot virtual machines in Ceph (ephemeral +backend or boot from volume), the Glance image format must be RAW.

See the OpenStack Glance documentation +for more details.

+

This requires the following parameter for the image import workflow.

+
[taskflow_executor]
conversion_format = raw

[image_import_opts]
image_import_plugins = ['image_decompression', 'image_conversion']

[image_conversion]
output_format = raw
+

Object storage backend

+

If the mirror functionality is used, an object storage backend is required. The use of the mirror functionality +is optional and is not used by default.

+

Getting started

+

This Getting started will upload a private image to your OpenStack environment with +the help of the OpenStack Image Manager.

+
    +
  1. +

    Install the openstack-image-manager package with +pip.

    +
    pip3 install openstack-image-manager
    +

    The installation can also be done via pipenv.

    +

    A Pipefile file is created with this content. The latest version of openstack-image-manager +is used.

    +
    [[source]]
    url = "https://pypi.org/simple"
    verify_ssl = true
    name = "pypi"

    [packages]
    openstack-image-manager = "==0.20240403.0"

    [dev-packages]

    [requires]
    python_version = "3.10"
    +

    The dependencies are then installed and the shell is prepared for use:

    +
    pipenv install
    pipenv shell
    +
  2. +
  3. +

    Create a image definition in the file getting-started.yml in the local directory images.

    +
    ---
    images:
    - name: MyCirros
    format: qcow2
    login: cirros
    password: gocubsgo
    min_disk: 1
    min_ram: 32
    status: active
    visibility: private
    multi: false
    meta:
    architecture: x86_64
    hw_disk_bus: scsi
    hw_rng_model: virtio
    hw_scsi_model: virtio-scsi
    hw_watchdog_action: reset
    os_distro: cirros
    replace_frequency: never
    uuid_validity: none
    provided_until: none
    tags: []
    versions:
    - version: "0.6.0"
    url: https://github.com/cirros-dev/cirros/releases/download/0.6.0/cirros-0.6.0-x86_64-disk.img
    checksum: "sha256:94e1e2c94dbbae7d4bdc38e68590a1daf73c9de2d03dd693857b4b0a042548e8"
    build_date: 2022-09-28
    +
  4. +
  5. +

    Run the OpenStack Image Manager. It is assumed that a profile with the name openstack exists in the +clouds.yaml.

    +
    openstack-image-manager --cloud openstack --filter ".*Cirr.*" --images images/
    +
  6. +
+

Image definitions

+

The configuration consists of different parameter settings, such as values for +minimum RAM or the visibility of the image. Have a look at the examples below +for all parameters. After a change to the configuration, validate it with +tox -- --dry-run.

+

SCS image standard

+
    +
  • The value of login is stored as image_original_user in the metadata of an image.
  • +
  • If image_description is not set as meta information, image_description is set to the name of the image.
  • +
  • The value of build_date of a specific version of an image is stored as image_build_date in the metadata of an image.
  • +
  • The value of url of a specific version of an image is stored as image_source in the metadata of an image.
  • +
+

Image with regular rebuilds

+

This type of image definition is used for images that are rebuilt at regular +intervals. For example, this is the case for the daily builds of the Ubuntu +images.

+

The attribute multi: true is set.

+

With this type of image definition, the version of the distribution (or product, +whatever is contained in the image) used is already in the name of the image +definition. The version properties from the definition's versions list +are appended only to older iterations of the image as timestamp suffixes +in parentheses upon each rotation (except for the latest entry).

+
images:
- name: Ubuntu 24.04
format: qcow2
login: ubuntu
min_disk: 8
min_ram: 512
status: active
visibility: public
multi: true
meta:
architecture: x86_64
hw_disk_bus: scsi
hw_scsi_model: virtio-scsi
hw_watchdog_action: reset
os_distro: ubuntu
os_version: '24.04'
tags: []
versions:
- version: '20240416'
url: https://cloud-images.ubuntu.com/noble/20240416/noble-server-cloudimg-amd64.img
- version: '20240422'
url: https://cloud-images.ubuntu.com/noble/20240422/noble-server-cloudimg-amd64.img
+

This configuration creates the following images:

+
    +
  • Ubuntu 24.04 (20240416)
  • +
  • Ubuntu 24.04
  • +
+

If a newer build is added, the following rotation takes place:

+
    +
  • Ubuntu 24.04 (20240416) does not change
  • +
  • Ubuntu 24.04 becomes Ubuntu 24.04 (20240422)
  • +
  • the new image becomes Ubuntu 24.04
  • +
+

By default the last three images will be visible. When a fourth image is added, the visibility of +the last image in the list is changed to community and the image can be deleted in the future.

+

Image without regular rebuild

+

This type of image definition is used for images that are not rebuilt. For example, +this is the case for the flatcar images. For each release of Flatcar there is exactly +one image which will not be rebuilt in the future.

+

The attribute multi: false is set.

+

With this type of image definition, the version of the distribution (or product, +whatever is contained in the image) used is not in the name of the image definition. +Instead, the version properties from the image definition's versions list +are appended as static version suffixes to the images' names.

+
images:
- name: RancherOS
format: qcow2
login: rancher
min_disk: 8
min_ram: 2048
status: active
visibility: public
multi: false
meta:
architecture: x86_64
hw_disk_bus: scsi
hw_scsi_model: virtio-scsi
hw_watchdog_action: reset
tags: []
versions:
- version: '1.3.0'
url: https://github.com/rancher/os/releases/download/v1.3.0/rancheros-openstack.img
- version: '1.4.0'
url: https://github.com/rancher/os/releases/download/v1.4.0/rancheros-openstack.img
- version: '1.4.1'
url: https://github.com/rancher/os/releases/download/v1.4.1/rancheros-openstack.img
+

This configuration creates the following images:

+
    +
  • RancherOS 1.3.0
  • +
  • RancherOS 1.4.0
  • +
  • RancherOS 1.4.1
  • +
+

If a new version is added, no rotation takes place. The new version is added +as RancherOS x.y.z. Here also the visibility of older images is not changed.

+

Other properties

+

Image properties

+
    +
  • Removal of properties is not yet possible
  • +
  • URL, name and format can not be changed
  • +
  • Any keys can be added to meta, these will be added to the image
  • +
  • Existing keys in meta can be changed, the same applies to min_disk +and min_ram
  • +
+

Image tags

+

image status

+
    +
  • deactivation: change status to deactivated
  • +
  • reactivation: change status to active
  • +
+

Image visibility

+

A full documentation about the visibility of images can be found in the Image visibility section in the +OpenStack Image Service API Documentation.

+
    +
  • public: set visibility to public
  • +
  • community: set visibility to community
  • +
  • shared: set visibility to shared
  • +
  • private: set visibility to private
  • +
+

Usage

+

Mirroring images

+

Since the upstreams often only keep their images for a short time, we mirror most of the images on REGIO.cloud. +This makes us independent of the availability of the images in the individual upstreams.

+

Updating images

+

Some of the images are automatically updated by a CI job. The latest available build at the time of the CI job execution is mirrored and +made available as the current version.

+

Currently, the following images are updated once a week (every Sunday at 0 am):

+
    +
  • Almalinux
  • +
  • CentOS
  • +
  • Debian
  • +
  • Rockylinux
  • +
  • Ubuntu
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/components/image-manager/update/index.html b/docs/iaas/components/image-manager/update/index.html new file mode 100644 index 0000000000..e122a3e224 --- /dev/null +++ b/docs/iaas/components/image-manager/update/index.html @@ -0,0 +1,45 @@ + + + + + +Image Manager update.py | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Image Manager update.py

+

Overview

+

The OpenStack Image Manager update.py Script updates the /etc/images/*.yaml files to the always latest release of the Distributions, set S3 Mirror Urls and uploads the Images to the mirror.

+

These updated yaml files are later processed by the Image Manger itself.

+

Installation

+

Prepare to use the update.py script.

+
git clone https://github.com/osism/openstack-image-manager/ 
cd openstack-image-manager
pipenv install
pipenv shell
+

Usage

+
python contrib/update.py --help

Usage: update.py [OPTIONS]

╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --debug Enable debug logging │
│ --dry-run Do not perform any changes │
│ --minio-access-key TEXT Minio access key [env var: MINIO_ACCESS_KEY] [default: None] │
│ --minio-secret-key TEXT Minio secret key [env var: MINIO_SECRET_KEY] [default: None] │
│ --minio-server TEXT Minio server [env var: MINIO_SERVER] [default: swift.services.a.regiocloud.tech] │
│ --minio-bucket TEXT Minio bucket [env var: MINIO_BUCKET] [default: openstack-images] │
│ --swift-prefix TEXT Swift prefix [env var: SWIFT_PREFIX] [default: swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/] │
│ --install-completion Install completion for the current shell. │
│ --show-completion Show completion for the current shell, to copy it or customize the installation. │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+
note
    +
  • At this time the update.py expects all yamls Files at /etc/images/, which can't be configured at the moment.
  • +
  • Mirroring can't be disabled at the moment.
  • +
+

Best is to run this Script by cron or a CI job, to update all Distribution Files periodically to the latest release and afterwards run Openstack Image Manager. +The Distribution Image yaml files must exists before running the script, you can use the files from Github repo at etc/images/ as template for your first run.

+
$ python contrib/update.py
2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/centos.yml
2024-04-24 09:29:44 | INFO | update_image:179 - Checking image CentOS Stream 9
2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-HEREBE\d+\.\dDRAGONS.x86_64.qcow2
2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cloud.centos.org/centos/9-stream/x86_64/images/CHECKSUM
2024-04-24 09:29:44 | INFO | get_latest_default:62 - Latest URL is now https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2
2024-04-24 09:29:44 | INFO | get_latest_default:63 - Latest filename is now CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2
2024-04-24 09:29:44 | INFO | update_image:192 - Checksum of current CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337
2024-04-24 09:29:44 | INFO | update_image:208 - Our checksum is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337
2024-04-24 09:29:44 | INFO | update_image:211 - Image CentOS Stream 9 is up-to-date, nothing to do
2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/debian.yml
2024-04-24 09:29:44 | INFO | update_image:179 - Checking image Debian 11
2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bullseye/latest/debian-11-genericcloud-amd64.raw
2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bullseye/latest/SHA512SUMS
2024-04-24 09:29:45 | INFO | update_image:192 - Checksum of current debian-11-genericcloud-amd64-20240211-1654.raw is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4
2024-04-24 09:29:45 | INFO | update_image:208 - Our checksum is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4
2024-04-24 09:29:45 | INFO | update_image:211 - Image Debian 11 is up-to-date, nothing to do
2024-04-24 09:29:45 | INFO | update_image:179 - Checking image Debian 12
2024-04-24 09:29:45 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.raw
2024-04-24 09:29:45 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS
2024-04-24 09:29:46 | INFO | update_image:192 - Checksum of current debian-12-genericcloud-amd64-daily-20240424-1727.raw is sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e
2024-04-24 09:29:46 | INFO | update_image:208 - Our checksum is sha512:5401f8c6361bb2a82c2c24b4b4606d95e77229152a80e61f9c613bc88e25de9257057d0ed68b0256b745c4059162a54970fe4a8daf456b2eb67b4f5db5c97fcc
2024-04-24 09:29:46 | INFO | update_image:229 - New values are {'version': '20240424', 'build_date': datetime.date(2024, 4, 24), 'checksum': 'sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e', 'url': 'https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240424-1727/debian-12-genericcloud-amd64-daily-20240424-1727.raw'}
2024-04-24 09:29:46 | INFO | main:300 - Processing file /etc/images/rockylinux.yml
2024-04-24 09:29:46 | INFO | update_image:179 - Checking image Rocky 9
2024-04-24 09:29:46 | INFO | update_image:182 - Latest download URL is https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2
2024-04-24 09:29:46 | INFO | update_image:185 - Getting checksums from https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2.CHECKSUM
2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current Rocky-9-GenericCloud.latest.x86_64.qcow2 is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651
2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651
2024-04-24 09:29:47 | INFO | update_image:211 - Image Rocky_9 is up-to-date, nothing to do
2024-04-24 09:29:47 | INFO | main:300 - Processing file /etc/images/ubuntu.yml
2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04
2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS
2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current jammy-server-cloudimg-amd64.img is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710
2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710
2024-04-24 09:29:47 | INFO | update_image:211 - Image Ubuntu_22.04 is up-to-date, nothing to do
2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04 Minimal
2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64.img
2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/minimal/releases/jammy/release/SHA256SUMS
2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current ubuntu-22.04-minimal-cloudimg-amd64.img is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65
2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65
2024-04-24 09:29:48 | INFO | update_image:211 - Image Ubuntu 22.04 Minimal is up-to-date, nothing to do
2024-04-24 09:29:48 | INFO | update_image:179 - Checking image Ubuntu 24.04
2024-04-24 09:29:48 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
2024-04-24 09:29:48 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/noble/current/SHA256SUMS
2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current noble-server-cloudimg-amd64.img is sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3
2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:d7ba8d5d1d073f2dc8351973bf4f35157c846a0ea6ee16fb2a9f45a78953e4a7
2024-04-24 09:29:48 | INFO | update_image:229 - New values are {'version': '20240423', 'build_date': datetime.date(2024, 4, 23), 'checksum': 'sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3', 'url': 'https://cloud-images.ubuntu.com/noble/20240423/noble-server-cloudimg-amd64.img'}
+

These yaml files are now extended with additional fields and the update.py will take care of the versions, checksum, url and build date to the latest release in the yaml file on every run.

+
    +
  • latest_checksum_url - URL of the distros checksum file
  • +
  • latest_url - URL of the distros latest image
  • +
  • mirror_url - URL of the Image File at the local S3 Mirror
  • +
+
someexample.yaml
---
images:
- name: Debian 12
enable: true
shortname: debian-12
format: qcow2
login: debian
min_disk: 8
min_ram: 512
status: active
visibility: public
multi: true
meta:
architecture: x86_64
hw_disk_bus: scsi
hw_rng_model: virtio
hw_scsi_model: virtio-scsi
hw_watchdog_action: reset
hypervisor_type: qemu
os_distro: debian
os_version: '12'
replace_frequency: quarterly
uuid_validity: last-3
provided_until: none
tags: []
latest_checksum_url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS
latest_url:
https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.qcow2
versions:
- build_date: 2024-04-11
checksum:
sha512:3d6f26616e2c8b705993ddef874232887cebe42f1e70fcc020827ac88e8990177d537d34538c71ae2afd3b8baca953fff71eaa7ef71e752e82532c93dcdca436
url:
https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240411-1714/debian-12-genericcloud-amd64-daily-20240411-1714.qcow2
mirror_url:
https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-images/debian-12/20240411-debian-12.qcow2
version: '20240411'

+ + \ No newline at end of file diff --git a/docs/iaas/components/index.html b/docs/iaas/components/index.html new file mode 100644 index 0000000000..82f64b41f0 --- /dev/null +++ b/docs/iaas/components/index.html @@ -0,0 +1,23 @@ + + + + + +Tools | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/components/openstack-health-monitor/index.html b/docs/iaas/components/openstack-health-monitor/index.html new file mode 100644 index 0000000000..295dcf5842 --- /dev/null +++ b/docs/iaas/components/openstack-health-monitor/index.html @@ -0,0 +1,278 @@ + + + + + +Setting up OpenStack health monitor on Debian | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Setting up OpenStack health monitor on Debian

+

Kurt Garloff, 2024-02-20

+

Intro

+

The development of openstack-health-monitor was done on openSUSE 15.x images, just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution.

+

Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here.

+

Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a successor project for the increasingly hard to maintain shell code, this may not be worth the trouble.

+

openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested. +The scenario is described in a bit more detail in the repository's README.md file.

+

The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the monitoring section of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up.

+

Setting up the driver VM

+

So we start a Debian 12 image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard; +the instructions use flavor names and image names from the SCS standards. +For many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack).

+

Internal vs external monitoring

+

There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor.

+

The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems.

+

Unprivileged operation

+

Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own.

+

If openstack availability zone list --compute fails for you without admin rights, please fix your openstack client. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Healh-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)

+

Driver VM via openstack CLI

+

The author prefers to setup the VM via openstack CLI tooling. He has working entries for all clouds he uses in his ~/.config/openstack/clouds.yaml and secure.yaml and has exported the OS_CLOUD environment variable to point to the cloud he is working on to set up the driver VM. The author uses the bash shell. All of this of course could be scripted.

+

So here we go

+
    +
  1. Create the network setup for a VM in a network oshm-network with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network.
  2. +
+
PUBLIC=$(openstack network list --external -f value -c Name)
openstack router create oshm-router
openstack router set --external-gateway $PUBLIC oshm-driver-router
openstack network create oshm-network
openstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet
openstack router add subnet oshm-router oshm-subnet
+
    +
  1. Create a security group that allows ssh and ping access
  2. +
+
openstack security group create sshping
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping
openstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping
+
    +
  1. Being at it, we also create the security group for grafana
  2. +
+
openstack security group create grafana
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana
+
    +
  1. To connect to the VM via ssh later, we create an SSH keypair
  2. +
+
openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key
chmod og-r ~/.ssh/oshm-key.pem
+

Rather than creating a new key (and storing and protecting the private key), we could have passed --public-key and used an existing keypair.

+
    +
  1. Look up Debian 12 image UUID.
  2. +
+
IMGUUID=$(openstack image list --name "Debian 12" -f value -c ID | tr -d '\r')
echo $IMGUUID
+

Sidenote: The tr command is there to handle broken tooling that embeds a trailing \r in the output.

+
    +
  1. Boot the driver VM
  2. +
+
openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver
+

Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing --block-device. See diskless flavor blog article. For flavors with local root disks, you could have used the --image $IMGUUID parameter instead.

+
    +
  1. Wait for it to boot (optional) +You can look at the boot log with openstack console log show oshm-driver or connect to it via VNC at the URL given by openstack console url show oshm-driver. You can of course also query openstack on the status openstack server list or openstack server show oshm-driver. You can also just create a simple loop:
  2. +
+
declare -i ctr=0 RC=0
while [ $ctr -le 120 ]; do
STATUS="$(openstack server list --name oshm-driver -f value -c Status)"
if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi
if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi
if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi
sleep 2
let ctr+=1
done
# return $RC
if [ $RC != 0 ]; then false; fi
+
    +
  1. Attach a floating IP so it's reachable from the outside.
  2. +
+
FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks |  sed "s@^[^:]*:[^']*'\([0-9\.]*\)'.*\$@\1@")
FIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)
echo $FIXEDIP $FIXEDPORT
openstack floating ip create --port $FIXEDPORT $PUBLIC
FLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")
echo "Floating IP: $FLOATINGIP"
+

Remember this floating IP address.

+
    +
  1. Connect to it via ssh
  2. +
+
ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP
+

On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)

+

All the following commands are performed on the newly started driver VM.

+

Configuring openstack CLI on the driver VM

+

We need to install the openstack client utilities.

+
sudo apt-get update
sudo apt-get install python3-openstackclient
sudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient
+

Configure your cloud access in ~/.config/openstack/clouds.yaml

+
clouds:
CLOUDNAME:
interface: public
identity-api-version: 3
#region_name: REGION
auth:
auth_url: KEYSTONE_ENDPOINT
project_id: PROJECT_UUID
#alternatively project_name and project_domain_name
user_domain_name: default
# change to your real domain
+

and secure.yaml (in the same directory)

+
clouds:
CLOUDNAME:
auth:
username: USERNAME
password: PASSWORD
+

The CLOUDNAME can be freely chosen. This is the value passed to the openstack CLI with --os-cloud or exported to your environment in OS_CLOUD. The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample clouds.yaml file that works (but lacks the password).

+

Protect your secure.yaml from being read by others: chmod 0600 ~/.config/openstack/secure.yaml.

+

If you are using application credentials instead of username, password to authenticate, you don't need to specify project_id nor project's nor user's domain names in clouds.yaml. Just (in secure.yaml):

+
clouds:
CLOUDNAME:
auth_type: v3applicationcredential
auth:
application_credential_id: APPCRED_ID
application_credential_secret: "APPCRED_SECRET"
+

Configure this to be your default cloud:

+
export OS_CLOUD=CLOUDNAME
+

You might consider adding this to your ~/.bashrc for convenience. Being at it, you might want to add export CLIFF_FIT_WIDTH=1 there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste).

+

Verify that your openstack CLI works:

+
openstack catalog list
openstack server list
+

You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases.

+

Custom CA

+

If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in /etc/ssl/certs/ca-certificates.crt. You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the debian user.

+

Add it to your clouds.yaml

+
clouds:
CLOUDNAME:
cacert: /PATH/TO/CACERT.CRT
[...]
+

If you want to allow api_monitor.sh to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:

+
export OS_CACERT=/PATH/TO/CACERT.CRT
+

Consider adding this to your ~/.bashrc as well.

+

Your first api_monitor.sh iteration

+

Checkout openstack-health-monitor:

+
sudo apt-get install git bc jq netcat-traditional tmux zstd
git clone https://github.com/SovereignCloudStack/openstack-health-monitor
cd openstack-health-monitor
+

You may want to start a tmux (or screen) session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect.

+

The script api_monitor.sh is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the README.md file.

+

It is good practice to use tmux. This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to screen over tmux.

+

You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:

+
export IMG="Debian 12"
export JHIMG="Debian 12"
./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1
+

Leave out the -LL if you don't have a working loadbalancer service or replace -LL with -LO if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources).

+

Feel free to study the meaning of all the command line parameters by looking at the README.md. (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)

+

This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs DOWN, BUILD, creating are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual openstack RESOURCE list and openstack RESOURCE show NAME and RESOURCE being something like router, network, subnet, port, volume, server, floating ip, loadbalancer, loadbalancer pool, loadbalancer listener, security group, keypair, image, ...)

+

The api_monitor.sh uses and APIMonitor_TIMESTAMP prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong. +TIMESTAMP is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time).

+

This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least -N 2 to test the ability of the router to route traffic between networks. So expect -n 6 to become -N 2 -n 6 for a very small single-AZ cloud or -n 12 for a large 3 AZ cloud region. So, re-run the api_monitor.sh with the target sizing.

+

Resource impact and charging

+

Note that api_monitor.sh uses small flavors (SCS-1V-2 for the N jump hosts and SCS-1L-1 for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors.

+

If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run api_monitor.sh in a loop (which you will) with say 10 VMs (e.g. -N 2 -n 8) in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference.

+

Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of openstack volume list, openstack volume show BROKEN_VOLUME, openstack loadbalancer list, openstack loadbalancer show BROKEN_LB.)

+

Using -w -1 makes api_monitor.sh wait for interactive input whenever an error occurs; this can be convenient for debugging.

+

Once you have single iterations working nicely, we can proceed.

+

Automating startup and cleanup

+

Typically, we run api_monitor.sh with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here.

+
#!/bin/bash
# run_CLOUDNAME.sh
# Do some global settings
export IMG="Debian 12"
export JHIMG="Debian 12"
#export OS_CACERT=/home/debian/ca-certificates.pem
# Additional settings to override flavors or to
# configure email addresses for sending alarms can be set here

# Does openstack CLI work?
openstack server list >/dev/null || exit 1
# Upload log files to this swift container (which you need to create)
#export SWIFTCONTAINER=OS-HM-Logfiles

# CLEANUP
echo "Finding resources from previous runs to clean up ..."
# Find Floating IPs
FIPLIST=""
FIPS=$(openstack floating ip list -f value -c ID)
for fip in $FIPS; do
FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")
if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_
"; fi
done
FIPLIST=$(echo "$FIPLIST" | grep -v '^$' | sort -u)
# Cleanup previous interrupted runs
SERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)
KEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)
VOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)
NETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)
LOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)
ROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)
SECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)
echo CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS
for ENV in $FIPLIST; do
echo "******************************"
echo "CLEAN $ENV"
bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV
echo "******************************"
done
TOCLEAN=$(echo "$SERVERS
$KEYPAIR
$VOLUMES
$NETWORK
$LOADBAL
$ROUTERS
$SECGRPS
" | grep -v '^$' | sort -u)
for ENV in $TOCLEAN; do
echo "******************************"
echo "CLEAN $ENV"
bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV
echo "******************************"
done

# Now run the monitor
#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"
exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"
+

Compared to the previous run, we have explicitly set two networks here -N 2 and rely on the iterations being passed in as command line arguments. Add parameter -t if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (-LO) in this example rather than the amphora based one (-LL).

+

You may use one of the existing run_XXXX.sh scripts as example. Beware: eMail alerting with ALARM_EMAIL_ADDRESS and NOTE_EMAIL_ADDRESS (and limiting with -a and -R ) and reporting data to telegraf (option -S) may be present in the samples. Make this script executable (chmod +x run_CLOUDNAME.sh).

+

We wrap a loop around this in run_in_loop.sh:

+
#!/bin/bash
# run_in_loop.sh
rm stop-os-hm 2>/dev/null
while true; do
./run_CLOUDNAME.sh -i 200
if test -e stop-os-hm; then break; fi
echo -n "Hit ^C to abort ..."
sleep 15; echo
done
+

Also make this executable (chmod +x run_in_loop.sh). +To run this automatically in a tmux window whenever the system starts, we follow the steps in the startup README.md

+

Change OS_CLOUD in startup/run-apimon-in-tmux.sh. (If you need to set OS_CACERT, also add it in this file and pass it into the windows.)

+

Activate everything:

+
mkdir -p ~/.config/systemd/user/
cp -p startup/apimon.service ~/.config/systemd/user/
systemctl --user enable apimon
systemctl --user start apimon
sudo loginctl enable-linger debian
tmux attach oshealthmon
+

This assumes that you are using the user debian for this monitoring and have checked out the repository at ~/openstack-health-monitor/. Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)

+

Changing parameters and restarting

+

If you want to change the parameters passed to api_monitor.sh, you best do this by editing run_CLOUDNAME.sh, potentially after testing it with one iteration before.

+

To make the change effective, you can wait until the current 200 iterations are completed and the run_in_loop.sh calls run_CLOUDNAME.sh again. You can also hit ^C in the tmux window that hasapi_monitor.sh running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ^C during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ^C twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ./run_in_loop.sh again.

+

You can also issue the systemctl --user stop apimon command; it will basically do the same thing: Send ^C and then wait for everything to be completed and tear down the tmux session. +After waiting for that to complete, you can start it again with systemctl --user start apimon.

+

Multiple instances

+

You can run multiple instances of api_monitor.sh on the same driver VM. In this case, you should rename run_in_loop.sh to e.g. run_in_loop_CLOUDNAME1.sh and call run_CLOUDNAME1.sh from there. Don't forget to adjust startup/run-apimon-in-tmux.sh and startup/kill-apimon-in-tmux.sh to start more windows.

+

It is not recommended to run multiple instances against the same OpenStack project however. While the api_monitor.sh script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the run_CLOUDNAME.sh script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations.

+

Alarming and Logs

+

eMail

+

If wanted, the api_monitor.sh can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the -a N and -R options. In order to enable sending emails from the driver VM, it needs to have postfix (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly.

+

Once you have configured postfix, you can enable eMail notifications using the option -e. Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ALARM_EMAIL_ADDRESSES and NOTE_EMAIL_ADDRESSES environment variables to api_monitor.sh, e.g. by setting it in the run_CLOUDNAME.sh.

+

Log files

+

api_monitor.sh writes a log file with the name APIMonitor_TIMESTAMP.log. It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (TIMESTAMP is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)

+

Note that api_monitor.sh does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties.

+

The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable SWIFTCONTAINER has been set (in run_COULDNAME.sh) when starting api_monitor.sh. the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER

+

After the 200 iterations, a .psv file (pipe-separated values) is created Stats.STARTTIME-ENDTIME.psv (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured).

+

Data collection and dashboard

+

See https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md

+

telegraf

+

To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:

+
sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key
echo "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list
sudo apt update
sudo apt -y install telegraf
+

In the config file /etc/telegraf/telegraf.conf, we enable

+
[[inputs.influxdb_listener]]
service_address = ":8186"

[[outputs.influxdb]]
urls = ["http://127.0.0.1:8086"]
+

and restart the service (sudo systemctl restart telegraf). +Enable it on system startup: sudo systemctl enable telegraf.

+

influxdb

+

We proceed to influxdb:

+
sudo apt-get install influxdb
+

In the configuration file /etc/influxdb/influxdb.conf, ensure that the http interface on port 8086 is enabled.

+
[http]
enabled = true
bind-address = ":8086"
+

Restart influxdb as needed with sudo systemctl restart influxdb. +Also enable it on system startup: sudo systemctl enable influxdb.

+

Add -S CLOUDNAME to your run_CLOUDNAME.sh script

+

You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter -S CLOUDNAME to the api_monitor.sh call in run_CLOUDNAME.sh. Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete).

+

grafana

+

Basic config

+

Finally grafana: We (still as root) follow https://www.server-world.info/en/note?os=Debian_12&p=grafana

+
sudo wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt -y install grafana
+

The config file /etc/grafana/grafana.ini needs some adjustments:

+
    +
  • Set the hostname in [server] section: domain = health.YOURCLOUD.sovereignit.cloud. Set the protocol = https if not enabled by default. +You can use a hostname of your liking, but we will need to create TLS certificates for this host. So we should have control over DNS TXT records for this domain if we want to use Let's Encrypt with DNSAUTH. The sovereignit.cloud domain is controlled by the SCS project team and has been used for a number of health mon instances. +In this same section, set cert_file = /etc/grafana/health-fullchain.pem and cert_key = /etc/grafana/health-key.pem. Ensure that both files are readable by root:grafana and that the key file is not world-readable.
  • +
  • Configure the admin access. In section [security], set the admin_user = admin and admin_password = SOME_SECRET_PASS which you keep private.
  • +
  • Allow local data sources (same section): data_source_proxy_whitelist = localhost:8088 localhost:8086
  • +
  • Let's disallow user signup (in section [users]): allow_sign_up = false and allow_org_create = false.
  • +
  • We do the OIDC connection with [auth.github] later.
  • +
+

We can now restart the service: sudo systemctl restart grafana-server. +Being at it, also enable it on system startup: sudo systemctl enable grafana-server.

+

You should now be able to access your dashboard on https://health.YOURCLOUD.sovereignit.de:3000 and log in via the configured username admin and your SOME_SECRET_PASS password.

+

Enable influx database in grafana

+

In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to http://localhost:8086 (despite this being the suggestion). Set the database name to telegraf. Save&test should succeed.

+

Importing the dashboard

+

Go to Home, Dashboards, New, Import. +Upload the dashboard .json file from the repository, user the Grafana-10 variant if you use Grafana 10 or newer.

+

In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.) +Save.

+

Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable).

+

No data displayed?

+

Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.

+

One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved.

+

Dashboard features

+

Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended.

+

The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously.

+

You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term.

+

github OIDC integration

+

The SCS providers do allow all github users that belong to the SovereignCloudStack organization to get Viewer access to the dashboards by adding a client_id and client_secret in the [github.auth] section that you request from the SCS github admins (github's oauth auth). This allows to exchange experience and to get a feeling for the achievable stability. (Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)

+

Alternative approach to install and configure the dashboard behind a reverse proxy

+

Install influxdb via apt: https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss +Install telegraf (same apt repo as influxdb): sudo apt update && sudo apt install telegraf +Install grafana: https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository

+

Prepare configuration by using the config files from the repository as an alternative to doing the changes manually (as described above):

+
sudo cp dashboard/telegraf.conf /etc/telegraf && sudo chown root:root /etc/telegraf/telegraf.conf && sudo chmod 0644 /etc/telegraf/telegraf.conf
sudo cp dashboard/config.toml /etc/influxdb && sudo chown root:influxdb /etc/influxdb/config.toml && sudo chmod 0640 /etc/influxdb/config.toml
sudo cp dashboard/grafana.ini /etc/grafana && sudo chown root:grafana /etc/grafana/grafana.ini && sudo chmod 0640 /etc/grafana/grafana.ini
+

These config files should work as long as the versions of telegraf, influxdb and grafana don't evolve too far from the ones used in the repository. (Otherwise refer to above instructions how to tweak the default config files.)

+

Changes to /etc/grafana/grafana.ini as we do tls termination at the reverse proxy:

+
    +
  • set protocol = http
  • +
  • comment out domain option (? FIXME) or set it to the hostname
  • +
  • comment out cert_* options
  • +
+

Also change the admin password in grafana.ini.

+

Changes to /etc/grafana/grafana.ini if github auth should not be used yet:

+
    +
  • comment out whole [auth.github] section for now (can be enabled later)
  • +
+

Restart services: sudo systemctl restart telegraf && sudo systemctl restart influxdb && sudo systemctl restart grafana-server

+

Configuration in grafana web gui:

+
    +
  • Login to grafana http(s)://<domain>:3000 with user admin and default password from /etc/grafana/grafana.ini and change password.
  • +
  • Create influxdb datasource with url http://localhost:8086 and database name telegraf.
  • +
  • Finally import dashboard dashboard/openstack-health-dashboard.json to grafana.
  • +
+

TODO:

+
    +
  • Reverse proxy (aka ingress) with Let's Encrypt cert
  • +
  • Github auth as described above
  • +
+

Maintenance

+

The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained.

+

Unattended upgrades

+

It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See https://wiki.debian.org/UnattendedUpgrades. If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and grafana (port 3000).

+

Updating openstack-health-monitor

+

You can just do a git update in the openstack-health-monitor directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ^C, see above in the restart section.

+

Backup

+

The system holds two things that you might consider valuable for long-term storage: +(1) The log files. These are compressed and uploaded to object storage if you enable the SWIFTCONTAINER setting, which probably means that these do not need any additional backing up then. +(2) The influx time series data. Back up the data in /var/lib/influxdb.

+

Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, clouds.yaml, etc. Be careful not to expose sensitive data by granting too generous access to your backed up files.

+

Troubleshooting

+

Debugging issues

+

In case there is trouble with your cloud, the normal course of action to analyze is as follows:

+
    +
  • Look at the dashboard (see above)
  • +
  • Connect to the driver VM and attach to the tmux session and look at the console output of api_monitor.sh
  • +
  • Analyze the logfile (locally on the driver VM or grab it from the object storage)
  • +
+

Analyzing failures

+

When VM instances are created successfully, but then end up in ERROR state, the api_monitor.sh does an explicit openstack server show, so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files.

+

Sometimes the VMs end up being ACTIVE as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail.

+

To gather more details, you can look at the console output openstack console log show VM (where VM is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ssh -i APIMonitor_XXXXX_JH.pem debian@FIP, whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP. Replace XXXXX with the number in your current APIMonitor prefix, FIP with the floating IP address of the responsible JumpHost and debian with the user name used by the images you boot. Use 223 to connect to the second VM in the network, 224 the third etc.

+

When logged in, look at /var/log/cloud-init-output.log and /var/log/cloud-init.log. You can find the metadata in /var/lib/cloud/instance/.

+

You will not have much time to look around -- the still running api_monitor.sh script does continue and clean things up again. So you might want to suspend it with ^Z (and continue it later with fg). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the run_CLOUDNAME.sh script as it would do cleanup against the running instance, but rather copy the api_monitor.sh command line from the bottom (without the exec), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach -w -1 to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work.

+

Cleaning things up

+

If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard).

+

There are a few things that may need support from a cloud admin:

+
    +
  • Volumes may end up permanently in a deleting or reserved state or may be in-use, attached to a VM that has long gone. The admin needs to set the state to error and then delete them.
  • +
  • Loadbalancers may end up in a PENDING_XXX state (XXX being CREATE, UPDATE or DELETE) without ever changing. This also needs the cloud admin to set the status to ERROR, so it can be cleaned up. amphorae are more prone to this than ovn LBs.
  • +
+

More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted.

+

The source of this document can be found in the SovereignCloudStack/openstack-health-monitor repository.

+

Author: SCS Community, License: CC by Attribution 4.0 International

+ + \ No newline at end of file diff --git a/docs/iaas/components/project-manager/index.html b/docs/iaas/components/project-manager/index.html new file mode 100644 index 0000000000..cfaafcbb52 --- /dev/null +++ b/docs/iaas/components/project-manager/index.html @@ -0,0 +1,86 @@ + + + + + +Project Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Project Manager

+

Overview

+

The OpenStack Project Manager manages the creation of Openstack Domains, Projects and Users.

+

Installation

+

Prepare to use the Openstack Project Manager.

+

During installation, ldap libraries are required under Linux; you should install libldap2-dev and libsasl2-dev beforehand.

+
git clone https://github.com/osism/openstack-project-manager
cd openstack-project-manager
pipenv install
pipenv shell
+

Defaults

+

create.py

+

The create.py command and his default options while executing the command.

+
 --admin-domain              default
--assign-admin-user true
--cloud admin
--create-admin-user true
--create-domain false
--create-user false
--domain-name-prefix true
--has-service-network false
--has-public-network true
--has-shared-images true
--internal-id unset
--random false
--managed-network-resources false
--name sandbox
--owner unset
--password unset
--password-length 16
--public-network public
--quota-class basic
--service-network-cidr unset
--quota-multiplier 1
--quota-multiplier-compute unset
--quota-multiplier-network unset
--quota-multiplier-storage unset
--quota-router 1
+

manage.py

+

The manage.py has also some defaults while executing and will touch all projects in your Openstack Cluster, if not --domain is used.

+
 --admin-domain        default
--assign-admin-user false
--classes etc/classes.yml
--domain unset
--dry-run false
--endpoints etc/endpoints.yml
--manage-endpoints false
--manage-homeprojects false
--name unset
+

Default Openstack Roles to users are set to member and load-balancer_member at this time, the behavior can only be changed in the code.

+

Usage

+

There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Project Manager will be executed, examples are provided within the git repository.

+

The cloud profile to be used can be specified via the optional --cloud parameter. By default the cloud profile with the name admin is used. It has to be and admin account, to create and modify domains, projects, users and quotas.

+

The Openstack Project Manager essentially consists of two parts, the create.py and the manage.py, there are more scripts for handling users using ldap which needs more configuration setup.

+

create.py

+

This command is used to create and modify domains, projects, users and quotas. As default the domain is used as prefix for all projects and users created for easy alloction in Openstack.

+
note

create.py can't delete once created objects, this must be done using Openstack commands to remove a project or domain.

+
python src/create.py -h
usage: create [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--create-admin-user] [--create-domain] [--create-user]
[--domain DOMAIN] [--domain-name-prefix] [--has-public-network] [--has-service-network] [--has-shared-images] [--internal-id INTERNAL_ID] [--managed-network-resources] [--name NAME]
[--noassign-admin-user] [--nocreate-admin-user] [--nocreate-domain] [--nocreate-user] [--nodomain-name-prefix] [--nohas-public-network] [--nohas-service-network]
[--nohas-shared-images] [--nomanaged-network-resources] [--norandom] [--owner OWNER] [--password PASSWORD] [--password-length PASSWORD_LENGTH] [--public-network PUBLIC_NETWORK]
[--quota-class QUOTA_CLASS] [--quota-multiplier QUOTA_MULTIPLIER] [--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE] [--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK]
[--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE] [--quota-router QUOTA_ROUTER] [--random] [--service-network-cidr SERVICE_NETWORK_CIDR]

options:
-h, --help show this help message and exit
--admin-domain ADMIN_DOMAIN
Admin domain
--assign-admin-user Assign admin user
--cloud CLOUD Managed cloud
--config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set
is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the
command-line.
--config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the
command-line.
--create-admin-user Create admin user
--create-domain Create domain only
--create-user Create user
--domain DOMAIN Domain
--domain-name-prefix Add domain name as prefix to the project name
--has-public-network Has public network infrastructure
--has-service-network
Has service network infrastructure
--has-shared-images Has shared images
--internal-id INTERNAL_ID
Internal ID
--managed-network-resources
Manage the network resources
--name NAME Projectname
--noassign-admin-user
The inverse of --assign-admin-user
--nocreate-admin-user
The inverse of --create-admin-user
--nocreate-domain The inverse of --create-domain
--nocreate-user The inverse of --create-user
--nodomain-name-prefix
The inverse of --domain-name-prefix
--nohas-public-network
The inverse of --has-public-network
--nohas-service-network
The inverse of --has-service-network
--nohas-shared-images
The inverse of --has-shared-images
--nomanaged-network-resources
The inverse of --managed-network-resources
--norandom The inverse of --random
--owner OWNER Owner of the project
--password PASSWORD Password
--password-length PASSWORD_LENGTH
Password length
--public-network PUBLIC_NETWORK
Public network
--quota-class QUOTA_CLASS
Quota class
--quota-multiplier QUOTA_MULTIPLIER
Quota multiplier
--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE
Quota multiplier compute
--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK
Quota multiplier network
--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE
Quota multiplier storage
--quota-router QUOTA_ROUTER
Quota router
--random Generate random names
--service-network-cidr SERVICE_NETWORK_CIDR
Service network CIDR
+

Create a Domain and inital project

+

When executing the create.py command, the first time with --domain, it will create a new domain, an admin account and the first project webshop. The admin account will be created in the default Domain of Openstack and can be used for the Service Provider to manager the complete domain.

+
$ python3 src/create.py --domain democompany --name webshop
+----------------+----------------------+----------------------------------+
| name | value | id |
|----------------+----------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-webshop | 645538bf67664cfeaed32476d58f95fb |
| admin | democompany-admin | cc8d6bf7b61d4199ba5a4230c4ec6d62 |
| admin_password | qawsEdfg2d45Fsxc | |
+----------------+----------------------+----------------------------------+
+

Create a User for a project

+
$ python3 src/create.py --domain democompany --name webshopuser --create-user             
+----------+-------------------------+----------------------------------+
| name | value | id |
|----------+-------------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-webshop | 5752b6701026478f9cac122fc54eb9cb |
| user | democompany-webshopuser | ce213655559d47d7800501124fed4d02 |
| password | vEvM9vgRESdffWE2 | |
+----------+-------------------------+----------------------------------+
+

Create additional project with unlimited quota

+
$ python3 src/create.py --domain democompany --name styles --quota-class unlimited
+----------+--------------------+----------------------------------+
| name | value | id |
|----------+--------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-styles | 666097e396fd4f9392d6aa55c76d8267 |
+----------+--------------------+----------------------------------+
+

Set quotas for a project

+

All quota information must be set as a property to the Openstack project within your Openstack Cluster, if no property is set, the basic quotaclass of etc/classes.yml will be applied. +It is possible to set a quota multiplier for any project.

+

The following command you set a multiplier of 256 of the basic quota:

+
$ openstack project set --property quotamultiplier=256 democompany-webshop
+

Adjusting gigabyte quota for storage with a multiplier of 20 of the basic quota for a project:

+
$ openstack project set  --property quotamultiplier_storage=20 democompany-webshop
+

This will override the general quotamultiplier only for storage.

+

Other possible multiplier which can be set individually are: quotamultiplier_compute, quotamultiplier_network, quota_router

+

To change the quotaclass to unlimited from the etc/classes.yaml

+
$ openstack project set  --property quotaclass=unlimited democompany-webshop
+

Special project: images

+

With this special Project you can share all images uploaded into this project to all other project in your domain which has set the property has-shared-images, which is by default set. +Alsoi only the domain-admin user has access to this project, other domain users won't see this, they will find the uploaded images in their projects. +If you want your grant other domain users also access to upload some images, you need to give them access to the images Project in Openstack.

+
$ python3 src/create.py --domain democompany --name images
+---------+---------------------+----------------------------------+
| name | value | id |
|---------+---------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-images | 6d57f39aacbe485d87733865b1e79d03 |
+---------+---------------------+----------------------------------+
+

Additionally you need to add the domain and domain-admin user to the clouds.yaml, it is always named opm-domainname-admin: so the manage.py can setup permissions to the projects later on and users are able to find the images.

+
  opm-democompany-admin:
auth:
auth_url: https://keystone.my.cloud:5000/v3
username: democompany-admin
password: yourpassword
user_domain_name: Default
project_domain_name: democompany
identity_api_version: 3
+

Special project: service

+

With this special project you can share installed services, like a harbor, to all other projects in your domain. Per default, only the domain admin has access to this project.

+
$ python3 src/create.py --domain democompany --name service
+---------+---------------------+----------------------------------+
| name | value | id |
|---------+---------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-service | a5558f7338f94adea5f41858636256b5 |
+---------+---------------------+----------------------------------+
+

manage.py

+
warning

This command applies quotas, networks and routers to all projects in the Openstack Cluster, not only to those have been configured previously with the create.py or openstack project set --property commands.

+

Best is to run this command by cron, every hour to apply all pending changes, it is also possible to run this at the command line to apply changes immediately.

+
python3 src/manage.py -h
usage: manage [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--classes CLASSES] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--domain DOMAIN] [--dry-run]
[--endpoints ENDPOINTS] [--manage-endpoints] [--manage-homeprojects] [--name NAME] [--noassign-admin-user] [--nodry-run] [--nomanage-endpoints] [--nomanage-homeprojects]

options:
-h, --help show this help message and exit
--admin-domain ADMIN_DOMAIN
Admin domain
--assign-admin-user Assign admin user
--classes CLASSES Path to the classes.yml file
--cloud CLOUD Cloud name in clouds.yaml
--config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set
is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the
command-line.
--config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the
command-line.
--domain DOMAIN Domain to be managed
--dry-run Do not really do anything
--endpoints ENDPOINTS
Path to the endpoints.yml file
--manage-endpoints Manage endpoints
--manage-homeprojects
Manage home projects
--name NAME Project to be managed
--noassign-admin-user
The inverse of --assign-admin-user
--nodry-run The inverse of --dry-run
--nomanage-endpoints The inverse of --manage-endpoints
--nomanage-homeprojects
The inverse of --manage-homeprojects
+

Manage a specific domain only

+
$ python3 src/manage.py --domain democompany

2024-04-19 14:24:02.873 | INFO | democompany - domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03
2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03, domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:04.953 | INFO | democompany-images - quotaclass {'compute': {'cores': 0, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 0, 'key_pairs': 0, 'metadata_items': 128, 'ram': 0, 'server_group_members': 0, 'server_groups': 0}, 'network': {'floatingip': 0, 'network': 0, 'port': 0, 'rbac_policy': 0, 'router': 0, 'security_group': 0, 'security_group_rule': 0, 'subnet': 0, 'subnetpool': 0}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 1000, 'per_volume_gigabytes': 25, 'snapshots': 0, 'volumes': 100}, 'parent': 'default'}
2024-04-19 14:24:04.953 | INFO | democompany-images - check network quota
2024-04-19 14:24:05.048 | INFO | democompany-images - check compute quota
2024-04-19 14:24:05.175 | INFO | democompany-images - check volume quota
2024-04-19 14:24:05.286 | INFO | democompany-images - check if external rbac policy must be deleted (public)
2024-04-19 14:24:05.349 | INFO | democompany-images - check if service rbac policy must be deleted (democompany-service)
2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5
2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5, domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:06.131 | INFO | democompany-service - quotaclass {'compute': {'cores': 256, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 256, 'key_pairs': 256, 'metadata_items': 128, 'ram': 262144, 'server_group_members': 256, 'server_groups': 256}, 'network': {'floatingip': 256, 'network': 256, 'port': 256, 'rbac_policy': 1024, 'router': 256, 'security_group': 256, 'security_group_rule': 1024, 'subnet': 256, 'subnetpool': 256}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 0, 'per_volume_gigabytes': 0, 'snapshots': 0, 'volumes': 0}, 'parent': 'default'}
2024-04-19 14:24:06.131 | INFO | democompany-service - check network quota
2024-04-19 14:24:06.212 | INFO | democompany-service - check compute quota
2024-04-19 14:24:06.330 | INFO | democompany-service - check volume quota
2024-04-19 14:24:06.467 | INFO | democompany-service - check if external rbac policy must be created (public)
2024-04-19 14:24:06.589 | INFO | democompany-service - check if service rbac policy must be deleted (democompany-service)
2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb
2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb, domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:06.915 | INFO | democompany-webshop - quotaclass {'compute': {'cores': 4, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': -1, 'key_pairs': 4, 'metadata_items': 128, 'ram': 8192, 'server_group_members': 4, 'server_groups': 4}, 'network': {'floatingip': 4, 'network': 1, 'port': 20, 'rbac_policy': 10, 'router': 0, 'security_group': 5, 'security_group_rule': 20, 'subnet': 2, 'subnetpool': 1}, 'volume': {'backup_gigabytes': 40, 'backups': 8, 'gigabytes': 20, 'per_volume_gigabytes': 200, 'snapshots': 4, 'volumes': 4}, 'parent': 'default'}
2024-04-19 14:24:06.915 | INFO | democompany-webshop - check network quota
2024-04-19 14:24:06.993 | INFO | democompany-webshop - check compute quota
2024-04-19 14:24:07.114 | INFO | democompany-webshop - check volume quota
2024-04-19 14:24:07.254 | INFO | democompany-webshop - check if external rbac policy must be created (public)
2024-04-19 14:24:07.334 | INFO | democompany-webshop - check if service rbac policy must be deleted (democompany-service)
+

Config files

+

The config files which can be used for create.py and manage.py are using the oslo.config format, you can set the command line options as key = value pair and create your own config files matching your setup.

+
democompany.conf
[DEFAULT]
cloud = admin
domain = democompany
+

Quota Templates

+

Edit the etc/classes.yml file if you want to change or add new quota templates

+

Setup Endpoints

+

Edit the etc/endpoints.yml file to fit your available endpoints

+ + \ No newline at end of file diff --git a/docs/iaas/components/resource-manager/index.html b/docs/iaas/components/resource-manager/index.html new file mode 100644 index 0000000000..c559a74825 --- /dev/null +++ b/docs/iaas/components/resource-manager/index.html @@ -0,0 +1,43 @@ + + + + + +Resource Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Resource Manager

+

Preparations

+

Prepare use of the OpenStack Resource Manager.

+
git clone https://github.com/osism/openstack-resource-manager
cd openstack-resource-manager
pipenv install
pipenv shell
+

Prepare cloud profile admin in clouds.yml and secure.yml (use clouds.yml.sample and secure.yml.sample +in the openstack-resource-manager repository as sample files).

+

Nova

+

Live migration

+

Live migrate all instances from compute node SOURCE to compute node TARGET.

+
python3 src/host-action.py --yes --disable --action live-migrate --host SOURCE --input TARGET
+

Evacuation

+

Evacuate all instances from compute node SOURCE to compute node TARGET.

+
python3 src/host-action.py --yes --action evacutate --host SOURCE --input TARGET
+

Octavia

+

Amphora rotation

+

Rotation of amphorae older than 30 days.

+
$ python3 src/amphora.py --rotate
2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa is older than 30 days
2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa of loadbalancer 9008d3d7-f593-4bc3-941c-a740c178148d is rotated by a loadbalancer failover
+

Cinder

+
$ python3 src/volume.py
2023-12-11 23:09:44 | INFO | Volume ad848454-ba1f-4c28-b9a8-edada17948b0 hangs in CREATING status for more than 2 hours
Delete volume ad848454-ba1f-4c28-b9a8-edada17948b0 [yes/no]:
+

Orphans

+
$ python3 src/orphan.py
2023-12-11 23:11:16 | INFO | Checking nova / server
2023-12-11 23:11:21 | INFO | Checking neutron / port
2023-12-11 23:11:23 | INFO | Checking neutron / router
2023-12-11 23:11:23 | INFO | Checking neutron / network
2023-12-11 23:11:24 | INFO | Checking neutron / subnet
2023-12-11 23:11:24 | INFO | Checking neutron / floatingip
2023-12-11 23:11:24 | INFO | Checking neutron / rbacpolicy
2023-12-11 23:11:24 | INFO | Checking neutron / securitygroup
2023-12-11 23:11:26 | INFO | Checking neutron / securitygrouprule
2023-12-11 23:11:27 | INFO | Checking glance / image
2023-12-11 23:11:30 | INFO | Checking glance / imagemember
[...]
+---------------+-------------------+--------------------------------------+----------------------------------+
| servicename | resourcename | resource_id | project_id |
|---------------+-------------------+--------------------------------------+----------------------------------|
| neutron | port | 561f8f76-18b0-470a-92cd-4336346b4b18 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | port | 6d1986e4-1e6d-4d4a-961d-97d372945bb1 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | port | 74f9bddc-9bfa-4d06-a147-ca87127e501e | 8268b05ef24b41d8806c0fe417576610 |
| neutron | port | f630a66b-7725-4a68-868b-caebbaf1c003 | 8268b05ef24b41d8806c0fe417576610 |
| neutron | router | c0c4e4aa-53ee-4fd1-8f53-84d52cf6c60b | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | router | c8f9a13b-adcd-4a8e-942b-338bcf4dde7c | 8268b05ef24b41d8806c0fe417576610 |
| neutron | network | 62d6ad2a-0cda-4d45-9325-963b8eb67000 | 8268b05ef24b41d8806c0fe417576610 |
| neutron | network | 63b8fea6-7d7b-40c3-9c31-bee4404a92d6 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | subnet | 0cd16262-330a-44ad-9160-daef84aded2d | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | subnet | 690dee14-ac12-464d-a911-a873c27ec818 | d33b0d15fd474131a335207216297a2a |
| neutron | subnet | 854e7c55-62e2-4679-9b18-805460b998ce | 8268b05ef24b41d8806c0fe417576610 |
| neutron | rbacpolicy | 00d7c2a2-6674-4f40-9f95-176a7858fcca | c8e4393b6d064a26a31014f82939172f |
| neutron | rbacpolicy | 0608c701-5b81-4712-989b-ba03cdcc255d | c8e4393b6d064a26a31014f82939172f |
[...]
| neutron | securitygrouprule | fd3c553f-168e-4c24-ab40-09aa934bab86 | 3a96207b719643ae9ea9a81d95116e9e |
| neutron | securitygrouprule | fdf337be-971c-4d5d-88ca-d90cdb468e88 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | securitygrouprule | ff8162fe-f053-49c9-8659-078061ce3e23 | d0b0add9ede0452791f71cb900e35242 |
| glance | imagemember | c7f2cb0c25d34c5d886ecaf483e5fda6 | c7f2cb0c25d34c5d886ecaf483e5fda6 |
| glance | imagemember | d4d0a161f9024fc8b517b0375eb97c89 | d4d0a161f9024fc8b517b0375eb97c89 |
| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |
| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |
| glance | imagemember | d33b0d15fd474131a335207216297a2a | d33b0d15fd474131a335207216297a2a |
| cinder | volume | e7c4b05c-b76a-40cc-8381-03262e57eb94 | 9b5f7f8ed70d410c81e3f45bf4e36498 |
+---------------+-------------------+--------------------------------------+----------------------------------+
+ + \ No newline at end of file diff --git a/docs/iaas/components/sandbox-manager/index.html b/docs/iaas/components/sandbox-manager/index.html new file mode 100644 index 0000000000..c2db3f3030 --- /dev/null +++ b/docs/iaas/components/sandbox-manager/index.html @@ -0,0 +1,23 @@ + + + + + +Sandbox Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/components/simple-stress/index.html b/docs/iaas/components/simple-stress/index.html new file mode 100644 index 0000000000..24211a9c93 --- /dev/null +++ b/docs/iaas/components/simple-stress/index.html @@ -0,0 +1,48 @@ + + + + + +Simple Stress | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Simple Stress

+

Overview

+

The OpenStack Simple Stress is a small stress test for your Openstack Cluster. You can use it for burnin tests or if you want to monitor your cluster perfomance. +It is able to start a predefined amount of Servers in specific networks in parallel and serial and removes them afterwards, so you can test your environment to the limits.

+

Installation

+

Prepare to use the Openstack Simple Stress.

+
git clone https://github.com/osism/openstack-simple-stress
cd openstack-simple-stress
pipenv install
pipenv shell
+

Defaults

+

The main.py command and his default options while executing the command.

+
 --cleanup       true
--cloud simple-stress
--compute-zone nova
--debug false
--delete true
--flavor SCS-2V-8
--floating false
--image Ubuntu 22.04
--interval 10 (seconds)
--keypair unset
--network simple-stress
--network-zone nova
--number 1
--parallel 1
--prefix simple-stress
--storage-zone simple-stress
--timeout 600 (seconds)
--volume false
--volume-number 1
--volume-size 1 (gigabyte)
--wait true
+

Usage

+

There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Simple Stress will be executed, examples are provided within the git repository.

+

The cloud profile to be used can be specified via the optional --cloud parameter. By default, the cloud profile with the name simple-stress is used.

+
$ python src/main.py -h
usage: main [-h] [--cleanup] [--cloud CLOUD] [--compute-zone COMPUTE_ZONE] [--config-dir DIR]
[--config-file PATH] [--debug] [--delete] [--flavor FLAVOR] [--floating] [--image IMAGE]
[--interval INTERVAL] [--keypair KEYPAIR] [--network NETWORK] [--network-zone NETWORK_ZONE]
[--nocleanup] [--nodebug] [--nodelete] [--nofloating] [--novolume] [--nowait]
[--number NUMBER] [--parallel PARALLEL] [--prefix PREFIX] [--storage-zone STORAGE_ZONE]
[--timeout TIMEOUT] [--volume] [--volume-number VOLUME_NUMBER] [--volume-size VOLUME_SIZE]
[--wait]

options:
-h, --help show this help message and exit
--cleanup
--cloud CLOUD Cloud name
--compute-zone COMPUTE_ZONE
Compute availability zone to use
--config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted,
so as to provide a predictable parse order if individual options are over-
ridden. The set is parsed after the file(s) specified via previous --config-
file, arguments hence over-ridden options in the directory take precedence. This
option must be set from the command-line.
--config-file PATH Path to a config file to use. Multiple config files can be specified, with
values in later files taking precedence. Defaults to None. This option must be
set from the command-line.
--debug
--delete
--flavor FLAVOR
--floating
--image IMAGE
--interval INTERVAL
--keypair KEYPAIR
--network NETWORK
--network-zone NETWORK_ZONE
Network availability zone to use
--nocleanup The inverse of --cleanup
--nodebug The inverse of --debug
--nodelete The inverse of --delete
--nofloating The inverse of --floating
--novolume The inverse of --volume
--nowait The inverse of --wait
--number NUMBER
--parallel PARALLEL
--prefix PREFIX
--storage-zone STORAGE_ZONE
Storage availability zone to use
--timeout TIMEOUT
--volume
--volume-number VOLUME_NUMBER
--volume-size VOLUME_SIZE
--wait
+

Running a small and simple test on your Openstack environment, using Ubuntu_22.04 image with the flavor of 2VCPUs and 8Gigabytes of RAM, starting 6 servers, 2 parallel each with a volume size of 20Gigabytes.

+
$ python src/main.py --network test-net --flavor SCS-2V-8 --image Ubuntu_22.04 --number 6 --parallel 2 --volume-size 20
2024-04-23 11:47:16 | INFO | Checking flavor SCS-2V-8
2024-04-23 11:47:17 | INFO | flavor.id = 926f952f-0714-4c55-92c2-7514191fecce
2024-04-23 11:47:17 | INFO | Checking image Ubuntu_22.04
2024-04-23 11:47:17 | INFO | image.id = 667649d6-e828-403b-8871-15dde7b9ce85
2024-04-23 11:47:17 | INFO | Checking network test-net
2024-04-23 11:47:18 | INFO | network.id = 9688192e-11dd-4618-a18c-99d3267f630a
2024-04-23 11:47:18 | INFO | Creating server simple-stress-0
2024-04-23 11:47:18 | INFO | Creating server simple-stress-1
2024-04-23 11:47:18 | INFO | Waiting for server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:18 | INFO | Waiting for server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:28 | INFO | Waiting for boot / test results of 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:29 | INFO | Waiting for boot / test results of e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:39 | INFO | Deleting server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:39 | INFO | Waiting for deletion of server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:39 | INFO | Deleting server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:40 | INFO | Waiting for deletion of server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:49 | INFO | Creating server simple-stress-2
2024-04-23 11:47:50 | INFO | Creating server simple-stress-3
2024-04-23 11:47:50 | INFO | Waiting for server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:47:51 | INFO | Waiting for server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:00 | INFO | Waiting for boot / test results of 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:48:01 | INFO | Waiting for boot / test results of a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:11 | INFO | Deleting server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:12 | INFO | Waiting for deletion of server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:12 | INFO | Deleting server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:48:12 | INFO | Waiting for deletion of server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:48:22 | INFO | Creating server simple-stress-4
2024-04-23 11:48:22 | INFO | Waiting for server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:22 | INFO | Creating server simple-stress-5
2024-04-23 11:48:23 | INFO | Waiting for server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:48:55 | INFO | Deleting server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:55 | INFO | Deleting server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:48:55 | INFO | Waiting for deletion of server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:55 | INFO | Waiting for deletion of server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:49:05 | INFO | Server 049bf974-b0fd-467f-aabd-3593b2a409a4 finished
2024-04-23 11:49:05 | INFO | Server e485697f-feae-458c-952d-000072374c3f finished
2024-04-23 11:49:05 | INFO | Server a098cc12-94ff-4036-bf42-4fc08287809f finished
2024-04-23 11:49:05 | INFO | Server 26595dd3-09d4-4758-8d1f-58a40b681d11 finished
2024-04-23 11:49:05 | INFO | Server 05b9f996-5a06-4359-b495-3463cc7b81e0 finished
2024-04-23 11:49:05 | INFO | Server 8d372de6-ca07-4afb-9e80-1589fd5242e8 finished
2024-04-23 11:49:05 | INFO | Runtime: 107.4460s
+

Using a config directory with configfiles to run the test.

+

Path to a config directory to pull *.conf files from. This file set is sorted, +so as to provide a predictable parse order if individual options are over-ridden. +The set is parsed after the file(s) specified via previous --config file, +arguments hence over-ridden options in the directory take precedence. This +option must be set from the command-line.

+
python src/main.py --config-dir /path/to/config-dir
+

Config files

+

The config files which can be used for main.py are using the oslo.config format, you can set the command line options as key = value pair and create your own config files matching your setup.

+
mytest.conf
[DEFAULT]
cloud = simple-stress
network = test-net
number = 6
parallel = 2
flavor = SCS-2V-8
image = Ubuntu_22.04
volume-size = 20
+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/ceph/index.html b/docs/iaas/guides/concept-guide/components/ceph/index.html new file mode 100644 index 0000000000..d53cdbc2cf --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/ceph/index.html @@ -0,0 +1,41 @@ + + + + + +Ceph | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Ceph

+

Ceph is an Open Source software defined storage platform designed to provide highly scalable +object, block and file-based storage in a unified system. Designed for flexibility, +Ceph integrates seamlessly with cloud infrastructures like OpenStack and supports +diverse workloads with robust, self-healing and self-managing capabilities.

+

Key benefits of Ceph include:

+
    +
  • Scalability: Ceph is designed to scale from terabytes to exabytes, easily meeting +the needs of small businesses to large enterprises.
  • +
  • Resilience: With built-in redundancy and data replication, Ceph ensures data +integrity and availability even in the face of hardware failures.
  • +
  • High performance: Using a distributed architecture, Ceph delivers high throughput +and low latency, making it ideal for high-demand workloads.
  • +
  • Cost-effective: As open source, Ceph eliminates licensing costs and its ability to +run on commodity hardware reduces CapEx.
  • +
  • Versatility: Ceph supports a variety of storage types - object, block and file - +on a single platform, simplifying storage management and reducing operational complexity.
  • +
+

Lifecycle Management of Ceph in OSISM

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/clusterapi/index.html b/docs/iaas/guides/concept-guide/components/clusterapi/index.html new file mode 100644 index 0000000000..82eea4670f --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/clusterapi/index.html @@ -0,0 +1,58 @@ + + + + + +Cluster API | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Cluster API

+

Kubernetes as a Service (KaaS) is a cloud service model that simplifies the deployment, +management and scaling of Kubernetes clusters. By abstracting the underlying infrastructure, +KaaS allows organisations to focus on developing and deploying applications without the +complexities of cluster management. One of the most powerful tools for implementing KaaS +is the Cluster API, an official Kubernetes project that provides declarative APIs and tools +for managing the lifecycle of Kubernetes clusters.

+

Key benefits of Cluster API include:

+
    +
  • Declarative Cluster Management: Cluster API allows users to define the desired state of +clusters using YAML manifests. This declarative approach simplifies the process of creating, +updating, and deleting clusters, making it easier to automate and version control cluster +configurations.
  • +
  • Infrastructure Abstraction: Cluster API abstracts the underlying infrastructure, enabling +the deployment of Kubernetes clusters across various environments, including public clouds +(AWS, Azure, GCP), private clouds (OpenStack), and on-premises data centers. This abstraction +ensures that the same API can be used regardless of the infrastructure provider.
  • +
  • Consistent Lifecycle Management: Cluster API standardizes the lifecycle management of +Kubernetes clusters, including provisioning, scaling, upgrading, and deletion. This consistency +reduces operational overhead and ensures that clusters are managed uniformly across different +environments.
  • +
  • Extensibility and Customization: Cluster API’s modular architecture allows for extensibility +through the use of custom resource definitions (CRDs) and controllers. Organizations can tailor +the API to meet specific requirements, such as integrating with existing CI/CD pipelines or +adding custom operational logic.
  • +
  • Improved Operational Efficiency: By leveraging Cluster API, organizations can automate repetitive +tasks, reduce human error, and ensure that clusters are configured according to best practices. +This automation leads to increased operational efficiency and faster delivery of applications.
  • +
+

By using Kubernetes as a Service with Cluster API, organisations can achieve a highly automated, +scalable and consistent approach to managing Kubernetes clusters across different environments. +This allows them to focus more on application development, and less on the operational +complexities of managing Kubernetes infrastructure.

+

Lifecycle Management of Cluster API in OSISM

+

Cluster API with OpenStack Magnum

+

Cluster API with SCS Cluster Stacks

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/gardener/index.html b/docs/iaas/guides/concept-guide/components/gardener/index.html new file mode 100644 index 0000000000..e67b5595c6 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/gardener/index.html @@ -0,0 +1,62 @@ + + + + + +Gardener | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Gardener

+

Kubernetes as a Service (KaaS) simplifies the deployment, management, and scaling of +Kubernetes clusters by abstracting the underlying infrastructure. Gardener by SAP is +an advanced KaaS solution that leverages a Kubernetes-native approach to manage +Kubernetes clusters at scale. Gardener is designed to provide consistent and efficient +cluster management across various cloud environments and on-premises data centers.

+

Key benefits of Gardener include:

+
    +
  • Kubernetes-Native Design: Gardener operates by treating Kubernetes clusters as first-class +citizens. It uses Kubernetes itself to orchestrate the deployment and management of other +Kubernetes clusters, ensuring that all operations are consistent and follow Kubernetes best +practices.
  • +
  • Shoot, Seed, and Garden Clusters: +
      +
    • Shoot Clusters: These are the user clusters managed by Gardener, running the workloads.
    • +
    • Seed Clusters: These clusters host the control planes of shoot clusters and are managed by +the Gardener infrastructure.
    • +
    • Garden Cluster: This is the central cluster where the Gardener components run and from which +all other clusters (seed and shoot) are managed.
    • +
    +
  • +
  • Multi-Cloud and Hybrid Cloud Support: Gardener supports deployment across various cloud providers, +including AWS, Azure, Google Cloud, and OpenStack, as well as on-premises environments. +This multi-cloud capability allows for a consistent Kubernetes experience regardless of the +underlying infrastructure.
  • +
  • Automated Cluster Management: Gardener automates the lifecycle management of Kubernetes clusters, +including provisioning, scaling, upgrading, and healing. This automation reduces operational +overhead and ensures clusters are always running optimally.
  • +
  • High Availability and Resilience: Gardener ensures high availability by distributing control +planes across multiple seed clusters and leveraging cloud provider features to enhance resilience. +This design minimizes downtime and enhances the reliability of managed clusters.
  • +
  • Extensibility and Customization: Gardener’s architecture allows for customization and extensibility +through extensions and webhooks. This flexibility enables organizations to tailor the solution to +meet specific requirements and integrate with existing tools and processes.
  • +
+

By using Gardener by SAP for Kubernetes as a Service, organisations can achieve a scalable, +automated and consistent approach to managing Kubernetes clusters across multiple environments. +This allows them to focus on delivering business value through their applications, rather +than dealing with the complexities of cluster management.

+

Lifecycle Management of Gardener in OSISM

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/index.html b/docs/iaas/guides/concept-guide/components/index.html new file mode 100644 index 0000000000..242fe459f0 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/index.html @@ -0,0 +1,37 @@ + + + + + +Components | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/ironic/index.html b/docs/iaas/guides/concept-guide/components/ironic/index.html new file mode 100644 index 0000000000..2535274184 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/ironic/index.html @@ -0,0 +1,59 @@ + + + + + +Ironic | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Ironic

+

OpenStack Ironic is a project that provides Baremetal as a Service (BMaaS), enabling the +provisioning and management of physical machines in a cloud-like manner. Unlike traditional +virtualization, where virtual machines run on top of a hypervisor, BMaaS allows users to +directly manage and utilize physical hardware, offering the full performance and isolation +of dedicated servers.

+

Key benefits of OpenStack Ironic:

+
    +
  • Hardware Provisioning: Ironic automates the provisioning of physical servers, including +the deployment of operating systems and configuration of hardware settings. This automation +streamlines the setup process, reducing the time and effort required to bring new servers +online.
  • +
  • Integration with OpenStack: Ironic integrates seamlessly with other OpenStack services, +such as Nova for compute management, Neutron for networking, and Glance for image services. +This integration allows users to manage both virtual and baremetal resources through a +unified OpenStack dashboard.
  • +
  • Support for Multiple Hardware Drivers: Ironic supports a wide range of hardware through +various drivers, including IPMI, Redfish, and vendor-specific drivers. This flexibility +ensures compatibility with a diverse set of hardware platforms and management interfaces.
  • +
  • Resource Management and Scheduling: Ironic leverages OpenStack’s scheduling capabilities +to manage the allocation of physical servers, ensuring optimal utilization of hardware +resources. Users can request specific hardware configurations and Ironic will match these +requests with available resources.
  • +
  • Provisioning States: Ironic manages the lifecycle of baremetal nodes through various +provisioning states, such as enroll, available, active, and maintenance. This state +management ensures that hardware is correctly tracked and managed throughout its lifecycle.
  • +
  • Network Integration: Ironic integrates with Neutron to provide networking services for +baremetal nodes, including support for VLANs, flat networks, and more complex networking +setups. This integration ensures that baremetal nodes can be seamlessly integrated into +existing network topologies.
  • +
+

By utilizing OpenStack Ironic, organizations can leverage the benefits of BMaaS, +providing users with the performance and control of physical hardware while maintaining +the flexibility and scalability of cloud infrastructure. This approach is particularly +beneficial for workloads that require high performance, low latency, or specific hardware +configurations that are not achievable with virtual machines.

+

Lifecycle Management of Ironic in OSISM

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/k3s/index.html b/docs/iaas/guides/concept-guide/components/k3s/index.html new file mode 100644 index 0000000000..56d3f08c55 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/k3s/index.html @@ -0,0 +1,24 @@ + + + + + +K3S | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/keycloak/index.html b/docs/iaas/guides/concept-guide/components/keycloak/index.html new file mode 100644 index 0000000000..b555fa34b1 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/keycloak/index.html @@ -0,0 +1,24 @@ + + + + + +Keycloak | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/netdata/index.html b/docs/iaas/guides/concept-guide/components/netdata/index.html new file mode 100644 index 0000000000..05e798bd36 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/netdata/index.html @@ -0,0 +1,24 @@ + + + + + +Netdata | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/openstack/index.html b/docs/iaas/guides/concept-guide/components/openstack/index.html new file mode 100644 index 0000000000..6932072dc9 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/openstack/index.html @@ -0,0 +1,35 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

OpenStack

+

Lifecycle Management of OpenStack in OSISM

+

The open source project Kolla from the OpenInfra Foundation is +used in OSISM for the life cycle management of OpenStack. Kolla’s mission is to provide +production-ready containers and deployment tools for operating OpenStack clouds. Kolla has +been actively developed by a very diverse team for 10 years and is one of the most common +(if not the most common) life cycle management tool for OpenStack.

+

The container images provided by Kolla are not only used by Kolla itself. They are also used +in TripleO, the basis for the now discontinued +RedHat OpenStack Platform, +and the OpenStack Kubernetes Operators, +the basis for the new +OpenStack Services on OpenShift from Redhat.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/prometheus/index.html b/docs/iaas/guides/concept-guide/components/prometheus/index.html new file mode 100644 index 0000000000..d8456c8923 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/prometheus/index.html @@ -0,0 +1,25 @@ + + + + + +Prometheus & Grafana | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/proxmox/index.html b/docs/iaas/guides/concept-guide/components/proxmox/index.html new file mode 100644 index 0000000000..037bb5e701 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/proxmox/index.html @@ -0,0 +1,62 @@ + + + + + +Proxmox VE | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Proxmox VE

+

Proxmox Virtual Environment (Proxmox VE) is an open-source server virtualization management +platform designed to manage virtual machines (VMs), containers, and software-defined storage. +Leveraging the power of KVM (Kernel-based Virtual Machine) for full virtualization and LXC +(Linux Containers) for containerization, Proxmox VE provides a robust and flexible solution +for enterprise virtualization needs.

+

Key benefits of Proxmox VE:

+
    +
  • Comprehensive Virtualization: +
      +
    • KVM Virtual Machines: Proxmox VE supports KVM-based virtualization, allowing users to run +multiple, isolated VMs on a single physical server. KVM provides near-native performance +and supports various operating systems, including Windows, Linux, and BSD.
    • +
    • LXC Containers: For lightweight virtualization, Proxmox VE uses LXC containers, which share +the host’s kernel but maintain isolated user spaces. This approach is ideal for runningx +Linux-based applications with minimal overhead.
    • +
    +
  • +
  • Integrated Management Interface: Proxmox VE includes a web-based management interface, enabling +administrators to manage VMs, containers, storage, and network configurations from a single, +intuitive dashboard. This interface supports various administrative tasks, including VM creation, +backup scheduling, and live migration.
  • +
  • High Availability (HA) and Clustering: Proxmox VE supports clustering, allowing multiple Proxmox +servers to be managed as a single entity. Clustering facilitates high availability by automatically +restarting VMs or containers on other nodes in the event of hardware failure, ensuring minimal downtime.
  • +
  • Storage Options: Proxmox VE offers flexible storage management with support for local storage, +shared storage (NFS, iSCSI, Ceph), and distributed storage systems. The built-in Proxmox VE storage +replication feature ensures data redundancy and high availability.
  • +
  • Backup and Restore: Proxmox VE includes integrated backup tools, supporting scheduled backups of VMs +and containers. These backups can be stored locally or on remote storage solutions, and can be restored +easily via the management interface.
  • +
  • Networking: Proxmox VE supports advanced networking features, including VLANs, bridges, and bonding. +This allows for complex network topologies and efficient use of network resources. The platform also +integrates seamlessly with SDN (Software-Defined Networking) solutions for enhanced network management.
  • +
+

By using Proxmox VE, organizations can leverage a powerful, open-source virtualization platform +that combines the benefits of both KVM and LXC. Proxmox VE’s comprehensive feature set, +intuitive management interface, and robust high availability options make it an ideal choice for +managing virtualized environments efficiently and effectively.

+

Lifecycle Management of Proxmox VE in OSISM

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/sonic/index.html b/docs/iaas/guides/concept-guide/components/sonic/index.html new file mode 100644 index 0000000000..44fbc3d8bb --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/sonic/index.html @@ -0,0 +1,26 @@ + + + + + +SONiC & OVN | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/components/teleport/index.html b/docs/iaas/guides/concept-guide/components/teleport/index.html new file mode 100644 index 0000000000..daa30a5715 --- /dev/null +++ b/docs/iaas/guides/concept-guide/components/teleport/index.html @@ -0,0 +1,24 @@ + + + + + +Teleport | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/design/index.html b/docs/iaas/guides/concept-guide/design/index.html new file mode 100644 index 0000000000..0c76ecfec3 --- /dev/null +++ b/docs/iaas/guides/concept-guide/design/index.html @@ -0,0 +1,31 @@ + + + + + +Cluster design | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/hardware-bom/index.html b/docs/iaas/guides/concept-guide/hardware-bom/index.html new file mode 100644 index 0000000000..80ba27fec4 --- /dev/null +++ b/docs/iaas/guides/concept-guide/hardware-bom/index.html @@ -0,0 +1,135 @@ + + + + + +Hardware Bill of Materials | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Hardware Bill of Materials

+
info

The brands, models and configurations listed are examples. There is no +single best specification for building a cluster. It always depends very +much on the requirements of the cluster and the situation. The examples +are not minimal and include various preferences of ours. The choice of +hardware always depends very much on the requirements, the available budget +and also the future plans of the cluster. There is no universal hardware +recommendation that fits all cases. These are all just examples.

+

Control nodes

+

A control node is responsible for running all or most of the OpenStack +services that manage API services and their associated runtimes. These +nodes are essential for users to interact with the cluster and maintain +its managed state.

+

However, control nodes typically do not run user virtual machines. It is +therefore advisable to replicate the control nodes to ensure high availability +and fault tolerance. A good starting point for achieving RAFT quorum is to have +three control nodes.

+
    +
  • 2x SSD with at least 480 GByte for the operating system
  • +
  • 4x NVMe with at least 960 GByte for the services
  • +
  • 128 GByte memory (it should be possible to upgrade to 256 GByte, or use 256 +GByte directly)
  • +
  • Dual port NIC with 25G or 100G (depending on which leaf switches are used)
  • +
  • 2 CPU sockets each with at least 32 cores or 1 CPU socket with at least 64 cores
  • +
+

Real world example:

+ +

Compute nodes

+

Compute nodes are dedicated to running users' virtual machines. They do not +host API services, storage services or network routers, other than the basic +network infrastructure required to connect virtual machines.

+
    +
  • 2x SSD or NVMe with at least 480 GByte for the operating system
  • +
  • 2x NVMe with at least 1.92 TByte for local storage recommended (if this is not implemented +at the start, the model should be selected so that NVMe devices can be added later, +the size depends on which CPU and how much memory is used, 7.68 TByte is more likely to be used)
  • +
  • Dual port NIC with 25G or 100G (depending on which leaf switches are used)
  • +
  • CPU sockets and memory depends on the requirement
  • +
+

Real world example:

+ +

Storage nodes

+

A dedicated storage node runs only storage services. This can be necessary in larger +deployments to protect the storage services from ressource starvation through user +workloads.

+

Read the Ceph hardware recommendations first.

+
    +
  • 2x SSD or NVMe with at least 480 GByte for the operating system
  • +
  • Dual port NIC with 100G (we recommend always using 100G for storage nodes)
  • +
  • Storage devices depends on the requirement
  • +
  • CPU sockets and memory depends on the storage devices used
  • +
+

Network nodes

+

A dedicated network node runs only network services. This is normally necessary to be +able to map safety zones. External networks terminate on the network nodes.

+

Real world example:

+
    +
  • +

    Supermicro SuperServer SYS-110D-8C-FRAN8TP

    +
      +
    • 2x SSD or NVMe with at least 480 GByte for the operating system
    • +
    • 2x DIMM slots with 32 GByte modules, leave 2 DIMM slots open for later expansion
    • +
    • If required, an additional dual port 25G or 100G NIC in the PCIe expansion slots
    • +
    • Intel Xeon Processor D-2733NT (this is onboard and not selectable)
    • +
    +
  • +
+

Manager nodes

+

The manager node, also known as the deploy node or deployment node, is designated +to manage the deployment process of all services. It is often also utilized to host +components of the monitoring services. It serves as the operator's entry point into +the cluster for operations.

+
    +
  • 2x SSD or NVMe with at least 1.92 TByte for the operating system and the services
  • +
  • 64 GByte memory (it should be possible to upgrade to 128 GByte, or use 128 GByte directly)
  • +
  • Dual port NIC with 25G or 100G (depending on which leaf switches are used)
  • +
  • 1 CPU socket with at least 16 cores
  • +
+

Real world example:

+ +

Switches

+

Management switches

+ +

Leaf switches

+

It is recommended to always use 100G for the data plane and the storage nodes. +Especially when using all-flash storage nodes, there is then enough bandwidth +available. The more and the larger flash devices you use, the more bandwidth is +required.

+

With the leaf switches for the compute plane, it depends on how large the compute +nodes are. The more CPU sockets/cores and the more memory the compute nodes have, +the more bandwidth is required on the compute nodes. Depending on how large the racks +are (or better how much power you can use in it), it may make sense to work with 100G +switches for the compute plane or with 25G switches if 4x 25G per compute node are used +instead of 2x 25G per compute node (if the compute nodes are large enough).

+ +

Spine switches

+ +

Network interface cards

+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/index.html b/docs/iaas/guides/concept-guide/index.html new file mode 100644 index 0000000000..3755dd1ac9 --- /dev/null +++ b/docs/iaas/guides/concept-guide/index.html @@ -0,0 +1,72 @@ + + + + + +Concept Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/layers/index.html b/docs/iaas/guides/concept-guide/layers/index.html new file mode 100644 index 0000000000..1a2fd334de --- /dev/null +++ b/docs/iaas/guides/concept-guide/layers/index.html @@ -0,0 +1,29 @@ + + + + + +Layers in a cluster | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/concept-guide/use-cases/index.html b/docs/iaas/guides/concept-guide/use-cases/index.html new file mode 100644 index 0000000000..7dd0471083 --- /dev/null +++ b/docs/iaas/guides/concept-guide/use-cases/index.html @@ -0,0 +1,24 @@ + + + + + +Use cases | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/ceph/index.html b/docs/iaas/guides/configuration-guide/ceph/index.html new file mode 100644 index 0000000000..a67353cd64 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/ceph/index.html @@ -0,0 +1,325 @@ + + + + + +Ceph | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Ceph

+

The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/

+

It is strongly advised to use the documentation for the version being used.

+ +

Unique Identifier

+

The File System ID is a unique identifier for the cluster. +The identifier is set via the parameter fsid in environments/ceph/configuration.yml +and must be unique. It can be generated with uuidgen.

+
environments/ceph/configuration.yml
fsid: c2120a4a-669c-4769-a32c-b7e9d7b848f4
+

Client

+

The client.admin keyring is placed in the file environments/infrastructure/files/ceph/ceph.client.admin.keyring.

+

Swappiness

+

The swappiness is set via the os_tuning_params dictionary. The dictionary can +only be completely overwritten via an entry in the file environments/ceph/configuration.yml.

+

By default, the dictionary looks like this:

+
os_tuning_params:
- { name: fs.file-max, value: 26234859 }
- { name: vm.zone_reclaim_mode, value: 0 }
- { name: vm.swappiness, value: 10 }
- { name: vm.min_free_kbytes, value: "{{ vm_min_free_kbytes }}" }
+

The sysctl paremeters are written to the file /etc/sysctl.d/ceph-tuning.conf +on the storage nodes.

+
# cat /etc/sysctl.d/ceph-tuning.conf
fs.aio-max-nr=1048576
fs.file-max=26234859
vm.zone_reclaim_mode=0
vm.swappiness=10
vm.min_free_kbytes=4194303
+

RGW service

+
    +
  1. +

    Add following configuration in environments/ceph/configuration.yml

    +
    environments/ceph/configuration.yml
    ceph_conf_overrides:
    "client.rgw.{{ hostvars[inventory_hostname]['ansible_hostname'] }}.rgw0":
    "rgw content length compat": "true"
    "rgw enable apis": "swift, s3, admin"
    "rgw keystone accepted roles": "member, admin"
    "rgw keystone accepted admin roles": "admin"
    "rgw keystone admin domain": "default"
    "rgw keystone admin password": "{{ ceph_rgw_keystone_password }}"
    "rgw keystone admin project": "service"
    "rgw keystone admin tenant": "service"
    "rgw keystone admin user": "ceph_rgw"
    "rgw keystone api version": "3"
    "rgw keystone url": "https://api-int.testbed.osism.xyz:5000"
    "rgw keystone verify ssl": "false"
    "rgw keystone implicit tenants": "true"
    "rgw s3 auth use keystone": "true"
    "rgw swift account in url": "true"
    "rgw swift versioning enabled": "true"
    +

    If the ceph_conf_overrides parameter already exists in environments/ceph/configuration.yml, +expand it and do not overwrite it.

    +

    If self-signed SSL certificates are used, two additional parameters must be set.

    +
    environments/ceph/configuration.yml
     "rgw keystone verify ssl": "false"
    "rgw verify ssl": "false"
    +

    For all possible configuration parameters visit the +Ceph configuration reference.

    +
  2. +
  3. +

    Add the ceph_rgw_keystone_password from environments/kolla/secrets.yml to +environments/ceph/secrets.yml.

    +
  4. +
  5. +

    Add following configuration in environments/kolla/configuration.yml

    +
    environments/kolla/configuration.yml
    enable_ceph_rgw: true
    enable_ceph_rgw_keystone: true

    ceph_rgw_swift_compatibility: false
    ceph_rgw_swift_account_in_url: true
    +
  6. +
  7. +

    On the nodes on which the RGW service is to be deployed, radowsgw_interface or +radosgw_address must be set in the host vars for the nodes in the inventory. +If radowsgw_interface is used, the first IPv4 address on this interface is used.

    +
    ##########################################################
    # ceph

    radosgw_address: 192.168.16.10
    +
  8. +
  9. +

    The nodes on which the RGW service is to be deployed can be defined in inventory group +ceph-rgw. By default, the RGW services are deployed on the Ceph control nodes..

    +
    inventory/20-roles
    [ceph-rgw:children]
    ceph-control
    +
  10. +
+

Extra pools

+

Extra pools can be defined via the openstack_pools_extra parameter.

+
inventory/group_vars/generic/ceph.yml
openstack_cinder_extra001_pool:
name: extra001
pg_num: "{{ openstack_pool_default_pg_num }}"
pgp_num: "{{ openstack_pool_default_pg_num }}"
rule_name: "replicated_rule"
min_size: "{{ openstack_pool_default_min_size }}"
application: "rbd"

openstack_pools_extra:
- "{{ openstack_cinder_extra001_pool }}"
+

If more than one Ceph cluster is managed with one manager, do not place the +parameters in inventory/group_vars/generic but in a corresponding directory.

+

If, for example, the inventory group of the Ceph cluster on which the additional +pools are to be created is ceph.rbd, then the parameters would be stored in +inventory/group_vars/ceph.rbd.yml accordingly.

+
ParameterDefault value
openstack_pool_default_pg_num64
openstack_pool_default_min_size0
+

LVM devices

+

For more advanced OSD layout requirements leave out the devices key +and instead use lvm_volumes. Details for this can be found on the +OSD Scenario documentation.

+

In order to aid in creating the lvm_volumes config entries and provision the LVM devices for them, +OSISM has the two playbooks ceph-configure-lvm-volumes and ceph-create-lvm-devices available.

+
    +
  1. +

    For each Ceph storage node edit the file inventory/host_vars/<nodename>.yml +add a configuration like the following to it. Ensure that no devices parameter +is present in the file.

    +
      +
    1. +

      Parameters

      +
        +
      • +

        With the optional parmaeter ceph_osd_db_wal_devices_buffer_space_percent it is possible to +set the percentage of VGs to leave free. The parameter is not set by default. Can be helpful +for SSD performance of some older SSD models or to extend lifetime of SSDs in general.

        +
        ceph_osd_db_wal_devices_buffer_space_percent: 10
        +
      • +
      • +

        It is possible to configure the devices to be used with the parameters ceph_osd_devices, +ceph_db_devices, ceph_wal_devices, and ceph_db_wal_devices. This is described below.

        +
      • +
      • +

        It is always possible to use device names such as sda or device IDs such as +disk/by-id/wwn-<something> or disk/by-id/nvme-eui.<something>. /dev/ is not +prefixed and is added automatically.

        +
      • +
      • +

        The db_size parameter is optional and defaults to (VG size - buffer space (if enabled)) / num_osds.

        +
      • +
      • +

        The wal_size parameter is optional and defaults to 2 GB.

        +
      • +
      • +

        The num_osds parameter specifies the maximum number of OSDs that can be assigned to a WAL device or DB device.

        +
      • +
      • +

        The optional parameter wal_pv can be used to set the device that is to be used as the WAL device.

        +
      • +
      • +

        The optional parameter db_pv can be used to set the device that is to be used as the DB device.

        +
      • +
      +
    2. +
    3. +

      OSD only

      +

      The sda device will be used as an OSD device without WAL and DB device.

      +
      ceph_osd_devices:
      sda:
      +
    4. +
    5. +

      OSD + DB device

      +

      The nvme0n1 device will be used as an DB device. It is possible to use this DB device for up to 6 OSDs. Each +OSD is provided with 30 GB.

      +
      ceph_db_devices:
      nvme0n1:
      num_osds: 6
      db_size: 30 GB
      +

      The sda device will be used as an OSD device with nvme0n1 as DB device.

      +
      ceph_osd_devices:
      sda:
      db_pv: nvme0n1
      +
    6. +
    7. +

      OSD + WAL device

      +

      The nvme0n1 device will be used as an WAL device. It is possible to use this WAL device for up to 6 OSDs. Each +OSD is provided with 2 GB.

      +
      ceph_wal_devices:
      nvme0n1:
      num_osds: 6
      wal_size: 2 GB
      +

      The sda device will be used as an OSD device with nvme0n1 as WAL device.

      +
      ceph_osd_devices:
      sda:
      wal_pv: nvme0n1
      +
    8. +
    9. +

      OSD + DB device + WAL device (same device for DB + WAL)

      +

      The nvme0n1 device will be used as an DB device and a WAL device. It is possible to use those devices for up +to 6 OSDs.

      +
      ceph_db_wal_devices:
      nvme0n1:
      num_osds: 6
      db_size: 30 GB
      wal_size: 2 GB
      +

      The sda device will be used as an OSD device with nvme0n1 as DB device and nvme0n1 as WAL device.

      +
      ceph_osd_devices:
      sda:
      db_pv: nvme0n1
      wal_pv: nvme0n1
      +
    10. +
    11. +

      OSD + DB device + WAL device (different device for DB + WAL)

      +

      The nvme0n1 device will be used as an DB device. It is possible to use this DB device for up to 6 OSDs. Each +OSD is provided with 30 GB.

      +
      ceph_db_devices:
      nvme0n1:
      num_osds: 6
      db_size: 30 GB
      +

      The nvme1n1 device will be used as an WAL device. It is possible to use this WAL device for up to 6 OSDs. Each +OSD is provided with 2 GB.

      +
      ceph_wal_devices:
      nvme1n1:
      num_osds: 6
      wal_size: 2 GB
      +

      The sda device will be used as an OSD device with nvme0n1 as DB device and nvme1n1 as WAL device.

      +
      ceph_osd_devices:
      sda:
      db_pv: nvme0n1
      wal_pv: nvme1n1
      +
    12. +
    +
  2. +
  3. +

    Push the configuration to your configuration repository and after that do the following

    +
    $ osism apply configuration
    $ osism reconciler sync
    $ osism apply facts
    +
  4. +
  5. +

    After the configuration has been pulled and facts updated, +you can run the LVM configuration playbook:

    +
    $ osism apply ceph-configure-lvm-volumes
    +

    This will generate a new configuration file for each node in /tmp +on the first manager node named <nodename>-ceph-lvm-configuration.yml.

    +
  6. +
  7. +

    Take the generated configuration file from /tmp and replace the previously +configuration for each node.

    +

    In this example, the following content was in the host vars file before +osism apply ceph-configure-lvm-volumes was called.

    +
    ceph_osd_devices:
    sdb:
    sdc:
    +

    The following content has now been generated in the file in the /tmp directory by running +osism apply ceph-configure-lvm-volumes.

    +
    ceph_osd_devices:
    sdb:
    osd_lvm_uuid: 196aad32-7cc4-5350-8a45-1b03f50fc9bb
    sdc:
    osd_lvm_uuid: c6df96be-1264-5815-9cb2-da5eb453a6de
    lvm_volumes:
    - data: osd-block-196aad32-7cc4-5350-8a45-1b03f50fc9bb
    data_vg: ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb
    - data: osd-block-c6df96be-1264-5815-9cb2-da5eb453a6de
    data_vg: ceph-c6df96be-1264-5815-9cb2-da5eb453a6de
    +

    This content from the file in the /tmp directory is added in the host vars file. +The previous ceph_osd_devices is replaced with the new content.

    +
  8. +
  9. +

    Push the updated configuration again to your configuration repository and re-run:

    +
    $ osism apply configuration
    $ osism reconciler sync
    +
  10. +
  11. +

    Finally create the LVM devices.

    +
    $ osism apply ceph-create-lvm-devices
    +

    These PVs, VGs and LVs are created using the example from step 4.

    +
    $ sudo pvs
    PV VG Fmt Attr PSize PFree
    /dev/sdb ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb lvm2 a-- <20.00g 0
    /dev/sdc ceph-c6df96be-1264-5815-9cb2-da5eb453a6de lvm2 a-- <20.00g 0

    $ sudo vgs
    VG #PV #LV #SN Attr VSize VFree
    ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb 1 1 0 wz--n- <20.00g 0
    ceph-c6df96be-1264-5815-9cb2-da5eb453a6de 1 1 0 wz--n- <20.00g 0

    $ sudo lvs
    LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
    osd-block-196aad32-7cc4-5350-8a45-1b03f50fc9bb ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb -wi-a----- <20.00g
    osd-block-c6df96be-1264-5815-9cb2-da5eb453a6de ceph-c6df96be-1264-5815-9cb2-da5eb453a6de -wi-a----- <20.00g
    +
  12. +
  13. +

    Everything is now ready for the deployment of the OSDs. +Details on deploying Ceph in the Ceph deploy guide.

    +
  14. +
+

Full examples

+

Use of dedicated DB devices

+

The ceph_osd_devices and ceph_db_devices parameters with the following content are initially added +in the host vars of the node. Devices /dev/sda and /dev/sdb are used as OSD devices. The device /dev/sdd +is used as a DB device for up to 2 OSDs. For each OSD that uses /dev/sdd as DB device, an LV volume of +(in this case) 5 GByte is created Please note that at least 30 GByte must be used for a DB device in production.

+
ceph_db_devices:
sdd:
num_osds: 2
db_size: 5 GB

ceph_osd_devices:
sdb:
db_pv: sdd
sdc:
db_pv: sdd
+

Then generate the required LVM2 device configuration with the ceph-configure-lvm-volumes play.

+
osism apply facts
osism reconciler sync
osism apply ceph-configure-lvm-volumes
+

Check the /tmp directory on the manager node for files like testbed-node-0.testbed.osism.xyz-ceph-lvm-configuration.yml. +Add this content to the host vars of the correspondingnode. The existing ceph_osd_devices parameter is replaced.

+
---
#
# This is Ceph LVM configuration for testbed-node-0.testbed.osism.xyz
# generated by ceph-configure-lvm-volumes playbook.
#
ceph_db_devices:
sdd:
db_size: 5 GB
num_osds: 2
vg_name: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb
ceph_osd_devices:
sdb:
db_pv: sdd
osd_lvm_uuid: 75960289-2e0e-525d-8bb5-dd8552531ef5
sdc:
db_pv: sdd
osd_lvm_uuid: ce2c2cb6-f911-52dd-b57f-4476bf7afe9f
lvm_volumes:
- data: osd-block-75960289-2e0e-525d-8bb5-dd8552531ef5
data_vg: ceph-75960289-2e0e-525d-8bb5-dd8552531ef5
db: osd-db-75960289-2e0e-525d-8bb5-dd8552531ef5
db_vg: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb
- data: osd-block-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f
data_vg: ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f
db: osd-db-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f
db_vg: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb
+

Finally, create the necessary PVs, VGs and LVs. The parameter -e ignore_db_too_small=true is only set +here in the example because we use less than 30 GByte for the size of the DB LV.

+
osism reconciler sync
osism apply ceph-create-lvm-devices -e ignore_db_too_small=true
+

You can check the PVs, VGs, and LVs on the node.

+
$ sudo pvs
PV VG Fmt Attr PSize PFree
/dev/sdb ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 lvm2 a-- <20.00g 0
/dev/sdc ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f lvm2 a-- <20.00g 0
/dev/sdd ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb lvm2 a-- <20.00g <10.00g

$ sudo vgs
VG #PV #LV #SN Attr VSize VFree
ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 1 1 0 wz--n- <20.00g 0
ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f 1 1 0 wz--n- <20.00g 0
ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb 1 2 0 wz--n- <20.00g <10.00g

$ sudo lvs
LV VG Attr LSize [...]
osd-block-75960289-2e0e-525d-8bb5-dd8552531ef5 ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 -wi-a----- <20.00g
osd-block-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f -wi-a----- <20.00g
osd-db-75960289-2e0e-525d-8bb5-dd8552531ef5 ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb -wi-a----- 5.00g
osd-db-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb -wi-a----- 5.00g
+

Use of partitions

+

The use of partitions presented in this example is not recommended for use in production but only for POCs.

+

First create partitions that should be used for Ceph. In this example we use a block device /dev/sdb +with four partitions that will be used for Ceph OSDs.

+
$ sudo fdisk -l /dev/sdb
Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 709B8C6C-51E1-4644-9ED4-0604607FCCEE

Device Start End Sectors Size Type
/dev/sdb1 2048 10487807 10485760 5G Linux filesystem
/dev/sdb2 10487808 20973567 10485760 5G Linux filesystem
/dev/sdb3 20973568 31459327 10485760 5G Linux filesystem
/dev/sdb4 31459328 41943006 10483679 5G Linux filesystem
+

The ceph_osd_devices parameter with the following content is initially added in the host vars of the node. +The partitions /dev/sda1, /dev/sdb1, /dev/sdc1 and /dev/sdd1, are to be used as OSD.

+
ceph_osd_devices:
sdb1:
sdb2:
sdb3:
sdb4:
+

Then generate the required LVM2 device configuration with the ceph-configure-lvm-volumes play.

+
osism apply facts
osism reconciler sync
osism apply ceph-configure-lvm-volumes
+

Check the /tmp directory on the manager node for files like testbed-node-0.testbed.osism.xyz-ceph-lvm-configuration.yml. +Add this content to the host vars of the correspondingnode. The existing ceph_osd_devices parameter is replaced.

+
---
#
# This is Ceph LVM configuration for testbed-node-0.testbed.osism.xyz
# generated by ceph-configure-lvm-volumes playbook.
#
ceph_osd_devices:
sdb1:
osd_lvm_uuid: 9e8799ae-c716-5212-8833-49f153ffbcef
sdb2:
osd_lvm_uuid: 8518d3a2-3194-5764-b55a-c51222b9b576
sdb3:
osd_lvm_uuid: a0da232a-e5b8-5823-8c42-8fb231442edc
sdb4:
osd_lvm_uuid: 56f7b5bc-82b0-5626-90a5-adf6078ceba6
lvm_volumes:
- data: osd-block-9e8799ae-c716-5212-8833-49f153ffbcef
data_vg: ceph-9e8799ae-c716-5212-8833-49f153ffbcef
- data: osd-block-8518d3a2-3194-5764-b55a-c51222b9b576
data_vg: ceph-8518d3a2-3194-5764-b55a-c51222b9b576
- data: osd-block-a0da232a-e5b8-5823-8c42-8fb231442edc
data_vg: ceph-a0da232a-e5b8-5823-8c42-8fb231442edc
- data: osd-block-56f7b5bc-82b0-5626-90a5-adf6078ceba6
data_vg: ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6
+

Finally, create the necessary PVs, VGs and LVs.

+
osism reconciler sync
osism apply ceph-create-lvm-devices
+

You can check the PVs, VGs, and LVs on the node.

+
$ sudo pvs
PV VG Fmt Attr PSize PFree
/dev/sdb1 ceph-9e8799ae-c716-5212-8833-49f153ffbcef lvm2 a-- <5.00g 0
/dev/sdb2 ceph-8518d3a2-3194-5764-b55a-c51222b9b576 lvm2 a-- <5.00g 0
/dev/sdb3 ceph-a0da232a-e5b8-5823-8c42-8fb231442edc lvm2 a-- <5.00g 0
/dev/sdb4 ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 lvm2 a-- <5.00g 0

$ sudo vgs
VG #PV #LV #SN Attr VSize VFree
ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 1 1 0 wz--n- <5.00g 0
ceph-8518d3a2-3194-5764-b55a-c51222b9b576 1 1 0 wz--n- <5.00g 0
ceph-9e8799ae-c716-5212-8833-49f153ffbcef 1 1 0 wz--n- <5.00g 0
ceph-a0da232a-e5b8-5823-8c42-8fb231442edc 1 1 0 wz--n- <5.00g 0

$ sudo lvs
LV VG Attr LSize [...]
osd-block-56f7b5bc-82b0-5626-90a5-adf6078ceba6 ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 -wi-a----- <5.00g
osd-block-8518d3a2-3194-5764-b55a-c51222b9b576 ceph-8518d3a2-3194-5764-b55a-c51222b9b576 -wi-a----- <5.00g
osd-block-9e8799ae-c716-5212-8833-49f153ffbcef ceph-9e8799ae-c716-5212-8833-49f153ffbcef -wi-a----- <5.00g
osd-block-a0da232a-e5b8-5823-8c42-8fb231442edc ceph-a0da232a-e5b8-5823-8c42-8fb231442edc -wi-a----- <5.00g
+

Dashboard

+

Password for the admin user of the Ceph dashboard is set via ceph_dashboard_password.

+
environments/ceph/secrets.yml
ceph_dashboard_password: password
+

User name of the admin user, port and listen IP address can be set via additional parameters.

+
environments/ceph/configuration.yml
ceph_dashboard_addr: 0.0.0.0
ceph_dashboard_port: 7000
ceph_dashboard_username: admin
+

The Ceph dashboard is bootstrapped with the ceph-bootstrap-dashboard play.

+
$ osism apply ceph-bootstrap-dashboard
+

Configuring the openstack loadbalancer to expose the ceph dashboard

+

The ceph dashboard runs in an active/standby configuration. In its default standby instances will +redirect to the active instance. Most deployments will want to use the openstack loadbalancer to +expose the ceph dashboard on the internal network and direct traffic directly to the active +instance.

+

In this scenario the dashboard should be configured to return an http error with status 404 on +standby instances.

+
environments/ceph/configuration.yml
ceph_dashboard_standby_behaviour: error
ceph_dashboard_standby_error_status_code: 404
+

Create a loadbalancer configuration

+
environments/kolla/files/overlays/haproxy/services.d/ceph_dashboard.cfg

{%- set internal_tls_bind_info = 'ssl crt /etc/haproxy/certificates/haproxy-internal.pem' if kolla_enable_tls_internal|bool else '' %}

listen ceph_dashboard
option httpchk
http-check expect status 200,404
http-check disable-on-404
{{ "bind %s:%s %s"|e|format(kolla_internal_vip_address, 8140, internal_tls_bind_info)|trim() }}
{% for host in groups['ceph-mgr'] %}
server {{ hostvars[host]['ansible_facts']['hostname'] }} {{ hostvars[host]['monitor_address'] }}:7000 check inter 2000 rise 2 fall 5
{% endfor %}
+

and apply it.

+
$ osism apply -a reconfigure loadbalancer
+

Second Ceph cluster

+

With OSISM, it is possible to manage any number of independent Ceph clusters via a single OSISM +manager service using sub-environments. A sub environment is basically nothing more than another directory +below the environments directory of the configuration repository with a special name.

+

A sub-environment for Ceph always has the name ceph.NAME. The ceph.NAME directory in the +configuration repository then contains the configuration.yml, images.yml and secrets.yml +files as usual.

+

In this example, a sub-environment ceph.rgw is created which is used for a Ceph cluster that +will only be used as an RGW cluster.

+

In comparison to the normal ceph environment, the groups to be used must be overwritten for a +Ceph sub-environment. In this case, two groups are defined: ceph.rgw and ceph.rgw.empty. +Any other groups can be used, e.g. ceph.rgw.osd. It is recommended to base the name of the +groups on the name of the sub-environments.

+

The ceph.rgw.empty group is important because there are plays in ceph-ansible that are executed +when nodes are in a specific group. To explicitly avoid this, certain groups are set to the empty +group.

+

All available group name parameters are listed in the [099-ceph.yml] +file of the osism/defaults repository.

+
environments/ceph.rgw/configuration.yml
##########################
# groups

ceph_group_name: ceph.rgw

client_group_name: ceph.rgw
grafana_server_group_name: ceph.rgw
iscsi_gw_group_name: ceph.rgw.empty
mds_group_name: ceph.rgw.empty
mgr_group_name: ceph.rgw
mon_group_name: ceph.rgw
nfs_group_name: ceph.rgw.empty
osd_group_name: ceph.rgw
rbdmirror_group_name: ceph.rgw.empty
restapi_group_name: ceph.rgw.empty
rgw_group_name: ceph.rgw
rgwloadbalancer_group_name: ceph.rgw.empty
+

The groups used are then added in the inventory in the 10-custom file.

+
inventory/10-custom
[ceph.rgw]
testbed-node-3.testbed.osism.xyz
testbed-node-4.testbed.osism.xyz
testbed-node-5.testbed.osism.xyz

[ceph.rgw.empty]
+

The sub environment can then be specified with all apply commands of the OSISM CLI. For example, +to deploy the Ceph mon services of the ceph.rgw sub environment:

+
osism apply --sub rgw ceph-osds
+

Resource limits

+

Resource limits for the individual Ceph services can be set via environments/ceph/configuration.yml. +The possible parameters and their defaults for memory limits and CPU limits are listed below.

+
    +
  • +

    Memory limits

    +
    ceph_mds_docker_memory_limit: "{{ ansible_facts['memtotal_mb'] }}m"
    ceph_mgr_docker_memory_limit: "{{ ansible_facts['memtotal_mb'] }}m"
    ceph_mon_docker_memory_limit: "{{ ansible_facts['memtotal_mb'] }}m"
    ceph_osd_docker_memory_limit: "{{ ansible_facts['memtotal_mb'] }}m"
    ceph_rbd_mirror_docker_memory_limit: "{{ ansible_facts['memtotal_mb'] }}m"
    ceph_rgw_docker_memory_limit: "4096m"
    +
  • +
  • +

    CPU limits

    +
    ceph_mds_docker_cpu_limit: 4
    ceph_mgr_docker_cpu_limit: 1
    ceph_mon_docker_cpu_limit: 1
    ceph_osd_docker_cpu_limit: 4
    ceph_rbd_mirror_docker_cpu_limit: 1
    ceph_rgw_docker_cpu_limit: 8
    +
  • +
+

CPU Pinning

+

CPU pinning and specifying the NUMA nodes to be used for the Ceph OSD and RGW services can be +set via environments/ceph/configuration.yml. +The possible parameters and possible values are listed below. The parameters are not enabled +by default.

+
    +
  • +

    Limit the specific CPUs or cores a container can use. A comma-separated list or +hyphen-separated range of CPUs a container can use, if you have more than one CPU. +The first CPU is numbered 0. A valid value might be 0-3 (to use the first, second, +third, and fourth CPU) or 1,3 (to use the second and fourth CPU).

    +
    # ceph_osd_docker_cpuset_cpus: "0,2,4,6,8,10,12,14,16"
    # ceph_rgw_docker_cpuset_cpus: "0,2,4,6,8,10,12,14,16"
    +
  • +
  • +

    Memory nodes in which to allow execution (e.g. 0-3, 0,1). Only effective on NUMA systems.

    +
    # ceph_osd_docker_cpuset_mems: "0"
    # ceph_rgw_docker_cpuset_mems: "0"
    +

    Available NUMA nodes on a node can be displayed with numactl. +In this example, there are 2 NUMA nodes. The pinned CPUs should all be assigned to the +specified NUMA node.

    +
    # numactl --hardware
    available: 2 nodes (0-1)
    node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
    node 0 size: 515581 MB
    node 0 free: 511680 MB
    node 1 cpus: 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
    node 1 size: 516078 MB
    node 1 free: 511865 MB
    node distances:
    node 0 1
    0: 10 20
    1: 20 10
    +
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/certificates/index.html b/docs/iaas/guides/configuration-guide/commons/certificates/index.html new file mode 100644 index 0000000000..dd40697f4b --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/certificates/index.html @@ -0,0 +1,31 @@ + + + + + +Certificates | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Certificates

+

With the osism.commons.certificates role, it is possible to add custom CA certificates +on a node. The parameter should be used in the environments/configuration.yml file.

+
environments/configuration.yml
certificates_ca:
- name: custom.crt
certificate: |
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
+

The role is part of the bootstrap of a node. CA certificates can be added at a later +point in time via osism apply certificates on a node.

+

Further details on the use of self-signed certificates can be found in chapter +Self-signed certificates +of the configuration guide.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/index.html b/docs/iaas/guides/configuration-guide/commons/index.html new file mode 100644 index 0000000000..aaa6bd58ab --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/index.html @@ -0,0 +1,25 @@ + + + + + +Commons | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/packages/index.html b/docs/iaas/guides/configuration-guide/commons/packages/index.html new file mode 100644 index 0000000000..4d0d583a2b --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/packages/index.html @@ -0,0 +1,45 @@ + + + + + +Packages | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Packages

+

With the osism.commons.packages role, it is possible to add packages on a node +The parameters should be used in the inventory or in the +environments/configuration.yml file.

+

The role is applied during the bootstrap. The role can be applied manually using +osism apply packages.

+

The following packages are installed by default.

+
required_packages_default:
- curl
- dmidecode
- ethtool
- iotop
- jq
- lsscsi
- ltrace
- mtr
- nvme-cli
- pciutils
- rsyslog
- socat
- sysstat
- tmux
- tree
- whois
+

Additional packages can be added via the required_packages_extra parameter.

+
required_packages_extra: []
+

Distribution specific packages

+

Debian

+

With Debian, the packages listed in required_packages_distribution are installed by default.

+
required_packages_distribution:
- command-not-found
- debconf
- debsums
- htop
- iftop
- iperf
- multitail
- ncdu
- pv
- python-is-python3
- selinux-utils
- ssh
+

The apt_cache_valid_time parameter can be used to set the cache_valid_time paremter +of the ansible.builtin.apt module. The module updates the apt cache if it is older than +the cache_valid_time. The parameter is set in seconds and defaults to 3600.

+

CentOS

+

With CentOS, the packages listed in required_packages_distribution are installed by default.

+
required_packages_distribution:
- libselinux-utils
- openssh
+

Upgrade of packages

+

The upgrade_packages parameter can be used to configure the upgrade of packages. +The parameter is set to true by default.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/resolvconf/index.html b/docs/iaas/guides/configuration-guide/commons/resolvconf/index.html new file mode 100644 index 0000000000..40e7a8e5a2 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/resolvconf/index.html @@ -0,0 +1,24 @@ + + + + + +Resolvconf | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/services/index.html b/docs/iaas/guides/configuration-guide/commons/services/index.html new file mode 100644 index 0000000000..d22214a7da --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/services/index.html @@ -0,0 +1,32 @@ + + + + + +Services | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Services

+

With the osism.commons.services role, it is possible to manage services on a node +in a general form. This allows you to either activate any services or indicate that +specific services are running and should be deactivated.

+

Start and enable required services

+
services_required_default:
- cron
services_required_extra: []
services_required: "{{ services_required_default + services_required_extra }}"
+
note

services_required should not be overwritten. Use services_required_extra to add extra services.

+

Note on services that should be deactivated

+
services_warning_default:
- nscd
services_warning_extra: []
services_warning: "{{ services_warning_default + services_warning_extra }}"
+
note

services_warning should not be overwritten. Use services_warning_extra to add extra services.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/sshconfig/index.html b/docs/iaas/guides/configuration-guide/commons/sshconfig/index.html new file mode 100644 index 0000000000..a993b58b97 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/sshconfig/index.html @@ -0,0 +1,34 @@ + + + + + +SSH Config | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SSH Config

+

With the osism.commons.sshconfig role, it is possible to manage a SSH config +file in the home directory of the operator user.

+

Extra config

+

The sshconfig_extra parameter can be used to add any other SSH configuration to the .ssh/config file.

+
sshconfig_extra: |
Host github.com
ProxyCommand nc -X connect -x <web-proxy-hostname-or-ip>:<web-proxy-port>> ssh.github.com 443
+

Example

+

In the testbed +the /home/dragon/.ssh/config file is created on the manager node testbed-manager.

+
Example for an assembled /home/dragon/.ssh/config file
Host testbed-manager
HostName testbed-manager.testbed.osism.xyz
User dragon
Port 22
IdentityFile /opt/ansible/secrets/id_rsa.operator

####################
Host testbed-node-0
HostName testbed-node-0.testbed.osism.xyz
User dragon
Port 22
IdentityFile /opt/ansible/secrets/id_rsa.operator

####################
Host testbed-node-1
HostName testbed-node-1.testbed.osism.xyz
User dragon
Port 22
IdentityFile /opt/ansible/secrets/id_rsa.operator

####################
Host testbed-node-2
HostName testbed-node-2.testbed.osism.xyz
User dragon
Port 22
IdentityFile /opt/ansible/secrets/id_rsa.operator
+

Defaults

+
ParameterDefaultDescription
sshconfig_groupnameallAll nodes in this group are included.
sshconfig_order20The .ssh/config.d directory is used to prepare the .ssh/config file. You can add your own files in this directory. Everything with a filename prefix smaller than sshconfig_order is placed at the beginning of the assembled .ssh/config file. Anything with a filename prefix greater than sshconfig_order goes at the end.
sshconfig_port22The SSH port.
sshconfig_private_key_file/opt/ansible/secrets/id_rsa.operatorThe identity file to use. The file itself must already exist there. The file is created by the osism.services.manager role.
sshconfig_user"{{ operator_user }}"The user in which home directory the .ssh/config file will be generated.
sshconfig_extra""Add additional SSH configuration to the end of the .ssh/config file.
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/sysctl/index.html b/docs/iaas/guides/configuration-guide/commons/sysctl/index.html new file mode 100644 index 0000000000..5a45f1c693 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/sysctl/index.html @@ -0,0 +1,30 @@ + + + + + +Sysctl | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Sysctl

+

With the osism.commons.sysctl role, it is possible to manage the attributes of the kernel +via sysctl on a node.

+

The following defaults are set via the parameter sysctl_defaults.

+
GroupAttributeDefault
elasticsearchvm.max_map_count262144
rabbitmqnet.ipv4.tcp_keepalive_time6
rabbitmqnet.ipv4.tcp_keepalive_intvl3
rabbitmqnet.ipv4.tcp_keepalive_probes3
rabbitmqnet.core.wmem_max16777216
rabbitmqnet.core.rmem_max16777216
rabbitmqnet.ipv4.tcp_fin_timeout20
rabbitmqnet.ipv4.tcp_tw_reuse1
rabbitmqnet.core.somaxconn4096
rabbitmqnet.ipv4.tcp_syncookies0
rabbitmqnet.ipv4.tcp_max_syn_backlog8192
genericvm.swappiness1
computenet.netfilter.nf_conntrack_max1048576
+

The sysctl_extra parameter can be used to set your own parameters or overwrite existing +parameters in the defaults.

+
Set attribute fs.inotify.max_user_instances to 256 for all nodes in group generic
sysctl_extra:
generic:
- name: fs.inotify.max_user_instances
value: 256
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/timezone/index.html b/docs/iaas/guides/configuration-guide/commons/timezone/index.html new file mode 100644 index 0000000000..ab9c1618c7 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/timezone/index.html @@ -0,0 +1,27 @@ + + + + + +Timezone | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Timezone

+

With the osism.commons.timezone role, it is possible to manage the used timezone on a node.

+

This role is just a wrapper for the community.general.timezone +module. The role also installs the tzdata package.

+
ParameterDefaultDescription
timezone_hwclockUTCWhether the hardware clock is in UTC or in local timezone.
timezone_nameUTCName of the timezone for the system clock.
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/commons/user/index.html b/docs/iaas/guides/configuration-guide/commons/user/index.html new file mode 100644 index 0000000000..89c08776b0 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/commons/user/index.html @@ -0,0 +1,36 @@ + + + + + +User | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

User

+

With the osism.commons.user role, it is possible to manage additional +user accounts on a node.

+

Users are managed via the user_list parameter.

+
user_list:
- name: testing
key: ssh-rsa AAAAB...
# default for groups is user_groups
# groups:
groups:
- docker
# default is a group with the name of the user
# or user_primary_group if set
# primary_group: dragon
- name: testing_github
key: https://github.com/testing.keys
+

By default a new group with the name of a user will be created and assigned as +primary group. It is possible to use an already existing group as primary group +for all users. Can be overwritten with the user specific primary_group key.

+
user_primary_group: dragon
+

If all users should be added to other specific groups by default, the user_groups +parameter can be used. Can be overwritten with the user specific groups key.

+
user_groups:
- docker
+

If users should be deleted, they are added to the user_delete list.

+
user_delete:
- user_to_delete_1
- user_to_delete_2
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/configuration-repository/index.html b/docs/iaas/guides/configuration-guide/configuration-repository/index.html new file mode 100644 index 0000000000..d14c54e589 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/configuration-repository/index.html @@ -0,0 +1,246 @@ + + + + + +Configuration Repository | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Configuration Repository

+

The configuration required for an OSISM managed cluster is stored in a single Git +monorepo, the configuration repository.

+

Creating a new configuration repository

+

The initial content for this configuration repository is generated using the +Cookiecutter.

+

Cookiecutter generates a simple initial configuration for your new cluster by prompting +you for the basic details of the new cluster.

+

The configuration repository is not created on the future Manager node. It is created on a +local workstation. If the local workstation cannot be used for this purpose, a dedicated +virtual system can be used. For more information on this topic, refer to the +Seed Deploy Guide..

+

Step 1: Preparation

+

First decide where to store your Git repository The content generated by the cookiecutter in +the output/configuration directory is committed to a new Git repository. By default, the +configuration repository is assumed to be on GitHub. This can also be GitLab or an internal +Git service as well.

+

Host and path to the Git repository are specified by the git_ parameters. These are +requested in step 2. The git_ parameters do not specify the path to the cookiecutter +to use.

+
  [8/20] git_host (github.com):
[9/20] git_port (22):
[10/20] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY): regiocloud/configuration
[11/20] git_username (git):
[12/20] git_version (main):
+

In this case, the generated configuration in the output/configuration directory is +stored on GitHub in the regiocloud/configuration repository.

+

See the parameter reference for more details. The parameters +listed there will be queried during the execution of Cookiecutter.

+

Step 2: Run Cookiecutter

+
    +
  1. +

    The directory output is created and used as output volume. It is only necessary to create the empty +directory here.

    +
    mkdir output
    +
  2. +
  3. +

    The Cookiecutter runs inside a container. Docker must be usable on the system +where the Cookiecutter will be used. It should also work with Podman.

    +
    docker run \
    -e TARGET_UID="$(id -u)" \
    -e TARGET_GID="$(id -g)" \
    -v $(pwd)/output:/output \
    --rm -it quay.io/osism/cookiecutter
    +
  4. +
  5. +

    A few parameters are requested. The parameters are documented in detail in the Parameters reference.

    +

    If you want to use the latest version, this is done using the manager_version parameter. By default, +this is always set to the latest stable version.

    +
    manager_version [7.0.4]: latest
    +

    If the manager_version parameter is set to latest it is also possible to explicitly +set the openstack_version and the ceph_version explicitly.

    +
    [1/19] with_ceph (1):
    [2/19] with_keycloak (0):
    [3/19] ceph_network(192.168.64.0/19):
    [4/19] ceph_version (quincy):
    [5/19] domain (osism.xyz):
    [6/19] fqdn_external (api.osism.xyz):
    [7/19] fqdn_internal (api-int.osism.xyz):
    [8/19] git_host (github.com):
    [9/19] git_port (22):
    [10/19] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY):
    [11/19] git_username (git):
    [12/19] git_version (main):
    [13/19] ip_external (192.168.96.9):
    [14/19] ip_internal (192.168.32.9):
    [15/19] manager_version (7.0.4):
    [16/19] name_server (149.112.112.112):
    [17/19] ntp_server (de.pool.ntp.org):
    [18/19] openstack_version (2023.2):
    [19/19] project_name (configuration):
    +
  6. +
+

Step 3: Upload the new configuration to the remote git repository

+

Add the initial configuration state to the repository. How to add a deploy key on GitHub is documented in +Managing deploy keys. +Read permissions are sufficient.

+
$ git clone git@github.com:YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY.git YOUR_NEW_CONFIGURATION_REPOSITORY
$ cp -r output/configuration/{*,.gitignore} YOUR_NEW_CONFIGURATION_REPOSITORY
$ cd YOUR_NEW_CONFIGURATION_REPOSITORY
$ git add -A .
$ git commit -m "Initial commit after bootstrap"
$ git push
+

The content is now committed to the Git repository that was created earlier in the process.

+
warning

The secrets directory is not stored in the Git repository. Its contents can be +stored in a trusted location.

The secrets directory contains an SSH key pair which is used as the deploy key to +make the configuration repository available on the manager node later. Write access +is not required. The public SSH key is stored in the secrets/id_rsa.configuration.pub file.

+

Step 4: Post-processing of the generated configuration

+

The configuration repository that is initially created with the Cookiecutter is not immediately usable. +For example, the inventory needs to be built. All other information can be found in the +Configuration Guide. Use git to version all your configuration changes.

+

The following 6 points must be changed after the initial creation of the configuration repository.

+
    +
  1. Secrets
  2. +
  3. Manager inventory
  4. +
  5. Global inventory
  6. +
  7. DNS servers
  8. +
  9. NTP servers
  10. +
  11. SSL certificates
  12. +
+

Secrets

+

The password for Ansible Vault encrypted files, is stored in secrets/vaultpass. Since the secrets directory +is not added to the configuration repository, it is important to store it in a password vault of your choice.

+

The password of the generated Keepass file is password. This should be changed when using the Keepass file. +If possible, an existing password vault should be used.

+

Manager inventory

+

The information required to perform the initial bootstrap of the manager node and the initial +deployment of the manager service from the seed Node is provided in the inventory of the manager +environment.

+

In the Cookiecutter, a node node01 is defined as an example in the manager inventory as well as +in the global inventory. The name of this node must be changed to match the name of the node used +as manager in your own cluster.

+

Roles

+
    +
  • +

    Manager role

    +

    The name of the node on which the manager service is to be deployed is +added to inventory group manager in file environments/manager/hosts.

    +

    Only the manager inventory group is available in environments/manager/hosts. There are no +other groups there.

    +
    environments/manager/hosts
    [manager]
    node01
    +
  • +
+

Host vars

+
    +
  • +

    Ansible section

    +

    The IP address where the node can be reached via SSH from the manager node. If DHCP is used after the +initial provisioning to assign an initial IP address to the nodes, the address assigned via DHCP is +initially used here and later changed to the static IP address.

    +
    environments/manager/host_vars/node01.yml
    ansible_host: 192.168.16.10
    +
  • +
  • +

    Generic section

    +

    The network interface on which the internal communication of the cluster will take place. If the +internal interface does not yet exist at the time the configuration is created, e.g. because it is a +bond interface or VLAN interface that is only created by the static network configuration, it can be +already used here.

    +
    environments/manager/host_vars/node01.yml
    internal_interface: eno1
    +
  • +
  • +

    Network section

    +

    The static and complete network configuration of the node. Further details on creating the +network configuration in the network configuration guide.

    +
    environments/manager/host_vars/node01.yml
    network_ethernets:
    eno1:
    addresses:
    - "192.168.16.10/20"
    gateway4: "192.168.16.1"
    mtu: 1500
    +
  • +
+

Global inventory

+

In the Cookiecutter, a node node01 is defined as an example in the manager inventory as well as +in the global inventory. The name of this node must be changed to match the name of the node used +as manager in your own cluster.

+

Roles

+
    +
  • +

    Generic role

    +
    inventory/20-roles
    # The "all" group is not used in OSISM. Therefore it is important
    # that all nodes are explicitly listed here.
    [generic]
    node01
    +
  • +
  • +

    Manager role

    +
    inventory/20-roles
    # Nodes that act as manager (sometimes called deployment node)
    # are included in this group.
    [manager]
    node01
    +
  • +
  • +

    Monitoring role

    +
    inventory/20-roles
    # Nodes which are intended for monitoring services belong to
    # this group
    [monitoring]
    +
  • +
  • +

    Control role

    +
    inventory/20-roles
    # Nodes that serve as controllers, so things like scheduler,
    # API or database run there, of the environment.
    [control]
    +
  • +
  • +

    Compute role

    +
    inventory/20-roles
    # Virtual systems managed by OpenStack Nova are placed on
    # nodes in this group.
    [compute]
    +
  • +
  • +

    Network role

    +
    inventory/20-roles
    # Network resources managed by OpenStack Neutron, such as
    # L3 routers, are placed on these nodes. This group has nothing
    # to do with the general network configuration.
    [network]
    +
  • +
  • +

    Ceph control role

    +
    inventory/20-roles
    # Nodes that serve as controllers for Ceph, so things like the
    # Ceph Monitor service run here.
    [ceph-control]
    +
  • +
  • +

    Ceph resource role

    +
    inventory/20-roles
    # The storage available in these systems is provided in the
    # form of OSDs for Ceph.
    [ceph-resource]
    +
  • +
  • +

    Ceph rgw role

    +
    inventory/20-roles
    [ceph-rgw:children]
    ceph-control
    +
  • +
+

Host vars

+
    +
  • +

    Ansible section

    +
    inventory/host_vars/node01.yml
    # NOTE: Address where the node can be reached via SSH.
    ansible_host: 192.168.16.10
    +
  • +
  • +

    Generic section

    +
    inventory/host_vars/node01.yml
    internal_interface: eno1

    # NOTE: The address of the internal interface.
    internal_address: 192.168.16.10
    +
  • +
  • +

    Netdata section

    +
    inventory/host_vars/node01.yml
    netdata_host_type: client

    # NOTE: Uncomment this when this node should be a Netdata server.
    # netdata_host_type: server
    +
  • +
  • +

    Network section

    +
    inventory/host_vars/node01.yml
    # NOTE: This is the initial management interface. Further interfaces can be added.
    # DOCS: https://osism.tech/docs/guides/configuration-guide/network

    network_ethernets:
    eno1:
    addresses:
    - "192.168.16.10/20"
    gateway4: "192.168.16.1"
    mtu: 1500
    +
  • +
  • +

    Kolla section

    +
    inventory/host_vars/node01.yml
    network_interface: eno1

    # api_interface:
    # bifrost_network_interface:
    # dns_interface:
    # kolla_external_vip_interface:
    # migration_interface:
    # neutron_external_interface:
    # octavia_network_interface:
    # storage_interface:
    # tunnel_interface:
    +
  • +
  • +

    Ceph section

    +
    inventory/host_vars/node01.yml
    # NOTE: Uncomment this when this node is a part of the Ceph cluster.
    # monitor_address:
    # radosgw_address:
    +
    inventory/host_vars/node01.yml
    # NOTE: Uncomment this when this node should be a OSD node.
    # DOCS: https://osism.tech/docs/guides/configuration-guide/ceph#lvm-devices

    # ceph_osd_devices:
    # sdb:
    # sdc:
    # sdd:
    # sde:
    +
  • +
+

DNS servers

+
environments/configuration.yml
resolvconf_nameserver:
- 8.8.8.8
- 9.9.9.9
+

NTP servers

+
environments/configuration.yml
chrony_servers:
- 1.de.pool.ntp.org
- 2.de.pool.ntp.org
- 3.de.pool.ntp.org
- 4.de.pool.ntp.org
+

SSL certificates

+

Using latest

+

If you want to use the latest version, this is done using the manager_version parameter. By default, +this is always set to the latest stable version.

+
manager_version [7.0.0]: latest
+

If the manager_version parameter is set to latest it is also possible to explicitly +set the openstack_version and the ceph_version explicitly.

+

Parameter reference

+
ParameterDescriptionDefault
ceph_networkAddress range for Ceph's network192.168.64.0/20
ceph_versionThe version of Ceph. When using a stable OSISM release (manager_version != latest), this value is ignoredquincy
domainThe domain used by hostnamesosism.xyz
fqdn_externalExternal API FQDNapi.osism.xyz
fqdn_internalInternal API FQDNapi-int.osism.xyz
git_hostAddress of the used Git servergithub.com
git_portPort of the used Git server22
git_repositoryPath to the git configuration repositoryYOUR_ORG/YOUR_CONFIGURATION_REPOSITORY
git_usernameUsername of the git repositorygit
git_versionGit branch namemain
ip_externalThe external IP address of the API (resolves to fqdn_external)192.168.96.9
ip_internalThe internal IP address of the API (resolves to fqdn_internal)192.168.32.9
manager_versionThe version of OSISM. An overview of available OSISM releases can be found here7.0.4
name_serverNameserver. Only one nameserver is set here because the query of multiple values in Cookiecutter is weird. Add more nameservers afterward.149.112.112.112
ntp_serverNTP server. Only one NTP server is set here because the query of multiple values in Cookiecutter is weird. Add more NTP servers afterward.de.pool.ntp.org
openstack_versionThe version of OpenStack. When using a stable OSISM release (manager_version != latest), this value is ignored2023.2
project_nameName of the configuration repository directoryconfiguration
with_ceph1 to use Ceph, 0 to not use Ceph1
with_keycloak1 to prepare Keycloak integration , 0 to not prepare Keycloak integration0
+

Configuration repository layout

+

A configuration repository always has the same layout. This section describes +the content available in a configuration repository. In the section +Creating a new configuration repository is the creation +of a new configuration repository documented.

+
Directory/FileDescription
environments
inventory
netboxoptional
requirements.txtIn the requirements.txt the necessary dependencies are listed to be able to execute Gilt.
gilt.yml
Makefile
gilt.yamlGilt is a Git layering tool. We use Gilt to maintain the image versions, Ansible configuration and scripts within the environments/manager directory.
+

Synchronising the configuration repository

+

Once the manager has been deployed and the configuration repository has been initially +transferred to the manager node, the configuration repository can be updated using +osism apply configuration.

+

If local changes were made directly in the configuration repository on the manager node, +these are overwritten.

+

Locks

+

It is possible to lock parts of the configuration repository or the complete configuration +repository. It is then no longer possible to execute plays assigned to these parts in the +locked parts. This makes it possible to prevent the execution of plays in specific areas.

+

To lock an environment, a .lock file is created in the corresponding directory of the environment. +For example, the file environments/kolla/.lock locks the Kolla environment.

+

If you try to execute a play in the Kolla environment, an error message is displayed.

+
$ osism apply common
2024-06-02 10:52:44 | INFO | Task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) was prepared for execution.
2024-06-02 10:52:44 | INFO | It takes a moment until task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) has been started and output is visible here.
ERROR: The environment kolla is locked via the configuration repository.
+

File environments/.lock is created to lock everything.

+

If you try to execute a play, an error message is displayed.

+
$ osism apply facts
2024-06-02 10:53:08 | INFO | Task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) was prepared for execution.
2024-06-02 10:53:08 | INFO | It takes a moment until task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) has been started and output is visible here.
ERROR: The configuration repository is locked.
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/index.html b/docs/iaas/guides/configuration-guide/index.html new file mode 100644 index 0000000000..c9c558c52f --- /dev/null +++ b/docs/iaas/guides/configuration-guide/index.html @@ -0,0 +1,23 @@ + + + + + +Configuration Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/inventory/index.html b/docs/iaas/guides/configuration-guide/inventory/index.html new file mode 100644 index 0000000000..8a88f014a7 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/inventory/index.html @@ -0,0 +1,36 @@ + + + + + +Inventory | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Inventory

+

The inventory used for the environment is located in the inventory directory.

+

Manager

+

The manager has his own inventory which is used exclusively for the seed phase of the manager. +It is located in the directory environments/manager. There is a hosts file with only the +manager node in it.

+

Reconciler

+

Inventory Reconciler

+

Host Vars

+

Group Vars

+

Define variable for all nodes

+

The Ansible group all is specifically used internally by OSISM, is reserved and is not supported +for additional variables. When variables are added in the configuration repository for the all group, +they are ignored. In OSISM the group generic can be used to store variables for all nodes.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/loadbalancer/index.html b/docs/iaas/guides/configuration-guide/loadbalancer/index.html new file mode 100644 index 0000000000..32c32c9f65 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/loadbalancer/index.html @@ -0,0 +1,60 @@ + + + + + +Loadbalancer | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Loadbalancer

+

Second Loadbalancer

+
info

This feature is available from OSISM 7.0.5.

+

With OSISM, it is possible to manage any number of independent loadbalancers via a single OSISM +manager service using sub-environments. A sub environment is basically nothing more than another directory +below the environments directory of the configuration repository with a special name.

+

A sub-environment for an additional loadbalancer always has the name kolla.NAME as the loadbalancer +is provided as part of Kolla. The kolla.NAME directory in the configuration repository then contains +the configuration.yml, images.yml and secrets.yml files as usual.

+

The following directories and files are also required in a sub-environment for a loadbalancer.

+
FileDescription
certificates/ca/custom.crtThe file is optional. If a custom CA is used, it must be added here.
certificates/haproxy-internal.pemSSL certificate to be used.
files/overlays/haproxy/services.d/haproxy.cfgHAProxy configuration to be used on the loadbalancer.
+

In this example, a sub-environment kolla.external is created, which is used for an outward facing +loadbalancer that only offers certain API services.

+

In comparison to the normal kolla environment, the groups to be used must be overwritten for a +Kolla sub-environment. In this case, one group is defined: kolla.external.loadbalancer. It is +recommended to base the name of the groups on the name of the sub-environments.

+

The group kolla.external.loadbalancer is added to the global inventory in the 10-custom file. +In this example, testbed-node-2.testbed.osism.xyz is used for the second loadbalancer.

+
inventory/10-custom
[kolla.external.loadbalancer]
testbed-node-2.testbed.osism.xyz
+

It is also important to ensure that the nodes used for the second loadbalancer are not included in +the loadbalancer group. This can be checked with osism get hosts -l loadbalancer. If the nodes of +the second loadbalancer are also listed there, the loadbalancer group in the 99-overwrite file of +the global inventory must be overwritten. In this example, the loadbalaner group is overwritten so +that only testbed-node-0.testbed.osism.xyz and testbed-node-1.testbed.osism.xyz are left in the +loadbalancer group.

+
inventory/99-overwrite
[loadbalancer]
testbed-node-0.testbed.osism.xyz
testbed-node-1.testbed.osism.xyz
+

Furthermore, in a Kolla sub-environment that is only used for a loadbalancer, only a few additional +parameters are required in the configuration.yml file.

+

Don't get confused, only the kolla_*internal* parameters and the haproxy-internal.pem file are used +here in the example. This is because we only want to configure one virtual IP address on the external +loadbalancer and the loadbalancer managed by Kolla has the internal IP address by default. It is therefore +not possible with Kolla to use only the kolla_*external* parameters as an additional virtual IP address +with default values would then be configured by default.

+
environments/kolla.external/configuration.yml
---
##########################################################
# hosts

hosts_kolla_all: kolla.external.loadbalancer
hosts_kolla_loadbalancer: kolla.external.loadbalancer

##########################################################
# docker

docker_namespace: osism

##########################################################
# loadbalancer

kolla_internal_vip_address: 192.168.24.200
kolla_internal_fqdn: api.testbed.osism.com
kolla_enable_tls_internal: "yes"

# Required if a custom CA is used.
kolla_copy_ca_into_containers: "yes"
+

At the moment it is only possible to deploy the loadbalancer itself with its own configuration. It is currently +not possible to use the integrated service configurations of Kolla itself (Nova, Cinder, ..) on an additional +loadbalancer. This will be possible in the future.

+
osism apply --sub external loadbalancer-without-service-config
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/manager/index.html b/docs/iaas/guides/configuration-guide/manager/index.html new file mode 100644 index 0000000000..1e3e5cf3fb --- /dev/null +++ b/docs/iaas/guides/configuration-guide/manager/index.html @@ -0,0 +1,76 @@ + + + + + +Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Manager

+

Stable release

+
warning

Always read the release notes first to learn what has changed and what +adjustments are necessary. Read the release notes even if you are only updating from e.g. 7.0.2 to 7.0.5.

+

In the example, OSISM release 7.0.5 is used.

+
    +
  1. +

    Set the new manager version in the configuration repository.

    +
    MANAGER_VERSION=7.0.5
    sed -i -e "s/manager_version: .*/manager_version: ${MANAGER_VERSION}/g" environments/manager/configuration.yml
    +
  2. +
  3. +

    If openstack_version or ceph_version are set in environments/manager/configuration.yml +(or anywhere else), they must be removed. If these are set, the stable release is not used for +these components.

    +
  4. +
  5. +

    Sync the image versions in the configuration repository.

    +
    make sync
    +
  6. +
  7. +

    Commit and push changes in the configuration repository. Since everyone here has their own +workflows for changes to the configuration repository, only a generic example for Git.

    +
    git commit -a -s -m "manager: use OSISM version 7.0.5"
    git push
    +
  8. +
  9. +

    The upgrade is described in the Manager Upgrade Guide.

    +
  10. +
+

OpenSearch integration

+

With the command osism log opensearch it is possible to send SQL queries +to the OpenSearch service. For the command to be functional, the OpenSearch +integration must be activated in the manager environment and the OpenSearch +address and port must be set.

+
environments/manager/configuration.yml
manager_opensearch_enable: true
manager_opensearch_address: api-int.testbed.osism.xyz
manager_opensearch_port: 9200
manager_opensearch_protocol: https
+

The integration can also be enabled later. osism update manager is then +executed after the configuration has been changed.

+

OpenStack broker integration

+

If the Baremetal Service Integration in OSISM is used, the OpenStack Broker integration is +required. The integration itself is activated by setting the parameter enable_listener to true.

+

The hosts in the manager_listener_broker_hosts list are the control nodes of OpenStack. +The user is set via manager_listener_broker_username. On OpenStack's RabbitMQ broker, the user openstack +is present by default.

+
environments/manager/configuration.yml
enable_listener: true
manager_listener_broker_hosts:
- 192.168.16.10
- 192.168.16.11
- 192.168.16.12
manager_listener_broker_username: openstack
manager_listener_broker_uri: "{% for host in manager_listener_broker_hosts %}amqp://{{ manager_listener_broker_username }}:{{ manager_listener_broker_password }}@{{ host }}:5672/{% if not loop.last %};{% endif %}{% endfor %}"
+

The password used when using the openstack user is rabbitmq_password from environments/kolla/secrets.yml.

+
environments/manager/secrets.yml
manager_listener_broker_password: RABBITMQ_PASSWORD
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/network/index.html b/docs/iaas/guides/configuration-guide/network/index.html new file mode 100644 index 0000000000..0c23f35c6f --- /dev/null +++ b/docs/iaas/guides/configuration-guide/network/index.html @@ -0,0 +1,64 @@ + + + + + +Network | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Network

+

Netplan

+
Since OSISM 6.1.0, the default network type is a netplan and no longer needs to be set explicitly
network_type: netplan
+

The configuration is written to /etc/netplan/01-osism.yaml by default. Can be changed +via the network_netplan_path and network_netplan_file parameters. The file permissions +are 0600 by default (cane be changed via the network_netplan_permissions parameter). +By default, all other files in /etc/netplan are removed. If you do not want this, you +can set network_netplan_remove_unmanaged_files to false. It is also possible to explicitly +list individual files that should not be deleted in network_netplan_managed_files_extra.

+

An existing /etc/intefaces file is replaced with a placeholder file. It is not possible +to use /etc/interfaces and Netplan in parallel.

+
This template is used as the base for the configuration
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
---
network:
version: {{ network_version }}
renderer: {{ network_renderer }}

bonds:
{{ network_bonds|to_nice_yaml(indent=4)|indent(4) }}

bridges:
{{ network_bridges|to_nice_yaml(indent=4)|indent(4) }}

ethernets:
{{ network_ethernets|to_nice_yaml(indent=4)|indent(4) }}

tunnels:
{{ network_tunnels|to_nice_yaml(indent=4)|indent(4) }}

vlans:
{{ network_vlans|to_nice_yaml(indent=4)|indent(4) }}

vrfs:
{{ network_vrfs|to_nice_yaml(indent=4)|indent(4) }}
+

The parameters listed in the following table can be used in the template.

+
ParameterDefaultDescription
network_version2Defines what version of the configuration format is used. The only value supported at the moment is 2.
network_renderernetworkdDefines what network configuration tool will be used to set up your configuration.
network_bonds{}https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bonds
network_bridges{}https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bridges
network_ethernets{}https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-ethernets
network_tunnels{}https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-tunnels
network_vlans{}https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vlans
network_vrfs{}https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vrfs
+

By default changes to the network configuration are not applied automatically. This is done on +purpose to allow a manual check in advance. Changes to the network configuration can +be applied either by rebooting or by executing netplan apply.

+
$ osism console --type clush all
Enter 'quit' to leave this interactive mode
Working with nodes: testbed-manager.testbed.osism.xyz,testbed-node-[0-2].testbed.osism.xyz
clush> sudo netplan apply
+

It is possible to execute the netplan apply automatically via a handler when changes are made. +The parameter network_allow_service_restart is used for this.

+
environments/configuration.yml
network_allow_service_restart: true
+

Example

+

The Netplan documentation contains a large number of example configurations. The following +example shows the use of How to create VLANs with the osism.commons.network role.

+
network_ethernets:
mainif:
match:
macaddress: "de:ad:be:ef:ca:fe"
set-name: mainif
addresses: [ "10.3.0.5/23" ]
nameservers:
addresses: [ "8.8.8.8", "8.8.4.4" ]
search: [ example.com ]
routes:
- to: default
via: 10.3.0.1

network_vlans:
vlan15:
id: 15
link: mainif
addresses: [ "10.3.99.5/24" ]
vlan10:
id: 10
link: mainif
addresses: [ "10.3.98.5/24" ]
nameservers:
addresses: [ "127.0.0.1" ]
search: [ domain1.example.com, domain2.example.com ]
+

Dispatcher scripts

+

Dummy interfaces

+

Dummy devices are created with the help of +systemd.netdev +and can then be used as a normal netowrk device in the Netplan configuration.

+
network_dummy_interfaces:
- dummy0
+

The MTU is set to 9000 by default and can be set via network_dummy_interface_mtu.

+

/etc/interfaces

+
If /etc/interfaces is to be used, the network_type must be explicitly set in environments/configuration.yml
network_type: interfaces
+

IPv6 fabric underlay

+

Example configuration for a node. The configuration is stored in the host_vars file for the node in inventory +directory in the configuration repository.

+
##########################################################
# ansible

ansible_host: 10.10.42.10
+
##########################################################
# generic

internal_interface: dummy0
+
##########################################################
# network

network_type: netplan
network_dummy_interfaces:
- dummy0
network_ethernets:
enp99s0f0np0:
mtu: 9100
enp99s0f1np1:
mtu: 9100
dummy0:
addresses:
- 10.10.42.10/32
- 2001:db8::10:10:42:10/128
+
##########################################################
# frr

frr_local_as: 4210042010
frr_loopback_v4: 10.10.42.10
frr_loopback_v6: 2001:db8::10:10:42:10
frr_uplinks:
- interface: enp99s0f0np0
remote_as: 65401
- interface: enp99s0f1np1
remote_as: 65402
+
##########################################################
# kolla

network_interface: "{{ internal_interface }}"
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/aodh/index.html b/docs/iaas/guides/configuration-guide/openstack/aodh/index.html new file mode 100644 index 0000000000..44e3519630 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/aodh/index.html @@ -0,0 +1,28 @@ + + + + + +Aodh | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/barbican/index.html b/docs/iaas/guides/configuration-guide/openstack/barbican/index.html new file mode 100644 index 0000000000..cbf2ac0da6 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/barbican/index.html @@ -0,0 +1,28 @@ + + + + + +Barbican | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/ceilometer/index.html b/docs/iaas/guides/configuration-guide/openstack/ceilometer/index.html new file mode 100644 index 0000000000..dac2d42a8f --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/ceilometer/index.html @@ -0,0 +1,27 @@ + + + + + +Ceilometer | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/cinder/index.html b/docs/iaas/guides/configuration-guide/openstack/cinder/index.html new file mode 100644 index 0000000000..61ae0229f6 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/cinder/index.html @@ -0,0 +1,35 @@ + + + + + +Cinder | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/designate/index.html b/docs/iaas/guides/configuration-guide/openstack/designate/index.html new file mode 100644 index 0000000000..4a9530ff90 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/designate/index.html @@ -0,0 +1,28 @@ + + + + + +Designate | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/glance/index.html b/docs/iaas/guides/configuration-guide/openstack/glance/index.html new file mode 100644 index 0000000000..eaa142f318 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/glance/index.html @@ -0,0 +1,27 @@ + + + + + +Glance | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/heat/index.html b/docs/iaas/guides/configuration-guide/openstack/heat/index.html new file mode 100644 index 0000000000..5f641f81ce --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/heat/index.html @@ -0,0 +1,27 @@ + + + + + +Heat | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/horizon/index.html b/docs/iaas/guides/configuration-guide/openstack/horizon/index.html new file mode 100644 index 0000000000..cf25b8302e --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/horizon/index.html @@ -0,0 +1,41 @@ + + + + + +Horizon | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Horizon

+ +

Problems uploading machine images larger than 1 GiB

+

By default, the LimitRequestBody is set to 1073741824 (1 GiB). +This is a security feature (CVE-2022-29404) +and not a bug. Further details in the +A new default for the LimitRequestBody directive in httpd configuration +article in the RedHat knowledgebase.

+

This limit can be increased via the parameter horizon_httpd_limitrequestbody.

+
environments/kolla/configuration.yml
horizon_httpd_limitrequestbody: 2147483648  # 2 GiB
+

Make clouds.yml file downloadable as an alternative to the RC file

+

By default, only the openrc file is offered for download in Horizon. It makes sense to also add the +clouds.yaml as a download. To do this, the menu is customised in the custom_local_settings. The +change can be deployed with osism apply -a reconfigure horizon.

+
environments/kolla/files/overlays/horizon/custom_local_settings
SHOW_KEYSTONE_V2_RC = False
USER_MENU_LINKS = [
{'name': _('OpenStack clouds.yml File'),
'icon_classes': ['fa-download', ],
'url': 'horizon:project:api_access:clouds.yaml',
'external': False,
},
{'name': _('OpenStack RC File v3'),
'icon_classes': ['fa-download', ],
'url': 'horizon:project:api_access:openrc',
'external': False,
}
]
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/index.html b/docs/iaas/guides/configuration-guide/openstack/index.html new file mode 100644 index 0000000000..71ccfa84bd --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/index.html @@ -0,0 +1,172 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

OpenStack

+

Image tags

+

Sometimes it is necessary to specify the image tag to be used for a specific service or a specific image of a service. +All available images and tags are listed in the 002-images-kolla.yml +file.

+

The image tags can be set in the environments/kolla/images.yml file.

+
    +
  • +

    Use a specific tag for all images of a service:

    +
    environments/kolla/images.yml
    barbican_tag: "2023.1"
    +
  • +
  • +

    Use a specific tag for a specific image of a service:

    +
    environments/kolla/images.yml
    barbican_worker_tag: "2023.1"
    +
  • +
+

Endpoints

+

Public endpoints

+

The public endpoints used for the individual OpenStack services can be configured via the public_endpoint parameters. +These are defined as follows.

+
ParameterDefault value
aodh_public_endpointaodh_external_fqdn | kolla_url(public_protocol, aodh_api_public_port)
blazar_public_endpointblazar_external_fqdn | kolla_url(public_protocol, blazar_api_public_port, '/v1')
ceph_rgw_public_endpointceph_rgw_external_fqdn | kolla_url(public_protocol, ceph_rgw_public_port, ceph_rgw_endpoint_path)
cinder_v3_public_endpoint{{ cinder_public_base_endpoint }}/v3/%(tenant_id)s
cloudkitty_public_endpointcloudkitty_external_fqdn | kolla_url(public_protocol, cloudkitty_api_public_port)
cyborg_public_endpointcyborg_external_fqdn | kolla_url(public_protocol, cyborg_api_port, '/v2')
gnocchi_public_endpointgnocchi_external_fqdn | kolla_url(public_protocol, gnocchi_api_public_port)
heat_cfn_public_endpoint{{ heat_cfn_public_base_endpoint }}/v1
heat_public_endpointheat_external_fqdn | kolla_url(public_protocol, heat_api_public_port, '/v1/%(tenant_id)s')
ironic_inspector_public_endpointironic_inspector_external_fqdn | kolla_url(public_protocol, ironic_inspector_public_port)
magnum_public_endpointmagnum_external_fqdn | kolla_url(public_protocol, magnum_api_public_port, '/v1')
manila_public_endpoint{{ manila_public_base_endpoint }}/v1/%(tenant_id)s
manila_v2_public_endpoint{{ manila_public_base_endpoint }}/v2
masakari_public_endpointmasakari_external_fqdn | kolla_url(public_protocol, masakari_api_public_port)
mistral_public_endpointmistral_external_fqdn | kolla_url(public_protocol, mistral_api_public_port, '/v2')
nova_legacy_public_endpoint{{ nova_public_base_endpoint }}/v2/%(tenant_id)s
nova_public_endpoint{{ nova_public_base_endpoint }}/v2.1
placement_public_endpointplacement_external_fqdn | kolla_url(public_protocol, placement_api_public_port)
tacker_public_endpointtacker_external_fqdn | kolla_url(public_protocol, tacker_server_public_port)
trove_public_endpointtrove_external_fqdn | kolla_url(public_protocol, trove_api_public_port, '/v1.0/%(tenant_id)s')
venus_public_endpointvenus_external_fqdn | kolla_url(public_protocol, venus_api_port)
watcher_public_endpointwatcher_external_fqdn | kolla_url(public_protocol, watcher_api_public_port)
zun_public_endpointzun_external_fqdn | kolla_url(public_protocol, zun_api_public_port, '/v1/')
+

Some of the previous default values refer to a public_base_endpoint parameter. These are defined as follows.

+
ParameterDefault value
cinder_public_base_endpointcinder_external_fqdn | kolla_url(public_protocol, cinder_api_public_port)
heat_cfn_public_base_endpointheat_cfn_external_fqdn | kolla_url(public_protocol, heat_api_cfn_public_port)
manila_public_base_endpointmanila_external_fqdn | kolla_url(public_protocol, manila_api_public_port)
nova_public_base_endpointnova_external_fqdn | kolla_url(public_protocol, nova_api_public_port)
skyline_apiserver_public_base_endpointskyline_apiserver_external_fqdn | kolla_url(public_protocol, skyline_apiserver_public_port)
+

Example for the use of name-based endpoints

+

DNS records pointing to the kolla_external_vip_address are created in advance.

+

Additional configuration parameters to overwrite the public endpoints +are added in the environments/kolla/configuration.yml file. If certain services +are not used, they are removed. If other services are used, these are added (see the +table above).

+
environments/kolla/configuration.yml
barbican_public_endpoint: https://barbican.services.a.regiocloud.tech
cinder_public_base_endpoint: https://cinder.services.a.regiocloud.tech
designate_public_endpoint: https://designate.services.a.regiocloud.tech
glance_public_endpoint: https://glance.services.a.regiocloud.tech
ironic_public_endpoint: https://ironic.services.a.regiocloud.tech
keystone_public_url: https://keystone.services.a.regiocloud.tech
manila_public_endpoint: https://manila.services.a.regiocloud.tech
neutron_public_endpoint: https://neutron.services.a.regiocloud.tech
nova_public_base_endpoint: https://nova.services.a.regiocloud.tech
octavia_public_endpoint: https://octavia.services.a.regiocloud.tech
placement_public_endpoint: https://placement.services.a.regiocloud.tech
+

Since we bind the name_based_external_front frontend to the same ports as the +horizon_external_front, the external Horizon frontend must be disabled. This is +only possible as of OSISM 7.0.6.

+
environments/kolla/configuration.yml
haproxy_enable_horizon_external: false
+

Additional HAProxy configuration in haproxy/services.d/haproxy.cfg is required to map +the DNS records to the correct backends. Here too, unused services are removed or +additional services are added.

+
environments/kolla/files/overlays/haproxy/services.d/haproxy.cfg
frontend name_based_external_front
mode http
http-request del-header X-Forwarded-Proto
option httplog
option forwardfor
http-request set-header X-Forwarded-Proto https if { ssl_fc }
bind {{ kolla_external_vip_address }}:80
bind {{ kolla_external_vip_address }}:443 ssl crt /etc/haproxy/certificates/haproxy.pem
default_backend horizon_back

acl ACL_keystone.services.a.regiocloud.tech hdr(host) -i keystone.services.a.regiocloud.tech
use_backend keystone_external_back if ACL_keystone.services.a.regiocloud.tech

acl ACL_glance.services.a.regiocloud.tech hdr(host) -i glance.services.a.regiocloud.tech
use_backend glance_api_external_back if ACL_glance.services.a.regiocloud.tech

acl ACL_neutron.services.a.regiocloud.tech hdr(host) -i neutron.services.a.regiocloud.tech
use_backend neutron_server_external_back if ACL_neutron.services.a.regiocloud.tech

acl ACL_placement.services.a.regiocloud.tech hdr(host) -i placement.services.a.regiocloud.tech
use_backend placement_api_external_back if ACL_placement.services.a.regiocloud.tech

acl ACL_nova.services.a.regiocloud.tech hdr(host) -i nova.services.a.regiocloud.tech
use_backend nova_api_external_back if ACL_nova.services.a.regiocloud.tech

acl ACL_console.services.a.regiocloud.tech hdr(host) -i console.services.a.regiocloud.tech
use_backend nova_novncproxy_external_back if ACL_console.services.a.regiocloud.tech

acl ACL_designate.services.a.regiocloud.tech hdr(host) -i designate.services.a.regiocloud.tech
use_backend designate_api_external_back if ACL_designate.services.a.regiocloud.tech

acl ACL_cinder.services.a.regiocloud.tech hdr(host) -i cinder.services.a.regiocloud.tech
use_backend cinder_api_external_back if ACL_cinder.services.a.regiocloud.tech

acl ACL_octavia.services.a.regiocloud.tech hdr(host) -i octavia.services.a.regiocloud.tech
use_backend octavia_api_external_back if ACL_octavia.services.a.regiocloud.tech

acl ACL_swift.services.a.regiocloud.tech hdr(host) -i swift.services.a.regiocloud.tech
use_backend swift_api_external_back if ACL_swift.services.a.regiocloud.tech

acl ACL_ironic.services.a.regiocloud.tech hdr(host) -i ironic.services.a.regiocloud.tech
use_backend ironic_api_external_back if ACL_ironic.services.a.regiocloud.tech
+

Additional Nova configuration in nova.conf is required to use the URL for the NoVNC service.

+
environments/kolla/files/overlays/nova.conf
[vnc]
novncproxy_base_url = https://console.services.a.regiocloud.tech/vnc_lite.html
+

Network interfaces

+
ParameterDefaultDescription
network_interfaceeth0
neutron_external_interface{{ network_interface }}
kolla_external_vip_interface{{ network_interface }}
api_interface{{ network_interface }}
migration_interface{{ api_interface }}
tunnel_interface{{ network_interface }}
octavia_network_interface{{ 'o-hm0' if octavia_network_type == 'tenant' else api_interface }}
dns_interface{{ network_interface }}
dpdk_tunnel_interface{{ neutron_external_interface }}
ironic_http_interface{{ api_interface }}
ironic_tftp_interface{{ api_interface }}
+

Customization of the service configurations

+
info

The following content is based on the kolla-ansible uptream documentation.

+

OSISM will generally look for files in environments/kolla/files/overlays/CONFIGFILE, +environments/kolla/files/overlays/SERVICENAME/CONFIGFILE or environments/kolla/files/overlays/SERVICENAME/HOSTNAME/CONFIGFILE +in the configuration repository. These locations sometimes vary and you should check the config task in the appropriate +Ansible role for a full list of supported locations. For example, in the case of nova.conf the following locations are +supported, assuming that you have services using nova.conf running on hosts called ctl1, ctl2 and ctl3:

+
    +
  • environments/kolla/files/overlays/nova.conf
  • +
  • environments/kolla/files/overlays/nova/ctl1/nova.conf
  • +
  • environments/kolla/files/overlays/nova/ctl2/nova.conf
  • +
  • environments/kolla/files/overlays/nova/ctl3/nova.conf
  • +
  • environments/kolla/files/overlays/nova/nova-scheduler.conf
  • +
+

Using this mechanism, overrides can be configured per-project (Nova), per-project-service (Nova scheduler service) or +per-project-service-on-specified-host (Nova servies on ctl1).

+

Overriding an option is as simple as setting the option under the relevant section. For example, to set +override scheduler_max_attempts in the Nova scheduler service, the operator could create +environments/kolla/files/overlays/nova/nova-scheduler.conf in the configuration repository with this content:

+
[DEFAULT]
scheduler_max_attempts = 100
+

If the operator wants to configure the initial disk, cpu and ram allocation ratio on compute node com1, +the operator needs to create the file environments/kolla/files/overlays/nova/com1/nova.conf with this +content:

+
[DEFAULT]
initial_cpu_allocation_ratio = 3.0
initial_ram_allocation_ratio = 1.0
initial_disk_allocation_ratio = 1.0
+

Note that the numbers shown here with an initial_cpu_allocation_ratio of 3.0 do match the requirements +of the SCS-nV-* (moderate oversubscription) flavors. If you do not use SMT/hyperthreading, SCS would allow +5.0 here (for the V flavors).

+

This method of merging configuration sections is supported for all services using oslo.config, +which includes the vast majority of OpenStack services, and in some cases for services using YAML configuration. +Since the INI format is an informal standard, not all INI files can be merged in this way. In these cases OSISM supports +overriding the entire config file.

+

Additional flexibility can be introduced by using Jinja conditionals in the config files. For example, you may create +Nova cells which are homogeneous with respect to the hypervisor model. In each cell, you may wish to configure the +hypervisors differently, for example the following override shows one way of setting the bandwidth_poll_interval +variable as a function of the cell:

+
[DEFAULT]
{% if 'cell0001' in group_names %}
bandwidth_poll_interval = 100
{% elif 'cell0002' in group_names %}
bandwidth_poll_interval = -1
{% else %}
bandwidth_poll_interval = 300
{% endif %}
+

An alternative to Jinja conditionals would be to define a variable for the bandwidth_poll_interval and set +it in according to your requirements in the inventory group or host vars:

+
[DEFAULT]
bandwidth_poll_interval = {{ bandwidth_poll_interval }}
+

OSISM allows the operator to override configuration globally for all services. It will look for a file +called environments/kolla/files/overlays/global.conf in the configuration repository.

+

For example to modify database pool size connection for all services, the operator needs to create +environments/kolla/files/overlays/global.conf in the configuration repository with this content:

+
[database]
max_pool_size = 100
+

How does the configuration get into services?

+

It is explained with example of OpenSearch Service how the configuration for OpenSearch +is created and gets into the container.

+
    +
  • +

    The task Copying over opensearch service config file +merges the individual sources of the files.

    +
    Copying over opensearch service config file task
    - name: Copying over opensearch service config file
    merge_yaml:
    sources:
    - "{{ role_path }}/templates/opensearch.yml.j2"
    - "{{ node_custom_config }}/opensearch.yml"
    - "{{ node_custom_config }}/opensearch/opensearch.yml"
    - "{{ node_custom_config }}/opensearch/{{ inventory_hostname }}/opensearch.yml"
    dest: "{{ node_config_directory }}/opensearch/opensearch.yml"
    mode: "0660"
    become: true
    when:
    - inventory_hostname in groups['opensearch']
    - opensearch_services['opensearch'].enabled | bool
    notify:
    - Restart opensearch container
    +
  • +
  • +

    As a basis a template opensearch.yml.j2 +is used which is part of the OpenSearch service role.

    +
    opensearch.yml.j2 template
    {% set num_nodes = groups['opensearch'] | length %}
    {% set recover_after_nodes = (num_nodes * 2 / 3) | round(0, 'floor') | int if num_nodes > 1 else 1 %}
    plugins.security.disabled: "true"

    node.name: "{{ 'api' | kolla_address | put_address_in_context('url') }}"
    network.host: "{{ 'api' | kolla_address | put_address_in_context('url') }}"

    cluster.name: "{{ opensearch_cluster_name }}"
    cluster.initial_master_nodes: [{% for host in groups['opensearch'] %}"{{ 'api' | kolla_address(host) }}"{% if not loop.last %},{% endif %}{% endfor %}]
    node.master: true
    node.data: true
    discovery.seed_hosts: [{% for host in groups['opensearch'] %}"{{ 'api' | kolla_address(host) | put_address_in_context('url') }}"{% if not loop.last %},{% endif %}{% endfor %}]

    http.port: {{ opensearch_port }}
    gateway.expected_nodes: {{ num_nodes }}
    gateway.recover_after_time: "5m"
    gateway.recover_after_nodes: {{ recover_after_nodes }}
    path.data: "/var/lib/opensearch/data"
    path.logs: "/var/log/kolla/opensearch"
    indices.fielddata.cache.size: 40%
    action.auto_create_index: "true"
    +
  • +
  • +

    For OpenSearch, overlay files can additionally be stored in 3 places in the configuration repository.

    +
      +
    • environments/kolla/files/overlays/opensearch.yml
    • +
    • environments/kolla/files/overlays/opensearch/opensearch.yml
    • +
    • environments/kolla/files/overlays/opensearch/{{ inventory_hostname }}/opensearch.yml
    • +
    +

    When merging files, the last file found has the most weight. If there is a parameter node.master: true +in the service role template opensearch.yml.j2 of the OpenSearch service and you set e.g. +node.master: false in environments/kolla/files/overlays/opensearch.yml then accordingly in the finished opensearch.yml +node.master: false is used.

    +
  • +
  • +

    After the merge the task Copying over opensearch service config file copies the content into the +configuration directory /etc/kolla/opensearch of the service.

    +
    /etc/kolla/opensearch/opensearch.yml
    action.auto_create_index: 'true'
    cluster.initial_master_nodes:
    - 192.168.16.10
    cluster.name: kolla_logging
    discovery.seed_hosts:
    - 192.168.16.10
    gateway.expected_nodes: 1
    gateway.recover_after_nodes: 1
    gateway.recover_after_time: 5m
    http.port: 9200
    indices.fielddata.cache.size: 40%
    network.host: 192.168.16.10
    node.data: true
    node.master: true
    node.name: 192.168.16.10
    path.data: /var/lib/opensearch/data
    path.logs: /var/log/kolla/opensearch
    plugins.security.disabled: 'true'
    +
  • +
  • +

    The configuration directory /etc/kolla/opensearch is mounted in each container of the OpenSearch service +to /var/lib/kolla/config_files.

    +
    Output of docker inspect opensearch
    "Mounts": [
    {
    "Type": "bind",
    "Source": "/etc/kolla/opensearch",
    "Destination": "/var/lib/kolla/config_files",
    "Mode": "rw",
    "RW": true,
    "Propagation": "rprivate"
    },
    +
  • +
  • +

    Entrypoint of a service is always kolla_start. +This script calls a script set_configs.py. +This script takes care of copying files from /var/lib/kolla/config_files to the right place inside the container. +For this purpose, the container has a +config.json +in which the individual actions are configured.

    +

    The file /var/lib/kolla/config_files/opensearch.yml is copied to /etc/opensearch/opensearch.yml.

    +

    The permissions of /var/lib/opensearch and /var/log/kolla/opensearch are set accordingly.

    +
    /etc/kolla/opensearch/config.json
    {
    "command": "/usr/share/opensearch/bin/opensearch",
    "config_files": [
    {
    "source": "/var/lib/kolla/config_files/opensearch.yml",
    "dest": "/etc/opensearch/opensearch.yml",
    "owner": "opensearch",
    "perm": "0600"
    }
    ],
    "permissions": [
    {
    "path": "/var/lib/opensearch",
    "owner": "opensearch:opensearch",
    "recurse": true
    },
    {
    "path": "/var/log/kolla/opensearch",
    "owner": "opensearch:opensearch",
    "recurse": true
    }
    ]
    }
    +
  • +
  • +

    In the config.json of the service is also defined the command which will be executed after finishing the preparations. +In the case of OpenSearch this is /usr/share/opensearch/bin/opensearch.

    +
    /etc/kolla/opensearch/config.json
    {
    "command": "/usr/share/opensearch/bin/opensearch",
    "config_files": [
    {
    "source": "/var/lib/kolla/config_files/opensearch.yml",
    "dest": "/etc/opensearch/opensearch.yml",
    "owner": "opensearch",
    "perm": "0600"
    }
    ],
    "permissions": [
    {
    "path": "/var/lib/opensearch",
    "owner": "opensearch:opensearch",
    "recurse": true
    },
    {
    "path": "/var/log/kolla/opensearch",
    "owner": "opensearch:opensearch",
    "recurse": true
    }
    ]
    }
    +
  • +
+

Number of service workers

+

The number of workers used for the individual services can generally be configured using two parameters.

+
openstack_service_workers: "{{ [ansible_facts.processor_vcpus, 5] | min }}"
openstack_service_rpc_workers: "{{ [ansible_facts.processor_vcpus, 3] | min }}
+

The default for openstack_service_workers is set to 5 when using the cookiecutter for the initial creation +of the configuration.

+

This value can be overwritten for individual services. The default for all parameters in the following table is +{{ openstack_service_workers }}. The parameter aodh_api_workers can then be used to explicitly set the +number of workers for the AODH API, for example. A reconfigure must be made for the particular services in the +case of a change. osism apply -a reconfigure aodh in this example.

+

These parameters are all set in environments/kolla/configuration.yml.

+
Parameter
aodh_api_workers
barbican_api_workers
cinder_api_workers
designate_api_workers
designate_worker_workers
designate_producer_workers
designate_central_workers
designate_sink_workers
designate_mdns_workers
glance_api_workers
gnocchi_metricd_workers
gnocchi_api_workers
heat_api_cfn_workers
heat_api_workers
heat_engine_workers
horizon_wsgi_processes
ironic_api_workers
keystone_api_workers
proxysql_workers
magnum_api_workers
magnum_conductor_workers
manila_api_workers
neutron_api_workers
neutron_metadata_workers
nova_api_workers
nova_superconductor_workers
nova_metadata_api_workers
nova_scheduler_workers
nova_cell_conductor_workers
octavia_api_workers
octavia_healthmanager_health_workers
octavia_healthmanager_stats_workers
placement_api_workers
skyline_gunicorn_workers
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/ironic/index.html b/docs/iaas/guides/configuration-guide/openstack/ironic/index.html new file mode 100644 index 0000000000..2814dfb612 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/ironic/index.html @@ -0,0 +1,27 @@ + + + + + +Ironic | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/keystone/index.html b/docs/iaas/guides/configuration-guide/openstack/keystone/index.html new file mode 100644 index 0000000000..63b8ab08cd --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/keystone/index.html @@ -0,0 +1,41 @@ + + + + + +Keystone | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Keystone

+ +

Domain manager policy

+

This policy is currently still in draft status. Its use in production is currently not recommended.

+
SCS Standard TrackSCS StandardSCS Documentation
IAMscs-0302Domain Manager configuration for Keystone
+

To configure and use the domain manager role from the SCS project, the +environments/kolla/files/overlays/keystone/policy.yaml file is created +in the configuration repository. The deployment and upgrade of the Keystone +service itself is then done as usual.

+
environments/kolla/files/overlays/keystone/policy.yaml
---
# SCS Domain Manager policy configuration

# Section A: OpenStack base definitons
# The entries beginning with "base_<rule>" should be exact copies of the
# default "identity:<rule>" definitions for the target OpenStack release.
# They will be extended upon for the domain manager role below this section.
"base_get_domain": "(role:reader and system_scope:all) or token.domain.id:%(target.domain.id)s or token.project.domain.id:%(target.domain.id)s"
"base_list_domains": "(role:reader and system_scope:all)"
"base_list_roles": "(role:reader and system_scope:all)"
"base_get_role": "(role:reader and system_scope:all)"
"base_list_users": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
"base_get_user": "(role:reader and system_scope:all) or (role:reader and token.domain.id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"
"base_create_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"
"base_update_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"
"base_delete_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"
"base_list_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
"base_get_project": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.project.domain_id)s) or project_id:%(target.project.id)s"
"base_create_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"
"base_update_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"
"base_delete_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"
"base_list_user_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"
"base_check_grant": "(role:reader and system_scope:all) or ((role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"
"base_list_grants": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)"
"base_create_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"
"base_revoke_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"
"base_list_role_assignments": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
"base_list_groups": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"
"base_get_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"
"base_create_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"
"base_update_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"
"base_delete_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"
"base_list_groups_for_user": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(user_id)s"
"base_list_users_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"
"base_remove_user_from_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"
"base_check_user_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"
"base_add_user_to_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"

# Section B: Domain Manager Extensions

# classify domain managers with a special role
"is_domain_manager": "role:manager"

# specify a rule that whitelists roles which domain admins are permitted
# to assign and revoke within their domain
"is_domain_managed_role": "'member':%(target.role.name)s or 'load-balancer_member':%(target.role.name)s or 'creator':%(target.role.name)s"

# allow domain admins to retrieve their own domain (does not need changes)
"identity:get_domain": "rule:base_get_domain or rule:admin_required"

# list_domains is needed for GET /v3/domains?name=... requests
# this is mandatory for things like
# `create user --domain $DOMAIN_NAME $USER_NAME` to correctly discover
# domains by name
"identity:list_domains": "rule:is_domain_manager or rule:base_list_domains or rule:admin_required"

# list_roles is needed for GET /v3/roles?name=... requests
# this is mandatory for things like `role add ... $ROLE_NAME`` to correctly
# discover roles by name
"identity:list_roles": "rule:is_domain_manager or rule:base_list_roles or rule:admin_required"

# get_role is needed for GET /v3/roles/{role_id} requests
# this is mandatory for the OpenStack SDK to properly process role assignments
# which are issued by role id instead of name
"identity:get_role": "(rule:is_domain_manager and rule:is_domain_managed_role) or rule:base_get_role or rule:admin_required"

# allow domain admins to manage users within their domain
"identity:list_users": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_users or rule:admin_required"
"identity:get_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_get_user or rule:admin_required"
"identity:create_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_create_user or rule:admin_required"
"identity:update_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_update_user or rule:admin_required"
"identity:delete_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_delete_user or rule:admin_required"

# allow domain admins to manage projects within their domain
"identity:list_projects": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_projects or rule:admin_required"
"identity:get_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_get_project or rule:admin_required"
"identity:create_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_create_project or rule:admin_required"
"identity:update_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_update_project or rule:admin_required"
"identity:delete_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_delete_project or rule:admin_required"
"identity:list_user_projects": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_user_projects or rule:admin_required"

# allow domain managers to manage role assignments within their domain
# (restricted to specific roles by the 'is_domain_managed_role' rule)
#
# project-level role assignment to user within domain
"is_domain_user_project_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s"
# project-level role assignment to group within domain
"is_domain_group_project_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.project.domain_id)s"
# domain-level role assignment to group
"is_domain_level_group_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.domain.id)s"
# domain-level role assignment to user
"is_domain_level_user_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.domain.id)s"
"domain_manager_grant": "rule:is_domain_manager and (rule:is_domain_user_project_grant or rule:is_domain_group_project_grant or rule:is_domain_level_group_grant or rule:is_domain_level_user_grant)"
"identity:check_grant": "rule:domain_manager_grant or rule:base_check_grant or rule:admin_required"
"identity:list_grants": "rule:domain_manager_grant or rule:base_list_grants or rule:admin_required"
"identity:create_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_create_grant or rule:admin_required"
"identity:revoke_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_revoke_grant or rule:admin_required"
"identity:list_role_assignments": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_role_assignments or rule:admin_required"


# allow domain managers to manage groups within their domain
"identity:list_groups": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_list_groups or rule:admin_required"
"identity:get_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_get_group or rule:admin_required"
"identity:create_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_create_group or rule:admin_required"
"identity:update_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_update_group or rule:admin_required"
"identity:delete_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_delete_group or rule:admin_required"
"identity:list_groups_for_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_groups_for_user or rule:admin_required"
"identity:list_users_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_list_users_in_group or rule:admin_required"
"identity:remove_user_from_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_remove_user_from_group or rule:admin_required"
"identity:check_user_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_check_user_in_group or rule:admin_required"
"identity:add_user_to_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_add_user_to_group or rule:admin_required"
+

The role manager is created using the OpenStack CLI. Alternatively, the role can +be added using Ansible or other tools.

+
$ openstack --os-cloud admin \
role create \
--or-show \
--description "Domain Manager Role" \
manager
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | Domain Manager Role |
| domain_id | None |
| id | 9b7140bfe628468ab9b86b365f9ac4c2 |
| name | manager |
| options | {} |
+-------------+----------------------------------+
+

A user can then be made a domain manager for a particular domain by assigning this role.

+
$ openstack --os-cloud admin \
role add \
--user test \
--domain test \
manager
+

OIDC Federation

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/magnum/index.html b/docs/iaas/guides/configuration-guide/openstack/magnum/index.html new file mode 100644 index 0000000000..1b3f9447fa --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/magnum/index.html @@ -0,0 +1,27 @@ + + + + + +Magnum | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/manila/index.html b/docs/iaas/guides/configuration-guide/openstack/manila/index.html new file mode 100644 index 0000000000..accfb37ad5 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/manila/index.html @@ -0,0 +1,28 @@ + + + + + +Manila | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/neutron/index.html b/docs/iaas/guides/configuration-guide/openstack/neutron/index.html new file mode 100644 index 0000000000..07801f1649 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/neutron/index.html @@ -0,0 +1,48 @@ + + + + + +Neutron | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Neutron

+ +

Neutron-Dynamic-Routing:

+ +

Neutron-VPNaaS:

+ +

MTU Considerations

+

Neutron uses the MTU of the underlying physical network to calculate the MTU for virtual network +components including instance network interfaces. By default, it assumes a standard 1500-byte MTU +for the underlying physical network.

+

Neutron only references the underlying physical network MTU. Changing the underlying physical network +device MTU requires configuration of physical network devices such as switches and routers.

+

The configuration is described in the Neutron admin guide. +The configuration files are placed under environments/kolla/files/overlays/neutron/ml2_conf.ini +and environments/kolla/files/overlays/neutron.conf.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/nova/index.html b/docs/iaas/guides/configuration-guide/openstack/nova/index.html new file mode 100644 index 0000000000..a15a151531 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/nova/index.html @@ -0,0 +1,81 @@ + + + + + +Nova | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Nova

+ +

Nested virtualisation

+

AMD

+
echo "options kvm-amd nested=y" | sudo tee /etc/modprobe.d/kvm-nested-virtualization.conf
sudo modprobe -r kvm_amd
sudo modprobe kvm_amd
cat /sys/module/kvm_amd/parameters/nested
Y
docker restart nova_libvirt
+

Intel

+
echo "options kvm-intel nested=y" | sudo tee /etc/modprobe.d/kvm-nested-virtualization.conf
sudo modprobe -r kvm_intel
sudo modprobe kvm_intel
cat /sys/module/kvm_intel/parameters/nested
Y
docker restart nova_libvirt
+

Reserve compute node resources

+

How many resources you want to reserve on a compute node depends very much on which additional +services are running on the compute node.

+

Host memory

+ +
environments/kolla/files/overlays/nova/nova-compute.conf
[DEFAULT]
reserved_host_memory_mb = 32768
+

Host CPUs

+ +
environments/kolla/files/overlays/nova/nova-compute.conf
[DEFAULT]
reserved_host_cpus = 4
+

Local SSD storage

+

In this example, a local SSD is provided for use on compute node testbed-node-0. +By default, Nova accesses the local storage on a file basis.

+

It is also possible to work with logical volumes instead. However, this is not +recommended or supported by OSISM. More details in the +Nova Configuration Guide.

+

On the compute node, the local SSD to be used is formatted with a file system of +your choice and mounted to /var/lib/nova. When using more than one local SSD, a +software RAID 1 should be used It is recommended to automate the creation of the +file system and the creation of the mount point with a custom playbook.

+

A nova.conf configuration file is created as an overlay file for the compute node +testbed-node-0. The name of the directory must match the name of the host in the +inventory. If the compute node has a file with the name testbed-node-0.yml in the +host_vars directory in the inventory, then the name of the directory +in the overlays is testbed-node-0 accordingly. If the file name there were +testbed-node-0.testbed.osism.xyz.yml then the name of the directory would be +testbed-node-0.testbed.osism.xyz.

+
environments/kolla/files/overlays/nova/testbed-node-0/nova.conf
[libvirt]
images_type = raw

[glance]
enable_rbd_download = true
+

As Ceph is still used as the storage backend for Glance and Cinder, the image type is +set to raw. To allow to download and cache images from Ceph via rbd rather than the +Glance API via http enable_rbd_download is set to true.

+

Parameters must also be added in the inventory. This differs depending on the OSISM +version used.

+

Up to OSISM 6 it looks like this:

+

In the inventory, the parameter nova_instance_datadir_volume +is added in the section for the kolla environment.

+
inventory/host_vars/testbed-node-0.yml
##########################################################
# kolla

nova_instance_datadir_volume: /var/lib/nova
+

Starting with OSISM 7, it looks like this:

+

In the inventory, the parameters nova_instance_datadir_volume and nova_backend, +are added in the section for the kolla environment.

+
inventory/host_vars/testbed-node-0.yml
##########################################################
# kolla

nova_instance_datadir_volume: /var/lib/nova
nova_backend: default
+

It is currently not possible to completely deactivate the Ceph integration with Nova. +So if you have all compute nodes with local storage, you still have to do the Ceph +integration for Nova itself and convert each compute node specifically to local storage. +If this is not done, errors will occur when deploying Nova.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/octavia/index.html b/docs/iaas/guides/configuration-guide/openstack/octavia/index.html new file mode 100644 index 0000000000..c3b89fdae1 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/octavia/index.html @@ -0,0 +1,28 @@ + + + + + +Octavia | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/placement/index.html b/docs/iaas/guides/configuration-guide/openstack/placement/index.html new file mode 100644 index 0000000000..123269925c --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/placement/index.html @@ -0,0 +1,28 @@ + + + + + +Placement | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/openstack/skyline/index.html b/docs/iaas/guides/configuration-guide/openstack/skyline/index.html new file mode 100644 index 0000000000..f3c5ede398 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/openstack/skyline/index.html @@ -0,0 +1,32 @@ + + + + + +Skyline | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/proxy/index.html b/docs/iaas/guides/configuration-guide/proxy/index.html new file mode 100644 index 0000000000..0da55a2617 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/proxy/index.html @@ -0,0 +1,40 @@ + + + + + +Proxy | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Proxy

+

In the following examples, it is assumed that the Squid proxy integrated by OSISM +is used on the first manager node. Any other proxy accessible from the nodes can +also be used here.

+

The Squid service can be deployed on the first manager. This is useful if no proxy +can be used in the environment. The first manager node is then used by all other nodes +as a pass-through node. Please note that this is not a caching proxy or even an air gap. +This is also possible with OSISM, but not with the help of the Squid service.

+
osism apply squid
+

Docker

+

This allows Docker images to be pulled via a proxy.

+
environments/configuration.yml
##########################################################
# proxy

docker_configure_proxy: true
docker_proxy_http: "http://{{ groups['manager'][0] }}:3128"
docker_proxy_https: "{{ docker_proxy_http }}"
+

APT

+

This allows APT packages to be downloaded via a proxy.

+
environments/configuration.yml
##########################################################
# proxy

proxy_proxies:
http: "http://{{ groups['manager'][0] }}:3128"
https: "http://{{ groups['manager'][0] }}:3128"
+

Kolla

+

Proxy settings for containers such as magnum that need internet access.

+
environments/kolla/configuration.yml
##########################################################
# proxy

container_http_proxy: "http://{{ groups['manager'][0] }}:3128"
container_https_proxy: "http://{{ groups['manager'][0] }}:3128"
container_no_proxy: "localhost,127.0.0.1"
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/self-signed-certificates/index.html b/docs/iaas/guides/configuration-guide/self-signed-certificates/index.html new file mode 100644 index 0000000000..47ff4b20a1 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/self-signed-certificates/index.html @@ -0,0 +1,49 @@ + + + + + +Self-signed certificates | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Self-signed certificates

+

The use of self-signed certificates with a custom CA is possible. However, a few +additional parameters are then required in the configuration so that the custom CA +is known everywhere and the self-signed certificates are accepted as valid.

+
    +
  1. +

    Import custom CA

    +

    Any custom CA can be added via the certificates_ca parameter. +The import on the nodes is done via osism apply certificates. +This is already done in the bootstrap of the nodes.

    +
    environments/configuration.yml
    certificates_ca:
    - name: custom.crt
    certificate: |
    -----BEGIN CERTIFICATE-----
    [...]
    -----END CERTIFICATE-----
    +
  2. +
  3. +

    Manager service

    +

    The local environment variable REQUESTS_CA_BUNDLE must be set explicitly so that +the manager service knows the custom CA in all necessary places.

    +
    environments/manager/configuration.yml
    manager_environment_extra:
    REQUESTS_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt
    +
  4. +
  5. +

    Use in OpenStack

    +

    The custom CA must also be copied into the OpenStack containers. To do this, the custom +CA is first added in a file in the environments/kolla/certificates/ca of the configuration +repository. It makes sense to use the same filename like in step 1.

    +

    The import of the custom CA must then be explicitly enabled.

    +
    environments/kolla/configuration.yml
    kolla_copy_ca_into_containers: "yes"
    openstack_cacert: /etc/ssl/certs/ca-certificates.crt
    +
  6. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/services/chrony/index.html b/docs/iaas/guides/configuration-guide/services/chrony/index.html new file mode 100644 index 0000000000..99769f953d --- /dev/null +++ b/docs/iaas/guides/configuration-guide/services/chrony/index.html @@ -0,0 +1,25 @@ + + + + + +Chrony | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/services/docker/index.html b/docs/iaas/guides/configuration-guide/services/docker/index.html new file mode 100644 index 0000000000..f2240f6881 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/services/docker/index.html @@ -0,0 +1,39 @@ + + + + + +Docker | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Docker

+

With the osism.services.docker role, it is possible to manage Docker.

+

Configure logging drivers

+

Docker documentation: https://docs.docker.com/config/containers/logging/configure/

+

The role currently supports the following parameters with their respective defaults.

+
docker_log_driver: "json-file"
docker_log_level: info
docker_log_opts:
max-size: 10m
max-file: 3
+

The log driver to be used can be configured with docker_log_driver. By default, +json-file is used. +The log driver writes all logs of a container to a JSON file +in /var/lib/docker/containers. All supported log drivers can be found in the +Docker documentation.

+

The log level can be configured via docker_log_level.

+

Parameters for the log driver used can be set with the docker_log_opts dictionary. +By default, the maximum size of a JSON file is set to 10 MByte with max-size: 10m. +If it contains more, the file is rotated.

+

Furthermore, max-file: 3 specifies that up to 3 files should be available.

+

Existing containers don't use the new logging configuration automatically.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/services/index.html b/docs/iaas/guides/configuration-guide/services/index.html new file mode 100644 index 0000000000..25e14962f9 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/services/index.html @@ -0,0 +1,25 @@ + + + + + +Services | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/services/tuned/index.html b/docs/iaas/guides/configuration-guide/services/tuned/index.html new file mode 100644 index 0000000000..c2a9d2cc70 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/services/tuned/index.html @@ -0,0 +1,29 @@ + + + + + +Tuned | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Tuned

+

The roller can be applied with osism apply tuned. The role is applied to all +compute nodes by default. This can be changed via the hosts_tuned parameter.

+

The profile to be used can be set via tuned_profile. By default, virtual-host +is used.

+

The following profiles are available:

+
ProfileDescription
accelerator-performanceThroughput performance based tuning with disabled higher latency STOP states
atomic-guestOptimize virtual guests based on the Atomic variant
atomic-hostOptimize bare metal systems running the Atomic variant
balancedGeneral non-specialized tuned profile
cpu-partitioningOptimize for CPU partitioning
defaultLegacy default tuned profile
desktopOptimize for the desktop use-case
desktop-powersaveOptmize for the desktop use-case with power saving
enterprise-storageLegacy profile for RHEL6, for RHEL7, please use throughput-performance profile
hpc-computeOptimize for HPC compute workloads
intel-sstConfigure for Intel Speed Select Base Frequency
laptop-ac-powersaveOptimize for laptop with power savings
laptop-battery-powersaveOptimize laptop profile with more aggressive power saving
latency-performanceOptimize for deterministic performance at the cost of increased power consumption
mssqlOptimize for MS SQL Server
network-latencyOptimize for deterministic performance at the cost of increased power consumption, focused on low latency network performance
network-throughputOptimize for streaming network throughput, generally only necessary on older CPUs or 40G+ networks
optimize-serial-consoleOptimize for serial console use.
oracleOptimize for Oracle RDBMS
postgresqlOptimize for PostgreSQL server
powersaveOptimize for low power consumption
realtimeOptimize for realtime workloads
sap-hanaOptimize for SAP HANA
sap-netweaverOptimize for SAP NetWeaver
server-powersaveOptimize for server power savings
spectrumscale-eceOptimized for Spectrum Scale Erasure Code Edition Servers
spindown-diskOptimize for power saving by spinning-down rotational disks
throughput-performanceBroadly applicable tuning that provides excellent performance across a variety of common server workloads
virtual-guestOptimize for running inside a virtual guest
virtual-hostOptimize for running KVM guests
+ + \ No newline at end of file diff --git a/docs/iaas/guides/configuration-guide/validations/index.html b/docs/iaas/guides/configuration-guide/validations/index.html new file mode 100644 index 0000000000..e1603b04a4 --- /dev/null +++ b/docs/iaas/guides/configuration-guide/validations/index.html @@ -0,0 +1,25 @@ + + + + + +Validations | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/bootstrap/index.html b/docs/iaas/guides/deploy-guide/bootstrap/index.html new file mode 100644 index 0000000000..9c32437214 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/bootstrap/index.html @@ -0,0 +1,126 @@ + + + + + +Bootstrap | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Bootstrap

+
info

The prerequisite for bootstraping the nodes of a cluster the Manager node has to be +prepares. What a Manager node is and how to prepare it is documented in the +Manager chapter of the Deploy Guide.

All the nodes must also have already been provisioned. How manual provisioning is done +is documented in the Provisioning chapter of the Deploy Guide.

+

Before the nodes can be bootstrapped, they must all have already been provisioned. +The guide for this can be found in the section Provisioning of bare-metal nodes.

+

The following steps are applied to bootstrap all nodes. After the completion of the bootstrap, +the nodes are already ready for use.

+
    +
  1. +

    Create operator user.

    +
    osism apply operator -u osism
    +
      +
    • +

      When using the osism/node-image the user is osism +and the password of this user is password. If you install Ubuntu manually the user usually +is ubuntu. If you want to use any other user here, that's no problem. It is important that +this user has sudo rights. The password according to what you have set yourself.

      +
    • +
    • +

      The operator public SSH key has to be added in advance on all nodes to authorized_keys file +of the user specified with -u. This key is stored as operator_public_key in the file +environments/configuration.yml.

      +

      Alternatively (not recommended), the password can be stored in plain text in a file /opt/configuration/secrets/conn_password. +The parameter --conn-pass-file /opt/configuration/secrets/conn_password must then also be specified:

      +
      osism apply operator -u osism \
      --conn-pass-file /opt/configuration/secrets/conn_password
      +
    • +
    • +

      It is important that this user has sudo rights with NOPASSWD.

      +

      Alternatively (not recommended), the password can be stored in plain text in a file /opt/configuration/secrets/become_password. +The parameter --become-pass-file /opt/configuration/secrets/become_password must then also be specified:

      +
      osism apply operator -u osism \
      --become-pass-file /opt/configuration/secrets/become_password
      +
    • +
    • +

      If a password is required for both sudo and login, use both arguments at the same time.

      +
      osism apply operator -u osism \
      --become-pass-file /opt/configuration/secrets/become_password \
      --conn-pass-file /opt/configuration/secrets/conn_password
      +
    • +
    • +

      When using the osism/node-image the user is osism and the password of this +user is password. If you install Ubuntu manually the user usually is ubuntu. The password according to what you +have set yourself

      +
    • +
    +
  2. +
  3. +

    Proxy deployment (optional). This is only necessary if you use the proxy on the manager to enable external access to +the nodes.

    +
    osism apply squid
    +
  4. +
  5. +

    Proxy configuration (optional). This is only necessary if you use the proxy on the manager to enable external access to +the nodes.

    +
    osism apply proxy
    +
  6. +
  7. +

    Network configuration. It is recommended to backup the existing network configuration.

    +
    osism apply network
    +
  8. +
  9. +

    Reboot (optional). The reboot at this point is recommended to ensure that the network configuration is working.

    +
    osism apply reboot -l 'all:!manager' -e ireallymeanit=yes
    +
  10. +
  11. +

    Check if all systems are reachable (you probably have to do this several times until all systems are accessible).

    +
    osism apply ping
    +
      +
    • +

      System is currently rebooting and is not yet accessible via network.

      +
      fatal: [net003]: UNREACHABLE! => {"changed": false, "msg": "Connection timed
      out.", "unreachable": true}``
      +
    • +
    • +

      System has already been rebooted and is not accessible via the network.

      +
      fatal: [net003]: UNREACHABLE! => {"changed": false, "msg": "EOF on stream;
      last 100 lines received:\nssh: connect to host 10.15.0.33 port 22: No route
      to host\r", "unreachable": true}
      +
    • +
    +
  12. +
  13. +

    Refresh facts.

    +
    osism apply facts
    +
  14. +
  15. +

    Bootstrap.

    +
    osism apply bootstrap
    +
  16. +
  17. +

    Reboot (non-optional). Since the kernel version often changes after the initial bootstrap, +the reboot should always be performed.

    +
    osism apply reboot -l 'all:!manager' -e ireallymeanit=yes
    +
  18. +
  19. +

    Check if all systems are reachable (you probably have to do this several times until all systems are accessible).

    +
    osism apply ping
    +
  20. +
  21. +

    Prepare the SSH configuration of the manager node.

    +
    osism apply sshconfig
    +
  22. +
  23. +

    Make all SSH public keys known.

    +
    osism apply known-hosts
    +
  24. +
+

Ready. All nodes are now bootstrapped and available to deploy services.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box/index.html b/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box/index.html new file mode 100644 index 0000000000..d16dbf8509 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box/index.html @@ -0,0 +1,26 @@ + + + + + +Cloud in a Box | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/examples/index.html b/docs/iaas/guides/deploy-guide/examples/index.html new file mode 100644 index 0000000000..730ba9b517 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/examples/index.html @@ -0,0 +1,23 @@ + + + + + +Examples | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/examples/testbed/index.html b/docs/iaas/guides/deploy-guide/examples/testbed/index.html new file mode 100644 index 0000000000..b8f4d0ed6f --- /dev/null +++ b/docs/iaas/guides/deploy-guide/examples/testbed/index.html @@ -0,0 +1,26 @@ + + + + + +Testbed | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/index.html b/docs/iaas/guides/deploy-guide/index.html new file mode 100644 index 0000000000..0800688f69 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/index.html @@ -0,0 +1,34 @@ + + + + + +Deploy Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/manager/index.html b/docs/iaas/guides/deploy-guide/manager/index.html new file mode 100644 index 0000000000..cec906139a --- /dev/null +++ b/docs/iaas/guides/deploy-guide/manager/index.html @@ -0,0 +1,157 @@ + + + + + +Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Manager

+
info

The prerequisite for deploying the Manager node is a Seed node. What a Seed node is +and how to prepare it is documented in the Seed chapter of the Deploy Guide.

+

The Manager node serves as the central administration instance for managing the cloud environment. +With the help of Ansible and other OSISM-specific components, the entire +life cycle of the system is coordinated from here (installation, customization, upgrades, etc.).

+

Requirements for the manager node:

+
    +
  • The system should have the following hardware features +
      +
    • at least 64 GB RAM (We assume here that the monitoring services are also run on the manager. +If the manager node is only used for the sanager Service, 32 GByte is sufficient and +with 16 GByte it will probably also work.
    • +
    • at least 256 GB hard disk space
    • +
    • the system should be initially and permanently accessible independently of the cloud environment +itself from the seed node
    • +
    • the system should have direct access to the network areas of the individual server systems in the +cloud environment
    • +
    +
  • +
  • An Ubuntu version matching the OSISM version should be provisioned on the system +(typically the latest Ubuntu LTS version, a system based on one of the OSISM node images +would be ideal)
  • +
  • No manual adjustments or installations should have been made on the system apart from the basic installation
  • +
  • The system has to be accessible from the seed node via SSH
  • +
+

Deploy the manager service

+

Change into the environments/manager directory of the configuration repository +on the seed node. The deployment of the seed node itself is documented in the +Deploy Guide for the seed node.

+
cd environments/manager
+

Step 1: Create operator user

+

The operator user is created on each node. It is used as a service account for OSISM. All +containers run with this user. Ansible also uses this user to access the nodes. Commands +on the manager node need to be run as this user. The name of the operator user is always dragon.

+

With ANSIBLE_USER the existing user account is set after the provsioning of the management +node. When using the osism/node-image the user is osism +and the password of this user is password. If you install Ubuntu manually the user usually +is ubuntu. If you want to use any other user here, that's no problem. It is important that +this user has sudo rights. The password according to what you have set yourself.

+

The ANSIBLE_USER parameter is only required when executing operator play using the run.sh +script. After this step, the ANSIBLE_USER is always set to dragon in the run.sh script. +It is therefore important to only set this parameter for exactly this step.

+
ANSIBLE_BECOME_ASK_PASS=True \
ANSIBLE_ASK_VAULT_PASS=True \
ANSIBLE_ASK_PASS=True \
ANSIBLE_USER=osism \
./run.sh operator
+

When the ./run.sh operator is executed, the following prompts are displayed.

+
PromptValueComment
SSH password:Password so that the ANSIBLE_USER can loginEnabled by ANSIBLE_ASK_PASS
BECOME password[defaults to SSH password]:Password so that the ANSIBLE_USER can use sudoEnabled by ANSIBLE_BECOME_ASK_PASS
Vault password:Value of secrets/vaultpassEnabled by ANSIBLE_ASK_VAULT_PASS
+
    +
  • +

    If a password is required to login to the manager node, ANSIBLE_ASK_PASS=True must be set.

    +
  • +
  • +

    If an SSH key is required to login to the manager node, the key has to be added on the manager +node to ~/.ssh/authorized_keys in the home directory of the user specified as ANSIBLE_USER first.

    +
  • +
  • +

    If the error ERROR! Attempting to decrypt but no vault secrets found occurs, ANSIBLE_ASK_VAULT_PASS=True +has to be set.

    +
  • +
  • +

    If the error /bin/sh: 1: /usr/bin/python: not found occurs, Python has to be installed first on +the manager node:

    +
    ANSIBLE_USER=osism ./run.sh python3
    +
  • +
  • +

    If you receive the following error message ssh: Too many authentication failures set +ANSIBLE_SSH_ARGS environment variable to use only the operator ssh key for authentication.

    +
    export ANSIBLE_SSH_ARGS="-o IdentitiesOnly=yes"
    +
  • +
  • +

    The warning message [WARNING]: running playbook inside collection osism.manager can be ignored

    +
  • +
  • +

    If Ansible Vault is used, let Ansible ask for the Vault password:

    +
    export ANSIBLE_ASK_VAULT_PASS=True
    +
  • +
+

Details on all parameters can be found in +Ansible Configuration Settings +in the Ansible documentation.

+
Environment variableTypeDescription
ANSIBLE_ASK_PASSBooleanThis controls whether an Ansible playbook should prompt for a login password. If using SSH keys for authentication, you probably do not need to change this setting.
ANSIBLE_ASK_VAULT_PASSBooleanThis controls whether an Ansible playbook should prompt for a vault password.
ANSIBLE_BECOME_ASK_PASSBooleanToggle to prompt for privilege escalation password.
ANSIBLE_SSH_ARGSStringIf set, this will override the Ansible default ssh arguments.
ANSIBLE_USERStringThe user Ansible ‘logs in’ as.
To verify the creation of the operator user, use the private key file id_rsa.operator. Make
sure you purge all keys from ssh-agent identity cache using ssh-add -D. You can print the list
using ssh-add -l. The list should be empty.
+
ssh-add -D
ssh -o IdentitiesOnly=yes -i id_rsa.operator dragon@testbed-manager
+

Step 2: Apply the network configuration

+

Most of the parameters required for Ansible (ANSIBLE_BECOME_ASK_PASS, ANSIBLE_ASK_PASS, ANSIBLE_USER, ...) +in the previous step are no longer necessary. If Ansible Vault is used, however, ANSIBLE_ASK_VAULT_PASS +must still be set.

+
export ANSIBLE_ASK_VAULT_PASS=True
+

To prevent recurring installation of Ansible Collections, export INSTALL_ANSIBLE_ROLES=False can be set.

+

The network configuration, already present on a node should be backuped before this step. +Then you can deploy the network configuration with the network role.

+
./run.sh network
+

Upon completion of the network configurtion, a node reboot should be performed to ensure the configuration +is functional and reboot safe. Since network services are not restarted automatically, later changes to the +network configuration are not effective without a manual apply of the network configuration or reboot of the +nodes.

+

Step 3: Bootstrap the manager node

+

Most of the parameters required for Ansible (ANSIBLE_BECOME_ASK_PASS, ANSIBLE_ASK_PASS, ANSIBLE_USER, ...) +in the previous step are no longer necessary.

+

If Ansible Vault is used, however, export ANSIBLE_ASK_VAULT_PASS=True must still be set.

+

To prevent recurring installation of Ansible Collections, export INSTALL_ANSIBLE_ROLES=False can be set. +This is recommended.

+
    +
  1. +

    Bootstrap the manager node.

    +
    ./run.sh bootstrap
    +
  2. +
  3. +

    Reboot the manager node.

    +
    ./run.sh reboot
    +
  4. +
+

Step 4: Deploy the manager service

+
    +
  1. +

    Transfer the configuration repository.

    +
    ./run.sh configuration
    +
  2. +
  3. +

    Deploy the Traefik service. This is optional and only necessary if the Traefik service is to be used.

    +
    ./run.sh traefik
    +
  4. +
  5. +

    Deploy the Netbox service. This is optional and only necessary if the Netbox service is to be used.

    +
    ./run.sh netbox
    +
  6. +
  7. +

    Deploy the manager service.

    +
    ./run.sh manager
    +
  8. +
+

Step 5: Set vault password on the manager service

+

Finally, the Ansible Vault password is made known on the manager node. Before that, log in to the manager node +with the dragon user.

+
osism set vault password
Ansible Vault password: ********
+

Ready. The manager is now prepared and you can continue with the bootstrap of the other nodes. +The seed node used until here is no longer necessary.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/provisioning/index.html b/docs/iaas/guides/deploy-guide/provisioning/index.html new file mode 100644 index 0000000000..53f39f07ba --- /dev/null +++ b/docs/iaas/guides/deploy-guide/provisioning/index.html @@ -0,0 +1,112 @@ + + + + + +Provisioning of bare-metal nodes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Provisioning of bare-metal nodes

+

For the initial deployment of the management plane and the control plane of OSISM, +the nodes must be pre-provisioned with Ubuntu 22.04. Currently, only Ubuntu 22.04 is supported +by OSISM.

+

Data plane nodes can be automatically provisioned after the initial deployment and +do not need to be pre-provisioned.

+

It is recommended not to install the initial nodes of the management plane and the +control plane manually. An ISO image is provided for this purpose which automatically +provisions a node. The ISO images are available for download in the +osism/node-image repository.

+

There are different variants of the ISO image. The variants differ in the disc layout. +The available variants are described in the README file of the osism/node-image +repository.

+

Manual provisioning

+

If none of the provided variants is suitable, this section describes the manual +installation with the help of the Ubuntu 22.04 live ISO image. The manual installation +is possible without network connectivity.

+
    +
  • Download the latest ISO image for Ubuntu 22.04 from releases.ubuntu.com. +
      +
    • Use the ubuntu-22.04.1-live-server-amd64.iso image.
    • +
    • The version number may be different, always use the latest available version of 22.04 LTS.
    • +
    +
  • +
  • Choose English as language.
  • +
  • Choose Install Ubuntu Server.
  • +
  • Choose English as language (again).
  • +
  • Choose your location (e.g. Germany).
  • +
  • Choose en_US.UTF-8 as locale.
  • +
  • Choose the keyboard layout from a list, use English (US).
  • +
  • Choose and configure the primary network interface. +
      +
    • Depending on the environment, the network may not work at this point. Then select any interface +and then select Do not configure the network at this time in the next step.
    • +
    +
  • +
  • Set the hostname. +
      +
    • The hostname is e.g. node and not a FQDN like node.systems.osism.xyz.
    • +
    +
  • +
  • Set osism as full name for the new user.
  • +
  • Set osism as the username for the account. +
      +
    • The later used operator user dragon is created during the bootstrap and should not be created during the installation
    • +
    • The account is only needed initially and can be deleted after completion of the bootstrap.
    • +
    +
  • +
  • Set a password for the account.
  • +
  • Choose Manual as partitioning method and execute the partitioning according to company specifications +
      +
    • The use of a UEFI is recommended
    • +
    • The use of a RAID is recommended. We prefer the use of software RAIDs to make us less dependent on hardware. +But there is nothing against using hardware RAIDs.
    • +
    • The use of a LVM2 is recommended. system is recommended as the name for the volume group.
    • +
    • Dedicated disks may be provided for /var/lib/docker on the controller nodes. In this case, do not +use an LV for /var/lib/docker but the devices provided for it.
    • +
    • Do not configure devices that are not required for the operating system.
    • +
    • The use of own file systems for the following mountpoints is recommended. The size of the partitions/LVs +is minimal. Depending on the node type, the partitions/LVs should be made larger. +
        +
      • / (10 GByte, logical volume root)
      • +
      • /home (2 GByte, logical volume home)
      • +
      • /tmp (5 GByte, logical volume tmp)
      • +
      • /var/lib/ceph (50 GByte, logical volume ceph) (optional for storage nodes)
      • +
      • /var/lib/docker (30 GByte, logical volume docker, do not set the nosuid flag on /var/lib/docker) +
          +
        • When using XFS as the file system for /var/lib/docker, note the following: Running on XFS without d_type support +causes Docker to skip the attempt to use the overlay or overlay2 driver.
        • +
        • 100 GB should be used on a control node at the beginning.
        • +
        • /var/lib/docker must be extended later during operation depending on the node type. You do this +in operation when you can see how many logs etc. are generated.
        • +
        +
      • +
      • /var/log/audit (1 GByte, logical volume audit)
      • +
      • /var (10 GByte, logical volume var)
      • +
      • swap (8 GByte, logical volume swap)
      • +
      +
    • +
    +
  • +
  • Choose No automatic updates.
  • +
  • Choose OpenSSH server as software to install. +
      +
    • Do not install any other software component. Everything you need will be installed later by OSISM. +In particular, it is not necessary to install a desktop environment.
    • +
    +
  • +
  • After completion, restart the system.
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/seed/index.html b/docs/iaas/guides/deploy-guide/seed/index.html new file mode 100644 index 0000000000..35fe8662a1 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/seed/index.html @@ -0,0 +1,63 @@ + + + + + +Seed | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Seed

+
info

The prerequisite for the deployment of a cluster is a configuration repository. +What a configuration repository is and how it is created is described in the +Configuration Guide.

+

The seed node is used once for the initial bootstrap of the manager node. The seed node can +also be used to initially create and prepare the configuration repository. The seed node is +not the manager node itself. It is sufficient to use the local workstation. It doesn't have +to be a dedicated system. The seed node is no longer needed in the further process. The seed +node must be able to reach the manager node via SSH. It is important for the further process +that no packages are installed manually on the manager. Especially not Docker.

+

The use of Linux on the seed node is recommended. Other operating systems should also +work without problems. It is assumed in this documentation that Ubuntu 22.04 is used on +the seed node.

+

Install required packages

+
sudo apt-get install git python3-pip python3-virtualenv sshpass
+

Get a copy of the configuration repository

+

Each environment managed with OSISM is based on a configuration repository. This was +previously created with Cookiecutter and the osism/cfg-cookiecutter +repository.

+

The creation of the configuration repository is covered in chapter +Creation of a configuration repository +of the Configuration Guide.

+

A configuration repository is stored on a Git server (e.g. GitHub, Gitlab, ...). The +configuration repository is individual for each environment and is therefore not provided +by us.

+

The configuration repository to be used must be available on the seed node. In the following +example, replace YOUR_ORG and YOUR_NEW_CONFIGURATION_REPOSITORY accordingly.

+
git clone ssh://git@github.com:YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY.git
+

Examples:

+
    +
  • The repository is located in the regiocloud organisation on GitHub, has the name +configuration and can be accessed via SSH: ssh://git@github.com:regiocloud/configuration.git
  • +
  • The repository is located in the regiocloud organisation on Gitlab, has the name configuration +and can be accessed via SSH: ssh://git@gitlab.com:regiocloud/configuration.git
  • +
  • The repository is located in the regiocloud organisation on an internal Gitlab, has the name +configuration and can be accessed via SSH: ssh://git@git.services.osism.tech:regiocloud/configuration.git
  • +
+

If necessary, the configuration SSH key can be used for the initial transfer of the repository.

+

For this, the following content is added in ~/.ssh/config and the SSH privte key is stored in +~/.ssh/id_rsa.configuration.

+
Host github.com
HostName github.com
User git
Port 22
IdentityFile ~/.ssh/id_rsa.configuration
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/ceph/index.html b/docs/iaas/guides/deploy-guide/services/ceph/index.html new file mode 100644 index 0000000000..7ef3c98fa5 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/ceph/index.html @@ -0,0 +1,143 @@ + + + + + +Ceph | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Ceph

+

In OSISM it is also possible to integrate and use existing Ceph clusters. It +is not necessary to deploy Ceph with OSISM. If Ceph is deployed with OSISM, it +should be noted that OSISM does not claim to provide all possible features of Ceph. +Ceph provided with OSISM is intended to provide the storage for Glance, Nova, Cinder +and Manila. In a specific way that has been implemented by OSISM for years. It +should be checked in advance whether the way in OSISM the Ceph deployment and the +provided features are sufficient. If this is not the case, it is recommended to +deploy Ceph in a different way directly and independently of OSISM. For possible +open source projects, please refer to +cephadm and +Rook.

+
warning

Before starting the Ceph deployment, the configuration and creation of the necessary LVM2 +volumes must be completed. The steps that are required for this can be found in the +Ceph Configuration Guide.

+
    +
  1. +

    Deploy services.

    +
      +
    • +

      Deploy ceph-mon services

      +
      osism apply ceph-mons
      +
    • +
    • +

      Deploy ceph-mgr services

      +
      osism apply ceph-mgrs
      +
    • +
    • +

      Deploy ceph-osd services

      +
      osism apply ceph-osds
      +
    • +
    • +

      Generate pools and keys. This step is only necessary for OSISM >= 7.0.0.

      +
      osism apply ceph-pools
      +
    • +
    • +

      Deploy ceph-crash services

      +
      osism apply ceph-crash
      +
    • +
    +
    info

    It's all done step by step here. It is also possible to do this in a single step. +This speeds up the entire process and avoids unnecessary restarts of individual +services.

    osism apply ceph

    Generate pools and keys.

    osism apply ceph-pools
    +
  2. +
  3. +

    Get ceph keys. This places the necessary keys in /opt/configuration.

    +
    osism apply copy-ceph-keys
    +

    After run, these keys must be permanently added to the configuration repository +via Git.

    +
    environments/infrastructure/files/ceph/ceph.client.admin.keyring
    environments/kolla/files/overlays/gnocchi/ceph.client.gnocchi.keyring
    environments/kolla/files/overlays/nova/ceph.client.cinder.keyring
    environments/kolla/files/overlays/nova/ceph.client.nova.keyring
    environments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder.keyring
    environments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder-backup.keyring
    environments/kolla/files/overlays/cinder/cinder-volume/ceph.client.cinder.keyring
    environments/kolla/files/overlays/manila/ceph.client.manila.keyring
    environments/kolla/files/overlays/glance/ceph.client.glance.keyring
    +

    If the osism apply copy-ceph-keys fails because the keys are not found in the /share +directory, this can be ignored. The keys of the predefined keys (e.g. for Manila) were +then not created as they are not used. If you only use Ceph and do not need the predefined +keys for OpenStack at all, you can also overwrite the ceph_kolla_keys parameter to skip +these keys.

    +
    environments/ceph/configuration.yml
    ceph_kolla_keys: []
    +
  4. +
  5. +

    After the Ceph keys have been persisted in the configuration repository, the Ceph +client can be deployed.

    +
    osism apply cephclient
    +
  6. +
  7. +

    Enable and prepare the use of the Ceph dashboard.

    +
    osism apply ceph-bootstrap-dashboard
    +
  8. +
+

RGW service

+

Deployment of the Ceph RGW Service is optional. How the Ceph RGW service can be deployed +and integrated into OpenStack is described here.

+
info

If an initial deployment is performed and Ceph RGW is not added to an existing deployment, +steps 4 and 5 are not required.

Step 3 is then performed later after the OpenStack Keystone service has been deployed.

+
    +
  1. +

    Configure the RGW service

    +
  2. +
  3. +

    Apply role ceph-rgws to deploy the Ceph RGW services.

    +
    osism apply ceph-rgws
    +
  4. +
  5. +

    Apply role kolla-ceph-rgw to add the OpenStack endpoint. +If an initial deployment is performed and Ceph RGW is not added +to an existing deployment run this step later after the OpenStack +Keystone service has been deployed.

    +
    osism apply kolla-ceph-rgw
    +
  6. +
  7. +

    Apply role loadbalancer to add the HAProxy backend and frontend.

    +
    osism apply loadbalancer
    +
  8. +
  9. +

    Apply role horizon to enable the Swift dashboard.

    +
    osism apply horizon
    +
  10. +
+

Avoiding service restarts

+
info

Usable from OSISM 7.0.3 onwards.

+

If Ceph services are deployed sequentially, this can lead to unwanted service restarts. +This can also happen if, for example, new OSDs are added later or a new control node is +added.

+

The Ceph RGW services are deployed here without restarting the Ceph OSD services.

+
osism apply ceph-rgws -e ceph_handler_osds_restart=False
+

The following parameters are available. Any number of parameters can be used with a single command.

+
ceph_handler_crash_restart
ceph_handler_mdss_restart
ceph_handler_mgrs_restart
ceph_handler_mons_restart
ceph_handler_osds_restart
ceph_handler_rbdmirrors_restart
ceph_handler_rgws_restart
+

Throttling service restarts

+
info

Usable from OSISM 7.0.3 onwards.

+

Sometimes service restarts are required. For example, if the configuration has changed +or if new OSDs have been added. It may be necessary and useful to only restart the +services on a specific number of nodes at a specific time.

+

Further information on throttling can be found in the +Ansible documentation.

+

The Ceph OSD services are deployed here. If there is a restart required of other OSDs +that are already running, these restarts are executed on a maximum of 2 nodes at the +same time. The OSD services themselves on a node are always restarted one after the other +and never all at the same time.

+
osism apply ceph-osds -e ceph_handler_osds_restart_throttle=2
+

If the nodes are to be processed one after the other, ceph_handler_osds_restart_throttle=1 +can be used.

+

The following parameters are available. Any number of parameters can be used with a single command.

+
ceph_handler_crash_restart_throttle
ceph_handler_mdss_restart_throttle
ceph_handler_mgrs_restart_throttle
ceph_handler_mons_restart_throttle
ceph_handler_osds_restart_throttle
ceph_handler_rbdmirrors_restart_throttle
ceph_handler_rgws_restart_throttle
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/index.html b/docs/iaas/guides/deploy-guide/services/index.html new file mode 100644 index 0000000000..3cfa5d316c --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/index.html @@ -0,0 +1,34 @@ + + + + + +Services | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/infrastructure/index.html b/docs/iaas/guides/deploy-guide/services/infrastructure/index.html new file mode 100644 index 0000000000..fb6e5e396b --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/infrastructure/index.html @@ -0,0 +1,56 @@ + + + + + +Infrastructure | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Infrastructure

+

Common issues with deploying infrastructure services required by OpenStack +are documented in the OpenStack Troubleshooting Guide.

+
    +
  1. +

    Cron, Fluentd & Kolla Toolbox

    +

    The common role of Kolla is used to manage the services cron, fluentd +and kolla-toolbox.

    +

    It is important to do this deployment before any other deployements in the Kolla +environment, as parts of the other deployments depend on the kolla-toolbox +service.

    +
    osism apply -a pull common
    osism apply common
    +
  2. +
  3. +

    Loadbalancer

    +
    osism apply -a pull loadbalancer
    osism apply loadbalancer
    +
  4. +
  5. +

    Redis

    +
    osism apply -a pull redis
    osism apply redis
    +
  6. +
  7. +

    Memcached

    +
    osism apply -a pull memcached
    osism apply memcached
    +
  8. +
  9. +

    RabbitMQ

    +
    osism apply -a pull rabbitmq
    osism apply rabbitmq
    +
  10. +
  11. +

    MariaDB

    +
    osism apply -a pull mariadb
    osism apply mariadb
    +
  12. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/kubernetes/index.html b/docs/iaas/guides/deploy-guide/services/kubernetes/index.html new file mode 100644 index 0000000000..200c3bcb79 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/kubernetes/index.html @@ -0,0 +1,48 @@ + + + + + +Kubernetes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Kubernetes

+
info

As of OSISM 7, it is possible to create a Kubernetes cluster on all nodes. +At the moment, this is still optional. In the future, it will be necessary +to deploy this Kubernetes cluster.

+
    +
  1. +

    Deploy the K3s cluster.

    +
    osism apply kubernetes
    +
  2. +
  3. +

    Deploy the Kubernetes dashboard:

    +
    osism apply kubernetes-dashboard
    +
  4. +
+

Cluster API

+
    +
  1. +

    Deploy the Cluster API management cluster on the K3s cluster:

    +
    osism apply clusterapi
    +
  2. +
  3. +

    Add the kubeconfig file to the configuration repository (required later by OpenStack +Magnum Service):

    +
    osism apply copy-kubeconfig
    +
  4. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/logging-monitoring/index.html b/docs/iaas/guides/deploy-guide/services/logging-monitoring/index.html new file mode 100644 index 0000000000..5301dbec66 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/logging-monitoring/index.html @@ -0,0 +1,40 @@ + + + + + +Logging & Monitoring | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Logging & Monitoring

+

Common issues with deploying logging & monitoring services provided by Kolla +are documented in the OpenStack Troubleshooting Guide.

+
    +
  1. +

    OpenSearch

    +

    OpenSearch dashboards is also deployed with the opensearch role.

    +
    osism apply -a pull opensearch
    osism apply opensearch
    +
  2. +
  3. +

    Prometheus

    +
    osism apply -a pull prometheus
    osism apply prometheus
    +
  4. +
  5. +

    Grafana

    +
    osism apply -a pull grafana
    osism apply grafana
    +
  6. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/network/index.html b/docs/iaas/guides/deploy-guide/services/network/index.html new file mode 100644 index 0000000000..2a5da44485 --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/network/index.html @@ -0,0 +1,40 @@ + + + + + +Network | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Network

+
    +
  1. +

    Open vSwitch (OVS)

    +
    osism apply -a pull openvswitch
    osism apply openvswitch
    +
  2. +
  3. +

    Open Virtual Network (OVN)

    +

    In environments/kolla/configuration.yml the parameter neutron_plugin_agent is set to +ovn if OVN is used as a network plugin. The parameter is set to ovn by default in the +Cookiecutter.

    +
    environments/kolla/configuration.yml
    # neutron
    neutron_plugin_agent: "ovn"
    +

    Otherwise the network plugin is set to openvswitch. +If the neutron_plugin_agent is set to openvswitch, this step does not need to be done.

    +

    Before the deployment of OVN, the deployment of Open vSwitch must already have been done.

    +
    osism apply -a pull ovn
    osism apply ovn
    +
  4. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/deploy-guide/services/openstack/index.html b/docs/iaas/guides/deploy-guide/services/openstack/index.html new file mode 100644 index 0000000000..84771aad7a --- /dev/null +++ b/docs/iaas/guides/deploy-guide/services/openstack/index.html @@ -0,0 +1,80 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

OpenStack

+

Common issues with deploying OpenStack services are documented in the +OpenStack Troubleshooting Guide.

+
info

An OpenStack deployment contains a number of components providing APIs to access infrastructure resources. +The OpenStack Components +page lists the various services that can be deployed to provide such resources to cloud end users. +Unfortunately, not all of the OpenStack projects listed there are still active. +Not all of the services listed there are supported by OSISM.

+
    +
  1. +

    OpenStack client

    +
    osism apply openstackclient
    +
  2. +
  3. +

    Keystone

    +
    osism apply -a pull keystone
    osism apply keystone
    +
  4. +
  5. +

    Glance

    +
    osism apply -a pull glance
    osism apply glance
    +
  6. +
  7. +

    Designate

    +
    osism apply -a pull designate
    osism apply designate
    +
  8. +
  9. +

    Placement

    +
    osism apply -a pull placement
    osism apply placement
    +
  10. +
  11. +

    Cinder

    +
    osism apply -a pull cinder
    osism apply cinder
    +
  12. +
  13. +

    Neutron

    +
    osism apply -a pull neutron
    osism apply neutron
    +
  14. +
  15. +

    Nova

    +
    osism apply -a pull nova
    osism apply nova
    +
  16. +
  17. +

    Octavia

    +
    osism apply -a pull octavia
    osism apply octavia
    +

    9.1. Manage amphora image

    +

    This step is only necessary if the Amphora Driver is used. If OVN is used as the driver, +this step is not necessary.

    +

    We provide regularly updated images for Octavia in +osism/openstack-octavia/amphora-image. +The OSISM CLI can be used to upload the correct image depending on the OpenStack release +used.

    +
    osism manage image octavia
    +
  18. +
  19. +

    Horizon

    +
    osism apply -a pull horizon
    osism apply horizon
    +
  20. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/index.html b/docs/iaas/guides/index.html new file mode 100644 index 0000000000..2dfb33fabe --- /dev/null +++ b/docs/iaas/guides/index.html @@ -0,0 +1,38 @@ + + + + + +Guides | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Guides

+
    +
  • The Concept Guide explains which components and modules make up OSISM. It also +explains the use cases.
  • +
  • The Deploy Guide explains how the nodes of a cluster are created and bootstrapped. +It also explains how the individual modules can be deployed.
  • +
  • The Upgrade Guide explains how the individual modules can be upgraded.
  • +
  • The Configuration Guide explains how the individual modules can be +configured.
  • +
  • The Operations Guide explains how individual tasks can be done in +day-to-day business in a running cluster.
  • +
  • The Troubleshooting Guide explains how to resolve problems. +It is an extension of the Operations Guide.
  • +
  • The User Guide is intended for users of the individual components. It contains +best practices, as well as other information.
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/ceph/index.html b/docs/iaas/guides/operations-guide/ceph/index.html new file mode 100644 index 0000000000..f56dc5a344 --- /dev/null +++ b/docs/iaas/guides/operations-guide/ceph/index.html @@ -0,0 +1,428 @@ + + + + + +Ceph | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Ceph

+

Where to find docs

+

The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/operations/

+

It is strongly advised to use the documentation for the version being used.

+ +
note

Do not take information in the documentation at face value. +Especially when it comes to advanced/rarely used/very new features it is strongly advised +to test any claims made in the documentation about any particular feature.

Never assume that things will work as written without actually testing it on a test setup +as close to your real workload scenario as possible.

+

Advice on Ceph releases

+

The current Ceph releases and their support status can be found on https://docs.ceph.com/en/latest/releases/

+

When a new Ceph stable version is released you are strongly advised +to not roll it out on any production cluster whatsoever. +Even though its listed as "stable" it doesn't mean that this is actually true. +Especially avoid using .0 releases on anything remotely production +unless you really, really now what you're doing and can live with a possible catastrophic failure.

+

Be very conservative about what version you run on production systems.

+

Shiny new features aren't worth the risk of total or partial data loss/corruption.

+

General maintenance

+

60 seconds cluster overview

+

The following commands can be used to quickly check the status of Ceph:

+
    +
  • +

    Print overall cluster status

    +
    ceph -s
    +
  • +
  • +

    Print detailed health information

    +
    ceph health detail
    +
  • +
  • +

    Display current OSD tree

    +
    ceph osd tree
    +
  • +
  • +

    Cluster storage usage by pool and storage class

    +
    ceph df
    +
  • +
  • +

    List pools with detailed configuration

    +
    ceph osd pool ls detail
    +
  • +
  • +

    Get usage stats for OSDs

    +
    ceph osd df {plain|tree} {class e.g. hdd|ssd}
    +
  • +
  • +

    Watch Ceph health messages sequentially

    +
    ceph -w
    +
  • +
  • +

    List daemon versions running in the cluster

    +
    ceph versions
    +
  • +
+

Also you can run the following on each node running ceph-daemons, +to provide further debug information about the environment:

+
# lscpu
# cat /proc/cpuinfo # if lscpu isn't available
# free -g
# ip l
# ethtool <device> # for each network adapter
+

Mute/Unmute a health warning

+
$ ceph health mute <what> <duration>
$ ceph health unmute <what>
+

Disable/Enable (deep-)scrubbing

+
$ ceph osd set noscrub
$ ceph osd set nodeep-scrub
$ ceph osd unset noscrub
$ ceph osd unset nodeep-scrub
+
warning

Use this sparingly only in emergency situations. +Setting these flags will cause a HEALTH_WARN status, +increase risk of data corruption and also the risk of generating +a HEALTH_WARN due to PGs not being (deep-)scrubbed in time.

+

Reboot a single node

+

The traditional way of doing this is by setting the noout flag, +do the appropriate maintenance work and after the node is back online +unset the flag like so:

+
ceph osd set noout
+

After maintenance is done and host is back up:

+
ceph osd unset noout
+

On versions Luminous or above you can set the flag individually for single +OSDs or entire CRUSH buckets, which can be a safer option in case of prolonged +maintenance periods.

+

Add noout for a OSD:

+
ceph osd add-noout osd.<ID>
+

Remove noout for a OSD:

+
ceph osd rm-noout osd.<ID>
+

Add noout for CRUSH bucket (e.g. host name as seen in ceph osd tree):

+
ceph osd set-group noout <crush-bucket-name>
+

Remove noout for CRUSH bucket:

+
ceph osd unset-group noout <crush-bucket-name>
+

Gathering information about block devices

+

Enumerate typical storage devices and LVM

+
# lsblk
# lsblk -S
# lsscsi
# nvme list
# pvs
# vgs
# lvs
+

SMART data for SATA/SAS and NVME devices

+
# smartctl -a /dev/sdX
# nvme smart-log /dev/nvmeXnY
+

Check format of a NVME device

+
# nvme id-ns -H /dev/nvmeXnY
+
note

Check the last lines named "LBA Format". +It will show which formats are supported, +which format is in use and which format offers the best performance +according to the vendor.

+

Format a NVME device to a different LBA format using nvme-cli

+
warning

This will destroy all data on the device!

+
# nvme format --lbaf=<id> /dev/nvmeXnY
+

Secure Erase a NVME drive using nvme-cli

+
warning

This will destroy all data on the device!

+
# nvme format -s2 /dev/nvmeXnY
# blkdiscard /dev/nvmeXnY
# nvme format -s1 /dev/nvmeXnY
+

Secure Erase a SATA/SAS drive using hdparm

+
warning

This will destroy all data on the device!

+
    +
  1. +

    Gather device info:

    +
    # hdparm -I /dev/sdX
    +
  2. +
+

Check that the output says "not frozen" and "not locked", +also it should list support for enhanced erase and list time estimates +for SECURITY ERASE UNIT and/or ENHANCED SECURITY ERASE UNIT

+
    +
  1. +

    Set a master password for the disk (required, will be automatically removed after wipe)

    +
    # hdparm --user-master wipeit --security-set-pass wipeit /dev/sdX
    # hdparm -I /dev/sdX
    +

    Check that "Security level" is now "high" and master password is now +"enabled" instead of "not enabled" before

    +
  2. +
  3. +

    Wipe the device

    +

    If device supports enhanced security erase (better), use the following:

    +
    # hdparm --user-master wipeit --security-erase-enhanced wipeit /dev/sdX
    +

    If not, use standard security erase:

    +
    # hdparm --user-master wipeit --security-erase wipeit /dev/sdX
    +
  4. +
+
note

On some systems the system firmware might "freeze" the device, +which makes it impossible to issue a secure erase or reformat the device. +In that case it might be necessary to either "unfreeze" the drive or +to install the drive in another system where it can be unfrozen. +Also make sure that the device is actually wiped. Its recommended to +at least perform a blanking pass on HDDs with a tool like nwipe.

+

OSD maintenance tasks

+

Locate a specific OSD in the cluster

+
$ ceph osd find osd.<ID>
+

Get OSD metadata (global and single OSD)

+
$ ceph osd metadata
$ ceph osd metadata osd.<ID>
+

Interesting fields:

+
    +
  • bluefs_db_rotational
  • +
  • bluefs_dedicated_db
  • +
  • bluefs_dedicated_wal
  • +
  • bluefs_wal_rotational
  • +
  • bluestore_bdev_rotational
  • +
  • device_ids
  • +
  • device_paths
  • +
  • devices
  • +
  • hostname
  • +
  • osd_objectstore
  • +
  • rotational
  • +
+

Add a new OSD

+

Replace a defect OSD

+

Remove a OSD

+

As with ‘Remove a single OSD node’. Except that the steps are only executed +for a single OSD and the node is not removed from the CRUSH map and the inventory. +Only the entries relating to the removed OSD are removed from the host vars.

+

Manual way

+
$ ceph osd crush reweight osd.<ID> 0.0
# Wait for rebalance to complete...
$ ceph osd out osd.<ID>
# systemctl stop ceph-osd@<ID>
# systemctl disable ceph-osd@<ID>
$ ceph osd purge osd.<ID> --yes-i-really-mean-it
+

The LV and VG defined in the inventory for this OSD must also be removed. The +OSD itself should be wiped.

+

Remove a single OSD node

+
    +
  1. +

    Get all OSDs of the node

    +
    $ ceph osd tree
    ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
    -1 0.11691 root default
    -3 0.03897 host testbed-node-0
    0 hdd 0.01949 osd.0 up 1.00000 1.00000
    4 hdd 0.01949 osd.4 up 1.00000 1.00000
    -5 0.03897 host testbed-node-1
    1 hdd 0.01949 osd.1 up 1.00000 1.00000
    3 hdd 0.01949 osd.3 up 1.00000 1.00000
    -7 0.03897 host testbed-node-2
    2 hdd 0.01949 osd.2 up 1.00000 1.00000
    5 hdd 0.01949 osd.5 up 1.00000 1.00000
    +
  2. +
  3. +

    Reduce the weighting of all OSDs on the node to 0. Do this for each OSD +in a row and wait after each adjustment until the Ceph cluster is balanced. +Depending on how large the Ceph cluster and the individual OSDs are, this +may take some time.

    +
    $ ceph osd crush reweight osd.2 0.0
    $ ceph osd crush reweight osd.5 0.0
    +

    The Ceph OSDs that are to be removed then have a weight of 0.

    +
    $ ceph osd tree
    ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
    -1 0.07794 root default
    -3 0.03897 host testbed-node-0
    0 hdd 0.01949 osd.0 up 1.00000 1.00000
    4 hdd 0.01949 osd.4 up 1.00000 1.00000
    -5 0.03897 host testbed-node-1
    1 hdd 0.01949 osd.1 up 1.00000 1.00000
    3 hdd 0.01949 osd.3 up 1.00000 1.00000
    -7 0 host testbed-node-2
    2 hdd 0 osd.2 up 1.00000 1.00000
    5 hdd 0 osd.5 up 1.00000 1.00000
    +
  4. +
  5. +

    Remove the OSDs and everything that belongs to them from the node. +This is a disruptive action that cannot be undone. The devices used +are also reset.

    +
    $ osism apply ceph-shrink-osd -e ireallymeanit=yes -e osd_to_kill=2,5
    +

    All OSDs were removed.

    +
    $ ceph osd tree
    ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
    -1 0.07794 root default
    -3 0.03897 host testbed-node-0
    0 hdd 0.01949 osd.0 up 1.00000 1.00000
    4 hdd 0.01949 osd.4 up 1.00000 1.00000
    -5 0.03897 host testbed-node-1
    1 hdd 0.01949 osd.1 up 1.00000 1.00000
    3 hdd 0.01949 osd.3 up 1.00000 1.00000
    -7 0 host testbed-node-2
    +
  6. +
  7. +

    Remove the node from the CRUSH map.

    +
    $ ceph osd crush remove testbed-node-2
    removed item id -7 name 'testbed-node-2' from crush map
    +
  8. +
  9. +

    Remove the node from all Ceph groups in the inventory.

    +
  10. +
  11. +

    Remove all Ceph-specific parameters from the host vars of the node from the +inventory

    +
  12. +
+

Remove an OSD (temporarily e.g. when replacing a broken disk)

+
$ ceph osd out osd.<ID>
# systemctl stop ceph-osd@<ID>
# systemctl disable ceph-osd@<ID>
+

Disable backfills/recovery completely

+
warning

Use only in emergency situations!

+
$ ceph osd set nobackfill
$ ceph osd set norecovery
$ ceph osd set norebalance
+

Unset the flags with ceph osd unset <flag>.

+

Rebalance OSDs

+

Placement Group maintenance

+

Dump placement groups

+

Usually only useful when parsing it, so here are two ways to get the data:

+
$ ceph pg dump
$ ceph pg dump --format=json-pretty
+

Query a PG about its status

+
$ ceph pg <pgid> query
+

Start (deep-)scrubbing of a placement group

+
$ ceph pg scrub <pgid>
$ ceph pg deep-scrub <pgid>
+
note

Instructing a PG to (deep-)scrub does not mean that it will do so immediately, +it can take some time for the scrub to start.

+

HEALTH_WARN - Large omap objects found...

+

Finding PGs which have large OMAP objects:

+
# ceph pg dump --format=json | jq '.pg_map.pg_stats[] |
select(.stat_sum.num_large_omap_objects != 0) |
(.pgid, .stat_sum.num_large_omap_objects, .up, .acting)'
+

(Remove the line breaks between the single quotes or jq might act weird!)

+

This will dump all PG IDs with large OMAP objects and their up/acting OSDs. +You then can grep the logs of these OSDs for "Large omap object" +to find the actual objects causing the health warning.

+

Also the PG ID before the dot is equal to the pool ID it belongs to.

+

In case the logs have been rotated, instruct those OSDs to do a deep-scrub +and watch the logs for the message to appear.

+

From there you can investigate the issue further, +mostly it'll be due to the index of a RGW bucket getting too big due to too many objects, +thus resharding that bucket's index will be necessary.

+

Instruct a PG to repair in case of scrub errors (inconsistent PG)

+
$ ceph pg repair <pgid>
+
note

Recovery might not start immediately and might take some time. +You can query the status of the recovery through ceph pg <pgid> query. +Be sure to read the Ceph manual about this topic thoroughly:

https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshooting-pg/

+

RADOS Pool maintenance

+
note

Read the RADOS pool operations documentation in detail before playing around with pools. +Especially when considering making changes to the CRUSH map. +Wrong decisions there can lead to data loss or other catastrophic failures.

https://docs.ceph.com/en/latest/rados/operations/pools/

+

Get pools and their configuration

+
$ ceph osd pool ls detail
+

Dump all CRUSH rules

+
$ ceph osd crush rule dump
+

Get autoscaler status

+
$ ceph osd pool autoscale-status
+

Create a replicated pool

+
$ ceph osd pool create <pool_name> <pg_num> <pgp_num> replicated [<crush_rule_name>]
+

Enabling an application on a pool

+

Required, otherwise a health warning will be raised after some time.

+
$ ceph osd pool application enable <pool_name> <application_name> # Syntax
$ ceph osd pool application enable cinder rbd # Example
+

Typical application names are: rbd, rgw, cephfs

+

Delete a pool

+
warning

This will delete all data in that pool. There is no undo/undelete.

+
$ ceph osd pool delete <pool_name> <pool_name> --yes-i-really-really-mean-it
+
note

In order to be able to delete pools, it has to be enabled on the monitors +by setting the mon_allow_pool_delete flag to true. Default is false.

See: https://docs.ceph.com/en/latest/rados/configuration/mon-config-ref

+

Set number of PGs for a pool

+

If no autoscaling of PGs is used, it is very important to adapt the PGs per pool to the +real world when operating a Ceph cluster. If, for example, OSDs are exchanged, added, new +nodes are added, etc., the number of PGs must also be taken into account.

+

The PG Calc Tool can be used +to calculate a reasonable number of PGs per pool depending on all ODSs and pools.

+

Further information on placement groups can be found in the +Ceph documentation. +You should definitely read FACTORS RELEVANT TO SPECIFYING PG_NUM and CHOOSING THE NUMBER OF PGS +there.

+
$ ceph osd pool set <poolname> pg_num <num_pgs>
+
note

Num PGs must be a power of two! Be careful about changing number of PGs. +Changing pg_num to a new value will gradually increase pgp_num on newer versions of Ceph.

In older versions one also has to set pgp_num manually, either in increments or in one big leap.

+

Create CRUSH rules for different storage classes

+
$ ceph osd crush rule create-replicated replicated_hdd default host hdd
$ ceph osd crush rule create-replicated replicated_ssd default host ssd
$ ceph osd crush rule create-replicated replicated_nvme default host nvme
+

Change CRUSH rule for a pool ("move pool")

+
$ ceph osd pool set <poolname> crush_rule <rule_name>
+

This can be used to move a pool from e.g. HDD to SSD or NVME class +or anything else that the new CRUSH rule specifies.

+

Advanced topics

+

Validating Ceph using OSISM playbooks

+

For Ceph, special playbooks were added to validate the deployment status of +the OSD, MON and MGR services. The commands for use are osism validate ceph-osds, +osism validate ceph-mons, and osism validate ceph-mgrs.

+

These playbooks will validate that the deployed Ceph environment matches +the configuration and is overall in a healthy state. The playbooks will +generate report files in JSON format on the first manager node in /opt/reports/validator.

+

Shutdown a Ceph cluster

+

In order to fully shutdown a Ceph cluster safely, you first do the following steps:

+
warning

Take GOOD NOTES of the unit names and OSD IDs running on each node. +You will need them to restart the cluster later.

+
    +
  1. +

    Stop the workload that is using the cluster

    +

    This will vary depending on your environment and is not covered here.

    +
  2. +
  3. +

    Pause/Stop operations on the cluster by setting flags

    +
    $ ceph osd set noout
    $ ceph osd set nobackfill
    $ ceph osd set norecover
    $ ceph osd set norebalance
    $ ceph osd set nodown
    $ ceph osd set pause
    +
  4. +
  5. +

    Stop and disable the radosgw services on all nodes (on each rgw node) (if RGW is used)

    +

    Get the name of the unit (globs not supported for disable) and +make a note of the unit name for that node:

    +
    # systemctl | grep ceph-radosgw
    +

    Then disable and stop the unit:

    +
    # systemctl disable --now ceph-radosgw@<name>.service
    +
  6. +
  7. +

    Stop all CephFS file systems (if CephFS is used)

    +

    List all Ceph file systems

    +
    $ ceph fs ls
    +

    For each CephFS do:

    +
    $ ceph fs <file system name> down true
    +
  8. +
  9. +

    After that disable and stop all ceph-mds services on all nodes (do this on each node)

    +

    Get the name of the unit (globs not supported for disable) and +make a note of the unit name for that node:

    +
    # systemctl | grep ceph-mds
    +
    # systemctl disable --now ceph-mds@<unit>.service
    +
  10. +
  11. +

    Stop and disable the ceph-mgr services on all nodes (do this on each node)

    +

    Get the name of the unit (globs not supported for disable) and +make a note of the unit name for that node:

    +
    # systemctl | grep ceph-mgr
    +
    # systemctl disable --now ceph-mgr@<unit>.service
    +
  12. +
  13. +

    Stop and disable the ceph-osd services on all nodes (do this on each node)

    +

    Get the names of the units (globs not supported for disable) and +make a note of the unit names for that node (best to save it to a file):

    +
    # systemctl | grep ceph-osd
    +

    For each OSD unit execute:

    +
    # systemctl disable ceph-osd@<osd-id>.service
    +

    Stop all OSDs at once:

    +
    # systemctl stop ceph-osd\*.service
    +
  14. +
  15. +

    Finally stop the ceph-mon services on all nodes (do this on each node)

    +

    Get the name of the unit (globs not supported for disable) and +make a note of the unit name for that node:

    +
    # systemctl | grep ceph-mon
    +
    # systemctl disable --now ceph-mon@<unit>.service
    +
  16. +
+

Restart a Ceph cluster after manual shutdown

+
warning

You will need the notes taken during shutdown of the unit names. +It can be done without, but then it'll be way more work finding out the names.

+

In order to restart a Ceph cluster after performing a manual shutdown like described +in the section above, you do the following:

+
    +
  1. +

    Enable & start the ceph-mon services on all nodes (do this on each node)

    +
    # systemctl enable --now ceph-mon@<unit-name>.service
    +
  2. +
  3. +

    Enable & start the ceph-osd services on all nodes (do this on each node)

    +

    For each Ceph OSD on that node do:

    +
    # systemctl enable --now ceph-osd@<osd-id>.service
    +

    Depending on the number of OSDs on that node it can take a while.

    +
  4. +
  5. +

    Enable & start the ceph-mgr services on all nodes (do this on each node)

    +
    # systemctl enable --now ceph-mgr@<unit-name>.service
    +
  6. +
  7. +

    Check the status of your cluster and wait for all OSDs to come online

    +

    You can watch the status periodically by running:

    +
    $ watch ceph -s
    +

    You should wait until all OSDs are up + in again, before removing flags.

    +
  8. +
  9. +

    Remove flags to unpause operations

    +
    $ ceph osd unset pause
    $ ceph osd unset nodown
    $ ceph osd unset noout
    $ ceph osd unset nobackfill
    $ ceph osd unset norecover
    $ ceph osd unset norebalance
    +
  10. +
  11. +

    Wait for cluster to resume operations

    +

    See step #4 of this SOP. +Now you wait until the cluster seems "happy enough" to accept clients. +(i.e. rebalancing finished etc.) +Maybe it will complain about MDS being down, but that's normal for now.

    +
  12. +
  13. +

    Enable & start the ceph-mds services on each node (if CephFS is used)

    +
    # systemctl enable --now ceph-mds@<unit>.service
    +
  14. +
  15. +

    Start CephFS file systems again

    +

    List all Ceph file systems

    +
    $ ceph fs ls
    +

    For each CephFS do:

    +
    $ ceph fs <file system name> down false
    +
  16. +
  17. +

    Enable & start the radosgw services on each node (if RGW is used)

    +
    # systemctl enable --now ceph-radosgw@<name>.service
    +
  18. +
+

Performance benchmark

+
# apt-get install -y fio
+
#!/usr/bin/env bash

BENCH_DEVICE="$2"
DATE=$(date +%s)
IOENGINE="libaio"
LOGPATH="$1"
SIZE=1G

mkdir -p $LOGPATH

for RW in "write" "randwrite" "read" "randread"
do
for BS in "4K" "64K" "1M" "4M" "16M" "64M"
do
(
echo "==== $RW - $BS - DIRECT ===="
echo 3 > /proc/sys/vm/drop_caches
fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json
sync
echo 3 > /proc/sys/vm/drop_caches
echo "==== $RW - $BS - DIRECT IODEPTH 32 ===="
fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --iodepth=32 --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-iod32-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json
sync
) | tee $LOGPATH/$RW.$BS-$(basename $BENCH_DEVICE).$DATE.log
echo
done
done
+

Where and how to get further help

+

Join the #ceph IRC channel on irc.oftc.net, state the problem with as many details as possible +including information about what steps have already been taken to solve the problem +also provide information from the command output from the "60 seconds cluster overview" above +through a pastebin or a similar service. In order for people to be able +to help, details and some patience are important.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/index.html b/docs/iaas/guides/operations-guide/index.html new file mode 100644 index 0000000000..bcea50e02b --- /dev/null +++ b/docs/iaas/guides/operations-guide/index.html @@ -0,0 +1,64 @@ + + + + + +Operations Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Operations Guide

+

Change Node states

+

A node can be in different states. Depending on the state, different actions +are possible or are triggered.

+

The individual states of a node can be retrieved via Ansible Facts and local +files on the node itself.

+

Maintenance

+
osism set maintenance NODE
osism noset maintenance NODE
+
    +
  • Ansible fact: ansible_local.osism.maintenance
  • +
  • State file: /etc/osism/maintenance
  • +
+

Bootstrap

+
osism set bootstrap NODE
osism noset bootstrap NODE
+
    +
  • Ansible fact: ansible_local.osism.bootstrap
  • +
  • State file: /etc/osism/bootstrap
  • +
+

Use of custom plays

+

Custom Plays can be used in all environments in the configuration repository.

+

For example, this is a play to prepare all devices to be used for Ceph on a Ceph +resource node. It is saved in the configuration repository in the file +environments/ceph/playbook-wipe-partitions.yml. It is run with +osism apply -e ceph wipe-parititons.

+
---
- name: Wipe partitions
hosts: ceph-resource
gather_facts: false

tasks:
- name: Wipe partitions
become: true
ansible.builtin.shell: |
wipefs --all "{{ item }}"
dd if=/dev/zero of="{{ item }}" bs=1 count=4096
changed_when: false
with_items: "{{ devices }}"
+

Manage services

+
osism apply manage-service \
-e service_name=rsysloc \
-e service_state=restarted
+

Manage containers

+
osism apply manage-container \
-e container_name=nova_compute \
-e container_action=restart
+

Reboot nodes

+

When using reboot play, the node is rebooted directly. It is not ensured in +advance that there is no more payload on the node and no services etc. are +disabled.

+

Reboot node testbed-node-0.testbed.osism.xyz and wait until the reboot has +been completed and the system is accessible again.

+
osism apply reboot \
-e reboot_wait=True \
-e ireallymeanit=yes \
-l testbed-node-0.testbed.osism.xyz
+

Reboot node testbed-node-0.testbed.osism.xyz and do not wait for the reboot +to complete.

+
osism apply reboot \
-e ireallymeanit=yes \
-l testbed-node-0.testbed.osism.xyz
+

Working with the OOB Board via IPMI

+

Display the IP address

+
$ sudo ipmitool lan print | grep 'IP Address'
IP Address Source : DHCP Address
IP Address : 10.10.0.100
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/infrastructure/index.html b/docs/iaas/guides/operations-guide/infrastructure/index.html new file mode 100644 index 0000000000..7e1af595d8 --- /dev/null +++ b/docs/iaas/guides/operations-guide/infrastructure/index.html @@ -0,0 +1,49 @@ + + + + + +Infrastructure | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Infrastructure

+

MariaDB

+

Backup

+

Mariabackup is used to create backups +of MariaDB.

+
    +
  • +

    Full backup

    +
    osism apply mariadb_backup
    +
  • +
  • +

    Incremental backup (supported as of OSISM 7.0.6)

    +
    osism apply mariadb_backup -e mariadb_backup_type=incremental
    +
  • +
+

There is a Docker volume mariadb_backup on the 1st control node. The backups +are stored in this volume.

+
$ docker run --rm -v mariadb_backup:/backup -it ubuntu:22.04 bash -c 'ls -la /backup'
total 9728
drwxr-xr-x 2 42434 42434 4096 Jun 3 18:46 .
drwxr-xr-x 1 root root 4096 Jun 3 18:47 ..
-rw-r--r-- 1 42434 42434 4530618 Jun 3 18:46 incremental-18-mysqlbackup-03-06-2024-1717440409.qp.xbc.xbs.gz
-rw-r--r-- 1 42434 42434 11 Jun 3 18:45 last_full_date
-rw-r--r-- 1 42434 42434 5411763 Jun 3 18:45 mysqlbackup-03-06-2024-1717440342.qp.xbc.xbs.gz
+

Restore

+

https://docs.openstack.org/kolla-ansible/latest/admin/mariadb-backup-and-restore.html#restoring-backups

+

Recovery

+
osism apply mariadb_recovery
+ +

Get all indices

+
$ curl https://api-int.testbed.osism.xyz:9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open flog-2024.04.17 1rCP3NpUQSS5wmulCn6Y5g 1 1 1657832 0 1gb 654.4mb
green open .opensearch-observability UnS2gFb-QhC8oIefL3C52Q 1 2 0 0 624b 208b
green open .plugins-ml-config hMdzW6ooRMGZ_0OGcdNSgA 1 1 1 0 7.8kb 3.9kb
green open .opendistro-job-scheduler-lock fa_Io8bJQ8qfGII4DypxFg 1 1 1 3 51.1kb 35.1kb
green open .kibana_1 v-aJ6ioSQsOwHQn_NNbeOg 1 1 0 0 416b 208b
+

Delete an index

+
$ curl -X DELETE https://api-int.testbed.osism.xyz:9200/flog-2024.04.17
{"acknowledged":true}
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/manager/apply/index.html b/docs/iaas/guides/operations-guide/manager/apply/index.html new file mode 100644 index 0000000000..022dd8b767 --- /dev/null +++ b/docs/iaas/guides/operations-guide/manager/apply/index.html @@ -0,0 +1,25 @@ + + + + + +Apply | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Apply

+

List all available plays

+
$ osism apply
2023-09-30 10:09:25 | INFO | No role given for execution. The roles listed in the table can be used.
+------------------------------------------------------------------+----------------+
| Role | Environment |
|------------------------------------------------------------------+----------------|
| aodh | kolla |
| barbican | kolla |
| bifrost | kolla |
| bifrost-keypair | kolla |
| ceilometer | kolla |
| certificates | generic |
| cinder | kolla |
| cloudkitty | kolla |
| collectd | kolla |
| common | kolla |
| designate | kolla |
| elasticsearch | kolla |
| etcd | kolla |
| glance | kolla |
| gnocchi | kolla |
| grafana | kolla |
| heat | kolla |
| horizon | kolla |
| ironic | kolla |
| iscsi | kolla |
...
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/manager/console/index.html b/docs/iaas/guides/operations-guide/manager/console/index.html new file mode 100644 index 0000000000..1706db351c --- /dev/null +++ b/docs/iaas/guides/operations-guide/manager/console/index.html @@ -0,0 +1,42 @@ + + + + + +Console | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Console

+

A console command is available in the OSISM CLI. This allows specific parts of the +environment to be operated interactively.

+

Ansible

+

Used tool: ansible-console

+
$ osism console --type ansible testbed-node-0
Welcome to the ansible console. Type help or ? to list commands.

dragon@testbed-node-0 (1)[f:5]$ !uptime
testbed-node-0 | CHANGED | rc=0 >>
18:14:15 up 80 days, 33 min, 0 users, load average: 4.00, 3.07, 2.67
dragon@testbed-node-0 (1)[f:5]$
+

Shortcut: osism console .testbed-node-0

+

Clush

+

Used tool: ClusterShell

+

The same groups as defined in the Ansible Inventory can be used.

+
$ osism console --type clush control
Enter 'quit' to leave this interactive mode
Working with nodes: testbed-node-[0-2]
clush>
+

Shortcut: osism console :control

+

Container

+

Used tool: Python Prompt Toolkit

+
$ osism console --type container testbed-node-0/fluentd
(fluentd)[td-agent@testbed-node-0 /]$ ps ax
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 dumb-init --single-child -- kolla_start
7 ? Sl 24:28 /opt/td-agent/bin/ruby /usr/sbin/td-agent -o /var/log/kolla/fluentd/fluent
25 ? Sl 3519:55 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /usr/sbin/td-agent -o /var
238 pts/0 Ss 0:00 bash
247 pts/0 R+ 0:00 ps ax
+

Shortcut: osism console testbed-node-0/fluentd

+

SSH

+

Used tool: OpenSSH

+
$ osism console --type ssh testbed-node-0
You have new mail.
Last login: Wed Sep 27 18:15:39 2023 from 192.168.16.5
dragon@testbed-node-0:~$ uptime
18:16:25 up 80 days, 35 min, 1 user, load average: 2.85, 3.04, 2.71
+

Shortcut: osism console testbed-node-0

+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/manager/get/index.html b/docs/iaas/guides/operations-guide/manager/get/index.html new file mode 100644 index 0000000000..f4f4ac3bcb --- /dev/null +++ b/docs/iaas/guides/operations-guide/manager/get/index.html @@ -0,0 +1,57 @@ + + + + + +Get | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Get

+

A get command is available in the OSISM CLI. This allows to gather specific information.

+

Hosts

+
    +
  • +

    Get all hosts defined in the inventory

    +
    $ osism get hosts
    +-----------------------------------+
    | Host |
    |-----------------------------------|
    | testbed-manager.testbed.osism.xyz |
    | testbed-node-0.testbed.osism.xyz |
    | testbed-node-1.testbed.osism.xyz |
    | testbed-node-2.testbed.osism.xyz |
    +-----------------------------------+
    +
  • +
  • +

    Get all hosts defined in the inventory that are member of a specific inventory group

    +
    $ osism get hosts -l manager
    +-----------------------------------+
    | Host |
    |-----------------------------------|
    | testbed-manager.testbed.osism.xyz |
    +-----------------------------------+

    $ osism get hosts -l control
    +----------------------------------+
    | Host |
    |----------------------------------|
    | testbed-node-0.testbed.osism.xyz |
    | testbed-node-1.testbed.osism.xyz |
    | testbed-node-2.testbed.osism.xyz |
    +----------------------------------+
    +
  • +
+

Host variables

+
    +
  • +

    Get all host vars of a specific node

    +
    osism get hostvars testbed-manager.testbed.osism.xyz
    +
  • +
  • +

    Get a specific host var of a specific node

    +
    $ osism get hostvars testbed-manager.testbed.osism.xyz ansible_host
    +-----------------------------------+--------------+----------------+
    | Host | Variable | Value |
    +===================================+==============+================+
    | testbed-manager.testbed.osism.xyz | ansible_host | '192.168.16.5' |
    +-----------------------------------+--------------+----------------+
    +
  • +
+

Host facts

+
    +
  • +

    Get all facts of a specific node

    +
    osism get facts testbed-manager.testbed.osism.xyz
    +
  • +
  • +

    Get a specific fact of a specific node

    +
    $ osism get facts testbed-manager.testbed.osism.xyz ansible_architecture
    +-----------------------------------+----------------------+----------+
    | Host | Fact | Value |
    +===================================+======================+==========+
    | testbed-manager.testbed.osism.xyz | ansible_architecture | 'x86_64' |
    +-----------------------------------+----------------------+----------+
    +
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/manager/index.html b/docs/iaas/guides/operations-guide/manager/index.html new file mode 100644 index 0000000000..e5536f0df7 --- /dev/null +++ b/docs/iaas/guides/operations-guide/manager/index.html @@ -0,0 +1,24 @@ + + + + + +Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/manager/log/index.html b/docs/iaas/guides/operations-guide/manager/log/index.html new file mode 100644 index 0000000000..3ca64a1e79 --- /dev/null +++ b/docs/iaas/guides/operations-guide/manager/log/index.html @@ -0,0 +1,48 @@ + + + + + +Logging | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Logging

+

Ansible

+

Files

+

Each Ansible service has its own local Ansible log file. These log files are not persistent. The ARA service is +used for the persistence of Ansible logs. The log files can be used to view currently running Ansible Plays, +for example if they are running as a background task.

+
$ docker exec -it osism-ansible tail -f /ansible/logs/ansible.log
$ docker exec -it ceph-ansible tail -f /ansible/logs/ansible.log
$ docker exec -it kolla-ansible tail -f /ansible/logs/ansible.log
+

ARA - ARA Records Ansible

+
$ osism log ansible
(ara) help

Documented commands (use 'help -v' for verbose/'help <topic>' for details):
===========================================================================
alias exit history quit run_script shell
edit help macro run_pyscript set shortcuts

Application commands (type help <topic>):
=========================================
complete host metrics playbook delete record delete result show
expire host show playbook list record list task delete
help play delete playbook metrics record show task list
host delete play list playbook prune result delete task metrics
host list play show playbook show result list task show
+

Sample usage

+

As an example, the role common is run. Irrelevant parts of outputs have been removed.

+
$ osism apply common
+
$ osism log ansible
+
(ara) play list
+----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+
| id | status | name | playbook | tasks | results | started | duration |
+----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+
| 69 | completed | Apply role common | 49 | 21 | 68 | 2023-09-30T10:14:01.731212Z | 00:00:38.238032 |
+----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+
+
(ara) play show 69
+----------+------------------------------------------+
| Field | Value |
+----------+------------------------------------------+
| id | 69 |
| report | http://ara-server:8000/playbooks/49.html |
| status | completed |
| name | Apply role common |
| playbook | (49) /ansible/kolla-common.yml |
| started | 2023-09-30T10:14:01.731212Z |
| ended | 2023-09-30T10:14:39.969244Z |
| duration | 00:00:38.238032 |
| items | {'tasks': 21, 'results': 68} |
+----------+------------------------------------------+
+
(ara) task list
+-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+
| id | status | results | action | name | playbook | started | duration |
+-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+
| 910 | completed | 0 | meta | common : Flush handlers | 49 | 2023-09-30T10:14:37.126872Z | 00:00:02.552006 |
| 909 | completed | 4 | file | common : Link kolla_logs volume to /var/log/kolla | 49 | 2023-09-30T10:14:35.502754Z | 00:00:01.039468 |
| 908 | completed | 4 | kolla_docker | common : Creating log volume | 49 | 2023-09-30T10:14:34.134312Z | 00:00:01.076976 |
| 907 | completed | 4 | kolla_docker | common : Check common containers | 49 | 2023-09-30T10:14:31.411916Z | 00:00:02.146165 |
| 906 | completed | 4 | template | common : Copy rabbitmq erl_inetrc to kolla toolbox | 49 | 2023-09-30T10:14:29.500998Z | 00:00:01.327607 |
| 905 | completed | 4 | template | common : Copy rabbitmq-env.conf to kolla toolbox | 49 | 2023-09-30T10:14:27.979869Z | 00:00:01.231630 |
| 904 | completed | 4 | file | common : Ensuring config directories have correct owner and permission | 49 | 2023-09-30T10:14:26.422535Z | 00:00:01.263370 |
| 903 | completed | 4 | template | common : Ensure RabbitMQ Erlang cookie exists | 49 | 2023-09-30T10:14:24.880329Z | 00:00:01.255475 |
| 902 | completed | 4 | template | common : Copying over cron logrotate config file | 49 | 2023-09-30T10:14:23.199518Z | 00:00:01.392765 |
| 901 | completed | 4 | template | common : Copying over td-agent.conf | 49 | 2023-09-30T10:14:21.085351Z | 00:00:01.826039 |
| 900 | completed | 1 | find | common : Find custom fluentd output config files | 49 | 2023-09-30T10:14:19.859670Z | 00:00:00.939663 |
| 899 | completed | 1 | find | common : Find custom fluentd format config files | 49 | 2023-09-30T10:14:18.711171Z | 00:00:00.858586 |
| 898 | completed | 1 | find | common : Find custom fluentd filter config files | 49 | 2023-09-30T10:14:17.542234Z | 00:00:00.877270 |
| 897 | completed | 1 | find | common : Find custom fluentd input config files | 49 | 2023-09-30T10:14:15.911699Z | 00:00:01.315217 |
| 896 | completed | 4 | template | common : Copying over config.json files for services | 49 | 2023-09-30T10:14:13.588195Z | 00:00:02.031647 |
| 895 | completed | 4 | copy | service-cert-copy : common | Copying over backend internal TLS key | 49 | 2023-09-30T10:14:12.216984Z | 00:00:01.074853 |
| 894 | completed | 4 | copy | service-cert-copy : common | Copying over backend internal TLS certificate | 49 | 2023-09-30T10:14:10.895833Z | 00:00:01.022530 |
| 893 | completed | 4 | copy | service-cert-copy : common | Copying over extra CA certificates | 49 | 2023-09-30T10:14:08.551850Z | 00:00:02.040932 |
| 892 | completed | 4 | include_tasks | common : include_tasks | 49 | 2023-09-30T10:14:07.019883Z | 00:00:00.950605 |
| 891 | completed | 4 | file | common : Ensuring config directories exist | 49 | 2023-09-30T10:14:04.801633Z | 00:00:01.926842 |
| 890 | completed | 4 | include_tasks | common : include_tasks | 49 | 2023-09-30T10:14:03.054547Z | 00:00:01.166032 |
+-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+
+
(ara) task show 910
+----------+------------------------------------------+
| Field | Value |
+----------+------------------------------------------+
| id | 910 |
| uuid | 0242ac1f-6510-3867-9eea-00000000004f |
| report | http://ara-server:8000/playbooks/49.html |
| name | common : Flush handlers |
| action | meta |
| status | completed |
| path | /ansible/roles/common/tasks/deploy.yml |
| lineno | 8 |
| started | 2023-09-30T10:14:37.126872Z |
| ended | 2023-09-30T10:14:39.678878Z |
| duration | 00:00:02.552006 |
| tags | ['common'] |
| handler | False |
+----------+------------------------------------------+
+
(ara) playbook list
+----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+
| id | status | controller | user | ansible_version | path | tasks | results | hosts | started | duration |
+----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+
| 49 | completed | kolla-ansible.manager_default | dragon | 2.14.10 | /ansible/kolla-common.yml | 21 | 68 | 5 | 2023-09-30T10:14:01.410334Z | 00:00:39.135309 |
+----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+
+
(ara) playbook metrics
+---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+
| aggregate | count | duration_total | duration_avg | tasks | results | hosts | completed | failed | running |
+---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+
| /ansible/kolla-common.yml | 2 | 0:02:53.934432 | 0:01:26.967216 | 46 | 152 | 10 | 2 | 0 | 0 |
+---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+
+
(ara) host list
+-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+
| id | name | playbook | changed | failed | ok | skipped | unreachable | updated |
+-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+
| 164 | testbed-node-2.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.543599Z |
| 161 | testbed-manager.testbed.osism.xyz | 49 | 0 | 0 | 18 | 2 | 0 | 2023-09-30T10:14:40.283581Z |
| 163 | testbed-node-1.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.280601Z |
| 162 | testbed-node-0.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.279181Z |
| 165 | kolla-ansible.manager_default | 49 | 0 | 0 | 0 | 0 | 0 | 2023-09-30T10:14:16.932135Z |
+-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+
+
(ara) host show 164
+-------------+------------------------------------------+
| Field | Value |
+-------------+------------------------------------------+
| id | 164 |
| report | http://ara-server:8000/playbooks/49.html |
| name | testbed-node-2.testbed.osism.xyz |
| changed | 0 |
| failed | 0 |
| ok | 14 |
| skipped | 2 |
| unreachable | 0 |
| updated | 2023-09-30T10:14:40.543599Z |
+-------------+------------------------------------------+
+

Container

+
$ osism log container testbed-node-0 horizon
[...]
++++ APACHE_LOCK_DIR=/var/lock/apache2
++++ export APACHE_LOG_DIR=/var/log/apache2
++++ APACHE_LOG_DIR=/var/log/apache2
++++ export LANG=C
++++ LANG=C
++++ export LANG
+++ install -d /var/run/apache2/
+++ rm -rf '/var/run/apache2/*'
+++ [[ ubuntu =~ centos|rocky ]]
+ echo 'Running command: '\''/usr/sbin/apache2 -DFOREGROUND'\'''
+ exec /usr/sbin/apache2 -DFOREGROUND
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.16.10. Set the 'ServerName' directive globally to suppress this message
+

OpenSearch

+

OpenSearch can be queried with SQL.

+
$ osism log opensearch
>>> SELECT * FROM flog-2023.10.31 LIMIT 1;
Oct 31 10:45:36 testbed-node-0 docker[847573]: cluster 2023-10-31T10:45:35.498718+0000 mgr.testbed-node-0 (mgr.5184) 24194 : cluster [DBG] pgmap v24196: 321 pgs: 321 active+clean; 577 KiB data, 270 MiB used, 60 GiB / 60 GiB avail

>>> SELECT * FROM flog-2023.10.31 LIMIT 5;
Oct 31 11:19:57 testbed-node-2 docker[880827]: 2023-10-31T11:19:57.650+0000 7fa7e7c88700 0 [dashboard INFO root] Redirecting to active 'http://192.168.16.10:7000/'
Oct 31 11:19:57 testbed-node-2 docker[880827]: 2023-10-31T11:19:57.650+0000 7fa7e7c88700 0 [dashboard INFO request] [::ffff:192.168.16.11:56210] [OPTIONS] [302] [0.001s] [105.0B] [8a69cc7a-23db-410b-b744-cc5689cb4f4c] /
Oct 31 11:19:58 testbed-node-2 docker[844686]: cluster 2023-10-31T11:19:56.329684+0000 mgr.testbed-node-0 (mgr.5184) 25224 : cluster [DBG] pgmap v25226: 321 pgs: 321 active+clean; 577 KiB data, 270 MiB used, 60 GiB / 60 GiB avail
Oct 31 11:19:58 testbed-node-2 docker[844686]: debug 2023-10-31T11:19:58.566+0000 7fdbc9728700 1 mon.testbed-node-2@2(peon).osd e74 _set_new_cache_sizes cache_size:1020054731 inc_alloc: 348127232 full_alloc: 348127232 kv_alloc: 322961408
Oct 31 11:19:58 testbed-node-2 docker[880827]: 2023-10-31T11:19:58.710+0000 7fa7eb48f700 0 [dashboard INFO root] Redirecting to active 'http://192.168.16.10:7000/'

>>> SELECT * FROM flog-2023.10.31 WHERE Hostname = 'testbed-node-0' LIMIT 5
PATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29
REQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27
SCRIPT_NAME: `` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:28
192.168.16.10 - - [31/Oct/2023 10:57:33] "GET / HTTP/1.1" 300 1761 0.001253
(1039) accepted ('192.168.16.10', 58732) server /var/lib/kolla/venv/lib/python3.10/site-packages/eventlet/wsgi.py:1004

>>> SELECT * FROM flog-2023.10.31 WHERE Hostname = 'testbed-node-0' AND programname = 'keystone' LIMIT 5
PATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29
REQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27
SCRIPT_NAME: `` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:28
PATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29
REQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/manager/task/index.html b/docs/iaas/guides/operations-guide/manager/task/index.html new file mode 100644 index 0000000000..462a13f293 --- /dev/null +++ b/docs/iaas/guides/operations-guide/manager/task/index.html @@ -0,0 +1,35 @@ + + + + + +Task | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Task

+

List

+

All running or scheduled tasks can be listed with osism task list.

+
+----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------+
| Worker | ID | Name | Status | Start time | Arguments |
|----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------|
| celery@kolla-ansible | 8a553e69-c532-4ba0-a5d4-08a983bde692 | osism.tasks.kolla.run | ACTIVE | 2023-09-27 17:55:54.252250 | ['kolla', 'common', ['-e kolla_action=pull']] |
| celery@osism-ansible | dba72dd5-1885-408f-9262-e0ded111a007 | osism.tasks.ansible.run | ACTIVE | 2023-09-27 18:00:31.215879 | ['generic', 'facts', []] |
+----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------+
+

Broker reset

+

Sometimes tasks get stuck. Due to the internal locks it is then not possible to re-execute +plays with the same name. Also it is currently not possible to cancel already running tasks +(is on the todo list). The only way to unblock the situation is to stop the manager service +and start it again.

+
cd /opt/manager
docker compose down
docker compose up -d
+

In earlier versions of OSISM, the Redis service was not stateless. In these cases, it is +necessary to delete the Redis service volume before restarting the manager service.

+
docker volume rm manager_redis
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/network/index.html b/docs/iaas/guides/operations-guide/network/index.html new file mode 100644 index 0000000000..a5cb0369d7 --- /dev/null +++ b/docs/iaas/guides/operations-guide/network/index.html @@ -0,0 +1,58 @@ + + + + + +Network | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Network

+

OpenStack, OVN, and Open vSwitch all really like UUIDs.

+
$ openstack --os-cloud admin image list -f yaml
- ID: d64f0b9d-0ea1-40b0-b879-b98e46fc7bcf
Name: Cirros 0.6.0
Status: active
- ID: ee842bc5-dd29-4de5-a5db-1c9be759fe85
Name: Cirros 0.6.1
Status: active
- ID: cd28d95c-bd12-4e1e-8155-b9bf5ecbcb2f
Name: Cirros 0.6.2
Status: active
+

These UUIDs are great for uniqueness, but 36-character strings are terrible +for readability. Statistically, just the first few characters are enough for +uniqueness in small environments, so let’s define a helper to make things more +readable:

+
abbrev() { a='[0-9a-fA-F]' b=$a$a c=$b$b; sed "s/$b-$c-$c-$c-$c$c$c//g"; }
+

You can use this as a filter to abbreviate UUIDs. For example, use it to abbreviate +the above image list:

+
$ openstack --os-cloud admin image list -f yaml | abbrev
- ID: d64f0b
Name: Cirros 0.6.0
Status: active
- ID: ee842b
Name: Cirros 0.6.1
Status: active
- ID: cd28d9
Name: Cirros 0.6.2
Status: active
+

Source: https://docs.ovn.org/en/stable/tutorials/ovn-openstack.html#shortening-uuids

+

Open vSwitch (OVS)

+ +

Open vSwitch on a network node with external network vxlan0 and integration +with the Octavia service via ohm0.

+
$ docker exec -it openvswitch_vswitchd ovs-vsctl show
2e6227aa-33f1-4762-8831-ab678ce7272d
Bridge br-int
fail_mode: secure
datapath_type: system
Port ovn-testbe-0
Interface ovn-testbe-0
type: geneve
options: {csum="true", key=flow, remote_ip="192.168.16.12"}
Port br-int
Interface br-int
type: internal
Port ovn-testbe-1
Interface ovn-testbe-1
type: geneve
options: {csum="true", key=flow, remote_ip="192.168.16.11"}
Port tap8fe7d09b-90
Interface tap8fe7d09b-90
Port ohm0
Interface ohm0
type: internal
Bridge br-ex
Port vxlan0
Interface vxlan0
Port br-ex
Interface br-ex
type: internal
+

Open Virtual Network (OVN)

+ +

Get OVN NB and OVN SB connection information from the /etc/kolla/neutron-server/ml2_conf.ini +file.

+
ovn_nb_connection=$(sudo grep -P -o -e "(?<=^ovn_nb_connection = ).*" "/etc/kolla/neutron-server/ml2_conf.ini")
ovn_sb_connection=$(sudo grep -P -o -e "(?<=^ovn_sb_connection = ).*" "/etc/kolla/neutron-server/ml2_conf.ini")
+

The following examples are from a fresh osism/testbed +deployment with no payload running yet.

+

OVN NB DB entries:

+
$ docker exec ovn_northd ovn-nbctl --db "$ovn_nb_connection" show | abbrev
switch b5139b (neutron-8fe7d0) (aka lb-mgmt-net)
port 45a49e
type: localport
addresses: ["fa:16:3e:fa:99:ea 10.1.0.2"]
port 4d39a5 (aka octavia-listen-port-testbed-node-2)
addresses: ["fa:16:3e:dc:11:e4 10.1.0.45"]
port 8df1b7 (aka octavia-listen-port-testbed-node-0)
addresses: ["fa:16:3e:4d:63:a9 10.1.0.43"]
port ddb6aa (aka octavia-listen-port-testbed-node-1)
addresses: ["fa:16:3e:67:f3:3d 10.1.0.40"]
+

OVN SB DB entries:

+
$ docker exec ovn_northd ovn-sbctl --db "$ovn_sb_connection" show | abbrev
Chassis testbed-node-0
hostname: testbed-node-0
Encap geneve
ip: "192.168.16.10"
options: {csum="true"}
Port_Binding "8df1b7"
Chassis testbed-node-2
hostname: testbed-node-2
Encap geneve
ip: "192.168.16.12"
options: {csum="true"}
Port_Binding "4d39a5"
Chassis testbed-node-1
hostname: testbed-node-1
Encap geneve
ip: "192.168.16.11"
options: {csum="true"}
Port_Binding "ddb6aa
+

OVN NB status:

+
$ docker exec ovn_nb_db ovs-appctl -t /var/run/ovn/ovnnb_db.ctl cluster/status OVN_Northbound | abbrev
6d15
Name: OVN_Northbound
Cluster ID: f5eb (f5ebd8)
Server ID: 6d15 (6d159e)
Address: tcp:192.168.16.10:6643
Status: cluster member
Role: follower
Term: 5
Leader: 87d6
Vote: 87d6

Last Election started 41049332 ms ago, reason: timeout
Election timer: 1000
Log: [2, 54]
Entries not yet committed: 0
Entries not yet applied: 0
Connections: ->21d7 ->87d6 <-87d6 <-21d7
Disconnections: 6
Servers:
6d15 (6d15 at tcp:192.168.16.10:6643) (self)
87d6 (87d6 at tcp:192.168.16.11:6643) last msg 266 ms ago
21d7 (21d7 at tcp:192.168.16.12:6643) last msg 41048563 ms ago
+

OVN SB status:

+
$ docker exec ovn_sb_db ovs-appctl -t /var/run/ovn/ovnsb_db.ctl cluster/status OVN_Southbound | abbrev
be29
Name: OVN_Southbound
Cluster ID: bd0c (bd0c26)
Server ID: be29 (be2932)
Address: tcp:192.168.16.10:6644
Status: cluster member
Role: follower
Term: 6
Leader: dfdf
Vote: unknown

Last Election started 41063820 ms ago, reason: timeout
Election timer: 1000
Log: [2, 62]
Entries not yet committed: 0
Entries not yet applied: 0
Connections: ->dfdf ->085c <-dfdf <-085c
Disconnections: 7
Servers:
be29 (be29 at tcp:192.168.16.10:6644) (self)
dfdf (dfdf at tcp:192.168.16.11:6644) last msg 146 ms ago
085c (085c at tcp:192.168.16.12:6644) last msg 41063293 ms ago
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/cinder/index.html b/docs/iaas/guides/operations-guide/openstack/cinder/index.html new file mode 100644 index 0000000000..492c9d57ff --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/cinder/index.html @@ -0,0 +1,76 @@ + + + + + +Cinder | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Cinder

+

Remove service

+
$ openstack --os-cloud admin volume service list
+------------------+-----------------------------------+----------+---------+-------+----------------------------+
| Binary | Host | Zone | Status | State | Updated At |
+------------------+-----------------------------------+----------+---------+-------+----------------------------+
| cinder-scheduler | testbed-node-0 | internal | enabled | up | 2023-10-01T08:53:14.000000 |
| cinder-scheduler | testbed-node-1 | internal | enabled | up | 2023-10-01T08:53:15.000000 |
| cinder-scheduler | testbed-node-2 | internal | enabled | up | 2023-10-01T08:53:15.000000 |
| cinder-volume | testbed-node-0@rbd-1 | nova | enabled | down | 2023-09-30T18:50:05.000000 |
| cinder-volume | testbed-node-2@rbd-1 | nova | enabled | down | 2023-09-30T18:50:05.000000 |
| cinder-volume | testbed-node-1@rbd-1 | nova | enabled | down | 2023-09-30T18:50:08.000000 |
+------------------+-----------------------------------+----------+---------+-------+----------------------------+
+
$ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-0@rbd-1
Service cinder-volume on host testbed-node-0@rbd-1 removed.
$ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-1@rbd-1
Service cinder-volume on host testbed-node-1@rbd-1 removed.
$ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-2@rbd-1
Service cinder-volume on host testbed-node-2@rbd-1 removed.
+
$ openstack --os-cloud admin volume service list
+------------------+-----------------------------------+----------+---------+-------+----------------------------+
| Binary | Host | Zone | Status | State | Updated At |
+------------------+-----------------------------------+----------+---------+-------+----------------------------+
| cinder-scheduler | testbed-node-0 | internal | enabled | up | 2023-10-01T08:56:24.000000 |
| cinder-scheduler | testbed-node-1 | internal | enabled | up | 2023-10-01T08:56:25.000000 |
| cinder-scheduler | testbed-node-2 | internal | enabled | up | 2023-10-01T08:56:25.000000 |
+------------------+-----------------------------------+----------+---------+-------+----------------------------+
+

Sync quota

+

It can happen that more block storage usage is stored in the database for a project than +is actually used. This can be corrected using cinder-manage.

+

For all projects:

+
$ docker exec -it cinder_api cinder-manage quota sync
+

Only for a specific project:

+
$ docker exec -it cinder_api cinder-manage quota sync --project-id PROJECT_ID
+

Quality of Service (QoS)

+ +

Create default volume QoS policy that allows 1000 read IOPS and 1000 write IOPS.

+
$ openstack --os-cloud admin volume qos create \
--consumer both \
--property read_iops_sec=1000 \
--property write_iops_sec=1000 \
default
+------------+---------------------------------------------+
| Field | Value |
+------------+---------------------------------------------+
| consumer | both |
| id | 48920d26-e85f-4920-8ed4-ff8d322c77b9 |
| name | testing |
| properties | read_iops_sec='1000', write_iops_sec='1000' |
+------------+---------------------------------------------+
+
$ openstack --os-cloud admin volume qos list
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
| ID | Name | Consumer | Associations | Properties |
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
| 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | | read_iops_sec='1000', write_iops_sec='1000' |
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
+

Assign the default volume QoS policy to the __DEFAULT volume type.

+
$ openstack --os-cloud admin volume qos associate default __DEFAULT__
+
$ openstack --os-cloud admin volume qos list
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
| ID | Name | Consumer | Associations | Properties |
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
| 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | __DEFAULT__ | read_iops_sec='1000', write_iops_sec='1000' |
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
+

Change the read IOPS from 1000 to 2000 and the write IOPS from 1000 to 2000 of the default volume QoS policy.

+
$ openstack --os-cloud admin volume qos set \
--property read_iops_sec=2000 \
--property write_iops_sec=2000 \
default
+
$ openstack --os-cloud admin volume qos list
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
| ID | Name | Consumer | Associations | Properties |
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
| 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | __DEFAULT__ | read_iops_sec='2000', write_iops_sec='2000' |
+--------------------------------------+---------+----------+--------------+---------------------------------------------+
+

The following properties are available.

+

For Fixed IOPS per volume:

+
    +
  • read_iops_sec
  • +
  • write_iops_sec
  • +
  • total_iops_sec
  • +
+

For Burst IOPS per volume:

+
    +
  • read_iops_sec_max
  • +
  • write_iops_sec_max
  • +
  • total_iops_sec_max
  • +
+

For Fixed bandwidth per volume:

+
    +
  • read_bytes_sec
  • +
  • write_bytes_sec
  • +
  • total_bytes_sec
  • +
+

For Burst bandwidth per volume:

+
    +
  • read_bytes_sec_max
  • +
  • write_bytes_sec_max
  • +
  • total_bytes_sec_max
  • +
+

For burst bucket size:

+
    +
  • size_iops_sec
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/index.html b/docs/iaas/guides/operations-guide/openstack/index.html new file mode 100644 index 0000000000..4a6152460f --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/index.html @@ -0,0 +1,165 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

OpenStack

+

Create an external network

+

The play network-external is available and usable as of OSISM 7.0.6.

+
osism apply network-external
+

Available parameters for the OpenStack Environment (environments/openstack/configuration.yml).

+
ParameterDefault
network_external_allocation_pool_end"192.168.112.200"
network_external_allocation_pool_start"192.168.112.100"
network_external_cidr"192.168.112.0/20"
network_external_cloudadmin
network_external_gateway_ip"192.168.112.5"
network_external_namepublic
network_external_provider_network_typeflat
network_external_provider_physical_networkphysnet1
network_external_statepresent
+

Reboot a compute node

+
    +
  1. +

    Live migrate all instances running on the compute node +with the help of the OpenStack Resource Manager

    +
  2. +
  3. +

    Ensure that no more instances are running on the compute node

    +
    ps ax | grep qemu
    +
  4. +
  5. +

    Reboot the compute node

    +
    osism apply reboot -l NODE -e ireallymeanit=yes
    +
  6. +
  7. +

    Wait for the compute node to reboot

    +
  8. +
  9. +

    Re-enable the compute service

    +
    openstack --os-cloud admin compute service set --enable --disable-reason "" NODE nova-compute
    +
  10. +
  11. +

    Check compute service

    +
    openstack --os-cloud admin compute service list --host NODE --service nova-compute
    +
  12. +
+

Add a new compute node

+
    +
  1. +

    Add the operater user

    +
    osism apply operator -u osism -l NODE
    +
  2. +
  3. +

    Run the bootstrap

    +
    osism apply bootstrap -l NODE
    +
  4. +
  5. +

    When a routed network fabric is used deploy the FRR service (optional)

    +
    osism apply frr -l NODE
    +
  6. +
  7. +

    Deploy logging service and Prometheus exporters

    +
    osism apply common -l NODE
    osism apply prometheus -l NODE
    osism apply scaphandre -l NODE
    +
  8. +
  9. +

    Deploy network services

    +
    osism apply openvswitch -l NODE
    osism apply ovn -l NODE
    osism apply neutron -l NODE
    +

    If you do not use the OVN SDN skip osism apply ovn -l NODE.

    +
  10. +
  11. +

    Deploy compute services

    +
    osism apply nova -l NODE
    +
  12. +
  13. +

    Deploy telemetry services (optional)

    +
    osism apply ceilometer -l NODE
    +
  14. +
  15. +

    Deploy Netdata service (optional)

    +
    osism apply netdata -l NODE
    +
  16. +
  17. +

    Add compute node to Prometheus monitoring

    +
    osism apply prometheus -l monitoring
    +
  18. +
  19. +

    Refresh the /etc/hosts file

    +
    osism apply hosts
    +
  20. +
  21. +

    Refresh the SSH client configuration file

    +
    osism apply sshconfig
    +
  22. +
  23. +

    Add compute node to the known hosts file

    +
    osism apply known-hosts
    +
  24. +
+

Containers that run on a compute node. Versions may differ. There is no ceilometer_compute container +if you have not deployed the optional OpenStack telemetry service.

+
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
559e5176695c quay.io/osism/nova-compute:27.1.1.20230919 "dumb-init --single-…" 5 minutes ago Up 5 minutes (healthy) nova_compute
31248d71ab7d quay.io/osism/nova-libvirt:8.0.0.20230919 "dumb-init --single-…" 6 minutes ago Up 6 minutes (healthy) nova_libvirt
9292030d706c quay.io/osism/nova-ssh:27.1.1.20230919 "dumb-init --single-…" 6 minutes ago Up 6 minutes (healthy) nova_ssh
fda4b6fb30c8 quay.io/osism/neutron-metadata-agent:22.0.3.20230919 "dumb-init --single-…" 2 hours ago Up 2 hours (healthy) neutron_ovn_metadata_agent
0e3ec450b668 quay.io/osism/ceilometer-compute:20.0.1.20230919 "dumb-init --single-…" 6 hours ago Up 6 hours (healthy) ceilometer_compute
25ff9702e0e5 quay.io/osism/prometheus-libvirt-exporter:6.0.0.20230919 "dumb-init --single-…" 6 hours ago Up 6 hours prometheus_libvirt_exporter
1bff2e29923b quay.io/osism/prometheus-cadvisor:0.45.0.20230919 "dumb-init --single-…" 6 hours ago Up 6 hours prometheus_cadvisor
602832daf237 quay.io/osism/prometheus-node-exporter:1.4.0.20230919 "dumb-init --single-…" 6 hours ago Up 6 hours prometheus_node_exporter
d4de2f32cdf8 quay.io/osism/ovn-controller:23.6.1.20230919 "dumb-init --single-…" 6 hours ago Up 6 hours ovn_controller
3bf43ae5a94f quay.io/osism/openvswitch-vswitchd:3.1.2.20230919 "dumb-init --single-…" 7 hours ago Up 7 hours (healthy) openvswitch_vswitchd
ebc048b02ab2 quay.io/osism/openvswitch-db-server:3.1.2.20230919 "dumb-init --single-…" 7 hours ago Up 7 hours (healthy) openvswitch_db
4f33dfa66c14 hubblo/scaphandre:0.5.0 "scaphandre promethe…" 7 hours ago Up 7 hours 10.10.129.64:9155->8080/tcp scaphandre
9b1f6342dc60 quay.io/osism/cron:3.0.20230919 "dumb-init --single-…" 7 hours ago Up 7 hours cron
718aecaddde1 quay.io/osism/kolla-toolbox:16.1.1.20230919 "dumb-init --single-…" 7 hours ago Up 7 hours kolla_toolbox
f6f9422c1853 quay.io/osism/fluentd:4.5.1.20230919 "dumb-init --single-…" 7 hours ago Up 7 hours fluentd
+

Remove a compute node

+
    +
  1. +

    In the configuration repository remove the compute node everywhere. Then update the configuration +repository on the manager with osism apply configuration

    +
  2. +
  3. +

    Live migrate all instances running on the compute node +with the help of the OpenStack Resource Manager

    +
  4. +
  5. +

    Evacuate all instances on the compute node +with the help of the OpenStack Resource Manager

    +
  6. +
  7. +

    Ensure that no more instances are running on the compute node

    +
    ps ax | grep qemu
    +
  8. +
  9. +

    Stop all OpenStack compute services on the compute node

    +
    systemctl stop kolla-nova_ssh-container.service
    systemctl stop kolla-nova_libvirt-container.service
    systemctl stop kolla-nova_compute-container.service
    +
  10. +
  11. +

    Delete the compute service

    +
    $ openstack --os-cloud admin compute service list --host NODE
    +--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+
    | ID | Binary | Host | Zone | Status | State | Updated At |
    +--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+
    | 90345eb5-cf2f-47ef-becc-758ee36fb132 | nova-compute | NODE | nova | enabled | down | 2023-12-21T11:53:00.000000 |
    +--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+
    +
    $ openstack --os-cloud admin compute service delete 90345eb5-cf2f-47ef-becc-758ee36fb132
    +
  12. +
  13. +

    Stop all OpenStack network services on the compute node

    +
    systemctl stop kolla-neutron_ovn_metadata_agent-container.service
    systemctl stop kolla-ovn_controller-container.service
    +
  14. +
  15. +

    Delete the network services

    +
    $ openstack --os-cloud admin network agent list --host NODE
    +--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+
    | ID | Agent Type | Host | Availability Zone | Alive | State | Binary |
    +--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+
    | 0a5708ea-ba8b-5fde-8187-c6b24d3cf5ed | OVN Metadata agent | NODE | | :-) | UP | neutron-ovn-metadata-agent |
    | NODE | OVN Controller agent | NODE | | :-) | UP | ovn-controller |
    +--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+

    $ openstack --os-cloud admin network agent delete 0a5708ea-ba8b-5fde-8187-c6b24d3cf5ed
    $ openstack --os-cloud admin network agent delete NODE
    +
  16. +
  17. +

    Refresh the facts

    +
    osism apply facts
    +
  18. +
  19. +

    Refresh the /etc/hosts file

    +
    osism apply hosts
    +
  20. +
  21. +

    Refresh the SSH client configuration file

    +
    osism apply sshconfig
    +
  22. +
  23. +

    Remove compute node from Prometheus monitoring

    +
    osism apply prometheus -l monitoring
    +
  24. +
  25. +

    Remove compute node from the known hosts file

    +
    osism apply known-hosts
    +
  26. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/keystone/index.html b/docs/iaas/guides/operations-guide/openstack/keystone/index.html new file mode 100644 index 0000000000..f0bd2445f6 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/keystone/index.html @@ -0,0 +1,29 @@ + + + + + +Keystone | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Keystone

+
    +
  • +

    List all users of a project who have been assigned the member role

    +
    $ openstack --os-cloud admin role assignment list --names --role member --project test
    +--------+-----------+-------+-----------+--------+--------+-----------+
    | Role | User | Group | Project | Domain | System | Inherited |
    +--------+-----------+-------+-----------+--------+--------+-----------+
    | member | test@test | | test@test | | | False |
    +--------+-----------+-------+-----------+--------+--------+-----------+
    +
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/neutron/index.html b/docs/iaas/guides/operations-guide/openstack/neutron/index.html new file mode 100644 index 0000000000..9d567f4241 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/neutron/index.html @@ -0,0 +1,27 @@ + + + + + +Neutron | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/nova/index.html b/docs/iaas/guides/operations-guide/openstack/nova/index.html new file mode 100644 index 0000000000..3f40976c7b --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/nova/index.html @@ -0,0 +1,54 @@ + + + + + +Nova | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Nova

+

Get all servers on a node

+
openstack --os-cloud admin server list --all-projects --host testbed-node-0
+

Stop all servers running on a node

+
for server in $(openstack --os-cloud admin server list --all-projects --host testbed-node-0 --vm-state active -f value -c ID | tr -d '\r'); do
echo stopping server $server
openstack --os-cloud admin server stop $server
sleep 2
done
+

Disable & enable a compute service

+
openstack --os-cloud admin compute service set --disable --description MAINTENANCE testbed-node-0 nova-compute
+
openstack --os-cloud admin compute service list --long
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
| ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | up | 2023-12-14T14:20:24.000000 | MAINTENANCE | False |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
+
openstack --os-cloud admin compute service set --enable testbed-node-0 nova-compute
+
openstack --os-cloud admin compute service list
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+
| ID | Binary | Host | Zone | Status | State | Updated At |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+
| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | enabled | up | 2023-12-14T14:22:54.000000 |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+
+

Force down & up a compute service

+
openstack --os-cloud admin --os-compute-api-version 2.12 compute service set --down testbed-node-0 nova-compute
+
openstack --os-cloud admin compute service list --long
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
| ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | down | 2023-12-14T14:21:47.000000 | None | True |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
+
openstack --os-cloud admin --os-compute-api-version 2.12 compute service set --up testbed-node-0 nova-compute
+
openstack --os-cloud admin compute service list --long
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
| ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
| b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | up | 2023-12-14T14:20:24.000000 | None | False |
+--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+
+

Huge pages

+
$ grep Huge /proc/meminfo
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
+
$ sudo sudo hugeadm --pool-list
libhugetlbfs: ERROR: Line too long when parsing mounts
Size Minimum Current Maximum Default
2097152 0 0 0 *
1073741824 0 0 0
+
/etc/default/grub
GRUB_CMDLINE_LINUX="default_hugepagesz=1G hugepagesz=1G hugepages=512 transparent_hugepage=never"
+
update-grub
reboot
+
$ grep Huge /proc/meminfo
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 512
HugePages_Free: 512
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 1048576 kB
Hugetlb: 536870912 kB
+
$ sudo hugeadm --pool-list
libhugetlbfs: ERROR: Line too long when parsing mounts
Size Minimum Current Maximum Default
2097152 0 0 0 *
1073741824 512 512 512
+

Quality of Service (QoS)

+ +

Host aggregates

+

Host aggregates can be managed with the playbook. The playbook is used with +osism apply -e openstack host-aggregates.

+

Further arguments for host aggregates can be found in the +documentation for the openstack.cloud.host_aggregate Ansible module.

+
environments/openstack/playbook-host-aggregates.yml
---
- name: Manage host aggregates
hosts: localhost
connection: local

vars:
host_aggregates:
- name: aggregate1
hosts:
- host1
- host2
- host3

tasks:
- name: Create host aggregate
openstack.cloud.host_aggregate:
cloud: admin
state: present
name: "{{ item.name }}"
hosts: "{{ item.hosts }}"
loop: "{{ host_aggregates }}"
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/octavia/index.html b/docs/iaas/guides/operations-guide/openstack/octavia/index.html new file mode 100644 index 0000000000..abcafb4fbc --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/octavia/index.html @@ -0,0 +1,42 @@ + + + + + +Octavia | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Octavia

+

Cleanup of amphorae missing from the DB

+
/var/log/kolla/octavia/octavia-health-manager.log
2023-10-25 16:43:52.547 22 WARNING octavia.amphorae.drivers.health.heartbeat_udp [-]
The amphora 2a33a889-4f9a-4340-84a5-e58a7a8af17e with IP 10.1.0.79 is missing from the
DB, so it cannot be automatically deleted (the compute_id is unknown). An operator must
manually delete it from the compute service.
+

SSH access to amphorae

+
    +
  1. +

    Get the local IP address (lb_network_ip) of the amphora you want to access via +openstack --os-cloud admin loadbalancer amphora list.

    +
  2. +
  3. +

    Connect to one of the nodes that you use for Octavia. Normally the control- +or network nodes.

    +
  4. +
  5. +

    You can now use SSH to access the amphora. The use of sudo is required here because +you cannot access /etc/kolla/octavia-worker/octavia_ssh_key with the operator user +account. Replace lb_network_ip with the local IP address of the amphora.

    +
    sudo ssh -i /etc/kolla/octavia-worker/octavia_ssh_key ubuntu@lb_network_ip
    +
  6. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager/index.html b/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager/index.html new file mode 100644 index 0000000000..d42e6288e4 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager/index.html @@ -0,0 +1,74 @@ + + + + + +Flavor Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Flavor Manager

+

Overview

+

The OpenStack Flavor Manager manages the creation, modification, and removal of flavors. +It operates as a facilitator that orchestrates compute flavors in alignment +with the standard SCS-0100: Flavor Naming +by utilizing YAML files provided by the SCS project.

+

Installation

+

The OpenStack Flavor Manager can be used via the OSISM CLI. This is the preferred way to use it. +No installation is then required. It is used via osism manage flavors.

+

For use independent of OSISM install the openstack-flavor-manager package with pip. It is likely +that additional dependencies such as pkg-config or libssl-dev must be installed in advance.

+
$ pip install openstack-flavor-manager
+

Or clone the repository osism/openstack-flavor-manager +and use the OpenStack Flavor Manager from source with tox.

+
$ tox -- --help
+

Usage

+

There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Flavor Manager +will be executed. When using the OSISM CLI, the files are expected in environments/openstack +in your configuration repository.

+

The cloud profile to be used can be specified via the optional --cloud parameter. +By default the cloud profile with the name admin is used. It must be possible to create and delete +flavors with the used cloud credentials.

+
$ openstack-flavor-manager --help

Usage: openstack-flavor-manager [OPTIONS]

╭─ Options ────────────────────────────────────────────────────────────────────────────────────╮
│ --name TEXT Name of flavor definitions. [default: scs] │
│ --debug Enable debug logging. │
│ --cloud TEXT Cloud name in clouds.yaml. [default: admin] │
│ --recommended Create recommended flavors. │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────╯
+

To create the mandatory flavors by the SCS-0100: Flavor Naming +standard, you run:

+
$ openstack-flavor-manager
+

To create the recommended flavors by the SCS Flavor Naming Standard, you run:

+
$ openstack-flavor-manager --recommended
+

The output should look like this:

+
2023-09-20 13:03:14 | INFO     | Flavor SCS-1V-4 created
2023-09-20 13:03:14 | INFO | Flavor SCS-2V-8 created
2023-09-20 13:03:14 | INFO | Flavor SCS-4V-16 created
2023-09-20 13:03:14 | INFO | Flavor SCS-8V-32 created
...
+

All recommended flavors are now be available in your OpenStack environment. +Check yourself by running:

+
$ openstack --os-cloud admin flavor list
+
$ openstack --os-cloud admin flavor show SCS-2V-4-20s
+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 0 |
| access_project_ids | None |
| description | None |
| disk | 20 |
| id | 652e3a6c-330e-4ee3-922b-b49c3c093062 |
| name | SCS-2V-4-20s |
| os-flavor-access:is_public | True |
| properties | hw_rng:allowed='true', scs:cpu-type='shared-core', scs:disk0-type='ssd', scs:name-v1='SCS-2V:4:20s', scs:name-v2='SCS-2V-4-20s' |
| ram | 4096 |
| rxtx_factor | 1.0 |
| swap | 0 |
| vcpus | 2 |
+----------------------------+---------------------------------------------------------------------------------------------------------------------------------+
+

Definitions

+

There are two flavor definitions available by default. One for +SCS +and one for OSISM. +Each definition has its own set of mandatory and recommended flavors. The definition of OSISM contains +all definitions of SCS as well as some others.

+

To run the OpenStack Flavor Manager with a specific definition, either scs or osism, +use the optional --name parameter. By default the SCS-0100: Flavor Naming +standard definition will be used.

+
$ openstack-flavor-manager --name osism
+

Name parser and generator

+

A generator and parser for flavor names according to the SCS standard is available on +flavors.scs.community.

+

The flavor name SCS-2V-4-20s is inserted in field Flavor name:

+ +

The flavor SCS-2V-4-20s translated is +2 generic x86-64 vCPUs with 4.0 GiB RAM and SSD 20GB root volume:

+
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/image-manager/index.html b/docs/iaas/guides/operations-guide/openstack/tools/image-manager/index.html new file mode 100644 index 0000000000..022a5dce9d --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/image-manager/index.html @@ -0,0 +1,164 @@ + + + + + +Image Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Image Manager

+

The OpenStack Image Manager is a tool for managing all +images on an OpenStack environment

+

Requirements

+

This information is only relevant for the operator of an OpenStack environment. You can skip this section if +you want to use OpenStack Image Manager as a normal user and you are not an operator of an openStack environment.

+

OpenStack Image Service (Glance)

+

The OpenStack Image Service (Glance) is required to upload and discover data assets that are used by other +services.

+

Since this script stores many images in a single project, the Glance quota must be set accordingly high or to unlimited.

+
[DEFAULT]
user_storage_quota = 1TB
+

With most storage backends it makes sense to convert the imported images directly to RAW. So it is required for using Ceph and it's +features too. Recited from the Ceph documentation QEMU and block devices and +Block devices and OpenStack.

+
info

The raw data format is really the only sensible format option to use with RBD. Technically, you could use other QEMU-supported formats +(such as qcow2 or vmdk), but doing so would add additional overhead, and would also render the volume unsafe for virtual machine live +migration when caching (see below) is enabled.

Important Ceph doesn't support QCOW2 for hosting a virtual machine disk. Thus if you want to boot virtual machines in Ceph (ephemeral +backend or boot from volume), the Glance image format must be RAW.

See the OpenStack Glance documentation +for more details.

+

This requires the following parameter for the image import workflow.

+
[taskflow_executor]
conversion_format = raw

[image_import_opts]
image_import_plugins = ['image_decompression', 'image_conversion']

[image_conversion]
output_format = raw
+

Object storage backend

+

If the mirror functionality is used, an object storage backend is required. The use of the mirror functionality +is optional and is not used by default.

+

Getting started

+

This Getting started will upload a private image to your OpenStack environment with +the help of the OpenStack Image Manager.

+
    +
  1. +

    Install the openstack-image-manager package with +pip.

    +
    pip3 install openstack-image-manager
    +

    The installation can also be done via pipenv.

    +

    A Pipefile file is created with this content. The latest version of openstack-image-manager +is used.

    +
    [[source]]
    url = "https://pypi.org/simple"
    verify_ssl = true
    name = "pypi"

    [packages]
    openstack-image-manager = "==0.20240403.0"

    [dev-packages]

    [requires]
    python_version = "3.10"
    +

    The dependencies are then installed and the shell is prepared for use:

    +
    pipenv install
    pipenv shell
    +
  2. +
  3. +

    Create a image definition in the file getting-started.yml in the local directory images.

    +
    ---
    images:
    - name: MyCirros
    format: qcow2
    login: cirros
    password: gocubsgo
    min_disk: 1
    min_ram: 32
    status: active
    visibility: private
    multi: false
    meta:
    architecture: x86_64
    hw_disk_bus: scsi
    hw_rng_model: virtio
    hw_scsi_model: virtio-scsi
    hw_watchdog_action: reset
    os_distro: cirros
    replace_frequency: never
    uuid_validity: none
    provided_until: none
    tags: []
    versions:
    - version: "0.6.0"
    url: https://github.com/cirros-dev/cirros/releases/download/0.6.0/cirros-0.6.0-x86_64-disk.img
    checksum: "sha256:94e1e2c94dbbae7d4bdc38e68590a1daf73c9de2d03dd693857b4b0a042548e8"
    build_date: 2022-09-28
    +
  4. +
  5. +

    Run the OpenStack Image Manager. It is assumed that a profile with the name openstack exists in the +clouds.yaml.

    +
    openstack-image-manager --cloud openstack --filter ".*Cirr.*" --images images/
    +
  6. +
+

Image definitions

+

The configuration consists of different parameter settings, such as values for +minimum RAM or the visibility of the image. Have a look at the examples below +for all parameters. After a change to the configuration, validate it with +tox -- --dry-run.

+

SCS image standard

+
    +
  • The value of login is stored as image_original_user in the metadata of an image.
  • +
  • If image_description is not set as meta information, image_description is set to the name of the image.
  • +
  • The value of build_date of a specific version of an image is stored as image_build_date in the metadata of an image.
  • +
  • The value of url of a specific version of an image is stored as image_source in the metadata of an image.
  • +
+

Image with regular rebuilds

+

This type of image definition is used for images that are rebuilt at regular +intervals. For example, this is the case for the daily builds of the Ubuntu +images.

+

The attribute multi: true is set.

+

With this type of image definition, the version of the distribution (or product, +whatever is contained in the image) used is already in the name of the image +definition. The version properties from the definition's versions list +are appended only to older iterations of the image as timestamp suffixes +in parentheses upon each rotation (except for the latest entry).

+
images:
- name: Ubuntu 24.04
format: qcow2
login: ubuntu
min_disk: 8
min_ram: 512
status: active
visibility: public
multi: true
meta:
architecture: x86_64
hw_disk_bus: scsi
hw_scsi_model: virtio-scsi
hw_watchdog_action: reset
os_distro: ubuntu
os_version: '24.04'
tags: []
versions:
- version: '20240416'
url: https://cloud-images.ubuntu.com/noble/20240416/noble-server-cloudimg-amd64.img
- version: '20240422'
url: https://cloud-images.ubuntu.com/noble/20240422/noble-server-cloudimg-amd64.img
+

This configuration creates the following images:

+
    +
  • Ubuntu 24.04 (20240416)
  • +
  • Ubuntu 24.04
  • +
+

If a newer build is added, the following rotation takes place:

+
    +
  • Ubuntu 24.04 (20240416) does not change
  • +
  • Ubuntu 24.04 becomes Ubuntu 24.04 (20240422)
  • +
  • the new image becomes Ubuntu 24.04
  • +
+

By default the last three images will be visible. When a fourth image is added, the visibility of +the last image in the list is changed to community and the image can be deleted in the future.

+

Image without regular rebuild

+

This type of image definition is used for images that are not rebuilt. For example, +this is the case for the flatcar images. For each release of Flatcar there is exactly +one image which will not be rebuilt in the future.

+

The attribute multi: false is set.

+

With this type of image definition, the version of the distribution (or product, +whatever is contained in the image) used is not in the name of the image definition. +Instead, the version properties from the image definition's versions list +are appended as static version suffixes to the images' names.

+
images:
- name: RancherOS
format: qcow2
login: rancher
min_disk: 8
min_ram: 2048
status: active
visibility: public
multi: false
meta:
architecture: x86_64
hw_disk_bus: scsi
hw_scsi_model: virtio-scsi
hw_watchdog_action: reset
tags: []
versions:
- version: '1.3.0'
url: https://github.com/rancher/os/releases/download/v1.3.0/rancheros-openstack.img
- version: '1.4.0'
url: https://github.com/rancher/os/releases/download/v1.4.0/rancheros-openstack.img
- version: '1.4.1'
url: https://github.com/rancher/os/releases/download/v1.4.1/rancheros-openstack.img
+

This configuration creates the following images:

+
    +
  • RancherOS 1.3.0
  • +
  • RancherOS 1.4.0
  • +
  • RancherOS 1.4.1
  • +
+

If a new version is added, no rotation takes place. The new version is added +as RancherOS x.y.z. Here also the visibility of older images is not changed.

+

Other properties

+

Image properties

+
    +
  • Removal of properties is not yet possible
  • +
  • URL, name and format can not be changed
  • +
  • Any keys can be added to meta, these will be added to the image
  • +
  • Existing keys in meta can be changed, the same applies to min_disk +and min_ram
  • +
+

Image tags

+

image status

+
    +
  • deactivation: change status to deactivated
  • +
  • reactivation: change status to active
  • +
+

Image visibility

+

A full documentation about the visibility of images can be found in the Image visibility section in the +OpenStack Image Service API Documentation.

+
    +
  • public: set visibility to public
  • +
  • community: set visibility to community
  • +
  • shared: set visibility to shared
  • +
  • private: set visibility to private
  • +
+

Usage

+

Mirroring images

+

Since the upstreams often only keep their images for a short time, we mirror most of the images on REGIO.cloud. +This makes us independent of the availability of the images in the individual upstreams.

+

Updating images

+

Some of the images are automatically updated by a CI job. The latest available build at the time of the CI job execution is mirrored and +made available as the current version.

+

Currently, the following images are updated once a week (every Sunday at 0 am):

+
    +
  • Almalinux
  • +
  • CentOS
  • +
  • Debian
  • +
  • Rockylinux
  • +
  • Ubuntu
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update/index.html b/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update/index.html new file mode 100644 index 0000000000..6a0d38df63 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update/index.html @@ -0,0 +1,45 @@ + + + + + +Image Manager update.py | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Image Manager update.py

+

Overview

+

The OpenStack Image Manager update.py Script updates the /etc/images/*.yaml files to the always latest release of the Distributions, set S3 Mirror Urls and uploads the Images to the mirror.

+

These updated yaml files are later processed by the Image Manger itself.

+

Installation

+

Prepare to use the update.py script.

+
git clone https://github.com/osism/openstack-image-manager/ 
cd openstack-image-manager
pipenv install
pipenv shell
+

Usage

+
python contrib/update.py --help

Usage: update.py [OPTIONS]

╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --debug Enable debug logging │
│ --dry-run Do not perform any changes │
│ --minio-access-key TEXT Minio access key [env var: MINIO_ACCESS_KEY] [default: None] │
│ --minio-secret-key TEXT Minio secret key [env var: MINIO_SECRET_KEY] [default: None] │
│ --minio-server TEXT Minio server [env var: MINIO_SERVER] [default: swift.services.a.regiocloud.tech] │
│ --minio-bucket TEXT Minio bucket [env var: MINIO_BUCKET] [default: openstack-images] │
│ --swift-prefix TEXT Swift prefix [env var: SWIFT_PREFIX] [default: swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/] │
│ --install-completion Install completion for the current shell. │
│ --show-completion Show completion for the current shell, to copy it or customize the installation. │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+
note
    +
  • At this time the update.py expects all yamls Files at /etc/images/, which can't be configured at the moment.
  • +
  • Mirroring can't be disabled at the moment.
  • +
+

Best is to run this Script by cron or a CI job, to update all Distribution Files periodically to the latest release and afterwards run Openstack Image Manager. +The Distribution Image yaml files must exists before running the script, you can use the files from Github repo at etc/images/ as template for your first run.

+
$ python contrib/update.py
2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/centos.yml
2024-04-24 09:29:44 | INFO | update_image:179 - Checking image CentOS Stream 9
2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-HEREBE\d+\.\dDRAGONS.x86_64.qcow2
2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cloud.centos.org/centos/9-stream/x86_64/images/CHECKSUM
2024-04-24 09:29:44 | INFO | get_latest_default:62 - Latest URL is now https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2
2024-04-24 09:29:44 | INFO | get_latest_default:63 - Latest filename is now CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2
2024-04-24 09:29:44 | INFO | update_image:192 - Checksum of current CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337
2024-04-24 09:29:44 | INFO | update_image:208 - Our checksum is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337
2024-04-24 09:29:44 | INFO | update_image:211 - Image CentOS Stream 9 is up-to-date, nothing to do
2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/debian.yml
2024-04-24 09:29:44 | INFO | update_image:179 - Checking image Debian 11
2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bullseye/latest/debian-11-genericcloud-amd64.raw
2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bullseye/latest/SHA512SUMS
2024-04-24 09:29:45 | INFO | update_image:192 - Checksum of current debian-11-genericcloud-amd64-20240211-1654.raw is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4
2024-04-24 09:29:45 | INFO | update_image:208 - Our checksum is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4
2024-04-24 09:29:45 | INFO | update_image:211 - Image Debian 11 is up-to-date, nothing to do
2024-04-24 09:29:45 | INFO | update_image:179 - Checking image Debian 12
2024-04-24 09:29:45 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.raw
2024-04-24 09:29:45 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS
2024-04-24 09:29:46 | INFO | update_image:192 - Checksum of current debian-12-genericcloud-amd64-daily-20240424-1727.raw is sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e
2024-04-24 09:29:46 | INFO | update_image:208 - Our checksum is sha512:5401f8c6361bb2a82c2c24b4b4606d95e77229152a80e61f9c613bc88e25de9257057d0ed68b0256b745c4059162a54970fe4a8daf456b2eb67b4f5db5c97fcc
2024-04-24 09:29:46 | INFO | update_image:229 - New values are {'version': '20240424', 'build_date': datetime.date(2024, 4, 24), 'checksum': 'sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e', 'url': 'https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240424-1727/debian-12-genericcloud-amd64-daily-20240424-1727.raw'}
2024-04-24 09:29:46 | INFO | main:300 - Processing file /etc/images/rockylinux.yml
2024-04-24 09:29:46 | INFO | update_image:179 - Checking image Rocky 9
2024-04-24 09:29:46 | INFO | update_image:182 - Latest download URL is https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2
2024-04-24 09:29:46 | INFO | update_image:185 - Getting checksums from https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2.CHECKSUM
2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current Rocky-9-GenericCloud.latest.x86_64.qcow2 is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651
2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651
2024-04-24 09:29:47 | INFO | update_image:211 - Image Rocky_9 is up-to-date, nothing to do
2024-04-24 09:29:47 | INFO | main:300 - Processing file /etc/images/ubuntu.yml
2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04
2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS
2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current jammy-server-cloudimg-amd64.img is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710
2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710
2024-04-24 09:29:47 | INFO | update_image:211 - Image Ubuntu_22.04 is up-to-date, nothing to do
2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04 Minimal
2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64.img
2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/minimal/releases/jammy/release/SHA256SUMS
2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current ubuntu-22.04-minimal-cloudimg-amd64.img is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65
2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65
2024-04-24 09:29:48 | INFO | update_image:211 - Image Ubuntu 22.04 Minimal is up-to-date, nothing to do
2024-04-24 09:29:48 | INFO | update_image:179 - Checking image Ubuntu 24.04
2024-04-24 09:29:48 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
2024-04-24 09:29:48 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/noble/current/SHA256SUMS
2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current noble-server-cloudimg-amd64.img is sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3
2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:d7ba8d5d1d073f2dc8351973bf4f35157c846a0ea6ee16fb2a9f45a78953e4a7
2024-04-24 09:29:48 | INFO | update_image:229 - New values are {'version': '20240423', 'build_date': datetime.date(2024, 4, 23), 'checksum': 'sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3', 'url': 'https://cloud-images.ubuntu.com/noble/20240423/noble-server-cloudimg-amd64.img'}
+

These yaml files are now extended with additional fields and the update.py will take care of the versions, checksum, url and build date to the latest release in the yaml file on every run.

+
    +
  • latest_checksum_url - URL of the distros checksum file
  • +
  • latest_url - URL of the distros latest image
  • +
  • mirror_url - URL of the Image File at the local S3 Mirror
  • +
+
someexample.yaml
---
images:
- name: Debian 12
enable: true
shortname: debian-12
format: qcow2
login: debian
min_disk: 8
min_ram: 512
status: active
visibility: public
multi: true
meta:
architecture: x86_64
hw_disk_bus: scsi
hw_rng_model: virtio
hw_scsi_model: virtio-scsi
hw_watchdog_action: reset
hypervisor_type: qemu
os_distro: debian
os_version: '12'
replace_frequency: quarterly
uuid_validity: last-3
provided_until: none
tags: []
latest_checksum_url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS
latest_url:
https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.qcow2
versions:
- build_date: 2024-04-11
checksum:
sha512:3d6f26616e2c8b705993ddef874232887cebe42f1e70fcc020827ac88e8990177d537d34538c71ae2afd3b8baca953fff71eaa7ef71e752e82532c93dcdca436
url:
https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240411-1714/debian-12-genericcloud-amd64-daily-20240411-1714.qcow2
mirror_url:
https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-images/debian-12/20240411-debian-12.qcow2
version: '20240411'

+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/index.html b/docs/iaas/guides/operations-guide/openstack/tools/index.html new file mode 100644 index 0000000000..e717c7b8be --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/index.html @@ -0,0 +1,23 @@ + + + + + +Tools | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor/index.html b/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor/index.html new file mode 100644 index 0000000000..644251672e --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor/index.html @@ -0,0 +1,278 @@ + + + + + +Setting up OpenStack health monitor on Debian | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Setting up OpenStack health monitor on Debian

+

Kurt Garloff, 2024-02-20

+

Intro

+

The development of openstack-health-monitor was done on openSUSE 15.x images, just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution.

+

Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here.

+

Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a successor project for the increasingly hard to maintain shell code, this may not be worth the trouble.

+

openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested. +The scenario is described in a bit more detail in the repository's README.md file.

+

The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the monitoring section of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up.

+

Setting up the driver VM

+

So we start a Debian 12 image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard; +the instructions use flavor names and image names from the SCS standards. +For many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack).

+

Internal vs external monitoring

+

There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor.

+

The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems.

+

Unprivileged operation

+

Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own.

+

If openstack availability zone list --compute fails for you without admin rights, please fix your openstack client. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Healh-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)

+

Driver VM via openstack CLI

+

The author prefers to setup the VM via openstack CLI tooling. He has working entries for all clouds he uses in his ~/.config/openstack/clouds.yaml and secure.yaml and has exported the OS_CLOUD environment variable to point to the cloud he is working on to set up the driver VM. The author uses the bash shell. All of this of course could be scripted.

+

So here we go

+
    +
  1. Create the network setup for a VM in a network oshm-network with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network.
  2. +
+
PUBLIC=$(openstack network list --external -f value -c Name)
openstack router create oshm-router
openstack router set --external-gateway $PUBLIC oshm-driver-router
openstack network create oshm-network
openstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet
openstack router add subnet oshm-router oshm-subnet
+
    +
  1. Create a security group that allows ssh and ping access
  2. +
+
openstack security group create sshping
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping
openstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping
+
    +
  1. Being at it, we also create the security group for grafana
  2. +
+
openstack security group create grafana
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana
+
    +
  1. To connect to the VM via ssh later, we create an SSH keypair
  2. +
+
openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key
chmod og-r ~/.ssh/oshm-key.pem
+

Rather than creating a new key (and storing and protecting the private key), we could have passed --public-key and used an existing keypair.

+
    +
  1. Look up Debian 12 image UUID.
  2. +
+
IMGUUID=$(openstack image list --name "Debian 12" -f value -c ID | tr -d '\r')
echo $IMGUUID
+

Sidenote: The tr command is there to handle broken tooling that embeds a trailing \r in the output.

+
    +
  1. Boot the driver VM
  2. +
+
openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver
+

Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing --block-device. See diskless flavor blog article. For flavors with local root disks, you could have used the --image $IMGUUID parameter instead.

+
    +
  1. Wait for it to boot (optional) +You can look at the boot log with openstack console log show oshm-driver or connect to it via VNC at the URL given by openstack console url show oshm-driver. You can of course also query openstack on the status openstack server list or openstack server show oshm-driver. You can also just create a simple loop:
  2. +
+
declare -i ctr=0 RC=0
while [ $ctr -le 120 ]; do
STATUS="$(openstack server list --name oshm-driver -f value -c Status)"
if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi
if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi
if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi
sleep 2
let ctr+=1
done
# return $RC
if [ $RC != 0 ]; then false; fi
+
    +
  1. Attach a floating IP so it's reachable from the outside.
  2. +
+
FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks |  sed "s@^[^:]*:[^']*'\([0-9\.]*\)'.*\$@\1@")
FIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)
echo $FIXEDIP $FIXEDPORT
openstack floating ip create --port $FIXEDPORT $PUBLIC
FLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")
echo "Floating IP: $FLOATINGIP"
+

Remember this floating IP address.

+
    +
  1. Connect to it via ssh
  2. +
+
ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP
+

On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)

+

All the following commands are performed on the newly started driver VM.

+

Configuring openstack CLI on the driver VM

+

We need to install the openstack client utilities.

+
sudo apt-get update
sudo apt-get install python3-openstackclient
sudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient
+

Configure your cloud access in ~/.config/openstack/clouds.yaml

+
clouds:
CLOUDNAME:
interface: public
identity-api-version: 3
#region_name: REGION
auth:
auth_url: KEYSTONE_ENDPOINT
project_id: PROJECT_UUID
#alternatively project_name and project_domain_name
user_domain_name: default
# change to your real domain
+

and secure.yaml (in the same directory)

+
clouds:
CLOUDNAME:
auth:
username: USERNAME
password: PASSWORD
+

The CLOUDNAME can be freely chosen. This is the value passed to the openstack CLI with --os-cloud or exported to your environment in OS_CLOUD. The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample clouds.yaml file that works (but lacks the password).

+

Protect your secure.yaml from being read by others: chmod 0600 ~/.config/openstack/secure.yaml.

+

If you are using application credentials instead of username, password to authenticate, you don't need to specify project_id nor project's nor user's domain names in clouds.yaml. Just (in secure.yaml):

+
clouds:
CLOUDNAME:
auth_type: v3applicationcredential
auth:
application_credential_id: APPCRED_ID
application_credential_secret: "APPCRED_SECRET"
+

Configure this to be your default cloud:

+
export OS_CLOUD=CLOUDNAME
+

You might consider adding this to your ~/.bashrc for convenience. Being at it, you might want to add export CLIFF_FIT_WIDTH=1 there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste).

+

Verify that your openstack CLI works:

+
openstack catalog list
openstack server list
+

You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases.

+

Custom CA

+

If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in /etc/ssl/certs/ca-certificates.crt. You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the debian user.

+

Add it to your clouds.yaml

+
clouds:
CLOUDNAME:
cacert: /PATH/TO/CACERT.CRT
[...]
+

If you want to allow api_monitor.sh to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:

+
export OS_CACERT=/PATH/TO/CACERT.CRT
+

Consider adding this to your ~/.bashrc as well.

+

Your first api_monitor.sh iteration

+

Checkout openstack-health-monitor:

+
sudo apt-get install git bc jq netcat-traditional tmux zstd
git clone https://github.com/SovereignCloudStack/openstack-health-monitor
cd openstack-health-monitor
+

You may want to start a tmux (or screen) session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect.

+

The script api_monitor.sh is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the README.md file.

+

It is good practice to use tmux. This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to screen over tmux.

+

You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:

+
export IMG="Debian 12"
export JHIMG="Debian 12"
./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1
+

Leave out the -LL if you don't have a working loadbalancer service or replace -LL with -LO if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources).

+

Feel free to study the meaning of all the command line parameters by looking at the README.md. (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)

+

This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs DOWN, BUILD, creating are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual openstack RESOURCE list and openstack RESOURCE show NAME and RESOURCE being something like router, network, subnet, port, volume, server, floating ip, loadbalancer, loadbalancer pool, loadbalancer listener, security group, keypair, image, ...)

+

The api_monitor.sh uses and APIMonitor_TIMESTAMP prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong. +TIMESTAMP is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time).

+

This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least -N 2 to test the ability of the router to route traffic between networks. So expect -n 6 to become -N 2 -n 6 for a very small single-AZ cloud or -n 12 for a large 3 AZ cloud region. So, re-run the api_monitor.sh with the target sizing.

+

Resource impact and charging

+

Note that api_monitor.sh uses small flavors (SCS-1V-2 for the N jump hosts and SCS-1L-1 for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors.

+

If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run api_monitor.sh in a loop (which you will) with say 10 VMs (e.g. -N 2 -n 8) in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference.

+

Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of openstack volume list, openstack volume show BROKEN_VOLUME, openstack loadbalancer list, openstack loadbalancer show BROKEN_LB.)

+

Using -w -1 makes api_monitor.sh wait for interactive input whenever an error occurs; this can be convenient for debugging.

+

Once you have single iterations working nicely, we can proceed.

+

Automating startup and cleanup

+

Typically, we run api_monitor.sh with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here.

+
#!/bin/bash
# run_CLOUDNAME.sh
# Do some global settings
export IMG="Debian 12"
export JHIMG="Debian 12"
#export OS_CACERT=/home/debian/ca-certificates.pem
# Additional settings to override flavors or to
# configure email addresses for sending alarms can be set here

# Does openstack CLI work?
openstack server list >/dev/null || exit 1
# Upload log files to this swift container (which you need to create)
#export SWIFTCONTAINER=OS-HM-Logfiles

# CLEANUP
echo "Finding resources from previous runs to clean up ..."
# Find Floating IPs
FIPLIST=""
FIPS=$(openstack floating ip list -f value -c ID)
for fip in $FIPS; do
FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")
if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_
"; fi
done
FIPLIST=$(echo "$FIPLIST" | grep -v '^$' | sort -u)
# Cleanup previous interrupted runs
SERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)
KEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)
VOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)
NETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)
LOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)
ROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)
SECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)
echo CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS
for ENV in $FIPLIST; do
echo "******************************"
echo "CLEAN $ENV"
bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV
echo "******************************"
done
TOCLEAN=$(echo "$SERVERS
$KEYPAIR
$VOLUMES
$NETWORK
$LOADBAL
$ROUTERS
$SECGRPS
" | grep -v '^$' | sort -u)
for ENV in $TOCLEAN; do
echo "******************************"
echo "CLEAN $ENV"
bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV
echo "******************************"
done

# Now run the monitor
#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"
exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"
+

Compared to the previous run, we have explicitly set two networks here -N 2 and rely on the iterations being passed in as command line arguments. Add parameter -t if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (-LO) in this example rather than the amphora based one (-LL).

+

You may use one of the existing run_XXXX.sh scripts as example. Beware: eMail alerting with ALARM_EMAIL_ADDRESS and NOTE_EMAIL_ADDRESS (and limiting with -a and -R ) and reporting data to telegraf (option -S) may be present in the samples. Make this script executable (chmod +x run_CLOUDNAME.sh).

+

We wrap a loop around this in run_in_loop.sh:

+
#!/bin/bash
# run_in_loop.sh
rm stop-os-hm 2>/dev/null
while true; do
./run_CLOUDNAME.sh -i 200
if test -e stop-os-hm; then break; fi
echo -n "Hit ^C to abort ..."
sleep 15; echo
done
+

Also make this executable (chmod +x run_in_loop.sh). +To run this automatically in a tmux window whenever the system starts, we follow the steps in the startup README.md

+

Change OS_CLOUD in startup/run-apimon-in-tmux.sh. (If you need to set OS_CACERT, also add it in this file and pass it into the windows.)

+

Activate everything:

+
mkdir -p ~/.config/systemd/user/
cp -p startup/apimon.service ~/.config/systemd/user/
systemctl --user enable apimon
systemctl --user start apimon
sudo loginctl enable-linger debian
tmux attach oshealthmon
+

This assumes that you are using the user debian for this monitoring and have checked out the repository at ~/openstack-health-monitor/. Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)

+

Changing parameters and restarting

+

If you want to change the parameters passed to api_monitor.sh, you best do this by editing run_CLOUDNAME.sh, potentially after testing it with one iteration before.

+

To make the change effective, you can wait until the current 200 iterations are completed and the run_in_loop.sh calls run_CLOUDNAME.sh again. You can also hit ^C in the tmux window that hasapi_monitor.sh running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ^C during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ^C twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ./run_in_loop.sh again.

+

You can also issue the systemctl --user stop apimon command; it will basically do the same thing: Send ^C and then wait for everything to be completed and tear down the tmux session. +After waiting for that to complete, you can start it again with systemctl --user start apimon.

+

Multiple instances

+

You can run multiple instances of api_monitor.sh on the same driver VM. In this case, you should rename run_in_loop.sh to e.g. run_in_loop_CLOUDNAME1.sh and call run_CLOUDNAME1.sh from there. Don't forget to adjust startup/run-apimon-in-tmux.sh and startup/kill-apimon-in-tmux.sh to start more windows.

+

It is not recommended to run multiple instances against the same OpenStack project however. While the api_monitor.sh script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the run_CLOUDNAME.sh script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations.

+

Alarming and Logs

+

eMail

+

If wanted, the api_monitor.sh can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the -a N and -R options. In order to enable sending emails from the driver VM, it needs to have postfix (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly.

+

Once you have configured postfix, you can enable eMail notifications using the option -e. Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ALARM_EMAIL_ADDRESSES and NOTE_EMAIL_ADDRESSES environment variables to api_monitor.sh, e.g. by setting it in the run_CLOUDNAME.sh.

+

Log files

+

api_monitor.sh writes a log file with the name APIMonitor_TIMESTAMP.log. It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (TIMESTAMP is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)

+

Note that api_monitor.sh does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties.

+

The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable SWIFTCONTAINER has been set (in run_COULDNAME.sh) when starting api_monitor.sh. the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER

+

After the 200 iterations, a .psv file (pipe-separated values) is created Stats.STARTTIME-ENDTIME.psv (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured).

+

Data collection and dashboard

+

See https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md

+

telegraf

+

To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:

+
sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key
echo "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list
sudo apt update
sudo apt -y install telegraf
+

In the config file /etc/telegraf/telegraf.conf, we enable

+
[[inputs.influxdb_listener]]
service_address = ":8186"

[[outputs.influxdb]]
urls = ["http://127.0.0.1:8086"]
+

and restart the service (sudo systemctl restart telegraf). +Enable it on system startup: sudo systemctl enable telegraf.

+

influxdb

+

We proceed to influxdb:

+
sudo apt-get install influxdb
+

In the configuration file /etc/influxdb/influxdb.conf, ensure that the http interface on port 8086 is enabled.

+
[http]
enabled = true
bind-address = ":8086"
+

Restart influxdb as needed with sudo systemctl restart influxdb. +Also enable it on system startup: sudo systemctl enable influxdb.

+

Add -S CLOUDNAME to your run_CLOUDNAME.sh script

+

You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter -S CLOUDNAME to the api_monitor.sh call in run_CLOUDNAME.sh. Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete).

+

grafana

+

Basic config

+

Finally grafana: We (still as root) follow https://www.server-world.info/en/note?os=Debian_12&p=grafana

+
sudo wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt -y install grafana
+

The config file /etc/grafana/grafana.ini needs some adjustments:

+
    +
  • Set the hostname in [server] section: domain = health.YOURCLOUD.sovereignit.cloud. Set the protocol = https if not enabled by default. +You can use a hostname of your liking, but we will need to create TLS certificates for this host. So we should have control over DNS TXT records for this domain if we want to use Let's Encrypt with DNSAUTH. The sovereignit.cloud domain is controlled by the SCS project team and has been used for a number of health mon instances. +In this same section, set cert_file = /etc/grafana/health-fullchain.pem and cert_key = /etc/grafana/health-key.pem. Ensure that both files are readable by root:grafana and that the key file is not world-readable.
  • +
  • Configure the admin access. In section [security], set the admin_user = admin and admin_password = SOME_SECRET_PASS which you keep private.
  • +
  • Allow local data sources (same section): data_source_proxy_whitelist = localhost:8088 localhost:8086
  • +
  • Let's disallow user signup (in section [users]): allow_sign_up = false and allow_org_create = false.
  • +
  • We do the OIDC connection with [auth.github] later.
  • +
+

We can now restart the service: sudo systemctl restart grafana-server. +Being at it, also enable it on system startup: sudo systemctl enable grafana-server.

+

You should now be able to access your dashboard on https://health.YOURCLOUD.sovereignit.de:3000 and log in via the configured username admin and your SOME_SECRET_PASS password.

+

Enable influx database in grafana

+

In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to http://localhost:8086 (despite this being the suggestion). Set the database name to telegraf. Save&test should succeed.

+

Importing the dashboard

+

Go to Home, Dashboards, New, Import. +Upload the dashboard .json file from the repository, user the Grafana-10 variant if you use Grafana 10 or newer.

+

In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.) +Save.

+

Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable).

+

No data displayed?

+

Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.

+

One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved.

+

Dashboard features

+

Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended.

+

The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously.

+

You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term.

+

github OIDC integration

+

The SCS providers do allow all github users that belong to the SovereignCloudStack organization to get Viewer access to the dashboards by adding a client_id and client_secret in the [github.auth] section that you request from the SCS github admins (github's oauth auth). This allows to exchange experience and to get a feeling for the achievable stability. (Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)

+

Alternative approach to install and configure the dashboard behind a reverse proxy

+

Install influxdb via apt: https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss +Install telegraf (same apt repo as influxdb): sudo apt update && sudo apt install telegraf +Install grafana: https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository

+

Prepare configuration by using the config files from the repository as an alternative to doing the changes manually (as described above):

+
sudo cp dashboard/telegraf.conf /etc/telegraf && sudo chown root:root /etc/telegraf/telegraf.conf && sudo chmod 0644 /etc/telegraf/telegraf.conf
sudo cp dashboard/config.toml /etc/influxdb && sudo chown root:influxdb /etc/influxdb/config.toml && sudo chmod 0640 /etc/influxdb/config.toml
sudo cp dashboard/grafana.ini /etc/grafana && sudo chown root:grafana /etc/grafana/grafana.ini && sudo chmod 0640 /etc/grafana/grafana.ini
+

These config files should work as long as the versions of telegraf, influxdb and grafana don't evolve too far from the ones used in the repository. (Otherwise refer to above instructions how to tweak the default config files.)

+

Changes to /etc/grafana/grafana.ini as we do tls termination at the reverse proxy:

+
    +
  • set protocol = http
  • +
  • comment out domain option (? FIXME) or set it to the hostname
  • +
  • comment out cert_* options
  • +
+

Also change the admin password in grafana.ini.

+

Changes to /etc/grafana/grafana.ini if github auth should not be used yet:

+
    +
  • comment out whole [auth.github] section for now (can be enabled later)
  • +
+

Restart services: sudo systemctl restart telegraf && sudo systemctl restart influxdb && sudo systemctl restart grafana-server

+

Configuration in grafana web gui:

+
    +
  • Login to grafana http(s)://<domain>:3000 with user admin and default password from /etc/grafana/grafana.ini and change password.
  • +
  • Create influxdb datasource with url http://localhost:8086 and database name telegraf.
  • +
  • Finally import dashboard dashboard/openstack-health-dashboard.json to grafana.
  • +
+

TODO:

+
    +
  • Reverse proxy (aka ingress) with Let's Encrypt cert
  • +
  • Github auth as described above
  • +
+

Maintenance

+

The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained.

+

Unattended upgrades

+

It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See https://wiki.debian.org/UnattendedUpgrades. If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and grafana (port 3000).

+

Updating openstack-health-monitor

+

You can just do a git update in the openstack-health-monitor directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ^C, see above in the restart section.

+

Backup

+

The system holds two things that you might consider valuable for long-term storage: +(1) The log files. These are compressed and uploaded to object storage if you enable the SWIFTCONTAINER setting, which probably means that these do not need any additional backing up then. +(2) The influx time series data. Back up the data in /var/lib/influxdb.

+

Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, clouds.yaml, etc. Be careful not to expose sensitive data by granting too generous access to your backed up files.

+

Troubleshooting

+

Debugging issues

+

In case there is trouble with your cloud, the normal course of action to analyze is as follows:

+
    +
  • Look at the dashboard (see above)
  • +
  • Connect to the driver VM and attach to the tmux session and look at the console output of api_monitor.sh
  • +
  • Analyze the logfile (locally on the driver VM or grab it from the object storage)
  • +
+

Analyzing failures

+

When VM instances are created successfully, but then end up in ERROR state, the api_monitor.sh does an explicit openstack server show, so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files.

+

Sometimes the VMs end up being ACTIVE as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail.

+

To gather more details, you can look at the console output openstack console log show VM (where VM is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ssh -i APIMonitor_XXXXX_JH.pem debian@FIP, whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP. Replace XXXXX with the number in your current APIMonitor prefix, FIP with the floating IP address of the responsible JumpHost and debian with the user name used by the images you boot. Use 223 to connect to the second VM in the network, 224 the third etc.

+

When logged in, look at /var/log/cloud-init-output.log and /var/log/cloud-init.log. You can find the metadata in /var/lib/cloud/instance/.

+

You will not have much time to look around -- the still running api_monitor.sh script does continue and clean things up again. So you might want to suspend it with ^Z (and continue it later with fg). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the run_CLOUDNAME.sh script as it would do cleanup against the running instance, but rather copy the api_monitor.sh command line from the bottom (without the exec), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach -w -1 to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work.

+

Cleaning things up

+

If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard).

+

There are a few things that may need support from a cloud admin:

+
    +
  • Volumes may end up permanently in a deleting or reserved state or may be in-use, attached to a VM that has long gone. The admin needs to set the state to error and then delete them.
  • +
  • Loadbalancers may end up in a PENDING_XXX state (XXX being CREATE, UPDATE or DELETE) without ever changing. This also needs the cloud admin to set the status to ERROR, so it can be cleaned up. amphorae are more prone to this than ovn LBs.
  • +
+

More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted.

+

The source of this document can be found in the SovereignCloudStack/openstack-health-monitor repository.

+

Author: SCS Community, License: CC by Attribution 4.0 International

+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/project-manager/index.html b/docs/iaas/guides/operations-guide/openstack/tools/project-manager/index.html new file mode 100644 index 0000000000..6c861af861 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/project-manager/index.html @@ -0,0 +1,86 @@ + + + + + +Project Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Project Manager

+

Overview

+

The OpenStack Project Manager manages the creation of Openstack Domains, Projects and Users.

+

Installation

+

Prepare to use the Openstack Project Manager.

+

During installation, ldap libraries are required under Linux; you should install libldap2-dev and libsasl2-dev beforehand.

+
git clone https://github.com/osism/openstack-project-manager
cd openstack-project-manager
pipenv install
pipenv shell
+

Defaults

+

create.py

+

The create.py command and his default options while executing the command.

+
 --admin-domain              default
--assign-admin-user true
--cloud admin
--create-admin-user true
--create-domain false
--create-user false
--domain-name-prefix true
--has-service-network false
--has-public-network true
--has-shared-images true
--internal-id unset
--random false
--managed-network-resources false
--name sandbox
--owner unset
--password unset
--password-length 16
--public-network public
--quota-class basic
--service-network-cidr unset
--quota-multiplier 1
--quota-multiplier-compute unset
--quota-multiplier-network unset
--quota-multiplier-storage unset
--quota-router 1
+

manage.py

+

The manage.py has also some defaults while executing and will touch all projects in your Openstack Cluster, if not --domain is used.

+
 --admin-domain        default
--assign-admin-user false
--classes etc/classes.yml
--domain unset
--dry-run false
--endpoints etc/endpoints.yml
--manage-endpoints false
--manage-homeprojects false
--name unset
+

Default Openstack Roles to users are set to member and load-balancer_member at this time, the behavior can only be changed in the code.

+

Usage

+

There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Project Manager will be executed, examples are provided within the git repository.

+

The cloud profile to be used can be specified via the optional --cloud parameter. By default the cloud profile with the name admin is used. It has to be and admin account, to create and modify domains, projects, users and quotas.

+

The Openstack Project Manager essentially consists of two parts, the create.py and the manage.py, there are more scripts for handling users using ldap which needs more configuration setup.

+

create.py

+

This command is used to create and modify domains, projects, users and quotas. As default the domain is used as prefix for all projects and users created for easy alloction in Openstack.

+
note

create.py can't delete once created objects, this must be done using Openstack commands to remove a project or domain.

+
python src/create.py -h
usage: create [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--create-admin-user] [--create-domain] [--create-user]
[--domain DOMAIN] [--domain-name-prefix] [--has-public-network] [--has-service-network] [--has-shared-images] [--internal-id INTERNAL_ID] [--managed-network-resources] [--name NAME]
[--noassign-admin-user] [--nocreate-admin-user] [--nocreate-domain] [--nocreate-user] [--nodomain-name-prefix] [--nohas-public-network] [--nohas-service-network]
[--nohas-shared-images] [--nomanaged-network-resources] [--norandom] [--owner OWNER] [--password PASSWORD] [--password-length PASSWORD_LENGTH] [--public-network PUBLIC_NETWORK]
[--quota-class QUOTA_CLASS] [--quota-multiplier QUOTA_MULTIPLIER] [--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE] [--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK]
[--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE] [--quota-router QUOTA_ROUTER] [--random] [--service-network-cidr SERVICE_NETWORK_CIDR]

options:
-h, --help show this help message and exit
--admin-domain ADMIN_DOMAIN
Admin domain
--assign-admin-user Assign admin user
--cloud CLOUD Managed cloud
--config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set
is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the
command-line.
--config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the
command-line.
--create-admin-user Create admin user
--create-domain Create domain only
--create-user Create user
--domain DOMAIN Domain
--domain-name-prefix Add domain name as prefix to the project name
--has-public-network Has public network infrastructure
--has-service-network
Has service network infrastructure
--has-shared-images Has shared images
--internal-id INTERNAL_ID
Internal ID
--managed-network-resources
Manage the network resources
--name NAME Projectname
--noassign-admin-user
The inverse of --assign-admin-user
--nocreate-admin-user
The inverse of --create-admin-user
--nocreate-domain The inverse of --create-domain
--nocreate-user The inverse of --create-user
--nodomain-name-prefix
The inverse of --domain-name-prefix
--nohas-public-network
The inverse of --has-public-network
--nohas-service-network
The inverse of --has-service-network
--nohas-shared-images
The inverse of --has-shared-images
--nomanaged-network-resources
The inverse of --managed-network-resources
--norandom The inverse of --random
--owner OWNER Owner of the project
--password PASSWORD Password
--password-length PASSWORD_LENGTH
Password length
--public-network PUBLIC_NETWORK
Public network
--quota-class QUOTA_CLASS
Quota class
--quota-multiplier QUOTA_MULTIPLIER
Quota multiplier
--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE
Quota multiplier compute
--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK
Quota multiplier network
--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE
Quota multiplier storage
--quota-router QUOTA_ROUTER
Quota router
--random Generate random names
--service-network-cidr SERVICE_NETWORK_CIDR
Service network CIDR
+

Create a Domain and inital project

+

When executing the create.py command, the first time with --domain, it will create a new domain, an admin account and the first project webshop. The admin account will be created in the default Domain of Openstack and can be used for the Service Provider to manager the complete domain.

+
$ python3 src/create.py --domain democompany --name webshop
+----------------+----------------------+----------------------------------+
| name | value | id |
|----------------+----------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-webshop | 645538bf67664cfeaed32476d58f95fb |
| admin | democompany-admin | cc8d6bf7b61d4199ba5a4230c4ec6d62 |
| admin_password | qawsEdfg2d45Fsxc | |
+----------------+----------------------+----------------------------------+
+

Create a User for a project

+
$ python3 src/create.py --domain democompany --name webshopuser --create-user             
+----------+-------------------------+----------------------------------+
| name | value | id |
|----------+-------------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-webshop | 5752b6701026478f9cac122fc54eb9cb |
| user | democompany-webshopuser | ce213655559d47d7800501124fed4d02 |
| password | vEvM9vgRESdffWE2 | |
+----------+-------------------------+----------------------------------+
+

Create additional project with unlimited quota

+
$ python3 src/create.py --domain democompany --name styles --quota-class unlimited
+----------+--------------------+----------------------------------+
| name | value | id |
|----------+--------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-styles | 666097e396fd4f9392d6aa55c76d8267 |
+----------+--------------------+----------------------------------+
+

Set quotas for a project

+

All quota information must be set as a property to the Openstack project within your Openstack Cluster, if no property is set, the basic quotaclass of etc/classes.yml will be applied. +It is possible to set a quota multiplier for any project.

+

The following command you set a multiplier of 256 of the basic quota:

+
$ openstack project set --property quotamultiplier=256 democompany-webshop
+

Adjusting gigabyte quota for storage with a multiplier of 20 of the basic quota for a project:

+
$ openstack project set  --property quotamultiplier_storage=20 democompany-webshop
+

This will override the general quotamultiplier only for storage.

+

Other possible multiplier which can be set individually are: quotamultiplier_compute, quotamultiplier_network, quota_router

+

To change the quotaclass to unlimited from the etc/classes.yaml

+
$ openstack project set  --property quotaclass=unlimited democompany-webshop
+

Special project: images

+

With this special Project you can share all images uploaded into this project to all other project in your domain which has set the property has-shared-images, which is by default set. +Alsoi only the domain-admin user has access to this project, other domain users won't see this, they will find the uploaded images in their projects. +If you want your grant other domain users also access to upload some images, you need to give them access to the images Project in Openstack.

+
$ python3 src/create.py --domain democompany --name images
+---------+---------------------+----------------------------------+
| name | value | id |
|---------+---------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-images | 6d57f39aacbe485d87733865b1e79d03 |
+---------+---------------------+----------------------------------+
+

Additionally you need to add the domain and domain-admin user to the clouds.yaml, it is always named opm-domainname-admin: so the manage.py can setup permissions to the projects later on and users are able to find the images.

+
  opm-democompany-admin:
auth:
auth_url: https://keystone.my.cloud:5000/v3
username: democompany-admin
password: yourpassword
user_domain_name: Default
project_domain_name: democompany
identity_api_version: 3
+

Special project: service

+

With this special project you can share installed services, like a harbor, to all other projects in your domain. Per default, only the domain admin has access to this project.

+
$ python3 src/create.py --domain democompany --name service
+---------+---------------------+----------------------------------+
| name | value | id |
|---------+---------------------+----------------------------------|
| domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 |
| project | democompany-service | a5558f7338f94adea5f41858636256b5 |
+---------+---------------------+----------------------------------+
+

manage.py

+
warning

This command applies quotas, networks and routers to all projects in the Openstack Cluster, not only to those have been configured previously with the create.py or openstack project set --property commands.

+

Best is to run this command by cron, every hour to apply all pending changes, it is also possible to run this at the command line to apply changes immediately.

+
python3 src/manage.py -h
usage: manage [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--classes CLASSES] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--domain DOMAIN] [--dry-run]
[--endpoints ENDPOINTS] [--manage-endpoints] [--manage-homeprojects] [--name NAME] [--noassign-admin-user] [--nodry-run] [--nomanage-endpoints] [--nomanage-homeprojects]

options:
-h, --help show this help message and exit
--admin-domain ADMIN_DOMAIN
Admin domain
--assign-admin-user Assign admin user
--classes CLASSES Path to the classes.yml file
--cloud CLOUD Cloud name in clouds.yaml
--config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set
is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the
command-line.
--config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the
command-line.
--domain DOMAIN Domain to be managed
--dry-run Do not really do anything
--endpoints ENDPOINTS
Path to the endpoints.yml file
--manage-endpoints Manage endpoints
--manage-homeprojects
Manage home projects
--name NAME Project to be managed
--noassign-admin-user
The inverse of --assign-admin-user
--nodry-run The inverse of --dry-run
--nomanage-endpoints The inverse of --manage-endpoints
--nomanage-homeprojects
The inverse of --manage-homeprojects
+

Manage a specific domain only

+
$ python3 src/manage.py --domain democompany

2024-04-19 14:24:02.873 | INFO | democompany - domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03
2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03, domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:04.953 | INFO | democompany-images - quotaclass {'compute': {'cores': 0, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 0, 'key_pairs': 0, 'metadata_items': 128, 'ram': 0, 'server_group_members': 0, 'server_groups': 0}, 'network': {'floatingip': 0, 'network': 0, 'port': 0, 'rbac_policy': 0, 'router': 0, 'security_group': 0, 'security_group_rule': 0, 'subnet': 0, 'subnetpool': 0}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 1000, 'per_volume_gigabytes': 25, 'snapshots': 0, 'volumes': 100}, 'parent': 'default'}
2024-04-19 14:24:04.953 | INFO | democompany-images - check network quota
2024-04-19 14:24:05.048 | INFO | democompany-images - check compute quota
2024-04-19 14:24:05.175 | INFO | democompany-images - check volume quota
2024-04-19 14:24:05.286 | INFO | democompany-images - check if external rbac policy must be deleted (public)
2024-04-19 14:24:05.349 | INFO | democompany-images - check if service rbac policy must be deleted (democompany-service)
2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5
2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5, domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:06.131 | INFO | democompany-service - quotaclass {'compute': {'cores': 256, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 256, 'key_pairs': 256, 'metadata_items': 128, 'ram': 262144, 'server_group_members': 256, 'server_groups': 256}, 'network': {'floatingip': 256, 'network': 256, 'port': 256, 'rbac_policy': 1024, 'router': 256, 'security_group': 256, 'security_group_rule': 1024, 'subnet': 256, 'subnetpool': 256}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 0, 'per_volume_gigabytes': 0, 'snapshots': 0, 'volumes': 0}, 'parent': 'default'}
2024-04-19 14:24:06.131 | INFO | democompany-service - check network quota
2024-04-19 14:24:06.212 | INFO | democompany-service - check compute quota
2024-04-19 14:24:06.330 | INFO | democompany-service - check volume quota
2024-04-19 14:24:06.467 | INFO | democompany-service - check if external rbac policy must be created (public)
2024-04-19 14:24:06.589 | INFO | democompany-service - check if service rbac policy must be deleted (democompany-service)
2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb
2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb, domain_id = a8549ef5d3d14f938b127a1cdefe3788
2024-04-19 14:24:06.915 | INFO | democompany-webshop - quotaclass {'compute': {'cores': 4, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': -1, 'key_pairs': 4, 'metadata_items': 128, 'ram': 8192, 'server_group_members': 4, 'server_groups': 4}, 'network': {'floatingip': 4, 'network': 1, 'port': 20, 'rbac_policy': 10, 'router': 0, 'security_group': 5, 'security_group_rule': 20, 'subnet': 2, 'subnetpool': 1}, 'volume': {'backup_gigabytes': 40, 'backups': 8, 'gigabytes': 20, 'per_volume_gigabytes': 200, 'snapshots': 4, 'volumes': 4}, 'parent': 'default'}
2024-04-19 14:24:06.915 | INFO | democompany-webshop - check network quota
2024-04-19 14:24:06.993 | INFO | democompany-webshop - check compute quota
2024-04-19 14:24:07.114 | INFO | democompany-webshop - check volume quota
2024-04-19 14:24:07.254 | INFO | democompany-webshop - check if external rbac policy must be created (public)
2024-04-19 14:24:07.334 | INFO | democompany-webshop - check if service rbac policy must be deleted (democompany-service)
+

Config files

+

The config files which can be used for create.py and manage.py are using the oslo.config format, you can set the command line options as key = value pair and create your own config files matching your setup.

+
democompany.conf
[DEFAULT]
cloud = admin
domain = democompany
+

Quota Templates

+

Edit the etc/classes.yml file if you want to change or add new quota templates

+

Setup Endpoints

+

Edit the etc/endpoints.yml file to fit your available endpoints

+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/resource-manager/index.html b/docs/iaas/guides/operations-guide/openstack/tools/resource-manager/index.html new file mode 100644 index 0000000000..307b9a7c54 --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/resource-manager/index.html @@ -0,0 +1,43 @@ + + + + + +Resource Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Resource Manager

+

Preparations

+

Prepare use of the OpenStack Resource Manager.

+
git clone https://github.com/osism/openstack-resource-manager
cd openstack-resource-manager
pipenv install
pipenv shell
+

Prepare cloud profile admin in clouds.yml and secure.yml (use clouds.yml.sample and secure.yml.sample +in the openstack-resource-manager repository as sample files).

+

Nova

+

Live migration

+

Live migrate all instances from compute node SOURCE to compute node TARGET.

+
python3 src/host-action.py --yes --disable --action live-migrate --host SOURCE --input TARGET
+

Evacuation

+

Evacuate all instances from compute node SOURCE to compute node TARGET.

+
python3 src/host-action.py --yes --action evacutate --host SOURCE --input TARGET
+

Octavia

+

Amphora rotation

+

Rotation of amphorae older than 30 days.

+
$ python3 src/amphora.py --rotate
2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa is older than 30 days
2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa of loadbalancer 9008d3d7-f593-4bc3-941c-a740c178148d is rotated by a loadbalancer failover
+

Cinder

+
$ python3 src/volume.py
2023-12-11 23:09:44 | INFO | Volume ad848454-ba1f-4c28-b9a8-edada17948b0 hangs in CREATING status for more than 2 hours
Delete volume ad848454-ba1f-4c28-b9a8-edada17948b0 [yes/no]:
+

Orphans

+
$ python3 src/orphan.py
2023-12-11 23:11:16 | INFO | Checking nova / server
2023-12-11 23:11:21 | INFO | Checking neutron / port
2023-12-11 23:11:23 | INFO | Checking neutron / router
2023-12-11 23:11:23 | INFO | Checking neutron / network
2023-12-11 23:11:24 | INFO | Checking neutron / subnet
2023-12-11 23:11:24 | INFO | Checking neutron / floatingip
2023-12-11 23:11:24 | INFO | Checking neutron / rbacpolicy
2023-12-11 23:11:24 | INFO | Checking neutron / securitygroup
2023-12-11 23:11:26 | INFO | Checking neutron / securitygrouprule
2023-12-11 23:11:27 | INFO | Checking glance / image
2023-12-11 23:11:30 | INFO | Checking glance / imagemember
[...]
+---------------+-------------------+--------------------------------------+----------------------------------+
| servicename | resourcename | resource_id | project_id |
|---------------+-------------------+--------------------------------------+----------------------------------|
| neutron | port | 561f8f76-18b0-470a-92cd-4336346b4b18 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | port | 6d1986e4-1e6d-4d4a-961d-97d372945bb1 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | port | 74f9bddc-9bfa-4d06-a147-ca87127e501e | 8268b05ef24b41d8806c0fe417576610 |
| neutron | port | f630a66b-7725-4a68-868b-caebbaf1c003 | 8268b05ef24b41d8806c0fe417576610 |
| neutron | router | c0c4e4aa-53ee-4fd1-8f53-84d52cf6c60b | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | router | c8f9a13b-adcd-4a8e-942b-338bcf4dde7c | 8268b05ef24b41d8806c0fe417576610 |
| neutron | network | 62d6ad2a-0cda-4d45-9325-963b8eb67000 | 8268b05ef24b41d8806c0fe417576610 |
| neutron | network | 63b8fea6-7d7b-40c3-9c31-bee4404a92d6 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | subnet | 0cd16262-330a-44ad-9160-daef84aded2d | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | subnet | 690dee14-ac12-464d-a911-a873c27ec818 | d33b0d15fd474131a335207216297a2a |
| neutron | subnet | 854e7c55-62e2-4679-9b18-805460b998ce | 8268b05ef24b41d8806c0fe417576610 |
| neutron | rbacpolicy | 00d7c2a2-6674-4f40-9f95-176a7858fcca | c8e4393b6d064a26a31014f82939172f |
| neutron | rbacpolicy | 0608c701-5b81-4712-989b-ba03cdcc255d | c8e4393b6d064a26a31014f82939172f |
[...]
| neutron | securitygrouprule | fd3c553f-168e-4c24-ab40-09aa934bab86 | 3a96207b719643ae9ea9a81d95116e9e |
| neutron | securitygrouprule | fdf337be-971c-4d5d-88ca-d90cdb468e88 | 3cfa8679f5d8429382b95d4d2dd80f79 |
| neutron | securitygrouprule | ff8162fe-f053-49c9-8659-078061ce3e23 | d0b0add9ede0452791f71cb900e35242 |
| glance | imagemember | c7f2cb0c25d34c5d886ecaf483e5fda6 | c7f2cb0c25d34c5d886ecaf483e5fda6 |
| glance | imagemember | d4d0a161f9024fc8b517b0375eb97c89 | d4d0a161f9024fc8b517b0375eb97c89 |
| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |
| glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 |
| glance | imagemember | d33b0d15fd474131a335207216297a2a | d33b0d15fd474131a335207216297a2a |
| cinder | volume | e7c4b05c-b76a-40cc-8381-03262e57eb94 | 9b5f7f8ed70d410c81e3f45bf4e36498 |
+---------------+-------------------+--------------------------------------+----------------------------------+
+ + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager/index.html b/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager/index.html new file mode 100644 index 0000000000..4ee26fc53e --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager/index.html @@ -0,0 +1,23 @@ + + + + + +Sandbox Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/operations-guide/openstack/tools/simple-stress/index.html b/docs/iaas/guides/operations-guide/openstack/tools/simple-stress/index.html new file mode 100644 index 0000000000..ab399ac4dd --- /dev/null +++ b/docs/iaas/guides/operations-guide/openstack/tools/simple-stress/index.html @@ -0,0 +1,48 @@ + + + + + +Simple Stress | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Simple Stress

+

Overview

+

The OpenStack Simple Stress is a small stress test for your Openstack Cluster. You can use it for burnin tests or if you want to monitor your cluster perfomance. +It is able to start a predefined amount of Servers in specific networks in parallel and serial and removes them afterwards, so you can test your environment to the limits.

+

Installation

+

Prepare to use the Openstack Simple Stress.

+
git clone https://github.com/osism/openstack-simple-stress
cd openstack-simple-stress
pipenv install
pipenv shell
+

Defaults

+

The main.py command and his default options while executing the command.

+
 --cleanup       true
--cloud simple-stress
--compute-zone nova
--debug false
--delete true
--flavor SCS-2V-8
--floating false
--image Ubuntu 22.04
--interval 10 (seconds)
--keypair unset
--network simple-stress
--network-zone nova
--number 1
--parallel 1
--prefix simple-stress
--storage-zone simple-stress
--timeout 600 (seconds)
--volume false
--volume-number 1
--volume-size 1 (gigabyte)
--wait true
+

Usage

+

There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Simple Stress will be executed, examples are provided within the git repository.

+

The cloud profile to be used can be specified via the optional --cloud parameter. By default, the cloud profile with the name simple-stress is used.

+
$ python src/main.py -h
usage: main [-h] [--cleanup] [--cloud CLOUD] [--compute-zone COMPUTE_ZONE] [--config-dir DIR]
[--config-file PATH] [--debug] [--delete] [--flavor FLAVOR] [--floating] [--image IMAGE]
[--interval INTERVAL] [--keypair KEYPAIR] [--network NETWORK] [--network-zone NETWORK_ZONE]
[--nocleanup] [--nodebug] [--nodelete] [--nofloating] [--novolume] [--nowait]
[--number NUMBER] [--parallel PARALLEL] [--prefix PREFIX] [--storage-zone STORAGE_ZONE]
[--timeout TIMEOUT] [--volume] [--volume-number VOLUME_NUMBER] [--volume-size VOLUME_SIZE]
[--wait]

options:
-h, --help show this help message and exit
--cleanup
--cloud CLOUD Cloud name
--compute-zone COMPUTE_ZONE
Compute availability zone to use
--config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted,
so as to provide a predictable parse order if individual options are over-
ridden. The set is parsed after the file(s) specified via previous --config-
file, arguments hence over-ridden options in the directory take precedence. This
option must be set from the command-line.
--config-file PATH Path to a config file to use. Multiple config files can be specified, with
values in later files taking precedence. Defaults to None. This option must be
set from the command-line.
--debug
--delete
--flavor FLAVOR
--floating
--image IMAGE
--interval INTERVAL
--keypair KEYPAIR
--network NETWORK
--network-zone NETWORK_ZONE
Network availability zone to use
--nocleanup The inverse of --cleanup
--nodebug The inverse of --debug
--nodelete The inverse of --delete
--nofloating The inverse of --floating
--novolume The inverse of --volume
--nowait The inverse of --wait
--number NUMBER
--parallel PARALLEL
--prefix PREFIX
--storage-zone STORAGE_ZONE
Storage availability zone to use
--timeout TIMEOUT
--volume
--volume-number VOLUME_NUMBER
--volume-size VOLUME_SIZE
--wait
+

Running a small and simple test on your Openstack environment, using Ubuntu_22.04 image with the flavor of 2VCPUs and 8Gigabytes of RAM, starting 6 servers, 2 parallel each with a volume size of 20Gigabytes.

+
$ python src/main.py --network test-net --flavor SCS-2V-8 --image Ubuntu_22.04 --number 6 --parallel 2 --volume-size 20
2024-04-23 11:47:16 | INFO | Checking flavor SCS-2V-8
2024-04-23 11:47:17 | INFO | flavor.id = 926f952f-0714-4c55-92c2-7514191fecce
2024-04-23 11:47:17 | INFO | Checking image Ubuntu_22.04
2024-04-23 11:47:17 | INFO | image.id = 667649d6-e828-403b-8871-15dde7b9ce85
2024-04-23 11:47:17 | INFO | Checking network test-net
2024-04-23 11:47:18 | INFO | network.id = 9688192e-11dd-4618-a18c-99d3267f630a
2024-04-23 11:47:18 | INFO | Creating server simple-stress-0
2024-04-23 11:47:18 | INFO | Creating server simple-stress-1
2024-04-23 11:47:18 | INFO | Waiting for server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:18 | INFO | Waiting for server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:28 | INFO | Waiting for boot / test results of 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:29 | INFO | Waiting for boot / test results of e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:39 | INFO | Deleting server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:39 | INFO | Waiting for deletion of server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0)
2024-04-23 11:47:39 | INFO | Deleting server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:40 | INFO | Waiting for deletion of server e485697f-feae-458c-952d-000072374c3f (simple-stress-1)
2024-04-23 11:47:49 | INFO | Creating server simple-stress-2
2024-04-23 11:47:50 | INFO | Creating server simple-stress-3
2024-04-23 11:47:50 | INFO | Waiting for server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:47:51 | INFO | Waiting for server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:00 | INFO | Waiting for boot / test results of 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:48:01 | INFO | Waiting for boot / test results of a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:11 | INFO | Deleting server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:12 | INFO | Waiting for deletion of server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3)
2024-04-23 11:48:12 | INFO | Deleting server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:48:12 | INFO | Waiting for deletion of server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2)
2024-04-23 11:48:22 | INFO | Creating server simple-stress-4
2024-04-23 11:48:22 | INFO | Waiting for server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:22 | INFO | Creating server simple-stress-5
2024-04-23 11:48:23 | INFO | Waiting for server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:48:55 | INFO | Deleting server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:55 | INFO | Deleting server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:48:55 | INFO | Waiting for deletion of server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4)
2024-04-23 11:48:55 | INFO | Waiting for deletion of server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5)
2024-04-23 11:49:05 | INFO | Server 049bf974-b0fd-467f-aabd-3593b2a409a4 finished
2024-04-23 11:49:05 | INFO | Server e485697f-feae-458c-952d-000072374c3f finished
2024-04-23 11:49:05 | INFO | Server a098cc12-94ff-4036-bf42-4fc08287809f finished
2024-04-23 11:49:05 | INFO | Server 26595dd3-09d4-4758-8d1f-58a40b681d11 finished
2024-04-23 11:49:05 | INFO | Server 05b9f996-5a06-4359-b495-3463cc7b81e0 finished
2024-04-23 11:49:05 | INFO | Server 8d372de6-ca07-4afb-9e80-1589fd5242e8 finished
2024-04-23 11:49:05 | INFO | Runtime: 107.4460s
+

Using a config directory with configfiles to run the test.

+

Path to a config directory to pull *.conf files from. This file set is sorted, +so as to provide a predictable parse order if individual options are over-ridden. +The set is parsed after the file(s) specified via previous --config file, +arguments hence over-ridden options in the directory take precedence. This +option must be set from the command-line.

+
python src/main.py --config-dir /path/to/config-dir
+

Config files

+

The config files which can be used for main.py are using the oslo.config format, you can set the command line options as key = value pair and create your own config files matching your setup.

+
mytest.conf
[DEFAULT]
cloud = simple-stress
network = test-net
number = 6
parallel = 2
flavor = SCS-2V-8
image = Ubuntu_22.04
volume-size = 20
+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/cloud-in-a-box/index.html b/docs/iaas/guides/other-guides/cloud-in-a-box/index.html new file mode 100644 index 0000000000..d71c837696 --- /dev/null +++ b/docs/iaas/guides/other-guides/cloud-in-a-box/index.html @@ -0,0 +1,300 @@ + + + + + +Cloud in a Box - CiaB | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Cloud in a Box - CiaB

+

💡 Cloud in a Box (CiaB) is a minimalistic installation of the latest stable OSISM release with only services which are needed to +make it work with Kubernetes. It is intended for use as a development +system on bare-metal or for use in edge environments.

+
warning

At the moment the secrets are stored in plain text in the osism/cloud-in-a-box +repository and are not secure. Do not use for public accessible systems. In the future, the secrets will be generated automatically.

+

Requirements

+

The system to be used as Cloud in a Box must fulfill these minimum requirements.

+
Type of resourceAmountNote
CPUat least 1 socket with 4 coresMore is better here. This is the minimum where you can't use much payload (LBaaS, VMs). The use of Kubernetes with Cluster API is not possible with this minimum size.
RAMat least 32 GByteMore is better here. In principle, it also works with 8 GByte, but then no payload (LBaaS, VMs) can be used. Kubernetes with Cluster API cannot be used then.
Storageat least 1 TByteHas to be available as /dev/sda or /dev/nvme0n1. Less than 1 TByte is also possible, the smaller the less storage is available for use in Ceph.
Networkat least 1 network interface (DHCP and internet access)An optional 2nd network interface can be used for external connectivity.
USB stickat least 2 GByteInstallation media for Cloud in a Box bootstrapping
+

Types

+

There are two types of Cloud in a Box.

+
    +
  1. +

    The sandbox type is intended for developers and demonstrations. A full OSISM installation +is one there which also includes Ceph and OpenSearch, for example. In the course of the +installation, necessary images, networks, etc. are also created.

    +
  2. +
  3. +

    The edge type is intended to be deployed as an appliance to provide an edge cloud on a +single node. Compared to the sandbox, certain services are not provided there or are +implemented differently. For example, OpenSearch is not deployed because the logs are +delivered to a central location. The storage backend will also be implemented differently there +in the future instead of Ceph.

    +
  4. +
+

General notes and limitations

+
    +
  • Load balancing in Octavia is only possible via OVN. The Amphora driver is not supported. This is due +to the limited resources we have. With the Amphora driver, a dedicated instance is started for each +load balancer, each of which consumes 1 GByte of memory. This represents a very high consumption in +relation to the usual sizes of the Cloud in a Box.
  • +
+

Installation

+ +

The images currently download and install the +latest state of the installation scripts, +therefore it is mandatory to update the installation media at least when the underlying Ubuntu operating +system release changes. The installation of older releases is currently not supported.

+
    +
  1. +

    Download one of the Cloud in a Box images of type sandbox

    + +
  2. +
  3. +

    Use a tool like balenaEtcher or dd to create a bootable USB stick with the Cloud +in a Box image.

    +
  4. +
  5. +

    Boot from the USB stick. Make sure that the boot from USB is activated in the BIOS.

    +
    warning

    When booting from this USB stick, all data on the hard disks will be destroyed +without confirmation.

    +
  6. +
  7. +

    The installation of the operating system (Ubuntu 22.04) will start and take a few minutes. After that the system +will shutdown.

    +
  8. +
  9. +

    The first start of the system

    +
      +
    • Remove the USB storage device +(The USB stick is only needed again if the Cloud in a Box system is to be fully reinstalled.)
    • +
    • Connect the first network interface to an ethernet interface that provides access to the internet via DHCP configuration
    • +
    • Boot the system from the internal hard disk device
    • +
    +
  10. +
  11. +

    The deployment will start. This takes some time and the system will shutdown when the +deployment is finished. This takes roughly an hour, possibly longer depending on the +hardware and internet connection.

    +
  12. +
  13. +

    Start the system again. System is ready for use, by default DHCP is tried on the first network device.

    +
  14. +
  15. +

    Login via SSH. Use the user dragon with the password password. +(You can obtain the ip address by inspecting the logs of your dhcp server or from the issue text of the virtual consoles of the system)

    +
    ssh dragon@IP_FROM_YOUR_SERVER
    passwd
    +

    CiaB Issue Text

    +
  16. +
+

Manual installation

+
    +
  1. +

    Follow the provisioning guide, +skip the part about disk layout and do it this way:

    +

    Disk layout

    +
      +
    1. Create a 1 GByte ext4 partition mounted in /boot
    2. +
    3. Create a 8 GByte swap partition
    4. +
    5. Create a 120 GByte unformatted partition
    6. +
    7. Use a Create volume group (LVM) to create a volume group called system with the size of +120 GByte on the partition 4 you just created
    8. +
    9. Create a logical volume by selecting the Free Space option under system LVM. This volume +should be mounted in / and have size of 100 GByte
    10. +
    11. Create a partition with the size of the rest of the drive's space
    12. +
    13. Create a new LVM volume group on partition 5 called osd-vg (will be used for Ceph)
    14. +
    +
  2. +
  3. +

    After the Ubuntu installation, the system will be rebooted

    +
  4. +
  5. +

    Log into the machine via console to get its IP address and then use SSH to connect to the machine

    +
  6. +
  7. +

    Clone the osism/cloud-in-a-box repository into /opt/cloud-in-a-box

    +
    sudo git clone https://github.com/osism/cloud-in-a-box /opt/cloud-in-a-box
    +
  8. +
  9. +

    Disable conflicting services from the default Ubuntu installation

    +
    sudo /opt/cloud-in-a-box/cleanup.sh
    +
  10. +
  11. +

    Install upgrades

    +
    sudo apt update
    sudo apt upgrade
    +
  12. +
  13. +

    Run the bootstrap.sh script with the required type (use of sandbox is recommended)

    +
    sudo /opt/cloud-in-a-box/bootstrap.sh sandbox
    +
  14. +
  15. +

    Run the deploy.sh script with the same type as in step 8 to deploy services like Ceph and OpenStack

    +
    sudo /opt/cloud-in-a-box/deploy.sh sandbox
    +
  16. +
  17. +

    Shutdown the system

    +
    sudo shutdown -h now
    +
  18. +
  19. +

    Start the system again. System is ready for use, by default DHCP is tried on the first network device.

    +
  20. +
  21. +

    Login via SSH. Use the user dragon with the password password. +(You can obtain the ip address by inspecting the logs of your dhcp server or from the issue text of the virtual consoles of the system)

    +
    ssh dragon@IP_FROM_YOUR_SERVER
    passwd
    +

    CiaB Issue Text

    +
  22. +
+
info

The scripts are not idempotent yet. In case there is any fail during bootstrap.sh or deploy.sh you have to +start over with fresh installation.

+

Usage

+

Wireguard VPN service access

+

Copy the /home/dragon/wireguard-client.conf file from Cloud in a Box to your workstation. This is necessary +for using the web endpoints on your workstation. Rename the wireguard config file to something +like cloud-in-a-box.conf.

+

If you want to connect to the Cloud in a Box system from multiple clients, change the client IP +address in the config file to be different on each client.

+
scp dragon@IP_FROM_YOUR_SERVER:/home/dragon/wireguard-client.conf $HOME/cloud-in-a-box.conf
+

Install wireguard on your workstation, if you have not done this before. For instructions how to do +it on your workstation, please have a look on the documentation of your used distribution. The +wireguard documentation you will find here.

+

Start the wireguard tunnel.

+
sudo wg-quick up $HOME/cloud-in-a-box.conf
+

Webinterfaces

+

If you want to access the services please choose the URL from the following list:

+
NameURLUsernamePasswordNote
ARAhttps://ara.services.in-a-box.cloudarapassword
Cephhttp://manager.systems.in-a-box.cloud:7000adminpassword
Flowerhttps://flower.services.in-a-box.cloud--
Grafanahttps://api.in-a-box.cloud:3000adminpassword
HAProxyhttp://manager.systems.in-a-box.cloud:1984openstackpassword
Homerhttps://homer.services.in-a-box.cloud--
Horizon - admin projecthttps://api.in-a-box.cloudadminpassworddomain: default
Horizon - test projecthttps://api.in-a-box.cloudtesttestdomain: test
Netboxhttps://netbox.services.in-a-box.cloudadminpassword
Netdatahttp://manager.systems.in-a-box.cloud:19999--
OpenSearch Dashboardshttps://api.in-a-box.cloud:5601opensearchpassword
PhpMyAdminhttps://phpmyadmin.services.in-a-box.cloudrootpasswordStarting with OSISM 7, root_shard_0 is used as the user name
RabbitMQhttps://api.in-a-box.cloud:15672openstackpassword
Skyline - admin projecthttps://api.in-a-box.cloud:9999adminpassword
Skyline - test projecthttps://api.in-a-box.cloud:9999testtest
+

Command-line interfaces

+

Login to Cloud in a Box as described in step 8 of the installation chapter.

+
    +
  • Select one of the preconfigured environments: +
      +
    • system
    • +
    • admin
    • +
    • test
    • +
    +
  • +
  • Set the environment by exporting the environment variable: OS_CLOUD: +
    export OS_CLOUD=admin
    +
  • +
  • Use OpenStack CLI via the command openstack. +
    openstack availability zone list
    openstack image list
    openstack server list # After installation there are no servers
    +
  • +
+

Import of additional images

+

The OpenStack Image Manager is used to manage images. +In the example, the Garden Linux image is imported.

+
osism manage images --cloud=admin --filter 'Garden Linux'
+

All available images can be found in the osism/openstack-image-manager repository.

+

Upgrade

+

It is best to execute the commands within a screen session, it takes some time. Please note +that you cannot update the Ceph deployment at the moment. This will be enabled in the future.

+
osism apply configuration
/opt/configuration/upgrade.sh
docker system prune -a
+

Customisations

+

Use of 2nd NIC for external network

+

In the default configuration, the Cloud in a Box is built in such a way that an internal +VLAN101 is used as an simulated external network and this is made usable via the 1st network +interface using masquerading. This makes it possible for instances running on the Cloud +in a Box to reach the internet. The disadvantage of this is that the instances themselves +can only be reached via floating IP addresses from the Cloud in a Box system itself or +via the Wireguard tunnel. Especially in edge environments, however, one would usually like +to have this differently and the instances should be directly accessible via the local +network.

+

To make this work, first identify the name of a 2nd network card to be used.

+
dragon@manager:~$ sudo lshw -class network -short
H/W path Device Class Description
============================================================
/0/100/2.2/0 eno7 network Ethernet Connection X552 10 GbE SFP+
/0/100/2.2/0.1 eno8 network Ethernet Connection X552 10 GbE SFP+
/0/100/1c/0 eno1 network I210 Gigabit Network Connection
/0/100/1c.1/0 eno2 network I210 Gigabit Network Connection
/0/100/1c.4/0 eno3 network I350 Gigabit Network Connection
/0/100/1c.4/0.1 eno4 network I350 Gigabit Network Connection
/0/100/1c.4/0.2 eno5 network I350 Gigabit Network Connection
/0/100/1c.4/0.3 eno6 network I350 Gigabit Network Connection
+

In the following we use eno7. Activate the device manually with sudo ip link set up dev eno7. +Then check that a link is actually present.

+
dragon@manager:~$ ethtool eno7
Settings for eno7:
Supported ports: [ FIBRE ]
Supported link modes: 10000baseT/Full
[...]
Link detected: yes
+

Now this device is made permanently known in the network configuration. Select the MTU +accordingly. For 1 GBit rather 1500 than 9100. The 2nd network interface should be +configured without IP configuration (neither static nor DHCP).

+
    +
  • /opt/configuration/inventory/group_vars/generic/network.yml
  • +
  • /opt/configuration/environments/manager/group_vars/manager.yml
  • +
+
network_ethernets:
eno1:
dhcp4: true
eno7:
mtu: 9100
+

Then, this change is deployed and applied.

+
osism apply network
sudo netplan apply
+

Now the configuration for Neutron and OVN is prepared. network_workload_interface +is expanded by the 2nd network interface. The order is not random, first vlan101 +then eno7. neutron_bridge_name is added.

+
    +
  • /opt/configuration/inventory/group_vars/generic/network.yml
  • +
  • /opt/configuration/environments/manager/group_vars/manager.yml
  • +
+
network_workload_interface: "vlan101,eno7"
neutron_bridge_name: "br-ex,br-add"
+

Then, this change is deployed.

+
osism reconciler sync
osism apply openvswitch
osism apply ovn
osism apply neutron
+

Now segments and/or subnets can be configured. In this case, eno7 is configured as an +untagged port on the remote side.

+
    +
  • /opt/configuration/environments/openstack/playbook-additional-public-network.yml
  • +
+
- name: Create additional public network
hosts: localhost
connection: local

tasks:
- name: Create additional public network
openstack.cloud.network:
cloud: admin
state: present
name: public-add
external: true
provider_network_type: flat
provider_physical_network: physnet2

- name: Create additional public subnet
openstack.cloud.subnet:
cloud: admin
state: present
name: subnet-public-add
network_name: public-add
cidr: 192.168.23.0/24
enable_dhcp: false
allocation_pool_start: 192.168.23.100
allocation_pool_end: 192.168.23.200
gateway_ip: 192.168.23.1
dns_nameservers:
- 8.8.8.8
- 9.9.9.9
+

The additional public network can now be made known with +osism apply -e openstack additional-public-network.

+

There is now a 2nd floating IP address pool with the name public-add +available for use. If instances are to be started directly in this network, +enable_dhcp: true must be set. In this case, it should be clarified in +advance with the provider of the external network whether the use of DHCP +is permitted there.

+

Running on a Virtual Machine

+

The Cloud in a Box has been tested to run on a virtual machine. However, the Cloud in a Box is mainly made +for running on bare metal, the automated installation does not work, and other things may not work either.

+

Nested virtualization

+

You likely want to run virtual machines on top of your Cloud in a Box. +The host machine has to support and enabled nested virtualization.

+

To enable nested virtualization the CPU configuration of the VM has to be host-passthrough or host-model

+ +

The linked guide can be used in other distributions as well.

+

Disk space saving

+

When using Cloud in a Box in a VM, you can utilize the qcow2 disk image or similar technology to save space. +In that case, the base installation requires just around 70 GB instead of a full 1 TB. +(The drive still needs to be made with a capacity of at least 1TB; however, the actual disk space usage is lower.)

+

Also in case you want to experiment a bit more and "hack around" using the manual installation +you can make disk snapshots when turned off after the Ubuntu installs, bootstrap.sh and deploy.sh to speed up your +progress.

+

If you use qemu, you can use following command to do snapshots.

+
sudo virsh snapshot-create-as --domain cib bootstrap "run of bootstrap.sh" --disk-only --diskspec sda,snapshot=external,file=/var/lib/libvirt/images/ub2022_cib_boostrap.qcow2 --atomic
+

QEMU guest agent

+

When running inside QEMU, it may be worth it to install the QEMU guest agent.

+
sudo apt -y install qemu-guest-agent
sudo systemctl enable qemu-guest-agent
sudo systemctl start qemu-guest-agent
+

Troubleshooting

+

Broken disk setup

+

This error means that your disk setup is broken. Use cfdisk and delete all partitions on +the system on which you want to install the Cloud in a Box image.

+

With lsblk you can verify if the partitions are empty.

+

Development

+

For the further development of the scripts and the mechanisms of the Cloud in a Box, +you need to know the following.

+
    +
  • The operating system is brought onto the node via an automatic Ubuntu installation +that uses cloud-init
  • +
  • The installation starts the script init.sh which performs +an initial clone of the osism/cloud-in-a-box repository and a checkout of +the main branch. It also executes the deploy.sh and +bootstrap.sh scripts.
  • +
  • The installation persists the kernel parameters of the initial boot to the file /etc/.initial-kernel-commandline
  • +
  • The status and activities of the deployment are logged in /var/log/install-cloud-in-a-box.log. For proper colors use less -r. +Search for OVERALL STATUS to find the result of the specific installation steps.
  • +
  • Branch and location of the osism/cloud-in-a-box repository can be overriden +by setting the kernel parameters ciab_repo_url (a public repository address without authentication) and ciab_branch +(a name of a branch, use only ASCII chars, -, and _).
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/contributor-guide/index.html b/docs/iaas/guides/other-guides/contributor-guide/index.html new file mode 100644 index 0000000000..12c2660a33 --- /dev/null +++ b/docs/iaas/guides/other-guides/contributor-guide/index.html @@ -0,0 +1,33 @@ + + + + + +Contributor Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Contributor Guide

+

We welcome any issues, change requests or general feedback. Do not hestiate to open an issue.

+

We use GitHub Issues to capture feature requests, feedback, bugs, etc. The tracker is available in the +osism/issues repository. There are no specific requirements for the creation of an issue. +Error cases should be described in such a way that they are directly reproducible. The more outputs there are, +the better.

+

We use GitHub pull requests for contributions. The use of pull requets is documented in the +official GitHub documentation. +The process in detail for the creation of a fork, branch etc. is also documented in the +official GitHub documentation. +It is recommended to use the GitHub CLI. Makes many steps easier.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/developer-guide/index.html b/docs/iaas/guides/other-guides/developer-guide/index.html new file mode 100644 index 0000000000..2ea72769a3 --- /dev/null +++ b/docs/iaas/guides/other-guides/developer-guide/index.html @@ -0,0 +1,38 @@ + + + + + +Developer Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Developer Guide

+

How to add a new service

+

If you want to add a new service to OSISM, this is done via an Ansible role and (most often) +a container image. The following steps are necessary and are demonstrated using the example +of osism.services.cgit.

+
DescriptionExample
Add the Ansible role in one of the Ansible collection repositorieshttps://github.com/osism/ansible-collection-services/pull/578/files
Add the Ansible playbookhttps://github.com/osism/ansible-playbooks/pull/215/files
Add the Ansible inventory grouphttps://github.com/osism/cfg-generics/pull/225/files
Add the used container image(s) to the release repositoryhttps://github.com/osism/release/pull/278/files
Add the container images(s) to osism-ansible container imagehttps://github.com/osism/container-image-osism-ansible/pull/215/files
Add the container image registry/registries and host(s) to the defaults repositoryhttps://github.com/osism/defaults/pull/54/files
Add a sample deployment to the testbedhttps://github.com/osism/testbed/pull/1043/files
+

How to add a new container image

+

If required, add a new container image in the osism/container-images +repository. The example here is from the osism.services.keycloak role: https://github.com/osism/container-images/pull/34/files.

+

Whenever possible, upstream container images should be used. If only minor customizations are necessary, +always work with overlay container images based on upstream container images.

+

How service deployment works

+

Docker

+

Service deployment with Docker

+

Kubernetes

+

Service deployment with Kubernetes

+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/developer-guide/releases/index.html b/docs/iaas/guides/other-guides/developer-guide/releases/index.html new file mode 100644 index 0000000000..ae32b900ac --- /dev/null +++ b/docs/iaas/guides/other-guides/developer-guide/releases/index.html @@ -0,0 +1,165 @@ + + + + + +Releases | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Releases

+

How we handle releases

+

Currently we do a major release every 6 months. Minor releases we do when +needed and about every 2 weeks.

+

In a minor release, only updates, bug fixes, etc. take place. There are also +no major upgrades of included components such as OpenStack, Keycloak or Ceph +in a minor release.

+

It is possible to jump from any minor version within a major version to higher +minor versions without any intervention.

+

Deprecations, removals, etc. take place in a major release. New mandatory +features are also added in a major release. Upgrades of the included components +can also take place during a major release (e.g. OpenStack Xena -> OpenStack Yoga).

+

It is possible to jump from the previous major version to the next major version. +It may be that manual intervention is necessary. For example, configuration +parameters may need to be added or services that no longer exist may need to be +removed.

+

How to make a release

+
    +
  1. +

    On all repositories that are used, check that the versions to be used have an +appropriate version tag (e.g. v0.20230308.0).

    +
    osism/ansible-collection-commons
    osism/ansible-collection-services
    osism/ansible-collection-validations
    osism/ansible-defaults
    osism/ansible-playbooks
    osism/ansible-playbooks-manager
    osism/cf-generics
    osism/kolla-operations
    osism/python-osism
    +
  2. +
  3. +

    Copy the latest directory. The release to be created is used as the new name.

    +
    latest -> 6.0.0b
    +
  4. +
  5. +

    Remove all # renovate lines from the base.yml file.

    +
  6. +
  7. +

    Remove all Ceph and OpenStack releases that should not be part of the pre-release. +There is only one OpenStack version and one Ceph version per (pre-)release.

    +
  8. +
  9. +

    Ensure that the symlinks openstack.yml and ceph.yml point to the releases +to be used in this pre-release.

    +
    base.yml
    ceph-pacific.yml
    ceph.yml -> ceph-pacific.yml
    openstack-zed.yml
    openstack.yml -> openstack-zed.yml
    +
  10. +
  11. +

    Run src/prepare-release.py.

    +
    RELEASE=6.0.0b python3 src/prepare-release.py
    +
  12. +
  13. +

    Do the steps from the Stable release starting from the 4th step.

    +
  14. +
+

Stable release

+
    +
  1. +

    Copy the directory of the last pre-release or the previous stable release. +The release to be created is used as the new name.

    +
    5.0.0a -> 5.0.0b
    5.0.0b -> 5.0.0
    5.0.0 -> 5.1.0
    5.1.0 -> 5.2.0
    5.2.0 -> 5.3.0
    +
  2. +
  3. +

    Change all necessary versions in the YAML files within the new directory. +In any case, the version of the pre-release or the version of the stable +release must be replaced by the release to be created.

    +
  4. +
  5. +

    The release to be created is submitted as a pull request as usual and then +merged.

    +
  6. +
  7. +

    Add a tag with the name of the new release to the listed repositories.

    +
    osism/container-image-ceph-ansible
    osism/container-image-inventory-reconciler
    osism/container-image-osism-ansible
    osism/container-images-kolla
    +
  8. +
  9. +

    After completing the creation of the images in repository container-images-kolla, +the file images.yml must be added to repository osism/sbom as +5.0.0/openstack.yml (instead of 5.0.0, the corresponding release is used). +The file is available as a build artefact of the Release container images action +on the created tag.

    +

    Before the file is added, it is enhanced with the checksums of the images. The script +is available in the osism/sbom repository.

    +
    VERSION=5.0.0 python3 scripts/add-image-checksum.py
    +
  10. +
  11. +

    If 5.0.0/openstack.yml is present in osism/sbom, repository +osism/container-image-kolla-ansible can be tagged like the other +repositories before.

    +
  12. +
  13. +

    Add the created SPDX files from the listed repositories to the osism/sbom repository. +The file are available as build artefacts of the Build container image action +on the created tags.

    +
    osism/container-image-ceph-ansible
    osism/container-image-kolla-ansible
    osism/container-image-osism-ansible
    +
  14. +
  15. +

    Add and run temporary CI jobs in osism/testbed that uses the pre-release.

    +
    - job:
    name: testbed-deploy-stable-next
    parent: testbed-deploy
    vars:
    manager_version: "5.0.0a"
    refstack: true
    nodeset: testbed-orchestrator

    - job:
    name: testbed-upgrade-stable-next
    parent: testbed-deploy
    vars:
    manager_version: "4.2.0"
    manager_version_next: "5.0.0a"
    nodeset: testbed-orchestrator
    +
  16. +
  17. +

    Test. Test. Test.

    +
  18. +
  19. +

    Prepare a PR to change the stable version to the new stable version in the following Zuul jobs +in the osism/testbed repository. All tests there must pass successfully before the tag is +set on this repository in the next step. The temporary CI jobs (step 8) are removed again with +this PR.

    +
    testbed-deploy-stable
    testbed-update-stable
    testbed-update-stable
    testbed-upgrade-stable
    +
  20. +
  21. +

    Add a new release notes file to doc/sorce/notes. Generate the versions table with the +help of the release-table.py script in the osism/sbom repository.

    +
  22. +
  23. +

    After all known issues are documented, a corresponding tag, e.g. 5.0.0, is set on the +osism/release repository.

    +
  24. +
  25. +

    Create a GitHub release with the new tag on the +osism/release repository. The release is +now public available.

    +
  26. +
  27. +

    As the last of the release process, the previously prepared PR is merged on the +osism/testbed repository to change the stable version.

    +
  28. +
+

How we write release notes

+

We use Reno to manage the release notes.

+

Installation

+

Reno is provided as a Python package and can be installed with pip.

+
pip3 install reno
+

Usage

+

For each change in a repository, a release note is created with Reno. +Something meaningful is used as the name for the note. For example, if the +requirements file for Ansible is removed, remove-ansible-requirements is a good name.

+
$ reno new remove-ansible-requirements
no configuration file in: ./releasenotes/config.yaml, ./reno.yaml
Created new notes file in releasenotes/notes/remove-ansible-requirements-6c6eba43f616bc6b.yaml
+

The created file contains prepared entries for several categories. It is described briefly +in each instance which contents belong in which category. What is not needed is deleted.

+
prelude: >
Replace this text with content to appear at the top of the section for this
release. All of the prelude content is merged together and then rendered
separately from the items listed in other parts of the file, so the text
needs to be worded so that both the prelude and the other items make sense
when read independently. This may mean repeating some details. Not every
release note requires a prelude. Usually only notes describing major
features or adding release theme details should have a prelude.
features:
- |
List new features here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
issues:
- |
List known issues here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
upgrade:
- |
List upgrade notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
deprecations:
- |
List deprecations notes here, or remove this section. All of the list
items in this section are combined when the release notes are rendered, so
the text needs to be worded so that it does not depend on any information
only available in another section, such as the prelude. This may mean
repeating some details.
critical:
- |
Add critical notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
security:
- |
Add security notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
fixes:
- |
Add normal bug fixes here, or remove this section. All of the list items
in this section are combined when the release notes are rendered, so the
text needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
other:
- |
Add other notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
+

Example

+

Here is an example of a commit from the osism/cfg-generics repository.

+
---
features:
- |
The `requirements.yml` has been removed. The version will be set in the `run.sh`
script for the seed process in the future exactly as later in the update process
via the parameters `ANSIBLE_COLLECTION_SERVICES_VERSION` and
`ANSIBLE_PLAYBOOKS_MANAGER_VERSION`.
upgrade:
- |
In existing configuration repositories, the `environments/manager/requirements.yml`
file can be removed after the generics have been synced.
+

Repositories without release notes

+

We do not create release notes in the following repositories:

+
    +
  • osism/github-manager
  • +
  • osism/osism.github.io
  • +
  • osism/release
  • +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/developer-guide/scripts/index.html b/docs/iaas/guides/other-guides/developer-guide/scripts/index.html new file mode 100644 index 0000000000..31501bb3a2 --- /dev/null +++ b/docs/iaas/guides/other-guides/developer-guide/scripts/index.html @@ -0,0 +1,78 @@ + + + + + +Scripts | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Scripts

+

Scripts are included in container images to simplify development work and to enable +testing and hotfixes in running environments. What scripts are available and how to +use them is described in this chapter.

+

The change.sh script may be used to update repositories to development branches. Different +targets may be passed as a first parameter and existing branch names as a second. The availability +of targets depends on the container it is run in.

+ +

In this example, the main branch of osism/ansible-collection-services +is used in the osism-ansible container.

+
docker exec -u root -it osism-ansible /change.sh services main
+

The respective container should always be restarted after a change.

+
docker restart osism-ansible
+

If something has been changed in the defaults and is to be tested, this must be +changed in the inventory reconciler service. Regardless of which of the Ansible services +the customised defaults are intended for.

+
docker exec -u root -it manager-inventory_reconciler-1 /change.sh defaults main
docker restart manager-inventory_reconciler-1
+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/developer-guide/zuul/index.html b/docs/iaas/guides/other-guides/developer-guide/zuul/index.html new file mode 100644 index 0000000000..82f43bf448 --- /dev/null +++ b/docs/iaas/guides/other-guides/developer-guide/zuul/index.html @@ -0,0 +1,137 @@ + + + + + +Zuul CI | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Zuul CI

+
note

We use Zuul CI as a CI service for OSISM. The service is not required for +the use of OSISM itself. However, as we deploy and provide Zuul CI ourselves, +the documentation for this is also included in the OSISM Developer Guide.

Our Zuul CI instance is available at +zuul.services.betacloud.xyz.

+

osism.services.zuul is the Ansible role to set up Zuul CI as a single-node +installation with Docker Compose.

+

The zuul label

+

On CI jobs that consume a lot of resources and have long runtimes we use a label +zuul to run these jobs.

+

These CI jobs run in the label pipeline +and are only started once after the label has been assigned. If changes are made +to a PR, the label must first be removed and then reassigned for a new run of the +CI jobs.

+

The zuul label is usable in the following repositories:

+ +

Installation

+

Server preparation

+

Set up a server (VM) with Ubuntu Server 22.04 LTS and make +sure that these packages are installed:

+
    +
  • docker.io
  • +
  • docker-compose
  • +
  • python3-docker
  • +
  • python3-openstackclient
  • +
+

Also configure your deploy user to be in the docker group and set up the +account for the zuul user. TCP-Ports 80 and 443 should be accessible +from the internet, port 22 for management via SSH will also often be +useful, but not required.

+

If you have an OpenStack tenant where you want to deploy the Zuul +server, you can download and adapt this example +playbook:

+
---
- name: Setup zuul server
hosts: localhost
vars:
cloud: mycloud
flavor: myflavor
image: Ubuntu 22.04
keypair: mykeypair
network: myprivatenet
project: myproject
zuul_domain: mydomain.xyz.
zuul_fqdn: "zuul01.services.{{ zuul_domain }}"
zuul_host: zuul01

tasks:
- name: Create security group
openstack.cloud.security_group:
cloud: "{{ cloud }}"
name: "{{ project }}-zuul"
description: "Default security group for {{ project }}-zuul"

- name: Create security group rule (icmp)
openstack.cloud.security_group_rule:
cloud: "{{ cloud }}"
security_group: "{{ project }}-zuul"
protocol: icmp
remote_ip_prefix: 0.0.0.0/0

- name: Create security group rules (tcp)
openstack.cloud.security_group_rule:
cloud: "{{ cloud }}"
security_group: "{{ project }}-zuul"
protocol: tcp
remote_ip_prefix: 0.0.0.0/0
port_range_min: "{{ item }}"
port_range_max: "{{ item }}"
loop:
- 22
- 80
- 443

- name: Create zuul server
openstack.cloud.server:
cloud: "{{ cloud }}"
flavor: "{{ flavor }}"
image: "{{ image }}"
key_name: "{{ keypair }}"
name: "{{ zuul_host }}"
network: "{{ network }}"
security_groups:
- default
- "{{ project }}-zuul"
meta:
hostname: "{{ zuul_host }}"
register: zuul_server

- name: Add host
ansible.builtin.add_host:
name: "{{ zuul_server.openstack.accessIPv4 }}"
groups: zuul
ansible_user: ubuntu

- name: Initialize zuul server
hosts: zuul
gather_facts: false
vars:
zuul_user: zuul

tasks:
- name: Wait for system to become reachable
ansible.builtin.wait_for_connection:

- name: Update all packages
ansible.builtin.apt:
update_cache: true
name: '*'
state: latest
become: true

- name: Install required packages
ansible.builtin.apt:
name:
- docker.io
- docker-compose
- python3-docker
- python3-openstackclient
become: true

- name: Add user to docker group
ansible.builtin.user:
name: "{{ ansible_ssh_user }}"
groups: docker
append: true
become: true

- name: Add group
ansible.builtin.group:
name: "{{ zuul_user }}"
become: true

- name: Add user
ansible.builtin.user:
name: "{{ zuul_user }}"
uid: 10001
shell: /bin/bash
group: "{{ zuul_user }}"
groups: sudo
append: true
home: "/home/{{ zuul_user }}"
become: true
+

Define secrets

+

There need to be some secrets handed to the deployment, the suggested +method is to have a dedicated file that contains them, which will be +included in the example playbook below via a vars_files statement. +This allows you to easily protect all your secrets by applying +ansible-vault encrypt to that file. The contents of this file should +look like:

+
---
zuul_auth_secret: secret used for zuul web auth
webhook_token: token defined for github webhooks
db_user_pass: DB password for the zuul user
db_root_pass: DB root password
+

In addition you need to prepare some further data that needs to be +placed into a files directory in order to be consumed by the zuul +role. These are:

+
    +
  1. A clouds.yaml file for nodepool. This will be used by +nodepool-builder to upload the newly created images and by +nodepool-launcher to start instances running these images, these +will then be handed over to Zuul as CI nodes.
  2. +
  3. An SSH private key in the file nodepool and the matching public +key in nodepool.pub. These will be used by nodepool and zuul to +access the CI nodes via SSH.
  4. +
  5. An SSL private key and certificate pasted together in a file +named server.crt. This file will be used in the https setup by +the webserver. The certificate should cover both zuul_webserver_fqdn +and zuul_logserver_fqdn.
  6. +
+

Github App setup

+

In order for zuul to be able to interact with repositories hosted on +github, you need to set up a github application. Follow the instructions +at https://zuul-ci.org/docs/zuul/latest/drivers/github.html#application +to do this. The webhook token to use is the one defined in the +pervious section. Use github in place of <connection-name> for the +Webhook URL in the app configuration. After the app has been created, +place the PEM files that you downloaded into a +directory named pem-files:

+
$ mkdir -p pem-files
$ cp ~/Downloads/my-org-zuul.*.private-key.pem pem-files/my-org-zuul.pem
+

Now add the information about your github app to vars.yml:

+
github_app_id: 000000
github_pem_name: my-org-zuul
+

Example Playbook

+

Save this file as main.yaml:

+
---
- name: Set up zuul
hosts: zuul.example.com
vars_files:
- vars.yml
pre_tasks:
- name: Create /etc/openstack/
ansible.builtin.file:
state: directory
path: /etc/openstack
owner: root
group: root
mode: 0755
become: true

- name: Deploy clouds.yaml file
ansible.builtin.copy:
src: clouds.yaml
dest: /etc/openstack/clouds.yaml
owner: root
group: zuul
mode: '0640'
become: true

- name: Create keypair in the cloud
openstack.cloud.keypair:
cloud: osism-ci
name: osism-zuul
public_key: "{{ lookup('file', 'nodepool.pub') }}"
become: true

roles:
- name: Execute zuul role
role: zuul
vars:
zuul_connections:
github:
driver: github
webhook_token: "{{ webhook_token }}"
app_id: "{{ github_app_id }}"
app_key: "/etc/zuul/pem-files/{{ github_pem_name }}.pem"
opendevorg:
name: opendev
driver: git
baseurl: https://opendev.org
zuul_tenants:
- tenant:
name: my-tenant-name
source:
opendevorg:
untrusted-projects:
- zuul/zuul-jobs:
include:
- job
github:
config-projects:
- my-org/zuul_demo_config:
load-branch: main
untrusted-projects:
- my-org/zuul_demo_repo
become: true
+

Create an inventory file containing the login information for your zuul +server, it might look like:

+
zuul.example.com ansible_host=192.0.2.2 ansible_user=ubuntu
+

Then you can deploy your zuul server by running:

+
ansible-playbook -i inventory main.yaml
+

This will deploy a simple zuul setup with sample example repos being +referenced. You can fork the example repos from the +https://github.com/osism tenant or just use them as a guide for how +to build your own.

+

For further information about how to tune this setup for +you specific environment, have a look at the sections covering +nodepool and tenant configuration.

+

Troubleshooting

+

Your git repos are not displayed?

+

Have you thought of naming your repos with the prefix of your organization? release should be osism/release for example.

+

Your git repos are using the wrong branch?

+

For config-projects you set this value in the tenant-configuration with the load-branch stanza. +For untrusted-projects you set this value in the config-projects project sections AND in EVERY untrusted-project. +Each project section needs to have the default-branch stanza.

+

Your logs are not displayed in the web-UI?

+

Check, if the IP of the logfile server is really correct. In combination with GitHub there is a +bug which keeps the GitHub App posting to the old IP even if the webhook IP was changed. Current +workaround: Delete the old GitHub App and create a new one.

+

Hanging jobs in a pipeline?

+

Sometimes jobs get stuck in a pipeline and are never scheduled. They must then be removed manually +so that they do not block other jobs.

+

Hanging jobs in a pipeline

+

First create a local .zuul.conf configuration file in your home directory.

+
+

[osism] +url=https://zuul.services.betacloud.xyz/ +auth_token=TOKEN +tenant=osism

+

The required auth token can be generated on the Zuul control node with the `zuul-admin` client.

+

docker exec -it zuul_scheduler zuul-admin create-auth-token --user USER --tenant osism --expires-in 3600 --auth-config zuul_operator

+

With the [zuul-client](https://zuul-ci.org/docs/zuul-client/index.html) it is possible to
remove the two hanging jobs from the screenshot.

+

zuul-client --use-config osism dequeue --pipeline periodic-daily --project osism/k8s-capi-images --ref refs/heads/main +zuul-client --use-config osism dequeue --pipeline periodic-daily --project osism/cfg-generics --ref refs/heads/main

+

## Important daily CI jobs

* [osism/container-image-ceph-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-ceph-ansible&pipeline=periodic-daily&skip=0)
* [osism/container-image-kolla-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-kolla-ansible&pipeline=periodic-daily&skip=0)
* [osism/container-image-osism-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-osism-ansible&pipeline=periodic-daily&skip=0)
* [osism/container-images-kolla](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-images-kolla&pipeline=periodic-midnight&skip=0)
* [osism/testbed](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Ftestbed&pipeline=periodic-daily&skip=0)
+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/index.html b/docs/iaas/guides/other-guides/index.html new file mode 100644 index 0000000000..c4d8074eab --- /dev/null +++ b/docs/iaas/guides/other-guides/index.html @@ -0,0 +1,23 @@ + + + + + +Other Guides | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/style-guide/index.html b/docs/iaas/guides/other-guides/style-guide/index.html new file mode 100644 index 0000000000..bfb6a69b5d --- /dev/null +++ b/docs/iaas/guides/other-guides/style-guide/index.html @@ -0,0 +1,79 @@ + + + + + +Style Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Style Guide

+

Ansible

+

We implement all the default rules of Ansible Lint. All default rules can be found in the +Ansible Lint documentation.

+

Task names

+
    +
  • Tasks must always have names. The only exception allowed is for forked playbooks.
  • +
  • A name never starts with a small letter
  • +
  • Names are written in present tense
  • +
  • No punctuation is used in names
  • +
+

become directive

+

The become directive is only set when needed and is always set explicitly for each task that needs it.

+

Blocks, roles, or playbooks are never executed in a privileged mode.

+

We always insert the become directive between the name of a task and the task itself. This also applies +to related directives like become_user or become_flags. This is for better visibility if a task is +privileged or not.

+
- name: Copy hddtemp configuration file
become: true
ansible.builtin.copy:
src: "{{ ansible_os_family }}/hddtemp"
dest: "{{ hddtemp_conf_file }}"
owner: root
group: root
mode: 0644
notify: Restart hddtemp service
+

when directive

+

If you need to use the when directive add this at the end-section from the task where it is needed. This +makes the code easier to understand for others.

+
- name: "Archive existing {{ resolvconf_file }} file"
become: true
ansible.posix.synchronize:
src: "/etc/resolv.conf"
dest: "/etc/resolv.conf.{{ ansible_date_time.date }}"
archive: true
delegate_to: "{{ inventory_hostname }}"
when: stat_resolvconf_file.stat.islnk is defined and not stat_resolvconf_file.stat.islnk
+

Lists as defaults

+

Defaults that provide a list are always defined as in the following example.

+

docker_hosts_defaults sets the defaults in the role. Overriding is only possible with the defaults repository.

+

In the configuration repository, docker_hosts_extra is then used to add additional items to the list.

+

docker_hosts itself is never modified from the outside.

+
docker_hosts_defaults:
- "unix:///var/run/docker.sock"
docker_hosts_extra: []
docker_hosts: "{{ docker_hosts_defaults + docker_hosts_extra }}"
+

Containerfiles

+

Commit messages

+

Python

+

Black is a popular Python code formatter that automatically +formats your code to adhere to a consistent style. We use it to automatically format the +syntax of Python. A job is running in the CI that checks, if Black has been applied. Therefore, +format the files with Black accordingly in advance.

+

Installation

+

pip install black

+

Formatting a Single File

+

black myfile.py

+

Formatting Multiple Files and/or directories

+

black file1.py file2.py dir/

+

Formatting an Entire Project

+

This command will format all Python files in the current directory and its subdirectories:

+

black .

+

Check Mode (Dry Run)

+

Running Black with the --check option performs a dry run and reports files that would be +changed without actually modifying them:

+

black --check myfile.py

+

Excluding Files or Directories

+

You can exclude files or directories from formatting using the --exclude option:

+

black --exclude=dir_to_exclude/ .

+

Integration with Code Editors

+

Many code editors have extensions or plugins that can automatically run Black on your code. +For example, if you're using VSCode or PyCharm, you can easily integrate it into your IDE.

+

Example of failed python-black Zuul job

+

job-output.txt:

+
[…]
2023-11-16 14:38:14.149756 | TASK [python-black : Install pip module black]
2023-11-16 14:38:18.717886 | ubuntu-jammy | changed
2023-11-16 14:38:18.723062 |
2023-11-16 14:38:18.723137 | TASK [python-black : Format code with Black if there is nothing to exclude]
2023-11-16 14:38:19.138060 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/adminer.py
2023-11-16 14:38:19.151965 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/bird.py
2023-11-16 14:38:19.163608 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/auditd.py
2023-11-16 14:38:19.187772 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cephclient/package.py
2023-11-16 14:38:19.192695 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cephclient/container.py
2023-11-16 14:38:19.219694 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cgit.py
2023-11-16 14:38:19.230577 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/dnsdist.py
2023-11-16 14:38:19.275681 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/hddtemp/redhat.py
2023-11-16 14:38:19.300350 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/homer.py
2023-11-16 14:38:19.310641 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/lldpd.py
2023-11-16 14:38:19.318096 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/docker.py
2023-11-16 14:38:19.329099 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/osquery.py
2023-11-16 14:38:19.344766 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/rsyslog.py
2023-11-16 14:38:19.358190 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/smartd.py
2023-11-16 14:38:19.363578 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/tuned.py
2023-11-16 14:38:19.389205 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/util/util.py
2023-11-16 14:38:19.406360 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_container_facts.py
2023-11-16 14:38:19.415046 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/filter/address.py
2023-11-16 14:38:19.473508 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_toolbox.py
2023-11-16 14:38:19.908963 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_docker.py
2023-11-16 14:38:19.914395 | ubuntu-jammy |
2023-11-16 14:38:19.914412 | ubuntu-jammy | Oh no! 💥 💔 💥
2023-11-16 14:38:19.914419 | ubuntu-jammy | 20 files would be reformatted, 18 files would be left unchanged.
2023-11-16 14:38:20.249358 | ubuntu-jammy | ERROR
2023-11-16 14:38:20.249501 | ubuntu-jammy | {
2023-11-16 14:38:20.249533 | ubuntu-jammy | "delta": "0:00:01.053565",
2023-11-16 14:38:20.249553 | ubuntu-jammy | "end": "2023-11-16 14:38:19.932073",
2023-11-16 14:38:20.249571 | ubuntu-jammy | "msg": "non-zero return code",
2023-11-16 14:38:20.249587 | ubuntu-jammy | "rc": 1,
2023-11-16 14:38:20.249603 | ubuntu-jammy | "start": "2023-11-16 14:38:18.878508"
2023-11-16 14:38:20.249618 | ubuntu-jammy | }
[…]
+ + \ No newline at end of file diff --git a/docs/iaas/guides/other-guides/testbed/index.html b/docs/iaas/guides/other-guides/testbed/index.html new file mode 100644 index 0000000000..60d5bf4ff4 --- /dev/null +++ b/docs/iaas/guides/other-guides/testbed/index.html @@ -0,0 +1,366 @@ + + + + + +Testbed | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Testbed

+

With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack +deployment on an existing OpenStack environment such as Cleura or REGIO.cloud.

+

OSISM is the reference implementation for the Infrastructure as a Service (IaaS) layer in the +Sovereign Cloud Stack (SCS) project. The OSISM Testbed is therefore +used in the SCS project to test and work on the Instrastructure as a Service layer.

+

The OSISM Testbed is intended as a playground. Further services and integration will +be added over time. A increasing number of best practices and experiences from the productive +deployments will be included here in the future. It will become more production-like +over time. However, at no point does it claim to represent a production setup exactly.

+

Requirements

+

Cloud access

+

The usual prerequisite is to have an account on one of the supported OpenStack cloud providers. +As the OSISM Testbed also virtualizes systems itself, the OpenStack cluster should provide +the capabilities for nested virtualization.

+

It is not part of this guide to describe the registration with the individual cloud +providers. Please contact the respective cloud provider for this.

+
ProductProviderProfile nameNote
CleuraCleuracleura
Fuga CloudFUGAfuga
HuaweiCloudHuaweiCloudhuaweicloud
OVHOVHovh
OpenTelekomCloudT-Systemsotc
pluscloud openplusserverpluscloudopen
pluscloud SCS Testplusservergx-scs
REGIO.cloudOSISMregiocloud
REGIO.cloudOSISMregio-fastboot from NVMe SSD backed volumes
Wavestacknoris networkwavestack
+

For each cloud provider listed in the table, a predefined profile is available in the +terraform/environments directory. This profile contains the name of the public +network, which flavors to use, etc.

+

Here is an example from the profile for REGIO.cloud.

+
flavor_manager            = "SCS-4V-16-50"
flavor_node = "SCS-8V-32-50"
volume_type = "ssd"
image = "Ubuntu 22.04"
image_node = "Ubuntu 22.04"
public = "public"
availability_zone = "nova"
volume_availability_zone = "nova"
network_availability_zone = "nova"
+

Cloud resources

+

The OSISM Testbed requires at least the following project quota when using the default flavors:

+
QuantityResourceNote
4Instances28 VCPUs + 112 GByte RAM (3 modes, 1 manager)
9Volumes90 GByte volume storage
1Floating IP
1Keypair
3Security group
16Security group rules
1Network
1Subetwork
6Ports
1Router
+

Software

+
    +
  • make must be installed on the system
  • +
  • Wireguard or sshuttle must be installed on your system for VPN access
  • +
  • Python must be installed, the Python version used must be at least 3.10, otherwise +the current Ansible release cannot be used (details in the +Ansible support matrix)
  • +
  • python3-venv must be installed for managing Python dependencies like Ansible
  • +
+

Deployment

+

This section describes step by step how to deploy the OSISM Testbed.

+
    +
  1. +

    Request access from the administrator of the respective cloud or get access to an OpenStack cloud.

    +
  2. +
  3. +

    Clone the osism/testbed repository.

    +

    The repository can also be cloned to any other location.

    +
    mkdir -p ~/src/github.com/osism
    git clone https://github.com/osism/testbed ~/src/github.com/osism/testbed
    cd ~/src/github.com/osism/testbed
    +
  4. +
  5. +

    Configure your cloud access profile

    +

    The access data for the cloud provider used is stored in terraform/clouds.yaml and (optionally) +in terraform/secure.yaml (same structure, if you want to store credentials on a separate place).

    +

    In file terraform/clouds.yaml.sample +you will find examples of typical setups. Settings that are identical for all users of a cloud can be defined +centrally via the profiles of the file +terraform/clouds-public.yaml. +You can reference these settings by using the profile parameter in cloud-specific +definition in terraform/clouds.yaml.

    +

    The user specific settings of the clouds.yaml file are provided by the cloud provider. Please check the +documentation of the cloud provider you are using or their support for details.

    +

    REGIO.cloud is used as an example here. The cloud name in clouds.yaml +and the environment name (value of ENVIRONMENT) are regiocloud in this case. It is important that +the name of the cloud in clouds.yaml matches the name of the environment to be used. The names must +be identical. It is currently not possible to name the cloud regiocloud-123 in clouds.yaml if the +environment is regiocloud.

    +

    If another cloud is used, replace regiocloud with the respective profile name from the table above.

    +

    The use of application credentials is preferred. This way it is not necessary to store +details like username, project name or sensitive information like the password in the +clouds.yaml file.

    The application credentials can be found in Horizon under Identity. Use OSISM Testbed as +name and click Create Application Credential.

    terraform/clouds.yaml
    clouds:
    regiocloud:
    profile: regiocloud
    auth:
    application_credential_id: ID
    application_credential_secret: SECRET
    auth_type: "v3applicationcredential"

    If you want to make use of terraform/secure.yaml add your application credential secret there +instead of terraform/clouds.yaml.

    terraform/secure.yaml
    clouds:
    regiocloud:
    auth:
    application_credential_secret: SECRET
    +
  6. +
  7. +

    Prepare the deployment.

    +

    The versions of Ansible and OpenTofu are managed +automatically and necessary dependencies are cloned.

    +
    make prepare
    +

    If any error occurs during preparation and you want to run the preparation +again, it is important to run make wipe-local-install first. Otherwise the +preparation will not be redone completely and necessary parts will be missing +later on.

    +
  8. +
  9. +

    Create the infrastructure with OpenTofu.

    +
    make ENVIRONMENT=regiocloud create
    +
  10. +
  11. +

    Deploy the OSISM manager and bootstrap all nodes.

    +
    make ENVIRONMENT=regiocloud manager
    +
  12. +
  13. +

    After the bootstrap, you can log in to the manager via SSH.

    +
    make ENVIRONMENT=regiocloud login
    +

    Yo can log in to the nodes of the cluster via the manager.

    +
    osism console testbed-node-0
    +
  14. +
  15. +

    Deploy all services.

    +

    It is also possible to deploy the services step by step on the +manager. To do this, first log in to the manager with make ENVIRONMENT=regiocloud login +and then execute the deploy scripts one after the other. It is recommended to do this +within a screen session.

    Deploying the services takes some time and depends on how much bandwidth is available, +how the instances are equipped, etc. 90-120 minutes is not unusual when Ceph and OpenStack +are fully deployed.

    To speed up the Ansible playbooks, ARA can be disabled. This +is done by executing /opt/configuration/scripts/disable-ara.sh. Run this script before the deployment scripts. +Afterwards no more logs are available in the ARA web +interface. To re-enable ARA use /opt/configuration/scripts/enable-ara.sh.

    There is also the option of pre-population of images with /opt/configuration/scripts/pull-images.sh +so that deployments do not have to be lengthy. Run this script before the deployment scripts.

    /opt/configuration/scripts/deploy/001-helper-services.sh
    /opt/configuration/scripts/deploy/005-kubernetes.sh
    /opt/configuration/scripts/deploy/100-ceph-services-basic.sh
    /opt/configuration/scripts/deploy/200-infrastructure-services-basic.sh
    /opt/configuration/scripts/deploy/300-openstack-services-basic.sh
    /opt/configuration/scripts/deploy/400-monitoring-services.sh

    Prepare OpenStack resources like public network, flavors and images by running +/opt/configuration/scripts/bootstrap.sh. Run this script after the deployment scripts.

    info

    If you only want to deploy the monitoring services with /opt/configuration/scripts/deploy/400-monitoring-services.sh, +a few dependencies must be deployed first. You can then use the monitoring services without having to install a +complete OpenStack & Ceph environment.

    osism apply common
    osism apply loadbalancer
    osism apply opensearch
    osism apply mariadb
    +
  16. +
  17. +

    If you want to verify the deployment with refstack run +/opt/configuration/scripts/check.sh. This step will take some time and is optional.

    +
  18. +
  19. +

    The machine images required for the use of Kubernetes Cluster API and the amphora driver of OpenStack Octavia +service are not provided by default to save resources on the OSISM Testbed and improve deployment time. +These can be provisioned if required.

    +
    /opt/configuration/scripts/bootstrap/301-openstack-octavia-amhpora-image.sh
    /opt/configuration/scripts/bootstrap/302-openstack-k8s-clusterapi-images.sh
    +
  20. +
  21. +

    If you want you can create a test project with a test user after login. It also +creates an instance with a volume attached to a network with a router. This step is optional.

    +
    osism apply --environment openstack test
    +
  22. +
  23. +

    When the OSISM Testbed is no longer needed, it can be deleted.

    +
    make ENVIRONMENT=regiocloud clean
    +
  24. +
+

Usage

+

Deployment must be completed at this point.

+

Custom CA

+

The OSISM Testbed deployment currently uses hostnames in the domain testbed.osism.xyz. This is a real domain +and we provide the DNS records matching the addresses used in the OSISM Testbed, so that once you connect to your testbed via a direct +link or Wireguard, you can access hosts and servers by their hostname (e.g. ssh testbed-manager.testbed.osism.xyz).

+

We also provide a wildcard TLS certificate signed by a custom CA for testbed.osism.xyz and *.testbed.osism.xyz. +This CA is always used for each testbed. The CA is not regenerated and it is not planned to change this for the next 10 years.

+

In order for these certificates to be recognized locally as valid, the CA +environments/kolla/certificates/ca/testbed.crt +must be imported locally.

+

VPN access

+

Wireguard

+

Install wireguard on your workstation, if you have not done this before. For instructions how to do +it on your workstation, please have a look on the documentation of your used distribution. The +wireguard documentation you will find here.

+

Start the wireguard tunnel. +(Press CTRL+c to keep the tunnel running forever. The make target also launches a browser tab with references to all services)

+
make vpn-wireguard ENVIRONMENT=regiocloud
+

If you want to connect to the OSISM Testbed from multiple clients, change the client IP +address in the downloaded configuration file to be different on each client.

+

If you only want to download the Wireguard configuration, you can use the vpn-wireguard-config +target. The configuration is then available in the file wg-testbed-regiocloud.conf, for example.

+
make vpn-wireguard-config ENVIRONMENT=regiocloud
+

sshuttle

+

If you do not want to use Wireguard you can also work with sshuttle.

+
make vpn-sshuttle ENVIRONMENT=regiocloud
killall sshuttle
+

Static entries in /etc/hosts

+

If you are unable to access the following domains, you can customize your local /etc/hosts +with the following static entries. This may be necessary, for example, if you use Pi-hole and +all DNS entries from a public DNS with a non-public IP address are filtered.

+
# OSISM Testbed hosts
192.168.16.5 ara.testbed.osism.xyz ara
192.168.16.5 cgit.testbed.osism.xyz cgit
192.168.16.5 flower.testbed.osism.xyz flower
192.168.16.5 homer.testbed.osism.xyz homer
192.168.16.5 netbox.testbed.osism.xyz netbox
192.168.16.5 testbed-manager.testbed.osism.xyz testbed-manager
192.168.16.5 nexus.testbed.osism.xyz nexus
192.168.16.5 phpmyadmin.testbed.osism.xyz phpmyadmin
192.168.16.9 api-int.testbed.osism.xyz api-int
192.168.16.10 testbed-node-0.testbed.osism.xyz testbed-node-0
192.168.16.11 testbed-node-1.testbed.osism.xyz testbed-node-1
192.168.16.12 testbed-node-2.testbed.osism.xyz testbed-node-2
192.168.16.13 testbed-node-3.testbed.osism.xyz testbed-node-3
192.168.16.14 testbed-node-4.testbed.osism.xyz testbed-node-4
192.168.16.15 testbed-node-5.testbed.osism.xyz testbed-node-5
192.168.16.16 testbed-node-6.testbed.osism.xyz testbed-node-6
192.168.16.17 testbed-node-7.testbed.osism.xyz testbed-node-7
192.168.16.18 testbed-node-8.testbed.osism.xyz testbed-node-8
192.168.16.19 testbed-node-9.testbed.osism.xyz testbed-node-9
192.168.16.100 keycloak.testbed.osism.xyz keycloak
192.168.16.254 api.testbed.osism.xyz api
+

Webinterfaces

+

All SSL enabled services within the OSISM Testbed use certs which are signed by the self-signed +OSISM Testbed CA +(Download the file and import it as certification authority to your browser).

+

If you want to access the services please choose the URL from the following table.

+
NameURLUsernamePasswordNote
ARAhttps://ara.testbed.osism.xyzarapassword
Cephhttps://api-int.testbed.osism.xyz:8140adminpassword
Flowerhttps://flower.testbed.osism.xyz
Grafanahttps://api-int.testbed.osism.xyz:3000adminpassword
HAProxy (testbed-node-0)http://testbed-node-0.testbed.osism.xyz:1984openstackpassword
HAProxy (testbed-node-1)http://testbed-node-1.testbed.osism.xyz:1984openstackpassword
HAProxy (testbed-node-2)http://testbed-node-2.testbed.osism.xyz:1984openstackpassword
Homerhttps://homer.testbed.osism.xyz
Horizon (via Keycloak)https://api.testbed.osism.xyzalicepassword
Horizon (via Keystone)https://api.testbed.osism.xyzadminpassworddomain: default
Horizon (via Keystone)https://api.testbed.osism.xyztesttestdomain: test
Keycloakhttps://keycloak.testbed.osism.xyz/authadminpassword
Netboxhttps://netbox.testbed.osism.xyzadminpassword
Netdatahttp://testbed-manager.testbed.osism.xyz:19999
Nexushttps://nexus.testbed.osism.xyzadminpassword
OpenSearch Dashboardshttps://api.testbed.osism.xyz:5601opensearchpassword
Prometheushttps://api-int.testbed.osism.xyz:9091adminpassword
RabbitMQhttps://api-int.testbed.osism.xyz:15672openstackpassword
phpMyAdminhttps://phpmyadmin.testbed.osism.xyzrootpassword
+

Authentication with OIDC

+

Authentication with OpenID Connect (OIDC) is possible via Keycloak, which is automatically configured for the OIDC mechanism.

+

OpenStack web dashboard (Horizon) login via OIDC

+

For logging in via OIDC, open your browser at OpenStack Dashboard Login Page, select Authenticate via Keycloak, after being +redirected to the Keycloak login page, perform the login with the credentials alice and password. +After that you will be redirected back to the Horizon dashboard, where you will be logged in with the user alice.

+

OpenStack web dashboard (Horizon) logout

+

Keep in mind, that clicking Sign Out on the Horizon dashboard currently doesn't revoke your OIDC token, and any consequent +attempt to Authenticate via Keycloak will succeed without providing the credentials.

+

The expiration time of the Single Sign On tokens can be controlled on multiple levels in Keycloak.

+
    +
  1. +

    On realm level under Realm Settings > Tokens. +Assuming the keycloak_realm ansible variable is the default osism, and keycloak is listening on +keycloak.testbed.osism.xyz, then the configuration form is available +here.

    +

    Detailed information is available in the Keycloak Server Administrator Documentation +Session and Token Timeouts section.

    +
  2. +
  3. +

    In a realm down on the client level +select the client (keystone), and under Settings > Advanced Settings.

    +

    It is recommended to keep the Access Token Lifespan on a relatively low value, with the trend of blocking third party +cookies. For further information see the Keycloak documentation's Browsers with Blocked Third-Party Cookies section.

    +
  4. +
+

Usage of the OpenStack CLI

+

The environments/openstack folder contains the needed files for the openstack client:

+
cd environments/openstack
export OS_CLOUD=<the cloud environment> # i.e. admin
openstack floating ip list
+

OpenStack CLI operations with OpenID Connect password

+

Using the OpenStack cli is also possible via OIDC, assuming you provisioned the user alice with password password, +then you can perform a simple project list operation like this:

+

See chapter "Usage the OpenStack CLI" for basic openstack usage.

+
openstack \
--os-cacert /etc/ssl/certs/ca-certificates.crt \
--os-auth-url https://api.testbed.osism.xyz:5000/v3 \
--os-auth-type v3oidcpassword \
--os-client-id keystone \
--os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \
--os-username alice \
--os-password password \
--os-identity-provider keycloak \
--os-protocol openid \
--os-identity-api-version 3 \
--os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \
project list
+

OpenStack CLI token issue with OpenID Connect

+

It is also possible to exchange your username/password to a token, for further use with the cli. +The token issue subcommand returns an SQL table, in which the id column's value field contains the token:

+

See chapter "Usage the OpenStack CLI" for basic openstack usage.

+
openstack \
--os-cacert /etc/ssl/certs/ca-certificates.crt \
--os-auth-url https://api.testbed.osism.xyz:5000/v3 \
--os-auth-type v3oidcpassword \
--os-client-id keystone \
--os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \
--os-username alice \
--os-password password \
--os-identity-provider keycloak \
--os-protocol openid \
--os-identity-api-version 3 \
--os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \
--os-openid-scope "openid profile email" \
token issue \
-c id
-f value
+

An example token is like:

+
gAAAAABhC98gL8nsQWknro3JWDXWLFCG3CDr3Mi9OIlvVAZMjy2mNgYtlXv_0yAIy-
nSlLAaLIGhht17-mwf8uclKgRuNVsYLSmgUpB163l89-ch2w2_OFe9zNSQNWf4qfd8
Cl7E7XvvUoFr1N8Gh09vaYLvRvYgCGV05xBUSs76qCHa0qElPUsk56s5ft4ALrSrzD
4cEQRVb5PXNjywdZk9_gtJziz31A7sD4LPIy82O5N9NryDoDw
+
    +
  • TODO: OpenStack CLI operations with token
  • +
  • TODO: OpenStack CLI token revoke
  • +
+

Advanced Usage

+

External API

+

It is possible to provide the OpenStack APIs and the OpenStack Dashboard via the manager's public IP address. +This is not enabled by default, with the exception of the OTC profile. To provide the OpenStack APIs and the +OpenStack dashboard via the public IP address of the manager, the following changes are necessary in the +terraform/environments/regiocloud.tfvars file. If a cloud other than the REGIO.cloud is used, the profile +of the other cloud is changed accordingly.

+
    +
  1. +

    Add the customisation external_api. This customisation makes sure that the required security group rules +are created for the various OpenStack APIs and the OpenStack dashboard.

    +
    # customisation:external_api
    +
  2. +
  3. +

    Set parameter external_api to true. This makes sure that all necessary changes are made in the configuration +repository when the Manager service is deployed. It is correct that this is added as a comment.

    +
    external_api = true
    +
  4. +
  5. +

    After the deployment of the Manager service and the OpenStack services, the OpenStack APIs and the OpenStack +dashboard can be reached via a DNS name. The service traefik.me is used for the DNS record. +Run the following two commands on the manager node to get the DNS record.

    +
    $ source /opt/manager-vars.sh
    $ echo "api-${MANAGER_PUBLIC_IP_ADDRESS//./-}.traefik.me"
    api-80-158-46-219.traefik.me
    +
  6. +
+

Change versions

+
    +
  1. Go to /opt/configuration on testbed-manager
  2. +
  3. Run ./scripts/set-openstack-version.sh 2023.2 to set the OpenStack version to 2023.2
  4. +
  5. Run ./scripts/set-ceph-version.sh reef to set the Ceph version to reef
  6. +
  7. Run osism update manager to update the Manager service
  8. +
+

Deploy services

+
ScriptDescription
/opt/configuration/scripts/deploy/000-manager-service.sh
/opt/configuration/scripts/deploy/001-helper-services.sh
/opt/configuration/scripts/deploy/100-ceph-services-basic.sh
/opt/configuration/scripts/deploy/200-infrastructure-services-basic.sh
/opt/configuration/scripts/deploy/210-infrastructure-services-extended.sh
/opt/configuration/scripts/deploy/300-openstack-services-basic.sh
/opt/configuration/scripts/deploy/310-openstack-services-extended.sh
/opt/configuration/scripts/deploy/320-openstack-services-baremetal.sh
/opt/configuration/scripts/deploy/330-openstack-services-additional.sh
/opt/configuration/scripts/deploy/400-monitoring-services.sh
+

Upgrade services

+
ScriptDescription
/opt/configuration/scripts/upgrade/100-ceph-services.sh
/opt/configuration/scripts/upgrade/200-infrastructure-services-basic.sh
/opt/configuration/scripts/upgrade/300-openstack-services-basic.sh
/opt/configuration/scripts/upgrade/310-openstack-services-extended.sh
/opt/configuration/scripts/upgrade/320-openstack-services-baremetal.sh
/opt/configuration/scripts/upgrade/330-openstack-services-additional.sh
+

Troubleshooting

+

Ansible errors

+

Ansible errors that have something to do with undefined variables (e.g. AnsibleUndefined) are most likely due to cached +facts that are no longer valid. The facts can be updated by running osism apply facts.

+

Unsupported locale setting

+
$ make prepare
ansible-playbook -i localhost, ansible/check-local-versions.yml
ERROR: Ansible could not initialize the preferred locale: unsupported locale setting
make: *** [prepare] Error 1
+

To solve the problem you have to modify the Makefile. Change the 1st line as follows.

+
export LC_ALL=en_US.UTF-8
+

To find out the locale used on the system printenv can be used.

+
$ printenv | grep -i lang|locale
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=
+

Appendix

+

Configuration

+

This section describes how to configure and customise the OSISM Testbed.

+

Variables

+

The defaults for the OpenTofu variables are intended for REGIO.cloud.

+
VariableDefaultNote
availability_zonenova
ceph_versionquincy
cloud_providerregiocloud
configuration_versionmain
deploy_monitoringfalse
dns_nameservers["8.8.8.8", "9.9.9.9"]
enable_config_drivetrue
external_apifalse
flavor_managerSCS-4V-16-50
flavor_nodeSCS-8V-32-50
imageUbuntu 22.04Only Ubuntu 22.04 is currently supported
image_nodeUbuntu 22.04Only Ubuntu 22.04 is currently supported
keypairtestbed
manager_versionlatest
network_availability_zonenova
number_of_nodes3
number_of_volumes3
openstack_version2023.2
prefixtestbed
publicexternal
refstackfalse
volume_availability_zonenova
volume_size_base30
volume_size_storage10
volume_type__DEFAULT__
+

Overrides

+
NameDescription
manager_boot_from_image
manager_boot_from_volume
neutron_availability_zone_hints_network
neutron_availability_zone_hints_router
neutron_router_enable_snat
nodes_boot_from_image
nodes_boot_from_volume
nodes_use_ephemeral_storage
+

Customisations

+
NameDescription
access_floatingip
access_ipv4
access_ipv6
default
external_api
neutron_floatingip
+

Notes

+
    +
  • The configuration is intentionally kept quite static. Please create no PRs to make the configuration more flexible/dynamic.
  • +
  • The OSISM documentation uses hostnames, examples, addresses etc. from OSISM Testbed.
  • +
  • The third volume (/dev/sdd) is not enabled for Ceph by default. This is to test the scaling of Ceph.
  • +
  • The manager is used as pull through cache for Docker images and Ubuntu packages. This reduces the amount of traffic consumed.
  • +
+

Supported releases

+

The following stable Ceph and OpenStack releases are supported.

+

The deployment of Ceph is based on ceph-ansible.

+
    +
  • Ceph Quincy (default)
  • +
  • Ceph Reef
  • +
+

The deployment of OpenStack is based on kolla-ansible.

+
    +
  • OpenStack 2023.1
  • +
  • OpenStack 2023.2 (default)
  • +
  • OpenStack 2024.1
  • +
+

The deployment of Kubernetes is based on k3s-ansible.

+
    +
  • Kubernetes v1.29 (default)
  • +
+

Included services

+

The following services can currently be used with the OSISM Testbed without further adjustments.

+

Infrastructure

+
    +
  • Ceph
  • +
  • Cluster API Management Cluster
  • +
  • Fluentd
  • +
  • Gnocchi
  • +
  • Grafana
  • +
  • Haproxy
  • +
  • Influxdb
  • +
  • Keepalived
  • +
  • Keycloak
  • +
  • Kubernetes
  • +
  • Mariadb
  • +
  • Memcached
  • +
  • Netbox
  • +
  • Netdata
  • +
  • Opensearch
  • +
  • Openvswitch
  • +
  • Patchman
  • +
  • Prometheus exporters
  • +
  • Rabbitmq
  • +
  • Redis
  • +
+

OpenStack

+
    +
  • Barbican
  • +
  • Ceilometer
  • +
  • Cinder
  • +
  • Designate
  • +
  • Glance
  • +
  • Heat
  • +
  • Horizon
  • +
  • Ironic
  • +
  • Keystone
  • +
  • Magnum
  • +
  • Manila
  • +
  • Neutron
  • +
  • Nova (with Libvirt/KVM)
  • +
  • Octavia
  • +
  • Senlin
  • +
  • Skyline
  • +
+

Makefile reference

+
$ make help

Usage:
make <target>
help Display this help.
clean Destroy infrastructure with OpenTofu.
wipe-local-install Wipe the software dependencies in `venv`.
create Create required infrastructure with OpenTofu.
login Log in on the manager.
vpn-wireguard Establish a wireguard vpn tunnel.
vpn-sshuttle Establish a sshuttle vpn tunnel.
bootstrap Bootstrap everything.
manager Deploy only the manager service.
identity Deploy only identity services.
ceph Deploy only ceph services.
deploy Deploy everything and then check it.
prepare Run local preperations.
deps Install software preconditions to `venv`.

$ make <TAB> <TAB>
+

CI jobs

+

You can inspect the results of the daily zuul jobs.

+
NameDescription
testbed-deploy
testbed-deploy-ceph
testbed-deploy-stable
testbed-update-stable
testbed-upgrade
testbed-upgrade-ceph
testbed-upgrade-stable
+ + \ No newline at end of file diff --git a/docs/iaas/guides/troubleshooting-guide/ceph/index.html b/docs/iaas/guides/troubleshooting-guide/ceph/index.html new file mode 100644 index 0000000000..355e8d6baa --- /dev/null +++ b/docs/iaas/guides/troubleshooting-guide/ceph/index.html @@ -0,0 +1,46 @@ + + + + + +Ceph | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Ceph

+

Where to find docs

+

The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/troubleshooting/

+

It is strongly advised to use the documentation for the version being used.

+ +

Critical medium error

+

The block device sdf has errors. You can see this in the kernel ring buffer, for example.

+
$ sudo dmesg
[...]
[14062414.575715] sd 14:0:5:0: [sdf] tag#2120 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=1s
[14062414.575722] sd 14:0:5:0: [sdf] tag#2120 Sense Key : Medium Error [current] [descriptor]
[14062414.575725] sd 14:0:5:0: [sdf] tag#2120 Add. Sense: Unrecovered read error
[14062414.575728] sd 14:0:5:0: [sdf] tag#2120 CDB: Read(16) 88 00 00 00 00 01 09 7c d9 50 00 00 00 80 00 00
[14062414.575730] critical medium error, dev sdf, sector 4454144360 op 0x0:(READ) flags 0x0 phys_seg 13 prio class 2
+

It may also be displayed in the health details of Ceph.

+
$ ceph -s
[...]
health: HEALTH_WARN
Too many repaired reads on 1 OSDs
[...]

$ ceph health detail
HEALTH_WARN Too many repaired reads on 1 OSDs
[WRN] OSD_TOO_MANY_REPAIRS: Too many repaired reads on 1 OSDs
osd.17 had 13 reads repaire
+

In this case the block device sdf is in the storage node sto1001. The OSD assigned +to this block device can be determined.

+
$ ceph device ls | grep 'sto1001:sdf'
SEAGATE_ST16000NM004J_ZR604ZDZ0000C210PWE9 sto1001:sdf osd.17
+

If you only know the OSD ID, you can also determine the associated block device and the storage node.

+
$ ceph device ls | grep osd.17
[...]
SEAGATE_ST16000NM004J_ZR604ZDZ0000C210PWE9 sto1001:sdf osd.17
+

The broken OSD can be removed from the Ceph cluster. The Ceph cluster is then rebalanced. +This can take some time and cause a high level of activity on the Ceph cluster.

+
$ ceph osd out osd.17
marked out osd.17.
+

On the storage node disable the OSD service for the OSD.

+
$ sudo systemctl stop ceph-osd@17.service
+ + \ No newline at end of file diff --git a/docs/iaas/guides/troubleshooting-guide/index.html b/docs/iaas/guides/troubleshooting-guide/index.html new file mode 100644 index 0000000000..f85c082e3e --- /dev/null +++ b/docs/iaas/guides/troubleshooting-guide/index.html @@ -0,0 +1,24 @@ + + + + + +Troubleshooting Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/troubleshooting-guide/manager/index.html b/docs/iaas/guides/troubleshooting-guide/manager/index.html new file mode 100644 index 0000000000..407a380a13 --- /dev/null +++ b/docs/iaas/guides/troubleshooting-guide/manager/index.html @@ -0,0 +1,61 @@ + + + + + +Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Manager

+

Reset

+

Sometimes it is necessary to reset the entire manager service.

+
warning

This is a disruptive action. Data is lost in the process. For example, the database +of the ARA service.

+
    +
  1. +

    Stop the manager service

    +
    sudo systemctl stop docker-compose@manager.service
    +
  2. +
  3. +

    Files on the /share volume are backed up in advance and restored after +the manager service is started.

    +
    docker run --rm \
    --mount source=manager_share,target=/share \
    --volume $(pwd):/backup \
    busybox \
    tar -czvf /backup/manager-share-$(date +%Y%m%d).tar.gz /share
    +
  4. +
  5. +

    Delete the manager service. This is a disruptive action.

    +
    docker compose --project-directory /opt/manager down -v
    +
  6. +
  7. +

    Start the manager service

    +
    sudo systemctl start docker-compose@manager.service
    +
  8. +
  9. +

    Restore the files on the /share volume.

    +
    docker run --rm \
    --mount source=manager_share,target=/share \
    --volume $(pwd):/backup \
    busybox \
    tar -xzvf /backup/manager-share-$(date +%Y%m%d).tar.gz -C /
    +
  10. +
  11. +

    Check that manager service is healthy

    +
    docker compose --project-directory /opt/manager ps
    +

    Depending on what the manager service looks like, this output may vary.

    +
    NAME                             IMAGE                                        COMMAND                  SERVICE                CREATED              STATUS                        PORTS
    ceph-ansible quay.io/osism/ceph-ansible:quincy "/entrypoint.sh osis…" ceph-ansible About a minute ago Up About a minute (healthy)
    kolla-ansible quay.io/osism/kolla-ansible:2023.2 "/entrypoint.sh osis…" kolla-ansible About a minute ago Up About a minute (healthy)
    manager-api-1 quay.io/osism/osism:latest "osism service api" api About a minute ago Up About a minute (healthy) 192.168.16.5:8000->8000/tcp
    manager-ara-server-1 quay.io/osism/ara-server:latest "sh -c '/wait && /ru…" ara-server About a minute ago Up About a minute (healthy) 8000/tcp
    manager-beat-1 quay.io/osism/osism:latest "osism service beat" beat About a minute ago Up About a minute (healthy)
    manager-conductor-1 quay.io/osism/osism:latest "osism worker conduc…" conductor About a minute ago Up About a minute (healthy)
    manager-flower-1 quay.io/osism/osism:latest "osism service flower" flower About a minute ago Up About a minute (healthy)
    manager-inventory_reconciler-1 quay.io/osism/inventory-reconciler:latest "/sbin/tini -- /entr…" inventory_reconciler About a minute ago Up About a minute (healthy)
    manager-listener-1 quay.io/osism/osism:latest "osism service liste…" listener About a minute ago Up About a minute (healthy)
    manager-mariadb-1 index.docker.io/library/mariadb:11.3.2 "docker-entrypoint.s…" mariadb About a minute ago Up About a minute (healthy) 3306/tcp
    manager-netbox-1 quay.io/osism/osism-netbox:latest "osism worker netbox" netbox About a minute ago Up About a minute (healthy)
    manager-openstack-1 quay.io/osism/osism:latest "osism worker openst…" openstack About a minute ago Up About a minute (healthy)
    manager-redis-1 index.docker.io/library/redis:7.2.4-alpine "docker-entrypoint.s…" redis About a minute ago Up About a minute (healthy) 6379/tcp
    manager-watchdog-1 quay.io/osism/osism:latest "osism service watch…" watchdog About a minute ago Up About a minute (healthy)
    osism-ansible quay.io/osism/osism-ansible:latest "/entrypoint.sh osis…" osism-ansible About a minute ago Up About a minute (healthy)
    osismclient quay.io/osism/osism:latest "sleep infinity" osismclient About a minute ago Up About a minute
    +
  12. +
  13. +

    When the manager service is healthy, the inventory and the fact cache +must be rebuilt.

    +
    osism reconciler sync
    osism apply facts
    +
  14. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/troubleshooting-guide/openstack/index.html b/docs/iaas/guides/troubleshooting-guide/openstack/index.html new file mode 100644 index 0000000000..6e707ac320 --- /dev/null +++ b/docs/iaas/guides/troubleshooting-guide/openstack/index.html @@ -0,0 +1,29 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

OpenStack

+

Database creation fails

+

Problem:

+
TASK [keystone : Creating keystone database] ***********************************
fatal: [testbed-node-0]: FAILED! => changed=false
action: mysql_db
msg: 'unable to find /var/lib/ansible/.my.cnf. Exception message: (2003, "Can''t connect to MySQL server on ''api-int.local'' ([Errno 111] Connection refused)")'
+

Solution:

+

Restart the kolla_toolbox container. in this case on the node testbed-node-0.

+
$ osism console testbed-node-0/
testbed-node-0>>> restart kolla_toolbox
kolla_toolbox
testbed-node-0>>>
+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/ceph/index.html b/docs/iaas/guides/upgrade-guide/ceph/index.html new file mode 100644 index 0000000000..9586a71bb4 --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/ceph/index.html @@ -0,0 +1,24 @@ + + + + + +Ceph | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/docker/index.html b/docs/iaas/guides/upgrade-guide/docker/index.html new file mode 100644 index 0000000000..73c0731829 --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/docker/index.html @@ -0,0 +1,82 @@ + + + + + +Docker | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Docker

+

The Docker version used is defined via the parameter docker_version in the file +environments/configuration.yml.

+
docker_version: '5:20.10.24'
+

All installable versions can be displayed with apt-cache madison docker-ce.

+
$ apt-cache madison docker-ce
docker-ce | 5:24.0.6-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:24.0.5-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:24.0.4-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:24.0.3-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:24.0.2-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:24.0.1-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:24.0.0-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.6-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.5-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.4-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.3-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.2-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.1-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:23.0.0-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.24~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.23~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.22~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.21~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.20~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.19~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.18~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.17~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.16~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.15~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.14~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
docker-ce | 5:20.10.13~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
+

If, for example, you want to change the Docker version from 20.10.24 to 24.0.6, docker_version in +environments/configuration.yml is changed accordingly. The 5: prefix is placed in front of the version. Commit and push the changes to your configuration repository afterwards.

+

The upgrade of Docker is then done with the OSISM CLI. Docker on the manager itself is updated differently. +This does not work on the manager itself because the Docker service may be started during the upgrade and +individual containers may be started as a result. This would interrupt the run of the role itself.

+
osism apply docker -l 'docker:!manager'
+

By default, serial is set to 1 so that the the hosts are upgrade one after the other. +To adjust this, either use the osism_serial dictionary in the environments/configuration.yml file +to change the value in docker or append -e serial=10% to upgrade, for example, 10% +with each iteration.

+

Please note that it is not a good idea to upgrade more than one Docker service at a time. +This can lead to anomalies, especially on storage nodes and control nodes. It is recommended +not to change the default of 1.

+
osism_serial:
docker: 10%
+

On the manager itself, the run.sh script in the manager environment of the configuration must +currently be used to upgrade the Docker service. In a future release a dedicated osism update docker +command will be available for this purpose.

+
cd /opt/configuration/environments/manager
ANSIBLE_ASK_VAULT_PASS=True ./run.sh docker
+

Restart behaviour

+

When upgrading, the Docker service is restarted. As a result, it can come to a restart of the +running containers. This can lead to interruptions in individual services. A change in +/etc/docker/daemon.json due to a new configuration parameter etc. can also result in a +required restart.

+

Whether the containers are restarted when the Docker Service is restarted depends on whether the +Live Restore feature is used. +This can be configured via the parameter docker_live_restore. Live restore is enabled by default.

+

It is important to set the docker_live_restore parameter explicitly as a string. This means +docker_live_restore: "false" or docker_live_restore: "true".

+

But even if the Live Restore feature is enabled, certain upgrades will cause running containers +to be restarted:

+
+

Live restore allows you to keep containers running across Docker daemon updates, but is only +supported when installing patch releases (YY.MM.x), not for major (YY.MM) daemon upgrades.

+
+

There are two ways to prevent a restart of the Docker service during an upgrade.

+

If the restart behaviour of the Docker service is changed, always make sure to restart the +Docker service manually afterwards (e.g. by a system reboot).

+
    +
  1. +

    A host group can be defined via the parameter docker_ignore_restart_groupname. The +restart of the Docker service is not triggered for all hosts in this group. By default, +docker_ignore_restart_groupname is set to manager. The parameter is best set in the +environments/configuration.yml file when making an adjustment. For example, to prevent +the restart on all hosts, docker_ignore_restart_groupname is set to generic.

    +
    docker_ignore_restart_groupname: generic
    +
  2. +
  3. +

    With the parameter docker_allow_restart, the restart of the Docker service can be +prevented. By default, docker_allow_restart is set to true. It is recommended to set +this parameter only at runtime. Otherwise, the best place for the parameter is the +environments/configuration.yml file.

    +
    osism apply docker -e docker_allow_restart=false
    +
  4. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/index.html b/docs/iaas/guides/upgrade-guide/index.html new file mode 100644 index 0000000000..0b37b6e852 --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/index.html @@ -0,0 +1,27 @@ + + + + + +Upgrade Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Upgrade Guide

+

In the examples, the pull of images (if supported by a role) is always run first. While +this is optional, it is recommended to speed up the execution of the upgrade action in +the second step. This significantly reduces the times required for the restart from a +service.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/infrastructure/index.html b/docs/iaas/guides/upgrade-guide/infrastructure/index.html new file mode 100644 index 0000000000..6db132221a --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/infrastructure/index.html @@ -0,0 +1,60 @@ + + + + + +Infrastructure | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Infrastructure

+
    +
  1. +

    Kubernetes

    +

    This is only necessary if the internal Kubernetes cluster has also been deployed. +This can be checked by executing kubectl get nodes on the manager node.

    +
    osism apply k3s-upgrade
    +
  2. +
  3. +

    Cron, Fluentd & Kolla Toolbox

    +

    The common role of Kolla is used to manage the services cron, fluentd +and kolla-toolbox.

    +

    It is important to do this upgrade before any other upgrades in the Kolla +environment, as parts of the other upgrades depend on the kolla-toolbox +service.

    +
    osism apply -a pull common
    osism apply -a upgrade common
    +
  4. +
  5. +

    Loadbalancer

    +
    osism apply -a pull loadbalancer
    osism apply -a upgrade loadbalancer
    +
  6. +
  7. +

    Redis

    +
    osism apply -a pull redis
    osism apply -a upgrade redis
    +
  8. +
  9. +

    Memcached

    +
    osism apply -a pull memcached
    osism apply -a upgrade memcached
    +
  10. +
  11. +

    RabbitMQ

    +
    osism apply -a pull rabbitmq
    osism apply -a upgrade rabbitmq
    +
  12. +
  13. +

    MariaDB

    +
    osism apply -a pull mariadb
    osism apply -a upgrade mariadb
    +
  14. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/logging-monitoring/index.html b/docs/iaas/guides/upgrade-guide/logging-monitoring/index.html new file mode 100644 index 0000000000..3bf15faf3b --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/logging-monitoring/index.html @@ -0,0 +1,38 @@ + + + + + +Logging & Monitoring | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Logging & Monitoring

+
    +
  1. +

    OpenSearch

    +

    OpenSearch dashboards is also upgraded with the opensearch role.

    +
    osism apply -a pull opensearch
    osism apply -a upgrade opensearch
    +
  2. +
  3. +

    Prometheus

    +
    osism apply -a pull prometheus
    osism apply prometheus
    +
  4. +
  5. +

    Grafana

    +
    osism apply -a pull grafana
    osism apply -a upgrade grafana
    +
  6. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/manager/index.html b/docs/iaas/guides/upgrade-guide/manager/index.html new file mode 100644 index 0000000000..8d093c85e0 --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/manager/index.html @@ -0,0 +1,77 @@ + + + + + +Manager | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Manager

+
warning

Always read the release notes first to learn what has changed and what +adjustments are necessary. Read the release notes even if you are only updating from e.g. 7.0.2 to 7.0.5.

+

The update of a manager service with a stable release of OSISM is described here. +In the example, OSISM release 7.0.5 is used.

+
    +
  1. +

    Change the OSISM release in the configuration repository.

    +

    1.1. Set the new OSISM version in the configuration repository.

    +
    MANAGER_VERSION=7.0.5
    sed -i -e "s/manager_version: .*/manager_version: ${MANAGER_VERSION}/g" environments/manager/configuration.yml
    +

    1.2. If openstack_version or ceph_version are set in environments/manager/configuration.yml +(or anywhere else), they must be removed. If these are set, the stable release is not used for +these components.

    +

    1.3. Sync the image versions and files in the configuration repository.

    +
    make sync
    +

    1.4. Commit and push all changes in the configuration repository. Since everyone here has their own +workflows for changes to the configuration repository, only a generic example for Git.

    +
    git commit -a -s -m "manager: use OSISM version 7.0.5"
    git push
    +
  2. +
  3. +

    Update the configuration repository on the manager node.

    +
    osism apply configuration
    +
  4. +
  5. +

    Update the manager service on the manager node.

    +
    osism update manager
    +
      +
    • If Ansible Vault was used to encrypt environments/manager/secrets.yml, the parameter +--ask-vault-pass is also appended. From OSISM >= 7.0.5 this is no longer necessary.
    • +
    • If osism update manager does not work yet, use osism-update-manager instead.
    • +
    +
  6. +
  7. +

    Refresh the facts cache.

    +
    osism apply facts
    +
  8. +
  9. +

    If Traefik is used on the manager node (traefik_enable: true in environments/infrastructure/configuration.yml) +then Traefik should also be upgraded.

    +
    osism apply traefik
    +
  10. +
  11. +

    Finally, the Ansible vault password must be made known again.

    +
    osism set vault password
    +
  12. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/network/index.html b/docs/iaas/guides/upgrade-guide/network/index.html new file mode 100644 index 0000000000..8f2b80b04e --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/network/index.html @@ -0,0 +1,40 @@ + + + + + +Network | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Network

+
    +
  1. +

    Open vSwitch (OVS)

    +
    osism apply -a pull openvswitch
    osism apply -a upgrade openvswitch
    +
  2. +
  3. +

    Open Virtual Network (OVN)

    +

    In environments/kolla/configuration.yml the parameter neutron_plugin_agent is set to +ovn if OVN is used as a network plugin. The parameter is set to ovn by default in the +Cookiecutter.

    +
    environments/kolla/configuration.yml
    # neutron
    neutron_plugin_agent: "ovn"
    +

    Otherwise the network plugin is set to openvswitch. +If the neutron_plugin_agent is set to openvswitch, this step does not need to be done.

    +

    Before the upgrade of OVN, the upgrade of Open vSwitch must already have been done.

    +
    osism apply -a pull ovn
    osism apply -a upgrade ovn
    +
  4. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/upgrade-guide/openstack/index.html b/docs/iaas/guides/upgrade-guide/openstack/index.html new file mode 100644 index 0000000000..12a71bf772 --- /dev/null +++ b/docs/iaas/guides/upgrade-guide/openstack/index.html @@ -0,0 +1,79 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

OpenStack

+
info

When upgrade the different OpenStack services, all containers must be +restarted. When restarting the API services, there is a short downtime +of the APIs. This downtime is usually less than 1 minute.

+
    +
  1. +

    OpenStack client

    +
    osism apply openstackclient
    +
  2. +
  3. +

    Keystone

    +
    osism apply -a pull keystone
    osism apply -a upgrade keystone
    +
  4. +
  5. +

    Glance

    +
    osism apply -a pull glance
    osism apply -a upgrade glance
    +
  6. +
  7. +

    Designate

    +
    osism apply -a pull designate
    osism apply -a upgrade designate
    +
  8. +
  9. +

    Placement

    +
    osism apply -a pull placement
    osism apply -a upgrade placement
    +
  10. +
  11. +

    Cinder

    +
    osism apply -a pull cinder
    osism apply -a upgrade cinder
    +
  12. +
  13. +

    Neutron

    +
    osism apply -a pull neutron
    osism apply -a upgrade neutron
    +
  14. +
  15. +

    Nova

    +
    osism apply -a pull nova
    osism apply -a upgrade nova
    +
  16. +
  17. +

    Octavia

    +
    osism apply -a pull octavia
    osism apply -a upgrade octavia
    +

    9.1. Update amphora image

    +

    This step is only necessary if the Amphora Driver is used. If OVN is used as the driver, +this step is not necessary.

    +

    We provide regularly updated images for Octavia in +osism/openstack-octavia/amphora-image. +The OSISM CLI can be used to upload the correct image depending on the OpenStack release +used.

    +
    osism manage image octavia
    +

    9.2. Amphora rotation

    +

    This step is only necessary if the Amphora driver is used. If OVN is used as the driver, +this step is not necessary.

    +
  18. +
  19. +

    Horizon

    +
    osism apply -a pull horizon
    osism apply -a upgrade horizon
    +
  20. +
+ + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/index.html b/docs/iaas/guides/user-guide/index.html new file mode 100644 index 0000000000..ee425c32ca --- /dev/null +++ b/docs/iaas/guides/user-guide/index.html @@ -0,0 +1,23 @@ + + + + + +User Guide | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/migration-vmware-esix/index.html b/docs/iaas/guides/user-guide/migration-vmware-esix/index.html new file mode 100644 index 0000000000..89d92d5758 --- /dev/null +++ b/docs/iaas/guides/user-guide/migration-vmware-esix/index.html @@ -0,0 +1,150 @@ + + + + + +Migrate from VMware ESXi to OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Migrate from VMware ESXi to OpenStack

+

This guide is an example of how to perform a manual migration from a VMware ESXi host to OpenStack. +Migration to OpenStack always depends very much on the use case. It is not possible to document an +approach or to write a tool that works for all use cases. This guide shows one possible way. There are many ways to +perform a migration. A migration must always be carefully prepared and tested in advance.

+

At this point, we would also like to point out the open source project +cloudbase/coriolis from Cloudbase. There are also commercial +providers that perform migration from VMware ESXi to OpenStack. One of the offerings is +Hystax Acura Live Cloud Migration.

+

Scenario

+
    +
  • Source: ESXi 7.0 host
  • +
  • Destination: OpenStack
  • +
  • a security group (web_ssh) is already available at the destination
  • +
  • a Linux converter host is installed and ready, we also have root access to it
  • +
  • an IPv4 address (10.50.40.230) will be given manually out of a preconfigured network
  • +
  • we migrate one host with a kernel newer then 2.6.25 with two scsi harddrives attached and one networkcard
  • +
  • destination openstack using Libvirt/KVM as virtualisation
  • +
  • the converter host has access to ESXi and the OpenStack environment over IP network
  • +
+

Requirements

+
    +
  • +

    VMware credentials

    +
      +
    • SSH enabled on ESXi host
    • +
    • access to the webinterface of the ESXi host
    • +
    +
  • +
  • +

    OpenStack credentials

    +
  • +
  • +

    Linux packages installed on the coverter, in this case it is an Ubuntu 22.04

    +
    apt-get install qemu-utils python3-openstackclient
    +
  • +
  • +

    twice the space of the largest vmdk disc image on the converter or nfs access to the image files with enough storage

    +
  • +
+

Prechecks

+

Check the /etc/fstab file of your VMware ESXi host you want to move. See how all the discs or paritions are mounted. +If they are all mounted by LVM or UUID you do not need to change anything.

+
cat /etc/fstab
/dev/mapper/vg00-lvroot /               ext4    errors=remount-ro 0       1
/dev/mapper/vg00-lvboot /boot ext2 defaults 0 2
/dev/mapper/vg00-lvhome /home ext4 defaults 0 2
/dev/mapper/vg00-lvvar /var ext4 defaults 0 2
/dev/mapper/vg00-lvswap none swap sw 0 0
/dev/mapper/vgdata-lvsrv /srv ext4 defaults 0 2
+

If they are mounted like /dev/sda it is better to change the /etc/fstab to UUID mounting using blkid.

+

Replace these entries with UUID=filesystems_uuid and add the rest of the line same as with the devicenames.

+

Example:

+
example devicename fstab
/dev/sda1 /boot     ext2  defaults          0       2
/dev/sda2 / ext4 errors=remount-ro 0 1
+

Change it to something like this:

+
example uuid fstab
UUID=574c96bf-f2cb-49b8-9196-232a24047f94 /boot     ext2  defaults          0       2
UUID=93cc3b34-36c3-422e-b7a6-c80439e8f431 / ext4 errors=remount-ro 0 1
+
caution

When creating a new server, OpenStack uses /dev/vd* or /dev/sd* as devices for volumes. +Using UUID/LVM mounts will ensure that the kernel will find your devices while booting. +Using old device names may lead to the boot sequence to get stuck, due to missing devices.

+

Also check your NIC interface configuration as the devicenames can change to a new devicename.

+

This depends on the udev or systemd setup of your specific system.

+

It needs to be changed to either DCHP if you want to use floating IPs or static IP of the new network.

+

Migration

+
note

Shutdown the host in VMware as the movement is only possible while the host is offline. +Otherwise you will get corrupted disc files.

+

You can use either the webinterface or SSH to identify and copy the *.vmdk files of your VMware ESXi host.

+

While using the web interface you need to locate the datastore and the directoy where the disc files are +located and start downloading all vmdk files. You will always get files files for a disc, a smaller and a +larger one, both are required.

+

When using SSh, please also copy both vmdk files for the disc to the converter host. Start looking up your +files under /vmfs/volumes/.

+

How to copy vmdk images

+

Example SSH copy and path of all vmdk files to the converter host using the scp command for our testing-host:

+
scp user@vmhost:/vmfs/volumes/datastore1/testing-host/*.vmdk .
+

After copying is finished, we find several vmdk files in our directory. +We copied two disc images:

+
testing-host-disc0-flat.vmdk testing-host-disc1.vmdk
testing-host-disc0.vmdk testing-host-disc1-flat.vmdk
+

How to convert vmdk to raw

+
note

Now convert those vmdk files into raw images with the following flags:

-p show progress (optional)  
-f Input Format
-O Output Format

Raw files are required to import images into OpenStack.

+
qemu-img convert -p -f vmdk -O raw testing-host-disc0.vmdk testing-host-disc0.raw
+

Repeat this step for each disc image you need to convert.

+

Edit the raw Images (optional)

+
note

This step is completely optional and you should have some Linux knowledge to do this.

+

After converting the images of a Linux host, you now have the possibilty to edit some settings offline before importing the images into OpenStack.

+

By mounting the raw image files you can edit the configuration files to, e.g.:

+
    +
  • disable mountpoints at the fstab, like nfs server
  • +
  • change the ip config of the networkcard to dhcp or fixed ip
  • +
  • adjust resolv.conf
  • +
  • adjust routing
  • +
+

On Ubuntu you can use losetup to mount the raw image as a loopdevice to mount it somewhere you have access to.

+
losetup -f -P testing-host-disc0.raw
losetup -l

mount /dev/loop0p1 /mnt/test/
or
lvscan and mount the lvm volume
+

How to import Images

+

First of all you need your OpenStack credentials, having them in an my-project-openrc.sh file and source them to your shell.

+

The openstack cli client is now able to connect to the cloud environment and do all the following steps.

+

To get your credentials please check with your OpenStack provider.

+

If you want to preserve the /dev/sd* device names of the mountpoints, you must inject the new image and add some properties while uploading it into the OpenStack environment or add them later on to the images with Horzion web interface or openstack cli client.

+
openstack image create --progress --property hw_disk_bus=scsi --property hw_scsi_model=virtio-scsi --property hw_watchdog_action=reset --disk-format raw --private --file testing-host-disc0.raw  testing-host-image-disc0
+
openstack image list
+--------------------------------------+------------------------------+--------+
| ID | Name | Status |
+--------------------------------------+------------------------------+--------+
| 2a12b545-5d09-4ca1-9a76-b57f8d2489be | testing-host-disc0 | active |
| b34744f7-6ef6-4282-a001-08a06812e381 | testing-host-disc1 | active |
+--------------------------------------+------------------------------+--------+
+

How to create your server

+

The previously imported images need to be copied to a volume so the server is also able to evict to other hosts in the cluster, +so lets create and start our server in OpenStack.

+

Select one flavor for the host, in this case SCS-8V-16, which means 8 Virtual CPUs and 16GB of RAM, get a list of all your available flavors by executing +openstack flavor list and select the best matching one.

+

As the images are 20GB, you tell openstack that you need a boot volume with a size of 20 and a block-device for the additional device also with a size of 20GB.

+

In this guide there is already a security group which fits our needs, if not, create one or you will not be able to communicate with your new host.

+
openstack security group list
+--------------------------------------+-----------------+------------------------------+----------------------------------+------+
| ID | Name | Description | Project | Tags |
+--------------------------------------+-----------------+------------------------------+----------------------------------+------+
| 4fd1d060-bf1d-4f5a-8e80-fde975d41f5f | default | Default security group | c9aa53cc3c654692b14a8f81a88cfa2f | [] |
| 73967e73-e8d5-4318-b621-a06e7496fec3 | web_ssh | Webserver security group | c9aa53cc3c654692b14a8f81a88cfa2f | [] |
+--------------------------------------+-----------------+------------------------------+----------------------------------+------+
+

The web_ssh group will be attached to the server.

+

Now you need to tell which network you want to deploy your host on, optionally including a fixed IPv4 address.

+

You can repeat the --nic for additional nics in your server, in this guide it's the my_corp_net.

+
openstack network list
+--------------------------------------+-------------------+--------------------------------------+
| ID | Name | Subnets |
+--------------------------------------+-------------------+--------------------------------------+
| 9688192e-11dd-4618-a18c-99d3267f630a | my_corp_net | 0d502fdb-be73-457a-8678-79eb6088a9a1 |
| 98842b77-c070-4532-a2a9-99d588c4e947 | internet | 2dfc3916-972f-44d1-afdb-6f89488ef3a4 |
| c846238a-b00a-4c73-87e3-3614d94f46fd | my_other_corp_net | b8210b4e-5d91-425a-b05c-ca5d4bf8329a |
+--------------------------------------+-------------------+--------------------------------------+
+

As last parameter, you give the server name of your migrated system.

+

As we are starting an already configured system we do not need to inject SSH keys or passwords as they should already be present on the host.

+
openstack server create --flavor SCS-8V-16 \
--image 2a12b545-5d09-4ca1-9a76-b57f8d2489be --boot-from-volume 20 \
--security-group 73967e73-e8d5-4318-b621-a06e7496fec3 \
--nic net-id=9688192e-11dd-4618-a18c-99d3267f630a,v4-fixed-ip=10.50.40.230 \
--block-device uuid=b34744f7-6ef6-4282-a001-08a06812e381,source_type=image,destination_type=volume,volume_size=20 \
--os-compute-api-version 2.90 testing-host
+

Show your new server

+
openstack server list
+--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+
| 71a8b930-4212-434a-8891-afdeeb1802dc | testing-host | ACTIVE | my_network=10.50.40.230 | N/A (booted from volume) | SCS-8V-16 |
+--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+
+

To see the attached volumes and their mountpoints:

+
openstack server volume list 71a8b930-4212-434a-8891-afdeeb1802dc   
+----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+
| Device | Server ID | Volume ID | Tag | Delete On Termination? | Attachment ID | BlockDeviceMapping UUID |
+----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+
| /dev/sda | 71a8b930-4212-434a-8891-afdeeb1802dc | 71902b03-48ea-483c-a6a3-6c47b9d8537b | None | False | 3cd241ff-5296-4bb1-9ba0-d743cb8c8f31 | 2d08e835-156f-4f71-8c95-7ff828230b8e |
| /dev/sdb | 71a8b930-4212-434a-8891-afdeeb1802dc | 15a835a3-5149-49a8-8e2b-a81ef8097c35 | None | False | 9deeb06b-718b-49d4-84a4-87dabc34ba56 | 04483f95-0333-4b37-92e6-db604e4ddc7c |
+----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+
+

How to access the VNC console

+

To get the VNC URL for console login use:

+
openstack console url show 71a8b930-4212-434a-8891-afdeeb1802dc
+----------+-------------------------------------------------------------------------------------------+
| Field | Value |
+----------+-------------------------------------------------------------------------------------------+
| protocol | vnc |
| type | novnc |
| url | https://vnc.your.cloud/vnc_lite.html?path=%3Ftoken%3Db9b6920d-e533-4728-8132-a5a0adfc24e5 |
+----------+-------------------------------------------------------------------------------------------+
+

This will print out the VNC URL for the videoconsole connection to your host.

+

Now the server will boot and be available.

+

Maybe you need to tweak the network setup if it is still not accessible. +To do this, you could use the VNC console of the OpenStack host:

+

Login and then setup the network card if you have not already done that before host had been shutdown.

+

You now can remove the imported images, as they are no longer required - except you want to generate +another host with the same images.

+

Last words

+

In this little guide, we only can give a sneak peak of what you need to do with a simple VMware ESXi host. +More complex setups needs consulting, planning and testing as there a several scenarios out there which +cannot be handled like this. +Especially if you have terrabytes of data to move or graphics- or AIcards in you VMware ESXi hosts.

+ + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/openstack/index.html b/docs/iaas/guides/user-guide/openstack/index.html new file mode 100644 index 0000000000..e12fbe69e9 --- /dev/null +++ b/docs/iaas/guides/user-guide/openstack/index.html @@ -0,0 +1,23 @@ + + + + + +OpenStack | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/openstack/security-groups/index.html b/docs/iaas/guides/user-guide/openstack/security-groups/index.html new file mode 100644 index 0000000000..0c761c727c --- /dev/null +++ b/docs/iaas/guides/user-guide/openstack/security-groups/index.html @@ -0,0 +1,107 @@ + + + + + +How to configure and use security groups | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

How to configure and use security groups

+

Security groups in OpenStack are part of the network security mechanisms provided for the users. +They resemble sets of simple firewall rules allowing specific network traffic at a Port of a VM that connects it to a network. +The rules allow specific network port numbers and protocols while also differentiating between ingress and egress directions. +Usually security groups are assigned to the Port(s) when a virtual machine is created, but assignments can also be changed at runtime later on. +Multiple security groups can be assigned to a VM or Port simultaneously and in such case they will be combined as the union of all their rules.

+
caution

Security groups are mutable resources. +Their rules can be adjusted at any time after creation. +Changing the rules of a security group will immediately apply the changes to all Ports or VMs it is assigned to. +It is advisable to always review resources which use a security group before making changes to it.

+

Identify the requirements of your setup

+

Every virtual machine that is created may need different firewall rules. +These requirements can also change over time. +Adding or removing security groups will allow users to adapt the firewall rules specifically to their virtual machines.

+

To harden the firewall settings for your virtual machine you may follow these steps:

+
    +
  1. Before creating a virtual machine its purpose is usually already known. Use this information to identify all incoming and outgoing traffic rules that will be needed based on the communication patterns of the services it is meant to deploy. This includes communication protocols, port numbers, communication directions and optionally target/source address ranges.
  2. +
  3. Look through already existing security groups and their rules. If a security group allows more traffic than needed it SHOULD NOT be used. If a security group contains only a subset of the required rules it MAY be used in combination with other security groups that contain rules which fulfill the remaining required traffic rules from point 1.
  4. +
  5. If you were not successful in finding an appropriate combination of existing security groups or you need additional specific rules to cover all requirements, you MAY create one or more new Security Groups in which you can add the required rules.
  6. +
  7. After ensuring the existence of one or more security groups that fulfill your requirements, you can create the VM with those security groups already specified in the creation command.
  8. +
+

Further security considerations

+

When implementing network security requirements, firewall rules alone are not always sufficient and might need to be augmented with additional configuration or time-based constraints. Notable examples are:

+

SSH +SSH is needed on many virtual machines to operate their guest operating system. +In a security group the port 22 can be opened for the TCP protocol to allow incoming SSH connections. +But that only should be done while also restricting the SSH configuration to public key authentication only (the recommended way) or having a strong username and password policy already applied to the operating system of the virtual machine. +Otherwise default usernames and passwords which are often preconfigured in system images may be exploited through the exposed SSH port which enables attackers to compromise the virtual machine.

+

ICMP +It might be useful to be able to ping a virtual machine or use other ICMP requests. +But for some virtual machine configurations this is either not necessary at all or only temporarily needed. +One benefit of security groups among other things is the ability to be easily added to and removed from existing virtual machines. +So a dedicated security group allowing ICMP could be added temporarily to a virtual machine for debugging purposes and removed from it afterwards.

+

How to create security groups

+

Security groups are managed within a project. +So every project will have a different set of security groups. +They can be added dynamically to each virtual machine, during their creation or afterwards. +Additionally, they may also be removed from VMs at any point.

+

Every project has its own default security group, which rules can be edited. +Additionally other security groups can be added until the project's quota is exhausted. +To add a security group, use the following command:

+
openstack security group create $SECURITY_GROUP
+

Within every security group rules can be added up unto a defined maximum of rules, that usually is about 100. +Rules can be added to security groups with the following command:

+
openstack security group rule create [...] $SECURITY_GROUP
+

To delete rules from a security group, the rule id has to be used. +It is listed in the details of the rules section of the security group.

+
openstack security group rule delete $RULE_ID
+

Default security group

+

Unless specified otherwise, the default security group is assigned to all VMs or Ports at creation. +To use any other than the default security group at creation it is necessary to specify the desired security group(s) during the creation process.

+

To review which rules are defined in a security group, the following command can be used:

+
openstack security group show default
+ +

While projects can use very different aspects in security group rules and thus the security groups will always differ between projects, there are some security groups that are widely used. +Through the nature of security groups being seen as a set of rules that can be combined, having some basic security groups that allow basic protocols is a commonly used setup. +This section will demonstrate how to create some security groups for commonly used protocols and ports.

+
    +
  1. A security groups, that allows incoming SSH traffic:
  2. +
+
openstack security group create ssh
openstack security group rule create --ingress --protocol tcp --dst-port 22 ssh
+
    +
  1. A security group, that allows incoming HTTP requests:
  2. +
+
openstack security group create http
openstack security group rule create --ingress --protocol tcp --dst-port 80 http
+
    +
  1. A security group, that allows incoming HTTPS requests:
  2. +
+
openstack security group create https
openstack security group rule create --ingress --protocol tcp --dst-port 443 https
+
    +
  1. A security group, that allows incoming ICMP requests:
  2. +
+
openstack security group create icmp
openstack security group rule create --protocol icmp icmp
+

How to use security groups

+
info

Security groups can be assigned to multiple resources simultaneously (such as VMs or Ports). +This means that security groups are reusable and don't need to be recreated for each applicable resource individually.

+

Usually, initial security groups are added at the time of the creation of a VM. +During creation, multiple security groups can also be added at the same time by repeating the --security-group argument:

+
openstack server create [...] --security-group $SECURITY_GROUP_1 --security-group $SECURITY_GROUP_2 $SERVER_NAME
+

To add a security group to an existing VM, the following command can be used:

+
openstack server add security group $SERVER_NAME $SECURITY_GROUP
+

To remove a security group from a VM, the following command can be used:

+
openstack server remove security group $SERVER_NAME $SECURITY_GROUP
+

The source of this document can be found in the SovereignCloudStack/docs repository.

+

Author: SCS Community, License: CC by Attribution 4.0 International

+ + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/openstack/user-data-backups/index.html b/docs/iaas/guides/user-guide/openstack/user-data-backups/index.html new file mode 100644 index 0000000000..9a69babdbb --- /dev/null +++ b/docs/iaas/guides/user-guide/openstack/user-data-backups/index.html @@ -0,0 +1,250 @@ + + + + + +User Data Backups | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

User Data Backups

+

This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.

+

Glossary

+
TermExplanation
Virtual MachineEquals the server resource in Nova.
Ephemeral StorageDisk storage directly supplied to a virtual machine by Nova. Different from volumes.
(Glance) ImageIaaS resource usually storing raw disk data. Managed by the Glance service.
(Cinder) VolumeIaaS resource representing block storage disk that can be attached as a virtual disk to virtual machines. Managed by the Cinder service.
(Volume) SnapshotThinly-provisioned copy-on-write snapshots of volumes. Stored in the same Cinder storage backend as volumes.
Volume TypeAttribute of volumes determining storage details of a volume such as backend location or whether the volume will be encrypted.
(Barbican) SecretIaaS resource storing cryptographic assets such as encryption keys. Managed by the Barbican service.
+

Scope

+

User data in the context of this guide describes data accumulated in cloud resources of a user at runtime. +This concerns primarily storage data of virtual machines stored at at-rest. +This does not cover in-transit or in-use data such as network traffic, virtual machines' RAM contents or IaaS configuration and metadata of cloud resources.

+

Overview of applicable User Data

+

Given the mentioned scope, the following can be classified as user data:

+
    +
  • images stored in Glance
  • +
  • virtual machine disks, either: +
      +
    • Ephemeral Storage stored in Nova
    • +
    • volumes stored in Cinder
    • +
    +
  • +
  • encryption keys stored as secrets in Barbican
  • +
+

The following sections will describe backup procedures for each of those resources individually.

+

Image backup using download

+

Glance images may act as backup targets for other resources (such as volumes) but don't have a dedicated backup service for themselves.

+

When an image is to be backed up, it can be downloaded from the Glance image service and stored outside of the IaaS infrastructure for backup purposes. +In this case it is the user's responsibility to establish the backup procedure and appropriate target storage.

+
caution

When creating images from volumes with a volume type that uses encryption, the resulting image will contain the raw LUKS-encrypted blocks of the volume. +When transferred outside of the IaaS infrastructure, this data is only useful as a backup together with the corresponding encryption key.

Such images can be identified by an attribute called cinder_encryption_key_id in the properties metadata field of the image. +It only exists for encrypted images and references the encryption key in Barbican. +Refer to the Barbican secrets section for instructions on how to backup the key.

+

The API or the OpenStack client may be used to initiate the download, for example:

+
openstack image save --file $TARGET_FILE_PATH $IMAGE_NAME_OR_ID
+

This or the underlying API request may be automated as part of a regular backup schedule involving the backup storage target on the user side.

+

Ephemeral Storage backup using Glance images

+
caution

When using the createImage Compute API action (e.g. via the openstack server image create command) on a virtual machine that has volumes attached to it in addition to its Ephemeral Storage disk, the volumes will not be backed up into the image. Instead, a snapshot will be created for each attached volume and referenced in the image metadata. This does not replace genuine volume backups.

See the corresponding appendix section for further details.

+

Ephemeral Storage disks of virtual machines can be backed up to Glance images easily by using the createImage Compute API action or the corresponding OpenStack client command:

+
openstack server image create --name $IMAGE_NAME $SERVER_NAME_OR_ID
+

This will create a Glance image containing a one-to-one copy of the data on the Ephemeral Storage disk at the time of execution.

+

If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.

+

Volume data backup using Cinder Backup API

+

The following instructions only apply if the infrastructure offers the Cinder Backup API.

+
note

Backups of volumes using a volume type that uses encryption will retain their encryption and a clone of the original encryption key is created in Barbican linked to the backup. +These backups can only be restored when the Barbican service is available and still has the corresponding copy of the encryption key.

Also, it is advised to take note of the exact volume type when creating a backup of an encrypted volume, because this information will be needed to restore the backup. +See restoring an encrypted volume backup.

+
info

It might be difficult or even impossible for a user to transfer backups created by the Cinder Backup API outside of the IaaS infrastructure, depending on the backup backend. +A more easily accessible backup of volumes can be created by using Glance images. +See the section about volume data backup using Glance images for details.

+

Backup of detached volumes

+

Backups can be created using the Cinder Backup API or the corresponding OpenStack client commands:

+
openstack volume backup create $VOLUME_NAME_OR_ID
+

Further backups of the same volume can subsequently be created as incremental backups using the following command:

+
openstack volume backup create --incremental $VOLUME_NAME_OR_ID
+

Backup of attached volumes

+
note

When creating backups of attached (in-use) volumes, the state of the full volume is captured at runtime. Backups created this way will be crash-consistent but not app-consistent.

+

In case of attached (in-use) volumes, backups can only be created while also specfiying the force parameter:

+
openstack volume backup create --force $VOLUME_NAME_OR_ID
+

Further backups of the same volume can subsequently be created as incremental backups using the following command:

+
openstack volume backup create --force --incremental $VOLUME_NAME_OR_ID
+

Volume data backup using Glance images

+

In case the Cinder Backup storage is not available in the IaaS infrastructure, Glance images can be used as a backup target instead. +Such images may also subsequently be downloaded to transfer the backup outside of the IaaS infrastructure.

+
note

Glance image backups of Cinder volumes only allow full backup copies and do not offer incremental or differential backup mechanisms.

+

Glance image backups of detached volumes

+

Volumes not attached to virtual machines can be directly copied into an image. +Such volumes can be identified by their status being available. +To backup a detached volume to a Glance image, directly use the corresponding image creation action:

+
openstack image create --volume $VOLUME_NAME_OR_ID $IMAGE_NAME
+

After the image creation has finished, a full backup copy of the volume will reside in the Glance storage backend.

+

If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.

+

Glance image backups of attached (in-use) volumes

+

Cinder is unable to directly create Glance images from volumes which are attached to virtual machines. +To create backups of such volumes regardless, a detour using volume snapshots can be used which will be described below.

+
note

When creating snapshots of attached (in-use) volumes, the force parameter has to be used. These snapshots capture a state of the full volume at runtime. They will be crash-consistent but not app-consistent.

+
    +
  1. Create a snapshot of the target volume while including the force parameter in the request: +
      +
    • openstack volume snapshot create --volume $VOLUME_NAME_OR_ID $SNAPSHOT_NAME
    • +
    +
  2. +
  3. Create a new temporary volume based on the snapshot to act as backup source: +
      +
    • openstack volume create --snapshot $SNAPSHOT_NAME $TEMP_VOLUME_NAME
    • +
    +
  4. +
  5. Wait until the volume creation is finished and the temporary volume reaches the available status.
  6. +
  7. Create a backup image of the temporary volume: +
      +
    • openstack image create --volume $TEMP_VOLUME_NAME $IMAGE_NAME
    • +
    +
  8. +
  9. Wait until the image creation finishes and the target image reaches the active status.
  10. +
  11. Delete the temporary volume and snapshot: +
      +
    • openstack volume delete $TEMP_VOLUME_NAME
    • +
    • openstack volume snapshot delete $SNAPSHOT_NAME
    • +
    +
  12. +
+

A full backup copy of the volume now resides in the Glance storage backend.

+

If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.

+

Barbican secrets backup using download

+
danger

Secrets downloaded from Barbican will be in plaintext, which means that the secret is unprotected once received from the API. +Before downloading secrets from Barbican make sure that a secure target environment is established for receiving and securely storing the secret's contents.

+

Barbican secrets can be downloaded in plaintext using the corresponding API or client command:

+
openstack secret get --file $TARGET_FILE_PATH --payload_content_type "application/octet-stream" $SECRET_ID
+
tip

In case the secret needs to be restored into an OpenStack Barbican later on, it is recommended to also note down the following attributes shown by openstack secret get $SECRET_ID:

    +
  • Algorithm
  • +
  • Bit length
  • +
  • Secret type
  • +
  • Mode
  • +
+

Retrieving encryption keys from Barbican

+

In case of encrypted volumes (i.e. using a volume type with encryption), a corresponding encryption key is stored in Barbican. +When an image is created from such a volume, the encryption key is duplicated in Barbican for the image. +In order to backup those keys, the corresponding secret must first be identified.

+

For volumes, this is possible starting with the Volume API microversion 3.64:

+
openstack volume show --os-volume-api-version 3.64 $VOLUME_NAME_OR_ID
+

The response will contain an encryption_key_id field with the ID of the Barbican secret.

+

For images, the secret reference is stored in the properties field instead:

+
openstack image show -f value -c properties $IMAGE_NAME_OR_ID
+

In case of images created from encrypted volumes, the resulting output will have a nested cinder_encryption_key_id field that contains the ID of the Barbican secret.

+

The resulting IDs can be used to retrieve the corresponding key using the Barbican instructions above.

+
caution

Note that the key retrieved from the secret is not immediately usable as LUKS passphrase to the image data of the volume. +OpenStack does some processing to the key before it is passed to the LUKS encryption, which must be mimicked accordingly in order to unlock the encryption outside of OpenStack!

See the example procedure for converting the LUKS key in the appendix section.

+

Restore

+

The following sections will illustrate how to restore the individual resource backups that have been documented above.

+

Restoring a backup of a Barbican secret

+
note

Note that restoring a Barbican secret by re-uploading it via the Barbican API will lead to the secret receiving a new ID. +Existing resources referencing an old secret ID cannot make use of the restored copy.

+
openstack secret store --algorithm aes --bit-length 256 --mode cbc \
--secret-type symmetric --file $KEY_FILE_PATH --name $SECRET_NAME
+

Notes:

+
    +
  • Attributes like algorithm, bit length, mode and secret type are not verified by Barbican. Their main purpose is to classify the secret on a metadata level. Make sure to align the attributes with the original secret.
  • +
  • $KEY_FILE_PATH is the local file path of the secret backup as created originally using the instructions above.
  • +
  • $SECRET_NAME is entirely optional but helps identifying the restored secret later on and to distinguish it from secrets created by OpenStack itself. It is best to not put whitespace characters in the name, otherwise it has to be surrounded by quotes.
  • +
+

The successful registration of the restored secret can subsequently be verified using:

+
openstack secret list --name $SECRET_NAME
+

Restoring a backup of an unencrypted image

+

Unencrypted image backups can simply be restored using the regular image upload functionality and specifying the backup file:

+
openstack image create --file $IMAGE_FILE_PATH $IMAGE_NAME
+
note

In case the original image backup was not based on a volume originally, the image may have had a non-default disk or container format. +In this case, add the command parameters --container-format and --disk-format to the command accordingly.

+

Restoring a backup of an encrypted image

+

The following section only applies to image backups that were originally created from images of encrypted volumes.

+

First, restore the corresponding secret of the image using the instructions above. +The restored secret will receive a new ID in the form of a UUID. +Note down the ID of the restored secret and insert it in place of $SECRET_ID in the command below.

+
openstack image create --file $IMAGE_FILE_PATH \
--property cinder_encryption_key_id=$SECRET_ID \
--property cinder_encryption_key_deletion_policy=on_image_deletion \
$IMAGE_NAME
+

The cinder_encryption_key_deletion_policy attribute is optional. +If not specified, the referenced secret will not be deleted on image deletion automatically. +In contrast, if set to on_image_deletion, the referenced secret will be deleted as soon as the image referencing it is deleted.

+

Restoring a volume backup from an image

+

To restore a volume from an image backup, simply use the volume creation action and specify the image as source.

+

Depending on whether the original volume the image was created from was encrypted or not, the target volume type might need to be specified accordingly. +Whether this is the case can be identified by inspecting the image's metadata using openstack image show $IMAGE_NAME_OR_ID and looking for a "cinder_encryption_key_id" field within "properties". +If it exists, the source volume of the image was encrypted.

+

To restore the image of an unencrypted volume:

+
openstack volume create --image $IMAGE_NAME_OR_ID \
--size $VOLUME_SIZE_IN_GB $VOLUME_NAME
+

To restore the image of an encrypted volume:

+
openstack volume create --image $IMAGE_NAME_OR_ID \
--type $ENCRYPTED_VOLUME_TYPE \
--size $VOLUME_SIZE_IN_GB $VOLUME_NAME
+

If restoring an encrypted image, make sure to specify $ENCRYPTED_VOLUME_TYPE correctly and have it reference a volume type which also supports the encryption. +Otherwise the volume will be unbootable or unusable by Nova instances.

+

Restoring a volume backup from the Cinder Backup service

+

The Cinder Backup service offers dedicated API actions and commands for restoring volume backups created using the service. +These backups can be restored in one of two ways:

+
    +
  1. Letting the Cinder Backup service create a new volume based on the backup.
  2. +
  3. Overwriting an existing volume with the backup data.
  4. +
+
note

If the volume backup was originally created from a volume that used a non-default encrypted volume type, letting Cinder Backup create a new volume for backup restoration does not work and the volume type must match exactly. +In such case provision an empty volume with the correct type first and then restore the backup onto it as explained further down.

+

Restoring to a new volume (Cinder Backup)

+
openstack volume backup restore $BACKUP_NAME_OR_ID $TARGET_NAME
+

... where $TARGET_NAME is the desired name of the new volume to be created. +Make sure that no volume with this name already exists. +The Cinder Backup service will create the volume with the same size as the backup indicates.

+

Restoring on an existing volume (Cinder Backup)

+

As an alternative to creating a new volume as the restore target, the backup can also be restored on an existing volume:

+
openstack volume backup restore --force $BACKUP_NAME_OR_ID $VOLUME_NAME_OR_ID
+

... which will overwrite the data on the existing volume, regardless of whether it is empty or not!

+

The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.

+

Restoring an encrypted volume backup (Cinder Backup)

+

When restoring a volume backup of a volume that was using a non-default encrypted volume type, a new volume of that type needs to be created first and then the backup restored onto it. +Otherwise, the restoration will fail with the target volume ending up in the "error_restoring" state. +For this procedure to succeed it is necessary to know the exact volume type of the volume the backup was created from.

+

If the source volume of the backup still exists, the original volume type can be determined by inspecting the backup's volume_id attribute and then using it to look up the corresponding volume and its type attribute. +The following client command can be used for this (fill in the value for BACKUP_ID):

+
export BACKUP_ID=...

SOURCE_VOLUME_ID="$(openstack volume backup show $BACKUP_ID -f value -c volume_id)"
openstack volume show -f value -c type "$SOURCE_VOLUME_ID"
+

This returns the name of the original volume type. +If the source volume does not exist anymore, rely on documentation about the backup to determine the type, if available.

+

First, create a new empty volume as the restore target and use the backup's size metadata attribute to match the size of the volume to the backup:

+
openstack volume create --size $BACKUP_SIZE --type $VOLUME_TYPE $TARGET_NAME
+

... where $TARGET_NAME is the desired name of the new volume.

+

Once the volume reaches "available" state, restore the backup onto it:

+
openstack volume backup restore --force $BACKUP_NAME_OR_ID $TARGET_NAME
+

The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.

+

Appendix

+

Image creation action for servers with attached volumes

+

When the createImage action of the Compute API (openstack server image create) is used on virtual machines that have at least one volume attached, a snapshot will be created for each attached volume individually and referenced in the resulting image's metadata.

+

This happens regardless of whether the virtual machine has an Ephemeral Storage disk attached. +In case of an Ephemeral Storage disk, only the Ephemeral Storage is copied into the Glance image as a 1:1 copy.

+

In case of a virtual machine that has no Ephemeral Storage but only volumes, the createImage action leads to a Glance image that only consists of metadata (including the resulting volume snapshot references) but carries no actual binary data.

+

Figure: createImage action flow involving Ephemeral Storage and/or volumes

+

LUKS encryption key conversion to decrypt volume images

+

The volume encryption keys stored in Barbican are not directly used as LUKS passphrases by OpenStack because they are in binary format. +OpenStack converts them to ASCII internally before passing them to the encryption layer. +This behavior needs to be reproduced if a decryption of a volume image is desired outside of OpenStack.

+
danger

The instructions below will expose plaintext data of encryption keys and encrypted volume images. +Make sure to only execute these steps in a secure and trusted environment.

+

First, download the image:

+
openstack image save --file image.raw $IMAGE_NAME_OR_ID
+

Next, inspect the image metadata, determine the reference to the encryption key (cinder_encryption_key_id property) and download the encryption key:

+
openstack image show -f value -c properties $IMAGE_NAME_OR_ID
# (use the value of `cinder_encryption_key_id` as `$SECRET_ID` below)
openstack secret get --file image.key --payload_content_type "application/octet-stream" $SECRET_ID
+

This will result in the following local files:

+
    +
  • image.raw = the raw encrypted image downloaded from Glance
  • +
  • image.key = the LUKS encryption key in binary format (plaintext)
  • +
+

Since OpenStack internally uses Python's binascii.hexlify() to convert the binary encryption key before passing it as a passphrase to the LUKS encryption, as a last step this conversion must be mimicked to unlock the encryption:

+
python3 -c "import binascii; \
f = open('image.key', 'rb'); \
print(binascii.hexlify(f.read()).decode('utf-8'))" \
| sudo cryptsetup luksOpen ./image.raw decrypted_image
+

The decrypted image is now accessible at /dev/mapper/decrypted_image. +Note that this is a live en-/decryption operation on the image.raw file. +The image is not converted, the encryption is simply unlocked in-memory using LUKS and dm-crypt until the encryption is closed again.

+

The /dev/mapper/decrypted_image can now be handled like a raw block device (e.g. mounted as a filesystem) or snapshotted in decrypted form.

+

To close the encryption execute:

+
sudo cryptsetup luksClose decrypted_image
+

The source of this document can be found in the SovereignCloudStack/docs repository.

+

Author: SCS Community, License: CC by Attribution 4.0 International

+ + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/security-groups/index.html b/docs/iaas/guides/user-guide/security-groups/index.html new file mode 100644 index 0000000000..a0d68ec16c --- /dev/null +++ b/docs/iaas/guides/user-guide/security-groups/index.html @@ -0,0 +1,105 @@ + + + + + +Best Practise: How to configure and use security groups | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Best Practise: How to configure and use security groups

+

Security groups in OpenStack are part of the network security mechanisms provided for the users. +They resemble sets of simple firewall rules allowing specific network traffic at a Port of a VM that connects it to a network. +The rules allow specific network port numbers and protocols while also differentiating between ingress and egress directions. +Usually security groups are assigned to the Port(s) when a virtual machine is created, but assignments can also be changed at runtime later on. +Multiple security groups can be assigned to a VM or Port simultaneously and in such case they will be combined as the union of all their rules.

+
caution

Security groups are mutable resources. +Their rules can be adjusted at any time after creation. +Changing the rules of a security group will immediately apply the changes to all Ports or VMs it is assigned to. +It is advisable to always review resources which use a security group before making changes to it.

+

Identify the requirements of your setup

+

Every virtual machine that is created may need different firewall rules. +These requirements can also change over time. +Adding or removing security groups will allow users to adapt the firewall rules specifically to their virtual machines.

+

To harden the firewall settings for your virtual machine you may follow these steps:

+
    +
  1. Before creating a virtual machine its purpose is usually already known. Use this information to identify all incoming and outgoing traffic rules that will be needed based on the communication patterns of the services it is meant to deploy. This includes communication protocols, port numbers, communication directions and optionally target/source address ranges.
  2. +
  3. Look through already existing security groups and their rules. If a security group allows more traffic than needed it SHOULD NOT be used. If a security group contains only a subset of the required rules it MAY be used in combination with other security groups that contain rules which fulfill the remaining required traffic rules from point 1.
  4. +
  5. If you were not successful in finding an appropriate combination of existing security groups or you need additional specific rules to cover all requirements, you MAY create one or more new Security Groups in which you can add the required rules.
  6. +
  7. After ensuring the existence of one or more security groups that fulfill your requirements, you can create the VM with those security groups already specified in the creation command.
  8. +
+

Further security considerations

+

When implementing network security requirements, firewall rules alone are not always sufficient and might need to be augmented with additional configuration or time-based constraints. Notable examples are:

+

SSH +SSH is needed on many virtual machines to operate their guest operating system. +In a security group the port 22 can be opened for the TCP protocol to allow incoming SSH connections. +But that only should be done while also restricting the SSH configuration to public key authentication only (the recommended way) or having a strong username and password policy already applied to the operating system of the virtual machine. +Otherwise default usernames and passwords which are often preconfigured in system images may be exploited through the exposed SSH port which enables attackers to compromise the virtual machine.

+

ICMP +It might be useful to be able to ping a virtual machine or use other ICMP requests. +But for some virtual machine configurations this is either not necessary at all or only temporarily needed. +One benefit of security groups among other things is the ability to be easily added to and removed from existing virtual machines. +So a dedicated security group allowing ICMP could be added temporarily to a virtual machine for debugging purposes and removed from it afterwards.

+

How to create security groups

+

Security groups are managed within a project. +So every project will have a different set of security groups. +They can be added dynamically to each virtual machine, during their creation or afterwards. +Additionally, they may also be removed from VMs at any point.

+

Every project has its own default security group, which rules can be edited. +Additionally other security groups can be added until the project's quota is exhausted. +To add a security group, use the following command:

+
openstack security group create $SECURITY_GROUP
+

Within every security group rules can be added up unto a defined maximum of rules, that usually is about 100. +Rules can be added to security groups with the following command:

+
openstack security group rule create [...] $SECURITY_GROUP
+

To delete rules from a security group, the rule id has to be used. +It is listed in the details of the rules section of the security group.

+
openstack security group rule delete $RULE_ID
+

Default security group

+

Unless specified otherwise, the default security group is assigned to all VMs or Ports at creation. +To use any other than the default security group at creation it is necessary to specify the desired security group(s) during the creation process.

+

To review which rules are defined in a security group, the following command can be used:

+
openstack security group show default
+ +

While projects can use very different aspects in security group rules and thus the security groups will always differ between projects, there are some security groups that are widely used. +Through the nature of security groups being seen as a set of rules that can be combined, having some basic security groups that allow basic protocols is a commonly used setup. +This section will demonstrate how to create some security groups for commonly used protocols and ports.

+
    +
  1. A security groups, that allows incoming SSH traffic:
  2. +
+
openstack security group create ssh
openstack security group rule create --ingress --protocol tcp --dst-port 22 ssh
+
    +
  1. A security group, that allows incoming HTTP requests:
  2. +
+
openstack security group create http
openstack security group rule create --ingress --protocol tcp --dst-port 80 http
+
    +
  1. A security group, that allows incoming HTTPS requests:
  2. +
+
openstack security group create https
openstack security group rule create --ingress --protocol tcp --dst-port 443 https
+
    +
  1. A security group, that allows incoming ICMP requests:
  2. +
+
openstack security group create icmp
openstack security group rule create --protocol icmp icmp
+

How to use security groups

+
info

Security groups can be assigned to multiple resources simultaneously (such as VMs or Ports). +This means that security groups are reusable and don't need to be recreated for each applicable resource individually.

+

Usually, initial security groups are added at the time of the creation of a VM. +During creation, multiple security groups can also be added at the same time by repeating the --security-group argument:

+
openstack server create [...] --security-group $SECURITY_GROUP_1 --security-group $SECURITY_GROUP_2 $SERVER_NAME
+

To add a security group to an existing VM, the following command can be used:

+
openstack server add security group $SERVER_NAME $SECURITY_GROUP
+

To remove a security group from a VM, the following command can be used:

+
openstack server remove security group $SERVER_NAME $SECURITY_GROUP
+ + \ No newline at end of file diff --git a/docs/iaas/guides/user-guide/user-data-backups/index.html b/docs/iaas/guides/user-guide/user-data-backups/index.html new file mode 100644 index 0000000000..962a7bedc8 --- /dev/null +++ b/docs/iaas/guides/user-guide/user-data-backups/index.html @@ -0,0 +1,248 @@ + + + + + +User Data Backups | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

User Data Backups

+

This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.

+

Glossary

+
TermExplanation
Virtual MachineEquals the server resource in Nova.
Ephemeral StorageDisk storage directly supplied to a virtual machine by Nova. Different from volumes.
(Glance) ImageIaaS resource usually storing raw disk data. Managed by the Glance service.
(Cinder) VolumeIaaS resource representing block storage disk that can be attached as a virtual disk to virtual machines. Managed by the Cinder service.
(Volume) SnapshotThinly-provisioned copy-on-write snapshots of volumes. Stored in the same Cinder storage backend as volumes.
Volume TypeAttribute of volumes determining storage details of a volume such as backend location or whether the volume will be encrypted.
(Barbican) SecretIaaS resource storing cryptographic assets such as encryption keys. Managed by the Barbican service.
+

Scope

+

User data in the context of this guide describes data accumulated in cloud resources of a user at runtime. +This concerns primarily storage data of virtual machines stored at at-rest. +This does not cover in-transit or in-use data such as network traffic, virtual machines' RAM contents or IaaS configuration and metadata of cloud resources.

+

Overview of applicable User Data

+

Given the mentioned scope, the following can be classified as user data:

+
    +
  • images stored in Glance
  • +
  • virtual machine disks, either: +
      +
    • Ephemeral Storage stored in Nova
    • +
    • volumes stored in Cinder
    • +
    +
  • +
  • encryption keys stored as secrets in Barbican
  • +
+

The following sections will describe backup procedures for each of those resources individually.

+

Image backup using download

+

Glance images may act as backup targets for other resources (such as volumes) but don't have a dedicated backup service for themselves.

+

When an image is to be backed up, it can be downloaded from the Glance image service and stored outside of the IaaS infrastructure for backup purposes. +In this case it is the user's responsibility to establish the backup procedure and appropriate target storage.

+
caution

When creating images from volumes with a volume type that uses encryption, the resulting image will contain the raw LUKS-encrypted blocks of the volume. +When transferred outside of the IaaS infrastructure, this data is only useful as a backup together with the corresponding encryption key.

Such images can be identified by an attribute called cinder_encryption_key_id in the properties metadata field of the image. +It only exists for encrypted images and references the encryption key in Barbican. +Refer to the Barbican secrets section for instructions on how to backup the key.

+

The API or the OpenStack client may be used to initiate the download, for example:

+
openstack image save --file $TARGET_FILE_PATH $IMAGE_NAME_OR_ID
+

This or the underlying API request may be automated as part of a regular backup schedule involving the backup storage target on the user side.

+

Ephemeral Storage backup using Glance images

+
caution

When using the createImage Compute API action (e.g. via the openstack server image create command) on a virtual machine that has volumes attached to it in addition to its Ephemeral Storage disk, the volumes will not be backed up into the image. Instead, a snapshot will be created for each attached volume and referenced in the image metadata. This does not replace genuine volume backups.

See the corresponding appendix section for further details.

+

Ephemeral Storage disks of virtual machines can be backed up to Glance images easily by using the createImage Compute API action or the corresponding OpenStack client command:

+
openstack server image create --name $IMAGE_NAME $SERVER_NAME_OR_ID
+

This will create a Glance image containing a one-to-one copy of the data on the Ephemeral Storage disk at the time of execution.

+

If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.

+

Volume data backup using Cinder Backup API

+

The following instructions only apply if the infrastructure offers the Cinder Backup API.

+
note

Backups of volumes using a volume type that uses encryption will retain their encryption and a clone of the original encryption key is created in Barbican linked to the backup. +These backups can only be restored when the Barbican service is available and still has the corresponding copy of the encryption key.

Also, it is advised to take note of the exact volume type when creating a backup of an encrypted volume, because this information will be needed to restore the backup. +See restoring an encrypted volume backup.

+
info

It might be difficult or even impossible for a user to transfer backups created by the Cinder Backup API outside of the IaaS infrastructure, depending on the backup backend. +A more easily accessible backup of volumes can be created by using Glance images. +See the section about volume data backup using Glance images for details.

+

Backup of detached volumes

+

Backups can be created using the Cinder Backup API or the corresponding OpenStack client commands:

+
openstack volume backup create $VOLUME_NAME_OR_ID
+

Further backups of the same volume can subsequently be created as incremental backups using the following command:

+
openstack volume backup create --incremental $VOLUME_NAME_OR_ID
+

Backup of attached volumes

+
note

When creating backups of attached (in-use) volumes, the state of the full volume is captured at runtime. Backups created this way will be crash-consistent but not app-consistent.

+

In case of attached (in-use) volumes, backups can only be created while also specfiying the force parameter:

+
openstack volume backup create --force $VOLUME_NAME_OR_ID
+

Further backups of the same volume can subsequently be created as incremental backups using the following command:

+
openstack volume backup create --force --incremental $VOLUME_NAME_OR_ID
+

Volume data backup using Glance images

+

In case the Cinder Backup storage is not available in the IaaS infrastructure, Glance images can be used as a backup target instead. +Such images may also subsequently be downloaded to transfer the backup outside of the IaaS infrastructure.

+
note

Glance image backups of Cinder volumes only allow full backup copies and do not offer incremental or differential backup mechanisms.

+

Glance image backups of detached volumes

+

Volumes not attached to virtual machines can be directly copied into an image. +Such volumes can be identified by their status being available. +To backup a detached volume to a Glance image, directly use the corresponding image creation action:

+
openstack image create --volume $VOLUME_NAME_OR_ID $IMAGE_NAME
+

After the image creation has finished, a full backup copy of the volume will reside in the Glance storage backend.

+

If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.

+

Glance image backups of attached (in-use) volumes

+

Cinder is unable to directly create Glance images from volumes which are attached to virtual machines. +To create backups of such volumes regardless, a detour using volume snapshots can be used which will be described below.

+
note

When creating snapshots of attached (in-use) volumes, the force parameter has to be used. These snapshots capture a state of the full volume at runtime. They will be crash-consistent but not app-consistent.

+
    +
  1. Create a snapshot of the target volume while including the force parameter in the request: +
      +
    • openstack volume snapshot create --volume $VOLUME_NAME_OR_ID $SNAPSHOT_NAME
    • +
    +
  2. +
  3. Create a new temporary volume based on the snapshot to act as backup source: +
      +
    • openstack volume create --snapshot $SNAPSHOT_NAME $TEMP_VOLUME_NAME
    • +
    +
  4. +
  5. Wait until the volume creation is finished and the temporary volume reaches the available status.
  6. +
  7. Create a backup image of the temporary volume: +
      +
    • openstack image create --volume $TEMP_VOLUME_NAME $IMAGE_NAME
    • +
    +
  8. +
  9. Wait until the image creation finishes and the target image reaches the active status.
  10. +
  11. Delete the temporary volume and snapshot: +
      +
    • openstack volume delete $TEMP_VOLUME_NAME
    • +
    • openstack volume snapshot delete $SNAPSHOT_NAME
    • +
    +
  12. +
+

A full backup copy of the volume now resides in the Glance storage backend.

+

If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.

+

Barbican secrets backup using download

+
danger

Secrets downloaded from Barbican will be in plaintext, which means that the secret is unprotected once received from the API. +Before downloading secrets from Barbican make sure that a secure target environment is established for receiving and securely storing the secret's contents.

+

Barbican secrets can be downloaded in plaintext using the corresponding API or client command:

+
openstack secret get --file $TARGET_FILE_PATH --payload_content_type "application/octet-stream" $SECRET_ID
+
tip

In case the secret needs to be restored into an OpenStack Barbican later on, it is recommended to also note down the following attributes shown by openstack secret get $SECRET_ID:

    +
  • Algorithm
  • +
  • Bit length
  • +
  • Secret type
  • +
  • Mode
  • +
+

Retrieving encryption keys from Barbican

+

In case of encrypted volumes (i.e. using a volume type with encryption), a corresponding encryption key is stored in Barbican. +When an image is created from such a volume, the encryption key is duplicated in Barbican for the image. +In order to backup those keys, the corresponding secret must first be identified.

+

For volumes, this is possible starting with the Volume API microversion 3.64:

+
openstack volume show --os-volume-api-version 3.64 $VOLUME_NAME_OR_ID
+

The response will contain an encryption_key_id field with the ID of the Barbican secret.

+

For images, the secret reference is stored in the properties field instead:

+
openstack image show -f value -c properties $IMAGE_NAME_OR_ID
+

In case of images created from encrypted volumes, the resulting output will have a nested cinder_encryption_key_id field that contains the ID of the Barbican secret.

+

The resulting IDs can be used to retrieve the corresponding key using the Barbican instructions above.

+
caution

Note that the key retrieved from the secret is not immediately usable as LUKS passphrase to the image data of the volume. +OpenStack does some processing to the key before it is passed to the LUKS encryption, which must be mimicked accordingly in order to unlock the encryption outside of OpenStack!

See the example procedure for converting the LUKS key in the appendix section.

+

Restore

+

The following sections will illustrate how to restore the individual resource backups that have been documented above.

+

Restoring a backup of a Barbican secret

+
note

Note that restoring a Barbican secret by re-uploading it via the Barbican API will lead to the secret receiving a new ID. +Existing resources referencing an old secret ID cannot make use of the restored copy.

+
openstack secret store --algorithm aes --bit-length 256 --mode cbc \
--secret-type symmetric --file $KEY_FILE_PATH --name $SECRET_NAME
+

Notes:

+
    +
  • Attributes like algorithm, bit length, mode and secret type are not verified by Barbican. Their main purpose is to classify the secret on a metadata level. Make sure to align the attributes with the original secret.
  • +
  • $KEY_FILE_PATH is the local file path of the secret backup as created originally using the instructions above.
  • +
  • $SECRET_NAME is entirely optional but helps identifying the restored secret later on and to distinguish it from secrets created by OpenStack itself. It is best to not put whitespace characters in the name, otherwise it has to be surrounded by quotes.
  • +
+

The successful registration of the restored secret can subsequently be verified using:

+
openstack secret list --name $SECRET_NAME
+

Restoring a backup of an unencrypted image

+

Unencrypted image backups can simply be restored using the regular image upload functionality and specifying the backup file:

+
openstack image create --file $IMAGE_FILE_PATH $IMAGE_NAME
+
note

In case the original image backup was not based on a volume originally, the image may have had a non-default disk or container format. +In this case, add the command parameters --container-format and --disk-format to the command accordingly.

+

Restoring a backup of an encrypted image

+

The following section only applies to image backups that were originally created from images of encrypted volumes.

+

First, restore the corresponding secret of the image using the instructions above. +The restored secret will receive a new ID in the form of a UUID. +Note down the ID of the restored secret and insert it in place of $SECRET_ID in the command below.

+
openstack image create --file $IMAGE_FILE_PATH \
--property cinder_encryption_key_id=$SECRET_ID \
--property cinder_encryption_key_deletion_policy=on_image_deletion \
$IMAGE_NAME
+

The cinder_encryption_key_deletion_policy attribute is optional. +If not specified, the referenced secret will not be deleted on image deletion automatically. +In contrast, if set to on_image_deletion, the referenced secret will be deleted as soon as the image referencing it is deleted.

+

Restoring a volume backup from an image

+

To restore a volume from an image backup, simply use the volume creation action and specify the image as source.

+

Depending on whether the original volume the image was created from was encrypted or not, the target volume type might need to be specified accordingly. +Whether this is the case can be identified by inspecting the image's metadata using openstack image show $IMAGE_NAME_OR_ID and looking for a "cinder_encryption_key_id" field within "properties". +If it exists, the source volume of the image was encrypted.

+

To restore the image of an unencrypted volume:

+
openstack volume create --image $IMAGE_NAME_OR_ID \
--size $VOLUME_SIZE_IN_GB $VOLUME_NAME
+

To restore the image of an encrypted volume:

+
openstack volume create --image $IMAGE_NAME_OR_ID \
--type $ENCRYPTED_VOLUME_TYPE \
--size $VOLUME_SIZE_IN_GB $VOLUME_NAME
+

If restoring an encrypted image, make sure to specify $ENCRYPTED_VOLUME_TYPE correctly and have it reference a volume type which also supports the encryption. +Otherwise the volume will be unbootable or unusable by Nova instances.

+

Restoring a volume backup from the Cinder Backup service

+

The Cinder Backup service offers dedicated API actions and commands for restoring volume backups created using the service. +These backups can be restored in one of two ways:

+
    +
  1. Letting the Cinder Backup service create a new volume based on the backup.
  2. +
  3. Overwriting an existing volume with the backup data.
  4. +
+
note

If the volume backup was originally created from a volume that used a non-default encrypted volume type, letting Cinder Backup create a new volume for backup restoration does not work and the volume type must match exactly. +In such case provision an empty volume with the correct type first and then restore the backup onto it as explained further down.

+

Restoring to a new volume (Cinder Backup)

+
openstack volume backup restore $BACKUP_NAME_OR_ID $TARGET_NAME
+

... where $TARGET_NAME is the desired name of the new volume to be created. +Make sure that no volume with this name already exists. +The Cinder Backup service will create the volume with the same size as the backup indicates.

+

Restoring on an existing volume (Cinder Backup)

+

As an alternative to creating a new volume as the restore target, the backup can also be restored on an existing volume:

+
openstack volume backup restore --force $BACKUP_NAME_OR_ID $VOLUME_NAME_OR_ID
+

... which will overwrite the data on the existing volume, regardless of whether it is empty or not!

+

The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.

+

Restoring an encrypted volume backup (Cinder Backup)

+

When restoring a volume backup of a volume that was using a non-default encrypted volume type, a new volume of that type needs to be created first and then the backup restored onto it. +Otherwise, the restoration will fail with the target volume ending up in the "error_restoring" state. +For this procedure to succeed it is necessary to know the exact volume type of the volume the backup was created from.

+

If the source volume of the backup still exists, the original volume type can be determined by inspecting the backup's volume_id attribute and then using it to look up the corresponding volume and its type attribute. +The following client command can be used for this (fill in the value for BACKUP_ID):

+
export BACKUP_ID=...

SOURCE_VOLUME_ID="$(openstack volume backup show $BACKUP_ID -f value -c volume_id)"
openstack volume show -f value -c type "$SOURCE_VOLUME_ID"
+

This returns the name of the original volume type. +If the source volume does not exist anymore, rely on documentation about the backup to determine the type, if available.

+

First, create a new empty volume as the restore target and use the backup's size metadata attribute to match the size of the volume to the backup:

+
openstack volume create --size $BACKUP_SIZE --type $VOLUME_TYPE $TARGET_NAME
+

... where $TARGET_NAME is the desired name of the new volume.

+

Once the volume reaches "available" state, restore the backup onto it:

+
openstack volume backup restore --force $BACKUP_NAME_OR_ID $TARGET_NAME
+

The volume will enter the "restoring-backup" state temporarily and will return to the "available" state again once the restore process has finished.

+

Appendix

+

Image creation action for servers with attached volumes

+

When the createImage action of the Compute API (openstack server image create) is used on virtual machines that have at least one volume attached, a snapshot will be created for each attached volume individually and referenced in the resulting image's metadata.

+

This happens regardless of whether the virtual machine has an Ephemeral Storage disk attached. +In case of an Ephemeral Storage disk, only the Ephemeral Storage is copied into the Glance image as a 1:1 copy.

+

In case of a virtual machine that has no Ephemeral Storage but only volumes, the createImage action leads to a Glance image that only consists of metadata (including the resulting volume snapshot references) but carries no actual binary data.

+

Figure: createImage action flow involving Ephemeral Storage and/or volumes

+

LUKS encryption key conversion to decrypt volume images

+

The volume encryption keys stored in Barbican are not directly used as LUKS passphrases by OpenStack because they are in binary format. +OpenStack converts them to ASCII internally before passing them to the encryption layer. +This behavior needs to be reproduced if a decryption of a volume image is desired outside of OpenStack.

+
danger

The instructions below will expose plaintext data of encryption keys and encrypted volume images. +Make sure to only execute these steps in a secure and trusted environment.

+

First, download the image:

+
openstack image save --file image.raw $IMAGE_NAME_OR_ID
+

Next, inspect the image metadata, determine the reference to the encryption key (cinder_encryption_key_id property) and download the encryption key:

+
openstack image show -f value -c properties $IMAGE_NAME_OR_ID
# (use the value of `cinder_encryption_key_id` as `$SECRET_ID` below)
openstack secret get --file image.key --payload_content_type "application/octet-stream" $SECRET_ID
+

This will result in the following local files:

+
    +
  • image.raw = the raw encrypted image downloaded from Glance
  • +
  • image.key = the LUKS encryption key in binary format (plaintext)
  • +
+

Since OpenStack internally uses Python's binascii.hexlify() to convert the binary encryption key before passing it as a passphrase to the LUKS encryption, as a last step this conversion must be mimicked to unlock the encryption:

+
python3 -c "import binascii; \
f = open('image.key', 'rb'); \
print(binascii.hexlify(f.read()).decode('utf-8'))" \
| sudo cryptsetup luksOpen ./image.raw decrypted_image
+

The decrypted image is now accessible at /dev/mapper/decrypted_image. +Note that this is a live en-/decryption operation on the image.raw file. +The image is not converted, the encryption is simply unlocked in-memory using LUKS and dm-crypt until the encryption is closed again.

+

The /dev/mapper/decrypted_image can now be handled like a raw block device (e.g. mounted as a filesystem) or snapshotted in decrypted form.

+

To close the encryption execute:

+
sudo cryptsetup luksClose decrypted_image
+ + \ No newline at end of file diff --git a/docs/iaas/overview/architecture/index.html b/docs/iaas/overview/architecture/index.html new file mode 100644 index 0000000000..512cae4f13 --- /dev/null +++ b/docs/iaas/overview/architecture/index.html @@ -0,0 +1,24 @@ + + + + + +Architecture | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/overview/compute/index.html b/docs/iaas/overview/compute/index.html new file mode 100644 index 0000000000..e8166f6013 --- /dev/null +++ b/docs/iaas/overview/compute/index.html @@ -0,0 +1,24 @@ + + + + + +Compute | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/overview/knowledge/index.html b/docs/iaas/overview/knowledge/index.html new file mode 100644 index 0000000000..19bb447b92 --- /dev/null +++ b/docs/iaas/overview/knowledge/index.html @@ -0,0 +1,24 @@ + + + + + +Knowledge | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/overview/network/index.html b/docs/iaas/overview/network/index.html new file mode 100644 index 0000000000..5ec16aa692 --- /dev/null +++ b/docs/iaas/overview/network/index.html @@ -0,0 +1,24 @@ + + + + + +Network | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iaas/overview/storage/index.html b/docs/iaas/overview/storage/index.html new file mode 100644 index 0000000000..f578cf342a --- /dev/null +++ b/docs/iaas/overview/storage/index.html @@ -0,0 +1,24 @@ + + + + + +Storage | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/iam/SCS-example-setup-configuration-description/index.html b/docs/iam/SCS-example-setup-configuration-description/index.html new file mode 100644 index 0000000000..104ec5ed33 --- /dev/null +++ b/docs/iam/SCS-example-setup-configuration-description/index.html @@ -0,0 +1,49 @@ + + + + + +Example setup configuration in SCS deployment explained | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Example setup configuration in SCS deployment explained

+

The following document explains the idea behind the example configuration is done. +The playbook creates a proxy realm used to connect with Keystone, a customer realm, the clients needed to connect the realms, the identity brokering for the customer realm, a login flow +to be able to use the home-IdP-discovery plugin to redirect to the correct customer realm and an example user. +SCS operators can find the playbook that creates the setup here.

+
    +
  1. +

    In the first place a proxy realm called osism on the example deployment. That realm will +become the realm that will be conected to Keystone

    +
  2. +
  3. +

    A customer realm called CustomerA is created. On that realm a OIDC client is created to hook +up the realm to the proxy realm. This is done via Identity Brokering in the proxy realm.

    +
  4. +
  5. +

    An Identity provider is configured in the osism realm, this is configured to be connected to +the CustomerA realm. For that, a set of mappers are created, the default ones are a hardcoded-attribute +that sets the domain where the user came from, and an attribute-importer mapper for the openstack-default-project that comes +in the OIDC claim from the customer realm.

    +
  6. +
  7. +

    A new login flow has been created in the osism realm, this login flow is needed to use the home-IdP-discovery plugin.

    +
  8. +
  9. +

    Creation of an example user called Alice.

    +
  10. +
+ + \ No newline at end of file diff --git a/docs/iam/domain-manager-setup-and-usage/index.html b/docs/iam/domain-manager-setup-and-usage/index.html new file mode 100644 index 0000000000..2ce4c42297 --- /dev/null +++ b/docs/iam/domain-manager-setup-and-usage/index.html @@ -0,0 +1,144 @@ + + + + + +Domain Manager setup and usage | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Domain Manager setup and usage

+
info

The following documentation refers to a SCS standard that is still in draft state. +It is not meant for productive use yet but CSPs are encouraged to test-drive and provide feedback!

+

Preface

+

SCS defines the Domain Manager standard, introducing a special persona to the OpenStack Keystone identity manager. +This persona offers a properly domain-scoped permission set to manage users, groups, projects and role assignments within a domain. +Its intended use case is to offer extensive identity management self-service capabilities to tenants mapped to a domain.

+

This guide will explain setup, configuration and usage of the SCS Domain Manager standard.

+

Warning regarding the exposure of domain names

+

Due to architectural limitations currently existing in OpenStack Keystone, assigning the manager role to users while the configuration of the SCS Domain Manager standard has been applied will enable them to see the IDs and names of all existing domains. +This includes domains other than their own, meaning that other tenant's identities might be exposed depending on the relation between them and the name of their domain. +CSPs aiming to appoint Domain Manager users must be aware of this limitation and should exclusively use pseudonymized domain names across the whole infrastructure. +If CSPs strictly follow the SCS naming conventions for domains this is already addressed. +If this is not feasible for the CSP, they may opt to refrain from making use of the Domain Manager functionality at all, i.e. never assign the manager role to tenant users.

+
info

This architectural limitation will be fixed in upcoming OpenStack and SCS releases.

See https://bugs.launchpad.net/keystone/+bug/2041611

+

Infrastructure configuration

+

An initial infrastructure configuration of the Domain Manager persona must be completed before it can be used. +This includes adjusting the Keystone API policy configuration and the registration of the manager role.

+

The following sections describe the configuration to be implemented on the infrastructure-level. +This requires infrastructure access and OpenStack admin rights. +For tasks marked with "[Initial]" the described procedure only has to happen once initially. +For tasks marked with "[Runtime]" the described procedure may be repeated later on to make adjustments.

+

[Initial] Keystone API policy adjustments

+

First, incorporate the Keystone API policy definitions as described in the SCS Domain Manager standard. +This is usually done in "/etc/keystone/policy.yaml" of the Keystone API service. +Otherwise, an entry called "policy_file" under the "[oslo_policy]" section of "/etc/keystone/keystone.conf" might exist that points to a different policy file path. +In such case, adjust or create the file at the specified path.

+

When incorporating the policy definitions from the standard make sure to properly merge it with existing policy definitions, if any exist. +Also choose the definition of manageable roles in the "is_domain_managed_role" rule of the policy carefully according to your requirements and environment. +See the standard for more details on this rule.

+

Depending on the deployment method used, the adjustments may also need to be persisted in the corresponding infrastructure management solution, such as Ansible.

+

[Initial] Keystone role creation

+

The role manager has to exist in Keystone. +If the role does not exist, it needs to be created in Keystone once. +This can be done with the OpenStackClient using the following command:

+
openstack role create manager
+

[Runtime] Domain Manager managed roles adjustment

+

The list of roles that a Domain Manager can assign within a domain is configured using the "is_domain_managed_role" rule of the policy definitions. +The SCS Domain Manager standard allows flexibility in defining the set of roles a Domain Manager may assign and revoke within a domain and enables adjustments at runtime1.

+

The set of roles can be adjusted independently from the rest of the policy by changing only the "is_domain_managed_role" line it Keystone's API policy file. +Changes will apply to existing and future Domain Manager users. +This means that changes can be implemented at runtime1.

+

The following example entry adjusts the rule to allow both member and reader roles to be managed by Domain Managers:

+
'is_domain_managed_role': "'member':%(target.role.name)s or 'reader':%(target.role.name)s"
+

Refer to the SCS Domain Manager standard for more information.

+

Administrative operation

+

The following sections describe actions available to CSP operators that possess the admin role.

+

Creating domains

+
caution

It is highly recommended to use pseudonymized domain names when creating domains, since Domain Managers will currently be able to see the names of all existing domains. +See Warning regarding the exposure of domain names for more details.

+

For each tenant for which a self-service area (i.e. a domain) is to be established, a domain should be created before creating any users, projects or groups for this tenant:

+
openstack domain create $DOMAIN
+

Any creation of users, projects or group for a tenant should happen strictly within the tenant's domain by passing the "--domain" flag to the corresponding creation commands, regardless of whether the commands are executed by an administrator or a Domain Manager. +See the Domain Manager operation section further down for reference.

+

Creating a Domain Manager user

+
info

Creating the first Domain Manager users for a domain is an action reserved for CSP administrators. +Depending on whether the manager role has been approved as a domain-managed role in the policy configuration by the CSP, Domain Manager users may be able to appoint further Domain Managers within the domain on their own later on.

+

First, create the user for the Domain Manager. +You may create the Domain Manager user either directly in the target tenant's domain or in a different domain. +The domain a Domain Manager will effectively be able to manage solely depends on where its role assignment of the manager role is scoped, not the domain the Domain Manager user was originally created in.

+
openstack user create --domain $MANAGER_DOMAIN $USER_NAME
+
note

$MANAGER_DOMAIN can be the same as the tenant domain $DOMAIN or an entirely different one, depending on the desired origin domain of the user. +In the following sections $DOMAIN will denote the tenant domain that the user is intended to manage as the Domain Manager persona.

+

Next, assign the manager role in a domain-scoped fashion to the tenant domain:

+
openstack role add --user $USER_NAME --domain $DOMAIN manager
+

Assigning the Domain Manager role to an existing user

+
openstack role add --user $USER_NAME --domain $DOMAIN manager
+

Revoking the Domain Manager role

+

In case the manager role is to be revoked from an existing Domain Manager user, the following command can be used:

+
openstack role remove --user $USER_NAME --domain $DOMAIN manager
+

Domain Manager operation

+

The following sections describe actions available to Domain Managers that possess the manager role.

+

Managing users within a domain

+

Creating a user within a domain:

+
openstack user create --domain $DOMAIN $USER_NAME
+
note

The explicit domain-scoping is only required for the creation command, any other user-centric commands like "user set" or "user delete" do not require the "--domain" flag and are automatically scoped to the domain for Domain Managers.

+

Managing projects within a domain

+

Creating a project within a domain:

+
openstack project create --domain $DOMAIN $PROJECT_NAME
+
note

The explicit domain-scoping is only required for the creation command, any other project-centric commands like "project set" or "project delete" do not require the "--domain" flag and are automatically scoped to the domain for Domain Managers.

+

Deleting projects

+

Note that before deleting projects, make sure that all cloud resources (servers, volumes etc.) belonging to that project have been removed beforehand. +Otherwise such resources might become orphaned and inaccessible without involving the CSP.

+

Managing groups within a domain

+

Creating a group within a domain:

+
openstack group create --domain $DOMAIN $GROUP_NAME
+
note

The explicit domain-scoping is only required for the creation command, any other group-centric commands like "group set" or "group delete" do not require the "--domain" flag and are automatically scoped to the domain for Domain Managers.

+

Managing group membership

+

Adding a user to a group:

+
openstack group add user $GROUP $USER
+

Removing a user from a group:

+
openstack group remove user $GROUP $USER
+

Managing role assignments within a domain

+

Role assignments managed by a Domain Manager work as usual with the exception that the roles that can be assigned and revoked are limited to a defined set which is explicitly approved for Domain Managers by the CSP. +This may or may not include the manager role itself, meaning that Domain Managers may either be able to appoint other Domain Managers by themselves or have to ask the CSP to do so.

+

Managing user role assignments

+

Assigning a role to a user within a project:

+
openstack role add --project $PROJECT --user $USER $ROLE
+

Assigning a role to a user domain-wide:

+
openstack role add --domain $DOMAIN --user $USER $ROLE
+

Revoking a project-level role assignment from a user:

+
openstack role remove --project $PROJECT --user $USER $ROLE
+

Revoking a domain-wide role assignment from a user:

+
openstack role remove --domain $DOMAIN --user $USER $ROLE
+

Managing group role assignments

+

Assigning a role to a group within a project:

+
openstack role add --project $PROJECT --group $GROUP $ROLE
+

Assigning a role to a group domain-wide:

+
openstack role add --domain $DOMAIN --group $GROUP $ROLE
+

Revoking a project-level role assignment from a group:

+
openstack role remove --project $PROJECT --group $GROUP $ROLE
+

Revoking a domain-wide role assignment from a group:

+
openstack role remove --domain $DOMAIN --group $GROUP $ROLE
+ +

Footnotes

+
    +
  1. +

    "at runtime" in this context means that the configuration may be changed repeatedly after the initial configuration of Keystone and take effect immediately. +Depending on the infrastructure management solution and high-availability configuration the described adjustments may or may not require a restart of the Keystone API service or lead to a downtime of the service. 2

    +
  2. +
+
+ + \ No newline at end of file diff --git a/docs/iam/index.html b/docs/iam/index.html new file mode 100644 index 0000000000..0cde3c5d0f --- /dev/null +++ b/docs/iam/index.html @@ -0,0 +1,81 @@ + + + + + +Introduction on Identity Management and Federation in SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Introduction on Identity Management and Federation in SCS

+

Sovereign Cloud Stack wants to make it possible for operators to delegate +administration of user identities to the organizational entities that the +users are part of. Usually that's customer organizations but it could also +be the operator itself. Federation protocols like OpenID Connect can be used +to achieve that goal. To simplify connecting the different parts of SCS +to customer owned IAM solutions, the SCS reference implementation offers +Keycloak as central Identity Provider (IdP) service.

+

Deployment

+

Keycloak can be deployed by running

+
osism apply keycloak
+

The required Keycloak client configuration that allows Keystone to obtain +OIDC token from Keycloak needs to be deployed by running

+
osism apply keycloak-oidc-client-config
+

After these steps Keystone should be able to obtain token using the +Device Authorization Grant with PKCE, which is configured by default in the +wsgi-keystone.conf deployed in SCS.

+

Accessing Keycloak

+

Currently deployed on the manager node, by default under https://keycloak.<yourdomain>. +Details TODO.

+

Identity Mapping

+

The idea is that customer can create groups with specific names in their own IAM. +These shall be mapped to a claim groups to be included in the OIDC token. +Via the Keystone mapping +they shall be mapped to roles on OpenStack projects. +The corresponding section for Developers may be interesting for more technical details. +Please be aware that currently there are still some technical challenges to be solved +within the OpenStack Keystone mapping engine and the mapping rules to make this work +seamlessly.

+

SCS to SCS federation

+

Federation between separate deployments of SCS is possible via the IdP by +means of OpenID Connect. +The section on inter SCS federation setup explains the required steps in some detail.

+

Prerequisites and Requirements

+
    +
  • Knowledge: Familiarity with Keycloak, OIDC federation, and basic SSL and web security principles is pivotal.
  • +
  • Software: The core software component is the OpenID-Connect identity provider, configured to function optimally with OpenStack environments. While the SCS reference implementation focusses on Keycloak as IdP, with appropriate configuration adjustments any OAuth 2.0 compliant IdP should be suitable as an alternative. Each implemntation may have its own pros and cons.
  • +
+

Features

+
    +
  • Horizon Web SSO
  • +
  • OpenStack CLI use via the Device Authorization Grant
  • +
+

Limitations

+
    +
  • Keystone currently still has limitations in its mapping engine, which are addressed by the SCS development team as we +see possibilities and alignement with upstream OpenDev development plans. Automatically creating ephemeral users in +their specific OpenStack domains, as specified in their OIDC token is one example, currently beeing worked on. Please +check carefully if the technical results meet the security demands of your specific environment.
  • +
  • Keystone currently has another limitation which is being addressed by the SCS development team aligned +with upstream OpenDev development plans: The roles for federated users are stored on the database for the ephemeral users +created during a federated login. This limits the ability to modify users roles from the identity source directly, as roles of +the epehemeral users do not get cleaned up or updated based on changes in the claims contained in the OpenID-Connect token.
  • +
+

Current state and future Outlook

+

Currently SCS exemplifies deploying Keycloak on the management plane. This shall be moved to a Kubernetes based +management plane to improve scalability and architecture.

+

In the near future, the Container layer shall be able to make use of the IdP to allow federated users to access Kubernetes. +In the mid term, workloads on Kubernetes shall be able to make use of OAuth tokens to access resources on the IaaS layer.

+ + \ No newline at end of file diff --git a/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations/index.html b/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations/index.html new file mode 100644 index 0000000000..7bb5d18814 --- /dev/null +++ b/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations/index.html @@ -0,0 +1,88 @@ + + + + + +Proposal for documentation for Keycloak to Keycloak Federation (WebSSO) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)

+

The followig section is a reasonably detailed hands on description of how +to configure a federation between two separate SCS compliant domains by means +of Keycloak Identity Brokering. If we decide to use Keycloak as a component +to allow self service by tenants, then this documentation may be a useful addition +to some tenant facing documentation (or for the SCS operators too).

+

OTOH one could probably also script pretty much everything of this to allow +tenants to use a CLI tool to automate the setup. For that purpose the documentation +may be useful to guide the implementation of such a scripted solution.

+

Detailed tutorial on how to configure Federation (OpenID Connect) between two Keycloak instances in two separate SCS domains

+

Assume you have two CSPs using SCS. The first one wants to grant access to users of the other. +So let's call the first domain "resource domain" and the second one "accounts domain". +Both domains need to agree upon a name for the "OIDC RP" (which Keycloak calls Clients). +The Keycloak in the "resource domain" will be the OIDC RP and the Keycloak in the "accounts domain" will be the OIDC OP. +Assuming the "resource domain" is called foo and the "accounts domain" is called bar, the name for the "OIDC RP" could be oidc-rp-foo.

+
    +
  1. +

    In the accounts domain (bar) open Keycloak realm osism, click on Clients in the sidebar and click on Create client. +Leave the client type as OpenID Connect and enter the Client ID, e.g. oidc-rp-foo. +Turn on Client authentication for it and click Save.

    +

    On the Client details page open the tab Credentials and copy the Client secret. Communicate this to the operato of the "resource domain" foo via a secure channel.

    +
  2. +
  3. +

    In the resource domain (foo) open Keycloak realm osism, click on Identity providers +and create a new provider definition of type OpenID Connect v1.0. As Alias choose a name, +e.g. oidc-op-bar. Don't copy the Redirect URI given at the top yet, because is will change depending +on the chosen Alias. Instead, scroll down to the mandatory field Discovery endpoint and paste +the OpenID Connect metadata URL of the KEycloak realm osism in the "accounts domain" (bar). +The operator of the "accounts domain" (bar) may easily copy that URL from the Realm Settins in the +sidebar of his Keycloak instance, where the Endpoints are listed on the bottom of that form. +The URL may have the format https://bar.com/auth/realms/osism/.well-known/openid-configuration. +Once you leave that input field, Keycloak will attempt to fetch the metadata and extract the required +details about protocol enspoints from the retrieved document. If this shows an error, it will give you +an HTTP status code. If this shows an error code of 500, then this may be caused by a failure in +certificate verification. In that case you may want to check the output of docker logs keycloak for +java stack traces. If you find any, the top of those stack traces may indicate what kind of problem +occurred to the java code. From here we will assume that the emtadata URL could be fecthed without +any issues.

    +

    Now, go to the bottom of that form and insert tjhe Client ID (oidc-rp-foo) and the +Client secret that was provided by the operator of the "accounts domain" (bar). +Finally click on Add. From the Provider Details page on the top for the Settings tab copy the value of the +Redirect URI and communicate it back to the operator of the "accounts domain" (bar).

    +
  4. +
  5. +

    In the accounts domain (bar) open Keycloak realm osism, click on Clients in the sidebar and click +on the name of the OIDC RP clinent that you created for domain foo (e.g. oidc-rp-foo). +On the Client details page on the tab Settings fill in the field Valid redirect URIs with the value +obtained from the resource domain (foo), which should look similar to +https://foo.com/auth/realms/osism/broker/oidc-op-bar/endpoint. Additionally the +Valid post logout redirect URIs need to be set to something like https://foo.com/auth/realms/osism/*.

    +
  6. +
  7. +

    To test federated login in the "resource domain" (foo) open the URL of the Keycloak admin console for +the realm osism: https://foo.com/auth/admin/osism/console (or https://foo.com/auth/realms/osism/protocol/openid-connect/auth?client_id=security-admin-console). +Ignore the top section of the login form titled +Sign in to your account and choose one of the OIDC OP federation choises below the line Or sign in with. +In this example it would be oidc-op-bar. This should redirect your browser to the authentication endpoint +of the "accounts domain" (https://bar.com/auth/realms/osism/protocol/openid-connect/auth?scope=openid&...) +where you should be able to log in with credentials that are valid in the "accounts domain" (bar). +After successull authentication your broser should be redirected to admin console of the "resource domain", +which may offer you a "first login flow" form where you can choose a username, email, firstname and lastname. +The details depend on the Mappers that have been configured for the Identity Provider oidc-op-bar. +After that you will be presented with a Keycloak themed page with the error message Request failed with status code 403, +which is normal because the test account is not authorized to access any elements of the Keycloak admin console.

    +
  8. +
+ + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000000..1d7c4e860c --- /dev/null +++ b/docs/index.html @@ -0,0 +1,69 @@ + + + + + +Introduction | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Introduction

About

+

The Sovereign Cloud Stack combines the best of Cloud Computing in one unified standard. +SCS is built, backed, and operated by an active open-source community worldwide.

+

Architectural Overview

+ +

Use Cases and Deployment Examples

+

IaaS Layer

+

Quick Start with Cloud-In-A-Box

+

The fastest way to get in touch with SCS is to deploy a SCS cloud virtually. The Cloud-In-A-Box was built explicitly for this scenario. Check it out here

+

Reference Implementation Testbed

+

This means that you set up an SCS test installation including all the infrastructure +pieces such as database, message queueing, ceph, monitoring and logging, IAM, the +OpenStack core services, and (soon) the Container layer +on top of an existing IaaS platform.

+

The SCS IaaS reference implementation is based on OSISM. Read on the +OSISM testbed docs to learn how to get the +testbed running. Please read carefully through the +deployment section of the +manual.

+

Container Layer

+

K8s Cluster API Provider

+

You can easily deploy the container layer on top of the testbed (or a production +SCS cloud) checking out the code from +k8s-cluster-api-provider.

+

Cluster Stacks

+

With the Cluster Stacks, in the V2 KaaS reference implementation, we provide an opinionated optimized configuration of Kubernetes clusters. Through better packaging, integrated testing, and bundled configuration, SCS-based Kubernetes clusters provide easier individualization.
+Throughout the R6 development cycle Cluster Stacks are taken from a technical preview to be functional and available on top of the IaaS reference implementation as well to replace the V1 KaaS reference implementation k8s-cluster-api-provider.
+The Cluster Stacks can already be tried with the demo repository. Although this is based on the not-production-ready Docker provider, the usage is the same for every provider.

+

Public SCS Clouds in production

+

Find the current list of scs compatible clouds here.

+

Development of SCS

+

While the SCS project tracks the efforts across the released epics and user stories, the work on the code, whenever possible, happens upstream. As such, these repositories are usually not found in the SCS GitHub organization. SCS works directly in the following upstream projects:

+
    +
  • CNCF projects,
  • +
  • OpenStack,
  • +
  • kolla-ansible,
  • +
  • OSISM and others.
  • +
+

All code not pushed upstream can be found in the SCS Github organization.

+

Issues and Bugs

+

If you can identify the affected component, raise the issue against the relevant repository in the SovereignCloudStack or OSISM space. Otherwise, you can use the issues repository. We appreciate PRs as well as issues; please don't forget to sign off your contributions see contributor guide.

+

Contribute and Connect

+

Please see the SCS contributor guide.

+

Releases and Roadmap

+

See our Release Notes here

+

Standards, Conformity and Certification

+

How to get compliant? What do I need to be compliant? What are the benefits? What does it involve? What to expect in the future? Learn more in the standards section.

+ + \ No newline at end of file diff --git a/docs/operating-scs/audits/index.html b/docs/operating-scs/audits/index.html new file mode 100644 index 0000000000..28bb15d9ce --- /dev/null +++ b/docs/operating-scs/audits/index.html @@ -0,0 +1,24 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/automated-pentesting/overview/index.html b/docs/operating-scs/components/automated-pentesting/overview/index.html new file mode 100644 index 0000000000..9909ea8553 --- /dev/null +++ b/docs/operating-scs/components/automated-pentesting/overview/index.html @@ -0,0 +1,33 @@ + + + + + +SCS automated pentesting | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS automated pentesting

+

Security has a high priority in modern cloud infrastructures. If you look at it from an automation perspective, a basic distinction of tooling is needed to be considered:

+
    +
  • SAST or Static Application Security Testing: These tools scan code that is checked into e.g. git and are integrated into build pipelines. They only look at static artifacts: code, dependencies, container images.
  • +
  • DAST or Dynamic Application Security Testing: With dynamic testing, running programs and deployed infrastructure are scanned. This allows to identify vulnerabilities, test infrastructure configuration and analyze the behaviour of running processes.
  • +
+

In this project, the SCS automated pentesting pipeline, we solely focus on DAST.

+

Source

+

github.com/SovereignCloudStack/security-infra-scan-pipeline.

+

Tools

+

See the tools page.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/automated-pentesting/tools/index.html b/docs/operating-scs/components/automated-pentesting/tools/index.html new file mode 100644 index 0000000000..bed928da8e --- /dev/null +++ b/docs/operating-scs/components/automated-pentesting/tools/index.html @@ -0,0 +1,102 @@ + + + + + +Tools Description | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Tools Description

+

The following tools make up the automated pentesting pipeline. Each tool has it's own use case and they build up onto each other.

+

Naabu

+
    +
  • Functionality: Naabu is a port scanning tool used for identifying open ports on a target host or IP range, crucial for initial reconnaissance in penetration testing.
  • +
  • Capabilities: +
      +
    • Fast Scanning: Utilizes a high-speed, asynchronous approach for efficient port scanning.
    • +
    • Multiple Output Formats: Supports text, JSON, and XML formats for integration with other tools.
    • +
    • Flexible Target Specification: Capable of scanning individual hosts, IP ranges, or CIDR notations.
    • +
    • Custom Port Ranges: Allows scanning specific port ranges or using standard lists of common ports.
    • +
    +
  • +
  • Updates: Regularly updated for performance improvements and new features.
  • +
+

HTTPx

+
    +
  • Functionality: HTTPx is a powerful HTTP toolkit for web server fingerprinting, crucial for identifying web technologies and analyzing responses from web servers.
  • +
  • Capabilities: +
      +
    • High-Speed HTTP Detection: Efficient in analyzing HTTP servers and responses.
    • +
    • Status Code Retrieval: Collects HTTP status codes to identify live hosts and valid endpoints.
    • +
    • Custom Headers and Methods: Supports advanced HTTP requests for detailed analysis.
    • +
    • Automation-Friendly: Easily integrates into automated workflows and pipelines.
    • +
    +
  • +
  • Updates: Continuously updated with enhancements for speed, accuracy, and additional features.
  • +
+

Nuclei

+
    +
  • Functionality: Nuclei is a template-based vulnerability scanner, essential for detecting known vulnerabilities using predefined and community-driven templates.
  • +
  • Capabilities: +
      +
    • Extensive Template Library: Wide range of continuously updated templates for various vulnerabilities.
    • +
    • Custom Template Creation: Allows creation of tailored templates for specific environment needs.
    • +
    • Broad Vulnerability Coverage: Capable of scanning a variety of security weaknesses and exposures.
    • +
    • Integration-Ready: Designed to fit seamlessly into CI/CD pipelines.
    • +
    +
  • +
  • Updates: Community and developers regularly update templates and tool features.
  • +
+

Greenbone Community Edition (OpenVAS)

+
    +
  • Functionality: Greenbone CE, known as OpenVAS, is a full-featured vulnerability scanner for comprehensive assessments of networks, hosts, and applications.
  • +
  • Capabilities: +
      +
    • Wide Range of Tests: Offers a broad spectrum of network and application vulnerability tests.
    • +
    • Regular Feed Updates: The vulnerability feed is frequently updated for new threats.
    • +
    • Scan Customization: Supports various scan configurations and scheduling.
    • +
    • Detailed Reporting: Generates comprehensive reports for compliance and remediation planning.
    • +
    +
  • +
  • Updates: Maintained with regular updates to the vulnerability feed and software enhancements.
  • +
+

ZAP Proxy

+
    +
  • Functionality: ZAP Proxy is an intercepting proxy for dynamic application security testing (DAST), vital for identifying vulnerabilities in web applications.
  • +
  • Capabilities: +
      +
    • Passive and Active Scanning: Provides both passive scanning (traffic analysis) and active scanning (direct testing).
    • +
    • Comprehensive Web App Mapping: Includes tools like Spider and AJAX Spider for thorough application mapping.
    • +
    • Supports Various Authentication Types: Handles different web application authentication mechanisms.
    • +
    • Extensibility: Offers a range of plugins and extensions for additional functionalities.
    • +
    +
  • +
  • Updates: Regularly updated with new features and security tests.
  • +
+

Defect Dojo

+
    +
  • Functionality: Defect Dojo is a security program and vulnerability management tool. It centralizes and streamlines the management of security programs, allowing for efficient tracking, measurement, and reporting of vulnerabilities.
  • +
  • Capabilities: +
      +
    • Vulnerability Management: Enables tracking and management of vulnerabilities discovered across different tools and tests.
    • +
    • Reporting and Metrics: Offers comprehensive reporting features for understanding security postures and metrics.
    • +
    • Integration with CI/CD: Seamlessly integrates with CI/CD pipelines for automated importing of scan results.
    • +
    • Customization and Flexibility: Allows customizations to fit various workflow requirements and integrates with other tools via APIs.
    • +
    +
  • +
  • Updates: Regularly updated with enhancements for functionality, usability, and security.
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/central-api/overview/index.html b/docs/operating-scs/components/central-api/overview/index.html new file mode 100644 index 0000000000..77c87b41fc --- /dev/null +++ b/docs/operating-scs/components/central-api/overview/index.html @@ -0,0 +1,143 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Overview

+

Premise

+

By embracing existing open source solutions and bundling them, SCS provides a viable +alternative to widely adopted proprietary cloud offerings, including +Infrastructure-as-a-Service offerings, Kubernetes-as-a-Service offerings and other +X-as-a-Service offerings.

+

The choice to embrace existing technology has huge advantages over starting from +scratch. +By not reinventing wheels, a lot of effort is saved and existing communities are +strengthened. The adoption of existing open standards is supported, reducing +market fragmentation and increasing interoperability.

+

Challenge

+

The challenge: Using popular open source components at cloud service providers +does not result in a consistent experience for their users, yet.

+

Each part of the stack is consistent within its own scope: E.g. The +OpenStack Networking API is sort of +consistent with the +OpenStack Load Balancer API.

+

The OpenStack API's share API idioms like the used AuthN/AuthZ +(Authentication/Authorization) mechanisms. But these are not applicable beyond +OpenStack services.

+

Entering general IAM (Identity and Access Management), Keycloak has its own set of +API endpoints and authentication flows. +Entering Kubernetes, CAPI (Kubernetes Cluster API) +uses the Kubernetes API with its own authentication configuration, RBAC (Role Based +Access Control) and opinionated resource management idioms.

+

So, without a central API harmonizing at least the semantics of AuthN/AuthZ and +resource management, users are left with a bunch of semantically incompatible API's. +If resources in different API's are somehow interconnected, the users have to take +care of bridging these differences themselves.

+

Providing a consistent API across many different offerings with sort of consistent +API idioms is something that primarily the big proprietary cloud providers manage to +do. And while that serves users well in that regard, it also serves as an effective +vendor lock-in feature.

+

The chosen approach to pursue

+ +

Goal: Provide a "semantically" consistent API modelling most cloud resources +that are in scope for SCS.

+

In other words: Bring each cloud resource type - as it is - into the central API.

+

An OpenStack Compute Instance continues to be as-is with all of its usual +properties and implementation details. +A Keycloak Realm continues to be as-is with all of its usual properties +and implementation details.

+

That is not to say that abstractions are absolutely not planned as further steps. +There were discussions happening about that already: Regarding IAM management 1 +and Kubernetes management 2.

+

However, the main benefit is that all offered API objects can be managed +using the same API idioms (AuthN/AuthZ/REST) with the same client tooling 3.

+

Kubernetes API

+

Instead of creating SCS-specific API idioms and building the implementation +from scratch, the Kubernetes API will be "reused". Essentially, the Kubernetes +API is just an opinionated REST API which has opinions on how a resource +is defined, how it looks like, how it is reconciled/handled, how AuthN/AuthZ +can be implemented. The Kubernetes ecosystem provides much tooling for working +with such (custom) resource definitions: For creating the definitions +themselves, building controllers, making them discoverable and deployable.

+

As such, Kubernetes is a great choice for building any sort of resource +management API - with some caveats regarding its deployment and the legacy +of starting off as container orchestration tooling.

+

Crossplane tooling

+

Crossplane even extends the Kubernetes API with +"Compositions" and +"Composite Resource Definitions" +(XRD) to make Kubernetes the base for platform engineering within organizations.

+

Secondly, it provides an API machinery to bring any cloud resource into Kubernetes +using backend-specific "providers" (roughly comparable with Terraform providers). +As such, Crossplane with its provider ecosystem actually already did most of +the heavy lifting for providing e.g. OpenStack or Keycloak resources inside of Kubernetes.

+

On top, the platform engineering concepts in Crossplane make building multi-tenancy +systems pretty straight-forward, even for +single clusters.

+

Alright. Crossplane takes care of exposing OpenStack resources and does some +fancy stuff regarding multi-tenancy. What about providing actual Kubernetes +workload clusters?

+

Cluster stacks / Cluster API

+

Cluster stacks do +not replace the use of Cluster API. +Instead, they are complementing Cluster API by providing ClusterClasses, node +images (if required) and workload cluster addons.

+

It is still to be determined how to bring multi-tenancy concepts from Crossplane +into ClusterStacks/CAPI, if even required.

+

Should the provider be responsible for creating ClusterClasses? +If yes, enforcing some parameters inside via a ClusterClass may be enough +to provide multi-tenancy, already. That is to be determined, though.

+

Implementation

+

Disregarding any potential further abstractions, most work in automation for +the providers will be about installing the central API and securely distributing +credentials for backing services like OpenStack or Keycloak. +For that, there is no production implementation yet. See +the POC for inspiration for now. It includes access to an OpenStack API +through Kubernetes/Crossplane.

+ +

Footnotes

+
    +
  1. +

    There were discussions to build a generic SCS API to support +SCS installations powered by Zitadel. Approaching the issue a little +bit like the "Abstract all the things!" consideration above, but focusing +on two basic use cases (Firstly, setting up an identity federation to some +existing identity provider; Secondly, managing users without remote identity +provider). While not in scope for the first steps, this probably could be +elegantly implemented as one generic Crossplane "Composite Resource Definition" +backed by a Crossplane "Composition" defining either Keycloak objects OR +Zitadel objects (given that Zitadel gets a Crossplane provider or a similar +Kubernetes controller before).

    +
  2. +
  3. +

    In order to cover providers that use Gardnener, a generic Crossplane +"Composite Resource Definition" like in 1 may be created. Alternatively, +Gardnener CRD's could maybe just be mirrored in their Central API instance, +still creating an interoperability benefit through "semantic" compatibility.

    +
  4. +
  5. +

    Which is also not to say that it will be suggested to providers to disable +their public OpenStack/Keycloak/... API's, preventing use of native +OpenStack/Keycloak/... tooling and breaking existing solutions. +Extensively using these API's together with the central API may compromise +the benefits of its uniform AuthZ, though.

    +
  6. +
+
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/central-api/poc-setup/index.html b/docs/operating-scs/components/central-api/poc-setup/index.html new file mode 100644 index 0000000000..5685eb8546 --- /dev/null +++ b/docs/operating-scs/components/central-api/poc-setup/index.html @@ -0,0 +1,45 @@ + + + + + +Central API MVP | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Central API MVP

+

Right now, this repository implements issue 374. +It contains a script (gen.py) to mirror all crossplane openstack provider cluster-scoped resources to namespaced resources in an SCS API group.

+

Also, these instructions are striving to implement namespaces as isolation mechanism to implement a multi-tenant system backed by a single Kubernetes cluster.

+

crossplane-contrib/x-generation might be used as soon as the required feature for namespace mapping is implemented.

+

Quick Start

+
    +
  1. Setup testing Kubernetes cluster
  2. +
  3. Install crossplane
  4. +
  5. Install openstack provider (See provider.yaml)
  6. +
  7. Mirror openstack resources (See gen.py)
  8. +
  9. Setup provider config (wearing CSP hat) +
    apiVersion: v1
    kind: Namespace
    metadata:
    name: tenant-name
    ---
    apiVersion: openstack.upbound.io/v1beta1
    kind: ProviderConfig
    metadata:
    name: tenant-name
    spec:
    credentials:
    secretRef:
    namespace: crossplane-system
    name: tenant-name-clouds-yaml
    key: clouds.json
    source: Secret
    ---
    apiVersion: v1
    kind: Secret
    metadata:
    name: tenant-name-clouds-yaml
    namespace: crossplane-system
    stringData:
    clouds.json: |
    {
    "auth_url": "https://api.gx-scs.sovereignit.cloud:5000",
    "application_credential_id": "...",
    "application_credential_secret": "...",
    "tenant_name": "tenant-name"
    }
    +
  10. +
  11. Setup RBAC for tenants (wearing CSP hat) +
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
    name: tenant
    rules:
    - apiGroups:
    - api.scs.community
    resources:
    - '*'
    verbs:
    - '*'
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
    name: tenant
    namespace: tenant-name
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
    name: scs-bind
    namespace: tenant-name
    roleRef:
    apiGroup: rbac.authorization.k8s.io
    kind: ClusterRole
    name: tenant
    subjects:
    - kind: ServiceAccount
    name: tenant
    namespace: tenant-name
    +
  12. +
  13. Create resource (wearing tenant hat, kubectl --as system:serviceaccount:tenant-name:tenant -n tenant-name) +
    apiVersion: api.scs.community/v1alpha1
    kind: KeypairV2
    metadata:
    name: admin
    namespace: tenant-name
    spec:
    name: admin-keypair
    publicKey: |-
    ssh-rsa ...
    ---
    apiVersion: api.scs.community/v1alpha1
    kind: InstanceV2
    metadata:
    name: testing-vm
    namespace: tenant-name
    spec:
    name: testing-vm
    keyPair: admin-keyPair
    imageName: 'Debian 12'
    flavorName: 'SCS-1V:1:20'
    +
  14. +
  15. Observe creation of resources
  16. +
+

Right now, it would be expected to hand out the ServiceAccount token to the actual tenant; When AuthN is done via OIDC (or other means), the ServiceAccount tenant-name/tenant may be dropped and RoleBinding tenant-name/scs-bind may point to an actual user/group.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/alertmanager/index.html b/docs/operating-scs/components/monitoring/docs/alertmanager/index.html new file mode 100644 index 0000000000..7a4257ccc7 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/alertmanager/index.html @@ -0,0 +1,31 @@ + + + + + +Alertmanager notifications in Matrix chat | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Alertmanager notifications in Matrix chat

+

This page contains instructions on how to enable the Alertmanager to Matrix chat notifications in the Observer solution.

+

Project https://github.com/metio/matrix-alertmanager-receiver is used for forwarding alerts to a Matrix room.

+

To use it, fill your matrix credentials in matrix-alertmanager/matrix-alertmanager-receiver.yaml ConfigMap and deploy it:

+
kubectl apply -f matrix-alertmanager/matrix-alertmanager-receiver.yaml
+

You can modify other settings according to the mentioned project docs +in the ConfigMap.

+

You have to also uncomment a related section in values-observer.yaml alertmanager section. +The sections related to Alertmanager notifications in the values-observer-scs.yaml values file are already uncommented.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/iaas/index.html b/docs/operating-scs/components/monitoring/docs/iaas/index.html new file mode 100644 index 0000000000..d205a7f9b3 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/iaas/index.html @@ -0,0 +1,135 @@ + + + + + +IaaS monitoring (experimental) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

IaaS monitoring (experimental)

+

This component is marked as experimental, and it is not part of the reference SCS installation available +at https://monitoring.scs.community.

+

IaaS monitoring currently integrates and is able to observe the following targets:

+ +

Prerequisites

+

To test the Monitoring of the IaaS layer we expect running Kubernetes cluster that already contains +SCS monitoring platform.

+

Local environment use case - KinD/K3s cluster deployed locally

+

KinD

+

Install the SCS monitoring solution into the KinD Kubernetes cluster following the instructions provided in +the quickstart guide.

+

K3s

+

Install the SCS monitoring solution into the K3s Kubernetes cluster following the instructions provided in +the k3s guide.

+

OSISM use case - K3s cluster in OSISM deployment

+

OSISM utilizes the k3s distribution of Kubernetes +as a management cluster for the OSISM IaaS platform. This management cluster is then used as a host for +the SCS monitoring solution. Subsequently, the management cluster becomes an Observer cluster as it hosts +the SCS monitoring solution. +From that point, the Observer cluster observes itself (i.e., k3s cluster control plane components and nodes) and is used +for observing the IaaS layer around the k3s cluster.

+

In the case of the existing OSISM IaaS deployment >= 7.0.3 on +baremetal, testbed or cloud in the box +we expect a management k3s Kubernetes cluster with the deployed SCS monitoring platform. +If your OSISM installation does not meet the above requirements, apply the following plays:

+
osism apply kubernetes
osism apply kubernetes-monitoring
+

Deploy IaaS monitoring components

+

OpenStack

+

Prometheus metrics and alerts

+

The OpenStack exporter for Prometheus could be deployed using the SCS openstack-exporter-helm-chart. +This exporter contains a bunch of Prometheus alerts and rules +that are deployed together with the exporter. +Visit the iaas/openstack-exporter-values.yaml file to validate the Helm configuration options. +Ensure valid OpenStack API credentials are set under the clouds_yaml_config section. This MUST be overridden!

+
helm upgrade --install prometheus-openstack-exporter oci://registry.scs.community/openstack-exporter/prometheus-openstack-exporter \
--version 0.4.5 \
-f iaas/openstack-exporter-values.yaml # --set "endpoint_type=public" --set "serviceMonitor.scrapeTimeout=1m"
+

Tip: If you want to test the exporter basic functionality with public OpenStack API, configure endpoint_type +to public (--set "endpoint_type=public"). Note that configuring endpoint_type as public will result in +incomplete functionality for the Grafana dashboard.

+

Tip: Requesting and collecting metrics from the OpenStack API can be time-consuming, especially if the API is not +performing well. In such cases, you may observe timeouts on the Prometheus server when it tries to fetch OpenStack +metrics. To mitigate this, consider increasing the scrape interval to e.g. 1 minute (--set "serviceMonitor.scrapeTimeout=1m").

+

Grafana dashboards

+

The Grafana dashboard designed to visualize metrics collected from an OpenStack cloud through the OpenStack exporter +is publicly available at https://grafana.com/grafana/dashboards/21085. Its source code is located in the +iaas/dashboards directory. Feel free to import it to the Grafana via its source or ID. +For automatic integration into the SCS monitoring solution proceed to the next step.

+

Update the SCS monitoring deployment

+

This step deploys the Grafana dashboards and instructs the monitoring stack to add the OpenStack exporter target into the Prometheus configuration:

+
helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack --reset-then-reuse-values -f iaas/values-observer-iaas.yaml
+
    +
  • Note: The --reset-then-reuse-values option requires Helm v3.14.0 or later. Alternatively, you can use the original values +by applying -f values-observer.yaml, see full command: helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml -f iaas/values-observer-iaas.yaml
  • +
+

Access the OpenStack dashboard

+

At this point, you should have the ability to access the Grafana UI, and OpenStack dashboard.

+

Log in to the Grafana UI and find the OpenStack dashboard in IaaS directory:

+
http://localhost:30000
+

or directly access the OpenStack dashboard:

+
http://localhost:30000/d/openstack-overview
+
    +
  • Use the following credentials: +
      +
    • username: admin
    • +
    • password: pass
    • +
    +
  • +
+

Ceph

+

The SCS IaaS reference implementation (OSISM) currently supports ceph-ansible +method for deploying Ceph. Support for the rook operator deployment method will be available soon.

+

This guide covers Ceph cluster monitoring for both deployment methods. While both expose the same metrics via the same +endpoint, there are some differences in Prometheus configuration and alerts.

+

Prometheus metrics and alerts

+

Ceph contains 2 build-in sources of metrics a.k.a. exporters. +The Ceph exporter (introduced in Reef release of Ceph) is the main source of Ceph performance metrics. It runs as a +dedicated daemon. This daemon runs on every Ceph cluster host and exposes a metrics end point where all the performance +counters exposed by all the Ceph daemons running in the host are published in the form of Prometheus metrics.

+

The second source of metrics is the Prometheus manager module. It exposes metrics related to the whole cluster, +basically metrics that are not produced by individual Ceph daemons.

+

Read the related Ceph docs. +Since these exporters are integrated with Ceph, deploying a third-party Ceph exporter is unnecessary.

+

Prometheus alerts

+

Both Ceph deployment strategies use the ceph-mixins project as a source of alerts. The ceph-ansible and rook projects +each maintain a rendered version of these alerts, but the rook repository contains some differences, primarily because +rook does not use the cephadm tool as a backend. +Therefore, find and apply one of the following commands to create a custom observer rules values file for either the +ceph-ansible or ceph-rook deployment (yq tool required):

+
# ceph-ansible
curl -s https://raw.githubusercontent.com/ceph/ceph/main/monitoring/ceph-mixin/prometheus_alerts.yml | \
yq '{"kube-prometheus-stack": {"additionalPrometheusRulesMap": {"ceph-ansible-rules": (. + {"additionalLabels": {"prometheus_rule": "1"}})}}}' > iaas/values-observer-ceph-rules.yaml

# rook
curl -s https://raw.githubusercontent.com/rook/rook/master/deploy/charts/rook-ceph-cluster/prometheus/localrules.yaml | \
yq '{"kube-prometheus-stack": {"additionalPrometheusRulesMap": {"ceph-rook-rules": (. + {"additionalLabels": {"prometheus_rule": "1"}})}}}' > iaas/values-observer-ceph-rules.yaml
+

Grafana dashboards

+

We've tested and could recommend 2 sources of Grafana dashboards that are suitable for both Ceph deployment strategies (ansible and rook):

+ +

We consider the dashboards created within the Rook project as a solid starting point for Ceph metrics visualization. +If you want to see more detailed dashboards, uncomment and use the ceph-mixin dashboards in the values-observer-ceph-rook.yaml +or values-observer-ceph-ansible.yaml file. You can use both.

+

Update the SCS monitoring deployment

+

This step deploys Grafana dashboards, Prometheus rules and instruct monitoring stack to add the Ceph exporter targets into the Prometheus configuration. +Ensure that you add the monitoring targets' IPs and ports to values-observer-ceph-ansible.yaml for Ceph-ansible deployment.

+
helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack --reset-then-reuse-values \
-f iaas/values-observer-ceph-rules.yaml \
-f iaas/values-observer-ceph-[rook|ansible].yaml # use values file for either the ceph-ansible or ceph-rook deployment
+
    +
  • Note: The --reset-then-reuse-values option requires Helm v3.14.0 or later. Alternatively, you can use the original values +by applying -f values-observer.yaml, see full command: helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml -f iaas/values-observer-ceph-rules.yaml -f iaas/values-observer-ceph-[rook|ansible].yaml
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/infrastructure_services/index.html b/docs/operating-scs/components/monitoring/docs/infrastructure_services/index.html new file mode 100644 index 0000000000..f00de87594 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/infrastructure_services/index.html @@ -0,0 +1,29 @@ + + + + + +Infrastructure service endpoints | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Infrastructure service endpoints

+

This page contains instructions on how to enable probing of infrastructure service endpoints using blackbox exporter.

+

Infrastructure service endpoints can be probed using protocols such as HTTP, HTTPS, DNS, TCP, ICMP, and gRPC.

+

Blackbox exporter is a component of the monitoring stack. +Therefore, it can be deployed into the Observer cluster and configured simply by using the Helm chart values.

+

To enable probing of infrastructure service endpoints with blackbox exporter, locate and uncomment the related section in values-observer.yaml. +The sections related to blackbox exporter in the values-observer-scs.yaml values file are already uncommented.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/k3s/index.html b/docs/operating-scs/components/monitoring/docs/k3s/index.html new file mode 100644 index 0000000000..a17de02980 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/k3s/index.html @@ -0,0 +1,91 @@ + + + + + +K3s support | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

K3s support

+

K3s is a certified Kubernetes distribution optimized for production environments, particularly in remote locations +or resource-constrained environments. Within the OSISM IaaS distribution, it serves as the management cluster, +accommodating various management software. Our aim is to integrate the SCS Observability platform as an observer solution +for the IaaS layer. To achieve this, we deploy the SCS Observability solution within the IaaS k3s management cluster. +This setup enables us to monitor not only the management k3s cluster itself but also the surrounding IaaS control +plane components.

+

This page contains information on how to develop and/or test the Observer solution as a monitoring solution for a k3s +cluster. It guides the user to create an HA k3s cluster via k3d (a wrapper to run k3s in Docker) and bootstrap +it with the Observer solution.

+

Note that the following tutorial guides you to deploy an HA K3s cluster consisting of 3 control plane nodes (servers) +and one worker node (agent). The reason is that the HA K3s cluster utilizes an embedded etcd cluster as cluster storage +(refer to https://docs.k3s.io/datastore/ha-embedded) and the HA mode is also used in OSISM Testbed and productive bare +metal deployments. +Using a single-node K3s cluster that uses the SQLite database (default) requires additional tweaks of monitoring values, +which are not covered in this guide.

+

Prerequisites

+ +

Prepare K3s Kubernetes cluster via K3d

+
k3d cluster create --config k3s-config.yaml --image rancher/k3s:v1.28.8-k3s1 observer
+

If you opt not to use K3D with the custom config we provided here, and prefer utilizing another Kubernetes cluster, +ensure that the metric endpoints for various control plane components are properly exposed. +Refer to the docs.

+

Deploy Observer monitoring solution

+

K3s consolidates all Kubernetes control plane components into a single process, which means that the metrics for these +control plane components are exposed on the K3d hosts rather than through individual Kubernetes Services/PODs. +To customize monitoring values for K3s, refer to the specific custom HELM values file values-observer-k3s.yaml. +This file contains the necessary configurations and adjustments needed to monitor K3s. +Note that list of control plane node IPs (endpoints) should be overridden.

+

Get and store the K3d control plane node IPs:

+
NODE_IPS=$(kubectl get nodes -l node-role.kubernetes.io/control-plane=true -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}' | tr ' ' ',' | sed 's/^/{&/;s/$/}/')
+

Install the monitoring stack and set the control plane component endpoints

+
helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/
helm repo update dnationcloud
helm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer-k3s.yaml \
--set "kube-prometheus-stack.kubeEtcd.endpoints=$NODE_IPS" \
--set "kube-prometheus-stack.kubeProxy.endpoints=$NODE_IPS" \
--set "kube-prometheus-stack.kubeControllerManager.endpoints=$NODE_IPS" \
--set "kube-prometheus-stack.kubeScheduler.endpoints=$NODE_IPS"
+

Access the Observer monitoring UIs

+

At this point, you should have the ability to access the Grafana, Alertmanager and Prometheus UIs +within the Observer monitoring cluster.

+
    +
  • +

    Grafana UI

    +
    http://localhost:30000
    + +
  • +
  • +

    Alertmanager UI

    +
    http://localhost:30001
    +
  • +
  • +

    Prometheus UI

    +
    http://localhost:30002
    +
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/kaas/index.html b/docs/operating-scs/components/monitoring/docs/kaas/index.html new file mode 100644 index 0000000000..321e2680ce --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/kaas/index.html @@ -0,0 +1,91 @@ + + + + + +KaaS monitoring (experimental) | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

KaaS monitoring (experimental)

+

This component is marked as experimental, and it is not part of the reference SCS installation available +at https://monitoring.scs.community.

+

Enable KaaS layer monitoring

+

TODO: Provide clear instructions on how to enable KaaS layer monitoring.

+

Please check out the mvp-0 tag and find the related comments on what needs to be done in the monitoring +values to enable KaaS monitoring in your Observer cluster.

+

KaaS metric importer

+

To test the Monitoring of the KaaS layer use case, deploy the Kaas-metric-importer +into the Observer cluster.

+

The Kaas-metric-importer is a simple service through which the KaaS software registers +and unregisters newly created or deleted KaaS clusters in the Observer monitoring. +This functionality enables the Observer monitoring to differentiate between KaaS clusters deleted intentionally +and those that have stopped writing metrics to the Observer monitoring for any reason.

+
kubectl apply -f kaas/kaas-metric-importer.yaml
+

The Kaas-metric-importer uses an image built from https://github.com/m3dbx/prometheus_remote_client_golang. +It has mounted configmap and based on configmap keys it pushes custom metric kaas +with label cluster and value 1 into the thanos receiver.

+

Example of configmap:

+
data:
workload-cluster: ""
+

It pushes metric e.g. kaas{cluster="workload-cluster"} 1 to the Observer. +It is important to keep the configmap up-to-date with your KaaS offering. This is automated e.g. +in the KaaS mock service below.

+

KaaS mock service

+

To evaluate the Monitoring of the KaaS layer use case and view actual metrics in your +Observer monitoring cluster, you can launch the KaaS mock service.

+

Put your Observer monitoring cluster kubeconfig into the ./kaas/manifests/ directory and name +it observer-kubeconfig.yaml (or adjust kaas service ./kaas/app/config.py accordingly).

+

If you're utilizing the KinD Observer deployment outlined in this tutorial, collect the kubeconfig using the following command:

+
kind get kubeconfig --name observer > ./kaas/manifests/observer-kubeconfig.yaml
+

All KaaS mock service dependencies can be installed via the corresponding ./kaas/requirements.txt file. +Installing them into a Python virtualenv is recommended.

+
cd kaas
python3 -m venv .venv # Optional
source .venv/bin/activate # Optional
# Install kaas dependencies
pip install -r requirements.txt

# Launch the KaaS mock service
make kaas
+

At this point, you should have the ability to access the KaaS mock service Swagger UI:

+
http://127.0.0.1:8080/kaas
+
    +
  • +

    Create KaaS cluster through Swagger UI: Create Cluster or +call directly the KaaS service API via some client, e.g.:

    +
    curl -X POST -H "Content-Type: application/json" http://127.0.0.1:8080/api/clusters/ -d '{"name": "kaas"}'
    +

    Navigate to the KaaS Monitoring dashboard +in the Observer monitoring. After a few minutes (approximately 4), your KaaS cluster should become visible. +Click on the cluster box to dive into KaaS cluster dashboards at a more detailed level. +Repeat the process to explore further and gain deeper insights.

    +

    Note: The disk utilization expression for the Docker environment has not been adjusted, +so you will encounter non-realistic numbers in the nodes/disk sections. However, +the other sections should accurately reflect the reality.

    +
  • +
  • +

    Retrieve a list of all KaaS clusters and check their status. Swagger UI: Get List of Clusters or +call directly the KaaS service API via some client, e.g.:

    +
    curl -s -X GET -H 'accept: application/json' http://127.0.0.1:8080/api/clusters/
    +
  • +
  • +

    Get Kaas Cluster kubeconfig by its name through Swagger UI: Get Cluster kubeconfig or +call directly the KaaS service API via some client and save it, e.g.:

    +
    curl -s -X GET -H 'accept: application/json' http://127.0.0.1:8080/api/clusters/kaas > kaas-kube
    +
  • +
  • +

    Now, you have the opportunity to play with your KaaS cluster and experiment with triggering +monitoring alerts by initiating actions like destroying certain components 😎.

    +
    kubectl --kubeconfig kaas-kube get po -A
    +
  • +
  • +

    Finally, delete your KaaS cluster by its name through Swagger UI: Delete Cluster or +call directly the KaaS service API via some client and save it, e.g.:

    +
    curl -X DELETE http://127.0.0.1:8080/api/clusters/?name=kaas
    +
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/oauth/index.html b/docs/operating-scs/components/monitoring/docs/oauth/index.html new file mode 100644 index 0000000000..317dd161f0 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/oauth/index.html @@ -0,0 +1,60 @@ + + + + + +OAUTH | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

OAUTH

+

We set up oauth2 with GitHub provider for the https://monitoring.scs.community according to the https://kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/.

+

To use it, inspect oauth/oauth2-proxy.yaml and modify it according to your needs. +You want to change at least these:

+
    +
  • OAUTH2_PROXY_CLIENT_ID
  • +
  • OAUTH2_PROXY_CLIENT_SECRET
  • +
  • OAUTH2_PROXY_COOKIE_SECRET
  • +
  • ingress host
  • +
+

Then deploy oauth2-proxy as follows:

+
kubectl apply -f oauth/oauth2-proxy.yaml
+

We set up OAuth authentication for these components:

+
    +
  • Thanos Query +
      +
    • it is exposed via ingress on monitoring.scs.community/thanos
    • +
    • modified with --web.external-prefix=thanos extra flag +
        +
      • ruler query endpoint and grafana datasource url need to be modified
      • +
      +
    • +
    +
  • +
  • Alertmanager +
      +
    • it is exposed via ingress on monitoring.scs.community/alertmanager
    • +
    • modified with routePrefix: /alertmanager alertmanagerSpec +
        +
      • ruler alertmanager url needs to be modified
      • +
      +
    • +
    +
  • +
+

You have to also uncomment a related sections in values-observer.yaml for exposing +the components via ingress. +The sections related to OAUTH in the values-observer-scs.yaml values file are already uncommented.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/overview/index.html b/docs/operating-scs/components/monitoring/docs/overview/index.html new file mode 100644 index 0000000000..65ceaaa2dc --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/overview/index.html @@ -0,0 +1,48 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Overview

+

This repository aims to build an Observer monitoring solution intended to offer a global metrics +view of the CSP infrastructure. It is the platform where CSP infrastructure metrics +are fetched, processed, stored, and visualized. Note that this monitoring solution could +be extended, and the other two observability signals (logs and traces) from the CSP +infrastructure could also be processed here.

+

The Observer monitoring solution is developed on the foundation of the dNation monitoring solution. +and it is intended to become an SCS product.

+

This repository includes the manifest for the stable deployment of the Observer monitoring solution, +as well as experimental and illustrative examples of how this monitoring solution can be extended and utilized.

+

The stable version of the Observer monitoring solution empowers its reference SCS installation available +at https://monitoring.scs.community. This deployment covers the monitoring of core SCS infrastructure services, +subsequently referred to as 'Monitoring of infrastructure services'. Refer to the details here. +The high-level architecture could be visualized as follows:

+

monitoring_scs_high_level.png

+

Some illustrative and experimental examples of how this monitoring solution can be utilized have been introduced +within the MVP-0 version of this project (refer to the mvp-0 tag, related comments, and docs sections: kaas, iaas). +These examples include:

+
    +
  • Monitoring of the KaaS layer
  • +
  • Monitoring of the IaaS layer
  • +
+

The above experimental components are not part of the reference SCS installation available +at https://monitoring.scs.community. +The high-level architecture of these experimental components could be visualized as follows:

+

monitoring_scs_experimental.png

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/quickstart/index.html b/docs/operating-scs/components/monitoring/docs/quickstart/index.html new file mode 100644 index 0000000000..01228cbf98 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/quickstart/index.html @@ -0,0 +1,82 @@ + + + + + +Quickstart | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Quickstart

+

These page covers the process of deploying the Observer monitoring solution +into the Kubernetes cluster.

+

The configuration options used in this tutorial result in a non-productive and simple +deployment of the Observer monitoring solution. The steps do not guide users to register +certain observer targets, such as existing Kubernetes clusters or virtual machines. +Additionally, the tutorial lacks guidance for deploying optional and experimental components +like IaaS and KaaS monitoring.

+

At the end of this tutorial, the reader should end up with a Kubernetes cluster where the Observer solution will +be installed and will monitor the Kubernetes cluster hosting it.

+

Prerequisites

+ +

Prepare Kubernetes cluster

+

The Observer monitoring solution is designed to operate on Kubernetes clusters. We have continuously tested it with +various Kubernetes distributions, including vanilla Kubernetes, OKD, SCS KaaS V1, +and SCS KaaS V2.

+

To set up the SCS KaaS V2 Kubernetes cluster, please refer to the quickstart guide.

+

For local testing purposes, we recommend using KinD (Kubernetes in Docker) as follows:

+
kind create cluster --config kind-observer-config.yaml --image kindest/node:v1.27.3 --name observer
+

If you opt not to use KinD with the custom config we provided here, and prefer utilizing another Kubernetes cluster, +ensure that the metric endpoints for various control plane components are properly exposed. +Refer to the docs.

+

Deploy Observer monitoring solution

+
helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/
helm repo update dnationcloud
helm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml
+

Access the Observer monitoring UIs

+

At this point, you should have the ability to access the Grafana, Alertmanager and Thanos UIs +within the Observer monitoring cluster.

+
    +
  • +

    Grafana UI

    +
    http://localhost:30000
    + +
  • +
  • +

    Alertmanager UI

    +
    http://localhost:30001
    +
  • +
  • +

    Thanos UI

    +
    http://localhost:30002
    +
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/scs-deployment/index.html b/docs/operating-scs/components/monitoring/docs/scs-deployment/index.html new file mode 100644 index 0000000000..794f417e2b --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/scs-deployment/index.html @@ -0,0 +1,64 @@ + + + + + +SCS deployment | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS deployment

+

The following steps were utilized to deploy the SCS reference installation of the Observer monitoring solution, +which is available at https://monitoring.scs.community.

+

Architecture

+

Currently, the detailed architecture diagram can be visualized as follows:

+

monitoring_scs_detailed.png

+

Prerequisites

+
    +
  • Kubernetes cluster +
      +
    • We used the R5 version of SCS KaaS V1, which includes an ingress controller and cert manager +
      export KUBECONFIG=/path/to/kubeconfig
      +
    • +
    +
  • +
  • kubectl
  • +
  • helm
  • +
+

Install Observer solution

+
    +
  • +

    Apply SCS brand secrets and letsencrypt issuer manifest.

    +
    kubectl apply -f scs/logo.yaml
    kubectl apply -f scs/brand.yaml
    kubectl apply -f scs/issuer.yaml
    +
  • +
  • +

    Deploy the Zuul monitoring related Helm chart and all associated manifests according to the instructions provided on this documentation page.

    +
  • +
  • +

    Deploy the Alertmanager to Matrix chat notifications related manifest according to the instructions provided on this documentation page.

    +
  • +
  • +

    Deploy the OAUTH related manifest according to the instructions provided on this documentation page.

    +
  • +
  • +

    Review the values-observer-scs.yaml file and locate all instances of the placeholder text "replace-me". +These values relate to configuring access to the object store as well as the Grafana admin password.

    +
  • +
  • +

    Finally, install the monitoring stack using values that incorporate all the configurations mentioned above

    +
  • +
+
helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/
helm repo update dnationcloud
helm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer-scs.yaml
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/tracing/index.html b/docs/operating-scs/components/monitoring/docs/tracing/index.html new file mode 100644 index 0000000000..33533f7d75 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/tracing/index.html @@ -0,0 +1,36 @@ + + + + + +Traces | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Traces

+

This page contains a guide on how to enable traces in Thanos. Traces are not enabled by default.

+

Thanos supports different tracing backends that implements opentracing.Tracer interface. +All clients could be configured by --tracing.config-file parameter to reference to the configuration file or by --tracing.config +parameter to put yaml config directly. Recommended way is to pass configuration directly as it gives an explicit static view of +configuration for each component, and it also saves you the fuss of creating and managing additional files.

+

Example

+

Here is the example of the configuration how to enable jaeger in Thanos. This configuration can be applied for multiple components e.g. query-frontend, query or thanos-sidecar.

+
thanos:
queryFrontend:
extraFlags:
- |-
--tracing.config="config":
"sampler_param": 2
"sampler_type": "ratelimiting"
"service_name": "thanos-query-frontend"
"agent_host": "jaeger-agent.<namespace>.svc"
"agent_port": 5775
"type": "JAEGER"
+

Usage

+

Once tracing is enabled, Thanos will generate traces for all gRPC and HTTP APIs thanks to generic “middlewares”. +Some more interesting to observe APIs like query or query_range have more low-level spans with focused metadata showing +latency for important functionalities. For example, Jaeger view of query_range HTTP API call might look as follows: +Jaeger-example

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/tuning/index.html b/docs/operating-scs/components/monitoring/docs/tuning/index.html new file mode 100644 index 0000000000..e183684ea8 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/tuning/index.html @@ -0,0 +1,62 @@ + + + + + +Tuning | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Tuning

+

This page contains recommended parameters to set for the Thanos components to improve performance in terms of query time. +The following parameters have already been incorporated into the upstream dNation monitoring repositories, +and therefore are already included in the SCS observability deployment.

+

Query Frontend

+
queryFrontend:
extraFlags:
- --query-range.split-interval=12h
- --query-frontend.log-queries-longer-than=10s
- --query-frontend.compress-responses
- |-
--query-range.response-cache-config="config":
"max_size": "500MB"
"max_size_items": 0
"validity": 0s
"type": "in-memory"
+
    +
  • Notes on the parameters for query frontend: +
      +
    • query-range.split-interval - splits a long query into multiple short queries to improve query time. Default=24h.
    • +
    • query-frontend.log-queries-longer-than=10s - log queries running longer than 10s, which helps to identify new querries, which should be improved)
    • +
    • query-frontend.compress-responses - compress HTTP responses, helps with query time
    • +
    • query-range.response-cache-config - cahcing is common solution to speed up response time(https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/)
    • +
    +
  • +
+

Compactor

+
compactor:
retentionResolutionRaw: 2d
retentionResolution5m: 10d
retentionResolution1h: 15d
extraFlags:
- --compact.concurrency=3
- --downsample.concurrency=3
+
    +
  • Notes on the parameters for compactor: +
      +
    • retentionResolutionRaw - how long to retain raw samples in bucket. Minimum is two days, because just after 40 hours 5m downsampled data are created.
    • +
    • retentionResolution5m - how long to retain samples of resolution 1 (5 minutes) in bucket. Setting this to 0d will retain samples of this resolution forever. One hour downsampled data are created only after 10 days, so this is minimum if you want also 1h downsampled data.
    • +
    • retentionResolution1h - how long to retain samples of resolution 2 hour) in bucket.
    • +
    • delete-delay - make sure you have set this parameter. It is time before a block marked for deletion is deleted from bucket. Note that deleting blocks immediately can cause query failures, if store gateway still has the block loaded, or compactor is ignoring the deletion because it's compacting the block at the same time. Default=48h.
    • +
    • compact.concurrency - number of goroutines to use when compacting groups(https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/). Default=1.
    • +
    • downsample.concurrency - number of goroutines to use when downsampling block(https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/). Default=1.
    • +
    +
  • +
+

Query

+
query:
extraFlags:
- --query.auto-downsampling
- --query.replica-label=prometheus_replica
+
    +
  • Notes on the parameters for query: +
      +
    • query.auto-downsampling - enable automatic adjustment (step / 5) to what source of data should be used in store gateways if no max_source_resolution param is specified. Default step for range queries is equal to 1s and it is only used when step is not set in UI. Can be changed by setting --query.default-step parameter. Hovewer, when you are using Grafana as your UI, the step is taken from min_step. The preferred options is to set HTTP URL/FORM parameter max_source_resolution to auto, which selects downsample resolution automatically based on the query.
    • +
    • query.replica-label - labels to treat as a replica indicator along which data is deduplicated.
    • +
    +
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/monitoring/docs/zuul/index.html b/docs/operating-scs/components/monitoring/docs/zuul/index.html new file mode 100644 index 0000000000..215df89273 --- /dev/null +++ b/docs/operating-scs/components/monitoring/docs/zuul/index.html @@ -0,0 +1,35 @@ + + + + + +Zuul monitoring | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Zuul monitoring

+

This page contains instructions on how to enable the Zuul monitoring in the Observer solution.

+

Zuul comes with support for the statsd protocol, hence the graphite instance is needed when +we want directly consume Zuul metrics.

+

Graphite deployment:

+
helm add repo kiwigrid https://kiwigrid.github.io
helm upgrade --install graphite kiwigrid/graphite -f zuul/values-zuul.yaml
+

A UDP load balancer that exposes the Graphite receiver service:

+
kubectl apply -f zuul/udp-lb-service.yaml
+

Zuul dashboards:

+
kubectl apply -f zuul/zuul-status-dashboard.yaml
kubectl apply -f zuul/zuul-nodepool-dashboard.yaml
kubectl create -f zuul/zuul-zookeeper-dashboard.yaml
+

Find and uncomment a related section in values-observer.yaml if you want to link the above +dashboards to the L1 Zuul host dashboard. +The sections related to Zuul in the values-observer-scs.yaml values file are already uncommented.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page/docs/component_overview/index.html b/docs/operating-scs/components/status-page/docs/component_overview/index.html new file mode 100644 index 0000000000..5d2f5df42d --- /dev/null +++ b/docs/operating-scs/components/status-page/docs/component_overview/index.html @@ -0,0 +1,31 @@ + + + + + +Component Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Component Overview

+

This represents a part of the decision process related to the overall structure the API wants to represent.

+ +

Color meaning:

+
    +
  • Blue: Existing structure
  • +
  • Red: Deprecated / removed
  • +
  • Green: New
  • +
+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page/docs/components/index.html b/docs/operating-scs/components/status-page/docs/components/index.html new file mode 100644 index 0000000000..751de10a96 --- /dev/null +++ b/docs/operating-scs/components/status-page/docs/components/index.html @@ -0,0 +1,26 @@ + + + + + +Components | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Components

+

Illustrating multiple interchangable logical "layers" of possible Status Page application stacks:

+ +

Note that not everything that is shown here, actually exists or was tested. It is just shown for illustration purposes.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page/docs/levels_of_consensus/index.html b/docs/operating-scs/components/status-page/docs/levels_of_consensus/index.html new file mode 100644 index 0000000000..b3e96016ab --- /dev/null +++ b/docs/operating-scs/components/status-page/docs/levels_of_consensus/index.html @@ -0,0 +1,63 @@ + + + + + +"Levels of consensus" | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

"Levels of consensus"

+

When implementing any system to be used by a group of potential users, there will be varying use cases and opinions about API's, programming languages, persistence models, authentication, authorization, deployment options and so on. +Hence, building a complete one-fits-all solution is difficult, but (while offering a pretty un-opinionated reference implementation) even finding consensus on a few basic concepts may make adaptation and integration of different solutions possible.

+

The "levels" of consensus could be split into:

+

Consensus on...

+
    +
  1. Resource Definition +
      +
    • "What is an incident?"
    • +
    • Core REST API Spec
    • +
    +
  2. +
  3. General Architecture +
      +
    • "Monolithic Web App or multiple components?"
    • +
    • "Use static password file or rely on OIDC provider?"
    • +
    • (If any:) Interfaces between components: +
        +
      • AuthN mechanisms
      • +
      • AuthZ decisions
      • +
      +
    • +
    +
  4. +
  5. Implementation of core component(s) +
      +
    • "Use reference implementation components?"
    • +
    • "Go vs. JavaScript?"
    • +
    • "Postgres vs. MySQL?"
    • +
    +
  6. +
  7. Choice of all used components +
      +
    • "Policy: Istio vs. traefik?"
    • +
    • "Deployment: Helm vs. ansible?"
    • +
    • "dex vs. keycloak vs. zitadel?"
    • +
    +
  8. +
+

Every user of the Status Page (API) should be able to either make full use of the full reference implementation, building little to none on their own; Or just pick core concepts/API's/automation and build partial compatibility.

+

E.g. while the value on agreeing on every aspect would bring the most value, this most likely is not likely to happen, but adopting only the "Resource Definition", should ideally bring value already.

+ + \ No newline at end of file diff --git a/docs/operating-scs/components/status-page/docs/overview/index.html b/docs/operating-scs/components/status-page/docs/overview/index.html new file mode 100644 index 0000000000..3eb98e983b --- /dev/null +++ b/docs/operating-scs/components/status-page/docs/overview/index.html @@ -0,0 +1,69 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Overview

+

Service providers often times want to communicate the status of their systems transparently to their users. +A commonly used pattern is to provide a "status page" web application, where the current system health as well as recent incidents are made available.

+

SCS strives to implement a status page that works well, while being interoperable with other systems.

+
note

How was the decision to implement a new status page application made? What were the requirements? See the decision record.

+

To be easily interoperable with other software, being "API-first" is a priority. +As such, the status page should not need to be a typical monolithic web application (even though it could be), hence making it possible to split functionality into an API server and a frontend component.

+

The SCS status page API

+

The SCS status page API (as opposed to actual implementations) is supposed to be as un-opinionated as possible regarding deployment, user management, persistence and tech stack, to allow operators/developers (1) to make their own decisions regarding these topics and (2) to quickly implement the API with their own tech stack opinions, if the reference implementation does not fit theirs.

+

In particular, the API has no opinion about:

+
    +
  • How authentication/authorization is done (apart from splitting Read-only from Read-write 1; See below)
  • +
  • Server implementation, used database, deployment automation, high availability
  • +
+

However, as un-opinionated the API (in its first iteration) strives to be, it is...:

+
    +
  • a REST API (no GRPC/GraphQL/...)
  • +
  • defined using an OpenAPI file to make use of OpenAPI tooling
  • +
  • split in two parts 1: +
      +
    1. Read-only anonymous access
    2. +
    3. Read-write authenticated access
    4. +
    +
  • +
+

Reference implementation

+

It is envisioned to have a well-maintained reference implementation of the status page API with some basic tech stack decisions made, to not require anyone to implement the API themselves:

+
    +
  • Programming Language: Go
  • +
  • Persistence: Postgres compatible database
  • +
+

The SCS status page frontend

+

The SCS status page frontend is supposed to be an application which uses the status page API to get information. This could be an CLI tool as well as an web application.

+

Reference implementation

+

It is envisioned to have a well-maintained reference implementation of an status page frontend with some basic tech stack decisions made:

+
    +
  • Platform: Web (HTML/JS/...)
  • +
  • Framework: VueJS, Vuetify
  • +
+ +

Footnotes

+
    +
  1. +

    In the future 2

    +
  2. +
+
+ + \ No newline at end of file diff --git a/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install/index.html b/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install/index.html new file mode 100644 index 0000000000..c1d92f4cd9 --- /dev/null +++ b/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install/index.html @@ -0,0 +1,276 @@ + + + + + +Guide: Setting up openstack-health-monitor on Debian 12 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Guide: Setting up openstack-health-monitor on Debian 12

+

Kurt Garloff, 2024-02-20

+

Intro

+

The development of openstack-health-monitor was done on openSUSE 15.x images, just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution.

+

Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here.

+

Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a successor project for the increasingly hard to maintain shell code, this may not be worth the trouble.

+

openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested. +The scenario is described in a bit more detail in the repository's README.md file.

+

The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the monitoring section of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up.

+

Setting up the driver VM

+

So we start a Debian 12 image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard; +the instructions use flavor names and image names from the SCS standards. +For many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack).

+

Internal vs external monitoring

+

There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor.

+

The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems.

+

Unprivileged operation

+

Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own.

+

If openstack availability zone list --compute fails for you without admin rights, please fix your openstack client. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Healh-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)

+

Driver VM via openstack CLI

+

The author prefers to setup the VM via openstack CLI tooling. He has working entries for all clouds he uses in his ~/.config/openstack/clouds.yaml and secure.yaml and has exported the OS_CLOUD environment variable to point to the cloud he is working on to set up the driver VM. The author uses the bash shell. All of this of course could be scripted.

+

So here we go

+
    +
  1. Create the network setup for a VM in a network oshm-network with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network.
  2. +
+
PUBLIC=$(openstack network list --external -f value -c Name)
openstack router create oshm-router
openstack router set --external-gateway $PUBLIC oshm-driver-router
openstack network create oshm-network
openstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet
openstack router add subnet oshm-router oshm-subnet
+
    +
  1. Create a security group that allows ssh and ping access
  2. +
+
openstack security group create sshping
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping
openstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping
+
    +
  1. Being at it, we also create the security group for grafana
  2. +
+
openstack security group create grafana
openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana
+
    +
  1. To connect to the VM via ssh later, we create an SSH keypair
  2. +
+
openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key
chmod og-r ~/.ssh/oshm-key.pem
+

Rather than creating a new key (and storing and protecting the private key), we could have passed --public-key and used an existing keypair.

+
    +
  1. Look up Debian 12 image UUID.
  2. +
+
IMGUUID=$(openstack image list --name "Debian 12" -f value -c ID | tr -d '\r')
echo $IMGUUID
+

Sidenote: The tr command is there to handle broken tooling that embeds a trailing \r in the output.

+
    +
  1. Boot the driver VM
  2. +
+
openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver
+

Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing --block-device. See diskless flavor blog article. For flavors with local root disks, you could have used the --image $IMGUUID parameter instead.

+
    +
  1. Wait for it to boot (optional) +You can look at the boot log with openstack console log show oshm-driver or connect to it via VNC at the URL given by openstack console url show oshm-driver. You can of course also query openstack on the status openstack server list or openstack server show oshm-driver. You can also just create a simple loop:
  2. +
+
declare -i ctr=0 RC=0
while [ $ctr -le 120 ]; do
STATUS="$(openstack server list --name oshm-driver -f value -c Status)"
if [ "$STATUS" = "ACTIVE" ]; then echo "$STATUS"; break; fi
if [ "$STATUS" = "ERROR" ]; then echo "$STATUS"; RC=1; break; fi
if [ -z "$STATUS" ]; then echo "No such VM"; RC=2; break; fi
sleep 2
let ctr+=1
done
# return $RC
if [ $RC != 0 ]; then false; fi
+
    +
  1. Attach a floating IP so it's reachable from the outside.
  2. +
+
FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks |  sed "s@^[^:]*:[^']*'\([0-9\.]*\)'.*\$@\1@")
FIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID)
echo $FIXEDIP $FIXEDPORT
openstack floating ip create --port $FIXEDPORT $PUBLIC
FLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c "Floating IP Address")
echo "Floating IP: $FLOATINGIP"
+

Remember this floating IP address.

+
    +
  1. Connect to it via ssh
  2. +
+
ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP
+

On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.)

+

All the following commands are performed on the newly started driver VM.

+

Configuring openstack CLI on the driver VM

+

We need to install the openstack client utilities.

+
sudo apt-get update
sudo apt-get install python3-openstackclient
sudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient
+

Configure your cloud access in ~/.config/openstack/clouds.yaml

+
clouds:
CLOUDNAME:
interface: public
identity-api-version: 3
#region_name: REGION
auth:
auth_url: KEYSTONE_ENDPOINT
project_id: PROJECT_UUID
#alternatively project_name and project_domain_name
user_domain_name: default
# change to your real domain
+

and secure.yaml (in the same directory)

+
clouds:
CLOUDNAME:
auth:
username: USERNAME
password: PASSWORD
+

The CLOUDNAME can be freely chosen. This is the value passed to the openstack CLI with --os-cloud or exported to your environment in OS_CLOUD. The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample clouds.yaml file that works (but lacks the password).

+

Protect your secure.yaml from being read by others: chmod 0600 ~/.config/openstack/secure.yaml.

+

If you are using application credentials instead of username, password to authenticate, you don't need to specify project_id nor project's nor user's domain names in clouds.yaml. Just (in secure.yaml):

+
clouds:
CLOUDNAME:
auth_type: v3applicationcredential
auth:
application_credential_id: APPCRED_ID
application_credential_secret: "APPCRED_SECRET"
+

Configure this to be your default cloud:

+
export OS_CLOUD=CLOUDNAME
+

You might consider adding this to your ~/.bashrc for convenience. Being at it, you might want to add export CLIFF_FIT_WIDTH=1 there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste).

+

Verify that your openstack CLI works:

+
openstack catalog list
openstack server list
+

You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases.

+

Custom CA

+

If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in /etc/ssl/certs/ca-certificates.crt. You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the debian user.

+

Add it to your clouds.yaml

+
clouds:
CLOUDNAME:
cacert: /PATH/TO/CACERT.CRT
[...]
+

If you want to allow api_monitor.sh to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment:

+
export OS_CACERT=/PATH/TO/CACERT.CRT
+

Consider adding this to your ~/.bashrc as well.

+

Your first api_monitor.sh iteration

+

Checkout openstack-health-monitor:

+
sudo apt-get install git bc jq netcat-traditional tmux zstd
git clone https://github.com/SovereignCloudStack/openstack-health-monitor
cd openstack-health-monitor
+

You may want to start a tmux (or screen) session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect.

+

The script api_monitor.sh is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the README.md file.

+

It is good practice to use tmux. This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to screen over tmux.

+

You should be ready to run one iteration of the openstack-health-monitor now. Run it like this:

+
export IMG="Debian 12"
export JHIMG="Debian 12"
./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1
+

Leave out the -LL if you don't have a working loadbalancer service or replace -LL with -LO if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources).

+

Feel free to study the meaning of all the command line parameters by looking at the README.md. (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.)

+

This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs DOWN, BUILD, creating are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual openstack RESOURCE list and openstack RESOURCE show NAME and RESOURCE being something like router, network, subnet, port, volume, server, floating ip, loadbalancer, loadbalancer pool, loadbalancer listener, security group, keypair, image, ...)

+

The api_monitor.sh uses and APIMonitor_TIMESTAMP prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong. +TIMESTAMP is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time).

+

This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least -N 2 to test the ability of the router to route traffic between networks. So expect -n 6 to become -N 2 -n 6 for a very small single-AZ cloud or -n 12 for a large 3 AZ cloud region. So, re-run the api_monitor.sh with the target sizing.

+

Resource impact and charging

+

Note that api_monitor.sh uses small flavors (SCS-1V-2 for the N jump hosts and SCS-1L-1 for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors.

+

If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run api_monitor.sh in a loop (which you will) with say 10 VMs (e.g. -N 2 -n 8) in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference.

+

Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of openstack volume list, openstack volume show BROKEN_VOLUME, openstack loadbalancer list, openstack loadbalancer show BROKEN_LB.)

+

Using -w -1 makes api_monitor.sh wait for interactive input whenever an error occurs; this can be convenient for debugging.

+

Once you have single iterations working nicely, we can proceed.

+

Automating startup and cleanup

+

Typically, we run api_monitor.sh with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here.

+
#!/bin/bash
# run_CLOUDNAME.sh
# Do some global settings
export IMG="Debian 12"
export JHIMG="Debian 12"
#export OS_CACERT=/home/debian/ca-certificates.pem
# Additional settings to override flavors or to
# configure email addresses for sending alarms can be set here

# Does openstack CLI work?
openstack server list >/dev/null || exit 1
# Upload log files to this swift container (which you need to create)
#export SWIFTCONTAINER=OS-HM-Logfiles

# CLEANUP
echo "Finding resources from previous runs to clean up ..."
# Find Floating IPs
FIPLIST=""
FIPS=$(openstack floating ip list -f value -c ID)
for fip in $FIPS; do
FIP=$(openstack floating ip show $fip | grep -o "APIMonitor_[0-9]*")
if test -n "$FIP"; then FIPLIST="${FIPLIST}${FIP}_
"; fi
done
FIPLIST=$(echo "$FIPLIST" | grep -v '^$' | sort -u)
# Cleanup previous interrupted runs
SERVERS=$(openstack server list | grep -o "APIMonitor_[0-9]*_" | sort -u)
KEYPAIR=$(openstack keypair list | grep -o "APIMonitor_[0-9]*_" | sort -u)
VOLUMES=$(openstack volume list | grep -o "APIMonitor_[0-9]*_" | sort -u)
NETWORK=$(openstack network list | grep -o "APIMonitor_[0-9]*_" | sort -u)
LOADBAL=$(openstack loadbalancer list | grep -o "APIMonitor_[0-9]*_" | sort -u)
ROUTERS=$(openstack router list | grep -o "APIMonitor_[0-9]*_" | sort -u)
SECGRPS=$(openstack security group list | grep -o "APIMonitor_[0-9]*_" | sort -u)
echo CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS
for ENV in $FIPLIST; do
echo "******************************"
echo "CLEAN $ENV"
bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV
echo "******************************"
done
TOCLEAN=$(echo "$SERVERS
$KEYPAIR
$VOLUMES
$NETWORK
$LOADBAL
$ROUTERS
$SECGRPS
" | grep -v '^$' | sort -u)
for ENV in $TOCLEAN; do
echo "******************************"
echo "CLEAN $ENV"
bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV
echo "******************************"
done

# Now run the monitor
#exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab "$@"
exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T "$@"
+

Compared to the previous run, we have explicitly set two networks here -N 2 and rely on the iterations being passed in as command line arguments. Add parameter -t if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (-LO) in this example rather than the amphora based one (-LL).

+

You may use one of the existing run_XXXX.sh scripts as example. Beware: eMail alerting with ALARM_EMAIL_ADDRESS and NOTE_EMAIL_ADDRESS (and limiting with -a and -R ) and reporting data to telegraf (option -S) may be present in the samples. Make this script executable (chmod +x run_CLOUDNAME.sh).

+

We wrap a loop around this in run_in_loop.sh:

+
#!/bin/bash
# run_in_loop.sh
rm stop-os-hm 2>/dev/null
while true; do
./run_CLOUDNAME.sh -i 200
if test -e stop-os-hm; then break; fi
echo -n "Hit ^C to abort ..."
sleep 15; echo
done
+

Also make this executable (chmod +x run_in_loop.sh). +To run this automatically in a tmux window whenever the system starts, we follow the steps in the startup README.md

+

Change OS_CLOUD in startup/run-apimon-in-tmux.sh. (If you need to set OS_CACERT, also add it in this file and pass it into the windows.)

+

Activate everything:

+
mkdir -p ~/.config/systemd/user/
cp -p startup/apimon.service ~/.config/systemd/user/
systemctl --user enable apimon
systemctl --user start apimon
sudo loginctl enable-linger debian
tmux attach oshealthmon
+

This assumes that you are using the user debian for this monitoring and have checked out the repository at ~/openstack-health-monitor/. Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)

+

Changing parameters and restarting

+

If you want to change the parameters passed to api_monitor.sh, you best do this by editing run_CLOUDNAME.sh, potentially after testing it with one iteration before.

+

To make the change effective, you can wait until the current 200 iterations are completed and the run_in_loop.sh calls run_CLOUDNAME.sh again. You can also hit ^C in the tmux window that hasapi_monitor.sh running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ^C during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ^C twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ./run_in_loop.sh again.

+

You can also issue the systemctl --user stop apimon command; it will basically do the same thing: Send ^C and then wait for everything to be completed and tear down the tmux session. +After waiting for that to complete, you can start it again with systemctl --user start apimon.

+

Multiple instances

+

You can run multiple instances of api_monitor.sh on the same driver VM. In this case, you should rename run_in_loop.sh to e.g. run_in_loop_CLOUDNAME1.sh and call run_CLOUDNAME1.sh from there. Don't forget to adjust startup/run-apimon-in-tmux.sh and startup/kill-apimon-in-tmux.sh to start more windows.

+

It is not recommended to run multiple instances against the same OpenStack project however. While the api_monitor.sh script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the run_CLOUDNAME.sh script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations.

+

Alarming and Logs

+

eMail

+

If wanted, the api_monitor.sh can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the -a N and -R options. In order to enable sending emails from the driver VM, it needs to have postfix (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly.

+

Once you have configured postfix, you can enable eMail notifications using the option -e. Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ALARM_EMAIL_ADDRESSES and NOTE_EMAIL_ADDRESSES environment variables to api_monitor.sh, e.g. by setting it in the run_CLOUDNAME.sh.

+

Log files

+

api_monitor.sh writes a log file with the name APIMonitor_TIMESTAMP.log. It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (TIMESTAMP is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.)

+

Note that api_monitor.sh does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties.

+

The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable SWIFTCONTAINER has been set (in run_COULDNAME.sh) when starting api_monitor.sh. the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER

+

After the 200 iterations, a .psv file (pipe-separated values) is created Stats.STARTTIME-ENDTIME.psv (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured).

+

Data collection and dashboard

+

See https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md

+

telegraf

+

To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData:

+
sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key
echo "deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main" | sudo tee /etc/apt/sources.list.d/influxdata.list
sudo apt update
sudo apt -y install telegraf
+

In the config file /etc/telegraf/telegraf.conf, we enable

+
[[inputs.influxdb_listener]]
service_address = ":8186"

[[outputs.influxdb]]
urls = ["http://127.0.0.1:8086"]
+

and restart the service (sudo systemctl restart telegraf). +Enable it on system startup: sudo systemctl enable telegraf.

+

influxdb

+

We proceed to influxdb:

+
sudo apt-get install influxdb
+

In the configuration file /etc/influxdb/influxdb.conf, ensure that the http interface on port 8086 is enabled.

+
[http]
enabled = true
bind-address = ":8086"
+

Restart influxdb as needed with sudo systemctl restart influxdb. +Also enable it on system startup: sudo systemctl enable influxdb.

+

Add -S CLOUDNAME to your run_CLOUDNAME.sh script

+

You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter -S CLOUDNAME to the api_monitor.sh call in run_CLOUDNAME.sh. Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete).

+

grafana

+

Basic config

+

Finally grafana: We (still as root) follow https://www.server-world.info/en/note?os=Debian_12&p=grafana

+
sudo wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt -y install grafana
+

The config file /etc/grafana/grafana.ini needs some adjustments:

+
    +
  • Set the hostname in [server] section: domain = health.YOURCLOUD.sovereignit.cloud. Set the protocol = https if not enabled by default. +You can use a hostname of your liking, but we will need to create TLS certificates for this host. So we should have control over DNS TXT records for this domain if we want to use Let's Encrypt with DNSAUTH. The sovereignit.cloud domain is controlled by the SCS project team and has been used for a number of health mon instances. +In this same section, set cert_file = /etc/grafana/health-fullchain.pem and cert_key = /etc/grafana/health-key.pem. Ensure that both files are readable by root:grafana and that the key file is not world-readable.
  • +
  • Configure the admin access. In section [security], set the admin_user = admin and admin_password = SOME_SECRET_PASS which you keep private.
  • +
  • Allow local data sources (same section): data_source_proxy_whitelist = localhost:8088 localhost:8086
  • +
  • Let's disallow user signup (in section [users]): allow_sign_up = false and allow_org_create = false.
  • +
  • We do the OIDC connection with [auth.github] later.
  • +
+

We can now restart the service: sudo systemctl restart grafana-server. +Being at it, also enable it on system startup: sudo systemctl enable grafana-server.

+

You should now be able to access your dashboard on https://health.YOURCLOUD.sovereignit.de:3000 and log in via the configured username admin and your SOME_SECRET_PASS password.

+

Enable influx database in grafana

+

In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to http://localhost:8086 (despite this being the suggestion). Set the database name to telegraf. Save&test should succeed.

+

Importing the dashboard

+

Go to Home, Dashboards, New, Import. +Upload the dashboard .json file from the repository, user the Grafana-10 variant if you use Grafana 10 or newer.

+

In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.) +Save.

+

Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable).

+

No data displayed?

+

Sometimes, you may see a panel displaying "no data" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana.

+

One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved.

+

Dashboard features

+

Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended.

+

The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously.

+

You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term.

+

github OIDC integration

+

The SCS providers do allow all github users that belong to the SovereignCloudStack organization to get Viewer access to the dashboards by adding a client_id and client_secret in the [github.auth] section that you request from the SCS github admins (github's oauth auth). This allows to exchange experience and to get a feeling for the achievable stability. (Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)

+

Alternative approach to install and configure the dashboard behind a reverse proxy

+

Install influxdb via apt: https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss +Install telegraf (same apt repo as influxdb): sudo apt update && sudo apt install telegraf +Install grafana: https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository

+

Prepare configuration by using the config files from the repository as an alternative to doing the changes manually (as described above):

+
sudo cp dashboard/telegraf.conf /etc/telegraf && sudo chown root:root /etc/telegraf/telegraf.conf && sudo chmod 0644 /etc/telegraf/telegraf.conf
sudo cp dashboard/config.toml /etc/influxdb && sudo chown root:influxdb /etc/influxdb/config.toml && sudo chmod 0640 /etc/influxdb/config.toml
sudo cp dashboard/grafana.ini /etc/grafana && sudo chown root:grafana /etc/grafana/grafana.ini && sudo chmod 0640 /etc/grafana/grafana.ini
+

These config files should work as long as the versions of telegraf, influxdb and grafana don't evolve too far from the ones used in the repository. (Otherwise refer to above instructions how to tweak the default config files.)

+

Changes to /etc/grafana/grafana.ini as we do tls termination at the reverse proxy:

+
    +
  • set protocol = http
  • +
  • comment out domain option (? FIXME) or set it to the hostname
  • +
  • comment out cert_* options
  • +
+

Also change the admin password in grafana.ini.

+

Changes to /etc/grafana/grafana.ini if github auth should not be used yet:

+
    +
  • comment out whole [auth.github] section for now (can be enabled later)
  • +
+

Restart services: sudo systemctl restart telegraf && sudo systemctl restart influxdb && sudo systemctl restart grafana-server

+

Configuration in grafana web gui:

+
    +
  • Login to grafana http(s)://<domain>:3000 with user admin and default password from /etc/grafana/grafana.ini and change password.
  • +
  • Create influxdb datasource with url http://localhost:8086 and database name telegraf.
  • +
  • Finally import dashboard dashboard/openstack-health-dashboard.json to grafana.
  • +
+

TODO:

+
    +
  • Reverse proxy (aka ingress) with Let's Encrypt cert
  • +
  • Github auth as described above
  • +
+

Maintenance

+

The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained.

+

Unattended upgrades

+

It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See https://wiki.debian.org/UnattendedUpgrades. If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and grafana (port 3000).

+

Updating openstack-health-monitor

+

You can just do a git update in the openstack-health-monitor directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ^C, see above in the restart section.

+

Backup

+

The system holds two things that you might consider valuable for long-term storage: +(1) The log files. These are compressed and uploaded to object storage if you enable the SWIFTCONTAINER setting, which probably means that these do not need any additional backing up then. +(2) The influx time series data. Back up the data in /var/lib/influxdb.

+

Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, clouds.yaml, etc. Be careful not to expose sensitive data by granting too generous access to your backed up files.

+

Troubleshooting

+

Debugging issues

+

In case there is trouble with your cloud, the normal course of action to analyze is as follows:

+
    +
  • Look at the dashboard (see above)
  • +
  • Connect to the driver VM and attach to the tmux session and look at the console output of api_monitor.sh
  • +
  • Analyze the logfile (locally on the driver VM or grab it from the object storage)
  • +
+

Analyzing failures

+

When VM instances are created successfully, but then end up in ERROR state, the api_monitor.sh does an explicit openstack server show, so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files.

+

Sometimes the VMs end up being ACTIVE as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail.

+

To gather more details, you can look at the console output openstack console log show VM (where VM is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ssh -i APIMonitor_XXXXX_JH.pem debian@FIP, whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP. Replace XXXXX with the number in your current APIMonitor prefix, FIP with the floating IP address of the responsible JumpHost and debian with the user name used by the images you boot. Use 223 to connect to the second VM in the network, 224 the third etc.

+

When logged in, look at /var/log/cloud-init-output.log and /var/log/cloud-init.log. You can find the metadata in /var/lib/cloud/instance/.

+

You will not have much time to look around -- the still running api_monitor.sh script does continue and clean things up again. So you might want to suspend it with ^Z (and continue it later with fg). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the run_CLOUDNAME.sh script as it would do cleanup against the running instance, but rather copy the api_monitor.sh command line from the bottom (without the exec), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach -w -1 to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work.

+

Cleaning things up

+

If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard).

+

There are a few things that may need support from a cloud admin:

+
    +
  • Volumes may end up permanently in a deleting or reserved state or may be in-use, attached to a VM that has long gone. The admin needs to set the state to error and then delete them.
  • +
  • Loadbalancers may end up in a PENDING_XXX state (XXX being CREATE, UPDATE or DELETE) without ever changing. This also needs the cloud admin to set the status to ERROR, so it can be cleaned up. amphorae are more prone to this than ovn LBs.
  • +
+

More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted.

+ + \ No newline at end of file diff --git a/docs/operating-scs/incident-management/index.html b/docs/operating-scs/incident-management/index.html new file mode 100644 index 0000000000..a40f15d885 --- /dev/null +++ b/docs/operating-scs/incident-management/index.html @@ -0,0 +1,24 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/lifecycle-management/index.html b/docs/operating-scs/lifecycle-management/index.html new file mode 100644 index 0000000000..7bbba3c662 --- /dev/null +++ b/docs/operating-scs/lifecycle-management/index.html @@ -0,0 +1,24 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/logging/index.html b/docs/operating-scs/logging/index.html new file mode 100644 index 0000000000..72b437b19e --- /dev/null +++ b/docs/operating-scs/logging/index.html @@ -0,0 +1,24 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/metering/meter_configuration/index.html b/docs/operating-scs/metering/meter_configuration/index.html new file mode 100644 index 0000000000..d39440b6d3 --- /dev/null +++ b/docs/operating-scs/metering/meter_configuration/index.html @@ -0,0 +1,43 @@ + + + + + +Metering Configuration | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Metering Configuration

The Metrics and events we want to use in the metering process can be defined in two ways. The first one is to allow ceilometer to poll distinct metrics and events. +This can be achived by setting up ceilometers config files.

+

1. ceilometer metering configuration

+

there is the polling.yaml file that describes what metrics to poll and when. It allows to create multiple sources for the ceilometer pipeline with different metrics and intervals.

+

ceilometer polling +ceilometer polling metrics

+

1.1 polling.yaml

+
---
sources:
- name: billing_source # 'source name'
interval: 300 # 'how often the samples should be generated'
meters:
- "volume.size" # 'meter filter'
# - "*" # 'using all pollsters
+

in the event_definitions file all data structure of events are defined. If a message with a distinct event_type appears, the Fields and values from the message are matched with the Event-object.

+

ceilometer events +ceilometer event_definitions

+

1.2 event_definitions.yaml

+
---
- event_type: "compute.instance.*"
traits: &instance_traits
tenant_id:
fields: payload.tenant_id
user_id:
fields: payload.user_id
instance_id:
fields: payload.instance_id
display_name:
fields: payload.display_name
resource_id:
fields: payload.instance_id
cell_name:
fields: payload.cell_name
host:
fields: publisher_id.`split(., 1, 1)`
service:
fields: publisher_id.`split(., 0, -1)`
memory_mb:
type: int
fields: payload.memory_mb
disk_gb:
type: int
fields: payload.disk_gb
root_gb:
type: int
fields: payload.root_gb
ephemeral_gb:
type: int
fields: payload.ephemeral_gb
vcpus:
type: int
fields: payload.vcpus
instance_type_id:
fields: payload.instance_type_id
instance_type:
fields: payload.instance_type
state:
fields: payload.state
os_architecture:
fields: payload.image_meta.'org.openstack__1__architecture'
os_version:
fields: payload.image_meta.'org.openstack__1__os_version'
os_distro:
fields: payload.image_meta.'org.openstack__1__os_distro'
launched_at:
type: datetime
fields: payload.launched_at
deleted_at:
type: datetime
fields: payload.deleted_at
- event_type: compute.instance.create.end
traits:
<<: *instance_traits
availability_zone:
fields: payload.availability_zone
- event_type: compute.instance.update
traits:
<<: *instance_traits
old_state:
fields: payload.old_state
- event_type: compute.instance.exists
traits:
<<: *instance_traits
audit_period_beginning:
type: datetime
fields: payload.audit_period_beginning
audit_period_ending:
type: datetime
fields: payload.audit_period_ending
- event_type:
[
"volume.exists",
"volume.retype",
"volume.create.*",
"volume.delete.*",
"volume.resize.*",
"volume.attach.*",
"volume.detach.*",
"volume.update.*",
"snapshot.exists",
"snapshot.create.*",
"snapshot.delete.*",
"snapshot.update.*",
"volume.transfer.accept.end",
"snapshot.transfer.accept.end",
]
traits: &cinder_traits
user_id:
fields: payload.user_id
project_id:
fields: payload.tenant_id
availability_zone:
fields: payload.availability_zone
display_name:
fields: payload.display_name
replication_status:
fields: payload.replication_status
status:
fields: payload.status
created_at:
type: datetime
fields: payload.created_at
image_id:
fields: payload.glance_metadata[?key=image_id].value
instance_id:
fields: payload.volume_attachment[0].server_id
- event_type:
[
"volume.transfer.*",
"volume.exists",
"volume.retype",
"volume.create.*",
"volume.delete.*",
"volume.resize.*",
"volume.attach.*",
"volume.detach.*",
"volume.update.*",
"snapshot.transfer.accept.end",
]
traits:
<<: *cinder_traits
resource_id:
fields: payload.volume_id
host:
fields: payload.host
size:
type: int
fields: payload.size
type:
fields: payload.volume_type
replication_status:
fields: payload.replication_status
- event_type: ["snapshot.transfer.accept.end"]
traits:
<<: *cinder_traits
resource_id:
fields: payload.snapshot_id
project_id:
fields: payload.tenant_id
- event_type:
["share.create.*", "share.delete.*", "share.extend.*", "share.shrink.*"]
traits: &share_traits
share_id:
fields: payload.share_id
user_id:
fields: payload.user_id
project_id:
fields: payload.tenant_id
snapshot_id:
fields: payload.snapshot_id
availability_zone:
fields: payload.availability_zone
status:
fields: payload.status
created_at:
type: datetime
fields: payload.created_at
share_group_id:
fields: payload.share_group_id
size:
type: int
fields: payload.size
name:
fields: payload.name
proto:
fields: payload.proto
is_public:
fields: payload.is_public
description:
fields: payload.description
host:
fields: payload.host
- event_type:
[
"snapshot.exists",
"snapshot.create.*",
"snapshot.delete.*",
"snapshot.update.*",
]
traits:
<<: *cinder_traits
resource_id:
fields: payload.snapshot_id
volume_id:
fields: payload.volume_id
- event_type: ["image_volume_cache.*"]
traits:
image_id:
fields: payload.image_id
host:
fields: payload.host
- event_type: ["image.create", "image.update", "image.upload", "image.delete"]
traits: &glance_crud
project_id:
fields: payload.owner
resource_id:
fields: payload.id
name:
fields: payload.name
status:
fields: payload.status
created_at:
type: datetime
fields: payload.created_at
user_id:
fields: payload.owner
deleted_at:
type: datetime
fields: payload.deleted_at
size:
type: int
fields: payload.size
- event_type: image.send
traits: &glance_send
receiver_project:
fields: payload.receiver_tenant_id
receiver_user:
fields: payload.receiver_user_id
user_id:
fields: payload.owner_id
image_id:
fields: payload.image_id
destination_ip:
fields: payload.destination_ip
bytes_sent:
type: int
fields: payload.bytes_sent
- event_type: orchestration.stack.*
traits: &orchestration_crud
project_id:
fields: payload.tenant_id
user_id:
fields: ["ctxt.trustor_user_id", "ctxt.user_id"]
resource_id:
fields: payload.stack_identity
name:
fields: payload.name
- event_type: sahara.cluster.*
traits: &sahara_crud
project_id:
fields: payload.project_id
user_id:
fields: ctxt.user_id
resource_id:
fields: payload.cluster_id
name:
fields: payload.name
- event_type: sahara.cluster.health
traits: &sahara_health
<<: *sahara_crud
verification_id:
fields: payload.verification_id
health_check_status:
fields: payload.health_check_status
health_check_name:
fields: payload.health_check_name
health_check_description:
fields: payload.health_check_description
created_at:
type: datetime
fields: payload.created_at
updated_at:
type: datetime
fields: payload.updated_at
- event_type:
[
"identity.user.*",
"identity.project.*",
"identity.group.*",
"identity.role.*",
"identity.OS-TRUST:trust.*",
"identity.region.*",
"identity.service.*",
"identity.endpoint.*",
"identity.policy.*",
]
traits: &identity_crud
resource_id:
fields: payload.resource_info
initiator_id:
fields: payload.initiator.id
project_id:
fields: payload.initiator.project_id
domain_id:
fields: payload.initiator.domain_id
- event_type: identity.role_assignment.*
traits: &identity_role_assignment
role:
fields: payload.role
group:
fields: payload.group
domain:
fields: payload.domain
user:
fields: payload.user
project:
fields: payload.project
- event_type: identity.authenticate
traits: &identity_authenticate
typeURI:
fields: payload.typeURI
id:
fields: payload.id
action:
fields: payload.action
eventType:
fields: payload.eventType
eventTime:
type: datetime
fields: payload.eventTime
outcome:
fields: payload.outcome
initiator_typeURI:
fields: payload.initiator.typeURI
initiator_id:
fields: payload.initiator.id
initiator_name:
fields: payload.initiator.name
initiator_host_agent:
fields: payload.initiator.host.agent
initiator_host_addr:
fields: payload.initiator.host.address
target_typeURI:
fields: payload.target.typeURI
target_id:
fields: payload.target.id
observer_typeURI:
fields: payload.observer.typeURI
observer_id:
fields: payload.observer.id
- event_type: objectstore.http.request
traits: &objectstore_request
typeURI:
fields: payload.typeURI
id:
fields: payload.id
action:
fields: payload.action
eventType:
fields: payload.eventType
eventTime:
type: datetime
fields: payload.eventTime
outcome:
fields: payload.outcome
initiator_typeURI:
fields: payload.initiator.typeURI
initiator_id:
fields: payload.initiator.id
initiator_project_id:
fields: payload.initiator.project_id
target_typeURI:
fields: payload.target.typeURI
target_id:
fields: payload.target.id
target_action:
fields: payload.target.action
target_metadata_path:
fields: payload.target.metadata.path
target_metadata_version:
fields: payload.target.metadata.version
target_metadata_container:
fields: payload.target.metadata.container
target_metadata_object:
fields: payload.target.metadata.object
observer_id:
fields: payload.observer.id
- event_type:
[
"network.*",
"subnet.*",
"port.*",
"router.*",
"floatingip.*",
"firewall.*",
"firewall_policy.*",
"firewall_rule.*",
"vpnservice.*",
"ipsecpolicy.*",
"ikepolicy.*",
"ipsec_site_connection.*",
]
traits: &network_traits
user_id:
fields: ctxt.user_id
project_id:
fields: ctxt.tenant_id
- event_type: network.*
traits:
<<: *network_traits
name:
fields: payload.network.name
resource_id:
fields: ["payload.network.id", "payload.id"]
- event_type: subnet.*
traits:
<<: *network_traits
name:
fields: payload.subnet.name
resource_id:
fields: ["payload.subnet.id", "payload.id"]
- event_type: port.*
traits:
<<: *network_traits
name:
fields: payload.port.name
resource_id:
fields: ["payload.port.id", "payload.id"]
- event_type: router.*
traits:
<<: *network_traits
name:
fields: payload.router.name
resource_id:
fields: ["payload.router.id", "payload.id"]
- event_type: floatingip.*
traits:
<<: *network_traits
resource_id:
fields: ["payload.floatingip.id", "payload.id"]
- event_type: firewall.*
traits:
<<: *network_traits
name:
fields: payload.firewall.name
resource_id:
fields: ["payload.firewall.id", "payload.id"]
- event_type: firewall_policy.*
traits:
<<: *network_traits
name:
fields: payload.firewall_policy.name
resource_id:
fields: ["payload.firewall_policy.id", "payload.id"]
- event_type: firewall_rule.*
traits:
<<: *network_traits
name:
fields: payload.firewall_rule.name
resource_id:
fields: ["payload.firewall_rule.id", "payload.id"]
- event_type: vpnservice.*
traits:
<<: *network_traits
name:
fields: payload.vpnservice.name
resource_id:
fields: ["payload.vpnservice.id", "payload.id"]
- event_type: ipsecpolicy.*
traits:
<<: *network_traits
name:
fields: payload.ipsecpolicy.name
resource_id:
fields: ["payload.ipsecpolicy.id", "payload.id"]
- event_type: ikepolicy.*
traits:
<<: *network_traits
name:
fields: payload.ikepolicy.name
resource_id:
fields: ["payload.ikepolicy.id", "payload.id"]
- event_type: ipsec_site_connection.*
traits:
<<: *network_traits
resource_id:
fields: ["payload.ipsec_site_connection.id", "payload.id"]
- event_type: "*http.*"
traits: &http_audit
project_id:
fields: payload.initiator.project_id
user_id:
fields: payload.initiator.id
typeURI:
fields: payload.typeURI
eventType:
fields: payload.eventType
action:
fields: payload.action
outcome:
fields: payload.outcome
id:
fields: payload.id
eventTime:
type: datetime
fields: payload.eventTime
requestPath:
fields: payload.requestPath
observer_id:
fields: payload.observer.id
target_id:
fields: payload.target.id
target_typeURI:
fields: payload.target.typeURI
target_name:
fields: payload.target.name
initiator_typeURI:
fields: payload.initiator.typeURI
initiator_id:
fields: payload.initiator.id
initiator_name:
fields: payload.initiator.name
initiator_host_address:
fields: payload.initiator.host.address
- event_type: "*http.response"
traits:
<<: *http_audit
reason_code:
fields: payload.reason.reasonCode
- event_type: ["dns.domain.create", "dns.domain.update", "dns.domain.delete"]
traits: &dns_domain_traits
status:
fields: payload.status
retry:
fields: payload.retry
description:
fields: payload.description
expire:
fields: payload.expire
email:
fields: payload.email
ttl:
fields: payload.ttl
action:
fields: payload.action
name:
fields: payload.name
resource_id:
fields: payload.id
created_at:
type: datetime
fields: payload.created_at
updated_at:
type: datetime
fields: payload.updated_at
version:
fields: payload.version
parent_domain_id:
fields: parent_domain_id
serial:
fields: payload.serial
- event_type: dns.domain.exists
traits:
<<: *dns_domain_traits
audit_period_beginning:
type: datetime
fields: payload.audit_period_beginning
audit_period_ending:
type: datetime
fields: payload.audit_period_ending
- event_type: trove.*
traits: &trove_base_traits
instance_type:
fields: payload.instance_type
user_id:
fields: payload.user_id
resource_id:
fields: payload.instance_id
instance_type_id:
fields: payload.instance_type_id
launched_at:
type: datetime
fields: payload.launched_at
instance_name:
fields: payload.instance_name
state:
fields: payload.state
nova_instance_id:
fields: payload.nova_instance_id
service_id:
fields: payload.service_id
created_at:
type: datetime
fields: payload.created_at
region:
fields: payload.region
- event_type:
[
"trove.instance.create",
"trove.instance.modify_volume",
"trove.instance.modify_flavor",
"trove.instance.delete",
]
traits: &trove_common_traits
name:
fields: payload.name
availability_zone:
fields: payload.availability_zone
instance_size:
type: int
fields: payload.instance_size
volume_size:
type: int
fields: payload.volume_size
nova_volume_id:
fields: payload.nova_volume_id
- event_type: trove.instance.create
traits:
<<: [*trove_base_traits, *trove_common_traits]
- event_type: trove.instance.modify_volume
traits:
<<: [*trove_base_traits, *trove_common_traits]
old_volume_size:
type: int
fields: payload.old_volume_size
modify_at:
type: datetime
fields: payload.modify_at
- event_type: trove.instance.modify_flavor
traits:
<<: [*trove_base_traits, *trove_common_traits]
old_instance_size:
type: int
fields: payload.old_instance_size
modify_at:
type: datetime
fields: payload.modify_at
- event_type: trove.instance.delete
traits:
<<: [*trove_base_traits, *trove_common_traits]
deleted_at:
type: datetime
fields: payload.deleted_at
- event_type: trove.instance.exists
traits:
<<: *trove_base_traits
display_name:
fields: payload.display_name
audit_period_beginning:
type: datetime
fields: payload.audit_period_beginning
audit_period_ending:
type: datetime
fields: payload.audit_period_ending
- event_type: profiler.*
traits:
project:
fields: payload.project
service:
fields: payload.service
name:
fields: payload.name
base_id:
fields: payload.base_id
trace_id:
fields: payload.trace_id
parent_id:
fields: payload.parent_id
timestamp:
type: datetime
fields: payload.timestamp
host:
fields: payload.info.host
path:
fields: payload.info.request.path
query:
fields: payload.info.request.query
method:
fields: payload.info.request.method
scheme:
fields: payload.info.request.scheme
db.statement:
fields: payload.info.db.statement
db.params:
fields: payload.info.db.params
- event_type: "magnum.cluster.*"
traits: &magnum_cluster_crud
id:
fields: payload.id
typeURI:
fields: payload.typeURI
eventType:
fields: payload.eventType
eventTime:
type: datetime
fields: payload.eventTime
action:
fields: payload.action
outcome:
fields: payload.outcome
initiator_id:
fields: payload.initiator.id
initiator_typeURI:
fields: payload.initiator.typeURI
initiator_name:
fields: payload.initiator.name
initiator_host_agent:
fields: payload.initiator.host.agent
initiator_host_address:
fields: payload.initiator.host.address
target_id:
fields: payload.target.id
target_typeURI:
fields: payload.target.typeURI
observer_id:
fields: payload.observer.id
observer_typeURI:
fields: payload.observer.typeURI
- event_type: "alarm.*"
traits:
id:
fields: payload.alarm_id
user_id:
fields: payload.user_id
project_id:
fields: payload.project_id
on_behalf_of:
fields: payload.on_behalf_of
severity:
fields: payload.severity
detail:
fields: payload.detail
type:
fields: payload.type
+

The event_pipeline can be used to filter events and pipeline them to different publishers. +the notifier publisher is the message queue broadcasster (RabbitMQ).

+

1.3 event_pipeline.yaml

+
---
sources:
- name: event_source # 'source name'
events:
- "*" # 'event filter'
sinks:
- event_sink # 'sink name'
sinks:
- name: event_sink # 'sink name'
publishers: # 'list of publishers'
- notifier://
- http://localhost:8088/post_json
+

The pipeline.yaml can be used to filter and pipeline all metrics and events since events send via the notifier also appears in the meters and send them to different publishers.

+

In our case we want to push to the metering api.

+

1.4 pipeline.yaml

+
---
sources:
- name: meter_source
meters:
- "*"
sinks:
- meter_sink
sinks:
- name: meter_sink
publishers:
- gnocchi://?archive_policy=ceilometer-low&filter_project=service
- http://localhost:8088/post_json
+ + \ No newline at end of file diff --git a/docs/operating-scs/monitoring/index.html b/docs/operating-scs/monitoring/index.html new file mode 100644 index 0000000000..71ca753fbb --- /dev/null +++ b/docs/operating-scs/monitoring/index.html @@ -0,0 +1,24 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/operating-scs/overview/index.html b/docs/operating-scs/overview/index.html new file mode 100644 index 0000000000..9d28b0a618 --- /dev/null +++ b/docs/operating-scs/overview/index.html @@ -0,0 +1,24 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/docs/releases/Release0/index.html b/docs/releases/Release0/index.html new file mode 100644 index 0000000000..2a6c8da399 --- /dev/null +++ b/docs/releases/Release0/index.html @@ -0,0 +1,80 @@ + + + + + +Release Notes for SCS Release 0 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Release Notes for SCS Release 0

+

(Release Date: 2021-07-15)

+

Scope

+

The main focus of R0 is to demonstrate the viability of our approach to a much broader +audience by providing a well-documented testbed. This will allow anyone interested +to study the system in real-life, test, contribute, compare, ... it.

+

Also we learn performing the release process.

+

Features

+

Fully automated virtual (testbed setup) with ansible (terraform bootstrap to create +storage, networking and VM resources for bootstrapping via cloud-init injected +scripts that call ansible).)

+

The infrastructure, management and openstack services are all deployed in containers.

+

Included tools for Operations: ARA, Netbox, Cockpit, Netdata, Skydive (opt-in), +Patchman, phpMyAdmin, Elasticsearch (b/f license change), Kibana, Grafana, influxdb

+

Validation: Rally, Refstack

+

Infrastructure: Linux, KVM, ceph (pacific), OpenVSwitch, OVN, MariaDB, RabbitMQ, Redis, +Etcd, HAproxy, Keepalived, Memcached, Keycloak

+

IaaS (OpenStack - Wallaby): keystone, nova, glance, cinder, neutron, octavia, horizon

+

Optional OpenStack services: designate, heat, gnocchi, ceilometer, aodh, panko, senlin, +barbican, manila, magnum

+

See testbed SBOM for +a complete list. The exact versions of the contained components can be retrieved from the +release repo of OSISM.

+

Get SCS

+

See main README.

+

Known Bugs

+

Nothing major known yet.

+

Technical Previews

+

While already in productive use (on bare metal) by two providers, the bare metal +setup currently has a few more manual steps than we would like. This will improve +with the next releases.

+

We have worked hard on supporting identity federation (OIDC and SAML) during the last +few months. We have also spent significant effort on getting the k8s stack with +k8s cluster API into a good shape. However, we have determined that we do not +yet consider those two key pieces as production-ready. The goal is to change that +for R1 (see below).

+

For now, you can use the software to see where SCS is going and test our technical +preview code. We really appreciate feedback we get on these pieces as well. +However keep in mind that we do not guarantee to ship technical previews from +a Release as production-ready software in one of the next releases. We certainly +hope to do so.

+

To test how our k8s aaS platform will look like, have a look at the +k8s-cluster-api-provider repository +You can follow the documentation to set up the k8s cluster API on an SCS +cloud (or other well configured OpenStack clouds that support octavia).

+

The openstack-health-monitor +is used by us to monitor that the API works and successfully creates working resources +in finite time. We plan to integrate it with a dashboard and an alarming mechanism in +the next releases.

+

Release tagging

+

See Release Numbering scheme. +The containers have version number v1.0.0 for R0.

+

Updates

+

Updating the software can conveniently be done from the manager node by running the +ansible playbooks again. Details are in the +OSISM testbed documentation.

+

Bug reporting

+

See main README file.

+ + \ No newline at end of file diff --git a/docs/releases/Release1/index.html b/docs/releases/Release1/index.html new file mode 100644 index 0000000000..aabff44dd1 --- /dev/null +++ b/docs/releases/Release1/index.html @@ -0,0 +1,178 @@ + + + + + +Release Notes for SCS Release 1 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Release Notes for SCS Release 1

+

(Release Date: 2021-09-29)

+

Scope

+

Main goals for Release 1 (R1) was the strengthening of our CI test coverage and +integration, the operational tooling (metrics collection, dashboards, logging), +latest versions of upstream software (OpenStack Wallaby, Kubernetes-1.21.5), +support for Bare Metal service, progress on user federation for clouds, and +progress on the integration of the container layer with k8s Cluster API (now in +version 0.4.x).

+

CI framework

+

Zuul-CI

+

For our internal development workflows we are planning to switch from GitHub +Actions to Zuul-CI (mostly). The infrastructure itself is already available, +yet most of the repositories in the SovereignCloudStack organisation have not +switched over. Reasons for switching include cross-dependencies, scalability +and costs. Reasons for using Zuul-CI include the close connection to the +OpenStack project and the enormous flexibility in comparison to other similar +tools. On top of that you have also gating instead of only CI. A quick example +for a Zuul-CI operated repository can be found here: +https://github.com/SovereignCloudStack/zuul-sandbox.

+

Metrics collection and dashboards

+

Prometheus exporters and Grafana dashboards

+

We provide generic configuration examples and blueprints for prometheus rules +and grafana dashboards. The examples need to be understood and adapted to the +particular needs of your environment. You can find the examples at +https://github.com/osism/kolla-operations].

+

With R2 we plan to implement a basic set of these alerts and dashboards in the +testbed deployment in order to make them even easier consumable for new users. +Feel free to give feedback on the examples and contribute your own generic +examples.

+

We're working on bringing a basic set of prometheus exporters to the +OpenStack-kolla upstream community.

+

As part of our effort to add more monitoring tooling, we're integrating further +prometheus exporters such as +libvirt and +ovn. Integration is +targeted for R2.

+

More detailed information on monitoring topics will be continously provided in +the corresponding design document.

+

openstack-health-monitor

+

We have made some progress with openstack-health-monitor since R0, but we have +not yet created ready-to-be-used influx data collection and the grafana +dashboard. While the black box monitoring is perceived as very useful, the +script certainly has reached a complexity that is not handled well with bash +scripting and makes it a difficult to maintain and even to use tool, so the +usefulness of shipping it with SCS to make it available for Ops teams to +monitor has been questioned. Instead an expectation has been expressed that the +SCS uses this to monitor all SCS partner clouds and provides some transparency +this way to the public -- and detailed statistics via e.g. a prometheus +exporter to the respective cloud provider. This is currently under consideration.

+

Logging

+

Central logging

+

OSISM now enables kolla-ansible centralized logging by default. The default +rules need to be further refined to suit your needs. We plan to implement a +more generic set of rules for R2.

+

Federation

+

OIDC support via keycloak

+

Logging in to Horizon by authenticating with OIDC via Keycloak is now possible. +For details see the testbed documentation.

+

non-TLS restrictions (testbed)

+

Only TLS secured deployments get full support. +Without TLS, certain browsers won't be able to log in. +For deatils see the testbed documentation

+

Known Issue with OIDC Logout

+

Clicking Sign Out on the Horizon dashboard doesn't perform +a proper OIDC logout. This is documented in osism testbed, +with some Keycloak settings that can be relevant for alleviating the issue, +but in Release 1 there is no solution for this yet.

+

Bare Metal Service

+

The ironic Bare Metal service can be deployed with the SCS (OSISM) +installation. For it to get full test coverage, a virtual BMC +solution has been created, so bare metal can be validated in our testbed +setup just as nicely as the other components. While most pieces +are ready, the final integration steps are still work-in-progress +and will happen after R1.

+

Container Layer

+

Overview and Goals for R1

+

The container layer on SCS is implemented as a Self-Service, +leveraging the Kubernetes cluster API +technology. This was provided as a technical preview from the +SCS k8s-cluster-api-provider +repository for R0 back in July.

+

The focus for R1 was to make it ready for production, so DevOps teams can +use this to create and manage their k8s clusters in self-service for +development, testing, deployment and production.

+

To achieve this, a lot of work has been invested, updating the +cluster API to 0.4 along the way, fixing snapshot classes, enabling +optional metrics and ingress services, using application credentials +and much improved management scripts. The sonobuoy test automation has +been included and successfully used to validate the created clusters. +Real-world testing has happened though the Gaia-X Hackathon #1, where +clusters were provided on the fly for the various work streams.

+

The detailed list of changes for R1 is covered in the +k8s capi provider Release Notes.

+

Still in technical preview, but very promising are the helm charts +based k8s cluster management templates also documented there.

+

Beyond CAPI

+

Some of our partners are using Gardener as a layer to manage +large fleets of (optionally cross-cloud) k8s clusters. While there is a bit of +overlap in functionality, they do happily coexist and our partner is actually +using k8s capi to bootstrap clusters on SCS clouds for Gardener management.

+

Standardization

+

As of this writing, the list of SCS defined standards still comprises +two standards:

+ +

As before, we continue to rely on OpenStack and CNCF defined standards +in addition to this -- the k8s clusters need to pass the conformance +tests with sonobuoy and the OpenStack environment the OpenStack powered +guidelines (with refstack).

+

There is a discussion on a glossary, detailing what we expect from regions, +availability zones etc. Some major parts of it still need to be agreed +before a useful doc can be published -- this will happen in due time and +is expected before R2.

+ +

We stand on the shoulders of giants: +Without all the great work from many open source communities, we would +not get anywhere.

+

We are working on automation to create a complete list for all the software +that is used and deployed with SCS, so we have a complete Software Bill +of Materials (SBoM). The reason this is non-trivial is that we are not +aggregating it all ourselves, but rely on pre-integrated pieces, such +as Linux distributions, OpenStack, CNCF projects etc. The good news is +that these projects are diligent in their work, making sure we don't need +to be too worried about security risks or legal risks introduced this way. +Nevertheless, the goal of creating a complete graph remains.

+

We have started to put SPDX license identifiers into the SCS produced +code, so we make it easier for downstream consumers of our software to +automate the license compliance checks when assembling an SBoM.

+

For R1, some of the major projects we build on have had releases that we +incorporated and whose release notes we want to link here for convenience:

+ +

Release tagging

+

See Release Numbering scheme -- unchanged from R0. +We have added the tag v2.0.0 to the relevant repositories to designate the SCS_RELEASE_R1.

+

List of known issues & restrictions in R1

+
+ + \ No newline at end of file diff --git a/docs/releases/Release2/index.html b/docs/releases/Release2/index.html new file mode 100644 index 0000000000..cea1edbb6c --- /dev/null +++ b/docs/releases/Release2/index.html @@ -0,0 +1,235 @@ + + + + + +Release Notes for SCS Release 2 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Release Notes for SCS Release 2

+

(Release Date: 2022-03-23)

+

Scope

+

Main goals for Release 2 (R2) were massive improvements in bare +metal deployment and our cluster management layer gaining the +ability to handle many clusters independently with a number +of optional services.

+

Component Versions and User-visible improvements (highlights)

+
    +
  • +

    We support the latest Kubernetes 1.22 and +1.23 releases.

    +
  • +
  • +

    The Kubernetes Cluster API is now available in a stable v1beta1 +release 1.0.x +with the corresponding cluster-api-provider-openstack 0.5.x.

    +
  • +
  • +

    There are a number of new standard services available for the +k8s capi +managed clusters, amongst which cert-manager and flux. The clusters +have better default settings for the nginx-ingress, anti-affinity +for the nodes and the ability to chose cilium over calico and +to have stable multi-controller node setups on clouds without +low-latency local storage. +Please consult the +k8s capi provider release notes +for more details.

    +
  • +
  • +

    OpenStack Xena release

    +
      +
    • We have also enabled SPICE support in addition to noVNC to +access the graphical console of VMs.
    • +
    +
  • +
  • +

    The base infrastructure is provided by +OSISM 3.0.0 +which in turn build on top of kolla and kolla-ansible.

    +
  • +
+

New Features (Highlights)

+

Operator focused improvements

+
    +
  • +

    The Cluster Management Node is now well prepared to manage numerous +clusters with independent settings and different feature sets by +creating default settings and then keeping track of various workload +clusters in own directories. Documentation has been vastly improved.

    +
  • +
  • +

    The Cluster Management node now gets its artifacts directly from +git, making incremental updates to it a lot easier, thus also +avoiding to disrupt workload clusters through redeployed management +nodes to roll out updates.

    +
  • +
  • +

    Added dashboards for the operators:

    +
      +
    • Homer
    • +
    • Flower
    • +
    • Grafana dashboards
    • +
    +
  • +
  • +

    Work is underway to supersede openstack-health-monitor +with a solution that is using tempest and rally. The health-monitor +has received improvements though and is at this point still fully +supported and recommended -- it has surfaced a number of issues with +test clouds, especially failed metadata services.

    +
  • +
  • +

    User federation has been prepared to be ready for Gaia-X federation integration

    +
      +
    • Keystone can consume users from Keycloak via OpenID-Connect
    • +
    • Keycloak uses the highly-available Galera database cluster now
    • +
    • mod_oauth2 support for Keystone
    • +
    +
  • +
  • +

    Vast improvements in the SCS Deployment automation

    +
      +
    • Full automation of bare metal deployment with Bifrost and Ironic
    • +
    • Using NetBox as central source of truth for the complete setup
    • +
    +
  • +
  • +

    New services available (opt-in)

    +
      +
    • ClamAV, dnsdist, cgit, FRRouting, Nexus, Tang
    • +
    +
  • +
  • +

    Traefik centrally routes the connections to Nexus, NetBox, phpMyAdmin, Homer, Flower, ARA, cgit

    +
  • +
+

SCS Developer focused improvements (testbed)

+

We now have scripts that allow us to connect to the workload cluster node network +for debugging purposes.

+

The configuration of the testbed was minimized and the deployment was made more production-oriented.

+

Further noteworthy improvements to testbed:

+
    +
  • TLS is implemented throughout the services also in testbed
  • +
  • Virtual BMC in testbed
  • +
  • Public DNS for testbed (testbed.osism.xyz)
  • +
+

We have a Zuul CI framework running and started migrating CI testing from github actions to +using our Zuul infrastructure.

+

Renovate is being used to keep the pinned versions up-to-date and consistent across the +many repositories.

+

An overview over the used software versions is available from the +OSISM release repository as input +for a complete SBOM. This allows to e.g. investigate the contents of the +used (v3.0.0) images.

+

Upgrade/Migration notes

+

Cluster Management

+

The names of a few settings have changed since R1 -- if you have diverged from the defaults, +this may require adjusting the environment.tfvars or the clusterctl.yaml files. +See k8s-cluster-api-provider Release Notes +for more details.

+

The updating approach has fundamentally changed: +If you were used to deploy fresh management nodes regularly to +benefit from the upstream improvements, this need has been vastly reduced now, +allowing for long-living management nodes and workload clusters managed by them.

+

OSISM

+
    +
  • +

    Playbook generic-configuration.yml was deprecated. From now on, please use the playbook of +the same name in the manager environment (manager-configuration.yml). All configuration +parameters from environments/configuration.yml should be moved to environments/manager/configuration.yml.

    +
  • +
  • +

    In kolla-ansible the haproxy role was renamed to loadbalancer. Accordingly, loadbalancer must now be +used for the deployment of HAProxy.

    +
  • +
+

Removals

+
    +
  • OpenStack Victoria images are no longer built and thus no longer kept updated
  • +
  • Support for Zabbix has been removed, Prometheus will be used as the only monitoring stack in the future
  • +
  • Heimdall as a service was removed, as an alternative Homer is now available
  • +
+

Deprecations

+

Deprecations happen according to our deprecation policy.

+
    +
  • Cockpit is deprecated in favor of Boundary by HashiCorp or Teleport
  • +
  • ceph-ansible is deprecated in preparation for cephadm
  • +
  • All osism- scripts on the manager are deprecated and will be replaced by the new OSISM CLI. The scripts will be removed in the next release
  • +
  • The following services are currently not used and are deprecated and scheduled for removal as of now: Falco, Jenkins, Rundeck, Lynis, Trivy
  • +
  • Heat will no longer be offered by default in the testbed in the future
  • +
  • The docker-compose CLI will be removed and replaced by the new compose plugin for Docker. +docker-compose is then no longer available and docker compose must be used instead
  • +
+

Security Fixes

+
    +
  • The Elasticsearch container included in OSISM testbed was exposed to the log4j +issue -- new images were provided for addressing this. See the +security advisory
  • +
+

Resolved Issues

+
    +
  • +

    The nginx-ingress loadbalancer could run into name conflicts before. +The loadbalancer now uses a health monitor to avoid routing to the wrong +nodes, which typically resulted in 10s delays when connecting to the service +behind the ingress controller.

    +
  • +
  • +

    cAdvisor has now reduced number of Prometheus metrics and labels exported by +default - this will ease the load on the system. +This implies that corresponding time series data will no longer be created.

    +
  • +
+

Standards Conformance

+

The clusters created with our cluster-API cluster management solution pass +the CNCF conformance tests +as reported by sonobuoy.

+

The OpenStack layer passes the +OIF trademark tests, so cloud providers +leveraging the stack should easily be able to achieve the +"OpenStack powered compute" +trademark certification.

+

Our partner plusserver has achieved +a BSI C5 +security certification for their SCS implementation pluscloud open.

+

We are working within Gaia-X to further the power +of Gaia-X self-descriptions and are closely working with the +GXFS project +to jointly deliver a standard toolbox for Gaia-X compliant +infrastructure and service offerings.

+

The SCS standards for flavor naming and +image metadata +are largely unchanged since R1. We have however +made progress in our reference implementation fully implementing +them without any further tweaks.

+

Release Tagging

+

See Release Numbering scheme -- unchanged from R0. +We have added the tag v3.0.0 to the relevant repositories to designate the SCS_RELEASE_R2.

+

Note that we will release R3 (v4.0.0) in September 2022 and stop providing maintenance +updates for R2 at the end of October.

+

List of known issues & restrictions in R2

+

Future directions (selected Highlights)

+

Alongside with R2 we published a blog post on some first thoughts on +future directions towards R3.

+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our contributor guide. +We also have worked on a Code of Conduct +to document the expected behavior of contributors and how we deal with +cases where individuals fail to meet the expectation.

+ + \ No newline at end of file diff --git a/docs/releases/Release3/index.html b/docs/releases/Release3/index.html new file mode 100644 index 0000000000..23ac1eb317 --- /dev/null +++ b/docs/releases/Release3/index.html @@ -0,0 +1,205 @@ + + + + + +Release Notes for SCS Release 3 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Release Notes for SCS Release 3

+

(Release Date: 2022-09-21)

+

Scope

+

Main goals for Release 3 (R3) were user federation, increase in deployment and upgrade +velocity by improving automated test coverage as well as bringing disk encryption based on +tang from the state of a technical preview to be fully supported.

+

Component Versions and User-visible improvements (highlights)

+ +

New Features (Highlights)

+

Operator focused improvements

+
    +
  • +

    Work is underway to supersede openstack-health-monitor +with a comprehensive approach using scenarios with ansible playbooks +that has been developed and used by T-Systems for their Open Telekom Cloud. +Meanwhile, openstack-health-monitor has seen the addition of data +collection with telegraf and influxdb as well as a good dashboard +with grafana.

    +
  • +
  • +

    We have used our keystone to keycloak federation to use keycloak as identity +broker to federate identities from other (SCS) clouds' keycloaks. +This works well for the Web-Interface; we have still some work to do to also make it smooth +also for API/CLI usage. We have documented the current status

    +
  • +
  • +

    We believe that Gaia-X self-descriptions should also contain a description of +technical properties of services; higher-level services and workloads can than +declare their requirements and be matched against lower level services / platforms. +In good platforms, most (or all) technical properties are discoverable. In the +Gaia-X Hackathon #4, we have worked on a demonstrator that characterizes some +aspects of an OpenStack-based IaaS platform and which produces self-descriptions +that can be submitted to the Gaia-X trust service, pass the tests and you can +be awared a verifiable credential. Code is available in the +gx-self-description-generator repo

    +
  • +
+

SCS Developer focused improvements (testbed and k8s cluster management)

+
    +
  • +

    Following significant discussions on how to standardize our cluster management solution, +there is a draft concept as part of R3 now, which will be further worked on during +the R4 cycle. See Cluster standardization +section of the release notes from k8s-cluster-api-provider. +While our reference implementation uses the concepts and code from k8s cluster API on +top of our SCS reference implementation (OpenStack automated by OSISM), we want to +assure that non-OpenStack IaaS and solutions that diverge from cluster-API have the possibility +to be SCS compliant.

    +
  • +
  • +

    Workload clusters managed by our SCS cluster management solutions can now much +more easily receive k8s version upgrades, as the cluster-template no longer needs +to be touched for this. There is an Upgrade Guide available now.

    +
  • +
  • +

    LUKS encryption is now documented and enabled in the testbed by default.

    +
  • +
  • +

    Further noteworthy improvements to testbed:

    +
      +
    • Public DNS for testbed is now available (testbed.osism.xyz), allowing to access services +via TLS protected by a wildcard CA certificate.
    • +
    • The wireguard VPN service is deployed in the testbed by default.
    • +
    +
  • +
+

An overview over the used software versions is available from the +OSISM release repository as input +for a complete SBOM. This allows to e.g. investigate the contents of the +used (v4.0.0) images.

+

Upgrade/Migration notes

+

Cluster Management

+

Upgrade from R2 to R3 for cluster management and clusters: +See k8s-cluster-api-provider Release Notes +for more details. There is an Upgrade Guide written specifically to address the steps needed for upgrading +your cluster management and the workload clusters.

+

OSISM

+
    +
  • +

    In environments/kolla/secrets.yml the parameter neutron_ssh_key must be +added.

    +
    neutron_ssh_key:
    private_key:
    public_key:
    +

    The ssh key can be generated as follows: ssh-keygen -t rsa -b 4096 -N "" -f id_rsa.neutron -C "" -m PEM

    +
  • +
+

Removals

+
    +
  • The Cockpit service has been removed.
  • +
+

Deprecations

+

Deprecations happen according to our deprecation policy.

+
    +
  • Linux bridge support has been deprecated by the Neutron team and marked as experimental. +If Linux bridge is used in deployments, migrating to OpenVSwitch is recommended.
  • +
  • Debian dropped hddtemp (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1002484), +therefore the hddtemp service will be removed from the next OSISM release, as there is +no package available for Ubuntu 22.04.
  • +
  • Heat will no longer be offered by default in the testbed in the future
  • +
  • The following services are currently not used and are deprecated and scheduled for removal as of now: Falco, Jenkins, Rundeck, Lynis, Trivy
  • +
  • The docker-compose CLI will be removed and replaced by the new compose plugin for Docker. +docker-compose is then no longer available and docker compose must be used instead
  • +
  • The cleanup-elasticsearch playbook is deprecated. In the future, +the elasticsearch-curator service (part of Kolla) has to be used +for Elasticsearch cleanup.
  • +
  • All osism- scripts on the manager are deprecated and will be replaced by the new OSISM CLI. The scripts will be removed in the next release
  • +
+

Security Fixes

+

No severe security issues need to be highlighted since Release 2. However, by updating to the latest stable version of +the integrated open source components, we benefit from the upstream security fixes and thus recommend to upgrade all +SCS environments. Please note that Release 2 maintenance by the SCS project team will end by the end of October.

+

Resolved Issues

+
    +
  • Certificates in k8s clusters are subject to expiration - typically after one year. +We ensure these are renewed on control-plane upgrades, but operators may need manual attention +in case upgrades are not performed for extended periods of time. This is documented in +the k8s-cluster-api-provider's +Maintenance and Troubleshooting Guide.
  • +
+

Standards Conformance

+

The clusters created with our cluster-API cluster management solution pass +the CNCF conformance tests +as reported by sonobuoy.

+

The OpenStack layer passes the +OIF trademark tests, so cloud providers +leveraging the stack should easily be able to achieve the +"OpenStack powered compute" +trademark certification.

+

Our partner plusserver has achieved +a BSI C5 +security certification for their SCS implementation pluscloud open.

+

We are working within Gaia-X to further the power +of Gaia-X self-descriptions and are closely working with the +GXFS project +to jointly deliver a standard toolbox for Gaia-X compliant +infrastructure and service offerings.

+

The SCS standards for flavor naming and +image metadata +are largely unchanged since R1. We have however +made progress in our reference implementation fully implementing +them without any further tweaks. The +conformance test for the flavor naming +has seen minor improvements; a +conformance test for the image metadata +has been added.

+

Release Tagging

+

See Release Numbering scheme -- unchanged from R0. +We have added the tag v4.0.0 to the relevant repositories to designate the SCS_RELEASE_R3.

+

Note that we will release R4 (v5.0.0) in March 2023 and stop providing maintenance +updates for R3 at the end of April 2023.

+

List of known issues & restrictions in R3

+
    +
  • Distributed Virtual Routing (DVR) is not officially supported by OSISM, not tested and not recommended.
  • +
+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our How to contribute page.

+

Thanks

+

The work for R3 has been done by many contributors from our community. +We have not collected detailed stats that would split out the individual contributor's +and companies shares ... we may do so in the future. We are grateful to have such an +active and engaged community that has done so much work! Thanks to our contributors!

+

Of course we are leveraging a huge amount of open source technology that has been +created by our friends in other communities, many of which are part of the +CNCF, Linux Foudation, OIF, and others. We participate and contribute where +we can and definitely want to acknowledge the great work that we build upon.

+ + \ No newline at end of file diff --git a/docs/releases/Release4/index.html b/docs/releases/Release4/index.html new file mode 100644 index 0000000000..186e64793a --- /dev/null +++ b/docs/releases/Release4/index.html @@ -0,0 +1,145 @@ + + + + + +Release Notes for SCS Release 4 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Release Notes for SCS Release 4

+

(Release Date: 2023-03-22)

+

Scope

+

Release 4 has been developed alongside a set of associated outcomes. These outcomes are comprised of:

+
    +
  • SCS is standardized
  • +
  • SCS is federated
  • +
  • SCS is continuously built and tested
  • +
  • SCS is understandable
  • +
  • SCS enables Operators with an excellent toolbox
  • +
+

The SCS project is completely developed in the open, based on the principles of the four opens. Due to this a lot of our work can be tracked and used continuously without waiting for the half-year releases. Especially, but not limited to, this includes our efforts in regards to documentation and our standards.

+

One of the major highlights that happened in the R4 development cycle is our work on assuring SCS is understandable. +Be sure to look at our new documentation entry point. +We have created a systematic approach to structure documentation which already has been implemented for the OpenStack Image Manager, +the OSISM testbed and the K8s Cluster API Provider. More will follow in a continuous manner.

+

Our community has created a growing amount of blog articles which also help to understand the SCS project, its community and the technology that is worked on.

+

Component Versions and User-visible improvements (highlights)

+
    +
  • OpenStack Zed release
  • +
  • Ceph Quincy is available, the default release of Ceph is still Pacific.
  • +
  • The base infrastructure is provided by +OSISM 5.0.0 +which in turn builds on top of kolla and kolla-ansible.
  • +
  • With Cloud-in-a-Box there is an easy way to get SCS up and running on a single hardware node as a test environment. There are two blog posts (part 1 and part2) covering it.
  • +
  • For new deployments of the IaaS reference implementation Ubuntu 22.04 is recommended while existing installations can be upgraded to R4 while staying on Ubuntu 20.04. With Release 5, upgrading to Ubuntu 22.04 will be required.
  • +
  • With osism/node-image an iso image for much easier bootstrapping of new OSISM environments is available now
  • +
  • The software for our Kubernetes Cluster-API reference implementation has been updated and highlights are covered in own release notes.
  • +
+

New Features (Highlights)

+

Operator focused improvements

+
    +
  • The Openstack Image Manager has seen many improvements and is the reference command to assure the images available comply with the SCS Image Standard
  • +
  • For Ceph, special playbooks were added to validate the deployment status of the OSD, MON and MGR services in OSISM. The commands for use are osism validate ceph-osds, osism validate ceph-mons, and osism validate ceph-mgrs.
  • +
  • OVN has been updated to version 22.09.
  • +
  • OVS has been updated to version 3.0.1.
  • +
  • The testbed uses per default a proxy for container pulling. This will allow for airgapped installations out of the box. Please note: a full airgap support (with local mirrors, etc.) will follow in a future release.
  • +
  • The efforts to create a well-maintained status page with well-defined interfaces resulted in an OpenAPI specification (within its own repository) which is intended to be implementable by multiple implementations.
  • +
  • The dashboard of the OpenStack Health Monitor is in use by the SCS operators and has proven helpful a number of times in detecting and addressing issues. That said, it only received a few fixes and minor enhancements, as we plan to replace it with a more generic and more maintainable solution soon.
  • +
  • The k8s clusters built with our k8s-capi implementation now allow controlling the versions of more components; the latest tested and stable versions are used by default (if enabled). The latest version for the cilium CNI for example allows testing the upcoming k8s gateway API.
  • +
  • The k8s cluster now allows filtering access to the kubernetes API by IP ranges.
  • +
  • The k8s clusters now have the proxy protocol enabled with the nginx-ingress controller, so client IPs are visible; the previous issue that blocked internal access could be worked around.
  • +
+

SCS Developer focused improvements (testbed and k8s cluster management)

+
    +
  • The testbed has been significantly simplified for new operators and developers and a Quick Start guide has been added.
  • +
+

Upgrade/Migration notes

+
    +
  • For the IaaS reference implementation, please refer to the OSISM 5.0.0 Upgrade Notes.
  • +
  • The k8s Cluster Management solution has an enhanced upgrade guide that covers the upgrade of clusters as well as the upgrade of the cluster management server.
  • +
+

Removals

+
    +
  • The ospurge wrapper script has been removed from the osism.services.openstackclient role. The ospurge project is no longer compatible with the current OpenStack SDK. The command openstack project purge can be used as an alternative.
  • +
  • The docker-compose package is uninstalled by the osism.commons.docker_compose role. The Compose v2 plugin for Docker is now used instead of the old standalone docker-compose CLI. A dummy script has been added to /usr/local/bin which displays a corresponding message when using docker-compose.
  • +
  • Further removals from the IaaS reference implementation, please refer to the OSISM 5.0.0 Removals Section.
  • +
  • The k8s cluster parameter ETCD_PRIO_BOOST that was already unused has been removed as announced with R3.
  • +
+

Deprecations

+

Deprecations via OSISM

+

For these please also refer to the upstream deprecation notices

+
    +
  • The role osism.services.bird is deprecated. In future, FRRouting (osism.services.frr) will be used.
  • +
  • The role osism.services.minikube is deprecated. In future osism.services.k8s will be used.
  • +
  • Heat is deprecated in favor of more generic Infrastructure as Code tools like Terraform as of now and will be removed in the future (exact removal date is not yet known)
  • +
  • Swift (currently available as Technical Preview) will be removed in favor of Ceph RGW
  • +
  • Trove (currently available as Technical Preview) will be removed in favor of Kubernetes database operators
  • +
  • Skydive (currently available as Technical Preview) will be removed in the future, the project is not maintained anymore, last commit is 8th Jan 2022: https://review.opendev.org/c/openstack/kolla/+/869191
  • +
  • The login to a registry with the osism.services.docker role is deprecated in favor of the new osism.commons.docker_login role.
  • +
+

Security Fixes

+

Throughout the Release 4 development cycle, the SCS project issued two security advisories for upstream components:

+ +

Fixes were delivered via maintenance updates to existing R3 deployments, but of course also included in the main development branch that became R4.

+

Resolved Issues

+
    +
  • Breakage with old kustomize syntax has been addressed.(k8s-capi/#328)
  • +
  • The move of k8s container images from k8s.gcr.io to registry.k8s.io needed adjustments.(k8s-capi/#321)
  • +
+

Standards Conformance

+

The last months saw intense work in the standardization area. The process how standards are created has been documented. +The standards are collected in its own standards repository. +A machine readable file lists the required (and optional) standards that apply to "SCS-compatible" conformance at +the IaaS and the Container (KaaS) layer. The referenced executables are used by the compliance checking framework +to test existing implementations for compliance. To run the checker, the tester needs access to the infrastructure +under test (normal user privileges are sufficient) and standard openstack and kubernetes client tools -- or just +use the docker container that is provided.

+

The public clouds based on the SCS reference implementation from plusserver and Noris/Wavecon are tested automatically +from us and the live result is visible in standards page. +We will enhance the standardization and test coverage significantly in the next months and we hope to list a number +of more clouds there soon.

+

Release Tagging

+

The code in OSISM and a number of SCS repositories will receive the v5.0.0 tag; some repositories use +maintained/v5.0.x and maintained/v5.x branches for providing code that only gets bug- and security fixes (5.0.x) +or only those plus selected, backwards-compatible enhancements (5.x).

+

List of known issues & restrictions in R4

+
    +
  • The k8s cluster-API code does not work well with OpenStack API endpoints that require trusting a custom CA.
  • +
  • The OpenStack component Horizon has two issues when working with Swift endpoints. One issue is a known bug when uploading objects to Swift endpoints. A workaround will be released shortly after R4. The second issue is that existing Swift containers can not be set to public.
  • +
+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our How to contribute page.

+

Thanks

+

The work for R4 has been done by many contributors from our community. +The special thanks goes out to our contributors who participate in our community +on a very regular base - without these the various team calls and events like +the hackathons would be much less successful and fun.

+

Of course we are leveraging a huge amount of open source technology that has been +created by our friends in other communities, many of which are part of the +CNCF, Linux Foudation, OIF, and others. We participate and contribute where +we can and definitely want to acknowledge the great work that we build upon.

+ + \ No newline at end of file diff --git a/docs/releases/Release5/index.html b/docs/releases/Release5/index.html new file mode 100644 index 0000000000..36fb7eff2c --- /dev/null +++ b/docs/releases/Release5/index.html @@ -0,0 +1,175 @@ + + + + + +Release Notes for SCS Release 5 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Release Notes for SCS Release 5

+

(Release Date: 2023-09-20)

+

Scope

+

Just as our previous release, Release 5 has been developed alongside a set of associated outcomes. +These outcomes are comprised of:

+
    +
  • SCS is standardized
  • +
  • SCS is understandable
  • +
  • SCS is transparent
  • +
  • SCS is continuously built and tested
  • +
  • SCS is opinionated
  • +
  • SCS enables
  • +
+

Component Versions and User-visible improvements (highlights)

+

IaaS

+
    +
  • The IaaS reference implementation is based on OSISM 6.0.0.
  • +
  • OpenStack 2023.1 (Antelope)
  • +
  • Default Ceph version is now Ceph Quincy.
  • +
  • OVN and OVS have been updated to their latest versions (OVN: 23.06.1, OVS: 3.2.0).
  • +
  • IPv6 east-west and north-south support is present and documented upstream.
  • +
  • Cloud-in-a-Box now comes with Swift enabled as well as the option +for secondary NIC for external connectivity.
  • +
+

Container Management

+
    +
  • The Kubernetes Cluster Management solution is available as version 6.0.0
  • +
  • Kubernetes v1.24 .. 1.27 are officially supported. v1.28 also works (technical preview until officially supported by capo) as do older versions (with downgrading nginx-ingress), matching OCCM and CSI versions.
  • +
  • Cluster-API (capi) v1.5.1, Cluster-API provider for Openstack (capo) v0.7.3
  • +
  • The node images now use Ubuntu 22.04, the management host can use Ubuntu 22.04 or Debian 12.
  • +
  • Cilium v1.14.1, default now, though Calico (3.26.x) is still supported.
  • +
  • Cilium also brings the upcoming gateway API (opt-in) as technical preview.
  • +
  • The Harbor container registry can now be rolled out with each cluster.
  • +
  • The clusters can use a registry as cache to upstream dockerhub or gcr registries.
  • +
  • The cluster management now works also on OpenStack clouds with a custom CA.
  • +
  • Storage snapshots are supported now (fix was also backported to maintained branches).
  • +
  • Diskless flavors are supported everywhere (cluster-management, health-monitor).
  • +
  • etcd defragmentation and backup.
  • +
  • Controls for pod and service IP ranges.
  • +
+

Preview: Cluster-Stacks

+

The old scripts that are used to create, change and delete Kubernetes clusters with +Cluster API will be replaced by a proper Operator in the next release. A description can be found at the +cluster-stacks +and cluster-stack-operator +repositories. The technical preview can be tried with the cluster-stacks-demo. +This solution will fit more nicely into the CNCF landscape and +also allow for easier support of IaaS solutions that do not comply to our SCS +IaaS standards.

+ +
    +
  • A number of improvements when using identity federation via OIDC has been added, including +addressing openstack CLI usage with PKCE Device Authz Grant, logout, and the usage of a +proxy realm in keycloak. Improvements have been contributed to upstream keystone.
  • +
  • With the openstack-resource-manager a new day 2 operations tool has been added. +Furthermore an osism role for tuned to optimize system profiles is now present.
  • +
  • The openstack-flavor-manager is now able to create all standard, mandatory SCS flavors for you.
  • +
  • Scaphandre Prometheus Exporter has been added to export power consumption metrics more easily.
  • +
  • To optimize system profiles an osism role for tuned is now present.
  • +
  • Full support for air-gapped installation and operation of environments.
  • +
  • A migration script and guide for moving from R4 to R5 clusters is available.
  • +
  • Metering has been improved and a reference billing API implementation is available as technical preview.
  • +
+

SCS Developer focused improvements (Cloud-in-a-Box, testbed and k8s cluster management)

+
    +
  • Documentation on testbed and Cloud-in-a-Box have been reworked.
  • +
  • Reflecting CiaB's usage as edge cloud appliance, it now receives more automated testing.
  • +
+

Project Infrastructure

+
    +
  • zuul.scs.community now complements OSISM's existing zuul infrastructure and is used also +by the container layer to execute the CNCF e2e tests.
  • +
  • registry.scs.community has been migrated to a new IaaS location (documented in a blog +article) and is kept up-to-date now.
  • +
+

Upgrade/Migration notes

+ +

Removals

+
    +
  • +

    Please check the removals for OSISM in the upstream removal notices.

    +
  • +
  • +

    The services minio.services.osism.tech and harbor.services.osism.tech are deprecated and will be turned of on October 20th, 2023.

    +
  • +
+

Deprecations

+

Deprecations via OSISM

+

For these please also refer to the upstream deprecation notices.

+
    +
  • +

    It is again noted that the old scripts of the form osism- will be removed in the future. +A note has been added to the scripts showing this when they are executed.

    +
  • +
  • +

    The following services are deprecated and will be removed with R6 (OSISM 6.1.0):

    +
      +
    • Patchman
    • +
    • Adminer
    • +
    • Patchman Client
    • +
    • Virtualbmc
    • +
    • Bird
    • +
    +
  • +
+

Security Fixes

+

Throughout the Release 5 development cycle, the SCS project issued two security advisories for upstream components:

+
    +
  • +

    In April 2023 an advisory in Open vSwitch (OvS) (CVE-2023-1668 was issued. +Our advisory.

    +
  • +
  • +

    In May 2023 an advisory affecting the OpenStack component Cinder (CVE-2023-2088) was issued. +Our advisory.

    +
  • +
+

Resolved Issues

+

Numerous minor issue have been resolved. The most important steps on the IaaS side probably being the move to ceph Quincy +to avoid running out of upstream support. On the container side, the fix of storage snapshots is probably most significant.

+

For details, we again refer to the OSISM and +k8s-cluster-api-provider release notes.

+

Standards Conformance

+

A new certification set is expected in December. It will ensure we +run all automated tests also for all new standards, such as +v3 flavor naming, +and the (previously included) v1 standard flavors -- which includes the new SSD flavors, the v1 entropy standard. We have also split image naming and standard image recommendations into v1 standards images.

+

Requirements for k8s version recency, default storage class as well as requirements to the container registry have been captured.

+

The IAM area has seen ADRs on the chosen architecture.

+

The (design) decisions on the metering work as well as on the status page project have also been +captured.

+

The standards and the standards compliance of our operators' clouds can be seen in the +standards section of our doc pages while the raw content is developed +and discussed in the respective github standards repository.

+

The SCS reference implementation follows all approved SCS standards.

+

Release Tagging

+

Relevant repositories have been tagged with v6.0.0 tag. +For some repositories maintained/v6.x and maintained/v6.0.x branches have been created.

+

List of known issues & restrictions in R5

+

Nothing that we are aware of at this point.

+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our How to contribute page.

+

Thanks

+

Our wonderful community of integrators, operators, contractors and volunteers +made R5 possible. The project management team is employed by the OSB Alliance +and we as well as the contractors are paid thanks to funding from the German +Ministry for economic affairs and climate action. We build on top of a lot of +existing open source code from the CNCF, the OIF and various others and we +try to contribute back as much as we can.

+ + \ No newline at end of file diff --git a/docs/releases/Release6/index.html b/docs/releases/Release6/index.html new file mode 100644 index 0000000000..eb909dbfcd --- /dev/null +++ b/docs/releases/Release6/index.html @@ -0,0 +1,277 @@ + + + + + +Release Notes for SCS Release 6 | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Release Notes for SCS Release 6

+

SCS Release 6 has been published on 2024-03-20.

+

Scope

+

Just as our previous release, Release 6 has been developed alongside a set of associated outcomes. +Overall with Release 6 it becomes apparent that SCS is efficient to operate.

+
    +
  • SCS is standardized
  • +
  • SCS is understandable
  • +
  • SCS enables
  • +
  • SCS is transparent
  • +
  • SCS is continuously built and tested
  • +
  • SCS is opinionated
  • +
  • SCS charters new territory
  • +
+

Component Versions and User-visible improvements (highlights)

+

IaaS

+

The IaaS reference implementation is based on OSISM 7.0.0 +and delivers the following components:

+ +

KaaS

+

On the KaaS level, the development of the Cluster Stacks as KaaS V2 has reached a state where the approach is finally usable. With Cluster Stacks it is possible to bundle all components of Kubernetes clusters, i.e. node images, Kubernetes configuration, and cluster addons (core applications necessary to use a Kubernetes cluster) together and use the bundles to create and update clusters with one simple command.

+

One bundle, a Cluster Stack, can be tested extensively and is only released if both creating and upgrading clusters works smoothly. Users of these Cluster Stacks profit from the Cluster Stack Operator that works alongside with Cluster API to create and update ready-to-use clusters easily.

+
    +
  • k8s-cluster-api-provider (KaaS v1) +
      +
    • Moved to OpenTofu
    • +
    • Migrated to ClusterClass (last not least to ease the migration to Cluster Stacks)
    • +
    • HTTP_Proxy configurable
    • +
    • OVN LB
    • +
    +
  • +
  • Cluster Stacks (KaaS v2) + +
  • +
+

Operations

+

Observability

+

The Observability stack reference implementation is based on dNation Kubernetes monitoring stack v3.5.0 +and delivers the following components:

+ +

Zuul

+
    +
  • Created a development deployment for advancement testing.
  • +
  • Simplified the installation requirements.
  • +
  • Updated the Zuul repository's README file to include complete installation instructions for Terraform an Ansible.
  • +
  • Added the clouds data into the ansible vault.
  • +
  • Created an independent ansible Zuul role.
  • +
  • Moved the custom Zuul tasks from the playbook and incorporated them into the role.
  • +
  • Moved the custom Zuul variables from the playbook into the role's variables.
  • +
  • Included the installation of Letsencrypt which adds certificates as part of the installation.
  • +
  • Added a volume on the VM for the MariaDB instance to use for continuity.
  • +
  • Added volumes on the VM for Zookeeper to use for the data snapshots and datalog.
  • +
+

IAM

+ +

New Features (Highlights)

+

Operator focused improvements

+

A Kubernetes engine, via k3s, has been introduced to the control plane of the IaaS reference +implementation.

+

osism now deploys Keycloak to k3s via codecentric/keycloakx helm chart and CloudNativePG operator.

+

Rotation of the Octavia Amphora images has been added to the osism command. osism manage image octavia will rotate +the image, which is rebuilt on a daily basis.

+

OpenStack Health Monitor

+

A new monitoring stack will replace the old +openstack-health-monitor. +Nevertheless, it is currently still in heavy use and has thus seen a few improvements +responding to challenges observed in real-life clouds:

+
    +
  • A new installation guide
  • +
  • Robustness against leaking volumes even with overloaded cinder API
  • +
  • Robustness against leaking ports from OVN LB health-monitor
  • +
  • Robustness against leftover keypairs
  • +
  • Avoid some followup errors when VM creation failed
  • +
  • Add logic to startup os-health-mon in tmux windows via systemctl --user
  • +
+

SCS Developer focused improvements (testbed and k8s cluster management)

+

KaaS

+
    +
  • Every component of Cluster Stacks brings a Tilt environment for local test and development
  • +
  • With csctl Cluster Stacks assets can be created and tested locally without uploading to GitHub
  • +
+

Preview: Domain Manager Persona

+

A Domain Manager role has been established in a standard draft in SCS aiming to allow self-service capabilities for customers at the identity API. +Work is in progress to contribute this functionality to OpenStack Keystone and the corresponding upstream spec is currently under review. +The feature is expected to be available in the next SCS release.

+

Preview: Central API

+

To improve the experience of SCS cloud customers, the idea of a "Central API" was discussed. Such API should enable customers to manage various "as-a-Service" resources. For example: OpenStack instances as well as Kubernetes clusters as well as Keycloak OAuth2 clients. +Read about the trade-offs and ideas in the central-api repository and feel free to test out the POC.

+

Preview: Keycloak Home-IdP-discovery

+

To improve flexibility of onboarding new customer domains via IdP federation, SCS now deploys Keycloak with the Home-IdP-discovery plugin. The idea is, that Keystone federates out to a single Keycloak "proxy" realm (called osism in the testbed) and using the plugin, Keycloak can identify the user specific realm from an email-format login-ID. Operators can create dedicated realms for each customer and Keycloak uses internal federation to redirect from the "proxy" realm to the specific customer realm. In the customer ream they can configure IdP federation (OpenID-Connect or SAML) to their own IAM solution. The IAM section of the SCS documentation shall be extended to detail the configuration. SCS is working upstream to contribute required enhancements in the +mapping of users, groups and roles from OpenID-Connect token claims to the OpenStack Keystone access management.

+

Upgrade/Migration notes

+ +

Removals

+ +

Deprecations

+
    +
  • +

    KaaSv1 is still provided with R6, but we do not intend to include it in R7 again. +We want to rather focus on the feature completeness of the much more future-proof +cluster-stacks.

    +
  • +
  • +

    In upstream OSISM the role for deploying the Tang service (osism.services.tang) has been deprecated. +We would like to encourage active contributions in this area via the deprecation, since this piece of +code is currently not actively maintained nor -- to our knowledge -- actively used.

    +
  • +
+

Security Fixes

+

During the R6 development cycle a few security issues were reported and we issued security +advisories and addressed them via maintenance updates. All of these issues are also fixed +in the upcoming R6 release. These include:

+ +

Other security topics were covered in our community blog as well:

+ +

Security assessment for IaaS

+

We invested in a range of penetration tests of the IaaS layer which resulted in valuable insight in possible improvements (e.g. applying hardening measures):

+
    +
  • External pentesting of components (scanning, blackbox testing)
  • +
  • Internal pentesting of components with privileged and unprivileged system users (scanning from inside the cluster)
  • +
  • Scanning and pentesting the environment from a customer workload machine
  • +
+

The vision of SCS is to have continuous security assurance by adding security checks and pentesting tooling +to our CI pipelines; this is currently in implementation. Next step will then be to also cover other parts +(beyond the IaaS layer) of our stack with manual and then +automated penetration testing.

+

Resolved Issues

+

Preview: proper scope filtering for domain list API

+

A fix to a bug where listing domains via Keystone API would return domains not intended to be visible to the requesting entity was contributed and merged upstream. +The fix is expected to be available by the next SCS release.

+

Documentation

+

The docs page has come a long way in the last 6 months. +It pulls in a lot more content from the various projects and structures it in a much +more accessible way. Look at the standards pages +there to get an impression.

+

Highlighted blog posts

+ +

IAM

+

The documentation now contains an IAM overview document which explains current +limitations for the dynamic mapping of user roles and shall be extended to explain configuration options for Operators.

+

Standards Conformance

+

The standards have evolved, increasing the amount of guarantees that software developers +and operators have for workloads that work across SCS-compatible clouds. +The SCS-compatible IaaS-v4 +has seen improvements and better test coverage; the OSISM IaaS reference implementation +fulfills all of these standards in the default configuration.

+

For the Kubernetes layer, we have our first set of standards almost finalized. +Some of the standards for SCS-compatible KaaS-v1 +are unfortunately hard to test, so we are working on adding some more tests before +we cut it in stone. We aim for both KaaSv1 and v2 to fulfill the standards. +(Future standards will likely not be fulfilled by KaaSv1 as it's being deprecated.)

+

Release Tagging

+

A number of repositories follow OSISM's example and use the 7.0.0 or v7.0.0 tag +to denote SCS Release 6.

+

List of known issues & restrictions in R6

+

IaaS

+

Loadbalancer service (octavia)

+
    +
  • Creating loadbalancers in Cloud-in-a-Box installations fails with the +error message that the VIP subnet does not exist. OSISM #890
  • +
  • When using --provider ovn with a loadbalancer health-monitor, we leak ports ovn-lb-hm-$SUBNETID in all +but the VIP subnet, if we clean up the LB members before the health-monitor. This is tracked as +OSISM issue #921. Deleting the health-monitor before the +members or using openstack loadbalancer delete --cascade avoids this issue.
  • +
  • With amphora loadbalancers, we can end up in situations that LB deletion does no longer work due to +a failover or a failed creation of the vrrp port. This is tracked in +OSISM issue #925. An upstream fix exists and a backport +is already underway.
  • +
+

We expect to resolve these issues with a maintenance update.

+

KaaS

+

Some features of KaaS v1 are not available yet in KaaS v2 because they are WIP in upstream CAPO. +This includes the creation of some of the optional components such as e.g. the deployment +of ingress service, cert-manager, flux, harbor. More importantly, we do not yet have the +handling of restrictive security groups implemented nor the ability to avoid OpenStack +scheduling more than one control plane node on the same host (hypervisor).

+

For this reason, we are including KaaS v1 (k8s-cluster-api-provider) in the R6 release, +so existing users can upgrade to the latest upstream code and continuing using it as +a maintained solution while they evaluate the migration to KaaS v2 (cluster-stacks).

+

We will address most of the gaps during the next release cycle.

+

KaaS v1 should not be used for new deployments; we intend to remove it with the next +release (R7).

+

IAM

+

Since Keycloak is a Java application it requires importing certificates into its certificate store. +As the Keycloak pod in k3s now runs the service as non-root user, it gets more challenging to import +custom certificates from arbitrary customers for IdP federation. In case this topic is interesting for +specific deployments, the SCS project team would like to hear from users and discuss how to best +expose such a capability.

+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our How to contribute page.

+

Thanks

+

We have had considerable help from many partners and upstream projects during +the R6 development cycle. We continue to be grateful for the generous support +from providers that support with infrastructure that we can use for testing and +development. plusserver has been particularly generous and also helped us +finding a few issues during the pre-release phase by upgrading test +environments and testing them.

+ + \ No newline at end of file diff --git a/docs/releases/ReleaseX/index.html b/docs/releases/ReleaseX/index.html new file mode 100644 index 0000000000..2a80fc8f6c --- /dev/null +++ b/docs/releases/ReleaseX/index.html @@ -0,0 +1,44 @@ + + + + + +Release Notes for SCS Release X | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Release Notes for SCS Release X

+

This document is work in progress for the upcoming Release X. +Release X will be released in Months/Year. +This note will be removed, once Release X is released and these notes are valid.

+

Scope

+

Component Versions and User-visible improvements (highlights)

+

New Features (Highlights)

+

Operator focused improvements

+

SCS Developer focused improvements (testbed and k8s cluster management)

+

Upgrade/Migration notes

+

Removals

+

Deprecations

+

Security Fixes

+

Resolved Issues

+

Standards Conformance

+

Release Tagging

+

List of known issues & restrictions in RX

+

Contributing

+

We appreciate contribution to strategy and implementation, please join +our community -- or just leave input on the github issues and PRs. +Have a look at our How to contribute page.

+

Thanks

+ + \ No newline at end of file diff --git a/docs/standards/index.html b/docs/standards/index.html new file mode 100644 index 0000000000..3ac083acd1 --- /dev/null +++ b/docs/standards/index.html @@ -0,0 +1,24 @@ + + + + + +Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/img/favicon.ico b/img/favicon.ico new file mode 100644 index 0000000000..8e0002e27e Binary files /dev/null and b/img/favicon.ico differ diff --git a/img/github-failed-dco.png b/img/github-failed-dco.png new file mode 100644 index 0000000000..a21febb629 Binary files /dev/null and b/img/github-failed-dco.png differ diff --git a/img/logo.svg b/img/logo.svg new file mode 100644 index 0000000000..8950ebcd07 --- /dev/null +++ b/img/logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/img/summit-social.png b/img/summit-social.png new file mode 100644 index 0000000000..66a362e6f5 Binary files /dev/null and b/img/summit-social.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000000..964eab463f --- /dev/null +++ b/index.html @@ -0,0 +1,23 @@ + + + + + +One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Welcome to the SCS Documentation

Find user guides, code samples, deployment examples, reference, community pages and more.

Introduction to SCS

Get to know SCS better and learn about the background.

Releases

SCS is currently in Release 6. Check out the latest Release Notes.

Frequently Asked Questions

You are curious what SCS is all about, what it can do and what it can't?

Existing Public Clouds

There are SCS compliant public clouds in production.

Architectural Layers

Ops Layer

Tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.

Container Layer

SCS offers a robust solution for managing container workloads on a Kubernetes infrastructure.

IaaS Layer

SCS offers OpenStack infrastructure solutions based on KVM virtualization to deploy VM workloads and enabling the container layer optionally.

IAM Layer

Working on Keycloak federated identity provider within our Team IAM.

Additional Resources

Get in touch

Come into our Matrix Chat in the SCS | Tech Room.

Come to our Meet-Ups

Our working groups and special interest groups meet weekly or biweekly. When? Find out within our public community calendar.

Standardization in progress

Get to know our current Decision Records and Standards.

Deployment Examples

Get to know different ways to deploy SCS with cloud resources or on bare metal.

+ + \ No newline at end of file diff --git a/search-index.json b/search-index.json new file mode 100644 index 0000000000..d576840c84 --- /dev/null +++ b/search-index.json @@ -0,0 +1 @@ +[{"documents":[{"i":1,"t":"","u":"/blog/archive","b":[]},{"i":2,"t":"Overview","u":"/community/","b":["Community"]},{"i":5,"t":"First Blog Post","u":"/blog/first-blog-post","b":[]},{"i":7,"t":"Getting Started with OpenStack","u":"/community/cloud-resources/getting-started-openstack","b":["Community","Tools","Cloud Resources"]},{"i":15,"t":"Test and development cloud resources","u":"/community/cloud-resources/","b":["Community","Tools","Cloud Resources"]},{"i":33,"t":"Central services","u":"/community/central-services/plusserver-gx-scs","b":["Community"]},{"i":41,"t":"Getting Started Gaia-X Demonstrator @ plusserver","u":"/community/cloud-resources/plusserver-gx-scs","b":["Community","Tools","Cloud Resources"]},{"i":49,"t":"Getting Started with Wavestack","u":"/community/cloud-resources/wavestack","b":["Community","Tools","Cloud Resources"]},{"i":56,"t":"Collaboration","u":"/community/collaboration/","b":["Community","Collaboration"]},{"i":68,"t":"SIG Community","u":"/community/collaboration/sig-community","b":["Community","Collaboration"]},{"i":70,"t":"SIG Central API","u":"/community/collaboration/sig-central-api","b":["Community","Collaboration"]},{"i":72,"t":"SIG Documentation","u":"/community/collaboration/sig-documentation","b":["Community","Collaboration"]},{"i":74,"t":"SIG Monitoring","u":"/community/collaboration/sig-monitoring","b":["Community","Collaboration"]},{"i":76,"t":"Team Container","u":"/community/collaboration/team-container","b":["Community","Collaboration"]},{"i":78,"t":"SIG Standardization","u":"/community/collaboration/sig-standardization","b":["Community","Collaboration"]},{"i":80,"t":"Team Iaas","u":"/community/collaboration/team-iaas","b":["Community","Collaboration"]},{"i":82,"t":"Team Ops","u":"/community/collaboration/team-ops","b":["Community","Collaboration"]},{"i":84,"t":"Documentation Files Structure","u":"/community/contribute/doc-files-structure-guide","b":["Community","Contribute to Docs"]},{"i":100,"t":"Team IAM","u":"/community/collaboration/team-iam","b":["Community","Collaboration"]},{"i":102,"t":"Documentation workflow explanation","u":"/community/contribute/docs-workflow-explanation","b":["Community","Contribute to Docs"]},{"i":106,"t":"Adding Docs Guide","u":"/community/contribute/adding-docs-guide","b":["Community","Contribute to Docs"]},{"i":119,"t":"Linting Guide","u":"/community/contribute/linting-guide","b":["Community","Contribute to Docs"]},{"i":125,"t":"Styleguide","u":"/community/contribute/styleguide","b":["Community","Contribute to Docs"]},{"i":132,"t":"Ansible Style Guide","u":"/community/contribute/styleguides/ansible_styleguide","b":["Community"]},{"i":152,"t":"Installation","u":"/community/contribute/local-docusaurus-development-guide","b":["Community","Contribute to Docs"]},{"i":165,"t":"License considerations for SCS","u":"/community/license-considerations","b":["Community"]},{"i":183,"t":"Branch Protection Rules","u":"/community/tools/github/branchprotection","b":["Community","Tools","GitHub"]},{"i":185,"t":"Tips and Tricks","u":"/community/tools/github/tips-and-tricks","b":["Community","Tools","GitHub"]},{"i":188,"t":"Hackathon planning checklist","u":"/community/hackathons/checklist","b":["Community"]},{"i":234,"t":"Mission Statement","u":"/community/mission-statement","b":["Community"]},{"i":248,"t":"Jitsi","u":"/community/tools/jitsi","b":["Community","Tools"]},{"i":252,"t":"Developer Certificate of Origin + Licenses","u":"/community/tools/github/dco-and-licenses","b":["Community","Tools","GitHub"]},{"i":256,"t":"Matrix","u":"/community/tools/matrix","b":["Community","Tools"]},{"i":260,"t":"Mailing Lists","u":"/community/tools/mailinglists","b":["Community","Tools"]},{"i":262,"t":"Nextcloud","u":"/community/tools/nextcloud","b":["Community","Tools"]},{"i":264,"t":"Developer documentation","u":"/contributor-docs/development/","b":["For Contributors","Developer documentation"]},{"i":266,"t":"Zuul","u":"/community/tools/zuul","b":["Community","Tools"]},{"i":273,"t":"Documentation for SCS Contributors","u":"/contributor-docs/","b":["For Contributors"]},{"i":275,"t":"SCS Conformance Test Implementation Guide","u":"/contributor-docs/development/tests/test-implementation-guide","b":["For Contributors","Developer documentation","tests"]},{"i":289,"t":"Identity Federation in SCS","u":"/contributor-docs/operations/iam/identity-federation-in-scs","b":["For Contributors","operations","iam"]},{"i":295,"t":"OpenStack Federation via OpenID-Connect","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","b":["For Contributors","operations","iam"]},{"i":309,"t":"Zuul users guide","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","b":["For Contributors","operations","operations"]},{"i":326,"t":"Container Layer Introduction","u":"/docs/container/","b":["For Operators","Container Layer"]},{"i":340,"t":"Introduction","u":"/docs/","b":["For Operators"]},{"i":362,"t":"Overview","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","b":["For Operators","Container Layer","Components","Cluster Stacks","Cluster Stack Provider OpenStack"]},{"i":364,"t":"SCS RFC2119 Keyword Test Guide","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","b":["For Contributors","Developer documentation","tests"]},{"i":382,"t":"Developer Guide","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","b":["For Operators","Container Layer","Components","Cluster Stacks","Cluster Stack Provider OpenStack"]},{"i":394,"t":"Controllers","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","b":["For Operators","Container Layer","Components","Cluster Stacks","Cluster Stack Provider OpenStack"]},{"i":399,"t":"Quickstart","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","b":["For Operators","Container Layer","Components","Cluster Stacks","Cluster Stack Provider OpenStack"]},{"i":401,"t":"Troubleshooting","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","b":["For Operators"]},{"i":405,"t":"HA deployment","u":"/docs/container/components/container-registry/docs/ha-deployment","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":416,"t":"Migration","u":"/docs/container/components/container-registry/docs/migration","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":429,"t":"Quickstart","u":"/docs/container/components/container-registry/docs/quickstart","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":435,"t":"Rate limit","u":"/docs/container/components/container-registry/docs/rate_limit","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":437,"t":"SCS deployment","u":"/docs/container/components/container-registry/docs/scs-deployment","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":443,"t":"Persistence","u":"/docs/container/components/container-registry/docs/persistence","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":459,"t":"Upgrade","u":"/docs/container/components/container-registry/docs/upgrade","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":461,"t":"Backup and restore","u":"/docs/container/components/container-registry/docs/backup_and_restore","b":["For Operators","Container Layer","Components","Container Registry"]},{"i":477,"t":"Configuration","u":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","b":["For Operators","Container Layer","Components","K8s Cluster API Provider"]},{"i":488,"t":"Continuous integration","u":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","b":["For Operators","Container Layer","Components","K8s Cluster API Provider"]},{"i":500,"t":"Application Credentials","u":"/docs/container/components/k8s-cluster-api-provider/doc/application-credentials","b":["For Operators","Container Layer","Components","K8s Cluster API Provider"]},{"i":502,"t":"Ingress with externalTrafficPolicy: local","u":"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","b":["For Operators","Container Layer","Components","K8s Cluster API Provider"]},{"i":512,"t":"Overview","u":"/docs/container/components/k8s-cluster-api-provider/doc/overview","b":["For Operators","Container Layer","Components","K8s Cluster API Provider"]},{"i":514,"t":"Quickstart","u":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","b":["For Operators","Container Layer","Components","K8s Cluster API Provider"]},{"i":526,"t":"Makefile reference","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","b":["For Operators","Container Layer","Components","K8s Cluster API Provider"]},{"i":581,"t":"Roadmap","u":"/docs/container/components/k8s-cluster-api-provider/doc/roadmap","b":["For Operators","Container Layer","Components","K8s Cluster API Provider"]},{"i":584,"t":"Maintenance and Troubleshooting Guide for SCS k8s-cluster-api-provider","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","b":["For Operators","Container Layer","Components","K8s Cluster API Provider"]},{"i":597,"t":"SCS k8s-cluster-api-provider upgrade guide","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","b":["For Operators","Container Layer","Components","K8s Cluster API Provider"]},{"i":616,"t":"Requirements","u":"/docs/container/components/k8s-cluster-api-provider/doc/requirements","b":["For Operators","Container Layer","Components","K8s Cluster API Provider"]},{"i":626,"t":"Cluster Management on the capi management node","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node","b":["For Operators","Container Layer","Components","K8s Cluster API Provider","Usage"]},{"i":628,"t":"Usage","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/","b":["For Operators","Container Layer","Components","K8s Cluster API Provider","Usage"]},{"i":630,"t":"Create a new cluster","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster","b":["For Operators","Container Layer","Components","K8s Cluster API Provider","Usage"]},{"i":632,"t":"Container registry configuration","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration","b":["For Operators","Container Layer","Components","K8s Cluster API Provider","Usage"]},{"i":636,"t":"Gateway-API","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api","b":["For Operators","Container Layer","Components","K8s Cluster API Provider","Usage"]},{"i":638,"t":"Harbor","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor","b":["For Operators","Container Layer","Components","K8s Cluster API Provider","Usage"]},{"i":647,"t":"Managing many clusters","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters","b":["For Operators","Container Layer","Components","K8s Cluster API Provider","Usage"]},{"i":649,"t":"Custom CA","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca","b":["For Operators","Container Layer","Components","K8s Cluster API Provider","Usage"]},{"i":653,"t":"Multi-AZ and multi-cloud environments","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments","b":["For Operators","Container Layer","Components","K8s Cluster API Provider","Usage"]},{"i":655,"t":"Migration to KaaS v2","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2","b":["For Operators"]},{"i":661,"t":"Migration to ClusterClass","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class","b":["For Operators","Container Layer","Components","K8s Cluster API Provider","Usage"]},{"i":668,"t":"Testing","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/testing","b":["For Operators","Container Layer","Components","K8s Cluster API Provider","Usage"]},{"i":670,"t":"Overview","u":"/docs/container/deployment-examples/a/","b":["For Operators"]},{"i":672,"t":"Hardware Requirements","u":"/docs/container/deployment-examples/a/hardware","b":["For Operators"]},{"i":674,"t":"Guide 1","u":"/docs/container/guides/guide1","b":["For Operators"]},{"i":676,"t":"Software Requirements","u":"/docs/container/deployment-examples/a/software","b":["For Operators"]},{"i":678,"t":"Architecture","u":"/docs/container/overview/architecture","b":["For Operators"]},{"i":680,"t":"Knowledge","u":"/docs/container/overview/knowledge","b":["For Operators"]},{"i":682,"t":"Containerization","u":"/docs/getting-started/containerization","b":["For Operators"]},{"i":684,"t":"Overview","u":"/docs/getting-started/overview","b":["For Operators"]},{"i":686,"t":"Virtualization","u":"/docs/getting-started/virtualization","b":["For Operators"]},{"i":688,"t":"Frequently Asked Questions","u":"/docs/faq/","b":["For Operators"]},{"i":723,"t":"Tools","u":"/docs/iaas/components/","b":["For Operators"]},{"i":724,"t":"Flavor Manager","u":"/docs/iaas/components/flavor-manager","b":["For Operators","IaaS Layer","Components"]},{"i":735,"t":"Glossary","u":"/docs/glossary","b":["For Operators"]},{"i":781,"t":"Image Manager","u":"/docs/iaas/components/image-manager/","b":["For Operators","IaaS Layer","Components","Openstack Image Manager"]},{"i":806,"t":"Project Manager","u":"/docs/iaas/components/project-manager","b":["For Operators"]},{"i":828,"t":"Resource Manager","u":"/docs/iaas/components/resource-manager","b":["For Operators"]},{"i":843,"t":"Sandbox Manager","u":"/docs/iaas/components/sandbox-manager","b":["For Operators"]},{"i":844,"t":"Image Manager update.py","u":"/docs/iaas/components/image-manager/update","b":["For Operators","IaaS Layer","Components","Openstack Image Manager"]},{"i":851,"t":"Simple Stress","u":"/docs/iaas/components/simple-stress","b":["For Operators"]},{"i":862,"t":"Concept Guide","u":"/docs/iaas/guides/concept-guide/","b":["For Operators","IaaS Layer","Guides","Concept Guide"]},{"i":875,"t":"Guides","u":"/docs/iaas/guides/","b":["For Operators","IaaS Layer","Guides"]},{"i":877,"t":"Components","u":"/docs/iaas/guides/concept-guide/components/","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":879,"t":"Ceph","u":"/docs/iaas/guides/concept-guide/components/ceph","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":882,"t":"Cluster API","u":"/docs/iaas/guides/concept-guide/components/clusterapi","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":887,"t":"Gardener","u":"/docs/iaas/guides/concept-guide/components/gardener","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":890,"t":"K3S","u":"/docs/iaas/guides/concept-guide/components/k3s","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":892,"t":"Setting up OpenStack health monitor on Debian","u":"/docs/iaas/components/openstack-health-monitor","b":["For Operators"]},{"i":950,"t":"Keycloak","u":"/docs/iaas/guides/concept-guide/components/keycloak","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":952,"t":"OpenStack","u":"/docs/iaas/guides/concept-guide/components/openstack","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":955,"t":"Ironic","u":"/docs/iaas/guides/concept-guide/components/ironic","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":958,"t":"Prometheus & Grafana","u":"/docs/iaas/guides/concept-guide/components/prometheus","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":961,"t":"Netdata","u":"/docs/iaas/guides/concept-guide/components/netdata","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":963,"t":"SONiC & OVN","u":"/docs/iaas/guides/concept-guide/components/sonic","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":967,"t":"Teleport","u":"/docs/iaas/guides/concept-guide/components/teleport","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":969,"t":"Cluster design","u":"/docs/iaas/guides/concept-guide/design","b":["For Operators","IaaS Layer","Guides","Concept Guide"]},{"i":976,"t":"Proxmox VE","u":"/docs/iaas/guides/concept-guide/components/proxmox","b":["For Operators","IaaS Layer","Guides","Concept Guide","Components"]},{"i":979,"t":"Hardware Bill of Materials","u":"/docs/iaas/guides/concept-guide/hardware-bom","b":["For Operators","IaaS Layer","Guides","Concept Guide"]},{"i":999,"t":"Layers in a cluster","u":"/docs/iaas/guides/concept-guide/layers","b":["For Operators","IaaS Layer","Guides","Concept Guide"]},{"i":1006,"t":"Configuration Guide","u":"/docs/iaas/guides/configuration-guide/","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1007,"t":"Commons","u":"/docs/iaas/guides/configuration-guide/commons/","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1009,"t":"Use cases","u":"/docs/iaas/guides/concept-guide/use-cases","b":["For Operators","IaaS Layer","Guides","Concept Guide"]},{"i":1011,"t":"Certificates","u":"/docs/iaas/guides/configuration-guide/commons/certificates","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1013,"t":"Packages","u":"/docs/iaas/guides/configuration-guide/commons/packages","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1022,"t":"Resolvconf","u":"/docs/iaas/guides/configuration-guide/commons/resolvconf","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1024,"t":"Services","u":"/docs/iaas/guides/configuration-guide/commons/services","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1030,"t":"Sysctl","u":"/docs/iaas/guides/configuration-guide/commons/sysctl","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1032,"t":"Timezone","u":"/docs/iaas/guides/configuration-guide/commons/timezone","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1034,"t":"SSH Config","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1042,"t":"User","u":"/docs/iaas/guides/configuration-guide/commons/user","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Commons"]},{"i":1044,"t":"Inventory","u":"/docs/iaas/guides/configuration-guide/inventory","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1053,"t":"Loadbalancer","u":"/docs/iaas/guides/configuration-guide/loadbalancer","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1056,"t":"Configuration Repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1078,"t":"Manager","u":"/docs/iaas/guides/configuration-guide/manager","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1085,"t":"Aodh","u":"/docs/iaas/guides/configuration-guide/openstack/aodh","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1087,"t":"Network","u":"/docs/iaas/guides/configuration-guide/network","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1099,"t":"Ceph","u":"/docs/iaas/guides/configuration-guide/ceph","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1125,"t":"Barbican","u":"/docs/iaas/guides/configuration-guide/openstack/barbican","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1127,"t":"Cinder","u":"/docs/iaas/guides/configuration-guide/openstack/cinder","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1131,"t":"Designate","u":"/docs/iaas/guides/configuration-guide/openstack/designate","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1133,"t":"Ceilometer","u":"/docs/iaas/guides/configuration-guide/openstack/ceilometer","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1135,"t":"Glance","u":"/docs/iaas/guides/configuration-guide/openstack/glance","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1137,"t":"Heat","u":"/docs/iaas/guides/configuration-guide/openstack/heat","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1139,"t":"Ironic","u":"/docs/iaas/guides/configuration-guide/openstack/ironic","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1141,"t":"Horizon","u":"/docs/iaas/guides/configuration-guide/openstack/horizon","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1147,"t":"Keystone","u":"/docs/iaas/guides/configuration-guide/openstack/keystone","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1152,"t":"Manila","u":"/docs/iaas/guides/configuration-guide/openstack/manila","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1154,"t":"OpenStack","u":"/docs/iaas/guides/configuration-guide/openstack/","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1170,"t":"Nova","u":"/docs/iaas/guides/configuration-guide/openstack/nova","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1185,"t":"Neutron","u":"/docs/iaas/guides/configuration-guide/openstack/neutron","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1189,"t":"Magnum","u":"/docs/iaas/guides/configuration-guide/openstack/magnum","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1191,"t":"Octavia","u":"/docs/iaas/guides/configuration-guide/openstack/octavia","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1193,"t":"Skyline","u":"/docs/iaas/guides/configuration-guide/openstack/skyline","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1198,"t":"Proxy","u":"/docs/iaas/guides/configuration-guide/proxy","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1206,"t":"Services","u":"/docs/iaas/guides/configuration-guide/services/","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Services"]},{"i":1208,"t":"Chrony","u":"/docs/iaas/guides/configuration-guide/services/chrony","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Services"]},{"i":1210,"t":"Placement","u":"/docs/iaas/guides/configuration-guide/openstack/placement","b":["For Operators","IaaS Layer","Guides","Configuration Guide","OpenStack"]},{"i":1212,"t":"Self-signed certificates","u":"/docs/iaas/guides/configuration-guide/self-signed-certificates","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1214,"t":"Docker","u":"/docs/iaas/guides/configuration-guide/services/docker","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Services"]},{"i":1218,"t":"Deploy Guide","u":"/docs/iaas/guides/deploy-guide/","b":["For Operators","IaaS Layer","Guides","Deploy Guide"]},{"i":1220,"t":"Validations","u":"/docs/iaas/guides/configuration-guide/validations/","b":["For Operators","IaaS Layer","Guides","Configuration Guide"]},{"i":1222,"t":"Examples","u":"/docs/iaas/guides/deploy-guide/examples/","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Examples"]},{"i":1223,"t":"Bootstrap","u":"/docs/iaas/guides/deploy-guide/bootstrap","b":["For Operators","IaaS Layer","Guides","Deploy Guide"]},{"i":1225,"t":"Tuned","u":"/docs/iaas/guides/configuration-guide/services/tuned","b":["For Operators","IaaS Layer","Guides","Configuration Guide","Services"]},{"i":1227,"t":"Cloud in a Box","u":"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Examples"]},{"i":1229,"t":"Testbed","u":"/docs/iaas/guides/deploy-guide/examples/testbed","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Examples"]},{"i":1231,"t":"Provisioning of bare-metal nodes","u":"/docs/iaas/guides/deploy-guide/provisioning","b":["For Operators","IaaS Layer","Guides","Deploy Guide"]},{"i":1235,"t":"Seed","u":"/docs/iaas/guides/deploy-guide/seed","b":["For Operators","IaaS Layer","Guides","Deploy Guide"]},{"i":1241,"t":"Infrastructure","u":"/docs/iaas/guides/deploy-guide/services/infrastructure","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1243,"t":"Services","u":"/docs/iaas/guides/deploy-guide/services/","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1245,"t":"Kubernetes","u":"/docs/iaas/guides/deploy-guide/services/kubernetes","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1249,"t":"Logging & Monitoring","u":"/docs/iaas/guides/deploy-guide/services/logging-monitoring","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1251,"t":"Manager","u":"/docs/iaas/guides/deploy-guide/manager","b":["For Operators","IaaS Layer","Guides","Deploy Guide"]},{"i":1265,"t":"Operations Guide","u":"/docs/iaas/guides/operations-guide/","b":["For Operators","IaaS Layer","Guides","Operations Guide"]},{"i":1283,"t":"Network","u":"/docs/iaas/guides/deploy-guide/services/network","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1285,"t":"Ceph","u":"/docs/iaas/guides/deploy-guide/services/ceph","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1293,"t":"OpenStack","u":"/docs/iaas/guides/deploy-guide/services/openstack","b":["For Operators","IaaS Layer","Guides","Deploy Guide","Services"]},{"i":1295,"t":"Infrastructure","u":"/docs/iaas/guides/operations-guide/infrastructure","b":["For Operators","IaaS Layer","Guides","Operations Guide"]},{"i":1308,"t":"Manager","u":"/docs/iaas/guides/operations-guide/manager/","b":["For Operators","IaaS Layer","Guides","Operations Guide","Manager"]},{"i":1309,"t":"Apply","u":"/docs/iaas/guides/operations-guide/manager/apply","b":["For Operators","IaaS Layer","Guides","Operations Guide","Manager"]},{"i":1312,"t":"Logging","u":"/docs/iaas/guides/operations-guide/manager/log","b":["For Operators","IaaS Layer","Guides","Operations Guide","Manager"]},{"i":1322,"t":"Get","u":"/docs/iaas/guides/operations-guide/manager/get","b":["For Operators","IaaS Layer","Guides","Operations Guide","Manager"]},{"i":1330,"t":"Console","u":"/docs/iaas/guides/operations-guide/manager/console","b":["For Operators","IaaS Layer","Guides","Operations Guide","Manager"]},{"i":1340,"t":"Task","u":"/docs/iaas/guides/operations-guide/manager/task","b":["For Operators","IaaS Layer","Guides","Operations Guide","Manager"]},{"i":1345,"t":"Cinder","u":"/docs/iaas/guides/operations-guide/openstack/cinder","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack"]},{"i":1352,"t":"Keystone","u":"/docs/iaas/guides/operations-guide/openstack/keystone","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack"]},{"i":1354,"t":"OpenStack","u":"/docs/iaas/guides/operations-guide/openstack/","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack"]},{"i":1363,"t":"Network","u":"/docs/iaas/guides/operations-guide/network","b":["For Operators","IaaS Layer","Guides","Operations Guide"]},{"i":1369,"t":"Nova","u":"/docs/iaas/guides/operations-guide/openstack/nova","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack"]},{"i":1384,"t":"Octavia","u":"/docs/iaas/guides/operations-guide/openstack/octavia","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack"]},{"i":1389,"t":"Neutron","u":"/docs/iaas/guides/operations-guide/openstack/neutron","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack"]},{"i":1392,"t":"Tools","u":"/docs/iaas/guides/operations-guide/openstack/tools/","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1393,"t":"Ceph","u":"/docs/iaas/guides/operations-guide/ceph","b":["For Operators","IaaS Layer","Guides","Operations Guide"]},{"i":1478,"t":"Image Manager update.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools","Image Manager"]},{"i":1485,"t":"Flavor Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1496,"t":"Project Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1518,"t":"Image Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools","Image Manager"]},{"i":1543,"t":"Resource Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1558,"t":"Sandbox Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/sandbox-manager","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1559,"t":"Cloud in a Box - CiaB","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","b":["For Operators","IaaS Layer","Guides","Other Guides"]},{"i":1592,"t":"Other Guides","u":"/docs/iaas/guides/other-guides/","b":["For Operators","IaaS Layer","Guides","Other Guides"]},{"i":1593,"t":"Contributor Guide","u":"/docs/iaas/guides/other-guides/contributor-guide","b":["For Operators","IaaS Layer","Guides","Other Guides"]},{"i":1595,"t":"Simple Stress","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1606,"t":"Developer Guide","u":"/docs/iaas/guides/other-guides/developer-guide/","b":["For Operators","IaaS Layer","Guides","Other Guides","Developer Guide"]},{"i":1614,"t":"Setting up OpenStack health monitor on Debian","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","b":["For Operators","IaaS Layer","Guides","Operations Guide","OpenStack","Tools"]},{"i":1672,"t":"Releases","u":"/docs/iaas/guides/other-guides/developer-guide/releases","b":["For Operators","IaaS Layer","Guides","Other Guides","Developer Guide"]},{"i":1689,"t":"Scripts","u":"/docs/iaas/guides/other-guides/developer-guide/scripts","b":["For Operators","IaaS Layer","Guides","Other Guides","Developer Guide"]},{"i":1691,"t":"Style Guide","u":"/docs/iaas/guides/other-guides/style-guide","b":["For Operators","IaaS Layer","Guides","Other Guides"]},{"i":1722,"t":"Troubleshooting Guide","u":"/docs/iaas/guides/troubleshooting-guide/","b":["For Operators","IaaS Layer","Guides","Troubleshooting Guide"]},{"i":1724,"t":"Ceph","u":"/docs/iaas/guides/troubleshooting-guide/ceph","b":["For Operators","IaaS Layer","Guides","Troubleshooting Guide"]},{"i":1729,"t":"Manager","u":"/docs/iaas/guides/troubleshooting-guide/manager","b":["For Operators","IaaS Layer","Guides","Troubleshooting Guide"]},{"i":1732,"t":"OpenStack","u":"/docs/iaas/guides/troubleshooting-guide/openstack","b":["For Operators","IaaS Layer","Guides","Troubleshooting Guide"]},{"i":1735,"t":"Upgrade Guide","u":"/docs/iaas/guides/upgrade-guide/","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":1737,"t":"Zuul CI","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","b":["For Operators","IaaS Layer","Guides","Other Guides","Developer Guide"]},{"i":1759,"t":"Ceph","u":"/docs/iaas/guides/upgrade-guide/ceph","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":1761,"t":"Logging & Monitoring","u":"/docs/iaas/guides/upgrade-guide/logging-monitoring","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":1763,"t":"Docker","u":"/docs/iaas/guides/upgrade-guide/docker","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":1767,"t":"Infrastructure","u":"/docs/iaas/guides/upgrade-guide/infrastructure","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":1769,"t":"Testbed","u":"/docs/iaas/guides/other-guides/testbed","b":["For Operators","IaaS Layer","Guides","Other Guides"]},{"i":1819,"t":"Network","u":"/docs/iaas/guides/upgrade-guide/network","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":1821,"t":"OpenStack","u":"/docs/iaas/guides/upgrade-guide/openstack","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":1823,"t":"User Guide","u":"/docs/iaas/guides/user-guide/","b":["For Operators","IaaS Layer","Guides","User Guide"]},{"i":1824,"t":"Manager","u":"/docs/iaas/guides/upgrade-guide/manager","b":["For Operators","IaaS Layer","Guides","Upgrade Guide"]},{"i":1826,"t":"Migrate from VMware ESXi to OpenStack","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","b":["For Operators","IaaS Layer","Guides","User Guide"]},{"i":1852,"t":"How to configure and use security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","b":["For Operators","IaaS Layer","Guides","User Guide","OpenStack"]},{"i":1866,"t":"OpenStack","u":"/docs/iaas/guides/user-guide/openstack/","b":["For Operators","IaaS Layer","Guides","User Guide","OpenStack"]},{"i":1867,"t":"Architecture","u":"/docs/iaas/overview/architecture","b":["For Operators"]},{"i":1869,"t":"User Data Backups","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","b":["For Operators","IaaS Layer","Guides","User Guide","OpenStack"]},{"i":1914,"t":"Best Practise: How to configure and use security groups","u":"/docs/iaas/guides/user-guide/security-groups/","b":["For Operators","IaaS Layer","Guides","User Guide"]},{"i":1928,"t":"Compute","u":"/docs/iaas/overview/compute","b":["For Operators"]},{"i":1930,"t":"Knowledge","u":"/docs/iaas/overview/knowledge","b":["For Operators"]},{"i":1932,"t":"Network","u":"/docs/iaas/overview/network","b":["For Operators"]},{"i":1934,"t":"Storage","u":"/docs/iaas/overview/storage","b":["For Operators"]},{"i":1936,"t":"Introduction on Identity Management and Federation in SCS","u":"/docs/iam/","b":["For Operators","Identity and Access Management (IAM)"]},{"i":1954,"t":"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)","u":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","b":["For Operators","Identity and Access Management (IAM)"]},{"i":1958,"t":"Example setup configuration in SCS deployment explained","u":"/docs/iam/SCS-example-setup-configuration-description","b":["For Operators","Identity and Access Management (IAM)","Guides"]},{"i":1960,"t":"Overview","u":"/docs/operating-scs/audits/","b":["For Operators"]},{"i":1962,"t":"SCS automated pentesting","u":"/docs/operating-scs/components/automated-pentesting/overview","b":["For Operators","Operating SCS","Components","Automated Pentesting"]},{"i":1968,"t":"Overview","u":"/docs/operating-scs/components/central-api/overview","b":["For Operators","Operating SCS","Components","Central API"]},{"i":1985,"t":"User Data Backups","u":"/docs/iaas/guides/user-guide/user-data-backups","b":["For Operators","IaaS Layer","Guides","User Guide"]},{"i":2030,"t":"Central API MVP","u":"/docs/operating-scs/components/central-api/poc-setup","b":["For Operators","Operating SCS","Components","Central API"]},{"i":2034,"t":"Domain Manager setup and usage","u":"/docs/iam/domain-manager-setup-and-usage","b":["For Operators","Identity and Access Management (IAM)","Guides"]},{"i":2070,"t":"Alertmanager notifications in Matrix chat","u":"/docs/operating-scs/components/monitoring/docs/alertmanager","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2072,"t":"Tools Description","u":"/docs/operating-scs/components/automated-pentesting/tools","b":["For Operators","Operating SCS","Components","Automated Pentesting"]},{"i":2086,"t":"IaaS monitoring (experimental)","u":"/docs/operating-scs/components/monitoring/docs/iaas","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2099,"t":"K3s support","u":"/docs/operating-scs/components/monitoring/docs/k3s","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2109,"t":"OAUTH","u":"/docs/operating-scs/components/monitoring/docs/oauth","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2111,"t":"KaaS monitoring (experimental)","u":"/docs/operating-scs/components/monitoring/docs/kaas","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2119,"t":"Infrastructure service endpoints","u":"/docs/operating-scs/components/monitoring/docs/infrastructure_services","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2121,"t":"Quickstart","u":"/docs/operating-scs/components/monitoring/docs/quickstart","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2131,"t":"SCS deployment","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2139,"t":"Traces","u":"/docs/operating-scs/components/monitoring/docs/tracing","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2145,"t":"Tuning","u":"/docs/operating-scs/components/monitoring/docs/tuning","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2153,"t":"Overview","u":"/docs/operating-scs/components/monitoring/docs/overview","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2155,"t":"Component Overview","u":"/docs/operating-scs/components/status-page/docs/component_overview","b":["For Operators","Operating SCS","Components","Status Page API"]},{"i":2157,"t":"Zuul monitoring","u":"/docs/operating-scs/components/monitoring/docs/zuul","b":["For Operators","Operating SCS","Components","Monitoring"]},{"i":2159,"t":"Components","u":"/docs/operating-scs/components/status-page/docs/components","b":["For Operators","Operating SCS","Components","Status Page API"]},{"i":2161,"t":"Overview","u":"/docs/operating-scs/components/status-page/docs/overview","b":["For Operators","Operating SCS","Components","Status Page API"]},{"i":2173,"t":"Overview","u":"/docs/operating-scs/incident-management/","b":["For Operators"]},{"i":2175,"t":"\"Levels of consensus\"","u":"/docs/operating-scs/components/status-page/docs/levels_of_consensus","b":["For Operators","Operating SCS","Components","Status Page API"]},{"i":2177,"t":"Overview","u":"/docs/operating-scs/lifecycle-management/","b":["For Operators"]},{"i":2179,"t":"Overview","u":"/docs/operating-scs/logging/","b":["For Operators"]},{"i":2181,"t":"Overview","u":"/docs/operating-scs/monitoring/","b":["For Operators"]},{"i":2183,"t":"Overview","u":"/docs/operating-scs/overview","b":["For Operators"]},{"i":2185,"t":"Release Notes for SCS Release 0","u":"/docs/releases/Release0","b":["For Operators","Releases"]},{"i":2203,"t":"Release Notes for SCS Release 1","u":"/docs/releases/Release1","b":["For Operators","Releases"]},{"i":2240,"t":"Release Notes for SCS Release 2","u":"/docs/releases/Release2","b":["For Operators","Releases"]},{"i":2273,"t":"Release Notes for SCS Release 3","u":"/docs/releases/Release3","b":["For Operators","Releases"]},{"i":2307,"t":"Release Notes for SCS Release 4","u":"/docs/releases/Release4","b":["For Operators","Releases"]},{"i":2339,"t":"Guide: Setting up openstack-health-monitor on Debian 12","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","b":["For Operators","Operating SCS","Guides"]},{"i":2397,"t":"Release Notes for SCS Release 5","u":"/docs/releases/Release5","b":["For Operators","Releases"]},{"i":2435,"t":"Release Notes for SCS Release X","u":"/docs/releases/ReleaseX","b":["For Operators"]},{"i":2453,"t":"Release Notes for SCS Release 6","u":"/docs/releases/Release6","b":["For Operators","Releases"]},{"i":2511,"t":"Standards","u":"/docs/standards/","b":["For Operators"]},{"i":2513,"t":"Introduction","u":"/standards/","b":["Standards"]},{"i":2515,"t":"Certification","u":"/standards/certification/overview","b":["Standards","Certification"]},{"i":2521,"t":"Scopes and versions","u":"/standards/certification/scopes-versions","b":["Standards","Certification","Scopes and Versions"]},{"i":2523,"t":"scs-0001: Sovereign Cloud Standards","u":"/standards/global/scs-0001","b":["Standards","Standards","Global","scs-0001"]},{"i":2525,"t":"Global Standards","u":"/standards/global/","b":["Standards","Standards","Global"]},{"i":2527,"t":"scs-0002: Standards, Docs and Organisation","u":"/standards/global/scs-0002","b":["Standards","Standards","Global","scs-0002"]},{"i":2529,"t":"scs-0003: Sovereign Cloud Standards YAML","u":"/standards/global/scs-0003","b":["Standards","Standards","Global","scs-0003"]},{"i":2531,"t":"scs-0004: Regulations for achieving SCS-compatible certification","u":"/standards/global/scs-0004","b":["Standards","Standards","Global","scs-0004"]},{"i":2533,"t":"scs-0112: SONiC Support in SCS","u":"/standards/global/scs-0112","b":["Standards","Standards","Global","scs-0112"]},{"i":2535,"t":"scs-0100: SCS Flavor Naming Standard","u":"/standards/iaas/scs-0100","b":["Standards","Standards","IaaS","scs-0100"]},{"i":2539,"t":"scs-0101: SCS Entropy","u":"/standards/iaas/scs-0101","b":["Standards","Standards","IaaS","scs-0101"]},{"i":2543,"t":"IaaS Standards","u":"/standards/iaas/","b":["Standards","Standards","IaaS"]},{"i":2545,"t":"scs-0102: SCS Image Metadata Standard","u":"/standards/iaas/scs-0102","b":["Standards","Standards","IaaS","scs-0102"]},{"i":2547,"t":"scs-0104: SCS Standard Images","u":"/standards/iaas/scs-0104","b":["Standards","Standards","IaaS","scs-0104"]},{"i":2549,"t":"scs-0103: SCS Standard Flavors and Properties","u":"/standards/iaas/scs-0103","b":["Standards","Standards","IaaS","scs-0103"]},{"i":2551,"t":"scs-0113: Security Groups Decision Record","u":"/standards/iaas/scs-0113","b":["Standards","Standards","IaaS","scs-0113"]},{"i":2553,"t":"scs-0110: SSD Flavors","u":"/standards/iaas/scs-0110","b":["Standards","Standards","IaaS","scs-0110"]},{"i":2555,"t":"scs-0111: Decisions for the Volume Type Standard","u":"/standards/iaas/scs-0111","b":["Standards","Standards","IaaS","scs-0111"]},{"i":2557,"t":"scs-0114: Volume Type Standard","u":"/standards/iaas/scs-0114","b":["Standards","Standards","IaaS","scs-0114"]},{"i":2559,"t":"Metering Configuration","u":"/docs/operating-scs/metering/meter_configuration","b":["For Operators","Operating SCS","Metering"]},{"i":2571,"t":"scs-0115: Default Rules for Security Groups","u":"/standards/iaas/scs-0115","b":["Standards","Standards","IaaS","scs-0115"]},{"i":2573,"t":"IAM Standards","u":"/standards/iam/","b":["Standards","Standards","IAM"]},{"i":2575,"t":"scs-0300: Requirements for SSO identity federation","u":"/standards/iam/scs-0300","b":["Standards","Standards","IAM","scs-0300"]},{"i":2577,"t":"scs-0302: Domain Manager configuration for Keystone","u":"/standards/iam/scs-0302","b":["Standards","Standards","IAM","scs-0302"]},{"i":2579,"t":"scs-0301: Naming for domains/groups/roles/project when onboarding new customers","u":"/standards/iam/scs-0301","b":["Standards","Standards","IAM","scs-0301"]},{"i":2581,"t":"scs-0200: Using Sonobuoy for KaaS conformance tests","u":"/standards/kaas/scs-0200","b":["Standards","Standards","KaaS","scs-0200"]},{"i":2583,"t":"scs-0210: SCS K8S Version Policy","u":"/standards/kaas/scs-0210","b":["Standards","Standards","KaaS","scs-0210"]},{"i":2585,"t":"scs-0211: SCS KaaS default storage class","u":"/standards/kaas/scs-0211","b":["Standards","Standards","KaaS","scs-0211"]},{"i":2587,"t":"scs-0212: Requirements for container registries","u":"/standards/kaas/scs-0212","b":["Standards","Standards","KaaS","scs-0212"]},{"i":2589,"t":"scs-0213: Kubernetes Nodes Anti Affinity","u":"/standards/kaas/scs-0213","b":["Standards","Standards","KaaS","scs-0213"]},{"i":2591,"t":"KaaS Standards","u":"/standards/kaas/","b":["Standards","Standards","KaaS"]},{"i":2593,"t":"scs-0214: Kubernetes Node Distribution and Availability","u":"/standards/kaas/scs-0214","b":["Standards","Standards","KaaS","scs-0214"]},{"i":2595,"t":"scs-0217: Kubernetes cluster baseline security","u":"/standards/kaas/scs-0217","b":["Standards","Standards","KaaS","scs-0217"]},{"i":2597,"t":"scs-0218: Container registry for SCS standard implementation","u":"/standards/kaas/scs-0218","b":["Standards","Standards","KaaS","scs-0218"]},{"i":2599,"t":"scs-0215: Robustness features for Kubernetes clusters","u":"/standards/kaas/scs-0215","b":["Standards","Standards","KaaS","scs-0215"]},{"i":2601,"t":"Ops Standards","u":"/standards/ops/","b":["Standards","Standards","Ops"]},{"i":2603,"t":"scs-0216: Requirements for testing cluster-stacks","u":"/standards/kaas/scs-0216","b":["Standards","Standards","KaaS","scs-0216"]},{"i":2605,"t":"scs-0400: Status Page create decision","u":"/standards/ops/scs-0400","b":["Standards","Standards","Ops","scs-0400"]},{"i":2607,"t":"scs-0401: Status page reference implementation decision","u":"/standards/ops/scs-0401","b":["Standards","Standards","Ops","scs-0401"]},{"i":2609,"t":"scs-0410: Gnocchi as database for metering","u":"/standards/ops/scs-0410","b":["Standards","Standards","Ops","scs-0410"]},{"i":2611,"t":"scs-0402: Status page OpenAPI decision","u":"/standards/ops/scs-0402","b":["Standards","Standards","Ops","scs-0402"]},{"i":2613,"t":"scs-0411: Push-based approach for providing usage data","u":"/standards/ops/scs-0411","b":["Standards","Standards","Ops","scs-0411"]},{"i":2615,"t":"Sovereign Cloud Standards","u":"/standards/scs-0001-v1-sovereign-cloud-standards","b":["Standards","Standards","Global","scs-0001"]},{"i":2650,"t":"scs-0412: Exposition of IaaS metering data as JSON","u":"/standards/ops/scs-0412","b":["Standards","Standards","Ops","scs-0412"]},{"i":2652,"t":"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer","u":"/standards/ops/scs-0403","b":["Standards","Standards","Ops","scs-0403"]},{"i":2654,"t":"Standards, Docs and Organisation","u":"/standards/scs-0002-v1-standards-docs-org","b":["Standards","Standards","Global","scs-0002"]},{"i":2661,"t":"SCS Documentation structure","u":"/standards/scs-0002-v2-standards-docs-org","b":["Standards","Standards","Global","scs-0002"]},{"i":2682,"t":"Regulations for achieving SCS-compatible certification","u":"/standards/scs-0004-v1-achieving-certification","b":["Standards","Standards","Global","scs-0004"]},{"i":2693,"t":"SCS Flavor Naming Standard","u":"/standards/scs-0100-v2-flavor-naming","b":["Standards","Standards","IaaS","scs-0100"]},{"i":2738,"t":"SCS Flavor Naming Standard","u":"/standards/scs-0100-v3-flavor-naming","b":["Standards","Standards","IaaS","scs-0100"]},{"i":2777,"t":"SCS Flavor Naming Standard: Implementation and Testing Notes","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","b":["Standards","Standards","IaaS","scs-0100"]},{"i":2793,"t":"Sovereign Cloud Standards YAML","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","b":["Standards","Standards","Global","scs-0003"]},{"i":2828,"t":"SCS Flavor Naming Standard","u":"/standards/scs-0100-v1-flavor-naming","b":["Standards","Standards","IaaS","scs-0100"]},{"i":2865,"t":"SCS Entropy","u":"/standards/scs-0101-v1-entropy","b":["Standards","Standards","IaaS","scs-0101"]},{"i":2884,"t":"SCS Image Metadata Standard","u":"/standards/scs-0102-v1-image-metadata","b":["Standards","Standards","IaaS","scs-0102"]},{"i":2904,"t":"SCS Entropy: Implementation and Testing Notes","u":"/standards/scs-0101-w1-entropy-implementation-testing","b":["Standards","Standards","IaaS","scs-0101"]},{"i":2918,"t":"SCS Standard Flavors and Properties","u":"/standards/scs-0103-v1-standard-flavors","b":["Standards","Standards","IaaS","scs-0103"]},{"i":2940,"t":"SSD Flavors","u":"/standards/scs-0110-v1-ssd-flavors","b":["Standards","Standards","IaaS","scs-0110"]},{"i":2958,"t":"Decisions for the Volume Type Standard","u":"/standards/scs-0111-v1-volume-type-decisions","b":["Standards","Standards","IaaS","scs-0111"]},{"i":2973,"t":"SCS Standard Images","u":"/standards/scs-0104-v1-standard-images","b":["Standards","Standards","IaaS","scs-0104"]},{"i":2997,"t":"SONiC Support in SCS","u":"/standards/scs-0112-v1-sonic","b":["Standards","Standards","Global","scs-0112"]},{"i":3019,"t":"Volume Type Standard","u":"/standards/scs-0114-v1-volume-type-standard","b":["Standards","Standards","IaaS","scs-0114"]},{"i":3051,"t":"Using Sonobuoy for KaaS conformance tests","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","b":["Standards","Standards","KaaS","scs-0200"]},{"i":3072,"t":"Default Rules for Security Groups","u":"/standards/scs-0115-v1-default-rules-for-security-groups","b":["Standards","Standards","IaaS","scs-0115"]},{"i":3095,"t":"Security Groups Decision Record","u":"/standards/scs-0113-v1-security-groups-decision-record","b":["Standards","Standards","IaaS","scs-0113"]},{"i":3122,"t":"SCS K8S Version Policy","u":"/standards/scs-0210-v2-k8s-version-policy","b":["Standards","Standards","KaaS","scs-0210"]},{"i":3133,"t":"SCS KaaS default storage class","u":"/standards/scs-0211-v1-kaas-default-storage-class","b":["Standards","Standards","KaaS","scs-0211"]},{"i":3148,"t":"Requirements for container registries","u":"/standards/scs-0212-v1-requirements-for-container-registries","b":["Standards","Standards","KaaS","scs-0212"]},{"i":3165,"t":"SCS K8S Version Policy for new Kubernetes versions","u":"/standards/scs-0210-v1-k8s-new-version-policy","b":["Standards","Standards","KaaS","scs-0210"]},{"i":3176,"t":"Kubernetes Nodes Anti Affinity","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","b":["Standards","Standards","KaaS","scs-0213"]},{"i":3189,"t":"Kubernetes Node Distribution and Availability","u":"/standards/scs-0214-v1-k8s-node-distribution","b":["Standards","Standards","KaaS","scs-0214"]},{"i":3202,"t":"Requirements for testing cluster-stacks","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","b":["Standards","Standards","KaaS","scs-0216"]},{"i":3225,"t":"Kubernetes cluster baseline security","u":"/standards/scs-0217-v1-baseline-cluster-security","b":["Standards","Standards","KaaS","scs-0217"]},{"i":3243,"t":"Requirements for SSO identity federation","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","b":["Standards","Standards","IAM","scs-0300"]},{"i":3260,"t":"Robustness features for Kubernetes clusters","u":"/standards/scs-0215-v1-robustness-features","b":["Standards","Standards","KaaS","scs-0215"]},{"i":3291,"t":"Container registry for SCS standard implementation","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","b":["Standards","Standards","KaaS","scs-0218"]},{"i":3306,"t":"Status Page create decision","u":"/standards/scs-0400-v1-status-page-create-decision","b":["Standards","Standards","Ops","scs-0400"]},{"i":3317,"t":"Naming for domains/groups/roles/project when onboarding new customers","u":"/standards/scs-0301-v1-naming-conventions","b":["Standards","Standards","IAM","scs-0301"]},{"i":3334,"t":"Status page OpenAPI decision","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","b":["Standards","Standards","Ops","scs-0402"]},{"i":3368,"t":"Gnocchi as database for metering","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","b":["Standards","Standards","Ops","scs-0410"]},{"i":3387,"t":"Architecture for the Cloud Service provider Observability System for the KaaS Layer","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","b":["Standards","Standards","Ops","scs-0403"]},{"i":3401,"t":"Status page reference implementation decision","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","b":["Standards","Standards","Ops","scs-0401"]},{"i":3411,"t":"Exposition of IaaS metering data as JSON","u":"/standards/scs-0412-v1-metering-json","b":["Standards","Standards","Ops","scs-0412"]},{"i":3428,"t":"SCS Compatible IaaS","u":"/standards/scs-compatible-iaas","b":["Standards","Certification","Scopes and Versions"]},{"i":3430,"t":"SCS Compatible KaaS","u":"/standards/scs-compatible-kaas","b":["Standards","Certification","Scopes and Versions"]},{"i":3432,"t":"Push-based approach for providing usage data","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","b":["Standards","Standards","Ops","scs-0411"]},{"i":3451,"t":"Domain Manager configuration for Keystone","u":"/standards/scs-0302-v1-domain-manager-role","b":["Standards","Standards","IAM","scs-0302"]},{"i":3485,"t":"_Descriptive title_","u":"/standards/scs-XXXX-vN-decision-record-template","b":["Standards"]},{"i":3498,"t":"_Descriptive title_","u":"/standards/scs-XXXX-vN-standard-template","b":["Standards"]},{"i":3517,"t":"Overview","u":"/standards/standards/overview","b":["Standards","Standards"]}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/1",[]],["t/2",[0,4.143]],["t/5",[1,5.18,2,5.18,3,5.18]],["t/7",[4,4.381,5,4.381,6,3.109]],["t/15",[7,2.915,8,3.446,9,2.915,10,3.818]],["t/33",[11,5.14,12,4.297]],["t/41",[4,2.755,5,2.755,13,3.257,14,2.954,15,3.257,16,2.388,17,3.257]],["t/49",[4,4.381,5,4.381,18,5.18]],["t/56",[19,7.351]],["t/68",[20,4.64,21,6.077]],["t/70",[11,4.381,20,3.955,22,3.798]],["t/72",[20,4.64,23,4.297]],["t/74",[20,4.64,24,4.036]],["t/76",[25,4.862,26,4.297]],["t/78",[20,4.64,27,2.746]],["t/80",[25,4.862,28,4.456]],["t/82",[25,4.862,29,5.512]],["t/84",[23,3.663,30,5.18,31,4.699]],["t/100",[25,4.862,32,5.512]],["t/102",[23,3.663,33,5.18,34,5.18]],["t/106",[35,5.18,36,4.381,37,2.586]],["t/119",[37,3.034,38,6.077]],["t/125",[39,7.351]],["t/132",[37,2.586,40,5.18,41,4.699]],["t/152",[42,7.351]],["t/165",[43,4.699,44,5.18,45,1.511]],["t/183",[46,5.18,47,5.18,48,4.381]],["t/185",[49,6.077,50,6.077]],["t/188",[51,5.18,52,5.18,53,5.18]],["t/234",[54,6.077,55,6.077]],["t/248",[56,7.351]],["t/252",[8,3.054,16,2.932,43,3.628,57,2.932,58,3.999]],["t/256",[59,6.667]],["t/260",[60,6.077,61,6.077]],["t/262",[62,7.351]],["t/264",[8,4.64,23,4.297]],["t/266",[63,5.881]],["t/273",[23,3.663,45,1.511,64,4.699]],["t/275",[7,2.583,37,1.997,45,1.167,65,3.383,66,2.828]],["t/289",[45,1.511,67,4.144,68,3.798]],["t/295",[6,2.4,68,2.932,69,3.999,70,3.999,71,3.999]],["t/309",[37,2.586,63,4.144,72,3.955]],["t/326",[26,3.663,73,4.144,74,4.144]],["t/340",[74,5.881]],["t/362",[0,4.143]],["t/364",[7,2.583,37,1.997,45,1.167,75,3.999,76,3.999]],["t/382",[8,4.64,37,3.034]],["t/394",[77,7.351]],["t/399",[78,5.881]],["t/401",[79,6.217]],["t/405",[80,6.077,81,4.64]],["t/416",[82,5.881]],["t/429",[78,5.881]],["t/435",[83,6.077,84,6.077]],["t/437",[45,1.773,81,4.64]],["t/443",[85,7.351]],["t/459",[86,6.217]],["t/461",[87,5.14,88,6.077]],["t/477",[89,4.747]],["t/488",[90,6.077,91,6.077]],["t/500",[92,6.077,93,6.077]],["t/502",[94,5.18,95,5.18,96,5.18]],["t/512",[0,4.143]],["t/514",[78,5.881]],["t/526",[97,6.077,98,5.14]],["t/581",[99,7.351]],["t/584",[22,2.185,37,1.488,45,0.869,79,2.521,100,2.98,101,2.276,102,1.75,103,2.185]],["t/597",[22,2.388,37,1.626,45,0.95,86,2.755,101,2.487,102,1.912,103,2.388]],["t/616",[104,4.881]],["t/626",[102,2.348,105,3,106,3.999,107,2.932]],["t/628",[108,5.881]],["t/630",[102,3.041,109,4.381,110,4.144]],["t/632",[26,3.663,89,3.346,111,3.955]],["t/636",[22,4.456,112,6.077]],["t/638",[113,7.351]],["t/647",[102,3.041,105,2.586,114,5.18]],["t/649",[115,5.14,116,6.077]],["t/653",[9,2.583,117,6.01,118,3.999,119,3.999]],["t/655",[82,4.144,120,3.346,121,5.18]],["t/661",[82,4.862,122,6.077]],["t/668",[7,4.747]],["t/670",[0,4.143]],["t/672",[104,4.036,123,5.512]],["t/674",[37,3.034,124,5.512]],["t/676",[104,4.036,125,6.077]],["t/678",[126,5.881]],["t/680",[127,6.667]],["t/682",[128,7.351]],["t/684",[0,4.143]],["t/686",[129,7.351]],["t/688",[130,5.18,131,5.18,132,5.18]],["t/723",[133,6.217]],["t/724",[105,3.034,134,3.824]],["t/735",[135,7.351]],["t/781",[105,3.034,136,4.159]],["t/806",[105,3.034,137,5.512]],["t/828",[10,5.14,105,3.034]],["t/843",[105,3.034,138,5.512]],["t/844",[105,2.586,136,3.545,139,4.699]],["t/851",[140,5.512,141,5.512]],["t/862",[37,3.034,142,6.077]],["t/875",[37,3.669]],["t/877",[143,6.217]],["t/879",[144,5.389]],["t/882",[22,4.456,102,3.568]],["t/887",[145,7.351]],["t/890",[146,6.667]],["t/892",[6,2.154,24,2.384,147,3.037,148,3.037,149,3.037,150,3.037]],["t/950",[151,6.667]],["t/952",[6,4.411]],["t/955",[152,6.667]],["t/958",[16,3.798,153,5.18,154,5.18]],["t/961",[155,7.351]],["t/963",[16,3.798,156,4.381,157,5.18]],["t/967",[158,7.351]],["t/969",[102,3.568,159,5.512]],["t/976",[160,6.077,161,6.077]],["t/979",[123,4.699,162,5.18,163,5.18]],["t/999",[73,4.862,102,3.568]],["t/1006",[37,3.034,89,3.925]],["t/1007",[164,7.351]],["t/1009",[165,4.64,166,6.077]],["t/1011",[57,5.389]],["t/1013",[167,7.351]],["t/1022",[168,7.351]],["t/1024",[12,5.197]],["t/1030",[169,7.351]],["t/1032",[170,7.351]],["t/1034",[171,6.077,172,6.077]],["t/1042",[72,5.612]],["t/1044",[173,7.351]],["t/1053",[174,7.351]],["t/1056",[89,3.925,175,6.077]],["t/1078",[105,3.669]],["t/1085",[176,7.351]],["t/1087",[177,5.612]],["t/1099",[144,5.389]],["t/1125",[178,7.351]],["t/1127",[179,6.667]],["t/1131",[159,6.667]],["t/1133",[180,7.351]],["t/1135",[181,7.351]],["t/1137",[182,7.351]],["t/1139",[152,6.667]],["t/1141",[183,7.351]],["t/1147",[184,5.881]],["t/1152",[185,7.351]],["t/1154",[6,4.411]],["t/1170",[186,6.667]],["t/1185",[187,6.667]],["t/1189",[188,7.351]],["t/1191",[189,6.667]],["t/1193",[190,7.351]],["t/1198",[191,7.351]],["t/1206",[12,5.197]],["t/1208",[192,7.351]],["t/1210",[193,7.351]],["t/1212",[57,3.798,194,5.18,195,5.18]],["t/1214",[196,6.667]],["t/1218",[37,3.034,81,4.64]],["t/1220",[197,7.351]],["t/1222",[198,6.667]],["t/1223",[199,7.351]],["t/1225",[200,6.667]],["t/1227",[9,3.925,201,5.512]],["t/1229",[202,6.667]],["t/1231",[107,3.309,203,4.514,204,4.514,205,4.514]],["t/1235",[206,7.351]],["t/1241",[207,5.881]],["t/1243",[12,5.197]],["t/1245",[208,4.747]],["t/1249",[16,3.798,24,3.44,209,4.381]],["t/1251",[105,3.669]],["t/1265",[37,3.034,210,6.077]],["t/1283",[177,5.612]],["t/1285",[144,5.389]],["t/1293",[6,4.411]],["t/1295",[207,5.881]],["t/1308",[105,3.669]],["t/1309",[211,7.351]],["t/1312",[209,6.217]],["t/1322",[]],["t/1330",[212,7.351]],["t/1340",[213,7.351]],["t/1345",[179,6.667]],["t/1352",[184,5.881]],["t/1354",[6,4.411]],["t/1363",[177,5.612]],["t/1369",[186,6.667]],["t/1384",[189,6.667]],["t/1389",[187,6.667]],["t/1392",[133,6.217]],["t/1393",[144,5.389]],["t/1478",[105,2.586,136,3.545,139,4.699]],["t/1485",[105,3.034,134,3.824]],["t/1496",[105,3.034,137,5.512]],["t/1518",[105,3.034,136,4.159]],["t/1543",[10,5.14,105,3.034]],["t/1558",[105,3.034,138,5.512]],["t/1559",[9,3.346,201,4.699,214,5.18]],["t/1592",[37,3.669]],["t/1593",[37,3.034,64,5.512]],["t/1595",[140,5.512,141,5.512]],["t/1606",[8,4.64,37,3.034]],["t/1614",[6,2.154,24,2.384,147,3.037,148,3.037,149,3.037,150,3.037]],["t/1672",[215,4.881]],["t/1689",[216,7.351]],["t/1691",[37,3.034,41,5.512]],["t/1722",[37,3.034,79,5.14]],["t/1724",[144,5.389]],["t/1729",[105,3.669]],["t/1732",[6,4.411]],["t/1735",[37,3.034,86,5.14]],["t/1737",[63,4.862,217,6.077]],["t/1759",[144,5.389]],["t/1761",[16,3.798,24,3.44,209,4.381]],["t/1763",[196,6.667]],["t/1767",[207,5.881]],["t/1769",[202,6.667]],["t/1819",[177,5.612]],["t/1821",[6,4.411]],["t/1823",[37,3.034,72,4.64]],["t/1824",[105,3.669]],["t/1826",[6,2.709,82,3.611,218,4.514,219,4.514]],["t/1852",[89,2.915,165,3.446,220,3.089,221,3.309]],["t/1866",[6,4.411]],["t/1867",[126,5.881]],["t/1869",[72,3.955,87,4.381,222,3.798]],["t/1914",[89,2.319,165,2.741,220,2.457,221,2.632,223,3.59,224,3.59]],["t/1928",[225,7.351]],["t/1930",[127,6.667]],["t/1932",[177,5.612]],["t/1934",[226,6.217]],["t/1936",[45,1.167,67,3.2,68,2.932,74,3.2,105,1.997]],["t/1954",[23,2.539,68,2.632,151,5.021,227,3.59,228,3.59]],["t/1958",[45,1.047,81,2.741,89,2.319,198,3.256,229,3.256,230,3.59]],["t/1960",[0,4.143]],["t/1962",[45,1.511,231,5.18,232,5.18]],["t/1968",[0,4.143]],["t/1985",[72,3.955,87,4.381,222,3.798]],["t/2030",[11,4.381,22,3.798,233,5.18]],["t/2034",[105,2.253,108,3.611,229,4.094,234,3.818]],["t/2070",[59,4.094,235,4.514,236,4.514,237,4.514]],["t/2072",[133,5.14,238,6.077]],["t/2086",[24,3.44,28,3.798,239,4.699]],["t/2099",[146,5.512,240,5.14]],["t/2109",[241,7.351]],["t/2111",[24,3.44,120,3.346,239,4.699]],["t/2119",[12,3.663,207,4.144,242,5.18]],["t/2121",[78,5.881]],["t/2131",[45,1.773,81,4.64]],["t/2139",[243,7.351]],["t/2145",[200,6.667]],["t/2153",[0,4.143]],["t/2155",[0,3.425,143,5.14]],["t/2157",[24,4.036,63,4.862]],["t/2159",[143,6.217]],["t/2161",[0,4.143]],["t/2173",[0,4.143]],["t/2175",[244,6.077,245,6.077]],["t/2177",[0,4.143]],["t/2179",[0,4.143]],["t/2181",[0,4.143]],["t/2183",[0,4.143]],["t/2185",[45,1.167,215,3.991,246,2.583,247,3.999]],["t/2203",[45,1.167,124,3.628,215,3.991,246,2.583]],["t/2240",[45,1.167,215,3.991,246,2.583,248,3.999]],["t/2273",[45,1.167,215,3.991,246,2.583,249,3.999]],["t/2307",[45,1.167,215,3.991,246,2.583,250,3.999]],["t/2339",[6,1.788,24,1.979,37,1.488,147,2.521,148,2.521,149,2.521,150,2.521,251,2.98]],["t/2397",[45,1.167,215,3.991,246,2.583,252,3.999]],["t/2435",[14,3.628,45,1.167,215,3.991,246,2.583]],["t/2453",[45,1.167,215,3.991,246,2.583,253,3.999]],["t/2511",[27,3.321]],["t/2513",[74,5.881]],["t/2515",[57,5.389]],["t/2521",[254,6.077,255,4.862]],["t/2523",[9,2.583,27,1.807,45,1.167,256,3.999,257,3.2]],["t/2525",[27,2.746,258,6.077]],["t/2527",[27,1.807,36,3.383,45,1.167,259,3.999,260,3.628]],["t/2529",[9,2.319,27,1.622,45,1.047,257,2.872,261,3.59,262,3.256]],["t/2531",[45,1.497,57,2.388,263,3.257,264,2.954,265,2.954,266,2.606]],["t/2533",[45,1.753,156,3.383,240,3.383,267,3.999]],["t/2535",[27,1.622,45,1.615,134,2.259,268,3.59,269,2.539]],["t/2539",[45,1.917,270,4.514,271,3.818]],["t/2543",[27,2.746,28,4.456]],["t/2545",[27,1.622,45,1.615,136,2.457,272,3.59,273,3.256]],["t/2547",[27,1.807,45,1.753,136,2.737,274,3.999]],["t/2549",[27,1.622,45,1.615,134,2.259,275,3.59,276,3.256]],["t/2551",[45,1.047,220,2.457,221,2.632,277,3.59,278,2.319,279,3.256]],["t/2553",[45,1.317,134,2.84,280,4.514,281,4.094]],["t/2555",[27,1.622,45,1.047,278,2.319,282,3.59,283,2.872,284,2.872]],["t/2557",[27,1.807,45,1.167,283,3.2,284,3.2,285,3.999]],["t/2559",[89,3.925,286,4.64]],["t/2571",[45,1.047,48,3.037,220,2.457,221,2.632,287,3.59,288,2.872]],["t/2573",[27,2.746,32,5.512]],["t/2575",[45,1.047,67,2.872,68,2.632,104,2.384,289,3.59,290,3.256]],["t/2577",[45,1.047,89,2.319,105,1.792,184,2.872,234,3.037,291,3.59]],["t/2579",[45,0.95,110,2.606,115,2.755,269,2.303,292,3.257,293,2.954,294,2.954]],["t/2581",[7,2.103,45,0.95,65,2.755,120,2.103,165,2.487,295,3.257,296,2.954]],["t/2583",[45,1.615,101,2.741,255,2.872,297,3.59,298,3.037]],["t/2585",[45,1.497,120,2.103,226,2.755,288,2.606,299,3.257,300,2.954]],["t/2587",[26,2.828,45,1.167,104,2.656,111,3.054,301,3.999]],["t/2589",[45,1.047,107,2.632,208,2.319,302,3.59,303,3.256,304,3.256]],["t/2591",[27,2.746,120,3.925]],["t/2593",[45,1.047,107,2.632,208,2.319,305,3.59,306,3.256,307,3.256]],["t/2595",[45,1.047,102,2.108,208,2.319,220,2.457,308,3.59,309,3.256]],["t/2597",[26,2.303,27,1.471,45,1.497,66,2.303,111,2.487,310,3.257]],["t/2599",[45,1.047,102,2.108,208,2.319,311,3.59,312,3.256,313,3.256]],["t/2601",[27,2.746,29,5.512]],["t/2603",[7,2.319,45,1.047,102,2.108,104,2.384,314,3.59,315,3.256]],["t/2605",[45,1.047,109,3.037,278,2.319,316,3.59,317,2.632,318,2.632]],["t/2607",[45,0.95,66,2.303,98,2.755,278,2.103,317,2.388,318,2.388,319,3.257]],["t/2609",[45,1.167,286,3.054,320,3.999,321,3.628,322,3.628]],["t/2611",[45,1.047,278,2.319,317,2.632,318,2.632,323,3.59,324,3.256]],["t/2613",[45,0.869,103,2.185,108,2.384,222,2.185,325,2.98,326,2.703,327,2.703,328,2.703]],["t/2615",[9,3.346,27,2.34,257,4.144]],["t/2650",[28,2.388,45,0.95,222,2.388,286,2.487,329,3.257,330,2.954,331,2.954]],["t/2652",[9,1.645,12,1.801,45,0.743,73,2.038,103,1.868,120,1.645,126,2.038,332,2.548,333,2.311,334,2.311]],["t/2654",[27,2.34,36,4.381,260,4.699]],["t/2661",[23,3.663,31,4.699,45,1.511]],["t/2682",[45,1.167,57,2.932,264,3.628,265,3.628,266,3.2]],["t/2693",[27,2.039,45,1.317,134,2.84,269,3.192]],["t/2738",[27,2.039,45,1.317,134,2.84,269,3.192]],["t/2777",[7,2.103,27,1.471,45,0.95,66,2.303,134,2.05,246,2.103,269,2.303]],["t/2793",[9,2.915,27,2.039,257,3.611,262,4.094]],["t/2828",[27,2.039,45,1.317,134,2.84,269,3.192]],["t/2865",[45,1.773,271,5.14]],["t/2884",[27,2.039,45,1.317,136,3.089,273,4.094]],["t/2904",[7,2.583,45,1.167,66,2.828,246,2.583,271,3.383]],["t/2918",[27,2.039,45,1.317,134,2.84,276,4.094]],["t/2940",[134,3.824,281,5.512]],["t/2958",[27,2.039,278,2.915,283,3.611,284,3.611]],["t/2973",[27,2.34,45,1.511,136,3.545]],["t/2997",[45,1.511,156,4.381,240,4.381]],["t/3019",[27,2.34,283,4.144,284,4.144]],["t/3051",[7,2.583,65,3.383,120,2.583,165,3.054,296,3.628]],["t/3072",[48,3.818,220,3.089,221,3.309,288,3.611]],["t/3095",[220,3.089,221,3.309,278,2.915,279,4.094]],["t/3122",[45,1.317,101,3.446,255,3.611,298,3.818]],["t/3133",[45,1.167,120,2.583,226,3.383,288,3.2,300,3.628]],["t/3148",[26,3.663,104,3.44,111,3.955]],["t/3165",[45,0.95,101,2.487,110,2.606,208,2.103,255,4.105,298,2.755]],["t/3176",[107,3.309,208,2.915,303,4.094,304,4.094]],["t/3189",[107,3.309,208,2.915,306,4.094,307,4.094]],["t/3202",[7,2.915,102,2.65,104,2.997,315,4.094]],["t/3225",[102,2.65,208,2.915,220,3.089,309,4.094]],["t/3243",[67,3.611,68,3.309,104,2.997,290,4.094]],["t/3260",[102,2.65,208,2.915,312,4.094,313,4.094]],["t/3291",[26,2.828,27,1.807,45,1.167,66,2.828,111,3.054]],["t/3306",[109,3.818,278,2.915,317,3.309,318,3.309]],["t/3317",[110,3.2,115,3.383,269,2.828,293,3.628,294,3.628]],["t/3334",[278,2.915,317,3.309,318,3.309,324,4.094]],["t/3368",[286,3.955,321,4.699,322,4.699]],["t/3387",[9,1.925,12,2.107,73,2.384,103,2.185,120,1.925,126,2.384,333,2.703,334,2.703]],["t/3401",[66,2.828,98,3.383,278,2.583,317,2.932,318,2.932]],["t/3411",[28,2.932,222,2.932,286,3.054,330,3.628,331,3.628]],["t/3428",[28,3.798,45,1.511,266,4.144]],["t/3430",[45,1.511,120,3.346,266,4.144]],["t/3432",[103,2.632,108,2.872,222,2.632,326,3.256,327,3.256,328,3.256]],["t/3451",[89,2.915,105,2.253,184,3.611,234,3.818]],["t/3485",[335,5.512,336,5.512]],["t/3498",[335,5.512,336,5.512]],["t/3517",[0,4.143]]],"invertedIndex":[["",{"_index":16,"t":{"41":{"position":[[36,1]]},"252":{"position":[[32,1]]},"958":{"position":[[11,1]]},"963":{"position":[[6,1]]},"1249":{"position":[[8,1]]},"1761":{"position":[[8,1]]}}}],["0",{"_index":247,"t":{"2185":{"position":[[30,1]]}}}],["0001",{"_index":256,"t":{"2523":{"position":[[4,5]]}}}],["0002",{"_index":259,"t":{"2527":{"position":[[4,5]]}}}],["0003",{"_index":261,"t":{"2529":{"position":[[4,5]]}}}],["0004",{"_index":263,"t":{"2531":{"position":[[4,5]]}}}],["0100",{"_index":268,"t":{"2535":{"position":[[4,5]]}}}],["0101",{"_index":270,"t":{"2539":{"position":[[4,5]]}}}],["0102",{"_index":272,"t":{"2545":{"position":[[4,5]]}}}],["0103",{"_index":275,"t":{"2549":{"position":[[4,5]]}}}],["0104",{"_index":274,"t":{"2547":{"position":[[4,5]]}}}],["0110",{"_index":280,"t":{"2553":{"position":[[4,5]]}}}],["0111",{"_index":282,"t":{"2555":{"position":[[4,5]]}}}],["0112",{"_index":267,"t":{"2533":{"position":[[4,5]]}}}],["0113",{"_index":277,"t":{"2551":{"position":[[4,5]]}}}],["0114",{"_index":285,"t":{"2557":{"position":[[4,5]]}}}],["0115",{"_index":287,"t":{"2571":{"position":[[4,5]]}}}],["0200",{"_index":295,"t":{"2581":{"position":[[4,5]]}}}],["0210",{"_index":297,"t":{"2583":{"position":[[4,5]]}}}],["0211",{"_index":299,"t":{"2585":{"position":[[4,5]]}}}],["0212",{"_index":301,"t":{"2587":{"position":[[4,5]]}}}],["0213",{"_index":302,"t":{"2589":{"position":[[4,5]]}}}],["0214",{"_index":305,"t":{"2593":{"position":[[4,5]]}}}],["0215",{"_index":311,"t":{"2599":{"position":[[4,5]]}}}],["0216",{"_index":314,"t":{"2603":{"position":[[4,5]]}}}],["0217",{"_index":308,"t":{"2595":{"position":[[4,5]]}}}],["0218",{"_index":310,"t":{"2597":{"position":[[4,5]]}}}],["0300",{"_index":289,"t":{"2575":{"position":[[4,5]]}}}],["0301",{"_index":292,"t":{"2579":{"position":[[4,5]]}}}],["0302",{"_index":291,"t":{"2577":{"position":[[4,5]]}}}],["0400",{"_index":316,"t":{"2605":{"position":[[4,5]]}}}],["0401",{"_index":319,"t":{"2607":{"position":[[4,5]]}}}],["0402",{"_index":323,"t":{"2611":{"position":[[4,5]]}}}],["0403",{"_index":332,"t":{"2652":{"position":[[4,5]]}}}],["0410",{"_index":320,"t":{"2609":{"position":[[4,5]]}}}],["0411",{"_index":325,"t":{"2613":{"position":[[4,5]]}}}],["0412",{"_index":329,"t":{"2650":{"position":[[4,5]]}}}],["1",{"_index":124,"t":{"674":{"position":[[6,1]]},"2203":{"position":[[30,1]]}}}],["12",{"_index":251,"t":{"2339":{"position":[[53,2]]}}}],["2",{"_index":248,"t":{"2240":{"position":[[30,1]]}}}],["3",{"_index":249,"t":{"2273":{"position":[[30,1]]}}}],["4",{"_index":250,"t":{"2307":{"position":[[30,1]]}}}],["5",{"_index":252,"t":{"2397":{"position":[[30,1]]}}}],["6",{"_index":253,"t":{"2453":{"position":[[30,1]]}}}],["_descript",{"_index":335,"t":{"3485":{"position":[[0,12]]},"3498":{"position":[[0,12]]}}}],["achiev",{"_index":265,"t":{"2531":{"position":[[26,9]]},"2682":{"position":[[16,9]]}}}],["ad",{"_index":35,"t":{"106":{"position":[[0,6]]}}}],["affin",{"_index":304,"t":{"2589":{"position":[[32,8]]},"3176":{"position":[[22,8]]}}}],["alertmanag",{"_index":235,"t":{"2070":{"position":[[0,12]]}}}],["ansibl",{"_index":40,"t":{"132":{"position":[[0,7]]}}}],["anti",{"_index":303,"t":{"2589":{"position":[[27,4]]},"3176":{"position":[[17,4]]}}}],["aodh",{"_index":176,"t":{"1085":{"position":[[0,4]]}}}],["api",{"_index":22,"t":{"70":{"position":[[12,3]]},"584":{"position":[[58,3]]},"597":{"position":[[16,3]]},"636":{"position":[[8,3]]},"882":{"position":[[8,3]]},"2030":{"position":[[8,3]]}}}],["appli",{"_index":211,"t":{"1309":{"position":[[0,5]]}}}],["applic",{"_index":92,"t":{"500":{"position":[[0,11]]}}}],["approach",{"_index":328,"t":{"2613":{"position":[[21,8]]},"3432":{"position":[[11,8]]}}}],["architectur",{"_index":126,"t":{"678":{"position":[[0,12]]},"1867":{"position":[[0,12]]},"2652":{"position":[[10,12]]},"3387":{"position":[[0,12]]}}}],["ask",{"_index":131,"t":{"688":{"position":[[11,5]]}}}],["autom",{"_index":231,"t":{"1962":{"position":[[4,9]]}}}],["avail",{"_index":307,"t":{"2593":{"position":[[43,12]]},"3189":{"position":[[33,12]]}}}],["az",{"_index":118,"t":{"653":{"position":[[6,2]]}}}],["backup",{"_index":87,"t":{"461":{"position":[[0,6]]},"1869":{"position":[[10,7]]},"1985":{"position":[[10,7]]}}}],["barbican",{"_index":178,"t":{"1125":{"position":[[0,8]]}}}],["bare",{"_index":204,"t":{"1231":{"position":[[16,4]]}}}],["base",{"_index":327,"t":{"2613":{"position":[[15,5]]},"3432":{"position":[[5,5]]}}}],["baselin",{"_index":309,"t":{"2595":{"position":[[29,8]]},"3225":{"position":[[19,8]]}}}],["best",{"_index":223,"t":{"1914":{"position":[[0,4]]}}}],["bill",{"_index":162,"t":{"979":{"position":[[9,4]]}}}],["blog",{"_index":2,"t":{"5":{"position":[[6,4]]}}}],["bootstrap",{"_index":199,"t":{"1223":{"position":[[0,9]]}}}],["box",{"_index":201,"t":{"1227":{"position":[[11,3]]},"1559":{"position":[[11,3]]}}}],["branch",{"_index":46,"t":{"183":{"position":[[0,6]]}}}],["ca",{"_index":116,"t":{"649":{"position":[[7,2]]}}}],["capi",{"_index":106,"t":{"626":{"position":[[26,4]]}}}],["case",{"_index":166,"t":{"1009":{"position":[[4,5]]}}}],["ceilomet",{"_index":180,"t":{"1133":{"position":[[0,10]]}}}],["central",{"_index":11,"t":{"33":{"position":[[0,7]]},"70":{"position":[[4,7]]},"2030":{"position":[[0,7]]}}}],["ceph",{"_index":144,"t":{"879":{"position":[[0,4]]},"1099":{"position":[[0,4]]},"1285":{"position":[[0,4]]},"1393":{"position":[[0,4]]},"1724":{"position":[[0,4]]},"1759":{"position":[[0,4]]}}}],["certif",{"_index":57,"t":{"252":{"position":[[10,11]]},"1011":{"position":[[0,12]]},"1212":{"position":[[12,12]]},"2515":{"position":[[0,13]]},"2531":{"position":[[51,13]]},"2682":{"position":[[41,13]]}}}],["chat",{"_index":237,"t":{"2070":{"position":[[37,4]]}}}],["checklist",{"_index":53,"t":{"188":{"position":[[19,9]]}}}],["chroni",{"_index":192,"t":{"1208":{"position":[[0,6]]}}}],["ci",{"_index":217,"t":{"1737":{"position":[[5,2]]}}}],["ciab",{"_index":214,"t":{"1559":{"position":[[17,4]]}}}],["cinder",{"_index":179,"t":{"1127":{"position":[[0,6]]},"1345":{"position":[[0,6]]}}}],["class",{"_index":300,"t":{"2585":{"position":[[35,5]]},"3133":{"position":[[25,5]]}}}],["cloud",{"_index":9,"t":{"15":{"position":[[21,5]]},"653":{"position":[[19,5]]},"1227":{"position":[[0,5]]},"1559":{"position":[[0,5]]},"2523":{"position":[[20,5]]},"2529":{"position":[[20,5]]},"2615":{"position":[[10,5]]},"2652":{"position":[[31,5]]},"2793":{"position":[[10,5]]},"3387":{"position":[[21,5]]}}}],["cluster",{"_index":102,"t":{"584":{"position":[[50,7]]},"597":{"position":[[8,7]]},"626":{"position":[[0,7]]},"630":{"position":[[13,7]]},"647":{"position":[[14,8]]},"882":{"position":[[0,7]]},"969":{"position":[[0,7]]},"999":{"position":[[12,7]]},"2595":{"position":[[21,7]]},"2599":{"position":[[45,8]]},"2603":{"position":[[35,7]]},"3202":{"position":[[25,7]]},"3225":{"position":[[11,7]]},"3260":{"position":[[35,8]]}}}],["clusterclass",{"_index":122,"t":{"661":{"position":[[13,12]]}}}],["collabor",{"_index":19,"t":{"56":{"position":[[0,13]]}}}],["common",{"_index":164,"t":{"1007":{"position":[[0,7]]}}}],["commun",{"_index":21,"t":{"68":{"position":[[4,9]]}}}],["compat",{"_index":266,"t":{"2531":{"position":[[40,10]]},"2682":{"position":[[30,10]]},"3428":{"position":[[4,10]]},"3430":{"position":[[4,10]]}}}],["compon",{"_index":143,"t":{"877":{"position":[[0,10]]},"2155":{"position":[[0,9]]},"2159":{"position":[[0,10]]}}}],["comput",{"_index":225,"t":{"1928":{"position":[[0,7]]}}}],["concept",{"_index":142,"t":{"862":{"position":[[0,7]]}}}],["config",{"_index":172,"t":{"1034":{"position":[[4,6]]}}}],["configur",{"_index":89,"t":{"477":{"position":[[0,13]]},"632":{"position":[[19,13]]},"1006":{"position":[[0,13]]},"1056":{"position":[[0,13]]},"1852":{"position":[[7,9]]},"1914":{"position":[[22,9]]},"1958":{"position":[[14,13]]},"2559":{"position":[[9,13]]},"2577":{"position":[[25,13]]},"3451":{"position":[[15,13]]}}}],["conform",{"_index":65,"t":{"275":{"position":[[4,11]]},"2581":{"position":[[34,11]]},"3051":{"position":[[24,11]]}}}],["connect",{"_index":71,"t":{"295":{"position":[[32,7]]}}}],["consensu",{"_index":245,"t":{"2175":{"position":[[11,10]]}}}],["consider",{"_index":44,"t":{"165":{"position":[[8,14]]}}}],["consol",{"_index":212,"t":{"1330":{"position":[[0,7]]}}}],["contain",{"_index":26,"t":{"76":{"position":[[5,9]]},"326":{"position":[[0,9]]},"632":{"position":[[0,9]]},"2587":{"position":[[27,9]]},"2597":{"position":[[10,9]]},"3148":{"position":[[17,9]]},"3291":{"position":[[0,9]]}}}],["container",{"_index":128,"t":{"682":{"position":[[0,16]]}}}],["continu",{"_index":90,"t":{"488":{"position":[[0,10]]}}}],["contributor",{"_index":64,"t":{"273":{"position":[[22,12]]},"1593":{"position":[[0,11]]}}}],["control",{"_index":77,"t":{"394":{"position":[[0,11]]}}}],["creat",{"_index":109,"t":{"630":{"position":[[0,6]]},"2605":{"position":[[22,6]]},"3306":{"position":[[12,6]]}}}],["credenti",{"_index":93,"t":{"500":{"position":[[12,11]]}}}],["custom",{"_index":115,"t":{"649":{"position":[[0,6]]},"2579":{"position":[[70,9]]},"3317":{"position":[[60,9]]}}}],["data",{"_index":222,"t":{"1869":{"position":[[5,4]]},"1985":{"position":[[5,4]]},"2613":{"position":[[50,4]]},"2650":{"position":[[38,4]]},"3411":{"position":[[28,4]]},"3432":{"position":[[40,4]]}}}],["databas",{"_index":322,"t":{"2609":{"position":[[21,8]]},"3368":{"position":[[11,8]]}}}],["debian",{"_index":150,"t":{"892":{"position":[[39,6]]},"1614":{"position":[[39,6]]},"2339":{"position":[[46,6]]}}}],["decis",{"_index":278,"t":{"2551":{"position":[[26,8]]},"2555":{"position":[[10,9]]},"2605":{"position":[[29,8]]},"2607":{"position":[[47,8]]},"2611":{"position":[[30,8]]},"2958":{"position":[[0,9]]},"3095":{"position":[[16,8]]},"3306":{"position":[[19,8]]},"3334":{"position":[[20,8]]},"3401":{"position":[[37,8]]}}}],["default",{"_index":288,"t":{"2571":{"position":[[10,7]]},"2585":{"position":[[19,7]]},"3072":{"position":[[0,7]]},"3133":{"position":[[9,7]]}}}],["demonstr",{"_index":15,"t":{"41":{"position":[[23,12]]}}}],["deploy",{"_index":81,"t":{"405":{"position":[[3,10]]},"437":{"position":[[4,10]]},"1218":{"position":[[0,6]]},"1958":{"position":[[35,10]]},"2131":{"position":[[4,10]]}}}],["descript",{"_index":238,"t":{"2072":{"position":[[6,11]]}}}],["design",{"_index":159,"t":{"969":{"position":[[8,6]]},"1131":{"position":[[0,9]]}}}],["develop",{"_index":8,"t":{"15":{"position":[[9,11]]},"252":{"position":[[0,9]]},"264":{"position":[[0,9]]},"382":{"position":[[0,9]]},"1606":{"position":[[0,9]]}}}],["distribut",{"_index":306,"t":{"2593":{"position":[[26,12]]},"3189":{"position":[[16,12]]}}}],["doc",{"_index":36,"t":{"106":{"position":[[7,4]]},"2527":{"position":[[21,4]]},"2654":{"position":[[11,4]]}}}],["docker",{"_index":196,"t":{"1214":{"position":[[0,6]]},"1763":{"position":[[0,6]]}}}],["document",{"_index":23,"t":{"72":{"position":[[4,13]]},"84":{"position":[[0,13]]},"102":{"position":[[0,13]]},"264":{"position":[[10,13]]},"273":{"position":[[0,13]]},"1954":{"position":[[13,13]]},"2661":{"position":[[4,13]]}}}],["domain",{"_index":234,"t":{"2034":{"position":[[0,6]]},"2577":{"position":[[10,6]]},"3451":{"position":[[0,6]]}}}],["domains/groups/roles/project",{"_index":293,"t":{"2579":{"position":[[21,28]]},"3317":{"position":[[11,28]]}}}],["endpoint",{"_index":242,"t":{"2119":{"position":[[23,9]]}}}],["entropi",{"_index":271,"t":{"2539":{"position":[[14,7]]},"2865":{"position":[[4,7]]},"2904":{"position":[[4,8]]}}}],["environ",{"_index":119,"t":{"653":{"position":[[25,12]]}}}],["esxi",{"_index":219,"t":{"1826":{"position":[[20,4]]}}}],["exampl",{"_index":198,"t":{"1222":{"position":[[0,8]]},"1958":{"position":[[0,7]]}}}],["experiment",{"_index":239,"t":{"2086":{"position":[[16,14]]},"2111":{"position":[[16,14]]}}}],["explain",{"_index":230,"t":{"1958":{"position":[[46,9]]}}}],["explan",{"_index":34,"t":{"102":{"position":[[23,11]]}}}],["exposit",{"_index":330,"t":{"2650":{"position":[[10,10]]},"3411":{"position":[[0,10]]}}}],["externaltrafficpolici",{"_index":95,"t":{"502":{"position":[[13,22]]}}}],["featur",{"_index":313,"t":{"2599":{"position":[[21,8]]},"3260":{"position":[[11,8]]}}}],["feder",{"_index":68,"t":{"289":{"position":[[9,10]]},"295":{"position":[[10,10]]},"1936":{"position":[[40,10]]},"1954":{"position":[[52,10]]},"2575":{"position":[[40,10]]},"3243":{"position":[[30,10]]}}}],["file",{"_index":30,"t":{"84":{"position":[[14,5]]}}}],["first",{"_index":1,"t":{"5":{"position":[[0,5]]}}}],["flavor",{"_index":134,"t":{"724":{"position":[[0,6]]},"1485":{"position":[[0,6]]},"2535":{"position":[[14,6]]},"2549":{"position":[[23,7]]},"2553":{"position":[[14,7]]},"2693":{"position":[[4,6]]},"2738":{"position":[[4,6]]},"2777":{"position":[[4,6]]},"2828":{"position":[[4,6]]},"2918":{"position":[[13,7]]},"2940":{"position":[[4,7]]}}}],["frequent",{"_index":130,"t":{"688":{"position":[[0,10]]}}}],["gaia",{"_index":13,"t":{"41":{"position":[[16,4]]}}}],["garden",{"_index":145,"t":{"887":{"position":[[0,8]]}}}],["gateway",{"_index":112,"t":{"636":{"position":[[0,7]]}}}],["get",{"_index":4,"t":{"7":{"position":[[0,7]]},"41":{"position":[[0,7]]},"49":{"position":[[0,7]]}}}],["glanc",{"_index":181,"t":{"1135":{"position":[[0,6]]}}}],["global",{"_index":258,"t":{"2525":{"position":[[0,6]]}}}],["glossari",{"_index":135,"t":{"735":{"position":[[0,8]]}}}],["gnocchi",{"_index":321,"t":{"2609":{"position":[[10,7]]},"3368":{"position":[[0,7]]}}}],["grafana",{"_index":154,"t":{"958":{"position":[[13,7]]}}}],["group",{"_index":221,"t":{"1852":{"position":[[34,6]]},"1914":{"position":[[49,6]]},"2551":{"position":[[19,6]]},"2571":{"position":[[37,6]]},"3072":{"position":[[27,6]]},"3095":{"position":[[9,6]]}}}],["guid",{"_index":37,"t":{"106":{"position":[[12,5]]},"119":{"position":[[8,5]]},"132":{"position":[[14,5]]},"275":{"position":[[36,5]]},"309":{"position":[[11,5]]},"364":{"position":[[25,5]]},"382":{"position":[[10,5]]},"584":{"position":[[32,5]]},"597":{"position":[[37,5]]},"674":{"position":[[0,5]]},"862":{"position":[[8,5]]},"875":{"position":[[0,6]]},"1006":{"position":[[14,5]]},"1218":{"position":[[7,5]]},"1265":{"position":[[11,5]]},"1592":{"position":[[6,6]]},"1593":{"position":[[12,5]]},"1606":{"position":[[10,5]]},"1691":{"position":[[6,5]]},"1722":{"position":[[16,5]]},"1735":{"position":[[8,5]]},"1823":{"position":[[5,5]]},"2339":{"position":[[0,6]]}}}],["ha",{"_index":80,"t":{"405":{"position":[[0,2]]}}}],["hackathon",{"_index":51,"t":{"188":{"position":[[0,9]]}}}],["harbor",{"_index":113,"t":{"638":{"position":[[0,6]]}}}],["hardwar",{"_index":123,"t":{"672":{"position":[[0,8]]},"979":{"position":[[0,8]]}}}],["health",{"_index":149,"t":{"892":{"position":[[21,6]]},"1614":{"position":[[21,6]]},"2339":{"position":[[28,6]]}}}],["heat",{"_index":182,"t":{"1137":{"position":[[0,4]]}}}],["horizon",{"_index":183,"t":{"1141":{"position":[[0,7]]}}}],["iaa",{"_index":28,"t":{"80":{"position":[[5,4]]},"2086":{"position":[[0,4]]},"2543":{"position":[[0,4]]},"2650":{"position":[[24,4]]},"3411":{"position":[[14,4]]},"3428":{"position":[[15,4]]}}}],["iam",{"_index":32,"t":{"100":{"position":[[5,3]]},"2573":{"position":[[0,3]]}}}],["ident",{"_index":67,"t":{"289":{"position":[[0,8]]},"1936":{"position":[[16,8]]},"2575":{"position":[[31,8]]},"3243":{"position":[[21,8]]}}}],["imag",{"_index":136,"t":{"781":{"position":[[0,5]]},"844":{"position":[[0,5]]},"1478":{"position":[[0,5]]},"1518":{"position":[[0,5]]},"2545":{"position":[[14,5]]},"2547":{"position":[[23,6]]},"2884":{"position":[[4,5]]},"2973":{"position":[[13,6]]}}}],["implement",{"_index":66,"t":{"275":{"position":[[21,14]]},"2597":{"position":[[46,14]]},"2607":{"position":[[32,14]]},"2777":{"position":[[28,14]]},"2904":{"position":[[13,14]]},"3291":{"position":[[36,14]]},"3401":{"position":[[22,14]]}}}],["infrastructur",{"_index":207,"t":{"1241":{"position":[[0,14]]},"1295":{"position":[[0,14]]},"1767":{"position":[[0,14]]},"2119":{"position":[[0,14]]}}}],["ingress",{"_index":94,"t":{"502":{"position":[[0,7]]}}}],["instal",{"_index":42,"t":{"152":{"position":[[0,12]]}}}],["integr",{"_index":91,"t":{"488":{"position":[[11,11]]}}}],["introduct",{"_index":74,"t":{"326":{"position":[[16,12]]},"340":{"position":[[0,12]]},"1936":{"position":[[0,12]]},"2513":{"position":[[0,12]]}}}],["inventori",{"_index":173,"t":{"1044":{"position":[[0,9]]}}}],["iron",{"_index":152,"t":{"955":{"position":[[0,6]]},"1139":{"position":[[0,6]]}}}],["jitsi",{"_index":56,"t":{"248":{"position":[[0,5]]}}}],["json",{"_index":331,"t":{"2650":{"position":[[46,4]]},"3411":{"position":[[36,4]]}}}],["k3",{"_index":146,"t":{"890":{"position":[[0,3]]},"2099":{"position":[[0,3]]}}}],["k8",{"_index":101,"t":{"584":{"position":[[46,3]]},"597":{"position":[[4,3]]},"2583":{"position":[[14,3]]},"3122":{"position":[[4,3]]},"3165":{"position":[[4,3]]}}}],["kaa",{"_index":120,"t":{"655":{"position":[[13,4]]},"2111":{"position":[[0,4]]},"2581":{"position":[[29,4]]},"2585":{"position":[[14,4]]},"2591":{"position":[[0,4]]},"2652":{"position":[[83,4]]},"3051":{"position":[[19,4]]},"3133":{"position":[[4,4]]},"3387":{"position":[[73,4]]},"3430":{"position":[[15,4]]}}}],["keycloak",{"_index":151,"t":{"950":{"position":[[0,8]]},"1954":{"position":[[31,8],[43,8]]}}}],["keyston",{"_index":184,"t":{"1147":{"position":[[0,8]]},"1352":{"position":[[0,8]]},"2577":{"position":[[43,8]]},"3451":{"position":[[33,8]]}}}],["keyword",{"_index":76,"t":{"364":{"position":[[12,7]]}}}],["knowledg",{"_index":127,"t":{"680":{"position":[[0,9]]},"1930":{"position":[[0,9]]}}}],["kubernet",{"_index":208,"t":{"1245":{"position":[[0,10]]},"2589":{"position":[[10,10]]},"2593":{"position":[[10,10]]},"2595":{"position":[[10,10]]},"2599":{"position":[[34,10]]},"3165":{"position":[[31,10]]},"3176":{"position":[[0,10]]},"3189":{"position":[[0,10]]},"3225":{"position":[[0,10]]},"3260":{"position":[[24,10]]}}}],["layer",{"_index":73,"t":{"326":{"position":[[10,5]]},"999":{"position":[[0,6]]},"2652":{"position":[[88,5]]},"3387":{"position":[[78,5]]}}}],["level",{"_index":244,"t":{"2175":{"position":[[0,7]]}}}],["licens",{"_index":43,"t":{"165":{"position":[[0,7]]},"252":{"position":[[34,8]]}}}],["limit",{"_index":84,"t":{"435":{"position":[[5,5]]}}}],["lint",{"_index":38,"t":{"119":{"position":[[0,7]]}}}],["list",{"_index":61,"t":{"260":{"position":[[8,5]]}}}],["loadbalanc",{"_index":174,"t":{"1053":{"position":[[0,12]]}}}],["local",{"_index":96,"t":{"502":{"position":[[36,5]]}}}],["log",{"_index":209,"t":{"1249":{"position":[[0,7]]},"1312":{"position":[[0,7]]},"1761":{"position":[[0,7]]}}}],["magnum",{"_index":188,"t":{"1189":{"position":[[0,6]]}}}],["mail",{"_index":60,"t":{"260":{"position":[[0,7]]}}}],["mainten",{"_index":100,"t":{"584":{"position":[[0,11]]}}}],["makefil",{"_index":97,"t":{"526":{"position":[[0,8]]}}}],["manag",{"_index":105,"t":{"626":{"position":[[8,10],[31,10]]},"647":{"position":[[0,8]]},"724":{"position":[[7,7]]},"781":{"position":[[6,7]]},"806":{"position":[[8,7]]},"828":{"position":[[9,7]]},"843":{"position":[[8,7]]},"844":{"position":[[6,7]]},"1078":{"position":[[0,7]]},"1251":{"position":[[0,7]]},"1308":{"position":[[0,7]]},"1478":{"position":[[6,7]]},"1485":{"position":[[7,7]]},"1496":{"position":[[8,7]]},"1518":{"position":[[6,7]]},"1543":{"position":[[9,7]]},"1558":{"position":[[8,7]]},"1729":{"position":[[0,7]]},"1824":{"position":[[0,7]]},"1936":{"position":[[25,10]]},"2034":{"position":[[7,7]]},"2577":{"position":[[17,7]]},"3451":{"position":[[7,7]]}}}],["mani",{"_index":114,"t":{"647":{"position":[[9,4]]}}}],["manila",{"_index":185,"t":{"1152":{"position":[[0,6]]}}}],["materi",{"_index":163,"t":{"979":{"position":[[17,9]]}}}],["matrix",{"_index":59,"t":{"256":{"position":[[0,6]]},"2070":{"position":[[30,6]]}}}],["metadata",{"_index":273,"t":{"2545":{"position":[[20,8]]},"2884":{"position":[[10,8]]}}}],["metal",{"_index":205,"t":{"1231":{"position":[[21,5]]}}}],["meter",{"_index":286,"t":{"2559":{"position":[[0,8]]},"2609":{"position":[[34,8]]},"2650":{"position":[[29,8]]},"3368":{"position":[[24,8]]},"3411":{"position":[[19,8]]}}}],["migrat",{"_index":82,"t":{"416":{"position":[[0,9]]},"655":{"position":[[0,9]]},"661":{"position":[[0,9]]},"1826":{"position":[[0,7]]}}}],["mission",{"_index":54,"t":{"234":{"position":[[0,7]]}}}],["monitor",{"_index":24,"t":{"74":{"position":[[4,10]]},"892":{"position":[[28,7]]},"1249":{"position":[[10,10]]},"1614":{"position":[[28,7]]},"1761":{"position":[[10,10]]},"2086":{"position":[[5,10]]},"2111":{"position":[[5,10]]},"2157":{"position":[[5,10]]},"2339":{"position":[[35,7]]}}}],["multi",{"_index":117,"t":{"653":{"position":[[0,5],[13,5]]}}}],["mvp",{"_index":233,"t":{"2030":{"position":[[12,3]]}}}],["name",{"_index":269,"t":{"2535":{"position":[[21,6]]},"2579":{"position":[[10,6]]},"2693":{"position":[[11,6]]},"2738":{"position":[[11,6]]},"2777":{"position":[[11,6]]},"2828":{"position":[[11,6]]},"3317":{"position":[[0,6]]}}}],["netdata",{"_index":155,"t":{"961":{"position":[[0,7]]}}}],["network",{"_index":177,"t":{"1087":{"position":[[0,7]]},"1283":{"position":[[0,7]]},"1363":{"position":[[0,7]]},"1819":{"position":[[0,7]]},"1932":{"position":[[0,7]]}}}],["neutron",{"_index":187,"t":{"1185":{"position":[[0,7]]},"1389":{"position":[[0,7]]}}}],["new",{"_index":110,"t":{"630":{"position":[[9,3]]},"2579":{"position":[[66,3]]},"3165":{"position":[[27,3]]},"3317":{"position":[[56,3]]}}}],["nextcloud",{"_index":62,"t":{"262":{"position":[[0,9]]}}}],["node",{"_index":107,"t":{"626":{"position":[[42,4]]},"1231":{"position":[[27,5]]},"2589":{"position":[[21,5]]},"2593":{"position":[[21,4]]},"3176":{"position":[[11,5]]},"3189":{"position":[[11,4]]}}}],["note",{"_index":246,"t":{"2185":{"position":[[8,5]]},"2203":{"position":[[8,5]]},"2240":{"position":[[8,5]]},"2273":{"position":[[8,5]]},"2307":{"position":[[8,5]]},"2397":{"position":[[8,5]]},"2435":{"position":[[8,5]]},"2453":{"position":[[8,5]]},"2777":{"position":[[55,5]]},"2904":{"position":[[40,5]]}}}],["notif",{"_index":236,"t":{"2070":{"position":[[13,13]]}}}],["nova",{"_index":186,"t":{"1170":{"position":[[0,4]]},"1369":{"position":[[0,4]]}}}],["oauth",{"_index":241,"t":{"2109":{"position":[[0,5]]}}}],["observ",{"_index":333,"t":{"2652":{"position":[[54,13]]},"3387":{"position":[[44,13]]}}}],["octavia",{"_index":189,"t":{"1191":{"position":[[0,7]]},"1384":{"position":[[0,7]]}}}],["onboard",{"_index":294,"t":{"2579":{"position":[[55,10]]},"3317":{"position":[[45,10]]}}}],["op",{"_index":29,"t":{"82":{"position":[[5,3]]},"2601":{"position":[[0,3]]}}}],["openapi",{"_index":324,"t":{"2611":{"position":[[22,7]]},"3334":{"position":[[12,7]]}}}],["openid",{"_index":70,"t":{"295":{"position":[[25,6]]}}}],["openstack",{"_index":6,"t":{"7":{"position":[[21,9]]},"295":{"position":[[0,9]]},"892":{"position":[[11,9]]},"952":{"position":[[0,9]]},"1154":{"position":[[0,9]]},"1293":{"position":[[0,9]]},"1354":{"position":[[0,9]]},"1614":{"position":[[11,9]]},"1732":{"position":[[0,9]]},"1821":{"position":[[0,9]]},"1826":{"position":[[28,9]]},"1866":{"position":[[0,9]]},"2339":{"position":[[18,9]]}}}],["oper",{"_index":210,"t":{"1265":{"position":[[0,10]]}}}],["organis",{"_index":260,"t":{"2527":{"position":[[30,12]]},"2654":{"position":[[20,12]]}}}],["origin",{"_index":58,"t":{"252":{"position":[[25,6]]}}}],["overview",{"_index":0,"t":{"2":{"position":[[0,8]]},"362":{"position":[[0,8]]},"512":{"position":[[0,8]]},"670":{"position":[[0,8]]},"684":{"position":[[0,8]]},"1960":{"position":[[0,8]]},"1968":{"position":[[0,8]]},"2153":{"position":[[0,8]]},"2155":{"position":[[10,8]]},"2161":{"position":[[0,8]]},"2173":{"position":[[0,8]]},"2177":{"position":[[0,8]]},"2179":{"position":[[0,8]]},"2181":{"position":[[0,8]]},"2183":{"position":[[0,8]]},"3517":{"position":[[0,8]]}}}],["ovn",{"_index":157,"t":{"963":{"position":[[8,3]]}}}],["packag",{"_index":167,"t":{"1013":{"position":[[0,8]]}}}],["page",{"_index":318,"t":{"2605":{"position":[[17,4]]},"2607":{"position":[[17,4]]},"2611":{"position":[[17,4]]},"3306":{"position":[[7,4]]},"3334":{"position":[[7,4]]},"3401":{"position":[[7,4]]}}}],["pentest",{"_index":232,"t":{"1962":{"position":[[14,10]]}}}],["persist",{"_index":85,"t":{"443":{"position":[[0,11]]}}}],["placement",{"_index":193,"t":{"1210":{"position":[[0,9]]}}}],["plan",{"_index":52,"t":{"188":{"position":[[10,8]]}}}],["plusserv",{"_index":17,"t":{"41":{"position":[[38,10]]}}}],["polici",{"_index":298,"t":{"2583":{"position":[[26,6]]},"3122":{"position":[[16,6]]},"3165":{"position":[[16,6]]}}}],["post",{"_index":3,"t":{"5":{"position":[[11,4]]}}}],["practis",{"_index":224,"t":{"1914":{"position":[[5,9]]}}}],["project",{"_index":137,"t":{"806":{"position":[[0,7]]},"1496":{"position":[[0,7]]}}}],["prometheu",{"_index":153,"t":{"958":{"position":[[0,10]]}}}],["properti",{"_index":276,"t":{"2549":{"position":[[35,10]]},"2918":{"position":[[25,10]]}}}],["propos",{"_index":227,"t":{"1954":{"position":[[0,8]]}}}],["protect",{"_index":47,"t":{"183":{"position":[[7,10]]}}}],["provid",{"_index":103,"t":{"584":{"position":[[62,8]]},"597":{"position":[[20,8]]},"2613":{"position":[[34,9]]},"2652":{"position":[[45,8]]},"3387":{"position":[[35,8]]},"3432":{"position":[[24,9]]}}}],["provis",{"_index":203,"t":{"1231":{"position":[[0,12]]}}}],["proxi",{"_index":191,"t":{"1198":{"position":[[0,5]]}}}],["proxmox",{"_index":160,"t":{"976":{"position":[[0,7]]}}}],["push",{"_index":326,"t":{"2613":{"position":[[10,4]]},"3432":{"position":[[0,4]]}}}],["question",{"_index":132,"t":{"688":{"position":[[17,9]]}}}],["quickstart",{"_index":78,"t":{"399":{"position":[[0,10]]},"429":{"position":[[0,10]]},"514":{"position":[[0,10]]},"2121":{"position":[[0,10]]}}}],["rate",{"_index":83,"t":{"435":{"position":[[0,4]]}}}],["record",{"_index":279,"t":{"2551":{"position":[[35,6]]},"3095":{"position":[[25,6]]}}}],["refer",{"_index":98,"t":{"526":{"position":[[9,9]]},"2607":{"position":[[22,9]]},"3401":{"position":[[12,9]]}}}],["registri",{"_index":111,"t":{"632":{"position":[[10,8]]},"2587":{"position":[[37,10]]},"2597":{"position":[[20,8]]},"3148":{"position":[[27,10]]},"3291":{"position":[[10,8]]}}}],["regul",{"_index":264,"t":{"2531":{"position":[[10,11]]},"2682":{"position":[[0,11]]}}}],["releas",{"_index":215,"t":{"1672":{"position":[[0,8]]},"2185":{"position":[[0,7],[22,7]]},"2203":{"position":[[0,7],[22,7]]},"2240":{"position":[[0,7],[22,7]]},"2273":{"position":[[0,7],[22,7]]},"2307":{"position":[[0,7],[22,7]]},"2397":{"position":[[0,7],[22,7]]},"2435":{"position":[[0,7],[22,7]]},"2453":{"position":[[0,7],[22,7]]}}}],["repositori",{"_index":175,"t":{"1056":{"position":[[14,10]]}}}],["requir",{"_index":104,"t":{"616":{"position":[[0,12]]},"672":{"position":[[9,12]]},"676":{"position":[[9,12]]},"2575":{"position":[[10,12]]},"2587":{"position":[[10,12]]},"2603":{"position":[[10,12]]},"3148":{"position":[[0,12]]},"3202":{"position":[[0,12]]},"3243":{"position":[[0,12]]}}}],["resolvconf",{"_index":168,"t":{"1022":{"position":[[0,10]]}}}],["resourc",{"_index":10,"t":{"15":{"position":[[27,9]]},"828":{"position":[[0,8]]},"1543":{"position":[[0,8]]}}}],["restor",{"_index":88,"t":{"461":{"position":[[11,7]]}}}],["rfc2119",{"_index":75,"t":{"364":{"position":[[4,7]]}}}],["roadmap",{"_index":99,"t":{"581":{"position":[[0,7]]}}}],["robust",{"_index":312,"t":{"2599":{"position":[[10,10]]},"3260":{"position":[[0,10]]}}}],["rule",{"_index":48,"t":{"183":{"position":[[18,5]]},"2571":{"position":[[18,5]]},"3072":{"position":[[8,5]]}}}],["sandbox",{"_index":138,"t":{"843":{"position":[[0,7]]},"1558":{"position":[[0,7]]}}}],["sc",{"_index":45,"t":{"165":{"position":[[27,3]]},"273":{"position":[[18,3]]},"275":{"position":[[0,3]]},"289":{"position":[[23,3]]},"364":{"position":[[0,3]]},"437":{"position":[[0,3]]},"584":{"position":[[42,3]]},"597":{"position":[[0,3]]},"1936":{"position":[[54,3]]},"1958":{"position":[[31,3]]},"1962":{"position":[[0,3]]},"2131":{"position":[[0,3]]},"2185":{"position":[[18,3]]},"2203":{"position":[[18,3]]},"2240":{"position":[[18,3]]},"2273":{"position":[[18,3]]},"2307":{"position":[[18,3]]},"2397":{"position":[[18,3]]},"2435":{"position":[[18,3]]},"2453":{"position":[[18,3]]},"2523":{"position":[[0,3]]},"2527":{"position":[[0,3]]},"2529":{"position":[[0,3]]},"2531":{"position":[[0,3],[36,3]]},"2533":{"position":[[0,3],[27,3]]},"2535":{"position":[[0,3],[10,3]]},"2539":{"position":[[0,3],[10,3]]},"2545":{"position":[[0,3],[10,3]]},"2547":{"position":[[0,3],[10,3]]},"2549":{"position":[[0,3],[10,3]]},"2551":{"position":[[0,3]]},"2553":{"position":[[0,3]]},"2555":{"position":[[0,3]]},"2557":{"position":[[0,3]]},"2571":{"position":[[0,3]]},"2575":{"position":[[0,3]]},"2577":{"position":[[0,3]]},"2579":{"position":[[0,3]]},"2581":{"position":[[0,3]]},"2583":{"position":[[0,3],[10,3]]},"2585":{"position":[[0,3],[10,3]]},"2587":{"position":[[0,3]]},"2589":{"position":[[0,3]]},"2593":{"position":[[0,3]]},"2595":{"position":[[0,3]]},"2597":{"position":[[0,3],[33,3]]},"2599":{"position":[[0,3]]},"2603":{"position":[[0,3]]},"2605":{"position":[[0,3]]},"2607":{"position":[[0,3]]},"2609":{"position":[[0,3]]},"2611":{"position":[[0,3]]},"2613":{"position":[[0,3]]},"2650":{"position":[[0,3]]},"2652":{"position":[[0,3]]},"2661":{"position":[[0,3]]},"2682":{"position":[[26,3]]},"2693":{"position":[[0,3]]},"2738":{"position":[[0,3]]},"2777":{"position":[[0,3]]},"2828":{"position":[[0,3]]},"2865":{"position":[[0,3]]},"2884":{"position":[[0,3]]},"2904":{"position":[[0,3]]},"2918":{"position":[[0,3]]},"2973":{"position":[[0,3]]},"2997":{"position":[[17,3]]},"3122":{"position":[[0,3]]},"3133":{"position":[[0,3]]},"3165":{"position":[[0,3]]},"3291":{"position":[[23,3]]},"3428":{"position":[[0,3]]},"3430":{"position":[[0,3]]}}}],["scope",{"_index":254,"t":{"2521":{"position":[[0,6]]}}}],["script",{"_index":216,"t":{"1689":{"position":[[0,7]]}}}],["secur",{"_index":220,"t":{"1852":{"position":[[25,8]]},"1914":{"position":[[40,8]]},"2551":{"position":[[10,8]]},"2571":{"position":[[28,8]]},"2595":{"position":[[38,8]]},"3072":{"position":[[18,8]]},"3095":{"position":[[0,8]]},"3225":{"position":[[28,8]]}}}],["seed",{"_index":206,"t":{"1235":{"position":[[0,4]]}}}],["self",{"_index":194,"t":{"1212":{"position":[[0,4]]}}}],["servic",{"_index":12,"t":{"33":{"position":[[8,8]]},"1024":{"position":[[0,8]]},"1206":{"position":[[0,8]]},"1243":{"position":[[0,8]]},"2119":{"position":[[15,7]]},"2652":{"position":[[37,7]]},"3387":{"position":[[27,7]]}}}],["set",{"_index":147,"t":{"892":{"position":[[0,7]]},"1614":{"position":[[0,7]]},"2339":{"position":[[7,7]]}}}],["setup",{"_index":229,"t":{"1958":{"position":[[8,5]]},"2034":{"position":[[15,5]]}}}],["sig",{"_index":20,"t":{"68":{"position":[[0,3]]},"70":{"position":[[0,3]]},"72":{"position":[[0,3]]},"74":{"position":[[0,3]]},"78":{"position":[[0,3]]}}}],["sign",{"_index":195,"t":{"1212":{"position":[[5,6]]}}}],["simpl",{"_index":140,"t":{"851":{"position":[[0,6]]},"1595":{"position":[[0,6]]}}}],["skylin",{"_index":190,"t":{"1193":{"position":[[0,7]]}}}],["softwar",{"_index":125,"t":{"676":{"position":[[0,8]]}}}],["sonic",{"_index":156,"t":{"963":{"position":[[0,5]]},"2533":{"position":[[10,5]]},"2997":{"position":[[0,5]]}}}],["sonobuoy",{"_index":296,"t":{"2581":{"position":[[16,8]]},"3051":{"position":[[6,8]]}}}],["sovereign",{"_index":257,"t":{"2523":{"position":[[10,9]]},"2529":{"position":[[10,9]]},"2615":{"position":[[0,9]]},"2793":{"position":[[0,9]]}}}],["ssd",{"_index":281,"t":{"2553":{"position":[[10,3]]},"2940":{"position":[[0,3]]}}}],["ssh",{"_index":171,"t":{"1034":{"position":[[0,3]]}}}],["sso",{"_index":290,"t":{"2575":{"position":[[27,3]]},"3243":{"position":[[17,3]]}}}],["stack",{"_index":315,"t":{"2603":{"position":[[43,6]]},"3202":{"position":[[33,6]]}}}],["standard",{"_index":27,"t":{"78":{"position":[[4,15]]},"2511":{"position":[[0,9]]},"2523":{"position":[[26,9]]},"2525":{"position":[[7,9]]},"2527":{"position":[[10,10]]},"2529":{"position":[[26,9]]},"2535":{"position":[[28,8]]},"2543":{"position":[[5,9]]},"2545":{"position":[[29,8]]},"2547":{"position":[[14,8]]},"2549":{"position":[[14,8]]},"2555":{"position":[[40,8]]},"2557":{"position":[[22,8]]},"2573":{"position":[[4,9]]},"2591":{"position":[[5,9]]},"2597":{"position":[[37,8]]},"2601":{"position":[[4,9]]},"2615":{"position":[[16,9]]},"2654":{"position":[[0,10]]},"2693":{"position":[[18,8]]},"2738":{"position":[[18,8]]},"2777":{"position":[[18,9]]},"2793":{"position":[[16,9]]},"2828":{"position":[[18,8]]},"2884":{"position":[[19,8]]},"2918":{"position":[[4,8]]},"2958":{"position":[[30,8]]},"2973":{"position":[[4,8]]},"3019":{"position":[[12,8]]},"3291":{"position":[[27,8]]}}}],["start",{"_index":5,"t":{"7":{"position":[[8,7]]},"41":{"position":[[8,7]]},"49":{"position":[[8,7]]}}}],["statement",{"_index":55,"t":{"234":{"position":[[8,9]]}}}],["statu",{"_index":317,"t":{"2605":{"position":[[10,6]]},"2607":{"position":[[10,6]]},"2611":{"position":[[10,6]]},"3306":{"position":[[0,6]]},"3334":{"position":[[0,6]]},"3401":{"position":[[0,6]]}}}],["storag",{"_index":226,"t":{"1934":{"position":[[0,7]]},"2585":{"position":[[27,7]]},"3133":{"position":[[17,7]]}}}],["stress",{"_index":141,"t":{"851":{"position":[[7,6]]},"1595":{"position":[[7,6]]}}}],["structur",{"_index":31,"t":{"84":{"position":[[20,9]]},"2661":{"position":[[18,9]]}}}],["style",{"_index":41,"t":{"132":{"position":[[8,5]]},"1691":{"position":[[0,5]]}}}],["styleguid",{"_index":39,"t":{"125":{"position":[[0,10]]}}}],["support",{"_index":240,"t":{"2099":{"position":[[4,7]]},"2533":{"position":[[16,7]]},"2997":{"position":[[6,7]]}}}],["sysctl",{"_index":169,"t":{"1030":{"position":[[0,6]]}}}],["system",{"_index":334,"t":{"2652":{"position":[[68,6]]},"3387":{"position":[[58,6]]}}}],["task",{"_index":213,"t":{"1340":{"position":[[0,4]]}}}],["team",{"_index":25,"t":{"76":{"position":[[0,4]]},"80":{"position":[[0,4]]},"82":{"position":[[0,4]]},"100":{"position":[[0,4]]}}}],["teleport",{"_index":158,"t":{"967":{"position":[[0,8]]}}}],["test",{"_index":7,"t":{"15":{"position":[[0,4]]},"275":{"position":[[16,4]]},"364":{"position":[[20,4]]},"668":{"position":[[0,7]]},"2581":{"position":[[46,5]]},"2603":{"position":[[27,7]]},"2777":{"position":[[47,7]]},"2904":{"position":[[32,7]]},"3051":{"position":[[36,5]]},"3202":{"position":[[17,7]]}}}],["testb",{"_index":202,"t":{"1229":{"position":[[0,7]]},"1769":{"position":[[0,7]]}}}],["timezon",{"_index":170,"t":{"1032":{"position":[[0,8]]}}}],["tip",{"_index":49,"t":{"185":{"position":[[0,4]]}}}],["title_",{"_index":336,"t":{"3485":{"position":[[13,6]]},"3498":{"position":[[13,6]]}}}],["tool",{"_index":133,"t":{"723":{"position":[[0,5]]},"1392":{"position":[[0,5]]},"2072":{"position":[[0,5]]}}}],["trace",{"_index":243,"t":{"2139":{"position":[[0,6]]}}}],["trick",{"_index":50,"t":{"185":{"position":[[9,6]]}}}],["troubleshoot",{"_index":79,"t":{"401":{"position":[[0,15]]},"584":{"position":[[16,15]]},"1722":{"position":[[0,15]]}}}],["tune",{"_index":200,"t":{"1225":{"position":[[0,5]]},"2145":{"position":[[0,6]]}}}],["type",{"_index":284,"t":{"2555":{"position":[[35,4]]},"2557":{"position":[[17,4]]},"2958":{"position":[[25,4]]},"3019":{"position":[[7,4]]}}}],["up",{"_index":148,"t":{"892":{"position":[[8,2]]},"1614":{"position":[[8,2]]},"2339":{"position":[[15,2]]}}}],["update.pi",{"_index":139,"t":{"844":{"position":[[14,9]]},"1478":{"position":[[14,9]]}}}],["upgrad",{"_index":86,"t":{"459":{"position":[[0,7]]},"597":{"position":[[29,7]]},"1735":{"position":[[0,7]]}}}],["us",{"_index":165,"t":{"1009":{"position":[[0,3]]},"1852":{"position":[[21,3]]},"1914":{"position":[[36,3]]},"2581":{"position":[[10,5]]},"3051":{"position":[[0,5]]}}}],["usag",{"_index":108,"t":{"628":{"position":[[0,5]]},"2034":{"position":[[25,5]]},"2613":{"position":[[44,5]]},"3432":{"position":[[34,5]]}}}],["user",{"_index":72,"t":{"309":{"position":[[5,5]]},"1042":{"position":[[0,4]]},"1823":{"position":[[0,4]]},"1869":{"position":[[0,4]]},"1985":{"position":[[0,4]]}}}],["v2",{"_index":121,"t":{"655":{"position":[[18,2]]}}}],["valid",{"_index":197,"t":{"1220":{"position":[[0,11]]}}}],["ve",{"_index":161,"t":{"976":{"position":[[8,2]]}}}],["version",{"_index":255,"t":{"2521":{"position":[[11,8]]},"2583":{"position":[[18,7]]},"3122":{"position":[[8,7]]},"3165":{"position":[[8,7],[42,8]]}}}],["via",{"_index":69,"t":{"295":{"position":[[21,3]]}}}],["virtual",{"_index":129,"t":{"686":{"position":[[0,14]]}}}],["vmware",{"_index":218,"t":{"1826":{"position":[[13,6]]}}}],["volum",{"_index":283,"t":{"2555":{"position":[[28,6]]},"2557":{"position":[[10,6]]},"2958":{"position":[[18,6]]},"3019":{"position":[[0,6]]}}}],["wavestack",{"_index":18,"t":{"49":{"position":[[21,9]]}}}],["websso",{"_index":228,"t":{"1954":{"position":[[63,8]]}}}],["workflow",{"_index":33,"t":{"102":{"position":[[14,8]]}}}],["x",{"_index":14,"t":{"41":{"position":[[21,1]]},"2435":{"position":[[30,1]]}}}],["yaml",{"_index":262,"t":{"2529":{"position":[[36,4]]},"2793":{"position":[[26,4]]}}}],["zuul",{"_index":63,"t":{"266":{"position":[[0,4]]},"309":{"position":[[0,4]]},"1737":{"position":[[0,4]]},"2157":{"position":[[0,4]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":3,"t":"Welcome to our SCS Community","u":"/community/","h":"#welcome-to-our-scs-community","p":2},{"i":8,"t":"Getting Started with OpenStack CLI","u":"/community/cloud-resources/getting-started-openstack","h":"#getting-started-with-openstack-cli","p":7},{"i":9,"t":"OpenStackClient (CLI)","u":"/community/cloud-resources/getting-started-openstack","h":"#openstackclient-cli","p":7},{"i":11,"t":"Object Storage (S3)","u":"/community/cloud-resources/getting-started-openstack","h":"#object-storage-s3","p":7},{"i":13,"t":"References","u":"/community/cloud-resources/getting-started-openstack","h":"#references","p":7},{"i":17,"t":"How to request cloud resources","u":"/community/cloud-resources/","h":"#how-to-request-cloud-resources","p":15},{"i":19,"t":"plusserver","u":"/community/cloud-resources/","h":"#plusserver","p":15},{"i":20,"t":"Usage","u":"/community/cloud-resources/","h":"#usage","p":15},{"i":22,"t":"Users","u":"/community/cloud-resources/","h":"#users","p":15},{"i":24,"t":"Service Users","u":"/community/cloud-resources/","h":"#service-users","p":15},{"i":26,"t":"Projects","u":"/community/cloud-resources/","h":"#projects","p":15},{"i":28,"t":"Wavecon","u":"/community/cloud-resources/","h":"#wavecon","p":15},{"i":29,"t":"Service Users","u":"/community/cloud-resources/","h":"#service-users-1","p":15},{"i":31,"t":"Projects","u":"/community/cloud-resources/","h":"#projects-1","p":15},{"i":35,"t":"Project p500924-harbor","u":"/community/central-services/plusserver-gx-scs","h":"#project-p500924-harbor","p":33},{"i":36,"t":"K8s clusters","u":"/community/central-services/plusserver-gx-scs","h":"#k8s-clusters","p":33},{"i":38,"t":"Project p500924-sig-monitoring1","u":"/community/central-services/plusserver-gx-scs","h":"#project-p500924-sig-monitoring1","p":33},{"i":39,"t":"K8s clusters","u":"/community/central-services/plusserver-gx-scs","h":"#k8s-clusters-1","p":33},{"i":42,"t":"Getting Started for the Gaia-X Demonstrator @ plusserver","u":"/community/cloud-resources/plusserver-gx-scs","h":"#getting-started-for-the-gaia-x-demonstrator--plusserver","p":41},{"i":43,"t":"URLs for access","u":"/community/cloud-resources/plusserver-gx-scs","h":"#urls-for-access","p":41},{"i":45,"t":"Authentication (UI)","u":"/community/cloud-resources/plusserver-gx-scs","h":"#authentication-ui","p":41},{"i":47,"t":"Getting Started with OpenStack","u":"/community/cloud-resources/plusserver-gx-scs","h":"#getting-started-with-openstack","p":41},{"i":50,"t":"URLs for access","u":"/community/cloud-resources/wavestack","h":"#urls-for-access","p":49},{"i":52,"t":"Authentication (UI)","u":"/community/cloud-resources/wavestack","h":"#authentication-ui","p":49},{"i":54,"t":"OpenStackClient (CLI)","u":"/community/cloud-resources/wavestack","h":"#openstackclient-cli","p":49},{"i":57,"t":"We’re an open community","u":"/community/collaboration/","h":"#were-an-open-community","p":56},{"i":59,"t":"Collaborating with issues and pull requests","u":"/community/collaboration/","h":"#collaborating-with-issues-and-pull-requests","p":56},{"i":61,"t":"Meetings","u":"/community/collaboration/","h":"#meetings","p":56},{"i":62,"t":"Project updates","u":"/community/collaboration/","h":"#project-updates","p":56},{"i":64,"t":"Sprint review/Backlog refinement/Sprint planning meetings","u":"/community/collaboration/","h":"#sprint-reviewbacklog-refinementsprint-planning-meetings","p":56},{"i":66,"t":"Special interest groups (SIGs) and hacking sessions","u":"/community/collaboration/","h":"#special-interest-groups-sigs-and-hacking-sessions","p":56},{"i":85,"t":"Structure Best Practice","u":"/community/contribute/doc-files-structure-guide","h":"#structure-best-practice","p":84},{"i":86,"t":"Overview - mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#overview---mandatory","p":84},{"i":88,"t":"Requirements - mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#requirements---mandatory","p":84},{"i":90,"t":"Quickstart - optional. If it is possible, then mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#quickstart---optional-if-it-is-possible-then-mandatory","p":84},{"i":92,"t":"Getting Started - mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#getting-started---mandatory","p":84},{"i":94,"t":"Configuration – mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#configuration--mandatory","p":84},{"i":96,"t":"Contribute – mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#contribute--mandatory","p":84},{"i":98,"t":"FAQ`s – optional","u":"/community/contribute/doc-files-structure-guide","h":"#faqs--optional","p":84},{"i":104,"t":"Information Architecture","u":"/community/contribute/docs-workflow-explanation","h":"#information-architecture","p":102},{"i":108,"t":"Step 1 – Documentation type","u":"/community/contribute/adding-docs-guide","h":"#step-1--documentation-type","p":106},{"i":110,"t":"1. Technical Documentation","u":"/community/contribute/adding-docs-guide","h":"#1-technical-documentation","p":106},{"i":111,"t":"Step 1 – Checklist","u":"/community/contribute/adding-docs-guide","h":"#step-1--checklist","p":106},{"i":113,"t":"Step 2 – Adding your repo to the docs.json","u":"/community/contribute/adding-docs-guide","h":"#step-2--adding-your-repo-to-the-docsjson","p":106},{"i":115,"t":"2. Operational documentation","u":"/community/contribute/adding-docs-guide","h":"#2-operational-documentation","p":106},{"i":117,"t":"3. Community documentation","u":"/community/contribute/adding-docs-guide","h":"#3-community-documentation","p":106},{"i":121,"t":"Pre Commit","u":"/community/contribute/linting-guide","h":"#pre-commit","p":119},{"i":123,"t":"Github Workflows","u":"/community/contribute/linting-guide","h":"#github-workflows","p":119},{"i":126,"t":"Admonitions","u":"/community/contribute/styleguide","h":"#admonitions","p":125},{"i":128,"t":"Blockquotes","u":"/community/contribute/styleguide","h":"#blockquotes","p":125},{"i":130,"t":"Codeblocks","u":"/community/contribute/styleguide","h":"#codeblocks","p":125},{"i":134,"t":"Task naming","u":"/community/contribute/styleguides/ansible_styleguide","h":"#task-naming","p":132},{"i":136,"t":"Key Order","u":"/community/contribute/styleguides/ansible_styleguide","h":"#key-order","p":132},{"i":138,"t":"Positioning and use of the become directive","u":"/community/contribute/styleguides/ansible_styleguide","h":"#positioning-and-use-of-the-become-directive","p":132},{"i":140,"t":"Position of the when condition","u":"/community/contribute/styleguides/ansible_styleguide","h":"#position-of-the-when-condition","p":132},{"i":142,"t":"Usage of collections","u":"/community/contribute/styleguides/ansible_styleguide","h":"#usage-of-collections","p":132},{"i":144,"t":"Usage of roles from other collections","u":"/community/contribute/styleguides/ansible_styleguide","h":"#usage-of-roles-from-other-collections","p":132},{"i":146,"t":"Parameters that offer lists","u":"/community/contribute/styleguides/ansible_styleguide","h":"#parameters-that-offer-lists","p":132},{"i":148,"t":"Usage of changed_when","u":"/community/contribute/styleguides/ansible_styleguide","h":"#usage-of-changed_when","p":132},{"i":150,"t":"Disable linting rules","u":"/community/contribute/styleguides/ansible_styleguide","h":"#disable-linting-rules","p":132},{"i":154,"t":"Requirements","u":"/community/contribute/local-docusaurus-development-guide","h":"#requirements","p":152},{"i":156,"t":"Installation Guide","u":"/community/contribute/local-docusaurus-development-guide","h":"#installation-guide","p":152},{"i":157,"t":"Step 1 – Installing Node.js via nvm","u":"/community/contribute/local-docusaurus-development-guide","h":"#step-1--installing-nodejs-via-nvm","p":152},{"i":159,"t":"Step 2 – Cloning the repository","u":"/community/contribute/local-docusaurus-development-guide","h":"#step-2-cloning-the-repository","p":152},{"i":161,"t":"Step 3 – Installing dependencies","u":"/community/contribute/local-docusaurus-development-guide","h":"#step-3--installing-dependencies","p":152},{"i":163,"t":"Step 4 – Starting the development server","u":"/community/contribute/local-docusaurus-development-guide","h":"#step-4--starting-the-development-server","p":152},{"i":167,"t":"Reciprocity","u":"/community/license-considerations","h":"#reciprocity","p":165},{"i":169,"t":"Controversy","u":"/community/license-considerations","h":"#controversy","p":165},{"i":171,"t":"Affero","u":"/community/license-considerations","h":"#affero","p":165},{"i":173,"t":"Derived works and Strong vs. Weak Copyleft","u":"/community/license-considerations","h":"#derived-works-and-strong-vs-weak-copyleft","p":165},{"i":175,"t":"Patents","u":"/community/license-considerations","h":"#patents","p":165},{"i":177,"t":"Copyright Assignments and Contributor License Agreements","u":"/community/license-considerations","h":"#copyright-assignments-and-contributor-license-agreements","p":165},{"i":179,"t":"License in = License out","u":"/community/license-considerations","h":"#license-in--license-out","p":165},{"i":181,"t":"Further reading","u":"/community/license-considerations","h":"#further-reading","p":165},{"i":186,"t":"Octo Reminder - your friendly assistant","u":"/community/tools/github/tips-and-tricks","h":"#octo-reminder---your-friendly-assistant","p":185},{"i":190,"t":"Checklist 6 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-6-months-before-hackathon","p":188},{"i":192,"t":"Checklist advertising","u":"/community/hackathons/checklist","h":"#checklist-advertising","p":188},{"i":194,"t":"Checklist 5 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-5-months-before-hackathon","p":188},{"i":196,"t":"Checklist hotel","u":"/community/hackathons/checklist","h":"#checklist-hotel","p":188},{"i":197,"t":"Iportant things","u":"/community/hackathons/checklist","h":"#iportant-things","p":188},{"i":199,"t":"Nice-to-have things","u":"/community/hackathons/checklist","h":"#nice-to-have-things","p":188},{"i":201,"t":"Checklist 4 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-4-months-before-hackathon","p":188},{"i":203,"t":"Checklist for evening before location","u":"/community/hackathons/checklist","h":"#checklist-for-evening-before-location","p":188},{"i":205,"t":"Checklist rooms 1","u":"/community/hackathons/checklist","h":"#checklist-rooms-1","p":188},{"i":207,"t":"Checklist merch (examples)","u":"/community/hackathons/checklist","h":"#checklist-merch-examples","p":188},{"i":209,"t":"Checklist 3 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-3-months-before-hackathon","p":188},{"i":211,"t":"Checklist evening event","u":"/community/hackathons/checklist","h":"#checklist-evening-event","p":188},{"i":213,"t":"Checklist 2 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-2-months-before-hackathon","p":188},{"i":215,"t":"Snacks checklist","u":"/community/hackathons/checklist","h":"#snacks-checklist","p":188},{"i":216,"t":"Breakfast examples","u":"/community/hackathons/checklist","h":"#breakfast-examples","p":188},{"i":218,"t":"Snack exemples","u":"/community/hackathons/checklist","h":"#snack-exemples","p":188},{"i":220,"t":"Vegan snack examples","u":"/community/hackathons/checklist","h":"#vegan-snack-examples","p":188},{"i":222,"t":"Checklist rooms 2","u":"/community/hackathons/checklist","h":"#checklist-rooms-2","p":188},{"i":224,"t":"Checklist 1 month before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-1-month-before-hackathon","p":188},{"i":226,"t":"Checklist 1 week before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-1-week-before-hackathon","p":188},{"i":228,"t":"Checklist one day before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-one-day-before-hackathon","p":188},{"i":230,"t":"Checklist Hackathon Day X","u":"/community/hackathons/checklist","h":"#checklist-hackathon-day-x","p":188},{"i":232,"t":"Checklist after Hackathon","u":"/community/hackathons/checklist","h":"#checklist-after-hackathon","p":188},{"i":236,"t":"Values of our collaboration","u":"/community/mission-statement","h":"#values-of-our-collaboration","p":234},{"i":237,"t":"4+1 Open","u":"/community/mission-statement","h":"#41-open","p":234},{"i":239,"t":"The 'Four Open\"","u":"/community/mission-statement","h":"#the-four-open","p":234},{"i":241,"t":"+1 Open","u":"/community/mission-statement","h":"#1-open","p":234},{"i":243,"t":"Code of Conduct","u":"/community/mission-statement","h":"#code-of-conduct","p":234},{"i":244,"t":"Sovereign Cloud Stack Community","u":"/community/mission-statement","h":"#sovereign-cloud-stack-community","p":234},{"i":246,"t":"Our Standards","u":"/community/mission-statement","h":"#our-standards","p":234},{"i":250,"t":"Usage","u":"/community/tools/jitsi","h":"#usage","p":248},{"i":254,"t":"Further reading","u":"/community/tools/github/dco-and-licenses","h":"#further-reading","p":252},{"i":258,"t":"Client and Registration","u":"/community/tools/matrix","h":"#client-and-registration","p":256},{"i":267,"t":"Zuul CI/CD pipelines and project gating","u":"/community/tools/zuul","h":"#zuul-cicd-pipelines-and-project-gating","p":266},{"i":269,"t":"How to make a repo use Zuul","u":"/community/tools/zuul","h":"#how-to-make-a-repo-use-zuul","p":266},{"i":271,"t":"General information about Zuul","u":"/community/tools/zuul","h":"#general-information-about-zuul","p":266},{"i":277,"t":"1. Mapping of RFC2119 Keywords","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#1-mapping-of-rfc2119-keywords","p":275},{"i":279,"t":"2. Unit and Regression Tests","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#2-unit-and-regression-tests","p":275},{"i":281,"t":"Naming Conventions","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#naming-conventions","p":275},{"i":283,"t":"Write Testable Conformance Tests","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#write-testable-conformance-tests","p":275},{"i":285,"t":"Pytest Test Example","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#pytest-test-example","p":275},{"i":287,"t":"3. Conformance Tests Shouldn't Require Admin Privileges","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#3-conformance-tests-shouldnt-require-admin-privileges","p":275},{"i":291,"t":"1. IaaS / OpenStack","u":"/contributor-docs/operations/iam/identity-federation-in-scs","h":"#1-iaas--openstack","p":289},{"i":293,"t":"2. CaaS","u":"/contributor-docs/operations/iam/identity-federation-in-scs","h":"#2-caas","p":289},{"i":297,"t":"1. Keystone","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#1-keystone","p":295},{"i":299,"t":"1.1 Keycloak IdP realm discovery","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#11-keycloak-idp-realm-discovery","p":295},{"i":301,"t":"1.2 Keystone mapping of token claims","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#12-keystone-mapping-of-token-claims","p":295},{"i":303,"t":"1.3 Horizon WebSSO for federated users","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#13-horizon-websso-for-federated-users","p":295},{"i":305,"t":"1.4 OpenStack CLI and API access for federated users","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#14-openstack-cli-and-api-access-for-federated-users","p":295},{"i":307,"t":"1.5 SSO Federation between to SCS deployments","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#15-sso-federation-between-to-scs-deployments","p":295},{"i":310,"t":"Prerequisites","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#prerequisites","p":309},{"i":312,"t":"Who is it for?","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#who-is-it-for","p":309},{"i":314,"t":"Where do I start?","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#where-do-i-start","p":309},{"i":316,"t":"Where to save the Zuul relevant data?","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#where-to-save-the-zuul-relevant-data","p":309},{"i":318,"t":"Projects","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#projects","p":309},{"i":320,"t":"Pipelines","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#pipelines","p":309},{"i":322,"t":"Reports","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#reports","p":309},{"i":324,"t":"Jobs","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#jobs","p":309},{"i":328,"t":"Target groups","u":"/docs/container/","h":"#target-groups","p":326},{"i":330,"t":"What is it not","u":"/docs/container/","h":"#what-is-it-not","p":326},{"i":332,"t":"Prerequisites and Requirements","u":"/docs/container/","h":"#prerequisites-and-requirements","p":326},{"i":334,"t":"Features","u":"/docs/container/","h":"#features","p":326},{"i":336,"t":"Limitations","u":"/docs/container/","h":"#limitations","p":326},{"i":338,"t":"Current state and future Outlook","u":"/docs/container/","h":"#current-state-and-future-outlook","p":326},{"i":341,"t":"About","u":"/docs/","h":"#about","p":340},{"i":343,"t":"Architectural Overview","u":"/docs/","h":"#architectural-overview","p":340},{"i":345,"t":"Use Cases and Deployment Examples","u":"/docs/","h":"#use-cases-and-deployment-examples","p":340},{"i":346,"t":"IaaS Layer","u":"/docs/","h":"#iaas-layer","p":340},{"i":348,"t":"Container Layer","u":"/docs/","h":"#container-layer","p":340},{"i":350,"t":"Public SCS Clouds in production","u":"/docs/","h":"#public-scs-clouds-in-production","p":340},{"i":352,"t":"Development of SCS","u":"/docs/","h":"#development-of-scs","p":340},{"i":354,"t":"Issues and Bugs","u":"/docs/","h":"#issues-and-bugs","p":340},{"i":356,"t":"Contribute and Connect","u":"/docs/","h":"#contribute-and-connect","p":340},{"i":358,"t":"Releases and Roadmap","u":"/docs/","h":"#releases-and-roadmap","p":340},{"i":360,"t":"Standards, Conformity and Certification","u":"/docs/","h":"#standards-conformity-and-certification","p":340},{"i":365,"t":"Introduction","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#introduction","p":364},{"i":367,"t":"1. Understanding SCS Standards and RFC2119 Keywords","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#1-understanding-scs-standards-and-rfc2119-keywords","p":364},{"i":369,"t":"2. Interpreting RFC2119 Keywords in the Context of SCS","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#2-interpreting-rfc2119-keywords-in-the-context-of-scs","p":364},{"i":371,"t":"3. Channels for Output in Test Scripts","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#3-channels-for-output-in-test-scripts","p":364},{"i":373,"t":"4. Compliance and Test Passing Criteria","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#4-compliance-and-test-passing-criteria","p":364},{"i":375,"t":"Examples","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#examples","p":364},{"i":376,"t":"5.1 Example: Standards Document using RFC2119 Keywords","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#51-example-standards-document-using-rfc2119-keywords","p":364},{"i":378,"t":"Web Server Installation Standard","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#web-server-installation-standard","p":364},{"i":380,"t":"5.2 Example: Test script using RFC2119 Keywords","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#52-example-test-script-using-rfc2119-keywords","p":364},{"i":384,"t":"Setting Tilt up","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#setting-tilt-up","p":382},{"i":386,"t":"Developing with Tilt","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#developing-with-tilt","p":382},{"i":388,"t":"Applying ClusterStack","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#applying-clusterstack","p":382},{"i":390,"t":"Creating workload cluster","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#creating-workload-cluster","p":382},{"i":392,"t":"Toggle between local_mode and remote mode","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#toggle-between-local_mode-and-remote-mode","p":382},{"i":395,"t":"OpenStackClusterStackRelease controller","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","h":"#openstackclusterstackrelease-controller","p":394},{"i":397,"t":"OpenStackNodeImageRelease controller","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","h":"#openstacknodeimagerelease-controller","p":394},{"i":403,"t":"providerClient authentication err","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","h":"#providerclient-authentication-err","p":401},{"i":406,"t":"Prerequisites","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#prerequisites","p":405},{"i":408,"t":"Install and wait for operators","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#install-and-wait-for-operators","p":405},{"i":410,"t":"Create redis and postgres clusters","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#create-redis-and-postgres-clusters","p":405},{"i":412,"t":"Install Harbor","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#install-harbor","p":405},{"i":414,"t":"All in one installation using FluxCD Kustomization and GitRepository reconciliation","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#all-in-one-installation-using-fluxcd-kustomization-and-gitrepository-reconciliation","p":405},{"i":418,"t":"Prerequisites","u":"/docs/container/components/container-registry/docs/migration","h":"#prerequisites","p":416},{"i":420,"t":"Kubernetes clusters","u":"/docs/container/components/container-registry/docs/migration","h":"#kubernetes-clusters","p":416},{"i":422,"t":"S3 bucket and EC2 credentials","u":"/docs/container/components/container-registry/docs/migration","h":"#s3-bucket-and-ec2-credentials","p":416},{"i":424,"t":"Velero client","u":"/docs/container/components/container-registry/docs/migration","h":"#velero-client","p":416},{"i":426,"t":"Velero server","u":"/docs/container/components/container-registry/docs/migration","h":"#velero-server","p":416},{"i":431,"t":"Prerequisites","u":"/docs/container/components/container-registry/docs/quickstart","h":"#prerequisites","p":429},{"i":433,"t":"Install Harbor container registry","u":"/docs/container/components/container-registry/docs/quickstart","h":"#install-harbor-container-registry","p":429},{"i":439,"t":"Prerequisites","u":"/docs/container/components/container-registry/docs/scs-deployment","h":"#prerequisites","p":437},{"i":441,"t":"Install Harbor","u":"/docs/container/components/container-registry/docs/scs-deployment","h":"#install-harbor","p":437},{"i":445,"t":"Data Access Layer","u":"/docs/container/components/container-registry/docs/persistence","h":"#data-access-layer","p":443},{"i":446,"t":"Redis","u":"/docs/container/components/container-registry/docs/persistence","h":"#redis","p":443},{"i":448,"t":"Database (PostgreSQL)","u":"/docs/container/components/container-registry/docs/persistence","h":"#database-postgresql","p":443},{"i":450,"t":"OCI Distribution Registry","u":"/docs/container/components/container-registry/docs/persistence","h":"#oci-distribution-registry","p":443},{"i":452,"t":"Fundamental Services","u":"/docs/container/components/container-registry/docs/persistence","h":"#fundamental-services","p":443},{"i":453,"t":"Proxy, Core, Web Portal","u":"/docs/container/components/container-registry/docs/persistence","h":"#proxy-core-web-portal","p":443},{"i":455,"t":"Trivy","u":"/docs/container/components/container-registry/docs/persistence","h":"#trivy","p":443},{"i":457,"t":"JobService","u":"/docs/container/components/container-registry/docs/persistence","h":"#jobservice","p":443},{"i":463,"t":"Prerequisites","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#prerequisites","p":461},{"i":464,"t":"Kubernetes cluster","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#kubernetes-cluster","p":461},{"i":466,"t":"S3 bucket and EC2 credentials","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#s3-bucket-and-ec2-credentials","p":461},{"i":468,"t":"Velero client","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#velero-client","p":461},{"i":470,"t":"Velero server","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#velero-server","p":461},{"i":473,"t":"Backup Harbor Instance","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#backup-harbor-instance","p":461},{"i":475,"t":"Restore Harbor Instance","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#restore-harbor-instance","p":461},{"i":478,"t":"Supported k8s versions","u":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","h":"#supported-k8s-versions","p":477},{"i":480,"t":"Overview over the parameters in clusterctl.yaml and environment-XXX.tfvars","u":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","h":"#overview-over-the-parameters-in-clusterctlyaml-and-environment-xxxtfvars","p":477},{"i":482,"t":"Parameters CAPI management server","u":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","h":"#parameters-capi-management-server","p":477},{"i":484,"t":"Common parameters management server and clusters","u":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","h":"#common-parameters-management-server-and-clusters","p":477},{"i":486,"t":"Parameters clusters","u":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","h":"#parameters-clusters","p":477},{"i":490,"t":"Configuration","u":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","h":"#configuration","p":488},{"i":492,"t":"Pipelines","u":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","h":"#pipelines","p":488},{"i":494,"t":"Jobs","u":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","h":"#jobs","p":488},{"i":496,"t":"Secrets","u":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","h":"#secrets","p":488},{"i":498,"t":"Job customization","u":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","h":"#job-customization","p":488},{"i":504,"t":"Getting it to work for managed ingress","u":"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","h":"","p":502},{"i":506,"t":"Getting it to work in general","u":"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","h":"","p":502},{"i":508,"t":"OVN provider LoadBalancer","u":"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","h":"","p":502},{"i":510,"t":"Disabled health-monitor by default","u":"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","h":"","p":502},{"i":516,"t":"Requirements","u":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","h":"#requirements","p":514},{"i":518,"t":"Prepare the environment","u":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","h":"#prepare-the-environment","p":514},{"i":520,"t":"Create a test cluster","u":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","h":"#create-a-test-cluster","p":514},{"i":522,"t":"Teardown","u":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","h":"#teardown","p":514},{"i":524,"t":"Beyond quickstart","u":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","h":"#beyond-quickstart","p":514},{"i":528,"t":"General commands","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#general-commands","p":526},{"i":529,"t":"make create","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-create","p":526},{"i":531,"t":"make get-kubeconfig","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-get-kubeconfig","p":526},{"i":533,"t":"make ssh","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-ssh","p":526},{"i":535,"t":"make openstack","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-openstack","p":526},{"i":537,"t":"make k9s","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-k9s","p":526},{"i":539,"t":"make log","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-log","p":526},{"i":541,"t":"make console","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-console","p":526},{"i":543,"t":"make deploy-cso","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-deploy-cso","p":526},{"i":545,"t":"make deploy-cspo","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-deploy-cspo","p":526},{"i":547,"t":"Teardown","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#teardown","p":526},{"i":549,"t":"Make clean","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-clean","p":526},{"i":551,"t":"Make fullclean","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-fullclean","p":526},{"i":553,"t":"Make purge","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-purge","p":526},{"i":555,"t":"Testing commands","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#testing-commands","p":526},{"i":556,"t":"make check","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-check","p":526},{"i":558,"t":"make check-quick","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-check-quick","p":526},{"i":560,"t":"make check-conformance","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-check-conformance","p":526},{"i":562,"t":"make check-storage","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-check-storage","p":526},{"i":564,"t":"make check-csi","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-check-csi","p":526},{"i":566,"t":"OpenTofu commands","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#opentofu-commands","p":526},{"i":567,"t":"make init","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-init","p":526},{"i":569,"t":"make attach","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-attach","p":526},{"i":571,"t":"make detach","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-detach","p":526},{"i":573,"t":"make state-push","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-state-push","p":526},{"i":575,"t":"make dry-run","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-dry-run","p":526},{"i":577,"t":"make show","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-show","p":526},{"i":579,"t":"make list","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-list","p":526},{"i":582,"t":"Advanced cluster templating with helm (Technical Preview)","u":"/docs/container/components/k8s-cluster-api-provider/doc/roadmap","h":"#advanced-cluster-templating-with-helm-technical-preview","p":581},{"i":585,"t":"Client Certificates in Kubernetes expire after one year","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","h":"#client-certificates-in-kubernetes-expire-after-one-year","p":584},{"i":587,"t":"Certificate Authority expires","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","h":"#certificate-authority-expires","p":584},{"i":589,"t":"Failed cluster deployment debugging","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","h":"#failed-cluster-deployment-debugging","p":584},{"i":591,"t":"Cluster state","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","h":"#cluster-state","p":584},{"i":593,"t":"Etcd maintenance","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","h":"#etcd-maintenance","p":584},{"i":595,"t":"Defragmentation and backup","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","h":"#defragmentation-and-backup","p":584},{"i":599,"t":"Management host (cluster) vs. Workload clusters","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#management-host-cluster-vs-workload-clusters","p":597},{"i":601,"t":"Updating the management host","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#updating-the-management-host","p":597},{"i":603,"t":"In-place upgrade","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#in-place-upgrade","p":597},{"i":605,"t":"The clusterctl move approach","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#the-clusterctl-move-approach","p":597},{"i":607,"t":"Updating workload clusters","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#updating-workload-clusters","p":597},{"i":608,"t":"k8s version upgrade","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#k8s-version-upgrade","p":597},{"i":610,"t":"New versions for mandatory components","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#new-versions-for-mandatory-components","p":597},{"i":612,"t":"New versions for optional components","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#new-versions-for-optional-components","p":597},{"i":614,"t":"etcd leader changes","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#etcd-leader-changes","p":597},{"i":618,"t":"Environments","u":"/docs/container/components/k8s-cluster-api-provider/doc/requirements","h":"#environments","p":616},{"i":620,"t":"Plusserver community environment","u":"/docs/container/components/k8s-cluster-api-provider/doc/requirements","h":"#plusserver-community-environment","p":616},{"i":622,"t":"Wavestack environment","u":"/docs/container/components/k8s-cluster-api-provider/doc/requirements","h":"#wavestack-environment","p":616},{"i":624,"t":"Custom environment","u":"/docs/container/components/k8s-cluster-api-provider/doc/requirements","h":"#custom-environment","p":616},{"i":634,"t":"Tutorial: configure an existing cluster to use containerd registry configuration","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration","h":"#tutorial-configure-an-existing-cluster-to-use-containerd-registry-configuration","p":632},{"i":640,"t":"Default deployment","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor","h":"#default-deployment","p":638},{"i":642,"t":"Configuration options","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor","h":"#configuration-options","p":638},{"i":643,"t":"Persistence","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor","h":"#persistence","p":638},{"i":645,"t":"Ingress and TLS","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor","h":"#ingress-and-tls","p":638},{"i":651,"t":"Rotation","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca","h":"#rotation","p":649},{"i":657,"t":"Migration","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2","h":"#migration","p":655},{"i":659,"t":"Steps","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2","h":"#steps","p":655},{"i":663,"t":"Migration","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class","h":"#migration","p":661},{"i":664,"t":"Prerequisites","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class","h":"#prerequisites","p":661},{"i":666,"t":"Steps","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class","h":"#steps","p":661},{"i":689,"t":"What does SCS stand for?","u":"/docs/faq/","h":"#what-does-scs-stand-for","p":688},{"i":691,"t":"Who is SCS intended for?","u":"/docs/faq/","h":"#who-is-scs-intended-for","p":688},{"i":693,"t":"Who or what is behind SCS?","u":"/docs/faq/","h":"#who-or-what-is-behind-scs","p":688},{"i":695,"t":"Why is there a need for a standardized cloud environment?","u":"/docs/faq/","h":"#why-is-there-a-need-for-a-standardized-cloud-environment","p":688},{"i":697,"t":"Where can I find the SCS standards?","u":"/docs/faq/","h":"#where-can-i-find-the-scs-standards","p":688},{"i":699,"t":"How is the SCS different from other cloud environments (e.g. AWS, Azure,...)?","u":"/docs/faq/","h":"#how-is-the-scs-different-from-other-cloud-environments-eg-aws-azure","p":688},{"i":701,"t":"My company already has a cloud environment. Can we still use the SCS?","u":"/docs/faq/","h":"#my-company-already-has-a-cloud-environment-can-we-still-use-the-scs","p":688},{"i":703,"t":"What does reference implementation mean?","u":"/docs/faq/","h":"#what-does-reference-implementation-mean","p":688},{"i":705,"t":"Do I need to use the reference implementation to be SCS compliant?","u":"/docs/faq/","h":"#do-i-need-to-use-the-reference-implementation-to-be-scs-compliant","p":688},{"i":707,"t":"Do I have to use all layers of the reference implementation (IaaS, CaaS)?","u":"/docs/faq/","h":"#do-i-have-to-use-all-layers-of-the-reference-implementation-iaas-caas","p":688},{"i":709,"t":"What does IaaS mean?","u":"/docs/faq/","h":"#what-does-iaas-mean","p":688},{"i":711,"t":"How is the IaaS layer structured?","u":"/docs/faq/","h":"#how-is-the-iaas-layer-structured","p":688},{"i":713,"t":"What does CaaS mean? (Container Layer)","u":"/docs/faq/","h":"#what-does-caas-mean-container-layer","p":688},{"i":715,"t":"I want to try out the SCS! Where do I start?","u":"/docs/faq/","h":"#i-want-to-try-out-the-scs-where-do-i-start","p":688},{"i":717,"t":"I want to use an SCS Cloud! How do I get started?","u":"/docs/faq/","h":"#i-want-to-use-an-scs-cloud-how-do-i-get-started","p":688},{"i":719,"t":"I want to use the SCS in my company and build my own cloud! Where do I start?","u":"/docs/faq/","h":"#i-want-to-use-the-scs-in-my-company-and-build-my-own-cloud-where-do-i-start","p":688},{"i":721,"t":"I have a technical problem. Where can I find help?","u":"/docs/faq/","h":"#i-have-a-technical-problem-where-can-i-find-help","p":688},{"i":725,"t":"Overview","u":"/docs/iaas/components/flavor-manager","h":"#overview","p":724},{"i":727,"t":"Installation","u":"/docs/iaas/components/flavor-manager","h":"#installation","p":724},{"i":729,"t":"Usage","u":"/docs/iaas/components/flavor-manager","h":"#usage","p":724},{"i":731,"t":"Definitions","u":"/docs/iaas/components/flavor-manager","h":"#definitions","p":724},{"i":733,"t":"Name parser and generator","u":"/docs/iaas/components/flavor-manager","h":"#name-parser-and-generator","p":724},{"i":737,"t":"Definition of a Region","u":"/docs/glossary","h":"#definition-of-a-region","p":735},{"i":739,"t":"Definition of a Availability Zone","u":"/docs/glossary","h":"#definition-of-a-availability-zone","p":735},{"i":741,"t":"Definition of Host Aggregates","u":"/docs/glossary","h":"#definition-of-host-aggregates","p":735},{"i":743,"t":"Definition of a Cell","u":"/docs/glossary","h":"#definition-of-a-cell","p":735},{"i":745,"t":"Definition of a Control Plane","u":"/docs/glossary","h":"#definition-of-a-control-plane","p":735},{"i":747,"t":"Definition of Control Node","u":"/docs/glossary","h":"#definition-of-control-node","p":735},{"i":749,"t":"Definition of Compute Node","u":"/docs/glossary","h":"#definition-of-compute-node","p":735},{"i":751,"t":"Definition of Manager Node","u":"/docs/glossary","h":"#definition-of-manager-node","p":735},{"i":753,"t":"Definition of provider network","u":"/docs/glossary","h":"#definition-of-provider-network","p":735},{"i":755,"t":"Definition of API","u":"/docs/glossary","h":"#definition-of-api","p":735},{"i":757,"t":"Horizon","u":"/docs/glossary","h":"#horizon","p":735},{"i":759,"t":"Message Queue","u":"/docs/glossary","h":"#message-queue","p":735},{"i":761,"t":"Keystone","u":"/docs/glossary","h":"#keystone","p":735},{"i":763,"t":"Glance","u":"/docs/glossary","h":"#glance","p":735},{"i":765,"t":"OSISM","u":"/docs/glossary","h":"#osism","p":735},{"i":767,"t":"Ceph","u":"/docs/glossary","h":"#ceph","p":735},{"i":769,"t":"Nova","u":"/docs/glossary","h":"#nova","p":735},{"i":771,"t":"Neutron","u":"/docs/glossary","h":"#neutron","p":735},{"i":773,"t":"Cinder","u":"/docs/glossary","h":"#cinder","p":735},{"i":775,"t":"Swift","u":"/docs/glossary","h":"#swift","p":735},{"i":777,"t":"Ceph OSD","u":"/docs/glossary","h":"#ceph-osd","p":735},{"i":779,"t":"Personas","u":"/docs/glossary","h":"#personas","p":735},{"i":783,"t":"Requirements","u":"/docs/iaas/components/image-manager/","h":"#requirements","p":781},{"i":785,"t":"OpenStack Image Service (Glance)","u":"/docs/iaas/components/image-manager/","h":"#openstack-image-service-glance","p":781},{"i":787,"t":"Object storage backend","u":"/docs/iaas/components/image-manager/","h":"#object-storage-backend","p":781},{"i":789,"t":"Getting started","u":"/docs/iaas/components/image-manager/","h":"#getting-started","p":781},{"i":791,"t":"Image definitions","u":"/docs/iaas/components/image-manager/","h":"#image-definitions","p":781},{"i":793,"t":"SCS image standard","u":"/docs/iaas/components/image-manager/","h":"#scs-image-standard","p":781},{"i":795,"t":"Image with regular rebuilds","u":"/docs/iaas/components/image-manager/","h":"#image-with-regular-rebuilds","p":781},{"i":797,"t":"Image without regular rebuild","u":"/docs/iaas/components/image-manager/","h":"#image-without-regular-rebuild","p":781},{"i":799,"t":"Other properties","u":"/docs/iaas/components/image-manager/","h":"#other-properties","p":781},{"i":801,"t":"Usage","u":"/docs/iaas/components/image-manager/","h":"#usage","p":781},{"i":802,"t":"Mirroring images","u":"/docs/iaas/components/image-manager/","h":"#mirroring-images","p":781},{"i":804,"t":"Updating images","u":"/docs/iaas/components/image-manager/","h":"#updating-images","p":781},{"i":807,"t":"Overview","u":"/docs/iaas/components/project-manager","h":"#overview","p":806},{"i":809,"t":"Installation","u":"/docs/iaas/components/project-manager","h":"#installation","p":806},{"i":811,"t":"Defaults","u":"/docs/iaas/components/project-manager","h":"#defaults","p":806},{"i":812,"t":"create.py","u":"/docs/iaas/components/project-manager","h":"#createpy","p":806},{"i":814,"t":"manage.py","u":"/docs/iaas/components/project-manager","h":"#managepy","p":806},{"i":816,"t":"Usage","u":"/docs/iaas/components/project-manager","h":"#usage","p":806},{"i":818,"t":"create.py","u":"/docs/iaas/components/project-manager","h":"#createpy-1","p":806},{"i":820,"t":"manage.py","u":"/docs/iaas/components/project-manager","h":"#managepy-1","p":806},{"i":822,"t":"Config files","u":"/docs/iaas/components/project-manager","h":"#config-files","p":806},{"i":824,"t":"Quota Templates","u":"/docs/iaas/components/project-manager","h":"#quota-templates","p":806},{"i":826,"t":"Setup Endpoints","u":"/docs/iaas/components/project-manager","h":"#setup-endpoints","p":806},{"i":829,"t":"Preparations","u":"/docs/iaas/components/resource-manager","h":"#preparations","p":828},{"i":831,"t":"Nova","u":"/docs/iaas/components/resource-manager","h":"#nova","p":828},{"i":832,"t":"Live migration","u":"/docs/iaas/components/resource-manager","h":"#live-migration","p":828},{"i":834,"t":"Evacuation","u":"/docs/iaas/components/resource-manager","h":"#evacuation","p":828},{"i":836,"t":"Octavia","u":"/docs/iaas/components/resource-manager","h":"#octavia","p":828},{"i":837,"t":"Amphora rotation","u":"/docs/iaas/components/resource-manager","h":"#amphora-rotation","p":828},{"i":839,"t":"Cinder","u":"/docs/iaas/components/resource-manager","h":"#cinder","p":828},{"i":841,"t":"Orphans","u":"/docs/iaas/components/resource-manager","h":"#orphans","p":828},{"i":845,"t":"Overview","u":"/docs/iaas/components/image-manager/update","h":"#overview","p":844},{"i":847,"t":"Installation","u":"/docs/iaas/components/image-manager/update","h":"#installation","p":844},{"i":849,"t":"Usage","u":"/docs/iaas/components/image-manager/update","h":"#usage","p":844},{"i":852,"t":"Overview","u":"/docs/iaas/components/simple-stress","h":"#overview","p":851},{"i":854,"t":"Installation","u":"/docs/iaas/components/simple-stress","h":"#installation","p":851},{"i":856,"t":"Defaults","u":"/docs/iaas/components/simple-stress","h":"#defaults","p":851},{"i":858,"t":"Usage","u":"/docs/iaas/components/simple-stress","h":"#usage","p":851},{"i":860,"t":"Config files","u":"/docs/iaas/components/simple-stress","h":"#config-files","p":851},{"i":863,"t":"Highlevel Overview","u":"/docs/iaas/guides/concept-guide/","h":"#highlevel-overview","p":862},{"i":864,"t":"Components in a cluster","u":"/docs/iaas/guides/concept-guide/","h":"#components-in-a-cluster","p":862},{"i":866,"t":"Requirements","u":"/docs/iaas/guides/concept-guide/","h":"#requirements","p":862},{"i":867,"t":"Layers in a cluster","u":"/docs/iaas/guides/concept-guide/","h":"#layers-in-a-cluster","p":862},{"i":869,"t":"Cluster design","u":"/docs/iaas/guides/concept-guide/","h":"#cluster-design","p":862},{"i":871,"t":"Use cases","u":"/docs/iaas/guides/concept-guide/","h":"#use-cases","p":862},{"i":873,"t":"Hardware Bill of Materials","u":"/docs/iaas/guides/concept-guide/","h":"#hardware-bill-of-materials","p":862},{"i":881,"t":"Lifecycle Management of Ceph in OSISM","u":"/docs/iaas/guides/concept-guide/components/ceph","h":"#lifecycle-management-of-ceph-in-osism","p":879},{"i":884,"t":"Lifecycle Management of Cluster API in OSISM","u":"/docs/iaas/guides/concept-guide/components/clusterapi","h":"#lifecycle-management-of-cluster-api-in-osism","p":882},{"i":885,"t":"Cluster API with OpenStack Magnum","u":"/docs/iaas/guides/concept-guide/components/clusterapi","h":"#cluster-api-with-openstack-magnum","p":882},{"i":886,"t":"Cluster API with SCS Cluster Stacks","u":"/docs/iaas/guides/concept-guide/components/clusterapi","h":"#cluster-api-with-scs-cluster-stacks","p":882},{"i":889,"t":"Lifecycle Management of Gardener in OSISM","u":"/docs/iaas/guides/concept-guide/components/gardener","h":"#lifecycle-management-of-gardener-in-osism","p":887},{"i":891,"t":"Lifecycle Management of K3S in OSISM","u":"/docs/iaas/guides/concept-guide/components/k3s","h":"#lifecycle-management-of-k3s-in-osism","p":890},{"i":894,"t":"Intro","u":"/docs/iaas/components/openstack-health-monitor","h":"#intro","p":892},{"i":896,"t":"Setting up the driver VM","u":"/docs/iaas/components/openstack-health-monitor","h":"#setting-up-the-driver-vm","p":892},{"i":898,"t":"Internal vs external monitoring","u":"/docs/iaas/components/openstack-health-monitor","h":"#internal-vs-external-monitoring","p":892},{"i":900,"t":"Unprivileged operation","u":"/docs/iaas/components/openstack-health-monitor","h":"#unprivileged-operation","p":892},{"i":902,"t":"Driver VM via openstack CLI","u":"/docs/iaas/components/openstack-health-monitor","h":"#driver-vm-via-openstack-cli","p":892},{"i":904,"t":"Configuring openstack CLI on the driver VM","u":"/docs/iaas/components/openstack-health-monitor","h":"#configuring-openstack-cli-on-the-driver-vm","p":892},{"i":906,"t":"Custom CA","u":"/docs/iaas/components/openstack-health-monitor","h":"#custom-ca","p":892},{"i":908,"t":"Your first api_monitor.sh iteration","u":"/docs/iaas/components/openstack-health-monitor","h":"#your-first-api_monitorsh-iteration","p":892},{"i":910,"t":"Resource impact and charging","u":"/docs/iaas/components/openstack-health-monitor","h":"#resource-impact-and-charging","p":892},{"i":912,"t":"Automating startup and cleanup","u":"/docs/iaas/components/openstack-health-monitor","h":"#automating-startup-and-cleanup","p":892},{"i":914,"t":"Changing parameters and restarting","u":"/docs/iaas/components/openstack-health-monitor","h":"#changing-parameters-and-restarting","p":892},{"i":916,"t":"Multiple instances","u":"/docs/iaas/components/openstack-health-monitor","h":"#multiple-instances","p":892},{"i":918,"t":"Alarming and Logs","u":"/docs/iaas/components/openstack-health-monitor","h":"#alarming-and-logs","p":892},{"i":919,"t":"eMail","u":"/docs/iaas/components/openstack-health-monitor","h":"#email","p":892},{"i":921,"t":"Log files","u":"/docs/iaas/components/openstack-health-monitor","h":"#log-files","p":892},{"i":923,"t":"Data collection and dashboard","u":"/docs/iaas/components/openstack-health-monitor","h":"#data-collection-and-dashboard","p":892},{"i":925,"t":"telegraf","u":"/docs/iaas/components/openstack-health-monitor","h":"#telegraf","p":892},{"i":927,"t":"influxdb","u":"/docs/iaas/components/openstack-health-monitor","h":"#influxdb","p":892},{"i":929,"t":"Add -S CLOUDNAME to your run_CLOUDNAME.sh script","u":"/docs/iaas/components/openstack-health-monitor","h":"#add--s-cloudname-to-your-run_cloudnamesh-script","p":892},{"i":931,"t":"grafana","u":"/docs/iaas/components/openstack-health-monitor","h":"#grafana","p":892},{"i":933,"t":"Alternative approach to install and configure the dashboard behind a reverse proxy","u":"/docs/iaas/components/openstack-health-monitor","h":"#alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy","p":892},{"i":935,"t":"Maintenance","u":"/docs/iaas/components/openstack-health-monitor","h":"#maintenance","p":892},{"i":937,"t":"Unattended upgrades","u":"/docs/iaas/components/openstack-health-monitor","h":"#unattended-upgrades","p":892},{"i":939,"t":"Updating openstack-health-monitor","u":"/docs/iaas/components/openstack-health-monitor","h":"#updating-openstack-health-monitor","p":892},{"i":941,"t":"Backup","u":"/docs/iaas/components/openstack-health-monitor","h":"#backup","p":892},{"i":943,"t":"Troubleshooting","u":"/docs/iaas/components/openstack-health-monitor","h":"#troubleshooting","p":892},{"i":944,"t":"Debugging issues","u":"/docs/iaas/components/openstack-health-monitor","h":"#debugging-issues","p":892},{"i":946,"t":"Analyzing failures","u":"/docs/iaas/components/openstack-health-monitor","h":"#analyzing-failures","p":892},{"i":948,"t":"Cleaning things up","u":"/docs/iaas/components/openstack-health-monitor","h":"#cleaning-things-up","p":892},{"i":951,"t":"Lifecycle Management of Keycloak in OSISM","u":"/docs/iaas/guides/concept-guide/components/keycloak","h":"#lifecycle-management-of-keycloak-in-osism","p":950},{"i":953,"t":"Lifecycle Management of OpenStack in OSISM","u":"/docs/iaas/guides/concept-guide/components/openstack","h":"#lifecycle-management-of-openstack-in-osism","p":952},{"i":957,"t":"Lifecycle Management of Ironic in OSISM","u":"/docs/iaas/guides/concept-guide/components/ironic","h":"#lifecycle-management-of-ironic-in-osism","p":955},{"i":959,"t":"Lifecycle Management of Prometheus in OSISM","u":"/docs/iaas/guides/concept-guide/components/prometheus","h":"#lifecycle-management-of-prometheus-in-osism","p":958},{"i":960,"t":"Lifecycle Management of Grafana in OSISM","u":"/docs/iaas/guides/concept-guide/components/prometheus","h":"#lifecycle-management-of-grafana-in-osism","p":958},{"i":962,"t":"Lifecycle Management of Netdata in OSISM","u":"/docs/iaas/guides/concept-guide/components/netdata","h":"#lifecycle-management-of-netdata-in-osism","p":961},{"i":964,"t":"## Lifecycle Management of SONiC in OSISM","u":"/docs/iaas/guides/concept-guide/components/sonic","h":"#-lifecycle-management-of-sonic-in-osism","p":963},{"i":965,"t":"## Lifecycle Management of Open Virtual Network (OVN) in OSISM","u":"/docs/iaas/guides/concept-guide/components/sonic","h":"#-lifecycle-management-of-open-virtual-network-ovn-in-osism","p":963},{"i":966,"t":"## Lifecycle Management of Open vSwitch (OVS) in OSISM","u":"/docs/iaas/guides/concept-guide/components/sonic","h":"#-lifecycle-management-of-open-vswitch-ovs-in-osism","p":963},{"i":968,"t":"Lifecycle Management of Teleport in OSISM","u":"/docs/iaas/guides/concept-guide/components/teleport","h":"#lifecycle-management-of-teleport-in-osism","p":967},{"i":971,"t":"Compute architecture","u":"/docs/iaas/guides/concept-guide/design","h":"#compute-architecture","p":969},{"i":972,"t":"Storage architecture","u":"/docs/iaas/guides/concept-guide/design","h":"#storage-architecture","p":969},{"i":973,"t":"Network architecture","u":"/docs/iaas/guides/concept-guide/design","h":"#network-architecture","p":969},{"i":974,"t":"Identity architecture","u":"/docs/iaas/guides/concept-guide/design","h":"#identity-architecture","p":969},{"i":975,"t":"Control plane architecture","u":"/docs/iaas/guides/concept-guide/design","h":"#control-plane-architecture","p":969},{"i":978,"t":"Lifecycle Management of Proxmox VE in OSISM","u":"/docs/iaas/guides/concept-guide/components/proxmox","h":"#lifecycle-management-of-proxmox-ve-in-osism","p":976},{"i":981,"t":"Control nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#control-nodes","p":979},{"i":983,"t":"Compute nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#compute-nodes","p":979},{"i":985,"t":"Storage nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#storage-nodes","p":979},{"i":987,"t":"Network nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#network-nodes","p":979},{"i":989,"t":"Manager nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#manager-nodes","p":979},{"i":991,"t":"Switches","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#switches","p":979},{"i":992,"t":"Management switches","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#management-switches","p":979},{"i":994,"t":"Leaf switches","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#leaf-switches","p":979},{"i":996,"t":"Spine switches","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#spine-switches","p":979},{"i":998,"t":"Network interface cards","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#network-interface-cards","p":979},{"i":1000,"t":"Compute Plane","u":"/docs/iaas/guides/concept-guide/layers","h":"#compute-plane","p":999},{"i":1001,"t":"Control Plane","u":"/docs/iaas/guides/concept-guide/layers","h":"#control-plane","p":999},{"i":1002,"t":"Data Plane","u":"/docs/iaas/guides/concept-guide/layers","h":"#data-plane","p":999},{"i":1003,"t":"Management Plane","u":"/docs/iaas/guides/concept-guide/layers","h":"#management-plane","p":999},{"i":1004,"t":"Monitoring Plane","u":"/docs/iaas/guides/concept-guide/layers","h":"#monitoring-plane","p":999},{"i":1005,"t":"Network Plane","u":"/docs/iaas/guides/concept-guide/layers","h":"#network-plane","p":999},{"i":1010,"t":"Hyper-converged infrastructure (HCI)","u":"/docs/iaas/guides/concept-guide/use-cases","h":"#hyper-converged-infrastructure-hci","p":1009},{"i":1015,"t":"Distribution specific packages","u":"/docs/iaas/guides/configuration-guide/commons/packages","h":"#distribution-specific-packages","p":1013},{"i":1016,"t":"Debian","u":"/docs/iaas/guides/configuration-guide/commons/packages","h":"#debian","p":1013},{"i":1018,"t":"CentOS","u":"/docs/iaas/guides/configuration-guide/commons/packages","h":"#centos","p":1013},{"i":1020,"t":"Upgrade of packages","u":"/docs/iaas/guides/configuration-guide/commons/packages","h":"#upgrade-of-packages","p":1013},{"i":1026,"t":"Start and enable required services","u":"/docs/iaas/guides/configuration-guide/commons/services","h":"#start-and-enable-required-services","p":1024},{"i":1028,"t":"Note on services that should be deactivated","u":"/docs/iaas/guides/configuration-guide/commons/services","h":"#note-on-services-that-should-be-deactivated","p":1024},{"i":1036,"t":"Extra config","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","h":"#extra-config","p":1034},{"i":1038,"t":"Example","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","h":"#example","p":1034},{"i":1040,"t":"Defaults","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","h":"#defaults","p":1034},{"i":1046,"t":"Manager","u":"/docs/iaas/guides/configuration-guide/inventory","h":"#manager","p":1044},{"i":1048,"t":"Reconciler","u":"/docs/iaas/guides/configuration-guide/inventory","h":"#reconciler","p":1044},{"i":1049,"t":"Host Vars","u":"/docs/iaas/guides/configuration-guide/inventory","h":"#host-vars","p":1044},{"i":1050,"t":"Group Vars","u":"/docs/iaas/guides/configuration-guide/inventory","h":"#group-vars","p":1044},{"i":1051,"t":"Define variable for all nodes","u":"/docs/iaas/guides/configuration-guide/inventory","h":"#define-variable-for-all-nodes","p":1044},{"i":1054,"t":"Second Loadbalancer","u":"/docs/iaas/guides/configuration-guide/loadbalancer","h":"#second-loadbalancer","p":1053},{"i":1058,"t":"Creating a new configuration repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#creating-a-new-configuration-repository","p":1056},{"i":1060,"t":"Step 1: Preparation","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#step-1-preparation","p":1056},{"i":1062,"t":"Step 2: Run Cookiecutter","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#step-2-run-cookiecutter","p":1056},{"i":1064,"t":"Step 3: Upload the new configuration to the remote git repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#step-3-upload-the-new-configuration-to-the-remote-git-repository","p":1056},{"i":1066,"t":"Step 4: Post-processing of the generated configuration","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#step-4-post-processing-of-the-generated-configuration","p":1056},{"i":1068,"t":"Using latest","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#using-latest","p":1056},{"i":1070,"t":"Parameter reference","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#parameter-reference","p":1056},{"i":1072,"t":"Configuration repository layout","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#configuration-repository-layout","p":1056},{"i":1074,"t":"Synchronising the configuration repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#synchronising-the-configuration-repository","p":1056},{"i":1076,"t":"Locks","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#locks","p":1056},{"i":1079,"t":"Stable release","u":"/docs/iaas/guides/configuration-guide/manager","h":"#stable-release","p":1078},{"i":1081,"t":"OpenSearch integration","u":"/docs/iaas/guides/configuration-guide/manager","h":"#opensearch-integration","p":1078},{"i":1083,"t":"OpenStack broker integration","u":"/docs/iaas/guides/configuration-guide/manager","h":"#openstack-broker-integration","p":1078},{"i":1088,"t":"Netplan","u":"/docs/iaas/guides/configuration-guide/network","h":"#netplan","p":1087},{"i":1090,"t":"Example","u":"/docs/iaas/guides/configuration-guide/network","h":"#example","p":1087},{"i":1092,"t":"Dispatcher scripts","u":"/docs/iaas/guides/configuration-guide/network","h":"#dispatcher-scripts","p":1087},{"i":1093,"t":"Dummy interfaces","u":"/docs/iaas/guides/configuration-guide/network","h":"#dummy-interfaces","p":1087},{"i":1095,"t":"/etc/interfaces","u":"/docs/iaas/guides/configuration-guide/network","h":"#etcinterfaces","p":1087},{"i":1097,"t":"IPv6 fabric underlay","u":"/docs/iaas/guides/configuration-guide/network","h":"#ipv6-fabric-underlay","p":1087},{"i":1101,"t":"Unique Identifier","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#unique-identifier","p":1099},{"i":1103,"t":"Client","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#client","p":1099},{"i":1105,"t":"Swappiness","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#swappiness","p":1099},{"i":1107,"t":"RGW service","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#rgw-service","p":1099},{"i":1109,"t":"Extra pools","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#extra-pools","p":1099},{"i":1111,"t":"LVM devices","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#lvm-devices","p":1099},{"i":1113,"t":"Full examples","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#full-examples","p":1099},{"i":1115,"t":"Dashboard","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#dashboard","p":1099},{"i":1117,"t":"Configuring the openstack loadbalancer to expose the ceph dashboard","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#configuring-the-openstack-loadbalancer-to-expose-the-ceph-dashboard","p":1099},{"i":1119,"t":"Second Ceph cluster","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#second-ceph-cluster","p":1099},{"i":1121,"t":"Resource limits","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#resource-limits","p":1099},{"i":1123,"t":"CPU Pinning","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#cpu-pinning","p":1099},{"i":1129,"t":"Pure Storage FlashArray","u":"/docs/iaas/guides/configuration-guide/openstack/cinder","h":"#pure-storage-flasharray","p":1127},{"i":1143,"t":"Problems uploading machine images larger than 1 GiB","u":"/docs/iaas/guides/configuration-guide/openstack/horizon","h":"#problems-uploading-machine-images-larger-than-1-gib","p":1141},{"i":1145,"t":"Make clouds.yml file downloadable as an alternative to the RC file","u":"/docs/iaas/guides/configuration-guide/openstack/horizon","h":"#make-cloudsyml-file-downloadable-as-an-alternative-to-the-rc-file","p":1141},{"i":1149,"t":"Domain manager policy","u":"/docs/iaas/guides/configuration-guide/openstack/keystone","h":"#domain-manager-policy","p":1147},{"i":1151,"t":"OIDC Federation","u":"/docs/iaas/guides/configuration-guide/openstack/keystone","h":"#oidc-federation","p":1147},{"i":1155,"t":"Image tags","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#image-tags","p":1154},{"i":1157,"t":"Endpoints","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#endpoints","p":1154},{"i":1158,"t":"Public endpoints","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#public-endpoints","p":1154},{"i":1160,"t":"Example for the use of name-based endpoints","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#example-for-the-use-of-name-based-endpoints","p":1154},{"i":1162,"t":"Network interfaces","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#network-interfaces","p":1154},{"i":1164,"t":"Customization of the service configurations","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#customization-of-the-service-configurations","p":1154},{"i":1166,"t":"How does the configuration get into services?","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#how-does-the-configuration-get-into-services","p":1154},{"i":1168,"t":"Number of service workers","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#number-of-service-workers","p":1154},{"i":1172,"t":"Nested virtualisation","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#nested-virtualisation","p":1170},{"i":1173,"t":"AMD","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#amd","p":1170},{"i":1175,"t":"Intel","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#intel","p":1170},{"i":1177,"t":"Reserve compute node resources","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#reserve-compute-node-resources","p":1170},{"i":1179,"t":"Host memory","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#host-memory","p":1170},{"i":1181,"t":"Host CPUs","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#host-cpus","p":1170},{"i":1183,"t":"Local SSD storage","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#local-ssd-storage","p":1170},{"i":1187,"t":"MTU Considerations","u":"/docs/iaas/guides/configuration-guide/openstack/neutron","h":"#mtu-considerations","p":1185},{"i":1194,"t":"Skyline APIServer","u":"/docs/iaas/guides/configuration-guide/openstack/skyline","h":"#skyline-apiserver","p":1193},{"i":1196,"t":"Skyline Console","u":"/docs/iaas/guides/configuration-guide/openstack/skyline","h":"#skyline-console","p":1193},{"i":1200,"t":"Docker","u":"/docs/iaas/guides/configuration-guide/proxy","h":"#docker","p":1198},{"i":1202,"t":"APT","u":"/docs/iaas/guides/configuration-guide/proxy","h":"#apt","p":1198},{"i":1204,"t":"Kolla","u":"/docs/iaas/guides/configuration-guide/proxy","h":"#kolla","p":1198},{"i":1216,"t":"Configure logging drivers","u":"/docs/iaas/guides/configuration-guide/services/docker","h":"#configure-logging-drivers","p":1214},{"i":1233,"t":"Manual provisioning","u":"/docs/iaas/guides/deploy-guide/provisioning","h":"#manual-provisioning","p":1231},{"i":1237,"t":"Install required packages","u":"/docs/iaas/guides/deploy-guide/seed","h":"#install-required-packages","p":1235},{"i":1239,"t":"Get a copy of the configuration repository","u":"/docs/iaas/guides/deploy-guide/seed","h":"#get-a-copy-of-the-configuration-repository","p":1235},{"i":1247,"t":"Cluster API","u":"/docs/iaas/guides/deploy-guide/services/kubernetes","h":"#cluster-api","p":1245},{"i":1253,"t":"Deploy the manager service","u":"/docs/iaas/guides/deploy-guide/manager","h":"#deploy-the-manager-service","p":1251},{"i":1255,"t":"Step 1: Create operator user","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-1-create-operator-user","p":1251},{"i":1257,"t":"Step 2: Apply the network configuration","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-2-apply-the-network-configuration","p":1251},{"i":1259,"t":"Step 3: Bootstrap the manager node","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-3-bootstrap-the-manager-node","p":1251},{"i":1261,"t":"Step 4: Deploy the manager service","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-4-deploy-the-manager-service","p":1251},{"i":1263,"t":"Step 5: Set vault password on the manager service","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-5-set-vault-password-on-the-manager-service","p":1251},{"i":1266,"t":"Change Node states","u":"/docs/iaas/guides/operations-guide/","h":"#change-node-states","p":1265},{"i":1268,"t":"Maintenance","u":"/docs/iaas/guides/operations-guide/","h":"#maintenance","p":1265},{"i":1270,"t":"Bootstrap","u":"/docs/iaas/guides/operations-guide/","h":"#bootstrap","p":1265},{"i":1272,"t":"Use of custom plays","u":"/docs/iaas/guides/operations-guide/","h":"#use-of-custom-plays","p":1265},{"i":1274,"t":"Manage services","u":"/docs/iaas/guides/operations-guide/","h":"#manage-services","p":1265},{"i":1276,"t":"Manage containers","u":"/docs/iaas/guides/operations-guide/","h":"#manage-containers","p":1265},{"i":1278,"t":"Reboot nodes","u":"/docs/iaas/guides/operations-guide/","h":"#reboot-nodes","p":1265},{"i":1280,"t":"Working with the OOB Board via IPMI","u":"/docs/iaas/guides/operations-guide/","h":"#working-with-the-oob-board-via-ipmi","p":1265},{"i":1281,"t":"Display the IP address","u":"/docs/iaas/guides/operations-guide/","h":"#display-the-ip-address","p":1265},{"i":1287,"t":"RGW service","u":"/docs/iaas/guides/deploy-guide/services/ceph","h":"#rgw-service","p":1285},{"i":1289,"t":"Avoiding service restarts","u":"/docs/iaas/guides/deploy-guide/services/ceph","h":"#avoiding-service-restarts","p":1285},{"i":1291,"t":"Throttling service restarts","u":"/docs/iaas/guides/deploy-guide/services/ceph","h":"#throttling-service-restarts","p":1285},{"i":1296,"t":"MariaDB","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#mariadb","p":1295},{"i":1297,"t":"Backup","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#backup","p":1295},{"i":1299,"t":"Restore","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#restore","p":1295},{"i":1301,"t":"Recovery","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#recovery","p":1295},{"i":1303,"t":"Open Search","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#open-search","p":1295},{"i":1304,"t":"Get all indices","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#get-all-indices","p":1295},{"i":1306,"t":"Delete an index","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#delete-an-index","p":1295},{"i":1310,"t":"List all available plays","u":"/docs/iaas/guides/operations-guide/manager/apply","h":"#list-all-available-plays","p":1309},{"i":1313,"t":"Ansible","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#ansible","p":1312},{"i":1314,"t":"Files","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#files","p":1312},{"i":1316,"t":"ARA - ARA Records Ansible","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#ara---ara-records-ansible","p":1312},{"i":1318,"t":"Container","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#container","p":1312},{"i":1320,"t":"OpenSearch","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#opensearch","p":1312},{"i":1324,"t":"Hosts","u":"/docs/iaas/guides/operations-guide/manager/get","h":"#hosts","p":1322},{"i":1326,"t":"Host variables","u":"/docs/iaas/guides/operations-guide/manager/get","h":"#host-variables","p":1322},{"i":1328,"t":"Host facts","u":"/docs/iaas/guides/operations-guide/manager/get","h":"#host-facts","p":1322},{"i":1332,"t":"Ansible","u":"/docs/iaas/guides/operations-guide/manager/console","h":"#ansible","p":1330},{"i":1334,"t":"Clush","u":"/docs/iaas/guides/operations-guide/manager/console","h":"#clush","p":1330},{"i":1336,"t":"Container","u":"/docs/iaas/guides/operations-guide/manager/console","h":"#container","p":1330},{"i":1338,"t":"SSH","u":"/docs/iaas/guides/operations-guide/manager/console","h":"#ssh","p":1330},{"i":1341,"t":"List","u":"/docs/iaas/guides/operations-guide/manager/task","h":"#list","p":1340},{"i":1343,"t":"Broker reset","u":"/docs/iaas/guides/operations-guide/manager/task","h":"#broker-reset","p":1340},{"i":1346,"t":"Remove service","u":"/docs/iaas/guides/operations-guide/openstack/cinder","h":"#remove-service","p":1345},{"i":1348,"t":"Sync quota","u":"/docs/iaas/guides/operations-guide/openstack/cinder","h":"#sync-quota","p":1345},{"i":1350,"t":"Quality of Service (QoS)","u":"/docs/iaas/guides/operations-guide/openstack/cinder","h":"#quality-of-service-qos","p":1345},{"i":1355,"t":"Create an external network","u":"/docs/iaas/guides/operations-guide/openstack/","h":"#create-an-external-network","p":1354},{"i":1357,"t":"Reboot a compute node","u":"/docs/iaas/guides/operations-guide/openstack/","h":"#reboot-a-compute-node","p":1354},{"i":1359,"t":"Add a new compute node","u":"/docs/iaas/guides/operations-guide/openstack/","h":"#add-a-new-compute-node","p":1354},{"i":1361,"t":"Remove a compute node","u":"/docs/iaas/guides/operations-guide/openstack/","h":"#remove-a-compute-node","p":1354},{"i":1365,"t":"Open vSwitch (OVS)","u":"/docs/iaas/guides/operations-guide/network","h":"#open-vswitch-ovs","p":1363},{"i":1367,"t":"Open Virtual Network (OVN)","u":"/docs/iaas/guides/operations-guide/network","h":"#open-virtual-network-ovn","p":1363},{"i":1370,"t":"Get all servers on a node","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#get-all-servers-on-a-node","p":1369},{"i":1372,"t":"Stop all servers running on a node","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#stop-all-servers-running-on-a-node","p":1369},{"i":1374,"t":"Disable & enable a compute service","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#disable--enable-a-compute-service","p":1369},{"i":1376,"t":"Force down & up a compute service","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#force-down--up-a-compute-service","p":1369},{"i":1378,"t":"Huge pages","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#huge-pages","p":1369},{"i":1380,"t":"Quality of Service (QoS)","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#quality-of-service-qos","p":1369},{"i":1382,"t":"Host aggregates","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#host-aggregates","p":1369},{"i":1385,"t":"Cleanup of amphorae missing from the DB","u":"/docs/iaas/guides/operations-guide/openstack/octavia","h":"#cleanup-of-amphorae-missing-from-the-db","p":1384},{"i":1387,"t":"SSH access to amphorae","u":"/docs/iaas/guides/operations-guide/openstack/octavia","h":"#ssh-access-to-amphorae","p":1384},{"i":1390,"t":"Quality of Service (QoS)","u":"/docs/iaas/guides/operations-guide/openstack/neutron","h":"#quality-of-service-qos","p":1389},{"i":1394,"t":"Where to find docs","u":"/docs/iaas/guides/operations-guide/ceph","h":"#where-to-find-docs","p":1393},{"i":1396,"t":"Advice on Ceph releases","u":"/docs/iaas/guides/operations-guide/ceph","h":"#advice-on-ceph-releases","p":1393},{"i":1398,"t":"General maintenance","u":"/docs/iaas/guides/operations-guide/ceph","h":"#general-maintenance","p":1393},{"i":1399,"t":"60 seconds cluster overview","u":"/docs/iaas/guides/operations-guide/ceph","h":"#60-seconds-cluster-overview","p":1393},{"i":1401,"t":"Mute/Unmute a health warning","u":"/docs/iaas/guides/operations-guide/ceph","h":"#muteunmute-a-health-warning","p":1393},{"i":1403,"t":"Disable/Enable (deep-)scrubbing","u":"/docs/iaas/guides/operations-guide/ceph","h":"#disableenable-deep-scrubbing","p":1393},{"i":1405,"t":"Reboot a single node","u":"/docs/iaas/guides/operations-guide/ceph","h":"#reboot-a-single-node","p":1393},{"i":1407,"t":"Gathering information about block devices","u":"/docs/iaas/guides/operations-guide/ceph","h":"#gathering-information-about-block-devices","p":1393},{"i":1408,"t":"Enumerate typical storage devices and LVM","u":"/docs/iaas/guides/operations-guide/ceph","h":"#enumerate-typical-storage-devices-and-lvm","p":1393},{"i":1410,"t":"SMART data for SATA/SAS and NVME devices","u":"/docs/iaas/guides/operations-guide/ceph","h":"#smart-data-for-satasas-and-nvme-devices","p":1393},{"i":1412,"t":"Check format of a NVME device","u":"/docs/iaas/guides/operations-guide/ceph","h":"#check-format-of-a-nvme-device","p":1393},{"i":1414,"t":"Format a NVME device to a different LBA format using nvme-cli","u":"/docs/iaas/guides/operations-guide/ceph","h":"#format-a-nvme-device-to-a-different-lba-format-using-nvme-cli","p":1393},{"i":1416,"t":"Secure Erase a NVME drive using nvme-cli","u":"/docs/iaas/guides/operations-guide/ceph","h":"#secure-erase-a-nvme-drive-using-nvme-cli","p":1393},{"i":1418,"t":"Secure Erase a SATA/SAS drive using hdparm","u":"/docs/iaas/guides/operations-guide/ceph","h":"#secure-erase-a-satasas-drive-using-hdparm","p":1393},{"i":1420,"t":"OSD maintenance tasks","u":"/docs/iaas/guides/operations-guide/ceph","h":"#osd-maintenance-tasks","p":1393},{"i":1421,"t":"Locate a specific OSD in the cluster","u":"/docs/iaas/guides/operations-guide/ceph","h":"#locate-a-specific-osd-in-the-cluster","p":1393},{"i":1423,"t":"Get OSD metadata (global and single OSD)","u":"/docs/iaas/guides/operations-guide/ceph","h":"#get-osd-metadata-global-and-single-osd","p":1393},{"i":1425,"t":"Add a new OSD","u":"/docs/iaas/guides/operations-guide/ceph","h":"#add-a-new-osd","p":1393},{"i":1426,"t":"Replace a defect OSD","u":"/docs/iaas/guides/operations-guide/ceph","h":"#replace-a-defect-osd","p":1393},{"i":1427,"t":"Remove a OSD","u":"/docs/iaas/guides/operations-guide/ceph","h":"#remove-a-osd","p":1393},{"i":1429,"t":"Remove a single OSD node","u":"/docs/iaas/guides/operations-guide/ceph","h":"#remove-a-single-osd-node","p":1393},{"i":1431,"t":"Remove an OSD (temporarily e.g. when replacing a broken disk)","u":"/docs/iaas/guides/operations-guide/ceph","h":"#remove-an-osd-temporarily-eg-when-replacing-a-broken-disk","p":1393},{"i":1433,"t":"Disable backfills/recovery completely","u":"/docs/iaas/guides/operations-guide/ceph","h":"#disable-backfillsrecovery-completely","p":1393},{"i":1435,"t":"Rebalance OSDs","u":"/docs/iaas/guides/operations-guide/ceph","h":"#rebalance-osds","p":1393},{"i":1436,"t":"Placement Group maintenance","u":"/docs/iaas/guides/operations-guide/ceph","h":"#placement-group-maintenance","p":1393},{"i":1437,"t":"Dump placement groups","u":"/docs/iaas/guides/operations-guide/ceph","h":"#dump-placement-groups","p":1393},{"i":1439,"t":"Query a PG about its status","u":"/docs/iaas/guides/operations-guide/ceph","h":"#query-a-pg-about-its-status","p":1393},{"i":1441,"t":"Start (deep-)scrubbing of a placement group","u":"/docs/iaas/guides/operations-guide/ceph","h":"#start-deep-scrubbing-of-a-placement-group","p":1393},{"i":1443,"t":"HEALTH_WARN - Large omap objects found...","u":"/docs/iaas/guides/operations-guide/ceph","h":"#health_warn---large-omap-objects-found","p":1393},{"i":1445,"t":"Instruct a PG to repair in case of scrub errors (inconsistent PG)","u":"/docs/iaas/guides/operations-guide/ceph","h":"#instruct-a-pg-to-repair-in-case-of-scrub-errors-inconsistent-pg","p":1393},{"i":1447,"t":"RADOS Pool maintenance","u":"/docs/iaas/guides/operations-guide/ceph","h":"#rados-pool-maintenance","p":1393},{"i":1449,"t":"Get pools and their configuration","u":"/docs/iaas/guides/operations-guide/ceph","h":"#get-pools-and-their-configuration","p":1393},{"i":1451,"t":"Dump all CRUSH rules","u":"/docs/iaas/guides/operations-guide/ceph","h":"#dump-all-crush-rules","p":1393},{"i":1453,"t":"Get autoscaler status","u":"/docs/iaas/guides/operations-guide/ceph","h":"#get-autoscaler-status","p":1393},{"i":1455,"t":"Create a replicated pool","u":"/docs/iaas/guides/operations-guide/ceph","h":"#create-a-replicated-pool","p":1393},{"i":1457,"t":"Enabling an application on a pool","u":"/docs/iaas/guides/operations-guide/ceph","h":"#enabling-an-application-on-a-pool","p":1393},{"i":1459,"t":"Delete a pool","u":"/docs/iaas/guides/operations-guide/ceph","h":"#delete-a-pool","p":1393},{"i":1461,"t":"Set number of PGs for a pool","u":"/docs/iaas/guides/operations-guide/ceph","h":"#set-number-of-pgs-for-a-pool","p":1393},{"i":1463,"t":"Create CRUSH rules for different storage classes","u":"/docs/iaas/guides/operations-guide/ceph","h":"#create-crush-rules-for-different-storage-classes","p":1393},{"i":1465,"t":"Change CRUSH rule for a pool (\"move pool\")","u":"/docs/iaas/guides/operations-guide/ceph","h":"#change-crush-rule-for-a-pool-move-pool","p":1393},{"i":1467,"t":"Advanced topics","u":"/docs/iaas/guides/operations-guide/ceph","h":"#advanced-topics","p":1393},{"i":1468,"t":"Validating Ceph using OSISM playbooks","u":"/docs/iaas/guides/operations-guide/ceph","h":"#validating-ceph-using-osism-playbooks","p":1393},{"i":1470,"t":"Shutdown a Ceph cluster","u":"/docs/iaas/guides/operations-guide/ceph","h":"#shutdown-a-ceph-cluster","p":1393},{"i":1472,"t":"Restart a Ceph cluster after manual shutdown","u":"/docs/iaas/guides/operations-guide/ceph","h":"#restart-a-ceph-cluster-after-manual-shutdown","p":1393},{"i":1474,"t":"Performance benchmark","u":"/docs/iaas/guides/operations-guide/ceph","h":"#performance-benchmark","p":1393},{"i":1476,"t":"Where and how to get further help","u":"/docs/iaas/guides/operations-guide/ceph","h":"#where-and-how-to-get-further-help","p":1393},{"i":1479,"t":"Overview","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","h":"#overview","p":1478},{"i":1481,"t":"Installation","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","h":"#installation","p":1478},{"i":1483,"t":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","h":"#usage","p":1478},{"i":1486,"t":"Overview","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#overview","p":1485},{"i":1488,"t":"Installation","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#installation","p":1485},{"i":1490,"t":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#usage","p":1485},{"i":1492,"t":"Definitions","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#definitions","p":1485},{"i":1494,"t":"Name parser and generator","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#name-parser-and-generator","p":1485},{"i":1497,"t":"Overview","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#overview","p":1496},{"i":1499,"t":"Installation","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#installation","p":1496},{"i":1501,"t":"Defaults","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#defaults","p":1496},{"i":1502,"t":"create.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#createpy","p":1496},{"i":1504,"t":"manage.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#managepy","p":1496},{"i":1506,"t":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#usage","p":1496},{"i":1508,"t":"create.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#createpy-1","p":1496},{"i":1510,"t":"manage.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#managepy-1","p":1496},{"i":1512,"t":"Config files","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#config-files","p":1496},{"i":1514,"t":"Quota Templates","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#quota-templates","p":1496},{"i":1516,"t":"Setup Endpoints","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#setup-endpoints","p":1496},{"i":1520,"t":"Requirements","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#requirements","p":1518},{"i":1522,"t":"OpenStack Image Service (Glance)","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#openstack-image-service-glance","p":1518},{"i":1524,"t":"Object storage backend","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#object-storage-backend","p":1518},{"i":1526,"t":"Getting started","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#getting-started","p":1518},{"i":1528,"t":"Image definitions","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#image-definitions","p":1518},{"i":1530,"t":"SCS image standard","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#scs-image-standard","p":1518},{"i":1532,"t":"Image with regular rebuilds","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#image-with-regular-rebuilds","p":1518},{"i":1534,"t":"Image without regular rebuild","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#image-without-regular-rebuild","p":1518},{"i":1536,"t":"Other properties","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#other-properties","p":1518},{"i":1538,"t":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#usage","p":1518},{"i":1539,"t":"Mirroring images","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#mirroring-images","p":1518},{"i":1541,"t":"Updating images","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#updating-images","p":1518},{"i":1544,"t":"Preparations","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#preparations","p":1543},{"i":1546,"t":"Nova","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#nova","p":1543},{"i":1547,"t":"Live migration","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#live-migration","p":1543},{"i":1549,"t":"Evacuation","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#evacuation","p":1543},{"i":1551,"t":"Octavia","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#octavia","p":1543},{"i":1552,"t":"Amphora rotation","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#amphora-rotation","p":1543},{"i":1554,"t":"Cinder","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#cinder","p":1543},{"i":1556,"t":"Orphans","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#orphans","p":1543},{"i":1561,"t":"Requirements","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#requirements","p":1559},{"i":1563,"t":"Types","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#types","p":1559},{"i":1565,"t":"General notes and limitations","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#general-notes-and-limitations","p":1559},{"i":1567,"t":"Installation","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#installation","p":1559},{"i":1568,"t":"Automated installation (recommended)","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#automated-installation-recommended","p":1559},{"i":1570,"t":"Manual installation","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#manual-installation","p":1559},{"i":1572,"t":"Usage","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#usage","p":1559},{"i":1573,"t":"Wireguard VPN service access","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#wireguard-vpn-service-access","p":1559},{"i":1575,"t":"Webinterfaces","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#webinterfaces","p":1559},{"i":1577,"t":"Command-line interfaces","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#command-line-interfaces","p":1559},{"i":1579,"t":"Import of additional images","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#import-of-additional-images","p":1559},{"i":1581,"t":"Upgrade","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#upgrade","p":1559},{"i":1583,"t":"Customisations","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#customisations","p":1559},{"i":1584,"t":"Use of 2nd NIC for external network","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#use-of-2nd-nic-for-external-network","p":1559},{"i":1586,"t":"Running on a Virtual Machine","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#running-on-a-virtual-machine","p":1559},{"i":1588,"t":"Troubleshooting","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#troubleshooting","p":1559},{"i":1590,"t":"Development","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#development","p":1559},{"i":1596,"t":"Overview","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#overview","p":1595},{"i":1598,"t":"Installation","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#installation","p":1595},{"i":1600,"t":"Defaults","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#defaults","p":1595},{"i":1602,"t":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#usage","p":1595},{"i":1604,"t":"Config files","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#config-files","p":1595},{"i":1607,"t":"How to add a new service","u":"/docs/iaas/guides/other-guides/developer-guide/","h":"#how-to-add-a-new-service","p":1606},{"i":1609,"t":"How to add a new container image","u":"/docs/iaas/guides/other-guides/developer-guide/","h":"#how-to-add-a-new-container-image","p":1606},{"i":1611,"t":"How service deployment works","u":"/docs/iaas/guides/other-guides/developer-guide/","h":"#how-service-deployment-works","p":1606},{"i":1612,"t":"Docker","u":"/docs/iaas/guides/other-guides/developer-guide/","h":"#docker","p":1606},{"i":1613,"t":"Kubernetes","u":"/docs/iaas/guides/other-guides/developer-guide/","h":"#kubernetes","p":1606},{"i":1616,"t":"Intro","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#intro","p":1614},{"i":1618,"t":"Setting up the driver VM","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#setting-up-the-driver-vm","p":1614},{"i":1620,"t":"Internal vs external monitoring","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#internal-vs-external-monitoring","p":1614},{"i":1622,"t":"Unprivileged operation","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#unprivileged-operation","p":1614},{"i":1624,"t":"Driver VM via openstack CLI","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#driver-vm-via-openstack-cli","p":1614},{"i":1626,"t":"Configuring openstack CLI on the driver VM","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#configuring-openstack-cli-on-the-driver-vm","p":1614},{"i":1628,"t":"Custom CA","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#custom-ca","p":1614},{"i":1630,"t":"Your first api_monitor.sh iteration","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#your-first-api_monitorsh-iteration","p":1614},{"i":1632,"t":"Resource impact and charging","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#resource-impact-and-charging","p":1614},{"i":1634,"t":"Automating startup and cleanup","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#automating-startup-and-cleanup","p":1614},{"i":1636,"t":"Changing parameters and restarting","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#changing-parameters-and-restarting","p":1614},{"i":1638,"t":"Multiple instances","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#multiple-instances","p":1614},{"i":1640,"t":"Alarming and Logs","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#alarming-and-logs","p":1614},{"i":1641,"t":"eMail","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#email","p":1614},{"i":1643,"t":"Log files","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#log-files","p":1614},{"i":1645,"t":"Data collection and dashboard","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#data-collection-and-dashboard","p":1614},{"i":1647,"t":"telegraf","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#telegraf","p":1614},{"i":1649,"t":"influxdb","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#influxdb","p":1614},{"i":1651,"t":"Add -S CLOUDNAME to your run_CLOUDNAME.sh script","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#add--s-cloudname-to-your-run_cloudnamesh-script","p":1614},{"i":1653,"t":"grafana","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#grafana","p":1614},{"i":1655,"t":"Alternative approach to install and configure the dashboard behind a reverse proxy","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy","p":1614},{"i":1657,"t":"Maintenance","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#maintenance","p":1614},{"i":1659,"t":"Unattended upgrades","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#unattended-upgrades","p":1614},{"i":1661,"t":"Updating openstack-health-monitor","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#updating-openstack-health-monitor","p":1614},{"i":1663,"t":"Backup","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#backup","p":1614},{"i":1665,"t":"Troubleshooting","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#troubleshooting","p":1614},{"i":1666,"t":"Debugging issues","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#debugging-issues","p":1614},{"i":1668,"t":"Analyzing failures","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#analyzing-failures","p":1614},{"i":1670,"t":"Cleaning things up","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#cleaning-things-up","p":1614},{"i":1673,"t":"How we handle releases","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#how-we-handle-releases","p":1672},{"i":1675,"t":"How to make a release","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#how-to-make-a-release","p":1672},{"i":1677,"t":"Stable release","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#stable-release","p":1672},{"i":1679,"t":"How we write release notes","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#how-we-write-release-notes","p":1672},{"i":1681,"t":"Installation","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#installation","p":1672},{"i":1683,"t":"Usage","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#usage","p":1672},{"i":1685,"t":"Example","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#example","p":1672},{"i":1687,"t":"Repositories without release notes","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#repositories-without-release-notes","p":1672},{"i":1692,"t":"Ansible","u":"/docs/iaas/guides/other-guides/style-guide","h":"#ansible","p":1691},{"i":1694,"t":"Task names","u":"/docs/iaas/guides/other-guides/style-guide","h":"#task-names","p":1691},{"i":1696,"t":"become directive","u":"/docs/iaas/guides/other-guides/style-guide","h":"#become-directive","p":1691},{"i":1698,"t":"when directive","u":"/docs/iaas/guides/other-guides/style-guide","h":"#when-directive","p":1691},{"i":1700,"t":"Lists as defaults","u":"/docs/iaas/guides/other-guides/style-guide","h":"#lists-as-defaults","p":1691},{"i":1702,"t":"Containerfiles","u":"/docs/iaas/guides/other-guides/style-guide","h":"#containerfiles","p":1691},{"i":1703,"t":"Commit messages","u":"/docs/iaas/guides/other-guides/style-guide","h":"#commit-messages","p":1691},{"i":1704,"t":"Python","u":"/docs/iaas/guides/other-guides/style-guide","h":"#python","p":1691},{"i":1706,"t":"Installation","u":"/docs/iaas/guides/other-guides/style-guide","h":"#installation","p":1691},{"i":1708,"t":"Formatting a Single File","u":"/docs/iaas/guides/other-guides/style-guide","h":"#formatting-a-single-file","p":1691},{"i":1710,"t":"Formatting Multiple Files and/or directories","u":"/docs/iaas/guides/other-guides/style-guide","h":"#formatting-multiple-files-andor-directories","p":1691},{"i":1712,"t":"Formatting an Entire Project","u":"/docs/iaas/guides/other-guides/style-guide","h":"#formatting-an-entire-project","p":1691},{"i":1714,"t":"Check Mode (Dry Run)","u":"/docs/iaas/guides/other-guides/style-guide","h":"#check-mode-dry-run","p":1691},{"i":1716,"t":"Excluding Files or Directories","u":"/docs/iaas/guides/other-guides/style-guide","h":"#excluding-files-or-directories","p":1691},{"i":1718,"t":"Integration with Code Editors","u":"/docs/iaas/guides/other-guides/style-guide","h":"#integration-with-code-editors","p":1691},{"i":1720,"t":"Example of failed python-black Zuul job","u":"/docs/iaas/guides/other-guides/style-guide","h":"#example-of-failed-python-black-zuul-job","p":1691},{"i":1725,"t":"Where to find docs","u":"/docs/iaas/guides/troubleshooting-guide/ceph","h":"#where-to-find-docs","p":1724},{"i":1727,"t":"Critical medium error","u":"/docs/iaas/guides/troubleshooting-guide/ceph","h":"#critical-medium-error","p":1724},{"i":1730,"t":"Reset","u":"/docs/iaas/guides/troubleshooting-guide/manager","h":"#reset","p":1729},{"i":1733,"t":"Database creation fails","u":"/docs/iaas/guides/troubleshooting-guide/openstack","h":"#database-creation-fails","p":1732},{"i":1739,"t":"The zuul label","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#the-zuul-label","p":1737},{"i":1741,"t":"Installation","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#installation","p":1737},{"i":1742,"t":"Server preparation","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#server-preparation","p":1737},{"i":1744,"t":"Define secrets","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#define-secrets","p":1737},{"i":1746,"t":"Github App setup","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#github-app-setup","p":1737},{"i":1748,"t":"Example Playbook","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#example-playbook","p":1737},{"i":1750,"t":"Troubleshooting","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#troubleshooting","p":1737},{"i":1751,"t":"Your git repos are not displayed?","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#your-git-repos-are-not-displayed","p":1737},{"i":1753,"t":"Your git repos are using the wrong branch?","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#your-git-repos-are-using-the-wrong-branch","p":1737},{"i":1755,"t":"Your logs are not displayed in the web-UI?","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#your-logs-are-not-displayed-in-the-web-ui","p":1737},{"i":1757,"t":"Hanging jobs in a pipeline?","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#hanging-jobs-in-a-pipeline","p":1737},{"i":1765,"t":"Restart behaviour","u":"/docs/iaas/guides/upgrade-guide/docker","h":"#restart-behaviour","p":1763},{"i":1771,"t":"Requirements","u":"/docs/iaas/guides/other-guides/testbed","h":"#requirements","p":1769},{"i":1772,"t":"Cloud access","u":"/docs/iaas/guides/other-guides/testbed","h":"#cloud-access","p":1769},{"i":1774,"t":"Cloud resources","u":"/docs/iaas/guides/other-guides/testbed","h":"#cloud-resources","p":1769},{"i":1776,"t":"Software","u":"/docs/iaas/guides/other-guides/testbed","h":"#software","p":1769},{"i":1778,"t":"Deployment","u":"/docs/iaas/guides/other-guides/testbed","h":"#deployment","p":1769},{"i":1780,"t":"Usage","u":"/docs/iaas/guides/other-guides/testbed","h":"#usage","p":1769},{"i":1782,"t":"Custom CA","u":"/docs/iaas/guides/other-guides/testbed","h":"#custom-ca","p":1769},{"i":1784,"t":"VPN access","u":"/docs/iaas/guides/other-guides/testbed","h":"#vpn-access","p":1769},{"i":1786,"t":"Static entries in /etc/hosts","u":"/docs/iaas/guides/other-guides/testbed","h":"#static-entries-in-etchosts","p":1769},{"i":1788,"t":"Webinterfaces","u":"/docs/iaas/guides/other-guides/testbed","h":"#webinterfaces","p":1769},{"i":1790,"t":"Authentication with OIDC","u":"/docs/iaas/guides/other-guides/testbed","h":"#authentication-with-oidc","p":1769},{"i":1792,"t":"Advanced Usage","u":"/docs/iaas/guides/other-guides/testbed","h":"#advanced-usage","p":1769},{"i":1793,"t":"External API","u":"/docs/iaas/guides/other-guides/testbed","h":"#external-api","p":1769},{"i":1795,"t":"Change versions","u":"/docs/iaas/guides/other-guides/testbed","h":"#change-versions","p":1769},{"i":1797,"t":"Deploy services","u":"/docs/iaas/guides/other-guides/testbed","h":"#deploy-services","p":1769},{"i":1799,"t":"Upgrade services","u":"/docs/iaas/guides/other-guides/testbed","h":"#upgrade-services","p":1769},{"i":1801,"t":"Troubleshooting","u":"/docs/iaas/guides/other-guides/testbed","h":"#troubleshooting","p":1769},{"i":1802,"t":"Ansible errors","u":"/docs/iaas/guides/other-guides/testbed","h":"#ansible-errors","p":1769},{"i":1804,"t":"Unsupported locale setting","u":"/docs/iaas/guides/other-guides/testbed","h":"#unsupported-locale-setting","p":1769},{"i":1806,"t":"Appendix","u":"/docs/iaas/guides/other-guides/testbed","h":"#appendix","p":1769},{"i":1807,"t":"Configuration","u":"/docs/iaas/guides/other-guides/testbed","h":"#configuration","p":1769},{"i":1809,"t":"Notes","u":"/docs/iaas/guides/other-guides/testbed","h":"#notes","p":1769},{"i":1811,"t":"Supported releases","u":"/docs/iaas/guides/other-guides/testbed","h":"#supported-releases","p":1769},{"i":1813,"t":"Included services","u":"/docs/iaas/guides/other-guides/testbed","h":"#included-services","p":1769},{"i":1815,"t":"Makefile reference","u":"/docs/iaas/guides/other-guides/testbed","h":"#makefile-reference","p":1769},{"i":1817,"t":"CI jobs","u":"/docs/iaas/guides/other-guides/testbed","h":"#ci-jobs","p":1769},{"i":1828,"t":"Scenario","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#scenario","p":1826},{"i":1830,"t":"Requirements","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#requirements","p":1826},{"i":1832,"t":"Prechecks","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#prechecks","p":1826},{"i":1834,"t":"Migration","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#migration","p":1826},{"i":1836,"t":"How to copy vmdk images","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#how-to-copy-vmdk-images","p":1826},{"i":1838,"t":"How to convert vmdk to raw","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#how-to-convert-vmdk-to-raw","p":1826},{"i":1840,"t":"Edit the raw Images (optional)","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#edit-the-raw-images-optional","p":1826},{"i":1842,"t":"How to import Images","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#how-to-import-images","p":1826},{"i":1844,"t":"How to create your server","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#how-to-create-your-server","p":1826},{"i":1846,"t":"Show your new server","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#show-your-new-server","p":1826},{"i":1848,"t":"How to access the VNC console","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#how-to-access-the-vnc-console","p":1826},{"i":1850,"t":"Last words","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#last-words","p":1826},{"i":1854,"t":"Identify the requirements of your setup","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#identify-the-requirements-of-your-setup","p":1852},{"i":1856,"t":"Further security considerations","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#further-security-considerations","p":1852},{"i":1858,"t":"How to create security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#how-to-create-security-groups","p":1852},{"i":1860,"t":"Default security group","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#default-security-group","p":1852},{"i":1862,"t":"Recommended security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#recommended-security-groups","p":1852},{"i":1864,"t":"How to use security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#how-to-use-security-groups","p":1852},{"i":1871,"t":"Glossary","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#glossary","p":1869},{"i":1873,"t":"Scope","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#scope","p":1869},{"i":1875,"t":"Overview of applicable User Data","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#overview-of-applicable-user-data","p":1869},{"i":1877,"t":"Image backup using download","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#image-backup-using-download","p":1869},{"i":1879,"t":"Ephemeral Storage backup using Glance images","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#ephemeral-storage-backup-using-glance-images","p":1869},{"i":1881,"t":"Volume data backup using Cinder Backup API","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#volume-data-backup-using-cinder-backup-api","p":1869},{"i":1883,"t":"Backup of detached volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#backup-of-detached-volumes","p":1869},{"i":1885,"t":"Backup of attached volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#backup-of-attached-volumes","p":1869},{"i":1887,"t":"Volume data backup using Glance images","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#volume-data-backup-using-glance-images","p":1869},{"i":1889,"t":"Glance image backups of detached volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#glance-image-backups-of-detached-volumes","p":1869},{"i":1891,"t":"Glance image backups of attached (in-use) volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#glance-image-backups-of-attached-in-use-volumes","p":1869},{"i":1893,"t":"Barbican secrets backup using download","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#barbican-secrets-backup-using-download","p":1869},{"i":1895,"t":"Retrieving encryption keys from Barbican","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#retrieving-encryption-keys-from-barbican","p":1869},{"i":1897,"t":"Restore","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restore","p":1869},{"i":1899,"t":"Restoring a backup of a Barbican secret","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-backup-of-a-barbican-secret","p":1869},{"i":1901,"t":"Restoring a backup of an unencrypted image","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-backup-of-an-unencrypted-image","p":1869},{"i":1903,"t":"Restoring a backup of an encrypted image","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-backup-of-an-encrypted-image","p":1869},{"i":1905,"t":"Restoring a volume backup from an image","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-volume-backup-from-an-image","p":1869},{"i":1907,"t":"Restoring a volume backup from the Cinder Backup service","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-volume-backup-from-the-cinder-backup-service","p":1869},{"i":1909,"t":"Appendix","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#appendix","p":1869},{"i":1910,"t":"Image creation action for servers with attached volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#image-creation-action-for-servers-with-attached-volumes","p":1869},{"i":1912,"t":"LUKS encryption key conversion to decrypt volume images","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#luks-encryption-key-conversion-to-decrypt-volume-images","p":1869},{"i":1916,"t":"Identify the requirements of your setup","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#identify-the-requirements-of-your-setup","p":1914},{"i":1918,"t":"Further security considerations","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#further-security-considerations","p":1914},{"i":1920,"t":"How to create security groups","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#how-to-create-security-groups","p":1914},{"i":1922,"t":"Default security group","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#default-security-group","p":1914},{"i":1924,"t":"Recommended security groups","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#recommended-security-groups","p":1914},{"i":1926,"t":"How to use security groups","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#how-to-use-security-groups","p":1914},{"i":1938,"t":"Deployment","u":"/docs/iam/","h":"#deployment","p":1936},{"i":1940,"t":"Accessing Keycloak","u":"/docs/iam/","h":"#accessing-keycloak","p":1936},{"i":1942,"t":"Identity Mapping","u":"/docs/iam/","h":"#identity-mapping","p":1936},{"i":1944,"t":"SCS to SCS federation","u":"/docs/iam/","h":"#scs-to-scs-federation","p":1936},{"i":1946,"t":"Prerequisites and Requirements","u":"/docs/iam/","h":"#prerequisites-and-requirements","p":1936},{"i":1948,"t":"Features","u":"/docs/iam/","h":"#features","p":1936},{"i":1950,"t":"Limitations","u":"/docs/iam/","h":"#limitations","p":1936},{"i":1952,"t":"Current state and future Outlook","u":"/docs/iam/","h":"#current-state-and-future-outlook","p":1936},{"i":1956,"t":"Detailed tutorial on how to configure Federation (OpenID Connect) between two Keycloak instances in two separate SCS domains","u":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","h":"#detailed-tutorial-on-how-to-configure-federation-openid-connect-between-two-keycloak-instances-in-two-separate-scs-domains","p":1954},{"i":1964,"t":"Source","u":"/docs/operating-scs/components/automated-pentesting/overview","h":"#source","p":1962},{"i":1966,"t":"Tools","u":"/docs/operating-scs/components/automated-pentesting/overview","h":"#tools","p":1962},{"i":1969,"t":"Premise","u":"/docs/operating-scs/components/central-api/overview","h":"#premise","p":1968},{"i":1971,"t":"Challenge","u":"/docs/operating-scs/components/central-api/overview","h":"#challenge","p":1968},{"i":1973,"t":"The chosen approach to pursue","u":"/docs/operating-scs/components/central-api/overview","h":"#the-chosen-approach-to-pursue","p":1968},{"i":1975,"t":"Kubernetes API","u":"/docs/operating-scs/components/central-api/overview","h":"#kubernetes-api","p":1968},{"i":1977,"t":"Crossplane tooling","u":"/docs/operating-scs/components/central-api/overview","h":"#crossplane-tooling","p":1968},{"i":1979,"t":"Cluster stacks / Cluster API","u":"/docs/operating-scs/components/central-api/overview","h":"#cluster-stacks--cluster-api","p":1968},{"i":1981,"t":"Implementation","u":"/docs/operating-scs/components/central-api/overview","h":"#implementation","p":1968},{"i":1983,"t":"Footnotes","u":"/docs/operating-scs/components/central-api/overview","h":"#footnote-label","p":1968},{"i":1987,"t":"Glossary","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#glossary","p":1985},{"i":1989,"t":"Scope","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#scope","p":1985},{"i":1991,"t":"Overview of applicable User Data","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#overview-of-applicable-user-data","p":1985},{"i":1993,"t":"Image backup using download","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#image-backup-using-download","p":1985},{"i":1995,"t":"Ephemeral Storage backup using Glance images","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#ephemeral-storage-backup-using-glance-images","p":1985},{"i":1997,"t":"Volume data backup using Cinder Backup API","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#volume-data-backup-using-cinder-backup-api","p":1985},{"i":1999,"t":"Backup of detached volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#backup-of-detached-volumes","p":1985},{"i":2001,"t":"Backup of attached volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#backup-of-attached-volumes","p":1985},{"i":2003,"t":"Volume data backup using Glance images","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#volume-data-backup-using-glance-images","p":1985},{"i":2005,"t":"Glance image backups of detached volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#glance-image-backups-of-detached-volumes","p":1985},{"i":2007,"t":"Glance image backups of attached (in-use) volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#glance-image-backups-of-attached-in-use-volumes","p":1985},{"i":2009,"t":"Barbican secrets backup using download","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#barbican-secrets-backup-using-download","p":1985},{"i":2011,"t":"Retrieving encryption keys from Barbican","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#retrieving-encryption-keys-from-barbican","p":1985},{"i":2013,"t":"Restore","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restore","p":1985},{"i":2015,"t":"Restoring a backup of a Barbican secret","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-backup-of-a-barbican-secret","p":1985},{"i":2017,"t":"Restoring a backup of an unencrypted image","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-backup-of-an-unencrypted-image","p":1985},{"i":2019,"t":"Restoring a backup of an encrypted image","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-backup-of-an-encrypted-image","p":1985},{"i":2021,"t":"Restoring a volume backup from an image","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-volume-backup-from-an-image","p":1985},{"i":2023,"t":"Restoring a volume backup from the Cinder Backup service","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-volume-backup-from-the-cinder-backup-service","p":1985},{"i":2025,"t":"Appendix","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#appendix","p":1985},{"i":2026,"t":"Image creation action for servers with attached volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#image-creation-action-for-servers-with-attached-volumes","p":1985},{"i":2028,"t":"LUKS encryption key conversion to decrypt volume images","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#luks-encryption-key-conversion-to-decrypt-volume-images","p":1985},{"i":2032,"t":"Quick Start","u":"/docs/operating-scs/components/central-api/poc-setup","h":"#quick-start","p":2030},{"i":2036,"t":"Preface","u":"/docs/iam/domain-manager-setup-and-usage","h":"#preface","p":2034},{"i":2038,"t":"Warning regarding the exposure of domain names","u":"/docs/iam/domain-manager-setup-and-usage","h":"#warning-regarding-the-exposure-of-domain-names","p":2034},{"i":2040,"t":"Infrastructure configuration","u":"/docs/iam/domain-manager-setup-and-usage","h":"#infrastructure-configuration","p":2034},{"i":2042,"t":"[Initial] Keystone API policy adjustments","u":"/docs/iam/domain-manager-setup-and-usage","h":"#initial-keystone-api-policy-adjustments","p":2034},{"i":2044,"t":"[Initial] Keystone role creation","u":"/docs/iam/domain-manager-setup-and-usage","h":"#initial-keystone-role-creation","p":2034},{"i":2046,"t":"[Runtime] Domain Manager managed roles adjustment","u":"/docs/iam/domain-manager-setup-and-usage","h":"#runtime-domain-manager-managed-roles-adjustment","p":2034},{"i":2048,"t":"Administrative operation","u":"/docs/iam/domain-manager-setup-and-usage","h":"#administrative-operation","p":2034},{"i":2050,"t":"Creating domains","u":"/docs/iam/domain-manager-setup-and-usage","h":"#creating-domains","p":2034},{"i":2052,"t":"Creating a Domain Manager user","u":"/docs/iam/domain-manager-setup-and-usage","h":"#creating-a-domain-manager-user","p":2034},{"i":2054,"t":"Assigning the Domain Manager role to an existing user","u":"/docs/iam/domain-manager-setup-and-usage","h":"#assigning-the-domain-manager-role-to-an-existing-user","p":2034},{"i":2056,"t":"Revoking the Domain Manager role","u":"/docs/iam/domain-manager-setup-and-usage","h":"#revoking-the-domain-manager-role","p":2034},{"i":2058,"t":"Domain Manager operation","u":"/docs/iam/domain-manager-setup-and-usage","h":"#domain-manager-operation","p":2034},{"i":2060,"t":"Managing users within a domain","u":"/docs/iam/domain-manager-setup-and-usage","h":"#managing-users-within-a-domain","p":2034},{"i":2062,"t":"Managing projects within a domain","u":"/docs/iam/domain-manager-setup-and-usage","h":"#managing-projects-within-a-domain","p":2034},{"i":2064,"t":"Managing groups within a domain","u":"/docs/iam/domain-manager-setup-and-usage","h":"#managing-groups-within-a-domain","p":2034},{"i":2066,"t":"Managing role assignments within a domain","u":"/docs/iam/domain-manager-setup-and-usage","h":"#managing-role-assignments-within-a-domain","p":2034},{"i":2068,"t":"Footnotes","u":"/docs/iam/domain-manager-setup-and-usage","h":"#footnote-label","p":2034},{"i":2074,"t":"Naabu","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"#naabu","p":2072},{"i":2076,"t":"HTTPx","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"#httpx","p":2072},{"i":2078,"t":"Nuclei","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"#nuclei","p":2072},{"i":2080,"t":"Greenbone Community Edition (OpenVAS)","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"#greenbone-community-edition-openvas","p":2072},{"i":2082,"t":"ZAP Proxy","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"#zap-proxy","p":2072},{"i":2084,"t":"Defect Dojo","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"#defect-dojo","p":2072},{"i":2088,"t":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#prerequisites","p":2086},{"i":2090,"t":"Local environment use case - KinD/K3s cluster deployed locally","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#local-environment-use-case---kindk3s-cluster-deployed-locally","p":2086},{"i":2092,"t":"OSISM use case - K3s cluster in OSISM deployment","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#osism-use-case---k3s-cluster-in-osism-deployment","p":2086},{"i":2094,"t":"Deploy IaaS monitoring components","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#deploy-iaas-monitoring-components","p":2086},{"i":2095,"t":"OpenStack","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#openstack","p":2086},{"i":2097,"t":"Ceph","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#ceph","p":2086},{"i":2101,"t":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"#prerequisites","p":2099},{"i":2103,"t":"Prepare K3s Kubernetes cluster via K3d","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"#prepare-k3s-kubernetes-cluster-via-k3d","p":2099},{"i":2105,"t":"Deploy Observer monitoring solution","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"#deploy-observer-monitoring-solution","p":2099},{"i":2107,"t":"Access the Observer monitoring UIs","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"","p":2099},{"i":2113,"t":"Enable KaaS layer monitoring","u":"/docs/operating-scs/components/monitoring/docs/kaas","h":"#enable-kaas-layer-monitoring","p":2111},{"i":2115,"t":"KaaS metric importer","u":"/docs/operating-scs/components/monitoring/docs/kaas","h":"#kaas-metric-importer","p":2111},{"i":2117,"t":"KaaS mock service","u":"/docs/operating-scs/components/monitoring/docs/kaas","h":"#kaas-mock-service","p":2111},{"i":2123,"t":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"#prerequisites","p":2121},{"i":2125,"t":"Prepare Kubernetes cluster","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"#prepare-kubernetes-cluster","p":2121},{"i":2127,"t":"Deploy Observer monitoring solution","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"#deploy-observer-monitoring-solution","p":2121},{"i":2129,"t":"Access the Observer monitoring UIs","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"#access-the-observer-monitoring-uis","p":2121},{"i":2133,"t":"Architecture","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","h":"#architecture","p":2131},{"i":2135,"t":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","h":"#prerequisites","p":2131},{"i":2137,"t":"Install Observer solution","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","h":"#install-observer-solution","p":2131},{"i":2141,"t":"Example","u":"/docs/operating-scs/components/monitoring/docs/tracing","h":"#example","p":2139},{"i":2143,"t":"Usage","u":"/docs/operating-scs/components/monitoring/docs/tracing","h":"#usage","p":2139},{"i":2147,"t":"Query Frontend","u":"/docs/operating-scs/components/monitoring/docs/tuning","h":"#query-frontend","p":2145},{"i":2149,"t":"Compactor","u":"/docs/operating-scs/components/monitoring/docs/tuning","h":"#compactor","p":2145},{"i":2151,"t":"Query","u":"/docs/operating-scs/components/monitoring/docs/tuning","h":"#query","p":2145},{"i":2163,"t":"The SCS status page API","u":"/docs/operating-scs/components/status-page/docs/overview","h":"#the-scs-status-page-api","p":2161},{"i":2165,"t":"Reference implementation","u":"/docs/operating-scs/components/status-page/docs/overview","h":"#reference-implementation","p":2161},{"i":2167,"t":"The SCS status page frontend","u":"/docs/operating-scs/components/status-page/docs/overview","h":"#the-scs-status-page-frontend","p":2161},{"i":2169,"t":"Reference implementation","u":"/docs/operating-scs/components/status-page/docs/overview","h":"#reference-implementation-1","p":2161},{"i":2171,"t":"Footnotes","u":"/docs/operating-scs/components/status-page/docs/overview","h":"#footnote-label","p":2161},{"i":2187,"t":"Scope","u":"/docs/releases/Release0","h":"#scope","p":2185},{"i":2189,"t":"Features","u":"/docs/releases/Release0","h":"#features","p":2185},{"i":2191,"t":"Get SCS","u":"/docs/releases/Release0","h":"#get-scs","p":2185},{"i":2193,"t":"Known Bugs","u":"/docs/releases/Release0","h":"#known-bugs","p":2185},{"i":2195,"t":"Technical Previews","u":"/docs/releases/Release0","h":"#technical-previews","p":2185},{"i":2197,"t":"Release tagging","u":"/docs/releases/Release0","h":"#release-tagging","p":2185},{"i":2199,"t":"Updates","u":"/docs/releases/Release0","h":"#updates","p":2185},{"i":2201,"t":"Bug reporting","u":"/docs/releases/Release0","h":"#bug-reporting","p":2185},{"i":2205,"t":"Scope","u":"/docs/releases/Release1","h":"#scope","p":2203},{"i":2207,"t":"CI framework","u":"/docs/releases/Release1","h":"#ci-framework","p":2203},{"i":2208,"t":"Zuul-CI","u":"/docs/releases/Release1","h":"#zuul-ci","p":2203},{"i":2210,"t":"Metrics collection and dashboards","u":"/docs/releases/Release1","h":"#metrics-collection-and-dashboards","p":2203},{"i":2211,"t":"Prometheus exporters and Grafana dashboards","u":"/docs/releases/Release1","h":"#prometheus-exporters-and-grafana-dashboards","p":2203},{"i":2213,"t":"openstack-health-monitor","u":"/docs/releases/Release1","h":"#openstack-health-monitor","p":2203},{"i":2215,"t":"Logging","u":"/docs/releases/Release1","h":"#logging","p":2203},{"i":2216,"t":"Central logging","u":"/docs/releases/Release1","h":"#central-logging","p":2203},{"i":2218,"t":"Federation","u":"/docs/releases/Release1","h":"#federation","p":2203},{"i":2219,"t":"OIDC support via keycloak","u":"/docs/releases/Release1","h":"#oidc-support-via-keycloak","p":2203},{"i":2221,"t":"non-TLS restrictions (testbed)","u":"/docs/releases/Release1","h":"#non-tls-restrictions-testbed","p":2203},{"i":2223,"t":"Known Issue with OIDC Logout","u":"/docs/releases/Release1","h":"#known-issue-with-oidc-logout","p":2203},{"i":2225,"t":"Bare Metal Service","u":"/docs/releases/Release1","h":"#bare-metal-service","p":2203},{"i":2227,"t":"Container Layer","u":"/docs/releases/Release1","h":"#container-layer","p":2203},{"i":2228,"t":"Overview and Goals for R1","u":"/docs/releases/Release1","h":"#overview-and-goals-for-r1","p":2203},{"i":2230,"t":"Beyond CAPI","u":"/docs/releases/Release1","h":"#beyond-capi","p":2203},{"i":2232,"t":"Standardization","u":"/docs/releases/Release1","h":"#standardization","p":2203},{"i":2234,"t":"SBOM and Links","u":"/docs/releases/Release1","h":"#sbom-and-links","p":2203},{"i":2236,"t":"Release tagging","u":"/docs/releases/Release1","h":"#release-tagging","p":2203},{"i":2238,"t":"List of known issues & restrictions in R1","u":"/docs/releases/Release1","h":"#list-of-known-issues--restrictions-in-r1","p":2203},{"i":2242,"t":"Scope","u":"/docs/releases/Release2","h":"#scope","p":2240},{"i":2244,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release2","h":"#component-versions-and-user-visible-improvements-highlights","p":2240},{"i":2246,"t":"New Features (Highlights)","u":"/docs/releases/Release2","h":"#new-features-highlights","p":2240},{"i":2247,"t":"Operator focused improvements","u":"/docs/releases/Release2","h":"#operator-focused-improvements","p":2240},{"i":2249,"t":"SCS Developer focused improvements (testbed)","u":"/docs/releases/Release2","h":"#scs-developer-focused-improvements-testbed","p":2240},{"i":2251,"t":"Upgrade/Migration notes","u":"/docs/releases/Release2","h":"#upgrademigration-notes","p":2240},{"i":2252,"t":"Cluster Management","u":"/docs/releases/Release2","h":"#cluster-management","p":2240},{"i":2254,"t":"OSISM","u":"/docs/releases/Release2","h":"#osism","p":2240},{"i":2256,"t":"Removals","u":"/docs/releases/Release2","h":"#removals","p":2240},{"i":2258,"t":"Deprecations","u":"/docs/releases/Release2","h":"#deprecations","p":2240},{"i":2260,"t":"Security Fixes","u":"/docs/releases/Release2","h":"#security-fixes","p":2240},{"i":2262,"t":"Resolved Issues","u":"/docs/releases/Release2","h":"#resolved-issues","p":2240},{"i":2264,"t":"Standards Conformance","u":"/docs/releases/Release2","h":"#standards-conformance","p":2240},{"i":2266,"t":"Release Tagging","u":"/docs/releases/Release2","h":"#release-tagging","p":2240},{"i":2268,"t":"List of known issues & restrictions in R2","u":"/docs/releases/Release2","h":"#list-of-known-issues--restrictions-in-r2","p":2240},{"i":2269,"t":"Future directions (selected Highlights)","u":"/docs/releases/Release2","h":"#future-directions-selected-highlights","p":2240},{"i":2271,"t":"Contributing","u":"/docs/releases/Release2","h":"#contributing","p":2240},{"i":2275,"t":"Scope","u":"/docs/releases/Release3","h":"#scope","p":2273},{"i":2277,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release3","h":"#component-versions-and-user-visible-improvements-highlights","p":2273},{"i":2279,"t":"New Features (Highlights)","u":"/docs/releases/Release3","h":"#new-features-highlights","p":2273},{"i":2280,"t":"Operator focused improvements","u":"/docs/releases/Release3","h":"#operator-focused-improvements","p":2273},{"i":2282,"t":"SCS Developer focused improvements (testbed and k8s cluster management)","u":"/docs/releases/Release3","h":"#scs-developer-focused-improvements-testbed-and-k8s-cluster-management","p":2273},{"i":2284,"t":"Upgrade/Migration notes","u":"/docs/releases/Release3","h":"#upgrademigration-notes","p":2273},{"i":2285,"t":"Cluster Management","u":"/docs/releases/Release3","h":"#cluster-management","p":2273},{"i":2287,"t":"OSISM","u":"/docs/releases/Release3","h":"#osism","p":2273},{"i":2289,"t":"Removals","u":"/docs/releases/Release3","h":"#removals","p":2273},{"i":2291,"t":"Deprecations","u":"/docs/releases/Release3","h":"#deprecations","p":2273},{"i":2293,"t":"Security Fixes","u":"/docs/releases/Release3","h":"#security-fixes","p":2273},{"i":2295,"t":"Resolved Issues","u":"/docs/releases/Release3","h":"#resolved-issues","p":2273},{"i":2297,"t":"Standards Conformance","u":"/docs/releases/Release3","h":"#standards-conformance","p":2273},{"i":2299,"t":"Release Tagging","u":"/docs/releases/Release3","h":"#release-tagging","p":2273},{"i":2301,"t":"List of known issues & restrictions in R3","u":"/docs/releases/Release3","h":"#list-of-known-issues--restrictions-in-r3","p":2273},{"i":2303,"t":"Contributing","u":"/docs/releases/Release3","h":"#contributing","p":2273},{"i":2305,"t":"Thanks","u":"/docs/releases/Release3","h":"#thanks","p":2273},{"i":2309,"t":"Scope","u":"/docs/releases/Release4","h":"#scope","p":2307},{"i":2311,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release4","h":"#component-versions-and-user-visible-improvements-highlights","p":2307},{"i":2313,"t":"New Features (Highlights)","u":"/docs/releases/Release4","h":"#new-features-highlights","p":2307},{"i":2314,"t":"Operator focused improvements","u":"/docs/releases/Release4","h":"#operator-focused-improvements","p":2307},{"i":2316,"t":"SCS Developer focused improvements (testbed and k8s cluster management)","u":"/docs/releases/Release4","h":"#scs-developer-focused-improvements-testbed-and-k8s-cluster-management","p":2307},{"i":2318,"t":"Upgrade/Migration notes","u":"/docs/releases/Release4","h":"#upgrademigration-notes","p":2307},{"i":2320,"t":"Removals","u":"/docs/releases/Release4","h":"#removals","p":2307},{"i":2322,"t":"Deprecations","u":"/docs/releases/Release4","h":"#deprecations","p":2307},{"i":2323,"t":"Deprecations via OSISM","u":"/docs/releases/Release4","h":"#deprecations-via-osism","p":2307},{"i":2325,"t":"Security Fixes","u":"/docs/releases/Release4","h":"#security-fixes","p":2307},{"i":2327,"t":"Resolved Issues","u":"/docs/releases/Release4","h":"#resolved-issues","p":2307},{"i":2329,"t":"Standards Conformance","u":"/docs/releases/Release4","h":"#standards-conformance","p":2307},{"i":2331,"t":"Release Tagging","u":"/docs/releases/Release4","h":"#release-tagging","p":2307},{"i":2333,"t":"List of known issues & restrictions in R4","u":"/docs/releases/Release4","h":"#list-of-known-issues--restrictions-in-r4","p":2307},{"i":2335,"t":"Contributing","u":"/docs/releases/Release4","h":"#contributing","p":2307},{"i":2337,"t":"Thanks","u":"/docs/releases/Release4","h":"#thanks","p":2307},{"i":2341,"t":"Intro","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#intro","p":2339},{"i":2343,"t":"Setting up the driver VM","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#setting-up-the-driver-vm","p":2339},{"i":2345,"t":"Internal vs external monitoring","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#internal-vs-external-monitoring","p":2339},{"i":2347,"t":"Unprivileged operation","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#unprivileged-operation","p":2339},{"i":2349,"t":"Driver VM via openstack CLI","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#driver-vm-via-openstack-cli","p":2339},{"i":2351,"t":"Configuring openstack CLI on the driver VM","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#configuring-openstack-cli-on-the-driver-vm","p":2339},{"i":2353,"t":"Custom CA","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#custom-ca","p":2339},{"i":2355,"t":"Your first api_monitor.sh iteration","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#your-first-api_monitorsh-iteration","p":2339},{"i":2357,"t":"Resource impact and charging","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#resource-impact-and-charging","p":2339},{"i":2359,"t":"Automating startup and cleanup","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#automating-startup-and-cleanup","p":2339},{"i":2361,"t":"Changing parameters and restarting","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#changing-parameters-and-restarting","p":2339},{"i":2363,"t":"Multiple instances","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#multiple-instances","p":2339},{"i":2365,"t":"Alarming and Logs","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#alarming-and-logs","p":2339},{"i":2366,"t":"eMail","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#email","p":2339},{"i":2368,"t":"Log files","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#log-files","p":2339},{"i":2370,"t":"Data collection and dashboard","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#data-collection-and-dashboard","p":2339},{"i":2372,"t":"telegraf","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#telegraf","p":2339},{"i":2374,"t":"influxdb","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#influxdb","p":2339},{"i":2376,"t":"Add -S CLOUDNAME to your run_CLOUDNAME.sh script","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#add--s-cloudname-to-your-run_cloudnamesh-script","p":2339},{"i":2378,"t":"grafana","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#grafana","p":2339},{"i":2380,"t":"Alternative approach to install and configure the dashboard behind a reverse proxy","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy","p":2339},{"i":2382,"t":"Maintenance","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#maintenance","p":2339},{"i":2384,"t":"Unattended upgrades","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#unattended-upgrades","p":2339},{"i":2386,"t":"Updating openstack-health-monitor","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#updating-openstack-health-monitor","p":2339},{"i":2388,"t":"Backup","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#backup","p":2339},{"i":2390,"t":"Troubleshooting","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#troubleshooting","p":2339},{"i":2391,"t":"Debugging issues","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#debugging-issues","p":2339},{"i":2393,"t":"Analyzing failures","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#analyzing-failures","p":2339},{"i":2395,"t":"Cleaning things up","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#cleaning-things-up","p":2339},{"i":2399,"t":"Scope","u":"/docs/releases/Release5","h":"#scope","p":2397},{"i":2401,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release5","h":"#component-versions-and-user-visible-improvements-highlights","p":2397},{"i":2402,"t":"IaaS","u":"/docs/releases/Release5","h":"#iaas","p":2397},{"i":2404,"t":"Container Management","u":"/docs/releases/Release5","h":"#container-management","p":2397},{"i":2406,"t":"Preview: Cluster-Stacks","u":"/docs/releases/Release5","h":"#preview-cluster-stacks","p":2397},{"i":2408,"t":"Operations and IAM related","u":"/docs/releases/Release5","h":"#operations-and-iam-related","p":2397},{"i":2410,"t":"SCS Developer focused improvements (Cloud-in-a-Box, testbed and k8s cluster management)","u":"/docs/releases/Release5","h":"#scs-developer-focused-improvements-cloud-in-a-box-testbed-and-k8s-cluster-management","p":2397},{"i":2412,"t":"Project Infrastructure","u":"/docs/releases/Release5","h":"#project-infrastructure","p":2397},{"i":2414,"t":"Upgrade/Migration notes","u":"/docs/releases/Release5","h":"#upgrademigration-notes","p":2397},{"i":2416,"t":"Removals","u":"/docs/releases/Release5","h":"#removals","p":2397},{"i":2418,"t":"Deprecations","u":"/docs/releases/Release5","h":"#deprecations","p":2397},{"i":2419,"t":"Deprecations via OSISM","u":"/docs/releases/Release5","h":"#deprecations-via-osism","p":2397},{"i":2421,"t":"Security Fixes","u":"/docs/releases/Release5","h":"#security-fixes","p":2397},{"i":2423,"t":"Resolved Issues","u":"/docs/releases/Release5","h":"#resolved-issues","p":2397},{"i":2425,"t":"Standards Conformance","u":"/docs/releases/Release5","h":"#standards-conformance","p":2397},{"i":2427,"t":"Release Tagging","u":"/docs/releases/Release5","h":"#release-tagging","p":2397},{"i":2429,"t":"List of known issues & restrictions in R5","u":"/docs/releases/Release5","h":"#list-of-known-issues--restrictions-in-r5","p":2397},{"i":2431,"t":"Contributing","u":"/docs/releases/Release5","h":"#contributing","p":2397},{"i":2433,"t":"Thanks","u":"/docs/releases/Release5","h":"#thanks","p":2397},{"i":2437,"t":"Scope","u":"/docs/releases/ReleaseX","h":"#scope","p":2435},{"i":2438,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/ReleaseX","h":"#component-versions-and-user-visible-improvements-highlights","p":2435},{"i":2439,"t":"New Features (Highlights)","u":"/docs/releases/ReleaseX","h":"#new-features-highlights","p":2435},{"i":2440,"t":"Operator focused improvements","u":"/docs/releases/ReleaseX","h":"#operator-focused-improvements","p":2435},{"i":2441,"t":"SCS Developer focused improvements (testbed and k8s cluster management)","u":"/docs/releases/ReleaseX","h":"#scs-developer-focused-improvements-testbed-and-k8s-cluster-management","p":2435},{"i":2442,"t":"Upgrade/Migration notes","u":"/docs/releases/ReleaseX","h":"#upgrademigration-notes","p":2435},{"i":2443,"t":"Removals","u":"/docs/releases/ReleaseX","h":"#removals","p":2435},{"i":2444,"t":"Deprecations","u":"/docs/releases/ReleaseX","h":"#deprecations","p":2435},{"i":2445,"t":"Security Fixes","u":"/docs/releases/ReleaseX","h":"#security-fixes","p":2435},{"i":2446,"t":"Resolved Issues","u":"/docs/releases/ReleaseX","h":"#resolved-issues","p":2435},{"i":2447,"t":"Standards Conformance","u":"/docs/releases/ReleaseX","h":"#standards-conformance","p":2435},{"i":2448,"t":"Release Tagging","u":"/docs/releases/ReleaseX","h":"#release-tagging","p":2435},{"i":2449,"t":"List of known issues & restrictions in RX","u":"/docs/releases/ReleaseX","h":"#list-of-known-issues--restrictions-in-rx","p":2435},{"i":2450,"t":"Contributing","u":"/docs/releases/ReleaseX","h":"#contributing","p":2435},{"i":2452,"t":"Thanks","u":"/docs/releases/ReleaseX","h":"#thanks","p":2435},{"i":2455,"t":"Scope","u":"/docs/releases/Release6","h":"#scope","p":2453},{"i":2457,"t":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release6","h":"#component-versions-and-user-visible-improvements-highlights","p":2453},{"i":2458,"t":"IaaS","u":"/docs/releases/Release6","h":"#iaas","p":2453},{"i":2460,"t":"KaaS","u":"/docs/releases/Release6","h":"#kaas","p":2453},{"i":2462,"t":"Operations","u":"/docs/releases/Release6","h":"#operations","p":2453},{"i":2464,"t":"IAM","u":"/docs/releases/Release6","h":"#iam","p":2453},{"i":2466,"t":"New Features (Highlights)","u":"/docs/releases/Release6","h":"#new-features-highlights","p":2453},{"i":2467,"t":"Operator focused improvements","u":"/docs/releases/Release6","h":"#operator-focused-improvements","p":2453},{"i":2469,"t":"SCS Developer focused improvements (testbed and k8s cluster management)","u":"/docs/releases/Release6","h":"#scs-developer-focused-improvements-testbed-and-k8s-cluster-management","p":2453},{"i":2471,"t":"Preview: Domain Manager Persona","u":"/docs/releases/Release6","h":"#preview-domain-manager-persona","p":2453},{"i":2473,"t":"Preview: Central API","u":"/docs/releases/Release6","h":"#preview-central-api","p":2453},{"i":2475,"t":"Preview: Keycloak Home-IdP-discovery","u":"/docs/releases/Release6","h":"#preview-keycloak-home-idp-discovery","p":2453},{"i":2477,"t":"Upgrade/Migration notes","u":"/docs/releases/Release6","h":"#upgrademigration-notes","p":2453},{"i":2479,"t":"Removals","u":"/docs/releases/Release6","h":"#removals","p":2453},{"i":2481,"t":"Deprecations","u":"/docs/releases/Release6","h":"#deprecations","p":2453},{"i":2483,"t":"Security Fixes","u":"/docs/releases/Release6","h":"#security-fixes","p":2453},{"i":2485,"t":"Security assessment for IaaS","u":"/docs/releases/Release6","h":"#security-assessment-for-iaas","p":2453},{"i":2487,"t":"Resolved Issues","u":"/docs/releases/Release6","h":"#resolved-issues","p":2453},{"i":2488,"t":"Preview: proper scope filtering for domain list API","u":"/docs/releases/Release6","h":"#preview-proper-scope-filtering-for-domain-list-api","p":2453},{"i":2490,"t":"Documentation","u":"/docs/releases/Release6","h":"#documentation","p":2453},{"i":2492,"t":"Highlighted blog posts","u":"/docs/releases/Release6","h":"#highlighted-blog-posts","p":2453},{"i":2494,"t":"IAM","u":"/docs/releases/Release6","h":"#iam-1","p":2453},{"i":2496,"t":"Standards Conformance","u":"/docs/releases/Release6","h":"#standards-conformance","p":2453},{"i":2498,"t":"Release Tagging","u":"/docs/releases/Release6","h":"#release-tagging","p":2453},{"i":2500,"t":"List of known issues & restrictions in R6","u":"/docs/releases/Release6","h":"#list-of-known-issues--restrictions-in-r6","p":2453},{"i":2501,"t":"IaaS","u":"/docs/releases/Release6","h":"#iaas-1","p":2453},{"i":2503,"t":"KaaS","u":"/docs/releases/Release6","h":"#kaas-2","p":2453},{"i":2505,"t":"IAM","u":"/docs/releases/Release6","h":"#iam-2","p":2453},{"i":2507,"t":"Contributing","u":"/docs/releases/Release6","h":"#contributing","p":2453},{"i":2509,"t":"Thanks","u":"/docs/releases/Release6","h":"#thanks","p":2453},{"i":2517,"t":"Becoming certified","u":"/standards/certification/overview","h":"#becoming-certified","p":2515},{"i":2519,"t":"Compliant cloud environments","u":"/standards/certification/overview","h":"#compliant-cloud-environments","p":2515},{"i":2537,"t":"Supplement: Implementation and Testing Notes","u":"/standards/iaas/scs-0100","h":"#supplement-implementation-and-testing-notes","p":2535},{"i":2541,"t":"Supplement: Implementation and Testing Notes","u":"/standards/iaas/scs-0101","h":"#supplement-implementation-and-testing-notes","p":2539},{"i":2561,"t":"1. ceilometer metering configuration","u":"/docs/operating-scs/metering/meter_configuration","h":"#1-ceilometer-metering-configuration","p":2559},{"i":2563,"t":"1.1 polling.yaml","u":"/docs/operating-scs/metering/meter_configuration","h":"#11-pollingyaml","p":2559},{"i":2565,"t":"1.2 event_definitions.yaml","u":"/docs/operating-scs/metering/meter_configuration","h":"#12-event_definitionsyaml","p":2559},{"i":2567,"t":"1.3 event_pipeline.yaml","u":"/docs/operating-scs/metering/meter_configuration","h":"#13-event_pipelineyaml","p":2559},{"i":2569,"t":"1.4 pipeline.yaml","u":"/docs/operating-scs/metering/meter_configuration","h":"#14-pipelineyaml","p":2559},{"i":2616,"t":"Introduction","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#introduction","p":2615},{"i":2618,"t":"Requirements","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#requirements","p":2615},{"i":2620,"t":"Sovereign Cloud Standard documents","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#sovereign-cloud-standard-documents","p":2615},{"i":2622,"t":"Types of documents","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#types-of-documents","p":2615},{"i":2624,"t":"Document format","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#document-format","p":2615},{"i":2626,"t":"Sections","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#sections","p":2615},{"i":2628,"t":"Process","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#process","p":2615},{"i":2630,"t":"Proposal phase","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#proposal-phase","p":2615},{"i":2632,"t":"Development phase (Draft)","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#development-phase-draft","p":2615},{"i":2634,"t":"Stabilized phase (Stable)","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#stabilized-phase-stable","p":2615},{"i":2636,"t":"Deprecation phase (Deprecated)","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#deprecation-phase-deprecated","p":2615},{"i":2638,"t":"Rejection","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#rejection","p":2615},{"i":2640,"t":"Open Questions","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#open-questions","p":2615},{"i":2641,"t":"Stabilization criteria","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#stabilization-criteria","p":2615},{"i":2643,"t":"Breaking change criteria","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#breaking-change-criteria","p":2615},{"i":2645,"t":"Design Considerations","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#design-considerations","p":2615},{"i":2646,"t":"Versioning","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#versioning","p":2615},{"i":2648,"t":"Acknowledgements","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#acknowledgements","p":2615},{"i":2655,"t":"Introduction","u":"/standards/scs-0002-v1-standards-docs-org","h":"#introduction","p":2654},{"i":2657,"t":"Motivation","u":"/standards/scs-0002-v1-standards-docs-org","h":"#motivation","p":2654},{"i":2659,"t":"Suggested cleanup (step 1)","u":"/standards/scs-0002-v1-standards-docs-org","h":"#suggested-cleanup-step-1","p":2654},{"i":2662,"t":"Introduction","u":"/standards/scs-0002-v2-standards-docs-org","h":"#introduction","p":2661},{"i":2664,"t":"Motivation","u":"/standards/scs-0002-v2-standards-docs-org","h":"#motivation","p":2661},{"i":2666,"t":"Distributed Documentation","u":"/standards/scs-0002-v2-standards-docs-org","h":"#distributed-documentation","p":2661},{"i":2668,"t":"Methodology and Taxonomy","u":"/standards/scs-0002-v2-standards-docs-org","h":"#methodology-and-taxonomy","p":2661},{"i":2670,"t":"Structure Template","u":"/standards/scs-0002-v2-standards-docs-org","h":"#structure-template","p":2661},{"i":2672,"t":"Single Component/Component","u":"/standards/scs-0002-v2-standards-docs-org","h":"#single-componentcomponent","p":2661},{"i":2674,"t":"Technical Implementation","u":"/standards/scs-0002-v2-standards-docs-org","h":"#technical-implementation","p":2661},{"i":2676,"t":"Writing Style and Format – Style Guide","u":"/standards/scs-0002-v2-standards-docs-org","h":"#writing-style-and-format--style-guide","p":2661},{"i":2678,"t":"Open Questions","u":"/standards/scs-0002-v2-standards-docs-org","h":"#open-questions","p":2661},{"i":2680,"t":"Reference","u":"/standards/scs-0002-v2-standards-docs-org","h":"#reference","p":2661},{"i":2683,"t":"Introduction","u":"/standards/scs-0004-v1-achieving-certification","h":"#introduction","p":2682},{"i":2685,"t":"Motivation","u":"/standards/scs-0004-v1-achieving-certification","h":"#motivation","p":2682},{"i":2687,"t":"Regulations","u":"/standards/scs-0004-v1-achieving-certification","h":"#regulations","p":2682},{"i":2689,"t":"Design Considerations","u":"/standards/scs-0004-v1-achieving-certification","h":"#design-considerations","p":2682},{"i":2690,"t":"Open Questions","u":"/standards/scs-0004-v1-achieving-certification","h":"#open-questions","p":2682},{"i":2691,"t":"Related Documents","u":"/standards/scs-0004-v1-achieving-certification","h":"#related-documents","p":2682},{"i":2694,"t":"Introduction","u":"/standards/scs-0100-v2-flavor-naming","h":"#introduction","p":2693},{"i":2696,"t":"Motivation","u":"/standards/scs-0100-v2-flavor-naming","h":"#motivation","p":2693},{"i":2698,"t":"Design Considerations","u":"/standards/scs-0100-v2-flavor-naming","h":"#design-considerations","p":2693},{"i":2699,"t":"Type of information included","u":"/standards/scs-0100-v2-flavor-naming","h":"#type-of-information-included","p":2693},{"i":2701,"t":"Complete Proposal for systematic flavor naming","u":"/standards/scs-0100-v2-flavor-naming","h":"#complete-proposal-for-systematic-flavor-naming","p":2693},{"i":2703,"t":"Proposal Details","u":"/standards/scs-0100-v2-flavor-naming","h":"#proposal-details","p":2693},{"i":2704,"t":"[REQUIRED] CPU Suffixes","u":"/standards/scs-0100-v2-flavor-naming","h":"#required-cpu-suffixes","p":2693},{"i":2706,"t":"[REQUIRED] Memory","u":"/standards/scs-0100-v2-flavor-naming","h":"#required-memory","p":2693},{"i":2708,"t":"[OPTIONAL] Disk sizes and types","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-disk-sizes-and-types","p":2693},{"i":2710,"t":"Standard SCS flavors","u":"/standards/scs-0100-v2-flavor-naming","h":"#standard-scs-flavors","p":2693},{"i":2712,"t":"Naming policy compliance","u":"/standards/scs-0100-v2-flavor-naming","h":"#naming-policy-compliance","p":2693},{"i":2714,"t":"Validation","u":"/standards/scs-0100-v2-flavor-naming","h":"#validation","p":2693},{"i":2716,"t":"Operational tooling","u":"/standards/scs-0100-v2-flavor-naming","h":"#operational-tooling","p":2693},{"i":2718,"t":"Extensions","u":"/standards/scs-0100-v2-flavor-naming","h":"#extensions","p":2693},{"i":2720,"t":"[OPTIONAL] Hypervisor","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-hypervisor","p":2693},{"i":2722,"t":"[OPTIONAL] Hardware virtualization / Nested virtualization","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-hardware-virtualization--nested-virtualization","p":2693},{"i":2724,"t":"[OPTIONAL] CPU Architecture Details","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-cpu-architecture-details","p":2693},{"i":2726,"t":"[OPTIONAL] GPU support","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-gpu-support","p":2693},{"i":2728,"t":"[OPTIONAL] Infiniband","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-infiniband","p":2693},{"i":2730,"t":"Naming options advice","u":"/standards/scs-0100-v2-flavor-naming","h":"#naming-options-advice","p":2693},{"i":2732,"t":"Proposal Examples","u":"/standards/scs-0100-v2-flavor-naming","h":"#proposal-examples","p":2693},{"i":2734,"t":"Previous standard versions","u":"/standards/scs-0100-v2-flavor-naming","h":"#previous-standard-versions","p":2693},{"i":2736,"t":"Beyond SCS","u":"/standards/scs-0100-v2-flavor-naming","h":"#beyond-scs","p":2693},{"i":2739,"t":"Introduction","u":"/standards/scs-0100-v3-flavor-naming","h":"#introduction","p":2738},{"i":2741,"t":"Motivation","u":"/standards/scs-0100-v3-flavor-naming","h":"#motivation","p":2738},{"i":2743,"t":"Design Considerations","u":"/standards/scs-0100-v3-flavor-naming","h":"#design-considerations","p":2738},{"i":2744,"t":"Type of information included","u":"/standards/scs-0100-v3-flavor-naming","h":"#type-of-information-included","p":2738},{"i":2746,"t":"Complete Proposal for systematic flavor naming","u":"/standards/scs-0100-v3-flavor-naming","h":"#complete-proposal-for-systematic-flavor-naming","p":2738},{"i":2748,"t":"Proposal Details","u":"/standards/scs-0100-v3-flavor-naming","h":"#proposal-details","p":2738},{"i":2749,"t":"[REQUIRED] CPU Suffixes","u":"/standards/scs-0100-v3-flavor-naming","h":"#required-cpu-suffixes","p":2738},{"i":2751,"t":"[REQUIRED] Memory","u":"/standards/scs-0100-v3-flavor-naming","h":"#required-memory","p":2738},{"i":2753,"t":"[OPTIONAL] Disk sizes and types","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-disk-sizes-and-types","p":2738},{"i":2755,"t":"Naming policy compliance","u":"/standards/scs-0100-v3-flavor-naming","h":"#naming-policy-compliance","p":2738},{"i":2757,"t":"Extensions","u":"/standards/scs-0100-v3-flavor-naming","h":"#extensions","p":2738},{"i":2759,"t":"[OPTIONAL] Hypervisor","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-hypervisor","p":2738},{"i":2761,"t":"[OPTIONAL] Hardware virtualization / Nested virtualization","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-hardware-virtualization--nested-virtualization","p":2738},{"i":2763,"t":"[OPTIONAL] CPU Architecture Details","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-cpu-architecture-details","p":2738},{"i":2765,"t":"[OPTIONAL] GPU support","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-gpu-support","p":2738},{"i":2767,"t":"[OPTIONAL] Infiniband","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-infiniband","p":2738},{"i":2769,"t":"Naming options advice","u":"/standards/scs-0100-v3-flavor-naming","h":"#naming-options-advice","p":2738},{"i":2771,"t":"Proposal Examples","u":"/standards/scs-0100-v3-flavor-naming","h":"#proposal-examples","p":2738},{"i":2773,"t":"Previous standard versions","u":"/standards/scs-0100-v3-flavor-naming","h":"#previous-standard-versions","p":2738},{"i":2775,"t":"Beyond SCS","u":"/standards/scs-0100-v3-flavor-naming","h":"#beyond-scs","p":2738},{"i":2778,"t":"Introduction","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#introduction","p":2777},{"i":2780,"t":"Implementation Notes","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#implementation-notes","p":2777},{"i":2782,"t":"Operational Tooling","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#operational-tooling","p":2777},{"i":2784,"t":"Automated Tests","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#automated-tests","p":2777},{"i":2785,"t":"Errors","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#errors","p":2777},{"i":2787,"t":"Warnings","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#warnings","p":2777},{"i":2789,"t":"Implementation","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#implementation","p":2777},{"i":2791,"t":"Manual Tests","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#manual-tests","p":2777},{"i":2794,"t":"Introduction","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#introduction","p":2793},{"i":2796,"t":"Motivation","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#motivation","p":2793},{"i":2798,"t":"Overview of mandatory SCS standards","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#overview-of-mandatory-scs-standards","p":2793},{"i":2800,"t":"Lifecycle of certificate scopes","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#lifecycle-of-certificate-scopes","p":2793},{"i":2802,"t":"Machine-readability for further processing","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#machine-readability-for-further-processing","p":2793},{"i":2804,"t":"SCS Certification YAML","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#scs-certification-yaml","p":2793},{"i":2806,"t":"Prerequisite descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#prerequisite-descriptor","p":2793},{"i":2808,"t":"Version descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#version-descriptor","p":2793},{"i":2810,"t":"Standard descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#standard-descriptor","p":2793},{"i":2812,"t":"Check descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#check-descriptor","p":2793},{"i":2814,"t":"Basic Example","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#basic-example","p":2793},{"i":2816,"t":"Process","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#process","p":2793},{"i":2818,"t":"Design Considerations","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#design-considerations","p":2793},{"i":2819,"t":"File format","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#file-format","p":2793},{"i":2821,"t":"Dependency graph for certifications","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#dependency-graph-for-certifications","p":2793},{"i":2823,"t":"Tooling","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#tooling","p":2793},{"i":2825,"t":"Open Questions","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#open-questions","p":2793},{"i":2826,"t":"Acknowledgements","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#acknowledgements","p":2793},{"i":2829,"t":"Introduction","u":"/standards/scs-0100-v1-flavor-naming","h":"#introduction","p":2828},{"i":2831,"t":"Motivation","u":"/standards/scs-0100-v1-flavor-naming","h":"#motivation","p":2828},{"i":2833,"t":"Proposal","u":"/standards/scs-0100-v1-flavor-naming","h":"#proposal","p":2828},{"i":2834,"t":"Type of information included","u":"/standards/scs-0100-v1-flavor-naming","h":"#type-of-information-included","p":2828},{"i":2836,"t":"Complete Proposal","u":"/standards/scs-0100-v1-flavor-naming","h":"#complete-proposal","p":2828},{"i":2838,"t":"Proposal Details","u":"/standards/scs-0100-v1-flavor-naming","h":"#proposal-details","p":2828},{"i":2839,"t":"[REQUIRED] CPU Suffixes","u":"/standards/scs-0100-v1-flavor-naming","h":"#required-cpu-suffixes","p":2828},{"i":2841,"t":"[REQUIRED] Memory","u":"/standards/scs-0100-v1-flavor-naming","h":"#required-memory","p":2828},{"i":2843,"t":"[OPTIONAL] Disk sizes and types","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-disk-sizes-and-types","p":2828},{"i":2845,"t":"[OPTIONAL] Hypervisor","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-hypervisor","p":2828},{"i":2847,"t":"[OPTIONAL] Hardware virtualization / Nested virtualization","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-hardware-virtualization--nested-virtualization","p":2828},{"i":2849,"t":"[OPTIONAL] CPU Architecture Details","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-cpu-architecture-details","p":2828},{"i":2851,"t":"[OPTIONAL] Extra features","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-extra-features","p":2828},{"i":2853,"t":"Proposal Examples","u":"/standards/scs-0100-v1-flavor-naming","h":"#proposal-examples","p":2828},{"i":2855,"t":"Standard SCS flavors","u":"/standards/scs-0100-v1-flavor-naming","h":"#standard-scs-flavors","p":2828},{"i":2857,"t":"Naming policies","u":"/standards/scs-0100-v1-flavor-naming","h":"#naming-policies","p":2828},{"i":2859,"t":"Rationale","u":"/standards/scs-0100-v1-flavor-naming","h":"#rationale","p":2828},{"i":2861,"t":"Validation","u":"/standards/scs-0100-v1-flavor-naming","h":"#validation","p":2828},{"i":2863,"t":"Beyond SCS: Gaia-X","u":"/standards/scs-0100-v1-flavor-naming","h":"#beyond-scs-gaia-x","p":2828},{"i":2866,"t":"Introduction","u":"/standards/scs-0101-v1-entropy","h":"#introduction","p":2865},{"i":2867,"t":"Entropy in information technology","u":"/standards/scs-0101-v1-entropy","h":"#entropy-in-information-technology","p":2865},{"i":2869,"t":"Real-world uses of entropy","u":"/standards/scs-0101-v1-entropy","h":"#real-world-uses-of-entropy","p":2865},{"i":2871,"t":"Sources of entropy","u":"/standards/scs-0101-v1-entropy","h":"#sources-of-entropy","p":2865},{"i":2873,"t":"Entropy in virtual instances","u":"/standards/scs-0101-v1-entropy","h":"#entropy-in-virtual-instances","p":2865},{"i":2875,"t":"Motivation","u":"/standards/scs-0101-v1-entropy","h":"#motivation","p":2865},{"i":2877,"t":"Entropy in SCS clouds","u":"/standards/scs-0101-v1-entropy","h":"#entropy-in-scs-clouds","p":2865},{"i":2878,"t":"Flavors","u":"/standards/scs-0101-v1-entropy","h":"#flavors","p":2865},{"i":2880,"t":"Images","u":"/standards/scs-0101-v1-entropy","h":"#images","p":2865},{"i":2882,"t":"Compute nodes","u":"/standards/scs-0101-v1-entropy","h":"#compute-nodes","p":2865},{"i":2885,"t":"Motivation","u":"/standards/scs-0102-v1-image-metadata","h":"#motivation","p":2884},{"i":2887,"t":"Overview","u":"/standards/scs-0102-v1-image-metadata","h":"#overview","p":2884},{"i":2889,"t":"Naming","u":"/standards/scs-0102-v1-image-metadata","h":"#naming","p":2884},{"i":2891,"t":"Technical requirements and features","u":"/standards/scs-0102-v1-image-metadata","h":"#technical-requirements-and-features","p":2884},{"i":2893,"t":"Image handling","u":"/standards/scs-0102-v1-image-metadata","h":"#image-handling","p":2884},{"i":2894,"t":"Image updating","u":"/standards/scs-0102-v1-image-metadata","h":"#image-updating","p":2884},{"i":2896,"t":"Image Origin","u":"/standards/scs-0102-v1-image-metadata","h":"#image-origin","p":2884},{"i":2898,"t":"Image build info","u":"/standards/scs-0102-v1-image-metadata","h":"#image-build-info","p":2884},{"i":2900,"t":"Licensing / Maintenance subscription / Support","u":"/standards/scs-0102-v1-image-metadata","h":"#licensing--maintenance-subscription--support","p":2884},{"i":2902,"t":"Conformance Tests","u":"/standards/scs-0102-v1-image-metadata","h":"#conformance-tests","p":2884},{"i":2905,"t":"Implementation","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#implementation","p":2904},{"i":2907,"t":"Automated Tests","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#automated-tests","p":2904},{"i":2908,"t":"Images Sample","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#images-sample","p":2904},{"i":2910,"t":"Errors","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#errors","p":2904},{"i":2912,"t":"Warnings","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#warnings","p":2904},{"i":2914,"t":"Implementation","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#implementation-1","p":2904},{"i":2916,"t":"Manual Tests","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#manual-tests","p":2904},{"i":2919,"t":"Introduction","u":"/standards/scs-0103-v1-standard-flavors","h":"#introduction","p":2918},{"i":2920,"t":"Motivation","u":"/standards/scs-0103-v1-standard-flavors","h":"#motivation","p":2918},{"i":2922,"t":"Properties (extra specs)","u":"/standards/scs-0103-v1-standard-flavors","h":"#properties-extra-specs","p":2918},{"i":2924,"t":"Standard SCS flavors","u":"/standards/scs-0103-v1-standard-flavors","h":"#standard-scs-flavors","p":2918},{"i":2926,"t":"Mandatory","u":"/standards/scs-0103-v1-standard-flavors","h":"#mandatory","p":2918},{"i":2928,"t":"Recommended","u":"/standards/scs-0103-v1-standard-flavors","h":"#recommended","p":2918},{"i":2930,"t":"Guarantees and properties","u":"/standards/scs-0103-v1-standard-flavors","h":"#guarantees-and-properties","p":2918},{"i":2932,"t":"Remarks","u":"/standards/scs-0103-v1-standard-flavors","h":"#remarks","p":2918},{"i":2934,"t":"Conformance Tests","u":"/standards/scs-0103-v1-standard-flavors","h":"#conformance-tests","p":2918},{"i":2936,"t":"Operational tooling","u":"/standards/scs-0103-v1-standard-flavors","h":"#operational-tooling","p":2918},{"i":2938,"t":"Previous standard versions","u":"/standards/scs-0103-v1-standard-flavors","h":"#previous-standard-versions","p":2918},{"i":2941,"t":"Introduction","u":"/standards/scs-0110-v1-ssd-flavors","h":"#introduction","p":2940},{"i":2943,"t":"Motivation","u":"/standards/scs-0110-v1-ssd-flavors","h":"#motivation","p":2940},{"i":2945,"t":"Design Considerations","u":"/standards/scs-0110-v1-ssd-flavors","h":"#design-considerations","p":2940},{"i":2946,"t":"Options considered","u":"/standards/scs-0110-v1-ssd-flavors","h":"#options-considered","p":2940},{"i":2948,"t":"Decision","u":"/standards/scs-0110-v1-ssd-flavors","h":"#decision","p":2940},{"i":2950,"t":"Out of Scope","u":"/standards/scs-0110-v1-ssd-flavors","h":"#out-of-scope","p":2940},{"i":2952,"t":"Implementation note","u":"/standards/scs-0110-v1-ssd-flavors","h":"#implementation-note","p":2940},{"i":2954,"t":"Related Documents","u":"/standards/scs-0110-v1-ssd-flavors","h":"#related-documents","p":2940},{"i":2956,"t":"Conformance Tests","u":"/standards/scs-0110-v1-ssd-flavors","h":"#conformance-tests","p":2940},{"i":2959,"t":"Introduction","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#introduction","p":2958},{"i":2961,"t":"Motivation","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#motivation","p":2958},{"i":2963,"t":"Design Considerations","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#design-considerations","p":2958},{"i":2965,"t":"Options considered","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#options-considered","p":2958},{"i":2967,"t":"Open questions","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#open-questions","p":2958},{"i":2969,"t":"Decision","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#decision","p":2958},{"i":2971,"t":"Related Documents","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#related-documents","p":2958},{"i":2974,"t":"Introduction","u":"/standards/scs-0104-v1-standard-images","h":"#introduction","p":2973},{"i":2976,"t":"Motivation","u":"/standards/scs-0104-v1-standard-images","h":"#motivation","p":2973},{"i":2978,"t":"Uploading custom images","u":"/standards/scs-0104-v1-standard-images","h":"#uploading-custom-images","p":2973},{"i":2980,"t":"Standard images YAML","u":"/standards/scs-0104-v1-standard-images","h":"#standard-images-yaml","p":2973},{"i":2982,"t":"Image specification, single image","u":"/standards/scs-0104-v1-standard-images","h":"#image-specification-single-image","p":2973},{"i":2984,"t":"Image specification, class of images","u":"/standards/scs-0104-v1-standard-images","h":"#image-specification-class-of-images","p":2973},{"i":2986,"t":"Full example","u":"/standards/scs-0104-v1-standard-images","h":"#full-example","p":2973},{"i":2988,"t":"Lifecycle considerations","u":"/standards/scs-0104-v1-standard-images","h":"#lifecycle-considerations","p":2973},{"i":2989,"t":"YAML lifecycle","u":"/standards/scs-0104-v1-standard-images","h":"#yaml-lifecycle","p":2973},{"i":2991,"t":"Image lifecycle","u":"/standards/scs-0104-v1-standard-images","h":"#image-lifecycle","p":2973},{"i":2993,"t":"Conformance Tests","u":"/standards/scs-0104-v1-standard-images","h":"#conformance-tests","p":2973},{"i":2995,"t":"Operational tooling","u":"/standards/scs-0104-v1-standard-images","h":"#operational-tooling","p":2973},{"i":2998,"t":"Introduction","u":"/standards/scs-0112-v1-sonic","h":"#introduction","p":2997},{"i":3000,"t":"Motivation","u":"/standards/scs-0112-v1-sonic","h":"#motivation","p":2997},{"i":3002,"t":"SONiC as a network OS where dynamic network configuration in Openstack is required","u":"/standards/scs-0112-v1-sonic","h":"#sonic-as-a-network-os-where-dynamic-network-configuration-in-openstack-is-required","p":2997},{"i":3004,"t":"Automation and tooling for SONiC","u":"/standards/scs-0112-v1-sonic","h":"#automation-and-tooling-for-sonic","p":2997},{"i":3006,"t":"OVN for SONiC","u":"/standards/scs-0112-v1-sonic","h":"#ovn-for-sonic","p":2997},{"i":3008,"t":"Design Considerations","u":"/standards/scs-0112-v1-sonic","h":"#design-considerations","p":2997},{"i":3010,"t":"Options considered","u":"/standards/scs-0112-v1-sonic","h":"#options-considered","p":2997},{"i":3012,"t":"Open questions","u":"/standards/scs-0112-v1-sonic","h":"#open-questions","p":2997},{"i":3013,"t":"State of SONiC community?","u":"/standards/scs-0112-v1-sonic","h":"#state-of-sonic-community","p":2997},{"i":3015,"t":"Decision","u":"/standards/scs-0112-v1-sonic","h":"#decision","p":2997},{"i":3017,"t":"Related Documents","u":"/standards/scs-0112-v1-sonic","h":"#related-documents","p":2997},{"i":3020,"t":"Introduction","u":"/standards/scs-0114-v1-volume-type-standard","h":"#introduction","p":3019},{"i":3022,"t":"Glossary","u":"/standards/scs-0114-v1-volume-type-standard","h":"#glossary","p":3019},{"i":3024,"t":"Motivation","u":"/standards/scs-0114-v1-volume-type-standard","h":"#motivation","p":3019},{"i":3026,"t":"Design Considerations","u":"/standards/scs-0114-v1-volume-type-standard","h":"#design-considerations","p":3019},{"i":3028,"t":"Systematic Description of Volume Types","u":"/standards/scs-0114-v1-volume-type-standard","h":"#systematic-description-of-volume-types","p":3019},{"i":3030,"t":"Standardized Aspects","u":"/standards/scs-0114-v1-volume-type-standard","h":"#standardized-aspects","p":3019},{"i":3032,"t":"DEFAULT volume type","u":"/standards/scs-0114-v1-volume-type-standard","h":"#default-volume-type","p":3019},{"i":3034,"t":"REQUIRED volume types","u":"/standards/scs-0114-v1-volume-type-standard","h":"#required-volume-types","p":3019},{"i":3036,"t":"RECOMMENDED volume types","u":"/standards/scs-0114-v1-volume-type-standard","h":"#recommended-volume-types","p":3019},{"i":3038,"t":"OPTIONAL volume types","u":"/standards/scs-0114-v1-volume-type-standard","h":"#optional-volume-types","p":3019},{"i":3040,"t":"Implementation Details","u":"/standards/scs-0114-v1-volume-type-standard","h":"#implementation-details","p":3019},{"i":3041,"t":"Encryption","u":"/standards/scs-0114-v1-volume-type-standard","h":"#encryption","p":3019},{"i":3043,"t":"Replication","u":"/standards/scs-0114-v1-volume-type-standard","h":"#replication","p":3019},{"i":3045,"t":"Example","u":"/standards/scs-0114-v1-volume-type-standard","h":"#example","p":3019},{"i":3047,"t":"Related Documents","u":"/standards/scs-0114-v1-volume-type-standard","h":"#related-documents","p":3019},{"i":3049,"t":"Conformance Tests","u":"/standards/scs-0114-v1-volume-type-standard","h":"#conformance-tests","p":3019},{"i":3052,"t":"Motivation","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#motivation","p":3051},{"i":3054,"t":"Short Sonobuoy Introduction","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#short-sonobuoy-introduction","p":3051},{"i":3056,"t":"Design Considerations","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#design-considerations","p":3051},{"i":3058,"t":"Option 1 Golang based approach 1: Pick a framework from the Sonobuoy plugin examples","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-1-golang-based-approach-1-pick-a-framework-from-the-sonobuoy-plugin-examples","p":3051},{"i":3060,"t":"Option 2 Golang based approach 2: Reuse the Kubernetes own e2e test infrastructure and framework","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-2-golang-based-approach-2-reuse-the-kubernetes-own-e2e-test-infrastructure-and-framework","p":3051},{"i":3062,"t":"Option 3 Write Python scripts for tests","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-3-write-python-scripts-for-tests","p":3051},{"i":3064,"t":"Approaches to providing a Sonobuoy plugin image","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#approaches-to-providing-a-sonobuoy-plugin-image","p":3051},{"i":3066,"t":"Option 1 Public container registry","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-1-public-container-registry","p":3051},{"i":3068,"t":"Option 2 Local image upload","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-2-local-image-upload","p":3051},{"i":3070,"t":"Decision","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#decision","p":3051},{"i":3073,"t":"Introduction","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#introduction","p":3072},{"i":3075,"t":"Terminology","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#terminology","p":3072},{"i":3077,"t":"Default Security Groups, Custom Security Groups and default Security Group Rules","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#default-security-groups-custom-security-groups-and-default-security-group-rules","p":3072},{"i":3079,"t":"Motivation","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#motivation","p":3072},{"i":3081,"t":"Design Considerations","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#design-considerations","p":3072},{"i":3083,"t":"Further Annotations","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#further-annotations","p":3072},{"i":3085,"t":"Standard","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#standard","p":3072},{"i":3087,"t":"Example","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#example","p":3072},{"i":3089,"t":"Related Documents","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#related-documents","p":3072},{"i":3091,"t":"Conformance Tests","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#conformance-tests","p":3072},{"i":3093,"t":"Footnotes","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#footnote-label","p":3072},{"i":3096,"t":"Introduction","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#introduction","p":3095},{"i":3098,"t":"Terminology","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#terminology","p":3095},{"i":3100,"t":"Context","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#context","p":3095},{"i":3102,"t":"Reasons for and against a standard for security groups","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#reasons-for-and-against-a-standard-for-security-groups","p":3095},{"i":3104,"t":"Technical limitations","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#technical-limitations","p":3095},{"i":3106,"t":"Option 0: Pre-Requirement: default rules for the (default) security group","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#option-0-pre-requirement-default-rules-for-the-default-security-group","p":3095},{"i":3108,"t":"Option 1: operator usage of network rbac","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#option-1-operator-usage-of-network-rbac","p":3095},{"i":3110,"t":"Option 2: stay project-scoped","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#option-2-stay-project-scoped","p":3095},{"i":3112,"t":"Option 3: security-focused guide","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#option-3-security-focused-guide","p":3095},{"i":3114,"t":"Decisions","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#decisions","p":3095},{"i":3116,"t":"Consequences","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#consequences","p":3095},{"i":3118,"t":"Related Documents","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#related-documents","p":3095},{"i":3120,"t":"Footnotes","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#footnote-label","p":3095},{"i":3123,"t":"Introduction","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#introduction","p":3122},{"i":3125,"t":"Motivation","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#motivation","p":3122},{"i":3127,"t":"Decision","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#decision","p":3122},{"i":3129,"t":"Related Documents","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#related-documents","p":3122},{"i":3131,"t":"Conformance Tests","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#conformance-tests","p":3122},{"i":3134,"t":"Introduction","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#introduction","p":3133},{"i":3136,"t":"Motivation","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#motivation","p":3133},{"i":3138,"t":"Decision","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#decision","p":3133},{"i":3140,"t":"Required non-performance-related properties","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#required-non-performance-related-properties","p":3133},{"i":3142,"t":"Required performance-related properties","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#required-performance-related-properties","p":3133},{"i":3144,"t":"Related Documents","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#related-documents","p":3133},{"i":3146,"t":"Conformance Tests","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#conformance-tests","p":3133},{"i":3149,"t":"Introduction","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#introduction","p":3148},{"i":3151,"t":"Terminology","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#terminology","p":3148},{"i":3153,"t":"Motivation","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#motivation","p":3148},{"i":3155,"t":"Design considerations","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#design-considerations","p":3148},{"i":3157,"t":"OSS health check","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#oss-health-check","p":3148},{"i":3159,"t":"Required and desirable features check","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#required-and-desirable-features-check","p":3148},{"i":3161,"t":"Standard","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#standard","p":3148},{"i":3163,"t":"Related Documents","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#related-documents","p":3148},{"i":3166,"t":"Introduction","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#introduction","p":3165},{"i":3168,"t":"Motivation","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#motivation","p":3165},{"i":3170,"t":"Decision","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#decision","p":3165},{"i":3172,"t":"Related Documents","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#related-documents","p":3165},{"i":3174,"t":"Conformance Tests","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#conformance-tests","p":3165},{"i":3177,"t":"Introduction","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#introduction","p":3176},{"i":3179,"t":"Glossary","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#glossary","p":3176},{"i":3181,"t":"Motivation","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#motivation","p":3176},{"i":3183,"t":"Design considerations","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#design-considerations","p":3176},{"i":3185,"t":"Decision","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#decision","p":3176},{"i":3187,"t":"Documents","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#documents","p":3176},{"i":3190,"t":"Introduction","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#introduction","p":3189},{"i":3192,"t":"Glossary","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#glossary","p":3189},{"i":3194,"t":"Motivation","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#motivation","p":3189},{"i":3196,"t":"Design Considerations","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#design-considerations","p":3189},{"i":3198,"t":"Decision","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#decision","p":3189},{"i":3200,"t":"Conformance Tests","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#conformance-tests","p":3189},{"i":3203,"t":"Introduction","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#introduction","p":3202},{"i":3205,"t":"Motivation","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#motivation","p":3202},{"i":3207,"t":"Design Considerations","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#design-considerations","p":3202},{"i":3209,"t":"Required Features","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#required-features","p":3202},{"i":3211,"t":"Pros and Cons of Different Approaches","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#pros-and-cons-of-different-approaches","p":3202},{"i":3213,"t":"IaaS Provider (OpenStack, Hetzner, AWS)","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#iaas-provider-openstack-hetzner-aws","p":3202},{"i":3215,"t":"Local Environment (Docker, Kubevirt)","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#local-environment-docker-kubevirt","p":3202},{"i":3217,"t":"Beyond Docker: Virtual Machine based Approach","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#beyond-docker-virtual-machine-based-approach","p":3202},{"i":3219,"t":"Virtual Machine Based Approach","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#virtual-machine-based-approach","p":3202},{"i":3221,"t":"Proposed Path Forward","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#proposed-path-forward","p":3202},{"i":3223,"t":"Conclusion","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#conclusion","p":3202},{"i":3226,"t":"Introduction","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#introduction","p":3225},{"i":3228,"t":"Terminology","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#terminology","p":3225},{"i":3230,"t":"Motivation","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#motivation","p":3225},{"i":3232,"t":"Design Considerations","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#design-considerations","p":3225},{"i":3233,"t":"External CA","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#external-ca","p":3225},{"i":3235,"t":"Protected Kubernetes endpoints","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#protected-kubernetes-endpoints","p":3225},{"i":3237,"t":"Decision","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#decision","p":3225},{"i":3239,"t":"Related Documents","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#related-documents","p":3225},{"i":3241,"t":"Conformance Tests","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#conformance-tests","p":3225},{"i":3244,"t":"Introduction","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#introduction","p":3243},{"i":3246,"t":"Motivation for this document","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#motivation-for-this-document","p":3243},{"i":3248,"t":"Design Considerations","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#design-considerations","p":3243},{"i":3250,"t":"Options considered","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#options-considered","p":3243},{"i":3252,"t":"Open questions","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#open-questions","p":3243},{"i":3254,"t":"Decision","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#decision","p":3243},{"i":3256,"t":"Related Documents","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#related-documents","p":3243},{"i":3258,"t":"Conformance Tests","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#conformance-tests","p":3243},{"i":3259,"t":"Conformance Tests, OPTIONAL","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#conformance-tests-optional","p":3243},{"i":3261,"t":"Introduction","u":"/standards/scs-0215-v1-robustness-features","h":"#introduction","p":3260},{"i":3263,"t":"Glossary","u":"/standards/scs-0215-v1-robustness-features","h":"#glossary","p":3260},{"i":3265,"t":"Motivation","u":"/standards/scs-0215-v1-robustness-features","h":"#motivation","p":3260},{"i":3267,"t":"Design Considerations","u":"/standards/scs-0215-v1-robustness-features","h":"#design-considerations","p":3260},{"i":3269,"t":"Kube-API rate limiting","u":"/standards/scs-0215-v1-robustness-features","h":"#kube-api-rate-limiting","p":3260},{"i":3271,"t":"etcd maintenance","u":"/standards/scs-0215-v1-robustness-features","h":"#etcd-maintenance","p":3260},{"i":3273,"t":"etcd backup","u":"/standards/scs-0215-v1-robustness-features","h":"#etcd-backup","p":3260},{"i":3275,"t":"Certificate rotation","u":"/standards/scs-0215-v1-robustness-features","h":"#certificate-rotation","p":3260},{"i":3277,"t":"Decision","u":"/standards/scs-0215-v1-robustness-features","h":"#decision","p":3260},{"i":3279,"t":"Kube-API rate limiting","u":"/standards/scs-0215-v1-robustness-features","h":"#kube-api-rate-limiting-1","p":3260},{"i":3281,"t":"etcd compaction","u":"/standards/scs-0215-v1-robustness-features","h":"#etcd-compaction","p":3260},{"i":3283,"t":"etcd backup","u":"/standards/scs-0215-v1-robustness-features","h":"#etcd-backup-1","p":3260},{"i":3285,"t":"Certificate rotation","u":"/standards/scs-0215-v1-robustness-features","h":"#certificate-rotation-1","p":3260},{"i":3287,"t":"Related Documents","u":"/standards/scs-0215-v1-robustness-features","h":"#related-documents","p":3260},{"i":3289,"t":"Conformance Tests","u":"/standards/scs-0215-v1-robustness-features","h":"#conformance-tests","p":3260},{"i":3292,"t":"Introduction","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#introduction","p":3291},{"i":3294,"t":"Terminology","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#terminology","p":3291},{"i":3296,"t":"Motivation","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#motivation","p":3291},{"i":3298,"t":"Evaluated projects","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#evaluated-projects","p":3291},{"i":3300,"t":"Deeper look into selected projects","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#deeper-look-into-selected-projects","p":3291},{"i":3302,"t":"Decision","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#decision","p":3291},{"i":3304,"t":"Related Documents","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#related-documents","p":3291},{"i":3307,"t":"Introduction","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#introduction","p":3306},{"i":3309,"t":"Existing Applications","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#existing-applications","p":3306},{"i":3311,"t":"Decision","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#decision","p":3306},{"i":3313,"t":"Status Page Requirements","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#status-page-requirements","p":3306},{"i":3315,"t":"Comparison matrix","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#comparison-matrix","p":3306},{"i":3318,"t":"Introduction","u":"/standards/scs-0301-v1-naming-conventions","h":"#introduction","p":3317},{"i":3320,"t":"Motivation","u":"/standards/scs-0301-v1-naming-conventions","h":"#motivation","p":3317},{"i":3322,"t":"Design Considerations","u":"/standards/scs-0301-v1-naming-conventions","h":"#design-considerations","p":3317},{"i":3324,"t":"Options considered","u":"/standards/scs-0301-v1-naming-conventions","h":"#options-considered","p":3317},{"i":3326,"t":"Open questions","u":"/standards/scs-0301-v1-naming-conventions","h":"#open-questions","p":3317},{"i":3328,"t":"Decision","u":"/standards/scs-0301-v1-naming-conventions","h":"#decision","p":3317},{"i":3330,"t":"Related Documents","u":"/standards/scs-0301-v1-naming-conventions","h":"#related-documents","p":3317},{"i":3332,"t":"Conformance Tests","u":"/standards/scs-0301-v1-naming-conventions","h":"#conformance-tests","p":3317},{"i":3335,"t":"Introduction","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#introduction","p":3334},{"i":3337,"t":"Requirements","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#requirements","p":3334},{"i":3339,"t":"Motivation","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#motivation","p":3334},{"i":3341,"t":"Decision","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#decision","p":3334},{"i":3342,"t":"Common definitions","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#common-definitions","p":3334},{"i":3344,"t":"API objects","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#api-objects","p":3334},{"i":3346,"t":"API object fields","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#api-object-fields","p":3334},{"i":3348,"t":"Endpoint naming","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#endpoint-naming","p":3334},{"i":3350,"t":"Phase list","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#phase-list","p":3334},{"i":3352,"t":"Labels","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#labels","p":3334},{"i":3354,"t":"Impact","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#impact","p":3334},{"i":3356,"t":"Severity","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#severity","p":3334},{"i":3358,"t":"Component impacts","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#component-impacts","p":3334},{"i":3360,"t":"Return of POST requests","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#return-of-post-requests","p":3334},{"i":3362,"t":"Return of PATCH requestes","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#return-of-patch-requestes","p":3334},{"i":3364,"t":"PATCH vs PUT for updating resources","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#patch-vs-put-for-updating-resources","p":3334},{"i":3366,"t":"Authentication and authorization","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#authentication-and-authorization","p":3334},{"i":3369,"t":"Introduction","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#introduction","p":3368},{"i":3371,"t":"Definitions","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#definitions","p":3368},{"i":3373,"t":"Motivation","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#motivation","p":3368},{"i":3375,"t":"Design Considerations","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#design-considerations","p":3368},{"i":3377,"t":"Options","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#options","p":3368},{"i":3379,"t":"Decision","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#decision","p":3368},{"i":3381,"t":"Open questions","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#open-questions","p":3368},{"i":3383,"t":"Related Documents","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#related-documents","p":3368},{"i":3385,"t":"Conformance Tests","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#conformance-tests","p":3368},{"i":3388,"t":"Introduction","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#introduction","p":3387},{"i":3390,"t":"Motivation","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#motivation","p":3387},{"i":3392,"t":"Requirements","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#requirements","p":3387},{"i":3394,"t":"Options considered","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#options-considered","p":3387},{"i":3396,"t":"Decisions","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#decisions","p":3387},{"i":3398,"t":"Reference","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#reference","p":3387},{"i":3399,"t":"Outcome of the CSP Survey about Requirements for KaaS Observability","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#outcome-of-the-csp-survey-about-requirements-for-kaas-observability","p":3387},{"i":3402,"t":"Introduction","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#introduction","p":3401},{"i":3404,"t":"Motivation","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#motivation","p":3401},{"i":3406,"t":"Decision","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#decision","p":3401},{"i":3407,"t":"Programming Language","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#programming-language","p":3401},{"i":3409,"t":"Database","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#database","p":3401},{"i":3412,"t":"Introduction","u":"/standards/scs-0412-v1-metering-json","h":"#introduction","p":3411},{"i":3414,"t":"Motivation","u":"/standards/scs-0412-v1-metering-json","h":"#motivation","p":3411},{"i":3416,"t":"Design Considerations","u":"/standards/scs-0412-v1-metering-json","h":"#design-considerations","p":3411},{"i":3418,"t":"Options considered","u":"/standards/scs-0412-v1-metering-json","h":"#options-considered","p":3411},{"i":3420,"t":"Open questions","u":"/standards/scs-0412-v1-metering-json","h":"#open-questions","p":3411},{"i":3422,"t":"Decision","u":"/standards/scs-0412-v1-metering-json","h":"#decision","p":3411},{"i":3424,"t":"Related Documents","u":"/standards/scs-0412-v1-metering-json","h":"#related-documents","p":3411},{"i":3426,"t":"Conformance Tests","u":"/standards/scs-0412-v1-metering-json","h":"#conformance-tests","p":3411},{"i":3433,"t":"Introduction","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#introduction","p":3432},{"i":3435,"t":"Definitions","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#definitions","p":3432},{"i":3437,"t":"Motivation","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#motivation","p":3432},{"i":3439,"t":"Design Considerations","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#design-considerations","p":3432},{"i":3441,"t":"Options","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#options","p":3432},{"i":3443,"t":"Open questions","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#open-questions","p":3432},{"i":3445,"t":"Decision","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#decision","p":3432},{"i":3447,"t":"Related Documents","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#related-documents","p":3432},{"i":3449,"t":"Conformance Tests","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#conformance-tests","p":3432},{"i":3452,"t":"Introduction","u":"/standards/scs-0302-v1-domain-manager-role","h":"#introduction","p":3451},{"i":3454,"t":"Glossary","u":"/standards/scs-0302-v1-domain-manager-role","h":"#glossary","p":3451},{"i":3456,"t":"Impact","u":"/standards/scs-0302-v1-domain-manager-role","h":"#impact","p":3451},{"i":3458,"t":"Motivation","u":"/standards/scs-0302-v1-domain-manager-role","h":"#motivation","p":3451},{"i":3460,"t":"Desired Workflow","u":"/standards/scs-0302-v1-domain-manager-role","h":"#desired-workflow","p":3451},{"i":3462,"t":"Design Considerations","u":"/standards/scs-0302-v1-domain-manager-role","h":"#design-considerations","p":3451},{"i":3464,"t":"Options considered","u":"/standards/scs-0302-v1-domain-manager-role","h":"#options-considered","p":3451},{"i":3466,"t":"Open questions","u":"/standards/scs-0302-v1-domain-manager-role","h":"#open-questions","p":3451},{"i":3467,"t":"Limitations","u":"/standards/scs-0302-v1-domain-manager-role","h":"#limitations","p":3451},{"i":3469,"t":"Decision","u":"/standards/scs-0302-v1-domain-manager-role","h":"#decision","p":3451},{"i":3471,"t":"Policy adjustments","u":"/standards/scs-0302-v1-domain-manager-role","h":"#policy-adjustments","p":3451},{"i":3473,"t":"Related Documents","u":"/standards/scs-0302-v1-domain-manager-role","h":"#related-documents","p":3451},{"i":3474,"t":"\"admin\"-ness not properly scoped","u":"/standards/scs-0302-v1-domain-manager-role","h":"#admin-ness-not-properly-scoped","p":3451},{"i":3476,"t":"Consistent and Secure Default RBAC","u":"/standards/scs-0302-v1-domain-manager-role","h":"#consistent-and-secure-default-rbac","p":3451},{"i":3478,"t":"Conformance Tests","u":"/standards/scs-0302-v1-domain-manager-role","h":"#conformance-tests","p":3451},{"i":3480,"t":"Appendix","u":"/standards/scs-0302-v1-domain-manager-role","h":"#appendix","p":3451},{"i":3481,"t":"Decision Record","u":"/standards/scs-0302-v1-domain-manager-role","h":"#decision-record","p":3451},{"i":3483,"t":"Footnotes","u":"/standards/scs-0302-v1-domain-manager-role","h":"#footnote-label","p":3451},{"i":3486,"t":"Abstract","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#abstract","p":3485},{"i":3488,"t":"Terminology","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#terminology","p":3485},{"i":3490,"t":"Context","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#context","p":3485},{"i":3492,"t":"Decision","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#decision","p":3485},{"i":3494,"t":"Consequences","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#consequences","p":3485},{"i":3496,"t":"Related Documents","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#related-documents","p":3485},{"i":3499,"t":"Introduction","u":"/standards/scs-XXXX-vN-standard-template","h":"#introduction","p":3498},{"i":3501,"t":"Terminology","u":"/standards/scs-XXXX-vN-standard-template","h":"#terminology","p":3498},{"i":3503,"t":"Motivation","u":"/standards/scs-XXXX-vN-standard-template","h":"#motivation","p":3498},{"i":3505,"t":"Design Considerations","u":"/standards/scs-XXXX-vN-standard-template","h":"#design-considerations","p":3498},{"i":3507,"t":"Options considered","u":"/standards/scs-XXXX-vN-standard-template","h":"#options-considered","p":3498},{"i":3509,"t":"Open questions","u":"/standards/scs-XXXX-vN-standard-template","h":"#open-questions","p":3498},{"i":3511,"t":"Standard","u":"/standards/scs-XXXX-vN-standard-template","h":"#standard","p":3498},{"i":3513,"t":"Related Documents","u":"/standards/scs-XXXX-vN-standard-template","h":"#related-documents","p":3498},{"i":3515,"t":"Conformance Tests","u":"/standards/scs-XXXX-vN-standard-template","h":"#conformance-tests","p":3498}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/3",[0,6.403,1,3.382,2,4.916]],["t/8",[3,4.169,4,3.741,5,3.32,6,3.86]],["t/9",[6,5.238,7,6.989]],["t/11",[8,5.049,9,4.445,10,5.62]],["t/13",[11,6.606]],["t/17",[12,5.388,13,4.308,14,4.801]],["t/19",[15,8.062]],["t/20",[16,5.657]],["t/22",[17,5.93]],["t/24",[17,4.871,18,4.133]],["t/26",[19,6.273]],["t/28",[20,9.184]],["t/29",[17,4.871,18,4.133]],["t/31",[19,6.273]],["t/35",[19,4.374,21,5.931,22,5.049]],["t/36",[23,5.536,24,3.958]],["t/38",[19,3.798,21,5.151,25,5.151,26,5.561]],["t/39",[23,5.536,24,3.958]],["t/42",[3,2.99,4,2.683,15,3.5,27,3.694,28,3.5,29,3.988,30,2.236]],["t/43",[31,6.989,32,5.238]],["t/45",[33,6.131,34,6.131]],["t/47",[3,4.801,4,4.308,5,3.823]],["t/50",[31,6.989,32,5.238]],["t/52",[33,6.131,34,6.131]],["t/54",[6,5.238,7,6.989]],["t/57",[2,4.916,35,6.403,36,3.902]],["t/59",[12,4.68,37,5.151,38,3.503,39,5.561]],["t/61",[40,8.507]],["t/62",[19,5.154,41,5.328]],["t/64",[40,4.552,42,4.914,43,4.914,44,4.914,45,4.914]],["t/66",[25,4.078,46,4.403,47,4.403,48,2.807,49,4.403,50,4.403]],["t/85",[51,5.62,52,6.403,53,6.403]],["t/86",[54,4.811,55,5.536]],["t/88",[55,5.536,56,4.102]],["t/90",[55,4.08,57,5.151,58,2.806,59,5.561]],["t/92",[3,4.801,4,4.308,55,4.698]],["t/94",[30,3.591,55,4.698,60,3.716]],["t/96",[30,3.591,55,4.698,61,4.801]],["t/98",[30,3.591,58,3.231,62,6.403]],["t/104",[63,5.794,64,5.328]],["t/108",[30,2.756,65,3.096,66,3.061,67,2.692,68,3.306]],["t/110",[66,3.988,67,3.507,69,4.916]],["t/111",[30,3.119,65,3.503,66,3.463,70,3.503]],["t/113",[30,2.469,65,2.774,71,3.007,72,4.403,73,3.705,74,4.403]],["t/115",[67,3.507,71,4.374,75,3.988]],["t/117",[2,4.916,67,3.507,76,4.698]],["t/121",[77,6.989,78,6.989]],["t/123",[79,6.989,80,6.989]],["t/126",[81,9.184]],["t/128",[82,9.184]],["t/130",[83,9.184]],["t/134",[84,6.623,85,4.936]],["t/136",[86,6.131,87,7.545]],["t/138",[88,5.151,89,2.937,90,4.881,91,4.68]],["t/140",[88,6.989,92,7.545]],["t/142",[16,4.647,93,5.949]],["t/144",[16,3.944,93,5.049,94,5.049]],["t/146",[95,4.698,96,6.403,97,4.308]],["t/148",[16,4.647,98,7.545]],["t/150",[99,5.388,100,6.403,101,5.049]],["t/154",[56,4.993]],["t/156",[102,4.341,103,6.623]],["t/157",[30,2.236,65,2.512,66,2.483,102,2.294,104,3.988,105,2.926,106,3.988]],["t/159",[30,2.756,65,3.096,71,3.357,107,4.914,108,3.774]],["t/161",[30,2.756,65,3.096,76,3.606,102,2.827,109,4.552]],["t/163",[4,2.962,30,2.469,65,2.774,110,3.578,111,3.109,112,3.007]],["t/167",[113,9.184]],["t/169",[114,9.184]],["t/171",[115,9.184]],["t/173",[116,4.403,117,3.578,118,4.403,119,3.472,120,4.403,121,4.403]],["t/175",[122,9.184]],["t/177",[123,4.914,124,4.314,125,4.914,126,4.314,127,4.914]],["t/179",[30,3.119,126,7.154,128,4.881]],["t/181",[129,5.794,130,6.989]],["t/186",[131,5.561,132,5.561,133,5.561,134,5.561]],["t/190",[70,3.096,135,4.914,136,3.875,137,3.606,138,3.535]],["t/192",[70,4.754,139,7.545]],["t/194",[70,3.096,136,3.875,137,3.606,138,3.535,140,4.552]],["t/196",[70,4.754,141,7.545]],["t/197",[142,7.545,143,6.131]],["t/199",[143,6.131,144,7.545]],["t/201",[70,3.096,110,3.993,136,3.875,137,3.606,138,3.535]],["t/203",[70,3.503,137,4.08,145,5.151,146,5.151]],["t/205",[66,3.988,70,4.034,147,5.931]],["t/207",[70,4.034,148,6.403,149,3.823]],["t/209",[70,3.096,76,3.606,136,3.875,137,3.606,138,3.535]],["t/211",[70,4.034,145,5.931,150,6.403]],["t/213",[70,3.096,71,3.357,136,3.875,137,3.606,138,3.535]],["t/215",[70,4.754,151,6.623]],["t/216",[149,4.505,152,7.545]],["t/218",[151,6.623,153,7.545]],["t/220",[149,3.823,151,5.62,154,6.403]],["t/222",[70,4.034,71,4.374,147,5.931]],["t/224",[66,3.061,70,3.096,136,3.875,137,3.606,138,3.535]],["t/226",[66,3.061,70,3.096,137,3.606,138,3.535,155,4.914]],["t/228",[70,3.096,137,3.606,138,3.535,156,4.314,157,4.552]],["t/230",[28,4.881,70,3.503,138,4,157,5.151]],["t/232",[70,4.754,138,5.427]],["t/236",[37,6.989,158,7.545]],["t/237",[36,4.598,159,7.545]],["t/239",[36,4.598,160,7.545]],["t/241",[36,4.598,66,4.699]],["t/243",[161,6.989,162,7.545]],["t/244",[2,4.27,13,3.741,163,5.151,164,4.68]],["t/246",[165,5.151]],["t/250",[16,5.657]],["t/254",[129,5.794,130,6.989]],["t/258",[166,6.131,167,7.545]],["t/267",[19,3.357,168,3.774,169,4.914,170,4.136,171,4.914]],["t/269",[73,4.68,89,2.937,168,4.27,172,3.228]],["t/271",[63,4.916,168,4.916,173,4.801]],["t/277",[66,3.463,174,4.881,175,4.519,176,4.519]],["t/279",[71,3.798,177,5.561,178,5.561,179,2.979]],["t/281",[85,4.936,180,7.545]],["t/283",[179,2.979,181,4.68,182,5.561,183,3.145]],["t/285",[149,3.823,179,3.43,184,6.403]],["t/287",[56,2.168,76,2.926,179,2.136,183,2.255,185,3.988,186,3.694,187,3.988]],["t/291",[5,3.32,30,3.119,66,3.463,188,3.927]],["t/293",[71,5.154,189,6.623]],["t/297",[66,4.699,190,6.131]],["t/299",[191,4.552,192,3.875,193,4.552,194,4.914,195,4.552]],["t/301",[174,4.314,190,3.993,196,4.552,197,4.914,198,4.914]],["t/303",[17,3.173,199,4.552,200,4.552,201,4.914,202,3.774]],["t/305",[5,2.381,6,2.768,17,2.575,32,2.768,202,3.062,203,3.694,204,2.512]],["t/307",[1,2.326,202,3.381,205,4.403,206,4.403,207,3.865,208,2.843]],["t/310",[209,6.179]],["t/312",[]],["t/314",[4,6.179]],["t/316",[168,4.27,210,5.561,211,5.561,212,3.798]],["t/318",[19,6.273]],["t/320",[170,7.729]],["t/322",[213,8.507]],["t/324",[214,7.242]],["t/328",[48,4.811,215,7.545]],["t/330",[]],["t/332",[56,4.102,209,5.076]],["t/334",[216,6.375]],["t/336",[217,6.886]],["t/338",[218,5.151,219,4.385,220,4.881,221,5.151]],["t/341",[]],["t/343",[54,4.811,64,5.328]],["t/345",[89,2.937,149,3.32,208,3.59,222,4.519]],["t/346",[188,5.328,223,5.536]],["t/348",[223,5.536,224,5.427]],["t/350",[1,2.937,13,3.741,225,4.881,226,5.561]],["t/352",[1,3.985,111,5.328]],["t/354",[38,4.754,227,6.623]],["t/356",[61,5.657,228,6.989]],["t/358",[229,4.871,230,7.545]],["t/360",[165,3.591,183,3.621,231,4.801]],["t/365",[232,4.786]],["t/367",[1,2.326,66,2.742,165,2.469,175,3.578,176,3.578,233,4.403]],["t/369",[1,2.326,71,3.007,175,3.578,176,3.578,234,4.403,235,3.865]],["t/371",[76,3.606,179,2.633,236,4.914,237,4.914,238,3.774]],["t/373",[110,3.993,179,2.633,239,4.314,240,4.914,241,4.314]],["t/375",[149,5.484]],["t/376",[67,2.184,89,2.106,149,2.381,165,2.236,175,3.24,176,3.24,242,3.988]],["t/378",[102,3.199,112,3.798,165,3.119,243,4.881]],["t/380",[89,2.106,149,2.381,175,3.24,176,3.24,179,2.136,238,3.062,244,3.988]],["t/384",[245,4.916,246,5.931,247,4.801]],["t/386",[111,5.328,246,6.989]],["t/388",[248,6.989,249,7.545]],["t/390",[24,3.359,250,4.308,251,5.62]],["t/392",[207,4.314,252,4.914,253,4.914,254,4.552,255,4.552]],["t/395",[256,7.545,257,5.794]],["t/397",[257,5.794,258,7.545]],["t/403",[33,5.203,259,6.403,260,6.403]],["t/406",[209,6.179]],["t/408",[75,3.988,102,3.683,261,6.403]],["t/410",[24,2.917,250,3.741,262,5.151,263,5.561]],["t/412",[22,5.949,102,4.341]],["t/414",[89,2.106,102,2.294,156,3.5,264,3.988,265,3.988,266,3.988,267,3.988]],["t/418",[209,6.179]],["t/420",[24,3.958,268,5.536]],["t/422",[10,4.881,269,5.151,270,5.151,271,5.151]],["t/424",[166,6.131,272,6.35]],["t/426",[112,5.154,272,6.35]],["t/431",[209,6.179]],["t/433",[22,4.385,102,3.199,224,4,273,4.68]],["t/439",[209,6.179]],["t/441",[22,5.949,102,4.341]],["t/445",[32,4.445,212,4.374,223,4.698]],["t/446",[262,8.507]],["t/448",[274,6.623,275,7.545]],["t/450",[273,5.388,276,6.403,277,5.62]],["t/452",[18,4.133,278,7.545]],["t/453",[243,4.881,279,4.519,280,5.561,281,5.561]],["t/455",[282,9.184]],["t/457",[283,9.184]],["t/463",[209,6.179]],["t/464",[24,3.958,268,5.536]],["t/466",[10,4.881,269,5.151,270,5.151,271,5.151]],["t/468",[166,6.131,272,6.35]],["t/470",[112,5.154,272,6.35]],["t/473",[22,5.049,284,3.455,285,4.916]],["t/475",[22,5.049,285,4.916,286,4.308]],["t/478",[23,4.698,287,5.049,288,4.188]],["t/480",[54,2.807,95,3.231,289,4.403,290,4.403,291,3.056,292,4.403]],["t/482",[95,4.08,112,3.798,293,5.151,294,2.74]],["t/484",[24,2.578,95,3.606,112,3.357,294,2.422,295,4.552]],["t/486",[24,3.958,95,5.536]],["t/490",[60,5.331]],["t/492",[170,7.729]],["t/494",[214,7.242]],["t/496",[296,7.242]],["t/498",[214,5.949,297,5.427]],["t/504",[3,4.169,117,4.519,294,2.74,298,5.151]],["t/506",[3,4.801,117,5.203,173,4.801]],["t/508",[299,5.388,300,5.388,301,5.62]],["t/510",[99,4.68,302,4.27,303,3.688,304,3.741]],["t/516",[56,4.993]],["t/518",[291,5.238,305,5.794]],["t/520",[24,3.359,179,3.43,250,4.308]],["t/522",[306,8.507]],["t/524",[57,6.989,307,5.949]],["t/528",[173,5.657,308,6.35]],["t/529",[172,4.38,250,5.076]],["t/531",[172,4.38,309,7.545]],["t/533",[172,4.38,310,6.623]],["t/535",[5,4.505,172,4.38]],["t/537",[172,4.38,311,7.545]],["t/539",[172,4.38,312,5.328]],["t/541",[172,4.38,313,6.623]],["t/543",[172,3.716,208,4.134,314,6.403]],["t/545",[172,3.716,208,4.134,315,6.403]],["t/547",[306,8.507]],["t/549",[172,4.38,316,6.35]],["t/551",[172,4.38,317,7.545]],["t/553",[172,4.38,318,7.545]],["t/555",[179,4.042,308,6.35]],["t/556",[172,4.38,319,5.427]],["t/558",[172,3.716,319,4.606,320,5.931]],["t/560",[172,3.716,183,3.621,319,4.606]],["t/562",[9,4.445,172,3.716,319,4.606]],["t/564",[172,3.716,319,4.606,321,6.403]],["t/566",[308,6.35,322,7.545]],["t/567",[172,4.38,323,7.545]],["t/569",[172,4.38,324,5.794]],["t/571",[172,4.38,325,6.131]],["t/573",[172,3.716,219,5.049,326,6.403]],["t/575",[172,3.716,327,5.931,328,5.203]],["t/577",[172,4.38,329,6.989]],["t/579",[97,5.076,172,4.38]],["t/582",[24,2.31,69,3.381,330,3.865,331,3.705,332,4.403,333,3.381]],["t/585",[156,3.865,166,3.578,231,3.301,268,3.231,334,4.078,335,4.403]],["t/587",[231,4.801,334,5.931,336,5.931]],["t/589",[24,2.917,208,3.59,337,4.881,338,4.68]],["t/591",[24,3.958,219,5.949]],["t/593",[339,5.949,340,5.328]],["t/595",[284,4.071,341,7.545]],["t/599",[24,3.585,119,3.472,251,3.865,294,2.17,342,3.167]],["t/601",[41,4.522,294,3.155,342,4.606]],["t/603",[343,7.545,344,5.657]],["t/605",[345,6.403,346,5.931,347,4.522]],["t/607",[24,3.359,41,4.522,251,5.62]],["t/608",[23,4.698,288,4.188,344,4.801]],["t/610",[55,4.08,288,3.637,348,3.741,349,3.927]],["t/612",[58,2.806,288,3.637,348,3.741,349,3.927]],["t/614",[339,5.049,350,6.403,351,4.801]],["t/618",[291,6.375]],["t/620",[2,4.916,15,5.62,291,4.445]],["t/622",[291,5.238,352,7.545]],["t/624",[291,5.238,297,5.427]],["t/634",[24,1.912,60,3.414,89,1.925,273,3.066,353,3.375,354,3.199,355,3.644]],["t/640",[208,4.871,304,5.076]],["t/642",[58,3.808,60,4.38]],["t/643",[356,9.184]],["t/645",[298,6.989,357,6.989]],["t/651",[358,7.463]],["t/657",[359,7.463]],["t/659",[65,5.786]],["t/663",[359,7.463]],["t/664",[209,6.179]],["t/666",[65,5.786]],["t/689",[1,3.985,360,7.545]],["t/691",[1,3.985,361,7.545]],["t/693",[1,3.985,362,6.35]],["t/695",[13,3.741,165,3.119,291,3.86,363,5.151]],["t/697",[1,3.382,165,3.591,364,5.388]],["t/699",[1,2.106,13,2.683,291,2.768,365,3.356,366,3.694,367,3.694,368,3.988]],["t/701",[1,2.106,13,2.683,89,2.106,291,2.768,369,3.694,370,3.988,371,3.988]],["t/703",[11,4.606,372,4.246,373,5.62]],["t/705",[1,2.326,11,3.167,89,2.326,363,4.078,372,2.92,374,4.078]],["t/707",[11,3.167,89,2.326,188,3.109,189,3.865,223,3.231,372,2.92]],["t/709",[188,5.328,373,6.623]],["t/711",[51,5.62,188,4.522,223,4.698]],["t/713",[189,4.881,223,4.08,224,4,373,4.881]],["t/715",[1,2.596,4,3.306,128,4.314,375,4.314,376,4.914]],["t/717",[1,2.596,4,3.306,13,3.306,89,2.596,375,4.314]],["t/719",[1,2.106,4,2.683,13,2.683,89,2.106,369,3.694,375,3.5,377,3.694]],["t/721",[69,4.27,364,4.68,378,5.151,379,5.151]],["t/725",[54,5.856]],["t/727",[102,5.284]],["t/729",[16,5.657]],["t/731",[380,5.93]],["t/733",[85,4.188,173,4.801,381,5.931]],["t/737",[380,4.871,382,7.545]],["t/739",[380,4.134,383,5.931,384,6.403]],["t/741",[342,4.606,380,4.134,385,5.931]],["t/743",[380,4.871,386,7.545]],["t/745",[257,4.916,380,4.134,387,4.801]],["t/747",[257,4.916,380,4.134,388,3.944]],["t/749",[380,4.134,388,3.944,389,4.522]],["t/751",[294,3.155,380,4.134,388,3.944]],["t/753",[300,5.388,380,4.134,390,4.374]],["t/755",[204,4.754,380,4.871]],["t/757",[200,8.507]],["t/759",[391,6.989,392,7.545]],["t/761",[190,7.463]],["t/763",[393,6.486]],["t/765",[394,5.597]],["t/767",[395,6.606]],["t/769",[396,8.062]],["t/771",[397,9.184]],["t/773",[398,7.052]],["t/775",[399,9.184]],["t/777",[395,5.427,400,5.427]],["t/779",[401,8.507]],["t/783",[56,4.993]],["t/785",[5,3.32,18,3.046,393,3.927,402,2.679]],["t/787",[8,5.049,9,4.445,403,5.931]],["t/789",[3,5.657,4,5.076]],["t/791",[380,4.871,402,3.635]],["t/793",[1,3.382,165,3.591,402,3.085]],["t/795",[402,3.085,404,5.388,405,5.388]],["t/797",[402,2.679,404,4.68,405,4.68,406,4.881]],["t/799",[407,7.242]],["t/801",[16,5.657]],["t/802",[402,3.635,408,6.989]],["t/804",[41,5.328,402,3.635]],["t/807",[54,5.856]],["t/809",[102,5.284]],["t/811",[304,6.179]],["t/812",[409,7.729]],["t/814",[410,7.729]],["t/816",[16,5.657]],["t/818",[409,7.729]],["t/820",[410,7.729]],["t/822",[411,6.131,412,5.154]],["t/824",[331,6.35,413,6.623]],["t/826",[414,6.131,415,5.794]],["t/829",[305,7.052]],["t/831",[396,8.062]],["t/832",[359,6.131,416,6.989]],["t/834",[417,8.507]],["t/836",[418,8.507]],["t/837",[358,6.131,419,6.35]],["t/839",[398,7.052]],["t/841",[420,8.507]],["t/845",[54,5.856]],["t/847",[102,5.284]],["t/849",[16,5.657]],["t/852",[54,5.856]],["t/854",[102,5.284]],["t/856",[304,6.179]],["t/858",[16,5.657]],["t/860",[411,6.131,412,5.154]],["t/863",[54,4.811,421,7.545]],["t/864",[24,3.958,349,5.328]],["t/866",[56,4.993]],["t/867",[24,3.958,223,5.536]],["t/869",[24,3.958,422,4.462]],["t/871",[89,3.985,222,6.131]],["t/873",[423,5.388,424,6.403,425,6.403]],["t/881",[294,2.74,394,3.389,395,4,426,3.503]],["t/884",[24,2.578,204,3.096,294,2.422,394,2.995,426,3.096]],["t/885",[5,3.32,24,2.917,204,3.503,427,5.561]],["t/886",[1,2.596,24,3.9,164,4.136,204,3.096]],["t/889",[294,2.74,394,3.389,426,3.503,428,5.561]],["t/891",[294,2.74,394,3.389,426,3.503,429,4.881]],["t/894",[430,8.062]],["t/896",[245,4.27,247,4.169,431,4,432,4.08]],["t/898",[119,4.385,303,3.688,433,4.881,434,4.27]],["t/900",[75,4.699,435,6.623]],["t/902",[5,2.934,6,3.411,105,3.606,431,3.535,432,3.606]],["t/904",[5,2.934,6,3.411,60,2.853,431,3.535,432,3.606]],["t/906",[297,5.427,436,6.131]],["t/908",[437,5.62,438,5.62,439,5.62]],["t/910",[14,4.801,440,5.049,441,5.62]],["t/912",[442,4.916,443,5.62,444,5.203]],["t/914",[95,4.698,351,4.801,445,4.916]],["t/916",[285,5.794,446,6.35]],["t/918",[312,5.328,447,6.623]],["t/919",[448,8.062]],["t/921",[312,5.328,412,5.154]],["t/923",[93,5.049,212,4.374,449,4.606]],["t/925",[450,8.062]],["t/927",[451,8.062]],["t/929",[238,3.774,452,3.774,453,4.314,454,4.314,455,4.314]],["t/931",[456,7.463]],["t/933",[60,2.115,102,2.096,279,2.961,347,2.573,362,3.066,449,2.621,457,3.066,458,3.199]],["t/935",[340,6.486]],["t/937",[344,5.657,459,6.623]],["t/939",[5,3.32,41,3.927,302,4.27,303,3.688]],["t/941",[284,4.956]],["t/943",[460,7.242]],["t/944",[38,4.754,338,6.35]],["t/946",[461,6.623,462,6.623]],["t/948",[143,5.203,247,4.801,316,5.388]],["t/951",[192,4.385,294,2.74,394,3.389,426,3.503]],["t/953",[5,3.32,294,2.74,394,3.389,426,3.503]],["t/957",[294,2.74,394,3.389,426,3.503,463,5.561]],["t/959",[294,2.74,394,3.389,426,3.503,464,5.151]],["t/960",[294,2.74,394,3.389,426,3.503,456,4.519]],["t/962",[294,2.74,394,3.389,426,3.503,465,5.561]],["t/964",[30,2.756,294,2.422,394,2.995,426,3.096,466,3.993]],["t/965",[30,2.044,36,2.221,294,1.796,299,3.066,390,2.489,394,2.221,426,2.296,467,2.674]],["t/966",[30,2.236,36,2.43,294,1.965,394,2.43,426,2.512,468,3.694,469,3.694]],["t/968",[294,2.74,394,3.389,426,3.503,470,5.561]],["t/971",[64,5.328,389,5.328]],["t/972",[9,5.238,64,5.328]],["t/973",[64,5.328,390,5.154]],["t/974",[64,5.328,471,6.989]],["t/975",[64,4.522,257,4.916,387,4.801]],["t/978",[294,2.422,394,2.995,426,3.096,472,4.914,473,4.914]],["t/981",[257,5.794,388,4.647]],["t/983",[388,4.647,389,5.328]],["t/985",[9,5.238,388,4.647]],["t/987",[388,4.647,390,5.154]],["t/989",[294,3.718,388,4.647]],["t/991",[474,7.729]],["t/992",[294,3.718,474,6.35]],["t/994",[474,6.35,475,7.545]],["t/996",[474,6.35,476,7.545]],["t/998",[390,4.374,477,5.388,478,6.403]],["t/1000",[387,5.657,389,5.328]],["t/1001",[257,5.794,387,5.657]],["t/1002",[212,5.154,387,5.657]],["t/1003",[294,3.718,387,5.657]],["t/1004",[303,5.004,387,5.657]],["t/1005",[387,5.657,390,5.154]],["t/1010",[479,5.561,480,5.561,481,4.68,482,5.561]],["t/1015",[277,5.62,483,5.388,484,5.62]],["t/1016",[485,9.184]],["t/1018",[486,9.184]],["t/1020",[344,5.657,484,6.623]],["t/1026",[4,3.741,18,3.046,56,3.023,487,4.68]],["t/1028",[18,3.507,488,4.246,489,6.403]],["t/1036",[411,6.131,490,6.35]],["t/1038",[149,5.484]],["t/1040",[304,6.179]],["t/1046",[294,4.526]],["t/1048",[491,9.184]],["t/1049",[342,5.427,492,6.989]],["t/1050",[48,4.811,492,6.989]],["t/1051",[388,3.944,493,5.931,494,5.931]],["t/1054",[301,6.623,495,6.623]],["t/1058",[60,3.228,108,4.27,250,3.741,348,3.741]],["t/1060",[65,4.034,66,3.988,305,4.916]],["t/1062",[65,3.503,71,3.798,328,4.519,496,5.561]],["t/1064",[60,2.115,65,2.296,76,2.674,108,2.798,254,3.375,348,2.451,497,3.066,498,3.199]],["t/1066",[60,2.556,65,2.774,110,3.578,173,3.301,499,3.865,500,3.705]],["t/1068",[89,3.985,501,7.545]],["t/1070",[11,5.427,95,5.536]],["t/1072",[60,3.716,108,4.916,502,6.403]],["t/1074",[60,3.716,108,4.916,503,6.403]],["t/1076",[504,9.184]],["t/1079",[229,4.871,505,6.623]],["t/1081",[506,6.989,507,6.623]],["t/1083",[5,3.823,507,5.62,508,5.931]],["t/1088",[509,9.184]],["t/1090",[149,5.484]],["t/1092",[238,5.794,510,7.545]],["t/1093",[477,6.35,511,7.545]],["t/1095",[512,9.184]],["t/1097",[513,6.403,514,6.403,515,6.403]],["t/1101",[516,7.545,517,6.623]],["t/1103",[166,7.463]],["t/1105",[518,9.184]],["t/1107",[18,4.133,519,6.989]],["t/1109",[490,6.35,520,5.657]],["t/1111",[521,6.989,522,5.949]],["t/1113",[149,4.505,523,6.989]],["t/1115",[449,6.606]],["t/1117",[5,2.629,60,2.556,301,3.865,395,3.167,449,3.167,524,4.403]],["t/1119",[24,3.359,395,4.606,495,5.62]],["t/1121",[14,5.657,217,5.657]],["t/1123",[525,5.657,526,7.545]],["t/1129",[9,4.445,527,6.403,528,6.403]],["t/1143",[66,2.483,378,3.694,402,1.921,497,3.356,529,3.24,530,3.988,531,3.988]],["t/1145",[172,2.315,412,4.318,457,3.356,532,3.988,533,3.24,534,3.988]],["t/1149",[294,3.155,535,4.246,536,5.049]],["t/1151",[202,5.794,537,6.35]],["t/1155",[402,3.635,538,5.536]],["t/1157",[415,7.052]],["t/1158",[225,6.623,415,5.794]],["t/1160",[85,3.215,89,2.596,149,2.934,415,3.774,539,3.993]],["t/1162",[390,5.154,477,6.35]],["t/1164",[18,3.507,60,3.716,297,4.606]],["t/1166",[18,4.133,60,4.38]],["t/1168",[18,3.507,540,5.931,541,6.403]],["t/1172",[542,6.35,543,7.545]],["t/1173",[544,9.184]],["t/1175",[545,9.184]],["t/1177",[14,4.169,388,3.425,389,3.927,546,5.561]],["t/1179",[342,5.427,547,6.35]],["t/1181",[342,5.427,525,5.657]],["t/1183",[9,4.445,548,5.203,549,6.403]],["t/1187",[550,7.545,551,4.341]],["t/1194",[552,6.989,553,7.545]],["t/1196",[313,6.623,552,6.989]],["t/1200",[554,7.729]],["t/1202",[555,9.184]],["t/1204",[556,9.184]],["t/1216",[60,3.716,312,4.522,431,4.606]],["t/1233",[557,6.131,558,7.545]],["t/1237",[56,3.481,102,3.683,484,5.62]],["t/1239",[60,3.716,108,4.916,559,5.931]],["t/1247",[24,3.958,204,4.754]],["t/1253",[18,3.507,208,4.134,294,3.155]],["t/1255",[17,3.173,65,3.096,66,3.061,75,3.061,250,3.306]],["t/1257",[60,2.853,65,3.096,71,3.357,248,4.552,390,3.357]],["t/1259",[65,3.096,76,3.606,294,2.422,388,3.027,560,4.552]],["t/1261",[18,2.692,65,3.096,110,3.993,208,3.173,294,2.422]],["t/1263",[18,2.184,65,2.512,140,3.694,245,3.062,294,1.965,561,3.988,562,3.988]],["t/1266",[219,5.049,351,4.801,388,3.944]],["t/1268",[340,6.486]],["t/1270",[560,8.507]],["t/1272",[89,3.382,297,4.606,563,5.931]],["t/1274",[18,4.133,294,3.718]],["t/1276",[224,5.427,294,3.718]],["t/1278",[388,4.647,564,6.623]],["t/1280",[105,3.606,117,3.993,565,4.914,566,4.914,567,4.914]],["t/1281",[568,5.62,569,6.403,570,6.403]],["t/1287",[18,4.133,519,6.989]],["t/1289",[18,3.507,445,4.916,571,6.403]],["t/1291",[18,3.507,445,4.916,572,6.403]],["t/1296",[573,9.184]],["t/1297",[284,4.956]],["t/1299",[286,6.179]],["t/1301",[574,9.184]],["t/1303",[36,4.598,575,7.545]],["t/1304",[576,9.184]],["t/1306",[577,6.989,578,7.545]],["t/1310",[97,4.308,383,5.931,563,5.931]],["t/1313",[579,7.463]],["t/1314",[412,6.273]],["t/1316",[579,4.519,580,8.15,581,5.151]],["t/1318",[224,6.606]],["t/1320",[506,8.507]],["t/1324",[342,6.606]],["t/1326",[342,5.427,494,6.989]],["t/1328",[342,5.427,582,7.545]],["t/1332",[579,7.463]],["t/1334",[583,9.184]],["t/1336",[224,6.606]],["t/1338",[310,8.062]],["t/1341",[97,6.179]],["t/1343",[508,6.989,584,6.989]],["t/1346",[18,4.133,585,5.328]],["t/1348",[413,6.623,586,7.545]],["t/1350",[18,3.507,587,5.62,588,5.62]],["t/1355",[250,4.308,390,4.374,434,4.916]],["t/1357",[388,3.944,389,4.522,564,5.62]],["t/1359",[348,3.741,388,3.425,389,3.927,452,4.27]],["t/1361",[388,3.944,389,4.522,585,4.522]],["t/1365",[36,3.902,468,5.931,469,5.931]],["t/1367",[36,3.389,299,4.68,390,3.798,467,4.08]],["t/1370",[112,5.154,388,4.647]],["t/1372",[112,3.798,328,4.519,388,3.425,589,5.561]],["t/1374",[18,2.692,30,2.756,99,4.136,389,3.471,487,4.136]],["t/1376",[18,2.412,30,2.469,247,3.301,389,3.109,590,4.403,591,4.403]],["t/1378",[592,7.545,593,6.35]],["t/1380",[18,3.507,587,5.62,588,5.62]],["t/1382",[342,5.427,385,6.989]],["t/1385",[419,4.68,444,4.519,594,5.561,595,5.561]],["t/1387",[32,4.445,310,5.62,419,5.388]],["t/1390",[18,3.507,587,5.62,588,5.62]],["t/1394",[364,6.35,596,6.989]],["t/1396",[229,4.134,395,4.606,597,5.62]],["t/1398",[173,5.657,340,5.328]],["t/1399",[24,2.917,54,3.546,495,4.881,598,5.561]],["t/1401",[302,4.916,599,6.403,600,5.388]],["t/1403",[601,6.403,602,5.931,603,5.62]],["t/1405",[388,3.944,564,5.62,604,5.049]],["t/1407",[63,4.27,522,4.385,605,5.561,606,5.561]],["t/1408",[9,3.411,521,4.552,522,3.875,607,4.914,608,4.914]],["t/1410",[212,3.357,522,3.875,609,4.914,610,4.552,611,4.136]],["t/1412",[319,4,522,4.385,611,4.68,612,4.169]],["t/1414",[6,2.329,89,1.772,365,2.823,522,2.645,611,4.628,612,4.124,613,3.355]],["t/1416",[6,2.768,89,2.106,611,5.32,614,2.381,615,3.694,616,3.694]],["t/1418",[89,2.326,610,4.078,614,2.629,615,4.078,616,4.078,617,4.403]],["t/1420",[84,5.62,340,4.522,400,4.606]],["t/1421",[24,2.917,146,5.151,400,4,483,4.68]],["t/1423",[400,5.347,604,3.875,618,4.914,619,4.914]],["t/1425",[348,4.308,400,4.606,452,4.916]],["t/1426",[400,4.606,620,5.931,621,5.931]],["t/1427",[400,5.427,585,5.328]],["t/1429",[388,3.425,400,4,585,3.927,604,4.385]],["t/1431",[366,3.694,400,2.868,585,2.816,620,3.694,622,3.988,623,3.988,624,3.356]],["t/1433",[99,5.388,625,6.403,626,5.388]],["t/1435",[400,5.427,627,7.545]],["t/1436",[48,4.083,340,4.522,628,5.62]],["t/1437",[48,4.083,628,5.62,629,5.931]],["t/1439",[630,5.62,631,5.62,632,5.203]],["t/1441",[4,3.306,48,3.134,602,4.552,603,4.314,628,4.314]],["t/1443",[8,3.875,633,4.914,634,4.914,635,4.914,636,4.914]],["t/1445",[222,2.961,603,3.199,631,5.164,637,3.644,638,3.644,639,2.961,640,3.644]],["t/1447",[340,4.522,520,4.801,641,6.403]],["t/1449",[60,4.38,520,5.657]],["t/1451",[101,5.049,629,5.931,642,5.62]],["t/1453",[632,6.131,643,7.545]],["t/1455",[250,4.308,520,4.801,644,5.931]],["t/1457",[487,5.388,520,4.801,645,5.388]],["t/1459",[520,5.657,577,6.989]],["t/1461",[245,4.27,520,4.169,540,5.151,631,4.881]],["t/1463",[9,3.056,101,3.472,250,2.962,365,3.705,642,3.865,646,4.078]],["t/1465",[101,3.472,346,4.078,351,3.301,520,5.123,642,3.865]],["t/1467",[330,6.623,647,7.545]],["t/1468",[89,2.596,394,2.995,395,3.535,648,4.314,649,4.552]],["t/1470",[24,3.359,395,4.606,650,5.931]],["t/1472",[24,2.578,395,3.535,445,3.774,557,3.993,650,4.552]],["t/1474",[651,6.623,652,7.545]],["t/1476",[129,5.794,379,6.989]],["t/1479",[54,5.856]],["t/1481",[102,5.284]],["t/1483",[16,5.657]],["t/1486",[54,5.856]],["t/1488",[102,5.284]],["t/1490",[16,5.657]],["t/1492",[380,5.93]],["t/1494",[85,4.188,173,4.801,381,5.931]],["t/1497",[54,5.856]],["t/1499",[102,5.284]],["t/1501",[304,6.179]],["t/1502",[409,7.729]],["t/1504",[410,7.729]],["t/1506",[16,5.657]],["t/1508",[409,7.729]],["t/1510",[410,7.729]],["t/1512",[411,6.131,412,5.154]],["t/1514",[331,6.35,413,6.623]],["t/1516",[414,6.131,415,5.794]],["t/1520",[56,4.993]],["t/1522",[5,3.32,18,3.046,393,3.927,402,2.679]],["t/1524",[8,5.049,9,4.445,403,5.931]],["t/1526",[3,5.657,4,5.076]],["t/1528",[380,4.871,402,3.635]],["t/1530",[1,3.382,165,3.591,402,3.085]],["t/1532",[402,3.085,404,5.388,405,5.388]],["t/1534",[402,2.679,404,4.68,405,4.68,406,4.881]],["t/1536",[407,7.242]],["t/1538",[16,5.657]],["t/1539",[402,3.635,408,6.989]],["t/1541",[41,5.328,402,3.635]],["t/1544",[305,7.052]],["t/1546",[396,8.062]],["t/1547",[359,6.131,416,6.989]],["t/1549",[417,8.507]],["t/1551",[418,8.507]],["t/1552",[358,6.131,419,6.35]],["t/1554",[398,7.052]],["t/1556",[420,8.507]],["t/1561",[56,4.993]],["t/1563",[68,6.179]],["t/1565",[173,4.801,217,4.801,488,4.246]],["t/1567",[102,5.284]],["t/1568",[102,3.683,442,4.916,653,5.203]],["t/1570",[102,4.341,557,6.131]],["t/1572",[16,5.657]],["t/1573",[18,3.046,32,3.86,654,5.561,655,5.151]],["t/1575",[656,8.507]],["t/1577",[308,5.388,477,5.388,657,6.403]],["t/1579",[402,3.085,658,5.62,659,6.403]],["t/1581",[344,6.886]],["t/1583",[660,9.184]],["t/1584",[89,2.596,390,3.357,434,3.774,661,4.914,662,4.914]],["t/1586",[328,5.203,467,4.698,529,5.203]],["t/1588",[460,7.242]],["t/1590",[111,6.486]],["t/1596",[54,5.856]],["t/1598",[102,5.284]],["t/1600",[304,6.179]],["t/1602",[16,5.657]],["t/1604",[411,6.131,412,5.154]],["t/1607",[18,3.507,348,4.308,452,4.916]],["t/1609",[224,4,348,3.741,402,2.679,452,4.27]],["t/1611",[18,3.507,117,5.203,208,4.134]],["t/1612",[554,7.729]],["t/1613",[268,6.739]],["t/1616",[430,8.062]],["t/1618",[245,4.27,247,4.169,431,4,432,4.08]],["t/1620",[119,4.385,303,3.688,433,4.881,434,4.27]],["t/1622",[75,4.699,435,6.623]],["t/1624",[5,2.934,6,3.411,105,3.606,431,3.535,432,3.606]],["t/1626",[5,2.934,6,3.411,60,2.853,431,3.535,432,3.606]],["t/1628",[297,5.427,436,6.131]],["t/1630",[437,5.62,438,5.62,439,5.62]],["t/1632",[14,4.801,440,5.049,441,5.62]],["t/1634",[442,4.916,443,5.62,444,5.203]],["t/1636",[95,4.698,351,4.801,445,4.916]],["t/1638",[285,5.794,446,6.35]],["t/1640",[312,5.328,447,6.623]],["t/1641",[448,8.062]],["t/1643",[312,5.328,412,5.154]],["t/1645",[93,5.049,212,4.374,449,4.606]],["t/1647",[450,8.062]],["t/1649",[451,8.062]],["t/1651",[238,3.774,452,3.774,453,4.314,454,4.314,455,4.314]],["t/1653",[456,7.463]],["t/1655",[60,2.115,102,2.096,279,2.961,347,2.573,362,3.066,449,2.621,457,3.066,458,3.199]],["t/1657",[340,6.486]],["t/1659",[344,5.657,459,6.623]],["t/1661",[5,3.32,41,3.927,302,4.27,303,3.688]],["t/1663",[284,4.956]],["t/1665",[460,7.242]],["t/1666",[38,4.754,338,6.35]],["t/1668",[461,6.623,462,6.623]],["t/1670",[143,5.203,247,4.801,316,5.388]],["t/1673",[229,4.871,663,6.989]],["t/1675",[172,4.38,229,4.871]],["t/1677",[229,4.871,505,6.623]],["t/1679",[181,5.388,229,4.134,488,4.246]],["t/1681",[102,5.284]],["t/1683",[16,5.657]],["t/1685",[149,5.484]],["t/1687",[108,4.27,229,3.59,406,4.881,488,3.688]],["t/1692",[579,7.463]],["t/1694",[84,6.623,85,4.936]],["t/1696",[90,6.623,91,6.35]],["t/1698",[91,7.729]],["t/1700",[97,5.076,304,5.076]],["t/1702",[664,9.184]],["t/1703",[78,6.989,391,6.989]],["t/1704",[665,8.062]],["t/1706",[102,5.284]],["t/1708",[412,4.374,604,5.049,612,4.801]],["t/1710",[412,3.357,446,4.136,612,3.685,666,4.914,667,4.552]],["t/1712",[19,4.374,612,4.801,668,6.403]],["t/1714",[255,5.151,319,4,327,5.151,328,4.519]],["t/1716",[412,4.374,667,5.931,669,6.403]],["t/1718",[161,5.931,507,5.62,670,6.403]],["t/1720",[149,2.629,168,3.381,214,3.472,337,3.865,665,3.865,671,4.403]],["t/1725",[364,6.35,596,6.989]],["t/1727",[639,5.203,672,6.403,673,6.403]],["t/1730",[584,8.507]],["t/1733",[274,5.62,337,5.62,674,5.388]],["t/1739",[168,5.794,675,6.989]],["t/1741",[102,5.284]],["t/1742",[112,5.154,305,5.794]],["t/1744",[296,5.949,493,6.989]],["t/1746",[79,5.931,414,5.203,676,6.403]],["t/1748",[149,4.505,649,6.989]],["t/1750",[460,7.242]],["t/1751",[73,5.388,498,5.62,568,5.62]],["t/1753",[73,4.136,89,2.596,498,4.314,677,4.914,678,4.914]],["t/1755",[34,4.519,243,4.881,312,3.927,568,4.881]],["t/1757",[170,5.388,214,5.049,679,6.403]],["t/1765",[445,5.794,680,7.545]],["t/1771",[56,4.993]],["t/1772",[13,5.076,32,5.238]],["t/1774",[13,5.076,14,5.657]],["t/1776",[681,9.184]],["t/1778",[208,5.93]],["t/1780",[16,5.657]],["t/1782",[297,5.427,436,6.131]],["t/1784",[32,5.238,655,6.989]],["t/1786",[682,6.403,683,6.403,684,6.403]],["t/1788",[656,8.507]],["t/1790",[33,6.131,537,6.35]],["t/1792",[16,4.647,330,6.623]],["t/1793",[204,4.754,434,5.794]],["t/1795",[288,4.936,351,5.657]],["t/1797",[18,4.133,208,4.871]],["t/1799",[18,4.133,344,5.657]],["t/1801",[460,7.242]],["t/1802",[579,6.131,639,6.131]],["t/1804",[245,4.916,548,5.203,685,6.403]],["t/1806",[686,7.729]],["t/1807",[60,5.331]],["t/1809",[488,6.09]],["t/1811",[229,4.871,287,5.949]],["t/1813",[18,4.133,687,6.35]],["t/1815",[11,5.427,688,7.545]],["t/1817",[214,5.949,689,6.623]],["t/1828",[690,9.184]],["t/1830",[56,4.993]],["t/1832",[691,9.184]],["t/1834",[359,7.463]],["t/1836",[402,3.085,559,5.931,692,5.931]],["t/1838",[692,5.931,693,6.403,694,5.931]],["t/1840",[58,2.806,402,2.679,694,5.151,695,5.151]],["t/1842",[402,3.635,658,6.623]],["t/1844",[112,5.154,250,5.076]],["t/1846",[112,4.374,329,5.931,348,4.308]],["t/1848",[32,4.445,313,5.62,696,6.403]],["t/1850",[697,7.545,698,7.545]],["t/1854",[56,3.481,414,5.203,517,5.62]],["t/1856",[129,4.916,551,3.683,614,3.823]],["t/1858",[48,4.083,250,4.308,614,3.823]],["t/1860",[48,4.083,304,4.308,614,3.823]],["t/1862",[48,4.083,614,3.823,653,5.203]],["t/1864",[48,4.083,89,3.382,614,3.823]],["t/1871",[699,7.052]],["t/1873",[700,6.09]],["t/1875",[17,3.59,54,3.546,212,3.798,645,4.68]],["t/1877",[89,2.937,284,3.001,402,2.679,533,4.519]],["t/1879",[9,3.056,89,2.326,284,2.376,393,3.109,402,2.121,701,4.078]],["t/1881",[89,2.106,204,2.512,212,2.724,284,3.411,398,3.062,702,2.358]],["t/1883",[284,3.455,325,5.203,702,3.786]],["t/1885",[284,3.455,324,4.916,702,3.786]],["t/1887",[89,2.326,212,3.007,284,2.376,393,3.109,402,2.121,702,2.603]],["t/1889",[284,2.652,325,3.993,393,3.471,402,2.368,702,2.906]],["t/1891",[89,2.326,284,2.376,324,3.381,393,3.109,402,2.121,702,2.603]],["t/1893",[89,2.596,284,2.652,296,3.875,533,3.993,703,3.875]],["t/1895",[86,4.519,703,4.385,704,5.151,705,4.27]],["t/1897",[286,6.179]],["t/1899",[284,3.001,286,3.741,296,4.385,703,4.385]],["t/1901",[284,3.001,286,3.741,402,2.679,706,5.151]],["t/1903",[284,3.001,286,3.741,402,2.679,705,4.27]],["t/1905",[284,3.001,286,3.741,402,2.679,702,3.288]],["t/1907",[18,2.412,284,3.687,286,2.962,398,3.381,702,2.603]],["t/1909",[686,7.729]],["t/1910",[112,3.007,324,3.381,402,2.121,674,3.705,702,2.603,707,4.078]],["t/1912",[86,3.24,402,1.921,702,2.358,705,3.062,708,3.694,709,3.694,710,3.694]],["t/1916",[56,3.481,414,5.203,517,5.62]],["t/1918",[129,4.916,551,3.683,614,3.823]],["t/1920",[48,4.083,250,4.308,614,3.823]],["t/1922",[48,4.083,304,4.308,614,3.823]],["t/1924",[48,4.083,614,3.823,653,5.203]],["t/1926",[48,4.083,89,3.382,614,3.823]],["t/1938",[208,5.93]],["t/1940",[32,5.238,192,5.949]],["t/1942",[174,6.623,471,6.989]],["t/1944",[1,4.764,202,4.916]],["t/1946",[56,4.102,209,5.076]],["t/1948",[216,6.375]],["t/1950",[217,6.886]],["t/1952",[218,5.151,219,4.385,220,4.881,221,5.151]],["t/1956",[1,1.269,60,1.394,192,1.894,202,1.844,207,2.108,228,2.225,285,1.844,353,2.225,535,1.593,711,1.801,712,2.402,713,4.15,714,2.402]],["t/1964",[715,8.507]],["t/1966",[716,6.886]],["t/1969",[717,9.184]],["t/1971",[718,9.184]],["t/1973",[347,4.522,719,6.403,720,6.403]],["t/1975",[204,4.754,268,5.536]],["t/1977",[716,5.657,721,7.545]],["t/1979",[24,3.9,30,2.756,164,4.136,204,3.096]],["t/1981",[372,6.09]],["t/1983",[722,7.242]],["t/1987",[699,7.052]],["t/1989",[700,6.09]],["t/1991",[17,3.59,54,3.546,212,3.798,645,4.68]],["t/1993",[89,2.937,284,3.001,402,2.679,533,4.519]],["t/1995",[9,3.056,89,2.326,284,2.376,393,3.109,402,2.121,701,4.078]],["t/1997",[89,2.106,204,2.512,212,2.724,284,3.411,398,3.062,702,2.358]],["t/1999",[284,3.455,325,5.203,702,3.786]],["t/2001",[284,3.455,324,4.916,702,3.786]],["t/2003",[89,2.326,212,3.007,284,2.376,393,3.109,402,2.121,702,2.603]],["t/2005",[284,2.652,325,3.993,393,3.471,402,2.368,702,2.906]],["t/2007",[89,2.326,284,2.376,324,3.381,393,3.109,402,2.121,702,2.603]],["t/2009",[89,2.596,284,2.652,296,3.875,533,3.993,703,3.875]],["t/2011",[86,4.519,703,4.385,704,5.151,705,4.27]],["t/2013",[286,6.179]],["t/2015",[284,3.001,286,3.741,296,4.385,703,4.385]],["t/2017",[284,3.001,286,3.741,402,2.679,706,5.151]],["t/2019",[284,3.001,286,3.741,402,2.679,705,4.27]],["t/2021",[284,3.001,286,3.741,402,2.679,702,3.288]],["t/2023",[18,2.412,284,3.687,286,2.962,398,3.381,702,2.603]],["t/2025",[686,7.729]],["t/2026",[112,3.007,324,3.381,402,2.121,674,3.705,702,2.603,707,4.078]],["t/2028",[86,3.24,402,1.921,702,2.358,705,3.062,708,3.694,709,3.694,710,3.694]],["t/2032",[4,5.076,320,6.989]],["t/2036",[723,9.184]],["t/2038",[85,3.215,535,3.259,600,4.136,724,4.914,725,4.914]],["t/2040",[60,4.38,481,6.35]],["t/2042",[190,3.993,204,3.096,536,3.875,726,4.552,727,4.314]],["t/2044",[94,4.385,190,4.519,674,4.68,726,5.151]],["t/2046",[94,3.472,294,3.367,535,2.92,727,3.865,728,4.403]],["t/2048",[75,4.699,729,7.545]],["t/2050",[250,5.076,535,5.004]],["t/2052",[17,3.59,250,3.741,294,2.74,535,3.688]],["t/2054",[17,2.843,94,3.472,124,3.865,294,2.17,354,3.865,535,2.92]],["t/2056",[94,4.385,294,2.74,535,3.688,730,5.561]],["t/2058",[75,3.988,294,3.155,535,4.246]],["t/2060",[17,3.59,294,2.74,535,3.688,731,4.68]],["t/2062",[19,3.798,294,2.74,535,3.688,731,4.68]],["t/2064",[48,3.546,294,2.74,535,3.688,731,4.68]],["t/2066",[94,3.875,124,4.314,294,2.422,535,3.259,731,4.136]],["t/2068",[722,7.242]],["t/2074",[732,9.184]],["t/2076",[733,9.184]],["t/2078",[734,9.184]],["t/2080",[2,4.27,695,5.151,735,5.561,736,5.561]],["t/2082",[279,6.131,737,7.545]],["t/2084",[621,6.989,738,7.545]],["t/2088",[209,6.179]],["t/2090",[24,1.912,89,1.925,208,2.353,222,2.961,291,2.529,548,4.78,739,3.644]],["t/2092",[24,2.092,89,2.106,208,2.575,222,3.24,394,3.853,429,3.5]],["t/2094",[188,3.927,208,3.59,303,3.688,349,3.927]],["t/2095",[5,5.484]],["t/2097",[395,6.606]],["t/2101",[209,6.179]],["t/2103",[24,2.31,105,3.231,268,3.231,305,3.381,429,3.865,740,4.403]],["t/2105",[208,3.59,303,3.688,741,4.385,742,4.881]],["t/2107",[32,3.86,34,4.519,303,3.688,741,4.385]],["t/2113",[223,4.08,303,3.688,487,4.68,743,4.385]],["t/2115",[658,5.62,743,5.049,744,5.931]],["t/2117",[18,3.507,743,5.049,745,6.403]],["t/2123",[209,6.179]],["t/2125",[24,3.359,268,4.698,305,4.916]],["t/2127",[208,3.59,303,3.688,741,4.385,742,4.881]],["t/2129",[32,3.86,34,4.519,303,3.688,741,4.385]],["t/2133",[64,6.486]],["t/2135",[209,6.179]],["t/2137",[102,3.683,741,5.049,742,5.62]],["t/2141",[149,5.484]],["t/2143",[16,5.657]],["t/2147",[630,6.623,746,6.989]],["t/2149",[747,9.184]],["t/2151",[630,8.062]],["t/2163",[1,2.937,204,3.503,593,4.68,632,4.519]],["t/2165",[11,5.427,372,5.004]],["t/2167",[1,2.937,593,4.68,632,4.519,746,5.151]],["t/2169",[11,5.427,372,5.004]],["t/2171",[722,7.242]],["t/2187",[700,6.09]],["t/2189",[216,6.375]],["t/2191",[1,4.851]],["t/2193",[227,6.623,748,5.536]],["t/2195",[69,5.794,333,5.794]],["t/2197",[229,4.871,538,5.536]],["t/2199",[41,6.486]],["t/2201",[213,6.989,227,6.623]],["t/2205",[700,6.09]],["t/2207",[689,6.623,749,6.623]],["t/2208",[168,5.794,689,6.623]],["t/2210",[93,5.049,449,4.606,744,5.931]],["t/2211",[449,4,456,4.519,464,5.151,750,5.561]],["t/2213",[5,3.823,302,4.916,303,4.246]],["t/2215",[312,6.486]],["t/2216",[312,5.328,751,6.989]],["t/2218",[202,7.052]],["t/2219",[105,4.08,192,4.385,287,4.385,537,4.68]],["t/2221",[357,5.151,752,5.151,753,4.169,754,4.27]],["t/2223",[38,3.503,537,4.68,748,4.08,755,5.561]],["t/2225",[18,3.507,756,6.403,757,6.403]],["t/2227",[223,5.536,224,5.427]],["t/2228",[54,4.083,758,6.403,759,5.931]],["t/2230",[293,6.989,307,5.949]],["t/2232",[165,5.151]],["t/2234",[760,7.545,761,7.545]],["t/2236",[229,4.871,538,5.536]],["t/2238",[30,2.469,38,2.774,97,2.962,748,3.231,753,3.301,759,4.078]],["t/2242",[700,6.09]],["t/2244",[17,2.843,288,2.88,349,3.109,762,3.472,763,2.843,764,3.007]],["t/2246",[216,4.445,348,4.308,764,4.374]],["t/2247",[75,3.988,763,4.134,765,4.445]],["t/2249",[1,2.596,111,3.471,754,3.774,763,3.173,765,3.411]],["t/2251",[488,5.004,766,5.949]],["t/2252",[24,3.958,294,3.718]],["t/2254",[394,5.597]],["t/2256",[585,6.486]],["t/2258",[767,6.739]],["t/2260",[614,4.505,768,5.949]],["t/2262",[38,4.754,769,5.949]],["t/2264",[165,4.232,183,4.267]],["t/2266",[229,4.871,538,5.536]],["t/2268",[30,2.469,38,2.774,97,2.962,748,3.231,753,3.301,770,4.403]],["t/2269",[91,4.68,220,4.881,764,3.798,771,5.151]],["t/2271",[61,6.886]],["t/2275",[700,6.09]],["t/2277",[17,2.843,288,2.88,349,3.109,762,3.472,763,2.843,764,3.007]],["t/2279",[216,4.445,348,4.308,764,4.374]],["t/2280",[75,3.988,763,4.134,765,4.445]],["t/2282",[1,1.925,23,2.674,24,1.912,111,2.573,294,1.796,754,2.798,763,2.353,765,2.529]],["t/2284",[488,5.004,766,5.949]],["t/2285",[24,3.958,294,3.718]],["t/2287",[394,5.597]],["t/2289",[585,6.486]],["t/2291",[767,6.739]],["t/2293",[614,4.505,768,5.949]],["t/2295",[38,4.754,769,5.949]],["t/2297",[165,4.232,183,4.267]],["t/2299",[229,4.871,538,5.536]],["t/2301",[30,2.469,38,2.774,97,2.962,748,3.231,753,3.301,772,4.403]],["t/2303",[61,6.886]],["t/2305",[773,7.463]],["t/2309",[700,6.09]],["t/2311",[17,2.843,288,2.88,349,3.109,762,3.472,763,2.843,764,3.007]],["t/2313",[216,4.445,348,4.308,764,4.374]],["t/2314",[75,3.988,763,4.134,765,4.445]],["t/2316",[1,1.925,23,2.674,24,1.912,111,2.573,294,1.796,754,2.798,763,2.353,765,2.529]],["t/2318",[488,5.004,766,5.949]],["t/2320",[585,6.486]],["t/2322",[767,6.739]],["t/2323",[105,4.698,394,3.902,767,4.698]],["t/2325",[614,4.505,768,5.949]],["t/2327",[38,4.754,769,5.949]],["t/2329",[165,4.232,183,4.267]],["t/2331",[229,4.871,538,5.536]],["t/2333",[30,2.469,38,2.774,97,2.962,748,3.231,753,3.301,774,4.403]],["t/2335",[61,6.886]],["t/2337",[773,7.463]],["t/2341",[430,8.062]],["t/2343",[245,4.27,247,4.169,431,4,432,4.08]],["t/2345",[119,4.385,303,3.688,433,4.881,434,4.27]],["t/2347",[75,4.699,435,6.623]],["t/2349",[5,2.934,6,3.411,105,3.606,431,3.535,432,3.606]],["t/2351",[5,2.934,6,3.411,60,2.853,431,3.535,432,3.606]],["t/2353",[297,5.427,436,6.131]],["t/2355",[437,5.62,438,5.62,439,5.62]],["t/2357",[14,4.801,440,5.049,441,5.62]],["t/2359",[442,4.916,443,5.62,444,5.203]],["t/2361",[95,4.698,351,4.801,445,4.916]],["t/2363",[285,5.794,446,6.35]],["t/2365",[312,5.328,447,6.623]],["t/2366",[448,8.062]],["t/2368",[312,5.328,412,5.154]],["t/2370",[93,5.049,212,4.374,449,4.606]],["t/2372",[450,8.062]],["t/2374",[451,8.062]],["t/2376",[238,3.774,452,3.774,453,4.314,454,4.314,455,4.314]],["t/2378",[456,7.463]],["t/2380",[60,2.115,102,2.096,279,2.961,347,2.573,362,3.066,449,2.621,457,3.066,458,3.199]],["t/2382",[340,6.486]],["t/2384",[344,5.657,459,6.623]],["t/2386",[5,3.32,41,3.927,302,4.27,303,3.688]],["t/2388",[284,4.956]],["t/2390",[460,7.242]],["t/2391",[38,4.754,338,6.35]],["t/2393",[461,6.623,462,6.623]],["t/2395",[143,5.203,247,4.801,316,5.388]],["t/2399",[700,6.09]],["t/2401",[17,2.843,288,2.88,349,3.109,762,3.472,763,2.843,764,3.007]],["t/2402",[188,6.486]],["t/2404",[224,5.427,294,3.718]],["t/2406",[24,3.359,164,5.388,333,4.916]],["t/2408",[75,3.988,775,5.388,776,3.786]],["t/2410",[1,1.642,13,2.091,23,2.281,24,1.631,111,2.195,294,1.532,754,2.387,763,2.007,765,2.158,777,3.108]],["t/2412",[19,5.154,481,6.35]],["t/2414",[488,5.004,766,5.949]],["t/2416",[585,6.486]],["t/2418",[767,6.739]],["t/2419",[105,4.698,394,3.902,767,4.698]],["t/2421",[614,4.505,768,5.949]],["t/2423",[38,4.754,769,5.949]],["t/2425",[165,4.232,183,4.267]],["t/2427",[229,4.871,538,5.536]],["t/2429",[30,2.469,38,2.774,97,2.962,748,3.231,753,3.301,778,4.403]],["t/2431",[61,6.886]],["t/2433",[773,7.463]],["t/2437",[700,6.09]],["t/2438",[17,2.843,288,2.88,349,3.109,762,3.472,763,2.843,764,3.007]],["t/2439",[216,4.445,348,4.308,764,4.374]],["t/2440",[75,3.988,763,4.134,765,4.445]],["t/2441",[1,1.925,23,2.674,24,1.912,111,2.573,294,1.796,754,2.798,763,2.353,765,2.529]],["t/2442",[488,5.004,766,5.949]],["t/2443",[585,6.486]],["t/2444",[767,6.739]],["t/2445",[614,4.505,768,5.949]],["t/2446",[38,4.754,769,5.949]],["t/2447",[165,4.232,183,4.267]],["t/2448",[229,4.871,538,5.536]],["t/2449",[30,2.469,38,2.774,97,2.962,748,3.231,753,3.301,779,4.403]],["t/2450",[61,6.886]],["t/2452",[773,7.463]],["t/2455",[700,6.09]],["t/2457",[17,2.843,288,2.88,349,3.109,762,3.472,763,2.843,764,3.007]],["t/2458",[188,6.486]],["t/2460",[743,7.242]],["t/2462",[75,5.72]],["t/2464",[775,7.729]],["t/2466",[216,4.445,348,4.308,764,4.374]],["t/2467",[75,3.988,763,4.134,765,4.445]],["t/2469",[1,1.925,23,2.674,24,1.912,111,2.573,294,1.796,754,2.798,763,2.353,765,2.529]],["t/2471",[294,2.74,333,4.27,401,5.151,535,3.688]],["t/2473",[204,4.034,333,4.916,751,5.931]],["t/2475",[192,3.875,193,4.552,195,4.552,333,3.774,780,4.914]],["t/2477",[488,5.004,766,5.949]],["t/2479",[585,6.486]],["t/2481",[767,6.739]],["t/2483",[614,4.505,768,5.949]],["t/2485",[188,4.522,614,3.823,781,6.403]],["t/2487",[38,4.754,769,5.949]],["t/2488",[97,2.683,204,2.512,333,3.062,535,2.644,700,2.644,782,3.988,783,3.988]],["t/2490",[67,5.03]],["t/2492",[499,5.62,764,4.374,784,6.403]],["t/2494",[775,7.729]],["t/2496",[165,4.232,183,4.267]],["t/2498",[229,4.871,538,5.536]],["t/2500",[30,2.469,38,2.774,97,2.962,748,3.231,753,3.301,785,4.403]],["t/2501",[188,6.486]],["t/2503",[743,7.242]],["t/2505",[775,7.729]],["t/2507",[61,6.886]],["t/2509",[773,7.463]],["t/2517",[90,6.623,786,7.545]],["t/2519",[13,4.308,291,4.445,374,5.931]],["t/2537",[179,2.979,372,3.688,488,3.688,787,5.151]],["t/2541",[179,2.979,372,3.688,488,3.688,787,5.151]],["t/2561",[60,3.228,66,3.463,788,5.561,789,5.561]],["t/2563",[191,6.989,790,7.545]],["t/2565",[196,6.989,791,7.545]],["t/2567",[199,6.989,792,7.545]],["t/2569",[203,6.989,793,7.545]],["t/2616",[232,4.786]],["t/2618",[56,4.993]],["t/2620",[13,3.741,67,3.046,163,5.151,165,3.119]],["t/2622",[67,4.133,68,5.076]],["t/2624",[67,4.133,612,5.657]],["t/2626",[794,9.184]],["t/2628",[500,7.729]],["t/2630",[795,5.238,796,6.131]],["t/2632",[111,4.522,796,5.203,797,6.403]],["t/2634",[505,5.62,796,5.203,798,5.931]],["t/2636",[767,6.618,796,5.203]],["t/2638",[799,9.184]],["t/2640",[36,4.598,800,5.154]],["t/2641",[241,6.623,798,6.989]],["t/2643",[241,5.62,351,4.801,801,6.403]],["t/2645",[422,4.462,551,4.341]],["t/2646",[288,6.008]],["t/2648",[802,8.507]],["t/2655",[232,4.786]],["t/2657",[803,4.92]],["t/2659",[65,3.503,66,3.463,444,4.519,804,5.561]],["t/2662",[232,4.786]],["t/2664",[803,4.92]],["t/2666",[67,4.133,277,6.623]],["t/2668",[805,7.545,806,7.545]],["t/2670",[51,6.623,331,6.35]],["t/2672",[604,5.949,807,7.545]],["t/2674",[69,5.794,372,5.004]],["t/2676",[30,2.469,103,3.865,181,3.705,612,3.301,808,6.833]],["t/2678",[36,4.598,800,5.154]],["t/2680",[11,6.606]],["t/2683",[232,4.786]],["t/2685",[803,4.92]],["t/2687",[809,9.184]],["t/2689",[422,4.462,551,4.341]],["t/2690",[36,4.598,800,5.154]],["t/2691",[67,4.133,776,4.462]],["t/2694",[232,4.786]],["t/2696",[803,4.92]],["t/2698",[422,4.462,551,4.341]],["t/2699",[63,4.916,68,4.308,687,5.388]],["t/2701",[85,3.215,626,4.136,795,3.411,810,4.314,811,3.875]],["t/2703",[711,5.657,795,5.238]],["t/2704",[56,3.481,525,4.801,812,5.62]],["t/2706",[56,4.102,547,6.35]],["t/2708",[58,2.806,68,3.741,624,4.68,813,4.881]],["t/2710",[1,3.382,165,3.591,811,5.049]],["t/2712",[85,4.188,239,5.62,536,5.049]],["t/2714",[648,8.062]],["t/2716",[75,4.699,716,5.657]],["t/2718",[814,8.507]],["t/2720",[58,3.808,815,6.623]],["t/2722",[30,2.469,58,2.222,423,3.705,467,5.014,542,3.705]],["t/2724",[58,2.806,64,3.927,525,4.169,711,4.169]],["t/2726",[58,3.231,287,5.049,816,5.931]],["t/2728",[58,3.808,817,6.989]],["t/2730",[58,3.231,85,4.188,597,5.62]],["t/2732",[149,4.505,795,5.238]],["t/2734",[165,3.591,288,4.188,818,5.62]],["t/2736",[1,3.985,307,5.949]],["t/2739",[232,4.786]],["t/2741",[803,4.92]],["t/2743",[422,4.462,551,4.341]],["t/2744",[63,4.916,68,4.308,687,5.388]],["t/2746",[85,3.215,626,4.136,795,3.411,810,4.314,811,3.875]],["t/2748",[711,5.657,795,5.238]],["t/2749",[56,3.481,525,4.801,812,5.62]],["t/2751",[56,4.102,547,6.35]],["t/2753",[58,2.806,68,3.741,624,4.68,813,4.881]],["t/2755",[85,4.188,239,5.62,536,5.049]],["t/2757",[814,8.507]],["t/2759",[58,3.808,815,6.623]],["t/2761",[30,2.469,58,2.222,423,3.705,467,5.014,542,3.705]],["t/2763",[58,2.806,64,3.927,525,4.169,711,4.169]],["t/2765",[58,3.231,287,5.049,816,5.931]],["t/2767",[58,3.808,817,6.989]],["t/2769",[58,3.231,85,4.188,597,5.62]],["t/2771",[149,4.505,795,5.238]],["t/2773",[165,3.591,288,4.188,818,5.62]],["t/2775",[1,3.985,307,5.949]],["t/2778",[232,4.786]],["t/2780",[372,5.004,488,5.004]],["t/2782",[75,4.699,716,5.657]],["t/2784",[179,4.042,442,5.794]],["t/2785",[639,7.463]],["t/2787",[600,7.729]],["t/2789",[372,6.09]],["t/2791",[179,4.042,557,6.131]],["t/2794",[232,4.786]],["t/2796",[803,4.92]],["t/2798",[1,2.937,54,3.546,55,4.08,165,3.119]],["t/2800",[231,4.801,426,4.034,700,4.246]],["t/2802",[129,4.27,500,4.68,529,4.519,819,5.561]],["t/2804",[1,3.382,231,4.801,820,5.62]],["t/2806",[209,5.076,821,6.35]],["t/2808",[288,4.936,821,6.35]],["t/2810",[165,4.232,821,6.35]],["t/2812",[319,5.427,821,6.35]],["t/2814",[149,4.505,822,7.545]],["t/2816",[500,7.729]],["t/2818",[422,4.462,551,4.341]],["t/2819",[412,5.154,612,5.657]],["t/2821",[109,5.931,231,4.801,823,6.403]],["t/2823",[716,6.886]],["t/2825",[36,4.598,800,5.154]],["t/2826",[802,8.507]],["t/2829",[232,4.786]],["t/2831",[803,4.92]],["t/2833",[795,6.375]],["t/2834",[63,4.916,68,4.308,687,5.388]],["t/2836",[626,6.35,795,5.238]],["t/2838",[711,5.657,795,5.238]],["t/2839",[56,3.481,525,4.801,812,5.62]],["t/2841",[56,4.102,547,6.35]],["t/2843",[58,2.806,68,3.741,624,4.68,813,4.881]],["t/2845",[58,3.808,815,6.623]],["t/2847",[30,2.469,58,2.222,423,3.705,467,5.014,542,3.705]],["t/2849",[58,2.806,64,3.927,525,4.169,711,4.169]],["t/2851",[58,3.231,216,4.445,490,5.388]],["t/2853",[149,4.505,795,5.238]],["t/2855",[1,3.382,165,3.591,811,5.049]],["t/2857",[85,4.936,536,5.949]],["t/2859",[824,9.184]],["t/2861",[648,8.062]],["t/2863",[1,2.937,27,5.151,28,4.881,307,4.385]],["t/2866",[232,4.786]],["t/2867",[63,4.916,825,5.203,826,6.403]],["t/2869",[89,2.937,825,4.519,827,5.561,828,5.561]],["t/2871",[715,6.989,825,6.131]],["t/2873",[285,4.916,467,4.698,825,5.203]],["t/2875",[803,4.92]],["t/2877",[1,3.382,13,4.308,825,5.203]],["t/2878",[811,7.242]],["t/2880",[402,4.425]],["t/2882",[388,4.647,389,5.328]],["t/2885",[803,4.92]],["t/2887",[54,5.856]],["t/2889",[85,6.008]],["t/2891",[56,3.481,69,4.916,216,4.445]],["t/2893",[402,3.635,663,6.989]],["t/2894",[41,5.328,402,3.635]],["t/2896",[402,3.635,829,7.545]],["t/2898",[377,5.931,402,3.085,830,6.403]],["t/2900",[30,3.832,126,3.865,287,3.472,340,3.109,831,4.403]],["t/2902",[179,4.042,183,4.267]],["t/2905",[372,6.09]],["t/2907",[179,4.042,442,5.794]],["t/2908",[402,3.635,832,7.545]],["t/2910",[639,7.463]],["t/2912",[600,7.729]],["t/2914",[372,6.09]],["t/2916",[179,4.042,557,6.131]],["t/2919",[232,4.786]],["t/2920",[803,4.92]],["t/2922",[407,5.049,490,5.388,833,6.403]],["t/2924",[1,3.382,165,3.591,811,5.049]],["t/2926",[55,6.739]],["t/2928",[653,7.463]],["t/2930",[407,5.949,834,7.545]],["t/2932",[835,9.184]],["t/2934",[179,4.042,183,4.267]],["t/2936",[75,4.699,716,5.657]],["t/2938",[165,3.591,288,4.188,818,5.62]],["t/2941",[232,4.786]],["t/2943",[803,4.92]],["t/2945",[422,4.462,551,4.341]],["t/2946",[58,3.808,836,5.536]],["t/2948",[837,5.431]],["t/2950",[128,6.623,700,5.004]],["t/2952",[372,5.004,488,5.004]],["t/2954",[67,4.133,776,4.462]],["t/2956",[179,4.042,183,4.267]],["t/2959",[232,4.786]],["t/2961",[803,4.92]],["t/2963",[422,4.462,551,4.341]],["t/2965",[58,3.808,836,5.536]],["t/2967",[36,4.598,800,5.154]],["t/2969",[837,5.431]],["t/2971",[67,4.133,776,4.462]],["t/2974",[232,4.786]],["t/2976",[803,4.92]],["t/2978",[297,4.606,402,3.085,497,5.388]],["t/2980",[165,3.591,402,3.085,820,5.62]],["t/2982",[402,3.926,483,4.68,604,4.385]],["t/2984",[402,3.926,483,4.68,646,5.151]],["t/2986",[149,4.505,523,6.989]],["t/2988",[426,4.754,551,4.341]],["t/2989",[426,4.754,820,6.623]],["t/2991",[402,3.635,426,4.754]],["t/2993",[179,4.042,183,4.267]],["t/2995",[75,4.699,716,5.657]],["t/2998",[232,4.786]],["t/3000",[803,4.92]],["t/3002",[5,2.176,56,1.981,60,2.115,390,4.018,466,2.961,838,3.644,839,3.644]],["t/3004",[442,4.916,466,5.203,716,4.801]],["t/3006",[299,6.35,466,6.131]],["t/3008",[422,4.462,551,4.341]],["t/3010",[58,3.808,836,5.536]],["t/3012",[36,4.598,800,5.154]],["t/3013",[2,4.916,219,5.049,466,5.203]],["t/3015",[837,5.431]],["t/3017",[67,4.133,776,4.462]],["t/3020",[232,4.786]],["t/3022",[699,7.052]],["t/3024",[803,4.92]],["t/3026",[422,4.462,551,4.341]],["t/3028",[68,3.741,702,3.288,810,4.881,840,5.561]],["t/3030",[165,4.232,841,7.545]],["t/3032",[68,4.308,304,4.308,702,3.786]],["t/3034",[56,3.481,68,4.308,702,3.786]],["t/3036",[68,4.308,653,5.203,702,3.786]],["t/3038",[58,3.231,68,4.308,702,3.786]],["t/3040",[372,5.004,711,5.657]],["t/3041",[705,7.052]],["t/3043",[644,8.507]],["t/3045",[149,5.484]],["t/3047",[67,4.133,776,4.462]],["t/3049",[179,4.042,183,4.267]],["t/3052",[803,4.92]],["t/3054",[232,3.336,842,6.403,843,5.62]],["t/3056",[422,4.462,551,4.341]],["t/3058",[58,1.461,66,3.031,149,1.729,347,2.045,539,2.353,749,2.542,843,2.542,844,2.682,845,2.895,846,2.682]],["t/3060",[58,1.368,71,3.143,179,1.452,268,1.988,347,1.914,481,2.28,539,2.202,749,2.379,844,2.51,847,2.71,848,2.71]],["t/3062",[58,2.222,76,3.231,179,2.359,181,3.705,238,3.381,665,3.865]],["t/3064",[300,4.136,347,3.471,402,2.368,843,4.314,846,4.552]],["t/3066",[58,2.48,66,3.061,224,3.535,225,4.314,273,4.136]],["t/3068",[58,2.48,71,3.357,402,2.368,497,4.136,548,3.993]],["t/3070",[837,5.431]],["t/3073",[232,4.786]],["t/3075",[849,7.052]],["t/3077",[48,4.224,101,2.451,297,2.236,304,3.474,614,3.956]],["t/3079",[803,4.92]],["t/3081",[422,4.462,551,4.341]],["t/3083",[129,5.794,850,7.545]],["t/3085",[165,5.151]],["t/3087",[149,5.484]],["t/3089",[67,4.133,776,4.462]],["t/3091",[179,4.042,183,4.267]],["t/3093",[722,7.242]],["t/3096",[232,4.786]],["t/3098",[849,7.052]],["t/3100",[235,8.062]],["t/3102",[48,3.134,165,2.756,614,2.934,851,4.914,852,4.914]],["t/3104",[69,5.794,217,5.657]],["t/3106",[48,2.139,56,1.824,58,1.693,77,3.108,101,2.645,304,3.7,614,2.003,853,3.355]],["t/3108",[16,2.712,58,2.222,66,2.742,75,2.742,390,3.007,854,4.078]],["t/3110",[19,3.357,58,2.48,71,3.357,700,3.259,855,4.914]],["t/3112",[58,2.48,76,3.606,103,4.314,614,2.934,765,3.411]],["t/3114",[837,5.431]],["t/3116",[856,8.507]],["t/3118",[67,4.133,776,4.462]],["t/3120",[722,7.242]],["t/3123",[232,4.786]],["t/3125",[803,4.92]],["t/3127",[837,5.431]],["t/3129",[67,4.133,776,4.462]],["t/3131",[179,4.042,183,4.267]],["t/3134",[232,4.786]],["t/3136",[803,4.92]],["t/3138",[837,5.431]],["t/3140",[56,2.672,407,3.875,651,4.314,752,4.552,776,2.906]],["t/3142",[56,3.023,407,4.385,651,4.881,776,3.288]],["t/3144",[67,4.133,776,4.462]],["t/3146",[179,4.042,183,4.267]],["t/3149",[232,4.786]],["t/3151",[849,7.052]],["t/3153",[803,4.92]],["t/3155",[422,4.462,551,4.341]],["t/3157",[302,4.916,319,4.606,857,6.403]],["t/3159",[56,3.023,216,3.86,319,4,858,5.151]],["t/3161",[165,5.151]],["t/3163",[67,4.133,776,4.462]],["t/3166",[232,4.786]],["t/3168",[803,4.92]],["t/3170",[837,5.431]],["t/3172",[67,4.133,776,4.462]],["t/3174",[179,4.042,183,4.267]],["t/3177",[232,4.786]],["t/3179",[699,7.052]],["t/3181",[803,4.92]],["t/3183",[422,4.462,551,4.341]],["t/3185",[837,5.431]],["t/3187",[67,5.03]],["t/3190",[232,4.786]],["t/3192",[699,7.052]],["t/3194",[803,4.92]],["t/3196",[422,4.462,551,4.341]],["t/3198",[837,5.431]],["t/3200",[179,4.042,183,4.267]],["t/3203",[232,4.786]],["t/3205",[803,4.92]],["t/3207",[422,4.462,551,4.341]],["t/3209",[56,4.102,216,5.238]],["t/3211",[347,3.927,365,4.68,859,5.561,860,5.561]],["t/3213",[5,2.934,188,3.471,300,4.136,367,4.552,861,4.914]],["t/3215",[291,3.86,548,4.519,554,4.68,862,5.561]],["t/3217",[307,3.472,347,3.109,467,3.231,529,3.578,539,3.578,554,3.705]],["t/3219",[347,3.927,467,4.08,529,4.519,539,4.519]],["t/3221",[795,4.445,863,6.403,864,6.403]],["t/3223",[865,9.184]],["t/3226",[232,4.786]],["t/3228",[849,7.052]],["t/3230",[803,4.92]],["t/3232",[422,4.462,551,4.341]],["t/3233",[434,5.794,436,6.131]],["t/3235",[268,4.698,415,4.916,866,6.403]],["t/3237",[837,5.431]],["t/3239",[67,4.133,776,4.462]],["t/3241",[179,4.042,183,4.267]],["t/3244",[232,4.786]],["t/3246",[67,4.133,803,4.042]],["t/3248",[422,4.462,551,4.341]],["t/3250",[58,3.808,836,5.536]],["t/3252",[36,4.598,800,5.154]],["t/3254",[837,5.431]],["t/3256",[67,4.133,776,4.462]],["t/3258",[179,4.042,183,4.267]],["t/3259",[58,3.231,179,3.43,183,3.621]],["t/3261",[232,4.786]],["t/3263",[699,7.052]],["t/3265",[803,4.92]],["t/3267",[422,4.462,551,4.341]],["t/3269",[204,3.503,217,4.169,867,5.151,868,5.151]],["t/3271",[339,5.949,340,5.328]],["t/3273",[284,4.071,339,5.949]],["t/3275",[231,5.657,358,6.131]],["t/3277",[837,5.431]],["t/3279",[204,3.503,217,4.169,867,5.151,868,5.151]],["t/3281",[339,5.949,869,7.545]],["t/3283",[284,4.071,339,5.949]],["t/3285",[231,5.657,358,6.131]],["t/3287",[67,4.133,776,4.462]],["t/3289",[179,4.042,183,4.267]],["t/3292",[232,4.786]],["t/3294",[849,7.052]],["t/3296",[803,4.92]],["t/3298",[19,5.154,870,7.545]],["t/3300",[19,3.798,771,5.151,871,5.561,872,5.561]],["t/3302",[837,5.431]],["t/3304",[67,4.133,776,4.462]],["t/3307",[232,4.786]],["t/3309",[354,6.623,645,6.35]],["t/3311",[837,5.431]],["t/3313",[56,3.481,593,5.388,632,5.203]],["t/3315",[873,7.545,874,7.545]],["t/3318",[232,4.786]],["t/3320",[803,4.92]],["t/3322",[422,4.462,551,4.341]],["t/3324",[58,3.808,836,5.536]],["t/3326",[36,4.598,800,5.154]],["t/3328",[837,5.431]],["t/3330",[67,4.133,776,4.462]],["t/3332",[179,4.042,183,4.267]],["t/3335",[232,4.786]],["t/3337",[56,4.993]],["t/3339",[803,4.92]],["t/3341",[837,5.431]],["t/3342",[295,6.989,380,4.871]],["t/3344",[8,5.949,204,4.754]],["t/3346",[8,5.049,204,4.034,875,6.403]],["t/3348",[85,4.936,415,5.794]],["t/3350",[97,5.076,796,6.131]],["t/3352",[675,8.507]],["t/3354",[440,7.242]],["t/3356",[876,9.184]],["t/3358",[349,5.328,440,5.949]],["t/3360",[12,5.388,499,5.62,877,5.931]],["t/3362",[12,5.388,877,5.931,878,5.931]],["t/3364",[14,3.685,41,3.471,119,3.875,878,4.552,879,4.914]],["t/3366",[33,6.131,336,6.989]],["t/3369",[232,4.786]],["t/3371",[380,5.93]],["t/3373",[803,4.92]],["t/3375",[422,4.462,551,4.341]],["t/3377",[58,4.635]],["t/3379",[837,5.431]],["t/3381",[36,4.598,800,5.154]],["t/3383",[67,4.133,776,4.462]],["t/3385",[179,4.042,183,4.267]],["t/3388",[232,4.786]],["t/3390",[803,4.92]],["t/3392",[56,4.993]],["t/3394",[58,3.808,836,5.536]],["t/3396",[837,5.431]],["t/3398",[11,6.606]],["t/3399",[56,2.393,741,3.472,743,3.472,880,4.403,881,4.403,882,4.403]],["t/3402",[232,4.786]],["t/3404",[803,4.92]],["t/3406",[837,5.431]],["t/3407",[883,7.545,884,7.545]],["t/3409",[274,8.062]],["t/3412",[232,4.786]],["t/3414",[803,4.92]],["t/3416",[422,4.462,551,4.341]],["t/3418",[58,3.808,836,5.536]],["t/3420",[36,4.598,800,5.154]],["t/3422",[837,5.431]],["t/3424",[67,4.133,776,4.462]],["t/3426",[179,4.042,183,4.267]],["t/3433",[232,4.786]],["t/3435",[380,5.93]],["t/3437",[803,4.92]],["t/3439",[422,4.462,551,4.341]],["t/3441",[58,4.635]],["t/3443",[36,4.598,800,5.154]],["t/3445",[837,5.431]],["t/3447",[67,4.133,776,4.462]],["t/3449",[179,4.042,183,4.267]],["t/3452",[232,4.786]],["t/3454",[699,7.052]],["t/3456",[440,7.242]],["t/3458",[803,4.92]],["t/3460",[80,6.989,858,6.989]],["t/3462",[422,4.462,551,4.341]],["t/3464",[58,3.808,836,5.536]],["t/3466",[36,4.598,800,5.154]],["t/3467",[217,6.886]],["t/3469",[837,5.431]],["t/3471",[536,5.949,727,6.623]],["t/3473",[67,4.133,776,4.462]],["t/3474",[186,5.151,700,3.688,885,5.561,886,5.561]],["t/3476",[304,3.741,614,3.32,854,5.151,887,5.561]],["t/3478",[179,4.042,183,4.267]],["t/3480",[686,7.729]],["t/3481",[581,6.989,837,4.462]],["t/3483",[722,7.242]],["t/3486",[888,9.184]],["t/3488",[849,7.052]],["t/3490",[235,8.062]],["t/3492",[837,5.431]],["t/3494",[856,8.507]],["t/3496",[67,4.133,776,4.462]],["t/3499",[232,4.786]],["t/3501",[849,7.052]],["t/3503",[803,4.92]],["t/3505",[422,4.462,551,4.341]],["t/3507",[58,3.808,836,5.536]],["t/3509",[36,4.598,800,5.154]],["t/3511",[165,5.151]],["t/3513",[67,4.133,776,4.462]],["t/3515",[179,4.042,183,4.267]]],"invertedIndex":[["",{"_index":30,"t":{"42":{"position":[[44,1]]},"94":{"position":[[14,1]]},"96":{"position":[[11,1]]},"98":{"position":[[6,1]]},"108":{"position":[[7,1]]},"111":{"position":[[7,1]]},"113":{"position":[[7,1]]},"157":{"position":[[7,1]]},"159":{"position":[[7,1]]},"161":{"position":[[7,1]]},"163":{"position":[[7,1]]},"179":{"position":[[11,1]]},"291":{"position":[[8,1]]},"964":{"position":[[0,2]]},"965":{"position":[[0,2]]},"966":{"position":[[0,2]]},"1374":{"position":[[8,1]]},"1376":{"position":[[11,1]]},"1979":{"position":[[15,1]]},"2238":{"position":[[21,1]]},"2268":{"position":[[21,1]]},"2301":{"position":[[21,1]]},"2333":{"position":[[21,1]]},"2429":{"position":[[21,1]]},"2449":{"position":[[21,1]]},"2500":{"position":[[21,1]]},"2676":{"position":[[25,1]]},"2722":{"position":[[35,1]]},"2761":{"position":[[35,1]]},"2847":{"position":[[35,1]]},"2900":{"position":[[10,1],[37,1]]}}}],["0",{"_index":853,"t":{"3106":{"position":[[7,2]]}}}],["1",{"_index":66,"t":{"108":{"position":[[5,1]]},"110":{"position":[[0,2]]},"111":{"position":[[5,1]]},"157":{"position":[[5,1]]},"205":{"position":[[16,1]]},"224":{"position":[[10,1]]},"226":{"position":[[10,1]]},"241":{"position":[[0,2]]},"277":{"position":[[0,2]]},"291":{"position":[[0,2]]},"297":{"position":[[0,2]]},"367":{"position":[[0,2]]},"1060":{"position":[[5,2]]},"1143":{"position":[[46,1]]},"1255":{"position":[[5,2]]},"2561":{"position":[[0,2]]},"2659":{"position":[[24,2]]},"3058":{"position":[[7,1],[31,2]]},"3066":{"position":[[7,1]]},"3108":{"position":[[7,2]]}}}],["1.1",{"_index":191,"t":{"299":{"position":[[0,3]]},"2563":{"position":[[0,3]]}}}],["1.2",{"_index":196,"t":{"301":{"position":[[0,3]]},"2565":{"position":[[0,3]]}}}],["1.3",{"_index":199,"t":{"303":{"position":[[0,3]]},"2567":{"position":[[0,3]]}}}],["1.4",{"_index":203,"t":{"305":{"position":[[0,3]]},"2569":{"position":[[0,3]]}}}],["1.5",{"_index":205,"t":{"307":{"position":[[0,3]]}}}],["2",{"_index":71,"t":{"113":{"position":[[5,1]]},"115":{"position":[[0,2]]},"159":{"position":[[5,1]]},"213":{"position":[[10,1]]},"222":{"position":[[16,1]]},"279":{"position":[[0,2]]},"293":{"position":[[0,2]]},"369":{"position":[[0,2]]},"1062":{"position":[[5,2]]},"1257":{"position":[[5,2]]},"3060":{"position":[[7,1],[31,2]]},"3068":{"position":[[7,1]]},"3110":{"position":[[7,2]]}}}],["2nd",{"_index":661,"t":{"1584":{"position":[[7,3]]}}}],["3",{"_index":76,"t":{"117":{"position":[[0,2]]},"161":{"position":[[5,1]]},"209":{"position":[[10,1]]},"287":{"position":[[0,2]]},"371":{"position":[[0,2]]},"1064":{"position":[[5,2]]},"1259":{"position":[[5,2]]},"3062":{"position":[[7,1]]},"3112":{"position":[[7,2]]}}}],["4",{"_index":110,"t":{"163":{"position":[[5,1]]},"201":{"position":[[10,1]]},"373":{"position":[[0,2]]},"1066":{"position":[[5,2]]},"1261":{"position":[[5,2]]}}}],["4+1",{"_index":159,"t":{"237":{"position":[[0,3]]}}}],["5",{"_index":140,"t":{"194":{"position":[[10,1]]},"1263":{"position":[[5,2]]}}}],["5.1",{"_index":242,"t":{"376":{"position":[[0,3]]}}}],["5.2",{"_index":244,"t":{"380":{"position":[[0,3]]}}}],["6",{"_index":135,"t":{"190":{"position":[[10,1]]}}}],["60",{"_index":598,"t":{"1399":{"position":[[0,2]]}}}],["abstract",{"_index":888,"t":{"3486":{"position":[[0,8]]}}}],["access",{"_index":32,"t":{"43":{"position":[[9,6]]},"50":{"position":[[9,6]]},"305":{"position":[[26,6]]},"445":{"position":[[5,6]]},"1387":{"position":[[4,6]]},"1573":{"position":[[22,6]]},"1772":{"position":[[6,6]]},"1784":{"position":[[4,6]]},"1848":{"position":[[7,6]]},"1940":{"position":[[0,9]]},"2107":{"position":[[0,6]]},"2129":{"position":[[0,6]]}}}],["acknowledg",{"_index":802,"t":{"2648":{"position":[[0,16]]},"2826":{"position":[[0,16]]}}}],["action",{"_index":707,"t":{"1910":{"position":[[15,6]]},"2026":{"position":[[15,6]]}}}],["ad",{"_index":72,"t":{"113":{"position":[[9,6]]}}}],["add",{"_index":452,"t":{"929":{"position":[[0,3]]},"1359":{"position":[[0,3]]},"1425":{"position":[[0,3]]},"1607":{"position":[[7,3]]},"1609":{"position":[[7,3]]},"1651":{"position":[[0,3]]},"2376":{"position":[[0,3]]}}}],["addit",{"_index":659,"t":{"1579":{"position":[[10,10]]}}}],["address",{"_index":570,"t":{"1281":{"position":[[15,7]]}}}],["adjust",{"_index":727,"t":{"2042":{"position":[[30,11]]},"2046":{"position":[[39,10]]},"3471":{"position":[[7,11]]}}}],["admin",{"_index":186,"t":{"287":{"position":[[39,5]]},"3474":{"position":[[0,7]]}}}],["administr",{"_index":729,"t":{"2048":{"position":[[0,14]]}}}],["admonit",{"_index":81,"t":{"126":{"position":[[0,11]]}}}],["advanc",{"_index":330,"t":{"582":{"position":[[0,8]]},"1467":{"position":[[0,8]]},"1792":{"position":[[0,8]]}}}],["advertis",{"_index":139,"t":{"192":{"position":[[10,11]]}}}],["advic",{"_index":597,"t":{"1396":{"position":[[0,6]]},"2730":{"position":[[15,6]]},"2769":{"position":[[15,6]]}}}],["affero",{"_index":115,"t":{"171":{"position":[[0,6]]}}}],["against",{"_index":852,"t":{"3102":{"position":[[16,7]]}}}],["aggreg",{"_index":385,"t":{"741":{"position":[[19,10]]},"1382":{"position":[[5,10]]}}}],["agreement",{"_index":127,"t":{"177":{"position":[[46,10]]}}}],["alarm",{"_index":447,"t":{"918":{"position":[[0,8]]},"1640":{"position":[[0,8]]},"2365":{"position":[[0,8]]}}}],["alreadi",{"_index":370,"t":{"701":{"position":[[11,7]]}}}],["altern",{"_index":457,"t":{"933":{"position":[[0,11]]},"1145":{"position":[[40,11]]},"1655":{"position":[[0,11]]},"2380":{"position":[[0,11]]}}}],["amd",{"_index":544,"t":{"1173":{"position":[[0,3]]}}}],["amphora",{"_index":419,"t":{"837":{"position":[[0,7]]},"1385":{"position":[[11,8]]},"1387":{"position":[[14,8]]},"1552":{"position":[[0,7]]}}}],["analyz",{"_index":461,"t":{"946":{"position":[[0,9]]},"1668":{"position":[[0,9]]},"2393":{"position":[[0,9]]}}}],["and/or",{"_index":666,"t":{"1710":{"position":[[26,6]]}}}],["annot",{"_index":850,"t":{"3083":{"position":[[8,11]]}}}],["ansibl",{"_index":579,"t":{"1313":{"position":[[0,7]]},"1316":{"position":[[18,7]]},"1332":{"position":[[0,7]]},"1692":{"position":[[0,7]]},"1802":{"position":[[0,7]]}}}],["api",{"_index":204,"t":{"305":{"position":[[22,3]]},"755":{"position":[[14,3]]},"884":{"position":[[32,3]]},"885":{"position":[[8,3]]},"886":{"position":[[8,3]]},"1247":{"position":[[8,3]]},"1793":{"position":[[9,3]]},"1881":{"position":[[39,3]]},"1975":{"position":[[11,3]]},"1979":{"position":[[25,3]]},"1997":{"position":[[39,3]]},"2042":{"position":[[19,3]]},"2163":{"position":[[20,3]]},"2473":{"position":[[17,3]]},"2488":{"position":[[48,3]]},"3269":{"position":[[5,3]]},"3279":{"position":[[5,3]]},"3344":{"position":[[0,3]]},"3346":{"position":[[0,3]]}}}],["api_monitor.sh",{"_index":438,"t":{"908":{"position":[[11,14]]},"1630":{"position":[[11,14]]},"2355":{"position":[[11,14]]}}}],["apiserv",{"_index":553,"t":{"1194":{"position":[[8,9]]}}}],["app",{"_index":676,"t":{"1746":{"position":[[7,3]]}}}],["appendix",{"_index":686,"t":{"1806":{"position":[[0,8]]},"1909":{"position":[[0,8]]},"2025":{"position":[[0,8]]},"3480":{"position":[[0,8]]}}}],["appli",{"_index":248,"t":{"388":{"position":[[0,8]]},"1257":{"position":[[8,5]]}}}],["applic",{"_index":645,"t":{"1457":{"position":[[12,11]]},"1875":{"position":[[12,10]]},"1991":{"position":[[12,10]]},"3309":{"position":[[9,12]]}}}],["approach",{"_index":347,"t":{"605":{"position":[[20,8]]},"933":{"position":[[12,8]]},"1655":{"position":[[12,8]]},"1973":{"position":[[11,8]]},"2380":{"position":[[12,8]]},"3058":{"position":[[22,8]]},"3060":{"position":[[22,8]]},"3064":{"position":[[0,10]]},"3211":{"position":[[27,10]]},"3217":{"position":[[37,8]]},"3219":{"position":[[22,8]]}}}],["apt",{"_index":555,"t":{"1202":{"position":[[0,3]]}}}],["ara",{"_index":580,"t":{"1316":{"position":[[0,3],[6,3]]}}}],["architectur",{"_index":64,"t":{"104":{"position":[[12,12]]},"343":{"position":[[0,13]]},"971":{"position":[[8,12]]},"972":{"position":[[8,12]]},"973":{"position":[[8,12]]},"974":{"position":[[9,12]]},"975":{"position":[[14,12]]},"2133":{"position":[[0,12]]},"2724":{"position":[[15,12]]},"2763":{"position":[[15,12]]},"2849":{"position":[[15,12]]}}}],["aspect",{"_index":841,"t":{"3030":{"position":[[13,7]]}}}],["assess",{"_index":781,"t":{"2485":{"position":[[9,10]]}}}],["assign",{"_index":124,"t":{"177":{"position":[[10,11]]},"2054":{"position":[[0,9]]},"2066":{"position":[[14,11]]}}}],["assist",{"_index":134,"t":{"186":{"position":[[30,9]]}}}],["attach",{"_index":324,"t":{"569":{"position":[[5,6]]},"1885":{"position":[[10,8]]},"1891":{"position":[[24,8]]},"1910":{"position":[[39,8]]},"2001":{"position":[[10,8]]},"2007":{"position":[[24,8]]},"2026":{"position":[[39,8]]}}}],["authent",{"_index":33,"t":{"45":{"position":[[0,14]]},"52":{"position":[[0,14]]},"403":{"position":[[15,14]]},"1790":{"position":[[0,14]]},"3366":{"position":[[0,14]]}}}],["author",{"_index":336,"t":{"587":{"position":[[12,9]]},"3366":{"position":[[19,13]]}}}],["autom",{"_index":442,"t":{"912":{"position":[[0,10]]},"1568":{"position":[[0,9]]},"1634":{"position":[[0,10]]},"2359":{"position":[[0,10]]},"2784":{"position":[[0,9]]},"2907":{"position":[[0,9]]},"3004":{"position":[[0,10]]}}}],["autoscal",{"_index":643,"t":{"1453":{"position":[[4,10]]}}}],["avail",{"_index":383,"t":{"739":{"position":[[16,12]]},"1310":{"position":[[9,9]]}}}],["avoid",{"_index":571,"t":{"1289":{"position":[[0,8]]}}}],["aw",{"_index":367,"t":{"699":{"position":[[61,4]]},"3213":{"position":[[35,4]]}}}],["azur",{"_index":368,"t":{"699":{"position":[[66,11]]}}}],["backend",{"_index":403,"t":{"787":{"position":[[15,7]]},"1524":{"position":[[15,7]]}}}],["backfills/recoveri",{"_index":625,"t":{"1433":{"position":[[8,18]]}}}],["backup",{"_index":284,"t":{"473":{"position":[[0,6]]},"595":{"position":[[20,6]]},"941":{"position":[[0,6]]},"1297":{"position":[[0,6]]},"1663":{"position":[[0,6]]},"1877":{"position":[[6,6]]},"1879":{"position":[[18,6]]},"1881":{"position":[[12,6],[32,6]]},"1883":{"position":[[0,6]]},"1885":{"position":[[0,6]]},"1887":{"position":[[12,6]]},"1889":{"position":[[13,7]]},"1891":{"position":[[13,7]]},"1893":{"position":[[17,6]]},"1899":{"position":[[12,6]]},"1901":{"position":[[12,6]]},"1903":{"position":[[12,6]]},"1905":{"position":[[19,6]]},"1907":{"position":[[19,6],[42,6]]},"1993":{"position":[[6,6]]},"1995":{"position":[[18,6]]},"1997":{"position":[[12,6],[32,6]]},"1999":{"position":[[0,6]]},"2001":{"position":[[0,6]]},"2003":{"position":[[12,6]]},"2005":{"position":[[13,7]]},"2007":{"position":[[13,7]]},"2009":{"position":[[17,6]]},"2015":{"position":[[12,6]]},"2017":{"position":[[12,6]]},"2019":{"position":[[12,6]]},"2021":{"position":[[19,6]]},"2023":{"position":[[19,6],[42,6]]},"2388":{"position":[[0,6]]},"3273":{"position":[[5,6]]},"3283":{"position":[[5,6]]}}}],["barbican",{"_index":703,"t":{"1893":{"position":[[0,8]]},"1895":{"position":[[32,8]]},"1899":{"position":[[24,8]]},"2009":{"position":[[0,8]]},"2011":{"position":[[32,8]]},"2015":{"position":[[24,8]]}}}],["bare",{"_index":756,"t":{"2225":{"position":[[0,4]]}}}],["base",{"_index":539,"t":{"1160":{"position":[[28,5]]},"3058":{"position":[[16,5]]},"3060":{"position":[[16,5]]},"3217":{"position":[[31,5]]},"3219":{"position":[[16,5]]}}}],["basic",{"_index":822,"t":{"2814":{"position":[[0,5]]}}}],["becom",{"_index":90,"t":{"138":{"position":[[27,6]]},"1696":{"position":[[0,6]]},"2517":{"position":[[0,8]]}}}],["befor",{"_index":137,"t":{"190":{"position":[[19,6]]},"194":{"position":[[19,6]]},"201":{"position":[[19,6]]},"203":{"position":[[22,6]]},"209":{"position":[[19,6]]},"213":{"position":[[19,6]]},"224":{"position":[[18,6]]},"226":{"position":[[17,6]]},"228":{"position":[[18,6]]}}}],["behaviour",{"_index":680,"t":{"1765":{"position":[[8,9]]}}}],["behind",{"_index":362,"t":{"693":{"position":[[15,6]]},"933":{"position":[[60,6]]},"1655":{"position":[[60,6]]},"2380":{"position":[[60,6]]}}}],["benchmark",{"_index":652,"t":{"1474":{"position":[[12,9]]}}}],["best",{"_index":52,"t":{"85":{"position":[[10,4]]}}}],["between",{"_index":207,"t":{"307":{"position":[[19,7]]},"392":{"position":[[7,7]]},"1956":{"position":[[66,7]]}}}],["beyond",{"_index":307,"t":{"524":{"position":[[0,6]]},"2230":{"position":[[0,6]]},"2736":{"position":[[0,6]]},"2775":{"position":[[0,6]]},"2863":{"position":[[0,6]]},"3217":{"position":[[0,6]]}}}],["bill",{"_index":424,"t":{"873":{"position":[[9,4]]}}}],["black",{"_index":671,"t":{"1720":{"position":[[25,5]]}}}],["block",{"_index":606,"t":{"1407":{"position":[[28,5]]}}}],["blockquot",{"_index":82,"t":{"128":{"position":[[0,11]]}}}],["blog",{"_index":784,"t":{"2492":{"position":[[12,4]]}}}],["board",{"_index":566,"t":{"1280":{"position":[[21,5]]}}}],["bootstrap",{"_index":560,"t":{"1259":{"position":[[8,9]]},"1270":{"position":[[0,9]]}}}],["box",{"_index":777,"t":{"2410":{"position":[[47,4]]}}}],["branch",{"_index":678,"t":{"1753":{"position":[[35,7]]}}}],["break",{"_index":801,"t":{"2643":{"position":[[0,8]]}}}],["breakfast",{"_index":152,"t":{"216":{"position":[[0,9]]}}}],["broken",{"_index":623,"t":{"1431":{"position":[[49,6]]}}}],["broker",{"_index":508,"t":{"1083":{"position":[[10,6]]},"1343":{"position":[[0,6]]}}}],["bucket",{"_index":269,"t":{"422":{"position":[[3,6]]},"466":{"position":[[3,6]]}}}],["bug",{"_index":227,"t":{"354":{"position":[[11,4]]},"2193":{"position":[[6,4]]},"2201":{"position":[[0,3]]}}}],["build",{"_index":377,"t":{"719":{"position":[[40,5]]},"2898":{"position":[[6,5]]}}}],["ca",{"_index":436,"t":{"906":{"position":[[7,2]]},"1628":{"position":[[7,2]]},"1782":{"position":[[7,2]]},"2353":{"position":[[7,2]]},"3233":{"position":[[9,2]]}}}],["caa",{"_index":189,"t":{"293":{"position":[[3,4]]},"707":{"position":[[67,6]]},"713":{"position":[[10,4]]}}}],["capi",{"_index":293,"t":{"482":{"position":[[11,4]]},"2230":{"position":[[7,4]]}}}],["card",{"_index":478,"t":{"998":{"position":[[18,5]]}}}],["case",{"_index":222,"t":{"345":{"position":[[4,5]]},"871":{"position":[[4,5]]},"1445":{"position":[[27,4]]},"2090":{"position":[[22,4]]},"2092":{"position":[[10,4]]}}}],["ceilomet",{"_index":788,"t":{"2561":{"position":[[3,10]]}}}],["cell",{"_index":386,"t":{"743":{"position":[[16,4]]}}}],["cento",{"_index":486,"t":{"1018":{"position":[[0,6]]}}}],["central",{"_index":751,"t":{"2216":{"position":[[0,7]]},"2473":{"position":[[9,7]]}}}],["ceph",{"_index":395,"t":{"767":{"position":[[0,4]]},"777":{"position":[[0,4]]},"881":{"position":[[24,4]]},"1117":{"position":[[53,4]]},"1119":{"position":[[7,4]]},"1396":{"position":[[10,4]]},"1468":{"position":[[11,4]]},"1470":{"position":[[11,4]]},"1472":{"position":[[10,4]]},"2097":{"position":[[0,4]]}}}],["certif",{"_index":231,"t":{"360":{"position":[[26,13]]},"585":{"position":[[7,12]]},"587":{"position":[[0,11]]},"2800":{"position":[[13,11]]},"2804":{"position":[[4,13]]},"2821":{"position":[[21,14]]},"3275":{"position":[[0,11]]},"3285":{"position":[[0,11]]}}}],["certifi",{"_index":786,"t":{"2517":{"position":[[9,9]]}}}],["challeng",{"_index":718,"t":{"1971":{"position":[[0,9]]}}}],["chang",{"_index":351,"t":{"614":{"position":[[12,7]]},"914":{"position":[[0,8]]},"1266":{"position":[[0,6]]},"1465":{"position":[[0,6]]},"1636":{"position":[[0,8]]},"1795":{"position":[[0,6]]},"2361":{"position":[[0,8]]},"2643":{"position":[[9,6]]}}}],["changed_when",{"_index":98,"t":{"148":{"position":[[9,12]]}}}],["channel",{"_index":236,"t":{"371":{"position":[[3,8]]}}}],["charg",{"_index":441,"t":{"910":{"position":[[20,8]]},"1632":{"position":[[20,8]]},"2357":{"position":[[20,8]]}}}],["check",{"_index":319,"t":{"556":{"position":[[5,5]]},"558":{"position":[[5,5]]},"560":{"position":[[5,5]]},"562":{"position":[[5,5]]},"564":{"position":[[5,5]]},"1412":{"position":[[0,5]]},"1714":{"position":[[0,5]]},"2812":{"position":[[0,5]]},"3157":{"position":[[11,5]]},"3159":{"position":[[32,5]]}}}],["checklist",{"_index":70,"t":{"111":{"position":[[9,9]]},"190":{"position":[[0,9]]},"192":{"position":[[0,9]]},"194":{"position":[[0,9]]},"196":{"position":[[0,9]]},"201":{"position":[[0,9]]},"203":{"position":[[0,9]]},"205":{"position":[[0,9]]},"207":{"position":[[0,9]]},"209":{"position":[[0,9]]},"211":{"position":[[0,9]]},"213":{"position":[[0,9]]},"215":{"position":[[7,9]]},"222":{"position":[[0,9]]},"224":{"position":[[0,9]]},"226":{"position":[[0,9]]},"228":{"position":[[0,9]]},"230":{"position":[[0,9]]},"232":{"position":[[0,9]]}}}],["chosen",{"_index":719,"t":{"1973":{"position":[[4,6]]}}}],["ci",{"_index":689,"t":{"1817":{"position":[[0,2]]},"2207":{"position":[[0,2]]},"2208":{"position":[[5,2]]}}}],["ci/cd",{"_index":169,"t":{"267":{"position":[[5,5]]}}}],["cinder",{"_index":398,"t":{"773":{"position":[[0,6]]},"839":{"position":[[0,6]]},"1554":{"position":[[0,6]]},"1881":{"position":[[25,6]]},"1907":{"position":[[35,6]]},"1997":{"position":[[25,6]]},"2023":{"position":[[35,6]]}}}],["claim",{"_index":198,"t":{"301":{"position":[[30,6]]}}}],["class",{"_index":646,"t":{"1463":{"position":[[41,7]]},"2984":{"position":[[21,5]]}}}],["clean",{"_index":316,"t":{"549":{"position":[[5,5]]},"948":{"position":[[0,8]]},"1670":{"position":[[0,8]]},"2395":{"position":[[0,8]]}}}],["cleanup",{"_index":444,"t":{"912":{"position":[[23,7]]},"1385":{"position":[[0,7]]},"1634":{"position":[[23,7]]},"2359":{"position":[[23,7]]},"2659":{"position":[[10,7]]}}}],["cli",{"_index":6,"t":{"8":{"position":[[31,3]]},"9":{"position":[[16,5]]},"54":{"position":[[16,5]]},"305":{"position":[[14,3]]},"902":{"position":[[24,3]]},"904":{"position":[[22,3]]},"1414":{"position":[[58,3]]},"1416":{"position":[[37,3]]},"1624":{"position":[[24,3]]},"1626":{"position":[[22,3]]},"2349":{"position":[[24,3]]},"2351":{"position":[[22,3]]}}}],["client",{"_index":166,"t":{"258":{"position":[[0,6]]},"424":{"position":[[7,6]]},"468":{"position":[[7,6]]},"585":{"position":[[0,6]]},"1103":{"position":[[0,6]]}}}],["clone",{"_index":107,"t":{"159":{"position":[[9,7]]}}}],["cloud",{"_index":13,"t":{"17":{"position":[[15,5]]},"244":{"position":[[10,5]]},"350":{"position":[[11,6]]},"695":{"position":[[39,5]]},"699":{"position":[[36,5]]},"701":{"position":[[25,5]]},"717":{"position":[[21,6]]},"719":{"position":[[53,6]]},"1772":{"position":[[0,5]]},"1774":{"position":[[0,5]]},"2410":{"position":[[35,6]]},"2519":{"position":[[10,5]]},"2620":{"position":[[10,5]]},"2877":{"position":[[15,6]]}}}],["cloudnam",{"_index":454,"t":{"929":{"position":[[7,9]]},"1651":{"position":[[7,9]]},"2376":{"position":[[7,9]]}}}],["clouds.yml",{"_index":532,"t":{"1145":{"position":[[5,10]]}}}],["clush",{"_index":583,"t":{"1334":{"position":[[0,5]]}}}],["cluster",{"_index":24,"t":{"36":{"position":[[4,8]]},"39":{"position":[[4,8]]},"390":{"position":[[18,7]]},"410":{"position":[[26,8]]},"420":{"position":[[11,8]]},"464":{"position":[[11,7]]},"484":{"position":[[40,8]]},"486":{"position":[[11,8]]},"520":{"position":[[14,7]]},"582":{"position":[[9,7]]},"589":{"position":[[7,7]]},"591":{"position":[[0,7]]},"599":{"position":[[16,9],[39,8]]},"607":{"position":[[18,8]]},"634":{"position":[[32,7]]},"864":{"position":[[16,7]]},"867":{"position":[[12,7]]},"869":{"position":[[0,7]]},"884":{"position":[[24,7]]},"885":{"position":[[0,7]]},"886":{"position":[[0,7],[21,7]]},"1119":{"position":[[12,7]]},"1247":{"position":[[0,7]]},"1399":{"position":[[11,7]]},"1421":{"position":[[29,7]]},"1470":{"position":[[16,7]]},"1472":{"position":[[15,7]]},"1979":{"position":[[0,7],[17,7]]},"2090":{"position":[[38,7]]},"2092":{"position":[[21,7]]},"2103":{"position":[[23,7]]},"2125":{"position":[[19,7]]},"2252":{"position":[[0,7]]},"2282":{"position":[[52,7]]},"2285":{"position":[[0,7]]},"2316":{"position":[[52,7]]},"2406":{"position":[[9,7]]},"2410":{"position":[[68,7]]},"2441":{"position":[[52,7]]},"2469":{"position":[[52,7]]}}}],["clusterctl",{"_index":345,"t":{"605":{"position":[[4,10]]}}}],["clusterctl.yaml",{"_index":290,"t":{"480":{"position":[[32,15]]}}}],["clusterstack",{"_index":249,"t":{"388":{"position":[[9,12]]}}}],["code",{"_index":161,"t":{"243":{"position":[[0,4]]},"1718":{"position":[[17,4]]}}}],["codeblock",{"_index":83,"t":{"130":{"position":[[0,10]]}}}],["collabor",{"_index":37,"t":{"59":{"position":[[0,13]]},"236":{"position":[[14,13]]}}}],["collect",{"_index":93,"t":{"142":{"position":[[9,11]]},"144":{"position":[[26,11]]},"923":{"position":[[5,10]]},"1645":{"position":[[5,10]]},"2210":{"position":[[8,10]]},"2370":{"position":[[5,10]]}}}],["command",{"_index":308,"t":{"528":{"position":[[8,8]]},"555":{"position":[[8,8]]},"566":{"position":[[9,8]]},"1577":{"position":[[0,7]]}}}],["commit",{"_index":78,"t":{"121":{"position":[[4,6]]},"1703":{"position":[[0,6]]}}}],["common",{"_index":295,"t":{"484":{"position":[[0,6]]},"3342":{"position":[[0,6]]}}}],["commun",{"_index":2,"t":{"3":{"position":[[19,9]]},"57":{"position":[[14,9]]},"117":{"position":[[3,9]]},"244":{"position":[[22,9]]},"620":{"position":[[11,9]]},"2080":{"position":[[10,9]]},"3013":{"position":[[15,10]]}}}],["compact",{"_index":869,"t":{"3281":{"position":[[5,10]]}}}],["compactor",{"_index":747,"t":{"2149":{"position":[[0,9]]}}}],["compani",{"_index":369,"t":{"701":{"position":[[3,7]]},"719":{"position":[[28,7]]}}}],["comparison",{"_index":873,"t":{"3315":{"position":[[0,10]]}}}],["complet",{"_index":626,"t":{"1433":{"position":[[27,10]]},"2701":{"position":[[0,8]]},"2746":{"position":[[0,8]]},"2836":{"position":[[0,8]]}}}],["complianc",{"_index":239,"t":{"373":{"position":[[3,10]]},"2712":{"position":[[14,10]]},"2755":{"position":[[14,10]]}}}],["compliant",{"_index":374,"t":{"705":{"position":[[56,10]]},"2519":{"position":[[0,9]]}}}],["compon",{"_index":349,"t":{"610":{"position":[[27,10]]},"612":{"position":[[26,10]]},"864":{"position":[[0,10]]},"2094":{"position":[[23,10]]},"2244":{"position":[[0,9]]},"2277":{"position":[[0,9]]},"2311":{"position":[[0,9]]},"2401":{"position":[[0,9]]},"2438":{"position":[[0,9]]},"2457":{"position":[[0,9]]},"3358":{"position":[[0,9]]}}}],["component/compon",{"_index":807,"t":{"2672":{"position":[[7,19]]}}}],["comput",{"_index":389,"t":{"749":{"position":[[14,7]]},"971":{"position":[[0,7]]},"983":{"position":[[0,7]]},"1000":{"position":[[0,7]]},"1177":{"position":[[8,7]]},"1357":{"position":[[9,7]]},"1359":{"position":[[10,7]]},"1361":{"position":[[9,7]]},"1374":{"position":[[19,7]]},"1376":{"position":[[18,7]]},"2882":{"position":[[0,7]]}}}],["con",{"_index":860,"t":{"3211":{"position":[[9,4]]}}}],["conclus",{"_index":865,"t":{"3223":{"position":[[0,10]]}}}],["condit",{"_index":92,"t":{"140":{"position":[[21,9]]}}}],["conduct",{"_index":162,"t":{"243":{"position":[[8,7]]}}}],["config",{"_index":411,"t":{"822":{"position":[[0,6]]},"860":{"position":[[0,6]]},"1036":{"position":[[6,6]]},"1512":{"position":[[0,6]]},"1604":{"position":[[0,6]]}}}],["configur",{"_index":60,"t":{"94":{"position":[[0,13]]},"490":{"position":[[0,13]]},"634":{"position":[[10,9],[67,13]]},"642":{"position":[[0,13]]},"904":{"position":[[0,11]]},"933":{"position":[[36,9]]},"1058":{"position":[[15,13]]},"1064":{"position":[[23,13]]},"1066":{"position":[[41,13]]},"1072":{"position":[[0,13]]},"1074":{"position":[[18,13]]},"1117":{"position":[[0,11]]},"1164":{"position":[[29,14]]},"1166":{"position":[[13,13]]},"1216":{"position":[[0,9]]},"1239":{"position":[[18,13]]},"1257":{"position":[[26,13]]},"1449":{"position":[[20,13]]},"1626":{"position":[[0,11]]},"1655":{"position":[[36,9]]},"1807":{"position":[[0,13]]},"1956":{"position":[[28,9]]},"2040":{"position":[[15,13]]},"2351":{"position":[[0,11]]},"2380":{"position":[[36,9]]},"2561":{"position":[[23,13]]},"3002":{"position":[[44,13]]}}}],["conform",{"_index":183,"t":{"283":{"position":[[15,11]]},"287":{"position":[[3,11]]},"360":{"position":[[11,10]]},"560":{"position":[[11,11]]},"2264":{"position":[[10,11]]},"2297":{"position":[[10,11]]},"2329":{"position":[[10,11]]},"2425":{"position":[[10,11]]},"2447":{"position":[[10,11]]},"2496":{"position":[[10,11]]},"2902":{"position":[[0,11]]},"2934":{"position":[[0,11]]},"2956":{"position":[[0,11]]},"2993":{"position":[[0,11]]},"3049":{"position":[[0,11]]},"3091":{"position":[[0,11]]},"3131":{"position":[[0,11]]},"3146":{"position":[[0,11]]},"3174":{"position":[[0,11]]},"3200":{"position":[[0,11]]},"3241":{"position":[[0,11]]},"3258":{"position":[[0,11]]},"3259":{"position":[[0,11]]},"3289":{"position":[[0,11]]},"3332":{"position":[[0,11]]},"3385":{"position":[[0,11]]},"3426":{"position":[[0,11]]},"3449":{"position":[[0,11]]},"3478":{"position":[[0,11]]},"3515":{"position":[[0,11]]}}}],["connect",{"_index":228,"t":{"356":{"position":[[15,7]]},"1956":{"position":[[57,8]]}}}],["consequ",{"_index":856,"t":{"3116":{"position":[[0,12]]},"3494":{"position":[[0,12]]}}}],["consid",{"_index":836,"t":{"2946":{"position":[[8,10]]},"2965":{"position":[[8,10]]},"3010":{"position":[[8,10]]},"3250":{"position":[[8,10]]},"3324":{"position":[[8,10]]},"3394":{"position":[[8,10]]},"3418":{"position":[[8,10]]},"3464":{"position":[[8,10]]},"3507":{"position":[[8,10]]}}}],["consider",{"_index":551,"t":{"1187":{"position":[[4,14]]},"1856":{"position":[[17,14]]},"1918":{"position":[[17,14]]},"2645":{"position":[[7,14]]},"2689":{"position":[[7,14]]},"2698":{"position":[[7,14]]},"2743":{"position":[[7,14]]},"2818":{"position":[[7,14]]},"2945":{"position":[[7,14]]},"2963":{"position":[[7,14]]},"2988":{"position":[[10,14]]},"3008":{"position":[[7,14]]},"3026":{"position":[[7,14]]},"3056":{"position":[[7,14]]},"3081":{"position":[[7,14]]},"3155":{"position":[[7,14]]},"3183":{"position":[[7,14]]},"3196":{"position":[[7,14]]},"3207":{"position":[[7,14]]},"3232":{"position":[[7,14]]},"3248":{"position":[[7,14]]},"3267":{"position":[[7,14]]},"3322":{"position":[[7,14]]},"3375":{"position":[[7,14]]},"3416":{"position":[[7,14]]},"3439":{"position":[[7,14]]},"3462":{"position":[[7,14]]},"3505":{"position":[[7,14]]}}}],["consist",{"_index":887,"t":{"3476":{"position":[[0,10]]}}}],["consol",{"_index":313,"t":{"541":{"position":[[5,7]]},"1196":{"position":[[8,7]]},"1848":{"position":[[22,7]]}}}],["contain",{"_index":224,"t":{"348":{"position":[[0,9]]},"433":{"position":[[15,9]]},"713":{"position":[[21,10]]},"1276":{"position":[[7,10]]},"1318":{"position":[[0,9]]},"1336":{"position":[[0,9]]},"1609":{"position":[[17,9]]},"2227":{"position":[[0,9]]},"2404":{"position":[[0,9]]},"3066":{"position":[[16,9]]}}}],["containerd",{"_index":355,"t":{"634":{"position":[[47,10]]}}}],["containerfil",{"_index":664,"t":{"1702":{"position":[[0,14]]}}}],["context",{"_index":235,"t":{"369":{"position":[[40,7]]},"3100":{"position":[[0,7]]},"3490":{"position":[[0,7]]}}}],["contribut",{"_index":61,"t":{"96":{"position":[[0,10]]},"356":{"position":[[0,10]]},"2271":{"position":[[0,12]]},"2303":{"position":[[0,12]]},"2335":{"position":[[0,12]]},"2431":{"position":[[0,12]]},"2450":{"position":[[0,12]]},"2507":{"position":[[0,12]]}}}],["contributor",{"_index":125,"t":{"177":{"position":[[26,11]]}}}],["control",{"_index":257,"t":{"395":{"position":[[29,10]]},"397":{"position":[[26,10]]},"745":{"position":[[16,7]]},"747":{"position":[[14,7]]},"975":{"position":[[0,7]]},"981":{"position":[[0,7]]},"1001":{"position":[[0,7]]}}}],["controversi",{"_index":114,"t":{"169":{"position":[[0,11]]}}}],["convent",{"_index":180,"t":{"281":{"position":[[7,11]]}}}],["converg",{"_index":480,"t":{"1010":{"position":[[6,9]]}}}],["convers",{"_index":709,"t":{"1912":{"position":[[20,10]]},"2028":{"position":[[20,10]]}}}],["convert",{"_index":693,"t":{"1838":{"position":[[7,7]]}}}],["cookiecutt",{"_index":496,"t":{"1062":{"position":[[12,12]]}}}],["copi",{"_index":559,"t":{"1239":{"position":[[6,4]]},"1836":{"position":[[7,4]]}}}],["copyleft",{"_index":121,"t":{"173":{"position":[[34,8]]}}}],["copyright",{"_index":123,"t":{"177":{"position":[[0,9]]}}}],["core",{"_index":280,"t":{"453":{"position":[[7,5]]}}}],["cpu",{"_index":525,"t":{"1123":{"position":[[0,3]]},"1181":{"position":[[5,4]]},"2704":{"position":[[11,3]]},"2724":{"position":[[11,3]]},"2749":{"position":[[11,3]]},"2763":{"position":[[11,3]]},"2839":{"position":[[11,3]]},"2849":{"position":[[11,3]]}}}],["creat",{"_index":250,"t":{"390":{"position":[[0,8]]},"410":{"position":[[0,6]]},"520":{"position":[[0,6]]},"529":{"position":[[5,6]]},"1058":{"position":[[0,8]]},"1255":{"position":[[8,6]]},"1355":{"position":[[0,6]]},"1455":{"position":[[0,6]]},"1463":{"position":[[0,6]]},"1844":{"position":[[7,6]]},"1858":{"position":[[7,6]]},"1920":{"position":[[7,6]]},"2050":{"position":[[0,8]]},"2052":{"position":[[0,8]]}}}],["create.pi",{"_index":409,"t":{"812":{"position":[[0,9]]},"818":{"position":[[0,9]]},"1502":{"position":[[0,9]]},"1508":{"position":[[0,9]]}}}],["creation",{"_index":674,"t":{"1733":{"position":[[9,8]]},"1910":{"position":[[6,8]]},"2026":{"position":[[6,8]]},"2044":{"position":[[24,8]]}}}],["credenti",{"_index":271,"t":{"422":{"position":[[18,11]]},"466":{"position":[[18,11]]}}}],["criteria",{"_index":241,"t":{"373":{"position":[[31,8]]},"2641":{"position":[[14,8]]},"2643":{"position":[[16,8]]}}}],["critic",{"_index":672,"t":{"1727":{"position":[[0,8]]}}}],["crossplan",{"_index":721,"t":{"1977":{"position":[[0,10]]}}}],["crush",{"_index":642,"t":{"1451":{"position":[[9,5]]},"1463":{"position":[[7,5]]},"1465":{"position":[[7,5]]}}}],["csi",{"_index":321,"t":{"564":{"position":[[11,3]]}}}],["cso",{"_index":314,"t":{"543":{"position":[[12,3]]}}}],["csp",{"_index":881,"t":{"3399":{"position":[[15,3]]}}}],["cspo",{"_index":315,"t":{"545":{"position":[[12,4]]}}}],["current",{"_index":218,"t":{"338":{"position":[[0,7]]},"1952":{"position":[[0,7]]}}}],["custom",{"_index":297,"t":{"498":{"position":[[4,13]]},"624":{"position":[[0,6]]},"906":{"position":[[0,6]]},"1164":{"position":[[0,13]]},"1272":{"position":[[7,6]]},"1628":{"position":[[0,6]]},"1782":{"position":[[0,6]]},"2353":{"position":[[0,6]]},"2978":{"position":[[10,6]]},"3077":{"position":[[25,6]]}}}],["customis",{"_index":660,"t":{"1583":{"position":[[0,14]]}}}],["dashboard",{"_index":449,"t":{"923":{"position":[[20,9]]},"933":{"position":[[50,9]]},"1115":{"position":[[0,9]]},"1117":{"position":[[58,9]]},"1645":{"position":[[20,9]]},"1655":{"position":[[50,9]]},"2210":{"position":[[23,10]]},"2211":{"position":[[33,10]]},"2370":{"position":[[20,9]]},"2380":{"position":[[50,9]]}}}],["data",{"_index":212,"t":{"316":{"position":[[32,5]]},"445":{"position":[[0,4]]},"923":{"position":[[0,4]]},"1002":{"position":[[0,4]]},"1410":{"position":[[6,4]]},"1645":{"position":[[0,4]]},"1875":{"position":[[28,4]]},"1881":{"position":[[7,4]]},"1887":{"position":[[7,4]]},"1991":{"position":[[28,4]]},"1997":{"position":[[7,4]]},"2003":{"position":[[7,4]]},"2370":{"position":[[0,4]]}}}],["databas",{"_index":274,"t":{"448":{"position":[[0,8]]},"1733":{"position":[[0,8]]},"3409":{"position":[[0,8]]}}}],["day",{"_index":157,"t":{"228":{"position":[[14,3]]},"230":{"position":[[20,3]]}}}],["db",{"_index":595,"t":{"1385":{"position":[[37,2]]}}}],["deactiv",{"_index":489,"t":{"1028":{"position":[[32,11]]}}}],["debian",{"_index":485,"t":{"1016":{"position":[[0,6]]}}}],["debug",{"_index":338,"t":{"589":{"position":[[26,9]]},"944":{"position":[[0,9]]},"1666":{"position":[[0,9]]},"2391":{"position":[[0,9]]}}}],["decis",{"_index":837,"t":{"2948":{"position":[[0,8]]},"2969":{"position":[[0,8]]},"3015":{"position":[[0,8]]},"3070":{"position":[[0,8]]},"3114":{"position":[[0,9]]},"3127":{"position":[[0,8]]},"3138":{"position":[[0,8]]},"3170":{"position":[[0,8]]},"3185":{"position":[[0,8]]},"3198":{"position":[[0,8]]},"3237":{"position":[[0,8]]},"3254":{"position":[[0,8]]},"3277":{"position":[[0,8]]},"3302":{"position":[[0,8]]},"3311":{"position":[[0,8]]},"3328":{"position":[[0,8]]},"3341":{"position":[[0,8]]},"3379":{"position":[[0,8]]},"3396":{"position":[[0,9]]},"3406":{"position":[[0,8]]},"3422":{"position":[[0,8]]},"3445":{"position":[[0,8]]},"3469":{"position":[[0,8]]},"3481":{"position":[[0,8]]},"3492":{"position":[[0,8]]}}}],["decrypt",{"_index":710,"t":{"1912":{"position":[[34,7]]},"2028":{"position":[[34,7]]}}}],["deep",{"_index":602,"t":{"1403":{"position":[[15,5]]},"1441":{"position":[[6,5]]}}}],["deeper",{"_index":871,"t":{"3300":{"position":[[0,6]]}}}],["default",{"_index":304,"t":{"510":{"position":[[27,7]]},"640":{"position":[[0,7]]},"811":{"position":[[0,8]]},"856":{"position":[[0,8]]},"1040":{"position":[[0,8]]},"1501":{"position":[[0,8]]},"1600":{"position":[[0,8]]},"1700":{"position":[[9,8]]},"1860":{"position":[[0,7]]},"1922":{"position":[[0,7]]},"3032":{"position":[[0,7]]},"3077":{"position":[[0,7],[52,7]]},"3106":{"position":[[27,7],[49,9]]},"3476":{"position":[[22,7]]}}}],["defect",{"_index":621,"t":{"1426":{"position":[[10,6]]},"2084":{"position":[[0,6]]}}}],["defin",{"_index":493,"t":{"1051":{"position":[[0,6]]},"1744":{"position":[[0,6]]}}}],["definit",{"_index":380,"t":{"731":{"position":[[0,11]]},"737":{"position":[[0,10]]},"739":{"position":[[0,10]]},"741":{"position":[[0,10]]},"743":{"position":[[0,10]]},"745":{"position":[[0,10]]},"747":{"position":[[0,10]]},"749":{"position":[[0,10]]},"751":{"position":[[0,10]]},"753":{"position":[[0,10]]},"755":{"position":[[0,10]]},"791":{"position":[[6,11]]},"1492":{"position":[[0,11]]},"1528":{"position":[[6,11]]},"3342":{"position":[[7,11]]},"3371":{"position":[[0,11]]},"3435":{"position":[[0,11]]}}}],["defragment",{"_index":341,"t":{"595":{"position":[[0,15]]}}}],["delet",{"_index":577,"t":{"1306":{"position":[[0,6]]},"1459":{"position":[[0,6]]}}}],["demonstr",{"_index":29,"t":{"42":{"position":[[31,12]]}}}],["depend",{"_index":109,"t":{"161":{"position":[[20,12]]},"2821":{"position":[[0,10]]}}}],["deploy",{"_index":208,"t":{"307":{"position":[[34,11]]},"345":{"position":[[14,10]]},"543":{"position":[[5,6]]},"545":{"position":[[5,6]]},"589":{"position":[[15,10]]},"640":{"position":[[8,10]]},"1253":{"position":[[0,6]]},"1261":{"position":[[8,6]]},"1611":{"position":[[12,10]]},"1778":{"position":[[0,10]]},"1797":{"position":[[0,6]]},"1938":{"position":[[0,10]]},"2090":{"position":[[46,8]]},"2092":{"position":[[38,10]]},"2094":{"position":[[0,6]]},"2105":{"position":[[0,6]]},"2127":{"position":[[0,6]]}}}],["deprec",{"_index":767,"t":{"2258":{"position":[[0,12]]},"2291":{"position":[[0,12]]},"2322":{"position":[[0,12]]},"2323":{"position":[[0,12]]},"2418":{"position":[[0,12]]},"2419":{"position":[[0,12]]},"2444":{"position":[[0,12]]},"2481":{"position":[[0,12]]},"2636":{"position":[[0,11],[18,12]]}}}],["deriv",{"_index":116,"t":{"173":{"position":[[0,7]]}}}],["descript",{"_index":840,"t":{"3028":{"position":[[11,11]]}}}],["descriptor",{"_index":821,"t":{"2806":{"position":[[13,10]]},"2808":{"position":[[8,10]]},"2810":{"position":[[9,10]]},"2812":{"position":[[6,10]]}}}],["design",{"_index":422,"t":{"869":{"position":[[8,6]]},"2645":{"position":[[0,6]]},"2689":{"position":[[0,6]]},"2698":{"position":[[0,6]]},"2743":{"position":[[0,6]]},"2818":{"position":[[0,6]]},"2945":{"position":[[0,6]]},"2963":{"position":[[0,6]]},"3008":{"position":[[0,6]]},"3026":{"position":[[0,6]]},"3056":{"position":[[0,6]]},"3081":{"position":[[0,6]]},"3155":{"position":[[0,6]]},"3183":{"position":[[0,6]]},"3196":{"position":[[0,6]]},"3207":{"position":[[0,6]]},"3232":{"position":[[0,6]]},"3248":{"position":[[0,6]]},"3267":{"position":[[0,6]]},"3322":{"position":[[0,6]]},"3375":{"position":[[0,6]]},"3416":{"position":[[0,6]]},"3439":{"position":[[0,6]]},"3462":{"position":[[0,6]]},"3505":{"position":[[0,6]]}}}],["desir",{"_index":858,"t":{"3159":{"position":[[13,9]]},"3460":{"position":[[0,7]]}}}],["detach",{"_index":325,"t":{"571":{"position":[[5,6]]},"1883":{"position":[[10,8]]},"1889":{"position":[[24,8]]},"1999":{"position":[[10,8]]},"2005":{"position":[[24,8]]}}}],["detail",{"_index":711,"t":{"1956":{"position":[[0,8]]},"2703":{"position":[[9,7]]},"2724":{"position":[[28,7]]},"2748":{"position":[[9,7]]},"2763":{"position":[[28,7]]},"2838":{"position":[[9,7]]},"2849":{"position":[[28,7]]},"3040":{"position":[[15,7]]}}}],["develop",{"_index":111,"t":{"163":{"position":[[22,11]]},"352":{"position":[[0,11]]},"386":{"position":[[0,10]]},"1590":{"position":[[0,11]]},"2249":{"position":[[4,9]]},"2282":{"position":[[4,9]]},"2316":{"position":[[4,9]]},"2410":{"position":[[4,9]]},"2441":{"position":[[4,9]]},"2469":{"position":[[4,9]]},"2632":{"position":[[0,11]]}}}],["devic",{"_index":522,"t":{"1111":{"position":[[4,7]]},"1407":{"position":[[34,7]]},"1408":{"position":[[26,7]]},"1410":{"position":[[33,7]]},"1412":{"position":[[23,6]]},"1414":{"position":[[14,6]]}}}],["differ",{"_index":365,"t":{"699":{"position":[[15,9]]},"1414":{"position":[[26,9]]},"1463":{"position":[[23,9]]},"3211":{"position":[[17,9]]}}}],["direct",{"_index":91,"t":{"138":{"position":[[34,9]]},"1696":{"position":[[7,9]]},"1698":{"position":[[5,9]]},"2269":{"position":[[7,10]]}}}],["directori",{"_index":667,"t":{"1710":{"position":[[33,11]]},"1716":{"position":[[19,11]]}}}],["disabl",{"_index":99,"t":{"150":{"position":[[0,7]]},"510":{"position":[[0,8]]},"1374":{"position":[[0,7]]},"1433":{"position":[[0,7]]}}}],["disable/en",{"_index":601,"t":{"1403":{"position":[[0,14]]}}}],["discoveri",{"_index":195,"t":{"299":{"position":[[23,9]]},"2475":{"position":[[27,9]]}}}],["disk",{"_index":624,"t":{"1431":{"position":[[56,5]]},"2708":{"position":[[11,4]]},"2753":{"position":[[11,4]]},"2843":{"position":[[11,4]]}}}],["dispatch",{"_index":510,"t":{"1092":{"position":[[0,10]]}}}],["display",{"_index":568,"t":{"1281":{"position":[[0,7]]},"1751":{"position":[[23,10]]},"1755":{"position":[[18,9]]}}}],["distribut",{"_index":277,"t":{"450":{"position":[[4,12]]},"1015":{"position":[[0,12]]},"2666":{"position":[[0,11]]}}}],["doc",{"_index":596,"t":{"1394":{"position":[[14,4]]},"1725":{"position":[[14,4]]}}}],["docker",{"_index":554,"t":{"1200":{"position":[[0,6]]},"1612":{"position":[[0,6]]},"3215":{"position":[[18,8]]},"3217":{"position":[[7,7]]}}}],["docs.json",{"_index":74,"t":{"113":{"position":[[33,9]]}}}],["document",{"_index":67,"t":{"108":{"position":[[9,13]]},"110":{"position":[[13,13]]},"115":{"position":[[15,13]]},"117":{"position":[[13,13]]},"376":{"position":[[23,8]]},"2490":{"position":[[0,13]]},"2620":{"position":[[25,9]]},"2622":{"position":[[9,9]]},"2624":{"position":[[0,8]]},"2666":{"position":[[12,13]]},"2691":{"position":[[8,9]]},"2954":{"position":[[8,9]]},"2971":{"position":[[8,9]]},"3017":{"position":[[8,9]]},"3047":{"position":[[8,9]]},"3089":{"position":[[8,9]]},"3118":{"position":[[8,9]]},"3129":{"position":[[8,9]]},"3144":{"position":[[8,9]]},"3163":{"position":[[8,9]]},"3172":{"position":[[8,9]]},"3187":{"position":[[0,9]]},"3239":{"position":[[8,9]]},"3246":{"position":[[20,8]]},"3256":{"position":[[8,9]]},"3287":{"position":[[8,9]]},"3304":{"position":[[8,9]]},"3330":{"position":[[8,9]]},"3383":{"position":[[8,9]]},"3424":{"position":[[8,9]]},"3447":{"position":[[8,9]]},"3473":{"position":[[8,9]]},"3496":{"position":[[8,9]]},"3513":{"position":[[8,9]]}}}],["dojo",{"_index":738,"t":{"2084":{"position":[[7,4]]}}}],["domain",{"_index":535,"t":{"1149":{"position":[[0,6]]},"1956":{"position":[[117,7]]},"2038":{"position":[[34,6]]},"2046":{"position":[[10,6]]},"2050":{"position":[[9,7]]},"2052":{"position":[[11,6]]},"2054":{"position":[[14,6]]},"2056":{"position":[[13,6]]},"2058":{"position":[[0,6]]},"2060":{"position":[[24,6]]},"2062":{"position":[[27,6]]},"2064":{"position":[[25,6]]},"2066":{"position":[[35,6]]},"2471":{"position":[[9,6]]},"2488":{"position":[[36,6]]}}}],["down",{"_index":591,"t":{"1376":{"position":[[6,4]]}}}],["download",{"_index":533,"t":{"1145":{"position":[[21,12]]},"1877":{"position":[[19,8]]},"1893":{"position":[[30,8]]},"1993":{"position":[[19,8]]},"2009":{"position":[[30,8]]}}}],["draft",{"_index":797,"t":{"2632":{"position":[[18,7]]}}}],["dri",{"_index":327,"t":{"575":{"position":[[5,3]]},"1714":{"position":[[11,4]]}}}],["drive",{"_index":616,"t":{"1416":{"position":[[20,5]]},"1418":{"position":[[24,5]]}}}],["driver",{"_index":431,"t":{"896":{"position":[[15,6]]},"902":{"position":[[0,6]]},"904":{"position":[[33,6]]},"1216":{"position":[[18,7]]},"1618":{"position":[[15,6]]},"1624":{"position":[[0,6]]},"1626":{"position":[[33,6]]},"2343":{"position":[[15,6]]},"2349":{"position":[[0,6]]},"2351":{"position":[[33,6]]}}}],["dummi",{"_index":511,"t":{"1093":{"position":[[0,5]]}}}],["dump",{"_index":629,"t":{"1437":{"position":[[0,4]]},"1451":{"position":[[0,4]]}}}],["dynam",{"_index":839,"t":{"3002":{"position":[[28,7]]}}}],["e.g",{"_index":366,"t":{"699":{"position":[[55,5]]},"1431":{"position":[[27,4]]}}}],["e2",{"_index":848,"t":{"3060":{"position":[[59,3]]}}}],["ec2",{"_index":270,"t":{"422":{"position":[[14,3]]},"466":{"position":[[14,3]]}}}],["edit",{"_index":695,"t":{"1840":{"position":[[0,4]]},"2080":{"position":[[20,7]]}}}],["editor",{"_index":670,"t":{"1718":{"position":[[22,7]]}}}],["email",{"_index":448,"t":{"919":{"position":[[0,5]]},"1641":{"position":[[0,5]]},"2366":{"position":[[0,5]]}}}],["enabl",{"_index":487,"t":{"1026":{"position":[[10,6]]},"1374":{"position":[[10,6]]},"1457":{"position":[[0,8]]},"2113":{"position":[[0,6]]}}}],["encrypt",{"_index":705,"t":{"1895":{"position":[[11,10]]},"1903":{"position":[[25,9]]},"1912":{"position":[[5,10]]},"2011":{"position":[[11,10]]},"2019":{"position":[[25,9]]},"2028":{"position":[[5,10]]},"3041":{"position":[[0,10]]}}}],["endpoint",{"_index":415,"t":{"826":{"position":[[6,9]]},"1157":{"position":[[0,9]]},"1158":{"position":[[7,9]]},"1160":{"position":[[34,9]]},"1516":{"position":[[6,9]]},"3235":{"position":[[21,9]]},"3348":{"position":[[0,8]]}}}],["entir",{"_index":668,"t":{"1712":{"position":[[14,6]]}}}],["entri",{"_index":683,"t":{"1786":{"position":[[7,7]]}}}],["entropi",{"_index":825,"t":{"2867":{"position":[[0,7]]},"2869":{"position":[[19,7]]},"2871":{"position":[[11,7]]},"2873":{"position":[[0,7]]},"2877":{"position":[[0,7]]}}}],["enumer",{"_index":607,"t":{"1408":{"position":[[0,9]]}}}],["environ",{"_index":291,"t":{"480":{"position":[[52,11]]},"518":{"position":[[12,11]]},"618":{"position":[[0,12]]},"620":{"position":[[21,11]]},"622":{"position":[[10,11]]},"624":{"position":[[7,11]]},"695":{"position":[[45,12]]},"699":{"position":[[42,12]]},"701":{"position":[[31,12]]},"2090":{"position":[[6,11]]},"2519":{"position":[[16,12]]},"3215":{"position":[[6,11]]}}}],["ephemer",{"_index":701,"t":{"1879":{"position":[[0,9]]},"1995":{"position":[[0,9]]}}}],["eras",{"_index":615,"t":{"1416":{"position":[[7,5]]},"1418":{"position":[[7,5]]}}}],["err",{"_index":260,"t":{"403":{"position":[[30,3]]}}}],["error",{"_index":639,"t":{"1445":{"position":[[41,6]]},"1727":{"position":[[16,5]]},"1802":{"position":[[8,6]]},"2785":{"position":[[0,6]]},"2910":{"position":[[0,6]]}}}],["etc/host",{"_index":684,"t":{"1786":{"position":[[18,10]]}}}],["etc/interfac",{"_index":512,"t":{"1095":{"position":[[0,15]]}}}],["etcd",{"_index":339,"t":{"593":{"position":[[0,4]]},"614":{"position":[[0,4]]},"3271":{"position":[[0,4]]},"3273":{"position":[[0,4]]},"3281":{"position":[[0,4]]},"3283":{"position":[[0,4]]}}}],["evacu",{"_index":417,"t":{"834":{"position":[[0,10]]},"1549":{"position":[[0,10]]}}}],["evalu",{"_index":870,"t":{"3298":{"position":[[0,9]]}}}],["even",{"_index":145,"t":{"203":{"position":[[14,7]]},"211":{"position":[[10,7]]}}}],["event",{"_index":150,"t":{"211":{"position":[[18,5]]}}}],["event_definitions.yaml",{"_index":791,"t":{"2565":{"position":[[4,22]]}}}],["event_pipeline.yaml",{"_index":792,"t":{"2567":{"position":[[4,19]]}}}],["exampl",{"_index":149,"t":{"207":{"position":[[16,10]]},"216":{"position":[[10,8]]},"220":{"position":[[12,8]]},"285":{"position":[[12,7]]},"345":{"position":[[25,8]]},"375":{"position":[[0,8]]},"376":{"position":[[4,8]]},"380":{"position":[[4,8]]},"1038":{"position":[[0,7]]},"1090":{"position":[[0,7]]},"1113":{"position":[[5,8]]},"1160":{"position":[[0,7]]},"1685":{"position":[[0,7]]},"1720":{"position":[[0,7]]},"1748":{"position":[[0,7]]},"2141":{"position":[[0,7]]},"2732":{"position":[[9,8]]},"2771":{"position":[[9,8]]},"2814":{"position":[[6,7]]},"2853":{"position":[[9,8]]},"2986":{"position":[[5,7]]},"3045":{"position":[[0,7]]},"3058":{"position":[[76,8]]},"3087":{"position":[[0,7]]}}}],["exclud",{"_index":669,"t":{"1716":{"position":[[0,9]]}}}],["exempl",{"_index":153,"t":{"218":{"position":[[6,8]]}}}],["exist",{"_index":354,"t":{"634":{"position":[[23,8]]},"2054":{"position":[[40,8]]},"3309":{"position":[[0,8]]}}}],["expir",{"_index":334,"t":{"585":{"position":[[34,6]]},"587":{"position":[[22,7]]}}}],["export",{"_index":750,"t":{"2211":{"position":[[11,9]]}}}],["expos",{"_index":524,"t":{"1117":{"position":[[42,6]]}}}],["exposur",{"_index":725,"t":{"2038":{"position":[[22,8]]}}}],["extens",{"_index":814,"t":{"2718":{"position":[[0,10]]},"2757":{"position":[[0,10]]}}}],["extern",{"_index":434,"t":{"898":{"position":[[12,8]]},"1355":{"position":[[10,8]]},"1584":{"position":[[19,8]]},"1620":{"position":[[12,8]]},"1793":{"position":[[0,8]]},"2345":{"position":[[12,8]]},"3233":{"position":[[0,8]]}}}],["extra",{"_index":490,"t":{"1036":{"position":[[0,5]]},"1109":{"position":[[0,5]]},"2851":{"position":[[11,5]]},"2922":{"position":[[11,6]]}}}],["fabric",{"_index":514,"t":{"1097":{"position":[[5,6]]}}}],["fact",{"_index":582,"t":{"1328":{"position":[[5,5]]}}}],["fail",{"_index":337,"t":{"589":{"position":[[0,6]]},"1720":{"position":[[11,6]]},"1733":{"position":[[18,5]]}}}],["failur",{"_index":462,"t":{"946":{"position":[[10,8]]},"1668":{"position":[[10,8]]},"2393":{"position":[[10,8]]}}}],["faq`",{"_index":62,"t":{"98":{"position":[[0,5]]}}}],["featur",{"_index":216,"t":{"334":{"position":[[0,8]]},"1948":{"position":[[0,8]]},"2189":{"position":[[0,8]]},"2246":{"position":[[4,8]]},"2279":{"position":[[4,8]]},"2313":{"position":[[4,8]]},"2439":{"position":[[4,8]]},"2466":{"position":[[4,8]]},"2851":{"position":[[17,8]]},"2891":{"position":[[27,8]]},"3159":{"position":[[23,8]]},"3209":{"position":[[9,8]]}}}],["feder",{"_index":202,"t":{"303":{"position":[[23,9]]},"305":{"position":[[37,9]]},"307":{"position":[[8,10]]},"1151":{"position":[[5,10]]},"1944":{"position":[[11,10]]},"1956":{"position":[[38,10]]},"2218":{"position":[[0,10]]}}}],["field",{"_index":875,"t":{"3346":{"position":[[11,6]]}}}],["file",{"_index":412,"t":{"822":{"position":[[7,5]]},"860":{"position":[[7,5]]},"921":{"position":[[4,5]]},"1145":{"position":[[16,4],[62,4]]},"1314":{"position":[[0,5]]},"1512":{"position":[[7,5]]},"1604":{"position":[[7,5]]},"1643":{"position":[[4,5]]},"1708":{"position":[[20,4]]},"1710":{"position":[[20,5]]},"1716":{"position":[[10,5]]},"2368":{"position":[[4,5]]},"2819":{"position":[[0,4]]}}}],["filter",{"_index":783,"t":{"2488":{"position":[[22,9]]}}}],["find",{"_index":364,"t":{"697":{"position":[[12,4]]},"721":{"position":[[40,4]]},"1394":{"position":[[9,4]]},"1725":{"position":[[9,4]]}}}],["first",{"_index":437,"t":{"908":{"position":[[5,5]]},"1630":{"position":[[5,5]]},"2355":{"position":[[5,5]]}}}],["fix",{"_index":768,"t":{"2260":{"position":[[9,5]]},"2293":{"position":[[9,5]]},"2325":{"position":[[9,5]]},"2421":{"position":[[9,5]]},"2445":{"position":[[9,5]]},"2483":{"position":[[9,5]]}}}],["flasharray",{"_index":528,"t":{"1129":{"position":[[13,10]]}}}],["flavor",{"_index":811,"t":{"2701":{"position":[[33,6]]},"2710":{"position":[[13,7]]},"2746":{"position":[[33,6]]},"2855":{"position":[[13,7]]},"2878":{"position":[[0,7]]},"2924":{"position":[[13,7]]}}}],["fluxcd",{"_index":264,"t":{"414":{"position":[[30,6]]}}}],["focus",{"_index":765,"t":{"2247":{"position":[[9,7]]},"2249":{"position":[[14,7]]},"2280":{"position":[[9,7]]},"2282":{"position":[[14,7]]},"2314":{"position":[[9,7]]},"2316":{"position":[[14,7]]},"2410":{"position":[[14,7]]},"2440":{"position":[[9,7]]},"2441":{"position":[[14,7]]},"2467":{"position":[[9,7]]},"2469":{"position":[[14,7]]},"3112":{"position":[[19,7]]}}}],["footnot",{"_index":722,"t":{"1983":{"position":[[0,9]]},"2068":{"position":[[0,9]]},"2171":{"position":[[0,9]]},"3093":{"position":[[0,9]]},"3120":{"position":[[0,9]]},"3483":{"position":[[0,9]]}}}],["forc",{"_index":590,"t":{"1376":{"position":[[0,5]]}}}],["format",{"_index":612,"t":{"1412":{"position":[[6,6]]},"1414":{"position":[[0,6],[40,6]]},"1708":{"position":[[0,10]]},"1710":{"position":[[0,10]]},"1712":{"position":[[0,10]]},"2624":{"position":[[9,6]]},"2676":{"position":[[18,6]]},"2819":{"position":[[5,6]]}}}],["forward",{"_index":864,"t":{"3221":{"position":[[14,7]]}}}],["found",{"_index":636,"t":{"1443":{"position":[[33,8]]}}}],["four",{"_index":160,"t":{"239":{"position":[[4,5]]}}}],["framework",{"_index":749,"t":{"2207":{"position":[[3,9]]},"3058":{"position":[[41,9]]},"3060":{"position":[[87,9]]}}}],["friendli",{"_index":133,"t":{"186":{"position":[[21,8]]}}}],["frontend",{"_index":746,"t":{"2147":{"position":[[6,8]]},"2167":{"position":[[20,8]]}}}],["full",{"_index":523,"t":{"1113":{"position":[[0,4]]},"2986":{"position":[[0,4]]}}}],["fullclean",{"_index":317,"t":{"551":{"position":[[5,9]]}}}],["fundament",{"_index":278,"t":{"452":{"position":[[0,11]]}}}],["further",{"_index":129,"t":{"181":{"position":[[0,7]]},"254":{"position":[[0,7]]},"1476":{"position":[[21,7]]},"1856":{"position":[[0,7]]},"1918":{"position":[[0,7]]},"2802":{"position":[[24,7]]},"3083":{"position":[[0,7]]}}}],["futur",{"_index":220,"t":{"338":{"position":[[18,6]]},"1952":{"position":[[18,6]]},"2269":{"position":[[0,6]]}}}],["gaia",{"_index":27,"t":{"42":{"position":[[24,4]]},"2863":{"position":[[12,4]]}}}],["garden",{"_index":428,"t":{"889":{"position":[[24,8]]}}}],["gate",{"_index":171,"t":{"267":{"position":[[33,6]]}}}],["gather",{"_index":605,"t":{"1407":{"position":[[0,9]]}}}],["gener",{"_index":173,"t":{"271":{"position":[[0,7]]},"506":{"position":[[22,7]]},"528":{"position":[[0,7]]},"733":{"position":[[16,9]]},"1066":{"position":[[31,9]]},"1398":{"position":[[0,7]]},"1494":{"position":[[16,9]]},"1565":{"position":[[0,7]]}}}],["get",{"_index":3,"t":{"8":{"position":[[0,7]]},"42":{"position":[[0,7]]},"47":{"position":[[0,7]]},"92":{"position":[[0,7]]},"504":{"position":[[0,7]]},"506":{"position":[[0,7]]},"789":{"position":[[0,7]]},"1526":{"position":[[0,7]]}}}],["gib",{"_index":531,"t":{"1143":{"position":[[48,3]]}}}],["git",{"_index":498,"t":{"1064":{"position":[[51,3]]},"1751":{"position":[[5,3]]},"1753":{"position":[[5,3]]}}}],["github",{"_index":79,"t":{"123":{"position":[[0,6]]},"1746":{"position":[[0,6]]}}}],["gitrepositori",{"_index":266,"t":{"414":{"position":[[55,13]]}}}],["glanc",{"_index":393,"t":{"763":{"position":[[0,6]]},"785":{"position":[[24,8]]},"1522":{"position":[[24,8]]},"1879":{"position":[[31,6]]},"1887":{"position":[[25,6]]},"1889":{"position":[[0,6]]},"1891":{"position":[[0,6]]},"1995":{"position":[[31,6]]},"2003":{"position":[[25,6]]},"2005":{"position":[[0,6]]},"2007":{"position":[[0,6]]}}}],["global",{"_index":619,"t":{"1423":{"position":[[17,7]]}}}],["glossari",{"_index":699,"t":{"1871":{"position":[[0,8]]},"1987":{"position":[[0,8]]},"3022":{"position":[[0,8]]},"3179":{"position":[[0,8]]},"3192":{"position":[[0,8]]},"3263":{"position":[[0,8]]},"3454":{"position":[[0,8]]}}}],["goal",{"_index":758,"t":{"2228":{"position":[[13,5]]}}}],["golang",{"_index":844,"t":{"3058":{"position":[[9,6]]},"3060":{"position":[[9,6]]}}}],["gpu",{"_index":816,"t":{"2726":{"position":[[11,3]]},"2765":{"position":[[11,3]]}}}],["grafana",{"_index":456,"t":{"931":{"position":[[0,7]]},"960":{"position":[[24,7]]},"1653":{"position":[[0,7]]},"2211":{"position":[[25,7]]},"2378":{"position":[[0,7]]}}}],["graph",{"_index":823,"t":{"2821":{"position":[[11,5]]}}}],["greenbon",{"_index":735,"t":{"2080":{"position":[[0,9]]}}}],["group",{"_index":48,"t":{"66":{"position":[[17,6]]},"328":{"position":[[7,6]]},"1050":{"position":[[0,5]]},"1436":{"position":[[10,5]]},"1437":{"position":[[15,6]]},"1441":{"position":[[38,5]]},"1858":{"position":[[23,6]]},"1860":{"position":[[17,5]]},"1862":{"position":[[21,6]]},"1864":{"position":[[20,6]]},"1920":{"position":[[23,6]]},"1922":{"position":[[17,5]]},"1924":{"position":[[21,6]]},"1926":{"position":[[20,6]]},"2064":{"position":[[9,6]]},"3077":{"position":[[17,7],[41,6],[69,5]]},"3102":{"position":[[48,6]]},"3106":{"position":[[68,5]]}}}],["guarante",{"_index":834,"t":{"2930":{"position":[[0,10]]}}}],["guid",{"_index":103,"t":{"156":{"position":[[13,5]]},"2676":{"position":[[33,5]]},"3112":{"position":[[27,5]]}}}],["hack",{"_index":49,"t":{"66":{"position":[[35,7]]}}}],["hackathon",{"_index":138,"t":{"190":{"position":[[26,9]]},"194":{"position":[[26,9]]},"201":{"position":[[26,9]]},"209":{"position":[[26,9]]},"213":{"position":[[26,9]]},"224":{"position":[[25,9]]},"226":{"position":[[24,9]]},"228":{"position":[[25,9]]},"230":{"position":[[10,9]]},"232":{"position":[[16,9]]}}}],["handl",{"_index":663,"t":{"1673":{"position":[[7,6]]},"2893":{"position":[[6,8]]}}}],["hang",{"_index":679,"t":{"1757":{"position":[[0,7]]}}}],["harbor",{"_index":22,"t":{"35":{"position":[[16,6]]},"412":{"position":[[8,6]]},"433":{"position":[[8,6]]},"441":{"position":[[8,6]]},"473":{"position":[[7,6]]},"475":{"position":[[8,6]]}}}],["hardwar",{"_index":423,"t":{"873":{"position":[[0,8]]},"2722":{"position":[[11,8]]},"2761":{"position":[[11,8]]},"2847":{"position":[[11,8]]}}}],["hci",{"_index":482,"t":{"1010":{"position":[[31,5]]}}}],["hdparm",{"_index":617,"t":{"1418":{"position":[[36,6]]}}}],["health",{"_index":302,"t":{"510":{"position":[[9,6]]},"939":{"position":[[19,6]]},"1401":{"position":[[14,6]]},"1661":{"position":[[19,6]]},"2213":{"position":[[10,6]]},"2386":{"position":[[19,6]]},"3157":{"position":[[4,6]]}}}],["health_warn",{"_index":633,"t":{"1443":{"position":[[0,11]]}}}],["helm",{"_index":332,"t":{"582":{"position":[[33,4]]}}}],["help",{"_index":379,"t":{"721":{"position":[[45,5]]},"1476":{"position":[[29,4]]}}}],["hetzner",{"_index":861,"t":{"3213":{"position":[[26,8]]}}}],["highlevel",{"_index":421,"t":{"863":{"position":[[0,9]]}}}],["highlight",{"_index":764,"t":{"2244":{"position":[[49,12]]},"2246":{"position":[[13,12]]},"2269":{"position":[[28,11]]},"2277":{"position":[[49,12]]},"2279":{"position":[[13,12]]},"2311":{"position":[[49,12]]},"2313":{"position":[[13,12]]},"2401":{"position":[[49,12]]},"2438":{"position":[[49,12]]},"2439":{"position":[[13,12]]},"2457":{"position":[[49,12]]},"2466":{"position":[[13,12]]},"2492":{"position":[[0,11]]}}}],["home",{"_index":780,"t":{"2475":{"position":[[18,4]]}}}],["horizon",{"_index":200,"t":{"303":{"position":[[4,7]]},"757":{"position":[[0,7]]}}}],["host",{"_index":342,"t":{"599":{"position":[[11,4]]},"601":{"position":[[24,4]]},"741":{"position":[[14,4]]},"1049":{"position":[[0,4]]},"1179":{"position":[[0,4]]},"1181":{"position":[[0,4]]},"1324":{"position":[[0,5]]},"1326":{"position":[[0,4]]},"1328":{"position":[[0,4]]},"1382":{"position":[[0,4]]}}}],["hotel",{"_index":141,"t":{"196":{"position":[[10,5]]}}}],["httpx",{"_index":733,"t":{"2076":{"position":[[0,5]]}}}],["huge",{"_index":592,"t":{"1378":{"position":[[0,4]]}}}],["hyper",{"_index":479,"t":{"1010":{"position":[[0,5]]}}}],["hypervisor",{"_index":815,"t":{"2720":{"position":[[11,10]]},"2759":{"position":[[11,10]]},"2845":{"position":[[11,10]]}}}],["iaa",{"_index":188,"t":{"291":{"position":[[3,4]]},"346":{"position":[[0,4]]},"707":{"position":[[60,6]]},"709":{"position":[[10,4]]},"711":{"position":[[11,4]]},"2094":{"position":[[7,4]]},"2402":{"position":[[0,4]]},"2458":{"position":[[0,4]]},"2485":{"position":[[24,4]]},"2501":{"position":[[0,4]]},"3213":{"position":[[0,4]]}}}],["iam",{"_index":775,"t":{"2408":{"position":[[15,3]]},"2464":{"position":[[0,3]]},"2494":{"position":[[0,3]]},"2505":{"position":[[0,3]]}}}],["ident",{"_index":471,"t":{"974":{"position":[[0,8]]},"1942":{"position":[[0,8]]}}}],["identifi",{"_index":517,"t":{"1101":{"position":[[7,10]]},"1854":{"position":[[0,8]]},"1916":{"position":[[0,8]]}}}],["idp",{"_index":193,"t":{"299":{"position":[[13,3]]},"2475":{"position":[[23,3]]}}}],["imag",{"_index":402,"t":{"785":{"position":[[10,5]]},"791":{"position":[[0,5]]},"793":{"position":[[4,5]]},"795":{"position":[[0,5]]},"797":{"position":[[0,5]]},"802":{"position":[[10,6]]},"804":{"position":[[9,6]]},"1143":{"position":[[27,6]]},"1155":{"position":[[0,5]]},"1522":{"position":[[10,5]]},"1528":{"position":[[0,5]]},"1530":{"position":[[4,5]]},"1532":{"position":[[0,5]]},"1534":{"position":[[0,5]]},"1539":{"position":[[10,6]]},"1541":{"position":[[9,6]]},"1579":{"position":[[21,6]]},"1609":{"position":[[27,5]]},"1836":{"position":[[17,6]]},"1840":{"position":[[13,6]]},"1842":{"position":[[14,6]]},"1877":{"position":[[0,5]]},"1879":{"position":[[38,6]]},"1887":{"position":[[32,6]]},"1889":{"position":[[7,5]]},"1891":{"position":[[7,5]]},"1901":{"position":[[37,5]]},"1903":{"position":[[35,5]]},"1905":{"position":[[34,5]]},"1910":{"position":[[0,5]]},"1912":{"position":[[49,6]]},"1993":{"position":[[0,5]]},"1995":{"position":[[38,6]]},"2003":{"position":[[32,6]]},"2005":{"position":[[7,5]]},"2007":{"position":[[7,5]]},"2017":{"position":[[37,5]]},"2019":{"position":[[35,5]]},"2021":{"position":[[34,5]]},"2026":{"position":[[0,5]]},"2028":{"position":[[49,6]]},"2880":{"position":[[0,6]]},"2893":{"position":[[0,5]]},"2894":{"position":[[0,5]]},"2896":{"position":[[0,5]]},"2898":{"position":[[0,5]]},"2908":{"position":[[0,6]]},"2978":{"position":[[17,6]]},"2980":{"position":[[9,6]]},"2982":{"position":[[0,5],[28,5]]},"2984":{"position":[[0,5],[30,6]]},"2991":{"position":[[0,5]]},"3064":{"position":[[42,5]]},"3068":{"position":[[15,5]]}}}],["impact",{"_index":440,"t":{"910":{"position":[[9,6]]},"1632":{"position":[[9,6]]},"2357":{"position":[[9,6]]},"3354":{"position":[[0,6]]},"3358":{"position":[[10,7]]},"3456":{"position":[[0,6]]}}}],["implement",{"_index":372,"t":{"703":{"position":[[20,14]]},"705":{"position":[[31,14]]},"707":{"position":[[45,14]]},"1981":{"position":[[0,14]]},"2165":{"position":[[10,14]]},"2169":{"position":[[10,14]]},"2537":{"position":[[12,14]]},"2541":{"position":[[12,14]]},"2674":{"position":[[10,14]]},"2780":{"position":[[0,14]]},"2789":{"position":[[0,14]]},"2905":{"position":[[0,14]]},"2914":{"position":[[0,14]]},"2952":{"position":[[0,14]]},"3040":{"position":[[0,14]]}}}],["import",{"_index":658,"t":{"1579":{"position":[[0,6]]},"1842":{"position":[[7,6]]},"2115":{"position":[[12,8]]}}}],["improv",{"_index":763,"t":{"2244":{"position":[[36,12]]},"2247":{"position":[[17,12]]},"2249":{"position":[[22,12]]},"2277":{"position":[[36,12]]},"2280":{"position":[[17,12]]},"2282":{"position":[[22,12]]},"2311":{"position":[[36,12]]},"2314":{"position":[[17,12]]},"2316":{"position":[[22,12]]},"2401":{"position":[[36,12]]},"2410":{"position":[[22,12]]},"2438":{"position":[[36,12]]},"2440":{"position":[[17,12]]},"2441":{"position":[[22,12]]},"2457":{"position":[[36,12]]},"2467":{"position":[[17,12]]},"2469":{"position":[[22,12]]}}}],["includ",{"_index":687,"t":{"1813":{"position":[[0,8]]},"2699":{"position":[[20,8]]},"2744":{"position":[[20,8]]},"2834":{"position":[[20,8]]}}}],["inconsist",{"_index":640,"t":{"1445":{"position":[[48,13]]}}}],["index",{"_index":578,"t":{"1306":{"position":[[10,5]]}}}],["indic",{"_index":576,"t":{"1304":{"position":[[8,7]]}}}],["infiniband",{"_index":817,"t":{"2728":{"position":[[11,10]]},"2767":{"position":[[11,10]]}}}],["influxdb",{"_index":451,"t":{"927":{"position":[[0,8]]},"1649":{"position":[[0,8]]},"2374":{"position":[[0,8]]}}}],["info",{"_index":830,"t":{"2898":{"position":[[12,4]]}}}],["inform",{"_index":63,"t":{"104":{"position":[[0,11]]},"271":{"position":[[8,11]]},"1407":{"position":[[10,11]]},"2699":{"position":[[8,11]]},"2744":{"position":[[8,11]]},"2834":{"position":[[8,11]]},"2867":{"position":[[11,11]]}}}],["infrastructur",{"_index":481,"t":{"1010":{"position":[[16,14]]},"2040":{"position":[[0,14]]},"2412":{"position":[[8,14]]},"3060":{"position":[[68,14]]}}}],["ingress",{"_index":298,"t":{"504":{"position":[[31,7]]},"645":{"position":[[0,7]]}}}],["init",{"_index":323,"t":{"567":{"position":[[5,4]]}}}],["initi",{"_index":726,"t":{"2042":{"position":[[0,9]]},"2044":{"position":[[0,9]]}}}],["instal",{"_index":102,"t":{"156":{"position":[[0,12]]},"157":{"position":[[9,10]]},"161":{"position":[[9,10]]},"378":{"position":[[11,12]]},"408":{"position":[[0,7]]},"412":{"position":[[0,7]]},"414":{"position":[[11,12]]},"433":{"position":[[0,7]]},"441":{"position":[[0,7]]},"727":{"position":[[0,12]]},"809":{"position":[[0,12]]},"847":{"position":[[0,12]]},"854":{"position":[[0,12]]},"933":{"position":[[24,7]]},"1237":{"position":[[0,7]]},"1481":{"position":[[0,12]]},"1488":{"position":[[0,12]]},"1499":{"position":[[0,12]]},"1567":{"position":[[0,12]]},"1568":{"position":[[10,12]]},"1570":{"position":[[7,12]]},"1598":{"position":[[0,12]]},"1655":{"position":[[24,7]]},"1681":{"position":[[0,12]]},"1706":{"position":[[0,12]]},"1741":{"position":[[0,12]]},"2137":{"position":[[0,7]]},"2380":{"position":[[24,7]]}}}],["instanc",{"_index":285,"t":{"473":{"position":[[14,8]]},"475":{"position":[[15,8]]},"916":{"position":[[9,9]]},"1638":{"position":[[9,9]]},"1956":{"position":[[87,9]]},"2363":{"position":[[9,9]]},"2873":{"position":[[19,9]]}}}],["instruct",{"_index":637,"t":{"1445":{"position":[[0,8]]}}}],["integr",{"_index":507,"t":{"1081":{"position":[[11,11]]},"1083":{"position":[[17,11]]},"1718":{"position":[[0,11]]}}}],["intel",{"_index":545,"t":{"1175":{"position":[[0,5]]}}}],["intend",{"_index":361,"t":{"691":{"position":[[11,8]]}}}],["interest",{"_index":47,"t":{"66":{"position":[[8,8]]}}}],["interfac",{"_index":477,"t":{"998":{"position":[[8,9]]},"1093":{"position":[[6,10]]},"1162":{"position":[[8,10]]},"1577":{"position":[[13,10]]}}}],["intern",{"_index":433,"t":{"898":{"position":[[0,8]]},"1620":{"position":[[0,8]]},"2345":{"position":[[0,8]]}}}],["interpret",{"_index":234,"t":{"369":{"position":[[3,12]]}}}],["intro",{"_index":430,"t":{"894":{"position":[[0,5]]},"1616":{"position":[[0,5]]},"2341":{"position":[[0,5]]}}}],["introduct",{"_index":232,"t":{"365":{"position":[[0,12]]},"2616":{"position":[[0,12]]},"2655":{"position":[[0,12]]},"2662":{"position":[[0,12]]},"2683":{"position":[[0,12]]},"2694":{"position":[[0,12]]},"2739":{"position":[[0,12]]},"2778":{"position":[[0,12]]},"2794":{"position":[[0,12]]},"2829":{"position":[[0,12]]},"2866":{"position":[[0,12]]},"2919":{"position":[[0,12]]},"2941":{"position":[[0,12]]},"2959":{"position":[[0,12]]},"2974":{"position":[[0,12]]},"2998":{"position":[[0,12]]},"3020":{"position":[[0,12]]},"3054":{"position":[[15,12]]},"3073":{"position":[[0,12]]},"3096":{"position":[[0,12]]},"3123":{"position":[[0,12]]},"3134":{"position":[[0,12]]},"3149":{"position":[[0,12]]},"3166":{"position":[[0,12]]},"3177":{"position":[[0,12]]},"3190":{"position":[[0,12]]},"3203":{"position":[[0,12]]},"3226":{"position":[[0,12]]},"3244":{"position":[[0,12]]},"3261":{"position":[[0,12]]},"3292":{"position":[[0,12]]},"3307":{"position":[[0,12]]},"3318":{"position":[[0,12]]},"3335":{"position":[[0,12]]},"3369":{"position":[[0,12]]},"3388":{"position":[[0,12]]},"3402":{"position":[[0,12]]},"3412":{"position":[[0,12]]},"3433":{"position":[[0,12]]},"3452":{"position":[[0,12]]},"3499":{"position":[[0,12]]}}}],["ip",{"_index":569,"t":{"1281":{"position":[[12,2]]}}}],["ipmi",{"_index":567,"t":{"1280":{"position":[[31,4]]}}}],["iport",{"_index":142,"t":{"197":{"position":[[0,8]]}}}],["ipv6",{"_index":513,"t":{"1097":{"position":[[0,4]]}}}],["iron",{"_index":463,"t":{"957":{"position":[[24,6]]}}}],["issu",{"_index":38,"t":{"59":{"position":[[19,6]]},"354":{"position":[[0,6]]},"944":{"position":[[10,6]]},"1666":{"position":[[10,6]]},"2223":{"position":[[6,5]]},"2238":{"position":[[14,6]]},"2262":{"position":[[9,6]]},"2268":{"position":[[14,6]]},"2295":{"position":[[9,6]]},"2301":{"position":[[14,6]]},"2327":{"position":[[9,6]]},"2333":{"position":[[14,6]]},"2391":{"position":[[10,6]]},"2423":{"position":[[9,6]]},"2429":{"position":[[14,6]]},"2446":{"position":[[9,6]]},"2449":{"position":[[14,6]]},"2487":{"position":[[9,6]]},"2500":{"position":[[14,6]]}}}],["iter",{"_index":439,"t":{"908":{"position":[[26,9]]},"1630":{"position":[[26,9]]},"2355":{"position":[[26,9]]}}}],["job",{"_index":214,"t":{"324":{"position":[[0,4]]},"494":{"position":[[0,4]]},"498":{"position":[[0,3]]},"1720":{"position":[[36,3]]},"1757":{"position":[[8,4]]},"1817":{"position":[[3,4]]}}}],["jobservic",{"_index":283,"t":{"457":{"position":[[0,10]]}}}],["k3",{"_index":429,"t":{"891":{"position":[[24,3]]},"2092":{"position":[[17,3]]},"2103":{"position":[[8,3]]}}}],["k3d",{"_index":740,"t":{"2103":{"position":[[35,3]]}}}],["k8",{"_index":23,"t":{"36":{"position":[[0,3]]},"39":{"position":[[0,3]]},"478":{"position":[[10,3]]},"608":{"position":[[0,3]]},"2282":{"position":[[48,3]]},"2316":{"position":[[48,3]]},"2410":{"position":[[64,3]]},"2441":{"position":[[48,3]]},"2469":{"position":[[48,3]]}}}],["k9",{"_index":311,"t":{"537":{"position":[[5,3]]}}}],["kaa",{"_index":743,"t":{"2113":{"position":[[7,4]]},"2115":{"position":[[0,4]]},"2117":{"position":[[0,4]]},"2460":{"position":[[0,4]]},"2503":{"position":[[0,4]]},"3399":{"position":[[49,4]]}}}],["key",{"_index":86,"t":{"136":{"position":[[0,3]]},"1895":{"position":[[22,4]]},"1912":{"position":[[16,3]]},"2011":{"position":[[22,4]]},"2028":{"position":[[16,3]]}}}],["keycloak",{"_index":192,"t":{"299":{"position":[[4,8]]},"951":{"position":[[24,8]]},"1940":{"position":[[10,8]]},"1956":{"position":[[78,8]]},"2219":{"position":[[17,8]]},"2475":{"position":[[9,8]]}}}],["keyston",{"_index":190,"t":{"297":{"position":[[3,8]]},"301":{"position":[[4,8]]},"761":{"position":[[0,8]]},"2042":{"position":[[10,8]]},"2044":{"position":[[10,8]]}}}],["keyword",{"_index":176,"t":{"277":{"position":[[22,8]]},"367":{"position":[[43,8]]},"369":{"position":[[24,8]]},"376":{"position":[[46,8]]},"380":{"position":[[39,8]]}}}],["kind/k3",{"_index":739,"t":{"2090":{"position":[[29,8]]}}}],["known",{"_index":748,"t":{"2193":{"position":[[0,5]]},"2223":{"position":[[0,5]]},"2238":{"position":[[8,5]]},"2268":{"position":[[8,5]]},"2301":{"position":[[8,5]]},"2333":{"position":[[8,5]]},"2429":{"position":[[8,5]]},"2449":{"position":[[8,5]]},"2500":{"position":[[8,5]]}}}],["kolla",{"_index":556,"t":{"1204":{"position":[[0,5]]}}}],["kube",{"_index":867,"t":{"3269":{"position":[[0,4]]},"3279":{"position":[[0,4]]}}}],["kubeconfig",{"_index":309,"t":{"531":{"position":[[9,10]]}}}],["kubernet",{"_index":268,"t":{"420":{"position":[[0,10]]},"464":{"position":[[0,10]]},"585":{"position":[[23,10]]},"1613":{"position":[[0,10]]},"1975":{"position":[[0,10]]},"2103":{"position":[[12,10]]},"2125":{"position":[[8,10]]},"3060":{"position":[[44,10]]},"3235":{"position":[[10,10]]}}}],["kubevirt",{"_index":862,"t":{"3215":{"position":[[27,9]]}}}],["kustom",{"_index":265,"t":{"414":{"position":[[37,13]]}}}],["label",{"_index":675,"t":{"1739":{"position":[[9,5]]},"3352":{"position":[[0,6]]}}}],["languag",{"_index":884,"t":{"3407":{"position":[[12,8]]}}}],["larg",{"_index":634,"t":{"1443":{"position":[[14,5]]}}}],["larger",{"_index":530,"t":{"1143":{"position":[[34,6]]}}}],["last",{"_index":697,"t":{"1850":{"position":[[0,4]]}}}],["latest",{"_index":501,"t":{"1068":{"position":[[6,6]]}}}],["layer",{"_index":223,"t":{"346":{"position":[[5,5]]},"348":{"position":[[10,5]]},"445":{"position":[[12,5]]},"707":{"position":[[21,6]]},"711":{"position":[[16,5]]},"713":{"position":[[32,6]]},"867":{"position":[[0,6]]},"2113":{"position":[[12,5]]},"2227":{"position":[[10,5]]}}}],["layout",{"_index":502,"t":{"1072":{"position":[[25,6]]}}}],["lba",{"_index":613,"t":{"1414":{"position":[[36,3]]}}}],["leader",{"_index":350,"t":{"614":{"position":[[5,6]]}}}],["leaf",{"_index":475,"t":{"994":{"position":[[0,4]]}}}],["licens",{"_index":126,"t":{"177":{"position":[[38,7]]},"179":{"position":[[0,7],[13,7]]},"2900":{"position":[[0,9]]}}}],["lifecycl",{"_index":426,"t":{"881":{"position":[[0,9]]},"884":{"position":[[0,9]]},"889":{"position":[[0,9]]},"891":{"position":[[0,9]]},"951":{"position":[[0,9]]},"953":{"position":[[0,9]]},"957":{"position":[[0,9]]},"959":{"position":[[0,9]]},"960":{"position":[[0,9]]},"962":{"position":[[0,9]]},"964":{"position":[[3,9]]},"965":{"position":[[3,9]]},"966":{"position":[[3,9]]},"968":{"position":[[0,9]]},"978":{"position":[[0,9]]},"2800":{"position":[[0,9]]},"2988":{"position":[[0,9]]},"2989":{"position":[[5,9]]},"2991":{"position":[[6,9]]}}}],["limit",{"_index":217,"t":{"336":{"position":[[0,11]]},"1121":{"position":[[9,6]]},"1565":{"position":[[18,11]]},"1950":{"position":[[0,11]]},"3104":{"position":[[10,11]]},"3269":{"position":[[14,8]]},"3279":{"position":[[14,8]]},"3467":{"position":[[0,11]]}}}],["line",{"_index":657,"t":{"1577":{"position":[[8,4]]}}}],["link",{"_index":761,"t":{"2234":{"position":[[9,5]]}}}],["lint",{"_index":100,"t":{"150":{"position":[[8,7]]}}}],["list",{"_index":97,"t":{"146":{"position":[[22,5]]},"579":{"position":[[5,4]]},"1310":{"position":[[0,4]]},"1341":{"position":[[0,4]]},"1700":{"position":[[0,5]]},"2238":{"position":[[0,4]]},"2268":{"position":[[0,4]]},"2301":{"position":[[0,4]]},"2333":{"position":[[0,4]]},"2429":{"position":[[0,4]]},"2449":{"position":[[0,4]]},"2488":{"position":[[43,4]]},"2500":{"position":[[0,4]]},"3350":{"position":[[6,4]]}}}],["live",{"_index":416,"t":{"832":{"position":[[0,4]]},"1547":{"position":[[0,4]]}}}],["loadbalanc",{"_index":301,"t":{"508":{"position":[[13,12]]},"1054":{"position":[[7,12]]},"1117":{"position":[[26,12]]}}}],["local",{"_index":548,"t":{"1183":{"position":[[0,5]]},"1804":{"position":[[12,6]]},"2090":{"position":[[0,5],[55,7]]},"3068":{"position":[[9,5]]},"3215":{"position":[[0,5]]}}}],["local_mod",{"_index":253,"t":{"392":{"position":[[15,10]]}}}],["locat",{"_index":146,"t":{"203":{"position":[[29,8]]},"1421":{"position":[[0,6]]}}}],["lock",{"_index":504,"t":{"1076":{"position":[[0,5]]}}}],["log",{"_index":312,"t":{"539":{"position":[[5,3]]},"918":{"position":[[13,4]]},"921":{"position":[[0,3]]},"1216":{"position":[[10,7]]},"1640":{"position":[[13,4]]},"1643":{"position":[[0,3]]},"1755":{"position":[[5,4]]},"2215":{"position":[[0,7]]},"2216":{"position":[[8,7]]},"2365":{"position":[[13,4]]},"2368":{"position":[[0,3]]}}}],["logout",{"_index":755,"t":{"2223":{"position":[[22,6]]}}}],["look",{"_index":872,"t":{"3300":{"position":[[7,4]]}}}],["luk",{"_index":708,"t":{"1912":{"position":[[0,4]]},"2028":{"position":[[0,4]]}}}],["lvm",{"_index":521,"t":{"1111":{"position":[[0,3]]},"1408":{"position":[[38,3]]}}}],["machin",{"_index":529,"t":{"1143":{"position":[[19,7]]},"1586":{"position":[[21,7]]},"2802":{"position":[[0,7]]},"3217":{"position":[[23,7]]},"3219":{"position":[[8,7]]}}}],["magnum",{"_index":427,"t":{"885":{"position":[[27,6]]}}}],["mainten",{"_index":340,"t":{"593":{"position":[[5,11]]},"935":{"position":[[0,11]]},"1268":{"position":[[0,11]]},"1398":{"position":[[8,11]]},"1420":{"position":[[4,11]]},"1436":{"position":[[16,11]]},"1447":{"position":[[11,11]]},"1657":{"position":[[0,11]]},"2382":{"position":[[0,11]]},"2900":{"position":[[12,11]]},"3271":{"position":[[5,11]]}}}],["make",{"_index":172,"t":{"269":{"position":[[7,4]]},"529":{"position":[[0,4]]},"531":{"position":[[0,4]]},"533":{"position":[[0,4]]},"535":{"position":[[0,4]]},"537":{"position":[[0,4]]},"539":{"position":[[0,4]]},"541":{"position":[[0,4]]},"543":{"position":[[0,4]]},"545":{"position":[[0,4]]},"549":{"position":[[0,4]]},"551":{"position":[[0,4]]},"553":{"position":[[0,4]]},"556":{"position":[[0,4]]},"558":{"position":[[0,4]]},"560":{"position":[[0,4]]},"562":{"position":[[0,4]]},"564":{"position":[[0,4]]},"567":{"position":[[0,4]]},"569":{"position":[[0,4]]},"571":{"position":[[0,4]]},"573":{"position":[[0,4]]},"575":{"position":[[0,4]]},"577":{"position":[[0,4]]},"579":{"position":[[0,4]]},"1145":{"position":[[0,4]]},"1675":{"position":[[7,4]]}}}],["makefil",{"_index":688,"t":{"1815":{"position":[[0,8]]}}}],["manag",{"_index":294,"t":{"482":{"position":[[16,10]]},"484":{"position":[[18,10]]},"504":{"position":[[23,7]]},"599":{"position":[[0,10]]},"601":{"position":[[13,10]]},"751":{"position":[[14,7]]},"881":{"position":[[10,10]]},"884":{"position":[[10,10]]},"889":{"position":[[10,10]]},"891":{"position":[[10,10]]},"951":{"position":[[10,10]]},"953":{"position":[[10,10]]},"957":{"position":[[10,10]]},"959":{"position":[[10,10]]},"960":{"position":[[10,10]]},"962":{"position":[[10,10]]},"964":{"position":[[13,10]]},"965":{"position":[[13,10]]},"966":{"position":[[13,10]]},"968":{"position":[[10,10]]},"978":{"position":[[10,10]]},"989":{"position":[[0,7]]},"992":{"position":[[0,10]]},"1003":{"position":[[0,10]]},"1046":{"position":[[0,7]]},"1149":{"position":[[7,7]]},"1253":{"position":[[11,7]]},"1259":{"position":[[22,7]]},"1261":{"position":[[19,7]]},"1263":{"position":[[34,7]]},"1274":{"position":[[0,6]]},"1276":{"position":[[0,6]]},"2046":{"position":[[17,7],[25,7]]},"2052":{"position":[[18,7]]},"2054":{"position":[[21,7]]},"2056":{"position":[[20,7]]},"2058":{"position":[[7,7]]},"2060":{"position":[[0,8]]},"2062":{"position":[[0,8]]},"2064":{"position":[[0,8]]},"2066":{"position":[[0,8]]},"2252":{"position":[[8,10]]},"2282":{"position":[[60,11]]},"2285":{"position":[[8,10]]},"2316":{"position":[[60,11]]},"2404":{"position":[[10,10]]},"2410":{"position":[[76,11]]},"2441":{"position":[[60,11]]},"2469":{"position":[[60,11]]},"2471":{"position":[[16,7]]}}}],["manage.pi",{"_index":410,"t":{"814":{"position":[[0,9]]},"820":{"position":[[0,9]]},"1504":{"position":[[0,9]]},"1510":{"position":[[0,9]]}}}],["mandatori",{"_index":55,"t":{"86":{"position":[[11,9]]},"88":{"position":[[15,9]]},"90":{"position":[[47,9]]},"92":{"position":[[18,9]]},"94":{"position":[[16,9]]},"96":{"position":[[13,9]]},"610":{"position":[[17,9]]},"2798":{"position":[[12,9]]},"2926":{"position":[[0,9]]}}}],["manual",{"_index":557,"t":{"1233":{"position":[[0,6]]},"1472":{"position":[[29,6]]},"1570":{"position":[[0,6]]},"2791":{"position":[[0,6]]},"2916":{"position":[[0,6]]}}}],["map",{"_index":174,"t":{"277":{"position":[[3,7]]},"301":{"position":[[13,7]]},"1942":{"position":[[9,7]]}}}],["mariadb",{"_index":573,"t":{"1296":{"position":[[0,7]]}}}],["materi",{"_index":425,"t":{"873":{"position":[[17,9]]}}}],["matrix",{"_index":874,"t":{"3315":{"position":[[11,6]]}}}],["mean",{"_index":373,"t":{"703":{"position":[[35,5]]},"709":{"position":[[15,5]]},"713":{"position":[[15,5]]}}}],["medium",{"_index":673,"t":{"1727":{"position":[[9,6]]}}}],["meet",{"_index":40,"t":{"61":{"position":[[0,8]]},"64":{"position":[[49,8]]}}}],["memori",{"_index":547,"t":{"1179":{"position":[[5,6]]},"2706":{"position":[[11,6]]},"2751":{"position":[[11,6]]},"2841":{"position":[[11,6]]}}}],["merch",{"_index":148,"t":{"207":{"position":[[10,5]]}}}],["messag",{"_index":391,"t":{"759":{"position":[[0,7]]},"1703":{"position":[[7,8]]}}}],["metadata",{"_index":618,"t":{"1423":{"position":[[8,8]]}}}],["metal",{"_index":757,"t":{"2225":{"position":[[5,5]]}}}],["meter",{"_index":789,"t":{"2561":{"position":[[14,8]]}}}],["methodolog",{"_index":805,"t":{"2668":{"position":[[0,11]]}}}],["metric",{"_index":744,"t":{"2115":{"position":[[5,6]]},"2210":{"position":[[0,7]]}}}],["migrat",{"_index":359,"t":{"657":{"position":[[0,9]]},"663":{"position":[[0,9]]},"832":{"position":[[5,9]]},"1547":{"position":[[5,9]]},"1834":{"position":[[0,9]]}}}],["mirror",{"_index":408,"t":{"802":{"position":[[0,9]]},"1539":{"position":[[0,9]]}}}],["miss",{"_index":594,"t":{"1385":{"position":[[20,7]]}}}],["mock",{"_index":745,"t":{"2117":{"position":[[5,4]]}}}],["mode",{"_index":255,"t":{"392":{"position":[[37,4]]},"1714":{"position":[[6,4]]}}}],["monitor",{"_index":303,"t":{"510":{"position":[[16,7]]},"898":{"position":[[21,10]]},"939":{"position":[[26,7]]},"1004":{"position":[[0,10]]},"1620":{"position":[[21,10]]},"1661":{"position":[[26,7]]},"2094":{"position":[[12,10]]},"2105":{"position":[[16,10]]},"2107":{"position":[[20,10]]},"2113":{"position":[[18,10]]},"2127":{"position":[[16,10]]},"2129":{"position":[[20,10]]},"2213":{"position":[[17,7]]},"2345":{"position":[[21,10]]},"2386":{"position":[[26,7]]}}}],["monitoring1",{"_index":26,"t":{"38":{"position":[[20,11]]}}}],["month",{"_index":136,"t":{"190":{"position":[[12,6]]},"194":{"position":[[12,6]]},"201":{"position":[[12,6]]},"209":{"position":[[12,6]]},"213":{"position":[[12,6]]},"224":{"position":[[12,5]]}}}],["motiv",{"_index":803,"t":{"2657":{"position":[[0,10]]},"2664":{"position":[[0,10]]},"2685":{"position":[[0,10]]},"2696":{"position":[[0,10]]},"2741":{"position":[[0,10]]},"2796":{"position":[[0,10]]},"2831":{"position":[[0,10]]},"2875":{"position":[[0,10]]},"2885":{"position":[[0,10]]},"2920":{"position":[[0,10]]},"2943":{"position":[[0,10]]},"2961":{"position":[[0,10]]},"2976":{"position":[[0,10]]},"3000":{"position":[[0,10]]},"3024":{"position":[[0,10]]},"3052":{"position":[[0,10]]},"3079":{"position":[[0,10]]},"3125":{"position":[[0,10]]},"3136":{"position":[[0,10]]},"3153":{"position":[[0,10]]},"3168":{"position":[[0,10]]},"3181":{"position":[[0,10]]},"3194":{"position":[[0,10]]},"3205":{"position":[[0,10]]},"3230":{"position":[[0,10]]},"3246":{"position":[[0,10]]},"3265":{"position":[[0,10]]},"3296":{"position":[[0,10]]},"3320":{"position":[[0,10]]},"3339":{"position":[[0,10]]},"3373":{"position":[[0,10]]},"3390":{"position":[[0,10]]},"3404":{"position":[[0,10]]},"3414":{"position":[[0,10]]},"3437":{"position":[[0,10]]},"3458":{"position":[[0,10]]},"3503":{"position":[[0,10]]}}}],["move",{"_index":346,"t":{"605":{"position":[[15,4]]},"1465":{"position":[[29,6]]}}}],["mtu",{"_index":550,"t":{"1187":{"position":[[0,3]]}}}],["multipl",{"_index":446,"t":{"916":{"position":[[0,8]]},"1638":{"position":[[0,8]]},"1710":{"position":[[11,8]]},"2363":{"position":[[0,8]]}}}],["mute/unmut",{"_index":599,"t":{"1401":{"position":[[0,11]]}}}],["naabu",{"_index":732,"t":{"2074":{"position":[[0,5]]}}}],["name",{"_index":85,"t":{"134":{"position":[[5,6]]},"281":{"position":[[0,6]]},"733":{"position":[[0,4]]},"1160":{"position":[[23,4]]},"1494":{"position":[[0,4]]},"1694":{"position":[[5,5]]},"2038":{"position":[[41,5]]},"2701":{"position":[[40,6]]},"2712":{"position":[[0,6]]},"2730":{"position":[[0,6]]},"2746":{"position":[[40,6]]},"2755":{"position":[[0,6]]},"2769":{"position":[[0,6]]},"2857":{"position":[[0,6]]},"2889":{"position":[[0,6]]},"3348":{"position":[[9,6]]}}}],["need",{"_index":363,"t":{"695":{"position":[[15,4]]},"705":{"position":[[5,4]]}}}],["ness",{"_index":885,"t":{"3474":{"position":[[8,4]]}}}],["nest",{"_index":542,"t":{"1172":{"position":[[0,6]]},"2722":{"position":[[37,6]]},"2761":{"position":[[37,6]]},"2847":{"position":[[37,6]]}}}],["netdata",{"_index":465,"t":{"962":{"position":[[24,7]]}}}],["netplan",{"_index":509,"t":{"1088":{"position":[[0,7]]}}}],["network",{"_index":390,"t":{"753":{"position":[[23,7]]},"965":{"position":[[40,7]]},"973":{"position":[[0,7]]},"987":{"position":[[0,7]]},"998":{"position":[[0,7]]},"1005":{"position":[[0,7]]},"1162":{"position":[[0,7]]},"1257":{"position":[[18,7]]},"1355":{"position":[[19,7]]},"1367":{"position":[[13,7]]},"1584":{"position":[[28,7]]},"3002":{"position":[[11,7],[36,7]]},"3108":{"position":[[28,7]]}}}],["neutron",{"_index":397,"t":{"771":{"position":[[0,7]]}}}],["new",{"_index":348,"t":{"610":{"position":[[0,3]]},"612":{"position":[[0,3]]},"1058":{"position":[[11,3]]},"1064":{"position":[[19,3]]},"1359":{"position":[[6,3]]},"1425":{"position":[[6,3]]},"1607":{"position":[[13,3]]},"1609":{"position":[[13,3]]},"1846":{"position":[[10,3]]},"2246":{"position":[[0,3]]},"2279":{"position":[[0,3]]},"2313":{"position":[[0,3]]},"2439":{"position":[[0,3]]},"2466":{"position":[[0,3]]}}}],["nic",{"_index":662,"t":{"1584":{"position":[[11,3]]}}}],["nice",{"_index":144,"t":{"199":{"position":[[0,4]]}}}],["node",{"_index":388,"t":{"747":{"position":[[22,4]]},"749":{"position":[[22,4]]},"751":{"position":[[22,4]]},"981":{"position":[[8,5]]},"983":{"position":[[8,5]]},"985":{"position":[[8,5]]},"987":{"position":[[8,5]]},"989":{"position":[[8,5]]},"1051":{"position":[[24,5]]},"1177":{"position":[[16,4]]},"1259":{"position":[[30,4]]},"1266":{"position":[[7,4]]},"1278":{"position":[[7,5]]},"1357":{"position":[[17,4]]},"1359":{"position":[[18,4]]},"1361":{"position":[[17,4]]},"1370":{"position":[[21,4]]},"1372":{"position":[[30,4]]},"1405":{"position":[[16,4]]},"1429":{"position":[[20,4]]},"2882":{"position":[[8,5]]}}}],["node.j",{"_index":104,"t":{"157":{"position":[[20,7]]}}}],["non",{"_index":752,"t":{"2221":{"position":[[0,3]]},"3140":{"position":[[9,3]]}}}],["note",{"_index":488,"t":{"1028":{"position":[[0,4]]},"1565":{"position":[[8,5]]},"1679":{"position":[[21,5]]},"1687":{"position":[[29,5]]},"1809":{"position":[[0,5]]},"2251":{"position":[[18,5]]},"2284":{"position":[[18,5]]},"2318":{"position":[[18,5]]},"2414":{"position":[[18,5]]},"2442":{"position":[[18,5]]},"2477":{"position":[[18,5]]},"2537":{"position":[[39,5]]},"2541":{"position":[[39,5]]},"2780":{"position":[[15,5]]},"2952":{"position":[[15,4]]}}}],["nova",{"_index":396,"t":{"769":{"position":[[0,4]]},"831":{"position":[[0,4]]},"1546":{"position":[[0,4]]}}}],["nuclei",{"_index":734,"t":{"2078":{"position":[[0,6]]}}}],["number",{"_index":540,"t":{"1168":{"position":[[0,6]]},"1461":{"position":[[4,6]]}}}],["nvm",{"_index":106,"t":{"157":{"position":[[32,3]]}}}],["nvme",{"_index":611,"t":{"1410":{"position":[[28,4]]},"1412":{"position":[[18,4]]},"1414":{"position":[[9,4],[53,4]]},"1416":{"position":[[15,4],[32,4]]}}}],["object",{"_index":8,"t":{"11":{"position":[[0,6]]},"787":{"position":[[0,6]]},"1443":{"position":[[25,7]]},"1524":{"position":[[0,6]]},"3344":{"position":[[4,7]]},"3346":{"position":[[4,6]]}}}],["observ",{"_index":741,"t":{"2105":{"position":[[7,8]]},"2107":{"position":[[11,8]]},"2127":{"position":[[7,8]]},"2129":{"position":[[11,8]]},"2137":{"position":[[8,8]]},"3399":{"position":[[54,13]]}}}],["oci",{"_index":276,"t":{"450":{"position":[[0,3]]}}}],["octavia",{"_index":418,"t":{"836":{"position":[[0,7]]},"1551":{"position":[[0,7]]}}}],["octo",{"_index":131,"t":{"186":{"position":[[0,4]]}}}],["offer",{"_index":96,"t":{"146":{"position":[[16,5]]}}}],["oidc",{"_index":537,"t":{"1151":{"position":[[0,4]]},"1790":{"position":[[20,4]]},"2219":{"position":[[0,4]]},"2223":{"position":[[17,4]]}}}],["omap",{"_index":635,"t":{"1443":{"position":[[20,4]]}}}],["on",{"_index":156,"t":{"228":{"position":[[10,3]]},"414":{"position":[[7,3]]},"585":{"position":[[47,3]]}}}],["oob",{"_index":565,"t":{"1280":{"position":[[17,3]]}}}],["open",{"_index":36,"t":{"57":{"position":[[9,4]]},"237":{"position":[[4,4]]},"239":{"position":[[10,5]]},"241":{"position":[[3,4]]},"965":{"position":[[27,4]]},"966":{"position":[[27,4]]},"1303":{"position":[[0,4]]},"1365":{"position":[[0,4]]},"1367":{"position":[[0,4]]},"2640":{"position":[[0,4]]},"2678":{"position":[[0,4]]},"2690":{"position":[[0,4]]},"2825":{"position":[[0,4]]},"2967":{"position":[[0,4]]},"3012":{"position":[[0,4]]},"3252":{"position":[[0,4]]},"3326":{"position":[[0,4]]},"3381":{"position":[[0,4]]},"3420":{"position":[[0,4]]},"3443":{"position":[[0,4]]},"3466":{"position":[[0,4]]},"3509":{"position":[[0,4]]}}}],["openid",{"_index":712,"t":{"1956":{"position":[[49,7]]}}}],["opensearch",{"_index":506,"t":{"1081":{"position":[[0,10]]},"1320":{"position":[[0,10]]}}}],["openstack",{"_index":5,"t":{"8":{"position":[[21,9]]},"47":{"position":[[21,9]]},"291":{"position":[[10,9]]},"305":{"position":[[4,9]]},"535":{"position":[[5,9]]},"785":{"position":[[0,9]]},"885":{"position":[[17,9]]},"902":{"position":[[14,9]]},"904":{"position":[[12,9]]},"939":{"position":[[9,9]]},"953":{"position":[[24,9]]},"1083":{"position":[[0,9]]},"1117":{"position":[[16,9]]},"1522":{"position":[[0,9]]},"1624":{"position":[[14,9]]},"1626":{"position":[[12,9]]},"1661":{"position":[[9,9]]},"2095":{"position":[[0,9]]},"2213":{"position":[[0,9]]},"2349":{"position":[[14,9]]},"2351":{"position":[[12,9]]},"2386":{"position":[[9,9]]},"3002":{"position":[[61,9]]},"3213":{"position":[[14,11]]}}}],["openstackcli",{"_index":7,"t":{"9":{"position":[[0,15]]},"54":{"position":[[0,15]]}}}],["openstackclusterstackreleas",{"_index":256,"t":{"395":{"position":[[0,28]]}}}],["openstacknodeimagereleas",{"_index":258,"t":{"397":{"position":[[0,25]]}}}],["opentofu",{"_index":322,"t":{"566":{"position":[[0,8]]}}}],["openva",{"_index":736,"t":{"2080":{"position":[[28,9]]}}}],["oper",{"_index":75,"t":{"115":{"position":[[3,11]]},"408":{"position":[[21,9]]},"900":{"position":[[13,9]]},"1255":{"position":[[15,8]]},"1622":{"position":[[13,9]]},"2048":{"position":[[15,9]]},"2058":{"position":[[15,9]]},"2247":{"position":[[0,8]]},"2280":{"position":[[0,8]]},"2314":{"position":[[0,8]]},"2347":{"position":[[13,9]]},"2408":{"position":[[0,10]]},"2440":{"position":[[0,8]]},"2462":{"position":[[0,10]]},"2467":{"position":[[0,8]]},"2716":{"position":[[0,11]]},"2782":{"position":[[0,11]]},"2936":{"position":[[0,11]]},"2995":{"position":[[0,11]]},"3108":{"position":[[10,8]]}}}],["option",{"_index":58,"t":{"90":{"position":[[13,9]]},"98":{"position":[[8,8]]},"612":{"position":[[17,8]]},"642":{"position":[[14,7]]},"1840":{"position":[[20,10]]},"2708":{"position":[[0,10]]},"2720":{"position":[[0,10]]},"2722":{"position":[[0,10]]},"2724":{"position":[[0,10]]},"2726":{"position":[[0,10]]},"2728":{"position":[[0,10]]},"2730":{"position":[[7,7]]},"2753":{"position":[[0,10]]},"2759":{"position":[[0,10]]},"2761":{"position":[[0,10]]},"2763":{"position":[[0,10]]},"2765":{"position":[[0,10]]},"2767":{"position":[[0,10]]},"2769":{"position":[[7,7]]},"2843":{"position":[[0,10]]},"2845":{"position":[[0,10]]},"2847":{"position":[[0,10]]},"2849":{"position":[[0,10]]},"2851":{"position":[[0,10]]},"2946":{"position":[[0,7]]},"2965":{"position":[[0,7]]},"3010":{"position":[[0,7]]},"3038":{"position":[[0,8]]},"3058":{"position":[[0,6]]},"3060":{"position":[[0,6]]},"3062":{"position":[[0,6]]},"3066":{"position":[[0,6]]},"3068":{"position":[[0,6]]},"3106":{"position":[[0,6]]},"3108":{"position":[[0,6]]},"3110":{"position":[[0,6]]},"3112":{"position":[[0,6]]},"3250":{"position":[[0,7]]},"3259":{"position":[[19,8]]},"3324":{"position":[[0,7]]},"3377":{"position":[[0,7]]},"3394":{"position":[[0,7]]},"3418":{"position":[[0,7]]},"3441":{"position":[[0,7]]},"3464":{"position":[[0,7]]},"3507":{"position":[[0,7]]}}}],["order",{"_index":87,"t":{"136":{"position":[[4,5]]}}}],["origin",{"_index":829,"t":{"2896":{"position":[[6,6]]}}}],["orphan",{"_index":420,"t":{"841":{"position":[[0,7]]},"1556":{"position":[[0,7]]}}}],["os",{"_index":838,"t":{"3002":{"position":[[19,2]]}}}],["osd",{"_index":400,"t":{"777":{"position":[[5,3]]},"1420":{"position":[[0,3]]},"1421":{"position":[[18,3]]},"1423":{"position":[[4,3],[36,4]]},"1425":{"position":[[10,3]]},"1426":{"position":[[17,3]]},"1427":{"position":[[9,3]]},"1429":{"position":[[16,3]]},"1431":{"position":[[10,3]]},"1435":{"position":[[10,4]]}}}],["osism",{"_index":394,"t":{"765":{"position":[[0,5]]},"881":{"position":[[32,5]]},"884":{"position":[[39,5]]},"889":{"position":[[36,5]]},"891":{"position":[[31,5]]},"951":{"position":[[36,5]]},"953":{"position":[[37,5]]},"957":{"position":[[34,5]]},"959":{"position":[[38,5]]},"960":{"position":[[35,5]]},"962":{"position":[[35,5]]},"964":{"position":[[36,5]]},"965":{"position":[[57,5]]},"966":{"position":[[49,5]]},"968":{"position":[[36,5]]},"978":{"position":[[38,5]]},"1468":{"position":[[22,5]]},"2092":{"position":[[0,5],[32,5]]},"2254":{"position":[[0,5]]},"2287":{"position":[[0,5]]},"2323":{"position":[[17,5]]},"2419":{"position":[[17,5]]}}}],["oss",{"_index":857,"t":{"3157":{"position":[[0,3]]}}}],["out",{"_index":128,"t":{"179":{"position":[[21,3]]},"715":{"position":[[14,3]]},"2950":{"position":[[0,3]]}}}],["outcom",{"_index":880,"t":{"3399":{"position":[[0,7]]}}}],["outlook",{"_index":221,"t":{"338":{"position":[[25,7]]},"1952":{"position":[[25,7]]}}}],["output",{"_index":237,"t":{"371":{"position":[[16,6]]}}}],["ov",{"_index":469,"t":{"966":{"position":[[40,5]]},"1365":{"position":[[13,5]]}}}],["over",{"_index":289,"t":{"480":{"position":[[9,4]]}}}],["overview",{"_index":54,"t":{"86":{"position":[[0,8]]},"343":{"position":[[14,8]]},"480":{"position":[[0,8]]},"725":{"position":[[0,8]]},"807":{"position":[[0,8]]},"845":{"position":[[0,8]]},"852":{"position":[[0,8]]},"863":{"position":[[10,8]]},"1399":{"position":[[19,8]]},"1479":{"position":[[0,8]]},"1486":{"position":[[0,8]]},"1497":{"position":[[0,8]]},"1596":{"position":[[0,8]]},"1875":{"position":[[0,8]]},"1991":{"position":[[0,8]]},"2228":{"position":[[0,8]]},"2798":{"position":[[0,8]]},"2887":{"position":[[0,8]]}}}],["ovn",{"_index":299,"t":{"508":{"position":[[0,3]]},"965":{"position":[[48,5]]},"1367":{"position":[[21,5]]},"3006":{"position":[[0,3]]}}}],["p500924",{"_index":21,"t":{"35":{"position":[[8,7]]},"38":{"position":[[8,7]]}}}],["packag",{"_index":484,"t":{"1015":{"position":[[22,8]]},"1020":{"position":[[11,8]]},"1237":{"position":[[17,8]]}}}],["page",{"_index":593,"t":{"1378":{"position":[[5,5]]},"2163":{"position":[[15,4]]},"2167":{"position":[[15,4]]},"3313":{"position":[[7,4]]}}}],["paramet",{"_index":95,"t":{"146":{"position":[[0,10]]},"480":{"position":[[18,10]]},"482":{"position":[[0,10]]},"484":{"position":[[7,10]]},"486":{"position":[[0,10]]},"914":{"position":[[9,10]]},"1070":{"position":[[0,9]]},"1636":{"position":[[9,10]]},"2361":{"position":[[9,10]]}}}],["parser",{"_index":381,"t":{"733":{"position":[[5,6]]},"1494":{"position":[[5,6]]}}}],["pass",{"_index":240,"t":{"373":{"position":[[23,7]]}}}],["password",{"_index":562,"t":{"1263":{"position":[[18,8]]}}}],["patch",{"_index":878,"t":{"3362":{"position":[[10,5]]},"3364":{"position":[[0,5]]}}}],["patent",{"_index":122,"t":{"175":{"position":[[0,7]]}}}],["path",{"_index":863,"t":{"3221":{"position":[[9,4]]}}}],["perform",{"_index":651,"t":{"1474":{"position":[[0,11]]},"3140":{"position":[[13,11]]},"3142":{"position":[[9,11]]}}}],["persist",{"_index":356,"t":{"643":{"position":[[0,11]]}}}],["persona",{"_index":401,"t":{"779":{"position":[[0,8]]},"2471":{"position":[[24,7]]}}}],["pg",{"_index":631,"t":{"1439":{"position":[[8,2]]},"1445":{"position":[[11,2],[62,3]]},"1461":{"position":[[14,3]]}}}],["phase",{"_index":796,"t":{"2630":{"position":[[9,5]]},"2632":{"position":[[12,5]]},"2634":{"position":[[11,5]]},"2636":{"position":[[12,5]]},"3350":{"position":[[0,5]]}}}],["pick",{"_index":845,"t":{"3058":{"position":[[34,4]]}}}],["pin",{"_index":526,"t":{"1123":{"position":[[4,7]]}}}],["pipelin",{"_index":170,"t":{"267":{"position":[[11,9]]},"320":{"position":[[0,9]]},"492":{"position":[[0,9]]},"1757":{"position":[[18,9]]}}}],["pipeline.yaml",{"_index":793,"t":{"2569":{"position":[[4,13]]}}}],["place",{"_index":343,"t":{"603":{"position":[[3,5]]}}}],["placement",{"_index":628,"t":{"1436":{"position":[[0,9]]},"1437":{"position":[[5,9]]},"1441":{"position":[[28,9]]}}}],["plan",{"_index":45,"t":{"64":{"position":[[40,8]]}}}],["plane",{"_index":387,"t":{"745":{"position":[[24,5]]},"975":{"position":[[8,5]]},"1000":{"position":[[8,5]]},"1001":{"position":[[8,5]]},"1002":{"position":[[5,5]]},"1003":{"position":[[11,5]]},"1004":{"position":[[11,5]]},"1005":{"position":[[8,5]]}}}],["play",{"_index":563,"t":{"1272":{"position":[[14,5]]},"1310":{"position":[[19,5]]}}}],["playbook",{"_index":649,"t":{"1468":{"position":[[28,9]]},"1748":{"position":[[8,8]]}}}],["plugin",{"_index":846,"t":{"3058":{"position":[[69,6]]},"3064":{"position":[[35,6]]}}}],["plusserv",{"_index":15,"t":{"19":{"position":[[0,10]]},"42":{"position":[[46,10]]},"620":{"position":[[0,10]]}}}],["polici",{"_index":536,"t":{"1149":{"position":[[15,6]]},"2042":{"position":[[23,6]]},"2712":{"position":[[7,6]]},"2755":{"position":[[7,6]]},"2857":{"position":[[7,8]]},"3471":{"position":[[0,6]]}}}],["polling.yaml",{"_index":790,"t":{"2563":{"position":[[4,12]]}}}],["pool",{"_index":520,"t":{"1109":{"position":[[6,5]]},"1447":{"position":[[6,4]]},"1449":{"position":[[4,5]]},"1455":{"position":[[20,4]]},"1457":{"position":[[29,4]]},"1459":{"position":[[9,4]]},"1461":{"position":[[24,4]]},"1465":{"position":[[24,4],[36,6]]}}}],["portal",{"_index":281,"t":{"453":{"position":[[17,6]]}}}],["posit",{"_index":88,"t":{"138":{"position":[[0,11]]},"140":{"position":[[0,8]]}}}],["possibl",{"_index":59,"t":{"90":{"position":[[32,9]]}}}],["post",{"_index":499,"t":{"1066":{"position":[[8,4]]},"2492":{"position":[[17,5]]},"3360":{"position":[[10,4]]}}}],["postgr",{"_index":263,"t":{"410":{"position":[[17,8]]}}}],["postgresql",{"_index":275,"t":{"448":{"position":[[9,12]]}}}],["practic",{"_index":53,"t":{"85":{"position":[[15,8]]}}}],["pre",{"_index":77,"t":{"121":{"position":[[0,3]]},"3106":{"position":[[10,3]]}}}],["precheck",{"_index":691,"t":{"1832":{"position":[[0,9]]}}}],["prefac",{"_index":723,"t":{"2036":{"position":[[0,7]]}}}],["premis",{"_index":717,"t":{"1969":{"position":[[0,7]]}}}],["prepar",{"_index":305,"t":{"518":{"position":[[0,7]]},"829":{"position":[[0,12]]},"1060":{"position":[[8,11]]},"1544":{"position":[[0,12]]},"1742":{"position":[[7,11]]},"2103":{"position":[[0,7]]},"2125":{"position":[[0,7]]}}}],["prerequisit",{"_index":209,"t":{"310":{"position":[[0,13]]},"332":{"position":[[0,13]]},"406":{"position":[[0,13]]},"418":{"position":[[0,13]]},"431":{"position":[[0,13]]},"439":{"position":[[0,13]]},"463":{"position":[[0,13]]},"664":{"position":[[0,13]]},"1946":{"position":[[0,13]]},"2088":{"position":[[0,13]]},"2101":{"position":[[0,13]]},"2123":{"position":[[0,13]]},"2135":{"position":[[0,13]]},"2806":{"position":[[0,12]]}}}],["preview",{"_index":333,"t":{"582":{"position":[[49,8]]},"2195":{"position":[[10,8]]},"2406":{"position":[[0,8]]},"2471":{"position":[[0,8]]},"2473":{"position":[[0,8]]},"2475":{"position":[[0,8]]},"2488":{"position":[[0,8]]}}}],["previou",{"_index":818,"t":{"2734":{"position":[[0,8]]},"2773":{"position":[[0,8]]},"2938":{"position":[[0,8]]}}}],["privileg",{"_index":187,"t":{"287":{"position":[[45,10]]}}}],["pro",{"_index":859,"t":{"3211":{"position":[[0,4]]}}}],["problem",{"_index":378,"t":{"721":{"position":[[19,8]]},"1143":{"position":[[0,8]]}}}],["process",{"_index":500,"t":{"1066":{"position":[[13,10]]},"2628":{"position":[[0,7]]},"2802":{"position":[[32,10]]},"2816":{"position":[[0,7]]}}}],["product",{"_index":226,"t":{"350":{"position":[[21,10]]}}}],["program",{"_index":883,"t":{"3407":{"position":[[0,11]]}}}],["project",{"_index":19,"t":{"26":{"position":[[0,8]]},"31":{"position":[[0,8]]},"35":{"position":[[0,7]]},"38":{"position":[[0,7]]},"62":{"position":[[0,7]]},"267":{"position":[[25,7]]},"318":{"position":[[0,8]]},"1712":{"position":[[21,7]]},"2062":{"position":[[9,8]]},"2412":{"position":[[0,7]]},"3110":{"position":[[15,7]]},"3298":{"position":[[10,8]]},"3300":{"position":[[26,8]]}}}],["prometheu",{"_index":464,"t":{"959":{"position":[[24,10]]},"2211":{"position":[[0,10]]}}}],["proper",{"_index":782,"t":{"2488":{"position":[[9,6]]}}}],["properli",{"_index":886,"t":{"3474":{"position":[[17,8]]}}}],["properti",{"_index":407,"t":{"799":{"position":[[6,10]]},"1536":{"position":[[6,10]]},"2922":{"position":[[0,10]]},"2930":{"position":[[15,10]]},"3140":{"position":[[33,10]]},"3142":{"position":[[29,10]]}}}],["propos",{"_index":795,"t":{"2630":{"position":[[0,8]]},"2701":{"position":[[9,8]]},"2703":{"position":[[0,8]]},"2732":{"position":[[0,8]]},"2746":{"position":[[9,8]]},"2748":{"position":[[0,8]]},"2771":{"position":[[0,8]]},"2833":{"position":[[0,8]]},"2836":{"position":[[9,8]]},"2838":{"position":[[0,8]]},"2853":{"position":[[0,8]]},"3221":{"position":[[0,8]]}}}],["protect",{"_index":866,"t":{"3235":{"position":[[0,9]]}}}],["provid",{"_index":300,"t":{"508":{"position":[[4,8]]},"753":{"position":[[14,8]]},"3064":{"position":[[14,9]]},"3213":{"position":[[5,8]]}}}],["providercli",{"_index":259,"t":{"403":{"position":[[0,14]]}}}],["provis",{"_index":558,"t":{"1233":{"position":[[7,12]]}}}],["proxi",{"_index":279,"t":{"453":{"position":[[0,6]]},"933":{"position":[[77,5]]},"1655":{"position":[[77,5]]},"2082":{"position":[[4,5]]},"2380":{"position":[[77,5]]}}}],["proxmox",{"_index":472,"t":{"978":{"position":[[24,7]]}}}],["public",{"_index":225,"t":{"350":{"position":[[0,6]]},"1158":{"position":[[0,6]]},"3066":{"position":[[9,6]]}}}],["pull",{"_index":39,"t":{"59":{"position":[[30,4]]}}}],["pure",{"_index":527,"t":{"1129":{"position":[[0,4]]}}}],["purg",{"_index":318,"t":{"553":{"position":[[5,5]]}}}],["pursu",{"_index":720,"t":{"1973":{"position":[[23,6]]}}}],["push",{"_index":326,"t":{"573":{"position":[[11,4]]}}}],["put",{"_index":879,"t":{"3364":{"position":[[9,3]]}}}],["pytest",{"_index":184,"t":{"285":{"position":[[0,6]]}}}],["python",{"_index":665,"t":{"1704":{"position":[[0,6]]},"1720":{"position":[[18,6]]},"3062":{"position":[[15,6]]}}}],["qo",{"_index":588,"t":{"1350":{"position":[[19,5]]},"1380":{"position":[[19,5]]},"1390":{"position":[[19,5]]}}}],["qualiti",{"_index":587,"t":{"1350":{"position":[[0,7]]},"1380":{"position":[[0,7]]},"1390":{"position":[[0,7]]}}}],["queri",{"_index":630,"t":{"1439":{"position":[[0,5]]},"2147":{"position":[[0,5]]},"2151":{"position":[[0,5]]}}}],["question",{"_index":800,"t":{"2640":{"position":[[5,9]]},"2678":{"position":[[5,9]]},"2690":{"position":[[5,9]]},"2825":{"position":[[5,9]]},"2967":{"position":[[5,9]]},"3012":{"position":[[5,9]]},"3252":{"position":[[5,9]]},"3326":{"position":[[5,9]]},"3381":{"position":[[5,9]]},"3420":{"position":[[5,9]]},"3443":{"position":[[5,9]]},"3466":{"position":[[5,9]]},"3509":{"position":[[5,9]]}}}],["queue",{"_index":392,"t":{"759":{"position":[[8,5]]}}}],["quick",{"_index":320,"t":{"558":{"position":[[11,5]]},"2032":{"position":[[0,5]]}}}],["quickstart",{"_index":57,"t":{"90":{"position":[[0,10]]},"524":{"position":[[7,10]]}}}],["quota",{"_index":413,"t":{"824":{"position":[[0,5]]},"1348":{"position":[[5,5]]},"1514":{"position":[[0,5]]}}}],["r1",{"_index":759,"t":{"2228":{"position":[[23,2]]},"2238":{"position":[[39,2]]}}}],["r2",{"_index":770,"t":{"2268":{"position":[[39,2]]}}}],["r3",{"_index":772,"t":{"2301":{"position":[[39,2]]}}}],["r4",{"_index":774,"t":{"2333":{"position":[[39,2]]}}}],["r5",{"_index":778,"t":{"2429":{"position":[[39,2]]}}}],["r6",{"_index":785,"t":{"2500":{"position":[[39,2]]}}}],["rado",{"_index":641,"t":{"1447":{"position":[[0,5]]}}}],["rate",{"_index":868,"t":{"3269":{"position":[[9,4]]},"3279":{"position":[[9,4]]}}}],["rational",{"_index":824,"t":{"2859":{"position":[[0,9]]}}}],["raw",{"_index":694,"t":{"1838":{"position":[[23,3]]},"1840":{"position":[[9,3]]}}}],["rbac",{"_index":854,"t":{"3108":{"position":[[36,4]]},"3476":{"position":[[30,4]]}}}],["rc",{"_index":534,"t":{"1145":{"position":[[59,2]]}}}],["read",{"_index":130,"t":{"181":{"position":[[8,7]]},"254":{"position":[[8,7]]}}}],["readabl",{"_index":819,"t":{"2802":{"position":[[8,11]]}}}],["real",{"_index":827,"t":{"2869":{"position":[[0,4]]}}}],["realm",{"_index":194,"t":{"299":{"position":[[17,5]]}}}],["reason",{"_index":851,"t":{"3102":{"position":[[0,7]]}}}],["rebal",{"_index":627,"t":{"1435":{"position":[[0,9]]}}}],["reboot",{"_index":564,"t":{"1278":{"position":[[0,6]]},"1357":{"position":[[0,6]]},"1405":{"position":[[0,6]]}}}],["rebuild",{"_index":405,"t":{"795":{"position":[[19,8]]},"797":{"position":[[22,7]]},"1532":{"position":[[19,8]]},"1534":{"position":[[22,7]]}}}],["reciproc",{"_index":113,"t":{"167":{"position":[[0,11]]}}}],["recommend",{"_index":653,"t":{"1568":{"position":[[23,13]]},"1862":{"position":[[0,11]]},"1924":{"position":[[0,11]]},"2928":{"position":[[0,11]]},"3036":{"position":[[0,11]]}}}],["reconcil",{"_index":491,"t":{"1048":{"position":[[0,10]]}}}],["reconcili",{"_index":267,"t":{"414":{"position":[[69,14]]}}}],["record",{"_index":581,"t":{"1316":{"position":[[10,7]]},"3481":{"position":[[9,6]]}}}],["recoveri",{"_index":574,"t":{"1301":{"position":[[0,8]]}}}],["redi",{"_index":262,"t":{"410":{"position":[[7,5]]},"446":{"position":[[0,5]]}}}],["refer",{"_index":11,"t":{"13":{"position":[[0,10]]},"703":{"position":[[10,9]]},"705":{"position":[[21,9]]},"707":{"position":[[35,9]]},"1070":{"position":[[10,9]]},"1815":{"position":[[9,9]]},"2165":{"position":[[0,9]]},"2169":{"position":[[0,9]]},"2680":{"position":[[0,9]]},"3398":{"position":[[0,9]]}}}],["refinement/sprint",{"_index":44,"t":{"64":{"position":[[22,17]]}}}],["regard",{"_index":724,"t":{"2038":{"position":[[8,9]]}}}],["region",{"_index":382,"t":{"737":{"position":[[16,6]]}}}],["registr",{"_index":167,"t":{"258":{"position":[[11,12]]}}}],["registri",{"_index":273,"t":{"433":{"position":[[25,8]]},"450":{"position":[[17,8]]},"634":{"position":[[58,8]]},"3066":{"position":[[26,8]]}}}],["regress",{"_index":178,"t":{"279":{"position":[[12,10]]}}}],["regul",{"_index":809,"t":{"2687":{"position":[[0,11]]}}}],["regular",{"_index":404,"t":{"795":{"position":[[11,7]]},"797":{"position":[[14,7]]},"1532":{"position":[[11,7]]},"1534":{"position":[[14,7]]}}}],["reject",{"_index":799,"t":{"2638":{"position":[[0,9]]}}}],["relat",{"_index":776,"t":{"2408":{"position":[[19,7]]},"2691":{"position":[[0,7]]},"2954":{"position":[[0,7]]},"2971":{"position":[[0,7]]},"3017":{"position":[[0,7]]},"3047":{"position":[[0,7]]},"3089":{"position":[[0,7]]},"3118":{"position":[[0,7]]},"3129":{"position":[[0,7]]},"3140":{"position":[[25,7]]},"3142":{"position":[[21,7]]},"3144":{"position":[[0,7]]},"3163":{"position":[[0,7]]},"3172":{"position":[[0,7]]},"3239":{"position":[[0,7]]},"3256":{"position":[[0,7]]},"3287":{"position":[[0,7]]},"3304":{"position":[[0,7]]},"3330":{"position":[[0,7]]},"3383":{"position":[[0,7]]},"3424":{"position":[[0,7]]},"3447":{"position":[[0,7]]},"3473":{"position":[[0,7]]},"3496":{"position":[[0,7]]},"3513":{"position":[[0,7]]}}}],["releas",{"_index":229,"t":{"358":{"position":[[0,8]]},"1079":{"position":[[7,7]]},"1396":{"position":[[15,8]]},"1673":{"position":[[14,8]]},"1675":{"position":[[14,7]]},"1677":{"position":[[7,7]]},"1679":{"position":[[13,7]]},"1687":{"position":[[21,7]]},"1811":{"position":[[10,8]]},"2197":{"position":[[0,7]]},"2236":{"position":[[0,7]]},"2266":{"position":[[0,7]]},"2299":{"position":[[0,7]]},"2331":{"position":[[0,7]]},"2427":{"position":[[0,7]]},"2448":{"position":[[0,7]]},"2498":{"position":[[0,7]]}}}],["relev",{"_index":211,"t":{"316":{"position":[[23,8]]}}}],["remark",{"_index":835,"t":{"2932":{"position":[[0,7]]}}}],["remind",{"_index":132,"t":{"186":{"position":[[5,8]]}}}],["remot",{"_index":254,"t":{"392":{"position":[[30,6]]},"1064":{"position":[[44,6]]}}}],["remov",{"_index":585,"t":{"1346":{"position":[[0,6]]},"1361":{"position":[[0,6]]},"1427":{"position":[[0,6]]},"1429":{"position":[[0,6]]},"1431":{"position":[[0,6]]},"2256":{"position":[[0,8]]},"2289":{"position":[[0,8]]},"2320":{"position":[[0,8]]},"2416":{"position":[[0,8]]},"2443":{"position":[[0,8]]},"2479":{"position":[[0,8]]}}}],["repair",{"_index":638,"t":{"1445":{"position":[[17,6]]}}}],["replac",{"_index":620,"t":{"1426":{"position":[[0,7]]},"1431":{"position":[[37,9]]}}}],["replic",{"_index":644,"t":{"1455":{"position":[[9,10]]},"3043":{"position":[[0,11]]}}}],["repo",{"_index":73,"t":{"113":{"position":[[21,4]]},"269":{"position":[[14,4]]},"1751":{"position":[[9,5]]},"1753":{"position":[[9,5]]}}}],["report",{"_index":213,"t":{"322":{"position":[[0,7]]},"2201":{"position":[[4,9]]}}}],["repositori",{"_index":108,"t":{"159":{"position":[[21,10]]},"1058":{"position":[[29,10]]},"1064":{"position":[[55,10]]},"1072":{"position":[[14,10]]},"1074":{"position":[[32,10]]},"1239":{"position":[[32,10]]},"1687":{"position":[[0,12]]}}}],["request",{"_index":12,"t":{"17":{"position":[[7,7]]},"59":{"position":[[35,8]]},"3360":{"position":[[15,8]]},"3362":{"position":[[16,9]]}}}],["requir",{"_index":56,"t":{"88":{"position":[[0,12]]},"154":{"position":[[0,12]]},"287":{"position":[[31,7]]},"332":{"position":[[18,12]]},"516":{"position":[[0,12]]},"783":{"position":[[0,12]]},"866":{"position":[[0,12]]},"1026":{"position":[[17,8]]},"1237":{"position":[[8,8]]},"1520":{"position":[[0,12]]},"1561":{"position":[[0,12]]},"1771":{"position":[[0,12]]},"1830":{"position":[[0,12]]},"1854":{"position":[[13,12]]},"1916":{"position":[[13,12]]},"1946":{"position":[[18,12]]},"2618":{"position":[[0,12]]},"2704":{"position":[[0,10]]},"2706":{"position":[[0,10]]},"2749":{"position":[[0,10]]},"2751":{"position":[[0,10]]},"2839":{"position":[[0,10]]},"2841":{"position":[[0,10]]},"2891":{"position":[[10,12]]},"3002":{"position":[[74,8]]},"3034":{"position":[[0,8]]},"3106":{"position":[[14,12]]},"3140":{"position":[[0,8]]},"3142":{"position":[[0,8]]},"3159":{"position":[[0,8]]},"3209":{"position":[[0,8]]},"3313":{"position":[[12,12]]},"3337":{"position":[[0,12]]},"3392":{"position":[[0,12]]},"3399":{"position":[[32,12]]}}}],["reserv",{"_index":546,"t":{"1177":{"position":[[0,7]]}}}],["reset",{"_index":584,"t":{"1343":{"position":[[7,5]]},"1730":{"position":[[0,5]]}}}],["resolv",{"_index":769,"t":{"2262":{"position":[[0,8]]},"2295":{"position":[[0,8]]},"2327":{"position":[[0,8]]},"2423":{"position":[[0,8]]},"2446":{"position":[[0,8]]},"2487":{"position":[[0,8]]}}}],["resourc",{"_index":14,"t":{"17":{"position":[[21,9]]},"910":{"position":[[0,8]]},"1121":{"position":[[0,8]]},"1177":{"position":[[21,9]]},"1632":{"position":[[0,8]]},"1774":{"position":[[6,9]]},"2357":{"position":[[0,8]]},"3364":{"position":[[26,9]]}}}],["restart",{"_index":445,"t":{"914":{"position":[[24,10]]},"1289":{"position":[[17,8]]},"1291":{"position":[[19,8]]},"1472":{"position":[[0,7]]},"1636":{"position":[[24,10]]},"1765":{"position":[[0,7]]},"2361":{"position":[[24,10]]}}}],["restor",{"_index":286,"t":{"475":{"position":[[0,7]]},"1299":{"position":[[0,7]]},"1897":{"position":[[0,7]]},"1899":{"position":[[0,9]]},"1901":{"position":[[0,9]]},"1903":{"position":[[0,9]]},"1905":{"position":[[0,9]]},"1907":{"position":[[0,9]]},"2013":{"position":[[0,7]]},"2015":{"position":[[0,9]]},"2017":{"position":[[0,9]]},"2019":{"position":[[0,9]]},"2021":{"position":[[0,9]]},"2023":{"position":[[0,9]]}}}],["restrict",{"_index":753,"t":{"2221":{"position":[[8,12]]},"2238":{"position":[[23,12]]},"2268":{"position":[[23,12]]},"2301":{"position":[[23,12]]},"2333":{"position":[[23,12]]},"2429":{"position":[[23,12]]},"2449":{"position":[[23,12]]},"2500":{"position":[[23,12]]}}}],["retriev",{"_index":704,"t":{"1895":{"position":[[0,10]]},"2011":{"position":[[0,10]]}}}],["return",{"_index":877,"t":{"3360":{"position":[[0,6]]},"3362":{"position":[[0,6]]}}}],["reus",{"_index":847,"t":{"3060":{"position":[[34,5]]}}}],["revers",{"_index":458,"t":{"933":{"position":[[69,7]]},"1655":{"position":[[69,7]]},"2380":{"position":[[69,7]]}}}],["review/backlog",{"_index":43,"t":{"64":{"position":[[7,14]]}}}],["revok",{"_index":730,"t":{"2056":{"position":[[0,8]]}}}],["rfc2119",{"_index":175,"t":{"277":{"position":[[14,7]]},"367":{"position":[[35,7]]},"369":{"position":[[16,7]]},"376":{"position":[[38,7]]},"380":{"position":[[31,7]]}}}],["rgw",{"_index":519,"t":{"1107":{"position":[[0,3]]},"1287":{"position":[[0,3]]}}}],["roadmap",{"_index":230,"t":{"358":{"position":[[13,7]]}}}],["role",{"_index":94,"t":{"144":{"position":[[9,5]]},"2044":{"position":[[19,4]]},"2046":{"position":[[33,5]]},"2054":{"position":[[29,4]]},"2056":{"position":[[28,4]]},"2066":{"position":[[9,4]]}}}],["room",{"_index":147,"t":{"205":{"position":[[10,5]]},"222":{"position":[[10,5]]}}}],["rotat",{"_index":358,"t":{"651":{"position":[[0,8]]},"837":{"position":[[8,8]]},"1552":{"position":[[8,8]]},"3275":{"position":[[12,8]]},"3285":{"position":[[12,8]]}}}],["rule",{"_index":101,"t":{"150":{"position":[[16,5]]},"1451":{"position":[[15,5]]},"1463":{"position":[[13,5]]},"1465":{"position":[[13,4]]},"3077":{"position":[[75,5]]},"3106":{"position":[[35,5]]}}}],["run",{"_index":328,"t":{"575":{"position":[[9,3]]},"1062":{"position":[[8,3]]},"1372":{"position":[[17,7]]},"1586":{"position":[[0,7]]},"1714":{"position":[[16,4]]}}}],["run_cloudname.sh",{"_index":455,"t":{"929":{"position":[[25,16]]},"1651":{"position":[[25,16]]},"2376":{"position":[[25,16]]}}}],["runtim",{"_index":728,"t":{"2046":{"position":[[0,9]]}}}],["rx",{"_index":779,"t":{"2449":{"position":[[39,2]]}}}],["s",{"_index":453,"t":{"929":{"position":[[5,1]]},"1651":{"position":[[5,1]]},"2376":{"position":[[5,1]]}}}],["s3",{"_index":10,"t":{"11":{"position":[[15,4]]},"422":{"position":[[0,2]]},"466":{"position":[[0,2]]}}}],["sampl",{"_index":832,"t":{"2908":{"position":[[7,6]]}}}],["sata/sa",{"_index":610,"t":{"1410":{"position":[[15,8]]},"1418":{"position":[[15,8]]}}}],["save",{"_index":210,"t":{"316":{"position":[[9,4]]}}}],["sbom",{"_index":760,"t":{"2234":{"position":[[0,4]]}}}],["sc",{"_index":1,"t":{"3":{"position":[[15,3]]},"307":{"position":[[30,3]]},"350":{"position":[[7,3]]},"352":{"position":[[15,3]]},"367":{"position":[[17,3]]},"369":{"position":[[51,3]]},"689":{"position":[[10,3]]},"691":{"position":[[7,3]]},"693":{"position":[[22,4]]},"697":{"position":[[21,3]]},"699":{"position":[[11,3]]},"701":{"position":[[65,4]]},"705":{"position":[[52,3]]},"715":{"position":[[22,4]]},"717":{"position":[[17,3]]},"719":{"position":[[18,3]]},"793":{"position":[[0,3]]},"886":{"position":[[17,3]]},"1530":{"position":[[0,3]]},"1944":{"position":[[0,3],[7,3]]},"1956":{"position":[[113,3]]},"2163":{"position":[[4,3]]},"2167":{"position":[[4,3]]},"2191":{"position":[[4,3]]},"2249":{"position":[[0,3]]},"2282":{"position":[[0,3]]},"2316":{"position":[[0,3]]},"2410":{"position":[[0,3]]},"2441":{"position":[[0,3]]},"2469":{"position":[[0,3]]},"2710":{"position":[[9,3]]},"2736":{"position":[[7,3]]},"2775":{"position":[[7,3]]},"2798":{"position":[[22,3]]},"2804":{"position":[[0,3]]},"2855":{"position":[[9,3]]},"2863":{"position":[[7,4]]},"2877":{"position":[[11,3]]},"2924":{"position":[[9,3]]}}}],["scenario",{"_index":690,"t":{"1828":{"position":[[0,8]]}}}],["scope",{"_index":700,"t":{"1873":{"position":[[0,5]]},"1989":{"position":[[0,5]]},"2187":{"position":[[0,5]]},"2205":{"position":[[0,5]]},"2242":{"position":[[0,5]]},"2275":{"position":[[0,5]]},"2309":{"position":[[0,5]]},"2399":{"position":[[0,5]]},"2437":{"position":[[0,5]]},"2455":{"position":[[0,5]]},"2488":{"position":[[16,5]]},"2800":{"position":[[25,6]]},"2950":{"position":[[7,5]]},"3110":{"position":[[23,6]]},"3474":{"position":[[26,6]]}}}],["script",{"_index":238,"t":{"371":{"position":[[31,7]]},"380":{"position":[[18,6]]},"929":{"position":[[42,6]]},"1092":{"position":[[11,7]]},"1651":{"position":[[42,6]]},"2376":{"position":[[42,6]]},"3062":{"position":[[22,7]]}}}],["scrub",{"_index":603,"t":{"1403":{"position":[[21,10]]},"1441":{"position":[[12,10]]},"1445":{"position":[[35,5]]}}}],["search",{"_index":575,"t":{"1303":{"position":[[5,6]]}}}],["second",{"_index":495,"t":{"1054":{"position":[[0,6]]},"1119":{"position":[[0,6]]},"1399":{"position":[[3,7]]}}}],["secret",{"_index":296,"t":{"496":{"position":[[0,7]]},"1744":{"position":[[7,7]]},"1893":{"position":[[9,7]]},"1899":{"position":[[33,6]]},"2009":{"position":[[9,7]]},"2015":{"position":[[33,6]]}}}],["section",{"_index":794,"t":{"2626":{"position":[[0,8]]}}}],["secur",{"_index":614,"t":{"1416":{"position":[[0,6]]},"1418":{"position":[[0,6]]},"1856":{"position":[[8,8]]},"1858":{"position":[[14,8]]},"1860":{"position":[[8,8]]},"1862":{"position":[[12,8]]},"1864":{"position":[[11,8]]},"1918":{"position":[[8,8]]},"1920":{"position":[[14,8]]},"1922":{"position":[[8,8]]},"1924":{"position":[[12,8]]},"1926":{"position":[[11,8]]},"2260":{"position":[[0,8]]},"2293":{"position":[[0,8]]},"2325":{"position":[[0,8]]},"2421":{"position":[[0,8]]},"2445":{"position":[[0,8]]},"2483":{"position":[[0,8]]},"2485":{"position":[[0,8]]},"3077":{"position":[[8,8],[32,8],[60,8]]},"3102":{"position":[[39,8]]},"3106":{"position":[[59,8]]},"3112":{"position":[[10,8]]},"3476":{"position":[[15,6]]}}}],["select",{"_index":771,"t":{"2269":{"position":[[18,9]]},"3300":{"position":[[17,8]]}}}],["separ",{"_index":714,"t":{"1956":{"position":[[104,8]]}}}],["server",{"_index":112,"t":{"163":{"position":[[34,6]]},"378":{"position":[[4,6]]},"426":{"position":[[7,6]]},"470":{"position":[[7,6]]},"482":{"position":[[27,6]]},"484":{"position":[[29,6]]},"1370":{"position":[[8,7]]},"1372":{"position":[[9,7]]},"1742":{"position":[[0,6]]},"1844":{"position":[[19,6]]},"1846":{"position":[[14,6]]},"1910":{"position":[[26,7]]},"2026":{"position":[[26,7]]}}}],["servic",{"_index":18,"t":{"24":{"position":[[0,7]]},"29":{"position":[[0,7]]},"452":{"position":[[12,8]]},"785":{"position":[[16,7]]},"1026":{"position":[[26,8]]},"1028":{"position":[[8,8]]},"1107":{"position":[[4,7]]},"1164":{"position":[[21,7]]},"1166":{"position":[[36,9]]},"1168":{"position":[[10,7]]},"1253":{"position":[[19,7]]},"1261":{"position":[[27,7]]},"1263":{"position":[[42,7]]},"1274":{"position":[[7,8]]},"1287":{"position":[[4,7]]},"1289":{"position":[[9,7]]},"1291":{"position":[[11,7]]},"1346":{"position":[[7,7]]},"1350":{"position":[[11,7]]},"1374":{"position":[[27,7]]},"1376":{"position":[[26,7]]},"1380":{"position":[[11,7]]},"1390":{"position":[[11,7]]},"1522":{"position":[[16,7]]},"1573":{"position":[[14,7]]},"1607":{"position":[[17,7]]},"1611":{"position":[[4,7]]},"1797":{"position":[[7,8]]},"1799":{"position":[[8,8]]},"1813":{"position":[[9,8]]},"1907":{"position":[[49,7]]},"2023":{"position":[[49,7]]},"2117":{"position":[[10,7]]},"2225":{"position":[[11,7]]}}}],["session",{"_index":50,"t":{"66":{"position":[[43,8]]}}}],["set",{"_index":245,"t":{"384":{"position":[[0,7]]},"896":{"position":[[0,7]]},"1263":{"position":[[8,3]]},"1461":{"position":[[0,3]]},"1618":{"position":[[0,7]]},"1804":{"position":[[19,7]]},"2343":{"position":[[0,7]]}}}],["setup",{"_index":414,"t":{"826":{"position":[[0,5]]},"1516":{"position":[[0,5]]},"1746":{"position":[[11,5]]},"1854":{"position":[[34,5]]},"1916":{"position":[[34,5]]}}}],["sever",{"_index":876,"t":{"3356":{"position":[[0,8]]}}}],["short",{"_index":842,"t":{"3054":{"position":[[0,5]]}}}],["shouldn't",{"_index":185,"t":{"287":{"position":[[21,9]]}}}],["show",{"_index":329,"t":{"577":{"position":[[5,4]]},"1846":{"position":[[0,4]]}}}],["shutdown",{"_index":650,"t":{"1470":{"position":[[0,8]]},"1472":{"position":[[36,8]]}}}],["sig",{"_index":25,"t":{"38":{"position":[[16,3]]},"66":{"position":[[24,6]]}}}],["singl",{"_index":604,"t":{"1405":{"position":[[9,6]]},"1423":{"position":[[29,6]]},"1429":{"position":[[9,6]]},"1708":{"position":[[13,6]]},"2672":{"position":[[0,6]]},"2982":{"position":[[21,6]]}}}],["size",{"_index":813,"t":{"2708":{"position":[[16,5]]},"2753":{"position":[[16,5]]},"2843":{"position":[[16,5]]}}}],["skylin",{"_index":552,"t":{"1194":{"position":[[0,7]]},"1196":{"position":[[0,7]]}}}],["smart",{"_index":609,"t":{"1410":{"position":[[0,5]]}}}],["snack",{"_index":151,"t":{"215":{"position":[[0,6]]},"218":{"position":[[0,5]]},"220":{"position":[[6,5]]}}}],["softwar",{"_index":681,"t":{"1776":{"position":[[0,8]]}}}],["solut",{"_index":742,"t":{"2105":{"position":[[27,8]]},"2127":{"position":[[27,8]]},"2137":{"position":[[17,8]]}}}],["sonic",{"_index":466,"t":{"964":{"position":[[27,5]]},"3002":{"position":[[0,5]]},"3004":{"position":[[27,5]]},"3006":{"position":[[8,5]]},"3013":{"position":[[9,5]]}}}],["sonobuoy",{"_index":843,"t":{"3054":{"position":[[6,8]]},"3058":{"position":[[60,8]]},"3064":{"position":[[26,8]]}}}],["sourc",{"_index":715,"t":{"1964":{"position":[[0,6]]},"2871":{"position":[[0,7]]}}}],["sovereign",{"_index":163,"t":{"244":{"position":[[0,9]]},"2620":{"position":[[0,9]]}}}],["spec",{"_index":833,"t":{"2922":{"position":[[18,6]]}}}],["special",{"_index":46,"t":{"66":{"position":[[0,7]]}}}],["specif",{"_index":483,"t":{"1015":{"position":[[13,8]]},"1421":{"position":[[9,8]]},"2982":{"position":[[6,14]]},"2984":{"position":[[6,14]]}}}],["spine",{"_index":476,"t":{"996":{"position":[[0,5]]}}}],["sprint",{"_index":42,"t":{"64":{"position":[[0,6]]}}}],["ssd",{"_index":549,"t":{"1183":{"position":[[6,3]]}}}],["ssh",{"_index":310,"t":{"533":{"position":[[5,3]]},"1338":{"position":[[0,3]]},"1387":{"position":[[0,3]]}}}],["sso",{"_index":206,"t":{"307":{"position":[[4,3]]}}}],["stabil",{"_index":798,"t":{"2634":{"position":[[0,10]]},"2641":{"position":[[0,13]]}}}],["stabl",{"_index":505,"t":{"1079":{"position":[[0,6]]},"1677":{"position":[[0,6]]},"2634":{"position":[[17,8]]}}}],["stack",{"_index":164,"t":{"244":{"position":[[16,5]]},"886":{"position":[[29,6]]},"1979":{"position":[[8,6]]},"2406":{"position":[[17,6]]}}}],["stand",{"_index":360,"t":{"689":{"position":[[14,5]]}}}],["standard",{"_index":165,"t":{"246":{"position":[[4,9]]},"360":{"position":[[0,10]]},"367":{"position":[[21,9]]},"376":{"position":[[13,9]]},"378":{"position":[[24,8]]},"695":{"position":[[26,12]]},"697":{"position":[[25,10]]},"793":{"position":[[10,8]]},"1530":{"position":[[10,8]]},"2232":{"position":[[0,15]]},"2264":{"position":[[0,9]]},"2297":{"position":[[0,9]]},"2329":{"position":[[0,9]]},"2425":{"position":[[0,9]]},"2447":{"position":[[0,9]]},"2496":{"position":[[0,9]]},"2620":{"position":[[16,8]]},"2710":{"position":[[0,8]]},"2734":{"position":[[9,8]]},"2773":{"position":[[9,8]]},"2798":{"position":[[26,9]]},"2810":{"position":[[0,8]]},"2855":{"position":[[0,8]]},"2924":{"position":[[0,8]]},"2938":{"position":[[9,8]]},"2980":{"position":[[0,8]]},"3030":{"position":[[0,12]]},"3085":{"position":[[0,8]]},"3102":{"position":[[26,8]]},"3161":{"position":[[0,8]]},"3511":{"position":[[0,8]]}}}],["start",{"_index":4,"t":{"8":{"position":[[8,7]]},"42":{"position":[[8,7]]},"47":{"position":[[8,7]]},"92":{"position":[[8,7]]},"163":{"position":[[9,8]]},"314":{"position":[[11,6]]},"715":{"position":[[38,6]]},"717":{"position":[[41,8]]},"719":{"position":[[71,6]]},"789":{"position":[[8,7]]},"1026":{"position":[[0,5]]},"1441":{"position":[[0,5]]},"1526":{"position":[[8,7]]},"2032":{"position":[[6,5]]}}}],["startup",{"_index":443,"t":{"912":{"position":[[11,7]]},"1634":{"position":[[11,7]]},"2359":{"position":[[11,7]]}}}],["state",{"_index":219,"t":{"338":{"position":[[8,5]]},"573":{"position":[[5,5]]},"591":{"position":[[8,5]]},"1266":{"position":[[12,6]]},"1952":{"position":[[8,5]]},"3013":{"position":[[0,5]]}}}],["static",{"_index":682,"t":{"1786":{"position":[[0,6]]}}}],["statu",{"_index":632,"t":{"1439":{"position":[[21,6]]},"1453":{"position":[[15,6]]},"2163":{"position":[[8,6]]},"2167":{"position":[[8,6]]},"3313":{"position":[[0,6]]}}}],["stay",{"_index":855,"t":{"3110":{"position":[[10,4]]}}}],["step",{"_index":65,"t":{"108":{"position":[[0,4]]},"111":{"position":[[0,4]]},"113":{"position":[[0,4]]},"157":{"position":[[0,4]]},"159":{"position":[[0,4]]},"161":{"position":[[0,4]]},"163":{"position":[[0,4]]},"659":{"position":[[0,5]]},"666":{"position":[[0,5]]},"1060":{"position":[[0,4]]},"1062":{"position":[[0,4]]},"1064":{"position":[[0,4]]},"1066":{"position":[[0,4]]},"1255":{"position":[[0,4]]},"1257":{"position":[[0,4]]},"1259":{"position":[[0,4]]},"1261":{"position":[[0,4]]},"1263":{"position":[[0,4]]},"2659":{"position":[[18,5]]}}}],["still",{"_index":371,"t":{"701":{"position":[[51,5]]}}}],["stop",{"_index":589,"t":{"1372":{"position":[[0,4]]}}}],["storag",{"_index":9,"t":{"11":{"position":[[7,7]]},"562":{"position":[[11,7]]},"787":{"position":[[7,7]]},"972":{"position":[[0,7]]},"985":{"position":[[0,7]]},"1129":{"position":[[5,7]]},"1183":{"position":[[10,7]]},"1408":{"position":[[18,7]]},"1463":{"position":[[33,7]]},"1524":{"position":[[7,7]]},"1879":{"position":[[10,7]]},"1995":{"position":[[10,7]]}}}],["strong",{"_index":118,"t":{"173":{"position":[[18,6]]}}}],["structur",{"_index":51,"t":{"85":{"position":[[0,9]]},"711":{"position":[[22,11]]},"2670":{"position":[[0,9]]}}}],["style",{"_index":808,"t":{"2676":{"position":[[8,5],[27,5]]}}}],["subscript",{"_index":831,"t":{"2900":{"position":[[24,12]]}}}],["suffix",{"_index":812,"t":{"2704":{"position":[[15,8]]},"2749":{"position":[[15,8]]},"2839":{"position":[[15,8]]}}}],["suggest",{"_index":804,"t":{"2659":{"position":[[0,9]]}}}],["supplement",{"_index":787,"t":{"2537":{"position":[[0,11]]},"2541":{"position":[[0,11]]}}}],["support",{"_index":287,"t":{"478":{"position":[[0,9]]},"1811":{"position":[[0,9]]},"2219":{"position":[[5,7]]},"2726":{"position":[[15,7]]},"2765":{"position":[[15,7]]},"2900":{"position":[[39,7]]}}}],["survey",{"_index":882,"t":{"3399":{"position":[[19,6]]}}}],["swappi",{"_index":518,"t":{"1105":{"position":[[0,10]]}}}],["swift",{"_index":399,"t":{"775":{"position":[[0,5]]}}}],["switch",{"_index":474,"t":{"991":{"position":[[0,8]]},"992":{"position":[[11,8]]},"994":{"position":[[5,8]]},"996":{"position":[[6,8]]}}}],["sync",{"_index":586,"t":{"1348":{"position":[[0,4]]}}}],["synchronis",{"_index":503,"t":{"1074":{"position":[[0,13]]}}}],["systemat",{"_index":810,"t":{"2701":{"position":[[22,10]]},"2746":{"position":[[22,10]]},"3028":{"position":[[0,10]]}}}],["tag",{"_index":538,"t":{"1155":{"position":[[6,4]]},"2197":{"position":[[8,7]]},"2236":{"position":[[8,7]]},"2266":{"position":[[8,7]]},"2299":{"position":[[8,7]]},"2331":{"position":[[8,7]]},"2427":{"position":[[8,7]]},"2448":{"position":[[8,7]]},"2498":{"position":[[8,7]]}}}],["target",{"_index":215,"t":{"328":{"position":[[0,6]]}}}],["task",{"_index":84,"t":{"134":{"position":[[0,4]]},"1420":{"position":[[16,5]]},"1694":{"position":[[0,4]]}}}],["taxonomi",{"_index":806,"t":{"2668":{"position":[[16,8]]}}}],["teardown",{"_index":306,"t":{"522":{"position":[[0,8]]},"547":{"position":[[0,8]]}}}],["technic",{"_index":69,"t":{"110":{"position":[[3,9]]},"582":{"position":[[38,10]]},"721":{"position":[[9,9]]},"2195":{"position":[[0,9]]},"2674":{"position":[[0,9]]},"2891":{"position":[[0,9]]},"3104":{"position":[[0,9]]}}}],["technolog",{"_index":826,"t":{"2867":{"position":[[23,10]]}}}],["telegraf",{"_index":450,"t":{"925":{"position":[[0,8]]},"1647":{"position":[[0,8]]},"2372":{"position":[[0,8]]}}}],["teleport",{"_index":470,"t":{"968":{"position":[[24,8]]}}}],["templat",{"_index":331,"t":{"582":{"position":[[17,10]]},"824":{"position":[[6,9]]},"1514":{"position":[[6,9]]},"2670":{"position":[[10,8]]}}}],["temporarili",{"_index":622,"t":{"1431":{"position":[[14,12]]}}}],["terminolog",{"_index":849,"t":{"3075":{"position":[[0,11]]},"3098":{"position":[[0,11]]},"3151":{"position":[[0,11]]},"3228":{"position":[[0,11]]},"3294":{"position":[[0,11]]},"3488":{"position":[[0,11]]},"3501":{"position":[[0,11]]}}}],["test",{"_index":179,"t":{"279":{"position":[[23,5]]},"283":{"position":[[27,5]]},"285":{"position":[[7,4]]},"287":{"position":[[15,5]]},"371":{"position":[[26,4]]},"373":{"position":[[18,4]]},"380":{"position":[[13,4]]},"520":{"position":[[9,4]]},"555":{"position":[[0,7]]},"2537":{"position":[[31,7]]},"2541":{"position":[[31,7]]},"2784":{"position":[[10,5]]},"2791":{"position":[[7,5]]},"2902":{"position":[[12,5]]},"2907":{"position":[[10,5]]},"2916":{"position":[[7,5]]},"2934":{"position":[[12,5]]},"2956":{"position":[[12,5]]},"2993":{"position":[[12,5]]},"3049":{"position":[[12,5]]},"3060":{"position":[[63,4]]},"3062":{"position":[[34,5]]},"3091":{"position":[[12,5]]},"3131":{"position":[[12,5]]},"3146":{"position":[[12,5]]},"3174":{"position":[[12,5]]},"3200":{"position":[[12,5]]},"3241":{"position":[[12,5]]},"3258":{"position":[[12,5]]},"3259":{"position":[[12,6]]},"3289":{"position":[[12,5]]},"3332":{"position":[[12,5]]},"3385":{"position":[[12,5]]},"3426":{"position":[[12,5]]},"3449":{"position":[[12,5]]},"3478":{"position":[[12,5]]},"3515":{"position":[[12,5]]}}}],["testabl",{"_index":182,"t":{"283":{"position":[[6,8]]}}}],["testb",{"_index":754,"t":{"2221":{"position":[[21,9]]},"2249":{"position":[[35,9]]},"2282":{"position":[[35,8]]},"2316":{"position":[[35,8]]},"2410":{"position":[[52,7]]},"2441":{"position":[[35,8]]},"2469":{"position":[[35,8]]}}}],["thank",{"_index":773,"t":{"2305":{"position":[[0,6]]},"2337":{"position":[[0,6]]},"2433":{"position":[[0,6]]},"2452":{"position":[[0,6]]},"2509":{"position":[[0,6]]}}}],["thing",{"_index":143,"t":{"197":{"position":[[9,6]]},"199":{"position":[[13,6]]},"948":{"position":[[9,6]]},"1670":{"position":[[9,6]]},"2395":{"position":[[9,6]]}}}],["throttl",{"_index":572,"t":{"1291":{"position":[[0,10]]}}}],["tilt",{"_index":246,"t":{"384":{"position":[[8,4]]},"386":{"position":[[16,4]]}}}],["tl",{"_index":357,"t":{"645":{"position":[[12,3]]},"2221":{"position":[[4,3]]}}}],["toggl",{"_index":252,"t":{"392":{"position":[[0,6]]}}}],["token",{"_index":197,"t":{"301":{"position":[[24,5]]}}}],["tool",{"_index":716,"t":{"1966":{"position":[[0,5]]},"1977":{"position":[[11,7]]},"2716":{"position":[[12,7]]},"2782":{"position":[[12,7]]},"2823":{"position":[[0,7]]},"2936":{"position":[[12,7]]},"2995":{"position":[[12,7]]},"3004":{"position":[[15,7]]}}}],["topic",{"_index":647,"t":{"1467":{"position":[[9,6]]}}}],["tri",{"_index":376,"t":{"715":{"position":[[10,3]]}}}],["trivi",{"_index":282,"t":{"455":{"position":[[0,5]]}}}],["troubleshoot",{"_index":460,"t":{"943":{"position":[[0,15]]},"1588":{"position":[[0,15]]},"1665":{"position":[[0,15]]},"1750":{"position":[[0,15]]},"1801":{"position":[[0,15]]},"2390":{"position":[[0,15]]}}}],["tutori",{"_index":353,"t":{"634":{"position":[[0,9]]},"1956":{"position":[[9,8]]}}}],["two",{"_index":713,"t":{"1956":{"position":[[74,3],[100,3]]}}}],["type",{"_index":68,"t":{"108":{"position":[[23,4]]},"1563":{"position":[[0,5]]},"2622":{"position":[[0,5]]},"2699":{"position":[[0,4]]},"2708":{"position":[[26,5]]},"2744":{"position":[[0,4]]},"2753":{"position":[[26,5]]},"2834":{"position":[[0,4]]},"2843":{"position":[[26,5]]},"3028":{"position":[[33,5]]},"3032":{"position":[[15,4]]},"3034":{"position":[[16,5]]},"3036":{"position":[[19,5]]},"3038":{"position":[[16,5]]}}}],["typic",{"_index":608,"t":{"1408":{"position":[[10,7]]}}}],["ui",{"_index":34,"t":{"45":{"position":[[15,4]]},"52":{"position":[[15,4]]},"1755":{"position":[[39,3]]},"2107":{"position":[[31,3]]},"2129":{"position":[[31,3]]}}}],["unattend",{"_index":459,"t":{"937":{"position":[[0,10]]},"1659":{"position":[[0,10]]},"2384":{"position":[[0,10]]}}}],["underlay",{"_index":515,"t":{"1097":{"position":[[12,8]]}}}],["understand",{"_index":233,"t":{"367":{"position":[[3,13]]}}}],["unencrypt",{"_index":706,"t":{"1901":{"position":[[25,11]]},"2017":{"position":[[25,11]]}}}],["uniqu",{"_index":516,"t":{"1101":{"position":[[0,6]]}}}],["unit",{"_index":177,"t":{"279":{"position":[[3,4]]}}}],["unprivileg",{"_index":435,"t":{"900":{"position":[[0,12]]},"1622":{"position":[[0,12]]},"2347":{"position":[[0,12]]}}}],["unsupport",{"_index":685,"t":{"1804":{"position":[[0,11]]}}}],["up",{"_index":247,"t":{"384":{"position":[[13,2]]},"896":{"position":[[8,2]]},"948":{"position":[[16,2]]},"1376":{"position":[[13,2]]},"1618":{"position":[[8,2]]},"1670":{"position":[[16,2]]},"2343":{"position":[[8,2]]},"2395":{"position":[[16,2]]}}}],["updat",{"_index":41,"t":{"62":{"position":[[8,7]]},"601":{"position":[[0,8]]},"607":{"position":[[0,8]]},"804":{"position":[[0,8]]},"939":{"position":[[0,8]]},"1541":{"position":[[0,8]]},"1661":{"position":[[0,8]]},"2199":{"position":[[0,7]]},"2386":{"position":[[0,8]]},"2894":{"position":[[6,8]]},"3364":{"position":[[17,8]]}}}],["upgrad",{"_index":344,"t":{"603":{"position":[[9,7]]},"608":{"position":[[12,7]]},"937":{"position":[[11,8]]},"1020":{"position":[[0,7]]},"1581":{"position":[[0,7]]},"1659":{"position":[[11,8]]},"1799":{"position":[[0,7]]},"2384":{"position":[[11,8]]}}}],["upgrade/migr",{"_index":766,"t":{"2251":{"position":[[0,17]]},"2284":{"position":[[0,17]]},"2318":{"position":[[0,17]]},"2414":{"position":[[0,17]]},"2442":{"position":[[0,17]]},"2477":{"position":[[0,17]]}}}],["upload",{"_index":497,"t":{"1064":{"position":[[8,6]]},"1143":{"position":[[9,9]]},"2978":{"position":[[0,9]]},"3068":{"position":[[21,6]]}}}],["url",{"_index":31,"t":{"43":{"position":[[0,4]]},"50":{"position":[[0,4]]}}}],["us",{"_index":89,"t":{"138":{"position":[[16,3]]},"269":{"position":[[19,3]]},"345":{"position":[[0,3]]},"376":{"position":[[32,5]]},"380":{"position":[[25,5]]},"414":{"position":[[24,5]]},"634":{"position":[[43,3]]},"701":{"position":[[57,3]]},"705":{"position":[[13,3]]},"707":{"position":[[13,3]]},"717":{"position":[[10,3]]},"719":{"position":[[10,3]]},"871":{"position":[[0,3]]},"1068":{"position":[[0,5]]},"1160":{"position":[[16,3]]},"1272":{"position":[[0,3]]},"1414":{"position":[[47,5]]},"1416":{"position":[[26,5]]},"1418":{"position":[[30,5]]},"1468":{"position":[[16,5]]},"1584":{"position":[[0,3]]},"1753":{"position":[[19,5]]},"1864":{"position":[[7,3]]},"1877":{"position":[[13,5]]},"1879":{"position":[[25,5]]},"1881":{"position":[[19,5]]},"1887":{"position":[[19,5]]},"1891":{"position":[[37,4]]},"1893":{"position":[[24,5]]},"1926":{"position":[[7,3]]},"1993":{"position":[[13,5]]},"1995":{"position":[[25,5]]},"1997":{"position":[[19,5]]},"2003":{"position":[[19,5]]},"2007":{"position":[[37,4]]},"2009":{"position":[[24,5]]},"2090":{"position":[[18,3]]},"2092":{"position":[[6,3]]},"2869":{"position":[[11,4]]}}}],["usag",{"_index":16,"t":{"20":{"position":[[0,5]]},"142":{"position":[[0,5]]},"144":{"position":[[0,5]]},"148":{"position":[[0,5]]},"250":{"position":[[0,5]]},"729":{"position":[[0,5]]},"801":{"position":[[0,5]]},"816":{"position":[[0,5]]},"849":{"position":[[0,5]]},"858":{"position":[[0,5]]},"1483":{"position":[[0,5]]},"1490":{"position":[[0,5]]},"1506":{"position":[[0,5]]},"1538":{"position":[[0,5]]},"1572":{"position":[[0,5]]},"1602":{"position":[[0,5]]},"1683":{"position":[[0,5]]},"1780":{"position":[[0,5]]},"1792":{"position":[[9,5]]},"2143":{"position":[[0,5]]},"3108":{"position":[[19,5]]}}}],["user",{"_index":17,"t":{"22":{"position":[[0,5]]},"24":{"position":[[8,5]]},"29":{"position":[[8,5]]},"303":{"position":[[33,5]]},"305":{"position":[[47,5]]},"1255":{"position":[[24,4]]},"1875":{"position":[[23,4]]},"1991":{"position":[[23,4]]},"2052":{"position":[[26,4]]},"2054":{"position":[[49,4]]},"2060":{"position":[[9,5]]},"2244":{"position":[[23,4]]},"2277":{"position":[[23,4]]},"2311":{"position":[[23,4]]},"2401":{"position":[[23,4]]},"2438":{"position":[[23,4]]},"2457":{"position":[[23,4]]}}}],["valid",{"_index":648,"t":{"1468":{"position":[[0,10]]},"2714":{"position":[[0,10]]},"2861":{"position":[[0,10]]}}}],["valu",{"_index":158,"t":{"236":{"position":[[0,6]]}}}],["var",{"_index":492,"t":{"1049":{"position":[[5,4]]},"1050":{"position":[[6,4]]}}}],["variabl",{"_index":494,"t":{"1051":{"position":[[7,8]]},"1326":{"position":[[5,9]]}}}],["vault",{"_index":561,"t":{"1263":{"position":[[12,5]]}}}],["ve",{"_index":473,"t":{"978":{"position":[[32,2]]}}}],["vegan",{"_index":154,"t":{"220":{"position":[[0,5]]}}}],["velero",{"_index":272,"t":{"424":{"position":[[0,6]]},"426":{"position":[[0,6]]},"468":{"position":[[0,6]]},"470":{"position":[[0,6]]}}}],["version",{"_index":288,"t":{"478":{"position":[[14,8]]},"608":{"position":[[4,7]]},"610":{"position":[[4,8]]},"612":{"position":[[4,8]]},"1795":{"position":[[7,8]]},"2244":{"position":[[10,8]]},"2277":{"position":[[10,8]]},"2311":{"position":[[10,8]]},"2401":{"position":[[10,8]]},"2438":{"position":[[10,8]]},"2457":{"position":[[10,8]]},"2646":{"position":[[0,10]]},"2734":{"position":[[18,8]]},"2773":{"position":[[18,8]]},"2808":{"position":[[0,7]]},"2938":{"position":[[18,8]]}}}],["via",{"_index":105,"t":{"157":{"position":[[28,3]]},"902":{"position":[[10,3]]},"1280":{"position":[[27,3]]},"1624":{"position":[[10,3]]},"2103":{"position":[[31,3]]},"2219":{"position":[[13,3]]},"2323":{"position":[[13,3]]},"2349":{"position":[[10,3]]},"2419":{"position":[[13,3]]}}}],["virtual",{"_index":467,"t":{"965":{"position":[[32,7]]},"1367":{"position":[[5,7]]},"1586":{"position":[[13,7]]},"2722":{"position":[[20,14],[44,14]]},"2761":{"position":[[20,14],[44,14]]},"2847":{"position":[[20,14],[44,14]]},"2873":{"position":[[11,7]]},"3217":{"position":[[15,7]]},"3219":{"position":[[0,7]]}}}],["virtualis",{"_index":543,"t":{"1172":{"position":[[7,14]]}}}],["visibl",{"_index":762,"t":{"2244":{"position":[[28,7]]},"2277":{"position":[[28,7]]},"2311":{"position":[[28,7]]},"2401":{"position":[[28,7]]},"2438":{"position":[[28,7]]},"2457":{"position":[[28,7]]}}}],["vm",{"_index":432,"t":{"896":{"position":[[22,2]]},"902":{"position":[[7,2]]},"904":{"position":[[40,2]]},"1618":{"position":[[22,2]]},"1624":{"position":[[7,2]]},"1626":{"position":[[40,2]]},"2343":{"position":[[22,2]]},"2349":{"position":[[7,2]]},"2351":{"position":[[40,2]]}}}],["vmdk",{"_index":692,"t":{"1836":{"position":[[12,4]]},"1838":{"position":[[15,4]]}}}],["vnc",{"_index":696,"t":{"1848":{"position":[[18,3]]}}}],["volum",{"_index":702,"t":{"1881":{"position":[[0,6]]},"1883":{"position":[[19,7]]},"1885":{"position":[[19,7]]},"1887":{"position":[[0,6]]},"1889":{"position":[[33,7]]},"1891":{"position":[[42,7]]},"1905":{"position":[[12,6]]},"1907":{"position":[[12,6]]},"1910":{"position":[[48,7]]},"1912":{"position":[[42,6]]},"1997":{"position":[[0,6]]},"1999":{"position":[[19,7]]},"2001":{"position":[[19,7]]},"2003":{"position":[[0,6]]},"2005":{"position":[[33,7]]},"2007":{"position":[[42,7]]},"2021":{"position":[[12,6]]},"2023":{"position":[[12,6]]},"2026":{"position":[[48,7]]},"2028":{"position":[[42,6]]},"3028":{"position":[[26,6]]},"3032":{"position":[[8,6]]},"3034":{"position":[[9,6]]},"3036":{"position":[[12,6]]},"3038":{"position":[[9,6]]}}}],["vpn",{"_index":655,"t":{"1573":{"position":[[10,3]]},"1784":{"position":[[0,3]]}}}],["vs",{"_index":119,"t":{"173":{"position":[[25,3]]},"599":{"position":[[26,3]]},"898":{"position":[[9,2]]},"1620":{"position":[[9,2]]},"2345":{"position":[[9,2]]},"3364":{"position":[[6,2]]}}}],["vswitch",{"_index":468,"t":{"966":{"position":[[32,7]]},"1365":{"position":[[5,7]]}}}],["wait",{"_index":261,"t":{"408":{"position":[[12,4]]}}}],["want",{"_index":375,"t":{"715":{"position":[[2,4]]},"717":{"position":[[2,4]]},"719":{"position":[[2,4]]}}}],["warn",{"_index":600,"t":{"1401":{"position":[[21,7]]},"2038":{"position":[[0,7]]},"2787":{"position":[[0,8]]},"2912":{"position":[[0,8]]}}}],["wavecon",{"_index":20,"t":{"28":{"position":[[0,7]]}}}],["wavestack",{"_index":352,"t":{"622":{"position":[[0,9]]}}}],["weak",{"_index":120,"t":{"173":{"position":[[29,4]]}}}],["web",{"_index":243,"t":{"378":{"position":[[0,3]]},"453":{"position":[[13,3]]},"1755":{"position":[[35,3]]}}}],["webinterfac",{"_index":656,"t":{"1575":{"position":[[0,13]]},"1788":{"position":[[0,13]]}}}],["websso",{"_index":201,"t":{"303":{"position":[[12,6]]}}}],["week",{"_index":155,"t":{"226":{"position":[[12,4]]}}}],["welcom",{"_index":0,"t":{"3":{"position":[[0,7]]}}}],["we’r",{"_index":35,"t":{"57":{"position":[[0,5]]}}}],["wireguard",{"_index":654,"t":{"1573":{"position":[[0,9]]}}}],["within",{"_index":731,"t":{"2060":{"position":[[15,6]]},"2062":{"position":[[18,6]]},"2064":{"position":[[16,6]]},"2066":{"position":[[26,6]]}}}],["without",{"_index":406,"t":{"797":{"position":[[6,7]]},"1534":{"position":[[6,7]]},"1687":{"position":[[13,7]]}}}],["word",{"_index":698,"t":{"1850":{"position":[[5,5]]}}}],["work",{"_index":117,"t":{"173":{"position":[[8,5]]},"504":{"position":[[14,4]]},"506":{"position":[[14,4]]},"1280":{"position":[[0,7]]},"1611":{"position":[[23,5]]}}}],["worker",{"_index":541,"t":{"1168":{"position":[[18,7]]}}}],["workflow",{"_index":80,"t":{"123":{"position":[[7,9]]},"3460":{"position":[[8,8]]}}}],["workload",{"_index":251,"t":{"390":{"position":[[9,8]]},"599":{"position":[[30,8]]},"607":{"position":[[9,8]]}}}],["world",{"_index":828,"t":{"2869":{"position":[[5,5]]}}}],["write",{"_index":181,"t":{"283":{"position":[[0,5]]},"1679":{"position":[[7,5]]},"2676":{"position":[[0,7]]},"3062":{"position":[[9,5]]}}}],["wrong",{"_index":677,"t":{"1753":{"position":[[29,5]]}}}],["x",{"_index":28,"t":{"42":{"position":[[29,1]]},"230":{"position":[[24,1]]},"2863":{"position":[[17,1]]}}}],["xxx.tfvar",{"_index":292,"t":{"480":{"position":[[64,10]]}}}],["yaml",{"_index":820,"t":{"2804":{"position":[[18,4]]},"2980":{"position":[[16,4]]},"2989":{"position":[[0,4]]}}}],["year",{"_index":335,"t":{"585":{"position":[[51,4]]}}}],["zap",{"_index":737,"t":{"2082":{"position":[[0,3]]}}}],["zone",{"_index":384,"t":{"739":{"position":[[29,4]]}}}],["zuul",{"_index":168,"t":{"267":{"position":[[0,4]]},"269":{"position":[[23,4]]},"271":{"position":[[26,4]]},"316":{"position":[[18,4]]},"1720":{"position":[[31,4]]},"1739":{"position":[[4,4]]},"2208":{"position":[[0,4]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":4,"t":"Sovereign Cloud Stack is an open community of providers and end-users joining forces in defining, implementing and operating a fully open, federated, compatible platform. We actively encourage you to contribute either code, documentation or issues and to participate in the various discussions happening on GitHub or during our various meetings. We have created an open community space on the Matrix network. Feel free to join the several channels and start interacting with the community. A good starting point is entering the General & Announcements and the Tech channel. Check out our Community Calendar to know when our several Teams and SIGs meet.","s":"Welcome to our SCS Community","u":"/community/","h":"#welcome-to-our-scs-community","p":2},{"i":6,"t":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet","s":"First Blog Post","u":"/blog/first-blog-post","h":"","p":5},{"i":10,"t":"The OpenStackClient is installable via all major Linux Distributions: for debian and ubuntu with apt: sudo apt install python3-openstackclient for ubuntu with snap openstack CLI is installable too: sudo snap install openstackclients [!NOTE] Versions from Linux repository could be in a stable but old state. Install it directly via pypi from upstream is the recommend way. Here for example RHEL: sudo dnf install python3 python3-devel gcc python3-pip Here for example Debian and Ubuntu: sudo apt install python3-minimal python3-pip python3-venv python3-dev build-essential Here as example for SUSE sudo zypper in python3-pip python3-venv python3-dev Here for example with Apple's MacOS brew install python3 [!NOTE] Python installation for windows systems please use the python installation guide or recommend use the Linux Subsystem WSL Python Virtualenv It is also recommended to use virtual environments, here as an example for Linux and MacOS: python3 -m venv oscli source oscli/bin/activate pip install --upgrade pip pip install python-openstackclient \\ python-cinderclient \\ python-designateclient \\ python-glanceclient \\ python-neutronclient \\ python-novaclient \\ python-octaviaclient \\ python-barbicanclient For further Information see the OpenStack Project upstream website python-openstackclient. This repo holds examples for clouds-public.yaml + clouds.yaml. Alternatively you can download an OpenRC Environment file when you're logged in to Horizon: upper right side ➡️ OpenStack RC File $ source ./<$yourfile>-openrc.sh Please enter your OpenStack Password for project XXX as user YYY: openstack --help when you're using clouds.yaml you can specify multiple endpoints and select the specific endpoint by passing --os-cloud= to the openstack cmdline or setting OS_CLOUD. openstack --os-cloud MYCLOUD or export OS_CLOUD=MYCLOUD openstack OpenStack Client in action inside of the OSISM testbed:","s":"OpenStackClient (CLI)","u":"/community/cloud-resources/getting-started-openstack","h":"#openstackclient-cli","p":7},{"i":12,"t":"Create AWS like credentials with openstack ec2 credentials create. If you use libs3, store the access field in S3_ACCESS_KEY_ID and the secret field inS3_SECRET_ACCESS_KEY and set S3_HOSTNAME=. You will see the same buckets (containers) and objects whether you access your object store via the swift or via the s3 protocol.","s":"Object Storage (S3)","u":"/community/cloud-resources/getting-started-openstack","h":"#object-storage-s3","p":7},{"i":14,"t":"OpenStack SovereignCloudStack OSISM ansible terraform cloud-init","s":"References","u":"/community/cloud-resources/getting-started-openstack","h":"#references","p":7},{"i":16,"t":"This document gives an overview of the test and development cloud resources currently provided by our partners.","s":"Test and development cloud resources","u":"/community/cloud-resources/","h":"","p":15},{"i":18,"t":"To request access to an existing project, please contact the responsible community member. To apply for a new project, please create a pull request against this document (leave Unique Identifier blank) and assign it to the particular CSP team (e.g. @SovereignCloudStack/plusserver, @SovereignCloudStack/wavecon, ...)","s":"How to request cloud resources","u":"/community/cloud-resources/","h":"#how-to-request-cloud-resources","p":15},{"i":21,"t":"A brief guide on how to use the resources provided by plusserver GmbH can be found here","s":"Usage","u":"/community/cloud-resources/","h":"#usage","p":15},{"i":23,"t":"As suggested in #155 the username for non-\"service users\" will contain the users github handle and are prefixed with a plusserver default. prefix-<$github handle> Note ATM this is not directly connected to the SovereignCloudStack github org membership, accounts will be created manually for now. Example: github handle plusserver login frosty-geek u500924-frosty-geek fkr u500924-fkr Note To easy collaboration & transparency within the SCS team all users will have their default_project_id set to p500924-scs-community by default and will have full access on all projects listed below.","s":"Users","u":"/community/cloud-resources/","h":"#users","p":15},{"i":25,"t":"Service users will have their default_project_id set to a specific project and will NOT be granted full access to other projects by default. Unique Identifier Service User Name Full Access on Community Contact Description Needed until 9a1576af59644a2dbbace773ad17158d u500924-svc-sig-monitoring p500924-sig-monitoring1 fkr Service User - SIG Monitoring 31.12.2023 4925967416894fd78be6701689059653 u500924-svc-cloudmon p500924-cloudmon-target Erik-Kostelansky-dNation Service User - VP12 Test Project 31.12.2024 f89b3d64ddff4d9d8cadb5e06fa22299 u500924-svc-healthmonitor p500924-scs-healthmonitor garloff Service User - SCS Health Monitor ∞ 49cc3d72fbdf41fe8dc407f57f026dbf u500924-svc-standards p500924-scs-healthmonitor garloff Service User - SCS Standards Compliance Check ∞ 1b6bb583fc5e40e49f2a7e9b4301de65 u500924-svc-zuul p500924-scs-zuul o-otte Service User - SCS Zuul 30.11.2024","s":"Service Users","u":"/community/cloud-resources/","h":"#service-users","p":15},{"i":27,"t":"Unique Identifier Project Name Community Contact Description Needed until 2237c767cf5f456da19359ed31c1c16b p500924-scs-community fkr SCS Community Project ∞ b43cfafbcf1f4eb08865b2886c29e09b p500924-cluster-api-session garloff cluster-api hands on session ∞ 9b7a73e516be4cd1acbd63d543985c52 p500924-gonicus-dev o-otte GONICUS GmbH ∞ 3829cc7c8f034fc985f5055a1df6f247 p500924-scs-healthmonitor garloff SCS Health Monitor ∞ b97d38bf128b4479981c4dbe2ef70cd5 p500924-SIG-IAM fkr SIG IAM and VP08 ∞ 9de7d8dc2d674e52be44904d6b338b0b p500924-cloudmon Erik-Kostelansky-dNation VP12 Test Project 31.12.2024 2c9e0e4ef8d44c36807df50b06b3c81d p500924-cloudmon-target Erik-Kostelansky-dNation Target project for VP12 tests 31.12.2024 3501db829014406884990a1016f3e25d p500924-sig-monitoring1 fkr SIG Monitoring - cloudmon target ∞ 602778bad3d3470cbe58c4f7611e8eb7 p500924-dnation chess-knight dNation dev for VP06c ∞ 91091d4039a6457db27d48d58bb1b4e4 p500924-jschoone jschoone KaaS dev and evaluation ∞ 93956190702b4a7d8a8886806d57713f p500924-metering cah-link Dev Environment for VP13 31.12.2023 abbe6561cf6248b6af395334aa09af85 p500924-harbor chess-knight SCS Harbor for VP06c ∞ e7622c1048ac4520a2d050ae141e826b p500924-tender-6a mxmxchere Dev Environment for VP06a ∞ eeed7e0ad33f42f189fb4165116f5a1b p500924-dnation-k8s matofeder dNation dev for VP06c ∞ b342f37804f14459bdf703573169bf79 p500924-minery 90n20 Testbed env for Pentesting 30.11.2024 0fa3c3559f0d4f39ba7aa70c7f7188ca p500924-tender-10-3 tonifinger Dev Environment for VP10-3 ∞ b682eb90fb834278afb1182018dd2133 p500924-scoopex scoopex Marc's gx-scs project ∞ 021af0688c594bf88ed675b942d3bea8 p500924-gx-cred-generator anjastrunk SCS Gaia-X Self-Description Generator ∞ a07c811315ad40f585945b2939ef12dd p500924-scs-zuul o-otte SCS Zuul 30.11.2024 1846709967a744b69f9eb48cac89bb04 p500924-scs-k8s-e2e chess-knight E2E-Test for KaaS ∞ 6ee4b373cb6d42a5bb59d5080987b70d p500924-bitkeks bitkeks Cluster Stacks and Sec ∞ 4ea22ba875474d039cb57d20b7f710b5 p500924-kaas-playground0 jschoone Playground0 for Hackathon 30.09.2024 476672f1023b4bac8837f95a76881757 p500924-kaas-playground1 jschoone Playground1 for Hackathon 30.09.2024 04dac2927f744479a5d4c23dd0a3c378 p500924-kaas-playground2 jschoone Playground2 for Hackathon 30.09.2024 75279777029847ab9b399390c0dd6042 p500924-kaas-playground3 jschoone Playground3 for Hackathon 30.09.2024 0b3c75f80b6743778daccec0da423465 p500924-kaas-playground4 jschoone Playground4 for Hackathon 30.09.2024 2340a73644ca47189329061e9c2a0bfe p500924-kaas-playground5 jschoone Playground5 for Hackathon 30.09.2024 3c5bae4a233c4a9d8ae2e4b799d757c9 p500924-kaas-playground6 jschoone Playground6 for Hackathon 30.09.2024 03783b4952344c849af37d26818d19f0 p500924-kaas-playground7 jschoone Playground7 for Hackathon 30.09.2024 5c6d4d7183834eafbc20108ad647a9c0 p500924-kaas-playground8 jschoone Playground8 for Hackathon 30.09.2024 7e18881932f749baa7d547ebd407b8d8 p500924-kaas-playground9 jschoone Playground9 for Hackathon 30.09.2024 d9dc2f33e76240219db484526e9f601d p500924-akafazov akafazov akafazov Testbed 30.04.2024 b07ad6a84982471b9a344ef9947f0e0f p500924-gtema gtema Testbed for gtema ∞ e89ac8c9f66f46b5a983b2a05d2a66ec p500924-zuse-z3 zuse-z3 Josefine's gx-scs project ∞ fc1f7a0e10a64d6083dcdbcb7ccf6ff4 p500924-compliance-monitor mbuechse SCS Compliance Monitor Deployment ∞","s":"Projects","u":"/community/cloud-resources/","h":"#projects","p":15},{"i":30,"t":"Unique Identifier Service User Name Full Access on Community Contact Description Needed until df4af5376bbd4de587c4335622149be7 scs-standards scs-standards itrich Service User - SCS Standards Compliance Check ∞","s":"Service Users","u":"/community/cloud-resources/","h":"#service-users-1","p":15},{"i":32,"t":"Unique Identifier Project Name Community Contact Description Needed until 718964b4b87446688ac04b151519fb51 scs garloff SCS Health Monitor ∞ c46ccc9e695c4b23bacee2ad11145d9a scs-health-monitor garloff SCS Health Monitor ∞ 00de553df86949b49365baee6375fb5a scs-standards itrich SCS Health Monitor ∞","s":"Projects","u":"/community/cloud-resources/","h":"#projects-1","p":15},{"i":34,"t":"This document gives an overview of what SCS central services are deployed and who is responsible for them in plusserver gx-scs infrastructure.","s":"Central services","u":"/community/central-services/plusserver-gx-scs","h":"","p":33},{"i":37,"t":"Harbor​ Responsibility: @SovereignCloudStack/vp06c Services: SCS Registry k8s-harbor Utilization: Instances: 7 VCPUs: 32 RAM: 64GB Spec: version: v7.0.0 - R6 management cluster: 1 instance: SCS-2V:4:20 image: Ubuntu 22.04 (20230416) k8s: v1.25.3 - KinD workload cluster: 6 instances: 3 control-planes: SCS-2V:4:20 3 workers: SCS-8V:16:100 image: ubuntu-capi-image-v1.28.7 k8s: v1.28.7","s":"K8s clusters","u":"/community/central-services/plusserver-gx-scs","h":"#k8s-clusters","p":33},{"i":40,"t":"Monitoring​ Responsibility: @SovereignCloudStack/vp06c Services: k8s-observability Utilization: Instances: 7 VCPUs: 32 RAM: 64GB Spec: version: v6.0.0 - R5 management cluster: 1 instance: SCS-2V:4:20 image: Ubuntu 22.04 (20231211) k8s: v1.27.3 - KinD workload cluster: 6 instances: 3 control-planes: SCS-2V:4:20 3 workers: SCS-8V:16:100 image: ubuntu-capi-image-v1.27.5 k8s: v1.27.5","s":"K8s clusters","u":"/community/central-services/plusserver-gx-scs","h":"#k8s-clusters-1","p":33},{"i":44,"t":"UI (Horizon): https://ui.gx-scs.sovereignit.cloud/ API auth url (Keystone): https://api.gx-scs.sovereignit.cloud:5000 Object Storage endpoint (S3/SWIFT): https://api.gx-scs.sovereignit.cloud:8080","s":"URLs for access","u":"/community/cloud-resources/plusserver-gx-scs","h":"#urls-for-access","p":41},{"i":46,"t":"For your login you will need: Username (u500924-<$github-handle>) Password Domain (d500924)","s":"Authentication (UI)","u":"/community/cloud-resources/plusserver-gx-scs","h":"#authentication-ui","p":41},{"i":48,"t":"See Getting Started with OpenStack","s":"Getting Started with OpenStack","u":"/community/cloud-resources/plusserver-gx-scs","h":"#getting-started-with-openstack","p":41},{"i":51,"t":"UI (Horizon): https://dashboard.wavestack.de/ API auth url (Keystone): https://api.wavestack.de:5000 Object Storage endpoint (S3/SWIFT): https://rgw.muc5.wavestack.de:443","s":"URLs for access","u":"/community/cloud-resources/wavestack","h":"#urls-for-access","p":49},{"i":53,"t":"For your login you will need: Username Password Domain","s":"Authentication (UI)","u":"/community/cloud-resources/wavestack","h":"#authentication-ui","p":49},{"i":55,"t":"See: Getting Started with OpenStack","s":"OpenStackClient (CLI)","u":"/community/cloud-resources/wavestack","h":"#openstackclient-cli","p":49},{"i":58,"t":"Our meetings are publicly announced and we are happy to welcome both newcomers and established members alike. You can navigate either through the calendar below or subscribe with your favorite client to https://sovereigncloudstack.github.io/calendar/scs.ics. The calendar is collaboratively maintained on GitHub and new entries, such as a lightning talk, are highly appreciated!","s":"We’re an open community","u":"/community/collaboration/","h":"#were-an-open-community","p":56},{"i":60,"t":"We use the GitHub flow to track and discuss changes in issues, then propose and review changes in pull requests. See the GitHub documentation for more details.","s":"Collaborating with issues and pull requests","u":"/community/collaboration/","h":"#collaborating-with-issues-and-pull-requests","p":56},{"i":63,"t":"Weekly with all teams on Thursday at 15:05 CEST (40 mins) In some weeks we schedule an additional lightning talk at 15:40 CEST","s":"Project updates","u":"/community/collaboration/","h":"#project-updates","p":56},{"i":65,"t":"Weekly Team meetings (~1hr) for currently 4 teams: Team IaaS Team Container Team IAM & Security Team Operations Please refer to the public calendar above for details.","s":"Sprint review/Backlog refinement/Sprint planning meetings","u":"/community/collaboration/","h":"#sprint-reviewbacklog-refinementsprint-planning-meetings","p":56},{"i":67,"t":"There are a number of SIG meetings and hacking sessions that meet weekly or bi-weekly SIG Monitoring and Logging SIG Standardization and Certification SIG Documentation SIG Community SIG Central API Please refer to the public calendar above for details.","s":"Special interest groups (SIGs) and hacking sessions","u":"/community/collaboration/","h":"#special-interest-groups-sigs-and-hacking-sessions","p":56},{"i":69,"t":"In this meeting, we come together to shape our community strategy and coordinate collaborative efforts within our community. Our goal is to cultivate an open and welcoming community where we can share the message of SCS. We plan engaging community events, strive to make this open-source community even more inclusive, and aim to keep it informative, inspiring, and captivating. We warmly invite you to join us in our mission and become a part of this exciting journey!","s":"SIG Community","u":"/community/collaboration/sig-community","h":"","p":68},{"i":71,"t":"For defining a Common and Central interface for the Customers of SCS cloud to manage the Infrastructure cloud resources open stack and Kubernetes and identity and Access management. We want to define a single point of managment with consistent experience for managing the entire infrastructure. We aim to establish an unified and central interface that provides customers of the SCS clouds with the ability to manage cloud resources and/or services. SIG explores the possibilities for a central API by creating a MVP.","s":"SIG Central API","u":"/community/collaboration/sig-central-api","h":"","p":70},{"i":73,"t":"We curate and enhance the SCS Documentation, focusing on refining its information architecture for optimal usability. Our objective is to facilitate straightforward contributions from community developers and to provide operators with a clear, quick reference guide that accelerates the initiation of an SCS deployment.","s":"SIG Documentation","u":"/community/collaboration/sig-documentation","h":"","p":72},{"i":75,"t":"The Special Interest Group (SIG) Monitoring meets on a fortnightly base (alternating with the audit log WG) to discuss the monitoring needs of SCS Operators, Users and Integrators. Together we shape how monitoring and observability within the SCS landscape looks like.","s":"SIG Monitoring","u":"/community/collaboration/sig-monitoring","h":"","p":74},{"i":77,"t":"The Team Container deals with all topics around Containers and Kubernetes. at the moment: Kubernetes Deployments via ClusterAPI in the future deployments via ClusterStacks KaaS Standard","s":"Team Container","u":"/community/collaboration/team-container","h":"","p":76},{"i":79,"t":"In this Special Interest Group, we discuss and align our activities and approach to standardization and certification. That is to say, we devise and refine the relevant concepts and processes; we work on a roadmap for new certificate versions; and we align on which standards are desireable for each certificate subject. We then work with the teams to align on existing or new standards. Besides aspects of openness and sovereignty, the main goal of our standards is interoperability. We should take the user perspective: As a member of a DevOps team developing a service (think SaaS or PaaS) for SCS, I need XYZ. Every standard should be abstract enough to work regardless of the SCS reference implementation.","s":"SIG Standardization","u":"/community/collaboration/sig-standardization","h":"","p":78},{"i":81,"t":"We build the reference implementation of the IaaS parts of SCS that informs and adheres to the SCS IaaS standards.","s":"Team Iaas","u":"/community/collaboration/team-iaas","h":"","p":80},{"i":83,"t":"We build tooling and infrastructure design for easy, efficient and transparent ways to operate an SCS Cloud.","s":"Team Ops","u":"/community/collaboration/team-ops","h":"","p":82},{"i":87,"t":"What is it and for what do I need this? What benefits does it have for users? What organization/company does this belong to? (Link to company/organization) Where am I – as module – within the bigger context of SCS?","s":"Overview - mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#overview---mandatory","p":84},{"i":89,"t":"What minimal requirements do i need to quickstart?","s":"Requirements - mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#requirements---mandatory","p":84},{"i":91,"t":"Link to requirements What is the aim of this quickstart guide? Caution: only for testing, not for production Rule: one line per command for easy copy&paste and one line for description where possible Rule: only one working path for installation!","s":"Quickstart - optional. If it is possible, then mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#quickstart---optional-if-it-is-possible-then-mandatory","p":84},{"i":93,"t":"Aim is a production ready installation","s":"Getting Started - mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#getting-started---mandatory","p":84},{"i":95,"t":"Showing all possible config options","s":"Configuration – mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#configuration--mandatory","p":84},{"i":97,"t":"Description for how can i contribute with Link to Github repository","s":"Contribute – mandatory","u":"/community/contribute/doc-files-structure-guide","h":"#contribute--mandatory","p":84},{"i":99,"t":"Roadmap - optional","s":"FAQ`s – optional","u":"/community/contribute/doc-files-structure-guide","h":"#faqs--optional","p":84},{"i":101,"t":"The Team IAM deals with topics around Identity and Access Management. Users that access cloud and container infrastructure need to authenticate themselves and then authorizations to see and access resources from the infrastructure are derived from the identity of the users as they belong to groups and are roles are assigned to them (or the groups they belong to). Sovereign Cloud Stack has the goal that user identities can used across several layers in the stack (most importantly IaaS and Container layer), that user management should be a self-service capability and that user identities can be federated, i.e. user identities and authentication from one SCS cloud (or from one standards-compliant Identity Provider) can be used in other SCS clouds. Federation is an imporant principle in SCS.","s":"Team IAM","u":"/community/collaboration/team-iam","h":"","p":100},{"i":103,"t":"The aim within this documentation is to have a good developer experience and a low entry barrier to start with SCS. For this to achieve we think all docs that define the SCS stack and have been developed by the SCS community should be within this documentation framework.","s":"Documentation workflow explanation","u":"/community/contribute/docs-workflow-explanation","h":"","p":102},{"i":105,"t":"All general docs are located within the SovereignCloudStack/docs repository. Docs that explain, guide or contextualize specific modules such as the openstack-image-manager or the k8s-cluster-api-provider reside within their repository in a seperate docs directory. Both, the general docs and docs of the external repositories are combined into the one unified documentation collection that is being rendered in a static page on https://docs.scs.community. In order to make this work we have developed a workflow that syncs all doc repositories and distills only the relevant markdown files. The script is called getDocs. It is a postinstall script and is executed after npm install. This has the advantage to have the docs – coming from the cloud – in your local docusaurus development environment as well as in the build process. You'll find the script in the root directory of the SovereignCloudStack/docs-page repository: getDocs.js const fs = require('fs') const { execSync } = require('child_process') // Read the contents of the \"docs.package.json\" file and remove all whitespace const reposJson = fs .readFileSync('./docs.package.json', 'utf8') .replace(/\\s/g, '') // Parse the JSON and create an array of repositories const repos = JSON.parse(reposJson) const ghUrl = 'https://github.com/' // Clone each repository, remove git folders and README files, and copy the docs to the target directory repos.forEach((repo) => { const repoDir = `repo_to_be_edited/${repo.label}` // Clone the repository const cloneCommand = `git clone ${ghUrl + repo.repo} ${repoDir}` execSync(cloneCommand) // Remove git folders const removeGitCommand = `rm -rf ${repoDir}/.git` execSync(removeGitCommand) // Remove README files const removeReadmeCommand = `find ${repoDir} -name \"README.md\" | xargs rm -f` execSync(removeReadmeCommand) // Create the docusaurus subdirectory const subDirPath = `${repo.target}/${repo.label}` fs.mkdirSync(subDirPath, { recursive: true }) // Copy docs content from A to B const copyDocsCommand = `cp -r ${repoDir}/${repo.source} ${subDirPath}` execSync(copyDocsCommand) // Remove the cloned repository const removeRepoCommand = 'rm -rf repo_to_be_edited' execSync(removeRepoCommand) })","s":"Information Architecture","u":"/community/contribute/docs-workflow-explanation","h":"#information-architecture","p":102},{"i":107,"t":"In this Guide you will learn how to integrate your documentation to the SCS documentation, which you will find on docs.scs.community.","s":"Adding Docs Guide","u":"/community/contribute/adding-docs-guide","h":"","p":106},{"i":109,"t":"Determine the type of your documentation and click to continue. Technical documentation Operational documentation Community documentation If unsure don't hestitate to ask us at Matrix","s":"Step 1 – Documentation type","u":"/community/contribute/adding-docs-guide","h":"#step-1--documentation-type","p":106},{"i":112,"t":"Your repository containing the documentation has to... be a public repository contain a directory named /doc or /docs within root, containing the documentation files The documentation files have to be in markdown format and... comply SCS licensing guidelines match our markdown file structure guideline linting Rules styleguide","s":"Step 1 – Checklist","u":"/community/contribute/adding-docs-guide","h":"#step-1--checklist","p":106},{"i":114,"t":"File a Pull Request within the docs-page repository and add your repo to the docs.package.json: [ { \"repo\": \"demo-organisation/demo-repository\", \"source\": \"doc/*.md\", \"target\": \"docs\", \"label\": \"demo-repository-label\" } ] key description repo reference to github organisation and repository source path to content to copy: Either glob matching individual markdown files OR the path of a single directory target directory where the files should be copied to within the docs-page repo label label for directory. only mandatory if source file is set to copy only *.md files and not the complete directory Once it is approved and merged, a postinstall script will be triggered within the build process. This initiates downloading, copy and distilling which results in this static generated documentation page – now with your content. An explanation on how the sync & distill workflow and a guide on how to test it in a local development environment you will find here.","s":"Step 2 – Adding your repo to the docs.json","u":"/community/contribute/adding-docs-guide","h":"#step-2--adding-your-repo-to-the-docsjson","p":106},{"i":116,"t":"Your doc files contain operational knowledge. Which layer in the stack do they belong to? iaas iam kaas operations File a Pull Request within the docs repository and add your markdown files to the fitting directory.","s":"2. Operational documentation","u":"/community/contribute/adding-docs-guide","h":"#2-operational-documentation","p":106},{"i":118,"t":"Your doc files contain knowledge regarding our community? Choose the right directory. If unsure don't hestitate to ask us at Matrix. File a Pull Request within the docs repository and add your markdown files to the fitting directory.","s":"3. Community documentation","u":"/community/contribute/adding-docs-guide","h":"#3-community-documentation","p":106},{"i":120,"t":"In order to have a clean content repository regarding all markdown files we enforce linting on: all staged files prior committing all Pull Requests","s":"Linting Guide","u":"/community/contribute/linting-guide","h":"","p":119},{"i":122,"t":"Run markdownlint against staged git files with Husky git hook: lint-staged husky The rules are enforced on markdown files, for which we use: markdownlint-cli2 for markdownlint prettier for code formatting The markdownlint rules are defined in the configuration file .markdownlint-cli2.jsonc Additionally we use markdownlint-rule-search-replace for fixing","s":"Pre Commit","u":"/community/contribute/linting-guide","h":"#pre-commit","p":119},{"i":124,"t":"There are two actions running on every Pull Request on the main branch. link-validator.ymlis checking every link in markdown files. pr-markdownlint.ymlis checking all markdown files regarding to the rules defined within .markdownlint-cli2.jsonc","s":"Github Workflows","u":"/community/contribute/linting-guide","h":"#github-workflows","p":119},{"i":127,"t":"We adopt the default Admonition colors for Note, Tip, Info, Caution, Danger by docusaurus: Docusaurus Admonitons note Some content with Markdown syntax. tip Some content with Markdown syntax. info Some content with Markdown syntax. caution Some content with Markdown syntax. danger Some content with Markdown syntax.","s":"Admonitions","u":"/community/contribute/styleguide","h":"#admonitions","p":125},{"i":129,"t":"Blockquotes should be handled with standard markdown > Example Blockquote: The raw data format is really the only sensible format option to use with RBD. asdasdasdasd asd asd a Technically, you could use other QEMU-supported formats (such as qcow2 or vmdk), but doing so would add additional overhead, and would also render the volume unsafe for virtual machine live migration when caching (see below) is enabled.","s":"Blockquotes","u":"/community/contribute/styleguide","h":"#blockquotes","p":125},{"i":131,"t":"We support markdown language features for Codeblocks. It is mandatory to define the language to be quoted, when using codeblocks. Syntax Highlighting is also supported by Docusaurus via Prism. We are using the GitHub language themeing as default. Python example def code_block(): # Everything in this function is part of the same code block print (1) print (2) for i in range(4): # Everyting in this loop is part of the same code block print (i) Javascript example const code_block = () => { console.log('inside code_block') } YAML example --- doe: 'a deer, a female deer' ray: 'a drop of golden sun' pi: 3.14159 xmas: true french-hens: 3 calling-birds: - huey - dewey - louie - fred Ruby example require 'redcarpet' markdown = Redcarpet.new(\"Hello World!\") puts markdown.to_html","s":"Codeblocks","u":"/community/contribute/styleguide","h":"#codeblocks","p":125},{"i":133,"t":"We use nearly all default rules of ansible lint. A listing of all these rules can be found in the Ansible Lint documentation: https://ansible.readthedocs.io/projects/lint/rules/. Please always use the ansible linting to check if the code complies with the default linting rules. However, since in most cases we always use the latest version of packages and Ansible lint does not provide this, we decided to disable the package_latest rule.","s":"Ansible Style Guide","u":"/community/contribute/styleguides/ansible_styleguide","h":"","p":132},{"i":135,"t":"Tasks must always have names. The only exception allowed is for forked playbooks. A name never starts with a small letter Names are written in present tense No punctuation is used in names","s":"Task naming","u":"/community/contribute/styleguides/ansible_styleguide","h":"#task-naming","p":132},{"i":137,"t":"To check the key order we use our own rule. This can be found here.","s":"Key Order","u":"/community/contribute/styleguides/ansible_styleguide","h":"#key-order","p":132},{"i":139,"t":"The become directive is only set when needed and is always set explicitly for each task that needs it. Blocks, roles or playbooks are never executed in a privileged mode. We always insert the become directive between the name of a task and the task itself. This also applies to related directives like become_user or become_flags. This is for better visibility if a task is privileged or not. - name: Copy hddtemp configuration file become: true ansible.builtin.copy: src: \"{{ ansible_os_family }}/hddtemp\" dest: \"{{ hddtemp_conf_file }}\" owner: root group: root mode: 0644 notify: Restart hddtemp service","s":"Positioning and use of the become directive","u":"/community/contribute/styleguides/ansible_styleguide","h":"#positioning-and-use-of-the-become-directive","p":132},{"i":141,"t":"If you need to use the when condition please add this at the end-section from the task where it is needed. This makes the code easier to understand for others. Ansible lint provides the when condition under the task name for blocks. To keep the code clear we decided against it. Please disable this with a noqa if necessary. For example: - name: \"Archive existing {{ resolvconf_file }} file\" become: true ansible.posix.synchronize: src: \"/etc/resolv.conf\" dest: \"/etc/resolv.conf.{{ ansible_date_time.date }}\" archive: true delegate_to: \"{{ inventory_hostname }}\" when: stat_resolvconf_file.stat.islnk is defined and not stat_resolvconf_file.stat.islnk","s":"Position of the when condition","u":"/community/contribute/styleguides/ansible_styleguide","h":"#position-of-the-when-condition","p":132},{"i":143,"t":"Collections are always defined as in the following example. netbox.netbox is here the collection that is used. - name: Configure netbox manufacturers netbox.netbox.netbox_manufacturer: netbox_url: '{{ netbox_url }}' netbox_token: '{{ netbox_token }}' data: name: '{{ item.value.name }}' slug: '{{ item.value.slug }}' description: \"{{ item.value.description | default('') }}\" state: present with_dict: '{{ netbox_data_manufacturers }}' Please don´t declare it in this way!: collections: - netbox.netbox tasks: - name: Manage Discworld site netbox_site: netbox_url: \"{{ netbox_url }}\" netbox_token: \"{{ netbox_token }}\" validate_certs: false data: name: Discworld slug: discworld state: present If you have to use collections please define them in a requirements.yml. Example yaml: roles: - name: geerlingguy.certbot version: master type: git src: git+https://github.com/geerlingguy/ansible-role-certbot.git --- collections: - name: ansible.netcommon source: https://galaxy.ansible.com - name: https://github.com/ansible-collections/ansible.posix.git type: git version: main","s":"Usage of collections","u":"/community/contribute/styleguides/ansible_styleguide","h":"#usage-of-collections","p":132},{"i":145,"t":"If you want to reuse roles please do it in the following way: First you have to declare the role or collection in the requirements.yml like shown in the example before. Than you can use it in playbooks like this roles: - role: osism.services.auditd","s":"Usage of roles from other collections","u":"/community/contribute/styleguides/ansible_styleguide","h":"#usage-of-roles-from-other-collections","p":132},{"i":147,"t":"Parameters that provide a list are always defined as in the following example. docker_hosts_defaults sets the defaults in the role. Overriding is only possible with the ansible-defaults repository. In the configuration repository, docker_hosts_extra is then used to add additional items to the list. docker_hosts itself is never modified from the outside. docker_hosts_defaults: - 'unix:///var/run/docker.sock' docker_hosts_extra: [] docker_hosts: '{{ docker_hosts_defaults + docker_hosts_extra }}'","s":"Parameters that offer lists","u":"/community/contribute/styleguides/ansible_styleguide","h":"#parameters-that-offer-lists","p":132},{"i":149,"t":"Please think twice before turning off changed_when. It's a fairly simple yet safety-relevant linting rule and is quite easy to implement.","s":"Usage of changed_when","u":"/community/contribute/styleguides/ansible_styleguide","h":"#usage-of-changed_when","p":132},{"i":151,"t":"In principle, it is only allowed to disable rules if there is really no other possibility. Please do not disable rules in general but only in individual cases via Noqa. Please use in this case the full rulename and not the numbers, because them are depricated. If it makes sense to ignore a rule, please open up an issue in the https://github.com/osism/issues repository with a label discussion.","s":"Disable linting rules","u":"/community/contribute/styleguides/ansible_styleguide","h":"#disable-linting-rules","p":132},{"i":153,"t":"This Guide shows you how to setup docusaurus on your local machine to run this docs in your local development enviroment.","s":"Installation","u":"/community/contribute/local-docusaurus-development-guide","h":"","p":152},{"i":155,"t":"git Node.js v16","s":"Requirements","u":"/community/contribute/local-docusaurus-development-guide","h":"#requirements","p":152},{"i":158,"t":"It is recommended to install Node.js via nvm – a node version manager – to have the possibility to switch between different node.js versions. macOS Linux Windows You must have macOS desktop access with administrator privileges. Login to the macOS desktop system and install Homebrew on your system (if not already installed). Install nvm via homebrew: brew install nvm See this installation guide on GitHub by nvm-sh for installing nvm. NVM for Windows runs in an Admin shell. You'll need to start powershell or Command Prompt as Administrator to use nvm-windows. Install NVM for Windows with an Installer provided by nvm-sh on their release page. Once installed you can check the available versions with nvm list If you have no other projects, where you need a different version, it is recommended to install the latest stable LTS version of node. nvm install lts nvm has now installed the latest node.js version with its package manager npm. Check if the installation has been successfull by checking it: node --version","s":"Step 1 – Installing Node.js via nvm","u":"/community/contribute/local-docusaurus-development-guide","h":"#step-1--installing-nodejs-via-nvm","p":152},{"i":160,"t":"Clone the docs repository via your favourite method: HTTPS SSH HTTPS git clone https://github.com/SovereignCloudStack/docs.git SSH git clone git@github.com:SovereignCloudStack/docs.git","s":"Step 2 – Cloning the repository","u":"/community/contribute/local-docusaurus-development-guide","h":"#step-2-cloning-the-repository","p":152},{"i":162,"t":"Change your working directory within your terminal to the root of the cloned repository /docs and install all dependencies: npm install","s":"Step 3 – Installing dependencies","u":"/community/contribute/local-docusaurus-development-guide","h":"#step-3--installing-dependencies","p":152},{"i":164,"t":"You can now run the local development server from your terminal: npm start Once the server is up and running, your terminal will show you the local URL which you can open with your browser to see the page.","s":"Step 4 – Starting the development server","u":"/community/contribute/local-docusaurus-development-guide","h":"#step-4--starting-the-development-server","p":152},{"i":166,"t":"As Sovereign Cloud Stack (SCS), our mission is to provide Operators (be it Cloud Service Providers or just internal IT departments) with a well working software stack, that avoids exposing them to legal risks or additional restrictions that limits the usefulness. Free software licenses have this intention but differ in how they achieve it and in what kind of protections they provide. In the first approximation, all OSI-approved open source licenses can be considered as valid options. As a matter of fact, we do consider projects under such licenses as valid modules for SCS — where we use such projects and adjust or extend them, we would provide our contributions under the license terms of the respective project, so we can achieve our goal to feed back code upstream to the respective project, contribute to it and avoid fragmentation. Where we do create independent code, we do have additional preferences, though. For our own code, we do prefer the Affero General Public License version 3 (AGPLv3) as license. Likewise, for documentation, we prefer CC-BY-SA. Where we create standard libraries to interface with our software, we would consider the LGPLv3 for these, as we don't want interaction with our platform to be seen as requiring licensing code.","s":"License considerations for SCS","u":"/community/license-considerations","h":"","p":165},{"i":168,"t":"The GPL family of licenses are reciprocal licenses — sometimes called copyleft licenses — the recipient of the licensed code can make all sorts of modifications, but if she uses the code to release software (GPL) or provide a networked service (AGPL) to others, then she must grant the same rights to the recipients — this includes making the modifications available under the same terms as the received software. Microsoft has infamously attacked copyleft licenses (and specifically the GPL) as cancerous \"viral\" license. Reciprocity has many advantages: Code that has been created as free software will stay free. While GPL code can be combined in a larger software collection with proprietary software, the code itself including its enhancements etc. (technically: all derived works, see below) will remain free. The obligation to make the changes available avoids fragmentation. As changed and \"improved\" versions need to be made available, it is much easier to review and feed those changes back and create a unified upstream codebase that reflects the needs of the complete user base by including the needed changes. This was observed and reported by Martin Fink (HP's former CTO). The hugely successful Linux kernel project uses the GNU GPL; many of the more traditional key projects in the open source world use copyleft licenses such as the AGPL, GNU GPL, GNU LGPL, MPL or the OSL.","s":"Reciprocity","u":"/community/license-considerations","h":"#reciprocity","p":165},{"i":170,"t":"Not fulfilling the license terms of a software license typically leads to the ability for the license owner to revoke the license — as it is relatively easy to not fulfill all obligations of the GPL out of sheer negligence, the revocation without prior warning seems disproportionate — this is sometimes called the GPL death penalty. The open source community though has a strong interest in bringing every licensee into compliance by giving violators a fair chance to correct their behavior. SCS explicitly supports the GPL Cooperation Commitment and the respective document from the Linux kernel developers and pledges to give violators a warning and a chance to correct action by allowing for a cure period. This is a bit of a legacy issue — it is relevant to (L)GPLv2 code only — v3 of L/A/GPL does already contain language that has cure provisions, so it's clear by the licensing terms. Many companies seem to be worried that they will inadvertently violate the GPL by negligence. And it is true that a company needs a tighter control of the usage of inbound source code which comes with a reciprocal license than the permissive BSD 3-clause or Apache Software (v2) licenses. This advantage however quickly turns into a disadvantage as soon as the company does significant outbound open source contributions under a permissive license — they rarely want to give their competitors an opportunity to consume their contributions and then add proprietary changes to gain an advantage. In general, companies are well advised to have a detailed understanding of all code that is being used and contributed and their respective license terms — for proprietary and open source code and for reciprocal and for permissive licenses. Some companies have successfully installed license review boards or open source review boards to create oversight, recommendations and policies to ease the governance. Despite this, many of the recent open source projects, especially in the cloud world have adopted permissive licenses, such as X11, BSD 3-clause, MIT and especially the popular Apache software license (ASL2), as it appears to allow for faster adoption by companies that may not have mature open source policies in place or that simply have overly careful lawyers which may be influenced by the scare tactics some bad companies have built on top of copyleft licenses.","s":"Controversy","u":"/community/license-considerations","h":"#controversy","p":165},{"i":172,"t":"The reciprocity of the GNU GPL does not apply on the creation of a derived work. A company can consume GPL'ed code and change it to their own liking without ever making any the changes available if only used in-house. The terms however do apply as soon as the derived work is released, i.e. the software is passed on to a third party. In modern times, software is often used to provide a networked service (think SaaS) to third parties. Unlike the standard GPL, the Affero GPL (AGPL) does consider the act of making it available in such a way as similar to releasing the software and does require that applied changes to the software are being made available in this case. The AGPL thus closes a shortcoming in the traditional non-Affero GPL for a world that increasingly moves towards networked services. The very successful Nextcloud project uses the AGPLv3.","s":"Affero","u":"/community/license-considerations","h":"#affero","p":165},{"i":174,"t":"What exactly constitutes derived work needs to be defined — it's one of the questions where copyright law can get subtle. From a practical view, consuming (non-trivial) source code and binary linking is typically considered creating derived works. Whereas interacting via a network API or starting another process is typically considered a copyright boundary. To avoid any unclarity, the Linux kernel community has explicitly called out using Linux system calls (which includes using the interface definitions) is a copyright boundary and can thus be done by applications without any license implications. Considering linked code to be derived works (as is the case in the GPL and AGPL) and thus requiring it under the same (or a compatible) copyleft license is considered a Strong Copyleft license. Libraries are often providing implementations for standard services and helpers; it may not be reasonable to consider applications that want to use a library as derived works from that library and requiring the application to thus be licensed under a (compatible) copyleft license. For these libraries, a Weak Copyleft license (such as the LGPL or the EPL can be used. This would still require changes to the library itself to me made available under the copyleft license but would make binary linking (including the use of interface definitions) a copyright barrier and thus allow for non-copylefted code to be linked against a weakly copylefted library. This license is used by many of the standard and system libraries in the Linux world and is often a good choice for libraries of standardized services.","s":"Derived works and Strong vs. Weak Copyleft","u":"/community/license-considerations","h":"#derived-works-and-strong-vs-weak-copyleft","p":165},{"i":176,"t":"Free software licenses are intended to give users broad rights — the GNU GPL talks about the four freedoms to use software for any purpose, to study and adjust the software (this needs source code access), to redistribute the software and to improve it and to make these improvements available. Software patents can significantly subvert the intended rights — the open source community in general dislikes software patents for this and many other reasons that are discussed elsewhere . In some countries, there are rules that prevent pure software from being patented, though not all patent offices are fully following these rules. As software patents are existing and a serious danger to the open source goals, there are a few attempts to improve the situation. The Apache Software License (a permissive license), requires code contributors to grant a patent license to all downstream recipients of the code to use the contributed code by itself or in combination with the project that it was contributed to and makes a possible patent holder lose its license rights should he nevertheless try to assert a patent against the thus licensed use. The (A)GPLv3 has a similar clause. The Open Invention Network (OIN) has a meanwhile huge patent pool that is cross-licensed between all participants and which can freely be used in a large list of covered open source software by everyone, except for those that raise patent violation claims against any of the covered open source projects. This basically restricts those patents to be only used defensively in the context of the covered open source projects. Should SCS be in a position to make inventions that should be protected by a software patent, it pledges to contribute these to the OIN pool.","s":"Patents","u":"/community/license-considerations","h":"#patents","p":165},{"i":178,"t":"Very few Open Source projects require copyright assignment; the GNU projects are the only commonly used ones that the author is aware of. This results in fully centralized copyright ownership. This puts the FSF into a very strong position — a position to enforce copyright, to change licenses etc. This requires a lot of trust towards the copyright assigneed. Most open source projects prefer distributed copyright — the authors (or their employers) retain the copyright to their works. They grant a license for the open source project to use and integrate and redistribute the work — typically the license grant is extended to the public. In a sufficiently distributed copyright model, it is very hard to change a license, as all copyright holders would need to agree. This can both be considered advantageous and disadvantageous. Many software projects use Contributor License Agreements (CLAs), documenting that contributed code grants certain rights to the project owner (a foundation or sometimes a company). This ensures that the project owner has all needed rights to use, protect, redistribute ... the code. If the CLA contains copyright assignment, it also allows the project to change the license or to create derived works under a different license. While this is advantageous for the project owner, it is not necessarily advantageous for the code contributor. Copyright enforcement does not require all copyrights to be held by a legal entity. Any holder of significant copyrights can actually enforce it against violators. The Linux kernel and an increasing number of projects do not work with copyright assignments nor CLAs, but with Developer Certificates of Origin (DCO — the signed-off lines of kernel commits). This is deemed sufficient to document the origin and the authorization to contribute code. The SCS project will not change the license. There however might be cases, where potential users can not consume AGPL'ed or LGPL'ed code (due to corporate policies, e.g. based on bad experience, immature license governance practices or lawyers that panic). Our goal would be to ensure that our licensing terms and all other pledges provide the assurance needed that users do not need to be afraid of the AGPL. The cure provisions from v3 of the GPL license family actually also help to avoid unnecessary fear. However, unfortunately, some \"open source\" companies in the past have abused copyleft with a scare and sell a proprietary license tactics to make money, which has hurt copyleft acceptance significantly. We might thus not be successful and need to somehow accept not serving all users or come up with a relicensing scheme that can not corrupt ourselves. We are following the copyleft-next discussion to work out how we can best achieve this, but have not yet found the silver bullet. This might have an influence how we do DCOs, maybe under a permissive license, or maybe need to use CLAs.","s":"Copyright Assignments and Contributor License Agreements","u":"/community/license-considerations","h":"#copyright-assignments-and-contributor-license-agreements","p":165},{"i":180,"t":"It is best practice that open source projects grant their downstream users the same license rights as they received contributions under. Or worded the opposite direction: It is best practice to require no more rights to be granted from upstream contributors (in the CLA or DCO) than the projects grants to downstream consumers of the project. SCS follows this best practice.","s":"License in = License out","u":"/community/license-considerations","h":"#license-in--license-out","p":165},{"i":182,"t":"https://en.wikipedia.org/wiki/Comparison_of_free_and_open-source_software_licences https://en.wikipedia.org/wiki/Software_patents_and_free_software https://joinup.ec.europa.eu/collection/eupl/matrix-eupl-compatible-open-source-licences https://lwn.net/Articles/592503/ https://sfconservancy.org/blog/2020/jan/06/copyleft-equality/ https://developercertificate.org https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/","s":"Further reading","u":"/community/license-considerations","h":"#further-reading","p":165},{"i":184,"t":"To protect our source code from unwanted changes, we enforce the following branch protection rules for all repositories within our GitHub organization: Require a pull request before merging into our default branch main. Require at least one approval before pull requests can be merged. Dismiss stale pull request approvals when new commits are pushed Require status checks to pass before merging Require branches to be up to date before merging Status checks that are required: DCO Do not allow bypassing the above settings The branch protection rules are rolled out by our github-manager to ensure that all repositories use a consistent set of rules. Should you intend to propose changes to the above rules, please open a pull request against orgs/SovereignCloudStack/data.yaml. Some repositories however do allow that the above rules are bypassed by the organization's owners, especially repositories that are used for public resources such as the website or the weekly digest.","s":"Branch Protection Rules","u":"/community/tools/github/branchprotection","h":"","p":183},{"i":187,"t":"Are you tired of keeping track of planned changes or issues you scheduled for the future? Our Octo Reminder is here to safe you from unneeded cognitive load! The app configuration is stored in our .github repository. Using the bot is fairly simple: To schedule a reminder, simply comment with /remind-me [date] [message] on an issue or pull request. The bot will answer and mention you in the particular issue/pull request upon reaching the configured date. If you don't specify a time for the reminder, the bot will use 9:00 CET as default reminder time. The date and time can be anything that momentjs understands, e.g. an ISO 8601 string or a relative string such as tomorrow or next week.","s":"Octo Reminder - your friendly assistant","u":"/community/tools/github/tips-and-tricks","h":"#octo-reminder---your-friendly-assistant","p":185},{"i":189,"t":"This checklist is designed to simplify the planning of hackathons and meetups. All items are suggestions and optionally adaptable to the situation.","s":"Hackathon planning checklist","u":"/community/hackathons/checklist","h":"","p":188},{"i":191,"t":"Date Task - [ ] Clarify sponsorship - [ ] Clarify who is responsible for planning. Contact persons of the companies involved. These should then also be present at the hackathon. - [ ] Set a specific date. - [ ] Clarify responsibilities. - [ ] First advertising in form of advertising in meetings, LinkedIn post, mailing list or similar. - [ ] Clarify which advertising measures are required (see checklist advertising). - [ ] Determine venue. - [ ] Set the theme for the hackathon and apply it to the design.","s":"Checklist 6 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-6-months-before-hackathon","p":188},{"i":193,"t":"Topic Task - [ ] Social Media Create content plan. - [ ] Which accounts/people/companies have to be mentioned as well. - [ ] Which persons must agree to a publication. - [ ] Should hashtags be used, if yes which ones. - [ ] Newsletter Create content plan with possible content and frequency. - [ ] Website Content plan: Blogposts. - [ ] Info landing page. - [ ] Registration page. - [ ] Special newsletter or just regular. - [ ] Other placements Spread the word in meetings or at other events. - [ ] Media Should be changeable, specify target audience, language, sources. - [ ] Media suggestions Video, images, PDF, texts, merch, graphics. Everything should be planned in advance precisely date, type, releases, scope, size, etc. - [ ] Graphics Set design motto. - [ ] Key metrics Should the success be tracked by key metrics, if so which ones.","s":"Checklist advertising","u":"/community/hackathons/checklist","h":"#checklist-advertising","p":188},{"i":195,"t":"Date Task - [ ] Clarify if extra merch is desired and start looking for vendors. Order samples. - [ ] Discuss concrete advertising measures. - [ ] Check hotels (see checklist hotel).","s":"Checklist 5 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-5-months-before-hackathon","p":188},{"i":198,"t":"Availabilities in the period. Way from the hotel to the hackathon. Parking at the hotel. Way from train station to hotel. Checkin / Checkout times. Check barrier-free accessibility.","s":"Iportant things","u":"/community/hackathons/checklist","h":"#iportant-things","p":188},{"i":200,"t":"Bar in the hotel, for relaxed sitting together in the evening. Clarify whether employees from on site are also allowed in the bar. Clarify whether reservations must be made in the bar, if so, reserve for the evening before. Possibility of contingent reservation.","s":"Nice-to-have things","u":"/community/hackathons/checklist","h":"#nice-to-have-things","p":188},{"i":202,"t":"Date Task - [ ] Determine hotel final and make recommendation. Possibly reserve contingent if the hotel offers it. - [ ] Find the location for the evening before (see checklist for evening before location). - [ ] Start organizing venue. (See checklist rooms 1). - [ ] Roughly plan evening event (consider volume level and space available). - [ ] Promotional drumbeat. Social media, website, meetings, newsletter. - [ ] Order special merch. - [ ] Organize merch in general (see merch checklist). - [ ] Start collecting statements that need to be sent around. (Privacy statements, photo statements, data center statements, security statements). - [ ] Rough sequence of events to be able to plan more precisely at a later date.","s":"Checklist 4 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-4-months-before-hackathon","p":188},{"i":204,"t":"Volume level. Consider food possibilities. Enough space. Availability. If intermediate change from A to B, then plan and include firmly in the plan. If it is necessary to choose two locations because of food, drink, coziness, distance to the hotel: plan both, ask for and book them. Ask for flexibility in the reservation. If more people come as registered. Plan times. Price / performance ratio should fit. Way from the hotel to the evening before location.","s":"Checklist for evening before location","u":"/community/hackathons/checklist","h":"#checklist-for-evening-before-location","p":188},{"i":206,"t":"Space available (Enough space available for: Work area, meet-up area, no-photo area, break room, restrooms?). Provisional room plan. How long are the rooms available? Are there any legal/corporate issues to consider? Do declarations need to be signed to enter the premises? List what hackathon relevant equipment is on site and if anything needs to be organized. For example, screens, whiteboards, power sockets if necessary, tables, chairs, wi-fi, etc.","s":"Checklist rooms 1","u":"/community/hackathons/checklist","h":"#checklist-rooms-1","p":188},{"i":208,"t":"Ballpens Lanyards Notepads Stickers ID card / name badge covers Name badges Snacks","s":"Checklist merch (examples)","u":"/community/hackathons/checklist","h":"#checklist-merch-examples","p":188},{"i":210,"t":"Date Task - [ ] Required declarations (photo/video usage rights, data center, premises, etc.) are available as a form. Have a look if you can have them confirmed with the registration. Otherwise as a circular email to all who register with the registration confirmation. Well visible. For the photo/video declaration: Give the option of refusing and explain the variant with the no-photo dot. - [ ] Promote again: Website, social media, newsletter, meetings, circular email, etc.... - [ ] Make reservations for pre-evening event. - [ ] Plan evening event and reserve location / tables (see checklist evening event). - [ ] Create a provisional schedule. - [ ] Eventually invite people separately. (Special guests). - [ ] Schedule start time and arrival time. Allow enough time for everyone to arrive. - [ ] Set presentation time and end time. - [ ] Define arrival time evening event. Leave enough time to change, but also do not define too long. - [ ] Schedule a fixed cleanup time. - [ ] Plan break time. - [ ] Activate login page.","s":"Checklist 3 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-3-months-before-hackathon","p":188},{"i":212,"t":"Volume level (It should be possible to have relaxed conversations) Available space Price / performance ratio should be suitable Check availabilities Snacks should be possible Request flexibility with reservation (number of participants) Actions would be a nice-to-have, everyone has been sitting and working all day, so it's good to have a change. Way from the hotel to the evening location.","s":"Checklist evening event","u":"/community/hackathons/checklist","h":"#checklist-evening-event","p":188},{"i":214,"t":"Date Task - [ ] Start collecting goals and topics. - [ ] Work out goals and topics yourself. - [ ] Check results from the checklist rooms 1 again. - [ ] Go through checklist rooms 2. - [ ] Advertising (social media, mailing list, website, blog post, newsletter, room plan video, etc). - [ ] Go through checklists again in general, was anything forgotten? - [ ] Plan food for the break. - [ ] Plan snacks / breakfast (See snacks checklist).","s":"Checklist 2 months before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-2-months-before-hackathon","p":188},{"i":217,"t":"Sandwiches (rolls) Pretzel sandwiches Sandwiches (toast) Cocktail tomatoes","s":"Breakfast examples","u":"/community/hackathons/checklist","h":"#breakfast-examples","p":188},{"i":219,"t":"\"Kinder Schokobons\" \"Kinder Schokoriegel\" \"Kinder Duplo\" Hanuta Gummy bears Apples Bananas Nuts Grapes Dried fruits Salted sticks Salted pretzels","s":"Snack exemples","u":"/community/hackathons/checklist","h":"#snack-exemples","p":188},{"i":221,"t":"\"Katjes Fruchtgummi\" \"Katjes Lakritz\"","s":"Vegan snack examples","u":"/community/hackathons/checklist","h":"#vegan-snack-examples","p":188},{"i":223,"t":"Create a room plan for publication. In it, work areas, break areas, no-photo area, meet-up places should be clearly visible. Gladly also again as a video. If necessary route map. Is wifi available without any problems? Where will drinks be located? Where to set up snacks? Where the food for the break? Are there enough plates, cups, glasses, cutlery, napkins, and bowls for snacks?","s":"Checklist rooms 2","u":"/community/hackathons/checklist","h":"#checklist-rooms-2","p":188},{"i":225,"t":"Date Task - [ ] Fix and publish the agenda. - [ ] Check the declarations once again, has every declaration been send, have any answered yet? - [ ] Check reservations, expand if necessary. - [ ] Check whether all possible special features have been observed (location etc). - [ ] Pre-order food for in-between meals and for the lunch break. - [ ] Plan drinks, type and quantity (don't forget coffee, tea, milk, sugar).","s":"Checklist 1 month before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-1-month-before-hackathon","p":188},{"i":227,"t":"Date Task - [ ] Print statements and forms. - [ ] Advertise again. - [ ] Make a list for the snacks (See for inspiration checklist snacks). - [ ] Pre-order the food, if necessary, check whether the quantity still fits with the registrations. Depending on expand. Firmly plan transport / pickup / delivery. - [ ] Create a room plan with the topics, where, when, what takes place. - [ ] Organize drinks. - [ ] Determine the time when the helpers / organizers meet. - [ ] If necessary create / organize lists and visitor cards.","s":"Checklist 1 week before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-1-week-before-hackathon","p":188},{"i":229,"t":"Date Task - [ ] Buy snacks. - [ ] Contact food supplier again if the delivery date is suitable. - [ ] Check technology for functionality. - [ ] Send around the room plan with the topics by email. - [ ] Prepare rooms if necessary / possible. - [ ] Put drinks in the refrigerator. - [ ] Provide coffee machine. - [ ] Provide dishes. - [ ] Label rooms. - [ ] Check visitor cards and lists for completeness.","s":"Checklist one day before Hackathon","u":"/community/hackathons/checklist","h":"#checklist-one-day-before-hackathon","p":188},{"i":231,"t":"Time Task - [ ] Place snacks on the tables in small bowls or similar. - [ ] Distribute merchandise. - [ ] Have declarations and forms ready for late deciders. - [ ] Have lists and visitor cards ready if necessary. - [ ] Check drinks in an interval. - [ ] Make coffee if necessary. - [ ] Provide tea, coffee, milk, sugar. - [ ] Provide breakfast / snacks. - [ ] Pick up lunch. - [ ] Lunch \"build up\" - [ ] Cleanup - [ ] Keep an eye on the process (keep times a little bit). - [ ] See if everyone feels picked up, no one is bored. - [ ] Makes Photos.","s":"Checklist Hackathon Day X","u":"/community/hackathons/checklist","h":"#checklist-hackathon-day-x","p":188},{"i":233,"t":"Date Task - [ ] Collect photos and provide them in a link for review and approval. - [ ] Create and send feedback sheet. - [ ] Create Blog Post Article. - [ ] Eventually create retro video. - [ ] Create social media posts. (After all approvals). - [ ] Prepare debriefing. - [ ] Summarize and process feedback.","s":"Checklist after Hackathon","u":"/community/hackathons/checklist","h":"#checklist-after-hackathon","p":188},{"i":235,"t":"Sovereign Cloud Stack (SCS) offers more than just a software stack — it's the embodiment of a collaborative open-source spirit, united by the aim of achieving digital sovereignty. At the heart of this initiative is a foundational pillar: the community. Open Source technology has become increasingly mature. However, the greatest software is useless if it cannot be developed and operated with full confidence. For this to happen, it is imperative that skills and knowledge be built up, fostered, and retained. In an increasingly competitive market for skilled people and complex IT systems, this is becoming an ever greater challenge for governments, institutions, and companies. How can we operate digital offerings in a self-determined, secure, and excellent manner? The answer to this must be the collectivization of operational knowledge, just as it has been practiced for many years with software development. In essence, the community is the core of the Sovereign Cloud Stack. It not only propels its evolution but also ensures its relevance, reliability, and resilience in an ever-evolving digital landscape. Read our open operations manifesto or join our Community either by joining our team meetings or by joining our matrix channel. Check out the different meetings and working topics within our team and SIG introductions.","s":"Mission Statement","u":"/community/mission-statement","h":"","p":234},{"i":238,"t":"For us as a community, the \"Four Open\" are more than a philosophy; rather, we see them as fundamental values that are essential for working collaborativly. The Four Opens give us the frame to develop SCS as a community that can be considered an important cornerstone tomorrow. We can also contribute to future developments and play an active role in shaping them.","s":"4+1 Open","u":"/community/mission-statement","h":"#41-open","p":234},{"i":240,"t":"Open Source: source code - open software that can be modified without restriction, on the condition that it is not limited in functionality or performance Open Design: the open process for designing the software Open Development: the opportunity to participate in the transparent development process on an equal footing Open Community: an equal community where everyone can be heard","s":"The 'Four Open\"","u":"/community/mission-statement","h":"#the-four-open","p":234},{"i":242,"t":"For us, the 5th Open is the Open Operation. At its core, the manifesto encompasses the collective, transparent exchange of knowledge. It describes the way to encourage everyone - regardless of their level of knowledge - to contribute to the community. The 5th Open has the principle that we can only learn from mistakes and therefore has an open and friendly mistake tolerance. Our SCS '5-Open' community is just as open as described above - join us and leave your mark on the technologies of tomorrow. Join our Open Operations Meetup.","s":"+1 Open","u":"/community/mission-statement","h":"#1-open","p":234},{"i":245,"t":"Sovereign Cloud Stack (SCS) is a network of organizations and individuals: providers, integrators, contributors, users, developers, operators, and associates of standardized sovereign cloud infrastructure. We join forces in defining, implementing and operating a fully open, federated, compatible, interoperable cloud infrastructure and platform. We are committed to \"The Four Opens\" of the Open Infrastructure Foundation and align our actions according to these four non-negotiable core principles of open collaboration. To include the whole DevOps approach we added the fifth open: Open Operations. We do believe that an open and welcoming environment is essential for an active and engaged community. As contributors and maintainers we pledge to make participation in our project and our community a harassment-free experience for everyone. No list is ever exhaustive, so we encourage members of the SCS community to adhere to the spirit, rather than the letter, of this code, as that is how it will be enforced. Places where this code may be particularly applicable are GitHub issues and pull requests, chat, mailing lists, team meetings, discussions on social networks broadly directed at or between members of the community, and other direct interactions within the community. Violations may lead to verbal or even public warnings or - especially in case of continued or flagrant offenses - may affect an individual's (or organization's) ability to participate within the SCS community. We encourage you to confront someone or a group of people that you observe to be in violation of the CoC (whether in letter or in spirit) with your observation, so that the person(s) can correct his/her/their behavior. If this is not successful or it is difficult for you to confront the people and you seek support for this, you may contact the SCS project lead at project-lead(at)lists.scs.community A large fraction of SCS consists of contributions to upstream projects. All SCS contributors are expected to adhere to the respective upstream Codes of Conduct when interacting with such projects, or developing code intended for upstreaming.","s":"Sovereign Cloud Stack Community","u":"/community/mission-statement","h":"#sovereign-cloud-stack-community","p":234},{"i":247,"t":"We ask you to please adhere to the following basic rules: Be friendly and patient. We were all new or lacked knowledge at various points in time. Please try to remember what it felt like to be on that end, and treat people accordingly. Use welcoming and inclusive language. We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, organization, color, immigration status, social and economic status, educational level, level of experience, sex characteristics, gender identity and expression, sexual orientation, gender identity and expression, age, body size and personal appearance, disability, family status, political belief, religion, and mental and physical ability. Be helpful. By helping others to learn our entire ecosystem is enriched. We encourage members of the SCS community to mentor each other and help to raise the general level of knowledge in the community whenever possible. Choose words that shows respect, empathy and promote constructive dialogue. We are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable. This includes, but is not limited to: Violent threats or language directed against another person. Discriminatory jokes and language. Posting sexually explicit or violent material. Posting (or threatening to post) other people's personally identifying information (\"doxing\"), regardless of whether it is publicly available. Personal insults, especially those using racist, sexist, or otherwise discriminatory terms. Deliberately referring to others by names or pronouns counter to their identity. Unwelcome sexual attention. Repeated harassment of others, e.g. not stopping behavior when someone asks you to stop. Advocating for, or encouraging, any of the above behavior. Be respectful, accept differing viewpoints and focus on what is best for the community. Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It's important to remember that a community where people feel uncomfortable or threatened is not a productive one. Members of the SCS community should be respectful when dealing with other members as well as with people outside the SCS community. When we disagree, try to understand why. Disagreements, both social and technical, happen all the time and SCS is no exception. It is important that we resolve disagreements and differing views constructively. Remember that we're different. The strength of SCS comes from its broad community, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn't mean that they're wrong. Don't forget that it is human to err and blaming each other doesn't get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes. Attribution​ This Code of Conduct is mainly adapted from the Asahi Linux Code of Conduct and the Contributor Covenant Code of Conduct.","s":"Our Standards","u":"/community/mission-statement","h":"#our-standards","p":234},{"i":249,"t":"We use a self-hosted Jitsi Meet instance for video conferencing. Thanks go to Cleura for providing the server for it. The server uses an automated deployment based on the heat-docker-jitsi-meet project. Configuration is such everyone who knows the room can connect, unless the moderator sets a password/PIN. Opening a new room requires authentication. (Contact Kurt if you need a password.) Links to the meeting room (as well as dial-in information) are in the appointments in the public calendar.","s":"Jitsi","u":"/community/tools/jitsi","h":"","p":248},{"i":251,"t":"Connect with a desktop browser (Chrome/Chromium or other blink based browser recommended due to superior WebRTC implementation with SimulCast/SVC for VP8/VP9 -- Safari & Firefox work, but cause higher data traffic). For mobile devices use the Jitsi Meet App. Use the little arrows in the control bar at the bottom to select speaker, microphone and camera in case you lack audio/video. Occasionally, you can not hear all but one participant; in this case reconnecting typically helps. We have an asterisk connected to some conference rooms to provide dial-in capabilities for folks that lack internet connectivity (but have a working phone connection).","s":"Usage","u":"/community/tools/jitsi","h":"#usage","p":248},{"i":253,"t":"The Developer Certificate of Origin (DCO) is a lightweight way for contributors to certify that they wrote or otherwise have the right to submit the code they are contributing to the Sovereign Cloud Stack. By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. All contributions to the Sovereign Cloud Stack are licensed under the (OSI approved) open source license of the upstream project being used therein (very often this is the Apache Software License v2). Where we create independent code, we prefer to use the GNU Affero General Public License 3, except for interface code which we would put under LGPL-3 (weak copyleft). Own documentation content is licensed under Creative Commons BY-SA 4.0. Contributors sign-off that they adhere to these requirements by adding a Signed-off-by line to commit messages. My fancy commit message Signed-off-by: Christian Berendt Git has a -s command line option to append this automatically to your commit message: git commit -s -m 'My fancy commit message' The status of a pull request is set to failed if commits do not contain a valid Signed-off-by line. Considerations behind the choice of AGPLv3, CC-BY-SA and the usage of the DCO can be found license-considerations.md.","s":"Developer Certificate of Origin + Licenses","u":"/community/tools/github/dco-and-licenses","h":"","p":252},{"i":255,"t":"https://developercertificate.org/ https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/ https://lwn.net/Articles/592503/","s":"Further reading","u":"/community/tools/github/dco-and-licenses","h":"#further-reading","p":252},{"i":257,"t":"We have created an open community space on the Matrix federation. Feel free to join the several channels and start chatting with our community. A good starting point is entering the General & Announcements and the Tech channel.","s":"Matrix","u":"/community/tools/matrix","h":"","p":256},{"i":259,"t":"To connect to the Matrix federation, you will need an account on a federated homeserver and a client. The easiest way to join us is register on the popular matrix.org homeserver via the Element web client: https://app.element.io/#/register. A list of curated Matrix clients is collected on the official Matrix website: https://matrix.org/clients/","s":"Client and Registration","u":"/community/tools/matrix","h":"#client-and-registration","p":256},{"i":261,"t":"We have an announcements mailing list there announce@lists.scs.community and you can subscribe via the mailman3 frontend also without the SCS nextcloud account if you prefer.","s":"Mailing Lists","u":"/community/tools/mailinglists","h":"","p":260},{"i":263,"t":"We have a Nextcloud instance for sharing files, doing polls, ... setup for things that are not public. You can contribute to SCS via the github workflows, asking questions there (via opening issues against the issues repository), submitting pull requests, ... If you want to contribute on a regular basis, we are happy to also onboard you to the nextcloud and do an onboarding call. Nextcloud onboarding also adds you to the scs-member@lists.scs.community mailing list which also add you to the announcement list (described in the next paragraph).","s":"Nextcloud","u":"/community/tools/nextcloud","h":"","p":262},{"i":265,"t":"Welcome to the developer section of the contributor docs. Here you will find guidelines for the implementation of tooling such as the SCS conformance tests.","s":"Developer documentation","u":"/contributor-docs/development/","h":"","p":264},{"i":268,"t":"Since we are expecting a lot of pipelines beeing created and used GitHub actions won't keep up well. We also expect cross-repository and even cross-project dependencies. Therefore we decided to use Zuul as our main pipeline solution.","s":"Zuul CI/CD pipelines and project gating","u":"/community/tools/zuul","h":"#zuul-cicd-pipelines-and-project-gating","p":266},{"i":270,"t":"Make Zuul aware of your repository in this repo Create a file .zuul.yaml An example can be found here You can have a job section containing self-defined jobs which you need to write on your own You have to have a project section containing the default-branch name the merge-mode which should be used to auto-merge the jobs to run in each pipeline (gh_check, gh_gate, gh_post, gh_tag) these pipelines are triggered by events which can be looked up here some default jobs can be found here If you have self-defined jobs, you need to create a folder .playbooks this folder containers ansible playbooks which will be triggered","s":"How to make a repo use Zuul","u":"/community/tools/zuul","h":"#how-to-make-a-repo-use-zuul","p":266},{"i":272,"t":"Zuul does not take anything for granted. If you need to have something installed, you should install it via ansible. Our test-machines are basically pimped docker-containers, so we might run into issues some time. But for now, things work pretty good.","s":"General information about Zuul","u":"/community/tools/zuul","h":"#general-information-about-zuul","p":266},{"i":274,"t":"Welcome to the Contributor Docs. This section is primarily for SCS Contributors and will contain documentation regarding the Development and Architecture of the Sovereign Cloud Stack and its components. You will find documents, explanations and guides regarding the tooling necessary for the development of SCS. If you want to contribute you can reach out to us via our Matrix Channel.","s":"Documentation for SCS Contributors","u":"/contributor-docs/","h":"","p":273},{"i":276,"t":"SovereignCloudStack (SCS) uses conformance tests to certify compliance of a given cloud offering with respect to a given certificate scope such as SCS Compatible IaaS v4. Our aim is that these tests are reliable, consistent and comprehensible for the users. This document is a guideline for conformance test authors and summarizes the current best practices to achieve this goal.","s":"SCS Conformance Test Implementation Guide","u":"/contributor-docs/development/tests/test-implementation-guide","h":"","p":275},{"i":278,"t":"Test authors working on new and existing conformance tests for an SCS standard must implement the keywords such as MUST and SHOULD according to the SCS RFC2119 Keyword Test Guide.","s":"1. Mapping of RFC2119 Keywords","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#1-mapping-of-rfc2119-keywords","p":275},{"i":280,"t":"Test authors are strongly encouraged to include unit and regression tests for the conformance test's logic. Conformance tests will inevitably contain some non-trivial algorithms, be it for parsing flavor names or evaluating CVE vulnerability reports. Testing them automatically and regularly against valid and invalid inputs helps test authors to find programming mistakes early on. As a bonus, a well written unit test also makes it easier for reviewers to cross check a given pull request with new, enhanced or refactored conformance tests. In general, unit and regression tests for the conformance tests are located in the same location as the conformance tests, that is, the Tests/ directory of the SCS standards repository. Setup and development of the unit tests is described in the SCS conformance tests README.","s":"2. Unit and Regression Tests","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#2-unit-and-regression-tests","p":275},{"i":282,"t":"Any module that ends in _test will be picked up as a unit test module by pytest in our CI pipeline (in other words, all files matched by the pattern Tests/**/*_test.py). Pytest will execute any function prefixed with test_ as a test function, or, alternatively, tests based on the unittest module from the Python standard library. Follow these naming rules: The name of a unit test module is constructed from the module to be unit tested and the _test suffix. For example, unit tests for flavor_names.py should reside in flavor_names_test.py. The name of a Python module in general should be a valid Python identifier, to allow imports via the import statement. For example, use flavor_names.py instead of flavor-names.py.","s":"Naming Conventions","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#naming-conventions","p":275},{"i":284,"t":"Software design fills complete book shelves and this section can only cover some basic best practices. As a general rule of thumb, the earlier you begin writing unit tests, the better – it will force you to write modules that are easy to test. Divide conformance tests scripts into smaller, loosely coupled units, i.e., functions that serve one purpose each. Use the dependency injection technique, i.e., pass externally retrieved data as function arguments instead of hardcoding the calls to the retrieval functions inside a function. Avoid logging calls deep down in the call hierarchy and use explicit return values or raise exceptions, instead. Here is an abstract example of a conformance test which does exactly that: # property_compliance.py def retrieve(location): \"\"\"Retrieve raw data via network.\"\"\" ... def parse(data): \"\"\"Parse raw data and return a dict.\"\"\" ... def handle(...): \"\"\"Evaluate parsed data.\"\"\" ... def main(args): ... data = retrieve(location) parsed = parse(data) result = handle(parsed) ... if result.some_prop != expected_value: logging.warn(\"some_prop is not as expected: %s (vs. %s)\", result.some_prop, expected_value) ... return result.success if __name__ == \"__main__\": # using sys.exit(…) only here makes it possible to unit test main(…) sys.exit(main(sys.argv)) Adhering to this style makes it easier to test an algorithm in isolation, without actually making a call to some external service.","s":"Write Testable Conformance Tests","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#write-testable-conformance-tests","p":275},{"i":286,"t":"Assuming we want to unit test some members of the module property_compliance from the previous section, we would create a file property_compliance_test.py with the following content as a starting point: \"\"\"Unit tests for property_compliance. (c) Your Name , 4/2024 SPDX-License-Identifier: CC-BY-SA-4.0 \"\"\" import pytest from property_compliance import parse def test_success(): assert parse(\"some valid input\") == \"expected output\" def test_failure(): with pytest.raises(ValueError): parse(\"invalid input\")","s":"Pytest Test Example","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#pytest-test-example","p":275},{"i":288,"t":"Conformance tests are expected to be executable without admin privileges (see §2 of Regulations for achieving SCS-compatible certification). In particular, this means: The cloud credentials (e.g., kubeconfig and OpenStack clouds.yaml) passed to the scripts are non-admin credentials. Conformance tests scripts should not require root privileges, except for the installation of operating system prerequisites (e.g., a Python interpreter).","s":"3. Conformance Tests Shouldn't Require Admin Privileges","u":"/contributor-docs/development/tests/test-implementation-guide","h":"#3-conformance-tests-shouldnt-require-admin-privileges","p":275},{"i":290,"t":"SovereignCloudStack wants to make it possible for operators to delegate administration of user identities to the organizational entities that the users are part of. Usually that's customer organizations but it could also be the operator itself. Federation protocols like OpenID Connect can be used to achieve that goal. To simplify connecting the different parts of SCS to customer owned IAM solutions, SCS deploys Keycloak as central Identity Provider (IdP) service. Currently this is deployed automatically only in the osism/testbed, which provides its own documentation for authentication with OIDC. The following sections describe how this is done.","s":"Identity Federation in SCS","u":"/contributor-docs/operations/iam/identity-federation-in-scs","h":"","p":289},{"i":292,"t":"To provide Infrastrucure as a Service SCS builds upon OpenStack. See section OpenStack Federation via OpenID-Connect for more details on identity federation for OpenStack.","s":"1. IaaS / OpenStack","u":"/contributor-docs/operations/iam/identity-federation-in-scs","h":"#1-iaas--openstack","p":289},{"i":294,"t":"To provide Container as a Service SCS builds upon Kubernetes. There is work in progress to optionally connect Kubernetes to Keycloak and to map authorization decisions based on claims via cluster role bindings.","s":"2. CaaS","u":"/contributor-docs/operations/iam/identity-federation-in-scs","h":"#2-caas","p":289},{"i":296,"t":"Keystone supports federating authentication and authorization decisions via several mechanisms as documented by the project. In SCS OpenID Connect is used for federation between Keystone and the IdP, which is currently provided by Keycloak in SCS. The following sections describe the setup.","s":"OpenStack Federation via OpenID-Connect","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"","p":295},{"i":298,"t":"Keystone supports federated identities. To allow SCS to consume identities managed in external IAM solutions, federation protocols like OpenID Connect or SAML can be used. Keystone currently makes use of third party apache modules like mod_auth_openidc, mod_oauth2 and mod_auth_mellon to delegate authentication to a SSO IdP (i.e. SAML IdP or OpenID Connect provider). In OpenStack the apache modules are configured using the wsgi-keystone.conf template. In SCS we make use of the OAuth 2.0 Authorization Code Grant flow between Keystone and Keycloak and use PKCE (RFC 7636) with the S256 challenge method. In addition to the usual SSL CA of the environment, Keycloak uses separate certificates to sign the OIDC tokens. Due to the way the Keystone container image runs apache (in the foreground) and keystone itself (as WSGI module), reconfiguring the apache URL locations on the fly is not possible currently without a downtime of several seconds. That is the reason why SCS currently makes use of a single central proxy realm in Keycloak, to which Keystone connects.","s":"1. Keystone","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#1-keystone","p":295},{"i":300,"t":"Keycloak offers standard OIDC service discovery via .well-known documents to advertise its endpoints. In SCS we want to represent each customer by a separate dedicated Keycloak realm, which can enventually be used for customer self service and to federate out to customer owned IAM external solutions. In the SCS testbed we currently experiment with the implications of using a single central proxy realm in Keycloak and chaining federation from there to customer specific realms, also hosted in the same Keycloak instance. To make this usable, SCS makes use of the Keycloak Home IdP Discovery extension.","s":"1.1 Keycloak IdP realm discovery","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#11-keycloak-idp-realm-discovery","p":295},{"i":302,"t":"Upon login of a user Keystone evaluates the credentials obtained from the ID token that the IdP issued. These include group memberships and roles, which can be used to assign the user to a certain project. Keystone maps these external identities to internal (shadow) users. It can either attempt to map the obtained information to a local type user, which needs to be provisioned before authentication by external tooling, or it can be instructed via the mapping to generate an ephemeral type user. ephemeral users are cleaned up automatically after some time of inactivity and with that, they lose access to projects, iff the access is granted indirectly via group membership rather than directly to the user itself. Group memberships for ephemeral users are only represented via their tokens, but not stored in the Keystone backend database. After successful authorization Keystone issues an OpenStack specific fernet token to the user, which is the currency that is understood by other OpenStack services and can be used to access them. In SCS we want to represent each customer by a sepatate dedicated OpenStack domain to host their projects and (shadow) user accounts. The processing of information from the OIDC tokens is configured by two parts. The first part is the rules.json mapping which is described in the OpenStack federation mapping combinations document. This file is used to configure Keystones internal mapping engine and it needs to be attached to some OpenStack domain, which is named keycloak by default in SCS. The second (static) part is the [auth] and [mapped] sections in keystone.conf (see e.g. the overlays currently used in the OSISM testbed ).","s":"1.2 Keystone mapping of token claims","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#12-keystone-mapping-of-token-claims","p":295},{"i":304,"t":"The Horizon dashboard supports login via OpenID Connect via Keystone endpoint. SCS adjusted the logout behavior to invalidate both, the OpenID Connect session with the IdP and the Keystone token.","s":"1.3 Horizon WebSSO for federated users","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#13-horizon-websso-for-federated-users","p":295},{"i":306,"t":"To support OpenStack CLI and API access, SCS implemented support for the OIDC Device Authorization Grant in Keystone. On top we added support for PKCE (RFC 7636) in combination with that.","s":"1.4 OpenStack CLI and API access for federated users","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#14-openstack-cli-and-api-access-for-federated-users","p":295},{"i":308,"t":"To show the potential of this approach to federation SCS created a Howto for OIDC federation between SCS deployments.","s":"1.5 SSO Federation between to SCS deployments","u":"/contributor-docs/operations/iam/openstack-federation-via-oidc","h":"#15-sso-federation-between-to-scs-deployments","p":295},{"i":311,"t":"Repository is known by SCS Zuul Basic ansible knowledge Basic yaml knowledge zuul-client installed (Only if you want to create secrets. See also) Check SCS Zuul projects for your repository to be available. If it is missing you need an administrator to get your repository configured to Zuul.","s":"Prerequisites","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#prerequisites","p":309},{"i":313,"t":"You may have heard about Zuul and may ask yourself if it is capable to support you. Basically everything you use ansible for can be done using Zuul. That is not always a good thing since you may get careless and your workload will exceed the CI/CD concept. If you find yourself doing things under the following list you are at the right place. Code testing Deployment tests using IaC If you want to, let's say, monitor something using Zuul, that is possible but not the intended use case.","s":"Who is it for?","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#who-is-it-for","p":309},{"i":315,"t":"Right in your project's repository! The only prerequisite is that your repository you want Zuul to work on is known by Zuul. This is done by the Zuul's tenant configuration. To update this configuration you need access to the Zuul instance or ask an administrator for help. We assume that Zuul knows about your repository so we can get started. There are three topics that you should know about. To get jobs running you need the \"job\" itself. Jobs run within a \"pipeline\". The third important thing is to provide a \"project\" definition.","s":"Where do I start?","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#where-do-i-start","p":309},{"i":317,"t":"Zuul will parse all branches of the untrusted repositories that Zuul knows about. Your repository is most likely an untrusted one since only the configuration repositories should have the \"trusted\" state. So it doesn't matter whether you have just one branch containing Zuul files or all branches. Zuul is looking for the following pathes on your repositories root. ./zuul.yaml # everything is in here ./.zuul.yaml # ... or here ./zuul.d/ # use directory style to get a bit of a structure ├── jobs.yaml └── project.yaml ./.zuul.d/ # the same as before just hidden ├── jobs.yaml └── project.yaml Just use exactly one of the four possibilities. If using the directory style configuration all yaml files within this directory will be processed. If your projects configuration is small enough you may put all information in a single file called zuul.yaml. It is also possible to create the file or the directory with a leading dot to hide them for non zuul related work within the repository.","s":"Where to save the Zuul relevant data?","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#where-to-save-the-zuul-relevant-data","p":309},{"i":319,"t":"If Zuul is configured to observe your repository it will have a look at your projects definition. Minimal example: - project: name: my-org/my-repo default-branch: main merge-mode: \"squash-merge\" my_pipeline1: jobs: - my_job1 - my_job2 ...... my_pipeline2: jobs: - my_jobs ... By default Zuul will observe all branches for such files. We have to set the repository name that have to match the exact value that was set for Zuul. Set a default-branch where actions that don't match an explicit branch are executed on. Set the merge-mode that Zuul has to use. But beware that not all issue tracker support all methods. For github squash-merge will work. After these three properties add the pipelines you want to use to the project definition. With the jobs list you define which jobs to run in which pipeline. See official documentation","s":"Projects","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#projects","p":309},{"i":321,"t":"Every Zuul instance will have at least one repository that is used for configuration. There you will find the available pipelines. Pipelines are used to run your jobs on a periodic or event driven base. Pipelines can be used to run other pipelines and to keep your jobs in a defined order if you need this. Have a look at the configuration repository to utilize the pipelines for your repository. See available pipelines for SCS. You are not able to define new pipelines outside of a so called \"configuration\" repository. Since, by default your repo is considered \"untrusted\". So in the first place you don't need to think about, how to create a pipeline. Just use one that fits your needs as close as possible. Next you will find an enumeration and a small description about the available pipelines in SCS Zuul. Pipelines available in SCS Zuul: 1. check​ event driven pipeline runs if a pull request is created, changed or reopened re-runs if a comment contains recheck 2. gate​ event driven pipeline trigger events: pull_request_review, pull_request, check_run 3. post​ event driven pipeline trigger event: post 4. tag​ event driven pipeline trigger event: push 5. e2e-test​ event driven pipeline trigger event: pull_request 6. e2e-quick-test​ event driven pipeline trigger event: pull_request 7. unlabel-on-update-e2e-test​ event driven pipeline trigger event: pull_request 8. unlabel-on-update-e2e-quick-test​ event driven pipeline trigger event: pull_request 9. periodic-hourly​ time based pipeline that runs every hour 10. periodic-daily​ time based pipeline that runs every day at 3 o'clock am. 11. compliance_check​ time based pipeline that runs every 15 minutes If you want to know more about pipelines: See official documentation","s":"Pipelines","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#pipelines","p":309},{"i":323,"t":"The SCS Zuul instance can transmit build reports through an MQTT connection to the dedicated Matrix chat room SCS | Zuul Reports. Currently, this MQTT reporting feature is activated for periodic pipelines (periodic-hourly, periodic-daily, compliance_check), and reports are dispatched solely in the event of failures occurring in builds triggered by the mentioned pipelines. See an example pipeline that reports failed result to the SCS | Zuul Reports Matrix room: - pipeline: name: pipeline-that-reports-to-matrix description: | In the event of a failure, this pipeline transmits reports to the SCS | Zuul Reports Matrix chat room. failure: mqtt: topic: \"zuul/{pipeline}/{project}/{branch}/{change}\" Visit the official Zuul documentation and explore the configuration options available for Zuul's reporters.","s":"Reports","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#reports","p":309},{"i":325,"t":"All jobs that your Zuul instances knows of can be used for your own purposes. Call them directly or implement a job that uses an existing job as parent. Didn't find the right job? Than we have to create a new one. Existing jobs can be found in the web ui of your Zuul instance: Example First have a look on a basic job example: - job: name: base parent: null description: | The recommended base job. All jobs ultimately inherit from this. It runs a pre-playbook which copies all of the job's prepared git repos on to all of the nodes in the nodeset. It also sets a default timeout value (which may be overidden). pre-run: playbooks/base/pre.yaml post-run: - playbooks/base/post.yaml - playbooks/base/post-logs.yaml roles: - zuul: zuul/zuul-jobs timeout: 1800 nodeset: nodes: - name: ubuntu-jammy label: ubuntu-jammy Each job needs a name that has to be unique within the whole tenant. A useful convention to achieve this is to prepend the name of the repository. Each job need to define whether there is parent job or not. Jobs without a parent are called \"base\" jobs. Usually you don't want to implement base jobs since there are already some base jobs that implement often used stuff. A description may not be mandatory but is obviously useful. Necessary for Zuul to do anything you just need to add a run or roles property. Within a job that is like a noop job or just printing something to stdout that is everything you need to run your first job. Since anything we want to do requires a little bit more you have to define a nodeset. The nodes are used to run your playbooks on. In 99,9% you will need this too. The properties pre-run and post-run are useful for bootstrap and cleanup. If your actual job wants to create bootstrap some infrastructure you can to this in the pre-run. Using an cloud provider you want to release no longer used resources. That can be done in the post-run. If you are using a parent job it is likely that the parent job may has pre- and post-run playbooks. In this case your pre- and post-run playbooks are \"nested\". Example: pre-run parent pre-run my job post-run my job post-run parent If your job exceeds the defined timeout, the job is considered as failed. See official documentation What about secrets?​ Right now you should be able to run basic tasks. But what if you try to test something that needs credentials to connect to an outside service? Or you have to address additional ressources in an openstack environment and you have to use something like app credentials? That is where job secrets are used. Example: - job: name: SOME_JOB parent: base description: | A job basic job used as example secrets: - name: clouds_conf secret: app_credential_cloud_conf run: playbooks/my-playbook.yaml Secrets for a job are simply defined by the keyword secrets. Each secret needs a name that can be used in your playbooks. The property secret references the secret that is defined within your project. ATTENTION! If your job is using a secret job.post-review is automatically set to true. For untrusted projects, that means that your job is only called in piplines that have the pipeline.post-review flag set to true. In SCS context that means you may run these jobs only with the pipelines tag and post. If you want to run jobs on pipelines that have post-review set to false, which is default, and your job needs a secret, the secret may be defined in the zuul-config repository. Example: - secret: name: app_credential_cloud_conf data: credentials: my-secret-value Within my-playbook.yaml you can reference the secret value using \"{{ clouds_conf.credentials }}\". In this example my-secret-value is clear readable text. That is not something we want to keep secrets. But how do you encrypt secrets in a way that they are secure and also can be decrypted by Zuul? For this purpose Zuul creates its own public/private key pair for each project. Everyone may use the public key to create secrets. But only Zuul will be able to decrypt these values. To avoid the user to be responsible for the correct encryption there is an zuul-client tool that will do this for you. Example (reading from stdin and writing to stdout): zuul-client --zuul-url ZUUL_URL encrypt --tenant SCS --project SovereignCloudStack/REPO Add --infile INFILE or --outfile OUTFILE if you prefer to work with files directly. The output might look like this: - secret: name: data: : !encrypted/pkcs1-oaep - IGZ2Wu47R9mEY4fjetbxSAUGNaz4HR1mjk9lCLq3HsUMjHGj9YPlb2MvnPQw1LCJSvpaK ogth7hi2zYwrs5tNAik/qlVSB7AM+LQRP7lmlM4JmD6WOyR7DisHu7oMD1Gqem2ZuMggA DIBn5+DeBIvnwihDOcS+BKPTVMEtXOJNkuObZHE8DweB/RQIGUvjyeq5yoAmz/y+qGVqe 0Vk4pTYFIBgk5DMzwVnDzDkqs/QokoOupMUoBcpapmM11do4ymjbDpeINjayoro6VXTtX Mkk9fDv9wuJIQTuyHAOfMD+UYS/HqVSF/Hm9ScUvfhw02gTdzKCxliWhFHJOj7RbdUUMK OYYcUkNp5cXZUYFnflMhxVEnzREbdAIklNPfoHOizsxLPaUZ9yk6XcFRflFfMvqBtUS00 LCx0Uh906NwdaEUrv2ZdrN123rwfwfw4333232rDFDFfsdfddsfdDFSFSdqrrtwms5Mi0 szUBaM4j+Mayep+41vl0cpsLU91GzXEATWMaPIN8OnEHF6qQIv0wB6VaKd5aeAyERisb3 wFdjEo4faLO70RWzR33k+4xqAYNIIFyTMpWJz21CUSfoYG8ygL6t7RJGgyjA+0KsVEyj+ ewEtiaUOLYyD7pXtqdw1HgzjqiXnfxk+wSv/y5y/TGGYpQj8zU76jS7Zj0ft/0= You may use this content or the file to provide it as a secret. You just have to update the and the part. The secret name has to be unique across all projects. Because of this, we have a naming convention in the SovereignCloudStack organisation that ensures that a secret has a unique name. Our convention is as follows. There is only one secret per Zuul configuration per project (for exceptions, see below). This secret always has a name in the form SECRET_REPOSITORY_NAME. For instance, if a secret in the SovereignCloudStack/k8s-cluster-api-provider repository is to be used, it is given the name SECRET_K8S_CLUSTER_API_PROVIDER. The name of the repository is always written in capital letters. A dash is replaced with an underscore. Any number of values (: !encrypted/pkcs1-oaep) can then be assigned to this one secret. In certain cases, it can be undesireable to expose all secret information to all jobs in a project. Then additional secrets may be used, whose names have to be formed by appending an underscore and some upper-case prefix to the name of the primary secret. For instance, we might use the name SECRET_REPOSITORY_NAME_FOOBAR. Official documentation: Secrets documentation Encryption documentation Let's put it all together​ For a basic but working example the following content may be written into a zuul.yaml file. # zuul.yaml content --- - secret: name: SECRET_REPOSITORY_NAME data: secretValue1: !encrypted/pkcs1-oaep - secretValue2: !encrypted/pkcs1-oaep - secretValue3: !encrypted/pkcs1-oaep - - job: name: myFirstTestJob parent: base secrets: - name: secretName # The name of the secret that is used within \"playbooks/testPlaybook.yaml\" secret: SECRET_REPOSITORY_NAME run: playbooks/testPlaybook.yaml - job: name: mySecondTestJob parent: base run: playbooks/testPlaybookTwo.yaml - project: tag: jobs: - myFirstTestJob check: jobs: - mySecondTestJob This will run the job myFirstTestJob whenever the tag pipeline is triggered, and mySecondTestJob whenever check is triggered. Within SCS the check pipeline is always triggered if you open, change or reopen a pull request. This pipeline can also be triggered manually if you write a comment on an already existing pull request and place the string recheck in it. Recall that the first test job cannot run on the same pipeline because it uses a secret. The tag pipeline is run whenever a new tag is created. The path to you playbook is always the full path within the repository. The playbook contains the tasks you actually want to run on all or a specific subset of nodes. Example playbook: # playbooks/testPlaybook.yaml content --- - hosts: all tasks: - debug: msg: 'Debug print my secrets! {{ secretName.secretValue1 }}' # do not do this as it will expose your secrets","s":"Jobs","u":"/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guide","h":"#jobs","p":309},{"i":327,"t":"The container layer within the Sovereign Cloud Stack (SCS) offers a robust solution for managing container workloads on a Kubernetes infrastructure. It facilitates the on-demand creation and scaling of Kubernetes clusters, catering to various needs across development, testing, deployment, and operation of services and applications. While the container layer is versatile for a range of use cases, the most common ones include: Self-Service: Here, entities can empower their development teams with the autonomy to spawn and manage their clusters on demand, fostering a more agile and responsive development environment. KaaS (Kubernetes as a Service): In this model, an SCS Cloud provider can offer their customers a managed Kubernetes service, abstracting much of the underlying operational complexity from their customers.","s":"Container Layer Introduction","u":"/docs/container/","h":"","p":326},{"i":329,"t":"DevOps/SysOps Teams: They are the primary beneficiaries as the container layer promotes flexible, on-demand operations helpful for continuous development, testing, deployment, and service management. Cloud Service Providers: By delivering a standardized container orchestration platform, they can provide more reliable and robust services to their customers, enhancing their product portfolio.","s":"Target groups","u":"/docs/container/","h":"#target-groups","p":326},{"i":331,"t":"The container layer is not an alternative to Infrastructure as a Service (IaaS) but rather an extension that allows for more streamlined operation and management of containerized applications. Although the container layer doesn't directly support Serverless Containers or Functions as a Service, these can be run on a Kubernetes cluster. However, as of now, the SCS container layer doesn't offer specialized tools for these use cases.","s":"What is it not","u":"/docs/container/","h":"#what-is-it-not","p":326},{"i":333,"t":"Knowledge: Familiarity with Kubernetes, container orchestration, and basic cloud infrastructure principles is pivotal. Software: The core software component is the K8s Cluster API Provider, crafted to function optimally on OpenStack environments. Although designed to run on the SCS IaaS layer, with minor configuration adjustments, it can operate on any OpenStack environment. Hardware: Virtualization-enabled hardware capable of running OpenStack is essential if hosting the IaaS layer independently. For further details, refer to the IaaS layer documentation.","s":"Prerequisites and Requirements","u":"/docs/container/","h":"#prerequisites-and-requirements","p":326},{"i":335,"t":"Automated Cluster Management: The K8s Cluster API Provider automates the process of creating, scaling, managing and updating Kubernetes clusters, thus significantly reducing the operational overhead. Standardized Operations: Upholding SCS standards across various clusters ensures operational consistency and reliability. Integration with OpenStack: The K8s Cluster API Provider is tailored to work seamlessly with SCS IaaS (OpenStack), thus offering a unified platform for managing both containers and the underlying infrastructure. Container Registry Integration: The container layer has an integrated container registry, facilitating easy management and deployment of container images. Certificate Managment: The kubernetes clusters can optionaly include a certbot allowing for ease of deployment of public facing services out of the box. Preconfigured ingress: Certificate Management: Optional inclusion of Certbot in Kubernetes clusters facilitates straightforward deployment of publicly accessible services. Preconfigured Ingress: Kubernetes clusters come with a preconfigured Nginx ingress, designed with OpenStack in mind, providing a ready-to-use ingress solution with enhancements like out-of-the-box client source IP visibility.","s":"Features","u":"/docs/container/","h":"#features","p":326},{"i":337,"t":"OpenStack Dependency: The current design primarily supports OpenStack environments, which could be a limitation for other infrastructure setups. Serverless/Functions as a Service Support: Lack of direct support for serverless containers and Functions as a Service (FaaS) might require additional tools or platforms.","s":"Limitations","u":"/docs/container/","h":"#limitations","p":326},{"i":339,"t":"The container layer has matured with multiple cloud providers now offering Kubernetes as a Service using this layer to manage a multitude of clusters. It follows a half-yearly release schedule to ensure security and up-to-date Kubernetes clusters, alongside providing backports for significant features into older versions. Looking ahead, a new version based on ClusterStacks is in the pipeline, currently in its Alpha state. This upcoming release aims to be backward compatible, facilitating smooth migration from existing setups, and further extending the capabilities of the SCS container layer.","s":"Current state and future Outlook","u":"/docs/container/","h":"#current-state-and-future-outlook","p":326},{"i":342,"t":"The Sovereign Cloud Stack combines the best of Cloud Computing in one unified standard. SCS is built, backed, and operated by an active open-source community worldwide.","s":"About","u":"/docs/","h":"#about","p":340},{"i":344,"t":"SCS Component Map Ops Layer Status Page Monitoring Central API Automated Pentesting Container Layer KaaS V1: K8s Cluster API Provider KaaS V2: Cluster Stacks Container Registry IaaS Layer Image Manager Flavor Manager IAM Layer Keycloak","s":"Architectural Overview","u":"/docs/","h":"#architectural-overview","p":340},{"i":347,"t":"Quick Start with Cloud-In-A-Box​ The fastest way to get in touch with SCS is to deploy a SCS cloud virtually. The Cloud-In-A-Box was built explicitly for this scenario. Check it out here Reference Implementation Testbed​ This means that you set up an SCS test installation including all the infrastructure pieces such as database, message queueing, ceph, monitoring and logging, IAM, the OpenStack core services, and (soon) the Container layer on top of an existing IaaS platform. The SCS IaaS reference implementation is based on OSISM. Read on the OSISM testbed docs to learn how to get the testbed running. Please read carefully through the deployment section of the manual.","s":"IaaS Layer","u":"/docs/","h":"#iaas-layer","p":340},{"i":349,"t":"K8s Cluster API Provider​ You can easily deploy the container layer on top of the testbed (or a production SCS cloud) checking out the code from k8s-cluster-api-provider. Cluster Stacks​ With the Cluster Stacks, in the V2 KaaS reference implementation, we provide an opinionated optimized configuration of Kubernetes clusters. Through better packaging, integrated testing, and bundled configuration, SCS-based Kubernetes clusters provide easier individualization. Throughout the R6 development cycle Cluster Stacks are taken from a technical preview to be functional and available on top of the IaaS reference implementation as well to replace the V1 KaaS reference implementation k8s-cluster-api-provider. The Cluster Stacks can already be tried with the demo repository. Although this is based on the not-production-ready Docker provider, the usage is the same for every provider.","s":"Container Layer","u":"/docs/","h":"#container-layer","p":340},{"i":351,"t":"Find the current list of scs compatible clouds here.","s":"Public SCS Clouds in production","u":"/docs/","h":"#public-scs-clouds-in-production","p":340},{"i":353,"t":"While the SCS project tracks the efforts across the released epics and user stories, the work on the code, whenever possible, happens upstream. As such, these repositories are usually not found in the SCS GitHub organization. SCS works directly in the following upstream projects: CNCF projects, OpenStack, kolla-ansible, OSISM and others. All code not pushed upstream can be found in the SCS Github organization.","s":"Development of SCS","u":"/docs/","h":"#development-of-scs","p":340},{"i":355,"t":"If you can identify the affected component, raise the issue against the relevant repository in the SovereignCloudStack or OSISM space. Otherwise, you can use the issues repository. We appreciate PRs as well as issues; please don't forget to sign off your contributions see contributor guide.","s":"Issues and Bugs","u":"/docs/","h":"#issues-and-bugs","p":340},{"i":357,"t":"Please see the SCS contributor guide.","s":"Contribute and Connect","u":"/docs/","h":"#contribute-and-connect","p":340},{"i":359,"t":"See our Release Notes here","s":"Releases and Roadmap","u":"/docs/","h":"#releases-and-roadmap","p":340},{"i":361,"t":"How to get compliant? What do I need to be compliant? What are the benefits? What does it involve? What to expect in the future? Learn more in the standards section.","s":"Standards, Conformity and Certification","u":"/docs/","h":"#standards-conformity-and-certification","p":340},{"i":363,"t":"The Cluster Stack Provider OpenStack (CSPO) works with the Cluster Stack Operator (CSO) and Cluster Stacks, enabling the creation of Kubernetes clusters in a Cluster-API-native (CAPI) fashion. The primary goal of the CSPO is to facilitate the import of node images in a manner specific to OpenStack. These images are then used to create Kubernetes workload clusters on top of the OpenStack infrastructure. To gain a comprehensive understanding of the entire concept, we recommend familiarizing yourself with the fundamental concepts and architecture outlined in CSO and Cluster Stacks.","s":"Overview","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overview","h":"","p":362},{"i":366,"t":"The development and validation of tests within the Sovereign Cloud Stack (SCS) is a critical endeavor aimed at ensuring that cloud technologies meet the highest standards of interoperability, security and sovereignty. This process is not only about aligning with the technical specifications and standards set by SCS but also about safeguarding the principles of open-source collaboration and the autonomy of cloud services. By thoroughly crafting tests that adhere to the stringent requirement levels as indicated by RFC2119 keywords, we ensure that the infrastructure, services and their integrations within the SCS ecosystem are robust, secure and sovereign. This detailed process is crucial for stakeholders seeking to develop or utilize sovereign cloud services that are reliable, compliant and capable of standing up to the demands of modern cloud computing. It serves as an indispensable guide for developers, operators and policymakers who are involved in the creation, deployment and governance of cloud services within SCS. By understanding and implementing the standards and tests defined by the SCS, professionals can contribute to a cloud infrastructure that is not only technologically advanced but also aligns with the core values of sovereignty and open-source ethics. Therefore, for individuals tasked with writing tests and defining standards within SCS, this document is particularly important. It serves as a base with guidelines on how to use and understand RFC2119 keywords in the context of SCS. Its insights are crucial for anyone from technical architects to regulatory bodies within the SCS ecosystem, underlining the foundational principles necessary for achieving a sovereign cloud environment.","s":"Introduction","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#introduction","p":364},{"i":368,"t":"SCS standards use RFC2119 keywords like: MUST (same as REQUIRED, SHALL), MUST NOT (same as SHALL NOT), SHOULD (same as RECOMMENDED), SHOULD NOT (same as NOT RECOMMENDED), MAY (same as OPTIONAL) to define requirements for SCS-compatible IaaS and KaaS resources. These standards & tests are crucial for ensuring interoperability and sovereignty in cloud services, as they are built on open-source components such as Kubernetes and OpenStack. To ensure readability and comprehensibility, only the main keywords MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are referred to below.","s":"1. Understanding SCS Standards and RFC2119 Keywords","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#1-understanding-scs-standards-and-rfc2119-keywords","p":364},{"i":370,"t":"MUST and MUST NOT: These are binary and straightforward to test. Compliance or non-compliance directly affects whether the standard is satisfied. For visualization, fulfilled requirements could be marked in green, unfulfilled ones in red. SHOULD and SHOULD NOT: These represent recommendations. While fulfilling these do not directly affect standard compliance, it is advised for future-proofing against potential standard evolutions. Non-compliance could be visualized in yellow, possibly with a valid reason for non-fulfillment. MAY: This is more flexible and could be used to provide additional information or best practices. Their impact on compliance is not as direct as MUST or SHOULD categories. These can be marked as blue.","s":"2. Interpreting RFC2119 Keywords in the Context of SCS","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#2-interpreting-rfc2119-keywords-in-the-context-of-scs","p":364},{"i":372,"t":"In test scripts, different channels are used to convey information of different importance to the user. These channels are based on the ubiquitous and de-facto standard logging levels of common logging libraries in scripting and programming languages, in particular Python: DEBUG, INFO, WARNING, ERROR and CRITICAL. Alignment of the RFC2119 keywords with specific channels in test scripts: MUST and MUST NOT lead to the ERROR channel for failed tests SHOULD and SHOULD NOT lead to the WARNING channel, the test is still passed MAY leads to the INFO channel, the test is still passed However, the CRITICAL level is not directly associated with any of the RFC2119 keywords; it is instead used to signify that a test was unable to complete or was interrupted due to various issues, such as runtime failures.","s":"3. Channels for Output in Test Scripts","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#3-channels-for-output-in-test-scripts","p":364},{"i":374,"t":"A test is considered to pass if and only if it doesn't produce any messages on the ERROR nor the CRITICAL channel. The presence of warnings or informational items from SHOULD and MAY categories do not directly impact the pass/fail status but is important for overall quality and compatibility with future standards. That means a test can have one of three results: fail: if it has at least one message on ERROR DNF (did not finish): if it has no message on ERROR, but at least one on CRITICAL pass: otherwise In addition, a test MUST exit with a non-zero exit code (e.g., via sys.exit(…)) if there are any ERROR or CRITICAL messages, thus signaling a failure to meet a standard. In test scripts it is a MUST to redirect all channel outputs to standard error (stderr), which aligns with Python's default logging behavior. The format which MUST be used is CHANNEL: MESSAGE, where CHANNEL represents the log level (e.g., DEBUG, INFO, WARNING, ERROR, CRITICAL) and MESSAGE encapsulates the actual log message. For instance, when logging an INFO regarding a Kubernetes cluster, the format on the command line should be like this: INFO: Checking cluster specified by context 'my-cluster' in /path/to/.kube/config. This example adheres to our proposed format by clearly indicating the severity level (INFO) followed by the specific message intended for the user or developer.","s":"4. Compliance and Test Passing Criteria","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#4-compliance-and-test-passing-criteria","p":364},{"i":377,"t":"The following example of a fictitious document for a \"Web Server Installation Standard\" is intended to illustrate the use of RFC2119 keywords in connection with the creation of SCS-compliant standard documents.","s":"5.1 Example: Standards Document using RFC2119 Keywords","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#51-example-standards-document-using-rfc2119-keywords","p":364},{"i":379,"t":"Purpose​ This document provides a concise set of requirements for installing a secure web server. Requirements​ Web Server Software: Apache HTTP Server 2.4.x or Nginx 1.18.x MUST be installed. No other web server software versions or types are permitted. Operating System: The server MUST run on an OS that receives current security updates. Unsupported versions MUST NOT be used. TLS Configuration: TLS 1.2 or higher MUST be enabled for all connections. SSL and earlier TLS versions MUST NOT be used. Security Patches: The web server and OS MUST be kept up-to-date with security patches. Critical patches SHOULD be applied within 48 hours of release. Firewall Setup: The firewall SHOULD be configured to allow only necessary ports, such as 80 (HTTP) and 443 (HTTPS). All unnecessary ports SHOULD NOT be open. Backup Plan: Regular backups of the web server data MAY be performed, and it is recommended that backup integrity checks are conducted to ensure recoverability. Compliance​ Failure to comply with these requirements results in the web server being considered non-compliant with the organization's security policies.","s":"Web Server Installation Standard","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#web-server-installation-standard","p":364},{"i":381,"t":"The following example of a fictitious code for a test of \"process_requirements\" is intended to illustrate the use of RFC2119 keywords in connection with the creation of SCS-compliant standard tests. import logging logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) def process_requirements(var1, var2): try: # debug log for input variables logger.debug(f\"Received input var1: {var1}, var2: {var2}\") # example of an error case (equivalent to MUST and MUST NOT) if var1 < 0: logger.error(\"var1 must be positive\") elif var1 > 100: logger.error(\"var1 must not exceed 100\") # add debug log to confirm evaluation of var1 logger.debug(f\"var1 evaluated: {var1 > 0 and var1 < 100}\") # example of a warning case (equivalent to SHOULD and SHOULD NOT) if var2 < 10: logger.warning(\"var2 should be at least 10 for optimal performance\") elif var2 > 50: logger.warning(\"var2 should not exceed 50 for optimal performance\") # add debug log to confirm evaluation of var2 logger.debug(f\"var2 evaluated: {var2 > 10 and var2 < 50}\") # example of an informative case (equivalent to MAY) if var1 + var2 < 100: logger.info(\"Combination is within recommended range\") else: logger.info(\"Combination exceeds the recommended range but may still proceed\") # debug log before completing the process logger.debug(f\"Final evaluation before completion: var1 + var2 = {var1 + var2}\") # success log logger.debug(\"Process completed successfully\") except ValueError as e: # debug log before raising a critical error logger.debug(\"Encountered a critical error about to log\", exc_info=True) logger.critical(f\"Process failed: {e}\", exc_info=True) Note: The DEBUG channel is used for additional information for developers to better understand a process and does not apply to RFC2119 keywords.","s":"5.2 Example: Test script using RFC2119 Keywords","u":"/contributor-docs/development/tests/rfc2119-keyword-test-guide","h":"#52-example-test-script-using-rfc2119-keywords","p":364},{"i":383,"t":"Developing Cluster Stack Provider OpenStack operator is quite straightforward. First, you need to install some basic prerequisites: Docker Go Next, configure your environment variables. Once that's done, you can initiate development using the local Kind cluster and the Tilt UI to create a workload cluster that comes pre-configured.","s":"Developer Guide","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"","p":382},{"i":385,"t":"Install Docker and Go. We expect you to run on a Linux OS. Create an .envrc file and specify the values you need. See the .envrc.sample for details.","s":"Setting Tilt up","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#setting-tilt-up","p":382},{"i":387,"t":"Operator development requires a lot of iteration, and the “build, tag, push, update deployment” workflow can be very tedious. Tilt makes this process much simpler by watching for updates and automatically building and deploying them. To build a kind cluster and to start Tilt, run: make tilt-up To access the Tilt UI please go to: http://localhost:10351 You should make sure that everything in the UI looks green. If not, you can trigger the Tilt workflow again.","s":"Developing with Tilt","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#developing-with-tilt","p":382},{"i":389,"t":"When you start your tilt setup then the ClusterStack manifest gets copied from config/cspo directory to root of your repository. In order to apply the ClusterStack to the running local development cluster, you can click on the tilt UI. There should a click on the top-right hand side that is named as apply-clusterstack if you hover over it. Once the ClusterStack is applied wait for the ClusterStack and ClusterStackRelease object to be ready. In case your ClusterStack shows that it is ready, you can deploy a workload cluster.","s":"Applying ClusterStack","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#applying-clusterstack","p":382},{"i":391,"t":"This could be done through the Tilt UI, by pressing the button in the top right corner Create Workload Cluster. This triggers the make create-workload-cluster-openstack, which uses the environment variables and the cluster-template. To interact with your freshly created workload cluster, you can use these commands: make get-kubeconfig-workload-cluster #KUBECONFIG for the workload cluster is placed here: \".workload-cluster-kubeconfig.yaml\" export KUBECONFIG=$PWD/.workload-cluster-kubeconfig.yaml In case you want to change some code, you can do so and see that Tilt triggers on save. It will update the container of the operator automatically. If you want to change something in your ClusterStack or Cluster custom resources, you can have a look at .cluster.yaml and .clusterstack.yaml, which Tilt uses. To delete the ClusterStack you can click on the delete-clusterstack button in the tilt UI. To tear down the workload cluster, click on the Delete Workload Cluster button in the top right corner of the Tilt UI. This action triggers the execution of make delete-workload-cluster-openstack. After a few minutes, the resources should be successfully deleted. To tear down the kind cluster, use: make delete-bootstrap-cluster If you have any trouble finding the right command, then you can use make help to get a list of all available make targets.","s":"Creating workload cluster","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#creating-workload-cluster","p":382},{"i":393,"t":"We can retrieve cluster-stacks in two modes. One way is to let the controller fetch it from GitHub which is remote mode and other is we mount the cluster-stacks inside the container at /tmp/downloads/cluster-stacks directory. [!NOTE] Using remote mode is the default behavior. Switching between both modes is relatively simple if you're using Tilt. There is a file at the root of the repo tilt-settings.yaml.example Make a copy of that file with the name of tilt-settings.yaml cp tilt-settings.yaml.example tilt-settings.yaml Now, open the file and set the local_mode to true to use cluster-stacks in local_mode. It should look the following content wise. local_mode: true [!NOTE] In this mode you need to have cluster-stacks present locally. Downloading cluster-stacks can be achieved by many ways but below is a simple way to download it quickly. mkdir -p .release/openstack-scs-1-27-v1/ cd .release/openstack-scs-1-27-v1 gh release download --repo SovereignCloudStack/cluster-stacks openstack-scs-1-27-v1 Change the repo and tag as per the requirement. You can also download it directly from browser and move it to .release directory. Please make sure the directory structure remains the same otherwise you'll not be able to start the tilt setup. Here's an example of structuring openstack-scs-1-27-v1 cluster-stack. $ tree .release/openstack-scs-1-27-v1/ .release/openstack-scs-1-27-v1/ ├── clusterstack.yaml ├── metadata.yaml └── openstack-scs-1-27-cluster-class-v1.tgz [!IMPORTANT] There's an alternative way to get clusterstacks using csctl. You can follow the README of csctl for specific instructions and a good quickstart. You can use csctl create subcommand to create clusterstack locally. You'll need a csctl.yaml file in the cluster-stack configuration directory. Please read more about creating configuration file for csctl in the csctl docs.","s":"Toggle between local_mode and remote mode","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/develop","h":"#toggle-between-local_mode-and-remote-mode","p":382},{"i":396,"t":"The OpenStackClusterStackRelease controller’s main responsibilities are: Download release assets into the CSPO container Create OpenStackNodeImageRelease resources based on the required NodeImages defined in the downloaded release asset node-images.yaml Set an OwnerReference on the existing OpenStackNodeImageRelease resources that could be utilized by the ClusterStack release (multiple versions of one ClusterStack could share an image) Update the OpenStackClusterStackRelease status to ready once all related OpenStackNodeImageReleases are also ready","s":"OpenStackClusterStackRelease controller","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","h":"#openstackclusterstackrelease-controller","p":394},{"i":398,"t":"The OpenStackNodeImageRelease controller’s main responsibilities are: Load the OpenStack Cloud configuration from the Secret referenced in spec.IdentityRef Create an Image as defined by spec.Image if it does not already exist in the specified OpenStack project Instruct the OpenStack Glance service to import an Image from the provided URL Set the OpenStackNodeImageRelease status to ready once the image achieves an Active status","s":"OpenStackNodeImageRelease controller","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllers","h":"#openstacknodeimagerelease-controller","p":394},{"i":400,"t":"This document has been moved. You can find the current version of the quickstart guide here.","s":"Quickstart","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstart","h":"","p":399},{"i":402,"t":"This guide explains general info on how to debug issues if a cluster creation fails.","s":"Troubleshooting","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","h":"","p":401},{"i":404,"t":"If you are using https, and when you encounter issues like: kubectl logs -n cspo-system -l control-plane=controller-manager ... [manager] 2024-04-15T15:20:07Z DEBUG events Post \"https://10.0.3.15/identity/v3/auth/tokens\": tls: failed to verify certificate: x509: certificate signed by unknown authority {\"type\": \"Warning\", \"object\": {\"kind\":\"OpenStackNodeImageRelease\",\"namespace\":\"cluster\",\"name\":\"openstack-ferrol-1-27-ubuntu-capi-image-v1.27.8-v2\",\"uid\":\"93d2c1c8-5a19-45f8-9f93-8e8bd5227ebf\",\"apiVersion\":\"infrastructure.clusterstack.x-k8s.io/v1alpha1\",\"resourceVersion\":\"3773\"}, \"reason\": \"OpenStackProviderClientNotSet\"} ... you must specify the CA certificate in your secret, which contains the access data to the OpenStack instance, then secret should look similar to this example: apiVersion: v1 data: cacert: clouds.yaml: kind: Secret metadata: labels: clusterctl.cluster.x-k8s.io/move: \"true\" name: \"openstack\" namespace: cluster","s":"providerClient authentication err","u":"/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshooting","h":"#providerclient-authentication-err","p":401},{"i":407,"t":"Kubernetes cluster v1.20+ Use existing cluster export KUBECONFIG=/path/to/kubeconfig Alternatively, spawn some dev cluster, e.g. using KinD kind create cluster Flux CLI Installation documentation: https://fluxcd.io/flux/installation/#install-the-flux-cli curl -s https://fluxcd.io/install.sh | sudo FLUX_VERSION=2.2.3 bash flux install","s":"Prerequisites","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#prerequisites","p":405},{"i":409,"t":"$ kubectl apply -k operators/ $ flux get helmrelease -n default NAME REVISION SUSPENDED READY MESSAGE cert-manager v1.11.0 False True Release reconciliation succeeded ingress-nginx 4.5.2 False True Release reconciliation succeeded postgres-operator 1.9.0 False True Release reconciliation succeeded redis-operator 3.2.7 False True Release reconciliation succeeded Note: Install separate operators by e.g.: kubectl apply -k operators/redis/ kubectl apply -k operators/postgres/","s":"Install and wait for operators","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#install-and-wait-for-operators","p":405},{"i":411,"t":"envs/public-ha/redis/redis-secret.bash # pwgen needs to be installed kubectl apply -k envs/public-ha/redis/ kubectl apply -k envs/public-ha/postgres/","s":"Create redis and postgres clusters","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#create-redis-and-postgres-clusters","p":405},{"i":413,"t":"Replace the example.com URL in the harbor-config.yaml file with the desired one. Take ingress-nginx-controller LoadBalancer IP address and create DNS record for Harbor. kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller LoadBalancer 100.92.14.168 81.163.194.219 80:30799/TCP,443:32482/TCP 2m51s ingress-nginx-controller-admission ClusterIP 100.88.40.231 443/TCP 2m51s Generate secrets and install Harbor: It is recommended to replace admin@example.com email address in issuer.yaml with your own. Let's Encrypt will use this to contact you about expiring certificates, and issues related to your account. base/harbor-secrets.bash # pwgen and htpasswd need to be installed envs/public-ha/swift-secret.bash kubectl apply -k envs/public-ha/","s":"Install Harbor","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#install-harbor","p":405},{"i":415,"t":"envs/public-ha/redis/redis-secret.bash base/harbor-secrets.bash envs/public-ha/swift-secret.bash # --branch/tag can be specified, default to master flux create source git k8s-harbor --url=https://github.com/SovereignCloudStack/k8s-harbor --interval=5m kubectl apply -f envs/public-ha/public-ha.yaml","s":"All in one installation using FluxCD Kustomization and GitRepository reconciliation","u":"/docs/container/components/container-registry/docs/ha-deployment","h":"#all-in-one-installation-using-fluxcd-kustomization-and-gitrepository-reconciliation","p":405},{"i":417,"t":"This page aims at providing a step-by-step guide for lift and shift migration of Harbor container registry, which operates in the Kubernetes environment and is deployed with Helm. This migration scenario uses Velero tool which enables moving your Harbor instance as-is from one Kubernetes environment to another Kubernetes environment. The motivation behind this could be e.g. migration from one cloud provider to another, an outdated Kubernetes environment of your Harbor instance or avoiding the Harbor in-place upgrade. Note that the official Harbor's documentation contains an \"Upgrade Harbor and Migrate Data\" page that instructs users on how to upgrade and migrate Harbor data from one instance to another. This tutorial supports only deployments that have been installed by Harbor installer script. Hence, Harbor instances running in docker containers and spawned by docker-compose. Note that this guide is not limited to Harbor deployments that utilize SCS environments. Visit the prerequisites section to see what is required for a successful migration. These prerequisites come out of the box when the SCS infrastructure and KaaS are used for Harbor deployment, hence it is convenient to use them.","s":"Migration","u":"/docs/container/components/container-registry/docs/migration","h":"","p":416},{"i":419,"t":"As this scenario uses a backup and restore procedure for the migration process, this section refers to the prerequisites section in Harbor - backup and restore docs page.","s":"Prerequisites","u":"/docs/container/components/container-registry/docs/migration","h":"#prerequisites","p":416},{"i":421,"t":"This migration scenario expects that you want to migrate your Harbor instance between different Kubernetes clusters that could live in different environments (e.g. OpenStack projects) or even in different cloud providers. Let's call them Cluster_A and Cluster_B. Cluster_A represents the Kubernetes cluster where your Harbor currently operates and Cluster_B represents the target Kubernetes cluster to which you want to migrate your Harbor. As Cluster_A and Cluster_B do not have to share the same infrastructure it is convenient to use a full Harbor data backup (not a snapshot) using Restic integration in Velero. In this case, Cluster_A and Cluster_B should have Kubernetes version 1.16 or greater. For further details about Restic-Velero integration refer to the related Velero docs. Kubernetes versions of Cluster_A and Cluster_B may differ. In this case, it is not unusual to see the Kubernetes API group versions differing between clusters. This incompatibility may cause issues during the migration of your Harbor instance. By default, Velero only backs up resources that use the preferred version of the Kubernetes API. However, Velero also includes a feature, Enable API Group Versions, that overcomes this limitation and backup all Kubernetes API group versions that are supported on the source Cluster_A. Then, if this feature is also enabled on the Cluster_B, Velero will make the best choice of Kubernetes API version which is defined in the group name of both source Cluster_A and target Cluster_B based on API group version priority order, read docs for further details. If the above is the case consider installing Velero on both clusters with a feature flag --features=EnableAPIGroupVersions. Note that this feature is still in beta.","s":"Kubernetes clusters","u":"/docs/container/components/container-registry/docs/migration","h":"#kubernetes-clusters","p":416},{"i":423,"t":"This guide assumes that the public cloud's object store with S3-compatible API is available as the storage backend for Velero. Refer to the S3 bucket and EC2 credentials section in the backup and restore docs and create a bucket that will be later used for the migration.","s":"S3 bucket and EC2 credentials","u":"/docs/container/components/container-registry/docs/migration","h":"#s3-bucket-and-ec2-credentials","p":416},{"i":425,"t":"Install the Velero client on your local environment, refer to Velero client.","s":"Velero client","u":"/docs/container/components/container-registry/docs/migration","h":"#velero-client","p":416},{"i":427,"t":"Install Velero server components along with the appropriate plugins, into the both (Cluster_A and Cluster_B) clusters. Keep in mind that we will use Restic uploader in Velero, hence follows interactions on how to do that in the related docs section Velero server. Do not forget to add --kubeconfig argument to install Velero server components to the Cluster_A and then to the Cluster_B. The rest of arguments should be the same: velero install \\ --kubeconfig \\ --provider aws \\ --plugins velero/velero-plugin-for-aws:v1.6.1 \\ --bucket velero-backup \\ --secret-file ~/.aws/credentials \\ --use-volume-snapshots=false \\ --uploader-type=restic \\ --use-node-agent \\ --backup-location-config region=RegionOne,s3ForcePathStyle=\"true\",s3Url=https://api.gx-scs.sovereignit.cloud:8080 It is a good practice to configure the backup location in the Cluster_B as read-only. This will make sure that the backup created from Cluster_A is not deleted from the object store by mistake during the restore to Cluster_B. To do this you can just edit the default BackupStorageLocation resource in Cluster_B. $ kubectl -n velero --kubeconfig edit backupstoragelocations default # Set the `accessMode` to `ReadOnly` # spec: # accessMode: ReadOnly","s":"Velero server","u":"/docs/container/components/container-registry/docs/migration","h":"#velero-server","p":416},{"i":428,"t":"Before we start to migrate Harbor instance from one environment to another go through the Backup and restore section and read various limitations of the backup/restore process to be aware of the potential impact on your Harbor instance. Backup Harbor instance in Cluster_A Set Harbor to the ReadOnly mode Exclude the volume of Redis in backup in Cluster_A # replace the namespace and pod name with yours kubectl -n default --kubeconfig annotate pod/harbor-harbor-redis-0 backup.velero.io/backup-volumes-excludes=data Back up Harbor in Cluster_A velero backup create harbor-backup --kubeconfig --include-namespaces default --default-volumes-to-fs-backup --wait This creates a full backup of all resources in the given namespace including their persistent storages (besides Redis PV). Optionally: Unset Harbor from the ReadOnly mode. Keep in mind that the ReadOnly mode protects your Harbor instance from deleting repository, artifact, tag, and pushing images. This ensures that the Harbor instance in Cluster_A will be in sync with the Harbor instance in Cluster_B after you restored Harbor instance from the backup in Cluster_B. Therefore, it is recommended to not unset Harbor from the ReadOnly mode in Cluster_A. Restore Harbor instance in Cluster_B Restore from the Backup # replace the backup and restore names with yours velero restore create harbor-restore --from-backup harbor-backup --kubeconfig --wait Velero backed up the whole namespace where the Harbor instance lives in Cluster_A, therefore the restored namespace in Cluster_B may contain resources (e.g. service, ingress, TLS certificates) that expose Harbor instance in the same way as in Cluster_A. It is a good practice to test this Cluster_B instance before you allow users to use it. Unset Harbor from the ReadOnly mode. As we set Harbor in Cluster_A to ReadOnly when doing the backup, the instance is still in ReadOnly mode after restoring. Unset Harbor from the ReadOnly mode after you check its functionality.","s":"Migration","u":"/docs/container/components/container-registry/docs/migration","h":"#migration-1","p":416},{"i":430,"t":"This guide shows you how to set up a working Harbor Container Registry that utilizes a Kubernetes cluster.","s":"Quickstart","u":"/docs/container/components/container-registry/docs/quickstart","h":"","p":429},{"i":432,"t":"Kubernetes cluster v1.20+ Use existing cluster export KUBECONFIG=/path/to/kubeconfig Alternatively, spawn some dev cluster, e.g. using KinD kind create cluster Flux CLI Installation documentation: https://fluxcd.io/flux/installation/#install-the-flux-cli curl -s https://fluxcd.io/install.sh | sudo FLUX_VERSION=2.2.3 bash flux install","s":"Prerequisites","u":"/docs/container/components/container-registry/docs/quickstart","h":"#prerequisites","p":429},{"i":434,"t":"Apply kustomization manifest in envs/dev directory: kubectl apply -k envs/dev/ Port-forward the Harbor container registry service: kubectl port-forward svc/harbor 8080:80 Access the Harbor container registry UI and use Harbor's default credentials username: admin password: Harbor12345 http://localhost:8080","s":"Install Harbor container registry","u":"/docs/container/components/container-registry/docs/quickstart","h":"#install-harbor-container-registry","p":429},{"i":436,"t":"This page describes how the rate limiting can be set up for the Harbor container registry. Harbor itself doesn't support rate limit protection yet, see open issue. Therefore, we can take advantage of the ingress controller in front of the Harbor. In our case Nginx. In the ingress-nginx controller, the rate-limiting options can be specified via annotations. E.g. nginx.ingress.kubernetes.io/limit-rps: \"1\" means that ingress will allow only 1 request from a given IP per second. Client IP is set based on the use of PROXY protocol or from the X-Forwarded-For header value. In the SCS reference implementation, proxy protocol for ingress nginx is enabled by default. This rate-limit annotation is ideal for DDoS attacks mitigation. When clients exceed this limit 503 status code is returned. This status code can be changed via nginx ingress controller configmap: $ kubectl edit cm -n ingress-nginx ingress-nginx-controller # data: # limit-req-status-code: \"429\" There are other useful annotations, such as limit concurrent connections, number of kilobytes per second or limit burst requests. E.g. bursts can be configured via nginx.ingress.kubernetes.io/limit-burst-multiplier, which is by default 5. It means that burst will be set in this case to limit-rps * limit-burst-multiplier = 1 * 5 = 5. More information about nginx rate-limiting and real-world examples can be seen in this nginx blog. Also, there is a second option for how the rate limiting can be configured called global rate limiting. Detailed research and comparison are done in this issue. Furthermore, see this PR, which adds a rate limit for the public(registry.scs.community) environment.","s":"Rate limit","u":"/docs/container/components/container-registry/docs/rate_limit","h":"","p":435},{"i":438,"t":"The following steps were utilized for deploying the SCS reference installation of the Harbor container registry, which is available at https://registry.scs.community.","s":"SCS deployment","u":"/docs/container/components/container-registry/docs/scs-deployment","h":"","p":437},{"i":440,"t":"Kubernetes cluster v1.20+ We used the R5 version of SCS KaaS V1, which includes an ingress controller and cert manager export KUBECONFIG=/path/to/kubeconfig Flux CLI (it is part of SCS KaaS V1) Installation documentation: https://fluxcd.io/flux/installation/#install-the-flux-cli curl -s https://fluxcd.io/install.sh | sudo FLUX_VERSION=2.2.3 bash flux install kubectl","s":"Prerequisites","u":"/docs/container/components/container-registry/docs/scs-deployment","h":"#prerequisites","p":437},{"i":442,"t":"Take ingress-nginx-controller LoadBalancer IP address and create DNS record for Harbor. kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller LoadBalancer 100.92.14.168 81.163.194.219 80:30799/TCP,443:32482/TCP 2m51s ingress-nginx-controller-admission ClusterIP 100.88.40.231 443/TCP 2m51s Generate secrets and install Harbor: base/harbor-secrets.bash # pwgen and htpasswd need to be installed envs/public/s3-credentials.bash kubectl apply -k envs/public/","s":"Install Harbor","u":"/docs/container/components/container-registry/docs/scs-deployment","h":"#install-harbor","p":437},{"i":444,"t":"This page briefly describes and provides pointers on how Harbor persists data when it is deployed in a Kubernetes cluster environment. It points out the default persistence settings of Harbor helm chart as well as available options. Harbor, by design, consists of multiple (micro)services that could store their data variously, based on the Harbor configuration, see the Architecture Overview of Harbor.","s":"Persistence","u":"/docs/container/components/container-registry/docs/persistence","h":"","p":443},{"i":447,"t":"Usage Key value storage used as a login session cache, a registry manifest cache, and a queue for the jobservice (e.g. see Trivy) Default settings Deployed as an \"internal\" single node database into the same Kubernetes cluster as Harbor (helm value: redis.type.internal) Deployed as a StatefulSet with 1 replica PV persistence is enabled by default (helm value: persistence.enabled.true), Redis POD mounts PV into the /var/lib/redis directory Additional settings Harbor could be pointed to the \"external\" Redis (or Redis Sentinel) database (helm value: redis.type.external) \"Internal\" Redis could be deployed without any persistence, i.e. it could use emptyDir (helm value: persistence.enabled.false) Notes What is the role of Redis in Harbor? Redis data does not need to be backed up, see the Limitations docs for more details of the potential impact","s":"Redis","u":"/docs/container/components/container-registry/docs/persistence","h":"#redis","p":443},{"i":449,"t":"Usage Stores the related metadata of Harbor models, like projects, users, roles, replication policies, tag retention policies, scanners, charts, and images Could store JobService logs (helm value: jobservice.jobLoggers.[database]) Default settings Deployed as an \"internal\" single node database into the same Kubernetes cluster as Harbor (helm value: database.type.internal) Deployed as a StatefulSet with 1 replica PV persistence is enabled by default (helm value: persistence.enabled.true), PostgreSQL POD mounts PV into the /var/lib/postgresql/data directory Additional settings Harbor could be pointed to the \"external\" database (PostgreSQL) (helm value: database.type.external) \"Internal\" database could be deployed without any persistence, i.e. it could use emptyDir (helm value: persistence.enabled.false)","s":"Database (PostgreSQL)","u":"/docs/container/components/container-registry/docs/persistence","h":"#database-postgresql","p":443},{"i":451,"t":"Usage Backend storage of container images and charts Default settings Images and charts are stored in registry POD filesystem directory /storage (helm value: persistence.imageChartStorage.type.filesystem), this directory is mounted to the PV Additional settings Various object storage backends: \"azure\", \"gcs\", \"s3\", \"swift\", \"oss\" (helm value: persistence.imageChartStorage.type.) Backend storage could beemptyDir (helm value: persistence.enabled.false)","s":"OCI Distribution Registry","u":"/docs/container/components/container-registry/docs/persistence","h":"#oci-distribution-registry","p":443},{"i":454,"t":"These Harbor services are stateless","s":"Proxy, Core, Web Portal","u":"/docs/container/components/container-registry/docs/persistence","h":"#proxy-core-web-portal","p":443},{"i":456,"t":"Usage A 3rd party vulnerability scanner provided by Aqua Security Default settings Deployed as a StatefulSet with 1 replica PV persistence is enabled by default (helm value: persistence.enabled.true), Trivy POD mounts PV into the /home/scanner/.cache directory Additional settings Trivy could be deployed without any persistence, i.e. it could use emptyDir (helm value: persistence.enabled.false) Notes What kind of data are stored in /home/scanner/.cache?","s":"Trivy","u":"/docs/container/components/container-registry/docs/persistence","h":"#trivy","p":443},{"i":458,"t":"Usage General job execution queue service to let other components/services submit requests of running asynchronous tasks concurrently Default settings Deployed as a Deployment with 1 replica Store logs in the POD filesystem directory /var/log/jobs (helm value: jobservice.jobLoggers.[file]), this directory is mounted to the PV Additional settings JobService could be deployed without any persistence, i.e. it could use emptyDir (helm value: persistence.enabled.false) Logs could be stored in Harbor database (helm value: jobservice.jobLoggers.[database]) or just printed to the STDOUT (helm value: jobservice.jobLoggers.[stdout])","s":"JobService","u":"/docs/container/components/container-registry/docs/persistence","h":"#jobservice","p":443},{"i":460,"t":"This page aims at providing additional information for upgrading Harbor container registry, which operates in the Kubernetes environment and is deployed with Helm. It extends the official Upgrading Harbor Deployed with Helm page, where the upgrade process is well described. See the following upgrade hints: Always backup your Harbor instance before upgrade Normally Harbor helm upgrade from 2 minor versions lower should be tested, but always validate your planned upgrade path with recommendations in the official docs. The step-by-step upgrade is needed because of possible DDL changes in the Harbor database. Harbor core service executes the migrations scripts automatically. The helm upgrade process may fail in the case of the failure of migration scripts. Hence, it is a good idea to run migration scripts with a pre-upgrade job. Harbor Helm has an option enableMigrateHelmHook which separates the database migration from Harbor core and runs the migration job as a pre-upgrade hook.","s":"Upgrade","u":"/docs/container/components/container-registry/docs/upgrade","h":"","p":459},{"i":462,"t":"This page aims at providing a step-by-step guide for backup and restore Harbor container registry using Velero tool. It extends the official Harbor backup-restore docs page with up-to-date commands, explanations, and an extensive prerequisites section. This guide references and uses Velero in v1.10.2 as this is the latest stable version at the time of writing this guide. It provides guidance and commands that readers are encouraged to try out by themselves on Harbor deployment as described in the next sections. It does not aim at providing an exhaustive list of commands nor all the possible ways how to use them. The guide covers two strategies to save Harbor data: Backup: a regular backup created by the restic integration in Velero as described in the related docs Snapshot: a point-in-time snapshot be the Container Storage Interface (CSI) snapshot support in Velero as described in the related docs Before you choose the right strategy for your Harbor deployment backup, make sure that you understand differences between the backup and snapshot. In general, for long-term protection of Harbor data, you may use backup and for temporary protection of data (e.g. before Harbor upgrade) you may use snapshot. Note that this guide is not limited to Harbor deployments that utilize SCS environments, but it is required to have a set of tools and services (e.g. Kubernetes CSI plugin with volume snapshot support, S3 compatible object store for backups) for successful backup and restore procedure (see the prerequisites section). These tools and services come out of the box when the SCS infrastructure and KaaS are used for Harbor deployment, hence it is convenient to use them.","s":"Backup and restore","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"","p":461},{"i":465,"t":"If you want to use snapshot to back up Harbor data ensure the following: Your cluster is Kubernetes version 1.20 or greater Your cluster is running a CSI driver capable of support volume snapshots at the v1 API level. To enable creating volume snapshots, the snapshot-controller and its CRDs should be deployed in the Kubernetes cluster as well. The snapshot-controller is independent of any CSI Driver. These prerequisites come out of the box with the SCS KaaS solution. If you want to create Harbor backup ensure the following: Your cluster is Kubernetes version 1.16 or greater If your cluster meets the above, export its kubeconfig path in env. variable KUBECONFIG: export KUBECONFIG=/path/to/kubeconfig","s":"Kubernetes cluster","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#kubernetes-cluster","p":461},{"i":467,"t":"This guide assumes that the public cloud's object store with S3-compatible API is available as the storage backend for Velero. In this guide, we are using OpenStack Swift which offers S3-compatible API. Let's create an S3 bucket on Swift object storage and EC2 credentials that will be later used by Velero. You should have access to your OpenStack project, and the OpenStack RC file that contains access values. Set the environment variables by sourcing the OpenStack RC file: source -openrc.sh Swift object store service does not support application credentials authentication to access S3 API. To authenticate in S3 API, you should generate and use the EC2 credentials mechanism. Note that EC2 credentials are associated with a user and are scoped only to a specific project. EC2 credentials are not protected by limited roles, expiration time, or access rules, therefore they have the same access as the user who created them. If you want to restrict EC2 credentials you could use application credentials for their creation, then EC2 credentials should inherit a (potentially) limited subset of roles that creator owns (see this for details). You can generate EC2 credentials as follows: $ openstack ec2 credentials create +------------+----------------------------------------------------------------------------------------------------------+ | Field | Value | +------------+----------------------------------------------------------------------------------------------------------+ | access | | | links | {'self': 'https://api.gx-scs.sovereignit.cloud:5000/v3/users//credentials/OS-EC2/'} | | project_id | | | secret | | | trust_id | None | | user_id | | +------------+----------------------------------------------------------------------------------------------------------+ Write down aws_access_key_id and aws_secret_access_key values from the output of openstack ec2 credentials create command and store them in the ~/.aws/credentials file as follows: mkdir ~/.aws cat >~/.aws/credentials < aws_secret_access_key = EOF This credential file is then used as an access and secret source for AWS CLI tool and also as a source for Velero. If your environment does not have AWS CLI installed, install it as follows: pip3 install awscli awscli-plugin-endpoint Finally, create a new bucket. Note that the following command contains endpoint-url argument that points AWS CLI to the GX-SCS OpenStack Swift object store API. aws --endpoint-url https://api.gx-scs.sovereignit.cloud:8080 s3 mb s3://velero-backup","s":"S3 bucket and EC2 credentials","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#s3-bucket-and-ec2-credentials","p":461},{"i":469,"t":"In this guide, we are using Velero to back up and restore a Harbor instance. Velero is an open source tool to safely back up and restore, perform disaster recovery, and migrate Kubernetes cluster resources. Go through the official docs and install the Velero client on your desired environment. If your environment is Linux distribution you can use the following steps and install the Velero client from the GitHub release binaries: wget https://github.com/vmware-tanzu/velero/releases/download/v1.10.2/velero-v1.10.2-linux-amd64.tar.gz tar -zxvf velero-v1.10.2-linux-amd64.tar.gz sudo mv velero-v1.10.2-linux-amd64/velero /usr/local/bin/","s":"Velero client","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#velero-client","p":461},{"i":471,"t":"Install Velero server components along with the appropriate plugins, into the Kubernetes cluster. This will create a namespace called velero, and place a deployment named velero in it. Note that the installation command sets the bucket velero-backup that has been created a few steps earlier as well as EC2 credentials located in ~/.aws/credentials file. Also note that the region and s3Url parameters are GX-SCS specific. For further details about installation options, supported storage providers, and more visit the official Velero docs. If you want to use snapshot to back up Harbor data: Install Velero: velero install \\ --features=EnableCSI \\ --provider aws \\ --plugins velero/velero-plugin-for-aws:v1.6.1,velero/velero-plugin-for-csi:v0.4.2 \\ --bucket velero-backup \\ --secret-file ~/.aws/credentials \\ --backup-location-config region=RegionOne,s3ForcePathStyle=\"true\",s3Url=https://api.gx-scs.sovereignit.cloud:8080 \\ --snapshot-location-config region=RegionOne,enableSharedConfig=true In order to allow Velero to do Volume Snapshots, we need to deploy a new VolumeSnapshotClass. Create a velero-snapclass.yaml file as follows: cat > velero-snapclass.yaml << EOF apiVersion: snapshot.storage.k8s.io/v1 deletionPolicy: Delete driver: cinder.csi.openstack.org kind: VolumeSnapshotClass metadata: name: csi-cinder-snapclass-in-use-v1-velero labels: velero.io/csi-volumesnapshot-class: \"true\" parameters: force-create: \"true\" EOF Apply the new class: kubectl apply -f velero-snapclass.yaml If you want to create Harbor backup with Restic: Install Velero: velero install \\ --provider aws \\ --plugins velero/velero-plugin-for-aws:v1.6.1 \\ --bucket velero-backup \\ --secret-file ~/.aws/credentials \\ --use-volume-snapshots=false \\ --uploader-type=restic \\ --use-node-agent \\ --backup-location-config region=RegionOne,s3ForcePathStyle=\"true\",s3Url=https://api.gx-scs.sovereignit.cloud:8080","s":"Velero server","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#velero-server","p":461},{"i":472,"t":"Note that the following backup steps mainly point to actions from an official Backup And Restore Harbor With Velero tutorial. In this guide, find the added value from additional explanations/hints and up-to-date commands. Harbor, by design, consists of multiple (micro)services that could store their data variously, based on the Harbor configuration. See the Harbor persistence docs for further information regarding the Harbor persistence layer. The following steps cover cases when Harbor persistence is enabled and the \"internal\" databases (PostgreSQL and Redis) are used. Note that Redis key-value database is not backed up in both cases, i.e. when \"internal\" or \"external\" Redis instance is used. As a result, the user sessions of logged users that are stored in Redis will be lost. Hence, after the restore, users should log in again. This data loss should be a low impact on your restored Harbor instance. PostgreSQL database should be backed up as it stores important metadata of Harbor models, like projects, users, roles, etc. The backup and restore of \"internal\" PostgreSQL instance is covered by this guide. The \"external\" PostgreSQL backup is not supported by the official tutorial and is out of the scope of this guide as well. Also, keep an eye on the official backup and restore limitations section to be aware of the potential impact on your Harbor instance. The limitation: The upload purging process may cause backup failure mentioned that it is better to increase registry upload purging interval (it is a background process that periodically removes orphaned files from the upload directories of the registry, see the docs). This interval is by default set to 24h (helm value: registry.upload_purging.interval). If you do not want to change the registry configuration at all you should ensure that the backup will be performed in the middle of two rounds of purging. This background process starts when the registry container is initialized, therefore is a good idea to check logs of the registry container and determine when is a good time to do a backup, e.g. as follows: $ kubectl logs -l component=registry -c registry --tail -1 | grep -i purge time=\"2023-04-17T09:02:08.320514706Z\" level=info msg=\"Starting upload purge in 24h0m0s\" go.version=go1.15.6 instance.id=xxx service=registry version=v2.7.1.m time=\"2023-04-17T09:09:08.321004645Z\" level=info msg=\"PurgeUploads starting: olderThan=2023-04-10 09:09:08.320738572 +0000 UTC m=-604379.969424455, actuallyDelete=true\" time=\"2023-04-17T09:09:08.331433127Z\" level=info msg=\"Purge uploads finished. Num deleted=0, num errors=0\" ...","s":"Backup and restore","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#backup-and-restore-1","p":461},{"i":474,"t":"Set Harbor to the ReadOnly mode Backup Harbor: Using snapshot to back up Harbor data: Exclude the volume of Redis in backup, we need to label the Redis pod, PVC and PV with specific label: # label the Pod of Redis, replace the namespace and Pod name with yours kubectl -n default label pod/harbor-harbor-redis-0 velero.io/exclude-from-backup=true # label the PVC of Redis, replace the namespace and PVC name with yours kubectl -n default label pvc/data-harbor-harbor-redis-0 velero.io/exclude-from-backup=true # get the name of Redis PV, replace the namespace and PVC name with yours kubectl -n default get pvc data-harbor-harbor-redis-0 --template={{.spec.volumeName}} # label the PV of Redis, replace the pv-name with the one get from last command kubectl label pv/pv-name velero.io/exclude-from-backup=true Back up Harbor # replace the namespace and backup name with yours velero backup create harbor-backup --include-namespaces default --snapshot-volumes --wait Using Restic to back up Harbor data: Exclude the volume of Redis in backup # replace the namespace and pod name with yours kubectl -n default annotate pod/harbor-harbor-redis-0 backup.velero.io/backup-volumes-excludes=data Back up Harbor velero backup create harbor-backup --include-namespaces default --default-volumes-to-fs-backup --wait Unset Harbor from the ReadOnly mode","s":"Backup Harbor Instance","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#backup-harbor-instance","p":461},{"i":476,"t":"Restore Harbor Instance","s":"Restore Harbor Instance","u":"/docs/container/components/container-registry/docs/backup_and_restore","h":"#restore-harbor-instance","p":461},{"i":479,"t":"As of R6, our tests cover 1.25.latest ... 1.28.latest. All of them pass the sonobuoy CNCF conformance tests.","s":"Supported k8s versions","u":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","h":"#supported-k8s-versions","p":477},{"i":481,"t":"The provenance capo means that this setting comes from the templates used by the cluster-api-provider-openstack, while SCS denotes that this setting has been added by the SCS project.","s":"Overview over the parameters in clusterctl.yaml and environment-XXX.tfvars","u":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","h":"#overview-over-the-parameters-in-clusterctlyaml-and-environment-xxxtfvars","p":477},{"i":483,"t":"Parameters controlling the Cluster-API management server (capi management server) creation: environment clusterctl.yaml provenance default meaning prefix SCS capi Prefix used for OpenStack resources for the capi mgmt node kind_flavor SCS SCS-2V-4 Flavor to be used for the k8s capi mgmt server image SCS Ubuntu 22.04 Image for the capi mgmt server. Use Ubuntu 22.04 or Debian 12. Check also the ssh_username parameter ssh_username SCS ubuntu Name of the default user for the image clusterapi_version SCS 1.6.3 Version of the cluster-API incl. clusterctl capi_openstack_version SCS 0.9.0 Version of the cluster-api-provider-openstack (needs to fit the CAPI version) cilium_binaries SCS v0.15.23;v0.13.0 Versions of the cilium and hubble CLI in the vA.B.C;vX.Y.Z format restrict_mgmt_server SCS [\"0.0.0.0/0\"] Allows restricting access to the management server by the given list of CIDRs. Empty value (default) means public. mgmt_cidr SCS 10.0.0.0/24 IPv4 address range (CIDR notation) for management cluster mgmt_ip_range SCS {start:\"10.0.0.11\", end:\"10.0.0.254\"} IP range from defined mgmt_cidr variable for management cluster. It is recommended to reserve the first 10 IPs.","s":"Parameters CAPI management server","u":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","h":"#parameters-capi-management-server","p":477},{"i":485,"t":"Parameters controlling both management server creation and cluster creation: environment clusterctl.yaml provenance default meaning cloud_provider OPENSTACK_CLOUD capo OS_CLOUD name in clouds.yaml external/external_id OPENSTACK_EXTERNAL_NETWORK_ID capo \"\" Name/ID of the external (public) OpenStack network, default \"\" uses the detected external network (for clouds with one external network). Required for clouds with more than one external network dns_nameservers OPENSTACK_DNS_NAMESERVERS capo [ \"5.1.66.255\", \"185.150.99.255\" ] Array of nameservers for capi mgmt server and for cluster nodes, replace the FF MUC defaults with local servers if available availability_zone OPENSTACK_FAILURE_DOMAIN capo Availability Zone(s) for the mgmt node / workload clusters kind_mtu MTU_VALUE SCS 0 MTU for the mgmt server; Calico is set 50 bytes smaller; 0 means autodetection http_proxy SCS Global setting for HTTP Proxy is set on the management host including all cluster-api components running in the bootstrap-cluster. Specify with protocol: e.g http://10.10.10.10:3128 no_proxy SCS Global setting for HTTP Proxy exception list. If http_proxy is not set this setting has no effect. If http_proxy is set, the default value for the NO_PROXY environment variable on all affected components is set to .svc,.svc.cluster,.svc.cluster.local,127.0.0.0/8,169.254.169.254/32,fd00:ec2::254/128,${var.node_cidr},${var.pod_cidr},${var.service_cidr}. The content of no_proxy is appended to this list. This setting has no effect on apt and snap commands, the way http_proxy is set for apt and snap does not allow the configuration of proxy exceptions.","s":"Common parameters management server and clusters","u":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","h":"#common-parameters-management-server-and-clusters","p":477},{"i":487,"t":"Parameters controlling the cluster creation: environment clusterctl.yaml provenance default meaning node_cidr NODE_CIDR SCS 10.8.0.0/20 IPv4 address range (CIDR notation) for workload nodes pod_cidr POD_CIDR SCS 192.168.0.0/16 IPv4 address range (CIDR notation) for pods service_cidr SERVICE_CIDR SCS 10.96.0.0/12 IPv4 address range (CIDR notation) for services use_cilium USE_CILIUM SCS true Use cilium as CNI instead of calico, it can be set to vX.Y.Z and true results in v1.15.1, also see cilium_binaries calico_version CALICO_VERSION SCS v3.27.3 Version of the Calico CNI provider (ignored if use_cilium is set) kubernetes_version KUBERNETES_VERSION capo v1.28.x Kubernetes version deployed into workload cluster (.x means latest patch release) `` OPENSTACK_IMAGE_NAME capo ubuntu-capi-image-${KUBERNETES_VERION} Image name for k8s controller and worker nodes. Ubuntu 22.04 image is used for k8s versions >= 1.27.3, 1.26.6, 1.25.11, Ubuntu 20.04 otherwise. kube_image_raw OPENSTACK_IMAGE_RAW SCS true Register images in raw format (instead of qcow2), good for ceph COW image_registration_extra_flags OPENSTACK_IMAGE_REGISTATION_EXTRA_FLAGS SCS \"\" Extra flags passed during image registration `` OPENSTACK_SSH_KEY_NAME capo ${prefix}-keypair SSH key name generated and used to connect to workload cluster nodes controller_flavor OPENSTACK_CONTROL_PLANE_MACHINE_FLAVOR capo SCS-2V-4-20s Flavor to be used for control plane nodes worker_flavor OPENSTACK_NODE_MACHINE_FLAVOR capo SCS-2V-4-20s Flavor to be used for worker nodes controller_count CONTROL_PLANE_MACHINE_COUNT capo 1 Number of control plane nodes in testcluster (0 skips testcluster creation) `` CONTROL_PLANE_MACHINE_GEN SCS genc01 Suffix for control plane node resources, to be changed for rolling upgrades worker_count WORKER_MACHINE_COUNT capo 3 Number of worker nodes in testcluster `` WORKER_MACHINE_GEN SCS genw01 Suffix for worker node resources, to be changed for rolling upgrades `` CONTROL_PLANE_ROOT_DISKSIZE SCS 20 If diskless flavors are used for control plane nodes, this is the allocated root volume disk size (in GB) `` WORKER_ROOT_DISKSIZE SCS 20 If diskless flavors are used for worker nodes, this is the allocated root volume disk size (in GB) anti_affinity OPENSTACK_ANTI_AFFINITY SCS true Use anti-affinity server groups to prevent k8s nodes on same host (soft for workers, hard for controllers) `` OPENSTACK_SRVGRP_CONTROLLER SCS nonono Autogenerated if anti_affinity is true, eliminated otherwise `` OPENSTACK_SRVGRP_WORKER SCS nonono Autogenerated if anti_affinity is true, eliminated otherwise deploy_occm DEPLOY_OCCM SCS true Deploy the given version of OCCM into the cluster. true (default) chooses the latest version matching the k8s version. You can specify master to chose the upstream master branch. Don't disable this. deploy_cindercsi DEPLOY_CINDERCSI SCS true Deploy the given (or latest matching for the default true value) of cinder CSI. etcd_unsafe_fs ETCD_UNSAFE_FS SCS false Use barrier=0 for filesystem on control nodes to avoid storage latency. Use for multi-controller clusters on slow/networked storage, otherwise not recommended. testcluster_name (cmd line) SCS testcluster Allows setting the default cluster name, created at bootstrap (if controller_count is larger than 0) restrict_kubeapi RESTRICT_KUBEAPI SCS [ ] Allows restricting access to kubernetes API by list of CIDRs. Empty list (default) means public, [ \"none\" ] means internal access only. `` OPENSTACK_CLUSTER_GEN SCS geno01 Generation counter for the OpenStackClusterTemplate resource. Increase, when changing restrict_kubeapi or other OC settings capo_instance_create_timeout CLUSTER_API_OPENSTACK_INSTANCE_CREATE_TIMEOUT capo 5 Time to wait for an OpenStack machine to be created (in minutes) containerd_registry_files SCS {\"hosts\":[\"./files/containerd/docker.io\"], \"certs\":[]} Containerd registry hosts config files, see related docs for details. Optional services deployed to cluster: environment clusterctl.yaml provenance default script meaning deploy_metrics DEPLOY_METRICS SCS true apply_metrics.sh Deploy metrics service to nodes to make kubectl top work deploy_nginx_ingress DEPLOY_NGINX_INGRESS SCS true apply_nginx_ingress.sh Deploy NGINX ingress controller (this spawns an OpenStack Loadbalancer), pass version to explicitly choose the version, true results in v1.9.6 (supported k8s >= 1.25) `` NGINX_INGRESS_PROXY SCS true (dito) Configure LB and nginx to get real IP via PROXY protocol; trouble for pod to LB connections has been resolved by setting hostname use_ovn_lb_provider USE_OVN_LB_PROVIDER SCS false apply_nginx_ingress.sh Clouds using OVN networking can deploy the OVN provider that has low overhead (L3) and makes real client IPs visible without proxy protocol hacks. Set to auto to enable. deploy_gateway_api DEPLOY_GATEWAY_API SCS false create_cluster.sh Deploy Gateway APIs CRDs and enable ciliums Gateway API implementation. This only works in conjunction with USE_CILIUM=true. Also this will break at least one CNCF conformance test. This feature is considered a tech-review. Keep in mind that Gateway API itself is under development and not GA. Also note that ciliums implementation of Gateway API is considered \"beta\". deploy_cert_manager DEPLOY_CERT_MANAGER SCS false apply_cert_manager.sh Deploy cert-manager, pass version (e.g. v1.14.2) to explicitly choose a version deploy_flux DEPLOY_FLUX SCS false create_cluster.sh Deploy flux2 into the cluster deploy_harbor SCS false deploy_harbor.sh Deploy harbor into the cluster. When enabled, it will overwrite the settings above. Harbor forces deployment of flux and based on config, it can force deployment of other dependencies (cert-manager, ingress-nginx and Cinder CSI) harbor_config SCS {domain_name:\"\", issuer_email:\"\", persistence:false, database_size:\"1Gi\", redis_size:\"1Gi\", trivy_size:\"5Gi\"} (dito) Harbor container registry configuration options, see related docs for details.","s":"Parameters clusters","u":"/docs/container/components/k8s-cluster-api-provider/doc/configuration","h":"#parameters-clusters","p":477},{"i":489,"t":"Project k8s-cluster-api-provider uses SCS Zuul CI platform to drive its continuous integration tests. The project is registered under the SCS tenant and therefore is able to use a set of pre-defined pipelines, jobs, and ansible roles that SCS Zuul instance defines and imports. If you want to explore currently available SCS pipelines, visit the SCS zuul-config project. If you want to see the full list of jobs that are available, visit the SCS Zuul UI. And if you are looking for some handy ansible role that SCS Zuul imports, visit they source. Refer to SCS Zuul users guide and/or Zuul docs for further details on how to define and use Zuul CI/CD pipelines and jobs. Note (for geeks): If you are interested in Zuul CI platform and want to deploy your own development instance of it, then read the official quick-start manual or visit this tutorial which aims a connection of Zuul CI platform with a GitHub organization.","s":"Continuous integration","u":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","h":"","p":488},{"i":491,"t":"SCS Zuul automatically recognizes .zuul.yaml configuration file that is located in the k8s-cluster-api-provider's root. This file informs Zuul about the project's default-branch and preferred merge-mode. It also references SCS Zuul pipelines and their jobs used by the k8s-cluster-api-provider project. Then, jobs link Ansible playbooks that contain tasks for actual CI testing. See relevant CI configuration files: ├── .zuul.yaml ├── playbooks │ ├── cleanup.yaml │ ├── dependencies.yaml │ ├── e2e.yaml │ ├── templates │ │ └── environment.tfvars.j2","s":"Configuration","u":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","h":"#configuration","p":488},{"i":493,"t":"This section describes an SCS Zuul pipelines that are used by the k8s-cluster-api-provider project. e2e-test It is triggered by the e2e-test label in the opened PR It executes k8s-cluster-api-provider-e2e-conformance job It applies the PR label successful-e2e-test and leaves an informative PR comment when the k8s-cluster-api-provider-e2e-conformance job succeeded It applies the PR label failed-e2e-test and leaves an informative PR comment when the k8s-cluster-api-provider-e2e-conformance job failed It applies the PR label cancelled-e2e-test and leaves an informative PR comment when the k8s-cluster-api-provider-e2e-conformance job is canceled unlabel-on-update-e2e-test It is triggered by the PR update only when PR contains the successful-e2e-test label It ensures that any PR update invalidates a previous successful e2e test It removes successful-e2e-test label from the PR e2e-quick-test It is triggered by the e2e-quick-test label in the opened PR It executes k8s-cluster-api-provider-e2e-quick job It applies the PR label successful-e2e-quick-test and leaves an informative PR comment when the k8s-cluster-api-provider-e2e-quick job succeeded It applies the PR label failed-e2e-quick-test and leaves an informative PR comment when the k8s-cluster-api-provider-e2e-quick job failed It applies the PR label cancelled-e2e-quick-test and leaves an informative PR comment when the k8s-cluster-api-provider-e2e-quick job is canceled unlabel-on-update-e2e-quick-test It is triggered by the PR update only when PR contains the successful-e2e-quick-test label It ensures that any PR update invalidates a previous successful e2e test It removes successful-e2e-quick-test label from the PR periodic-daily This pipeline runs jobs daily at 3AM It executes k8s-cluster-api-provider-e2e-conformance job The job overrides the git_reference variable to ensure that the e2e conformance testing is executed on a specific tag","s":"Pipelines","u":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","h":"#pipelines","p":488},{"i":495,"t":"This section describes Zuul jobs defined within the k8s-cluster-api-provider project and linked in the above pipelines. k8s-cluster-api-provider-e2e-conformance It runs a sonobuoy conformance test against Kubernetes cluster spawned by k8s-cluster-api-provider scripts This job is a child job of openstack-access-base that ensures OpenStack credentials availability in Zuul worker node. Parent job also defines a Zuul semaphore semaphore-openstack-access, that ensures that a maximum of three openstack-access-base jobs (or their children) can run at a time See a high level k8s-cluster-api-provider-e2e-conformance job steps: Pre-run playbook dependencies.yaml installs project prerequisites, e.g. opentofu, yq, etc. Main playbook e2e.yaml spawns a k8s cluster, runs sonobuoy conformance test, and cleans created infrastructure, all by k8s-cluster-api-provider scripts Cleanup-run playbook cleanup.yaml runs ospurge, cleanup created application credentials and keypair to ensure that multiple e2e runs do not interfere k8s-cluster-api-provider-e2e-quick It runs a sonobuoy quick test against Kubernetes cluster spawned by k8s-cluster-api-provider scripts This job is a child job of openstack-access-base that ensures OpenStack credentials availability in Zuul worker node. Parent job also defines a Zuul semaphore semaphore-openstack-access, that ensures that a maximum of three openstack-access-base jobs (or their children) can run at a time See a high level k8s-cluster-api-provider-e2e-quick job steps: Pre-run playbook dependencies.yaml installs project prerequisites, e.g. opentofu, yq, etc. Main playbook e2e.yaml spawns a k8s cluster, runs sonobuoy quick test, and cleans created infrastructure, all by k8s-cluster-api-provider scripts Cleanup-run playbook cleanup.yaml runs ospurge, cleanup created application credentials and keypair to ensure that multiple e2e runs do not interfere","s":"Jobs","u":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","h":"#jobs","p":488},{"i":497,"t":"The parent job openstack-access-base, from which e2e jobs inherit, defines secret variable openstack-application-credential. This secret is stored directly in the SCS/zuul-config repository in an encrypted form. It contains OpenStack application credentials to access the OpenStack project dedicated for CI testing. This secret is encrypted by the SCS/zuul-config repository RSA key that has been generated by SCS Zuul instance. So only SCS Zuul instance is able to decrypt it (read the docs). If you want to re-generate the mentioned secret or add another one using SCS/zuul-config repository RSA key, follow the below instructions: Install zuul-client pip install zuul-client Encrypt \"super-secret\" string by the SCS/zuul-config repository public key from SCS Zuul echo -n \"super-secret\" | \\ zuul-client --zuul-url https://zuul.scs.community encrypt \\ --tenant SCS \\ --project github.com/SovereignCloudStack/zuul-config","s":"Secrets","u":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","h":"#secrets","p":488},{"i":499,"t":"In some cases you may want to change your environment.tfvars file before running the e2e test without changing the environment.tfvars file in the repository. For example, you may want to change the image variable to test a different system image without altering the default image used by the project. To do so, you can in the body of the PR add the following text: ```ZUUL_CONFIG image = \"Ubuntu 20.04\" ### FAQ #### How do developers/reviewers should proceed if they want to CI test this project? A developer initiates a PR as usual. If a reviewer deems that the PR requires e2e testing, they can apply a specific label to the PR. Currently, the following labels could be applied: - `e2e-test` (for comprehensive e2e testing, including k8s cluster creation, execution of sonobuoy conformance tests, and cluster deletion) - `e2e-quick-test` (for expedited e2e testing, involving k8s cluster creation, quick sonobuoy tests, and cluster deletion) After the e2e test has completed, the reviewer can examine the test results and respond accordingly, such as approving the PR if everything appears to be in order or requesting changes. Sonobuoy test results, along with a link to the e2e logs, are conveyed back to the PR via a comment. Additionally, the PR is labeled appropriately based on the overall e2e test result, using labels like `successful-e2e-test`, `successful-e2e-quick-test`, `failed-e2e-test`, or `failed-e2e-quick-test`. #### Why do we use PR `label` as an e2e pipeline trigger instead of e.g. PR `comment`? We consider PR labels to be a more secure pipeline trigger compared to, for example, PR comments. PR labels can only be applied by developers with [triage](https://docs.github.com/en/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization#permissions-for-each-role) repository access or higher. In contrast, PR comments can be added by anyone with a GitHub account. Members of the SCS GitHub organization are automatically granted 'write' access to SCS repositories. Consequently, the PR label mechanism ensures that only SCS organization members can trigger e2e pipelines. #### How do we ensure that any PR update invalidates a previous successful e2e test? In fact, two mechanisms ensure the invalidation of a previously successful test when a PR is updated. Firstly, the pipelines `unlabel-on-update-` remove the `successful-` label from the PR when it's updated after a successful e2e test has finished. If an e2e test is in progress and the PR is updated, the currently running e2e test is canceled, the `successful-` label is removed (if it exists), and the `cancelled-` label is applied along with an informative PR comment to inform the reviewer about the situation.","s":"Job customization","u":"/docs/container/components/k8s-cluster-api-provider/doc/continuous-integration","h":"#job-customization","p":488},{"i":501,"t":"OpenTofu creates an application credential that it passes into the created VM. This one is then used to authenticate the cluster API provider against the OpenStack API to allow it to create resources needed for the k8s cluster. The AppCredential has a few advantages: We take out variance in how the authentication works -- we don't have to deal with a mixture of project_id, project_name, project_domain_name, user_domain_name, only a subset of which is needed depending on the cloud. We do not leak the user credentials into the cluster, making any security breach easier to contain. AppCreds are connected to one project and can be revoked. We are using an unrestricted AppCred for the management server which can then create further AppCreds, so we can each cluster its own (restricted) credentials. In the case of breaches, these AppCreds can be revoked. Note that you can have additional projects or clouds listed in your ~/.config/openstack/clouds.yaml (and secure.yaml) and reference them in the OPENSTACK_CLOUD setting of your clusterctl.yaml, so you can manage clusters in various projects and clouds from the same management server.","s":"Application Credentials","u":"/docs/container/components/k8s-cluster-api-provider/doc/application-credentials","h":"","p":500},{"i":503,"t":"Setting up the nginx ingress controller from the upstream deployment templates using the externalTrafficPolicy: local setting and -- without any special treatment -- results in a service that is only partially working: Only requests that the LoadBalancer happens to route at the node where the nginx container is running get a response. nginx could just use the cluster setting instead and kube-proxy would forward the network packets. There are two reasons for nginx not to do that Having a load-balancer balance the traffic to a node that is not active just to have kube-proxy forward it to the active node does not make much sense. It creates an unnecessary hop and makes the LoadBalancer pretty useless. Packets forwarded by kube-proxy do not carry the original client IP, so any source IP dependant handling in nginx (filtering, QoS, ...) will not be possible.","s":"Ingress with externalTrafficPolicy: local","u":"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","h":"","p":502},{"i":505,"t":"There does not seem to be a standard mechanism where k8s tells the LoadBalancer (LB) which backend members are active, but the load-balancer can find this out by using a health-monitor that probes for the availability of the service and then takes the inactive nodes out of the rotation. Should the container be rescheduled on some other node, the health-monitor will adapt within a few seconds. Since SCS R2, the deployed nginx-ingress deployment is patched to carry a service annotation (a behavior specifically needed by OpenStack) that enables the health-monitor for the LB in front of the ingress. This results in traffic to flow. This covers the nginx ingress controller that is deployed by setting DEPLOY_NGINX_INGRESS: true with the create_cluster.sh or apply_nginx_ingress.sh. That the ingress we call the \"managed ingress\". For the ingress service to see the client IPs, more is needed. The Octavia LB as well as the nginx service both support the proxy protocol, which can be used to communicate the real client IP. We had plumbing included which we disabled by default prior to releasing R2, because it broke the access to ingress from software that runs inside the cluster. A workaround for this has been implemented, so the default is NGINX_USE_PROXY: true as of R4. So the managed nginx ingress service does work reliably and gets the client IPs.","s":"Getting it to work for managed ingress","u":"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","h":"","p":502},{"i":507,"t":"Users that deploy their own nginx or other services with externalTrafficPolicy: local won't be helped by the annotations done by the SCS cluster management. They will have to do similar custom patching or revert to a cluster policy and forego the visibility on real client IPs. A generic solution to this would be a different kind of LB that does work at the networking layer 3 (routing), so the (TCP) connections are not terminated at the LB and then data being forwarded on a new connection to the backend member, but the routing would create a direct connection. Google (with Direct Server Return, DSR) and Azure support such LB modes. As it turns out, on OpenStack clouds that use OVN as networking (SDN) layer, the OVN loadbalancer does almost deliver what's needed.","s":"Getting it to work in general","u":"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","h":"","p":502},{"i":509,"t":"The OVN provider for the load-balancer does create direct flows to the chosen backend member, so no proxy protocol (or similar hacks) are needed to make the backend service see the client IPs. This has been validated (and can even be monitored by openstack-health-monitor) on SCS clouds that use OVN. A health-monitor is still needed to ensure that only active members receive requests. Health monitors for the ovn provider are only supported on OpenStack Wallaby and later. See also occm docs. OVN LoadBalancer can be enabled by setting use_ovn_lb_provider = \"true\" or use_ovn_lb_provider = \"auto\". Note that the use_ovn_lb_provider does not affect the LB in front of the kube API. That one is created by capo and requires other settings. Also note that it would not yet support the CIDR filtering with restrict_kubeapi setting.","s":"OVN provider LoadBalancer","u":"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","h":"","p":502},{"i":511,"t":"We could enable a health-monitor by default for load-balancers created from OCCM in the k8s clusters. This would make services with externalTrafficPolicy: local work, as the traffic would be routed exclusively to active members. But the other goal would not be achieved: Getting the real client IPs. We decided against turning on the health-monitor by default, as this might result in the wrong impression that local fully works. Rather break and then have users take a decision to go for cluster, to enable health-monitoring to get it half-working or to do health-monitoring plus some extra plumbing for proxy protocol (or similar) to get all aspects working.","s":"Disabled health-monitor by default","u":"/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocal","h":"","p":502},{"i":513,"t":"Creating and scaling k8s clusters on demand is providing a lot of flexibility to DevOps teams that develop, test, deploy and operate services and applications. We expect the functionality to be mainly consumed in two scenarios: Self-service: The DevOps team leverages the code provided from this repository to create their own capi management server and use it then to manage a number of k8s clusters for their own needs. Managed k8s: The Operator's service team creates the capi management server and uses it to provide managed k8s clusters for their clients. Note that we have an intermediate model in mind -- a model where a one-click / one-API call interface would allow the management server to be created on behalf of a user and then serve as an API endpoint to that user's k8s CAPI needs. Ideally with some dashboard or GUI that would shield less experienced users from all the YAML. Once we as the SCS Community have the gitops style cluster control working, the self-service model will become more convenient to use. The provided solution covers the following two main topics: Automation (opentofu, Makefile) to bootstrap a cluster-API management server by installing kind on a vanilla Ubuntu image and deploying some tools on this node (kubectl, openstack CLI tools, k9s, cilium, calico, helm, flux ...) and deploying cluster-API (clusterctl) and the OpenStack cluster-api provider along with suitable credentials. The opentofu automation is driven by a Makefile for convenience. The tooling also contains all the logic to clean up again. The newly deployed node clones this git repository early in the bootstrap process and uses the thus received files to set up the management cluster and scripts. This node can be connected to via ssh and the deployed scripts there can be used to manage workload clusters and then deploy various standardized tools (such as e.g. OpenStack Cloud Controller Manager(OCCM), cinder CSI, calico or cilium CNI, nginx ingress controller, cert-manager, ...) and run tests (e.g. CNCF conformance with sonobuoy). The tools and artifacts can be updated via git pull at any time and the updated settings rolled out to the workload clusters. Note that the script collection will eventually be superseded by the capi-helm-charts. The medium-term goal is to actually create a reconciliation loop here that would perform life-cycle-management for clusters according to the cluster configuration stored in an enhanced cluster-api style clusterctl.yaml from git repositories and thus allow a pure gitops style cluster management without ever ssh'ing to the management server.","s":"Overview","u":"/docs/container/components/k8s-cluster-api-provider/doc/overview","h":"","p":512},{"i":515,"t":"This guide shows you how to get working Kubernetes clusters on a SCS cloud via cluster-api(CAPI).","s":"Quickstart","u":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","h":"","p":514},{"i":517,"t":"make kubectl opentofu yq python3-openstackclient, python3-octaviaclient","s":"Requirements","u":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","h":"#requirements","p":514},{"i":519,"t":"You need access to an OpenStack project. Copy the default environment and adjust the options according to your cloud. cp terraform/environments/environment-{default,}.tfvars Edit terraform/environments/environment-.tfvars with your favourite text editor. Every option without a default value must be set. Add a clouds.yaml inside the terraform dir, in ~/.config/openstack or /etc/openstack. It is recommended to set the name of the cloud in the clouds.yml to the same value as the cloud_provider in the environment-.tfvars, then you only have to specify the ENVIRONMENT or OS_CLOUD variable.","s":"Prepare the environment","u":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","h":"#prepare-the-environment","p":514},{"i":521,"t":"# Set the ENVIRONMENT to the name specified in the name of the file # `cloud_provider` option has to be set in the environment file # to the name of the cloud in the clouds.yaml export ENVIRONMENT= # Create your environment. This includes a management node as virtual machine # in your OpenStack environment as well as a Kubernetes testcluster. make create # Get the kubeconfig of the testcluster make get-kubeconfig # Interact with the testcluster kubectl --kubeconfig testcluster.yaml. get nodes","s":"Create a test cluster","u":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","h":"#create-a-test-cluster","p":514},{"i":523,"t":"make clean If make clean fails to clean up completely, you can also use the fullclean target. Review the Teardown section of the Makefile reference document for more details.","s":"Teardown","u":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","h":"#teardown","p":514},{"i":525,"t":"This guide assumes you just create one test cluster directly when creating the management server. In a production setting, you would not use this test cluster but create clusters via the management server. You can read more about this in the usage guide.","s":"Beyond quickstart","u":"/docs/container/components/k8s-cluster-api-provider/doc/quickstart","h":"#beyond-quickstart","p":514},{"i":527,"t":"This is a reference to the Makefile targets. Almost all targets require the ENVIRONMENT variable to be set to the name of the environment you want to use. (See Environments in the requirements documentation for more information.)","s":"Makefile reference","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"","p":526},{"i":530,"t":"make create To initiate the management server setup, various components are created. This includes the provisioning of networks, security groups, and a virtual machine. An application credential is also generated for authentication purposes. Once the virtual machine is up and running, it is bootstrapped by cloning the specified git repository. Additionally, specific tools are installed to facilitate the process. Next, a local Kubernetes cluster is deployed using kind. The cluster acts as a foundation for further operations. During the setup, the Cluster API, as well as the Cluster API Provider (e.g. CAPO), are installed within the local cluster. This provider serves as the API server for Kubernetes CAPI, enabling management and interaction with the cloud backends (e.g. OpenStack). Finally, a test cluster is created utilizing Kubernetes CAPI. This test cluster allows for experimentation, validation, and development within the CAPI environment. Note that make create will not create a testcluster if you have set controller_count to zero in your environment file (environment-.tfvars). Note that make create does not copy local files to the management server, only some files are templated there from the terraform/files/template directory. If you want to change any of the scripts being copied to the management server, you need to commit, push your changes, and run make create again. make create will pull the latest changes from the git repository.","s":"make create","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-create","p":526},{"i":532,"t":"make get-kubeconfig This will get the kubeconfig of the testcluster and store it in the file testcluster.yaml..","s":"make get-kubeconfig","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-get-kubeconfig","p":526},{"i":534,"t":"make ssh This will ssh into the management server, using the username that was set in your environment-.tfvarsfile. The default in the environment file is ubuntu. Note: there is also an alias to this make login","s":"make ssh","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-ssh","p":526},{"i":536,"t":"make openstack This will run openstack cli.","s":"make openstack","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-openstack","p":526},{"i":538,"t":"make k9s This will run k9s on the management server.","s":"make k9s","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-k9s","p":526},{"i":540,"t":"make log CONSOLE=capi-mgmtcluster This will show openstack console log of the management server. You can specify the console log you want to see by setting the CONSOLE variable. The default is capi-mgmtcluster.","s":"make log","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-log","p":526},{"i":542,"t":"make console CONSOLE=capi-mgmtcluster This will open openstack console of the management server in the browser using XDG-open. You can specify the console you want to open by setting the CONSOLE variable. The default is capi-mgmtcluster.","s":"make console","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-console","p":526},{"i":544,"t":"make deploy-cso This will deploy the cluster-stack-operator. The preconfigured repo to look for cluster-stacks is https://github.com/SovereignCloudStack/cluster-stacks/. GIT_ACCESS_TOKEN can be specified.","s":"make deploy-cso","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-deploy-cso","p":526},{"i":546,"t":"make deploy-cspo This will deploy the cluster-stack-provider-openstack. The preconfigured repo to look for cluster-stacks is https://github.com/SovereignCloudStack/cluster-stacks/. GIT_ACCESS_TOKEN can be specified.","s":"make deploy-cspo","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-deploy-cspo","p":526},{"i":548,"t":"Note that clean and fullclean leave the ubuntu-capi-image-$KUBERNETES_VERSION image registered, so it can be reused. You need to manually unregister it, if you want your next deployment to register a new image with the same kubernetes version number.","s":"Teardown","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#teardown","p":526},{"i":550,"t":"make clean does ssh to the capi management server to clean up the created clusters prior to opentofu cleaning up the resources it has created. This is sometimes insufficient to clean up unfortunately, some error in the deployment may result in resources left around.","s":"Make clean","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-clean","p":526},{"i":552,"t":"make fullclean uses a custom script cleanup/cleanup.sh (using the openstack CLI) to clean up everything while trying to not hit any resources not created by the CAPI or opentofu for clusters from this management host. It is the recommended way for doing cleanups if make clean fails. Watch out for leftover floating IP addresses and persistent volumes, as these can not be easily traced back to the Cluster API created resources and may thus be left. There is also a make forceclean variant that hits unused floating IPs and all persistent volumes -- this is risky as there is no good way to tell which PVCs belong to us unless we find them attached to cluster nodes in which case we don't need the force options.","s":"Make fullclean","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-fullclean","p":526},{"i":554,"t":"You can purge the whole project via make purge. Be careful with that command as it will purge all resources in the OpenStack project even those that have not been created through this OpenTofu script or the Cluster API. It requires the ospurge tool. Install it with python3 -m pip install git+https://git.openstack.org/openstack/ospurge.","s":"Make purge","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-purge","p":526},{"i":557,"t":"make check SONOMODE=... This will run tests of the configuration on testcluster using sonobuoy. It will also download the results and print them to the console. Optionally you can also specify a mode by using for example SONOMODE=\"--mode quick\" Note: This runs over 5000 tests and takes a long time to complete (~ 2 hours).","s":"make check","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-check","p":526},{"i":559,"t":"make check-quick This will run tests of the configuration on testcluster using sonobuoy with mode quick.","s":"make check-quick","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-check-quick","p":526},{"i":561,"t":"make check-conformance This will run tests of the configuration on testcluster using sonobuoy with mode conformance meaning it will test if the cluster is conformant to the CNCF.","s":"make check-conformance","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-check-conformance","p":526},{"i":563,"t":"make check-storage This will run tests of the configuration on testcluster using sonobuoy of the storage.","s":"make check-storage","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-check-storage","p":526},{"i":565,"t":"make check-csi This will run tests of the configuration on testcluster using sonobuoy of the CSI.","s":"make check-csi","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-check-csi","p":526},{"i":568,"t":"make init This will initialize opentofu. It will download the required providers and modules. It will also select or create a new workspace for you. The workspace name is the same as the ENVIROMENT variable.","s":"make init","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-init","p":526},{"i":570,"t":"make attach RESOURCE= PARAMS=... This will attach a resource to the opentofu state. This is useful if you have created a resource outside of opentofu and want to manage it with opentofu.","s":"make attach","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-attach","p":526},{"i":572,"t":"make detach RESOURCE= PARAMS=... This will detach a resource from the opentofu state. This is useful if you have changed a resource outside of opentofu or you no longer want to manage it with opentofu.","s":"make detach","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-detach","p":526},{"i":574,"t":"make state-push This will push the opentofu state to specified storage if set. This is useful if you don't want to store the state locally.","s":"make state-push","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-state-push","p":526},{"i":576,"t":"make dry-run This will run a dry-run of the opentofu apply command. This is useful if you want to see what opentofu will do before actually doing it.","s":"make dry-run","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-dry-run","p":526},{"i":578,"t":"make show This will show the opentofu state. This is useful if you want to see what opentofu is managing.","s":"make show","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-show","p":526},{"i":580,"t":"make list This will list all the resources managed by opentofu. This is useful if you want to see what opentofu is managing.","s":"make list","u":"/docs/container/components/k8s-cluster-api-provider/doc/make-reference","h":"#make-list","p":526},{"i":583,"t":"On the management server, we have not only helm installed, but also the repository https://github.com/stackhpc/capi-helm-charts checked out. Amongst other things, it automates the creation of new machine templates when needed and doing rolling updates on your k8s cluster with clusterctl. This allows for an easy adaptation of your cluster to different requirements, new k8s versions etc. Please note that this is currently evolving quickly and we have not completely assessed and tested the capabilities. We intend to do this after R2 and eventually recommend this as the standard way of managing clusters in production. At this point, it's included as a technical preview.","s":"Advanced cluster templating with helm (Technical Preview)","u":"/docs/container/components/k8s-cluster-api-provider/doc/roadmap","h":"#advanced-cluster-templating-with-helm-technical-preview","p":581},{"i":586,"t":"What does a provider need to do in order to NOT run into a certificate issue? Update the cluster at least once a year to rotate certificates automatically Automatic certificate renewal for cluster upgrades kubeadm renews all the certificates during control plane upgrade. This feature is designed for addressing the simplest use cases; if you don't have specific requirements on certificate renewal and perform Kubernetes version upgrades regularly (less than 1 year in between each upgrade), kubeadm will take care of keeping your cluster up to date and reasonably secure. Renew all certificates with kubeadm certs renew all You only need to do this when you don't upgrade your cluster kubeadm certs renew","s":"Client Certificates in Kubernetes expire after one year","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","h":"#client-certificates-in-kubernetes-expire-after-one-year","p":584},{"i":588,"t":"Another problem is that the CA might expire as well (normally after 10 years) kubeadm does not have any tooling for this at the time of writing There is documentation for Manual Rotation of CA Certifcates On the management node, there is a signer.sh that can be used to sign server certificates after checking that they belong to the server.","s":"Certificate Authority expires","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","h":"#certificate-authority-expires","p":584},{"i":590,"t":"NOTE: The following kubectl and clusterctl commands should be executed against the management Kubernetes cluster API. Keep in mind that these tools and the kubeconfig to access the management Kubernetes cluster are available in the management host, hence it is convenient to execute the following commands from the management host. Ask Kubernetes what went wrong: kubectl describe cluster The status and the events may give you a clue what happened. The healthy cluster should be in the phase: Provisioned $ kubectl describe cluster | yq .Status.Phase Provisioned You can also have a look at the openstackcluster object and see OpenStack related statuses and events. The healthy cluster should be ready: $ kubectl describe openstackcluster | yq .Status.Ready true Note that you can instead execute kubectl get cluster -ojsonpath='{ .status.phase }' and kubectl get openstackcluster -ojsonpath='{ .status.ready }' if you don't have yq at hand. A handy command for cluster health investigation is clusterctl describe cluster . This prints infrastructure/control plane/workers readiness status and other relevant information like a failure reason. The healthy cluster output is similar to this: $ clusterctl describe cluster NAME READY SEVERITY REASON SINCE MESSAGE Cluster/testcluster True 21m ├─ClusterInfrastructure - OpenStackCluster/testcluster ├─ControlPlane - KubeadmControlPlane/testcluster-control-plane True 23m │ └─3 Machines... True 21m See testcluster-control-plane-5ftjs, testcluster-control-plane-62cdj, ... └─Workers └─MachineDeployment/capi-testcluster-md-0-no1 True 22m └─3 Machines... True 21m See capi-testcluster-md-0-no1-84dd86f598-bhxfd, capi-testcluster-md-0-no1-84dd86f598-f6pnl, ... The logs of the capi pod and especially the capo pod are a good source of information. To find out in which condition the deployment status is, you can use the following way: kubectl logs -n capo-system -l control-plane=capo-controller-manager -c manager Successful cluster creation will log Reconciled Machine create successfully for successfully created nodes. kubectl logs -n capi-system -l control-plane=controller-manager -c manager In some cases could be a good idea to go through the official [capi] (https://cluster-api.sigs.k8s.io/user/troubleshooting.html) and capo troubleshooting guides or check whether you hit some known bug already reported in capi or capo projects. You can also check the OpenStack layer. A cluster deployment should result in a router,a network, a subnet, a loadbalancer (in front of kubeapi) and a number of servers (VMs) for the control-plane and worker nodes. Have you run out of quota?","s":"Failed cluster deployment debugging","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","h":"#failed-cluster-deployment-debugging","p":584},{"i":592,"t":"Have a look at the pods that run: kubectl --context=-admin@ get pods -A or have a look at the nodes: kubectl --context=-admin@ get nodes -o wide If you fall into some Kubernetes specific issues after a successful cluster creation, go through the official Kubernetes troubleshooting guide.","s":"Cluster state","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","h":"#cluster-state","p":584},{"i":594,"t":"Etcd is a highly-available key value store used as Kubernetes' backing store for all cluster data. This section contains etcd related maintenance notes from SCS k8s-cluster-api-provider project perspective. For further information about etcd maintenance visit an official etcd maintenance guide and/or Kubernetes etcd operating guide.","s":"Etcd maintenance","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","h":"#etcd-maintenance","p":584},{"i":596,"t":"Etcd storage can become fragmented over time, for this, we have included a maintenance script that regularly defragments and then also backups the database. The script, called etcd-defrag.sh is located in each control plane node's /root directory . It is executed through the systemd service unit file etcd-defrag.service and scheduled to run each day at 02:30:00 using the etcd-defrag.timer systemd timer. The defragmentation strategy is inspired by the etcd-defrag-cronjob and practices recommended by the OpenShift project. Note that the proposed strategy could be changed in a future version based on results from related upstream issue #15477 which wants to define an official solution on how to defragment etcd cluster. The etcd-defrag.sh script checks multiple conditions before the actual defragmentation as follows: The script should not be executed on non leader etcd member The script should not be executed on etcd cluster with some unhealthy member The script should not be executed on single member etcd cluster These pre-flight checks should ensure, that the defragmentation does not cause temporary etcd cluster failures and/or unwanted etcd leader changes. They also prevent executing the script on a single control-plane node cluster. Single-node etcd clusters are not made for long-term operation. As a workaround, however, you can scale up to three control-plane nodes overnight from time to time. After all pre-flight checks passed the etcd cluster defragmentation is performed as follows: Defragment the non leader etcd members first Change the leadership to the randomly selected and defragmentation completed etcd member Defragment the local (ex-leader) etcd member At the end of the defragmentation script, the local (ex-leader) etcd member is backed up and trimmed. Backup is saved and then compressed in the control plane /root directory. You can find it here: /root/etcd-backup.xz. File system trim is performed by the fstrim command that discards unused blocks on a filesystem which could increase write performance on the long run and also release unused storage. Cluster admins are not supposed to log in to the cluster nodes (neither control plane nor workers) and thus won't access or use these backup files. The local backups on these nodes however can prove useful however in a disaster recovery scenario. All mentioned pre-flight checks could be skipped by the optional arguments that force defragmentation despite potential failures. Optional arguments are: --force-single (allows to execute defragmentation on single member etcd cluster) --force-unhealthy (allows to execute defragmentation on unhealthy etcd member) --force-nonleader (allows to execute defragmentation on non leader etcd member) We do not recommend to log in to the cluster nodes let alone executing manual defragmentation using the optional arguments above. If you are aware of potential issues, you can access the control plane node and execute the defragmentation script manually as follows: /root/etcd-defrag.sh [--force-single] [--force-unhealthy] [--force-nonleader]","s":"Defragmentation and backup","u":"/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshooting","h":"#defragmentation-and-backup","p":584},{"i":598,"t":"This document explains the steps to upgrade the SCS Kubernetes cluster-API based cluster management solution as follows: from the R2 (2022-03) to the R3 (2022-09) state from the R3 (2022-09) to the R4 (2023-03) state from the R4 (2023-03) to the R5 (2023-09) state from the R5 (2023-09) to the R6 (2024-03) state The document explains how the management cluster and the workload clusters can be upgraded without disruption. It is highly recommended to do a step-by-step upgrade across major releases i.e. upgrade from R2 to R3 and then to R4 in the case of upgrade from the R2 to the R4. Upgrades across major releases without step-by-step process is not recommended and could lead to undocumented issues. The various steps are not very complicated, but there are numerous steps to take, and it is advisable that cluster operators get some experience with this kind of cluster management before applying this to customer clusters that carry important workloads. Note that while the detailed steps are tested and targeted to an R2 -> R3 move, R3 -> R4 move, R4 -> R5 move or R5 -> R6 move, many of the steps are a generic approach that will apply also for other upgrades, so expect a lot of similar steps when moving beyond R6. Upgrades from cluster management prior to R2 are difficult; many changes before R2 assumed that you would redeploy the management cluster. Redeploying the management cluster can of course always be done, but it's typically disruptive to your workload clusters, unless you move your cluster management state into a new management cluster with clusterctl move.","s":"SCS k8s-cluster-api-provider upgrade guide","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#scs-k8s-cluster-api-provider-upgrade-guide","p":597},{"i":600,"t":"When you initially deployed the SCS k8s-cluster-api-provider, you created a VM with a kind cluster inside and a number of templates, scripts and binaries that are then used to do the cluster management. This is your management host (or more precisely your single-host management cluster). Currently, all cluster management including upgrading etc. is done by connecting to this host via ssh and performing commands there. (You don't need root privileges to do cluster management there, the normal ubuntu user rights are sufficient; there are obviously host management tasks such as installing package updates that do require root power and the user has the sudo rights to do so.) When you create the management host, you have the option to create your first workload cluster. This cluster is no different from other workload clusters that you create by calling commands on the management host, so you can manage it there. (The default name of this cluster is typically testcluster, though that can be changed since a while, #264). On the management host, you have the openstack and kubernetes tools installed and configured, so you can nicely manage all aspects of your CaaS setups as well as the underlying IaaS. The kubectl configuration is in ~/.kube/config while you will find the OpenStack configuration in ~/.config/openstack/clouds.yaml. These files are automatically managed; you can add entries to the files though, and they should persist.","s":"Management host (cluster) vs. Workload clusters","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#management-host-cluster-vs-workload-clusters","p":597},{"i":602,"t":"There are two different possibilities to upgrade the management host. You do a component-wise in-place upgrade of it. You deploy a new management host and clusterctl move the resources over to it from the old one. (Note: Config state in ~/CLUSTER_NAME/) TODO: Advice when to do what, risks, limitations","s":"Updating the management host","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#updating-the-management-host","p":597},{"i":604,"t":"Operating system​ You should keep the host up-to-date with respect to normal operating system upgrades, so perform your normal sudo apt-get update && sudo apt-get upgrade. kubectl, kustomize, yq, lxd and a few other tools are installed as snaps, so you may want to upgrade these as well: sudo snap refresh. From R5 sudo apt-get install -y jq is also required as this is used by the diskless flavors feature, #424. Default operating system image was changed from Ubuntu 20.04 to Ubuntu 22.04 in R4. k8s-cluster-api-provider git​ The automation is deployed on the management host by cloning the relevant git repository. into the k8s-cluster-api-provider directory. Note that the checked out branch will be the one that has been used when creating the management host, and you might want to change branches from maintained/v3.x to maintained/v4.x in case of R2 to R3 upgrade, maintained/v5.x for R3 to R4 upgrade, maintained/v6.x for R4 to R5 upgrade or maintained/v7.x for R5 to R6 upgrade. Use git branch -rl to see available branches in the k8s-cluster-api-provider repository. You can update the scripts and templates by checking out the relevant branch main, maintained/v4.x, maintained/v5.x, maintained/v6.x or maintained/v7.x and using a git pull to ensure the latest content is retrieved. Once you do that, the cluster-management scripts will be up-to-date. (The ~/bin directory in your search PATH is symlinked to the check-ed out scripts.) Note however that the binaries and used templates are NOT automatically updated. This should not normally result in problems -- when new features are introduced in the management scripts, they ensure to continue to support older templates. Updating cluster-API and openstack cluster-API provider​ To get the latest version of cluster-API, you can download a new clusterctl binary from https://github.com/kubernetes-sigs/cluster-api/releases, make it executable chmod +x clusterctl and install it to /usr/local/bin/, possibly saving the old binary by renaming it. clusterctl version should now display the current version number (v1.6.2 at the time of this writing). You can now issue the command clusterctl upgrade plan and clusterctl will list the components in your (kind) management cluster that can be upgraded. Here's an example output: ubuntu@capi-old-mgmtcluster:~ [0]$ clusterctl upgrade plan Checking cert-manager version... Cert-Manager is already up to date Checking new release availability... Latest release available for the v1beta1 API Version of Cluster API (contract): NAME NAMESPACE TYPE CURRENT VERSION NEXT VERSION bootstrap-kubeadm capi-kubeadm-bootstrap-system BootstrapProvider v1.5.1 v1.6.2 control-plane-kubeadm capi-kubeadm-control-plane-system ControlPlaneProvider v1.5.1 v1.6.2 cluster-api capi-system CoreProvider v1.5.1 v1.6.2 infrastructure-openstack capo-system InfrastructureProvider v0.7.3 v0.9.0 You can now apply the upgrade by executing the following command: clusterctl upgrade apply --contract v1beta1 You can then upgrade the components: export CLUSTER_TOPOLOGY=true - this is needed from R5 to R6 upgrade due to ClusterClass feature #600 Upgrade components You can do them one-by-one, e.g.: clusterctl upgrade apply --infrastructure capo-system/openstack:v0.9.0 --core capi-system/cluster-api:v1.6.2 -b capi-kubeadm-bootstrap-system/kubeadm:v1.6.2 -c capi-kubeadm-control-plane-system/kubeadm:v1.6.2 Or simply do clusterctl upgrade apply --contract v1beta1 New templates​ The cluster-template.yaml template used for the workload clusters is located in ~/k8s-cluster-api-provider/terraform/files/template/ and copied from there into ~/cluster-defaults/. Then workload clusters are created, they will also have a copy of it in ~/${CLUSTER_NAME}/. If you have not changed it manually, you can copy it over the old templates. (Consider backing up the old one though.) The next create_cluster.sh run will then use the new template. Note that create_cluster.sh is idempotent -- it will not perform any changes on the cluster unless you have changed its configuration by tweaking cluster-template.yaml (which you almost never do!) or clusterctl.yaml (which you do often). The other template file that changed -- however, some opentofu logic is used to prefill it with values. So you can't copy it from git. R2 to R3​ For going from R2 to R3, there is just one real change that you want to apply: Add the variables CONTROL_PLANE_MACHINE_GEN: genc01 and WORKER_MACHINE_GEN: genw01 to it. If you have copied over the new cluster-template.yaml as described above, then you're done. Otherwise you can use the script update-R2-R3.sh to tweak both clusterctl.yaml and cluster-template.yaml for the relevant cluster. (You can use cluster-defaults to change the templates in ~/cluster-defaults/ which get used when creating new clusters.) R3 to R4​ In the R3 to R4, CALICO_VERSION was moved from .capi-settings to clusterctl.yaml. So before upgrading workload clusters, you must add it also to the ~/${CLUSTER_NAME}/clusterctl.yaml. echo \"CALICO_VERSION: v3.25.0\" >> ~/cluster-defaults/clusterctl.yaml echo \"CALICO_VERSION: v3.25.0\" >> ~/testcluster/clusterctl.yaml In the R3 to R4 upgrade process, cluster-template.yaml changed etcd defrag process in the kubeadm control-planes and also security group names by adding ${PREFIX}- to them, so it has to be changed also in openstack project e.g. (PREFIX=capi): openstack security group set --name capi-allow-ssh allow-ssh openstack security group set --name capi-allow-icmp allow-icmp We changed immutable fields in the Cluster API templates, so before running create_cluster.sh to upgrade existing workload cluster the CONTROL_PLANE_MACHINE_GEN and WORKER_MACHINE_GEN needs to be incremented in cluster specific clusterctl.yaml. In the R3 to R4 process, also cloud.conf added enable-ingress-hostname=true to the LoadBalancer section. It is due to NGINX_INGRESS_PROXY defaulting to true now. So if you want to use, or you are already using this proxy functionality we recommend you to add this line to your cloud.conf, e.g.: echo \"enable-ingress-hostname=true\" >> ~/cluster-defaults/cloud.conf echo \"enable-ingress-hostname=true\" >> ~/testcluster/cloud.conf Then, before upgrading workload cluster by create_cluster.sh, you should delete cloud-config secret in the kube-system namespace, so it can be recreated. E.g.: kubectl delete secret cloud-config -n kube-system --kubeconfig=testcluster/testcluster.yaml Also, the default nginx-ingress version has changed, so we recommend before upgrading cluster to delete ingress-nginx jobs, so new job with new image can be created in the update process. kubectl delete job ingress-nginx-admission-create -n ingress-nginx --kubeconfig=testcluster/testcluster.yaml kubectl delete job ingress-nginx-admission-patch -n ingress-nginx --kubeconfig=testcluster/testcluster.yaml R4 to R5​ In R4 to R5, the cluster-template.yaml and clusterctl.yaml changed (see release notes). You can use script update-R4-to-R5.sh to update the cluster's cluster-template.yaml and clusterctl.yaml from R4 to R5. This script could update an existing Kubernetes cluster configuration files as well as cluster-defaults files that could be used for spawning new R5 clusters. If you want to update an existing cluster configuration files from R4 to R5, just use script as follows: update-R4-to-R5.sh After you executed the above you will find that e.g. Calico version has been bumped from v3.25.0 to v3.26.1. Note that some software versions are not configurable and are not directly mentioned in the cluster configuration files, but they are hardcoded in R5 scripts (e.g. ingress nginx controller, metrics server), see new-defaults section. Note that the Kubernetes version was not updated as well the default CNI is not the Cilium yet. This two R5 features are out of scope this script when it is applied on the existing cluster configuration files as this features require advanced action such as CNI migration and step-by-step Kubernetes upgrade of +2 minor releases. If you want to update cluster-defaults configuration files from R4 to R5, just use script as follows: update-R4-to-R5.sh cluster-defaults The above action updates a cluster-defaults configuration file, which is almost similar to updating an existing cluster configuration file described above. The distinction lies in the fact that both the Kubernetes version and the default CNI are also updated, specifically to Kubernetes version v1.27.5 and Cilium as a default CNI. R5 to R6​ In R5 to R6, the cluster-template.yaml and clusterctl.yaml changed (see release notes). You can use script update-R5-to-R6.sh to update the cluster's cluster-template.yaml and clusterctl.yaml from R5 to R6. This script could update an existing Kubernetes cluster configuration files as well as cluster-defaults files that could be used for spawning new R6 clusters. If you want to update an existing cluster configuration files from R5 to R6, just use script as follows: update-R5-to-R6.sh After you executed the above you will find that e.g. Calico version has been bumped from v3.26.1 to v3.27.2 or Kubernetes version bumped from v1.27.5 to v1.28.7. Note that some software versions are not configurable and are not directly mentioned in the cluster configuration files, but they are hardcoded in R6 scripts (e.g. ingress nginx controller, metrics server, cilium), see new-defaults section. If you want to update cluster-defaults configuration files from R5 to R6, just use script as follows: update-R5-to-R6.sh cluster-defaults If you are curious: In R2, doing rolling upgrades of k8s versions required edits in cluster-template.yaml -- this is no longer the case in R3, R4, R5 and R6. Just increase the generation counter for node and control plane nodes if you upgrade k8s versions -- or otherwise change the worker or control plane node specs, such as e.g. using a different flavor. New defaults​ You deploy a CNI (calico or cilium), the OpenStack Cloud Controller Manager (OCCM), the cinder CSI driver to clusters; optionally also a metrics server (default is true), a nginx ingress controller (also defaulting to true), the flux2 controller, the cert-manager. Some of these tools come with binaries that you can use for management purposes and which get installed on the management host in /usr/local/bin/. The scripts that deploy these components into your workload clusters download the manifests into ~/kubernetes-manifests.d/ with a version specific name. If you request a new version, a new download will happen; already existing versions will not be re-downloaded. Most binaries in /usr/local/bin/ are not stored under a version-specific name. You need to rename them to case a re-download of a newer version. (The reason for not having version specific names is that this would break scripts from users that assume the unversioned names; the good news is that most of these binaries have no trouble managing somewhat older deployments, so you can typically work with the latest binary tool even if you have a variety of versions deployed into various clusters.) The defaults have changed as follows: R2 R3 R4 R5 R6 kind v0.14.0 v0.14.0 v0.17.0 v0.20.0 v0.20.0 capi v1.0.5 v1.2.2 v1.3.5 v1.5.1 v1.6.2 capo v0.5.3 v0.6.3 v0.7.1 v0.7.3 v0.9.0 helm v3.8.1 v3.9.4 v3.11.1 v3.12.3 v3.14.1 sonobuoy v0.56.2 v0.56.10 v0.56.16 v0.56.17 v0.57.1 k9s unversioned unversioned unversioned v0.27.4 v0.31.9 calico v3.22.1 v3.24.1 v3.25.0 v3.26.1 v3.27.2 calico CLI v3.22.1 v3.24.1 v3.25.0 v3.26.1 v3.27.2 cilium unversioned unversioned v1.13.0 v1.14.1 v1.15.1 cilium CLI unversioned unversioned v0.13.1 v0.15.7 v0.15.23 hubble CLI unversioned unversioned v0.11.2 v0.12.0 v0.13.0 nginx-ingress v1.1.2 v1.3.0 v1.6.4 v1.8.1 v1.9.6 flux2 unversioned unversioned v0.40.2 v2.1.0 v2.2.3 cert-manager v1.7.1 v1.9.1 v1.11.0 v1.12.4 v1.14.2 metrics-server v0.6.1 v0.6.1 v0.6.1 v0.6.4 v0.7.0 kubectx v0.9.5 kube-ps1 v0.8.0","s":"In-place upgrade","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#in-place-upgrade","p":597},{"i":606,"t":"To be written Create new management host in same project -- avoid name conflicts with different prefix, to be tweaked later. Avoid testcluster creation Ensure it's up and running ... Tweak prefix Copy over configs (and a bit of state though that's uncritical) by using the directories Copy over the openstack credentials clouds.yaml and the kubectl config clusterctl move","s":"The clusterctl move approach","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#the-clusterctl-move-approach","p":597},{"i":609,"t":"On R2 clusters​ The old way: Editing cluster-template.yaml. Or better use the update-R2-to-R3.sh script to convert first. On R3 and R4 clusters​ Edit ~//clusterctl.yaml and put the wanted version into the fields KUBERNETES_VERSION and OPENSTACK_IMAGE_NAME. The node image will be downloaded from https://minio.services.osism.tech/openstack-k8s-capi-images and registered if needed. (If you have updated the k8s-cluster-api-provider repo, you can use a version v1.NN.x, where you fill in NN with the wanted k8s version, but leave a literal .x which will get translated to the newest tested version.) In the same file, increase the generation counters for CONTROL_PLANE_MACHINE_GEN and WORKER_MACHINE_GEN. Now do the normal create_cluster.sh and watch cluster-api replace your worker nodes and doing a rolling upgrade of your control plane. If you used a 3-node (or 5 or higher) control plane node setup, you will have uninterrupted access not just to your workloads but also the workload's cluster control plane. Use clusterctl describe cluster or simply kubectl --context -admin@ get nodes -o wide to watch the progress of this. On R5 clusters​ If you decide to migrate your existing Kubernetes cluster from R4 to R5 be aware of the following: R5 features such as per cluster namespaces and Cilium as a default CNI are supported only on new clusters and will not be migrated on the existing clusters R4 default Kubernetes version v1.25.6 can not be directly migrated to the R5 default Kubernetes version v1.27.5, because +2 minor Kubernetes version upgrade is not allowed. See further migration steps below if you want to upgrade also Kubernetes version to R5 Follow the below steps if you want to migrate an existing cluster from R4 to R5: Access your management node Checkout R5 branch cd k8s-cluster-api-provider git pull git checkout maintained/v6.x Backup an existing cluster configuration files (recommended) cd .. cp -R -backup Update an existing cluster configuration files from R4 to R5 update-R4-to-R5.sh Validate updated cluster configuration files. You will find that e.g. Calico version has been bumped from v3.25.0 to v3.26.1. Note that some software versions are not configurable and are not directly mentioned in the cluster configuration files, but they are hardcoded in R5 scripts (e.g. ingress nginx controller, metrics server). Hence, read carefully the R5 release notes too. Also see that Kubernetes version was not updated, and it is still v1.25.6. Update an existing cluster (except Kubernetes version) create_cluster.sh Update cluster-API and openstack cluster-API provider, see related section for details clusterctl upgrade plan clusterctl upgrade apply --contract v1beta1 Bump Kubernetes version +1 minor release (to v1.26.8) and increase the generation counter for node and control plane nodes sed -i 's/^KUBERNETES_VERSION: v1.25.6/KUBERNETES_VERSION: v1.26.8/' /clusterctl.yaml sed -i 's/^OPENSTACK_IMAGE_NAME: ubuntu-capi-image-v1.25.6/OPENSTACK_IMAGE_NAME: ubuntu-capi-image-v1.26.8/' /clusterctl.yaml sed -r 's/(^CONTROL_PLANE_MACHINE_GEN: genc)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i /clusterctl.yaml sed -r 's/(^WORKER_MACHINE_GEN: genw)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i /clusterctl.yaml Update an existing cluster Kubernetes version to v1.26.8 create_cluster.sh Bump Kubernetes version to R5 v1.27.5 and increase the generation counter for node and control plane nodes sed -i 's/^KUBERNETES_VERSION: v1.26.8/KUBERNETES_VERSION: v1.27.5/' /clusterctl.yaml sed -i 's/^OPENSTACK_IMAGE_NAME: ubuntu-capi-image-v1.26.8/OPENSTACK_IMAGE_NAME: ubuntu-capi-image-v1.27.5/' /clusterctl.yaml sed -r 's/(^CONTROL_PLANE_MACHINE_GEN: genc)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i /clusterctl.yaml sed -r 's/(^WORKER_MACHINE_GEN: genw)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i /clusterctl.yaml Update an existing cluster to the R5 Kubernetes version v1.27.5 create_cluster.sh On R6 clusters​ If you decide to migrate your existing Kubernetes cluster from R5 to R6 be aware of the following: Kubernetes version will be upgraded from v1.27.5 to v1.28.7 You have to migrate from Cluster based templates to ClusterClass based templates Upgrade of cilium needs to be done manually (for clusters with USE_CILIUM: true) Follow the below steps if you want to migrate an existing cluster from R5 to R6: Access your management node Checkout R6 branch cd k8s-cluster-api-provider git pull git checkout maintained/v7.x Backup an existing cluster configuration files (recommended) cd .. cp -R -backup Update an existing cluster configuration files from R5 to R6 update-R5-to-R6.sh Validate updated cluster configuration files. You will find that e.g. Calico version has been bumped from v3.26.1 to v3.27.2 or Kubernetes version bumped from v1.27.5 to v1.28.7. Note that some software versions are not configurable and are not directly mentioned in the cluster configuration files, but they are hardcoded in R6 scripts (e.g. ingress nginx controller, metrics server, cilium). Hence, read carefully the R6 release notes too. Update cluster-API and openstack cluster-API provider, see related section for details clusterctl upgrade plan export CLUSTER_TOPOLOGY=true clusterctl upgrade apply --contract v1beta1 Migrate to ClusterClass migrate-to-cluster-class.sh Increase the generation counter for worker and control plane nodes sed -r 's/(^CONTROL_PLANE_MACHINE_GEN: genc)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i /clusterctl.yaml sed -r 's/(^WORKER_MACHINE_GEN: genw)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i /clusterctl.yaml Update an existing cluster to the R6 create_cluster.sh Note: You will probably experience a double rollout of nodes because the k8s version and templates are changed concurrently here. See https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-class/operate-cluster#effects-of-concurrent-changes Upgrade cilium (for clusters with USE_CILIUM: true) KUBECONFIG=/.yaml bash -c 'helm get values cilium -n kube-system -o yaml | cilium upgrade --version v1.15.1 -f -'","s":"k8s version upgrade","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#k8s-version-upgrade","p":597},{"i":611,"t":"OCCM, CNI (calico/cilium), CSI","s":"New versions for mandatory components","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#new-versions-for-mandatory-components","p":597},{"i":613,"t":"nginx, metrics server, cert-manager, flux","s":"New versions for optional components","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#new-versions-for-optional-components","p":597},{"i":615,"t":"While testing clusters with >= 3 control nodes, we have observed occasional transient error messages that reported an etcd leader change preventing a command from succeeding. This could result in a dozen of random failed tests in a sonobuoy conformance run. (Retrying the commands would let them succeed.) Too frequent etcd leader changes are detrimental to your control plane performance and can lead to transient failures. They are a sign that the infrastructure supporting your cluster is introducing too high latencies. We recommend to deploy the control nodes (which run etcd) on instances with local SSD storage (which we reflect in the default flavor name) and recommend using flavors with dedicated cores and that your network does not introduce latencies by significant packet drop. We now always use slower heartbeat (250ms) and increase CPU and IO priority which used to be controlled by ETCD_PRIO_BOOST. This is safe. If you build multi-controller clusters and can not use a flavor with low latency local storage (ideally SSD), you can also work around this with ETCD_UNSAFE_FS. ETCD_UNSAFE_FS is using barrier=0 mount option, which violates filesystem ordering guarantees. This works around storage latencies, but introduces the risk of inconsistent filesystem state and inconsistent etcd data in case of an unclean shutdown. You may be able to live with this risk in a multi-controller etcd setup. If you don't have flavors that fulfill the requirements (low-latency storage attached), your choice is between a single-controller cluster (without ETCD_UNSAFE_FS) and a multi-controller cluster with ETCD_UNSAFE_FS. Neither option is perfect, but we deem the multi-controller cluster preferable in such a scenario.","s":"etcd leader changes","u":"/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guide","h":"#etcd-leader-changes","p":597},{"i":617,"t":"Cluster API requires an existing Kubernetes cluster to operate. In our setup, we utilize kind a tool for running Kubernetes clusters using Docker containers, to create the initial management Kubernetes cluster in a single docker container. The OpenStack instance serves as the CAPI management server or management cluster, responsible for overseeing the management and operation of the created kubernetes clusters. The provisioning of the CAPI management server is done on a deployment host, possibly a tiny jumphost style VM, or some Linux/MacOS/WSL laptop. Requirements for the deployment host: You need to have installed: OpenTofu yq (python3-yq or yq snap) GNU make openstack (python3-openstackclient) and plugin for octavia (python3-octaviaclient) Via pip or your distribution. Needed only in case you want to clean the management server or interact with openstack directly. You must have credentials to access the cloud. OpenTofu will look for clouds.yaml and optionally secure.yaml in the current working directory (terraform), in ~/.config/openstack/ or /etc/openstack (in this order), just like the openstack client. The API endpoints of the OpenStack cloud should have a certificate signed by a trusted CA. (Self-signed or custom CAs need significant manual work -- this will be improved after R4.) An Environment file for the cloud you want to use. See Environments below for more details.","s":"Requirements","u":"/docs/container/components/k8s-cluster-api-provider/doc/requirements","h":"","p":616},{"i":619,"t":"To use a specific environment, you have to set the ENVIRONMENT variable (export ENVIRONMENT=) or pass it to the make command by using make ENVIRONMENT=. You can also do the same by utilizing the OS_CLOUD (openstack native) variable. The name of the environment is derived from the name of the file environments/environment-.tfvars. The name of the environment specified either via ENVIRONMENT or OS_CLOUD has to be equal the name of the cloud (cloud_provider) as specified in your clouds.yaml. In case you use plusserver community environment or wavestack environment you can use the default environment file for those directly or base your configuration on it. In case you need custom configuration see Custom environment. More information about the configuration options can be found in the configuration documentation.","s":"Environments","u":"/docs/container/components/k8s-cluster-api-provider/doc/requirements","h":"#environments","p":616},{"i":621,"t":"Using it directly: export ENVIRONMENT=gx-scs or insert inside of Makefile: ENVIRONMENT=gx-scs File: environments/environment-gx-scs.tfvars The name of the cloud has to be gx-scs in the cloud.yaml file, otherwise you will need to change the cloud_provider variable inside of terraform/environments/environment-gx-scs.tfvars file.","s":"Plusserver community environment","u":"/docs/container/components/k8s-cluster-api-provider/doc/requirements","h":"#plusserver-community-environment","p":616},{"i":623,"t":"Using it directly: export ENVIRONMENT=gx-wavestack or insert inside of Makefile: ENVIRONMENT=gx-wavestack File: environments/environment-gx-wavestack.tfvars The name of the cloud has to be gx-wavestack in the cloud.yaml file, otherwise you will need to change the cloud_provider variable inside of terraform/environments/environment-gx-scs.tfvars file.","s":"Wavestack environment","u":"/docs/container/components/k8s-cluster-api-provider/doc/requirements","h":"#wavestack-environment","p":616},{"i":625,"t":"You can create your own environment file from the sample file environments/environment-default.tfvars and provide the necessary information like machine flavor or machine image. You can comment out all lines where the defaults match your needs.","s":"Custom environment","u":"/docs/container/components/k8s-cluster-api-provider/doc/requirements","h":"#custom-environment","p":616},{"i":627,"t":"You can use make ssh to log in to the capi management server. There you can issueclusterctl and kubectl (aliased to k) commands. The context kind-kind is used for the CAPI management while the context testcluster-admin@testcluster can be used to control the workload cluster testcluster. You can of course create many of them. There are management scripts on the management server: In the user's (ubuntu) home directory, create a subdirectory with the CLUSTERNAME to hold your cluster's configuration data. Copy over the clusterctl.yaml file from ~/cluster-defaults/ and edit it to meet your needs. Note that you can also copy over cloud.conf and cluster-template.yaml and adjust them, but you don't need to. (If you don't create the subdirectory, the create_cluster.sh script will do so for you and use all defaults settings.) create_cluster.sh CLUSTERNAME: Use this command to create a cluster with the settings from ~/$CLUSTERNAME/clusterctl.yaml. More precisely, it uses the template $CLUSTERNAME/cluster-template.yaml and fills in the settings from $CLUSTERNAME/clusterctl.yaml to render a config file $CLUSTERNAME/$CLUSTERNAME-config.yaml which will then be submitted to the capi server (kind-kind context) for creating the control plane nodes and worker nodes. The script will also apply openstack integration, cinder CSI, calico or cilium CNI, and optionally also metrics server, nginx ingress controller, flux, cert-manager. (These can be controlled by DEPLOY_XXX variables, see below. Defaults can be preconfigured from the environment.tfvars file during management server creation.) Note that CLUSTERNAME defaults to testcluster and must not contain whitespace. The script also makes sure that appropriate CAPI images are available (it grabs them from OSISM as needed and registers them with OpenStack, following the SCS image metadata standard). The script returns once the control plane is fully working (the worker nodes might still be under construction). The kubectl file to talk to this cluster (as admin) can be found in ~/$CLUSTERNAME/$CLUSTERNAME.yaml. Expect the cluster creation to take ~8mins. (CLUSTERNAME defaults to testcluster.) You can pass --context=${CLUSTERNAME}-admin@$CLUSTERNAME to kubectl (with the default ~/.kubernetes/config config file) or export KUBECONFIG=$CLUSTERNAME.yaml to talk to the workload cluster. The subdirectory ~/$CLUSTERNAME/deployed-manifests.d/ will contain the deployed manifests for reference (and in case of nginx-ingress also to facilitate a full cleanup). The clusterctl.yaml file can be edited the create_cluster.sh script be called again to submit the changes. (If you have not done any changes, re-running the script again is harmless.) Note that the create_cluster.sh does not currently remove any of the previously deployed services/deployments from the workload clusters -- this will be added later on with the appropriate care and warnings. Also note that not all changes are allowed. You can easily change the number of nodes or add k8s services to a cluster. For changing machine flavors, machine images, kubernetes versions ... you will need to also increase the CONTROL_PLANE_MACHINE_GEN or the WORKER_MACHINE_GEN counter to add a different suffix to these read-only resources. This will cause Cluster-API to orchestrate a rolling upgrade for you on rollout. (This is solved more elegantly in the helm chart style cluster management, see below.) The directory ~/k8s-cluster-api-provider/ contains a checked out git tree from the SCS project. It can be updated (git pull) to receive the latest fixes and improvements. This way, most incremental updates do not need the recreation of the management server (and thus also not the recreation of your managed workload clusters), but can be applied with calling create_cluster.sh again to the workload clusters. The installation of the openstack integration, cinder CSI, metrics server and nginx ingress controller is done via the bin/apply_*.sh scripts that are called from create_cluster.sh. You can manually call them as well -- they take the cluster name as argument. (It's better to just call create_cluster.sh again, though.) The applied yaml files are collected in ~/$CLUSTERNAME/deployed-manifests.d/. You can kubectl delete -f them to remove the functionality again. You can, of course, also delete the cluster and create a new one if that level of disruption is fine for you. (See below in Advanced cluster templating with helm to get an idea how we want to make this more convenient in the future.) Use kubectl get clusters -A in the kind-kind context to see what clusters exist. Use kubectl get all -A in the testcluster-admin@testcluster context to get an overview over the state of your workload cluster. You can access the logs from the capo controller in case you have trouble with cluster creation. delete_cluster.sh [CLUSTERNAME]: Tell the capi management server to remove the cluster $CLUSTERNAME. It will also remove persistent volume claims belonging to the cluster. The script will return once the removal is done. cleanup.sh: Remove all running clusters. add_cluster-network.sh CLUSTERNAME adds the management server to the node network of the cluster CLUSTERNAME, assuming that it runs on the same cloud (a region). remove_cluster-network.sh undoes this again. This is useful for debugging purposes. For your convenience, k9s is installed on the management server as well as calicoctl, cilium, hubble, cmctl, helm and sonobuoy. These binaries can all be found in /usr/local/bin while the helper scripts have been deployed to ~/bin/.","s":"Cluster Management on the capi management node","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-node","h":"","p":626},{"i":629,"t":"The subsequent management of the cluster can best be done from the management server VM, as it has all the tools deployed there and config files can be edited and resubmitted to the kubernetes kind cluster for reconciliation. To log in to this management server via ssh, you can issue make ssh. You can create and do life cycle management for many more clusters from this management server. The kubeconfig with admin power for the created testcluster is named testcluster/testcluster.yaml ( or $CLUSTER_NAME/$CLUSTER_NAME.yaml for all the other clusters) and can be handed out to users that should get full administrative control over the cluster. You can also retrieve them using make get-kubeconfig TESTCLUSTER=${CLUSTER_NAME} from the machines where you created the management server from, and possibly create an encrypted .zip file for handing these out. (You can omit TESTCLUSTER=... for the default testcluster.)","s":"Usage","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/","h":"","p":628},{"i":631,"t":"On the management server (login with make ssh), create a directory (below the home of the standard ubuntu user) with the name of your cluster. Copy over clusterctl.yaml from ~/cluster-defaults/ and edit it according to your needs. You can also copy over other files from ~/cluster-defaults/ and adjust them, but this is only needed in exceptional cases. Now run create_cluster.sh This will copy all missing defaults from ~/cluster-defaults/ into the directory with your cluster name and then ask cluster-api to create the cluster. The scripts also take care of security groups, anti-affinity, node image registration (if needed) and of deploying CCM, CNI, CSI as well as optional services such as metrics or nginx-ingress controller. You can access the new cluster with kubectl --context clustername-admin@cluster or KUBECONFIG=~/clustername/clustername.yaml kubectl. The management cluster is in context kind-kind. Note that you can always change clusterctl.yaml and re-run create_cluster.sh. The script is idempotent and running it multiple times with the unchanged input file will result in no changes to the cluster.","s":"Create a new cluster","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-cluster","h":"","p":630},{"i":633,"t":"Containerd as container runtime interface (CRI) used in the reference SCS KaaS implementation allows configuring its behavior when it interacts with public or private container registry hosts. Container registry hosts configuration options in containerd are well described in related docs. This feature could be useful in various uses cases, e.g.: Configure containerd to use a custom CA certificate when it interacts with a container registry host that uses this CA Configure containerd to use some container registry mirror host instead of the target public or private container registry. This could be useful when the target container registry somehow restricts its clients e.g. DockerHub's pull rate limit to 100 pulls per 6 hours per IP address SCS KaaS reference implementation allows users to pass container registry host config files to configure containerd. Containerd configuration is applied cluster wide as it is CRI used in SCS KaaS clusters. Additional registry host config files for containerd could be passed through the containerd_registry_files opentofu variable. This variable expects an object with two attributes: hosts attribute defines additional registry host config files for containerd. The filename should reference the registry host namespace. Files defined in this set will be copied into the /etc/containerd/certs.d directory on each workload cluster node certs attribute defines additional client and/or CA certificate files needed for containerd authentication against registries defined by hosts. Files defined in this set will be copied into the /etc/containerd/certs directory on each workload cluster node The default value of the containerd_registry_files variable instructs containerd to use registry.scs.community container registry instance as a public mirror of DockerHub container registry, see related issue #417. The host config file used as a default is defined here. This should prevent issues with pull rate limiting from DockerHub public container registry, e.g. #414. The above default value could be overridden using any techniques that OpenTofu allows, e.g. via environment variable: export TF_VAR_containerd_registry_files='{\"hosts\":[\"\"], \"certs\":[\"\"]}' SCS container registry reference installation https://registry.scs.community contains several pre-configured \"proxy-cache\" projects. These projects allow you to use SCS container registry reference installation to proxy and cache images from target public registries. This may reduce the load of overused public container registries and/or helps to avoid rate limiting by individual public registries. Currently, SCS container registry is set up to \"proxy-cache\" the following public container registries: docker.io ghcr.io quay.io registry.gitlab.com registry.k8s.io Find also a corresponding containerd registry host config files in ./terraform/files/containerd directory. If you want to configure containerd to use mentioned pre-configured SCS container registry \"proxy cache\" projects, feel free to do that e.g. as follows (path is relative to the terraform directory): export TF_VAR_containerd_registry_files='{\"hosts\":[\"./files/containerd/docker.io\", \"./files/containerd/ghcr.io\", \"./files/containerd/quay.io\", \"./files/containerd/registry.gitlab.com\", \"./files/containerd/registry.k8s.io\" ]}' If you did not find your preferred public container registry in the list of pre-configured SCS container registry \"proxy cache\" projects, and you would like to use the SCS container registry as a mirror for it, please open an issue in one of the following repositories: scs/k8s-cluster-api-provider, scs/k8s-harbor.","s":"Container registry configuration","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration","h":"","p":632},{"i":635,"t":"This tutorial is experimental and out of the usual release cycle. We recommend to upgrade existing environments (workload clusters) with stable releases which are properly tested. This tutorial instructs (advanced) users what needs to be done on the cluster management instance without re-deploying it via OpenTofu. Patches described in this tutorial modify existing environment with changes that have been developed within \"containerd registry\"-related PRs: PR#432 PR#447 PR#472 Warning: This tutorial causes a rolling update (rolling re-deployment) of the control plane and worker nodes. Log in to the cluster management instance, pull remote changes, and then checkout to relevant commit that includes all mentioned PRs. cd k8s-cluster-api-provider/ git pull git checkout b31a79db26c3956b473f026038e71e9aba7819b8 Backup the config directory of an existing cluster. cd .. cp -R .bkp Ensure that the directory for containerd registry configs exists and create a default containerd registry config file that instructs containerd to use registry.scs.community container registry instance as a public mirror of DockerHub. Optionally, create another containerd container registry host file in the containerd/hosts directory. You can find working examples of those files here. cd mkdir -p containerd/hosts cat >containerd/hosts/docker.io < Inject containerd configuration in cluster-template.yaml. This configuration allows containerd to discover registry host file(s). Create containerd_conf_append temp file cat >containerd_conf_append <> /etc/containerd/config.toml [plugins.\"io.containerd.grpc.v1.cri\".registry] config_path = \"/etc/containerd/certs.d\" EOT EOF Inject temp file and systemctl restart containerd.service line into the cluster-template.yaml (inplace) yq 'select(.kind == \"KubeadmControlPlane\").spec.kubeadmConfigSpec.preKubeadmCommands |= ( (.[] | select(. == \"apt-get install -y ca-certificates socat*\") | key + 1) as $pos | .[:$pos] + [load_str(\"containerd_conf_append\")] + .[$pos:])' -i cluster-template.yaml yq 'select(.kind == \"KubeadmControlPlane\").spec.kubeadmConfigSpec.preKubeadmCommands |= ( (.[] | select(. == \"systemctl daemon-reload\") | key + 1) as $pos | .[:$pos] + [\"systemctl restart containerd.service\"] + .[$pos:])' -i cluster-template.yaml yq 'select(.kind == \"KubeadmConfigTemplate\").spec.template.spec.preKubeadmCommands |= ( (.[] | select(. == \"apt-get install -y ca-certificates socat*\") | key + 1) as $pos | .[:$pos] + [load_str(\"containerd_conf_append\")] + .[$pos:])' -i cluster-template.yaml yq 'select(.kind == \"KubeadmConfigTemplate\").spec.template.spec.preKubeadmCommands |= ( (.[] | select(. == \"systemctl daemon-reload\") | key + 1) as $pos | .[:$pos] + [\"systemctl restart containerd.service\"] + .[$pos:])' -i cluster-template.yaml The above changes (when point 8. will be applied) of KubeadmControlPlane will cause a rolling update of control plane nodes. As the KubeadmConfigTemplate has been adjusted we need to increase the generation counter of worker machines to ensure that the worker nodes will be rolling updated as well. sed -r 's/(^WORKER_MACHINE_GEN: genw)([0-9][0-9])/printf \"\\1%02d\" $((\\2+1))/ge' -i clusterctl.yaml Workaround: If your environment contains nginx ingress deployed via k8s-cluster-api-provider (variable DEPLOY_NGINX_INGRESS=true) disable its update. Nginx-ingress controller has been updated to version 1.8.0 in PR#440 and later to 1.8.1. This is a breaking change that includes updates of immutable fields. If the above is the case skip this update as follows: sed 's/DEPLOY_NGINX_INGRESS: true/DEPLOY_NGINX_INGRESS: false/g' -i clusterctl.yaml Update the existing cluster. create_cluster.sh test1","s":"Tutorial: configure an existing cluster to use containerd registry configuration","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configuration","h":"#tutorial-configure-an-existing-cluster-to-use-containerd-registry-configuration","p":632},{"i":637,"t":"Starting with R5, this k8s-solution offers experimental kubernetes gateway API support. You need to set deploy_gateway_api to true in your environments configuration. Also you need to use cilium as your CNI (default since R5). After deploying your cluster, you can use gateway API and deploy Gateways and HTTP-Routes. As a starting point you can deploy this example app: kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/bookinfo/platform/kube/bookinfo.yaml and this example Gateway and HTTP-Route kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.15.1/examples/kubernetes/gateway/basic-http.yaml","s":"Gateway-API","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-api","h":"","p":636},{"i":639,"t":"Project k8s-harbor is used for the SCS Harbor container registry deployment https://registry.scs.community/. With this project, it is possible to deploy Harbor in a similar way into the workload cluster. If you want to deploy Harbor, set opentofu variable deploy_harbor = true. It will deploy Harbor with default options. The recommended approach is to set up also persistence and ingress with tls. It automatically deploys flux as k8s-harbor requirement. It also expects that the Swift object store is available in the targeting OpenStack project. S3 credentials (openstack ec2 credentials create) are created and saved into ~/$CLUSTER_NAME/deployed-manifests.d/harbor/.ec2. Bucket (openstack container create \"$PREFIX-$CLUSTER_NAME-harbor-registry\") for storing container images is also automatically created in the openstack Swift object store. Warning: Swift container and ec2 credentials are not removed when the workload cluster is deleted.","s":"Harbor","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor","h":"","p":638},{"i":641,"t":"By default, Harbor will be deployed with these options: harbor_config = { domain_name: \"\", issuer_email: \"\", persistence: false, database_size: \"1Gi\", redis_size: \"1Gi\", trivy_size: \"5Gi\" } These options are templated to the mgmt server and used as environment variables during the creation of the workload cluster: $ cat ~/cluster-defaults/harbor-settings DEPLOY_HARBOR=true HARBOR_DATABASE_SIZE=1Gi HARBOR_DOMAIN_NAME= HARBOR_ISSUER_EMAIL= HARBOR_PERSISTENCE=false HARBOR_REDIS_SIZE=1Gi HARBOR_TRIVY_SIZE=5G When the Harbor is deployed, you can check the status, e.g. by: $ flux get helmrelease -n default NAME REVISION SUSPENDED READY MESSAGE harbor 1.12.4 False True Release reconciliation succeeded or you can simply check if pods are running by kubectl get pods. Harbor components are deployed as deployments and statefulsets: $ kubectl get deploy,sts NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/harbor-core 2/2 2 2 11m deployment.apps/harbor-exporter 1/1 1 1 11m deployment.apps/harbor-jobservice 2/2 2 2 11m deployment.apps/harbor-nginx 1/1 1 1 11m deployment.apps/harbor-portal 2/2 2 2 11m deployment.apps/harbor-registry 2/2 2 2 11m NAME READY AGE statefulset.apps/harbor-database 1/1 11m statefulset.apps/harbor-redis 1/1 11m statefulset.apps/harbor-trivy 2/2 11m Default options deploy Harbor as clusterIP service without pvc persistence for database, redis and trivy. See terraform/files/kubernetes-manifests.d/harbor/envs/clusterIP/ for further details. You can access it via the k8s service harbor, for example, port-forward it and access it at http://localhost:8080: $ kubectl get svc harbor -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR harbor ClusterIP 10.109.57.148 80/TCP 11m app=harbor,component=nginx,release=harbor $ kubectl port-forward svc/harbor 8080:80 Forwarding from 127.0.0.1:8080 -> 8080 Forwarding from [::1]:8080 -> 8080 Admin username is admin and password can be obtained from the secret by: kubectl get secret harbor-secrets -o jsonpath='{.data.values\\.yaml}' | base64 -d | yq .harborAdminPassword","s":"Default deployment","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor","h":"#default-deployment","p":638},{"i":644,"t":"By default, persistence is set to false. When persistence is set to true, i.e. harbor_config = {persistence: true}, Harbor components (database, redis, trivy) are deployed with PVCs: $ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-harbor-redis-0 Bound pvc-982221c1-64cb-4d3e-a77d-1db5b4429a69 1Gi RWO cinder-default 6m12s data-harbor-trivy-0 Bound pvc-8a2ad60c-c7bf-40e1-8593-0d00b3d40b4f 5Gi RWO cinder-default 6m12s data-harbor-trivy-1 Bound pvc-734f9b6a-9cee-40e4-9e1c-b959d9f7b7cf 5Gi RWO cinder-default 5m11s database-data-harbor-database-0 Bound pvc-c5c3a7e6-a99a-4f16-a5cc-792e9b3665d8 1Gi RWO cinder-default 6m12s The size of PVCs can be configured by harbor_config = {_size: \"size\"}. Trivy has 2 replicas, i.e. 2 PVCs will be created. When persistence is set to true, Cinder CSI is automatically deployed.","s":"Persistence","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor","h":"#persistence","p":638},{"i":646,"t":"If you want to deploy ingress in front of Harbor and secure it with SSL/TLS certificate, set the domain_name option. Relevant files which will be deployed are located in terraform/files/kubernetes-manifests.d/harbor/envs/ingress/. When domain_name is set, cert-manager and ingress-nginx are automatically deployed. So, instead of default harbor clusterIP service and harbor-nginx deployment, harbor-ingress will be deployed: $ kubectl get ing harbor-ingress NAME CLASS HOSTS ADDRESS PORTS AGE harbor-ingress nginx harbor.example.com 213.131.230.203.nip.io 80, 443 13m There will be also an additional cert-manager issuer letsencrypt deployed: $ kubectl get issuers -o wide NAME READY STATUS AGE letsencrypt True The ACME account was registered with the ACME server 13m This ACME issuer has an optional email field, which can be set by issuer_email option. This is recommended option because it will be used to contact you in case of issues with your account or certificates, including expiry notification emails. Then, the settings can look like this: harbor_config = { domain_name: \"harbor.example.com\", issuer_email: \"email@example.com\", } After the deployment, there is one mandatory step to set up proper TLS communication with this Harbor instance. harbor-ingress has special annotation cert-manager.io/issuer: letsencrypt which instructs cert-manager to create a certificate object: $ kubectl get cert -o wide NAME READY SECRET ISSUER STATUS AGE harbor-crt False harbor-crt letsencrypt Issuing certificate as Secret does not exist 13m The certificate is not ready, because it uses Let’s Encrypt standard ACME HTTP-01 challenge. In this challenge, you need to take the IP address of the ingress load balancer and create a DNS record for your domain_name. You can get an IP address (don't look on nip.io suffix) e.g. by this command: $ kubectl -n ingress-nginx get svc ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress}' [{\"hostname\":\"213.131.230.203.nip.io\"}] And after a while, your cert is ready, and you can access harbor at https://harbor.example.com/: $ kubectl get cert -o wide NAME READY SECRET ISSUER STATUS AGE harbor-crt True harbor-crt letsencrypt Certificate is up to date and has not expired 18m","s":"Ingress and TLS","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/harbor","h":"#ingress-and-tls","p":638},{"i":648,"t":"While the scripts all use a default testcluster, they have been developed and tested to manage many clusters from a single management node. Copy the ~/cluster-defaults/clusterctl.yaml file to ~/MYCLUSTER/clusterctl.yaml and edit the copy to describe the properties of the cluster to be created. Use ./create_cluster.sh MYCLUSTER then to create a workload cluster with the name MYCLUSTER. You will find the kubeconfig file in ~/MYCLUSTER/MYCLUSTER.yaml, granting its owner admin access to that cluster. Likewise, delete_cluster.sh and the apply_*.sh scripts take a cluster name as parameter. This way, dozens of clusters can be controlled from one management server. You can add credentials from different projects into ~/.config/openstack/clouds.yaml and reference them in the OPENSTACK_CLOUD setting in clusterctl.yaml, this way managing clusters in many different projects and even clouds from one management server.","s":"Managing many clusters","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clusters","h":"","p":647},{"i":650,"t":"OpenStack provides public-facing API endpoints which protection by SSL/TLS certificates is highly recommended in production environments. These certificates are usually issued by public CA but also the custom or private CA could be used. If the communication with OpenStack API is protected by the certificate issued by custom CA the cacert setting needs to be provided inside clouds.yaml, e.g.: clouds: devstack: cacert: ca-bundle.pem auth: auth_url: https://10.0.3.15/identity project_domain_id: default project_name: demo user_domain_id: default identity_api_version: 3 region_name: RegionOne interface: public Here the file ca-bundle.pem contains custom root CA and potentially intermediate CA(s). The ca-bundle.pem file will be copied to the management server and used by CAPO in the management cluster. Also, it will be copied to the workload cluster (control plane and worker nodes) and mounted and used by OCCM and CCSI pods. So provide only the necessary certificates in that file. Steps of what happens with the custom cacert in k8s-cluster-api-provider: cacert setting is provided inside clouds.yaml Cacert file referenced by cacert key (1.) is copied to the management server directory ~/cluster-defaults/${cloud_provider}-cacert by OpenTofu During the management server bootstrap process cacert is injected to the ~/cluster-defaults/cluster-template.yaml to KubeadmControlPlane and KubeadmConfigTemplate files as file with cacert content from already defined secret ${CLUSTER_NAME}-cloud-config and will be later templated and copied to the workload cluster (control plane and worker nodes) provisioned by CAPO, e.g.: files: - contentFrom: secret: key: cacert name: ${CLUSTER_NAME}-cloud-config owner: root:root path: /etc/ssl/certs/devstack-cacert permissions: \"0644\" When the creation of the workload cluster (create_cluster.sh) starts, ~/cluster-defaults/cluster-template.yaml is copied into workload cluster directory (~/$CLUSTER_NAME/) Then the cacert file content is base64 encoded and saved in OPENSTACK_CLOUD_CACERT_B64 variable inside ~/$CLUSTER_NAME/clusterctl.yaml, so it can be used during the workload cluster templating Later, when the workload cluster templates are applied to the management cluster, secret ${CLUSTER_NAME}-cloud-config with base64 encoded cacert is created and used by CAPO CAPO will create workload cluster (thanks to steps 5. and 6.) and cacert is transferred to the control plane and worker nodes (thanks to steps 3. and 4.) OCCM and CCSI pods mount cacert via hostPath volume and use it for e.g. creating load balancers or volumes","s":"Custom CA","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca","h":"","p":649},{"i":652,"t":"When the custom CA expires or otherwise changes it needs to be rotated. CAPO uses the custom CA certificate in the management cluster for creating the infrastructure for the workload clusters and in the workload clusters by OCCM and CCSI for e.g. creating load balancers or volumes. In both cases, cacert is provided via secret ${CLUSTER_NAME}-cloud-config and needs to be updated. There are 3 steps in this rotation process: Replace/append custom CA certificate in ~/cluster-defaults/${cloud_provider}-cacert Increase generation counters CONTROL_PLANE_MACHINE_GEN and WORKER_MACHINE_GEN in ~/$CLUSTER_NAME/clusterctl.yaml Run create_cluster.sh $CLUSTER_NAME and wait for the rolling update of your workload cluster In step 1, appending can be useful for avoiding downtime of your services. Your cacert file will contain two CA certificates - old and new. This should help with a smooth transition to a new certificate and later, the old one can be removed. Steps 2 and 3 need to be done per workload cluster. When step 2 is omitted, only cacert secret in the management cluster is updated and no rolling update of the workload cluster in step 3 is started and existing nodes remain with the old certificate.","s":"Rotation","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-ca","h":"#rotation","p":649},{"i":654,"t":"The provided cluster-template.yaml assumes that all control nodes on one hand and all worker nodes on the other are equal. They are in the same cloud within the same availability zone, using the same flavor. cluster API allows k8s clusters to have varying flavors, span availability zones and even clouds. For this, you can create an advanced cluster-template with more different machine descriptions and potentially several secrets. Depending on your changes, the logic in create_cluster.sh might also need enhancements to handle this. Extending this is not hard and we're happy to hear from your use cases and take patches. However, we are currently investigating to use helm templating for anything beyond the simple use cases instead, see next chapter.","s":"Multi-AZ and multi-cloud environments","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environments","h":"","p":653},{"i":656,"t":"From R6, k8s-cluster-api-provider repository (SCS KaaS reference implementation v1) is deprecated and should not be used for new deployments. We intend to remove it with the next release (R7). Therefore, it is recommended to migrate to Cluster Stacks - SCS KaaS reference implementation v2. For list of known issues and in restrictions KaaS v2 see SCS R6 Release Notes. We will try to address most of the gaps during the next release cycle (R7).","s":"Migration to KaaS v2","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2","h":"","p":655},{"i":658,"t":"In R6, we migrated to ClusterClass feature to ease the migration to KaaS v2, because Cluster Classes are the main component there. So this guide will work only on release >= R6 (use upgrade guide first, when you are on release < R6). Warning: This guide supports only cilium CNI (the only CNI Cluster Addon in KaaS v2) Warning: After the migration, create_cluster.sh and other KaaS v1 scripts and features should not be used anymore","s":"Migration","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2","h":"#migration","p":655},{"i":660,"t":"Deploy KaaS v1, e.g.: cloud_provider = \"gx-scs\" availability_zone = \"nova\" controller_flavor = \"SCS-2V-4\" worker_flavor = \"SCS-2V-4\" dns_nameservers = [\"62.138.222.111\", \"62.138.222.222\"] Deploy CSO and CSPO: deploy with make (access token optional and recommended) make deploy-cso GIT_ACCESS_TOKEN= make deploy-cspo GIT_ACCESS_TOKEN= Export ${PREFIX} and ${CLUSTER_NAME}: . ~/bin/cccfg.inc Patch secret with cloudName: kubectl patch secret -n ${CLUSTER_NAME} ${CLUSTER_NAME}-cloud-config -p '{\"stringData\":{\"cloudName\":\"'\"${PREFIX}-${CLUSTER_NAME}\"'\"}}' Create Cluster Stack: kubectl -n ${CLUSTER_NAME} apply -f - <= v1.5.2 due to NamingStrategy feature upgrade can be performed as stated in upgrade guide","s":"Prerequisites","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class","h":"#prerequisites","p":661},{"i":667,"t":"Git pull/checkout new changes into the ~/k8s-cluster-api-provider directory Run migrate-to-cluster-class.sh (verify machines were not recreated) Copy new templates for existing and new clusters (consider backup) cp ~/k8s-cluster-api-provider/terraform/files/template/cluster-template.yaml ~//cluster-template.yaml cp ~/k8s-cluster-api-provider/terraform/files/template/cluster-template.yaml ~/cluster-defaults/cluster-template.yaml Add the newly introduced generation counter for the OpenStackClusterTemplate to the settings in clusterctl.yaml echo \"OPENSTACK_CLUSTER_GEN: geno01\" >> ~//clusterctl.yaml echo \"OPENSTACK_CLUSTER_GEN: geno01\" >> ~/cluster-defaults/clusterctl.yaml Next run of create_cluster.sh should be idempotent","s":"Steps","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-class","h":"#steps","p":661},{"i":669,"t":"To test the created k8s cluster, there are several tools available. Apply all commands to the testcluster context (by passing the appropriate --context setting to kubectl or by using the right KUBECONFIG file). Looking at all pods (kubectl get pods -A) to see that they all come up (and don't suffer excessive restarts) is a good first check. Look at the pod logs to investigate any failures. You can create a very simple deployment with the provided kuard.yaml, which is an example taken from the O'Reilly book from B. Burns, J. Beda, K. Hightower: \"Kubernetes Up & Running\" enhanced to also use a persistent volume. You can deploy Google's demo microservice application. sonobuoy runs a subset of the k8s tests, providing a simple way to filter the >5000 existing test cases to only run the CNCF conformance tests or to restrict testing to non-disruptive tests. The sonobuoy.sh wrapper helps with calling it. There are also Makefile targets check-* that call various sonobuoy test sets. This is how we call sonobuoy for our CI tests. You can use cilium connectivity test to check whether your cilium CNI is working properly. You might need to enable hubble to get a fully successful result.","s":"Testing","u":"/docs/container/components/k8s-cluster-api-provider/doc/usage/testing","h":"","p":668},{"i":671,"t":"TODO","s":"Overview","u":"/docs/container/deployment-examples/a/","h":"","p":670},{"i":673,"t":"TODO","s":"Hardware Requirements","u":"/docs/container/deployment-examples/a/hardware","h":"","p":672},{"i":675,"t":"TODO","s":"Guide 1","u":"/docs/container/guides/guide1","h":"","p":674},{"i":677,"t":"TODO","s":"Software Requirements","u":"/docs/container/deployment-examples/a/software","h":"","p":676},{"i":679,"t":"TODO","s":"Architecture","u":"/docs/container/overview/architecture","h":"","p":678},{"i":681,"t":"TODO","s":"Knowledge","u":"/docs/container/overview/knowledge","h":"","p":680},{"i":683,"t":"TODO","s":"Containerization","u":"/docs/getting-started/containerization","h":"","p":682},{"i":685,"t":"TODO","s":"Overview","u":"/docs/getting-started/overview","h":"","p":684},{"i":687,"t":"TODO","s":"Virtualization","u":"/docs/getting-started/virtualization","h":"","p":686},{"i":690,"t":"The Sovereign Cloud Stack (SCS) provides standards for a range of cloud infrastructure types. It strives for interoperable and sovereign cloud offerings which can be deployed and used by a wide range of organizations and individuals.","s":"What does SCS stand for?","u":"/docs/faq/","h":"#what-does-scs-stand-for","p":688},{"i":692,"t":"SCS is a Software Stack to power data centers of different scale. It empowers public or private cloud service providers to offer resources to their endusers.","s":"Who is SCS intended for?","u":"/docs/faq/","h":"#who-is-scs-intended-for","p":688},{"i":694,"t":"SCS is run by the SCS Project Team which is based at the Open Source Business Alliance e.V. and 100% funded by the German Ministry of Economics and Climate Action (BMWK). Public money means public code.","s":"Who or what is behind SCS?","u":"/docs/faq/","h":"#who-or-what-is-behind-scs","p":688},{"i":696,"t":"A standardized environment promotes interoperability, reduces vendor lock-in, and facilitates smoother transitions between providers. It gives individuals, companies and public institutions the freedom of choice.","s":"Why is there a need for a standardized cloud environment?","u":"/docs/faq/","h":"#why-is-there-a-need-for-a-standardized-cloud-environment","p":688},{"i":698,"t":"The SCS standards are available on the standards pages within our documentation page. Find them here","s":"Where can I find the SCS standards?","u":"/docs/faq/","h":"#where-can-i-find-the-scs-standards","p":688},{"i":700,"t":"Unlike proprietary clouds, SCS emphasizes standardization, ensuring interoperability and reduced dependency on one provider.","s":"How is the SCS different from other cloud environments (e.g. AWS, Azure,...)?","u":"/docs/faq/","h":"#how-is-the-scs-different-from-other-cloud-environments-eg-aws-azure","p":688},{"i":702,"t":"Yes, SCS can complement existing environments, enhancing standardization and interoperability.","s":"My company already has a cloud environment. Can we still use the SCS?","u":"/docs/faq/","h":"#my-company-already-has-a-cloud-environment-can-we-still-use-the-scs","p":688},{"i":704,"t":"Reference implementation is a concrete example or blueprint of how the SCS standards can be implemented.","s":"What does reference implementation mean?","u":"/docs/faq/","h":"#what-does-reference-implementation-mean","p":688},{"i":706,"t":"No, while the reference implementation is a guide, compliance requires adhering to SCS standards, not the exact blueprint of the reference implementation. Check the standards page on how to be SCS-compatible","s":"Do I need to use the reference implementation to be SCS compliant?","u":"/docs/faq/","h":"#do-i-need-to-use-the-reference-implementation-to-be-scs-compliant","p":688},{"i":708,"t":"No, you can choose layers based on your needs and still be SCS compliant.","s":"Do I have to use all layers of the reference implementation (IaaS, CaaS)?","u":"/docs/faq/","h":"#do-i-have-to-use-all-layers-of-the-reference-implementation-iaas-caas","p":688},{"i":710,"t":"IaaS stands for Infrastructure as a Service, providing virtualized computing resources over the internet.","s":"What does IaaS mean?","u":"/docs/faq/","h":"#what-does-iaas-mean","p":688},{"i":712,"t":"IaaS typically comprises virtual machines, storage, and network resources, all offered as scalable services. Find the architecture here","s":"How is the IaaS layer structured?","u":"/docs/faq/","h":"#how-is-the-iaas-layer-structured","p":688},{"i":714,"t":"CaaS refers to Container as a Service, where providers offer container orchestration platforms.","s":"What does CaaS mean? (Container Layer)","u":"/docs/faq/","h":"#what-does-caas-mean-container-layer","p":688},{"i":716,"t":"As a user: Existing SCS Clouds: Explore and test on any of the cloud providers offering SCS. Choose one from here As a Cloud Service Provider: Cloud in a Box: Start with our pre-packaged solutions. Link to Ciab Testbed: Use the SCS test environment to experiment. Link to Testbed/deployment example","s":"I want to try out the SCS! Where do I start?","u":"/docs/faq/","h":"#i-want-to-try-out-the-scs-where-do-i-start","p":688},{"i":718,"t":"As a user: Browse our list of providers and choose one that fits your needs. As a Cloud Service Provider: Adopt SCS standards and utilize our resources and tools to integrate them.","s":"I want to use an SCS Cloud! How do I get started?","u":"/docs/faq/","h":"#i-want-to-use-an-scs-cloud-how-do-i-get-started","p":688},{"i":720,"t":"Start by understanding SCS standards and then move on to the reference implementation. Link to guide.","s":"I want to use the SCS in my company and build my own cloud! Where do I start?","u":"/docs/faq/","h":"#i-want-to-use-the-scs-in-my-company-and-build-my-own-cloud-where-do-i-start","p":688},{"i":722,"t":"Refer to our support section or check our community channels for assistance. Link to community.","s":"I have a technical problem. Where can I find help?","u":"/docs/faq/","h":"#i-have-a-technical-problem-where-can-i-find-help","p":688},{"i":726,"t":"The OpenStack Flavor Manager manages the creation, modification, and removal of flavors. It operates as a facilitator that orchestrates compute flavors in alignment with the standard SCS-0100: Flavor Naming by utilizing YAML files provided by the SCS project.","s":"Overview","u":"/docs/iaas/components/flavor-manager","h":"#overview","p":724},{"i":728,"t":"The OpenStack Flavor Manager can be used via the OSISM CLI. This is the preferred way to use it. No installation is then required. It is used via osism manage flavors. For use independent of OSISM install the openstack-flavor-manager package with pip. It is likely that additional dependencies such as pkg-config or libssl-dev must be installed in advance. $ pip install openstack-flavor-manager Or clone the repository osism/openstack-flavor-manager and use the OpenStack Flavor Manager from source with tox. $ tox -- --help","s":"Installation","u":"/docs/iaas/components/flavor-manager","h":"#installation","p":724},{"i":730,"t":"There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Flavor Manager will be executed. When using the OSISM CLI, the files are expected in environments/openstack in your configuration repository. The cloud profile to be used can be specified via the optional --cloud parameter. By default the cloud profile with the name admin is used. It must be possible to create and delete flavors with the used cloud credentials. $ openstack-flavor-manager --help Usage: openstack-flavor-manager [OPTIONS] ╭─ Options ────────────────────────────────────────────────────────────────────────────────────╮ │ --name TEXT Name of flavor definitions. [default: scs] │ │ --debug Enable debug logging. │ │ --cloud TEXT Cloud name in clouds.yaml. [default: admin] │ │ --recommended Create recommended flavors. │ │ --help Show this message and exit. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ To create the mandatory flavors by the SCS-0100: Flavor Naming standard, you run: $ openstack-flavor-manager To create the recommended flavors by the SCS Flavor Naming Standard, you run: $ openstack-flavor-manager --recommended The output should look like this: 2023-09-20 13:03:14 | INFO | Flavor SCS-1V-4 created 2023-09-20 13:03:14 | INFO | Flavor SCS-2V-8 created 2023-09-20 13:03:14 | INFO | Flavor SCS-4V-16 created 2023-09-20 13:03:14 | INFO | Flavor SCS-8V-32 created ... All recommended flavors are now be available in your OpenStack environment. Check yourself by running: $ openstack --os-cloud admin flavor list $ openstack --os-cloud admin flavor show SCS-2V-4-20s +----------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | Field | Value | +----------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | OS-FLV-DISABLED:disabled | False | | OS-FLV-EXT-DATA:ephemeral | 0 | | access_project_ids | None | | description | None | | disk | 20 | | id | 652e3a6c-330e-4ee3-922b-b49c3c093062 | | name | SCS-2V-4-20s | | os-flavor-access:is_public | True | | properties | hw_rng:allowed='true', scs:cpu-type='shared-core', scs:disk0-type='ssd', scs:name-v1='SCS-2V:4:20s', scs:name-v2='SCS-2V-4-20s' | | ram | 4096 | | rxtx_factor | 1.0 | | swap | 0 | | vcpus | 2 | +----------------------------+---------------------------------------------------------------------------------------------------------------------------------+","s":"Usage","u":"/docs/iaas/components/flavor-manager","h":"#usage","p":724},{"i":732,"t":"There are two flavor definitions available by default. One for SCS and one for OSISM. Each definition has its own set of mandatory and recommended flavors. The definition of OSISM contains all definitions of SCS as well as some others. To run the OpenStack Flavor Manager with a specific definition, either scs or osism, use the optional --name parameter. By default the SCS-0100: Flavor Naming standard definition will be used. $ openstack-flavor-manager --name osism","s":"Definitions","u":"/docs/iaas/components/flavor-manager","h":"#definitions","p":724},{"i":734,"t":"A generator and parser for flavor names according to the SCS standard is available on flavors.scs.community. The flavor name SCS-2V-4-20s is inserted in field Flavor name: The flavor SCS-2V-4-20s translated is 2 generic x86-64 vCPUs with 4.0 GiB RAM and SSD 20GB root volume:","s":"Name parser and generator","u":"/docs/iaas/components/flavor-manager","h":"#name-parser-and-generator","p":724},{"i":736,"t":"This file serves as the central glossary within SCS. It is intended to clearly define terms used within SCS where there may be differing understandings. The glossary is not intended to evaluate or standardize specific terms.","s":"Glossary","u":"/docs/glossary","h":"","p":735},{"i":738,"t":"An OpenStack/SCS region consists of at least one or more Availability Zones that share a Control Plane with their services. As a result, they share one API. Also a Control Plane can share one CEPH cluster over different fire departments or each Availbility Zone can have its own CEPH cluster. Within the region, any Layer 2 networks are available to the user. Availbility Zones which build a region are connected by redundant low-latency (< 2ms ) high-bandwidth (10s of Gbps) connections. Regions can be federated when the SCS code is ready.","s":"Definition of a Region","u":"/docs/glossary","h":"#definition-of-a-region","p":735},{"i":740,"t":"An Availability Zone is a (physical) group of multiple compute nodes, controlled by the region's control plane that provides the API and interface. An Availability Zone allows OpenStack compute hosts to be divided into logical groups and provides a form of physical isolation and redundancy from other Availability Zones, for example by using a separate power supply or network devices. When users provision resources, they can specify in which Availability Zone their instances should be created. In this way, customers can ensure that their application resources are distributed across different failure domains to achieve high availability in the event of a hardware failure.","s":"Definition of a Availability Zone","u":"/docs/glossary","h":"#definition-of-a-availability-zone","p":735},{"i":742,"t":"Host aggregates are a mechanism for partitioning compute nodes which is not explicitly visible to users in an OpenStack/SCS cloud. Host aggregates are based on arbitrary characteristics such as server type, processor type, GPU, disk speed, etc. Administrators assign flavors to host aggregates by specifying metadata on the host aggregate and customizing the extra specifications of the flavor. It is then up to the Nova scheduler to determine the best match for the user request. Compute nodes can also be in more than one host aggregate. Optionally, one can designate a host aggregate as an Availability Zone, e.g. for simplification reasons of the user selection of an availbility zone. Availability Zones differ from Host Aggregates in that they are shown to the user as a Nova boot option, so Compute VMs can be started on them. Compute Nodes, however, can only be in a single Availability Zone. We can configure a default Availability Zone where instances will be scheduled if the user does not specify an Availability Zone. Info: A prerequisite for creating an Availability Zone is a host aggregate.","s":"Definition of Host Aggregates","u":"/docs/glossary","h":"#definition-of-host-aggregates","p":735},{"i":744,"t":"The Cells paradigm simplifies the handling of large Openstack deployments. Cells is an OpenStack Nova feature that improves scalability for Nova in OpenStack Platform. Each Cell has a separate database and message queue, which increases performance when scaling. One can provision additional Cells to handle large deployments, and compared to Regions, this allows access to a large number of compute nodes through a single API. Each Cell has its own Cell controllers running the database server and RabbitMQ along with the Nova Conductor services. Nova Conductor services, called \"Super Conductor\", continue to run on the main controller nodes. The services in the Cell Controllers can still call placement APIs, but cannot access other API layer services via RPC, nor can they access global API databases on the control nodes.","s":"Definition of a Cell","u":"/docs/glossary","h":"#definition-of-a-cell","p":735},{"i":746,"t":"In Openstack/SCS, a Control Plane consists of at least 5 hardware nodes, which together serve several Availability Zones and thus provide a common usable API for a region. The Control Plane also shares the network (Neutron), the Scheduler and the CEPH services. It includes the Controller Nodes (Galera Cluster, RabbitMQ) and the Manager Nodes, Maas,...","s":"Definition of a Control Plane","u":"/docs/glossary","h":"#definition-of-a-control-plane","p":735},{"i":748,"t":"The Control Node runs the Identity Service, Image Service , management processes for compute nodes, management processes for networking, various networking agents, and the Dashboard. It also includes supporting services such as an SQL database, a message queue, and NTP. Optionally, the Controller Node runs parts of the Block Storage, Object Storage, Orchestration and Telemetry services. The Controller Node requires at least two network interfaces.","s":"Definition of Control Node","u":"/docs/glossary","h":"#definition-of-control-node","p":735},{"i":750,"t":"A compute host runs the hypervisor part of compute that runs instances. By default, compute uses the KVM hypervisor. The compute host also runs a networking service agent that connects instances to virtual networks and provides firewall services to the instances through security groups. If you offer hyper-converged infrastructure, a compute host also serves the Ceph. This makes the storage dynamically scalable (horizontally and vertically). For the Ceph services, 1 CPU core and 4 GB of RAM are reserved per OSD to ensure appropriate performance.","s":"Definition of Compute Node","u":"/docs/glossary","h":"#definition-of-compute-node","p":735},{"i":752,"t":"From here, the OSISM Ansible playbooks are applied to the environment. Furthermore, the following services often run here non-redundantly: Prometheus server,....","s":"Definition of Manager Node","u":"/docs/glossary","h":"#definition-of-manager-node","p":735},{"i":754,"t":"The provider network is the network that is \"in front\", i.e. at the output points of the openstack/SCS. This is usually a public network, but can also be a private network in individual cases. IPs from the provider network can be assigned to instances within the SCS. The same applies to load balancers, of course.","s":"Definition of provider network","u":"/docs/glossary","h":"#definition-of-provider-network","p":735},{"i":756,"t":"The Rest API provides the core of openstack/SCS and can be addressed for a whole region. It accepts and responds to end-user API calls. The service supports the OpenStack Compute API, the Amazon EC2 API, and a special Admin API for privileged users to perform administrative actions. Policies are enforced and most orchestration actions can be started, such as launching an instance.","s":"Definition of API","u":"/docs/glossary","h":"#definition-of-api","p":735},{"i":758,"t":"Horizon is openstack's preferred GUI for the end user, but also for the administrator for a quick overview. It runs on the controller node. Other GUIs are possible, also GUIs which replace the horizon interface","s":"Horizon","u":"/docs/glossary","h":"#horizon","p":735},{"i":760,"t":"Most OpenStack services communicate with each other through the message queue. For example, Compute communicates with Block Storage services and Network services via the message queue. RabbitMQ, Qpid, and Zeromq are popular choices for a message queue service. When the message queue fails or becomes inaccessible, the cluster generally comes to a halt and ends up in a read-only state where the information is stuck at the point where the last message was sent. Therefore, this is clustered. RabbitMQ has shown itself to be the most widespread and best supported variant in the OpenStack context, Qpid occurs occasionally, ZeroMQ lacks HA functionality to date","s":"Message Queue","u":"/docs/glossary","h":"#message-queue","p":735},{"i":762,"t":"( The OpenStack Identity module called Keystone is used as an authentication and rights system between the OpenStack components. Keystone divides access to projects in the cloud into so-called \"tenants\". A tenant is a tenant of the cloud and has at least one assigned user. It is possible to create multiple users per tenant with different rights. Keystone uses a token system for authorization and also supports the connection to other authentication options such as LDAP. (wikipedia) )","s":"Keystone","u":"/docs/glossary","h":"#keystone","p":735},{"i":764,"t":"The OpenStack Image Service, also called Glance, is a service that provides virtual machine images to OpenStack users. These images are used by Nova as a template to compile virtual machine instances. Both local hard disks and object storage solutions such as Swift or Ceph can be used as storage backends. In addition to the images, Glance can also store metadata such as the operating system used or the kernel version. Access to both this metadata and the images themselves is via a REST API. Glance supports a number of formats such as VHD, VMDK and qcow2.","s":"Glance","u":"/docs/glossary","h":"#glance","p":735},{"i":766,"t":"The Open Source Infrastructure & Service Manager is a powerful deployment framework for OpenStack and Ceph as well as required services such as a RabbitMQ broker or a MariaDB Galera cluster.","s":"OSISM","u":"/docs/glossary","h":"#osism","p":735},{"i":768,"t":"Ceph is an open source distributed storage solution. The core component is RADOS (Reliable Autonomic Distributed Object Store), an object store that can be distributed redundantly over any number of servers. Ceph offers the user three types of storage: An object store compatible with the Swift and S3 API (RADOS Gateway), virtual block devices (RADOS Block Devices) and CephFS, a distributed file system.","s":"Ceph","u":"/docs/glossary","h":"#ceph","p":735},{"i":770,"t":"Nova is virtually a synonym for Compute. It is the part of the stack that can manage groups of virtual machines. The virtualized systems can be distributed over any number of so-called compute nodes. Hypervisors supported include KVM, Xen Hyper-V and ESXI. In the community, KVM is considered to be set and best supported (we use KVM), which is controlled via libvirt. ESXI and Hyper-V can be used, sometimes with limited functionality.","s":"Nova","u":"/docs/glossary","h":"#nova","p":735},{"i":772,"t":"The OpenStack Networking module Neutron provides the networking service for OpenStack. Neutron can be used to manage networks, subnets, and IP addresses/floating IPs. A floating IP in OpenStack refers to an official IP that serves as an interface from the internal to the public network. In addition to a load balancer, HA proxy and health monitor, Neutron also supports techniques such as VLAN and VPN. To secure the networks, Neutron uses a firewall that allows versatile port rules, e.g. on a security group basis. For trademark reasons, the OpenStack networking module had to be renamed \"Neutron\". The previous name was \"Quantum\". For the management of the data link layer, Neutron offers the possibility to use various already existing networking software such as Open vSwitch or the bridge functionality of the Linux kernel by means of plugins. In the OpenStack releases since Ussuri, the \"OpenVirtualNetwork\"(OVN) has established itself, it replaces many of the Neutron components, e.g. L3 and DHCP agent, so that Neutron only has to talk directly to OVN.","s":"Neutron","u":"/docs/glossary","h":"#neutron","p":735},{"i":774,"t":"OpenStack Block Storage or Cinder provides virtual block storage in the form of virtualized storage media (hard disks, CDs, etc.). The block storage can be attached to virtual machines. An API interface allows Cinder to connect to Swift so that block storage media can communicate with object storage. Meanwhile, many other storage backends are also fully or partially supported. There is also the option of defining multiple backends and creating a volume type for each backend, so that when a new volume is created, it can be selected on which storage backend the volume is created.","s":"Cinder","u":"/docs/glossary","h":"#cinder","p":735},{"i":776,"t":"Swift is the so-called object storage that can be used by Nova. This is responsible for redundant data storage. Swift can also be used as a backend for Cinder or Glance. Objects are stored in so-called containers, which are primarily used to group objects and store metadata and in turn belong to individual accounts. Objects and containers are accessed via a REST API.","s":"Swift","u":"/docs/glossary","h":"#swift","p":735},{"i":778,"t":"A Ceph OSD (Object Storage Daemon) logically represents a storage device in a Ceph cluster, which can logically be a hard disk, which is the ideal case. In other cases it can also be a raid, which however leads to considerable performance limitations due to caching or other raid optimization.","s":"Ceph OSD","u":"/docs/glossary","h":"#ceph-osd","p":735},{"i":780,"t":"Persona Description SCS Operator The SCS Operator is the one who owns and operates a standardized cloud environment. SCS Operations Team The team at the SCS Operator which actually runs the cloud environment. SCS Consumer The SCS Consumer consumes a standardized SCS environment and operates and orchestrates applications on top of it. The SCS Consumer is typically a customer or user of the SCS Operator. SCS Integrator The SCS Integrator assists in or is building up a standardized cloud environment. The SCS Integrator can be 2nd or 3rd level support for the SCS Operator. SCS Project The SCS Project oversees the overall activities around the Sovereign Cloud Stack. SCS Developer The SCS Developer actively contributes to technical elements of the Sovereign Cloud Stack.","s":"Personas","u":"/docs/glossary","h":"#personas","p":735},{"i":782,"t":"The OpenStack Image Manager is a tool for managing all images on an OpenStack environment","s":"Image Manager","u":"/docs/iaas/components/image-manager/","h":"","p":781},{"i":784,"t":"This information is only relevant for the operator of an OpenStack environment. You can skip this section if you want to use OpenStack Image Manager as a normal user and you are not an operator of an openStack environment.","s":"Requirements","u":"/docs/iaas/components/image-manager/","h":"#requirements","p":781},{"i":786,"t":"The OpenStack Image Service (Glance) is required to upload and discover data assets that are used by other services. Since this script stores many images in a single project, the Glance quota must be set accordingly high or to unlimited. [DEFAULT] user_storage_quota = 1TB With most storage backends it makes sense to convert the imported images directly to RAW. So it is required for using Ceph and it's features too. Recited from the Ceph documentation QEMU and block devices and Block devices and OpenStack. info The raw data format is really the only sensible format option to use with RBD. Technically, you could use other QEMU-supported formats (such as qcow2 or vmdk), but doing so would add additional overhead, and would also render the volume unsafe for virtual machine live migration when caching (see below) is enabled. Important Ceph doesn't support QCOW2 for hosting a virtual machine disk. Thus if you want to boot virtual machines in Ceph (ephemeral backend or boot from volume), the Glance image format must be RAW. See the OpenStack Glance documentation for more details. This requires the following parameter for the image import workflow. [taskflow_executor] conversion_format = raw [image_import_opts] image_import_plugins = ['image_decompression', 'image_conversion'] [image_conversion] output_format = raw","s":"OpenStack Image Service (Glance)","u":"/docs/iaas/components/image-manager/","h":"#openstack-image-service-glance","p":781},{"i":788,"t":"If the mirror functionality is used, an object storage backend is required. The use of the mirror functionality is optional and is not used by default.","s":"Object storage backend","u":"/docs/iaas/components/image-manager/","h":"#object-storage-backend","p":781},{"i":790,"t":"This Getting started will upload a private image to your OpenStack environment with the help of the OpenStack Image Manager. Install the openstack-image-manager package with pip. pip3 install openstack-image-manager The installation can also be done via pipenv. A Pipefile file is created with this content. The latest version of openstack-image-manager is used. [[source]] url = \"https://pypi.org/simple\" verify_ssl = true name = \"pypi\" [packages] openstack-image-manager = \"==0.20240403.0\" [dev-packages] [requires] python_version = \"3.10\" The dependencies are then installed and the shell is prepared for use: pipenv install pipenv shell Create a image definition in the file getting-started.yml in the local directory images. --- images: - name: MyCirros format: qcow2 login: cirros password: gocubsgo min_disk: 1 min_ram: 32 status: active visibility: private multi: false meta: architecture: x86_64 hw_disk_bus: scsi hw_rng_model: virtio hw_scsi_model: virtio-scsi hw_watchdog_action: reset os_distro: cirros replace_frequency: never uuid_validity: none provided_until: none tags: [] versions: - version: \"0.6.0\" url: https://github.com/cirros-dev/cirros/releases/download/0.6.0/cirros-0.6.0-x86_64-disk.img checksum: \"sha256:94e1e2c94dbbae7d4bdc38e68590a1daf73c9de2d03dd693857b4b0a042548e8\" build_date: 2022-09-28 Run the OpenStack Image Manager. It is assumed that a profile with the name openstack exists in the clouds.yaml. openstack-image-manager --cloud openstack --filter \".*Cirr.*\" --images images/","s":"Getting started","u":"/docs/iaas/components/image-manager/","h":"#getting-started","p":781},{"i":792,"t":"The configuration consists of different parameter settings, such as values for minimum RAM or the visibility of the image. Have a look at the examples below for all parameters. After a change to the configuration, validate it with tox -- --dry-run.","s":"Image definitions","u":"/docs/iaas/components/image-manager/","h":"#image-definitions","p":781},{"i":794,"t":"The value of login is stored as image_original_user in the metadata of an image. If image_description is not set as meta information, image_description is set to the name of the image. The value of build_date of a specific version of an image is stored as image_build_date in the metadata of an image. The value of url of a specific version of an image is stored as image_source in the metadata of an image.","s":"SCS image standard","u":"/docs/iaas/components/image-manager/","h":"#scs-image-standard","p":781},{"i":796,"t":"This type of image definition is used for images that are rebuilt at regular intervals. For example, this is the case for the daily builds of the Ubuntu images. The attribute multi: true is set. With this type of image definition, the version of the distribution (or product, whatever is contained in the image) used is already in the name of the image definition. The version properties from the definition's versions list are appended only to older iterations of the image as timestamp suffixes in parentheses upon each rotation (except for the latest entry). images: - name: Ubuntu 24.04 format: qcow2 login: ubuntu min_disk: 8 min_ram: 512 status: active visibility: public multi: true meta: architecture: x86_64 hw_disk_bus: scsi hw_scsi_model: virtio-scsi hw_watchdog_action: reset os_distro: ubuntu os_version: '24.04' tags: [] versions: - version: '20240416' url: https://cloud-images.ubuntu.com/noble/20240416/noble-server-cloudimg-amd64.img - version: '20240422' url: https://cloud-images.ubuntu.com/noble/20240422/noble-server-cloudimg-amd64.img This configuration creates the following images: Ubuntu 24.04 (20240416) Ubuntu 24.04 If a newer build is added, the following rotation takes place: Ubuntu 24.04 (20240416) does not change Ubuntu 24.04 becomes Ubuntu 24.04 (20240422) the new image becomes Ubuntu 24.04 By default the last three images will be visible. When a fourth image is added, the visibility of the last image in the list is changed to community and the image can be deleted in the future.","s":"Image with regular rebuilds","u":"/docs/iaas/components/image-manager/","h":"#image-with-regular-rebuilds","p":781},{"i":798,"t":"This type of image definition is used for images that are not rebuilt. For example, this is the case for the flatcar images. For each release of Flatcar there is exactly one image which will not be rebuilt in the future. The attribute multi: false is set. With this type of image definition, the version of the distribution (or product, whatever is contained in the image) used is not in the name of the image definition. Instead, the version properties from the image definition's versions list are appended as static version suffixes to the images' names. images: - name: RancherOS format: qcow2 login: rancher min_disk: 8 min_ram: 2048 status: active visibility: public multi: false meta: architecture: x86_64 hw_disk_bus: scsi hw_scsi_model: virtio-scsi hw_watchdog_action: reset tags: [] versions: - version: '1.3.0' url: https://github.com/rancher/os/releases/download/v1.3.0/rancheros-openstack.img - version: '1.4.0' url: https://github.com/rancher/os/releases/download/v1.4.0/rancheros-openstack.img - version: '1.4.1' url: https://github.com/rancher/os/releases/download/v1.4.1/rancheros-openstack.img This configuration creates the following images: RancherOS 1.3.0 RancherOS 1.4.0 RancherOS 1.4.1 If a new version is added, no rotation takes place. The new version is added as RancherOS x.y.z. Here also the visibility of older images is not changed.","s":"Image without regular rebuild","u":"/docs/iaas/components/image-manager/","h":"#image-without-regular-rebuild","p":781},{"i":800,"t":"Image properties​ Removal of properties is not yet possible URL, name and format can not be changed Any keys can be added to meta, these will be added to the image Existing keys in meta can be changed, the same applies to min_disk and min_ram Image tags​ image status​ deactivation: change status to deactivated reactivation: change status to active Image visibility​ A full documentation about the visibility of images can be found in the Image visibility section in the OpenStack Image Service API Documentation. public: set visibility to public community: set visibility to community shared: set visibility to shared private: set visibility to private","s":"Other properties","u":"/docs/iaas/components/image-manager/","h":"#other-properties","p":781},{"i":803,"t":"Since the upstreams often only keep their images for a short time, we mirror most of the images on REGIO.cloud. This makes us independent of the availability of the images in the individual upstreams.","s":"Mirroring images","u":"/docs/iaas/components/image-manager/","h":"#mirroring-images","p":781},{"i":805,"t":"Some of the images are automatically updated by a CI job. The latest available build at the time of the CI job execution is mirrored and made available as the current version. Currently, the following images are updated once a week (every Sunday at 0 am): Almalinux CentOS Debian Rockylinux Ubuntu","s":"Updating images","u":"/docs/iaas/components/image-manager/","h":"#updating-images","p":781},{"i":808,"t":"The OpenStack Project Manager manages the creation of Openstack Domains, Projects and Users.","s":"Overview","u":"/docs/iaas/components/project-manager","h":"#overview","p":806},{"i":810,"t":"Prepare to use the Openstack Project Manager. During installation, ldap libraries are required under Linux; you should install libldap2-dev and libsasl2-dev beforehand. git clone https://github.com/osism/openstack-project-manager cd openstack-project-manager pipenv install pipenv shell","s":"Installation","u":"/docs/iaas/components/project-manager","h":"#installation","p":806},{"i":813,"t":"The create.py command and his default options while executing the command. --admin-domain default --assign-admin-user true --cloud admin --create-admin-user true --create-domain false --create-user false --domain-name-prefix true --has-service-network false --has-public-network true --has-shared-images true --internal-id unset --random false --managed-network-resources false --name sandbox --owner unset --password unset --password-length 16 --public-network public --quota-class basic --service-network-cidr unset --quota-multiplier 1 --quota-multiplier-compute unset --quota-multiplier-network unset --quota-multiplier-storage unset --quota-router 1","s":"create.py","u":"/docs/iaas/components/project-manager","h":"#createpy","p":806},{"i":815,"t":"The manage.py has also some defaults while executing and will touch all projects in your Openstack Cluster, if not --domain is used. --admin-domain default --assign-admin-user false --classes etc/classes.yml --domain unset --dry-run false --endpoints etc/endpoints.yml --manage-endpoints false --manage-homeprojects false --name unset Default Openstack Roles to users are set to member and load-balancer_member at this time, the behavior can only be changed in the code.","s":"manage.py","u":"/docs/iaas/components/project-manager","h":"#managepy","p":806},{"i":817,"t":"There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Project Manager will be executed, examples are provided within the git repository. The cloud profile to be used can be specified via the optional --cloud parameter. By default the cloud profile with the name admin is used. It has to be and admin account, to create and modify domains, projects, users and quotas. The Openstack Project Manager essentially consists of two parts, the create.py and the manage.py, there are more scripts for handling users using ldap which needs more configuration setup.","s":"Usage","u":"/docs/iaas/components/project-manager","h":"#usage","p":806},{"i":819,"t":"This command is used to create and modify domains, projects, users and quotas. As default the domain is used as prefix for all projects and users created for easy alloction in Openstack. note create.py can't delete once created objects, this must be done using Openstack commands to remove a project or domain. python src/create.py -h usage: create [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--create-admin-user] [--create-domain] [--create-user] [--domain DOMAIN] [--domain-name-prefix] [--has-public-network] [--has-service-network] [--has-shared-images] [--internal-id INTERNAL_ID] [--managed-network-resources] [--name NAME] [--noassign-admin-user] [--nocreate-admin-user] [--nocreate-domain] [--nocreate-user] [--nodomain-name-prefix] [--nohas-public-network] [--nohas-service-network] [--nohas-shared-images] [--nomanaged-network-resources] [--norandom] [--owner OWNER] [--password PASSWORD] [--password-length PASSWORD_LENGTH] [--public-network PUBLIC_NETWORK] [--quota-class QUOTA_CLASS] [--quota-multiplier QUOTA_MULTIPLIER] [--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE] [--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK] [--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE] [--quota-router QUOTA_ROUTER] [--random] [--service-network-cidr SERVICE_NETWORK_CIDR] options: -h, --help show this help message and exit --admin-domain ADMIN_DOMAIN Admin domain --assign-admin-user Assign admin user --cloud CLOUD Managed cloud --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the command-line. --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the command-line. --create-admin-user Create admin user --create-domain Create domain only --create-user Create user --domain DOMAIN Domain --domain-name-prefix Add domain name as prefix to the project name --has-public-network Has public network infrastructure --has-service-network Has service network infrastructure --has-shared-images Has shared images --internal-id INTERNAL_ID Internal ID --managed-network-resources Manage the network resources --name NAME Projectname --noassign-admin-user The inverse of --assign-admin-user --nocreate-admin-user The inverse of --create-admin-user --nocreate-domain The inverse of --create-domain --nocreate-user The inverse of --create-user --nodomain-name-prefix The inverse of --domain-name-prefix --nohas-public-network The inverse of --has-public-network --nohas-service-network The inverse of --has-service-network --nohas-shared-images The inverse of --has-shared-images --nomanaged-network-resources The inverse of --managed-network-resources --norandom The inverse of --random --owner OWNER Owner of the project --password PASSWORD Password --password-length PASSWORD_LENGTH Password length --public-network PUBLIC_NETWORK Public network --quota-class QUOTA_CLASS Quota class --quota-multiplier QUOTA_MULTIPLIER Quota multiplier --quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE Quota multiplier compute --quota-multiplier-network QUOTA_MULTIPLIER_NETWORK Quota multiplier network --quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE Quota multiplier storage --quota-router QUOTA_ROUTER Quota router --random Generate random names --service-network-cidr SERVICE_NETWORK_CIDR Service network CIDR Create a Domain and inital project​ When executing the create.py command, the first time with --domain, it will create a new domain, an admin account and the first project webshop. The admin account will be created in the default Domain of Openstack and can be used for the Service Provider to manager the complete domain. $ python3 src/create.py --domain democompany --name webshop +----------------+----------------------+----------------------------------+ | name | value | id | |----------------+----------------------+----------------------------------| | domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 | | project | democompany-webshop | 645538bf67664cfeaed32476d58f95fb | | admin | democompany-admin | cc8d6bf7b61d4199ba5a4230c4ec6d62 | | admin_password | qawsEdfg2d45Fsxc | | +----------------+----------------------+----------------------------------+ Create a User for a project​ $ python3 src/create.py --domain democompany --name webshopuser --create-user +----------+-------------------------+----------------------------------+ | name | value | id | |----------+-------------------------+----------------------------------| | domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 | | project | democompany-webshop | 5752b6701026478f9cac122fc54eb9cb | | user | democompany-webshopuser | ce213655559d47d7800501124fed4d02 | | password | vEvM9vgRESdffWE2 | | +----------+-------------------------+----------------------------------+ Create additional project with unlimited quota​ $ python3 src/create.py --domain democompany --name styles --quota-class unlimited +----------+--------------------+----------------------------------+ | name | value | id | |----------+--------------------+----------------------------------| | domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 | | project | democompany-styles | 666097e396fd4f9392d6aa55c76d8267 | +----------+--------------------+----------------------------------+ Set quotas for a project​ All quota information must be set as a property to the Openstack project within your Openstack Cluster, if no property is set, the basic quotaclass of etc/classes.yml will be applied. It is possible to set a quota multiplier for any project. The following command you set a multiplier of 256 of the basic quota: $ openstack project set --property quotamultiplier=256 democompany-webshop Adjusting gigabyte quota for storage with a multiplier of 20 of the basic quota for a project: $ openstack project set --property quotamultiplier_storage=20 democompany-webshop This will override the general quotamultiplier only for storage. Other possible multiplier which can be set individually are: quotamultiplier_compute, quotamultiplier_network, quota_router To change the quotaclass to unlimited from the etc/classes.yaml $ openstack project set --property quotaclass=unlimited democompany-webshop Special project: images​ With this special Project you can share all images uploaded into this project to all other project in your domain which has set the property has-shared-images, which is by default set. Alsoi only the domain-admin user has access to this project, other domain users won't see this, they will find the uploaded images in their projects. If you want your grant other domain users also access to upload some images, you need to give them access to the images Project in Openstack. $ python3 src/create.py --domain democompany --name images +---------+---------------------+----------------------------------+ | name | value | id | |---------+---------------------+----------------------------------| | domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 | | project | democompany-images | 6d57f39aacbe485d87733865b1e79d03 | +---------+---------------------+----------------------------------+ Additionally you need to add the domain and domain-admin user to the clouds.yaml, it is always named opm-domainname-admin: so the manage.py can setup permissions to the projects later on and users are able to find the images. opm-democompany-admin: auth: auth_url: https://keystone.my.cloud:5000/v3 username: democompany-admin password: yourpassword user_domain_name: Default project_domain_name: democompany identity_api_version: 3 Special project: service​ With this special project you can share installed services, like a harbor, to all other projects in your domain. Per default, only the domain admin has access to this project. $ python3 src/create.py --domain democompany --name service +---------+---------------------+----------------------------------+ | name | value | id | |---------+---------------------+----------------------------------| | domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 | | project | democompany-service | a5558f7338f94adea5f41858636256b5 | +---------+---------------------+----------------------------------+","s":"create.py","u":"/docs/iaas/components/project-manager","h":"#createpy-1","p":806},{"i":821,"t":"warning This command applies quotas, networks and routers to all projects in the Openstack Cluster, not only to those have been configured previously with the create.py or openstack project set --property commands. Best is to run this command by cron, every hour to apply all pending changes, it is also possible to run this at the command line to apply changes immediately. python3 src/manage.py -h usage: manage [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--classes CLASSES] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--domain DOMAIN] [--dry-run] [--endpoints ENDPOINTS] [--manage-endpoints] [--manage-homeprojects] [--name NAME] [--noassign-admin-user] [--nodry-run] [--nomanage-endpoints] [--nomanage-homeprojects] options: -h, --help show this help message and exit --admin-domain ADMIN_DOMAIN Admin domain --assign-admin-user Assign admin user --classes CLASSES Path to the classes.yml file --cloud CLOUD Cloud name in clouds.yaml --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the command-line. --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the command-line. --domain DOMAIN Domain to be managed --dry-run Do not really do anything --endpoints ENDPOINTS Path to the endpoints.yml file --manage-endpoints Manage endpoints --manage-homeprojects Manage home projects --name NAME Project to be managed --noassign-admin-user The inverse of --assign-admin-user --nodry-run The inverse of --dry-run --nomanage-endpoints The inverse of --manage-endpoints --nomanage-homeprojects The inverse of --manage-homeprojects Manage a specific domain only​ $ python3 src/manage.py --domain democompany 2024-04-19 14:24:02.873 | INFO | democompany - domain_id = a8549ef5d3d14f938b127a1cdefe3788 2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03 2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03, domain_id = a8549ef5d3d14f938b127a1cdefe3788 2024-04-19 14:24:04.953 | INFO | democompany-images - quotaclass {'compute': {'cores': 0, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 0, 'key_pairs': 0, 'metadata_items': 128, 'ram': 0, 'server_group_members': 0, 'server_groups': 0}, 'network': {'floatingip': 0, 'network': 0, 'port': 0, 'rbac_policy': 0, 'router': 0, 'security_group': 0, 'security_group_rule': 0, 'subnet': 0, 'subnetpool': 0}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 1000, 'per_volume_gigabytes': 25, 'snapshots': 0, 'volumes': 100}, 'parent': 'default'} 2024-04-19 14:24:04.953 | INFO | democompany-images - check network quota 2024-04-19 14:24:05.048 | INFO | democompany-images - check compute quota 2024-04-19 14:24:05.175 | INFO | democompany-images - check volume quota 2024-04-19 14:24:05.286 | INFO | democompany-images - check if external rbac policy must be deleted (public) 2024-04-19 14:24:05.349 | INFO | democompany-images - check if service rbac policy must be deleted (democompany-service) 2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5 2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5, domain_id = a8549ef5d3d14f938b127a1cdefe3788 2024-04-19 14:24:06.131 | INFO | democompany-service - quotaclass {'compute': {'cores': 256, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 256, 'key_pairs': 256, 'metadata_items': 128, 'ram': 262144, 'server_group_members': 256, 'server_groups': 256}, 'network': {'floatingip': 256, 'network': 256, 'port': 256, 'rbac_policy': 1024, 'router': 256, 'security_group': 256, 'security_group_rule': 1024, 'subnet': 256, 'subnetpool': 256}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 0, 'per_volume_gigabytes': 0, 'snapshots': 0, 'volumes': 0}, 'parent': 'default'} 2024-04-19 14:24:06.131 | INFO | democompany-service - check network quota 2024-04-19 14:24:06.212 | INFO | democompany-service - check compute quota 2024-04-19 14:24:06.330 | INFO | democompany-service - check volume quota 2024-04-19 14:24:06.467 | INFO | democompany-service - check if external rbac policy must be created (public) 2024-04-19 14:24:06.589 | INFO | democompany-service - check if service rbac policy must be deleted (democompany-service) 2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb 2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb, domain_id = a8549ef5d3d14f938b127a1cdefe3788 2024-04-19 14:24:06.915 | INFO | democompany-webshop - quotaclass {'compute': {'cores': 4, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': -1, 'key_pairs': 4, 'metadata_items': 128, 'ram': 8192, 'server_group_members': 4, 'server_groups': 4}, 'network': {'floatingip': 4, 'network': 1, 'port': 20, 'rbac_policy': 10, 'router': 0, 'security_group': 5, 'security_group_rule': 20, 'subnet': 2, 'subnetpool': 1}, 'volume': {'backup_gigabytes': 40, 'backups': 8, 'gigabytes': 20, 'per_volume_gigabytes': 200, 'snapshots': 4, 'volumes': 4}, 'parent': 'default'} 2024-04-19 14:24:06.915 | INFO | democompany-webshop - check network quota 2024-04-19 14:24:06.993 | INFO | democompany-webshop - check compute quota 2024-04-19 14:24:07.114 | INFO | democompany-webshop - check volume quota 2024-04-19 14:24:07.254 | INFO | democompany-webshop - check if external rbac policy must be created (public) 2024-04-19 14:24:07.334 | INFO | democompany-webshop - check if service rbac policy must be deleted (democompany-service)","s":"manage.py","u":"/docs/iaas/components/project-manager","h":"#managepy-1","p":806},{"i":823,"t":"The config files which can be used for create.py and manage.py are using the oslo.config format, you can set the command line options as key = value pair and create your own config files matching your setup. democompany.conf [DEFAULT] cloud = admin domain = democompany","s":"Config files","u":"/docs/iaas/components/project-manager","h":"#config-files","p":806},{"i":825,"t":"Edit the etc/classes.yml file if you want to change or add new quota templates","s":"Quota Templates","u":"/docs/iaas/components/project-manager","h":"#quota-templates","p":806},{"i":827,"t":"Edit the etc/endpoints.yml file to fit your available endpoints","s":"Setup Endpoints","u":"/docs/iaas/components/project-manager","h":"#setup-endpoints","p":806},{"i":830,"t":"Prepare use of the OpenStack Resource Manager. git clone https://github.com/osism/openstack-resource-manager cd openstack-resource-manager pipenv install pipenv shell Prepare cloud profile admin in clouds.yml and secure.yml (use clouds.yml.sample and secure.yml.sample in the openstack-resource-manager repository as sample files).","s":"Preparations","u":"/docs/iaas/components/resource-manager","h":"#preparations","p":828},{"i":833,"t":"Live migrate all instances from compute node SOURCE to compute node TARGET. python3 src/host-action.py --yes --disable --action live-migrate --host SOURCE --input TARGET","s":"Live migration","u":"/docs/iaas/components/resource-manager","h":"#live-migration","p":828},{"i":835,"t":"Evacuate all instances from compute node SOURCE to compute node TARGET. python3 src/host-action.py --yes --action evacutate --host SOURCE --input TARGET","s":"Evacuation","u":"/docs/iaas/components/resource-manager","h":"#evacuation","p":828},{"i":838,"t":"Rotation of amphorae older than 30 days. $ python3 src/amphora.py --rotate 2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa is older than 30 days 2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa of loadbalancer 9008d3d7-f593-4bc3-941c-a740c178148d is rotated by a loadbalancer failover","s":"Amphora rotation","u":"/docs/iaas/components/resource-manager","h":"#amphora-rotation","p":828},{"i":840,"t":"$ python3 src/volume.py 2023-12-11 23:09:44 | INFO | Volume ad848454-ba1f-4c28-b9a8-edada17948b0 hangs in CREATING status for more than 2 hours Delete volume ad848454-ba1f-4c28-b9a8-edada17948b0 [yes/no]:","s":"Cinder","u":"/docs/iaas/components/resource-manager","h":"#cinder","p":828},{"i":842,"t":"$ python3 src/orphan.py 2023-12-11 23:11:16 | INFO | Checking nova / server 2023-12-11 23:11:21 | INFO | Checking neutron / port 2023-12-11 23:11:23 | INFO | Checking neutron / router 2023-12-11 23:11:23 | INFO | Checking neutron / network 2023-12-11 23:11:24 | INFO | Checking neutron / subnet 2023-12-11 23:11:24 | INFO | Checking neutron / floatingip 2023-12-11 23:11:24 | INFO | Checking neutron / rbacpolicy 2023-12-11 23:11:24 | INFO | Checking neutron / securitygroup 2023-12-11 23:11:26 | INFO | Checking neutron / securitygrouprule 2023-12-11 23:11:27 | INFO | Checking glance / image 2023-12-11 23:11:30 | INFO | Checking glance / imagemember [...] +---------------+-------------------+--------------------------------------+----------------------------------+ | servicename | resourcename | resource_id | project_id | |---------------+-------------------+--------------------------------------+----------------------------------| | neutron | port | 561f8f76-18b0-470a-92cd-4336346b4b18 | 3cfa8679f5d8429382b95d4d2dd80f79 | | neutron | port | 6d1986e4-1e6d-4d4a-961d-97d372945bb1 | 3cfa8679f5d8429382b95d4d2dd80f79 | | neutron | port | 74f9bddc-9bfa-4d06-a147-ca87127e501e | 8268b05ef24b41d8806c0fe417576610 | | neutron | port | f630a66b-7725-4a68-868b-caebbaf1c003 | 8268b05ef24b41d8806c0fe417576610 | | neutron | router | c0c4e4aa-53ee-4fd1-8f53-84d52cf6c60b | 3cfa8679f5d8429382b95d4d2dd80f79 | | neutron | router | c8f9a13b-adcd-4a8e-942b-338bcf4dde7c | 8268b05ef24b41d8806c0fe417576610 | | neutron | network | 62d6ad2a-0cda-4d45-9325-963b8eb67000 | 8268b05ef24b41d8806c0fe417576610 | | neutron | network | 63b8fea6-7d7b-40c3-9c31-bee4404a92d6 | 3cfa8679f5d8429382b95d4d2dd80f79 | | neutron | subnet | 0cd16262-330a-44ad-9160-daef84aded2d | 3cfa8679f5d8429382b95d4d2dd80f79 | | neutron | subnet | 690dee14-ac12-464d-a911-a873c27ec818 | d33b0d15fd474131a335207216297a2a | | neutron | subnet | 854e7c55-62e2-4679-9b18-805460b998ce | 8268b05ef24b41d8806c0fe417576610 | | neutron | rbacpolicy | 00d7c2a2-6674-4f40-9f95-176a7858fcca | c8e4393b6d064a26a31014f82939172f | | neutron | rbacpolicy | 0608c701-5b81-4712-989b-ba03cdcc255d | c8e4393b6d064a26a31014f82939172f | [...] | neutron | securitygrouprule | fd3c553f-168e-4c24-ab40-09aa934bab86 | 3a96207b719643ae9ea9a81d95116e9e | | neutron | securitygrouprule | fdf337be-971c-4d5d-88ca-d90cdb468e88 | 3cfa8679f5d8429382b95d4d2dd80f79 | | neutron | securitygrouprule | ff8162fe-f053-49c9-8659-078061ce3e23 | d0b0add9ede0452791f71cb900e35242 | | glance | imagemember | c7f2cb0c25d34c5d886ecaf483e5fda6 | c7f2cb0c25d34c5d886ecaf483e5fda6 | | glance | imagemember | d4d0a161f9024fc8b517b0375eb97c89 | d4d0a161f9024fc8b517b0375eb97c89 | | glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 | | glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 | | glance | imagemember | d33b0d15fd474131a335207216297a2a | d33b0d15fd474131a335207216297a2a | | cinder | volume | e7c4b05c-b76a-40cc-8381-03262e57eb94 | 9b5f7f8ed70d410c81e3f45bf4e36498 | +---------------+-------------------+--------------------------------------+----------------------------------+","s":"Orphans","u":"/docs/iaas/components/resource-manager","h":"#orphans","p":828},{"i":846,"t":"The OpenStack Image Manager update.py Script updates the /etc/images/*.yaml files to the always latest release of the Distributions, set S3 Mirror Urls and uploads the Images to the mirror. These updated yaml files are later processed by the Image Manger itself.","s":"Overview","u":"/docs/iaas/components/image-manager/update","h":"#overview","p":844},{"i":848,"t":"Prepare to use the update.py script. git clone https://github.com/osism/openstack-image-manager/ cd openstack-image-manager pipenv install pipenv shell","s":"Installation","u":"/docs/iaas/components/image-manager/update","h":"#installation","p":844},{"i":850,"t":"python contrib/update.py --help Usage: update.py [OPTIONS] ╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ --debug Enable debug logging │ │ --dry-run Do not perform any changes │ │ --minio-access-key TEXT Minio access key [env var: MINIO_ACCESS_KEY] [default: None] │ │ --minio-secret-key TEXT Minio secret key [env var: MINIO_SECRET_KEY] [default: None] │ │ --minio-server TEXT Minio server [env var: MINIO_SERVER] [default: swift.services.a.regiocloud.tech] │ │ --minio-bucket TEXT Minio bucket [env var: MINIO_BUCKET] [default: openstack-images] │ │ --swift-prefix TEXT Swift prefix [env var: SWIFT_PREFIX] [default: swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/] │ │ --install-completion Install completion for the current shell. │ │ --show-completion Show completion for the current shell, to copy it or customize the installation. │ │ --help Show this message and exit. │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ note At this time the update.py expects all yamls Files at /etc/images/, which can't be configured at the moment. Mirroring can't be disabled at the moment. Best is to run this Script by cron or a CI job, to update all Distribution Files periodically to the latest release and afterwards run Openstack Image Manager. The Distribution Image yaml files must exists before running the script, you can use the files from Github repo at etc/images/ as template for your first run. $ python contrib/update.py 2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/centos.yml 2024-04-24 09:29:44 | INFO | update_image:179 - Checking image CentOS Stream 9 2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-HEREBE\\d+\\.\\dDRAGONS.x86_64.qcow2 2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cloud.centos.org/centos/9-stream/x86_64/images/CHECKSUM 2024-04-24 09:29:44 | INFO | get_latest_default:62 - Latest URL is now https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 2024-04-24 09:29:44 | INFO | get_latest_default:63 - Latest filename is now CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 2024-04-24 09:29:44 | INFO | update_image:192 - Checksum of current CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337 2024-04-24 09:29:44 | INFO | update_image:208 - Our checksum is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337 2024-04-24 09:29:44 | INFO | update_image:211 - Image CentOS Stream 9 is up-to-date, nothing to do 2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/debian.yml 2024-04-24 09:29:44 | INFO | update_image:179 - Checking image Debian 11 2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bullseye/latest/debian-11-genericcloud-amd64.raw 2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bullseye/latest/SHA512SUMS 2024-04-24 09:29:45 | INFO | update_image:192 - Checksum of current debian-11-genericcloud-amd64-20240211-1654.raw is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4 2024-04-24 09:29:45 | INFO | update_image:208 - Our checksum is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4 2024-04-24 09:29:45 | INFO | update_image:211 - Image Debian 11 is up-to-date, nothing to do 2024-04-24 09:29:45 | INFO | update_image:179 - Checking image Debian 12 2024-04-24 09:29:45 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.raw 2024-04-24 09:29:45 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS 2024-04-24 09:29:46 | INFO | update_image:192 - Checksum of current debian-12-genericcloud-amd64-daily-20240424-1727.raw is sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e 2024-04-24 09:29:46 | INFO | update_image:208 - Our checksum is sha512:5401f8c6361bb2a82c2c24b4b4606d95e77229152a80e61f9c613bc88e25de9257057d0ed68b0256b745c4059162a54970fe4a8daf456b2eb67b4f5db5c97fcc 2024-04-24 09:29:46 | INFO | update_image:229 - New values are {'version': '20240424', 'build_date': datetime.date(2024, 4, 24), 'checksum': 'sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e', 'url': 'https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240424-1727/debian-12-genericcloud-amd64-daily-20240424-1727.raw'} 2024-04-24 09:29:46 | INFO | main:300 - Processing file /etc/images/rockylinux.yml 2024-04-24 09:29:46 | INFO | update_image:179 - Checking image Rocky 9 2024-04-24 09:29:46 | INFO | update_image:182 - Latest download URL is https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2 2024-04-24 09:29:46 | INFO | update_image:185 - Getting checksums from https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2.CHECKSUM 2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current Rocky-9-GenericCloud.latest.x86_64.qcow2 is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651 2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651 2024-04-24 09:29:47 | INFO | update_image:211 - Image Rocky_9 is up-to-date, nothing to do 2024-04-24 09:29:47 | INFO | main:300 - Processing file /etc/images/ubuntu.yml 2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04 2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img 2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS 2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current jammy-server-cloudimg-amd64.img is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710 2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710 2024-04-24 09:29:47 | INFO | update_image:211 - Image Ubuntu_22.04 is up-to-date, nothing to do 2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04 Minimal 2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64.img 2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/minimal/releases/jammy/release/SHA256SUMS 2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current ubuntu-22.04-minimal-cloudimg-amd64.img is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65 2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65 2024-04-24 09:29:48 | INFO | update_image:211 - Image Ubuntu 22.04 Minimal is up-to-date, nothing to do 2024-04-24 09:29:48 | INFO | update_image:179 - Checking image Ubuntu 24.04 2024-04-24 09:29:48 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img 2024-04-24 09:29:48 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/noble/current/SHA256SUMS 2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current noble-server-cloudimg-amd64.img is sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3 2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:d7ba8d5d1d073f2dc8351973bf4f35157c846a0ea6ee16fb2a9f45a78953e4a7 2024-04-24 09:29:48 | INFO | update_image:229 - New values are {'version': '20240423', 'build_date': datetime.date(2024, 4, 23), 'checksum': 'sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3', 'url': 'https://cloud-images.ubuntu.com/noble/20240423/noble-server-cloudimg-amd64.img'} These yaml files are now extended with additional fields and the update.py will take care of the versions, checksum, url and build date to the latest release in the yaml file on every run. latest_checksum_url - URL of the distros checksum file latest_url - URL of the distros latest image mirror_url - URL of the Image File at the local S3 Mirror someexample.yaml --- images: - name: Debian 12 enable: true shortname: debian-12 format: qcow2 login: debian min_disk: 8 min_ram: 512 status: active visibility: public multi: true meta: architecture: x86_64 hw_disk_bus: scsi hw_rng_model: virtio hw_scsi_model: virtio-scsi hw_watchdog_action: reset hypervisor_type: qemu os_distro: debian os_version: '12' replace_frequency: quarterly uuid_validity: last-3 provided_until: none tags: [] latest_checksum_url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS latest_url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.qcow2 versions: - build_date: 2024-04-11 checksum: sha512:3d6f26616e2c8b705993ddef874232887cebe42f1e70fcc020827ac88e8990177d537d34538c71ae2afd3b8baca953fff71eaa7ef71e752e82532c93dcdca436 url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240411-1714/debian-12-genericcloud-amd64-daily-20240411-1714.qcow2 mirror_url: https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-images/debian-12/20240411-debian-12.qcow2 version: '20240411'","s":"Usage","u":"/docs/iaas/components/image-manager/update","h":"#usage","p":844},{"i":853,"t":"The OpenStack Simple Stress is a small stress test for your Openstack Cluster. You can use it for burnin tests or if you want to monitor your cluster perfomance. It is able to start a predefined amount of Servers in specific networks in parallel and serial and removes them afterwards, so you can test your environment to the limits.","s":"Overview","u":"/docs/iaas/components/simple-stress","h":"#overview","p":851},{"i":855,"t":"Prepare to use the Openstack Simple Stress. git clone https://github.com/osism/openstack-simple-stress cd openstack-simple-stress pipenv install pipenv shell","s":"Installation","u":"/docs/iaas/components/simple-stress","h":"#installation","p":851},{"i":857,"t":"The main.py command and his default options while executing the command. --cleanup true --cloud simple-stress --compute-zone nova --debug false --delete true --flavor SCS-2V-8 --floating false --image Ubuntu 22.04 --interval 10 (seconds) --keypair unset --network simple-stress --network-zone nova --number 1 --parallel 1 --prefix simple-stress --storage-zone simple-stress --timeout 600 (seconds) --volume false --volume-number 1 --volume-size 1 (gigabyte) --wait true","s":"Defaults","u":"/docs/iaas/components/simple-stress","h":"#defaults","p":851},{"i":859,"t":"There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Simple Stress will be executed, examples are provided within the git repository. The cloud profile to be used can be specified via the optional --cloud parameter. By default, the cloud profile with the name simple-stress is used. $ python src/main.py -h usage: main [-h] [--cleanup] [--cloud CLOUD] [--compute-zone COMPUTE_ZONE] [--config-dir DIR] [--config-file PATH] [--debug] [--delete] [--flavor FLAVOR] [--floating] [--image IMAGE] [--interval INTERVAL] [--keypair KEYPAIR] [--network NETWORK] [--network-zone NETWORK_ZONE] [--nocleanup] [--nodebug] [--nodelete] [--nofloating] [--novolume] [--nowait] [--number NUMBER] [--parallel PARALLEL] [--prefix PREFIX] [--storage-zone STORAGE_ZONE] [--timeout TIMEOUT] [--volume] [--volume-number VOLUME_NUMBER] [--volume-size VOLUME_SIZE] [--wait] options: -h, --help show this help message and exit --cleanup --cloud CLOUD Cloud name --compute-zone COMPUTE_ZONE Compute availability zone to use --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over- ridden. The set is parsed after the file(s) specified via previous --config- file, arguments hence over-ridden options in the directory take precedence. This option must be set from the command-line. --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the command-line. --debug --delete --flavor FLAVOR --floating --image IMAGE --interval INTERVAL --keypair KEYPAIR --network NETWORK --network-zone NETWORK_ZONE Network availability zone to use --nocleanup The inverse of --cleanup --nodebug The inverse of --debug --nodelete The inverse of --delete --nofloating The inverse of --floating --novolume The inverse of --volume --nowait The inverse of --wait --number NUMBER --parallel PARALLEL --prefix PREFIX --storage-zone STORAGE_ZONE Storage availability zone to use --timeout TIMEOUT --volume --volume-number VOLUME_NUMBER --volume-size VOLUME_SIZE --wait Running a small and simple test on your Openstack environment, using Ubuntu_22.04 image with the flavor of 2VCPUs and 8Gigabytes of RAM, starting 6 servers, 2 parallel each with a volume size of 20Gigabytes. $ python src/main.py --network test-net --flavor SCS-2V-8 --image Ubuntu_22.04 --number 6 --parallel 2 --volume-size 20 2024-04-23 11:47:16 | INFO | Checking flavor SCS-2V-8 2024-04-23 11:47:17 | INFO | flavor.id = 926f952f-0714-4c55-92c2-7514191fecce 2024-04-23 11:47:17 | INFO | Checking image Ubuntu_22.04 2024-04-23 11:47:17 | INFO | image.id = 667649d6-e828-403b-8871-15dde7b9ce85 2024-04-23 11:47:17 | INFO | Checking network test-net 2024-04-23 11:47:18 | INFO | network.id = 9688192e-11dd-4618-a18c-99d3267f630a 2024-04-23 11:47:18 | INFO | Creating server simple-stress-0 2024-04-23 11:47:18 | INFO | Creating server simple-stress-1 2024-04-23 11:47:18 | INFO | Waiting for server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0) 2024-04-23 11:47:18 | INFO | Waiting for server e485697f-feae-458c-952d-000072374c3f (simple-stress-1) 2024-04-23 11:47:28 | INFO | Waiting for boot / test results of 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0) 2024-04-23 11:47:29 | INFO | Waiting for boot / test results of e485697f-feae-458c-952d-000072374c3f (simple-stress-1) 2024-04-23 11:47:39 | INFO | Deleting server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0) 2024-04-23 11:47:39 | INFO | Waiting for deletion of server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0) 2024-04-23 11:47:39 | INFO | Deleting server e485697f-feae-458c-952d-000072374c3f (simple-stress-1) 2024-04-23 11:47:40 | INFO | Waiting for deletion of server e485697f-feae-458c-952d-000072374c3f (simple-stress-1) 2024-04-23 11:47:49 | INFO | Creating server simple-stress-2 2024-04-23 11:47:50 | INFO | Creating server simple-stress-3 2024-04-23 11:47:50 | INFO | Waiting for server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2) 2024-04-23 11:47:51 | INFO | Waiting for server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3) 2024-04-23 11:48:00 | INFO | Waiting for boot / test results of 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2) 2024-04-23 11:48:01 | INFO | Waiting for boot / test results of a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3) 2024-04-23 11:48:11 | INFO | Deleting server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3) 2024-04-23 11:48:12 | INFO | Waiting for deletion of server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3) 2024-04-23 11:48:12 | INFO | Deleting server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2) 2024-04-23 11:48:12 | INFO | Waiting for deletion of server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2) 2024-04-23 11:48:22 | INFO | Creating server simple-stress-4 2024-04-23 11:48:22 | INFO | Waiting for server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4) 2024-04-23 11:48:22 | INFO | Creating server simple-stress-5 2024-04-23 11:48:23 | INFO | Waiting for server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5) 2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4) 2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5) 2024-04-23 11:48:55 | INFO | Deleting server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4) 2024-04-23 11:48:55 | INFO | Deleting server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5) 2024-04-23 11:48:55 | INFO | Waiting for deletion of server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4) 2024-04-23 11:48:55 | INFO | Waiting for deletion of server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5) 2024-04-23 11:49:05 | INFO | Server 049bf974-b0fd-467f-aabd-3593b2a409a4 finished 2024-04-23 11:49:05 | INFO | Server e485697f-feae-458c-952d-000072374c3f finished 2024-04-23 11:49:05 | INFO | Server a098cc12-94ff-4036-bf42-4fc08287809f finished 2024-04-23 11:49:05 | INFO | Server 26595dd3-09d4-4758-8d1f-58a40b681d11 finished 2024-04-23 11:49:05 | INFO | Server 05b9f996-5a06-4359-b495-3463cc7b81e0 finished 2024-04-23 11:49:05 | INFO | Server 8d372de6-ca07-4afb-9e80-1589fd5242e8 finished 2024-04-23 11:49:05 | INFO | Runtime: 107.4460s Using a config directory with configfiles to run the test. Path to a config directory to pull *.conf files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set is parsed after the file(s) specified via previous --config file, arguments hence over-ridden options in the directory take precedence. This option must be set from the command-line. python src/main.py --config-dir /path/to/config-dir","s":"Usage","u":"/docs/iaas/components/simple-stress","h":"#usage","p":851},{"i":861,"t":"The config files which can be used for main.py are using the oslo.config format, you can set the command line options as key = value pair and create your own config files matching your setup. mytest.conf [DEFAULT] cloud = simple-stress network = test-net number = 6 parallel = 2 flavor = SCS-2V-8 image = Ubuntu_22.04 volume-size = 20","s":"Config files","u":"/docs/iaas/components/simple-stress","h":"#config-files","p":851},{"i":865,"t":"Infrastructure as a Service (IaaS) with OpenStack Software Defined Storage (SDS) with Ceph Bare Metal as a Service (BMaaS) with Ironic Software Defined Networking (SDN) with SONiC & OVN Kubernetes (K8s) with K3S Kubernetes as a Service (KaaS) with Gardener Kubernetes as a Service (KaaS) with Cluster API Identity & Access Management with Keycloak Privileged Access Management (PAM) to all infrastructure with Teleport Logging, Monitoring & Telemetry with Prometheus & Grafana Realtime insights with Netdata Simple virtualization & containerization with Proxmox VE","s":"Components in a cluster","u":"/docs/iaas/guides/concept-guide/","h":"#components-in-a-cluster","p":862},{"i":868,"t":"Compute Plane Control Plane Data Plane Management Plane Monitoring Plane Network Plane","s":"Layers in a cluster","u":"/docs/iaas/guides/concept-guide/","h":"#layers-in-a-cluster","p":862},{"i":870,"t":"Compute architecture Storage architecture Network architecture Identity architecture Control plane architecture","s":"Cluster design","u":"/docs/iaas/guides/concept-guide/","h":"#cluster-design","p":862},{"i":872,"t":"Hyper-converged infrastructure (HCI)","s":"Use cases","u":"/docs/iaas/guides/concept-guide/","h":"#use-cases","p":862},{"i":874,"t":"Control nodes Compute nodes Storage nodes Network nodes Manager nodes Switches Network interface cards","s":"Hardware Bill of Materials","u":"/docs/iaas/guides/concept-guide/","h":"#hardware-bill-of-materials","p":862},{"i":876,"t":"The Concept Guide explains which components and modules make up OSISM. It also explains the use cases. The Deploy Guide explains how the nodes of a cluster are created and bootstrapped. It also explains how the individual modules can be deployed. The Upgrade Guide explains how the individual modules can be upgraded. The Configuration Guide explains how the individual modules can be configured. The Operations Guide explains how individual tasks can be done in day-to-day business in a running cluster. The Troubleshooting Guide explains how to resolve problems. It is an extension of the Operations Guide. The User Guide is intended for users of the individual components. It contains best practices, as well as other information.","s":"Guides","u":"/docs/iaas/guides/","h":"","p":875},{"i":878,"t":"Infrastructure as a Service (IaaS) with OpenStack Software Defined Storage (SDS) with Ceph Bare Metal as a Service (BMaaS) with Ironic Software Defined Networking (SDN) with SONiC & OVN Kubernetes (K8s) with K3S Kubernetes as a Service (KaaS) with Gardener Kubernetes as a Service (KaaS) with Cluster API Identity & Access Management with Keycloak Privileged Access Management (PAM) to all infrastructure with Teleport Logging, Monitoring & Telemetry with Prometheus & Grafana Realtime insights with Netdata Simple virtualization & containerization with Proxmox VE","s":"Components","u":"/docs/iaas/guides/concept-guide/components/","h":"","p":877},{"i":880,"t":"Ceph is an Open Source software defined storage platform designed to provide highly scalable object, block and file-based storage in a unified system. Designed for flexibility, Ceph integrates seamlessly with cloud infrastructures like OpenStack and supports diverse workloads with robust, self-healing and self-managing capabilities. Key benefits of Ceph include: Scalability: Ceph is designed to scale from terabytes to exabytes, easily meeting the needs of small businesses to large enterprises. Resilience: With built-in redundancy and data replication, Ceph ensures data integrity and availability even in the face of hardware failures. High performance: Using a distributed architecture, Ceph delivers high throughput and low latency, making it ideal for high-demand workloads. Cost-effective: As open source, Ceph eliminates licensing costs and its ability to run on commodity hardware reduces CapEx. Versatility: Ceph supports a variety of storage types - object, block and file - on a single platform, simplifying storage management and reducing operational complexity.","s":"Ceph","u":"/docs/iaas/guides/concept-guide/components/ceph","h":"","p":879},{"i":883,"t":"Kubernetes as a Service (KaaS) is a cloud service model that simplifies the deployment, management and scaling of Kubernetes clusters. By abstracting the underlying infrastructure, KaaS allows organisations to focus on developing and deploying applications without the complexities of cluster management. One of the most powerful tools for implementing KaaS is the Cluster API, an official Kubernetes project that provides declarative APIs and tools for managing the lifecycle of Kubernetes clusters. Key benefits of Cluster API include: Declarative Cluster Management: Cluster API allows users to define the desired state of clusters using YAML manifests. This declarative approach simplifies the process of creating, updating, and deleting clusters, making it easier to automate and version control cluster configurations. Infrastructure Abstraction: Cluster API abstracts the underlying infrastructure, enabling the deployment of Kubernetes clusters across various environments, including public clouds (AWS, Azure, GCP), private clouds (OpenStack), and on-premises data centers. This abstraction ensures that the same API can be used regardless of the infrastructure provider. Consistent Lifecycle Management: Cluster API standardizes the lifecycle management of Kubernetes clusters, including provisioning, scaling, upgrading, and deletion. This consistency reduces operational overhead and ensures that clusters are managed uniformly across different environments. Extensibility and Customization: Cluster API’s modular architecture allows for extensibility through the use of custom resource definitions (CRDs) and controllers. Organizations can tailor the API to meet specific requirements, such as integrating with existing CI/CD pipelines or adding custom operational logic. Improved Operational Efficiency: By leveraging Cluster API, organizations can automate repetitive tasks, reduce human error, and ensure that clusters are configured according to best practices. This automation leads to increased operational efficiency and faster delivery of applications. By using Kubernetes as a Service with Cluster API, organisations can achieve a highly automated, scalable and consistent approach to managing Kubernetes clusters across different environments. This allows them to focus more on application development, and less on the operational complexities of managing Kubernetes infrastructure.","s":"Cluster API","u":"/docs/iaas/guides/concept-guide/components/clusterapi","h":"","p":882},{"i":888,"t":"Kubernetes as a Service (KaaS) simplifies the deployment, management, and scaling of Kubernetes clusters by abstracting the underlying infrastructure. Gardener by SAP is an advanced KaaS solution that leverages a Kubernetes-native approach to manage Kubernetes clusters at scale. Gardener is designed to provide consistent and efficient cluster management across various cloud environments and on-premises data centers. Key benefits of Gardener include: Kubernetes-Native Design: Gardener operates by treating Kubernetes clusters as first-class citizens. It uses Kubernetes itself to orchestrate the deployment and management of other Kubernetes clusters, ensuring that all operations are consistent and follow Kubernetes best practices. Shoot, Seed, and Garden Clusters: Shoot Clusters: These are the user clusters managed by Gardener, running the workloads. Seed Clusters: These clusters host the control planes of shoot clusters and are managed by the Gardener infrastructure. Garden Cluster: This is the central cluster where the Gardener components run and from which all other clusters (seed and shoot) are managed. Multi-Cloud and Hybrid Cloud Support: Gardener supports deployment across various cloud providers, including AWS, Azure, Google Cloud, and OpenStack, as well as on-premises environments. This multi-cloud capability allows for a consistent Kubernetes experience regardless of the underlying infrastructure. Automated Cluster Management: Gardener automates the lifecycle management of Kubernetes clusters, including provisioning, scaling, upgrading, and healing. This automation reduces operational overhead and ensures clusters are always running optimally. High Availability and Resilience: Gardener ensures high availability by distributing control planes across multiple seed clusters and leveraging cloud provider features to enhance resilience. This design minimizes downtime and enhances the reliability of managed clusters. Extensibility and Customization: Gardener’s architecture allows for customization and extensibility through extensions and webhooks. This flexibility enables organizations to tailor the solution to meet specific requirements and integrate with existing tools and processes. By using Gardener by SAP for Kubernetes as a Service, organisations can achieve a scalable, automated and consistent approach to managing Kubernetes clusters across multiple environments. This allows them to focus on delivering business value through their applications, rather than dealing with the complexities of cluster management.","s":"Gardener","u":"/docs/iaas/guides/concept-guide/components/gardener","h":"","p":887},{"i":893,"t":"Kurt Garloff, 2024-02-20","s":"Setting up OpenStack health monitor on Debian","u":"/docs/iaas/components/openstack-health-monitor","h":"","p":892},{"i":895,"t":"The development of openstack-health-monitor was done on openSUSE 15.x images, just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution. Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here. Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a successor project for the increasingly hard to maintain shell code, this may not be worth the trouble. openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested. The scenario is described in a bit more detail in the repository's README.md file. The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the monitoring section of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up.","s":"Intro","u":"/docs/iaas/components/openstack-health-monitor","h":"#intro","p":892},{"i":897,"t":"So we start a Debian 12 image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard; the instructions use flavor names and image names from the SCS standards. For many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack).","s":"Setting up the driver VM","u":"/docs/iaas/components/openstack-health-monitor","h":"#setting-up-the-driver-vm","p":892},{"i":899,"t":"There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor. The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems.","s":"Internal vs external monitoring","u":"/docs/iaas/components/openstack-health-monitor","h":"#internal-vs-external-monitoring","p":892},{"i":901,"t":"Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own. If openstack availability zone list --compute fails for you without admin rights, please fix your openstack client. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Healh-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)","s":"Unprivileged operation","u":"/docs/iaas/components/openstack-health-monitor","h":"#unprivileged-operation","p":892},{"i":903,"t":"The author prefers to setup the VM via openstack CLI tooling. He has working entries for all clouds he uses in his ~/.config/openstack/clouds.yaml and secure.yaml and has exported the OS_CLOUD environment variable to point to the cloud he is working on to set up the driver VM. The author uses the bash shell. All of this of course could be scripted. So here we go Create the network setup for a VM in a network oshm-network with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network. PUBLIC=$(openstack network list --external -f value -c Name) openstack router create oshm-router openstack router set --external-gateway $PUBLIC oshm-driver-router openstack network create oshm-network openstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet openstack router add subnet oshm-router oshm-subnet Create a security group that allows ssh and ping access openstack security group create sshping openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping openstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping Being at it, we also create the security group for grafana openstack security group create grafana openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana To connect to the VM via ssh later, we create an SSH keypair openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key chmod og-r ~/.ssh/oshm-key.pem Rather than creating a new key (and storing and protecting the private key), we could have passed --public-key and used an existing keypair. Look up Debian 12 image UUID. IMGUUID=$(openstack image list --name \"Debian 12\" -f value -c ID | tr -d '\\r') echo $IMGUUID Sidenote: The tr command is there to handle broken tooling that embeds a trailing \\r in the output. Boot the driver VM openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing --block-device. See diskless flavor blog article. For flavors with local root disks, you could have used the --image $IMGUUID parameter instead. Wait for it to boot (optional) You can look at the boot log with openstack console log show oshm-driver or connect to it via VNC at the URL given by openstack console url show oshm-driver. You can of course also query openstack on the status openstack server list or openstack server show oshm-driver. You can also just create a simple loop: declare -i ctr=0 RC=0 while [ $ctr -le 120 ]; do STATUS=\"$(openstack server list --name oshm-driver -f value -c Status)\" if [ \"$STATUS\" = \"ACTIVE\" ]; then echo \"$STATUS\"; break; fi if [ \"$STATUS\" = \"ERROR\" ]; then echo \"$STATUS\"; RC=1; break; fi if [ -z \"$STATUS\" ]; then echo \"No such VM\"; RC=2; break; fi sleep 2 let ctr+=1 done # return $RC if [ $RC != 0 ]; then false; fi Attach a floating IP so it's reachable from the outside. FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks | sed \"s@^[^:]*:[^']*'\\([0-9\\.]*\\)'.*\\$@\\1@\") FIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID) echo $FIXEDIP $FIXEDPORT openstack floating ip create --port $FIXEDPORT $PUBLIC FLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c \"Floating IP Address\") echo \"Floating IP: $FLOATINGIP\" Remember this floating IP address. Connect to it via ssh ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.) All the following commands are performed on the newly started driver VM.","s":"Driver VM via openstack CLI","u":"/docs/iaas/components/openstack-health-monitor","h":"#driver-vm-via-openstack-cli","p":892},{"i":905,"t":"We need to install the openstack client utilities. sudo apt-get update sudo apt-get install python3-openstackclient sudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient Configure your cloud access in ~/.config/openstack/clouds.yaml clouds: CLOUDNAME: interface: public identity-api-version: 3 #region_name: REGION auth: auth_url: KEYSTONE_ENDPOINT project_id: PROJECT_UUID #alternatively project_name and project_domain_name user_domain_name: default # change to your real domain and secure.yaml (in the same directory) clouds: CLOUDNAME: auth: username: USERNAME password: PASSWORD The CLOUDNAME can be freely chosen. This is the value passed to the openstack CLI with --os-cloud or exported to your environment in OS_CLOUD. The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample clouds.yaml file that works (but lacks the password). Protect your secure.yaml from being read by others: chmod 0600 ~/.config/openstack/secure.yaml. If you are using application credentials instead of username, password to authenticate, you don't need to specify project_id nor project's nor user's domain names in clouds.yaml. Just (in secure.yaml): clouds: CLOUDNAME: auth_type: v3applicationcredential auth: application_credential_id: APPCRED_ID application_credential_secret: \"APPCRED_SECRET\" Configure this to be your default cloud: export OS_CLOUD=CLOUDNAME You might consider adding this to your ~/.bashrc for convenience. Being at it, you might want to add export CLIFF_FIT_WIDTH=1 there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste). Verify that your openstack CLI works: openstack catalog list openstack server list You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases.","s":"Configuring openstack CLI on the driver VM","u":"/docs/iaas/components/openstack-health-monitor","h":"#configuring-openstack-cli-on-the-driver-vm","p":892},{"i":907,"t":"If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in /etc/ssl/certs/ca-certificates.crt. You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the debian user. Add it to your clouds.yaml clouds: CLOUDNAME: cacert: /PATH/TO/CACERT.CRT [...] If you want to allow api_monitor.sh to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment: export OS_CACERT=/PATH/TO/CACERT.CRT Consider adding this to your ~/.bashrc as well.","s":"Custom CA","u":"/docs/iaas/components/openstack-health-monitor","h":"#custom-ca","p":892},{"i":909,"t":"Checkout openstack-health-monitor: sudo apt-get install git bc jq netcat-traditional tmux zstd git clone https://github.com/SovereignCloudStack/openstack-health-monitor cd openstack-health-monitor You may want to start a tmux (or screen) session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect. The script api_monitor.sh is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the README.md file. It is good practice to use tmux. This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to screen over tmux. You should be ready to run one iteration of the openstack-health-monitor now. Run it like this: export IMG=\"Debian 12\" export JHIMG=\"Debian 12\" ./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1 Leave out the -LL if you don't have a working loadbalancer service or replace -LL with -LO if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources). Feel free to study the meaning of all the command line parameters by looking at the README.md. (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.) This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs DOWN, BUILD, creating are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual openstack RESOURCE list and openstack RESOURCE show NAME and RESOURCE being something like router, network, subnet, port, volume, server, floating ip, loadbalancer, loadbalancer pool, loadbalancer listener, security group, keypair, image, ...) The api_monitor.sh uses and APIMonitor_TIMESTAMP prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong. TIMESTAMP is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time). This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least -N 2 to test the ability of the router to route traffic between networks. So expect -n 6 to become -N 2 -n 6 for a very small single-AZ cloud or -n 12 for a large 3 AZ cloud region. So, re-run the api_monitor.sh with the target sizing.","s":"Your first api_monitor.sh iteration","u":"/docs/iaas/components/openstack-health-monitor","h":"#your-first-api_monitorsh-iteration","p":892},{"i":911,"t":"Note that api_monitor.sh uses small flavors (SCS-1V-2 for the N jump hosts and SCS-1L-1 for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors. If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run api_monitor.sh in a loop (which you will) with say 10 VMs (e.g. -N 2 -n 8) in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference. Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of openstack volume list, openstack volume show BROKEN_VOLUME, openstack loadbalancer list, openstack loadbalancer show BROKEN_LB.) Using -w -1 makes api_monitor.sh wait for interactive input whenever an error occurs; this can be convenient for debugging. Once you have single iterations working nicely, we can proceed.","s":"Resource impact and charging","u":"/docs/iaas/components/openstack-health-monitor","h":"#resource-impact-and-charging","p":892},{"i":913,"t":"Typically, we run api_monitor.sh with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here. #!/bin/bash # run_CLOUDNAME.sh # Do some global settings export IMG=\"Debian 12\" export JHIMG=\"Debian 12\" #export OS_CACERT=/home/debian/ca-certificates.pem # Additional settings to override flavors or to # configure email addresses for sending alarms can be set here # Does openstack CLI work? openstack server list >/dev/null || exit 1 # Upload log files to this swift container (which you need to create) #export SWIFTCONTAINER=OS-HM-Logfiles # CLEANUP echo \"Finding resources from previous runs to clean up ...\" # Find Floating IPs FIPLIST=\"\" FIPS=$(openstack floating ip list -f value -c ID) for fip in $FIPS; do FIP=$(openstack floating ip show $fip | grep -o \"APIMonitor_[0-9]*\") if test -n \"$FIP\"; then FIPLIST=\"${FIPLIST}${FIP}_ \"; fi done FIPLIST=$(echo \"$FIPLIST\" | grep -v '^$' | sort -u) # Cleanup previous interrupted runs SERVERS=$(openstack server list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) KEYPAIR=$(openstack keypair list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) VOLUMES=$(openstack volume list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) NETWORK=$(openstack network list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) LOADBAL=$(openstack loadbalancer list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) ROUTERS=$(openstack router list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) SECGRPS=$(openstack security group list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) echo CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS for ENV in $FIPLIST; do echo \"******************************\" echo \"CLEAN $ENV\" bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV echo \"******************************\" done TOCLEAN=$(echo \"$SERVERS $KEYPAIR $VOLUMES $NETWORK $LOADBAL $ROUTERS $SECGRPS \" | grep -v '^$' | sort -u) for ENV in $TOCLEAN; do echo \"******************************\" echo \"CLEAN $ENV\" bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV echo \"******************************\" done # Now run the monitor #exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab \"$@\" exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T \"$@\" Compared to the previous run, we have explicitly set two networks here -N 2 and rely on the iterations being passed in as command line arguments. Add parameter -t if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (-LO) in this example rather than the amphora based one (-LL). You may use one of the existing run_XXXX.sh scripts as example. Beware: eMail alerting with ALARM_EMAIL_ADDRESS and NOTE_EMAIL_ADDRESS (and limiting with -a and -R ) and reporting data to telegraf (option -S) may be present in the samples. Make this script executable (chmod +x run_CLOUDNAME.sh). We wrap a loop around this in run_in_loop.sh: #!/bin/bash # run_in_loop.sh rm stop-os-hm 2>/dev/null while true; do ./run_CLOUDNAME.sh -i 200 if test -e stop-os-hm; then break; fi echo -n \"Hit ^C to abort ...\" sleep 15; echo done Also make this executable (chmod +x run_in_loop.sh). To run this automatically in a tmux window whenever the system starts, we follow the steps in the startup README.md Change OS_CLOUD in startup/run-apimon-in-tmux.sh. (If you need to set OS_CACERT, also add it in this file and pass it into the windows.) Activate everything: mkdir -p ~/.config/systemd/user/ cp -p startup/apimon.service ~/.config/systemd/user/ systemctl --user enable apimon systemctl --user start apimon sudo loginctl enable-linger debian tmux attach oshealthmon This assumes that you are using the user debian for this monitoring and have checked out the repository at ~/openstack-health-monitor/. Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)","s":"Automating startup and cleanup","u":"/docs/iaas/components/openstack-health-monitor","h":"#automating-startup-and-cleanup","p":892},{"i":915,"t":"If you want to change the parameters passed to api_monitor.sh, you best do this by editing run_CLOUDNAME.sh, potentially after testing it with one iteration before. To make the change effective, you can wait until the current 200 iterations are completed and the run_in_loop.sh calls run_CLOUDNAME.sh again. You can also hit ^C in the tmux window that hasapi_monitor.sh running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ^C during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ^C twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ./run_in_loop.sh again. You can also issue the systemctl --user stop apimon command; it will basically do the same thing: Send ^C and then wait for everything to be completed and tear down the tmux session. After waiting for that to complete, you can start it again with systemctl --user start apimon.","s":"Changing parameters and restarting","u":"/docs/iaas/components/openstack-health-monitor","h":"#changing-parameters-and-restarting","p":892},{"i":917,"t":"You can run multiple instances of api_monitor.sh on the same driver VM. In this case, you should rename run_in_loop.sh to e.g. run_in_loop_CLOUDNAME1.sh and call run_CLOUDNAME1.sh from there. Don't forget to adjust startup/run-apimon-in-tmux.sh and startup/kill-apimon-in-tmux.sh to start more windows. It is not recommended to run multiple instances against the same OpenStack project however. While the api_monitor.sh script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the run_CLOUDNAME.sh script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations.","s":"Multiple instances","u":"/docs/iaas/components/openstack-health-monitor","h":"#multiple-instances","p":892},{"i":920,"t":"If wanted, the api_monitor.sh can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the -a N and -R options. In order to enable sending emails from the driver VM, it needs to have postfix (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly. Once you have configured postfix, you can enable eMail notifications using the option -e. Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ALARM_EMAIL_ADDRESSES and NOTE_EMAIL_ADDRESSES environment variables to api_monitor.sh, e.g. by setting it in the run_CLOUDNAME.sh.","s":"eMail","u":"/docs/iaas/components/openstack-health-monitor","h":"#email","p":892},{"i":922,"t":"api_monitor.sh writes a log file with the name APIMonitor_TIMESTAMP.log. It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (TIMESTAMP is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.) Note that api_monitor.sh does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties. The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable SWIFTCONTAINER has been set (in run_COULDNAME.sh) when starting api_monitor.sh. the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER After the 200 iterations, a .psv file (pipe-separated values) is created Stats.STARTTIME-ENDTIME.psv (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured).","s":"Log files","u":"/docs/iaas/components/openstack-health-monitor","h":"#log-files","p":892},{"i":924,"t":"See https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md","s":"Data collection and dashboard","u":"/docs/iaas/components/openstack-health-monitor","h":"#data-collection-and-dashboard","p":892},{"i":926,"t":"To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData: sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key echo \"deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main\" | sudo tee /etc/apt/sources.list.d/influxdata.list sudo apt update sudo apt -y install telegraf In the config file /etc/telegraf/telegraf.conf, we enable [[inputs.influxdb_listener]] service_address = \":8186\" [[outputs.influxdb]] urls = [\"http://127.0.0.1:8086\"] and restart the service (sudo systemctl restart telegraf). Enable it on system startup: sudo systemctl enable telegraf.","s":"telegraf","u":"/docs/iaas/components/openstack-health-monitor","h":"#telegraf","p":892},{"i":928,"t":"We proceed to influxdb: sudo apt-get install influxdb In the configuration file /etc/influxdb/influxdb.conf, ensure that the http interface on port 8086 is enabled. [http] enabled = true bind-address = \":8086\" Restart influxdb as needed with sudo systemctl restart influxdb. Also enable it on system startup: sudo systemctl enable influxdb.","s":"influxdb","u":"/docs/iaas/components/openstack-health-monitor","h":"#influxdb","p":892},{"i":930,"t":"You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter -S CLOUDNAME to the api_monitor.sh call in run_CLOUDNAME.sh. Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete).","s":"Add -S CLOUDNAME to your run_CLOUDNAME.sh script","u":"/docs/iaas/components/openstack-health-monitor","h":"#add--s-cloudname-to-your-run_cloudnamesh-script","p":892},{"i":932,"t":"Basic config​ Finally grafana: We (still as root) follow https://www.server-world.info/en/note?os=Debian_12&p=grafana sudo wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key echo \"deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main\" | sudo tee -a /etc/apt/sources.list.d/grafana.list sudo apt update sudo apt -y install grafana The config file /etc/grafana/grafana.ini needs some adjustments: Set the hostname in [server] section: domain = health.YOURCLOUD.sovereignit.cloud. Set the protocol = https if not enabled by default. You can use a hostname of your liking, but we will need to create TLS certificates for this host. So we should have control over DNS TXT records for this domain if we want to use Let's Encrypt with DNSAUTH. The sovereignit.cloud domain is controlled by the SCS project team and has been used for a number of health mon instances. In this same section, set cert_file = /etc/grafana/health-fullchain.pem and cert_key = /etc/grafana/health-key.pem. Ensure that both files are readable by root:grafana and that the key file is not world-readable. Configure the admin access. In section [security], set the admin_user = admin and admin_password = SOME_SECRET_PASS which you keep private. Allow local data sources (same section): data_source_proxy_whitelist = localhost:8088 localhost:8086 Let's disallow user signup (in section [users]): allow_sign_up = false and allow_org_create = false. We do the OIDC connection with [auth.github] later. We can now restart the service: sudo systemctl restart grafana-server. Being at it, also enable it on system startup: sudo systemctl enable grafana-server. You should now be able to access your dashboard on https://health.YOURCLOUD.sovereignit.de:3000 and log in via the configured username admin and your SOME_SECRET_PASS password. Enable influx database in grafana​ In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to http://localhost:8086 (despite this being the suggestion). Set the database name to telegraf. Save&test should succeed. Importing the dashboard​ Go to Home, Dashboards, New, Import. Upload the dashboard .json file from the repository, user the Grafana-10 variant if you use Grafana 10 or newer. In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.) Save. Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable). No data displayed?​ Sometimes, you may see a panel displaying \"no data\" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana. One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved. Dashboard features​ Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended. The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously. You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term. github OIDC integration​ The SCS providers do allow all github users that belong to the SovereignCloudStack organization to get Viewer access to the dashboards by adding a client_id and client_secret in the [github.auth] section that you request from the SCS github admins (github's oauth auth). This allows to exchange experience and to get a feeling for the achievable stability. (Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)","s":"grafana","u":"/docs/iaas/components/openstack-health-monitor","h":"#grafana","p":892},{"i":934,"t":"Install influxdb via apt: https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss Install telegraf (same apt repo as influxdb): sudo apt update && sudo apt install telegraf Install grafana: https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository Prepare configuration by using the config files from the repository as an alternative to doing the changes manually (as described above): sudo cp dashboard/telegraf.conf /etc/telegraf && sudo chown root:root /etc/telegraf/telegraf.conf && sudo chmod 0644 /etc/telegraf/telegraf.conf sudo cp dashboard/config.toml /etc/influxdb && sudo chown root:influxdb /etc/influxdb/config.toml && sudo chmod 0640 /etc/influxdb/config.toml sudo cp dashboard/grafana.ini /etc/grafana && sudo chown root:grafana /etc/grafana/grafana.ini && sudo chmod 0640 /etc/grafana/grafana.ini These config files should work as long as the versions of telegraf, influxdb and grafana don't evolve too far from the ones used in the repository. (Otherwise refer to above instructions how to tweak the default config files.) Changes to /etc/grafana/grafana.ini as we do tls termination at the reverse proxy: set protocol = http comment out domain option (? FIXME) or set it to the hostname comment out cert_* options Also change the admin password in grafana.ini. Changes to /etc/grafana/grafana.ini if github auth should not be used yet: comment out whole [auth.github] section for now (can be enabled later) Restart services: sudo systemctl restart telegraf && sudo systemctl restart influxdb && sudo systemctl restart grafana-server Configuration in grafana web gui: Login to grafana http(s)://:3000 with user admin and default password from /etc/grafana/grafana.ini and change password. Create influxdb datasource with url http://localhost:8086 and database name telegraf. Finally import dashboard dashboard/openstack-health-dashboard.json to grafana. TODO: Reverse proxy (aka ingress) with Let's Encrypt cert Github auth as described above","s":"Alternative approach to install and configure the dashboard behind a reverse proxy","u":"/docs/iaas/components/openstack-health-monitor","h":"#alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy","p":892},{"i":936,"t":"The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained.","s":"Maintenance","u":"/docs/iaas/components/openstack-health-monitor","h":"#maintenance","p":892},{"i":938,"t":"It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See https://wiki.debian.org/UnattendedUpgrades. If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and grafana (port 3000).","s":"Unattended upgrades","u":"/docs/iaas/components/openstack-health-monitor","h":"#unattended-upgrades","p":892},{"i":940,"t":"You can just do a git update in the openstack-health-monitor directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ^C, see above in the restart section.","s":"Updating openstack-health-monitor","u":"/docs/iaas/components/openstack-health-monitor","h":"#updating-openstack-health-monitor","p":892},{"i":942,"t":"The system holds two things that you might consider valuable for long-term storage: (1) The log files. These are compressed and uploaded to object storage if you enable the SWIFTCONTAINER setting, which probably means that these do not need any additional backing up then. (2) The influx time series data. Back up the data in /var/lib/influxdb. Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, clouds.yaml, etc. Be careful not to expose sensitive data by granting too generous access to your backed up files.","s":"Backup","u":"/docs/iaas/components/openstack-health-monitor","h":"#backup","p":892},{"i":945,"t":"In case there is trouble with your cloud, the normal course of action to analyze is as follows: Look at the dashboard (see above) Connect to the driver VM and attach to the tmux session and look at the console output of api_monitor.sh Analyze the logfile (locally on the driver VM or grab it from the object storage)","s":"Debugging issues","u":"/docs/iaas/components/openstack-health-monitor","h":"#debugging-issues","p":892},{"i":947,"t":"When VM instances are created successfully, but then end up in ERROR state, the api_monitor.sh does an explicit openstack server show, so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files. Sometimes the VMs end up being ACTIVE as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail. To gather more details, you can look at the console output openstack console log show VM (where VM is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ssh -i APIMonitor_XXXXX_JH.pem debian@FIP, whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP. Replace XXXXX with the number in your current APIMonitor prefix, FIP with the floating IP address of the responsible JumpHost and debian with the user name used by the images you boot. Use 223 to connect to the second VM in the network, 224 the third etc. When logged in, look at /var/log/cloud-init-output.log and /var/log/cloud-init.log. You can find the metadata in /var/lib/cloud/instance/. You will not have much time to look around -- the still running api_monitor.sh script does continue and clean things up again. So you might want to suspend it with ^Z (and continue it later with fg). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the run_CLOUDNAME.sh script as it would do cleanup against the running instance, but rather copy the api_monitor.sh command line from the bottom (without the exec), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach -w -1 to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work.","s":"Analyzing failures","u":"/docs/iaas/components/openstack-health-monitor","h":"#analyzing-failures","p":892},{"i":949,"t":"If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard). There are a few things that may need support from a cloud admin: Volumes may end up permanently in a deleting or reserved state or may be in-use, attached to a VM that has long gone. The admin needs to set the state to error and then delete them. Loadbalancers may end up in a PENDING_XXX state (XXX being CREATE, UPDATE or DELETE) without ever changing. This also needs the cloud admin to set the status to ERROR, so it can be cleaned up. amphorae are more prone to this than ovn LBs. More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted. The source of this document can be found in the SovereignCloudStack/openstack-health-monitor repository. Author: SCS Community, License: CC by Attribution 4.0 International","s":"Cleaning things up","u":"/docs/iaas/components/openstack-health-monitor","h":"#cleaning-things-up","p":892},{"i":954,"t":"The open source project Kolla from the OpenInfra Foundation is used in OSISM for the life cycle management of OpenStack. Kolla’s mission is to provide production-ready containers and deployment tools for operating OpenStack clouds. Kolla has been actively developed by a very diverse team for 10 years and is one of the most common (if not the most common) life cycle management tool for OpenStack. The container images provided by Kolla are not only used by Kolla itself. They are also used in TripleO, the basis for the now discontinued RedHat OpenStack Platform, and the OpenStack Kubernetes Operators, the basis for the new OpenStack Services on OpenShift from Redhat.","s":"Lifecycle Management of OpenStack in OSISM","u":"/docs/iaas/guides/concept-guide/components/openstack","h":"#lifecycle-management-of-openstack-in-osism","p":952},{"i":956,"t":"OpenStack Ironic is a project that provides Baremetal as a Service (BMaaS), enabling the provisioning and management of physical machines in a cloud-like manner. Unlike traditional virtualization, where virtual machines run on top of a hypervisor, BMaaS allows users to directly manage and utilize physical hardware, offering the full performance and isolation of dedicated servers. Key benefits of OpenStack Ironic: Hardware Provisioning: Ironic automates the provisioning of physical servers, including the deployment of operating systems and configuration of hardware settings. This automation streamlines the setup process, reducing the time and effort required to bring new servers online. Integration with OpenStack: Ironic integrates seamlessly with other OpenStack services, such as Nova for compute management, Neutron for networking, and Glance for image services. This integration allows users to manage both virtual and baremetal resources through a unified OpenStack dashboard. Support for Multiple Hardware Drivers: Ironic supports a wide range of hardware through various drivers, including IPMI, Redfish, and vendor-specific drivers. This flexibility ensures compatibility with a diverse set of hardware platforms and management interfaces. Resource Management and Scheduling: Ironic leverages OpenStack’s scheduling capabilities to manage the allocation of physical servers, ensuring optimal utilization of hardware resources. Users can request specific hardware configurations and Ironic will match these requests with available resources. Provisioning States: Ironic manages the lifecycle of baremetal nodes through various provisioning states, such as enroll, available, active, and maintenance. This state management ensures that hardware is correctly tracked and managed throughout its lifecycle. Network Integration: Ironic integrates with Neutron to provide networking services for baremetal nodes, including support for VLANs, flat networks, and more complex networking setups. This integration ensures that baremetal nodes can be seamlessly integrated into existing network topologies. By utilizing OpenStack Ironic, organizations can leverage the benefits of BMaaS, providing users with the performance and control of physical hardware while maintaining the flexibility and scalability of cloud infrastructure. This approach is particularly beneficial for workloads that require high performance, low latency, or specific hardware configurations that are not achievable with virtual machines.","s":"Ironic","u":"/docs/iaas/guides/concept-guide/components/ironic","h":"","p":955},{"i":970,"t":"info Parts of this chapter are based on the OpenStack Architecture Design Guide. The sources for this guide can be found in repostory openstack/arch-design and have been published under the Apache Licence 2.0.","s":"Cluster design","u":"/docs/iaas/guides/concept-guide/design","h":"","p":969},{"i":977,"t":"Proxmox Virtual Environment (Proxmox VE) is an open-source server virtualization management platform designed to manage virtual machines (VMs), containers, and software-defined storage. Leveraging the power of KVM (Kernel-based Virtual Machine) for full virtualization and LXC (Linux Containers) for containerization, Proxmox VE provides a robust and flexible solution for enterprise virtualization needs. Key benefits of Proxmox VE: Comprehensive Virtualization: KVM Virtual Machines: Proxmox VE supports KVM-based virtualization, allowing users to run multiple, isolated VMs on a single physical server. KVM provides near-native performance and supports various operating systems, including Windows, Linux, and BSD. LXC Containers: For lightweight virtualization, Proxmox VE uses LXC containers, which share the host’s kernel but maintain isolated user spaces. This approach is ideal for runningx Linux-based applications with minimal overhead. Integrated Management Interface: Proxmox VE includes a web-based management interface, enabling administrators to manage VMs, containers, storage, and network configurations from a single, intuitive dashboard. This interface supports various administrative tasks, including VM creation, backup scheduling, and live migration. High Availability (HA) and Clustering: Proxmox VE supports clustering, allowing multiple Proxmox servers to be managed as a single entity. Clustering facilitates high availability by automatically restarting VMs or containers on other nodes in the event of hardware failure, ensuring minimal downtime. Storage Options: Proxmox VE offers flexible storage management with support for local storage, shared storage (NFS, iSCSI, Ceph), and distributed storage systems. The built-in Proxmox VE storage replication feature ensures data redundancy and high availability. Backup and Restore: Proxmox VE includes integrated backup tools, supporting scheduled backups of VMs and containers. These backups can be stored locally or on remote storage solutions, and can be restored easily via the management interface. Networking: Proxmox VE supports advanced networking features, including VLANs, bridges, and bonding. This allows for complex network topologies and efficient use of network resources. The platform also integrates seamlessly with SDN (Software-Defined Networking) solutions for enhanced network management. By using Proxmox VE, organizations can leverage a powerful, open-source virtualization platform that combines the benefits of both KVM and LXC. Proxmox VE’s comprehensive feature set, intuitive management interface, and robust high availability options make it an ideal choice for managing virtualized environments efficiently and effectively.","s":"Proxmox VE","u":"/docs/iaas/guides/concept-guide/components/proxmox","h":"","p":976},{"i":980,"t":"info The brands, models and configurations listed are examples. There is no single best specification for building a cluster. It always depends very much on the requirements of the cluster and the situation. The examples are not minimal and include various preferences of ours. The choice of hardware always depends very much on the requirements, the available budget and also the future plans of the cluster. There is no universal hardware recommendation that fits all cases. These are all just examples.","s":"Hardware Bill of Materials","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"","p":979},{"i":982,"t":"A control node is responsible for running all or most of the OpenStack services that manage API services and their associated runtimes. These nodes are essential for users to interact with the cluster and maintain its managed state. However, control nodes typically do not run user virtual machines. It is therefore advisable to replicate the control nodes to ensure high availability and fault tolerance. A good starting point for achieving RAFT quorum is to have three control nodes. 2x SSD with at least 480 GByte for the operating system 4x NVMe with at least 960 GByte for the services 128 GByte memory (it should be possible to upgrade to 256 GByte, or use 256 GByte directly) Dual port NIC with 25G or 100G (depending on which leaf switches are used) 2 CPU sockets each with at least 32 cores or 1 CPU socket with at least 64 cores Real world example: https://www.supermicro.com/de/products/system/clouddc/1u/sys-121c-tn10r","s":"Control nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#control-nodes","p":979},{"i":984,"t":"Compute nodes are dedicated to running users' virtual machines. They do not host API services, storage services or network routers, other than the basic network infrastructure required to connect virtual machines. 2x SSD or NVMe with at least 480 GByte for the operating system 2x NVMe with at least 1.92 TByte for local storage recommended (if this is not implemented at the start, the model should be selected so that NVMe devices can be added later, the size depends on which CPU and how much memory is used, 7.68 TByte is more likely to be used) Dual port NIC with 25G or 100G (depending on which leaf switches are used) CPU sockets and memory depends on the requirement Real world example: https://www.supermicro.com/de/products/twin","s":"Compute nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#compute-nodes","p":979},{"i":986,"t":"A dedicated storage node runs only storage services. This can be necessary in larger deployments to protect the storage services from ressource starvation through user workloads. Read the Ceph hardware recommendations first. 2x SSD or NVMe with at least 480 GByte for the operating system Dual port NIC with 100G (we recommend always using 100G for storage nodes) Storage devices depends on the requirement CPU sockets and memory depends on the storage devices used","s":"Storage nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#storage-nodes","p":979},{"i":988,"t":"A dedicated network node runs only network services. This is normally necessary to be able to map safety zones. External networks terminate on the network nodes. Real world example: Supermicro SuperServer SYS-110D-8C-FRAN8TP 2x SSD or NVMe with at least 480 GByte for the operating system 2x DIMM slots with 32 GByte modules, leave 2 DIMM slots open for later expansion If required, an additional dual port 25G or 100G NIC in the PCIe expansion slots Intel Xeon Processor D-2733NT (this is onboard and not selectable)","s":"Network nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#network-nodes","p":979},{"i":990,"t":"The manager node, also known as the deploy node or deployment node, is designated to manage the deployment process of all services. It is often also utilized to host components of the monitoring services. It serves as the operator's entry point into the cluster for operations. 2x SSD or NVMe with at least 1.92 TByte for the operating system and the services 64 GByte memory (it should be possible to upgrade to 128 GByte, or use 128 GByte directly) Dual port NIC with 25G or 100G (depending on which leaf switches are used) 1 CPU socket with at least 16 cores Real world example: https://www.supermicro.com/de/products/system/clouddc/1u/sys-121c-tn10r","s":"Manager nodes","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#manager-nodes","p":979},{"i":993,"t":"1G: Edgecore AS4610-54T 10G: Edgecore DCS202 - AS5835-54T","s":"Management switches","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#management-switches","p":979},{"i":995,"t":"It is recommended to always use 100G for the data plane and the storage nodes. Especially when using all-flash storage nodes, there is then enough bandwidth available. The more and the larger flash devices you use, the more bandwidth is required. With the leaf switches for the compute plane, it depends on how large the compute nodes are. The more CPU sockets/cores and the more memory the compute nodes have, the more bandwidth is required on the compute nodes. Depending on how large the racks are (or better how much power you can use in it), it may make sense to work with 100G switches for the compute plane or with 25G switches if 4x 25G per compute node are used instead of 2x 25G per compute node (if the compute nodes are large enough). 25G: Edgecore DCS203 - AS7326-56X 100G: Edgecore DCS204 - AS7726-32X","s":"Leaf switches","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#leaf-switches","p":979},{"i":997,"t":"100G: Edgecore DCS204 - AS7726-32X 400G: Edgecore DCS510 - AS9716-32D","s":"Spine switches","u":"/docs/iaas/guides/concept-guide/hardware-bom","h":"#spine-switches","p":979},{"i":1008,"t":"This section contains the documentation of the Ansible collection osism.commons. Role Description osism.commons.network osism.commons.packages osism.commons.services osism.commons.sshconfig osism.commons.timezone","s":"Commons","u":"/docs/iaas/guides/configuration-guide/commons/","h":"","p":1007},{"i":1012,"t":"With the osism.commons.certificates role, it is possible to add custom CA certificates on a node. The parameter should be used in the environments/configuration.yml file. environments/configuration.yml certificates_ca: - name: custom.crt certificate: | -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- The role is part of the bootstrap of a node. CA certificates can be added at a later point in time via osism apply certificates on a node. Further details on the use of self-signed certificates can be found in chapter Self-signed certificates of the configuration guide.","s":"Certificates","u":"/docs/iaas/guides/configuration-guide/commons/certificates","h":"","p":1011},{"i":1014,"t":"With the osism.commons.packages role, it is possible to add packages on a node The parameters should be used in the inventory or in the environments/configuration.yml file. The role is applied during the bootstrap. The role can be applied manually using osism apply packages. The following packages are installed by default. required_packages_default: - curl - dmidecode - ethtool - iotop - jq - lsscsi - ltrace - mtr - nvme-cli - pciutils - rsyslog - socat - sysstat - tmux - tree - whois Additional packages can be added via the required_packages_extra parameter. required_packages_extra: []","s":"Packages","u":"/docs/iaas/guides/configuration-guide/commons/packages","h":"","p":1013},{"i":1017,"t":"With Debian, the packages listed in required_packages_distribution are installed by default. required_packages_distribution: - command-not-found - debconf - debsums - htop - iftop - iperf - multitail - ncdu - pv - python-is-python3 - selinux-utils - ssh The apt_cache_valid_time parameter can be used to set the cache_valid_time paremter of the ansible.builtin.apt module. The module updates the apt cache if it is older than the cache_valid_time. The parameter is set in seconds and defaults to 3600.","s":"Debian","u":"/docs/iaas/guides/configuration-guide/commons/packages","h":"#debian","p":1013},{"i":1019,"t":"With CentOS, the packages listed in required_packages_distribution are installed by default. required_packages_distribution: - libselinux-utils - openssh","s":"CentOS","u":"/docs/iaas/guides/configuration-guide/commons/packages","h":"#centos","p":1013},{"i":1021,"t":"The upgrade_packages parameter can be used to configure the upgrade of packages. The parameter is set to true by default.","s":"Upgrade of packages","u":"/docs/iaas/guides/configuration-guide/commons/packages","h":"#upgrade-of-packages","p":1013},{"i":1023,"t":"With the osism.commons.resolvconf role, it is possible to manage the used DNS servers on a node.","s":"Resolvconf","u":"/docs/iaas/guides/configuration-guide/commons/resolvconf","h":"","p":1022},{"i":1025,"t":"With the osism.commons.services role, it is possible to manage services on a node in a general form. This allows you to either activate any services or indicate that specific services are running and should be deactivated.","s":"Services","u":"/docs/iaas/guides/configuration-guide/commons/services","h":"","p":1024},{"i":1027,"t":"services_required_default: - cron services_required_extra: [] services_required: \"{{ services_required_default + services_required_extra }}\" note services_required should not be overwritten. Use services_required_extra to add extra services.","s":"Start and enable required services","u":"/docs/iaas/guides/configuration-guide/commons/services","h":"#start-and-enable-required-services","p":1024},{"i":1029,"t":"services_warning_default: - nscd services_warning_extra: [] services_warning: \"{{ services_warning_default + services_warning_extra }}\" note services_warning should not be overwritten. Use services_warning_extra to add extra services.","s":"Note on services that should be deactivated","u":"/docs/iaas/guides/configuration-guide/commons/services","h":"#note-on-services-that-should-be-deactivated","p":1024},{"i":1031,"t":"With the osism.commons.sysctl role, it is possible to manage the attributes of the kernel via sysctl on a node. The following defaults are set via the parameter sysctl_defaults. Group Attribute Default elasticsearch vm.max_map_count 262144 rabbitmq net.ipv4.tcp_keepalive_time 6 rabbitmq net.ipv4.tcp_keepalive_intvl 3 rabbitmq net.ipv4.tcp_keepalive_probes 3 rabbitmq net.core.wmem_max 16777216 rabbitmq net.core.rmem_max 16777216 rabbitmq net.ipv4.tcp_fin_timeout 20 rabbitmq net.ipv4.tcp_tw_reuse 1 rabbitmq net.core.somaxconn 4096 rabbitmq net.ipv4.tcp_syncookies 0 rabbitmq net.ipv4.tcp_max_syn_backlog 8192 generic vm.swappiness 1 compute net.netfilter.nf_conntrack_max 1048576 The sysctl_extra parameter can be used to set your own parameters or overwrite existing parameters in the defaults. Set attribute fs.inotify.max_user_instances to 256 for all nodes in group generic sysctl_extra: generic: - name: fs.inotify.max_user_instances value: 256","s":"Sysctl","u":"/docs/iaas/guides/configuration-guide/commons/sysctl","h":"","p":1030},{"i":1033,"t":"With the osism.commons.timezone role, it is possible to manage the used timezone on a node. This role is just a wrapper for the community.general.timezone module. The role also installs the tzdata package. Parameter Default Description timezone_hwclock UTC Whether the hardware clock is in UTC or in local timezone. timezone_name UTC Name of the timezone for the system clock.","s":"Timezone","u":"/docs/iaas/guides/configuration-guide/commons/timezone","h":"","p":1032},{"i":1035,"t":"With the osism.commons.sshconfig role, it is possible to manage a SSH config file in the home directory of the operator user.","s":"SSH Config","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","h":"","p":1034},{"i":1037,"t":"The sshconfig_extra parameter can be used to add any other SSH configuration to the .ssh/config file. sshconfig_extra: | Host github.com ProxyCommand nc -X connect -x :> ssh.github.com 443","s":"Extra config","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","h":"#extra-config","p":1034},{"i":1039,"t":"In the testbed the /home/dragon/.ssh/config file is created on the manager node testbed-manager. Example for an assembled /home/dragon/.ssh/config file Host testbed-manager HostName testbed-manager.testbed.osism.xyz User dragon Port 22 IdentityFile /opt/ansible/secrets/id_rsa.operator #################### Host testbed-node-0 HostName testbed-node-0.testbed.osism.xyz User dragon Port 22 IdentityFile /opt/ansible/secrets/id_rsa.operator #################### Host testbed-node-1 HostName testbed-node-1.testbed.osism.xyz User dragon Port 22 IdentityFile /opt/ansible/secrets/id_rsa.operator #################### Host testbed-node-2 HostName testbed-node-2.testbed.osism.xyz User dragon Port 22 IdentityFile /opt/ansible/secrets/id_rsa.operator","s":"Example","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","h":"#example","p":1034},{"i":1041,"t":"Parameter Default Description sshconfig_groupname all All nodes in this group are included. sshconfig_order 20 The .ssh/config.d directory is used to prepare the .ssh/config file. You can add your own files in this directory. Everything with a filename prefix smaller than sshconfig_order is placed at the beginning of the assembled .ssh/config file. Anything with a filename prefix greater than sshconfig_order goes at the end. sshconfig_port 22 The SSH port. sshconfig_private_key_file /opt/ansible/secrets/id_rsa.operator The identity file to use. The file itself must already exist there. The file is created by the osism.services.manager role. sshconfig_user \"{{ operator_user }}\" The user in which home directory the .ssh/config file will be generated. sshconfig_extra \"\" Add additional SSH configuration to the end of the .ssh/config file.","s":"Defaults","u":"/docs/iaas/guides/configuration-guide/commons/sshconfig","h":"#defaults","p":1034},{"i":1043,"t":"With the osism.commons.user role, it is possible to manage additional user accounts on a node. Users are managed via the user_list parameter. user_list: - name: testing key: ssh-rsa AAAAB... # default for groups is user_groups # groups: groups: - docker # default is a group with the name of the user # or user_primary_group if set # primary_group: dragon - name: testing_github key: https://github.com/testing.keys By default a new group with the name of a user will be created and assigned as primary group. It is possible to use an already existing group as primary group for all users. Can be overwritten with the user specific primary_group key. user_primary_group: dragon If all users should be added to other specific groups by default, the user_groups parameter can be used. Can be overwritten with the user specific groups key. user_groups: - docker If users should be deleted, they are added to the user_delete list. user_delete: - user_to_delete_1 - user_to_delete_2","s":"User","u":"/docs/iaas/guides/configuration-guide/commons/user","h":"","p":1042},{"i":1045,"t":"The inventory used for the environment is located in the inventory directory.","s":"Inventory","u":"/docs/iaas/guides/configuration-guide/inventory","h":"","p":1044},{"i":1047,"t":"The manager has his own inventory which is used exclusively for the seed phase of the manager. It is located in the directory environments/manager. There is a hosts file with only the manager node in it.","s":"Manager","u":"/docs/iaas/guides/configuration-guide/inventory","h":"#manager","p":1044},{"i":1052,"t":"The Ansible group all is specifically used internally by OSISM, is reserved and is not supported for additional variables. When variables are added in the configuration repository for the all group, they are ignored. In OSISM the group generic can be used to store variables for all nodes.","s":"Define variable for all nodes","u":"/docs/iaas/guides/configuration-guide/inventory","h":"#define-variable-for-all-nodes","p":1044},{"i":1055,"t":"info This feature is available from OSISM 7.0.5. With OSISM, it is possible to manage any number of independent loadbalancers via a single OSISM manager service using sub-environments. A sub environment is basically nothing more than another directory below the environments directory of the configuration repository with a special name. A sub-environment for an additional loadbalancer always has the name kolla.NAME as the loadbalancer is provided as part of Kolla. The kolla.NAME directory in the configuration repository then contains the configuration.yml, images.yml and secrets.yml files as usual. The following directories and files are also required in a sub-environment for a loadbalancer. File Description certificates/ca/custom.crt The file is optional. If a custom CA is used, it must be added here. certificates/haproxy-internal.pem SSL certificate to be used. files/overlays/haproxy/services.d/haproxy.cfg HAProxy configuration to be used on the loadbalancer. In this example, a sub-environment kolla.external is created, which is used for an outward facing loadbalancer that only offers certain API services. In comparison to the normal kolla environment, the groups to be used must be overwritten for a Kolla sub-environment. In this case, one group is defined: kolla.external.loadbalancer. It is recommended to base the name of the groups on the name of the sub-environments. The group kolla.external.loadbalancer is added to the global inventory in the 10-custom file. In this example, testbed-node-2.testbed.osism.xyz is used for the second loadbalancer. inventory/10-custom [kolla.external.loadbalancer] testbed-node-2.testbed.osism.xyz It is also important to ensure that the nodes used for the second loadbalancer are not included in the loadbalancer group. This can be checked with osism get hosts -l loadbalancer. If the nodes of the second loadbalancer are also listed there, the loadbalancer group in the 99-overwrite file of the global inventory must be overwritten. In this example, the loadbalaner group is overwritten so that only testbed-node-0.testbed.osism.xyz and testbed-node-1.testbed.osism.xyz are left in the loadbalancer group. inventory/99-overwrite [loadbalancer] testbed-node-0.testbed.osism.xyz testbed-node-1.testbed.osism.xyz Furthermore, in a Kolla sub-environment that is only used for a loadbalancer, only a few additional parameters are required in the configuration.yml file. Don't get confused, only the kolla_*internal* parameters and the haproxy-internal.pem file are used here in the example. This is because we only want to configure one virtual IP address on the external loadbalancer and the loadbalancer managed by Kolla has the internal IP address by default. It is therefore not possible with Kolla to use only the kolla_*external* parameters as an additional virtual IP address with default values would then be configured by default. environments/kolla.external/configuration.yml --- ########################################################## # hosts hosts_kolla_all: kolla.external.loadbalancer hosts_kolla_loadbalancer: kolla.external.loadbalancer ########################################################## # docker docker_namespace: osism ########################################################## # loadbalancer kolla_internal_vip_address: 192.168.24.200 kolla_internal_fqdn: api.testbed.osism.com kolla_enable_tls_internal: \"yes\" # Required if a custom CA is used. kolla_copy_ca_into_containers: \"yes\" At the moment it is only possible to deploy the loadbalancer itself with its own configuration. It is currently not possible to use the integrated service configurations of Kolla itself (Nova, Cinder, ..) on an additional loadbalancer. This will be possible in the future. osism apply --sub external loadbalancer-without-service-config","s":"Second Loadbalancer","u":"/docs/iaas/guides/configuration-guide/loadbalancer","h":"#second-loadbalancer","p":1053},{"i":1057,"t":"The configuration required for an OSISM managed cluster is stored in a single Git monorepo, the configuration repository.","s":"Configuration Repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"","p":1056},{"i":1059,"t":"The initial content for this configuration repository is generated using the Cookiecutter. Cookiecutter generates a simple initial configuration for your new cluster by prompting you for the basic details of the new cluster. The configuration repository is not created on the future Manager node. It is created on a local workstation. If the local workstation cannot be used for this purpose, a dedicated virtual system can be used. For more information on this topic, refer to the Seed Deploy Guide..","s":"Creating a new configuration repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#creating-a-new-configuration-repository","p":1056},{"i":1061,"t":"First decide where to store your Git repository The content generated by the cookiecutter in the output/configuration directory is committed to a new Git repository. By default, the configuration repository is assumed to be on GitHub. This can also be GitLab or an internal Git service as well. Host and path to the Git repository are specified by the git_ parameters. These are requested in step 2. The git_ parameters do not specify the path to the cookiecutter to use. [8/20] git_host (github.com): [9/20] git_port (22): [10/20] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY): regiocloud/configuration [11/20] git_username (git): [12/20] git_version (main): In this case, the generated configuration in the output/configuration directory is stored on GitHub in the regiocloud/configuration repository. See the parameter reference for more details. The parameters listed there will be queried during the execution of Cookiecutter.","s":"Step 1: Preparation","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#step-1-preparation","p":1056},{"i":1063,"t":"The directory output is created and used as output volume. It is only necessary to create the empty directory here. mkdir output The Cookiecutter runs inside a container. Docker must be usable on the system where the Cookiecutter will be used. It should also work with Podman. docker run \\ -e TARGET_UID=\"$(id -u)\" \\ -e TARGET_GID=\"$(id -g)\" \\ -v $(pwd)/output:/output \\ --rm -it quay.io/osism/cookiecutter A few parameters are requested. The parameters are documented in detail in the Parameters reference. If you want to use the latest version, this is done using the manager_version parameter. By default, this is always set to the latest stable version. manager_version [7.0.4]: latest If the manager_version parameter is set to latest it is also possible to explicitly set the openstack_version and the ceph_version explicitly. [1/19] with_ceph (1): [2/19] with_keycloak (0): [3/19] ceph_network(192.168.64.0/19): [4/19] ceph_version (quincy): [5/19] domain (osism.xyz): [6/19] fqdn_external (api.osism.xyz): [7/19] fqdn_internal (api-int.osism.xyz): [8/19] git_host (github.com): [9/19] git_port (22): [10/19] git_repository (YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY): [11/19] git_username (git): [12/19] git_version (main): [13/19] ip_external (192.168.96.9): [14/19] ip_internal (192.168.32.9): [15/19] manager_version (7.0.4): [16/19] name_server (149.112.112.112): [17/19] ntp_server (de.pool.ntp.org): [18/19] openstack_version (2023.2): [19/19] project_name (configuration):","s":"Step 2: Run Cookiecutter","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#step-2-run-cookiecutter","p":1056},{"i":1065,"t":"Add the initial configuration state to the repository. How to add a deploy key on GitHub is documented in Managing deploy keys. Read permissions are sufficient. $ git clone git@github.com:YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY.git YOUR_NEW_CONFIGURATION_REPOSITORY $ cp -r output/configuration/{*,.gitignore} YOUR_NEW_CONFIGURATION_REPOSITORY $ cd YOUR_NEW_CONFIGURATION_REPOSITORY $ git add -A . $ git commit -m \"Initial commit after bootstrap\" $ git push The content is now committed to the Git repository that was created earlier in the process. warning The secrets directory is not stored in the Git repository. Its contents can be stored in a trusted location. The secrets directory contains an SSH key pair which is used as the deploy key to make the configuration repository available on the manager node later. Write access is not required. The public SSH key is stored in the secrets/id_rsa.configuration.pub file.","s":"Step 3: Upload the new configuration to the remote git repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#step-3-upload-the-new-configuration-to-the-remote-git-repository","p":1056},{"i":1067,"t":"The configuration repository that is initially created with the Cookiecutter is not immediately usable. For example, the inventory needs to be built. All other information can be found in the Configuration Guide. Use git to version all your configuration changes. The following 6 points must be changed after the initial creation of the configuration repository. Secrets Manager inventory Global inventory DNS servers NTP servers SSL certificates Secrets​ The password for Ansible Vault encrypted files, is stored in secrets/vaultpass. Since the secrets directory is not added to the configuration repository, it is important to store it in a password vault of your choice. The password of the generated Keepass file is password. This should be changed when using the Keepass file. If possible, an existing password vault should be used. Manager inventory​ The information required to perform the initial bootstrap of the manager node and the initial deployment of the manager service from the seed Node is provided in the inventory of the manager environment. In the Cookiecutter, a node node01 is defined as an example in the manager inventory as well as in the global inventory. The name of this node must be changed to match the name of the node used as manager in your own cluster. Roles Manager role The name of the node on which the manager service is to be deployed is added to inventory group manager in file environments/manager/hosts. Only the manager inventory group is available in environments/manager/hosts. There are no other groups there. environments/manager/hosts [manager] node01 Host vars Ansible section The IP address where the node can be reached via SSH from the manager node. If DHCP is used after the initial provisioning to assign an initial IP address to the nodes, the address assigned via DHCP is initially used here and later changed to the static IP address. environments/manager/host_vars/node01.yml ansible_host: 192.168.16.10 Generic section The network interface on which the internal communication of the cluster will take place. If the internal interface does not yet exist at the time the configuration is created, e.g. because it is a bond interface or VLAN interface that is only created by the static network configuration, it can be already used here. environments/manager/host_vars/node01.yml internal_interface: eno1 Network section The static and complete network configuration of the node. Further details on creating the network configuration in the network configuration guide. environments/manager/host_vars/node01.yml network_ethernets: eno1: addresses: - \"192.168.16.10/20\" gateway4: \"192.168.16.1\" mtu: 1500 Global inventory​ In the Cookiecutter, a node node01 is defined as an example in the manager inventory as well as in the global inventory. The name of this node must be changed to match the name of the node used as manager in your own cluster. Roles Generic role inventory/20-roles # The \"all\" group is not used in OSISM. Therefore it is important # that all nodes are explicitly listed here. [generic] node01 Manager role inventory/20-roles # Nodes that act as manager (sometimes called deployment node) # are included in this group. [manager] node01 Monitoring role inventory/20-roles # Nodes which are intended for monitoring services belong to # this group [monitoring] Control role inventory/20-roles # Nodes that serve as controllers, so things like scheduler, # API or database run there, of the environment. [control] Compute role inventory/20-roles # Virtual systems managed by OpenStack Nova are placed on # nodes in this group. [compute] Network role inventory/20-roles # Network resources managed by OpenStack Neutron, such as # L3 routers, are placed on these nodes. This group has nothing # to do with the general network configuration. [network] Ceph control role inventory/20-roles # Nodes that serve as controllers for Ceph, so things like the # Ceph Monitor service run here. [ceph-control] Ceph resource role inventory/20-roles # The storage available in these systems is provided in the # form of OSDs for Ceph. [ceph-resource] Ceph rgw role inventory/20-roles [ceph-rgw:children] ceph-control Host vars Ansible section inventory/host_vars/node01.yml # NOTE: Address where the node can be reached via SSH. ansible_host: 192.168.16.10 Generic section inventory/host_vars/node01.yml internal_interface: eno1 # NOTE: The address of the internal interface. internal_address: 192.168.16.10 Netdata section inventory/host_vars/node01.yml netdata_host_type: client # NOTE: Uncomment this when this node should be a Netdata server. # netdata_host_type: server Network section inventory/host_vars/node01.yml # NOTE: This is the initial management interface. Further interfaces can be added. # DOCS: https://osism.tech/docs/guides/configuration-guide/network network_ethernets: eno1: addresses: - \"192.168.16.10/20\" gateway4: \"192.168.16.1\" mtu: 1500 Kolla section inventory/host_vars/node01.yml network_interface: eno1 # api_interface: # bifrost_network_interface: # dns_interface: # kolla_external_vip_interface: # migration_interface: # neutron_external_interface: # octavia_network_interface: # storage_interface: # tunnel_interface: Ceph section inventory/host_vars/node01.yml # NOTE: Uncomment this when this node is a part of the Ceph cluster. # monitor_address: # radosgw_address: inventory/host_vars/node01.yml # NOTE: Uncomment this when this node should be a OSD node. # DOCS: https://osism.tech/docs/guides/configuration-guide/ceph#lvm-devices # ceph_osd_devices: # sdb: # sdc: # sdd: # sde: DNS servers​ environments/configuration.yml resolvconf_nameserver: - 8.8.8.8 - 9.9.9.9 NTP servers​ environments/configuration.yml chrony_servers: - 1.de.pool.ntp.org - 2.de.pool.ntp.org - 3.de.pool.ntp.org - 4.de.pool.ntp.org SSL certificates​","s":"Step 4: Post-processing of the generated configuration","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#step-4-post-processing-of-the-generated-configuration","p":1056},{"i":1069,"t":"If you want to use the latest version, this is done using the manager_version parameter. By default, this is always set to the latest stable version. manager_version [7.0.0]: latest If the manager_version parameter is set to latest it is also possible to explicitly set the openstack_version and the ceph_version explicitly.","s":"Using latest","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#using-latest","p":1056},{"i":1071,"t":"Parameter Description Default ceph_network Address range for Ceph's network 192.168.64.0/20 ceph_version The version of Ceph. When using a stable OSISM release (manager_version != latest), this value is ignored quincy domain The domain used by hostnames osism.xyz fqdn_external External API FQDN api.osism.xyz fqdn_internal Internal API FQDN api-int.osism.xyz git_host Address of the used Git server github.com git_port Port of the used Git server 22 git_repository Path to the git configuration repository YOUR_ORG/YOUR_CONFIGURATION_REPOSITORY git_username Username of the git repository git git_version Git branch name main ip_external The external IP address of the API (resolves to fqdn_external) 192.168.96.9 ip_internal The internal IP address of the API (resolves to fqdn_internal) 192.168.32.9 manager_version The version of OSISM. An overview of available OSISM releases can be found here 7.0.4 name_server Nameserver. Only one nameserver is set here because the query of multiple values in Cookiecutter is weird. Add more nameservers afterward. 149.112.112.112 ntp_server NTP server. Only one NTP server is set here because the query of multiple values in Cookiecutter is weird. Add more NTP servers afterward. de.pool.ntp.org openstack_version The version of OpenStack. When using a stable OSISM release (manager_version != latest), this value is ignored 2023.2 project_name Name of the configuration repository directory configuration with_ceph 1 to use Ceph, 0 to not use Ceph 1 with_keycloak 1 to prepare Keycloak integration , 0 to not prepare Keycloak integration 0","s":"Parameter reference","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#parameter-reference","p":1056},{"i":1073,"t":"A configuration repository always has the same layout. This section describes the content available in a configuration repository. In the section Creating a new configuration repository is the creation of a new configuration repository documented. Directory/File Description environments inventory netbox optional requirements.txt In the requirements.txt the necessary dependencies are listed to be able to execute Gilt. gilt.yml Makefile gilt.yaml Gilt is a Git layering tool. We use Gilt to maintain the image versions, Ansible configuration and scripts within the environments/manager directory.","s":"Configuration repository layout","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#configuration-repository-layout","p":1056},{"i":1075,"t":"Once the manager has been deployed and the configuration repository has been initially transferred to the manager node, the configuration repository can be updated using osism apply configuration. If local changes were made directly in the configuration repository on the manager node, these are overwritten.","s":"Synchronising the configuration repository","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#synchronising-the-configuration-repository","p":1056},{"i":1077,"t":"It is possible to lock parts of the configuration repository or the complete configuration repository. It is then no longer possible to execute plays assigned to these parts in the locked parts. This makes it possible to prevent the execution of plays in specific areas. To lock an environment, a .lock file is created in the corresponding directory of the environment. For example, the file environments/kolla/.lock locks the Kolla environment. If you try to execute a play in the Kolla environment, an error message is displayed. $ osism apply common 2024-06-02 10:52:44 | INFO | Task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) was prepared for execution. 2024-06-02 10:52:44 | INFO | It takes a moment until task 2f25f55f-96ae-4a6c-aeb4-c1c01e716d91 (common) has been started and output is visible here. ERROR: The environment kolla is locked via the configuration repository. File environments/.lock is created to lock everything. If you try to execute a play, an error message is displayed. $ osism apply facts 2024-06-02 10:53:08 | INFO | Task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) was prepared for execution. 2024-06-02 10:53:08 | INFO | It takes a moment until task 6ac9a526-f88d-4756-bf46-2179636dfb42 (facts) has been started and output is visible here. ERROR: The configuration repository is locked.","s":"Locks","u":"/docs/iaas/guides/configuration-guide/configuration-repository","h":"#locks","p":1056},{"i":1080,"t":"warning Always read the release notes first to learn what has changed and what adjustments are necessary. Read the release notes even if you are only updating from e.g. 7.0.2 to 7.0.5. In the example, OSISM release 7.0.5 is used. Set the new manager version in the configuration repository. MANAGER_VERSION=7.0.5 sed -i -e \"s/manager_version: .*/manager_version: ${MANAGER_VERSION}/g\" environments/manager/configuration.yml If openstack_version or ceph_version are set in environments/manager/configuration.yml (or anywhere else), they must be removed. If these are set, the stable release is not used for these components. Sync the image versions in the configuration repository. OSISM >= 7.0.0 OSISM < 7.0.0 make sync If Gilt is not installed via the requirements.txt of the manager environment it is important to use a version smaller v2. The v2 of Gilt is not yet usable. gilt overlay # you have to do this 2x, this is not a copy & paste error gilt overlay Optionally, this is normally not necessary, it is possible to reference a specific tag of the osism/cfg-generics repository. To do this, first check which version of osism/cfg-generics is used in a particular release. The version is defined in generics_version in the base.yml file in the osism/release repository. For OSISM 6.0.0, for example, this is version v0.20230919.0. This version is then added to the file gilt.yml in the configuration repository instead of main at version. This change must be made again after each execution of gilt overlay as it is overwritten by the call of gilt overlay. This cannot be realized differently in the current implementation of Gilt. Commit and push changes in the configuration repository. Since everyone here has their own workflows for changes to the configuration repository, only a generic example for Git. git commit -a -s -m \"manager: use OSISM version 7.0.5\" git push The upgrade is described in the Manager Upgrade Guide.","s":"Stable release","u":"/docs/iaas/guides/configuration-guide/manager","h":"#stable-release","p":1078},{"i":1082,"t":"With the command osism log opensearch it is possible to send SQL queries to the OpenSearch service. For the command to be functional, the OpenSearch integration must be activated in the manager environment and the OpenSearch address and port must be set. environments/manager/configuration.yml manager_opensearch_enable: true manager_opensearch_address: api-int.testbed.osism.xyz manager_opensearch_port: 9200 manager_opensearch_protocol: https The integration can also be enabled later. osism update manager is then executed after the configuration has been changed.","s":"OpenSearch integration","u":"/docs/iaas/guides/configuration-guide/manager","h":"#opensearch-integration","p":1078},{"i":1084,"t":"If the Baremetal Service Integration in OSISM is used, the OpenStack Broker integration is required. The integration itself is activated by setting the parameter enable_listener to true. The hosts in the manager_listener_broker_hosts list are the control nodes of OpenStack. The user is set via manager_listener_broker_username. On OpenStack's RabbitMQ broker, the user openstack is present by default. environments/manager/configuration.yml enable_listener: true manager_listener_broker_hosts: - 192.168.16.10 - 192.168.16.11 - 192.168.16.12 manager_listener_broker_username: openstack manager_listener_broker_uri: \"{% for host in manager_listener_broker_hosts %}amqp://{{ manager_listener_broker_username }}:{{ manager_listener_broker_password }}@{{ host }}:5672/{% if not loop.last %};{% endif %}{% endfor %}\" The password used when using the openstack user is rabbitmq_password from environments/kolla/secrets.yml. environments/manager/secrets.yml manager_listener_broker_password: RABBITMQ_PASSWORD","s":"OpenStack broker integration","u":"/docs/iaas/guides/configuration-guide/manager","h":"#openstack-broker-integration","p":1078},{"i":1086,"t":"Aodh admin guide Aodh configuration guide Aodh configuration reference","s":"Aodh","u":"/docs/iaas/guides/configuration-guide/openstack/aodh","h":"","p":1085},{"i":1089,"t":"Since OSISM 6.1.0, the default network type is a netplan and no longer needs to be set explicitly network_type: netplan The configuration is written to /etc/netplan/01-osism.yaml by default. Can be changed via the network_netplan_path and network_netplan_file parameters. The file permissions are 0600 by default (cane be changed via the network_netplan_permissions parameter). By default, all other files in /etc/netplan are removed. If you do not want this, you can set network_netplan_remove_unmanaged_files to false. It is also possible to explicitly list individual files that should not be deleted in network_netplan_managed_files_extra. An existing /etc/intefaces file is replaced with a placeholder file. It is not possible to use /etc/interfaces and Netplan in parallel. This template is used as the base for the configuration # This file describes the network interfaces available on your system # For more information, see netplan(5). --- network: version: {{ network_version }} renderer: {{ network_renderer }} bonds: {{ network_bonds|to_nice_yaml(indent=4)|indent(4) }} bridges: {{ network_bridges|to_nice_yaml(indent=4)|indent(4) }} ethernets: {{ network_ethernets|to_nice_yaml(indent=4)|indent(4) }} tunnels: {{ network_tunnels|to_nice_yaml(indent=4)|indent(4) }} vlans: {{ network_vlans|to_nice_yaml(indent=4)|indent(4) }} vrfs: {{ network_vrfs|to_nice_yaml(indent=4)|indent(4) }} The parameters listed in the following table can be used in the template. Parameter Default Description network_version 2 Defines what version of the configuration format is used. The only value supported at the moment is 2. network_renderer networkd Defines what network configuration tool will be used to set up your configuration. network_bonds {} https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bonds network_bridges {} https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-bridges network_ethernets {} https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-ethernets network_tunnels {} https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-tunnels network_vlans {} https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vlans network_vrfs {} https://netplan.readthedocs.io/en/stable/netplan-yaml/#properties-for-device-type-vrfs By default changes to the network configuration are not applied automatically. This is done on purpose to allow a manual check in advance. Changes to the network configuration can be applied either by rebooting or by executing netplan apply. $ osism console --type clush all Enter 'quit' to leave this interactive mode Working with nodes: testbed-manager.testbed.osism.xyz,testbed-node-[0-2].testbed.osism.xyz clush> sudo netplan apply It is possible to execute the netplan apply automatically via a handler when changes are made. The parameter network_allow_service_restart is used for this. environments/configuration.yml network_allow_service_restart: true","s":"Netplan","u":"/docs/iaas/guides/configuration-guide/network","h":"#netplan","p":1087},{"i":1091,"t":"The Netplan documentation contains a large number of example configurations. The following example shows the use of How to create VLANs with the osism.commons.network role. network_ethernets: mainif: match: macaddress: \"de:ad:be:ef:ca:fe\" set-name: mainif addresses: [ \"10.3.0.5/23\" ] nameservers: addresses: [ \"8.8.8.8\", \"8.8.4.4\" ] search: [ example.com ] routes: - to: default via: 10.3.0.1 network_vlans: vlan15: id: 15 link: mainif addresses: [ \"10.3.99.5/24\" ] vlan10: id: 10 link: mainif addresses: [ \"10.3.98.5/24\" ] nameservers: addresses: [ \"127.0.0.1\" ] search: [ domain1.example.com, domain2.example.com ]","s":"Example","u":"/docs/iaas/guides/configuration-guide/network","h":"#example","p":1087},{"i":1094,"t":"Dummy devices are created with the help of systemd.netdev and can then be used as a normal netowrk device in the Netplan configuration. network_dummy_interfaces: - dummy0 The MTU is set to 9000 by default and can be set via network_dummy_interface_mtu.","s":"Dummy interfaces","u":"/docs/iaas/guides/configuration-guide/network","h":"#dummy-interfaces","p":1087},{"i":1096,"t":"If /etc/interfaces is to be used, the network_type must be explicitly set in environments/configuration.yml network_type: interfaces","s":"/etc/interfaces","u":"/docs/iaas/guides/configuration-guide/network","h":"#etcinterfaces","p":1087},{"i":1098,"t":"Example configuration for a node. The configuration is stored in the host_vars file for the node in inventory directory in the configuration repository. ########################################################## # ansible ansible_host: 10.10.42.10 ########################################################## # generic internal_interface: dummy0 ########################################################## # network network_type: netplan network_dummy_interfaces: - dummy0 network_ethernets: enp99s0f0np0: mtu: 9100 enp99s0f1np1: mtu: 9100 dummy0: addresses: - 10.10.42.10/32 - 2001:db8::10:10:42:10/128 ########################################################## # frr frr_local_as: 4210042010 frr_loopback_v4: 10.10.42.10 frr_loopback_v6: 2001:db8::10:10:42:10 frr_uplinks: - interface: enp99s0f0np0 remote_as: 65401 - interface: enp99s0f1np1 remote_as: 65402 ########################################################## # kolla network_interface: \"{{ internal_interface }}\"","s":"IPv6 fabric underlay","u":"/docs/iaas/guides/configuration-guide/network","h":"#ipv6-fabric-underlay","p":1087},{"i":1100,"t":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/configuration/ It is strongly advised to use the documentation for the version being used. Pacific - https://docs.ceph.com/en/pacific/rados/configuration/ Quincy - https://docs.ceph.com/en/quincy/rados/configuration/ Reef - https://docs.ceph.com/en/reef/rados/configuration/","s":"Ceph","u":"/docs/iaas/guides/configuration-guide/ceph","h":"","p":1099},{"i":1102,"t":"The File System ID is a unique identifier for the cluster. The identifier is set via the parameter fsid in environments/ceph/configuration.yml and must be unique. It can be generated with uuidgen. environments/ceph/configuration.yml fsid: c2120a4a-669c-4769-a32c-b7e9d7b848f4","s":"Unique Identifier","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#unique-identifier","p":1099},{"i":1104,"t":"The client.admin keyring is placed in the file environments/infrastructure/files/ceph/ceph.client.admin.keyring.","s":"Client","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#client","p":1099},{"i":1106,"t":"The swappiness is set via the os_tuning_params dictionary. The dictionary can only be completely overwritten via an entry in the file environments/ceph/configuration.yml. By default, the dictionary looks like this: os_tuning_params: - { name: fs.file-max, value: 26234859 } - { name: vm.zone_reclaim_mode, value: 0 } - { name: vm.swappiness, value: 10 } - { name: vm.min_free_kbytes, value: \"{{ vm_min_free_kbytes }}\" } The sysctl paremeters are written to the file /etc/sysctl.d/ceph-tuning.conf on the storage nodes. # cat /etc/sysctl.d/ceph-tuning.conf fs.aio-max-nr=1048576 fs.file-max=26234859 vm.zone_reclaim_mode=0 vm.swappiness=10 vm.min_free_kbytes=4194303","s":"Swappiness","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#swappiness","p":1099},{"i":1108,"t":"Add following configuration in environments/ceph/configuration.yml environments/ceph/configuration.yml ceph_conf_overrides: \"client.rgw.{{ hostvars[inventory_hostname]['ansible_hostname'] }}.rgw0\": \"rgw content length compat\": \"true\" \"rgw enable apis\": \"swift, s3, admin\" \"rgw keystone accepted roles\": \"member, admin\" \"rgw keystone accepted admin roles\": \"admin\" \"rgw keystone admin domain\": \"default\" \"rgw keystone admin password\": \"{{ ceph_rgw_keystone_password }}\" \"rgw keystone admin project\": \"service\" \"rgw keystone admin tenant\": \"service\" \"rgw keystone admin user\": \"ceph_rgw\" \"rgw keystone api version\": \"3\" \"rgw keystone url\": \"https://api-int.testbed.osism.xyz:5000\" \"rgw keystone verify ssl\": \"false\" \"rgw keystone implicit tenants\": \"true\" \"rgw s3 auth use keystone\": \"true\" \"rgw swift account in url\": \"true\" \"rgw swift versioning enabled\": \"true\" If the ceph_conf_overrides parameter already exists in environments/ceph/configuration.yml, expand it and do not overwrite it. If self-signed SSL certificates are used, two additional parameters must be set. environments/ceph/configuration.yml \"rgw keystone verify ssl\": \"false\" \"rgw verify ssl\": \"false\" For all possible configuration parameters visit the Ceph configuration reference. Add the ceph_rgw_keystone_password from environments/kolla/secrets.yml to environments/ceph/secrets.yml. Add following configuration in environments/kolla/configuration.yml environments/kolla/configuration.yml enable_ceph_rgw: true enable_ceph_rgw_keystone: true ceph_rgw_swift_compatibility: false ceph_rgw_swift_account_in_url: true On the nodes on which the RGW service is to be deployed, radowsgw_interface or radosgw_address must be set in the host vars for the nodes in the inventory. If radowsgw_interface is used, the first IPv4 address on this interface is used. ########################################################## # ceph radosgw_address: 192.168.16.10 The nodes on which the RGW service is to be deployed can be defined in inventory group ceph-rgw. By default, the RGW services are deployed on the Ceph control nodes.. inventory/20-roles [ceph-rgw:children] ceph-control","s":"RGW service","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#rgw-service","p":1099},{"i":1110,"t":"Extra pools can be defined via the openstack_pools_extra parameter. inventory/group_vars/generic/ceph.yml openstack_cinder_extra001_pool: name: extra001 pg_num: \"{{ openstack_pool_default_pg_num }}\" pgp_num: \"{{ openstack_pool_default_pg_num }}\" rule_name: \"replicated_rule\" min_size: \"{{ openstack_pool_default_min_size }}\" application: \"rbd\" openstack_pools_extra: - \"{{ openstack_cinder_extra001_pool }}\" If more than one Ceph cluster is managed with one manager, do not place the parameters in inventory/group_vars/generic but in a corresponding directory. If, for example, the inventory group of the Ceph cluster on which the additional pools are to be created is ceph.rbd, then the parameters would be stored in inventory/group_vars/ceph.rbd.yml accordingly. Parameter Default value openstack_pool_default_pg_num 64 openstack_pool_default_min_size 0","s":"Extra pools","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#extra-pools","p":1099},{"i":1112,"t":"For more advanced OSD layout requirements leave out the devices key and instead use lvm_volumes. Details for this can be found on the OSD Scenario documentation. In order to aid in creating the lvm_volumes config entries and provision the LVM devices for them, OSISM has the two playbooks ceph-configure-lvm-volumes and ceph-create-lvm-devices available. For each Ceph storage node edit the file inventory/host_vars/.yml add a configuration like the following to it. Ensure that no devices parameter is present in the file. Parameters With the optional parmaeter ceph_osd_db_wal_devices_buffer_space_percent it is possible to set the percentage of VGs to leave free. The parameter is not set by default. Can be helpful for SSD performance of some older SSD models or to extend lifetime of SSDs in general. ceph_osd_db_wal_devices_buffer_space_percent: 10 It is possible to configure the devices to be used with the parameters ceph_osd_devices, ceph_db_devices, ceph_wal_devices, and ceph_db_wal_devices. This is described below. It is always possible to use device names such as sda or device IDs such as disk/by-id/wwn- or disk/by-id/nvme-eui.. /dev/ is not prefixed and is added automatically. The db_size parameter is optional and defaults to (VG size - buffer space (if enabled)) / num_osds. The wal_size parameter is optional and defaults to 2 GB. The num_osds parameter specifies the maximum number of OSDs that can be assigned to a WAL device or DB device. The optional parameter wal_pv can be used to set the device that is to be used as the WAL device. The optional parameter db_pv can be used to set the device that is to be used as the DB device. OSD only The sda device will be used as an OSD device without WAL and DB device. ceph_osd_devices: sda: OSD + DB device The nvme0n1 device will be used as an DB device. It is possible to use this DB device for up to 6 OSDs. Each OSD is provided with 30 GB. ceph_db_devices: nvme0n1: num_osds: 6 db_size: 30 GB The sda device will be used as an OSD device with nvme0n1 as DB device. ceph_osd_devices: sda: db_pv: nvme0n1 OSD + WAL device The nvme0n1 device will be used as an WAL device. It is possible to use this WAL device for up to 6 OSDs. Each OSD is provided with 2 GB. ceph_wal_devices: nvme0n1: num_osds: 6 wal_size: 2 GB The sda device will be used as an OSD device with nvme0n1 as WAL device. ceph_osd_devices: sda: wal_pv: nvme0n1 OSD + DB device + WAL device (same device for DB + WAL) The nvme0n1 device will be used as an DB device and a WAL device. It is possible to use those devices for up to 6 OSDs. ceph_db_wal_devices: nvme0n1: num_osds: 6 db_size: 30 GB wal_size: 2 GB The sda device will be used as an OSD device with nvme0n1 as DB device and nvme0n1 as WAL device. ceph_osd_devices: sda: db_pv: nvme0n1 wal_pv: nvme0n1 OSD + DB device + WAL device (different device for DB + WAL) The nvme0n1 device will be used as an DB device. It is possible to use this DB device for up to 6 OSDs. Each OSD is provided with 30 GB. ceph_db_devices: nvme0n1: num_osds: 6 db_size: 30 GB The nvme1n1 device will be used as an WAL device. It is possible to use this WAL device for up to 6 OSDs. Each OSD is provided with 2 GB. ceph_wal_devices: nvme1n1: num_osds: 6 wal_size: 2 GB The sda device will be used as an OSD device with nvme0n1 as DB device and nvme1n1 as WAL device. ceph_osd_devices: sda: db_pv: nvme0n1 wal_pv: nvme1n1 Push the configuration to your configuration repository and after that do the following $ osism apply configuration $ osism reconciler sync $ osism apply facts After the configuration has been pulled and facts updated, you can run the LVM configuration playbook: $ osism apply ceph-configure-lvm-volumes This will generate a new configuration file for each node in /tmp on the first manager node named -ceph-lvm-configuration.yml. Take the generated configuration file from /tmp and replace the previously configuration for each node. In this example, the following content was in the host vars file before osism apply ceph-configure-lvm-volumes was called. ceph_osd_devices: sdb: sdc: The following content has now been generated in the file in the /tmp directory by running osism apply ceph-configure-lvm-volumes. ceph_osd_devices: sdb: osd_lvm_uuid: 196aad32-7cc4-5350-8a45-1b03f50fc9bb sdc: osd_lvm_uuid: c6df96be-1264-5815-9cb2-da5eb453a6de lvm_volumes: - data: osd-block-196aad32-7cc4-5350-8a45-1b03f50fc9bb data_vg: ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb - data: osd-block-c6df96be-1264-5815-9cb2-da5eb453a6de data_vg: ceph-c6df96be-1264-5815-9cb2-da5eb453a6de This content from the file in the /tmp directory is added in the host vars file. The previous ceph_osd_devices is replaced with the new content. Push the updated configuration again to your configuration repository and re-run: $ osism apply configuration $ osism reconciler sync Finally create the LVM devices. $ osism apply ceph-create-lvm-devices These PVs, VGs and LVs are created using the example from step 4. $ sudo pvs PV VG Fmt Attr PSize PFree /dev/sdb ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb lvm2 a-- <20.00g 0 /dev/sdc ceph-c6df96be-1264-5815-9cb2-da5eb453a6de lvm2 a-- <20.00g 0 $ sudo vgs VG #PV #LV #SN Attr VSize VFree ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb 1 1 0 wz--n- <20.00g 0 ceph-c6df96be-1264-5815-9cb2-da5eb453a6de 1 1 0 wz--n- <20.00g 0 $ sudo lvs LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert osd-block-196aad32-7cc4-5350-8a45-1b03f50fc9bb ceph-196aad32-7cc4-5350-8a45-1b03f50fc9bb -wi-a----- <20.00g osd-block-c6df96be-1264-5815-9cb2-da5eb453a6de ceph-c6df96be-1264-5815-9cb2-da5eb453a6de -wi-a----- <20.00g Everything is now ready for the deployment of the OSDs. Details on deploying Ceph in the Ceph deploy guide.","s":"LVM devices","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#lvm-devices","p":1099},{"i":1114,"t":"Use of dedicated DB devices​ The ceph_osd_devices and ceph_db_devices parameters with the following content are initially added in the host vars of the node. Devices /dev/sda and /dev/sdb are used as OSD devices. The device /dev/sdd is used as a DB device for up to 2 OSDs. For each OSD that uses /dev/sdd as DB device, an LV volume of (in this case) 5 GByte is created Please note that at least 30 GByte must be used for a DB device in production. ceph_db_devices: sdd: num_osds: 2 db_size: 5 GB ceph_osd_devices: sdb: db_pv: sdd sdc: db_pv: sdd Then generate the required LVM2 device configuration with the ceph-configure-lvm-volumes play. osism apply facts osism reconciler sync osism apply ceph-configure-lvm-volumes Check the /tmp directory on the manager node for files like testbed-node-0.testbed.osism.xyz-ceph-lvm-configuration.yml. Add this content to the host vars of the correspondingnode. The existing ceph_osd_devices parameter is replaced. --- # # This is Ceph LVM configuration for testbed-node-0.testbed.osism.xyz # generated by ceph-configure-lvm-volumes playbook. # ceph_db_devices: sdd: db_size: 5 GB num_osds: 2 vg_name: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb ceph_osd_devices: sdb: db_pv: sdd osd_lvm_uuid: 75960289-2e0e-525d-8bb5-dd8552531ef5 sdc: db_pv: sdd osd_lvm_uuid: ce2c2cb6-f911-52dd-b57f-4476bf7afe9f lvm_volumes: - data: osd-block-75960289-2e0e-525d-8bb5-dd8552531ef5 data_vg: ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 db: osd-db-75960289-2e0e-525d-8bb5-dd8552531ef5 db_vg: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb - data: osd-block-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f data_vg: ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f db: osd-db-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f db_vg: ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb Finally, create the necessary PVs, VGs and LVs. The parameter -e ignore_db_too_small=true is only set here in the example because we use less than 30 GByte for the size of the DB LV. osism reconciler sync osism apply ceph-create-lvm-devices -e ignore_db_too_small=true You can check the PVs, VGs, and LVs on the node. $ sudo pvs PV VG Fmt Attr PSize PFree /dev/sdb ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 lvm2 a-- <20.00g 0 /dev/sdc ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f lvm2 a-- <20.00g 0 /dev/sdd ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb lvm2 a-- <20.00g <10.00g $ sudo vgs VG #PV #LV #SN Attr VSize VFree ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 1 1 0 wz--n- <20.00g 0 ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f 1 1 0 wz--n- <20.00g 0 ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb 1 2 0 wz--n- <20.00g <10.00g $ sudo lvs LV VG Attr LSize [...] osd-block-75960289-2e0e-525d-8bb5-dd8552531ef5 ceph-75960289-2e0e-525d-8bb5-dd8552531ef5 -wi-a----- <20.00g osd-block-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f ceph-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f -wi-a----- <20.00g osd-db-75960289-2e0e-525d-8bb5-dd8552531ef5 ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb -wi-a----- 5.00g osd-db-ce2c2cb6-f911-52dd-b57f-4476bf7afe9f ceph-db-eb7522b1-41cf-522e-8d7e-2a4a82a879bb -wi-a----- 5.00g Use of partitions​ The use of partitions presented in this example is not recommended for use in production but only for POCs. First create partitions that should be used for Ceph. In this example we use a block device /dev/sdb with four partitions that will be used for Ceph OSDs. $ sudo fdisk -l /dev/sdb Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors Disk model: QEMU HARDDISK Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: gpt Disk identifier: 709B8C6C-51E1-4644-9ED4-0604607FCCEE Device Start End Sectors Size Type /dev/sdb1 2048 10487807 10485760 5G Linux filesystem /dev/sdb2 10487808 20973567 10485760 5G Linux filesystem /dev/sdb3 20973568 31459327 10485760 5G Linux filesystem /dev/sdb4 31459328 41943006 10483679 5G Linux filesystem The ceph_osd_devices parameter with the following content is initially added in the host vars of the node. The partitions /dev/sda1, /dev/sdb1, /dev/sdc1 and /dev/sdd1, are to be used as OSD. ceph_osd_devices: sdb1: sdb2: sdb3: sdb4: Then generate the required LVM2 device configuration with the ceph-configure-lvm-volumes play. osism apply facts osism reconciler sync osism apply ceph-configure-lvm-volumes Check the /tmp directory on the manager node for files like testbed-node-0.testbed.osism.xyz-ceph-lvm-configuration.yml. Add this content to the host vars of the correspondingnode. The existing ceph_osd_devices parameter is replaced. --- # # This is Ceph LVM configuration for testbed-node-0.testbed.osism.xyz # generated by ceph-configure-lvm-volumes playbook. # ceph_osd_devices: sdb1: osd_lvm_uuid: 9e8799ae-c716-5212-8833-49f153ffbcef sdb2: osd_lvm_uuid: 8518d3a2-3194-5764-b55a-c51222b9b576 sdb3: osd_lvm_uuid: a0da232a-e5b8-5823-8c42-8fb231442edc sdb4: osd_lvm_uuid: 56f7b5bc-82b0-5626-90a5-adf6078ceba6 lvm_volumes: - data: osd-block-9e8799ae-c716-5212-8833-49f153ffbcef data_vg: ceph-9e8799ae-c716-5212-8833-49f153ffbcef - data: osd-block-8518d3a2-3194-5764-b55a-c51222b9b576 data_vg: ceph-8518d3a2-3194-5764-b55a-c51222b9b576 - data: osd-block-a0da232a-e5b8-5823-8c42-8fb231442edc data_vg: ceph-a0da232a-e5b8-5823-8c42-8fb231442edc - data: osd-block-56f7b5bc-82b0-5626-90a5-adf6078ceba6 data_vg: ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 Finally, create the necessary PVs, VGs and LVs. osism reconciler sync osism apply ceph-create-lvm-devices You can check the PVs, VGs, and LVs on the node. $ sudo pvs PV VG Fmt Attr PSize PFree /dev/sdb1 ceph-9e8799ae-c716-5212-8833-49f153ffbcef lvm2 a-- <5.00g 0 /dev/sdb2 ceph-8518d3a2-3194-5764-b55a-c51222b9b576 lvm2 a-- <5.00g 0 /dev/sdb3 ceph-a0da232a-e5b8-5823-8c42-8fb231442edc lvm2 a-- <5.00g 0 /dev/sdb4 ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 lvm2 a-- <5.00g 0 $ sudo vgs VG #PV #LV #SN Attr VSize VFree ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 1 1 0 wz--n- <5.00g 0 ceph-8518d3a2-3194-5764-b55a-c51222b9b576 1 1 0 wz--n- <5.00g 0 ceph-9e8799ae-c716-5212-8833-49f153ffbcef 1 1 0 wz--n- <5.00g 0 ceph-a0da232a-e5b8-5823-8c42-8fb231442edc 1 1 0 wz--n- <5.00g 0 $ sudo lvs LV VG Attr LSize [...] osd-block-56f7b5bc-82b0-5626-90a5-adf6078ceba6 ceph-56f7b5bc-82b0-5626-90a5-adf6078ceba6 -wi-a----- <5.00g osd-block-8518d3a2-3194-5764-b55a-c51222b9b576 ceph-8518d3a2-3194-5764-b55a-c51222b9b576 -wi-a----- <5.00g osd-block-9e8799ae-c716-5212-8833-49f153ffbcef ceph-9e8799ae-c716-5212-8833-49f153ffbcef -wi-a----- <5.00g osd-block-a0da232a-e5b8-5823-8c42-8fb231442edc ceph-a0da232a-e5b8-5823-8c42-8fb231442edc -wi-a----- <5.00g","s":"Full examples","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#full-examples","p":1099},{"i":1116,"t":"Password for the admin user of the Ceph dashboard is set via ceph_dashboard_password. environments/ceph/secrets.yml ceph_dashboard_password: password User name of the admin user, port and listen IP address can be set via additional parameters. environments/ceph/configuration.yml ceph_dashboard_addr: 0.0.0.0 ceph_dashboard_port: 7000 ceph_dashboard_username: admin The Ceph dashboard is bootstrapped with the ceph-bootstrap-dashboard play. $ osism apply ceph-bootstrap-dashboard","s":"Dashboard","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#dashboard","p":1099},{"i":1118,"t":"The ceph dashboard runs in an active/standby configuration. In its default standby instances will redirect to the active instance. Most deployments will want to use the openstack loadbalancer to expose the ceph dashboard on the internal network and direct traffic directly to the active instance. In this scenario the dashboard should be configured to return an http error with status 404 on standby instances. environments/ceph/configuration.yml ceph_dashboard_standby_behaviour: error ceph_dashboard_standby_error_status_code: 404 Create a loadbalancer configuration environments/kolla/files/overlays/haproxy/services.d/ceph_dashboard.cfg {%- set internal_tls_bind_info = 'ssl crt /etc/haproxy/certificates/haproxy-internal.pem' if kolla_enable_tls_internal|bool else '' %} listen ceph_dashboard option httpchk http-check expect status 200,404 http-check disable-on-404 {{ \"bind %s:%s %s\"|e|format(kolla_internal_vip_address, 8140, internal_tls_bind_info)|trim() }} {% for host in groups['ceph-mgr'] %} server {{ hostvars[host]['ansible_facts']['hostname'] }} {{ hostvars[host]['monitor_address'] }}:7000 check inter 2000 rise 2 fall 5 {% endfor %} and apply it. $ osism apply -a reconfigure loadbalancer","s":"Configuring the openstack loadbalancer to expose the ceph dashboard","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#configuring-the-openstack-loadbalancer-to-expose-the-ceph-dashboard","p":1099},{"i":1120,"t":"With OSISM, it is possible to manage any number of independent Ceph clusters via a single OSISM manager service using sub-environments. A sub environment is basically nothing more than another directory below the environments directory of the configuration repository with a special name. A sub-environment for Ceph always has the name ceph.NAME. The ceph.NAME directory in the configuration repository then contains the configuration.yml, images.yml and secrets.yml files as usual. In this example, a sub-environment ceph.rgw is created which is used for a Ceph cluster that will only be used as an RGW cluster. In comparison to the normal ceph environment, the groups to be used must be overwritten for a Ceph sub-environment. In this case, two groups are defined: ceph.rgw and ceph.rgw.empty. Any other groups can be used, e.g. ceph.rgw.osd. It is recommended to base the name of the groups on the name of the sub-environments. The ceph.rgw.empty group is important because there are plays in ceph-ansible that are executed when nodes are in a specific group. To explicitly avoid this, certain groups are set to the empty group. All available group name parameters are listed in the [099-ceph.yml] file of the osism/defaults repository. environments/ceph.rgw/configuration.yml ########################## # groups ceph_group_name: ceph.rgw client_group_name: ceph.rgw grafana_server_group_name: ceph.rgw iscsi_gw_group_name: ceph.rgw.empty mds_group_name: ceph.rgw.empty mgr_group_name: ceph.rgw mon_group_name: ceph.rgw nfs_group_name: ceph.rgw.empty osd_group_name: ceph.rgw rbdmirror_group_name: ceph.rgw.empty restapi_group_name: ceph.rgw.empty rgw_group_name: ceph.rgw rgwloadbalancer_group_name: ceph.rgw.empty The groups used are then added in the inventory in the 10-custom file. inventory/10-custom [ceph.rgw] testbed-node-3.testbed.osism.xyz testbed-node-4.testbed.osism.xyz testbed-node-5.testbed.osism.xyz [ceph.rgw.empty] The sub environment can then be specified with all apply commands of the OSISM CLI. For example, to deploy the Ceph mon services of the ceph.rgw sub environment: osism apply --sub rgw ceph-osds","s":"Second Ceph cluster","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#second-ceph-cluster","p":1099},{"i":1122,"t":"Resource limits for the individual Ceph services can be set via environments/ceph/configuration.yml. The possible parameters and their defaults for memory limits and CPU limits are listed below. Memory limits ceph_mds_docker_memory_limit: \"{{ ansible_facts['memtotal_mb'] }}m\" ceph_mgr_docker_memory_limit: \"{{ ansible_facts['memtotal_mb'] }}m\" ceph_mon_docker_memory_limit: \"{{ ansible_facts['memtotal_mb'] }}m\" ceph_osd_docker_memory_limit: \"{{ ansible_facts['memtotal_mb'] }}m\" ceph_rbd_mirror_docker_memory_limit: \"{{ ansible_facts['memtotal_mb'] }}m\" ceph_rgw_docker_memory_limit: \"4096m\" CPU limits ceph_mds_docker_cpu_limit: 4 ceph_mgr_docker_cpu_limit: 1 ceph_mon_docker_cpu_limit: 1 ceph_osd_docker_cpu_limit: 4 ceph_rbd_mirror_docker_cpu_limit: 1 ceph_rgw_docker_cpu_limit: 8","s":"Resource limits","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#resource-limits","p":1099},{"i":1124,"t":"CPU pinning and specifying the NUMA nodes to be used for the Ceph OSD and RGW services can be set via environments/ceph/configuration.yml. The possible parameters and possible values are listed below. The parameters are not enabled by default. Limit the specific CPUs or cores a container can use. A comma-separated list or hyphen-separated range of CPUs a container can use, if you have more than one CPU. The first CPU is numbered 0. A valid value might be 0-3 (to use the first, second, third, and fourth CPU) or 1,3 (to use the second and fourth CPU). # ceph_osd_docker_cpuset_cpus: \"0,2,4,6,8,10,12,14,16\" # ceph_rgw_docker_cpuset_cpus: \"0,2,4,6,8,10,12,14,16\" Memory nodes in which to allow execution (e.g. 0-3, 0,1). Only effective on NUMA systems. # ceph_osd_docker_cpuset_mems: \"0\" # ceph_rgw_docker_cpuset_mems: \"0\" Available NUMA nodes on a node can be displayed with numactl. In this example, there are 2 NUMA nodes. The pinned CPUs should all be assigned to the specified NUMA node. # numactl --hardware available: 2 nodes (0-1) node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 node 0 size: 515581 MB node 0 free: 511680 MB node 1 cpus: 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 node 1 size: 516078 MB node 1 free: 511865 MB node distances: node 0 1 0: 10 20 1: 20 10","s":"CPU Pinning","u":"/docs/iaas/guides/configuration-guide/ceph","h":"#cpu-pinning","p":1099},{"i":1126,"t":"Barbican admin guide Barbican configuration guide Barbican configuration reference","s":"Barbican","u":"/docs/iaas/guides/configuration-guide/openstack/barbican","h":"","p":1125},{"i":1128,"t":"Cinder admin guide Cinder configuration guide Cinder configuration reference","s":"Cinder","u":"/docs/iaas/guides/configuration-guide/openstack/cinder","h":"","p":1127},{"i":1130,"t":"https://support.purestorage.com/bundle/m_openstack/page/Solutions/topics/concept/c_openstack_02.html Pure Storage OpenStack (2023.2) Cinder Driver Best Practices https://github.com/openstack/cinder/blob/master/cinder/volume/drivers/pure.py https://docs.openstack.org/cinder/latest/configuration/block-storage/drivers/pure-storage-driver.html","s":"Pure Storage FlashArray","u":"/docs/iaas/guides/configuration-guide/openstack/cinder","h":"#pure-storage-flasharray","p":1127},{"i":1132,"t":"Designate admin guide Designate configuration guide Designate configuration reference","s":"Designate","u":"/docs/iaas/guides/configuration-guide/openstack/designate","h":"","p":1131},{"i":1134,"t":"Ceilometer admin guide Ceilometer configuration reference","s":"Ceilometer","u":"/docs/iaas/guides/configuration-guide/openstack/ceilometer","h":"","p":1133},{"i":1136,"t":"Glance admin guide Glance configuration reference","s":"Glance","u":"/docs/iaas/guides/configuration-guide/openstack/glance","h":"","p":1135},{"i":1138,"t":"Heat admin guide Heat configuration reference","s":"Heat","u":"/docs/iaas/guides/configuration-guide/openstack/heat","h":"","p":1137},{"i":1140,"t":"Ironic admin guide Ironic configuration reference","s":"Ironic","u":"/docs/iaas/guides/configuration-guide/openstack/ironic","h":"","p":1139},{"i":1142,"t":"Horizon admin guide Horizon configuration guide Horizon configuration reference","s":"Horizon","u":"/docs/iaas/guides/configuration-guide/openstack/horizon","h":"","p":1141},{"i":1144,"t":"By default, the LimitRequestBody is set to 1073741824 (1 GiB). This is a security feature (CVE-2022-29404) and not a bug. Further details in the A new default for the LimitRequestBody directive in httpd configuration article in the RedHat knowledgebase. This limit can be increased via the parameter horizon_httpd_limitrequestbody. environments/kolla/configuration.yml horizon_httpd_limitrequestbody: 2147483648 # 2 GiB","s":"Problems uploading machine images larger than 1 GiB","u":"/docs/iaas/guides/configuration-guide/openstack/horizon","h":"#problems-uploading-machine-images-larger-than-1-gib","p":1141},{"i":1146,"t":"By default, only the openrc file is offered for download in Horizon. It makes sense to also add the clouds.yaml as a download. To do this, the menu is customised in the custom_local_settings. The change can be deployed with osism apply -a reconfigure horizon. environments/kolla/files/overlays/horizon/custom_local_settings SHOW_KEYSTONE_V2_RC = False USER_MENU_LINKS = [ {'name': _('OpenStack clouds.yml File'), 'icon_classes': ['fa-download', ], 'url': 'horizon:project:api_access:clouds.yaml', 'external': False, }, {'name': _('OpenStack RC File v3'), 'icon_classes': ['fa-download', ], 'url': 'horizon:project:api_access:openrc', 'external': False, } ]","s":"Make clouds.yml file downloadable as an alternative to the RC file","u":"/docs/iaas/guides/configuration-guide/openstack/horizon","h":"#make-cloudsyml-file-downloadable-as-an-alternative-to-the-rc-file","p":1141},{"i":1148,"t":"Keystone admin guide Keystone configuration reference","s":"Keystone","u":"/docs/iaas/guides/configuration-guide/openstack/keystone","h":"","p":1147},{"i":1150,"t":"This policy is currently still in draft status. Its use in production is currently not recommended. SCS Standard Track SCS Standard SCS Documentation IAM scs-0302 Domain Manager configuration for Keystone To configure and use the domain manager role from the SCS project, the environments/kolla/files/overlays/keystone/policy.yaml file is created in the configuration repository. The deployment and upgrade of the Keystone service itself is then done as usual. environments/kolla/files/overlays/keystone/policy.yaml --- # SCS Domain Manager policy configuration # Section A: OpenStack base definitons # The entries beginning with \"base_\" should be exact copies of the # default \"identity:\" definitions for the target OpenStack release. # They will be extended upon for the domain manager role below this section. \"base_get_domain\": \"(role:reader and system_scope:all) or token.domain.id:%(target.domain.id)s or token.project.domain.id:%(target.domain.id)s\" \"base_list_domains\": \"(role:reader and system_scope:all)\" \"base_list_roles\": \"(role:reader and system_scope:all)\" \"base_get_role\": \"(role:reader and system_scope:all)\" \"base_list_users\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)\" \"base_get_user\": \"(role:reader and system_scope:all) or (role:reader and token.domain.id:%(target.user.domain_id)s) or user_id:%(target.user.id)s\" \"base_create_user\": \"(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)\" \"base_update_user\": \"(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)\" \"base_delete_user\": \"(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)\" \"base_list_projects\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)\" \"base_get_project\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.project.domain_id)s) or project_id:%(target.project.id)s\" \"base_create_project\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)\" \"base_update_project\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)\" \"base_delete_project\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)\" \"base_list_user_projects\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(target.user.id)s\" \"base_check_grant\": \"(role:reader and system_scope:all) or ((role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)\" \"base_list_grants\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)\" \"base_create_grant\": \"(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)\" \"base_revoke_grant\": \"(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)\" \"base_list_role_assignments\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)\" \"base_list_groups\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)\" \"base_get_group\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)\" \"base_create_group\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)\" \"base_update_group\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)\" \"base_delete_group\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)\" \"base_list_groups_for_user\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(user_id)s\" \"base_list_users_in_group\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)\" \"base_remove_user_from_group\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)\" \"base_check_user_in_group\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)\" \"base_add_user_to_group\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)\" # Section B: Domain Manager Extensions # classify domain managers with a special role \"is_domain_manager\": \"role:manager\" # specify a rule that whitelists roles which domain admins are permitted # to assign and revoke within their domain \"is_domain_managed_role\": \"'member':%(target.role.name)s or 'load-balancer_member':%(target.role.name)s or 'creator':%(target.role.name)s\" # allow domain admins to retrieve their own domain (does not need changes) \"identity:get_domain\": \"rule:base_get_domain or rule:admin_required\" # list_domains is needed for GET /v3/domains?name=... requests # this is mandatory for things like # `create user --domain $DOMAIN_NAME $USER_NAME` to correctly discover # domains by name \"identity:list_domains\": \"rule:is_domain_manager or rule:base_list_domains or rule:admin_required\" # list_roles is needed for GET /v3/roles?name=... requests # this is mandatory for things like `role add ... $ROLE_NAME`` to correctly # discover roles by name \"identity:list_roles\": \"rule:is_domain_manager or rule:base_list_roles or rule:admin_required\" # get_role is needed for GET /v3/roles/{role_id} requests # this is mandatory for the OpenStack SDK to properly process role assignments # which are issued by role id instead of name \"identity:get_role\": \"(rule:is_domain_manager and rule:is_domain_managed_role) or rule:base_get_role or rule:admin_required\" # allow domain admins to manage users within their domain \"identity:list_users\": \"(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_users or rule:admin_required\" \"identity:get_user\": \"(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_get_user or rule:admin_required\" \"identity:create_user\": \"(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_create_user or rule:admin_required\" \"identity:update_user\": \"(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_update_user or rule:admin_required\" \"identity:delete_user\": \"(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_delete_user or rule:admin_required\" # allow domain admins to manage projects within their domain \"identity:list_projects\": \"(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_projects or rule:admin_required\" \"identity:get_project\": \"(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_get_project or rule:admin_required\" \"identity:create_project\": \"(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_create_project or rule:admin_required\" \"identity:update_project\": \"(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_update_project or rule:admin_required\" \"identity:delete_project\": \"(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_delete_project or rule:admin_required\" \"identity:list_user_projects\": \"(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_user_projects or rule:admin_required\" # allow domain managers to manage role assignments within their domain # (restricted to specific roles by the 'is_domain_managed_role' rule) # # project-level role assignment to user within domain \"is_domain_user_project_grant\": \"token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s\" # project-level role assignment to group within domain \"is_domain_group_project_grant\": \"token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.project.domain_id)s\" # domain-level role assignment to group \"is_domain_level_group_grant\": \"token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.domain.id)s\" # domain-level role assignment to user \"is_domain_level_user_grant\": \"token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.domain.id)s\" \"domain_manager_grant\": \"rule:is_domain_manager and (rule:is_domain_user_project_grant or rule:is_domain_group_project_grant or rule:is_domain_level_group_grant or rule:is_domain_level_user_grant)\" \"identity:check_grant\": \"rule:domain_manager_grant or rule:base_check_grant or rule:admin_required\" \"identity:list_grants\": \"rule:domain_manager_grant or rule:base_list_grants or rule:admin_required\" \"identity:create_grant\": \"(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_create_grant or rule:admin_required\" \"identity:revoke_grant\": \"(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_revoke_grant or rule:admin_required\" \"identity:list_role_assignments\": \"(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_role_assignments or rule:admin_required\" # allow domain managers to manage groups within their domain \"identity:list_groups\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_list_groups or rule:admin_required\" \"identity:get_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_get_group or rule:admin_required\" \"identity:create_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_create_group or rule:admin_required\" \"identity:update_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_update_group or rule:admin_required\" \"identity:delete_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_delete_group or rule:admin_required\" \"identity:list_groups_for_user\": \"(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_groups_for_user or rule:admin_required\" \"identity:list_users_in_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_list_users_in_group or rule:admin_required\" \"identity:remove_user_from_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_remove_user_from_group or rule:admin_required\" \"identity:check_user_in_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_check_user_in_group or rule:admin_required\" \"identity:add_user_to_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_add_user_to_group or rule:admin_required\" The role manager is created using the OpenStack CLI. Alternatively, the role can be added using Ansible or other tools. $ openstack --os-cloud admin \\ role create \\ --or-show \\ --description \"Domain Manager Role\" \\ manager +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | Domain Manager Role | | domain_id | None | | id | 9b7140bfe628468ab9b86b365f9ac4c2 | | name | manager | | options | {} | +-------------+----------------------------------+ A user can then be made a domain manager for a particular domain by assigning this role. $ openstack --os-cloud admin \\ role add \\ --user test \\ --domain test \\ manager","s":"Domain manager policy","u":"/docs/iaas/guides/configuration-guide/openstack/keystone","h":"#domain-manager-policy","p":1147},{"i":1153,"t":"Manila admin guide Manila configuration guide Manila configuration reference","s":"Manila","u":"/docs/iaas/guides/configuration-guide/openstack/manila","h":"","p":1152},{"i":1156,"t":"Sometimes it is necessary to specify the image tag to be used for a specific service or a specific image of a service. All available images and tags are listed in the 002-images-kolla.yml file. The image tags can be set in the environments/kolla/images.yml file. Use a specific tag for all images of a service: environments/kolla/images.yml barbican_tag: \"2023.1\" Use a specific tag for a specific image of a service: environments/kolla/images.yml barbican_worker_tag: \"2023.1\"","s":"Image tags","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#image-tags","p":1154},{"i":1159,"t":"The public endpoints used for the individual OpenStack services can be configured via the public_endpoint parameters. These are defined as follows. Parameter Default value aodh_public_endpoint aodh_external_fqdn | kolla_url(public_protocol, aodh_api_public_port) blazar_public_endpoint blazar_external_fqdn | kolla_url(public_protocol, blazar_api_public_port, '/v1') ceph_rgw_public_endpoint ceph_rgw_external_fqdn | kolla_url(public_protocol, ceph_rgw_public_port, ceph_rgw_endpoint_path) cinder_v3_public_endpoint {{ cinder_public_base_endpoint }}/v3/%(tenant_id)s cloudkitty_public_endpoint cloudkitty_external_fqdn | kolla_url(public_protocol, cloudkitty_api_public_port) cyborg_public_endpoint cyborg_external_fqdn | kolla_url(public_protocol, cyborg_api_port, '/v2') gnocchi_public_endpoint gnocchi_external_fqdn | kolla_url(public_protocol, gnocchi_api_public_port) heat_cfn_public_endpoint {{ heat_cfn_public_base_endpoint }}/v1 heat_public_endpoint heat_external_fqdn | kolla_url(public_protocol, heat_api_public_port, '/v1/%(tenant_id)s') ironic_inspector_public_endpoint ironic_inspector_external_fqdn | kolla_url(public_protocol, ironic_inspector_public_port) magnum_public_endpoint magnum_external_fqdn | kolla_url(public_protocol, magnum_api_public_port, '/v1') manila_public_endpoint {{ manila_public_base_endpoint }}/v1/%(tenant_id)s manila_v2_public_endpoint {{ manila_public_base_endpoint }}/v2 masakari_public_endpoint masakari_external_fqdn | kolla_url(public_protocol, masakari_api_public_port) mistral_public_endpoint mistral_external_fqdn | kolla_url(public_protocol, mistral_api_public_port, '/v2') nova_legacy_public_endpoint {{ nova_public_base_endpoint }}/v2/%(tenant_id)s nova_public_endpoint {{ nova_public_base_endpoint }}/v2.1 placement_public_endpoint placement_external_fqdn | kolla_url(public_protocol, placement_api_public_port) tacker_public_endpoint tacker_external_fqdn | kolla_url(public_protocol, tacker_server_public_port) trove_public_endpoint trove_external_fqdn | kolla_url(public_protocol, trove_api_public_port, '/v1.0/%(tenant_id)s') venus_public_endpoint venus_external_fqdn | kolla_url(public_protocol, venus_api_port) watcher_public_endpoint watcher_external_fqdn | kolla_url(public_protocol, watcher_api_public_port) zun_public_endpoint zun_external_fqdn | kolla_url(public_protocol, zun_api_public_port, '/v1/') Some of the previous default values refer to a public_base_endpoint parameter. These are defined as follows. Parameter Default value cinder_public_base_endpoint cinder_external_fqdn | kolla_url(public_protocol, cinder_api_public_port) heat_cfn_public_base_endpoint heat_cfn_external_fqdn | kolla_url(public_protocol, heat_api_cfn_public_port) manila_public_base_endpoint manila_external_fqdn | kolla_url(public_protocol, manila_api_public_port) nova_public_base_endpoint nova_external_fqdn | kolla_url(public_protocol, nova_api_public_port) skyline_apiserver_public_base_endpoint skyline_apiserver_external_fqdn | kolla_url(public_protocol, skyline_apiserver_public_port)","s":"Public endpoints","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#public-endpoints","p":1154},{"i":1161,"t":"DNS records pointing to the kolla_external_vip_address are created in advance. Additional configuration parameters to overwrite the public endpoints are added in the environments/kolla/configuration.yml file. If certain services are not used, they are removed. If other services are used, these are added (see the table above). environments/kolla/configuration.yml barbican_public_endpoint: https://barbican.services.a.regiocloud.tech cinder_public_base_endpoint: https://cinder.services.a.regiocloud.tech designate_public_endpoint: https://designate.services.a.regiocloud.tech glance_public_endpoint: https://glance.services.a.regiocloud.tech ironic_public_endpoint: https://ironic.services.a.regiocloud.tech keystone_public_url: https://keystone.services.a.regiocloud.tech manila_public_endpoint: https://manila.services.a.regiocloud.tech neutron_public_endpoint: https://neutron.services.a.regiocloud.tech nova_public_base_endpoint: https://nova.services.a.regiocloud.tech octavia_public_endpoint: https://octavia.services.a.regiocloud.tech placement_public_endpoint: https://placement.services.a.regiocloud.tech Since we bind the name_based_external_front frontend to the same ports as the horizon_external_front, the external Horizon frontend must be disabled. This is only possible as of OSISM 7.0.6. environments/kolla/configuration.yml haproxy_enable_horizon_external: false Additional HAProxy configuration in haproxy/services.d/haproxy.cfg is required to map the DNS records to the correct backends. Here too, unused services are removed or additional services are added. environments/kolla/files/overlays/haproxy/services.d/haproxy.cfg frontend name_based_external_front mode http http-request del-header X-Forwarded-Proto option httplog option forwardfor http-request set-header X-Forwarded-Proto https if { ssl_fc } bind {{ kolla_external_vip_address }}:80 bind {{ kolla_external_vip_address }}:443 ssl crt /etc/haproxy/certificates/haproxy.pem default_backend horizon_back acl ACL_keystone.services.a.regiocloud.tech hdr(host) -i keystone.services.a.regiocloud.tech use_backend keystone_external_back if ACL_keystone.services.a.regiocloud.tech acl ACL_glance.services.a.regiocloud.tech hdr(host) -i glance.services.a.regiocloud.tech use_backend glance_api_external_back if ACL_glance.services.a.regiocloud.tech acl ACL_neutron.services.a.regiocloud.tech hdr(host) -i neutron.services.a.regiocloud.tech use_backend neutron_server_external_back if ACL_neutron.services.a.regiocloud.tech acl ACL_placement.services.a.regiocloud.tech hdr(host) -i placement.services.a.regiocloud.tech use_backend placement_api_external_back if ACL_placement.services.a.regiocloud.tech acl ACL_nova.services.a.regiocloud.tech hdr(host) -i nova.services.a.regiocloud.tech use_backend nova_api_external_back if ACL_nova.services.a.regiocloud.tech acl ACL_console.services.a.regiocloud.tech hdr(host) -i console.services.a.regiocloud.tech use_backend nova_novncproxy_external_back if ACL_console.services.a.regiocloud.tech acl ACL_designate.services.a.regiocloud.tech hdr(host) -i designate.services.a.regiocloud.tech use_backend designate_api_external_back if ACL_designate.services.a.regiocloud.tech acl ACL_cinder.services.a.regiocloud.tech hdr(host) -i cinder.services.a.regiocloud.tech use_backend cinder_api_external_back if ACL_cinder.services.a.regiocloud.tech acl ACL_octavia.services.a.regiocloud.tech hdr(host) -i octavia.services.a.regiocloud.tech use_backend octavia_api_external_back if ACL_octavia.services.a.regiocloud.tech acl ACL_swift.services.a.regiocloud.tech hdr(host) -i swift.services.a.regiocloud.tech use_backend swift_api_external_back if ACL_swift.services.a.regiocloud.tech acl ACL_ironic.services.a.regiocloud.tech hdr(host) -i ironic.services.a.regiocloud.tech use_backend ironic_api_external_back if ACL_ironic.services.a.regiocloud.tech Additional Nova configuration in nova.conf is required to use the URL for the NoVNC service. environments/kolla/files/overlays/nova.conf [vnc] novncproxy_base_url = https://console.services.a.regiocloud.tech/vnc_lite.html","s":"Example for the use of name-based endpoints","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#example-for-the-use-of-name-based-endpoints","p":1154},{"i":1163,"t":"Parameter Default Description network_interface eth0 neutron_external_interface {{ network_interface }} kolla_external_vip_interface {{ network_interface }} api_interface {{ network_interface }} migration_interface {{ api_interface }} tunnel_interface {{ network_interface }} octavia_network_interface {{ 'o-hm0' if octavia_network_type == 'tenant' else api_interface }} dns_interface {{ network_interface }} dpdk_tunnel_interface {{ neutron_external_interface }} ironic_http_interface {{ api_interface }} ironic_tftp_interface {{ api_interface }}","s":"Network interfaces","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#network-interfaces","p":1154},{"i":1165,"t":"info The following content is based on the kolla-ansible uptream documentation. OSISM will generally look for files in environments/kolla/files/overlays/CONFIGFILE, environments/kolla/files/overlays/SERVICENAME/CONFIGFILE or environments/kolla/files/overlays/SERVICENAME/HOSTNAME/CONFIGFILE in the configuration repository. These locations sometimes vary and you should check the config task in the appropriate Ansible role for a full list of supported locations. For example, in the case of nova.conf the following locations are supported, assuming that you have services using nova.conf running on hosts called ctl1, ctl2 and ctl3: environments/kolla/files/overlays/nova.conf environments/kolla/files/overlays/nova/ctl1/nova.conf environments/kolla/files/overlays/nova/ctl2/nova.conf environments/kolla/files/overlays/nova/ctl3/nova.conf environments/kolla/files/overlays/nova/nova-scheduler.conf Using this mechanism, overrides can be configured per-project (Nova), per-project-service (Nova scheduler service) or per-project-service-on-specified-host (Nova servies on ctl1). Overriding an option is as simple as setting the option under the relevant section. For example, to set override scheduler_max_attempts in the Nova scheduler service, the operator could create environments/kolla/files/overlays/nova/nova-scheduler.conf in the configuration repository with this content: [DEFAULT] scheduler_max_attempts = 100 If the operator wants to configure the initial disk, cpu and ram allocation ratio on compute node com1, the operator needs to create the file environments/kolla/files/overlays/nova/com1/nova.conf with this content: [DEFAULT] initial_cpu_allocation_ratio = 3.0 initial_ram_allocation_ratio = 1.0 initial_disk_allocation_ratio = 1.0 Note that the numbers shown here with an initial_cpu_allocation_ratio of 3.0 do match the requirements of the SCS-nV-* (moderate oversubscription) flavors. If you do not use SMT/hyperthreading, SCS would allow 5.0 here (for the V flavors). This method of merging configuration sections is supported for all services using oslo.config, which includes the vast majority of OpenStack services, and in some cases for services using YAML configuration. Since the INI format is an informal standard, not all INI files can be merged in this way. In these cases OSISM supports overriding the entire config file. Additional flexibility can be introduced by using Jinja conditionals in the config files. For example, you may create Nova cells which are homogeneous with respect to the hypervisor model. In each cell, you may wish to configure the hypervisors differently, for example the following override shows one way of setting the bandwidth_poll_interval variable as a function of the cell: [DEFAULT] {% if 'cell0001' in group_names %} bandwidth_poll_interval = 100 {% elif 'cell0002' in group_names %} bandwidth_poll_interval = -1 {% else %} bandwidth_poll_interval = 300 {% endif %} An alternative to Jinja conditionals would be to define a variable for the bandwidth_poll_interval and set it in according to your requirements in the inventory group or host vars: [DEFAULT] bandwidth_poll_interval = {{ bandwidth_poll_interval }} OSISM allows the operator to override configuration globally for all services. It will look for a file called environments/kolla/files/overlays/global.conf in the configuration repository. For example to modify database pool size connection for all services, the operator needs to create environments/kolla/files/overlays/global.conf in the configuration repository with this content: [database] max_pool_size = 100","s":"Customization of the service configurations","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#customization-of-the-service-configurations","p":1154},{"i":1167,"t":"It is explained with example of OpenSearch Service how the configuration for OpenSearch is created and gets into the container. The task Copying over opensearch service config file merges the individual sources of the files. Copying over opensearch service config file task - name: Copying over opensearch service config file merge_yaml: sources: - \"{{ role_path }}/templates/opensearch.yml.j2\" - \"{{ node_custom_config }}/opensearch.yml\" - \"{{ node_custom_config }}/opensearch/opensearch.yml\" - \"{{ node_custom_config }}/opensearch/{{ inventory_hostname }}/opensearch.yml\" dest: \"{{ node_config_directory }}/opensearch/opensearch.yml\" mode: \"0660\" become: true when: - inventory_hostname in groups['opensearch'] - opensearch_services['opensearch'].enabled | bool notify: - Restart opensearch container As a basis a template opensearch.yml.j2 is used which is part of the OpenSearch service role. opensearch.yml.j2 template {% set num_nodes = groups['opensearch'] | length %} {% set recover_after_nodes = (num_nodes * 2 / 3) | round(0, 'floor') | int if num_nodes > 1 else 1 %} plugins.security.disabled: \"true\" node.name: \"{{ 'api' | kolla_address | put_address_in_context('url') }}\" network.host: \"{{ 'api' | kolla_address | put_address_in_context('url') }}\" cluster.name: \"{{ opensearch_cluster_name }}\" cluster.initial_master_nodes: [{% for host in groups['opensearch'] %}\"{{ 'api' | kolla_address(host) }}\"{% if not loop.last %},{% endif %}{% endfor %}] node.master: true node.data: true discovery.seed_hosts: [{% for host in groups['opensearch'] %}\"{{ 'api' | kolla_address(host) | put_address_in_context('url') }}\"{% if not loop.last %},{% endif %}{% endfor %}] http.port: {{ opensearch_port }} gateway.expected_nodes: {{ num_nodes }} gateway.recover_after_time: \"5m\" gateway.recover_after_nodes: {{ recover_after_nodes }} path.data: \"/var/lib/opensearch/data\" path.logs: \"/var/log/kolla/opensearch\" indices.fielddata.cache.size: 40% action.auto_create_index: \"true\" For OpenSearch, overlay files can additionally be stored in 3 places in the configuration repository. environments/kolla/files/overlays/opensearch.yml environments/kolla/files/overlays/opensearch/opensearch.yml environments/kolla/files/overlays/opensearch/{{ inventory_hostname }}/opensearch.yml When merging files, the last file found has the most weight. If there is a parameter node.master: true in the service role template opensearch.yml.j2 of the OpenSearch service and you set e.g. node.master: false in environments/kolla/files/overlays/opensearch.yml then accordingly in the finished opensearch.yml node.master: false is used. After the merge the task Copying over opensearch service config file copies the content into the configuration directory /etc/kolla/opensearch of the service. /etc/kolla/opensearch/opensearch.yml action.auto_create_index: 'true' cluster.initial_master_nodes: - 192.168.16.10 cluster.name: kolla_logging discovery.seed_hosts: - 192.168.16.10 gateway.expected_nodes: 1 gateway.recover_after_nodes: 1 gateway.recover_after_time: 5m http.port: 9200 indices.fielddata.cache.size: 40% network.host: 192.168.16.10 node.data: true node.master: true node.name: 192.168.16.10 path.data: /var/lib/opensearch/data path.logs: /var/log/kolla/opensearch plugins.security.disabled: 'true' The configuration directory /etc/kolla/opensearch is mounted in each container of the OpenSearch service to /var/lib/kolla/config_files. Output of docker inspect opensearch \"Mounts\": [ { \"Type\": \"bind\", \"Source\": \"/etc/kolla/opensearch\", \"Destination\": \"/var/lib/kolla/config_files\", \"Mode\": \"rw\", \"RW\": true, \"Propagation\": \"rprivate\" }, Entrypoint of a service is always kolla_start. This script calls a script set_configs.py. This script takes care of copying files from /var/lib/kolla/config_files to the right place inside the container. For this purpose, the container has a config.json in which the individual actions are configured. The file /var/lib/kolla/config_files/opensearch.yml is copied to /etc/opensearch/opensearch.yml. The permissions of /var/lib/opensearch and /var/log/kolla/opensearch are set accordingly. /etc/kolla/opensearch/config.json { \"command\": \"/usr/share/opensearch/bin/opensearch\", \"config_files\": [ { \"source\": \"/var/lib/kolla/config_files/opensearch.yml\", \"dest\": \"/etc/opensearch/opensearch.yml\", \"owner\": \"opensearch\", \"perm\": \"0600\" } ], \"permissions\": [ { \"path\": \"/var/lib/opensearch\", \"owner\": \"opensearch:opensearch\", \"recurse\": true }, { \"path\": \"/var/log/kolla/opensearch\", \"owner\": \"opensearch:opensearch\", \"recurse\": true } ] } In the config.json of the service is also defined the command which will be executed after finishing the preparations. In the case of OpenSearch this is /usr/share/opensearch/bin/opensearch. /etc/kolla/opensearch/config.json { \"command\": \"/usr/share/opensearch/bin/opensearch\", \"config_files\": [ { \"source\": \"/var/lib/kolla/config_files/opensearch.yml\", \"dest\": \"/etc/opensearch/opensearch.yml\", \"owner\": \"opensearch\", \"perm\": \"0600\" } ], \"permissions\": [ { \"path\": \"/var/lib/opensearch\", \"owner\": \"opensearch:opensearch\", \"recurse\": true }, { \"path\": \"/var/log/kolla/opensearch\", \"owner\": \"opensearch:opensearch\", \"recurse\": true } ] }","s":"How does the configuration get into services?","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#how-does-the-configuration-get-into-services","p":1154},{"i":1169,"t":"The number of workers used for the individual services can generally be configured using two parameters. openstack_service_workers: \"{{ [ansible_facts.processor_vcpus, 5] | min }}\" openstack_service_rpc_workers: \"{{ [ansible_facts.processor_vcpus, 3] | min }}“ The default for openstack_service_workers is set to 5 when using the cookiecutter for the initial creation of the configuration. This value can be overwritten for individual services. The default for all parameters in the following table is {{ openstack_service_workers }}. The parameter aodh_api_workers can then be used to explicitly set the number of workers for the AODH API, for example. A reconfigure must be made for the particular services in the case of a change. osism apply -a reconfigure aodh in this example. These parameters are all set in environments/kolla/configuration.yml. Parameter aodh_api_workers barbican_api_workers cinder_api_workers designate_api_workers designate_worker_workers designate_producer_workers designate_central_workers designate_sink_workers designate_mdns_workers glance_api_workers gnocchi_metricd_workers gnocchi_api_workers heat_api_cfn_workers heat_api_workers heat_engine_workers horizon_wsgi_processes ironic_api_workers keystone_api_workers proxysql_workers magnum_api_workers magnum_conductor_workers manila_api_workers neutron_api_workers neutron_metadata_workers nova_api_workers nova_superconductor_workers nova_metadata_api_workers nova_scheduler_workers nova_cell_conductor_workers octavia_api_workers octavia_healthmanager_health_workers octavia_healthmanager_stats_workers placement_api_workers skyline_gunicorn_workers","s":"Number of service workers","u":"/docs/iaas/guides/configuration-guide/openstack/","h":"#number-of-service-workers","p":1154},{"i":1171,"t":"Nova admin guide Nova configuration guide Nova configuration reference","s":"Nova","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"","p":1170},{"i":1174,"t":"echo \"options kvm-amd nested=y\" | sudo tee /etc/modprobe.d/kvm-nested-virtualization.conf sudo modprobe -r kvm_amd sudo modprobe kvm_amd cat /sys/module/kvm_amd/parameters/nested Y docker restart nova_libvirt","s":"AMD","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#amd","p":1170},{"i":1176,"t":"echo \"options kvm-intel nested=y\" | sudo tee /etc/modprobe.d/kvm-nested-virtualization.conf sudo modprobe -r kvm_intel sudo modprobe kvm_intel cat /sys/module/kvm_intel/parameters/nested Y docker restart nova_libvirt","s":"Intel","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#intel","p":1170},{"i":1178,"t":"How many resources you want to reserve on a compute node depends very much on which additional services are running on the compute node.","s":"Reserve compute node resources","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#reserve-compute-node-resources","p":1170},{"i":1180,"t":"https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.reserved_host_memory_mb environments/kolla/files/overlays/nova/nova-compute.conf [DEFAULT] reserved_host_memory_mb = 32768","s":"Host memory","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#host-memory","p":1170},{"i":1182,"t":"https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.reserved_host_cpus environments/kolla/files/overlays/nova/nova-compute.conf [DEFAULT] reserved_host_cpus = 4","s":"Host CPUs","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#host-cpus","p":1170},{"i":1184,"t":"In this example, a local SSD is provided for use on compute node testbed-node-0. By default, Nova accesses the local storage on a file basis. It is also possible to work with logical volumes instead. However, this is not recommended or supported by OSISM. More details in the Nova Configuration Guide. On the compute node, the local SSD to be used is formatted with a file system of your choice and mounted to /var/lib/nova. When using more than one local SSD, a software RAID 1 should be used It is recommended to automate the creation of the file system and the creation of the mount point with a custom playbook. A nova.conf configuration file is created as an overlay file for the compute node testbed-node-0. The name of the directory must match the name of the host in the inventory. If the compute node has a file with the name testbed-node-0.yml in the host_vars directory in the inventory, then the name of the directory in the overlays is testbed-node-0 accordingly. If the file name there were testbed-node-0.testbed.osism.xyz.yml then the name of the directory would be testbed-node-0.testbed.osism.xyz. environments/kolla/files/overlays/nova/testbed-node-0/nova.conf [libvirt] images_type = raw [glance] enable_rbd_download = true As Ceph is still used as the storage backend for Glance and Cinder, the image type is set to raw. To allow to download and cache images from Ceph via rbd rather than the Glance API via http enable_rbd_download is set to true. Parameters must also be added in the inventory. This differs depending on the OSISM version used. Up to OSISM 6 it looks like this: In the inventory, the parameter nova_instance_datadir_volume is added in the section for the kolla environment. inventory/host_vars/testbed-node-0.yml ########################################################## # kolla nova_instance_datadir_volume: /var/lib/nova Starting with OSISM 7, it looks like this: In the inventory, the parameters nova_instance_datadir_volume and nova_backend, are added in the section for the kolla environment. inventory/host_vars/testbed-node-0.yml ########################################################## # kolla nova_instance_datadir_volume: /var/lib/nova nova_backend: default It is currently not possible to completely deactivate the Ceph integration with Nova. So if you have all compute nodes with local storage, you still have to do the Ceph integration for Nova itself and convert each compute node specifically to local storage. If this is not done, errors will occur when deploying Nova.","s":"Local SSD storage","u":"/docs/iaas/guides/configuration-guide/openstack/nova","h":"#local-ssd-storage","p":1170},{"i":1186,"t":"Neutron admin guide Neutron configuration guide Neutron configuration reference Neutron-Dynamic-Routing: Neutron-Dynamic-Routing admin guide Neutron-Dynamic-Routing configuration guide Neutron-Dynamic-Routing configuration reference Neutron-VPNaaS: Neutron-VPNaaS admin guide Neutron-VPNaaS configuration guide","s":"Neutron","u":"/docs/iaas/guides/configuration-guide/openstack/neutron","h":"","p":1185},{"i":1188,"t":"Neutron uses the MTU of the underlying physical network to calculate the MTU for virtual network components including instance network interfaces. By default, it assumes a standard 1500-byte MTU for the underlying physical network. Neutron only references the underlying physical network MTU. Changing the underlying physical network device MTU requires configuration of physical network devices such as switches and routers. The configuration is described in the Neutron admin guide. The configuration files are placed under environments/kolla/files/overlays/neutron/ml2_conf.ini and environments/kolla/files/overlays/neutron.conf.","s":"MTU Considerations","u":"/docs/iaas/guides/configuration-guide/openstack/neutron","h":"#mtu-considerations","p":1185},{"i":1190,"t":"Magnum admin guide Magnum configuration reference","s":"Magnum","u":"/docs/iaas/guides/configuration-guide/openstack/magnum","h":"","p":1189},{"i":1192,"t":"Octavia admin guide Octavia configuration guide Octavia configuration reference","s":"Octavia","u":"/docs/iaas/guides/configuration-guide/openstack/octavia","h":"","p":1191},{"i":1195,"t":"Skyline APIServer configuration reference","s":"Skyline APIServer","u":"/docs/iaas/guides/configuration-guide/openstack/skyline","h":"#skyline-apiserver","p":1193},{"i":1197,"t":"Skyline Console admin guide Skyline Console configuration reference","s":"Skyline Console","u":"/docs/iaas/guides/configuration-guide/openstack/skyline","h":"#skyline-console","p":1193},{"i":1199,"t":"In the following examples, it is assumed that the Squid proxy integrated by OSISM is used on the first manager node. Any other proxy accessible from the nodes can also be used here. The Squid service can be deployed on the first manager. This is useful if no proxy can be used in the environment. The first manager node is then used by all other nodes as a pass-through node. Please note that this is not a caching proxy or even an air gap. This is also possible with OSISM, but not with the help of the Squid service. osism apply squid","s":"Proxy","u":"/docs/iaas/guides/configuration-guide/proxy","h":"","p":1198},{"i":1201,"t":"This allows Docker images to be pulled via a proxy. environments/configuration.yml ########################################################## # proxy docker_configure_proxy: true docker_proxy_http: \"http://{{ groups['manager'][0] }}:3128\" docker_proxy_https: \"{{ docker_proxy_http }}\"","s":"Docker","u":"/docs/iaas/guides/configuration-guide/proxy","h":"#docker","p":1198},{"i":1203,"t":"This allows APT packages to be downloaded via a proxy. environments/configuration.yml ########################################################## # proxy proxy_proxies: http: \"http://{{ groups['manager'][0] }}:3128\" https: \"http://{{ groups['manager'][0] }}:3128\"","s":"APT","u":"/docs/iaas/guides/configuration-guide/proxy","h":"#apt","p":1198},{"i":1205,"t":"Proxy settings for containers such as magnum that need internet access. environments/kolla/configuration.yml ########################################################## # proxy container_http_proxy: \"http://{{ groups['manager'][0] }}:3128\" container_https_proxy: \"http://{{ groups['manager'][0] }}:3128\" container_no_proxy: \"localhost,127.0.0.1\"","s":"Kolla","u":"/docs/iaas/guides/configuration-guide/proxy","h":"#kolla","p":1198},{"i":1207,"t":"This section contains the documentation of the Ansible collection osism.services.","s":"Services","u":"/docs/iaas/guides/configuration-guide/services/","h":"","p":1206},{"i":1209,"t":"With the osism.services.chrony role, it is possible to manage the used NTP servers on a node. It is also possible to configure the Chrony service for use inside the cluster.","s":"Chrony","u":"/docs/iaas/guides/configuration-guide/services/chrony","h":"","p":1208},{"i":1211,"t":"Placement admin guide Placement configuration guide Placement configuration reference","s":"Placement","u":"/docs/iaas/guides/configuration-guide/openstack/placement","h":"","p":1210},{"i":1213,"t":"The use of self-signed certificates with a custom CA is possible. However, a few additional parameters are then required in the configuration so that the custom CA is known everywhere and the self-signed certificates are accepted as valid. Import custom CA Any custom CA can be added via the certificates_ca parameter. The import on the nodes is done via osism apply certificates. This is already done in the bootstrap of the nodes. environments/configuration.yml certificates_ca: - name: custom.crt certificate: | -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- Manager service The local environment variable REQUESTS_CA_BUNDLE must be set explicitly so that the manager service knows the custom CA in all necessary places. environments/manager/configuration.yml manager_environment_extra: REQUESTS_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt Use in OpenStack The custom CA must also be copied into the OpenStack containers. To do this, the custom CA is first added in a file in the environments/kolla/certificates/ca of the configuration repository. It makes sense to use the same filename like in step 1. The import of the custom CA must then be explicitly enabled. environments/kolla/configuration.yml kolla_copy_ca_into_containers: \"yes\" openstack_cacert: /etc/ssl/certs/ca-certificates.crt","s":"Self-signed certificates","u":"/docs/iaas/guides/configuration-guide/self-signed-certificates","h":"","p":1212},{"i":1215,"t":"With the osism.services.docker role, it is possible to manage Docker.","s":"Docker","u":"/docs/iaas/guides/configuration-guide/services/docker","h":"","p":1214},{"i":1217,"t":"Docker documentation: https://docs.docker.com/config/containers/logging/configure/ The role currently supports the following parameters with their respective defaults. docker_log_driver: \"json-file\" docker_log_level: info docker_log_opts: max-size: 10m max-file: 3 The log driver to be used can be configured with docker_log_driver. By default, json-file is used. The log driver writes all logs of a container to a JSON file in /var/lib/docker/containers. All supported log drivers can be found in the Docker documentation. The log level can be configured via docker_log_level. Parameters for the log driver used can be set with the docker_log_opts dictionary. By default, the maximum size of a JSON file is set to 10 MByte with max-size: 10m. If it contains more, the file is rotated. Furthermore, max-file: 3 specifies that up to 3 files should be available. Existing containers don't use the new logging configuration automatically.","s":"Configure logging drivers","u":"/docs/iaas/guides/configuration-guide/services/docker","h":"#configure-logging-drivers","p":1214},{"i":1219,"t":"OSISM is deployed in a series of successive steps. The steps are documented in the Deploy Guide. info The prerequisite for the deployment of a cluster is a configuration repository. What a configuration repository is and how it is created is described in the Configuration Guide. Step 1: Preparation of the seed node Step 2: Preparation of the manager node Step 3: Provisioning of the bare-metal nodes Step 4: Bootstrap of the bare-metal nodes Step 5: Deployment of the services","s":"Deploy Guide","u":"/docs/iaas/guides/deploy-guide/","h":"","p":1218},{"i":1221,"t":"This section contains the documentation of the Ansible collection osism.validations.","s":"Validations","u":"/docs/iaas/guides/configuration-guide/validations/","h":"","p":1220},{"i":1224,"t":"info The prerequisite for bootstraping the nodes of a cluster the Manager node has to be prepares. What a Manager node is and how to prepare it is documented in the Manager chapter of the Deploy Guide. All the nodes must also have already been provisioned. How manual provisioning is done is documented in the Provisioning chapter of the Deploy Guide. Before the nodes can be bootstrapped, they must all have already been provisioned. The guide for this can be found in the section Provisioning of bare-metal nodes. The following steps are applied to bootstrap all nodes. After the completion of the bootstrap, the nodes are already ready for use. Create operator user. osism apply operator -u osism When using the osism/node-image the user is osism and the password of this user is password. If you install Ubuntu manually the user usually is ubuntu. If you want to use any other user here, that's no problem. It is important that this user has sudo rights. The password according to what you have set yourself. The operator public SSH key has to be added in advance on all nodes to authorized_keys file of the user specified with -u. This key is stored as operator_public_key in the file environments/configuration.yml. Alternatively (not recommended), the password can be stored in plain text in a file /opt/configuration/secrets/conn_password. The parameter --conn-pass-file /opt/configuration/secrets/conn_password must then also be specified: osism apply operator -u osism \\ --conn-pass-file /opt/configuration/secrets/conn_password It is important that this user has sudo rights with NOPASSWD. Alternatively (not recommended), the password can be stored in plain text in a file /opt/configuration/secrets/become_password. The parameter --become-pass-file /opt/configuration/secrets/become_password must then also be specified: osism apply operator -u osism \\ --become-pass-file /opt/configuration/secrets/become_password If a password is required for both sudo and login, use both arguments at the same time. osism apply operator -u osism \\ --become-pass-file /opt/configuration/secrets/become_password \\ --conn-pass-file /opt/configuration/secrets/conn_password When using the osism/node-image the user is osism and the password of this user is password. If you install Ubuntu manually the user usually is ubuntu. The password according to what you have set yourself Proxy deployment (optional). This is only necessary if you use the proxy on the manager to enable external access to the nodes. osism apply squid Proxy configuration (optional). This is only necessary if you use the proxy on the manager to enable external access to the nodes. osism apply proxy Network configuration. It is recommended to backup the existing network configuration. osism apply network Reboot (optional). The reboot at this point is recommended to ensure that the network configuration is working. osism apply reboot -l 'all:!manager' -e ireallymeanit=yes Check if all systems are reachable (you probably have to do this several times until all systems are accessible). osism apply ping System is currently rebooting and is not yet accessible via network. fatal: [net003]: UNREACHABLE! => {\"changed\": false, \"msg\": \"Connection timed out.\", \"unreachable\": true}`` System has already been rebooted and is not accessible via the network. fatal: [net003]: UNREACHABLE! => {\"changed\": false, \"msg\": \"EOF on stream; last 100 lines received:\\nssh: connect to host 10.15.0.33 port 22: No route to host\\r\", \"unreachable\": true} Refresh facts. osism apply facts Bootstrap. osism apply bootstrap Reboot (non-optional). Since the kernel version often changes after the initial bootstrap, the reboot should always be performed. osism apply reboot -l 'all:!manager' -e ireallymeanit=yes Check if all systems are reachable (you probably have to do this several times until all systems are accessible). osism apply ping Prepare the SSH configuration of the manager node. osism apply sshconfig Make all SSH public keys known. osism apply known-hosts Ready. All nodes are now bootstrapped and available to deploy services.","s":"Bootstrap","u":"/docs/iaas/guides/deploy-guide/bootstrap","h":"","p":1223},{"i":1226,"t":"The roller can be applied with osism apply tuned. The role is applied to all compute nodes by default. This can be changed via the hosts_tuned parameter. The profile to be used can be set via tuned_profile. By default, virtual-host is used. The following profiles are available: Profile Description accelerator-performance Throughput performance based tuning with disabled higher latency STOP states atomic-guest Optimize virtual guests based on the Atomic variant atomic-host Optimize bare metal systems running the Atomic variant balanced General non-specialized tuned profile cpu-partitioning Optimize for CPU partitioning default Legacy default tuned profile desktop Optimize for the desktop use-case desktop-powersave Optmize for the desktop use-case with power saving enterprise-storage Legacy profile for RHEL6, for RHEL7, please use throughput-performance profile hpc-compute Optimize for HPC compute workloads intel-sst Configure for Intel Speed Select Base Frequency laptop-ac-powersave Optimize for laptop with power savings laptop-battery-powersave Optimize laptop profile with more aggressive power saving latency-performance Optimize for deterministic performance at the cost of increased power consumption mssql Optimize for MS SQL Server network-latency Optimize for deterministic performance at the cost of increased power consumption, focused on low latency network performance network-throughput Optimize for streaming network throughput, generally only necessary on older CPUs or 40G+ networks optimize-serial-console Optimize for serial console use. oracle Optimize for Oracle RDBMS postgresql Optimize for PostgreSQL server powersave Optimize for low power consumption realtime Optimize for realtime workloads sap-hana Optimize for SAP HANA sap-netweaver Optimize for SAP NetWeaver server-powersave Optimize for server power savings spectrumscale-ece Optimized for Spectrum Scale Erasure Code Edition Servers spindown-disk Optimize for power saving by spinning-down rotational disks throughput-performance Broadly applicable tuning that provides excellent performance across a variety of common server workloads virtual-guest Optimize for running inside a virtual guest virtual-host Optimize for running KVM guests","s":"Tuned","u":"/docs/iaas/guides/configuration-guide/services/tuned","h":"","p":1225},{"i":1228,"t":"This section has moved. You can now find the content in the Other Guides as Cloud in a Box Guide.","s":"Cloud in a Box","u":"/docs/iaas/guides/deploy-guide/examples/cloud-in-a-box","h":"","p":1227},{"i":1230,"t":"This section has moved. You can now find the content in the Other Guides as Testbed Guide.","s":"Testbed","u":"/docs/iaas/guides/deploy-guide/examples/testbed","h":"","p":1229},{"i":1232,"t":"For the initial deployment of the management plane and the control plane of OSISM, the nodes must be pre-provisioned with Ubuntu 22.04. Currently, only Ubuntu 22.04 is supported by OSISM. Data plane nodes can be automatically provisioned after the initial deployment and do not need to be pre-provisioned. It is recommended not to install the initial nodes of the management plane and the control plane manually. An ISO image is provided for this purpose which automatically provisions a node. The ISO images are available for download in the osism/node-image repository. There are different variants of the ISO image. The variants differ in the disc layout. The available variants are described in the README file of the osism/node-image repository.","s":"Provisioning of bare-metal nodes","u":"/docs/iaas/guides/deploy-guide/provisioning","h":"","p":1231},{"i":1234,"t":"If none of the provided variants is suitable, this section describes the manual installation with the help of the Ubuntu 22.04 live ISO image. The manual installation is possible without network connectivity. Download the latest ISO image for Ubuntu 22.04 from releases.ubuntu.com. Use the ubuntu-22.04.1-live-server-amd64.iso image. The version number may be different, always use the latest available version of 22.04 LTS. Choose English as language. Choose Install Ubuntu Server. Choose English as language (again). Choose your location (e.g. Germany). Choose en_US.UTF-8 as locale. Choose the keyboard layout from a list, use English (US). Choose and configure the primary network interface. Depending on the environment, the network may not work at this point. Then select any interface and then select Do not configure the network at this time in the next step. Set the hostname. The hostname is e.g. node and not a FQDN like node.systems.osism.xyz. Set osism as full name for the new user. Set osism as the username for the account. The later used operator user dragon is created during the bootstrap and should not be created during the installation The account is only needed initially and can be deleted after completion of the bootstrap. Set a password for the account. Choose Manual as partitioning method and execute the partitioning according to company specifications The use of a UEFI is recommended The use of a RAID is recommended. We prefer the use of software RAIDs to make us less dependent on hardware. But there is nothing against using hardware RAIDs. The use of a LVM2 is recommended. system is recommended as the name for the volume group. Dedicated disks may be provided for /var/lib/docker on the controller nodes. In this case, do not use an LV for /var/lib/docker but the devices provided for it. Do not configure devices that are not required for the operating system. The use of own file systems for the following mountpoints is recommended. The size of the partitions/LVs is minimal. Depending on the node type, the partitions/LVs should be made larger. / (10 GByte, logical volume root) /home (2 GByte, logical volume home) /tmp (5 GByte, logical volume tmp) /var/lib/ceph (50 GByte, logical volume ceph) (optional for storage nodes) /var/lib/docker (30 GByte, logical volume docker, do not set the nosuid flag on /var/lib/docker) When using XFS as the file system for /var/lib/docker, note the following: Running on XFS without d_type support causes Docker to skip the attempt to use the overlay or overlay2 driver. 100 GB should be used on a control node at the beginning. /var/lib/docker must be extended later during operation depending on the node type. You do this in operation when you can see how many logs etc. are generated. /var/log/audit (1 GByte, logical volume audit) /var (10 GByte, logical volume var) swap (8 GByte, logical volume swap) Choose No automatic updates. Choose OpenSSH server as software to install. Do not install any other software component. Everything you need will be installed later by OSISM. In particular, it is not necessary to install a desktop environment. After completion, restart the system.","s":"Manual provisioning","u":"/docs/iaas/guides/deploy-guide/provisioning","h":"#manual-provisioning","p":1231},{"i":1236,"t":"info The prerequisite for the deployment of a cluster is a configuration repository. What a configuration repository is and how it is created is described in the Configuration Guide. The seed node is used once for the initial bootstrap of the manager node. The seed node can also be used to initially create and prepare the configuration repository. The seed node is not the manager node itself. It is sufficient to use the local workstation. It doesn't have to be a dedicated system. The seed node is no longer needed in the further process. The seed node must be able to reach the manager node via SSH. It is important for the further process that no packages are installed manually on the manager. Especially not Docker. The use of Linux on the seed node is recommended. Other operating systems should also work without problems. It is assumed in this documentation that Ubuntu 22.04 is used on the seed node.","s":"Seed","u":"/docs/iaas/guides/deploy-guide/seed","h":"","p":1235},{"i":1238,"t":"sudo apt-get install git python3-pip python3-virtualenv sshpass","s":"Install required packages","u":"/docs/iaas/guides/deploy-guide/seed","h":"#install-required-packages","p":1235},{"i":1240,"t":"Each environment managed with OSISM is based on a configuration repository. This was previously created with Cookiecutter and the osism/cfg-cookiecutter repository. The creation of the configuration repository is covered in chapter Creation of a configuration repository of the Configuration Guide. A configuration repository is stored on a Git server (e.g. GitHub, Gitlab, ...). The configuration repository is individual for each environment and is therefore not provided by us. The configuration repository to be used must be available on the seed node. In the following example, replace YOUR_ORG and YOUR_NEW_CONFIGURATION_REPOSITORY accordingly. git clone ssh://git@github.com:YOUR_ORG/YOUR_NEW_CONFIGURATION_REPOSITORY.git Examples: The repository is located in the regiocloud organisation on GitHub, has the name configuration and can be accessed via SSH: ssh://git@github.com:regiocloud/configuration.git The repository is located in the regiocloud organisation on Gitlab, has the name configuration and can be accessed via SSH: ssh://git@gitlab.com:regiocloud/configuration.git The repository is located in the regiocloud organisation on an internal Gitlab, has the name configuration and can be accessed via SSH: ssh://git@git.services.osism.tech:regiocloud/configuration.git If necessary, the configuration SSH key can be used for the initial transfer of the repository. For this, the following content is added in ~/.ssh/config and the SSH privte key is stored in ~/.ssh/id_rsa.configuration. Host github.com HostName github.com User git Port 22 IdentityFile ~/.ssh/id_rsa.configuration","s":"Get a copy of the configuration repository","u":"/docs/iaas/guides/deploy-guide/seed","h":"#get-a-copy-of-the-configuration-repository","p":1235},{"i":1242,"t":"Common issues with deploying infrastructure services required by OpenStack are documented in the OpenStack Troubleshooting Guide. Cron, Fluentd & Kolla Toolbox The common role of Kolla is used to manage the services cron, fluentd and kolla-toolbox. It is important to do this deployment before any other deployements in the Kolla environment, as parts of the other deployments depend on the kolla-toolbox service. osism apply -a pull common osism apply common Loadbalancer osism apply -a pull loadbalancer osism apply loadbalancer Redis osism apply -a pull redis osism apply redis Memcached osism apply -a pull memcached osism apply memcached RabbitMQ osism apply -a pull rabbitmq osism apply rabbitmq MariaDB osism apply -a pull mariadb osism apply mariadb","s":"Infrastructure","u":"/docs/iaas/guides/deploy-guide/services/infrastructure","h":"","p":1241},{"i":1244,"t":"info The prerequisite for depoying the services of a cluster is the bootstrap of the nodes. How to bootstrap the nodes is documented in the Bootstrap chapter of the Deploy Guide. When setting up a new cluster, the services are deployed in a specific order. Infrastructure Network Logging & Monitoring Ceph OpenStack","s":"Services","u":"/docs/iaas/guides/deploy-guide/services/","h":"","p":1243},{"i":1246,"t":"info As of OSISM 7, it is possible to create a Kubernetes cluster on all nodes. At the moment, this is still optional. In the future, it will be necessary to deploy this Kubernetes cluster. Deploy the K3s cluster. osism apply kubernetes Deploy the Kubernetes dashboard: osism apply kubernetes-dashboard","s":"Kubernetes","u":"/docs/iaas/guides/deploy-guide/services/kubernetes","h":"","p":1245},{"i":1248,"t":"Deploy the Cluster API management cluster on the K3s cluster: osism apply clusterapi Add the kubeconfig file to the configuration repository (required later by OpenStack Magnum Service): osism apply copy-kubeconfig","s":"Cluster API","u":"/docs/iaas/guides/deploy-guide/services/kubernetes","h":"#cluster-api","p":1245},{"i":1250,"t":"Common issues with deploying logging & monitoring services provided by Kolla are documented in the OpenStack Troubleshooting Guide. OpenSearch OpenSearch dashboards is also deployed with the opensearch role. osism apply -a pull opensearch osism apply opensearch Prometheus osism apply -a pull prometheus osism apply prometheus Grafana osism apply -a pull grafana osism apply grafana","s":"Logging & Monitoring","u":"/docs/iaas/guides/deploy-guide/services/logging-monitoring","h":"","p":1249},{"i":1252,"t":"info The prerequisite for deploying the Manager node is a Seed node. What a Seed node is and how to prepare it is documented in the Seed chapter of the Deploy Guide. The Manager node serves as the central administration instance for managing the cloud environment. With the help of Ansible and other OSISM-specific components, the entire life cycle of the system is coordinated from here (installation, customization, upgrades, etc.). Requirements for the manager node: The system should have the following hardware features at least 64 GB RAM (We assume here that the monitoring services are also run on the manager. If the manager node is only used for the sanager Service, 32 GByte is sufficient and with 16 GByte it will probably also work. at least 256 GB hard disk space the system should be initially and permanently accessible independently of the cloud environment itself from the seed node the system should have direct access to the network areas of the individual server systems in the cloud environment An Ubuntu version matching the OSISM version should be provisioned on the system (typically the latest Ubuntu LTS version, a system based on one of the OSISM node images would be ideal) No manual adjustments or installations should have been made on the system apart from the basic installation The system has to be accessible from the seed node via SSH","s":"Manager","u":"/docs/iaas/guides/deploy-guide/manager","h":"","p":1251},{"i":1254,"t":"Change into the environments/manager directory of the configuration repository on the seed node. The deployment of the seed node itself is documented in the Deploy Guide for the seed node. cd environments/manager","s":"Deploy the manager service","u":"/docs/iaas/guides/deploy-guide/manager","h":"#deploy-the-manager-service","p":1251},{"i":1256,"t":"The operator user is created on each node. It is used as a service account for OSISM. All containers run with this user. Ansible also uses this user to access the nodes. Commands on the manager node need to be run as this user. The name of the operator user is always dragon. With ANSIBLE_USER the existing user account is set after the provsioning of the management node. When using the osism/node-image the user is osism and the password of this user is password. If you install Ubuntu manually the user usually is ubuntu. If you want to use any other user here, that's no problem. It is important that this user has sudo rights. The password according to what you have set yourself. The ANSIBLE_USER parameter is only required when executing operator play using the run.sh script. After this step, the ANSIBLE_USER is always set to dragon in the run.sh script. It is therefore important to only set this parameter for exactly this step. ANSIBLE_BECOME_ASK_PASS=True \\ ANSIBLE_ASK_VAULT_PASS=True \\ ANSIBLE_ASK_PASS=True \\ ANSIBLE_USER=osism \\ ./run.sh operator When the ./run.sh operator is executed, the following prompts are displayed. Prompt Value Comment SSH password: Password so that the ANSIBLE_USER can login Enabled by ANSIBLE_ASK_PASS BECOME password[defaults to SSH password]: Password so that the ANSIBLE_USER can use sudo Enabled by ANSIBLE_BECOME_ASK_PASS Vault password: Value of secrets/vaultpass Enabled by ANSIBLE_ASK_VAULT_PASS If a password is required to login to the manager node, ANSIBLE_ASK_PASS=True must be set. If an SSH key is required to login to the manager node, the key has to be added on the manager node to ~/.ssh/authorized_keys in the home directory of the user specified as ANSIBLE_USER first. If the error ERROR! Attempting to decrypt but no vault secrets found occurs, ANSIBLE_ASK_VAULT_PASS=True has to be set. If the error /bin/sh: 1: /usr/bin/python: not found occurs, Python has to be installed first on the manager node: ANSIBLE_USER=osism ./run.sh python3 If you receive the following error message ssh: Too many authentication failures set ANSIBLE_SSH_ARGS environment variable to use only the operator ssh key for authentication. export ANSIBLE_SSH_ARGS=\"-o IdentitiesOnly=yes\" The warning message [WARNING]: running playbook inside collection osism.manager can be ignored If Ansible Vault is used, let Ansible ask for the Vault password: export ANSIBLE_ASK_VAULT_PASS=True Details on all parameters can be found in Ansible Configuration Settings in the Ansible documentation. Environment variable Type Description ANSIBLE_ASK_PASS Boolean This controls whether an Ansible playbook should prompt for a login password. If using SSH keys for authentication, you probably do not need to change this setting. ANSIBLE_ASK_VAULT_PASS Boolean This controls whether an Ansible playbook should prompt for a vault password. ANSIBLE_BECOME_ASK_PASS Boolean Toggle to prompt for privilege escalation password. ANSIBLE_SSH_ARGS String If set, this will override the Ansible default ssh arguments. ANSIBLE_USER String The user Ansible ‘logs in’ as. To verify the creation of the operator user, use the private key file id_rsa.operator. Make sure you purge all keys from ssh-agent identity cache using ssh-add -D. You can print the list using ssh-add -l. The list should be empty. ssh-add -D ssh -o IdentitiesOnly=yes -i id_rsa.operator dragon@testbed-manager","s":"Step 1: Create operator user","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-1-create-operator-user","p":1251},{"i":1258,"t":"Most of the parameters required for Ansible (ANSIBLE_BECOME_ASK_PASS, ANSIBLE_ASK_PASS, ANSIBLE_USER, ...) in the previous step are no longer necessary. If Ansible Vault is used, however, ANSIBLE_ASK_VAULT_PASS must still be set. export ANSIBLE_ASK_VAULT_PASS=True To prevent recurring installation of Ansible Collections, export INSTALL_ANSIBLE_ROLES=False can be set. The network configuration, already present on a node should be backuped before this step. Then you can deploy the network configuration with the network role. ./run.sh network Upon completion of the network configurtion, a node reboot should be performed to ensure the configuration is functional and reboot safe. Since network services are not restarted automatically, later changes to the network configuration are not effective without a manual apply of the network configuration or reboot of the nodes.","s":"Step 2: Apply the network configuration","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-2-apply-the-network-configuration","p":1251},{"i":1260,"t":"Most of the parameters required for Ansible (ANSIBLE_BECOME_ASK_PASS, ANSIBLE_ASK_PASS, ANSIBLE_USER, ...) in the previous step are no longer necessary. If Ansible Vault is used, however, export ANSIBLE_ASK_VAULT_PASS=True must still be set. To prevent recurring installation of Ansible Collections, export INSTALL_ANSIBLE_ROLES=False can be set. This is recommended. Bootstrap the manager node. ./run.sh bootstrap Reboot the manager node. ./run.sh reboot","s":"Step 3: Bootstrap the manager node","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-3-bootstrap-the-manager-node","p":1251},{"i":1262,"t":"Transfer the configuration repository. ./run.sh configuration Deploy the Traefik service. This is optional and only necessary if the Traefik service is to be used. ./run.sh traefik Deploy the Netbox service. This is optional and only necessary if the Netbox service is to be used. ./run.sh netbox Deploy the manager service. ./run.sh manager","s":"Step 4: Deploy the manager service","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-4-deploy-the-manager-service","p":1251},{"i":1264,"t":"Finally, the Ansible Vault password is made known on the manager node. Before that, log in to the manager node with the dragon user. osism set vault password Ansible Vault password: ******** Ready. The manager is now prepared and you can continue with the bootstrap of the other nodes. The seed node used until here is no longer necessary.","s":"Step 5: Set vault password on the manager service","u":"/docs/iaas/guides/deploy-guide/manager","h":"#step-5-set-vault-password-on-the-manager-service","p":1251},{"i":1267,"t":"A node can be in different states. Depending on the state, different actions are possible or are triggered. The individual states of a node can be retrieved via Ansible Facts and local files on the node itself.","s":"Change Node states","u":"/docs/iaas/guides/operations-guide/","h":"#change-node-states","p":1265},{"i":1269,"t":"osism set maintenance NODE osism noset maintenance NODE Ansible fact: ansible_local.osism.maintenance State file: /etc/osism/maintenance","s":"Maintenance","u":"/docs/iaas/guides/operations-guide/","h":"#maintenance","p":1265},{"i":1271,"t":"osism set bootstrap NODE osism noset bootstrap NODE Ansible fact: ansible_local.osism.bootstrap State file: /etc/osism/bootstrap","s":"Bootstrap","u":"/docs/iaas/guides/operations-guide/","h":"#bootstrap","p":1265},{"i":1273,"t":"Custom Plays can be used in all environments in the configuration repository. For example, this is a play to prepare all devices to be used for Ceph on a Ceph resource node. It is saved in the configuration repository in the file environments/ceph/playbook-wipe-partitions.yml. It is run with osism apply -e ceph wipe-parititons. --- - name: Wipe partitions hosts: ceph-resource gather_facts: false tasks: - name: Wipe partitions become: true ansible.builtin.shell: | wipefs --all \"{{ item }}\" dd if=/dev/zero of=\"{{ item }}\" bs=1 count=4096 changed_when: false with_items: \"{{ devices }}\"","s":"Use of custom plays","u":"/docs/iaas/guides/operations-guide/","h":"#use-of-custom-plays","p":1265},{"i":1275,"t":"osism apply manage-service \\ -e service_name=rsysloc \\ -e service_state=restarted","s":"Manage services","u":"/docs/iaas/guides/operations-guide/","h":"#manage-services","p":1265},{"i":1277,"t":"osism apply manage-container \\ -e container_name=nova_compute \\ -e container_action=restart","s":"Manage containers","u":"/docs/iaas/guides/operations-guide/","h":"#manage-containers","p":1265},{"i":1279,"t":"When using reboot play, the node is rebooted directly. It is not ensured in advance that there is no more payload on the node and no services etc. are disabled. Reboot node testbed-node-0.testbed.osism.xyz and wait until the reboot has been completed and the system is accessible again. osism apply reboot \\ -e reboot_wait=True \\ -e ireallymeanit=yes \\ -l testbed-node-0.testbed.osism.xyz Reboot node testbed-node-0.testbed.osism.xyz and do not wait for the reboot to complete. osism apply reboot \\ -e ireallymeanit=yes \\ -l testbed-node-0.testbed.osism.xyz","s":"Reboot nodes","u":"/docs/iaas/guides/operations-guide/","h":"#reboot-nodes","p":1265},{"i":1282,"t":"$ sudo ipmitool lan print | grep 'IP Address' IP Address Source : DHCP Address IP Address : 10.10.0.100","s":"Display the IP address","u":"/docs/iaas/guides/operations-guide/","h":"#display-the-ip-address","p":1265},{"i":1284,"t":"Open vSwitch (OVS) osism apply -a pull openvswitch osism apply openvswitch Open Virtual Network (OVN) In environments/kolla/configuration.yml the parameter neutron_plugin_agent is set to ovn if OVN is used as a network plugin. The parameter is set to ovn by default in the Cookiecutter. environments/kolla/configuration.yml # neutron neutron_plugin_agent: \"ovn\" Otherwise the network plugin is set to openvswitch. If the neutron_plugin_agent is set to openvswitch, this step does not need to be done. Before the deployment of OVN, the deployment of Open vSwitch must already have been done. osism apply -a pull ovn osism apply ovn","s":"Network","u":"/docs/iaas/guides/deploy-guide/services/network","h":"","p":1283},{"i":1286,"t":"In OSISM it is also possible to integrate and use existing Ceph clusters. It is not necessary to deploy Ceph with OSISM. If Ceph is deployed with OSISM, it should be noted that OSISM does not claim to provide all possible features of Ceph. Ceph provided with OSISM is intended to provide the storage for Glance, Nova, Cinder and Manila. In a specific way that has been implemented by OSISM for years. It should be checked in advance whether the way in OSISM the Ceph deployment and the provided features are sufficient. If this is not the case, it is recommended to deploy Ceph in a different way directly and independently of OSISM. For possible open source projects, please refer to cephadm and Rook. warning Before starting the Ceph deployment, the configuration and creation of the necessary LVM2 volumes must be completed. The steps that are required for this can be found in the Ceph Configuration Guide. Deploy services. Deploy ceph-mon services osism apply ceph-mons Deploy ceph-mgr services osism apply ceph-mgrs Deploy ceph-osd services osism apply ceph-osds Generate pools and keys. This step is only necessary for OSISM >= 7.0.0. osism apply ceph-pools Deploy ceph-crash services osism apply ceph-crash info It's all done step by step here. It is also possible to do this in a single step. This speeds up the entire process and avoids unnecessary restarts of individual services. OSISM >= 7.0.0 OSISM < 7.0.0 osism apply ceph Generate pools and keys. osism apply ceph-pools osism apply ceph-base Get ceph keys. This places the necessary keys in /opt/configuration. osism apply copy-ceph-keys After run, these keys must be permanently added to the configuration repository via Git. environments/infrastructure/files/ceph/ceph.client.admin.keyring environments/kolla/files/overlays/gnocchi/ceph.client.gnocchi.keyring environments/kolla/files/overlays/nova/ceph.client.cinder.keyring environments/kolla/files/overlays/nova/ceph.client.nova.keyring environments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder.keyring environments/kolla/files/overlays/cinder/cinder-backup/ceph.client.cinder-backup.keyring environments/kolla/files/overlays/cinder/cinder-volume/ceph.client.cinder.keyring environments/kolla/files/overlays/manila/ceph.client.manila.keyring environments/kolla/files/overlays/glance/ceph.client.glance.keyring If the osism apply copy-ceph-keys fails because the keys are not found in the /share directory, this can be ignored. The keys of the predefined keys (e.g. for Manila) were then not created as they are not used. If you only use Ceph and do not need the predefined keys for OpenStack at all, you can also overwrite the ceph_kolla_keys parameter to skip these keys. environments/ceph/configuration.yml ceph_kolla_keys: [] After the Ceph keys have been persisted in the configuration repository, the Ceph client can be deployed. osism apply cephclient Enable and prepare the use of the Ceph dashboard. osism apply ceph-bootstrap-dashboard","s":"Ceph","u":"/docs/iaas/guides/deploy-guide/services/ceph","h":"","p":1285},{"i":1288,"t":"Deployment of the Ceph RGW Service is optional. How the Ceph RGW service can be deployed and integrated into OpenStack is described here. info If an initial deployment is performed and Ceph RGW is not added to an existing deployment, steps 4 and 5 are not required. Step 3 is then performed later after the OpenStack Keystone service has been deployed. Configure the RGW service Apply role ceph-rgws to deploy the Ceph RGW services. osism apply ceph-rgws Apply role kolla-ceph-rgw to add the OpenStack endpoint. If an initial deployment is performed and Ceph RGW is not added to an existing deployment run this step later after the OpenStack Keystone service has been deployed. osism apply kolla-ceph-rgw Apply role loadbalancer to add the HAProxy backend and frontend. osism apply loadbalancer Apply role horizon to enable the Swift dashboard. osism apply horizon","s":"RGW service","u":"/docs/iaas/guides/deploy-guide/services/ceph","h":"#rgw-service","p":1285},{"i":1290,"t":"info Usable from OSISM 7.0.3 onwards. If Ceph services are deployed sequentially, this can lead to unwanted service restarts. This can also happen if, for example, new OSDs are added later or a new control node is added. The Ceph RGW services are deployed here without restarting the Ceph OSD services. osism apply ceph-rgws -e ceph_handler_osds_restart=False The following parameters are available. Any number of parameters can be used with a single command. ceph_handler_crash_restart ceph_handler_mdss_restart ceph_handler_mgrs_restart ceph_handler_mons_restart ceph_handler_osds_restart ceph_handler_rbdmirrors_restart ceph_handler_rgws_restart","s":"Avoiding service restarts","u":"/docs/iaas/guides/deploy-guide/services/ceph","h":"#avoiding-service-restarts","p":1285},{"i":1292,"t":"info Usable from OSISM 7.0.3 onwards. Sometimes service restarts are required. For example, if the configuration has changed or if new OSDs have been added. It may be necessary and useful to only restart the services on a specific number of nodes at a specific time. Further information on throttling can be found in the Ansible documentation. The Ceph OSD services are deployed here. If there is a restart required of other OSDs that are already running, these restarts are executed on a maximum of 2 nodes at the same time. The OSD services themselves on a node are always restarted one after the other and never all at the same time. osism apply ceph-osds -e ceph_handler_osds_restart_throttle=2 If the nodes are to be processed one after the other, ceph_handler_osds_restart_throttle=1 can be used. The following parameters are available. Any number of parameters can be used with a single command. ceph_handler_crash_restart_throttle ceph_handler_mdss_restart_throttle ceph_handler_mgrs_restart_throttle ceph_handler_mons_restart_throttle ceph_handler_osds_restart_throttle ceph_handler_rbdmirrors_restart_throttle ceph_handler_rgws_restart_throttle","s":"Throttling service restarts","u":"/docs/iaas/guides/deploy-guide/services/ceph","h":"#throttling-service-restarts","p":1285},{"i":1294,"t":"Common issues with deploying OpenStack services are documented in the OpenStack Troubleshooting Guide. info An OpenStack deployment contains a number of components providing APIs to access infrastructure resources. The OpenStack Components page lists the various services that can be deployed to provide such resources to cloud end users. Unfortunately, not all of the OpenStack projects listed there are still active. Not all of the services listed there are supported by OSISM. OpenStack client osism apply openstackclient Keystone osism apply -a pull keystone osism apply keystone Glance osism apply -a pull glance osism apply glance Designate osism apply -a pull designate osism apply designate Placement osism apply -a pull placement osism apply placement Cinder osism apply -a pull cinder osism apply cinder Neutron osism apply -a pull neutron osism apply neutron Nova osism apply -a pull nova osism apply nova Octavia osism apply -a pull octavia osism apply octavia 9.1. Manage amphora image This step is only necessary if the Amphora Driver is used. If OVN is used as the driver, this step is not necessary. We provide regularly updated images for Octavia in osism/openstack-octavia/amphora-image. The OSISM CLI can be used to upload the correct image depending on the OpenStack release used. osism manage image octavia Horizon osism apply -a pull horizon osism apply horizon","s":"OpenStack","u":"/docs/iaas/guides/deploy-guide/services/openstack","h":"","p":1293},{"i":1298,"t":"Mariabackup is used to create backups of MariaDB. Full backup osism apply mariadb_backup Incremental backup (supported as of OSISM 7.0.6) osism apply mariadb_backup -e mariadb_backup_type=incremental There is a Docker volume mariadb_backup on the 1st control node. The backups are stored in this volume. $ docker run --rm -v mariadb_backup:/backup -it ubuntu:22.04 bash -c 'ls -la /backup' total 9728 drwxr-xr-x 2 42434 42434 4096 Jun 3 18:46 . drwxr-xr-x 1 root root 4096 Jun 3 18:47 .. -rw-r--r-- 1 42434 42434 4530618 Jun 3 18:46 incremental-18-mysqlbackup-03-06-2024-1717440409.qp.xbc.xbs.gz -rw-r--r-- 1 42434 42434 11 Jun 3 18:45 last_full_date -rw-r--r-- 1 42434 42434 5411763 Jun 3 18:45 mysqlbackup-03-06-2024-1717440342.qp.xbc.xbs.gz","s":"Backup","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#backup","p":1295},{"i":1300,"t":"https://docs.openstack.org/kolla-ansible/latest/admin/mariadb-backup-and-restore.html#restoring-backups","s":"Restore","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#restore","p":1295},{"i":1302,"t":"osism apply mariadb_recovery","s":"Recovery","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#recovery","p":1295},{"i":1305,"t":"$ curl https://api-int.testbed.osism.xyz:9200/_cat/indices?v health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open flog-2024.04.17 1rCP3NpUQSS5wmulCn6Y5g 1 1 1657832 0 1gb 654.4mb green open .opensearch-observability UnS2gFb-QhC8oIefL3C52Q 1 2 0 0 624b 208b green open .plugins-ml-config hMdzW6ooRMGZ_0OGcdNSgA 1 1 1 0 7.8kb 3.9kb green open .opendistro-job-scheduler-lock fa_Io8bJQ8qfGII4DypxFg 1 1 1 3 51.1kb 35.1kb green open .kibana_1 v-aJ6ioSQsOwHQn_NNbeOg 1 1 0 0 416b 208b","s":"Get all indices","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#get-all-indices","p":1295},{"i":1307,"t":"$ curl -X DELETE https://api-int.testbed.osism.xyz:9200/flog-2024.04.17 {\"acknowledged\":true}","s":"Delete an index","u":"/docs/iaas/guides/operations-guide/infrastructure","h":"#delete-an-index","p":1295},{"i":1311,"t":"$ osism apply 2023-09-30 10:09:25 | INFO | No role given for execution. The roles listed in the table can be used. +------------------------------------------------------------------+----------------+ | Role | Environment | |------------------------------------------------------------------+----------------| | aodh | kolla | | barbican | kolla | | bifrost | kolla | | bifrost-keypair | kolla | | ceilometer | kolla | | certificates | generic | | cinder | kolla | | cloudkitty | kolla | | collectd | kolla | | common | kolla | | designate | kolla | | elasticsearch | kolla | | etcd | kolla | | glance | kolla | | gnocchi | kolla | | grafana | kolla | | heat | kolla | | horizon | kolla | | ironic | kolla | | iscsi | kolla | ...","s":"List all available plays","u":"/docs/iaas/guides/operations-guide/manager/apply","h":"#list-all-available-plays","p":1309},{"i":1315,"t":"Each Ansible service has its own local Ansible log file. These log files are not persistent. The ARA service is used for the persistence of Ansible logs. The log files can be used to view currently running Ansible Plays, for example if they are running as a background task. $ docker exec -it osism-ansible tail -f /ansible/logs/ansible.log $ docker exec -it ceph-ansible tail -f /ansible/logs/ansible.log $ docker exec -it kolla-ansible tail -f /ansible/logs/ansible.log","s":"Files","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#files","p":1312},{"i":1317,"t":"$ osism log ansible (ara) help Documented commands (use 'help -v' for verbose/'help ' for details): =========================================================================== alias exit history quit run_script shell edit help macro run_pyscript set shortcuts Application commands (type help ): ========================================= complete host metrics playbook delete record delete result show expire host show playbook list record list task delete help play delete playbook metrics record show task list host delete play list playbook prune result delete task metrics host list play show playbook show result list task show Sample usage​ As an example, the role common is run. Irrelevant parts of outputs have been removed. $ osism apply common $ osism log ansible (ara) play list +----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+ | id | status | name | playbook | tasks | results | started | duration | +----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+ | 69 | completed | Apply role common | 49 | 21 | 68 | 2023-09-30T10:14:01.731212Z | 00:00:38.238032 | +----+-----------+-------------------------------------------------------+----------+-------+---------+-----------------------------+-----------------+ (ara) play show 69 +----------+------------------------------------------+ | Field | Value | +----------+------------------------------------------+ | id | 69 | | report | http://ara-server:8000/playbooks/49.html | | status | completed | | name | Apply role common | | playbook | (49) /ansible/kolla-common.yml | | started | 2023-09-30T10:14:01.731212Z | | ended | 2023-09-30T10:14:39.969244Z | | duration | 00:00:38.238032 | | items | {'tasks': 21, 'results': 68} | +----------+------------------------------------------+ (ara) task list +-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+ | id | status | results | action | name | playbook | started | duration | +-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+ | 910 | completed | 0 | meta | common : Flush handlers | 49 | 2023-09-30T10:14:37.126872Z | 00:00:02.552006 | | 909 | completed | 4 | file | common : Link kolla_logs volume to /var/log/kolla | 49 | 2023-09-30T10:14:35.502754Z | 00:00:01.039468 | | 908 | completed | 4 | kolla_docker | common : Creating log volume | 49 | 2023-09-30T10:14:34.134312Z | 00:00:01.076976 | | 907 | completed | 4 | kolla_docker | common : Check common containers | 49 | 2023-09-30T10:14:31.411916Z | 00:00:02.146165 | | 906 | completed | 4 | template | common : Copy rabbitmq erl_inetrc to kolla toolbox | 49 | 2023-09-30T10:14:29.500998Z | 00:00:01.327607 | | 905 | completed | 4 | template | common : Copy rabbitmq-env.conf to kolla toolbox | 49 | 2023-09-30T10:14:27.979869Z | 00:00:01.231630 | | 904 | completed | 4 | file | common : Ensuring config directories have correct owner and permission | 49 | 2023-09-30T10:14:26.422535Z | 00:00:01.263370 | | 903 | completed | 4 | template | common : Ensure RabbitMQ Erlang cookie exists | 49 | 2023-09-30T10:14:24.880329Z | 00:00:01.255475 | | 902 | completed | 4 | template | common : Copying over cron logrotate config file | 49 | 2023-09-30T10:14:23.199518Z | 00:00:01.392765 | | 901 | completed | 4 | template | common : Copying over td-agent.conf | 49 | 2023-09-30T10:14:21.085351Z | 00:00:01.826039 | | 900 | completed | 1 | find | common : Find custom fluentd output config files | 49 | 2023-09-30T10:14:19.859670Z | 00:00:00.939663 | | 899 | completed | 1 | find | common : Find custom fluentd format config files | 49 | 2023-09-30T10:14:18.711171Z | 00:00:00.858586 | | 898 | completed | 1 | find | common : Find custom fluentd filter config files | 49 | 2023-09-30T10:14:17.542234Z | 00:00:00.877270 | | 897 | completed | 1 | find | common : Find custom fluentd input config files | 49 | 2023-09-30T10:14:15.911699Z | 00:00:01.315217 | | 896 | completed | 4 | template | common : Copying over config.json files for services | 49 | 2023-09-30T10:14:13.588195Z | 00:00:02.031647 | | 895 | completed | 4 | copy | service-cert-copy : common | Copying over backend internal TLS key | 49 | 2023-09-30T10:14:12.216984Z | 00:00:01.074853 | | 894 | completed | 4 | copy | service-cert-copy : common | Copying over backend internal TLS certificate | 49 | 2023-09-30T10:14:10.895833Z | 00:00:01.022530 | | 893 | completed | 4 | copy | service-cert-copy : common | Copying over extra CA certificates | 49 | 2023-09-30T10:14:08.551850Z | 00:00:02.040932 | | 892 | completed | 4 | include_tasks | common : include_tasks | 49 | 2023-09-30T10:14:07.019883Z | 00:00:00.950605 | | 891 | completed | 4 | file | common : Ensuring config directories exist | 49 | 2023-09-30T10:14:04.801633Z | 00:00:01.926842 | | 890 | completed | 4 | include_tasks | common : include_tasks | 49 | 2023-09-30T10:14:03.054547Z | 00:00:01.166032 | +-----+-----------+---------+---------------------------------+----------------------------------------------------------------------------+----------+-----------------------------+-----------------+ (ara) task show 910 +----------+------------------------------------------+ | Field | Value | +----------+------------------------------------------+ | id | 910 | | uuid | 0242ac1f-6510-3867-9eea-00000000004f | | report | http://ara-server:8000/playbooks/49.html | | name | common : Flush handlers | | action | meta | | status | completed | | path | /ansible/roles/common/tasks/deploy.yml | | lineno | 8 | | started | 2023-09-30T10:14:37.126872Z | | ended | 2023-09-30T10:14:39.678878Z | | duration | 00:00:02.552006 | | tags | ['common'] | | handler | False | +----------+------------------------------------------+ (ara) playbook list +----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+ | id | status | controller | user | ansible_version | path | tasks | results | hosts | started | duration | +----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+ | 49 | completed | kolla-ansible.manager_default | dragon | 2.14.10 | /ansible/kolla-common.yml | 21 | 68 | 5 | 2023-09-30T10:14:01.410334Z | 00:00:39.135309 | +----+-----------+-------------------------------+--------+-----------------+---------------------------------------------------+-------+---------+-------+-----------------------------+-----------------+ (ara) playbook metrics +---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+ | aggregate | count | duration_total | duration_avg | tasks | results | hosts | completed | failed | running | +---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+ | /ansible/kolla-common.yml | 2 | 0:02:53.934432 | 0:01:26.967216 | 46 | 152 | 10 | 2 | 0 | 0 | +---------------------------------------------------+-------+----------------+----------------+-------+---------+-------+-----------+--------+---------+ (ara) host list +-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+ | id | name | playbook | changed | failed | ok | skipped | unreachable | updated | +-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+ | 164 | testbed-node-2.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.543599Z | | 161 | testbed-manager.testbed.osism.xyz | 49 | 0 | 0 | 18 | 2 | 0 | 2023-09-30T10:14:40.283581Z | | 163 | testbed-node-1.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.280601Z | | 162 | testbed-node-0.testbed.osism.xyz | 49 | 0 | 0 | 14 | 2 | 0 | 2023-09-30T10:14:40.279181Z | | 165 | kolla-ansible.manager_default | 49 | 0 | 0 | 0 | 0 | 0 | 2023-09-30T10:14:16.932135Z | +-----+-----------------------------------+----------+---------+--------+----+---------+-------------+-----------------------------+ (ara) host show 164 +-------------+------------------------------------------+ | Field | Value | +-------------+------------------------------------------+ | id | 164 | | report | http://ara-server:8000/playbooks/49.html | | name | testbed-node-2.testbed.osism.xyz | | changed | 0 | | failed | 0 | | ok | 14 | | skipped | 2 | | unreachable | 0 | | updated | 2023-09-30T10:14:40.543599Z | +-------------+------------------------------------------+","s":"ARA - ARA Records Ansible","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#ara---ara-records-ansible","p":1312},{"i":1319,"t":"$ osism log container testbed-node-0 horizon [...] ++++ APACHE_LOCK_DIR=/var/lock/apache2 ++++ export APACHE_LOG_DIR=/var/log/apache2 ++++ APACHE_LOG_DIR=/var/log/apache2 ++++ export LANG=C ++++ LANG=C ++++ export LANG +++ install -d /var/run/apache2/ +++ rm -rf '/var/run/apache2/*' +++ [[ ubuntu =~ centos|rocky ]] + echo 'Running command: '\\''/usr/sbin/apache2 -DFOREGROUND'\\''' + exec /usr/sbin/apache2 -DFOREGROUND AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.16.10. Set the 'ServerName' directive globally to suppress this message","s":"Container","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#container","p":1312},{"i":1321,"t":"OpenSearch can be queried with SQL. $ osism log opensearch >>> SELECT * FROM flog-2023.10.31 LIMIT 1; Oct 31 10:45:36 testbed-node-0 docker[847573]: cluster 2023-10-31T10:45:35.498718+0000 mgr.testbed-node-0 (mgr.5184) 24194 : cluster [DBG] pgmap v24196: 321 pgs: 321 active+clean; 577 KiB data, 270 MiB used, 60 GiB / 60 GiB avail >>> SELECT * FROM flog-2023.10.31 LIMIT 5; Oct 31 11:19:57 testbed-node-2 docker[880827]: 2023-10-31T11:19:57.650+0000 7fa7e7c88700 0 [dashboard INFO root] Redirecting to active 'http://192.168.16.10:7000/' Oct 31 11:19:57 testbed-node-2 docker[880827]: 2023-10-31T11:19:57.650+0000 7fa7e7c88700 0 [dashboard INFO request] [::ffff:192.168.16.11:56210] [OPTIONS] [302] [0.001s] [105.0B] [8a69cc7a-23db-410b-b744-cc5689cb4f4c] / Oct 31 11:19:58 testbed-node-2 docker[844686]: cluster 2023-10-31T11:19:56.329684+0000 mgr.testbed-node-0 (mgr.5184) 25224 : cluster [DBG] pgmap v25226: 321 pgs: 321 active+clean; 577 KiB data, 270 MiB used, 60 GiB / 60 GiB avail Oct 31 11:19:58 testbed-node-2 docker[844686]: debug 2023-10-31T11:19:58.566+0000 7fdbc9728700 1 mon.testbed-node-2@2(peon).osd e74 _set_new_cache_sizes cache_size:1020054731 inc_alloc: 348127232 full_alloc: 348127232 kv_alloc: 322961408 Oct 31 11:19:58 testbed-node-2 docker[880827]: 2023-10-31T11:19:58.710+0000 7fa7eb48f700 0 [dashboard INFO root] Redirecting to active 'http://192.168.16.10:7000/' >>> SELECT * FROM flog-2023.10.31 WHERE Hostname = 'testbed-node-0' LIMIT 5 PATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29 REQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27 SCRIPT_NAME: `` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:28 192.168.16.10 - - [31/Oct/2023 10:57:33] \"GET / HTTP/1.1\" 300 1761 0.001253 (1039) accepted ('192.168.16.10', 58732) server /var/lib/kolla/venv/lib/python3.10/site-packages/eventlet/wsgi.py:1004 >>> SELECT * FROM flog-2023.10.31 WHERE Hostname = 'testbed-node-0' AND programname = 'keystone' LIMIT 5 PATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29 REQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27 SCRIPT_NAME: `` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:28 PATH_INFO: `/` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:29 REQUEST_METHOD: `GET` log_request_info /var/lib/kolla/venv/lib/python3.10/site-packages/keystone/server/flask/request_processing/req_logging.py:27","s":"OpenSearch","u":"/docs/iaas/guides/operations-guide/manager/log","h":"#opensearch","p":1312},{"i":1323,"t":"A get command is available in the OSISM CLI. This allows to gather specific information.","s":"Get","u":"/docs/iaas/guides/operations-guide/manager/get","h":"","p":1322},{"i":1325,"t":"Get all hosts defined in the inventory $ osism get hosts +-----------------------------------+ | Host | |-----------------------------------| | testbed-manager.testbed.osism.xyz | | testbed-node-0.testbed.osism.xyz | | testbed-node-1.testbed.osism.xyz | | testbed-node-2.testbed.osism.xyz | +-----------------------------------+ Get all hosts defined in the inventory that are member of a specific inventory group $ osism get hosts -l manager +-----------------------------------+ | Host | |-----------------------------------| | testbed-manager.testbed.osism.xyz | +-----------------------------------+ $ osism get hosts -l control +----------------------------------+ | Host | |----------------------------------| | testbed-node-0.testbed.osism.xyz | | testbed-node-1.testbed.osism.xyz | | testbed-node-2.testbed.osism.xyz | +----------------------------------+","s":"Hosts","u":"/docs/iaas/guides/operations-guide/manager/get","h":"#hosts","p":1322},{"i":1327,"t":"Get all host vars of a specific node osism get hostvars testbed-manager.testbed.osism.xyz Get a specific host var of a specific node $ osism get hostvars testbed-manager.testbed.osism.xyz ansible_host +-----------------------------------+--------------+----------------+ | Host | Variable | Value | +===================================+==============+================+ | testbed-manager.testbed.osism.xyz | ansible_host | '192.168.16.5' | +-----------------------------------+--------------+----------------+","s":"Host variables","u":"/docs/iaas/guides/operations-guide/manager/get","h":"#host-variables","p":1322},{"i":1329,"t":"Get all facts of a specific node osism get facts testbed-manager.testbed.osism.xyz Get a specific fact of a specific node $ osism get facts testbed-manager.testbed.osism.xyz ansible_architecture +-----------------------------------+----------------------+----------+ | Host | Fact | Value | +===================================+======================+==========+ | testbed-manager.testbed.osism.xyz | ansible_architecture | 'x86_64' | +-----------------------------------+----------------------+----------+","s":"Host facts","u":"/docs/iaas/guides/operations-guide/manager/get","h":"#host-facts","p":1322},{"i":1331,"t":"A console command is available in the OSISM CLI. This allows specific parts of the environment to be operated interactively.","s":"Console","u":"/docs/iaas/guides/operations-guide/manager/console","h":"","p":1330},{"i":1333,"t":"Used tool: ansible-console $ osism console --type ansible testbed-node-0 Welcome to the ansible console. Type help or ? to list commands. dragon@testbed-node-0 (1)[f:5]$ !uptime testbed-node-0 | CHANGED | rc=0 >> 18:14:15 up 80 days, 33 min, 0 users, load average: 4.00, 3.07, 2.67 dragon@testbed-node-0 (1)[f:5]$ Shortcut: osism console .testbed-node-0","s":"Ansible","u":"/docs/iaas/guides/operations-guide/manager/console","h":"#ansible","p":1330},{"i":1335,"t":"Used tool: ClusterShell The same groups as defined in the Ansible Inventory can be used. $ osism console --type clush control Enter 'quit' to leave this interactive mode Working with nodes: testbed-node-[0-2] clush> Shortcut: osism console :control","s":"Clush","u":"/docs/iaas/guides/operations-guide/manager/console","h":"#clush","p":1330},{"i":1337,"t":"Used tool: Python Prompt Toolkit $ osism console --type container testbed-node-0/fluentd (fluentd)[td-agent@testbed-node-0 /]$ ps ax PID TTY STAT TIME COMMAND 1 ? Ss 0:00 dumb-init --single-child -- kolla_start 7 ? Sl 24:28 /opt/td-agent/bin/ruby /usr/sbin/td-agent -o /var/log/kolla/fluentd/fluent 25 ? Sl 3519:55 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /usr/sbin/td-agent -o /var 238 pts/0 Ss 0:00 bash 247 pts/0 R+ 0:00 ps ax Shortcut: osism console testbed-node-0/fluentd","s":"Container","u":"/docs/iaas/guides/operations-guide/manager/console","h":"#container","p":1330},{"i":1339,"t":"Used tool: OpenSSH $ osism console --type ssh testbed-node-0 You have new mail. Last login: Wed Sep 27 18:15:39 2023 from 192.168.16.5 dragon@testbed-node-0:~$ uptime 18:16:25 up 80 days, 35 min, 1 user, load average: 2.85, 3.04, 2.71 Shortcut: osism console testbed-node-0","s":"SSH","u":"/docs/iaas/guides/operations-guide/manager/console","h":"#ssh","p":1330},{"i":1342,"t":"All running or scheduled tasks can be listed with osism task list. +----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------+ | Worker | ID | Name | Status | Start time | Arguments | |----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------| | celery@kolla-ansible | 8a553e69-c532-4ba0-a5d4-08a983bde692 | osism.tasks.kolla.run | ACTIVE | 2023-09-27 17:55:54.252250 | ['kolla', 'common', ['-e kolla_action=pull']] | | celery@osism-ansible | dba72dd5-1885-408f-9262-e0ded111a007 | osism.tasks.ansible.run | ACTIVE | 2023-09-27 18:00:31.215879 | ['generic', 'facts', []] | +----------------------+--------------------------------------+-------------------------+----------+----------------------------+-----------------------------------------------+","s":"List","u":"/docs/iaas/guides/operations-guide/manager/task","h":"#list","p":1340},{"i":1344,"t":"Sometimes tasks get stuck. Due to the internal locks it is then not possible to re-execute plays with the same name. Also it is currently not possible to cancel already running tasks (is on the todo list). The only way to unblock the situation is to stop the manager service and start it again. cd /opt/manager docker compose down docker compose up -d In earlier versions of OSISM, the Redis service was not stateless. In these cases, it is necessary to delete the Redis service volume before restarting the manager service. docker volume rm manager_redis","s":"Broker reset","u":"/docs/iaas/guides/operations-guide/manager/task","h":"#broker-reset","p":1340},{"i":1347,"t":"$ openstack --os-cloud admin volume service list +------------------+-----------------------------------+----------+---------+-------+----------------------------+ | Binary | Host | Zone | Status | State | Updated At | +------------------+-----------------------------------+----------+---------+-------+----------------------------+ | cinder-scheduler | testbed-node-0 | internal | enabled | up | 2023-10-01T08:53:14.000000 | | cinder-scheduler | testbed-node-1 | internal | enabled | up | 2023-10-01T08:53:15.000000 | | cinder-scheduler | testbed-node-2 | internal | enabled | up | 2023-10-01T08:53:15.000000 | | cinder-volume | testbed-node-0@rbd-1 | nova | enabled | down | 2023-09-30T18:50:05.000000 | | cinder-volume | testbed-node-2@rbd-1 | nova | enabled | down | 2023-09-30T18:50:05.000000 | | cinder-volume | testbed-node-1@rbd-1 | nova | enabled | down | 2023-09-30T18:50:08.000000 | +------------------+-----------------------------------+----------+---------+-------+----------------------------+ $ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-0@rbd-1 Service cinder-volume on host testbed-node-0@rbd-1 removed. $ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-1@rbd-1 Service cinder-volume on host testbed-node-1@rbd-1 removed. $ docker exec -it cinder_api cinder-manage service remove cinder-volume testbed-node-2@rbd-1 Service cinder-volume on host testbed-node-2@rbd-1 removed. $ openstack --os-cloud admin volume service list +------------------+-----------------------------------+----------+---------+-------+----------------------------+ | Binary | Host | Zone | Status | State | Updated At | +------------------+-----------------------------------+----------+---------+-------+----------------------------+ | cinder-scheduler | testbed-node-0 | internal | enabled | up | 2023-10-01T08:56:24.000000 | | cinder-scheduler | testbed-node-1 | internal | enabled | up | 2023-10-01T08:56:25.000000 | | cinder-scheduler | testbed-node-2 | internal | enabled | up | 2023-10-01T08:56:25.000000 | +------------------+-----------------------------------+----------+---------+-------+----------------------------+","s":"Remove service","u":"/docs/iaas/guides/operations-guide/openstack/cinder","h":"#remove-service","p":1345},{"i":1349,"t":"It can happen that more block storage usage is stored in the database for a project than is actually used. This can be corrected using cinder-manage. For all projects: $ docker exec -it cinder_api cinder-manage quota sync Only for a specific project: $ docker exec -it cinder_api cinder-manage quota sync --project-id PROJECT_ID","s":"Sync quota","u":"/docs/iaas/guides/operations-guide/openstack/cinder","h":"#sync-quota","p":1345},{"i":1351,"t":"https://docs.openstack.org/cinder/latest/admin/basic-volume-qos.html Create default volume QoS policy that allows 1000 read IOPS and 1000 write IOPS. $ openstack --os-cloud admin volume qos create \\ --consumer both \\ --property read_iops_sec=1000 \\ --property write_iops_sec=1000 \\ default +------------+---------------------------------------------+ | Field | Value | +------------+---------------------------------------------+ | consumer | both | | id | 48920d26-e85f-4920-8ed4-ff8d322c77b9 | | name | testing | | properties | read_iops_sec='1000', write_iops_sec='1000' | +------------+---------------------------------------------+ $ openstack --os-cloud admin volume qos list +--------------------------------------+---------+----------+--------------+---------------------------------------------+ | ID | Name | Consumer | Associations | Properties | +--------------------------------------+---------+----------+--------------+---------------------------------------------+ | 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | | read_iops_sec='1000', write_iops_sec='1000' | +--------------------------------------+---------+----------+--------------+---------------------------------------------+ Assign the default volume QoS policy to the __DEFAULT volume type. $ openstack --os-cloud admin volume qos associate default __DEFAULT__ $ openstack --os-cloud admin volume qos list +--------------------------------------+---------+----------+--------------+---------------------------------------------+ | ID | Name | Consumer | Associations | Properties | +--------------------------------------+---------+----------+--------------+---------------------------------------------+ | 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | __DEFAULT__ | read_iops_sec='1000', write_iops_sec='1000' | +--------------------------------------+---------+----------+--------------+---------------------------------------------+ Change the read IOPS from 1000 to 2000 and the write IOPS from 1000 to 2000 of the default volume QoS policy. $ openstack --os-cloud admin volume qos set \\ --property read_iops_sec=2000 \\ --property write_iops_sec=2000 \\ default $ openstack --os-cloud admin volume qos list +--------------------------------------+---------+----------+--------------+---------------------------------------------+ | ID | Name | Consumer | Associations | Properties | +--------------------------------------+---------+----------+--------------+---------------------------------------------+ | 48920d26-e85f-4920-8ed4-ff8d322c77b9 | default | both | __DEFAULT__ | read_iops_sec='2000', write_iops_sec='2000' | +--------------------------------------+---------+----------+--------------+---------------------------------------------+ The following properties are available. For Fixed IOPS per volume: read_iops_sec write_iops_sec total_iops_sec For Burst IOPS per volume: read_iops_sec_max write_iops_sec_max total_iops_sec_max For Fixed bandwidth per volume: read_bytes_sec write_bytes_sec total_bytes_sec For Burst bandwidth per volume: read_bytes_sec_max write_bytes_sec_max total_bytes_sec_max For burst bucket size: size_iops_sec","s":"Quality of Service (QoS)","u":"/docs/iaas/guides/operations-guide/openstack/cinder","h":"#quality-of-service-qos","p":1345},{"i":1353,"t":"List all users of a project who have been assigned the member role $ openstack --os-cloud admin role assignment list --names --role member --project test +--------+-----------+-------+-----------+--------+--------+-----------+ | Role | User | Group | Project | Domain | System | Inherited | +--------+-----------+-------+-----------+--------+--------+-----------+ | member | test@test | | test@test | | | False | +--------+-----------+-------+-----------+--------+--------+-----------+","s":"Keystone","u":"/docs/iaas/guides/operations-guide/openstack/keystone","h":"","p":1352},{"i":1356,"t":"The play network-external is available and usable as of OSISM 7.0.6. osism apply network-external Available parameters for the OpenStack Environment (environments/openstack/configuration.yml). Parameter Default network_external_allocation_pool_end \"192.168.112.200\" network_external_allocation_pool_start \"192.168.112.100\" network_external_cidr \"192.168.112.0/20\" network_external_cloud admin network_external_gateway_ip \"192.168.112.5\" network_external_name public network_external_provider_network_type flat network_external_provider_physical_network physnet1 network_external_state present","s":"Create an external network","u":"/docs/iaas/guides/operations-guide/openstack/","h":"#create-an-external-network","p":1354},{"i":1358,"t":"Live migrate all instances running on the compute node with the help of the OpenStack Resource Manager Ensure that no more instances are running on the compute node ps ax | grep qemu Reboot the compute node osism apply reboot -l NODE -e ireallymeanit=yes Wait for the compute node to reboot Re-enable the compute service openstack --os-cloud admin compute service set --enable --disable-reason \"\" NODE nova-compute Check compute service openstack --os-cloud admin compute service list --host NODE --service nova-compute","s":"Reboot a compute node","u":"/docs/iaas/guides/operations-guide/openstack/","h":"#reboot-a-compute-node","p":1354},{"i":1360,"t":"Add the operater user osism apply operator -u osism -l NODE Run the bootstrap osism apply bootstrap -l NODE When a routed network fabric is used deploy the FRR service (optional) osism apply frr -l NODE Deploy logging service and Prometheus exporters osism apply common -l NODE osism apply prometheus -l NODE osism apply scaphandre -l NODE Deploy network services osism apply openvswitch -l NODE osism apply ovn -l NODE osism apply neutron -l NODE If you do not use the OVN SDN skip osism apply ovn -l NODE. Deploy compute services osism apply nova -l NODE Deploy telemetry services (optional) osism apply ceilometer -l NODE Deploy Netdata service (optional) osism apply netdata -l NODE Add compute node to Prometheus monitoring osism apply prometheus -l monitoring Refresh the /etc/hosts file osism apply hosts Refresh the SSH client configuration file osism apply sshconfig Add compute node to the known hosts file osism apply known-hosts Containers that run on a compute node. Versions may differ. There is no ceilometer_compute container if you have not deployed the optional OpenStack telemetry service. $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 559e5176695c quay.io/osism/nova-compute:27.1.1.20230919 \"dumb-init --single-…\" 5 minutes ago Up 5 minutes (healthy) nova_compute 31248d71ab7d quay.io/osism/nova-libvirt:8.0.0.20230919 \"dumb-init --single-…\" 6 minutes ago Up 6 minutes (healthy) nova_libvirt 9292030d706c quay.io/osism/nova-ssh:27.1.1.20230919 \"dumb-init --single-…\" 6 minutes ago Up 6 minutes (healthy) nova_ssh fda4b6fb30c8 quay.io/osism/neutron-metadata-agent:22.0.3.20230919 \"dumb-init --single-…\" 2 hours ago Up 2 hours (healthy) neutron_ovn_metadata_agent 0e3ec450b668 quay.io/osism/ceilometer-compute:20.0.1.20230919 \"dumb-init --single-…\" 6 hours ago Up 6 hours (healthy) ceilometer_compute 25ff9702e0e5 quay.io/osism/prometheus-libvirt-exporter:6.0.0.20230919 \"dumb-init --single-…\" 6 hours ago Up 6 hours prometheus_libvirt_exporter 1bff2e29923b quay.io/osism/prometheus-cadvisor:0.45.0.20230919 \"dumb-init --single-…\" 6 hours ago Up 6 hours prometheus_cadvisor 602832daf237 quay.io/osism/prometheus-node-exporter:1.4.0.20230919 \"dumb-init --single-…\" 6 hours ago Up 6 hours prometheus_node_exporter d4de2f32cdf8 quay.io/osism/ovn-controller:23.6.1.20230919 \"dumb-init --single-…\" 6 hours ago Up 6 hours ovn_controller 3bf43ae5a94f quay.io/osism/openvswitch-vswitchd:3.1.2.20230919 \"dumb-init --single-…\" 7 hours ago Up 7 hours (healthy) openvswitch_vswitchd ebc048b02ab2 quay.io/osism/openvswitch-db-server:3.1.2.20230919 \"dumb-init --single-…\" 7 hours ago Up 7 hours (healthy) openvswitch_db 4f33dfa66c14 hubblo/scaphandre:0.5.0 \"scaphandre promethe…\" 7 hours ago Up 7 hours 10.10.129.64:9155->8080/tcp scaphandre 9b1f6342dc60 quay.io/osism/cron:3.0.20230919 \"dumb-init --single-…\" 7 hours ago Up 7 hours cron 718aecaddde1 quay.io/osism/kolla-toolbox:16.1.1.20230919 \"dumb-init --single-…\" 7 hours ago Up 7 hours kolla_toolbox f6f9422c1853 quay.io/osism/fluentd:4.5.1.20230919 \"dumb-init --single-…\" 7 hours ago Up 7 hours fluentd","s":"Add a new compute node","u":"/docs/iaas/guides/operations-guide/openstack/","h":"#add-a-new-compute-node","p":1354},{"i":1362,"t":"In the configuration repository remove the compute node everywhere. Then update the configuration repository on the manager with osism apply configuration Live migrate all instances running on the compute node with the help of the OpenStack Resource Manager Evacuate all instances on the compute node with the help of the OpenStack Resource Manager Ensure that no more instances are running on the compute node ps ax | grep qemu Stop all OpenStack compute services on the compute node systemctl stop kolla-nova_ssh-container.service systemctl stop kolla-nova_libvirt-container.service systemctl stop kolla-nova_compute-container.service Delete the compute service $ openstack --os-cloud admin compute service list --host NODE +--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+ | ID | Binary | Host | Zone | Status | State | Updated At | +--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+ | 90345eb5-cf2f-47ef-becc-758ee36fb132 | nova-compute | NODE | nova | enabled | down | 2023-12-21T11:53:00.000000 | +--------------------------------------+----------------+---------+----------+----------+-------+----------------------------+ $ openstack --os-cloud admin compute service delete 90345eb5-cf2f-47ef-becc-758ee36fb132 Stop all OpenStack network services on the compute node systemctl stop kolla-neutron_ovn_metadata_agent-container.service systemctl stop kolla-ovn_controller-container.service Delete the network services $ openstack --os-cloud admin network agent list --host NODE +--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+ | ID | Agent Type | Host | Availability Zone | Alive | State | Binary | +--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+ | 0a5708ea-ba8b-5fde-8187-c6b24d3cf5ed | OVN Metadata agent | NODE | | :-) | UP | neutron-ovn-metadata-agent | | NODE | OVN Controller agent | NODE | | :-) | UP | ovn-controller | +--------------------------------------+----------------------+---------+-------------------+-------+-------+----------------------------+ $ openstack --os-cloud admin network agent delete 0a5708ea-ba8b-5fde-8187-c6b24d3cf5ed $ openstack --os-cloud admin network agent delete NODE Refresh the facts osism apply facts Refresh the /etc/hosts file osism apply hosts Refresh the SSH client configuration file osism apply sshconfig Remove compute node from Prometheus monitoring osism apply prometheus -l monitoring Remove compute node from the known hosts file osism apply known-hosts","s":"Remove a compute node","u":"/docs/iaas/guides/operations-guide/openstack/","h":"#remove-a-compute-node","p":1354},{"i":1364,"t":"OpenStack, OVN, and Open vSwitch all really like UUIDs. $ openstack --os-cloud admin image list -f yaml - ID: d64f0b9d-0ea1-40b0-b879-b98e46fc7bcf Name: Cirros 0.6.0 Status: active - ID: ee842bc5-dd29-4de5-a5db-1c9be759fe85 Name: Cirros 0.6.1 Status: active - ID: cd28d95c-bd12-4e1e-8155-b9bf5ecbcb2f Name: Cirros 0.6.2 Status: active These UUIDs are great for uniqueness, but 36-character strings are terrible for readability. Statistically, just the first few characters are enough for uniqueness in small environments, so let’s define a helper to make things more readable: abbrev() { a='[0-9a-fA-F]' b=$a$a c=$b$b; sed \"s/$b-$c-$c-$c-$c$c$c//g\"; } You can use this as a filter to abbreviate UUIDs. For example, use it to abbreviate the above image list: $ openstack --os-cloud admin image list -f yaml | abbrev - ID: d64f0b Name: Cirros 0.6.0 Status: active - ID: ee842b Name: Cirros 0.6.1 Status: active - ID: cd28d9 Name: Cirros 0.6.2 Status: active Source: https://docs.ovn.org/en/stable/tutorials/ovn-openstack.html#shortening-uuids","s":"Network","u":"/docs/iaas/guides/operations-guide/network","h":"","p":1363},{"i":1366,"t":"https://gist.github.com/djoreilly/c5ea44663c133b246dd9d42b921f7646 Open vSwitch on a network node with external network vxlan0 and integration with the Octavia service via ohm0. $ docker exec -it openvswitch_vswitchd ovs-vsctl show 2e6227aa-33f1-4762-8831-ab678ce7272d Bridge br-int fail_mode: secure datapath_type: system Port ovn-testbe-0 Interface ovn-testbe-0 type: geneve options: {csum=\"true\", key=flow, remote_ip=\"192.168.16.12\"} Port br-int Interface br-int type: internal Port ovn-testbe-1 Interface ovn-testbe-1 type: geneve options: {csum=\"true\", key=flow, remote_ip=\"192.168.16.11\"} Port tap8fe7d09b-90 Interface tap8fe7d09b-90 Port ohm0 Interface ohm0 type: internal Bridge br-ex Port vxlan0 Interface vxlan0 Port br-ex Interface br-ex type: internal","s":"Open vSwitch (OVS)","u":"/docs/iaas/guides/operations-guide/network","h":"#open-vswitch-ovs","p":1363},{"i":1368,"t":"https://docs.ovn.org/en/stable/tutorials/ovn-openstack.html Get OVN NB and OVN SB connection information from the /etc/kolla/neutron-server/ml2_conf.ini file. ovn_nb_connection=$(sudo grep -P -o -e \"(?<=^ovn_nb_connection = ).*\" \"/etc/kolla/neutron-server/ml2_conf.ini\") ovn_sb_connection=$(sudo grep -P -o -e \"(?<=^ovn_sb_connection = ).*\" \"/etc/kolla/neutron-server/ml2_conf.ini\") The following examples are from a fresh osism/testbed deployment with no payload running yet. OVN NB DB entries: $ docker exec ovn_northd ovn-nbctl --db \"$ovn_nb_connection\" show | abbrev switch b5139b (neutron-8fe7d0) (aka lb-mgmt-net) port 45a49e type: localport addresses: [\"fa:16:3e:fa:99:ea 10.1.0.2\"] port 4d39a5 (aka octavia-listen-port-testbed-node-2) addresses: [\"fa:16:3e:dc:11:e4 10.1.0.45\"] port 8df1b7 (aka octavia-listen-port-testbed-node-0) addresses: [\"fa:16:3e:4d:63:a9 10.1.0.43\"] port ddb6aa (aka octavia-listen-port-testbed-node-1) addresses: [\"fa:16:3e:67:f3:3d 10.1.0.40\"] OVN SB DB entries: $ docker exec ovn_northd ovn-sbctl --db \"$ovn_sb_connection\" show | abbrev Chassis testbed-node-0 hostname: testbed-node-0 Encap geneve ip: \"192.168.16.10\" options: {csum=\"true\"} Port_Binding \"8df1b7\" Chassis testbed-node-2 hostname: testbed-node-2 Encap geneve ip: \"192.168.16.12\" options: {csum=\"true\"} Port_Binding \"4d39a5\" Chassis testbed-node-1 hostname: testbed-node-1 Encap geneve ip: \"192.168.16.11\" options: {csum=\"true\"} Port_Binding \"ddb6aa OVN NB status: $ docker exec ovn_nb_db ovs-appctl -t /var/run/ovn/ovnnb_db.ctl cluster/status OVN_Northbound | abbrev 6d15 Name: OVN_Northbound Cluster ID: f5eb (f5ebd8) Server ID: 6d15 (6d159e) Address: tcp:192.168.16.10:6643 Status: cluster member Role: follower Term: 5 Leader: 87d6 Vote: 87d6 Last Election started 41049332 ms ago, reason: timeout Election timer: 1000 Log: [2, 54] Entries not yet committed: 0 Entries not yet applied: 0 Connections: ->21d7 ->87d6 <-87d6 <-21d7 Disconnections: 6 Servers: 6d15 (6d15 at tcp:192.168.16.10:6643) (self) 87d6 (87d6 at tcp:192.168.16.11:6643) last msg 266 ms ago 21d7 (21d7 at tcp:192.168.16.12:6643) last msg 41048563 ms ago OVN SB status: $ docker exec ovn_sb_db ovs-appctl -t /var/run/ovn/ovnsb_db.ctl cluster/status OVN_Southbound | abbrev be29 Name: OVN_Southbound Cluster ID: bd0c (bd0c26) Server ID: be29 (be2932) Address: tcp:192.168.16.10:6644 Status: cluster member Role: follower Term: 6 Leader: dfdf Vote: unknown Last Election started 41063820 ms ago, reason: timeout Election timer: 1000 Log: [2, 62] Entries not yet committed: 0 Entries not yet applied: 0 Connections: ->dfdf ->085c <-dfdf <-085c Disconnections: 7 Servers: be29 (be29 at tcp:192.168.16.10:6644) (self) dfdf (dfdf at tcp:192.168.16.11:6644) last msg 146 ms ago 085c (085c at tcp:192.168.16.12:6644) last msg 41063293 ms ago","s":"Open Virtual Network (OVN)","u":"/docs/iaas/guides/operations-guide/network","h":"#open-virtual-network-ovn","p":1363},{"i":1371,"t":"openstack --os-cloud admin server list --all-projects --host testbed-node-0","s":"Get all servers on a node","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#get-all-servers-on-a-node","p":1369},{"i":1373,"t":"for server in $(openstack --os-cloud admin server list --all-projects --host testbed-node-0 --vm-state active -f value -c ID | tr -d '\\r'); do echo stopping server $server openstack --os-cloud admin server stop $server sleep 2 done","s":"Stop all servers running on a node","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#stop-all-servers-running-on-a-node","p":1369},{"i":1375,"t":"openstack --os-cloud admin compute service set --disable --description MAINTENANCE testbed-node-0 nova-compute openstack --os-cloud admin compute service list --long +--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+ | ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down | +--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+ | b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | up | 2023-12-14T14:20:24.000000 | MAINTENANCE | False | +--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+ openstack --os-cloud admin compute service set --enable testbed-node-0 nova-compute openstack --os-cloud admin compute service list +--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+ | ID | Binary | Host | Zone | Status | State | Updated At | +--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+ | b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | enabled | up | 2023-12-14T14:22:54.000000 | +--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+","s":"Disable & enable a compute service","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#disable--enable-a-compute-service","p":1369},{"i":1377,"t":"openstack --os-cloud admin --os-compute-api-version 2.12 compute service set --down testbed-node-0 nova-compute openstack --os-cloud admin compute service list --long +--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+ | ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down | +--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+ | b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | down | 2023-12-14T14:21:47.000000 | None | True | +--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+ openstack --os-cloud admin --os-compute-api-version 2.12 compute service set --up testbed-node-0 nova-compute openstack --os-cloud admin compute service list --long +--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+ | ID | Binary | Host | Zone | Status | State | Updated At | Disabled Reason | Forced Down | +--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+ | b77c5aeb-91c0-4972-84ea-7c8bd5a49fdd | nova-compute | testbed-node-0 | nova | disabled | up | 2023-12-14T14:20:24.000000 | None | False | +--------------------------------------+----------------+-----------------+----------+----------+-------+----------------------------+----------------------------------------------------+-------------+","s":"Force down & up a compute service","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#force-down--up-a-compute-service","p":1369},{"i":1379,"t":"$ grep Huge /proc/meminfo AnonHugePages: 0 kB ShmemHugePages: 0 kB FileHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 0 kB $ sudo sudo hugeadm --pool-list libhugetlbfs: ERROR: Line too long when parsing mounts Size Minimum Current Maximum Default 2097152 0 0 0 * 1073741824 0 0 0 /etc/default/grub GRUB_CMDLINE_LINUX=\"default_hugepagesz=1G hugepagesz=1G hugepages=512 transparent_hugepage=never\" update-grub reboot $ grep Huge /proc/meminfo AnonHugePages: 0 kB ShmemHugePages: 0 kB FileHugePages: 0 kB HugePages_Total: 512 HugePages_Free: 512 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 1048576 kB Hugetlb: 536870912 kB $ sudo hugeadm --pool-list libhugetlbfs: ERROR: Line too long when parsing mounts Size Minimum Current Maximum Default 2097152 0 0 0 * 1073741824 512 512 512","s":"Huge pages","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#huge-pages","p":1369},{"i":1381,"t":"https://docs.openstack.org/nova/latest/admin/resource-limits.html","s":"Quality of Service (QoS)","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#quality-of-service-qos","p":1369},{"i":1383,"t":"Host aggregates can be managed with the playbook. The playbook is used with osism apply -e openstack host-aggregates. Further arguments for host aggregates can be found in the documentation for the openstack.cloud.host_aggregate Ansible module. environments/openstack/playbook-host-aggregates.yml --- - name: Manage host aggregates hosts: localhost connection: local vars: host_aggregates: - name: aggregate1 hosts: - host1 - host2 - host3 tasks: - name: Create host aggregate openstack.cloud.host_aggregate: cloud: admin state: present name: \"{{ item.name }}\" hosts: \"{{ item.hosts }}\" loop: \"{{ host_aggregates }}\"","s":"Host aggregates","u":"/docs/iaas/guides/operations-guide/openstack/nova","h":"#host-aggregates","p":1369},{"i":1386,"t":"/var/log/kolla/octavia/octavia-health-manager.log 2023-10-25 16:43:52.547 22 WARNING octavia.amphorae.drivers.health.heartbeat_udp [-] The amphora 2a33a889-4f9a-4340-84a5-e58a7a8af17e with IP 10.1.0.79 is missing from the DB, so it cannot be automatically deleted (the compute_id is unknown). An operator must manually delete it from the compute service.","s":"Cleanup of amphorae missing from the DB","u":"/docs/iaas/guides/operations-guide/openstack/octavia","h":"#cleanup-of-amphorae-missing-from-the-db","p":1384},{"i":1388,"t":"Get the local IP address (lb_network_ip) of the amphora you want to access via openstack --os-cloud admin loadbalancer amphora list. Connect to one of the nodes that you use for Octavia. Normally the control- or network nodes. You can now use SSH to access the amphora. The use of sudo is required here because you cannot access /etc/kolla/octavia-worker/octavia_ssh_key with the operator user account. Replace lb_network_ip with the local IP address of the amphora. sudo ssh -i /etc/kolla/octavia-worker/octavia_ssh_key ubuntu@lb_network_ip","s":"SSH access to amphorae","u":"/docs/iaas/guides/operations-guide/openstack/octavia","h":"#ssh-access-to-amphorae","p":1384},{"i":1391,"t":"https://docs.openstack.org/neutron/latest/admin/config-qos.html","s":"Quality of Service (QoS)","u":"/docs/iaas/guides/operations-guide/openstack/neutron","h":"#quality-of-service-qos","p":1389},{"i":1395,"t":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/operations/ It is strongly advised to use the documentation for the version being used. Pacific - https://docs.ceph.com/en/pacific/rados/operations/ Quincy - https://docs.ceph.com/en/quincy/rados/operations/ Reef - https://docs.ceph.com/en/reef/rados/operations/ note Do not take information in the documentation at face value. Especially when it comes to advanced/rarely used/very new features it is strongly advised to test any claims made in the documentation about any particular feature. Never assume that things will work as written without actually testing it on a test setup as close to your real workload scenario as possible.","s":"Where to find docs","u":"/docs/iaas/guides/operations-guide/ceph","h":"#where-to-find-docs","p":1393},{"i":1397,"t":"The current Ceph releases and their support status can be found on https://docs.ceph.com/en/latest/releases/ When a new Ceph stable version is released you are strongly advised to not roll it out on any production cluster whatsoever. Even though its listed as \"stable\" it doesn't mean that this is actually true. Especially avoid using .0 releases on anything remotely production unless you really, really now what you're doing and can live with a possible catastrophic failure. Be very conservative about what version you run on production systems. Shiny new features aren't worth the risk of total or partial data loss/corruption.","s":"Advice on Ceph releases","u":"/docs/iaas/guides/operations-guide/ceph","h":"#advice-on-ceph-releases","p":1393},{"i":1400,"t":"The following commands can be used to quickly check the status of Ceph: Print overall cluster status ceph -s Print detailed health information ceph health detail Display current OSD tree ceph osd tree Cluster storage usage by pool and storage class ceph df List pools with detailed configuration ceph osd pool ls detail Get usage stats for OSDs ceph osd df {plain|tree} {class e.g. hdd|ssd} Watch Ceph health messages sequentially ceph -w List daemon versions running in the cluster ceph versions Also you can run the following on each node running ceph-daemons, to provide further debug information about the environment: # lscpu # cat /proc/cpuinfo # if lscpu isn't available # free -g # ip l # ethtool # for each network adapter","s":"60 seconds cluster overview","u":"/docs/iaas/guides/operations-guide/ceph","h":"#60-seconds-cluster-overview","p":1393},{"i":1402,"t":"$ ceph health mute $ ceph health unmute ","s":"Mute/Unmute a health warning","u":"/docs/iaas/guides/operations-guide/ceph","h":"#muteunmute-a-health-warning","p":1393},{"i":1404,"t":"$ ceph osd set noscrub $ ceph osd set nodeep-scrub $ ceph osd unset noscrub $ ceph osd unset nodeep-scrub warning Use this sparingly only in emergency situations. Setting these flags will cause a HEALTH_WARN status, increase risk of data corruption and also the risk of generating a HEALTH_WARN due to PGs not being (deep-)scrubbed in time.","s":"Disable/Enable (deep-)scrubbing","u":"/docs/iaas/guides/operations-guide/ceph","h":"#disableenable-deep-scrubbing","p":1393},{"i":1406,"t":"The traditional way of doing this is by setting the noout flag, do the appropriate maintenance work and after the node is back online unset the flag like so: ceph osd set noout After maintenance is done and host is back up: ceph osd unset noout On versions Luminous or above you can set the flag individually for single OSDs or entire CRUSH buckets, which can be a safer option in case of prolonged maintenance periods. Add noout for a OSD: ceph osd add-noout osd. Remove noout for a OSD: ceph osd rm-noout osd. Add noout for CRUSH bucket (e.g. host name as seen in ceph osd tree): ceph osd set-group noout Remove noout for CRUSH bucket: ceph osd unset-group noout ","s":"Reboot a single node","u":"/docs/iaas/guides/operations-guide/ceph","h":"#reboot-a-single-node","p":1393},{"i":1409,"t":"# lsblk # lsblk -S # lsscsi # nvme list # pvs # vgs # lvs","s":"Enumerate typical storage devices and LVM","u":"/docs/iaas/guides/operations-guide/ceph","h":"#enumerate-typical-storage-devices-and-lvm","p":1393},{"i":1411,"t":"# smartctl -a /dev/sdX # nvme smart-log /dev/nvmeXnY","s":"SMART data for SATA/SAS and NVME devices","u":"/docs/iaas/guides/operations-guide/ceph","h":"#smart-data-for-satasas-and-nvme-devices","p":1393},{"i":1413,"t":"# nvme id-ns -H /dev/nvmeXnY note Check the last lines named \"LBA Format\". It will show which formats are supported, which format is in use and which format offers the best performance according to the vendor.","s":"Check format of a NVME device","u":"/docs/iaas/guides/operations-guide/ceph","h":"#check-format-of-a-nvme-device","p":1393},{"i":1415,"t":"warning This will destroy all data on the device! # nvme format --lbaf= /dev/nvmeXnY","s":"Format a NVME device to a different LBA format using nvme-cli","u":"/docs/iaas/guides/operations-guide/ceph","h":"#format-a-nvme-device-to-a-different-lba-format-using-nvme-cli","p":1393},{"i":1417,"t":"warning This will destroy all data on the device! # nvme format -s2 /dev/nvmeXnY # blkdiscard /dev/nvmeXnY # nvme format -s1 /dev/nvmeXnY","s":"Secure Erase a NVME drive using nvme-cli","u":"/docs/iaas/guides/operations-guide/ceph","h":"#secure-erase-a-nvme-drive-using-nvme-cli","p":1393},{"i":1419,"t":"warning This will destroy all data on the device! Gather device info: # hdparm -I /dev/sdX Check that the output says \"not frozen\" and \"not locked\", also it should list support for enhanced erase and list time estimates for SECURITY ERASE UNIT and/or ENHANCED SECURITY ERASE UNIT Set a master password for the disk (required, will be automatically removed after wipe) # hdparm --user-master wipeit --security-set-pass wipeit /dev/sdX # hdparm -I /dev/sdX Check that \"Security level\" is now \"high\" and master password is now \"enabled\" instead of \"not enabled\" before Wipe the device If device supports enhanced security erase (better), use the following: # hdparm --user-master wipeit --security-erase-enhanced wipeit /dev/sdX If not, use standard security erase: # hdparm --user-master wipeit --security-erase wipeit /dev/sdX note On some systems the system firmware might \"freeze\" the device, which makes it impossible to issue a secure erase or reformat the device. In that case it might be necessary to either \"unfreeze\" the drive or to install the drive in another system where it can be unfrozen. Also make sure that the device is actually wiped. Its recommended to at least perform a blanking pass on HDDs with a tool like nwipe.","s":"Secure Erase a SATA/SAS drive using hdparm","u":"/docs/iaas/guides/operations-guide/ceph","h":"#secure-erase-a-satasas-drive-using-hdparm","p":1393},{"i":1422,"t":"$ ceph osd find osd.","s":"Locate a specific OSD in the cluster","u":"/docs/iaas/guides/operations-guide/ceph","h":"#locate-a-specific-osd-in-the-cluster","p":1393},{"i":1424,"t":"$ ceph osd metadata $ ceph osd metadata osd. Interesting fields: bluefs_db_rotational bluefs_dedicated_db bluefs_dedicated_wal bluefs_wal_rotational bluestore_bdev_rotational device_ids device_paths devices hostname osd_objectstore rotational","s":"Get OSD metadata (global and single OSD)","u":"/docs/iaas/guides/operations-guide/ceph","h":"#get-osd-metadata-global-and-single-osd","p":1393},{"i":1428,"t":"As with ‘Remove a single OSD node’. Except that the steps are only executed for a single OSD and the node is not removed from the CRUSH map and the inventory. Only the entries relating to the removed OSD are removed from the host vars. Manual way​ $ ceph osd crush reweight osd. 0.0 # Wait for rebalance to complete... $ ceph osd out osd. # systemctl stop ceph-osd@ # systemctl disable ceph-osd@ $ ceph osd purge osd. --yes-i-really-mean-it The LV and VG defined in the inventory for this OSD must also be removed. The OSD itself should be wiped.","s":"Remove a OSD","u":"/docs/iaas/guides/operations-guide/ceph","h":"#remove-a-osd","p":1393},{"i":1430,"t":"Get all OSDs of the node $ ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.11691 root default -3 0.03897 host testbed-node-0 0 hdd 0.01949 osd.0 up 1.00000 1.00000 4 hdd 0.01949 osd.4 up 1.00000 1.00000 -5 0.03897 host testbed-node-1 1 hdd 0.01949 osd.1 up 1.00000 1.00000 3 hdd 0.01949 osd.3 up 1.00000 1.00000 -7 0.03897 host testbed-node-2 2 hdd 0.01949 osd.2 up 1.00000 1.00000 5 hdd 0.01949 osd.5 up 1.00000 1.00000 Reduce the weighting of all OSDs on the node to 0. Do this for each OSD in a row and wait after each adjustment until the Ceph cluster is balanced. Depending on how large the Ceph cluster and the individual OSDs are, this may take some time. $ ceph osd crush reweight osd.2 0.0 $ ceph osd crush reweight osd.5 0.0 The Ceph OSDs that are to be removed then have a weight of 0. $ ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.07794 root default -3 0.03897 host testbed-node-0 0 hdd 0.01949 osd.0 up 1.00000 1.00000 4 hdd 0.01949 osd.4 up 1.00000 1.00000 -5 0.03897 host testbed-node-1 1 hdd 0.01949 osd.1 up 1.00000 1.00000 3 hdd 0.01949 osd.3 up 1.00000 1.00000 -7 0 host testbed-node-2 2 hdd 0 osd.2 up 1.00000 1.00000 5 hdd 0 osd.5 up 1.00000 1.00000 Remove the OSDs and everything that belongs to them from the node. This is a disruptive action that cannot be undone. The devices used are also reset. $ osism apply ceph-shrink-osd -e ireallymeanit=yes -e osd_to_kill=2,5 All OSDs were removed. $ ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.07794 root default -3 0.03897 host testbed-node-0 0 hdd 0.01949 osd.0 up 1.00000 1.00000 4 hdd 0.01949 osd.4 up 1.00000 1.00000 -5 0.03897 host testbed-node-1 1 hdd 0.01949 osd.1 up 1.00000 1.00000 3 hdd 0.01949 osd.3 up 1.00000 1.00000 -7 0 host testbed-node-2 Remove the node from the CRUSH map. $ ceph osd crush remove testbed-node-2 removed item id -7 name 'testbed-node-2' from crush map Remove the node from all Ceph groups in the inventory. Remove all Ceph-specific parameters from the host vars of the node from the inventory","s":"Remove a single OSD node","u":"/docs/iaas/guides/operations-guide/ceph","h":"#remove-a-single-osd-node","p":1393},{"i":1432,"t":"$ ceph osd out osd. # systemctl stop ceph-osd@ # systemctl disable ceph-osd@","s":"Remove an OSD (temporarily e.g. when replacing a broken disk)","u":"/docs/iaas/guides/operations-guide/ceph","h":"#remove-an-osd-temporarily-eg-when-replacing-a-broken-disk","p":1393},{"i":1434,"t":"warning Use only in emergency situations! $ ceph osd set nobackfill $ ceph osd set norecovery $ ceph osd set norebalance Unset the flags with ceph osd unset .","s":"Disable backfills/recovery completely","u":"/docs/iaas/guides/operations-guide/ceph","h":"#disable-backfillsrecovery-completely","p":1393},{"i":1438,"t":"Usually only useful when parsing it, so here are two ways to get the data: $ ceph pg dump $ ceph pg dump --format=json-pretty","s":"Dump placement groups","u":"/docs/iaas/guides/operations-guide/ceph","h":"#dump-placement-groups","p":1393},{"i":1440,"t":"$ ceph pg query","s":"Query a PG about its status","u":"/docs/iaas/guides/operations-guide/ceph","h":"#query-a-pg-about-its-status","p":1393},{"i":1442,"t":"$ ceph pg scrub $ ceph pg deep-scrub note Instructing a PG to (deep-)scrub does not mean that it will do so immediately, it can take some time for the scrub to start.","s":"Start (deep-)scrubbing of a placement group","u":"/docs/iaas/guides/operations-guide/ceph","h":"#start-deep-scrubbing-of-a-placement-group","p":1393},{"i":1444,"t":"Finding PGs which have large OMAP objects: # ceph pg dump --format=json | jq '.pg_map.pg_stats[] | select(.stat_sum.num_large_omap_objects != 0) | (.pgid, .stat_sum.num_large_omap_objects, .up, .acting)' (Remove the line breaks between the single quotes or jq might act weird!) This will dump all PG IDs with large OMAP objects and their up/acting OSDs. You then can grep the logs of these OSDs for \"Large omap object\" to find the actual objects causing the health warning. Also the PG ID before the dot is equal to the pool ID it belongs to. In case the logs have been rotated, instruct those OSDs to do a deep-scrub and watch the logs for the message to appear. From there you can investigate the issue further, mostly it'll be due to the index of a RGW bucket getting too big due to too many objects, thus resharding that bucket's index will be necessary.","s":"HEALTH_WARN - Large omap objects found...","u":"/docs/iaas/guides/operations-guide/ceph","h":"#health_warn---large-omap-objects-found","p":1393},{"i":1446,"t":"$ ceph pg repair note Recovery might not start immediately and might take some time. You can query the status of the recovery through ceph pg query. Be sure to read the Ceph manual about this topic thoroughly: https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshooting-pg/","s":"Instruct a PG to repair in case of scrub errors (inconsistent PG)","u":"/docs/iaas/guides/operations-guide/ceph","h":"#instruct-a-pg-to-repair-in-case-of-scrub-errors-inconsistent-pg","p":1393},{"i":1448,"t":"note Read the RADOS pool operations documentation in detail before playing around with pools. Especially when considering making changes to the CRUSH map. Wrong decisions there can lead to data loss or other catastrophic failures. https://docs.ceph.com/en/latest/rados/operations/pools/","s":"RADOS Pool maintenance","u":"/docs/iaas/guides/operations-guide/ceph","h":"#rados-pool-maintenance","p":1393},{"i":1450,"t":"$ ceph osd pool ls detail","s":"Get pools and their configuration","u":"/docs/iaas/guides/operations-guide/ceph","h":"#get-pools-and-their-configuration","p":1393},{"i":1452,"t":"$ ceph osd crush rule dump","s":"Dump all CRUSH rules","u":"/docs/iaas/guides/operations-guide/ceph","h":"#dump-all-crush-rules","p":1393},{"i":1454,"t":"$ ceph osd pool autoscale-status","s":"Get autoscaler status","u":"/docs/iaas/guides/operations-guide/ceph","h":"#get-autoscaler-status","p":1393},{"i":1456,"t":"$ ceph osd pool create replicated []","s":"Create a replicated pool","u":"/docs/iaas/guides/operations-guide/ceph","h":"#create-a-replicated-pool","p":1393},{"i":1458,"t":"Required, otherwise a health warning will be raised after some time. $ ceph osd pool application enable # Syntax $ ceph osd pool application enable cinder rbd # Example Typical application names are: rbd, rgw, cephfs","s":"Enabling an application on a pool","u":"/docs/iaas/guides/operations-guide/ceph","h":"#enabling-an-application-on-a-pool","p":1393},{"i":1460,"t":"warning This will delete all data in that pool. There is no undo/undelete. $ ceph osd pool delete --yes-i-really-really-mean-it note In order to be able to delete pools, it has to be enabled on the monitors by setting the mon_allow_pool_delete flag to true. Default is false. See: https://docs.ceph.com/en/latest/rados/configuration/mon-config-ref","s":"Delete a pool","u":"/docs/iaas/guides/operations-guide/ceph","h":"#delete-a-pool","p":1393},{"i":1462,"t":"If no autoscaling of PGs is used, it is very important to adapt the PGs per pool to the real world when operating a Ceph cluster. If, for example, OSDs are exchanged, added, new nodes are added, etc., the number of PGs must also be taken into account. The PG Calc Tool can be used to calculate a reasonable number of PGs per pool depending on all ODSs and pools. Further information on placement groups can be found in the Ceph documentation. You should definitely read FACTORS RELEVANT TO SPECIFYING PG_NUM and CHOOSING THE NUMBER OF PGS there. $ ceph osd pool set pg_num note Num PGs must be a power of two! Be careful about changing number of PGs. Changing pg_num to a new value will gradually increase pgp_num on newer versions of Ceph. In older versions one also has to set pgp_num manually, either in increments or in one big leap.","s":"Set number of PGs for a pool","u":"/docs/iaas/guides/operations-guide/ceph","h":"#set-number-of-pgs-for-a-pool","p":1393},{"i":1464,"t":"$ ceph osd crush rule create-replicated replicated_hdd default host hdd $ ceph osd crush rule create-replicated replicated_ssd default host ssd $ ceph osd crush rule create-replicated replicated_nvme default host nvme","s":"Create CRUSH rules for different storage classes","u":"/docs/iaas/guides/operations-guide/ceph","h":"#create-crush-rules-for-different-storage-classes","p":1393},{"i":1466,"t":"$ ceph osd pool set crush_rule This can be used to move a pool from e.g. HDD to SSD or NVME class or anything else that the new CRUSH rule specifies.","s":"Change CRUSH rule for a pool (\"move pool\")","u":"/docs/iaas/guides/operations-guide/ceph","h":"#change-crush-rule-for-a-pool-move-pool","p":1393},{"i":1469,"t":"For Ceph, special playbooks were added to validate the deployment status of the OSD, MON and MGR services. The commands for use are osism validate ceph-osds, osism validate ceph-mons, and osism validate ceph-mgrs. These playbooks will validate that the deployed Ceph environment matches the configuration and is overall in a healthy state. The playbooks will generate report files in JSON format on the first manager node in /opt/reports/validator.","s":"Validating Ceph using OSISM playbooks","u":"/docs/iaas/guides/operations-guide/ceph","h":"#validating-ceph-using-osism-playbooks","p":1393},{"i":1471,"t":"In order to fully shutdown a Ceph cluster safely, you first do the following steps: warning Take GOOD NOTES of the unit names and OSD IDs running on each node. You will need them to restart the cluster later. Stop the workload that is using the cluster This will vary depending on your environment and is not covered here. Pause/Stop operations on the cluster by setting flags $ ceph osd set noout $ ceph osd set nobackfill $ ceph osd set norecover $ ceph osd set norebalance $ ceph osd set nodown $ ceph osd set pause Stop and disable the radosgw services on all nodes (on each rgw node) (if RGW is used) Get the name of the unit (globs not supported for disable) and make a note of the unit name for that node: # systemctl | grep ceph-radosgw Then disable and stop the unit: # systemctl disable --now ceph-radosgw@.service Stop all CephFS file systems (if CephFS is used) List all Ceph file systems $ ceph fs ls For each CephFS do: $ ceph fs down true After that disable and stop all ceph-mds services on all nodes (do this on each node) Get the name of the unit (globs not supported for disable) and make a note of the unit name for that node: # systemctl | grep ceph-mds # systemctl disable --now ceph-mds@.service Stop and disable the ceph-mgr services on all nodes (do this on each node) Get the name of the unit (globs not supported for disable) and make a note of the unit name for that node: # systemctl | grep ceph-mgr # systemctl disable --now ceph-mgr@.service Stop and disable the ceph-osd services on all nodes (do this on each node) Get the names of the units (globs not supported for disable) and make a note of the unit names for that node (best to save it to a file): # systemctl | grep ceph-osd For each OSD unit execute: # systemctl disable ceph-osd@.service Stop all OSDs at once: # systemctl stop ceph-osd\\*.service Finally stop the ceph-mon services on all nodes (do this on each node) Get the name of the unit (globs not supported for disable) and make a note of the unit name for that node: # systemctl | grep ceph-mon # systemctl disable --now ceph-mon@.service","s":"Shutdown a Ceph cluster","u":"/docs/iaas/guides/operations-guide/ceph","h":"#shutdown-a-ceph-cluster","p":1393},{"i":1473,"t":"warning You will need the notes taken during shutdown of the unit names. It can be done without, but then it'll be way more work finding out the names. In order to restart a Ceph cluster after performing a manual shutdown like described in the section above, you do the following: Enable & start the ceph-mon services on all nodes (do this on each node) # systemctl enable --now ceph-mon@.service Enable & start the ceph-osd services on all nodes (do this on each node) For each Ceph OSD on that node do: # systemctl enable --now ceph-osd@.service Depending on the number of OSDs on that node it can take a while. Enable & start the ceph-mgr services on all nodes (do this on each node) # systemctl enable --now ceph-mgr@.service Check the status of your cluster and wait for all OSDs to come online You can watch the status periodically by running: $ watch ceph -s You should wait until all OSDs are up + in again, before removing flags. Remove flags to unpause operations $ ceph osd unset pause $ ceph osd unset nodown $ ceph osd unset noout $ ceph osd unset nobackfill $ ceph osd unset norecover $ ceph osd unset norebalance Wait for cluster to resume operations See step #4 of this SOP. Now you wait until the cluster seems \"happy enough\" to accept clients. (i.e. rebalancing finished etc.) Maybe it will complain about MDS being down, but that's normal for now. Enable & start the ceph-mds services on each node (if CephFS is used) # systemctl enable --now ceph-mds@.service Start CephFS file systems again List all Ceph file systems $ ceph fs ls For each CephFS do: $ ceph fs down false Enable & start the radosgw services on each node (if RGW is used) # systemctl enable --now ceph-radosgw@.service","s":"Restart a Ceph cluster after manual shutdown","u":"/docs/iaas/guides/operations-guide/ceph","h":"#restart-a-ceph-cluster-after-manual-shutdown","p":1393},{"i":1475,"t":"# apt-get install -y fio #!/usr/bin/env bash BENCH_DEVICE=\"$2\" DATE=$(date +%s) IOENGINE=\"libaio\" LOGPATH=\"$1\" SIZE=1G mkdir -p $LOGPATH for RW in \"write\" \"randwrite\" \"read\" \"randread\" do for BS in \"4K\" \"64K\" \"1M\" \"4M\" \"16M\" \"64M\" do ( echo \"==== $RW - $BS - DIRECT ====\" echo 3 > /proc/sys/vm/drop_caches fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json sync echo 3 > /proc/sys/vm/drop_caches echo \"==== $RW - $BS - DIRECT IODEPTH 32 ====\" fio --rw=$RW --ioengine=${IOENGINE} --size=$SIZE --bs=$BS --iodepth=32 --direct=1 --runtime=60 --time_based --name=bench --filename=$BENCH_DEVICE --output=$LOGPATH/$RW.${BS}-direct-iod32-$(basename $BENCH_DEVICE).$DATE.log.json --output-format=json sync ) | tee $LOGPATH/$RW.$BS-$(basename $BENCH_DEVICE).$DATE.log echo done done","s":"Performance benchmark","u":"/docs/iaas/guides/operations-guide/ceph","h":"#performance-benchmark","p":1393},{"i":1477,"t":"Join the #ceph IRC channel on irc.oftc.net, state the problem with as many details as possible including information about what steps have already been taken to solve the problem also provide information from the command output from the \"60 seconds cluster overview\" above through a pastebin or a similar service. In order for people to be able to help, details and some patience are important.","s":"Where and how to get further help","u":"/docs/iaas/guides/operations-guide/ceph","h":"#where-and-how-to-get-further-help","p":1393},{"i":1480,"t":"The OpenStack Image Manager update.py Script updates the /etc/images/*.yaml files to the always latest release of the Distributions, set S3 Mirror Urls and uploads the Images to the mirror. These updated yaml files are later processed by the Image Manger itself.","s":"Overview","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","h":"#overview","p":1478},{"i":1482,"t":"Prepare to use the update.py script. git clone https://github.com/osism/openstack-image-manager/ cd openstack-image-manager pipenv install pipenv shell","s":"Installation","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","h":"#installation","p":1478},{"i":1484,"t":"python contrib/update.py --help Usage: update.py [OPTIONS] ╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ --debug Enable debug logging │ │ --dry-run Do not perform any changes │ │ --minio-access-key TEXT Minio access key [env var: MINIO_ACCESS_KEY] [default: None] │ │ --minio-secret-key TEXT Minio secret key [env var: MINIO_SECRET_KEY] [default: None] │ │ --minio-server TEXT Minio server [env var: MINIO_SERVER] [default: swift.services.a.regiocloud.tech] │ │ --minio-bucket TEXT Minio bucket [env var: MINIO_BUCKET] [default: openstack-images] │ │ --swift-prefix TEXT Swift prefix [env var: SWIFT_PREFIX] [default: swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/] │ │ --install-completion Install completion for the current shell. │ │ --show-completion Show completion for the current shell, to copy it or customize the installation. │ │ --help Show this message and exit. │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ note At this time the update.py expects all yamls Files at /etc/images/, which can't be configured at the moment. Mirroring can't be disabled at the moment. Best is to run this Script by cron or a CI job, to update all Distribution Files periodically to the latest release and afterwards run Openstack Image Manager. The Distribution Image yaml files must exists before running the script, you can use the files from Github repo at etc/images/ as template for your first run. $ python contrib/update.py 2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/centos.yml 2024-04-24 09:29:44 | INFO | update_image:179 - Checking image CentOS Stream 9 2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-HEREBE\\d+\\.\\dDRAGONS.x86_64.qcow2 2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cloud.centos.org/centos/9-stream/x86_64/images/CHECKSUM 2024-04-24 09:29:44 | INFO | get_latest_default:62 - Latest URL is now https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 2024-04-24 09:29:44 | INFO | get_latest_default:63 - Latest filename is now CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 2024-04-24 09:29:44 | INFO | update_image:192 - Checksum of current CentOS-Stream-GenericCloud-9-20240422.0.x86_64.qcow2 is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337 2024-04-24 09:29:44 | INFO | update_image:208 - Our checksum is sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337 2024-04-24 09:29:44 | INFO | update_image:211 - Image CentOS Stream 9 is up-to-date, nothing to do 2024-04-24 09:29:44 | INFO | main:300 - Processing file /etc/images/debian.yml 2024-04-24 09:29:44 | INFO | update_image:179 - Checking image Debian 11 2024-04-24 09:29:44 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bullseye/latest/debian-11-genericcloud-amd64.raw 2024-04-24 09:29:44 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bullseye/latest/SHA512SUMS 2024-04-24 09:29:45 | INFO | update_image:192 - Checksum of current debian-11-genericcloud-amd64-20240211-1654.raw is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4 2024-04-24 09:29:45 | INFO | update_image:208 - Our checksum is sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4 2024-04-24 09:29:45 | INFO | update_image:211 - Image Debian 11 is up-to-date, nothing to do 2024-04-24 09:29:45 | INFO | update_image:179 - Checking image Debian 12 2024-04-24 09:29:45 | INFO | update_image:182 - Latest download URL is https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.raw 2024-04-24 09:29:45 | INFO | update_image:185 - Getting checksums from https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS 2024-04-24 09:29:46 | INFO | update_image:192 - Checksum of current debian-12-genericcloud-amd64-daily-20240424-1727.raw is sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e 2024-04-24 09:29:46 | INFO | update_image:208 - Our checksum is sha512:5401f8c6361bb2a82c2c24b4b4606d95e77229152a80e61f9c613bc88e25de9257057d0ed68b0256b745c4059162a54970fe4a8daf456b2eb67b4f5db5c97fcc 2024-04-24 09:29:46 | INFO | update_image:229 - New values are {'version': '20240424', 'build_date': datetime.date(2024, 4, 24), 'checksum': 'sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085e', 'url': 'https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240424-1727/debian-12-genericcloud-amd64-daily-20240424-1727.raw'} 2024-04-24 09:29:46 | INFO | main:300 - Processing file /etc/images/rockylinux.yml 2024-04-24 09:29:46 | INFO | update_image:179 - Checking image Rocky 9 2024-04-24 09:29:46 | INFO | update_image:182 - Latest download URL is https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2 2024-04-24 09:29:46 | INFO | update_image:185 - Getting checksums from https://download.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2.CHECKSUM 2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current Rocky-9-GenericCloud.latest.x86_64.qcow2 is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651 2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651 2024-04-24 09:29:47 | INFO | update_image:211 - Image Rocky_9 is up-to-date, nothing to do 2024-04-24 09:29:47 | INFO | main:300 - Processing file /etc/images/ubuntu.yml 2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04 2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img 2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/jammy/current/SHA256SUMS 2024-04-24 09:29:47 | INFO | update_image:192 - Checksum of current jammy-server-cloudimg-amd64.img is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710 2024-04-24 09:29:47 | INFO | update_image:208 - Our checksum is sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710 2024-04-24 09:29:47 | INFO | update_image:211 - Image Ubuntu_22.04 is up-to-date, nothing to do 2024-04-24 09:29:47 | INFO | update_image:179 - Checking image Ubuntu 22.04 Minimal 2024-04-24 09:29:47 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64.img 2024-04-24 09:29:47 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/minimal/releases/jammy/release/SHA256SUMS 2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current ubuntu-22.04-minimal-cloudimg-amd64.img is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65 2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65 2024-04-24 09:29:48 | INFO | update_image:211 - Image Ubuntu 22.04 Minimal is up-to-date, nothing to do 2024-04-24 09:29:48 | INFO | update_image:179 - Checking image Ubuntu 24.04 2024-04-24 09:29:48 | INFO | update_image:182 - Latest download URL is https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img 2024-04-24 09:29:48 | INFO | update_image:185 - Getting checksums from https://cloud-images.ubuntu.com/noble/current/SHA256SUMS 2024-04-24 09:29:48 | INFO | update_image:192 - Checksum of current noble-server-cloudimg-amd64.img is sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3 2024-04-24 09:29:48 | INFO | update_image:208 - Our checksum is sha256:d7ba8d5d1d073f2dc8351973bf4f35157c846a0ea6ee16fb2a9f45a78953e4a7 2024-04-24 09:29:48 | INFO | update_image:229 - New values are {'version': '20240423', 'build_date': datetime.date(2024, 4, 23), 'checksum': 'sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3', 'url': 'https://cloud-images.ubuntu.com/noble/20240423/noble-server-cloudimg-amd64.img'} These yaml files are now extended with additional fields and the update.py will take care of the versions, checksum, url and build date to the latest release in the yaml file on every run. latest_checksum_url - URL of the distros checksum file latest_url - URL of the distros latest image mirror_url - URL of the Image File at the local S3 Mirror someexample.yaml --- images: - name: Debian 12 enable: true shortname: debian-12 format: qcow2 login: debian min_disk: 8 min_ram: 512 status: active visibility: public multi: true meta: architecture: x86_64 hw_disk_bus: scsi hw_rng_model: virtio hw_scsi_model: virtio-scsi hw_watchdog_action: reset hypervisor_type: qemu os_distro: debian os_version: '12' replace_frequency: quarterly uuid_validity: last-3 provided_until: none tags: [] latest_checksum_url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/SHA512SUMS latest_url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian-12-genericcloud-amd64-daily.qcow2 versions: - build_date: 2024-04-11 checksum: sha512:3d6f26616e2c8b705993ddef874232887cebe42f1e70fcc020827ac88e8990177d537d34538c71ae2afd3b8baca953fff71eaa7ef71e752e82532c93dcdca436 url: https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240411-1714/debian-12-genericcloud-amd64-daily-20240411-1714.qcow2 mirror_url: https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-images/debian-12/20240411-debian-12.qcow2 version: '20240411'","s":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/update","h":"#usage","p":1478},{"i":1487,"t":"The OpenStack Flavor Manager manages the creation, modification, and removal of flavors. It operates as a facilitator that orchestrates compute flavors in alignment with the standard SCS-0100: Flavor Naming by utilizing YAML files provided by the SCS project.","s":"Overview","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#overview","p":1485},{"i":1489,"t":"The OpenStack Flavor Manager can be used via the OSISM CLI. This is the preferred way to use it. No installation is then required. It is used via osism manage flavors. For use independent of OSISM install the openstack-flavor-manager package with pip. It is likely that additional dependencies such as pkg-config or libssl-dev must be installed in advance. $ pip install openstack-flavor-manager Or clone the repository osism/openstack-flavor-manager and use the OpenStack Flavor Manager from source with tox. $ tox -- --help","s":"Installation","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#installation","p":1485},{"i":1491,"t":"There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Flavor Manager will be executed. When using the OSISM CLI, the files are expected in environments/openstack in your configuration repository. The cloud profile to be used can be specified via the optional --cloud parameter. By default the cloud profile with the name admin is used. It must be possible to create and delete flavors with the used cloud credentials. $ openstack-flavor-manager --help Usage: openstack-flavor-manager [OPTIONS] ╭─ Options ────────────────────────────────────────────────────────────────────────────────────╮ │ --name TEXT Name of flavor definitions. [default: scs] │ │ --debug Enable debug logging. │ │ --cloud TEXT Cloud name in clouds.yaml. [default: admin] │ │ --recommended Create recommended flavors. │ │ --help Show this message and exit. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ To create the mandatory flavors by the SCS-0100: Flavor Naming standard, you run: $ openstack-flavor-manager To create the recommended flavors by the SCS Flavor Naming Standard, you run: $ openstack-flavor-manager --recommended The output should look like this: 2023-09-20 13:03:14 | INFO | Flavor SCS-1V-4 created 2023-09-20 13:03:14 | INFO | Flavor SCS-2V-8 created 2023-09-20 13:03:14 | INFO | Flavor SCS-4V-16 created 2023-09-20 13:03:14 | INFO | Flavor SCS-8V-32 created ... All recommended flavors are now be available in your OpenStack environment. Check yourself by running: $ openstack --os-cloud admin flavor list $ openstack --os-cloud admin flavor show SCS-2V-4-20s +----------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | Field | Value | +----------------------------+---------------------------------------------------------------------------------------------------------------------------------+ | OS-FLV-DISABLED:disabled | False | | OS-FLV-EXT-DATA:ephemeral | 0 | | access_project_ids | None | | description | None | | disk | 20 | | id | 652e3a6c-330e-4ee3-922b-b49c3c093062 | | name | SCS-2V-4-20s | | os-flavor-access:is_public | True | | properties | hw_rng:allowed='true', scs:cpu-type='shared-core', scs:disk0-type='ssd', scs:name-v1='SCS-2V:4:20s', scs:name-v2='SCS-2V-4-20s' | | ram | 4096 | | rxtx_factor | 1.0 | | swap | 0 | | vcpus | 2 | +----------------------------+---------------------------------------------------------------------------------------------------------------------------------+","s":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#usage","p":1485},{"i":1493,"t":"There are two flavor definitions available by default. One for SCS and one for OSISM. Each definition has its own set of mandatory and recommended flavors. The definition of OSISM contains all definitions of SCS as well as some others. To run the OpenStack Flavor Manager with a specific definition, either scs or osism, use the optional --name parameter. By default the SCS-0100: Flavor Naming standard definition will be used. $ openstack-flavor-manager --name osism","s":"Definitions","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#definitions","p":1485},{"i":1495,"t":"A generator and parser for flavor names according to the SCS standard is available on flavors.scs.community. The flavor name SCS-2V-4-20s is inserted in field Flavor name: The flavor SCS-2V-4-20s translated is 2 generic x86-64 vCPUs with 4.0 GiB RAM and SSD 20GB root volume:","s":"Name parser and generator","u":"/docs/iaas/guides/operations-guide/openstack/tools/flavor-manager","h":"#name-parser-and-generator","p":1485},{"i":1498,"t":"The OpenStack Project Manager manages the creation of Openstack Domains, Projects and Users.","s":"Overview","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#overview","p":1496},{"i":1500,"t":"Prepare to use the Openstack Project Manager. During installation, ldap libraries are required under Linux; you should install libldap2-dev and libsasl2-dev beforehand. git clone https://github.com/osism/openstack-project-manager cd openstack-project-manager pipenv install pipenv shell","s":"Installation","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#installation","p":1496},{"i":1503,"t":"The create.py command and his default options while executing the command. --admin-domain default --assign-admin-user true --cloud admin --create-admin-user true --create-domain false --create-user false --domain-name-prefix true --has-service-network false --has-public-network true --has-shared-images true --internal-id unset --random false --managed-network-resources false --name sandbox --owner unset --password unset --password-length 16 --public-network public --quota-class basic --service-network-cidr unset --quota-multiplier 1 --quota-multiplier-compute unset --quota-multiplier-network unset --quota-multiplier-storage unset --quota-router 1","s":"create.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#createpy","p":1496},{"i":1505,"t":"The manage.py has also some defaults while executing and will touch all projects in your Openstack Cluster, if not --domain is used. --admin-domain default --assign-admin-user false --classes etc/classes.yml --domain unset --dry-run false --endpoints etc/endpoints.yml --manage-endpoints false --manage-homeprojects false --name unset Default Openstack Roles to users are set to member and load-balancer_member at this time, the behavior can only be changed in the code.","s":"manage.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#managepy","p":1496},{"i":1507,"t":"There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Project Manager will be executed, examples are provided within the git repository. The cloud profile to be used can be specified via the optional --cloud parameter. By default the cloud profile with the name admin is used. It has to be and admin account, to create and modify domains, projects, users and quotas. The Openstack Project Manager essentially consists of two parts, the create.py and the manage.py, there are more scripts for handling users using ldap which needs more configuration setup.","s":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#usage","p":1496},{"i":1509,"t":"This command is used to create and modify domains, projects, users and quotas. As default the domain is used as prefix for all projects and users created for easy alloction in Openstack. note create.py can't delete once created objects, this must be done using Openstack commands to remove a project or domain. python src/create.py -h usage: create [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--create-admin-user] [--create-domain] [--create-user] [--domain DOMAIN] [--domain-name-prefix] [--has-public-network] [--has-service-network] [--has-shared-images] [--internal-id INTERNAL_ID] [--managed-network-resources] [--name NAME] [--noassign-admin-user] [--nocreate-admin-user] [--nocreate-domain] [--nocreate-user] [--nodomain-name-prefix] [--nohas-public-network] [--nohas-service-network] [--nohas-shared-images] [--nomanaged-network-resources] [--norandom] [--owner OWNER] [--password PASSWORD] [--password-length PASSWORD_LENGTH] [--public-network PUBLIC_NETWORK] [--quota-class QUOTA_CLASS] [--quota-multiplier QUOTA_MULTIPLIER] [--quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE] [--quota-multiplier-network QUOTA_MULTIPLIER_NETWORK] [--quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE] [--quota-router QUOTA_ROUTER] [--random] [--service-network-cidr SERVICE_NETWORK_CIDR] options: -h, --help show this help message and exit --admin-domain ADMIN_DOMAIN Admin domain --assign-admin-user Assign admin user --cloud CLOUD Managed cloud --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the command-line. --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the command-line. --create-admin-user Create admin user --create-domain Create domain only --create-user Create user --domain DOMAIN Domain --domain-name-prefix Add domain name as prefix to the project name --has-public-network Has public network infrastructure --has-service-network Has service network infrastructure --has-shared-images Has shared images --internal-id INTERNAL_ID Internal ID --managed-network-resources Manage the network resources --name NAME Projectname --noassign-admin-user The inverse of --assign-admin-user --nocreate-admin-user The inverse of --create-admin-user --nocreate-domain The inverse of --create-domain --nocreate-user The inverse of --create-user --nodomain-name-prefix The inverse of --domain-name-prefix --nohas-public-network The inverse of --has-public-network --nohas-service-network The inverse of --has-service-network --nohas-shared-images The inverse of --has-shared-images --nomanaged-network-resources The inverse of --managed-network-resources --norandom The inverse of --random --owner OWNER Owner of the project --password PASSWORD Password --password-length PASSWORD_LENGTH Password length --public-network PUBLIC_NETWORK Public network --quota-class QUOTA_CLASS Quota class --quota-multiplier QUOTA_MULTIPLIER Quota multiplier --quota-multiplier-compute QUOTA_MULTIPLIER_COMPUTE Quota multiplier compute --quota-multiplier-network QUOTA_MULTIPLIER_NETWORK Quota multiplier network --quota-multiplier-storage QUOTA_MULTIPLIER_STORAGE Quota multiplier storage --quota-router QUOTA_ROUTER Quota router --random Generate random names --service-network-cidr SERVICE_NETWORK_CIDR Service network CIDR Create a Domain and inital project​ When executing the create.py command, the first time with --domain, it will create a new domain, an admin account and the first project webshop. The admin account will be created in the default Domain of Openstack and can be used for the Service Provider to manager the complete domain. $ python3 src/create.py --domain democompany --name webshop +----------------+----------------------+----------------------------------+ | name | value | id | |----------------+----------------------+----------------------------------| | domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 | | project | democompany-webshop | 645538bf67664cfeaed32476d58f95fb | | admin | democompany-admin | cc8d6bf7b61d4199ba5a4230c4ec6d62 | | admin_password | qawsEdfg2d45Fsxc | | +----------------+----------------------+----------------------------------+ Create a User for a project​ $ python3 src/create.py --domain democompany --name webshopuser --create-user +----------+-------------------------+----------------------------------+ | name | value | id | |----------+-------------------------+----------------------------------| | domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 | | project | democompany-webshop | 5752b6701026478f9cac122fc54eb9cb | | user | democompany-webshopuser | ce213655559d47d7800501124fed4d02 | | password | vEvM9vgRESdffWE2 | | +----------+-------------------------+----------------------------------+ Create additional project with unlimited quota​ $ python3 src/create.py --domain democompany --name styles --quota-class unlimited +----------+--------------------+----------------------------------+ | name | value | id | |----------+--------------------+----------------------------------| | domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 | | project | democompany-styles | 666097e396fd4f9392d6aa55c76d8267 | +----------+--------------------+----------------------------------+ Set quotas for a project​ All quota information must be set as a property to the Openstack project within your Openstack Cluster, if no property is set, the basic quotaclass of etc/classes.yml will be applied. It is possible to set a quota multiplier for any project. The following command you set a multiplier of 256 of the basic quota: $ openstack project set --property quotamultiplier=256 democompany-webshop Adjusting gigabyte quota for storage with a multiplier of 20 of the basic quota for a project: $ openstack project set --property quotamultiplier_storage=20 democompany-webshop This will override the general quotamultiplier only for storage. Other possible multiplier which can be set individually are: quotamultiplier_compute, quotamultiplier_network, quota_router To change the quotaclass to unlimited from the etc/classes.yaml $ openstack project set --property quotaclass=unlimited democompany-webshop Special project: images​ With this special Project you can share all images uploaded into this project to all other project in your domain which has set the property has-shared-images, which is by default set. Alsoi only the domain-admin user has access to this project, other domain users won't see this, they will find the uploaded images in their projects. If you want your grant other domain users also access to upload some images, you need to give them access to the images Project in Openstack. $ python3 src/create.py --domain democompany --name images +---------+---------------------+----------------------------------+ | name | value | id | |---------+---------------------+----------------------------------| | domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 | | project | democompany-images | 6d57f39aacbe485d87733865b1e79d03 | +---------+---------------------+----------------------------------+ Additionally you need to add the domain and domain-admin user to the clouds.yaml, it is always named opm-domainname-admin: so the manage.py can setup permissions to the projects later on and users are able to find the images. opm-democompany-admin: auth: auth_url: https://keystone.my.cloud:5000/v3 username: democompany-admin password: yourpassword user_domain_name: Default project_domain_name: democompany identity_api_version: 3 Special project: service​ With this special project you can share installed services, like a harbor, to all other projects in your domain. Per default, only the domain admin has access to this project. $ python3 src/create.py --domain democompany --name service +---------+---------------------+----------------------------------+ | name | value | id | |---------+---------------------+----------------------------------| | domain | democompany | a8549ef5d3d14f938b127a1cdefe3788 | | project | democompany-service | a5558f7338f94adea5f41858636256b5 | +---------+---------------------+----------------------------------+","s":"create.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#createpy-1","p":1496},{"i":1511,"t":"warning This command applies quotas, networks and routers to all projects in the Openstack Cluster, not only to those have been configured previously with the create.py or openstack project set --property commands. Best is to run this command by cron, every hour to apply all pending changes, it is also possible to run this at the command line to apply changes immediately. python3 src/manage.py -h usage: manage [-h] [--admin-domain ADMIN_DOMAIN] [--assign-admin-user] [--classes CLASSES] [--cloud CLOUD] [--config-dir DIR] [--config-file PATH] [--domain DOMAIN] [--dry-run] [--endpoints ENDPOINTS] [--manage-endpoints] [--manage-homeprojects] [--name NAME] [--noassign-admin-user] [--nodry-run] [--nomanage-endpoints] [--nomanage-homeprojects] options: -h, --help show this help message and exit --admin-domain ADMIN_DOMAIN Admin domain --assign-admin-user Assign admin user --classes CLASSES Path to the classes.yml file --cloud CLOUD Cloud name in clouds.yaml --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This option must be set from the command-line. --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the command-line. --domain DOMAIN Domain to be managed --dry-run Do not really do anything --endpoints ENDPOINTS Path to the endpoints.yml file --manage-endpoints Manage endpoints --manage-homeprojects Manage home projects --name NAME Project to be managed --noassign-admin-user The inverse of --assign-admin-user --nodry-run The inverse of --dry-run --nomanage-endpoints The inverse of --manage-endpoints --nomanage-homeprojects The inverse of --manage-homeprojects Manage a specific domain only​ $ python3 src/manage.py --domain democompany 2024-04-19 14:24:02.873 | INFO | democompany - domain_id = a8549ef5d3d14f938b127a1cdefe3788 2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03 2024-04-19 14:24:04.886 | INFO | democompany-images - project_id = 6d57f39aacbe485d87733865b1e79d03, domain_id = a8549ef5d3d14f938b127a1cdefe3788 2024-04-19 14:24:04.953 | INFO | democompany-images - quotaclass {'compute': {'cores': 0, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 0, 'key_pairs': 0, 'metadata_items': 128, 'ram': 0, 'server_group_members': 0, 'server_groups': 0}, 'network': {'floatingip': 0, 'network': 0, 'port': 0, 'rbac_policy': 0, 'router': 0, 'security_group': 0, 'security_group_rule': 0, 'subnet': 0, 'subnetpool': 0}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 1000, 'per_volume_gigabytes': 25, 'snapshots': 0, 'volumes': 100}, 'parent': 'default'} 2024-04-19 14:24:04.953 | INFO | democompany-images - check network quota 2024-04-19 14:24:05.048 | INFO | democompany-images - check compute quota 2024-04-19 14:24:05.175 | INFO | democompany-images - check volume quota 2024-04-19 14:24:05.286 | INFO | democompany-images - check if external rbac policy must be deleted (public) 2024-04-19 14:24:05.349 | INFO | democompany-images - check if service rbac policy must be deleted (democompany-service) 2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5 2024-04-19 14:24:06.081 | INFO | democompany-service - project_id = a5558f7338f94adea5f41858636256b5, domain_id = a8549ef5d3d14f938b127a1cdefe3788 2024-04-19 14:24:06.131 | INFO | democompany-service - quotaclass {'compute': {'cores': 256, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': 256, 'key_pairs': 256, 'metadata_items': 128, 'ram': 262144, 'server_group_members': 256, 'server_groups': 256}, 'network': {'floatingip': 256, 'network': 256, 'port': 256, 'rbac_policy': 1024, 'router': 256, 'security_group': 256, 'security_group_rule': 1024, 'subnet': 256, 'subnetpool': 256}, 'volume': {'backup_gigabytes': 0, 'backups': 0, 'gigabytes': 0, 'per_volume_gigabytes': 0, 'snapshots': 0, 'volumes': 0}, 'parent': 'default'} 2024-04-19 14:24:06.131 | INFO | democompany-service - check network quota 2024-04-19 14:24:06.212 | INFO | democompany-service - check compute quota 2024-04-19 14:24:06.330 | INFO | democompany-service - check volume quota 2024-04-19 14:24:06.467 | INFO | democompany-service - check if external rbac policy must be created (public) 2024-04-19 14:24:06.589 | INFO | democompany-service - check if service rbac policy must be deleted (democompany-service) 2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb 2024-04-19 14:24:06.840 | INFO | democompany-webshop - project_id = 5752b6701026478f9cac122fc54eb9cb, domain_id = a8549ef5d3d14f938b127a1cdefe3788 2024-04-19 14:24:06.915 | INFO | democompany-webshop - quotaclass {'compute': {'cores': 4, 'injected_file_content_bytes': 10240, 'injected_file_path_bytes': 255, 'injected_files': 5, 'instances': -1, 'key_pairs': 4, 'metadata_items': 128, 'ram': 8192, 'server_group_members': 4, 'server_groups': 4}, 'network': {'floatingip': 4, 'network': 1, 'port': 20, 'rbac_policy': 10, 'router': 0, 'security_group': 5, 'security_group_rule': 20, 'subnet': 2, 'subnetpool': 1}, 'volume': {'backup_gigabytes': 40, 'backups': 8, 'gigabytes': 20, 'per_volume_gigabytes': 200, 'snapshots': 4, 'volumes': 4}, 'parent': 'default'} 2024-04-19 14:24:06.915 | INFO | democompany-webshop - check network quota 2024-04-19 14:24:06.993 | INFO | democompany-webshop - check compute quota 2024-04-19 14:24:07.114 | INFO | democompany-webshop - check volume quota 2024-04-19 14:24:07.254 | INFO | democompany-webshop - check if external rbac policy must be created (public) 2024-04-19 14:24:07.334 | INFO | democompany-webshop - check if service rbac policy must be deleted (democompany-service)","s":"manage.py","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#managepy-1","p":1496},{"i":1513,"t":"The config files which can be used for create.py and manage.py are using the oslo.config format, you can set the command line options as key = value pair and create your own config files matching your setup. democompany.conf [DEFAULT] cloud = admin domain = democompany","s":"Config files","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#config-files","p":1496},{"i":1515,"t":"Edit the etc/classes.yml file if you want to change or add new quota templates","s":"Quota Templates","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#quota-templates","p":1496},{"i":1517,"t":"Edit the etc/endpoints.yml file to fit your available endpoints","s":"Setup Endpoints","u":"/docs/iaas/guides/operations-guide/openstack/tools/project-manager","h":"#setup-endpoints","p":1496},{"i":1519,"t":"The OpenStack Image Manager is a tool for managing all images on an OpenStack environment","s":"Image Manager","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"","p":1518},{"i":1521,"t":"This information is only relevant for the operator of an OpenStack environment. You can skip this section if you want to use OpenStack Image Manager as a normal user and you are not an operator of an openStack environment.","s":"Requirements","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#requirements","p":1518},{"i":1523,"t":"The OpenStack Image Service (Glance) is required to upload and discover data assets that are used by other services. Since this script stores many images in a single project, the Glance quota must be set accordingly high or to unlimited. [DEFAULT] user_storage_quota = 1TB With most storage backends it makes sense to convert the imported images directly to RAW. So it is required for using Ceph and it's features too. Recited from the Ceph documentation QEMU and block devices and Block devices and OpenStack. info The raw data format is really the only sensible format option to use with RBD. Technically, you could use other QEMU-supported formats (such as qcow2 or vmdk), but doing so would add additional overhead, and would also render the volume unsafe for virtual machine live migration when caching (see below) is enabled. Important Ceph doesn't support QCOW2 for hosting a virtual machine disk. Thus if you want to boot virtual machines in Ceph (ephemeral backend or boot from volume), the Glance image format must be RAW. See the OpenStack Glance documentation for more details. This requires the following parameter for the image import workflow. [taskflow_executor] conversion_format = raw [image_import_opts] image_import_plugins = ['image_decompression', 'image_conversion'] [image_conversion] output_format = raw","s":"OpenStack Image Service (Glance)","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#openstack-image-service-glance","p":1518},{"i":1525,"t":"If the mirror functionality is used, an object storage backend is required. The use of the mirror functionality is optional and is not used by default.","s":"Object storage backend","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#object-storage-backend","p":1518},{"i":1527,"t":"This Getting started will upload a private image to your OpenStack environment with the help of the OpenStack Image Manager. Install the openstack-image-manager package with pip. pip3 install openstack-image-manager The installation can also be done via pipenv. A Pipefile file is created with this content. The latest version of openstack-image-manager is used. [[source]] url = \"https://pypi.org/simple\" verify_ssl = true name = \"pypi\" [packages] openstack-image-manager = \"==0.20240403.0\" [dev-packages] [requires] python_version = \"3.10\" The dependencies are then installed and the shell is prepared for use: pipenv install pipenv shell Create a image definition in the file getting-started.yml in the local directory images. --- images: - name: MyCirros format: qcow2 login: cirros password: gocubsgo min_disk: 1 min_ram: 32 status: active visibility: private multi: false meta: architecture: x86_64 hw_disk_bus: scsi hw_rng_model: virtio hw_scsi_model: virtio-scsi hw_watchdog_action: reset os_distro: cirros replace_frequency: never uuid_validity: none provided_until: none tags: [] versions: - version: \"0.6.0\" url: https://github.com/cirros-dev/cirros/releases/download/0.6.0/cirros-0.6.0-x86_64-disk.img checksum: \"sha256:94e1e2c94dbbae7d4bdc38e68590a1daf73c9de2d03dd693857b4b0a042548e8\" build_date: 2022-09-28 Run the OpenStack Image Manager. It is assumed that a profile with the name openstack exists in the clouds.yaml. openstack-image-manager --cloud openstack --filter \".*Cirr.*\" --images images/","s":"Getting started","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#getting-started","p":1518},{"i":1529,"t":"The configuration consists of different parameter settings, such as values for minimum RAM or the visibility of the image. Have a look at the examples below for all parameters. After a change to the configuration, validate it with tox -- --dry-run.","s":"Image definitions","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#image-definitions","p":1518},{"i":1531,"t":"The value of login is stored as image_original_user in the metadata of an image. If image_description is not set as meta information, image_description is set to the name of the image. The value of build_date of a specific version of an image is stored as image_build_date in the metadata of an image. The value of url of a specific version of an image is stored as image_source in the metadata of an image.","s":"SCS image standard","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#scs-image-standard","p":1518},{"i":1533,"t":"This type of image definition is used for images that are rebuilt at regular intervals. For example, this is the case for the daily builds of the Ubuntu images. The attribute multi: true is set. With this type of image definition, the version of the distribution (or product, whatever is contained in the image) used is already in the name of the image definition. The version properties from the definition's versions list are appended only to older iterations of the image as timestamp suffixes in parentheses upon each rotation (except for the latest entry). images: - name: Ubuntu 24.04 format: qcow2 login: ubuntu min_disk: 8 min_ram: 512 status: active visibility: public multi: true meta: architecture: x86_64 hw_disk_bus: scsi hw_scsi_model: virtio-scsi hw_watchdog_action: reset os_distro: ubuntu os_version: '24.04' tags: [] versions: - version: '20240416' url: https://cloud-images.ubuntu.com/noble/20240416/noble-server-cloudimg-amd64.img - version: '20240422' url: https://cloud-images.ubuntu.com/noble/20240422/noble-server-cloudimg-amd64.img This configuration creates the following images: Ubuntu 24.04 (20240416) Ubuntu 24.04 If a newer build is added, the following rotation takes place: Ubuntu 24.04 (20240416) does not change Ubuntu 24.04 becomes Ubuntu 24.04 (20240422) the new image becomes Ubuntu 24.04 By default the last three images will be visible. When a fourth image is added, the visibility of the last image in the list is changed to community and the image can be deleted in the future.","s":"Image with regular rebuilds","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#image-with-regular-rebuilds","p":1518},{"i":1535,"t":"This type of image definition is used for images that are not rebuilt. For example, this is the case for the flatcar images. For each release of Flatcar there is exactly one image which will not be rebuilt in the future. The attribute multi: false is set. With this type of image definition, the version of the distribution (or product, whatever is contained in the image) used is not in the name of the image definition. Instead, the version properties from the image definition's versions list are appended as static version suffixes to the images' names. images: - name: RancherOS format: qcow2 login: rancher min_disk: 8 min_ram: 2048 status: active visibility: public multi: false meta: architecture: x86_64 hw_disk_bus: scsi hw_scsi_model: virtio-scsi hw_watchdog_action: reset tags: [] versions: - version: '1.3.0' url: https://github.com/rancher/os/releases/download/v1.3.0/rancheros-openstack.img - version: '1.4.0' url: https://github.com/rancher/os/releases/download/v1.4.0/rancheros-openstack.img - version: '1.4.1' url: https://github.com/rancher/os/releases/download/v1.4.1/rancheros-openstack.img This configuration creates the following images: RancherOS 1.3.0 RancherOS 1.4.0 RancherOS 1.4.1 If a new version is added, no rotation takes place. The new version is added as RancherOS x.y.z. Here also the visibility of older images is not changed.","s":"Image without regular rebuild","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#image-without-regular-rebuild","p":1518},{"i":1537,"t":"Image properties​ Removal of properties is not yet possible URL, name and format can not be changed Any keys can be added to meta, these will be added to the image Existing keys in meta can be changed, the same applies to min_disk and min_ram Image tags​ image status​ deactivation: change status to deactivated reactivation: change status to active Image visibility​ A full documentation about the visibility of images can be found in the Image visibility section in the OpenStack Image Service API Documentation. public: set visibility to public community: set visibility to community shared: set visibility to shared private: set visibility to private","s":"Other properties","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#other-properties","p":1518},{"i":1540,"t":"Since the upstreams often only keep their images for a short time, we mirror most of the images on REGIO.cloud. This makes us independent of the availability of the images in the individual upstreams.","s":"Mirroring images","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#mirroring-images","p":1518},{"i":1542,"t":"Some of the images are automatically updated by a CI job. The latest available build at the time of the CI job execution is mirrored and made available as the current version. Currently, the following images are updated once a week (every Sunday at 0 am): Almalinux CentOS Debian Rockylinux Ubuntu","s":"Updating images","u":"/docs/iaas/guides/operations-guide/openstack/tools/image-manager/","h":"#updating-images","p":1518},{"i":1545,"t":"Prepare use of the OpenStack Resource Manager. git clone https://github.com/osism/openstack-resource-manager cd openstack-resource-manager pipenv install pipenv shell Prepare cloud profile admin in clouds.yml and secure.yml (use clouds.yml.sample and secure.yml.sample in the openstack-resource-manager repository as sample files).","s":"Preparations","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#preparations","p":1543},{"i":1548,"t":"Live migrate all instances from compute node SOURCE to compute node TARGET. python3 src/host-action.py --yes --disable --action live-migrate --host SOURCE --input TARGET","s":"Live migration","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#live-migration","p":1543},{"i":1550,"t":"Evacuate all instances from compute node SOURCE to compute node TARGET. python3 src/host-action.py --yes --action evacutate --host SOURCE --input TARGET","s":"Evacuation","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#evacuation","p":1543},{"i":1553,"t":"Rotation of amphorae older than 30 days. $ python3 src/amphora.py --rotate 2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa is older than 30 days 2023-10-12 21:00:38 | INFO | Amphora 95a07c43-c0f9-44d2-bde8-a989e52427fa of loadbalancer 9008d3d7-f593-4bc3-941c-a740c178148d is rotated by a loadbalancer failover","s":"Amphora rotation","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#amphora-rotation","p":1543},{"i":1555,"t":"$ python3 src/volume.py 2023-12-11 23:09:44 | INFO | Volume ad848454-ba1f-4c28-b9a8-edada17948b0 hangs in CREATING status for more than 2 hours Delete volume ad848454-ba1f-4c28-b9a8-edada17948b0 [yes/no]:","s":"Cinder","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#cinder","p":1543},{"i":1557,"t":"$ python3 src/orphan.py 2023-12-11 23:11:16 | INFO | Checking nova / server 2023-12-11 23:11:21 | INFO | Checking neutron / port 2023-12-11 23:11:23 | INFO | Checking neutron / router 2023-12-11 23:11:23 | INFO | Checking neutron / network 2023-12-11 23:11:24 | INFO | Checking neutron / subnet 2023-12-11 23:11:24 | INFO | Checking neutron / floatingip 2023-12-11 23:11:24 | INFO | Checking neutron / rbacpolicy 2023-12-11 23:11:24 | INFO | Checking neutron / securitygroup 2023-12-11 23:11:26 | INFO | Checking neutron / securitygrouprule 2023-12-11 23:11:27 | INFO | Checking glance / image 2023-12-11 23:11:30 | INFO | Checking glance / imagemember [...] +---------------+-------------------+--------------------------------------+----------------------------------+ | servicename | resourcename | resource_id | project_id | |---------------+-------------------+--------------------------------------+----------------------------------| | neutron | port | 561f8f76-18b0-470a-92cd-4336346b4b18 | 3cfa8679f5d8429382b95d4d2dd80f79 | | neutron | port | 6d1986e4-1e6d-4d4a-961d-97d372945bb1 | 3cfa8679f5d8429382b95d4d2dd80f79 | | neutron | port | 74f9bddc-9bfa-4d06-a147-ca87127e501e | 8268b05ef24b41d8806c0fe417576610 | | neutron | port | f630a66b-7725-4a68-868b-caebbaf1c003 | 8268b05ef24b41d8806c0fe417576610 | | neutron | router | c0c4e4aa-53ee-4fd1-8f53-84d52cf6c60b | 3cfa8679f5d8429382b95d4d2dd80f79 | | neutron | router | c8f9a13b-adcd-4a8e-942b-338bcf4dde7c | 8268b05ef24b41d8806c0fe417576610 | | neutron | network | 62d6ad2a-0cda-4d45-9325-963b8eb67000 | 8268b05ef24b41d8806c0fe417576610 | | neutron | network | 63b8fea6-7d7b-40c3-9c31-bee4404a92d6 | 3cfa8679f5d8429382b95d4d2dd80f79 | | neutron | subnet | 0cd16262-330a-44ad-9160-daef84aded2d | 3cfa8679f5d8429382b95d4d2dd80f79 | | neutron | subnet | 690dee14-ac12-464d-a911-a873c27ec818 | d33b0d15fd474131a335207216297a2a | | neutron | subnet | 854e7c55-62e2-4679-9b18-805460b998ce | 8268b05ef24b41d8806c0fe417576610 | | neutron | rbacpolicy | 00d7c2a2-6674-4f40-9f95-176a7858fcca | c8e4393b6d064a26a31014f82939172f | | neutron | rbacpolicy | 0608c701-5b81-4712-989b-ba03cdcc255d | c8e4393b6d064a26a31014f82939172f | [...] | neutron | securitygrouprule | fd3c553f-168e-4c24-ab40-09aa934bab86 | 3a96207b719643ae9ea9a81d95116e9e | | neutron | securitygrouprule | fdf337be-971c-4d5d-88ca-d90cdb468e88 | 3cfa8679f5d8429382b95d4d2dd80f79 | | neutron | securitygrouprule | ff8162fe-f053-49c9-8659-078061ce3e23 | d0b0add9ede0452791f71cb900e35242 | | glance | imagemember | c7f2cb0c25d34c5d886ecaf483e5fda6 | c7f2cb0c25d34c5d886ecaf483e5fda6 | | glance | imagemember | d4d0a161f9024fc8b517b0375eb97c89 | d4d0a161f9024fc8b517b0375eb97c89 | | glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 | | glance | imagemember | 150688b82efa44a5ac452d2b937f16e5 | 150688b82efa44a5ac452d2b937f16e5 | | glance | imagemember | d33b0d15fd474131a335207216297a2a | d33b0d15fd474131a335207216297a2a | | cinder | volume | e7c4b05c-b76a-40cc-8381-03262e57eb94 | 9b5f7f8ed70d410c81e3f45bf4e36498 | +---------------+-------------------+--------------------------------------+----------------------------------+","s":"Orphans","u":"/docs/iaas/guides/operations-guide/openstack/tools/resource-manager","h":"#orphans","p":1543},{"i":1560,"t":"💡 Cloud in a Box (CiaB) is a minimalistic installation of the latest stable OSISM release with only services which are needed to make it work with Kubernetes. It is intended for use as a development system on bare-metal or for use in edge environments. warning At the moment the secrets are stored in plain text in the osism/cloud-in-a-box repository and are not secure. Do not use for public accessible systems. In the future, the secrets will be generated automatically.","s":"Cloud in a Box - CiaB","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"","p":1559},{"i":1562,"t":"The system to be used as Cloud in a Box must fulfill these minimum requirements. Type of resource Amount Note CPU at least 1 socket with 4 cores More is better here. This is the minimum where you can't use much payload (LBaaS, VMs). The use of Kubernetes with Cluster API is not possible with this minimum size. RAM at least 32 GByte More is better here. In principle, it also works with 8 GByte, but then no payload (LBaaS, VMs) can be used. Kubernetes with Cluster API cannot be used then. Storage at least 1 TByte Has to be available as /dev/sda or /dev/nvme0n1. Less than 1 TByte is also possible, the smaller the less storage is available for use in Ceph. Network at least 1 network interface (DHCP and internet access) An optional 2nd network interface can be used for external connectivity. USB stick at least 2 GByte Installation media for Cloud in a Box bootstrapping","s":"Requirements","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#requirements","p":1559},{"i":1564,"t":"There are two types of Cloud in a Box. The sandbox type is intended for developers and demonstrations. A full OSISM installation is one there which also includes Ceph and OpenSearch, for example. In the course of the installation, necessary images, networks, etc. are also created. The edge type is intended to be deployed as an appliance to provide an edge cloud on a single node. Compared to the sandbox, certain services are not provided there or are implemented differently. For example, OpenSearch is not deployed because the logs are delivered to a central location. The storage backend will also be implemented differently there in the future instead of Ceph.","s":"Types","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#types","p":1559},{"i":1566,"t":"Load balancing in Octavia is only possible via OVN. The Amphora driver is not supported. This is due to the limited resources we have. With the Amphora driver, a dedicated instance is started for each load balancer, each of which consumes 1 GByte of memory. This represents a very high consumption in relation to the usual sizes of the Cloud in a Box.","s":"General notes and limitations","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#general-notes-and-limitations","p":1559},{"i":1569,"t":"The images currently download and install the latest state of the installation scripts, therefore it is mandatory to update the installation media at least when the underlying Ubuntu operating system release changes. The installation of older releases is currently not supported. Download one of the Cloud in a Box images of type sandbox ubuntu-autoinstall-cloud-in-a-box-1.iso (with first block device as /dev/sda) ubuntu-autoinstall-cloud-in-a-box-2.iso (with first block device as /dev/nvme0n1) Use a tool like balenaEtcher or dd to create a bootable USB stick with the Cloud in a Box image. Boot from the USB stick. Make sure that the boot from USB is activated in the BIOS. warning When booting from this USB stick, all data on the hard disks will be destroyed without confirmation. The installation of the operating system (Ubuntu 22.04) will start and take a few minutes. After that the system will shutdown. The first start of the system Remove the USB storage device (The USB stick is only needed again if the Cloud in a Box system is to be fully reinstalled.) Connect the first network interface to an ethernet interface that provides access to the internet via DHCP configuration Boot the system from the internal hard disk device The deployment will start. This takes some time and the system will shutdown when the deployment is finished. This takes roughly an hour, possibly longer depending on the hardware and internet connection. Start the system again. System is ready for use, by default DHCP is tried on the first network device. Login via SSH. Use the user dragon with the password password. (You can obtain the ip address by inspecting the logs of your dhcp server or from the issue text of the virtual consoles of the system) ssh dragon@IP_FROM_YOUR_SERVER passwd","s":"Automated installation (recommended)","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#automated-installation-recommended","p":1559},{"i":1571,"t":"Follow the provisioning guide, skip the part about disk layout and do it this way: Create a 1 GByte ext4 partition mounted in /boot Create a 8 GByte swap partition Create a 120 GByte unformatted partition Use a Create volume group (LVM) to create a volume group called system with the size of 120 GByte on the partition 4 you just created Create a logical volume by selecting the Free Space option under system LVM. This volume should be mounted in / and have size of 100 GByte Create a partition with the size of the rest of the drive's space Create a new LVM volume group on partition 5 called osd-vg (will be used for Ceph) After the Ubuntu installation, the system will be rebooted Log into the machine via console to get its IP address and then use SSH to connect to the machine Clone the osism/cloud-in-a-box repository into /opt/cloud-in-a-box sudo git clone https://github.com/osism/cloud-in-a-box /opt/cloud-in-a-box Disable conflicting services from the default Ubuntu installation sudo /opt/cloud-in-a-box/cleanup.sh Install upgrades sudo apt update sudo apt upgrade Run the bootstrap.sh script with the required type (use of sandbox is recommended) sudo /opt/cloud-in-a-box/bootstrap.sh sandbox Run the deploy.sh script with the same type as in step 8 to deploy services like Ceph and OpenStack sudo /opt/cloud-in-a-box/deploy.sh sandbox Shutdown the system sudo shutdown -h now Start the system again. System is ready for use, by default DHCP is tried on the first network device. Login via SSH. Use the user dragon with the password password. (You can obtain the ip address by inspecting the logs of your dhcp server or from the issue text of the virtual consoles of the system) ssh dragon@IP_FROM_YOUR_SERVER passwd info The scripts are not idempotent yet. In case there is any fail during bootstrap.sh or deploy.sh you have to start over with fresh installation.","s":"Manual installation","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#manual-installation","p":1559},{"i":1574,"t":"Copy the /home/dragon/wireguard-client.conf file from Cloud in a Box to your workstation. This is necessary for using the web endpoints on your workstation. Rename the wireguard config file to something like cloud-in-a-box.conf. If you want to connect to the Cloud in a Box system from multiple clients, change the client IP address in the config file to be different on each client. scp dragon@IP_FROM_YOUR_SERVER:/home/dragon/wireguard-client.conf $HOME/cloud-in-a-box.conf Install wireguard on your workstation, if you have not done this before. For instructions how to do it on your workstation, please have a look on the documentation of your used distribution. The wireguard documentation you will find here. Start the wireguard tunnel. sudo wg-quick up $HOME/cloud-in-a-box.conf","s":"Wireguard VPN service access","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#wireguard-vpn-service-access","p":1559},{"i":1576,"t":"If you want to access the services please choose the URL from the following list: Name URL Username Password Note ARA https://ara.services.in-a-box.cloud ara password Ceph http://manager.systems.in-a-box.cloud:7000 admin password Flower https://flower.services.in-a-box.cloud - - Grafana https://api.in-a-box.cloud:3000 admin password HAProxy http://manager.systems.in-a-box.cloud:1984 openstack password Homer https://homer.services.in-a-box.cloud - - Horizon - admin project https://api.in-a-box.cloud admin password domain: default Horizon - test project https://api.in-a-box.cloud test test domain: test Netbox https://netbox.services.in-a-box.cloud admin password Netdata http://manager.systems.in-a-box.cloud:19999 - - OpenSearch Dashboards https://api.in-a-box.cloud:5601 opensearch password PhpMyAdmin https://phpmyadmin.services.in-a-box.cloud root password Starting with OSISM 7, root_shard_0 is used as the user name RabbitMQ https://api.in-a-box.cloud:15672 openstack password Skyline - admin project https://api.in-a-box.cloud:9999 admin password Skyline - test project https://api.in-a-box.cloud:9999 test test","s":"Webinterfaces","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#webinterfaces","p":1559},{"i":1578,"t":"Login to Cloud in a Box as described in step 8 of the installation chapter. Select one of the preconfigured environments: system admin test Set the environment by exporting the environment variable: OS_CLOUD: export OS_CLOUD=admin Use OpenStack CLI via the command openstack. openstack availability zone list openstack image list openstack server list # After installation there are no servers","s":"Command-line interfaces","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#command-line-interfaces","p":1559},{"i":1580,"t":"The OpenStack Image Manager is used to manage images. In the example, the Garden Linux image is imported. osism manage images --cloud=admin --filter 'Garden Linux' All available images can be found in the osism/openstack-image-manager repository.","s":"Import of additional images","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#import-of-additional-images","p":1559},{"i":1582,"t":"It is best to execute the commands within a screen session, it takes some time. Please note that you cannot update the Ceph deployment at the moment. This will be enabled in the future. osism apply configuration /opt/configuration/upgrade.sh docker system prune -a","s":"Upgrade","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#upgrade","p":1559},{"i":1585,"t":"In the default configuration, the Cloud in a Box is built in such a way that an internal VLAN101 is used as an simulated external network and this is made usable via the 1st network interface using masquerading. This makes it possible for instances running on the Cloud in a Box to reach the internet. The disadvantage of this is that the instances themselves can only be reached via floating IP addresses from the Cloud in a Box system itself or via the Wireguard tunnel. Especially in edge environments, however, one would usually like to have this differently and the instances should be directly accessible via the local network. To make this work, first identify the name of a 2nd network card to be used. dragon@manager:~$ sudo lshw -class network -short H/W path Device Class Description ============================================================ /0/100/2.2/0 eno7 network Ethernet Connection X552 10 GbE SFP+ /0/100/2.2/0.1 eno8 network Ethernet Connection X552 10 GbE SFP+ /0/100/1c/0 eno1 network I210 Gigabit Network Connection /0/100/1c.1/0 eno2 network I210 Gigabit Network Connection /0/100/1c.4/0 eno3 network I350 Gigabit Network Connection /0/100/1c.4/0.1 eno4 network I350 Gigabit Network Connection /0/100/1c.4/0.2 eno5 network I350 Gigabit Network Connection /0/100/1c.4/0.3 eno6 network I350 Gigabit Network Connection In the following we use eno7. Activate the device manually with sudo ip link set up dev eno7. Then check that a link is actually present. dragon@manager:~$ ethtool eno7 Settings for eno7: Supported ports: [ FIBRE ] Supported link modes: 10000baseT/Full [...] Link detected: yes Now this device is made permanently known in the network configuration. Select the MTU accordingly. For 1 GBit rather 1500 than 9100. The 2nd network interface should be configured without IP configuration (neither static nor DHCP). /opt/configuration/inventory/group_vars/generic/network.yml /opt/configuration/environments/manager/group_vars/manager.yml network_ethernets: eno1: dhcp4: true eno7: mtu: 9100 Then, this change is deployed and applied. osism apply network sudo netplan apply Now the configuration for Neutron and OVN is prepared. network_workload_interface is expanded by the 2nd network interface. The order is not random, first vlan101 then eno7. neutron_bridge_name is added. /opt/configuration/inventory/group_vars/generic/network.yml /opt/configuration/environments/manager/group_vars/manager.yml network_workload_interface: \"vlan101,eno7\" neutron_bridge_name: \"br-ex,br-add\" Then, this change is deployed. osism reconciler sync osism apply openvswitch osism apply ovn osism apply neutron Now segments and/or subnets can be configured. In this case, eno7 is configured as an untagged port on the remote side. /opt/configuration/environments/openstack/playbook-additional-public-network.yml - name: Create additional public network hosts: localhost connection: local tasks: - name: Create additional public network openstack.cloud.network: cloud: admin state: present name: public-add external: true provider_network_type: flat provider_physical_network: physnet2 - name: Create additional public subnet openstack.cloud.subnet: cloud: admin state: present name: subnet-public-add network_name: public-add cidr: 192.168.23.0/24 enable_dhcp: false allocation_pool_start: 192.168.23.100 allocation_pool_end: 192.168.23.200 gateway_ip: 192.168.23.1 dns_nameservers: - 8.8.8.8 - 9.9.9.9 The additional public network can now be made known with osism apply -e openstack additional-public-network. There is now a 2nd floating IP address pool with the name public-add available for use. If instances are to be started directly in this network, enable_dhcp: true must be set. In this case, it should be clarified in advance with the provider of the external network whether the use of DHCP is permitted there.","s":"Use of 2nd NIC for external network","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#use-of-2nd-nic-for-external-network","p":1559},{"i":1587,"t":"The Cloud in a Box has been tested to run on a virtual machine. However, the Cloud in a Box is mainly made for running on bare metal, the automated installation does not work, and other things may not work either. Nested virtualization​ You likely want to run virtual machines on top of your Cloud in a Box. The host machine has to support and enabled nested virtualization. To enable nested virtualization the CPU configuration of the VM has to be host-passthrough or host-model Enabling nested virtualization in Fedora The linked guide can be used in other distributions as well. Disk space saving​ When using Cloud in a Box in a VM, you can utilize the qcow2 disk image or similar technology to save space. In that case, the base installation requires just around 70 GB instead of a full 1 TB. (The drive still needs to be made with a capacity of at least 1TB; however, the actual disk space usage is lower.) Also in case you want to experiment a bit more and \"hack around\" using the manual installation you can make disk snapshots when turned off after the Ubuntu installs, bootstrap.sh and deploy.sh to speed up your progress. If you use qemu, you can use following command to do snapshots. sudo virsh snapshot-create-as --domain cib bootstrap \"run of bootstrap.sh\" --disk-only --diskspec sda,snapshot=external,file=/var/lib/libvirt/images/ub2022_cib_boostrap.qcow2 --atomic QEMU guest agent​ When running inside QEMU, it may be worth it to install the QEMU guest agent. sudo apt -y install qemu-guest-agent sudo systemctl enable qemu-guest-agent sudo systemctl start qemu-guest-agent","s":"Running on a Virtual Machine","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#running-on-a-virtual-machine","p":1559},{"i":1589,"t":"This error means that your disk setup is broken. Use cfdisk and delete all partitions on the system on which you want to install the Cloud in a Box image. With lsblk you can verify if the partitions are empty.","s":"Troubleshooting","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#troubleshooting","p":1559},{"i":1591,"t":"For the further development of the scripts and the mechanisms of the Cloud in a Box, you need to know the following. The operating system is brought onto the node via an automatic Ubuntu installation that uses cloud-init The installation starts the script init.sh which performs an initial clone of the osism/cloud-in-a-box repository and a checkout of the main branch. It also executes the deploy.sh and bootstrap.sh scripts. The installation persists the kernel parameters of the initial boot to the file /etc/.initial-kernel-commandline The status and activities of the deployment are logged in /var/log/install-cloud-in-a-box.log. For proper colors use less -r. Search for OVERALL STATUS to find the result of the specific installation steps. Branch and location of the osism/cloud-in-a-box repository can be overriden by setting the kernel parameters ciab_repo_url (a public repository address without authentication) and ciab_branch (a name of a branch, use only ASCII chars, -, and _).","s":"Development","u":"/docs/iaas/guides/other-guides/cloud-in-a-box","h":"#development","p":1559},{"i":1594,"t":"We welcome any issues, change requests or general feedback. Do not hestiate to open an issue. We use GitHub Issues to capture feature requests, feedback, bugs, etc. The tracker is available in the osism/issues repository. There are no specific requirements for the creation of an issue. Error cases should be described in such a way that they are directly reproducible. The more outputs there are, the better. We use GitHub pull requests for contributions. The use of pull requets is documented in the official GitHub documentation. The process in detail for the creation of a fork, branch etc. is also documented in the official GitHub documentation. It is recommended to use the GitHub CLI. Makes many steps easier.","s":"Contributor Guide","u":"/docs/iaas/guides/other-guides/contributor-guide","h":"","p":1593},{"i":1597,"t":"The OpenStack Simple Stress is a small stress test for your Openstack Cluster. You can use it for burnin tests or if you want to monitor your cluster perfomance. It is able to start a predefined amount of Servers in specific networks in parallel and serial and removes them afterwards, so you can test your environment to the limits.","s":"Overview","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#overview","p":1595},{"i":1599,"t":"Prepare to use the Openstack Simple Stress. git clone https://github.com/osism/openstack-simple-stress cd openstack-simple-stress pipenv install pipenv shell","s":"Installation","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#installation","p":1595},{"i":1601,"t":"The main.py command and his default options while executing the command. --cleanup true --cloud simple-stress --compute-zone nova --debug false --delete true --flavor SCS-2V-8 --floating false --image Ubuntu 22.04 --interval 10 (seconds) --keypair unset --network simple-stress --network-zone nova --number 1 --parallel 1 --prefix simple-stress --storage-zone simple-stress --timeout 600 (seconds) --volume false --volume-number 1 --volume-size 1 (gigabyte) --wait true","s":"Defaults","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#defaults","p":1595},{"i":1603,"t":"There must be a clouds.yml and a secure.yml file in the directory where the OpenStack Simple Stress will be executed, examples are provided within the git repository. The cloud profile to be used can be specified via the optional --cloud parameter. By default, the cloud profile with the name simple-stress is used. $ python src/main.py -h usage: main [-h] [--cleanup] [--cloud CLOUD] [--compute-zone COMPUTE_ZONE] [--config-dir DIR] [--config-file PATH] [--debug] [--delete] [--flavor FLAVOR] [--floating] [--image IMAGE] [--interval INTERVAL] [--keypair KEYPAIR] [--network NETWORK] [--network-zone NETWORK_ZONE] [--nocleanup] [--nodebug] [--nodelete] [--nofloating] [--novolume] [--nowait] [--number NUMBER] [--parallel PARALLEL] [--prefix PREFIX] [--storage-zone STORAGE_ZONE] [--timeout TIMEOUT] [--volume] [--volume-number VOLUME_NUMBER] [--volume-size VOLUME_SIZE] [--wait] options: -h, --help show this help message and exit --cleanup --cloud CLOUD Cloud name --compute-zone COMPUTE_ZONE Compute availability zone to use --config-dir DIR Path to a config directory to pull `*.conf` files from. This file set is sorted, so as to provide a predictable parse order if individual options are over- ridden. The set is parsed after the file(s) specified via previous --config- file, arguments hence over-ridden options in the directory take precedence. This option must be set from the command-line. --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. Defaults to None. This option must be set from the command-line. --debug --delete --flavor FLAVOR --floating --image IMAGE --interval INTERVAL --keypair KEYPAIR --network NETWORK --network-zone NETWORK_ZONE Network availability zone to use --nocleanup The inverse of --cleanup --nodebug The inverse of --debug --nodelete The inverse of --delete --nofloating The inverse of --floating --novolume The inverse of --volume --nowait The inverse of --wait --number NUMBER --parallel PARALLEL --prefix PREFIX --storage-zone STORAGE_ZONE Storage availability zone to use --timeout TIMEOUT --volume --volume-number VOLUME_NUMBER --volume-size VOLUME_SIZE --wait Running a small and simple test on your Openstack environment, using Ubuntu_22.04 image with the flavor of 2VCPUs and 8Gigabytes of RAM, starting 6 servers, 2 parallel each with a volume size of 20Gigabytes. $ python src/main.py --network test-net --flavor SCS-2V-8 --image Ubuntu_22.04 --number 6 --parallel 2 --volume-size 20 2024-04-23 11:47:16 | INFO | Checking flavor SCS-2V-8 2024-04-23 11:47:17 | INFO | flavor.id = 926f952f-0714-4c55-92c2-7514191fecce 2024-04-23 11:47:17 | INFO | Checking image Ubuntu_22.04 2024-04-23 11:47:17 | INFO | image.id = 667649d6-e828-403b-8871-15dde7b9ce85 2024-04-23 11:47:17 | INFO | Checking network test-net 2024-04-23 11:47:18 | INFO | network.id = 9688192e-11dd-4618-a18c-99d3267f630a 2024-04-23 11:47:18 | INFO | Creating server simple-stress-0 2024-04-23 11:47:18 | INFO | Creating server simple-stress-1 2024-04-23 11:47:18 | INFO | Waiting for server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0) 2024-04-23 11:47:18 | INFO | Waiting for server e485697f-feae-458c-952d-000072374c3f (simple-stress-1) 2024-04-23 11:47:28 | INFO | Waiting for boot / test results of 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0) 2024-04-23 11:47:29 | INFO | Waiting for boot / test results of e485697f-feae-458c-952d-000072374c3f (simple-stress-1) 2024-04-23 11:47:39 | INFO | Deleting server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0) 2024-04-23 11:47:39 | INFO | Waiting for deletion of server 049bf974-b0fd-467f-aabd-3593b2a409a4 (simple-stress-0) 2024-04-23 11:47:39 | INFO | Deleting server e485697f-feae-458c-952d-000072374c3f (simple-stress-1) 2024-04-23 11:47:40 | INFO | Waiting for deletion of server e485697f-feae-458c-952d-000072374c3f (simple-stress-1) 2024-04-23 11:47:49 | INFO | Creating server simple-stress-2 2024-04-23 11:47:50 | INFO | Creating server simple-stress-3 2024-04-23 11:47:50 | INFO | Waiting for server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2) 2024-04-23 11:47:51 | INFO | Waiting for server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3) 2024-04-23 11:48:00 | INFO | Waiting for boot / test results of 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2) 2024-04-23 11:48:01 | INFO | Waiting for boot / test results of a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3) 2024-04-23 11:48:11 | INFO | Deleting server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3) 2024-04-23 11:48:12 | INFO | Waiting for deletion of server a098cc12-94ff-4036-bf42-4fc08287809f (simple-stress-3) 2024-04-23 11:48:12 | INFO | Deleting server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2) 2024-04-23 11:48:12 | INFO | Waiting for deletion of server 26595dd3-09d4-4758-8d1f-58a40b681d11 (simple-stress-2) 2024-04-23 11:48:22 | INFO | Creating server simple-stress-4 2024-04-23 11:48:22 | INFO | Waiting for server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4) 2024-04-23 11:48:22 | INFO | Creating server simple-stress-5 2024-04-23 11:48:23 | INFO | Waiting for server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5) 2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4) 2024-04-23 11:48:43 | INFO | Waiting for boot / test results of 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5) 2024-04-23 11:48:55 | INFO | Deleting server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4) 2024-04-23 11:48:55 | INFO | Deleting server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5) 2024-04-23 11:48:55 | INFO | Waiting for deletion of server 05b9f996-5a06-4359-b495-3463cc7b81e0 (simple-stress-4) 2024-04-23 11:48:55 | INFO | Waiting for deletion of server 8d372de6-ca07-4afb-9e80-1589fd5242e8 (simple-stress-5) 2024-04-23 11:49:05 | INFO | Server 049bf974-b0fd-467f-aabd-3593b2a409a4 finished 2024-04-23 11:49:05 | INFO | Server e485697f-feae-458c-952d-000072374c3f finished 2024-04-23 11:49:05 | INFO | Server a098cc12-94ff-4036-bf42-4fc08287809f finished 2024-04-23 11:49:05 | INFO | Server 26595dd3-09d4-4758-8d1f-58a40b681d11 finished 2024-04-23 11:49:05 | INFO | Server 05b9f996-5a06-4359-b495-3463cc7b81e0 finished 2024-04-23 11:49:05 | INFO | Server 8d372de6-ca07-4afb-9e80-1589fd5242e8 finished 2024-04-23 11:49:05 | INFO | Runtime: 107.4460s Using a config directory with configfiles to run the test. Path to a config directory to pull *.conf files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set is parsed after the file(s) specified via previous --config file, arguments hence over-ridden options in the directory take precedence. This option must be set from the command-line. python src/main.py --config-dir /path/to/config-dir","s":"Usage","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#usage","p":1595},{"i":1605,"t":"The config files which can be used for main.py are using the oslo.config format, you can set the command line options as key = value pair and create your own config files matching your setup. mytest.conf [DEFAULT] cloud = simple-stress network = test-net number = 6 parallel = 2 flavor = SCS-2V-8 image = Ubuntu_22.04 volume-size = 20","s":"Config files","u":"/docs/iaas/guides/operations-guide/openstack/tools/simple-stress","h":"#config-files","p":1595},{"i":1608,"t":"If you want to add a new service to OSISM, this is done via an Ansible role and (most often) a container image. The following steps are necessary and are demonstrated using the example of osism.services.cgit. Description Example Add the Ansible role in one of the Ansible collection repositories https://github.com/osism/ansible-collection-services/pull/578/files Add the Ansible playbook https://github.com/osism/ansible-playbooks/pull/215/files Add the Ansible inventory group https://github.com/osism/cfg-generics/pull/225/files Add the used container image(s) to the release repository https://github.com/osism/release/pull/278/files Add the container images(s) to osism-ansible container image https://github.com/osism/container-image-osism-ansible/pull/215/files Add the container image registry/registries and host(s) to the defaults repository https://github.com/osism/defaults/pull/54/files Add a sample deployment to the testbed https://github.com/osism/testbed/pull/1043/files","s":"How to add a new service","u":"/docs/iaas/guides/other-guides/developer-guide/","h":"#how-to-add-a-new-service","p":1606},{"i":1610,"t":"If required, add a new container image in the osism/container-images repository. The example here is from the osism.services.keycloak role: https://github.com/osism/container-images/pull/34/files. Whenever possible, upstream container images should be used. If only minor customizations are necessary, always work with overlay container images based on upstream container images.","s":"How to add a new container image","u":"/docs/iaas/guides/other-guides/developer-guide/","h":"#how-to-add-a-new-container-image","p":1606},{"i":1615,"t":"Kurt Garloff, 2024-02-20","s":"Setting up OpenStack health monitor on Debian","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"","p":1614},{"i":1617,"t":"The development of openstack-health-monitor was done on openSUSE 15.x images, just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution. Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here. Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a successor project for the increasingly hard to maintain shell code, this may not be worth the trouble. openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested. The scenario is described in a bit more detail in the repository's README.md file. The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the monitoring section of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up.","s":"Intro","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#intro","p":1614},{"i":1619,"t":"So we start a Debian 12 image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard; the instructions use flavor names and image names from the SCS standards. For many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack).","s":"Setting up the driver VM","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#setting-up-the-driver-vm","p":1614},{"i":1621,"t":"There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor. The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems.","s":"Internal vs external monitoring","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#internal-vs-external-monitoring","p":1614},{"i":1623,"t":"Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own. If openstack availability zone list --compute fails for you without admin rights, please fix your openstack client. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Healh-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)","s":"Unprivileged operation","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#unprivileged-operation","p":1614},{"i":1625,"t":"The author prefers to setup the VM via openstack CLI tooling. He has working entries for all clouds he uses in his ~/.config/openstack/clouds.yaml and secure.yaml and has exported the OS_CLOUD environment variable to point to the cloud he is working on to set up the driver VM. The author uses the bash shell. All of this of course could be scripted. So here we go Create the network setup for a VM in a network oshm-network with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network. PUBLIC=$(openstack network list --external -f value -c Name) openstack router create oshm-router openstack router set --external-gateway $PUBLIC oshm-driver-router openstack network create oshm-network openstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet openstack router add subnet oshm-router oshm-subnet Create a security group that allows ssh and ping access openstack security group create sshping openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping openstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping Being at it, we also create the security group for grafana openstack security group create grafana openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana To connect to the VM via ssh later, we create an SSH keypair openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key chmod og-r ~/.ssh/oshm-key.pem Rather than creating a new key (and storing and protecting the private key), we could have passed --public-key and used an existing keypair. Look up Debian 12 image UUID. IMGUUID=$(openstack image list --name \"Debian 12\" -f value -c ID | tr -d '\\r') echo $IMGUUID Sidenote: The tr command is there to handle broken tooling that embeds a trailing \\r in the output. Boot the driver VM openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing --block-device. See diskless flavor blog article. For flavors with local root disks, you could have used the --image $IMGUUID parameter instead. Wait for it to boot (optional) You can look at the boot log with openstack console log show oshm-driver or connect to it via VNC at the URL given by openstack console url show oshm-driver. You can of course also query openstack on the status openstack server list or openstack server show oshm-driver. You can also just create a simple loop: declare -i ctr=0 RC=0 while [ $ctr -le 120 ]; do STATUS=\"$(openstack server list --name oshm-driver -f value -c Status)\" if [ \"$STATUS\" = \"ACTIVE\" ]; then echo \"$STATUS\"; break; fi if [ \"$STATUS\" = \"ERROR\" ]; then echo \"$STATUS\"; RC=1; break; fi if [ -z \"$STATUS\" ]; then echo \"No such VM\"; RC=2; break; fi sleep 2 let ctr+=1 done # return $RC if [ $RC != 0 ]; then false; fi Attach a floating IP so it's reachable from the outside. FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks | sed \"s@^[^:]*:[^']*'\\([0-9\\.]*\\)'.*\\$@\\1@\") FIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID) echo $FIXEDIP $FIXEDPORT openstack floating ip create --port $FIXEDPORT $PUBLIC FLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c \"Floating IP Address\") echo \"Floating IP: $FLOATINGIP\" Remember this floating IP address. Connect to it via ssh ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.) All the following commands are performed on the newly started driver VM.","s":"Driver VM via openstack CLI","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#driver-vm-via-openstack-cli","p":1614},{"i":1627,"t":"We need to install the openstack client utilities. sudo apt-get update sudo apt-get install python3-openstackclient sudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient Configure your cloud access in ~/.config/openstack/clouds.yaml clouds: CLOUDNAME: interface: public identity-api-version: 3 #region_name: REGION auth: auth_url: KEYSTONE_ENDPOINT project_id: PROJECT_UUID #alternatively project_name and project_domain_name user_domain_name: default # change to your real domain and secure.yaml (in the same directory) clouds: CLOUDNAME: auth: username: USERNAME password: PASSWORD The CLOUDNAME can be freely chosen. This is the value passed to the openstack CLI with --os-cloud or exported to your environment in OS_CLOUD. The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample clouds.yaml file that works (but lacks the password). Protect your secure.yaml from being read by others: chmod 0600 ~/.config/openstack/secure.yaml. If you are using application credentials instead of username, password to authenticate, you don't need to specify project_id nor project's nor user's domain names in clouds.yaml. Just (in secure.yaml): clouds: CLOUDNAME: auth_type: v3applicationcredential auth: application_credential_id: APPCRED_ID application_credential_secret: \"APPCRED_SECRET\" Configure this to be your default cloud: export OS_CLOUD=CLOUDNAME You might consider adding this to your ~/.bashrc for convenience. Being at it, you might want to add export CLIFF_FIT_WIDTH=1 there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste). Verify that your openstack CLI works: openstack catalog list openstack server list You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases.","s":"Configuring openstack CLI on the driver VM","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#configuring-openstack-cli-on-the-driver-vm","p":1614},{"i":1629,"t":"If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in /etc/ssl/certs/ca-certificates.crt. You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the debian user. Add it to your clouds.yaml clouds: CLOUDNAME: cacert: /PATH/TO/CACERT.CRT [...] If you want to allow api_monitor.sh to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment: export OS_CACERT=/PATH/TO/CACERT.CRT Consider adding this to your ~/.bashrc as well.","s":"Custom CA","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#custom-ca","p":1614},{"i":1631,"t":"Checkout openstack-health-monitor: sudo apt-get install git bc jq netcat-traditional tmux zstd git clone https://github.com/SovereignCloudStack/openstack-health-monitor cd openstack-health-monitor You may want to start a tmux (or screen) session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect. The script api_monitor.sh is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the README.md file. It is good practice to use tmux. This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to screen over tmux. You should be ready to run one iteration of the openstack-health-monitor now. Run it like this: export IMG=\"Debian 12\" export JHIMG=\"Debian 12\" ./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1 Leave out the -LL if you don't have a working loadbalancer service or replace -LL with -LO if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources). Feel free to study the meaning of all the command line parameters by looking at the README.md. (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.) This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs DOWN, BUILD, creating are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual openstack RESOURCE list and openstack RESOURCE show NAME and RESOURCE being something like router, network, subnet, port, volume, server, floating ip, loadbalancer, loadbalancer pool, loadbalancer listener, security group, keypair, image, ...) The api_monitor.sh uses and APIMonitor_TIMESTAMP prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong. TIMESTAMP is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time). This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least -N 2 to test the ability of the router to route traffic between networks. So expect -n 6 to become -N 2 -n 6 for a very small single-AZ cloud or -n 12 for a large 3 AZ cloud region. So, re-run the api_monitor.sh with the target sizing.","s":"Your first api_monitor.sh iteration","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#your-first-api_monitorsh-iteration","p":1614},{"i":1633,"t":"Note that api_monitor.sh uses small flavors (SCS-1V-2 for the N jump hosts and SCS-1L-1 for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors. If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run api_monitor.sh in a loop (which you will) with say 10 VMs (e.g. -N 2 -n 8) in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference. Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of openstack volume list, openstack volume show BROKEN_VOLUME, openstack loadbalancer list, openstack loadbalancer show BROKEN_LB.) Using -w -1 makes api_monitor.sh wait for interactive input whenever an error occurs; this can be convenient for debugging. Once you have single iterations working nicely, we can proceed.","s":"Resource impact and charging","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#resource-impact-and-charging","p":1614},{"i":1635,"t":"Typically, we run api_monitor.sh with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here. #!/bin/bash # run_CLOUDNAME.sh # Do some global settings export IMG=\"Debian 12\" export JHIMG=\"Debian 12\" #export OS_CACERT=/home/debian/ca-certificates.pem # Additional settings to override flavors or to # configure email addresses for sending alarms can be set here # Does openstack CLI work? openstack server list >/dev/null || exit 1 # Upload log files to this swift container (which you need to create) #export SWIFTCONTAINER=OS-HM-Logfiles # CLEANUP echo \"Finding resources from previous runs to clean up ...\" # Find Floating IPs FIPLIST=\"\" FIPS=$(openstack floating ip list -f value -c ID) for fip in $FIPS; do FIP=$(openstack floating ip show $fip | grep -o \"APIMonitor_[0-9]*\") if test -n \"$FIP\"; then FIPLIST=\"${FIPLIST}${FIP}_ \"; fi done FIPLIST=$(echo \"$FIPLIST\" | grep -v '^$' | sort -u) # Cleanup previous interrupted runs SERVERS=$(openstack server list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) KEYPAIR=$(openstack keypair list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) VOLUMES=$(openstack volume list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) NETWORK=$(openstack network list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) LOADBAL=$(openstack loadbalancer list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) ROUTERS=$(openstack router list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) SECGRPS=$(openstack security group list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) echo CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS for ENV in $FIPLIST; do echo \"******************************\" echo \"CLEAN $ENV\" bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV echo \"******************************\" done TOCLEAN=$(echo \"$SERVERS $KEYPAIR $VOLUMES $NETWORK $LOADBAL $ROUTERS $SECGRPS \" | grep -v '^$' | sort -u) for ENV in $TOCLEAN; do echo \"******************************\" echo \"CLEAN $ENV\" bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV echo \"******************************\" done # Now run the monitor #exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab \"$@\" exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T \"$@\" Compared to the previous run, we have explicitly set two networks here -N 2 and rely on the iterations being passed in as command line arguments. Add parameter -t if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (-LO) in this example rather than the amphora based one (-LL). You may use one of the existing run_XXXX.sh scripts as example. Beware: eMail alerting with ALARM_EMAIL_ADDRESS and NOTE_EMAIL_ADDRESS (and limiting with -a and -R ) and reporting data to telegraf (option -S) may be present in the samples. Make this script executable (chmod +x run_CLOUDNAME.sh). We wrap a loop around this in run_in_loop.sh: #!/bin/bash # run_in_loop.sh rm stop-os-hm 2>/dev/null while true; do ./run_CLOUDNAME.sh -i 200 if test -e stop-os-hm; then break; fi echo -n \"Hit ^C to abort ...\" sleep 15; echo done Also make this executable (chmod +x run_in_loop.sh). To run this automatically in a tmux window whenever the system starts, we follow the steps in the startup README.md Change OS_CLOUD in startup/run-apimon-in-tmux.sh. (If you need to set OS_CACERT, also add it in this file and pass it into the windows.) Activate everything: mkdir -p ~/.config/systemd/user/ cp -p startup/apimon.service ~/.config/systemd/user/ systemctl --user enable apimon systemctl --user start apimon sudo loginctl enable-linger debian tmux attach oshealthmon This assumes that you are using the user debian for this monitoring and have checked out the repository at ~/openstack-health-monitor/. Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)","s":"Automating startup and cleanup","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#automating-startup-and-cleanup","p":1614},{"i":1637,"t":"If you want to change the parameters passed to api_monitor.sh, you best do this by editing run_CLOUDNAME.sh, potentially after testing it with one iteration before. To make the change effective, you can wait until the current 200 iterations are completed and the run_in_loop.sh calls run_CLOUDNAME.sh again. You can also hit ^C in the tmux window that hasapi_monitor.sh running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ^C during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ^C twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ./run_in_loop.sh again. You can also issue the systemctl --user stop apimon command; it will basically do the same thing: Send ^C and then wait for everything to be completed and tear down the tmux session. After waiting for that to complete, you can start it again with systemctl --user start apimon.","s":"Changing parameters and restarting","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#changing-parameters-and-restarting","p":1614},{"i":1639,"t":"You can run multiple instances of api_monitor.sh on the same driver VM. In this case, you should rename run_in_loop.sh to e.g. run_in_loop_CLOUDNAME1.sh and call run_CLOUDNAME1.sh from there. Don't forget to adjust startup/run-apimon-in-tmux.sh and startup/kill-apimon-in-tmux.sh to start more windows. It is not recommended to run multiple instances against the same OpenStack project however. While the api_monitor.sh script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the run_CLOUDNAME.sh script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations.","s":"Multiple instances","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#multiple-instances","p":1614},{"i":1642,"t":"If wanted, the api_monitor.sh can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the -a N and -R options. In order to enable sending emails from the driver VM, it needs to have postfix (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly. Once you have configured postfix, you can enable eMail notifications using the option -e. Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ALARM_EMAIL_ADDRESSES and NOTE_EMAIL_ADDRESSES environment variables to api_monitor.sh, e.g. by setting it in the run_CLOUDNAME.sh.","s":"eMail","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#email","p":1614},{"i":1644,"t":"api_monitor.sh writes a log file with the name APIMonitor_TIMESTAMP.log. It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (TIMESTAMP is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.) Note that api_monitor.sh does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties. The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable SWIFTCONTAINER has been set (in run_COULDNAME.sh) when starting api_monitor.sh. the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER After the 200 iterations, a .psv file (pipe-separated values) is created Stats.STARTTIME-ENDTIME.psv (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured).","s":"Log files","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#log-files","p":1614},{"i":1646,"t":"See https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md","s":"Data collection and dashboard","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#data-collection-and-dashboard","p":1614},{"i":1648,"t":"To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData: sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key echo \"deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main\" | sudo tee /etc/apt/sources.list.d/influxdata.list sudo apt update sudo apt -y install telegraf In the config file /etc/telegraf/telegraf.conf, we enable [[inputs.influxdb_listener]] service_address = \":8186\" [[outputs.influxdb]] urls = [\"http://127.0.0.1:8086\"] and restart the service (sudo systemctl restart telegraf). Enable it on system startup: sudo systemctl enable telegraf.","s":"telegraf","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#telegraf","p":1614},{"i":1650,"t":"We proceed to influxdb: sudo apt-get install influxdb In the configuration file /etc/influxdb/influxdb.conf, ensure that the http interface on port 8086 is enabled. [http] enabled = true bind-address = \":8086\" Restart influxdb as needed with sudo systemctl restart influxdb. Also enable it on system startup: sudo systemctl enable influxdb.","s":"influxdb","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#influxdb","p":1614},{"i":1652,"t":"You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter -S CLOUDNAME to the api_monitor.sh call in run_CLOUDNAME.sh. Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete).","s":"Add -S CLOUDNAME to your run_CLOUDNAME.sh script","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#add--s-cloudname-to-your-run_cloudnamesh-script","p":1614},{"i":1654,"t":"Basic config​ Finally grafana: We (still as root) follow https://www.server-world.info/en/note?os=Debian_12&p=grafana sudo wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key echo \"deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main\" | sudo tee -a /etc/apt/sources.list.d/grafana.list sudo apt update sudo apt -y install grafana The config file /etc/grafana/grafana.ini needs some adjustments: Set the hostname in [server] section: domain = health.YOURCLOUD.sovereignit.cloud. Set the protocol = https if not enabled by default. You can use a hostname of your liking, but we will need to create TLS certificates for this host. So we should have control over DNS TXT records for this domain if we want to use Let's Encrypt with DNSAUTH. The sovereignit.cloud domain is controlled by the SCS project team and has been used for a number of health mon instances. In this same section, set cert_file = /etc/grafana/health-fullchain.pem and cert_key = /etc/grafana/health-key.pem. Ensure that both files are readable by root:grafana and that the key file is not world-readable. Configure the admin access. In section [security], set the admin_user = admin and admin_password = SOME_SECRET_PASS which you keep private. Allow local data sources (same section): data_source_proxy_whitelist = localhost:8088 localhost:8086 Let's disallow user signup (in section [users]): allow_sign_up = false and allow_org_create = false. We do the OIDC connection with [auth.github] later. We can now restart the service: sudo systemctl restart grafana-server. Being at it, also enable it on system startup: sudo systemctl enable grafana-server. You should now be able to access your dashboard on https://health.YOURCLOUD.sovereignit.de:3000 and log in via the configured username admin and your SOME_SECRET_PASS password. Enable influx database in grafana​ In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to http://localhost:8086 (despite this being the suggestion). Set the database name to telegraf. Save&test should succeed. Importing the dashboard​ Go to Home, Dashboards, New, Import. Upload the dashboard .json file from the repository, user the Grafana-10 variant if you use Grafana 10 or newer. In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.) Save. Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable). No data displayed?​ Sometimes, you may see a panel displaying \"no data\" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana. One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved. Dashboard features​ Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended. The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously. You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term. github OIDC integration​ The SCS providers do allow all github users that belong to the SovereignCloudStack organization to get Viewer access to the dashboards by adding a client_id and client_secret in the [github.auth] section that you request from the SCS github admins (github's oauth auth). This allows to exchange experience and to get a feeling for the achievable stability. (Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)","s":"grafana","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#grafana","p":1614},{"i":1656,"t":"Install influxdb via apt: https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss Install telegraf (same apt repo as influxdb): sudo apt update && sudo apt install telegraf Install grafana: https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository Prepare configuration by using the config files from the repository as an alternative to doing the changes manually (as described above): sudo cp dashboard/telegraf.conf /etc/telegraf && sudo chown root:root /etc/telegraf/telegraf.conf && sudo chmod 0644 /etc/telegraf/telegraf.conf sudo cp dashboard/config.toml /etc/influxdb && sudo chown root:influxdb /etc/influxdb/config.toml && sudo chmod 0640 /etc/influxdb/config.toml sudo cp dashboard/grafana.ini /etc/grafana && sudo chown root:grafana /etc/grafana/grafana.ini && sudo chmod 0640 /etc/grafana/grafana.ini These config files should work as long as the versions of telegraf, influxdb and grafana don't evolve too far from the ones used in the repository. (Otherwise refer to above instructions how to tweak the default config files.) Changes to /etc/grafana/grafana.ini as we do tls termination at the reverse proxy: set protocol = http comment out domain option (? FIXME) or set it to the hostname comment out cert_* options Also change the admin password in grafana.ini. Changes to /etc/grafana/grafana.ini if github auth should not be used yet: comment out whole [auth.github] section for now (can be enabled later) Restart services: sudo systemctl restart telegraf && sudo systemctl restart influxdb && sudo systemctl restart grafana-server Configuration in grafana web gui: Login to grafana http(s)://:3000 with user admin and default password from /etc/grafana/grafana.ini and change password. Create influxdb datasource with url http://localhost:8086 and database name telegraf. Finally import dashboard dashboard/openstack-health-dashboard.json to grafana. TODO: Reverse proxy (aka ingress) with Let's Encrypt cert Github auth as described above","s":"Alternative approach to install and configure the dashboard behind a reverse proxy","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy","p":1614},{"i":1658,"t":"The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained.","s":"Maintenance","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#maintenance","p":1614},{"i":1660,"t":"It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See https://wiki.debian.org/UnattendedUpgrades. If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and grafana (port 3000).","s":"Unattended upgrades","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#unattended-upgrades","p":1614},{"i":1662,"t":"You can just do a git update in the openstack-health-monitor directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ^C, see above in the restart section.","s":"Updating openstack-health-monitor","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#updating-openstack-health-monitor","p":1614},{"i":1664,"t":"The system holds two things that you might consider valuable for long-term storage: (1) The log files. These are compressed and uploaded to object storage if you enable the SWIFTCONTAINER setting, which probably means that these do not need any additional backing up then. (2) The influx time series data. Back up the data in /var/lib/influxdb. Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, clouds.yaml, etc. Be careful not to expose sensitive data by granting too generous access to your backed up files.","s":"Backup","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#backup","p":1614},{"i":1667,"t":"In case there is trouble with your cloud, the normal course of action to analyze is as follows: Look at the dashboard (see above) Connect to the driver VM and attach to the tmux session and look at the console output of api_monitor.sh Analyze the logfile (locally on the driver VM or grab it from the object storage)","s":"Debugging issues","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#debugging-issues","p":1614},{"i":1669,"t":"When VM instances are created successfully, but then end up in ERROR state, the api_monitor.sh does an explicit openstack server show, so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files. Sometimes the VMs end up being ACTIVE as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail. To gather more details, you can look at the console output openstack console log show VM (where VM is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ssh -i APIMonitor_XXXXX_JH.pem debian@FIP, whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP. Replace XXXXX with the number in your current APIMonitor prefix, FIP with the floating IP address of the responsible JumpHost and debian with the user name used by the images you boot. Use 223 to connect to the second VM in the network, 224 the third etc. When logged in, look at /var/log/cloud-init-output.log and /var/log/cloud-init.log. You can find the metadata in /var/lib/cloud/instance/. You will not have much time to look around -- the still running api_monitor.sh script does continue and clean things up again. So you might want to suspend it with ^Z (and continue it later with fg). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the run_CLOUDNAME.sh script as it would do cleanup against the running instance, but rather copy the api_monitor.sh command line from the bottom (without the exec), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach -w -1 to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work.","s":"Analyzing failures","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#analyzing-failures","p":1614},{"i":1671,"t":"If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard). There are a few things that may need support from a cloud admin: Volumes may end up permanently in a deleting or reserved state or may be in-use, attached to a VM that has long gone. The admin needs to set the state to error and then delete them. Loadbalancers may end up in a PENDING_XXX state (XXX being CREATE, UPDATE or DELETE) without ever changing. This also needs the cloud admin to set the status to ERROR, so it can be cleaned up. amphorae are more prone to this than ovn LBs. More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted. The source of this document can be found in the SovereignCloudStack/openstack-health-monitor repository. Author: SCS Community, License: CC by Attribution 4.0 International","s":"Cleaning things up","u":"/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitor","h":"#cleaning-things-up","p":1614},{"i":1674,"t":"Currently we do a major release every 6 months. Minor releases we do when needed and about every 2 weeks. In a minor release, only updates, bug fixes, etc. take place. There are also no major upgrades of included components such as OpenStack, Keycloak or Ceph in a minor release. It is possible to jump from any minor version within a major version to higher minor versions without any intervention. Deprecations, removals, etc. take place in a major release. New mandatory features are also added in a major release. Upgrades of the included components can also take place during a major release (e.g. OpenStack Xena -> OpenStack Yoga). It is possible to jump from the previous major version to the next major version. It may be that manual intervention is necessary. For example, configuration parameters may need to be added or services that no longer exist may need to be removed.","s":"How we handle releases","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#how-we-handle-releases","p":1672},{"i":1676,"t":"On all repositories that are used, check that the versions to be used have an appropriate version tag (e.g. v0.20230308.0). osism/ansible-collection-commons osism/ansible-collection-services osism/ansible-collection-validations osism/ansible-defaults osism/ansible-playbooks osism/ansible-playbooks-manager osism/cf-generics osism/kolla-operations osism/python-osism Copy the latest directory. The release to be created is used as the new name. latest -> 6.0.0b Remove all # renovate lines from the base.yml file. Remove all Ceph and OpenStack releases that should not be part of the pre-release. There is only one OpenStack version and one Ceph version per (pre-)release. Ensure that the symlinks openstack.yml and ceph.yml point to the releases to be used in this pre-release. base.yml ceph-pacific.yml ceph.yml -> ceph-pacific.yml openstack-zed.yml openstack.yml -> openstack-zed.yml Run src/prepare-release.py. RELEASE=6.0.0b python3 src/prepare-release.py Do the steps from the Stable release starting from the 4th step.","s":"How to make a release","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#how-to-make-a-release","p":1672},{"i":1678,"t":"Copy the directory of the last pre-release or the previous stable release. The release to be created is used as the new name. 5.0.0a -> 5.0.0b 5.0.0b -> 5.0.0 5.0.0 -> 5.1.0 5.1.0 -> 5.2.0 5.2.0 -> 5.3.0 Change all necessary versions in the YAML files within the new directory. In any case, the version of the pre-release or the version of the stable release must be replaced by the release to be created. The release to be created is submitted as a pull request as usual and then merged. Add a tag with the name of the new release to the listed repositories. osism/container-image-ceph-ansible osism/container-image-inventory-reconciler osism/container-image-osism-ansible osism/container-images-kolla After completing the creation of the images in repository container-images-kolla, the file images.yml must be added to repository osism/sbom as 5.0.0/openstack.yml (instead of 5.0.0, the corresponding release is used). The file is available as a build artefact of the Release container images action on the created tag. Before the file is added, it is enhanced with the checksums of the images. The script is available in the osism/sbom repository. VERSION=5.0.0 python3 scripts/add-image-checksum.py If 5.0.0/openstack.yml is present in osism/sbom, repository osism/container-image-kolla-ansible can be tagged like the other repositories before. Add the created SPDX files from the listed repositories to the osism/sbom repository. The file are available as build artefacts of the Build container image action on the created tags. osism/container-image-ceph-ansible osism/container-image-kolla-ansible osism/container-image-osism-ansible Add and run temporary CI jobs in osism/testbed that uses the pre-release. - job: name: testbed-deploy-stable-next parent: testbed-deploy vars: manager_version: \"5.0.0a\" refstack: true nodeset: testbed-orchestrator - job: name: testbed-upgrade-stable-next parent: testbed-deploy vars: manager_version: \"4.2.0\" manager_version_next: \"5.0.0a\" nodeset: testbed-orchestrator Test. Test. Test. Prepare a PR to change the stable version to the new stable version in the following Zuul jobs in the osism/testbed repository. All tests there must pass successfully before the tag is set on this repository in the next step. The temporary CI jobs (step 8) are removed again with this PR. testbed-deploy-stable testbed-update-stable testbed-update-stable testbed-upgrade-stable Add a new release notes file to doc/sorce/notes. Generate the versions table with the help of the release-table.py script in the osism/sbom repository. After all known issues are documented, a corresponding tag, e.g. 5.0.0, is set on the osism/release repository. Create a GitHub release with the new tag on the osism/release repository. The release is now public available. As the last of the release process, the previously prepared PR is merged on the osism/testbed repository to change the stable version.","s":"Stable release","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#stable-release","p":1672},{"i":1680,"t":"We use Reno to manage the release notes.","s":"How we write release notes","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#how-we-write-release-notes","p":1672},{"i":1682,"t":"Reno is provided as a Python package and can be installed with pip. pip3 install reno","s":"Installation","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#installation","p":1672},{"i":1684,"t":"For each change in a repository, a release note is created with Reno. Something meaningful is used as the name for the note. For example, if the requirements file for Ansible is removed, remove-ansible-requirements is a good name. $ reno new remove-ansible-requirements no configuration file in: ./releasenotes/config.yaml, ./reno.yaml Created new notes file in releasenotes/notes/remove-ansible-requirements-6c6eba43f616bc6b.yaml The created file contains prepared entries for several categories. It is described briefly in each instance which contents belong in which category. What is not needed is deleted. prelude: > Replace this text with content to appear at the top of the section for this release. All of the prelude content is merged together and then rendered separately from the items listed in other parts of the file, so the text needs to be worded so that both the prelude and the other items make sense when read independently. This may mean repeating some details. Not every release note requires a prelude. Usually only notes describing major features or adding release theme details should have a prelude. features: - | List new features here, or remove this section. All of the list items in this section are combined when the release notes are rendered, so the text needs to be worded so that it does not depend on any information only available in another section, such as the prelude. This may mean repeating some details. issues: - | List known issues here, or remove this section. All of the list items in this section are combined when the release notes are rendered, so the text needs to be worded so that it does not depend on any information only available in another section, such as the prelude. This may mean repeating some details. upgrade: - | List upgrade notes here, or remove this section. All of the list items in this section are combined when the release notes are rendered, so the text needs to be worded so that it does not depend on any information only available in another section, such as the prelude. This may mean repeating some details. deprecations: - | List deprecations notes here, or remove this section. All of the list items in this section are combined when the release notes are rendered, so the text needs to be worded so that it does not depend on any information only available in another section, such as the prelude. This may mean repeating some details. critical: - | Add critical notes here, or remove this section. All of the list items in this section are combined when the release notes are rendered, so the text needs to be worded so that it does not depend on any information only available in another section, such as the prelude. This may mean repeating some details. security: - | Add security notes here, or remove this section. All of the list items in this section are combined when the release notes are rendered, so the text needs to be worded so that it does not depend on any information only available in another section, such as the prelude. This may mean repeating some details. fixes: - | Add normal bug fixes here, or remove this section. All of the list items in this section are combined when the release notes are rendered, so the text needs to be worded so that it does not depend on any information only available in another section, such as the prelude. This may mean repeating some details. other: - | Add other notes here, or remove this section. All of the list items in this section are combined when the release notes are rendered, so the text needs to be worded so that it does not depend on any information only available in another section, such as the prelude. This may mean repeating some details.","s":"Usage","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#usage","p":1672},{"i":1686,"t":"Here is an example of a commit from the osism/cfg-generics repository. --- features: - | The `requirements.yml` has been removed. The version will be set in the `run.sh` script for the seed process in the future exactly as later in the update process via the parameters `ANSIBLE_COLLECTION_SERVICES_VERSION` and `ANSIBLE_PLAYBOOKS_MANAGER_VERSION`. upgrade: - | In existing configuration repositories, the `environments/manager/requirements.yml` file can be removed after the generics have been synced.","s":"Example","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#example","p":1672},{"i":1688,"t":"We do not create release notes in the following repositories: osism/github-manager osism/osism.github.io osism/release","s":"Repositories without release notes","u":"/docs/iaas/guides/other-guides/developer-guide/releases","h":"#repositories-without-release-notes","p":1672},{"i":1690,"t":"Scripts are included in container images to simplify development work and to enable testing and hotfixes in running environments. What scripts are available and how to use them is described in this chapter. The change.sh script may be used to update repositories to development branches. Different targets may be passed as a first parameter and existing branch names as a second. The availability of targets depends on the container it is run in. For the osismclient container /change.sh osism for the osism/python-osism repository For the inventory-reonciler container /change.sh osism for the osism/python-osism repository /change.sh generics for the osism/cfg-generics repository /change.sh defaults for the osism/defaults repository /change.sh release for the osism/release repository For the osism-ansible container /change.sh osism for the osism/python-osism repository /change.sh playbooks for the osism/ansible-playbooks repository /change.sh [services|commons|validations] for the osism/ansible-collection-services, osism/ansible-collection-commons, and osism/ansible-collection-validations repositories For the ceph-ansible container /change.sh osism for the osism/python-osism repository /change.sh operations for the osism/kolla-operations repository For the kolla-ansible container /change.sh osism for the osism/python-osism repository /change.sh operations for the osism/kolla-operations repository /change.sh kolla-ansible for the openstack/kolla-ansible repository In this example, the main branch of osism/ansible-collection-services is used in the osism-ansible container. docker exec -u root -it osism-ansible /change.sh services main The respective container should always be restarted after a change. docker restart osism-ansible If something has been changed in the defaults and is to be tested, this must be changed in the inventory reconciler service. Regardless of which of the Ansible services the customised defaults are intended for. docker exec -u root -it manager-inventory_reconciler-1 /change.sh defaults main docker restart manager-inventory_reconciler-1","s":"Scripts","u":"/docs/iaas/guides/other-guides/developer-guide/scripts","h":"","p":1689},{"i":1693,"t":"We implement all the default rules of Ansible Lint. All default rules can be found in the Ansible Lint documentation.","s":"Ansible","u":"/docs/iaas/guides/other-guides/style-guide","h":"#ansible","p":1691},{"i":1695,"t":"Tasks must always have names. The only exception allowed is for forked playbooks. A name never starts with a small letter Names are written in present tense No punctuation is used in names","s":"Task names","u":"/docs/iaas/guides/other-guides/style-guide","h":"#task-names","p":1691},{"i":1697,"t":"The become directive is only set when needed and is always set explicitly for each task that needs it. Blocks, roles, or playbooks are never executed in a privileged mode. We always insert the become directive between the name of a task and the task itself. This also applies to related directives like become_user or become_flags. This is for better visibility if a task is privileged or not. - name: Copy hddtemp configuration file become: true ansible.builtin.copy: src: \"{{ ansible_os_family }}/hddtemp\" dest: \"{{ hddtemp_conf_file }}\" owner: root group: root mode: 0644 notify: Restart hddtemp service","s":"become directive","u":"/docs/iaas/guides/other-guides/style-guide","h":"#become-directive","p":1691},{"i":1699,"t":"If you need to use the when directive add this at the end-section from the task where it is needed. This makes the code easier to understand for others. - name: \"Archive existing {{ resolvconf_file }} file\" become: true ansible.posix.synchronize: src: \"/etc/resolv.conf\" dest: \"/etc/resolv.conf.{{ ansible_date_time.date }}\" archive: true delegate_to: \"{{ inventory_hostname }}\" when: stat_resolvconf_file.stat.islnk is defined and not stat_resolvconf_file.stat.islnk","s":"when directive","u":"/docs/iaas/guides/other-guides/style-guide","h":"#when-directive","p":1691},{"i":1701,"t":"Defaults that provide a list are always defined as in the following example. docker_hosts_defaults sets the defaults in the role. Overriding is only possible with the defaults repository. In the configuration repository, docker_hosts_extra is then used to add additional items to the list. docker_hosts itself is never modified from the outside. docker_hosts_defaults: - \"unix:///var/run/docker.sock\" docker_hosts_extra: [] docker_hosts: \"{{ docker_hosts_defaults + docker_hosts_extra }}\"","s":"Lists as defaults","u":"/docs/iaas/guides/other-guides/style-guide","h":"#lists-as-defaults","p":1691},{"i":1705,"t":"Black is a popular Python code formatter that automatically formats your code to adhere to a consistent style. We use it to automatically format the syntax of Python. A job is running in the CI that checks, if Black has been applied. Therefore, format the files with Black accordingly in advance.","s":"Python","u":"/docs/iaas/guides/other-guides/style-guide","h":"#python","p":1691},{"i":1707,"t":"pip install black","s":"Installation","u":"/docs/iaas/guides/other-guides/style-guide","h":"#installation","p":1691},{"i":1709,"t":"black myfile.py","s":"Formatting a Single File","u":"/docs/iaas/guides/other-guides/style-guide","h":"#formatting-a-single-file","p":1691},{"i":1711,"t":"black file1.py file2.py dir/","s":"Formatting Multiple Files and/or directories","u":"/docs/iaas/guides/other-guides/style-guide","h":"#formatting-multiple-files-andor-directories","p":1691},{"i":1713,"t":"This command will format all Python files in the current directory and its subdirectories: black .","s":"Formatting an Entire Project","u":"/docs/iaas/guides/other-guides/style-guide","h":"#formatting-an-entire-project","p":1691},{"i":1715,"t":"Running Black with the --check option performs a dry run and reports files that would be changed without actually modifying them: black --check myfile.py","s":"Check Mode (Dry Run)","u":"/docs/iaas/guides/other-guides/style-guide","h":"#check-mode-dry-run","p":1691},{"i":1717,"t":"You can exclude files or directories from formatting using the --exclude option: black --exclude=dir_to_exclude/ .","s":"Excluding Files or Directories","u":"/docs/iaas/guides/other-guides/style-guide","h":"#excluding-files-or-directories","p":1691},{"i":1719,"t":"Many code editors have extensions or plugins that can automatically run Black on your code. For example, if you're using VSCode or PyCharm, you can easily integrate it into your IDE.","s":"Integration with Code Editors","u":"/docs/iaas/guides/other-guides/style-guide","h":"#integration-with-code-editors","p":1691},{"i":1721,"t":"job-output.txt: […] 2023-11-16 14:38:14.149756 | TASK [python-black : Install pip module black] 2023-11-16 14:38:18.717886 | ubuntu-jammy | changed 2023-11-16 14:38:18.723062 | 2023-11-16 14:38:18.723137 | TASK [python-black : Format code with Black if there is nothing to exclude] 2023-11-16 14:38:19.138060 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/adminer.py 2023-11-16 14:38:19.151965 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/bird.py 2023-11-16 14:38:19.163608 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/auditd.py 2023-11-16 14:38:19.187772 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cephclient/package.py 2023-11-16 14:38:19.192695 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cephclient/container.py 2023-11-16 14:38:19.219694 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/cgit.py 2023-11-16 14:38:19.230577 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/dnsdist.py 2023-11-16 14:38:19.275681 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/hddtemp/redhat.py 2023-11-16 14:38:19.300350 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/homer.py 2023-11-16 14:38:19.310641 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/lldpd.py 2023-11-16 14:38:19.318096 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/docker.py 2023-11-16 14:38:19.329099 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/osquery.py 2023-11-16 14:38:19.344766 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/rsyslog.py 2023-11-16 14:38:19.358190 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/smartd.py 2023-11-16 14:38:19.363578 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/tuned.py 2023-11-16 14:38:19.389205 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/molecule/delegated/tests/util/util.py 2023-11-16 14:38:19.406360 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_container_facts.py 2023-11-16 14:38:19.415046 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/filter/address.py 2023-11-16 14:38:19.473508 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_toolbox.py 2023-11-16 14:38:19.908963 | ubuntu-jammy | would reformat /home/zuul/src/github.com/osism/ansible-collection-services/plugins/modules/kolla_docker.py 2023-11-16 14:38:19.914395 | ubuntu-jammy | 2023-11-16 14:38:19.914412 | ubuntu-jammy | Oh no! 💥 💔 💥 2023-11-16 14:38:19.914419 | ubuntu-jammy | 20 files would be reformatted, 18 files would be left unchanged. 2023-11-16 14:38:20.249358 | ubuntu-jammy | ERROR 2023-11-16 14:38:20.249501 | ubuntu-jammy | { 2023-11-16 14:38:20.249533 | ubuntu-jammy | \"delta\": \"0:00:01.053565\", 2023-11-16 14:38:20.249553 | ubuntu-jammy | \"end\": \"2023-11-16 14:38:19.932073\", 2023-11-16 14:38:20.249571 | ubuntu-jammy | \"msg\": \"non-zero return code\", 2023-11-16 14:38:20.249587 | ubuntu-jammy | \"rc\": 1, 2023-11-16 14:38:20.249603 | ubuntu-jammy | \"start\": \"2023-11-16 14:38:18.878508\" 2023-11-16 14:38:20.249618 | ubuntu-jammy | } […]","s":"Example of failed python-black Zuul job","u":"/docs/iaas/guides/other-guides/style-guide","h":"#example-of-failed-python-black-zuul-job","p":1691},{"i":1723,"t":"💡 The Troubleshooting Guide describe how to solve issues.","s":"Troubleshooting Guide","u":"/docs/iaas/guides/troubleshooting-guide/","h":"","p":1722},{"i":1726,"t":"The official Ceph documentation is located on https://docs.ceph.com/en/latest/rados/troubleshooting/ It is strongly advised to use the documentation for the version being used. Pacific - https://docs.ceph.com/en/pacific/rados/troubleshooting/ Quincy - https://docs.ceph.com/en/quincy/rados/troubleshooting/ Reef - https://docs.ceph.com/en/reef/rados/troubleshooting/","s":"Where to find docs","u":"/docs/iaas/guides/troubleshooting-guide/ceph","h":"#where-to-find-docs","p":1724},{"i":1728,"t":"The block device sdf has errors. You can see this in the kernel ring buffer, for example. $ sudo dmesg [...] [14062414.575715] sd 14:0:5:0: [sdf] tag#2120 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=1s [14062414.575722] sd 14:0:5:0: [sdf] tag#2120 Sense Key : Medium Error [current] [descriptor] [14062414.575725] sd 14:0:5:0: [sdf] tag#2120 Add. Sense: Unrecovered read error [14062414.575728] sd 14:0:5:0: [sdf] tag#2120 CDB: Read(16) 88 00 00 00 00 01 09 7c d9 50 00 00 00 80 00 00 [14062414.575730] critical medium error, dev sdf, sector 4454144360 op 0x0:(READ) flags 0x0 phys_seg 13 prio class 2 It may also be displayed in the health details of Ceph. $ ceph -s [...] health: HEALTH_WARN Too many repaired reads on 1 OSDs [...] $ ceph health detail HEALTH_WARN Too many repaired reads on 1 OSDs [WRN] OSD_TOO_MANY_REPAIRS: Too many repaired reads on 1 OSDs osd.17 had 13 reads repaire In this case the block device sdf is in the storage node sto1001. The OSD assigned to this block device can be determined. $ ceph device ls | grep 'sto1001:sdf' SEAGATE_ST16000NM004J_ZR604ZDZ0000C210PWE9 sto1001:sdf osd.17 If you only know the OSD ID, you can also determine the associated block device and the storage node. $ ceph device ls | grep osd.17 [...] SEAGATE_ST16000NM004J_ZR604ZDZ0000C210PWE9 sto1001:sdf osd.17 The broken OSD can be removed from the Ceph cluster. The Ceph cluster is then rebalanced. This can take some time and cause a high level of activity on the Ceph cluster. $ ceph osd out osd.17 marked out osd.17. On the storage node disable the OSD service for the OSD. $ sudo systemctl stop ceph-osd@17.service","s":"Critical medium error","u":"/docs/iaas/guides/troubleshooting-guide/ceph","h":"#critical-medium-error","p":1724},{"i":1731,"t":"Sometimes it is necessary to reset the entire manager service. warning This is a disruptive action. Data is lost in the process. For example, the database of the ARA service. Stop the manager service sudo systemctl stop docker-compose@manager.service Files on the /share volume are backed up in advance and restored after the manager service is started. docker run --rm \\ --mount source=manager_share,target=/share \\ --volume $(pwd):/backup \\ busybox \\ tar -czvf /backup/manager-share-$(date +%Y%m%d).tar.gz /share Delete the manager service. This is a disruptive action. docker compose --project-directory /opt/manager down -v Start the manager service sudo systemctl start docker-compose@manager.service Restore the files on the /share volume. docker run --rm \\ --mount source=manager_share,target=/share \\ --volume $(pwd):/backup \\ busybox \\ tar -xzvf /backup/manager-share-$(date +%Y%m%d).tar.gz -C / Check that manager service is healthy docker compose --project-directory /opt/manager ps Depending on what the manager service looks like, this output may vary. NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS ceph-ansible quay.io/osism/ceph-ansible:quincy \"/entrypoint.sh osis…\" ceph-ansible About a minute ago Up About a minute (healthy) kolla-ansible quay.io/osism/kolla-ansible:2023.2 \"/entrypoint.sh osis…\" kolla-ansible About a minute ago Up About a minute (healthy) manager-api-1 quay.io/osism/osism:latest \"osism service api\" api About a minute ago Up About a minute (healthy) 192.168.16.5:8000->8000/tcp manager-ara-server-1 quay.io/osism/ara-server:latest \"sh -c '/wait && /ru…\" ara-server About a minute ago Up About a minute (healthy) 8000/tcp manager-beat-1 quay.io/osism/osism:latest \"osism service beat\" beat About a minute ago Up About a minute (healthy) manager-conductor-1 quay.io/osism/osism:latest \"osism worker conduc…\" conductor About a minute ago Up About a minute (healthy) manager-flower-1 quay.io/osism/osism:latest \"osism service flower\" flower About a minute ago Up About a minute (healthy) manager-inventory_reconciler-1 quay.io/osism/inventory-reconciler:latest \"/sbin/tini -- /entr…\" inventory_reconciler About a minute ago Up About a minute (healthy) manager-listener-1 quay.io/osism/osism:latest \"osism service liste…\" listener About a minute ago Up About a minute (healthy) manager-mariadb-1 index.docker.io/library/mariadb:11.3.2 \"docker-entrypoint.s…\" mariadb About a minute ago Up About a minute (healthy) 3306/tcp manager-netbox-1 quay.io/osism/osism-netbox:latest \"osism worker netbox\" netbox About a minute ago Up About a minute (healthy) manager-openstack-1 quay.io/osism/osism:latest \"osism worker openst…\" openstack About a minute ago Up About a minute (healthy) manager-redis-1 index.docker.io/library/redis:7.2.4-alpine \"docker-entrypoint.s…\" redis About a minute ago Up About a minute (healthy) 6379/tcp manager-watchdog-1 quay.io/osism/osism:latest \"osism service watch…\" watchdog About a minute ago Up About a minute (healthy) osism-ansible quay.io/osism/osism-ansible:latest \"/entrypoint.sh osis…\" osism-ansible About a minute ago Up About a minute (healthy) osismclient quay.io/osism/osism:latest \"sleep infinity\" osismclient About a minute ago Up About a minute When the manager service is healthy, the inventory and the fact cache must be rebuilt. osism reconciler sync osism apply facts","s":"Reset","u":"/docs/iaas/guides/troubleshooting-guide/manager","h":"#reset","p":1729},{"i":1734,"t":"Problem: TASK [keystone : Creating keystone database] *********************************** fatal: [testbed-node-0]: FAILED! => changed=false action: mysql_db msg: 'unable to find /var/lib/ansible/.my.cnf. Exception message: (2003, \"Can''t connect to MySQL server on ''api-int.local'' ([Errno 111] Connection refused)\")' Solution: Restart the kolla_toolbox container. in this case on the node testbed-node-0. $ osism console testbed-node-0/ testbed-node-0>>> restart kolla_toolbox kolla_toolbox testbed-node-0>>>","s":"Database creation fails","u":"/docs/iaas/guides/troubleshooting-guide/openstack","h":"#database-creation-fails","p":1732},{"i":1736,"t":"In the examples, the pull of images (if supported by a role) is always run first. While this is optional, it is recommended to speed up the execution of the upgrade action in the second step. This significantly reduces the times required for the restart from a service.","s":"Upgrade Guide","u":"/docs/iaas/guides/upgrade-guide/","h":"","p":1735},{"i":1738,"t":"note We use Zuul CI as a CI service for OSISM. The service is not required for the use of OSISM itself. However, as we deploy and provide Zuul CI ourselves, the documentation for this is also included in the OSISM Developer Guide. Our Zuul CI instance is available at zuul.services.betacloud.xyz. osism.services.zuul is the Ansible role to set up Zuul CI as a single-node installation with Docker Compose.","s":"Zuul CI","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"","p":1737},{"i":1740,"t":"On CI jobs that consume a lot of resources and have long runtimes we use a label zuul to run these jobs. These CI jobs run in the label pipeline and are only started once after the label has been assigned. If changes are made to a PR, the label must first be removed and then reassigned for a new run of the CI jobs. The zuul label is usable in the following repositories: osism/container-images-kolla osism/testbed","s":"The zuul label","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#the-zuul-label","p":1737},{"i":1743,"t":"Set up a server (VM) with Ubuntu Server 22.04 LTS and make sure that these packages are installed: docker.io docker-compose python3-docker python3-openstackclient Also configure your deploy user to be in the docker group and set up the account for the zuul user. TCP-Ports 80 and 443 should be accessible from the internet, port 22 for management via SSH will also often be useful, but not required. If you have an OpenStack tenant where you want to deploy the Zuul server, you can download and adapt this example playbook: --- - name: Setup zuul server hosts: localhost vars: cloud: mycloud flavor: myflavor image: Ubuntu 22.04 keypair: mykeypair network: myprivatenet project: myproject zuul_domain: mydomain.xyz. zuul_fqdn: \"zuul01.services.{{ zuul_domain }}\" zuul_host: zuul01 tasks: - name: Create security group openstack.cloud.security_group: cloud: \"{{ cloud }}\" name: \"{{ project }}-zuul\" description: \"Default security group for {{ project }}-zuul\" - name: Create security group rule (icmp) openstack.cloud.security_group_rule: cloud: \"{{ cloud }}\" security_group: \"{{ project }}-zuul\" protocol: icmp remote_ip_prefix: 0.0.0.0/0 - name: Create security group rules (tcp) openstack.cloud.security_group_rule: cloud: \"{{ cloud }}\" security_group: \"{{ project }}-zuul\" protocol: tcp remote_ip_prefix: 0.0.0.0/0 port_range_min: \"{{ item }}\" port_range_max: \"{{ item }}\" loop: - 22 - 80 - 443 - name: Create zuul server openstack.cloud.server: cloud: \"{{ cloud }}\" flavor: \"{{ flavor }}\" image: \"{{ image }}\" key_name: \"{{ keypair }}\" name: \"{{ zuul_host }}\" network: \"{{ network }}\" security_groups: - default - \"{{ project }}-zuul\" meta: hostname: \"{{ zuul_host }}\" register: zuul_server - name: Add host ansible.builtin.add_host: name: \"{{ zuul_server.openstack.accessIPv4 }}\" groups: zuul ansible_user: ubuntu - name: Initialize zuul server hosts: zuul gather_facts: false vars: zuul_user: zuul tasks: - name: Wait for system to become reachable ansible.builtin.wait_for_connection: - name: Update all packages ansible.builtin.apt: update_cache: true name: '*' state: latest become: true - name: Install required packages ansible.builtin.apt: name: - docker.io - docker-compose - python3-docker - python3-openstackclient become: true - name: Add user to docker group ansible.builtin.user: name: \"{{ ansible_ssh_user }}\" groups: docker append: true become: true - name: Add group ansible.builtin.group: name: \"{{ zuul_user }}\" become: true - name: Add user ansible.builtin.user: name: \"{{ zuul_user }}\" uid: 10001 shell: /bin/bash group: \"{{ zuul_user }}\" groups: sudo append: true home: \"/home/{{ zuul_user }}\" become: true","s":"Server preparation","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#server-preparation","p":1737},{"i":1745,"t":"There need to be some secrets handed to the deployment, the suggested method is to have a dedicated file that contains them, which will be included in the example playbook below via a vars_files statement. This allows you to easily protect all your secrets by applying ansible-vault encrypt to that file. The contents of this file should look like: --- zuul_auth_secret: secret used for zuul web auth webhook_token: token defined for github webhooks db_user_pass: DB password for the zuul user db_root_pass: DB root password In addition you need to prepare some further data that needs to be placed into a files directory in order to be consumed by the zuul role. These are: A clouds.yaml file for nodepool. This will be used by nodepool-builder to upload the newly created images and by nodepool-launcher to start instances running these images, these will then be handed over to Zuul as CI nodes. An SSH private key in the file nodepool and the matching public key in nodepool.pub. These will be used by nodepool and zuul to access the CI nodes via SSH. An SSL private key and certificate pasted together in a file named server.crt. This file will be used in the https setup by the webserver. The certificate should cover both zuul_webserver_fqdn and zuul_logserver_fqdn.","s":"Define secrets","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#define-secrets","p":1737},{"i":1747,"t":"In order for zuul to be able to interact with repositories hosted on github, you need to set up a github application. Follow the instructions at https://zuul-ci.org/docs/zuul/latest/drivers/github.html#application to do this. The webhook token to use is the one defined in the pervious section. Use github in place of for the Webhook URL in the app configuration. After the app has been created, place the PEM files that you downloaded into a directory named pem-files: $ mkdir -p pem-files $ cp ~/Downloads/my-org-zuul.*.private-key.pem pem-files/my-org-zuul.pem Now add the information about your github app to vars.yml: github_app_id: 000000 github_pem_name: my-org-zuul","s":"Github App setup","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#github-app-setup","p":1737},{"i":1749,"t":"Save this file as main.yaml: --- - name: Set up zuul hosts: zuul.example.com vars_files: - vars.yml pre_tasks: - name: Create /etc/openstack/ ansible.builtin.file: state: directory path: /etc/openstack owner: root group: root mode: 0755 become: true - name: Deploy clouds.yaml file ansible.builtin.copy: src: clouds.yaml dest: /etc/openstack/clouds.yaml owner: root group: zuul mode: '0640' become: true - name: Create keypair in the cloud openstack.cloud.keypair: cloud: osism-ci name: osism-zuul public_key: \"{{ lookup('file', 'nodepool.pub') }}\" become: true roles: - name: Execute zuul role role: zuul vars: zuul_connections: github: driver: github webhook_token: \"{{ webhook_token }}\" app_id: \"{{ github_app_id }}\" app_key: \"/etc/zuul/pem-files/{{ github_pem_name }}.pem\" opendevorg: name: opendev driver: git baseurl: https://opendev.org zuul_tenants: - tenant: name: my-tenant-name source: opendevorg: untrusted-projects: - zuul/zuul-jobs: include: - job github: config-projects: - my-org/zuul_demo_config: load-branch: main untrusted-projects: - my-org/zuul_demo_repo become: true Create an inventory file containing the login information for your zuul server, it might look like: zuul.example.com ansible_host=192.0.2.2 ansible_user=ubuntu Then you can deploy your zuul server by running: ansible-playbook -i inventory main.yaml This will deploy a simple zuul setup with sample example repos being referenced. You can fork the example repos from the https://github.com/osism tenant or just use them as a guide for how to build your own. For further information about how to tune this setup for you specific environment, have a look at the sections covering nodepool and tenant configuration.","s":"Example Playbook","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#example-playbook","p":1737},{"i":1752,"t":"Have you thought of naming your repos with the prefix of your organization? release should be osism/release for example.","s":"Your git repos are not displayed?","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#your-git-repos-are-not-displayed","p":1737},{"i":1754,"t":"For config-projects you set this value in the tenant-configuration with the load-branch stanza. For untrusted-projects you set this value in the config-projects project sections AND in EVERY untrusted-project. Each project section needs to have the default-branch stanza.","s":"Your git repos are using the wrong branch?","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#your-git-repos-are-using-the-wrong-branch","p":1737},{"i":1756,"t":"Check, if the IP of the logfile server is really correct. In combination with GitHub there is a bug which keeps the GitHub App posting to the old IP even if the webhook IP was changed. Current workaround: Delete the old GitHub App and create a new one.","s":"Your logs are not displayed in the web-UI?","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#your-logs-are-not-displayed-in-the-web-ui","p":1737},{"i":1758,"t":"Sometimes jobs get stuck in a pipeline and are never scheduled. They must then be removed manually so that they do not block other jobs. First create a local .zuul.conf configuration file in your home directory. [osism] url=https://zuul.services.betacloud.xyz/ auth_token=TOKEN tenant=osism The required auth token can be generated on the Zuul control node with the `zuul-admin` client. docker exec -it zuul_scheduler zuul-admin create-auth-token --user USER --tenant osism --expires-in 3600 --auth-config zuul_operator With the [zuul-client](https://zuul-ci.org/docs/zuul-client/index.html) it is possible to remove the two hanging jobs from the screenshot. zuul-client --use-config osism dequeue --pipeline periodic-daily --project osism/k8s-capi-images --ref refs/heads/main zuul-client --use-config osism dequeue --pipeline periodic-daily --project osism/cfg-generics --ref refs/heads/main ## Important daily CI jobs * [osism/container-image-ceph-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-ceph-ansible&pipeline=periodic-daily&skip=0) * [osism/container-image-kolla-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-kolla-ansible&pipeline=periodic-daily&skip=0) * [osism/container-image-osism-ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-image-osism-ansible&pipeline=periodic-daily&skip=0) * [osism/container-images-kolla](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Fcontainer-images-kolla&pipeline=periodic-midnight&skip=0) * [osism/testbed](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2Ftestbed&pipeline=periodic-daily&skip=0)","s":"Hanging jobs in a pipeline?","u":"/docs/iaas/guides/other-guides/developer-guide/zuul","h":"#hanging-jobs-in-a-pipeline","p":1737},{"i":1760,"t":"osism apply ceph-rolling_update -e ireallymeanit=yes osism apply cephclient","s":"Ceph","u":"/docs/iaas/guides/upgrade-guide/ceph","h":"","p":1759},{"i":1762,"t":"OpenSearch OpenSearch dashboards is also upgraded with the opensearch role. osism apply -a pull opensearch osism apply -a upgrade opensearch Prometheus osism apply -a pull prometheus osism apply prometheus Grafana osism apply -a pull grafana osism apply -a upgrade grafana","s":"Logging & Monitoring","u":"/docs/iaas/guides/upgrade-guide/logging-monitoring","h":"","p":1761},{"i":1764,"t":"The Docker version used is defined via the parameter docker_version in the file environments/configuration.yml. docker_version: '5:20.10.24' All installable versions can be displayed with apt-cache madison docker-ce. $ apt-cache madison docker-ce docker-ce | 5:24.0.6-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:24.0.5-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:24.0.4-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:24.0.3-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:24.0.2-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:24.0.1-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:24.0.0-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:23.0.6-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:23.0.5-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:23.0.4-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:23.0.3-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:23.0.2-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:23.0.1-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:23.0.0-1~ubuntu.22.04~jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:20.10.24~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:20.10.23~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:20.10.22~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:20.10.21~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:20.10.20~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:20.10.19~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:20.10.18~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:20.10.17~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:20.10.16~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:20.10.15~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:20.10.14~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages docker-ce | 5:20.10.13~3-0~ubuntu-jammy | https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages If, for example, you want to change the Docker version from 20.10.24 to 24.0.6, docker_version in environments/configuration.yml is changed accordingly. The 5: prefix is placed in front of the version. Commit and push the changes to your configuration repository afterwards. The upgrade of Docker is then done with the OSISM CLI. Docker on the manager itself is updated differently. This does not work on the manager itself because the Docker service may be started during the upgrade and individual containers may be started as a result. This would interrupt the run of the role itself. osism apply docker -l 'docker:!manager' By default, serial is set to 1 so that the the hosts are upgrade one after the other. To adjust this, either use the osism_serial dictionary in the environments/configuration.yml file to change the value in docker or append -e serial=10% to upgrade, for example, 10% with each iteration. Please note that it is not a good idea to upgrade more than one Docker service at a time. This can lead to anomalies, especially on storage nodes and control nodes. It is recommended not to change the default of 1. osism_serial: docker: 10% On the manager itself, the run.sh script in the manager environment of the configuration must currently be used to upgrade the Docker service. In a future release a dedicated osism update docker command will be available for this purpose. cd /opt/configuration/environments/manager ANSIBLE_ASK_VAULT_PASS=True ./run.sh docker","s":"Docker","u":"/docs/iaas/guides/upgrade-guide/docker","h":"","p":1763},{"i":1766,"t":"When upgrading, the Docker service is restarted. As a result, it can come to a restart of the running containers. This can lead to interruptions in individual services. A change in /etc/docker/daemon.json due to a new configuration parameter etc. can also result in a required restart. Whether the containers are restarted when the Docker Service is restarted depends on whether the Live Restore feature is used. This can be configured via the parameter docker_live_restore. Live restore is enabled by default. It is important to set the docker_live_restore parameter explicitly as a string. This means docker_live_restore: \"false\" or docker_live_restore: \"true\". But even if the Live Restore feature is enabled, certain upgrades will cause running containers to be restarted: Live restore allows you to keep containers running across Docker daemon updates, but is only supported when installing patch releases (YY.MM.x), not for major (YY.MM) daemon upgrades. There are two ways to prevent a restart of the Docker service during an upgrade. If the restart behaviour of the Docker service is changed, always make sure to restart the Docker service manually afterwards (e.g. by a system reboot). A host group can be defined via the parameter docker_ignore_restart_groupname. The restart of the Docker service is not triggered for all hosts in this group. By default, docker_ignore_restart_groupname is set to manager. The parameter is best set in the environments/configuration.yml file when making an adjustment. For example, to prevent the restart on all hosts, docker_ignore_restart_groupname is set to generic. docker_ignore_restart_groupname: generic With the parameter docker_allow_restart, the restart of the Docker service can be prevented. By default, docker_allow_restart is set to true. It is recommended to set this parameter only at runtime. Otherwise, the best place for the parameter is the environments/configuration.yml file. osism apply docker -e docker_allow_restart=false","s":"Restart behaviour","u":"/docs/iaas/guides/upgrade-guide/docker","h":"#restart-behaviour","p":1763},{"i":1768,"t":"Kubernetes This is only necessary if the internal Kubernetes cluster has also been deployed. This can be checked by executing kubectl get nodes on the manager node. osism apply k3s-upgrade Cron, Fluentd & Kolla Toolbox The common role of Kolla is used to manage the services cron, fluentd and kolla-toolbox. It is important to do this upgrade before any other upgrades in the Kolla environment, as parts of the other upgrades depend on the kolla-toolbox service. osism apply -a pull common osism apply -a upgrade common Loadbalancer osism apply -a pull loadbalancer osism apply -a upgrade loadbalancer Redis osism apply -a pull redis osism apply -a upgrade redis Memcached osism apply -a pull memcached osism apply -a upgrade memcached RabbitMQ osism apply -a pull rabbitmq osism apply -a upgrade rabbitmq MariaDB osism apply -a pull mariadb osism apply -a upgrade mariadb","s":"Infrastructure","u":"/docs/iaas/guides/upgrade-guide/infrastructure","h":"","p":1767},{"i":1770,"t":"With the OSISM Testbed, it is possible to run a full Sovereign Cloud Stack deployment on an existing OpenStack environment such as Cleura or REGIO.cloud. OSISM is the reference implementation for the Infrastructure as a Service (IaaS) layer in the Sovereign Cloud Stack (SCS) project. The OSISM Testbed is therefore used in the SCS project to test and work on the Instrastructure as a Service layer. The OSISM Testbed is intended as a playground. Further services and integration will be added over time. A increasing number of best practices and experiences from the productive deployments will be included here in the future. It will become more production-like over time. However, at no point does it claim to represent a production setup exactly.","s":"Testbed","u":"/docs/iaas/guides/other-guides/testbed","h":"","p":1769},{"i":1773,"t":"The usual prerequisite is to have an account on one of the supported OpenStack cloud providers. As the OSISM Testbed also virtualizes systems itself, the OpenStack cluster should provide the capabilities for nested virtualization. It is not part of this guide to describe the registration with the individual cloud providers. Please contact the respective cloud provider for this. Product Provider Profile name Note Cleura Cleura cleura Fuga Cloud FUGA fuga HuaweiCloud HuaweiCloud huaweicloud OVH OVH ovh OpenTelekomCloud T-Systems otc pluscloud open plusserver pluscloudopen pluscloud SCS Test plusserver gx-scs REGIO.cloud OSISM regiocloud REGIO.cloud OSISM regio-fast boot from NVMe SSD backed volumes Wavestack noris network wavestack For each cloud provider listed in the table, a predefined profile is available in the terraform/environments directory. This profile contains the name of the public network, which flavors to use, etc. Here is an example from the profile for REGIO.cloud. flavor_manager = \"SCS-4V-16-50\" flavor_node = \"SCS-8V-32-50\" volume_type = \"ssd\" image = \"Ubuntu 22.04\" image_node = \"Ubuntu 22.04\" public = \"public\" availability_zone = \"nova\" volume_availability_zone = \"nova\" network_availability_zone = \"nova\"","s":"Cloud access","u":"/docs/iaas/guides/other-guides/testbed","h":"#cloud-access","p":1769},{"i":1775,"t":"The OSISM Testbed requires at least the following project quota when using the default flavors: Quantity Resource Note 4 Instances 28 VCPUs + 112 GByte RAM (3 modes, 1 manager) 9 Volumes 90 GByte volume storage 1 Floating IP 1 Keypair 3 Security group 16 Security group rules 1 Network 1 Subetwork 6 Ports 1 Router","s":"Cloud resources","u":"/docs/iaas/guides/other-guides/testbed","h":"#cloud-resources","p":1769},{"i":1777,"t":"make must be installed on the system Wireguard or sshuttle must be installed on your system for VPN access Python must be installed, the Python version used must be at least 3.10, otherwise the current Ansible release cannot be used (details in the Ansible support matrix) python3-venv must be installed for managing Python dependencies like Ansible","s":"Software","u":"/docs/iaas/guides/other-guides/testbed","h":"#software","p":1769},{"i":1779,"t":"This section describes step by step how to deploy the OSISM Testbed. Request access from the administrator of the respective cloud or get access to an OpenStack cloud. Clone the osism/testbed repository. The repository can also be cloned to any other location. mkdir -p ~/src/github.com/osism git clone https://github.com/osism/testbed ~/src/github.com/osism/testbed cd ~/src/github.com/osism/testbed Configure your cloud access profile The access data for the cloud provider used is stored in terraform/clouds.yaml and (optionally) in terraform/secure.yaml (same structure, if you want to store credentials on a separate place). In file terraform/clouds.yaml.sample you will find examples of typical setups. Settings that are identical for all users of a cloud can be defined centrally via the profiles of the file terraform/clouds-public.yaml. You can reference these settings by using the profile parameter in cloud-specific definition in terraform/clouds.yaml. The user specific settings of the clouds.yaml file are provided by the cloud provider. Please check the documentation of the cloud provider you are using or their support for details. REGIO.cloud is used as an example here. The cloud name in clouds.yaml and the environment name (value of ENVIRONMENT) are regiocloud in this case. It is important that the name of the cloud in clouds.yaml matches the name of the environment to be used. The names must be identical. It is currently not possible to name the cloud regiocloud-123 in clouds.yaml if the environment is regiocloud. If another cloud is used, replace regiocloud with the respective profile name from the table above. Application Credentials Username/Password The use of application credentials is preferred. This way it is not necessary to store details like username, project name or sensitive information like the password in the clouds.yaml file. The application credentials can be found in Horizon under Identity. Use OSISM Testbed as name and click Create Application Credential. terraform/clouds.yaml clouds: regiocloud: profile: regiocloud auth: application_credential_id: ID application_credential_secret: SECRET auth_type: \"v3applicationcredential\" If you want to make use of terraform/secure.yaml add your application credential secret there instead of terraform/clouds.yaml. terraform/secure.yaml clouds: regiocloud: auth: application_credential_secret: SECRET terraform/clouds.yaml clouds: regiocloud: profile: regiocloud auth: project_name: PROJECT username: USERNAME project_domain_name: DOMAIN user_domain_name: DOMAIN If you want to make use of terraform/secure.yaml add your password there instead of terraform/clouds.yaml. terraform/secure.yaml clouds: regiocloud: auth: password: PASSWORD Prepare the deployment. The versions of Ansible and OpenTofu are managed automatically and necessary dependencies are cloned. make prepare If any error occurs during preparation and you want to run the preparation again, it is important to run make wipe-local-install first. Otherwise the preparation will not be redone completely and necessary parts will be missing later on. Create the infrastructure with OpenTofu. make ENVIRONMENT=regiocloud create Deploy the OSISM manager and bootstrap all nodes. Deploy latest manager version Deploy a stable manager version make ENVIRONMENT=regiocloud manager make ENVIRONMENT=regiocloud VERSION_MANAGER=7.0.3 manager After the bootstrap, you can log in to the manager via SSH. make ENVIRONMENT=regiocloud login Yo can log in to the nodes of the cluster via the manager. osism console testbed-node-0 Deploy all services. Deployment in single steps Deployment of all services It is also possible to deploy the services step by step on the manager. To do this, first log in to the manager with make ENVIRONMENT=regiocloud login and then execute the deploy scripts one after the other. It is recommended to do this within a screen session. Deploying the services takes some time and depends on how much bandwidth is available, how the instances are equipped, etc. 90-120 minutes is not unusual when Ceph and OpenStack are fully deployed. To speed up the Ansible playbooks, ARA can be disabled. This is done by executing /opt/configuration/scripts/disable-ara.sh. Run this script before the deployment scripts. Afterwards no more logs are available in the ARA web interface. To re-enable ARA use /opt/configuration/scripts/enable-ara.sh. There is also the option of pre-population of images with /opt/configuration/scripts/pull-images.sh so that deployments do not have to be lengthy. Run this script before the deployment scripts. /opt/configuration/scripts/deploy/001-helper-services.sh /opt/configuration/scripts/deploy/005-kubernetes.sh /opt/configuration/scripts/deploy/100-ceph-services-basic.sh /opt/configuration/scripts/deploy/200-infrastructure-services-basic.sh /opt/configuration/scripts/deploy/300-openstack-services-basic.sh /opt/configuration/scripts/deploy/400-monitoring-services.sh Prepare OpenStack resources like public network, flavors and images by running /opt/configuration/scripts/bootstrap.sh. Run this script after the deployment scripts. info If you only want to deploy the monitoring services with /opt/configuration/scripts/deploy/400-monitoring-services.sh, a few dependencies must be deployed first. You can then use the monitoring services without having to install a complete OpenStack & Ceph environment. osism apply common osism apply loadbalancer osism apply opensearch osism apply mariadb In this single step deployment, Ceph, OpenStack and all necessary infrastructure services (MariaDB, RabbitMQ, ...) are deployed. Depending on the cloud, the deployment will take some time. Up to two hours is not unusual. make ENVIRONMENT=regiocloud deploy If you want to verify the deployment with refstack run /opt/configuration/scripts/check.sh. This step will take some time and is optional. The machine images required for the use of Kubernetes Cluster API and the amphora driver of OpenStack Octavia service are not provided by default to save resources on the OSISM Testbed and improve deployment time. These can be provisioned if required. /opt/configuration/scripts/bootstrap/301-openstack-octavia-amhpora-image.sh /opt/configuration/scripts/bootstrap/302-openstack-k8s-clusterapi-images.sh If you want you can create a test project with a test user after login. It also creates an instance with a volume attached to a network with a router. This step is optional. osism apply --environment openstack test When the OSISM Testbed is no longer needed, it can be deleted. make ENVIRONMENT=regiocloud clean","s":"Deployment","u":"/docs/iaas/guides/other-guides/testbed","h":"#deployment","p":1769},{"i":1781,"t":"Deployment must be completed at this point.","s":"Usage","u":"/docs/iaas/guides/other-guides/testbed","h":"#usage","p":1769},{"i":1783,"t":"The OSISM Testbed deployment currently uses hostnames in the domain testbed.osism.xyz. This is a real domain and we provide the DNS records matching the addresses used in the OSISM Testbed, so that once you connect to your testbed via a direct link or Wireguard, you can access hosts and servers by their hostname (e.g. ssh testbed-manager.testbed.osism.xyz). We also provide a wildcard TLS certificate signed by a custom CA for testbed.osism.xyz and *.testbed.osism.xyz. This CA is always used for each testbed. The CA is not regenerated and it is not planned to change this for the next 10 years. In order for these certificates to be recognized locally as valid, the CA environments/kolla/certificates/ca/testbed.crt must be imported locally.","s":"Custom CA","u":"/docs/iaas/guides/other-guides/testbed","h":"#custom-ca","p":1769},{"i":1785,"t":"Wireguard​ Install wireguard on your workstation, if you have not done this before. For instructions how to do it on your workstation, please have a look on the documentation of your used distribution. The wireguard documentation you will find here. Start the wireguard tunnel. (Press CTRL+c to keep the tunnel running forever. The make target also launches a browser tab with references to all services) make vpn-wireguard ENVIRONMENT=regiocloud If you want to connect to the OSISM Testbed from multiple clients, change the client IP address in the downloaded configuration file to be different on each client. If you only want to download the Wireguard configuration, you can use the vpn-wireguard-config target. The configuration is then available in the file wg-testbed-regiocloud.conf, for example. make vpn-wireguard-config ENVIRONMENT=regiocloud sshuttle​ If you do not want to use Wireguard you can also work with sshuttle. make vpn-sshuttle ENVIRONMENT=regiocloud killall sshuttle","s":"VPN access","u":"/docs/iaas/guides/other-guides/testbed","h":"#vpn-access","p":1769},{"i":1787,"t":"If you are unable to access the following domains, you can customize your local /etc/hosts with the following static entries. This may be necessary, for example, if you use Pi-hole and all DNS entries from a public DNS with a non-public IP address are filtered. # OSISM Testbed hosts 192.168.16.5 ara.testbed.osism.xyz ara 192.168.16.5 cgit.testbed.osism.xyz cgit 192.168.16.5 flower.testbed.osism.xyz flower 192.168.16.5 homer.testbed.osism.xyz homer 192.168.16.5 netbox.testbed.osism.xyz netbox 192.168.16.5 testbed-manager.testbed.osism.xyz testbed-manager 192.168.16.5 nexus.testbed.osism.xyz nexus 192.168.16.5 phpmyadmin.testbed.osism.xyz phpmyadmin 192.168.16.9 api-int.testbed.osism.xyz api-int 192.168.16.10 testbed-node-0.testbed.osism.xyz testbed-node-0 192.168.16.11 testbed-node-1.testbed.osism.xyz testbed-node-1 192.168.16.12 testbed-node-2.testbed.osism.xyz testbed-node-2 192.168.16.13 testbed-node-3.testbed.osism.xyz testbed-node-3 192.168.16.14 testbed-node-4.testbed.osism.xyz testbed-node-4 192.168.16.15 testbed-node-5.testbed.osism.xyz testbed-node-5 192.168.16.16 testbed-node-6.testbed.osism.xyz testbed-node-6 192.168.16.17 testbed-node-7.testbed.osism.xyz testbed-node-7 192.168.16.18 testbed-node-8.testbed.osism.xyz testbed-node-8 192.168.16.19 testbed-node-9.testbed.osism.xyz testbed-node-9 192.168.16.100 keycloak.testbed.osism.xyz keycloak 192.168.16.254 api.testbed.osism.xyz api","s":"Static entries in /etc/hosts","u":"/docs/iaas/guides/other-guides/testbed","h":"#static-entries-in-etchosts","p":1769},{"i":1789,"t":"All SSL enabled services within the OSISM Testbed use certs which are signed by the self-signed OSISM Testbed CA (Download the file and import it as certification authority to your browser). If you want to access the services please choose the URL from the following table. Name URL Username Password Note ARA https://ara.testbed.osism.xyz ara password Ceph https://api-int.testbed.osism.xyz:8140 admin password Flower https://flower.testbed.osism.xyz Grafana https://api-int.testbed.osism.xyz:3000 admin password HAProxy (testbed-node-0) http://testbed-node-0.testbed.osism.xyz:1984 openstack password HAProxy (testbed-node-1) http://testbed-node-1.testbed.osism.xyz:1984 openstack password HAProxy (testbed-node-2) http://testbed-node-2.testbed.osism.xyz:1984 openstack password Homer https://homer.testbed.osism.xyz Horizon (via Keycloak) https://api.testbed.osism.xyz alice password Horizon (via Keystone) https://api.testbed.osism.xyz admin password domain: default Horizon (via Keystone) https://api.testbed.osism.xyz test test domain: test Keycloak https://keycloak.testbed.osism.xyz/auth admin password Netbox https://netbox.testbed.osism.xyz admin password Netdata http://testbed-manager.testbed.osism.xyz:19999 Nexus https://nexus.testbed.osism.xyz admin password OpenSearch Dashboards https://api.testbed.osism.xyz:5601 opensearch password Prometheus https://api-int.testbed.osism.xyz:9091 admin password RabbitMQ https://api-int.testbed.osism.xyz:15672 openstack password phpMyAdmin https://phpmyadmin.testbed.osism.xyz root password","s":"Webinterfaces","u":"/docs/iaas/guides/other-guides/testbed","h":"#webinterfaces","p":1769},{"i":1791,"t":"Authentication with OpenID Connect (OIDC) is possible via Keycloak, which is automatically configured for the OIDC mechanism. OpenStack web dashboard (Horizon) login via OIDC​ For logging in via OIDC, open your browser at OpenStack Dashboard Login Page, select Authenticate via Keycloak, after being redirected to the Keycloak login page, perform the login with the credentials alice and password. After that you will be redirected back to the Horizon dashboard, where you will be logged in with the user alice. OpenStack web dashboard (Horizon) logout​ Keep in mind, that clicking Sign Out on the Horizon dashboard currently doesn't revoke your OIDC token, and any consequent attempt to Authenticate via Keycloak will succeed without providing the credentials. The expiration time of the Single Sign On tokens can be controlled on multiple levels in Keycloak. On realm level under Realm Settings > Tokens. Assuming the keycloak_realm ansible variable is the default osism, and keycloak is listening on keycloak.testbed.osism.xyz, then the configuration form is available here. Detailed information is available in the Keycloak Server Administrator Documentation Session and Token Timeouts section. In a realm down on the client level select the client (keystone), and under Settings > Advanced Settings. It is recommended to keep the Access Token Lifespan on a relatively low value, with the trend of blocking third party cookies. For further information see the Keycloak documentation's Browsers with Blocked Third-Party Cookies section. Usage of the OpenStack CLI​ The environments/openstack folder contains the needed files for the openstack client: cd environments/openstack export OS_CLOUD= # i.e. admin openstack floating ip list OpenStack CLI operations with OpenID Connect password​ Using the OpenStack cli is also possible via OIDC, assuming you provisioned the user alice with password password, then you can perform a simple project list operation like this: See chapter \"Usage the OpenStack CLI\" for basic openstack usage. openstack \\ --os-cacert /etc/ssl/certs/ca-certificates.crt \\ --os-auth-url https://api.testbed.osism.xyz:5000/v3 \\ --os-auth-type v3oidcpassword \\ --os-client-id keystone \\ --os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \\ --os-username alice \\ --os-password password \\ --os-identity-provider keycloak \\ --os-protocol openid \\ --os-identity-api-version 3 \\ --os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \\ project list OpenStack CLI token issue with OpenID Connect​ It is also possible to exchange your username/password to a token, for further use with the cli. The token issue subcommand returns an SQL table, in which the id column's value field contains the token: See chapter \"Usage the OpenStack CLI\" for basic openstack usage. openstack \\ --os-cacert /etc/ssl/certs/ca-certificates.crt \\ --os-auth-url https://api.testbed.osism.xyz:5000/v3 \\ --os-auth-type v3oidcpassword \\ --os-client-id keystone \\ --os-client-secret 0056b89c-030f-486b-a6ad-f0fa398fa4ad \\ --os-username alice \\ --os-password password \\ --os-identity-provider keycloak \\ --os-protocol openid \\ --os-identity-api-version 3 \\ --os-discovery-endpoint https://keycloak.testbed.osism.xyz/auth/realms/osism/.well-known/openid-configuration \\ --os-openid-scope \"openid profile email\" \\ token issue \\ -c id -f value An example token is like: gAAAAABhC98gL8nsQWknro3JWDXWLFCG3CDr3Mi9OIlvVAZMjy2mNgYtlXv_0yAIy- nSlLAaLIGhht17-mwf8uclKgRuNVsYLSmgUpB163l89-ch2w2_OFe9zNSQNWf4qfd8 Cl7E7XvvUoFr1N8Gh09vaYLvRvYgCGV05xBUSs76qCHa0qElPUsk56s5ft4ALrSrzD 4cEQRVb5PXNjywdZk9_gtJziz31A7sD4LPIy82O5N9NryDoDw TODO: OpenStack CLI operations with token TODO: OpenStack CLI token revoke","s":"Authentication with OIDC","u":"/docs/iaas/guides/other-guides/testbed","h":"#authentication-with-oidc","p":1769},{"i":1794,"t":"It is possible to provide the OpenStack APIs and the OpenStack Dashboard via the manager's public IP address. This is not enabled by default, with the exception of the OTC profile. To provide the OpenStack APIs and the OpenStack dashboard via the public IP address of the manager, the following changes are necessary in the terraform/environments/regiocloud.tfvars file. If a cloud other than the REGIO.cloud is used, the profile of the other cloud is changed accordingly. Add the customisation external_api. This customisation makes sure that the required security group rules are created for the various OpenStack APIs and the OpenStack dashboard. # customisation:external_api Set parameter external_api to true. This makes sure that all necessary changes are made in the configuration repository when the Manager service is deployed. It is correct that this is added as a comment. external_api = true After the deployment of the Manager service and the OpenStack services, the OpenStack APIs and the OpenStack dashboard can be reached via a DNS name. The service traefik.me is used for the DNS record. Run the following two commands on the manager node to get the DNS record. $ source /opt/manager-vars.sh $ echo \"api-${MANAGER_PUBLIC_IP_ADDRESS//./-}.traefik.me\" api-80-158-46-219.traefik.me","s":"External API","u":"/docs/iaas/guides/other-guides/testbed","h":"#external-api","p":1769},{"i":1796,"t":"Go to /opt/configuration on testbed-manager Run ./scripts/set-openstack-version.sh 2023.2 to set the OpenStack version to 2023.2 Run ./scripts/set-ceph-version.sh reef to set the Ceph version to reef Run osism update manager to update the Manager service","s":"Change versions","u":"/docs/iaas/guides/other-guides/testbed","h":"#change-versions","p":1769},{"i":1798,"t":"Script Description /opt/configuration/scripts/deploy/000-manager-service.sh /opt/configuration/scripts/deploy/001-helper-services.sh /opt/configuration/scripts/deploy/100-ceph-services-basic.sh /opt/configuration/scripts/deploy/200-infrastructure-services-basic.sh /opt/configuration/scripts/deploy/210-infrastructure-services-extended.sh /opt/configuration/scripts/deploy/300-openstack-services-basic.sh /opt/configuration/scripts/deploy/310-openstack-services-extended.sh /opt/configuration/scripts/deploy/320-openstack-services-baremetal.sh /opt/configuration/scripts/deploy/330-openstack-services-additional.sh /opt/configuration/scripts/deploy/400-monitoring-services.sh","s":"Deploy services","u":"/docs/iaas/guides/other-guides/testbed","h":"#deploy-services","p":1769},{"i":1800,"t":"Script Description /opt/configuration/scripts/upgrade/100-ceph-services.sh /opt/configuration/scripts/upgrade/200-infrastructure-services-basic.sh /opt/configuration/scripts/upgrade/300-openstack-services-basic.sh /opt/configuration/scripts/upgrade/310-openstack-services-extended.sh /opt/configuration/scripts/upgrade/320-openstack-services-baremetal.sh /opt/configuration/scripts/upgrade/330-openstack-services-additional.sh","s":"Upgrade services","u":"/docs/iaas/guides/other-guides/testbed","h":"#upgrade-services","p":1769},{"i":1803,"t":"Ansible errors that have something to do with undefined variables (e.g. AnsibleUndefined) are most likely due to cached facts that are no longer valid. The facts can be updated by running osism apply facts.","s":"Ansible errors","u":"/docs/iaas/guides/other-guides/testbed","h":"#ansible-errors","p":1769},{"i":1805,"t":"$ make prepare ansible-playbook -i localhost, ansible/check-local-versions.yml ERROR: Ansible could not initialize the preferred locale: unsupported locale setting make: *** [prepare] Error 1 To solve the problem you have to modify the Makefile. Change the 1st line as follows. export LC_ALL=en_US.UTF-8 To find out the locale used on the system printenv can be used. $ printenv | grep -i lang|locale LANG=\"en_US.UTF-8\" LC_COLLATE=\"en_US.UTF-8\" LC_CTYPE=\"UTF-8\" LC_MESSAGES=\"en_US.UTF-8\" LC_MONETARY=\"en_US.UTF-8\" LC_NUMERIC=\"en_US.UTF-8\" LC_TIME=\"en_US.UTF-8\" LC_ALL=","s":"Unsupported locale setting","u":"/docs/iaas/guides/other-guides/testbed","h":"#unsupported-locale-setting","p":1769},{"i":1808,"t":"This section describes how to configure and customise the OSISM Testbed. Variables​ The defaults for the OpenTofu variables are intended for REGIO.cloud. Variable Default Note availability_zone nova ceph_version quincy cloud_provider regiocloud configuration_version main deploy_monitoring false dns_nameservers [\"8.8.8.8\", \"9.9.9.9\"] enable_config_drive true external_api false flavor_manager SCS-4V-16-50 flavor_node SCS-8V-32-50 image Ubuntu 22.04 Only Ubuntu 22.04 is currently supported image_node Ubuntu 22.04 Only Ubuntu 22.04 is currently supported keypair testbed manager_version latest network_availability_zone nova number_of_nodes 3 number_of_volumes 3 openstack_version 2023.2 prefix testbed public external refstack false volume_availability_zone nova volume_size_base 30 volume_size_storage 10 volume_type __DEFAULT__ Overrides​ Name Description manager_boot_from_image manager_boot_from_volume neutron_availability_zone_hints_network neutron_availability_zone_hints_router neutron_router_enable_snat nodes_boot_from_image nodes_boot_from_volume nodes_use_ephemeral_storage Customisations​ Name Description access_floatingip access_ipv4 access_ipv6 default external_api neutron_floatingip","s":"Configuration","u":"/docs/iaas/guides/other-guides/testbed","h":"#configuration","p":1769},{"i":1810,"t":"The configuration is intentionally kept quite static. Please create no PRs to make the configuration more flexible/dynamic. The OSISM documentation uses hostnames, examples, addresses etc. from OSISM Testbed. The third volume (/dev/sdd) is not enabled for Ceph by default. This is to test the scaling of Ceph. The manager is used as pull through cache for Docker images and Ubuntu packages. This reduces the amount of traffic consumed.","s":"Notes","u":"/docs/iaas/guides/other-guides/testbed","h":"#notes","p":1769},{"i":1812,"t":"The following stable Ceph and OpenStack releases are supported. The deployment of Ceph is based on ceph-ansible. Ceph Quincy (default) Ceph Reef The deployment of OpenStack is based on kolla-ansible. OpenStack 2023.1 OpenStack 2023.2 (default) OpenStack 2024.1 The deployment of Kubernetes is based on k3s-ansible. Kubernetes v1.29 (default)","s":"Supported releases","u":"/docs/iaas/guides/other-guides/testbed","h":"#supported-releases","p":1769},{"i":1814,"t":"The following services can currently be used with the OSISM Testbed without further adjustments. Infrastructure​ Ceph Cluster API Management Cluster Fluentd Gnocchi Grafana Haproxy Influxdb Keepalived Keycloak Kubernetes Mariadb Memcached Netbox Netdata Opensearch Openvswitch Patchman Prometheus exporters Rabbitmq Redis OpenStack​ Barbican Ceilometer Cinder Designate Glance Heat Horizon Ironic Keystone Magnum Manila Neutron Nova (with Libvirt/KVM) Octavia Senlin Skyline","s":"Included services","u":"/docs/iaas/guides/other-guides/testbed","h":"#included-services","p":1769},{"i":1816,"t":"$ make help Usage: make help Display this help. clean Destroy infrastructure with OpenTofu. wipe-local-install Wipe the software dependencies in `venv`. create Create required infrastructure with OpenTofu. login Log in on the manager. vpn-wireguard Establish a wireguard vpn tunnel. vpn-sshuttle Establish a sshuttle vpn tunnel. bootstrap Bootstrap everything. manager Deploy only the manager service. identity Deploy only identity services. ceph Deploy only ceph services. deploy Deploy everything and then check it. prepare Run local preperations. deps Install software preconditions to `venv`. $ make ","s":"Makefile reference","u":"/docs/iaas/guides/other-guides/testbed","h":"#makefile-reference","p":1769},{"i":1818,"t":"You can inspect the results of the daily zuul jobs. Name Description testbed-deploy testbed-deploy-ceph testbed-deploy-stable testbed-update-stable testbed-upgrade testbed-upgrade-ceph testbed-upgrade-stable","s":"CI jobs","u":"/docs/iaas/guides/other-guides/testbed","h":"#ci-jobs","p":1769},{"i":1820,"t":"Open vSwitch (OVS) osism apply -a pull openvswitch osism apply -a upgrade openvswitch Open Virtual Network (OVN) In environments/kolla/configuration.yml the parameter neutron_plugin_agent is set to ovn if OVN is used as a network plugin. The parameter is set to ovn by default in the Cookiecutter. environments/kolla/configuration.yml # neutron neutron_plugin_agent: \"ovn\" Otherwise the network plugin is set to openvswitch. If the neutron_plugin_agent is set to openvswitch, this step does not need to be done. Before the upgrade of OVN, the upgrade of Open vSwitch must already have been done. osism apply -a pull ovn osism apply -a upgrade ovn","s":"Network","u":"/docs/iaas/guides/upgrade-guide/network","h":"","p":1819},{"i":1822,"t":"info When upgrade the different OpenStack services, all containers must be restarted. When restarting the API services, there is a short downtime of the APIs. This downtime is usually less than 1 minute. OpenStack client osism apply openstackclient Keystone osism apply -a pull keystone osism apply -a upgrade keystone Glance osism apply -a pull glance osism apply -a upgrade glance Designate osism apply -a pull designate osism apply -a upgrade designate Placement osism apply -a pull placement osism apply -a upgrade placement Cinder osism apply -a pull cinder osism apply -a upgrade cinder Neutron osism apply -a pull neutron osism apply -a upgrade neutron Nova osism apply -a pull nova osism apply -a upgrade nova Octavia osism apply -a pull octavia osism apply -a upgrade octavia 9.1. Update amphora image This step is only necessary if the Amphora Driver is used. If OVN is used as the driver, this step is not necessary. We provide regularly updated images for Octavia in osism/openstack-octavia/amphora-image. The OSISM CLI can be used to upload the correct image depending on the OpenStack release used. osism manage image octavia 9.2. Amphora rotation This step is only necessary if the Amphora driver is used. If OVN is used as the driver, this step is not necessary. Horizon osism apply -a pull horizon osism apply -a upgrade horizon","s":"OpenStack","u":"/docs/iaas/guides/upgrade-guide/openstack","h":"","p":1821},{"i":1825,"t":"warning Always read the release notes first to learn what has changed and what adjustments are necessary. Read the release notes even if you are only updating from e.g. 7.0.2 to 7.0.5. The update of a manager service with a stable release of OSISM is described here. In the example, OSISM release 7.0.5 is used. Change the OSISM release in the configuration repository. 1.1. Set the new OSISM version in the configuration repository. MANAGER_VERSION=7.0.5 sed -i -e \"s/manager_version: .*/manager_version: ${MANAGER_VERSION}/g\" environments/manager/configuration.yml 1.2. If openstack_version or ceph_version are set in environments/manager/configuration.yml (or anywhere else), they must be removed. If these are set, the stable release is not used for these components. 1.3. Sync the image versions and files in the configuration repository. OSISM >= 7.0.0 OSISM < 7.0.0 make sync If Gilt is not installed via the requirements.txt of the manager environment it is important to use a version smaller v2. The v2 of Gilt is not yet usable. gilt overlay # you have to do this 2x, this is not a copy & paste error gilt overlay Optionally, this is normally not necessary, it is possible to reference a specific tag of the osism/cfg-generics repository. To do this, first check which version of osism/cfg-generics is used in a particular release. The version is defined in generics_version in the base.yml file in the osism/release repository. For OSISM 6.0.0, for example, this is version v0.20230919.0. This version is then added to the file gilt.yml in the configuration repository instead of main at version. This change must be made again after each execution of gilt overlay as it is overwritten by the call of gilt overlay. This cannot be realized differently in the current implementation of Gilt. 1.4. Commit and push all changes in the configuration repository. Since everyone here has their own workflows for changes to the configuration repository, only a generic example for Git. git commit -a -s -m \"manager: use OSISM version 7.0.5\" git push Update the configuration repository on the manager node. osism apply configuration Update the manager service on the manager node. osism update manager If Ansible Vault was used to encrypt environments/manager/secrets.yml, the parameter --ask-vault-pass is also appended. From OSISM >= 7.0.5 this is no longer necessary. If osism update manager does not work yet, use osism-update-manager instead. Refresh the facts cache. osism apply facts If Traefik is used on the manager node (traefik_enable: true in environments/infrastructure/configuration.yml) then Traefik should also be upgraded. osism apply traefik Finally, the Ansible vault password must be made known again. osism set vault password","s":"Manager","u":"/docs/iaas/guides/upgrade-guide/manager","h":"","p":1824},{"i":1827,"t":"This guide is an example of how to perform a manual migration from a VMware ESXi host to OpenStack. Migration to OpenStack always depends very much on the use case. It is not possible to document an approach or to write a tool that works for all use cases. This guide shows one possible way. There are many ways to perform a migration. A migration must always be carefully prepared and tested in advance. At this point, we would also like to point out the open source project cloudbase/coriolis from Cloudbase. There are also commercial providers that perform migration from VMware ESXi to OpenStack. One of the offerings is Hystax Acura Live Cloud Migration.","s":"Migrate from VMware ESXi to OpenStack","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"","p":1826},{"i":1829,"t":"Source: ESXi 7.0 host Destination: OpenStack a security group (web_ssh) is already available at the destination a Linux converter host is installed and ready, we also have root access to it an IPv4 address (10.50.40.230) will be given manually out of a preconfigured network we migrate one host with a kernel newer then 2.6.25 with two scsi harddrives attached and one networkcard destination openstack using Libvirt/KVM as virtualisation the converter host has access to ESXi and the OpenStack environment over IP network","s":"Scenario","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#scenario","p":1826},{"i":1831,"t":"VMware credentials SSH enabled on ESXi host access to the webinterface of the ESXi host OpenStack credentials Linux packages installed on the coverter, in this case it is an Ubuntu 22.04 apt-get install qemu-utils python3-openstackclient twice the space of the largest vmdk disc image on the converter or nfs access to the image files with enough storage","s":"Requirements","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#requirements","p":1826},{"i":1833,"t":"Check the /etc/fstab file of your VMware ESXi host you want to move. See how all the discs or paritions are mounted. If they are all mounted by LVM or UUID you do not need to change anything. cat /etc/fstab /dev/mapper/vg00-lvroot / ext4 errors=remount-ro 0 1 /dev/mapper/vg00-lvboot /boot ext2 defaults 0 2 /dev/mapper/vg00-lvhome /home ext4 defaults 0 2 /dev/mapper/vg00-lvvar /var ext4 defaults 0 2 /dev/mapper/vg00-lvswap none swap sw 0 0 /dev/mapper/vgdata-lvsrv /srv ext4 defaults 0 2 If they are mounted like /dev/sda it is better to change the /etc/fstab to UUID mounting using blkid. Replace these entries with UUID=filesystems_uuid and add the rest of the line same as with the devicenames. Example: example devicename fstab /dev/sda1 /boot ext2 defaults 0 2 /dev/sda2 / ext4 errors=remount-ro 0 1 Change it to something like this: example uuid fstab UUID=574c96bf-f2cb-49b8-9196-232a24047f94 /boot ext2 defaults 0 2 UUID=93cc3b34-36c3-422e-b7a6-c80439e8f431 / ext4 errors=remount-ro 0 1 caution When creating a new server, OpenStack uses /dev/vd* or /dev/sd* as devices for volumes. Using UUID/LVM mounts will ensure that the kernel will find your devices while booting. Using old device names may lead to the boot sequence to get stuck, due to missing devices. Also check your NIC interface configuration as the devicenames can change to a new devicename. This depends on the udev or systemd setup of your specific system. It needs to be changed to either DCHP if you want to use floating IPs or static IP of the new network.","s":"Prechecks","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#prechecks","p":1826},{"i":1835,"t":"note Shutdown the host in VMware as the movement is only possible while the host is offline. Otherwise you will get corrupted disc files. You can use either the webinterface or SSH to identify and copy the *.vmdk files of your VMware ESXi host. While using the web interface you need to locate the datastore and the directoy where the disc files are located and start downloading all vmdk files. You will always get files files for a disc, a smaller and a larger one, both are required. When using SSh, please also copy both vmdk files for the disc to the converter host. Start looking up your files under /vmfs/volumes/.","s":"Migration","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#migration","p":1826},{"i":1837,"t":"Example SSH copy and path of all vmdk files to the converter host using the scp command for our testing-host: scp user@vmhost:/vmfs/volumes/datastore1/testing-host/*.vmdk . After copying is finished, we find several vmdk files in our directory. We copied two disc images: testing-host-disc0-flat.vmdk testing-host-disc1.vmdk testing-host-disc0.vmdk testing-host-disc1-flat.vmdk","s":"How to copy vmdk images","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#how-to-copy-vmdk-images","p":1826},{"i":1839,"t":"note Now convert those vmdk files into raw images with the following flags: -p show progress (optional) -f Input Format -O Output Format Raw files are required to import images into OpenStack. qemu-img convert -p -f vmdk -O raw testing-host-disc0.vmdk testing-host-disc0.raw Repeat this step for each disc image you need to convert.","s":"How to convert vmdk to raw","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#how-to-convert-vmdk-to-raw","p":1826},{"i":1841,"t":"note This step is completely optional and you should have some Linux knowledge to do this. After converting the images of a Linux host, you now have the possibilty to edit some settings offline before importing the images into OpenStack. By mounting the raw image files you can edit the configuration files to, e.g.: disable mountpoints at the fstab, like nfs server change the ip config of the networkcard to dhcp or fixed ip adjust resolv.conf adjust routing On Ubuntu you can use losetup to mount the raw image as a loopdevice to mount it somewhere you have access to. losetup -f -P testing-host-disc0.raw losetup -l mount /dev/loop0p1 /mnt/test/ or lvscan and mount the lvm volume","s":"Edit the raw Images (optional)","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#edit-the-raw-images-optional","p":1826},{"i":1843,"t":"First of all you need your OpenStack credentials, having them in an my-project-openrc.sh file and source them to your shell. The openstack cli client is now able to connect to the cloud environment and do all the following steps. To get your credentials please check with your OpenStack provider. If you want to preserve the /dev/sd* device names of the mountpoints, you must inject the new image and add some properties while uploading it into the OpenStack environment or add them later on to the images with Horzion web interface or openstack cli client. openstack image create --progress --property hw_disk_bus=scsi --property hw_scsi_model=virtio-scsi --property hw_watchdog_action=reset --disk-format raw --private --file testing-host-disc0.raw testing-host-image-disc0 openstack image list +--------------------------------------+------------------------------+--------+ | ID | Name | Status | +--------------------------------------+------------------------------+--------+ | 2a12b545-5d09-4ca1-9a76-b57f8d2489be | testing-host-disc0 | active | | b34744f7-6ef6-4282-a001-08a06812e381 | testing-host-disc1 | active | +--------------------------------------+------------------------------+--------+","s":"How to import Images","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#how-to-import-images","p":1826},{"i":1845,"t":"The previously imported images need to be copied to a volume so the server is also able to evict to other hosts in the cluster, so lets create and start our server in OpenStack. Select one flavor for the host, in this case SCS-8V-16, which means 8 Virtual CPUs and 16GB of RAM, get a list of all your available flavors by executing openstack flavor list and select the best matching one. As the images are 20GB, you tell openstack that you need a boot volume with a size of 20 and a block-device for the additional device also with a size of 20GB. In this guide there is already a security group which fits our needs, if not, create one or you will not be able to communicate with your new host. openstack security group list +--------------------------------------+-----------------+------------------------------+----------------------------------+------+ | ID | Name | Description | Project | Tags | +--------------------------------------+-----------------+------------------------------+----------------------------------+------+ | 4fd1d060-bf1d-4f5a-8e80-fde975d41f5f | default | Default security group | c9aa53cc3c654692b14a8f81a88cfa2f | [] | | 73967e73-e8d5-4318-b621-a06e7496fec3 | web_ssh | Webserver security group | c9aa53cc3c654692b14a8f81a88cfa2f | [] | +--------------------------------------+-----------------+------------------------------+----------------------------------+------+ The web_ssh group will be attached to the server. Now you need to tell which network you want to deploy your host on, optionally including a fixed IPv4 address. You can repeat the --nic for additional nics in your server, in this guide it's the my_corp_net. openstack network list +--------------------------------------+-------------------+--------------------------------------+ | ID | Name | Subnets | +--------------------------------------+-------------------+--------------------------------------+ | 9688192e-11dd-4618-a18c-99d3267f630a | my_corp_net | 0d502fdb-be73-457a-8678-79eb6088a9a1 | | 98842b77-c070-4532-a2a9-99d588c4e947 | internet | 2dfc3916-972f-44d1-afdb-6f89488ef3a4 | | c846238a-b00a-4c73-87e3-3614d94f46fd | my_other_corp_net | b8210b4e-5d91-425a-b05c-ca5d4bf8329a | +--------------------------------------+-------------------+--------------------------------------+ As last parameter, you give the server name of your migrated system. As we are starting an already configured system we do not need to inject SSH keys or passwords as they should already be present on the host. openstack server create --flavor SCS-8V-16 \\ --image 2a12b545-5d09-4ca1-9a76-b57f8d2489be --boot-from-volume 20 \\ --security-group 73967e73-e8d5-4318-b621-a06e7496fec3 \\ --nic net-id=9688192e-11dd-4618-a18c-99d3267f630a,v4-fixed-ip=10.50.40.230 \\ --block-device uuid=b34744f7-6ef6-4282-a001-08a06812e381,source_type=image,destination_type=volume,volume_size=20 \\ --os-compute-api-version 2.90 testing-host","s":"How to create your server","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#how-to-create-your-server","p":1826},{"i":1847,"t":"openstack server list +--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+ | ID | Name | Status | Networks | Image | Flavor | +--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+ | 71a8b930-4212-434a-8891-afdeeb1802dc | testing-host | ACTIVE | my_network=10.50.40.230 | N/A (booted from volume) | SCS-8V-16 | +--------------------------------------+------------------+---------+----------------------------------+--------------------------+-----------+ To see the attached volumes and their mountpoints: openstack server volume list 71a8b930-4212-434a-8891-afdeeb1802dc +----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+ | Device | Server ID | Volume ID | Tag | Delete On Termination? | Attachment ID | BlockDeviceMapping UUID | +----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+ | /dev/sda | 71a8b930-4212-434a-8891-afdeeb1802dc | 71902b03-48ea-483c-a6a3-6c47b9d8537b | None | False | 3cd241ff-5296-4bb1-9ba0-d743cb8c8f31 | 2d08e835-156f-4f71-8c95-7ff828230b8e | | /dev/sdb | 71a8b930-4212-434a-8891-afdeeb1802dc | 15a835a3-5149-49a8-8e2b-a81ef8097c35 | None | False | 9deeb06b-718b-49d4-84a4-87dabc34ba56 | 04483f95-0333-4b37-92e6-db604e4ddc7c | +----------+--------------------------------------+--------------------------------------+------+------------------------+--------------------------------------+--------------------------------------+","s":"Show your new server","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#show-your-new-server","p":1826},{"i":1849,"t":"To get the VNC URL for console login use: openstack console url show 71a8b930-4212-434a-8891-afdeeb1802dc +----------+-------------------------------------------------------------------------------------------+ | Field | Value | +----------+-------------------------------------------------------------------------------------------+ | protocol | vnc | | type | novnc | | url | https://vnc.your.cloud/vnc_lite.html?path=%3Ftoken%3Db9b6920d-e533-4728-8132-a5a0adfc24e5 | +----------+-------------------------------------------------------------------------------------------+ This will print out the VNC URL for the videoconsole connection to your host. Now the server will boot and be available. Maybe you need to tweak the network setup if it is still not accessible. To do this, you could use the VNC console of the OpenStack host: Login and then setup the network card if you have not already done that before host had been shutdown. You now can remove the imported images, as they are no longer required - except you want to generate another host with the same images.","s":"How to access the VNC console","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#how-to-access-the-vnc-console","p":1826},{"i":1851,"t":"In this little guide, we only can give a sneak peak of what you need to do with a simple VMware ESXi host. More complex setups needs consulting, planning and testing as there a several scenarios out there which cannot be handled like this. Especially if you have terrabytes of data to move or graphics- or AIcards in you VMware ESXi hosts.","s":"Last words","u":"/docs/iaas/guides/user-guide/migration-vmware-esix","h":"#last-words","p":1826},{"i":1853,"t":"Security groups in OpenStack are part of the network security mechanisms provided for the users. They resemble sets of simple firewall rules allowing specific network traffic at a Port of a VM that connects it to a network. The rules allow specific network port numbers and protocols while also differentiating between ingress and egress directions. Usually security groups are assigned to the Port(s) when a virtual machine is created, but assignments can also be changed at runtime later on. Multiple security groups can be assigned to a VM or Port simultaneously and in such case they will be combined as the union of all their rules. caution Security groups are mutable resources. Their rules can be adjusted at any time after creation. Changing the rules of a security group will immediately apply the changes to all Ports or VMs it is assigned to. It is advisable to always review resources which use a security group before making changes to it.","s":"How to configure and use security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"","p":1852},{"i":1855,"t":"Every virtual machine that is created may need different firewall rules. These requirements can also change over time. Adding or removing security groups will allow users to adapt the firewall rules specifically to their virtual machines. To harden the firewall settings for your virtual machine you may follow these steps: Before creating a virtual machine its purpose is usually already known. Use this information to identify all incoming and outgoing traffic rules that will be needed based on the communication patterns of the services it is meant to deploy. This includes communication protocols, port numbers, communication directions and optionally target/source address ranges. Look through already existing security groups and their rules. If a security group allows more traffic than needed it SHOULD NOT be used. If a security group contains only a subset of the required rules it MAY be used in combination with other security groups that contain rules which fulfill the remaining required traffic rules from point 1. If you were not successful in finding an appropriate combination of existing security groups or you need additional specific rules to cover all requirements, you MAY create one or more new Security Groups in which you can add the required rules. After ensuring the existence of one or more security groups that fulfill your requirements, you can create the VM with those security groups already specified in the creation command.","s":"Identify the requirements of your setup","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#identify-the-requirements-of-your-setup","p":1852},{"i":1857,"t":"When implementing network security requirements, firewall rules alone are not always sufficient and might need to be augmented with additional configuration or time-based constraints. Notable examples are: SSH SSH is needed on many virtual machines to operate their guest operating system. In a security group the port 22 can be opened for the TCP protocol to allow incoming SSH connections. But that only should be done while also restricting the SSH configuration to public key authentication only (the recommended way) or having a strong username and password policy already applied to the operating system of the virtual machine. Otherwise default usernames and passwords which are often preconfigured in system images may be exploited through the exposed SSH port which enables attackers to compromise the virtual machine. ICMP It might be useful to be able to ping a virtual machine or use other ICMP requests. But for some virtual machine configurations this is either not necessary at all or only temporarily needed. One benefit of security groups among other things is the ability to be easily added to and removed from existing virtual machines. So a dedicated security group allowing ICMP could be added temporarily to a virtual machine for debugging purposes and removed from it afterwards.","s":"Further security considerations","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#further-security-considerations","p":1852},{"i":1859,"t":"Security groups are managed within a project. So every project will have a different set of security groups. They can be added dynamically to each virtual machine, during their creation or afterwards. Additionally, they may also be removed from VMs at any point. Every project has its own default security group, which rules can be edited. Additionally other security groups can be added until the project's quota is exhausted. To add a security group, use the following command: openstack security group create $SECURITY_GROUP Within every security group rules can be added up unto a defined maximum of rules, that usually is about 100. Rules can be added to security groups with the following command: openstack security group rule create [...] $SECURITY_GROUP To delete rules from a security group, the rule id has to be used. It is listed in the details of the rules section of the security group. openstack security group rule delete $RULE_ID","s":"How to create security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#how-to-create-security-groups","p":1852},{"i":1861,"t":"Unless specified otherwise, the default security group is assigned to all VMs or Ports at creation. To use any other than the default security group at creation it is necessary to specify the desired security group(s) during the creation process. To review which rules are defined in a security group, the following command can be used: openstack security group show default","s":"Default security group","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#default-security-group","p":1852},{"i":1863,"t":"While projects can use very different aspects in security group rules and thus the security groups will always differ between projects, there are some security groups that are widely used. Through the nature of security groups being seen as a set of rules that can be combined, having some basic security groups that allow basic protocols is a commonly used setup. This section will demonstrate how to create some security groups for commonly used protocols and ports. A security groups, that allows incoming SSH traffic: openstack security group create ssh openstack security group rule create --ingress --protocol tcp --dst-port 22 ssh A security group, that allows incoming HTTP requests: openstack security group create http openstack security group rule create --ingress --protocol tcp --dst-port 80 http A security group, that allows incoming HTTPS requests: openstack security group create https openstack security group rule create --ingress --protocol tcp --dst-port 443 https A security group, that allows incoming ICMP requests: openstack security group create icmp openstack security group rule create --protocol icmp icmp","s":"Recommended security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#recommended-security-groups","p":1852},{"i":1865,"t":"info Security groups can be assigned to multiple resources simultaneously (such as VMs or Ports). This means that security groups are reusable and don't need to be recreated for each applicable resource individually. Usually, initial security groups are added at the time of the creation of a VM. During creation, multiple security groups can also be added at the same time by repeating the --security-group argument: openstack server create [...] --security-group $SECURITY_GROUP_1 --security-group $SECURITY_GROUP_2 $SERVER_NAME To add a security group to an existing VM, the following command can be used: openstack server add security group $SERVER_NAME $SECURITY_GROUP To remove a security group from a VM, the following command can be used: openstack server remove security group $SERVER_NAME $SECURITY_GROUP The source of this document can be found in the SovereignCloudStack/docs repository. Author: SCS Community, License: CC by Attribution 4.0 International","s":"How to use security groups","u":"/docs/iaas/guides/user-guide/openstack/security-groups","h":"#how-to-use-security-groups","p":1852},{"i":1868,"t":"TODO","s":"Architecture","u":"/docs/iaas/overview/architecture","h":"","p":1867},{"i":1870,"t":"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.","s":"User Data Backups","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"","p":1869},{"i":1872,"t":"Term Explanation Virtual Machine Equals the server resource in Nova. Ephemeral Storage Disk storage directly supplied to a virtual machine by Nova. Different from volumes. (Glance) Image IaaS resource usually storing raw disk data. Managed by the Glance service. (Cinder) Volume IaaS resource representing block storage disk that can be attached as a virtual disk to virtual machines. Managed by the Cinder service. (Volume) Snapshot Thinly-provisioned copy-on-write snapshots of volumes. Stored in the same Cinder storage backend as volumes. Volume Type Attribute of volumes determining storage details of a volume such as backend location or whether the volume will be encrypted. (Barbican) Secret IaaS resource storing cryptographic assets such as encryption keys. Managed by the Barbican service.","s":"Glossary","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#glossary","p":1869},{"i":1874,"t":"User data in the context of this guide describes data accumulated in cloud resources of a user at runtime. This concerns primarily storage data of virtual machines stored at at-rest. This does not cover in-transit or in-use data such as network traffic, virtual machines' RAM contents or IaaS configuration and metadata of cloud resources.","s":"Scope","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#scope","p":1869},{"i":1876,"t":"Given the mentioned scope, the following can be classified as user data: images stored in Glance virtual machine disks, either: Ephemeral Storage stored in Nova volumes stored in Cinder encryption keys stored as secrets in Barbican The following sections will describe backup procedures for each of those resources individually.","s":"Overview of applicable User Data","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#overview-of-applicable-user-data","p":1869},{"i":1878,"t":"Glance images may act as backup targets for other resources (such as volumes) but don't have a dedicated backup service for themselves. When an image is to be backed up, it can be downloaded from the Glance image service and stored outside of the IaaS infrastructure for backup purposes. In this case it is the user's responsibility to establish the backup procedure and appropriate target storage. caution When creating images from volumes with a volume type that uses encryption, the resulting image will contain the raw LUKS-encrypted blocks of the volume. When transferred outside of the IaaS infrastructure, this data is only useful as a backup together with the corresponding encryption key. Such images can be identified by an attribute called cinder_encryption_key_id in the properties metadata field of the image. It only exists for encrypted images and references the encryption key in Barbican. Refer to the Barbican secrets section for instructions on how to backup the key. The API or the OpenStack client may be used to initiate the download, for example: openstack image save --file $TARGET_FILE_PATH $IMAGE_NAME_OR_ID This or the underlying API request may be automated as part of a regular backup schedule involving the backup storage target on the user side.","s":"Image backup using download","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#image-backup-using-download","p":1869},{"i":1880,"t":"caution When using the createImage Compute API action (e.g. via the openstack server image create command) on a virtual machine that has volumes attached to it in addition to its Ephemeral Storage disk, the volumes will not be backed up into the image. Instead, a snapshot will be created for each attached volume and referenced in the image metadata. This does not replace genuine volume backups. See the corresponding appendix section for further details. Ephemeral Storage disks of virtual machines can be backed up to Glance images easily by using the createImage Compute API action or the corresponding OpenStack client command: openstack server image create --name $IMAGE_NAME $SERVER_NAME_OR_ID This will create a Glance image containing a one-to-one copy of the data on the Ephemeral Storage disk at the time of execution. If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.","s":"Ephemeral Storage backup using Glance images","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#ephemeral-storage-backup-using-glance-images","p":1869},{"i":1882,"t":"The following instructions only apply if the infrastructure offers the Cinder Backup API. note Backups of volumes using a volume type that uses encryption will retain their encryption and a clone of the original encryption key is created in Barbican linked to the backup. These backups can only be restored when the Barbican service is available and still has the corresponding copy of the encryption key. Also, it is advised to take note of the exact volume type when creating a backup of an encrypted volume, because this information will be needed to restore the backup. See restoring an encrypted volume backup. info It might be difficult or even impossible for a user to transfer backups created by the Cinder Backup API outside of the IaaS infrastructure, depending on the backup backend. A more easily accessible backup of volumes can be created by using Glance images. See the section about volume data backup using Glance images for details.","s":"Volume data backup using Cinder Backup API","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#volume-data-backup-using-cinder-backup-api","p":1869},{"i":1884,"t":"Backups can be created using the Cinder Backup API or the corresponding OpenStack client commands: openstack volume backup create $VOLUME_NAME_OR_ID Further backups of the same volume can subsequently be created as incremental backups using the following command: openstack volume backup create --incremental $VOLUME_NAME_OR_ID","s":"Backup of detached volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#backup-of-detached-volumes","p":1869},{"i":1886,"t":"note When creating backups of attached (in-use) volumes, the state of the full volume is captured at runtime. Backups created this way will be crash-consistent but not app-consistent. In case of attached (in-use) volumes, backups can only be created while also specfiying the force parameter: openstack volume backup create --force $VOLUME_NAME_OR_ID Further backups of the same volume can subsequently be created as incremental backups using the following command: openstack volume backup create --force --incremental $VOLUME_NAME_OR_ID","s":"Backup of attached volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#backup-of-attached-volumes","p":1869},{"i":1888,"t":"In case the Cinder Backup storage is not available in the IaaS infrastructure, Glance images can be used as a backup target instead. Such images may also subsequently be downloaded to transfer the backup outside of the IaaS infrastructure. note Glance image backups of Cinder volumes only allow full backup copies and do not offer incremental or differential backup mechanisms.","s":"Volume data backup using Glance images","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#volume-data-backup-using-glance-images","p":1869},{"i":1890,"t":"Volumes not attached to virtual machines can be directly copied into an image. Such volumes can be identified by their status being available. To backup a detached volume to a Glance image, directly use the corresponding image creation action: openstack image create --volume $VOLUME_NAME_OR_ID $IMAGE_NAME After the image creation has finished, a full backup copy of the volume will reside in the Glance storage backend. If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.","s":"Glance image backups of detached volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#glance-image-backups-of-detached-volumes","p":1869},{"i":1892,"t":"Cinder is unable to directly create Glance images from volumes which are attached to virtual machines. To create backups of such volumes regardless, a detour using volume snapshots can be used which will be described below. note When creating snapshots of attached (in-use) volumes, the force parameter has to be used. These snapshots capture a state of the full volume at runtime. They will be crash-consistent but not app-consistent. Create a snapshot of the target volume while including the force parameter in the request: openstack volume snapshot create --volume $VOLUME_NAME_OR_ID $SNAPSHOT_NAME Create a new temporary volume based on the snapshot to act as backup source: openstack volume create --snapshot $SNAPSHOT_NAME $TEMP_VOLUME_NAME Wait until the volume creation is finished and the temporary volume reaches the available status. Create a backup image of the temporary volume: openstack image create --volume $TEMP_VOLUME_NAME $IMAGE_NAME Wait until the image creation finishes and the target image reaches the active status. Delete the temporary volume and snapshot: openstack volume delete $TEMP_VOLUME_NAME openstack volume snapshot delete $SNAPSHOT_NAME A full backup copy of the volume now resides in the Glance storage backend. If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.","s":"Glance image backups of attached (in-use) volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#glance-image-backups-of-attached-in-use-volumes","p":1869},{"i":1894,"t":"danger Secrets downloaded from Barbican will be in plaintext, which means that the secret is unprotected once received from the API. Before downloading secrets from Barbican make sure that a secure target environment is established for receiving and securely storing the secret's contents. Barbican secrets can be downloaded in plaintext using the corresponding API or client command: openstack secret get --file $TARGET_FILE_PATH --payload_content_type \"application/octet-stream\" $SECRET_ID tip In case the secret needs to be restored into an OpenStack Barbican later on, it is recommended to also note down the following attributes shown by openstack secret get $SECRET_ID: Algorithm Bit length Secret type Mode","s":"Barbican secrets backup using download","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#barbican-secrets-backup-using-download","p":1869},{"i":1896,"t":"In case of encrypted volumes (i.e. using a volume type with encryption), a corresponding encryption key is stored in Barbican. When an image is created from such a volume, the encryption key is duplicated in Barbican for the image. In order to backup those keys, the corresponding secret must first be identified. For volumes, this is possible starting with the Volume API microversion 3.64: openstack volume show --os-volume-api-version 3.64 $VOLUME_NAME_OR_ID The response will contain an encryption_key_id field with the ID of the Barbican secret. For images, the secret reference is stored in the properties field instead: openstack image show -f value -c properties $IMAGE_NAME_OR_ID In case of images created from encrypted volumes, the resulting output will have a nested cinder_encryption_key_id field that contains the ID of the Barbican secret. The resulting IDs can be used to retrieve the corresponding key using the Barbican instructions above. caution Note that the key retrieved from the secret is not immediately usable as LUKS passphrase to the image data of the volume. OpenStack does some processing to the key before it is passed to the LUKS encryption, which must be mimicked accordingly in order to unlock the encryption outside of OpenStack! See the example procedure for converting the LUKS key in the appendix section.","s":"Retrieving encryption keys from Barbican","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#retrieving-encryption-keys-from-barbican","p":1869},{"i":1898,"t":"The following sections will illustrate how to restore the individual resource backups that have been documented above.","s":"Restore","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restore","p":1869},{"i":1900,"t":"note Note that restoring a Barbican secret by re-uploading it via the Barbican API will lead to the secret receiving a new ID. Existing resources referencing an old secret ID cannot make use of the restored copy. openstack secret store --algorithm aes --bit-length 256 --mode cbc \\ --secret-type symmetric --file $KEY_FILE_PATH --name $SECRET_NAME Notes: Attributes like algorithm, bit length, mode and secret type are not verified by Barbican. Their main purpose is to classify the secret on a metadata level. Make sure to align the attributes with the original secret. $KEY_FILE_PATH is the local file path of the secret backup as created originally using the instructions above. $SECRET_NAME is entirely optional but helps identifying the restored secret later on and to distinguish it from secrets created by OpenStack itself. It is best to not put whitespace characters in the name, otherwise it has to be surrounded by quotes. The successful registration of the restored secret can subsequently be verified using: openstack secret list --name $SECRET_NAME","s":"Restoring a backup of a Barbican secret","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-backup-of-a-barbican-secret","p":1869},{"i":1902,"t":"Unencrypted image backups can simply be restored using the regular image upload functionality and specifying the backup file: openstack image create --file $IMAGE_FILE_PATH $IMAGE_NAME note In case the original image backup was not based on a volume originally, the image may have had a non-default disk or container format. In this case, add the command parameters --container-format and --disk-format to the command accordingly.","s":"Restoring a backup of an unencrypted image","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-backup-of-an-unencrypted-image","p":1869},{"i":1904,"t":"The following section only applies to image backups that were originally created from images of encrypted volumes. First, restore the corresponding secret of the image using the instructions above. The restored secret will receive a new ID in the form of a UUID. Note down the ID of the restored secret and insert it in place of $SECRET_ID in the command below. openstack image create --file $IMAGE_FILE_PATH \\ --property cinder_encryption_key_id=$SECRET_ID \\ --property cinder_encryption_key_deletion_policy=on_image_deletion \\ $IMAGE_NAME The cinder_encryption_key_deletion_policy attribute is optional. If not specified, the referenced secret will not be deleted on image deletion automatically. In contrast, if set to on_image_deletion, the referenced secret will be deleted as soon as the image referencing it is deleted.","s":"Restoring a backup of an encrypted image","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-backup-of-an-encrypted-image","p":1869},{"i":1906,"t":"To restore a volume from an image backup, simply use the volume creation action and specify the image as source. Depending on whether the original volume the image was created from was encrypted or not, the target volume type might need to be specified accordingly. Whether this is the case can be identified by inspecting the image's metadata using openstack image show $IMAGE_NAME_OR_ID and looking for a \"cinder_encryption_key_id\" field within \"properties\". If it exists, the source volume of the image was encrypted. To restore the image of an unencrypted volume: openstack volume create --image $IMAGE_NAME_OR_ID \\ --size $VOLUME_SIZE_IN_GB $VOLUME_NAME To restore the image of an encrypted volume: openstack volume create --image $IMAGE_NAME_OR_ID \\ --type $ENCRYPTED_VOLUME_TYPE \\ --size $VOLUME_SIZE_IN_GB $VOLUME_NAME If restoring an encrypted image, make sure to specify $ENCRYPTED_VOLUME_TYPE correctly and have it reference a volume type which also supports the encryption. Otherwise the volume will be unbootable or unusable by Nova instances.","s":"Restoring a volume backup from an image","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-volume-backup-from-an-image","p":1869},{"i":1908,"t":"The Cinder Backup service offers dedicated API actions and commands for restoring volume backups created using the service. These backups can be restored in one of two ways: Letting the Cinder Backup service create a new volume based on the backup. Overwriting an existing volume with the backup data. note If the volume backup was originally created from a volume that used a non-default encrypted volume type, letting Cinder Backup create a new volume for backup restoration does not work and the volume type must match exactly. In such case provision an empty volume with the correct type first and then restore the backup onto it as explained further down. Restoring to a new volume (Cinder Backup)​ openstack volume backup restore $BACKUP_NAME_OR_ID $TARGET_NAME ... where $TARGET_NAME is the desired name of the new volume to be created. Make sure that no volume with this name already exists. The Cinder Backup service will create the volume with the same size as the backup indicates. Restoring on an existing volume (Cinder Backup)​ As an alternative to creating a new volume as the restore target, the backup can also be restored on an existing volume: openstack volume backup restore --force $BACKUP_NAME_OR_ID $VOLUME_NAME_OR_ID ... which will overwrite the data on the existing volume, regardless of whether it is empty or not! The volume will enter the \"restoring-backup\" state temporarily and will return to the \"available\" state again once the restore process has finished. Restoring an encrypted volume backup (Cinder Backup)​ When restoring a volume backup of a volume that was using a non-default encrypted volume type, a new volume of that type needs to be created first and then the backup restored onto it. Otherwise, the restoration will fail with the target volume ending up in the \"error_restoring\" state. For this procedure to succeed it is necessary to know the exact volume type of the volume the backup was created from. If the source volume of the backup still exists, the original volume type can be determined by inspecting the backup's volume_id attribute and then using it to look up the corresponding volume and its type attribute. The following client command can be used for this (fill in the value for BACKUP_ID): export BACKUP_ID=... SOURCE_VOLUME_ID=\"$(openstack volume backup show $BACKUP_ID -f value -c volume_id)\" openstack volume show -f value -c type \"$SOURCE_VOLUME_ID\" This returns the name of the original volume type. If the source volume does not exist anymore, rely on documentation about the backup to determine the type, if available. First, create a new empty volume as the restore target and use the backup's size metadata attribute to match the size of the volume to the backup: openstack volume create --size $BACKUP_SIZE --type $VOLUME_TYPE $TARGET_NAME ... where $TARGET_NAME is the desired name of the new volume. Once the volume reaches \"available\" state, restore the backup onto it: openstack volume backup restore --force $BACKUP_NAME_OR_ID $TARGET_NAME The volume will enter the \"restoring-backup\" state temporarily and will return to the \"available\" state again once the restore process has finished.","s":"Restoring a volume backup from the Cinder Backup service","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#restoring-a-volume-backup-from-the-cinder-backup-service","p":1869},{"i":1911,"t":"When the createImage action of the Compute API (openstack server image create) is used on virtual machines that have at least one volume attached, a snapshot will be created for each attached volume individually and referenced in the resulting image's metadata. This happens regardless of whether the virtual machine has an Ephemeral Storage disk attached. In case of an Ephemeral Storage disk, only the Ephemeral Storage is copied into the Glance image as a 1:1 copy. In case of a virtual machine that has no Ephemeral Storage but only volumes, the createImage action leads to a Glance image that only consists of metadata (including the resulting volume snapshot references) but carries no actual binary data.","s":"Image creation action for servers with attached volumes","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#image-creation-action-for-servers-with-attached-volumes","p":1869},{"i":1913,"t":"The volume encryption keys stored in Barbican are not directly used as LUKS passphrases by OpenStack because they are in binary format. OpenStack converts them to ASCII internally before passing them to the encryption layer. This behavior needs to be reproduced if a decryption of a volume image is desired outside of OpenStack. danger The instructions below will expose plaintext data of encryption keys and encrypted volume images. Make sure to only execute these steps in a secure and trusted environment. First, download the image: openstack image save --file image.raw $IMAGE_NAME_OR_ID Next, inspect the image metadata, determine the reference to the encryption key (cinder_encryption_key_id property) and download the encryption key: openstack image show -f value -c properties $IMAGE_NAME_OR_ID # (use the value of `cinder_encryption_key_id` as `$SECRET_ID` below) openstack secret get --file image.key --payload_content_type \"application/octet-stream\" $SECRET_ID This will result in the following local files: image.raw = the raw encrypted image downloaded from Glance image.key = the LUKS encryption key in binary format (plaintext) Since OpenStack internally uses Python's binascii.hexlify() to convert the binary encryption key before passing it as a passphrase to the LUKS encryption, as a last step this conversion must be mimicked to unlock the encryption: python3 -c \"import binascii; \\ f = open('image.key', 'rb'); \\ print(binascii.hexlify(f.read()).decode('utf-8'))\" \\ | sudo cryptsetup luksOpen ./image.raw decrypted_image The decrypted image is now accessible at /dev/mapper/decrypted_image. Note that this is a live en-/decryption operation on the image.raw file. The image is not converted, the encryption is simply unlocked in-memory using LUKS and dm-crypt until the encryption is closed again. The /dev/mapper/decrypted_image can now be handled like a raw block device (e.g. mounted as a filesystem) or snapshotted in decrypted form. To close the encryption execute: sudo cryptsetup luksClose decrypted_image The source of this document can be found in the SovereignCloudStack/docs repository. Author: SCS Community, License: CC by Attribution 4.0 International","s":"LUKS encryption key conversion to decrypt volume images","u":"/docs/iaas/guides/user-guide/openstack/user-data-backups","h":"#luks-encryption-key-conversion-to-decrypt-volume-images","p":1869},{"i":1915,"t":"Security groups in OpenStack are part of the network security mechanisms provided for the users. They resemble sets of simple firewall rules allowing specific network traffic at a Port of a VM that connects it to a network. The rules allow specific network port numbers and protocols while also differentiating between ingress and egress directions. Usually security groups are assigned to the Port(s) when a virtual machine is created, but assignments can also be changed at runtime later on. Multiple security groups can be assigned to a VM or Port simultaneously and in such case they will be combined as the union of all their rules. caution Security groups are mutable resources. Their rules can be adjusted at any time after creation. Changing the rules of a security group will immediately apply the changes to all Ports or VMs it is assigned to. It is advisable to always review resources which use a security group before making changes to it.","s":"Best Practise: How to configure and use security groups","u":"/docs/iaas/guides/user-guide/security-groups/","h":"","p":1914},{"i":1917,"t":"Every virtual machine that is created may need different firewall rules. These requirements can also change over time. Adding or removing security groups will allow users to adapt the firewall rules specifically to their virtual machines. To harden the firewall settings for your virtual machine you may follow these steps: Before creating a virtual machine its purpose is usually already known. Use this information to identify all incoming and outgoing traffic rules that will be needed based on the communication patterns of the services it is meant to deploy. This includes communication protocols, port numbers, communication directions and optionally target/source address ranges. Look through already existing security groups and their rules. If a security group allows more traffic than needed it SHOULD NOT be used. If a security group contains only a subset of the required rules it MAY be used in combination with other security groups that contain rules which fulfill the remaining required traffic rules from point 1. If you were not successful in finding an appropriate combination of existing security groups or you need additional specific rules to cover all requirements, you MAY create one or more new Security Groups in which you can add the required rules. After ensuring the existence of one or more security groups that fulfill your requirements, you can create the VM with those security groups already specified in the creation command.","s":"Identify the requirements of your setup","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#identify-the-requirements-of-your-setup","p":1914},{"i":1919,"t":"When implementing network security requirements, firewall rules alone are not always sufficient and might need to be augmented with additional configuration or time-based constraints. Notable examples are: SSH SSH is needed on many virtual machines to operate their guest operating system. In a security group the port 22 can be opened for the TCP protocol to allow incoming SSH connections. But that only should be done while also restricting the SSH configuration to public key authentication only (the recommended way) or having a strong username and password policy already applied to the operating system of the virtual machine. Otherwise default usernames and passwords which are often preconfigured in system images may be exploited through the exposed SSH port which enables attackers to compromise the virtual machine. ICMP It might be useful to be able to ping a virtual machine or use other ICMP requests. But for some virtual machine configurations this is either not necessary at all or only temporarily needed. One benefit of security groups among other things is the ability to be easily added to and removed from existing virtual machines. So a dedicated security group allowing ICMP could be added temporarily to a virtual machine for debugging purposes and removed from it afterwards.","s":"Further security considerations","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#further-security-considerations","p":1914},{"i":1921,"t":"Security groups are managed within a project. So every project will have a different set of security groups. They can be added dynamically to each virtual machine, during their creation or afterwards. Additionally, they may also be removed from VMs at any point. Every project has its own default security group, which rules can be edited. Additionally other security groups can be added until the project's quota is exhausted. To add a security group, use the following command: openstack security group create $SECURITY_GROUP Within every security group rules can be added up unto a defined maximum of rules, that usually is about 100. Rules can be added to security groups with the following command: openstack security group rule create [...] $SECURITY_GROUP To delete rules from a security group, the rule id has to be used. It is listed in the details of the rules section of the security group. openstack security group rule delete $RULE_ID","s":"How to create security groups","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#how-to-create-security-groups","p":1914},{"i":1923,"t":"Unless specified otherwise, the default security group is assigned to all VMs or Ports at creation. To use any other than the default security group at creation it is necessary to specify the desired security group(s) during the creation process. To review which rules are defined in a security group, the following command can be used: openstack security group show default","s":"Default security group","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#default-security-group","p":1914},{"i":1925,"t":"While projects can use very different aspects in security group rules and thus the security groups will always differ between projects, there are some security groups that are widely used. Through the nature of security groups being seen as a set of rules that can be combined, having some basic security groups that allow basic protocols is a commonly used setup. This section will demonstrate how to create some security groups for commonly used protocols and ports. A security groups, that allows incoming SSH traffic: openstack security group create ssh openstack security group rule create --ingress --protocol tcp --dst-port 22 ssh A security group, that allows incoming HTTP requests: openstack security group create http openstack security group rule create --ingress --protocol tcp --dst-port 80 http A security group, that allows incoming HTTPS requests: openstack security group create https openstack security group rule create --ingress --protocol tcp --dst-port 443 https A security group, that allows incoming ICMP requests: openstack security group create icmp openstack security group rule create --protocol icmp icmp","s":"Recommended security groups","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#recommended-security-groups","p":1914},{"i":1927,"t":"info Security groups can be assigned to multiple resources simultaneously (such as VMs or Ports). This means that security groups are reusable and don't need to be recreated for each applicable resource individually. Usually, initial security groups are added at the time of the creation of a VM. During creation, multiple security groups can also be added at the same time by repeating the --security-group argument: openstack server create [...] --security-group $SECURITY_GROUP_1 --security-group $SECURITY_GROUP_2 $SERVER_NAME To add a security group to an existing VM, the following command can be used: openstack server add security group $SERVER_NAME $SECURITY_GROUP To remove a security group from a VM, the following command can be used: openstack server remove security group $SERVER_NAME $SECURITY_GROUP","s":"How to use security groups","u":"/docs/iaas/guides/user-guide/security-groups/","h":"#how-to-use-security-groups","p":1914},{"i":1929,"t":"TODO","s":"Compute","u":"/docs/iaas/overview/compute","h":"","p":1928},{"i":1931,"t":"TODO","s":"Knowledge","u":"/docs/iaas/overview/knowledge","h":"","p":1930},{"i":1933,"t":"TODO","s":"Network","u":"/docs/iaas/overview/network","h":"","p":1932},{"i":1935,"t":"TODO","s":"Storage","u":"/docs/iaas/overview/storage","h":"","p":1934},{"i":1937,"t":"Sovereign Cloud Stack wants to make it possible for operators to delegate administration of user identities to the organizational entities that the users are part of. Usually that's customer organizations but it could also be the operator itself. Federation protocols like OpenID Connect can be used to achieve that goal. To simplify connecting the different parts of SCS to customer owned IAM solutions, the SCS reference implementation offers Keycloak as central Identity Provider (IdP) service.","s":"Introduction on Identity Management and Federation in SCS","u":"/docs/iam/","h":"","p":1936},{"i":1939,"t":"Keycloak can be deployed by running osism apply keycloak The required Keycloak client configuration that allows Keystone to obtain OIDC token from Keycloak needs to be deployed by running osism apply keycloak-oidc-client-config After these steps Keystone should be able to obtain token using the Device Authorization Grant with PKCE, which is configured by default in the wsgi-keystone.conf deployed in SCS.","s":"Deployment","u":"/docs/iam/","h":"#deployment","p":1936},{"i":1941,"t":"Currently deployed on the manager node, by default under https://keycloak.. Details TODO.","s":"Accessing Keycloak","u":"/docs/iam/","h":"#accessing-keycloak","p":1936},{"i":1943,"t":"The idea is that customer can create groups with specific names in their own IAM. These shall be mapped to a claim groups to be included in the OIDC token. Via the Keystone mapping they shall be mapped to roles on OpenStack projects. The corresponding section for Developers may be interesting for more technical details. Please be aware that currently there are still some technical challenges to be solved within the OpenStack Keystone mapping engine and the mapping rules to make this work seamlessly.","s":"Identity Mapping","u":"/docs/iam/","h":"#identity-mapping","p":1936},{"i":1945,"t":"Federation between separate deployments of SCS is possible via the IdP by means of OpenID Connect. The section on inter SCS federation setup explains the required steps in some detail.","s":"SCS to SCS federation","u":"/docs/iam/","h":"#scs-to-scs-federation","p":1936},{"i":1947,"t":"Knowledge: Familiarity with Keycloak, OIDC federation, and basic SSL and web security principles is pivotal. Software: The core software component is the OpenID-Connect identity provider, configured to function optimally with OpenStack environments. While the SCS reference implementation focusses on Keycloak as IdP, with appropriate configuration adjustments any OAuth 2.0 compliant IdP should be suitable as an alternative. Each implemntation may have its own pros and cons.","s":"Prerequisites and Requirements","u":"/docs/iam/","h":"#prerequisites-and-requirements","p":1936},{"i":1949,"t":"Horizon Web SSO OpenStack CLI use via the Device Authorization Grant","s":"Features","u":"/docs/iam/","h":"#features","p":1936},{"i":1951,"t":"Keystone currently still has limitations in its mapping engine, which are addressed by the SCS development team as we see possibilities and alignement with upstream OpenDev development plans. Automatically creating ephemeral users in their specific OpenStack domains, as specified in their OIDC token is one example, currently beeing worked on. Please check carefully if the technical results meet the security demands of your specific environment. Keystone currently has another limitation which is being addressed by the SCS development team aligned with upstream OpenDev development plans: The roles for federated users are stored on the database for the ephemeral users created during a federated login. This limits the ability to modify users roles from the identity source directly, as roles of the epehemeral users do not get cleaned up or updated based on changes in the claims contained in the OpenID-Connect token.","s":"Limitations","u":"/docs/iam/","h":"#limitations","p":1936},{"i":1953,"t":"Currently SCS exemplifies deploying Keycloak on the management plane. This shall be moved to a Kubernetes based management plane to improve scalability and architecture. In the near future, the Container layer shall be able to make use of the IdP to allow federated users to access Kubernetes. In the mid term, workloads on Kubernetes shall be able to make use of OAuth tokens to access resources on the IaaS layer.","s":"Current state and future Outlook","u":"/docs/iam/","h":"#current-state-and-future-outlook","p":1936},{"i":1955,"t":"The followig section is a reasonably detailed hands on description of how to configure a federation between two separate SCS compliant domains by means of Keycloak Identity Brokering. If we decide to use Keycloak as a component to allow self service by tenants, then this documentation may be a useful addition to some tenant facing documentation (or for the SCS operators too). OTOH one could probably also script pretty much everything of this to allow tenants to use a CLI tool to automate the setup. For that purpose the documentation may be useful to guide the implementation of such a scripted solution.","s":"Proposal for documentation for Keycloak to Keycloak Federation (WebSSO)","u":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","h":"","p":1954},{"i":1957,"t":"Assume you have two CSPs using SCS. The first one wants to grant access to users of the other. So let's call the first domain \"resource domain\" and the second one \"accounts domain\". Both domains need to agree upon a name for the \"OIDC RP\" (which Keycloak calls Clients). The Keycloak in the \"resource domain\" will be the OIDC RP and the Keycloak in the \"accounts domain\" will be the OIDC OP. Assuming the \"resource domain\" is called foo and the \"accounts domain\" is called bar, the name for the \"OIDC RP\" could be oidc-rp-foo. In the accounts domain (bar) open Keycloak realm osism, click on Clients in the sidebar and click on Create client. Leave the client type as OpenID Connect and enter the Client ID, e.g. oidc-rp-foo. Turn on Client authentication for it and click Save. On the Client details page open the tab Credentials and copy the Client secret. Communicate this to the operato of the \"resource domain\" foo via a secure channel. In the resource domain (foo) open Keycloak realm osism, click on Identity providers and create a new provider definition of type OpenID Connect v1.0. As Alias choose a name, e.g. oidc-op-bar. Don't copy the Redirect URI given at the top yet, because is will change depending on the chosen Alias. Instead, scroll down to the mandatory field Discovery endpoint and paste the OpenID Connect metadata URL of the KEycloak realm osism in the \"accounts domain\" (bar). The operator of the \"accounts domain\" (bar) may easily copy that URL from the Realm Settins in the sidebar of his Keycloak instance, where the Endpoints are listed on the bottom of that form. The URL may have the format https://bar.com/auth/realms/osism/.well-known/openid-configuration. Once you leave that input field, Keycloak will attempt to fetch the metadata and extract the required details about protocol enspoints from the retrieved document. If this shows an error, it will give you an HTTP status code. If this shows an error code of 500, then this may be caused by a failure in certificate verification. In that case you may want to check the output of docker logs keycloak for java stack traces. If you find any, the top of those stack traces may indicate what kind of problem occurred to the java code. From here we will assume that the emtadata URL could be fecthed without any issues. Now, go to the bottom of that form and insert tjhe Client ID (oidc-rp-foo) and the Client secret that was provided by the operator of the \"accounts domain\" (bar). Finally click on Add. From the Provider Details page on the top for the Settings tab copy the value of the Redirect URI and communicate it back to the operator of the \"accounts domain\" (bar). In the accounts domain (bar) open Keycloak realm osism, click on Clients in the sidebar and click on the name of the OIDC RP clinent that you created for domain foo (e.g. oidc-rp-foo). On the Client details page on the tab Settings fill in the field Valid redirect URIs with the value obtained from the resource domain (foo), which should look similar to https://foo.com/auth/realms/osism/broker/oidc-op-bar/endpoint. Additionally the Valid post logout redirect URIs need to be set to something like https://foo.com/auth/realms/osism/*. To test federated login in the \"resource domain\" (foo) open the URL of the Keycloak admin console for the realm osism: https://foo.com/auth/admin/osism/console (or https://foo.com/auth/realms/osism/protocol/openid-connect/auth?client_id=security-admin-console). Ignore the top section of the login form titled Sign in to your account and choose one of the OIDC OP federation choises below the line Or sign in with. In this example it would be oidc-op-bar. This should redirect your browser to the authentication endpoint of the \"accounts domain\" (https://bar.com/auth/realms/osism/protocol/openid-connect/auth?scope=openid&...) where you should be able to log in with credentials that are valid in the \"accounts domain\" (bar). After successull authentication your broser should be redirected to admin console of the \"resource domain\", which may offer you a \"first login flow\" form where you can choose a username, email, firstname and lastname. The details depend on the Mappers that have been configured for the Identity Provider oidc-op-bar. After that you will be presented with a Keycloak themed page with the error message Request failed with status code 403, which is normal because the test account is not authorized to access any elements of the Keycloak admin console.","s":"Detailed tutorial on how to configure Federation (OpenID Connect) between two Keycloak instances in two separate SCS domains","u":"/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operations","h":"#detailed-tutorial-on-how-to-configure-federation-openid-connect-between-two-keycloak-instances-in-two-separate-scs-domains","p":1954},{"i":1959,"t":"The following document explains the idea behind the example configuration is done. The playbook creates a proxy realm used to connect with Keystone, a customer realm, the clients needed to connect the realms, the identity brokering for the customer realm, a login flow to be able to use the home-IdP-discovery plugin to redirect to the correct customer realm and an example user. SCS operators can find the playbook that creates the setup here. In the first place a proxy realm called osism on the example deployment. That realm will become the realm that will be conected to Keystone A customer realm called CustomerA is created. On that realm a OIDC client is created to hook up the realm to the proxy realm. This is done via Identity Brokering in the proxy realm. An Identity provider is configured in the osism realm, this is configured to be connected to the CustomerA realm. For that, a set of mappers are created, the default ones are a hardcoded-attribute that sets the domain where the user came from, and an attribute-importer mapper for the openstack-default-project that comes in the OIDC claim from the customer realm. A new login flow has been created in the osism realm, this login flow is needed to use the home-IdP-discovery plugin. Creation of an example user called Alice.","s":"Example setup configuration in SCS deployment explained","u":"/docs/iam/SCS-example-setup-configuration-description","h":"","p":1958},{"i":1961,"t":"TODO","s":"Overview","u":"/docs/operating-scs/audits/","h":"","p":1960},{"i":1963,"t":"Security has a high priority in modern cloud infrastructures. If you look at it from an automation perspective, a basic distinction of tooling is needed to be considered: SAST or Static Application Security Testing: These tools scan code that is checked into e.g. git and are integrated into build pipelines. They only look at static artifacts: code, dependencies, container images. DAST or Dynamic Application Security Testing: With dynamic testing, running programs and deployed infrastructure are scanned. This allows to identify vulnerabilities, test infrastructure configuration and analyze the behaviour of running processes. In this project, the SCS automated pentesting pipeline, we solely focus on DAST.","s":"SCS automated pentesting","u":"/docs/operating-scs/components/automated-pentesting/overview","h":"","p":1962},{"i":1965,"t":"github.com/SovereignCloudStack/security-infra-scan-pipeline.","s":"Source","u":"/docs/operating-scs/components/automated-pentesting/overview","h":"#source","p":1962},{"i":1967,"t":"See the tools page.","s":"Tools","u":"/docs/operating-scs/components/automated-pentesting/overview","h":"#tools","p":1962},{"i":1970,"t":"By embracing existing open source solutions and bundling them, SCS provides a viable alternative to widely adopted proprietary cloud offerings, including Infrastructure-as-a-Service offerings, Kubernetes-as-a-Service offerings and other X-as-a-Service offerings. The choice to embrace existing technology has huge advantages over starting from scratch. By not reinventing wheels, a lot of effort is saved and existing communities are strengthened. The adoption of existing open standards is supported, reducing market fragmentation and increasing interoperability.","s":"Premise","u":"/docs/operating-scs/components/central-api/overview","h":"#premise","p":1968},{"i":1972,"t":"The challenge: Using popular open source components at cloud service providers does not result in a consistent experience for their users, yet. Each part of the stack is consistent within its own scope: E.g. The OpenStack Networking API is sort of consistent with the OpenStack Load Balancer API. The OpenStack API's share API idioms like the used AuthN/AuthZ (Authentication/Authorization) mechanisms. But these are not applicable beyond OpenStack services. Entering general IAM (Identity and Access Management), Keycloak has its own set of API endpoints and authentication flows. Entering Kubernetes, CAPI (Kubernetes Cluster API) uses the Kubernetes API with its own authentication configuration, RBAC (Role Based Access Control) and opinionated resource management idioms. So, without a central API harmonizing at least the semantics of AuthN/AuthZ and resource management, users are left with a bunch of semantically incompatible API's. If resources in different API's are somehow interconnected, the users have to take care of bridging these differences themselves. Providing a consistent API across many different offerings with sort of consistent API idioms is something that primarily the big proprietary cloud providers manage to do. And while that serves users well in that regard, it also serves as an effective vendor lock-in feature.","s":"Challenge","u":"/docs/operating-scs/components/central-api/overview","h":"#challenge","p":1968},{"i":1974,"t":"Goal: Provide a \"semantically\" consistent API modelling most cloud resources that are in scope for SCS. In other words: Bring each cloud resource type - as it is - into the central API. An OpenStack Compute Instance continues to be as-is with all of its usual properties and implementation details. A Keycloak Realm continues to be as-is with all of its usual properties and implementation details. That is not to say that abstractions are absolutely not planned as further steps. There were discussions happening about that already: Regarding IAM management 1 and Kubernetes management 2. However, the main benefit is that all offered API objects can be managed using the same API idioms (AuthN/AuthZ/REST) with the same client tooling 3.","s":"The chosen approach to pursue","u":"/docs/operating-scs/components/central-api/overview","h":"#the-chosen-approach-to-pursue","p":1968},{"i":1976,"t":"Instead of creating SCS-specific API idioms and building the implementation from scratch, the Kubernetes API will be \"reused\". Essentially, the Kubernetes API is just an opinionated REST API which has opinions on how a resource is defined, how it looks like, how it is reconciled/handled, how AuthN/AuthZ can be implemented. The Kubernetes ecosystem provides much tooling for working with such (custom) resource definitions: For creating the definitions themselves, building controllers, making them discoverable and deployable. As such, Kubernetes is a great choice for building any sort of resource management API - with some caveats regarding its deployment and the legacy of starting off as container orchestration tooling.","s":"Kubernetes API","u":"/docs/operating-scs/components/central-api/overview","h":"#kubernetes-api","p":1968},{"i":1978,"t":"Crossplane even extends the Kubernetes API with \"Compositions\" and \"Composite Resource Definitions\" (XRD) to make Kubernetes the base for platform engineering within organizations. Secondly, it provides an API machinery to bring any cloud resource into Kubernetes using backend-specific \"providers\" (roughly comparable with Terraform providers). As such, Crossplane with its provider ecosystem actually already did most of the heavy lifting for providing e.g. OpenStack or Keycloak resources inside of Kubernetes. On top, the platform engineering concepts in Crossplane make building multi-tenancy systems pretty straight-forward, even for single clusters. Alright. Crossplane takes care of exposing OpenStack resources and does some fancy stuff regarding multi-tenancy. What about providing actual Kubernetes workload clusters?","s":"Crossplane tooling","u":"/docs/operating-scs/components/central-api/overview","h":"#crossplane-tooling","p":1968},{"i":1980,"t":"Cluster stacks do not replace the use of Cluster API. Instead, they are complementing Cluster API by providing ClusterClasses, node images (if required) and workload cluster addons. It is still to be determined how to bring multi-tenancy concepts from Crossplane into ClusterStacks/CAPI, if even required. Should the provider be responsible for creating ClusterClasses? If yes, enforcing some parameters inside via a ClusterClass may be enough to provide multi-tenancy, already. That is to be determined, though.","s":"Cluster stacks / Cluster API","u":"/docs/operating-scs/components/central-api/overview","h":"#cluster-stacks--cluster-api","p":1968},{"i":1982,"t":"Disregarding any potential further abstractions, most work in automation for the providers will be about installing the central API and securely distributing credentials for backing services like OpenStack or Keycloak. For that, there is no production implementation yet. See the POC for inspiration for now. It includes access to an OpenStack API through Kubernetes/Crossplane. Footnotes​ There were discussions to build a generic SCS API to support SCS installations powered by Zitadel. Approaching the issue a little bit like the \"Abstract all the things!\" consideration above, but focusing on two basic use cases (Firstly, setting up an identity federation to some existing identity provider; Secondly, managing users without remote identity provider). While not in scope for the first steps, this probably could be elegantly implemented as one generic Crossplane \"Composite Resource Definition\" backed by a Crossplane \"Composition\" defining either Keycloak objects OR Zitadel objects (given that Zitadel gets a Crossplane provider or a similar Kubernetes controller before). ↩ In order to cover providers that use Gardnener, a generic Crossplane \"Composite Resource Definition\" like in 1 may be created. Alternatively, Gardnener CRD's could maybe just be mirrored in their Central API instance, still creating an interoperability benefit through \"semantic\" compatibility. ↩ Which is also not to say that it will be suggested to providers to disable their public OpenStack/Keycloak/... API's, preventing use of native OpenStack/Keycloak/... tooling and breaking existing solutions. Extensively using these API's together with the central API may compromise the benefits of its uniform AuthZ, though. ↩","s":"Implementation","u":"/docs/operating-scs/components/central-api/overview","h":"#implementation","p":1968},{"i":1984,"t":"There were discussions to build a generic SCS API to support SCS installations powered by Zitadel. Approaching the issue a little bit like the \"Abstract all the things!\" consideration above, but focusing on two basic use cases (Firstly, setting up an identity federation to some existing identity provider; Secondly, managing users without remote identity provider). While not in scope for the first steps, this probably could be elegantly implemented as one generic Crossplane \"Composite Resource Definition\" backed by a Crossplane \"Composition\" defining either Keycloak objects OR Zitadel objects (given that Zitadel gets a Crossplane provider or a similar Kubernetes controller before). ↩ In order to cover providers that use Gardnener, a generic Crossplane \"Composite Resource Definition\" like in 1 may be created. Alternatively, Gardnener CRD's could maybe just be mirrored in their Central API instance, still creating an interoperability benefit through \"semantic\" compatibility. ↩ Which is also not to say that it will be suggested to providers to disable their public OpenStack/Keycloak/... API's, preventing use of native OpenStack/Keycloak/... tooling and breaking existing solutions. Extensively using these API's together with the central API may compromise the benefits of its uniform AuthZ, though. ↩","s":"Footnotes","u":"/docs/operating-scs/components/central-api/overview","h":"#footnote-label","p":1968},{"i":1986,"t":"This guide will explain common procedures for creating and restoring backups of user data accumulated in cloud resources such as volumes, images or ephemeral server disks.","s":"User Data Backups","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"","p":1985},{"i":1988,"t":"Term Explanation Virtual Machine Equals the server resource in Nova. Ephemeral Storage Disk storage directly supplied to a virtual machine by Nova. Different from volumes. (Glance) Image IaaS resource usually storing raw disk data. Managed by the Glance service. (Cinder) Volume IaaS resource representing block storage disk that can be attached as a virtual disk to virtual machines. Managed by the Cinder service. (Volume) Snapshot Thinly-provisioned copy-on-write snapshots of volumes. Stored in the same Cinder storage backend as volumes. Volume Type Attribute of volumes determining storage details of a volume such as backend location or whether the volume will be encrypted. (Barbican) Secret IaaS resource storing cryptographic assets such as encryption keys. Managed by the Barbican service.","s":"Glossary","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#glossary","p":1985},{"i":1990,"t":"User data in the context of this guide describes data accumulated in cloud resources of a user at runtime. This concerns primarily storage data of virtual machines stored at at-rest. This does not cover in-transit or in-use data such as network traffic, virtual machines' RAM contents or IaaS configuration and metadata of cloud resources.","s":"Scope","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#scope","p":1985},{"i":1992,"t":"Given the mentioned scope, the following can be classified as user data: images stored in Glance virtual machine disks, either: Ephemeral Storage stored in Nova volumes stored in Cinder encryption keys stored as secrets in Barbican The following sections will describe backup procedures for each of those resources individually.","s":"Overview of applicable User Data","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#overview-of-applicable-user-data","p":1985},{"i":1994,"t":"Glance images may act as backup targets for other resources (such as volumes) but don't have a dedicated backup service for themselves. When an image is to be backed up, it can be downloaded from the Glance image service and stored outside of the IaaS infrastructure for backup purposes. In this case it is the user's responsibility to establish the backup procedure and appropriate target storage. caution When creating images from volumes with a volume type that uses encryption, the resulting image will contain the raw LUKS-encrypted blocks of the volume. When transferred outside of the IaaS infrastructure, this data is only useful as a backup together with the corresponding encryption key. Such images can be identified by an attribute called cinder_encryption_key_id in the properties metadata field of the image. It only exists for encrypted images and references the encryption key in Barbican. Refer to the Barbican secrets section for instructions on how to backup the key. The API or the OpenStack client may be used to initiate the download, for example: openstack image save --file $TARGET_FILE_PATH $IMAGE_NAME_OR_ID This or the underlying API request may be automated as part of a regular backup schedule involving the backup storage target on the user side.","s":"Image backup using download","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#image-backup-using-download","p":1985},{"i":1996,"t":"caution When using the createImage Compute API action (e.g. via the openstack server image create command) on a virtual machine that has volumes attached to it in addition to its Ephemeral Storage disk, the volumes will not be backed up into the image. Instead, a snapshot will be created for each attached volume and referenced in the image metadata. This does not replace genuine volume backups. See the corresponding appendix section for further details. Ephemeral Storage disks of virtual machines can be backed up to Glance images easily by using the createImage Compute API action or the corresponding OpenStack client command: openstack server image create --name $IMAGE_NAME $SERVER_NAME_OR_ID This will create a Glance image containing a one-to-one copy of the data on the Ephemeral Storage disk at the time of execution. If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.","s":"Ephemeral Storage backup using Glance images","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#ephemeral-storage-backup-using-glance-images","p":1985},{"i":1998,"t":"The following instructions only apply if the infrastructure offers the Cinder Backup API. note Backups of volumes using a volume type that uses encryption will retain their encryption and a clone of the original encryption key is created in Barbican linked to the backup. These backups can only be restored when the Barbican service is available and still has the corresponding copy of the encryption key. Also, it is advised to take note of the exact volume type when creating a backup of an encrypted volume, because this information will be needed to restore the backup. See restoring an encrypted volume backup. info It might be difficult or even impossible for a user to transfer backups created by the Cinder Backup API outside of the IaaS infrastructure, depending on the backup backend. A more easily accessible backup of volumes can be created by using Glance images. See the section about volume data backup using Glance images for details.","s":"Volume data backup using Cinder Backup API","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#volume-data-backup-using-cinder-backup-api","p":1985},{"i":2000,"t":"Backups can be created using the Cinder Backup API or the corresponding OpenStack client commands: openstack volume backup create $VOLUME_NAME_OR_ID Further backups of the same volume can subsequently be created as incremental backups using the following command: openstack volume backup create --incremental $VOLUME_NAME_OR_ID","s":"Backup of detached volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#backup-of-detached-volumes","p":1985},{"i":2002,"t":"note When creating backups of attached (in-use) volumes, the state of the full volume is captured at runtime. Backups created this way will be crash-consistent but not app-consistent. In case of attached (in-use) volumes, backups can only be created while also specfiying the force parameter: openstack volume backup create --force $VOLUME_NAME_OR_ID Further backups of the same volume can subsequently be created as incremental backups using the following command: openstack volume backup create --force --incremental $VOLUME_NAME_OR_ID","s":"Backup of attached volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#backup-of-attached-volumes","p":1985},{"i":2004,"t":"In case the Cinder Backup storage is not available in the IaaS infrastructure, Glance images can be used as a backup target instead. Such images may also subsequently be downloaded to transfer the backup outside of the IaaS infrastructure. note Glance image backups of Cinder volumes only allow full backup copies and do not offer incremental or differential backup mechanisms.","s":"Volume data backup using Glance images","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#volume-data-backup-using-glance-images","p":1985},{"i":2006,"t":"Volumes not attached to virtual machines can be directly copied into an image. Such volumes can be identified by their status being available. To backup a detached volume to a Glance image, directly use the corresponding image creation action: openstack image create --volume $VOLUME_NAME_OR_ID $IMAGE_NAME After the image creation has finished, a full backup copy of the volume will reside in the Glance storage backend. If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.","s":"Glance image backups of detached volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#glance-image-backups-of-detached-volumes","p":1985},{"i":2008,"t":"Cinder is unable to directly create Glance images from volumes which are attached to virtual machines. To create backups of such volumes regardless, a detour using volume snapshots can be used which will be described below. note When creating snapshots of attached (in-use) volumes, the force parameter has to be used. These snapshots capture a state of the full volume at runtime. They will be crash-consistent but not app-consistent. Create a snapshot of the target volume while including the force parameter in the request: openstack volume snapshot create --volume $VOLUME_NAME_OR_ID $SNAPSHOT_NAME Create a new temporary volume based on the snapshot to act as backup source: openstack volume create --snapshot $SNAPSHOT_NAME $TEMP_VOLUME_NAME Wait until the volume creation is finished and the temporary volume reaches the available status. Create a backup image of the temporary volume: openstack image create --volume $TEMP_VOLUME_NAME $IMAGE_NAME Wait until the image creation finishes and the target image reaches the active status. Delete the temporary volume and snapshot: openstack volume delete $TEMP_VOLUME_NAME openstack volume snapshot delete $SNAPSHOT_NAME A full backup copy of the volume now resides in the Glance storage backend. If the necessity arises to store this backup outside of the IaaS infrastructure, the download procedure as described in Image backup using download may be used after the image creation.","s":"Glance image backups of attached (in-use) volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#glance-image-backups-of-attached-in-use-volumes","p":1985},{"i":2010,"t":"danger Secrets downloaded from Barbican will be in plaintext, which means that the secret is unprotected once received from the API. Before downloading secrets from Barbican make sure that a secure target environment is established for receiving and securely storing the secret's contents. Barbican secrets can be downloaded in plaintext using the corresponding API or client command: openstack secret get --file $TARGET_FILE_PATH --payload_content_type \"application/octet-stream\" $SECRET_ID tip In case the secret needs to be restored into an OpenStack Barbican later on, it is recommended to also note down the following attributes shown by openstack secret get $SECRET_ID: Algorithm Bit length Secret type Mode","s":"Barbican secrets backup using download","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#barbican-secrets-backup-using-download","p":1985},{"i":2012,"t":"In case of encrypted volumes (i.e. using a volume type with encryption), a corresponding encryption key is stored in Barbican. When an image is created from such a volume, the encryption key is duplicated in Barbican for the image. In order to backup those keys, the corresponding secret must first be identified. For volumes, this is possible starting with the Volume API microversion 3.64: openstack volume show --os-volume-api-version 3.64 $VOLUME_NAME_OR_ID The response will contain an encryption_key_id field with the ID of the Barbican secret. For images, the secret reference is stored in the properties field instead: openstack image show -f value -c properties $IMAGE_NAME_OR_ID In case of images created from encrypted volumes, the resulting output will have a nested cinder_encryption_key_id field that contains the ID of the Barbican secret. The resulting IDs can be used to retrieve the corresponding key using the Barbican instructions above. caution Note that the key retrieved from the secret is not immediately usable as LUKS passphrase to the image data of the volume. OpenStack does some processing to the key before it is passed to the LUKS encryption, which must be mimicked accordingly in order to unlock the encryption outside of OpenStack! See the example procedure for converting the LUKS key in the appendix section.","s":"Retrieving encryption keys from Barbican","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#retrieving-encryption-keys-from-barbican","p":1985},{"i":2014,"t":"The following sections will illustrate how to restore the individual resource backups that have been documented above.","s":"Restore","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restore","p":1985},{"i":2016,"t":"note Note that restoring a Barbican secret by re-uploading it via the Barbican API will lead to the secret receiving a new ID. Existing resources referencing an old secret ID cannot make use of the restored copy. openstack secret store --algorithm aes --bit-length 256 --mode cbc \\ --secret-type symmetric --file $KEY_FILE_PATH --name $SECRET_NAME Notes: Attributes like algorithm, bit length, mode and secret type are not verified by Barbican. Their main purpose is to classify the secret on a metadata level. Make sure to align the attributes with the original secret. $KEY_FILE_PATH is the local file path of the secret backup as created originally using the instructions above. $SECRET_NAME is entirely optional but helps identifying the restored secret later on and to distinguish it from secrets created by OpenStack itself. It is best to not put whitespace characters in the name, otherwise it has to be surrounded by quotes. The successful registration of the restored secret can subsequently be verified using: openstack secret list --name $SECRET_NAME","s":"Restoring a backup of a Barbican secret","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-backup-of-a-barbican-secret","p":1985},{"i":2018,"t":"Unencrypted image backups can simply be restored using the regular image upload functionality and specifying the backup file: openstack image create --file $IMAGE_FILE_PATH $IMAGE_NAME note In case the original image backup was not based on a volume originally, the image may have had a non-default disk or container format. In this case, add the command parameters --container-format and --disk-format to the command accordingly.","s":"Restoring a backup of an unencrypted image","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-backup-of-an-unencrypted-image","p":1985},{"i":2020,"t":"The following section only applies to image backups that were originally created from images of encrypted volumes. First, restore the corresponding secret of the image using the instructions above. The restored secret will receive a new ID in the form of a UUID. Note down the ID of the restored secret and insert it in place of $SECRET_ID in the command below. openstack image create --file $IMAGE_FILE_PATH \\ --property cinder_encryption_key_id=$SECRET_ID \\ --property cinder_encryption_key_deletion_policy=on_image_deletion \\ $IMAGE_NAME The cinder_encryption_key_deletion_policy attribute is optional. If not specified, the referenced secret will not be deleted on image deletion automatically. In contrast, if set to on_image_deletion, the referenced secret will be deleted as soon as the image referencing it is deleted.","s":"Restoring a backup of an encrypted image","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-backup-of-an-encrypted-image","p":1985},{"i":2022,"t":"To restore a volume from an image backup, simply use the volume creation action and specify the image as source. Depending on whether the original volume the image was created from was encrypted or not, the target volume type might need to be specified accordingly. Whether this is the case can be identified by inspecting the image's metadata using openstack image show $IMAGE_NAME_OR_ID and looking for a \"cinder_encryption_key_id\" field within \"properties\". If it exists, the source volume of the image was encrypted. To restore the image of an unencrypted volume: openstack volume create --image $IMAGE_NAME_OR_ID \\ --size $VOLUME_SIZE_IN_GB $VOLUME_NAME To restore the image of an encrypted volume: openstack volume create --image $IMAGE_NAME_OR_ID \\ --type $ENCRYPTED_VOLUME_TYPE \\ --size $VOLUME_SIZE_IN_GB $VOLUME_NAME If restoring an encrypted image, make sure to specify $ENCRYPTED_VOLUME_TYPE correctly and have it reference a volume type which also supports the encryption. Otherwise the volume will be unbootable or unusable by Nova instances.","s":"Restoring a volume backup from an image","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-volume-backup-from-an-image","p":1985},{"i":2024,"t":"The Cinder Backup service offers dedicated API actions and commands for restoring volume backups created using the service. These backups can be restored in one of two ways: Letting the Cinder Backup service create a new volume based on the backup. Overwriting an existing volume with the backup data. note If the volume backup was originally created from a volume that used a non-default encrypted volume type, letting Cinder Backup create a new volume for backup restoration does not work and the volume type must match exactly. In such case provision an empty volume with the correct type first and then restore the backup onto it as explained further down. Restoring to a new volume (Cinder Backup)​ openstack volume backup restore $BACKUP_NAME_OR_ID $TARGET_NAME ... where $TARGET_NAME is the desired name of the new volume to be created. Make sure that no volume with this name already exists. The Cinder Backup service will create the volume with the same size as the backup indicates. Restoring on an existing volume (Cinder Backup)​ As an alternative to creating a new volume as the restore target, the backup can also be restored on an existing volume: openstack volume backup restore --force $BACKUP_NAME_OR_ID $VOLUME_NAME_OR_ID ... which will overwrite the data on the existing volume, regardless of whether it is empty or not! The volume will enter the \"restoring-backup\" state temporarily and will return to the \"available\" state again once the restore process has finished. Restoring an encrypted volume backup (Cinder Backup)​ When restoring a volume backup of a volume that was using a non-default encrypted volume type, a new volume of that type needs to be created first and then the backup restored onto it. Otherwise, the restoration will fail with the target volume ending up in the \"error_restoring\" state. For this procedure to succeed it is necessary to know the exact volume type of the volume the backup was created from. If the source volume of the backup still exists, the original volume type can be determined by inspecting the backup's volume_id attribute and then using it to look up the corresponding volume and its type attribute. The following client command can be used for this (fill in the value for BACKUP_ID): export BACKUP_ID=... SOURCE_VOLUME_ID=\"$(openstack volume backup show $BACKUP_ID -f value -c volume_id)\" openstack volume show -f value -c type \"$SOURCE_VOLUME_ID\" This returns the name of the original volume type. If the source volume does not exist anymore, rely on documentation about the backup to determine the type, if available. First, create a new empty volume as the restore target and use the backup's size metadata attribute to match the size of the volume to the backup: openstack volume create --size $BACKUP_SIZE --type $VOLUME_TYPE $TARGET_NAME ... where $TARGET_NAME is the desired name of the new volume. Once the volume reaches \"available\" state, restore the backup onto it: openstack volume backup restore --force $BACKUP_NAME_OR_ID $TARGET_NAME The volume will enter the \"restoring-backup\" state temporarily and will return to the \"available\" state again once the restore process has finished.","s":"Restoring a volume backup from the Cinder Backup service","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#restoring-a-volume-backup-from-the-cinder-backup-service","p":1985},{"i":2027,"t":"When the createImage action of the Compute API (openstack server image create) is used on virtual machines that have at least one volume attached, a snapshot will be created for each attached volume individually and referenced in the resulting image's metadata. This happens regardless of whether the virtual machine has an Ephemeral Storage disk attached. In case of an Ephemeral Storage disk, only the Ephemeral Storage is copied into the Glance image as a 1:1 copy. In case of a virtual machine that has no Ephemeral Storage but only volumes, the createImage action leads to a Glance image that only consists of metadata (including the resulting volume snapshot references) but carries no actual binary data.","s":"Image creation action for servers with attached volumes","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#image-creation-action-for-servers-with-attached-volumes","p":1985},{"i":2029,"t":"The volume encryption keys stored in Barbican are not directly used as LUKS passphrases by OpenStack because they are in binary format. OpenStack converts them to ASCII internally before passing them to the encryption layer. This behavior needs to be reproduced if a decryption of a volume image is desired outside of OpenStack. danger The instructions below will expose plaintext data of encryption keys and encrypted volume images. Make sure to only execute these steps in a secure and trusted environment. First, download the image: openstack image save --file image.raw $IMAGE_NAME_OR_ID Next, inspect the image metadata, determine the reference to the encryption key (cinder_encryption_key_id property) and download the encryption key: openstack image show -f value -c properties $IMAGE_NAME_OR_ID # (use the value of `cinder_encryption_key_id` as `$SECRET_ID` below) openstack secret get --file image.key --payload_content_type \"application/octet-stream\" $SECRET_ID This will result in the following local files: image.raw = the raw encrypted image downloaded from Glance image.key = the LUKS encryption key in binary format (plaintext) Since OpenStack internally uses Python's binascii.hexlify() to convert the binary encryption key before passing it as a passphrase to the LUKS encryption, as a last step this conversion must be mimicked to unlock the encryption: python3 -c \"import binascii; \\ f = open('image.key', 'rb'); \\ print(binascii.hexlify(f.read()).decode('utf-8'))\" \\ | sudo cryptsetup luksOpen ./image.raw decrypted_image The decrypted image is now accessible at /dev/mapper/decrypted_image. Note that this is a live en-/decryption operation on the image.raw file. The image is not converted, the encryption is simply unlocked in-memory using LUKS and dm-crypt until the encryption is closed again. The /dev/mapper/decrypted_image can now be handled like a raw block device (e.g. mounted as a filesystem) or snapshotted in decrypted form. To close the encryption execute: sudo cryptsetup luksClose decrypted_image","s":"LUKS encryption key conversion to decrypt volume images","u":"/docs/iaas/guides/user-guide/user-data-backups","h":"#luks-encryption-key-conversion-to-decrypt-volume-images","p":1985},{"i":2031,"t":"Right now, this repository implements issue 374. It contains a script (gen.py) to mirror all crossplane openstack provider cluster-scoped resources to namespaced resources in an SCS API group. Also, these instructions are striving to implement namespaces as isolation mechanism to implement a multi-tenant system backed by a single Kubernetes cluster. crossplane-contrib/x-generation might be used as soon as the required feature for namespace mapping is implemented.","s":"Central API MVP","u":"/docs/operating-scs/components/central-api/poc-setup","h":"","p":2030},{"i":2033,"t":"Setup testing Kubernetes cluster Install crossplane Install openstack provider (See provider.yaml) Mirror openstack resources (See gen.py) Setup provider config (wearing CSP hat) apiVersion: v1 kind: Namespace metadata: name: tenant-name --- apiVersion: openstack.upbound.io/v1beta1 kind: ProviderConfig metadata: name: tenant-name spec: credentials: secretRef: namespace: crossplane-system name: tenant-name-clouds-yaml key: clouds.json source: Secret --- apiVersion: v1 kind: Secret metadata: name: tenant-name-clouds-yaml namespace: crossplane-system stringData: clouds.json: | { \"auth_url\": \"https://api.gx-scs.sovereignit.cloud:5000\", \"application_credential_id\": \"...\", \"application_credential_secret\": \"...\", \"tenant_name\": \"tenant-name\" } Setup RBAC for tenants (wearing CSP hat) apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: tenant rules: - apiGroups: - api.scs.community resources: - '*' verbs: - '*' --- apiVersion: v1 kind: ServiceAccount metadata: name: tenant namespace: tenant-name --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: scs-bind namespace: tenant-name roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: tenant subjects: - kind: ServiceAccount name: tenant namespace: tenant-name Create resource (wearing tenant hat, kubectl --as system:serviceaccount:tenant-name:tenant -n tenant-name) apiVersion: api.scs.community/v1alpha1 kind: KeypairV2 metadata: name: admin namespace: tenant-name spec: name: admin-keypair publicKey: |- ssh-rsa ... --- apiVersion: api.scs.community/v1alpha1 kind: InstanceV2 metadata: name: testing-vm namespace: tenant-name spec: name: testing-vm keyPair: admin-keyPair imageName: 'Debian 12' flavorName: 'SCS-1V:1:20' Observe creation of resources Right now, it would be expected to hand out the ServiceAccount token to the actual tenant; When AuthN is done via OIDC (or other means), the ServiceAccount tenant-name/tenant may be dropped and RoleBinding tenant-name/scs-bind may point to an actual user/group.","s":"Quick Start","u":"/docs/operating-scs/components/central-api/poc-setup","h":"#quick-start","p":2030},{"i":2035,"t":"info The following documentation refers to a SCS standard that is still in draft state. It is not meant for productive use yet but CSPs are encouraged to test-drive and provide feedback!","s":"Domain Manager setup and usage","u":"/docs/iam/domain-manager-setup-and-usage","h":"","p":2034},{"i":2037,"t":"SCS defines the Domain Manager standard, introducing a special persona to the OpenStack Keystone identity manager. This persona offers a properly domain-scoped permission set to manage users, groups, projects and role assignments within a domain. Its intended use case is to offer extensive identity management self-service capabilities to tenants mapped to a domain. This guide will explain setup, configuration and usage of the SCS Domain Manager standard.","s":"Preface","u":"/docs/iam/domain-manager-setup-and-usage","h":"#preface","p":2034},{"i":2039,"t":"Due to architectural limitations currently existing in OpenStack Keystone, assigning the manager role to users while the configuration of the SCS Domain Manager standard has been applied will enable them to see the IDs and names of all existing domains. This includes domains other than their own, meaning that other tenant's identities might be exposed depending on the relation between them and the name of their domain. CSPs aiming to appoint Domain Manager users must be aware of this limitation and should exclusively use pseudonymized domain names across the whole infrastructure. If CSPs strictly follow the SCS naming conventions for domains this is already addressed. If this is not feasible for the CSP, they may opt to refrain from making use of the Domain Manager functionality at all, i.e. never assign the manager role to tenant users. info This architectural limitation will be fixed in upcoming OpenStack and SCS releases. See https://bugs.launchpad.net/keystone/+bug/2041611","s":"Warning regarding the exposure of domain names","u":"/docs/iam/domain-manager-setup-and-usage","h":"#warning-regarding-the-exposure-of-domain-names","p":2034},{"i":2041,"t":"An initial infrastructure configuration of the Domain Manager persona must be completed before it can be used. This includes adjusting the Keystone API policy configuration and the registration of the manager role. The following sections describe the configuration to be implemented on the infrastructure-level. This requires infrastructure access and OpenStack admin rights. For tasks marked with \"[Initial]\" the described procedure only has to happen once initially. For tasks marked with \"[Runtime]\" the described procedure may be repeated later on to make adjustments.","s":"Infrastructure configuration","u":"/docs/iam/domain-manager-setup-and-usage","h":"#infrastructure-configuration","p":2034},{"i":2043,"t":"First, incorporate the Keystone API policy definitions as described in the SCS Domain Manager standard. This is usually done in \"/etc/keystone/policy.yaml\" of the Keystone API service. Otherwise, an entry called \"policy_file\" under the \"[oslo_policy]\" section of \"/etc/keystone/keystone.conf\" might exist that points to a different policy file path. In such case, adjust or create the file at the specified path. When incorporating the policy definitions from the standard make sure to properly merge it with existing policy definitions, if any exist. Also choose the definition of manageable roles in the \"is_domain_managed_role\" rule of the policy carefully according to your requirements and environment. See the standard for more details on this rule. Depending on the deployment method used, the adjustments may also need to be persisted in the corresponding infrastructure management solution, such as Ansible.","s":"[Initial] Keystone API policy adjustments","u":"/docs/iam/domain-manager-setup-and-usage","h":"#initial-keystone-api-policy-adjustments","p":2034},{"i":2045,"t":"The role manager has to exist in Keystone. If the role does not exist, it needs to be created in Keystone once. This can be done with the OpenStackClient using the following command: openstack role create manager","s":"[Initial] Keystone role creation","u":"/docs/iam/domain-manager-setup-and-usage","h":"#initial-keystone-role-creation","p":2034},{"i":2047,"t":"The list of roles that a Domain Manager can assign within a domain is configured using the \"is_domain_managed_role\" rule of the policy definitions. The SCS Domain Manager standard allows flexibility in defining the set of roles a Domain Manager may assign and revoke within a domain and enables adjustments at runtime1. The set of roles can be adjusted independently from the rest of the policy by changing only the \"is_domain_managed_role\" line it Keystone's API policy file. Changes will apply to existing and future Domain Manager users. This means that changes can be implemented at runtime1. The following example entry adjusts the rule to allow both member and reader roles to be managed by Domain Managers: 'is_domain_managed_role': \"'member':%(target.role.name)s or 'reader':%(target.role.name)s\" Refer to the SCS Domain Manager standard for more information.","s":"[Runtime] Domain Manager managed roles adjustment","u":"/docs/iam/domain-manager-setup-and-usage","h":"#runtime-domain-manager-managed-roles-adjustment","p":2034},{"i":2049,"t":"The following sections describe actions available to CSP operators that possess the admin role.","s":"Administrative operation","u":"/docs/iam/domain-manager-setup-and-usage","h":"#administrative-operation","p":2034},{"i":2051,"t":"caution It is highly recommended to use pseudonymized domain names when creating domains, since Domain Managers will currently be able to see the names of all existing domains. See Warning regarding the exposure of domain names for more details. For each tenant for which a self-service area (i.e. a domain) is to be established, a domain should be created before creating any users, projects or groups for this tenant: openstack domain create $DOMAIN Any creation of users, projects or group for a tenant should happen strictly within the tenant's domain by passing the \"--domain\" flag to the corresponding creation commands, regardless of whether the commands are executed by an administrator or a Domain Manager. See the Domain Manager operation section further down for reference.","s":"Creating domains","u":"/docs/iam/domain-manager-setup-and-usage","h":"#creating-domains","p":2034},{"i":2053,"t":"info Creating the first Domain Manager users for a domain is an action reserved for CSP administrators. Depending on whether the manager role has been approved as a domain-managed role in the policy configuration by the CSP, Domain Manager users may be able to appoint further Domain Managers within the domain on their own later on. First, create the user for the Domain Manager. You may create the Domain Manager user either directly in the target tenant's domain or in a different domain. The domain a Domain Manager will effectively be able to manage solely depends on where its role assignment of the manager role is scoped, not the domain the Domain Manager user was originally created in. openstack user create --domain $MANAGER_DOMAIN $USER_NAME note $MANAGER_DOMAIN can be the same as the tenant domain $DOMAIN or an entirely different one, depending on the desired origin domain of the user. In the following sections $DOMAIN will denote the tenant domain that the user is intended to manage as the Domain Manager persona. Next, assign the manager role in a domain-scoped fashion to the tenant domain: openstack role add --user $USER_NAME --domain $DOMAIN manager","s":"Creating a Domain Manager user","u":"/docs/iam/domain-manager-setup-and-usage","h":"#creating-a-domain-manager-user","p":2034},{"i":2055,"t":"openstack role add --user $USER_NAME --domain $DOMAIN manager","s":"Assigning the Domain Manager role to an existing user","u":"/docs/iam/domain-manager-setup-and-usage","h":"#assigning-the-domain-manager-role-to-an-existing-user","p":2034},{"i":2057,"t":"In case the manager role is to be revoked from an existing Domain Manager user, the following command can be used: openstack role remove --user $USER_NAME --domain $DOMAIN manager","s":"Revoking the Domain Manager role","u":"/docs/iam/domain-manager-setup-and-usage","h":"#revoking-the-domain-manager-role","p":2034},{"i":2059,"t":"The following sections describe actions available to Domain Managers that possess the manager role.","s":"Domain Manager operation","u":"/docs/iam/domain-manager-setup-and-usage","h":"#domain-manager-operation","p":2034},{"i":2061,"t":"Creating a user within a domain: openstack user create --domain $DOMAIN $USER_NAME note The explicit domain-scoping is only required for the creation command, any other user-centric commands like \"user set\" or \"user delete\" do not require the \"--domain\" flag and are automatically scoped to the domain for Domain Managers.","s":"Managing users within a domain","u":"/docs/iam/domain-manager-setup-and-usage","h":"#managing-users-within-a-domain","p":2034},{"i":2063,"t":"Creating a project within a domain: openstack project create --domain $DOMAIN $PROJECT_NAME note The explicit domain-scoping is only required for the creation command, any other project-centric commands like \"project set\" or \"project delete\" do not require the \"--domain\" flag and are automatically scoped to the domain for Domain Managers. Deleting projects​ Note that before deleting projects, make sure that all cloud resources (servers, volumes etc.) belonging to that project have been removed beforehand. Otherwise such resources might become orphaned and inaccessible without involving the CSP.","s":"Managing projects within a domain","u":"/docs/iam/domain-manager-setup-and-usage","h":"#managing-projects-within-a-domain","p":2034},{"i":2065,"t":"Creating a group within a domain: openstack group create --domain $DOMAIN $GROUP_NAME note The explicit domain-scoping is only required for the creation command, any other group-centric commands like \"group set\" or \"group delete\" do not require the \"--domain\" flag and are automatically scoped to the domain for Domain Managers. Managing group membership​ Adding a user to a group: openstack group add user $GROUP $USER Removing a user from a group: openstack group remove user $GROUP $USER","s":"Managing groups within a domain","u":"/docs/iam/domain-manager-setup-and-usage","h":"#managing-groups-within-a-domain","p":2034},{"i":2067,"t":"Role assignments managed by a Domain Manager work as usual with the exception that the roles that can be assigned and revoked are limited to a defined set which is explicitly approved for Domain Managers by the CSP. This may or may not include the manager role itself, meaning that Domain Managers may either be able to appoint other Domain Managers by themselves or have to ask the CSP to do so. Managing user role assignments​ Assigning a role to a user within a project: openstack role add --project $PROJECT --user $USER $ROLE Assigning a role to a user domain-wide: openstack role add --domain $DOMAIN --user $USER $ROLE Revoking a project-level role assignment from a user: openstack role remove --project $PROJECT --user $USER $ROLE Revoking a domain-wide role assignment from a user: openstack role remove --domain $DOMAIN --user $USER $ROLE Managing group role assignments​ Assigning a role to a group within a project: openstack role add --project $PROJECT --group $GROUP $ROLE Assigning a role to a group domain-wide: openstack role add --domain $DOMAIN --group $GROUP $ROLE Revoking a project-level role assignment from a group: openstack role remove --project $PROJECT --group $GROUP $ROLE Revoking a domain-wide role assignment from a group: openstack role remove --domain $DOMAIN --group $GROUP $ROLE Footnotes​ \"at runtime\" in this context means that the configuration may be changed repeatedly after the initial configuration of Keystone and take effect immediately. Depending on the infrastructure management solution and high-availability configuration the described adjustments may or may not require a restart of the Keystone API service or lead to a downtime of the service. ↩ ↩2","s":"Managing role assignments within a domain","u":"/docs/iam/domain-manager-setup-and-usage","h":"#managing-role-assignments-within-a-domain","p":2034},{"i":2069,"t":"\"at runtime\" in this context means that the configuration may be changed repeatedly after the initial configuration of Keystone and take effect immediately. Depending on the infrastructure management solution and high-availability configuration the described adjustments may or may not require a restart of the Keystone API service or lead to a downtime of the service. ↩ ↩2","s":"Footnotes","u":"/docs/iam/domain-manager-setup-and-usage","h":"#footnote-label","p":2034},{"i":2071,"t":"This page contains instructions on how to enable the Alertmanager to Matrix chat notifications in the Observer solution. Project https://github.com/metio/matrix-alertmanager-receiver is used for forwarding alerts to a Matrix room. To use it, fill your matrix credentials in matrix-alertmanager/matrix-alertmanager-receiver.yaml ConfigMap and deploy it: kubectl apply -f matrix-alertmanager/matrix-alertmanager-receiver.yaml You can modify other settings according to the mentioned project docs in the ConfigMap. You have to also uncomment a related section in values-observer.yaml alertmanager section. The sections related to Alertmanager notifications in the values-observer-scs.yaml values file are already uncommented.","s":"Alertmanager notifications in Matrix chat","u":"/docs/operating-scs/components/monitoring/docs/alertmanager","h":"","p":2070},{"i":2073,"t":"The following tools make up the automated pentesting pipeline. Each tool has it's own use case and they build up onto each other.","s":"Tools Description","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"","p":2072},{"i":2075,"t":"Functionality: Naabu is a port scanning tool used for identifying open ports on a target host or IP range, crucial for initial reconnaissance in penetration testing. Capabilities: Fast Scanning: Utilizes a high-speed, asynchronous approach for efficient port scanning. Multiple Output Formats: Supports text, JSON, and XML formats for integration with other tools. Flexible Target Specification: Capable of scanning individual hosts, IP ranges, or CIDR notations. Custom Port Ranges: Allows scanning specific port ranges or using standard lists of common ports. Updates: Regularly updated for performance improvements and new features.","s":"Naabu","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"#naabu","p":2072},{"i":2077,"t":"Functionality: HTTPx is a powerful HTTP toolkit for web server fingerprinting, crucial for identifying web technologies and analyzing responses from web servers. Capabilities: High-Speed HTTP Detection: Efficient in analyzing HTTP servers and responses. Status Code Retrieval: Collects HTTP status codes to identify live hosts and valid endpoints. Custom Headers and Methods: Supports advanced HTTP requests for detailed analysis. Automation-Friendly: Easily integrates into automated workflows and pipelines. Updates: Continuously updated with enhancements for speed, accuracy, and additional features.","s":"HTTPx","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"#httpx","p":2072},{"i":2079,"t":"Functionality: Nuclei is a template-based vulnerability scanner, essential for detecting known vulnerabilities using predefined and community-driven templates. Capabilities: Extensive Template Library: Wide range of continuously updated templates for various vulnerabilities. Custom Template Creation: Allows creation of tailored templates for specific environment needs. Broad Vulnerability Coverage: Capable of scanning a variety of security weaknesses and exposures. Integration-Ready: Designed to fit seamlessly into CI/CD pipelines. Updates: Community and developers regularly update templates and tool features.","s":"Nuclei","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"#nuclei","p":2072},{"i":2081,"t":"Functionality: Greenbone CE, known as OpenVAS, is a full-featured vulnerability scanner for comprehensive assessments of networks, hosts, and applications. Capabilities: Wide Range of Tests: Offers a broad spectrum of network and application vulnerability tests. Regular Feed Updates: The vulnerability feed is frequently updated for new threats. Scan Customization: Supports various scan configurations and scheduling. Detailed Reporting: Generates comprehensive reports for compliance and remediation planning. Updates: Maintained with regular updates to the vulnerability feed and software enhancements.","s":"Greenbone Community Edition (OpenVAS)","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"#greenbone-community-edition-openvas","p":2072},{"i":2083,"t":"Functionality: ZAP Proxy is an intercepting proxy for dynamic application security testing (DAST), vital for identifying vulnerabilities in web applications. Capabilities: Passive and Active Scanning: Provides both passive scanning (traffic analysis) and active scanning (direct testing). Comprehensive Web App Mapping: Includes tools like Spider and AJAX Spider for thorough application mapping. Supports Various Authentication Types: Handles different web application authentication mechanisms. Extensibility: Offers a range of plugins and extensions for additional functionalities. Updates: Regularly updated with new features and security tests.","s":"ZAP Proxy","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"#zap-proxy","p":2072},{"i":2085,"t":"Functionality: Defect Dojo is a security program and vulnerability management tool. It centralizes and streamlines the management of security programs, allowing for efficient tracking, measurement, and reporting of vulnerabilities. Capabilities: Vulnerability Management: Enables tracking and management of vulnerabilities discovered across different tools and tests. Reporting and Metrics: Offers comprehensive reporting features for understanding security postures and metrics. Integration with CI/CD: Seamlessly integrates with CI/CD pipelines for automated importing of scan results. Customization and Flexibility: Allows customizations to fit various workflow requirements and integrates with other tools via APIs. Updates: Regularly updated with enhancements for functionality, usability, and security.","s":"Defect Dojo","u":"/docs/operating-scs/components/automated-pentesting/tools","h":"#defect-dojo","p":2072},{"i":2087,"t":"This component is marked as experimental, and it is not part of the reference SCS installation available at https://monitoring.scs.community. IaaS monitoring currently integrates and is able to observe the following targets: OpenStack Ceph","s":"IaaS monitoring (experimental)","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"","p":2086},{"i":2089,"t":"To test the Monitoring of the IaaS layer we expect running Kubernetes cluster that already contains SCS monitoring platform.","s":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#prerequisites","p":2086},{"i":2091,"t":"KinD​ Install the SCS monitoring solution into the KinD Kubernetes cluster following the instructions provided in the quickstart guide. K3s​ Install the SCS monitoring solution into the K3s Kubernetes cluster following the instructions provided in the k3s guide.","s":"Local environment use case - KinD/K3s cluster deployed locally","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#local-environment-use-case---kindk3s-cluster-deployed-locally","p":2086},{"i":2093,"t":"OSISM utilizes the k3s distribution of Kubernetes as a management cluster for the OSISM IaaS platform. This management cluster is then used as a host for the SCS monitoring solution. Subsequently, the management cluster becomes an Observer cluster as it hosts the SCS monitoring solution. From that point, the Observer cluster observes itself (i.e., k3s cluster control plane components and nodes) and is used for observing the IaaS layer around the k3s cluster. In the case of the existing OSISM IaaS deployment >= 7.0.3 on baremetal, testbed or cloud in the box we expect a management k3s Kubernetes cluster with the deployed SCS monitoring platform. If your OSISM installation does not meet the above requirements, apply the following plays: osism apply kubernetes osism apply kubernetes-monitoring","s":"OSISM use case - K3s cluster in OSISM deployment","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#osism-use-case---k3s-cluster-in-osism-deployment","p":2086},{"i":2096,"t":"Prometheus metrics and alerts​ The OpenStack exporter for Prometheus could be deployed using the SCS openstack-exporter-helm-chart. This exporter contains a bunch of Prometheus alerts and rules that are deployed together with the exporter. Visit the iaas/openstack-exporter-values.yaml file to validate the Helm configuration options. Ensure valid OpenStack API credentials are set under the clouds_yaml_config section. This MUST be overridden! helm upgrade --install prometheus-openstack-exporter oci://registry.scs.community/openstack-exporter/prometheus-openstack-exporter \\ --version 0.4.5 \\ -f iaas/openstack-exporter-values.yaml # --set \"endpoint_type=public\" --set \"serviceMonitor.scrapeTimeout=1m\" Tip: If you want to test the exporter basic functionality with public OpenStack API, configure endpoint_type to public (--set \"endpoint_type=public\"). Note that configuring endpoint_type as public will result in incomplete functionality for the Grafana dashboard. Tip: Requesting and collecting metrics from the OpenStack API can be time-consuming, especially if the API is not performing well. In such cases, you may observe timeouts on the Prometheus server when it tries to fetch OpenStack metrics. To mitigate this, consider increasing the scrape interval to e.g. 1 minute (--set \"serviceMonitor.scrapeTimeout=1m\"). Grafana dashboards​ The Grafana dashboard designed to visualize metrics collected from an OpenStack cloud through the OpenStack exporter is publicly available at https://grafana.com/grafana/dashboards/21085. Its source code is located in the iaas/dashboards directory. Feel free to import it to the Grafana via its source or ID. For automatic integration into the SCS monitoring solution proceed to the next step. Update the SCS monitoring deployment​ This step deploys the Grafana dashboards and instructs the monitoring stack to add the OpenStack exporter target into the Prometheus configuration: helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack --reset-then-reuse-values -f iaas/values-observer-iaas.yaml Note: The --reset-then-reuse-values option requires Helm v3.14.0 or later. Alternatively, you can use the original values by applying -f values-observer.yaml, see full command: helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml -f iaas/values-observer-iaas.yaml Access the OpenStack dashboard​ At this point, you should have the ability to access the Grafana UI, and OpenStack dashboard. Log in to the Grafana UI and find the OpenStack dashboard in IaaS directory: http://localhost:30000 or directly access the OpenStack dashboard: http://localhost:30000/d/openstack-overview Use the following credentials: username: admin password: pass","s":"OpenStack","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#openstack","p":2086},{"i":2098,"t":"The SCS IaaS reference implementation (OSISM) currently supports ceph-ansible method for deploying Ceph. Support for the rook operator deployment method will be available soon. This guide covers Ceph cluster monitoring for both deployment methods. While both expose the same metrics via the same endpoint, there are some differences in Prometheus configuration and alerts. Prometheus metrics and alerts​ Ceph contains 2 build-in sources of metrics a.k.a. exporters. The Ceph exporter (introduced in Reef release of Ceph) is the main source of Ceph performance metrics. It runs as a dedicated daemon. This daemon runs on every Ceph cluster host and exposes a metrics end point where all the performance counters exposed by all the Ceph daemons running in the host are published in the form of Prometheus metrics. The second source of metrics is the Prometheus manager module. It exposes metrics related to the whole cluster, basically metrics that are not produced by individual Ceph daemons. Read the related Ceph docs. Since these exporters are integrated with Ceph, deploying a third-party Ceph exporter is unnecessary. Prometheus alerts Both Ceph deployment strategies use the ceph-mixins project as a source of alerts. The ceph-ansible and rook projects each maintain a rendered version of these alerts, but the rook repository contains some differences, primarily because rook does not use the cephadm tool as a backend. Therefore, find and apply one of the following commands to create a custom observer rules values file for either the ceph-ansible or ceph-rook deployment (yq tool required): # ceph-ansible curl -s https://raw.githubusercontent.com/ceph/ceph/main/monitoring/ceph-mixin/prometheus_alerts.yml | \\ yq '{\"kube-prometheus-stack\": {\"additionalPrometheusRulesMap\": {\"ceph-ansible-rules\": (. + {\"additionalLabels\": {\"prometheus_rule\": \"1\"}})}}}' > iaas/values-observer-ceph-rules.yaml # rook curl -s https://raw.githubusercontent.com/rook/rook/master/deploy/charts/rook-ceph-cluster/prometheus/localrules.yaml | \\ yq '{\"kube-prometheus-stack\": {\"additionalPrometheusRulesMap\": {\"ceph-rook-rules\": (. + {\"additionalLabels\": {\"prometheus_rule\": \"1\"}})}}}' > iaas/values-observer-ceph-rules.yaml Grafana dashboards​ We've tested and could recommend 2 sources of Grafana dashboards that are suitable for both Ceph deployment strategies (ansible and rook): dashboards linked in rook docs ceph-mixins dashboards Built version of ceph-mixins dashboards could be found e.g. here We consider the dashboards created within the Rook project as a solid starting point for Ceph metrics visualization. If you want to see more detailed dashboards, uncomment and use the ceph-mixin dashboards in the values-observer-ceph-rook.yaml or values-observer-ceph-ansible.yaml file. You can use both. Update the SCS monitoring deployment​ This step deploys Grafana dashboards, Prometheus rules and instruct monitoring stack to add the Ceph exporter targets into the Prometheus configuration. Ensure that you add the monitoring targets' IPs and ports to values-observer-ceph-ansible.yaml for Ceph-ansible deployment. helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack --reset-then-reuse-values \\ -f iaas/values-observer-ceph-rules.yaml \\ -f iaas/values-observer-ceph-[rook|ansible].yaml # use values file for either the ceph-ansible or ceph-rook deployment Note: The --reset-then-reuse-values option requires Helm v3.14.0 or later. Alternatively, you can use the original values by applying -f values-observer.yaml, see full command: helm upgrade dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml -f iaas/values-observer-ceph-rules.yaml -f iaas/values-observer-ceph-[rook|ansible].yaml","s":"Ceph","u":"/docs/operating-scs/components/monitoring/docs/iaas","h":"#ceph","p":2086},{"i":2100,"t":"K3s is a certified Kubernetes distribution optimized for production environments, particularly in remote locations or resource-constrained environments. Within the OSISM IaaS distribution, it serves as the management cluster, accommodating various management software. Our aim is to integrate the SCS Observability platform as an observer solution for the IaaS layer. To achieve this, we deploy the SCS Observability solution within the IaaS k3s management cluster. This setup enables us to monitor not only the management k3s cluster itself but also the surrounding IaaS control plane components. This page contains information on how to develop and/or test the Observer solution as a monitoring solution for a k3s cluster. It guides the user to create an HA k3s cluster via k3d (a wrapper to run k3s in Docker) and bootstrap it with the Observer solution. Note that the following tutorial guides you to deploy an HA K3s cluster consisting of 3 control plane nodes (servers) and one worker node (agent). The reason is that the HA K3s cluster utilizes an embedded etcd cluster as cluster storage (refer to https://docs.k3s.io/datastore/ha-embedded) and the HA mode is also used in OSISM Testbed and productive bare metal deployments. Using a single-node K3s cluster that uses the SQLite database (default) requires additional tweaks of monitoring values, which are not covered in this guide.","s":"K3s support","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"","p":2099},{"i":2102,"t":"K3d helm kubectl","s":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"#prerequisites","p":2099},{"i":2104,"t":"k3d cluster create --config k3s-config.yaml --image rancher/k3s:v1.28.8-k3s1 observer If you opt not to use K3D with the custom config we provided here, and prefer utilizing another Kubernetes cluster, ensure that the metric endpoints for various control plane components are properly exposed. Refer to the docs.","s":"Prepare K3s Kubernetes cluster via K3d","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"#prepare-k3s-kubernetes-cluster-via-k3d","p":2099},{"i":2106,"t":"K3s consolidates all Kubernetes control plane components into a single process, which means that the metrics for these control plane components are exposed on the K3d hosts rather than through individual Kubernetes Services/PODs. To customize monitoring values for K3s, refer to the specific custom HELM values file values-observer-k3s.yaml. This file contains the necessary configurations and adjustments needed to monitor K3s. Note that list of control plane node IPs (endpoints) should be overridden. Get and store the K3d control plane node IPs: NODE_IPS=$(kubectl get nodes -l node-role.kubernetes.io/control-plane=true -o jsonpath='{.items[*].status.addresses[?(@.type==\"InternalIP\")].address}' | tr ' ' ',' | sed 's/^/{&/;s/$/}/') Install the monitoring stack and set the control plane component endpoints helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/ helm repo update dnationcloud helm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer-k3s.yaml \\ --set \"kube-prometheus-stack.kubeEtcd.endpoints=$NODE_IPS\" \\ --set \"kube-prometheus-stack.kubeProxy.endpoints=$NODE_IPS\" \\ --set \"kube-prometheus-stack.kubeControllerManager.endpoints=$NODE_IPS\" \\ --set \"kube-prometheus-stack.kubeScheduler.endpoints=$NODE_IPS\"","s":"Deploy Observer monitoring solution","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"#deploy-observer-monitoring-solution","p":2099},{"i":2108,"t":"At this point, you should have the ability to access the Grafana, Alertmanager and Prometheus UIs within the Observer monitoring cluster. Grafana UI http://localhost:30000 Use the following credentials: username: admin password: pass Visit the Layer 0 dashboard, infrastructure-services-monitoring, and drill down to explore cluster metrics http://localhost:30000/d/monitoring/infrastructure-services-monitoring Alertmanager UI http://localhost:30001 Prometheus UI http://localhost:30002","s":"Access the Observer monitoring UIs","u":"/docs/operating-scs/components/monitoring/docs/k3s","h":"","p":2099},{"i":2110,"t":"We set up oauth2 with GitHub provider for the https://monitoring.scs.community according to the https://kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/. To use it, inspect oauth/oauth2-proxy.yaml and modify it according to your needs. You want to change at least these: OAUTH2_PROXY_CLIENT_ID OAUTH2_PROXY_CLIENT_SECRET OAUTH2_PROXY_COOKIE_SECRET ingress host Then deploy oauth2-proxy as follows: kubectl apply -f oauth/oauth2-proxy.yaml We set up OAuth authentication for these components: Thanos Query it is exposed via ingress on monitoring.scs.community/thanos modified with --web.external-prefix=thanos extra flag ruler query endpoint and grafana datasource url need to be modified Alertmanager it is exposed via ingress on monitoring.scs.community/alertmanager modified with routePrefix: /alertmanager alertmanagerSpec ruler alertmanager url needs to be modified You have to also uncomment a related sections in values-observer.yaml for exposing the components via ingress. The sections related to OAUTH in the values-observer-scs.yaml values file are already uncommented.","s":"OAUTH","u":"/docs/operating-scs/components/monitoring/docs/oauth","h":"","p":2109},{"i":2112,"t":"This component is marked as experimental, and it is not part of the reference SCS installation available at https://monitoring.scs.community.","s":"KaaS monitoring (experimental)","u":"/docs/operating-scs/components/monitoring/docs/kaas","h":"","p":2111},{"i":2114,"t":"TODO: Provide clear instructions on how to enable KaaS layer monitoring. Please check out the mvp-0 tag and find the related comments on what needs to be done in the monitoring values to enable KaaS monitoring in your Observer cluster.","s":"Enable KaaS layer monitoring","u":"/docs/operating-scs/components/monitoring/docs/kaas","h":"#enable-kaas-layer-monitoring","p":2111},{"i":2116,"t":"To test the Monitoring of the KaaS layer use case, deploy the Kaas-metric-importer into the Observer cluster. The Kaas-metric-importer is a simple service through which the KaaS software registers and unregisters newly created or deleted KaaS clusters in the Observer monitoring. This functionality enables the Observer monitoring to differentiate between KaaS clusters deleted intentionally and those that have stopped writing metrics to the Observer monitoring for any reason. kubectl apply -f kaas/kaas-metric-importer.yaml The Kaas-metric-importer uses an image built from https://github.com/m3dbx/prometheus_remote_client_golang. It has mounted configmap and based on configmap keys it pushes custom metric kaas with label cluster and value 1 into the thanos receiver. Example of configmap: data: workload-cluster: \"\" It pushes metric e.g. kaas{cluster=\"workload-cluster\"} 1 to the Observer. It is important to keep the configmap up-to-date with your KaaS offering. This is automated e.g. in the KaaS mock service below.","s":"KaaS metric importer","u":"/docs/operating-scs/components/monitoring/docs/kaas","h":"#kaas-metric-importer","p":2111},{"i":2118,"t":"To evaluate the Monitoring of the KaaS layer use case and view actual metrics in your Observer monitoring cluster, you can launch the KaaS mock service. Put your Observer monitoring cluster kubeconfig into the ./kaas/manifests/ directory and name it observer-kubeconfig.yaml (or adjust kaas service ./kaas/app/config.py accordingly). If you're utilizing the KinD Observer deployment outlined in this tutorial, collect the kubeconfig using the following command: kind get kubeconfig --name observer > ./kaas/manifests/observer-kubeconfig.yaml All KaaS mock service dependencies can be installed via the corresponding ./kaas/requirements.txt file. Installing them into a Python virtualenv is recommended. cd kaas python3 -m venv .venv # Optional source .venv/bin/activate # Optional # Install kaas dependencies pip install -r requirements.txt # Launch the KaaS mock service make kaas At this point, you should have the ability to access the KaaS mock service Swagger UI: http://127.0.0.1:8080/kaas Create KaaS cluster through Swagger UI: Create Cluster or call directly the KaaS service API via some client, e.g.: curl -X POST -H \"Content-Type: application/json\" http://127.0.0.1:8080/api/clusters/ -d '{\"name\": \"kaas\"}' Navigate to the KaaS Monitoring dashboard in the Observer monitoring. After a few minutes (approximately 4), your KaaS cluster should become visible. Click on the cluster box to dive into KaaS cluster dashboards at a more detailed level. Repeat the process to explore further and gain deeper insights. Note: The disk utilization expression for the Docker environment has not been adjusted, so you will encounter non-realistic numbers in the nodes/disk sections. However, the other sections should accurately reflect the reality. Retrieve a list of all KaaS clusters and check their status. Swagger UI: Get List of Clusters or call directly the KaaS service API via some client, e.g.: curl -s -X GET -H 'accept: application/json' http://127.0.0.1:8080/api/clusters/ Get Kaas Cluster kubeconfig by its name through Swagger UI: Get Cluster kubeconfig or call directly the KaaS service API via some client and save it, e.g.: curl -s -X GET -H 'accept: application/json' http://127.0.0.1:8080/api/clusters/kaas > kaas-kube Now, you have the opportunity to play with your KaaS cluster and experiment with triggering monitoring alerts by initiating actions like destroying certain components 😎. kubectl --kubeconfig kaas-kube get po -A Finally, delete your KaaS cluster by its name through Swagger UI: Delete Cluster or call directly the KaaS service API via some client and save it, e.g.: curl -X DELETE http://127.0.0.1:8080/api/clusters/?name=kaas","s":"KaaS mock service","u":"/docs/operating-scs/components/monitoring/docs/kaas","h":"#kaas-mock-service","p":2111},{"i":2120,"t":"This page contains instructions on how to enable probing of infrastructure service endpoints using blackbox exporter. Infrastructure service endpoints can be probed using protocols such as HTTP, HTTPS, DNS, TCP, ICMP, and gRPC. Blackbox exporter is a component of the monitoring stack. Therefore, it can be deployed into the Observer cluster and configured simply by using the Helm chart values. To enable probing of infrastructure service endpoints with blackbox exporter, locate and uncomment the related section in values-observer.yaml. The sections related to blackbox exporter in the values-observer-scs.yaml values file are already uncommented.","s":"Infrastructure service endpoints","u":"/docs/operating-scs/components/monitoring/docs/infrastructure_services","h":"","p":2119},{"i":2122,"t":"These page covers the process of deploying the Observer monitoring solution into the Kubernetes cluster. The configuration options used in this tutorial result in a non-productive and simple deployment of the Observer monitoring solution. The steps do not guide users to register certain observer targets, such as existing Kubernetes clusters or virtual machines. Additionally, the tutorial lacks guidance for deploying optional and experimental components like IaaS and KaaS monitoring. At the end of this tutorial, the reader should end up with a Kubernetes cluster where the Observer solution will be installed and will monitor the Kubernetes cluster hosting it.","s":"Quickstart","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"","p":2121},{"i":2124,"t":"Kubernetes cluster kubectl helm","s":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"#prerequisites","p":2121},{"i":2126,"t":"The Observer monitoring solution is designed to operate on Kubernetes clusters. We have continuously tested it with various Kubernetes distributions, including vanilla Kubernetes, OKD, SCS KaaS V1, and SCS KaaS V2. To set up the SCS KaaS V2 Kubernetes cluster, please refer to the quickstart guide. For local testing purposes, we recommend using KinD (Kubernetes in Docker) as follows: kind create cluster --config kind-observer-config.yaml --image kindest/node:v1.27.3 --name observer If you opt not to use KinD with the custom config we provided here, and prefer utilizing another Kubernetes cluster, ensure that the metric endpoints for various control plane components are properly exposed. Refer to the docs.","s":"Prepare Kubernetes cluster","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"#prepare-kubernetes-cluster","p":2121},{"i":2128,"t":"helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/ helm repo update dnationcloud helm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer.yaml","s":"Deploy Observer monitoring solution","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"#deploy-observer-monitoring-solution","p":2121},{"i":2130,"t":"At this point, you should have the ability to access the Grafana, Alertmanager and Thanos UIs within the Observer monitoring cluster. Grafana UI http://localhost:30000 Use the following credentials: username: admin password: pass Visit the Layer 0 dashboard, infrastructure-services-monitoring, and drill down to explore cluster metrics http://localhost:30000/d/monitoring/infrastructure-services-monitoring Alertmanager UI http://localhost:30001 Thanos UI http://localhost:30002","s":"Access the Observer monitoring UIs","u":"/docs/operating-scs/components/monitoring/docs/quickstart","h":"#access-the-observer-monitoring-uis","p":2121},{"i":2132,"t":"The following steps were utilized to deploy the SCS reference installation of the Observer monitoring solution, which is available at https://monitoring.scs.community.","s":"SCS deployment","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","h":"","p":2131},{"i":2134,"t":"Currently, the detailed architecture diagram can be visualized as follows:","s":"Architecture","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","h":"#architecture","p":2131},{"i":2136,"t":"Kubernetes cluster We used the R5 version of SCS KaaS V1, which includes an ingress controller and cert manager export KUBECONFIG=/path/to/kubeconfig kubectl helm","s":"Prerequisites","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","h":"#prerequisites","p":2131},{"i":2138,"t":"Apply SCS brand secrets and letsencrypt issuer manifest. kubectl apply -f scs/logo.yaml kubectl apply -f scs/brand.yaml kubectl apply -f scs/issuer.yaml Deploy the Zuul monitoring related Helm chart and all associated manifests according to the instructions provided on this documentation page. Deploy the Alertmanager to Matrix chat notifications related manifest according to the instructions provided on this documentation page. Deploy the OAUTH related manifest according to the instructions provided on this documentation page. Review the values-observer-scs.yaml file and locate all instances of the placeholder text \"replace-me\". These values relate to configuring access to the object store as well as the Grafana admin password. Finally, install the monitoring stack using values that incorporate all the configurations mentioned above helm repo add dnationcloud https://dnationcloud.github.io/helm-hub/ helm repo update dnationcloud helm upgrade --install dnation-kubernetes-monitoring-stack dnationcloud/dnation-kubernetes-monitoring-stack -f values-observer-scs.yaml","s":"Install Observer solution","u":"/docs/operating-scs/components/monitoring/docs/scs-deployment","h":"#install-observer-solution","p":2131},{"i":2140,"t":"This page contains a guide on how to enable traces in Thanos. Traces are not enabled by default. Thanos supports different tracing backends that implements opentracing.Tracer interface. All clients could be configured by --tracing.config-file parameter to reference to the configuration file or by --tracing.config parameter to put yaml config directly. Recommended way is to pass configuration directly as it gives an explicit static view of configuration for each component, and it also saves you the fuss of creating and managing additional files.","s":"Traces","u":"/docs/operating-scs/components/monitoring/docs/tracing","h":"","p":2139},{"i":2142,"t":"Here is the example of the configuration how to enable jaeger in Thanos. This configuration can be applied for multiple components e.g. query-frontend, query or thanos-sidecar. thanos: queryFrontend: extraFlags: - |- --tracing.config=\"config\": \"sampler_param\": 2 \"sampler_type\": \"ratelimiting\" \"service_name\": \"thanos-query-frontend\" \"agent_host\": \"jaeger-agent..svc\" \"agent_port\": 5775 \"type\": \"JAEGER\"","s":"Example","u":"/docs/operating-scs/components/monitoring/docs/tracing","h":"#example","p":2139},{"i":2144,"t":"Once tracing is enabled, Thanos will generate traces for all gRPC and HTTP APIs thanks to generic “middlewares”. Some more interesting to observe APIs like query or query_range have more low-level spans with focused metadata showing latency for important functionalities. For example, Jaeger view of query_range HTTP API call might look as follows:","s":"Usage","u":"/docs/operating-scs/components/monitoring/docs/tracing","h":"#usage","p":2139},{"i":2146,"t":"This page contains recommended parameters to set for the Thanos components to improve performance in terms of query time. The following parameters have already been incorporated into the upstream dNation monitoring repositories, and therefore are already included in the SCS observability deployment.","s":"Tuning","u":"/docs/operating-scs/components/monitoring/docs/tuning","h":"","p":2145},{"i":2148,"t":"queryFrontend: extraFlags: - --query-range.split-interval=12h - --query-frontend.log-queries-longer-than=10s - --query-frontend.compress-responses - |- --query-range.response-cache-config=\"config\": \"max_size\": \"500MB\" \"max_size_items\": 0 \"validity\": 0s \"type\": \"in-memory\" Notes on the parameters for query frontend: query-range.split-interval - splits a long query into multiple short queries to improve query time. Default=24h. query-frontend.log-queries-longer-than=10s - log queries running longer than 10s, which helps to identify new querries, which should be improved) query-frontend.compress-responses - compress HTTP responses, helps with query time query-range.response-cache-config - cahcing is common solution to speed up response time(https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/)","s":"Query Frontend","u":"/docs/operating-scs/components/monitoring/docs/tuning","h":"#query-frontend","p":2145},{"i":2150,"t":"compactor: retentionResolutionRaw: 2d retentionResolution5m: 10d retentionResolution1h: 15d extraFlags: - --compact.concurrency=3 - --downsample.concurrency=3 Notes on the parameters for compactor: retentionResolutionRaw - how long to retain raw samples in bucket. Minimum is two days, because just after 40 hours 5m downsampled data are created. retentionResolution5m - how long to retain samples of resolution 1 (5 minutes) in bucket. Setting this to 0d will retain samples of this resolution forever. One hour downsampled data are created only after 10 days, so this is minimum if you want also 1h downsampled data. retentionResolution1h - how long to retain samples of resolution 2 hour) in bucket. delete-delay - make sure you have set this parameter. It is time before a block marked for deletion is deleted from bucket. Note that deleting blocks immediately can cause query failures, if store gateway still has the block loaded, or compactor is ignoring the deletion because it's compacting the block at the same time. Default=48h. compact.concurrency - number of goroutines to use when compacting groups(https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/). Default=1. downsample.concurrency - number of goroutines to use when downsampling block(https://zapier.com/blog/five-recommendations-when-running-thanos-and-prometheus/). Default=1.","s":"Compactor","u":"/docs/operating-scs/components/monitoring/docs/tuning","h":"#compactor","p":2145},{"i":2152,"t":"query: extraFlags: - --query.auto-downsampling - --query.replica-label=prometheus_replica Notes on the parameters for query: query.auto-downsampling - enable automatic adjustment (step / 5) to what source of data should be used in store gateways if no max_source_resolution param is specified. Default step for range queries is equal to 1s and it is only used when step is not set in UI. Can be changed by setting --query.default-step parameter. Hovewer, when you are using Grafana as your UI, the step is taken from min_step. The preferred options is to set HTTP URL/FORM parameter max_source_resolution to auto, which selects downsample resolution automatically based on the query. query.replica-label - labels to treat as a replica indicator along which data is deduplicated.","s":"Query","u":"/docs/operating-scs/components/monitoring/docs/tuning","h":"#query","p":2145},{"i":2154,"t":"This repository aims to build an Observer monitoring solution intended to offer a global metrics view of the CSP infrastructure. It is the platform where CSP infrastructure metrics are fetched, processed, stored, and visualized. Note that this monitoring solution could be extended, and the other two observability signals (logs and traces) from the CSP infrastructure could also be processed here. The Observer monitoring solution is developed on the foundation of the dNation monitoring solution. and it is intended to become an SCS product. This repository includes the manifest for the stable deployment of the Observer monitoring solution, as well as experimental and illustrative examples of how this monitoring solution can be extended and utilized. The stable version of the Observer monitoring solution empowers its reference SCS installation available at https://monitoring.scs.community. This deployment covers the monitoring of core SCS infrastructure services, subsequently referred to as 'Monitoring of infrastructure services'. Refer to the details here. The high-level architecture could be visualized as follows: Some illustrative and experimental examples of how this monitoring solution can be utilized have been introduced within the MVP-0 version of this project (refer to the mvp-0 tag, related comments, and docs sections: kaas, iaas). These examples include: Monitoring of the KaaS layer Monitoring of the IaaS layer The above experimental components are not part of the reference SCS installation available at https://monitoring.scs.community. The high-level architecture of these experimental components could be visualized as follows:","s":"Overview","u":"/docs/operating-scs/components/monitoring/docs/overview","h":"","p":2153},{"i":2156,"t":"This represents a part of the decision process related to the overall structure the API wants to represent. Color meaning: Blue: Existing structure Red: Deprecated / removed Green: New","s":"Component Overview","u":"/docs/operating-scs/components/status-page/docs/component_overview","h":"","p":2155},{"i":2158,"t":"This page contains instructions on how to enable the Zuul monitoring in the Observer solution. Zuul comes with support for the statsd protocol, hence the graphite instance is needed when we want directly consume Zuul metrics. Graphite deployment: helm add repo kiwigrid https://kiwigrid.github.io helm upgrade --install graphite kiwigrid/graphite -f zuul/values-zuul.yaml A UDP load balancer that exposes the Graphite receiver service: kubectl apply -f zuul/udp-lb-service.yaml Zuul dashboards: kubectl apply -f zuul/zuul-status-dashboard.yaml kubectl apply -f zuul/zuul-nodepool-dashboard.yaml kubectl create -f zuul/zuul-zookeeper-dashboard.yaml Find and uncomment a related section in values-observer.yaml if you want to link the above dashboards to the L1 Zuul host dashboard. The sections related to Zuul in the values-observer-scs.yaml values file are already uncommented.","s":"Zuul monitoring","u":"/docs/operating-scs/components/monitoring/docs/zuul","h":"","p":2157},{"i":2160,"t":"Illustrating multiple interchangable logical \"layers\" of possible Status Page application stacks: Note that not everything that is shown here, actually exists or was tested. It is just shown for illustration purposes.","s":"Components","u":"/docs/operating-scs/components/status-page/docs/components","h":"","p":2159},{"i":2162,"t":"Service providers often times want to communicate the status of their systems transparently to their users. A commonly used pattern is to provide a \"status page\" web application, where the current system health as well as recent incidents are made available. SCS strives to implement a status page that works well, while being interoperable with other systems. note How was the decision to implement a new status page application made? What were the requirements? See the decision record. To be easily interoperable with other software, being \"API-first\" is a priority. As such, the status page should not need to be a typical monolithic web application (even though it could be), hence making it possible to split functionality into an API server and a frontend component.","s":"Overview","u":"/docs/operating-scs/components/status-page/docs/overview","h":"","p":2161},{"i":2164,"t":"The SCS status page API (as opposed to actual implementations) is supposed to be as un-opinionated as possible regarding deployment, user management, persistence and tech stack, to allow operators/developers (1) to make their own decisions regarding these topics and (2) to quickly implement the API with their own tech stack opinions, if the reference implementation does not fit theirs. In particular, the API has no opinion about: How authentication/authorization is done (apart from splitting Read-only from Read-write 1; See below) Server implementation, used database, deployment automation, high availability However, as un-opinionated the API (in its first iteration) strives to be, it is...: a REST API (no GRPC/GraphQL/...) defined using an OpenAPI file to make use of OpenAPI tooling split in two parts 1: Read-only anonymous access Read-write authenticated access","s":"The SCS status page API","u":"/docs/operating-scs/components/status-page/docs/overview","h":"#the-scs-status-page-api","p":2161},{"i":2166,"t":"It is envisioned to have a well-maintained reference implementation of the status page API with some basic tech stack decisions made, to not require anyone to implement the API themselves: Programming Language: Go Persistence: Postgres compatible database","s":"Reference implementation","u":"/docs/operating-scs/components/status-page/docs/overview","h":"#reference-implementation","p":2161},{"i":2168,"t":"The SCS status page frontend is supposed to be an application which uses the status page API to get information. This could be an CLI tool as well as an web application.","s":"The SCS status page frontend","u":"/docs/operating-scs/components/status-page/docs/overview","h":"#the-scs-status-page-frontend","p":2161},{"i":2170,"t":"It is envisioned to have a well-maintained reference implementation of an status page frontend with some basic tech stack decisions made: Platform: Web (HTML/JS/...) Framework: VueJS, Vuetify Footnotes​ In the future ↩ ↩2","s":"Reference implementation","u":"/docs/operating-scs/components/status-page/docs/overview","h":"#reference-implementation-1","p":2161},{"i":2172,"t":"In the future ↩ ↩2","s":"Footnotes","u":"/docs/operating-scs/components/status-page/docs/overview","h":"#footnote-label","p":2161},{"i":2174,"t":"TODO","s":"Overview","u":"/docs/operating-scs/incident-management/","h":"","p":2173},{"i":2176,"t":"When implementing any system to be used by a group of potential users, there will be varying use cases and opinions about API's, programming languages, persistence models, authentication, authorization, deployment options and so on. Hence, building a complete one-fits-all solution is difficult, but (while offering a pretty un-opinionated reference implementation) even finding consensus on a few basic concepts may make adaptation and integration of different solutions possible. The \"levels\" of consensus could be split into: Consensus on... Resource Definition \"What is an incident?\" Core REST API Spec General Architecture \"Monolithic Web App or multiple components?\" \"Use static password file or rely on OIDC provider?\" (If any:) Interfaces between components: AuthN mechanisms AuthZ decisions Implementation of core component(s) \"Use reference implementation components?\" \"Go vs. JavaScript?\" \"Postgres vs. MySQL?\" Choice of all used components \"Policy: Istio vs. traefik?\" \"Deployment: Helm vs. ansible?\" \"dex vs. keycloak vs. zitadel?\" Every user of the Status Page (API) should be able to either make full use of the full reference implementation, building little to none on their own; Or just pick core concepts/API's/automation and build partial compatibility. E.g. while the value on agreeing on every aspect would bring the most value, this most likely is not likely to happen, but adopting only the \"Resource Definition\", should ideally bring value already.","s":"\"Levels of consensus\"","u":"/docs/operating-scs/components/status-page/docs/levels_of_consensus","h":"","p":2175},{"i":2178,"t":"TODO","s":"Overview","u":"/docs/operating-scs/lifecycle-management/","h":"","p":2177},{"i":2180,"t":"TODO","s":"Overview","u":"/docs/operating-scs/logging/","h":"","p":2179},{"i":2182,"t":"TODO","s":"Overview","u":"/docs/operating-scs/monitoring/","h":"","p":2181},{"i":2184,"t":"TODO","s":"Overview","u":"/docs/operating-scs/overview","h":"","p":2183},{"i":2186,"t":"(Release Date: 2021-07-15)","s":"Release Notes for SCS Release 0","u":"/docs/releases/Release0","h":"","p":2185},{"i":2188,"t":"The main focus of R0 is to demonstrate the viability of our approach to a much broader audience by providing a well-documented testbed. This will allow anyone interested to study the system in real-life, test, contribute, compare, ... it. Also we learn performing the release process.","s":"Scope","u":"/docs/releases/Release0","h":"#scope","p":2185},{"i":2190,"t":"Fully automated virtual (testbed setup) with ansible (terraform bootstrap to create storage, networking and VM resources for bootstrapping via cloud-init injected scripts that call ansible).) The infrastructure, management and openstack services are all deployed in containers. Included tools for Operations: ARA, Netbox, Cockpit, Netdata, Skydive (opt-in), Patchman, phpMyAdmin, Elasticsearch (b/f license change), Kibana, Grafana, influxdb Validation: Rally, Refstack Infrastructure: Linux, KVM, ceph (pacific), OpenVSwitch, OVN, MariaDB, RabbitMQ, Redis, Etcd, HAproxy, Keepalived, Memcached, Keycloak IaaS (OpenStack - Wallaby): keystone, nova, glance, cinder, neutron, octavia, horizon Optional OpenStack services: designate, heat, gnocchi, ceilometer, aodh, panko, senlin, barbican, manila, magnum See testbed SBOM for a complete list. The exact versions of the contained components can be retrieved from the release repo of OSISM.","s":"Features","u":"/docs/releases/Release0","h":"#features","p":2185},{"i":2192,"t":"See main README.","s":"Get SCS","u":"/docs/releases/Release0","h":"#get-scs","p":2185},{"i":2194,"t":"Nothing major known yet.","s":"Known Bugs","u":"/docs/releases/Release0","h":"#known-bugs","p":2185},{"i":2196,"t":"While already in productive use (on bare metal) by two providers, the bare metal setup currently has a few more manual steps than we would like. This will improve with the next releases. We have worked hard on supporting identity federation (OIDC and SAML) during the last few months. We have also spent significant effort on getting the k8s stack with k8s cluster API into a good shape. However, we have determined that we do not yet consider those two key pieces as production-ready. The goal is to change that for R1 (see below). For now, you can use the software to see where SCS is going and test our technical preview code. We really appreciate feedback we get on these pieces as well. However keep in mind that we do not guarantee to ship technical previews from a Release as production-ready software in one of the next releases. We certainly hope to do so. To test how our k8s aaS platform will look like, have a look at the k8s-cluster-api-provider repository You can follow the documentation to set up the k8s cluster API on an SCS cloud (or other well configured OpenStack clouds that support octavia). The openstack-health-monitor is used by us to monitor that the API works and successfully creates working resources in finite time. We plan to integrate it with a dashboard and an alarming mechanism in the next releases.","s":"Technical Previews","u":"/docs/releases/Release0","h":"#technical-previews","p":2185},{"i":2198,"t":"See Release Numbering scheme. The containers have version number v1.0.0 for R0.","s":"Release tagging","u":"/docs/releases/Release0","h":"#release-tagging","p":2185},{"i":2200,"t":"Updating the software can conveniently be done from the manager node by running the ansible playbooks again. Details are in the OSISM testbed documentation.","s":"Updates","u":"/docs/releases/Release0","h":"#updates","p":2185},{"i":2202,"t":"See main README file.","s":"Bug reporting","u":"/docs/releases/Release0","h":"#bug-reporting","p":2185},{"i":2204,"t":"(Release Date: 2021-09-29)","s":"Release Notes for SCS Release 1","u":"/docs/releases/Release1","h":"","p":2203},{"i":2206,"t":"Main goals for Release 1 (R1) was the strengthening of our CI test coverage and integration, the operational tooling (metrics collection, dashboards, logging), latest versions of upstream software (OpenStack Wallaby, Kubernetes-1.21.5), support for Bare Metal service, progress on user federation for clouds, and progress on the integration of the container layer with k8s Cluster API (now in version 0.4.x).","s":"Scope","u":"/docs/releases/Release1","h":"#scope","p":2203},{"i":2209,"t":"For our internal development workflows we are planning to switch from GitHub Actions to Zuul-CI (mostly). The infrastructure itself is already available, yet most of the repositories in the SovereignCloudStack organisation have not switched over. Reasons for switching include cross-dependencies, scalability and costs. Reasons for using Zuul-CI include the close connection to the OpenStack project and the enormous flexibility in comparison to other similar tools. On top of that you have also gating instead of only CI. A quick example for a Zuul-CI operated repository can be found here: https://github.com/SovereignCloudStack/zuul-sandbox.","s":"Zuul-CI","u":"/docs/releases/Release1","h":"#zuul-ci","p":2203},{"i":2212,"t":"We provide generic configuration examples and blueprints for prometheus rules and grafana dashboards. The examples need to be understood and adapted to the particular needs of your environment. You can find the examples at https://github.com/osism/kolla-operations]. With R2 we plan to implement a basic set of these alerts and dashboards in the testbed deployment in order to make them even easier consumable for new users. Feel free to give feedback on the examples and contribute your own generic examples. We're working on bringing a basic set of prometheus exporters to the OpenStack-kolla upstream community. As part of our effort to add more monitoring tooling, we're integrating further prometheus exporters such as libvirt and ovn. Integration is targeted for R2. More detailed information on monitoring topics will be continously provided in the corresponding design document.","s":"Prometheus exporters and Grafana dashboards","u":"/docs/releases/Release1","h":"#prometheus-exporters-and-grafana-dashboards","p":2203},{"i":2214,"t":"We have made some progress with openstack-health-monitor since R0, but we have not yet created ready-to-be-used influx data collection and the grafana dashboard. While the black box monitoring is perceived as very useful, the script certainly has reached a complexity that is not handled well with bash scripting and makes it a difficult to maintain and even to use tool, so the usefulness of shipping it with SCS to make it available for Ops teams to monitor has been questioned. Instead an expectation has been expressed that the SCS uses this to monitor all SCS partner clouds and provides some transparency this way to the public -- and detailed statistics via e.g. a prometheus exporter to the respective cloud provider. This is currently under consideration.","s":"openstack-health-monitor","u":"/docs/releases/Release1","h":"#openstack-health-monitor","p":2203},{"i":2217,"t":"OSISM now enables kolla-ansible centralized logging by default. The default rules need to be further refined to suit your needs. We plan to implement a more generic set of rules for R2.","s":"Central logging","u":"/docs/releases/Release1","h":"#central-logging","p":2203},{"i":2220,"t":"Logging in to Horizon by authenticating with OIDC via Keycloak is now possible. For details see the testbed documentation.","s":"OIDC support via keycloak","u":"/docs/releases/Release1","h":"#oidc-support-via-keycloak","p":2203},{"i":2222,"t":"Only TLS secured deployments get full support. Without TLS, certain browsers won't be able to log in. For deatils see the testbed documentation","s":"non-TLS restrictions (testbed)","u":"/docs/releases/Release1","h":"#non-tls-restrictions-testbed","p":2203},{"i":2224,"t":"Clicking Sign Out on the Horizon dashboard doesn't perform a proper OIDC logout. This is documented in osism testbed, with some Keycloak settings that can be relevant for alleviating the issue, but in Release 1 there is no solution for this yet.","s":"Known Issue with OIDC Logout","u":"/docs/releases/Release1","h":"#known-issue-with-oidc-logout","p":2203},{"i":2226,"t":"The ironic Bare Metal service can be deployed with the SCS (OSISM) installation. For it to get full test coverage, a virtual BMC solution has been created, so bare metal can be validated in our testbed setup just as nicely as the other components. While most pieces are ready, the final integration steps are still work-in-progress and will happen after R1.","s":"Bare Metal Service","u":"/docs/releases/Release1","h":"#bare-metal-service","p":2203},{"i":2229,"t":"The container layer on SCS is implemented as a Self-Service, leveraging the Kubernetes cluster API technology. This was provided as a technical preview from the SCS k8s-cluster-api-provider repository for R0 back in July. The focus for R1 was to make it ready for production, so DevOps teams can use this to create and manage their k8s clusters in self-service for development, testing, deployment and production. To achieve this, a lot of work has been invested, updating the cluster API to 0.4 along the way, fixing snapshot classes, enabling optional metrics and ingress services, using application credentials and much improved management scripts. The sonobuoy test automation has been included and successfully used to validate the created clusters. Real-world testing has happened though the Gaia-X Hackathon #1, where clusters were provided on the fly for the various work streams. The detailed list of changes for R1 is covered in the k8s capi provider Release Notes. Still in technical preview, but very promising are the helm charts based k8s cluster management templates also documented there.","s":"Overview and Goals for R1","u":"/docs/releases/Release1","h":"#overview-and-goals-for-r1","p":2203},{"i":2231,"t":"Some of our partners are using Gardener as a layer to manage large fleets of (optionally cross-cloud) k8s clusters. While there is a bit of overlap in functionality, they do happily coexist and our partner is actually using k8s capi to bootstrap clusters on SCS clouds for Gardener management.","s":"Beyond CAPI","u":"/docs/releases/Release1","h":"#beyond-capi","p":2203},{"i":2233,"t":"As of this writing, the list of SCS defined standards still comprises two standards: SCS Flavor naming and standard flavors standard SCS Image naming and metadata standard As before, we continue to rely on OpenStack and CNCF defined standards in addition to this -- the k8s clusters need to pass the conformance tests with sonobuoy and the OpenStack environment the OpenStack powered guidelines (with refstack). There is a discussion on a glossary, detailing what we expect from regions, availability zones etc. Some major parts of it still need to be agreed before a useful doc can be published -- this will happen in due time and is expected before R2.","s":"Standardization","u":"/docs/releases/Release1","h":"#standardization","p":2203},{"i":2235,"t":"We stand on the shoulders of giants: Without all the great work from many open source communities, we would not get anywhere. We are working on automation to create a complete list for all the software that is used and deployed with SCS, so we have a complete Software Bill of Materials (SBoM). The reason this is non-trivial is that we are not aggregating it all ourselves, but rely on pre-integrated pieces, such as Linux distributions, OpenStack, CNCF projects etc. The good news is that these projects are diligent in their work, making sure we don't need to be too worried about security risks or legal risks introduced this way. Nevertheless, the goal of creating a complete graph remains. We have started to put SPDX license identifiers into the SCS produced code, so we make it easier for downstream consumers of our software to automate the license compliance checks when assembling an SBoM. For R1, some of the major projects we build on have had releases that we incorporated and whose release notes we want to link here for convenience: Kubernetes v1.21.x Kubernetes Cluster API v0.4 and k8s cluster-api-provider openstack v0.4 OpenStack Wallaby Release Highlights","s":"SBOM and Links","u":"/docs/releases/Release1","h":"#sbom-and-links","p":2203},{"i":2237,"t":"See Release Numbering scheme -- unchanged from R0. We have added the tag v2.0.0 to the relevant repositories to designate the SCS_RELEASE_R1.","s":"Release tagging","u":"/docs/releases/Release1","h":"#release-tagging","p":2203},{"i":2239,"t":"OIDC Logout doesn't work properly. OIDC Login is meant to be used with TLS, on non-TLS setups it only works with restrictions.","s":"List of known issues & restrictions in R1","u":"/docs/releases/Release1","h":"#list-of-known-issues--restrictions-in-r1","p":2203},{"i":2241,"t":"(Release Date: 2022-03-23)","s":"Release Notes for SCS Release 2","u":"/docs/releases/Release2","h":"","p":2240},{"i":2243,"t":"Main goals for Release 2 (R2) were massive improvements in bare metal deployment and our cluster management layer gaining the ability to handle many clusters independently with a number of optional services.","s":"Scope","u":"/docs/releases/Release2","h":"#scope","p":2240},{"i":2245,"t":"We support the latest Kubernetes 1.22 and 1.23 releases. The Kubernetes Cluster API is now available in a stable v1beta1 release 1.0.x with the corresponding cluster-api-provider-openstack 0.5.x. There are a number of new standard services available for the k8s capi managed clusters, amongst which cert-manager and flux. The clusters have better default settings for the nginx-ingress, anti-affinity for the nodes and the ability to chose cilium over calico and to have stable multi-controller node setups on clouds without low-latency local storage. Please consult the k8s capi provider release notes for more details. OpenStack Xena release We have also enabled SPICE support in addition to noVNC to access the graphical console of VMs. The base infrastructure is provided by OSISM 3.0.0 which in turn build on top of kolla and kolla-ansible.","s":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release2","h":"#component-versions-and-user-visible-improvements-highlights","p":2240},{"i":2248,"t":"The Cluster Management Node is now well prepared to manage numerous clusters with independent settings and different feature sets by creating default settings and then keeping track of various workload clusters in own directories. Documentation has been vastly improved. The Cluster Management node now gets its artifacts directly from git, making incremental updates to it a lot easier, thus also avoiding to disrupt workload clusters through redeployed management nodes to roll out updates. Added dashboards for the operators: Homer Flower Grafana dashboards Work is underway to supersede openstack-health-monitor with a solution that is using tempest and rally. The health-monitor has received improvements though and is at this point still fully supported and recommended -- it has surfaced a number of issues with test clouds, especially failed metadata services. User federation has been prepared to be ready for Gaia-X federation integration Keystone can consume users from Keycloak via OpenID-Connect Keycloak uses the highly-available Galera database cluster now mod_oauth2 support for Keystone Vast improvements in the SCS Deployment automation Full automation of bare metal deployment with Bifrost and Ironic Using NetBox as central source of truth for the complete setup New services available (opt-in) ClamAV, dnsdist, cgit, FRRouting, Nexus, Tang Traefik centrally routes the connections to Nexus, NetBox, phpMyAdmin, Homer, Flower, ARA, cgit","s":"Operator focused improvements","u":"/docs/releases/Release2","h":"#operator-focused-improvements","p":2240},{"i":2250,"t":"We now have scripts that allow us to connect to the workload cluster node network for debugging purposes. The configuration of the testbed was minimized and the deployment was made more production-oriented. Further noteworthy improvements to testbed: TLS is implemented throughout the services also in testbed Virtual BMC in testbed Public DNS for testbed (testbed.osism.xyz) We have a Zuul CI framework running and started migrating CI testing from github actions to using our Zuul infrastructure. Renovate is being used to keep the pinned versions up-to-date and consistent across the many repositories. An overview over the used software versions is available from the OSISM release repository as input for a complete SBOM. This allows to e.g. investigate the contents of the used (v3.0.0) images.","s":"SCS Developer focused improvements (testbed)","u":"/docs/releases/Release2","h":"#scs-developer-focused-improvements-testbed","p":2240},{"i":2253,"t":"The names of a few settings have changed since R1 -- if you have diverged from the defaults, this may require adjusting the environment.tfvars or the clusterctl.yaml files. See k8s-cluster-api-provider Release Notes for more details. The updating approach has fundamentally changed: If you were used to deploy fresh management nodes regularly to benefit from the upstream improvements, this need has been vastly reduced now, allowing for long-living management nodes and workload clusters managed by them.","s":"Cluster Management","u":"/docs/releases/Release2","h":"#cluster-management","p":2240},{"i":2255,"t":"Playbook generic-configuration.yml was deprecated. From now on, please use the playbook of the same name in the manager environment (manager-configuration.yml). All configuration parameters from environments/configuration.yml should be moved to environments/manager/configuration.yml. In kolla-ansible the haproxy role was renamed to loadbalancer. Accordingly, loadbalancer must now be used for the deployment of HAProxy.","s":"OSISM","u":"/docs/releases/Release2","h":"#osism","p":2240},{"i":2257,"t":"OpenStack Victoria images are no longer built and thus no longer kept updated Support for Zabbix has been removed, Prometheus will be used as the only monitoring stack in the future Heimdall as a service was removed, as an alternative Homer is now available","s":"Removals","u":"/docs/releases/Release2","h":"#removals","p":2240},{"i":2259,"t":"Deprecations happen according to our deprecation policy. Cockpit is deprecated in favor of Boundary by HashiCorp or Teleport ceph-ansible is deprecated in preparation for cephadm All osism- scripts on the manager are deprecated and will be replaced by the new OSISM CLI. The scripts will be removed in the next release The following services are currently not used and are deprecated and scheduled for removal as of now: Falco, Jenkins, Rundeck, Lynis, Trivy Heat will no longer be offered by default in the testbed in the future The docker-compose CLI will be removed and replaced by the new compose plugin for Docker. docker-compose is then no longer available and docker compose must be used instead","s":"Deprecations","u":"/docs/releases/Release2","h":"#deprecations","p":2240},{"i":2261,"t":"The Elasticsearch container included in OSISM testbed was exposed to the log4j issue -- new images were provided for addressing this. See the security advisory","s":"Security Fixes","u":"/docs/releases/Release2","h":"#security-fixes","p":2240},{"i":2263,"t":"The nginx-ingress loadbalancer could run into name conflicts before. The loadbalancer now uses a health monitor to avoid routing to the wrong nodes, which typically resulted in 10s delays when connecting to the service behind the ingress controller. cAdvisor has now reduced number of Prometheus metrics and labels exported by default - this will ease the load on the system. This implies that corresponding time series data will no longer be created.","s":"Resolved Issues","u":"/docs/releases/Release2","h":"#resolved-issues","p":2240},{"i":2265,"t":"The clusters created with our cluster-API cluster management solution pass the CNCF conformance tests as reported by sonobuoy. The OpenStack layer passes the OIF trademark tests, so cloud providers leveraging the stack should easily be able to achieve the \"OpenStack powered compute\" trademark certification. Our partner plusserver has achieved a BSI C5 security certification for their SCS implementation pluscloud open. We are working within Gaia-X to further the power of Gaia-X self-descriptions and are closely working with the GXFS project to jointly deliver a standard toolbox for Gaia-X compliant infrastructure and service offerings. The SCS standards for flavor naming and image metadata are largely unchanged since R1. We have however made progress in our reference implementation fully implementing them without any further tweaks.","s":"Standards Conformance","u":"/docs/releases/Release2","h":"#standards-conformance","p":2240},{"i":2267,"t":"See Release Numbering scheme -- unchanged from R0. We have added the tag v3.0.0 to the relevant repositories to designate the SCS_RELEASE_R2. Note that we will release R3 (v4.0.0) in September 2022 and stop providing maintenance updates for R2 at the end of October.","s":"Release Tagging","u":"/docs/releases/Release2","h":"#release-tagging","p":2240},{"i":2270,"t":"Alongside with R2 we published a blog post on some first thoughts on future directions towards R3.","s":"Future directions (selected Highlights)","u":"/docs/releases/Release2","h":"#future-directions-selected-highlights","p":2240},{"i":2272,"t":"We appreciate contribution to strategy and implementation, please join our community -- or just leave input on the github issues and PRs. Have a look at our contributor guide. We also have worked on a Code of Conduct to document the expected behavior of contributors and how we deal with cases where individuals fail to meet the expectation.","s":"Contributing","u":"/docs/releases/Release2","h":"#contributing","p":2240},{"i":2274,"t":"(Release Date: 2022-09-21)","s":"Release Notes for SCS Release 3","u":"/docs/releases/Release3","h":"","p":2273},{"i":2276,"t":"Main goals for Release 3 (R3) were user federation, increase in deployment and upgrade velocity by improving automated test coverage as well as bringing disk encryption based on tang from the state of a technical preview to be fully supported.","s":"Scope","u":"/docs/releases/Release3","h":"#scope","p":2273},{"i":2278,"t":"We support the latest Kubernetes 1.25 releases. The Kubernetes Cluster API is now available in a stable v1beta1 release 1.2.x with the corresponding cluster-api-provider-openstack 0.6.x. The Kubernetes Cluster API cluster management service has seen major managability improvements. Please consult the k8s cluster api provider release notes for more details. OpenStack Yoga release Ceph Quincy is available, the default release of Ceph is still Pacific. The base infrastructure is provided by OSISM 4.0.0 which in turn builds on top of kolla and kolla-ansible. Disk encryption based on Network bound disk encryption (NBDE) is available.","s":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release3","h":"#component-versions-and-user-visible-improvements-highlights","p":2273},{"i":2281,"t":"Work is underway to supersede openstack-health-monitor with a comprehensive approach using scenarios with ansible playbooks that has been developed and used by T-Systems for their Open Telekom Cloud. Meanwhile, openstack-health-monitor has seen the addition of data collection with telegraf and influxdb as well as a good dashboard with grafana. We have used our keystone to keycloak federation to use keycloak as identity broker to federate identities from other (SCS) clouds' keycloaks. This works well for the Web-Interface; we have still some work to do to also make it smooth also for API/CLI usage. We have documented the current status We believe that Gaia-X self-descriptions should also contain a description of technical properties of services; higher-level services and workloads can than declare their requirements and be matched against lower level services / platforms. In good platforms, most (or all) technical properties are discoverable. In the Gaia-X Hackathon #4, we have worked on a demonstrator that characterizes some aspects of an OpenStack-based IaaS platform and which produces self-descriptions that can be submitted to the Gaia-X trust service, pass the tests and you can be awared a verifiable credential. Code is available in the gx-self-description-generator repo","s":"Operator focused improvements","u":"/docs/releases/Release3","h":"#operator-focused-improvements","p":2273},{"i":2283,"t":"Following significant discussions on how to standardize our cluster management solution, there is a draft concept as part of R3 now, which will be further worked on during the R4 cycle. See Cluster standardization section of the release notes from k8s-cluster-api-provider. While our reference implementation uses the concepts and code from k8s cluster API on top of our SCS reference implementation (OpenStack automated by OSISM), we want to assure that non-OpenStack IaaS and solutions that diverge from cluster-API have the possibility to be SCS compliant. Workload clusters managed by our SCS cluster management solutions can now much more easily receive k8s version upgrades, as the cluster-template no longer needs to be touched for this. There is an Upgrade Guide available now. LUKS encryption is now documented and enabled in the testbed by default. Further noteworthy improvements to testbed: Public DNS for testbed is now available (testbed.osism.xyz), allowing to access services via TLS protected by a wildcard CA certificate. The wireguard VPN service is deployed in the testbed by default. An overview over the used software versions is available from the OSISM release repository as input for a complete SBOM. This allows to e.g. investigate the contents of the used (v4.0.0) images.","s":"SCS Developer focused improvements (testbed and k8s cluster management)","u":"/docs/releases/Release3","h":"#scs-developer-focused-improvements-testbed-and-k8s-cluster-management","p":2273},{"i":2286,"t":"Upgrade from R2 to R3 for cluster management and clusters: See k8s-cluster-api-provider Release Notes for more details. There is an Upgrade Guide written specifically to address the steps needed for upgrading your cluster management and the workload clusters.","s":"Cluster Management","u":"/docs/releases/Release3","h":"#cluster-management","p":2273},{"i":2288,"t":"In environments/kolla/secrets.yml the parameter neutron_ssh_key must be added. neutron_ssh_key: private_key: public_key: The ssh key can be generated as follows: ssh-keygen -t rsa -b 4096 -N \"\" -f id_rsa.neutron -C \"\" -m PEM","s":"OSISM","u":"/docs/releases/Release3","h":"#osism","p":2273},{"i":2290,"t":"The Cockpit service has been removed.","s":"Removals","u":"/docs/releases/Release3","h":"#removals","p":2273},{"i":2292,"t":"Deprecations happen according to our deprecation policy. Linux bridge support has been deprecated by the Neutron team and marked as experimental. If Linux bridge is used in deployments, migrating to OpenVSwitch is recommended. Debian dropped hddtemp (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1002484), therefore the hddtemp service will be removed from the next OSISM release, as there is no package available for Ubuntu 22.04. Heat will no longer be offered by default in the testbed in the future The following services are currently not used and are deprecated and scheduled for removal as of now: Falco, Jenkins, Rundeck, Lynis, Trivy The docker-compose CLI will be removed and replaced by the new compose plugin for Docker. docker-compose is then no longer available and docker compose must be used instead The cleanup-elasticsearch playbook is deprecated. In the future, the elasticsearch-curator service (part of Kolla) has to be used for Elasticsearch cleanup. All osism- scripts on the manager are deprecated and will be replaced by the new OSISM CLI. The scripts will be removed in the next release","s":"Deprecations","u":"/docs/releases/Release3","h":"#deprecations","p":2273},{"i":2294,"t":"No severe security issues need to be highlighted since Release 2. However, by updating to the latest stable version of the integrated open source components, we benefit from the upstream security fixes and thus recommend to upgrade all SCS environments. Please note that Release 2 maintenance by the SCS project team will end by the end of October.","s":"Security Fixes","u":"/docs/releases/Release3","h":"#security-fixes","p":2273},{"i":2296,"t":"Certificates in k8s clusters are subject to expiration - typically after one year. We ensure these are renewed on control-plane upgrades, but operators may need manual attention in case upgrades are not performed for extended periods of time. This is documented in the k8s-cluster-api-provider's Maintenance and Troubleshooting Guide.","s":"Resolved Issues","u":"/docs/releases/Release3","h":"#resolved-issues","p":2273},{"i":2298,"t":"The clusters created with our cluster-API cluster management solution pass the CNCF conformance tests as reported by sonobuoy. The OpenStack layer passes the OIF trademark tests, so cloud providers leveraging the stack should easily be able to achieve the \"OpenStack powered compute\" trademark certification. Our partner plusserver has achieved a BSI C5 security certification for their SCS implementation pluscloud open. We are working within Gaia-X to further the power of Gaia-X self-descriptions and are closely working with the GXFS project to jointly deliver a standard toolbox for Gaia-X compliant infrastructure and service offerings. The SCS standards for flavor naming and image metadata are largely unchanged since R1. We have however made progress in our reference implementation fully implementing them without any further tweaks. The conformance test for the flavor naming has seen minor improvements; a conformance test for the image metadata has been added.","s":"Standards Conformance","u":"/docs/releases/Release3","h":"#standards-conformance","p":2273},{"i":2300,"t":"See Release Numbering scheme -- unchanged from R0. We have added the tag v4.0.0 to the relevant repositories to designate the SCS_RELEASE_R3. Note that we will release R4 (v5.0.0) in March 2023 and stop providing maintenance updates for R3 at the end of April 2023.","s":"Release Tagging","u":"/docs/releases/Release3","h":"#release-tagging","p":2273},{"i":2302,"t":"Distributed Virtual Routing (DVR) is not officially supported by OSISM, not tested and not recommended.","s":"List of known issues & restrictions in R3","u":"/docs/releases/Release3","h":"#list-of-known-issues--restrictions-in-r3","p":2273},{"i":2304,"t":"We appreciate contribution to strategy and implementation, please join our community -- or just leave input on the github issues and PRs. Have a look at our How to contribute page.","s":"Contributing","u":"/docs/releases/Release3","h":"#contributing","p":2273},{"i":2306,"t":"The work for R3 has been done by many contributors from our community. We have not collected detailed stats that would split out the individual contributor's and companies shares ... we may do so in the future. We are grateful to have such an active and engaged community that has done so much work! Thanks to our contributors! Of course we are leveraging a huge amount of open source technology that has been created by our friends in other communities, many of which are part of the CNCF, Linux Foudation, OIF, and others. We participate and contribute where we can and definitely want to acknowledge the great work that we build upon.","s":"Thanks","u":"/docs/releases/Release3","h":"#thanks","p":2273},{"i":2308,"t":"(Release Date: 2023-03-22)","s":"Release Notes for SCS Release 4","u":"/docs/releases/Release4","h":"","p":2307},{"i":2310,"t":"Release 4 has been developed alongside a set of associated outcomes. These outcomes are comprised of: SCS is standardized SCS is federated SCS is continuously built and tested SCS is understandable SCS enables Operators with an excellent toolbox The SCS project is completely developed in the open, based on the principles of the four opens. Due to this a lot of our work can be tracked and used continuously without waiting for the half-year releases. Especially, but not limited to, this includes our efforts in regards to documentation and our standards. One of the major highlights that happened in the R4 development cycle is our work on assuring SCS is understandable. Be sure to look at our new documentation entry point. We have created a systematic approach to structure documentation which already has been implemented for the OpenStack Image Manager, the OSISM testbed and the K8s Cluster API Provider. More will follow in a continuous manner. Our community has created a growing amount of blog articles which also help to understand the SCS project, its community and the technology that is worked on.","s":"Scope","u":"/docs/releases/Release4","h":"#scope","p":2307},{"i":2312,"t":"OpenStack Zed release Ceph Quincy is available, the default release of Ceph is still Pacific. The base infrastructure is provided by OSISM 5.0.0 which in turn builds on top of kolla and kolla-ansible. With Cloud-in-a-Box there is an easy way to get SCS up and running on a single hardware node as a test environment. There are two blog posts (part 1 and part2) covering it. For new deployments of the IaaS reference implementation Ubuntu 22.04 is recommended while existing installations can be upgraded to R4 while staying on Ubuntu 20.04. With Release 5, upgrading to Ubuntu 22.04 will be required. With osism/node-image an iso image for much easier bootstrapping of new OSISM environments is available now The software for our Kubernetes Cluster-API reference implementation has been updated and highlights are covered in own release notes.","s":"Component Versions and User-visible improvements (highlights)","u":"/docs/releases/Release4","h":"#component-versions-and-user-visible-improvements-highlights","p":2307},{"i":2315,"t":"The Openstack Image Manager has seen many improvements and is the reference command to assure the images available comply with the SCS Image Standard For Ceph, special playbooks were added to validate the deployment status of the OSD, MON and MGR services in OSISM. The commands for use are osism validate ceph-osds, osism validate ceph-mons, and osism validate ceph-mgrs. OVN has been updated to version 22.09. OVS has been updated to version 3.0.1. The testbed uses per default a proxy for container pulling. This will allow for airgapped installations out of the box. Please note: a full airgap support (with local mirrors, etc.) will follow in a future release. The efforts to create a well-maintained status page with well-defined interfaces resulted in an OpenAPI specification (within its own repository) which is intended to be implementable by multiple implementations. The dashboard of the OpenStack Health Monitor is in use by the SCS operators and has proven helpful a number of times in detecting and addressing issues. That said, it only received a few fixes and minor enhancements, as we plan to replace it with a more generic and more maintainable solution soon. The k8s clusters built with our k8s-capi implementation now allow controlling the versions of more components; the latest tested and stable versions are used by default (if enabled). The latest version for the cilium CNI for example allows testing the upcoming k8s gateway API. The k8s cluster now allows filtering access to the kubernetes API by IP ranges. The k8s clusters now have the proxy protocol enabled with the nginx-ingress controller, so client IPs are visible; the previous issue that blocked internal access could be worked around.","s":"Operator focused improvements","u":"/docs/releases/Release4","h":"#operator-focused-improvements","p":2307},{"i":2317,"t":"The testbed has been significantly simplified for new operators and developers and a Quick Start guide has been added.","s":"SCS Developer focused improvements (testbed and k8s cluster management)","u":"/docs/releases/Release4","h":"#scs-developer-focused-improvements-testbed-and-k8s-cluster-management","p":2307},{"i":2319,"t":"For the IaaS reference implementation, please refer to the OSISM 5.0.0 Upgrade Notes. The k8s Cluster Management solution has an enhanced upgrade guide that covers the upgrade of clusters as well as the upgrade of the cluster management server.","s":"Upgrade/Migration notes","u":"/docs/releases/Release4","h":"#upgrademigration-notes","p":2307},{"i":2321,"t":"The ospurge wrapper script has been removed from the osism.services.openstackclient role. The ospurge project is no longer compatible with the current OpenStack SDK. The command openstack project purge can be used as an alternative. The docker-compose package is uninstalled by the osism.commons.docker_compose role. The Compose v2 plugin for Docker is now used instead of the old standalone docker-compose CLI. A dummy script has been added to /usr/local/bin which displays a corresponding message when using docker-compose. Further removals from the IaaS reference implementation, please refer to the OSISM 5.0.0 Removals Section. The k8s cluster parameter ETCD_PRIO_BOOST that was already unused has been removed as announced with R3.","s":"Removals","u":"/docs/releases/Release4","h":"#removals","p":2307},{"i":2324,"t":"For these please also refer to the upstream deprecation notices The role osism.services.bird is deprecated. In future, FRRouting (osism.services.frr) will be used. The role osism.services.minikube is deprecated. In future osism.services.k8s will be used. Heat is deprecated in favor of more generic Infrastructure as Code tools like Terraform as of now and will be removed in the future (exact removal date is not yet known) Swift (currently available as Technical Preview) will be removed in favor of Ceph RGW Trove (currently available as Technical Preview) will be removed in favor of Kubernetes database operators Skydive (currently available as Technical Preview) will be removed in the future, the project is not maintained anymore, last commit is 8th Jan 2022: https://review.opendev.org/c/openstack/kolla/+/869191 The login to a registry with the osism.services.docker role is deprecated in favor of the new osism.commons.docker_login role.","s":"Deprecations via OSISM","u":"/docs/releases/Release4","h":"#deprecations-via-osism","p":2307},{"i":2326,"t":"Throughout the Release 4 development cycle, the SCS project issued two security advisories for upstream components: In November 2022 an advisory regarding CVE-2022-3602 and CVE-2022-3786 in OpenSSL was issued. Our advisory. In February 2023 an advisory regarding CVE 2022-47951 in OpenStack components nova and glance was published. Our advisory. Fixes were delivered via maintenance updates to existing R3 deployments, but of course also included in the main development branch that became R4.","s":"Security Fixes","u":"/docs/releases/Release4","h":"#security-fixes","p":2307},{"i":2328,"t":"Breakage with old kustomize syntax has been addressed.(k8s-capi/#328) The move of k8s container images from k8s.gcr.io to registry.k8s.io needed adjustments.(k8s-capi/#321)","s":"Resolved Issues","u":"/docs/releases/Release4","h":"#resolved-issues","p":2307},{"i":2330,"t":"The last months saw intense work in the standardization area. The process how standards are created has been documented. The standards are collected in its own standards repository. A machine readable file lists the required (and optional) standards that apply to \"SCS-compatible\" conformance at the IaaS and the Container (KaaS) layer. The referenced executables are used by the compliance checking framework to test existing implementations for compliance. To run the checker, the tester needs access to the infrastructure under test (normal user privileges are sufficient) and standard openstack and kubernetes client tools -- or just use the docker container that is provided. The public clouds based on the SCS reference implementation from plusserver and Noris/Wavecon are tested automatically from us and the live result is visible in standards page. We will enhance the standardization and test coverage significantly in the next months and we hope to list a number of more clouds there soon.","s":"Standards Conformance","u":"/docs/releases/Release4","h":"#standards-conformance","p":2307},{"i":2332,"t":"The code in OSISM and a number of SCS repositories will receive the v5.0.0 tag; some repositories use maintained/v5.0.x and maintained/v5.x branches for providing code that only gets bug- and security fixes (5.0.x) or only those plus selected, backwards-compatible enhancements (5.x).","s":"Release Tagging","u":"/docs/releases/Release4","h":"#release-tagging","p":2307},{"i":2334,"t":"The k8s cluster-API code does not work well with OpenStack API endpoints that require trusting a custom CA. The OpenStack component Horizon has two issues when working with Swift endpoints. One issue is a known bug when uploading objects to Swift endpoints. A workaround will be released shortly after R4. The second issue is that existing Swift containers can not be set to public.","s":"List of known issues & restrictions in R4","u":"/docs/releases/Release4","h":"#list-of-known-issues--restrictions-in-r4","p":2307},{"i":2336,"t":"We appreciate contribution to strategy and implementation, please join our community -- or just leave input on the github issues and PRs. Have a look at our How to contribute page.","s":"Contributing","u":"/docs/releases/Release4","h":"#contributing","p":2307},{"i":2338,"t":"The work for R4 has been done by many contributors from our community. The special thanks goes out to our contributors who participate in our community on a very regular base - without these the various team calls and events like the hackathons would be much less successful and fun. Of course we are leveraging a huge amount of open source technology that has been created by our friends in other communities, many of which are part of the CNCF, Linux Foudation, OIF, and others. We participate and contribute where we can and definitely want to acknowledge the great work that we build upon.","s":"Thanks","u":"/docs/releases/Release4","h":"#thanks","p":2307},{"i":2340,"t":"Kurt Garloff, 2024-02-20","s":"Guide: Setting up openstack-health-monitor on Debian 12","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"","p":2339},{"i":2342,"t":"The development of openstack-health-monitor was done on openSUSE 15.x images, just because the author is very familiar with it and has some of the needed tools preinstalled. That said, the setup is not depending on anything specific from openSUSE and should work on every modern Linux distribution. Setting it up again in a different environment using Debian 12 images avoids a few of the shortcuts that were used and thus should be very suitable instructions to get it working in general. The step by step instructions are covered here. Note: This is a rather classical snowflake setup -- we create a VM and do some manual configuration to get everything configured. Having it well documented here should make this more replicatable, and is an important precondition for more automation, but larger steps to full automate this using ansible or helm charts (in a containerized variant) are not addressed here. As we expect a successor project for the increasingly hard to maintain shell code, this may not be worth the trouble. openstack-health-monitor implements a scripted scenario test with a large shell-script that uses the openstackclient tools to set up the scenario, test it and tear everything down again in a loop. Any errors are recorded, as well as timings and some very basic benchmarks. The script sets up some virtual network infrastructure (routers, networks, subnets, floating IPs), security groups, keypairs, volumes and finally boots some VMs. Access to these is tested (ensuring metadata injection works) and connectivity between them tested and measured. A loadbalancer (optionally) is set up with a health-monitor and access via it before and after killing some backends is tested. The scenario is described in a bit more detail in the repository's README.md file. The openstack-health-monitor is not the intended long-term solution for monitoring your infrastructure. The SCS project has a project underway that will create more modern, flexible, and more maintainable monitoring infrastructure; the concepts are described on the monitoring section of the project's documentation. The openstack-health-monitor will thus not see any significant enhancements any more; it will be maintained and kept alive as long as there are users. This guide exclusively focuses on how to set it up.","s":"Intro","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#intro","p":2339},{"i":2344,"t":"So we start a Debian 12 image on a cloud of our choice. This should work on any OpenStack cloud that is reasonably standard; the instructions use flavor names and image names from the SCS standards. For many, the simplest way may be to use the Web-UI of their cloud (e.g. horizon for OpenStack).","s":"Setting up the driver VM","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#setting-up-the-driver-vm","p":2339},{"i":2346,"t":"There are pros and cons to run the driver VM in the same cloud that is also under test. We obviously don't test the external reachability of the cloud (more precisely its API endpoints and VMs) if we run it on the same cloud -- which may or may not be desirable. Having the tests happily continuing to collect data may actually be valuable in times when external access is barred. If the cloud goes down, we will no longer see API calls against it, although the information of them not being available does not reveal much in terms of insight into the reasons for the outage. Also, the driver VM is the only long-lived VM in the openstack-health-monitor setup, so it may be useful to have it in the same cloud to reveal any issues that do not occur on the short-lived resources created and deleted by the health-monitor. The author tends to see running it internally as advantageous -- ideally combined with a simple API reachability test from the outside that sends alarms as needed to detect any reachability problems.","s":"Internal vs external monitoring","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#internal-vs-external-monitoring","p":2339},{"i":2348,"t":"Nothing in this test requires admin privileges on the cloud where the driver runs nor on the cloud under test. We do install and configure a few software packages in the driver VM, which requires sudo power there, but the script should just run as a normal user. For the cloud under test it is recommended to use a user (or an application credential) with a normal tenant member role to access the cloud under test. If you can, give it an OpenStack project on its own. If openstack availability zone list --compute fails for you without admin rights, please fix your openstack client. (Versions 6.3.0 and 6.4.0 are broken.) Do not consider giving the OpenStack Healh-Monitor admin power. (Note: It has a workaround for the broken AZ listing using curl now.)","s":"Unprivileged operation","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#unprivileged-operation","p":2339},{"i":2350,"t":"The author prefers to setup the VM via openstack CLI tooling. He has working entries for all clouds he uses in his ~/.config/openstack/clouds.yaml and secure.yaml and has exported the OS_CLOUD environment variable to point to the cloud he is working on to set up the driver VM. The author uses the bash shell. All of this of course could be scripted. So here we go Create the network setup for a VM in a network oshm-network with an IPv4 subnet, connected to a router that connects (and by default SNATs) to the public network. PUBLIC=$(openstack network list --external -f value -c Name) openstack router create oshm-router openstack router set --external-gateway $PUBLIC oshm-driver-router openstack network create oshm-network openstack subnet create --subnet-range 192.168.192.0/24 --network oshm-network oshm-subnet openstack router add subnet oshm-router oshm-subnet Create a security group that allows ssh and ping access openstack security group create sshping openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 22 sshping openstack security group rule create --ingress --ethertype ipv4 --protocol icmp --icmp-type 8 sshping Being at it, we also create the security group for grafana openstack security group create grafana openstack security group rule create --ingress --ethertype ipv4 --protocol tcp --dst-port 3000 grafana To connect to the VM via ssh later, we create an SSH keypair openstack keypair create --private-key ~/.ssh/oshm-key.pem oshm-key chmod og-r ~/.ssh/oshm-key.pem Rather than creating a new key (and storing and protecting the private key), we could have passed --public-key and used an existing keypair. Look up Debian 12 image UUID. IMGUUID=$(openstack image list --name \"Debian 12\" -f value -c ID | tr -d '\\r') echo $IMGUUID Sidenote: The tr command is there to handle broken tooling that embeds a trailing \\r in the output. Boot the driver VM openstack server create --network oshm-network --key-name oshm-key --security-group default --security-group sshping --security-group grafana --flavor SCS-2V-4 --block-device boot_index=0,uuid=$IMGUUID,source_type=image,volume_size=10,destination_type=volume,delete_on_termination=true oshm-driver Chose a flavor that exists on your cloud. Here we have used one without root disk and asked nova to create a volume on the fly by passing --block-device. See diskless flavor blog article. For flavors with local root disks, you could have used the --image $IMGUUID parameter instead. Wait for it to boot (optional) You can look at the boot log with openstack console log show oshm-driver or connect to it via VNC at the URL given by openstack console url show oshm-driver. You can of course also query openstack on the status openstack server list or openstack server show oshm-driver. You can also just create a simple loop: declare -i ctr=0 RC=0 while [ $ctr -le 120 ]; do STATUS=\"$(openstack server list --name oshm-driver -f value -c Status)\" if [ \"$STATUS\" = \"ACTIVE\" ]; then echo \"$STATUS\"; break; fi if [ \"$STATUS\" = \"ERROR\" ]; then echo \"$STATUS\"; RC=1; break; fi if [ -z \"$STATUS\" ]; then echo \"No such VM\"; RC=2; break; fi sleep 2 let ctr+=1 done # return $RC if [ $RC != 0 ]; then false; fi Attach a floating IP so it's reachable from the outside. FIXEDIP=$(openstack server list --name oshm-driver -f value -c Networks | sed \"s@^[^:]*:[^']*'\\([0-9\\.]*\\)'.*\\$@\\1@\") FIXEDPORT=$(openstack port list --fixed-ip ip-address=$FIXEDIP,subnet=oshm-subnet -f value -c ID) echo $FIXEDIP $FIXEDPORT openstack floating ip create --port $FIXEDPORT $PUBLIC FLOATINGIP=$(openstack floating ip list --fixed-ip-address $FIXEDIP -f value -c \"Floating IP Address\") echo \"Floating IP: $FLOATINGIP\" Remember this floating IP address. Connect to it via ssh ssh -i ~/.ssh/oshm-key.pem debian@$FLOATINGIP On the first connection, you need to accept the new ssh host key. (Very careful people would compare the fingerprint with the console log output.) All the following commands are performed on the newly started driver VM.","s":"Driver VM via openstack CLI","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#driver-vm-via-openstack-cli","p":2339},{"i":2352,"t":"We need to install the openstack client utilities. sudo apt-get update sudo apt-get install python3-openstackclient sudo apt-get install python3-cinderclient python3-octaviaclient python3-swiftclient python3-designateclient Configure your cloud access in ~/.config/openstack/clouds.yaml clouds: CLOUDNAME: interface: public identity-api-version: 3 #region_name: REGION auth: auth_url: KEYSTONE_ENDPOINT project_id: PROJECT_UUID #alternatively project_name and project_domain_name user_domain_name: default # change to your real domain and secure.yaml (in the same directory) clouds: CLOUDNAME: auth: username: USERNAME password: PASSWORD The CLOUDNAME can be freely chosen. This is the value passed to the openstack CLI with --os-cloud or exported to your environment in OS_CLOUD. The other uppercase words need to be adjusted to match your cloud. Hint: horizon typically lets you download a sample clouds.yaml file that works (but lacks the password). Protect your secure.yaml from being read by others: chmod 0600 ~/.config/openstack/secure.yaml. If you are using application credentials instead of username, password to authenticate, you don't need to specify project_id nor project's nor user's domain names in clouds.yaml. Just (in secure.yaml): clouds: CLOUDNAME: auth_type: v3applicationcredential auth: application_credential_id: APPCRED_ID application_credential_secret: \"APPCRED_SECRET\" Configure this to be your default cloud: export OS_CLOUD=CLOUDNAME You might consider adding this to your ~/.bashrc for convenience. Being at it, you might want to add export CLIFF_FIT_WIDTH=1 there as well to make openstack command output tables more readable (but sometimes less easy to cut'n'paste). Verify that your openstack CLI works: openstack catalog list openstack server list You can use the same project as you use for your driver VM (and possibly other workloads). The openstack-health-monitor is carefully designed to not clean up anything that it has not created. There is however some trickiness, as not all resources have names (floating IPs for example do not) and sometimes names need to be assigned after creation of a resource (volumes of diskless flavors), so in case there are API errors, some heuristics is used to identify resources which may not be safe under all circumstances. So ideally, you have an extra project created just for the health-monitor and configure the credentials for it here, so you can not possibly hit any wrong resource in the script's extensive efforts to clean up in error cases.","s":"Configuring openstack CLI on the driver VM","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#configuring-openstack-cli-on-the-driver-vm","p":2339},{"i":2354,"t":"If your cloud API's endpoints don't use TLS certificates that are signed by an official CA, you need to provide your CA to this VM and configure it. (On a SCS Cloud-in-a-Box system, you find it on the manager node in /etc/ssl/certs/ca-certificates.crt. You may extract the last cert or just leave them all together.) Copy the CA file to your driver VM and ensure it's readable by the debian user. Add it to your clouds.yaml clouds: CLOUDNAME: cacert: /PATH/TO/CACERT.CRT [...] If you want to allow api_monitor.sh to be able to talk to the service endpoints directly to avoid getting a fresh token from keystone for each call, you also need to export it to your environment: export OS_CACERT=/PATH/TO/CACERT.CRT Consider adding this to your ~/.bashrc as well.","s":"Custom CA","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#custom-ca","p":2339},{"i":2356,"t":"Checkout openstack-health-monitor: sudo apt-get install git bc jq netcat-traditional tmux zstd git clone https://github.com/SovereignCloudStack/openstack-health-monitor cd openstack-health-monitor You may want to start a tmux (or screen) session now, so you can do multiple things in parallel (e.g. for debugging) and reconnect. The script api_monitor.sh is the main worker of openstack-health-monitor and runs one to many iterations of a cycle where resources are created, tested and torn down. Its operation is described in the README.md file. It is good practice to use tmux. This allows you to return (reattach) to console sessions and to open new windows to investigate things. Traditional people may prefer to screen over tmux. You should be ready to run one iteration of the openstack-health-monitor now. Run it like this: export IMG=\"Debian 12\" export JHIMG=\"Debian 12\" ./api_monitor.sh -O -C -D -n 6 -s -b -B -M -T -LL -i 1 Leave out the -LL if you don't have a working loadbalancer service or replace -LL with -LO if you want to test the ovn loadbalancer instead of amphorae (saving quite some resources). Feel free to study the meaning of all the command line parameters by looking at the README.md. (Note: Many of the things enabled by the parameters should be default, but are not for historic reasons. This would change if we rewrite this whole thing in python.) This will run for ~7 minutes, depending on the performance of your OpenStack environment. You should not get any error. (The amber-colored outputs DOWN, BUILD, creating are not errors. Nothing in red should be displayed.) Studying the console output may be instructive to follow the script's progress. You may also open another window (remember the tmux recommendation above) and look at the resources with the usual openstack RESOURCE list and openstack RESOURCE show NAME and RESOURCE being something like router, network, subnet, port, volume, server, floating ip, loadbalancer, loadbalancer pool, loadbalancer listener, security group, keypair, image, ...) The api_monitor.sh uses and APIMonitor_TIMESTAMP prefix for all OpenStack resource names. This allows to identify the created resources and clean them up even if things go wrong. TIMESTAMP is an integer number representing the seconds after 1970-01-01 00:00:00 UTC (Unix time). This may be the time to check that you have sufficient quota to create the resources. While we only create 6+N VMs (and volumes) with the above call (N being the number of AZs), we would want to increase this number for larger clouds. For single-AZ deployments, we would want to still use 2 networks at least -N 2 to test the ability of the router to route traffic between networks. So expect -n 6 to become -N 2 -n 6 for a very small single-AZ cloud or -n 12 for a large 3 AZ cloud region. So, re-run the api_monitor.sh with the target sizing.","s":"Your first api_monitor.sh iteration","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#your-first-api_monitorsh-iteration","p":2339},{"i":2358,"t":"Note that api_monitor.sh uses small flavors (SCS-1V-2 for the N jump hosts and SCS-1L-1 for the other VMs) to keep the impact on your cloud (and on your invoice if you are not monitoring your own cloud) small. You can change the flavors. If you have to pay for this, also consider that some clouds are not charging by the minute but may count by the started hour. So when you run api_monitor.sh in a loop (which you will) with say 10 VMs (e.g. -N 2 -n 8) in each iteration and run this for an hour with 8 iterations, you will never have more than 10 VMs in parallel and they only are alive a bit more than half of the time, but rather than being charged for ~6 VM hours, you end up being charged for ~80 VM hours. Similar for volumes, routers, floating IPs. This makes a huge difference. Sometimes the cloud under test has issues. That's why we do monitoring ... One thing that might happen is that loadbalancers and volumes (and other resources, but those two are the most prone to this) end up in a broken state that can not be cleaned up by the user any more. Bad providers may charge for these anyhow, although this will never stand a legal dispute. (IANAL, but charging for providing something that is not working is not typically supported by civil law in most jurisdictions and T&Cs that would say so would not normally be legally enforceable.) If this happens, I recommend to keep records of the broken state (store the output of openstack volume list, openstack volume show BROKEN_VOLUME, openstack loadbalancer list, openstack loadbalancer show BROKEN_LB.) Using -w -1 makes api_monitor.sh wait for interactive input whenever an error occurs; this can be convenient for debugging. Once you have single iterations working nicely, we can proceed.","s":"Resource impact and charging","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#resource-impact-and-charging","p":2339},{"i":2360,"t":"Typically, we run api_monitor.sh with a limited amount of iterations (200) and then restart it. For each restart, we also output some statistics, compress the log file and look at any leftovers that did not get cleaned up. The latter happens in the start script that we create here. #!/bin/bash # run_CLOUDNAME.sh # Do some global settings export IMG=\"Debian 12\" export JHIMG=\"Debian 12\" #export OS_CACERT=/home/debian/ca-certificates.pem # Additional settings to override flavors or to # configure email addresses for sending alarms can be set here # Does openstack CLI work? openstack server list >/dev/null || exit 1 # Upload log files to this swift container (which you need to create) #export SWIFTCONTAINER=OS-HM-Logfiles # CLEANUP echo \"Finding resources from previous runs to clean up ...\" # Find Floating IPs FIPLIST=\"\" FIPS=$(openstack floating ip list -f value -c ID) for fip in $FIPS; do FIP=$(openstack floating ip show $fip | grep -o \"APIMonitor_[0-9]*\") if test -n \"$FIP\"; then FIPLIST=\"${FIPLIST}${FIP}_ \"; fi done FIPLIST=$(echo \"$FIPLIST\" | grep -v '^$' | sort -u) # Cleanup previous interrupted runs SERVERS=$(openstack server list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) KEYPAIR=$(openstack keypair list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) VOLUMES=$(openstack volume list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) NETWORK=$(openstack network list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) LOADBAL=$(openstack loadbalancer list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) ROUTERS=$(openstack router list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) SECGRPS=$(openstack security group list | grep -o \"APIMonitor_[0-9]*_\" | sort -u) echo CLEANUP: FIPs $FIPLIST Servers $SERVERS Keypairs $KEYPAIR Volumes $VOLUMES Networks $NETWORK LoadBalancers $LOADBAL Routers $ROUTERS SecGrps $SECGRPS for ENV in $FIPLIST; do echo \"******************************\" echo \"CLEAN $ENV\" bash ./api_monitor.sh -o -T -q -c CLEANUP $ENV echo \"******************************\" done TOCLEAN=$(echo \"$SERVERS $KEYPAIR $VOLUMES $NETWORK $LOADBAL $ROUTERS $SECGRPS \" | grep -v '^$' | sort -u) for ENV in $TOCLEAN; do echo \"******************************\" echo \"CLEAN $ENV\" bash ./api_monitor.sh -o -q -LL -c CLEANUP $ENV echo \"******************************\" done # Now run the monitor #exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -a 2 -t -T -R -S ciab \"$@\" exec ./api_monitor.sh -O -C -D -N 2 -n 6 -s -M -LO -b -B -T \"$@\" Compared to the previous run, we have explicitly set two networks here -N 2 and rely on the iterations being passed in as command line arguments. Add parameter -t if your cloud is slow to increase timeouts. We have enabled the ovtavia loadbalancer (-LO) in this example rather than the amphora based one (-LL). You may use one of the existing run_XXXX.sh scripts as example. Beware: eMail alerting with ALARM_EMAIL_ADDRESS and NOTE_EMAIL_ADDRESS (and limiting with -a and -R ) and reporting data to telegraf (option -S) may be present in the samples. Make this script executable (chmod +x run_CLOUDNAME.sh). We wrap a loop around this in run_in_loop.sh: #!/bin/bash # run_in_loop.sh rm stop-os-hm 2>/dev/null while true; do ./run_CLOUDNAME.sh -i 200 if test -e stop-os-hm; then break; fi echo -n \"Hit ^C to abort ...\" sleep 15; echo done Also make this executable (chmod +x run_in_loop.sh). To run this automatically in a tmux window whenever the system starts, we follow the steps in the startup README.md Change OS_CLOUD in startup/run-apimon-in-tmux.sh. (If you need to set OS_CACERT, also add it in this file and pass it into the windows.) Activate everything: mkdir -p ~/.config/systemd/user/ cp -p startup/apimon.service ~/.config/systemd/user/ systemctl --user enable apimon systemctl --user start apimon sudo loginctl enable-linger debian tmux attach oshealthmon This assumes that you are using the user debian for this monitoring and have checked out the repository at ~/openstack-health-monitor/. Adjust the paths and user name otherwise. (If for whatever reason you have chosen to install things as root, you will have to install the systemd service unit in the system paths and ensure it's not started too early in the boot process.)","s":"Automating startup and cleanup","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#automating-startup-and-cleanup","p":2339},{"i":2362,"t":"If you want to change the parameters passed to api_monitor.sh, you best do this by editing run_CLOUDNAME.sh, potentially after testing it with one iteration before. To make the change effective, you can wait until the current 200 iterations are completed and the run_in_loop.sh calls run_CLOUDNAME.sh again. You can also hit ^C in the tmux window that hasapi_monitor.sh running. The script will then exit after the current iteration. Note that sending this interrupt is handled by the script, so it does still continue the current iteration and do all the cleanup work. However, you may interrupt an API call and thus cause a spurious error (which may in the worst case lead to a couple more spurious errors). If you want to avoid this, hit ^C during the wait/sleep phases of the script (after having done all the tests or after having completed the iteration). If you hit ^C twice, it will abort the the current iteration, but still try to clean up. Then the outer script will also exit and you have to restart by manually calling ./run_in_loop.sh again. You can also issue the systemctl --user stop apimon command; it will basically do the same thing: Send ^C and then wait for everything to be completed and tear down the tmux session. After waiting for that to complete, you can start it again with systemctl --user start apimon.","s":"Changing parameters and restarting","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#changing-parameters-and-restarting","p":2339},{"i":2364,"t":"You can run multiple instances of api_monitor.sh on the same driver VM. In this case, you should rename run_in_loop.sh to e.g. run_in_loop_CLOUDNAME1.sh and call run_CLOUDNAME1.sh from there. Don't forget to adjust startup/run-apimon-in-tmux.sh and startup/kill-apimon-in-tmux.sh to start more windows. It is not recommended to run multiple instances against the same OpenStack project however. While the api_monitor.sh script carefully keeps track of its own resources and avoids to delete things it has not created, this is not the case for the run_CLOUDNAME.sh script, which is explicitly meant to identify anything in the target project that was created by a health monitor and clean it up. If it hits the resources that are currently in use by another health mon instance, this will create spurious errors. This will happen every ~200 iterations, so you could still have some short-term coexistence when you are performing debug operations.","s":"Multiple instances","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#multiple-instances","p":2339},{"i":2367,"t":"If wanted, the api_monitor.sh can send statistics and error messages via email, so operator personnel is informed about the state of the monitoring. This email notification service potentially results in many emails; one error may produce several mails. So in case of a systematic problem, expect to receive dozens of mails per hour. This can be reduced a bit using the -a N and -R options. In order to enable sending emails from the driver VM, it needs to have postfix (or another MTA) installed and configured and outgoing connections for eMail need to be allowed. Note that many operators prefer not to use the eMail notifications but rather rely on looking at the dashboards (see further down) regularly. Once you have configured postfix, you can enable eMail notifications using the option -e. Using it twice allows you to differentiate between notes (statistical summaries) and errors. If you want to send mails to more than one recipient, you can do so by passing ALARM_EMAIL_ADDRESSES and NOTE_EMAIL_ADDRESSES environment variables to api_monitor.sh, e.g. by setting it in the run_CLOUDNAME.sh.","s":"eMail","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#email","p":2339},{"i":2369,"t":"api_monitor.sh writes a log file with the name APIMonitor_TIMESTAMP.log. It contains a bit of information to see the progress of the script; more importantly, it logs every single openstack CLI call along with parameters and results. (TIMESTAMP is the Unix time, i.e. seconds since 1970-01-01 00:00:00 UTC.) Note that api_monitor.sh does take some care not to expose secrets -- since v1.99, it does also redact issued tokens (which would otherwise give you up to 24hrs of access). But the Log files still may contain moderately sensitive information, so we suggest to not share it with untrusted parties. The log file is written to the file system. After finishing the 200 iterations, the log file is compressed. If the environment variable SWIFTCONTAINER has been set (in run_COULDNAME.sh) when starting api_monitor.sh. the log file will be uploaded to a container with that name if it exists and if the swift object storage service is supported by the cloud. So create the container (a bucket in S3 speak) before if you want to use this: export SWIFTCONTAINER=OSHM_Logs; openstack container create $SWIFTCONTAINER After the 200 iterations, a .psv file (pipe-separated values) is created Stats.STARTTIME-ENDTIME.psv (with times as calendar dates) which contains a bit of statistics on the last 200 iterations. This one will also be uploaded to $SWIFTCONTAINER (if configured).","s":"Log files","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#log-files","p":2339},{"i":2371,"t":"See https://github.com/SovereignCloudStack/openstack-health-monitor/blob/main/dashboard/README.md","s":"Data collection and dashboard","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#data-collection-and-dashboard","p":2339},{"i":2373,"t":"To install telegraf on Debian 12, we need to add the apt repository provided by InfluxData: sudo curl -fsSL https://repos.influxdata.com/influxdata-archive_compat.key -o /etc/apt/keyrings/influxdata-archive_compat.key echo \"deb [signed-by=/etc/apt/keyrings/influxdata-archive_compat.key] https://repos.influxdata.com/debian stable main\" | sudo tee /etc/apt/sources.list.d/influxdata.list sudo apt update sudo apt -y install telegraf In the config file /etc/telegraf/telegraf.conf, we enable [[inputs.influxdb_listener]] service_address = \":8186\" [[outputs.influxdb]] urls = [\"http://127.0.0.1:8086\"] and restart the service (sudo systemctl restart telegraf). Enable it on system startup: sudo systemctl enable telegraf.","s":"telegraf","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#telegraf","p":2339},{"i":2375,"t":"We proceed to influxdb: sudo apt-get install influxdb In the configuration file /etc/influxdb/influxdb.conf, ensure that the http interface on port 8086 is enabled. [http] enabled = true bind-address = \":8086\" Restart influxdb as needed with sudo systemctl restart influxdb. Also enable it on system startup: sudo systemctl enable influxdb.","s":"influxdb","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#influxdb","p":2339},{"i":2377,"t":"You need to tell the monitor that it should send data via telegraf to influxdb by adding the parameter -S CLOUDNAME to the api_monitor.sh call in run_CLOUDNAME.sh. Restart it (see above) to make the change effective immediately (and not only after 200 iterations complete).","s":"Add -S CLOUDNAME to your run_CLOUDNAME.sh script","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#add--s-cloudname-to-your-run_cloudnamesh-script","p":2339},{"i":2379,"t":"Basic config​ Finally grafana: We (still as root) follow https://www.server-world.info/en/note?os=Debian_12&p=grafana sudo wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key echo \"deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main\" | sudo tee -a /etc/apt/sources.list.d/grafana.list sudo apt update sudo apt -y install grafana The config file /etc/grafana/grafana.ini needs some adjustments: Set the hostname in [server] section: domain = health.YOURCLOUD.sovereignit.cloud. Set the protocol = https if not enabled by default. You can use a hostname of your liking, but we will need to create TLS certificates for this host. So we should have control over DNS TXT records for this domain if we want to use Let's Encrypt with DNSAUTH. The sovereignit.cloud domain is controlled by the SCS project team and has been used for a number of health mon instances. In this same section, set cert_file = /etc/grafana/health-fullchain.pem and cert_key = /etc/grafana/health-key.pem. Ensure that both files are readable by root:grafana and that the key file is not world-readable. Configure the admin access. In section [security], set the admin_user = admin and admin_password = SOME_SECRET_PASS which you keep private. Allow local data sources (same section): data_source_proxy_whitelist = localhost:8088 localhost:8086 Let's disallow user signup (in section [users]): allow_sign_up = false and allow_org_create = false. We do the OIDC connection with [auth.github] later. We can now restart the service: sudo systemctl restart grafana-server. Being at it, also enable it on system startup: sudo systemctl enable grafana-server. You should now be able to access your dashboard on https://health.YOURCLOUD.sovereignit.de:3000 and log in via the configured username admin and your SOME_SECRET_PASS password. Enable influx database in grafana​ In the dashboard, go to Home, Connections, choose InfluxDB and Add new datasource. The defaults (database name, InfluxQL query language) work. You need to explicitly set the URL to http://localhost:8086 (despite this being the suggestion). Set the database name to telegraf. Save&test should succeed. Importing the dashboard​ Go to Home, Dashboards, New, Import. Upload the dashboard .json file from the repository, user the Grafana-10 variant if you use Grafana 10 or newer. In the dashboard, go to the settings gear wheel, variables, mycloud and add CLOUDNAME to the list of clouds that can be displayed. (There are some existing SCS clouds in that list.) Save. Now choose CLOUDNAME as cloud (top of the dashboard, rightmost dropdown for the mycloud filter variable). No data displayed?​ Sometimes, you may see a panel displaying \"no data\" despite the fact that the first full iteration of data has been sent to influx already. This may be a strange interaction between the browser and Grafana -- we have not analyzed whether that is a bug in Grafana. One way to work around is to go into the setting of the panel (the three dots in the upper right corner), go to edit and start changing one aspect of the query. Apply. Change it back to the original. Apply. The data will appear. Save to be sure it's conserved. Dashboard features​ Look at the top line filters: You can filter to only see certain API calls or certain resources; the graphs are very crowded and filtering to better see what you want to focus on is very well intended. The first row of panels give a health impression; there are absolute numbers as well as percentage numbers and the panels turn amber and red in case you have too many errors. Note that the colors on the panels with absolute numbers can not take into account whether you look at just a few hours or at weeks. Accordingly, consider the colors a reasonable hint if things are green or not when looking at a ~24 hours interval. This limitation does not affect the colors on the percentage graph, obviously. You can change the time interval and zoom in also by marking an interval with the mouse. Zooming out to a few months can be a very useful feature to see trends and watch e.g. your API performance, your resource creation times or the benchmarks change over the long term. github OIDC integration​ The SCS providers do allow all github users that belong to the SovereignCloudStack organization to get Viewer access to the dashboards by adding a client_id and client_secret in the [github.auth] section that you request from the SCS github admins (github's oauth auth). This allows to exchange experience and to get a feeling for the achievable stability. (Hint: A single digit number of API call fails per week and no other failures is achievable on loaded clouds.)","s":"grafana","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#grafana","p":2339},{"i":2381,"t":"Install influxdb via apt: https://docs.influxdata.com/influxdb/v1/introduction/install/#installing-influxdb-oss Install telegraf (same apt repo as influxdb): sudo apt update && sudo apt install telegraf Install grafana: https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/#install-from-apt-repository Prepare configuration by using the config files from the repository as an alternative to doing the changes manually (as described above): sudo cp dashboard/telegraf.conf /etc/telegraf && sudo chown root:root /etc/telegraf/telegraf.conf && sudo chmod 0644 /etc/telegraf/telegraf.conf sudo cp dashboard/config.toml /etc/influxdb && sudo chown root:influxdb /etc/influxdb/config.toml && sudo chmod 0640 /etc/influxdb/config.toml sudo cp dashboard/grafana.ini /etc/grafana && sudo chown root:grafana /etc/grafana/grafana.ini && sudo chmod 0640 /etc/grafana/grafana.ini These config files should work as long as the versions of telegraf, influxdb and grafana don't evolve too far from the ones used in the repository. (Otherwise refer to above instructions how to tweak the default config files.) Changes to /etc/grafana/grafana.ini as we do tls termination at the reverse proxy: set protocol = http comment out domain option (? FIXME) or set it to the hostname comment out cert_* options Also change the admin password in grafana.ini. Changes to /etc/grafana/grafana.ini if github auth should not be used yet: comment out whole [auth.github] section for now (can be enabled later) Restart services: sudo systemctl restart telegraf && sudo systemctl restart influxdb && sudo systemctl restart grafana-server Configuration in grafana web gui: Login to grafana http(s)://:3000 with user admin and default password from /etc/grafana/grafana.ini and change password. Create influxdb datasource with url http://localhost:8086 and database name telegraf. Finally import dashboard dashboard/openstack-health-dashboard.json to grafana. TODO: Reverse proxy (aka ingress) with Let's Encrypt cert Github auth as described above","s":"Alternative approach to install and configure the dashboard behind a reverse proxy","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#alternative-approach-to-install-and-configure-the-dashboard-behind-a-reverse-proxy","p":2339},{"i":2383,"t":"The driver VM is a snowflake: A manually set up system (unless you automate all the above steps, which is possible of course) that holds data and is long-lived. As such it's important to be maintained.","s":"Maintenance","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#maintenance","p":2339},{"i":2385,"t":"It is recommended to ensure maintenance updates are deployed automatically. These are unlikely to negatively impact the openstack-health-monitor. See https://wiki.debian.org/UnattendedUpgrades. If you decide against unattended upgrades, it is recommended to install updates manually regularly and especially watch out for issues that affect the services that are exposed to the world: sshd (port 22) and grafana (port 3000).","s":"Unattended upgrades","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#unattended-upgrades","p":2339},{"i":2387,"t":"You can just do a git update in the openstack-health-monitor directory to get the latest improvements. Note that these will only become effective after the 200 iterations have completed. You can speed this up by injecting a ^C, see above in the restart section.","s":"Updating openstack-health-monitor","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#updating-openstack-health-monitor","p":2339},{"i":2389,"t":"The system holds two things that you might consider valuable for long-term storage: (1) The log files. These are compressed and uploaded to object storage if you enable the SWIFTCONTAINER setting, which probably means that these do not need any additional backing up then. (2) The influx time series data. Back up the data in /var/lib/influxdb. Obviously, if you want to recover quickly from a crash, you might consider to also back up telegraf, influx and grafana config files as well as the edited startup scripts, clouds.yaml, etc. Be careful not to expose sensitive data by granting too generous access to your backed up files.","s":"Backup","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#backup","p":2339},{"i":2392,"t":"In case there is trouble with your cloud, the normal course of action to analyze is as follows: Look at the dashboard (see above) Connect to the driver VM and attach to the tmux session and look at the console output of api_monitor.sh Analyze the logfile (locally on the driver VM or grab it from the object storage)","s":"Debugging issues","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#debugging-issues","p":2339},{"i":2394,"t":"When VM instances are created successfully, but then end up in ERROR state, the api_monitor.sh does an explicit openstack server show, so you will find some details in the tmux session, in the alarm emails (if you use those) and in the log files. Sometimes the VMs end up being ACTIVE as wanted but then they can't be accessed via ssh. More often than not, this is a problem with meta-data service on a compute host. Without metadata, not ssh key is injected and login will fail. To gather more details, you can look at the console output openstack console log show VM (where VM is the name of the uuid of the affected VM instance). The cloud-init output is often enough to see what has gone wrong. You can log in to the VMs: The jumphosts are directly accessible via ssh -i APIMonitor_XXXXX_JH.pem debian@FIP, whereas the JumpHost does port forwarding to the other VMs that don't have their own floating IP address: ssh -i APIMonitor_XXXXX_VM.pem -p 222 debian@FIP. Replace XXXXX with the number in your current APIMonitor prefix, FIP with the floating IP address of the responsible JumpHost and debian with the user name used by the images you boot. Use 223 to connect to the second VM in the network, 224 the third etc. When logged in, look at /var/log/cloud-init-output.log and /var/log/cloud-init.log. You can find the metadata in /var/lib/cloud/instance/. You will not have much time to look around -- the still running api_monitor.sh script does continue and clean things up again. So you might want to suspend it with ^Z (and continue it later with fg). Another option is to not stop the regular monitoring, but start a second instance manually; see above notes for running multiple instances though. If you start a second instance manually against the same project, do NOT use the run_CLOUDNAME.sh script as it would do cleanup against the running instance, but rather copy the api_monitor.sh command line from the bottom (without the exec), reduce the iterations to a few (unless you need a lot to trigger the issue again) and attach -w -1 to make the script stop its operation (and wait for Enter) once it hits an error. Of course, you still will face cleanup when the continuing main script hits its 200th iteration and you have chosen to run this second instance against the same project in the same cloud. After analyzing, do not forget to go back to the tmux window where the stopped script is running and do hit Enter, so it can continue and do its cleanup work.","s":"Analyzing failures","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#analyzing-failures","p":2339},{"i":2396,"t":"If you are unlucky, the script fails to clean something up. A volume may not have been named (because of a cinder failure) or all the logic may have gone wrong, e.g. the heuristic to avoid leaking floating IPs. You can try to clean this up using the normal openstack commands (or horizon dashboard). There are a few things that may need support from a cloud admin: Volumes may end up permanently in a deleting or reserved state or may be in-use, attached to a VM that has long gone. The admin needs to set the state to error and then delete them. Loadbalancers may end up in a PENDING_XXX state (XXX being CREATE, UPDATE or DELETE) without ever changing. This also needs the cloud admin to set the status to ERROR, so it can be cleaned up. amphorae are more prone to this than ovn LBs. More like these may happen, but those two are the only ones that have been observed to happen occasionally. Some services seem to be less robust than others against an event in the event queue (rabbitmq) being lost or an connection to be interrupted.","s":"Cleaning things up","u":"/docs/operating-scs/guides/openstack-health-monitor/Debian12-Install","h":"#cleaning-things-up","p":2339},{"i":2398,"t":"(Release Date: 2023-09-20)","s":"Release Notes for SCS Release 5","u":"/docs/releases/Release5","h":"","p":2397},{"i":2400,"t":"Just as our previous release, Release 5 has been developed alongside a set of associated outcomes. These outcomes are comprised of: SCS is standardized SCS is understandable SCS is transparent SCS is continuously built and tested SCS is opinionated SCS enables","s":"Scope","u":"/docs/releases/Release5","h":"#scope","p":2397},{"i":2403,"t":"The IaaS reference implementation is based on OSISM 6.0.0. OpenStack 2023.1 (Antelope) Default Ceph version is now Ceph Quincy. OVN and OVS have been updated to their latest versions (OVN: 23.06.1, OVS: 3.2.0). IPv6 east-west and north-south support is present and documented upstream. Cloud-in-a-Box now comes with Swift enabled as well as the option for secondary NIC for external connectivity.","s":"IaaS","u":"/docs/releases/Release5","h":"#iaas","p":2397},{"i":2405,"t":"The Kubernetes Cluster Management solution is available as version 6.0.0 Kubernetes v1.24 .. 1.27 are officially supported. v1.28 also works (technical preview until officially supported by capo) as do older versions (with downgrading nginx-ingress), matching OCCM and CSI versions. Cluster-API (capi) v1.5.1, Cluster-API provider for Openstack (capo) v0.7.3 The node images now use Ubuntu 22.04, the management host can use Ubuntu 22.04 or Debian 12. Cilium v1.14.1, default now, though Calico (3.26.x) is still supported. Cilium also brings the upcoming gateway API (opt-in) as technical preview. The Harbor container registry can now be rolled out with each cluster. The clusters can use a registry as cache to upstream dockerhub or gcr registries. The cluster management now works also on OpenStack clouds with a custom CA. Storage snapshots are supported now (fix was also backported to maintained branches). Diskless flavors are supported everywhere (cluster-management, health-monitor). etcd defragmentation and backup. Controls for pod and service IP ranges.","s":"Container Management","u":"/docs/releases/Release5","h":"#container-management","p":2397},{"i":2407,"t":"The old scripts that are used to create, change and delete Kubernetes clusters with Cluster API will be replaced by a proper Operator in the next release. A description can be found at the cluster-stacks and cluster-stack-operator repositories. The technical preview can be tried with the cluster-stacks-demo. This solution will fit more nicely into the CNCF landscape and also allow for easier support of IaaS solutions that do not comply to our SCS IaaS standards.","s":"Preview: Cluster-Stacks","u":"/docs/releases/Release5","h":"#preview-cluster-stacks","p":2397},{"i":2409,"t":"A number of improvements when using identity federation via OIDC has been added, including addressing openstack CLI usage with PKCE Device Authz Grant, logout, and the usage of a proxy realm in keycloak. Improvements have been contributed to upstream keystone. With the openstack-resource-manager a new day 2 operations tool has been added. Furthermore an osism role for tuned to optimize system profiles is now present. The openstack-flavor-manager is now able to create all standard, mandatory SCS flavors for you. Scaphandre Prometheus Exporter has been added to export power consumption metrics more easily. To optimize system profiles an osism role for tuned is now present. Full support for air-gapped installation and operation of environments. A migration script and guide for moving from R4 to R5 clusters is available. Metering has been improved and a reference billing API implementation is available as technical preview.","s":"Operations and IAM related","u":"/docs/releases/Release5","h":"#operations-and-iam-related","p":2397},{"i":2411,"t":"Documentation on testbed and Cloud-in-a-Box have been reworked. Reflecting CiaB's usage as edge cloud appliance, it now receives more automated testing.","s":"SCS Developer focused improvements (Cloud-in-a-Box, testbed and k8s cluster management)","u":"/docs/releases/Release5","h":"#scs-developer-focused-improvements-cloud-in-a-box-testbed-and-k8s-cluster-management","p":2397},{"i":2413,"t":"zuul.scs.community now complements OSISM's existing zuul infrastructure and is used also by the container layer to execute the CNCF e2e tests. registry.scs.community has been migrated to a new IaaS location (documented in a blog article) and is kept up-to-date now.","s":"Project Infrastructure","u":"/docs/releases/Release5","h":"#project-infrastructure","p":2397},{"i":2415,"t":"For the IaaS reference implementation, please refer to the OSISM 6.0.0 Upgrade Notes.","s":"Upgrade/Migration notes","u":"/docs/releases/Release5","h":"#upgrademigration-notes","p":2397},{"i":2417,"t":"Please check the removals for OSISM in the upstream removal notices. The services minio.services.osism.tech and harbor.services.osism.tech are deprecated and will be turned of on October 20th, 2023.","s":"Removals","u":"/docs/releases/Release5","h":"#removals","p":2397},{"i":2420,"t":"For these please also refer to the upstream deprecation notices. It is again noted that the old scripts of the form osism- will be removed in the future. A note has been added to the scripts showing this when they are executed. The following services are deprecated and will be removed with R6 (OSISM 6.1.0): Patchman Adminer Patchman Client Virtualbmc Bird","s":"Deprecations via OSISM","u":"/docs/releases/Release5","h":"#deprecations-via-osism","p":2397},{"i":2422,"t":"Throughout the Release 5 development cycle, the SCS project issued two security advisories for upstream components: In April 2023 an advisory in Open vSwitch (OvS) (CVE-2023-1668 was issued. Our advisory. In May 2023 an advisory affecting the OpenStack component Cinder (CVE-2023-2088) was issued. Our advisory.","s":"Security Fixes","u":"/docs/releases/Release5","h":"#security-fixes","p":2397},{"i":2424,"t":"Numerous minor issue have been resolved. The most important steps on the IaaS side probably being the move to ceph Quincy to avoid running out of upstream support. On the container side, the fix of storage snapshots is probably most significant. For details, we again refer to the OSISM and k8s-cluster-api-provider release notes.","s":"Resolved Issues","u":"/docs/releases/Release5","h":"#resolved-issues","p":2397},{"i":2426,"t":"A new certification set is expected in December. It will ensure we run all automated tests also for all new standards, such as v3 flavor naming, and the (previously included) v1 standard flavors -- which includes the new SSD flavors, the v1 entropy standard. We have also split image naming and standard image recommendations into v1 standards images. Requirements for k8s version recency, default storage class as well as requirements to the container registry have been captured. The IAM area has seen ADRs on the chosen architecture. The (design) decisions on the metering work as well as on the status page project have also been captured. The standards and the standards compliance of our operators' clouds can be seen in the standards section of our doc pages while the raw content is developed and discussed in the respective github standards repository. The SCS reference implementation follows all approved SCS standards.","s":"Standards Conformance","u":"/docs/releases/Release5","h":"#standards-conformance","p":2397},{"i":2428,"t":"Relevant repositories have been tagged with v6.0.0 tag. For some repositories maintained/v6.x and maintained/v6.0.x branches have been created.","s":"Release Tagging","u":"/docs/releases/Release5","h":"#release-tagging","p":2397},{"i":2430,"t":"Nothing that we are aware of at this point.","s":"List of known issues & restrictions in R5","u":"/docs/releases/Release5","h":"#list-of-known-issues--restrictions-in-r5","p":2397},{"i":2432,"t":"We appreciate contribution to strategy and implementation, please join our community -- or just leave input on the github issues and PRs. Have a look at our How to contribute page.","s":"Contributing","u":"/docs/releases/Release5","h":"#contributing","p":2397},{"i":2434,"t":"Our wonderful community of integrators, operators, contractors and volunteers made R5 possible. The project management team is employed by the OSB Alliance and we as well as the contractors are paid thanks to funding from the German Ministry for economic affairs and climate action. We build on top of a lot of existing open source code from the CNCF, the OIF and various others and we try to contribute back as much as we can.","s":"Thanks","u":"/docs/releases/Release5","h":"#thanks","p":2397},{"i":2436,"t":"This document is work in progress for the upcoming Release X. Release X will be released in Months/Year. This note will be removed, once Release X is released and these notes are valid.","s":"Release Notes for SCS Release X","u":"/docs/releases/ReleaseX","h":"","p":2435},{"i":2451,"t":"We appreciate contribution to strategy and implementation, please join our community -- or just leave input on the github issues and PRs. Have a look at our How to contribute page.","s":"Contributing","u":"/docs/releases/ReleaseX","h":"#contributing","p":2435},{"i":2454,"t":"SCS Release 6 has been published on 2024-03-20.","s":"Release Notes for SCS Release 6","u":"/docs/releases/Release6","h":"","p":2453},{"i":2456,"t":"Just as our previous release, Release 6 has been developed alongside a set of associated outcomes. Overall with Release 6 it becomes apparent that SCS is efficient to operate. SCS is standardized SCS is understandable SCS enables SCS is transparent SCS is continuously built and tested SCS is opinionated SCS charters new territory","s":"Scope","u":"/docs/releases/Release6","h":"#scope","p":2453},{"i":2459,"t":"The IaaS reference implementation is based on OSISM 7.0.0 and delivers the following components: OpenStack 2023.2 (Bobcat) Default Ceph version is Ceph Quincy Ceph Reef is included as a technical preview OVS and OVN have been updated and switched to LTS versions OVS 3.3.0 OVN 24.03.1","s":"IaaS","u":"/docs/releases/Release6","h":"#iaas","p":2453},{"i":2461,"t":"On the KaaS level, the development of the Cluster Stacks as KaaS V2 has reached a state where the approach is finally usable. With Cluster Stacks it is possible to bundle all components of Kubernetes clusters, i.e. node images, Kubernetes configuration, and cluster addons (core applications necessary to use a Kubernetes cluster) together and use the bundles to create and update clusters with one simple command. One bundle, a Cluster Stack, can be tested extensively and is only released if both creating and upgrading clusters works smoothly. Users of these Cluster Stacks profit from the Cluster Stack Operator that works alongside with Cluster API to create and update ready-to-use clusters easily. k8s-cluster-api-provider (KaaS v1) Moved to OpenTofu Migrated to ClusterClass (last not least to ease the migration to Cluster Stacks) HTTP_Proxy configurable OVN LB Cluster Stacks (KaaS v2) First Cluster Stacks for OpenStack build Cluster Stack Operator core component to manage Cluster Stack releases Cluster Stack Provider OpenStack manages node image release for OpenStack csctl builds Cluster Stacks assets builds node images tests Cluster Stacks","s":"KaaS","u":"/docs/releases/Release6","h":"#kaas","p":2453},{"i":2463,"t":"Observability​ The Observability stack reference implementation is based on dNation Kubernetes monitoring stack v3.5.0 and delivers the following components: Monitoring of infrastructure services such as Kubernetes clusters, physical or virtual machines, and infrastructure endpoints Zuul CI monitoring Matrix chat notifications OAUTH authentication IaaS monitoring is included as a technical preview Zuul​ Created a development deployment for advancement testing. Simplified the installation requirements. Updated the Zuul repository's README file to include complete installation instructions for Terraform an Ansible. Added the clouds data into the ansible vault. Created an independent ansible Zuul role. Moved the custom Zuul tasks from the playbook and incorporated them into the role. Moved the custom Zuul variables from the playbook into the role's variables. Included the installation of Letsencrypt which adds certificates as part of the installation. Added a volume on the VM for the MariaDB instance to use for continuity. Added volumes on the VM for Zookeeper to use for the data snapshots and datalog.","s":"Operations","u":"/docs/releases/Release6","h":"#operations","p":2453},{"i":2465,"t":"Updated Keycloak image to 23.0.6. Custom SCS-Keycloak image now includes the Home-IdP-discovery plugin.","s":"IAM","u":"/docs/releases/Release6","h":"#iam","p":2453},{"i":2468,"t":"A Kubernetes engine, via k3s, has been introduced to the control plane of the IaaS reference implementation. osism now deploys Keycloak to k3s via codecentric/keycloakx helm chart and CloudNativePG operator. Rotation of the Octavia Amphora images has been added to the osism command. osism manage image octavia will rotate the image, which is rebuilt on a daily basis. OpenStack Health Monitor​ A new monitoring stack will replace the old openstack-health-monitor. Nevertheless, it is currently still in heavy use and has thus seen a few improvements responding to challenges observed in real-life clouds: A new installation guide Robustness against leaking volumes even with overloaded cinder API Robustness against leaking ports from OVN LB health-monitor Robustness against leftover keypairs Avoid some followup errors when VM creation failed Add logic to startup os-health-mon in tmux windows via systemctl --user","s":"Operator focused improvements","u":"/docs/releases/Release6","h":"#operator-focused-improvements","p":2453},{"i":2470,"t":"KaaS​ Every component of Cluster Stacks brings a Tilt environment for local test and development With csctl Cluster Stacks assets can be created and tested locally without uploading to GitHub","s":"SCS Developer focused improvements (testbed and k8s cluster management)","u":"/docs/releases/Release6","h":"#scs-developer-focused-improvements-testbed-and-k8s-cluster-management","p":2453},{"i":2472,"t":"A Domain Manager role has been established in a standard draft in SCS aiming to allow self-service capabilities for customers at the identity API. Work is in progress to contribute this functionality to OpenStack Keystone and the corresponding upstream spec is currently under review. The feature is expected to be available in the next SCS release.","s":"Preview: Domain Manager Persona","u":"/docs/releases/Release6","h":"#preview-domain-manager-persona","p":2453},{"i":2474,"t":"To improve the experience of SCS cloud customers, the idea of a \"Central API\" was discussed. Such API should enable customers to manage various \"as-a-Service\" resources. For example: OpenStack instances as well as Kubernetes clusters as well as Keycloak OAuth2 clients. Read about the trade-offs and ideas in the central-api repository and feel free to test out the POC.","s":"Preview: Central API","u":"/docs/releases/Release6","h":"#preview-central-api","p":2453},{"i":2476,"t":"To improve flexibility of onboarding new customer domains via IdP federation, SCS now deploys Keycloak with the Home-IdP-discovery plugin. The idea is, that Keystone federates out to a single Keycloak \"proxy\" realm (called osism in the testbed) and using the plugin, Keycloak can identify the user specific realm from an email-format login-ID. Operators can create dedicated realms for each customer and Keycloak uses internal federation to redirect from the \"proxy\" realm to the specific customer realm. In the customer ream they can configure IdP federation (OpenID-Connect or SAML) to their own IAM solution. The IAM section of the SCS documentation shall be extended to detail the configuration. SCS is working upstream to contribute required enhancements in the mapping of users, groups and roles from OpenID-Connect token claims to the OpenStack Keystone access management.","s":"Preview: Keycloak Home-IdP-discovery","u":"/docs/releases/Release6","h":"#preview-keycloak-home-idp-discovery","p":2453},{"i":2478,"t":"For the IaaS reference implementation, please refer to the OSISM 7.0.0 Upgrade Notes.","s":"Upgrade/Migration notes","u":"/docs/releases/Release6","h":"#upgrademigration-notes","p":2453},{"i":2480,"t":"Please check the removals for OSISM in the upstream removal notices.","s":"Removals","u":"/docs/releases/Release6","h":"#removals","p":2453},{"i":2482,"t":"KaaSv1 is still provided with R6, but we do not intend to include it in R7 again. We want to rather focus on the feature completeness of the much more future-proof cluster-stacks. In upstream OSISM the role for deploying the Tang service (osism.services.tang) has been deprecated. We would like to encourage active contributions in this area via the deprecation, since this piece of code is currently not actively maintained nor -- to our knowledge -- actively used.","s":"Deprecations","u":"/docs/releases/Release6","h":"#deprecations","p":2453},{"i":2484,"t":"During the R6 development cycle a few security issues were reported and we issued security advisories and addressed them via maintenance updates. All of these issues are also fixed in the upcoming R6 release. These include: A OvS vulnerability with crafted Geneve packets and HW acceleration A OVN vulnerability against specific BFD packets Other security topics were covered in our community blog as well: Delving into the Technical Depths of Intel-SA-00950 and AMD Cachewarp Vulnerabilities","s":"Security Fixes","u":"/docs/releases/Release6","h":"#security-fixes","p":2453},{"i":2486,"t":"We invested in a range of penetration tests of the IaaS layer which resulted in valuable insight in possible improvements (e.g. applying hardening measures): External pentesting of components (scanning, blackbox testing) Internal pentesting of components with privileged and unprivileged system users (scanning from inside the cluster) Scanning and pentesting the environment from a customer workload machine The vision of SCS is to have continuous security assurance by adding security checks and pentesting tooling to our CI pipelines; this is currently in implementation. Next step will then be to also cover other parts (beyond the IaaS layer) of our stack with manual and then automated penetration testing.","s":"Security assessment for IaaS","u":"/docs/releases/Release6","h":"#security-assessment-for-iaas","p":2453},{"i":2489,"t":"A fix to a bug where listing domains via Keystone API would return domains not intended to be visible to the requesting entity was contributed and merged upstream. The fix is expected to be available by the next SCS release.","s":"Preview: proper scope filtering for domain list API","u":"/docs/releases/Release6","h":"#preview-proper-scope-filtering-for-domain-list-api","p":2453},{"i":2491,"t":"The docs page has come a long way in the last 6 months. It pulls in a lot more content from the various projects and structures it in a much more accessible way. Look at the standards pages there to get an impression.","s":"Documentation","u":"/docs/releases/Release6","h":"#documentation","p":2453},{"i":2493,"t":"Oct'23: Progress: OpenStack API access with OpenID Connect in Sovereign Cloud Stack Nov'23: Confidential Computing in digital sovereign environments Dec'23: SCS observability and monitoring - An opinionated proposal Dec'23: Cluster Stacks Feb'24: SDN scalability improvements","s":"Highlighted blog posts","u":"/docs/releases/Release6","h":"#highlighted-blog-posts","p":2453},{"i":2495,"t":"The documentation now contains an IAM overview document which explains current limitations for the dynamic mapping of user roles and shall be extended to explain configuration options for Operators.","s":"IAM","u":"/docs/releases/Release6","h":"#iam-1","p":2453},{"i":2497,"t":"The standards have evolved, increasing the amount of guarantees that software developers and operators have for workloads that work across SCS-compatible clouds. The SCS-compatible IaaS-v4 has seen improvements and better test coverage; the OSISM IaaS reference implementation fulfills all of these standards in the default configuration. For the Kubernetes layer, we have our first set of standards almost finalized. Some of the standards for SCS-compatible KaaS-v1 are unfortunately hard to test, so we are working on adding some more tests before we cut it in stone. We aim for both KaaSv1 and v2 to fulfill the standards. (Future standards will likely not be fulfilled by KaaSv1 as it's being deprecated.)","s":"Standards Conformance","u":"/docs/releases/Release6","h":"#standards-conformance","p":2453},{"i":2499,"t":"A number of repositories follow OSISM's example and use the 7.0.0 or v7.0.0 tag to denote SCS Release 6.","s":"Release Tagging","u":"/docs/releases/Release6","h":"#release-tagging","p":2453},{"i":2502,"t":"Loadbalancer service (octavia)​ Creating loadbalancers in Cloud-in-a-Box installations fails with the error message that the VIP subnet does not exist. OSISM #890 When using --provider ovn with a loadbalancer health-monitor, we leak ports ovn-lb-hm-$SUBNETID in all but the VIP subnet, if we clean up the LB members before the health-monitor. This is tracked as OSISM issue #921. Deleting the health-monitor before the members or using openstack loadbalancer delete --cascade avoids this issue. With amphora loadbalancers, we can end up in situations that LB deletion does no longer work due to a failover or a failed creation of the vrrp port. This is tracked in OSISM issue #925. An upstream fix exists and a backport is already underway. We expect to resolve these issues with a maintenance update.","s":"IaaS","u":"/docs/releases/Release6","h":"#iaas-1","p":2453},{"i":2504,"t":"Some features of KaaS v1 are not available yet in KaaS v2 because they are WIP in upstream CAPO. This includes the creation of some of the optional components such as e.g. the deployment of ingress service, cert-manager, flux, harbor. More importantly, we do not yet have the handling of restrictive security groups implemented nor the ability to avoid OpenStack scheduling more than one control plane node on the same host (hypervisor). For this reason, we are including KaaS v1 (k8s-cluster-api-provider) in the R6 release, so existing users can upgrade to the latest upstream code and continuing using it as a maintained solution while they evaluate the migration to KaaS v2 (cluster-stacks). We will address most of the gaps during the next release cycle. KaaS v1 should not be used for new deployments; we intend to remove it with the next release (R7).","s":"KaaS","u":"/docs/releases/Release6","h":"#kaas-2","p":2453},{"i":2506,"t":"Since Keycloak is a Java application it requires importing certificates into its certificate store. As the Keycloak pod in k3s now runs the service as non-root user, it gets more challenging to import custom certificates from arbitrary customers for IdP federation. In case this topic is interesting for specific deployments, the SCS project team would like to hear from users and discuss how to best expose such a capability.","s":"IAM","u":"/docs/releases/Release6","h":"#iam-2","p":2453},{"i":2508,"t":"We appreciate contribution to strategy and implementation, please join our community -- or just leave input on the github issues and PRs. Have a look at our How to contribute page.","s":"Contributing","u":"/docs/releases/Release6","h":"#contributing","p":2453},{"i":2510,"t":"We have had considerable help from many partners and upstream projects during the R6 development cycle. We continue to be grateful for the generous support from providers that support with infrastructure that we can use for testing and development. plusserver has been particularly generous and also helped us finding a few issues during the pre-release phase by upgrading test environments and testing them.","s":"Thanks","u":"/docs/releases/Release6","h":"#thanks","p":2453},{"i":2512,"t":"TODO","s":"Standards","u":"/docs/standards/","h":"","p":2511},{"i":2514,"t":"The Sovereign Cloud Stack (SCS) is a community-driven project that curates a set of standards—including both existing standards, such as the OpenInfra interoperability guides or the CNCF Kubernetes conformance, and newly created ones—to enable and ensure compatibility, openness, and sovereignty of cloud services across a wide range of providers, particularly small and medium businesses. In addition, SCS provides a certification framework that enables these providers to verify and advertise their compliance with these standards. This framework consists of six kinds of certificates of varying scope, where each scope corresponds to a subset of the set of standards mentioned above. Learn more about these scopes as well as the currently certified clouds under Certification. More details on individual standards can be found under Standards.","s":"Introduction","u":"/standards/","h":"","p":2513},{"i":2516,"t":"SCS certificates come with various scopes. See Scopes and Versions for details.","s":"Certification","u":"/standards/certification/overview","h":"","p":2515},{"i":2518,"t":"In order for a cloud service offering to obtain a certificate, it has to conform to all standards of the respective scope, which will be tested at regular intervals, and the results of these tests will be made available publicly. For more details on how to become certified, please consult the corresponding document.","s":"Becoming certified","u":"/standards/certification/overview","h":"#becoming-certified","p":2515},{"i":2520,"t":"This is a list of clouds that we test on a nightly basis against the certificate scope SCS-compatible IaaS. Name Description Operator IaaS Compliance Check HealthMon gx-scs Dev environment provided for SCS & GAIA-X context plusserver GmbH HM pluscloud open - prod1 - prod2 - prod3 - prod4 Public cloud for customers (4 regions) plusserver GmbH HM1 HM2 HM3 HM4 Wavestack Public cloud for customers noris network AG/Wavecon GmbH HM REGIO.cloud Public cloud for customers OSISM GmbH broken CNDS Public cloud for customers artcodix UG HM aov Community cloud for customers aov IT.Services GmbH (soon) HM PoC WG-Cloud OSBA Cloud PoC for FITKO Cloud&Heat Technologies GmbH HM","s":"Compliant cloud environments","u":"/standards/certification/overview","h":"#compliant-cloud-environments","p":2515},{"i":2522,"t":"SCS provides a certification framework consisting of six different kinds of certificates of varying scope. These scopes can be sorted into two dimensions: certification level, of which there are three: SCS-compatible SCS-open SCS-sovereign cloud layer, of which there are two: infastructure as a service (IaaS) Kubernetes as a service (KaaS) So, for instance, a certificate can have the scope SCS-compatible IaaS or SCS-sovereign KaaS. Each scope corresponds to a set of standards. As these standards progress, so do the scopes, and we keep track of this by versioning. Each version undergoes a lifecycle of Draft, Stable, and Deprecated, and we aim to keep at most one version stable at the same time, with the exception of a transition period of 4 to 6 weeks.","s":"Scopes and versions","u":"/standards/certification/scopes-versions","h":"","p":2521},{"i":2524,"t":"SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision records within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in the development and maintenance of interoperable and transparent cloud infrastructure standards. Version Type State stabilized deprecated scs-0001-v1 Procedural Stable 2022-11-28 -","s":"scs-0001: Sovereign Cloud Standards","u":"/standards/global/scs-0001","h":"","p":2523},{"i":2526,"t":"This track encompasses the foundational standards that guide the overall structure, documentation, and general topics related to the Sovereign Cloud Stack. It serves as the core framework, ensuring consistency, clarity, and comprehensibility across all aspects of the cloud stack, fostering an environment where information is easily accessible and understood. *Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective). Standard Description Draft Stable* Effective Deprecated* scs-0001 Sovereign Cloud Standards - - v1 - scs-0002 Standards, Docs and Organisation v2 - v1 - scs-0003 Sovereign Cloud Standards YAML v1 - - - scs-0004 Regulations for achieving SCS-compatible certification v1 - - - scs-0112 SONiC Support in SCS v1 - - -","s":"Global Standards","u":"/standards/global/","h":"","p":2525},{"i":2528,"t":"Version Type State stabilized deprecated scs-0002-v1 Procedural Stable 2023-02-06 - scs-0002-v2 Procedural Draft - -","s":"scs-0002: Standards, Docs and Organisation","u":"/standards/global/scs-0002","h":"","p":2527},{"i":2530,"t":"SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings, categorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning in a machine-readable YAML format for clarity, traceability, and tool integration. Version Type State stabilized deprecated scs-0003-v1 Procedural Draft - -","s":"scs-0003: Sovereign Cloud Standards YAML","u":"/standards/global/scs-0003","h":"","p":2529},{"i":2532,"t":"Version Type State stabilized deprecated scs-0004-v1 Procedural Draft - -","s":"scs-0004: Regulations for achieving SCS-compatible certification","u":"/standards/global/scs-0004","h":"","p":2531},{"i":2534,"t":"SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration. Version Type State stabilized deprecated scs-0112-v1 Decision Record Draft - -","s":"scs-0112: SONiC Support in SCS","u":"/standards/global/scs-0112","h":"","p":2533},{"i":2536,"t":"The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack environments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM, and Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for usability and portability across all SCS flavors. Version Type State stabilized deprecated scs-0100-v1 Standard Deprecated 2022-09-08 2023-10-31 scs-0100-v2 Standard Deprecated 2023-02-21 2023-11-30 scs-0100-v3 Standard Stable 2023-06-14 -","s":"scs-0100: SCS Flavor Naming Standard","u":"/standards/iaas/scs-0100","h":"","p":2535},{"i":2538,"t":"Version State stabilized deprecated w1 Proposal - -","s":"Supplement: Implementation and Testing Notes","u":"/standards/iaas/scs-0100","h":"#supplement-implementation-and-testing-notes","p":2535},{"i":2540,"t":"The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations such as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and activating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy accessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into virtual instances and ensures the availability and quality of entropy in virtual environments, promoting system security and efficiency. Version Type State stabilized deprecated scs-0101-v1 Standard Stable 2024-02-08 -","s":"scs-0101: SCS Entropy","u":"/standards/iaas/scs-0101","h":"","p":2539},{"i":2542,"t":"Version State stabilized deprecated w1 Proposal - -","s":"Supplement: Implementation and Testing Notes","u":"/standards/iaas/scs-0101","h":"#supplement-implementation-and-testing-notes","p":2539},{"i":2544,"t":"The IaaS Layer Standards track focuses on the protocols, guidelines, and specifications that govern the infrastructure as a service layer. This encompasses standards for virtual machines, storage, networking, and other foundational resources, ensuring seamless, efficient, and secure operation, interoperability, and management of the underlying cloud infrastructure. *Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective). Standard Description Draft Stable* Effective Deprecated* scs-0100 SCS Flavor Naming Standard - - v3 v1, v2 Supplement: Implementation and Testing Notes w1 - - - scs-0101 SCS Entropy - - v1 - Supplement: Implementation and Testing Notes w1 - - - scs-0102 SCS Image Metadata Standard - - v1 - scs-0103 SCS Standard Flavors and Properties - - v1 - scs-0104 SCS Standard Images - - v1 - scs-0110 SSD Flavors - - v1 - scs-0111 Decisions for the Volume Type Standard v1 - - - scs-0113 Security Groups Decision Record v1 - - - scs-0114 Volume Type Standard v1 - - - scs-0115 Default Rules for Security Groups v1 - - -","s":"IaaS Standards","u":"/standards/iaas/","h":"","p":2543},{"i":2546,"t":"The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating system images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements, image handling protocols including updating and origin, and licensing/support details. These guidelines ensure that users can understand, access, and utilize OS images effectively, with clear information on features, updates, and licensing provided through well-defined metadata properties. Version Type State stabilized deprecated scs-0102-v1 Standard Stable 2022-10-31 -","s":"scs-0102: SCS Image Metadata Standard","u":"/standards/iaas/scs-0102","h":"","p":2545},{"i":2548,"t":"The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments, specifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined deployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard's machine-readable document facilitates automated processing for compliance and integration purposes, promoting consistency and reliability in cloud environments. Version Type State stabilized deprecated scs-0104-v1 Standard Stable 2024-02-21 -","s":"scs-0104: SCS Standard Images","u":"/standards/iaas/scs-0104","h":"","p":2547},{"i":2550,"t":"The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack environments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific configurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs:name-vN, scs:cpu-type, and scs:diskN-type to detail the flavor's specifications. This standard facilitates guaranteed availability and consistency of flavors, simplifying the deployment process for DevOps teams. Version Type State stabilized deprecated scs-0103-v1 Standard Stable 2024-02-08 -","s":"scs-0103: SCS Standard Flavors and Properties","u":"/standards/iaas/scs-0103","h":"","p":2549},{"i":2552,"t":"Version Type State stabilized deprecated scs-0113-v1 Decision Record Draft - -","s":"scs-0113: Security Groups Decision Record","u":"/standards/iaas/scs-0113","h":"","p":2551},{"i":2554,"t":"Version Type State stabilized deprecated scs-0110-v1 Decision Record Stable 2023-06-14 -","s":"scs-0110: SSD Flavors","u":"/standards/iaas/scs-0110","h":"","p":2553},{"i":2556,"t":"Version Type State stabilized deprecated scs-0111-v1 Decision Record Draft - -","s":"scs-0111: Decisions for the Volume Type Standard","u":"/standards/iaas/scs-0111","h":"","p":2555},{"i":2558,"t":"Version Type State stabilized deprecated scs-0114-v1 Standard Draft - -","s":"scs-0114: Volume Type Standard","u":"/standards/iaas/scs-0114","h":"","p":2557},{"i":2560,"t":"The Metrics and events we want to use in the metering process can be defined in two ways. The first one is to allow ceilometer to poll distinct metrics and events. This can be achived by setting up ceilometers config files.","s":"Metering Configuration","u":"/docs/operating-scs/metering/meter_configuration","h":"","p":2559},{"i":2562,"t":"there is the polling.yaml file that describes what metrics to poll and when. It allows to create multiple sources for the ceilometer pipeline with different metrics and intervals. ceilometer polling ceilometer polling metrics","s":"1. ceilometer metering configuration","u":"/docs/operating-scs/metering/meter_configuration","h":"#1-ceilometer-metering-configuration","p":2559},{"i":2564,"t":"--- sources: - name: billing_source # 'source name' interval: 300 # 'how often the samples should be generated' meters: - \"volume.size\" # 'meter filter' # - \"*\" # 'using all pollsters in the event_definitions file all data structure of events are defined. If a message with a distinct event_type appears, the Fields and values from the message are matched with the Event-object. ceilometer events ceilometer event_definitions","s":"1.1 polling.yaml","u":"/docs/operating-scs/metering/meter_configuration","h":"#11-pollingyaml","p":2559},{"i":2566,"t":"--- - event_type: \"compute.instance.*\" traits: &instance_traits tenant_id: fields: payload.tenant_id user_id: fields: payload.user_id instance_id: fields: payload.instance_id display_name: fields: payload.display_name resource_id: fields: payload.instance_id cell_name: fields: payload.cell_name host: fields: publisher_id.`split(., 1, 1)` service: fields: publisher_id.`split(., 0, -1)` memory_mb: type: int fields: payload.memory_mb disk_gb: type: int fields: payload.disk_gb root_gb: type: int fields: payload.root_gb ephemeral_gb: type: int fields: payload.ephemeral_gb vcpus: type: int fields: payload.vcpus instance_type_id: fields: payload.instance_type_id instance_type: fields: payload.instance_type state: fields: payload.state os_architecture: fields: payload.image_meta.'org.openstack__1__architecture' os_version: fields: payload.image_meta.'org.openstack__1__os_version' os_distro: fields: payload.image_meta.'org.openstack__1__os_distro' launched_at: type: datetime fields: payload.launched_at deleted_at: type: datetime fields: payload.deleted_at - event_type: compute.instance.create.end traits: <<: *instance_traits availability_zone: fields: payload.availability_zone - event_type: compute.instance.update traits: <<: *instance_traits old_state: fields: payload.old_state - event_type: compute.instance.exists traits: <<: *instance_traits audit_period_beginning: type: datetime fields: payload.audit_period_beginning audit_period_ending: type: datetime fields: payload.audit_period_ending - event_type: [ \"volume.exists\", \"volume.retype\", \"volume.create.*\", \"volume.delete.*\", \"volume.resize.*\", \"volume.attach.*\", \"volume.detach.*\", \"volume.update.*\", \"snapshot.exists\", \"snapshot.create.*\", \"snapshot.delete.*\", \"snapshot.update.*\", \"volume.transfer.accept.end\", \"snapshot.transfer.accept.end\", ] traits: &cinder_traits user_id: fields: payload.user_id project_id: fields: payload.tenant_id availability_zone: fields: payload.availability_zone display_name: fields: payload.display_name replication_status: fields: payload.replication_status status: fields: payload.status created_at: type: datetime fields: payload.created_at image_id: fields: payload.glance_metadata[?key=image_id].value instance_id: fields: payload.volume_attachment[0].server_id - event_type: [ \"volume.transfer.*\", \"volume.exists\", \"volume.retype\", \"volume.create.*\", \"volume.delete.*\", \"volume.resize.*\", \"volume.attach.*\", \"volume.detach.*\", \"volume.update.*\", \"snapshot.transfer.accept.end\", ] traits: <<: *cinder_traits resource_id: fields: payload.volume_id host: fields: payload.host size: type: int fields: payload.size type: fields: payload.volume_type replication_status: fields: payload.replication_status - event_type: [\"snapshot.transfer.accept.end\"] traits: <<: *cinder_traits resource_id: fields: payload.snapshot_id project_id: fields: payload.tenant_id - event_type: [\"share.create.*\", \"share.delete.*\", \"share.extend.*\", \"share.shrink.*\"] traits: &share_traits share_id: fields: payload.share_id user_id: fields: payload.user_id project_id: fields: payload.tenant_id snapshot_id: fields: payload.snapshot_id availability_zone: fields: payload.availability_zone status: fields: payload.status created_at: type: datetime fields: payload.created_at share_group_id: fields: payload.share_group_id size: type: int fields: payload.size name: fields: payload.name proto: fields: payload.proto is_public: fields: payload.is_public description: fields: payload.description host: fields: payload.host - event_type: [ \"snapshot.exists\", \"snapshot.create.*\", \"snapshot.delete.*\", \"snapshot.update.*\", ] traits: <<: *cinder_traits resource_id: fields: payload.snapshot_id volume_id: fields: payload.volume_id - event_type: [\"image_volume_cache.*\"] traits: image_id: fields: payload.image_id host: fields: payload.host - event_type: [\"image.create\", \"image.update\", \"image.upload\", \"image.delete\"] traits: &glance_crud project_id: fields: payload.owner resource_id: fields: payload.id name: fields: payload.name status: fields: payload.status created_at: type: datetime fields: payload.created_at user_id: fields: payload.owner deleted_at: type: datetime fields: payload.deleted_at size: type: int fields: payload.size - event_type: image.send traits: &glance_send receiver_project: fields: payload.receiver_tenant_id receiver_user: fields: payload.receiver_user_id user_id: fields: payload.owner_id image_id: fields: payload.image_id destination_ip: fields: payload.destination_ip bytes_sent: type: int fields: payload.bytes_sent - event_type: orchestration.stack.* traits: &orchestration_crud project_id: fields: payload.tenant_id user_id: fields: [\"ctxt.trustor_user_id\", \"ctxt.user_id\"] resource_id: fields: payload.stack_identity name: fields: payload.name - event_type: sahara.cluster.* traits: &sahara_crud project_id: fields: payload.project_id user_id: fields: ctxt.user_id resource_id: fields: payload.cluster_id name: fields: payload.name - event_type: sahara.cluster.health traits: &sahara_health <<: *sahara_crud verification_id: fields: payload.verification_id health_check_status: fields: payload.health_check_status health_check_name: fields: payload.health_check_name health_check_description: fields: payload.health_check_description created_at: type: datetime fields: payload.created_at updated_at: type: datetime fields: payload.updated_at - event_type: [ \"identity.user.*\", \"identity.project.*\", \"identity.group.*\", \"identity.role.*\", \"identity.OS-TRUST:trust.*\", \"identity.region.*\", \"identity.service.*\", \"identity.endpoint.*\", \"identity.policy.*\", ] traits: &identity_crud resource_id: fields: payload.resource_info initiator_id: fields: payload.initiator.id project_id: fields: payload.initiator.project_id domain_id: fields: payload.initiator.domain_id - event_type: identity.role_assignment.* traits: &identity_role_assignment role: fields: payload.role group: fields: payload.group domain: fields: payload.domain user: fields: payload.user project: fields: payload.project - event_type: identity.authenticate traits: &identity_authenticate typeURI: fields: payload.typeURI id: fields: payload.id action: fields: payload.action eventType: fields: payload.eventType eventTime: type: datetime fields: payload.eventTime outcome: fields: payload.outcome initiator_typeURI: fields: payload.initiator.typeURI initiator_id: fields: payload.initiator.id initiator_name: fields: payload.initiator.name initiator_host_agent: fields: payload.initiator.host.agent initiator_host_addr: fields: payload.initiator.host.address target_typeURI: fields: payload.target.typeURI target_id: fields: payload.target.id observer_typeURI: fields: payload.observer.typeURI observer_id: fields: payload.observer.id - event_type: objectstore.http.request traits: &objectstore_request typeURI: fields: payload.typeURI id: fields: payload.id action: fields: payload.action eventType: fields: payload.eventType eventTime: type: datetime fields: payload.eventTime outcome: fields: payload.outcome initiator_typeURI: fields: payload.initiator.typeURI initiator_id: fields: payload.initiator.id initiator_project_id: fields: payload.initiator.project_id target_typeURI: fields: payload.target.typeURI target_id: fields: payload.target.id target_action: fields: payload.target.action target_metadata_path: fields: payload.target.metadata.path target_metadata_version: fields: payload.target.metadata.version target_metadata_container: fields: payload.target.metadata.container target_metadata_object: fields: payload.target.metadata.object observer_id: fields: payload.observer.id - event_type: [ \"network.*\", \"subnet.*\", \"port.*\", \"router.*\", \"floatingip.*\", \"firewall.*\", \"firewall_policy.*\", \"firewall_rule.*\", \"vpnservice.*\", \"ipsecpolicy.*\", \"ikepolicy.*\", \"ipsec_site_connection.*\", ] traits: &network_traits user_id: fields: ctxt.user_id project_id: fields: ctxt.tenant_id - event_type: network.* traits: <<: *network_traits name: fields: payload.network.name resource_id: fields: [\"payload.network.id\", \"payload.id\"] - event_type: subnet.* traits: <<: *network_traits name: fields: payload.subnet.name resource_id: fields: [\"payload.subnet.id\", \"payload.id\"] - event_type: port.* traits: <<: *network_traits name: fields: payload.port.name resource_id: fields: [\"payload.port.id\", \"payload.id\"] - event_type: router.* traits: <<: *network_traits name: fields: payload.router.name resource_id: fields: [\"payload.router.id\", \"payload.id\"] - event_type: floatingip.* traits: <<: *network_traits resource_id: fields: [\"payload.floatingip.id\", \"payload.id\"] - event_type: firewall.* traits: <<: *network_traits name: fields: payload.firewall.name resource_id: fields: [\"payload.firewall.id\", \"payload.id\"] - event_type: firewall_policy.* traits: <<: *network_traits name: fields: payload.firewall_policy.name resource_id: fields: [\"payload.firewall_policy.id\", \"payload.id\"] - event_type: firewall_rule.* traits: <<: *network_traits name: fields: payload.firewall_rule.name resource_id: fields: [\"payload.firewall_rule.id\", \"payload.id\"] - event_type: vpnservice.* traits: <<: *network_traits name: fields: payload.vpnservice.name resource_id: fields: [\"payload.vpnservice.id\", \"payload.id\"] - event_type: ipsecpolicy.* traits: <<: *network_traits name: fields: payload.ipsecpolicy.name resource_id: fields: [\"payload.ipsecpolicy.id\", \"payload.id\"] - event_type: ikepolicy.* traits: <<: *network_traits name: fields: payload.ikepolicy.name resource_id: fields: [\"payload.ikepolicy.id\", \"payload.id\"] - event_type: ipsec_site_connection.* traits: <<: *network_traits resource_id: fields: [\"payload.ipsec_site_connection.id\", \"payload.id\"] - event_type: \"*http.*\" traits: &http_audit project_id: fields: payload.initiator.project_id user_id: fields: payload.initiator.id typeURI: fields: payload.typeURI eventType: fields: payload.eventType action: fields: payload.action outcome: fields: payload.outcome id: fields: payload.id eventTime: type: datetime fields: payload.eventTime requestPath: fields: payload.requestPath observer_id: fields: payload.observer.id target_id: fields: payload.target.id target_typeURI: fields: payload.target.typeURI target_name: fields: payload.target.name initiator_typeURI: fields: payload.initiator.typeURI initiator_id: fields: payload.initiator.id initiator_name: fields: payload.initiator.name initiator_host_address: fields: payload.initiator.host.address - event_type: \"*http.response\" traits: <<: *http_audit reason_code: fields: payload.reason.reasonCode - event_type: [\"dns.domain.create\", \"dns.domain.update\", \"dns.domain.delete\"] traits: &dns_domain_traits status: fields: payload.status retry: fields: payload.retry description: fields: payload.description expire: fields: payload.expire email: fields: payload.email ttl: fields: payload.ttl action: fields: payload.action name: fields: payload.name resource_id: fields: payload.id created_at: type: datetime fields: payload.created_at updated_at: type: datetime fields: payload.updated_at version: fields: payload.version parent_domain_id: fields: parent_domain_id serial: fields: payload.serial - event_type: dns.domain.exists traits: <<: *dns_domain_traits audit_period_beginning: type: datetime fields: payload.audit_period_beginning audit_period_ending: type: datetime fields: payload.audit_period_ending - event_type: trove.* traits: &trove_base_traits instance_type: fields: payload.instance_type user_id: fields: payload.user_id resource_id: fields: payload.instance_id instance_type_id: fields: payload.instance_type_id launched_at: type: datetime fields: payload.launched_at instance_name: fields: payload.instance_name state: fields: payload.state nova_instance_id: fields: payload.nova_instance_id service_id: fields: payload.service_id created_at: type: datetime fields: payload.created_at region: fields: payload.region - event_type: [ \"trove.instance.create\", \"trove.instance.modify_volume\", \"trove.instance.modify_flavor\", \"trove.instance.delete\", ] traits: &trove_common_traits name: fields: payload.name availability_zone: fields: payload.availability_zone instance_size: type: int fields: payload.instance_size volume_size: type: int fields: payload.volume_size nova_volume_id: fields: payload.nova_volume_id - event_type: trove.instance.create traits: <<: [*trove_base_traits, *trove_common_traits] - event_type: trove.instance.modify_volume traits: <<: [*trove_base_traits, *trove_common_traits] old_volume_size: type: int fields: payload.old_volume_size modify_at: type: datetime fields: payload.modify_at - event_type: trove.instance.modify_flavor traits: <<: [*trove_base_traits, *trove_common_traits] old_instance_size: type: int fields: payload.old_instance_size modify_at: type: datetime fields: payload.modify_at - event_type: trove.instance.delete traits: <<: [*trove_base_traits, *trove_common_traits] deleted_at: type: datetime fields: payload.deleted_at - event_type: trove.instance.exists traits: <<: *trove_base_traits display_name: fields: payload.display_name audit_period_beginning: type: datetime fields: payload.audit_period_beginning audit_period_ending: type: datetime fields: payload.audit_period_ending - event_type: profiler.* traits: project: fields: payload.project service: fields: payload.service name: fields: payload.name base_id: fields: payload.base_id trace_id: fields: payload.trace_id parent_id: fields: payload.parent_id timestamp: type: datetime fields: payload.timestamp host: fields: payload.info.host path: fields: payload.info.request.path query: fields: payload.info.request.query method: fields: payload.info.request.method scheme: fields: payload.info.request.scheme db.statement: fields: payload.info.db.statement db.params: fields: payload.info.db.params - event_type: \"magnum.cluster.*\" traits: &magnum_cluster_crud id: fields: payload.id typeURI: fields: payload.typeURI eventType: fields: payload.eventType eventTime: type: datetime fields: payload.eventTime action: fields: payload.action outcome: fields: payload.outcome initiator_id: fields: payload.initiator.id initiator_typeURI: fields: payload.initiator.typeURI initiator_name: fields: payload.initiator.name initiator_host_agent: fields: payload.initiator.host.agent initiator_host_address: fields: payload.initiator.host.address target_id: fields: payload.target.id target_typeURI: fields: payload.target.typeURI observer_id: fields: payload.observer.id observer_typeURI: fields: payload.observer.typeURI - event_type: \"alarm.*\" traits: id: fields: payload.alarm_id user_id: fields: payload.user_id project_id: fields: payload.project_id on_behalf_of: fields: payload.on_behalf_of severity: fields: payload.severity detail: fields: payload.detail type: fields: payload.type The event_pipeline can be used to filter events and pipeline them to different publishers. the notifier publisher is the message queue broadcasster (RabbitMQ).","s":"1.2 event_definitions.yaml","u":"/docs/operating-scs/metering/meter_configuration","h":"#12-event_definitionsyaml","p":2559},{"i":2568,"t":"--- sources: - name: event_source # 'source name' events: - \"*\" # 'event filter' sinks: - event_sink # 'sink name' sinks: - name: event_sink # 'sink name' publishers: # 'list of publishers' - notifier:// - http://localhost:8088/post_json The pipeline.yaml can be used to filter and pipeline all metrics and events since events send via the notifier also appears in the meters and send them to different publishers. In our case we want to push to the metering api.","s":"1.3 event_pipeline.yaml","u":"/docs/operating-scs/metering/meter_configuration","h":"#13-event_pipelineyaml","p":2559},{"i":2570,"t":"--- sources: - name: meter_source meters: - \"*\" sinks: - meter_sink sinks: - name: meter_sink publishers: - gnocchi://?archive_policy=ceilometer-low&filter_project=service - http://localhost:8088/post_json","s":"1.4 pipeline.yaml","u":"/docs/operating-scs/metering/meter_configuration","h":"#14-pipelineyaml","p":2559},{"i":2572,"t":"Version Type State stabilized deprecated scs-0115-v1 Standard Draft - -","s":"scs-0115: Default Rules for Security Groups","u":"/standards/iaas/scs-0115","h":"","p":2571},{"i":2574,"t":"This track revolves around Identity and Access Management (IAM) standards, providing guidelines for ensuring secure and efficient user authentication, authorization, and administration. It addresses issues related to user identity, permissions, roles, and policies, aiming to safeguard and streamline access to cloud resources and services. *Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective). Standard Description Draft Stable* Effective Deprecated* scs-0300 Requirements for SSO identity federation - - v1 - scs-0301 Naming for domains/groups/roles/project when onboarding new customers v1 - - - scs-0302 Domain Manager configuration for Keystone v1 - - -","s":"IAM Standards","u":"/standards/iam/","h":"","p":2573},{"i":2576,"t":"The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign Cloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed externally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard focuses on delegating authentication to external identity providers and mapping users to roles within SCS for authorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity Provider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible. Version Type State stabilized deprecated scs-0300-v1 Decision Record Stable 2023-06-21 -","s":"scs-0300: Requirements for SSO identity federation","u":"/standards/iam/scs-0300","h":"","p":2575},{"i":2578,"t":"Version Type State stabilized deprecated scs-0302-v1 Standard Draft - -","s":"scs-0302: Domain Manager configuration for Keystone","u":"/standards/iam/scs-0302","h":"","p":2577},{"i":2580,"t":"Version Type State stabilized deprecated scs-0301-v1 Decision Record Draft - -","s":"scs-0301: Naming for domains/groups/roles/project when onboarding new customers","u":"/standards/iam/scs-0301","h":"","p":2579},{"i":2582,"t":"Version Type State stabilized deprecated scs-0200-v1 Decision Record Draft - -","s":"scs-0200: Using Sonobuoy for KaaS conformance tests","u":"/standards/kaas/scs-0200","h":"","p":2581},{"i":2584,"t":"Version Type State stabilized deprecated scs-0210-v1 Standard Deprecated 2023-02-07 2024-02-08 scs-0210-v2 Standard Stable 2024-02-08 -","s":"scs-0210: SCS K8S Version Policy","u":"/standards/kaas/scs-0210","h":"","p":2583},{"i":2586,"t":"The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS). The standard ensures that the default StorageClass, identified by the \"storageclass.kubernetes.io/is-default-class\" annotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or host hardware failures. Version Type State stabilized deprecated scs-0211-v1 Standard Stable 2023-02-13 -","s":"scs-0211: SCS KaaS default storage class","u":"/standards/kaas/scs-0211","h":"","p":2585},{"i":2588,"t":"Version Type State stabilized deprecated scs-0212-v1 Standard Draft - -","s":"scs-0212: Requirements for container registries","u":"/standards/kaas/scs-0212","h":"","p":2587},{"i":2590,"t":"Version Type State stabilized deprecated scs-0213-v1 Decision Record Draft - -","s":"scs-0213: Kubernetes Nodes Anti Affinity","u":"/standards/kaas/scs-0213","h":"","p":2589},{"i":2592,"t":"Standards in this track are concerned with Kubernetes as a Service layer, outlining norms and best practices for deploying, managing, and operating Kubernetes clusters. These standards aim to ensure that the orchestration of containers is streamlined, secure, and compatible across various cloud environments and platforms. *Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective). Standard Description Draft Stable* Effective Deprecated* scs-0200 Using Sonobuoy for KaaS conformance tests v1 - - - scs-0210 SCS K8S Version Policy - - v2 v1 scs-0211 SCS KaaS default storage class - - v1 - scs-0212 Requirements for container registries v1 - - - scs-0213 Kubernetes Nodes Anti Affinity v1 - - - scs-0214 Kubernetes Node Distribution and Availability - - v1 - scs-0215 Robustness features for Kubernetes clusters v1 - - - scs-0216 Requirements for testing cluster-stacks v1 - - - scs-0217 Kubernetes cluster baseline security v1 - - - scs-0218 Container registry for SCS standard implementation v1 - - -","s":"KaaS Standards","u":"/standards/kaas/","h":"","p":2591},{"i":2594,"t":"Version Type State stabilized deprecated scs-0214-v1 Standard Stable 2024-02-08 -","s":"scs-0214: Kubernetes Node Distribution and Availability","u":"/standards/kaas/scs-0214","h":"","p":2593},{"i":2596,"t":"Version Type State stabilized deprecated scs-0217-v1 Standard Draft - -","s":"scs-0217: Kubernetes cluster baseline security","u":"/standards/kaas/scs-0217","h":"","p":2595},{"i":2598,"t":"Version Type State stabilized deprecated scs-0218-v1 Decision Record Draft - -","s":"scs-0218: Container registry for SCS standard implementation","u":"/standards/kaas/scs-0218","h":"","p":2597},{"i":2600,"t":"Version Type State stabilized deprecated scs-0215-v1 Standard Draft - -","s":"scs-0215: Robustness features for Kubernetes clusters","u":"/standards/kaas/scs-0215","h":"","p":2599},{"i":2602,"t":"Operational Tooling Standards cover the protocols and guidelines associated with tools and utilities used for monitoring, management, and maintenance of the cloud environment. This includes standards for status pages, alerts, logs, and other operational tools, aiming to optimize the reliability, performance, and security of cloud services and resources. *Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective). Standard Description Draft Stable* Effective Deprecated* scs-0400 Status Page create decision v1 - - - scs-0401 Status page reference implementation decision v1 - - - scs-0402 Status page OpenAPI decision v1 - - - scs-0403 Architecture for the Cloud Service provider Observability System for the KaaS Layer v1 - - - scs-0410 Gnocchi as database for metering v1 - - - scs-0411 Push-based approach for providing usage data v1 - - - scs-0412 Exposition of IaaS metering data as JSON v1 - - -","s":"Ops Standards","u":"/standards/ops/","h":"","p":2601},{"i":2604,"t":"Version Type State stabilized deprecated scs-0216-v1 Decision Record Draft - -","s":"scs-0216: Requirements for testing cluster-stacks","u":"/standards/kaas/scs-0216","h":"","p":2603},{"i":2606,"t":"Version Type State stabilized deprecated scs-0400-v1 Decision Record Draft - -","s":"scs-0400: Status Page create decision","u":"/standards/ops/scs-0400","h":"","p":2605},{"i":2608,"t":"Version Type State stabilized deprecated scs-0401-v1 Decision Record Draft - -","s":"scs-0401: Status page reference implementation decision","u":"/standards/ops/scs-0401","h":"","p":2607},{"i":2610,"t":"Version Type State stabilized deprecated scs-0410-v1 Decision Record Draft - -","s":"scs-0410: Gnocchi as database for metering","u":"/standards/ops/scs-0410","h":"","p":2609},{"i":2612,"t":"Version Type State stabilized deprecated scs-0402-v1 Decision Record Draft - -","s":"scs-0402: Status page OpenAPI decision","u":"/standards/ops/scs-0402","h":"","p":2611},{"i":2614,"t":"Version Type State stabilized deprecated scs-0411-v1 Decision Record Draft - -","s":"scs-0411: Push-based approach for providing usage data","u":"/standards/ops/scs-0411","h":"","p":2613},{"i":2617,"t":"The Sovereign Cloud Stack (SCS) provides standards for a range of cloud infrastructure types. It strives for interoperable and sovereign cloud stacks which can be deployed and used by a wide range of organizations and individuals. Wherever feasible, transparency and openness both in respect to the inner workings of the platforms standardised by SCS, as well as the SCS organisation itself are a paradigm we intend to live.","s":"Introduction","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#introduction","p":2615},{"i":2619,"t":"The key words \"MUST\", \"MUST NOT\", \"REQUIRED\", \"SHALL\", \"SHALL NOT\", \"SHOULD\", \"SHOULD NOT\", \"RECOMMENDED\", \"MAY\", and \"OPTIONAL\" in this document are to be interpreted as described in RFC 2119. In addition, \"FORBIDDEN\" is to be interpreted equivalent to \"MUST NOT\".","s":"Requirements","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#requirements","p":2615},{"i":2621,"t":"One of the main products of the SCS organisation are Sovereign Cloud Standard documents.","s":"Sovereign Cloud Standard documents","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#sovereign-cloud-standard-documents","p":2615},{"i":2623,"t":"Procedural​ A procedural SCS document describes a process, a policy or a guideline to which the SCS community adheres. Standard​ A standard SCS document describes a technical standard for SCS compliant clouds. Note that it may not be necessary for all clouds to implement all standards. Decision Record​ Sometimes during the development of the SCS standard, a complex technical decision needs to be taken, which does not directly result in a new standard. The SCS document format formally integrates the documentation of such decisions as documents of type Decision Record. Supplement​ A supplement extends a Standard with additional information, such as implementation and testing notes, that is merely informative, but not authoritative, and that may be subject to change more frequently than the standard itself.","s":"Types of documents","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#types-of-documents","p":2615},{"i":2625,"t":"The SCS documents are provided in GitHub flavored markdown. Each document is assigned a unique number. To disambiguate with other organisations using similar schemes (such as XEPs, PEPs or IETF RFCs), the numbers are prefixed with SCS-. To allow a concept to evolve while allowing breaking changes, each SCS document is associated with a major version number. This major version number is a positive number and the numbering starts at one for each document. In order to make organisation of the SCS documents easier, each document also has a slugified title. The slugified title MUST NOT be changed after the acceptance of the document into the repository, as it is part of its canonical URL. It MUST consist only of lower-case ASCII letters, numbers and hyphens. It MUST NOT start with a hyphen and SHOULD start with a lower-case letter. It SHOULD NOT contain more than one subsequent hyphen. The file name of an SCS document is formed using the following pattern: scs-XXXX-vN-T.md, where XXXX is replaced with the zero-padded document number, N is replaced with the major version of the document, and T is replaced with the slugified title. For a document with the number 190, with a major version number 2 and a slugified title flavor-naming, the resulting file name would be scs-0190-v2-flavor-naming.md. Supplements deviate from this pattern in that they employ a w instead of a v in front of the version number, and each supplement uses the same document number as the main document it is extending. The second digit in XXXX describes the track where the document belongs: Track Number Global 0 IaaS 1 KaaS 2 IAM 3 Ops 4 In addition to the number, each document has the following metadata, embedded in the markdown header. Field name Requirement Description type REQUIRED one of Procedural, Standard, Decision Record, or Supplement status REQUIRED one of Proposal, Draft, Stable, Deprecated, or Rejected track REQUIRED one of Global, IaaS, KaaS, IAM, Ops supplements REQUIRED precisely when type is Supplement list of documents that are extended by this document (e.g., multiple major versions) deprecated_at REQUIRED if status is Deprecated ISO formatted date indicating the date after which the deprecation is in effect stabilized_at REQUIRED if status was ever Stable ISO formatted date indicating the date after which the document was considered stable rejected_at REQUIRED if status is Rejected ISO formatted date indicating the date on which the document was rejected replaced_by RECOMMENDED if status is Deprecated or Rejected, FORBIDDEN otherwise List of documents which replace this document. replaces OPTIONAL List of documents which this document replaces.","s":"Document format","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#document-format","p":2615},{"i":2627,"t":"Standard​ Each Standard document MUST have the following sections: An Introduction providing context on the document and linking to other relevant materials. A Motivation section which details why this document or the thing it describes is necessary. A section containing the actual standardization decision. A Conformance Tests section that contains hints on how to validate conformance with this spec, ideally links to conformance test cases. We also RECOMMEND the following sections: A Terminology section which briefly describes terms used in the document, including possible abbreviations. In addition, the following OPTIONAL sections should be considered: A Design Considerations section for Standard type documents, which details other choices which have been considered for the specific feature but were ultimately rejected. An Open Questions section which links to issues detailing any open discussion points with respect to a document. This section is RECOMMENDED during the discussion phase (pre 1.0.0) as a \"table of contents\" of things to work on in that context. A Related Documents section which references related Standards or Decisions, both upstream and/or other SCS documents. Decision Record​ Each Decision Record document MUST have the following sections: An Abstract providing a brief introduction on the topic of the document. A Context section describing the issue relevant for motivating this Decision Record. A section containing the actual decision that is introduced. The section should also include reasoning for this decision. We also RECOMMEND the following sections: A Terminology section which shortly describes terms used in the document, including possible abbreviations. A Related Documents section which references related Standards or Decisions, both upstream and/or other SCS documents. In addition, the following OPTIONAL sections should be considered: A Consequences section describing outcomes from implementing the changes described.","s":"Sections","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#sections","p":2615},{"i":2629,"t":"The lifecycle of an SCS document goes through the following phases: Proposal, Draft, Stable, Deprecated, and Rejected. All decisions for phase transitions follow loose consensus, where the group which has to form the consensus depends on the track of the document: IaaS: The team working on infrastructure-as-a-service topics KaaS: The team working on Kubernetes-as-a-service topics Ops: The team working on operations topics IAM: The team working on identity and access management topics Global: The entire SCS community Supplements may be kept in Draft state, because they are not authoritative.","s":"Process","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#process","p":2615},{"i":2631,"t":"Proposal of a new document​ To propose a new SCS document, a community participant creates a pull request on GitHub against the standards repository in the SovereignCloudStack organisation. The pull request MUST add exactly one SCS document, in the Standards folder. In the proposal phase, the document number MUST be replaced with xxxx in the file name, except for a Supplement, which uses the document number of the document it refers to. The major version MUST be 1. For a document with a slugified title flavor-naming, the file name would for instance be scs-xxxx-v1-flavor-naming.md; for a Supplement of scs-0100-v3-flavor-naming.md, the file name might be scs-0100-w1-flavor-naming-implementation-testing.md (note the w1!). The metadata MUST indicate the intended track and type of the document, and the status MUST be set to Proposal; for a Supplement, the supplements field MUST be set to a list of documents (usually containing one element). Upon acceptance by the group of people identified by the track, a number is assigned (the next unused number) and the proposer is asked to rename the file to replace the xxxx with that number. Note: Documents on the Design Record track MAY be proposed or accepted directly into Stable state, if no further discussion is required. Hereafter, the pull request can be merged and henceforth the document is an official SCS document in Draft state. Proposal of a major update to a stable document​ To propose major update to a Stable SCS document, a community participant creates a pull request on GitHub against the standards repository in the SovereignCloudStack organisation. The pull request MUST add exactly one SCS document, in the Standards folder. The document number MUST be the same as the document it is updating, and the major version number MUST be incremented by 1. The slugified title MAY be changed. It MUST refer to the old document in its replaces metadata. The pull request SHOULD NOT modify the previous document; deprecation of the previous document as well as adding the replaced_by metadata is a separate step, and can only be executed once the new document is Stable. For a document updating a hypothetical SCS-0390-v3 document, the file name may be scs-0390-v4-flavor-naming-this-time-its-serious.md. Other than the file naming difference, the proposal process is the same as for new documents. In particular, the new document starts out in Draft state and does not automatically become part of the normative corpus of an SCS release.","s":"Proposal phase","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#proposal-phase","p":2615},{"i":2633,"t":"In this phase, the document is developed inside the SCS community. It should not be considered to be normative for any SCS release, even if an SCS release happens after the acceptance of the document. Experimental and exploratory implementations are encouraged, however, implementors must be prepared for breaking changes. Changes to the documents are gated through pull requests.","s":"Development phase (Draft)","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#development-phase-draft","p":2615},{"i":2635,"t":"Once the document is deemed ready for production use, its status is changed to Stable. If the document in question is a Standard (and if applicable), the following conditions MUST all be satisfied before stabilizing: the corresponding conformance tests have been implemented according to the general guidelines, they have been shown to work with the reference implementation, they are documented in the standard or one of its Supplement documents. After stabilization, changes to the document which may render existing implementations non-conformant MUST NOT be made. If a breaking change to an existing SCS document is deemed necessary, a new document with a new number shall be created and the old document SHOULD be deprecated.","s":"Stabilized phase (Stable)","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#stabilized-phase-stable","p":2615},{"i":2637,"t":"Should a document become obsolete, it can be deprecated. Obsoletions SHOULD be announced ahead of their execution by setting the deprecated_at field to a future date and moving the status to Deprecated. This signals current and future implementors that the subject matter of the document is not considered necessary or state of the art anymore. If one or more replacement documents for the document exists, it MUST be listed in the replaced_by metadata field.","s":"Deprecation phase (Deprecated)","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#deprecation-phase-deprecated","p":2615},{"i":2639,"t":"If a document is removed from the normative corpus of SCS standards, its status is changed to Rejected. If one or more replacement documents for the document exists, it MUST be listed in the replaced_by metadata field.","s":"Rejection","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#rejection","p":2615},{"i":2642,"t":"When should a document be stabilized? Should we require at least one public implementation? Should we require a minimum experimental time? What about non-Standard track documents?","s":"Stabilization criteria","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#stabilization-criteria","p":2615},{"i":2644,"t":"When is a change breaking and cannot be applied to a Stable document? What about previously undefined behaviour (uncovered edge case)? What about ambiguous wording? Do we need a separate \"Errata\" section?","s":"Breaking change criteria","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#breaking-change-criteria","p":2615},{"i":2647,"t":"An alternative to the proposed scheme for stabilization is the use of SemVer-like versioning. In that case, one would have an individual version number with each document, where a major version greater than zero indicates a stable document. The Stable state would be merged with Draft state into an Active state and shared between the stabilized and the development phase. The advantages of such an approach are: It is easy to recognize whether an SCS document has changed between two SCS releases, just by looking at the released version number. It is possible to make breaking changes after stabilization by increasing the major version number. The disadvantages of that approach are: It is possible to make breaking changes after stabilization. Potentially, an hypothetical SCS-1234 document might refer to something completely different in a hypothetical R15 release than what it meant in R5, if there have been sufficient, gradual breaking changes to the document. That means that for proper linking, it would be required to always include the major version number when referring to an SCS document. This implies having to keep all former versions around in a canonical, linkable form. This induces non-trivial organizational and editorial overhead and raises questions around which changes are acceptable to \"archived\" versions, if any. It would require a clone of the SemVer spec, as that spec is highly specific toward software and does not fully (at least not in the standard-as-written) cover specifics of a standards organisation's use-cases.","s":"Versioning","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#versioning","p":2615},{"i":2649,"t":"This document is heavily inspired by XEP-0001, as published by the XMPP Standards Foundation.","s":"Acknowledgements","u":"/standards/scs-0001-v1-sovereign-cloud-standards","h":"#acknowledgements","p":2615},{"i":2651,"t":"The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format within the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with their existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format provided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation layers and implementation components. Version Type State stabilized deprecated scs-0412-v1 Standard Draft - -","s":"scs-0412: Exposition of IaaS metering data as JSON","u":"/standards/ops/scs-0412","h":"","p":2650},{"i":2653,"t":"Version Type State stabilized deprecated scs-0403-v1 Decision Record Draft - -","s":"scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer","u":"/standards/ops/scs-0403","h":"","p":2652},{"i":2656,"t":"The old Docs repository had a subdirectory Design-Docs/ which holds Docs on Design Considerations, older Architecture Decision Records (ADRs) and even Standards. It also has a Design-Docs/tools/ subdirectory with conformance checks and our overall conformance check driver (from PR#182).","s":"Introduction","u":"/standards/scs-0002-v1-standards-docs-org","h":"#introduction","p":2654},{"i":2658,"t":"This directory structure is confusing in a number of ways: The conformance checks are hard to find. The mixture of document types requires searching at two or three places. We want to improve this (while avoiding unnecessary churn).","s":"Motivation","u":"/standards/scs-0002-v1-standards-docs-org","h":"#motivation","p":2654},{"i":2660,"t":"Move Design-Docs/tools/ contents to Tests/ Also create subdirectories then for layers and test, while the overall conformance check tool, certification specs and README remain in Tests/. Rename Design-Docs/ to Drafts/. Use individual PRs to rewrite existing ADRs and Standards there to conform to our standards and move them over to Standards/. Some documents with findings will remain in the Drafts directory. We may want to categorize these and have a folder e.g. for research results.","s":"Suggested cleanup (step 1)","u":"/standards/scs-0002-v1-standards-docs-org","h":"#suggested-cleanup-step-1","p":2654},{"i":2663,"t":"The Sovereign Cloud Stack (SCS) is a complex ecosystem, comprised of numerous Components and packages designed to accommodate a wide array of use cases. Given the unique functionalities of these components, the creation of a unified and comprehensible documentation presents a significant challenge. This procedural standard aims to define the structure and maintenance process for our documentation, thereby offering seamless and efficient access to users.","s":"Introduction","u":"/standards/scs-0002-v2-standards-docs-org","h":"#introduction","p":2661},{"i":2665,"t":"SCS promotes a collaborative environment by actively contributing to upstream projects. The involvement of individuals and companies within our community significantly enhances the SCS Bill of Materials (BOM), further amplifying its complexity. Consequently, our documentation must: Offer an overview and visual representation of the architectural model Foster coherence by maintaining a consistent theme throughout the documentation Facilitate a transparent and inclusive community environment Describe various deployment examples and use cases Reflect the SCS structure in the documentation's navigation","s":"Motivation","u":"/standards/scs-0002-v2-standards-docs-org","h":"#motivation","p":2661},{"i":2667,"t":"In line with the OpenStack documentation approach, most SCS Components and components maintain independent documentation. To keep this documentation up-to-date and eliminate manual duplication, we utilize a custom workflow that synchronizes individual documents during the static documentation page's build process.","s":"Distributed Documentation","u":"/standards/scs-0002-v2-standards-docs-org","h":"#distributed-documentation","p":2661},{"i":2669,"t":"Addressing the complexity of SCS requires an effective documentation structure. Accordingly, we have adopted the Diataxis taxonomy, categorizing the documentation into four distinct sections: Tutorials, Guides, References, and Explanations.","s":"Methodology and Taxonomy","u":"/standards/scs-0002-v2-standards-docs-org","h":"#methodology-and-taxonomy","p":2661},{"i":2671,"t":"The technical documentation and navigation should parallel the logical structure of the SCS Architecture. By doing so, users can better comprehend the information hierarchy and effectively visualize the SCS. The proposed structure is as follows: ├── Introduction ├── Getting Started │ ├── Overview │ ├── Virtualization │ └── Containerization ├── IaaS Layer │ ├── Overview │ │ ├── Architecture │ │ ├── Compute │ │ ├── Storage │ │ ├── Knowledge │ │ └── Network │ ├── Deployment Examples │ │ ├── Example 1 │ │ │ ├── Hardware │ │ │ └── Software │ │ ├── ... │ │ │ ├── Hardware │ │ │ └── Software │ │ └── Example x │ │ ├── Hardware │ │ └── Software │ ├── Guides │ │ ├── Guide 1 │ │ ├ ... │ │ └── Guide x │ └── Components │ ├── Component 1 │ ├ ... │ └── Component x ├── Container Layer │ ├── Overview │ │ ├── Architecture │ │ └── ... │ ├── Prerequisites │ │ ├── Hardware │ │ ├── Software │ │ └── Knowledge │ ├── Guides │ │ ├── Guide 1 │ │ ├── ... │ │ └── Guide x │ └── Components │ ├── k8s-cluster-api-provider │ ├ ... │ └── Component x ├── Operating SCS │ ├── Overview │ ├── Guides │ │ ├── Guide 1 │ │ ├── ... │ │ └── Guide x │ ├── Monitoring │ ├── Incident Management │ ├── Audits │ ├── Lifecycle Management: Patches/Updates & Upgrades │ └── Logging ├── Identity and Access Management (IAM) ├── Releases ├── Standards ├── FAQ └── Glossary","s":"Structure Template","u":"/standards/scs-0002-v2-standards-docs-org","h":"#structure-template","p":2661},{"i":2673,"t":"The technical documentation and navigation should parallel the logical structure of the SCS Architecture. By doing so, users can better comprehend the information hierarchy and effectively visualize the SCS. The proposed structure is as follows: │ ├── Component │ │ ├── overview.md │ │ └── requirements.md │ │ ├── quickstart.md │ │ ├── configuration.md │ │ ├── contribute.md Each document serves a specific purpose: Overview​ This document introduces the Component/component by addressing the basic \"Why,\" \"How,\" and \"What\" questions, and articulating the problems it solves in the broader SCS context answering the following questions: What is it and for what do I need this? What benefits does it have for users? What organization/company does this belong to? (Link to company/organization) Where am I – as module – within the bigger context of SCS? Requirements​ This section enumerates the necessary prerequisites to utilize the component, including software, hardware, and any required technical knowledge. What are the minimal requirements needed for a quickstart? Quickstart​ A concise guide providing users with a quick set up of the component, covering installation instructions, basic configuration, and initial steps. Caution: it is only for testing and not for production. What is the aim of this quickstart guide? Rule: one line per command for easy copy&paste and one line for description where possible Rule: only one working path for installation. Configuration​ This section elaborates on the configurable aspects of the component, such as options, parameters, or settings that users can modify to suit their needs. Contribute​ This document provides instructions on how interested parties can contribute to the component's development. It includes information on issue submission, proposed changes, and participation in discussions.","s":"Single Component/Component","u":"/standards/scs-0002-v2-standards-docs-org","h":"#single-componentcomponent","p":2661},{"i":2675,"t":"SCS employs Docusaurus, a contemporary static website generator, to implement the Docs Standard. Docusaurus serves as an ideal platform for creating, managing, and deploying extensive documentation. Documentation Framework​ Docusaurus' robust toolkit assists in crafting and maintaining quality documentation. It offers comprehensive features such as Markdown support, customizable themes, and versioning, making it an excellent choice for our needs. This platform allows us to create user-friendly and visually engaging documentation. Special Implementation Details​ SCS's unique architecture necessitates a unique approach to documentation. To ensure seamless integration of reference documentation for Components and components developed for SCS, we have created a custom workflow. This workflow automatically syncs upstream repositories, pulling the most recent documentation at regular intervals. We have accomplished this by utilizing a Node.js post-install script found here. This script prompts the system to pull the latest docs every eight hours and build the static page. The workflow's specifications can be viewed here. The SCS documentation is built by the tooling from the docs-page repository, pulling content from docs repository as well as many other components as defined in the docs.package.json here.","s":"Technical Implementation","u":"/standards/scs-0002-v2-standards-docs-org","h":"#technical-implementation","p":2661},{"i":2677,"t":"Formatting and Linting​ All documentation text files must be provided as markdown files with an .md extension. This prerequisite ensures uniformity across our documents, making them more accessible and comprehensible. Diagrams, Charts, and Images​ When necessary, diagrams, charts, and images can be used to simplify complex information. They should be properly captioned and referenced in the text. Linting​ To maintain a clean and consistent content repository, we enforce linting on: All staged files before committing All Pull Requests Pre Commit​ We run markdownlint against staged Git files using the Husky Git hook. This process is facilitated by lint-staged and husky. The markdown files are linted according to the rules specified by markdownlint-cli2 and formatted with prettier. The linting rules are specified in the configuration file .markdownlint-cli2.jsonc. Additionally, markdownlint-rule-search-replace GitHub Workflows​ There are two actions running on every Pull Request on the main branch: link-validator.yml validates every link in the markdown files. pr-markdownlint.yml checks all markdown files according to the rules defined within .markdownlint-cli2.jsonc. The Style Guide can be found here.","s":"Writing Style and Format – Style Guide","u":"/standards/scs-0002-v2-standards-docs-org","h":"#writing-style-and-format--style-guide","p":2661},{"i":2679,"t":"--","s":"Open Questions","u":"/standards/scs-0002-v2-standards-docs-org","h":"#open-questions","p":2661},{"i":2681,"t":"--","s":"Reference","u":"/standards/scs-0002-v2-standards-docs-org","h":"#reference","p":2661},{"i":2684,"t":"The Sovereign Cloud Stack (SCS) issues certificates with various scopes, among them SCS-compatible IaaS (infrastructure as a service) and SCS-compatible KaaS (Kubernetes as a service). This document details how a cloud service provider (henceforth also called operator) can attain such a certificate for one of their clouds.","s":"Introduction","u":"/standards/scs-0004-v1-achieving-certification","h":"#introduction","p":2682},{"i":2686,"t":"As operator, I want to obtain a certificate with the scope SCS-compatible IaaS or SCS-compatible KaaS.","s":"Motivation","u":"/standards/scs-0004-v1-achieving-certification","h":"#motivation","p":2682},{"i":2688,"t":"Each certificate issued pertains to a given cloud, a given scope, and a given version of that scope with a fixed expiry date. The certificate is only valid for that cloud and for the time frame that ends on that expiry date. The operator MUST include the official SCS compliance test suite (which does not require admin privileges) in their continuous test infrastructure (e.g., Zuul). The tests MUST be run at given intervals, depending on their resource-usage classification: light: at least nightly, medium: at least weekly, heavy: at least monthly. For public clouds, it is recommended to offer the SCS project access to the infrastructure so the test suite runs can be triggered continuously by the SCS team. Alternatively, and for non-public clouds, the results (log files) MUST be submitted to SCS (by a mechanism of SCS' choice) at least weekly, and they need to be reproduced again on request by SCS. If the desired certificate requires manual checks, then the operator MUST offer the SCS project suitable access. Manual checks MUST be repeated once every quarter. Details on the standards achieved, as well as the current state and the history of all test and check results of the past 18 months will be displayed on a public webpage (henceforth, certificate status page) owned by SCS. The page will be kept online for the duration of the certificate's validity, plus at least 3 months; afterwards, it can be taken offline, either upon request or in the course of maintenance cleanup. However, the page's content won't be deleted until 12 months after the certificate's expiration, for the page will be reanimated and reused if, within this timeframe, a new certificate is issued for the same scope and the same cloud. The SCS certification assessment body (initially the SCS project in the OSB Alliance e.V., possibly further entities empowered to do so by the SCS trademark owner, currently the OSB Alliance e.V.) WILL review the certification application and either grant the certification, reject it or ask for further measures or information. Once the certificate is granted by the SCS certification assessment body, the operator SHOULD use the corresponding logo and publicly state the certified \"SCS compatibility\" on the respective layer for the time of the validity of the certification. In case of a public cloud, this public display is even REQUIRED. In any case, the logo MUST be accompanied by a hyperlink (a QR code for printed assets) to the respective certificate status page. If the certificate is to be revoked for any reason, it will be included in a publicly available Certificate Revokation List (CRL). This fact will also be reflected in the certificate status page. If any of the automated tests or manual checks fail after the certificate has been issued, the certificate is not immediately revoked. Rather, the automated tests MUST pass 99.x % of the runs, and the operator SHALL be notified at the second failed attempt in a row at the latest. In case a manual check fails, it has to be repeated at a date to be negotiated with SCS. It MAY NOT fail more than two times in a row.","s":"Regulations","u":"/standards/scs-0004-v1-achieving-certification","h":"#regulations","p":2682},{"i":2692,"t":"As of now, this document pertains to the certificate scopes on the certification level SCS-compatible only. It will be extended to cover the remaining levels as they become relevant, either directly or by way of referring to additional documents. For details on our mechanisms for developing, denoting, and versioning the certificate scopes, we refer to the document scs-0003-v1.","s":"Related Documents","u":"/standards/scs-0004-v1-achieving-certification","h":"#related-documents","p":2682},{"i":2695,"t":"This is the standard v2.1 for SCS Release 4. Note that we intend to only extend it (so it's always backwards compatible), but try to avoid changing in incompatible ways. (See at the end for the v1 to v2 transition where we have not met that goal, but at least managed to have a 1:1 relationship between v1 and v2 names.)","s":"Introduction","u":"/standards/scs-0100-v2-flavor-naming","h":"#introduction","p":2693},{"i":2697,"t":"In OpenStack environments there is a need to define different flavors for instances. The flavors are pre-defined by the operator, the customer can not change these. OpenStack providers thus typically offer a large selection of flavors. While flavors can be discovered (openstack flavor list), it is helpful for users (DevOps teams), to have A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere. Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered. While not all details will be encoded in the name, the key features should be obvious: Number of vCPUs, RAM, Root Disk. Extra features are important as well: There will be flavors with GPU support, fast disks for databases, memory-heavy applications, and other useful aspects of an instance. It may also be important to make the CPU generation clearly recognizable, as this is always a topic in discussions with customers. Note that not all relevant properties of flavors can be discovered; creating a specification to address this is a separate but related effort to the name standardization. Commonly used infrastructure-as-code tools do not provide a way to use discoverability features to express something like \"I want a flavor with 2 vCPUs, 8GiB of RAM, a local 20GB SSD disk and Infiniband support but I don't care whether it's AMD or intel\" in a reasonable manner. Using flavor names to express this will thus continue to be useful and we don't expect the need for standardization of flavor names to go away until the commonly used IaC tools work on a higher abstraction layer than they currently do.","s":"Motivation","u":"/standards/scs-0100-v2-flavor-naming","h":"#motivation","p":2693},{"i":2700,"t":"From discussions of our operators with their customers we learned that the following characteristics are important in a flavor description: Type Description Generation CPU Generation Number of CPU Number of vCPUs - suffixed by L,V,T,C (see below) Amount of RAM Amount of memory available for the VM Performance Class Ability to label high-performance CPUs, disks, network CPU Type X86-intel, X86-amd, ARM, RISC-V, Generic \"bms\" Bare Metal System (no virtualization/hypervisor) This list is likely not comprehensive and will grow over time. Rather than using random names s5a.medium and assigning a discrete set of properties to them, we wanted to come up with a scheme that allows to systematically derive names from properties and vice versa. The scheme allows for short names (by not encoding all details) as well as very detailed longer names.","s":"Type of information included","u":"/standards/scs-0100-v2-flavor-naming","h":"#type-of-information-included","p":2693},{"i":2702,"t":"Prefix CPUs & Suffix RAM[GiB] optional: Disk[GB]&type opt: extensions SCS- NL/V/T/C[i] -N[u][o] [-[Mx]N[n/s/l/p]] [_EXT] Note that N and M are placeholders for numbers here. The optional fields are denoted in brackets (and have opt: in the header. See below for extensions. Note that all letters are case-sensitive. Typical flavor names look like SCS-4V-16-50 for a flavor with 4vCPUs (with limited oversubscription), 16GiB RAM and a 50GB disk (of unspecified type).","s":"Complete Proposal for systematic flavor naming","u":"/standards/scs-0100-v2-flavor-naming","h":"#complete-proposal-for-systematic-flavor-naming","p":2693},{"i":2705,"t":"Next to the number of vCPUs, these vCPUs need to be characterized ti describe their nature. Suffix Meaning C dedicated Core T dedicated Thread (SMT) V vCPU (oversubscribed) L vCPU (heavily oversubscribed) Baseline​ Note that vCPU oversubscription for a V vCPU should be implemented such, that we can guarantee at least 20% of a core in >99% of the time; this can be achieved by limiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled) or by more advanced workload management logic. Otherwise L (low performance) instead of V must be used. The >99% is measured over a month (1% is 7.2h/month). Note that CPUs should use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.). Microcode must be updated within less than a month of a new release; for CVSS scores above 8, providers should do it in less than a week. The provider should enable at least all mitigations that are enabled by default in the Linux kernel and the KVM hypervisor. CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) should switch off hyperthreading OR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team. If microcode updates needed for mitigation are lacking for longer than a month, default kernel/hypervisor mitigations are disabled or hyperthreading is enabled despite the CPU being susceptible to L1TF, the flavors must declare themselves insecure with the i suffix (see below). Higher oversubscription​ Must be indicated with a L vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and the lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month). Insufficient microcode​ Not using these mitigations must be indicated by an additional i suffix for insecure (weak protection against CPU vulns through insufficient microcode, lack of disabled hyperthreading on L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor). Examples​ SCS-2C-4-10n SCS-2T-4-10n SCS-2V-4-10n SCS-2L-4-10n SCS-2Li-4-10n SCS-2-**4-10n - CPU suffix missing SCS-2iT-4-10n - This order is forbidden","s":"[REQUIRED] CPU Suffixes","u":"/standards/scs-0100-v2-flavor-naming","h":"#required-cpu-suffixes","p":2693},{"i":2707,"t":"Baseline​ Cloud providers should use ECC memory. Memory oversubscription should not be used. It is allowed to specify half GiBs (e.g. 3.5), though this is should not be done for larger memory sizes (>= 10GiB). No ECC​ If no ECC is used, the u suffix must indicate this. Enabled Oversubscription​ If memory is oversubscribed, you must expose this with the o suffix. Examples​ SCS-2C-4-10n SCS-2C-3.5-10n SCS-2C-4u-10n SCS-2C-4o-10n SCS-2C-4uo-10n SCS-2C-4ou-10n - This order is forbidden","s":"[REQUIRED] Memory","u":"/standards/scs-0100-v2-flavor-naming","h":"#required-memory","p":2693},{"i":2709,"t":"Disk sizes (in GB) should use sizes 5, 10, 20, 50, 100, 200, 500, 1000. Disk type Meaning n Network shared storage (ceph/cinder) h Local disk (HDD: SATA/SAS class) s Local SSD disk p Local high-perf NVMe Baseline​ Note that disk type might be omitted — the user then can not take any assumptions on what storage is provided for the root disk (that the image gets provisioned to). It does make sense for n to be requested explicitly to allow for smooth live migration. h typically provides latency advantages vs n (but not necessarily bandwidth and also is more likely to fail), s and p are for applications that need low latency (high IOPS) and bandwidth disk I/O. n storage is expected to survive single-disk and single-node failure. If the disk size is left out, the cloud is expected to allocate a disk (network or local) that is large enough to fit the root file system (min_disk in image). This automatic allocation is indicated with - without a disk size. If the - is left out completely, the user must create a boot volume manually and tell the instance to boot from it or use the block_device_mapping_v2 mechanism explicitly to create the boot volume from an image. Multi-provisioned Disk​ The disk size can be prefixed with Mx prefix, where M is an integer specifying that the disk is provisioned M times. Multiple disks provided this way should be independent storage media, so users can expect some level of parallelism and independence. Examples​ SCS-2C-4-10n SCS-2C-4-10s SCS-2C-4-10s_bms_z3 SCS-2C-4-3x10s - Cloud creates three 10GB SSDs SCS-2C-4-3x10s_bms_z3 SCS-2C-4-10 - Cloud decides disk type SCS-2C-4-10_bms_z3 SCS-2C-4-n - Cloud decides disk size (min_disk from image or larger) SCS-2C-4-n_bms_3 SCS-2C-4- - Cloud decides disk type and size SCS-2C-4-_bms_z3 SCS-2C-4-_bms_z3h_GNa-64_ib SCS-2C-4-_ib SCS-2C-4 - You need to specify a boot volume yourself (boot from volume, or use block_device_mapping_v2) SCS-2C-4_bms_z3 SCS-2C-4-3x- - Cloud decides disk type and size and creates three of them (FIXME: Is this useful?) SCS-2C-4-3xs - Cloud decides size and creates three local SSD volumes (FIXME: useful?) SCS-2C-4-3x10 - Cloud decides type and creates three 10GB volumes SCS-2C-4-1.5n - You must not specify disk sizes which are not in full GiBs","s":"[OPTIONAL] Disk sizes and types","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-disk-sizes-and-types","p":2693},{"i":2711,"t":"These are flavors that must exist on standard SCS clouds (x86-64). We expect disk sizes to be 5, 10, 20, 50, 100, 200, 500, 1000GB, 2000GB. We expect a typical CPU GiB vCPU:RAM ratio Mandatory Flavors 1:4 SCS-1V-4, SCS-1V-4-10 2:8 SCS-2V-8, SCS-2V-8-20 4:16 SCS-4V-16, SCS-4V-16-50 8:32 SCS-8V-32, SCS-8V-32-100 1:2 SCS-1V-2, SCS-1V-2-5 2:4 SCS-2V-4, SCS-2V-4-10 4:8 SCS-4V-8, SCS-4V-8-20 8:16 SCS-8V-16, SCS-8V-16-50 16:32 SCS-16V-32, SCS-16V-32-100 1:8 SCS-1V-8, SCS-1V-8-20 2:16 SCS-2V-16, SCS-2V-16-50 4:32 SCS-4V-32, SCS-4V-32-100 1:1 SCS-1L-1, SCS-1L-1-5 Note that all vCPUs of SCS standard flavors are oversubscribed — the smallest 1L-1 flavor allows for heavy oversubscription (note the L), and thus can be offered very cheaply — imagine jump hosts ... Disks types are not specified (and expected to be n or h typically). The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM compute hosts) to offer all flavors. Note: Compared to previous drafts, we have heavily reduced the variations on disk sizes — this reflects that for the standard networked cinder disks, you can pass block_device_mapping_v2 on server (VM) creation to allocate a boot disk of any size you desire. We have scaled the few mandatory disk sizes with the amount of RAM. For each flavor there is also one without a pre-attached disk — these are meant to be used to boot from a volume (either created beforehand or allocated on-the-fly with block_device_mapping_v2, e.g. openstack server create --flavor SCS-1V:2 --block-device-mapping sda=IMGUUID:image:12:true to create a bootable 12G cinder volume from image IMGUUID that gets tied to the VM instance life cycle.)","s":"Standard SCS flavors","u":"/standards/scs-0100-v2-flavor-naming","h":"#standard-scs-flavors","p":2693},{"i":2713,"t":"To be certified as an SCS compliant x86-64 IaaS platform, you must offer all standard SCS flavors according to the previous section. (We may define a mechanism that allows exceptions to be granted in a way that makes this very transparent and visible to clients.) You are allowed to understate your performance; you may implement a SCS-1V-1-5 flavor with a flavor that actually implements SCS-1T-1-5n (i.e. you dedicate a dedicated hyperthread instead of higher oversubscription) or even SCS-1D-1.5-8s (1 dedicated core, 50% more RAM and a 8GiB SSD). Flavor names indicating certain capabilities must at least provide these, otherwise they are in violation of the SCS specification and prevent SCS compliance. We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V-32-100). Larger providers that offer more details (using the extension below) are expected to still also offer the short variants for usability and easier portability, even beyond the mandated flavors. You must be very careful to expose low vCPU guarantees (L instead of V), insecure hyperthreading/microcode i, non-ECC-RAM u, memory oversubscription o. Note that omitting these qualifiers is overstating your security, reliability or performance properties and may be reason for clients to feel betrayed or claim damages. This would prevent SCS compliance and certification; in extreme cases, the SCS project might be forced to work with public statements. You may offer additional SCS- flavors, following the naming scheme and rules outlined here. You may offer additional flavors, not following above scheme and not starting with SCS- You must not offer flavors with the SCS- prefix which do not follow this naming scheme. You must not extend the SCS naming scheme with your own suffices; you are encouraged however to suggest extensions that we can discuss and add to the official scheme.","s":"Naming policy compliance","u":"/standards/scs-0100-v2-flavor-naming","h":"#naming-policy-compliance","p":2693},{"i":2715,"t":"There is a script in flavor_name_check.py which can be used to decode, validate and construct flavor names. This script must stay in sync with the specification text. Ensure you have your OpenStack tooling (python3-openstackclient, OS_CLOUD) setup and call tools/flavor-name-check.py -c $(openstack flavor list -f value -c Name) to get a report on the flavor list compliance of the cloud environment. The script flavor-names-openstack.py talks to the OpenStack API of the cloud specified by the OS_CLOUD environment and queries properties and checks the names for standards compliance and completeness w.r.t. the mandatory flavor list. It goes beyond the above example in checking that the discoverable features of flavors (vCPUs, RAM, Disk) match what the flavor names claim.","s":"Validation","u":"/standards/scs-0100-v2-flavor-naming","h":"#validation","p":2693},{"i":2717,"t":"The openstack-flavor-manager is able to create all standard, mandatory SCS flavors for you.","s":"Operational tooling","u":"/standards/scs-0100-v2-flavor-naming","h":"#operational-tooling","p":2693},{"i":2719,"t":"Extensions provide a possibility for providers that offer a very differentiated set of flavors to indicate hypervisors, support for hardware/nested virtuatlization, CPU types and generations, high-frequency models, GPU support and GPU types as well as Inifiniband support. (More extensions may be appended in the future.) Using the systematic naming approach ensures that two providers that offer flavors with the same specific features will use the same name for them, thus simplifying life for their customers when consuming these flavors. Note that there is no need to indicate all details and extra features this way. Flavors may always perform better or have more features than indicated in a name. Underperformance (CPU suffices L or i or memory suffices o and u) on the other hand MUST be indicated in the name; this happens rarely in practice. For smaller providers, the ability to e.g. differentiate between an AMD Milan and an intel IceLake and exposed the slightly different feature set to customers and have slightly different price points is often not worth the extra effort. This is because having this extra differentiation causes fragmentation of the machines (host aggregates) that can offer these flavors, thus resulting in a lower utilization (as the capacity management will need to have a certain amount of headroom per machine pool to avoid running out of capacity). Note that it possible for providers to register both the generic short names and the longer, more detailed names and allow them to use the same set of machines (host aggregates). Note that machines (hypervisors) can be part of more than one host aggregate. The extensions have the format: [_hyp][_hwv][_[arch[N][h][_[G/g]X[N][-M[h]]][_ib] Remember that letters are case-sensitive. In case you wonder: Feature indicators are capitalized, modifiers are lower case. (An exception is the uppercase -G for a pass-through GPU vs. lowercase -g for vGPU.)","s":"Extensions","u":"/standards/scs-0100-v2-flavor-naming","h":"#extensions","p":2693},{"i":2721,"t":"The default Hypervisor is assumed to be KVM. Clouds, that offer different hypervisors or Bare Metal Systems should indicate the Hypervisor according to the following table: hyp Meaning kvm KVM xen Xen vmw VMware hyv Hyper-V bms Bare Metal System Examples​ SCS-2C-4-10n SCS-2C-4-10n_bms SCS-2C-4-10n_bms_z3h","s":"[OPTIONAL] Hypervisor","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-hypervisor","p":2693},{"i":2723,"t":"If the instances that are created with this flavor support hardware-accelerated virtualization, this can be reflected with the _hwv flag (after the optional Hypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel) or svm (AMD) is available. This will be the case on Bare Metal flavors on almost all non-ancient x86 CPUs or if your virtualization hypervisor is configured to support nested virtualization. Flavors without the _hwv flag may or may not support hardware virtualization (as we recommend enabling nesting, but don't require flavor names to reflect all capabilities. Flavors may over-deliver ...) Examples​ SCS-2C-4-10 - may or may not support HW virtualization in VMs SCS-2C-4-10_kvm_hwv - kvm with enabled nested virtualization SCS-2C-4-10_hwv - not recommended, but allowed SCS-2C-4-10_bms_hwv - better: bare metal with HW virt support (VMX on intel, SVM on AMD, ...) SCS-2C-4-10_hwv_xen - illegal, wrong ordering","s":"[OPTIONAL] Hardware virtualization / Nested virtualization","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-hardware-virtualization--nested-virtualization","p":2693},{"i":2725,"t":"Arch details provide more details on the specific CPU: Vendor Generation Frequency Generation and Vendor​ The generations are vendor specific and can be left out. Not specifying arch means that we have a generic CPU (x86-64). The letters i, z, a and r specify the vendors Intel, AMD (z like in Zen), ARM v8+, RISC-V. Generation i (Intel x86-64) z (AMD x86-64) a (AArch64) r (RISC-V) 0 pre Skylake pre Zen pre Cortex A76 TBD 1 Skylake Zen-1 (Naples) A76/NeoN1 class TBD 2 Cascade Lake Zen-2 (Rome) A78/x1/NeoV1 class TBD 3 Ice Lake Zen-3 (Milan) A71x/NeoN2 (ARMv9) TBD 4 Sapphire Rapids Zen-4 (Genoa) TBD It is recommended to leave out the 0 when specifying the old generation; this will help the parser tool, which assumes 0 for an unspecified value and does leave it out when generating the name for comparison. In other words: 0 has a meaning of \"rather old or unspecified\". Frequency Suffixes​ Suffix Meaning h >2.75GHz all-core hh >3.25GHz all-core hhh >3.75GHz all-core Examples​ SCS-2C-4-10n SCS-2C-4-10n_z SCS-2C-4-10n_z3 SCS-2C-4-10n_z3h SCS-2C-4-10n_z3hh SCS-2C-4-10n_bms_z SCS-2C-4-10n_bms_z3 SCS-2C-4-10n_bms_z3 SCS-2C-4-10n_bms_z3h SCS-2C-4-10n_bms_z3hh - Bare Metal, Intel Ice Lake with > 3.25GHz all core freq","s":"[OPTIONAL] CPU Architecture Details","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-cpu-architecture-details","p":2693},{"i":2727,"t":"_GX[N][-M[h]] indicates a Pass-Through GPU from vendor X of gen N with M compute units / SMs / EUs exposed. _gX[N][-M[h]] indicates a vGPU from vendor X of gen N with M compute units / SMs / EUs assigned. Note that the vendor letter X is mandatory, generation and compute units are optional. GPU Vendor N nVidia A AMD I Intel For nVidia, the generation N can be f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, l=Ada Lovelace, ..., for AMD GCN-x=0.x, RDNA1=1, RDNA2=2, RDNA3=3, for intel Gen9=0.9, Xe(12.1)=1, ... (Note: This may need further work to properly reflect what's out there.) The optional h suffix to the compute unit count indicates high-performance (e.g. high freq or special high bandwidth gfx memory such as HBM); h can be duplicated for even higher performance.","s":"[OPTIONAL] GPU support","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-gpu-support","p":2693},{"i":2729,"t":"_ib indicates Infiniband networking. More extensions may be forthcoming and appended in a later revision of this spec. Extensions need to be specified in the above mentioned order.","s":"[OPTIONAL] Infiniband","u":"/standards/scs-0100-v2-flavor-naming","h":"#optional-infiniband","p":2693},{"i":2731,"t":"Note that we expect most clouds to prefer short flavor names, not indicating CPU details or hypervisor types. See above list of standard flavors to get a feeling. However, more successful providers will often need to differentiate their offerings in response to customer demand and allow customers to request flavors with specific detailed properties. The goal of this proposal is to avoid providers to invent their own names and then refer customers to (currently incompletely standardized) extra_specs or worse a non-machine-readable service descriptions to find out the details. So a cloud provider might well evolve from offering SCS-8T-16-50 to offering SCS-8T-16-50n, SCS-8T-16-50n_i2 and SCS-8T-16-50n_a2 to specify that he is using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome. We would expect the cloud provider to still offer the generic flavor SCS-8T-16-50 and allow the scheduler (placement service) to pick both more specific types (or just one if e.g. capacity management considerations suggest so). Providers should in such cases make sure that the price does not depend on scheduler decisions. We are looking into the metadefs mechanism and extra_specs to allow customers to ask for specific flavor properties without the need to encode all these flavor details into the flavor name, so the optional pieces may not be needed much. However, there must be a way to request flavor properties without encoding the need into an image — the indirection via an image is considered broken by the SCS team.","s":"Naming options advice","u":"/standards/scs-0100-v2-flavor-naming","h":"#naming-options-advice","p":2693},{"i":2733,"t":"Example Decoding SCS-2C-4-10n 2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk SCS-8Ti-32-50p_i1 8 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe SCS-1L-1u-5 1 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific) SCS-16T-64-200s_GNa-64_ib 16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 64 Passthrough nVidia Ampere SMs SCS-4C-16-2x200p_a1 4 dedicated Arm64 cores (A76 class), 16GiB RAM, 2x200GB local NVMe drives SCS-1V-0.5 1 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)","s":"Proposal Examples","u":"/standards/scs-0100-v2-flavor-naming","h":"#proposal-examples","p":2693},{"i":2735,"t":"Version 1 of the standard used a slightly different naming syntax while the logic was exactly the same. What is a - in v2 used to be a :; _ used to be -. The reason for the change was certain Kubernetes tools using the flavor names as labels. Labels however are subject to stricter naming rules and in particular don't allow for a :. See PR #190 for a discussion. Version 1 flavor names can be translated to v2 using the following transformation: NAMEV2=$(echo \"$NAMEV1\" | sed -e 's/\\-/_/g' -e 's/:/-/g' -e 's/^SCS_/SCS-/') and the way back can be done with NAMEV1=$(echo \"$NAMEV2\" | sed -e 's/\\-/:/g' -e 's/_/-/g' -e 's/^SCS:/SCS-/') Considerations for how providers can ensure a smooth transition for their customers from v1 to v2 are written in a separate document. For the time being, the validation tools still accept the old names with a warning (despite the unchanged SCS- prefix) unless you pass option -2 to them. They will however not count v1 flavors towards fulfilling the needs against the corresponding v2 mandatory flavor list unless you pass the option -1. In other words: An IaaS infrastructure with the 26 v1 mandatory flavors will produce 26 warnings (for using old flavors) and 26 errors (for missing the 26 mandatory v2 flavors) unless you pass -1 in which case no errors and no warnings will be produced. Registering the 26 mandatory v2 flavor names in addition will result in passing the test with only 26 warnings — unless you specify -2. If you do and want to pass you'll need to remove the old v1 names or rename them to no longer start with SCS-.","s":"Previous standard versions","u":"/standards/scs-0100-v2-flavor-naming","h":"#previous-standard-versions","p":2693},{"i":2737,"t":"The Gaia-X provider working group which could have created a superseding standard does no longer exist. However, we have been reaching out to the OpenStack Public Cloud SIG and the ALASCA members to seek further alignment. Getting upstream OpenStack support for flavor aliases would provide more flexibility and ease migrations between providers, also providers that don't offer the SCS- flavors. We also would like to see upstream extra_specs standardizing the discoverability of some properties exposed via the SCS names and work on IaC tooling (terraform ...) to make use of these when selecting a flavor.","s":"Beyond SCS","u":"/standards/scs-0100-v2-flavor-naming","h":"#beyond-scs","p":2693},{"i":2740,"t":"This is the standard v3.1 for SCS Release 5. Note that we intend to only extend it (so it's always backwards compatible), but try to avoid changing in incompatible ways. (See at the end for the v1 to v2 transition where we have not met that goal, but at least managed to have a 1:1 relationship between v1 and v2 names.)","s":"Introduction","u":"/standards/scs-0100-v3-flavor-naming","h":"#introduction","p":2738},{"i":2742,"t":"In OpenStack environments there is a need to define different flavors for instances. The flavors are pre-defined by the operator, the customer can not change these. OpenStack providers thus typically offer a large selection of flavors. While flavors can be discovered (openstack flavor list), it is helpful for users (DevOps teams), to have a naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere. While not all details will be encoded in the name, the key features should be obvious: Number of vCPUs, RAM, Root Disk. Extra features are important as well: There will be flavors with GPU support, fast disks for databases, memory-heavy applications, and other useful aspects of an instance. It may also be important to make the CPU generation clearly recognizable, as this is always a topic in discussions with customers. Note that not all relevant properties of flavors can be discovered; creating a specification to address this is a separate but related effort to the name standardization. Commonly used infrastructure-as-code tools do not provide a way to use discoverability features to express something like \"I want a flavor with 2 vCPUs, 8GiB of RAM, a local 20GB SSD disk and Infiniband support but I don't care whether it's AMD or intel\" in a reasonable manner. Using flavor names to express this will thus continue to be useful and we don't expect the need for standardization of flavor names to go away until the commonly used IaC tools work on a higher abstraction layer than they currently do.","s":"Motivation","u":"/standards/scs-0100-v3-flavor-naming","h":"#motivation","p":2738},{"i":2745,"t":"From discussions of our operators with their customers we learned that the following characteristics are important in a flavor description: Type Description Generation CPU Generation Number of CPU Number of vCPUs - suffixed by L,V,T,C (see below) Amount of RAM Amount of memory available for the VM Performance Class Ability to label high-performance CPUs, disks, network CPU Type X86-intel, X86-amd, ARM, RISC-V, Generic \"bms\" Bare Metal System (no virtualization/hypervisor) This list is likely not comprehensive and will grow over time. Rather than using random names s5a.medium and assigning a discrete set of properties to them, we wanted to come up with a scheme that allows to systematically derive names from properties and vice versa. The scheme allows for short names (by not encoding all details) as well as very detailed longer names.","s":"Type of information included","u":"/standards/scs-0100-v3-flavor-naming","h":"#type-of-information-included","p":2738},{"i":2747,"t":"Prefix CPUs & Suffix RAM[GiB] optional: Disk[GB]&type opt: extensions SCS- NL/V/T/C[i] -N[u][o] [-[Mx]N[n/h/s/p]] [_EXT] Note that N and M are placeholders for numbers here. The optional fields are denoted in brackets (and have opt: in the header. See below for extensions. Note that all letters are case-sensitive. Typical flavor names look like SCS-4V-16-50 for a flavor with 4vCPUs (with limited oversubscription), 16GiB RAM and a 50GB disk (of unspecified type).","s":"Complete Proposal for systematic flavor naming","u":"/standards/scs-0100-v3-flavor-naming","h":"#complete-proposal-for-systematic-flavor-naming","p":2738},{"i":2750,"t":"Next to the number of vCPUs, these vCPUs need to be characterized to describe their nature. Suffix Meaning C dedicated Core T dedicated Thread (SMT) V vCPU (oversubscribed) L vCPU (heavily oversubscribed) Baseline​ Note that vCPU oversubscription for a V vCPU should be implemented such, that we can guarantee at least 20% of a core in >99% of the time; this can be achieved by limiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled) or by more advanced workload management logic. Otherwise L (low performance) instead of V must be used. The >99% is measured over a month (1% is 7.2h/month). Note that CPUs should use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.). In particular, microcode must be updated within less than a month of a new release; for CVSS scores above 8, providers should do it in less than a week. all mitigations that are enabled by default in the Linux kernel and the KVM hypervisor should be enabled, CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) should have hyperthreading disabled OR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team. That is to say, except when the suffix i is used, the provider commits itself to implementing the appropriate mitigations if and when they become available, within the timeframes mentioned above. If a provider does not want to commit to deploying available microcode fixes and upstream kernel/hypervisor updates within a month or if the provider wants to enable hyperthreading on compute hosts despite having CPUs susceptible to L1TF there (and no SCS-accepted core-scheduling mechanism is used for mitigation), the flavors must be declared insecure with the i suffix (see below). Higher oversubscription​ Must be indicated with a L vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and the lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month). Insufficient microcode​ Not using these mitigations must be indicated by an additional i suffix for insecure (weak protection against CPU vulns through insufficient microcode, lack of disabled hyperthreading on L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor). Examples​ SCS-2C-4-10n SCS-2T-4-10n SCS-2V-4-10n SCS-2L-4-10n SCS-2Li-4-10n SCS-2-**4-10n - CPU suffix missing SCS-2iT-4-10n - This order is forbidden","s":"[REQUIRED] CPU Suffixes","u":"/standards/scs-0100-v3-flavor-naming","h":"#required-cpu-suffixes","p":2738},{"i":2752,"t":"Baseline​ Cloud providers should use ECC memory. Memory oversubscription should not be used. It is allowed to specify half GiBs (e.g. 3.5), though this is should not be done for larger memory sizes (>= 10GiB). No ECC​ If no ECC is used, the u suffix must indicate this. Enabled Oversubscription​ If memory is oversubscribed, you must expose this with the o suffix. Examples​ SCS-2C-4-10n SCS-2C-3.5-10n SCS-2C-4u-10n SCS-2C-4o-10n SCS-2C-4uo-10n SCS-2C-4ou-10n - This order is forbidden","s":"[REQUIRED] Memory","u":"/standards/scs-0100-v3-flavor-naming","h":"#required-memory","p":2738},{"i":2754,"t":"Disk sizes (in GB) should use sizes 5, 10, 20, 50, 100, 200, 500, 1000. Disk type Meaning n Network shared storage (ceph/cinder) h Local disk (HDD: SATA/SAS class) s Local SSD disk p Local high-perf NVMe Baseline​ Note that disk type might be omitted — the user then can not take any assumptions on what storage is provided for the root disk (that the image gets provisioned to). It does make sense for n to be requested explicitly to allow for smooth live migration. h typically provides latency advantages vs n (but not necessarily bandwidth and also is more likely to fail), s and p are for applications that need low latency (high IOPS) and bandwidth disk I/O. n storage is expected to survive single-disk and single-node failure. For specific requirements on the SSD and NVMe disks regarding IOPS and power-loss protection, refer to Decision Record scs-0110-ssd-flavors. If the disk size is left out, the cloud is expected to allocate a disk (network or local) that is large enough to fit the root file system (min_disk in image). This automatic allocation is indicated with - without a disk size. If the - is left out completely, the user must create a boot volume manually and tell the instance to boot from it or use the block_device_mapping_v2 mechanism explicitly to create the boot volume from an image. Multi-provisioned Disk​ The disk size can be prefixed with Mx prefix, where M is an integer specifying that the disk is provisioned M times. Multiple disks provided this way should be independent storage media, so users can expect some level of parallelism and independence. Examples​ SCS-2C-4-10n SCS-2C-4-10s SCS-2C-4-10s_bms_z3 SCS-2C-4-3x10s - Cloud creates three 10GB SSDs SCS-2C-4-3x10s_bms_z3 SCS-2C-4-10 - Cloud decides disk type SCS-2C-4-10_bms_z3 SCS-2C-4-n - Cloud decides disk size (min_disk from image or larger) SCS-2C-4-n_bms_3 SCS-2C-4- - Cloud decides disk type and size SCS-2C-4-_bms_z3 SCS-2C-4-_bms_z3h_GNa-64_ib SCS-2C-4-_ib SCS-2C-4 - You need to specify a boot volume yourself (boot from volume, or use block_device_mapping_v2) SCS-2C-4_bms_z3 SCS-2C-4-3x10 - Cloud decides type and creates three 10GB volumes SCS-2C-4-1.5n - You must not specify disk sizes which are not in full GiBs","s":"[OPTIONAL] Disk sizes and types","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-disk-sizes-and-types","p":2738},{"i":2756,"t":"Every flavor you offer MUST satisfy the following assertion: If its name starts with SCS-, the name has to conform to the syntax outlined above, and the flavor must at least provide the capabilities indicated by the name. That is to say: You may offer flavors not following the above scheme, as long as the name does not start with SCS-. You are allowed to understate your performance; for instance, a flavor that satisfies SCS-1C-1.5-8s (1 dedicated core, 1.5 GiB RAM, 8 GiB SSD) may also be named SCS-1T-1-5n (1 dedicated hyperthread, 1 GiB RAM, 5 GiB network volume) or even SCS-1V-1-5. Similarly, you may offer the (v3 mandatory) SCS-2V-4-20s with a SCS-2V-4-20p implementation (using a local NVMe instead of an SSD). You must be very careful to expose low vCPU guarantees (L instead of V), insecure hyperthreading/microcode i, non-ECC-RAM u, memory oversubscription o. Note that omitting these qualifiers is overstating your security, reliability or performance properties and may be reason for clients to feel betrayed or claim damages. This would prevent SCS compliance and certification; in extreme cases, the SCS project might be forced to work with public statements. We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V-32-100). Larger providers that offer more details (using the extension below) are expected to still also offer the short variants for usability and easier portability, even beyond the mandated flavors. You must not extend the SCS naming scheme with your own extensions; you are encouraged however to suggest extensions that we can discuss and add to the official scheme.","s":"Naming policy compliance","u":"/standards/scs-0100-v3-flavor-naming","h":"#naming-policy-compliance","p":2738},{"i":2758,"t":"Extensions provide a possibility for providers that offer a very differentiated set of flavors to indicate hypervisors, support for hardware/nested virtualization, CPU types and generations, high-frequency models, GPU support and GPU types as well as Infiniband support. (More extensions may be appended in the future.) Using the systematic naming approach ensures that two providers that offer flavors with the same specific features will use the same name for them, thus simplifying life for their customers when consuming these flavors. Note that there is no need to indicate all details and extra features this way. Flavors may always perform better or have more features than indicated in a name. Underperformance (CPU suffixes L or i or memory suffixes o and u) on the other hand MUST be indicated in the name; this happens rarely in practice. For smaller providers, the ability to e.g. differentiate between an AMD Milan and an intel IceLake and exposed the slightly different feature set to customers and have slightly different price points is often not worth the extra effort. This is because having this extra differentiation causes fragmentation of the machines (host aggregates) that can offer these flavors, thus resulting in a lower utilization (as the capacity management will need to have a certain amount of headroom per machine pool to avoid running out of capacity). Note that it is possible for providers to register both the generic short names and the longer, more detailed names and allow them to use the same set of machines (host aggregates). Note that machines (hypervisors) can be part of more than one host aggregate. The extensions have the format: [_hyp][_hwv][_arch[N][h]][_[G/g]X[N][-M][h]][_ib] Extensions are individually optional, but the ones that are used must appear in the order given in the above line. Remember that letters are case-sensitive. In case you wonder: Feature indicators are capitalized, modifiers are lower case. (An exception is the uppercase _G for a pass-through GPU vs. lowercase _g for vGPU.)","s":"Extensions","u":"/standards/scs-0100-v3-flavor-naming","h":"#extensions","p":2738},{"i":2760,"t":"Format: _hyp The default Hypervisor is assumed to be KVM. Clouds that offer different hypervisors or Bare Metal Systems should indicate the Hypervisor according to the following table: hyp Meaning kvm KVM xen Xen vmw VMware hyv Hyper-V bms Bare Metal System Examples​ SCS-2C-4-10n SCS-2C-4-10n_bms SCS-2C-4-10n_bms_z3h","s":"[OPTIONAL] Hypervisor","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-hypervisor","p":2738},{"i":2762,"t":"Format: _hwv If the instances that are created with this flavor support hardware-accelerated virtualization, this can be reflected with the _hwv flag (after the optional Hypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel) or svm (AMD) is available. This will be the case on Bare Metal flavors on almost all non-ancient x86 CPUs or if your virtualization hypervisor is configured to support nested virtualization. Flavors without the _hwv flag may or may not support hardware virtualization (as we recommend enabling nesting, but don't require flavor names to reflect all capabilities. Flavors may over-deliver ...) Examples​ SCS-2C-4-10 - may or may not support HW virtualization in VMs SCS-2C-4-10_kvm_hwv - kvm with enabled nested virtualization SCS-2C-4-10_hwv - not recommended, but allowed SCS-2C-4-10_bms_hwv - better: bare metal with HW virt support (VMX on intel, SVM on AMD, ...) SCS-2C-4-10_hwv_xen - illegal, wrong ordering","s":"[OPTIONAL] Hardware virtualization / Nested virtualization","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-hardware-virtualization--nested-virtualization","p":2738},{"i":2764,"t":"Format: _arch[N][h] This extension provides more details on the specific CPU: vendor/architecture (arch) generation (N) frequency (h) Generation and Vendor​ The options for arch are as follows: Letter vendor/architecture Corresponding image architecture (none) Generic x86-64 x86_64 i Intel x86-64 x86_64 z AMD (Zen) x86-64 x86_64 a ARM v8+ aarch64 r RISC-V (not yet listed in Glance) The generation is vendor specific and can be left out, but it can only be specified in conjunction with a vendor. At present, these values are possible: Generation i (Intel x86-64) z (AMD x86-64) a (AArch64) r (RISC-V) 0 pre Skylake pre Zen pre Cortex A76 TBD 1 Skylake Zen-1 (Naples) A76/NeoN1 class TBD 2 Cascade Lake Zen-2 (Rome) A78/x1/NeoV1 class TBD 3 Ice Lake Zen-3 (Milan) A71x/NeoN2 (ARMv9) TBD 4 Sapphire Rapids Zen-4 (Genoa) TBD It is recommended to leave out the 0 when specifying the old generation; this will help the parser tool, which assumes 0 for an unspecified value and does leave it out when generating the name for comparison. In other words: 0 has a meaning of \"rather old or unspecified\". note We don't differentiate between Zen-4 (Genoa) and Zen-4c (Bergamo); L3 cache per Siena core is smaller on Bergamo and the frequency lower but the cores are otherwise identical. As we already have a qualifier h that allows to specify higher frequencies (which Genoa thus may use more and Bergamo less or not), we have enough distinction capabilities. Frequency Suffixes​ Suffix Meaning h >2.75GHz all-core hh >3.25GHz all-core hhh >3.75GHz all-core Examples​ SCS-2C-4-10n SCS-2C-4-10n_z SCS-2C-4-10n_z3 SCS-2C-4-10n_z3h SCS-2C-4-10n_z3hh SCS-2C-4-10n_bms_z SCS-2C-4-10n_bms_z3 SCS-2C-4-10n_bms_z3 SCS-2C-4-10n_bms_z3h SCS-2C-4-10n_bms_z3hh - Bare Metal, AMD Milan with > 3.25GHz all core freq","s":"[OPTIONAL] CPU Architecture Details","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-cpu-architecture-details","p":2738},{"i":2766,"t":"Format: _[G/g]X[N][-M][h] This extension provides more details on the specific GPU: pass-through (G) vs. virtual GPU (g) vendor (X) generation (N) number (M) of processing units that are exposed (for pass-through) or assigned; see table below for vendor-specific terminology high-performance indicator (h) Note that the vendor letter X is mandatory, generation and processing units are optional. letter X vendor processing units N nVidia streaming multiprocessors (SMs) A AMD compute units (CUs) I Intel execution units (EUs) For nVidia, the generation N can be f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, l=Ada Lovelace, ..., for AMD GCN-x=0.x, RDNA1=1, RDNA2=2, RDNA3=3, for Intel Gen9=0.9, Xe(12.1)=1, ... (Note: This may need further work to properly reflect what's out there.) The optional h suffix to the compute unit count indicates high-performance (e.g. high freq or special high bandwidth gfx memory such as HBM); h can be duplicated for even higher performance. Example: SCS-16V-64-500s_GNa-14h This flavor has a pass-through GPU nVidia Ampere with 14 SMs and either high-bandwidth memory or specially high frequencies. Looking through GPU specs you could guess it's 1/4 of an A30.","s":"[OPTIONAL] GPU support","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-gpu-support","p":2738},{"i":2768,"t":"Format: _ib This extension indicates Infiniband networking. More extensions may be forthcoming and appended in a later revision of this spec. Extensions need to be specified in the above-mentioned order.","s":"[OPTIONAL] Infiniband","u":"/standards/scs-0100-v3-flavor-naming","h":"#optional-infiniband","p":2738},{"i":2770,"t":"Note that we expect most clouds to prefer short flavor names, not indicating CPU details or hypervisor types. See above list of standard flavors to get a feeling. However, more successful providers will often need to differentiate their offerings in response to customer demand and allow customers to request flavors with specific detailed properties. The goal of this proposal is to avoid providers to invent their own names and then refer customers to (currently incompletely standardized) extra_specs or worse a non-machine-readable service descriptions to find out the details. So a cloud provider might well evolve from offering SCS-8T-16-50 to offering SCS-8T-16-50n, SCS-8T-16-50n_i2 and SCS-8T-16-50n_z2 to specify that he is using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome. We would expect the cloud provider to still offer the generic flavor SCS-8T-16-50 and allow the scheduler (placement service) to pick both more specific types (or just one if e.g. capacity management considerations suggest so). Providers in such cases should ensure that the price of a requested flavor does not depend on the scheduler decisions. We are looking into the metadefs mechanism and extra_specs to allow customers to ask for specific flavor properties without the need to encode all these flavor details into the flavor name, so the optional pieces may not be needed much. However, there must be a way to request flavor properties without encoding the need into an image — the indirection via an image is considered broken by the SCS team.","s":"Naming options advice","u":"/standards/scs-0100-v3-flavor-naming","h":"#naming-options-advice","p":2738},{"i":2772,"t":"Example Decoding SCS-2C-4-10n 2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk SCS-8Ti-32-50p_i1 8 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe SCS-1L-1u-5 1 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific) SCS-16T-64-200s_GNa-64_ib 16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 64 Passthrough nVidia Ampere SMs SCS-4C-16-2x200p_a1 4 dedicated Arm64 cores (A76 class), 16GiB RAM, 2x200GB local NVMe drives SCS-1V-0.5 1 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)","s":"Proposal Examples","u":"/standards/scs-0100-v3-flavor-naming","h":"#proposal-examples","p":2738},{"i":2774,"t":"Previous versions up to version 3.0 contained the list of mandatory/recommended flavors, which has been moved to a standard of its own. Version 1 of the standard used a slightly different naming syntax while the logic was exactly the same. What is a - in v2 used to be a :; _ used to be -. The reason for the change was certain Kubernetes tools using the flavor names as labels. Labels however are subject to stricter naming rules and in particular don't allow for a :. See PR #190 for a discussion. Version 1 flavor names can be translated to v2 using the following transformation: NAMEV2=$(echo \"$NAMEV1\" | sed -e 's/\\-/_/g' -e 's/:/-/g' -e 's/^SCS_/SCS-/') and the way back can be done with NAMEV1=$(echo \"$NAMEV2\" | sed -e 's/\\-/:/g' -e 's/_/-/g' -e 's/^SCS:/SCS-/') For the time being, the validation tools still accept the old names with a warning (despite the unchanged SCS- prefix) unless you pass option -2 to them. They will however not count v1 flavors towards fulfilling the needs against the corresponding v2 mandatory flavor list unless you pass the option -1. In other words: An IaaS infrastructure with the 26 v1 mandatory flavors will produce 26 warnings (for using old flavors) and 26 errors (for missing the 26 mandatory v2 flavors) unless you pass -1 in which case no errors and no warnings will be produced. Registering the 26 mandatory v2 flavor names in addition will result in passing the test with only 26 warnings — unless you specify -2. If you do and want to pass you'll need to remove the old v1 names or rename them to no longer start with SCS-.","s":"Previous standard versions","u":"/standards/scs-0100-v3-flavor-naming","h":"#previous-standard-versions","p":2738},{"i":2776,"t":"The Gaia-X provider working group which could have created a superseding standard does no longer exist. However, we have been reaching out to the OpenStack Public Cloud SIG and the ALASCA members to seek further alignment. Getting upstream OpenStack support for flavor aliases would provide more flexibility and ease migrations between providers, also providers that don't offer the SCS- flavors. We also would like to see upstream extra_specs standardizing the discoverability of some properties exposed via the SCS names and work on IaC tooling (terraform ...) to make use of these when selecting a flavor.","s":"Beyond SCS","u":"/standards/scs-0100-v3-flavor-naming","h":"#beyond-scs","p":2738},{"i":2779,"t":"The three major versions of the standard that exist so far are very similar, and deliberately so. Therefore, the procedures needed to implement or test them are very similar as well. Yet, this document will only cover v3, because v1 and v2 are already obsolete by the time of writing.","s":"Introduction","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#introduction","p":2777},{"i":2781,"t":"Every flavor whose name starts with SCS- must conform with the naming scheme laid down in the standard.","s":"Implementation Notes","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#implementation-notes","p":2777},{"i":2783,"t":"Syntax Check​ The test suite comes with a handy command-line utility that can be used to validate flavor names, to interactively construct a flavor name via a questionnaire, and to generate prose descriptions for given flavor names. See the README for more details. The functionality of this script is also (partially) exposed via the web page https://flavors.scs.community/. With the OpenStack tooling (python3-openstackclient, OS_CLOUD) in place, you can call cli.py -v parse v3 $(openstack flavor list -f value -c Name) to get a report on the syntax compliance of the flavor names of the cloud environment. Flavor Creation​ The OpenStack Flavor Manager will create a whole set of flavors in one go, given a YAML description of this set.","s":"Operational Tooling","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#operational-tooling","p":2777},{"i":2786,"t":"The following items MUST be detected and reported as an error: any syntax error in a name starting with SCS-, any mismatch between any immediately discoverable property of a flavor (currently, CPU, RAM and disk size) and the meaning of its name (which is usually a lower bound), such as the CPU generation or hypervisor. In addition, the following items MAY be reported as an error: any mismatch between any non-immediately discoverable property of flavor and the meaning of its name.","s":"Errors","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#errors","p":2777},{"i":2788,"t":"None so far.","s":"Warnings","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#warnings","p":2777},{"i":2790,"t":"The script flavor-names-openstack.py talks to the OpenStack API of the cloud specified by the OS_CLOUD environment and queries properties and checks the names for standards compliance.","s":"Implementation","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#implementation","p":2777},{"i":2792,"t":"To be determined.","s":"Manual Tests","u":"/standards/scs-0100-w1-flavor-naming-implementation-testing","h":"#manual-tests","p":2777},{"i":2795,"t":"The Sovereign Cloud Stack (SCS) provides standards for a range of cloud infrastructure types. It strives for interoperable and sovereign cloud offerings which can be deployed and used by a wide range of organizations and individuals. SCS plans to offer six kinds of certificates with varying scope. These scopes can be sorted into two dimensions: certification level, of which there are three: SCS-compatible SCS-open SCS-sovereign cloud layer, of which there are two: infastructure as a service (IaaS) Kubernetes as a service (KaaS) So, for instance, a certificate can have the scope SCS-compatible IaaS or SCS-sovereign KaaS. Note that we don't currently have separate certification layers for Operations and IAM. We expect that tests for these aspects will exist, but be incorporated into the IaaS and KaaS layers. Each certificate scope amounts to a set of standards that have to be fulfilled by the cloud service in question in order for a certificate to be issued. In addition, a certificate with a certain scope may only be issued if some other certificate is already held. Case in point: the certification levels are meant to be seen as a progression, where the upper levels build on the lower ones, and the certificate for \"SCS-open IaaS\" will only be issued if a certificate for \"SCS-compatible IaaS\" is already held. We say that the latter certificate is a prerequisite of the former. Naturally, as the state of the art progresses, so do our certificates. We keep track of the changes by means of versioning. That is to say that each certificate scope can come in several versions, each one of them having its distinct timespan when it is in effect. For instance, we might have SCS-compatible IaaS v1, effective 2021-01-01 through 2023-10-31 SCS-compatible IaaS v2, effective 2023-03-23 through 2023-11-30 and so on (but usually, we aim to keep at most two versions in effect, with an overlap of 4 to 6 weeks). This decision record describes two main points: How we denote our certificate scopes by means of a YAML file. Our process for constructing and progressing the certificate scopes.","s":"Introduction","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#introduction","p":2793},{"i":2797,"t":"This decision record establishes a mechanism (by means of the YAML file) with the following three main objectives: to provide an overview of the mandatory standards for the different SCS certificate scopes to make the lifecycle of certificate scopes traceable to provide a machine-readable document for further processing (e.g. for a compliance tool suite or continuous integration).","s":"Motivation","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#motivation","p":2793},{"i":2799,"t":"Digging through a repository of draft, stable, replaced and rejected standards becomes increasingly challenging with a growing number documents and decision records. A central document that lists all mandatory standards to acquire a certificate with a certain scope can resolve this issue. It provides clarity for providers as well as users and helps to understand the value proposition of SCS.","s":"Overview of mandatory SCS standards","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#overview-of-mandatory-scs-standards","p":2793},{"i":2801,"t":"Standards and therefore certifications will evolve over time. To provide transparency and traceability for the lifecycle of SCS certificate scopes, the whole history of our certifications should be recorded. Pre-notification of changes to our certificate scopes allows users to adapt their environments or deployment automation to the new standards in advance.","s":"Lifecycle of certificate scopes","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#lifecycle-of-certificate-scopes","p":2793},{"i":2803,"t":"By providing a machine-readable document, we can generate web-friendly overviews of our certificate scopes as well as create a tool suite that checks environments against all described standards.","s":"Machine-readability for further processing","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#machine-readability-for-further-processing","p":2793},{"i":2805,"t":"Each certificate scope is recorded in a dedicated YAML file, e.g. scs-open-kaas.yaml. The certification YAML MUST contain the following keys: Key Type Description Example name String Full name of this certificate scope SCS Open KaaS url String Valid URL to the latest raw version of this document https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/scs-open-kaas.yaml versions Array of maps List of version descriptors (described below) (see below) The certification YAML MAY contain the following keys: Key Type Description prerequisite Map Descriptor for the prerequisite certificate scope (see below) variables Array of String Lists variables that may occur in check tool descriptors The main check tool will expect an assignment for these variables (which is specific to the subject under test), and every occurrence of the variable in the check tool descriptor will be substituted accordingly.","s":"SCS Certification YAML","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#scs-certification-yaml","p":2793},{"i":2807,"t":"A certificate within a certain level (above SCS-compatible) can only be granted if a valid corresponding certificate of the level below is presented, where corresponding means: of the same layer. The latter certificate is said to be a prerequisite for the former. We implement this logic by allowing for the designation of a certificate scope as a prerequisite; then a certificate of that prerequisite scope has to be presented before the certificate of the scope in question can be granted. Key Type Description Example name String Full name of the certificate scope SCS Compatible IaaS url String Valid URL to the latest raw version of the certificate scope scs-compatible-iaas.yaml","s":"Prerequisite descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#prerequisite-descriptor","p":2793},{"i":2809,"t":"Key Type Description Example version String Mandatory: Version of the particular list of standards v3 standards Array of maps Mandatory: List of standard descriptors for this particular layer stabilized_at Date ISO formatted date indicating the date after this version is considered stable. 2022-11-09 deprecated_at Date ISO formatted date indicating the date on which this version is expired. 2023-04-09 Once a version has a stabilized_at field, this field may not be changed. The same holds true for the deprecated_at field. Note that at any point in time, all versions that are older (stabilized_at is at or before this point) can be certified against, unless the version is already deprecated (the point is after deprecated_at). This means that more than one version may be allowable at a certain point in time. Tooling should default to use the newest allowable version (the one with the most recent stabilized_at date) then. Note: We intend to keep only one version in effect, except for a grace period of 4 to 6 weeks, when two versions are effective at the same time.","s":"Version descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#version-descriptor","p":2793},{"i":2811,"t":"Every list of standards consists of several standards that – altogether – define the particular layer standard in the given version. Key Type Description Example name String Full name of the particular standard Flavor naming url String Valid URL to the latest raw version of the particular standard Flavor naming condition String State of the particular standard, currently either mandatory or optional, default is mandatory mandatory checks Array List of all checks that must pass; each entry being a check descriptor","s":"Standard descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#standard-descriptor","p":2793},{"i":2813,"t":"The following fields are valid for every check descriptor: Key Type Description Example id String Identifier for this check (immutable and unique within this version of the certificate scope) image-md-check condition String Optionally overrides the per-standard condition (mandatory or optional) optional lifetime String One of: day (default), week, month, quarter; the test result is valid until the end of the next period week section String Optional what section to associate this check with (sections can be checked in isolation); default: equal to lifetime flavor-name syntax Additional fields are valid depending on whether the check is automated or manual. Automated check​ Key Type Description Example executable String Valid local filename (relative to the path of scs-compliance-check.py) of a script that verifies compliance with the particular standard image-md-check.py env Map Optional key-value map of environment variables (values may use variables) OS_CLOUD: {os_cloud} args String Optional command-line arguments to be passed to the check_tool (may use variables) -v -k {kubeconfig} As mentioned, variables may be used within env and args; they are enclosed in single braces, like so: {var}. If a brace is desired, it needs to be doubled: {{ will be turned into {. When the main check tool is run, each occurrence of a variable will be substituted for according to the variable assignment for the subject under test. Note: the executable could in principle also be given via a URL; however, this is not yet supported due to security considerations. Manual check​ TBD","s":"Check descriptor","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#check-descriptor","p":2793},{"i":2815,"t":"name: SCS Open IaaS url: https://raw.githubusercontent.com/SovereignCloudStack/Docs/main/Certification/scs-open-iaas.yaml prerequisite: name: SCS Compatible IaaS url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/scs-compatible-iaas.yaml variables: - os_cloud versions: - version: v5 # This version is in a draft state and work in progress # No stabilized_at: date set yet standards: - name: Flavor naming url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Standards/scs-0100-v2-flavor-naming.md condition: mandatory # is default and can be left out checks: - executable: flavor-name-check.py env: OS_CLOUD: \"{os_cloud}\" id: flavor-name-check lifetime: day - name: Image metadata url: https://raw.githubusercontent.com/SovereignCloudStack/Docs/main/Standards/SCS-0004-v1-image-metadata.md condition: mandatory checks: - executable: image-md-check.py args: -c {os_cloud} -v id: image-md-check lifetime: day - executable: image-md-check2.py condition: optional id: image-md-check-2 lifetime: day - version: v4 # This is the upcoming version with a given target date. No further changes should be done to this set of standards stabilized_at: 2022-04-01 standards: - name: .... - version: v3 # This is the stable set of standards that is currently active stabilized_at: 2021-10-01 deprecated_at: 2022-11-08 standards: - name: .... - version: v2 # This set of standards is obsolete and has been replaced by v3 stabilized_at: 2021-07-01 deprecated_at: 2021-11-01 standards: - name: ....","s":"Basic Example","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#basic-example","p":2793},{"i":2817,"t":"The lifecycle any version of any certificate scope goes through the following phases: Draft, Stable, and Deprecated. Note that one pull request can affect multiple versions, but each pull request has to affect at most one layer. Each pull request is to be voted upon in the corresponding team meeting. The vote has to be on the pull request only, i.e., it may not affect any other pull request or issue, and it must be announced 14 days in advance via the corresponding mailing list.","s":"Process","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#process","p":2793},{"i":2820,"t":"In order to have a document that can be processed by a wide range of tools, we need to opt for a simple but yet well supported format. YAML offers readability for humans as well as good support by many frameworks. Since YAML is heavily used in the cloud and container domain, the choice is obvious.","s":"File format","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#file-format","p":2793},{"i":2822,"t":"This standard only allows exactly one depending certification, otherwise we would need to use a list of mappings. Since this is in accordance to the current plan of the SIG Standardization & Certification, we can safely ignore multiple dependency of certification for now.","s":"Dependency graph for certifications","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#dependency-graph-for-certifications","p":2793},{"i":2824,"t":"The SCS repository Docs has a tool scs-compliance-check.py in the Tests directory which parses the SCS Certification YAML and then runs the tests referenced there, returning the results of the tests.","s":"Tooling","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#tooling","p":2793},{"i":2827,"t":"This document is heavily inspired by the publiccode.yml standard, as published by the Foundation for Public Code.","s":"Acknowledgements","u":"/standards/scs-0003-v1-sovereign-cloud-standards-yaml","h":"#acknowledgements","p":2793},{"i":2830,"t":"This is the standard v1.0 for SCS Release 0. Note that we intend to only extend it (so it's always backwards compatible), but try to avoid changing in incompatible ways.","s":"Introduction","u":"/standards/scs-0100-v1-flavor-naming","h":"#introduction","p":2828},{"i":2832,"t":"In OpenStack environments there is a need to define different flavors for instances. The flavors are pre-defined by the operator, the customer can not change these. OpenStack providers thus typically offer a large selection of flavors. While flavors can be discovered (openstack flavor list), it is helpful for users (DevOps teams), to have A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere. Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered. While not all details will be encoded in the name, the key features should be obvious: Number of vCPUs, RAM, Root Disk. Extra features are important as well: There will be flavors with GPU support, fast disks for databases, memory-heavy applications, and other useful aspects of an instance. It may also be important to make the CPU generation clearly recognisable, as this is always a topic in discussions with customers.","s":"Motivation","u":"/standards/scs-0100-v1-flavor-naming","h":"#motivation","p":2828},{"i":2835,"t":"We believe the following characteristics are important in a flavour description: Type Description Generation CPU Generation Number of CPU Number of vCPUs - suffixed by L,V,T,C (see below) Amount of RAM Amount of memory available for the VM Performance Class Ability to label high-performance CPUs, disks, network CPU Type X86-intel, X86-amd, ARM, RISC-V, Generic \"bms\" Bare Metal System (no virtualization/hypervisor)","s":"Type of information included","u":"/standards/scs-0100-v1-flavor-naming","h":"#type-of-information-included","p":2828},{"i":2837,"t":"Prefix CPU Suffix RAM[GiB] optional: Disk[GB] optional: Disk type optional: extra features SCS- N L/V/T/C[i] :N[u][o] [:[Mx]N] [n/s/l/p] [-hyp][-hwv]-[arch[N][h][-[G/g]X[N][:M[h]]][-ib] (Note that N and M are placeholders for numbers here).","s":"Complete Proposal","u":"/standards/scs-0100-v1-flavor-naming","h":"#complete-proposal","p":2828},{"i":2840,"t":"Suffix Meaning C dedicated Core T dedicated Thread (SMT) V vCPU (oversubscribed) L vCPU (heavily oversubscribed) Baseline​ Note that vCPU oversubscription for a V vCPU should be implemented such, that we can guarantee at least 20% of a core in >99% of the time; this can be achieved by limiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled) or by more advanced workload management logic. Otherwise L (low performance) must be used. The >99% is measured over a month (1% is 7.2h/month). Note that CPUs must use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.). We expect that microcode gets updated within less than a month of a new release; for CVSS scores above 8, we expect less than a week. The provider must enable at least all mitigations that are enabled by default in the Linux kernel. CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) must switch off hyperthreading OR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team, or declare themselves as insecure with the i suffix (see below). Higher oversubscription​ Must be indicated with a L vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and the lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month). Insufficient microcode​ Not using these mitigations must be indicated by an additional i suffix for insecure (weak protection against CPU vulns through insufficient microcode, lack of disabled hyperthreading on L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor). Examples​ SCS-2C:4:10n SCS-2T:4:10n SCS-2V:4:10n SCS-2L:4:10n SCS-2Li:4:10n SCS-2:**4:10n - CPU suffix missing SCS-2iT:4:10n - This order is forbidden","s":"[REQUIRED] CPU Suffixes","u":"/standards/scs-0100-v1-flavor-naming","h":"#required-cpu-suffixes","p":2828},{"i":2842,"t":"Baseline​ We expect cloud providers to use ECC memory. Memory oversubscription is not recommended. It is allowed to specify half GiBs (e.g. 3.5), though this is discouraged for larger memory sizes (>= 10GiB). No ECC​ If no ECC is used, the u suffix must indicate this. Enabled Oversubscription​ You have to expose this with the o sufffix. Examples​ SCS-2C:4:10n SCS-2C:3.5:10n SCS-2C:4u:10n SCS-2C:4o:10n SCS-2C:4uo:10n SCS-2C:4ou:10n - This order is forbidden","s":"[REQUIRED] Memory","u":"/standards/scs-0100-v1-flavor-naming","h":"#required-memory","p":2828},{"i":2844,"t":"Disk type Meaning n Network shared storage (ceph/cinder) h Local disk (HDD: SATA/SAS class) s Local SSD disk p Local high-perf NVMe Baseline​ Note that disk type might be omitted — the user then can not take any assumptions on what storage is provided for the root disk (that the image gets provisioned to). It does make sense for n to be requested explicitly to allow for smooth live migration. h typically provides latency advantages vs n (but not necessarily bandwidth and also is more likely to fail), s and p are for applications that need low latency (high IOPS) and bandwidth disk I/O. n storage is expected to survive single-disk and single-node failure. If the disk size is left out, the cloud is expected to allocate a disk (network or local) that is large enough to fit the root file system (min_disk in image). This automatic allocation is indicated with : without a disk size. If the : is left out completely, the user must create a boot volume manually and tell the instance to boot from it or use the block_device_mapping_v2 mechanism explicitly to create the boot volume from an image. Multi-provisioned Disk​ The disk size can be prefixed with Mx prefix, where M is an integer specifying that the disk is provisioned M times. Examples​ SCS-2C:4:10n SCS-2C:4:10s SCS-2C:4:10s-bms-z3 SCS-2C:4:3x10s - Cloud creates three 10GB SSDs SCS-2C:4:3x10s-bms-z3 SCS-2C:4:10 - Cloud decides disk type SCS-2C:4:10-bms-z3 SCS-2C:4:n - Cloud decides disk size (min_disk from image or larger) SCS-2C:4:n-bms-3 SCS-2C:4: - Cloud decides disk type and size SCS-2C:4:-bms-z3 SCS-2C:4:-bms-z3h-GNa:64-ib SCS-2C:4:-ib SCS-2C:4 - You need to specify a boot volume yourself (boot from volume, or use block_device_mapping_v2) SCS-2C:4-bms-z3 SCS-2C:4:3x - Cloud decides disk type and size and creates three of them (FIXME: Is this useful?) SCS-2C:4:3xs - Cloud decides size and creates three local SSD volumes (FIXME: useful?) SCS-2C:4:3x10 - Cloud decides type and creates three 10GB volumes SCS-2C:4:1.5n - You must not specify disk sizes which are not in full GiBs","s":"[OPTIONAL] Disk sizes and types","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-disk-sizes-and-types","p":2828},{"i":2846,"t":"The default Hypervisor is assumed to be KVM. Clouds, that offer different hypervisors or Bare Metal Systems should indicate the Hypervisor according to the following table: hyp Meaning kvm KVM xen Xen vmw VMware hyv Hyper-V bms Bare Metal System Examples​ SCS-2C:4:10n SCS-2C:4:10n-bms SCS-2C:4:10n-bms-z3h","s":"[OPTIONAL] Hypervisor","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-hypervisor","p":2828},{"i":2848,"t":"If the instances that are created with this flavor support hardware-accelerated virtualization, this can be reflected with the -hwv flag (after the optional Hypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel) or svm (AMD) is available. This will be the case on Bare Metal flavors on almost all non-ancient x86 CPUs or if your virtualization hypervisor is configured to support nested virtualization. Flavors without the -hwv flag may or may not support hardware virtualization (as we recommend enabling nesting, but don't require flavor names to reflect all capabilities. Flavors may overdeliver ...) Examples​ SCS-2C:4:10 - may or may not support HW virtualization in VMs SCS-2C:4:10-kvm-hwv SCS-2C:4:10-hwv - not recommended, but allowed SCS-2C:4:10-hwv-xen - illegal, wrong ordering","s":"[OPTIONAL] Hardware virtualization / Nested virtualization","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-hardware-virtualization--nested-virtualization","p":2828},{"i":2850,"t":"Arch details provide more details on the specific CPU: Vendor Generation Frequency Generation and Vendor​ The generations are vendor specific and can be left out. Not specifying arch means that we have a generic CPU (x86-64). Generation i (Intel x86-64) z (AMD x86-64) a (AArch64) r (RISC-V) 0 pre Skylake pre Zen pre Cortex A76 TBD 1 Skylake Zen-1 (Naples) A76/NeoN1 class TBD 2 Cascade Lake Zen-2 (Rome) A78/x1/NeoV1 class TBD 3 Ice Lake Zen-3 (Milan) A71x/NeoN2 (ARMv9) TBD 4 Zen-4 (Genoa) TBD It is recommended to leave out the 0 when specifying the old generation; this will help the parser tool, which assumes 0 for an unspecified value and does leave it out when generating the name for comparison. In other words: 0 has a meaning of \"rather old or unspecified\". Frequency Suffixes​ Suffix Meaning h >2.75GHz all-core hh >3.25GHz all-core hhh >3.75GHz all-core Examples​ SCS-2C:4:10n SCS-2C:4:10n-z SCS-2C:4:10n-z3 SCS-2C:4:10n-z3h SCS-2C:4:10n-z3hh SCS-2C:4:10n-bms-z SCS-2C:4:10n-bms-z3 SCS-2C:4:10n-bms-z3 SCS-2C:4:10n-bms-z3h SCS-2C:4:10n-bms-z3hh","s":"[OPTIONAL] CPU Architecture Details","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-cpu-architecture-details","p":2828},{"i":2852,"t":"Note that these are optional — it is recommended for providers to encode this information into the flavor name, so there is a systematic way of differentiating flavors. Providers could leave it out however, leaving it to extra_specs to make these flavor capabilities discoverable. Nothing prevents providers from registering the same flavor under a secondary (or tertiary) name. -GX[N][:M[h]] indicates a Pass-Through GPU from vendor X of gen N with M compute units / SMs / EUs exposed. -gX[N][:M[h]] indicates a vGPU from vendor X of gen N with M compute units / SMs / EUs assigned. Note that the vendor letter is mandatory, generation and compute units are optional. GPU Vendor N nVidia A AMD I Intel Generations could be nVidia (f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, ...), AMD (GCN-x=0.x, RDNA1=1, RDNA2=2), intel (Gen9=0.9, Xe(12.1)=1, ...), ... (Note: This may need further work to properly reflect what's out there.) The optional h suffix to the comput unit count indicates high-performance (e.g. high freq or special high bandwidth gfx memory such as HBM); h can be duplicated for even higher performance. -ib indicates Inifinband networking. More extensions will be forthcoming. Extensions need to be specified in the above mentioned order.","s":"[OPTIONAL] Extra features","u":"/standards/scs-0100-v1-flavor-naming","h":"#optional-extra-features","p":2828},{"i":2854,"t":"Example Decoding SCS-2C:4:10n 2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk SCS-8Ti:32:50p-i1 8 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe SCS-1L:1u:5 1 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific) SCS-16T:64:200s-GNa:64-ib 16 dedicated threads, 64GiB RAM, 200GB local SSD, Inifiniband, 64 Passthrough nVidia Ampere SMs SCS-4C:16:2x200p-a1 4 dedicated Arm64 cores (A78 class), 16GiB RAM, 2x200GB local NVMe drives SCS-1V:0.5 1 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)","s":"Proposal Examples","u":"/standards/scs-0100-v1-flavor-naming","h":"#proposal-examples","p":2828},{"i":2856,"t":"These are flavors expected to exist on standard SCS clouds (x86-64). We expect disk sizes to be 5, 10, 20, 50, 100, 200, 500, 1000GB, 2000GB. We expect a typical CPU GiB vCPU:RAM ratio Mandatory Flavors 1:4 SCS-1V:4, SCS-1V:4:10 2:8 SCS-2V:8, SCS-2V:8:20 4:16 SCS-4V:16, SCS-4V:16:50 8:32 SCS-8V:32, SCS-8V:32:100 1:2 SCS-1V:2, SCS-1V:2:5 2:4 SCS-2V:4, SCS-2V:4:10 4:8 SCS-4V:8, SCS-4V:8:20 8:16 SCS-8V:16, SCS-8V:16:50 16:32 SCS-16V:32, SCS-16V:32:100 1:8 SCS-1V:8, SCS-1V:8:20 2:16 SCS-2V:16, SCS-2V:16:50 4:32 SCS-4V:32, SCS-4V:32:100 1:1 SCS-1L:1, SCS-1L:1:5 Note that all vCPUs are oversubscribed — the smallest 1L:1 flavor allows for heavy oversubscription (note the L), and thus can be offered very cheaply — imagine jump hosts ... Disks types are not specified (and expected to be n or h typically). The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM compute hosts) to offer all flavors. Note: Compared to previous drafts, we have heavily reduced the variations on disk sizes — this reflects that for the standard networked cinder disks, you can pass blockdevice_mapping_v2 on server (VM) creation to allocate a boot disk of any size you desire. We have scaled the few mandatory disk sizes with the amount of RAM. For each flavor there is also one _without a pre-attached disk — these are meant to be used to boot from a volume (either created beforehand or allocated on-the-fly with block_device_mapping_v2, e.g. openstack server create --flavor SCS-1V:2 --block-device-mapping sda=IMGUUID:image:12:true to create a bootable 12G cinder volume from image IMGUUID that gets tied to the VM instance lifecycle.)","s":"Standard SCS flavors","u":"/standards/scs-0100-v1-flavor-naming","h":"#standard-scs-flavors","p":2828},{"i":2858,"t":"To be certified as an SCS compliant x86-64 IaaS platform, you must offer all standard SCS flavors according to the previous section. (We may define a mechanism that allows exceptions to be granted in a way that makes this very transparent and visible to clients.) You are allowed to understate your performance; you may implement a SCS-1Vl:1:5 flavor with a flavor that actually implements SCS-1T:1:5n (i.e. you dedicate a secured hyperthread instead of high oversubscription) or even SCS-1D:1.5:8s (1 dedicated core, 50% more RAM and a 8GiB SSD). We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V:32:100). Larger providers that offer more details are expected to still also offer the short variants for usability and easier portability, even beyond the mandated flavors. You must be very careful to expose low vCPU guarantees (L instead ov V), insecure hyperthreading/microcode i, non-ECC-RAM u, memory oversubscription o. Note that omitting these qualifiers is overstating your security, reliability or performance properties and may be reason for clients to feel betrayed or claim damages. It might in extreme cases also cause SCS to withdraw certification along with public statements. You may offer additional SCS- flavors, following the naming scheme outlined here. You may offer additional flavors, not following above scheme. You must not offer flavors with the SCS- prefix which do not follow this naming scheme. You must not extend the SCS naming scheme with your own suffices; you are encouraged however to suggest extensions that we can discuss and add to the official scheme. Note that all letters are case-sensitive. In case you wonder: Feature indicators are capitalized, modifiers are lower case. (An exception is the uppercase -G for a passthrough GPU vs. lowercase -g for vGPU.)","s":"Naming policies","u":"/standards/scs-0100-v1-flavor-naming","h":"#naming-policies","p":2828},{"i":2860,"t":"Note that we expect most clouds to prefer short flavor names, not indicating CPU details or hypervisor types. See above list of standard flavors to get a feeling. However, more successful providers will often need to differentiate their offerings in response to customer demand and allow customers to request flavors with specific detailed properties. The goal of this proposal is to avoid providers to invent their own names and then refer customers to extra_specs or worse a non-machine-readable service description to find out the details. So a cloud provider might well evolve from offering SCS-8T:16:50 to offering SCS-8T:16:50n, SCS-8T:16:50n-i2 and SCS-8T:16:50n-a2 to specify that he is using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome. We would expect the cloud provider to still offer the generic flavor SCS-8C:16:50 and allow the scheduler (placement service) to pick both more specific types (or just one if e.g. capacity management considerations suggest so). We would expect providers in such cases to ensure that the price of a requested flavor does not depend on the scheduler decisions. We are looking into the metadefs mechanism and extra_specs to allow customers to ask for specific flavor properties without the need to encode all these flavor details into the flavor name, so the optional pieces may not be needed much. However, there must be a way to request flavor properties without encoding the need into an image — this indirection is considered broken by the SCS team.","s":"Rationale","u":"/standards/scs-0100-v1-flavor-naming","h":"#rationale","p":2828},{"i":2862,"t":"There is a script in flavor_name_check.py which can be used to decode, validate and construct flavor names. This script must stay in sync with the specification text. Ensure you have your OpenStack tooling (python3-openstackclient, OS_CLOUD) setup and call tools/flavor-name-check.py -c $(openstack flavor list -f value -c Name) to get a report on the flavor list compliance of the cloud environment.","s":"Validation","u":"/standards/scs-0100-v1-flavor-naming","h":"#validation","p":2828},{"i":2864,"t":"Some providers might offer VM services (\"IaaS\") without trying to adhere to SCS standards, yet still finding the flavor naming standards useful. The Gaia-X Technical Committee's Provider Working Group (WG) would seem like a logical place for such dicussions then. If so, we could replace the SCS- prefix with a GX- prefix and transfer the naming scheme governance from the SCS project to the Gaia-X Provider WG (where we participate). SCS certification would then reference the Gaia-X flavor naming standard as a requirement.","s":"Beyond SCS: Gaia-X","u":"/standards/scs-0100-v1-flavor-naming","h":"#beyond-scs-gaia-x","p":2828},{"i":2868,"t":"Entropy is a concept that is widely used in the scope of information technology. It is a measurement of the amount of disorder or randomness in a system. Entropy is used to measure the amount of information in a self-contained system, as well as the amount of incertitude that exists in this system.","s":"Entropy in information technology","u":"/standards/scs-0101-v1-entropy","h":"#entropy-in-information-technology","p":2865},{"i":2870,"t":"Cryptography is a very prominent, albeit not the only application that heavily relies on entropy for operations such as creating secure keys. When the available entropy runs out, said operations can stall and take an abnormally long amount of time, which in turn can lead to malfunctions, e.g., with OpenSSL or load balancers.","s":"Real-world uses of entropy","u":"/standards/scs-0101-v1-entropy","h":"#real-world-uses-of-entropy","p":2865},{"i":2872,"t":"In traditional baremetal systems the amount of incertitude is sourced from the randomness of the read/write cycles of the disk heads of a disk drive, bus timings, or keyboard timings, to name a few. More recent methods of generating entropy include measuring IRQ jitter (available in Linux since kernel 5.4 or, before that, via a daemon such as HavegeD) as well as dedicated CPU instructions (available in virtually all major CPUs: RDSEED or RDRAND on x86_64 and RNDR on arm64). Finally, a dedicated device can be utilized — if present — that is called hardware random number generator or HRNG for short. For instance, the Trusted Platform Module includes a HRNG. On Linux systems, the HRNG appears as /dev/hwrng. Note that, while the dedicated CPU instructions can be construed as a HRNG, they are not treated as such by the kernel, i.e., they do not appear as /dev/hwrng! The Linux kernel combines multiple sources of entropy into a pool. To this end, it will use all of the sources discussed so far with one exception: the HRNG must be fed into the pool (if so desired) via the daemon rngd. The kernel converts the entropy from the pool into cryptographically secure random numbers that appear under /dev/random and /dev/urandom. With kernel 5.18, the algorithm that accomplishes said conversion has been drastically improved (see linux-rng-5.17-18), so much so that running out of entropy is virtually ruled out. These patches have now also arrived in the upstream LTS images.","s":"Sources of entropy","u":"/standards/scs-0101-v1-entropy","h":"#sources-of-entropy","p":2865},{"i":2874,"t":"Virtual instances or virtual machines do not have the traditional sources of entropy mentioned above. However, the more recent methods mentioned above do work just fine (the CPU instructions are not privileged). Alternatively, a virtualized HRNG called virtio-rng can be established that injects entropy from the host into the instance, where this entropy can be sourced optionally from either the host's /dev/random or some HRNG in the host. This virtualized HRNG behaves just like a real one, that is, it appears as /dev/hwrng, and the daemon rngd must be used to feed it into the kernel's entropy pool. On a side note, the kernel exposes available HRNGs via the special directory /sys/devices/virtual/misc/hw_random. In particular, the file rng_available lists availabe HRNGs while the file rng_current contains the HRNG currently used. In summary, with current kernels and CPUs entropy in virtual instances is readily available to a sufficient degree. In addition, the host's entropy sources can be injected using virtio-rng if so desired, e.g., to enable access to a HRNG.","s":"Entropy in virtual instances","u":"/standards/scs-0101-v1-entropy","h":"#entropy-in-virtual-instances","p":2865},{"i":2876,"t":"As stated above, good sources of entropy are paramount for many important applications. This standard ensures that sufficient entropy will be available in virtual instances.","s":"Motivation","u":"/standards/scs-0101-v1-entropy","h":"#motivation","p":2865},{"i":2879,"t":"It is recommended that all flavors have the following attribute: hw_rng:allowed=True The following attributes are optional: hw_rng:rate_bytes - The allowed amount of bytes for the the guest to read from the host's entropy per period. hw_rng:rate_period - Sets the duration of a read period in seconds.","s":"Flavors","u":"/standards/scs-0101-v1-entropy","h":"#flavors","p":2865},{"i":2881,"t":"It is recommended to use images having a kernel (patch level) version 5.18 or up. This condition is already satisfied by every mandatory image defined in the Image Metadata Standard. It is recommended that images activate the attribute hw_rng_model: virtio. The daemon rngd must be installed (usually from rng-tools or rng-utils). The user may choose to use the virtio-rng device via rngd.","s":"Images","u":"/standards/scs-0101-v1-entropy","h":"#images","p":2865},{"i":2883,"t":"Compute nodes must use CPUs that offer instructions for accessing entropy (such as RDSEED or RDRAND on x86_64 or RNDR on arm64), and these instructions may not be filtered by the hypervisor. Compute nodes may provide a HRNG via rngd.","s":"Compute nodes","u":"/standards/scs-0101-v1-entropy","h":"#compute-nodes","p":2865},{"i":2886,"t":"Many clouds offer standard Operating System images for their users' convenience. To make them really useful, they should contain meta data (properties) to allow users to understand what they can expect using these images. The specification is targeting images that are managed by the service provider, provided for public consumption. The spec or parts of it however might turn out to be useful whenever someone manages images for somebody else's consumption.","s":"Motivation","u":"/standards/scs-0102-v1-image-metadata","h":"#motivation","p":2884},{"i":2888,"t":"We categorize the image properties into a few buckets Technical requirements and features Image handling aspects Licensing/Maintenance/Support aspects","s":"Overview","u":"/standards/scs-0102-v1-image-metadata","h":"#overview","p":2884},{"i":2890,"t":"We suggest plain OS images to be named \"Distribution Version\", e.g. \"openSUSE Leap 15.3\" or \"Ubuntu 20.04\" or \"CentOS 8\", \"Windows Server 2012R2\". We do not normally recommend to add more detailed patch levels into the name. Special variants that include specific non-standard features should be named \"Distribution Version Feature1 Feature2\". There are several policies possible to provide updated images to include the latest bug- and security fixes. This is outlined in update policy description below.","s":"Naming","u":"/standards/scs-0102-v1-image-metadata","h":"#naming","p":2884},{"i":2892,"t":"This is dependent on whether we deal with VM images or container images. For VM images (OpenStack), we recommend to use the properties as described in the OpenStack Image documentation. The following properties are considered mandatory: architecture, hypervisor_type min_disk_size (in GiB), min_ram (in MiB) os_version, os_distro hw_rng_model, hw_disk_bus (scsi recommended, and then setting hw_scsi_model is also recommended) Note: Disk sizes tend to be measured in GB = 10^9 and not GiB = 2^30 in the disk industry, but OpenStack uses GiB. The following properties are recommended (if the features are supported): os_secure_boot, hw_firmware_type hw_watchdog_action, hw_mem_encryption, hw_pmu, hw_video_ram, hw_vif_multiqueue_enabled The trait:XXX=required property can be used to indicate that certain virtual hardware features XXX are required.","s":"Technical requirements and features","u":"/standards/scs-0102-v1-image-metadata","h":"#technical-requirements-and-features","p":2884},{"i":2895,"t":"It is recommended that provider managed images are regularly updated. This means that users referencing an image by name will always get the latest image for the operating system indicated by that name (which includes a version number, but not the patch level). Technically, the thus updated image is a new image and will thus carry a new UUID. It is recommended that the old image gets renamed (e.g. build date or patch level attached) and hidden (os_hidden=true), but remains accessible via its (unchanged) UUID for some time. The update handling by the provider is described via the properties replace_frequency, uuid_validity, provided_until, and hotfix_hours. The replace_frequency, provided_until, and hotfix_hours fields reference to the image as referenced by its name. replace_frequency meaning yearly the image will get replaced at least once per year quarterly the image will get replaced at least once per quarter monthly the image will get replaced at least once per month weekly the image will get replaced at least once per week daily the image will get replaced at least once per day critical_bug the image will get replaced for critical issues only never the image referenced by name will never change (until the date provided_until) Note the at least wording: Providers can replace images more often. The frequency is starting from the first release; so an image published on 2021-04-14 with an update frequency of monthly, should be replaced no later than 2021-05-14. Due to weekends etc., up to 3 days later is not considered a violation of this policy. So a valid sequence from an image with monthly update frequency might be 2021-04-14, 2021-05-14, 2021-06-15, 2021-07-14, 2021-07-27 (hotfix), 2021-08-13 ... Promises to update the registered public images typically depend on upstream image providers (Linux distributors, OS vendors) keeping their promises to build and provide updated images. Failures from upstream are not a reason to claim the cloud provider to be in violation of his promises. However, if the provider observes massive upstream failures (which can e.g. cause increased security risks), we advise the provider to inform the users. We recommend updating images at least monthly. The hotfix_hours field indicates how providers deal with critical security issues that affect the images; it is an optional field that contains a numerical value, indicating how quickly (in hours) a new image is provided after the latter of the points in time that the issue becomes public and a tested fix is available as maintenance update from the upstream distribution. A value of 0 indicates a best-effort approach without firm SLAs; the field not being present indicates no commitment. A value of 48 would indicate that the provider commits to a new image within 48hrs. A critical issue is defined as a security vulnerability with a CVSS score of 9.0 or higher that affects a package that is included in the image. The provided_until field is supposed to contain a date in YYYY-MM-DD format that indicates until when an image under this name will be provided and (according to the replace_frequency) updated at least. (Providers are free to provide updates for longer or leave the non-updated image visible for longer.) If this field is set to none, no promises are made, if it is set to notice, updates will be provided until a deprecation notice is published. (The values are the same as for below uuid_validity, except that forever and last-N don't make any sense.) The uuid_validity field indicates how long the public image will be referencable by its UUID. uuid_validity meaning none UUID will only be valid as long as the content does not change last-N The last N images for newer replacement will remain accessible via UUID YYYY-MM-DD UUID will be valid until at least the date YYYY-MM-DD notice UUID will remain valid until a deprecation notice will be published forever UUID will remain valid for as long as the cloud operates Note that the old images must be hidden from the image catalogue or renamed (or both) to avoid failing referencing by name. Note that last-N may be limited by the provided_until date. The three properties uuid_validity, provided_until and replace_frequency are mandatory; the field hotfix_hours is optional. All dates are in UTC. Example​ Providing an image with name OPSYS MAJ.MIN with replace_frequency=monthly, provided_until=2022-09-30, uuid_validity=2022-12-31, hotfix_hours=0 means that we will have a new image with this name at least once per month (starting from the initial release) until the end of September 2022. Old images will be hidden and/or renamed, but remain accessible via their UUID until at least the end of 2022 (in Universal Time). The provider makes an effort to replace images upon critical security issues out of order.","s":"Image updating","u":"/standards/scs-0102-v1-image-metadata","h":"#image-updating","p":2884},{"i":2897,"t":"Mandatory: image_source needs to be a URL to point to a place from which the image can be downloaded. (Note: This may be set to the string \"private\" to indicate that the image can not be freely downloaded.) Mandatory: image_description needs to be an URL (or text) with release notes and other human readable data about the image. Recommended tag: managed_by_VENDOR Note that for most images that come straight from an upstream source, image_description should point to a an upstream web page where these images are described. If download links are available as well on that page, image_source can point to the same page, otherwise a more direct link to the image should be used, e.g. directly linking the .qcow2 or .img file. If providers have their own image building machinery or do some post-processing on top of upstream images, they should point to the place where they document and offer these images.","s":"Image Origin","u":"/standards/scs-0102-v1-image-metadata","h":"#image-origin","p":2884},{"i":2899,"t":"Mandatory: image_build_date needs to be YYYY-MM-DD or YYYY-MM-DD hh:mm[:ss] (time in UTC, 24hrs clock). All publicly released and generally recommended patches before this date must be included in the image build. If the cutoff date is earlier, this cutoff date needs to be set instead, even if the actual build happens significantly after the cutoff date. If not all patches can be included for a good reason, then the patchlevel field (see below) must be used to describe the patch status. Mandatory: image_original_user is the default login user for the operating system which can connect to the image via the injected SSH key or provided password. (This can be set to none if no default user name exists for the operating system.) Optional: patchlevel can be set to an operating specific patch level that describes the patch status — typically we would expect the image_build_date to be sufficient. Recommended: os_hash_algo and os_hash_value: The sha256 or sha512 hash for the image file. (This references the image file in the format it is stored in, we recommend raw over qcow2 for systems that use ceph.) Note that these values are typically generated automatically upon image registration. Recommended tag: os:OPERATINGSYSTEM","s":"Image build info","u":"/standards/scs-0102-v1-image-metadata","h":"#image-build-info","p":2884},{"i":2901,"t":"Some images require a license; in many cases the cloud providers include the license cost by a per-use (e.g. hourly) fee. However, it is also possible sometimes that customers use their own license agreements with the OS vendor with a bring-your-own-license (BYOL) program. These properties may be attached to the image. Note that free Linux images might not use any of these properties, except maybe maintained_until. Note that Windows images would typically require license_included, subscription_included. A boolean property that is not present is considered to be false. Optional: license_included (boolean) indicates whether or not the flavor fee includes the licenses required to use this image. This field is mandatory for images that contain software that requires commercial licenses. Optional: license_required (boolean) indicates whether or not a customer must bring its own license to be license compliant. This can not be true at the same time as the previous setting. This field is mandatory IF customers need to bring their own license to use the image. Optional: subscription_included (boolean) indicates that the image contains already a maintenance subscription which typically gives access to bug fixes, security fixes and (minor) function updates. If a subscription is included, the CSP should have prepared the image to also receive the provided maintenance updates from the vendor (optionally via a mirror). Optional: subscription_required (boolean) indicates that the customer requires a maintenance subscription from the OS vendor in order to receive fixes (which is often also a prerequisite to be eligible for support). Optional: maintained_until: YYYY-MM-DD promises maintenance from the OS vendor until at least this date (in UTC). Optional: l1_support_contact contains a URI that provides customer support contact for issues with this image. Note that this field must only be set if the service provider does provide support for this image included in the image/flavor pricing (but it might be provided by a contracted 3rd party, e.g. the OS vendor).","s":"Licensing / Maintenance subscription / Support","u":"/standards/scs-0102-v1-image-metadata","h":"#licensing--maintenance-subscription--support","p":2884},{"i":2903,"t":"The script image-md-check.py retrieves the image list from a configured cloud and checks each image for the completeness and consistency of mandatory properties.","s":"Conformance Tests","u":"/standards/scs-0102-v1-image-metadata","h":"#conformance-tests","p":2884},{"i":2906,"t":"We presume that almost nothing has to be done (or indeed can be done), as long as the CPUs and VM images are reasonably recent; only the flavor and image attributes have to be set: flavor: hw_rng:allowed=True , image: hw_rng_model: virtio .","s":"Implementation","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#implementation","p":2904},{"i":2909,"t":"Some checks need to be performed on a live instance. For these checks, it is necessary to choose a sample of VM images to test on. For the time being, the sample MUST contain at least one public image reported by OpenStack. This may be extended in the future.","s":"Images Sample","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#images-sample","p":2904},{"i":2911,"t":"For every image in the chosen sample, the following items MUST be detected and reported as an error: the service rngd is not running, the special file /proc/sys/kernel/random/entropy_avail does not contain the value 256 (pinned since kernel 5.18), the number of FIPS 140-2 failures exceeds 3 out of 1000 blocks tested, as determined by cat /dev/random | rngtest -c 1000 . Note: The latter two items act as surrogates for the following item, which cannot be detected directly: CPU instructions for accessing entropy are not available to the VMs.","s":"Errors","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#errors","p":2904},{"i":2913,"t":"The following items MUST be detected and reported as a warning: any flavor missing the attribute hw_rng:allowed=True, any image missing the attribute hw_rng_model: virtio, Note that the requirement regarding the kernel patch level will not be checked, because of two reasons: (a) we already check the file entropy_avail (see subsection on Errors), and (b) users can always choose a recent image, as ensured by the image metadata standard.","s":"Warnings","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#warnings","p":2904},{"i":2915,"t":"The script entropy-check.py connects to OpenStack and performs the checks described in this section.","s":"Implementation","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#implementation-1","p":2904},{"i":2917,"t":"None.","s":"Manual Tests","u":"/standards/scs-0101-w1-entropy-implementation-testing","h":"#manual-tests","p":2904},{"i":2921,"t":"In OpenStack environments there is a need to define different flavors for instances. The flavors are pre-defined by the operator, the customer can not change these. OpenStack providers thus typically offer a large selection of flavors. While flavors can be discovered (openstack flavor list), it is helpful for users (DevOps teams), to have a guaranteed set of flavors available on all SCS clouds, so these need not be discovered.","s":"Motivation","u":"/standards/scs-0103-v1-standard-flavors","h":"#motivation","p":2918},{"i":2923,"t":"The following extra specs are recognized, together with the respective semantics: scs:name-vN=NAME (where N is 1 or 2, and NAME is some string) means that the flavor is one of the standard SCS flavors, and the requirements of Section \"Standard SCS flavors\" below apply. scs:cpu-type=shared-core means that at least 20% of a core in >99% of the time, measured over the course of one month (1% is 7,2 h/month). The cpu-type=shared-core corresponds to the V cpu modifier in the flavor-naming spec, other options are crowded-core (L), dedicated-thread (T) and dedicated-core (C). scs:diskN-type=ssd (where N is a nonnegative integer, usually 0) means that the root disk N must support 1000 sequential IOPS per VM and it must be equipped with power-loss protection; see scs-0110-v1-ssd-flavors. The diskN-type=ssd setting corresponds to the s disk modifier, other options are nvme (p), hdd (h) and network (n). Only flavors without disk and those with diskN-type=network can be expected to support live-migration. Whenever ANY of these are present on ANY flavor, the corresponding semantics must be satisfied.","s":"Properties (extra specs)","u":"/standards/scs-0103-v1-standard-flavors","h":"#properties-extra-specs","p":2918},{"i":2925,"t":"Following are flavors that must exist on standard SCS clouds (x86-64). Note that this statement does not preclude the existence of additional flavors.","s":"Standard SCS flavors","u":"/standards/scs-0103-v1-standard-flavors","h":"#standard-scs-flavors","p":2918},{"i":2927,"t":"Recommended name vCPUs vCPU type RAM [GiB] Root disk [GB] Disk type SCS-1V-4 1 shared-core 4 SCS-2V-8 2 shared-core 8 SCS-4V-16 4 shared-core 16 SCS-4V-16-100s 4 shared-core 16 100 ssd SCS-8V-32 8 shared-core 32 SCS-1V-2 1 shared-core 2 SCS-2V-4 2 shared-core 4 SCS-2V-4-20s 2 shared-core 4 20 ssd SCS-4V-8 4 shared-core 8 SCS-8V-16 8 shared-core 16 SCS-16V-32 16 shared-core 32 SCS-1V-8 1 shared-core 8 SCS-2V-16 2 shared-core 16 SCS-4V-32 4 shared-core 32 SCS-1L-1 1 crowded-core 1","s":"Mandatory","u":"/standards/scs-0103-v1-standard-flavors","h":"#mandatory","p":2918},{"i":2929,"t":"Recommended name vCPUs vCPU type RAM [GiB] Root disk [GB] Disk type SCS-1V-4-10 1 shared-core 4 10 (any) SCS-2V-8-20 2 shared-core 8 20 (any) SCS-4V-16-50 4 shared-core 16 50 (any) SCS-8V-32-100 8 shared-core 32 100 (any) SCS-1V-2-5 1 shared-core 2 5 (any) SCS-2V-4-10 2 shared-core 4 10 (any) SCS-4V-8-20 4 shared-core 8 20 (any) SCS-8V-16-50 8 shared-core 16 50 (any) SCS-16V-32-100 16 shared-core 32 100 (any) SCS-1V-8-20 1 shared-core 8 20 (any) SCS-2V-16-50 2 shared-core 16 50 (any) SCS-4V-32-100 4 shared-core 32 100 (any) SCS-1L-1-5 1 crowded-core 1 5 (any)","s":"Recommended","u":"/standards/scs-0103-v1-standard-flavors","h":"#recommended","p":2918},{"i":2931,"t":"The figures given in the table (number of CPUs, amount of RAM, root disk size) must match precisely the corresponding figures in the flavor. In addition, the following properties must be set (in the extra_specs): scs:name-v1 to the recommended name, but with each dash AFTER the first one replaced by a colon, scs:name-v2 to the recommended name, scs:cpu-type to shared-core or crowded-core, reflecting the vCPU type, scs:disk0-type not set if no disk is provided, otherwise set to ssd or some other value, reflecting the disk type.","s":"Guarantees and properties","u":"/standards/scs-0103-v1-standard-flavors","h":"#guarantees-and-properties","p":2918},{"i":2933,"t":"We expect the most used vCPU GiB Note that all vCPUs of SCS standard flavors are oversubscribed — the smallest 1L-1 flavor allows for heavy oversubscription (note the L), and thus can be offered very cheaply — imagine jump hosts ... The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM compute hosts) to offer all flavors. Except for the two flavors with SSD root volume, disks types are not specified (and expected to be network disks (Ceph/Cinder) or local SATA/SAS disks typically). We only included a limited variation of disk sizes — this reflects that for the standard networked cinder disks, you can pass block_device_mapping_v2 on server (VM) creation to allocate a boot disk of any size you desire. We have scaled the few recommended disk sizes with the amount of RAM. For each flavor there is also one without a pre-attached disk — these are meant to be used to boot from a volume (either created beforehand or allocated on-the-fly with block_device_mapping_v2, e.g. openstack server create --flavor SCS-1V-2 --block-device-mapping sda=IMGUUID:image:12:true to create a bootable 12G cinder volume from image IMGUUID that gets tied to the VM instance life cycle.)","s":"Remarks","u":"/standards/scs-0103-v1-standard-flavors","h":"#remarks","p":2918},{"i":2935,"t":"The script flavors-openstack.py will read the lists of mandatory and recommended flavors from a yaml file provided as command-line argument, connect to an OpenStack installation, and check whether the flavors are present and their extra specs are correct. Missing flavors will be reported on various logging channels: error for mandatory, info for recommended flavors. Incorrect extra specs will be reported as error in any case. The return code will be non-zero if the test could not be performed or if any error was reported.","s":"Conformance Tests","u":"/standards/scs-0103-v1-standard-flavors","h":"#conformance-tests","p":2918},{"i":2937,"t":"The openstack-flavor-manager is able to create all standard, mandatory SCS flavors for you. It takes input that can be generated by flavor-manager-input.py.","s":"Operational tooling","u":"/standards/scs-0103-v1-standard-flavors","h":"#operational-tooling","p":2918},{"i":2939,"t":"The list of standard flavors used to be part of the flavor naming standard up until version 3. The following changes have been made to the list in comparison with said standard: the flavor names have been turned into recommendations, and the properties have been introduced in order to help discoverability. Note that the flavors with fixed size root disks have all moved to Recommended with scs-0100-v3. This means that they are not a certification requirement any longer, but we still recommend implementing these for backwards compatibility reasons. Also in that standard, two flavors with SSD+ root disks have been added, as defined in scs-0110-v1-ssd-flavors.md","s":"Previous standard versions","u":"/standards/scs-0103-v1-standard-flavors","h":"#previous-standard-versions","p":2918},{"i":2942,"t":"SCS defines an IaaS Flavor Naming standard that mandates a number of standard flavors to be available in each SCS-compliant IaaS offering. While offering or exposing IaaS is not a requirement for SCS-compliant infrastructure offerings — SCS allows for platforms only exposing the container layer (plus S3 compatible object storage) for wave 2 (container-based) cloud-native workloads -- the SCS reference implementation does include a complete IaaS implementation that many providers want to expose as they have customers desiring access at this layer for wave 1 (VM-based) cloud-native workloads or for the virtualization of more classical (not cloud-native) workloads. The IaaS implementation thus comes with standards. This Decision Record is about adding a few mandatory flavors on the IaaS level that include flavors with local SSD (or better) storage.","s":"Introduction","u":"/standards/scs-0110-v1-ssd-flavors","h":"#introduction","p":2940},{"i":2944,"t":"The currently defined standard flavors do not include flavors that use local storage. For certain workloads such as databases or big data filesystems, local storage is highly desirable as replication may be handled at the application layer, making replication/redundancy in a networked storage solution (ceph in the SCS reference implementation) an unneeded and undesired property. Furthermore, write access to networked and replicated storage typically incurs a certain latency, as the writes can only be acknowledged once all the replicas have confirmed that the data has hit stable storage. Write latency is critical for e.g. relational database performance. The main purpose for the IaaS layer in SCS is to perform as a solid foundation to provide and manage kubernetes container clusters in a multi-tenant scenario. As such the standards at the IaaS layer should ensure that all the needed types of resources are available for the container clusters. This is not currently the case: In a scenario with multiple k8s control-plane nodes set up via kubeadm (as part of the k8s cluster-api automation), the control plane nodes each run an etcd instance and together form an etcd cluster. etcd is sensitive to scheduling, network and storage latencies. While network latencies and scheduling latencies have not been observed to be an issue in clusters within one cloud region, the storage latency is. With remote networked storage as delivered from ceph, the long tail of write latency causes etcd to often time out heartbeats, causing a new leader election with a leader change, preventing control plane changes on k8s for a few seconds. Too many leader changes can slow down cluster operation and even bring it to a halt. The etcd requirements are well documented. In particular, over a hundred of sequential IOPS are recommended. This requires write latencies in the range of a single-digit ms (or better).","s":"Motivation","u":"/standards/scs-0110-v1-ssd-flavors","h":"#motivation","p":2940},{"i":2947,"t":"One-node etcd (backed by redundant storage)​ If k8s uses only one control plane node, there will only be only one etcd node, avoiding timed out heartbeats. Single node control planes are typically not recommended for production workloads though. They are limited with respect to control plane performance, have a higher chance to fail (as a single node failure can create cluster control-plane downtime) and can not undergo rolling upgrades. Though not the normal setup with kubeadm, it is possible to use a multi-node control plane using a single-node etcd. This shares some of the challenges of single-node control-planes, although recovery may be faster to perform at least in scenarios where the etcd backend storage is redundant and not affected by the single-node outage. Neither scenario fulfills typical requirements for production workloads. RAM (tmpfs) etcd storage​ etcd could keep its database in volatile memory (e.g. on a tmpfs filesystem). For multi-node etcd clusters, this could actually be made work, as long as at least one cluster member stays alive and proper care is taken to remove shut-down nodes from the cluster. A loss of power affecting all nodes or a hardware maintenance operation not tracking etcd needs would result in a complete loss of all cluster state. The control plane nodes would require live migration to avoid this in the maintenance case. For the power loss scenario, a frequent backup might mitigate the cluster state loss case somewhat. The etcd database is normally limited to 2GiB in size, which is something that is realistic to keep in main memory. (Typical database sizes are much smaller.) This option requires additional care and may not be suitable for all production scenarios, but would seem a possible fallback position for etcd. It does obviously not address the database scenario. Heartbeat slowdown​ To avoid causing too many fail-overs by occasional high latencies, the frequency of heartbeats can be lowered from the default 1/100ms. The reelection timeout should change along with it (typically set to 10 beats). This will cause etcd to take a bit more time to notice the loss of a node, which is not typically critical if done within reasonable limits. This change however does not fully address the issue — occasional write latencies above 100ms will still cause failed heartbeats, just less often. This change has been implemented in SCS's k8s-cluster-api-provider reference implementation: The heartbeat has been changed from 1/100ms (10/s) to 1/250ms (4/s) and the reelection timeout from 1s to 2.5s. The etcd process also is afforded a higher CPU priority (lower niceness), resulting in a lower scheduling latency, as high-prio processes preempt lower-prio ones when they get woken up. The etcd process also gets its IO priority increased to get treated preferentially in case the IO scheduler has many outstanding requests. This has some positive effects with the CFQ IO scheduler. The slower heartbeat and the priority tweaks do lower the amount of leader changes but are insufficient to completely address the issue on the tests performed against networked ceph-backed storage. Filesystem tuning​ Databases must ensure that certain data has hit stable storage before acknowledging writes — this is required in order to live up to the ACID guarantees in situations when disruptions might happen. Databases typically use fsync() calls to ensure that write buffers are written to real persistent storage unless they use raw/direct block devices circumventing Linux's page and buffer cache. etcd normally uses a write-ahead-log (WOL) file that lives on a Linux filesystem and uses fsync to ensure the correct write ordering. Trouble with fsync is that it also causes unrelated data to be written out with most existing Linux filesystems, adding to the latency. It is possible to tell the Linux filesystems to not wait for all data to have hit storage before returning from fsync() calls. This avoids the latency caused by fsync but also subverts the very reason for using fsync: In case of a disruption (OS crash, power outage, loss of connection to storage, ...), the state is likely not consistent, as the kernel has lied to the application about data having been written out. Recovery from such a scenario can range from smooth to impossible. In a multi-node cluster, this may not be as bad as it sounds — if only one node is affected by a disruption, the crashed node can be recovered by resyncing the data from other nodes. In practice an inconsistent state would be considered too risky and it should be preferred to set up a fresh node to join the existing etcd cluster. This would need to be implemented to make this option less risky. The reference implementation has an option to use these unsafe filesystem settings. However, they are not enabled by default for good reasons. Flavors with local storage​ Flavors with local storage will have their root filesystem on a local storage device. To fulfill the need for high IOPS that etcd and especially databases have, the local storage device should be a solid state device — an SSD or NVMe device. While some use cases might even be fulfilled with local spinning disks (or raid arrays of local spinning disks). Local solid state storage avoids any network overhead and offers best latency. It however is not typically redundant, meaning that the loss of the device or the complete hardware node will result in data loss. So it is meant to be used with applications such as database clusters, replicating filesystems or block devices or etcd which can handle this at the application layer. The flavor naming spec in SCS allows performance to be understated — a flavor with NVMe storage can be advertised under the SSD storage name (and of course can be offered under both names). Note that this addresses the simple case where the root disk with the root filesystem (and possibly additional filesystems that are set up when first booting) uses the local storage. Scenarios where additional low-latency networked or local storage are made available via cinder and attached for database storage are possible and viable options for some scenarios, but not covered here.","s":"Options considered","u":"/standards/scs-0110-v1-ssd-flavors","h":"#options-considered","p":2940},{"i":2949,"t":"Two new mandatory flavors: SCS-2V-4-20s and SCS-4V-16-100s are added to the SCS flavor naming standard. The first is meant to be a good fit for k8s control nodes with etcd while the latter is a solid base for a small database server. Clouds claiming SCS-compliance for their IaaS layer MUST provide these two additional flavors. Obviously providers MAY offer many more combinations and e.g. create flavors with large local SSDs. The local storage advertised this way MUST support more than 1000 sequential IOPS per VM of both new mandatory types (which means a write latency lower than 1ms — this typically means SSDs/NVMEs that support at least several 10ks of parallel IOPS, not a challenge for current hardware). Local disks, SSDs, NVMes MUST have Power-Loss-Protection such that data reported to be written, but in reality being stored in RAM or SLC cache of an SSD or NVMe, is guaranteed to not be lost in case of a power loss. Like with networked storage, the provider must ensure that data from previous users is not accessible (e.g. by securely erasing it or by using a different encryption key) when local storage gets allocated to a new VM.","s":"Decision","u":"/standards/scs-0110-v1-ssd-flavors","h":"#decision","p":2940},{"i":2951,"t":"Hardware nodes (hypervisors in OpenStack language) that support flavors with local storage (are part of an appropriate OpenStack host aggregate) may have many VMs competing for bandwidth to the attached local storage devices; the host needs to be configured such that it can sustain VMs writing at full speed without causing the host to be overloaded or to cause huge queues for these writes. A more generic approach is to apply storage QoS policies to the VMs to manage bandwidth and IOPS and create the ability to have better performance isolation with certain guarantees. While this is desirable, it has not been found a necessity for etcd in our tests. Disk IO QoS is not part of this spec but may be considered in another one. Live-migration with local storage is significantly more difficult than with networked storage: The contents of the local disks also need to be replicated over to the new host. Live-migration for these VMs may thus take significantly longer or not be possible at all, depending the configuration from the provider. Not supporting live-migration is OK for flavors with local disks according to the flavor naming spec — a capability to indicate whether or not live-migration is supported will be subject to a flavor-metadata discoverability spec that is planned for the future.","s":"Out of Scope","u":"/standards/scs-0110-v1-ssd-flavors","h":"#out-of-scope","p":2940},{"i":2953,"t":"Local storage in OpenStack can be provided directly via nova or via the cinder service. While the latter has the advantage of making volumes visible and manageable via most of the normal cinder capabilities, it has the disadvantage of creating an indirection via iSCSI. This results in higher latency. The requirements in the above spec are not meant to mandate or prevent the implementation via either route.","s":"Implementation note","u":"/standards/scs-0110-v1-ssd-flavors","h":"#implementation-note","p":2940},{"i":2955,"t":"The flavors will be added as mandatory flavors to the flavor-naming standard, which will thus have to be released in a v3. The IOPS and Power-Loss requirements from this decision should become part of the flavor-naming standard for disk type s. When we standardize storage types in the future, additional possibilities to solve the latency requirements for databases and etcd may emerge. When we standardize QoS features there, we may amend this standard with QoS recommendations or possibly requirements. A future flavor metadata discoverability standard will indicate whether or not these flavors can be live-migrated. A future VM metadata standard will allow users to request live-migration and/or cold migration or restart to be or to not be performed.","s":"Related Documents","u":"/standards/scs-0110-v1-ssd-flavors","h":"#related-documents","p":2940},{"i":2957,"t":"The list of mandatory flavors that needs to be present should be added to the SCS-Spec.MandatoryFlavors.yaml spec as soon as this ADR becomes part of the certification requirements. Checks for conforming with IOPS and purging requirements will require test instances to be launched and might become part of a monitoring solution.","s":"Conformance Tests","u":"/standards/scs-0110-v1-ssd-flavors","h":"#conformance-tests","p":2940},{"i":2960,"t":"Volumes in OpenStack are virtual drives. They are managed by the storage service Cinder, which abstracts creation and usage of many different storage backends. While it is possible to use a backend like lvm which can reside on the same host as the hypervisor, the SCS wants to make a more clear differentiation between volumes and the ephemeral storage of a virtual machine. For all SCS deployments we want to assume that volumes are always residing in a storage backend that is NOT on the same host as a hypervisor - in short terms: Volumes are network storage. Ephemeral storage on the other hand is the only storage residing on a compute host. It is created by creating a VM directly from an Image and is automatically los as soon as the VM cease to exist. Volumes on the other hand have to be created from Images and only after that can be used for VMs. They are persistent and will remain in the last state a VM has written on them before they cease to exit. Being persistent and not relying on the host where the VM resides, Volumes can easily be attached to another VM in case of a node outage and VMs be migrated way more easily, because only metadata and data in RAM has to be shifted to another host, accelerating any migration or evacuation of a VM. Volume Types are used to classify volumes and provide a basic decision for what kind of volume should be created. These volume types can sometimes very be backend-specific and it might be hard for a user to choose the most suitable volume type, if there is more than one default type. Nevertheless the most of configuration is done in the backends themself, so volume types only work as a rough classification.","s":"Introduction","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#introduction","p":2958},{"i":2962,"t":"We want to standardize a few varieties of volume types. While a user can choose simple things like size when creating a volume, Volume Types define a few broader aspects of volume. Encryption of volumes for example is solely decided by the volume type. And whether the volume will be replicated is a mix between definiton in the volume type and backend specific configuration, but it's visiblity can only be reached in the volume type. In General: what the different volume types are capable of is highly dependend on both the used backend and the configurations of OpenStack. A few options are worth being at least recommended.","s":"Motivation","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#motivation","p":2958},{"i":2964,"t":"We want to have a discoverable Standard. So there should be no naming conventions as per request by operators. This first decision will have impacts on upstream OpenStack development, as those things, that would be nice to discover, may not be currently dicoverable by users or not at all. There are severel aspects of volume types, which will be discussed in the following:","s":"Design Considerations","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#design-considerations","p":2958},{"i":2966,"t":"Encryption​ Encryption for volumes is an option which has to be configured within the volume type. As an admin it is possible to set encryption-provider, key size, cipher and control location. As an admin it is also currently possible to see these configurations in a volume type with list and show commands. A user should not see these parameters in detail, but a boolean value that descibes whether encryption is used or not. Currently this is not possible in upstream OpenStack. Conclusion: This is a solid aspect to be standardized. But it will need work on OpenStack, to have a boolean value presented to the users. Backend Name​ OpenStack Cinder works with a lot of different backends. They all have some kind of special features, which might be attractive for a user. But showing the name of the backend to users is also considered a security risk by Cinder developers. Overall it is always an option to make users aware of special features through the name and description of a volume type and sometimes even through extra_specs. Conclusion: This should not be standardized. Availability Zones​ Availability Zones are used in Nova and Cinder seperatly to provide an often also physical separation of compute hosts or storage nodes. This leads to two options to consider: Multiple Volume AZs: This might be used if there are different backends present in one IaaS structure. The different volume types are usually used for the different volume AZs. This makes migration between those AZs only be possible for administrators. Volume Types that can be attached to multiple Nova Azs: This option can be seen in the extra specs of a volume type also by normal users. Another option is to use backend specific options, as for example with ceph that directly interacts with nova for this. In that case there will not be any visible extra specs for the users. Another question is how many providers use one of these options or both. Conclusion: The first part doesn't make much sense to standardize, as migration between the volume types can only be done by admins. However the second part might be noteable, but due to the variety of configuration options very hard to standardize. Multiattach​ It is possible in a few backends to attach a volume to multiple VMs. This has to be configured in the Volume Type and this information is also accessable for users. Nevertheless this option also needs a lot of work from users, as those types of volumes have to have a file system, that is capable of multiattach. Many providers don't provide multiattach. Conclusion: It might be noteable, that this already is a discoverable option. Replication​ Replication states, whether or not there are multiple replicas of a volume. Thus answers the question, whether the data could survive a node outage. Again there are different ways to achive replicated volumes. It can either be defined in the volume type and is discoverable also by normal users or it is configured in the backend. The last option is usually used with ceph for example. This makes it hard to discover, whether a volume is replicated or not. Another point is the number of replicas, that exist. Conclusion: Replication is a good option to be standardized. Whether this should be done as a boolean option or if the number of replicas is also something users need to know should still be discussed. Nevertheless due to the different options to configure replication this will be quite complex. QoS​ Quality of Service parameters can be stated in a volume qos object. These objects can then be associated to a volume type (or directly to a volume as an admin only option). But this is optional and thus even good or very good volume QoS parameters that are aquired through hardware configuration and storage parameters, might go by unmentioned. Furthermore the indirection makes it harder to discover the qos for a volume type. Only admins will see the associated qos ID and will have to take a closer look at the qos after discovering the volume type. PLUS: there can only be one qos association for one volume type. But a qos can be used for multiple volumes. Conclusion: The benefit of displaying qos parameters is clear, thus this option should be noted. But are volume qos objects widely used? If not, standardization process would be too much work. Other Backend-specific Highlights​ While every option above described things, that can at least be partly or for admins only visible in volume types, there are many different configuration options in hardware and backend providers can make use of. It is sadly not possible to get them into the volume type directly, but we recommend, that notable configurations are written into the description of a volume type to achieve transparency for the users.","s":"Options considered","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#options-considered","p":2958},{"i":2968,"t":"How often are the different options used by providers and users respectively? Especially important for qos and replication! Regarding Replication: Is the number of replicas needed by users and is it okay for providers to provide this information?","s":"Open questions","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#open-questions","p":2958},{"i":2970,"t":"Aspect Standardize? Discoverability other Things encryption Recommended work needed extra_spec: encrypted=True/False Backend name - - - AZs - - describe as optional and backend-dependend multiattach - yes describe as optional Replication Recommended lot of work either get from backend to OS or as extra_spec defined by deployer Number of Replicas, etc ? lot of work optional, work on it after Replication is standardized Volume QoS ? admin only needs further discussion, should be at least described as optional","s":"Decision","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#decision","p":2958},{"i":2972,"t":"This is an etherpad with a further look into the Options and a few examples.","s":"Related Documents","u":"/standards/scs-0111-v1-volume-type-decisions","h":"#related-documents","p":2958},{"i":2975,"t":"The Sovereign Cloud Stack (SCS) provides standards for a range of cloud infrastructure types. It strives for interoperable and sovereign cloud offerings which can be deployed and used by a wide range of organizations and individuals. To this end, SCS unifies the naming and sourcing of virtual machine images, and for certain images their presence is mandated or recommended.","s":"Introduction","u":"/standards/scs-0104-v1-standard-images","h":"#introduction","p":2973},{"i":2977,"t":"Following the example of the SCS standards YAML, this standard establishes, by means of a YAML file, a mechanism with the following main objectives: to maintain a list of mandatory, recommended, and optional images, which also fixes the source location, to provide a machine-readable document for further processing (e.g. for a compliance tool suite or continuous integration).","s":"Motivation","u":"/standards/scs-0104-v1-standard-images","h":"#motivation","p":2973},{"i":2979,"t":"Image upload via Glance MUST be allowed based on a fair-use policy.","s":"Uploading custom images","u":"/standards/scs-0104-v1-standard-images","h":"#uploading-custom-images","p":2973},{"i":2981,"t":"The YAML file MUST contain the key images, whose value is a list of objects. Each object has one of two forms, as described below.","s":"Standard images YAML","u":"/standards/scs-0104-v1-standard-images","h":"#standard-images-yaml","p":2973},{"i":2983,"t":"Key Type Description Example name String Name of the image \"Debian 12\" status String optional: either mandatory or recommended \"recommended\" source String Prefix of the source URL \"https://cloud.debian.org/images/cloud/bookworm/\" OR: List of strings multiple possible prefixes (see full example below) The meaning of this specification is as follows. If the status is mandatory, then the image MUST be present. If an image by the name given is present, then its image_source property (as described in the Image Metadata standard) MUST start with one of the prefixes given via source.","s":"Image specification, single image","u":"/standards/scs-0104-v1-standard-images","h":"#image-specification-single-image","p":2973},{"i":2985,"t":"Key Type Description Example name String Name of the class of images \"ubuntu-2204-kube\" name_scheme String (regex) Regular expression for the image name \"ubuntu-2204-kube-v[0-9].[0-9]+(.[0-9]+)?\" status String optional: either mandatory or recommended \"recommended\" source String Prefix of the source URL \"https://swift.services.a.regiocloud.tech\" OR: List of strings multiple possible prefixes (see full example below) The meaning of this specification is as follows: If the status is mandatory, then at least one image MUST be present whose name matches the regular expression given via name_scheme. For any image whose name matches the regular expression given via name_scheme, its image_source property MUST start with one of the prefixes given via source.","s":"Image specification, class of images","u":"/standards/scs-0104-v1-standard-images","h":"#image-specification-class-of-images","p":2973},{"i":2987,"t":"images: - name: \"Ubuntu 22.04\" source: - https://cloud-images.ubuntu.com/releases/jammy/ - https://cloud-images.ubuntu.com/jammy/ status: mandatory - name: \"ubuntu-capi-image\" name_scheme: \"ubuntu-capi-image-v[0-9].[0-9]+(.[0-9]+)?\" source: https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-k8s-capi-images/ubuntu-2204-kube status: recommended - name: \"Ubuntu 20.04\" source: - https://cloud-images.ubuntu.com/releases/focal/ - https://cloud-images.ubuntu.com/focal/ - name: \"Debian 12\" source: - https://cloud.debian.org/images/cloud/bookworm/ - https://cdimage.debian.org/cdimage/cloud/bookworm/ - name: \"Debian 11\" source: - https://cloud.debian.org/images/cloud/bullseye/ - https://cdimage.debian.org/cdimage/cloud/bullseye/ This example provides allowable source prefixes for two Debian versions, two Ubuntu versions, and for any version of the Kubernetes cloud API provider. Only the latter is recommended, while only Ubuntu 22.04 is mandatory.","s":"Full example","u":"/standards/scs-0104-v1-standard-images","h":"#full-example","p":2973},{"i":2990,"t":"The YAML file is generally located under https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/. Any change that could render existing installations non-conformant (i.e., when new specifications are added, when the name scheme of a specification is changed so as to match more names than before, when the status of an existing specification changes to mandatory, or when some source prefix is removed) requires a new YAML file to be created. As a consequence, any currently valid certificates stay valid; the change can only take effect in a new version of the certificate in question, if so desired.","s":"YAML lifecycle","u":"/standards/scs-0104-v1-standard-images","h":"#yaml-lifecycle","p":2973},{"i":2992,"t":"It is important to note that this standard does not prohibit any images, and neither does it preclude the operator from providing any and all optional images. It is possible that a specification is mandatory in one version and non-mandatory in the next version. This standard makes no statement as to what is supposed to happen to the corresponding images in a live cloud environment. It is recommended to keep the once-mandatory images in the live environment. As for new environments, it is up to the operator whether to provide any or all of these images, as stated above.","s":"Image lifecycle","u":"/standards/scs-0104-v1-standard-images","h":"#image-lifecycle","p":2973},{"i":2994,"t":"The script images-openstack.py will read the lists of mandatory and recommended images from a yaml file provided as command-line argument, connect to an OpenStack installation, and check whether the images are present. Missing images will be reported on various logging channels: error for mandatory, info for recommended images. Additionally, images whose image_source does not conform with the specifications will be reported on the error channel. The return code will be non-zero if the test could not be performed or if any errors have been reported.","s":"Conformance Tests","u":"/standards/scs-0104-v1-standard-images","h":"#conformance-tests","p":2973},{"i":2996,"t":"The openstack-image-manager is able to create all standard, mandatory SCS images for you given image definitions from a YAML file.","s":"Operational tooling","u":"/standards/scs-0104-v1-standard-images","h":"#operational-tooling","p":2973},{"i":2999,"t":"SONiC support in SCS was considered within the context of VP04 Networking, sub-lot 1 SDN scalability. Different challenges and approaches to SDN scalability have been explored and more specifically those who require support in the underlay network. Using SONiC in the underlay can have benefits for SCS users by using a standardized OS for network devices and also having a clear path for network scalability when using SONiC. For this to work, we have to define how SONiC is used and supported architecturally in SCS. This document outlines the architectural decisions in regards to SONiC support and integration in SCS.","s":"Introduction","u":"/standards/scs-0112-v1-sonic","h":"#introduction","p":2997},{"i":3001,"t":"In respect to SDN scalability improvements in Openstack and SCS, there are several ways SONiC can be leveraged.","s":"Motivation","u":"/standards/scs-0112-v1-sonic","h":"#motivation","p":2997},{"i":3003,"t":"In many network designs for Openstack, configuration of the actual network hardware by Openstack Neutron service is required. The following network designs apply: VLANs. Uisng VLANs to segment tenant networks requires the network switch to be configured. This can be manual or dynamic configuration via the ML2 Neutron driver. EVPN/VXLAN on the switch. In this use case, SONiC runs on leaf switches. Leafs terminate VXLAN endpoints and run BGP/EVPN for the control plane. Again, the ML2 Neutron driver is used to dynamically configure the network switch. The link between the switch and the service is regular VLAN. VXLAN on servers and switches. This is a hybrid use case, where most of the SDN is pushed to the server, but the network is still involved where support for bare metal hosts is needed.","s":"SONiC as a network OS where dynamic network configuration in Openstack is required","u":"/standards/scs-0112-v1-sonic","h":"#sonic-as-a-network-os-where-dynamic-network-configuration-in-openstack-is-required","p":2997},{"i":3005,"t":"There is no tooling in SCS or Openstack communities to facilitate the rollout and configuration of enterprise scale SONiC deployments. Netbox and OSISM can be integrated, so that Netbox becomes the source of truth for network configuration and OSISM supports the initial rollout and configuration for the switches.","s":"Automation and tooling for SONiC","u":"/standards/scs-0112-v1-sonic","h":"#automation-and-tooling-for-sonic","p":2997},{"i":3007,"t":"OVN and OVS are extensively leveraged in Neutron to SDN. In large scale deployments, OVN can become a bottleneck by exhausting resources on network nodes. SONiC can host the OVN control plane as a module (container) and spare the resources in network nodes. There is however a potential other bottleneck on SONiC hardware, as OVN control plane can be resource intensive. This is a potential area for further investigation.","s":"OVN for SONiC","u":"/standards/scs-0112-v1-sonic","h":"#ovn-for-sonic","p":2997},{"i":3009,"t":"There are different ways SONiC support can be implemented in SCS, very similar to existing approaches with Linux.","s":"Design Considerations","u":"/standards/scs-0112-v1-sonic","h":"#design-considerations","p":2997},{"i":3011,"t":"Option 1: SCS distribution of SONiC​ With this approach, SCS will create it's own distribution of SONiC, similar to what Debian or Arch are for Linux. This distribution will be based on the SONiC community distribution, but will have SCS specific modules, which will be developed and maintained by SCS. SCS will contribute its code to dedicated SCS repositories and build its own SONiC images. The code can eventually be pushed upstream, but not as top priority. This approach will allow SCS to have a clear path for SONiC support and integration in SCS, but will also require SCS to maintain a distribution of SONiC, which is a significant effort. Upstream/downstream changes will have to be managed and maintained. However the advantage is that SCS will have full control over the distribution and can make changes as needed. Users will have to use the SCS distribution of SONiC, which will be based on the community distribution. If users already deploy community or enterprise SONiC, a migration path to SCS SONiC will be needed. Option 2: SCS will support SONiC but will not change it​ SCS supports enterprise ans community versions of SONiC but will not develop its own code for it. This will significantly limit the ability to develop new features for SDN, because all changes will be done in the tooling around SONiC and not in the OS itself. The advantages are that SCS will still improve SONiC support and will have minimal effort for this. The downside is that some features like OVN control plane for SONiC will not be possible. Option 3: SCS develops SCS-specific modules as add-on for any SONiC (Community or Enterprise)​ In option 3, SCS will change SONiC by releasing its own modules for it. Those module can be provided as add-ons and installed on top of any version, community or enterprise. While compatability between the modules the SONiC releases will need to be maintained, there will be much broader support for SONiC and users will be able to pick and chose distributions based on their existing relationships and experience and use SCS independent of this. In cases where SCS provides contributions to core SONiC, those can be made in upstream Community repositories, so that the whole community including the propriatory vendors can adopt them eventually. Option 4: SCS does not adopt SONiC at all​ This option entails no dedicated effort on SCS's part in supporting SONiC network equipement for it's users and software stack. Users can still use SONiC from what is available by other projects or if they invest the effort themselves. This has several disadvantages: SCS is not contributing to the SONiC community the value for SCS by users who already use or plan to invest in SONiC is diminished users have less incentive to use community SONiC and switch to Enterprise SONiC SCS will not be able to leverage SONiC for SDN scalability improvements","s":"Options considered","u":"/standards/scs-0112-v1-sonic","h":"#options-considered","p":2997},{"i":3014,"t":"community version: mature or not? Commits: between 40-52 per month. Contributors to master: 10-20. Mailing list: 6 lists, about 10-30 messages/month for list. Community version supports 25 hardware vendors. Requires significant time and resource investment and \"Explorer's mindset\". enterprise version: mature or not? Multiple vendor distributions. Expensive in general release schedule - how often are features and bugfixes released? New tags appears on different periods, once 2 times per month, other 3 months between releases. adoption penetration - how many vendors use it? What type of venders (big, medium and large)? Good initial adoption: Microsoft, Target. Adoption requires time and money Is SONiC being overtaken by alternatives: SmartNICs and DPUs? How relevant is it still and will be in the coming years? Actually not, because of different use cases. Sustainability of community SONIC for 2025+ The SONiC community is healthy and growing, however progress is slower due to factors like investment of resources. The barrier of entry is much higher than other similar OSS projects.","s":"State of SONiC community?","u":"/standards/scs-0112-v1-sonic","h":"#state-of-sonic-community","p":2997},{"i":3016,"t":"IaaS team recommends to use Option 3: SCS develops SCS-specific modules as add-on for any SONiC (Community or Enterprise). It has the best tradeoff between time and resource investment and benefits for the community. Adopting this strategy would allow SCS to be agile and quickly adopt SONiC, by providing users with clear path while allowing the freedom to chose different hardware and software vendors. SCS code can be packaged independently of each SONiC distribution and installed as add-on. Also SCS contributions to core SONiC will be done directly upstream, so that the whole community can benefit from them. Work on hardware support in SONiC should be raised in upstream and SCS shouldn't make significant investments in this area.","s":"Decision","u":"/standards/scs-0112-v1-sonic","h":"#decision","p":2997},{"i":3018,"t":"Research SDN scalability Results SONIC Usage in SCS SONiC Community research","s":"Related Documents","u":"/standards/scs-0112-v1-sonic","h":"#related-documents","p":2997},{"i":3021,"t":"A volume is a virtual drive that is to be used by an instance (i. e., a virtual machine). With OpenStack, each volume is created per a type that determines basic features of the volume as provided by the backend, such as encryption, replication, or quality of service. As of the writing of this document, presence or absence of these features can not be discovered with full certainty by non-privileged users via the OpenStack API.","s":"Introduction","u":"/standards/scs-0114-v1-volume-type-standard","h":"#introduction","p":3019},{"i":3023,"t":"The following special terms are used throughout this standard document: Term Meaning volume OpenStack resource, virtual drive which usually resides in a network storage backend volume feature A certain feature a volume can possess aspect Part of a volume type that will activate a corresponding feature in a created volume AZ Availability Zone Volume QoS Quality of Service object for Volumes","s":"Glossary","u":"/standards/scs-0114-v1-volume-type-standard","h":"#glossary","p":3019},{"i":3025,"t":"As an SCS user, I want to be able to create volumes with certain common features, such as encryption or replication, and to do so in a standardized manner as well as programmatically. This standard outlines a way of formally advertising these common aspects for a volume type to non-privileged users, so that the most suitable volume type can be discovered and selected easily — both by the human user and by a program.","s":"Motivation","u":"/standards/scs-0114-v1-volume-type-standard","h":"#motivation","p":3019},{"i":3027,"t":"All considerations can be looked up in detail in the Decision Record for the Volume Type Standard.","s":"Design Considerations","u":"/standards/scs-0114-v1-volume-type-standard","h":"#design-considerations","p":3019},{"i":3029,"t":"To test whether a deployment has volume types with certain aspects, the discoverability of the parameters in the volume type has to be given. As for the time this standard is created, there is no way for users to discover all aspects through OpenStack commands. Therefore the aspects, that are fulfilled within a volume type, should be stated in the beginning of the description of a volume type in the following manner: [scs:aspect1, aspect2, ..., aspectN]... The mentioned aspects MUST be sorted alphebetically and every aspect should only be mentioned to the maximal amount of one.","s":"Systematic Description of Volume Types","u":"/standards/scs-0114-v1-volume-type-standard","h":"#systematic-description-of-volume-types","p":3019},{"i":3031,"t":"The following table shows which aspects are considered in this standard. The third column shows how the description of the volume type has to be adjusted, if the aspect is fulfilled: Aspect Requirement standardized description comment Encryption Recommended \"[scs:encrypted]\" volume is encrypted Replication Recommended \"[scs:replicated]\" volume is replicated to avoid data loss in a case of hardware failure It is possible to use multiple of those aspects within one volume type. There don't have to be different volume types for each aspect. For instance, one volume type that uses LUKS-encryption with a ceph storage with inherent replication would fulfill all recommendations of this standard.","s":"Standardized Aspects","u":"/standards/scs-0114-v1-volume-type-standard","h":"#standardized-aspects","p":3019},{"i":3033,"t":"There is always a default volume type defined in an OpenStack deployment. This volume type is created in the setup of cinder and will always be present in any OpenStack deployments under the name __default__. This standard does not have any requirements about this volume type at this moment, instead deployers are free to choose what fits best in their environment. Conversely, a cloud user can not expect any specific behavior or properties from volume types named __default__.","s":"DEFAULT volume type","u":"/standards/scs-0114-v1-volume-type-standard","h":"#default-volume-type","p":3019},{"i":3035,"t":"Currently, this standard will not require volume types with certain specification.","s":"REQUIRED volume types","u":"/standards/scs-0114-v1-volume-type-standard","h":"#required-volume-types","p":3019},{"i":3037,"t":"This standard recommends to have one or more volume types, that feature encryption and replication.","s":"RECOMMENDED volume types","u":"/standards/scs-0114-v1-volume-type-standard","h":"#recommended-volume-types","p":3019},{"i":3039,"t":"Any other aspects of volume types, that can be found in the decision record are OPTIONAL. They SHOULD NOT be referenced in the way this standard describes. Some of them already are natively discoverable by users, while others could be described in the name or description of a volume type. Users should look into the provided volume types of the Cloud Service Providers, if they want to use some of these other aspects.","s":"OPTIONAL volume types","u":"/standards/scs-0114-v1-volume-type-standard","h":"#optional-volume-types","p":3019},{"i":3042,"t":"Encryption for volumes is an option which has to be configured within the volume type. As an admin it is possible to set encryption-provider, key size, cipher and control location. Additionally to be discoverable by users, the description should start with an aspect list such as [scs:encrypted] (potentially with additional aspects). It should look like this example: openstack volume type show LUKS +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Field | Value | +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ | access_project_ids | None | | description | [scs:encrypted] This volume uses LUKS-encryption | | id | d63307fb-167a-4aa0-9066-66595ea9fb21 | | is_public | True | | name | LUKS | | qos_specs_id | None | +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+","s":"Encryption","u":"/standards/scs-0114-v1-volume-type-standard","h":"#encryption","p":3019},{"i":3044,"t":"Replication states whether or not there are multiple replicas of a volume. Thus, it answers the question whether the data could survive a node outage. Unfortunately there are two ways replication can be achieved: In the configuration of a volume type. It then is visible as extra_spec in the properties of a volume type. Via the used backend. Ceph for example provides automatic replication, that does not need to be specified in the volume type. This is currently not visible for users. To fulfill this recommendation, the description should start with an aspect list such as [scs:replicated] (potentially with additional aspects).","s":"Replication","u":"/standards/scs-0114-v1-volume-type-standard","h":"#replication","p":3019},{"i":3046,"t":"One volume type that is configured as an encrypted volume type in a ceph backend, with automated replication would fit both recommendations and will be enough to comply to this part of the volume type standard. It should look like the following part: +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Field | Value | +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ | access_project_ids | None | | description | [scs:encrypted, replicated] Content will be replicated three times to ensure consistency and availability for your data. LUKS encryption is used. | | id | d63307fb-167a-4aa0-9066-66595ea9fb21 | | is_public | True | | name | hdd-three-replicas-LUKS | | properties | | | qos_specs_id | None | +--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+","s":"Example","u":"/standards/scs-0114-v1-volume-type-standard","h":"#example","p":3019},{"i":3048,"t":"corresponding decision record document","s":"Related Documents","u":"/standards/scs-0114-v1-volume-type-standard","h":"#related-documents","p":3019},{"i":3050,"t":"The script /Tests/iaas/volume-types/volume-types-check.py connects to an OpenStack environment and tests the following: for each volume type: if its description starts with [scs:....], then this prefix is a feature list (sorted, each entry at most once), and each entry is one of the possible features described here, the recommended volume types are present (otherwise, a WARNING is produced). The return code is zero precisely when the test could be performed and the conditions are satisfied. Otherwise, detailed errors and warnings are output to stderr.","s":"Conformance Tests","u":"/standards/scs-0114-v1-volume-type-standard","h":"#conformance-tests","p":3019},{"i":3053,"t":"With the k8s-cluster-api-provider, the SCS provides a tool to generate and manage k8s clusters on top of its IaaS infrastructure. As part of the application, Sonobuoy is used as a test suite to execute the official Kubernetes e2e tests. We expect that current and future tests derived from SCS standards will benefit from (or even require) the testing mechanisms that Sonobuoy provides. Apart from running the Kubernetes e2e tests, Sonobuoy also allows users to write their own tests and apply them as a self-managed plugin. All tests not provided by the e2e test plugin could therefore be written by the respective SCS teams responsible for the standards or tests and then be made executable with Sonobuoy. Hence, Sonobuoy could provide both a pre-done test suite and a framework to write additional conformance tests required for SCS.","s":"Motivation","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#motivation","p":3051},{"i":3055,"t":"The main objective of Sonobuoy plugins is to present test results in a consolidated way. To do this, Sonobuoy integrates the test into a pod, which is then applied to the K8s cluster under test. A Sonobuoy worker supervises this pod and forwards all test results to the aggregator module. It does this by waiting for a specific \"Done\" file to be created. Once this file is recognized, the worker forwards the results to the aggregator, using a predefined location for the results file within a folder, as seen in following image: In order to use the existing conformance tests as a Sonobuoy plugin, a wrapper around the individual test scripts would be required. This wrapper would need to have the following effects: gathers all test results and provides them in the results file run tests in sequence and signal the worker when it's finished by generating a \"Done\" file Apart from providing the test results, a plugin container must also forward the status of each test by setting a status flag in the results file. Additionally, the tests would need to be able to run inside a pod in the K8s cluster under test.","s":"Short Sonobuoy Introduction","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#short-sonobuoy-introduction","p":3051},{"i":3057,"t":"There are different approaches to create a Sonobuoy plugin, which are discussed below in order to find a best practice for the SCS project. The documented approaches show one example each in order to give a better representation to the reader. Sonobuoy provides plugin examples in the plugins repository, which are referenced throughout this section.","s":"Design Considerations","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#design-considerations","p":3051},{"i":3059,"t":"The seemingly most interesting plugin is the e2e-skeleton, which uses the kubernetes-sigs/e2e-framework. The kubernetes-sigs/e2e-framework is a stand-alone project that is separate from the official Kubernetes e2e tests. The framework provides proper documentation as well as helper functions that abstract client functionalities, similar to those found in \"kubernetes/kubernetes/test/e2e/framework\" repository. As mentioned in the motivation of the e2e-framework, the project was created to circumvent the disadvantages of Kubernetes' own e2e-tests, which are described in more detail in the goals. PROS: arguments in favor of this framework can also be found under the goals description of the documentation e2e-framework is a well-defined framework, that allows the handling of resource creation and deletion official framework provided by \"Kubernetes-sigs\" CONS: arguments not in favor of this framework can be derived from the Non-Goals description of the documentation: \"no responsibility for bootstrapping or the execution of the tests themselves\" can be ignored, as this is partly taken over by Sonobuoy \"no mock or fake cluster components\" can be ignored, since the e2e tests of SCS should be used to test real clusters and their functionality for this test procedure, the Sonobuoy e2e plugin should be run in addition to the SCS KaaS conformance tests proof of concept: ../Tests/kaas/kaas-sonobuoy-go-example-e2e-framework/","s":"Option 1 Golang based approach 1: Pick a framework from the Sonobuoy plugin examples","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-1-golang-based-approach-1-pick-a-framework-from-the-sonobuoy-plugin-examples","p":3051},{"i":3061,"t":"The existing Sonobuoy e2e plugin already provides a vast number of tests that could be adapted or reused for the SCS project. If these e2e tests are to be reused in a customized structure, a framework like ginkgo must be used as it is used by the Kubernetes e2e test infrastructure. This could use the implementation of the build process responsible for the Docker image containing the e2e tests. The setup could be copied from kubernetes/test/conformance/image and adapted to the projects requirements. The mentioned build process must use the files of the following directories from the Kubernetes repository: kubernetes/cluster kubernetes/test/e2e/framework kubernetes/test/conformance/image/go-runner kubernetes/hack/conformance kubernetes/hack/make-rules PROS: Kubernetes' own e2e tests already provide a vast amount of examples, which could be reused to develop specific SCS tests compared to option 1, the non-goals of the e2e-framework can be seen as the advantages of using Kubernetes' own e2e-tests. CONS: not easy to implement, as we would have to copy part of the Kubernetes repository and track the changes from the upstream according to README.md, part of it seems to be outdated and might change with a future version compared to option 1, the goals of the e2e-framework can be seen as the disadvantages of using Kubernetes' own e2e-tests. TODO: provide proof of concept: kaas-sonobuoy-go-example-k8s-e2e","s":"Option 2 Golang based approach 2: Reuse the Kubernetes own e2e test infrastructure and framework","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-2-golang-based-approach-2-reuse-the-kubernetes-own-e2e-test-infrastructure-and-framework","p":3051},{"i":3063,"t":"Sonobuoy makes it possible to write tests in Python and execute them like other tests in a pod on the K8s cluster. It would therefore be possible to keep on writing conformance tests in Python. This option would require a wrapper in order to make the tests scripts executable as Sonobuoy plugins. This wrapper, as mentioned earlier, would need to capture the collection of test results as well as the generation of the \"Done\" file after the test execution is finished. This could be managed by executing each test script in a sequential order. The wrapper as well as the python tests and test framework could then be stored in a container image and uploaded to a registry in order to be usable by Sonobuoy within the k8s-cluster-api-provider. This approach also leaves the decision open as to which test framework should be used for Python, which should be decided in a secondary Decision Record. proof of work: ../Tests/kaas/k8s-default-storage-class PROS: continue using the already available Python tests only a small number of tests is implemented thus far CONS: no \"native\" support in Sonobuoy, a wrapper is needed decision for a framework is still not done","s":"Option 3 Write Python scripts for tests","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-3-write-python-scripts-for-tests","p":3051},{"i":3065,"t":"The following section showcases both ways to provide a Sonobuoy plugin image. Option 1 would most likely be used, if an image is published to be used by an end user. Option 2 is the expected way for local development and testing.","s":"Approaches to providing a Sonobuoy plugin image","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#approaches-to-providing-a-sonobuoy-plugin-image","p":3051},{"i":3067,"t":"The image can be made available via a public container registry, which would require a regular job (e.g. CI/CD) to build and publish the image.","s":"Option 1 Public container registry","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-1-public-container-registry","p":3051},{"i":3069,"t":"Create the image locally on the \"clusterctl admin control node\" and then upload it manually to the Kubernetes cluster under test. Both approaches are useful in different ways. While the usage of a container registry allows easy distribution of tests and guarantees new images through the usage of a CI/CD job, it also makes it harder to test changes quickly, since a wait time could be necessary to let the CI/CD job run through and access the image. This can be solved by using the \"Local image upload\" or a combination of both approaches.","s":"Option 2 Local image upload","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#option-2-local-image-upload","p":3051},{"i":3071,"t":"The KaaS conformance test MUST be provided as a test suite holding the test cases for the Kubernetes clusters to be checked. Furthermore, the test cases themselves MUST be wrapped by a test framework to: handle the creation and deletion of resources collect and present results consolidate redundant code across test cases support the creation of test cases through predefined structures As with the k8s-cluster-api-provider the SCS provides a tooling to generate its KaaS infrastructure. Part of the k8s-cluster-api-provider is the usage of Sonobuoy as a test suite to execute the Kubernetes own e2e tests. Investigating those e2e test lead to the conclusion that they are not always reusable. The main purpose of Kubernetes own e2e tests is to test the functionality of the Kubernetes code itself and not the resources and setup of a specific KaaS infrastructure as it is the aim of the SCS KaaS conformance test. However, considering that the SCS has an ongoing process of defining standards and implementing test cases to check their compliance, that means in some cases future standards might already be covered by the e2e test inside the Kubernetes repository. Hence, before writing tests, a developer SHOULD check the Kubernetes e2e tests for existing test cases that might cover conformance of a standard currently being worked on. As described above, Sonobuoy offers the possibility to generate custom plugins that provide self-created test cases. Therefore, future conformance tests MUST be executable by Sonobuoy by wrapping them in a Sonobuoy plugin. Moreover, three options for the implementation of the SCS KaaS compliance test cases are described above so that it can be decided within this decision record which options should be used. As a first decision, \"Option 2 Go Approach 2: Reuse Kubernetes' own e2e test infrastructure and framework\" is the least viable, as it would mean copying almost all the files used from the Kubernetes e2e tests. This framework is closely linked to the development of the Kubernetes code. Therefore, changes to its structure mainly are in line with its usage in the Kubernetes repository itself and is most likely not relevant for other parties. Changes in the framework cloud have a greater impact on our side as they are predictable. The development effort gained by reusing these examples could be outweighed by the investment necessary to adapt tests to the corresponding framework changes. This leaves \"Option 1 Go approach 1: Pick framework from the Sonobuoy plugin examples\" and \"Option 3 Write Python scripts for tests\" as methods for implementing test cases. It is possible to use both approaches in parallel, which would enable usage of both Python and Go code. This could possibly generate two Sonobuoy plugins, but this isn't a necessity.","s":"Decision","u":"/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests","h":"#decision","p":3051},{"i":3074,"t":"Security Groups in IaaS (OpenStack) are part of the network security mechanisms provided for the users. They resemble sets of virtual firewall rules allowing specific network traffic at a port of a VM that connects it to a network. They are project-bound, which means that all Security Groups that are newly created are only available to the project in which they were created. This is also the case for the default Security Group that is created for each project as soon as the project itself is created.","s":"Introduction","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#introduction","p":3072},{"i":3076,"t":"Security Group (abbr. SG) Set of ip table rules, used for tenant network security. Security Group Rule (abbr. SG Rule) A single ip table rule, that is part of a SG. Administrator (abbr. Admin) Operator = User of an OpenStack cloud with the admin role.","s":"Terminology","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#terminology","p":3072},{"i":3078,"t":"To properly understand the concepts in this standard and avoid ambiguity, is very important to distinguish between the following similar-sounding but different resources in the OpenStack Networking API: default Security Group custom Security Group default Security Group Rules A default Security Group is a predefined Security Group which is automatically created once a project is created and is specific to that project. This Security Group is called \"default\" and there exists only one per project. It will automatically be assigned to VMs that have no other Security Group explicitly assigned to it, when a VM is created. A custom Security Group is any additional Security Group created within a project separate from the default Security Group of the project. The default Security Group Rules may target the default Security Groups or the custom Security Groups or both. They resemble a rule template and each Security Group will be initially created with rules according to this template. Although the rules of a Security Group may be adjusted freely after its creation, these default rule presets applied on initialization are predefined. In recent OpenStack releases, both presets can be adjusted independently by administrators of the infrastructure.","s":"Default Security Groups, Custom Security Groups and default Security Group Rules","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#default-security-groups-custom-security-groups-and-default-security-group-rules","p":3072},{"i":3080,"t":"The rules of a Security Group can be edited by default by any user with the member role within a project. But when a Security Group is created it automatically incorporates a few SG rules that are configured as default rules. Since the 2023.2 release, the default set of Security Group rules can be adjusted. This functionality is only available to administrators12. In combination with the OpenStack behavior that when a VM is created with no Security Group specified, the default SG of the project is automatically applied to the ports of the VM, a user cannot be sure which firewall rules are applied to such a VM. Therefore this standard proposes default Security Group rules that MUST be set by administrators to avoid divergence in default network security between different IaaS environments.","s":"Motivation","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#motivation","p":3072},{"i":3082,"t":"Up to the 2023.1 release (antelope) the default Security Group rules are hardcoded in the OpenStack code. We should not require to change this behavior through code changes in deployments. Beginning with the 2023.2 release (bobcat) the default Security Group rules can now be edited by administrators through an API. All rules that should be present as default in Security Groups have to be configured by admins through this API. There are two ways to approach a standard for the default rules of Security Groups. There could be a set of rules standardized that has to be configured by admins. OpenStack's default rules for Security Groups already provide a good baseline for port security, because they allow all egress traffic and for the default Security Group only ingress traffic from the same group. Allowing more rules would not benefit the security level, while reducing or limiting the existing rules would barely improve it. Nevertheless a standard could hold up the current security level against possible future release with more open default rules. Changing the default rules will not change the rules of any existing Security Groups. With the already strict OpenStack default rules users are required in most use cases to create and manage their own Security Groups. This has the benefit that users need to explicitly think about the port security of their VMs and may be less likely to apply Security Groups which rules open up more ports than needed. There is also a guide from the SCS project on how to set up a Security Group that also focuses on having a good port security3. With the default OpenStack behavior of having already strict rules, which in most cases require users to manage their own Security Groups, this standard should mandate a middle way: It should allow adjusting the default rules, but only to a stricter version. Allowing all outgoing traffic in the default rules in combination with blocking all incoming traffic would be strict enough from a security point of view. And it would make it necessary for users to check and change the rules of their Security Group to a meaningful set.","s":"Design Considerations","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#design-considerations","p":3072},{"i":3084,"t":"This standard should only be applied onto versions of OpenStack that implement the new endpoint for the default Security Group rules, which would only include 2023.2 or higher releases. It is possible to have different default Security Group rules for the default SG and custom SGs. And it is arguable to have a more strict standard for default rules for the default Security Group than for the custom Security Groups. Because the latter ones are not automatically applied to a VM but are always edited by the users to apply to their requirements. The allowlisting concept of Security Group rules makes it hard to allow traffic with an exception of certain ports. It would be possible to just define many rules to achieve what a blocklist would achieve. But having many rules may confuse users and they may not disable unnecessary default rules in their SGs.","s":"Further Annotations","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#further-annotations","p":3072},{"i":3086,"t":"The default Security Group rules for the default Security Groups SHOULD allow incoming traffic from the same Security Group. The default Security Group rules for ALL Security Groups MUST NOT allow any other incoming traffic. Neither IPv4 nor IPv6. This can be achieved through having ingress rules in the default Security Group rules that allow ingress traffic from the Remote Security Group \"PARENT\" but are only used in the default Security Group. The default Security Group rules for ALL Security Groups SHOULD allow egress Traffic for both IPv4 and IPv6.","s":"Standard","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#standard","p":3072},{"i":3088,"t":"In the following table, there is only ingress traffic between the same default Security Groups allowed plus all egress traffic: $ openstack default security group rule list +--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+ | ID | IP Protocol | Ethertype | IP Range | Port Range | Direction | Remote Security Group | Remote Address Group | Used in default Security Group | Used in custom Security Group | +--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+ | 47b929fd-9b39-4f22-abc5- | None | IPv6 | ::/0 | | egress | None | None | True | True | | 7d4f64d10909 | | | | | | | | | | | 92a79600-5358-4fef-a390- | None | IPv4 | 0.0.0.0/0 | | egress | None | None | True | True | | 822665f46070 | | | | | | | | | | | 93e35d0c-2482-4ec1-9fbd- | None | IPv4 | 0.0.0.0/0 | | ingress | PARENT | None | True | False | | fd8c9a21a04e | | | | | | | | | | | ed5cd662-add2-4e42-b0a7- | None | IPv6 | ::/0 | | ingress | PARENT | None | True | False | | 3b585d348820 | | | | | | | | | | +--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+","s":"Example","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#example","p":3072},{"i":3090,"t":"The spec for introducing configurability for the default Security Groups Rules can be found here. More about Security Groups as a resource in OpenStack can be found here.","s":"Related Documents","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#related-documents","p":3072},{"i":3092,"t":"The conformance tests should check for the absence of any ingress traffic rules except traffic from the same Security Group in the openstack default security group rule list. As having egress rules is allowed by this standard, but not forced and can be set in various ways, the tests should check for presence of any egress rules. Footnotes​ Tracking of development for editable default SG rules ↩ Release Notes of Neutron 2023.2 ↩ Guide for Security Groups ↩","s":"Conformance Tests","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#conformance-tests","p":3072},{"i":3094,"t":"Tracking of development for editable default SG rules ↩ Release Notes of Neutron 2023.2 ↩ Guide for Security Groups ↩","s":"Footnotes","u":"/standards/scs-0115-v1-default-rules-for-security-groups","h":"#footnote-label","p":3072},{"i":3097,"t":"Security Groups in IaaS (OpenStack) are sets of ip table rules, that are applied to ports which connect a virtual machine to a network. In contrast to other resources like flavors or volume types that are always publicly accessible, or images that can be both public and private, security groups are always bound to the project level. That creates some difficulties for a possible standard of Security Groups, which are discussed in this document.","s":"Introduction","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#introduction","p":3095},{"i":3099,"t":"Security Group A set of iptables rules that is applied to ports connecting a virtual machine and a network. Security Group Rule (abbr. Rule) This references a single rule within a security group. RBAC Role Based Access Control used for policies and alike. network rbac / neutron rbac These access controls will let administrators and users share neutron related resources with other projects. admin The most powerful role in OpenStack. Only given to some Operators of the Cloud Infrastructure.","s":"Terminology","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#terminology","p":3095},{"i":3101,"t":"While creating a virtual machine and also later on, one or more security groups can be added to it. When there is no security group specified the default security group will always be added. Like every other security group, the default group is also project bound. That means, it can be edited as required by project members. By design of OpenStack and when not changed, default rules in the default security group block all incoming traffic except from the same Security Group and only allow outgoing traffic1.","s":"Context","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#context","p":3095},{"i":3103,"t":"Considering having most likely similiar security groups within different projects, it might make sense to standardize a few security groups for often used cases like ssh, http, https and maybe icmp. What speaks for standardizing a certain set of security groups: Having a set of correctly configured security groups could reduce misconfiguration from users Re-using correctly configured security groups saves time for users Auditing security groups would be way easier for operators when helping customers The configuration for the Security Groups can be done by networking experts, which may result in a higher security level as when users without expertise configure them What are the downsides of having a set of standardized security groups: A bug or misconfiguration is a single point of failure for ALL customers Users might apply the wrong security group to their port or VM because they lack the domain knowledge, unknowingly opening themselves to attacks Users will not inspect such default security groups: this may result in applying a wrong group and opening traffic too much the central authority managing the groups does not necessarily know the usecase of the user, the user/operator must know best what kind of security their workload needs. What is a necessary port for 99% of deployments might be a security disaster for my deployment Providing default groups could have the effect of stopping customers to think about their specific security needs and instead just copying default groups and or rules This leads to a conclusion, that a set of default security groups is only more valuable than harmful for users: when the rules in those groups are configured correctly and when the users still have to think about their network security on their own for each VM they start","s":"Reasons for and against a standard for security groups","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#reasons-for-and-against-a-standard-for-security-groups","p":3095},{"i":3105,"t":"As security groups are project bound and there is no native way to them to be shared, we are left with three options: To use another endpoint network rbac to share security groups among different projects. To adhere to the project scope of security groups and only give documentation about recommended security groups to users. To only add a tutorial on how to create your own security group in general, how to detect what kind of network permissions your project needs for most frequent (linux) workloads and how to craft your own security groups in a secure way.","s":"Technical limitations","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#technical-limitations","p":3095},{"i":3107,"t":"For every project that is created there will also be a project-specific default security group created. The default rules for the default groups and all other newly created groups can be looked up like this: stack@devstack:~/devstack$ openstack default security group rule list +------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+ | ID | IP Protocol | Ethertype | IP Range | Port Range | Direction | Remote Security Group | Remote Address Group | Used in default Security Group | Used in custom Security Group | +------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+ | 47b929fd-9b39-4f22- | None | IPv6 | ::/0 | | egress | None | None | True | True | | abc5-7d4f64d10909 | | | | | | | | | | | 6ace51bb-5258-45ab- | None | IPv6 | ::/0 | | ingress | PARENT | None | True | False | | 9ba9-1efbebfb086b | | | | | | | | | | | 92a79600-5358-4fef- | None | IPv4 | 0.0.0.0/0 | | egress | None | None | True | True | | a390-822665f46070 | | | | | | | | | | | 997bb0c2-652e-4d1f- | None | IPv4 | 0.0.0.0/0 | | ingress | PARENT | None | True | False | | b910-e12c89f88b44 | | | | | | | | | | +------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+ Those rules can be edited, which may pose a security risk for customers consuming the default security group. This should be adressed as a pre-requirement here.","s":"Option 0: Pre-Requirement: default rules for the (default) security group","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#option-0-pre-requirement-default-rules-for-the-default-security-group","p":3095},{"i":3109,"t":"The network rbac endpoint2 manages the possibitity to share and access certain network-specific resources such as security groups. For admins it is possible to use this endpoint to share a security group with ALL projects within the the cloud including ALL projects of ALL domains: stack@devstack:~/devstack$ openstack network rbac create --target-all-projects --action access_as_shared --type security_group group-for-everyone +-------------------+--------------------------------------+ | Field | Value | +-------------------+--------------------------------------+ | action | access_as_shared | | id | 394d8e71-143f-4c5b-a72f-cd10af3222df | | object_id | b6a3834a-f89c-47a9-9ed6-ca89e93701c4 | | object_type | security_group | | project_id | 15f2ab0eaa5b4372b759bde609e86224 | | target_project_id | * | +-------------------+--------------------------------------+ This would fulfill our goal to grant access to predefined security groups for all projects and all groups recieved as shared do not count into the projects quota for security groups. But there are a few downsides to this: This should be strictly bound to the admin: no other user should be able to share security groups so to not confuse user. The managing of those network rbac objects can get out of hand pretty quickly, because there neither is an explicit name for such an object nor do the names of the shared objects appear: stack@devstack:~/devstack$ openstack network rbac list --long +-----------------------------+----------------+-----------------------------+--------------------+ | ID | Object Type | Object ID | Action | +-----------------------------+----------------+-----------------------------+--------------------+ | 97507e4c-7413-4d61-ab21- | security_group | 110b1bea-f0e0-4fb7-9fc7- | access_as_shared | | 047fc23516dd | | cda1b6f927b0 | | | bc22a865-46f9-4cd2-80af- | security_group | 5f22e42e-95dc-4c0a-8651- | access_as_shared | | 3c249ba0e010 | | 57b1dfc8639f | | | 2467806f-5428-4506-8e23- | network | 02ef8579-9917-4a01-893d- | access_as_shared | | f4690db04e01 | | cb2f9f3d5f98 | | | ed40996e-218d-4daa-b222- | network | 73edb86b-d7ab-4db3-82b7- | access_as_external | | f3c603a5b8a6 | | 25fa8b012e40 | | | 45e0a707-af82-42a6-b93f- | subnetpool | cd7addd1-05d9-48a8-bc38- | access_as_shared | | efde18216f13 | | 4a581354983f | | | e514c2c8-65ac-4062-8b03- | subnetpool | ad1cc1ed-3261-4df2-8c73- | access_as_shared | | fe24f6fc4656 | | c3dd72d59061 | | +-----------------------------+----------------+-----------------------------+--------------------+ stack@devstack:~/devstack$ openstack network rbac show bc22a865-46f9-4cd2-80af-3c249ba0e010 +-------------------+--------------------------------------+ | Field | Value | +-------------------+--------------------------------------+ | action | access_as_shared | | id | bc22a865-46f9-4cd2-80af-3c249ba0e010 | | object_id | 5f22e42e-95dc-4c0a-8651-57b1dfc8639f | | object_type | security_group | | project_id | 15f2ab0eaa5b4372b759bde609e86224 | | target_project_id | * | +-------------------+--------------------------------------+ The biggest downside: As soon as a security group is shared, everyone from every project, can edit the rules of this group.","s":"Option 1: operator usage of network rbac","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#option-1-operator-usage-of-network-rbac","p":3095},{"i":3111,"t":"Using and adhering the project scope of the security groups has the consequence, that: either an admin has to set up security groups for each project or the SCS project only provides a guide on how to setup and use some recommended security groups. As users are allowed to, will and should edit their security groups, there is no way to ensure, that a certain set of security groups with certain rules is always present in a project. So packing an extra burden on admins is unreasonable. The option to give a guide and recommend a few security groups however is a quite good option.","s":"Option 2: stay project-scoped","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#option-2-stay-project-scoped","p":3095},{"i":3113,"t":"Instead of providing users with a set of default groups or the knowledge about how to create default groups, there could be a guide created that focuses on the crafting of a security group in a secure way. That would include identifying what kind of network permission a single VM needs and how to proceed after gathering all requirements of the customers workload.","s":"Option 3: security-focused guide","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#option-3-security-focused-guide","p":3095},{"i":3115,"t":"The default Security Group Rules should be standardized as a pre-requirement (Option 0). Using the network rbac endpoint (Option 1) would not solve the idea of having pre-defined and administrator audited Security Groups, because it is possible for any user to edit the rules of shared Security Groups. Instead the project-scope of the Security Groups should by focused and a guide prepared, that gives insight about creating and using Security Groups with a few examples but with a clear security focus (Mix of Option 2 and 3).","s":"Decisions","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#decisions","p":3095},{"i":3117,"t":"Any CSP will have to follow the standard for the default Security Group Rules. There are no consequences regarding Security Groups as it and users stay in full control and responsible for their own Security Groups","s":"Consequences","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#consequences","p":3095},{"i":3119,"t":"A PR to standardize default Security Group Rules A PR to a first draft for a guide for security groups Footnotes​ Default Security Group Rules ↩ Neutron RBAC ↩","s":"Related Documents","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#related-documents","p":3095},{"i":3121,"t":"Default Security Group Rules ↩ Neutron RBAC ↩","s":"Footnotes","u":"/standards/scs-0113-v1-security-groups-decision-record","h":"#footnote-label","p":3095},{"i":3124,"t":"The Kubernetes project maintains multiple release versions including their patched versions. In the project, the three most recent minor releases are actively maintained, with a fourth version being in development. As soon as a new minor version is officially released, the oldest version is dropped out of the support period. Kubernetes supports its releases for around 14 months. 12 of these are the standard support period. The remaining 2 months are the end-of-life support period for things like: CVEs (under the advisement of the Security Response Committee) dependency issues (including base image updates) critical core component issues More information can be found under [Kubernetes Support Period]. The Kubernetes release cycle is set around 4 months, which usually results in about 3 minor releases per year. Patches to these releases are provided monthly, with the exception of the first patch, which is usually provided 1-2 weeks after the initial release (see Patch Release Cadence).","s":"Introduction","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#introduction","p":3122},{"i":3126,"t":"Kubernetes is a living, fast-paced project, which follows a pre-defined release cycle. This enables forward planning with regards to releases and patches, but also implies a necessity to upgrade to newer versions quickly, since these often include new features, important security updates or especially if a previous version falls out of the support period window. We want to achieve an up-to-date policy, meaning that providers should be mostly in sync with the upstream and don't fall behind the official Kubernetes releases. This is achievable, since new versions are released periodical on a well communicated schedule, enabling providers and users to set up processes around it. Being up to date ensures that security issues and bugs are addressed and new features are made available when using SCS compliant clusters. It is nevertheless important to at least support all Kubernetes versions that are still inside the support period, since users could depend on specific versions or may need longer to upgrade their workloads to a newer version. The standard therefore should provide a version recency policy as well as a support window period.","s":"Motivation","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#motivation","p":3122},{"i":3128,"t":"In order to keep up-to-date with the latest Kubernetes features, bug fixes and security improvements, the provided Kubernetes versions should be kept up-to-date with new upstream releases: The latest minor version MUST be provided no later than 4 months after release. The latest patch version MUST be provided no later than 1 week after release. This time period MUST be even shorter for patches that fix critical CVEs. In this context, a critical CVE is a CVE with a CVSS base score >= 8 according to the CVSS version used in the original CVE record (e.g., CVSSv3.1). It is RECOMMENDED to provide a new patch version in a 2 day time period after their release. New versions MUST be tested before being rolled out on productive infrastructure; at least the CNCF E2E tests should be passed beforehand. At the same time, providers must support Kubernetes versions at least as long as the official sources as described in Kubernetes Support Period: Kubernetes versions MUST be supported as long as the official sources support them according to the Kubernetes Support Period and their end-of-life date according to the Kubernetes Releases page. It is RECOMMENDED to not support versions after this period in order to not encourage usage of out-of-date versions.","s":"Decision","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#decision","p":3122},{"i":3130,"t":"All documents regarding versioning, releases, etc. for the official Kubernetes projects can be found on the Kubernetes Releases page.","s":"Related Documents","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#related-documents","p":3122},{"i":3132,"t":"The script k8s_version_policy.py requires a kubeconfig file with connection details for a set of existing Kubernetes clusters that should be checked, with each of these clusters representing one of the currently supported upstream Kubernetes releases. It will check the encountered cluster versions according to the rules of this standard. Rule violations will be reported on various logging channels: ERROR for mandatory rules and INFO for recommended rules. The script will exit with a non-zero status if a mandatory rule has been violated or if the test could not be performed.","s":"Conformance Tests","u":"/standards/scs-0210-v2-k8s-version-policy","h":"#conformance-tests","p":3122},{"i":3135,"t":"Cluster consumers can request persistent storage via PersistentVolumeClaims which is provisioned automatically by cloud-provided automation. Storage requirements may vary across use cases, so there is the concept of StorageClasses. StorageClasses define some set of storage properties. So, consumers can choose one of these depending on the use case. Kubernetes documentation","s":"Introduction","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#introduction","p":3133},{"i":3137,"t":"While often times, consumers will choose a StorageClass explicitly, usually, there is also a default StorageClass to fall back on in case it is not chosen explicitly (that is, when storageClassName is not set on the PersistentVolumeClaim). This document attempts to define the properties this default StorageClass should have.","s":"Motivation","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#motivation","p":3133},{"i":3139,"t":"The default StorageClass is made default using the storageclass.kubernetes.io/is-default-class annotation, following Kubernetes upstream. Hence, standardizing its name is not required for the intents of this standard.","s":"Decision","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#decision","p":3133},{"i":3141,"t":"ReadWriteOnce must be a supported access mode volume must be protected against data loss due to hardware failures of a single disk or host volume must not be bound to the lifecycle of a Kubernetes Node Hence, ...volume must not be backed by local storage on the Kubernetes Node VM itself ...volume may be backed by some kind of redundant storage within an AZ, across hosts ...volume may be backed by some kind of redundant storage across AZ's","s":"Required non-performance-related properties","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#required-non-performance-related-properties","p":3133},{"i":3143,"t":"NO fixed guarantees regarding latency/bandwidth/IOPS/... Generally, customers should be able to expect low-tier performance without pricing surprises.","s":"Required performance-related properties","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#required-performance-related-properties","p":3133},{"i":3145,"t":"This document does not describe performance related properties. This will be done in another document which is yet to be created.","s":"Related Documents","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#related-documents","p":3133},{"i":3147,"t":"TBD","s":"Conformance Tests","u":"/standards/scs-0211-v1-kaas-default-storage-class","h":"#conformance-tests","p":3133},{"i":3150,"t":"A container registry is an infrastructure service to enable storing and accessing container images. Images can be pushed to the registry by e.g. Continuous integration pipelines and be pulled from by runtime environments like Kubernetes clusters. Container registries come in various forms, e.g. publicly accessible ones like Docker Hub or self-hosted and cloud-hosted services. The latter examples may apply various access control mechanisms to restrict access. Both solutions offer a wide range of features that may or may not attract potential users and CSPs.","s":"Introduction","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#introduction","p":3148},{"i":3152,"t":"Cloud Service Provider (abbr. CSP) Entity that provides scalable computing resources Identity Provider (abbr. IdP) System that creates, maintains, and manages identity information","s":"Terminology","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#terminology","p":3148},{"i":3154,"t":"This standard is motivated by different use cases identified through the topics in the SCS project. One use case would be the offering of private registries for customers by CSPs, which means that a CSP could offer private container registries either as a service or as a provided \"recipe\" to deploy a private registry utilizing the CSPs infrastructure. Another use case would be the selection of a registry for the SCS reference implementation. The idea and purpose of this document is to specify what requirements a specific technical container registry implementation (i.e. software solution) needs to fulfill for an SCS-compliant registry.","s":"Motivation","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#motivation","p":3148},{"i":3156,"t":"There are numerous features that should be evaluated for a container registry solution. It is important to assess the registries based on the requirements of the OSS health checks and desired features defined by the SCS. The following two subsections show these requirements.","s":"Design considerations","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#design-considerations","p":3148},{"i":3158,"t":"It is important to evaluate the health of a project before even evaluating the project for its feature set. A project should therefore fulfill all OSS health checks be defined by the OSS-Health document. This document evaluates the health of the open-source projects that were selected from the currently available solutions. The container registry software must fulfill all OSS health checks defined below: Four Opens (code is fully open source, community is open and diverse, development process is open, design process is open) Maturity Security Activity Lock-in risk assessment","s":"OSS health check","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#oss-health-check","p":3148},{"i":3160,"t":"A container registry provides a specific feature set, which can be mapped out against the requirements described in this section. The registry should generally be robust (e.g. operate under heavy load) and secure in order to be acceptable for the SCS standard. Therefore, a required and optional feature set were defined, to which a container registry must abide and be evaluated against. Required features​ Audit Logs ability to record use in auditable logs so that activity can be traced to a single user Authentication of system identities support for authenticating system identities like Kubernetes clusters possibly support for dynamic identity tokens from some IdP Authentication of users support for multiple authentication systems (IdM integration) user and user account management Authorization role-based access control to ensure strict access controls Automation integration with CI/CD tools e.g. via webhooks Vulnerability scanning reveal security vulnerabilities in container images Content Trust and Validation verify image authenticity before running image signing Multi-tenancy container registry is able to serve multiple tenants (projects, teams, namespaces) implementation on the storage level, see e.g. Keppel, which uses multi-tenant-aware storage drivers Backup and restore possible strategies for disaster recovery and data migration scenarios Monitoring observability is a key feature for operating a service in production so the container registry should expose key metrics HA mode enable the possibility of system uptime, even if a failure of some sort could occur Registry replication replication allows users to replicate container images between registries of the same instances and between registries of different instances as well Proxy cache (pull-through cache) Proxy cache enables the use of a container registry to proxy and cache images from a target public or private registry Quota management ability to control resource use of components or the whole registry Garbage collection removing blobs from the filesystem when they are no longer referenced by a manifest Retention policy reduce the number of image tags, many of which might not be required after a given time or once a subsequent image tag has superseded them Desirable features​ Additionally supported artifacts Additional artifacts that the registry is able to store in addition to OCI artifacts, e.g. Java, Node.js, or Python packages Integration possibilities Ability to cooperate with another software solution in order to improve own feature set (e.g. integration of P2P solution for improving container image distribution (download speed and stability, high scalability, ...)) Deployment capabilities ways to deploy a container registry (only \"official\" ways are mentioned) Administration capabilities \"as a code\" ability to manage container registry via \"as a code\" solutions, e.g. Ansible role","s":"Required and desirable features check","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#required-and-desirable-features-check","p":3148},{"i":3162,"t":"It is very unlikely, that every Container registry can fulfill every requirement defined by this document, and probably not all deployments require every feature listed here. The required feature set should therefore be carefully considered by the provider of the registry. We nevertheless RECOMMEND using most of the feature set provided in this document. If the features mentioned above are all considered, a possible registry solution SHOULD fulfill the majority of the required features. But this is again dependent on the specific use case and the surrounding architecture.","s":"Standard","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#standard","p":3148},{"i":3164,"t":"OSS-Health","s":"Related Documents","u":"/standards/scs-0212-v1-requirements-for-container-registries","h":"#related-documents","p":3148},{"i":3167,"t":"Here we will describe how fast providers need to keep up with the upstream Kubernetes version. To create a informed decision we summarize here the Kubernetes rules regarding versioning at the time of writing (2023-01-16): Kubernetes usually provides about 3 minor releases per year (see Kubernetes Release Cycle). Patch release cadence is typically monthly. However, the first patches after the first minor release usually arrive 1-2 weeks after the first minor release (see Patch Release Cadence). As stated in Kubernetes Support Period, in general the latest 3 minor versions are maintained by the Kubernetes project. Every release will be maintained for about 14 months. The first 12 months are the standard support period. The remaining 2 months are only for: CVEs (under the advisement of the Security Response Committee) dependency issues (including base image updates) critical core component issues","s":"Introduction","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#introduction","p":3165},{"i":3169,"t":"Kubernetes is a fast-paced project. We want to achieve that providers keep up to date with upstream and do not fall behind Kubernetes releases. This ensures that users are able to upgrade their clusters to address security issues, bug fixes and new features when using SCS compliant clusters in regards of Kubernetes. However, providers should have reasonable time to implement the new Kubernetes versions and test them.","s":"Motivation","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#motivation","p":3165},{"i":3171,"t":"Must provide latest minor version no later than 4 months after release Must provide latest patch version no later than a week after release Should be faster for critical CVEs (CVSS >= 8) Should be tested","s":"Decision","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#decision","p":3165},{"i":3173,"t":"All important documents regarding versioning, releases, etc. for the official Kubernetes project can be found on the Kubernetes Releases page.","s":"Related Documents","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#related-documents","p":3165},{"i":3175,"t":"The conformance test is written in the 'k8s-version-recency-check.py' script. The script requires the path to a valid kubeconfig file, which should describe the k8s cluster under test. This can either be done by creating a config from the also provided 'config.yaml.template' or by calling the test script with its cli arguments.","s":"Conformance Tests","u":"/standards/scs-0210-v1-k8s-new-version-policy","h":"#conformance-tests","p":3165},{"i":3178,"t":"A Kubernetes instance is provided as a cluster, which consists of a set of worker machines, so called nodes. A cluster is composed of a control plane and at least one worker node. The control plane manages the worker nodes and therefore the pods in the cluster by making decisions about scheduling, event detection and global decisions. Inside the control plane, multiple components exist, which can be duplicated and distributed over multiple machines inside the cluster. Typically, no user containers are run on these machines in order to separate the control plane from the live system.","s":"Introduction","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#introduction","p":3176},{"i":3180,"t":"The following special terms are used throughout this decision record document: Term Meaning Worker Virtual or bare-metal machine, which hosts workloads of customers Control Plane Virtual or bare-metal machine, which hosts the container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers. Machine Virtual or bare-metal entity with computational capabilities","s":"Glossary","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#glossary","p":3176},{"i":3182,"t":"In a productive environment, the control plane usually runs across multiple machines and a cluster usually contains multiple worker nodes in order to provide fault-tolerance and high availability. In order to ensure availability and scaling of workloads, even if some nodes in the cluster could fail, they should be distributed over multiple nodes on different machines. This can be steered with the Affinity or Anti Affinity features, which are separated by Kubernetes into two features: Node Affinity The Node Affinity feature allows to match pods according to logical matches of key-value-pairs referring to labels of nodes. These can be defined with different weights or preferences in order to allow fine-grained selection of nodes. The feature works similar to the Kubernetes nodeSelector. It is defined in the PodSpec using the nodeAffinity field in the affinity section. Pod Affinity Pod Affinity or Pod Anti Affinity allows the constraint of pod scheduling based on the labels of pods already running on a node. This means the constraint will match other pods on a node according to their labels key-value-pairs and then either schedule the pod to the same (Affinity) or another (Anti Affinity) node. This feature is also defined in the PodSpec using the podAffinity and podAntiAffinity fields in the affinity section. [3] Both features allow the usage of \"required\" or \"preferred\" keywords, which create \"hard\" or \"soft\" affinities. By using a hard affinity, a pod would need to be scheduled according to the rules set. If this possibility is not given, the pod can't be scheduled. A soft affinity would allow scheduling even if the requirements are not fulfilled, but they would be preferred if possible. These features allow efficient resource usage (e.g. by scheduling workloads to evenly distribute across nodes) and provide fault-tolerance and therefore high availability. But they also require more work during the setup of a service architecture, since nodes and pods need to be labelled and described consistently. In the case of SCS, affinity of the workloads themselves is not relevant, since this feature is mostly used by the customers of the providers. Instead, the expected standard should enable the Kubernetes cluster to handle Anti Affinity rules with a real physical separation as well as distributing the control plane over multiple machines in order to provide fault-tolerance during system outages. If the control plane survives an outage, a Kubernetes cluster can recover later on.","s":"Motivation","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#motivation","p":3176},{"i":3184,"t":"SCS plans to require a Hard Anti Affinity and/or Redundancy for the control plane and a Soft Anti Affinity for workers. This means, that Anti Affinity would be required for the control planes and their pods and only optional (but encouraged) for workers. In order to achieve the goals for these components, meaning availability and fault tolerance for the control plane, an outage resistant cluster, and the availability promise given with Anti Affinity for pods on the worker nodes, a separation of nodes on the hardware level would need to be achieved. For the control plane, a reference to the \"Kubernetes High Availability\" [1] can be useful, since it provides two ways to set up a highly available cluster. Both approaches are very similar. The \"Stacked Control Plane\" [2] requires less infrastructure, but also runs the risk of failed coupling, where if one node fails, the redundancy could be compromised due to the loss of a complete control plane instance. The \"External ETCD\" solves this problem, but also requires double the infrastructure, due to the externally incorporated etcd clusters. This also shows, that the wording \"anti affinity\" as used with Kubernetes pods is probably slightly misleading in the context of a Kubernetes control plane. It may consist of multiple pods with individual tasks, but distributing them over different nodes through Anti Affinity would probably still cascade the whole control plane into a complete failure, if one of the used nodes goes down. It could be possible to replicate specific important pods and assign them to different nodes, but at this point, a redundant setup like presented in [1] could be used. So Anti Affinity in this context probably means more like distribution over multiple physical machines, which needs to be planned beforehand on the machine/server level. Therefore would it be preferred for the control plane to use a redundant setup, which is separated over different physical machines, meaning at least half of the control plane nodes runs on a different physical machine as the rest. The currently used ClusterAPI enables this by establishing the concept of \"failure domains\". These are used to control the placement of k8s nodes and distribute them over multiple physical machines. For example, a High Availability K8s cluster with three control plane nodes could be distributed over three different availability zones (and therefore 3 different physical machines) in order to survive the failure of one availability zone. [5] For worker nodes, the whole idea of Anti Affinity is more of a preferable situation. The nodes themselves should at best be distributed over different machines, but this is not a requirement, especially since smaller providers wouldn't have the capacity to provide enough machines for these distributed Kubernetes clusters. Since customers that use the Affinity or Topology spread constraint [4] features would be especially interested in the worker nodes that host their workloads, it should be ensured that a good labeling system is provided for the nodes in order to see if two nodes are hosted on the same machine.","s":"Design considerations","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#design-considerations","p":3176},{"i":3186,"t":"The future standard should define a few important things in order to provide a solid base for the usage and advantages of workloads with Anti Affinity rules. Control planes SHOULD be made redundant in order to provide fault-tolerance and security against fatal errors on this layer, in the case of node failures. How this redundancy is achieved SHOULD be left to the providers, but since failure must be avoided, it is REQUIRED to at least duplicate control plane components. Half of every component SHOULD be located on a different node on a different physical machine than the other half of them. This should provide at least the minimum requirements for a fault-tolerant control plane. For the standard, there is also a possibility to define multiple stages of distributed infrastructure and only make sensible ones a requirement and the rest optional, e.g. non-distributed clusters High-Availability clusters that are distributed over multiple machines/availability zones distributed over multiple clouds distributed over multiple physical locations/datacenters The worker nodes are RECOMMENDED to be distributed over different machines. In order to provide clear information to the users, the nodes should be labeled to reflect the mapping to the underlying clusters. The labels can be obfuscated in order to not reveal the underlying structures to customers and users. It should be noted, that it is NOT REQUIRED to have this anti affinity for the worker nodes due to the requirements of infrastructure and complexity associated with this.","s":"Decision","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#decision","p":3176},{"i":3188,"t":"Kubernetes High Availability Documentation 1 Kubernetes High Availability - Stacked ETCD 2 Affinity and Anti-Affinity 3 Topology Spread Constraints 4 SCS Multi AZ and Multi Cloud Environments 5","s":"Documents","u":"/standards/scs-0213-v1-k8s-nodes-anti-affinity","h":"#documents","p":3176},{"i":3191,"t":"A Kubernetes instance is provided as a cluster, which consists of a set of machines, so-called nodes. A cluster is composed of a control plane and at least one worker node. The control plane manages the worker nodes and therefore the pods in the cluster by making decisions about scheduling, event detection and rights management. Inside the control plane, multiple components exist, which can be duplicated and distributed over multiple nodes inside the cluster. Typically, no user workloads are run on these nodes in order to separate the controller component from user workloads, which could pose a security risk.","s":"Introduction","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#introduction","p":3189},{"i":3193,"t":"The following terms are used throughout this document: Term Meaning Worker Virtual or bare-metal machine, which hosts workloads of customers Control Plane Virtual or bare-metal machine, which hosts the container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers. Machine Virtual or bare-metal entity with computational capabilities","s":"Glossary","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#glossary","p":3189},{"i":3195,"t":"In normal day-to-day operation, it is not unusual for some operational failures, either due to wear and tear of hardware, software misconfigurations, external problems or user errors. Whichever was the source of such an outage, it always means down-time for operations and users and possible even data loss. Therefore, a Kubernetes cluster in a productive environment should be distributed over multiple \"failure zones\" in order to provide fault-tolerance and high availability. This is especially important for the control plane of the cluster, since it contains the state of the whole cluster. A failure of this component could mean an unrecoverable failure of the whole cluster.","s":"Motivation","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#motivation","p":3189},{"i":3197,"t":"Most design considerations of this standard follow the previously written Decision Record Kubernetes Nodes Anti Affinity as well as the Kubernetes documents about High Availability and Best practices for large clusters. SCS wishes to prefer distributed, highly-available systems due to their obvious advantages like fault-tolerance and data redundancy. But it also understands the costs and overhead for the providers associated with this effort, since the infrastructure needs to have hardware which will just be used to provide fail-over safety or duplication. The document Best practices for large clusters describes the concept of a failure zone. This term isn't defined any further, but can in this context be described as a number of physical (computing) machines in such a vicinity to each other (either through physical or logical interconnection in some way), that specific problems inside this zone would put all these machines at risk of failure/shutdown. It is therefore necessary for important data or services to not be present just on one failure zone. How such a failure zone should be defined is dependent on the risk model of the service/data and its owner as well as the capabilities of the provider. Zones could be set from things like single machines or racks up to whole datacenters or even regions, which could be coupled by things like electrical grids. They're therefore purely logical entities, which shouldn't be defined further in this document.","s":"Design Considerations","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#design-considerations","p":3189},{"i":3199,"t":"This standard formulates the requirement for the distribution of Kubernetes nodes in order to provide a fault-tolerant and available Kubernetes cluster infrastructure. Since some providers only have small environments to work with and therefore couldn't comply with this standard, it will be treated as a RECOMMENDED standard, where providers can OPT OUT. If the standard is used by a provider, the following decisions are binding and valid: The control plane nodes MUST be distributed over multiple physical machines. Kubernetes provides best-practices on this topic, which are also RECOMMENDED by SCS. At least one control plane instance MUST be run in each \"failure zone\", more are RECOMMENDED in each \"failure zone\" to provide fault-tolerance for each zone. Worker nodes are RECOMMENDED to be distributed over multiple zones. This policy makes it OPTIONAL to provide a worker node in each \"failure zone\", meaning that worker nodes can also be scaled vertically first before scaling horizontally. Worker node distribution MUST be indicated to the user through some kind of labeling in order to enable (anti)-affinity for workloads over \"failure zones\".","s":"Decision","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#decision","p":3189},{"i":3201,"t":"The script k8s-node-distribution-check.py checks the nodes available with a user-provided kubeconfig file. It then determines based on the labels kubernetes.io/hostname, topology.kubernetes.io/zone, topology.kubernetes.io/region and node-role.kubernetes.io/control-plane, if a distribution of the available nodes is present. If this isn't the case, the script produces an error. If also produces warnings and informational outputs, if e.g. labels don't seem to be set.","s":"Conformance Tests","u":"/standards/scs-0214-v1-k8s-node-distribution","h":"#conformance-tests","p":3189},{"i":3204,"t":"In this proposal, we discuss the necessity and design considerations of a lightweight solution for testing cluster-stacks. The purpose is to address the challenges associated with testing on an Infrastructure as a Service (IaaS) provider and the limitations of using Docker as the primary containerization tool for testing. This proposal will elaborate on why we need to test in a local environment, specifically a laptop, and the benefits and drawbacks associated with it. We aim to make an informed decision for testing cluster stacks to cater to both the organizational and technical perspectives of our stakeholders.","s":"Introduction","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#introduction","p":3202},{"i":3206,"t":"From an organization's point of view, it is crucial to lower the entry barrier for testing. This action will make it possible for anyone, including external contributors, to easily participate in the testing process without needing an account with the IaaS provider. It is also necessary to overcome the hurdles associated with maintaining a balance in the provider account and managing sponsorships to fund the testing. From a technical standpoint, there are multiple reasons to favor a local environment for testing. Among them is the ability to test without internet, finish tests in a shorter timeframe, and incur no cost. The provider independence of Cluster Stacks makes it nonsensical to test with a specific provider due to the varied behaviors of different providers. There are also challenges in monitoring and debugging tests run on IaaS providers and dealing with their downtime and limitations on concurrent testing.","s":"Motivation","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#motivation","p":3202},{"i":3208,"t":"Lightweight Solution The testing solution should be lightweight and easy to use in a local environment, such as a laptop. This lightweight solution should minimize dependencies and resource usage while maximizing speed and efficiency of the tests. It should be capable of handling the cluster-stack testing requirements without necessitating a bulky or resource-intensive setup. Independence from Specific Providers The solution should be generalized and not bound to any specific provider. This consideration ensures that the solution can be applied to any provider, guaranteeing its versatility and broad applicability. Offline Testing The testing solution should support testing without internet connection, which will enable more robust and flexible testing scenarios. It should be possible to run the tests even in cases of limited or disrupted internet access. Fast Execution Time The tests should execute within a reasonably short amount of time. The solution must be optimized to ensure quick testing cycles, which can help increase productivity and shorten development cycles. No-Cost Solution The solution should not impose any additional costs on the organization or individual testers. This characteristic is crucial to enable widespread adoption of the testing process and to lower the entry barrier for contributors. Easy Monitoring and Debugging The solution should provide easy monitoring and debugging capabilities. It should allow developers to quickly identify, diagnose, and fix issues that arise during testing, without requiring access to any external logs or monitoring tools. Concurrent Testing The solution should support the ability to run concurrent tests without causing any disruption or downtime. This ability can improve the efficiency and speed of the testing process.","s":"Design Considerations","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#design-considerations","p":3202},{"i":3210,"t":"The proposed solution should meet the following feature requirements: Local Environment: The solution should support a local testing environment that allows developers to test cluster stacks on their local machines, reducing dependencies on external providers. Compatibility: The solution should be compatible with various operating systems and platforms, ensuring its usability across diverse environments. Performance: The solution should offer high-performance testing capabilities, allowing fast execution of tests. Offline Support: The solution should allow testing in offline mode, ensuring tests can be performed even without an internet connection. Concurrency: The solution should support running multiple tests concurrently without causing disruptions or conflicts. Monitoring & Debugging: The solution should provide easy-to-use tools for monitoring test progress and debugging issues. Cost-effectiveness: The solution should not require any financial investment from the testers or the organization, promoting broad accessibility and usage.","s":"Required Features","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#required-features","p":3202},{"i":3212,"t":"Two potential approaches for testing cluster stacks are the use of an IaaS provider and the use of a local environment. Here we discuss the pros and cons of these two approaches.","s":"Pros and Cons of Different Approaches","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#pros-and-cons-of-different-approaches","p":3202},{"i":3214,"t":"Pros​ Comprehensive testing environment with advanced capabilities. Possibility to mimic real-world production environments closely. Cons​ Requires signing up and account management, which can be a barrier for some testers. Requires maintaining a balance in the provider account, which can pose financial burdens. Internet dependency for testing. Potential for prolonged testing time due to various dependencies. Challenges with monitoring and debugging. Potential downtime and difficulty in running concurrent tests.","s":"IaaS Provider (OpenStack, Hetzner, AWS)","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#iaas-provider-openstack-hetzner-aws","p":3202},{"i":3216,"t":"Pros​ Faster test execution with no downtime. Ability to test without internet. Independent of any provider knowledge. Cost-free testing. Easier integration into CI/CD. Simplified monitoring and debugging. Cons​ Limited systemd support and containerd support for kubeadm in Docker. Inability to mimic the exact real-world production environments.","s":"Local Environment (Docker, Kubevirt)","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#local-environment-docker-kubevirt","p":3202},{"i":3218,"t":"While Docker provides significant benefits for local environment testing, it's important to recognize its limitations. Docker containers, by design, are lightweight and don't contain a full operating system which can lead to challenges when trying to mimic real-world production environments. Also, Docker containers lack some necessary features like systemd which is used in many production environments for initializing and managing services. One major aspect that Docker lacks is the ability to mimic real-world production environments effectively. This is primarily due to its nature as a containerization tool, operating within the host OS, and sharing resources among its containers. This might create disparities in behavior when comparing to deployments on real, isolated systems, which could be problematic in some scenarios. Furthermore, Docker utilizes a Union File System for its images, leading to the creation of layers. This approach can lead to some complexities when dealing with node-images which comprise a significant chunk of our layers. Handling such situations might require workarounds that could add additional complexity and potential points of failure. This creates a blind spot, as real providers won't require these workarounds, which might lead to disparities in results when comparing testing in local and actual production environments. Therefore, to achieve a more accurate representation of real-world environments, we propose a solution that utilizes a virtual machine based approach for local testing. This approach could leverage tools like KubeVirt, Vagrant, or VirtualBox to create and manage virtual machines on the local environment. This strategy would provide a more robust and realistic environment for testing, as it can better emulate the behavior of a full-fledged operating system and thereby more closely mimic a real-world production environment.","s":"Beyond Docker: Virtual Machine based Approach","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#beyond-docker-virtual-machine-based-approach","p":3202},{"i":3220,"t":"Pros​ Provides a more accurate representation of real-world production environments. Allows for full operating system emulation, including features like systemd. Can create isolated environments, thereby mimicking actual deployments better than containers. Cons​ Potentially more resource-intensive than container-based solutions. Increased complexity due to the need for managing full virtual machines rather than lightweight containers. Initial setup might be more complicated compared to a Docker-based solution.","s":"Virtual Machine Based Approach","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#virtual-machine-based-approach","p":3202},{"i":3222,"t":"Given the limitations of Docker and the potential advantages of a virtual machine based approach, we propose to investigate further into this strategy. The exact tool or set of tools used can be determined based on a thorough evaluation of the available options. Although there might be some initial complexity and potentially higher resource usage compared to Docker, we believe that the benefits of more accurate testing and better emulation of real-world environments outweigh these potential disadvantages. The proposed solution should meet all the requirements mentioned in the previous sections of the proposal, in addition to providing the benefits of a virtual machine based approach. By doing so, we aim to establish a robust, reliable, and realistic testing environment for cluster stacks that mimics real-world production environments as closely as possible.","s":"Proposed Path Forward","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#proposed-path-forward","p":3202},{"i":3224,"t":"After thoroughly examining the organizational needs, technical requirements, and potential testing approaches, it is evident that testing cluster stacks in a local environment provides significant advantages over using an Infrastructure as a Service (IaaS) provider. A local environment minimizes financial constraints, reduces testing time, offers offline capabilities, and enables greater tester participation without the need for specialized IaaS knowledge. While Docker stands out for its broad adoption, cost-effectiveness, and impressive containerization benefits, it also presents some limitations that cannot be overlooked. The lack of full operating system emulation and certain system features like systemd pose challenges to mimic real-world production environments accurately. Given Docker's limitations and the need to reproduce realistic testing scenarios, we propose moving beyond Docker to a virtual machine-based approach. Even though this approach may introduce initial complexity and potentially higher resource usage, it promises a more accurate representation of real-world environments, thereby ensuring more reliable and robust test results. Tools such as KubeVirt, Vagrant, or VirtualBox could potentially fulfill our requirements, offering benefits such as full operating system emulation and isolated environments. However, an in-depth evaluation of these and possibly other tools is necessary to determine the best path forward. In conclusion, our goal is to design a robust, reliable, and realistic testing environment for cluster stacks that closely mimics real-world production environments, aligns with our organizational and technical perspectives, and ensures a low entry barrier for all testers. Embracing a virtual machine-based approach for local environment testing represents a promising strategy to achieve this objective, paving the way for more efficient and reliable cluster stack testing.","s":"Conclusion","u":"/standards/scs-0216-v1-requirements-for-testing-cluster-stacks","h":"#conclusion","p":3202},{"i":3227,"t":"Due to the regular changes and updates, there are always new security features to deploy and use in Kubernetes. Nevertheless, a provider (or even a customer) needs to take action in order to achieve a hardened, secure cluster due to the myriad of configurations possible. This is especially the case since Kubernetes ships with insecure features and configurations out of the box, which will need to be mitigated by an administrator with the proper knowledge. Hardened, secure Kubernetes clusters are desirable regardless of the possible threat model, since higher security doesn't necessarily mean higher complexity in this case.","s":"Introduction","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#introduction","p":3225},{"i":3229,"t":"Term Meaning TLS Transport Layer Security CA Certificate Authority CSR Certificate Signing Request","s":"Terminology","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#terminology","p":3225},{"i":3231,"t":"Kubernetes clusters are highly configurable, which also gives rise to different security problems, if the configuration isn't done properly. These security risks can potentially be exposed in many different parts of a cluster, e.g. different APIs, authorization and authentication procedures or even Pod privilege mechanisms. In order to mitigate these problems, different steps and mechanisms could be used to increase the security of a Kubernetes setup.","s":"Motivation","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#motivation","p":3225},{"i":3234,"t":"Kubernetes provides an API to provision TLS certificates that can be signed by a CA. This CA can be controlled by the cluster provider, which enables much more tight control over the clusters communication and therefore also better controllable security. In order to do this, the CA certificate bundle needs to be added to the trusted certificates of the server. To provide a certificate, the following steps need to be undertaken: Create a CSR Send the CSR manifest to the k8s API Approve the CSR Sign CSR with your CA Upload the signed certificate to the server This certificate could now be used by a user in a pod in order to provide a trusted certificate. It is also possible for the Kubernetes controller manager to provide the signing functionality. To enable this, --cluster-signing-cert-file and --cluster-signing-key-file need to be set with a reference to the CA keypair, which was used in the previous example to sign a CSR.","s":"External CA","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#external-ca","p":3225},{"i":3236,"t":"In order to secure a Kubernetes cluster, the protection of endpoints is important. To do this, different approaches can be taken. TLS for all internal/API traffic​ It is already expected by Kubernetes that all API communication internally is encrypted with TLS. Nevertheless, some endpoints of internal components could be/will be exposed without the necessary encryption, which could lead to weak points in the system. A list of the default service endpoints can be seen in the following table Protocol Port Range Purpose Notes TCP 6443* Kubernetes API Server - TCP 2379-2380 etcd server client API - TCP 10250 Kubelet API - TCP 10251/10259 kube-scheduler 10251 could be insecure before 1.13, after that only the secure port 10259 is available TCP 10252/10257 kube-controller-manager 10252 could be insecure before 1.13, after that only the secure port 10257 is available TCP 30000-32767 NodePort Services Service endpoints, could be HTTP The usage of readOnlyPort (enabling a read-only Kubelet API port on 10255) by design neither provides authentication nor authorization. Its usage is strongly discouraged! Authentication and Authorization​ All API clients should authenticate and authorize in order to be able to access an API or even specific functions of this API. This is the case for users as well as internal components. Most internal clients (like proxies or nodes) are typically authenticated via service accounts or x509 certificates, which will normally be created automatically during the setup of a cluster. External users can authenticate via an access pattern of choice, which is typically decided by the cluster provider. Authorization is (normally) done by the Role-Based Access Control (RBAC), which matches a request by a user with a set of permissions, also called a role. Kubernetes deploys some roles out-of-the-box; additional roles need to be carefully checked, since some permissions for specific resources allow modification of other resources. This whole process is especially important for the Kubelet, which allows anonymous requests in its default configuration. This is obviously a security risk, since everybody with access to its endpoint could manipulate resources that are managed with the Kubelet. To disable anonymous requests, the Kubelet should be started with --anonymous-auth=false. Authentication can be provided either through x509 client certificates or API bearer tokens. How to set up both approaches can be found in the Kubelet Authentication and Authorization. Kubelet authorization is set to AlwaysAllow as a default mode. This can be quite problematic, since all authenticated users can do all actions. To mitigate this, it is possible to delegate authorization to the API server by: enabling the authorization.k8s.io/v1beta1 API group starting the Kubelet with the --authorization-mode=Webhook and the --kubeconfig flags After that, the Kubelet calls the SubjectAccessReview API in order to determine the authorization of a request.","s":"Protected Kubernetes endpoints","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#protected-kubernetes-endpoints","p":3225},{"i":3238,"t":"This standard tries to increase security for a Kubernetes cluster in order to provide a solid baseline setup with regard to security. For this to work, multiple measures need to be undertaken. A self-controlled CA SHOULD be used in order to be in control of the TLS certificates, which enables operators to provide and revoke certificates according to their own requirements. All internal endpoints found in the section [TLS for all internal/API traffic] MUST be encrypted with TLS in order to secure internal traffic. The Kubernetes API (kubeAPI) MUST be secured by authenticating and authorizing the users trying to access its endpoints. How a user is authenticated is up to the provider of the cluster and/or the wishes of the customer. Authorization MUST be done by providing fine-grained RBAC. The authentication and authorization steps MUST also be applied to the Kubelet, which in its default configuration doesn't enable them. A way to do this can be found in the section [Authentication and Authorization].","s":"Decision","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#decision","p":3225},{"i":3240,"t":"Managing TLS in a cluster Securing a cluster Controlling access Kubernetes Security Checklist Kubelet Authentication and Authorization Authentication OWASP Kubernetes Security Cheat Sheet","s":"Related Documents","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#related-documents","p":3225},{"i":3242,"t":"Conformance Tests will be written in another issue","s":"Conformance Tests","u":"/standards/scs-0217-v1-baseline-cluster-security","h":"#conformance-tests","p":3225},{"i":3245,"t":"Our assumption is that there are use cases, where CSPs would like to be able to let customers access their SCS based services by identifying themselves with credentials that are stored and managed external to the CSP's SCS installation. This is based on the observation that prospective customers of an SCS based CSP sometimes already come equipped with an IAM solution of their choice, either on premises or e.g. as an external 3rd party cloud service. To ease onboarding of customer employees (or e.g. customer contracted 3rd party admin staff) as SCS users, it would be good to be able to consume these external identities in SCS. For customers this avoids the neccessity to explicitly maintain an additional dedicated account in SCS and this also reduces what SCS needs to do with respect to taking care of persisting user account information. To put it in other words, in SCS we would like to be able to delegate authentication to external identity providers and map those users to roles in SCS that can be used for authorization decisions when users access SCS services. In addition to user identities there we also see the necessity to support the use of \"machine identites\" (aka \"workload identities\" or \"service accounts\"). These will probably be SCS-local accounts and have for example the purpose to grant CaaS workload access to storage resources served by the infrastructure layer. Exact architectural details for this are still in active discussion, but it is anticipated that the IdP component should be very useful in facilitating the integration.","s":"Introduction","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#introduction","p":3243},{"i":3247,"t":"SCS has multiple service layers, like IaaS and CaaS, both of which running their own technological stack with specific internal models of accounts and authorization. One thing these services have in common, is that they are able to use SSO protocols like OAuth 2.0 or OpenID Connect (OIDC) on top of it to delegate authentication. They are service providers (SAML terminology) and can be relying parties (OIDC terminology) of a protocol compliant identity provider (IdP). So the idea is, to run an SSO IdP as part of SCS to provide a dedicated point of entry for identites, which the SCS service layers can use as a common interface to consume external user identities. The purpose of this document is to specify what requirements a specific technical IdP implementation (i.e. software solution) needs to fulfill in the context of SCS.","s":"Motivation for this document","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#motivation-for-this-document","p":3243},{"i":3249,"t":"As a central service for identity handling, the IdP service needs to be robust and reliable. Customers shall be able to access self service, so that they can make reasonable adjustments e.g. to role mapping. At the time of writing this document it's still undecided if SCS has the requirement of a dedicated \"self service\" service that serves as a frontend to provision and re-configure customer specific data, abstracting e.g. from IdP specific user interface particularities. Keycloak is currently being deployed as part of the IaaS reference implementation. Technically this IdP component shall be shifted from the management plane to be run on the basis of a \"minimal\" Kubernetes (e.g. K3S), e.g. to make use of the \"self healing\" and scaling features achievable with that. So one of the considerations is if the solution will work well on a K8S environment. The instances will need to share configuration (probably via the shared backend database) as well as session state. Maybe one is better prepared for horizontal scaling than the other.","s":"Design Considerations","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#design-considerations","p":3243},{"i":3251,"t":"Keycloak​ Keycloak is a commonly used IdP solution implemented in Java. It is developed as an open source community project. Red Hat uses it as upstream source for their Red Hat SSO product and is also listed as sponsor of the project. Starting with version 17 the default distribution is based on Quarkus instead of WildFly/JBoss. The project maintains several means of community contributions as listed on the community section of the project website. It uses Github issues to track development. It offers a REST API for administration and there's a separately maintained 3rd party python module as well as ansible support for it. Both of these are downstream of Keycloak itself and may thus not always be feature complete and suffer latency with respect to getting adjusted to upstream changes. It offers support for commonly used SSO protocols and is \"reasonably\" fast in adopting to protocol standard changes and extensions. This has been observed in the case of logout support (backend and frontend variants) in OIDC. It offers a concept of \"Identity Brokering\", where Keycloak is not just IdP but also \"client\" to other IdPs. This allows daisy chaining of identity federation. In this configuration it can work as a point of protocol transition between different supported SSO protocols (SAML, OAuth 2.0, etc.). Beyond this capability of using other IdPs as identity sources, it also supports using classic LDAP based IAM services as backend (OpenLDAP and Active Directory, e.g.). Keycloak's implementation makes some design decisions, that are specific to it and have consequences for clients of the service. E.g. Keycloak has a concept of management \"Realms\", which have their own specific set of HTTP API entrypoints, both for administration as well as for IdP requests. Commonly Keycloak realms can be used to map them 1:1 to user domains, but since Keycloak supports configuring multiple backend IdPs in a realm to be used for \"Identity Brokering\", there is always the possibility to create a kind of \"proxy\" realm to provide a single standard set of HTTP API endpoints for SSO clients (service providers) to avoid the need to frequently extend/reduce client service configuration whenever a new IdP federation needs to be added to Keycloak to onboard a new customer. This is relevant for services like OpenStack Keystone, which currently cannot be easily reconfigured for new SSO endpoints without restarting the service, making the service unavailable for a short span of time and increasing risk connected with service restarts. Since version 17, Keycloak claims that it's capability for \"cloud native\" deployments on Kubernetes has improved. Keycloak is offering a documented REST API for all aspects of its administration interface. For storage of Keycloak configuration and local user metadata (e.g. from which external IdP a user account originally came from) Keycloak supports several SQL backends through JDBC. Thus it can be hooked up to a Postgres Database or to a MariaDB/Galera cluster e.g.. As of April 11, 2023, Keycloak joined the CNCF as an incubating project. Zitadel​ Zitadel is a newer implementation of an SSO IdP. It is implemented in Go and under active development and maintained by ZITADEL. The project is open for community contributions to all parts of the eco system. Feature requests and bugs being tracked on Github for development. Community questions can be asked in the public chat or via Github Discussions. ZITADEL offers support for the commonly used authentication and authorization protocols such as OIDC, OAuth2, SAML2. It is a compliant and certified OpenID Connect provider with support for various Grant Types for both human users and machine users. Compared to Keycloak SPIs, ZITADEL offers Actions to customize and integrate (eg, calling external APIs, Webhooks, customizing pre-built workflows, customizing tokens) Actions are executed at runtime and can be maintained independently of platform. Identity brokering (OIDC, SAML, JWT) can be configured system-wide or for each organization with templates. Users will be created just in time for audit purposes and linked to the external identity provider. Users can have multiple identity providers linked to their profile. It came to attention of the SCS project because it offers a fresh take of an organization focussed data model, which has the potential to simplify IdP federation to SCS customer domains in the following areas: For client services (single set of HTTP API endpoints). For SCS operators for provisioning customer organizations and robust configuraton by using templated client, role and mapping configuration. For SCS customers for a robust user experience for self servicing. The concept for Delegated Access Management reduces the management overhead compared to isolated realms. Projects (Applications + Roles) can be maintained by one organization and delegated to be used by other Organizations. Managers that receive granted Projects can assign users permissions to use the project. Zitadel is offering REST APIs for multiple areas of use and configuration. It recently also added support for the Device Authorization Grant, which, at time of writing, is a feauture that is relevant for SCS to be able use OpenStack CLI and APIs with federated identities (Device Authorization Grant). Support for consumption of LDAP backends is available since Zitadel v2.23.0 (see this guide). ZITADEL supported backend databases are CockroachDB and PostgreSQL. For production setups it is recommended to use Kubernetes (or similar like Knative) and CockroachDB. At time of writing a PoC \"spike\" is done to assess and verify the hopes connected with Zitadel in the context of the SCS testbed. Currently Zitadel is lacking the possibility to easily add custom claims. It supports urn:zitadel:iam:user:metadata, but that is more suitable towards Kubernetes and cannot be parsed with the OpenStack mapping mechanism. There is work going on which may be suitable to resolve this issue. An approach based on Zitadel actions is also currently evaluated. OpenStack currently makes use of custom claims to pass openstack-default-project from the IdP to OpenStack. Combined with federation to external customer managed IdPs this should allow customers to manage settings like these in their own IAM.","s":"Options considered","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#options-considered","p":3243},{"i":3253,"t":"How would we implement testbed deployment support for Zitadel? e.g. wsgi-keystone.conf would need to look different. One template covering both options? e.g. steps like openstack federation protocol create would probably be different. Should we support both as options? What's the benefit? How would we allow SCS operators to choose? Do we need some kind of SWOT analysis to come to a decision?","s":"Open questions","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#open-questions","p":3243},{"i":3255,"t":"SCS wants to make use of an IdP as part of the reference implementation. To move forward with topics of configuration and mapping of roles in a OAuth2 federation scenario as well as questions of token lifecycles etc. across the federation stack it makes sense to focus on one IdP implementation at a given time. Both considered options seem to be potentially viable, but ultimately, a decision should be made, even if there are no strict/strong reasons for dismissing either option in particular. The project's current choice is Keycloak for the following reasons: Keycloak currently supports the OAuth 2.0 grants that SCS wants to make use of (e.g. Device Authorization Grant). It is the implementation for which integration is currently documented in OpenStack and implemented in kolla-ansible. SCS currently deploys Keycloak and the IAM team has most hands on expecience with it, e.g. when it comes to colletaral questions like how to make TLS and signing certificates available to the IdP that shall be used in federation to external domains.","s":"Decision","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#decision","p":3243},{"i":3257,"t":"https://github.com/SovereignCloudStack/standards/tree/main/Drafts/IAM-federation","s":"Related Documents","u":"/standards/scs-0300-v1-requirements-for-sso-identity-federation","h":"#related-documents","p":3243},{"i":3262,"t":"Kubernetes clusters in a productive environment are under the assumption to always perform perfectly without any major interruptions. But due to external or unforeseen influences, clusters can be disrupted in their normal workflow, which could lead to slow responsiveness or even malfunctions. In order to possibly mitigate some problems for the Kubernetes clusters, robustness features should be introduced into the SCS standards. These would harden the cluster infrastructure against several problems, making failures less likely.","s":"Introduction","u":"/standards/scs-0215-v1-robustness-features","h":"#introduction","p":3260},{"i":3264,"t":"The following special terms are used throughout this standard document: Term Abbreviation Meaning Certificate Authority CA Trusted organization that issues digital certificates entities Certificate Signing Request CSR Request in order to apply for a digital identity certificate","s":"Glossary","u":"/standards/scs-0215-v1-robustness-features","h":"#glossary","p":3260},{"i":3266,"t":"A typical productive Kubernetes cluster could be hardened in many different ways, whereas probably many of these actions would overlap and target similar weaknesses of a cluster. For this version of the standard, the following points should be addressed: Kube-API rate limiting etcd compaction/defragmentation etcd backup Certificate Authority (CA) expiration avoidance These robustness features should mainly increase the up-time of the Kubernetes cluster by avoiding downtimes either because of internal problems or external threads like \"Denial of Service\" attacks. Additionally, the etcd database should be strengthened with these features in order to provide a secure and robust backend for the Kubernetes cluster.","s":"Motivation","u":"/standards/scs-0215-v1-robustness-features","h":"#motivation","p":3260},{"i":3268,"t":"In order to provide a conclusive standard, some design considerations need to be set beforehand:","s":"Design Considerations","u":"/standards/scs-0215-v1-robustness-features","h":"#design-considerations","p":3260},{"i":3270,"t":"Rate limiting is the practice of preventing too many requests to the same server in some time frame. This can help prevent service interruptions due to congestion and therefore slow responsiveness or even service shutdown. Kubernetes suggests multiple ways to integrate such a Ratelimit for its API server, a few of which will be mentioned here. In order to provide a useful Ratelimit for the Kubernetes cluster, combination of these methods should be considered. API server flags​ The Kubernetes API server has some flags available to limit the amount of incoming requests that will be accepted by the server, which should prevent crashing of the API server. This nevertheless shouldn't be the only measure to introduce a rate limit, since important requests could get blocked during high traffic periods (at least according to the official documentation). The following controls are available to tune the server: max-requests-inflight max-mutating-requests-inflight min-request-timeout More details can be found in the following documents: Flow Control Ratelimit Admission Controller​ From version 1.13 onwards, Kubernetes includes a EventRateLimit Admission Controller, which aims to mitigate Ratelimit problems associated with the API server by providing limits for requests every second either to specific resources or even the whole API server. If requests are denied due to this Admission Controller, they're either cached or denied completely and need to be retried; this also depends on the EventRateLimit configuration. More details can be found in the following documents: Rancher rate limiting EventRateLimit It is important to note, that this only helps the API server against event overloads and not necessarily the network in front of it, which could still be overwhelmed. Flow control​ Flow control for the Kubernetes API server can be provided by the API priority and fairness feature, which classifies and isolates requests in a fine-grained way in order to prevent an overload of the API server. The package introduces queues in order to not deny requests and dequeue them through Fair Queueing techniques. Overall, the Flow control package introduces many different features like request queues, rule-based flow control, different priority levels and rate limit maximums. The concept documentation offers a more in-depth explanation of the feature: Flow Control","s":"Kube-API rate limiting","u":"/standards/scs-0215-v1-robustness-features","h":"#kube-api-rate-limiting","p":3260},{"i":3272,"t":"etcd is a strongly consistent, distributed key-value store that provides a reliable way to store data that needs to be accessed by a distributed system or cluster of machines. For these reasons, etcd was chosen as the default database for Kubernetes. In order to remain reliable, an etcd cluster needs periodic maintenance. This is necessary to maintain the etcd keyspace; failure to do so could lead to a cluster-wide alarm, which would put the cluster into a limited-operation mode. To mitigate this scenario, the etcd keyspace can be compacted. Additionally, an etcd cluster can be defragmented, which gives back disk space to the underlying file system and can help bring the cluster back into an operable state, if it ran out of space earlier. etcd keyspace maintenance can be achieved by providing the necessary flags/parameters to etcd, either via the KubeadmControlPlane or in the configuration file of the etcd cluster, if it is managed independent of the Kubernetes cluster. Possible flags, that can be set for this feature, are: auto-compaction-mode auto-compaction-retention More information about compaction can be found in the respective etcd documentation etcd maintenance","s":"etcd maintenance","u":"/standards/scs-0215-v1-robustness-features","h":"#etcd-maintenance","p":3260},{"i":3274,"t":"An etcd cluster should be regularly backed up in order to be able to restore the cluster to a known good state at an earlier space in time if a failure or incorrect state happens. The cluster should be backed up multiple times in order to have different possible states to go back to. This is especially useful, if data in the newer backups was already corrupted in some way or important data was deleted in them. For this reason, a backup strategy needs to be developed with a decreasing number of backups in an increasing period of time, meaning that the previous year should only have 1 backup, but the current week should have multiple. Information about the backup process can be found in the etcd documentation: Upgrade etcd","s":"etcd backup","u":"/standards/scs-0215-v1-robustness-features","h":"#etcd-backup","p":3260},{"i":3276,"t":"In order to secure the communication of a Kubernetes cluster, (TLS) certificates signed by a controlled Certificate Authority (CA) can be used. Normally, these certificates expire after a set period of time. In order to avoid expiration and failure of a cluster, these certificates need to be rotated regularly and at best automatically. Certificates can either be rotated manually (a reference for manually working with certificates can be found here) or automatically, which requires other things to care about in a deployment. Some tools or clusters provide possibilities to rotate certificates manually. For example, kubeadm and k3s provides the following commands # kubeadm kubeadm certs renew all # k3s k3s certificate rotate A CA might also expire. Unfortunately, not all Kubernetes tools have functionality to renew these certificates. Instead, documentation is provided to manually rotating a CA ([Manual rotation of ca certificate]). Automatic certificate rotation​ kubelet can be configured to obtain properly signed certificates from the certificates.k8s.io API of Kubernetes. To do this, set serverTLSBootstrap: true in the configuration file of kubelet, which enables both the certificate request during bootstrapping and the rotation mechanism. Setting rotateCertificates: true only enables the certificate rotation [Kubeadm certs]. --rotate-certificates or --rotate-server-certificates shouldn't be used as command line arguments to set these flags, since both parameters are deprecated according to [Certificate rotation]. It is also important to note that some Kubernetes clusters or admin tools provide additional ways to rotate certificates. For example, kubeadm automatically rotates certificates, if the cluster is updated with the tool (see [Automatic Certificate renewal]). This would also mean, that at least kubeadm-based clusters can be assumed to rotate their certificates regularly, since they would probably be updated within the time period described in the standard SCS-0210-v2. If an automatic certificate rotation happens, these certificates need to be approved either manually or by a third party controller like the kubelet csr approver, which can be deployed on a Kubernetes cluster to automate this process. A manual approval of these CSRs could be done with the commands kubectl get csr kubectl certificate approve in order to complete a certificate rotation. But it should be noted, that this is also most likely dependent on the Kubernetes cluster solution in use. kubectl get csr allows to check, if a CSR needs to be approved; a Pending CSR would need to be approved. NAME AGE SIGNERNAME REQUESTOR CONDITION csr-9wvgt 112s kubernetes.io/kubelet-serving system:node:worker-1 Pending Further information and examples can be found in the Kubernetes documentation: Kubeadm certs Kubelete TLS bootstrapping","s":"Certificate rotation","u":"/standards/scs-0215-v1-robustness-features","h":"#certificate-rotation","p":3260},{"i":3278,"t":"Robustness features combine multiple aspects of increasing the security, hardness and longevity of a Kubernetes cluster. The decisions will be separated into their respective areas.","s":"Decision","u":"/standards/scs-0215-v1-robustness-features","h":"#decision","p":3260},{"i":3280,"t":"The number of requests send to the kube-api or Kubernetes API server MUST be limited in order to protect the server against outages, deceleration or malfunctions due to an overload of requests. In order to do so, at least the following parameters MUST be set on a Kubernetes cluster: max-requests-inflight max-mutating-requests-inflight min-request-timeout Values for these flags/parameters SHOULD be adapted to the needs of the environment and the expected load. A cluster MUST also activate and configure a Ratelimit admission controller. This requires an EventRateLimit resource to be deployed on the Kubernetes cluster. The following settings are RECOMMENDED for a cluster-wide deployment, but more fine-grained rate limiting can also be applied, if this is necessary. kind: Configuration apiVersion: eventratelimit.admission.k8s.io/v1alpha1 limits: - burst: 20000 qps: 5000 type: Server It is also RECOMMENDED to activate the Kubernetes API priority and fairness feature, which also uses the aforementioned cluster parameters to better queue, schedule and prioritize incoming requests.","s":"Kube-API rate limiting","u":"/standards/scs-0215-v1-robustness-features","h":"#kube-api-rate-limiting-1","p":3260},{"i":3282,"t":"etcd MUST be cleaned up regularly, so that it functions correctly and doesn't take up too much space, which happens because of its increase of the keyspace. To compact the etcd keyspace, the following flags/parameters MUST be set for etcd: auto-compaction-mode = periodic auto-compaction-retention = 8h","s":"etcd compaction","u":"/standards/scs-0215-v1-robustness-features","h":"#etcd-compaction","p":3260},{"i":3284,"t":"An etcd cluster MUST be backed up regularly. It is RECOMMENDED to adapt a strategy of decreasing backups over longer time periods, e.g. keeping snapshots every 10 minutes for the last 120 minutes, then one hourly for 1 day, then one daily for 2 weeks, then one weekly for 3 months, then one monthly for 2 years, and after that a yearly backup. At the very least, a backup MUST be done once a week. These numbers can be adapted to the security setup and concerns like storage or network usage. It is also RECOMMENDED to encrypt the backups in order to secure them further. How this is done is up to the operator.","s":"etcd backup","u":"/standards/scs-0215-v1-robustness-features","h":"#etcd-backup-1","p":3260},{"i":3286,"t":"It should be avoided, that certificates expire either on the whole cluster or for single components. To avoid this scenario, certificates MUST be rotated regularly; in the case of SCS, we REQUIRE at least a yearly certificate rotation. It is also RECOMMENDED to renew the CA regularly to avoid an expiration of the CA. This standard doesn't set an exact timeline for a renewal, since it is dependent on lifetime and therefore expiration date of the CA in question.","s":"Certificate rotation","u":"/standards/scs-0215-v1-robustness-features","h":"#certificate-rotation-1","p":3260},{"i":3288,"t":"Flow Control Rate limiting EventRateLimit etcd maintenance Upgrade etcd Kubeadm certs Kubelet TLS bootstrapping Certificate rotation Manual rotation of ca certificate Automatic Certificate renewal","s":"Related Documents","u":"/standards/scs-0215-v1-robustness-features","h":"#related-documents","p":3260},{"i":3290,"t":"Conformance Tests, OPTIONAL","s":"Conformance Tests","u":"/standards/scs-0215-v1-robustness-features","h":"#conformance-tests","p":3260},{"i":3293,"t":"A container registry is an infrastructure service to enable storing and accessing container images. Images can be pushed to the registry by e.g. Continuous integration pipelines and be pulled from by runtime environments like Kubernetes clusters. In the standard document [\"Requirements for container registries\"], requirements for a registry in the context of SCS were introduced. These are based on the principals, that a usable project should be open source, active and feature-rich, especially with regard to security.","s":"Introduction","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#introduction","p":3291},{"i":3295,"t":"Cloud Service Provider (abbr. CSP) Entity that provides scalable computing resources Cloud Native Computing Foundation (abbr. CNCF) Organization that hosts and develops open source projects for cloud native computing","s":"Terminology","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#terminology","p":3291},{"i":3297,"t":"In order to provide a usable, complete experience for the SCS reference implementation, it must be decided on a registry in accordance with requirements set by the [\"Requirements for container registries\"] standard as well as other dependencies set by the SCS project, including the OSS requirements. This document should finally lead to a decision about the container registry used as a reference implementation of the SCS container registry.","s":"Motivation","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#motivation","p":3291},{"i":3299,"t":"A few open source projects were evaluated for this document in order to find suitable candidates for the SCS reference implementation. These projects can be found in the following list of evaluated projects with their classified categories and comments. An initial assessment was done with the checks for OSS healthiness and a general overview of the features described in [\"Requirements for container registries\"], which enables classifying the projects into one of three categories as follows: ✔️ The project passed all OSS health checks and will be considered further as a valid candidate. ❔ The project passed almost all OSS health checks. There is place for improvement, but the missing points are not crucial from the OSS health check perspective. The project will be considered further as a valid candidate. ❌ The project does not pass the OSS health checks. Some OSS health check showstoppers have been found (e.g. open core software, not actively maintained). The project is filtered at this stage and won't be considered further. The following list contains these projects with a small assessment listed below them: ✔️ Harbor Harbor project meets all \"four opens\" Source code is open and available under the Apache 2 license Community is open, structured and well organized via workgroups and various communications channels e.g. Slack, mailing lists, etc. (#harbor Slack channel contains 3k+ members) The development process is open via GitHub issues and well described in the contributing document The design process is open via GitHub issues. Proposals are public. The decision process is well described as well. The project's roadmap is available in the roadmap document Maturity is on the CNCF graduation level. CNCF graduated projects are considered to be stable, widely adopted and production-ready Security The security disclosure and response policy is well described in the project's security document The code is reviewed within a standard PR process Activity 250+ contributors, 4k+ forks, 13k+ GitHub stars The project has been adopted by many companies that run Harbor in their production environments The project collaborates with other communities and projects (see Partners of Harbor section of the project's website) The project is visible and actively contributes to various conferences, e.g. FOSDEM 22, KubeCon Europe, etc. Lock-in risk assessment The project's maintainers document shows that there are a sufficient number of core maintainers/contributors that differ over various companies, we therefore deem the lock-in risk arising from a single point of failure to be low ✔️ Dragonfly Dragonfly project meets all \"four opens\" Source code is open and available under the Apache 2 license Community is open organized via multiple channels e.g. Slack, mailing lists, etc. (#dragonfly Slack channel contains ~50 members) The development process is open via GitHub issues and well described in the contributing document The design process is open via GitHub issues. The project's roadmap is available in the project's webpage Maturity is on the CNCF incubating level CNCF incubating project is considered stable and used in production by users with the healthy pool of contributors Security The security disclosure is handled via a dedicated email address The code is reviewed within a standard PR process Activity 30+ contributors, 100+ forks, 1k+ GitHub stars The project has been adopted by many companies that run Harbor in their production environments The project is visible and actively contributes to various conferences, e.g. KubeCon North America, KubeCon Europe, etc. Lock-in risk assessment The list of the project's maintainers includes contributors from various companies and the companies contributing dashboard shows that ~10 companies are actively contributing to a repository group ❔ Project Quay Project Quay meets all \"four opens\" Source code is open and available under the Apache 2 license Community is open organized via mailing list and IRC Development process is open via JBoss JIRA issues and well described in the governance document Design process is open via JBoss JIRA issues. The project's roadmap is available on the project's webpage Maturity Project Quay is an open-source project that started ~9 years ago. It powers Red Hat enterprise products Red Hat Quay and Quay.io, which are used in a productive way by many. Therefore, the project's maturity is at the good level Security The security disclosure is handled via a dedicated email address The code is reviewed within a standard PR process Activity 50+ contributors, 200+ forks, 2k+ GitHub stars The project has been used by many companies that run Quay in their production environments Lock-in risk assessment The project's owners/maintainers list is not publicly available and is stored in the downstream repository. Therefore, it is hard to distinguish the risk of project failure caused by low diversity across the companies. This should be improved. ❌ Keppel The project seems to be not widely used in a productive way and also the activity around is currently not on a good level (5+ contributors). The development process as well as the design process seem to be open, but neither of them are documented yet. ❌ Nexus Nexus is an open core software that offers paid pro version with advanced features ❌ JFrog JFrog Artifactory is shipped as an open core software with limited features. The software is primarily offered as a paid pro version ❌ Kraken It seems that the project is not actively maintained as is discussed in the related project's issue ❌ Portus It seems that the project is not actively maintained as is discussed in the related project's issue","s":"Evaluated projects","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#evaluated-projects","p":3291},{"i":3301,"t":"In the previous section, a wide range of open-source container registry projects (Quay, Harbor, Dragonfly, Keppel, Portus, Kraken, etc.) has been carefully evaluated based on the two main factors: the open-source health and range of supported features. The open-source software health is crucial and container registry implementation should pass it. It evaluates several important metrics of an open source software like whether the code/community/development/design is fully open or whether the project's maturity, security, and activity are on the desired level. This check also evaluates the lock-in risk due to possible single points of failure or internal project conflicts and several other aspects. Overall, three projects passed the OSS health checks: Harbor Project Quay Dragonfly The above projects were then evaluated from the \"supported features\" perspective. The document [\"Requirements for container registries\"] provides a \"Required and desirable features check\", which provides desired feature sets for open-source container registry implementations according to SCS requirements (and nice-to-haves). The list of required features is quite long and contains features that are primarily focused on security (authentication, vulnerability scanning, content trust, and validation, etc.), scalability (HA mode, registry replication, p2p integration, etc.) and visibility (monitoring). These requirements should ensure that the selected container registry implementation could be offered by CSPs as a secure and enterprise-ready solution. The following section compares the selected projects Dragonfly, Quay, and Harbor. Dragonfly is a healthy open-source project with a growing community and CNCF incubating maturity level. It is considered stable, and widely used by many companies in their production environments. We currently see that it is not as feature-rich as Harbor or Quay, hence it is not considered the best choice here. It seems, that its main aim (currently) is to offer (an efficient, stable, and secure) container distribution solution based on p2p technology. This improves download efficiency and saves bandwidth across CSPs. It also offers integration possibilities that allow one to use it as a p2p distribution network via a \"preheat\" API. This integration was implemented in the Harbor project via Dragonfly \"preheat\" adapter, and both parties may benefit from the integration. Harbor profits from Dragonfly's p2p distribution capabilities and on the other hand the Dragonfly project profits from Harbor's feature-rich container registry \"frontend\". Quay is an open-source project maintained by Red Hat. Its OSS health is on a good level, the surrounding community is growing, and we consider it to be quite mature as it powers enterprise solutions like Red Hat Quay and Quay.io. Besides this, there is still a place for OSS health improvement. It is hard to distinguish the risk of project failure caused by low diversity across the companies because the project's owners/maintainers list is not publicly available and is stored in the Red Hat private repository. Its feature set is impressive and this project fulfills all must-haves defined in this document. Quay gives you security over your repositories with image vulnerability scanning (Clair integration), content validation (Cosign integration), and access controls. Harbor stands out here as it allows users to use also project Trivy for vulnerability scanning. Project Quay also provides a scalable open-source platform to host container images across any size organization. One drawback in comparison to Harbor is that the proxy cache feature is still marked as a Technology Preview, hence this feature may not be completely production-ready yet. On the other hand, the project Quay supports building Dockerfiles using a set of workers on e.g. Kubernetes. Build triggers, such as GitHub webhooks can be configured to automatically build new versions of repositories when new code is committed. This feature is not supported by the Harbor project. Harbor is an outstanding open-source, community-led project with fully open and well-documented processes. Its large and thriving community powers the fast-growing feature set and attracts more and more developers and companies to active contributions. Harbor's CNCF graduation in 2020 made it one of the best choices for enterprise customers that want to operate container registries securely and in a large scale. Its community size, landscape, and CNCF graduation make a significant difference in comparison to Quay's open-source health capabilities. The list of supported features is also impressive. This project fulfills all must-haves defined in this document and overcome project Quay with a production-ready proxy cache feature and more options that the user may use in case of image vulnerability scanning. In addition, Harbor profits from p2p distribution capabilities via integration of p2p solutions like Kraken and Dragonfly. It is worth mentioning that Harbor, by design, operates on a single storage backend (e.g. S3). It means that the storage of container images is shared even when the Harbor instance serves multiple tenants. The same approach is used in Quay and Dragonfly projects, but e.g. Keppel uses multi-tenant-aware storage drivers instead so that each customer gets their own separate storage backend. CSP that considers offering container registry \"as a service\" solution based on Harbor should be aware of this shared storage backend architecture. In the following table, the feature sets of the evaluated projects that passed the OSS health state are listed and matched against. This enables a better understanding of the decision-making for this document. Features Harbor Quay Dragonfly Audit Logs ✓ ✓ ✗ Authentication of system identities ✓ Robot Accounts ✓ Robot Accounts ✗ Authentication of users ✓ Local database, LDAP, OIDC, UAA ✓ Local database, LDAP, Keystone, JWT ✓ Local database Authorization ✓ ✓ ✓ Automation ✓ Webhooks (HTTP, Slack) ✓ Webhooks (HTTP, Slack, E-mail ...), building images ✗ Vulnerability scanning ✓ Trivy, Clair ✓ Clair ✗ Content Trust and Validation ✓ Cosign ✓ Cosign ✗ Multi-tenancy ✓ (not on the storage level) ✓ (not on the storage level) ✓ (not on the storage level) Backup and restore ✓ ✓ ✗ Monitoring ✓ Prometheus metrics, Tracing ✓ Prometheus metrics, Tracing (only for Clair) ✓ Prometheus metrics, Tracing HA mode ✓ ✓ ✗ Registry replication ✓ ✓ ✓ Proxy cache ✓ ✓ Feature is in the technology preview stage (non production ready) ✗ Quota management ✓ Based on storage consumption ✓ Based on storage consumption ✗ Garbage collection ✓ Non-blocking ✓ Non-blocking ✗ Retention policy ✓ Multiple tag retention rules ✓ Only tag expiration rules ✗ Additional supported artifacts ✗ (only OCI artifacts) ✗ (only OCI artifacts) ✓ Maven, YUM Integration possibilities ✓ Dragonfly (P2P), Kraken (P2P) ✗ ✓ Harbor, Nydus, eStargz Deployment capabilities ✓ Docker-compose, Helm chart, Operator ✓ Docker-compose, Operator ✓ Docker-compose, Helm chart Administration capabilities ✓ Terraform, CRDs, Client libraries ✓ Ansible, Client libraries ✓ Client libraries Notes: Automation: Harbor should support webhooks following CloudEvents spec in the next release Content Trust and Validation: Harbor announced the deprecation of Notary integration, hence it is not mentioned in the table Multi-tenancy: Harbor, Quay, as well as Dragonfly, operates on a single storage backend (e.g. S3), i.e. the storage of container images is shared between tenants Additional supported artifacts: Harbor announced the deprecation of Chartmuseum integration, hence it is not mentioned in the table","s":"Deeper look into selected projects","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#deeper-look-into-selected-projects","p":3291},{"i":3303,"t":"Based on the requirements laid out in [\"Requirements for container registries\"], the OSS health check and the possible software solutions presented in this document, it was decided to use the Harbor project as the container registry for the SCS reference implementation.","s":"Decision","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#decision","p":3291},{"i":3305,"t":"\"Requirements for container registries\" harbor dragonfly projectquay","s":"Related Documents","u":"/standards/scs-0218-v1-container-registry-for-scs-standard-implementation","h":"#related-documents","p":3291},{"i":3308,"t":"Creating and maintaining IT infrastructure is a complex task. Any kind of consumer (e.g. operators, cutsomers) can be supported by presenting the status of all possible parts of the serving infrastructure. Whether a service is not reachable or the used hardware is having an outage we want the consumers to be easily informed by using a \"Status Page\" application. The need for a \"Status Page\" came up early in the SCS project and the requirements a \"Status Page\" application has to fulfill were defined and written down on 2022-06-02 as a MVP-0 epic. The upcoming research on existing solutions came to the conclusion that we want to create a new \"Status Page\" application.","s":"Introduction","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#introduction","p":3306},{"i":3310,"t":"Since we want to use as much as possible from existing projects and contribute to upstream projects to support the community with our efforts, it was a hard decision to create a new \"Status Page\" application. Before the decision was made some existing and known applications were tested and analyzed if they would fit to our use case. An overview of this comparison can be found below in this document While this is not a complete list of all existing applications it did capture the most promising ones from the awesome-status-page list in order to have base to decide upon. Work on an existing project only makes sense if the project is healthy OR can be brought into a healthy state. If upstream does not accept patches a fork is needed. The fork however only makes sense if the underlying technology is worth to be maintained. The possible candidates did not fulfill these conditions - in the cases where contribution seemed possible the candidates looked abandoned and long existing CVEs weren't worked on.","s":"Existing Applications","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#existing-applications","p":3306},{"i":3312,"t":"Based on the results the decision was made, that the effort is likely to be the same if we pick up an existing project and try to get it in shape for our use case. It was not 100% clear if this would even be possible or if we still would have to maintain our own additional patches. So there will be a reference implementation that will match the requirements we have. In addition there will be an architecture design documentation. So if the reference implementation may not fit to you, it will be possible to create your own application.","s":"Decision","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#decision","p":3306},{"i":3314,"t":"The status page application should be simplistic in software design and should not depend on a large variety of services simplistic, yet existing user management for write access (oauth? OIDC?) Simple RBAC (role based access control) is nice to have support that components are only visible to a subset of users implies that there is a role that is read-only On-Prem use case might be handled by having an authenticating reverse proxy in front The status page applicaton should allow for simple and easy theming Page = (Possibly simple) Web-UI As a CSP, I want to have a status page that allows to define locations and similar grouping (AZs, ...) define components globally or per location _to ease maintenance I want to define per component where it belongs so that I only have to define a component once, but have it visible in several locations _ status per component should be allowed to be toggleable per location or overall * a component should allow for several statuses, that are defined by me Status, Status Items should be easy to extract REST(less)-API to interact with _API should be versioned _ this allows for embedding status information in other applications, such as cloud dashboards _this also allows for submitting items from other tooling _ incoming webhooks (https POST) should be supported (e.g. for air-gapped setups) – i.e. submitting a health beacon every x seconds _web-UI wanted for posting updates as well _ Token based Auth Configuration should be manageable with YAML files (imho this annoys me using Uptime Kuma) As a consumer of the status page, I'd like to subscribe to events on the status page via e-mail for everything for specific components As a consumer of the status page, I'd like to subscribe to an RSS or atom feed Allow for the ability to trigger webhooks upon certain events (to submit info to other systems via webhooks, e.g. chat/messenger) As a CSP Operator, I want to be able to flag a component with a new status quick and easy to minimize the probability of making errors, updating the status of a component should not be hard brainwork updates can be both machine generated status changes (triggered e.g. by health monitoring) as well as updates from human operators updating a status should allow the CSP Operator to do that in a fashion that either pushes infos to the subscribers or just updates the status on the status page updating the status can either be toggling the status of the component or can be accompanied by additional textual information. When updating a status with textual information the status page application should make it easy for me as the CSP Operator to do in a way that if different people submit infos over time they are presented in a similar way (eg. the status page application should guide so that the resulting infos are presented in a identical way. Example: when updating infos of an incident over time the timeline should automatically be sorted by the status page application so that it does not depend on the Operator whether the newest info is on top or at the bottom. This is typical thing that varies if several people update items Allow for templates for certain types of incidents User-specific monitoring (how are MY instances, load-balancers, ... doing?) is OUT OF SCOPE for the status page. But having it would be useful and if we have something like this, link it from the status page (and a link to horizon might be the default) Sidenote: External hosting is desired to avoid status page going down with infra With those requirements in mind the projects that initially were found, were evaluated.","s":"Status Page Requirements","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#status-page-requirements","p":3306},{"i":3316,"t":"CachetHQ ClearStatus ciao cState Gatus Issue Status statusfy CSP VIEW small dependency tree ❌ Composer ✅ ❌ ruby gems ✅ ⁇ helm chart ❌ npm/github/zapier ❌ npm dependencies very huge easy themable ✅ ❌ ❌ ❌ ❌ ❌ ✅ grouping (by location...) ✅ ❌ ❌ ❌ ✅ ⁇ ✅ components definition ... ... local or global ✅ ❌ ❌ ✅ ⁇ ✅ ❌ ... easy flagging with new status ✅ ✅ ❌ ✅ ⁇ ✅ ❌ ... push notification on update ✅ ❌ ✅ ❌ ✅ ⁇ ✅ ... updates with additional information ✅ ✅ ❌ ✅ ⁇ ⁇ ⁇ API Support ... ✅ ✅ ✅ ❌ read only ❌ ✅ GitHub API ❌ ... versioned ✅ ❌ ❌ ❌ ❌ ✅ ⁇ ... web ui for posting updates ✅ ✅ ❌ ✅ ❌ ❌ ❌ ... token based auth ✅ ✅ Auth managed by git provider ❌ only basic auth ❌ ❌ BUT OIDC! ✅ ❌ manageable configuration ❌ config depends on web server and initial install relies on env variables ❌ based on hugo CMS ❌ config by env variables ❌ based on hugo CMS ✅ ❌ ❌ no real config needed templating support ✅ twig ❌ Hugo itself uses GO template libraries ❌ ❌ ❌ ❌ ❌ CUSTOMER VIEW subscription support ... ✅ ❌ only by git provider ✅ ❌ ❌ ✅ ✅ ... send by eMail ✅ ❌ ✅ ❌ ✅ ✅ ❌ watchdog for status page support ⁇ ⁇ ✅ ❌ ✅ ⁇ ❌ trigger webhook support ❌ needs cachet-monitor ⁇ ✅ ⁇ ✅ ⁇ ❌ additional infos - basically a theme for hugo cms, depends on netlify cms - basically a theme for hugo cms, depends on netlify cms - It's highly optimized for github pages SPA created with netlify hidden components ✅ ❌ ❌ ❌ ❌ ❌ ❌ user management ✅ ❌ ❌ ❌ ✅ by OIDC ⁇ through github? ❌ different output format on notification ❌ ❌ ✅ ✅ ✅ ❌ ✅ external hosting ✅ ✅ ✅ ✅ ✅ ❌ looks like you are limited to github ✅ project healthy ❌ last commit 17 months ❌ last commit 3 years ❌ last commit 5 months ✅ last commit 2 months ✅ recent activities ✅ recent activities ❌ archived and abondend by the owner documentation ✅ API ❌ User Documentation ❌ ❌ ❌ ✅ ⁇u ❌ not reachable anymore git based ❌ ✅ ❌ ✅ ❌ ✅ ⁇ a netlify based installation is able to communicate with github project page project page project page project page project page project page project page project page","s":"Comparison matrix","u":"/standards/scs-0400-v1-status-page-create-decision","h":"#comparison-matrix","p":3306},{"i":3319,"t":"When CSPs try to enroll a new customer they encounter themselves in a situation where they have to choose names for the openstack domain, project and user.","s":"Introduction","u":"/standards/scs-0301-v1-naming-conventions","h":"#introduction","p":3317},{"i":3321,"t":"Create a naming convention to use during the provisioning of the users and groups through an openstack domain.","s":"Motivation","u":"/standards/scs-0301-v1-naming-conventions","h":"#motivation","p":3317},{"i":3323,"t":"OPTIONAL","s":"Design Considerations","u":"/standards/scs-0301-v1-naming-conventions","h":"#design-considerations","p":3317},{"i":3325,"t":"PS approach to naming​ For naming the customers the suggestion from PS is the following: A prefix will be use to differenciate domain, project and user in the openstack environment. The project name is also added as a sufix. So the onboaring tool will create the following structure for a new customer onboarded in the system. domain: d project: p- user: u- For the customer also a domain admin group and a project admin group are created. Please note that, at the time of writing, PCO is not making any use of OpenStack domains to isolate customers. So, for the scope of this document, the term \"domain admin\" is used in a conceptual way rather than referring to the specific OpenStack implementation. For the scope of this document \"domain admins\" can do things like creating projects, creating users and granting users access to some projects (within the domain of course). \"Users\" can create and view resources within the projects that they have been granted access to by the \"domain admin\". These groups use the prefix \"gd\" for domain group and \"gp\" for group project and are build like the following: domain admin group: gd-member project admin group: gp--member For the creation of a domain a new domain admin group is created. openstack domain create d000001 openstack group create gd000001-member When a project is created a new admin group for that project is created. openstack project create p000001-scs_dev_project openstack group create p000001-scs_dev_project-member After the creation of a project it is necessary to assign roles to the new groups. openstack role add --group gd000001-member --project p000001-scs_dev_project $role openstack role add --group gp000001-scs_dev_project-member --project p000001-scs_dev_project $role For the creation of regular non admin users, the accounts will be added to the \"domain admin\" group to give them access to all projects within the domain. openstack user created u000001-user1 openstack group add user gd000001-member u000001-user1 In the case of machine accounts, they are only added to the specific \"project admin\" groups. openstack user created u000001-svc_user_project openstack group add user gp000001-scs_dev_project-member u000001-svc_user_project In case of using federation, there are suggestions to the namings within Keycloak. The realms in Keycloak for each customer would be the same as the customer. e.g. The Keycloak realm for \"Customer A\" will be called \"Customer A\". There should be an OIDC client in each customer realm to allow the federation to the Proxy realm. Currently called OSISM on the testbed. On the proxy realm, it's needed to add this new customer realm as an idenity provider. During the creation of the identity provider for \"Customer A\", the field \"Alias\" should be set to . This will make that the users federated from realm \"Customer A\" to the proxy realm to be prefixed to avoid naming colisions, e.g. d${ALIAS}-${CLAIM.preferred_username}. Also, on the identity federation there should be configured to store the from that realm into the users. So it can be send to Keystone mapping to use it as gd-member and gp--member. There is also the necessity of a mapper to send the openstack-default-project. Add the aditional mappings for roles and groups as necessary to get the attributes from the customer realm into the OIDC userinfo that is put into the OIDC to the proxy realm and from there to Keystone. Option 2​ Option 2 description","s":"Options considered","u":"/standards/scs-0301-v1-naming-conventions","h":"#options-considered","p":3317},{"i":3327,"t":"RECOMMENDED","s":"Open questions","u":"/standards/scs-0301-v1-naming-conventions","h":"#open-questions","p":3317},{"i":3329,"t":"Decision","s":"Decision","u":"/standards/scs-0301-v1-naming-conventions","h":"#decision","p":3317},{"i":3331,"t":"Related Documents, OPTIONAL","s":"Related Documents","u":"/standards/scs-0301-v1-naming-conventions","h":"#related-documents","p":3317},{"i":3333,"t":"Conformance Tests, OPTIONAL","s":"Conformance Tests","u":"/standards/scs-0301-v1-naming-conventions","h":"#conformance-tests","p":3317},{"i":3336,"t":"While defining the OpenAPI spec some considerations and decisions are made and should be documented.","s":"Introduction","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#introduction","p":3334},{"i":3338,"t":"The key words \"MUST\", \"MUST NOT\", \"REQUIRED\", \"SHALL\", \"SHALL NOT\", \"SHOULD\", \"SHOULD NOT\", \"RECOMMENDED\", \"MAY\", and \"OPTIONAL\" in this document are to be interpreted as described in RFC 2119. In addition, \"FORBIDDEN\" is to be interpreted equivalent to \"MUST NOT\".","s":"Requirements","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#requirements","p":3334},{"i":3340,"t":"The spec should be as minimal as possible, while being as understandable as possible, so some choices to the design of API objects, requests and responses are made.","s":"Motivation","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#motivation","p":3334},{"i":3343,"t":"Some defined schemas are used as common types. These common definitions help to simplify the actual object definitions by providing meaningful names, and reduce duplication. A change of ID type for example only needs one change in the common definition, and not in any of the object definitions which include an ID. Special mentions: Id​ IDs are used for identification of resources, which can be retrieved by the API. UUIDs are used, to ensure uniqueness. Also, they can be visually recognized as identifier. Incremental​ An Incremental is used in combination with other identifiers to identify a sub resource of any kind. Incrementals themselves are not globally unique, but unique for every sub resource of an unique resource. Generation and order​ Generation and Order are predefined objects which include a Incremental typed field for the common usages of the Incremental value. SeverityValue​ A SeverityValue is an unsiged integer ranging from 0 to 100 inclusively. It MUST be utilized by an Impact when referenced by a requested Component to gauge the severity of the impact on that component. It MUST be added to an Impact when refereced by an Incident, when its created. While being described as an unsiged integer, implementing this value MAY not require it to be an uint data type in any form, because its range even fits in a signed int8 (byte) data type.","s":"Common definitions","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#common-definitions","p":3334},{"i":3345,"t":"All objects which are used as payload, either as request or response, are defined by schemas. This centralizes the maintanence of field names and types, for both requests and responses.","s":"API objects","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#api-objects","p":3334},{"i":3347,"t":"Most fields of objects are not required. This allows usage as request and response payloads. Responses of payload objects, which contain an ID or an Incremental typed field, MUST fill the ID or Incremental field to fully identify the (sub) resource. Requests on a single resource MUST contain the ID in the path parameters. Request on sub resources MUST contain the ID and Incremental typed value as path parameters. The payload SHOULD NOT contain the ID or Incremental typed field. If it contains these fields as payload, they SHALL NOT change them. Requests to updating operations SHOULD contain the minimum of the changed fields, but MAY contain the full object. ID and Incremental typed fields MUST follow the same rules as stated above.","s":"API object fields","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#api-object-fields","p":3334},{"i":3349,"t":"The endpoints are named in plural form, even when handeling single objects, to keep uniform paths.","s":"Endpoint naming","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#endpoint-naming","p":3334},{"i":3351,"t":"The list of phases that an incident can go through has a crucial order. So it MUST be handled as the given list. Delete or update operations are FORBIDDEN. To \"change\" a phase list, a new one must be created. The old one must be kept. For this mechanic the lists are structured in generations. All references to phases MUST include their generation to ensure correct references. To reference a single phase a PhaseReference MUST include a generation and an order field. This MAY be used to reference a single generation too.","s":"Phase list","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#phase-list","p":3334},{"i":3353,"t":"Labels are identifying metadata to components. They do not represent a resource or sub resource of any kind. They are designed as non system critical pieces of information, mainly intended for human consumption. Labels are simple key/value pairs attached to components, categorizing them dynamically.","s":"Labels","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#labels","p":3334},{"i":3355,"t":"An impact defines the relation between an incident and a component. A component can be affected by multiple incidents and an incident can affect multiple components. Each of these impacts can have a different type depending on the incident and component, like for example connectivity or performance issues. To reflect this, each component and incident can have a list of impacts, stating the type of impact and a reference to the incident or component, it refers to. Furthermore, a SeverityValue MUST be supplied to the Impact when referenced by a Component, to gauge the impact's severity on that component.","s":"Impact","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#impact","p":3334},{"i":3357,"t":"A severity contains a name, that MUST be unique and will be used as identifier. The SeverityValue marks the upper boundary of the severity. The severity's value range is calculated by taking the previous severity's (SeverityA) value and adding 1 to obtain the starting point and taking the current severity's (SeverityB) value as the end point. These limits are inclusive. 0, ... , SeverityA.value, SeverityA.value, + 1, ... , SeverityB.value - 1, SeverityB.value, SeverityB.value + 1, ... , 100 |<------------range of severity values for SeverityB------------->| Example: [ { \"displayName\": \"operational\", \"value\": 25 }, { \"displayName\": \"maintenance\", \"value\": 50 }, { \"displayName\": \"limited\", \"value\": 75 }, { \"displayName\": \"broken\", \"value\": 100 } ] This means: operational from 0 to 25 maintenance from 26 to 50 limited from 51 to 75 broken from 76 to 100. A value of 100 is the maximum of the severity value. A severity with the value of 100 MUST always be supplied. This is the highest severity for the system. If no severity with a value of 100 exists, e.g. the highest severity value is set at 90, an Impact with a higher SeverityValue WILL be considered to be an unkown severity.","s":"Severity","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#severity","p":3334},{"i":3359,"t":"Components list their impacts, which they are affected by, as read only. Only an incident creates an impact on a component. Components MUST only list their currently active impacts.","s":"Component impacts","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#component-impacts","p":3334},{"i":3361,"t":"Generally POST requests create new resources. These endpoints do not return the new resource, but a unique identifier to the resource e.g. an UUID. In most cases the new resource won't be used directly after creation. Most often list calls are used. If the new resource is used directly, it can be retrieved by the returned identifier. Payloads to POST requests SHALL NOT include ID or Incremental typed fields, it lies in the responsibility of the API server to assign IDs and Incrementals to objects.","s":"Return of POST requests","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#return-of-post-requests","p":3334},{"i":3363,"t":"Most commonly PATCH requests are used to partially or fully change a resource. These requests do not respond with the changed resource, nor an identifier. Both the old state as well as the new state are known on the client at that point in time and if they need to load the actual recent version from the server, the identifier is already known.","s":"Return of PATCH requestes","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#return-of-patch-requestes","p":3334},{"i":3365,"t":"The PUT requests is most commonly used to update full objects, whereas PATCH is used for partial updates. PATCH is used as the default method for updating resources because it does not require the full object for an update, but does not discourage the use of the complete object.","s":"PATCH vs PUT for updating resources","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#patch-vs-put-for-updating-resources","p":3334},{"i":3367,"t":"The API spec does not include either authentication (AuthN) nor authorization (AuthZ) of any kind. The API server MUST be secured by an reverse/auth proxy.","s":"Authentication and authorization","u":"/standards/scs-0402-v1-status-page-openapi-spec-decision","h":"#authentication-and-authorization","p":3334},{"i":3370,"t":"In the past we noticed missing events in the telemetry stack of OpenStack. This results in situations where the Cloud Service Provider (CSP) may think that a resource is still in use while the owner shut it down, or may not be aware of a resource which has been created. Such inaccurate data is a problem, when it is supposed to be used for billing purposes. This document discusses how such metering data should be stored within the SCS. In partiuclar, it provides rationale for the choice of Gnocchi as time-series database for metering data within SCS.","s":"Introduction","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#introduction","p":3368},{"i":3372,"t":"TSDB, time-series database: Database which is specialised for storing data which is keyed by a timestamp. Popular examples are InfluxDB, Graphite, rrd, and Prometheus. Metering: Collection of usage data of a cloud, for the specific purpose of creating invoices to bill customers for the resources they have allocated. backfilling: The process of adding and modifying data in the past within a time-series database. Metric: A single time-series vector. Typically, a metric represents a single property of a resource, such as CPU usage of an instance. Resource metrics: A group of metrics belonging to a single resource. A compute instance, for instance, may have a metric indicating the number of CPUs allocated, another metric indicating the amount of RAM allocated, etc.","s":"Definitions","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#definitions","p":3368},{"i":3374,"t":"Being able to hold users accountable for the resources they use is a prerequisite for commercially operating a cloud. The SCS project wants to deliver a cloud stack which can be used for that purpose, hence providing reliable metering data is a requirement. As metering data is inherently keyed by time, a time-series database is required. The choice of time-series database is an important one as different databases come with different trade-offs. Not all databases are suitable for the kind of data which is collected in a metering context.","s":"Motivation","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#motivation","p":3368},{"i":3376,"t":"The following requirements for a time-series database exist: MUST support backfilling: As we need to catch up on changes to resources which may have happened during a brief network interruption, we need to be able to modify data after it has been written to the TSDB. MUST be able to handle lots of resources: As billing should happen with a resource-level granularity, we expect a lot of different metrics inside the TSDB. MUST scale to different timescales: We expect to have metrics which change frequently (e.g. object store usage) and metrics which change rarely (e.g. cinder volume sizes). The TSDB must be able to cope with both types of metrics efficiently. SHOULD provide an efficient way to query all currently alive resources. SHOULD allow truncation of storage to remove old data. MUST be available under an appropriate Open Source license, even for productive use cases.","s":"Design Considerations","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#design-considerations","p":3368},{"i":3378,"t":"Using Gnocchi​ Gnocchi is a time-series database which has its origins in the OpenStack ecosystem. It supports all requirements except truncation, which might have to be implemented. Using Prometheus​ Prometheus is a widely used time-series database with its focus on monitoring and incident response. While it is considered efficient for this use-case, it has shortcomings which make it unsuitable for the metering use case: Explicit recommendation against high-cardinality metrics: As we would have to label metrics by resource IDs and project IDs, we have to expect a very high cardinality, also with a significant amount of metric churn. Backfilling, albeit possible, is not well-supported. Using InfluxDB​ InfluxDB is a widely used time-series database with its focus on monitoring. In contrast to Prometheus, it does support backfilling. However, like Prometheus, it seems to run into scalability issues in high-cardinality scenarios. In addition, clustering is only available in commercial licensing options. Creating a custom TSDB implementation​ A custom TSDB implementation is a non-trivial project to pursue.","s":"Options","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#options","p":3368},{"i":3380,"t":"We use Gnocchi. According to research, it mostly fulfills the requirements. While some small development efforts may be needed, to make it fully usable, the amount of work is anticipated much less than making Prometheus or Influx fit the bill (due to backfilling / cardinality scaling constraints), let alone rolling a custom implementation.","s":"Decision","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#decision","p":3368},{"i":3382,"t":"What will be the granularity of the events meta information? If we decide to use resource metadata as a place to store slow-changing information (e.g. instance flavors, volume sizes), we need to know what the granularity of that is.","s":"Open questions","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#open-questions","p":3368},{"i":3384,"t":"SCS-0411-v1","s":"Related Documents","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#related-documents","p":3368},{"i":3386,"t":"None (this is a decision record).","s":"Conformance Tests","u":"/standards/scs-0410-v1-gnocchi-as-metering-database","h":"#conformance-tests","p":3368},{"i":3389,"t":"Cloud Service Providers offer a variety of products to a customer. Those can include compute resources like virtual machines, networking, and identity and access management. As customers of those services build their applications upon those offered services the service provider needs to ensure a certain quality level of their offerings. This is done by observing the infrastructure. Observability systems leverage different types of telemetry data which include: Metrics: Usually time series data about different parameters of a system which can include e.g. CPU usage, number of active requests, health status, etc. Logs: Messages of software events during runtime Traces: A more developer-oriented form of logging to provide insights into an application or to analyze request flows in distributed systems. Based on those data, an alerting system can be used to send out notifications to an Operations Team if a system behaves abnormally. Based on the telemetry data the Operations Team can find the issue, work on it, and mitigate future incidents.","s":"Introduction","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#introduction","p":3387},{"i":3391,"t":"Currently, only the IaaS Layer of the SCS Reference Implementation has an Observability Stack consisting of tools like Prometheus, Grafana, and Alertmanager as well as several Exporters to extract monitoring data from the several OpenStack components and additional software that is involved in the Reference Implementation. As the Kubernetes as a Service Layer becomes more and more important and the work on the Cluster API approach to create customer clusters progresses further, an observability solution for this layer is also needed. CSP should be able to watch over customer clusters and intervene if a cluster gets in a malfunctioning state. For this, a toolset and architecture are needed which is proposed in this ADR.","s":"Motivation","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#motivation","p":3387},{"i":3393,"t":"A survey was conducted to gather the needs and requirements of a CSP when providing Kubernetes as a Service. The feedback of the survey led to the following requirement on a Kubernetes as a Service Observability System: Telemetry Data that MUST be fetched: CPU, RAM, Disk, Network HTTP Connectivity Metrics Control Plane and Pod metrics (States, Ready, etc.) K8s certs metrics Metrics of underlying node Logs of control plane, kubelet and containerd Telemetry Data that MAY be fetched: K8s resources (exporters, kubestate metrics, cadvisor, parts of the kubelet) Ingress controller exporter (http error rate, cert metrics like expiration date) Telemetry Data that SHOULD NOT BE fetched: Any metrics or logs a CSP does not need to provide support with respect to their SLA with a Customer. Telemetry Data that MUST NOT be fetched: Secrets Customer Specific Workload Metrics The Alerting Mechanism MUST include a default ruleset The Observability Stack MUST run on the CSP Infrastructure The Observability Stack MUST be High Available The Observability Stack MUST be able to observe itself Observed Clusters SHOULD have a low resource impact on the used software to provide telemetry data for the Observability Stack","s":"Requirements","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#requirements","p":3387},{"i":3395,"t":"Use of the dNation Observability Stack as a base​ The dNation monitoring stack offers a lot of basic capabilities needed on an observability stack for Kubernetes like Prometheus Operator, Grafana, Alertmanager, Loki, Promtail and Thanos. Pull-based Architecture​ Each customer cluster has Thanos and Prometheus installed in addition to Thanos and Prometheus on the Observer Cluster. Metrics of a customer cluster are pulled from Thanos (Customer Cluster) for short term queries, as for long term queries the data of all Thanos instances is stored in an external Object Store of the CSP. Push-based Archtitecture​ Here, Thanos and Prometheus are only used on the CSP side to store and manage all observability data. For the customer clusters only the Prometheus Agent will be used. Prometheus Agent will push all metrics of a Customer Cluster to the central Thanos instance and is preserved in an external Object Store. This introduces less complexity and resource consumption on the customer workload clusters. Scope of the Observability Architecture​ The Observability Cluster and Architecture SHOULD be defined in a modular way so that it can be used to not only observe the Kubernetes Layer of an SCS Stack, but every aspect of an SCS Stack. Observing the Observability Infrastructure​ For usage in production, it needs to be possible to observe the Observability Cluster itself. Alerting Rulesets​ Use a mix of kubernetes-mixin alerts and dNation Alerts Ruleset, as they offer an extensive and well reviewed set of default Alerts covering the important Parts of a Kubernetes Deployment (Nodes, Controlplane, K8s Resources, etc.)","s":"Options considered","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#options-considered","p":3387},{"i":3397,"t":"Base the MVP-0 Implementation on the dNation Kubernetes Monitoring Stack. The Push-based Architecture was chosen over the Pull-based Approach. The Observability Stack will be created based on the dNation observability stack The Observability Stack can be used as a standalone component to use with the Kubernetes Layer. It should be possible to observe other parts of an SCS Stack like the status of the OpenStack components, but this will not be mandatory. The Observability Stack should be designed that it is possible to provision two observer clusters side by side, observing each other. To do this is only a recommendation for production usage. The MVP-0 will consist of the following features: Observability data from KaaS Clusters is scraped K8s cluster that hosts observer deployment is deployed S3 compatible bucket as a storage for long term metrics is configured thanos query-frontend is deployed and configured thanos query is deployed and configured thanos reciever is deployed and configured (simple deployment, non HA, without router) thanos ruler is deployed and configured thanos compactor is deployed and configured thanos bucket-web is deployed and configured thanos storegateway is deployed and configured prometheus server is deployed and configured prometheus alertmanager is deployed and configured prometheus black-box exporter is deployed and configured kaas-metric-importer is deployed and configured (service aims to differentiate between intentional deletion of KaaS instances and failures in the KaaS monitoring agent) Alerts are defined on the KaaS Clusters metrics all prometheus alerts are working as expected There exist Dashboards for KaaS Cluster Health KaaS L0 dashboard counters are working correctly Dedicated L0 dashboards are deployed for KaaS and for IaaS monitoring layers There exist Dashboards for SCS services endpoinds health (BlackBox exporter) There exist Dashboards for IaaS layer health Automatic Setup of Exporters for Observability of managed K8s clusters KaaS service is mocked VM that will host a mock of KaaS service is deployed a script that deploys a multiple KinD clusters and register them in observer is created Automatic Setup of Thanos sidecar for Observability of IaaS layer (testbed) IaaS service is mocked OSISM testbed is deployed implement an option to deploy thanos sidecar with some simple config in OSISM testbed There exist Dashboards for Harbor Registry Health Alerts are defined on the Harbor Registry metrics","s":"Decisions","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#decisions","p":3387},{"i":3400,"t":"A survey was conducted to gather the needs and requirements of a CSP when providing Kubernetes as a Service. The results of the Survey (Questions with answers) were the following: What is your understanding of a managed Kubernetes Offering: Hassle-Free Installation and Maintainance (customer viewpoint); Providing Controlplane and worker nodes and responsibility for correct function but agnostic to workload Day0, 1 and 2 (~planning, provisioning, operations) full lifecyle management or let customer manages some parts of that, depending on customer contract What Type and Depth of observability is needed CPU, RAM, HDD and Network usage, Health and Function of Cluster Nodes, Controlplane and if desired Customer Workload Do you have an observabiltiy infrastructure, if yes, how it is built Grafana/Thanos/Prometheus/Loki/Promtail/Alertmanger Stack, i.e. Example Infrastructure Data Must haves CPU, RAM, Disk, Network HTTP Connectivity Metrics Control Plane and Pod metrics (States, Ready, etc.) Workload specific metrics Node Stats K8s resources (exporters, kubestate metrics, cadvisor, parts of the kubelet) Ingress controller exporter (http error rate, cert metrics like expiration date) K8s certs metrics Metrics of underlying node Logs of control plane, kubelet and containerd Must Not haves Secrets, otherwise as much as possible for anomaly detection over long time data Must have Alerts Dependent on SLAs and SLA Types, highly individual Use of kubernetes-mixin alerts and dNation Alerts Ruleset Must NOT Alert on Should not wake people, nothing that does not lead to Action items Observability from Within Or Outside KaaS. How does the architecture look like? Monitoring Infra on CSP Side Data from Customer Clusters and Mon Infra on CSP and KaaS, get both data. KaaS Monitoring can also be used by customer Special Constraints HA Setup in different Clusters on Different Sites","s":"Outcome of the CSP Survey about Requirements for KaaS Observability","u":"/standards/scs-0403-v1-csp-kaas-observability-stack","h":"#outcome-of-the-csp-survey-about-requirements-for-kaas-observability","p":3387},{"i":3403,"t":"For the reference implementation of the status page API defined by the OpenAPI spec some decision should be made to which technlogy to be used and why. A reference implementation should be of use to most of the intended group, but is not necsessarily applicable for every use case.","s":"Introduction","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#introduction","p":3401},{"i":3405,"t":"For a reference implementation to be of any use, some common and widely used technologies should be used, so it's useful to most of the intended user group.","s":"Motivation","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#motivation","p":3401},{"i":3408,"t":"The status page application consists of an api server as well as a frontend. For implementing the api server, which is generated from the OpenAPI spec, Go was chosen, because of maturity and wide spread usage as industry standard. Go, in particular, is a modern programming language and is commonly used in network and cloud computing environments.","s":"Programming Language","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#programming-language","p":3401},{"i":3410,"t":"As database, PostgreSQL was chosen, since it is a mature, well-known database. PostgreSQL can be run in various environments from small setups to scaled setups. Furthermore PostgreSQL is a very healthy project with an active community and a solid license. It easily passed the SCS OSS health check.","s":"Database","u":"/standards/scs-0401-v1-status-page-reference-implementation-decision","h":"#database","p":3401},{"i":3413,"t":"The Sovereign Cloud Stack project intends to standardise an infrastructure-as-a-service (IaaS) layer. In order to economically sustainably run a cloud, it is generally useful to know which user or tenant consumes which amount of resources in which time frame. Similarly to how the SCS provides an interface for connecting monitoring services to detect outages, this standard aims for providing an interface for connecting systems which aggregate customer resource usage.","s":"Introduction","u":"/standards/scs-0412-v1-metering-json","h":"#introduction","p":3411},{"i":3415,"t":"In general, users of the SCS (i.e. cloud operators) may already have different systems in place for tracking customer relationships as well as billing. Those systems are unlikely to have a uniform interface across all possible implementations. Likewise, those systems are unlikely to have a way to interface with OpenStack, the reference IaaS layer in SCS. In order to provide SCS operators with a way to integrate the SCS IaaS layer with their billing, this document shall provide a standard format, upon which shim conversion layers (to whichever billing system is in place) can be built.","s":"Motivation","u":"/standards/scs-0412-v1-metering-json","h":"#motivation","p":3411},{"i":3417,"t":"In order to define a standard, the various options for formats need to be considered. However, all formats also come with different implementation costs. These aspects are weighed in this section.","s":"Design Considerations","u":"/standards/scs-0412-v1-metering-json","h":"#design-considerations","p":3411},{"i":3419,"t":"Use Ceilometer HTTP hook format​ The OpenStack Ceilometer project, which serves as a hub for all things telemetry and metering, provides an HTTP-based hook to extract metering data. This hook receives JSON-formatted data. Using this data has the advantage that we do not need to implement another component to translate the format which may in turn be a point of failure. Use another format​ In this option, a format for metering data is researched and reused, or defined and specified by the SCS project. This option was not explored deeply, for the reasons explained in the decision.","s":"Options considered","u":"/standards/scs-0412-v1-metering-json","h":"#options-considered","p":3411},{"i":3421,"t":"None.","s":"Open questions","u":"/standards/scs-0412-v1-metering-json","h":"#open-questions","p":3411},{"i":3423,"t":"We chose the Ceilometer HTTP hook format, described below, for the following reasons: Ceilometer is a component which needs to be there anyway for successful metering of OpenStack. Re-using the format makes sense. Using any other format requires a translation layer. However, users will likely need their own translation layer anyway, to integrate the metering with their own infrastructure. Hence, it makes more sense to expose the data from Ceilometer directly. A notable downside of this approach is that a change in Ceilometers format will inevitably cause issues in all downstream consumers.","s":"Decision","u":"/standards/scs-0412-v1-metering-json","h":"#decision","p":3411},{"i":3425,"t":"SCS-0410-v1 SCS-0411-v1","s":"Related Documents","u":"/standards/scs-0412-v1-metering-json","h":"#related-documents","p":3411},{"i":3427,"t":"None.","s":"Conformance Tests","u":"/standards/scs-0412-v1-metering-json","h":"#conformance-tests","p":3411},{"i":3429,"t":"Note that the state Stable is shown here if stabilized at is in the future, whereas Effective is shown here if stabilized at is in the past and deprecated at is unset or in the future. Scope versions -> v3 v4 State Deprecated Effective Stabilized at 2023-06-15 2024-02-28 Deprecated at 2024-04-30 Standards OpenStack Powered Compute v2022.11 v2022.11 scs-0100: Flavor naming v3 v3 scs-0101: Entropy v1 scs-0102: Image metadata v1 v1 scs-0103: Standard flavors v1 scs-0104: Standard images v1","s":"SCS Compatible IaaS","u":"/standards/scs-compatible-iaas","h":"","p":3428},{"i":3431,"t":"Note that the state Stable is shown here if stabilized at is in the future, whereas Effective is shown here if stabilized at is in the past and deprecated at is unset or in the future. Scope versions -> v1 v2 State Draft Draft Stabilized at Deprecated at Standards CNCF Kubernetes conformance ✓ scs-0210: Kubernetes version policy v2 v2 scs-0214: Kubernetes node distribution and availability v1 v1","s":"SCS Compatible KaaS","u":"/standards/scs-compatible-kaas","h":"","p":3430},{"i":3434,"t":"In the past we noticed missing events in the telemetry stack of OpenStack. This results in situations where the Cloud Service Provider (CSP) may think that a resource is still in use while the owner shut it down, or may not be aware of a resource which has been created. Such inaccurate data is a problem, when it is supposed to be used for billing purposes. This document discusses how such metering data should be made available to the cloud service provider for forwarding into their own billing solution.","s":"Introduction","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#introduction","p":3432},{"i":3436,"t":"Push-based flow: In a push-based flow, the system generating data actively sends that data to a consumer. Pull-based flow: In a pull-based flow, the system generating data waits for the system consuming the data to ask for that data. Metering: Collection of usage data of a cloud, for the specific purpose of creating invoices to bill customers for the resources they have allocated. Billing: The entire process of creation, management and sending of invoices generated from metering data.","s":"Definitions","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#definitions","p":3432},{"i":3438,"t":"Being able to bill users for the resources they use is a prerequisite for commercially operating a cloud. The SCS project wants to deliver a cloud stack which can be used for that purpose, hence providing reliable metering data is a requirement. We generally expect that cloud providers already have some kind of customer-relation management or billing system in place. Hence, it is important that the SCS is not too opinionated on this implementation detail, but provides a system which can easily interface with other systems. This is similar to how the SCS specified the monitoring stack.","s":"Motivation","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#motivation","p":3432},{"i":3440,"t":"The following requirements exist for the process for providing metrics to the cloud service provider: MUST scale to different timescales: We expect to have metrics which change frequently (e.g. object store usage) and metrics which change rarely (e.g. cinder volume sizes).","s":"Design Considerations","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#design-considerations","p":3432},{"i":3442,"t":"Push-based flow​ In a push-based flow, the to-be-implemented metering system pushes events to the sink as soon as it is reasonably confident that the event can be used for billing purposes. Poll-based flow​ In the poll-based flow, whichever system the CSP runs would be responsible for polling the metering API in a frequency sufficient to capture all data with sufficient granularity.","s":"Options","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#options","p":3432},{"i":3444,"t":"What is necessary to extend the availability of sending to various sinks? How does the configuration look like that is needed to push to a sink from the same type that will be already implemented?","s":"Open questions","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#open-questions","p":3432},{"i":3446,"t":"As we need to support very different time scales of data, the push-based flow is more suitable: it allows the producer of the data, which knows about the interval in which it changes, when to provide new data to the consumer. In contrast to that, a poll-based flow would need the consumer to know about change intervals, or alternatively poll in the highest change frequency ever expected.","s":"Decision","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#decision","p":3432},{"i":3448,"t":"SCS-0410-v1","s":"Related Documents","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#related-documents","p":3432},{"i":3450,"t":"None (this is a decision record).","s":"Conformance Tests","u":"/standards/scs-0411-v1-publishing_method_for_metering_data","h":"#conformance-tests","p":3432},{"i":3453,"t":"SCS Clouds should provide a way to grant Domain Manager rights to SCS Customers which provides IAM self-service capabilities within an OpenStack domain. This is not properly implemented in the default OpenStack configuration and requires specific adjustments to the Keystone identity management configuration. To avoid conflict with the unscoped admin role in OpenStack we want to refer to this new persona as \"Domain Manager\", introducing the manager role in the API for domains.","s":"Introduction","u":"/standards/scs-0302-v1-domain-manager-role","h":"#introduction","p":3451},{"i":3455,"t":"The following special terms are used throughout this standard document: Term Meaning RBAC Role-Based Access Control1 established by OpenStack Keystone project OpenStack project as per Keystone RBAC user OpenStack user as per Keystone RBAC group OpenStack group as per Keystone RBAC role OpenStack role as per Keystone RBAC domain OpenStack domain as per Keystone RBAC IAM identity and access management persona Abstract and conceptual role of a user in terms of IAM IAM resources projects, users, groups, roles, domains as managed by OpenStack Keystone CSP Cloud Service Provider, provider managing the OpenStack infrastructure cloud admin OpenStack user belonging to the CSP that possesses the admin role","s":"Glossary","u":"/standards/scs-0302-v1-domain-manager-role","h":"#glossary","p":3451},{"i":3457,"t":"Applying this standard modifies the API policy configuration of Keystone and introduces a new persona to Keystone to enable IAM self-service for customers within a domain. Once assigned, this persona allows special Domain Manager users within a domain to manage users, project, groups and role assignments as part of the IAM self-service. However, the configuration change introduced by this standard does not automatically assign the Domain Manager persona to any users per default. Assigning the new persona and granting customers the resulting self-service capabilities is a deliberate action to be taken by the CSP on a per-tenant (i.e. per domain) basis. Omitting the provisioning of any Domain Manager users (i.e. not assigning the new persona to any user) will result in an OpenStack cloud that behaves identically to a configuration without the standard applied, making the actual usage of the functionality a CSP's choice and entirely optional.","s":"Impact","u":"/standards/scs-0302-v1-domain-manager-role","h":"#impact","p":3451},{"i":3459,"t":"In the default configuration of Keystone, only users with the admin role may manage the IAM resources such as projects, groups and users and their relation through role assignments. The admin role in OpenStack Keystone is not properly scoped when assigned within a domain or project only as due to hard-coded architectural limitations in OpenStack, a user with the admin role may escalate their privileges outside of their assigned project or domain boundaries. Thus, it is not possible to properly give customers a self-service functionality in regards to project, group and user management with the default configuration. To address this, this standard defines a new Domain Manager persona implemented using a domain-scoped manager role in conjunction with appropriate Keystone API policy adjustments to establish a standardized extension to the default Keystone configuration allowing for IAM self-service capabilities for customers within domains.","s":"Motivation","u":"/standards/scs-0302-v1-domain-manager-role","h":"#motivation","p":3451},{"i":3461,"t":"The cloud admin deploys the Domain Manager policy configuration for Keystone as per this standard if it is not already applied. The cloud admin creates the desired domains for the customers for which IAM self-service capabilities are desired. The cloud admin creates one or more users within each of the applicable domains and assigns the manager role for a certain domain to them. These users represent the Domain Managers of the corresponding domain. The customer uses the Domain Manager users to manage (create, update, delete) users, projects, groups and corresponding role assignments within their domain.","s":"Desired Workflow","u":"/standards/scs-0302-v1-domain-manager-role","h":"#desired-workflow","p":3451},{"i":3463,"t":"the Domain Manager persona MUST support managing projects, groups and users within a specific domain the Domain Manager persona MUST be properly scoped to a domain, it MUST NOT gain access to resources outside of its owning domain the Domain Manager persona MUST NOT be able to manipulate existing roles or create new roles the Domain Manager persona MUST only be able to assign specific non-administrative* roles to their managed users where the applicable roles are defined by the CSP Domain Managers MUST NOT be able to abuse the role assignment functionalities to escalate their own privileges or those of other users beyond the roles defined by the CSP * \"non-administrative\" in this context means this excludes the role \"admin\" and any comparable role that grants permissions beyond domain and tenant scope. Since the \"manager\" role as defined in this standard is domain-scoped for a Domain Manager, it does not count as administrative.","s":"Design Considerations","u":"/standards/scs-0302-v1-domain-manager-role","h":"#design-considerations","p":3451},{"i":3465,"t":"Re-using the existing admin role​ As role assignments can be scoped to project, groups and domains the most obvious option would be to assign the existing admin role to users representing Domain Managers in a scoped fashion. However, due to architectural limitations2 of the existing OpenStack implementation of roles, the admin role has a special meaning reaching beyond the RBAC checks done by Keystone and other OpenStack components. This results in special permissions being granted to users possessing the role which ignore the project or domain scope of the role assignment. This poses severe security risks as the proper scoping of the admin role is impossible. Due to this, this approach was discarded early. Upstream (OpenStack) is in the process of addressing this across the services but it has not been fully implemented yet, especially for domains3. Introducing a new persona and role with API policy changes​ OpenStack Keystone allows for new roles to be created via its API by administrative users. Additionally, each OpenStack API's RBAC can be adjusted through an API policy file (policy.yaml) through olso-policy4, Keystone included. The possibility of managing users, projects, role assignments and so on is regulated through Keystone's RBAC configured by its API policy file. This means that by creating a new role and extending Keystone's API policy configuration a new Domain Manager persona can be established that is limited to a specific subset of the Keystone API to be used to manage users, projects and role assignments within a domain.","s":"Options considered","u":"/standards/scs-0302-v1-domain-manager-role","h":"#options-considered","p":3451},{"i":3468,"t":"The approach described in this standard imposes the following limitations: as a result of the \"identity:list_domains\" rule (see below), Domain Managers are able to see all domains5 via \"openstack domain list\" and can inspect the metadata of other domains with \"openstack domain show\" as a result of the \"identity:list_roles\" rule (see below), Domain Managers are able to see all roles via \"openstack role list\" and can inspect the metadata of other roles with \"openstack role show\" As a result of points 1 and 2, metadata of all domains and roles will be exposed to all Domain Managers! If a CSP deems either of these points critical, they may abstain from granting the \"manager\" role to any user in a domain scope, effectively disabling the Domain Manager functionality. See Impact.","s":"Limitations","u":"/standards/scs-0302-v1-domain-manager-role","h":"#limitations","p":3451},{"i":3470,"t":"A role named \"manager\" is to be created via the Keystone API and the policy adjustments quoted below are to be applied.","s":"Decision","u":"/standards/scs-0302-v1-domain-manager-role","h":"#decision","p":3451},{"i":3472,"t":"The following policy has to be applied to Keystone in a verbatim fashion. The only parts of the policy definitions that may be changed are: The \"base_*\" definitions to align them to the correct OpenStack defaults matching the OpenStack release of the environment in case those differ from this template. The \"is_domain_managed_role\" definition (see next section below). # SCS Domain Manager policy configuration # Section A: OpenStack base definitons # The entries beginning with \"base_\" should be exact copies of the # default \"identity:\" definitions for the target OpenStack release. # They will be extended upon for the manager role below this section. \"base_get_domain\": \"(role:reader and system_scope:all) or token.domain.id:%(target.domain.id)s or token.project.domain.id:%(target.domain.id)s\" \"base_list_domains\": \"(role:reader and system_scope:all)\" \"base_list_roles\": \"(role:reader and system_scope:all)\" \"base_get_role\": \"(role:reader and system_scope:all)\" \"base_list_users\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)\" \"base_get_user\": \"(role:reader and system_scope:all) or (role:reader and token.domain.id:%(target.user.domain_id)s) or user_id:%(target.user.id)s\" \"base_create_user\": \"(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)\" \"base_update_user\": \"(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)\" \"base_delete_user\": \"(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)\" \"base_list_projects\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)\" \"base_get_project\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.project.domain_id)s) or project_id:%(target.project.id)s\" \"base_create_project\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)\" \"base_update_project\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)\" \"base_delete_project\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)\" \"base_list_user_projects\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(target.user.id)s\" \"base_check_grant\": \"(role:reader and system_scope:all) or ((role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)\" \"base_list_grants\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)\" \"base_create_grant\": \"(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)\" \"base_revoke_grant\": \"(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)\" \"base_list_role_assignments\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)\" \"base_list_groups\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)\" \"base_get_group\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)\" \"base_create_group\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)\" \"base_update_group\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)\" \"base_delete_group\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)\" \"base_list_groups_for_user\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(user_id)s\" \"base_list_users_in_group\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)\" \"base_remove_user_from_group\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)\" \"base_check_user_in_group\": \"(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)\" \"base_add_user_to_group\": \"(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)\" # Section B: Domain Manager Extensions # classify domain managers with a special role \"is_domain_manager\": \"role:manager\" # specify a rule that whitelists roles which domain admins are permitted # to assign and revoke within their domain \"is_domain_managed_role\": \"'member':%(target.role.name)s or 'load-balancer_member':%(target.role.name)s\" # allow domain admins to retrieve their own domain (does not need changes) \"identity:get_domain\": \"rule:base_get_domain or rule:admin_required\" # list_domains is needed for GET /v3/domains?name=... requests # this is mandatory for things like # `create user --domain $DOMAIN_NAME $USER_NAME` to correctly discover # domains by name \"identity:list_domains\": \"rule:is_domain_manager or rule:base_list_domains or rule:admin_required\" # list_roles is needed for GET /v3/roles?name=... requests # this is mandatory for things like `role add ... $ROLE_NAME`` to correctly # discover roles by name \"identity:list_roles\": \"rule:is_domain_manager or rule:base_list_roles or rule:admin_required\" # get_role is needed for GET /v3/roles/{role_id} requests # this is mandatory for the OpenStack SDK to properly process role assignments # which are issued by role id instead of name \"identity:get_role\": \"(rule:is_domain_manager and rule:is_domain_managed_role) or rule:base_get_role or rule:admin_required\" # allow domain admins to manage users within their domain \"identity:list_users\": \"(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_users or rule:admin_required\" \"identity:get_user\": \"(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_get_user or rule:admin_required\" \"identity:create_user\": \"(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_create_user or rule:admin_required\" \"identity:update_user\": \"(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_update_user or rule:admin_required\" \"identity:delete_user\": \"(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_delete_user or rule:admin_required\" # allow domain admins to manage projects within their domain \"identity:list_projects\": \"(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_projects or rule:admin_required\" \"identity:get_project\": \"(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_get_project or rule:admin_required\" \"identity:create_project\": \"(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_create_project or rule:admin_required\" \"identity:update_project\": \"(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_update_project or rule:admin_required\" \"identity:delete_project\": \"(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_delete_project or rule:admin_required\" \"identity:list_user_projects\": \"(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_user_projects or rule:admin_required\" # allow domain managers to manage role assignments within their domain # (restricted to specific roles by the 'is_domain_managed_role' rule) # # project-level role assignment to user within domain \"is_domain_user_project_grant\": \"token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s\" # project-level role assignment to group within domain \"is_domain_group_project_grant\": \"token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.project.domain_id)s\" # domain-level role assignment to group \"is_domain_level_group_grant\": \"token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.domain.id)s\" # domain-level role assignment to user \"is_domain_level_user_grant\": \"token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.domain.id)s\" \"domain_manager_grant\": \"rule:is_domain_manager and (rule:is_domain_user_project_grant or rule:is_domain_group_project_grant or rule:is_domain_level_group_grant or rule:is_domain_level_user_grant)\" \"identity:check_grant\": \"rule:domain_manager_grant or rule:base_check_grant or rule:admin_required\" \"identity:list_grants\": \"rule:domain_manager_grant or rule:base_list_grants or rule:admin_required\" \"identity:create_grant\": \"(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_create_grant or rule:admin_required\" \"identity:revoke_grant\": \"(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_revoke_grant or rule:admin_required\" \"identity:list_role_assignments\": \"(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_role_assignments or rule:admin_required\" # allow domain managers to manage groups within their domain \"identity:list_groups\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_list_groups or rule:admin_required\" \"identity:get_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_get_group or rule:admin_required\" \"identity:create_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_create_group or rule:admin_required\" \"identity:update_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_update_group or rule:admin_required\" \"identity:delete_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_delete_group or rule:admin_required\" \"identity:list_groups_for_user\": \"(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_groups_for_user or rule:admin_required\" \"identity:list_users_in_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_list_users_in_group or rule:admin_required\" \"identity:remove_user_from_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_remove_user_from_group or rule:admin_required\" \"identity:check_user_in_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_check_user_in_group or rule:admin_required\" \"identity:add_user_to_group\": \"(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_add_user_to_group or rule:admin_required\" Note that the policy file begins with a list of \"base_*\" rule definitions (\"Section A\"). These mirror the default policies of recent OpenStack releases. They are used as a basis for the domain-manager-specific changes which are implemented in \"Section B\" where they are referenced to via \"or rule:base_*\" accordingly. The section of \"base_*\" rules is meant for easy maintenance/update of default rules while keeping the domain-manager-specific rules separate. Note: The \"or rule:admin_required\" appendix to the rule defintions in \"Section B\" is included for backwards compatibility with environments not yet fully configured for the new secure RBAC standard6. Specifying manageable roles via \"is_domain_managed_role\"​ The \"is_domain_managed_role\" rule of the above policy template may be adjusted according to the requirements of the CSP and infrastructure architecture to specify different or multiple roles as manageable by Domain Managers as long as the policy rule adheres to the following: the \"is_domain_managed_role\" rule MUST NOT contain the \"admin\" role, neither directly nor transitively the \"is_domain_managed_role\" rule MUST define all applicable roles directly, it MUST NOT contain a \"rule:\" reference within itself Example: permitting multiple roles​ The following example permits the \"reader\" role to be assigned/revoked by a Domain Manager in addition to the default \"member\" and \"load-balancer_member\" roles. Further roles can be appended using the logical or directive. \"is_domain_managed_role\": \"'member':%(target.role.name)s or 'load-balancer_member':%(target.role.name)s or 'reader':%(target.role.name)s\" Note regarding the manager role When adjusting the \"is_domain_managed_role\" rule a CSP might opt to also include the \"manager\" role itself in the manageable roles, resulting in Domain Managers being able to propagate the Domain Manager capabilities to other users within their domain. This increases the self-service capabilities of the customer but introduces risks of Domain Managers also being able to revoke this role from themselves or each other (within their domain) in an unintended fashion. CSPs have to carefully evaluate whether Domain Manager designation authority should reside solely on their side or be part of the customer self-service scope and decide about adding \"'manager':%(target.role.name)s\" to the rule accordingly.","s":"Policy adjustments","u":"/standards/scs-0302-v1-domain-manager-role","h":"#policy-adjustments","p":3451},{"i":3475,"t":"Description: Upstream bug report about the underlying architectural issue of the admin role not being properly scoped and giving system-level admin permissions regardless of whether the admin role assignment was scoped to project or domain level. This is the main reason for the admin role being inappropriate to implement Domain Managers. Link: Launchpad bug: \"admin\"-ness not properly scoped","s":"\"admin\"-ness not properly scoped","u":"/standards/scs-0302-v1-domain-manager-role","h":"#admin-ness-not-properly-scoped","p":3451},{"i":3477,"t":"Description: Upstream rework of the default role definitions and hierarchy across all OpenStack services. Aims to introduce support for a scoped manager role by 2024 but only focuses on project-level scoping for this role so far, not domain-level. Link: OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC","s":"Consistent and Secure Default RBAC","u":"/standards/scs-0302-v1-domain-manager-role","h":"#consistent-and-secure-default-rbac","p":3451},{"i":3479,"t":"There is a test suite in domain-manager-check.py. The test suite connects to the OpenStack API using two sample domains and corresponding Domain Manager accounts. It verifies the compliance to the standard and the proper domain-scoping as defined by the Keystone policy. Please consult the associated README.md for detailed setup and testing instructions.","s":"Conformance Tests","u":"/standards/scs-0302-v1-domain-manager-role","h":"#conformance-tests","p":3451},{"i":3482,"t":"Change the naming of the Domain Manager role to align with upstream​ Decision Date: 2024-03-13 Decision Maker: Team IaaS Decision: the Domain Manager role should be named \"manager\" not \"domain-manager\" Rationale: upstream (OpenStack) will introduce a \"manager\" role with the upcoming RBAC rework the \"manager\" role is intended to grant managing capabilities bound to the scope it is assigned for, e.g. projects; it would make sense to also integrate the Domain Manager approach here during the process of contributing the Domain Manager functionality upstream we were asked to use the already defined \"manager\" role instead of introducing a new role; so the rename would then also be in line with the upstream contribution Links / Comments / References: Team IaaS meeting protocol entry request from upstream to re-use existing \"manager\" role Allow flexibility for the roles a Domain Manager can assign/revoke within domain​ Decision Date: 2023-09-27 Decision Maker: Team IaaS, Team IAM Decision: the standard should not strictly limit the roles a Domain Manager can assign/revoke to/from other users within a domain to the \"member\" role the standard should allow CSPs to define one or more roles for Domain Managers to manage whether or not this includes the Domain Manager role itself is not to be predefined by the standard and should be up to the CSP to decide instead the standard should only strictly prohibit adding the \"admin\" role to the list of roles manageable by Domain Managers Rationale: the available and configured roles might differ between CSPs and infrastructures the Domain Manager standard should be flexible enough to adapt to different environments while still offering the intended functionality there might be a tradeoff between self-service flexibility desired by customers and the security regulation a CSP wants to impose, thus allowing or prohibiting the designation of Domain Managers by customers themselves should be up to the CSP to decide Links / Comments / References: Team IaaS meeting protocol entry Extend domain management functionality to Keystone groups​ Decision Date: 2023-08-04 Decision Maker: SIG IAM Decision: the Domain Manager Standard configuration should cover the groups functionality of Keystone, allowing domain manager to manage groups in domains Rationale: the groups functionality is a desired IAM feature for customers Links / Comments / References: SIG IAM meeting protocol entry action item issue Change the naming of the Domain Manager role​ Decision Date: 2023-08-04 Decision Maker: SIG IAM Decision: the Domain Manager role should be named \"domain-manager\" not \"domain-admin\". Rationale: avoid confusion with the unscoped admin role and to be inline with the upstream plan: Default Service Role - Identity Specs Links / Comments / References: SIG IAM meeting protocol entry issue commment about decision Footnotes​ OpenStack Documentation: Role-Based Access Control Overview ↩ Launchpad bug: \"admin\"-ness not properly scoped ↩ OpenStack Documentation: Keystone for Other Services - Domain Scope ↩ OpenStack Documentation: Administering Applications that use oslo.policy ↩ see the corresponding Launchpad bug at Keystone ↩ OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC ↩","s":"Decision Record","u":"/standards/scs-0302-v1-domain-manager-role","h":"#decision-record","p":3451},{"i":3484,"t":"OpenStack Documentation: Role-Based Access Control Overview ↩ Launchpad bug: \"admin\"-ness not properly scoped ↩ OpenStack Documentation: Keystone for Other Services - Domain Scope ↩ OpenStack Documentation: Administering Applications that use oslo.policy ↩ see the corresponding Launchpad bug at Keystone ↩ OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC ↩","s":"Footnotes","u":"/standards/scs-0302-v1-domain-manager-role","h":"#footnote-label","p":3451},{"i":3487,"t":"Very short introduction about the topic of this document.","s":"Abstract","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#abstract","p":3485},{"i":3489,"t":"Example (abbr. Ex) This is the description for an example terminology.","s":"Terminology","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#terminology","p":3485},{"i":3491,"t":"What is the issue that we're seeing that is motivating this decision or change?","s":"Context","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#context","p":3485},{"i":3493,"t":"What is the decision that we're proposing and/or doing? Should also include reasoning for this decision","s":"Decision","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#decision","p":3485},{"i":3495,"t":"What becomes easier or more difficult to do because of this change?","s":"Consequences","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#consequences","p":3485},{"i":3497,"t":"Related Documents, OPTIONAL","s":"Related Documents","u":"/standards/scs-XXXX-vN-decision-record-template","h":"#related-documents","p":3485},{"i":3500,"t":"Introduction","s":"Introduction","u":"/standards/scs-XXXX-vN-standard-template","h":"#introduction","p":3498},{"i":3502,"t":"Example (abbr. Ex) This is the description for an example terminology.","s":"Terminology","u":"/standards/scs-XXXX-vN-standard-template","h":"#terminology","p":3498},{"i":3504,"t":"Motivation","s":"Motivation","u":"/standards/scs-XXXX-vN-standard-template","h":"#motivation","p":3498},{"i":3506,"t":"OPTIONAL","s":"Design Considerations","u":"/standards/scs-XXXX-vN-standard-template","h":"#design-considerations","p":3498},{"i":3508,"t":"Option 1​ Option 1 description Option 2​ Option 2 description","s":"Options considered","u":"/standards/scs-XXXX-vN-standard-template","h":"#options-considered","p":3498},{"i":3510,"t":"RECOMMENDED","s":"Open questions","u":"/standards/scs-XXXX-vN-standard-template","h":"#open-questions","p":3498},{"i":3512,"t":"What is the essence of this standard? Adjust heading accordingly.","s":"Standard","u":"/standards/scs-XXXX-vN-standard-template","h":"#standard","p":3498},{"i":3514,"t":"Related Documents, OPTIONAL","s":"Related Documents","u":"/standards/scs-XXXX-vN-standard-template","h":"#related-documents","p":3498},{"i":3516,"t":"Conformance Tests, OPTIONAL","s":"Conformance Tests","u":"/standards/scs-XXXX-vN-standard-template","h":"#conformance-tests","p":3498},{"i":3518,"t":"Standards are the core deliverable of SCS. By standardizing the open source software components of a cloud computing stack, their versions, how they are to be configured, deployed and utilized, SCS guarantees the reproducibility of a certain behavior of this technology. SCS standards are discussed, developed and maintained in the community by the corresponding teams (see Track in the table below), which naturally include existing users of SCS. *Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective). Standard Track Description Draft Stable* Effective Deprecated* scs-0001 Global Sovereign Cloud Standards - - v1 - scs-0002 Global Standards, Docs and Organisation v2 - v1 - scs-0003 Global Sovereign Cloud Standards YAML v1 - - - scs-0004 Global Regulations for achieving SCS-compatible certification v1 - - - scs-0112 Global SONiC Support in SCS v1 - - - scs-0100 IaaS SCS Flavor Naming Standard - - v3 v1, v2 Supplement: Implementation and Testing Notes w1 - - - scs-0101 IaaS SCS Entropy - - v1 - Supplement: Implementation and Testing Notes w1 - - - scs-0102 IaaS SCS Image Metadata Standard - - v1 - scs-0103 IaaS SCS Standard Flavors and Properties - - v1 - scs-0104 IaaS SCS Standard Images - - v1 - scs-0110 IaaS SSD Flavors - - v1 - scs-0111 IaaS Decisions for the Volume Type Standard v1 - - - scs-0113 IaaS Security Groups Decision Record v1 - - - scs-0114 IaaS Volume Type Standard v1 - - - scs-0115 IaaS Default Rules for Security Groups v1 - - - scs-0200 KaaS Using Sonobuoy for KaaS conformance tests v1 - - - scs-0210 KaaS SCS K8S Version Policy - - v2 v1 scs-0211 KaaS SCS KaaS default storage class - - v1 - scs-0212 KaaS Requirements for container registries v1 - - - scs-0213 KaaS Kubernetes Nodes Anti Affinity v1 - - - scs-0214 KaaS Kubernetes Node Distribution and Availability - - v1 - scs-0215 KaaS Robustness features for Kubernetes clusters v1 - - - scs-0216 KaaS Requirements for testing cluster-stacks v1 - - - scs-0217 KaaS Kubernetes cluster baseline security v1 - - - scs-0218 KaaS Container registry for SCS standard implementation v1 - - - scs-0300 IAM Requirements for SSO identity federation - - v1 - scs-0301 IAM Naming for domains/groups/roles/project when onboarding new customers v1 - - - scs-0302 IAM Domain Manager configuration for Keystone v1 - - - scs-0400 Ops Status Page create decision v1 - - - scs-0401 Ops Status page reference implementation decision v1 - - - scs-0402 Ops Status page OpenAPI decision v1 - - - scs-0403 Ops Architecture for the Cloud Service provider Observability System for the KaaS Layer v1 - - - scs-0410 Ops Gnocchi as database for metering v1 - - - scs-0411 Ops Push-based approach for providing usage data v1 - - - scs-0412 Ops Exposition of IaaS metering data as JSON v1 - - -","s":"Overview","u":"/standards/standards/overview","h":"","p":3517}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/4",[0,4.329,1,1.876,2,3.157,3,4.756,4,5.133,5,1.644,6,3.901,7,1.958,8,6.722,9,4.914,10,2.793,11,2.647,12,2.467,13,4.519,14,4.08,15,3.855,16,4.295,17,3.383,18,5.182,19,3.974,20,3.459,21,2.206,22,2.92,23,5.182,24,5.025,25,3.949,26,3.949,27,3.707,28,3.832,29,5.728,30,1.571,31,5.04,32,5.345,33,2.519,34,4.801,35,4.651,36,5.599,37,6.813,38,3.759,39,4.605,40,4.026,41,3.459,42,5.26,43,2.67,44,1.365,45,5.647,46,6.064,47,2.759,48,2.98,49,5.769,50,5.04,51,3.855,52,5.345]],["t/6",[53,11.988,54,12.936,55,11.988,56,10.534,57,11.988,58,9.829,59,9.829,60,9.829,61,9.829,62,9.829,63,9.829,64,9.829,65,9.829,66,9.829,67,9.829,68,9.829,69,9.829,70,9.829]],["t/10",[1,1.972,7,1.056,42,2.837,44,2.149,71,6.457,72,4.102,73,1.941,74,2.619,75,4.936,76,2.01,77,3.593,78,4.053,79,4.589,80,4.917,81,6.952,82,5.495,83,2.331,84,2.079,85,1.844,86,1.259,87,1.42,88,1.919,89,2.415,90,1.52,91,1.91,92,3.637,93,3.038,94,2.721,95,1.564,96,3.922,97,3.265,98,4.139,99,3.836,100,4.139,101,4.139,102,7.252,103,2.683,104,6.8,105,4.403,106,2.01,107,3.045,108,4.139,109,4.139,110,4.139,111,6.044,112,3.836,113,7.312,114,2.534,115,1.428,116,3.024,117,1.004,118,1.544,119,4.139,120,4.139,121,3.637,122,1.69,123,2.007,124,2.46,125,4.139,126,2.549,127,4.139,128,1.901,129,3.488,130,3.488,131,4.139,132,4.139,133,4.139,134,3.27,135,4.139,136,1.849,137,1.69,138,1.277,139,1.918,140,2.986,141,2.483,142,2.794,143,3.836,144,3.678,145,2.335,146,2.171,147,3.836,148,1.663,149,5.152,150,1.722,151,2.298,152,3.185,153,2.335,154,2.882,155,2.117,156,1.006,157,3.185,158,4.139,159,3.637,160,2.067,161,3.369,162,4.139,163,1.968,164,1.69,165,1.786,166,3.275,167,2.354,168,1.381,169,1.883,170,3.515,171,4.139,172,0.958,173,2.589,174,3.369,175,1.978,176,4.139,177,1.892,178,1.999,179,2.437,180,1.33,181,1.832]],["t/12",[30,2.353,73,3.421,83,1.814,117,1.007,138,2.834,166,4.613,172,2.125,182,7.256,183,6.071,184,7.256,185,9.185,186,4.659,187,3.724,188,5.774,189,9.185,190,4.534,191,9.185,192,9.185,193,3.384,194,3.472,195,5.954,196,2.746,197,5.356,198,4.534,199,5.683,200,5.88,201,4.726]],["t/14",[1,2.728,83,2.203,180,3.586,202,7.905,203,4.919,204,7.905,205,7.905]],["t/16",[1,2.664,5,2.335,21,3.132,206,5.961,207,6.818,208,3.213,209,4.433,210,3.606,211,4.028,212,8.387]],["t/18",[4,3.94,21,2.71,30,1.93,44,1.677,51,4.737,116,5.419,139,3.437,187,3.055,213,5.043,214,3.291,215,6.464,216,4.915,217,5.278,218,3.291,219,3.112,220,4.555,221,4.507,222,5.364,223,6.278,224,4.58,225,8.742,226,4.395,227,5.659,228,5.197,229,3.217,230,9.432,231,9.432]],["t/21",[5,2.353,96,4.325,117,1.204,118,4.098,210,3.634,232,9.652,233,7.924,234,9.652,235,5.277]],["t/23",[4,3.26,7,2.962,27,5.973,30,1.597,44,1.387,51,3.919,85,2.927,91,3.601,97,2.408,139,2.295,155,3.991,172,1.806,187,2.528,196,2.333,202,5.528,233,7.466,236,4.828,237,7.804,238,4.513,239,3.691,240,1.771,241,6.26,242,5.198,243,2.684,244,7.804,245,3.062,246,7.233,247,6.857,248,4.237,249,3.601,250,3.128,251,10.35,252,9.593,253,9.094,254,9.094,255,4.729,256,5.865,257,5.194,258,2.979,259,1.952,260,7.233,261,6.857,262,3.636,263,2.426,264,3.636]],["t/25",[4,2.728,7,3.284,44,1.629,47,2.347,52,7.374,139,3.114,156,1.587,168,2.178,172,1.511,187,2.969,208,1.925,215,4.476,223,4.347,224,3.171,240,2.923,243,1.694,253,10.625,254,5.738,259,2.365,260,6.053,261,10.625,262,4.27,265,3.546,266,2.806,267,1.6,268,3.811,269,6.531,270,9.843,271,3.901,272,6.053,273,6.053,274,6.531,275,8.495,276,3.171,277,6.053,278,6.053,279,4.476,280,6.053,281,6.053,282,6.531,283,9.815,284,7.241,285,2.917,286,6.531,287,2.48,288,3.745,289,6.531,290,5.835,291,3.654,292,6.053,293,6.053]],["t/27",[2,1.3,4,2.805,43,1.823,44,2.27,52,5.443,105,6.684,123,2.067,139,2.749,156,0.768,181,2.973,208,1.98,215,2.165,223,2.103,224,1.534,234,2.776,254,5.901,259,2.192,261,12.158,266,2.252,267,0.774,268,1.843,271,2.879,272,2.928,273,2.928,275,6.224,276,3.261,277,4.857,278,4.857,279,6.405,280,4.857,281,4.857,283,2.928,284,4.14,285,1.411,288,3.005,290,2.888,291,2.933,292,4.857,293,4.857,294,3.159,295,3.159,296,1.775,297,1.541,298,3.243,299,2.133,300,3.159,301,5.241,302,3.159,303,3.159,304,2.933,305,3.159,306,3.159,307,3.159,308,3.159,309,3.159,310,6.716,311,6.716,312,6.716,313,3.159,314,11.622,315,5.872,316,2.023,317,3.159,318,1.976,319,3.159,320,1.691,321,3.159,322,3.159,323,2.749,324,3.159,325,5.241,326,3.159,327,3.159,328,3.159,329,3.159,330,2.224,331,3.159,332,3.159,333,3.159,334,3.159,335,2.279,336,2.571,337,3.159,338,1.534,339,2.373,340,3.159,341,3.159,342,3.159,343,5.241,344,3.159,345,4.757,346,3.159,347,3.159,348,3.159,349,2.279,350,1.812,351,1.703,352,3.159,353,3.159,354,3.65,355,3.159,356,5.241,357,3.159,358,3.159,359,5.241,360,8.33,361,11.082,362,3.159,363,5.241,364,3.159,365,5.241,366,3.159,367,5.241,368,3.159,369,5.241,370,3.159,371,5.241,372,3.159,373,5.241,374,3.159,375,5.241,376,3.159,377,5.241,378,3.159,379,5.241,380,3.159,381,6.716,382,3.159,383,3.159,384,6.716,385,3.159,386,5.241,387,4.605,388,3.159,389,3.159,390,3.159,391,0.902]],["t/30",[4,4.077,7,3.045,44,1.735,47,3.508,156,2.372,187,3.161,215,6.689,223,6.496,224,4.739,240,2.71,259,2.432,262,4.548,266,4.194,267,2.391,268,5.695,287,3.49,288,5.597,392,9.76,393,9.046]],["t/32",[4,3.862,44,2.238,139,2.719,156,2.246,215,6.336,223,6.153,224,4.489,259,2.61,266,3.973,267,2.264,268,5.394,271,4.856,284,9.12,285,5.888,287,2.502,393,8.569,394,9.245,395,9.245,396,9.245]],["t/34",[21,3.084,206,5.87,207,6.713,216,5.593,233,7.742,240,2.436,259,2.383,345,7.602,391,3.063,397,6.262,398,3.954]],["t/37",[78,5.377,86,2.498,216,4.281,240,1.865,259,2.38,296,2.83,323,5.616,330,5.055,339,4.848,399,7.614,400,4.368,401,4.176,402,4.624,403,5.468,404,4.597,405,5.083,406,4.079,407,7.614,408,4.634,409,7.614,410,5.631,411,1.901,412,2.802,413,9.022,414,3.23,415,5.083,416,8.215,417,8.215,418,4.126,419,3.755,420,4.46,421,3.085,422,4.151,423,4.634,424,7.614,425,4.711,426,9.022]],["t/40",[78,5.418,86,2.528,216,4.332,240,1.887,259,2.259,271,3.062,296,2.851,330,5.084,339,4.885,399,7.705,401,4.225,402,4.65,403,5.533,404,4.652,405,5.143,406,4.127,407,7.705,408,4.689,411,1.924,412,2.835,413,9.091,414,3.248,415,5.143,418,4.175,419,3.799,420,4.513,421,3.122,422,4.2,423,4.689,424,7.705,425,4.767,427,4.104,428,7.705,429,5.997,430,8.313,431,8.313,432,9.479]],["t/44",[151,5.782,166,5.23,193,3.836,197,4.852,297,3.062,433,6.588,434,10.413,435,10.413,436,6.31,437,5.056,438,5.002,439,10.907,440,9.651,441,9.651,442,8.775]],["t/46",[27,5.305,155,5.617,160,5.485,238,6.353,241,5.921,253,9.652,267,2.69,443,4.607,444,10.984]],["t/48",[38,4.199,83,2.257,138,3.528,445,6.207]],["t/51",[151,5.913,166,5.349,193,3.924,197,4.962,297,3.132,433,6.739,436,6.454,437,5.171,438,5.116,441,9.871,446,10.651,447,10.651,448,10.651]],["t/53",[155,5.799,160,5.662,238,6.559,267,2.778,443,4.756]],["t/55",[38,4.199,83,2.257,138,3.528,445,6.207]],["t/58",[27,4.586,29,5.313,45,6.986,49,8.822,177,4.34,217,5.313,219,3.133,256,7.137,264,4.424,449,6.726,450,8.002,451,7.137,452,4.261,453,9.496,454,6.008,455,8.801,456,7.729,457,4.261,458,8.344,459,9.496,460,9.496,461,4.886,462,5.445,463,3.238,464,8.801,465,6.85,466,6.235,467,6.986]],["t/60",[21,2.97,22,3.933,25,5.319,27,5.968,117,1.133,138,3.19,213,4.46,220,4.992,468,7.084,469,5.878,470,3.786,471,6.086,472,6.618,473,3.04,474,3.808]],["t/63",[51,5.309,464,9.797,465,7.625,475,8.134,476,10.57,477,10.57,478,12.524,479,8.134,480,8.351,481,6.471,482,5.739,483,4.022,484,10.57]],["t/65",[12,3.181,29,5.539,44,1.76,49,7.44,51,7.066,116,4.589,196,2.96,211,3.658,304,5.539,474,3.646,475,7.617,485,9.898,486,4.441,487,3.939,488,3.338,489,3.302,490,4.072,491,4.236]],["t/67",[4,3.994,21,2.747,29,6.595,49,7.186,52,9.716,116,4.433,150,3.978,271,3.522,287,2.587,297,2.812,298,5.915,397,5.578,474,3.522,475,9.07,489,3.189,490,3.933,491,4.091,492,3.777,493,8.057,494,9.561,495,4.01]],["t/69",[3,4.56,4,5.55,8,5.66,29,4.823,126,3.37,137,3.519,256,6.479,258,3.291,259,1.626,451,6.479,473,2.535,496,4.68,497,5.519,498,7.016,499,5.519,500,7.989,501,5.277,502,4.943,503,8.62,504,4.714,505,4.614,506,4.647,507,7.264,508,4.985,509,6.341,510,2.517,511,3.921,512,6.81,513,4.75,514,4.329,515,6.81,516,8.62,517,8.62,518,7.989,519,7.574,520,4.463,521,3.719,522,8.62,523,8.62]],["t/71",[1,3.106,2,3.44,3,3.453,5,1.791,10,3.94,30,1.711,41,3.769,52,5.824,187,2.709,210,3.583,240,1.898,259,2.043,297,2.459,397,7.009,398,3.99,411,3.045,454,5.291,513,4.608,524,4.879,525,5.377,526,4.041,527,2.782,528,4.017,529,2.926,530,3.67,531,4.152,532,5.174,533,5.646,534,6.152,535,4.717,536,5.646,537,6.152,538,2.653,539,6.807]],["t/73",[4,4.049,5,2.076,12,3.115,19,5.019,21,2.785,118,3.617,137,3.957,197,4.516,209,3.942,259,2.242,391,2.766,489,3.233,540,8.168,541,5.76,542,6.451,543,8.517,544,4.868,545,6.451,546,5.656,547,6.206,548,8.168,549,6.544,550,6.365,551,7.459,552,4.812]],["t/75",[7,2.455,12,3.094,25,4.953,29,5.386,52,6.704,145,5.43,150,4.006,258,3.675,259,2.232,267,2.358,271,4.722,427,4.752,497,6.163,498,7.835,553,5.118,554,6.704,555,3.492,556,9.626,557,3.557,558,7.235,559,7.835,560,4.206,561,8.112,562,3.93]],["t/77",[51,5.153,73,3.662,196,3.679,287,2.777,315,5.184,391,3.511,527,4.093,563,7.402,564,5.987,565,5.987,566,7.402,567,8.646,568,5.009,569,7.896]],["t/79",[3,3.222,7,1.991,11,2.692,17,3.44,25,4.015,51,5.198,86,2.373,209,3.174,214,2.723,217,4.367,219,3.415,240,1.771,259,1.952,267,1.911,287,3.483,489,2.603,495,4.871,502,4.475,543,6.857,553,4.149,554,5.434,555,2.83,570,7.73,571,3.852,572,7.804,573,4.475,574,4.778,575,3.198,576,3.752,577,6.857,578,4.3,579,2.884,580,5.629,581,6.857,582,4.3,583,6.352,584,3.618,585,4.882,586,3.501,587,5.865,588,5.741,589,5.741,590,7.233,591,7.804,592,7.804,593,5.194,594,4.778,595,5.194]],["t/81",[11,3.73,106,5.251,137,4.415,259,2.394,287,2.927,487,5.051,489,3.608,521,4.666,596,7.302]],["t/83",[1,2.644,12,3.476,95,4.088,106,5.251,255,6.554,257,7.198,259,2.04,398,3.984,597,4.171,598,5.014,599,6.924]],["t/87",[7,2.696,44,2.227,258,4.035,259,1.993,267,2.589,320,5.658,600,6.224,601,9.797,602,6.612,603,9.797,604,6.342,605,9.797,606,6.224]],["t/89",[103,7.411,267,2.8,607,3.134,608,8.798]],["t/91",[72,3.217,118,3.667,208,2.897,255,5.956,266,4.223,320,5.261,513,5.416,538,3.118,576,3.175,607,2.695,608,7.564,609,6.736,610,4.88,611,5.028,612,3.778,613,5.986,614,4.966,615,3.598,616,9.11,617,5.19]],["t/93",[72,3.742,513,6.299,610,5.676,618,6.253]],["t/95",[538,3.627,619,5.201,620,5.25,621,3.339]],["t/97",[19,5.872,27,5.476,87,3.889,266,4.873,320,6.07]],["t/99",[577,10.212,621,3.394]],["t/101",[0,4.169,1,2.958,2,4.106,5,1.583,7,3.322,14,5.306,36,4.043,51,3.713,117,1.094,138,2.281,187,3.661,196,2.985,210,2.446,226,3.444,240,1.678,259,2.131,267,1.811,287,2,304,4.136,351,3.985,398,3.677,411,2.31,487,2.941,502,4.239,528,6.256,555,3.62,563,5.332,564,4.313,565,4.313,602,6.244,612,2.915,622,5.271,623,4.435,624,3.691,625,5.332,626,2.831,627,4.343,628,6.017,629,3.67,630,4.043,631,4.526,632,7.392,633,5.332]],["t/103",[2,4.072,4,4.135,10,3.601,21,3.46,38,3.635,40,5.192,209,4.897,258,4.596,259,2.447,462,5.676,513,5.454,532,6.124,589,7.282,634,5.828,635,7.44,636,5.093,637,5.125,638,6.588]],["t/105",[1,1.009,5,0.884,21,1.186,30,1.331,43,2.263,44,2.523,72,1.351,83,0.815,87,4.045,106,2.004,118,1.54,123,1.27,141,2.476,148,2.332,156,1.003,168,1.377,209,2.646,258,2.484,276,2.004,296,1.091,297,1.214,330,1.752,411,0.955,414,1.119,452,1.852,463,1.407,496,2.241,510,1.205,534,3.036,573,2.366,575,1.691,576,1.333,579,1.525,604,2.476,612,1.205,637,6.108,639,2.137,640,5.717,641,2.747,642,4.127,643,3.036,644,4.127,645,3.338,646,2.049,647,2.408,648,2.194,649,1.811,650,2.977,651,2.747,652,3.077,653,4.127,654,1.672,655,2.71,656,2.71,657,3.825,658,2.786,659,3.095,660,1.766,661,4.127,662,3.825,663,1.788,664,3.359,665,2.526,666,1.704,667,5.295,668,1.54,669,3.359,670,2.906,671,2.037,672,4.127,673,11.606,674,5.295,675,4.127,676,4.127,677,4.127,678,2.209,679,3.287,680,3.626,681,4.463,682,3.478,683,4.127,684,4.127,685,4.127,686,4.127,687,2.71,688,2.923,689,3.176,690,4.127,691,6.506,692,4.127,693,5.334,694,3.932,695,5.14,696,4.786,697,3.062,698,4.127,699,8.054,700,4.127,701,4.127,702,4.127,703,4.127,704,4.127,705,5.81,706,6.03,707,4.127,708,4.127,709,4.127,710,2.874,711,4.127,712,2.209,713,4.127,714,3.359,715,6.506,716,4.127,717,4.127,718,3.825,719,1.835,720,2.747,721,4.127,722,2.786,723,2.501,724,4.127,725,4.127,726,4.127,727,4.127,728,4.127]],["t/107",[21,3.698,118,4.131,259,2.088,560,4.838,670,4.945,729,7.842,730,11.071]],["t/109",[4,4.35,12,3.347,21,3.946,32,7.252,731,6.248,732,3.279,733,7.661,734,5.654,735,5.536,736,9.651,737,4.737,738,9.651,739,6.31]],["t/112",[21,3.639,87,3.992,148,3.23,156,2.277,196,3.786,258,3.577,259,1.767,490,3.854,611,3.929,637,6.027,645,3.883,658,7.858,671,4.625,740,4.302,741,7.21,742,5.568,743,8.106,744,4.981,745,5.677,746,7.042,747,9.369]],["t/114",[21,1.859,27,3.125,43,2.251,44,2.222,87,3.922,96,2.547,106,3.142,118,2.414,123,1.992,126,4.119,141,6.861,146,3.394,148,3.074,172,1.497,208,1.907,209,2.632,213,2.792,220,3.125,250,2.593,258,4.022,266,2.78,276,4.421,489,2.158,530,2.84,552,3.212,575,2.651,617,4.808,637,5.456,645,4.74,651,4.307,652,4.983,655,4.249,656,4.249,657,8.44,658,4.368,659,2.487,662,5.997,666,2.672,670,2.89,679,4.601,680,5.685,697,5.381,744,3.44,748,2.478,749,7.412,750,6.47,751,6.47,752,6.733,753,2.682,754,4.506,755,5.997,756,3.06,757,3.125,758,4.76,759,2.971,760,3.125,761,4.583,762,4.435,763,4.094,764,2.746,765,4.979]],["t/116",[2,4.072,12,3.869,87,3.395,148,3.31,196,2.96,213,4.271,220,4.78,258,3.779,304,5.539,315,5.001,487,3.939,602,6.192,627,4.307,637,6.234,645,4.103,658,6.683,748,3.791,766,6.337,767,5.828]],["t/118",[4,4.077,32,6.797,87,3.347,148,3.289,153,5.505,196,2.918,213,4.211,220,4.714,258,3.726,637,6.181,645,4.948,658,6.59,736,9.046,737,4.44,738,9.046,739,5.915,748,3.739,766,6.249,767,5.747,768,5.55,769,5.695]],["t/120",[87,3.598,148,3.18,213,4.527,220,5.066,654,4.251,658,7.083,679,5.3,746,7.885,768,5.966,770,5.577,771,7.431,772,8.288,773,8.539,774,6.423]],["t/122",[10,3.277,20,4.06,117,1.245,148,3.173,221,4.304,611,5.216,658,6.081,694,5.544,740,4.136,746,6.77,771,6.38,772,8.972,775,2.637,776,12.079,777,10.526,778,6.77,779,8.349,780,8.349,781,2.279,782,7.915,783,5.699,784,7.116,785,4.635,786,4.822]],["t/124",[10,3.576,47,4.309,148,3.058,178,4.747,213,4.241,220,4.747,258,3.752,320,6.417,584,4.557,611,4.122,658,8.094,768,5.589,775,2.877,776,8.636,782,8.636,787,4.122,788,6.148,789,9.829,790,6.017,791,9.829]],["t/127",[85,3.278,243,2.414,609,7.944,658,9.178,667,9.435,679,6.868,792,6.283,793,9.307,794,6.713,795,9.768,796,5.539,797,9.158,798,9.307,799,9.629]],["t/129",[44,1.552,97,2.693,117,1.22,122,3.563,138,2.693,241,4.704,264,4.066,287,2.362,463,2.976,483,3.321,621,2.549,650,6.295,658,5.892,735,4.64,740,5.628,748,3.343,800,11.131,801,5.4,802,3.019,803,5.981,804,7.354,805,6.895,806,8.727,807,11.131,808,6.182,809,2.842,810,5.73,811,6.559,812,5.4,813,6.077,814,2.943,815,7.354,816,3.563,817,4.672,818,4.463,819,5.289,820,3.118]],["t/131",[10,2.444,20,4.214,27,3.245,44,2.353,73,1.999,97,3.587,113,3.92,117,1.025,194,3.534,243,1.742,339,3.042,412,2.291,521,4.034,607,1.842,658,6.312,660,2.875,667,5.469,673,6.227,719,2.988,757,3.245,799,4.759,809,3.044,821,7.369,822,2.693,823,9.349,824,5.469,825,5.308,826,6.719,827,5.05,828,5.662,829,10.752,830,3.92,831,3.28,832,4.937,833,7.616,834,2.507,835,6.719,836,6.719,837,4.412,838,6.227,839,6.719,840,3.622,841,6.719,842,9.349,843,6.719,844,6.719,845,5.469,846,6.719,847,6.719,848,6.227,849,6.719,850,6.719,851,6.719,852,6.719,853,6.227,854,6.719,855,6.719,856,6.719,857,6.719,858,6.227,859,6.719,860,6.719,861,4.031,862,4.302,863,6.719]],["t/133",[5,1.929,20,4.06,21,2.588,47,3.237,86,2.739,116,4.176,117,1.363,203,5.756,235,4.327,243,2.945,263,2.801,611,5.477,741,6.932,746,10.119,864,9.007,865,9.007,866,5.05,867,2.78,868,4.422,869,5.081,870,5.405,871,5.001,872,9.007]],["t/135",[38,3.741,117,1.117,156,3.312,866,4.529,873,5.275,874,5.53,875,3.282,876,8.047,877,5.7,878,6.603,879,5.891,880,6.78,881,6.112,882,5.146,883,9.441,884,9.441]],["t/137",[47,4.011,96,4.393,117,1.223,235,5.361,611,4.68,654,4.522,753,4.626]],["t/139",[44,2.065,148,1.991,156,2.515,172,2.395,218,2.723,240,1.771,267,2.535,520,6.014,555,2.83,579,2.884,626,2.989,663,3.381,671,5.109,697,3.672,719,3.47,781,1.974,832,4.121,866,4.602,873,6.404,877,4.367,878,5.058,885,6.838,886,4.333,887,6.404,888,5.747,889,5.741,890,3.618,891,3.81,892,4.041,893,7.233,894,7.233,895,4.268,896,4.268,897,10.204,898,6.857,899,6.165,900,7.233,901,6.165,902,7.233,903,4.937,904,6.165,905,6.165,906,3.896]],["t/141",[5,1.71,6,4.057,10,2.904,20,4.735,44,2.305,97,2.463,116,4.871,117,0.875,148,2.036,156,2.553,203,3.518,214,2.785,221,3.814,267,2.573,510,2.331,514,4.009,520,4.133,549,5.389,719,4.671,746,5.999,748,3.057,832,4.215,870,4.789,871,4.431,873,5.44,899,6.306,901,6.306,907,7.2,908,2.95,909,4.938,910,4.789,911,5.174,912,3.756,913,7.398,914,3.458,915,8.853,916,7.398,917,7.398,918,9.737,919,7.398,920,7.398,921,7.013,922,9.737]],["t/143",[10,3.271,44,2.521,86,2.734,90,3.301,95,2.401,96,2.501,97,2.774,116,4.168,117,0.985,126,2.484,156,3.104,243,1.648,266,2.73,411,1.47,584,2.946,626,3.443,648,6.363,694,4.388,732,2.83,781,1.607,802,3.109,840,3.425,866,2.825,873,3.29,882,4.541,899,5.019,923,1.668,924,8.989,925,4.5,926,6.353,927,6.353,928,11.342,929,11.342,930,6.353,931,8.989,932,6.353,933,6.353,934,6.353,935,6.353,936,6.353,937,4.289,938,10.432,939,5.354,940,6.353,941,6.353,942,3.21,943,5.582,944,6.353,945,5.171,946,6.353,947,6.353,948,6.353,949,6.353,950,6.353,951,6.353]],["t/145",[95,3.85,97,3.143,116,4.723,117,1.117,529,3.564,626,5.221,648,5.415,877,5.7,923,2.675,937,6.877,943,8.95,952,7.494,953,4.413,954,7.348,955,4.306,956,10.186]],["t/147",[5,1.905,10,3.236,44,2.311,87,3.864,97,2.745,117,0.975,172,2.058,203,3.92,243,2.922,263,3.503,483,3.384,538,2.821,626,3.406,748,3.406,781,2.25,866,3.955,878,5.765,891,4.342,923,2.336,957,3.373,958,11.46,959,6.193,960,11.46,961,5.919,962,10.441,963,5.336,964,4.976,965,8.243]],["t/149",[11,3.592,116,4.828,255,6.31,573,5.971,589,7.661,611,4.367,746,7.827,955,4.402,966,7.827,967,6.514,968,9.651,969,5.199,970,9.651,971,5.536,972,9.15,973,7.137]],["t/151",[3,3.817,22,3.518,25,4.757,43,3.216,73,2.751,87,3.171,116,5.836,117,1.013,262,4.308,492,3.653,510,2.7,538,2.933,611,5.279,633,6.669,752,5.443,756,4.373,803,6.336,867,3.563,871,6.409,875,2.979,913,8.569,974,9.245,975,9.245,976,5.85,977,6.549,978,2.918,979,9.245]],["t/153",[118,4.035,209,4.399,619,4.92,637,5.6,666,5.242,667,8.803,775,3.166,816,4.415,980,4.706,981,10.024]],["t/155",[694,5.627,982,9.713,983,11.527]],["t/158",[5,1.325,27,2.987,38,2.271,44,1.568,47,3.694,72,4.547,73,2.625,75,3.334,86,3.855,88,2.868,94,2.974,111,9.527,112,5.732,114,6.861,115,3.042,117,0.678,118,2.308,138,1.909,139,1.819,155,3.163,187,2.003,250,2.479,263,1.923,267,2.16,411,2.041,538,1.962,615,2.264,652,2.925,664,5.034,669,5.034,760,2.987,775,1.81,868,4.329,869,3.488,887,3.827,890,2.868,982,8.662,984,13.673,985,3.081,986,4.061,987,3.151,988,7.432,989,5.057,990,8.819,991,2.714,992,8.174,993,2.385,994,3.786,995,6.185,996,5.034,997,2.203,998,1.815,999,6.968,1000,6.185]],["t/160",[73,3.099,87,3.571,637,5.392,693,7.738,694,6.06,1001,9.651,1002,6.931,1003,6.469,1004,6.128,1005,10.413,1006,10.413]],["t/162",[72,4.118,87,3.653,258,4.066,470,3.263,576,3.441,637,5.515,645,4.415,664,8.669,671,5.258,693,6.214,1007,7.835,1008,4.415]],["t/164",[3,4.176,38,3.714,138,3.121,209,4.113,250,4.053,437,4.91,619,4.6,652,4.783,664,8.231,666,5.036,760,4.884,775,3.57,978,3.192,1007,8.973,1009,4.344,1010,7.042]],["t/166",[0,3.413,1,2.122,2,3.572,3,2.499,5,2.377,12,1.945,16,3.386,19,4.496,20,5.001,21,1.739,30,1.777,35,3.667,39,3.631,43,2.105,44,1.076,86,1.84,93,2.819,117,0.952,126,2.366,139,3.263,240,1.374,259,1.638,287,1.637,339,2.74,418,3.039,463,2.961,483,3.304,490,2.489,502,3.47,519,5.317,525,3.004,529,2.118,576,1.955,604,3.631,607,1.659,621,1.767,636,4.468,668,2.258,737,2.753,742,7.485,761,4.286,912,4.086,953,2.622,987,2.162,1011,3.154,1012,5.609,1013,4.803,1014,4.086,1015,2.987,1016,4.781,1017,3.785,1018,3.923,1019,2.806,1020,5.317,1021,3.5,1022,5.609,1023,5.317,1024,4.598,1025,4.335,1026,5.317,1027,3.785,1028,2.938,1029,3.441,1030,3.154,1031,5.066,1032,4.925,1033,3.057,1034,4.781,1035,3.5,1036,5.554,1037,3.667,1038,5.317,1039,5.317,1040,5.317,1041,4.657,1042,5.099,1043,4.452,1044,6.051,1045,3.923]],["t/168",[3,2.195,5,1.139,7,1.356,20,5.025,30,1.617,33,1.745,35,5.712,44,1.676,75,2.866,86,1.617,93,2.477,117,1.033,126,2.079,138,1.641,139,2.323,153,2.999,168,1.773,194,2.986,240,1.207,264,2.477,265,2.887,267,2.309,427,2.625,463,1.813,470,3.196,472,3.404,473,1.564,510,2.753,534,3.911,541,3.16,557,1.965,576,1.718,625,3.835,647,3.102,648,2.826,660,2.275,665,3.255,735,2.826,742,7.19,753,2.204,759,2.441,861,3.19,891,2.596,909,3.29,911,3.446,912,2.502,997,1.894,998,2.766,1013,5.273,1014,2.502,1030,2.771,1032,4.327,1033,2.686,1034,4.2,1046,9.231,1047,4.672,1048,6.941,1049,3.049,1050,7.672,1051,6.43,1052,3.404,1053,6.43,1054,6.657,1055,3.551,1056,3.102,1057,4.928,1058,5.317,1059,4.091,1060,5.317,1061,5.317,1062,3.577,1063,4.091,1064,3.29,1065,4.2,1066,2.625,1067,3.644,1068,4.928,1069,2.736,1070,2.67,1071,2.771,1072,2.686,1073,5.317,1074,3.404,1075,3.075,1076,5.317,1077,5.317,1078,5.317,1079,4.48,1080,5.317,1081,3.766,1082,3.19,1083,3.222,1084,7.447,1085,3.911,1086,4.672,1087,5.317,1088,5.317]],["t/170",[1,0.991,3,4.331,4,1.694,19,4.123,20,4.08,21,1.165,22,1.543,30,0.83,43,1.411,44,1.865,48,1.574,72,1.327,75,2.186,94,1.368,117,0.445,126,4.295,139,1.193,178,1.958,196,1.213,206,4.355,209,1.649,255,2.457,259,0.765,267,0.993,288,2.325,339,2.905,421,1.523,463,1.383,470,1.242,472,4.108,474,1.494,496,2.202,529,1.419,535,2.287,549,2.738,554,2.824,573,2.325,649,1.78,660,1.735,665,3.928,668,1.513,719,1.803,742,7.614,748,1.553,773,3.301,774,2.483,792,4.332,809,1.32,821,2.779,861,2.433,875,2.068,886,2.251,903,2.566,910,2.433,912,1.908,967,2.537,969,2.025,991,1.78,1013,3.766,1030,4.149,1031,3.744,1037,2.457,1046,7.152,1048,5.638,1049,2.325,1050,3.301,1062,2.905,1065,5.069,1068,3.758,1083,2.457,1089,3.813,1090,2.013,1091,2.269,1092,2.925,1093,3.204,1094,4.055,1095,6.417,1096,4.055,1097,1.662,1098,3.459,1099,4.271,1100,4.055,1101,4.055,1102,4.055,1103,3.301,1104,2.779,1105,4.055,1106,5.984,1107,3.417,1108,5.947,1109,4.108,1110,2.566,1111,3.758,1112,3.417,1113,5.947,1114,2.366,1115,2.388,1116,3.563,1117,4.055,1118,2.663,1119,4.055,1120,2.202,1121,7.782,1122,3.758,1123,4.055,1124,4.055,1125,1.918,1126,4.055,1127,5.728,1128,5.947,1129,5.947,1130,4.938,1131,2.251,1132,2.738,1133,2.983,1134,2.663,1135,2.566,1136,4.055,1137,3.301,1138,4.055,1139,3.563,1140,2.287,1141,3.204,1142,2.699,1143,2.872,1144,6.417,1145,4.055,1146,3.366,1147,2.983,1148,2.872,1149,2.983,1150,2.738,1151,3.679,1152,4.055,1153,4.055,1154,3.204,1155,4.055,1156,2.699,1157,3.301,1158,2.983,1159,2.113,1160,2.779,1161,4.055,1162,2.345,1163,3.758,1164,3.563,1165,3.758,1166,3.758,1167,3.204,1168,2.537,1169,2.345]],["t/172",[5,1.482,20,3.118,33,3.131,95,2.615,117,1.197,139,2.034,169,3.147,218,3.81,239,3.272,240,2.166,287,1.872,463,2.359,470,3.345,510,2.786,576,3.082,589,5.089,590,6.412,607,1.897,625,6.882,630,3.783,649,3.036,861,4.151,867,2.135,997,3.398,998,3.204,1013,5.567,1024,3.132,1030,3.605,1038,8.382,1039,6.078,1046,9.299,1048,6.078,1054,8.039,1070,3.474,1082,4.151,1084,5.465,1085,5.089,1097,2.835,1121,4.9,1134,4.542,1140,3.902,1170,2.948,1171,6.918,1172,5.829,1173,6.918,1174,6.643,1175,6.264,1176,5.323,1177,2.295,1178,5.199,1179,5.089,1180,3.812,1181,3.516,1182,4.741,1183,6.412,1184,5.465,1185,4.001,1186,5.323,1187,3.323,1188,6.078]],["t/174",[4,2.14,5,1.097,10,1.864,11,1.767,15,3.859,20,4.155,30,1.048,33,1.681,38,1.881,39,3.074,40,2.687,44,0.911,48,1.989,73,1.524,75,4.97,115,2.65,117,1.263,126,2.003,194,1.936,221,2.448,239,3.634,240,1.744,267,1.255,287,2.495,297,1.506,320,5.483,463,1.747,470,1.569,510,1.496,525,3.814,529,1.792,575,2.099,576,3.309,607,2.528,612,1.496,625,7.389,635,3.85,660,3.288,742,7.305,861,3.074,867,1.581,875,1.65,886,2.844,891,2.501,912,4.338,969,2.558,998,1.503,1014,2.41,1024,4.969,1043,9.043,1046,4.047,1050,9.727,1054,4.316,1055,2.895,1062,2.319,1070,2.573,1083,3.104,1086,4.501,1090,3.814,1097,2.099,1103,4.169,1140,2.889,1181,5.206,1189,3.458,1190,5.122,1191,3.363,1192,9.494,1193,4.316,1194,5.122,1195,3.016,1196,3.567,1197,4.169,1198,5.187,1199,3.85,1200,2.723,1201,6.474,1202,5.122,1203,4.299,1204,2.091,1205,4.194,1206,4.748,1207,3.942,1208,2.341,1209,3.85,1210,5.122,1211,2.157,1212,5.122,1213,2.866]],["t/176",[3,4.681,4,2.05,7,1.252,13,2.889,19,4.652,20,4.518,23,3.313,25,2.525,33,1.611,35,2.974,43,1.707,44,1.597,117,1.181,126,4.432,139,2.642,153,5.067,187,1.589,206,2.684,214,1.712,221,3.555,259,0.925,263,1.526,265,2.664,267,1.202,465,3.54,502,2.814,510,2.623,538,1.557,606,2.889,607,1.345,611,3.12,647,2.863,649,2.154,742,7,797,3.877,874,2.664,890,2.275,891,2.396,923,1.289,998,1.44,1013,6.087,1018,3.181,1021,2.838,1028,2.383,1037,2.974,1046,3.877,1051,3.994,1062,2.222,1069,4.622,1072,3.758,1081,3.476,1084,3.877,1106,3.688,1112,4.135,1127,3.105,1129,4.548,1130,3.776,1180,2.704,1181,2.494,1208,2.243,1214,3.876,1215,3.776,1216,3.61,1217,4.312,1218,2.574,1219,3.994,1220,4.312,1221,13.047,1222,3.54,1223,4.548,1224,4.907,1225,4.907,1226,4.907,1227,3.07,1228,4.135,1229,4.907,1230,4.907,1231,2.383,1232,3.688,1233,3.313,1234,3.105,1235,3.877,1236,4.548,1237,4.548,1238,3.476,1239,2.838,1240,4.312,1241,4.907,1242,6.268,1243,7.438,1244,4.312,1245,4.421,1246,3.994,1247,3.877,1248,2.79,1249,4.712,1250,3.417,1251,3.688,1252,3.181,1253,2.509,1254,4.907,1255,3.994]],["t/178",[3,3.5,5,0.774,7,1.881,13,2.129,19,3.031,20,4.197,21,1.682,25,1.86,30,0.74,44,1.656,48,1.404,75,1.949,76,2.842,117,1.021,126,3.314,139,3.488,153,3.302,163,1.719,196,1.081,209,1.471,221,1.728,226,3.436,229,1.233,235,1.737,259,0.682,265,4.004,267,2.441,397,2.11,452,1.622,470,2.597,490,1.487,492,1.428,495,1.516,496,1.963,502,2.073,510,1.056,532,2.237,557,1.336,560,1.58,576,3.008,607,2.022,612,1.056,613,1.805,624,3.683,625,2.608,636,1.86,665,4.515,742,7.305,764,1.535,771,5.224,774,2.214,862,2.315,867,1.116,875,1.165,903,4.667,912,2.755,923,0.95,978,1.141,987,1.292,1013,1.71,1014,1.701,1016,2.856,1021,2.091,1024,1.637,1029,2.056,1030,1.884,1036,1.977,1046,2.856,1047,3.177,1049,2.073,1050,6.003,1054,3.047,1062,1.637,1065,2.856,1066,1.785,1082,2.169,1083,3.547,1084,2.856,1090,1.795,1103,2.943,1106,2.718,1112,3.047,1113,3.351,1118,2.374,1120,1.963,1121,4.146,1127,2.288,1133,2.66,1135,2.288,1140,2.039,1146,1.897,1148,2.561,1163,3.351,1164,3.177,1165,3.351,1166,3.351,1167,2.856,1181,1.838,1186,2.782,1187,3.543,1192,11.392,1195,2.129,1220,5.143,1222,2.608,1231,1.756,1234,3.704,1236,5.425,1255,4.765,1256,2.608,1257,2.407,1258,3.616,1259,3.616,1260,2.262,1261,2.478,1262,3.616,1263,2.943,1264,2.943,1265,3.748,1266,2.237,1267,2.149,1268,2.782,1269,3.047,1270,7.857,1271,1.897,1272,2.478,1273,2.289,1274,2.782,1275,3.351,1276,2.478,1277,3.091,1278,1.909,1279,3.357,1280,4.933,1281,1.977,1282,2.66,1283,2.023,1284,3.616,1285,3.616,1286,1.909,1287,3.616,1288,3.616,1289,3.616,1290,2.943,1291,3.616,1292,2.782,1293,3.616,1294,2.856,1295,2.561,1296,3.351,1297,3.616,1298,3.177,1299,3.616,1300,3.622,1301,3.177,1302,2.149,1303,3.616,1304,2.288,1305,3.047,1306,3.047,1307,1.963,1308,1.827,1309,3.616,1310,3.616,1311,4.4]],["t/180",[3,3.743,7,2.312,19,4.694,93,4.224,126,3.544,139,3.669,153,6.432,194,3.427,259,1.71,265,6.773,473,2.666,607,2.485,742,5.388,885,5.338,912,4.266,923,2.381,1056,5.29,1140,5.113,1195,7.345,1234,5.736,1235,9.009,1270,8.403,1280,7.64,1308,6.303,1312,5.671,1313,9.066]],["t/182",[3,4.176,15,5.079,126,3.954,495,4.241,742,6.01,1234,6.398,1269,8.522,1279,5.799,1314,10.112,1315,10.112,1316,10.112,1317,10.112,1318,10.112,1319,9.373,1320,9.373,1321,10.112,1322,7.44,1323,9.373,1324,9.373,1325,9.373]],["t/184",[3,2.684,20,2.93,27,4.412,47,3.283,48,2.524,87,3.93,116,3.014,117,1.001,126,2.541,140,4.689,169,2.957,172,2.114,210,2.151,213,4.944,219,2.145,220,5.533,221,3.106,243,1.686,258,2.482,411,1.504,463,2.217,470,2.799,471,3.827,475,5.002,490,2.674,491,4.52,531,3.227,584,3.014,607,3.31,611,5.063,612,1.898,761,6.471,762,7.853,771,4.604,774,3.98,788,7.168,875,2.944,903,4.113,923,1.707,955,4.844,978,2.052,1021,6.109,1151,3.728,1214,3.388,1273,2.541,1280,5.478,1326,5.712,1327,3.637,1328,6.025,1329,6.5,1330,3.76,1331,3.688,1332,3.173,1333,9.136,1334,4.268,1335,6.5,1336,5.478,1337,6.5]],["t/187",[22,3.811,27,3.589,87,2.549,96,2.926,117,1.098,164,3.034,186,3.011,213,4.322,220,3.589,227,4.459,229,2.534,243,1.927,463,2.534,469,4.226,470,2.276,481,4.55,482,5.439,505,3.978,506,4.006,514,3.732,568,3.628,737,3.38,781,2.534,910,4.459,970,6.888,971,3.951,1093,5.871,1160,5.093,1177,3.759,1307,4.035,1332,5.532,1338,7.431,1339,7.431,1340,12.661,1341,5.467,1342,6.888,1343,7.431,1344,4.126,1345,5.175,1346,11.332,1347,4.817,1348,5.719,1349,4.191,1350,7.431,1351,4.55,1352,4.88,1353,7.431,1354,7.431,1355,4.598,1356,7.431,1357,5.871,1358,7.431,1359,6.667,1360,6.53]],["t/189",[236,6.692,360,8.129,506,5.83,598,5.014,621,3.158,961,7.198,1233,7.302,1361,8.129,1362,7.01,1363,10.024,1364,6.924]],["t/191",[29,4.441,44,2.58,138,2.449,168,2.647,172,2.422,215,5.439,216,5.454,218,2.769,263,2.468,360,7.866,506,4.278,598,3.68,607,2.176,731,4.762,827,5.965,873,4.11,882,4.01,953,3.439,1121,5.621,1180,4.373,1332,5.109,1361,5.965,1365,10.492,1366,7.356,1367,6.688,1368,5.621,1369,9.16,1370,4.631,1371,7.936,1372,5.144,1373,5.358,1374,5.144,1375,7.356]],["t/193",[29,3.507,30,1.822,44,2.597,117,0.687,126,2.45,140,4.521,164,2.559,172,1.45,236,3.878,276,3.043,414,1.7,469,3.564,490,2.578,506,6.077,508,3.625,538,1.989,553,3.332,564,3.657,598,2.906,612,2.6,652,4.211,668,2.339,679,5.696,732,1.973,753,3.691,796,2.995,821,4.296,830,3.657,873,3.246,997,2.232,1066,3.094,1082,3.761,1268,4.823,1312,3.921,1332,3.06,1349,3.535,1367,5.282,1376,4.823,1377,7.469,1378,6.268,1379,6.268,1380,4.232,1381,7.503,1382,4.365,1383,6.268,1384,6.268,1385,4.521,1386,3.837,1387,4.521,1388,5.282,1389,6.268,1390,5.809,1391,5.102,1392,6.268,1393,3.966,1394,5.507,1395,7.823,1396,3.564,1397,4.521,1398,3.027,1399,3.06,1400,6.268,1401,4.733]],["t/195",[25,4.988,38,3.56,44,2.489,47,3.484,138,2.991,562,3.957,578,5.341,654,3.928,873,5.019,1332,4.732,1361,7.285,1365,8.168,1369,7.131,1374,6.283,1394,8.517,1402,5.816,1403,6.365,1404,6.206,1405,8.984,1406,9.391]],["t/198",[35,6.173,44,1.811,47,3.661,95,4.63,187,3.299,360,7.656,635,7.656,998,2.989,1114,5.943,1177,3.379,1406,10.379,1407,10.186,1408,10.186,1409,10.186,1410,10.186,1411,7.839]],["t/200",[56,8.697,198,5.943,497,6.337,511,5.477,538,3.14,875,3.189,939,8.341,955,4.184,1070,4.971,1365,10.146,1406,7.82,1412,10.251,1413,8.697,1414,9.174,1415,8.76,1416,9.174]],["t/202",[29,3.689,31,4.329,38,3.388,43,2.293,44,2.543,94,2.223,138,3.285,140,4.755,267,1.615,412,2.248,473,1.939,488,2.223,506,4.973,508,5.336,510,1.925,511,4.842,538,2.091,553,3.505,565,3.846,639,4.777,648,3.505,654,2.671,670,2.944,731,3.955,802,2.28,814,2.223,873,3.414,955,3.9,998,1.934,1024,2.985,1327,5.162,1332,4.504,1361,8,1375,6.11,1376,5.073,1377,4.755,1381,5.555,1394,9.352,1397,4.755,1406,7.289,1415,4.451,1416,6.11,1417,3.918,1418,2.671,1419,4.755,1420,5.792,1421,3.218,1422,4.85,1423,6.592,1424,8.927,1425,5.366,1426,6.592,1427,5.208,1428,5.366,1429,6.11,1430,5.555,1431,3.087]],["t/204",[31,5.557,44,1.505,95,3.199,452,3.797,470,2.593,473,2.489,496,4.595,506,6.88,511,3.85,538,2.685,594,5.182,639,5.652,720,5.633,739,6.614,767,4.983,769,4.938,787,3.549,814,2.854,914,3.667,955,3.578,998,2.483,1024,3.832,1055,3.189,1177,2.808,1406,8.623,1415,5.714,1421,4.132,1432,8.623,1433,7.437,1434,7.844,1435,6.686,1436,8.463,1437,7.844,1438,7.437,1439,5.129,1440,5.633,1441,5.355,1442,6.226,1443,3.564,1444,6.889]],["t/206",[22,3.201,29,4.707,31,7.139,42,5.766,97,2.596,263,2.616,267,2.663,360,6.323,506,4.535,573,4.824,576,2.718,594,5.15,914,3.645,937,5.68,939,7.089,978,2.655,998,3.534,1024,3.809,1066,4.153,1281,4.601,1327,4.707,1355,5.205,1419,8.689,1427,6.646,1445,8.389,1446,5.098,1447,8.413,1448,7.797,1449,4.225,1450,8.413,1451,6.847,1452,6.847,1453,6.646,1454,8.413,1455,4.784,1456,6.646,1457,4.866,1458,8.413,1459,7.392,1460,6.474]],["t/208",[44,1.893,156,3.057,1249,5.587,1461,10.651,1462,10.651,1463,10.651,1464,10.651,1465,4.8,1466,8.196,1467,12.58,1468,8.196]],["t/210",[6,2.889,10,3.019,17,2.505,29,3.18,30,1.163,38,2.087,44,2.557,138,1.754,140,4.1,153,3.206,155,2.906,172,1.315,206,3.108,222,3.232,470,1.741,482,5.321,506,4.473,508,6.232,510,1.66,511,4.902,518,5.267,553,3.021,562,2.32,594,5.08,607,1.558,621,1.66,639,2.943,641,3.783,652,2.688,668,2.12,786,3.042,802,1.966,873,2.943,875,1.831,882,2.871,896,3.108,937,5.602,998,1.667,1066,4.096,1125,2.688,1177,4.286,1250,3.958,1332,2.774,1361,4.272,1370,3.316,1376,4.373,1377,4.1,1381,4.789,1385,5.985,1415,5.602,1422,4.181,1427,4.49,1428,4.626,1440,3.783,1441,3.596,1446,3.444,1448,5.267,1449,2.854,1451,4.626,1457,3.287,1469,8.297,1470,6.992,1471,2.821,1472,8.297,1473,5.25,1474,5.267,1475,3.684,1476,4.49,1477,2.943,1478,3.042,1479,4.626,1480,3.18,1481,4.49,1482,8.611,1483,3.516]],["t/212",[23,6.201,31,6.031,40,4.818,44,1.633,47,3.301,56,8.07,95,3.472,178,4.436,213,3.963,470,2.814,492,3.629,511,4.178,538,3.647,576,2.967,639,4.756,814,3.098,969,4.586,998,3.373,1250,6.396,1406,7.256,1413,8.07,1415,6.201,1421,4.484,1439,5.566,1442,6.757,1443,3.867,1444,7.476,1468,7.068,1484,7.256,1485,5.954,1486,6.506,1487,5.954]],["t/214",[38,2.758,43,2.613,44,2.573,47,2.699,48,2.916,138,2.318,140,5.418,263,2.335,412,2.561,457,4.527,502,5.786,506,6.142,564,5.887,576,2.426,648,3.993,764,3.188,834,2.802,873,3.889,1066,3.708,1332,3.667,1355,4.647,1361,9.155,1369,5.526,1372,4.869,1373,5.071,1376,5.78,1377,5.418,1381,6.329,1391,6.113,1419,8.218,1432,5.934,1446,4.552,1468,7.764,1477,5.224,1488,5.418,1489,5.292,1490,5.23,1491,7.511,1492,6.961]],["t/217",[1334,7.27,1493,13.605,1494,10.261,1495,11.071,1496,11.071,1497,11.071]],["t/219",[1494,9.441,1498,13.138,1499,10.186,1500,10.186,1501,10.186,1502,10.186,1503,10.186,1504,10.186,1505,10.186,1506,10.186,1507,10.186,1508,10.186,1509,7.215,1510,10.186,1511,12.25,1512,8.95]],["t/221",[1513,13.11,1514,11.433,1515,11.433]],["t/223",[29,4.945,30,1.809,172,2.045,490,3.635,506,4.764,576,2.855,594,5.41,639,4.576,896,4.833,914,3.829,978,3.542,998,2.593,1097,3.621,1159,4.605,1391,7.193,1419,6.375,1427,6.982,1432,6.982,1435,6.982,1445,8.585,1446,6.799,1468,8.634,1477,4.576,1516,6.982,1517,8.837,1518,5.728,1519,4.984,1520,8.837,1521,5.025,1522,8.837,1523,8.837,1524,8.837,1525,8.837,1526,8.837,1527,8.191]],["t/225",[44,2.545,47,4.268,198,4.032,427,4.032,506,4.403,538,2.591,553,4.342,639,4.229,654,3.31,732,2.572,737,3.715,760,3.944,786,4.372,822,3.273,873,4.229,890,3.787,914,3.539,937,7.2,1066,4.032,1332,3.987,1348,6.285,1415,5.514,1432,6.453,1435,6.453,1446,4.949,1477,4.229,1478,4.372,1528,5.436,1529,8.167,1530,4.766,1531,6.883,1532,8.167,1533,7.57,1534,7.177,1535,5.892,1536,7.177,1537,7.57,1538,7.57,1539,7.57]],["t/227",[29,4.158,30,2.05,44,2.593,47,2.671,138,2.293,198,3.668,263,3.115,506,5.4,510,2.17,515,5.871,564,4.336,586,3.334,654,3.011,731,4.459,767,4.375,833,5.264,873,3.848,914,4.34,1008,3.08,1159,3.873,1177,2.465,1207,5.719,1211,3.129,1327,6.341,1332,3.628,1361,5.585,1369,5.467,1370,4.336,1385,5.361,1419,5.361,1424,5.467,1432,5.871,1434,6.888,1435,5.871,1466,5.719,1468,7.709,1477,3.848,1478,3.978,1531,6.262,1534,6.53,1540,6.888,1541,7.431,1542,6.53,1543,6.53]],["t/229",[5,2.225,44,2.612,47,3.734,215,5.378,263,2.44,506,4.23,538,2.49,564,4.579,565,4.579,752,4.62,759,3.604,816,3.204,831,3.831,862,5.024,873,4.063,914,3.4,1332,5.072,1419,8.401,1432,6.2,1435,6.2,1466,6.039,1468,6.039,1473,4.965,1477,4.063,1485,5.087,1530,4.579,1536,6.895,1542,6.895,1543,6.895,1544,7.847,1545,7.847,1546,5.024,1547,4.116,1548,7.847,1549,7.847]],["t/231",[5,2.03,34,4.285,44,2.619,47,2.462,76,3.326,106,3.326,138,2.114,263,2.13,510,2.767,514,4.759,575,2.807,612,2,618,5.182,870,4.11,873,3.547,879,3.962,914,4.106,937,4.625,978,3.429,1115,4.033,1159,3.57,1177,3.144,1180,3.774,1250,4.77,1370,3.997,1427,5.412,1435,5.412,1457,3.962,1466,5.271,1468,7.292,1483,4.238,1492,6.349,1527,6.349,1533,8.782,1536,8.326,1537,6.349,1538,6.349,1539,6.349,1543,6.019,1550,6.85,1551,6.85,1552,4.334,1553,6.971,1554,6.349,1555,5.271,1556,6.85]],["t/233",[5,1.846,30,2.63,44,2.587,320,4.614,472,5.519,575,3.532,648,4.582,761,7.822,873,4.463,1332,4.208,1372,7.158,1376,6.633,1377,6.218,1391,7.016,1427,6.81,1479,7.016,1490,6.003,1530,5.029,1547,4.522,1557,8.725,1558,7.989,1559,6.633,1560,8.62,1561,8.62,1562,7.574]],["t/235",[0,4.897,1,2.122,2,4.177,3,4.193,4,4.242,8,6.668,12,3.566,26,3.114,29,4.859,32,4.214,37,4.028,44,1.076,47,2.175,48,2.35,51,4.361,52,4.214,115,2.087,126,3.395,209,3.531,256,4.548,258,2.31,259,1.141,262,2.819,351,3.262,473,1.78,488,2.041,513,3.334,520,4.496,552,3.004,561,5.099,564,3.531,573,3.47,576,1.955,583,4.925,636,3.114,678,3.239,731,3.631,766,5.559,969,3.022,978,1.91,987,2.162,1013,4.803,1062,2.74,1121,4.286,1148,4.286,1158,4.452,1168,3.785,1184,6.86,1195,3.563,1264,4.925,1272,4.147,1273,2.366,1348,4.657,1418,3.518,1440,4.028,1546,3.874,1563,6.051,1564,5.609,1565,3.973,1566,7.632,1567,6.051,1568,6.051,1569,6.051,1570,5.609,1571,5.609,1572,6.051,1573,8.683,1574,5.099,1575,6.051,1576,5.609,1577,3.667,1578,4.657,1579,3.923,1580,5.609,1581,5.099,1582,4.452,1583,6.051,1584,3.973,1585,5.609,1586,3.039,1587,6.051,1588,5.609,1589,3.785,1590,5.317,1591,4.286,1592,5.609,1593,4.925]],["t/238",[3,4.846,4,4.903,17,4.186,19,4.917,107,6.986,138,2.93,206,5.193,209,4.774,259,1.791,473,2.793,498,7.729,568,4.636,576,3.068,626,3.637,1024,4.3,1216,8.635,1360,8.344,1594,9.496,1595,8.344,1596,3.509,1597,9.496,1598,8.002,1599,3.921,1600,9.496,1601,6.32]],["t/240",[3,5.704,4,4.803,20,4.14,23,6.201,126,4.495,209,4.676,257,6.113,575,4.711,598,5.33,831,4.484,907,6.295,963,5.511,1013,5.437,1018,5.954,1019,4.258,1097,3.764,1139,8.07,1250,6.396,1322,8.458,1443,3.867,1602,9.185,1603,8.513]],["t/242",[3,5.69,4,4.577,8,7.195,12,3.521,18,5.749,19,4.409,95,3.219,222,4.842,257,5.667,259,1.606,491,3.644,595,5.667,633,6.142,648,4.527,729,6.031,766,7.015,1250,5.93,1360,7.482,1363,7.892,1421,4.157,1546,5.452,1586,4.277,1592,7.892,1604,10.957,1605,7.175,1606,6.727,1607,4.36,1608,9.233,1609,4.328,1610,6.931,1611,6.4,1612,4.354,1613,5.836]],["t/245",[0,4.056,1,2.136,2,1.931,3,4.789,4,4.654,5,1.005,7,1.197,8,3.082,9,3.005,10,1.708,11,1.619,12,2.809,13,2.763,14,2.495,15,2.357,16,2.626,17,2.069,18,4.854,19,2.43,20,4.415,22,1.786,23,4.854,25,2.415,27,2.267,29,2.626,33,2.36,35,2.844,39,4.314,51,2.357,93,4.072,107,3.453,123,1.445,139,3.106,178,2.267,198,2.317,209,2.924,213,2.025,215,3.217,217,4.023,220,2.267,239,2.22,256,3.528,258,2.745,259,2.101,263,2.236,287,1.27,398,3.22,427,3.549,451,3.528,461,2.415,463,1.601,490,1.931,507,3.955,510,1.371,511,2.135,531,2.33,532,2.904,535,2.647,555,1.702,560,2.051,570,3.124,571,2.317,585,2.936,588,3.453,596,4.854,633,3.386,734,2.548,756,2.22,771,3.324,774,2.873,809,1.528,867,1.448,880,4.786,885,4.234,890,2.176,1031,2.739,1055,1.768,1082,2.816,1091,4.023,1098,2.53,1106,5.404,1109,3.005,1110,2.97,1112,3.955,1151,2.691,1159,2.446,1205,2.135,1214,2.446,1216,5.29,1234,5.53,1248,2.669,1250,3.268,1272,3.217,1327,2.626,1336,3.955,1373,3.169,1376,3.612,1440,4.786,1564,6.664,1586,2.357,1614,2.936,1615,2.446,1616,4.35,1617,2.789,1618,1.874,1619,4.693,1620,3.955,1621,4.35,1622,3.82,1623,3.708,1624,3.612,1625,4.35,1626,4.693,1627,4.693,1628,4.693,1629,2.936,1630,4.693,1631,7.19,1632,4.124,1633,4.693,1634,4.693,1635,4.693,1636,3.528,1637,3.955,1638,4.693,1639,4.693,1640,2.096,1641,3.708]],["t/247",[4,4.592,6,1.706,18,3.719,20,3.158,22,2.096,23,2.266,24,1.647,26,1.727,34,2.099,41,1.513,43,1.168,75,1.809,116,2.554,117,0.604,137,1.37,142,2.266,156,0.815,163,3.855,198,1.657,217,4.538,219,1.107,221,1.604,224,1.629,229,1.144,250,1.345,259,1.689,418,1.685,449,2.377,451,4.14,452,1.506,489,1.119,491,1.436,496,1.822,509,2.469,512,2.651,528,3.896,532,3.408,533,2.266,535,1.893,538,1.065,563,2.421,579,2.036,587,2.522,595,2.234,596,2.266,610,1.666,611,1.407,612,0.98,619,1.527,649,1.473,668,1.252,729,3.902,735,1.784,737,1.527,739,3.338,766,3.527,769,1.958,794,2.421,809,1.093,821,4.802,862,2.149,871,1.863,874,1.822,875,1.081,885,1.976,910,3.305,911,5.257,923,0.881,964,1.878,967,2.099,969,1.676,987,3.199,998,0.985,1019,2.554,1030,1.749,1031,4.088,1047,2.949,1055,2.075,1059,2.582,1072,1.695,1110,5.131,1151,1.924,1156,2.234,1177,2.325,1196,2.337,1200,1.784,1215,2.582,1234,2.123,1239,3.186,1251,2.522,1253,1.716,1268,2.582,1279,1.924,1300,3.408,1306,2.828,1308,1.695,1312,2.099,1327,1.878,1331,2.829,1364,2.149,1367,7.546,1372,4.542,1376,4.239,1399,1.638,1421,3.421,1422,2.469,1440,6.406,1471,1.666,1535,2.421,1582,2.469,1599,2.275,1608,2.828,1610,2.732,1621,5.106,1632,4.84,1641,6.407,1642,3.356,1643,2.234,1644,5.155,1645,3.356,1646,2.651,1647,1.958,1648,4.84,1649,3.356,1650,3.356,1651,3.356,1652,3.356,1653,3.356,1654,2.828,1655,3.356,1656,3.356,1657,2.651,1658,5.509,1659,4.352,1660,7.007,1661,2.949,1662,2.522,1663,2.828,1664,3.356,1665,3.356,1666,3.356,1667,3.356,1668,2.337,1669,2.651,1670,3.356,1671,3.356,1672,2.3,1673,3.356,1674,4.239,1675,3.356,1676,5.106,1677,5.509,1678,1.685,1679,3.356,1680,3.11,1681,5.509,1682,2.949,1683,5.509,1684,3.356,1685,2.337,1686,2.828,1687,5.509,1688,3.356,1689,3.356,1690,3.356,1691,3.356,1692,2.949,1693,3.356,1694,2.421,1695,3.356,1696,2.828,1697,2.469,1698,3.338,1699,3.356,1700,5.106,1701,3.775,1702,7.007,1703,3.356,1704,5.509,1705,5.509,1706,3.356,1707,3.356,1708,4.14,1709,2.732,1710,3.356,1711,1.893,1712,1.822,1713,2.651,1714,3.571,1715,1.36,1716,2.949,1717,2.076,1718,2.522,1719,3.356,1720,3.356,1721,2.828,1722,1.548,1723,1.908,1724,2.582,1725,3.356,1726,3.356]],["t/249",[3,3.412,5,1.77,29,6.683,49,6.211,50,5.426,117,1.178,137,3.374,139,2.43,160,4.126,172,1.912,215,5.664,219,2.727,245,3.242,267,2.024,320,4.424,351,4.455,391,2.358,402,3.209,463,2.818,490,3.399,557,3.054,607,2.266,622,4.364,668,3.083,781,2.091,1009,3.828,1250,5.755,1391,6.726,1419,8.615,1489,4.335,1727,2.935,1728,9.961,1729,8.264,1730,6.529,1731,7.261,1732,4.2,1733,6.211,1734,4.057,1735,5.291,1736,6.726,1737,8.264,1738,6.964,1739,7.659,1740,6.964]],["t/251",[5,1.653,11,2.662,23,5.21,29,4.319,44,1.372,94,2.603,117,1.126,163,3.669,167,4.389,245,4.831,421,2.898,557,2.852,576,3.319,612,2.254,629,3.831,802,2.67,867,3.171,988,6.504,1010,7.155,1090,3.831,1286,4.075,1345,5.374,1412,6.097,1419,5.567,1555,5.939,1643,6.838,1728,7.153,1739,7.153,1741,7.718,1742,7.718,1743,7.718,1744,7.718,1745,7.718,1746,7.718,1747,7.718,1748,7.718,1749,4.464,1750,4.464,1751,4.426,1752,7.718,1753,3.831,1754,7.718,1755,6.097,1756,7.718,1757,7.718,1758,7.718,1759,7.718,1760,5.939,1761,6.781,1762,6.504,1763,7.718,1764,7.153,1765,7.718,1766,5.289,1767,7.718]],["t/253",[0,3.82,1,1.656,2,2.786,3,4.209,5,0.931,19,6.04,20,3.752,21,1.248,30,1.704,43,1.511,91,2.004,93,2.024,95,1.642,117,0.742,124,2.582,126,3.985,137,1.774,139,2.765,148,1.728,153,4.696,172,1.005,194,1.642,196,1.299,198,2.144,209,1.767,213,1.874,220,2.098,235,2.087,339,3.067,461,2.235,490,2.786,495,1.822,505,5.033,510,1.269,521,2.922,524,2.535,525,2.157,531,2.157,557,1.605,576,2.188,596,2.933,607,1.191,613,4.157,615,1.59,621,1.269,649,1.907,679,2.195,694,3.307,720,4.508,742,7.42,761,3.077,766,2.781,774,6.611,862,2.781,874,2.359,910,2.607,912,5.489,963,2.607,987,1.552,1013,2.055,1023,3.817,1025,2.169,1035,2.513,1036,2.376,1038,3.817,1039,3.817,1041,3.343,1042,5.708,1050,3.536,1053,3.536,1055,2.552,1084,3.432,1086,3.817,1125,2.055,1130,3.343,1131,2.412,1187,2.087,1209,3.265,1213,2.431,1220,3.817,1234,4.285,1249,2.279,1268,3.343,1279,2.491,1280,5.708,1281,5.575,1308,2.195,1331,1.754,1351,2.66,1367,5.708,1368,3.077,1471,2.157,1617,4.025,1618,1.735,1735,2.781,1768,3.432,1769,6.005,1770,4.344,1771,7.661,1772,3.464,1773,2.342,1774,2.749,1775,3.536,1776,3.53,1777,2.816,1778,2.044,1779,4.344,1780,4.344,1781,4.344,1782,4.344,1783,3.265,1784,6.278,1785,4.344,1786,4.344,1787,4.344,1788,3.852,1789,2.853,1790,1.976,1791,2.169,1792,2.718,1793,3.432,1794,4.344]],["t/255",[495,4.607,742,6.528,1234,6.95,1269,9.256,1279,6.299,1320,10.181,1323,10.181,1324,10.181,1325,10.181]],["t/257",[3,4.087,4,5.03,8,6.499,14,5.262,30,2.026,31,6.499,32,6.893,34,6.192,35,5.998,36,5.414,37,8.013,38,4.422,40,5.192,41,4.461,42,6.784,43,3.444,44,1.76,45,7.282,46,7.82,1624,7.617]],["t/259",[8,6.235,14,6.24,32,8.872,73,2.826,95,3.589,140,6.85,177,5.823,245,3.725,248,5.156,263,2.952,267,2.326,540,8.002,648,5.048,1154,7.502,1441,6.008,1795,11.737,1796,9.496,1797,9.496,1798,8.002,1799,5.272,1800,9.496,1801,4.981,1802,9.496]],["t/261",[45,7.835,73,3.169,248,5.783,259,2.009,263,3.311,458,9.358,1036,5.825,1097,4.364,1188,9.358,1373,7.191,1803,10.651,1804,10.651,1805,7.3]],["t/263",[3,3.453,19,5.608,22,4.121,27,4.039,44,1.925,45,6.152,73,3.223,87,2.868,148,2.133,213,3.608,220,4.039,221,3.996,259,2.043,263,3.367,402,3.247,450,7.047,490,3.44,504,4.574,529,2.926,655,5.491,660,3.578,739,5.068,748,4.148,812,5.174,980,3.639,1188,10.554,1191,5.491,1307,4.54,1373,5.646,1386,5.12,1607,3.327,1771,6.285,1806,6.807,1807,4.039,1808,6.032,1809,8.837,1810,8.362,1811,8.362]],["t/265",[11,3.646,96,4.161,208,3.116,209,4.299,259,1.993,451,7.945,463,3.605,597,4.076,637,5.473,670,4.721,743,7.361,908,3.906,1234,6.688,1812,5.405]],["t/268",[27,4.681,30,1.984,87,3.324,117,1.303,139,2.851,178,4.681,290,5.341,511,4.409,514,4.868,584,4.494,668,3.617,870,5.816,978,3.06,1008,4.018,1246,9.675,1260,6.063,1609,4.927,1640,5.309,1813,6.816,1814,8.984,1815,6.992,1816,4.218]],["t/270",[10,3.78,30,2.126,87,2.691,96,4.585,97,2.422,117,0.86,139,2.308,141,4.709,148,2.002,156,1.907,196,3.482,203,3.459,235,4.99,243,2.694,267,2.544,290,4.324,351,5.6,508,4.539,510,2.292,562,3.204,579,2.9,695,8.207,762,7.12,763,6.573,775,2.297,788,4.909,877,5.813,888,4.357,908,3.839,978,2.477,1257,5.223,1813,5.957,1817,6.387,1818,7.523,1819,4.23,1820,6.2,1821,7.847,1822,7.847,1823,7.847,1824,7.847]],["t/272",[22,3.74,40,5.156,72,3.924,73,2.925,196,2.939,203,4.332,208,2.897,250,3.939,265,5.336,267,2.407,290,5.416,576,3.175,586,4.41,775,2.877,816,4.013,1177,3.261,1253,5.026,1355,6.081,1734,4.825,1807,4.747,1825,5.735,1826,9.829,1827,7.564]],["t/274",[0,5.249,1,2.275,2,3.828,19,4.819,21,3.331,32,6.481,37,6.194,48,3.613,73,2.77,118,3.472,196,2.783,209,4.715,259,2.186,451,6.995,529,3.257,544,4.674,597,3.589,637,4.819,670,4.157,765,7.162,768,6.592,908,3.439,914,4.032,1234,7.334,1352,6.111,1828,6.713,1829,3.828]],["t/276",[1,2.216,7,2.312,15,4.553,21,2.605,117,0.994,202,6.422,208,3.677,211,3.35,259,2.151,288,5.199,463,3.092,487,3.607,495,3.802,502,5.199,513,4.995,531,4.501,624,4.527,636,4.665,743,6.313,1031,5.29,1195,5.338,1308,4.58,1398,4.378,1418,3.674,1562,7.966,1589,5.671,1769,6.54,1812,5.831,1830,6.147,1831,7.379,1832,5.953]],["t/278",[11,3.539,118,3.828,208,3.885,214,3.58,219,3.386,259,2.32,287,2.777,463,3.499,576,3.315,624,5.123,1615,5.347,1812,5.247,1833,9.248,1834,8.106]],["t/280",[18,4.717,43,2.431,47,2.511,87,2.396,156,1.698,163,3.321,194,2.641,196,2.089,208,4.147,209,2.842,213,3.015,219,2.305,220,3.374,221,3.339,239,3.304,259,1.812,287,1.891,316,4.473,472,4.473,510,2.04,541,4.152,624,4.796,639,4.974,645,2.896,668,2.607,670,3.121,687,4.588,696,5.14,881,4.192,909,4.323,980,3.04,1025,3.489,1055,2.632,1075,4.041,1197,5.687,1246,5.687,1565,7.762,1607,2.78,1608,5.887,1790,3.178,1812,6.548,1830,3.766,1835,5.376,1836,9.605,1837,6.987,1838,4.077,1839,6.476,1840,5.376,1841,2.566,1842,5.14,1843,4.717,1844,4.277,1845,5.887,1846,4.234,1847,5.14,1848,5.376,1849,6.987,1850,6.987]],["t/282",[6,3.818,43,2.613,73,2.235,97,3.114,113,6.648,117,0.823,145,4.236,148,1.916,156,2.768,208,3.857,224,3.647,242,3.772,287,2.032,557,2.776,604,7.851,611,3.15,643,5.526,663,3.254,744,3.993,831,4.925,875,2.42,923,1.973,978,2.371,1025,3.75,1043,5.526,1312,4.698,1424,5.526,1553,5.526,1565,7.998,1599,4.166,1674,5.78,1722,3.466,1813,4.307,1841,2.758,1851,10.089,1852,9.351,1853,4.598,1854,5.934,1855,7.511,1856,7.511,1857,7.511,1858,4.382,1859,10.089,1860,7.511,1861,7.511]],["t/284",[9,3.292,33,1.687,43,1.789,44,2.392,73,1.53,96,3.033,97,1.587,117,1.013,150,2.139,169,2.339,179,3.027,208,3.402,240,1.167,241,2.771,255,3.115,316,3.292,510,2.698,538,1.631,579,1.9,584,2.384,593,3.422,596,3.471,598,2.384,604,3.085,611,2.156,612,1.501,630,4.214,646,3.825,659,1.976,660,4.391,687,6.067,759,2.361,764,2.182,801,4.767,802,3.802,828,8.648,831,5.01,874,2.791,895,2.812,908,1.9,909,3.181,1008,2.131,1013,2.432,1014,2.419,1097,2.107,1189,3.471,1195,3.027,1218,2.697,1249,2.697,1251,3.864,1253,2.629,1277,2.715,1302,3.055,1308,2.597,1438,4.517,1565,6.067,1596,1.9,1640,2.296,1678,2.582,1685,3.58,1722,3.555,1788,4.381,1812,3.94,1819,4.153,1840,3.956,1862,3.864,1863,5.141,1864,5.141,1865,3.782,1866,3.709,1867,4.517,1868,3.58,1869,4.765,1870,4.062,1871,3.332,1872,4.332,1873,6.067,1874,3,1875,4.185,1876,4.332,1877,4.332,1878,5.657,1879,5.141,1880,7.704,1881,7.704,1882,5.141,1883,5.141,1884,5.141,1885,7.704,1886,7.704,1887,5.141,1888,3.782,1889,5.141,1890,5.141,1891,5.141,1892,4.765,1893,5.141,1894,3.782,1895,3.524]],["t/286",[30,1.711,38,3.071,41,3.769,44,1.925,148,2.133,156,2.032,208,3.193,217,4.679,224,4.06,529,2.926,604,5.018,679,4.225,687,5.491,742,4.97,828,9.126,908,3.09,923,2.196,1025,4.176,1041,6.435,1042,7.047,1240,7.348,1565,7.111,1599,4.472,1640,3.735,1773,4.508,1776,4.358,1783,6.285,1846,6.563,1852,7.751,1896,4.717,1897,12.012,1898,8.362,1899,8.362,1900,8.362,1901,7.348,1902,8.362,1903,8.362,1904,4.225,1905,8.362,1906,8.362,1907,8.362]],["t/288",[1,2.147,12,2.822,15,4.411,72,2.875,83,1.734,113,5.124,115,3.029,138,2.71,144,4.953,169,3.995,183,5.901,208,3.294,227,5.269,229,3.811,239,4.153,259,1.656,495,3.683,607,2.408,636,4.519,659,4.295,663,3.805,671,4.335,834,3.277,874,4.768,887,6.915,993,4.31,1097,3.599,1640,3.922,1715,3.558,1812,5.715,1908,7.148,1909,5.622,1910,5.171,1911,7.716]],["t/290",[5,2.276,7,2.71,12,3.415,14,4.317,21,2.333,117,0.89,201,4.178,202,5.752,211,3.001,240,1.843,245,4.168,259,2.004,304,4.544,391,3.032,397,4.738,502,4.656,510,2.371,521,4.584,526,3.964,528,5.104,538,2.576,622,4.288,636,4.178,891,3.964,908,3.001,923,2.133,987,2.901,989,4.656,1204,3.315,1276,5.565,1327,4.544,1362,5.264,1607,3.231,1790,3.694,1816,3.533,1912,6.103,1913,6.609,1914,4.055,1915,5.858,1916,5.332,1917,6.249,1918,4.205,1919,4.971,1920,6.609,1921,4.656]],["t/292",[5,2.182,14,6.513,73,3.031,83,2.594,106,4.946,138,3.143,240,2.312,245,3.996,259,1.921,473,2.996,474,3.753,528,4.893,908,3.764,1351,6.236,1916,6.688,1922,10.186]],["t/294",[5,2.135,73,2.967,106,4.84,196,2.981,240,2.263,245,3.911,259,1.88,296,2.635,527,4.023,557,3.684,576,3.22,621,2.911,624,4.978,626,3.818,1252,6.462,1351,6.103,1519,5.623,1918,5.162,1923,5.817,1924,4.301,1925,7.334]],["t/296",[5,2.062,14,6.293,21,2.766,36,5.265,73,2.865,117,1.055,139,2.831,211,3.557,245,3.777,259,2.232,438,5.686,622,5.083,624,4.807,809,3.134,890,4.463,908,3.557,923,2.528,980,4.189,1607,3.83,1916,6.321,1918,4.985,1919,5.893,1924,4.153,1926,5.153]],["t/298",[5,1.296,14,4.616,20,2.727,36,3.31,83,1.195,95,2.287,117,1.381,123,1.863,196,1.809,201,3.114,211,3.753,245,3.984,259,1.915,265,3.286,304,3.386,397,3.531,411,1.4,414,1.641,437,2.938,438,5.874,468,4.147,483,2.302,495,2.538,510,2.966,528,4.171,530,2.656,538,1.92,604,6.093,622,3.195,624,3.022,630,3.31,639,3.133,646,3.004,775,1.771,781,1.531,809,1.97,875,1.95,890,2.806,891,2.954,1002,4.028,1097,2.48,1130,8.538,1140,3.413,1174,4.214,1175,3.973,1208,2.766,1281,3.31,1286,3.195,1480,3.386,1579,3.923,1816,2.633,1912,4.548,1914,3.022,1916,5.701,1918,5.258,1919,5.316,1921,3.47,1927,7.067,1928,6.051,1929,5.609,1930,6.051,1931,4.657,1932,7.629,1933,5.099,1934,3.334,1935,4.085,1936,4.657,1937,5.099,1938,4.925,1939,5.609,1940,6.051,1941,4.365,1942,3.5,1943,3.531,1944,6.051,1945,4.925,1946,4.548,1947,4.147,1948,3.413,1949,3.334,1950,4.365]],["t/300",[14,5.462,21,2.218,48,2.997,73,2.297,117,1.266,166,3.876,168,2.574,181,3.417,194,2.917,211,2.852,240,2.332,259,2.178,287,2.088,304,4.319,351,4.16,397,4.503,402,2.997,510,3,526,4.594,529,2.701,530,3.387,532,4.775,546,4.503,579,2.852,646,3.831,668,2.88,1206,7.153,1369,5.678,1418,3.127,1480,4.319,1727,2.741,1816,3.358,1917,5.939,1918,6.64,1919,4.725,1921,4.426,1949,4.253,1950,8.331,1951,8.117,1952,4.544,1953,4.828,1954,3.996,1955,7.718,1956,7.153,1957,4.941,1958,4.19]],["t/302",[7,3.269,14,2.733,21,1.477,22,2.931,43,1.789,44,0.914,73,2.75,83,2.17,91,2.372,117,1.125,137,3.145,138,1.587,139,2.717,148,1.311,155,2.629,156,1.249,168,1.715,180,1.652,181,2.276,183,2.715,186,2.083,187,2.993,211,1.9,226,2.395,229,1.753,240,1.167,243,1.333,247,8.119,248,2.791,259,1.453,265,2.791,267,1.887,316,3.292,436,3.115,438,5.28,443,3.231,521,3.987,526,1.918,528,2.47,529,1.799,555,3.351,575,2.107,579,1.9,597,1.983,622,2.715,624,2.567,626,1.969,646,3.825,647,3,651,3.422,666,2.123,732,2.426,770,2.733,781,1.949,787,2.156,891,2.51,908,1.9,953,2.228,955,2.173,978,1.623,1011,4.015,1055,1.937,1082,3.085,1120,2.791,1177,1.706,1232,3.864,1237,4.765,1271,2.697,1351,3.147,1465,2.317,1519,6.749,1607,2.046,1727,1.826,1790,2.339,1918,2.662,1919,3.147,1921,2.948,1933,4.332,1943,5.988,1948,2.9,1953,4.819,1954,2.662,1959,5.557,1960,7.704,1961,2.496,1962,6.15,1963,4.765,1964,5.141,1965,5.141,1966,2.597,1967,2.567,1968,5.141,1969,5.141,1970,4.517,1971,5.141,1972,5.141,1973,4.185,1974,2.613,1975,3.956]],["t/304",[73,3.598,151,5.535,155,5.098,166,5.007,245,4.744,259,1.88,298,6.168,438,5.809,452,4.473,809,3.246,1028,4.84,1110,6.307,1845,8.4,1916,7.94,1919,6.103,1943,5.817,1976,4.978,1977,7.671]],["t/306",[11,3.488,83,1.997,84,5.079,187,3.276,259,1.907,265,5.491,297,2.974,438,4.858,624,5.049,647,5.9,809,4.265,1169,5.849,1618,4.038,1753,5.02,1921,5.799,1937,8.522,1938,8.231,1939,9.373]],["t/308",[14,6.718,30,2.196,259,2.383,391,3.063,571,5.298,619,4.882,890,4.976,1283,6.005,1921,6.154,1978,10.732]],["t/311",[30,1.943,47,3.413,72,3.108,87,4.369,138,2.93,139,2.793,177,4.34,190,4.688,203,4.186,259,2.214,267,2.326,290,7.333,529,3.323,766,7.515,781,2.402,840,5.119,989,5.445,998,2.786,1253,6.002,1952,5.591,1979,6.235]],["t/313",[20,3.838,40,4.467,117,1.451,153,4.803,203,3.753,208,3.23,263,2.647,271,3.137,290,6.676,391,2.43,419,3.892,529,2.98,538,2.701,574,5.213,629,4.227,670,3.803,739,5.16,809,2.773,812,5.268,830,4.968,866,3.786,867,2.628,912,4.007,923,2.236,1159,4.438,1204,3.476,1214,4.438,1253,4.354,1488,7.904,1603,7.892,1807,5.292,1825,4.968,1980,8.515,1981,6.931,1982,6.264,1983,6.931,1984,5.93]],["t/315",[5,1.824,38,3.127,50,7.195,87,4.155,139,2.504,153,4.803,163,4.048,187,2.758,258,3.251,267,2.684,290,7.048,402,3.306,529,2.98,564,4.968,576,2.751,739,5.16,775,3.207,781,2.772,891,4.157,989,4.883,1174,5.93,1203,4.765,1204,3.476,1599,3.516,1807,4.112,1813,4.883,1818,7.069,1896,4.803,1910,5.013,1952,5.013,1985,5.836,1986,7.892,1987,4.883,1988,3.117,1989,4.925]],["t/317",[30,1.349,44,2.38,50,4.329,87,4.162,90,2.421,96,3.632,117,1.167,137,2.691,139,1.939,148,2.941,194,2.492,196,1.971,198,3.254,239,3.118,258,3.522,290,6.686,530,2.893,538,2.927,562,2.691,575,2.701,576,2.13,594,4.036,612,3.108,617,3.481,645,4.779,660,2.821,671,3.254,687,4.329,745,3.995,781,2.693,788,6.658,830,3.846,840,3.554,862,4.221,879,3.813,892,3.414,923,1.731,955,2.787,1026,5.792,1091,3.689,1115,3.881,1189,4.451,1216,4.85,1261,4.518,1476,5.208,1714,4.273,1817,8.663,1894,6.787,1990,6.934,1991,9.226,1992,9.226,1993,9.226,1994,5.792,1995,6.592]],["t/319",[10,2.529,21,1.998,22,2.645,27,3.357,44,1.702,87,3.283,97,2.145,103,4.506,117,1.049,138,2.145,139,3.22,141,4.171,148,1.773,156,2.326,172,2.729,178,3.357,243,2.839,263,2.161,290,6.499,427,4.725,463,2.371,529,2.433,562,2.838,576,2.246,584,3.223,663,3.012,737,3.162,744,5.089,748,2.663,762,8.084,775,2.035,781,1.759,788,7.379,809,2.264,888,5.315,1002,4.627,1203,5.356,1596,2.569,1685,4.841,1801,3.647,1813,5.489,1818,6.883,1989,4.021,1996,6.952,1997,9.572,1998,6.952,1999,6.952,2000,6.952,2001,6.952,2002,6.952,2003,4.693,2004,5.858,2005,6.443,2006,3.162]],["t/321",[10,2.551,21,1.305,30,1.435,47,1.632,50,2.982,87,3.302,117,1.055,138,2.163,141,2.725,196,1.358,208,2.838,213,1.959,219,1.499,220,2.193,243,1.178,259,1.615,266,1.951,267,2.097,290,4.718,338,2.205,339,3.174,354,6.705,401,2.308,402,1.763,403,3.023,412,1.549,420,2.466,470,1.391,473,1.336,486,2.038,508,7.734,514,2.281,529,1.589,538,1.441,550,4.603,557,3.558,562,1.854,589,3.341,612,2.047,654,1.84,660,1.943,670,3.131,737,2.066,763,7.252,767,2.674,775,3.355,781,2.166,834,1.694,879,2.627,953,1.968,964,2.541,998,2.825,1024,2.056,1114,4.996,1159,2.367,1177,2.841,1182,3.112,1307,2.466,1330,2.627,1347,2.944,1372,4.544,1487,2.944,1612,2.322,1801,2.382,1813,7.949,1818,4.09,1988,2.566,1990,3.413,2007,10.236,2008,4.209,2009,4.209,2010,2.841,2011,4.209,2012,3.99,2013,4.541,2014,10.405,2015,4.541,2016,2.431,2017,6.16,2018,2.255,2019,3.163,2020,3.827,2021,2.752,2022,3.163,2023,4.541,2024,2.944,2025,4.209,2026,3.341,2027,2.908]],["t/323",[17,3.049,21,1.988,32,8.197,44,2.093,97,2.135,106,4.632,138,2.135,156,1.681,211,2.556,245,2.714,259,2.22,266,2.972,290,6.804,402,2.686,457,3.104,508,5.518,537,5.089,564,4.036,621,2.02,763,4.377,764,2.936,781,1.75,822,2.772,998,2.03,1075,7.919,1114,6.371,1349,3.902,1419,7.877,1624,7.341,1791,3.454,1801,3.629,1813,7.32,1954,3.582,1986,6.412,2020,5.829,2022,4.817,2025,6.412,2028,9.54,2029,10.92,2030,6.918,2031,5.631,2032,5.452,2033,4.67,2034,6.918,2035,5.089]],["t/325",[1,0.428,3,0.724,5,0.917,7,0.447,10,2.436,11,1.477,21,1.501,30,1.231,44,1.537,47,1.539,50,1.151,78,1.58,83,0.346,87,2.064,91,1.452,94,0.591,95,0.662,97,2.669,117,1.259,123,0.54,137,0.715,138,0.971,139,2.293,141,1.052,148,1.092,152,1.349,153,1.775,156,2.848,168,0.585,172,1.209,177,1.438,183,2.261,190,6.297,194,0.662,196,0.524,198,0.865,202,1.241,208,0.927,210,0.58,213,1.358,214,1.494,216,0.913,219,1.038,220,1.519,223,2.849,226,0.817,235,0.842,240,0.398,242,0.88,243,0.816,245,0.688,249,0.809,250,0.702,258,2.78,259,0.807,262,0.817,264,0.817,266,1.839,267,1.909,290,5.139,296,0.463,297,0.515,398,0.646,402,2.028,433,1.109,437,0.851,470,0.537,472,2.741,473,0.515,483,1.197,488,0.591,489,1.05,490,0.721,492,0.692,497,1.122,514,0.88,521,0.756,529,2.343,549,1.183,557,2.881,562,1.284,576,1.016,579,1.93,597,0.676,606,1.032,607,0.48,612,1.25,614,1.59,617,1.661,620,0.805,626,1.205,636,0.902,660,1.832,670,0.783,678,0.938,679,2.639,694,0.856,697,0.825,719,1.399,737,0.797,748,1.205,752,1.032,753,1.304,754,1.22,757,0.846,763,3.305,775,3.463,781,0.443,785,0.902,802,1.481,830,1.023,833,2.229,862,1.122,866,2.322,867,1.321,873,2.217,874,0.952,877,4.362,880,1.166,881,1.888,914,0.759,923,0.826,942,0.885,953,1.855,964,0.981,985,1.565,991,1.381,997,0.624,1014,0.825,1015,1.553,1024,0.794,1036,0.959,1097,0.718,1109,1.122,1115,1.032,1159,0.913,1160,1.201,1204,0.715,1218,1.65,1239,1.014,1250,1.22,1253,2.671,1271,0.919,1273,0.685,1277,1.661,1345,1.22,1347,1.136,1355,1.947,1359,1.166,1370,1.836,1372,5.346,1393,1.109,1478,4.173,1483,1.084,1547,0.919,1555,1.349,1596,2.475,1617,1.042,1672,2.934,1696,1.477,1715,1.275,1727,0.622,1789,1.151,1790,0.797,1791,0.875,1799,0.973,1801,1.65,1813,4.176,1817,2.561,1818,7.62,1819,1.696,1825,3.048,1830,0.945,1833,1.317,1904,0.885,1914,0.875,1981,1.427,1984,1.22,1987,1.804,1988,0.642,1990,1.317,2006,1.947,2009,1.624,2011,1.624,2016,3.221,2036,6.625,2037,1.753,2038,1.753,2039,1.54,2040,1.477,2041,1.753,2042,3.968,2043,2.89,2044,1.753,2045,1.753,2046,1.753,2047,1.753,2048,1.753,2049,1.54,2050,1.753,2051,2.561,2052,3.485,2053,1.753,2054,1.624,2055,1.183,2056,1.753,2057,2.916,2058,1.753,2059,1.708,2060,0.885,2061,1.264,2062,0.766,2063,1.624,2064,1.753,2065,1.753,2066,3.146,2067,1.753,2068,3.146,2069,1.753,2070,1.753,2071,1.753,2072,1.023,2073,1.753,2074,1.062,2075,2.623,2076,2.561,2077,1.753,2078,1.317,2079,1.753,2080,1.753,2081,1.753,2082,3.146,2083,3.146,2084,4.281,2085,6.017,2086,6.017,2087,1.753,2088,1.753,2089,1.753,2090,1.753,2091,1.753,2092,1.753,2093,1.753,2094,1.753,2095,1.753,2096,1.753,2097,4.281,2098,1.753,2099,1.753,2100,1.477,2101,1.624,2102,3.146,2103,1.624,2104,1.385,2105,1.385,2106,1.753,2107,1.753,2108,4.281,2109,1.753,2110,1.753,2111,4.281,2112,1.753,2113,4.281,2114,4.281,2115,1.753,2116,1.753,2117,1.289,2118,1.734,2119,1.427,2120,1.753]],["t/327",[0,4.083,1,2.406,2,2.978,5,1.551,12,3.163,24,3.554,51,3.636,96,2.85,117,0.794,123,2.229,196,3.343,208,2.134,209,4.548,216,3.773,240,2.724,258,2.764,259,1.856,267,1.773,296,2.601,315,3.657,351,3.902,391,2.066,398,2.667,411,2.587,419,3.309,473,2.129,524,4.224,526,3.672,527,3.991,547,4.635,593,4.818,612,2.114,627,4.282,867,2.234,1055,2.727,1071,3.773,1170,3.085,1205,3.293,1266,4.479,1276,4.962,1418,3.988,1574,6.1,1577,4.387,1712,3.93,1816,3.15,2121,4.432,2122,7.24,2123,4.302,2124,6.71,2125,6.1,2126,6.1,2127,6.71,2128,5.571,2129,6.71,2130,4.754]],["t/329",[1,2.245,5,2.463,12,2.952,16,5.139,51,4.613,163,4.366,196,3.438,208,2.708,209,3.736,240,2.849,287,2.485,391,2.621,411,2.125,473,2.701,526,3.427,541,5.458,610,4.56,627,3.996,734,4.987,1422,6.757,1439,5.566,1589,5.745,2105,7.256,2121,5.623,2122,6.757,2131,9.185,2132,9.185,2133,6.113,2134,6.113,2135,9.185]],["t/331",[12,2.895,91,4.156,117,0.987,145,5.081,196,3.905,240,2.578,250,3.61,259,1.699,296,2.381,398,3.318,411,2.084,473,2.649,487,3.584,527,2.997,553,4.789,597,3.474,627,5.412,775,2.637,809,2.933,831,4.397,867,2.78,875,2.902,1205,4.098,1418,3.65,1714,7.361,1958,4.891,2136,7.116,2137,6.38,2138,6.273,2139,8.349]],["t/333",[1,1.996,5,1.75,12,2.625,21,2.347,83,2.345,107,6.009,122,3.334,123,3.283,136,3.648,196,2.442,259,1.54,296,2.159,297,2.402,330,3.467,398,3.009,474,3.009,487,4.725,489,2.724,527,2.717,545,5.436,598,3.787,627,5.167,629,4.055,633,5.892,766,5.229,775,3.122,781,2.066,820,2.918,831,3.987,1013,5.044,1028,3.966,1035,4.724,1253,4.177,1586,4.102,1727,2.9,1829,3.36,2134,5.436,2138,5.688,2140,6.453,2141,7.57,2142,6.453,2143,5.514,2144,5.791]],["t/335",[5,2.144,12,3.217,16,3.301,24,2.896,30,1.207,48,3.31,83,1.976,117,0.647,126,2.306,177,2.696,187,1.911,196,3.478,240,1.935,255,3.574,259,1.608,287,2.307,296,3.382,297,2.507,330,3.618,391,2.857,398,2.173,400,4.532,411,2.805,414,1.6,449,4.178,452,2.647,487,2.347,490,2.426,495,3.575,496,3.203,512,4.66,527,3.648,531,2.928,534,4.339,541,3.505,547,5.458,548,4.971,560,4.374,575,2.417,576,1.906,598,2.735,618,3.226,621,1.723,627,2.567,813,4.108,875,1.901,896,3.226,1055,2.222,1147,4.339,1181,4.333,1222,4.255,1273,2.306,1418,2.39,1589,3.69,1732,4.333,1816,2.567,1988,2.159,2123,3.505,2130,3.873,2145,3.327,2146,5.898,2147,4.971,2148,4.539,2149,5.898,2150,8.524,2151,4.339,2152,4.733,2153,7.523,2154,5.678,2155,3.574,2156,4.339,2157,2.623]],["t/337",[16,5.424,83,2.347,123,2.984,196,2.898,211,3.582,240,2.698,398,3.571,483,3.688,597,3.738,598,4.494,607,2.657,809,4.186,831,4.732,885,5.707,980,4.218,1008,4.018,1019,4.494,1643,6.451,1828,6.992,2139,8.984,2158,9.693,2159,9.693]],["t/339",[1,1.929,5,2.234,15,3.963,86,3.171,90,2.898,117,0.865,136,3.525,165,3.405,196,3.118,211,2.916,214,2.753,219,2.604,240,1.791,250,3.163,259,1.488,296,2.756,411,1.826,482,4.285,488,2.661,513,4.348,527,3.469,547,5.053,557,2.916,562,3.222,569,6.073,627,5.081,629,3.918,818,4.036,822,3.163,923,2.073,978,2.491,980,3.434,997,3.714,1029,4.488,1135,4.993,1158,5.806,1273,3.085,1332,3.853,1418,3.198,1813,4.525,2160,7.892,2161,5.59,2162,6.65,2163,6.073,2164,6.934,2165,5.182,2166,6.934,2167,7.892,2168,5.806,2169,5.931,2170,5.931]],["t/342",[0,5.745,1,2.994,2,4.19,3,4.206,4,4.255,12,3.274,17,4.49,126,3.982,259,1.921,287,2.756,534,7.494,612,2.975,647,5.943,1033,5.146,1168,6.372,1308,5.146,2171,4.341,2172,10.186]],["t/344",[2,3.753,5,1.955,196,3.424,259,1.721,271,3.362,296,3.026,297,3.367,304,5.106,315,5.785,330,3.873,336,7.427,397,5.324,400,4.851,411,2.649,414,2.475,487,3.631,627,5.709,652,4.316,1131,5.066,1331,3.684,1519,5.147,1732,4.638,1829,3.753,1841,3.351,1918,4.725,2173,7.022,2174,3.987]],["t/347",[1,2.77,11,3.455,16,4.158,38,2.729,47,2.671,48,2.885,72,2.433,83,1.467,95,2.809,96,2.926,116,3.445,122,3.034,150,3.092,172,1.72,180,3.219,181,5.017,196,2.222,208,2.191,214,2.593,240,1.687,249,3.429,259,2.287,271,2.738,304,4.158,391,2.859,398,2.738,457,3.334,463,2.534,487,3.986,489,3.341,505,3.978,550,4.88,557,2.746,627,3.233,637,3.848,678,5.362,729,5.264,775,2.175,886,4.126,908,2.746,978,2.346,1055,2.8,1134,4.88,1168,4.649,1169,4.298,1586,3.732,1715,3.011,1967,3.711,2152,5.562,2175,7.431,2176,6.262,2177,4.416,2178,5.467,2179,5.093,2180,2.866,2181,4.946]],["t/349",[1,1.658,2,4.801,5,2.787,11,3.728,20,3.058,47,2.438,48,2.634,87,2.327,181,3.003,194,2.564,196,2.028,208,2,209,2.759,259,1.775,296,3.56,297,3.178,315,4.755,330,4.587,391,1.936,410,4.649,457,3.044,487,2.699,489,3.605,527,3.131,545,4.515,557,3.478,560,2.964,610,4.672,618,3.71,627,2.952,668,2.531,735,3.606,749,5.522,756,3.208,781,2.381,785,3.491,831,3.312,869,3.826,895,3.71,909,4.197,991,2.977,998,1.99,1125,3.208,1131,3.766,1169,5.443,1239,3.923,1734,3.33,2138,4.724,2174,2.964,2182,3.89,2183,4.991,2184,5.716,2185,4.724,2186,4.07,2187,4.724,2188,4.724]],["t/351",[1,2.728,15,5.605,96,4.393,211,4.124,259,2.105,263,3.47,670,4.984]],["t/353",[7,2.24,20,5.037,26,4.519,27,5.397,83,1.734,87,3.012,91,4.052,93,5.727,139,3.615,180,2.822,203,3.871,235,5.368,259,2.44,463,2.995,469,4.994,501,5.376,538,2.786,576,3.61,911,5.692,923,2.306,997,3.128,1327,6.253,1330,5.079,1672,6.019,1914,4.385,2189,8.139,2190,8.782,2191,5.376,2192,4.914]],["t/355",[19,4.985,22,4.877,31,6.321,87,4.059,116,4.463,117,1.055,118,3.592,138,2.971,180,3.094,202,6.819,221,4.6,224,4.674,467,7.082,573,5.52,668,3.592,737,4.379,790,5.893,1234,6.091,1251,7.235,1281,5.265,1471,4.779,1535,6.944,1629,6.022,1829,3.96]],["t/357",[116,5.258,118,4.231,138,3.5,259,2.139,1234,7.175]],["t/359",[85,3.233,96,4.501,138,3.528,997,4.072]],["t/361",[267,2.649,287,2.927,473,3.181,568,5.28,600,6.368,631,7.772,729,7.661,908,3.997,1368,7.661,1640,4.831]],["t/363",[2,5.156,5,1.729,12,2.595,30,1.652,83,2.332,94,2.723,117,0.885,168,2.693,296,3.597,297,2.374,398,2.974,414,2.87,419,3.69,425,4.63,502,4.63,527,3.521,533,5.451,544,4.055,547,5.169,574,6.48,576,2.608,820,2.884,910,4.844,985,2.42,1141,6.378,1169,4.669,1170,3.441,1488,5.824,1582,5.939,1595,7.094,1599,3.334,1832,5.301,2105,6.378,2140,6.378,2193,8.615,2194,9.3,2195,5.622,2196,6.571,2197,5.301]],["t/366",[0,5.874,1,3.035,2,2.179,3,3.253,10,2.866,11,1.827,12,1.702,19,2.743,21,1.522,29,2.964,117,0.581,118,1.976,123,1.631,126,3.08,168,1.767,172,1.226,208,3.07,209,3.825,240,2.364,256,3.981,258,4.25,259,2.341,287,2.818,391,1.512,398,2.902,401,2.692,474,1.951,488,2.657,513,2.918,557,1.957,560,2.314,570,5.243,575,3.228,583,6.412,585,3.313,596,3.576,606,3.119,607,1.452,629,2.629,631,3.243,633,5.682,636,2.725,735,4.188,743,3.688,756,2.505,873,2.743,910,4.727,914,2.295,978,1.672,1025,2.645,1148,3.752,1170,2.257,1176,4.076,1272,3.63,1273,3.08,1302,4.682,1368,3.752,1396,3.012,1421,2.586,1546,5.043,1586,2.66,1589,3.313,1596,1.957,1599,2.187,1609,2.692,1623,4.184,1637,4.463,1663,4.463,1669,6.223,1676,4.909,1772,2.709,1819,2.855,1833,5.921,1834,6.223,2121,3.243,2122,3.897,2127,4.909,2142,4.184,2171,2.257,2198,3.478,2199,5.297,2200,4.654,2201,4.909,2202,4.654,2203,5.297,2204,5.682,2205,4.909,2206,3.897,2207,5.297,2208,5.297,2209,5.297,2210,3.821,2211,4.311,2212,5.297,2213,5.297,2214,5.297]],["t/368",[1,2.081,3,3.516,10,3.098,15,4.277,44,1.514,83,1.681,94,3.695,117,0.933,126,3.329,194,5.003,208,2.51,210,2.817,240,1.933,259,2.066,264,3.967,287,2.965,315,4.302,463,2.904,487,3.388,489,2.84,527,2.833,583,6.931,584,3.948,585,5.326,607,3.004,621,2.487,1168,5.326,1273,4.284,1829,3.503,1832,5.591,1833,8.236,1834,6.727,2074,5.16,2204,6.142,2215,7.398]],["t/370",[5,1.719,91,4.866,94,2.707,117,0.88,137,3.277,198,3.963,208,2.366,221,3.836,239,5.57,287,3.187,288,7.448,473,2.361,483,3.054,538,2.547,548,6.764,568,3.919,607,2.201,612,2.344,885,4.726,1025,4.008,1089,6.998,1142,5.343,1195,4.726,1198,5.419,1208,3.669,1283,4.492,1308,4.055,1439,4.864,1588,7.44,1613,7.227,1629,6.596,1953,5.021,2216,6.342,2217,7.607,2218,6.177,2219,8.027,2220,5.686,2221,6.534,2222,8.027,2223,5.079,2224,6.764,2225,7.44]],["t/372",[7,1.856,22,2.769,24,3.572,37,8.628,91,3.358,113,4.246,117,1.083,137,2.971,150,4.11,168,2.427,169,4.493,208,3.821,227,4.366,287,1.969,463,2.482,524,4.246,557,2.689,570,4.843,659,4.309,759,3.342,796,4.719,821,4.987,987,3.528,1043,5.353,1091,6.273,1098,5.324,1211,4.158,1286,3.843,1421,4.821,1599,3.005,1614,4.552,1713,5.749,1722,3.358,1791,3.633,1833,7.423,1834,7.802,1847,5.353,2032,3.633,2118,4.01,2198,6.485,2226,6.745,2227,7.277,2228,7.277,2229,7.277,2230,4.411,2231,7.277,2232,4.843,2233,4.455]],["t/374",[7,1.486,15,2.926,20,2.625,29,3.259,36,3.186,37,7.255,47,2.094,73,1.733,91,2.688,97,1.798,99,5.399,117,0.639,137,2.378,150,4.536,164,2.378,168,1.943,169,3.843,208,3.213,209,2.369,229,2.881,239,2.755,243,1.511,287,2.689,296,2.627,402,2.262,471,3.43,483,2.216,505,6.827,527,1.938,568,2.844,570,3.877,596,3.933,606,3.43,612,2.902,613,2.908,615,2.132,659,2.239,740,4.564,764,2.472,768,3.312,796,5.209,923,1.53,961,3.877,1024,2.638,1098,4.554,1110,3.685,1181,2.961,1214,3.036,1277,3.076,1331,2.352,1421,4.124,1471,2.892,1516,4.602,1599,2.405,1714,3.776,1715,2.36,1772,2.979,1791,2.908,1892,5.399,1904,2.943,1953,3.644,1989,3.369,2032,2.908,2118,3.21,2198,7.158,2223,3.685,2224,4.909,2230,5.391,2234,4.056,2235,4.909,2236,5.825,2237,3.877,2238,4.482,2239,3.604,2240,5.284,2241,4.285,2242,4.909,2243,4.482,2244,5.399,2245,5.118,2246,5.825,2247,5.825]],["t/377",[21,3.52,72,3.334,97,3.143,117,1.117,245,3.996,259,1.921,287,3.315,631,6.236,923,2.675,1009,3.628,1170,4.341,1214,5.308,1799,5.656,1833,7.656,1834,8.047,2248,9.441,2249,8.047]],["t/379",[3,2.51,5,1.302,12,1.953,21,1.746,47,2.184,72,2.851,86,3.095,94,2.05,115,2.096,117,0.955,170,4.695,172,1.406,211,2.246,218,2.121,239,2.874,245,2.384,258,2.32,288,3.485,463,2.073,488,3.969,506,3.276,560,2.656,607,2.791,631,3.721,649,2.667,732,1.914,741,4.677,764,2.58,775,1.779,781,2.203,802,2.102,820,2.171,875,1.958,914,2.633,978,1.918,980,2.644,997,2.165,1003,5.305,1009,4.595,1013,4.119,1024,2.752,1056,3.546,1130,4.677,1146,3.188,1218,3.188,1273,2.376,1292,4.677,1332,2.967,1336,5.121,1386,3.721,1443,2.559,1641,4.801,1750,3.515,1775,4.947,1799,6.799,1865,4.471,1941,4.384,1988,2.225,2021,3.683,2032,3.035,2155,3.683,2198,3.991,2250,5.633,2251,6.078,2252,6.078,2253,5.633,2254,5.887,2255,5.633,2256,6.05,2257,4.305,2258,5.34,2259,6.065,2260,3.873,2261,4.165,2262,4.677,2263,4.674,2264,6.078]],["t/381",[20,2.108,37,3.113,44,2.485,85,1.323,94,2.419,97,3.018,117,0.786,137,2.928,150,4.973,208,2.114,209,1.903,218,1.632,245,1.835,258,1.786,259,0.882,287,1.266,316,6.752,338,4.235,483,1.78,545,4.773,575,2.939,631,2.864,748,2.747,759,4.005,828,3.942,867,2.692,874,2.54,895,2.558,910,2.807,923,1.228,955,3.687,1082,2.807,1098,2.522,1143,3.313,1170,1.994,1211,1.97,1214,2.438,1239,2.705,1251,3.516,1255,3.807,1443,3.02,1470,6.044,1599,1.932,1712,3.894,1791,2.336,1833,5.39,1834,5.666,1846,4.346,1981,7.099,2118,6.131,2198,4.709,2230,3.896,2248,4.336,2249,3.696,2265,4.678,2266,4.678,2267,4.678,2268,4.678,2269,4.678,2270,12.722,2271,2.296,2272,4.678,2273,12.507,2274,7.664,2275,3.147,2276,7.172,2277,6.647,2278,5.868,2279,4.678,2280,7.172,2281,5.456,2282,4.678,2283,7.172,2284,3.374,2285,4.678,2286,4.678,2287,4.678,2288,3.982,2289,4.678,2290,7.172,2291,4.678]],["t/383",[2,3.729,5,1.942,12,2.914,30,1.855,72,2.968,83,1.79,117,0.994,123,2.791,209,4.638,267,2.22,296,3.297,418,4.553,419,4.143,433,5.736,496,4.922,548,7.64,552,4.501,666,3.743,760,4.378,781,2.885,953,3.928,973,6.213,1204,3.701,1253,4.636,1307,4.922,1478,4.853,1489,4.756,1734,4.45,1910,5.338,1915,6.54,2271,4.45,2292,7.162]],["t/385",[30,2.131,72,3.409,75,5.613,138,3.214,148,2.656,164,4.251,170,5.613,267,2.551,474,3.836,775,3.048,1489,5.462,1596,3.848,1640,4.651,1734,5.112,2293,10.413,2294,10.413]],["t/387",[12,2.704,38,3.089,106,5.849,116,3.901,187,2.725,209,3.422,296,2.223,391,3.103,418,4.225,433,6.879,510,3.518,562,3.434,575,3.447,607,2.306,655,7.139,763,5.323,775,2.463,830,4.909,978,2.655,1071,4.384,1187,4.041,1260,5.263,1330,4.866,1477,4.356,1489,4.413,1790,3.827,1988,3.98,2016,4.503,2218,6.474,2292,10.416,2295,4.601,2296,8.413,2297,8.413,2298,5.68,2299,8.413,2300,4.707]],["t/389",[38,3.127,87,2.92,153,4.803,154,5.93,156,2.069,197,3.967,209,3.463,218,4.227,296,2.896,299,5.749,391,2.43,419,3.892,433,5.387,445,4.623,569,10.425,618,5.993,619,3.873,645,3.529,654,3.45,666,3.516,671,4.203,697,4.007,733,8.061,760,4.112,775,2.492,867,2.628,980,3.705,1169,4.925,2292,8.656,2301,6.142,2302,8.515,2303,8.515,2304,3.803,2305,4.657,2306,8.515]],["t/391",[12,1.849,20,2.593,30,2.02,39,3.452,83,1.653,96,2.265,117,1.262,123,1.771,138,1.775,153,5.566,163,2.735,175,2.749,178,2.778,196,1.72,210,2.77,263,1.789,276,2.793,296,3.628,418,2.889,419,5.923,433,6.244,457,2.581,470,2.564,510,3.51,526,2.147,529,2.929,562,2.349,569,7.594,615,3.065,663,2.493,670,2.57,733,6.159,763,6.244,867,1.775,998,1.688,1143,4.075,1159,2.998,1169,4.842,1204,2.349,1231,2.793,1678,4.205,1790,2.617,1825,3.357,1909,5.36,1934,3.17,1988,2.106,2027,3.683,2059,3.124,2271,2.824,2292,9.098,2307,5.332,2308,9.869,2309,7.055,2310,5.753,2311,7.759,2312,5.753,2313,3.327,2314,5.753,2315,5.332,2316,5.417,2317,6.292,2318,4.075]],["t/393",[2,4.93,3,1.794,27,2.098,30,1.704,38,1.595,40,2.279,44,1.671,83,1.644,85,1.916,91,2.004,95,3.554,97,1.341,116,3.14,117,1.117,141,4.995,145,2.45,146,4.932,148,2.6,149,3.432,156,1.056,168,1.449,172,1.005,179,2.558,194,1.642,196,1.299,243,1.127,250,1.741,259,2.127,264,2.024,267,1.659,296,3.083,412,3.846,421,1.631,452,1.949,470,1.331,473,1.278,510,1.978,562,1.774,569,5.212,607,1.191,608,3.343,612,1.269,614,2.195,636,2.235,637,2.25,645,3.897,666,2.797,669,5.513,671,2.144,678,2.325,679,2.195,696,3.196,697,2.044,719,3.012,722,2.933,745,4.105,781,1.714,787,1.822,882,2.195,888,5.659,890,2.014,923,1.779,971,3.601,980,1.89,986,2.853,997,2.412,1010,3.025,1062,1.967,1067,2.977,1093,3.432,1110,2.749,1132,2.933,1185,2.513,1471,2.157,1599,1.794,1873,2.853,1961,2.109,2016,2.325,2174,4.719,2292,8.531,2300,2.431,2315,4.026,2319,3.536,2320,4.717,2321,2.781,2322,4.344,2323,6.773,2324,6.773,2325,8.325,2326,4.026,2327,3.134,2328,2.749,2329,9.402,2330,8.678,2331,2.66,2332,4.344,2333,4.344,2334,4.026,2335,3.343,2336,4.344,2337,2.294,2338,4.344,2339,4.026,2340,8.956,2341,4.026,2342,4.344]],["t/396",[10,3.156,30,1.775,86,2.637,146,5.816,165,3.742,172,2.007,196,2.593,210,3.668,214,3.026,216,4.52,401,4.408,414,2.352,504,4.743,557,3.205,569,8.532,584,4.021,607,2.378,612,2.533,618,6.064,760,4.188,892,4.491,985,2.6,997,4.353,1331,3.501,1988,3.175,2193,7.059,2343,11.087,2344,8.039,2345,8.333,2346,11.327,2347,8.673,2348,8.673,2349,8.673]],["t/398",[1,2.202,5,1.929,10,3.277,17,3.97,30,1.843,83,2.456,139,2.649,164,3.677,172,2.084,190,4.446,214,3.143,216,4.694,240,2.045,414,3.373,437,4.373,584,4.176,618,4.926,636,4.635,760,4.35,781,2.279,991,3.953,1331,4.585,1344,5.001,1599,3.719,1961,4.373,2344,8.349,2346,10.526,2350,5.573,2351,9.007,2352,9.007,2353,4.756]],["t/400",[21,3.181,86,3.367,96,4.359,118,4.131,211,4.092,608,8.52,670,4.945,1185,6.403]],["t/402",[22,4.179,43,3.822,118,4.098,296,2.903,641,7.311,796,5.249,1170,4.681,1791,5.485,2118,6.053]],["t/404",[22,2.658,44,1.708,78,3.509,83,1.897,97,2.156,115,2.41,117,0.766,144,3.941,150,2.907,156,1.698,164,2.852,187,2.263,190,5.419,196,2.089,197,3.255,296,1.847,402,2.713,411,2.223,412,2.383,414,1.895,418,3.509,421,2.624,425,4.006,495,4.603,508,4.041,562,2.852,624,3.489,719,3.107,732,2.2,752,4.114,802,3.323,1003,3.641,1098,3.766,1180,3.85,1208,3.193,1281,3.821,1372,4.529,1791,3.489,1942,4.041,2118,3.85,2174,3.053,2193,5.687,2254,4.041,2330,5.376,2354,5.887,2355,3.595,2356,3.551,2357,4.041,2358,6.476,2359,4.277,2360,4.788,2361,6.987,2362,6.987,2363,4.529,2364,6.476,2365,6.139,2366,6.987,2367,6.987,2368,6.987,2369,6.987,2370,6.987,2371,6.987,2372,6.987,2373,6.987,2374,6.987,2375,6.987,2376,5.687,2377,5.376,2378,6.987,2379,6.987,2380,3.255,2381,6.987,2382,6.987,2383,5.04]],["t/407",[21,2.639,30,1.88,44,1.633,72,3.763,80,4.534,84,5.774,105,6.201,117,1.26,145,5.18,175,4.389,214,3.205,229,3.132,296,3.476,418,5.774,527,3.055,1788,5.223,2128,7.068,2384,8.07,2385,7.476,2386,8.601,2387,8.07,2388,6.201,2389,8.07,2390,8.07,2391,6.201]],["t/409",[12,3.984,44,1.847,72,2.569,85,2.219,156,1.907,218,4.063,229,2.676,243,2.035,411,1.816,505,4.201,618,4.292,719,5.512,942,6.262,997,4.415,1480,4.391,2154,4.063,2155,4.755,2355,5.992,2356,3.989,2386,5.378,2392,8.753,2393,7.273,2394,6.613,2395,6.387,2396,4.62,2397,7.273,2398,10.445,2399,10.445,2400,7.847,2401,6.613,2402,7.847,2403,5.378,2404,7.847,2405,7.847,2406,7.847]],["t/411",[44,1.838,72,3.384,218,4.312,267,2.532,2355,6.359,2392,9.289,2407,11.141,2408,9.58,2409,9.082,2410,9.082,2411,10.336,2412,10.336]],["t/413",[22,2.619,30,1.409,43,2.395,44,1.224,72,3.112,94,2.322,117,0.755,148,1.756,156,1.673,160,3.437,190,3.398,215,4.718,218,2.402,238,3.981,248,3.737,267,1.686,270,5.603,296,1.819,323,5.713,421,4.09,437,3.342,495,2.887,578,3.793,586,3.089,612,2.01,646,3.417,732,2.167,785,4.892,892,3.564,1473,4.355,1662,5.174,1778,3.239,1984,4.794,2062,4.155,2075,3.457,2154,6.082,2155,7.118,2157,4.843,2355,4.892,2356,3.499,2392,5.174,2407,8.012,2409,6.048,2410,6.048,2413,6.38,2414,5.801,2415,5.162,2416,4.582,2417,5.603,2418,6.38,2419,6.38,2420,6.38,2421,8.812,2422,5.603,2423,5.801,2424,6.38,2425,3.737,2426,6.38,2427,6.884,2428,6.884,2429,4.407,2430,6.048,2431,6.048,2432,6.38,2433,6.38,2434,5.064]],["t/415",[30,1.93,44,1.677,126,3.687,160,4.709,164,3.851,218,3.291,238,5.455,243,2.446,323,6.131,330,4.003,694,4.605,712,5.049,945,7.677,2355,4.853,2386,6.464,2407,10.703,2408,8.742,2409,10.27,2430,8.288,2431,8.288,2433,8.742,2435,9.432,2436,9.432,2437,9.432,2438,9.432,2439,9.432]],["t/417",[1,1.486,5,1.866,7,1.55,12,1.953,21,1.746,48,2.36,72,2.851,85,2.463,117,1.116,118,3.25,123,3.623,128,4.674,138,1.876,196,3.044,229,2.073,259,1.643,315,3.071,323,6.991,391,3.173,398,2.239,400,3.231,401,3.089,402,4.316,496,3.3,513,3.349,527,3.698,597,2.344,607,1.666,612,2.973,652,4.119,659,2.336,775,1.779,802,3.013,809,1.979,818,6.262,820,2.171,908,2.246,1014,2.86,1019,2.818,1082,3.647,1159,3.167,1185,3.515,1200,5.412,1734,4.276,1793,4.801,1801,3.188,1910,5.128,1961,2.951,2035,4.471,2128,4.677,2152,3.374,2177,3.612,2440,3.758,2441,5.633,2442,5.34,2443,3.374,2444,4.232,2445,4.801,2446,5.633,2447,5.34,2448,4.471,2449,5.226,2450,4.232,2451,4.045]],["t/419",[117,1.142,323,5.462,489,3.474,575,4.267,637,5.392,652,4.925,818,5.325,908,4.587,1910,6.131,2177,6.188,2263,5.7,2452,6.946,2453,5.971]],["t/421",[1,1.217,5,1.066,10,1.811,12,1.599,22,1.894,28,2.485,72,1.629,83,0.983,85,1.408,86,3.705,117,0.993,123,1.532,126,2.939,136,3.358,138,1.536,139,1.464,156,1.209,194,1.881,210,1.647,211,1.839,229,1.697,243,1.291,262,2.319,276,3.65,296,2.865,297,3.352,323,5.686,398,1.833,402,2.919,452,3.373,474,2.77,489,1.66,491,2.13,504,2.722,510,1.453,511,2.264,527,4.149,529,2.631,555,3.932,557,1.839,560,3.285,637,3.893,654,2.017,660,2.13,678,2.664,802,1.722,809,1.621,817,2.664,818,5.163,820,2.686,822,4.046,867,2.796,890,3.486,892,2.577,978,1.571,987,3.872,1019,2.307,1024,2.253,1033,2.514,1036,2.722,1055,1.875,1211,2.095,1213,2.785,1308,2.514,1578,3.83,1640,2.223,1749,2.878,1953,4.703,1984,3.466,2072,2.904,2177,2.958,2263,3.452,2444,8.242,2451,3.312,2454,10.399,2455,10.399,2456,3.016,2457,6.119,2458,4.613,2459,4.373,2460,4.051,2461,4.373,2462,3.741,2463,4.977,2464,4.613]],["t/423",[15,4.835,30,1.97,117,1.055,118,3.592,183,5.083,184,7.605,186,3.901,193,3.546,195,7.672,197,4.485,200,7.578,297,2.831,489,3.211,490,3.96,637,4.985,818,4.923,908,3.557,998,2.824,1431,4.507,1896,5.43,1966,4.863,2263,4.42,2444,6.704,2452,5.386,2465,8.922]],["t/425",[72,3.624,123,3.408,177,5.882,489,3.693,666,4.571,2444,8.962]],["t/427",[5,1.243,28,2.896,30,1.187,39,3.481,40,3.043,44,2.424,72,3.246,117,1.087,148,2.148,172,1.342,182,4.583,186,2.351,190,2.864,194,2.193,195,3.76,197,2.703,210,1.919,243,2.184,296,1.533,408,3.272,442,4.888,452,2.603,510,1.694,514,2.913,617,4.447,620,2.664,637,3.004,639,4.361,678,3.105,748,2.222,781,1.468,814,1.956,892,3.004,908,2.144,923,1.523,985,1.739,1009,3.532,1195,3.415,1535,4.184,1608,4.888,1774,3.67,1829,3.464,1874,4.914,1909,7.398,2156,4.268,2263,4.996,2300,3.246,2316,2.615,2355,2.985,2356,2.948,2444,8.66,2449,3.481,2452,3.246,2454,8.712,2455,10.59,2457,4.722,2466,4.04,2467,5.893,2468,4.508,2469,3.861,2470,5.801,2471,5.376,2472,5.376,2473,5.097,2474,5.376,2475,5.376,2476,4.04,2477,5.376,2478,4.508,2479,8.422,2480,8.422,2481,7.4]],["t/428",[7,1.091,24,2.1,30,1.687,38,1.571,40,2.244,44,1.19,47,1.538,87,1.467,94,1.443,95,1.617,117,0.469,123,1.317,156,1.626,172,1.549,193,1.576,194,1.617,196,1.279,208,1.261,210,2.214,229,1.459,240,0.971,243,2.138,262,1.993,323,7.174,402,4.906,414,1.16,457,1.919,495,1.794,514,2.149,575,1.753,581,3.759,612,1.249,617,4.353,621,1.249,656,2.809,674,3.482,678,2.29,785,3.444,812,2.647,814,2.78,817,2.29,818,2.188,831,2.088,875,1.378,888,6.226,908,1.581,955,2.829,978,2.112,1015,2.112,1019,1.983,1021,2.474,1033,3.381,1055,2.521,1195,2.519,1200,2.274,1211,1.801,1257,2.847,1273,1.672,1283,2.394,1330,2.474,1489,2.244,1609,3.402,1617,2.542,1830,2.306,1909,6.87,2016,2.29,2154,2.215,2156,3.147,2223,2.707,2254,2.474,2263,5.883,2275,1.877,2305,3.66,2316,1.928,2355,2.201,2356,2.174,2383,7.299,2403,5.65,2444,5.74,2452,6.675,2454,10.721,2455,9.428,2481,10.197,2482,4.278,2483,3.482,2484,2.519,2485,6.203,2486,3.147,2487,3.965,2488,3.965,2489,3.965,2490,2.542,2491,3.03,2492,6.295,2493,3.38]],["t/430",[118,4.035,172,2.503,196,3.234,296,2.858,323,5.673,400,5.75,401,5.497,527,3.598,576,3.494,619,4.92,978,3.414]],["t/432",[21,2.639,30,1.88,44,1.633,72,3.763,80,4.534,84,5.774,105,6.201,117,1.26,145,5.18,175,4.389,214,3.205,229,3.132,296,3.476,418,5.774,527,3.055,1788,5.223,2128,7.068,2384,8.07,2385,7.476,2386,8.601,2387,8.07,2388,6.201,2389,8.07,2390,8.07,2391,6.201]],["t/434",[117,1.007,160,4.586,183,4.85,187,2.975,196,3.438,218,4.011,238,5.312,240,2.085,243,2.382,323,6.031,400,6.112,433,5.811,645,3.807,993,3.542,2260,5.112,2301,6.625,2355,5.916,2392,6.903,2447,8.07,2494,8.07,2495,11.496,2496,7.549,2497,8.513,2498,8.513,2499,9.185,2500,8.513]],["t/436",[3,1.932,11,1.613,20,3.931,22,2.729,44,2.059,73,2.596,97,1.444,117,0.786,123,1.44,137,1.91,138,2.213,164,1.91,172,2.018,177,3.278,196,1.399,201,3.69,213,3.094,229,2.446,243,1.86,245,1.835,259,0.882,323,4.575,350,2.682,400,2.487,412,2.975,421,3.672,463,1.595,470,1.433,473,1.376,474,1.723,489,1.56,492,1.848,557,1.729,586,2.099,614,3.623,621,2.094,652,2.212,660,2.002,665,2.864,748,1.792,781,1.814,790,2.864,802,1.618,809,1.523,820,1.671,861,2.807,867,2.213,875,1.507,891,2.284,978,1.477,1019,6.124,1021,2.705,1045,3.032,1059,3.6,1204,1.91,1331,3.521,1490,3.258,1596,1.729,1607,1.861,1609,2.378,1612,4.46,1714,3.032,1715,2.906,1830,2.522,1878,2.864,1948,4.92,1949,3.952,1981,3.807,2154,5.998,2155,7.242,2157,3.189,2355,2.407,2356,2.378,2478,2.504,2486,6.417,2496,3.072,2501,8.983,2502,3.374,2503,7.172,2504,6.647,2505,3.696,2506,3.072,2507,4.678,2508,3.206,2509,4.678,2510,4.11,2511,4.336,2512,4.678,2513,4.678,2514,3.6,2515,4.678,2516,9.266,2517,5.838,2518,2.66,2519,2.995,2520,3.696,2521,3.374,2522,3.313,2523,4.678]],["t/438",[72,3.513,196,3.209,259,2.024,323,5.63,391,3.063,400,5.706,401,5.455,489,3.58,923,2.819,998,3.149,2440,4.631,2524,9.43]],["t/440",[21,2.588,44,1.601,72,3.718,80,4.446,84,5.704,86,2.739,117,0.987,175,4.304,259,2.142,296,2.381,315,5.738,411,2.084,421,3.383,429,6.498,521,3.886,527,2.997,1055,3.394,1788,5.122,2154,4.664,2174,4.963,2355,4.635,2384,7.915,2385,7.332,2386,8.525,2387,7.915,2388,6.081,2389,7.915,2390,7.915,2391,6.081,2396,5.304]],["t/442",[30,1.606,43,2.73,44,1.395,72,3.401,156,1.907,190,3.874,218,2.738,267,1.922,270,6.387,296,2.074,323,5.449,421,4.373,586,3.521,646,3.896,732,2.471,1662,5.898,1778,3.693,2062,3.429,2154,6.419,2155,7.512,2157,5.178,2355,5.346,2356,3.989,2392,5.898,2407,6.613,2410,6.895,2415,5.64,2416,5.223,2417,6.387,2418,7.273,2419,7.273,2420,7.273,2421,9.629,2422,6.387,2423,6.613,2424,7.273,2425,4.261,2426,7.273,2430,6.895,2431,6.895,2432,7.273,2525,7.847,2526,7.847,2527,7.847,2528,7.847]],["t/444",[5,1.917,41,4.034,48,3.475,123,2.755,138,2.762,165,3.862,172,2.071,186,3.627,207,5.599,243,2.321,296,2.365,323,7.049,391,2.554,527,2.977,531,4.443,544,4.495,557,3.308,598,4.15,621,2.614,652,4.233,668,3.339,781,2.264,802,3.913,998,2.626,1607,3.561,2443,4.969,2490,6.722,2529,7.864,2530,8.95,2531,5.801,2532,8.295,2533,8.295]],["t/447",[41,3.087,85,1.937,117,1.039,138,2.924,155,3.503,172,2.193,193,2.524,194,2.589,229,2.336,243,2.457,267,1.678,296,1.81,298,4.238,323,5.698,391,3.1,400,3.642,412,2.336,473,2.015,474,2.524,483,2.606,527,2.279,530,3.006,626,2.624,630,3.746,637,3.547,645,2.839,646,3.401,753,2.839,802,2.369,819,5.742,820,2.447,978,2.162,985,2.053,1011,4.938,1019,3.176,1033,3.461,1097,2.807,1125,3.24,1283,3.833,1596,4.547,1967,4.731,2179,4.695,2223,4.334,2301,4.941,2321,4.386,2403,8.723,2443,6.508,2484,4.033,2490,5.631,2491,6.712,2534,5.772,2535,5.271,2536,6.85,2537,5.772,2538,4.695,2539,6.019,2540,6.85,2541,6.85,2542,6.85,2543,5.772,2544,5.576]],["t/449",[7,1.847,41,3.263,117,0.794,139,2.129,150,3.012,172,2.277,186,3.988,194,2.736,243,2.552,296,1.913,323,5.865,391,3.191,412,2.469,414,1.963,483,2.754,527,2.408,530,3.177,626,2.773,630,3.959,645,3.001,646,3.594,820,2.586,892,3.749,985,2.17,1011,5.129,1097,2.967,1125,3.424,1146,5.162,1266,4.479,1596,4.637,1967,5.583,2016,3.875,2321,4.635,2380,3.373,2443,6.967,2484,4.262,2490,5.849,2491,6.971,2531,4.693,2534,6.1,2537,6.1,2538,4.962,2539,6.361,2543,6.1,2544,5.892,2545,4.432,2546,5.892,2547,6.1,2548,6.71,2549,7.239,2550,8.01,2551,7.239,2552,7.239]],["t/451",[24,4.284,172,2.576,186,3.536,193,4.756,196,2.609,197,4.066,199,5.4,200,5.587,243,2.263,400,4.64,414,3.019,483,3.321,645,4.614,1125,4.128,1596,4.53,1966,6.192,2321,5.587,2443,6.805,2484,5.138,2491,6.182,2531,7.215,2544,7.103,2553,6.182,2554,8.727,2555,7.354,2556,8.727,2557,5.981,2558,8.727,2559,8.727]],["t/454",[240,2.617,323,6.046,2560,10.683]],["t/456",[5,1.846,85,2.438,117,0.945,172,2.555,186,3.493,243,2.864,391,3.152,412,2.94,418,4.329,483,3.28,488,2.907,630,4.714,645,3.573,802,2.982,820,3.079,1097,3.532,1125,4.077,1175,5.66,1596,4.081,1843,5.819,2321,5.519,2443,6.132,2484,5.075,2490,6.563,2491,7.822,2535,8.498,2537,7.264,2538,5.908,2539,7.574,2543,7.264,2544,7.016,2547,7.264,2561,7.016,2562,8.62,2563,11.043]],["t/458",[43,2.809,117,0.885,150,4.404,172,2.449,186,4.289,213,3.483,240,1.833,243,2.094,323,4.235,391,3.37,412,2.753,483,3.072,630,4.415,645,4.387,663,3.498,775,2.363,833,5.719,873,4.181,1097,3.308,1125,3.818,1596,4.632,1771,6.068,1818,4.711,1967,4.031,2057,7.483,2179,5.533,2321,5.169,2443,6.959,2484,4.754,2490,4.798,2491,5.719,2514,6.213,2534,6.803,2538,5.533,2543,6.803,2544,6.571,2548,7.483,2553,5.719,2564,8.073,2565,7.483,2566,8.073,2567,8.073,2568,8.073]],["t/460",[5,1.373,12,2.06,40,3.363,86,1.95,94,2.162,123,1.974,128,6.26,137,2.617,138,1.979,196,1.917,208,1.89,240,1.455,267,1.57,323,6.862,391,2.582,400,3.408,402,2.489,470,1.964,483,2.439,506,3.456,513,3.533,527,2.133,538,2.034,575,3.707,617,3.385,621,1.872,637,3.32,652,4.279,659,4.029,663,2.778,668,2.392,775,2.648,778,4.819,818,6.142,834,2.392,866,4.023,867,1.979,923,1.684,955,2.71,1025,3.201,1029,3.646,1478,4.843,1480,3.587,1586,4.544,1607,2.551,1790,2.916,1791,3.201,1801,4.746,1818,5.279,1967,4.517,2032,3.201,2143,4.328,2263,2.944,2440,3.904,2443,6.668,2449,3.847,2569,4.819,2570,3.432,2571,4.328,2572,6.411,2573,4.394,2574,6.411]],["t/462",[5,1.924,15,2.465,18,3.313,30,1.004,41,2.212,43,1.707,48,2.888,85,1.388,86,1.492,88,2.275,95,1.855,117,1.291,118,4.019,123,1.511,128,2.253,138,1.514,153,2.768,172,1.135,186,1.988,193,1.808,196,2.224,197,2.286,200,3.142,229,2.537,240,1.689,259,1.403,263,1.526,315,2.479,323,6.516,391,2.861,398,1.808,400,2.609,401,2.494,489,1.637,496,2.664,499,4.762,510,1.433,513,4.099,525,2.436,527,1.632,538,1.557,560,2.144,597,3.464,607,1.345,615,3.289,623,2.944,637,4.652,652,3.518,765,3.776,769,2.863,787,2.058,802,3.107,809,2.422,814,1.655,868,2.409,890,2.275,892,3.852,908,3.32,910,2.944,955,3.144,978,1.549,987,1.753,1019,2.275,1021,4.302,1029,2.79,1030,2.557,1082,2.944,1177,2.468,1239,2.838,1249,2.574,1307,2.664,1332,2.396,1386,3.004,1449,2.465,1607,3.574,1622,3.994,1801,2.574,1819,2.645,1910,4.38,1958,2.664,2152,2.725,2263,5.705,2300,2.746,2313,2.838,2440,3.209,2444,6.98,2449,2.944,2451,3.266,2452,5.027,2453,2.814,2456,6.87,2457,3.994,2467,2.916,2575,4.548,2576,4.548,2577,3.994,2578,5.18,2579,3.994]],["t/465",[29,4.158,30,2.05,48,2.885,86,3.046,117,0.815,175,4.787,259,1.401,296,3.346,297,2.185,315,3.754,323,5.255,335,5.361,391,2.121,421,3.762,491,3.18,496,4.035,527,3.77,529,3.505,617,3.924,629,3.689,668,2.773,775,2.175,802,2.571,809,2.42,814,3.378,820,2.655,923,2.631,978,2.346,1033,3.754,1035,4.298,1273,3.916,1421,3.628,1578,7.709,1816,3.233,1909,6.414,1910,4.375,2152,4.126,2174,3.247,2263,3.412,2271,3.648,2385,6.049,2456,7.672,2458,6.888,2578,6.976,2580,7.431,2581,5.187,2582,6.262]],["t/467",[7,1.558,15,3.068,30,1.958,41,1.718,43,2.125,44,2.502,72,2.502,83,2.117,84,3.839,85,1.728,117,1.049,118,2.279,123,1.881,126,3.418,138,1.177,139,2.248,148,2.23,157,4.701,159,3.35,166,3.839,168,1.272,172,0.882,182,7.558,183,6.477,184,9.081,186,3.542,187,3.473,188,1.915,190,3.016,193,2.25,194,1.441,195,3.96,196,1.827,197,4.073,199,5.409,200,6.536,219,1.258,240,0.865,243,0.989,259,0.719,297,2.813,320,2.041,345,2.7,351,2.055,437,2.966,439,5.368,442,3.213,474,1.404,490,1.568,529,1.334,597,1.47,611,1.599,615,2.236,622,3.226,626,2.34,809,1.241,923,2.296,998,1.119,1018,2.471,1019,2.832,1021,2.205,1170,1.625,1177,1.265,1205,2.779,1283,2.133,1398,1.841,1417,2.266,1418,1.545,1431,1.785,1596,2.825,1609,1.938,1614,2.385,1678,1.915,1819,2.055,1874,2.224,1896,2.15,1904,1.926,1917,2.934,1926,2.041,1966,1.926,1984,2.655,2040,3.213,2117,2.805,2263,1.751,2271,1.871,2327,2.75,2425,2.07,2429,2.441,2444,5.323,2465,3.533,2467,2.266,2473,5.368,2583,3.812,2584,8.742,2585,3.812,2586,3.812,2587,4.254,2588,8.742,2589,3.812,2590,5.662,2591,2.7,2592,4.972,2593,3.213,2594,6.109,2595,3.533,2596,3.812]],["t/469",[3,3.187,27,3.727,72,3.363,75,6.638,76,3.747,80,3.81,117,1.126,118,2.88,123,3.163,126,3.017,177,4.696,210,2.554,296,2.04,323,4.048,402,2.997,457,3.463,527,2.567,578,4.253,597,2.976,637,3.996,818,3.947,923,2.027,978,3.243,997,2.749,1033,5.191,1198,5.21,1341,5.678,1443,3.25,1489,4.048,1801,4.048,2440,3.33,2444,9.183,2452,5.749,2575,10.705,2597,6.504,2598,6.282,2599,6.504,2600,7.718,2601,7.718,2602,10.274,2603,7.153,2604,7.718,2605,7.718,2606,7.718,2607,6.504]],["t/471",[5,1.83,9,2.898,30,2.126,44,2.394,72,3.748,85,1.978,117,1.054,136,2.022,148,2.452,156,1.699,168,1.51,172,1.047,182,5.525,183,2.39,184,3.576,190,3.452,193,1.668,195,5.539,218,2.44,219,2.308,259,0.854,267,1.109,296,1.196,323,3.668,345,3.206,391,1.996,418,2.273,442,5.893,473,1.331,474,1.668,527,1.506,529,2.447,615,1.657,620,3.924,621,1.322,637,2.344,639,4.977,654,1.834,660,1.937,668,1.689,712,2.423,719,3.11,752,2.665,802,1.566,809,1.474,814,2.358,875,1.459,923,1.189,957,2.652,978,1.429,985,1.357,1009,1.612,1033,2.287,1159,2.359,1231,2.198,1774,2.864,1801,2.374,1829,1.862,1865,3.33,2035,3.33,2174,1.978,2263,5.043,2316,2.04,2337,3.693,2355,2.329,2376,3.684,2380,2.109,2383,3.265,2440,1.953,2444,9.307,2456,5.178,2457,3.684,2466,3.152,2467,6.526,2468,2.423,2471,6.481,2472,4.196,2473,7.508,2474,4.196,2475,4.196,2476,3.152,2477,6.481,2578,3.152,2581,2.344,2591,3.206,2592,5.692,2608,2.934,2609,4.527,2610,4.527,2611,4.527,2612,4.527,2613,4.527,2614,6.993,2615,8.545,2616,4.527,2617,4.527,2618,4.527,2619,2.186,2620,4.527,2621,4.527,2622,4.527]],["t/472",[7,2.244,38,2.263,40,3.233,41,1.737,44,1.369,47,1.385,48,1.496,85,1.743,117,0.676,118,2.873,124,2.291,136,1.722,137,1.574,138,1.902,139,1.134,148,0.983,150,3.66,165,1.663,172,0.892,178,1.861,186,3.12,196,1.843,229,1.314,243,1,298,2.385,323,6.051,338,1.871,400,5.454,402,3.415,412,1.314,452,1.729,470,1.181,483,1.467,514,1.936,529,1.349,531,1.913,552,1.913,557,1.424,575,3.155,598,1.787,615,1.411,626,1.476,627,1.677,630,2.108,634,2.269,637,3.191,645,1.598,646,3.059,668,1.438,670,1.722,681,1.729,731,2.313,753,1.598,764,1.636,768,2.192,781,1.559,787,1.616,802,2.132,809,1.255,820,1.377,867,1.902,895,2.108,908,1.424,923,2.022,978,2.43,1011,4.013,1019,2.857,1033,3.113,1066,1.903,1114,2.249,1177,1.279,1249,3.233,1257,2.565,1266,2.385,1273,1.507,1278,2.035,1283,2.157,1332,1.882,1349,2.174,1398,1.861,1443,1.623,1477,1.996,1552,3.899,1554,3.572,1596,2.846,1599,1.592,1609,1.959,1618,1.539,1648,5.415,1724,2.966,1749,2.229,1776,2.009,1801,4.039,1967,3.845,2032,1.925,2223,3.899,2239,2.385,2263,5.138,2355,1.983,2357,2.229,2360,6.029,2380,1.796,2403,6.029,2440,2.659,2443,2.14,2444,2.684,2448,4.534,2449,2.313,2452,5.382,2468,5.149,2490,4.576,2532,3.572,2533,3.572,2550,7.16,2573,2.642,2623,3.854,2624,3.045,2625,2.684,2626,7.599,2627,3.572,2628,3.854,2629,3.854,2630,3.572,2631,3.854,2632,3.854,2633,3.387,2634,2.642,2635,7.7,2636,3.854,2637,7.7,2638,3.854,2639,3.854,2640,3.854,2641,3.854,2642,3.854,2643,3.854,2644,3.854,2645,3.854,2646,3.854,2647,3.854,2648,3.854,2649,2.73,2650,3.854,2651,3.854,2652,3.854,2653,3.854,2654,5.712,2655,3.854,2656,3.854]],["t/474",[30,1.53,44,2.021,117,0.82,156,2.954,168,1.648,172,1.143,243,3.062,267,1.21,323,7.066,612,1.443,615,1.809,674,4.022,752,7.159,785,5.849,802,3.121,814,3.644,888,4.152,978,3.175,1033,5.082,1055,2.817,2263,5.716,2275,4.415,2305,4.09,2355,5.56,2356,5.113,2383,8.517,2403,8.836,2444,5.208,2456,4.532,2457,4.022,2481,6.571,2483,6.087,2484,5.923,2485,10.015,2486,3.636,2487,6.931,2488,4.58,2489,4.58,2491,7.126,2492,3.336,2657,9.106,2658,9.022,2659,9.022,2660,4.942,2661,4.942,2662,2.787,2663,4.942]],["t/476",[323,6.046,402,4.475,2452,6.45]],["t/479",[44,1.923,169,4.92,208,3.742,410,7.412,1249,5.673,1812,5.531,2191,6.621,2664,10.815,2665,10.815,2666,6.31]],["t/481",[5,2.214,83,2.041,117,1.133,139,3.04,172,2.86,259,2.331,296,2.732,297,3.04,496,5.612,1618,4.128,1715,4.188,1934,5.695,2667,8.413,2668,7.198,2669,7.954]],["t/483",[5,1.208,7,1.438,10,2.051,47,2.026,77,3.106,78,4.899,83,1.629,84,2.831,86,3.264,94,1.901,117,1.069,123,1.735,156,1.37,187,1.826,210,1.865,242,4.143,243,2.53,259,2.505,263,1.753,267,1.381,296,3.019,297,2.869,330,2.393,338,2.737,411,2.643,414,2.645,415,5.103,421,2.117,425,6.842,486,2.529,490,2.319,740,2.589,767,3.319,875,1.816,953,2.443,957,3.128,985,1.69,1009,4.068,1018,3.654,1170,2.403,1415,3.806,1596,2.083,1712,4.478,1715,3.342,1830,3.039,1841,2.07,2062,2.463,2157,3.668,2271,2.767,2667,4.589,2670,3.926,2671,8.22,2672,5.637,2673,3.416,2674,2.997,2675,8.248,2676,5.637,2677,5.637,2678,5.637,2679,3.993,2680,5.637,2681,5.637,2682,5.225,2683,5.637,2684,3.864,2685,4.751,2686,5.637,2687,5.637,2688,4.751,2689,6.068,2690,4.237,2691,8.248,2692,5.637,2693,3.993,2694,4.953,2695,5.637,2696,5.637,2697,5.637]],["t/485",[1,1.899,33,3.387,44,1.963,79,4.417,82,6.546,83,1.026,95,1.965,117,0.57,123,2.391,144,2.932,156,1.263,164,2.122,172,2.974,173,3.252,201,2.675,229,1.773,243,2.676,259,1.754,263,2.415,296,2.919,297,1.529,411,1.798,419,2.376,421,1.952,425,2.981,452,2.332,473,1.529,490,2.138,607,1.425,612,2.269,615,1.903,646,5.123,666,2.146,679,2.626,689,4,775,1.522,781,1.315,785,2.675,874,4.218,875,1.675,957,1.971,985,2.328,998,2.279,1003,4.048,1009,3.675,1055,1.958,1170,3.311,1596,1.921,1629,3.252,1715,3.148,1727,1.846,1789,3.413,1829,3.195,1868,3.62,1949,5.125,2059,2.822,2271,2.552,2275,3.409,2281,3.252,2519,4.974,2667,4.231,2668,7.186,2670,3.62,2671,7.838,2698,3.907,2699,4.381,2700,5.198,2701,4.818,2702,5.198,2703,3.413,2704,4.381,2705,4.818,2706,5.198,2707,5.198,2708,4.568,2709,5.198,2710,5.198,2711,4.231,2712,4.818,2713,5.198,2714,5.198,2715,5.198,2716,4.107,2717,3.907,2718,4.231,2719,5.198,2720,9.564,2721,5.198,2722,9.301,2723,3.997,2724,5.198]],["t/487",[1,0.469,5,0.731,9,2.184,11,1.176,28,0.958,30,0.698,33,0.63,40,1.006,43,1.187,44,1.934,46,1.515,73,0.571,78,2.313,83,0.673,85,0.542,86,2.747,93,0.894,94,0.647,117,1.029,123,1.05,128,1.566,138,1.421,148,0.489,156,1.119,164,0.783,169,2.095,172,1.776,177,0.877,187,1.105,193,1.256,194,0.725,196,0.574,201,1.755,208,0.565,209,0.78,210,1.524,229,0.654,240,1.045,242,0.963,243,1.838,245,1.338,259,2.377,263,1.06,296,2.283,297,1.881,323,2.415,330,2.715,339,0.869,350,1.1,391,2.849,400,1.813,411,0.789,412,0.654,414,1.735,415,1.187,419,2.104,421,3.392,422,2.82,423,3.997,425,1.1,470,1.411,472,1.228,474,1.256,486,1.53,490,0.789,491,0.821,492,1.347,493,1.616,510,0.996,514,0.963,527,1.135,555,0.696,557,0.709,576,1.102,612,0.56,613,0.958,620,1.566,621,0.996,634,1.129,637,1.766,659,0.737,671,1.684,719,4.552,737,0.873,740,0.881,744,1.813,753,0.795,764,1.448,769,2.687,781,0.863,788,1.2,801,1.187,809,0.625,810,1.259,813,1.336,814,1.15,816,0.783,820,1.645,822,0.769,868,2.26,871,1.065,875,1.099,886,1.894,891,0.936,892,1.766,896,1.049,912,0.903,942,3.58,945,2.776,957,0.727,977,1.359,985,3.068,997,0.683,1004,0.947,1008,0.795,1009,0.683,1011,1,1014,0.903,1018,1.243,1024,1.544,1064,1.187,1097,0.786,1169,1.109,1170,1.453,1177,0.636,1227,1.2,1267,1.14,1278,1.013,1334,2.239,1385,1.384,1399,1.665,1401,1.02,1402,1.151,1441,1.214,1446,1.162,1471,2.771,1596,0.709,1612,0.981,1694,1.384,1708,1.442,1712,2.5,1715,2.592,1722,1.574,1727,1.211,1812,0.981,1820,1.515,1830,1.838,1841,2.05,1858,1.99,1949,1.879,2027,1.228,2059,1.041,2062,2.012,2072,1.119,2128,1.476,2154,1.766,2155,2.79,2156,1.411,2157,1.517,2180,0.74,2191,1.174,2256,1.14,2275,1.497,2305,1.049,2318,1.359,2355,0.987,2386,1.315,2396,2.711,2415,1.041,2425,1.041,2464,1.778,2484,2.008,2518,1.939,2553,1.359,2578,2.375,2582,1.616,2619,1.647,2667,2.776,2668,5.702,2670,2.375,2673,2.067,2682,1.778,2684,3.156,2689,4.106,2690,1.442,2693,3.262,2694,4.046,2717,2.563,2725,3.161,2726,1.918,2727,3.161,2728,1.918,2729,3.161,2730,1.918,2731,4.268,2732,2.416,2733,1.918,2734,1.685,2735,3.161,2736,1.918,2737,2.874,2738,1.918,2739,1.778,2740,1.918,2741,1.918,2742,1.918,2743,1.918,2744,1.515,2745,1.918,2746,1.918,2747,1.918,2748,1.918,2749,1.918,2750,1.778,2751,1.129,2752,1.778,2753,1.778,2754,3.009,2755,1.778,2756,1.778,2757,3.161,2758,1.778,2759,3.618,2760,1.384,2761,1.561,2762,1.778,2763,1.918,2764,1.778,2765,1.561,2766,1.778,2767,1.778,2768,2.509,2769,2.375,2770,1.465,2771,2.375,2772,1.778,2773,4.605,2774,1.918,2775,1.359,2776,1.359,2777,1.685,2778,1.778,2779,3.41,2780,3.41,2781,2.997,2782,1.778,2783,3.41,2784,1.442,2785,1.442,2786,3.41,2787,3.161,2788,1.778,2789,1.243,2790,1.162,2791,1.918,2792,1.918,2793,1.918,2794,4.268,2795,1.778,2796,1.778,2797,1.685,2798,1.918,2799,1.918,2800,1.918,2801,1.778,2802,1.918,2803,1.515,2804,3.41,2805,1.918,2806,3.161,2807,3.161,2808,1.778,2809,1.778,2810,1.778,2811,3.41,2812,2.375,2813,1.228,2814,3.161,2815,1.879,2816,1.616,2817,3.161,2818,2.337,2819,4.026,2820,1.685,2821,1.918,2822,1.918,2823,3.41,2824,1.918,2825,1.778,2826,3.41,2827,1.778,2828,1.778,2829,1.918,2830,1.442,2831,1.616,2832,1.561,2833,1.685,2834,1.918,2835,1.918,2836,1.918,2837,1.918]],["t/489",[5,1.355,7,1.613,10,3.786,16,5.823,27,3.054,38,2.323,85,1.789,117,1.141,118,2.36,126,2.473,136,2.825,138,1.952,139,3.06,172,1.463,203,3.949,208,1.864,209,2.572,211,2.337,245,2.481,249,2.918,252,5.862,259,2.458,262,2.947,263,1.966,290,7.407,296,1.672,297,1.86,330,2.684,391,1.805,402,3.479,433,4.002,474,2.33,489,2.11,513,3.485,529,3.641,536,4.27,537,4.653,550,4.153,554,4.404,560,2.764,562,2.582,620,2.904,626,3.432,637,3.275,678,3.385,734,3.434,912,2.976,998,2.629,1327,3.539,1441,4.002,1478,3.385,1599,3.7,1609,3.215,1801,3.318,1813,5.967,1818,6.072,1853,6.371,1982,4.653,1987,3.627,2035,8.327,2448,4.653,2838,4.48,2839,5.557]],["t/491",[5,1.618,44,2.53,117,0.828,137,3.083,138,2.33,139,2.221,148,2.914,196,2.258,203,3.328,208,2.226,243,1.958,259,1.91,290,6.295,296,2.676,297,2.978,320,4.042,330,4.298,489,2.519,573,4.33,639,3.91,671,3.728,762,5.175,781,2.562,788,4.724,873,3.91,877,5.666,888,4.193,1036,4.13,1277,3.987,1790,3.435,1813,4.33,1817,8.242,1818,5.908,1853,6.199,1934,4.161,1985,5.175,2840,5.811,2841,6.999,2842,6.999,2843,6.999,2844,6.999,2845,7.551]],["t/493",[3,2.579,5,2.547,117,0.43,137,4.219,139,1.153,168,1.307,196,1.867,208,3.926,218,3.606,222,5.876,259,0.739,290,2.159,296,3.143,297,3.497,330,5.047,354,9.689,550,8.114,663,3.848,681,2.802,752,7.275,763,5.619,775,1.147,790,8.304,908,1.448,959,2.729,1082,6.753,1114,2.287,1273,3.044,1347,6.699,1607,1.559,1773,3.366,1791,4.434,1812,5.285,1813,3.581,1818,7.084,1845,5.263,1988,3.783,2016,2.098,2017,5.487,2022,4.349,2271,1.924,2399,5.263,2846,7.803,2847,3.919,2848,3.919]],["t/495",[5,2.515,10,2.902,30,1.856,72,2.105,83,2.252,138,1.985,139,2.346,165,2.775,183,4.788,187,3.402,208,2.673,221,3.073,229,2.193,258,1.553,290,5.442,296,3.346,297,3.453,320,2.177,330,5.206,354,7.313,398,2.369,423,3.627,491,1.74,527,2.139,550,5.954,557,3.351,584,2.982,659,3.485,770,3.419,775,3.753,877,5.876,908,1.503,985,1.928,998,1.887,1066,3.175,1177,2.134,1205,2.926,1273,4.106,1421,3.14,1478,3.443,1483,5.61,1607,1.618,1812,4.637,1813,2.332,1818,7.157,1910,3.787,1989,3.72,2036,4.731,2128,6.977,2440,2.775,2666,5.29,2751,3.787,2842,5.961,2843,5.961,2844,5.961,2849,5.961,2850,9.067,2851,4.731,2852,6.431,2853,3.289,2854,3.859,2855,4.834,2856,5.651,2857,6.431]],["t/497",[10,2.301,43,3.117,44,2.012,72,2.933,83,2.235,87,3.882,91,2.918,102,4.335,117,0.693,139,2.635,177,4.756,183,4.732,186,2.563,187,2.902,190,6.125,196,1.891,208,1.864,259,2.135,264,2.947,290,7.03,354,4.404,402,3.479,437,3.071,490,2.602,529,2.213,557,2.337,612,1.847,620,5.487,637,3.275,678,3.385,748,2.422,753,4.313,923,1.661,1200,3.362,1205,4.076,1349,3.567,1359,4.209,1370,3.69,1818,5.228,1853,3.872,1954,3.275,1961,3.071,1987,3.627,2010,3.956,2036,4.653,2040,5.329,2075,5.685,2076,5.148,2271,3.105,2356,3.215,2858,11.319,2859,7.551,2860,8.305,2861,3.913,2862,6.324,2863,6.324]],["t/499",[7,0.881,27,2.725,44,1.617,73,1.028,78,1.735,87,2.83,97,1.741,115,1.192,117,0.784,137,2.303,139,1.659,148,1.439,150,1.438,156,2.005,168,1.153,187,2.316,208,4.016,209,2.295,211,2.085,213,1.491,214,1.206,217,3.157,218,2.88,229,1.178,243,0.896,248,1.876,259,1.348,265,1.876,296,2.181,320,1.85,330,2.395,354,9.305,414,2.238,463,1.178,470,2.528,472,4.578,473,1.016,488,1.165,529,2.502,550,5.419,552,1.715,557,1.277,579,1.277,607,0.947,626,2.161,654,1.4,663,1.497,681,2.531,748,1.323,752,6.888,759,1.587,761,2.447,763,4.524,764,3.035,775,1.651,783,2.186,787,1.449,790,7.962,830,2.016,867,1.066,923,1.482,955,1.461,969,1.725,987,1.234,1024,1.564,1027,2.161,1033,1.746,1055,1.302,1082,6.177,1097,2.312,1156,2.3,1170,2.404,1233,2.333,1273,2.795,1282,2.542,1327,4.001,1347,5.895,1368,2.447,1393,2.186,1618,1.38,1647,2.016,1663,2.912,1722,1.594,1750,1.998,1773,1.863,1774,2.186,1790,1.572,1791,2.817,1812,1.767,1813,4.732,1819,1.863,1832,2.269,1845,4.754,1853,2.115,1914,1.725,1923,2.016,1926,3.02,1988,3.33,2017,3.036,2211,2.812,2226,3.202,2237,2.3,2239,2.138,2271,1.696,2284,2.492,2316,2.543,2466,3.929,2666,4.172,2744,2.73,2846,4.957,2864,4.957,2865,3.455,2866,3.455,2867,3.202,2868,3.455,2869,3.455,2870,3.202,2871,2.912,2872,2.161,2873,3.455,2874,3.455,2875,3.455,2876,3.455,2877,2.73,2878,2.597,2879,2.447,2880,3.036]],["t/501",[1,2.628,5,1.439,7,1.714,24,3.298,30,2.379,48,2.609,83,1.327,85,1.9,117,1.025,136,3.001,139,3.162,169,3.056,172,1.555,183,5.678,194,2.54,196,2.009,210,2.223,221,3.211,245,2.636,263,2.089,267,2.29,296,3.229,297,2.749,330,2.852,411,2.488,483,2.556,488,2.266,489,2.241,510,1.962,563,4.847,576,2.171,579,2.483,586,3.014,612,2.73,622,4.937,665,4.113,737,3.056,867,2.073,875,2.165,909,4.157,1008,2.785,1009,3.33,1018,4.355,1092,6.744,1205,3.056,1231,3.262,2117,4.943,2587,4.679,2670,4.679,2699,5.662,2854,4.031,2881,2.693,2882,6.719,2883,6.719,2884,6.227,2885,4.847,2886,5.17,2887,5.17,2888,5.308,2889,9.349,2890,11.624,2891,6.719,2892,4.943,2893,5.05]],["t/503",[17,4.263,26,3.631,30,1.444,33,2.316,44,1.255,93,3.288,117,1.06,126,2.759,172,2.553,177,3.225,196,2.11,213,3.045,216,3.678,240,1.602,241,3.804,296,1.865,391,2.014,421,2.65,510,2.824,538,2.239,553,3.752,576,2.28,666,2.914,764,2.995,775,2.066,787,2.96,976,4.465,978,2.228,985,3.307,1008,2.925,1071,3.678,1097,2.892,1208,3.225,1279,4.047,1292,5.431,1344,3.918,1518,4.574,1570,6.541,1722,3.256,1751,4.047,1827,5.431,1934,3.888,1949,6.08,2154,3.654,2155,7.536,2157,4.301,2415,5.251,2496,7.245,2894,6.201,2895,7.057,2896,5.431,2897,7.563,2898,8.498,2899,3.86,2900,6.192,2901,7.057,2902,5.575,2903,4.518,2904,5.304]],["t/505",[4,2.443,11,2.018,17,2.578,48,3.29,83,1.155,117,0.929,138,1.805,168,1.951,172,1.353,177,4.553,179,3.444,187,1.895,196,1.749,201,3.01,217,3.273,240,2.632,243,2.197,258,2.233,259,1.103,267,2.075,271,3.67,285,4.45,287,1.583,296,1.546,330,2.483,391,2.843,411,1.961,421,2.197,445,3.176,452,2.624,468,4.009,473,1.72,576,1.89,586,2.624,660,2.503,668,2.182,670,2.613,719,3.768,764,2.483,773,4.761,775,1.712,809,1.905,820,2.09,871,3.248,985,2.54,997,2.083,998,1.716,1013,2.767,1055,2.204,1099,3.893,1110,3.701,1231,2.84,1249,3.068,1344,3.248,1364,3.745,1589,3.659,1751,3.354,1926,3.131,1948,3.299,1949,3.223,1963,5.421,1966,2.955,2154,6.611,2155,6.619,2157,4.43,2256,3.476,2415,3.176,2486,4.303,2502,4.219,2518,3.326,2806,5.421,2807,5.421,2812,6.938,2818,4.009,2900,3.745,2902,4.621,2905,4.143,2906,5.421,2907,3.701,2908,5.849,2909,5.9,2910,3.893,2911,5.421,2912,5.849,2913,4.303,2914,5.849,2915,4.009]],["t/507",[1,1.788,7,1.866,30,1.497,33,3.253,43,2.545,48,2.84,83,1.444,117,0.802,163,3.477,177,3.343,217,4.093,219,2.414,240,1.661,245,4.41,259,1.38,267,1.792,296,2.619,339,3.312,391,2.088,411,1.693,418,3.674,463,2.495,526,2.729,576,2.363,627,4.312,649,3.21,666,3.02,802,2.53,809,2.382,885,5.835,888,4.061,896,4.001,967,4.576,987,2.613,1007,5.381,1009,2.605,1146,3.837,1180,4.031,1204,2.986,1518,6.424,1815,5.277,1816,3.183,1878,4.478,1966,3.696,2133,4.869,2155,4.433,2157,3.253,2256,4.347,2415,3.972,2486,5.381,2496,4.803,2518,4.16,2555,6.164,2812,7.828,2815,5.461,2894,6.427,2916,7.315,2917,7.315,2918,5.181,2919,6.78,2920,7.315,2921,5.094,2922,5.954]],["t/509",[1,1.734,5,2.079,17,3.126,30,1.986,44,1.725,83,1.916,85,2.745,117,0.778,138,2.995,172,2.56,177,3.242,201,3.65,213,3.06,217,5.431,240,1.61,259,1.338,267,2.377,271,4.382,285,4.942,297,2.086,468,4.861,493,5.977,510,2.071,511,3.226,607,1.945,612,2.071,637,3.673,719,3.154,809,3.16,820,2.534,885,4.176,1025,3.541,1056,4.138,1180,3.908,1211,2.986,1273,2.773,1344,3.938,1431,3.321,1629,4.437,1820,5.603,1949,3.908,1966,4.903,2157,3.154,2415,3.851,2502,5.116,2668,4.939,2689,5.218,2784,5.331,2794,6.574,2812,4.939,2814,10.254,2815,6.555,2897,4.861,2900,4.541,2903,4.541,2923,4.541,2924,5.977]],["t/511",[7,2.013,13,4.646,17,3.478,30,1.615,177,3.607,201,4.061,217,4.416,221,3.771,240,1.791,243,2.704,271,4.577,285,5.549,296,2.756,330,3.35,445,4.285,502,4.525,510,2.305,576,4.013,582,4.348,586,3.541,636,4.061,666,4.306,764,3.35,820,3.725,870,4.735,967,4.937,1180,4.348,1344,4.382,1402,4.735,1446,4.782,1489,4.14,1518,5.115,1717,4.883,1751,4.525,1924,3.405,1949,4.348,2157,3.509,2161,5.59,2518,4.488,2784,5.931,2894,6.934,2900,5.053,2911,7.314,2925,6.235,2926,6.073,2927,6.235]],["t/513",[1,0.884,4,1.51,5,1.995,7,1.493,12,1.162,20,1.63,24,1.775,30,1.906,44,1.311,48,1.404,51,3.704,72,1.184,73,1.742,78,1.816,83,1.456,84,1.816,85,1.656,87,2.53,96,1.423,117,1.021,148,0.922,166,1.816,172,1.355,177,1.652,183,1.909,186,1.465,196,1.081,208,1.726,209,1.471,220,1.746,229,1.996,240,1.924,245,1.418,259,0.682,267,1.434,287,0.978,296,3.296,297,2.931,330,3.952,351,3.156,391,2.844,411,2.844,414,0.981,418,1.816,419,2.675,421,2.77,425,4.861,463,1.233,473,1.063,492,1.428,502,2.073,520,1.872,525,1.795,541,2.149,564,2.11,575,1.482,576,1.168,584,1.676,588,4.306,597,3.591,612,1.71,648,1.922,659,2.835,660,1.547,693,2.11,694,3.601,733,2.66,760,1.746,770,1.922,775,1.058,781,0.915,787,2.455,831,1.765,837,2.374,840,1.949,875,1.886,923,0.95,978,1.848,985,2.211,1004,1.785,1009,3.317,1030,1.884,1056,2.11,1097,1.482,1140,2.039,1177,1.2,1181,2.975,1205,1.645,1228,3.047,1249,1.897,1260,2.262,1266,4.563,1277,1.909,1302,2.149,1334,2.374,1433,3.177,1439,2.191,1443,1.522,1477,1.872,1479,2.943,1485,2.344,1615,1.884,1640,1.615,1724,2.782,1732,2.975,1812,1.849,1816,1.573,1838,2.11,1848,2.782,1894,5.426,1976,1.805,1988,2.143,2007,3.047,2059,3.178,2122,2.66,2123,2.149,2154,1.872,2155,2.191,2156,2.66,2177,2.149,2186,2.169,2191,2.214,2355,1.86,2386,2.478,2396,2.129,2398,3.047,2443,3.25,2451,3.896,2466,2.518,2493,2.856,2506,2.374,2531,2.344,2578,2.518,2619,1.746,2666,2.11,2670,2.518,2679,2.561,2684,4.012,2717,4.4,2732,2.561,2854,3.512,2928,2.407,2929,3.351,2930,3.616,2931,2.782,2932,2.943,2933,3.616,2934,2.073,2935,3.616,2936,5.854,2937,4.4,2938,3.351,2939,3.047,2940,2.608,2941,3.616,2942,2.856,2943,2.943,2944,2.518,2945,3.616]],["t/515",[1,2.664,73,3.243,118,4.067,259,2.056,296,3.37,527,3.626,576,3.521,619,4.958,2946,10.899]],["t/517",[71,7.176,81,7.038,134,8.747,510,3.233,2355,5.697,2854,6.643,2855,8.321]],["t/519",[1,2.678,83,1.681,94,2.872,123,3.73,139,2.504,144,4.803,156,2.069,164,3.476,172,2.535,173,5.326,179,5.013,187,2.758,194,3.219,204,6.031,243,2.842,267,2.086,621,3.2,697,4.007,722,5.749,748,3.262,1001,7.892,1028,4.134,1097,3.489,1393,5.387,1596,4.049,1615,4.438,2271,4.18,2478,4.558,2698,6.4,2947,9.628,2948,8.515,2949,9.628,2950,7.892,2951,6.4,2952,7.892,2953,7.482,2954,6.142]],["t/521",[1,2.069,30,2.234,39,5.078,44,2.446,83,1.671,122,3.455,123,3.929,144,4.774,148,2.784,156,2.935,164,3.455,172,2.526,175,4.044,411,1.958,510,3.187,527,2.816,621,2.472,668,3.158,816,3.455,985,3.271,1055,3.189,1909,7.735,2355,4.355,2698,6.361,2759,7.831,2955,7.844,2956,7.844]],["t/523",[21,2.927,117,1.117,276,4.946,472,6.522,473,2.996,474,3.753,489,3.398,510,3.578,759,4.678,770,6.984,908,3.764,978,3.215,1791,5.086,2937,7.656,2957,8.95,2958,10.186]],["t/525",[30,2.647,73,2.925,91,4.535,117,1.077,118,4.473,172,2.274,208,3.534,296,3.419,411,2.774,473,2.891,610,4.88,612,2.87,678,5.261,1009,4.27,1125,4.649,1896,5.544]],["t/527",[21,2.948,117,1.125,123,4.057,137,4.189,138,3.167,156,2.493,172,2.374,276,5.974,473,3.018,489,3.423,529,3.591,607,3.373,2271,5.037,2937,7.712]],["t/530",[1,1.335,5,1.726,12,1.755,24,2.681,28,2.727,30,2.563,33,1.793,39,3.277,43,1.9,72,2.638,83,1.078,85,2.279,87,2.764,117,0.599,122,3.29,123,2.948,136,2.44,148,2.443,164,2.23,168,1.822,172,1.264,183,2.884,208,2.376,209,2.221,220,2.638,229,2.748,258,3.076,267,1.338,296,3.225,297,2.816,391,1.559,401,2.776,411,2.446,418,2.743,425,5.491,470,2.934,488,1.842,510,3.293,527,3.186,529,1.911,547,3.497,552,2.711,555,1.981,575,2.238,597,2.106,622,2.884,645,2.264,649,2.397,659,2.099,666,3.954,668,2.038,693,3.187,694,3.934,697,3.792,760,2.638,774,3.344,775,2.359,783,3.456,816,3.29,820,1.951,868,2.681,875,1.76,978,1.724,980,3.506,1009,3.766,1025,2.727,1055,2.058,1120,2.965,1179,4.018,1205,2.485,1218,2.865,1272,3.743,1302,3.246,1307,2.965,1330,3.159,1417,3.246,1477,2.828,1829,2.247,1934,3.009,1966,2.759,2059,2.965,2241,4.018,2668,3.803,2757,5.062,2759,3.54,2949,4.799,2959,3.94,2960,5.462]],["t/532",[148,2.846,186,4.522,510,3.259,1909,8.277,2759,7.234,2956,10.343]],["t/534",[78,5.153,85,2.902,117,1.125,123,3.788,148,2.617,155,5.247,172,2.374,238,5.934,243,2.661,411,2.374,510,3.593,1004,6.074,1009,3.655,2961,10.261,2962,8.646]],["t/536",[83,2.576,84,5.695,510,3.312,775,3.319]],["t/538",[411,2.603,510,3.285,775,3.293,1009,4.007,2939,10.945]],["t/540",[83,1.982,138,3.098,150,5.433,164,4.099,172,2.323,243,2.604,411,2.323,425,5.757,510,2.932,529,3.513,619,4.567,1009,3.576,2271,4.929,2963,9.306,2964,10.671,2965,7.424]],["t/542",[3,5.358,83,1.954,117,1.085,164,4.041,172,2.29,243,2.567,411,2.29,425,5.676,510,2.891,529,3.464,1009,3.526,1010,6.893,2271,4.859,2963,9.174,2964,10.579,2965,7.677,2966,9.898]],["t/544",[2,5.455,12,3.347,141,6.248,164,4.251,296,3.281,391,3.543,510,3.041,562,4.251,2153,7.827,2194,9.15,2967,9.651,2968,9.651]],["t/546",[2,5.438,5,2.214,83,2.041,141,6.202,164,4.22,296,3.266,391,3.527,510,3.019,562,4.22,2153,7.769,2193,8.413,2967,9.58,2968,9.58]],["t/548",[78,4.936,85,2.78,86,2.989,194,3.715,219,3.243,222,5.589,249,4.535,267,2.407,391,2.805,414,3.508,425,5.636,492,3.883,527,3.27,529,3.439,770,5.225,952,7.231,1307,5.336,1441,7.585,2737,8.283,2957,8.636,2969,9.11]],["t/550",[30,2.422,210,3.916,296,2.544,391,2.747,411,2.227,425,5.52,510,2.811,565,5.617,764,4.086,770,7.109,773,7.835,978,4.046,1004,4.752,1009,3.429,1049,5.52,1294,7.605,2230,4.3,2854,5.776,2970,7.835,2971,6.499]],["t/552",[9,4.758,30,2.05,40,3.898,48,2.885,83,1.467,84,3.732,94,2.506,95,3.786,117,1.098,210,3.314,267,1.82,296,2.995,297,2.185,411,1.72,425,4.261,510,3.309,526,2.773,602,4.649,621,2.17,659,2.856,670,3.319,737,3.38,770,5.325,812,4.598,814,3.378,830,4.336,867,2.293,978,2.346,985,2.227,1033,3.754,1181,3.777,1239,4.298,1475,4.817,1483,4.598,1727,2.639,1735,4.758,1791,3.711,1974,3.777,2062,3.247,2157,4.454,2182,4.261,2298,5.017,2490,5.953,2657,6.262,2854,4.459,2905,5.264,2957,6.53,2971,5.017,2972,7.431,2973,6.338,2974,6.049,2975,5.52,2976,5.585,2977,7.431,2978,5.719,2979,6.888]],["t/554",[30,1.943,72,3.842,73,2.826,81,5.193,83,1.875,102,6.508,124,5.643,139,3.452,210,3.142,296,2.51,297,2.793,457,4.261,510,2.773,511,4.32,597,3.662,607,2.603,615,3.476,659,3.649,1072,4.797,1162,5.492,1617,5.643,2626,10.065,2854,5.698,2856,8.344,2980,9.496]],["t/557",[44,1.644,47,3.323,85,2.615,97,2.853,117,1.265,146,4.85,164,3.774,208,3.403,510,2.7,550,6.071,586,4.148,621,2.7,759,4.245,764,3.924,775,3.379,781,2.339,833,6.549,834,3.449,888,6.409,1177,3.067,1449,4.643,2021,5.603,2304,4.129,2666,5.394,2759,5.993,2965,5.257,2981,11.544,2982,8.123]],["t/559",[47,3.887,117,1.186,208,3.188,510,3.158,550,8.335,775,3.166,781,2.736,888,6.005,2666,6.31,2759,7.01]],["t/561",[47,3.743,117,1.142,208,3.659,296,2.752,510,3.041,775,3.048,781,2.634,888,5.782,1715,4.22,1812,6.782,2191,6.375,2666,6.076,2759,6.75]],["t/563",[47,3.917,117,1.195,193,4.698,208,3.213,510,3.183,775,3.19,781,2.757,2666,6.359,2759,7.065]],["t/565",[47,3.917,117,1.195,208,3.213,510,3.183,775,3.19,781,2.757,2578,8.88,2666,6.359,2759,7.065]],["t/568",[5,2.214,30,2.115,146,5.422,156,2.512,167,5.878,194,3.907,205,7.321,219,3.411,510,3.019,552,5.131,604,6.202,607,2.834,981,9.58,2271,5.074,2854,6.202,2983,12.358]],["t/570",[30,2.115,90,3.796,117,1.133,210,4.089,411,2.392,510,3.019,529,3.617,964,5.784,1465,4.659,1974,6.281,2854,7.933,2984,9.58,2985,9.082]],["t/572",[90,3.768,117,1.125,210,4.071,411,2.374,470,3.143,510,2.997,529,3.591,964,5.741,1465,4.625,2060,5.184,2854,7.908,2984,9.51,2985,9.016,2986,10.811]],["t/574",[90,4.886,117,1.15,164,4.283,172,2.428,186,4.251,193,3.865,510,3.064,529,3.671,666,4.332,737,4.772,1330,7.211,2854,6.295]],["t/576",[117,1.142,138,3.214,218,3.633,510,3.041,529,3.644,615,3.812,775,3.882,812,6.443,955,4.402,1277,5.499,1509,8.792,2854,7.448]],["t/578",[90,4.003,117,1.195,138,3.364,411,2.522,510,3.183,529,3.814,619,5.801,2854,7.651]],["t/580",[117,1.186,138,3.338,210,3.578,263,3.947,411,2.937,510,3.158,529,3.784,2854,7.617]],["t/583",[41,3.597,47,2.869,48,3.099,72,2.613,85,2.257,86,2.427,87,2.737,94,2.692,95,3.017,116,3.701,208,2.353,211,2.95,219,3.467,255,4.837,267,1.955,287,2.16,296,3.104,330,4.459,411,2.431,607,2.188,610,3.962,629,3.962,735,4.243,759,3.665,812,4.938,816,3.258,875,2.572,969,3.985,987,2.851,1009,2.843,1055,3.007,1066,3.94,1132,5.389,1170,3.401,1214,4.16,1334,5.241,1364,5.11,1479,6.496,1591,5.653,1732,4.057,1807,3.854,1934,4.398,1988,2.922,2188,5.558,2443,5.833,2531,5.174,2679,5.653,2909,5.558,2987,7.981,2988,7.398,2989,6.142]],["t/586",[5,1.609,22,2.858,28,3.75,86,2.284,117,0.823,128,5.835,168,2.505,267,2.471,296,3.219,412,2.561,421,2.821,422,3.795,488,2.533,495,5.487,514,3.772,527,2.499,579,2.776,586,3.37,598,3.482,607,2.059,654,3.044,737,4.59,760,3.627,775,2.199,822,3.01,867,2.318,890,3.482,978,2.371,1162,4.344,1208,3.433,1332,3.667,1443,3.162,1584,6.625,1790,4.59,1844,4.598,1988,2.75,2062,3.282,2396,5.94,2907,4.752,2934,4.307,2990,10.65,2991,9.155,2992,6.329]],["t/588",[21,2.766,47,3.46,117,1.055,249,4.442,338,4.674,411,2.227,495,4.037,597,3.712,602,6.022,668,3.592,985,2.885,1009,4.216,1177,3.194,1200,5.118,1281,5.265,1521,5.474,1584,6.321,1819,5.189,1942,6.846,2429,6.163,2570,5.153,2907,6.091,2991,7.235,2993,9.626,2994,9.626]],["t/590",[26,1.837,30,1.186,33,1.172,36,1.952,40,3.039,44,2.053,47,2.082,48,2.249,83,1.144,85,1.638,95,1.349,115,1.998,117,0.391,118,1.332,126,1.396,137,2.365,138,2.256,139,1.05,150,3.501,156,0.867,187,1.156,197,1.663,198,1.762,206,1.952,221,1.706,285,1.594,296,3.238,297,1.05,299,2.41,339,2.623,391,1.653,411,2.516,421,3.919,422,4.251,423,3.268,425,5.681,457,1.602,492,1.41,505,1.911,508,3.351,514,1.793,527,2.432,562,1.457,573,2.047,597,1.377,615,2.677,618,3.999,627,1.553,663,3.168,670,1.594,719,4.406,737,1.624,739,2.163,758,5.379,764,1.515,775,1.045,816,2.985,833,2.528,867,1.102,892,1.848,907,2.446,923,1.92,985,1.736,991,1.567,998,1.047,1009,1.271,1075,2.065,1082,2.142,1120,3.145,1143,4.103,1151,2.047,1170,1.521,1180,1.967,1208,2.648,1331,2.952,1489,1.872,1607,3.681,1717,2.209,1722,1.647,1727,2.057,1776,3.019,1801,1.872,1904,1.803,1909,2.285,1952,2.102,2032,1.782,2156,2.626,2275,3.209,2355,5.595,2356,2.944,2357,3.351,2358,3.308,2415,1.938,2449,2.142,2451,2.376,2484,3.411,2502,2.575,2573,2.446,2668,5.859,2679,5.179,2759,5.996,2839,3.136,2855,5.495,2881,1.431,2973,2.259,2995,3.57,2996,7.393,2997,3.57,2998,5.274,2999,2.446,3000,5.793,3001,7.311,3002,3.308,3003,5.793,3004,5.793,3005,2.486,3006,3.57,3007,3.57,3008,3.57,3009,7.311,3010,3.57,3011,3.57,3012,3.008,3013,3.57,3014,3.57,3015,3.57,3016,3.57,3017,3.57,3018,6.777,3019,3.57,3020,5.793,3021,3.57,3022,3.57,3023,3.57,3024,2.747,3025,3.308,3026,3.57,3027,2.683,3028,2.185,3029,3.57,3030,2.259,3031,3.308,3032,2.163]],["t/592",[22,3.638,118,3.567,168,3.189,291,5.35,296,2.527,457,4.29,527,3.921,562,4.812,775,2.799,985,3.533,1082,5.737,1170,4.074,1489,5.015,1711,5.393,1801,5.015,2355,6.065,2484,6.94,3027,7.186,3033,11.787,3034,10.924,3035,7.782]],["t/594",[5,1.905,12,2.858,85,2.515,117,0.975,118,4.203,136,3.972,137,3.631,139,2.615,186,4.565,196,2.659,259,1.677,296,2.977,297,2.615,330,3.775,466,5.84,527,3.748,536,6.004,587,6.684,753,3.686,802,3.076,892,4.605,908,3.287,998,2.609,1033,4.493,1596,3.287,1801,4.665,2035,6.543,3036,8.211,3037,7.215]],["t/596",[6,1.674,9,6.456,10,1.198,12,1.058,22,2.063,44,1.425,47,2.881,85,0.931,86,1.001,93,1.534,94,1.829,96,1.296,115,1.136,117,0.879,139,0.968,148,1.764,150,2.257,165,1.421,167,1.872,169,1.498,187,1.757,193,1.998,217,6.291,239,3.27,240,0.747,249,2.502,296,3.046,421,3.581,422,4.818,423,1.857,457,1.477,470,2.118,471,1.939,482,1.788,491,1.409,499,3.472,515,2.601,520,1.705,530,4.185,536,2.223,557,1.217,568,1.608,579,2.004,615,1.205,621,2.019,639,1.705,645,2.248,659,4.196,660,1.409,663,4.871,666,2.855,670,1.471,671,2.677,759,1.512,764,1.398,775,1.588,832,1.739,875,2.228,892,1.705,907,2.257,923,1.816,953,1.427,955,1.392,978,1.712,985,3.022,993,1.27,997,1.173,1030,1.716,1033,1.664,1034,2.601,1055,1.241,1070,1.654,1149,2.422,1177,2.294,1181,1.674,1195,1.939,1227,2.06,1257,2.192,1273,1.287,1277,1.739,1278,1.739,1283,3.035,1326,2.893,1349,1.857,1443,2.911,1449,2.724,1478,3.701,1487,2.134,1565,2.162,1749,1.904,1801,1.727,1815,2.375,1816,1.433,1819,1.775,1844,2.016,1874,4.035,1967,1.644,1989,1.904,2032,2.708,2123,1.957,2177,1.957,2263,3.681,2304,1.471,2313,1.904,2553,2.332,2579,2.68,2597,2.775,2598,2.68,2760,2.375,2913,2.422,2978,4.173,3036,8.008,3037,1.921,3038,7.789,3039,6.914,3040,3.293,3041,3.99,3042,3.293,3043,3.293,3044,3.293,3045,3.052,3046,10.908,3047,3.293,3048,3.052,3049,3.293,3050,7.763,3051,8.017,3052,6.914,3053,3.293,3054,3.293,3055,3.293,3056,4.57,3057,5.423,3058,2.332,3059,5.423,3060,3.293,3061,3.293,3062,3.052,3063,2.534,3064,3.293,3065,5.423,3066,2.68]],["t/598",[12,1.577,21,2.137,22,1.867,24,2.409,43,1.707,44,1.782,74,4.706,85,1.388,90,3.956,94,2.509,128,5.571,208,1.447,218,2.595,219,1.619,259,0.925,276,2.383,296,3.489,297,1.443,410,6.157,411,2.807,418,2.465,419,4.106,429,7.231,466,3.222,470,1.503,474,1.808,526,1.831,527,1.632,532,3.036,557,1.813,571,2.422,575,2.011,586,2.202,630,2.684,641,4.951,773,3.994,866,2.182,867,1.514,923,1.289,955,3.144,969,2.45,997,2.649,1062,3.368,1090,2.436,1091,2.746,1097,3.048,1142,3.266,1180,2.704,1185,6.812,1187,2.357,1204,2.003,1260,3.07,1599,2.026,1636,3.688,1640,2.192,1735,3.142,1816,2.135,1896,2.768,2359,3.004,2440,5.465,2679,3.476,2902,3.877,2909,7.895,2915,7.77,3067,5.899,3068,7.714,3069,7.502,3070,6.497,3071,5.366,3072,5.366,3073,4.907,3074,4.548,3075,3.877,3076,3.417,3077,6.894,3078,2.974]],["t/600",[5,1.253,7,2.161,30,2.235,72,2.774,73,1.741,78,2.938,80,2.887,83,1.673,117,0.641,128,2.686,148,2.161,153,4.779,156,1.421,179,3.444,211,2.162,243,1.517,245,2.295,259,1.103,267,1.433,296,3.492,297,1.72,330,2.483,391,1.669,411,3.131,418,2.938,419,3.872,462,3.354,463,1.995,470,1.792,473,1.72,487,2.327,492,2.311,527,1.946,530,2.567,552,2.904,582,3.223,597,2.256,607,1.604,615,3.102,621,1.708,659,2.248,660,2.503,668,2.182,670,2.613,671,4.183,737,2.661,748,2.24,781,2.52,869,3.299,873,3.029,887,3.619,953,2.534,980,2.545,987,2.09,1004,2.887,1037,5.134,1055,2.204,1066,2.887,1090,2.904,1198,3.949,1204,2.388,1265,3.745,1397,4.219,1443,2.463,1455,3.326,1486,4.143,1727,4.427,1790,2.661,1934,3.223,1988,2.141,2055,3.949,2130,3.841,2355,3.01,2490,3.476,2570,3.131,2759,3.792,2881,2.344,2892,4.303,3079,5.849,3080,4.929,3081,5.849]],["t/602",[85,2.704,89,5.578,90,3.511,128,5.413,210,3.163,219,3.155,391,2.729,411,2.727,538,3.033,612,2.792,620,4.39,787,4.01,987,3.416,1017,5.981,1019,4.433,1159,4.982,1185,5.53,1727,4.186,1829,3.933,2304,4.27,2326,8.861,2679,6.772,2996,6.772,3082,5.437,3083,9.561]],["t/604",[1,0.692,5,0.762,7,0.274,12,0.91,22,0.409,24,0.528,26,0.554,30,0.86,40,0.564,43,0.374,44,0.747,47,1.51,48,1.381,72,1.164,78,1.01,79,1.61,80,1.755,82,1.694,83,0.944,84,1.422,85,1.633,86,3.051,87,0.69,89,2.075,91,0.928,94,0.678,97,0.332,115,2.141,117,1.068,128,4.607,138,1.297,139,0.316,146,2.204,148,2.011,149,0.85,156,1.403,168,1.402,172,0.655,175,0.514,178,0.971,186,0.436,188,0.54,190,0.993,211,0.743,213,0.464,214,2.015,218,1.668,219,2.846,220,0.52,229,2.116,242,0.54,243,2.485,249,0.496,250,1.425,263,0.334,267,0.693,296,3.293,297,2.047,330,2.029,350,0.617,391,1.199,398,0.741,408,0.607,410,4.77,411,1.759,414,0.545,415,0.666,418,1.01,419,2.185,421,2.614,422,2.415,423,0.607,425,3.784,426,0.907,429,6.911,432,1.767,452,0.902,463,0.686,470,2.572,488,0.955,491,1.798,492,0.425,496,0.584,506,1.084,510,0.314,511,0.489,514,0.54,527,1.921,529,2.021,538,0.341,555,1.027,573,1.623,575,1.457,576,0.348,584,0.499,597,1.092,607,0.776,612,1.227,613,0.537,615,0.736,617,0.568,620,0.923,621,0.314,639,0.557,645,0.833,659,3.398,663,1.541,668,1.327,670,0.898,679,0.544,693,0.628,694,2.051,697,1.977,719,1.259,720,0.716,732,0.339,734,0.584,748,1.084,760,0.52,764,0.457,775,0.589,781,1.995,784,0.85,787,0.451,788,2.629,809,0.35,812,0.666,818,0.55,820,1.011,822,1.684,831,0.525,834,0.401,867,0.874,868,1.746,875,1.146,878,0.697,908,1.046,912,0.506,923,1.256,955,1.503,978,1.123,985,0.849,987,0.384,991,1.242,997,1.497,998,0.831,1004,0.993,1009,1.267,1013,0.951,1024,0.487,1027,0.673,1031,0.628,1033,0.544,1037,0.652,1090,0.534,1160,0.737,1177,0.357,1180,0.593,1185,0.622,1198,3.58,1204,0.439,1208,0.492,1218,0.564,1231,0.522,1273,0.786,1278,0.568,1286,1.062,1307,1.092,1332,1.382,1334,0.706,1349,1.134,1396,0.612,1398,0.52,1401,1.891,1443,0.847,1446,0.652,1471,0.998,1489,0.564,1521,0.612,1586,0.54,1596,0.398,1607,0.8,1618,0.803,1694,0.776,1727,1.263,1732,0.547,1735,0.689,1776,0.561,1790,0.489,1818,2.075,1819,0.58,1829,1.463,1838,0.628,1841,0.738,1873,0.706,1875,1.637,1896,0.607,1904,0.544,1934,3.636,1949,0.593,1988,3.621,2010,1.258,2059,1.537,2060,0.544,2128,1.547,2143,0.726,2154,3.935,2155,3.999,2165,1.32,2256,0.639,2271,0.528,2275,0.472,2301,0.776,2304,0.898,2313,0.622,2316,1.894,2318,0.762,2334,0.997,2355,1.83,2356,1.439,2383,1.451,2396,2.094,2397,0.997,2415,0.584,2422,1.637,2440,0.868,2443,0.597,2478,0.576,2494,0.945,2518,0.612,2570,1.515,2578,0.749,2581,0.557,2607,2.386,2619,0.52,2666,0.628,2668,1.971,2670,4.022,2679,4.396,2684,3.277,2685,0.907,2717,3.158,2732,2.976,2734,0.945,2735,2.624,2744,0.85,2761,1.637,2762,0.997,2765,1.637,2766,0.997,2768,0.791,2784,0.809,2808,0.997,2810,0.997,2818,2.437,2825,0.997,2827,1.864,2854,0.646,2855,0.809,2861,2.2,2897,1.94,2899,0.588,2909,3.329,2915,5.911,2939,0.907,2964,0.945,2991,3.986,2996,2.976,3036,0.659,3038,0.945,3069,4.596,3084,1.076,3085,0.876,3086,0.749,3087,0.85,3088,1.076,3089,1.076,3090,2.011,3091,1.864,3092,1.767,3093,1.864,3094,1.076,3095,0.997,3096,0.997,3097,1.076,3098,0.646,3099,1.076,3100,1.076,3101,1.076,3102,0.737,3103,1.378,3104,0.697,3105,4.202,3106,1.076,3107,2.386,3108,2.304,3109,1.076,3110,3.296,3111,1.076,3112,1.076,3113,1.076,3114,1.864,3115,2.011,3116,0.997,3117,0.85,3118,0.907,3119,1.076,3120,1.076,3121,1.076,3122,2.011,3123,5.078,3124,1.076,3125,0.907,3126,1.451,3127,1.076,3128,0.776,3129,0.997,3130,0.997,3131,3.895,3132,0.945,3133,1.076,3134,1.076,3135,1.4,3136,0.945,3137,0.716,3138,1.864,3139,2.831,3140,1.076,3141,1.076,3142,0.876,3143,2.831,3144,2.624,3145,1.864,3146,2.624,3147,3.296,3148,0.828,3149,0.945,3150,2.624,3151,2.624,3152,1.076,3153,0.997,3154,0.749,3155,7.293,3156,0.997,3157,0.809,3158,2.011,3159,1.076,3160,2.011,3161,1.076,3162,1.076,3163,1.076,3164,1.076,3165,1.076,3166,1.076,3167,1.076,3168,1.076,3169,1.076,3170,1.076,3171,1.076,3172,1.076,3173,1.076,3174,1.076,3175,1.076,3176,1.076,3177,1.076,3178,1.076,3179,2.011,3180,2.011,3181,1.076,3182,0.997,3183,1.076,3184,1.076,3185,1.076,3186,1.076,3187,1.076,3188,1.076,3189,1.076,3190,1.076,3191,1.076,3192,1.076,3193,1.076,3194,1.076,3195,1.076,3196,1.076,3197,1.076,3198,1.076,3199,2.831,3200,1.076,3201,1.076,3202,1.076,3203,1.076,3204,1.076,3205,1.076]],["t/606",[30,1.775,44,1.542,83,1.713,90,3.185,117,0.951,139,2.551,144,4.892,156,2.107,183,4.58,194,3.278,219,2.862,242,5.568,411,2.007,620,5.091,645,3.595,697,5.217,775,2.539,881,5.204,969,4.331,978,2.738,987,3.098,1014,5.217,1037,5.256,1115,5.107,1170,3.696,1185,5.016,1273,3.391,1431,4.061,1727,3.08,1915,6.256,2304,4.952,2355,4.463,2679,6.143,2759,5.622,3126,7.998,3206,6.852,3207,8.673]],["t/609",[5,1.366,43,1.936,44,0.989,78,2.795,83,0.671,85,1.804,86,3.539,89,1.115,91,2.118,94,1.146,95,0.722,96,0.752,115,0.659,117,0.61,128,4.301,136,0.853,138,1.969,141,1.146,146,1.002,148,2.199,175,0.913,187,1.487,188,0.959,194,0.722,208,0.563,214,3.477,218,1.186,219,0.63,220,1.641,222,1.086,229,1.898,243,1.19,249,0.881,250,0.766,264,2.138,267,0.832,291,1.901,296,3.426,297,2.403,330,3,339,0.865,350,1.095,410,5.6,411,0.786,412,0.651,414,1.917,419,0.873,421,3.068,422,3.571,423,1.917,425,3.658,426,2.863,429,7.695,432,6.729,463,0.651,470,1.041,474,1.252,506,1.832,527,3.4,529,2.232,532,1.182,557,1.256,606,1.125,614,0.965,659,1.764,670,1.518,678,1.819,694,2.717,712,1.023,719,1.511,722,2.294,723,4.951,781,2.281,785,0.983,788,2.126,809,0.622,812,1.182,818,4.61,822,0.766,834,0.713,840,1.03,862,1.223,870,2.039,874,1.037,875,0.616,892,1.76,895,1.045,908,1.256,923,1.462,953,0.828,980,0.831,985,2.987,997,1.635,1009,1.21,1013,1.607,1025,1.697,1160,1.309,1204,0.78,1211,0.804,1257,2.262,1278,2.939,1334,1.254,1349,1.917,1401,1.807,1411,4.283,1441,1.209,1596,0.706,1607,0.76,1612,0.977,1694,4.014,1711,1.077,1750,1.105,1776,0.996,1862,1.436,1875,2.766,1923,1.115,1934,2.529,1988,3.828,2143,2.294,2154,1.76,2155,2.059,2181,2.262,2263,2.556,2298,2.294,2331,3.407,2355,0.983,2356,0.971,2383,1.378,2391,1.29,2440,1.98,2443,1.061,2449,2.039,2478,1.819,2514,2.615,2570,1.023,2679,4.518,2684,4.844,2717,2.554,2731,3.149,2732,1.353,2734,1.678,2737,1.61,2739,1.771,2761,1.555,2765,1.555,2818,4.372,2897,1.309,2909,2.366,2915,4.844,2996,7.24,3025,1.771,3034,1.771,3069,1.33,3092,1.678,3093,1.771,3107,2.863,3108,2.766,3116,1.771,3117,2.685,3123,1.47,3129,1.771,3131,1.771,3144,1.771,3146,5.912,3147,3.149,3150,1.771,3151,1.771,3208,1.254,3209,8.682,3210,1.91,3211,1.91,3212,1.91,3213,1.91,3214,1.436,3215,1.678,3216,1.91,3217,1.91,3218,3.398,3219,5.565,3220,6.385,3221,3.398,3222,1.91,3223,3.398,3224,1.91,3225,4.59,3226,4.59,3227,6.551,3228,6.551,3229,6.551,3230,6.551,3231,4.254,3232,4.254,3233,1.91,3234,1.91,3235,1.678,3236,1.209,3237,1.678,3238,1.678,3239,1.91,3240,1.91,3241,1.91,3242,1.91,3243,1.91]],["t/611",[2578,7.961,2732,8.098,2784,8.593,3244,11.433]],["t/613",[411,2.603,1009,4.007,1401,5.98,2155,6.817,2386,7.71,2396,6.623]],["t/615",[33,1.657,44,0.898,90,1.854,94,2.563,106,2.451,117,1.196,156,1.227,193,3.746,208,2.24,243,1.309,250,2.023,296,3.029,339,2.286,391,1.441,398,1.86,402,1.96,421,4.702,422,2.551,427,2.492,463,1.722,470,2.328,505,2.702,530,2.216,565,4.434,576,2.455,607,1.384,615,2.782,621,2.219,634,4.475,654,2.046,666,3.138,737,2.297,764,2.143,775,2.225,802,1.746,809,1.644,817,2.702,845,4.109,866,2.245,867,1.558,890,2.341,980,2.197,985,2.278,1017,4.754,1036,2.761,1074,3.232,1075,2.92,1089,3,1091,2.825,1097,2.069,1106,3.795,1135,3.194,1213,2.825,1227,3.158,1278,2.666,1281,2.761,1282,3.714,1341,3.714,1443,2.126,1586,2.536,1760,3.885,1791,2.521,1812,2.582,1841,3.735,1954,2.614,1974,2.566,2032,2.521,2177,3,2230,2.255,2321,3.232,2399,4.254,2462,3.795,2506,3.315,2553,5.383,2666,2.946,2787,9.425,2788,4.679,2789,7.07,2790,6.162,2853,2.582,2898,4.436,3036,6.677,3050,6.186,3098,5.484,3245,7.6,3246,4.109,3247,3.642,3248,4.436,3249,3.885,3250,3.795,3251,5.048,3252,4.156,3253,4.436,3254,4.436,3255,5.048,3256,2.438,3257,4.436,3258,4.679,3259,3.158,3260,7.044,3261,5.048,3262,3.795,3263,5.048]],["t/617",[1,2.379,12,2.643,30,1.683,39,3.369,71,3.64,72,1.838,73,1.671,76,2.726,81,5.322,82,4.732,83,2.252,91,2.591,102,3.848,117,0.902,123,2.532,134,4.436,138,1.733,144,3.167,148,1.432,166,2.82,177,2.566,183,2.965,187,1.819,196,2.459,204,3.977,211,2.075,214,1.959,216,2.926,249,2.591,264,2.616,267,2.384,296,3.149,297,2.419,351,3.027,391,2.347,401,2.854,402,2.18,411,2.757,418,2.82,425,4.716,473,1.651,474,2.069,495,2.355,510,1.64,526,2.095,527,3.564,529,2.878,530,2.464,538,1.781,552,2.788,562,2.292,576,2.657,597,2.165,607,2.255,621,1.64,645,2.327,654,2.275,770,2.985,775,1.644,867,1.733,980,2.443,1009,3.466,1069,2.889,1084,4.436,1120,3.049,1135,3.553,1204,2.292,1261,3.848,1281,4.498,1302,3.337,1727,2.921,1734,4.037,1894,4.131,1942,4.757,2467,3.337,2854,4.935,2855,7.314,2881,2.25,2893,4.22,2910,3.737,2915,3.848,2952,5.204,2953,4.934,3264,5.204,3265,5.615,3266,4.732,3267,5.615,3268,4.732]],["t/619",[1,1.826,4,3.121,21,2.147,73,2.223,83,1.475,91,3.447,117,1.332,123,4.233,137,3.05,138,2.306,144,4.214,148,2.564,156,2.953,164,4.104,168,2.492,169,3.399,172,1.729,173,6.289,175,3.57,194,2.824,233,5.389,235,3.589,243,1.937,267,1.83,401,3.797,473,2.197,510,2.936,526,3.751,557,2.761,615,3.68,621,2.182,625,5.389,781,3.075,867,3.102,1072,3.774,1322,5.496,2195,5.203,2271,4.935,2698,5.615,2949,6.564,2955,9.318,3269,6.296,3270,6.296]],["t/621",[1,2.306,91,4.352,117,1.034,148,3.24,156,2.292,175,4.507,179,6.882,259,2.395,267,2.31,345,8.997,470,2.889,889,6.939,1471,4.682,2271,4.63,2698,7.089,2937,7.089,2947,8.288,3269,7.948,3271,10.833,3272,10.833,3273,8.742]],["t/623",[1,2.306,91,4.352,117,1.034,148,3.24,156,2.292,175,4.507,179,6.882,267,2.31,345,8.997,470,2.889,889,6.939,1471,4.682,2271,4.63,2698,7.089,2937,7.089,2947,8.288,3269,7.948,3270,10.703,3271,10.833,3272,8.742,3273,8.742,3274,9.432]],["t/625",[5,2.166,30,2.07,48,3.926,123,3.113,137,4.128,148,3.111,243,2.623,267,2.477,414,2.742,613,5.049,744,5.376,816,4.979,914,4.382,1347,6.555,1404,6.475,1841,3.714,3269,8.522,3275,10.112]],["t/627",[1,0.574,5,0.503,13,1.383,28,1.173,29,1.314,30,1.635,33,0.771,44,0.418,47,0.844,48,0.912,72,1.334,73,0.699,78,1.18,83,1.066,85,1.822,86,0.714,90,0.863,95,0.888,117,1.042,128,1.079,138,1.988,139,0.691,142,1.586,148,2.187,150,1.696,156,0.571,169,1.069,172,1.249,175,1.122,180,0.755,187,0.761,194,0.888,196,1.614,207,1.469,210,0.777,211,0.868,214,0.82,218,1.883,219,0.775,220,1.134,235,1.957,240,0.533,243,2.072,249,1.084,259,0.769,262,1.094,264,2.514,267,1.785,287,0.636,296,3.324,297,1.198,330,1.73,391,1.54,411,2.432,414,1.464,418,4.012,419,3.651,421,3.22,422,2.059,423,2.298,425,4.179,465,2.939,470,2.233,473,1.587,489,0.784,492,0.928,510,1.576,527,0.781,529,0.822,547,1.504,560,1.781,568,1.147,576,0.759,586,1.828,602,1.469,606,4.291,612,0.686,615,1.492,620,1.871,621,0.686,645,1.689,648,1.249,650,1.694,659,3.799,660,3.119,668,1.52,678,1.257,681,3.584,682,1.979,694,1.989,697,1.918,712,1.257,714,4.393,737,1.854,748,2.067,760,1.968,775,1.58,781,0.594,786,1.257,802,0.813,814,0.792,816,1.664,831,1.147,840,1.266,867,1.258,868,1.153,875,0.757,895,1.285,912,1.105,923,0.617,969,1.173,985,2.184,987,0.839,993,0.906,998,0.689,1004,1.16,1009,3.521,1028,1.141,1037,1.423,1056,1.371,1062,1.064,1069,1.209,1098,1.266,1162,1.359,1170,2.3,1181,1.194,1198,1.586,1204,2.203,1207,1.808,1211,0.989,1218,1.232,1252,1.523,1278,1.24,1334,1.542,1396,1.336,1397,1.694,1401,2.166,1421,1.147,1431,1.1,1441,1.486,1477,4.136,1483,1.453,1618,0.938,1640,1.049,1674,1.808,1694,1.694,1749,1.359,1771,3.063,1774,2.578,1841,0.863,1858,1.371,1862,1.766,1874,1.371,1878,2.495,1894,1.728,1896,1.325,1934,2.245,1957,1.504,1988,1.492,2010,1.469,2118,1.294,2134,1.563,2153,1.766,2154,2.794,2155,3.27,2182,1.347,2271,1.153,2300,1.314,2301,1.694,2304,2.41,2316,1.837,2318,1.664,2335,1.808,2355,4.11,2380,1.094,2386,1.61,2392,1.766,2396,1.383,2414,1.979,2443,2.996,2451,2.712,2478,2.181,2490,1.396,2531,1.523,2573,1.61,2578,2.838,2607,1.979,2608,1.523,2619,1.968,2666,1.371,2668,1.636,2670,2.838,2684,2.793,2685,1.979,2717,1.766,2732,1.664,2759,4.724,2761,1.912,2765,1.912,2818,5.878,2864,2.064,2879,1.664,2905,1.664,2931,1.808,2939,1.979,3072,1.694,3078,2.469,3095,2.177,3123,3.136,3137,1.563,3138,2.177,3142,3.317,3145,2.177,3153,3.777,3238,2.064,3276,2.349,3277,2.064,3278,4.075,3279,8.413,3280,4.075,3281,2.349,3282,2.349,3283,2.349,3284,1.979,3285,2.349,3286,2.349,3287,2.349,3288,2.349,3289,2.349,3290,2.349,3291,4.075,3292,2.349,3293,2.349,3294,1.694,3295,2.064,3296,2.349,3297,1.856,3298,2.177,3299,2.349,3300,2.349,3301,4.075,3302,2.349,3303,2.349,3304,2.349,3305,2.349]],["t/629",[7,1.866,22,2.783,30,2.466,44,1.3,48,3.848,73,2.177,117,0.802,148,2.528,150,3.044,156,1.777,243,1.897,262,3.408,296,3.328,299,6.691,391,2.088,411,3.004,418,3.674,421,2.747,473,2.151,510,2.894,527,2.433,538,2.321,597,2.821,620,3.359,816,2.986,989,4.195,993,2.821,1004,4.892,1009,4.292,1062,3.312,1204,2.986,1308,3.696,1455,4.16,1873,4.803,1909,6.345,2075,3.674,2186,4.389,2304,3.267,2398,6.164,2478,3.916,2759,7.286,2881,2.932,2944,5.094,3306,5.013,3307,7.315,3308,7.315,3309,7.315,3310,7.315,3311,7.315,3312,5.381]],["t/631",[7,1.613,30,1.834,78,3.176,85,1.789,148,2.286,155,3.234,156,2.177,165,2.729,187,2.049,219,2.087,240,1.436,243,2.936,250,2.535,264,2.947,267,2.549,287,1.711,296,3.553,297,1.86,391,1.805,411,2.073,414,1.715,418,4.5,421,2.375,463,2.157,470,2.745,488,2.133,510,1.847,555,2.294,586,2.838,606,5.276,621,1.847,645,3.714,659,3.444,668,2.36,697,4.897,739,3.833,764,2.684,775,3.046,866,2.812,867,1.952,874,3.434,985,1.896,1004,3.122,1009,2.253,1028,3.071,1162,3.658,1177,2.098,1385,4.562,1401,3.362,1615,3.296,1846,3.833,1957,4.049,1979,4.153,2010,3.956,2154,3.275,2155,3.833,2304,4.002,2355,4.611,2478,3.385,2578,4.404,2670,6.24,2732,4.48,2775,4.48,2776,4.48,2818,6.141,2996,4.48,3125,5.329,3279,5.862,3313,6.324,3314,6.324,3315,6.324,3316,4.562]],["t/633",[3,1.214,5,0.63,7,0.75,10,3.28,11,1.703,22,2.427,24,1.443,34,1.839,35,1.782,36,1.608,39,2.962,44,0.523,72,1.616,73,0.875,87,1.008,96,1.158,116,1.363,117,1.294,123,0.905,138,0.907,139,2.197,148,2.564,163,1.398,169,2.245,172,1.476,175,2.359,177,2.916,196,3.854,197,1.37,204,2.083,211,1.087,218,1.026,220,3.081,221,1.405,229,2.84,243,1.654,259,1.972,263,0.914,267,0.72,276,3.097,296,2.201,297,0.865,315,3.223,323,1.542,400,7.063,402,1.142,414,0.797,419,2.256,420,1.596,457,1.319,483,2.427,489,2.778,490,4.301,491,1.258,495,2.675,525,1.46,526,2.38,529,1.029,536,3.333,579,1.824,612,0.859,614,2.494,617,1.553,620,4.14,621,0.859,622,1.553,637,1.523,645,3.097,668,1.097,670,2.205,697,2.323,756,1.391,781,2.732,787,1.233,819,5.046,822,1.178,867,0.907,875,2.408,892,2.556,923,1.675,978,0.928,985,1.479,1014,1.384,1018,1.906,1019,2.958,1036,1.608,1093,2.323,1110,1.86,1227,1.839,1301,2.584,1344,1.633,1349,1.659,1478,3.415,1596,1.824,1607,1.17,1640,1.313,1711,1.659,1722,1.357,1723,3.628,1727,4.118,1872,2.478,1942,4.321,1949,4.588,1961,1.428,2021,1.782,2062,1.285,2145,1.659,2157,1.308,2233,1.8,2271,3.668,2278,1.764,2383,2.121,2396,1.731,2501,4.795,2524,2.584,2801,4.575,2803,8.977,2854,2.962,3317,4.936,3318,2.991,3319,4.036,3320,2.94,3321,2.323,3322,2.725,3323,2.94,3324,2.584,3325,4.337,3326,2.94,3327,2.94,3328,2.584,3329,2.94,3330,2.94,3331,2.94,3332,2.725,3333,2.94,3334,2.584,3335,2.94,3336,2.725,3337,1.435,3338,2.94,3339,2.94,3340,2.94,3341,2.94,3342,2.94,3343,2.94,3344,4.936]],["t/635",[5,0.97,7,0.678,30,1.432,41,2.041,43,0.924,44,2.497,48,1.031,72,1.483,73,1.348,79,2.576,86,0.808,88,1.232,94,0.896,96,1.783,97,0.82,117,0.291,123,1.823,128,1.22,148,2.18,150,1.105,167,3.978,188,1.334,196,2.092,208,0.783,209,1.08,214,2.739,218,0.927,220,2.86,243,0.689,258,1.014,267,1.109,296,3.079,297,1.332,330,1.922,339,1.203,391,1.69,400,5.111,402,2.299,411,1.048,412,2.386,419,1.214,421,2.224,422,2.288,423,3.34,470,2.143,490,1.093,491,1.938,495,1.9,573,1.523,576,0.858,613,1.326,620,2.719,621,1.323,629,1.319,645,2.454,659,1.021,668,0.991,670,1.186,694,2.211,719,1.181,722,1.793,723,2.745,753,2.9,774,1.626,781,1.146,790,2.773,816,1.084,867,0.82,871,1.475,875,0.856,892,1.375,906,2.957,923,0.698,963,1.594,985,1.775,997,1.613,1009,0.946,1028,1.29,1055,1.706,1072,1.342,1097,1.088,1098,1.432,1200,2.408,1204,1.084,1273,1.771,1278,1.403,1334,4.594,1349,1.498,1396,1.51,1411,3.485,1431,1.244,1446,1.61,1607,1.057,1694,1.916,1727,2.484,1749,2.62,1871,4.535,1914,1.326,1942,2.62,1961,2.199,1988,3.52,2010,2.833,2018,1.319,2154,2.345,2155,2.745,2186,1.594,2256,1.579,2263,1.22,2271,1.304,2320,1.85,2327,1.916,2328,1.681,2331,3.625,2448,5.147,2591,4.194,2592,5.694,2670,3.154,2760,1.916,2803,7.925,2818,1.82,2854,1.594,2855,5.258,2913,1.954,2959,1.916,2996,4.194,3086,3.154,3123,7.398,3136,2.334,3220,3.208,3227,2.462,3228,2.462,3229,2.462,3230,2.462,3231,2.462,3232,2.462,3319,1.681,3322,2.462,3324,2.334,3325,2.334,3345,1.626,3346,2.656,3347,2.656,3348,2.656,3349,2.656,3350,2.656,3351,4.529,3352,2.656,3353,2.656,3354,2.656,3355,2.656,3356,2.656,3357,3.485,3358,4.529,3359,1.768,3360,4.529,3361,4.529,3362,4.529,3363,2.656,3364,2.656,3365,2.656,3366,4.541,3367,5.921,3368,2.656,3369,6.996,3370,4.529,3371,4.198,3372,10.181,3373,4.529,3374,3.404,3375,4.529,3376,4.529,3377,2.334,3378,2.462,3379,2.656,3380,2.656,3381,2.656,3382,2.656,3383,2.656,3384,2.656,3385,2.656,3386,2.656]],["t/637",[38,3.962,41,3.747,97,3.329,117,1.183,123,2.559,172,1.924,218,3.764,243,2.156,267,2.642,296,2.197,297,3.173,330,3.528,391,3.418,429,7.782,527,2.765,712,5.775,719,3.696,781,2.103,809,2.707,1003,5.622,1345,5.789,1418,3.368,1518,6.993,1816,3.617,2355,5.551,2684,5.697,2732,5.888,2817,7.705,2819,9.144,2959,5.997,3387,8.313,3388,8.313,3389,8.313,3390,8.313]],["t/639",[30,2.389,44,1.206,83,2.305,94,2.288,95,2.564,117,0.744,139,3.178,172,2.178,183,5.707,184,7.435,186,4.379,195,4.397,196,3.49,197,4.385,199,6.687,200,4.343,242,3.407,243,1.759,259,1.279,276,3.294,296,2.487,323,6.826,330,3.995,391,3.499,400,5.004,414,1.84,419,4.302,529,2.374,538,2.152,571,3.349,607,1.86,621,1.981,681,3.044,719,3.017,978,2.141,998,1.99,1098,3.657,1180,3.738,1640,3.03,1790,4.281,2154,3.513,2254,3.923,2271,3.33,2313,3.923,2316,3.058,2386,4.649,2490,4.032,2524,5.961,2828,6.287,2854,4.07,2996,4.805,3391,6.784,3392,6.784]],["t/641",[28,2.085,44,2.293,47,2.36,73,1.243,97,1.289,117,0.458,123,1.286,136,1.865,138,1.289,156,2.236,160,2.085,172,0.966,175,1.996,187,2.127,190,4.006,229,1.424,238,2.415,240,1.491,243,2.105,270,3.399,291,3.675,296,2.145,323,6.21,330,1.772,391,2.855,400,2.22,412,3.138,419,1.909,474,1.538,505,2.235,618,4.439,621,2.37,646,2.073,719,1.857,732,1.315,775,1.222,834,4.294,942,3.318,978,1.318,993,2.532,997,1.487,998,1.225,1009,1.487,1097,1.711,1160,2.862,1170,1.78,1331,1.686,1332,2.039,1586,2.097,1662,6.1,1711,2.355,1777,2.707,1829,1.718,1934,2.301,1959,3.012,1967,3.279,2155,2.531,2157,2.92,2260,2.92,2271,2.05,2355,5.147,2356,2.122,2386,2.862,2393,3.87,2394,3.519,2395,3.399,2398,3.519,2399,3.519,2403,4.501,2417,3.399,2423,5.534,2425,2.267,2484,3.867,2490,3.903,2496,6.042,2497,3.87,2498,3.87,2500,3.87,2534,3.519,2535,5.053,2537,3.519,2591,2.958,2657,3.519,2671,3.519,2831,3.519,2832,3.399,2833,3.669,2855,3.139,3393,4.176,3394,6.087,3395,4.176,3396,4.176,3397,3.87,3398,4.176,3399,4.176,3400,4.176,3401,4.176,3402,4.176,3403,4.176,3404,4.176,3405,4.176,3406,4.176,3407,4.176,3408,10.621,3409,10.004,3410,12.117,3411,9.201,3412,4.176,3413,8.116,3414,3.87,3415,4.176,3416,4.176,3417,4.176,3418,4.176,3419,4.176,3420,4.176,3421,6.567,3422,4.176,3423,4.176,3424,3.87,3425,4.176]],["t/644",[30,1.223,44,1.792,156,1.452,172,2.333,187,1.935,243,3.031,323,6.132,391,2.455,412,2.037,630,4.705,719,4.483,781,1.511,802,3.815,814,2.015,834,3.21,888,3.317,942,3.018,1331,2.412,1399,4.2,1662,4.49,1790,2.718,1829,2.457,1967,5.034,2275,4.424,2355,3.074,2403,5.896,2490,6.555,2535,8.488,2538,4.094,2578,4.16,2619,5.645,2657,10.821,2831,7.249,3394,7.974,3397,7.974,3426,4.49,3427,4.862,3428,7.813,3429,5.974,3430,5.974,3431,5.974,3432,5.974,3433,5.974,3434,11.03,3435,10.082,3436,5.974,3437,5.974,3438,5.974,3439,5.974,3440,5.974,3441,5.974,3442,5.974,3443,5.974,3444,5.974,3445,5.974,3446,5.974,3447,5.974,3448,5.974,3449,5.974,3450,5.974,3451,5.974,3452,5.974]],["t/646",[4,1.714,22,2.464,30,1.325,44,2.034,94,1.384,117,0.71,148,1.046,156,2.214,172,2.295,187,1.329,188,2.06,190,3.96,197,1.911,214,1.431,215,2.812,229,1.399,240,0.931,243,1.064,248,3.516,267,1.005,270,3.339,287,1.11,291,5.098,323,6.654,391,3.15,402,1.593,411,1.856,421,1.541,483,1.561,488,1.384,495,4.421,529,1.436,553,2.181,562,2.644,573,2.353,586,1.841,612,1.198,615,1.502,618,5.425,621,2.661,639,2.124,719,2.88,737,1.866,757,1.981,867,1.266,942,2.073,978,2.044,1003,2.138,1009,1.461,1055,1.546,1331,3.239,1332,2.003,1344,2.278,1441,2.596,1473,4.097,1579,4.198,1662,6.848,1711,4.525,1722,1.893,1727,1.457,1778,1.931,1790,1.866,1858,2.394,1961,1.992,2062,3.506,2075,2.06,2154,6.096,2155,6.011,2157,2.88,2254,2.373,2260,1.824,2261,2.812,2262,3.157,2337,2.166,2355,5.104,2356,2.085,2396,6.498,2416,2.731,2423,3.457,2429,2.627,2440,1.77,2486,3.018,2502,2.959,2831,3.457,2832,7.416,2833,5.69,2900,2.627,3414,3.802,3453,3.802,3454,4.103,3455,4.103,3456,6.476,3457,4.103,3458,8.023,3459,9.193,3460,8.715,3461,9.111,3462,3.802,3463,2.959,3464,4.103,3465,2.959,3466,4.103,3467,8.006,3468,3.802,3469,2.906,3470,4.103,3471,4.103,3472,4.103,3473,4.103,3474,4.103]],["t/648",[1,1.77,30,2.014,95,3.72,117,1.079,139,2.894,148,2.51,156,2.391,172,1.675,183,3.823,187,2.345,208,2.134,209,2.944,243,1.877,265,3.93,296,3.561,411,2.903,419,3.309,421,2.719,489,2.415,511,3.293,530,3.177,586,3.248,612,2.874,659,3.782,670,3.233,697,4.631,748,2.773,903,4.58,957,2.745,985,2.17,987,3.516,993,2.792,1009,3.505,1040,6.361,1062,4.456,1607,2.881,1909,4.635,2006,3.293,2478,3.875,2670,5.041,2699,6.1,2759,4.693,2818,4.962,2892,5.326,3132,6.361,3246,5.892,3298,6.71,3475,7.239,3476,9.841,3477,7.239,3478,7.239]],["t/650",[1,2.14,4,1.597,5,2.052,10,1.391,22,2.329,26,1.967,28,3.057,30,1.567,38,1.404,73,1.138,83,1.209,94,1.289,96,1.505,117,1.12,123,1.177,144,3.453,148,2.845,156,0.929,166,1.92,172,1.417,179,4.509,190,3.78,196,1.143,218,1.334,229,2.612,243,1.588,267,0.936,296,3.295,297,2.252,330,1.623,339,2.772,411,2.217,412,1.304,419,4.906,420,2.076,421,2.876,422,3.869,423,4.319,436,2.317,466,2.51,486,1.715,490,3.15,495,3.672,525,1.898,526,3.267,575,1.567,610,1.898,617,2.019,620,3.516,645,2.538,671,1.887,679,3.093,697,4.508,749,3.112,753,2.538,814,2.065,903,2.419,904,3.02,914,1.656,985,2.295,991,1.678,1009,2.727,1021,3.541,1120,2.076,1127,2.419,1170,1.629,1283,2.139,1344,2.122,1431,2.867,1433,3.359,1612,1.955,1730,4.837,1871,2.478,1914,1.909,1934,4.219,1942,6.208,2059,2.076,2151,2.812,2271,1.877,2313,2.211,2321,3.92,2350,2.365,2377,9.842,2440,3.304,2484,3.605,2668,6.097,2784,4.602,2818,2.62,2854,2.294,2885,2.758,2900,2.448,2996,6.202,3123,4.711,3318,2.317,3377,3.359,3378,3.543,3424,5.674,3453,3.543,3479,3.823,3480,7.658,3481,2.942,3482,3.823,3483,3.823,3484,3.823,3485,3.359,3486,3.221,3487,3.823,3488,3.823,3489,5.674,3490,3.543,3491,5.674,3492,3.823,3493,3.221,3494,3.823,3495,4.416,3496,3.823,3497,3.543,3498,2.708,3499,3.823]],["t/652",[1,1.467,5,1.285,30,1.766,38,2.203,43,2.087,73,1.785,89,5.897,117,0.946,148,1.53,163,2.852,190,4.26,196,1.794,214,2.093,219,2.848,229,2.046,240,1.362,267,2.475,296,3.398,339,4.576,398,2.21,411,1.997,412,2.046,419,5.351,452,2.692,470,1.838,495,4.91,526,3.771,575,2.459,612,1.752,614,3.031,620,2.755,681,2.692,775,1.756,787,2.516,814,2.023,834,3.22,867,1.851,985,1.798,1014,2.823,1067,4.112,1204,2.449,1278,3.168,1334,5.666,1344,3.331,1431,2.809,1471,2.978,1694,4.328,1789,3.939,1942,6.392,1947,4.112,1988,4.046,2170,4.509,2305,3.281,2377,8.504,2429,3.841,2440,5.052,2668,4.178,2761,4.883,2765,4.883,2784,4.509,2818,4.112,2900,3.841,2907,5.46,2996,6.112,3312,4.414,3489,5.561,3490,5.561,3497,5.561,3500,5.999,3501,4.25]],["t/654",[1,2.423,5,1.567,30,1.497,36,4.001,117,1.321,138,2.257,190,3.611,194,4.249,211,2.703,241,3.943,258,2.792,266,3.143,267,1.792,296,3.185,297,2.151,299,4.938,330,3.105,421,2.747,423,4.126,450,6.164,470,2.241,473,2.151,511,3.328,541,4.347,586,3.282,612,2.136,816,2.986,867,3.059,875,2.357,971,3.889,985,2.971,987,2.613,998,2.908,1008,3.032,1029,4.16,1267,4.347,1283,4.093,1307,3.972,1322,5.381,1355,4.526,1396,4.16,1709,5.954,1722,3.375,1761,6.427,1838,4.268,1841,3.64,1896,4.126,1934,5.461,2256,4.347,2443,4.061,2818,5.013,3005,5.094,3076,5.094,3123,5.629,3502,5.835,3503,5.181,3504,6.427,3505,5.277]],["t/656",[2,3.44,5,1.791,11,3.736,22,3.182,28,4.176,85,2.365,87,2.868,94,2.82,117,0.917,138,2.581,219,2.759,259,2.265,263,2.6,296,2.862,297,2.459,315,6.069,330,3.549,391,2.387,410,7.423,489,3.613,681,3.752,818,4.276,997,4.278,1018,5.421,1131,6.013,1214,4.358,1239,4.837,1307,5.88,1609,4.25,1952,4.924,2062,3.654,2174,3.654,2186,5.018,3506,3.787,3507,9.516,3508,6.807]],["t/658",[44,1.971,117,1.215,118,4.56,128,3.983,296,2.93,315,6.174,410,8.376,576,2.802,584,4.021,659,3.333,809,2.824,818,6.25,822,4.444,953,3.758,997,3.949,1098,5.977,1131,6.156,1147,6.381,1829,3.568,2174,3.79,2337,4.58,2684,5.944,2732,7.853,2818,5.944,3117,6.852,3509,7.309,3510,6.852]],["t/660",[1,1.571,2,1.222,5,1.067,30,0.608,37,3.315,43,1.034,44,2.105,83,1.654,85,0.84,86,1.514,88,2.309,94,1.002,115,1.025,117,0.326,156,3.16,175,1.42,187,2.082,190,3.173,218,2.243,229,1.013,240,0.675,242,4.207,259,2.045,296,2.669,315,2.516,330,1.261,345,2.105,391,2.587,408,4.243,412,2.192,418,4.207,423,1.676,426,2.504,486,2.234,505,3.441,510,1.877,546,1.734,569,4.947,618,2.724,620,3.454,621,0.868,712,2.666,719,1.321,758,3.664,786,1.591,818,1.52,830,1.734,840,1.602,868,1.459,875,1.605,942,3.248,1004,1.467,1009,2.29,1131,1.65,1143,2.105,1208,2.938,1347,1.926,1401,3.417,1596,4.299,1662,4.831,1791,1.484,1841,1.091,1934,1.637,1943,3.751,2174,3.961,2193,4.053,2194,4.376,2256,2.96,2271,2.445,2275,2.186,2316,2.245,2328,1.88,2337,2.63,2355,4.954,2356,4.894,2376,6.122,2380,2.995,2484,1.75,2538,3.413,2591,2.105,2592,6.122,2673,3.018,2679,2.105,2684,2.037,2698,2.233,2699,2.504,2701,2.754,2704,4.197,2705,2.754,2711,2.419,2712,2.754,2725,4.616,2727,2.754,2729,2.754,2737,2.504,2750,2.754,2752,4.616,2753,2.754,2755,4.616,2756,2.754,2758,2.754,2759,4.876,2764,2.754,2767,2.754,2770,1.277,2772,2.754,2778,2.754,2782,2.754,2897,2.037,2996,8.385,3012,2.504,3018,4.616,3130,2.754,3135,2.069,3509,5.417,3511,1.549,3512,2.972,3513,2.972,3514,4.98,3515,2.972,3516,2.037,3517,2.972,3518,2.972,3519,6.428,3520,2.972,3521,4.98,3522,4.98,3523,2.972,3524,4.98,3525,4.98,3526,4.98,3527,2.972,3528,4.947,3529,2.972,3530,2.972,3531,2.972,3532,2.972,3533,4.98,3534,2.972,3535,2.972,3536,2.419,3537,4.98,3538,4.98,3539,2.972,3540,2.972,3541,2.972,3542,2.611,3543,2.972,3544,2.972,3545,2.972,3546,2.972,3547,2.972,3548,4.98,3549,2.972,3550,2.972,3551,2.972,3552,2.972,3553,2.972]],["t/662",[2,2.613,6,3.229,30,1.84,47,2.283,73,1.891,85,1.797,87,3.083,89,3.707,117,1.144,138,1.961,156,1.544,196,1.9,197,2.96,210,2.974,214,3.136,219,3.442,229,2.167,249,2.931,250,3.603,259,1.198,296,3.556,330,2.697,391,1.813,425,5.982,471,3.741,499,4.068,538,2.016,545,4.229,553,4.779,557,3.322,614,3.21,659,2.442,752,3.741,783,4.02,790,3.889,818,6.121,822,3.603,969,3.172,1025,3.172,1069,3.269,1170,2.707,1204,2.594,1413,5.582,1490,4.424,1609,3.229,1866,4.583,1874,3.707,1934,4.953,1988,3.291,2256,6.2,2337,4.747,2486,7.675,2797,5.582,3117,8.961,3118,5.354,3235,5.582,3554,5.171,3555,6.353,3556,4.583,3557,6.353,3558,6.353,3559,6.353,3560,6.353,3561,6.353,3562,6.353]],["t/665",[44,1.923,90,3.972,118,4.035,128,5.829,425,6.202,822,4.334,1286,5.711,1443,4.554,3563,10.815,3564,10.815]],["t/667",[5,1.626,43,2.641,44,1.807,172,1.757,214,2.649,219,3.78,296,3.543,297,3.369,330,4.862,470,2.326,645,3.147,694,3.706,697,3.573,722,6.861,748,2.908,775,2.975,816,3.1,818,3.883,1024,3.438,1307,4.122,1694,5.477,1934,4.183,2263,3.486,2363,4.921,2670,5.287,2795,9.419,2796,9.419,2797,6.671,2818,5.203,2861,6.288,2940,5.477,2996,7.198,3098,4.556,3123,9.414,3125,6.398,3132,6.671,3142,6.18,3209,7.037,3235,6.671,3491,7.037,3565,7.592,3566,10.162,3567,7.592]],["t/669",[5,1.804,13,3.415,24,2.848,30,1.724,36,3.173,40,3.043,44,1.497,47,3.564,95,2.193,97,1.79,117,1.087,138,1.79,148,1.48,150,2.414,153,3.272,163,2.758,169,2.639,172,1.949,198,2.864,208,3.828,214,2.024,218,2.024,239,2.744,245,2.276,267,1.421,276,2.817,296,1.533,330,3.575,391,2.404,496,3.15,527,1.93,541,3.447,562,3.438,576,1.874,597,2.237,606,4.959,615,2.124,660,4.243,720,3.861,737,2.639,749,4.722,764,2.462,775,2.902,814,1.956,820,2.072,867,1.79,906,2.896,953,2.513,971,4.477,978,2.658,998,1.702,1018,3.76,1082,3.481,1187,2.787,1205,2.639,1438,5.097,1774,3.67,1812,2.966,1853,3.551,1909,3.714,2032,2.896,2117,4.268,2187,4.04,2191,3.551,2355,4.334,2392,4.36,2484,5.838,2490,3.447,2666,5.785,2684,5.772,2685,4.888,2732,4.109,2759,3.76,2903,3.714,2937,4.36,2982,5.097,3005,4.04,3072,4.184,3345,3.551,3568,5.376,3569,5.801,3570,5.801,3571,5.801,3572,5.801,3573,5.801,3574,5.801,3575,5.801,3576,5.801,3577,5.801,3578,5.801,3579,4.583]],["t/671",[3082,6.664]],["t/673",[3082,6.664]],["t/675",[3082,6.664]],["t/677",[3082,6.664]],["t/679",[3082,6.664]],["t/681",[3082,6.664]],["t/683",[3082,6.664]],["t/685",[3082,6.664]],["t/687",[3082,6.664]],["t/690",[0,6.85,1,3.191,2,4.13,5,2.151,117,1.101,259,1.894,287,2.717,391,2.865,398,3.699,509,7.386,585,6.281,732,3.161,756,4.749,1327,5.618,1418,4.068,1711,5.663,1712,6.594]],["t/692",[1,2.527,2,4.252,5,2.214,210,3.42,240,2.346,259,1.949,490,4.252,802,3.575,987,3.693,1013,4.889,1418,4.188,1428,8.413,1455,5.878,2123,6.143,2126,8.71,3318,6.264,3580,10.336]],["t/694",[3,4.058,20,4.43,51,4.936,126,3.843,139,2.891,178,4.747,259,2.261,490,4.931,557,3.632,775,2.877,1298,8.636,1654,8.283,1715,3.983,2278,5.898,3581,8,3582,8.636,3583,9.11,3584,8.636,3585,9.11,3586,9.11,3587,9.11,3588,9.829]],["t/696",[5,2.182,123,3.136,206,5.571,287,2.756,490,4.19,547,6.522,585,6.372,756,4.818,890,4.723,1121,7.215,1213,5.7,1217,8.95,1403,6.688,1422,7.494,1580,9.441,2145,5.745,3501,7.215,3589,7.494,3590,10.186]],["t/698",[21,3.132,96,4.291,258,4.161,259,2.056,287,3.451,652,6.031,670,4.868,998,3.198]],["t/700",[1,2.623,5,2.299,259,2.024,287,2.904,585,6.713,612,3.134,1008,4.449,1065,8.479,1178,8.066,1273,4.196,2145,6.053,3591,10.732]],["t/702",[123,3.408,214,3.863,259,2.088,287,2.996,541,6.58,585,6.926,1380,7.475,3592,9.728]],["t/704",[11,4.439,97,3.417,259,2.088,287,2.996,489,3.693,1405,10.261,3593,9.728]],["t/706",[11,4.263,15,5.191,47,3.715,118,3.857,259,2.331,287,3.344,288,5.927,489,4.122,596,6.978,607,2.834,652,4.889,2003,6.978,3593,9.082]],["t/708",[259,2.105,267,2.733,557,4.124,627,4.856,631,6.832,769,6.511,1211,4.699]],["t/710",[5,2.335,122,4.449,210,3.606,240,2.474,398,4.015,487,4.337,1766,7.47,2171,4.645,2206,8.018,2304,4.868]],["t/712",[33,3.469,96,4.161,122,4.315,193,3.894,210,3.497,240,2.4,487,4.206,544,5.309,670,4.721,816,4.315,1090,5.248,1418,4.283,3594,8.351,3595,6.688]],["t/714",[5,2.353,16,6.147,196,3.83,240,2.494,489,3.664,1418,4.451,2134,7.311,3080,9.256]],["t/716",[1,3.222,5,2.473,7,2.358,38,3.395,96,3.64,97,2.853,117,1.013,123,2.846,181,4.093,208,3.403,214,3.226,240,2.099,259,2.374,320,6.179,532,5.72,537,6.802,612,2.7,769,5.394,869,5.215,1418,3.746,1478,4.949,1816,4.023,2152,5.133,3596,7.525,3597,9.245]],["t/718",[1,2.508,5,2.636,7,2.617,210,3.395,240,2.329,259,1.935,263,3.19,267,2.513,287,2.777,401,5.215,560,4.484,597,3.957,612,2.997,767,6.041,769,5.987,792,6.927,3598,10.261]],["t/720",[11,3.789,38,4.034,118,4.098,259,2.072,287,2.972,320,5.88,489,3.664,910,6.591,1185,6.353]],["t/722",[4,5.351,37,7.311,47,3.948,320,5.88,489,3.664,809,3.577,908,4.059,3599,9.652]],["t/726",[5,2.091,12,3.137,83,1.927,139,2.87,148,2.49,156,2.372,259,2.251,287,2.641,401,4.961,411,2.762,547,6.249,570,6.496,681,4.379,840,5.262,1053,7.944,1170,4.16,1841,4.934,2134,6.496,2171,4.16,3600,6.689]],["t/728",[44,1.882,72,4.103,73,3.15,83,2.475,84,4.055,87,2.769,95,3.052,102,7.254,105,5.451,117,1.427,126,3.156,163,3.838,180,3.795,411,3.09,463,2.753,483,3.072,607,2.213,620,3.707,693,4.711,869,4.554,1008,3.346,1035,4.669,1036,4.415,1396,4.591,1841,4.904,3601,7.483,3602,7.483,3603,6.571,3604,8.92]],["t/730",[1,2.6,30,2.177,44,2.612,47,1.212,73,1.003,83,2.1,84,1.694,87,1.156,94,3.028,117,0.892,123,1.038,144,1.902,148,1.411,150,1.403,156,2.476,163,2.629,164,1.377,170,4.84,180,1.084,183,1.781,188,1.694,243,1.823,250,1.351,259,2.077,263,1.048,266,1.449,287,1.496,404,1.887,405,2.086,406,1.674,411,2.077,413,2.842,486,3.649,505,1.805,538,1.07,562,1.377,619,2.516,621,2.053,645,1.398,663,1.461,719,1.499,757,1.628,775,2.058,781,0.853,796,3.886,820,1.205,834,1.258,942,1.704,957,1.279,993,3.136,998,0.989,1125,1.595,1203,1.887,1393,3.499,1465,1.52,1488,2.432,1586,1.694,1596,1.246,1640,1.506,1841,4.79,1904,1.704,2006,1.534,2018,1.674,2118,3.047,2240,2.109,2275,2.427,2316,1.52,2425,3.003,2673,4.929,2754,5.733,2770,1.449,2954,2.432,3070,5.272,3071,4.354,3600,2.311,3605,2.534,3606,2.963,3607,3.541,3608,7.538,3609,2.311,3610,2.432,3611,1.968,3612,2.388,3613,5.126,3614,3.125,3615,3.125,3616,3.125,3617,2.842,3618,3.125,3619,3.125,3620,3.125,3621,3.125,3622,3.125,3623,3.125,3624,3.125,3625,2.745,3626,3.125,3627,2.963,3628,3.125,3629,4.501,3630,3.125,3631,3.125,3632,2.745,3633,3.125,3634,2.963,3635,2.745]],["t/732",[44,1.496,83,2.147,94,2.837,117,1.192,156,2.927,168,2.806,172,1.947,180,4.092,196,2.515,243,2.82,259,2.401,287,2.276,411,2.516,579,3.109,612,3.175,621,2.457,668,3.139,757,4.063,775,2.463,787,3.528,911,5.453,957,3.19,998,2.468,1203,7.556,1841,4.842,3600,5.766]],["t/734",[43,3.951,156,3.022,188,4.524,259,2.346,287,2.437,404,5.04,406,4.472,486,5.095,671,4.446,814,3.038,834,3.361,889,6.627,998,2.643,1615,4.694,1783,6.77,1841,4.796,2673,6.882,2754,6.122,3214,6.77,3252,4.926,3636,7.332,3637,8.349,3638,5.515,3639,5.699,3640,5.767,3641,7.332]],["t/736",[10,3.653,117,1.101,148,2.561,168,3.349,258,4.636,259,2.29,287,2.717,316,6.428,397,5.858,910,6.024,987,3.587,1030,6.329,1214,6.329,1302,5.967,1516,7.932,3642,10.671]],["t/738",[7,2.024,14,4.219,20,3.577,33,2.605,44,1.861,106,3.853,240,1.802,245,4.106,258,3.03,259,1.497,296,2.766,297,2.334,338,3.853,421,3.93,422,5.288,473,2.334,504,6.405,531,3.94,579,2.933,612,3.42,618,4.34,627,3.453,634,4.673,764,3.368,834,2.961,987,2.835,998,3.071,1012,7.356,2180,4.036,2304,3.545,2608,8.071,2789,5.144,2853,4.058,3502,6.895,3643,6.46,3644,7.936,3645,9.701,3646,5.621,3647,7.936,3648,5.527,3649,7.936]],["t/740",[5,2.225,7,2.002,30,1.606,33,2.576,76,3.81,83,1.549,95,2.966,97,2.422,117,0.86,164,3.204,165,3.386,210,3.437,297,2.308,402,3.047,421,3.901,422,3.965,443,3.291,508,4.539,525,3.896,526,2.928,555,3.768,636,4.038,875,2.529,985,2.352,987,2.803,998,3.783,1120,4.261,1205,3.57,1273,3.068,1370,4.579,1455,4.462,1480,4.391,1668,7.234,1727,2.787,1753,3.896,1838,4.579,1867,6.895,1895,5.378,2032,5.187,2144,4.261,2171,4.427,2853,4.013,3502,7.298,3646,5.558,3650,7.847,3651,6.387]],["t/742",[1,1.56,7,3.058,30,1.306,38,2.344,164,3.682,167,3.629,168,2.129,213,2.754,226,2.974,229,2.177,243,1.655,402,2.478,463,2.177,473,1.877,482,4.896,526,2.381,530,2.801,557,2.359,598,2.959,612,2.634,621,2.634,731,3.829,732,2.839,744,3.393,781,1.615,796,3.05,886,3.543,896,3.49,954,4.604,978,2.015,985,3.134,987,2.28,989,3.66,998,3.651,1009,2.273,1066,3.15,1208,2.917,1308,3.224,1402,3.829,1657,5.042,1727,4.64,1841,3.312,1910,3.758,1926,3.416,2171,4.843,2380,2.974,2770,2.742,2881,2.558,3502,7.532,3511,4.7,3643,5.195,3645,5.915,3652,9.612,3653,4.911,3654,5.915,3655,5.915,3656,4.521,3657,4.248,3658,6.382,3659,3.49]],["t/744",[16,3.852,73,2.048,83,2.151,187,3.528,240,2.666,241,5.125,297,3.454,391,2.713,421,4.411,457,3.089,483,2.619,492,2.72,505,3.685,530,3.021,579,3.514,584,3.192,612,2.01,627,2.995,660,4.068,734,3.737,775,2.783,822,2.759,875,2.218,985,3.264,1009,2.452,1069,3.542,1120,3.737,1211,2.898,1248,6.193,1278,3.635,1362,4.462,1387,4.966,1443,2.898,1480,3.852,1967,5.438,2123,4.091,2171,2.934,2179,4.718,2466,4.794,2519,4.407,2608,4.462,2860,6.38,2872,4.306,3511,6.121,3595,4.355,3660,12.109,3661,6.38,3662,4.407,3663,10.095,3664,6.884]],["t/746",[5,1.955,33,2.995,36,4.991,240,2.071,296,2.412,297,2.684,411,2.111,421,4.699,422,5.785,482,4.954,497,5.842,504,4.991,524,5.324,531,4.53,546,5.324,985,3.75,998,2.677,1055,3.438,1181,4.638,1302,5.423,1612,4.666,2144,4.954,2180,3.519,2608,5.915,3502,5.373,3643,7.427,3662,5.842,3665,5.373,3666,8.018,3667,9.125]],["t/748",[24,4.18,33,3.977,44,1.514,193,4.037,197,3.967,240,2.904,411,2.535,414,2.309,421,4.55,463,2.904,505,4.558,521,3.674,525,4.227,528,4.09,575,4.49,607,2.334,621,2.487,775,3.207,787,3.571,809,2.773,832,4.496,985,3.834,1055,3.208,1967,4.252,1976,4.252,2134,5.667,2171,3.629,2179,5.836,2476,5.93,3668,6.727,3669,7.175,3670,6.142]],["t/750",[5,1.7,33,3.435,117,0.87,122,3.24,193,2.924,240,2.658,243,2.058,245,3.114,398,2.924,402,4.547,406,3.94,412,2.707,457,3.561,486,3.561,488,2.677,510,2.318,521,3.424,555,2.879,614,4.01,775,3.428,1273,3.103,1302,4.716,1415,5.358,1418,3.216,1443,3.342,1586,3.986,1727,4.159,1774,5.021,2171,5.515,2180,4.036,2259,5.527,2476,5.527,2771,5.527,3256,3.833,3595,5.021,3671,6.342,3672,5.282,3673,6.27,3674,7.356,3675,5.725,3676,6.973,3677,7.356,3678,4.34]],["t/752",[96,4.909,123,3.23,180,3.372,203,4.624,218,3.66,239,4.962,240,2.382,775,3.071,877,5.87,923,2.755,1009,3.737,2522,7.431,3679,9.724,3680,6.121]],["t/754",[5,2.535,33,4.506,41,4.339,194,3.639,218,3.359,226,4.485,258,3.675,259,1.815,402,3.738,490,3.96,630,5.265,756,4.553,867,2.971,1344,5.345,1904,4.863,1914,4.807,2157,4.281,2502,6.944,2900,6.163,3078,5.833,3318,5.833,3643,7.835]],["t/756",[5,1.917,6,4.549,7,2.885,38,3.287,83,1.767,178,5.462,184,7.071,240,2.032,297,3.952,402,3.475,463,3.052,553,4.758,660,3.83,771,6.34,809,2.914,887,5.538,989,5.132,993,3.451,1146,4.695,1300,5.538,1443,3.768,1586,4.495,1617,5.319,2062,3.911,2134,5.957,2171,3.814,2469,5.957,2608,5.801,2871,7.542,3643,7.285,3681,8.95,3682,7.542]],["t/758",[6,5.215,7,2.617,151,6.831,207,6.419,421,3.853,525,5.094,538,3.255,550,6.737,775,3.004,785,5.28,985,3.075,989,5.884,1036,5.612,2932,10.727,3683,9.016]],["t/760",[4,4.276,6,3.901,33,2.519,41,3.459,43,2.67,73,2.284,83,2.021,90,2.819,97,2.369,137,3.133,193,2.828,240,2.789,296,2.706,457,3.444,496,4.167,505,6.852,520,3.974,579,2.837,606,4.519,678,4.109,809,2.499,831,3.747,832,4.053,891,3.747,954,5.537,978,2.423,1154,6.064,1213,4.295,1308,3.878,1332,3.747,1425,6.247,1475,4.975,1609,3.901,1643,5.109,1760,5.906,1791,3.832,2033,5.182,2171,3.271,2179,8.421,2434,5.647,2662,4.329,3662,6.554,3684,10.237,3685,10.237,3686,7.114,3687,7.114,3688,6.468,3689,7.114]],["t/762",[1,2.668,7,2.784,30,1.732,44,1.94,83,2.155,115,3.765,117,1.196,139,2.489,153,6.156,165,3.652,187,2.741,226,3.943,245,3.32,438,5.803,463,2.886,528,4.066,538,2.685,604,5.078,612,2.472,614,4.276,621,2.472,622,5.763,624,4.226,660,4.67,809,2.756,890,3.924,987,3.024,1829,3.481,1867,7.437,1943,4.938,1987,7.318,3690,6.513,3691,8.463]],["t/764",[5,1.681,7,2.002,12,2.522,73,2.335,83,2.051,86,2.386,115,2.707,117,1.277,122,4.241,186,3.18,187,2.542,193,3.827,197,3.656,199,4.855,240,2.358,297,2.308,402,3.047,414,3.497,452,4.661,463,3.972,483,2.986,492,3.1,623,4.709,660,3.358,666,3.24,740,3.604,809,2.555,810,5.153,811,5.898,816,4.241,1083,4.755,1267,4.664,1816,3.415,1934,4.324,1966,3.965,2180,3.026,2353,6.149,2380,4.84,2469,5.223,2770,3.372,3511,4.09,3692,7.847,3693,7.847]],["t/766",[3,4.176,44,1.798,83,1.997,126,3.954,240,2.769,296,2.673,391,2.886,398,3.725,411,2.34,463,3.449,607,2.772,638,6.731,668,3.773,1455,5.751,2180,3.9,3662,6.475,3666,8.886,3694,7.989,3695,7.44]],["t/768",[3,3.537,7,2.185,15,4.303,76,6.225,115,2.955,122,3.497,126,3.349,148,2.185,186,4.924,193,4.052,197,5.661,199,5.301,200,5.485,297,2.52,492,3.385,732,2.697,832,5.809,1009,3.051,1418,3.471,1586,4.303,1589,5.359,1753,5.461,1816,3.728,1829,3.524,1989,4.955,2180,4.242,2304,3.827,2819,6.18,3679,7.94,3696,11.262,3697,8.567,3698,7.219]],["t/770",[2,3.546,4,3.601,73,2.565,76,4.185,115,2.973,117,1.211,122,4.975,172,1.995,411,1.995,421,3.237,492,3.406,521,3.719,555,3.126,660,3.688,809,3.596,816,3.519,831,4.208,985,2.584,1019,3.997,1024,3.903,1049,4.943,1055,3.247,1308,4.355,2171,4.706,2304,3.85,3511,4.492,3671,5.223,3672,8.111,3673,8.725,3699,8.62,3700,7.016,3701,6.28,3702,8.498,3703,7.264]],["t/772",[3,2.611,5,1.355,24,3.105,33,4.188,75,3.409,83,2.359,91,2.918,117,1.141,156,1.537,214,2.207,229,3.056,240,1.436,271,2.33,285,2.825,320,3.385,411,2.073,454,4.002,463,3.056,465,4.562,483,2.406,488,3.022,489,2.11,490,2.602,525,3.14,538,2.007,555,2.294,604,5.376,611,2.652,627,2.752,785,3.254,802,2.188,809,2.059,831,3.088,875,2.038,891,3.088,991,2.776,997,2.253,1011,3.296,1013,2.991,1062,2.864,1083,3.833,1208,2.891,1302,3.759,1344,3.511,1418,2.563,1715,2.563,1773,3.409,1801,3.318,1808,4.562,1829,2.602,1872,5.329,1949,3.485,2125,5.329,2157,5.033,2259,4.404,2260,2.812,2434,4.653,2467,3.759,2476,4.404,2815,3.485,2816,5.329,2900,4.049,2975,3.485,3030,4.002,3103,4.335,3665,7.675,3704,6.324,3705,4.867,3706,5.148,3707,5.329,3708,6.324,3709,4.996,3710,4.996,3711,6.324,3712,6.324,3713,4.754]],["t/774",[4,3.334,5,1.71,10,2.904,13,4.699,30,2.403,83,1.576,122,4.794,165,3.444,167,4.539,193,5.073,197,3.719,199,4.938,219,2.634,245,3.131,297,2.347,525,3.962,579,2.95,621,2.331,732,2.513,809,2.599,814,3.96,816,3.258,832,6.589,875,2.572,1062,3.614,1066,3.94,1244,7.013,1267,4.743,1370,4.657,1377,7.578,1966,6.304,1974,4.057,2331,4.886,2619,5.073,2770,3.429,2896,6.142]],["t/776",[73,2.715,117,1.372,186,4.64,187,2.956,193,4.218,196,3.424,197,6.113,199,7.084,216,4.755,248,4.954,297,2.684,555,3.31,602,5.708,660,4.899,756,4.316,802,3.156,967,5.708,1828,6.582,1966,4.61,2353,4.818,2380,4.251,2469,6.073,2619,4.407,3511,4.755,3646,6.463]],["t/778",[193,4.379,197,4.516,296,2.562,545,6.451,819,5.874,867,3.668,1019,4.494,1091,5.424,1267,5.76,1286,5.118,1443,4.081,1753,4.812,1792,6.063,1838,6.936,1953,6.063,2180,4.584,2506,6.365,2770,4.165,3374,7.285,3678,5.301,3714,10.017]],["t/780",[0,5.436,1,3.035,2,3.965,7,1.791,12,4.299,17,4.248,19,3.636,51,4.841,106,3.409,123,3.647,139,2.835,209,3.92,259,2.708,266,3.017,287,2.978,526,2.62,560,4.809,565,4.097,612,2.051,735,3.733,775,2.055,809,2.286,978,2.216,1090,3.486,1140,6.681,1169,4.061,1205,3.194,1277,3.708,1421,3.428,1798,5.917,1917,5.403,2134,4.673,2237,4.673,2561,5.715,3264,6.508,3599,6.17,3715,5.065,3716,6.17]],["t/782",[83,2.541,123,3.408,411,2.978,414,3.49,597,4.269]],["t/784",[7,2.637,12,3.972,83,2.61,117,1.133,123,3.804,137,4.22,411,2.392,414,2.803,529,3.617,573,5.927,908,3.82,2570,5.533,2760,7.456]],["t/786",[21,2.363,44,1.905,83,1.922,91,2.591,117,1.174,122,3.973,138,2.538,139,1.651,172,1.299,186,2.275,193,2.069,240,1.867,243,1.456,264,2.616,414,3.093,463,1.915,473,1.651,474,2.069,483,2.136,510,1.64,529,1.965,530,2.464,607,2.668,621,1.64,650,4.05,655,3.687,659,2.158,735,2.985,740,4.92,748,2.151,796,2.683,801,7.056,802,2.845,803,3.848,804,4.732,805,4.436,808,5.825,809,2.678,810,5.4,811,4.22,812,3.474,813,3.91,814,2.774,815,4.732,816,3.973,817,3.006,818,2.871,819,3.403,820,2.006,822,2.25,832,4.343,923,1.475,957,2.129,969,2.804,976,3.553,1062,2.542,1181,2.854,1599,4.018,1647,3.276,1714,3.64,1727,1.994,1753,4.083,1962,3.737,1966,4.155,2180,4.131,2345,4.22,2353,5.657,2468,3.006,2770,2.413,2853,2.871,3032,3.403,3208,3.687,3359,3.737,3659,4.498,3717,4.732,3718,5.204,3719,4.934,3720,5.204,3721,5.204,3722,5.204,3723,5.204,3724,5.204,3725,5.204,3726,7.623,3727,5.204]],["t/788",[117,1.468,193,3.924,197,4.962,243,2.762,607,2.92,621,3.11,831,6.141,1966,5.381,3319,7.96]],["t/790",[1,1.271,17,2.291,30,1.59,38,1.909,44,2.06,72,3.615,73,1.547,83,2.537,86,2.828,92,4.568,102,3.563,105,3.51,117,0.852,123,1.6,126,2.032,144,2.932,148,1.981,155,2.658,156,2.26,160,2.596,163,2.471,214,1.814,405,3.216,411,2.779,412,1.773,414,3.622,437,3.772,445,4.218,544,2.611,607,1.425,645,2.155,666,2.146,679,2.626,719,2.312,740,2.387,775,1.522,810,3.413,868,2.552,869,5.246,878,3.37,896,2.843,942,2.626,994,4.756,1008,2.155,1203,2.909,1204,2.122,1331,2.099,1547,2.727,1896,2.932,2016,2.783,2425,4.218,2468,2.783,2593,4.381,2790,3.15,2903,3.328,3067,3.413,3070,3.37,3318,4.707,3528,4,3607,3.328,3728,6.709,3729,4.818,3730,4.818,3731,4.818,3732,4.818,3733,4.818,3734,4.568,3735,4.818,3736,4.818,3737,6.826,3738,4.818,3739,3.563,3740,3.682,3741,3.252,3742,5.41,3743,3.824,3744,5.502,3745,3.824,3746,5.324,3747,3.824,3748,3.824,3749,3.62,3750,3.907,3751,4.231,3752,4.231,3753,4.231,3754,6.826,3755,4.818,3756,4.818,3757,4.818,3758,4.231,3759,4.818,3760,4.107,3761,4.818]],["t/792",[97,3.098,172,2.323,264,4.678,406,4.984,414,2.723,463,3.424,470,3.076,531,4.984,562,4.099,775,2.939,781,3.072,896,5.491,957,4.605,987,3.587,1025,5.013,1509,7.112,1596,3.71,3604,8.461,3762,7.546]],["t/794",[86,3.525,137,3.799,155,4.759,156,2.261,168,3.867,172,2.682,186,5.116,414,3.759,437,4.519,1596,4.666,2380,5.882,3741,5.822,3760,7.352,3763,8.177,3764,10.185,3765,8.177,3766,7.352]],["t/796",[4,2.188,17,2.308,30,1.072,44,0.931,76,2.543,78,6.466,86,3.533,97,1.616,106,3.793,117,0.856,155,2.678,156,1.898,172,1.212,196,1.566,219,1.728,243,1.358,263,2.429,414,3.661,437,3.793,462,3.003,470,2.393,490,2.154,520,4.045,544,2.63,568,2.557,579,1.935,586,2.35,610,2.6,719,3.474,732,2.459,740,2.405,781,1.325,810,3.439,867,1.616,868,2.571,874,2.843,896,5.109,923,2.052,991,2.298,1009,2.782,1159,2.729,1203,5.228,1331,2.114,1351,3.206,1386,3.206,1552,3.314,1618,3.119,1723,2.978,1789,3.439,1858,3.056,1989,3.029,2006,2.382,2016,2.803,2018,2.6,2022,3.647,2165,3.439,2295,2.864,2316,2.361,2662,4.406,2790,4.734,2907,4.942,3154,3.647,3739,3.589,3740,3.71,3741,3.276,3742,3.647,3743,3.853,3744,5.533,3746,3.589,3747,3.853,3748,3.853,3749,3.647,3750,3.936,3767,4.137,3768,4.03,3769,4.413,3770,3.778,3771,4.854,3772,10.427,3773,4.137,3774,4.137,3775,8.659,3776,6.358,3777,4.854,3778,6.583,3779,6.583,3780,7.24,3781,4.854,3782,4.413]],["t/798",[17,2.6,30,1.207,44,1.049,76,2.864,86,4.026,96,2.322,97,1.82,117,0.934,155,3.016,156,2.432,172,1.365,196,1.764,219,2.813,263,1.834,414,3.675,437,4.86,470,1.807,490,2.426,544,2.962,568,2.88,579,2.18,586,2.647,610,2.928,612,1.723,651,3.926,732,2.684,740,2.709,781,1.492,810,3.873,867,1.82,896,4.662,923,1.549,942,4.307,997,2.101,1159,3.074,1189,3.982,1203,5.601,1331,2.381,1618,3.404,1722,2.722,1723,3.354,1789,3.873,1858,3.442,2006,2.683,2016,3.157,2018,2.928,2165,3.873,2790,5.166,2907,3.732,3739,4.043,3740,4.178,3741,3.69,3742,4.108,3743,4.339,3744,6.038,3746,4.043,3747,4.339,3748,4.339,3749,4.108,3767,6.734,3768,4.539,3769,4.971,3783,7.901,3784,10.78,3785,5.183,3786,4.971,3787,7.901,3788,5.467,3789,9.277,3790,7.901,3791,5.467,3792,7.901,3793,5.467,3794,5.467]],["t/800",[4,4.261,17,3.365,21,2.931,83,1.507,156,1.855,172,2.837,194,2.885,214,2.663,218,2.663,235,3.667,240,1.733,262,3.557,297,2.245,414,3.698,437,3.706,470,3.756,490,4.195,504,5.578,538,2.422,681,3.425,740,3.505,753,4.228,896,7.341,908,2.821,1331,4.637,1618,4.073,2006,4.64,2016,4.086,3318,6.181,3739,5.232,3740,5.407,3741,6.38,3795,8.595,3796,7.075]],["t/803",[93,5.835,414,3.619,510,3.087,514,5.309,756,4.999,998,3.101,1035,6.113,1177,3.507,3319,6.688,3797,6.168,3798,7.945]],["t/805",[77,5.197,78,4.737,86,2.868,106,4.58,211,4.32,414,3.17,481,5.774,663,4.087,760,4.555,868,4.63,923,2.477,998,3.429,1070,4.737,1177,3.129,1790,4.291,1818,6.82,1853,7.156,1988,4.279,2275,4.139,3319,5.968,3799,8.742,3800,8.742,3801,7.451,3802,8.742]],["t/808",[7,2.802,83,2.529,139,3.767,411,2.964,443,4.607,1170,4.681]],["t/810",[28,4.678,72,4.145,75,5.05,83,2.298,105,7.858,117,1.027,139,3.724,411,2.93,607,2.569,693,5.467,694,4.574,912,4.409,994,5.736,1043,6.893,1547,4.914,2331,5.736,3690,7.21,3728,8.396,3803,8.683,3804,8.683,3805,6.893,3806,7.042]],["t/813",[1,1.691,7,2.785,30,2.235,33,4.19,156,2.318,160,4.763,193,2.548,210,2.289,226,3.223,240,2.166,242,3.474,243,2.474,411,1.601,412,3.253,414,1.876,443,4.58,490,4.492,504,3.783,615,3.493,621,2.02,663,2.997,719,5.491,903,4.377,942,6.239,993,4.539,1011,3.605,1253,3.538,1465,3.118,2171,2.948,2337,3.653,2492,8.832,2517,9.581,2689,5.089,3032,7.736,3247,4.99,3611,4.036,3807,4.99,3808,5.465,3809,4.99,3810,3.934]],["t/815",[7,2.806,20,3.861,83,2.172,117,0.939,139,2.52,156,2.082,166,5.525,172,1.982,217,4.794,226,3.992,243,3.151,296,2.264,411,2.545,443,5.096,470,2.624,626,3.281,663,3.712,775,2.508,942,6.477,993,4.242,1110,5.42,1177,2.842,1344,4.757,1509,6.068,2176,7.219,2337,4.524,2492,7.427,3811,6.439,3812,6.768,3813,7.219,3814,7.219,3815,7.528]],["t/817",[1,2.895,5,1.739,7,2.71,30,1.662,73,2.416,83,2.098,87,2.785,97,2.506,107,5.974,117,1.298,139,3.483,148,2.071,156,1.973,164,3.315,241,4.377,243,2.106,248,4.409,258,3.1,267,1.989,411,2.459,443,3.406,473,3.125,521,3.504,531,4.031,621,2.371,645,3.366,659,3.121,663,3.518,694,3.964,781,2.054,787,3.406,957,3.079,963,4.872,980,3.533,993,4.097,2954,5.858,3032,4.921,3605,6.103,3607,6.803,3690,6.249,3807,5.858,3811,6.103]],["t/819",[1,1.244,5,0.544,7,2.881,30,2.156,33,3.671,43,0.884,44,2.589,72,0.453,73,0.412,81,2.784,83,1.43,85,0.392,113,0.808,117,0.558,137,0.566,138,0.428,139,3.46,144,0.781,148,1.733,156,2.595,160,3.818,163,1.208,164,1.038,165,0.598,172,2.125,187,1.413,193,1.875,197,0.645,205,0.981,206,0.758,210,1.896,218,0.483,219,0.457,220,0.669,226,2.032,238,0.801,240,2.027,242,3.16,243,1.486,248,1.38,255,0.839,258,0.529,265,0.752,267,0.622,296,0.366,323,0.727,339,0.627,398,0.936,411,1.326,414,2.491,436,0.839,443,5.241,470,0.424,483,0.527,490,2.979,504,3.961,505,0.742,529,0.485,538,0.806,553,2.319,586,1.14,613,1.269,614,0.7,615,2.097,617,2.303,619,0.63,620,3.12,621,1.487,645,1.053,654,0.561,663,0.6,670,1.135,681,0.622,687,1.669,748,0.973,756,1.202,759,0.636,760,0.669,783,0.876,866,0.616,903,3.221,923,0.364,953,1.101,959,0.965,963,0.831,980,0.603,993,4.221,1011,1.835,1028,0.673,1052,0.887,1125,0.655,1127,0.876,1177,0.46,1204,0.566,1253,1.801,1431,1.19,1465,3.062,1596,2.117,1773,0.747,1815,0.999,1874,0.808,1894,1.87,2006,2.606,2171,1.501,2240,0.867,2304,1.135,2316,0.624,2337,2.303,2425,0.752,2449,0.831,2468,1.885,2517,7.669,2689,2.59,2754,0.747,2886,1.066,2887,1.066,2951,3.278,3032,6.777,3128,0.999,3247,3.146,3357,1.066,3481,1.066,3485,1.217,3717,2.967,3807,1.833,3809,2.54,3810,2.002,3811,1.041,3812,1.094,3816,1.284,3817,5.31,3818,2.179,3819,2.142,3820,2.356,3821,2.142,3822,5.31,3823,2.356,3824,5.31,3825,2.142,3826,2.356,3827,2.356,3828,2.356,3829,2.356,3830,2.356,3831,2.356,3832,2.356,3833,2.356,3834,3.263,3835,2.356,3836,1.094,3837,1.066,3838,2.008,3839,2.008,3840,1.284,3841,6.041,3842,5.303,3843,8.436,3844,4.29,3845,1.284,3846,1.284,3847,1.128,3848,1.284,3849,2.356,3850,1.167,3851,1.284,3852,1.284,3853,1.284,3854,2.142,3855,0.999,3856,1.284,3857,1.094,3858,1.284,3859,1.284,3860,1.284,3861,1.284,3862,1.284,3863,1.284,3864,1.284,3865,1.167,3866,2.356,3867,1.284,3868,1.284,3869,1.284,3870,1.167]],["t/821",[1,1.415,5,0.355,7,1.648,30,0.612,33,2.76,44,2.47,47,3.559,73,0.493,81,1.636,83,0.591,117,0.182,139,1.473,144,0.935,148,2.145,156,1.407,163,1.422,164,1.221,165,0.715,166,4.223,168,0.553,172,1.339,218,1.427,220,0.8,226,2.333,240,2.192,243,1.299,296,0.438,338,0.805,402,1.588,406,2.03,411,2.105,412,1.395,414,2.049,443,3.527,470,0.916,479,1.275,486,3.16,490,1.682,505,0.887,538,0.526,586,1.342,613,2.042,615,2.365,617,3.411,619,0.754,620,3.469,621,1.691,645,1.24,646,2.03,654,0.672,687,1.964,756,0.784,775,2.062,781,0.419,796,5.517,803,1.136,814,2.7,834,0.618,993,3.087,1052,1.061,1072,0.837,1098,0.893,1125,0.784,1146,3.388,1308,0.837,1355,1.025,1431,0.776,1509,2.897,1586,2.054,1596,0.612,1612,2.561,1773,0.893,1874,0.967,1957,1.061,2006,0.754,2018,0.823,2021,1.004,2036,3.009,2171,2.753,2240,1.037,2260,1.818,2263,1.878,2275,5.066,2278,0.994,2304,1.336,2316,2.257,2337,2.645,2359,7.068,2360,7.912,2425,0.9,2449,0.994,2456,2.478,2587,4.498,2754,2.205,2879,1.174,2951,3.764,3030,2.587,3032,5.096,3357,1.275,3807,1.195,3810,2.848,3814,4.878,3818,2.53,3819,2.521,3821,2.521,3825,4.22,3836,1.309,3837,1.275,3838,2.364,3839,2.364,3841,3.957,3842,6.366,3843,9.444,3844,4.22,3850,2.521,3854,3.446,3855,6.561,3857,3.231,3865,2.521,3870,2.521,3871,1.219,3872,1.456,3873,1.074,3874,2.773,3875,2.773,3876,1.536,3877,1.536,3878,10.144,3879,1.536,3880,4.22,3881,2.773,3882,2.773,3883,3.79,3884,3.79,3885,3.79,3886,3.79,3887,3.79,3888,3.79,3889,3.79,3890,3.446,3891,3.79,3892,3.79,3893,3.074,3894,3.79,3895,3.074,3896,3.79,3897,3.593,3898,3.79,3899,1.219,3900,3.79,3901,1.275,3902,1.536,3903,1.536,3904,1.536,3905,4.087,3906,1.536,3907,2.773,3908,2.773,3909,1.456,3910,2.773,3911,1.536,3912,1.536,3913,1.536,3914,1.536,3915,2.773,3916,2.773,3917,1.456,3918,0.985,3919,1.536,3920,1.536,3921,1.536,3922,1.536]],["t/823",[1,2.321,30,1.943,44,2.265,117,1.287,148,2.994,172,2.197,243,2.463,443,3.982,613,4.741,615,3.476,620,5.39,621,2.773,740,4.361,744,5.048,753,3.936,980,4.132,993,3.662,1596,3.509,2078,7.137,3807,6.85,3811,7.137,3843,7.502,3923,7.729,3924,8.801]],["t/825",[148,2.802,219,3.625,470,3.365,529,3.844,748,4.207,1934,6.053,2478,5.88,3032,6.657,3812,8.678]],["t/827",[148,2.869,166,5.65,767,6.623,998,3.301,2478,6.022,3813,9.479]],["t/830",[1,2.26,72,3.026,83,2.485,87,3.171,117,1.265,148,2.358,210,4.362,411,3.05,693,5.394,694,4.513,993,3.565,994,5.66,1404,5.919,1547,6.055,2331,5.66,2954,6.669,3605,6.949,3607,5.919,3728,8.327,3806,6.949,3925,8.569,3926,8.569]],["t/833",[81,5.491,126,4.748,178,4.849,276,5.896,402,3.898,817,6.501,818,6.21,871,5.574,985,3.64,1380,6.778,1727,3.565,1846,6.084,2171,5.175,3927,8.461,3928,8.461]],["t/835",[81,5.612,126,4.81,178,4.955,276,5.974,402,3.984,985,3.688,1380,6.927,1727,3.644,1846,6.218,2171,5.244,3927,8.646,3928,8.646,3929,8.646,3930,9.51]],["t/838",[44,2.348,81,4.629,338,5.299,796,5.216,1487,7.075,2165,7.167,2415,5.926,2674,5.802,2907,7.644,3071,5.843,3931,7.644,3932,7.369,3933,7.844,3934,10.116,3935,10.116,3936,10.116,3937,10.116,3938,10.116,3939,10.116,3940,7.844,3941,7.844,3942,7.844,3943,7.844,3944,7.844,3945,7.437]],["t/840",[30,1.93,44,2.258,81,5.158,473,2.774,796,4.507,814,3.942,834,3.519,1331,3.808,2021,5.716,2024,6.114,2316,4.251,2674,5.014,3071,5.049,3946,8.742,3947,8.742,3948,10.833,3949,10.833,3950,10.833,3951,10.833,3952,10.833,3953,8.288,3954,8.742]],["t/842",[33,1.924,44,2.654,47,3.83,81,1.434,414,0.711,796,5.092,814,0.884,1009,0.934,2024,6.907,2260,3.464,2353,4.788,2587,1.826,2619,1.266,2674,5.665,3030,4.388,3071,5.704,3511,1.366,3665,7.522,3810,3.334,3893,1.97,3955,2.43,3956,2.43,3957,2.43,3958,4.151,3959,6.428,3960,5.434,3961,2.43,3962,2.43,3963,6.428,3964,2.43,3965,2.43,3966,7.867,3967,2.43,3968,2.43,3969,2.303,3970,2.43,3971,2.43,3972,2.43,3973,2.43,3974,2.43,3975,7.867,3976,2.43,3977,2.43,3978,2.43,3979,2.43,3980,2.43,3981,2.43,3982,2.43,3983,2.43,3984,2.43,3985,2.43,3986,7.22,3987,2.43,3988,2.43,3989,2.43,3990,2.43,3991,2.43,3992,2.43,3993,2.43,3994,2.43,3995,2.43,3996,2.43,3997,2.43,3998,2.43,3999,2.43,4000,2.43,4001,2.43,4002,2.43,4003,2.43,4004,2.43,4005,2.43,4006,2.43,4007,2.43,4008,2.43,4009,2.43,4010,2.43,4011,2.43,4012,2.43,4013,2.43,4014,2.43,4015,2.43,4016,2.43,4017,2.43,4018,2.43,4019,2.43,4020,2.43,4021,2.43,4022,5.434,4023,2.43,4024,2.43,4025,2.43,4026,2.43,4027,2.43,4028,2.43,4029,2.43,4030,2.43,4031,2.43,4032,2.43,4033,4.151,4034,2.43,4035,2.43,4036,2.43,4037,2.43,4038,2.43,4039,2.43,4040,2.43,4041,2.43,4042,2.43,4043,2.43,4044,2.43,4045,2.43,4046,2.43,4047,2.43,4048,2.43,4049,2.43,4050,2.43,4051,2.43,4052,2.43,4053,2.43,4054,2.43,4055,2.43,4056,4.151,4057,4.151,4058,6.428,4059,2.43,4060,2.43,4061,2.43,4062,2.43,4063,2.43,4064,2.43]],["t/846",[76,4.674,83,1.901,148,3.019,172,2.227,200,6.163,411,2.227,414,3.476,437,4.674,575,3.945,659,3.7,840,5.189,866,4.281,868,4.725,891,4.699,997,3.429,1431,4.507,1988,4.333,2468,5.153,3319,7.489,4065,7.605,4066,8.922,4067,8.922]],["t/848",[72,3.384,83,2.041,117,1.133,411,2.86,414,3.351,659,3.972,693,6.031,694,5.046,994,6.328,1547,5.422,2331,6.328,3728,8.915,3806,7.769,4065,8.166]],["t/850",[17,0.583,27,0.639,44,2.511,47,2.195,72,1.109,76,1.184,77,4.108,78,2.472,83,0.481,85,0.374,86,1.497,103,2.727,106,0.643,113,1.422,117,0.145,141,0.794,146,3.204,148,2.08,150,0.551,155,0.677,156,0.322,163,1.159,187,0.79,188,0.665,190,1.203,195,1.58,199,1.508,200,0.848,211,2.606,214,0.462,219,0.804,242,1.224,243,1.277,250,1.358,335,3.551,339,0.599,411,0.306,414,2.622,415,3.046,437,4.37,445,3.317,470,0.406,483,0.504,486,1.094,490,0.545,505,0.709,526,0.494,544,0.665,566,1.758,575,1.724,586,0.594,619,1.541,621,0.712,659,0.937,666,0.547,697,0.623,719,1.084,740,0.608,753,1.744,759,1.932,775,1.625,781,0.335,796,6.013,808,0.938,810,0.869,820,0.871,840,2.268,868,4.004,871,0.735,896,0.724,953,0.574,955,0.56,978,1.554,994,1.492,997,0.868,1009,2.176,1029,0.753,1114,0.772,1125,0.626,1162,0.766,1177,0.439,1308,0.669,1331,0.534,1332,2.71,1393,3.114,1443,0.557,1509,0.938,1596,0.901,1640,0.591,1818,0.772,1853,0.81,1934,0.729,1988,0.485,2016,0.709,2018,0.657,2019,5.192,2022,2.359,2024,3.191,2051,1.077,2118,1.343,2240,0.828,2359,7.732,2360,8.656,2425,1.839,2662,0.747,2674,3.749,2790,0.802,3128,1.758,3319,1.542,3321,1.046,3739,0.907,3740,0.938,3741,0.828,3742,0.922,3743,0.974,3744,1.727,3745,0.974,3746,1.671,3747,0.974,3748,0.974,3749,0.922,3750,0.995,3751,1.077,3752,1.077,3753,1.077,3758,8.882,3760,2.676,3772,1.116,3773,1.046,3774,1.046,3776,4.972,3778,5.148,3779,5.148,3801,3.324,3871,0.974,4065,2.676,4068,2.259,4069,6.123,4070,3.152,4071,1.227,4072,1.227,4073,1.227,4074,1.163,4075,1.227,4076,1.227,4077,1.227,4078,2.259,4079,0.907,4080,9.978,4081,7.842,4082,3.9,4083,1.227,4084,5.662,4085,4.004,4086,5.662,4087,3.14,4088,2.259,4089,7.25,4090,1.227,4091,5.662,4092,1.227,4093,1.227,4094,3.14,4095,1.227,4096,5.662,4097,2.259,4098,5.662,4099,4.562,4100,3.152,4101,1.227,4102,1.227,4103,1.227,4104,1.227,4105,5.145,4106,4.878,4107,1.227,4108,1.227,4109,2.259,4110,2.259,4111,1.227,4112,2.259,4113,5.662,4114,3.14,4115,2.259,4116,2.259,4117,1.227,4118,2.259,4119,2.259,4120,1.227,4121,1.227,4122,1.227,4123,2.259,4124,2.259,4125,2.259,4126,1.227,4127,7.842,4128,2.259,4129,1.227,4130,1.227,4131,1.227,4132,1.227,4133,2.259,4134,1.046,4135,1.227,4136,1.227,4137,6.537,4138,2.259,4139,1.227,4140,1.227,4141,1.227,4142,2.259,4143,1.227,4144,1.227,4145,1.019,4146,1.227,4147,2.259,4148,2.259,4149,2.259,4150,2.259,4151,1.227,4152,1.227,4153,1.163,4154,1.163,4155,1.227,4156,1.227,4157,1.227,4158,1.227,4159,2.259,4160,1.227,4161,1.163,4162,1.227,4163,1.227,4164,1.227]],["t/853",[33,3.138,38,3.511,83,2.327,117,1.048,123,2.943,168,3.189,208,3.767,271,3.522,296,3.115,529,3.346,681,4.29,879,5.53,971,5.083,1009,3.405,1019,4.433,4079,6.553,4165,8.502,4166,8.861,4167,8.861,4168,6.772,4169,5.268,4170,5.915,4171,7.782]],["t/855",[72,3.359,83,2.429,117,1.125,693,5.987,694,5.009,971,7.006,994,6.282,1547,5.382,2331,6.282,3728,8.876,3806,7.712,4165,9.507]],["t/857",[1,1.887,33,3.372,78,3.876,193,2.843,242,3.876,243,2.002,259,1.456,338,3.747,412,4.2,414,2.093,415,4.775,492,4.059,615,3.761,621,2.254,663,3.344,719,5.136,814,3.895,942,5.835,971,6.546,1399,3.768,1483,4.775,1552,4.883,1841,2.834,1948,5.795,2018,3.831,2043,5.21,2118,4.253,2171,3.289,2305,4.221,2316,3.479,2492,5.21,2673,4.677,2751,4.544,2975,4.253,3118,6.504,3502,6.8,3511,5.354,3857,6.097,4165,8.883,4170,4.775,4172,6.504]],["t/859",[1,1.54,5,0.681,30,1.078,33,2.213,38,0.451,44,2.505,47,1.142,73,0.946,83,0.449,87,0.421,97,0.379,113,1.854,117,0.691,123,0.378,148,2.001,156,0.553,163,1.082,164,1.618,165,0.53,172,1.345,193,1.171,208,2.106,220,1.099,242,1.991,243,0.59,258,0.469,259,0.429,339,2.107,406,0.61,412,1.587,414,1.576,420,1.235,486,2.088,492,2.296,505,0.658,579,0.454,584,0.57,586,1.426,613,1.587,615,1.163,617,2.458,619,0.559,620,3.602,621,1.969,645,2.183,654,0.922,663,0.532,687,2.603,694,0.6,756,1.076,764,2.235,775,0.666,796,5.792,814,2.274,834,2.168,879,0.711,957,0.466,971,6.056,998,0.932,1009,3.991,1052,1.457,1125,0.581,1399,1.935,1431,0.575,1483,1.966,1552,2.508,1596,0.454,1612,2.38,1773,1.227,1841,2.134,1874,1.328,2018,1.13,2043,2.676,2118,1.751,2171,1.354,2233,0.752,2239,3.258,2240,0.769,2275,2.043,2304,1.77,2305,5.429,2316,3.919,2359,7.421,2360,8.307,2425,0.667,2449,1.365,2673,1.379,2751,2.334,2754,0.662,2951,3.958,2954,0.886,2975,1.751,3357,1.751,3502,3.97,3605,0.923,3607,1.457,3659,2.88,3818,1.966,3836,1.798,3837,1.751,3838,3.131,3839,2.51,3841,4.16,4134,2.51,4145,9.327,4165,8.152,4170,3.258,4173,2.945,4174,2.109,4175,2.109,4176,2.109,4177,2.109,4178,2.109,4179,2.109,4180,2.109,4181,2.109,4182,2.109,4183,2.109,4184,1.999,4185,1.139,4186,1.139,4187,1.139,4188,1.798,4189,1.139,4190,3.674,4191,1.139,4192,1.139,4193,1.139,4194,1.139,4195,1.139,4196,1.139,4197,1.139,4198,1.139,4199,1.139,4200,1.139,4201,1.139,4202,1.139,4203,4.314,4204,1.139,4205,1.08,4206,1.08,4207,1.08,4208,1.08,4209,1.08,4210,4.314,4211,4.314,4212,4.314,4213,4.314,4214,4.314,4215,4.314,4216,4.314,4217,4.314,4218,4.314,4219,4.314,4220,1.139,4221,1.139,4222,2.945,4223,1.139,4224,1.139,4225,2.109,4226,4.314,4227,4.314,4228,4.314,4229,4.314,4230,4.314,4231,1.139,4232,4.314,4233,4.314,4234,4.314,4235,4.314,4236,4.314,4237,1.139,4238,1.139,4239,1.139,4240,2.945,4241,2.945,4242,4.314,4243,4.314,4244,4.314,4245,4.314,4246,4.314,4247,1.139,4248,4.314,4249,4.314,4250,4.314,4251,4.314,4252,4.314,4253,2.109,4254,3.674,4255,5.387,4256,1.139,4257,1.139,4258,1.139]],["t/861",[1,2.056,30,1.722,33,2.761,44,2.476,117,1.192,148,2.773,172,1.947,208,2.48,243,2.182,259,1.587,414,2.281,420,4.568,492,3.324,613,4.201,615,3.08,620,4.993,621,2.457,740,3.863,744,4.472,753,3.487,814,2.837,834,3.139,971,4.472,980,3.661,1399,4.107,1596,3.109,1841,3.089,2018,4.176,2078,6.323,2673,5.098,2754,4.535,3923,6.847,4134,6.646,4165,6.069,4170,5.205,4172,7.089,4188,6.646,4259,7.797]],["t/865",[10,3.78,33,2.576,44,2.292,83,1.549,122,3.204,150,3.265,187,3.365,193,2.891,240,2.814,271,2.891,296,2.074,297,2.308,315,5.249,330,3.331,398,3.827,411,2.404,487,3.123,527,3.874,528,3.77,887,4.855,971,4.172,1013,4.913,1918,4.063,2137,5.558,2180,3.026,2210,5.661,2815,4.324,2921,5.465,3670,5.661,3680,4.579,4260,6.895,4261,4.539,4262,4.579,4263,6.895,4264,5.898,4265,5.223,4266,5.223,4267,6.387,4268,7.273,4269,6.895,4270,4.23,4271,6.895,4272,5.898,4273,6.895,4274,6.895]],["t/868",[33,3.523,271,3.954,411,2.483,421,4.03,422,7.241,802,3.712,2171,4.574]],["t/870",[33,3.55,193,3.984,421,4.061,422,5.464,528,5.195,544,7.118,2171,4.609]],["t/872",[398,4.212,3673,9.032,3674,10.596,4275,11.433]],["t/874",[33,4.111,193,3.894,411,2.446,421,3.969,525,5.248,985,4.222,986,6.941,1466,8.134,2171,4.505]],["t/876",[7,2.611,12,3.29,30,1.571,117,0.841,118,5.095,128,4.701,137,3.133,180,2.467,196,2.295,296,2.706,391,2.922,510,2.242,574,4.699,604,7.372,641,9.088,668,2.864,756,6.054,775,2.247,781,2.59,867,2.369,873,3.974,978,2.423,985,2.301,1195,4.519,1204,3.133,1214,4,1308,3.878,1487,6.636,1521,4.365,1708,5.769,1829,4.211,1958,4.167,2059,4.167,3027,5.769,3581,6.247]],["t/878",[10,3.78,33,2.576,44,2.292,83,1.549,122,3.204,150,3.265,187,3.365,193,2.891,240,2.814,271,2.891,296,2.074,297,2.308,315,5.249,330,3.331,398,3.827,411,2.404,487,3.123,527,3.874,528,3.77,887,4.855,971,4.172,1013,4.913,1918,4.063,2137,5.558,2180,3.026,2210,5.661,2815,4.324,2921,5.465,3670,5.661,3680,4.579,4260,6.895,4261,4.539,4262,4.579,4263,6.895,4264,5.898,4265,5.223,4266,5.223,4267,6.387,4268,7.273,4269,6.895,4270,4.23,4271,6.895,4272,5.898,4273,6.895,4274,6.895]],["t/880",[1,1.479,3,3.585,5,1.296,10,2.202,12,1.945,16,4.859,29,3.386,76,2.938,83,1.195,115,2.087,117,0.663,126,3.395,148,2.215,193,4.087,197,4.046,267,1.482,351,4.681,398,2.229,411,2.009,419,3.968,466,3.973,510,1.767,511,2.753,530,2.656,534,4.452,535,3.413,544,3.039,557,2.236,560,3.794,598,4.708,600,3.563,629,3.004,634,3.563,732,1.905,742,3.596,753,2.508,775,1.771,802,3.003,809,2.827,832,4.585,879,3.5,998,1.776,1013,2.862,1055,2.28,1168,3.785,1248,3.441,1273,2.366,1362,3.923,1439,3.667,1443,2.548,1577,3.667,1590,5.317,2032,3.022,2121,3.705,2122,4.452,2123,3.596,2125,5.099,2133,4.028,2144,4.714,2145,4.897,2148,4.657,2151,4.452,2180,4.969,2182,3.47,2506,3.973,2545,3.705,2723,3.114,2781,5.317,2789,3.923,2853,5.193,3157,4.548,3581,4.925,3595,5.494,3646,4.286,4276,4.657,4277,5.317,4278,6.051,4279,6.051,4280,4.452,4281,5.609,4282,6.15,4283,6.051,4284,6.051]],["t/883",[1,1.969,5,1.394,7,1.053,10,1.501,11,1.423,12,3.197,24,2.026,29,2.309,30,0.845,83,0.815,86,1.255,90,1.516,117,1.002,123,2.479,128,1.895,139,1.214,168,1.377,182,3.26,194,1.56,209,2.646,210,1.365,214,1.44,240,1.828,287,1.117,296,3.574,297,3.551,315,4.069,391,2.298,398,3.664,411,2.729,421,2.443,457,1.852,463,1.407,466,2.71,473,1.214,490,1.697,510,1.205,526,3.005,527,3.924,531,3.998,544,2.073,560,1.803,571,3.212,575,1.691,578,2.274,593,6.084,595,2.747,597,2.509,599,4.165,600,2.43,607,1.131,612,1.205,636,2.123,753,1.711,754,4.531,781,1.646,802,1.427,813,2.874,820,1.474,840,2.225,873,2.137,875,2.945,909,2.553,937,5.437,987,2.324,1055,3.034,1069,2.123,1091,2.309,1097,1.691,1120,2.241,1157,3.359,1195,2.43,1203,2.309,1205,3.664,1266,2.553,1273,3.149,1278,2.179,1308,2.085,1327,3.64,1362,4.217,1428,3.359,1451,3.359,1455,2.347,1542,3.626,1577,3.943,1615,2.151,1618,1.648,1701,4.459,1718,3.102,1732,4.646,1801,2.165,1813,2.366,1838,2.408,1958,3.532,1982,3.036,1988,1.511,2123,3.866,2130,4.272,2145,3.67,2147,3.478,2230,1.843,2301,2.977,2316,2.932,2555,3.478,2582,3.478,2928,2.747,2934,2.366,3318,2.501,3595,2.611,4285,5.36,4286,4.127,4287,4.127,4288,4.127,4289,3.825,4290,4.127]],["t/888",[1,2.677,5,1.696,7,1.025,12,2.544,24,3.128,29,2.25,76,1.952,83,0.794,103,2.606,117,0.699,123,2.437,128,1.846,165,2.75,168,1.341,182,3.176,214,1.403,240,1.447,296,3.58,315,3.22,391,2.26,397,2.346,398,2.917,411,2.878,419,1.837,421,2.393,422,3.22,457,2.859,526,2.378,527,4.2,531,4.472,532,2.487,541,3.787,544,2.019,545,2.676,560,1.757,563,2.9,571,3.146,575,1.647,593,2.676,595,2.676,597,1.55,598,3.671,599,2.574,600,2.367,607,1.102,629,1.996,636,2.069,668,1.5,753,1.666,754,2.8,775,2.318,802,1.391,809,2.075,813,2.8,820,1.436,822,1.611,866,1.788,875,2.551,891,1.963,923,1.056,953,1.742,998,1.87,1055,2.983,1120,2.183,1195,2.367,1205,1.829,1273,3.095,1308,2.031,1327,2.25,1362,2.606,1396,2.286,1428,3.272,1439,2.436,1451,5.187,1577,2.436,1589,2.515,1590,5.6,1596,1.486,1646,3.176,1701,2.755,1727,1.428,1732,4.579,1816,2.773,1829,1.654,1947,2.755,1958,4.299,2123,4.705,2130,4.185,2133,2.676,2134,2.676,2145,2.268,2147,3.388,2195,4.438,2337,2.123,2555,3.388,2790,3.862,2853,3.259,2919,3.726,2928,4.242,3556,2.9,3581,3.272,3595,2.544,4267,10.275,4277,3.532,4285,2.676,4291,5.907,4292,4.02,4293,9.009,4294,6.381,4295,3.726,4296,4.02]],["t/893",[284,8.959,1738,9.556,2359,6.943,2754,6.113,4297,7.656]],["t/895",[7,1.081,11,1.462,20,1.911,21,1.909,30,1.36,33,2.181,43,1.475,71,2.748,73,1.261,75,2.285,76,2.058,77,2.336,83,1.832,85,1.199,96,3.226,117,1.017,118,1.582,122,1.731,123,1.305,138,1.308,139,2.41,148,1.081,168,1.414,172,2.331,187,2.152,203,1.868,208,2.97,209,1.724,245,1.663,249,1.956,259,0.799,262,1.975,267,1.038,271,4.262,285,4.5,398,3.019,414,1.802,461,4.217,473,3.143,474,1.562,488,1.43,510,1.238,541,2.519,542,2.821,555,1.538,574,2.595,576,2.647,597,2.562,621,1.238,624,2.117,659,3.15,668,2.479,710,2.952,781,1.681,814,1.43,830,3.877,837,2.784,890,1.965,908,1.567,955,1.792,978,3.18,980,2.891,987,1.514,994,4.068,1008,1.757,1014,1.995,1030,2.209,1064,2.623,1115,2.496,1135,2.682,1176,5.113,1177,1.406,1181,3.377,1184,3.349,1187,3.937,1204,1.731,1214,2.209,1231,2.058,1248,2.411,1249,2.224,1253,2.168,1267,2.519,1273,1.657,1355,2.623,1374,2.748,1417,2.519,1439,2.569,1449,3.337,1475,2.748,1477,3.441,1485,2.748,1599,1.75,1607,2.644,1640,1.893,1678,2.129,1732,3.377,1778,1.995,1816,1.845,1871,2.748,1961,3.226,1966,2.142,1985,2.905,2062,1.852,2137,3.003,2140,3.349,2157,1.885,2177,4.87,2230,1.893,2257,3.003,2317,3.186,2318,3.003,2380,1.975,2415,2.302,2440,3.536,2443,2.354,2531,2.748,2674,2.254,2751,2.496,2881,2.663,2899,2.318,2925,3.349,2975,2.336,3030,2.682,3659,2.318,3810,2.411,4298,5.599,4299,3.725,4300,3.725,4301,3.186,4302,3.45,4303,3.349,4304,3.725,4305,3.572,4306,3.725,4307,3.058,4308,3.349,4309,3.725,4310,3.572,4311,3.349,4312,3.119]],["t/897",[1,3.114,38,3.487,77,5.232,83,2.318,95,3.589,117,1.287,151,5.272,156,2.852,229,3.238,259,1.791,287,3.176,414,3.183,433,6.008,576,3.068,1062,4.3,1208,4.34,1213,5.313,1799,5.272,1841,3.487,1961,4.611,2674,5.048,2992,8.002]],["t/899",[1,2.961,22,2.497,30,1.343,83,1.296,117,0.719,137,2.679,138,2.838,166,3.295,187,2.125,194,4.013,208,3.392,210,2.171,221,3.135,267,1.607,271,3.388,285,4.107,297,3.122,473,1.93,578,3.615,624,3.276,646,4.565,647,3.828,648,3.488,649,2.88,660,2.808,665,4.017,734,3.562,737,2.985,775,3.108,802,2.27,817,4.922,912,3.088,964,3.671,971,3.488,980,2.855,998,1.925,1011,3.419,1030,3.419,1071,3.419,1177,2.177,1208,2.999,1277,3.465,1397,4.733,1412,5.184,1449,3.295,1521,3.731,1530,3.828,1678,3.295,2033,4.43,2055,4.43,2060,3.315,2138,4.569,2210,4.733,2316,2.957,2506,4.308,2581,4.762,2703,4.308,2881,4.611,2899,3.589,3797,3.828,4313,4.569,4314,4.648,4315,7.658,4316,5.529,4317,4.932,4318,4.827,4319,7.485,4320,4.497,4321,5.529,4322,4.569]],["t/901",[1,2.926,7,2.501,72,2.358,80,3.555,83,2.364,85,2.037,86,2.19,94,2.429,116,3.339,117,1.075,139,2.118,153,4.062,177,3.292,183,3.803,187,2.333,206,5.364,208,3.529,217,4.03,250,2.886,263,3.049,271,2.653,607,2.689,626,2.759,659,2.768,775,2.871,781,1.822,786,3.855,869,4.062,887,4.456,912,5.248,993,4.3,998,2.113,1013,3.406,1024,3.261,1097,2.951,1205,3.276,1231,3.497,1455,5.577,1791,3.596,1987,4.13,2171,3.069,2388,4.862,2570,5.25,2581,5.078,2881,2.886,2913,5.298,3502,4.24,4100,4.611,4323,6.328,4324,6.328,4325,6.44,4326,6.328,4327,5.015]],["t/903",[1,1.312,17,1.028,30,2.4,33,3.441,38,0.857,41,1.052,44,2.025,73,1.908,77,2.232,83,2.344,84,1.172,96,1.595,117,0.796,123,0.718,138,0.72,150,2.234,156,1.764,157,3.118,169,1.843,172,0.937,173,1.46,175,1.115,186,0.945,187,0.756,201,2.763,214,1.414,219,1.337,241,1.258,243,1.051,245,3.122,259,0.44,263,2.657,267,0.572,414,1.456,437,1.967,462,1.338,463,0.796,486,1.047,488,3.325,490,2.637,555,3.576,562,1.654,576,1.309,597,1.562,611,2.252,612,0.681,615,1.483,619,2.442,621,0.681,624,2.023,646,2.011,649,1.024,659,0.897,666,0.963,671,2,712,4.26,723,3.254,732,0.735,739,1.414,748,0.894,753,3.75,786,2.169,814,0.787,832,2.139,834,0.871,837,1.532,875,0.752,923,0.613,937,1.575,942,1.179,953,1.011,957,0.885,964,1.306,969,1.165,971,1.24,978,1.279,980,1.763,994,1.428,1004,3.928,1009,2.585,1021,1.35,1036,1.276,1097,0.956,1162,1.35,1187,1.121,1204,0.953,1300,1.444,1331,3.45,1431,1.093,1440,1.553,1443,0.982,1446,3.254,1460,4.934,1465,1.826,1489,1.224,1490,1.625,1559,1.796,1596,2.941,1644,1.717,1712,1.267,1722,1.077,1727,0.829,1753,2.011,1776,4.147,1777,1.512,1830,1.258,1841,2.355,1878,1.428,1904,2.047,1946,1.754,1974,1.186,2018,1.158,2062,2.346,2154,2.78,2157,4.216,2230,1.042,2260,2.851,2271,1.145,2275,1.024,2305,1.276,2391,1.575,2581,5.105,2673,1.414,2674,2.154,2693,4.542,2751,3.161,2768,1.717,2770,1.741,2785,1.754,2819,1.683,2861,4.923,2872,1.46,2881,3.425,2892,1.717,2893,1.754,2918,2.87,2940,1.683,2965,3.053,2975,4.385,3030,5.407,3078,2.455,3102,1.599,3135,2.821,3220,1.653,3318,2.455,3511,1.216,3659,2.936,3810,4.86,3893,1.754,4270,3.456,4315,1.683,4325,1.532,4328,10.162,4329,2.05,4330,2.05,4331,2.05,4332,1.843,4333,5.634,4334,4.37,4335,3.298,4336,1.428,4337,1.843,4338,4.718,4339,4.132,4340,2.05,4341,1.532,4342,2.05,4343,3.298,4344,3.201,4345,1.966,4346,2.05,4347,2.05,4348,2.05,4349,1.899,4350,1.387,4351,2.05,4352,1.966,4353,2.05,4354,2.05,4355,1.843,4356,2.05,4357,2.05,4358,1.717,4359,2.05,4360,1.754,4361,2.05,4362,2.05,4363,2.05,4364,2.05,4365,2.05,4366,2.05,4367,3.56,4368,3.56,4369,2.05,4370,2.05,4371,1.966]],["t/905",[1,2.698,30,1.325,44,0.729,71,2.659,72,2.626,79,4.562,80,3.96,81,5.425,83,2.179,84,3.252,86,1.248,96,1.615,97,1.266,117,0.999,123,1.263,129,3.457,130,3.457,134,3.241,139,1.905,144,3.653,145,2.314,146,2.152,148,1.046,151,2.278,156,1.949,160,4.549,164,1.675,169,1.866,170,2.212,173,2.566,175,3.834,177,1.875,183,3.42,187,1.329,194,2.448,210,3.015,224,1.992,226,1.911,238,4.64,243,1.679,255,2.486,263,2.013,267,2.232,271,2.386,285,2.893,297,1.905,339,1.858,401,2.085,419,1.875,436,4.862,443,2.716,470,1.257,473,1.207,490,1.688,501,2.512,510,1.198,525,2.037,528,1.971,529,1.436,538,2.055,576,2.092,598,1.902,615,1.502,622,2.166,645,1.701,649,2.842,668,1.531,678,2.196,737,1.866,744,2.181,748,1.571,770,3.443,781,2.03,814,1.384,867,1.999,911,2.659,912,1.931,978,2.044,1009,1.461,1021,2.373,1024,1.858,1028,1.992,1049,3.713,1090,2.037,1170,1.748,1205,1.866,1247,3.241,1312,2.566,1341,3.018,1355,2.538,1402,2.462,1404,2.627,1457,2.373,1596,1.516,1618,1.638,1643,2.731,1717,2.538,1722,1.893,1841,1.507,1904,2.073,1958,2.227,1985,2.812,1988,1.502,2074,2.486,2157,1.824,2181,2.731,2230,2.893,2363,2.659,2451,2.731,2506,2.694,2518,2.333,2569,3.084,2581,2.124,2587,4.51,2608,2.659,2768,3.018,2881,1.644,2885,2.959,2886,3.157,2887,3.157,2892,3.018,2893,6.03,2923,2.627,2931,3.157,2934,2.353,2973,2.596,2975,2.261,3102,2.812,3481,3.157,3486,3.457,3516,6.245,4372,3.605,4373,3.605,4374,3.605,4375,3.241,4376,3.241,4377,3.339,4378,3.605,4379,3.457,4380,3.457,4381,3.339,4382,3.605,4383,3.339,4384,3.605,4385,3.605,4386,3.241,4387,3.605,4388,3.605,4389,3.605,4390,3.605,4391,3.241,4392,3.605,4393,3.241]],["t/907",[1,2.777,5,1.6,7,1.906,44,1.328,77,4.117,91,3.447,115,2.577,117,0.819,123,2.3,144,4.214,148,1.906,166,5.049,175,4.804,222,4.248,240,1.696,259,1.409,267,2.462,411,1.729,438,3.589,445,4.056,465,5.389,495,3.133,497,4.783,529,2.614,579,2.761,660,3.197,668,2.787,670,3.337,697,3.516,737,3.399,748,2.862,781,1.89,875,2.407,969,3.73,985,2.239,1014,3.516,1024,3.383,1273,2.921,1281,4.086,1618,2.983,1801,3.919,1942,6.572,1943,4.359,2074,4.527,2152,4.148,2254,4.321,2377,5.749,2396,4.399,2581,3.869,2662,4.214,2881,4.029,3516,5.12,4386,5.902,4394,5.615,4395,6.081,4396,6.081,4397,5.749,4398,6.564,4399,4.148,4400,5.615,4401,6.564]],["t/909",[1,1.71,3,2.27,12,1.076,30,1.83,33,2.296,34,2.094,35,2.029,38,1.229,40,1.756,44,0.595,47,1.203,48,1.3,72,1.096,79,1.904,80,1.653,83,2.094,85,0.947,94,1.129,106,1.626,113,1.953,114,3.366,117,0.767,123,1.031,124,1.99,148,0.854,156,1.336,165,1.445,175,2.627,208,2.062,210,3.634,219,1.105,222,1.904,224,1.626,229,1.142,240,0.76,242,1.681,243,0.868,250,2.203,263,1.041,271,3.295,276,1.626,285,3.995,291,1.873,298,3.402,339,1.516,391,0.955,403,2.228,412,1.142,414,0.908,420,3.798,423,1.888,470,1.026,488,1.129,491,2.353,492,2.764,511,1.523,520,1.734,529,2.834,530,2.413,535,1.888,555,1.214,562,2.244,576,1.082,584,1.552,612,1.606,613,1.672,615,1.226,618,1.831,619,1.523,649,2.413,659,1.287,660,1.433,693,1.953,694,2.684,710,3.829,720,3.659,737,1.523,770,1.78,775,2.618,785,1.723,794,2.415,814,1.854,820,1.196,834,2.61,875,1.771,879,1.936,890,1.552,923,0.879,957,2.085,973,2.295,978,1.057,1008,1.388,1009,1.192,1036,1.831,1062,2.489,1064,2.071,1085,4.045,1177,1.824,1187,1.608,1195,1.971,1200,1.78,1208,1.53,1211,1.41,1219,4.475,1245,1.99,1248,1.904,1265,2.143,1278,1.768,1399,1.634,1411,2.576,1440,2.228,1443,1.41,1453,4.343,1489,1.756,1518,2.17,1607,1.332,1617,1.99,1640,1.495,1644,2.463,1678,2.761,1715,1.357,1717,2.071,1722,1.545,1751,1.92,1762,2.821,1776,1.745,1777,2.17,1788,1.904,1807,4.319,1825,1.953,1878,2.05,1904,2.778,1914,1.672,1923,1.953,1948,1.888,1953,2.094,1961,1.626,2010,2.094,2027,2.143,2118,1.845,2157,1.489,2186,2.009,2220,2.371,2230,2.456,2260,1.489,2295,3.007,2304,1.495,2313,1.936,2331,2.05,2356,5.162,2415,4.856,2608,2.17,2649,2.371,2674,3.719,2751,1.971,2815,1.845,2881,1.342,2965,3.126,2975,1.845,3005,2.331,3030,2.118,3032,2.029,3087,2.645,3104,2.17,3469,3.894,3770,2.415,3810,3.126,3931,2.118,4100,2.143,4170,2.071,4327,5.639,4393,2.645,4399,4.496,4402,2.942,4403,2.942,4404,5.797,4405,2.942,4406,2.645,4407,2.942,4408,2.942,4409,2.645,4410,2.645,4411,2.228,4412,5.526,4413,2.576,4414,2.942,4415,2.821,4416,2.645,4417,2.516,4418,2.942,4419,2.516,4420,2.645,4421,2.645,4422,2.645,4423,2.942]],["t/911",[1,2.45,5,1.593,6,3.781,7,1.252,22,1.867,26,3.828,38,1.802,39,2.944,44,0.872,83,1.979,85,1.388,90,2.732,94,1.655,117,0.815,186,1.988,208,1.447,210,1.624,229,1.674,259,1.403,263,2.313,271,2.74,338,3.612,412,2.537,420,2.664,470,1.503,473,2.642,510,2.172,514,3.736,530,2.154,576,2.403,579,1.813,612,1.433,619,3.384,649,3.264,760,2.37,770,2.609,771,3.476,775,2.177,787,2.058,809,1.598,814,3.381,834,2.775,837,3.222,878,4.822,879,4.302,912,2.309,978,2.835,987,1.753,1016,5.876,1024,2.222,1049,2.814,1072,2.479,1081,3.476,1090,2.436,1115,2.889,1167,3.877,1177,1.628,1180,2.704,1193,4.135,1486,3.476,1672,3.363,1727,1.743,1778,2.309,1807,2.37,1825,2.863,1841,2.732,1846,2.974,1904,2.479,1915,3.54,2018,3.693,2021,6.074,2027,3.142,2033,3.313,2118,2.704,2138,3.417,2157,2.182,2161,3.476,2206,3.61,2223,3.105,2230,2.192,2261,3.363,2284,3.54,2295,4.913,2305,2.684,2356,4.566,2415,4.877,2451,3.266,2570,2.627,2881,4.317,2975,2.704,3609,3.363,3810,2.79,4170,3.036,4312,3.61,4325,4.884,4399,4.988,4424,3.776,4425,3.61,4426,3.994,4427,4.312,4428,9.466,4429,3.476,4430,3.877,4431,4.312,4432,4.312,4433,4.312,4434,4.312,4435,4.312,4436,4.312,4437,4.312,4438,4.312,4439,3.688]],["t/913",[1,0.552,7,1.599,17,0.995,26,1.162,30,0.806,33,2.334,38,2.302,44,2.425,47,0.812,48,0.877,72,1.289,77,2.17,80,1.115,83,1.034,84,1.134,87,0.774,96,2.061,97,1.215,114,2.411,115,1.358,117,0.432,124,2.34,148,1.335,150,1.638,156,0.549,169,1.791,170,2.123,172,1.645,173,1.413,175,2.995,196,0.675,199,1.397,208,1.161,210,0.747,214,0.788,240,0.513,250,0.905,263,2.904,267,0.964,271,1.929,285,1.009,291,5.794,335,5.633,350,2.258,412,0.77,420,2.138,470,0.692,483,0.859,488,0.762,510,1.15,555,0.819,557,0.835,562,0.922,565,1.318,575,0.925,576,0.73,579,0.835,612,1.15,613,1.128,615,0.827,617,2.079,619,1.027,621,0.659,649,0.991,659,2.012,663,1.706,670,1.759,671,1.115,705,1.629,710,1.573,712,1.209,719,1.004,720,4.172,722,1.525,723,2.386,748,1.508,770,3.333,775,2.286,781,0.571,787,0.947,802,0.781,814,2.114,820,1.87,830,1.318,834,2.339,837,1.483,882,1.141,886,1.254,906,1.966,923,0.593,957,0.856,959,1.573,969,1.128,978,1.243,1009,2.533,1019,1.826,1028,1.096,1052,5.98,1075,1.306,1090,1.121,1204,2.559,1208,1.032,1273,0.883,1278,1.192,1404,1.446,1446,1.368,1460,3.03,1465,1.018,1471,1.121,1473,2.491,1483,4.399,1530,1.318,1565,1.483,1596,0.835,1672,1.548,1698,2.386,1773,2.822,1776,4.07,1777,2.552,1788,3.565,1790,1.027,1807,1.091,1841,0.829,1848,1.738,1874,1.318,1896,1.274,1904,1.141,1974,1.148,2004,1.903,2019,1.573,2026,1.661,2043,1.525,2062,0.987,2157,2.328,2232,1.503,2240,1.413,2288,1.254,2295,2.153,2327,1.629,2328,2.491,2356,4.269,2391,2.658,2415,2.843,2440,0.974,2468,1.209,2519,1.446,2634,6.663,2674,2.093,2751,3.691,2861,6.015,2872,1.413,2923,1.446,2973,1.429,2974,1.838,2975,2.885,3041,1.661,3058,1.599,3102,2.699,3366,2.277,3596,1.838,3659,1.235,3701,2.239,3768,1.738,3810,3.565,3918,2.34,3931,1.429,4169,1.244,4322,1.573,4360,1.697,4399,3.948,4404,2.552,4409,1.784,4410,1.784,4411,4.733,4412,3.111,4413,4.029,4440,1.599,4441,1.573,4442,3.318,4443,3.352,4444,1.984,4445,1.984,4446,1.984,4447,1.984,4448,4.261,4449,1.738,4450,5.508,4451,1.984,4452,5.472,4453,1.984,4454,7.824,4455,1.984,4456,1.984,4457,6.133,4458,1.984,4459,7.38,4460,1.984,4461,1.984,4462,1.984,4463,1.984,4464,1.984,4465,1.984,4466,3.46,4467,4.6,4468,3.111,4469,1.984,4470,1.984,4471,2.658,4472,1.503,4473,1.738,4474,1.984,4475,1.984,4476,1.525,4477,1.784,4478,1.784,4479,1.429,4480,1.903,4481,3.852,4482,1.984,4483,1.784,4484,1.483,4485,1.784,4486,3.852,4487,1.784,4488,1.984,4489,3.46,4490,1.984,4491,1.984,4492,1.984,4493,1.984]],["t/915",[7,2.174,22,2.244,28,2.945,38,3.13,85,1.668,114,3.611,169,2.683,194,2.23,208,2.513,211,4.052,241,3.18,249,2.722,268,3.442,297,1.735,298,3.65,470,2.611,473,1.735,510,1.723,529,2.983,576,1.906,612,1.723,615,2.159,659,4.214,660,4.283,734,3.203,759,5.035,770,3.136,775,1.727,830,3.442,867,1.82,906,2.945,955,2.494,957,2.237,966,4.433,978,1.862,1014,2.776,1091,3.301,1181,2.998,1204,2.408,1211,3.589,1239,3.412,1253,3.016,1283,3.301,1308,2.98,1477,5.183,1483,3.65,1530,4.974,1678,2.962,1698,3.574,1749,3.412,1776,5.714,1807,2.849,1870,4.66,2230,3.807,2232,5.674,2240,5.332,2295,6.63,2305,5.474,2317,4.433,2478,3.157,2723,3.035,2899,4.662,2973,6.333,2999,4.043,3366,4.93,3918,3.505,4399,3.275,4404,5.526,4443,5.458,4481,6.271,4483,4.66,4486,6.271,4494,5.183,4495,6.734,4496,4.66,4497,5.183,4498,5.183]],["t/917",[12,2.279,26,3.65,30,2.264,38,2.605,83,1.4,94,2.392,114,4.342,117,0.778,139,2.854,165,4.187,194,3.668,210,3.211,211,2.621,221,3.389,224,3.444,229,2.419,271,2.613,276,3.444,285,4.335,402,4.295,469,4.033,473,2.086,514,3.562,659,3.73,660,3.035,737,3.226,770,3.771,775,2.841,867,2.995,886,3.938,978,2.239,1014,3.338,1028,3.444,1030,3.696,1200,3.771,1211,2.986,1355,4.388,1443,2.986,1535,5.116,1807,3.425,2118,3.908,2181,4.721,2230,3.168,2295,3.879,2316,3.197,2581,3.673,2881,2.843,2973,4.488,3103,4.861,3797,4.138,3918,4.215,4399,5.388,4443,4.541,4481,5.218,4485,5.603,4486,7.14,4487,7.667,4495,5.603,4499,6.232,4500,6.232,4501,6.232,4502,4.657,4503,4.789,4504,5.977]],["t/920",[12,2.871,36,3.443,72,2.061,73,1.874,85,2.526,90,2.312,117,1.238,123,1.938,136,2.812,137,2.57,138,1.943,169,2.864,172,1.457,229,2.147,240,1.429,245,2.47,267,2.188,271,2.319,473,1.852,505,3.37,529,3.126,562,2.57,612,2.608,614,3.181,621,2.608,654,2.551,723,3.815,760,3.041,764,2.672,781,2.26,820,3.191,867,1.943,875,2.878,890,2.919,966,4.732,1036,3.443,1051,5.125,1056,3.674,1062,4.044,1115,3.707,1200,3.347,1283,3.523,1373,7.008,1473,8.062,1521,3.58,1530,6.057,1640,2.812,1678,3.162,1844,3.855,1976,3.144,2021,3.815,2145,3.551,2230,4.636,2234,4.384,2271,3.091,2288,3.496,2356,3.2,2581,3.26,2881,2.523,3246,5.125,3463,7.488,4399,4.959,4440,6.327,4443,4.031,4472,4.191,4477,4.974,4478,4.974,4505,5.532,4506,4.542,4507,7.848,4508,5.532,4509,4.845,4510,4.081,4511,5.306]],["t/922",[1,1.406,22,2.189,30,2.02,38,2.113,49,4.324,83,1.653,84,2.889,85,1.627,115,1.984,117,0.631,123,1.771,137,3.418,138,1.775,148,3.164,150,5.001,156,2.034,172,1.331,175,2.749,187,1.864,190,2.84,193,2.119,195,3.729,196,3.593,197,2.681,199,3.56,200,3.683,206,3.147,214,2.007,236,3.56,240,1.306,473,1.692,504,3.147,529,2.013,530,2.525,586,2.581,612,1.68,628,4.683,630,3.147,659,2.211,660,2.462,764,2.442,781,1.455,809,1.873,881,3.452,955,2.432,957,2.182,978,1.816,1015,2.84,1115,4.929,1162,3.327,1175,3.778,1177,2.777,1211,2.422,1332,2.809,1471,2.856,1480,3.219,1596,2.126,1736,4.683,1819,3.101,1923,3.357,1943,3.357,1948,3.245,1990,4.324,2239,3.56,2271,2.824,2295,5.397,2466,4.006,2468,4.481,2649,4.075,2662,3.245,3058,4.075,3469,5.93,3770,4.15,3918,5.865,4399,5.479,4420,4.545,4421,4.545,4422,4.545,4440,4.075,4512,5.055,4513,5.055,4514,5.055,4515,4.848,4516,3.943,4517,7.796,4518,5.055,4519,4.848,4520,5.055,4521,5.055,4522,5.055,4523,5.055,4524,5.055]],["t/924",[138,3.528,285,5.106,4406,9.032,4525,10.045]],["t/926",[5,1.653,44,2.053,72,3.363,77,4.253,79,6.568,80,6.509,87,2.647,88,3.578,115,2.662,148,1.969,240,1.752,267,1.89,291,4.319,437,3.747,584,3.578,620,3.544,748,2.956,820,4.126,906,5.13,1281,4.221,1988,2.825,2388,5.21,2674,4.103,2861,4.775,3086,5.374,3366,5.942,4479,7.791,4484,5.068,4526,6.781,4527,6.781,4528,6.781,4529,10.148,4530,6.781,4531,6.097,4532,6.781,4533,6.781,4534,5.678,4535,6.781,4536,6.097,4537,6.781,4538,6.781,4539,6.781,4540,6.781,4541,6.781]],["t/928",[44,2.019,72,2.949,79,5.122,80,6.14,115,3.107,148,2.298,267,2.206,525,4.472,719,4.005,781,2.279,820,4.666,906,5.671,1003,5.919,1273,3.522,1925,6.627,2062,3.936,2260,4.005,2284,6.498,3366,6.568,4484,5.915,4542,8.727,4543,7.915,4544,9.979]],["t/930",[73,2.905,138,3.012,267,2.391,271,3.596,470,2.99,491,4.177,510,2.85,660,4.177,759,4.482,802,3.376,906,4.874,957,3.701,1530,5.695,1618,3.898,1788,5.55,2295,5.338,2723,5.022,2905,6.914,3516,6.689,3873,6.327,3918,5.801,4399,5.419,4443,6.249,4479,6.175,4542,6.327]],["t/932",[1,1.625,5,0.527,7,1.696,27,2.7,30,0.504,34,1.539,38,0.904,39,1.476,44,1.792,48,0.955,51,1.236,72,0.805,73,0.732,79,2.412,80,4.047,85,0.696,87,0.844,88,1.141,95,0.93,115,0.849,117,0.822,126,0.962,138,2.052,139,0.724,148,1.696,150,1.024,152,1.893,153,1.388,156,1.031,160,1.228,172,2.147,174,3.452,187,1.811,194,1.603,198,2.094,201,1.266,202,1.743,206,1.346,210,1.403,213,1.062,214,0.858,218,1.48,219,1.4,229,0.839,236,1.522,238,1.423,240,0.559,243,1.1,245,1.664,248,1.336,250,2.241,259,1.254,262,1.146,263,1.319,267,1.369,285,1.894,291,1.377,297,1.644,338,2.059,402,0.955,421,1.593,436,1.491,437,1.195,443,2.345,452,1.104,470,2.036,481,2.597,488,0.83,492,2.963,495,1.032,514,1.236,529,1.484,530,1.08,532,1.522,560,1.075,562,2.282,565,1.436,576,1.37,582,1.356,584,1.141,586,1.104,602,1.539,612,1.239,613,1.228,614,1.243,620,1.948,636,2.182,649,1.861,660,1.815,666,1.016,668,1.583,671,1.215,688,1.743,748,1.625,753,1.02,769,2.475,781,1.073,794,4.033,802,2.594,820,2.375,821,1.686,822,1.7,861,1.476,867,0.759,875,1.801,886,1.366,890,1.141,895,1.346,906,2.118,908,3.03,923,0.646,942,2.143,953,1.838,967,1.539,969,1.228,991,1.08,993,2.563,1003,1.282,1009,1.991,1010,1.713,1019,1.141,1024,1.114,1027,1.539,1028,1.195,1030,1.282,1033,1.243,1049,1.411,1062,1.114,1149,3.12,1156,1.638,1169,2.453,1170,1.049,1172,2.073,1177,1.407,1187,2.686,1208,1.124,1211,1.036,1214,1.282,1231,2.059,1253,1.258,1271,2.225,1273,0.962,1279,1.411,1281,1.346,1327,1.377,1344,1.366,1417,1.462,1425,2.003,1431,1.152,1443,1.036,1449,1.236,1475,1.595,1476,1.944,1489,3.933,1552,3.537,1566,1.849,1599,1.751,1606,1.944,1613,1.686,1618,0.982,1629,1.539,1647,1.436,1701,1.686,1727,0.874,1778,1.158,1791,1.228,1807,1.188,1921,2.432,1935,1.661,1957,2.716,1967,2.791,1976,4.847,1984,2.954,1988,0.901,1989,1.423,2021,2.57,2032,1.228,2055,1.661,2074,2.57,2075,1.236,2218,1.893,2220,1.743,2230,1.099,2254,1.423,2271,2.082,2295,1.346,2298,1.661,2300,1.377,2304,1.894,2309,2.073,2313,2.453,2416,1.638,2468,1.317,2478,1.317,2569,3.188,2599,2.073,2813,2.716,2861,1.522,2903,4.256,2926,1.893,3028,1.506,3086,1.713,3104,3.624,3154,1.713,3249,1.893,3318,1.491,3366,2.453,3516,2.907,3847,2.003,4080,1.944,4270,5.233,4308,1.944,4339,1.893,4350,2.521,4416,1.944,4468,1.944,4479,1.557,4484,1.616,4503,1.661,4531,1.944,4534,1.81,4542,1.595,4545,2.162,4546,2.162,4547,2.162,4548,2.162,4549,2.162,4550,2.162,4551,2.162,4552,1.944,4553,2.162,4554,2.162,4555,2.162,4556,2.162,4557,2.162,4558,3.727,4559,2.162,4560,2.162,4561,1.944,4562,2.162,4563,3.727,4564,2.162,4565,2.162,4566,2.162,4567,2.162,4568,2.162,4569,2.162,4570,2.162,4571,1.944,4572,2.162,4573,3.188,4574,1.893,4575,2.162,4576,1.944,4577,2.162,4578,2.162,4579,2.073,4580,2.162,4581,2.162,4582,6.589,4583,2.162,4584,1.686,4585,2.073,4586,3.574,4587,1.893,4588,2.003,4589,3.574,4590,3.574,4591,3.727,4592,2.162,4593,1.522,4594,2.073,4595,2.162,4596,2.162,4597,2.162,4598,2.162,4599,2.162,4600,1.25]],["t/934",[7,1.122,27,3.303,30,0.9,44,2.227,48,3.258,72,3.098,73,1.309,79,5.83,80,6.438,86,1.338,87,2.878,117,0.92,141,2.639,145,2.481,148,2.14,155,2.249,156,1.069,160,4.19,172,1.583,194,1.663,201,2.263,240,0.999,243,1.774,249,2.03,250,1.763,285,1.965,436,4.145,437,2.136,443,1.845,470,3.141,489,1.467,491,3.591,576,1.421,612,1.285,620,3.853,621,1.997,722,5.665,737,2.001,781,1.73,812,2.722,820,1.571,904,3.475,906,4.726,908,1.626,993,2.637,1003,2.292,1007,3.236,1009,1.567,1347,5.439,1417,2.614,1431,2.06,1449,2.209,1471,2.184,1547,2.307,1591,3.116,1599,1.816,1607,2.721,1617,2.614,1799,2.442,1949,3.769,1961,2.136,1967,2.196,1976,2.196,1984,3.063,1988,1.61,2075,2.209,2154,2.278,2254,2.544,2396,2.59,2557,3.015,2813,2.816,2932,3.58,3082,2.501,3102,5.751,3126,3.173,3366,4.853,3493,3.707,4270,5.851,4479,6.487,4536,5.403,4542,7.036,4552,8.1,4561,3.475,4571,3.475,4574,3.385,4576,3.475,4601,3.865,4602,3.865,4603,3.865,4604,3.865,4605,3.865,4606,7.373,4607,3.865,4608,3.865,4609,3.865,4610,6.01,4611,5.763,4612,3.865,4613,3.865,4614,3.306,4615,5.763,4616,3.58,4617,3.865,4618,3.865,4619,3.865,4620,3.865,4621,3.865,4622,3.58]],["t/936",[115,3.463,142,6.778,172,2.323,249,4.633,461,5.166,463,3.424,491,4.296,538,3.185,802,3.473,817,5.374,969,5.013,978,3.169,1449,5.043,1599,4.146,1732,5.103,1735,6.428,2440,4.332,2581,5.199,2881,4.024,3078,6.084,4303,7.932]],["t/938",[22,3.427,48,3.497,72,2.949,83,1.779,94,3.83,128,4.136,138,2.78,221,4.304,240,2.045,249,4.156,271,3.318,285,4.023,391,2.571,861,5.405,870,5.405,1015,4.446,1151,5.165,1178,6.77,1273,3.522,1629,5.635,1790,4.098,1844,5.515,1988,4.158,2223,5.699,2260,5.05,2298,6.081,3037,5.256,4270,4.856,4336,5.515,4337,7.116,4623,7.915,4624,7.915,4625,7.915,4626,7.915]],["t/940",[83,1.968,85,2.819,138,3.076,271,3.672,285,4.453,491,4.266,520,5.162,645,4.132,694,4.867,759,4.578,868,4.894,906,4.978,908,3.684,978,3.147,1069,5.13,1776,5.195,1871,6.462,1988,3.649,2295,5.452,2723,5.13,3657,6.635,3918,5.924]],["t/942",[43,2.685,115,2.662,142,5.21,144,4.353,148,2.946,150,3.211,172,1.786,187,2.5,193,3.785,197,3.596,265,4.19,267,1.89,412,2.632,483,2.936,529,2.701,620,3.544,659,2.966,668,2.88,787,3.237,802,3.995,820,2.757,834,2.88,978,3.887,1015,3.81,1024,4.652,1030,4.022,1033,6.221,1066,3.81,1132,5.21,1162,4.464,1177,2.56,1449,3.876,1715,3.127,1807,3.727,2055,5.21,2468,4.131,2478,4.131,3058,5.467,3236,4.883,4270,4.16,4317,5.801,4479,4.883,4484,5.068,4516,5.289,4517,6.097,4573,7.722,4627,5.467,4628,6.781,4629,6.282,4630,5.567]],["t/945",[1,2.306,138,2.911,178,4.555,193,3.475,197,4.395,245,3.7,298,5.836,491,4.036,562,4.772,666,3.895,867,2.911,923,2.477,1904,4.765,1974,4.794,1976,4.709,2318,6.681,2570,5.049,2581,6.052,2881,4.684,2965,5.364,3078,5.716,3284,7.948,4399,5.237,4404,6.114,4449,7.258,4584,8.011]],["t/947",[1,1.516,6,3.153,7,0.991,12,1.249,17,1.713,22,1.479,30,0.795,33,1.276,38,2.278,42,4.252,73,1.846,77,2.141,83,1.225,85,1.099,90,1.427,91,1.793,114,2.379,117,0.969,138,1.914,139,1.824,148,0.991,150,3.678,155,1.987,156,1.507,165,1.677,187,2.009,194,2.926,205,4.394,211,1.436,216,2.025,221,3.7,240,0.882,242,1.952,245,1.525,249,2.862,267,0.952,271,1.432,298,2.405,402,4.195,412,1.325,414,1.054,473,1.824,474,2.285,491,1.663,492,1.535,510,1.135,529,2.171,562,3.161,565,2.268,576,1.256,584,1.802,594,2.379,613,1.941,615,1.423,619,2.822,621,1.135,649,1.706,659,3.712,670,2.771,697,1.829,734,4.799,737,1.768,753,1.611,760,1.877,763,2.459,770,2.066,775,2.827,785,2,802,1.344,978,2.444,1004,4.363,1009,1.384,1033,1.963,1037,2.355,1049,2.229,1066,1.918,1071,2.025,1072,1.963,1097,2.542,1143,2.753,1174,2.706,1177,1.289,1199,2.921,1200,2.066,1211,2.612,1231,1.887,1260,2.431,1386,2.379,1431,1.82,1473,2.459,1477,3.212,1483,4.79,1489,2.039,1521,2.21,1535,2.803,1629,2.431,1685,2.706,1698,4.692,1717,2.405,1727,1.38,1735,2.488,1755,3.07,1791,1.941,1807,1.877,1871,2.519,1904,3.134,1948,4.985,1974,1.975,2062,2.711,2145,2.192,2151,2.859,2157,2.759,2171,1.656,2230,2.771,2260,1.728,2295,3.393,2305,2.126,2328,2.459,2380,2.89,2395,3.163,2496,2.552,2881,4.497,2923,2.488,2965,3.528,2973,4.899,2975,3.418,3078,2.355,3128,2.803,3266,6.524,3659,2.126,3741,2.431,4322,2.706,4341,2.552,4358,2.859,4399,4.299,4404,4.021,4439,2.921,4443,2.488,4452,2.991,4471,2.624,4584,2.664,4631,2.859,4632,3.07,4633,3.415,4634,5.451,4635,3.415,4636,3.415,4637,3.415,4638,3.415,4639,3.415,4640,3.415,4641,5.451,4642,3.415,4643,3.415,4644,3.415,4645,3.415,4646,3.415]],["t/949",[1,2.116,4,2.517,6,4.4,21,1.731,26,4.454,30,1.233,83,1.19,87,2.066,90,3.72,117,0.949,126,2.356,151,3.345,156,1.464,161,4.904,172,2.003,221,2.879,229,2.055,235,2.894,240,1.368,245,2.364,259,1.136,267,2.481,271,2.22,285,2.691,427,2.974,470,1.846,473,2.546,508,5.006,612,1.76,615,2.206,624,3.009,649,3.799,659,2.316,742,3.581,770,5.386,787,2.527,809,1.962,814,2.919,911,3.906,978,3.702,993,3.906,1011,3.14,1014,2.835,1041,4.637,1072,3.044,1097,2.469,1099,4.01,1231,2.926,1239,3.485,1331,2.433,1415,4.068,1449,3.026,1717,3.728,1723,3.426,1760,4.637,1783,4.529,1791,3.009,1807,2.91,1825,3.516,1838,3.516,1974,3.062,1976,3.009,1988,2.206,2032,3.009,2121,3.689,2157,2.679,2179,4.13,2230,3.866,2232,4.01,2316,4.566,2415,3.271,2570,3.225,2619,2.91,2624,4.76,2812,4.196,2815,3.32,2881,2.415,2888,4.76,2934,3.455,2975,3.32,3662,3.858,3931,3.812,4391,4.76,4430,4.76,4632,6.838,4647,5.294,4648,4.76,4649,5.294,4650,5.585]],["t/954",[1,1.887,3,3.187,5,2.201,12,3.302,16,4.319,17,3.402,51,3.876,83,2.604,117,1.266,126,3.017,139,2.27,180,2.48,196,3.072,209,3.139,219,2.547,240,1.752,250,3.093,338,3.747,391,2.203,411,2.377,414,2.093,519,6.781,524,5.995,527,2.567,597,3.962,610,3.831,612,2.254,618,4.221,891,3.768,1187,3.707,1272,5.289,1584,5.068,1808,7.411,2186,6.165,2192,6.89,2944,7.155,3048,7.153,4276,5.939,4651,7.153,4652,7.718,4653,7.718,4654,7.718,4655,9.523]],["t/956",[1,1.544,5,1.683,7,2.283,12,1.277,15,1.996,16,2.224,17,1.752,24,3.1,33,3.413,83,2.053,90,2.886,91,1.834,115,1.371,122,3.654,139,1.169,165,1.715,168,2.621,172,1.461,210,2.962,213,2.725,214,1.387,219,1.312,240,2.032,262,1.852,391,1.134,398,1.464,401,3.994,411,2.763,414,1.078,419,1.817,421,1.493,452,1.783,457,3.526,461,2.045,463,2.154,469,2.26,473,1.169,482,3.429,501,2.433,525,1.973,534,2.924,545,2.645,560,4.764,571,1.962,575,1.629,600,3.718,607,1.731,629,1.973,634,2.34,636,2.045,744,2.113,753,1.647,775,1.163,781,1.988,809,2.559,816,3.208,820,1.42,875,2.035,980,2.748,985,2.355,998,1.853,1009,3.188,1055,2.961,1085,2.924,1104,2.724,1120,5.303,1169,2.299,1177,1.319,1178,2.987,1273,3.5,1327,2.224,1403,2.61,1418,1.611,1439,3.827,1443,3.309,1577,2.409,1582,2.924,1623,3.14,1668,6.801,1711,2.242,1712,2.158,1732,3.21,1895,2.724,1954,2.058,1976,1.985,2136,3.14,2144,6.618,2145,2.242,2148,4.86,2171,1.694,2185,2.768,2353,2.099,2581,4.069,2769,2.768,2789,2.576,2853,2.033,2928,4.203,3037,2.319,3511,2.071,3536,3.235,3595,2.515,3665,3.718,3671,2.409,3705,3.059,4263,6.905,4264,8.976,4276,3.059,4285,4.203,4656,8.23,4657,3.349,4658,3.975,4659,3.975,4660,3.975,4661,3.684,4662,2.987,4663,3.492,4664,3.975]],["t/970",[83,2.011,118,4.571,126,3.982,235,4.893,521,4.395,544,5.116,557,3.764,598,5.68,796,4.868,912,4.793,1130,7.839,1319,9.441,1528,6.78,1936,7.839,3505,7.348,4665,10.186,4666,10.186]],["t/977",[3,2.339,5,1.213,7,1.445,10,2.061,12,1.116,16,4.014,24,2.781,31,2.28,33,3.386,73,1.033,75,3.867,76,1.686,103,3.672,114,2.126,115,1.954,117,0.786,122,4.88,123,1.744,126,2.215,165,2.444,172,0.803,186,1.407,193,4.1,196,3.085,210,1.149,262,1.618,267,0.85,296,1.896,411,2.711,452,1.558,461,1.787,482,3.075,504,3.098,508,2.008,510,1.014,525,4.527,530,3.148,541,2.064,547,2.223,557,3.059,560,3.135,571,1.714,597,1.339,598,1.61,599,3.627,600,3.335,621,1.654,647,2.026,666,2.339,753,1.439,775,1.016,781,0.878,802,1.201,809,3.359,813,2.418,816,2.929,817,1.859,818,1.776,820,1.24,822,2.875,873,1.798,875,2.312,906,1.734,985,1.041,989,3.248,998,2.429,1009,2.555,1013,2.679,1055,3.435,1083,3.433,1128,3.218,1168,2.172,1170,1.48,1205,1.58,1213,1.943,1273,2.215,1276,2.38,1327,1.943,1396,1.975,1418,1.407,1439,3.433,1443,1.462,1455,3.221,1577,2.104,1668,2.418,1768,2.743,1790,1.58,1799,1.928,1816,3.122,1832,3.719,1895,3.882,1947,2.38,1976,1.734,2032,1.734,2121,3.468,2137,2.46,2144,1.885,2148,2.672,2180,1.339,2182,1.991,2195,2.418,2263,4.187,2320,2.418,2434,2.555,2452,3.17,2506,3.719,2545,2.126,2723,1.787,2853,4.233,2881,3.92,2921,2.418,2928,3.77,3536,2.826,3646,2.46,3672,6.069,3705,2.672,3710,2.743,4273,10.99,4274,10.502,4280,2.555,4667,8.277,4668,3.218,4669,3.472,4670,3.472,4671,5.664,4672,3.051,4673,3.051,4674,3.051,4675,3.472]],["t/980",[24,4.284,94,2.943,97,3.783,103,5.657,106,4.237,168,2.911,263,2.713,296,3.239,506,4.704,530,3.83,568,4.26,607,3.052,767,5.138,781,2.208,796,4.17,866,4.95,867,2.693,998,2.561,1008,4.614,1036,4.773,1055,3.288,1071,5.801,1187,5.347,1213,4.883,1233,5.892,1266,5.4,1308,4.409,2144,6.044,4676,8.089,4677,8.727,4678,8.727,4679,8.089]],["t/982",[7,2.361,12,2.129,38,2.432,39,3.974,40,3.474,41,2.985,83,1.308,90,2.432,91,3.056,97,2.044,107,4.873,115,2.285,117,1.015,122,2.704,128,3.042,216,3.452,240,2.422,296,1.751,297,1.948,405,4.098,411,2.142,412,2.259,421,4.338,461,3.408,538,2.101,579,2.448,636,3.408,775,2.71,816,2.704,834,2.471,861,3.974,985,3.643,986,4.349,998,1.943,1008,2.745,1090,3.288,1142,4.408,1273,2.589,1456,7.313,1586,4.649,1609,3.366,1611,4.978,1614,4.143,1989,3.831,2233,4.055,2260,2.945,2518,3.766,2545,4.055,2853,3.387,3252,3.622,3256,4.47,3639,4.191,3855,6.677,3890,5.581,4680,5.097,4681,6.623,4682,6.623,4683,4.978,4684,5.581,4685,8.465,4686,6.139,4687,3.974,4688,6.623,4689,3.798,4690,5.391,4691,4.978,4692,5.391,4693,5.097,4694,5.391,4695,6.139,4696,6.139,4697,6.139]],["t/984",[7,1.886,11,2.55,12,2.376,33,3.276,38,2.715,94,2.493,97,2.281,115,2.55,117,1.239,122,4.075,167,4.204,193,3.677,240,2.266,245,2.9,297,2.174,398,2.723,473,2.174,607,2.737,666,3.052,775,2.164,816,4.075,861,4.435,985,2.216,986,4.854,1008,4.684,1071,3.852,1253,3.78,1266,4.574,1399,3.609,1431,3.461,1456,5.84,1618,2.952,1727,2.625,1753,3.67,1954,3.828,2171,3.15,2260,3.287,2518,4.204,3252,4.043,3256,4.82,3810,4.204,4683,7.502,4684,6.229,4685,5.148,4687,6.781,4689,5.724,4690,6.017,4691,5.556,4692,6.017,4693,5.688,4694,6.017,4698,6.851,4699,8.77,4700,7.392,4701,7.392]],["t/986",[7,2.12,12,2.672,94,3.638,115,2.867,117,1.183,193,4.959,240,2.449,391,2.372,419,3.799,457,3.73,607,2.279,678,4.45,775,2.433,866,3.696,914,3.602,953,3.602,985,3.234,1008,4.472,1021,4.808,1064,5.143,1456,6.567,1753,5.356,1954,4.305,2063,7.705,2144,4.513,2180,3.206,2260,3.696,3252,4.546,3256,4.015,4683,6.248,4684,7.005,4685,5.789,4687,4.988,4689,4.767,4690,6.766,4691,6.248,4693,8.302,4702,8.313]],["t/988",[3,3.204,12,2.494,33,4.051,97,2.395,115,2.677,167,4.413,222,4.413,240,1.762,405,4.802,483,2.953,604,4.656,607,2.128,646,3.853,775,2.272,834,2.896,861,4.656,914,3.362,972,6.819,985,3.091,1007,5.709,1431,3.634,1519,4.377,1777,5.03,1809,5.709,1954,4.018,2260,3.451,2518,4.413,2570,4.154,3252,4.244,3502,4.569,3655,7.193,4683,7.751,4684,6.54,4685,7.181,4687,4.656,4690,6.317,4691,5.833,4692,6.317,4693,5.972,4703,7.76,4704,7.76,4705,7.76,4706,7.76,4707,7.76,4708,7.76,4709,10.312,4710,11.581,4711,10.312,4712,7.76,4713,4.569,4714,7.76,4715,7.76]],["t/990",[12,3.314,41,3.498,91,3.581,97,2.395,115,2.677,117,1.13,128,3.564,240,2.629,271,2.859,296,2.051,391,3.305,401,3.944,411,2.386,412,2.647,462,4.45,538,2.462,575,3.18,598,3.598,861,4.656,985,3.471,986,5.096,1008,3.217,1302,4.612,1456,6.131,1586,3.898,1727,2.756,1829,3.192,1952,4.569,2260,3.451,2518,4.413,2929,7.193,3252,4.244,3256,3.748,3611,4.528,3639,4.91,3890,8.69,4683,5.833,4685,8.065,4687,4.656,4689,4.45,4690,6.317,4691,5.833,4692,6.317,4693,5.972,4694,6.317,4695,7.193,4696,7.193,4697,7.193,4698,7.193,4699,6.819]],["t/993",[4716,10.984,4717,11.256,4718,10.984,4719,12.81,4720,10.984,4721,10.984,4722,10.984]],["t/995",[94,2.31,117,1.349,193,3.491,422,5.488,473,3.619,510,2,576,2.213,594,5.801,607,2.598,614,4.787,802,2.369,866,3.046,895,3.746,976,4.334,985,3.986,986,7.133,998,2.01,1008,3.928,1064,4.238,1071,3.57,1151,3.928,1248,6.177,1455,3.895,1722,3.161,1753,3.401,2171,5.667,3256,3.308,3648,7.565,4683,5.149,4686,6.349,4689,3.928,4692,9.541,4693,8.36,4694,5.576,4717,8.326,4723,9.475,4724,6.85,4725,6.349,4726,6.85,4727,6.85,4728,6.85,4729,6.349,4730,6.349,4731,6.349]],["t/997",[4693,8.387,4717,11.205,4729,10.102,4730,10.102,4731,10.102,4732,10.899,4733,10.899,4734,10.899,4735,10.899]],["t/1008",[21,3.06,196,3.185,203,4.694,266,4.576,626,4.08,648,5.662,908,3.936,4736,10.651,4737,9.871,4738,9.871,4739,9.871,4740,9.871,4741,9.871]],["t/1012",[6,4.2,41,3.725,44,1.911,73,2.459,117,1.178,118,3.083,136,3.691,148,2.108,156,2.008,180,2.656,218,2.883,235,3.97,351,5.793,474,3.044,495,5.818,521,3.566,526,3.083,538,2.622,626,4.116,748,3.165,781,2.091,957,3.134,985,3.58,1177,2.742,1281,5.878,1431,3.869,1618,3.3,1866,5.961,1942,6.216,2059,4.487,3505,5.961,4742,8.264,4743,7.484,4744,7.659,4745,7.659]],["t/1014",[28,4.102,44,1.461,72,2.689,73,2.445,84,4.126,117,1.174,148,2.096,180,2.64,218,4.155,243,2.131,249,3.791,483,3.126,538,2.606,626,4.562,748,3.147,869,7.117,923,2.158,957,4.06,985,2.462,1618,3.281,2059,4.46,2335,6.322,2388,5.546,3087,6.49,3371,7.614,4404,5.325,4687,4.929,4738,7.614,4743,5.721,4746,5.083,4747,8.215,4748,8.215,4749,7.219,4750,8.215,4751,7.614,4752,8.215,4753,8.215,4754,8.215,4755,8.215,4756,8.215,4757,8.215,4758,10.706]],["t/1017",[72,2.875,77,4.839,79,4.994,81,4.803,113,5.124,117,0.963,172,2.586,235,4.219,243,2.898,263,2.73,401,4.463,604,6.706,615,3.215,819,5.322,869,4.953,957,4.238,1004,4.335,1948,4.953,1988,3.215,2165,5.766,2491,6.22,4759,10.358,4760,8.782,4761,8.782,4762,8.782,4763,8.782,4764,8.782,4765,8.782,4766,8.782,4767,8.782,4768,8.782,4769,11.176,4770,8.782,4771,8.139,4772,8.139]],["t/1019",[72,3.568,243,2.827,263,3.389,401,5.54,869,6.147,3801,8.611,4759,11.819,4773,10.899,4774,9.577]],["t/1021",[117,1.195,128,5.005,172,2.522,243,2.827,719,4.846,781,2.757,869,6.147,957,4.836,4775,10.899]],["t/1023",[117,1.214,411,2.562,538,3.513,626,4.241,985,3.318,1009,3.943,2416,7.369,4776,11.071]],["t/1025",[17,4.59,43,3.623,168,3.474,240,3.011,411,2.41,538,3.304,626,3.989,775,3.048,875,3.355,985,3.121,1370,6.076,1772,5.325,3795,8.775,4739,9.651]],["t/1027",[44,2.429,85,2.902,117,1.125,240,2.329,748,3.93,1402,6.157,3871,7.549,4777,12.304,4778,13.179,4779,12.304,4780,7.402]],["t/1029",[44,2.429,85,2.902,117,1.125,240,2.329,748,3.93,1402,6.157,4780,7.402,4781,12.304,4782,10.261,4783,13.179,4784,12.304]],["t/1031",[43,3.849,73,2.888,117,0.778,156,1.723,172,2.56,214,2.475,243,2.869,339,4.394,411,1.641,412,3.31,420,3.851,538,2.25,555,3.52,626,2.717,923,1.863,957,4.511,985,2.909,1083,4.298,1596,2.621,1723,6.291,2171,3.023,2275,3.113,2754,3.823,2830,5.331,3632,5.773,3662,8.809,3855,7.001,3909,6.232,3917,6.232,4785,7.093,4786,6.574,4787,7.093,4788,5.773,4789,7.093,4790,7.093,4791,7.093,4792,7.093,4793,7.093,4794,9.705,4795,7.093,4796,7.093,4797,7.093,4798,7.093,4799,7.093,4800,7.093,4801,6.574,4802,7.093,4803,6.574,4804,9.705,4805,9.705]],["t/1033",[72,3.046,115,3.21,117,1.02,156,2.261,198,4.594,243,2.414,266,3.999,411,2.154,538,2.953,604,5.584,626,4.836,666,3.843,869,5.249,957,3.529,985,2.789,2144,5.053,2649,8.942,3579,7.352,4741,8.626,4806,12.625,4807,9.307,4808,9.307,4809,9.307,4810,10.744,4811,9.307]],["t/1035",[7,2.759,12,3.476,148,2.759,411,2.503,538,3.431,620,4.966,626,4.142,645,4.483,1004,5.339,1957,6.924,4740,10.024]],["t/1037",[44,1.735,117,1.07,148,2.49,245,3.829,350,6.845,748,3.739,781,2.469,957,3.701,1004,4.818,1727,3.466,1799,5.419,1949,6.578,2260,4.34,2262,7.511,2813,6.249,4812,11.064,4813,8.576,4814,7.944,4815,9.76,4816,9.76,4817,9.76,4818,9.76]],["t/1039",[7,3.1,30,1.529,44,2.02,97,2.306,148,2.564,181,6.152,411,2.629,412,2.548,834,2.787,985,4.001,1727,4.316,2260,5.404,2275,3.279,2813,7.781,4336,7.441,4819,10.053,4820,6.564,4821,5.749,4822,9.135,4823,11.265,4824,11.265,4825,5.615,4826,6.081,4827,6.081]],["t/1041",[6,5.073,7,1.886,30,1.513,43,2.572,44,2.009,117,1.094,148,3.453,214,2.579,242,5.013,243,1.917,266,3.176,483,2.813,528,3.551,555,2.681,626,2.831,645,4.684,748,3.823,781,1.87,830,4.313,891,3.609,957,2.803,985,2.216,991,3.244,1004,4.927,1055,2.785,1159,3.852,1355,4.574,1547,3.878,1578,5.688,1866,5.332,1868,5.148,1957,4.733,2260,3.287,2754,3.985,3321,7.886,4318,5.438,4336,4.526,4812,6.851,4813,10.633,4820,6.495,4824,6.851,4828,7.392,4829,11.301,4830,7.392,4831,7.392,4832,7.392,4833,7.392,4834,7.392,4835,7.392]],["t/1043",[7,3.429,30,1.375,44,2.172,73,1.999,117,1.025,156,2.825,168,3.587,172,1.555,208,1.981,214,2.344,219,2.217,226,3.13,243,3.015,248,3.648,263,2.089,411,2.163,483,2.556,538,2.966,555,4.937,626,2.573,753,4.818,957,3.545,985,2.014,991,2.949,1004,3.317,1618,3.733,1734,4.589,2105,7.386,2316,3.028,2859,5.662,4780,6.744,4822,7.027,4836,6.719,4837,9.349,4838,6.719,4839,10.752,4840,9.349,4841,9.349,4842,6.719,4843,6.719,4844,9.349,4845,6.719,4846,6.719]],["t/1045",[117,1.233,123,3.463,639,5.825,645,4.663,4746,8.036]],["t/1047",[117,1.159,148,2.696,411,3.088,639,5.473,645,4.381,985,3.168,1727,3.754,2925,8.351,2999,7.244,4294,7.487,4746,6.54,4847,9.288]],["t/1052",[43,3.444,87,3.395,117,1.32,168,3.302,180,3.869,186,4.011,203,4.363,483,3.766,555,4.706,781,2.504,809,3.223,977,7.011,985,2.967,1011,5.158,1415,6.683,1618,3.953,2271,6.37]],["t/1055",[5,0.728,10,1.236,30,0.695,44,1.896,47,1.221,73,1.011,87,1.908,94,1.146,96,2.19,97,2.521,117,1.325,122,2.271,123,3.497,148,2.721,156,1.985,180,3.111,181,4.285,196,1.016,211,1.255,218,1.185,240,1.854,243,1.832,263,1.056,264,1.583,266,1.459,297,0.999,338,1.649,391,0.969,411,1.635,473,0.999,483,3.108,492,1.342,495,1.424,521,1.466,526,3.048,529,1.189,530,1.491,538,2.859,553,1.806,555,3.869,557,1.255,560,1.484,566,2.45,568,1.658,607,1.937,612,1.625,620,1.56,621,0.992,645,3.386,646,2.762,737,1.545,781,2.585,796,1.623,822,1.361,866,1.51,867,1.048,891,2.716,923,0.892,957,2.679,985,3.197,998,0.997,1011,1.77,1035,1.964,1055,1.28,1097,1.392,1200,1.806,1231,1.649,1253,1.737,1271,1.782,1273,1.328,1380,3.756,1418,1.376,1596,1.255,1599,1.402,1609,1.726,1618,2.222,1727,1.976,1734,1.667,1914,1.696,1941,2.45,1942,3.218,1948,3.985,2062,3.088,2151,2.499,2157,3.142,2192,5.719,2357,1.964,2415,7.143,2519,3.562,2521,2.45,2522,2.406,2570,1.818,2619,1.64,2830,4.181,2971,2.293,3511,1.77,4100,2.175,4746,3.442,4780,5.097,4825,4.181,4826,4.528,4827,4.528,4848,2.984,4849,8.723,4850,5.563,4851,4.528,4852,2.984,4853,3.148,4854,3.397,4855,3.397,4856,5.156,4857,3.397,4858,4.181,4859,3.397,4860,3.397,4861,9.013,4862,3.148,4863,2.683,4864,3.397,4865,3.397,4866,2.765,4867,3.397,4868,3.397,4869,3.397,4870,3.397,4871,3.397,4872,3.397,4873,3.397,4874,3.397,4875,3.397,4876,3.397,4877,3.397,4878,3.148]],["t/1057",[87,3.709,180,3.476,186,4.382,296,2.858,411,2.503,530,4.746,607,2.965,694,5.28,781,3.211,4879,10.815]],["t/1059",[30,2.269,43,3.857,87,3.803,115,2.992,117,1.34,118,3.236,122,3.541,137,3.541,219,3.659,296,2.93,391,2.475,411,2.007,473,2.551,474,3.195,489,2.893,552,5.504,564,5.061,568,4.234,666,4.578,679,4.382,781,3.092,971,4.611,985,2.6,996,7.059,1218,4.549,1253,4.435,1954,4.491,4294,6.143,4880,8.157,4881,9.343]],["t/1061",[27,4.736,28,3.596,43,3.412,87,4.296,117,0.79,138,2.223,164,4.004,186,3.974,213,3.107,219,2.377,240,1.635,243,1.868,263,2.239,473,2.118,474,2.653,489,2.402,584,3.339,617,5.179,645,4.065,663,3.121,668,2.687,679,3.639,694,6.115,774,4.409,781,2.481,834,2.687,867,2.223,870,4.321,953,3.121,957,4.54,1011,3.753,1727,2.558,1896,4.062,2440,3.107,4336,4.409,4350,4.28,4814,5.862,4880,8.204,4882,9.807,4883,6.675,4884,9.807,4885,7.202,4886,6.328,4887,7.202,4888,6.328,4889,7.202,4890,6.328,4891,6.675,4892,9.807,4893,7.202,4894,6.328,4895,7.202,4896,6.328]],["t/1063",[21,1.607,30,1.678,44,1.901,86,2.494,88,2.593,96,2.202,115,1.929,117,1.172,172,2.247,179,3.293,196,1.672,213,2.413,243,1.45,297,1.645,412,1.907,443,2.345,474,2.06,489,1.866,529,1.957,538,1.774,546,3.263,576,1.807,584,2.593,645,3.399,694,2.73,705,4.034,775,2.4,781,1.415,814,1.886,866,2.487,868,5.249,886,4.553,914,2.423,957,4.318,1204,2.283,1231,2.715,1734,4.025,1904,4.905,2275,2.454,2288,4.553,2327,4.034,2690,4.203,2885,4.034,3701,3.18,4336,3.424,4457,3.672,4814,4.552,4880,6.033,4886,4.914,4888,4.914,4890,4.914,4891,5.183,4894,4.914,4896,4.914,4897,5.592,4898,5.592,4899,5.592,4900,4.304,4901,5.592,4902,5.592,4903,8.229,4904,7.6,4905,6.478,4906,6.478,4907,5.592,4908,5.183,4909,5.592,4910,5.183,4911,5.592,4912,5.592,4913,5.592,4914,3.895,4915,5.592,4916,5.183,4917,5.592,4918,5.183,4919,5.183,4920,5.592,4921,5.183,4922,5.183,4923,5.592,4924,5.592,4925,5.592,4926,5.592,4927,5.592,4928,5.592,4929,5.183,4930,5.183,4931,5.592,4932,5.183,4933,5.183,4934,5.592,4935,5.592,4936,5.183,4937,5.183,4938,5.592,4939,5.183,4940,5.183,4941,5.592,4942,3.895,4943,5.592]],["t/1065",[21,1.968,27,3.308,30,1.402,44,2.32,87,4.02,90,2.516,117,0.751,124,4.071,148,1.747,186,4.402,187,2.219,190,4.677,196,2.048,250,2.745,391,3.1,411,2.193,490,2.818,510,2,552,4.704,575,2.807,607,1.878,639,3.547,645,3.928,678,3.667,679,4.787,693,3.997,694,6.213,722,4.625,723,4.151,748,4.161,753,5.1,774,6.651,781,2.397,985,2.053,998,2.01,1004,4.677,1098,3.693,1127,4.334,1261,4.695,1265,4.386,1330,3.962,1431,3.207,1819,3.693,1865,5.039,2059,3.719,2078,5.149,2331,4.194,4944,6.85,4945,10.069,4946,6.85,4947,6.85]],["t/1067",[4,0.907,5,0.815,10,1.384,30,1.248,33,3.248,41,0.978,43,2.655,44,2.386,73,1.511,83,0.751,85,2.159,86,0.66,87,1.741,96,2.401,97,1.567,115,1.312,117,1.005,118,1.419,122,0.886,123,1.171,136,1.699,137,1.553,148,1.555,156,1.685,160,3.462,177,0.992,180,0.698,186,1.541,190,2.506,193,0.8,203,2.238,210,1.68,214,1.327,226,1.772,229,0.74,235,1.043,240,1.384,263,0.675,267,0.532,271,2.246,296,1.612,297,0.638,391,1.449,411,2.757,420,1.179,421,3.088,463,0.74,470,2.338,474,0.8,482,1.179,495,1.595,521,0.937,525,4.083,538,0.689,546,1.267,552,4.334,555,3.167,586,0.974,602,1.358,607,0.595,626,4.564,637,1.97,645,0.9,651,3.379,660,0.929,668,1.419,694,1.06,744,2.022,759,0.997,775,1.113,781,2.504,886,1.205,908,3.389,923,0.57,985,3.732,991,0.953,998,1.116,1004,1.878,1009,2.718,1011,2.646,1049,1.245,1055,0.818,1120,1.179,1159,2.646,1168,1.358,1170,0.925,1177,0.72,1179,1.597,1213,1.215,1214,1.131,1302,2.261,1352,2.498,1370,1.267,1431,1.016,1443,0.914,1599,1.571,1609,1.103,1618,2.028,1727,1.351,1753,1.078,1807,1.837,1941,2.744,1967,1.084,2059,1.179,2062,3.815,2075,1.09,2157,2.258,2171,1.621,2180,3.933,2192,1.215,2416,2.532,2519,3.904,2716,3.005,2816,1.829,3511,1.131,3665,1.278,3669,3.205,3678,2.08,3705,1.67,3713,2.859,3810,1.234,3873,1.407,4070,2.435,4100,1.39,4272,2.859,4294,1.538,4674,1.907,4743,2.649,4746,6.31,4880,3.735,4948,3.816,4949,2.012,4950,3.804,4951,6.934,4952,5.077,4953,5.077,4954,3.342,4955,3.816,4956,3.526,4957,6.427,4958,3.096,4959,3.804,4960,3.804,4961,3.804,4962,3.342,4963,8.5,4964,1.538,4965,2.012,4966,8.223,4967,2.171,4968,3.804,4969,4.011,4970,3.804,4971,2.171,4972,1.907,4973,2.012,4974,2.171,4975,2.012,4976,2.012,4977,2.012,4978,2.012,4979,2.012,4980,2.171,4981,2.012,4982,2.171,4983,2.012,4984,2.171,4985,1.907,4986,1.907,4987,1.907,4988,2.012,4989,2.171,4990,2.171,4991,1.829,4992,1.907,4993,2.171,4994,2.171,4995,2.171,4996,2.171,4997,2.171]],["t/1069",[86,3.599,88,4.463,117,1.298,172,2.966,243,2.496,529,3.369,538,3.054,866,4.281,868,6.564,886,6.572,957,4.489,1204,3.93,4903,9.863,4905,7.605,4906,7.605,4998,7.408]],["t/1071",[33,1.622,44,1.604,83,0.976,86,2.743,87,3.094,88,3.467,96,3.552,117,1.294,156,1.817,165,3.227,172,1.73,180,3.233,207,3.091,235,2.374,238,2.858,243,1.282,266,2.123,297,3.178,412,3.077,443,3.136,473,2.199,560,3.268,584,2.291,612,2.184,617,2.609,645,2.048,646,3.712,694,5.55,748,2.864,781,2.282,788,3.091,868,3.671,957,1.874,977,5.297,997,3.213,998,1.45,1009,3.849,1011,3.897,1547,3.923,1596,3.718,1708,5.621,1712,2.683,1918,3.872,2062,4.396,2157,3.325,2180,3.479,2260,2.197,2275,3.959,2708,7.927,2813,3.164,2885,3.565,3669,7.602,4079,5.125,4336,3.025,4350,4.444,4814,4.022,4880,5.501,4886,4.342,4888,4.342,4890,4.342,4894,4.342,4896,4.342,4903,6.942,4904,4.58,4905,3.904,4906,3.904,4908,4.58,4910,4.58,4914,3.441,4916,4.58,4918,6.931,4919,4.58,4921,6.931,4922,4.58,4929,4.58,4930,4.58,4932,4.58,4933,4.58,4936,4.58,4937,4.58,4939,4.58,4940,4.58,4942,3.441,4999,4.942,5000,4.942,5001,4.942,5002,6.931,5003,4.942,5004,6.931]],["t/1073",[21,2.361,30,1.681,86,2.498,87,4.328,117,0.901,123,2.529,194,3.105,203,3.621,219,3.533,258,3.136,263,2.554,266,3.53,414,2.228,461,4.227,597,3.168,621,2.399,627,3.575,645,3.405,659,3.157,663,3.56,679,4.151,694,4.011,781,3.311,866,3.653,908,3.957,914,3.56,925,5.819,998,2.41,1008,3.405,1170,3.501,1607,3.269,2937,6.175,4746,5.083,4847,7.219,5005,6.687,5006,8.215,5007,9.022,5008,10.465,5009,7.219,5010,8.215]],["t/1075",[87,4.423,91,4.504,117,1.07,180,3.137,218,3.406,391,2.786,411,2.984,470,2.99,552,4.846,666,4.03,760,4.714,781,3.399,985,3.578,1070,4.902,1988,3.573,3498,6.914,4780,7.041]],["t/1077",[30,1.599,38,2.869,44,2.289,73,1.559,87,3.552,96,3.075,97,1.616,123,3.411,148,2.383,168,1.747,180,2.51,218,2.726,226,2.44,268,4.558,505,4.182,510,1.529,521,4.031,524,5.451,538,2.964,566,5.635,586,3.505,645,2.171,663,5.034,759,2.405,781,2.62,796,4.949,830,3.056,873,5.363,896,4.272,1027,5.844,1227,3.276,1239,4.518,1445,3.647,1547,4.098,1601,6.894,1904,3.947,2060,2.646,2192,5.228,2230,4.626,2359,6.341,3104,5.063,3337,2.557,3589,9.103,4297,6.992,5011,5.237,5012,7.62,5013,7.812,5014,7.812,5015,7.812,5016,7.812,5017,7.812,5018,7.812,5019,5.237,5020,7.812,5021,7.812,5022,7.812,5023,7.812,5024,7.812,5025,7.812]],["t/1080",[10,1.773,11,1.681,43,3.112,44,1.776,47,1.751,72,1.595,73,1.45,85,2.093,86,3.77,87,4.03,88,2.259,96,1.918,97,2.76,117,1.177,118,1.818,123,1.5,124,2.896,128,3.398,148,1.887,168,1.625,172,2.07,180,3.451,211,1.801,219,1.608,227,2.924,229,1.662,411,2.311,414,1.321,470,3.06,489,1.625,510,1.423,511,2.217,538,1.546,546,2.843,579,1.801,584,2.259,621,1.423,655,3.2,656,4.858,660,2.085,663,2.111,678,3.961,681,2.186,694,4.367,697,2.293,729,3.452,774,4.53,781,2.717,866,2.167,914,3.206,953,3.206,987,1.741,997,3.825,1028,2.366,1070,2.447,1098,2.627,1131,4.108,1250,3.393,1295,3.452,1330,4.279,1477,2.523,1599,2.012,1607,1.939,1618,1.946,1721,4.106,1722,2.248,1788,2.771,1829,2.004,1868,3.393,1975,7.686,1988,1.784,2016,2.608,2230,2.177,2288,2.706,2570,2.608,3220,3.452,4683,3.663,4780,3.515,4848,7.859,4903,3.75,4905,3.85,4906,3.85,4998,5.694,5007,4.106,5008,10.324,5009,4.282,5026,4.516,5027,4.516,5028,4.516,5029,4.516,5030,5.845,5031,5.845,5032,4.516,5033,4.282,5034,3.85,5035,3.966,5036,4.516,5037,4.516]],["t/1082",[17,3.895,123,2.72,150,3.677,172,2.045,180,3.606,240,2.006,297,2.599,411,2.596,470,2.707,538,2.804,560,4.903,615,4.108,663,3.829,719,3.93,781,2.236,820,3.157,831,4.314,1003,4.605,1431,4.138,1530,5.156,1988,3.235,2062,3.862,2260,3.93,3668,6.982,4350,5.252,5030,6.982,5038,9.186,5039,8.837,5040,8.837,5041,8.191,5042,8.837,5043,8.191,5044,8.837]],["t/1084",[7,2.898,17,3.293,44,2.322,73,2.223,83,2.504,117,1.246,160,3.73,172,2.326,180,2.401,240,1.696,243,1.937,263,2.323,421,2.806,560,4.965,607,2.048,719,4.47,882,3.774,891,3.647,957,2.833,985,2.239,1727,4.035,3662,4.783,3683,6.564,3694,7.942,4656,6.296,4955,5.615,5030,5.902,5045,10.053,5046,11.362,5047,11.362,5048,6.564,5049,6.564,5050,7.471,5051,7.471,5052,10.053,5053,7.471,5054,6.924,5055,6.564,5056,6.564,5057,10.053,5058,6.564,5059,6.924]],["t/1086",[118,4.78,489,3.664,781,3.241,993,4.236,5060,11.428]],["t/1089",[10,2.298,33,3.413,39,2.385,42,2.724,44,2.451,47,1.428,73,2.338,80,1.962,86,1.92,115,1.371,117,1.14,137,1.623,138,1.227,148,2.652,172,1.818,180,2.03,181,1.76,214,1.387,218,3.408,222,2.26,243,2.697,249,1.834,263,1.964,266,1.708,267,0.973,470,2.992,473,1.169,525,1.973,529,1.391,538,2.493,557,1.469,566,2.867,576,1.284,597,1.533,650,2.867,663,2.736,681,1.783,719,1.767,732,3.562,740,1.825,756,1.88,781,2.758,785,2.045,809,1.294,834,2.356,875,1.281,881,2.385,886,3.506,888,2.207,923,1.044,942,2.008,957,3.704,973,2.724,978,1.255,985,1.893,998,1.166,1070,1.996,1127,2.515,1204,1.623,1218,2.085,1396,2.26,1457,2.299,1596,1.469,1607,1.582,1753,5.162,1790,2.873,1934,3.48,2060,2.008,2275,1.744,2316,1.791,2965,2.26,3705,4.86,3710,4.989,4170,2.459,4377,3.235,4674,5.549,4743,2.768,4958,3.235,5061,3.684,5062,8.463,5063,3.492,5064,3.975,5065,3.975,5066,3.975,5067,3.975,5068,3.975,5069,3.975,5070,3.975,5071,3.975,5072,3.975,5073,3.975,5074,3.235,5075,3.684,5076,3.975,5077,6.315,5078,6.315,5079,3.975,5080,3.975,5081,5.549,5082,3.975,5083,5.14,5084,3.975,5085,3.975,5086,6.315,5087,3.975,5088,3.975,5089,3.975,5090,10.398,5091,10.398,5092,3.975,5093,3.975,5094,3.684,5095,3.975,5096,2.924,5097,5.853,5098,3.975,5099,3.975,5100,3.684,5101,6.315]],["t/1091",[21,2.135,30,1.521,44,2.538,73,2.211,97,3.091,117,0.815,156,1.806,172,1.72,196,2.222,243,1.927,320,5.362,338,3.608,492,2.936,619,3.38,626,2.846,744,3.951,781,1.88,784,7.914,923,1.952,1248,4.226,1465,4.515,1518,4.817,2026,5.467,2062,5.532,2413,6.888,2708,8.802,3705,5.719,4737,6.888,4958,6.049,4991,6.262,5062,6.049,5094,6.888,5102,12.127,5103,7.431,5104,7.431,5105,7.431,5106,7.431,5107,7.431,5108,7.431,5109,7.431,5110,7.431,5111,7.431,5112,7.431,5113,7.431,5114,7.431]],["t/1094",[30,2.07,73,3.009,117,1.109,163,4.807,172,2.822,243,2.623,781,2.558,1753,6.055,2570,5.413,2716,7.989,5062,8.231,5115,9.373,5116,10.112,5117,10.112,5118,9.373,5119,9.373,5120,10.112,5121,10.112]],["t/1096",[117,1.214,172,2.562,525,5.496,886,6.147,4743,7.71,5063,11.308,5075,10.261]],["t/1098",[33,2.506,43,2.656,44,2.519,87,2.618,97,2.356,148,1.947,186,3.093,203,3.365,525,5.064,645,3.164,781,2.906,985,3.057,2062,3.336,2192,4.271,2716,8.058,4746,4.723,4954,6.707,4956,9.453,4958,6.213,4972,6.707,5062,6.213,5063,6.707,5118,7.075,5119,10.646,5122,7.075,5123,10.199,5124,10.199,5125,9.453,5126,10.199,5127,7.634,5128,7.634,5129,7.075,5130,7.634,5131,7.634,5132,7.634,5133,7.634,5134,7.634,5135,7.634,5136,10.199,5137,7.634,5138,7.634]],["t/1100",[21,3.536,86,3.12,117,1.349,639,5.313,649,4.503,1142,6.829,1801,5.382,1835,7.896,2180,3.957,4914,7.145,5139,10.261,5140,8.106,5141,10.261,5142,10.261,5143,7.896,5144,10.261]],["t/1102",[43,3.468,73,2.967,115,3.438,148,2.543,172,2.307,223,8.048,224,5.871,296,2.635,957,3.78,1465,4.493,5145,12.092,5146,9.088,5147,9.969,5148,9.969,5149,9.969,5150,9.969,5151,9.969,5152,9.969]],["t/1104",[148,2.893,1159,5.91,5153,11.34,5154,11.34,5155,10.511]],["t/1106",[44,2.506,73,3.058,148,2.621,156,2.992,172,1.786,193,2.843,243,2.002,338,3.747,462,4.426,562,3.151,759,3.544,881,4.631,985,2.313,1596,4.551,2275,3.387,2591,5.467,4780,5.567,4786,7.153,4801,7.153,5146,5.801,5156,7.718,5157,10.274,5158,10.148,5159,10.274,5160,8.658,5161,7.718,5162,7.718,5163,7.718,5164,7.718,5165,7.718,5166,10.274,5167,10.274,5168,7.718,5169,7.718,5170,7.718,5171,7.718,5172,7.718,5173,7.718]],["t/1108",[7,1.158,10,1.652,15,2.281,44,1.712,86,2.132,117,1.055,139,1.336,160,2.268,172,1.622,199,5.298,200,4.488,214,1.585,217,2.541,240,2.362,243,1.818,248,2.466,297,2.062,339,2.056,351,2.448,391,2.444,421,2.633,436,2.752,437,3.404,438,6.237,443,1.905,483,1.728,489,1.515,495,1.905,525,2.255,538,1.441,555,1.647,626,3.28,679,2.294,719,5.264,748,3.28,781,2.436,787,1.905,820,2.504,923,1.841,942,4.864,953,1.968,957,3.247,985,2.886,991,1.993,993,4.684,1281,2.484,1300,4.338,1531,3.827,1727,1.613,1941,6.945,1987,4.02,2035,3.341,2062,1.984,2180,4.24,2363,5.55,2693,3.217,2830,3.413,3809,3.276,4070,2.908,4746,4.338,4955,3.413,4963,4.209,4964,9.819,4965,4.209,4983,6.498,5058,3.99,5146,7.236,5174,7.01,5175,4.541,5176,4.541,5177,4.541,5178,7.01,5179,4.541,5180,3.827,5181,4.541,5182,4.541,5183,4.209,5184,5.269,5185,4.541,5186,4.541,5187,4.541,5188,4.541,5189,7.01]],["t/1110",[10,2.824,30,1.588,44,2.433,73,2.309,97,2.395,156,1.886,186,3.145,243,2.013,296,2.725,411,2.386,473,2.282,483,2.953,555,2.815,612,3.012,645,3.217,805,6.131,957,4.68,1159,4.044,1205,3.53,1245,6.128,1402,4.656,1596,2.868,1647,4.528,2180,3.977,2275,3.406,3337,3.789,3639,4.91,4746,4.802,5190,10.312,5191,7.76,5192,10.312,5193,7.76,5194,6.819,5195,11.581,5196,6.819,5197,7.193,5198,7.76,5199,7.76,5200,10.312,5201,7.76,5202,7.76,5203,7.76]],["t/1112",[5,1.12,21,0.504,30,1.233,31,1.152,35,1.063,43,1.819,44,1.94,48,0.681,80,2.115,87,1.08,97,0.972,105,1.185,117,1.26,118,0.655,148,1.99,150,0.73,156,0.765,163,0.834,164,0.716,172,1.21,180,2.781,193,0.646,194,0.663,218,2.543,219,1.039,220,0.847,222,1.791,226,0.818,235,0.843,242,0.881,243,1.111,250,1.262,264,0.818,338,0.852,391,1.223,411,0.406,412,1.783,420,4.698,462,1.006,463,1.074,473,0.516,474,1.16,486,0.787,492,0.693,538,2.475,579,2.694,586,0.787,607,0.481,618,0.96,620,0.806,621,1.759,645,1.306,654,0.711,656,2.068,660,0.751,679,2.641,748,0.672,753,0.727,775,1.254,781,2.669,785,1.621,787,0.736,802,1.482,814,1.763,820,0.627,830,1.024,832,2.761,834,2.5,866,0.78,877,1.763,882,0.887,923,1.373,953,0.76,955,0.742,957,3.13,978,1.901,985,1.567,987,0.627,998,0.515,1027,1.97,1029,0.998,1072,0.887,1097,0.719,1120,0.953,1185,1.015,1245,1.043,1266,1.086,1273,0.686,1279,1.006,1330,1.822,1396,0.998,1399,0.857,1417,1.043,1443,0.739,1459,2.768,1465,0.791,1477,0.909,1607,0.698,1618,1.258,1722,0.81,1727,1.119,1753,6.7,1773,0.946,1790,0.798,1825,1.024,1988,1.153,2010,1.098,2165,1.152,2177,1.043,2180,4.141,2275,2.941,2356,1.601,2440,0.757,2478,0.939,2491,3.703,2771,6.275,2851,1.291,2879,1.243,3024,2.424,3208,1.152,3252,2.344,3678,6.528,3741,1.098,3932,4.066,4070,2.017,4590,1.479,4851,1.428,4985,7.251,4986,2.768,4987,2.768,5005,1.428,5204,3.972,5205,1.626,5206,6.836,5207,1.755,5208,1.755,5209,3.15,5210,5.933,5211,1.479,5212,3.972,5213,4.285,5214,3.15,5215,9.011,5216,3.15,5217,1.755,5218,1.755,5219,1.755,5220,4.845,5221,1.542,5222,6.755,5223,5.228,5224,10.348,5225,8.175,5226,5.228,5227,4.845,5228,10.737,5229,5.228,5230,4.594,5231,1.755,5232,2.919,5233,7.289,5234,7.289,5235,7.289,5236,7.289,5237,7.289,5238,7.289,5239,7.289,5240,7.289,5241,7.289,5242,7.289,5243,2.919,5244,4.255,5245,1.626,5246,3.972,5247,1.626,5248,1.626,5249,1.542,5250,2.654,5251,6.211,5252,1.626,5253,1.626,5254,1.626,5255,1.626,5256,2.919,5257,1.626,5258,1.755]],["t/1114",[6,0.705,30,1.173,38,0.509,43,1.519,44,1.846,47,1.569,75,2.353,80,3.108,85,0.392,94,0.468,96,0.546,97,1.088,116,0.643,117,0.949,148,0.649,172,0.321,180,2.459,181,1.932,214,0.888,218,2,224,0.673,411,0.589,412,3.046,552,1.263,579,0.512,607,0.697,610,1.263,645,1.054,656,2.866,679,2.205,732,0.801,748,0.974,781,1.936,785,1.309,802,1.983,808,0.982,814,2.124,832,4.57,834,1.629,867,0.428,877,1.423,882,0.701,914,1.102,923,0.668,953,0.601,957,1.932,978,0.438,985,2.293,1027,1.591,1216,1.02,1266,0.858,1399,2.131,1417,1.512,1459,5.973,1565,0.911,1601,1.693,1612,1.802,1618,1.016,1727,1.55,1753,4.296,1954,0.718,2180,4.84,2275,4.405,2288,1.412,2356,3.2,2357,0.802,2491,5.42,2553,3.092,2718,4.666,2754,0.748,2770,1.514,2771,1.771,2934,0.795,3024,3.359,3640,0.888,3653,3.92,3678,5.678,3773,4.529,3786,1.169,3932,1.717,4070,2.795,4685,2.454,4825,3.281,4851,2.07,4985,5.973,4986,2.235,4987,2.235,4988,5.313,5204,2.358,5206,6.597,5210,6.796,5212,3.266,5220,2.358,5222,2.358,5225,7.781,5227,4.046,5230,2.235,5232,5.313,5243,5.313,5244,6.796,5245,2.358,5246,5.313,5247,2.358,5248,2.358,5249,4.476,5250,6.107,5251,6.301,5252,1.285,5253,2.358,5254,2.358,5255,2.358,5256,5.836,5257,2.358,5259,1.129,5260,3.266,5261,2.544,5262,1.387,5263,6.297,5264,6.297,5265,6.297,5266,6.297,5267,6.297,5268,7.247,5269,7.247,5270,7.247,5271,7.247,5272,7.247,5273,7.247,5274,7.247,5275,7.247,5276,7.247,5277,7.247,5278,2.544,5279,2.544,5280,2.544,5281,8.932,5282,1.129,5283,1.387,5284,1.387,5285,1.387,5286,4.046,5287,1.387,5288,1.387,5289,1.169,5290,1.387,5291,1.387,5292,1.387,5293,1.387,5294,1.387,5295,1.387,5296,1.387,5297,1.387,5298,3.524,5299,1.387,5300,3.524,5301,4.365,5302,2.544,5303,1.387,5304,1.387,5305,2.544,5306,1.387,5307,1.387,5308,2.544,5309,1.387,5310,1.387,5311,1.387,5312,1.285,5313,1.387,5314,1.387,5315,2.544,5316,2.544,5317,2.544,5318,2.544,5319,6.297,5320,6.297,5321,6.297,5322,6.297,5323,6.297,5324,6.297,5325,6.297,5326,6.297,5327,6.297,5328,6.297,5329,6.297,5330,6.297,5331,6.297,5332,6.297,5333,6.297,5334,6.297,5335,6.297,5336,6.297,5337,6.297,5338,6.297]],["t/1116",[7,3.117,44,1.542,73,3.299,156,2.107,160,5.536,172,2.566,180,2.787,218,3.026,483,3.3,957,3.289,993,4.713,1601,5.773,1976,6.431,2059,6.635,2062,3.79,2157,3.857,2180,4.967,2260,3.857,4417,6.519,5146,6.519,5183,8.039,5339,11.087,5340,8.673,5341,8.673,5342,8.673,5343,8.039,5344,8.673]],["t/1118",[17,3.937,30,1.289,33,2.066,44,2.477,47,3.731,83,1.243,91,2.905,117,0.69,172,1.457,180,2.023,218,3.116,243,1.633,391,1.797,402,4.386,529,2.203,621,1.839,775,1.843,781,2.626,834,2.349,871,3.496,885,3.707,1003,5.41,1009,2.243,1011,3.281,1015,3.108,1331,3.606,1612,3.22,1640,2.812,1727,2.236,1751,3.61,1878,3.855,1925,4.632,1941,4.542,1945,5.125,1976,5.183,2177,3.742,2180,3.444,2230,3.989,2243,4.845,2415,5.636,3035,5.125,3467,5.532,4417,4.732,4856,5.835,5056,5.532,5146,4.732,5343,5.835,5345,6.296,5346,8.932,5347,10.38,5348,6.296,5349,6.296,5350,6.296,5351,6.296,5352,6.296,5353,6.296,5354,6.296,5355,6.296,5356,6.296,5357,6.296,5358,6.296,5359,6.296,5360,6.296,5361,6.296,5362,4.974,5363,6.296,5364,6.296,5365,5.835,5366,5.835,5367,5.835]],["t/1120",[10,1.702,30,0.957,44,1.275,73,1.392,84,2.349,87,2.991,94,1.578,97,2.213,117,1.22,123,3.85,148,2.225,156,2.562,164,1.91,168,1.56,172,1.082,180,3.143,181,3.861,196,1.399,203,2.062,218,2.502,229,1.595,240,1.628,263,1.454,264,2.179,296,2.305,338,2.271,391,1.335,411,1.66,473,1.376,492,1.848,526,2.676,530,2.053,538,1.484,553,2.487,555,4.614,557,1.729,615,1.713,645,3.615,663,2.027,781,1.814,787,1.962,866,2.08,867,1.444,886,2.597,957,1.774,985,2.931,998,1.372,1014,2.201,1035,2.705,1200,2.487,1253,2.392,1271,2.454,1599,1.932,1601,3.113,1618,1.868,1914,2.336,2180,4.609,2521,3.374,2570,2.504,2690,3.516,3678,2.558,4100,2.995,4503,3.158,4746,2.894,4780,3.374,4849,9.681,4851,3.807,4852,4.11,4853,4.336,4862,4.336,4964,5.08,5368,7.172,5369,12.722,5370,12.253,5371,4.678,5372,4.678,5373,4.336,5374,4.336,5375,4.678,5376,4.678,5377,4.678,5378,4.678,5379,4.678,5380,4.678,5381,4.678,5382,4.678,5383,4.678,5384,4.678,5385,4.678,5386,4.678,5387,4.678,5388,4.678,5389,4.336,5390,4.336,5391,4.336]],["t/1122",[44,2.314,73,2.403,124,7.734,172,1.868,210,2.671,240,1.833,243,2.094,263,2.51,264,3.762,412,4.027,486,4.749,538,2.561,756,3.818,957,3.062,1019,6.034,2018,4.008,2180,3.113,3256,5.112,4689,6.07,5146,6.068,5392,8.073,5393,13.013,5394,8.073,5395,8.073,5396,8.073,5397,8.073,5398,8.073,5399,8.073,5400,8.073,5401,8.073,5402,8.073,5403,8.073,5404,8.073,5405,8.073]],["t/1124",[35,3.924,44,1.763,73,1.221,97,1.266,115,1.415,117,1.087,164,2.644,168,1.369,172,0.949,196,1.936,226,1.911,229,1.399,240,0.931,243,1.064,263,2.013,264,1.911,338,3.895,339,3.633,403,2.731,405,2.538,412,3.764,420,2.227,473,1.207,479,3.157,486,1.841,492,1.621,538,2.055,612,1.198,663,1.778,820,1.466,834,2.993,875,1.322,953,2.806,957,2.456,985,3.893,998,1.9,1019,1.902,1025,2.048,1174,2.857,1399,3.161,1437,3.802,1480,3.624,1586,2.06,1596,2.393,1612,2.098,1712,2.227,1948,3.653,2018,2.037,2019,2.857,2024,2.659,2026,3.018,2144,2.227,2180,1.582,2258,3.605,2275,5.487,2281,2.566,2330,3.157,2595,8.445,2674,2.181,2723,2.111,2754,4.325,3104,2.659,3256,5.822,3528,3.157,3611,2.394,3639,2.596,3678,2.244,3782,5.457,3878,3.605,3901,3.157,3932,2.77,4080,3.241,4145,3.157,4336,2.512,4689,2.353,4964,2.906,5146,3.084,5406,5.69,5407,9.919,5408,4.103,5409,3.802,5410,4.103,5411,4.103,5412,6.476,5413,4.103,5414,4.103,5415,4.103,5416,4.103,5417,6.476,5418,3.339,5419,3.018,5420,3.605,5421,3.241,5422,4.103,5423,4.103,5424,4.103,5425,4.103,5426,4.103,5427,3.605,5428,4.103,5429,3.802,5430,3.802,5431,3.802,5432,4.103,5433,3.802,5434,4.103,5435,4.103,5436,4.103,5437,4.103,5438,4.103,5439,4.103,5440,4.103,5441,3.241,5442,3.457,5443,3.802,5444,3.241,5445,3.802,5446,4.103,5447,3.802,5448,3.802,5449,4.103,5450,4.103,5451,4.103,5452,3.605,5453,4.103,5454,3.802,5455,4.103,5456,4.103,5457,4.103,5458,4.103,5459,3.802,5460,3.802,5461,3.802,5462,4.103,5463,4.103,5464,4.103,5465,4.103,5466,3.802,5467,3.802,5468,4.103,5469,4.103,5470,4.103,5471,4.103,5472,4.103]],["t/1126",[118,4.78,489,3.664,781,3.241,993,4.236,5473,8.483]],["t/1128",[118,4.78,489,3.664,781,3.241,993,4.236,2619,6.549]],["t/1130",[83,2.087,193,4.614,1195,6.224,1228,8.907,1308,5.34,2581,5.473,2619,5.105,4942,7.361,5474,10.57,5475,10.57,5476,10.57,5477,10.57,5478,10.57]],["t/1132",[118,4.78,489,3.664,598,6.288,781,3.241,993,4.236]],["t/1134",[118,4.197,489,3.752,781,2.846,993,4.338,5479,9.2]],["t/1136",[118,4.197,489,3.752,781,2.846,993,4.338,2353,6.858]],["t/1138",[118,4.197,489,3.752,781,2.846,993,4.338,1733,9.762]],["t/1140",[118,4.197,489,3.752,781,2.846,993,4.338,4264,9.762]],["t/1142",[118,4.78,151,7.53,489,3.664,781,3.241,993,4.236]],["t/1144",[44,1.633,73,2.733,136,4.102,172,2.125,219,3.031,243,2.982,412,3.132,474,3.384,488,3.098,781,2.324,822,3.681,834,3.427,885,5.408,957,3.483,1019,4.258,1278,4.85,1559,7.068,1842,6.757,3028,5.623,3067,6.031,3640,7.361,4655,8.513,5184,6.903,5480,11.496,5481,8.513,5482,9.185,5483,9.185,5484,9.185,5485,11.496,5486,9.185]],["t/1146",[44,2.454,144,4.554,146,6.575,147,7.483,148,3.012,151,5.877,156,2.572,157,6.213,180,2.595,218,2.817,243,2.094,391,2.304,437,5.139,470,2.473,510,2.358,646,5.255,748,3.092,942,5.966,976,5.108,1118,5.301,1418,3.271,1945,6.571,2954,5.824,5487,8.073,5488,6.803,5489,8.073,5490,8.073,5491,8.073,5492,8.073,5493,10.585,5494,10.585,5495,9.81,5496,8.073,5497,8.073]],["t/1148",[118,4.197,438,6.239,489,3.752,781,2.846,993,4.338]],["t/1150",[1,0.755,7,1.685,21,0.493,22,0.653,30,1.052,44,2.449,83,1.305,84,0.862,87,0.589,94,0.579,117,0.564,128,0.788,139,1.512,145,0.968,148,0.438,156,1.249,164,0.701,168,0.572,170,1.664,188,0.862,203,0.756,208,0.91,211,1.141,213,1.816,226,3.59,227,1.03,240,0.39,243,0.445,258,2.746,259,1.246,264,0.8,266,1.327,267,1.259,276,0.833,287,0.835,304,0.96,391,0.49,411,2.506,438,1.483,443,5.057,462,0.984,469,0.976,470,0.526,553,0.912,555,1.526,557,0.634,575,0.703,597,0.662,610,0.852,611,1.295,619,0.781,621,0.501,626,4.268,697,0.808,720,1.142,748,1.183,757,2.032,781,1.301,875,1.911,891,0.838,908,1.555,993,2.548,997,0.611,1018,1.112,1029,0.976,1070,0.862,1092,1.238,1146,1.619,1203,0.96,1204,0.701,1211,0.723,1331,0.693,1344,0.953,1351,1.051,1421,2.51,1465,1.392,1596,0.634,1618,0.685,1722,0.792,1775,1.397,1807,1.491,1866,1.238,1873,1.127,1914,0.857,1958,0.932,2003,1.159,2425,0.932,2832,1.397,3345,1.051,3359,2.055,3880,1.446,4662,2.32,5498,0.867,5499,1.446,5500,3.087,5501,1.508,5502,1.591,5503,1.591,5504,1.591,5505,11.775,5506,11.405,5507,3.9,5508,1.591,5509,1.591,5510,1.591,5511,1.591,5512,1.591,5513,3.9,5514,1.591,5515,9.306,5516,2.862,5517,1.591,5518,11.405,5519,1.591,5520,1.591,5521,1.591,5522,1.591,5523,8.564,5524,1.591,5525,1.591,5526,1.591,5527,1.591,5528,1.591,5529,8.835,5530,1.591,5531,7.141,5532,9.701,5533,3.9,5534,3.9,5535,1.591,5536,1.591,5537,1.591,5538,1.591,5539,1.591,5540,1.591,5541,1.591,5542,1.591,5543,1.591,5544,1.591,5545,1.591,5546,1.591,5547,1.591,5548,1.591,5549,1.591,5550,1.263,5551,1.591,5552,1.591,5553,1.591,5554,2.602,5555,1.508,5556,1.591,5557,1.716,5558,1.591,5559,1.591,5560,11.256,5561,1.591,5562,1.591,5563,1.321,5564,1.508,5565,10.904,5566,1.591,5567,1.591,5568,1.591,5569,1.591,5570,1.508,5571,1.591,5572,1.591,5573,1.591,5574,1.508,5575,1.591,5576,3.9,5577,1.591,5578,1.591,5579,3.9,5580,1.591,5581,1.591,5582,1.591,5583,1.591,5584,1.591,5585,1.591,5586,1.591,5587,1.591,5588,1.591,5589,1.591,5590,1.591,5591,1.591,5592,6.123,5593,1.591,5594,1.591,5595,1.591,5596,1.591,5597,1.591,5598,1.591,5599,1.591,5600,1.591,5601,1.591,5602,1.591,5603,1.591,5604,8.265,5605,1.591,5606,1.591,5607,1.591,5608,1.591,5609,1.591,5610,1.591,5611,1.591,5612,1.591,5613,4.765,5614,1.591,5615,1.591,5616,1.591,5617,1.591,5618,1.591,5619,1.591,5620,1.591,5621,1.591,5622,1.591,5623,1.591,5624,1.591,5625,1.591,5626,1.591,5627,1.591,5628,1.591,5629,1.591,5630,1.591,5631,1.591,5632,1.591,5633,1.591,5634,1.591,5635,1.591,5636,1.591,5637,1.591,5638,1.591,5639,1.591,5640,1.591,5641,1.591,5642,1.591,5643,1.716]],["t/1153",[118,4.78,489,3.664,781,3.241,993,4.236,5644,11.428]],["t/1156",[117,1.348,148,2.851,164,3.585,168,4.457,172,2.032,240,2.937,263,2.73,414,3.763,914,3.805,998,2.577,1049,5.036,2016,7.152,5645,8.782,5646,8.782,5647,12.293,5648,8.782,5649,9.417,5650,8.782]],["t/1159",[10,2.699,44,2.537,73,1.455,83,0.966,117,0.536,166,2.456,240,1.11,243,2.325,489,1.631,490,2.011,756,2.313,781,1.237,923,1.948,957,3.795,1131,4.977,1596,3.313,1773,2.636,2174,4.372,5651,4.89,5652,4.89,5653,4.89,5654,14.001,5655,4.89,5656,4.89,5657,4.89,5658,4.89,5659,4.89,5660,4.89,5661,4.89,5662,4.89,5663,4.89,5664,6.876,5665,4.89,5666,4.89,5667,4.89,5668,4.89,5669,4.89,5670,4.89,5671,4.89,5672,4.89,5673,4.89,5674,4.89,5675,4.89,5676,7.419,5677,4.89,5678,4.89,5679,4.89,5680,7.419,5681,4.89,5682,4.89,5683,4.89,5684,4.89,5685,4.89,5686,4.89,5687,4.532,5688,8.964,5689,4.89,5690,4.89,5691,4.89,5692,4.89,5693,4.89,5694,4.89,5695,4.89,5696,4.89,5697,8.308,5698,4.89,5699,4.89,5700,4.532,5701,4.532,5702,4.89,5703,4.89,5704,4.89,5705,4.89,5706,4.89,5707,4.89,5708,4.89,5709,4.89,5710,4.89,5711,4.89,5712,4.89,5713,4.89,5714,4.89,5715,4.89,5716,4.89,5717,4.89,5718,4.89,5719,4.89,5720,4.89,5721,4.89,5722,4.89,5723,4.89,5724,4.89,5725,4.89,5726,4.89,5727,4.89,5728,4.89,5729,4.89,5730,4.89,5731,4.89]],["t/1161",[30,0.868,41,1.911,44,1.791,96,1.669,117,0.898,138,1.308,148,1.081,151,2.354,166,2.129,172,0.981,180,1.362,194,1.602,213,2.867,240,2.287,350,3.81,437,2.058,483,3.53,490,1.744,491,1.814,538,1.345,607,1.822,621,1.941,646,2.104,681,2.981,781,2.073,871,2.354,888,2.354,942,2.142,957,1.608,1003,4.835,1109,2.714,1271,2.224,1396,2.411,1457,2.452,1519,2.391,1618,3.273,1778,3.127,1805,5.617,1925,6.029,1941,3.058,1966,2.142,2260,1.885,2261,2.905,2262,3.262,2416,4.423,2496,4.363,2505,5.25,2830,3.186,2978,3.262,3467,3.725,3511,2.209,4074,3.725,4349,3.45,4858,3.186,5184,6.159,5664,3.929,5687,3.929,5697,3.929,5701,3.929,5732,8.195,5733,4.239,5734,4.239,5735,4.239,5736,4.239,5737,4.239,5738,4.239,5739,4.239,5740,4.239,5741,4.239,5742,4.239,5743,4.239,5744,4.239,5745,4.239,5746,4.239,5747,4.239,5748,4.239,5749,4.239,5750,4.239,5751,6.645,5752,4.239,5753,3.725,5754,4.239,5755,4.239,5756,4.239,5757,4.239,5758,6.159,5759,4.239,5760,4.239,5761,4.239,5762,4.239,5763,4.239,5764,4.239,5765,12.404,5766,6.645,5767,12.404,5768,4.239,5769,12.404,5770,4.239,5771,6.645,5772,4.239,5773,4.239,5774,6.645,5775,4.239,5776,4.239,5777,6.645,5778,4.239,5779,4.239,5780,6.645,5781,4.239,5782,4.239,5783,6.645,5784,4.239,5785,4.239,5786,6.645,5787,4.239,5788,4.239,5789,6.645,5790,4.239,5791,4.239,5792,6.645,5793,4.239,5794,4.239,5795,6.645,5796,4.239,5797,6.645,5798,4.239,5799,4.239,5800,3.725,5801,3.725,5802,3.929,5803,4.239,5804,4.239]],["t/1163",[44,2.625,243,2.156,266,3.572,291,4.652,957,3.153,1987,4.767,4972,11.828,4973,12.175,4975,7.705,4976,7.705,4977,7.705,4978,9.999,4979,7.705,4981,7.705,5805,8.313,5806,8.313,5807,8.313,5808,8.313,5809,8.313,5810,8.313]],["t/1165",[10,1.254,12,2.919,21,0.99,30,1.687,43,1.199,44,2.329,47,1.239,74,2.181,83,0.681,85,0.975,87,2.826,95,2.128,96,2.217,97,2.803,117,1.068,137,1.407,139,2.099,145,1.944,148,2.486,164,1.407,172,1.907,180,2.294,203,2.482,240,2.592,243,2.137,245,1.352,259,1.062,262,1.606,263,1.072,267,1.379,287,0.933,406,1.711,412,1.175,482,3.057,483,1.311,492,1.362,533,2.327,552,1.711,555,1.25,557,1.274,562,2.299,573,1.976,579,1.274,607,1.544,612,1.007,614,3.606,619,1.568,620,3.278,621,1.644,626,1.32,639,3.696,660,2.409,679,4.163,740,1.583,744,1.832,762,3.859,775,1.009,781,2.888,796,1.647,809,2.683,831,1.683,840,1.858,867,2.203,873,1.785,875,1.814,907,3.859,908,2.081,912,1.622,923,1.875,954,2.486,959,6.788,963,2.068,971,1.832,985,1.033,987,1.231,1002,2.294,1031,2.011,1049,1.976,1055,1.299,1245,2.048,1266,2.133,1399,1.683,1439,2.089,1444,2.805,1615,1.796,1727,2.535,1736,2.805,1774,2.181,1841,2.068,1896,1.944,1926,1.845,1967,2.811,2171,1.469,2192,1.929,2271,2.764,2277,3.195,2278,4.283,2519,2.207,2769,2.4,2770,1.481,3098,2.068,3256,1.665,3503,2.441,3511,4.734,3634,4.947,3660,6.615,3671,3.412,3701,1.96,3923,2.805,4070,2.207,4746,2.133,5055,3.028,5800,4.947,5802,3.195,5811,3.447,5812,3.447,5813,3.447,5814,3.447,5815,5.63,5816,3.447,5817,3.447,5818,3.447,5819,3.447,5820,3.447,5821,4.947,5822,5.63,5823,3.447,5824,5.63,5825,3.447,5826,3.447,5827,5.63,5828,5.218,5829,3.447,5830,3.447,5831,3.447,5832,2.294,5833,3.447,5834,3.447,5835,3.028,5836,5.63,5837,5.63,5838,3.447,5839,3.028,5840,10.284,5841,3.447,5842,5.218,5843,3.447,5844,3.028,5845,5.63,5846,3.447]],["t/1167",[10,0.952,30,0.535,44,2.567,87,0.897,97,0.807,117,0.49,126,3.042,148,2.635,153,1.476,156,0.636,172,1.603,178,1.264,179,1.541,186,1.06,196,2.327,229,0.892,235,1.257,240,2.481,297,2.037,339,2.025,412,2.362,445,1.421,479,3.441,520,1.355,521,1.129,579,0.967,586,1.174,615,2.144,617,3.658,620,3.181,626,1.713,641,1.741,645,1.853,659,2.25,660,1.12,663,1.134,679,1.322,697,4.263,718,6.42,719,5.157,732,0.824,756,2.115,762,4.013,781,1.969,783,1.655,834,0.976,866,1.163,867,0.807,873,3.032,888,2.483,901,4.626,903,5.365,905,2.067,906,1.306,921,5.145,942,2.259,957,0.992,1127,3.705,1159,2.33,1162,1.513,1218,1.373,1547,1.373,1647,2.609,1727,1.588,1734,1.284,1808,1.887,1904,1.322,1925,1.925,1934,3.226,1975,2.013,2239,2.767,2304,3.094,2321,2.863,2662,1.476,3809,1.887,4377,3.64,4955,5.206,5038,8.342,5043,2.425,5054,4.144,5055,3.929,5056,3.929,5847,2.616,5848,2.616,5849,2.616,5850,5.855,5851,6.927,5852,4.471,5853,2.616,5854,2.616,5855,6.927,5856,2.616,5857,2.616,5858,5.855,5859,6.927,5860,4.471,5861,2.616,5862,2.616,5863,2.205,5864,4.471,5865,4.471,5866,4.471,5867,5.855,5868,4.471,5869,4.471,5870,2.616,5871,4.471,5872,4.471,5873,7.782,5874,4.471,5875,4.471,5876,4.471,5877,2.616,5878,4.471,5879,4.471,5880,4.144,5881,4.471,5882,4.471,5883,4.471,5884,4.471,5885,7.782,5886,4.471,5887,4.471,5888,4.471,5889,2.616,5890,2.616,5891,2.299,5892,5.855,5893,2.616,5894,2.425,5895,5.855,5896,1.793,5897,2.425,5898,3.929,5899,2.425,5900,2.616,5901,2.425,5902,2.425,5903,2.616,5904,4.144,5905,5.855,5906,5.855,5907,5.855,5908,4.471,5909,5.855,5910,4.471,5911,4.471,5912,6.927]],["t/1169",[43,2.2,44,2.317,97,2.765,117,1.241,172,2.408,180,2.033,218,2.207,227,3.795,240,2.362,243,2.324,297,1.86,339,2.864,423,5.054,470,1.937,480,7.079,492,3.54,552,3.14,756,4.238,781,2.267,787,2.652,867,1.952,886,3.511,923,1.661,957,4.531,1070,3.176,1170,2.695,1457,3.658,1596,2.337,1612,4.582,1945,7.293,4780,4.562,4880,4.653,5060,7.551,5184,4.754,5913,10.406,5914,8.96,5915,6.324,5916,8.96,5917,6.324,5918,6.324,5919,6.324,5920,6.324,5921,6.324,5922,6.324,5923,6.324,5924,6.324,5925,6.324,5926,6.324,5927,6.324,5928,6.324,5929,6.324,5930,6.324,5931,6.324,5932,6.324,5933,6.324,5934,6.324,5935,6.324,5936,6.324,5937,6.324,5938,6.324,5939,6.324,5940,6.324,5941,6.324,5942,6.324,5943,6.324,5944,6.324,5945,6.324,5946,6.324,5947,6.324,5948,6.324,5949,6.324]],["t/1171",[118,4.78,489,3.664,781,3.241,993,4.236,3511,7.068]],["t/1174",[44,1.747,80,6.386,621,2.87,723,5.956,906,4.908,1734,4.825,2061,7.09,2591,6.962,2861,6.081,3086,6.845,3672,6.542,4534,7.231,5950,6.081,5951,9.11,5952,9.11,5953,9.11,5954,11.111,5955,11.988,5956,9.829,5957,8.283]],["t/1176",[44,1.747,80,6.386,621,2.87,723,5.956,906,4.908,1734,4.825,2061,7.09,2591,6.962,2861,6.081,3086,6.845,3672,6.542,4534,7.231,4713,5.787,5951,9.11,5952,9.11,5953,9.11,5954,11.111,5957,8.283,5958,11.988,5959,9.829]],["t/1178",[210,3.497,240,2.4,483,4.022,529,3.699,775,3.094,985,3.754,1008,4.381,1062,4.786,1071,5.509,1187,5.078,1415,7.136,2171,5.337]],["t/1180",[44,1.984,243,2.894,5821,9.805,5960,11.159,5961,10.343,5962,11.159,5963,11.159]],["t/1182",[44,1.984,243,2.894,486,5.007,5821,9.805,5961,10.343,5964,11.159,5965,11.159]],["t/1184",[5,0.895,30,0.855,38,1.534,41,1.882,44,1.888,73,1.954,86,1.27,94,2.215,97,1.289,115,2.265,117,1.164,118,1.558,123,2.022,146,2.191,148,2.834,156,2.581,168,1.393,172,1.52,180,2.957,181,4.702,187,1.353,193,3.39,211,1.543,243,1.703,297,1.228,391,1.192,403,2.779,412,1.424,414,1.781,420,2.267,473,1.931,474,1.538,526,1.558,538,2.083,560,2.87,562,2.681,576,1.349,579,1.543,612,1.22,645,3.814,666,4.386,719,2.92,732,1.315,740,1.918,744,2.22,759,1.918,781,1.661,801,4.063,805,3.299,809,1.36,814,1.408,819,2.531,875,1.346,877,2.337,891,2.039,908,2.427,957,3.078,978,1.318,985,3.907,987,1.492,1003,2.176,1008,1.731,1013,1.975,1170,2.799,1204,1.705,1211,2.765,1213,2.337,1618,3.241,1647,2.437,1722,1.927,1727,1.483,1732,2.122,1808,3.012,1838,2.437,1966,2.11,1975,5.053,2033,2.819,2171,4.526,2180,3.548,2192,5.149,2230,1.865,2275,3.562,2321,4.204,2353,4.286,2619,2.017,3208,2.742,3252,4.439,3511,5.213,3703,3.519,3714,3.519,3795,3.519,4746,6.189,4825,3.139,5122,3.87,5800,3.669,5966,8.116,5967,8.116,5968,4.176,5969,4.176,5970,4.176,5971,4.176,5972,6.567,5973,9.201,5974,6.567,5975,6.567]],["t/1186",[118,5.129,489,3.788,781,3.406,993,4.796,1518,8.465,3665,8.45,3675,9.421,5976,12.438]],["t/1188",[33,4.467,117,0.885,118,3.012,122,3.296,148,2.059,243,2.094,287,2.185,402,3.135,463,2.753,470,2.473,489,2.693,525,4.008,607,2.213,781,2.988,912,3.799,986,5.301,993,3.113,1055,3.042,1159,4.207,1607,3.212,1668,9.062,1753,5.255,1829,3.321,1896,4.554,2130,8.23,2716,10.281,2718,6.571,3665,6.953,3810,4.591,4962,7.094,5977,7.094,5978,8.073,5979,8.073]],["t/1190",[118,4.197,489,3.752,781,2.846,993,4.338,5980,10.572]],["t/1192",[118,4.78,489,3.664,781,3.241,993,4.236,2910,9.026]],["t/1195",[489,3.814,781,2.892,5981,9.634,5982,11.433]],["t/1197",[118,4.131,489,3.693,781,2.801,993,4.269,2965,7.318,5981,10.844]],["t/1199",[85,2.379,96,3.312,97,2.596,116,3.901,117,1.445,123,2.59,163,3.999,169,3.827,180,3.871,187,2.725,218,2.935,240,2.468,391,2.401,411,2.787,457,3.775,511,3.827,538,2.669,560,3.676,819,5.098,923,2.209,953,5.219,985,3.952,1896,4.745,1949,7.016,3508,6.847,5983,11.802,5984,7.392]],["t/1201",[44,2.418,73,3.009,220,4.884,414,2.742,719,4.497,875,3.258,1003,5.27,1734,4.964,1949,6.721,4743,7.042,5985,10.112,5986,13.097,5987,8.886,5988,8.886]],["t/1203",[44,2.178,73,3.031,79,5.792,146,5.343,869,5.745,875,3.282,1003,7.104,1949,6.75,4743,7.093,5987,10.764,5988,10.764,5989,10.186]],["t/1205",[44,2.15,172,2.307,187,3.229,196,2.981,267,2.442,463,3.4,1003,6.302,1766,6.832,1949,6.663,5184,7.493,5980,8.114,5987,10.625,5988,10.625,5990,9.969,5991,9.969,5992,9.969,5993,9.969]],["t/1207",[21,3.232,196,3.364,203,4.958,648,5.98,908,4.157,5994,11.249]],["t/1209",[117,1.367,179,6.177,240,2.382,296,2.773,411,2.428,538,3.956,626,4.018,781,2.654,985,3.144,1009,3.737,3669,8.841,5995,10.491,5996,10.491]],["t/1211",[118,4.78,489,3.664,781,3.241,993,4.236,1387,9.783]],["t/1213",[6,3.186,44,1.583,50,4.116,73,2.65,83,1.758,87,2.15,117,1.135,123,1.93,148,1.599,156,1.523,172,1.45,180,2.014,194,2.369,196,1.874,218,2.187,240,2.021,351,4.8,411,2.06,412,2.138,483,2.385,495,5.188,510,1.83,526,4.852,538,1.989,607,1.718,666,2.588,697,2.95,781,2.252,820,2.239,886,4.943,914,2.716,953,2.716,957,3.376,976,3.966,985,2.669,991,2.751,1025,3.13,1159,3.266,1204,3.635,1231,3.043,1281,4.869,1300,3.878,1380,4.232,1599,4.276,1618,3.555,1866,4.521,1942,7.522,1952,3.69,2059,3.403,2271,3.077,2440,2.704,3321,4.952,4395,7.247,4396,7.247,4743,4.365,4744,8.252,4745,5.809,4878,5.809,5030,4.952,5184,4.711,5997,4.952,5998,8.903,5999,6.268,6000,6.268,6001,6.268]],["t/1215",[411,2.624,538,3.598,626,4.344,1734,5.567,6002,10.511]],["t/1217",[21,2.695,73,2.009,117,1.277,148,3.38,150,5.408,164,2.756,172,2.171,196,3.223,211,2.495,214,2.356,219,2.228,235,3.243,243,2.796,338,3.278,339,4.881,473,1.985,626,2.586,688,8.251,737,3.071,781,2.727,796,3.226,809,3.054,923,1.773,957,3.557,978,2.131,998,1.981,1031,3.939,1399,5.262,1421,3.296,1734,4.605,1790,3.071,1819,3.639,2522,4.782,2581,6.032,2851,4.967,2907,4.271,5158,5.932,5160,9.816,6003,6.751,6004,9.38,6005,9.38,6006,9.38,6007,9.38,6008,6.751,6009,6.751]],["t/1219",[21,2.432,30,1.732,87,3.743,118,4.072,180,2.72,240,1.921,296,2.237,339,3.832,391,3.642,411,1.958,412,2.886,486,3.797,781,3.056,796,4.044,834,3.158,985,3.825,1082,5.078,1120,4.595,1547,5.725,1607,3.368,1612,4.328,1910,4.983,2059,4.595,2440,5.937,4261,6.313,4262,6.368,4294,5.995,4627,5.995]],["t/1221",[21,3.232,196,3.364,203,4.958,648,5.98,908,4.157,6010,11.249]],["t/1224",[7,2.799,12,2.848,21,1.38,30,0.582,33,2.909,36,2.626,41,1.282,44,1.576,47,1.725,48,1.105,72,1.572,73,1.429,78,3.674,80,3.074,86,0.865,94,2.467,96,1.12,115,3.057,117,1.034,118,2.324,145,2.708,148,2.721,153,2.708,155,1.455,160,5.152,164,2.543,169,4.032,172,1.111,180,4.082,186,2.524,187,2.871,194,1.075,211,1.051,214,0.993,218,4.204,235,1.367,239,1.346,240,0.646,245,1.883,249,2.874,250,1.14,268,2.801,296,0.752,391,2.088,411,2.051,414,1.302,452,2.154,470,1.908,490,1.975,510,0.831,520,3.225,529,0.996,552,1.412,576,0.919,607,0.78,613,1.421,618,2.626,621,2.136,646,2.383,719,2.135,753,2.582,759,1.306,781,2.067,796,1.359,820,1.715,866,1.265,908,1.051,914,2.08,923,0.747,942,2.425,955,1.203,957,1.821,985,3.44,991,3.211,998,0.835,1004,3.074,1027,3.003,1083,1.724,1120,4.437,1177,2.427,1204,1.161,1273,1.112,1393,3.038,1396,1.618,1443,1.198,1488,3.463,1518,1.844,1521,1.618,1547,3.267,1599,1.982,1615,2.502,1618,1.136,1727,1.705,1874,1.66,1910,1.675,1914,2.397,1915,2.052,1949,4.503,1952,2.827,2059,5.381,2119,3.908,2260,1.265,2263,1.306,2278,1.707,2288,2.666,2357,2.777,2440,1.227,2592,2.316,2662,1.605,3085,2.316,3236,3.038,3505,3.463,4085,2.052,4261,1.645,4262,1.66,4315,3.463,4332,3.793,4336,1.742,4457,5.366,4743,1.981,5096,7.292,5983,2.637,6011,4.046,6012,2.845,6013,2.845,6014,4.218,6015,7.316,6016,6.228,6017,2.845,6018,7.316,6019,4.801,6020,3.908,6021,4.218,6022,4.801,6023,6.781,6024,2.845,6025,2.845,6026,2.845,6027,2.5]],["t/1226",[5,0.814,20,1.714,33,3.136,43,2.121,73,1.814,90,1.396,115,1.311,116,1.763,117,1.118,122,3.9,167,2.162,172,0.88,179,2.239,180,1.222,193,1.401,218,2.662,239,1.798,243,2.264,266,1.634,419,3.487,470,1.165,473,1.118,524,2.218,542,2.531,545,9.076,551,2.926,553,2.021,557,2.82,626,1.456,634,3.589,775,2.233,781,0.962,867,1.881,871,2.111,914,1.647,923,0.999,957,1.442,985,1.14,988,7.355,998,1.116,1009,3.632,1116,5.356,1205,1.73,1278,3.219,1382,2.648,1443,4.835,1455,6.33,1475,3.951,1481,7.547,1581,3.204,1625,3.524,1678,1.91,1698,2.304,1727,2.709,1750,2.199,2123,2.26,2165,2.497,2171,3.252,2313,5.525,2478,2.035,2550,4.961,2770,2.619,2789,5.658,2900,2.434,2907,2.406,2965,3.466,3157,2.858,3256,3.685,3268,7.355,3607,7.127,3653,4.691,3657,2.531,3668,3.004,3672,2.531,4085,2.743,4171,4.961,4261,2.199,4262,2.218,4271,5.356,4280,2.797,4281,8.855,4282,4.318,4291,8.09,4713,3.589,6028,3.802,6029,7.776,6030,3.802,6031,3.802,6032,7.669,6033,9.553,6034,3.802,6035,3.802,6036,3.802,6037,6.096,6038,3.802,6039,3.802,6040,3.802,6041,3.802,6042,6.096,6043,5.735,6044,3.802,6045,3.341,6046,3.802,6047,6.096,6048,3.802,6049,6.096,6050,6.096,6051,3.802,6052,3.802,6053,3.524,6054,3.802,6055,3.802,6056,3.524]],["t/1228",[1,2.685,118,4.78,250,4.402,670,4.906,679,5.55,908,4.059,1185,6.353,2152,6.099]],["t/1230",[118,4.802,181,4.901,250,4.437,670,4.945,679,5.593,908,4.092,1185,6.403]],["t/1232",[5,1.626,72,2.485,78,5.104,87,3.485,94,2.561,146,3.983,148,1.937,180,3.266,211,2.806,249,3.503,267,1.86,391,2.9,411,2.352,414,3.458,415,6.288,421,3.816,422,6.443,552,5.687,696,5.585,802,2.626,809,2.472,985,3.667,987,3.631,998,2.982,1120,6.642,1218,3.983,1357,9.05,1475,7.425,1478,5.44,1607,3.021,1790,4.623,5005,6.18,6011,8.564,6057,5.998]],["t/1234",[5,1.471,7,1.373,12,2.562,28,3.43,30,1.101,33,2.616,41,1.47,43,1.135,44,0.58,72,3.436,78,4.003,85,0.923,86,1.637,94,2.975,103,2.115,115,3.042,117,1.331,123,1.657,138,1.007,146,1.711,148,1.373,150,1.357,156,1.308,160,1.629,163,1.551,167,3.06,168,1.088,172,2.041,180,2.208,193,1.202,219,1.076,221,1.559,227,1.957,229,1.835,238,1.887,245,1.28,248,3.73,249,3.17,262,1.52,263,1.014,267,1.318,338,2.613,412,1.113,414,1.863,415,4.25,421,2.021,492,1.289,510,0.953,525,2.672,538,1.035,552,1.619,555,1.183,558,2.452,576,1.054,607,0.894,621,0.953,639,1.689,663,1.413,666,1.347,671,1.61,732,1.694,759,2.471,769,6.539,775,0.955,781,1.738,809,1.062,814,3.669,817,2.881,821,3.688,830,1.903,834,1.217,866,1.451,867,1.007,868,2.642,906,1.629,908,1.206,914,1.413,923,1.413,985,2.846,987,1.165,988,2.749,998,0.957,999,2.577,1002,2.171,1008,3.304,1009,2.447,1013,3.249,1029,1.855,1036,1.784,1062,1.477,1064,2.018,1066,1.61,1070,1.638,1097,2.205,1121,2.311,1177,1.082,1232,2.452,1307,1.771,1357,4.252,1399,1.593,1431,3.216,1475,2.115,1477,1.689,1485,2.115,1607,1.298,1612,1.668,1615,1.7,1734,2.642,1749,1.887,1753,2.672,1790,1.484,1829,1.342,1838,6.124,1866,2.353,1954,1.689,1957,3.446,1975,2.51,1988,1.194,2018,2.672,2059,2.922,2072,1.903,2105,2.577,2144,2.922,2180,1.258,2278,1.957,2281,2.041,2316,1.47,2425,1.771,2440,1.408,2581,1.689,2760,2.353,2770,1.402,2771,2.272,2813,3.446,2934,1.871,3635,4.38,3653,4.141,3714,5.789,3932,2.202,4070,3.446,4100,2.089,4685,7.31,4774,2.866,4822,2.452,5002,3.024,5005,2.655,5230,4.729,5244,2.655,5250,2.749,6058,3.262,6059,3.262,6060,3.262,6061,6.869,6062,3.262,6063,3.262,6064,3.024,6065,3.262,6066,3.262,6067,9.494,6068,2.749,6069,5.382,6070,3.262,6071,3.262,6072,5.382,6073,3.262,6074,3.262,6075,3.262]],["t/1236",[12,2.279,21,2.038,30,1.986,72,2.322,73,2.111,75,3.823,78,3.562,87,3.794,94,2.392,115,3.347,117,1.366,118,2.646,136,4.335,249,3.273,267,1.737,296,1.875,391,2.024,411,2.753,415,4.388,552,4.818,575,3.977,576,2.291,666,2.929,760,3.425,781,3.009,796,3.389,869,4.001,891,3.463,985,4.124,1004,3.501,1097,2.906,1151,4.067,1265,4.541,1352,4.657,1521,4.033,1547,3.721,1599,2.929,1607,2.822,1714,4.598,1734,3.482,1896,4.001,1910,4.176,1954,3.673,2059,3.851,2060,3.583,4294,9.328,4881,5.977]],["t/1238",[72,3.596,79,6.246,80,5.422,81,7.006,102,7.528,121,9.652,694,5.362,6076,10.984]],["t/1240",[5,1.28,7,1.524,27,4.155,30,1.223,44,1.062,73,3,87,4.61,97,2.655,117,0.943,118,2.229,123,2.648,156,2.45,180,1.92,186,3.486,187,3.266,229,2.037,411,1.382,552,2.966,557,2.208,579,3.179,639,5.22,679,3.018,693,3.486,694,4.922,753,3.566,754,7.021,756,2.825,781,3.401,785,3.074,914,2.588,923,2.259,985,1.791,998,1.753,1004,5.77,1009,2.128,1011,3.113,1170,3.666,1249,3.134,1609,3.036,1618,2.386,1647,3.486,1727,2.121,2260,2.656,2813,3.825,2879,4.231,3498,4.231,3505,4.309,4294,4.231,4336,3.657,4813,5.249,4814,7.002,4823,5.537,4880,6.329,4883,9.344,4945,5.537,5031,4.72,6077,5.974,6078,5.974,6079,8.496,6080,5.974,6081,5.974,6082,5.974,6083,5.974,6084,8.603]],["t/1242",[21,1.978,22,2.619,44,1.224,83,1.877,117,0.755,118,2.568,123,2.119,180,4.478,218,4.862,220,6.156,240,2.472,391,3.352,398,2.536,411,1.593,521,2.97,524,6.854,607,1.887,626,2.637,955,2.91,1008,2.853,1599,2.842,2192,6.898,2403,7.465,2415,5.913,3027,5.174,3662,6.973,3695,8.013,3871,6.995,6085,7.739,6086,8.604,6087,9.178]],["t/1244",[21,2.729,33,3.117,44,1.688,83,1.875,118,3.543,150,3.951,168,3.168,172,2.197,219,3.133,240,2.664,271,3.498,296,3.102,391,3.35,398,3.498,654,3.848,796,4.538,978,2.997,985,3.518,1910,5.591,2059,6.917,2180,3.662,3505,6.85,6088,9.496]],["t/1246",[30,1.943,180,4.094,218,4.095,296,3.367,391,3.636,403,6.32,527,4.549,538,3.013,566,6.85,568,4.636,621,2.773,796,4.538,914,4.114,985,2.846,1211,3.998,1976,5.861,4266,6.32]],["t/1248",[83,1.941,87,3.371,148,2.507,180,3.853,218,4.183,240,2.231,296,3.419,297,2.891,391,2.805,411,2.274,567,8.283,607,2.695,697,4.625,748,3.765,781,2.487,1431,4.602,1909,7.675,4266,6.542,5980,8]],["t/1250",[5,1.869,21,2.508,22,3.321,44,1.552,83,1.723,118,3.256,150,3.631,180,4.382,218,4.758,220,5.919,240,1.981,271,3.215,391,3.177,524,5.092,626,3.343,1976,4.358,2192,4.883,3027,6.559,3680,7.152,4270,6.607,5038,9.446]],["t/1252",[1,2.412,21,1.653,31,3.778,33,1.888,72,3.23,73,1.712,78,4.205,86,3.001,96,3.296,115,4.47,117,0.631,118,2.147,123,3.038,128,2.642,163,2.735,168,1.919,180,3.172,187,3.197,203,2.536,240,1.9,249,2.655,271,2.119,391,2.389,397,3.357,402,2.234,405,3.56,406,2.856,411,2.781,414,1.56,500,5.332,526,2.147,533,3.884,552,2.856,557,2.126,576,1.859,607,1.577,612,1.68,744,3.059,756,2.721,775,1.684,796,2.749,822,2.306,868,2.824,885,3.387,891,2.809,923,1.511,985,3.884,989,3.299,999,4.545,1004,2.84,1009,2.049,1028,2.793,1035,3.327,1066,2.84,1070,2.889,1090,2.856,1120,3.124,1253,2.942,1265,3.683,1267,3.419,1302,3.419,1445,4.006,1547,3.018,1829,2.367,1896,3.245,1910,3.387,2144,3.124,2186,3.452,2506,3.778,2770,2.472,2771,5.83,2944,4.006,3236,3.64,3505,4.15,3611,3.357,3639,3.64,3855,4.15,4294,8.157,4648,4.545,4685,5.83,6089,5.753,6090,4.848]],["t/1254",[21,2.948,87,3.519,118,3.828,391,3.511,470,3.143,645,4.253,781,2.596,891,5.009,985,3.95,2331,6.282,4294,9.335,4847,10.811]],["t/1256",[7,3.098,12,3.227,21,0.937,30,0.668,44,1.417,72,1.762,78,2.703,80,2.657,81,1.784,96,1.284,113,1.903,117,1.286,123,1.657,148,0.832,150,1.357,153,1.84,155,4.076,156,0.793,160,5.968,164,1.332,172,2.593,175,2.572,179,1.921,180,1.73,187,1.057,190,1.61,196,0.975,198,2.657,203,4.795,214,1.138,235,3.3,240,0.741,243,0.846,248,2.922,249,1.505,263,1.673,266,1.402,267,1.318,291,3.011,411,2.324,412,1.113,414,0.885,421,2.021,470,0.999,474,1.202,505,2.881,510,0.953,520,1.689,528,1.567,529,1.142,579,1.206,607,1.883,615,1.194,622,3.627,645,1.352,648,1.734,659,2.068,663,2.332,732,1.027,739,1.977,748,2.631,753,3.935,775,2.011,781,0.825,819,1.977,820,2.454,833,2.311,866,2.393,877,3.844,887,2.018,923,1.413,953,2.332,957,2.605,959,2.272,977,2.311,985,3.146,996,7.179,1004,5.793,1056,1.903,1062,1.477,1098,2.901,1170,1.39,1189,2.202,1232,2.452,1347,2.115,1359,3.582,1488,2.353,1521,1.855,1596,1.989,1599,2.222,1601,2.171,1609,1.658,1615,1.7,1618,1.303,1777,3.488,1874,1.903,1914,1.629,1915,2.353,1957,2.089,2032,1.629,2033,3.633,2076,2.655,2230,3.56,2271,2.642,2300,1.825,2357,1.887,2363,2.115,2440,2.322,2476,2.272,2626,2.577,2690,2.452,3104,2.115,3236,2.064,3318,1.977,4822,4.045,4948,6.629,4949,3.024,6011,2.749,6091,8.462,6092,3.262,6093,6.968,6094,3.262,6095,5.789,6096,5.382,6097,5.382,6098,4.729,6099,3.262,6100,4.729,6101,4.988,6102,3.262,6103,3.262,6104,3.262,6105,6.869,6106,5.382,6107,3.262,6108,6.036,6109,3.024,6110,2.866,6111,5.382,6112,2.866]],["t/1258",[33,4.449,44,1.321,72,2.433,117,0.815,172,2.318,175,4.787,203,4.995,218,2.593,240,1.687,249,3.429,391,2.121,470,2.276,607,2.037,626,2.846,648,3.951,759,3.412,781,3.203,831,3.628,882,3.754,906,3.711,914,3.22,955,3.141,957,2.818,985,3.396,991,3.261,1097,3.045,1211,3.129,1227,4.649,1273,2.905,1341,5.467,1351,4.55,1431,3.48,1443,3.129,1773,4.006,1790,3.38,2060,3.754,2263,3.412,2440,4.322,2723,3.824,4948,5.585,5096,8.337,6091,6.262,6093,5.871,6095,6.262,6098,6.53,6100,6.53,6101,6.888,6113,6.888,6114,6.888,6115,7.431]],["t/1260",[44,1.601,72,2.949,94,3.038,117,0.987,172,2.628,175,5.427,203,5.482,411,2.628,607,2.469,648,4.789,914,3.903,957,3.416,985,3.404,1211,3.793,1227,5.635,1773,4.856,2059,6.166,2060,4.551,2440,3.886,4948,6.77,5096,8.355,6091,7.59,6093,8.972,6095,7.59,6098,7.915,6100,7.915,6113,8.349,6114,8.349]],["t/1262",[87,3.235,117,1.281,240,3.098,391,3.625,411,2.705,621,3.413,781,2.957,914,5.064,925,8.997,3498,6.681,6093,10.489,6116,10.703]],["t/1264",[7,2.312,44,1.612,96,3.569,117,0.994,150,3.772,160,6.229,172,2.098,180,2.914,203,5.026,250,3.633,268,5.29,411,2.887,618,4.958,734,4.922,914,3.928,955,3.832,985,3.923,1070,4.553,1417,5.388,1547,4.756,1952,5.338,2059,4.922,2060,4.58,4294,6.422,4822,6.814,4948,9.376]],["t/1267",[73,3.009,90,4.81,148,2.579,178,4.884,203,4.457,538,3.208,666,4.176,756,4.783,763,6.398,891,4.937,985,3.925,987,4.357,1008,4.192,1027,6.326,1873,6.64]],["t/1269",[90,3.882,148,2.696,172,2.446,180,4.025,203,4.659,985,3.754,1027,6.612,3037,7.308,6117,9.797,6118,10.57,6119,10.57]],["t/1271",[90,3.882,148,2.696,172,2.446,180,4.025,203,4.659,985,3.754,1027,6.612,2059,6.8,6117,9.797,6120,10.57,6121,10.57]],["t/1273",[44,2.352,87,3.55,97,2.408,117,1.135,123,2.402,148,1.991,156,2.515,180,2.508,210,3.425,218,2.723,520,4.041,526,2.912,719,3.47,775,2.284,781,2.618,873,4.041,942,5.229,961,6.889,968,7.233,985,2.339,1547,4.093,1601,6.889,1727,2.771,1753,5.138,2180,4.769,2288,4.333,2313,4.513,3653,7.965,6122,7.804,6123,10.067,6124,7.804,6125,7.804,6126,7.233,6127,7.804,6128,7.804,6129,6.352,6130,7.804,6131,7.804,6132,7.804,6133,7.804]],["t/1275",[44,2.267,180,3.503,218,3.803,240,2.474,411,2.522,2288,7.08,6134,10.899,6135,10.899]],["t/1277",[44,2.267,180,3.503,196,3.259,218,3.803,411,2.522,2288,7.08,6136,10.899,6137,10.899]],["t/1279",[44,2.297,91,3.641,115,2.722,117,0.865,180,3.351,181,5.5,187,2.556,218,3.638,240,1.791,268,4.605,473,2.321,759,4.788,871,4.382,985,4.118,1066,3.896,1273,3.085,1396,4.488,1477,4.086,1601,5.252,2288,6.484,2305,5.703,2357,6.031,4825,9.337,5096,10.107,6020,8.487,6138,6.235,6139,7.892]],["t/1282",[44,2.423,80,5.028,126,3.982,833,7.215,2062,5.957,2157,5.842,2634,6.981,3713,7.656,6140,10.186,6141,10.186,6142,10.186]],["t/1284",[3,4.822,33,3.833,44,1.403,117,0.865,122,3.222,172,2.875,180,3.993,218,4.335,220,5.036,243,2.047,267,1.933,391,2.976,955,3.336,957,3.954,991,3.463,1204,4.257,1471,3.918,2440,3.405,2467,6.197,2815,7.57,3665,4.646,3709,8.238,4880,5.806,5184,7.837,6143,5.59,6144,9.56,6145,10.824]],["t/1286",[3,1.574,5,1.873,11,1.315,30,0.78,38,1.4,43,2.125,44,1.554,47,1.37,73,1.135,83,0.753,85,1.078,87,2.095,91,1.759,94,1.286,95,2.889,96,1.501,116,1.768,117,0.958,118,1.422,126,1.49,139,1.121,168,1.272,177,1.742,180,4.363,193,1.404,198,1.882,214,1.33,218,4.28,229,1.3,235,2.935,240,2.317,267,0.934,296,1.008,391,3.438,489,1.272,504,2.085,530,1.673,533,2.574,538,2.773,557,1.409,560,1.666,575,1.562,607,1.045,645,1.58,694,1.861,697,2.875,753,5.165,756,1.803,759,1.751,775,1.116,781,2.212,796,1.822,814,1.286,820,1.362,822,2.448,867,1.177,906,1.904,914,3.788,955,1.612,957,1.446,969,1.904,977,2.7,978,1.203,987,1.362,1014,1.794,1035,2.205,1098,2.055,1159,1.987,1170,1.625,1204,1.556,1214,1.987,1245,5.195,1252,2.471,1265,2.441,1292,2.934,1396,2.168,1547,2,1584,2.503,1618,1.522,1791,1.904,1976,3.05,2059,2.07,2180,5.364,2353,2.013,2440,4.128,2490,2.266,2619,1.841,2760,2.75,2830,2.865,3511,1.987,3657,2.537,3678,3.341,4168,4.327,4503,4.124,4630,4.407,4648,3.012,4998,5.882,5146,2.865,5155,3.533,5250,3.213,5362,4.826,5644,5.148,6146,3.35,6147,3.533,6148,3.533,6149,3.812,6150,3.812,6151,3.812,6152,7.644,6153,3.812,6154,3.812,6155,3.812,6156,3.812,6157,3.812,6158,3.812,6159,6.109,6160,3.533]],["t/1288",[83,2.267,96,2.571,151,5.089,166,3.28,180,3.69,199,4.041,214,3.198,218,4.585,240,2.846,339,2.957,391,3.812,438,4.403,486,2.93,552,4.55,560,2.854,607,1.79,621,1.907,626,4.398,748,3.511,775,1.912,781,1.652,796,3.121,820,2.333,1431,4.292,1443,4.459,1607,2.599,1612,3.34,1618,3.66,1805,4.476,1966,3.299,1976,3.261,2180,5.151,2192,5.129,2415,4.976,2440,4.569,4858,4.909,4964,9.586]],["t/1290",[26,4.178,96,3.197,97,2.506,117,0.89,180,3.415,218,2.833,219,3.506,240,2.852,391,3.032,421,3.049,492,3.208,530,3.564,546,4.738,615,2.973,796,3.88,906,5.305,923,2.133,957,4.029,985,2.434,998,2.383,1091,4.544,1097,3.328,1326,7.135,1431,3.802,1618,4.243,2180,4.844,2288,4.509,3678,5.811,4964,7.526,6161,7.135,6162,7.135,6163,6.415,6164,8.12,6165,8.12,6166,8.12,6167,8.12,6168,8.12,6169,8.12,6170,8.12,6171,8.12]],["t/1292",[21,1.998,96,2.737,97,2.145,117,1.2,136,3.105,137,2.838,168,3.193,180,3.076,194,3.618,203,3.064,218,2.426,219,2.294,235,3.34,240,2.678,391,1.984,470,2.13,492,3.782,530,3.051,546,4.056,575,2.849,607,2.624,612,2.796,615,2.545,623,4.171,663,3.012,775,2.035,781,1.759,796,3.322,834,2.594,866,3.091,878,4.506,906,6.177,914,3.012,923,1.826,957,3.63,985,3.535,991,3.051,998,2.04,1049,3.986,1177,3.632,1618,2.776,2180,3.691,2288,3.86,2851,5.114,3678,6.765,6161,6.108,6162,6.108,6172,6.952,6173,6.952,6174,6.952,6175,6.952,6176,6.952,6177,6.952,6178,6.952,6179,6.952,6180,6.952,6181,6.952]],["t/1294",[1,1.248,5,1.971,6,2.594,7,1.302,17,2.25,21,1.467,22,1.942,24,2.505,71,3.308,83,2.357,84,2.563,117,1.121,118,1.904,139,1.501,151,5.108,177,2.333,180,4.524,187,1.653,196,1.526,210,2.535,218,4.848,220,6.065,240,2.088,263,2.86,297,1.501,391,2.625,398,1.88,411,1.773,414,2.972,438,4.419,463,1.741,492,2.016,524,2.978,598,4.265,652,2.414,796,2.439,809,1.662,914,3.32,997,1.818,1008,2.115,1109,3.268,1211,2.149,1294,4.032,1387,6.636,1829,3.152,1844,3.125,1988,1.868,2353,4.858,2440,3.306,2468,2.732,2581,3.968,2619,4.443,2815,2.812,2910,7.293,3027,3.836,3511,4.794,3603,4.154,3665,5.416,3931,4.848,6182,4.73,6183,4.73]],["t/1298",[30,1.266,44,1.827,117,0.678,180,3.303,186,2.506,218,3.077,262,2.882,339,5.364,350,5.057,412,3.822,421,2.323,671,4.354,705,4.461,723,7.464,775,1.81,809,2.014,814,2.974,834,2.308,985,1.854,1734,4.329,1776,3.223,2024,4.009,2263,5.44,2288,3.434,2359,5.399,2391,4.176,3068,6.787,3137,5.87,3632,7.179,3695,4.55,3701,3.517,5012,6.488,5421,4.886,5753,5.434,5898,9.032,6184,6.185,6185,10.279,6186,6.185,6187,5.434,6188,6.185,6189,6.185,6190,4.886,6191,6.185,6192,5.732,6193,6.185,6194,8.819,6195,8.819,6196,12.96,6197,11.847,6198,8.819,6199,6.185,6200,6.185,6201,8.819,6202,6.185,6203,8.819,6204,6.185,6205,6.185,6206,6.185]],["t/1300",[2263,5.992,6207,11.34,6208,11.34,6209,11.34]],["t/1302",[180,3.704,218,4.022,6210,11.527]],["t/1305",[3,5.2,44,1.3,285,3.267,339,3.312,412,4.763,427,3.611,482,3.972,620,3.359,834,2.729,1331,2.953,1818,4.268,2218,9.69,2275,5.698,2388,4.938,2467,4.347,3589,5.381,3701,4.16,4341,4.803,5038,5.181,5180,6.164,6211,7.315,6212,6.78,6213,6.78,6214,7.315,6215,7.315,6216,7.315,6217,7.315,6218,7.315,6219,6.78,6220,6.78,6221,7.315,6222,7.315,6223,7.315,6224,7.315,6225,7.315,6226,7.315,6227,7.315,6228,9.911,6229,7.315,6230,7.315,6231,7.315,6232,7.315,6233,7.315,6234,7.315,6235,7.315,6236,7.315,6237,7.315,6238,7.315,6239,7.315]],["t/1307",[44,1.968,350,6.349,2316,4.99,2388,7.475,5180,9.33,6220,10.261,6240,11.071,6241,11.071]],["t/1311",[43,1.961,44,2.668,117,0.618,123,1.735,151,3.13,180,1.812,218,1.967,263,1.753,495,2.364,524,3.289,598,2.614,626,3.736,663,2.443,796,2.694,1457,3.261,1733,4.237,1830,3.039,2192,7.881,2353,2.977,2619,2.723,2751,3.319,3036,3.451,3070,3.654,3071,3.018,3932,3.806,4264,4.237,4270,3.039,4673,4.953,4788,4.589,5060,4.751,5473,3.527,5479,3.993,6242,5.637,6243,7.645,6244,5.637,6245,5.637,6246,4.237]],["t/1315",[44,2.117,97,2.535,117,1.174,148,3.038,150,5.251,180,2.64,203,6.023,211,3.036,240,2.43,579,3.036,666,3.392,712,6.375,775,3.134,873,4.254,1196,5.721,1601,5.468,1648,7.219,1734,5.846,2180,3.168,2192,4.597,2490,6.363,2633,10.465,4471,8.041,6247,6.044,6248,11.909]],["t/1317",[6,0.937,7,0.25,21,0.282,30,0.201,38,1.434,44,2.67,47,0.352,97,0.303,117,0.107,148,1.49,150,1.085,156,1.083,163,1.856,172,0.227,178,0.89,180,0.838,181,1.729,188,1.31,196,0.293,203,0.812,214,0.643,218,0.91,240,0.747,263,1.936,320,0.525,338,0.476,412,1.122,421,0.368,470,0.565,474,0.361,486,3.596,495,0.773,521,0.423,524,5.882,526,1.228,564,1.075,615,0.675,617,0.973,619,2.657,620,2.279,626,0.999,645,0.764,670,2.421,681,0.44,697,3.53,732,0.309,740,0.45,753,0.406,759,4.571,764,2.301,775,0.539,814,0.622,834,1.851,873,3.224,877,3.683,903,0.62,942,0.495,961,0.652,973,0.672,985,0.986,994,0.6,1011,0.96,1075,1.508,1109,0.628,1125,0.464,1127,0.62,1205,0.446,1273,1.02,1331,1.576,1401,1.75,1402,0.588,1404,0.628,1465,2.237,1596,0.964,1601,2.599,1612,0.501,1727,1.925,1778,1.227,1791,1.302,1846,0.594,1904,0.931,1934,2.457,1942,0.567,1966,0.931,1988,0.675,2016,0.525,2018,0.487,2192,1.842,2240,0.613,2254,1.066,2275,4.116,2304,1.992,2316,2.01,2396,1.536,2429,0.628,2478,0.525,2760,1.329,2903,0.628,2962,0.826,3070,6.894,3071,5.693,3652,0.721,3662,1.67,3701,0.557,3741,1.153,3871,0.721,4301,0.737,4341,0.644,4429,0.694,4821,0.754,4822,0.737,4825,0.737,4826,0.798,4827,1.5,5100,2.417,5419,2.421,5421,0.774,5427,0.861,5429,9.456,5441,2.06,5459,2.417,5460,2.417,5894,0.909,5904,0.909,6023,1.708,6085,2.679,6086,1.456,6247,4.297,6249,0.98,6250,0.861,6251,0.98,6252,0.98,6253,0.98,6254,0.909,6255,0.98,6256,3.29,6257,1.843,6258,1.843,6259,2.608,6260,2.608,6261,2.608,6262,2.608,6263,0.98,6264,2.608,6265,1.843,6266,1.843,6267,1.843,6268,0.98,6269,0.98,6270,0.98,6271,0.98,6272,0.98,6273,1.843,6274,0.98,6275,0.98,6276,0.98,6277,0.98,6278,0.98,6279,0.98,6280,0.98,6281,0.98,6282,0.98,6283,0.98,6284,0.98,6285,0.98,6286,0.98,6287,0.98,6288,0.98,6289,0.98,6290,0.98,6291,0.98,6292,0.909,6293,0.98,6294,0.98,6295,0.98,6296,0.98,6297,0.98,6298,0.98,6299,0.98,6300,0.98,6301,0.98,6302,0.98,6303,0.98,6304,0.98,6305,0.98,6306,0.98,6307,0.98,6308,0.98,6309,0.98,6310,0.98,6311,0.98,6312,0.98,6313,0.98,6314,0.98,6315,0.98,6316,0.98,6317,0.98,6318,0.98,6319,0.98,6320,0.98,6321,0.98,6322,0.98,6323,0.98,6324,0.98,6325,0.98,6326,0.98,6327,0.98,6328,0.98,6329,3.291,6330,0.98,6331,0.98,6332,0.98,6333,0.98,6334,0.98,6335,0.909,6336,0.98,6337,0.98,6338,0.98,6339,0.98,6340,0.98,6341,0.98,6342,0.98,6343,0.98,6344,0.98,6345,0.98,6346,0.98,6347,1.843,6348,0.98,6349,0.98,6350,0.98,6351,0.98,6352,0.98,6353,0.98,6354,0.98,6355,0.98,6356,1.708,6357,2.608,6358,1.843,6359,0.98,6360,0.98,6361,0.98,6362,0.98,6363,0.98,6364,0.98,6365,0.98,6366,0.98]],["t/1319",[13,4.495,44,2.569,72,2.499,78,3.834,117,0.837,150,3.176,151,4.238,156,1.855,172,1.766,175,5.489,180,2.453,181,3.379,196,2.283,443,3.201,505,4.086,615,2.795,705,5.507,706,7.075,731,4.58,775,2.235,885,4.495,985,2.288,1589,4.775,1777,4.948,2275,3.35,2519,4.887,2861,4.723,4471,5.154,4955,5.738,6367,7.634,6368,10.199,6369,10.199,6370,7.634,6371,10.199,6372,7.634,6373,10.199,6374,10.199,6375,7.634,6376,7.634,6377,7.634,6378,6.213,6379,7.634,6380,7.634]],["t/1321",[17,2.624,44,2.401,117,0.653,150,1.536,167,4.88,180,1.186,181,4.875,213,1.593,296,2.268,338,4.885,412,2.03,438,1.773,621,1.078,671,2.939,796,3.575,802,2.059,834,3.512,985,3.577,998,1.747,1009,1.315,1019,3.979,1300,2.284,1612,3.825,1976,3.735,2118,2.034,2243,4.581,2275,4.833,2813,3.812,3071,5.386,3640,5.494,3668,2.917,4350,2.194,4955,4.474,5038,4.217,5444,7.949,5452,7.54,5844,3.244,6219,7.954,6381,8.581,6382,10.062,6383,3.692,6384,3.692,6385,3.692,6386,5.953,6387,5.953,6388,3.692,6389,5.953,6390,5.953,6391,3.692,6392,8.581,6393,4.474,6394,5.953,6395,5.953,6396,5.953,6397,5.953,6398,5.518,6399,5.953,6400,7.48,6401,5.953,6402,5.953,6403,5.953,6404,3.692,6405,3.692,6406,3.692,6407,3.692,6408,3.692,6409,3.692,6410,3.692,6411,3.692,6412,3.692,6413,7.48,6414,5.953,6415,3.692,6416,3.692,6417,3.692,6418,3.692,6419,3.692,6420,3.692,6421,3.692,6422,3.692,6423,3.692,6424,3.692,6425,3.692,6426,5.953,6427,3.692,6428,3.692,6429,3.692,6430,3.692,6431,3.692,6432,7.48,6433,11.012,6434,11.37,6435,7.48,6436,7.48,6437,7.48,6438,5.953,6439,5.953,6440,3.692,6441,3.692,6442,3.692,6443,3.692,6444,3.692,6445,3.692,6446,3.692,6447,3.692,6448,3.692]],["t/1323",[84,5.56,137,4.52,168,3.693,180,3.558,615,4.053,875,3.567,998,3.248,4631,8.145]],["t/1325",[10,3.424,44,2.653,168,2.263,180,3.473,181,5.873,217,3.796,411,1.57,421,2.547,555,2.461,985,3.803,1727,4.711,2357,5.443,4746,6.687,4821,7.243,4825,7.074,4826,7.661,4827,7.661]],["t/1327",[44,2.619,168,4.077,180,3.563,181,5.41,985,3.323,1596,3.205,1727,4.34,2271,4.257,4070,7.099,4821,9.405,4954,9.742,6449,11.087,6450,7.621]],["t/1329",[44,2.622,168,4.1,180,3.592,181,5.442,985,3.35,1027,8.358,1596,3.245,1727,3.119,3742,6.115,4821,9.46,6451,11.176]],["t/1331",[12,3.476,39,6.489,84,5.432,123,3.329,168,3.608,180,3.476,521,4.666,615,3.959,875,3.485,998,3.173,2965,6.15]],["t/1333",[7,2.048,44,2.309,117,0.88,163,3.816,180,3.389,181,5.213,203,5.191,263,2.496,451,6.033,470,2.459,480,6.342,597,3.095,615,2.939,732,3.32,978,2.534,985,3.893,1344,4.457,1487,5.203,2261,5.502,2275,5.851,2965,7.112,4301,6.033,4352,6.764,5445,7.44,6112,9.265,6452,10.545,6453,6.764,6454,8.027,6455,7.44,6456,8.027,6457,8.027,6458,8.027]],["t/1335",[10,3.409,39,5.622,42,6.421,44,1.666,117,1.276,180,3.741,181,4.148,194,3.541,203,4.13,222,5.328,421,4.371,555,3.398,576,3.027,597,3.613,732,2.95,834,3.496,888,5.202,973,6.421,985,3.489,2275,4.112,2965,6.619,4301,7.042,4746,5.797,5097,10.788,6459,9.369]],["t/1337",[44,2.235,113,4.246,117,0.798,180,3.174,181,4.372,196,2.176,205,5.154,291,5.526,403,4.843,412,2.482,530,3.194,597,2.806,615,2.664,723,4.41,732,2.291,985,3.36,996,5.923,1177,2.414,2275,3.194,2391,4.913,2476,6.878,2849,6.745,2965,5.616,3901,5.6,4070,4.659,4301,5.469,5902,6.745,6460,6.394,6461,9.876,6462,7.277,6463,7.277,6464,7.802,6465,8.678,6466,7.277,6467,7.277,6468,6.132,6469,9.876,6470,11.211,6471,6.745,6472,9.876,6473,7.277,6474,9.876,6475,9.876,6476,9.876,6477,7.277,6478,7.277,6479,7.277,6480,7.277,6481,7.277,6482,7.277,6483,9.876,6484,7.277]],["t/1339",[7,2.199,44,1.532,117,0.945,155,4.408,180,3.549,181,4.889,219,2.844,412,2.94,480,6.81,597,3.324,732,2.714,978,2.721,985,3.652,1004,4.255,1344,4.786,1373,5.819,1487,5.587,2261,5.908,2275,5.348,2330,6.633,2662,4.862,2965,6.28,3071,4.614,4301,6.479,4774,7.574,5447,7.989,6112,7.574,6450,7.574,6453,7.264,6455,7.989,6485,8.62,6486,8.62,6487,8.62,6488,8.62,6489,8.62,6490,8.62,6491,8.62]],["t/1342",[17,4.121,38,2.467,43,2.337,44,2.654,156,1.633,180,2.159,203,4.121,263,2.907,423,3.79,482,3.648,524,3.92,775,1.967,873,4.841,1027,4.203,1177,2.229,1331,2.712,1465,3.028,1874,3.92,2192,3.759,2288,3.73,2330,7.194,3070,6.06,3071,5.005,6492,6.719,6493,6.719,6494,6.719,6495,6.719,6496,6.719,6497,6.719,6498,6.719,6499,6.719,6500,6.719,6501,6.719,6502,6.719,6503,6.719,6504,6.719,6505,6.719,6506,6.719,6507,6.719,6508,6.719]],["t/1344",[38,2.931,86,2.427,95,3.017,156,1.939,180,2.565,194,3.017,211,2.95,240,2.833,263,2.482,411,2.431,538,3.333,663,3.458,705,5.757,775,2.336,814,3.543,867,2.463,873,5.44,906,3.985,914,3.458,955,3.374,978,2.519,991,3.503,1011,4.16,1049,4.577,1233,5.389,1286,4.215,1477,4.133,1601,5.312,1678,4.009,1698,4.837,1734,5.765,1777,5.174,1865,5.872,2010,4.993,2316,3.597,2331,4.886,2403,7.2,2450,7.316,2560,7.398,2846,7.013,3082,4.539,3589,5.872,3688,6.726,6509,7.981,6510,7.013,6511,7.981]],["t/1347",[1,1.298,44,2.65,83,1.049,90,1.95,170,2.863,181,5.431,240,2.367,263,1.651,338,4.573,411,1.572,412,3.898,482,5.114,681,4.226,814,3.855,820,3.863,834,1.981,978,2.973,985,3.677,993,2.048,1011,4.909,1198,3.585,1331,2.144,1678,3.411,1727,3.105,1734,3.334,1988,1.944,2275,2.33,2619,6.13,3070,4.402,3071,5.789,3502,3.127,3511,3.539,4471,4.585,6512,3.21,6513,5.31,6514,6.792,6515,5.31,6516,6.792,6517,6.792,6518,3.21,6519,6.295,6520,3.21,6521,5.31]],["t/1349",[26,4.665,44,2.027,117,1.25,139,3.85,168,3.024,186,3.674,193,3.34,411,2.887,473,2.666,656,7.488,832,4.787,1109,5.804,1125,4.288,1277,4.787,1465,4.086,1734,5.598,1967,4.527,2587,6.313,2619,6.025,3032,6.91,4471,7.699,6519,10.569]],["t/1351",[1,2.315,30,1.097,44,2.653,83,1.87,156,1.931,170,5.106,172,0.751,188,1.631,195,2.105,208,0.957,226,1.513,243,2.817,263,2.129,452,3.947,470,0.995,614,4.016,678,2.87,732,1.022,786,2.87,814,4.149,875,1.046,923,0.853,993,3.653,998,0.953,1140,4.962,1146,3.592,1399,1.585,1465,3.583,1596,1.2,1614,4.972,1819,2.89,2006,4.941,2516,6.016,2904,8.163,3648,3.733,3899,5.848,5366,4.969,6522,3.247,6523,3.009,6524,6.71,6525,3.247,6526,3.247,6527,7.948,6528,7.948,6529,7.948,6530,7.948,6531,7.948,6532,6.847,6533,6.847,6534,3.247,6535,6.016,6536,3.247,6537,3.247,6538,3.247,6539,3.247,6540,3.247,6541,3.247,6542,3.247,6543,3.247,6544,3.247,6545,3.247,6546,3.247,6547,3.247,6548,3.247,6549,3.247,6550,3.247,6551,3.247,6552,3.247]],["t/1353",[1,1.817,7,2.555,44,2.662,83,1.467,115,2.563,139,3.333,156,1.806,170,4.006,208,2.191,217,6.341,226,4.667,263,3.115,443,3.117,555,2.695,626,4.645,942,3.754,993,2.866,2040,6.262,6553,10.017]],["t/1356",[33,3.743,83,1.79,123,2.791,180,3.665,218,3.163,243,2.351,490,3.729,546,5.29,646,5.661,882,4.58,957,4.324,993,3.496,998,3.346,1601,6.034,4663,7.966,5753,7.966,6554,9.066,6555,9.066,6556,9.066,6557,9.066,6558,9.066,6559,9.066,6560,9.066,6561,9.066,6562,9.066,6563,9.066,6564,9.066,6565,9.066,6566,9.066,6567,9.066,6568,9.066]],["t/1358",[1,2.466,44,1.794,47,2.699,83,2.25,163,3.571,170,5.439,172,1.738,180,2.414,210,2.485,218,2.621,240,2.885,263,2.335,402,3.917,411,1.738,473,2.209,775,2.953,808,5.32,817,4.021,818,3.841,820,3.604,871,4.17,985,4.006,993,3.891,1208,3.433,1273,2.936,1727,2.667,2010,4.698,2171,5.928,2288,4.17,2305,4.108,2357,4.344,2634,5.148,3511,5.258,5096,8.382,6020,6.113,6464,5.934,6465,6.6]],["t/1360",[7,0.718,12,0.905,30,0.576,33,1.562,44,2.106,83,0.556,86,0.856,117,0.522,148,1.577,150,1.172,156,0.684,175,1.346,177,1.287,180,3.958,196,1.849,205,8.255,218,4.247,240,2.131,271,1.754,391,2.679,403,7.457,414,0.764,420,6.328,524,1.643,530,5.115,615,1.031,621,2.123,748,2.368,775,1.393,781,0.712,834,1.776,978,3.739,985,3.649,987,1.006,1004,1.39,1331,1.137,1465,1.269,1518,1.826,1612,2.434,1727,2.195,1734,1.383,1952,2.803,2021,7.853,2027,5.645,2059,2.584,2171,3.097,2260,1.252,2357,6.741,2380,1.312,2760,2.032,2815,3.407,2921,1.961,2998,6.772,3085,3.874,3511,1.468,3665,1.658,3670,3.434,3680,4.241,3703,2.373,3871,2.072,4272,3.578,4457,1.849,5129,4.412,5225,2.225,5479,1.995,5957,2.373,6027,2.475,6085,2.292,6144,2.167,6464,2.225,6471,10.802,6569,2.816,6570,2.816,6571,5.73,6572,2.475,6573,4.76,6574,2.816,6575,6.182,6576,2.816,6577,9.982,6578,2.61,6579,2.816,6580,2.816,6581,2.816,6582,2.816,6583,2.61,6584,2.816,6585,2.816,6586,2.816,6587,2.61,6588,2.816,6589,2.816,6590,2.816,6591,2.816,6592,6.182,6593,2.816,6594,2.816,6595,2.816,6596,2.816,6597,2.816,6598,2.816,6599,2.816,6600,2.816,6601,2.816,6602,2.816,6603,2.816,6604,2.61,6605,2.816,6606,4.76,6607,2.816,6608,2.61,6609,2.816,6610,2.816,6611,2.816,6612,2.816,6613,2.816,6614,2.816,6615,2.816,6616,2.816,6617,2.816,6618,2.816,6619,2.816,6620,2.61,6621,2.816,6622,2.61,6623,2.816,6624,2.816]],["t/1362",[1,2.124,33,2.852,44,2.628,83,2.126,87,1.804,90,1.932,148,1.718,163,2.501,170,4.684,177,1.45,180,3.01,210,1.741,218,3.268,240,2.126,263,1.636,271,1.938,402,2.616,411,1.559,421,1.975,473,0.933,681,3.023,732,0.999,775,1.54,781,1.983,808,2.248,817,1.699,818,1.623,820,1.134,978,1.66,985,3.666,993,3.351,998,0.931,1004,1.567,1027,3.291,1198,3.551,1273,1.241,1331,1.281,1465,2.371,1678,1.594,1698,6.011,1727,3.523,1952,3.097,1988,1.926,2171,5.054,2192,4.862,2316,3.916,2357,1.835,2380,2.451,2476,6.908,2634,2.175,2674,1.687,2815,4.318,3071,1.699,3085,5.484,3366,5.025,3502,3.097,3511,2.741,3665,1.869,3680,3.069,3929,2.674,4312,2.335,5957,2.674,5997,2.507,6027,2.788,6464,2.507,6465,2.788,6572,2.788,6578,2.941,6583,2.941,6587,2.941,6604,2.941,6625,8.689,6626,5.26,6627,5.26,6628,5.26,6629,5.26,6630,5.26,6631,3.173,6632,5.26,6633,5.26,6634,5.26,6635,5.26,6636,5.26]],["t/1364",[1,2.004,3,2.309,10,2.035,17,5.245,44,2.024,83,1.917,97,1.726,117,0.899,123,1.722,126,2.186,156,2.891,170,4.42,223,5.458,263,3.019,414,2.633,473,1.645,491,2.393,510,1.633,594,3.424,712,5.197,803,3.833,840,4.42,879,3.235,953,2.423,993,3.162,1207,4.304,1231,2.715,1331,4.804,1359,3.722,1465,5.363,1776,5.06,1807,2.701,2074,4.969,2815,3.082,2903,3.581,3220,3.961,3468,5.183,3709,4.418,3737,10.455,3754,7.205,4341,7.021,4440,3.961,5448,5.183,5495,5.183,6637,5.592,6638,5.592,6639,5.592,6640,5.592,6641,5.592,6642,5.592,6643,5.592,6644,5.592,6645,5.592,6646,5.592,6647,8.2,6648,5.592,6649,5.592,6650,5.592,6651,5.592,6652,5.592,6653,8.2,6654,4.552,6655,7.205,6656,5.592,6657,7.6,6658,5.592,6659,5.592,6660,5.592,6661,5.592,6662,5.592,6663,5.592,6664,7.205,6665,5.592,6666,5.592,6667,5.592,6668,5.183,6669,5.592]],["t/1366",[3,2.709,33,3.018,44,1.166,73,1.953,115,2.263,181,5.093,240,1.489,412,3.136,488,2.213,525,6.401,560,2.867,619,2.985,621,2.685,646,3.257,732,3.814,985,1.967,1011,5.533,1734,3.221,2260,5.733,2275,4.036,2815,6.339,2910,4.367,3056,8.946,3709,5.184,3710,7.265,4471,4.43,5863,8.946,6143,4.648,6608,6.081,6670,6.561,6671,10.616,6672,10.616,6673,6.561,6674,6.561,6675,6.561,6676,6.561,6677,6.561,6678,6.561,6679,11.638,6680,6.561,6681,6.561,6682,8.08,6683,8.523,6684,9.196,6685,6.561,6686,6.561,6687,9.196,6688,7.749]],["t/1368",[38,1.855,44,2.176,97,0.933,137,1.234,148,0.771,150,2.102,156,1.228,181,4.679,217,2.827,218,1.763,245,2.553,291,2.827,296,2.01,351,2.723,391,0.863,403,2.012,412,2.219,420,2.743,462,5.243,619,2.298,621,1.901,626,1.935,732,0.952,774,3.093,775,0.885,834,3.156,923,1.709,985,3.168,986,1.985,1009,2.708,1030,2.633,1208,2.309,1331,3.07,1465,3.427,1612,1.546,1734,3.732,1920,2.46,2043,3.411,2062,3.995,2119,6.189,2157,2.894,2260,4.315,2275,4.259,2288,2.805,2328,3.196,2365,2.656,2634,3.462,2662,5.157,2671,2.547,2812,2.105,2813,4.167,2815,5.605,2910,4.331,3045,4.682,3050,4.112,3665,1.78,3899,3.717,4188,2.388,4400,2.272,4411,3.362,4417,4.891,4471,5.133,4622,6.189,4955,2.272,5048,2.656,5049,2.656,5225,6.007,5433,2.802,5454,2.802,6045,8.034,6138,2.388,6143,3.578,6577,7.704,6657,7.047,6668,2.802,6682,5.718,6683,6.032,6689,3.023,6690,6.508,6691,6.508,6692,6.508,6693,6.508,6694,3.023,6695,5.052,6696,3.023,6697,5.052,6698,5.052,6699,3.023,6700,3.023,6701,3.023,6702,3.023,6703,3.023,6704,3.023,6705,3.023,6706,5.052,6707,3.023,6708,3.023,6709,5.052,6710,3.023,6711,3.023,6712,5.052,6713,3.023,6714,3.023,6715,3.023,6716,6.508,6717,6.508,6718,6.508,6719,3.023,6720,5.052,6721,3.023,6722,5.052,6723,5.052,6724,7.603,6725,3.023,6726,3.023,6727,3.023,6728,5.052,6729,9.143,6730,4.682,6731,7.047,6732,3.023,6733,7.603,6734,5.052,6735,3.023,6736,3.023,6737,3.023,6738,3.023,6739,3.023,6740,3.023,6741,5.052,6742,7.603,6743,3.023,6744,3.023,6745,3.023,6746,5.052,6747,8.458,6748,3.023,6749,7.603,6750,3.023,6751,3.023,6752,3.023,6753,3.023]],["t/1371",[1,2.644,83,2.135,139,3.181,170,5.83,181,4.788,263,3.363,985,3.242,993,4.171,1009,3.852,1727,3.841,2275,4.746]],["t/1373",[1,2.776,17,3.97,44,1.601,83,2.242,90,3.308,139,2.649,170,6.122,181,3.988,263,2.801,712,4.822,723,5.458,834,3.361,985,2.7,993,4.379,1009,4.896,1204,3.677,1465,4.06,1596,3.329,1698,6.882,1727,3.199,1776,4.694,1777,5.839,2275,3.953,2861,5.573,2881,3.61,4343,7.332,4360,6.77]],["t/1375",[1,2.374,9,2.955,44,2.663,83,1.917,90,2.607,170,5.235,172,1.643,181,4.299,240,2.205,263,2.207,266,1.983,820,2.536,871,4.803,942,2.332,978,2.241,985,2.911,993,3.745,1198,4.793,1208,2.11,1331,2.866,1449,2.318,1465,3.2,1678,2.318,1727,2.521,1988,2.599,2171,5.072,2275,4.262,2674,3.774,3037,4.142,3071,3.8,3502,4.18,3511,5.768,6754,6.58,6755,6.58,6756,6.58,6757,6.58,6758,6.58,6759,4.278,6760,4.616]],["t/1377",[1,2.275,9,4.275,44,2.662,83,1.838,86,2.03,90,2.452,170,5.777,172,1.545,181,4.121,240,2.113,263,2.076,297,1.964,719,1.896,871,5.168,942,2.155,978,2.107,985,2.79,993,3.589,1198,4.507,1208,3.051,1331,2.695,1449,3.353,1465,3.009,1678,4.675,1727,2.371,1988,2.444,2171,5.195,2275,4.085,2425,3.625,2674,3.549,3071,3.574,3502,3.931,3511,5.585,6754,6.188,6755,6.188,6756,6.188,6757,6.188,6758,6.188,6759,3.953,6761,6.676,6762,4.265]],["t/1379",[44,2.174,80,5.013,211,3.209,243,2.252,263,2.7,613,4.335,687,5.701,1081,6.15,1245,5.16,1399,4.239,1449,4.361,1988,2.215,2230,3.878,2275,6.302,2321,5.559,2634,5.951,2851,6.388,3762,6.526,3773,9.281,3786,5.099,4803,5.609,5096,4.452,5481,8.048,6763,8.683,6764,8.683,6765,13.315,6766,8.683,6767,8.683,6768,8.683,6769,8.683,6770,8.683,6771,8.683,6772,8.683,6773,8.683,6774,8.683,6775,8.683,6776,8.683,6777,6.051,6778,6.051,6779,6.051,6780,6.051,6781,6.051,6782,6.051,6783,6.051]],["t/1381",[6784,11.622,6785,11.622]],["t/1383",[1,1.897,21,2.23,30,1.588,44,2.348,83,1.532,90,2.85,117,0.851,136,3.466,156,2.999,180,2.494,203,3.421,218,2.708,235,3.728,245,3.045,411,2.386,604,4.656,666,3.204,837,5.096,873,4.018,877,5.77,882,3.921,993,2.993,1727,4.92,1874,4.528,2288,4.309,3652,9.451,4070,4.969,6786,10.312,6787,7.76,6788,7.76,6789,6.54,6790,10.312,6791,7.76,6792,7.76,6793,7.76,6794,7.76,6795,7.76,6796,7.76]],["t/1386",[12,3.011,44,2.069,240,2.127,249,4.323,285,4.185,338,4.549,1098,5.05,1790,4.262,1979,6.152,2157,4.166,2171,3.993,2316,5.246,2365,8.232,3071,5.015,3901,7.21,3931,5.928,4336,5.736,5225,7.402,6797,9.369,6798,9.369,6799,9.369,6800,9.369,6801,9.369,6802,9.369,6803,9.369,6804,9.369,6805,9.369,6806,9.369,6807,9.369]],["t/1388",[1,2.032,7,2.12,12,2.672,33,2.728,73,2.474,80,5.326,83,1.641,96,3.273,117,1.313,170,4.481,187,3.88,245,3.261,248,4.513,250,3.332,263,2.585,421,3.122,529,2.909,607,2.279,612,2.428,666,4.455,785,4.277,985,3.234,993,3.206,1004,5.326,2062,4.714,2157,4.797,2415,4.513,2570,4.45,2910,5.533,3931,8.02,6808,10.788,6809,10.788,6810,10.788,6811,8.313]],["t/1391",[6523,10.772,6812,11.622]],["t/1395",[21,3.618,85,2.31,86,2.484,117,1.169,137,3.334,208,3.501,219,2.695,227,4.901,419,3.733,496,4.434,538,2.591,576,2.639,586,3.665,639,4.229,649,3.584,822,4.274,878,5.294,881,4.901,980,3.554,1070,4.102,1097,3.347,1142,7.099,1151,4.684,1182,5.598,1252,5.294,1277,4.313,1596,3.018,1801,4.284,1807,3.944,1835,8.207,1896,4.607,2151,6.009,2177,4.854,2180,3.15,2518,4.645,4914,5.688,5140,6.453,5143,6.285,6813,8.167,6814,8.167,6815,8.167,6816,8.167,6817,8.167,6818,8.167]],["t/1397",[48,3.03,86,3.147,88,4.799,115,2.692,117,0.855,149,6.165,211,2.884,219,3.415,235,3.749,250,3.128,263,2.426,296,2.062,511,3.55,538,2.476,610,5.765,719,3.47,775,2.284,802,2.699,803,7.094,809,2.541,812,4.828,817,4.177,822,3.128,997,4.136,1014,3.672,1017,4.882,1037,4.729,1142,5.194,1151,4.475,1187,3.749,1277,4.121,1331,3.151,1334,5.124,1355,4.828,1680,7.233,1714,5.058,1715,3.162,1735,4.996,1835,6.005,2032,3.896,2180,3.991,2275,3.425,2320,5.434,2896,6.005,4307,5.629,4585,6.576,6192,7.233,6819,7.804,6820,7.804,6821,7.233,6822,7.804,6823,7.804]],["t/1400",[5,1.361,33,2.085,35,3.85,44,2.271,47,2.283,86,2.734,117,0.696,123,1.956,136,2.838,137,3.67,193,3.312,211,2.348,229,2.167,263,2.795,285,4.659,296,2.757,474,4.178,505,3.401,579,3.322,615,2.326,775,3.054,781,1.607,833,6.367,923,2.361,985,1.904,998,1.864,1125,4.252,1132,4.289,1245,6.2,1331,3.629,1364,4.068,1753,3.154,1788,3.613,2118,3.501,2157,2.825,2180,5.248,2237,4.229,2298,4.289,2335,6.917,2337,4.747,2357,3.674,2591,4.5,3104,4.118,3374,6.756,3678,6.546,4439,4.775,4749,5.582,4900,4.889,6163,5.019,6190,5.019,6468,5.354,6824,8.989,6825,6.353,6826,6.353,6827,8.989,6828,6.353,6829,5.171]],["t/1402",[44,2.277,285,5.722,2180,4.94,6256,9.256,6830,10.984,6831,10.984]],["t/1404",[43,2.98,44,2.279,117,0.939,172,2.812,649,3.76,802,2.963,1017,6.881,1098,4.618,1177,2.842,1233,5.784,1278,4.524,1286,4.524,1305,7.219,1331,3.459,1749,4.955,1876,7.219,2072,4.999,2180,4.944,2492,7.427,3678,7.012,6393,6.439,6832,11,6833,11,6834,10.676,6835,8.567,6836,7.528,6837,10.195]],["t/1406",[86,2.033,95,2.527,156,2.606,172,2.684,195,7.907,229,2.28,491,2.861,530,2.934,533,4.514,555,3.38,576,2.16,621,1.953,681,4.181,705,4.823,748,4.108,756,3.163,812,4.137,867,2.064,978,2.111,985,2.004,1033,4.708,1045,4.334,1085,4.919,1114,3.902,1204,2.73,1727,3.309,1774,4.231,2072,6.258,2180,4.998,2335,5.146,2492,7.241,3037,6.258,3678,7.438,4657,5.635,6838,12.075,6839,6.687,6840,9.387,6841,6.687,6842,6.197,6843,7.584]],["t/1409",[44,2.558,263,3.238,1788,5.921,2491,7.376,4687,6.248,4751,9.651,5210,8.476,5244,8.476,6844,11.505]],["t/1411",[44,2.288,150,4.607,4687,6.643,6845,11.071,6846,10.261,6847,11.071,6848,9.33]],["t/1413",[44,1.747,47,3.533,85,2.78,117,1.077,156,2.388,613,4.908,619,4.471,740,6.185,809,3.2,1308,4.966,1403,6.454,1418,3.983,1443,4.138,1465,4.43,1615,5.122,2662,5.544,3818,6.081,4687,5.898,6848,8.283,6849,9.829,6850,9.829]],["t/1415",[44,1.953,740,5.044,802,3.8,1098,5.921,1753,5.453,4687,6.591,6848,9.256,6851,8.678,6852,10.984]],["t/1417",[44,2.35,740,5.675,802,3.575,1098,5.572,1753,5.131,4687,7.415,6848,11.141,6851,8.166,6853,10.336,6854,10.336,6855,10.336]],["t/1419",[7,2.494,22,2.154,44,2.034,47,2.973,72,1.853,85,1.601,94,1.909,115,3.372,117,0.907,160,4.131,169,3.763,172,1.914,225,5.246,250,3.316,263,2.572,287,1.532,488,4.352,510,2.416,536,3.821,541,6.391,597,2.183,607,1.552,681,2.54,796,2.705,802,1.958,809,2.694,820,2.955,867,1.747,895,3.096,914,2.453,923,1.487,945,9.312,955,2.393,1098,3.051,1177,1.878,1200,3.009,1277,2.989,1421,2.763,1443,2.383,1565,5.432,1722,2.612,1753,6.127,1790,2.575,1904,2.86,2300,3.167,2770,2.432,2838,5.86,2853,2.895,3589,4.164,4631,4.164,6123,7.958,6846,10.604,6851,4.472,6856,11.441,6857,5.66,6858,11.727,6859,5.66,6860,11.949,6861,5.66,6862,5.66,6863,4.607,6864,5.246,6865,5.66,6866,5.66,6867,4.083,6868,5.66]],["t/1422",[44,2.016,670,5.065,2180,4.373,3678,6.202,6843,9.23]],["t/1424",[44,2.15,188,5.007,554,6.942,1753,4.949,2180,4.663,2380,5.634,2813,6.382,2907,6.307,3678,6.613,6843,8.114,6869,9.969,6870,9.969,6871,9.969,6872,9.969,6873,9.969,6874,9.969,6875,9.969,6876,9.969]],["t/1428",[10,2.762,44,2.333,48,2.948,95,2.87,249,3.503,462,4.354,530,4.46,663,3.29,681,5.722,759,3.486,803,5.203,871,4.215,874,4.122,891,3.706,892,3.931,985,3.046,1380,5.126,1519,4.282,1698,4.601,1715,3.076,1727,2.696,2180,4.918,2305,4.152,2440,3.276,2626,5.998,3366,5.878,3678,7.45,4070,4.861,4746,6.288,5210,6.18,5244,6.18,6123,6.18,6840,7.82,6843,9.324,6877,7.037,6878,7.037,6879,7.592,6880,9.419]],["t/1430",[44,1.771,117,0.351,156,1.915,168,1.068,178,1.547,180,1.029,181,5.056,218,1.117,243,1.759,268,1.869,296,1.401,339,4.26,403,5.246,412,3.685,486,3.042,555,1.162,579,1.959,586,1.437,602,2.003,671,3.347,681,4.674,732,2.135,756,1.515,830,1.869,834,3.716,957,1.214,961,2.132,978,3.919,985,3.764,1008,1.327,1028,1.555,1177,1.062,1248,1.821,1331,2.738,1465,3.552,1519,2.99,1612,4.465,1727,3.954,1753,1.59,2145,1.806,2180,4.5,2275,5.122,2288,2.943,2305,1.752,2335,5.218,2337,3.581,2900,2.05,3072,2.31,3678,6.61,3749,2.23,4070,2.05,4588,2.607,4746,3.279,5891,7.672,6020,2.607,6213,6.285,6840,6.72,6867,8.957,6877,8.093,6878,4.912,6881,6.781,6882,3.202,6883,9.96,6884,12.086,6885,6.781,6886,13.734,6887,6.781,6888,6.781,6889,6.781,6890,6.781,6891,6.781,6892,5.3,6893,3.202,6894,3.202,6895,3.202]],["t/1432",[44,2.365,48,4.073,871,5.825,1698,6.358,2180,5.13,3366,7.211,3678,5.738,6843,8.539,6880,11.556]],["t/1434",[44,2.293,117,1.07,172,2.984,1098,5.262,1233,6.59,2072,6.965,2180,5.181,2492,8.059,3678,7.348,6836,8.576,6896,8.576,6897,9.76,6898,8.576]],["t/1438",[44,2.197,95,3.907,96,4.069,117,1.133,687,6.787,787,4.335,802,3.575,1827,7.954,1914,5.161,2180,4.766,6393,9.289,6899,10.859,6900,9.082]],["t/1440",[44,2.016,2180,4.373,4350,6.739,6393,8.523,6901,9.556]],["t/1442",[38,3.661,44,2.15,85,2.819,586,4.473,1177,3.307,1715,4.039,1876,10.189,1961,4.84,2180,4.663,3873,6.462,6393,9.783,6834,11.891,6901,10.189]],["t/1444",[22,2.556,44,2.172,136,3.001,150,4.474,195,4.355,197,5.693,285,3.001,445,3.648,505,3.596,530,2.949,602,4.203,613,3.355,670,4.176,681,3.014,824,5.469,867,2.073,890,3.115,914,2.911,955,2.84,978,2.121,1062,3.042,1072,3.394,1098,3.622,1156,4.472,1179,6.878,1181,3.415,1245,3.993,1248,6.114,1277,3.548,1286,4.937,1322,4.943,1446,4.071,1465,4.846,1476,5.308,1749,3.886,1876,5.662,1961,3.262,2180,2.591,2275,2.949,2298,4.536,2634,4.605,2907,4.251,3005,4.679,3087,7.386,3678,5.88,4964,4.759,5004,6.227,6212,8.665,6393,8.737,6834,5.903,6899,8.215,6900,5.903,6901,5.662,6902,10.752,6903,6.719,6904,6.719,6905,6.719,6906,6.719,6907,5.469,6908,6.227,6909,5.469,6910,6.719,6911,6.719]],["t/1446",[38,3.535,44,1.711,85,2.722,249,4.442,457,4.319,564,5.617,586,4.319,678,5.153,1177,3.194,1331,3.886,2180,4.943,2202,8.458,2300,5.386,2598,9.634,3873,6.24,4350,7.034,6393,9.634,6901,9.974,6912,8.922,6913,9.626]],["t/1448",[12,3.137,21,2.805,85,2.76,470,2.99,474,3.596,510,2.85,565,5.695,678,5.225,802,3.376,955,4.126,1024,4.419,1091,5.462,1151,5.597,1245,7.094,1519,5.505,1601,6.496,1717,6.039,1924,4.211,2032,4.874,2625,6.797,3696,9.046,6821,9.046,6840,7.511,6914,9.76]],["t/1450",[44,2,474,4.144,1245,6.685,2180,4.338,3678,6.152,6190,8.887]],["t/1452",[44,2,611,4.718,2180,4.338,3678,6.152,6840,8.657,6899,9.884]],["t/1454",[44,2,1245,6.685,1331,4.541,2180,4.338,3678,6.152,6915,11.249]],["t/1456",[30,2.231,44,1.938,1245,6.477,2180,4.203,2545,6.673,3678,5.961,5194,9.577,5196,9.577,6916,9.577,6917,10.899]],["t/1458",[44,2.349,97,2.872,156,2.261,285,4.157,607,2.551,799,6.592,805,9.158,820,4.141,1090,4.62,1098,5.017,1177,3.088,1205,5.743,1245,6.889,1251,6.995,1471,4.62,2180,4.47,2619,4.494,3678,6.34,3698,7.843,4964,6.592,6916,8.177,6918,9.307]],["t/1460",[44,1.655,85,2.632,138,2.872,172,2.154,243,2.414,271,3.429,620,4.274,654,3.771,719,4.138,802,3.219,803,7.944,820,3.325,942,4.702,1098,5.017,1245,7.503,1380,6.283,1715,3.771,2072,5.43,2180,3.589,2316,5.69,3678,5.09,6916,10.185,6919,9.307,6920,9.307,6921,9.307,6922,8.626]],["t/1462",[12,2.139,21,1.912,44,1.183,85,1.882,86,2.824,97,2.054,117,1.018,136,2.972,137,2.717,164,2.717,172,2.149,219,3.065,235,3.197,248,3.613,249,3.071,296,1.759,470,2.845,492,4.574,555,2.414,573,3.816,597,2.566,612,2.712,614,4.692,678,3.562,769,3.883,787,2.791,861,3.993,985,1.995,1008,2.758,1066,3.285,1162,3.849,1187,3.197,1203,3.724,1208,3.042,1245,6.88,1278,3.514,1364,4.261,1387,4.8,1455,3.784,1596,2.459,1599,2.748,1606,5.257,1618,3.709,2165,4.37,2180,4.464,2187,4.634,2518,3.784,2654,6.168,3137,4.429,3154,4.634,3678,5.079,5194,9.399,5196,8.16,5977,5.847,6393,9.924,6909,5.417,6923,6.655,6924,6.655,6925,6.655,6926,5.847,6927,6.168,6928,6.655,6929,6.168,6930,6.168]],["t/1464",[30,2.576,44,2.238,243,3.264,611,5.279,1727,4.47,2180,4.854,2545,7.706,3252,5.056,3678,6.884,4687,5.547,6840,9.686,6867,6.669,6931,9.245,6932,9.245,6933,9.245]],["t/1466",[44,1.785,117,1.101,164,4.099,172,2.323,219,3.313,229,3.424,611,4.211,1185,5.807,1245,7.217,1355,6.212,2180,3.872,2337,5.302,3252,5.491,3678,5.491,4687,6.024,5197,9.306,6840,7.726,6867,7.242,6927,9.306,6934,10.04]],["t/1469",[43,2.98,90,3.146,117,0.939,123,2.637,148,2.185,180,3.905,240,1.945,391,3.139,411,1.982,553,4.554,615,3.136,688,6.068,740,3.934,744,4.554,781,2.167,877,6.799,953,3.712,985,2.568,1025,6.621,1075,4.955,1331,3.459,1618,3.421,2180,5.113,2237,5.702,2998,6.18,3678,6.016,4503,7.427,5362,8.69,6935,8.567]],["t/1471",[12,1.183,13,2.168,40,1.931,44,2.413,85,2.842,96,1.45,115,2.576,117,0.819,123,1.134,148,2.186,156,2.953,172,2.446,240,2.134,250,3.434,263,1.145,267,0.902,296,2.265,419,1.683,510,2.745,579,4.066,586,1.652,654,1.492,663,1.595,674,4.835,719,1.637,755,8.712,758,4.37,760,1.778,775,1.078,809,3.061,871,7.041,906,1.839,923,0.967,953,1.595,985,3.843,1008,1.526,1098,1.985,1249,1.931,1308,1.86,1341,2.709,1417,2.188,1431,1.724,1465,1.66,1565,8.109,1678,1.849,1698,7.068,2072,2.148,2180,5.257,2313,2.13,2440,1.589,2634,6.442,3262,2.768,3366,6.897,3503,2.608,3678,6.522,3698,6.292,4503,4.011,4964,4.208,5362,4.693,6190,2.909,6838,3.235,6896,3.235,6898,3.235,6936,3.682,6937,3.413,6938,3.413,6939,3.413,6940,5.506,6941,3.413,6942,3.413,6943,3.682,6944,3.413,6945,3.413,6946,3.682,6947,3.682]],["t/1473",[12,2.067,28,2.031,38,3.857,44,2.398,47,1.462,48,1.579,85,1.15,95,1.537,115,2.752,117,0.705,138,1.255,148,2.035,156,1.938,177,1.859,240,2.242,249,1.876,250,4.408,263,1.264,267,0.996,268,3.753,296,2.396,450,3.427,473,1.196,486,1.825,491,1.74,492,1.607,496,2.208,576,1.314,579,4.065,586,1.825,594,2.49,630,2.224,649,1.785,654,1.648,670,1.816,674,5.235,681,2.886,758,4.731,775,1.19,820,4.295,906,2.031,908,1.503,923,1.068,942,2.055,955,1.719,978,1.284,985,3.604,1008,1.686,1066,2.008,1097,1.667,1098,2.192,1099,2.707,1114,2.373,1204,1.66,1300,2.516,1311,3.057,1331,2.596,1443,1.712,1477,3.33,1565,2.67,1607,1.618,1678,3.23,1788,2.313,1915,2.934,2072,3.753,2180,5.233,2187,2.832,2239,2.516,2298,4.342,2305,4.959,2440,1.755,2492,7.09,2570,2.177,3262,4.834,3366,5.712,3678,6.709,3698,6.722,4503,2.746,4657,3.427,4964,2.881,5362,3.213,6190,3.213,6838,3.573,6896,3.573,6898,3.573,6908,3.769,6937,3.769,6938,3.769,6939,3.769,6940,3.769,6941,3.769,6942,3.769,6944,3.769,6945,3.769,6948,4.067,6949,6.431,6950,4.067,6951,4.067,6952,4.067,6953,4.067,6954,3.769,6955,4.067]],["t/1475",[44,2.406,72,2.138,79,3.714,339,4.15,405,4.041,656,6.018,678,3.496,885,6.76,1204,3.742,1788,3.714,1819,3.521,1904,4.631,2327,4.711,2328,4.132,2391,4.409,2861,7.482,3086,4.548,4534,4.805,5898,9.305,6900,8.053,6956,10.59,6957,6.531,6958,6.531,6959,6.531,6960,6.531,6961,6.531,6962,6.531,6963,6.531,6964,6.531,6965,6.531,6966,10.59,6967,6.053,6968,6.531,6969,6.053,6970,6.531,6971,6.531,6972,6.531,6973,9.165,6974,9.165,6975,9.165,6976,9.165,6977,9.165,6978,9.165,6979,9.165,6980,9.165,6981,9.165,6982,9.165,6983,9.165,6984,10.59,6985,9.165,6986,6.531,6987,6.531,6988,6.531,6989,6.531,6990,6.531]],["t/1477",[5,1.942,8,5.953,37,6.034,90,3.329,137,4.655,163,4.31,207,5.671,240,2.058,296,2.396,457,4.068,474,4.201,491,3.879,538,2.876,615,3.319,654,3.674,991,3.979,1055,3.416,1062,4.105,1180,4.995,1440,6.034,1521,6.484,1599,3.743,1904,4.58,1948,5.113,2180,3.496,2187,6.313,2440,3.912,3294,6.54,5452,7.966,6991,8.403,6992,9.066,6993,9.066,6994,9.066]],["t/1480",[76,4.674,83,1.901,148,3.019,172,2.227,200,6.163,411,2.227,414,3.476,437,4.674,575,3.945,659,3.7,840,5.189,866,4.281,868,4.725,891,4.699,997,3.429,1431,4.507,1988,4.333,2468,5.153,3319,7.489,4065,7.605,4066,8.922,4067,8.922]],["t/1482",[72,3.384,83,2.041,117,1.133,411,2.86,414,3.351,659,3.972,693,6.031,694,5.046,994,6.328,1547,5.422,2331,6.328,3728,8.915,3806,7.769,4065,8.166]],["t/1484",[17,0.583,27,0.639,44,2.511,47,2.195,72,1.109,76,1.184,77,4.108,78,2.472,83,0.481,85,0.374,86,1.497,103,2.727,106,0.643,113,1.422,117,0.145,141,0.794,146,3.204,148,2.08,150,0.551,155,0.677,156,0.322,163,1.159,187,0.79,188,0.665,190,1.203,195,1.58,199,1.508,200,0.848,211,2.606,214,0.462,219,0.804,242,1.224,243,1.277,250,1.358,335,3.551,339,0.599,411,0.306,414,2.622,415,3.046,437,4.37,445,3.317,470,0.406,483,0.504,486,1.094,490,0.545,505,0.709,526,0.494,544,0.665,566,1.758,575,1.724,586,0.594,619,1.541,621,0.712,659,0.937,666,0.547,697,0.623,719,1.084,740,0.608,753,1.744,759,1.932,775,1.625,781,0.335,796,6.013,808,0.938,810,0.869,820,0.871,840,2.268,868,4.004,871,0.735,896,0.724,953,0.574,955,0.56,978,1.554,994,1.492,997,0.868,1009,2.176,1029,0.753,1114,0.772,1125,0.626,1162,0.766,1177,0.439,1308,0.669,1331,0.534,1332,2.71,1393,3.114,1443,0.557,1509,0.938,1596,0.901,1640,0.591,1818,0.772,1853,0.81,1934,0.729,1988,0.485,2016,0.709,2018,0.657,2019,5.192,2022,2.359,2024,3.191,2051,1.077,2118,1.343,2240,0.828,2359,7.732,2360,8.656,2425,1.839,2662,0.747,2674,3.749,2790,0.802,3128,1.758,3319,1.542,3321,1.046,3739,0.907,3740,0.938,3741,0.828,3742,0.922,3743,0.974,3744,1.727,3745,0.974,3746,1.671,3747,0.974,3748,0.974,3749,0.922,3750,0.995,3751,1.077,3752,1.077,3753,1.077,3758,8.882,3760,2.676,3772,1.116,3773,1.046,3774,1.046,3776,4.972,3778,5.148,3779,5.148,3801,3.324,3871,0.974,4065,2.676,4068,2.259,4069,6.123,4070,3.152,4071,1.227,4072,1.227,4073,1.227,4074,1.163,4075,1.227,4076,1.227,4077,1.227,4078,2.259,4079,0.907,4080,9.978,4081,7.842,4082,3.9,4083,1.227,4084,5.662,4085,4.004,4086,5.662,4087,3.14,4088,2.259,4089,7.25,4090,1.227,4091,5.662,4092,1.227,4093,1.227,4094,3.14,4095,1.227,4096,5.662,4097,2.259,4098,5.662,4099,4.562,4100,3.152,4101,1.227,4102,1.227,4103,1.227,4104,1.227,4105,5.145,4106,4.878,4107,1.227,4108,1.227,4109,2.259,4110,2.259,4111,1.227,4112,2.259,4113,5.662,4114,3.14,4115,2.259,4116,2.259,4117,1.227,4118,2.259,4119,2.259,4120,1.227,4121,1.227,4122,1.227,4123,2.259,4124,2.259,4125,2.259,4126,1.227,4127,7.842,4128,2.259,4129,1.227,4130,1.227,4131,1.227,4132,1.227,4133,2.259,4134,1.046,4135,1.227,4136,1.227,4137,6.537,4138,2.259,4139,1.227,4140,1.227,4141,1.227,4142,2.259,4143,1.227,4144,1.227,4145,1.019,4146,1.227,4147,2.259,4148,2.259,4149,2.259,4150,2.259,4151,1.227,4152,1.227,4153,1.163,4154,1.163,4155,1.227,4156,1.227,4157,1.227,4158,1.227,4159,2.259,4160,1.227,4161,1.163,4162,1.227,4163,1.227,4164,1.227]],["t/1487",[5,2.091,12,3.137,83,1.927,139,2.87,148,2.49,156,2.372,259,2.251,287,2.641,401,4.961,411,2.762,547,6.249,570,6.496,681,4.379,840,5.262,1053,7.944,1170,4.16,1841,4.934,2134,6.496,2171,4.16,3600,6.689]],["t/1489",[44,1.882,72,4.103,73,3.15,83,2.475,84,4.055,87,2.769,95,3.052,102,7.254,105,5.451,117,1.427,126,3.156,163,3.838,180,3.795,411,3.09,463,2.753,483,3.072,607,2.213,620,3.707,693,4.711,869,4.554,1008,3.346,1035,4.669,1036,4.415,1396,4.591,1841,4.904,3601,7.483,3602,7.483,3603,6.571,3604,8.92]],["t/1491",[1,2.6,30,2.177,44,2.612,47,1.212,73,1.003,83,2.1,84,1.694,87,1.156,94,3.028,117,0.892,123,1.038,144,1.902,148,1.411,150,1.403,156,2.476,163,2.629,164,1.377,170,4.84,180,1.084,183,1.781,188,1.694,243,1.823,250,1.351,259,2.077,263,1.048,266,1.449,287,1.496,404,1.887,405,2.086,406,1.674,411,2.077,413,2.842,486,3.649,505,1.805,538,1.07,562,1.377,619,2.516,621,2.053,645,1.398,663,1.461,719,1.499,757,1.628,775,2.058,781,0.853,796,3.886,820,1.205,834,1.258,942,1.704,957,1.279,993,3.136,998,0.989,1125,1.595,1203,1.887,1393,3.499,1465,1.52,1488,2.432,1586,1.694,1596,1.246,1640,1.506,1841,4.79,1904,1.704,2006,1.534,2018,1.674,2118,3.047,2240,2.109,2275,2.427,2316,1.52,2425,3.003,2673,4.929,2754,5.733,2770,1.449,2954,2.432,3070,5.272,3071,4.354,3600,2.311,3605,2.534,3606,2.963,3607,3.541,3608,7.538,3609,2.311,3610,2.432,3611,1.968,3612,2.388,3613,5.126,3614,3.125,3615,3.125,3616,3.125,3617,2.842,3618,3.125,3619,3.125,3620,3.125,3621,3.125,3622,3.125,3623,3.125,3624,3.125,3625,2.745,3626,3.125,3627,2.963,3628,3.125,3629,4.501,3630,3.125,3631,3.125,3632,2.745,3633,3.125,3634,2.963,3635,2.745]],["t/1493",[44,1.496,83,2.147,94,2.837,117,1.192,156,2.927,168,2.806,172,1.947,180,4.092,196,2.515,243,2.82,259,2.401,287,2.276,411,2.516,579,3.109,612,3.175,621,2.457,668,3.139,757,4.063,775,2.463,787,3.528,911,5.453,957,3.19,998,2.468,1203,7.556,1841,4.842,3600,5.766]],["t/1495",[43,3.951,156,3.022,188,4.524,259,2.346,287,2.437,404,5.04,406,4.472,486,5.095,671,4.446,814,3.038,834,3.361,889,6.627,998,2.643,1615,4.694,1783,6.77,1841,4.796,2673,6.882,2754,6.122,3214,6.77,3252,4.926,3636,7.332,3637,8.349,3638,5.515,3639,5.699,3640,5.767,3641,7.332]],["t/1498",[7,2.802,83,2.529,139,3.767,411,2.964,443,4.607,1170,4.681]],["t/1500",[28,4.678,72,4.145,75,5.05,83,2.298,105,7.858,117,1.027,139,3.724,411,2.93,607,2.569,693,5.467,694,4.574,912,4.409,994,5.736,1043,6.893,1547,4.914,2331,5.736,3690,7.21,3728,8.396,3803,8.683,3804,8.683,3805,6.893,3806,7.042]],["t/1503",[1,1.691,7,2.785,30,2.235,33,4.19,156,2.318,160,4.763,193,2.548,210,2.289,226,3.223,240,2.166,242,3.474,243,2.474,411,1.601,412,3.253,414,1.876,443,4.58,490,4.492,504,3.783,615,3.493,621,2.02,663,2.997,719,5.491,903,4.377,942,6.239,993,4.539,1011,3.605,1253,3.538,1465,3.118,2171,2.948,2337,3.653,2492,8.832,2517,9.581,2689,5.089,3032,7.736,3247,4.99,3611,4.036,3807,4.99,3808,5.465,3809,4.99,3810,3.934]],["t/1505",[7,2.806,20,3.861,83,2.172,117,0.939,139,2.52,156,2.082,166,5.525,172,1.982,217,4.794,226,3.992,243,3.151,296,2.264,411,2.545,443,5.096,470,2.624,626,3.281,663,3.712,775,2.508,942,6.477,993,4.242,1110,5.42,1177,2.842,1344,4.757,1509,6.068,2176,7.219,2337,4.524,2492,7.427,3811,6.439,3812,6.768,3813,7.219,3814,7.219,3815,7.528]],["t/1507",[1,2.895,5,1.739,7,2.71,30,1.662,73,2.416,83,2.098,87,2.785,97,2.506,107,5.974,117,1.298,139,3.483,148,2.071,156,1.973,164,3.315,241,4.377,243,2.106,248,4.409,258,3.1,267,1.989,411,2.459,443,3.406,473,3.125,521,3.504,531,4.031,621,2.371,645,3.366,659,3.121,663,3.518,694,3.964,781,2.054,787,3.406,957,3.079,963,4.872,980,3.533,993,4.097,2954,5.858,3032,4.921,3605,6.103,3607,6.803,3690,6.249,3807,5.858,3811,6.103]],["t/1509",[1,1.244,5,0.544,7,2.881,30,2.156,33,3.671,43,0.884,44,2.589,72,0.453,73,0.412,81,2.784,83,1.43,85,0.392,113,0.808,117,0.558,137,0.566,138,0.428,139,3.46,144,0.781,148,1.733,156,2.595,160,3.818,163,1.208,164,1.038,165,0.598,172,2.125,187,1.413,193,1.875,197,0.645,205,0.981,206,0.758,210,1.896,218,0.483,219,0.457,220,0.669,226,2.032,238,0.801,240,2.027,242,3.16,243,1.486,248,1.38,255,0.839,258,0.529,265,0.752,267,0.622,296,0.366,323,0.727,339,0.627,398,0.936,411,1.326,414,2.491,436,0.839,443,5.241,470,0.424,483,0.527,490,2.979,504,3.961,505,0.742,529,0.485,538,0.806,553,2.319,586,1.14,613,1.269,614,0.7,615,2.097,617,2.303,619,0.63,620,3.12,621,1.487,645,1.053,654,0.561,663,0.6,670,1.135,681,0.622,687,1.669,748,0.973,756,1.202,759,0.636,760,0.669,783,0.876,866,0.616,903,3.221,923,0.364,953,1.101,959,0.965,963,0.831,980,0.603,993,4.221,1011,1.835,1028,0.673,1052,0.887,1125,0.655,1127,0.876,1177,0.46,1204,0.566,1253,1.801,1431,1.19,1465,3.062,1596,2.117,1773,0.747,1815,0.999,1874,0.808,1894,1.87,2006,2.606,2171,1.501,2240,0.867,2304,1.135,2316,0.624,2337,2.303,2425,0.752,2449,0.831,2468,1.885,2517,7.669,2689,2.59,2754,0.747,2886,1.066,2887,1.066,2951,3.278,3032,6.777,3128,0.999,3247,3.146,3357,1.066,3481,1.066,3485,1.217,3717,2.967,3807,1.833,3809,2.54,3810,2.002,3811,1.041,3812,1.094,3816,1.284,3817,5.31,3818,2.179,3819,2.142,3820,2.356,3821,2.142,3822,5.31,3823,2.356,3824,5.31,3825,2.142,3826,2.356,3827,2.356,3828,2.356,3829,2.356,3830,2.356,3831,2.356,3832,2.356,3833,2.356,3834,3.263,3835,2.356,3836,1.094,3837,1.066,3838,2.008,3839,2.008,3840,1.284,3841,6.041,3842,5.303,3843,8.436,3844,4.29,3845,1.284,3846,1.284,3847,1.128,3848,1.284,3849,2.356,3850,1.167,3851,1.284,3852,1.284,3853,1.284,3854,2.142,3855,0.999,3856,1.284,3857,1.094,3858,1.284,3859,1.284,3860,1.284,3861,1.284,3862,1.284,3863,1.284,3864,1.284,3865,1.167,3866,2.356,3867,1.284,3868,1.284,3869,1.284,3870,1.167]],["t/1511",[1,1.415,5,0.355,7,1.648,30,0.612,33,2.76,44,2.47,47,3.559,73,0.493,81,1.636,83,0.591,117,0.182,139,1.473,144,0.935,148,2.145,156,1.407,163,1.422,164,1.221,165,0.715,166,4.223,168,0.553,172,1.339,218,1.427,220,0.8,226,2.333,240,2.192,243,1.299,296,0.438,338,0.805,402,1.588,406,2.03,411,2.105,412,1.395,414,2.049,443,3.527,470,0.916,479,1.275,486,3.16,490,1.682,505,0.887,538,0.526,586,1.342,613,2.042,615,2.365,617,3.411,619,0.754,620,3.469,621,1.691,645,1.24,646,2.03,654,0.672,687,1.964,756,0.784,775,2.062,781,0.419,796,5.517,803,1.136,814,2.7,834,0.618,993,3.087,1052,1.061,1072,0.837,1098,0.893,1125,0.784,1146,3.388,1308,0.837,1355,1.025,1431,0.776,1509,2.897,1586,2.054,1596,0.612,1612,2.561,1773,0.893,1874,0.967,1957,1.061,2006,0.754,2018,0.823,2021,1.004,2036,3.009,2171,2.753,2240,1.037,2260,1.818,2263,1.878,2275,5.066,2278,0.994,2304,1.336,2316,2.257,2337,2.645,2359,7.068,2360,7.912,2425,0.9,2449,0.994,2456,2.478,2587,4.498,2754,2.205,2879,1.174,2951,3.764,3030,2.587,3032,5.096,3357,1.275,3807,1.195,3810,2.848,3814,4.878,3818,2.53,3819,2.521,3821,2.521,3825,4.22,3836,1.309,3837,1.275,3838,2.364,3839,2.364,3841,3.957,3842,6.366,3843,9.444,3844,4.22,3850,2.521,3854,3.446,3855,6.561,3857,3.231,3865,2.521,3870,2.521,3871,1.219,3872,1.456,3873,1.074,3874,2.773,3875,2.773,3876,1.536,3877,1.536,3878,10.144,3879,1.536,3880,4.22,3881,2.773,3882,2.773,3883,3.79,3884,3.79,3885,3.79,3886,3.79,3887,3.79,3888,3.79,3889,3.79,3890,3.446,3891,3.79,3892,3.79,3893,3.074,3894,3.79,3895,3.074,3896,3.79,3897,3.593,3898,3.79,3899,1.219,3900,3.79,3901,1.275,3902,1.536,3903,1.536,3904,1.536,3905,4.087,3906,1.536,3907,2.773,3908,2.773,3909,1.456,3910,2.773,3911,1.536,3912,1.536,3913,1.536,3914,1.536,3915,2.773,3916,2.773,3917,1.456,3918,0.985,3919,1.536,3920,1.536,3921,1.536,3922,1.536]],["t/1513",[1,2.321,30,1.943,44,2.265,117,1.287,148,2.994,172,2.197,243,2.463,443,3.982,613,4.741,615,3.476,620,5.39,621,2.773,740,4.361,744,5.048,753,3.936,980,4.132,993,3.662,1596,3.509,2078,7.137,3807,6.85,3811,7.137,3843,7.502,3923,7.729,3924,8.801]],["t/1515",[148,2.802,219,3.625,470,3.365,529,3.844,748,4.207,1934,6.053,2478,5.88,3032,6.657,3812,8.678]],["t/1517",[148,2.869,166,5.65,767,6.623,998,3.301,2478,6.022,3813,9.479]],["t/1519",[83,2.541,123,3.408,411,2.978,414,3.49,597,4.269]],["t/1521",[7,2.637,12,3.972,83,2.61,117,1.133,123,3.804,137,4.22,411,2.392,414,2.803,529,3.617,573,5.927,908,3.82,2570,5.533,2760,7.456]],["t/1523",[21,2.363,44,1.905,83,1.922,91,2.591,117,1.174,122,3.973,138,2.538,139,1.651,172,1.299,186,2.275,193,2.069,240,1.867,243,1.456,264,2.616,414,3.093,463,1.915,473,1.651,474,2.069,483,2.136,510,1.64,529,1.965,530,2.464,607,2.668,621,1.64,650,4.05,655,3.687,659,2.158,735,2.985,740,4.92,748,2.151,796,2.683,801,7.056,802,2.845,803,3.848,804,4.732,805,4.436,808,5.825,809,2.678,810,5.4,811,4.22,812,3.474,813,3.91,814,2.774,815,4.732,816,3.973,817,3.006,818,2.871,819,3.403,820,2.006,822,2.25,832,4.343,923,1.475,957,2.129,969,2.804,976,3.553,1062,2.542,1181,2.854,1599,4.018,1647,3.276,1714,3.64,1727,1.994,1753,4.083,1962,3.737,1966,4.155,2180,4.131,2345,4.22,2353,5.657,2468,3.006,2770,2.413,2853,2.871,3032,3.403,3208,3.687,3359,3.737,3659,4.498,3717,4.732,3718,5.204,3719,4.934,3720,5.204,3721,5.204,3722,5.204,3723,5.204,3724,5.204,3725,5.204,3726,7.623,3727,5.204]],["t/1525",[117,1.468,193,3.924,197,4.962,243,2.762,607,2.92,621,3.11,831,6.141,1966,5.381,3319,7.96]],["t/1527",[1,1.271,17,2.291,30,1.59,38,1.909,44,2.06,72,3.615,73,1.547,83,2.537,86,2.828,92,4.568,102,3.563,105,3.51,117,0.852,123,1.6,126,2.032,144,2.932,148,1.981,155,2.658,156,2.26,160,2.596,163,2.471,214,1.814,405,3.216,411,2.779,412,1.773,414,3.622,437,3.772,445,4.218,544,2.611,607,1.425,645,2.155,666,2.146,679,2.626,719,2.312,740,2.387,775,1.522,810,3.413,868,2.552,869,5.246,878,3.37,896,2.843,942,2.626,994,4.756,1008,2.155,1203,2.909,1204,2.122,1331,2.099,1547,2.727,1896,2.932,2016,2.783,2425,4.218,2468,2.783,2593,4.381,2790,3.15,2903,3.328,3067,3.413,3070,3.37,3318,4.707,3528,4,3607,3.328,3728,6.709,3729,4.818,3730,4.818,3731,4.818,3732,4.818,3733,4.818,3734,4.568,3735,4.818,3736,4.818,3737,6.826,3738,4.818,3739,3.563,3740,3.682,3741,3.252,3742,5.41,3743,3.824,3744,5.502,3745,3.824,3746,5.324,3747,3.824,3748,3.824,3749,3.62,3750,3.907,3751,4.231,3752,4.231,3753,4.231,3754,6.826,3755,4.818,3756,4.818,3757,4.818,3758,4.231,3759,4.818,3760,4.107,3761,4.818]],["t/1529",[97,3.098,172,2.323,264,4.678,406,4.984,414,2.723,463,3.424,470,3.076,531,4.984,562,4.099,775,2.939,781,3.072,896,5.491,957,4.605,987,3.587,1025,5.013,1509,7.112,1596,3.71,3604,8.461,3762,7.546]],["t/1531",[86,3.525,137,3.799,155,4.759,156,2.261,168,3.867,172,2.682,186,5.116,414,3.759,437,4.519,1596,4.666,2380,5.882,3741,5.822,3760,7.352,3763,8.177,3764,10.185,3765,8.177,3766,7.352]],["t/1533",[4,2.188,17,2.308,30,1.072,44,0.931,76,2.543,78,6.466,86,3.533,97,1.616,106,3.793,117,0.856,155,2.678,156,1.898,172,1.212,196,1.566,219,1.728,243,1.358,263,2.429,414,3.661,437,3.793,462,3.003,470,2.393,490,2.154,520,4.045,544,2.63,568,2.557,579,1.935,586,2.35,610,2.6,719,3.474,732,2.459,740,2.405,781,1.325,810,3.439,867,1.616,868,2.571,874,2.843,896,5.109,923,2.052,991,2.298,1009,2.782,1159,2.729,1203,5.228,1331,2.114,1351,3.206,1386,3.206,1552,3.314,1618,3.119,1723,2.978,1789,3.439,1858,3.056,1989,3.029,2006,2.382,2016,2.803,2018,2.6,2022,3.647,2165,3.439,2295,2.864,2316,2.361,2662,4.406,2790,4.734,2907,4.942,3154,3.647,3739,3.589,3740,3.71,3741,3.276,3742,3.647,3743,3.853,3744,5.533,3746,3.589,3747,3.853,3748,3.853,3749,3.647,3750,3.936,3767,4.137,3768,4.03,3769,4.413,3770,3.778,3771,4.854,3772,10.427,3773,4.137,3774,4.137,3775,8.659,3776,6.358,3777,4.854,3778,6.583,3779,6.583,3780,7.24,3781,4.854,3782,4.413]],["t/1535",[17,2.6,30,1.207,44,1.049,76,2.864,86,4.026,96,2.322,97,1.82,117,0.934,155,3.016,156,2.432,172,1.365,196,1.764,219,2.813,263,1.834,414,3.675,437,4.86,470,1.807,490,2.426,544,2.962,568,2.88,579,2.18,586,2.647,610,2.928,612,1.723,651,3.926,732,2.684,740,2.709,781,1.492,810,3.873,867,1.82,896,4.662,923,1.549,942,4.307,997,2.101,1159,3.074,1189,3.982,1203,5.601,1331,2.381,1618,3.404,1722,2.722,1723,3.354,1789,3.873,1858,3.442,2006,2.683,2016,3.157,2018,2.928,2165,3.873,2790,5.166,2907,3.732,3739,4.043,3740,4.178,3741,3.69,3742,4.108,3743,4.339,3744,6.038,3746,4.043,3747,4.339,3748,4.339,3749,4.108,3767,6.734,3768,4.539,3769,4.971,3783,7.901,3784,10.78,3785,5.183,3786,4.971,3787,7.901,3788,5.467,3789,9.277,3790,7.901,3791,5.467,3792,7.901,3793,5.467,3794,5.467]],["t/1537",[4,4.261,17,3.365,21,2.931,83,1.507,156,1.855,172,2.837,194,2.885,214,2.663,218,2.663,235,3.667,240,1.733,262,3.557,297,2.245,414,3.698,437,3.706,470,3.756,490,4.195,504,5.578,538,2.422,681,3.425,740,3.505,753,4.228,896,7.341,908,2.821,1331,4.637,1618,4.073,2006,4.64,2016,4.086,3318,6.181,3739,5.232,3740,5.407,3741,6.38,3795,8.595,3796,7.075]],["t/1540",[93,5.835,414,3.619,510,3.087,514,5.309,756,4.999,998,3.101,1035,6.113,1177,3.507,3319,6.688,3797,6.168,3798,7.945]],["t/1542",[77,5.197,78,4.737,86,2.868,106,4.58,211,4.32,414,3.17,481,5.774,663,4.087,760,4.555,868,4.63,923,2.477,998,3.429,1070,4.737,1177,3.129,1790,4.291,1818,6.82,1853,7.156,1988,4.279,2275,4.139,3319,5.968,3799,8.742,3800,8.742,3801,7.451,3802,8.742]],["t/1545",[1,2.26,72,3.026,83,2.485,87,3.171,117,1.265,148,2.358,210,4.362,411,3.05,693,5.394,694,4.513,993,3.565,994,5.66,1404,5.919,1547,6.055,2331,5.66,2954,6.669,3605,6.949,3607,5.919,3728,8.327,3806,6.949,3925,8.569,3926,8.569]],["t/1548",[81,5.491,126,4.748,178,4.849,276,5.896,402,3.898,817,6.501,818,6.21,871,5.574,985,3.64,1380,6.778,1727,3.565,1846,6.084,2171,5.175,3927,8.461,3928,8.461]],["t/1550",[81,5.612,126,4.81,178,4.955,276,5.974,402,3.984,985,3.688,1380,6.927,1727,3.644,1846,6.218,2171,5.244,3927,8.646,3928,8.646,3929,8.646,3930,9.51]],["t/1553",[44,2.348,81,4.629,338,5.299,796,5.216,1487,7.075,2165,7.167,2415,5.926,2674,5.802,2907,7.644,3071,5.843,3931,7.644,3932,7.369,3933,7.844,3934,10.116,3935,10.116,3936,10.116,3937,10.116,3938,10.116,3939,10.116,3940,7.844,3941,7.844,3942,7.844,3943,7.844,3944,7.844,3945,7.437]],["t/1555",[30,1.93,44,2.258,81,5.158,473,2.774,796,4.507,814,3.942,834,3.519,1331,3.808,2021,5.716,2024,6.114,2316,4.251,2674,5.014,3071,5.049,3946,8.742,3947,8.742,3948,10.833,3949,10.833,3950,10.833,3951,10.833,3952,10.833,3953,8.288,3954,8.742]],["t/1557",[33,1.924,44,2.654,47,3.83,81,1.434,414,0.711,796,5.092,814,0.884,1009,0.934,2024,6.907,2260,3.464,2353,4.788,2587,1.826,2619,1.266,2674,5.665,3030,4.388,3071,5.704,3511,1.366,3665,7.522,3810,3.334,3893,1.97,3955,2.43,3956,2.43,3957,2.43,3958,4.151,3959,6.428,3960,5.434,3961,2.43,3962,2.43,3963,6.428,3964,2.43,3965,2.43,3966,7.867,3967,2.43,3968,2.43,3969,2.303,3970,2.43,3971,2.43,3972,2.43,3973,2.43,3974,2.43,3975,7.867,3976,2.43,3977,2.43,3978,2.43,3979,2.43,3980,2.43,3981,2.43,3982,2.43,3983,2.43,3984,2.43,3985,2.43,3986,7.22,3987,2.43,3988,2.43,3989,2.43,3990,2.43,3991,2.43,3992,2.43,3993,2.43,3994,2.43,3995,2.43,3996,2.43,3997,2.43,3998,2.43,3999,2.43,4000,2.43,4001,2.43,4002,2.43,4003,2.43,4004,2.43,4005,2.43,4006,2.43,4007,2.43,4008,2.43,4009,2.43,4010,2.43,4011,2.43,4012,2.43,4013,2.43,4014,2.43,4015,2.43,4016,2.43,4017,2.43,4018,2.43,4019,2.43,4020,2.43,4021,2.43,4022,5.434,4023,2.43,4024,2.43,4025,2.43,4026,2.43,4027,2.43,4028,2.43,4029,2.43,4030,2.43,4031,2.43,4032,2.43,4033,4.151,4034,2.43,4035,2.43,4036,2.43,4037,2.43,4038,2.43,4039,2.43,4040,2.43,4041,2.43,4042,2.43,4043,2.43,4044,2.43,4045,2.43,4046,2.43,4047,2.43,4048,2.43,4049,2.43,4050,2.43,4051,2.43,4052,2.43,4053,2.43,4054,2.43,4055,2.43,4056,4.151,4057,4.151,4058,6.428,4059,2.43,4060,2.43,4061,2.43,4062,2.43,4063,2.43,4064,2.43]],["t/1560",[1,2.133,43,3.036,44,1.552,72,2.857,87,2.993,88,4.046,115,3.839,117,1.344,123,2.687,180,2.805,186,3.536,187,2.827,190,5.495,209,3.549,240,1.981,267,2.138,488,2.943,490,3.59,510,2.549,527,2.903,566,6.295,568,4.26,576,2.819,868,4.284,997,3.108,1098,4.704,1214,4.548,1393,5.522,1790,3.97,2152,6.18,3596,7.103,4261,5.047,4262,5.092,6014,7.668,6995,8.727,6996,7.103,6997,7.668]],["t/1562",[1,2.285,33,3.529,72,2.199,85,1.9,96,3.681,115,2.317,117,1.423,187,2.176,193,3.444,210,2.223,245,2.636,296,2.471,297,2.749,405,4.157,406,3.335,412,3.964,473,2.749,486,3.014,525,4.641,527,3.11,538,2.966,576,2.171,607,1.842,621,1.962,633,4.847,646,3.335,732,2.115,834,2.507,895,5.113,998,2.743,1071,3.501,1089,3.993,1377,4.847,1399,3.28,1456,5.308,1512,5.903,1586,3.374,1766,4.605,1868,4.679,2018,3.335,2059,3.648,2152,5.191,2180,2.591,2881,3.747,2934,5.361,3128,4.847,3256,3.245,3713,5.05,3716,5.903,3762,8.081,4169,3.702,4685,7.488,4699,8.215,5259,5.469,6138,7.386,6998,9.349,6999,6.227,7000,6.227]],["t/1564",[1,2.587,5,2.267,11,3.651,30,1.652,33,2.65,72,3.465,97,3.267,150,3.359,180,2.595,193,2.974,209,3.284,240,1.833,262,3.762,391,3.021,397,4.711,414,2.189,530,3.543,568,3.941,612,2.358,639,4.181,732,3.718,787,3.386,914,3.498,985,2.42,987,3.781,1055,3.042,1066,3.985,1214,5.516,1271,4.235,1722,3.725,1966,4.079,2133,5.374,2152,4.483,2180,4.082,2872,5.05,3078,4.892,3808,8.362,5038,7.497,6996,8.615,7001,6.378,7002,7.483]],["t/1566",[1,2.245,38,3.373,73,2.733,210,3.039,402,3.566,412,3.132,538,2.914,579,4.249,809,2.991,892,4.756,1019,4.258,1140,5.18,1187,4.412,1286,4.85,1344,6.383,1399,4.484,1914,4.586,1953,5.745,1954,4.756,2152,5.1,2581,5.953,2815,5.061,2853,4.697,2900,7.361,2910,6.113,3931,7.274,4685,6.396,4689,5.267,6043,6.903]],["t/1569",[1,2.597,5,1.019,7,1.213,12,2.335,13,2.801,17,2.097,22,1.81,30,0.974,33,2.384,38,3.623,72,3.478,73,2.162,78,4.955,90,1.747,115,4.333,117,0.966,122,1.942,146,3.811,150,1.98,155,2.433,160,3.627,187,1.541,193,1.753,211,2.685,243,1.234,245,2.85,267,1.165,391,2.073,414,2.39,415,2.943,470,1.457,510,1.389,525,3.607,538,1.509,586,3.954,597,1.834,612,1.389,618,2.602,659,1.828,681,2.134,732,1.498,757,2.297,781,1.203,802,1.646,809,1.549,832,3.836,868,2.335,953,4.604,997,2.588,1004,3.586,1008,1.972,1009,1.694,1011,2.479,1097,1.949,1098,2.564,1177,1.578,1231,2.31,1239,2.751,1267,4.317,1377,3.432,1393,3.01,1420,4.18,1470,4.009,1477,3.762,1512,8.668,1609,2.418,1753,5.275,1766,4.979,1959,3.432,1988,1.742,2021,2.883,2027,3.046,2060,2.403,2062,2.079,2130,3.124,2144,2.583,2152,5.9,2157,2.115,2165,3.124,2239,2.943,2300,2.662,2770,3.122,2965,2.705,3262,5.46,3659,5.395,3713,6.624,3808,3.758,4822,3.576,5081,4.18,5259,3.872,5896,3.26,6129,3.872,6851,3.758,6999,4.409,7000,10.382,7003,7.265,7004,4.757,7005,4.757,7006,4.757,7007,4.009,7008,4.757,7009,4.757,7010,4.409,7011,4.409]],["t/1571",[7,1.126,22,1.679,28,2.203,30,2.465,31,4.502,33,1.448,35,2.674,38,2.518,44,0.784,72,3.104,73,2.04,78,3.443,79,3.899,80,5.599,83,0.871,87,1.513,94,1.488,95,1.668,115,3.912,117,1.191,118,1.646,122,1.801,128,3.148,150,2.853,155,2.257,160,3.423,167,2.509,194,1.668,219,1.456,240,1.556,243,1.778,245,1.731,250,1.769,391,1.259,412,1.505,486,1.98,521,1.904,555,3.05,607,1.21,618,2.413,621,1.289,659,3.231,660,2.934,693,4,694,2.154,732,2.159,775,2.007,796,2.109,814,3.463,816,2.799,867,1.362,871,2.45,912,2.076,923,1.159,953,1.912,1004,4.151,1009,1.572,1120,2.396,1239,2.552,1393,2.792,1399,4.105,1477,2.285,1612,2.257,1753,2.191,1791,2.203,1838,2.575,1959,3.183,1988,1.615,2018,3.404,2062,2.996,2152,5.264,2157,3.049,2180,2.644,2278,2.648,2304,1.971,2321,4.39,2440,1.904,2469,2.937,2760,3.183,2770,1.896,2965,3.899,3125,3.718,3206,3.486,3262,5.153,3635,3.592,3653,8.364,3659,2.413,3678,2.413,3713,5.153,3808,6.643,3818,2.73,4355,5.416,4400,3.317,4685,7.15,4822,3.317,5005,3.592,5096,3.246,5206,6.643,5210,3.592,5896,3.024,6997,3.877,7010,4.09,7011,4.09,7012,4.09,7013,4.413,7014,4.413,7015,10.267,7016,4.413,7017,4.413,7018,6.024,7019,4.413,7020,6.024,7021,4.413]],["t/1574",[1,2.808,21,2.931,38,2.803,72,2.499,76,3.706,80,3.768,96,3.005,115,2.633,116,3.539,117,1.118,148,2.93,165,3.294,166,3.834,177,5.25,245,2.995,470,2.338,529,2.671,550,5.012,559,6.213,562,3.116,579,2.821,620,4.684,670,3.41,697,3.592,914,3.308,955,3.227,978,2.41,987,2.727,1204,3.116,1799,4.238,1825,4.454,1961,3.706,2062,3.336,2152,5.663,2157,3.394,3103,5.232,4881,10.331,5083,6.213,7022,7.634,7023,10.199,7024,9.434,7025,11.486,7026,7.075,7027,7.634,7028,10.199]],["t/1576",[7,1.621,38,2.333,83,1.775,85,1.797,116,2.946,117,0.696,139,3.336,151,4.991,156,2.184,160,6.795,180,2.042,187,2.058,208,3.766,238,3.674,240,1.442,243,1.648,263,1.975,403,4.229,437,4.365,443,3.77,529,2.223,671,3.136,769,3.707,923,1.668,925,4.5,993,4.926,1976,3.172,2180,2.45,3662,4.068,4270,3.425,4272,4.775,4858,4.775,5038,6.367,5981,7.575,6247,6.613,7029,6.353,7030,12.775,7031,10.432,7032,6.353,7033,5.171,7034,6.353,7035,12.775,7036,6.353,7037,6.353,7038,5.171,7039,6.353,7040,6.353,7041,6.353,7042,6.353,7043,5.171,7044,6.353,7045,6.353,7046,6.353,7047,8.989]],["t/1578",[1,2.133,44,1.552,72,3.644,73,2.597,83,2.633,84,4.383,115,3.01,117,0.957,123,3.773,155,4.463,167,4.963,172,2.019,173,5.459,175,5.319,208,2.573,263,3.811,414,2.367,612,2.549,615,3.195,993,3.365,998,2.561,1009,3.965,1607,3.473,2018,4.333,2152,4.845,2153,6.559,2271,4.284,2440,3.765,3502,5.138,3505,6.295,7048,8.727]],["t/1580",[75,6.435,83,1.927,87,3.347,97,3.012,117,1.07,180,3.137,235,4.689,411,3.109,414,3.803,998,2.864,1599,4.03,2903,6.249,3603,7.944,4267,9.716,7049,9.76]],["t/1582",[85,2.799,115,3.414,116,4.589,180,3.181,218,3.454,258,3.779,298,6.124,391,2.825,566,7.14,568,4.832,586,4.441,615,3.624,663,4.289,781,2.504,820,3.536,1177,3.284,1308,5.001,1453,7.82,1734,4.859,1988,3.624,2180,3.817,6254,9.174,7050,9.898]],["t/1585",[1,2.012,5,0.617,17,1.269,30,1.286,33,4.387,38,1.058,44,1.311,47,1.035,73,2.194,80,3.102,83,0.569,90,1.781,91,2.238,95,1.089,105,1.944,115,0.993,117,0.978,123,0.887,154,2.006,156,2.306,167,1.638,172,1.454,180,2.867,187,0.933,198,1.422,218,3.311,224,1.398,243,0.747,245,4.068,249,1.329,250,3.298,266,1.237,320,3.947,338,2.355,391,1.384,402,2.863,412,0.982,463,0.982,470,1.486,483,3.394,490,4.409,510,1.417,525,3.12,536,1.944,538,0.914,546,1.68,576,0.93,612,0.841,617,1.521,623,1.728,646,3.12,651,1.917,654,1.167,656,1.891,666,2.003,719,2.794,748,3.152,775,0.843,781,2.4,809,1.579,867,1.497,873,1.491,882,3.175,888,1.599,891,1.406,923,0.756,942,1.455,953,2.102,978,0.909,987,1.029,993,1.871,998,0.845,1011,1.501,1070,3.156,1097,1.18,1133,2.119,1151,1.651,1168,1.802,1245,1.712,1277,1.521,1352,3.185,1365,2.427,1380,1.944,1396,1.638,1466,2.216,1531,2.427,1547,1.511,1618,1.15,1647,1.68,1727,1.023,1753,3.12,1766,1.974,1775,2.344,1914,1.438,1952,2.856,2062,2.12,2152,3.489,2157,3.279,2260,2.157,2288,1.599,2320,2.006,2337,2.561,2689,2.119,2703,1.891,2704,2.427,2716,3.832,2815,2.673,2975,2.673,3024,2.216,3030,3.976,3247,2.077,3665,2.856,3713,3.646,3716,6.479,3797,1.68,4648,2.275,4663,2.531,4749,2.531,4957,4.496,4958,2.344,4962,2.531,4991,2.427,4992,2.531,5062,2.344,5081,4.262,5083,2.344,5125,4.496,6144,2.216,6187,2.531,6679,2.669,6789,2.427,6996,2.344,7024,2.216,7051,4.851,7052,2.88,7053,2.88,7054,4.851,7055,2.88,7056,2.88,7057,2.88,7058,9.965,7059,4.851,7060,4.851,7061,4.851,7062,2.88,7063,2.88,7064,2.88,7065,4.851,7066,8.92,7067,2.88,7068,2.88,7069,2.88,7070,2.88,7071,7.373,7072,2.88,7073,2.88,7074,2.88,7075,2.88,7076,2.88,7077,2.88,7078,2.88,7079,2.88,7080,2.88,7081,4.851,7082,4.851,7083,2.88,7084,4.851,7085,4.851,7086,2.88,7087,2.88,7088,2.669,7089,2.88,7090,2.88,7091,2.88,7092,2.88,7093,2.88,7094,2.88,7095,2.88,7096,2.88,7097,2.88,7098,2.88,7099,4.851,7100,2.88,7101,2.88,7102,2.88,7103,2.88,7104,2.88,7105,2.88]],["t/1587",[1,2.486,30,1.033,31,6.001,38,1.854,72,3.752,76,2.451,78,2.536,79,2.871,80,5.02,117,1.196,118,1.884,122,4.679,179,2.972,208,1.488,249,2.329,262,2.352,267,1.237,320,2.702,401,2.566,412,1.722,414,1.369,443,2.117,473,1.485,493,4.254,510,1.474,529,2.659,532,3.124,557,1.866,565,4.434,576,2.455,607,1.384,615,1.848,668,1.884,775,3.193,781,1.277,808,8.424,809,1.644,810,3.315,816,3.731,820,3.633,867,2.345,923,1.326,967,3.158,978,1.594,1070,3.817,1115,2.972,1125,2.388,1169,2.92,1180,2.782,1211,2.126,1266,3.124,1277,2.666,1481,8.617,1546,3.232,1722,2.329,1724,3.885,1727,3.246,1732,2.566,1807,2.438,1923,2.946,2059,2.741,2061,7.336,2152,5.646,2313,4.395,2456,5.538,2476,7.595,2571,3.408,2770,4.686,2771,3.516,2838,3.576,2881,3.046,3086,3.516,3256,2.438,3366,4.395,3426,3.795,3657,3.36,3719,4.436,4261,2.92,4262,2.946,4307,3.642,5461,4.679,6032,4.436,7018,6.678,7020,4.436,7106,4.109,7107,5.048,7108,5.048,7109,5.048,7110,5.048,7111,5.048,7112,5.048]],["t/1589",[1,2.49,72,3.334,115,3.513,117,1.117,414,2.762,529,3.564,980,4.432,1715,4.128,2152,5.656,2230,4.55,2316,4.591,2363,6.603,2690,7.656,2770,4.377,3653,9.427,4325,6.688,6844,9.441,7113,10.186]],["t/1591",[1,2.622,12,2.149,17,2.947,38,2.456,44,1.189,50,4.391,72,3.797,73,1.99,78,3.358,87,3.678,115,2.306,117,1.176,136,2.987,148,1.706,150,2.782,156,1.625,168,2.23,172,1.547,205,4.736,209,2.72,267,1.638,391,1.908,490,2.75,552,4.626,584,3.1,622,3.531,639,3.462,659,4.122,663,2.897,670,2.987,693,3.902,723,4.052,764,2.838,784,5.283,788,6.709,794,4.823,923,1.756,957,3.534,985,2.004,1083,6.499,1097,2.74,1331,3.762,1411,5.146,1443,2.815,1790,3.042,1926,3.579,2062,2.922,2152,5.955,2237,4.45,2440,2.885,2490,3.974,2934,3.834,3465,4.823,3659,3.657,6997,8.187,7018,5.875,7020,5.875,7114,6.197,7115,5.443,7116,6.687,7117,6.687,7118,6.687,7119,6.687,7120,6.687,7121,6.687,7122,6.687,7123,6.687,7124,5.635,7125,6.687,7126,5.635]],["t/1594",[3,3.135,19,3.931,21,3.515,22,4.655,27,6.159,43,2.641,84,3.813,87,2.604,91,3.503,94,2.561,95,2.87,117,1.341,168,2.533,213,4.943,220,4.908,451,5.706,463,2.589,470,2.326,473,2.233,474,2.797,510,2.217,575,3.111,607,2.081,788,4.749,822,3.043,867,2.343,876,5.998,895,4.152,909,4.698,998,2.228,1062,3.438,1066,5.017,1170,4.331,1557,8.029,1607,3.021,1801,5.331,1904,3.836,2005,7.037,2230,3.391,2440,3.276,3028,4.648,7127,7.592,7128,5.585,7129,7.592,7130,5.998,7131,7.592]],["t/1597",[33,3.138,38,3.511,83,2.327,117,1.048,123,2.943,168,3.189,208,3.767,271,3.522,296,3.115,529,3.346,681,4.29,879,5.53,971,5.083,1009,3.405,1019,4.433,4079,6.553,4165,8.502,4166,8.861,4167,8.861,4168,6.772,4169,5.268,4170,5.915,4171,7.782]],["t/1599",[72,3.359,83,2.429,117,1.125,693,5.987,694,5.009,971,7.006,994,6.282,1547,5.382,2331,6.282,3728,8.876,3806,7.712,4165,9.507]],["t/1601",[1,1.887,33,3.372,78,3.876,193,2.843,242,3.876,243,2.002,259,1.456,338,3.747,412,4.2,414,2.093,415,4.775,492,4.059,615,3.761,621,2.254,663,3.344,719,5.136,814,3.895,942,5.835,971,6.546,1399,3.768,1483,4.775,1552,4.883,1841,2.834,1948,5.795,2018,3.831,2043,5.21,2118,4.253,2171,3.289,2305,4.221,2316,3.479,2492,5.21,2673,4.677,2751,4.544,2975,4.253,3118,6.504,3502,6.8,3511,5.354,3857,6.097,4165,8.883,4170,4.775,4172,6.504]],["t/1603",[1,1.54,5,0.681,30,1.078,33,2.213,38,0.451,44,2.505,47,1.142,73,0.946,83,0.449,87,0.421,97,0.379,113,1.854,117,0.691,123,0.378,148,2.001,156,0.553,163,1.082,164,1.618,165,0.53,172,1.345,193,1.171,208,2.106,220,1.099,242,1.991,243,0.59,258,0.469,259,0.429,339,2.107,406,0.61,412,1.587,414,1.576,420,1.235,486,2.088,492,2.296,505,0.658,579,0.454,584,0.57,586,1.426,613,1.587,615,1.163,617,2.458,619,0.559,620,3.602,621,1.969,645,2.183,654,0.922,663,0.532,687,2.603,694,0.6,756,1.076,764,2.235,775,0.666,796,5.792,814,2.274,834,2.168,879,0.711,957,0.466,971,6.056,998,0.932,1009,3.991,1052,1.457,1125,0.581,1399,1.935,1431,0.575,1483,1.966,1552,2.508,1596,0.454,1612,2.38,1773,1.227,1841,2.134,1874,1.328,2018,1.13,2043,2.676,2118,1.751,2171,1.354,2233,0.752,2239,3.258,2240,0.769,2275,2.043,2304,1.77,2305,5.429,2316,3.919,2359,7.421,2360,8.307,2425,0.667,2449,1.365,2673,1.379,2751,2.334,2754,0.662,2951,3.958,2954,0.886,2975,1.751,3357,1.751,3502,3.97,3605,0.923,3607,1.457,3659,2.88,3818,1.966,3836,1.798,3837,1.751,3838,3.131,3839,2.51,3841,4.16,4134,2.51,4145,9.327,4165,8.152,4170,3.258,4173,2.945,4174,2.109,4175,2.109,4176,2.109,4177,2.109,4178,2.109,4179,2.109,4180,2.109,4181,2.109,4182,2.109,4183,2.109,4184,1.999,4185,1.139,4186,1.139,4187,1.139,4188,1.798,4189,1.139,4190,3.674,4191,1.139,4192,1.139,4193,1.139,4194,1.139,4195,1.139,4196,1.139,4197,1.139,4198,1.139,4199,1.139,4200,1.139,4201,1.139,4202,1.139,4203,4.314,4204,1.139,4205,1.08,4206,1.08,4207,1.08,4208,1.08,4209,1.08,4210,4.314,4211,4.314,4212,4.314,4213,4.314,4214,4.314,4215,4.314,4216,4.314,4217,4.314,4218,4.314,4219,4.314,4220,1.139,4221,1.139,4222,2.945,4223,1.139,4224,1.139,4225,2.109,4226,4.314,4227,4.314,4228,4.314,4229,4.314,4230,4.314,4231,1.139,4232,4.314,4233,4.314,4234,4.314,4235,4.314,4236,4.314,4237,1.139,4238,1.139,4239,1.139,4240,2.945,4241,2.945,4242,4.314,4243,4.314,4244,4.314,4245,4.314,4246,4.314,4247,1.139,4248,4.314,4249,4.314,4250,4.314,4251,4.314,4252,4.314,4253,2.109,4254,3.674,4255,5.387,4256,1.139,4257,1.139,4258,1.139]],["t/1605",[1,2.056,30,1.722,33,2.761,44,2.476,117,1.192,148,2.773,172,1.947,208,2.48,243,2.182,259,1.587,414,2.281,420,4.568,492,3.324,613,4.201,615,3.08,620,4.993,621,2.457,740,3.863,744,4.472,753,3.487,814,2.837,834,3.139,971,4.472,980,3.661,1399,4.107,1596,3.109,1841,3.089,2018,4.176,2078,6.323,2673,5.098,2754,4.535,3923,6.847,4134,6.646,4165,6.069,4170,5.205,4172,7.089,4188,6.646,4259,7.797]],["t/1608",[73,2.188,87,3.866,97,3.069,117,1.09,180,3.622,181,3.255,196,3.772,203,5.731,219,2.426,240,1.669,243,1.907,266,3.16,391,2.099,414,3.275,529,2.573,555,2.667,612,2.147,626,3.81,648,5.288,748,5.18,877,4.115,914,3.186,923,1.931,997,2.619,1204,3.002,1404,4.708,2440,3.173,4746,4.55,7001,5.809,7132,7.353,7133,9.946,7134,7.353,7135,7.353,7136,7.353,7137,7.353,7138,7.353,7139,7.353,7140,7.353,7141,6.815,7142,7.353,7143,7.353,7144,7.353,7145,7.353,7146,7.353]],["t/1610",[87,3.192,93,5.401,96,3.664,97,2.872,117,1.02,196,3.951,219,3.071,414,3.687,526,3.472,538,2.953,557,3.439,576,3.007,607,2.551,626,3.565,748,3.565,866,4.138,914,4.032,1672,6.378,1975,7.162,2143,6.283,7141,8.626,7147,7.843,7148,9.307,7149,9.307]],["t/1615",[284,8.959,1738,9.556,2359,6.943,2754,6.113,4297,7.656]],["t/1617",[7,1.081,11,1.462,20,1.911,21,1.909,30,1.36,33,2.181,43,1.475,71,2.748,73,1.261,75,2.285,76,2.058,77,2.336,83,1.832,85,1.199,96,3.226,117,1.017,118,1.582,122,1.731,123,1.305,138,1.308,139,2.41,148,1.081,168,1.414,172,2.331,187,2.152,203,1.868,208,2.97,209,1.724,245,1.663,249,1.956,259,0.799,262,1.975,267,1.038,271,4.262,285,4.5,398,3.019,414,1.802,461,4.217,473,3.143,474,1.562,488,1.43,510,1.238,541,2.519,542,2.821,555,1.538,574,2.595,576,2.647,597,2.562,621,1.238,624,2.117,659,3.15,668,2.479,710,2.952,781,1.681,814,1.43,830,3.877,837,2.784,890,1.965,908,1.567,955,1.792,978,3.18,980,2.891,987,1.514,994,4.068,1008,1.757,1014,1.995,1030,2.209,1064,2.623,1115,2.496,1135,2.682,1176,5.113,1177,1.406,1181,3.377,1184,3.349,1187,3.937,1204,1.731,1214,2.209,1231,2.058,1248,2.411,1249,2.224,1253,2.168,1267,2.519,1273,1.657,1355,2.623,1374,2.748,1417,2.519,1439,2.569,1449,3.337,1475,2.748,1477,3.441,1485,2.748,1599,1.75,1607,2.644,1640,1.893,1678,2.129,1732,3.377,1778,1.995,1816,1.845,1871,2.748,1961,3.226,1966,2.142,1985,2.905,2062,1.852,2137,3.003,2140,3.349,2157,1.885,2177,4.87,2230,1.893,2257,3.003,2317,3.186,2318,3.003,2380,1.975,2415,2.302,2440,3.536,2443,2.354,2531,2.748,2674,2.254,2751,2.496,2881,2.663,2899,2.318,2925,3.349,2975,2.336,3030,2.682,3659,2.318,3810,2.411,4298,5.599,4299,3.725,4300,3.725,4301,3.186,4302,3.45,4303,3.349,4304,3.725,4305,3.572,4306,3.725,4307,3.058,4308,3.349,4309,3.725,4310,3.572,4311,3.349,4312,3.119]],["t/1619",[1,3.114,38,3.487,77,5.232,83,2.318,95,3.589,117,1.287,151,5.272,156,2.852,229,3.238,259,1.791,287,3.176,414,3.183,433,6.008,576,3.068,1062,4.3,1208,4.34,1213,5.313,1799,5.272,1841,3.487,1961,4.611,2674,5.048,2992,8.002]],["t/1621",[1,2.961,22,2.497,30,1.343,83,1.296,117,0.719,137,2.679,138,2.838,166,3.295,187,2.125,194,4.013,208,3.392,210,2.171,221,3.135,267,1.607,271,3.388,285,4.107,297,3.122,473,1.93,578,3.615,624,3.276,646,4.565,647,3.828,648,3.488,649,2.88,660,2.808,665,4.017,734,3.562,737,2.985,775,3.108,802,2.27,817,4.922,912,3.088,964,3.671,971,3.488,980,2.855,998,1.925,1011,3.419,1030,3.419,1071,3.419,1177,2.177,1208,2.999,1277,3.465,1397,4.733,1412,5.184,1449,3.295,1521,3.731,1530,3.828,1678,3.295,2033,4.43,2055,4.43,2060,3.315,2138,4.569,2210,4.733,2316,2.957,2506,4.308,2581,4.762,2703,4.308,2881,4.611,2899,3.589,3797,3.828,4313,4.569,4314,4.648,4315,7.658,4316,5.529,4317,4.932,4318,4.827,4319,7.485,4320,4.497,4321,5.529,4322,4.569]],["t/1623",[1,2.926,7,2.501,72,2.358,80,3.555,83,2.364,85,2.037,86,2.19,94,2.429,116,3.339,117,1.075,139,2.118,153,4.062,177,3.292,183,3.803,187,2.333,206,5.364,208,3.529,217,4.03,250,2.886,263,3.049,271,2.653,607,2.689,626,2.759,659,2.768,775,2.871,781,1.822,786,3.855,869,4.062,887,4.456,912,5.248,993,4.3,998,2.113,1013,3.406,1024,3.261,1097,2.951,1205,3.276,1231,3.497,1455,5.577,1791,3.596,1987,4.13,2171,3.069,2388,4.862,2570,5.25,2581,5.078,2881,2.886,2913,5.298,3502,4.24,4100,4.611,4323,6.328,4324,6.328,4325,6.44,4326,6.328,4327,5.015]],["t/1625",[1,1.312,17,1.028,30,2.4,33,3.441,38,0.857,41,1.052,44,2.025,73,1.908,77,2.232,83,2.344,84,1.172,96,1.595,117,0.796,123,0.718,138,0.72,150,2.234,156,1.764,157,3.118,169,1.843,172,0.937,173,1.46,175,1.115,186,0.945,187,0.756,201,2.763,214,1.414,219,1.337,241,1.258,243,1.051,245,3.122,259,0.44,263,2.657,267,0.572,414,1.456,437,1.967,462,1.338,463,0.796,486,1.047,488,3.325,490,2.637,555,3.576,562,1.654,576,1.309,597,1.562,611,2.252,612,0.681,615,1.483,619,2.442,621,0.681,624,2.023,646,2.011,649,1.024,659,0.897,666,0.963,671,2,712,4.26,723,3.254,732,0.735,739,1.414,748,0.894,753,3.75,786,2.169,814,0.787,832,2.139,834,0.871,837,1.532,875,0.752,923,0.613,937,1.575,942,1.179,953,1.011,957,0.885,964,1.306,969,1.165,971,1.24,978,1.279,980,1.763,994,1.428,1004,3.928,1009,2.585,1021,1.35,1036,1.276,1097,0.956,1162,1.35,1187,1.121,1204,0.953,1300,1.444,1331,3.45,1431,1.093,1440,1.553,1443,0.982,1446,3.254,1460,4.934,1465,1.826,1489,1.224,1490,1.625,1559,1.796,1596,2.941,1644,1.717,1712,1.267,1722,1.077,1727,0.829,1753,2.011,1776,4.147,1777,1.512,1830,1.258,1841,2.355,1878,1.428,1904,2.047,1946,1.754,1974,1.186,2018,1.158,2062,2.346,2154,2.78,2157,4.216,2230,1.042,2260,2.851,2271,1.145,2275,1.024,2305,1.276,2391,1.575,2581,5.105,2673,1.414,2674,2.154,2693,4.542,2751,3.161,2768,1.717,2770,1.741,2785,1.754,2819,1.683,2861,4.923,2872,1.46,2881,3.425,2892,1.717,2893,1.754,2918,2.87,2940,1.683,2965,3.053,2975,4.385,3030,5.407,3078,2.455,3102,1.599,3135,2.821,3220,1.653,3318,2.455,3511,1.216,3659,2.936,3810,4.86,3893,1.754,4270,3.456,4315,1.683,4325,1.532,4328,10.162,4329,2.05,4330,2.05,4331,2.05,4332,1.843,4333,5.634,4334,4.37,4335,3.298,4336,1.428,4337,1.843,4338,4.718,4339,4.132,4340,2.05,4341,1.532,4342,2.05,4343,3.298,4344,3.201,4345,1.966,4346,2.05,4347,2.05,4348,2.05,4349,1.899,4350,1.387,4351,2.05,4352,1.966,4353,2.05,4354,2.05,4355,1.843,4356,2.05,4357,2.05,4358,1.717,4359,2.05,4360,1.754,4361,2.05,4362,2.05,4363,2.05,4364,2.05,4365,2.05,4366,2.05,4367,3.56,4368,3.56,4369,2.05,4370,2.05,4371,1.966]],["t/1627",[1,2.698,30,1.325,44,0.729,71,2.659,72,2.626,79,4.562,80,3.96,81,5.425,83,2.179,84,3.252,86,1.248,96,1.615,97,1.266,117,0.999,123,1.263,129,3.457,130,3.457,134,3.241,139,1.905,144,3.653,145,2.314,146,2.152,148,1.046,151,2.278,156,1.949,160,4.549,164,1.675,169,1.866,170,2.212,173,2.566,175,3.834,177,1.875,183,3.42,187,1.329,194,2.448,210,3.015,224,1.992,226,1.911,238,4.64,243,1.679,255,2.486,263,2.013,267,2.232,271,2.386,285,2.893,297,1.905,339,1.858,401,2.085,419,1.875,436,4.862,443,2.716,470,1.257,473,1.207,490,1.688,501,2.512,510,1.198,525,2.037,528,1.971,529,1.436,538,2.055,576,2.092,598,1.902,615,1.502,622,2.166,645,1.701,649,2.842,668,1.531,678,2.196,737,1.866,744,2.181,748,1.571,770,3.443,781,2.03,814,1.384,867,1.999,911,2.659,912,1.931,978,2.044,1009,1.461,1021,2.373,1024,1.858,1028,1.992,1049,3.713,1090,2.037,1170,1.748,1205,1.866,1247,3.241,1312,2.566,1341,3.018,1355,2.538,1402,2.462,1404,2.627,1457,2.373,1596,1.516,1618,1.638,1643,2.731,1717,2.538,1722,1.893,1841,1.507,1904,2.073,1958,2.227,1985,2.812,1988,1.502,2074,2.486,2157,1.824,2181,2.731,2230,2.893,2363,2.659,2451,2.731,2506,2.694,2518,2.333,2569,3.084,2581,2.124,2587,4.51,2608,2.659,2768,3.018,2881,1.644,2885,2.959,2886,3.157,2887,3.157,2892,3.018,2893,6.03,2923,2.627,2931,3.157,2934,2.353,2973,2.596,2975,2.261,3102,2.812,3481,3.157,3486,3.457,3516,6.245,4372,3.605,4373,3.605,4374,3.605,4375,3.241,4376,3.241,4377,3.339,4378,3.605,4379,3.457,4380,3.457,4381,3.339,4382,3.605,4383,3.339,4384,3.605,4385,3.605,4386,3.241,4387,3.605,4388,3.605,4389,3.605,4390,3.605,4391,3.241,4392,3.605,4393,3.241]],["t/1629",[1,2.777,5,1.6,7,1.906,44,1.328,77,4.117,91,3.447,115,2.577,117,0.819,123,2.3,144,4.214,148,1.906,166,5.049,175,4.804,222,4.248,240,1.696,259,1.409,267,2.462,411,1.729,438,3.589,445,4.056,465,5.389,495,3.133,497,4.783,529,2.614,579,2.761,660,3.197,668,2.787,670,3.337,697,3.516,737,3.399,748,2.862,781,1.89,875,2.407,969,3.73,985,2.239,1014,3.516,1024,3.383,1273,2.921,1281,4.086,1618,2.983,1801,3.919,1942,6.572,1943,4.359,2074,4.527,2152,4.148,2254,4.321,2377,5.749,2396,4.399,2581,3.869,2662,4.214,2881,4.029,3516,5.12,4386,5.902,4394,5.615,4395,6.081,4396,6.081,4397,5.749,4398,6.564,4399,4.148,4400,5.615,4401,6.564]],["t/1631",[1,1.71,3,2.27,12,1.076,30,1.83,33,2.296,34,2.094,35,2.029,38,1.229,40,1.756,44,0.595,47,1.203,48,1.3,72,1.096,79,1.904,80,1.653,83,2.094,85,0.947,94,1.129,106,1.626,113,1.953,114,3.366,117,0.767,123,1.031,124,1.99,148,0.854,156,1.336,165,1.445,175,2.627,208,2.062,210,3.634,219,1.105,222,1.904,224,1.626,229,1.142,240,0.76,242,1.681,243,0.868,250,2.203,263,1.041,271,3.295,276,1.626,285,3.995,291,1.873,298,3.402,339,1.516,391,0.955,403,2.228,412,1.142,414,0.908,420,3.798,423,1.888,470,1.026,488,1.129,491,2.353,492,2.764,511,1.523,520,1.734,529,2.834,530,2.413,535,1.888,555,1.214,562,2.244,576,1.082,584,1.552,612,1.606,613,1.672,615,1.226,618,1.831,619,1.523,649,2.413,659,1.287,660,1.433,693,1.953,694,2.684,710,3.829,720,3.659,737,1.523,770,1.78,775,2.618,785,1.723,794,2.415,814,1.854,820,1.196,834,2.61,875,1.771,879,1.936,890,1.552,923,0.879,957,2.085,973,2.295,978,1.057,1008,1.388,1009,1.192,1036,1.831,1062,2.489,1064,2.071,1085,4.045,1177,1.824,1187,1.608,1195,1.971,1200,1.78,1208,1.53,1211,1.41,1219,4.475,1245,1.99,1248,1.904,1265,2.143,1278,1.768,1399,1.634,1411,2.576,1440,2.228,1443,1.41,1453,4.343,1489,1.756,1518,2.17,1607,1.332,1617,1.99,1640,1.495,1644,2.463,1678,2.761,1715,1.357,1717,2.071,1722,1.545,1751,1.92,1762,2.821,1776,1.745,1777,2.17,1788,1.904,1807,4.319,1825,1.953,1878,2.05,1904,2.778,1914,1.672,1923,1.953,1948,1.888,1953,2.094,1961,1.626,2010,2.094,2027,2.143,2118,1.845,2157,1.489,2186,2.009,2220,2.371,2230,2.456,2260,1.489,2295,3.007,2304,1.495,2313,1.936,2331,2.05,2356,5.162,2415,4.856,2608,2.17,2649,2.371,2674,3.719,2751,1.971,2815,1.845,2881,1.342,2965,3.126,2975,1.845,3005,2.331,3030,2.118,3032,2.029,3087,2.645,3104,2.17,3469,3.894,3770,2.415,3810,3.126,3931,2.118,4100,2.143,4170,2.071,4327,5.639,4393,2.645,4399,4.496,4402,2.942,4403,2.942,4404,5.797,4405,2.942,4406,2.645,4407,2.942,4408,2.942,4409,2.645,4410,2.645,4411,2.228,4412,5.526,4413,2.576,4414,2.942,4415,2.821,4416,2.645,4417,2.516,4418,2.942,4419,2.516,4420,2.645,4421,2.645,4422,2.645,4423,2.942]],["t/1633",[1,2.45,5,1.593,6,3.781,7,1.252,22,1.867,26,3.828,38,1.802,39,2.944,44,0.872,83,1.979,85,1.388,90,2.732,94,1.655,117,0.815,186,1.988,208,1.447,210,1.624,229,1.674,259,1.403,263,2.313,271,2.74,338,3.612,412,2.537,420,2.664,470,1.503,473,2.642,510,2.172,514,3.736,530,2.154,576,2.403,579,1.813,612,1.433,619,3.384,649,3.264,760,2.37,770,2.609,771,3.476,775,2.177,787,2.058,809,1.598,814,3.381,834,2.775,837,3.222,878,4.822,879,4.302,912,2.309,978,2.835,987,1.753,1016,5.876,1024,2.222,1049,2.814,1072,2.479,1081,3.476,1090,2.436,1115,2.889,1167,3.877,1177,1.628,1180,2.704,1193,4.135,1486,3.476,1672,3.363,1727,1.743,1778,2.309,1807,2.37,1825,2.863,1841,2.732,1846,2.974,1904,2.479,1915,3.54,2018,3.693,2021,6.074,2027,3.142,2033,3.313,2118,2.704,2138,3.417,2157,2.182,2161,3.476,2206,3.61,2223,3.105,2230,2.192,2261,3.363,2284,3.54,2295,4.913,2305,2.684,2356,4.566,2415,4.877,2451,3.266,2570,2.627,2881,4.317,2975,2.704,3609,3.363,3810,2.79,4170,3.036,4312,3.61,4325,4.884,4399,4.988,4424,3.776,4425,3.61,4426,3.994,4427,4.312,4428,9.466,4429,3.476,4430,3.877,4431,4.312,4432,4.312,4433,4.312,4434,4.312,4435,4.312,4436,4.312,4437,4.312,4438,4.312,4439,3.688]],["t/1635",[1,0.552,7,1.599,17,0.995,26,1.162,30,0.806,33,2.334,38,2.302,44,2.425,47,0.812,48,0.877,72,1.289,77,2.17,80,1.115,83,1.034,84,1.134,87,0.774,96,2.061,97,1.215,114,2.411,115,1.358,117,0.432,124,2.34,148,1.335,150,1.638,156,0.549,169,1.791,170,2.123,172,1.645,173,1.413,175,2.995,196,0.675,199,1.397,208,1.161,210,0.747,214,0.788,240,0.513,250,0.905,263,2.904,267,0.964,271,1.929,285,1.009,291,5.794,335,5.633,350,2.258,412,0.77,420,2.138,470,0.692,483,0.859,488,0.762,510,1.15,555,0.819,557,0.835,562,0.922,565,1.318,575,0.925,576,0.73,579,0.835,612,1.15,613,1.128,615,0.827,617,2.079,619,1.027,621,0.659,649,0.991,659,2.012,663,1.706,670,1.759,671,1.115,705,1.629,710,1.573,712,1.209,719,1.004,720,4.172,722,1.525,723,2.386,748,1.508,770,3.333,775,2.286,781,0.571,787,0.947,802,0.781,814,2.114,820,1.87,830,1.318,834,2.339,837,1.483,882,1.141,886,1.254,906,1.966,923,0.593,957,0.856,959,1.573,969,1.128,978,1.243,1009,2.533,1019,1.826,1028,1.096,1052,5.98,1075,1.306,1090,1.121,1204,2.559,1208,1.032,1273,0.883,1278,1.192,1404,1.446,1446,1.368,1460,3.03,1465,1.018,1471,1.121,1473,2.491,1483,4.399,1530,1.318,1565,1.483,1596,0.835,1672,1.548,1698,2.386,1773,2.822,1776,4.07,1777,2.552,1788,3.565,1790,1.027,1807,1.091,1841,0.829,1848,1.738,1874,1.318,1896,1.274,1904,1.141,1974,1.148,2004,1.903,2019,1.573,2026,1.661,2043,1.525,2062,0.987,2157,2.328,2232,1.503,2240,1.413,2288,1.254,2295,2.153,2327,1.629,2328,2.491,2356,4.269,2391,2.658,2415,2.843,2440,0.974,2468,1.209,2519,1.446,2634,6.663,2674,2.093,2751,3.691,2861,6.015,2872,1.413,2923,1.446,2973,1.429,2974,1.838,2975,2.885,3041,1.661,3058,1.599,3102,2.699,3366,2.277,3596,1.838,3659,1.235,3701,2.239,3768,1.738,3810,3.565,3918,2.34,3931,1.429,4169,1.244,4322,1.573,4360,1.697,4399,3.948,4404,2.552,4409,1.784,4410,1.784,4411,4.733,4412,3.111,4413,4.029,4440,1.599,4441,1.573,4442,3.318,4443,3.352,4444,1.984,4445,1.984,4446,1.984,4447,1.984,4448,4.261,4449,1.738,4450,5.508,4451,1.984,4452,5.472,4453,1.984,4454,7.824,4455,1.984,4456,1.984,4457,6.133,4458,1.984,4459,7.38,4460,1.984,4461,1.984,4462,1.984,4463,1.984,4464,1.984,4465,1.984,4466,3.46,4467,4.6,4468,3.111,4469,1.984,4470,1.984,4471,2.658,4472,1.503,4473,1.738,4474,1.984,4475,1.984,4476,1.525,4477,1.784,4478,1.784,4479,1.429,4480,1.903,4481,3.852,4482,1.984,4483,1.784,4484,1.483,4485,1.784,4486,3.852,4487,1.784,4488,1.984,4489,3.46,4490,1.984,4491,1.984,4492,1.984,4493,1.984]],["t/1637",[7,2.174,22,2.244,28,2.945,38,3.13,85,1.668,114,3.611,169,2.683,194,2.23,208,2.513,211,4.052,241,3.18,249,2.722,268,3.442,297,1.735,298,3.65,470,2.611,473,1.735,510,1.723,529,2.983,576,1.906,612,1.723,615,2.159,659,4.214,660,4.283,734,3.203,759,5.035,770,3.136,775,1.727,830,3.442,867,1.82,906,2.945,955,2.494,957,2.237,966,4.433,978,1.862,1014,2.776,1091,3.301,1181,2.998,1204,2.408,1211,3.589,1239,3.412,1253,3.016,1283,3.301,1308,2.98,1477,5.183,1483,3.65,1530,4.974,1678,2.962,1698,3.574,1749,3.412,1776,5.714,1807,2.849,1870,4.66,2230,3.807,2232,5.674,2240,5.332,2295,6.63,2305,5.474,2317,4.433,2478,3.157,2723,3.035,2899,4.662,2973,6.333,2999,4.043,3366,4.93,3918,3.505,4399,3.275,4404,5.526,4443,5.458,4481,6.271,4483,4.66,4486,6.271,4494,5.183,4495,6.734,4496,4.66,4497,5.183,4498,5.183]],["t/1639",[12,2.279,26,3.65,30,2.264,38,2.605,83,1.4,94,2.392,114,4.342,117,0.778,139,2.854,165,4.187,194,3.668,210,3.211,211,2.621,221,3.389,224,3.444,229,2.419,271,2.613,276,3.444,285,4.335,402,4.295,469,4.033,473,2.086,514,3.562,659,3.73,660,3.035,737,3.226,770,3.771,775,2.841,867,2.995,886,3.938,978,2.239,1014,3.338,1028,3.444,1030,3.696,1200,3.771,1211,2.986,1355,4.388,1443,2.986,1535,5.116,1807,3.425,2118,3.908,2181,4.721,2230,3.168,2295,3.879,2316,3.197,2581,3.673,2881,2.843,2973,4.488,3103,4.861,3797,4.138,3918,4.215,4399,5.388,4443,4.541,4481,5.218,4485,5.603,4486,7.14,4487,7.667,4495,5.603,4499,6.232,4500,6.232,4501,6.232,4502,4.657,4503,4.789,4504,5.977]],["t/1642",[12,2.871,36,3.443,72,2.061,73,1.874,85,2.526,90,2.312,117,1.238,123,1.938,136,2.812,137,2.57,138,1.943,169,2.864,172,1.457,229,2.147,240,1.429,245,2.47,267,2.188,271,2.319,473,1.852,505,3.37,529,3.126,562,2.57,612,2.608,614,3.181,621,2.608,654,2.551,723,3.815,760,3.041,764,2.672,781,2.26,820,3.191,867,1.943,875,2.878,890,2.919,966,4.732,1036,3.443,1051,5.125,1056,3.674,1062,4.044,1115,3.707,1200,3.347,1283,3.523,1373,7.008,1473,8.062,1521,3.58,1530,6.057,1640,2.812,1678,3.162,1844,3.855,1976,3.144,2021,3.815,2145,3.551,2230,4.636,2234,4.384,2271,3.091,2288,3.496,2356,3.2,2581,3.26,2881,2.523,3246,5.125,3463,7.488,4399,4.959,4440,6.327,4443,4.031,4472,4.191,4477,4.974,4478,4.974,4505,5.532,4506,4.542,4507,7.848,4508,5.532,4509,4.845,4510,4.081,4511,5.306]],["t/1644",[1,1.406,22,2.189,30,2.02,38,2.113,49,4.324,83,1.653,84,2.889,85,1.627,115,1.984,117,0.631,123,1.771,137,3.418,138,1.775,148,3.164,150,5.001,156,2.034,172,1.331,175,2.749,187,1.864,190,2.84,193,2.119,195,3.729,196,3.593,197,2.681,199,3.56,200,3.683,206,3.147,214,2.007,236,3.56,240,1.306,473,1.692,504,3.147,529,2.013,530,2.525,586,2.581,612,1.68,628,4.683,630,3.147,659,2.211,660,2.462,764,2.442,781,1.455,809,1.873,881,3.452,955,2.432,957,2.182,978,1.816,1015,2.84,1115,4.929,1162,3.327,1175,3.778,1177,2.777,1211,2.422,1332,2.809,1471,2.856,1480,3.219,1596,2.126,1736,4.683,1819,3.101,1923,3.357,1943,3.357,1948,3.245,1990,4.324,2239,3.56,2271,2.824,2295,5.397,2466,4.006,2468,4.481,2649,4.075,2662,3.245,3058,4.075,3469,5.93,3770,4.15,3918,5.865,4399,5.479,4420,4.545,4421,4.545,4422,4.545,4440,4.075,4512,5.055,4513,5.055,4514,5.055,4515,4.848,4516,3.943,4517,7.796,4518,5.055,4519,4.848,4520,5.055,4521,5.055,4522,5.055,4523,5.055,4524,5.055]],["t/1646",[138,3.528,285,5.106,4406,9.032,4525,10.045]],["t/1648",[5,1.653,44,2.053,72,3.363,77,4.253,79,6.568,80,6.509,87,2.647,88,3.578,115,2.662,148,1.969,240,1.752,267,1.89,291,4.319,437,3.747,584,3.578,620,3.544,748,2.956,820,4.126,906,5.13,1281,4.221,1988,2.825,2388,5.21,2674,4.103,2861,4.775,3086,5.374,3366,5.942,4479,7.791,4484,5.068,4526,6.781,4527,6.781,4528,6.781,4529,10.148,4530,6.781,4531,6.097,4532,6.781,4533,6.781,4534,5.678,4535,6.781,4536,6.097,4537,6.781,4538,6.781,4539,6.781,4540,6.781,4541,6.781]],["t/1650",[44,2.019,72,2.949,79,5.122,80,6.14,115,3.107,148,2.298,267,2.206,525,4.472,719,4.005,781,2.279,820,4.666,906,5.671,1003,5.919,1273,3.522,1925,6.627,2062,3.936,2260,4.005,2284,6.498,3366,6.568,4484,5.915,4542,8.727,4543,7.915,4544,9.979]],["t/1652",[73,2.905,138,3.012,267,2.391,271,3.596,470,2.99,491,4.177,510,2.85,660,4.177,759,4.482,802,3.376,906,4.874,957,3.701,1530,5.695,1618,3.898,1788,5.55,2295,5.338,2723,5.022,2905,6.914,3516,6.689,3873,6.327,3918,5.801,4399,5.419,4443,6.249,4479,6.175,4542,6.327]],["t/1654",[1,1.625,5,0.527,7,1.696,27,2.7,30,0.504,34,1.539,38,0.904,39,1.476,44,1.792,48,0.955,51,1.236,72,0.805,73,0.732,79,2.412,80,4.047,85,0.696,87,0.844,88,1.141,95,0.93,115,0.849,117,0.822,126,0.962,138,2.052,139,0.724,148,1.696,150,1.024,152,1.893,153,1.388,156,1.031,160,1.228,172,2.147,174,3.452,187,1.811,194,1.603,198,2.094,201,1.266,202,1.743,206,1.346,210,1.403,213,1.062,214,0.858,218,1.48,219,1.4,229,0.839,236,1.522,238,1.423,240,0.559,243,1.1,245,1.664,248,1.336,250,2.241,259,1.254,262,1.146,263,1.319,267,1.369,285,1.894,291,1.377,297,1.644,338,2.059,402,0.955,421,1.593,436,1.491,437,1.195,443,2.345,452,1.104,470,2.036,481,2.597,488,0.83,492,2.963,495,1.032,514,1.236,529,1.484,530,1.08,532,1.522,560,1.075,562,2.282,565,1.436,576,1.37,582,1.356,584,1.141,586,1.104,602,1.539,612,1.239,613,1.228,614,1.243,620,1.948,636,2.182,649,1.861,660,1.815,666,1.016,668,1.583,671,1.215,688,1.743,748,1.625,753,1.02,769,2.475,781,1.073,794,4.033,802,2.594,820,2.375,821,1.686,822,1.7,861,1.476,867,0.759,875,1.801,886,1.366,890,1.141,895,1.346,906,2.118,908,3.03,923,0.646,942,2.143,953,1.838,967,1.539,969,1.228,991,1.08,993,2.563,1003,1.282,1009,1.991,1010,1.713,1019,1.141,1024,1.114,1027,1.539,1028,1.195,1030,1.282,1033,1.243,1049,1.411,1062,1.114,1149,3.12,1156,1.638,1169,2.453,1170,1.049,1172,2.073,1177,1.407,1187,2.686,1208,1.124,1211,1.036,1214,1.282,1231,2.059,1253,1.258,1271,2.225,1273,0.962,1279,1.411,1281,1.346,1327,1.377,1344,1.366,1417,1.462,1425,2.003,1431,1.152,1443,1.036,1449,1.236,1475,1.595,1476,1.944,1489,3.933,1552,3.537,1566,1.849,1599,1.751,1606,1.944,1613,1.686,1618,0.982,1629,1.539,1647,1.436,1701,1.686,1727,0.874,1778,1.158,1791,1.228,1807,1.188,1921,2.432,1935,1.661,1957,2.716,1967,2.791,1976,4.847,1984,2.954,1988,0.901,1989,1.423,2021,2.57,2032,1.228,2055,1.661,2074,2.57,2075,1.236,2218,1.893,2220,1.743,2230,1.099,2254,1.423,2271,2.082,2295,1.346,2298,1.661,2300,1.377,2304,1.894,2309,2.073,2313,2.453,2416,1.638,2468,1.317,2478,1.317,2569,3.188,2599,2.073,2813,2.716,2861,1.522,2903,4.256,2926,1.893,3028,1.506,3086,1.713,3104,3.624,3154,1.713,3249,1.893,3318,1.491,3366,2.453,3516,2.907,3847,2.003,4080,1.944,4270,5.233,4308,1.944,4339,1.893,4350,2.521,4416,1.944,4468,1.944,4479,1.557,4484,1.616,4503,1.661,4531,1.944,4534,1.81,4542,1.595,4545,2.162,4546,2.162,4547,2.162,4548,2.162,4549,2.162,4550,2.162,4551,2.162,4552,1.944,4553,2.162,4554,2.162,4555,2.162,4556,2.162,4557,2.162,4558,3.727,4559,2.162,4560,2.162,4561,1.944,4562,2.162,4563,3.727,4564,2.162,4565,2.162,4566,2.162,4567,2.162,4568,2.162,4569,2.162,4570,2.162,4571,1.944,4572,2.162,4573,3.188,4574,1.893,4575,2.162,4576,1.944,4577,2.162,4578,2.162,4579,2.073,4580,2.162,4581,2.162,4582,6.589,4583,2.162,4584,1.686,4585,2.073,4586,3.574,4587,1.893,4588,2.003,4589,3.574,4590,3.574,4591,3.727,4592,2.162,4593,1.522,4594,2.073,4595,2.162,4596,2.162,4597,2.162,4598,2.162,4599,2.162,4600,1.25]],["t/1656",[7,1.122,27,3.303,30,0.9,44,2.227,48,3.258,72,3.098,73,1.309,79,5.83,80,6.438,86,1.338,87,2.878,117,0.92,141,2.639,145,2.481,148,2.14,155,2.249,156,1.069,160,4.19,172,1.583,194,1.663,201,2.263,240,0.999,243,1.774,249,2.03,250,1.763,285,1.965,436,4.145,437,2.136,443,1.845,470,3.141,489,1.467,491,3.591,576,1.421,612,1.285,620,3.853,621,1.997,722,5.665,737,2.001,781,1.73,812,2.722,820,1.571,904,3.475,906,4.726,908,1.626,993,2.637,1003,2.292,1007,3.236,1009,1.567,1347,5.439,1417,2.614,1431,2.06,1449,2.209,1471,2.184,1547,2.307,1591,3.116,1599,1.816,1607,2.721,1617,2.614,1799,2.442,1949,3.769,1961,2.136,1967,2.196,1976,2.196,1984,3.063,1988,1.61,2075,2.209,2154,2.278,2254,2.544,2396,2.59,2557,3.015,2813,2.816,2932,3.58,3082,2.501,3102,5.751,3126,3.173,3366,4.853,3493,3.707,4270,5.851,4479,6.487,4536,5.403,4542,7.036,4552,8.1,4561,3.475,4571,3.475,4574,3.385,4576,3.475,4601,3.865,4602,3.865,4603,3.865,4604,3.865,4605,3.865,4606,7.373,4607,3.865,4608,3.865,4609,3.865,4610,6.01,4611,5.763,4612,3.865,4613,3.865,4614,3.306,4615,5.763,4616,3.58,4617,3.865,4618,3.865,4619,3.865,4620,3.865,4621,3.865,4622,3.58]],["t/1658",[115,3.463,142,6.778,172,2.323,249,4.633,461,5.166,463,3.424,491,4.296,538,3.185,802,3.473,817,5.374,969,5.013,978,3.169,1449,5.043,1599,4.146,1732,5.103,1735,6.428,2440,4.332,2581,5.199,2881,4.024,3078,6.084,4303,7.932]],["t/1660",[22,3.427,48,3.497,72,2.949,83,1.779,94,3.83,128,4.136,138,2.78,221,4.304,240,2.045,249,4.156,271,3.318,285,4.023,391,2.571,861,5.405,870,5.405,1015,4.446,1151,5.165,1178,6.77,1273,3.522,1629,5.635,1790,4.098,1844,5.515,1988,4.158,2223,5.699,2260,5.05,2298,6.081,3037,5.256,4270,4.856,4336,5.515,4337,7.116,4623,7.915,4624,7.915,4625,7.915,4626,7.915]],["t/1662",[83,1.968,85,2.819,138,3.076,271,3.672,285,4.453,491,4.266,520,5.162,645,4.132,694,4.867,759,4.578,868,4.894,906,4.978,908,3.684,978,3.147,1069,5.13,1776,5.195,1871,6.462,1988,3.649,2295,5.452,2723,5.13,3657,6.635,3918,5.924]],["t/1664",[43,2.685,115,2.662,142,5.21,144,4.353,148,2.946,150,3.211,172,1.786,187,2.5,193,3.785,197,3.596,265,4.19,267,1.89,412,2.632,483,2.936,529,2.701,620,3.544,659,2.966,668,2.88,787,3.237,802,3.995,820,2.757,834,2.88,978,3.887,1015,3.81,1024,4.652,1030,4.022,1033,6.221,1066,3.81,1132,5.21,1162,4.464,1177,2.56,1449,3.876,1715,3.127,1807,3.727,2055,5.21,2468,4.131,2478,4.131,3058,5.467,3236,4.883,4270,4.16,4317,5.801,4479,4.883,4484,5.068,4516,5.289,4517,6.097,4573,7.722,4627,5.467,4628,6.781,4629,6.282,4630,5.567]],["t/1667",[1,2.306,138,2.911,178,4.555,193,3.475,197,4.395,245,3.7,298,5.836,491,4.036,562,4.772,666,3.895,867,2.911,923,2.477,1904,4.765,1974,4.794,1976,4.709,2318,6.681,2570,5.049,2581,6.052,2881,4.684,2965,5.364,3078,5.716,3284,7.948,4399,5.237,4404,6.114,4449,7.258,4584,8.011]],["t/1669",[1,1.516,6,3.153,7,0.991,12,1.249,17,1.713,22,1.479,30,0.795,33,1.276,38,2.278,42,4.252,73,1.846,77,2.141,83,1.225,85,1.099,90,1.427,91,1.793,114,2.379,117,0.969,138,1.914,139,1.824,148,0.991,150,3.678,155,1.987,156,1.507,165,1.677,187,2.009,194,2.926,205,4.394,211,1.436,216,2.025,221,3.7,240,0.882,242,1.952,245,1.525,249,2.862,267,0.952,271,1.432,298,2.405,402,4.195,412,1.325,414,1.054,473,1.824,474,2.285,491,1.663,492,1.535,510,1.135,529,2.171,562,3.161,565,2.268,576,1.256,584,1.802,594,2.379,613,1.941,615,1.423,619,2.822,621,1.135,649,1.706,659,3.712,670,2.771,697,1.829,734,4.799,737,1.768,753,1.611,760,1.877,763,2.459,770,2.066,775,2.827,785,2,802,1.344,978,2.444,1004,4.363,1009,1.384,1033,1.963,1037,2.355,1049,2.229,1066,1.918,1071,2.025,1072,1.963,1097,2.542,1143,2.753,1174,2.706,1177,1.289,1199,2.921,1200,2.066,1211,2.612,1231,1.887,1260,2.431,1386,2.379,1431,1.82,1473,2.459,1477,3.212,1483,4.79,1489,2.039,1521,2.21,1535,2.803,1629,2.431,1685,2.706,1698,4.692,1717,2.405,1727,1.38,1735,2.488,1755,3.07,1791,1.941,1807,1.877,1871,2.519,1904,3.134,1948,4.985,1974,1.975,2062,2.711,2145,2.192,2151,2.859,2157,2.759,2171,1.656,2230,2.771,2260,1.728,2295,3.393,2305,2.126,2328,2.459,2380,2.89,2395,3.163,2496,2.552,2881,4.497,2923,2.488,2965,3.528,2973,4.899,2975,3.418,3078,2.355,3128,2.803,3266,6.524,3659,2.126,3741,2.431,4322,2.706,4341,2.552,4358,2.859,4399,4.299,4404,4.021,4439,2.921,4443,2.488,4452,2.991,4471,2.624,4584,2.664,4631,2.859,4632,3.07,4633,3.415,4634,5.451,4635,3.415,4636,3.415,4637,3.415,4638,3.415,4639,3.415,4640,3.415,4641,5.451,4642,3.415,4643,3.415,4644,3.415,4645,3.415,4646,3.415]],["t/1671",[1,2.116,4,2.517,6,4.4,21,1.731,26,4.454,30,1.233,83,1.19,87,2.066,90,3.72,117,0.949,126,2.356,151,3.345,156,1.464,161,4.904,172,2.003,221,2.879,229,2.055,235,2.894,240,1.368,245,2.364,259,1.136,267,2.481,271,2.22,285,2.691,427,2.974,470,1.846,473,2.546,508,5.006,612,1.76,615,2.206,624,3.009,649,3.799,659,2.316,742,3.581,770,5.386,787,2.527,809,1.962,814,2.919,911,3.906,978,3.702,993,3.906,1011,3.14,1014,2.835,1041,4.637,1072,3.044,1097,2.469,1099,4.01,1231,2.926,1239,3.485,1331,2.433,1415,4.068,1449,3.026,1717,3.728,1723,3.426,1760,4.637,1783,4.529,1791,3.009,1807,2.91,1825,3.516,1838,3.516,1974,3.062,1976,3.009,1988,2.206,2032,3.009,2121,3.689,2157,2.679,2179,4.13,2230,3.866,2232,4.01,2316,4.566,2415,3.271,2570,3.225,2619,2.91,2624,4.76,2812,4.196,2815,3.32,2881,2.415,2888,4.76,2934,3.455,2975,3.32,3662,3.858,3931,3.812,4391,4.76,4430,4.76,4632,6.838,4647,5.294,4648,4.76,4649,5.294,4650,5.585]],["t/1674",[28,3.387,44,1.206,74,8.394,83,2.134,86,3.729,97,2.093,128,4.322,211,2.507,214,2.367,219,2.239,229,2.314,240,1.54,249,3.13,258,2.59,267,2.647,420,3.683,463,2.314,481,4.153,538,2.986,586,4.849,681,4.223,757,3.276,781,1.716,786,3.631,822,2.719,834,2.531,914,2.939,957,2.573,997,4.635,1055,3.546,1066,4.646,1097,2.78,1159,5.632,1307,3.683,1618,3.758,1750,3.923,1773,3.657,1829,3.871,1918,3.513,1988,2.483,2060,3.427,2143,8.278,2180,2.616,3028,4.153,3506,3.072,4424,7.243,4593,4.197,7150,9.412,7151,6.287,7152,6.287]],["t/1676",[12,2.06,30,1.312,38,2.354,41,2.89,43,2.231,44,2.025,47,2.304,81,3.506,83,2.249,86,3.463,87,2.199,88,2.973,117,1.248,148,1.635,156,1.558,180,2.06,219,2.116,229,2.186,240,1.455,243,1.663,411,1.484,521,2.766,524,3.741,612,2.642,613,3.201,614,3.239,645,2.658,648,5.574,681,4.059,697,3.017,775,1.877,868,4.441,877,5.062,997,4.562,1025,3.201,1273,2.507,1478,5.612,1774,4.056,2016,3.432,2180,4.392,2440,3.904,3096,5.942,5033,7.949,5373,8.385,7153,6.411,7154,11.551,7155,6.411,7156,5.942,7157,5.942,7158,6.411,7159,5.942,7160,9.047,7161,9.047,7162,9.047,7163,9.047,7164,9.047,7165,6.411,7166,6.411]],["t/1678",[21,0.974,22,1.289,27,1.636,30,2.089,43,1.179,44,1.6,81,1.853,85,0.958,86,3.105,87,4.207,88,5.391,106,3.425,117,0.773,128,2.55,148,2.604,156,1.982,163,1.611,169,1.541,172,1.285,178,2.681,180,1.784,181,5.025,196,2.109,203,4.262,208,2.404,213,1.462,219,3.19,220,1.636,229,1.156,250,1.358,258,1.294,263,1.726,290,1.867,391,2.328,414,3.327,470,2.161,490,1.394,541,2.014,575,1.388,645,2.301,659,2.134,681,1.52,697,1.594,719,1.507,748,3.124,759,1.556,762,3.805,775,0.992,785,1.744,790,4.318,840,1.827,867,1.046,882,1.712,914,1.468,923,0.89,955,2.982,997,4.482,998,2.393,1143,2.4,1170,1.444,1307,3.83,1457,1.96,1477,1.755,1478,3.776,1547,2.912,1618,2.217,1722,1.563,1771,2.547,1773,1.827,1818,5.252,1853,3.399,1901,2.977,1914,1.692,1920,5.741,1952,1.995,1988,2.033,2016,5.465,2018,1.682,2036,4.085,2042,5.146,2134,3.695,2180,2.141,2192,4.564,2440,2.396,2579,4.519,2662,3.132,2879,2.4,3024,2.607,3337,2.711,3758,2.758,4070,3.555,4746,2.096,4852,2.977,4903,4.273,5034,4.386,7147,8.98,7167,7.054,7168,5.552,7169,6.873,7170,5.552,7171,5.552,7172,3.388,7173,9.001,7174,5.552,7175,5.552,7176,3.388,7177,3.388,7178,3.388,7179,2.758,7180,3.388,7181,3.388,7182,3.388,7183,3.388]],["t/1680",[85,3.207,117,1.243,411,2.624,997,4.039,7184,9.964]],["t/1682",[5,2.353,72,4.193,102,7.528,113,6.409,869,6.196,2593,9.256,7184,11.256]],["t/1684",[22,1.994,30,1.374,36,1.728,40,1.657,44,1.97,74,1.999,85,3.577,87,1.083,96,4.079,97,0.975,117,0.346,128,2.407,137,4.23,148,2.211,156,1.273,196,0.945,203,3.445,219,2.216,263,3.683,267,2.714,402,1.227,452,1.417,462,1.812,463,3.533,470,0.968,474,4.083,488,1.767,497,2.023,510,0.923,521,1.363,579,1.937,602,1.976,607,2.376,647,6.045,650,7.754,678,1.691,679,3.393,681,5.102,748,2.994,762,2.165,781,0.799,785,1.626,786,2.805,822,2.692,827,2.374,908,4.918,961,7.376,976,1.999,997,4.14,998,3.04,1008,4.295,1035,1.827,1156,2.103,1169,1.827,1200,5.508,1312,6.724,1393,7.012,1480,1.768,1547,1.657,1607,2.085,1618,1.262,1697,7.908,1715,4.356,1825,1.843,1914,1.577,1952,1.86,2198,3.441,2224,4.416,2316,1.424,2529,2.776,2570,1.691,3028,1.934,3506,2.373,7184,4.605,7185,2.776,7186,3.159,7187,3.159,7188,3.159,7189,3.159,7190,11.844]],["t/1686",[43,3.983,44,2.036,73,2.715,86,2.775,87,3.927,96,3.592,97,2.816,128,4.19,148,2.327,172,2.111,214,3.184,568,4.455,575,4.692,656,5.992,659,3.507,681,5.137,774,5.586,781,2.308,822,3.657,943,8.018,957,3.46,1189,6.16,1431,4.273,1988,3.341,4294,6.463,5031,7.209,6093,7.209,7191,9.125,7192,9.125,7193,9.125]],["t/1688",[30,2.248,85,3.107,87,3.767,411,2.542,923,2.885,997,3.912,5034,8.678,7194,10.984,7195,10.984]],["t/1690",[12,3.011,43,2.345,87,4.455,97,1.332,117,0.909,123,1.329,156,1.049,169,1.964,180,4.175,196,3.577,203,5.273,208,1.987,209,2.742,214,1.506,240,2.307,243,2.43,276,3.273,411,1.56,412,2.299,414,1.171,470,2.54,524,2.519,576,1.395,584,3.845,595,2.874,648,4.981,659,3.187,671,3.327,694,6.267,775,1.973,788,8.286,820,1.542,866,1.92,877,3.772,906,4.14,953,1.871,957,1.637,987,1.542,997,1.538,998,1.978,1008,1.79,1025,2.156,1031,2.519,1055,1.627,1214,2.25,1362,2.799,1607,1.718,1734,4.6,1825,2.519,1948,2.435,1988,1.581,2180,1.665,2192,3.772,3024,3.322,3505,3.114,4457,4.426,4471,4.551,4746,4.171,5031,3.411,5034,3.411,5374,4.002,5488,3.638,7154,9.42,7156,6.248,7157,9.42,7196,4.002,7197,13.246,7198,4.002,7199,4.317,7200,4.317,7201,4.317,7202,6.248]],["t/1693",[11,3.73,21,3.108,203,5.595,235,5.195,243,3.292,611,5.324,746,9.541]],["t/1695",[38,3.741,117,1.117,156,3.312,866,4.529,873,5.275,874,5.53,875,3.282,876,8.047,877,5.7,878,6.603,879,5.891,880,6.78,881,6.112,882,5.146,883,9.441,884,9.441]],["t/1697",[44,2.065,148,1.991,156,2.515,172,2.395,218,2.723,240,1.771,267,2.535,520,6.014,555,2.83,579,2.884,626,2.989,663,3.381,671,5.109,697,3.672,719,3.47,781,1.974,832,4.121,866,4.602,873,6.404,877,4.367,878,5.058,885,6.838,886,4.333,887,6.404,888,5.747,889,5.741,890,3.618,891,3.81,892,4.041,893,7.233,894,7.233,895,4.268,896,4.268,897,10.204,898,6.857,899,6.165,900,7.233,901,6.165,902,7.233,903,4.937,904,6.165,905,6.165,906,3.896]],["t/1699",[6,4.549,10,3.256,20,4.034,44,2.389,117,0.981,148,2.283,156,2.175,214,3.123,267,2.77,510,2.614,520,4.634,719,5.03,748,3.428,873,4.634,885,5.27,899,7.071,901,7.071,908,3.308,909,5.538,910,5.37,911,5.801,915,9.531,916,8.295,917,8.295,918,10.483,919,8.295,920,8.295,921,7.864,922,10.483]],["t/1701",[5,1.917,10,3.256,44,2.316,87,3.879,97,2.762,117,0.981,172,2.071,243,3.216,263,3.517,483,3.405,538,2.84,626,3.428,748,3.428,781,2.264,866,3.98,878,5.801,891,4.369,923,2.35,958,11.494,959,6.233,960,11.494,961,5.957,962,10.483,963,5.37,964,5.008,965,8.295]],["t/1705",[20,5.312,47,3.436,113,6.877,117,1.048,148,2.439,218,3.336,531,4.746,596,6.455,740,5.868,775,2.799,799,6.772,1154,7.553,1396,5.437,1609,4.859,1647,5.578,1790,5.362,1818,5.578,1853,5.853,1894,7.034,7203,9.051,7204,9.561]],["t/1707",[72,3.773,102,7.9,7203,8.165]],["t/1709",[7203,8.232,7205,10.772]],["t/1711",[2951,8.593,7203,8.098,7206,11.433,7207,11.433]],["t/1713",[44,1.953,113,6.409,148,2.802,211,4.059,615,4.021,645,4.553,714,8.941,740,5.044,7203,7.781]],["t/1715",[47,4.461,148,2.656,470,3.19,621,3.041,775,3.634,963,6.248,1075,6.023,1097,4.267,1277,5.499,1443,4.384,1509,7.376,7203,8.792,7205,9.651]],["t/1717",[44,1.938,117,1.195,148,2.78,621,3.183,645,4.518,740,5.005,2483,10.379,7203,7.72,7208,10.899]],["t/1719",[20,5.57,97,3.19,117,1.133,149,8.166,560,4.517,775,3.026,1062,4.68,1465,4.659,1790,4.702,1958,5.612,2182,5.927,2467,6.143,2950,9.58,7203,7.321,7209,10.336,7210,10.336]],["t/1721",[6,1.358,20,2.051,38,0.981,44,2.571,72,0.874,78,6.719,102,1.831,113,2.656,148,1.161,157,2.056,239,1.263,412,0.911,470,0.818,604,1.603,648,6.6,740,1.227,873,2.357,1818,1.559,1878,1.635,2024,8.826,2051,10.889,2119,2.174,2230,1.193,2241,1.965,2483,2.174,2754,1.44,2971,1.804,3071,7.288,3316,1.927,3611,7.944,4100,1.71,5421,2.11,6864,11.613,7203,4.974,7211,2.671,7212,2.671,7213,2.671,7214,2.671,7215,2.671,7216,2.671,7217,12.414,7218,2.671,7219,2.671,7220,2.671,7221,2.671,7222,2.671,7223,2.671,7224,2.671,7225,2.671,7226,2.671,7227,2.671,7228,2.671,7229,2.671,7230,2.671,7231,2.671,7232,2.671,7233,2.671,7234,2.671,7235,2.671,7236,2.671,7237,2.671,7238,2.671,7239,2.671,7240,2.671,7241,2.671,7242,2.671,7243,2.671,7244,2.671,7245,2.671,7246,2.671,7247,2.671,7248,2.671,7249,2.671,7250,2.671,7251,2.671,7252,2.671,7253,2.671,7254,2.671,7255,2.671,7256,2.671,7257,2.671,7258,2.671,7259,2.671,7260,2.671,7261,2.671,7262,2.671,7263,2.671,7264,2.671,7265,2.671,7266,2.671,7267,2.671,7268,2.671,7269,2.671,7270,2.671,7271,2.671,7272,2.671]],["t/1723",[22,4.28,44,2,118,4.197,1607,4.476,3027,8.455,3294,8.115]],["t/1726",[21,3.536,86,3.12,117,1.349,639,5.313,649,4.503,1142,6.829,1801,5.382,1835,7.896,2180,3.957,4914,7.145,5140,8.106,5143,7.896,7273,10.261,7274,10.261,7275,10.261,7276,10.261]],["t/1728",[17,1.939,44,2.319,48,2.655,50,2.888,80,3.376,97,1.357,105,2.97,138,1.357,193,3.091,211,1.626,226,2.049,240,0.999,285,3.748,296,2.218,412,2.862,474,2.52,586,1.974,678,5.488,681,1.974,731,4.104,748,1.685,753,1.823,764,1.867,832,4.998,834,1.641,867,1.357,871,2.442,976,4.327,985,2.515,1062,3.8,1083,2.666,1177,1.459,1421,2.147,1465,1.983,1613,3.015,1614,2.752,1698,2.666,1749,2.544,1753,5.389,1788,2.501,1791,2.196,2072,2.567,2173,3.385,2180,4.742,2198,2.888,2230,4.228,2261,3.015,2281,2.752,2337,2.323,2634,4.687,2853,2.249,2943,5.567,3070,2.851,3104,2.851,3366,2.544,3469,3.116,3678,6.58,4260,8.317,4325,2.888,5221,3.865,5286,4.077,5418,5.567,6190,5.403,6837,6.339,6912,8.773,6954,4.077,7277,11.329,7278,4.399,7279,4.399,7280,4.399,7281,9.465,7282,9.465,7283,4.399,7284,4.399,7285,4.399,7286,4.399,7287,3.58,7288,4.399,7289,4.399,7290,4.399,7291,4.399,7292,4.399,7293,4.399,7294,12.031,7295,4.399,7296,4.399,7297,4.399,7298,4.399,7299,4.399,7300,4.399,7301,4.399,7302,4.077,7303,4.399,7304,4.399,7305,10.854,7306,4.399,7307,8.391,7308,6.839,7309,4.399]],["t/1731",[30,0.616,38,2.383,44,1.937,47,1.082,80,2.485,83,0.994,97,0.929,139,1.48,148,1.284,156,0.731,178,2.431,180,3.679,203,4.021,218,1.05,240,2.738,263,0.936,297,1.908,411,2.95,412,3.904,414,0.816,423,3.659,504,4.615,533,2.032,562,1.229,575,1.233,615,1.102,645,2.086,656,1.976,705,3.631,775,1.473,802,1.041,814,2.557,819,1.824,914,1.304,925,4.595,978,3.906,992,2.79,1008,1.248,1009,1.793,1023,5.701,1027,3.149,1033,1.521,1049,1.726,1098,1.623,1331,1.215,1332,2.457,1396,1.712,1678,1.512,1698,3.05,1734,4.985,1776,2.623,1904,1.521,1967,1.503,2027,8.718,2180,1.941,2192,2.817,2260,1.338,2298,2.032,2305,1.646,2316,1.357,2321,3.223,2403,3.45,2450,3.505,2452,2.817,2603,4.665,2624,2.378,2998,8.927,3024,2.316,3072,3.631,3366,2.911,3503,2.132,3663,4.665,3695,3.703,3701,1.712,3749,2.096,3767,2.378,4360,2.262,4417,3.783,4746,1.862,6247,4.773,6464,2.378,6510,4.423,6577,10.304,6620,2.79,7033,5.281,7198,4.665,7202,4.665,7310,5.034,7311,5.034,7312,5.034,7313,5.034,7314,3.01,7315,5.034,7316,5.034,7317,3.01,7318,3.01,7319,3.01,7320,6.488,7321,3.01,7322,10.154,7323,3.01,7324,5.034,7325,3.01,7326,3.01,7327,3.01,7328,6.013,7329,3.01,7330,3.01,7331,3.01,7332,3.01,7333,3.01,7334,3.01,7335,5.034,7336,3.01,7337,5.034,7338,3.01,7339,3.01,7340,3.01,7341,3.01,7342,3.01,7343,4.665,7344,3.01,7345,3.01]],["t/1734",[30,1.624,44,2.214,178,3.833,180,2.551,181,5.729,196,2.373,245,4.106,297,2.334,438,5.028,505,4.248,670,3.545,867,2.449,873,4.11,874,4.309,906,5.226,985,3.984,1009,2.827,1474,7.356,1521,4.513,1713,6.27,1791,3.963,1816,3.453,1967,3.963,2119,6.46,2275,5.68,2965,4.513,6021,6.973,6622,10.854,7346,7.936,7347,7.936,7348,7.936,7349,7.936,7350,7.936,7351,7.356,7352,7.936,7353,7.936,7354,7.936]],["t/1736",[94,3.338,97,3.055,128,4.545,178,4.78,220,4.78,240,2.247,414,2.684,607,2.714,621,2.891,626,3.791,663,4.289,775,2.897,809,3.223,866,4.401,906,4.942,953,4.289,978,3.124,1177,3.284,1222,7.14,1948,5.583,2145,5.583,2440,4.271,3657,6.588]],["t/1738",[5,1.905,21,2.556,72,2.911,85,2.515,117,1.235,118,3.318,172,2.058,180,3.974,203,3.92,209,3.617,240,2.557,290,7.163,391,2.538,402,3.453,530,3.903,607,2.438,626,3.406,891,4.342,978,2.807,985,2.666,998,2.609,1055,3.351,1306,7.494,1734,4.366,1853,8.211,2450,6.193,7355,8.893,7356,8.893]],["t/1740",[38,3.225,87,3.012,117,0.963,210,2.906,219,2.898,226,4.092,290,6.158,414,2.381,470,2.69,546,5.124,681,3.94,752,7.867,760,4.241,775,3.598,790,5.376,923,2.306,953,3.805,1070,4.411,1140,4.953,1260,5.493,1449,4.411,1813,5.036,1818,7.55,1853,7.526,1920,7.148,2192,4.914,2233,5.376,7147,7.4,7357,8.782]],["t/1743",[1,2.671,7,2.048,30,1.643,33,2.273,44,2.534,71,3.522,72,1.779,73,0.982,78,3.478,80,1.629,81,4.391,83,0.652,90,1.212,97,1.019,115,1.138,117,0.362,139,2.808,146,1.731,156,3.18,172,1.257,174,2.686,187,1.069,201,2.796,243,1.409,248,1.792,266,1.418,290,6.608,391,1.551,411,0.764,414,1.878,415,3.362,488,2.708,510,0.964,520,4.944,529,1.155,552,1.639,555,4.183,607,1.49,611,2.279,719,4.689,748,3.075,781,0.835,837,2.167,868,1.62,869,3.906,873,2.814,877,1.847,942,1.668,961,3.617,978,1.715,980,1.436,994,2.021,999,2.608,1004,1.629,1009,3.401,1364,2.113,1441,2.088,1727,2.46,1734,4.955,1766,2.262,1789,3.568,1841,2.543,1957,3.479,1987,1.893,1988,1.208,2260,2.416,2261,3.724,2262,4.181,2300,1.847,2305,1.805,2450,3.784,2688,4.579,2751,3.199,2813,2.113,2881,1.323,2918,4.906,3135,3.784,3332,5.036,3741,2.065,3895,5.206,4070,3.479,4315,2.381,4336,3.327,4442,2.781,4771,5.036,6091,2.781,6126,3.059,6789,2.781,7358,3.301,7359,3.301,7360,3.301,7361,3.301,7362,5.434,7363,3.301,7364,3.301,7365,3.301,7366,6.926,7367,3.301,7368,3.301,7369,5.434,7370,5.434,7371,3.301,7372,3.301,7373,3.301,7374,3.301,7375,3.301,7376,3.301,7377,3.301,7378,8.876,7379,3.301,7380,3.301,7381,5.434,7382,3.301,7383,3.301,7384,3.301,7385,3.301]],["t/1745",[7,1.511,10,2.155,27,2.861,30,1.212,38,2.175,73,2.544,97,1.828,117,1.204,136,2.646,144,3.341,148,3.268,156,1.439,160,4.269,187,1.919,190,4.953,196,1.771,203,2.611,218,2.067,236,3.665,264,2.76,267,2.458,290,6.419,299,5.773,391,1.691,402,2.3,414,2.319,436,3.59,452,2.658,483,2.254,490,2.437,495,3.586,497,3.792,562,2.418,626,2.269,645,2.455,654,2.4,671,2.924,679,2.993,744,3.149,753,4.159,775,1.734,802,2.049,875,1.909,877,3.315,980,2.577,985,2.563,1002,3.943,1003,3.087,1004,4.221,1021,3.426,1055,2.232,1140,3.341,1159,3.087,1249,3.107,1295,4.196,1424,4.358,1547,3.107,1799,3.289,1853,5.235,1941,4.273,1943,3.456,1954,3.067,2075,2.975,2182,3.397,2304,2.646,2468,3.171,2940,4.273,3318,5.181,3556,4.273,4948,4.452,5225,6.755,7386,5.49,7387,5.923,7388,5.49,7389,5.923,7390,5.923,7391,10.237,7392,5.923,7393,5.923,7394,5.49,7395,5.923,7396,5.49,7397,5.923,7398,5.923]],["t/1747",[10,2.747,27,5.895,30,1.545,39,4.531,44,1.8,87,2.59,117,1.11,137,3.083,146,3.961,148,2.914,156,2.46,172,1.747,245,2.963,246,10.588,250,3.026,267,1.85,290,5.579,437,3.666,612,2.205,645,3.13,654,3.06,722,5.098,748,2.892,781,1.91,908,2.791,923,1.983,978,2.384,1159,5.277,1205,3.435,1345,7.956,1727,2.682,1943,4.406,1961,3.666,2327,5.447,2328,4.778,3556,7.304,4339,5.811,7399,7.551,7400,7.551,7401,7.551,7402,10.726,7403,7.551,7404,7.551,7405,7.551,7406,7.551,7407,6.999,7408,6.999,7409,7.551,7410,6.999]],["t/1749",[1,1.809,27,4.32,30,1.831,44,2.01,90,1.79,97,2.283,106,2.366,117,0.534,118,1.818,123,1.5,126,1.905,136,2.177,137,3.021,139,2.631,141,4.44,144,4.173,148,2.548,155,2.492,156,3.013,168,1.625,172,1.128,180,2.378,196,1.457,203,2.148,290,6.67,391,2.553,520,5.172,555,2.684,562,3.021,584,2.259,617,2.573,620,2.238,626,3.426,645,2.02,649,2.139,663,2.111,671,4.416,694,2.379,719,4.441,775,1.426,781,1.233,788,3.048,876,3.85,877,2.727,888,4.108,898,4.282,899,3.85,901,3.85,903,4.681,908,1.801,971,2.591,978,1.538,980,3.219,1009,2.635,1055,1.836,1249,2.556,1344,2.706,1404,3.12,1727,1.73,1818,4.317,1853,2.983,1987,5.727,1990,5.561,2049,4.282,2313,2.818,2350,3.015,2581,3.831,2751,2.869,2953,6.501,4070,3.12,4611,4.106,4746,4.578,6029,3.966,7386,4.516,7388,6.858,7391,4.282,7394,4.516,7402,4.282,7407,4.516,7408,4.516,7410,4.516,7411,7.399,7412,7.399,7413,4.873,7414,4.873,7415,4.873,7416,4.873,7417,4.873,7418,4.516,7419,4.873,7420,4.873,7421,4.873,7422,4.873,7423,4.873,7424,7.399,7425,4.516,7426,4.873,7427,4.873,7428,4.873,7429,4.873,7430,4.873,7431,4.873,7432,4.873,7433,4.873]],["t/1752",[97,3.417,141,6.643,156,2.69,242,5.56,997,3.943,1327,6.195,5034,8.747,7434,10.261]],["t/1754",[139,4.117,172,2.75,243,2.514,267,2.374,579,3.582,620,5.458,781,2.452,788,7.436,908,4.393,1344,5.382,1596,4.393,1987,5.558,1990,8.934,7435,11.887]],["t/1756",[27,6.171,30,1.957,47,3.436,89,6.877,211,3.533,219,3.155,470,2.929,511,4.349,514,4.802,612,2.792,647,5.578,803,6.553,1009,3.405,1109,6.121,1345,8.208,1372,6.197,2157,5.682,2316,4.309,2913,7.034,3028,5.853,3556,6.897,4449,7.357]],["t/1758",[7,2.104,30,1.688,43,2.87,44,2.121,117,0.904,139,2.426,148,1.438,177,4.458,180,3.835,249,2.601,290,6.575,414,3.496,421,2.117,425,3.233,436,5.911,482,3.061,538,1.789,607,1.546,620,4.479,645,2.337,666,2.328,681,3.701,781,1.426,787,2.364,832,2.977,878,3.654,953,2.443,985,1.69,993,3.181,1049,3.233,1114,4.813,1599,2.328,1734,2.767,1813,5.593,1818,6.263,1853,3.451,1943,4.813,1957,3.609,1987,3.233,2022,6.793,2180,3.181,2192,4.615,2429,3.609,3688,4.751,3953,4.953,4471,3.806,4772,5.225,5031,4.454,6922,7.645,7147,9.045,7436,5.637,7437,5.637,7438,5.637,7439,5.637,7440,5.637,7441,5.637,7442,5.637,7443,5.637,7444,5.637,7445,5.637,7446,7.645,7447,5.637,7448,8.248,7449,9.754,7450,9.754,7451,10.734,7452,5.637,7453,5.637,7454,5.637,7455,5.637]],["t/1760",[180,4.117,218,4.47,2180,4.236,2288,6.099,6020,8.941,6160,10.181,7456,10.984]],["t/1762",[128,5.815,180,4.462,218,4.844,220,6.115,626,3.589,1976,4.678,3680,7.389,4270,6.826,5038,9.648]],["t/1764",[10,0.94,28,1.29,38,1.624,40,1.355,44,2.498,72,0.845,73,0.769,79,2.515,84,1.297,85,0.73,86,2.088,87,0.886,94,0.871,97,1.365,116,1.197,117,0.636,123,0.795,128,3.866,148,1.128,172,0.598,180,1.864,193,0.951,196,0.772,211,0.954,218,0.901,240,1.316,242,1.297,243,1.147,338,2.147,411,1.589,412,1.508,421,0.97,470,2.365,473,0.76,529,0.904,568,1.261,576,0.834,579,0.954,612,1.291,615,0.946,626,0.989,659,0.993,756,1.222,764,1.096,774,1.581,775,0.756,781,1.119,819,2.68,869,7.28,891,3.353,957,0.979,985,1.325,987,0.923,997,0.92,998,0.758,1028,1.254,1091,1.445,1151,1.481,1159,1.346,1177,0.857,1204,1.054,1218,1.355,1330,1.494,1596,0.954,1612,1.321,1647,1.507,1727,0.917,1734,6.712,1789,1.696,1954,1.337,1988,1.619,2051,8.854,2232,1.719,2288,1.434,2295,1.413,2331,1.581,2357,1.494,2502,1.863,2573,1.77,3104,1.674,4079,1.77,4106,11.341,4171,2.102,4743,4.038,5158,2.269,6093,3.494,6095,2.176,7457,5.799,7458,2.583,7459,4.422,7460,12.101,7461,2.583,7462,11.351,7463,12.907,7464,12.907,7465,2.583,7466,2.583,7467,2.583,7468,2.583,7469,2.583,7470,2.583,7471,2.583,7472,2.583,7473,2.583,7474,2.583,7475,2.583,7476,2.583,7477,2.583,7478,2.583,7479,10.878,7480,2.583,7481,2.583,7482,2.583,7483,2.583,7484,2.583,7485,2.583,7486,2.583,7487,2.583,7488,2.583,7489,2.583,7490,2.583,7491,2.583,7492,2.583,7493,2.583,7494,4.422,7495,2.583,7496,2.394,7497,2.583]],["t/1766",[10,1.804,28,2.476,43,2.609,72,1.623,73,2.231,74,3.138,94,1.673,95,1.874,97,1.53,115,1.711,117,0.544,128,4.628,148,1.913,172,2.634,180,1.594,196,3.013,198,3.701,218,1.73,219,1.636,229,1.691,240,2.763,243,2.345,249,2.288,411,1.148,470,2.297,496,2.693,510,2.19,511,2.256,514,2.491,555,2.72,607,1.36,719,3.334,756,2.346,763,3.138,764,3.183,775,2.646,781,1.897,787,2.08,809,1.615,817,5.395,820,2.679,822,3.005,866,2.205,875,1.598,886,2.753,906,6.53,942,2.505,957,4.616,997,1.766,1008,2.056,1028,2.408,1066,2.448,1091,2.775,1159,2.584,1227,5.656,1271,2.601,1286,2.619,1308,3.788,1359,3.301,1471,2.462,1599,2.048,1715,2.01,1727,3.211,1734,6.116,1749,2.868,1988,1.816,2232,3.301,2233,3.036,2256,2.947,2288,2.753,2300,2.775,2452,5.639,3374,5.636,4079,3.399,4743,5.222,5096,3.648,7498,4.959,7499,10.078,7500,4.959,7501,4.959,7502,4.357,7503,10.078,7504,7.498,7505,4.959]],["t/1768",[44,1.161,47,2.347,117,0.716,123,2.01,128,6.215,180,4.472,218,4.855,220,6.055,240,2.081,296,1.726,391,1.864,411,2.121,521,2.818,524,6.179,527,3.049,626,2.502,663,2.83,914,2.83,955,2.761,985,2.747,1008,2.707,1011,3.403,1599,2.697,2192,6.767,2355,3.36,2403,7.258,2415,5.749,3662,6.78,3695,7.791,3871,6.743,4266,4.347,6085,7.46,6086,8.366,6087,8.924]],["t/1770",[0,5.67,1,2.457,2,4.135,11,2.577,41,3.367,83,1.475,96,2.941,117,0.819,123,2.3,136,3.337,139,2.957,180,3.906,181,5.03,208,2.202,214,2.607,240,2.579,259,1.896,262,3.481,391,2.869,398,2.752,463,2.548,473,2.197,487,2.973,489,2.492,492,2.952,520,3.869,532,4.622,538,2.37,560,3.265,568,3.647,576,2.414,610,5.641,627,4.374,775,2.187,980,3.251,1055,2.815,1177,3.335,1189,5.044,1195,4.399,1214,3.893,1252,4.843,1278,3.945,1308,3.774,1609,3.797,1618,2.983,1731,6.564,1953,4.673,2304,4.49,3798,5.615,7506,7.471,7507,7.471]],["t/1773",[1,2.765,3,2.273,5,2.534,33,2.66,44,2.278,78,4.071,83,1.6,85,1.557,96,2.167,97,1.699,115,2.796,116,2.552,117,0.603,118,2.054,122,3.309,156,1.969,180,3.092,181,2.437,196,1.646,208,1.623,215,3.773,233,5.847,248,2.989,259,2.001,263,1.711,296,1.455,345,3.899,405,3.406,414,1.493,415,5.015,490,3.957,521,2.375,579,2.034,610,2.733,612,1.608,629,2.733,645,2.282,756,2.603,809,1.792,814,1.856,891,2.687,998,1.615,1031,3.212,1033,2.781,1066,2.717,1385,3.971,1457,3.184,1607,2.19,1731,8.453,1841,2.022,1910,3.241,1914,2.749,2061,3.971,2281,5.07,2711,4.48,3252,4.433,3270,6.83,3511,5.014,3607,6.794,3610,3.971,3611,3.212,3612,3.899,3659,3.011,3798,7.231,4168,3.899,4411,3.664,4687,3.303,6079,4.639,7508,9.62,7509,9.62,7510,9.62,7511,5.505,7512,5.102,7513,6.83,7514,5.505,7515,5.505,7516,3.833,7517,5.102,7518,5.505,7519,5.102,7520,5.102,7521,4.639,7522,5.102,7523,5.102,7524,5.102]],["t/1775",[33,2.728,44,1.478,85,2.351,117,0.911,139,2.445,180,2.672,181,3.68,193,3.062,210,2.751,243,2.156,339,4.885,402,3.228,404,4.652,406,4.127,411,1.924,412,4.591,420,4.513,486,3.73,488,3.638,555,3.913,607,2.279,611,3.486,814,3.638,888,4.615,923,2.183,1534,7.304,1841,3.053,2019,5.789,2157,3.696,2260,3.696,2751,4.895,2975,4.58,3032,5.038,3528,6.397,3611,4.85,3810,4.727,4685,7.513,6688,7.005,7525,7.705,7526,8.313]],["t/1777",[32,6.524,72,4.336,81,5.124,86,2.849,104,7.895,113,7.389,115,4.015,117,1.276,187,3.035,203,5.581,211,3.462,411,2.168,474,3.451,510,2.736,809,3.051,997,3.337,1008,3.883,1471,4.651,3706,7.626,3734,8.232,7024,7.21,7527,8.232]],["t/1779",[1,2.733,5,1.448,7,1.256,10,0.759,13,1.229,21,0.6,28,1.042,30,1.384,33,1.206,44,0.653,47,0.75,72,1.203,73,1.465,83,1.854,86,1.497,87,1.26,88,0.967,94,0.704,95,0.789,96,0.821,97,1.134,116,0.967,117,1.131,123,2.295,137,0.852,139,1.448,143,1.934,144,3.813,148,1.513,150,2.468,151,1.159,155,2.517,156,2.187,160,2.961,168,1.226,172,1.139,180,3.128,181,2.993,183,3.937,186,1.995,187,1.921,190,2.43,194,0.789,203,1.62,208,1.451,210,1.216,211,0.771,213,0.9,218,2.359,235,1.002,238,2.847,240,2.21,243,0.541,258,0.797,267,0.511,271,2.185,296,0.971,297,0.614,298,1.291,330,0.886,391,3.466,397,1.218,398,1.814,402,1.427,411,2.173,414,1.335,436,3.594,443,1.541,473,0.614,474,1.354,489,0.696,490,0.858,491,0.893,510,2.843,521,0.9,524,1.218,525,1.036,527,0.694,528,2.365,529,2.816,530,1.612,538,1.166,567,1.758,586,2.209,607,1.007,612,0.609,621,1.732,639,1.08,659,3.093,663,1.592,666,0.862,670,0.932,693,3.46,694,1.019,733,1.535,744,1.109,745,1.264,748,1.407,759,1.687,770,1.109,775,2.356,781,0.528,785,1.074,787,0.875,796,0.997,802,0.722,809,0.679,814,0.704,816,0.852,820,0.745,867,0.644,868,1.024,871,1.159,877,1.168,908,0.771,912,0.982,914,2.569,953,2.133,955,1.553,957,0.791,978,1.16,980,0.908,985,1.475,989,1.197,998,1.078,1004,1.03,1008,2.458,1031,2.144,1036,1.141,1066,1.03,1069,1.074,1071,1.087,1090,1.036,1097,0.855,1120,1.133,1159,1.087,1177,1.967,1200,1.109,1203,1.168,1204,0.852,1205,3.075,1207,1.606,1231,1.013,1431,0.977,1452,1.698,1453,1.648,1457,1.207,1465,0.94,1471,1.036,1477,1.08,1478,1.117,1480,1.168,1547,3.911,1596,0.771,1599,1.517,1607,0.83,1722,1.695,1790,0.949,1799,1.159,1841,0.766,1920,1.698,1974,1.061,1979,1.37,2010,1.305,2021,1.264,2027,1.336,2033,1.409,2059,1.995,2060,1.054,2180,2.287,2230,0.932,2275,0.916,2313,1.207,2316,0.94,2327,1.505,2328,1.32,2331,1.277,2363,1.353,2415,1.133,2440,3.692,2459,3.228,2581,1.08,2854,2.205,2885,1.505,2886,1.606,2887,1.606,2899,1.141,2910,2.446,2965,1.187,3607,4.774,3648,1.453,3657,1.389,3662,1.336,3695,2.703,3798,1.568,3810,1.187,3931,1.32,4079,1.43,4355,1.648,4379,1.758,4380,1.758,4381,1.698,4383,2.991,4516,1.43,5038,1.478,6079,7.912,6123,1.698,6247,3.622,6688,1.758,7179,1.698,7528,2.087,7529,2.087,7530,3.674,7531,7.456,7532,6.76,7533,2.087,7534,2.087,7535,2.087,7536,1.934,7537,2.087,7538,7.459,7539,2.087,7540,2.087,7541,2.087,7542,3.674,7543,2.087,7544,2.087,7545,2.087,7546,3.674,7547,2.087,7548,1.934,7549,4.325,7550,2.087,7551,2.087,7552,1.934,7553,4.325,7554,1.934,7555,1.934,7556,3.405,7557,2.087,7558,2.087,7559,2.087,7560,2.087,7561,2.087,7562,2.087]],["t/1781",[41,5.195,391,3.29,759,5.293]],["t/1783",[5,2.201,73,2.297,117,1.266,180,3.302,181,5.677,187,2.5,211,2.852,229,2.632,245,3.028,320,4.131,338,3.747,391,2.203,443,4.309,470,2.364,495,4.309,506,4.16,526,2.88,579,2.852,654,3.127,666,4.242,744,4.103,760,3.727,866,3.432,885,4.544,1004,3.81,1009,2.749,1025,3.854,1281,4.221,1307,4.19,1584,5.068,1599,3.187,1727,2.741,1778,3.632,1942,7.122,2062,3.372,2254,4.464,2416,5.137,2518,4.389,2813,6.578,2840,5.939,4821,5.939,7024,5.939,7563,10.148,7564,7.153,7565,7.718,7566,7.718]],["t/1785",[21,2.723,38,2.516,72,2.242,76,3.326,96,2.697,97,2.114,116,3.176,117,1.191,146,4.97,148,2.417,165,2.956,177,4.965,180,2.201,181,4.195,240,1.555,245,2.687,276,4.601,470,2.098,489,2.285,510,3.423,514,3.44,529,3.801,559,5.576,562,2.796,576,2.213,579,2.531,620,4.351,670,3.06,775,2.005,781,2.748,955,2.896,987,2.447,998,2.01,1010,4.77,1204,2.796,1961,3.326,2062,2.993,2157,3.046,2307,6.349,3682,5.772,3706,9.541,4881,7.985,5083,7.712,7024,10.388,7527,10.299,7538,10.069,7567,6.85,7568,6.019,7569,6.019,7570,6.85,7571,6.85]],["t/1787",[44,0.982,97,1.705,117,0.606,180,1.776,181,6.313,187,1.79,239,2.614,297,2.836,339,2.502,403,3.678,411,1.279,412,1.885,420,3,443,2.318,462,4.661,486,2.48,490,3.344,526,2.062,651,3.678,666,2.282,834,2.062,848,5.122,914,2.394,923,2.135,925,3.914,985,4.229,1612,2.826,1713,4.366,1727,1.962,1918,2.862,2018,2.744,2019,3.848,2062,2.415,2157,2.457,2275,2.425,2416,5.41,2903,3.538,4821,4.253,4825,4.154,4826,4.498,4827,4.498,4955,4.154,5041,5.122,5048,4.856,5049,4.856,5389,5.122,5390,5.122,5391,5.122,5863,4.657,6247,4.066,6450,11.043,6572,4.856,7033,4.498,7038,4.498,7043,4.498,7572,5.526,7573,5.526,7574,5.526,7575,5.122,7576,5.526,7577,5.526,7578,5.526,7579,5.526,7580,4.657,7581,5.526,7582,5.526,7583,5.526,7584,5.526,7585,5.526,7586,5.526,7587,5.526,7588,5.526,7589,5.526,7590,5.526,7591,5.526,7592,5.526,7593,5.526,7594,5.526,7595,5.122,7596,5.526,7597,5.526]],["t/1789",[73,2.876,83,2.103,85,1.569,116,2.572,117,0.608,146,2.91,148,1.415,151,5.366,156,1.348,160,6.908,180,2.62,181,5.024,187,1.797,208,2.849,238,3.209,240,1.851,243,1.439,258,2.118,351,2.991,412,1.892,437,3.958,438,3.916,443,3.419,495,2.327,529,1.941,624,2.77,671,2.739,769,3.237,820,1.982,834,2.07,923,1.457,925,3.93,985,3.556,993,4.729,1010,3.864,1281,4.459,1457,3.209,1599,2.291,1918,4.221,1941,4.002,1942,3.209,1976,2.77,2180,2.14,2275,2.435,2396,3.267,3662,3.552,3680,3.237,4270,2.991,4272,4.17,4858,7.264,5038,5.775,5180,8.977,6247,5.998,7033,4.516,7038,4.516,7043,4.516,7580,4.675,7598,5.548,7599,5.548,7600,5.548,7601,5.548,7602,10.652,7603,5.548,7604,5.548,7605,5.548,7606,5.548,7607,9.664,7608,4.875,7609,5.548,7610,5.548,7611,5.548,7612,5.548,7613,5.548,7614,5.548,7615,5.548,7616,5.548]],["t/1791",[1,0.67,3,1.131,5,1.298,7,1.186,12,1.947,21,0.787,22,2.305,44,2.357,48,1.064,73,2.586,83,2.387,84,5.103,86,1.414,94,0.924,96,1.078,97,0.845,117,0.51,123,0.843,136,2.077,137,1.898,138,1.869,139,1.367,148,0.699,150,1.935,151,3.964,155,3.651,160,4.867,165,1.182,166,2.335,167,2.644,170,6.9,172,1.402,175,1.309,177,4.234,180,0.88,183,2.455,187,0.887,188,1.376,190,2.295,196,1.39,201,2.392,203,1.207,211,1.012,238,2.689,243,0.71,245,2.377,263,1.883,267,0.671,297,1.367,298,1.695,339,2.105,421,1.029,436,4.326,437,2.258,438,2.91,474,1.009,514,2.335,528,3.429,530,1.202,538,1.922,622,3.199,630,1.498,634,1.613,649,1.202,652,2.199,695,2.164,712,1.466,732,1.464,733,2.015,781,1.806,832,2.455,908,1.718,912,2.188,971,1.456,989,1.571,993,1.056,998,1.364,1009,0.976,1010,3.238,1033,1.384,1092,3.354,1093,2.164,1097,1.123,1120,1.487,1125,3.781,1174,3.238,1175,3.053,1177,0.909,1232,2.059,1253,2.378,1281,2.543,1370,1.598,1396,1.558,1398,1.323,1421,2.957,1443,1.958,1457,1.584,1465,3.218,1473,1.733,1596,2.239,1606,2.164,1678,1.376,1714,1.776,1776,1.428,1790,1.246,1799,2.582,1878,1.677,1896,2.623,1916,6.083,1918,5.446,1921,4.983,1926,1.466,1943,6.618,1950,4.37,1951,3.673,1976,3.992,1977,2.108,2043,1.849,2156,2.015,2157,1.218,2243,3.578,2271,1.345,2331,1.677,2341,2.539,2377,3.578,2429,1.754,2878,2.059,2975,1.509,3082,2.644,3249,2.108,3505,3.354,3606,4.085,3607,1.754,3668,2.164,4395,3.784,4396,3.784,4417,2.059,4594,2.308,6292,4.309,7536,2.539,7595,2.539,7608,7.025,7617,2.739,7618,2.739,7619,2.539,7620,2.739,7621,4.65,7622,4.65,7623,4.65,7624,4.65,7625,4.65,7626,4.65,7627,4.65,7628,4.65,7629,4.309,7630,2.739,7631,2.739,7632,2.739,7633,2.739,7634,2.739,7635,2.739,7636,2.739]],["t/1794",[1,2.103,5,1.843,24,2.933,30,1.223,44,1.961,73,3,83,2.583,87,2.049,117,0.943,126,2.336,148,1.524,156,1.452,172,1.382,240,2.504,243,1.549,297,3.58,391,2.455,411,2.552,470,3.088,488,2.015,490,3.539,510,2.512,538,1.895,555,2.167,607,1.638,611,2.505,615,2.187,719,3.825,748,2.288,775,1.749,781,1.511,787,2.505,820,2.134,874,3.243,914,3.727,923,2.259,957,2.266,985,1.791,1070,3,1109,3.825,1347,3.872,1352,3.923,1618,2.386,1647,3.486,1778,4.048,1976,5.507,2062,3.759,2157,3.825,2261,4.094,2300,4.814,2416,6.71,2861,3.696,3607,5.508,3798,4.49,5427,5.249,5488,7.249,6510,5.249,7512,5.537,7637,5.974,7638,5.974,7639,9.344,7640,5.974,7641,8.603,7642,5.974,7643,5.974,7644,5.974,7645,5.974]],["t/1796",[83,2.318,86,3.569,172,2.716,180,3.052,181,4.204,240,2.156,411,2.948,775,3.729,1489,4.981,1988,4.297,2180,4.526,4942,8.174,5143,9.032,6148,8.801,7646,11.737,7647,11.737]],["t/1798",[83,2.567,240,3.159,266,3.821,271,3.276,398,4.15,411,2.058,659,3.418,1207,6.844,2180,3.429,7548,8.243,7549,9.899,7552,8.243,7553,10.865,7554,8.243,7555,8.243,7556,8.243,7648,8.893,7649,8.893,7650,8.893,7651,10.441,7652,8.893,7653,8.893,7654,8.243,7655,8.893,7656,8.243]],["t/1800",[83,2.653,240,3.128,266,4.194,398,3.596,659,3.751,2180,3.764,7549,8.576,7553,10.489,7651,9.046,7654,9.046,7656,9.046,7657,9.76,7658,9.76,7659,9.76,7660,9.76,7661,9.76,7662,9.76]],["t/1803",[180,3.298,203,4.523,218,3.58,229,3.499,775,3.004,819,6.218,1025,5.123,1027,8.244,1286,5.418,1825,5.987,1988,3.756,2060,5.184,2230,4.583,2271,5.037,7663,9.51,7664,10.261]],["t/1805",[44,2.204,48,3.047,115,2.707,117,1.139,172,1.816,175,3.75,203,4.579,412,2.676,470,2.404,510,3.034,552,3.896,613,3.918,666,5.118,670,3.505,877,4.391,923,2.061,963,4.709,1036,4.292,1521,4.462,1547,5.449,2018,6.812,2230,4.64,2253,7.273,2634,5.378,2937,5.898,3294,5.661,6187,6.895,6789,6.613,7665,7.847,7666,7.847,7667,7.847,7668,10.388,7669,7.847,7670,7.847,7671,7.847,7672,7.847,7673,7.847,7674,7.847,7675,7.847,7676,7.847,7677,7.847]],["t/1808",[78,5.696,85,1.797,156,2.184,180,2.042,181,4.618,211,3.322,242,3.191,243,2.705,259,1.695,266,3.862,338,3.085,339,4.07,405,3.931,414,1.723,415,7.018,490,2.613,584,2.946,646,3.154,719,2.825,781,1.607,809,2.927,868,3.119,908,2.348,942,5.27,959,4.424,1214,3.311,1607,2.528,2271,5.121,2281,5.623,2698,4.775,2704,5.354,2711,5.171,2751,3.741,2854,3.812,3511,5.437,3610,4.583,3611,3.707,3612,4.5,3798,4.775,3932,4.289,4903,4.889,4905,5.019,4906,5.019,4914,4.424,4942,4.424,4991,5.354,4992,5.582,5488,7.575,6079,5.354,6535,5.582,7179,5.171,7519,5.888,7520,5.888,7521,5.354,7522,5.888,7523,5.888,7524,5.888,7639,8.332,7678,6.353,7679,6.353,7680,6.353,7681,6.353,7682,6.353,7683,6.353,7684,6.353,7685,6.353,7686,6.353,7687,6.353,7688,6.353,7689,6.353,7690,6.353,7691,6.353,7692,6.353,7693,6.353,7694,6.353,7695,6.353,7696,6.353]],["t/1810",[21,2.492,30,1.775,78,4.356,97,2.677,116,4.021,117,1.215,180,3.563,181,3.84,208,2.557,220,4.188,243,2.249,411,2.007,414,2.352,457,3.891,473,2.551,510,2.533,651,5.773,781,2.805,790,5.31,814,2.925,819,5.256,820,3.098,869,4.892,973,5.944,1066,4.281,1140,4.892,1174,6.04,1734,4.257,1751,4.973,2062,3.79,2123,5.154,2145,4.892,2180,4.276,2257,6.143,2813,5.553,4169,4.779,5260,8.039,7697,8.039,7698,8.673]],["t/1812",[83,2.664,88,4.203,203,5.499,243,3.235,391,3.56,527,3.793,557,4.61,809,2.952,923,2.381,997,3.229,2180,5.202,2192,5.073,4266,6.034,4914,6.313,4942,6.313,5143,6.976,5649,7.64,7699,9.066,7700,9.066]],["t/1814",[83,1.622,117,0.901,136,3.669,151,4.561,175,3.926,180,2.64,181,3.637,211,3.036,240,1.865,296,2.83,297,2.416,398,3.027,411,1.901,438,3.946,527,2.733,598,3.809,923,2.158,925,5.819,1028,3.989,1097,3.367,1733,6.175,1918,4.254,2180,3.168,2353,4.338,2403,5.631,2619,3.967,2910,5.468,3511,4.281,3662,5.26,3665,4.837,3680,4.794,3695,6.044,4264,6.175,4270,4.429,4272,6.175,4542,5.325,4858,6.175,5038,5.819,5473,5.139,5479,5.819,5644,6.923,5980,6.687,5981,6.923,6085,6.687,6087,6.923,6144,6.322,6246,6.175,7701,7.614,7702,7.219,7703,7.614,7704,7.614]],["t/1816",[30,2.036,44,1.768,47,2.643,72,3.256,104,8.381,150,3.06,155,3.76,163,5.358,240,2.559,276,3.57,391,3.6,398,3.664,411,2.608,454,6.293,510,3.292,528,4.778,607,2.016,666,4.107,770,3.909,775,2.152,830,5.803,1008,3.048,1013,4.704,1125,3.478,1547,3.857,2059,5.4,2180,3.835,2854,5.968,3104,4.766,3706,9.828,4305,6.196,5083,8.096,6123,8.096,6851,5.809,7024,7.654,7527,8.739,7569,8.739,7705,7.353,7706,7.353]],["t/1818",[88,5.961,128,5.904,156,2.355,181,6.277,266,4.165,290,5.341,391,3.669,764,4.114,1818,5.656,1988,3.549,2022,6.75,2180,4.584,5896,6.643]],["t/1820",[3,4.795,33,3.812,44,1.387,117,0.855,122,3.186,128,5.68,172,2.862,180,3.975,218,4.315,220,4.998,243,2.024,267,1.911,955,3.299,957,3.925,991,3.425,1204,4.225,1471,3.874,2440,3.367,2467,6.151,2815,7.551,3665,4.595,3709,8.177,4880,5.741,5184,7.779,6143,5.528,6144,9.518,6145,10.764]],["t/1822",[5,1.105,71,3.345,83,1.828,84,2.592,117,1.267,128,5.89,151,5.141,177,2.358,180,4.513,196,1.543,218,4.855,220,6.083,240,1.754,297,2.272,411,1.194,412,1.76,414,2.986,438,4.448,598,4.293,796,2.466,906,3.857,914,4.455,987,1.843,997,1.838,1008,2.139,1109,3.304,1387,6.68,1844,3.159,1914,2.576,1947,5.295,1988,2.828,2027,3.304,2353,4.89,2440,4.436,2468,2.762,2581,5.324,2619,4.472,2815,4.257,2907,3.265,2910,7.328,2934,2.959,3511,4.826,3603,4.2,3665,5.452,3797,3.011,3931,6.505,6182,4.783,6183,4.783,7707,5.16]],["t/1825",[10,1.38,11,1.308,43,2.65,44,1.696,47,1.363,72,1.241,73,1.128,85,1.72,86,3.489,87,3.935,88,2.82,96,2.395,97,2.35,117,1.219,123,1.167,124,2.253,128,1.741,148,1.943,160,3.037,168,1.265,169,1.725,172,2.017,180,4.147,203,2.681,211,1.401,218,2.657,219,1.251,227,2.275,229,1.293,240,1.381,411,2.724,414,1.028,470,2.923,489,1.265,510,1.107,511,1.725,538,1.203,546,2.212,576,1.225,579,1.401,584,1.758,621,1.107,655,2.49,656,3.994,660,1.623,663,1.643,678,3.256,681,1.701,694,3.718,697,1.784,719,1.686,729,2.686,739,2.298,774,3.724,781,2.814,819,2.298,866,1.686,914,3.3,953,2.635,957,1.438,985,2.283,987,1.355,997,3.811,1027,3.805,1028,1.841,1070,3.055,1098,2.044,1131,3.377,1250,2.641,1295,2.686,1330,3.518,1417,2.253,1477,3.15,1599,1.566,1607,1.509,1618,1.514,1721,3.195,1722,2.806,1788,2.156,1789,2.49,1829,1.56,1868,2.641,1952,2.233,1975,6.706,1988,3.917,2016,2.03,2060,1.916,2075,1.904,2230,1.694,2255,3.514,2288,2.105,2570,2.03,3085,3.086,3220,2.686,4683,2.85,4780,2.735,4848,7.657,4903,2.918,4905,2.996,4906,2.996,4948,6.55,4998,4.681,5007,3.195,5008,9.401,5009,3.332,5026,3.514,5027,3.514,5028,3.514,5029,3.514,5030,4.805,5031,4.805,5032,3.514,5033,3.332,5034,2.996,5035,3.086,5036,3.514,5037,3.514,5059,3.514,6116,6.418,7708,3.792,7709,3.792,7710,3.792,7711,3.792,7712,3.792]],["t/1827",[1,1.897,3,3.204,5,1.662,21,2.23,41,4.648,48,3.013,83,2.287,95,3.898,97,2.395,117,1.13,118,3.848,126,3.034,139,2.282,208,2.288,249,3.581,538,3.272,571,3.831,576,2.507,597,2.993,612,3.012,619,3.53,817,4.154,818,6.754,866,4.585,867,3.182,1008,3.217,1062,3.514,1071,4.044,1187,3.728,1396,4.413,1418,3.145,1443,4.876,1547,4.071,1727,2.756,1819,4.183,2181,5.165,3702,7.935,7713,7.751,7714,7.76,7715,7.76,7716,6.317,7717,7.76,7718,7.76]],["t/1829",[33,3.501,48,3.171,72,2.674,75,4.403,83,2.345,117,0.895,123,2.514,126,3.193,187,3.455,249,3.769,488,2.755,555,2.962,612,3.115,618,4.467,671,4.032,787,3.425,818,4.177,991,3.584,998,2.396,1083,4.949,1727,4.471,1830,4.403,1974,4.151,2062,3.569,2153,6.139,2157,3.632,2304,3.648,2693,5.785,3154,5.688,3208,7.003,3702,8.207,3744,5.785,5897,11.007,7703,7.57,7719,8.167,7720,7.57,7721,8.167,7722,8.167,7723,8.167,7724,7.57,7725,8.167]],["t/1831",[31,5.877,71,5.801,72,3.703,75,4.825,78,4.495,79,5.089,81,4.895,83,1.767,148,2.283,183,5.973,187,3.664,193,3.297,401,4.549,414,3.067,415,5.538,594,5.479,808,6.34,811,6.727,820,3.197,867,2.762,869,5.048,966,6.727,1004,4.418,1727,4.017,3208,5.877,3702,8.704,4672,7.864,6057,7.071,7713,6.727,7726,8.295,7727,8.95,7728,8.95]],["t/1833",[30,0.97,33,1.556,44,1.564,47,2.604,83,0.936,89,2.766,97,2.714,115,1.635,117,1.163,138,1.463,148,1.209,156,1.152,168,1.581,194,1.792,219,2.902,243,2.901,267,1.775,412,2.999,462,2.719,470,3.25,525,2.354,529,2.536,609,3.249,613,2.367,651,3.156,670,2.118,748,1.816,781,1.199,785,2.44,814,1.599,834,4.174,895,2.593,980,2.063,1008,1.965,1009,1.689,1083,2.873,1091,2.653,1185,2.742,1273,1.854,1286,2.504,1355,2.933,1430,3.995,1727,1.684,1753,4.889,1825,2.766,1957,3.035,1979,3.113,2157,3.222,2275,5.602,2321,6.793,2425,2.574,2469,3.156,2591,3.358,2975,2.612,3041,3.488,3635,3.859,3659,5.803,3688,3.995,3702,3.648,4070,3.035,4341,5.775,4691,3.563,5206,3.746,5259,3.859,5312,4.394,6057,3.746,7012,10.368,7713,3.563,7729,8.795,7730,4.741,7731,10.609,7732,4.741,7733,8.795,7734,8.795,7735,4.741,7736,8.795,7737,4.741,7738,4.741,7739,4.741,7740,4.741,7741,4.741,7742,4.741,7743,4.741,7744,4.741,7745,4.741,7746,9.848,7747,6.716,7748,4.741,7749,4.741,7750,4.741,7751,4.741,7752,4.741,7753,4.741,7754,4.741,7755,4.741,7756,4.741,7757,4.741,7758,4.741,7759,4.741,7760,4.394,7761,4.741,7762,4.741,7763,4.741]],["t/1835",[38,3.801,85,2.207,116,3.618,117,1.273,146,4.093,148,3.496,224,3.789,267,1.911,452,4.644,525,3.874,538,2.476,562,3.186,607,2.139,612,2.279,639,5.36,697,4.871,811,8.729,866,3.47,912,3.672,978,2.463,1004,5.109,1064,4.828,1305,6.576,1471,3.874,1727,4.392,1799,4.333,1868,5.434,3208,5.124,3262,5.865,3702,6.005,6057,9.771,7713,7.779,7726,7.233,7764,7.804,7765,6.165,7766,7.804,7767,7.804,7768,7.804]],["t/1837",[36,4.773,44,1.552,97,2.693,117,0.957,148,2.839,208,3.931,414,2.367,615,3.195,617,4.608,645,3.617,670,3.898,697,5.768,787,3.66,811,8.366,1004,4.308,1727,4.842,2239,5.4,3208,5.73,6057,6.895,7026,10.317,7769,8.727,7770,8.727,7771,8.089,7772,11.131,7773,8.727,7774,8.089,7775,8.089]],["t/1839",[83,1.671,85,2.394,148,2.784,208,3.217,250,3.392,267,2.073,291,6.107,414,3.276,579,3.128,607,2.32,619,3.85,621,2.472,712,5.843,740,5.012,801,7.475,808,5.995,811,8.203,923,2.223,1072,4.276,1599,3.495,1697,6.226,1727,3.876,1846,5.129,1904,4.276,1923,4.938,2072,4.938,2328,6.906,2440,3.652,3208,7.933,6057,6.686,7774,7.844,7776,7.844,7777,7.437]],["t/1841",[75,5.439,78,3.772,83,1.483,85,2.124,117,0.823,148,2.574,172,1.738,187,2.433,208,2.214,229,2.561,250,3.01,414,3.303,470,2.301,620,3.449,621,2.193,712,4.021,759,3.449,766,4.809,781,1.9,786,4.021,801,6.243,814,2.533,871,4.17,955,3.175,1009,2.675,1028,4.899,1518,4.869,1599,3.101,1727,3.583,2157,4.486,2321,8.135,2328,4.752,2357,4.344,2440,3.241,2478,5.401,3208,4.932,3713,5.645,4672,6.6,5206,5.934,6068,6.329,7724,6.961,7747,6.961,7765,5.934,7777,6.6,7778,7.511,7779,7.511,7780,11.393,7781,7.511,7782,7.511,7783,7.511,7784,7.511,7785,7.511]],["t/1843",[1,1.448,5,1.269,17,3.769,30,1.212,44,2.561,47,2.129,83,2.471,84,4.294,116,2.746,123,2.632,126,2.316,139,1.742,148,2.181,156,2.078,159,5.205,177,3.908,183,4.515,208,3.239,219,1.955,245,2.324,250,2.374,263,1.842,267,1.451,414,3.159,525,2.941,529,2.073,740,2.72,748,3.275,801,3.665,923,1.556,953,2.567,994,3.626,1331,2.391,1431,2.774,1465,2.67,1727,3.901,1753,2.941,1799,3.289,1871,3.84,1923,3.456,2006,4.998,2440,2.556,2468,3.171,2770,2.545,2899,3.24,3318,3.59,3744,4.196,6068,4.992,7760,5.49,7771,7.925,7775,5.49,7777,5.205,7786,5.49,7787,5.923,7788,5.923,7789,5.923,7790,5.923,7791,5.49,7792,5.49,7793,5.49,7794,5.49,7795,5.49,7796,5.923,7797,5.49,7798,5.49,7799,5.49,7800,5.923]],["t/1845",[4,1.419,30,1.446,33,1.826,38,2.043,44,2.602,83,1.911,86,1.033,115,1.919,118,2.076,122,1.387,139,0.999,156,1.717,160,1.696,167,3.164,170,1.831,206,1.858,208,1.001,219,1.121,243,1.443,250,1.361,259,1.049,263,2.54,266,1.459,267,2.208,296,0.898,297,0.999,391,0.969,406,1.686,414,1.916,483,2.117,488,3.04,529,1.189,555,3.511,612,2.063,621,0.992,663,1.472,697,1.598,744,1.806,753,1.408,767,2,781,0.859,786,2.978,814,2.383,818,1.737,832,2.938,867,1.048,882,1.716,957,1.288,969,1.696,991,3.101,998,0.997,1004,1.677,1009,3.448,1055,1.28,1308,1.716,1399,2.716,1465,2.507,1599,1.402,1697,2.499,1715,1.376,1727,3.437,1753,3.508,1766,2.328,1841,3,1871,2.202,1974,1.726,2016,1.818,2018,1.686,2062,1.484,2171,1.448,2662,1.916,2693,2.406,2754,2.999,2879,2.406,2905,3.941,3030,2.149,3256,1.64,3611,3.246,3612,3.941,3641,4.528,3659,3.043,4188,2.683,4205,2.984,4206,4.888,4207,4.888,4208,4.888,4209,2.984,4376,2.683,4691,5.311,7396,3.148,7720,5.156,7791,3.148,7792,3.148,7793,3.148,7794,3.148,7795,3.148,7797,3.148,7798,3.148,7799,3.148,7801,3.397,7802,3.397,7803,3.397,7804,3.397,7805,3.397,7806,3.397,7807,3.397,7808,5.563,7809,5.563,7810,5.563,7811,5.563,7812,5.563,7813,5.563,7814,5.563,7815,3.397,7816,3.397,7817,3.397,7818,3.397,7819,3.397,7820,3.397,7821,3.397,7822,3.397,7823,3.397,7824,3.397,7825,3.397,7826,3.397,7827,3.397,7828,3.397,7829,3.397,7830,3.397,7831,3.397,7832,3.397,7833,3.397,7834,3.397,7835,3.397,7836,3.397,7837,3.397,7838,3.397,7839,3.397,7840,3.397,7841,3.397,7842,3.397,7843,3.397,7844,3.397,7845,3.397,7846,3.397]],["t/1847",[17,2.083,33,1.551,44,2.659,83,1.427,138,1.458,156,1.148,208,1.393,259,0.891,263,2.247,414,1.281,814,3.315,942,3.651,1007,3.476,1009,3.126,1331,1.908,1465,4.431,1727,1.678,1753,2.346,1841,1.735,1974,3.673,2016,2.529,2316,2.13,2425,3.924,3611,2.757,3612,3.347,3659,2.584,4341,3.103,5249,4.152,5259,3.846,6068,3.982,7847,9.111,7848,9.111,7849,9.111,7850,9.111,7851,9.111,7852,4.725,7853,4.725,7854,4.725,7855,4.725,7856,4.725,7857,4.725,7858,4.725,7859,4.725,7860,4.725,7861,4.725,7862,4.725,7863,4.725,7864,4.725,7865,4.725,7866,4.725,7867,4.725,7868,4.725,7869,4.725,7870,4.725,7871,4.725,7872,4.725,7873,4.725,7874,4.725,7875,4.725,7876,4.725,7877,4.725,7878,4.725,7879,4.725,7880,4.725,7881,4.725,7882,4.725,7883,4.725,7884,4.725]],["t/1849",[33,3.048,43,2.315,44,2.571,48,2.584,83,1.834,117,1.018,155,4.749,187,2.156,188,3.342,194,2.515,201,3.424,245,2.611,250,3.722,267,1.63,414,2.518,437,5.621,529,2.329,607,1.824,619,3.027,681,2.986,732,2.095,833,4.714,874,3.613,955,2.813,980,4.041,991,2.921,998,1.953,1009,2.37,1200,3.538,1204,2.717,1211,2.802,1311,5.002,1466,5.121,1596,2.459,1599,2.748,1727,4.111,2060,3.362,2965,6.083,3126,4.8,3262,5.002,3659,3.64,4349,9.423,5801,5.847,7847,6.168,7848,6.168,7849,6.168,7850,6.168,7851,6.168,7885,6.655,7886,6.655,7887,6.655,7888,6.655,7889,6.655,7890,6.655]],["t/1851",[36,5.158,48,3.662,118,3.519,206,5.158,208,2.78,241,5.084,267,2.863,473,2.774,506,5.084,802,3.263,971,5.014,980,4.104,1151,5.409,1185,5.455,1395,8.288,1555,7.258,1577,5.716,1727,4.151,2177,5.605,3702,8.995,7713,8.785,7891,9.432,7892,9.432,7893,7.677,7894,9.432,7895,9.432]],["t/1853",[5,1.46,7,1.739,30,1.395,33,3.839,83,1.346,117,0.747,122,2.783,165,2.941,168,3.15,172,1.577,201,3.508,210,3.125,218,2.378,226,5.45,245,2.674,463,2.325,470,3.583,472,4.364,488,4.394,492,2.693,510,1.991,521,2.941,555,4.609,609,4.672,611,5.152,647,3.977,816,2.783,866,3.031,867,2.104,875,3.043,885,4.014,890,3.161,955,2.882,971,3.624,1028,3.31,1142,4.537,1170,2.905,1177,2.262,1431,3.192,1751,3.909,1914,3.404,1926,3.649,2154,3.53,2233,4.173,2259,4.747,2260,5.201,2417,5.548,2881,4.343,3873,4.419,4510,4.419,7896,5.744,7897,5.246,7898,5.744,7899,5.99,7900,6.318]],["t/1855",[4,4.028,7,1.41,30,2.176,41,2.491,117,1.057,122,4.341,137,2.256,164,2.256,168,2.712,172,1.279,196,2.431,201,2.844,214,3.364,219,1.824,224,2.683,240,1.255,267,2.604,391,1.577,412,1.885,457,2.48,470,1.693,473,2.836,483,2.103,488,4.326,492,2.183,555,4.652,557,2.042,562,2.256,607,3.248,611,5.379,612,2.374,615,2.023,621,1.614,647,4.743,670,2.468,681,2.48,748,2.117,816,4.341,875,2.619,885,3.254,923,1.451,955,2.336,987,1.974,991,4.232,1055,2.082,1067,3.788,1072,2.792,1082,3.316,1089,4.831,1170,2.355,1177,1.833,1218,2.899,1249,2.899,1273,2.161,1364,3.538,1618,2.207,1712,3,1751,5.529,1774,3.497,1854,4.366,1914,2.759,1952,3.254,2062,2.415,2117,4.066,2259,6.715,2260,2.457,2304,2.468,2440,2.384,2881,2.215,4502,3.629,4509,4.253,7901,4.366,7902,3.848,7903,5.122]],["t/1857",[3,2.477,11,2.069,12,3.248,33,1.969,94,2.023,95,2.268,97,1.851,115,3.486,117,0.946,122,5.129,160,4.309,201,3.087,213,2.589,214,2.093,218,2.093,238,4.991,243,1.556,245,2.354,267,2.475,414,1.627,457,2.692,483,2.283,488,3.727,490,2.468,535,3.384,555,3.666,557,2.217,600,3.532,607,1.645,611,2.516,612,1.752,622,3.168,681,3.872,753,2.487,781,2.557,816,5.129,820,2.143,866,2.668,875,2.781,914,2.599,991,2.633,1004,5.78,1015,2.962,1018,3.889,1059,4.617,1062,2.717,1103,4.883,1146,3.147,1177,1.99,1204,2.449,1218,3.147,1265,3.841,1471,2.978,1481,4.74,1618,3.446,1807,2.897,1954,3.107,2118,3.306,2153,4.509,2182,3.44,2259,4.178,2260,3.837,2899,3.281,2918,4.25,3066,4.883,3135,7.038,4079,4.112,4332,4.74,4336,3.673,7902,4.178,7904,5.561,7905,4.509,7906,5.056,7907,5.561,7908,4.883,7909,7.272]],["t/1859",[10,2.433,28,3.339,30,1.907,41,3.014,44,1.189,83,2.118,117,1.021,122,2.73,139,3.154,172,1.547,243,1.734,258,3.557,263,2.079,268,3.902,411,1.547,474,2.463,488,4.676,555,5.029,579,2.471,611,5.631,615,3.411,681,3,748,2.561,783,5.895,816,2.73,908,2.471,923,2.447,978,2.111,987,2.389,1170,2.85,1465,3.014,1618,4.632,1622,5.443,1914,3.339,1985,4.583,2278,4.012,2316,4.2,2478,3.579,2851,4.919,2881,2.68,3032,4.052,3675,4.823,3895,7.003,4079,4.583,7910,6.197,7911,6.197]],["t/1861",[10,3.298,28,4.527,83,1.79,117,1.25,164,4.655,226,4.224,243,3.235,472,5.804,488,4.549,555,4.748,575,3.715,578,4.995,611,3.802,615,3.319,619,4.124,914,3.928,923,2.381,1170,5.316,1471,4.501,1735,5.804,2260,4.031,2881,3.633,7912,8.403]],["t/1863",[30,2.625,83,2.481,117,1.166,139,2.391,172,1.279,201,6.097,213,4.16,457,2.48,488,4.715,555,5.071,582,3.045,611,4.969,647,3.225,649,2.425,866,2.457,875,3.651,890,2.562,908,2.042,980,2.405,987,2.904,1003,6.175,1004,4.76,1045,3.582,1181,2.809,1187,2.655,1253,4.157,1256,5.864,1711,3.117,1751,3.169,2154,4.993,2260,4.728,2261,3.788,2262,4.253,2899,3.022,2918,6.83,3135,7.404,4335,7.848,4336,3.383,7001,4.366,7902,7.404,7913,4.253]],["t/1865",[4,2.754,21,1.894,28,3.292,30,1.349,44,1.172,83,2.102,87,2.261,117,1.011,126,2.577,165,3.981,194,2.492,210,3.053,214,2.3,226,3.071,235,3.167,259,1.243,267,1.615,463,2.248,488,4.622,552,3.273,555,4.971,579,2.436,615,3.378,624,3.292,640,5.792,681,4.139,737,2.999,742,3.918,748,3.534,756,3.118,796,3.15,923,2.423,1009,3.791,1011,3.436,1041,5.073,1170,3.932,1177,3.061,1205,2.999,1618,3.684,1697,4.85,1715,2.671,1723,3.749,1783,4.955,1874,3.846,1914,3.292,2260,2.931,2881,4.621,3142,5.366,3895,6.934,7898,5.555,7914,5.792,7915,6.11,7916,6.11,7917,9.865]],["t/1868",[3082,6.664]],["t/1870",[1,2.508,7,2.617,30,2.1,118,3.828,210,3.395,414,2.783,463,3.499,524,5.987,641,6.829,802,3.549,814,3.46,1009,3.655,1962,6.829,2263,4.712,2452,5.741,2453,5.884,2770,4.409,7918,8.646]],["t/1872",[91,3.13,122,4.765,186,4.379,190,3.349,193,4.517,194,2.564,198,3.349,210,3.862,240,2.453,411,2.501,414,1.84,463,3.21,474,2.499,487,4.3,639,3.513,697,3.192,731,4.07,732,2.136,753,2.812,765,5.22,801,4.197,802,2.347,814,4.543,816,4.412,832,3.582,987,2.423,1009,2.416,1030,3.535,1120,3.683,1322,4.991,1723,3.858,1819,3.657,1914,3.387,1953,4.244,1962,4.515,1966,4.755,1974,3.448,2075,4.727,2345,5.099,2353,4.97,2456,5.703,2619,5.219,2770,5.016,3511,4.905,3651,5.522,5473,5.887,7919,6.287,7920,5.961]],["t/1874",[1,2.799,7,2.92,33,2.995,117,1,118,3.405,122,4.674,186,3.698,193,3.362,210,3.788,406,4.53,463,3.112,487,3.631,606,5.373,679,4.61,781,2.308,802,4.539,816,4.674,1249,4.786,1607,3.631,1751,5.232,1828,6.582,2233,5.586,2380,4.251,2469,6.073,3501,6.463,7918,7.689,7921,7.689]],["t/1876",[7,2.343,122,3.75,186,5.329,190,4.534,193,3.384,210,3.039,414,2.491,579,3.394,753,3.807,756,4.344,802,3.177,814,3.098,816,3.75,908,3.394,923,3.019,1072,4.64,1349,5.18,1398,4.436,1607,3.655,1830,4.951,1962,6.113,2075,4.613,2263,4.218,2353,4.85,2453,5.267,2619,4.436,2770,3.946,3511,4.787,5473,5.745,5550,6.757]],["t/1878",[7,1.544,30,1.238,83,1.714,97,1.867,117,1.113,146,4.555,148,1.544,154,4.214,177,2.766,186,2.452,188,3.039,190,2.987,193,3.199,196,1.809,210,2.002,213,2.611,214,2.111,216,3.154,224,2.938,240,1.971,276,4.93,297,2.554,398,3.199,414,3.558,454,3.829,463,2.961,482,3.286,487,3.455,489,2.896,497,3.874,521,2.611,552,3.004,609,4.147,623,3.631,660,2.589,732,1.905,737,2.753,753,4.209,764,2.568,801,3.744,802,2.093,814,3.742,832,3.195,867,1.867,908,2.236,964,4.859,978,1.91,1033,3.057,1179,4.452,1218,3.174,1368,4.286,1386,3.705,1723,3.441,1732,3.076,1774,3.829,1954,3.133,1961,2.938,2006,2.753,2075,5.9,2130,3.973,2263,5.917,2313,3.5,2353,4.585,2380,2.819,2453,3.47,2931,4.657,3337,2.954,3498,4.286,5473,5.431,7922,4.365,7923,4.548,7924,5.099,7925,4.548]],["t/1880",[30,2.331,73,1.908,83,2.07,117,1.248,122,3.693,136,2.864,138,1.979,146,4.746,156,1.558,177,2.93,178,4.369,186,2.598,193,3.862,196,1.917,229,2.186,297,2.661,398,2.362,414,3.547,474,2.362,483,2.439,487,2.551,579,2.369,609,4.394,612,2.642,615,3.312,663,2.778,697,3.017,785,3.299,802,2.218,814,3.841,816,3.693,908,2.369,964,3.587,978,2.856,1009,3.222,1033,4.571,1170,2.732,1177,2.127,1607,2.551,1722,2.958,1962,6.978,1974,4.598,2171,3.856,2182,3.676,2263,4.814,2350,3.967,2353,4.777,2380,2.987,2453,3.676,2456,3.885,2770,4.505,3337,4.417,7926,7.624,7927,5.942,7928,5.218,7929,4.625,7930,5.942,7931,4.465,7932,4.819]],["t/1882",[7,1.714,30,2.379,85,2.644,117,1.274,137,2.743,138,2.885,187,2.176,218,2.344,240,1.525,267,1.646,297,2.749,320,3.596,398,3.444,414,2.535,473,1.976,474,2.475,487,2.673,511,3.056,586,3.014,693,3.92,697,3.162,732,2.944,753,3.875,796,3.211,802,2.324,814,4.377,908,2.483,923,1.764,964,3.759,998,1.971,1008,2.785,1142,4.472,1211,2.829,1264,5.469,1279,3.853,1418,2.722,1636,5.05,1961,3.262,1966,3.394,2003,4.536,2075,6.354,2182,3.853,2263,6.372,2353,4.937,2452,6.016,2619,4.515,3337,3.28,3498,4.759,5473,5.848,6863,5.469]],["t/1884",[30,2.704,83,2.493,117,1.271,136,4.157,177,4.253,194,3.518,297,2.737,615,4.244,814,4.258,923,2.444,2263,6.365,2619,4.494,3137,7.715,3306,6.378,3337,4.543,7933,8.072]],["t/1886",[9,7.647,30,2.75,83,2.122,85,2.337,90,3.035,95,3.124,117,1.309,136,3.691,194,3.124,262,3.85,531,5.335,615,3.025,814,4.533,867,2.55,923,2.17,957,3.134,1345,5.755,1974,5.462,2233,5.059,2263,6.284,3137,7.153,3306,5.664,4630,5.961,7128,6.08,7933,7.484,7934,7.659]],["t/1888",[85,2.547,117,0.987,146,4.725,193,3.318,262,4.197,276,4.373,398,4.184,414,3.373,463,3.072,487,4.519,697,4.239,814,3.038,867,2.78,875,2.902,964,5.04,998,2.643,1418,3.65,1722,4.156,1926,4.822,2263,6.313,2353,5.997,2619,5.485,3137,5.995,3306,6.173,3498,6.38,4510,5.839]],["t/1890",[30,1.624,83,1.567,91,4.829,117,1.284,122,3.24,146,5.49,178,3.833,186,3.216,193,2.924,224,3.853,262,3.698,398,2.924,414,3.675,463,2.707,487,3.158,643,5.839,649,3.483,697,4.925,814,4.365,816,3.24,964,4.441,998,2.329,1170,4.991,1331,3.204,1607,3.158,1966,4.01,1974,4.034,2239,4.91,2263,5.717,2353,5.527,2453,4.551,2986,6.973,3337,3.874,7929,5.725,7931,5.527,7932,5.965,7933,5.527]],["t/1892",[9,5.115,17,2.38,30,2.609,83,2.216,85,1.527,90,1.983,91,2.491,117,1.288,122,2.204,126,2.111,146,4.191,186,2.188,193,1.989,213,2.329,219,1.781,250,2.164,262,3.723,264,2.515,268,4.662,276,3.879,398,1.989,414,3.297,463,1.841,487,2.148,531,3.966,557,1.995,595,3.593,643,3.972,697,2.54,814,4.7,816,2.204,957,3.03,964,3.021,998,1.584,1055,2.034,1170,4.053,1179,3.972,1331,3.226,1345,3.759,1352,5.246,1607,3.179,1713,4.265,1966,2.727,1974,4.061,2233,3.305,2239,4.943,2263,5.395,2305,4.37,2316,4.287,2353,4.219,2453,3.096,2456,7.726,2579,8.557,2619,2.607,4630,3.894,7128,3.972,7929,3.894,7931,3.759,7932,4.058,7933,3.759,7935,5.004,7936,8.816,7937,8.816]],["t/1894",[83,2.262,85,2.147,94,2.561,117,0.832,123,2.337,146,6.009,148,1.937,177,3.47,186,3.076,190,6.724,267,1.86,276,3.686,297,2.989,454,4.804,488,3.427,510,2.217,615,2.78,679,3.836,732,2.39,760,3.667,795,6.398,797,5.998,867,2.343,888,4.215,923,1.994,954,5.477,955,3.21,1056,5.93,1115,4.47,1431,3.555,1678,3.813,1715,3.076,1723,4.317,1840,5.842,2300,4.248,2452,4.248,3337,3.706,3809,5.477,4085,5.477,5473,7.652,7924,6.398,7938,8.564,7939,7.037,7940,7.037,7941,6.398,7942,6.398,7943,8.029]],["t/1896",[30,1.708,38,2.104,83,2.136,85,1.62,86,1.742,97,1.768,117,1.079,138,1.768,169,2.606,170,3.089,186,3.382,188,4.945,190,5.676,196,2.496,216,2.986,224,2.782,297,2.455,414,3.254,463,1.954,489,1.911,491,2.452,538,1.818,546,3.343,575,2.348,609,3.927,619,3.797,630,3.134,654,3.382,712,3.067,732,1.804,753,5.135,764,3.543,802,1.982,814,4.366,867,2.576,908,2.117,953,2.483,955,2.422,964,3.206,1072,2.895,1465,4.438,1596,2.117,1647,3.343,1722,2.644,1776,2.986,1873,5.481,1904,2.895,1961,2.782,2006,3.797,2061,4.133,2075,6.222,2263,2.631,2453,3.286,3208,3.762,3337,4.806,3873,3.714,5473,7.192,7922,7.102,7923,4.306,7925,4.306,7928,4.664,7933,3.99,7944,4.058,7945,5.311,7946,7.736,7947,5.311,7948,4.828,7949,4.664,7950,4.828]],["t/1898",[21,3.156,210,3.634,491,4.7,756,5.195,908,4.059,923,2.885,2249,8.678,2263,5.044,2452,6.147]],["t/1900",[30,1.799,44,1.095,73,1.832,83,2.025,85,2.9,89,3.593,117,1.124,148,2.243,156,2.492,163,2.927,186,2.495,190,6.802,210,2.037,214,2.149,219,2.032,224,2.99,263,1.915,297,1.811,491,2.635,510,2.568,533,4.157,570,4.098,584,2.855,617,3.252,621,1.798,666,2.543,682,5.189,697,2.898,732,2.768,824,5.012,862,3.942,888,4.881,891,3.006,1056,3.593,1082,3.695,1091,3.446,1115,5.176,1218,3.23,1279,5.041,1308,3.111,1385,4.442,1421,3.006,1431,2.883,1465,3.963,1471,3.057,1723,4.999,1840,6.766,1961,2.99,2010,3.852,2263,2.828,2300,3.446,2350,3.81,2363,5.699,2380,2.869,2452,6.258,2468,3.296,3306,4.22,3542,9.01,3809,6.342,3855,4.442,5473,6.414,5550,4.53,6655,5.411,7951,5.707,7952,5.707,7953,5.707,7954,8.149,7955,5.012,7956,5.012]],["t/1902",[30,1.775,83,1.713,85,2.453,117,0.951,148,2.828,164,3.541,196,3.315,239,4.102,243,2.249,414,3.61,557,3.205,615,4.059,740,5.612,748,3.322,814,2.925,831,4.234,867,3.422,957,3.289,1160,5.944,1279,6.358,1386,5.31,1647,5.061,2263,5.612,2452,4.853,2468,4.643,2770,4.764,7929,6.256,7957,7.309,7958,7.309]],["t/1904",[30,2.065,44,2.025,83,1.483,85,2.124,117,0.823,148,1.916,164,3.066,172,1.738,190,6.273,218,2.621,219,2.478,264,3.499,414,3.548,491,3.214,615,2.75,621,2.193,814,2.533,889,5.526,908,2.776,923,1.973,953,3.254,1056,4.382,1134,4.932,1159,3.914,1279,4.307,1370,4.382,1465,4.547,1678,3.772,1723,4.271,1790,3.417,1961,3.647,2006,4.59,2075,3.772,2263,3.449,2316,5.49,2350,7.049,2452,6.375,2877,5.934,3337,3.667,4341,4.932,7929,5.418,7943,5.934,7958,6.329,7959,6.961,7960,6.961,7961,6.961,7962,6.961]],["t/1906",[30,2.178,44,1.892,83,2.102,117,1.011,126,3.607,164,4.345,178,3.184,188,3.311,198,4.554,214,2.3,224,3.201,258,2.517,267,1.615,276,3.201,402,2.56,414,3.677,489,2.199,510,1.925,562,2.691,619,2.999,732,3.351,809,2.147,814,4.622,867,2.034,1008,2.733,1160,4.518,1170,2.809,1279,3.78,1399,4.504,1471,3.273,1647,3.846,2006,2.999,2075,6.094,2263,3.027,2300,3.689,2380,3.071,2452,6.451,2978,5.073,3511,3.436,4662,4.955,5896,4.518,7923,4.955,7925,8,7957,5.555,7963,5.555,7964,8.551,7965,8.551,7966,8.551,7967,6.11]],["t/1908",[6,1.65,9,3.432,21,0.933,30,2.348,42,3.674,44,1.217,50,2.132,83,1.737,85,0.918,90,3.479,95,1.227,117,1.038,126,2.096,136,1.45,145,1.831,156,1.931,175,1.552,177,1.484,178,1.568,194,1.227,198,1.603,214,3.497,219,3.457,239,2.536,240,1.804,243,1.39,267,0.795,276,3.324,297,0.955,463,1.107,510,0.948,557,1.2,562,1.326,575,2.197,576,1.049,578,2.954,595,2.161,612,0.948,615,1.963,619,2.439,641,2.161,712,2.87,731,3.217,732,3.69,744,2.85,760,3.307,787,1.362,802,1.854,814,4.759,867,1.002,914,1.407,923,0.853,953,2.967,978,1.692,991,1.425,998,2.332,1109,2.079,1120,1.763,1189,2.192,1211,1.367,1279,3.926,1352,2.132,1399,3.88,1418,1.316,1471,1.612,1477,2.776,1596,2.53,1678,1.631,1723,3.894,1772,1.66,1776,2.794,1791,1.621,1862,2.44,1878,4.192,1954,1.681,2003,2.192,2075,3.439,2239,3.317,2263,6.275,2300,1.817,2380,1.513,2452,7.3,2453,1.862,2619,4.84,2690,5.146,2830,4.029,3249,2.499,3337,1.585,3510,2.565,4376,4.235,4472,2.161,5896,2.225,7115,5.573,7521,2.736,7909,4.518,7933,2.261,7968,6.346,7969,7.73,7970,3.009,7971,4.969,7972,4.711,7973,6.346,7974,3.009,7975,3.009,7976,3.009]],["t/1911",[26,3.907,30,2.08,83,1.499,117,0.832,122,4.677,178,4.908,193,4.507,198,3.748,297,2.233,414,3.106,489,2.533,531,3.769,579,2.806,595,5.053,612,2.217,697,4.782,756,3.591,764,4.313,802,2.626,814,4.126,816,4.677,867,3.136,1009,2.704,1055,2.86,1091,4.248,1198,5.126,1277,4.009,1962,8.142,1974,5.822,2171,3.236,2350,4.698,2353,5.366,2380,4.735,2456,6.158,2770,4.367,2902,5.998,7926,8.564,7963,6.398,7977,5.842]],["t/1913",[4,1.798,12,1.383,21,1.237,44,2.067,80,3.319,81,2.354,83,2.219,85,1.217,87,1.476,91,1.986,117,1.025,123,1.325,126,1.683,146,4.341,148,2.386,169,3.059,186,1.744,187,1.394,190,2.125,229,1.468,235,2.068,241,2.32,250,2.695,259,0.812,264,3.133,267,1.054,268,2.511,414,3.241,488,1.452,489,1.436,510,1.257,578,2.372,619,1.958,624,2.149,627,1.873,640,3.782,663,2.914,666,1.777,712,3.6,731,2.583,740,3.088,742,2.558,753,4.459,764,1.827,797,3.4,801,4.161,802,1.489,814,2.791,817,2.304,832,2.273,923,1.13,953,1.865,955,2.843,964,2.408,1011,4.313,1015,2.125,1041,3.312,1110,2.723,1160,2.95,1182,4.609,1198,5.587,1261,2.95,1307,2.337,1370,2.511,1477,2.229,1484,3.4,1596,2.485,1599,1.777,1723,2.448,1753,2.137,1776,3.504,1783,3.235,1961,2.09,2006,3.059,2018,2.137,2075,6.52,2076,7.614,2245,3.782,2300,2.408,2313,2.489,2321,2.756,2353,2.273,2380,2.005,2440,2.901,2456,2.608,2553,3.049,2662,2.428,3208,5.434,4085,3.105,4689,2.468,5473,2.692,5896,2.95,7124,3.627,7130,3.4,7922,6.748,7923,5.054,7925,5.054,7938,5.667,7941,3.627,7942,3.627,7943,5.313,7948,5.667,7949,3.503,7950,5.667,7978,8.67,7979,6.233,7980,3.989,7981,3.989,7982,3.989,7983,3.989,7984,3.989,7985,6.233,7986,3.989,7987,6.233,7988,6.233,7989,3.989,7990,3.989,7991,3.989,7992,3.989]],["t/1915",[5,1.46,7,1.739,30,1.395,33,3.839,83,1.346,117,0.747,122,2.783,165,2.941,168,3.15,172,1.577,201,3.508,210,3.125,218,2.378,226,5.45,245,2.674,463,2.325,470,3.583,472,4.364,488,4.394,492,2.693,510,1.991,521,2.941,555,4.609,609,4.672,611,5.152,647,3.977,816,2.783,866,3.031,867,2.104,875,3.043,885,4.014,890,3.161,955,2.882,971,3.624,1028,3.31,1142,4.537,1170,2.905,1177,2.262,1431,3.192,1751,3.909,1914,3.404,1926,3.649,2154,3.53,2233,4.173,2259,4.747,2260,5.201,2417,5.548,2881,4.343,3873,4.419,4510,4.419,7896,5.744,7897,5.246,7898,5.744,7899,5.99,7900,6.318]],["t/1917",[4,4.028,7,1.41,30,2.176,41,2.491,117,1.057,122,4.341,137,2.256,164,2.256,168,2.712,172,1.279,196,2.431,201,2.844,214,3.364,219,1.824,224,2.683,240,1.255,267,2.604,391,1.577,412,1.885,457,2.48,470,1.693,473,2.836,483,2.103,488,4.326,492,2.183,555,4.652,557,2.042,562,2.256,607,3.248,611,5.379,612,2.374,615,2.023,621,1.614,647,4.743,670,2.468,681,2.48,748,2.117,816,4.341,875,2.619,885,3.254,923,1.451,955,2.336,987,1.974,991,4.232,1055,2.082,1067,3.788,1072,2.792,1082,3.316,1089,4.831,1170,2.355,1177,1.833,1218,2.899,1249,2.899,1273,2.161,1364,3.538,1618,2.207,1712,3,1751,5.529,1774,3.497,1854,4.366,1914,2.759,1952,3.254,2062,2.415,2117,4.066,2259,6.715,2260,2.457,2304,2.468,2440,2.384,2881,2.215,4502,3.629,4509,4.253,7901,4.366,7902,3.848,7903,5.122]],["t/1919",[3,2.477,11,2.069,12,3.248,33,1.969,94,2.023,95,2.268,97,1.851,115,3.486,117,0.946,122,5.129,160,4.309,201,3.087,213,2.589,214,2.093,218,2.093,238,4.991,243,1.556,245,2.354,267,2.475,414,1.627,457,2.692,483,2.283,488,3.727,490,2.468,535,3.384,555,3.666,557,2.217,600,3.532,607,1.645,611,2.516,612,1.752,622,3.168,681,3.872,753,2.487,781,2.557,816,5.129,820,2.143,866,2.668,875,2.781,914,2.599,991,2.633,1004,5.78,1015,2.962,1018,3.889,1059,4.617,1062,2.717,1103,4.883,1146,3.147,1177,1.99,1204,2.449,1218,3.147,1265,3.841,1471,2.978,1481,4.74,1618,3.446,1807,2.897,1954,3.107,2118,3.306,2153,4.509,2182,3.44,2259,4.178,2260,3.837,2899,3.281,2918,4.25,3066,4.883,3135,7.038,4079,4.112,4332,4.74,4336,3.673,7902,4.178,7904,5.561,7905,4.509,7906,5.056,7907,5.561,7908,4.883,7909,7.272]],["t/1921",[10,2.433,28,3.339,30,1.907,41,3.014,44,1.189,83,2.118,117,1.021,122,2.73,139,3.154,172,1.547,243,1.734,258,3.557,263,2.079,268,3.902,411,1.547,474,2.463,488,4.676,555,5.029,579,2.471,611,5.631,615,3.411,681,3,748,2.561,783,5.895,816,2.73,908,2.471,923,2.447,978,2.111,987,2.389,1170,2.85,1465,3.014,1618,4.632,1622,5.443,1914,3.339,1985,4.583,2278,4.012,2316,4.2,2478,3.579,2851,4.919,2881,2.68,3032,4.052,3675,4.823,3895,7.003,4079,4.583,7910,6.197,7911,6.197]],["t/1923",[10,3.298,28,4.527,83,1.79,117,1.25,164,4.655,226,4.224,243,3.235,472,5.804,488,4.549,555,4.748,575,3.715,578,4.995,611,3.802,615,3.319,619,4.124,914,3.928,923,2.381,1170,5.316,1471,4.501,1735,5.804,2260,4.031,2881,3.633,7912,8.403]],["t/1925",[30,2.625,83,2.481,117,1.166,139,2.391,172,1.279,201,6.097,213,4.16,457,2.48,488,4.715,555,5.071,582,3.045,611,4.969,647,3.225,649,2.425,866,2.457,875,3.651,890,2.562,908,2.042,980,2.405,987,2.904,1003,6.175,1004,4.76,1045,3.582,1181,2.809,1187,2.655,1253,4.157,1256,5.864,1711,3.117,1751,3.169,2154,4.993,2260,4.728,2261,3.788,2262,4.253,2899,3.022,2918,6.83,3135,7.404,4335,7.848,4336,3.383,7001,4.366,7902,7.404,7913,4.253]],["t/1927",[28,3.506,30,1.437,44,1.248,83,2.173,117,1.057,165,4.159,194,2.654,210,3.189,214,2.45,226,3.272,267,1.72,463,2.395,488,4.676,552,3.486,555,5.029,579,2.595,615,3.529,681,4.324,737,3.194,748,3.692,756,3.321,796,3.355,923,2.531,1009,3.92,1170,4.108,1177,3.198,1205,3.194,1618,3.849,1697,5.166,1715,2.845,1874,4.097,1914,3.506,2260,3.122,2881,4.747,3142,5.715,3895,7.244,7898,5.917,7914,6.17,7915,6.508,7916,6.508,7917,10.2]],["t/1929",[3082,6.664]],["t/1931",[3082,6.664]],["t/1933",[3082,6.664]],["t/1935",[3082,6.664]],["t/1937",[0,4.803,1,2.081,2,3.503,5,1.824,7,2.795,11,2.937,12,3.521,14,4.527,117,0.933,201,4.381,240,1.933,245,4.299,259,2.066,304,4.765,397,4.968,489,2.84,502,4.883,510,2.487,521,4.728,526,4.088,528,5.264,538,2.701,636,4.381,891,4.157,987,3.042,989,4.883,1276,5.836,1327,4.765,1362,5.519,1418,3.45,1816,3.705,1912,6.4,1913,6.931,1914,4.252,1915,6.142,1916,5.591,1917,6.553,1918,4.409,1919,5.213]],["t/1939",[117,0.969,177,5.128,180,3.606,218,3.915,243,2.292,259,1.667,265,4.798,267,2.164,391,3.519,438,5.39,607,2.423,620,4.058,624,4.412,775,3.284,781,2.839,875,2.847,1753,4.387,1918,6.932,1921,6.434,1932,7.765,1933,7.447,1937,7.447,1943,6.547,1959,8.094,2440,3.813]],["t/1941",[211,4.059,243,2.849,391,3.135,411,2.542,474,4.047,912,5.169,985,3.292,3082,6.246,7993,10.984]],["t/1943",[30,1.743,73,2.534,83,2.164,116,3.948,139,2.504,156,2.069,168,2.84,209,3.463,211,3.147,258,3.251,304,4.765,438,5.264,473,2.504,474,3.137,510,2.487,526,3.177,554,5.93,555,3.974,576,2.751,611,3.571,626,3.262,735,5.825,908,3.147,1055,3.208,1211,3.585,1252,5.519,1257,5.667,1519,7.465,1579,5.519,1921,4.883,1943,4.968,1973,6.931,2148,6.553,2215,7.398,2573,5.836,3294,6.142,3337,4.157]],["t/1945",[14,6.484,73,3.009,245,3.967,259,2.3,391,2.886,474,3.725,538,3.208,607,2.772,641,6.731,890,4.689,908,3.737,980,4.4,1480,5.659,1715,4.098,1916,6.64,1919,6.191,2440,4.363,5365,9.373]],["t/1947",[5,1.858,11,2.992,14,4.611,83,1.713,123,2.67,145,4.892,245,3.403,259,1.636,488,2.925,489,2.893,528,4.166,545,5.773,579,3.205,631,5.31,633,6.256,766,5.553,781,2.805,831,4.234,1013,5.244,1028,4.211,1253,4.435,1485,5.622,1586,4.356,1774,5.487,1799,4.815,1829,3.568,1916,5.695,1918,5.741,1919,6.788,1921,4.973,1935,5.855,1936,6.674,1941,6.256,2140,6.852,2141,8.039,4313,6.04,4314,6.143,7994,8.039,7995,8.673]],["t/1949",[73,3.243,83,2.152,84,5.474,117,1.195,151,6.051,265,5.918,624,5.442,1753,5.411,1799,6.051,1931,8.387]],["t/1951",[7,3.128,14,5.004,28,3.387,29,3.796,30,1.926,47,2.438,51,4.727,83,1.339,91,3.13,93,4.385,97,2.093,116,3.145,123,2.088,126,2.652,138,2.093,155,3.469,164,2.769,168,3.14,186,2.749,196,2.028,209,4.748,211,3.994,245,2.661,259,1.775,438,4.521,443,2.845,470,2.078,488,2.288,506,5.074,528,3.259,535,3.826,538,2.152,557,2.507,570,6.264,576,2.192,612,1.981,626,4.14,649,2.977,735,3.606,764,2.879,770,3.606,963,4.07,978,2.141,1019,5.011,1200,3.606,1211,2.856,1252,4.397,1519,3.826,1790,3.086,1814,6.287,1916,4.454,1921,3.89,1943,5.492,1962,6.264,1967,3.387,1973,5.522,1988,2.483,2062,4.113,2122,4.991,2181,4.515,7425,8.723,7996,6.784]],["t/1953",[7,2.226,14,4.64,117,1.22,187,3.605,196,2.609,210,2.888,211,3.225,259,1.646,391,2.491,411,2.576,419,3.989,422,5.624,487,3.473,510,3.251,527,4.077,544,4.383,557,3.225,568,4.26,627,4.843,875,2.812,1030,4.548,1069,4.491,1185,5.047,1918,4.519,1919,5.343,1935,5.892,1943,5.092,2215,8.275,3595,5.522,4668,8.089,7997,8.727,7998,8.727]],["t/1955",[11,2.769,12,2.58,14,4.267,21,3.384,84,4.032,117,1.371,118,2.995,240,1.822,259,1.989,266,3.449,299,5.419,351,4.327,443,3.366,463,2.738,474,2.957,483,3.054,528,3.856,597,3.095,612,2.344,631,4.914,659,4.053,781,2.031,787,3.366,830,4.684,870,4.816,875,3.398,890,3.722,908,2.967,980,3.493,1071,4.183,1208,3.669,1218,4.211,1480,4.492,1715,3.253,1732,4.08,1816,3.493,1827,6.177,1829,3.302,1918,5.46,1987,6.753,2151,5.905,3236,5.079,3694,6.342,7999,8.027,8000,8.027]],["t/1957",[2,1.822,3,3.192,4,1.85,5,1.656,7,0.66,12,1.866,14,2.355,20,3.099,21,0.744,22,0.985,30,1.188,37,1.722,42,1.773,47,0.93,73,0.77,96,1.019,97,0.799,117,0.284,150,1.843,155,2.969,156,1.671,166,2.916,172,1.344,177,4.975,180,2.484,183,2.339,187,1.435,188,2.916,190,2.186,201,1.331,206,1.415,208,1.306,210,3.143,213,1.116,219,0.854,222,2.519,228,1.426,229,1.98,238,1.497,245,2.278,248,6.045,250,1.037,259,0.488,263,0.805,264,1.206,265,1.405,267,1.085,402,1.005,418,1.3,437,3.753,443,5.262,452,1.161,468,1.773,470,0.793,474,2.848,488,0.873,495,1.085,505,1.385,528,2.128,529,0.905,562,1.056,607,0.709,612,1.696,613,1.292,619,2.015,622,3.066,624,1.292,652,3.252,660,2.942,670,1.156,697,3.236,732,1.395,733,6.628,737,1.177,740,1.188,748,0.991,757,1.25,760,1.25,769,3.388,781,1.121,783,1.637,787,1.085,827,1.945,867,0.799,882,1.307,889,1.904,908,0.956,953,2.516,967,1.619,977,1.833,993,2.652,1003,1.348,1008,1.836,1010,1.802,1025,2.899,1033,1.307,1072,1.307,1097,1.06,1169,3.977,1180,1.426,1203,1.448,1232,1.945,1268,1.991,1281,2.422,1295,1.833,1331,1.788,1351,1.584,1370,4.012,1372,1.677,1412,8.377,1417,1.538,1418,1.048,1465,1.996,1473,1.637,1489,1.357,1521,1.471,1596,1.637,1678,1.3,1722,1.194,1734,1.27,1749,1.497,1755,3.499,1772,1.323,1791,1.292,1798,2.18,1825,1.51,1830,1.395,1846,1.568,1862,1.945,1873,1.699,1896,3.275,1904,1.307,1916,3.813,1918,5.766,1921,6.385,1948,1.459,1950,6.08,1951,2.044,1959,1.867,1977,1.991,1984,1.802,2032,1.292,2033,1.747,2173,6.486,2182,1.484,2230,2.594,2243,6.486,2313,1.497,2319,2.106,2380,2.064,2504,8.805,2570,1.385,2923,1.657,2962,3.732,2965,3.91,2976,3.329,4397,1.991,7569,5.102,7629,2.398,8001,10.285,8002,5.807,8003,2.587,8004,2.398,8005,6.373,8006,2.587,8007,2.587,8008,2.587,8009,2.587,8010,2.106,8011,2.587,8012,3.732,8013,2.587,8014,2.587,8015,2.587,8016,2.587,8017,2.587,8018,2.587,8019,2.587,8020,2.587,8021,2.587,8022,2.587,8023,2.274,8024,2.587,8025,2.587,8026,2.587,8027,2.587,8028,2.587,8029,2.587,8030,2.587,8031,2.274,8032,2.587]],["t/1959",[5,1.217,7,2.5,12,1.826,21,1.633,30,2.449,73,1.691,83,1.122,96,2.237,97,3.325,117,1.074,139,1.671,155,5.011,172,1.92,177,3.792,180,3.149,219,1.875,243,2.152,245,3.845,259,1.072,267,2.032,391,1.622,438,3.986,443,2.383,468,6.716,496,3.086,520,2.943,526,4.276,528,4.708,612,1.66,641,3.783,660,4.193,670,2.538,778,4.272,781,2.479,877,4.643,923,1.493,953,2.462,978,1.794,980,2.473,1109,3.639,1159,2.962,1170,2.422,1204,3.387,1252,3.684,1599,2.347,1723,4.718,1793,4.49,1875,4.626,1919,5.08,1921,4.758,1949,5.937,1950,10.073,1951,6.555,1957,5.312,2243,4.373,2467,4.931,2573,3.895,3694,6.555,7608,4.994,8031,7.29,8033,5.683,8034,8.297,8035,4.994]],["t/1961",[3082,6.664]],["t/1963",[1,1.866,20,4.597,47,2.744,106,3.706,139,2.245,196,2.283,208,3.614,224,3.706,229,2.603,259,1.44,267,1.87,336,6.213,391,2.179,398,4.232,414,2.07,488,3.874,560,3.336,562,4.164,575,3.128,587,5.738,597,3.933,651,6.789,694,3.727,775,2.986,781,1.931,875,2.46,1008,3.164,1024,3.456,1176,5.874,1205,4.64,1253,3.904,1701,5.232,1732,5.184,1813,5.849,1843,5.154,1847,5.616,2031,6.213,2462,5.738,2493,6.031,2853,3.904,3148,5.874,3675,7.357,4584,5.232,7502,6.707,8036,7.634,8037,7.357,8038,9.453]],["t/1965",[1813,6.556,8037,8.247,8039,11.433,8040,10.045]],["t/1967",[138,3.557,597,4.445,652,5.452]],["t/1970",[1,2.008,3,4.421,4,3.432,5,1.76,38,3.017,126,3.212,145,4.634,214,4.403,240,2.704,259,1.549,287,2.223,350,4.711,398,3.027,501,5.03,527,2.733,585,5.139,665,5.03,792,7.228,809,2.675,1034,6.49,1055,3.095,1065,6.49,1081,5.819,1213,4.597,1260,5.139,1278,4.338,1418,5.113,1546,5.26,1576,7.614,1711,4.634,1816,3.575,2145,4.634,2184,6.923,2304,3.669,2313,4.752,4579,6.923,8041,9.923,8042,6.923,8043,7.614,8044,8.215,8045,7.219]],["t/1972",[1,2.046,2,2.367,3,2.376,5,2.114,7,2.764,33,1.888,42,5.738,43,2.002,83,2.14,117,1.082,126,2.249,166,2.889,172,1.331,187,2.712,210,3.265,229,1.962,240,1.9,258,2.196,296,1.521,297,3.811,304,3.219,397,3.357,411,2.508,421,2.16,425,3.299,468,3.943,504,3.147,521,2.482,527,3.283,528,2.764,531,5.717,532,3.56,557,2.126,579,2.126,586,2.581,622,4.421,623,3.452,626,2.204,668,2.147,764,2.442,768,3.272,781,1.455,822,2.306,987,3.526,1052,5.36,1062,2.605,1065,4.545,1097,2.358,1154,4.545,1162,3.327,1205,2.617,1301,5.055,1302,4.975,1344,3.194,1398,2.778,1403,3.778,1418,2.331,1579,3.729,1825,3.357,1828,4.15,1829,2.367,1918,2.979,1926,3.08,2183,4.233,2460,4.683,2723,2.96,2900,3.683,2971,3.884,3076,4.006,3589,4.233,3710,4.545,3905,3.64,4394,7.417,6909,4.683,8046,8.671,8047,7.759,8048,5.332,8049,5.753,8050,6.814,8051,5.332,8052,5.332]],["t/1974",[1,2.511,5,1.653,11,3.544,25,3.971,26,3.971,83,1.524,117,0.846,136,3.447,177,3.527,194,3.884,197,3.596,210,3.399,259,1.456,297,3.621,304,4.319,339,3.495,397,4.503,402,2.997,411,2.673,412,2.632,474,3.785,502,4.426,506,4.16,527,2.567,531,3.831,579,2.852,584,3.578,593,5.137,597,2.976,600,4.544,732,2.43,734,5.578,768,4.389,834,2.88,991,3.387,1104,5.289,1266,4.775,1312,4.828,1398,3.727,1418,3.127,1914,5.13,1918,3.996,1950,5.567,2006,4.674,2171,3.289,2440,3.33,4589,6.504,8046,6.781,8050,6.282,8053,7.718]],["t/1976",[5,1.681,10,2.855,11,3.583,30,2.126,38,2.882,106,5.654,107,5.773,168,2.618,196,2.346,210,3.853,259,1.48,297,3.792,391,2.965,411,1.816,421,2.947,463,3.543,510,2.292,526,2.928,527,4.124,562,3.204,576,2.535,597,4.006,623,4.709,768,4.462,952,5.773,1052,5.024,1071,4.09,1116,6.895,1203,5.813,1213,4.391,1669,6.2,1722,3.621,2134,5.223,2183,7.643,2469,5.223,6654,6.387,8043,7.273,8046,6.895,8047,7.273,8054,7.847,8055,5.024,8056,7.847]],["t/1978",[1,1.716,5,2.747,16,5.393,83,1.903,106,3.409,115,2.422,117,0.77,168,2.342,179,4.134,204,4.974,210,3.919,229,2.395,258,2.681,296,2.547,297,2.835,419,3.209,463,2.395,510,2.815,511,4.384,527,4.13,530,3.082,557,2.595,574,4.299,586,3.15,768,3.993,991,3.082,1015,3.466,1029,3.993,1104,4.812,1162,4.061,1169,4.061,1203,3.929,1277,5.09,1327,3.929,1420,6.17,1669,5.547,1784,6.508,1827,5.403,1918,3.636,1966,3.547,1973,7.845,2054,6.508,2441,6.508,2496,4.611,2790,5.841,2872,4.392,8057,9.358,8058,8.469,8059,7.022,8060,6.17,8061,6.508,8062,5.065,8063,8.122,8064,6.508,8065,7.022]],["t/1980",[2,3.524,5,2.603,30,1.753,73,2.549,117,0.939,179,5.044,216,4.465,296,3.389,297,3.235,414,2.323,419,3.915,511,3.897,574,5.245,594,5.245,607,3.016,731,6.6,771,6.068,785,4.408,957,3.249,985,2.568,991,3.76,1037,5.192,1104,5.872,1211,3.607,1380,5.784,1722,3.953,2790,6.666,3117,9.599,3509,7.219,3592,7.528,8057,6.768,8063,9.27,8066,8.567]],["t/1982",[5,2.479,7,1.321,10,1.884,11,2.672,14,2.753,15,2.601,22,1.971,25,2.665,30,1.585,43,3.229,44,1.65,72,2.536,76,2.515,83,1.53,106,2.515,117,1.129,136,2.313,138,1.598,145,2.921,172,1.198,183,2.735,187,1.678,197,3.609,210,2.563,214,2.703,236,3.204,240,1.176,250,2.076,259,1.461,297,3.243,397,5.415,402,2.011,411,1.198,412,1.766,421,1.945,445,2.812,457,3.476,488,1.747,490,2.13,491,2.216,497,3.316,515,4.092,527,1.723,528,4.458,542,3.447,571,2.557,576,1.673,585,3.24,593,5.156,597,1.997,600,4.561,610,2.571,612,1.513,654,2.099,787,2.172,809,1.686,867,1.598,871,2.876,953,2.244,955,2.189,978,1.635,1033,3.914,1037,3.138,1055,1.951,1097,2.122,1115,3.049,1180,2.854,1203,4.335,1211,2.181,1227,3.24,1249,2.717,1253,2.648,1283,2.898,1311,3.893,1398,2.501,1446,3.138,1455,2.945,1555,3.985,1732,2.632,1792,3.24,1807,2.501,1816,2.254,1830,2.792,1918,4.011,1958,2.812,2195,3.607,2320,3.607,2440,2.235,2880,4.551,3236,3.277,3295,4.551,3319,3.277,4394,5.823,5282,4.216,7908,4.216,8050,4.216,8057,8.137,8058,8.154,8060,4.551,8067,5.179,8068,5.179,8069,4.092,8070,7.554,8071,7.18,8072,4.8,8073,7.18,8074,4.092,8075,4.216]],["t/1984",[5,2.479,7,1.486,10,2.119,11,2.009,14,3.097,15,2.926,22,2.216,25,2.997,30,1.729,43,3.458,44,1.767,72,1.907,106,2.828,117,1.195,145,3.285,172,1.348,197,3.936,210,2.795,214,2.947,236,3.604,259,1.593,297,2.923,397,4.929,402,2.262,411,1.348,412,1.987,421,2.187,445,3.163,457,2.614,490,2.396,491,2.493,497,3.729,527,1.938,528,4.774,542,3.877,571,2.875,585,3.644,593,3.877,597,2.246,600,4.974,612,1.701,654,2.36,787,2.443,809,1.897,867,1.798,871,3.234,953,2.524,955,2.462,978,1.839,1033,2.943,1037,3.53,1097,2.387,1115,3.43,1180,3.21,1203,4.727,1211,2.453,1227,3.644,1249,3.056,1253,2.979,1311,4.378,1398,2.813,1446,3.53,1455,3.312,1555,4.482,1792,3.644,1807,2.813,1816,2.535,1830,3.14,1918,3.016,1958,3.163,2195,4.056,2320,4.056,2440,2.513,2880,5.118,3236,3.685,3295,5.118,3319,3.685,4394,6.349,7908,4.741,8050,4.741,8057,8.612,8058,8.733,8060,5.118,8070,8.09,8071,7.829,8072,5.399,8073,7.829,8074,4.602,8075,4.741]],["t/1986",[1,2.508,7,2.617,30,2.1,118,3.828,210,3.395,414,2.783,463,3.499,524,5.987,641,6.829,802,3.549,814,3.46,1009,3.655,1962,6.829,2263,4.712,2452,5.741,2453,5.884,2770,4.409,7918,8.646]],["t/1988",[91,3.13,122,4.765,186,4.379,190,3.349,193,4.517,194,2.564,198,3.349,210,3.862,240,2.453,411,2.501,414,1.84,463,3.21,474,2.499,487,4.3,639,3.513,697,3.192,731,4.07,732,2.136,753,2.812,765,5.22,801,4.197,802,2.347,814,4.543,816,4.412,832,3.582,987,2.423,1009,2.416,1030,3.535,1120,3.683,1322,4.991,1723,3.858,1819,3.657,1914,3.387,1953,4.244,1962,4.515,1966,4.755,1974,3.448,2075,4.727,2345,5.099,2353,4.97,2456,5.703,2619,5.219,2770,5.016,3511,4.905,3651,5.522,5473,5.887,7919,6.287,7920,5.961]],["t/1990",[1,2.799,7,2.92,33,2.995,117,1,118,3.405,122,4.674,186,3.698,193,3.362,210,3.788,406,4.53,463,3.112,487,3.631,606,5.373,679,4.61,781,2.308,802,4.539,816,4.674,1249,4.786,1607,3.631,1751,5.232,1828,6.582,2233,5.586,2380,4.251,2469,6.073,3501,6.463,7918,7.689,7921,7.689]],["t/1992",[7,2.343,122,3.75,186,5.329,190,4.534,193,3.384,210,3.039,414,2.491,579,3.394,753,3.807,756,4.344,802,3.177,814,3.098,816,3.75,908,3.394,923,3.019,1072,4.64,1349,5.18,1398,4.436,1607,3.655,1830,4.951,1962,6.113,2075,4.613,2263,4.218,2353,4.85,2453,5.267,2619,4.436,2770,3.946,3511,4.787,5473,5.745,5550,6.757]],["t/1994",[7,1.544,30,1.238,83,1.714,97,1.867,117,1.113,146,4.555,148,1.544,154,4.214,177,2.766,186,2.452,188,3.039,190,2.987,193,3.199,196,1.809,210,2.002,213,2.611,214,2.111,216,3.154,224,2.938,240,1.971,276,4.93,297,2.554,398,3.199,414,3.558,454,3.829,463,2.961,482,3.286,487,3.455,489,2.896,497,3.874,521,2.611,552,3.004,609,4.147,623,3.631,660,2.589,732,1.905,737,2.753,753,4.209,764,2.568,801,3.744,802,2.093,814,3.742,832,3.195,867,1.867,908,2.236,964,4.859,978,1.91,1033,3.057,1179,4.452,1218,3.174,1368,4.286,1386,3.705,1723,3.441,1732,3.076,1774,3.829,1954,3.133,1961,2.938,2006,2.753,2075,5.9,2130,3.973,2263,5.917,2313,3.5,2353,4.585,2380,2.819,2453,3.47,2931,4.657,3337,2.954,3498,4.286,5473,5.431,7922,4.365,7923,4.548,7924,5.099,7925,4.548]],["t/1996",[30,2.331,73,1.908,83,2.07,117,1.248,122,3.693,136,2.864,138,1.979,146,4.746,156,1.558,177,2.93,178,4.369,186,2.598,193,3.862,196,1.917,229,2.186,297,2.661,398,2.362,414,3.547,474,2.362,483,2.439,487,2.551,579,2.369,609,4.394,612,2.642,615,3.312,663,2.778,697,3.017,785,3.299,802,2.218,814,3.841,816,3.693,908,2.369,964,3.587,978,2.856,1009,3.222,1033,4.571,1170,2.732,1177,2.127,1607,2.551,1722,2.958,1962,6.978,1974,4.598,2171,3.856,2182,3.676,2263,4.814,2350,3.967,2353,4.777,2380,2.987,2453,3.676,2456,3.885,2770,4.505,3337,4.417,7926,7.624,7927,5.942,7928,5.218,7929,4.625,7930,5.942,7931,4.465,7932,4.819]],["t/1998",[7,1.714,30,2.379,85,2.644,117,1.274,137,2.743,138,2.885,187,2.176,218,2.344,240,1.525,267,1.646,297,2.749,320,3.596,398,3.444,414,2.535,473,1.976,474,2.475,487,2.673,511,3.056,586,3.014,693,3.92,697,3.162,732,2.944,753,3.875,796,3.211,802,2.324,814,4.377,908,2.483,923,1.764,964,3.759,998,1.971,1008,2.785,1142,4.472,1211,2.829,1264,5.469,1279,3.853,1418,2.722,1636,5.05,1961,3.262,1966,3.394,2003,4.536,2075,6.354,2182,3.853,2263,6.372,2353,4.937,2452,6.016,2619,4.515,3337,3.28,3498,4.759,5473,5.848,6863,5.469]],["t/2000",[30,2.704,83,2.493,117,1.271,136,4.157,177,4.253,194,3.518,297,2.737,615,4.244,814,4.258,923,2.444,2263,6.365,2619,4.494,3137,7.715,3306,6.378,3337,4.543,7933,8.072]],["t/2002",[9,7.647,30,2.75,83,2.122,85,2.337,90,3.035,95,3.124,117,1.309,136,3.691,194,3.124,262,3.85,531,5.335,615,3.025,814,4.533,867,2.55,923,2.17,957,3.134,1345,5.755,1974,5.462,2233,5.059,2263,6.284,3137,7.153,3306,5.664,4630,5.961,7128,6.08,7933,7.484,7934,7.659]],["t/2004",[85,2.547,117,0.987,146,4.725,193,3.318,262,4.197,276,4.373,398,4.184,414,3.373,463,3.072,487,4.519,697,4.239,814,3.038,867,2.78,875,2.902,964,5.04,998,2.643,1418,3.65,1722,4.156,1926,4.822,2263,6.313,2353,5.997,2619,5.485,3137,5.995,3306,6.173,3498,6.38,4510,5.839]],["t/2006",[30,1.624,83,1.567,91,4.829,117,1.284,122,3.24,146,5.49,178,3.833,186,3.216,193,2.924,224,3.853,262,3.698,398,2.924,414,3.675,463,2.707,487,3.158,643,5.839,649,3.483,697,4.925,814,4.365,816,3.24,964,4.441,998,2.329,1170,4.991,1331,3.204,1607,3.158,1966,4.01,1974,4.034,2239,4.91,2263,5.717,2353,5.527,2453,4.551,2986,6.973,3337,3.874,7929,5.725,7931,5.527,7932,5.965,7933,5.527]],["t/2008",[9,5.115,17,2.38,30,2.609,83,2.216,85,1.527,90,1.983,91,2.491,117,1.288,122,2.204,126,2.111,146,4.191,186,2.188,193,1.989,213,2.329,219,1.781,250,2.164,262,3.723,264,2.515,268,4.662,276,3.879,398,1.989,414,3.297,463,1.841,487,2.148,531,3.966,557,1.995,595,3.593,643,3.972,697,2.54,814,4.7,816,2.204,957,3.03,964,3.021,998,1.584,1055,2.034,1170,4.053,1179,3.972,1331,3.226,1345,3.759,1352,5.246,1607,3.179,1713,4.265,1966,2.727,1974,4.061,2233,3.305,2239,4.943,2263,5.395,2305,4.37,2316,4.287,2353,4.219,2453,3.096,2456,7.726,2579,8.557,2619,2.607,4630,3.894,7128,3.972,7929,3.894,7931,3.759,7932,4.058,7933,3.759,7935,5.004,7936,8.816,7937,8.816]],["t/2010",[83,2.262,85,2.147,94,2.561,117,0.832,123,2.337,146,6.009,148,1.937,177,3.47,186,3.076,190,6.724,267,1.86,276,3.686,297,2.989,454,4.804,488,3.427,510,2.217,615,2.78,679,3.836,732,2.39,760,3.667,795,6.398,797,5.998,867,2.343,888,4.215,923,1.994,954,5.477,955,3.21,1056,5.93,1115,4.47,1431,3.555,1678,3.813,1715,3.076,1723,4.317,1840,5.842,2300,4.248,2452,4.248,3337,3.706,3809,5.477,4085,5.477,5473,7.652,7924,6.398,7938,8.564,7939,7.037,7940,7.037,7941,6.398,7942,6.398,7943,8.029]],["t/2012",[30,1.708,38,2.104,83,2.136,85,1.62,86,1.742,97,1.768,117,1.079,138,1.768,169,2.606,170,3.089,186,3.382,188,4.945,190,5.676,196,2.496,216,2.986,224,2.782,297,2.455,414,3.254,463,1.954,489,1.911,491,2.452,538,1.818,546,3.343,575,2.348,609,3.927,619,3.797,630,3.134,654,3.382,712,3.067,732,1.804,753,5.135,764,3.543,802,1.982,814,4.366,867,2.576,908,2.117,953,2.483,955,2.422,964,3.206,1072,2.895,1465,4.438,1596,2.117,1647,3.343,1722,2.644,1776,2.986,1873,5.481,1904,2.895,1961,2.782,2006,3.797,2061,4.133,2075,6.222,2263,2.631,2453,3.286,3208,3.762,3337,4.806,3873,3.714,5473,7.192,7922,7.102,7923,4.306,7925,4.306,7928,4.664,7933,3.99,7944,4.058,7945,5.311,7946,7.736,7947,5.311,7948,4.828,7949,4.664,7950,4.828]],["t/2014",[21,3.156,210,3.634,491,4.7,756,5.195,908,4.059,923,2.885,2249,8.678,2263,5.044,2452,6.147]],["t/2016",[30,1.799,44,1.095,73,1.832,83,2.025,85,2.9,89,3.593,117,1.124,148,2.243,156,2.492,163,2.927,186,2.495,190,6.802,210,2.037,214,2.149,219,2.032,224,2.99,263,1.915,297,1.811,491,2.635,510,2.568,533,4.157,570,4.098,584,2.855,617,3.252,621,1.798,666,2.543,682,5.189,697,2.898,732,2.768,824,5.012,862,3.942,888,4.881,891,3.006,1056,3.593,1082,3.695,1091,3.446,1115,5.176,1218,3.23,1279,5.041,1308,3.111,1385,4.442,1421,3.006,1431,2.883,1465,3.963,1471,3.057,1723,4.999,1840,6.766,1961,2.99,2010,3.852,2263,2.828,2300,3.446,2350,3.81,2363,5.699,2380,2.869,2452,6.258,2468,3.296,3306,4.22,3542,9.01,3809,6.342,3855,4.442,5473,6.414,5550,4.53,6655,5.411,7951,5.707,7952,5.707,7953,5.707,7954,8.149,7955,5.012,7956,5.012]],["t/2018",[30,1.775,83,1.713,85,2.453,117,0.951,148,2.828,164,3.541,196,3.315,239,4.102,243,2.249,414,3.61,557,3.205,615,4.059,740,5.612,748,3.322,814,2.925,831,4.234,867,3.422,957,3.289,1160,5.944,1279,6.358,1386,5.31,1647,5.061,2263,5.612,2452,4.853,2468,4.643,2770,4.764,7929,6.256,7957,7.309,7958,7.309]],["t/2020",[30,2.065,44,2.025,83,1.483,85,2.124,117,0.823,148,1.916,164,3.066,172,1.738,190,6.273,218,2.621,219,2.478,264,3.499,414,3.548,491,3.214,615,2.75,621,2.193,814,2.533,889,5.526,908,2.776,923,1.973,953,3.254,1056,4.382,1134,4.932,1159,3.914,1279,4.307,1370,4.382,1465,4.547,1678,3.772,1723,4.271,1790,3.417,1961,3.647,2006,4.59,2075,3.772,2263,3.449,2316,5.49,2350,7.049,2452,6.375,2877,5.934,3337,3.667,4341,4.932,7929,5.418,7943,5.934,7958,6.329,7959,6.961,7960,6.961,7961,6.961,7962,6.961]],["t/2022",[30,2.178,44,1.892,83,2.102,117,1.011,126,3.607,164,4.345,178,3.184,188,3.311,198,4.554,214,2.3,224,3.201,258,2.517,267,1.615,276,3.201,402,2.56,414,3.677,489,2.199,510,1.925,562,2.691,619,2.999,732,3.351,809,2.147,814,4.622,867,2.034,1008,2.733,1160,4.518,1170,2.809,1279,3.78,1399,4.504,1471,3.273,1647,3.846,2006,2.999,2075,6.094,2263,3.027,2300,3.689,2380,3.071,2452,6.451,2978,5.073,3511,3.436,4662,4.955,5896,4.518,7923,4.955,7925,8,7957,5.555,7963,5.555,7964,8.551,7965,8.551,7966,8.551,7967,6.11]],["t/2024",[6,1.65,9,3.432,21,0.933,30,2.348,42,3.674,44,1.217,50,2.132,83,1.737,85,0.918,90,3.479,95,1.227,117,1.038,126,2.096,136,1.45,145,1.831,156,1.931,175,1.552,177,1.484,178,1.568,194,1.227,198,1.603,214,3.497,219,3.457,239,2.536,240,1.804,243,1.39,267,0.795,276,3.324,297,0.955,463,1.107,510,0.948,557,1.2,562,1.326,575,2.197,576,1.049,578,2.954,595,2.161,612,0.948,615,1.963,619,2.439,641,2.161,712,2.87,731,3.217,732,3.69,744,2.85,760,3.307,787,1.362,802,1.854,814,4.759,867,1.002,914,1.407,923,0.853,953,2.967,978,1.692,991,1.425,998,2.332,1109,2.079,1120,1.763,1189,2.192,1211,1.367,1279,3.926,1352,2.132,1399,3.88,1418,1.316,1471,1.612,1477,2.776,1596,2.53,1678,1.631,1723,3.894,1772,1.66,1776,2.794,1791,1.621,1862,2.44,1878,4.192,1954,1.681,2003,2.192,2075,3.439,2239,3.317,2263,6.275,2300,1.817,2380,1.513,2452,7.3,2453,1.862,2619,4.84,2690,5.146,2830,4.029,3249,2.499,3337,1.585,3510,2.565,4376,4.235,4472,2.161,5896,2.225,7115,5.573,7521,2.736,7909,4.518,7933,2.261,7968,6.346,7969,7.73,7970,3.009,7971,4.969,7972,4.711,7973,6.346,7974,3.009,7975,3.009,7976,3.009]],["t/2027",[26,3.907,30,2.08,83,1.499,117,0.832,122,4.677,178,4.908,193,4.507,198,3.748,297,2.233,414,3.106,489,2.533,531,3.769,579,2.806,595,5.053,612,2.217,697,4.782,756,3.591,764,4.313,802,2.626,814,4.126,816,4.677,867,3.136,1009,2.704,1055,2.86,1091,4.248,1198,5.126,1277,4.009,1962,8.142,1974,5.822,2171,3.236,2350,4.698,2353,5.366,2380,4.735,2456,6.158,2770,4.367,2902,5.998,7926,8.564,7963,6.398,7977,5.842]],["t/2029",[12,1.441,44,2.096,80,3.426,81,2.452,83,2.253,85,1.268,91,2.069,117,1.048,123,1.38,146,4.455,148,2.439,169,3.157,186,1.817,187,1.452,190,2.213,229,1.529,241,2.417,250,2.782,264,3.234,267,1.098,268,2.616,414,3.282,488,1.512,489,1.495,510,1.309,578,2.47,619,2.039,627,1.951,663,3.007,666,1.851,712,3.716,731,2.69,740,3.187,753,4.534,764,1.903,797,3.542,801,4.295,802,1.551,814,2.864,817,2.4,832,2.367,923,1.177,953,1.942,955,2.934,964,2.509,1011,3.617,1015,2.213,1110,2.837,1160,3.073,1182,4.757,1198,5.734,1261,3.073,1307,2.434,1370,2.616,1477,2.321,1484,3.542,1596,2.565,1599,1.851,1753,2.226,1776,3.617,1961,2.177,2006,3.157,2018,2.226,2075,6.576,2076,7.783,2245,3.939,2300,2.509,2313,2.593,2321,2.87,2353,2.367,2380,2.089,2440,2.995,2456,2.717,2553,3.176,2662,2.529,3208,5.577,4085,3.234,4689,2.571,5473,2.804,5896,3.073,7124,3.778,7130,3.542,7922,6.898,7923,5.217,7925,5.217,7938,5.849,7941,3.778,7942,3.778,7943,5.484,7948,5.849,7949,3.649,7950,5.849,7978,8.863,7979,6.433,7980,4.155,7981,4.155,7982,4.155,7983,4.155,7984,4.155,7985,6.433,7986,4.155,7987,6.433,7988,6.433,7989,4.155,7990,4.155,7991,4.155,7992,4.155]],["t/2031",[5,1.835,11,4.422,22,3.26,43,2.98,83,1.692,87,2.938,115,2.955,117,0.939,153,4.832,196,2.562,210,3.64,250,3.434,259,1.616,296,2.907,297,2.52,509,6.303,527,2.85,530,3.76,555,3.107,607,2.349,659,3.292,822,3.434,1033,4.328,1134,5.625,1398,4.137,1519,4.832,1895,5.872,1926,4.586,1961,4.16,1987,4.913,2383,8.765,2790,5.192,3319,5.42,8057,8.69,8076,8.567,8077,7.94,8078,8.567]],["t/2033",[1,1.598,5,1.4,30,0.85,41,1.871,44,2.101,48,1.612,72,2.14,73,1.235,77,2.287,83,1.291,115,2.255,126,1.623,138,2.017,153,2.341,156,3.356,183,2.192,190,3.227,208,2.383,210,3.034,228,3.602,250,1.664,259,1.233,296,1.097,299,2.803,408,4.56,418,6.075,427,2.049,439,3.648,440,3.848,527,1.381,580,2.994,611,1.741,620,1.906,753,1.721,840,3.524,845,3.379,980,3.518,993,3.118,1004,2.049,1170,1.769,1204,1.695,1277,3.451,1640,1.854,1715,1.682,1921,2.38,1925,4.809,1943,2.422,1987,7.762,2174,3.533,2355,2.136,2356,2.11,2376,9.349,2380,5.351,2383,8.285,2674,2.207,2751,4.76,2859,3.498,2881,2.62,3319,2.626,3481,3.194,3905,2.626,4381,3.379,4383,3.379,8057,6.387,8077,3.848,8079,4.151,8080,7.493,8081,6.813,8082,4.151,8083,4.151,8084,4.151,8085,6.536,8086,4.151,8087,4.151,8088,6.536,8089,6.536,8090,6.536,8091,4.151,8092,4.151,8093,9.171,8094,6.536,8095,4.151,8096,4.151,8097,4.151,8098,4.151,8099,6.536,8100,4.151,8101,4.151,8102,4.151,8103,4.151,8104,4.151,8105,4.151,8106,3.648,8107,4.151,8108,4.151,8109,4.151]],["t/2035",[5,2.198,18,6.927,21,2.948,90,3.768,117,1.125,208,3.025,228,5.654,259,1.935,287,2.777,489,3.423,610,5.094,796,4.903,923,2.695,1211,4.32,1557,8.106,2838,7.268,4502,6.737,5498,5.184]],["t/2037",[7,2.133,10,3.043,83,1.651,117,0.917,118,3.12,139,2.459,172,1.935,226,3.896,240,1.898,258,3.192,259,2.043,287,2.931,351,4.508,411,3.045,438,4.017,443,5.519,528,5.203,553,4.446,555,3.033,626,3.203,629,4.152,641,5.566,781,2.116,867,2.581,980,3.639,1125,3.955,1127,5.291,1214,4.358,1398,4.039,1418,4.389,1519,4.717,1958,4.54,1987,4.795,3098,5.018,3345,5.12,3715,7.812]],["t/2039",[7,2.785,83,1.884,117,1.046,138,2.944,156,2.86,211,2.556,214,3.329,218,2.414,226,4.445,228,6.017,259,2.059,287,1.872,398,2.548,411,2.857,438,3.323,443,5.59,510,2.02,513,3.812,528,3.323,544,4.791,626,3.654,630,3.783,781,1.75,786,3.703,796,3.306,820,2.471,831,3.377,878,4.484,890,3.207,892,3.582,923,1.817,991,3.036,997,2.464,1008,2.867,1015,3.415,1019,5.063,1055,2.606,1257,4.604,1286,3.653,1465,3.118,1617,4.111,1715,2.803,1740,5.829,1987,3.967,2052,5.631,2062,3.023,2168,5.089,2925,5.465,8110,6.078,8111,6.412,8112,5.829,8113,6.412,8114,4.9,8115,6.918,8116,6.918]],["t/2041",[11,2.902,26,4.329,83,1.661,117,0.922,153,4.745,187,2.725,297,2.474,398,4.438,411,2.516,438,4.041,443,3.528,510,2.457,552,5.98,607,2.306,626,3.222,759,3.863,760,4.063,781,3.047,873,5.63,908,3.109,923,2.209,955,3.556,993,3.244,1028,5.279,1055,3.169,1146,4.413,1385,6.069,1421,4.107,1431,3.939,1607,4.793,1613,7.451,1697,6.189,2233,5.15,2453,6.234,3715,6.069]],["t/2043",[30,1.452,41,3.197,117,0.778,123,2.183,138,2.189,148,2.475,164,2.896,203,3.126,214,3.86,240,1.61,259,1.338,267,1.737,287,2.994,297,2.854,391,2.024,398,2.613,411,2.56,438,4.662,443,2.975,462,4.067,463,3.31,473,2.086,474,2.613,510,2.071,607,1.945,611,4.07,617,5.125,626,2.717,660,3.035,762,4.861,769,4.138,867,2.189,908,2.621,912,3.338,953,3.073,987,2.534,1002,4.721,1008,2.94,1028,4.712,1146,6.535,1203,6.656,1204,2.896,1471,3.521,1607,2.822,1615,3.696,1816,3.086,1914,3.541,2181,4.721,2300,3.969,2490,4.215,3337,3.463,3345,4.342,5554,5.977,8117,7.294,8118,7.093,8119,7.093,8120,7.093,8121,7.093]],["t/2045",[30,2.507,71,6.603,83,2.011,117,1.117,214,4.274,267,2.495,411,2.835,438,5.885,615,3.729,626,5.032,760,4.919,923,2.675,1204,4.158]],["t/2047",[7,1.818,10,2.594,11,2.459,97,2.2,117,0.781,137,2.91,148,1.818,172,2.254,214,2.487,217,3.989,218,2.487,226,4.538,258,3.718,259,1.837,263,2.216,287,2.635,297,2.097,411,3.052,443,5.63,452,3.199,462,4.088,470,3.398,473,2.097,489,2.378,568,3.48,611,4.084,613,3.56,626,4.566,781,1.803,820,2.547,875,3.138,923,1.872,1028,5.386,1035,4.123,1092,5.142,1146,5.819,1203,3.989,1439,4.32,1715,2.889,2469,4.745,2577,5.802,5554,9.347,5555,6.264,8122,9.739,8123,6.607,8124,6.607]],["t/2049",[12,3.503,178,5.264,228,6.005,626,4.175,908,4.028,923,2.862,993,4.203,998,3.198,1607,4.337,8125,8.871]],["t/2051",[7,2.501,12,2.315,26,3.706,30,2.45,44,1.28,83,1.422,94,2.429,117,0.79,136,3.217,138,3.441,139,2.884,156,2.71,169,3.276,198,3.555,211,2.662,214,2.513,240,1.635,258,2.749,351,3.882,411,2.58,443,5.927,454,4.557,466,4.729,473,2.118,474,2.653,489,2.402,555,3.557,579,2.662,595,4.794,609,4.936,615,3.59,630,3.939,663,3.121,768,4.095,908,2.662,955,3.045,989,4.13,1098,3.882,1170,4.179,1445,5.015,1678,3.617,1987,6.395,2072,4.202,3337,3.516,8110,6.328,8111,6.675,8112,6.069,8126,6.675]],["t/2053",[7,3.343,30,2.4,83,1.709,85,1.704,91,2.78,136,2.691,178,2.91,194,2.277,198,2.974,226,4.033,228,4.77,258,2.3,276,2.926,411,3.222,443,6.067,533,4.068,578,3.32,612,1.76,626,4.677,748,2.308,761,4.268,781,1.524,796,2.879,908,2.227,923,1.582,953,3.75,987,3.092,989,3.455,1008,4.199,1146,3.161,1214,3.14,1279,4.964,1307,3.271,1398,4.18,1415,4.068,1431,2.821,1740,5.077,1987,5.809,2031,4.904,2196,4.904,2669,4.637,2723,3.1,3715,4.346,5563,6.661,8110,5.294,8127,8.656]],["t/2055",[7,2.824,83,2.186,411,2.562,443,5.397,626,4.241,748,4.241,5563,8.52]],["t/2057",[7,3.125,83,2.011,117,1.117,214,3.554,411,3.04,443,5.51,615,3.729,626,4.692,681,4.57,867,3.143,923,2.675,1092,7.348,5563,7.839]],["t/2059",[178,5.264,411,2.951,443,4.571,626,4.175,908,4.028,923,2.862,998,3.198,1607,4.337,8125,8.871]],["t/2061",[7,3.461,30,2.363,44,1.644,83,1.825,85,2.615,172,2.139,258,3.529,411,2.139,443,5.887,607,3.165,615,4.226,1170,3.94,1398,5.575,1685,6.438,1790,4.206,2072,5.394,2316,4.167,5563,7.115,8128,8.123]],["t/2063",[1,1.929,30,2.134,44,1.403,83,1.558,85,2.949,139,4.04,172,1.826,210,3.45,228,4.348,258,3.013,411,1.826,443,5.676,463,2.691,510,2.305,520,4.086,602,4.937,607,2.859,615,3.817,681,3.541,814,2.661,955,3.336,1009,2.811,1066,3.896,1097,3.234,1170,3.363,1368,5.59,1398,5.036,1471,3.918,1685,5.496,1790,3.59,2072,4.605,2300,4.416,2316,5.263,2627,7.314,2885,5.693,3686,7.314,3805,5.806,8128,6.934]],["t/2065",[7,3.412,30,2.174,44,1.444,83,2.338,85,2.297,172,1.879,247,7.135,258,3.1,411,2.459,443,5.715,555,5.187,607,2.913,615,3.89,681,4.767,748,3.11,1170,3.461,1398,5.131,1618,3.243,1685,5.655,1790,3.694,2072,4.738,2316,3.66,5842,7.526,8128,7.135]],["t/2067",[7,3.336,10,1.708,44,0.834,83,2.362,139,3.799,172,1.086,226,6.018,228,3.962,240,1.632,258,2.745,297,1.38,398,1.729,411,2.838,438,3.454,443,5.642,470,1.438,552,2.33,555,4.743,576,1.516,586,2.106,606,2.763,607,1.287,623,2.816,626,5.457,681,4.395,739,2.844,748,3.752,761,3.324,781,2.211,834,1.751,874,2.548,886,2.606,891,2.291,906,2.343,998,1.377,1008,1.945,1019,2.176,1028,2.279,1055,1.768,1091,2.626,1092,7.619,1421,3.51,1607,1.868,1711,5.525,1715,2.914,1740,3.955,1816,2.042,1914,2.343,1947,3.217,2233,2.873,2723,2.415,2853,2.4,3873,3.042,8069,3.708,8129,4.35]],["t/2069",[44,1.666,240,2.642,297,2.755,398,3.451,411,2.168,438,5.591,470,2.87,552,4.651,586,4.204,606,5.516,607,2.569,781,3.204,834,3.496,906,4.678,998,2.749,1008,3.883,1028,4.549,1091,5.242,1607,3.728,1715,3.796,1816,4.077,1947,6.421,2233,5.736,2723,4.821,2853,4.791,3873,6.073,8129,8.683]],["t/2071",[32,8.963,117,1.135,139,3.044,148,1.991,172,1.806,183,4.121,196,2.333,218,2.723,391,2.227,427,5.109,637,4.041,652,3.691,712,4.177,820,2.788,892,5.36,908,4.292,963,4.682,991,3.425,1056,4.553,1349,4.402,1419,5.629,1596,4.292,1615,4.067,1624,6.005,1816,3.396,1862,5.865,1961,3.789,2355,4.015,2496,5.124,2510,9.094,3463,7.466,4476,5.269,4969,8.177,8130,9.942,8131,7.804,8132,10.35,8133,10.35,8134,6.005,8135,6.352]],["t/2073",[106,5.056,117,1.142,336,8.476,510,3.041,579,4.587,597,4.787,867,3.214,923,2.735,969,5.199,978,3.918,1732,5.293,1813,5.971,7115,8.476]],["t/2075",[3,3.068,117,1.098,165,3.206,168,3.341,208,2.191,219,2.452,224,3.608,263,2.31,276,4.864,287,2.011,401,3.777,524,4.336,526,2.773,552,3.689,560,3.247,571,3.668,597,3.863,599,4.758,629,4.973,688,5.264,740,4.6,756,3.515,809,2.42,822,2.978,831,3.628,875,2.394,1069,3.824,1393,4.702,1439,4.503,1443,3.129,1712,6.584,1727,3.557,1844,4.55,1904,3.754,1988,3.667,2157,4.454,2204,5.361,2260,5.8,2565,6.888,2689,5.467,2694,6.53,2853,3.8,3657,4.946,7516,5.175,8037,9.133,8136,7.431,8137,7.431,8138,6.53,8139,7.431]],["t/2077",[20,4.648,166,3.898,213,3.348,216,5.374,224,5.007,474,2.859,483,2.953,526,2.896,541,4.612,560,3.391,599,4.969,629,3.853,648,4.126,655,5.096,734,4.213,809,2.527,817,4.154,822,3.11,831,3.789,1002,5.165,1003,6.695,1009,4.125,1025,3.875,1331,4.163,1396,4.413,1455,4.413,1546,4.969,1610,6.317,1727,2.756,1732,5.241,1799,6.43,1813,4.45,1873,5.096,1988,3.775,2182,4.45,2204,5.598,2505,6.131,2703,5.096,2853,3.969,3657,6.864,4371,6.54,4584,7.068,6460,6.819,8140,7.76,8141,6.819,8142,7.76]],["t/2079",[4,4.34,24,3.852,107,5.773,117,0.86,123,2.416,168,2.618,209,3.192,267,1.922,488,2.647,526,2.928,557,2.9,560,3.429,597,3.026,598,3.638,618,4.292,629,5.157,734,4.261,767,4.62,822,3.145,831,3.831,875,2.529,1043,5.773,1170,4.427,1209,5.898,1215,6.039,1711,4.426,1712,4.261,1813,4.5,1843,8.369,1844,4.804,1934,7.447,1952,4.62,1958,4.261,1982,5.773,1988,4.263,2007,6.613,2147,6.613,2148,6.039,2547,6.613,2703,5.153,3157,5.898,4168,5.558,8037,5.661,8126,7.273,8143,7.847,8144,6.2]],["t/2081",[24,3.918,33,3.448,43,2.777,208,3.097,219,2.634,262,3.719,288,4.577,461,4.107,474,2.94,482,4.333,506,4.303,526,2.978,541,4.743,629,3.962,781,2.019,809,2.599,822,3.199,831,3.896,1013,3.775,1032,9.558,1075,6.076,1205,4.779,1215,6.142,1386,6.432,1418,3.234,1682,7.013,1711,4.502,1712,4.333,1727,2.834,1832,6.898,1843,8.425,1952,4.699,1988,4.568,2547,6.726,2989,6.142,3250,5.999,6053,7.398,7460,7.398,8037,7.578,8145,7.981,8146,7.981,8147,7.981]],["t/2083",[5,1.635,17,4.496,24,3.747,208,3.386,219,2.519,224,3.706,241,4.115,452,3.425,483,2.905,488,3.44,597,2.944,622,5.386,629,3.79,732,2.403,809,2.486,822,3.059,831,4.979,885,4.495,987,2.727,1055,2.876,1205,5.577,1345,5.316,1418,3.093,1519,5.753,1712,4.145,1751,4.377,1799,6.378,1832,5.012,1843,5.154,1844,4.673,1926,4.086,1949,5.62,1958,5.538,1988,3.734,2467,4.537,3675,5.507,8037,8.286,8038,7.075,8141,6.707,8148,7.634,8149,7.634,8150,7.634,8151,10.199,8152,10.199,8153,7.634,8154,7.075]],["t/2085",[24,3.667,73,2.223,208,2.202,297,2.197,397,4.359,411,2.812,469,5.717,488,4.099,526,3.751,541,4.44,546,4.359,560,4.965,597,4.382,599,4.783,607,2.048,629,3.709,655,4.906,764,3.171,767,4.399,820,2.669,822,2.994,831,4.908,875,3.239,910,4.483,987,2.669,1075,6.572,1374,4.843,1401,5.345,1418,3.027,1439,4.527,1599,3.085,1732,3.797,1813,4.284,1832,4.906,1843,8.205,1844,4.574,1847,7.396,1982,7.396,1988,3.68,2136,5.902,2148,5.749,3359,4.972,8037,5.389,8155,7.471,8156,7.471,8157,7.471]],["t/2087",[72,3.359,83,2.026,211,3.792,259,1.935,271,3.78,276,4.982,427,5.065,487,4.083,489,3.423,521,4.427,560,4.484,923,2.695,998,3.011,1613,7.032,1829,4.221,2180,3.957,2959,7.402,8158,8.352]],["t/2089",[16,5.96,196,3.185,208,3.14,259,2.009,271,4.635,296,2.815,487,4.238,527,3.543,627,4.634,775,3.118,991,4.674,1640,4.757]],["t/2091",[5,2.546,72,3.891,118,4.435,259,2.242,271,4.379,296,3.142,418,5.97,527,3.954,608,7.459,923,3.122,1816,5.172,1961,5.771,4266,8.557]],["t/2093",[1,1.716,16,5.393,29,3.929,41,3.165,44,1.248,72,2.299,76,3.409,117,1.057,180,4.122,181,3.109,214,2.45,218,3.84,259,2.076,271,4.364,296,3.536,391,2.751,401,3.569,411,2.741,421,2.637,422,3.547,427,5.847,487,4.379,491,3.005,520,3.636,527,3.941,565,4.097,607,1.925,627,3.055,630,3.84,867,2.167,891,3.428,923,1.844,985,2.105,1601,4.673,1640,3.136,1727,3.423,1816,4.194,1829,2.888,2152,3.899,3306,4.812,4266,7.884,4656,5.917,6161,6.17]],["t/2096",[1,0.905,2,3.877,20,1.668,34,2.316,35,2.243,41,1.668,44,1.676,72,1.212,73,1.102,83,2.507,85,1.687,86,1.126,91,1.708,117,0.821,126,2.332,128,3.441,138,1.142,145,2.088,148,0.944,150,1.54,160,1.848,169,1.684,172,2.181,175,5.707,183,3.15,187,2.427,196,1.107,207,2.316,208,1.091,213,1.597,218,1.292,229,1.262,238,2.141,259,1.413,262,1.725,271,3.903,276,1.797,279,4.089,297,2.528,391,2.453,412,1.262,427,3.699,433,3.775,449,2.622,457,1.661,463,1.262,487,1.473,490,3.083,497,2.37,527,2.859,529,1.295,535,2.088,560,1.618,598,1.716,607,1.015,611,1.552,615,1.355,621,1.742,639,1.917,645,2.473,648,3.172,668,1.381,670,1.653,712,5.045,748,1.418,764,1.571,781,2.174,795,5.027,831,2.912,867,1.142,908,1.368,912,1.742,923,0.972,952,4.389,993,1.427,998,1.086,1009,1.318,1024,1.676,1025,2.979,1140,2.088,1151,2.123,1177,1.228,1239,2.141,1253,1.893,1273,1.447,1278,1.955,1279,2.123,1307,2.01,1401,4.569,1431,1.733,1443,1.559,1465,1.668,1552,2.342,1596,3.483,1599,1.528,1790,1.684,1816,1.611,1961,1.797,1976,5.504,1988,1.355,2027,2.37,2035,2.723,2043,2.499,2217,2.67,2284,2.67,2319,3.013,2440,2.574,2443,5.593,2508,2.537,2531,2.399,3328,3.252,3680,5.878,3749,4.155,4270,5.711,4476,4.028,8051,3.431,8134,4.591,8159,5.966,8160,5.966,8161,3.702,8162,3.702,8163,3.702,8164,3.702,8165,5.966,8166,5.966,8167,5.966,8168,3.252,8169,3.431,8170,3.702,8171,3.702,8172,4.856,8173,5.529,8174,5.242,8175,3.431,8176,3.252,8177,3.702]],["t/2098",[2,3.818,6,1.398,11,0.949,12,0.884,30,0.955,38,1.01,41,2.103,44,2.092,73,0.818,85,0.778,86,1.419,87,0.943,94,0.927,96,1.083,106,1.335,117,0.955,118,1.026,126,3.133,128,2.142,138,1.44,139,1.787,145,1.551,148,1.55,166,1.381,175,3.829,180,0.884,194,1.763,196,1.395,203,4.304,208,0.811,211,1.016,218,1.628,229,0.938,235,1.321,258,1.05,259,0.88,262,1.281,271,3.597,276,2.265,279,3.197,296,1.606,320,1.472,391,3.094,411,0.636,412,1.591,427,5.199,452,3.595,461,1.415,473,0.809,474,1.013,487,1.094,489,0.917,499,2.987,526,1.026,527,2.381,529,0.962,560,1.202,579,1.016,584,1.275,597,1.799,604,1.65,607,1.279,611,3.002,612,0.803,615,1.708,621,0.803,637,2.416,650,1.984,670,1.228,678,1.472,712,4.661,748,1.787,756,1.301,775,1.778,781,1.18,809,1.519,834,1.741,892,2.416,923,0.722,952,3.432,987,1.667,997,0.979,998,0.807,1002,4.044,1015,3.533,1024,1.245,1134,1.806,1168,1.72,1174,1.915,1175,1.806,1249,1.443,1253,1.406,1273,1.075,1279,1.577,1292,2.116,1370,1.605,1401,5.599,1431,1.288,1443,1.964,1485,1.783,1528,1.83,1596,3.892,1609,1.398,1617,1.634,1694,1.984,1727,1.657,1788,2.653,1828,1.984,1948,1.551,1954,1.424,1961,1.335,1966,1.389,1976,5.082,1988,1.007,2157,1.223,2180,5.315,2217,1.984,2234,1.915,2260,1.223,2388,3.149,2440,1.187,2443,3.373,2855,4.566,2897,3.197,3098,1.65,3374,5.379,3680,5.938,3749,3.249,4270,3.275,4476,5.41,4969,2.173,5143,2.116,6146,2.416,6147,10.049,8134,3.59,8172,3.797,8173,8.07,8175,2.549,8178,2.75,8179,6.289,8180,2.75,8181,2.75,8182,4.665,8183,4.665,8184,4.665,8185,7.157,8186,2.75,8187,2.75,8188,2.75,8189,2.067,8190,2.75,8191,4.665,8192,4.665]],["t/2100",[7,1.393,16,3.056,24,2.681,30,1.118,73,1.625,76,3.913,85,1.545,117,1.05,118,3.573,123,2.481,137,2.23,180,2.59,181,2.418,193,2.012,196,1.633,208,1.61,209,2.221,210,1.807,243,1.416,258,3.076,259,1.52,271,3.528,296,3.437,339,2.473,391,2.733,401,2.776,411,2.446,421,3.026,422,4.071,423,3.081,427,5.566,483,2.078,487,4.207,489,1.822,513,3.009,527,1.817,530,2.397,531,2.711,536,3.687,545,3.635,560,2.387,607,1.497,610,4.001,612,1.595,627,2.376,636,2.81,639,2.828,652,2.583,775,1.599,820,1.951,888,3.032,891,2.666,923,1.434,980,2.376,985,2.87,1009,1.945,1013,2.583,1208,2.496,1249,2.865,1302,3.246,1596,2.018,1623,4.315,1734,2.681,1769,3.94,1816,4.906,1829,2.247,1967,2.727,2059,2.965,2320,3.803,2434,7.778,2448,4.018,2476,3.803,3036,3.344,3126,3.94,3579,4.315,4261,3.159,4262,3.187,4266,8.511,7956,4.446,8193,5.462,8194,5.062,8195,4.602,8196,7.081,8197,5.462,8198,5.462]],["t/2102",[2355,5.931,2443,6.4,8195,9.713]],["t/2104",[5,1.98,24,4.538,30,1.892,96,3.64,117,1.013,166,4.643,296,3.051,401,4.699,414,2.507,421,3.472,422,4.671,427,4.564,489,3.084,526,3.449,527,3.076,620,5.301,637,4.787,1015,4.564,1036,5.056,1200,4.915,1273,3.614,1401,4.915,1829,3.803,2414,7.791,3345,5.66,4266,6.153,8114,6.549,8195,9.728,8199,9.245,8200,9.245]],["t/2106",[2,4.069,44,2.306,72,2.749,85,1.634,128,2.653,141,5.038,148,2.142,166,4.217,168,1.927,172,2.669,186,2.341,196,1.727,263,1.796,267,1.415,271,4.25,279,3.959,291,3.233,421,4.332,422,5.828,427,4.145,457,2.592,489,1.927,526,3.133,527,3.612,530,2.535,575,2.367,712,3.092,748,2.213,756,2.732,781,1.461,914,2.503,985,3.255,1015,2.852,1028,2.805,1401,3.071,1596,4.013,1715,2.341,1727,2.051,1829,4.069,1988,2.115,2157,3.734,2357,3.341,2443,6.029,2897,7.442,3220,4.092,3328,5.076,3680,6.336,4266,6.584,4343,4.702,8172,4.702,8195,7.076,8201,5.076,8202,5.777,8203,8.397,8204,5.777,8205,5.354,8206,5.777,8207,5.777,8208,5.777,8209,7.378,8210,5.076,8211,4.702,8212,5.777,8213,5.777,8214,5.777,8215,5.777]],["t/2108",[41,3.933,117,0.957,160,4.358,169,3.97,183,4.608,187,2.827,238,5.047,240,2.527,258,3.332,271,4.515,296,2.942,398,3.215,427,4.308,433,8.168,535,4.922,537,6.42,627,3.797,923,2.292,993,3.365,1401,4.64,1678,4.383,1976,4.358,2035,6.42,2275,3.83,3680,6.495,4270,6.001,8130,8.366,8176,7.668,8216,8.089,8217,8.089,8218,8.089,8219,8.089]],["t/2110",[5,1.432,27,3.229,73,3.192,117,0.733,148,1.706,166,3.358,172,2.156,218,2.333,267,2.627,391,1.908,427,3.301,436,4.052,437,4.524,470,2.048,529,2.34,622,3.531,646,3.32,712,3.579,892,4.825,908,3.444,923,1.756,963,7.319,978,2.941,991,2.934,1015,5.294,1402,4.012,1596,3.963,1615,4.856,1727,2.375,1829,3.833,1935,6.291,1949,3.684,2072,3.902,2154,6.007,2355,3.441,4270,3.605,4350,5.538,4574,5.146,4969,7.361,5896,4.583,8130,8.061,8134,5.146,8135,5.443,8158,5.443,8220,7.852,8221,6.687,8222,6.687,8223,9.318,8224,9.318,8225,6.687,8226,6.687,8227,6.687,8228,4.736,8229,6.687,8230,6.687,8231,6.687,8232,8.636,8233,6.687,8234,6.687,8235,6.687]],["t/2112",[72,3.596,259,2.072,489,3.664,521,4.74,998,3.223,1613,7.528,1829,4.518,2959,7.924,8158,8.941]],["t/2114",[5,2.076,47,3.484,48,3.763,116,4.494,267,2.374,271,4.736,296,2.562,315,6.005,427,4.785,539,7.889,549,6.544,627,4.218,670,4.329,820,4.246,892,5.019,1204,3.957,1347,6.283,1596,3.582,1961,4.706,2016,5.189,2275,4.254,3082,5.512]],["t/2116",[30,1.312,44,1.14,97,1.979,117,0.992,208,1.89,218,2.237,229,3.085,240,2.054,264,2.987,271,4.195,296,3.294,315,6.811,391,1.83,412,3.085,414,1.739,419,2.93,427,5.929,457,2.877,514,3.22,526,2.392,557,2.369,627,2.79,712,3.432,752,3.775,753,2.658,802,2.218,820,2.29,831,3.13,867,1.979,890,2.973,971,3.408,978,2.024,1013,3.032,1056,3.741,1072,3.239,1168,4.011,1208,2.93,1330,5.233,1332,3.13,1401,6.809,1418,2.598,1441,4.056,1596,2.369,1599,4.702,1698,3.885,1732,3.259,1819,3.456,2316,4.078,2321,4.105,2355,3.299,2510,10.006,2940,4.625,2969,5.942,4510,4.156,7697,5.942,8228,4.541,8236,6.411,8237,6.411,8238,6.411,8239,6.411,8240,5.403]],["t/2118",[30,1.196,41,1.625,44,1.863,47,1.296,72,2.771,73,2.768,81,1.972,85,1.02,91,3.906,94,1.216,102,2.472,104,4.923,113,2.104,117,0.64,121,3.169,123,1.11,124,2.143,126,1.41,136,1.611,148,0.92,149,2.849,156,2.26,177,3.869,178,1.742,187,1.168,229,2.887,239,1.706,240,2.56,250,1.445,263,1.816,271,3.667,296,3.294,297,2.489,315,6.834,316,2.309,350,4.854,391,1.029,401,2.969,418,2.934,427,4.914,433,5.884,456,2.935,457,3.303,473,1.061,474,1.329,486,1.618,492,1.425,510,1.053,520,1.867,532,2.231,535,2.034,537,2.653,552,1.79,575,1.478,615,1.32,621,1.706,627,1.569,645,1.495,648,1.917,660,3.622,679,1.822,723,2.185,732,1.135,733,2.653,763,2.282,862,2.309,867,1.113,896,1.972,908,2.159,923,0.947,1008,2.421,1022,3.343,1028,2.836,1074,2.309,1139,3.169,1141,2.849,1196,2.511,1231,1.751,1271,1.892,1277,1.904,1300,3.614,1331,1.456,1372,2.338,1401,1.917,1417,2.143,1421,1.761,1601,2.4,1647,2.104,1659,2.849,1697,2.653,1734,1.77,1777,2.338,1788,3.322,1829,1.483,1873,2.368,1909,6.373,1976,2.917,2027,2.309,2152,2.002,2197,2.368,2210,2.601,2311,5.414,2313,3.379,2316,3.318,2331,2.208,2354,3.039,2355,1.856,2388,5.715,2448,2.653,2770,1.55,2897,4.004,3337,1.761,3372,3.343,3682,4.923,3818,4.555,4476,2.435,5007,3.039,6851,2.849,8240,7.133,8241,3.606,8242,3.606,8243,3.606,8244,3.606,8245,3.606,8246,9.3,8247,3.606,8248,7.363,8249,5.841,8250,3.606,8251,3.606,8252,2.935,8253,3.606,8254,2.935,8255,3.343,8256,3.606,8257,3.606]],["t/2120",[2,3.175,117,1.266,148,1.969,166,5.801,175,5.884,196,2.308,201,3.971,240,2.622,271,2.843,296,2.04,391,2.203,398,4.255,427,5.072,463,2.632,639,3.996,652,3.65,781,1.952,820,3.67,892,5.32,908,3.797,991,3.387,1003,5.354,1160,5.289,1596,4.551,1609,3.923,1829,3.175,1961,3.747,2416,5.137,2443,4.285,2531,5.003,2906,10.705,2918,5.467,3135,5.374,4969,8.117,8134,5.939,8135,6.282,8258,10.82,8259,7.153]],["t/2122",[6,5.3,7,2.013,72,2.583,117,0.865,118,2.944,122,3.222,214,2.753,239,3.732,271,4.577,276,3.832,296,3.283,315,3.987,391,3.333,427,6.133,463,2.691,487,3.14,527,4.133,575,3.234,610,3.918,621,3.045,652,3.732,764,3.35,781,1.996,783,4.993,816,3.222,971,4.195,978,2.491,1249,4.14,1271,4.14,1441,4.993,1643,5.252,1727,2.802,1816,5.081,1829,3.246,2440,3.405,2448,8.591,2576,7.314,2577,6.423,2959,5.693]],["t/2124",[296,3.022,527,3.803,2355,5.883,2443,6.348]],["t/2126",[5,1.543,12,2.315,24,4.814,30,1.474,76,3.497,94,2.429,96,2.835,116,3.339,117,1.075,118,2.687,156,1.75,166,3.617,172,1.667,208,2.891,259,2.103,271,2.653,296,3.164,315,5.634,401,3.661,414,1.953,418,6.013,421,2.705,422,3.639,427,5.505,489,3.271,526,2.687,527,4.299,598,3.339,608,5.542,620,4.503,637,3.729,666,2.974,734,3.91,923,1.891,978,2.273,1015,3.555,1036,3.939,1055,2.713,1131,5.445,1200,3.829,1218,3.778,1273,2.816,1401,3.829,1734,3.535,1816,3.134,1829,2.963,2174,3.147,2414,6.069,2938,6.675,3345,4.409,8114,5.101,8260,7.202,8261,7.202]],["t/2128",[2,4.931,72,3.217,128,4.513,141,7.193,271,4.416,279,6.736,527,3.988,712,5.261,748,3.765,1596,3.632,1988,3.598,2443,7.182,8134,7.564,8172,8,8209,10.534,8210,8.636,8211,8]],["t/2130",[41,3.933,117,0.957,160,4.358,169,3.97,183,4.608,187,2.827,238,5.047,240,2.527,258,3.332,271,4.515,296,2.942,398,3.215,427,4.308,433,8.168,535,4.922,537,6.42,627,3.797,923,2.292,993,3.365,1401,4.64,1678,4.383,1976,4.358,2035,6.42,2275,3.83,4270,6.001,8130,8.366,8176,7.668,8216,8.089,8217,8.089,8218,8.089,8219,8.089,8228,7.885]],["t/2132",[72,3.513,259,2.024,271,3.954,391,3.063,401,5.455,427,5.298,489,3.58,923,2.819,998,3.149,1816,4.67,2440,4.631,8158,8.735]],["t/2134",[211,4.157,474,4.144,544,5.65,923,2.954,2217,8.115,8262,10.426]],["t/2136",[86,3.143,117,1.133,175,4.939,259,1.949,296,2.732,315,5.222,411,2.392,421,3.882,429,7.456,527,3.439,1055,3.894,2154,5.352,2174,4.517,2355,5.319,2385,8.413,2396,6.086,2443,5.739]],["t/2138",[2,4.228,5,2.202,21,2.954,32,4.307,72,2.887,117,0.678,128,2.84,141,5.292,148,1.578,160,3.088,186,2.506,187,2.003,190,3.053,197,2.882,218,3.91,259,1.166,271,4.128,279,4.239,290,3.408,391,2.934,402,2.401,427,4.354,472,3.96,491,2.647,527,2.934,639,3.203,652,4.862,668,2.308,712,5.999,748,2.369,781,2.231,785,3.183,892,5.803,993,2.385,1349,3.488,1393,3.913,1417,3.676,1596,4.141,1614,3.869,1615,5.357,1624,4.759,1935,4.176,1961,4.991,1988,2.264,2301,8.084,2355,5.289,2443,6.222,2531,4.009,3459,5.732,3460,5.434,3463,4.461,4270,3.334,4676,5.732,5074,5.034,8117,4.649,8130,4.649,8135,7.179,8172,5.034,8209,7.749,8210,5.434,8211,5.034,8263,6.185,8264,6.185,8265,6.185]],["t/2140",[11,2.884,30,1.711,91,4.997,94,2.82,95,3.161,118,3.12,148,3.064,169,3.804,177,3.822,196,2.5,206,4.574,243,2.169,411,1.935,483,3.182,489,2.79,525,4.152,579,3.09,620,3.84,651,5.566,652,3.955,781,3.214,809,2.723,820,3.869,840,4.508,862,5.354,957,4.107,987,2.987,1196,5.824,1685,5.824,1829,3.44,1966,4.225,2313,4.837,2976,9.028,8228,7.671,8266,8.362,8267,10.83,8268,8.362]],["t/2142",[44,1.612,96,3.569,97,2.798,165,3.912,218,3.163,229,3.092,732,2.854,781,2.885,820,3.239,834,3.383,1805,7.815,1829,3.729,4350,7.414,8228,9.272,8269,11.562,8270,8.403,8271,8.403,8272,7.64,8273,9.066,8274,9.066,8275,9.066,8276,7.966,8277,9.066,8278,9.066,8279,9.066,8280,9.066,8281,9.066]],["t/2144",[43,3.951,97,2.78,297,3.658,427,4.446,473,3.34,542,5.995,554,6.273,562,3.677,619,4.098,634,5.304,660,3.854,760,4.35,820,3.218,831,4.397,923,2.366,1003,5.919,1196,6.273,1421,4.397,1599,3.719,1730,7.116,2380,4.197,2789,5.839,2976,8.536,3504,7.915,4350,5.353,8228,6.38,8259,8.349,8269,8.349,8282,9.007,8283,11.357]],["t/2146",[87,3.324,93,4.516,94,3.269,172,2.243,196,2.898,259,1.828,271,3.571,279,6.643,391,2.766,427,4.785,652,4.584,923,2.546,957,4.508,991,5.217,1030,5.051,1055,3.652,1069,4.988,1177,3.216,1443,4.081,1609,4.927,1829,3.987,4350,5.76,8117,7.285,8228,6.866]],["t/2148",[44,1.242,85,1.976,94,2.356,150,2.907,163,4.566,165,3.015,216,6.16,219,2.305,224,3.392,338,3.392,524,4.077,620,3.208,732,2.2,775,2.812,819,5.821,957,2.65,978,2.205,1003,3.641,1025,3.489,1069,4.943,1177,3.187,1449,3.509,1552,4.42,1805,4.788,1816,3.04,2060,5.546,2275,3.066,3058,4.949,3657,4.65,3680,4.077,3797,4.077,4350,8.494,4689,4.006,8228,4.949,8271,6.476,8272,5.887,8284,9.605,8285,6.987,8286,9.605,8287,9.605,8288,9.605,8289,9.605,8290,6.987,8291,6.987,8292,6.987,8293,6.987,8294,6.987,8295,5.52,8296,6.987,8297,6.987,8298,6.987,8299,6.987]],["t/2150",[30,1.745,85,2.411,94,2.875,117,0.934,172,1.972,186,2.39,194,2.23,195,7.108,338,2.864,412,2.012,479,4.539,492,3.368,510,1.723,529,2.064,612,1.723,775,2.495,787,2.474,801,3.65,802,3.462,832,5.79,834,2.201,955,2.494,957,3.233,969,2.945,977,4.178,1177,2.828,1211,2.484,1264,8.925,1344,3.275,1404,7.02,1449,5.027,1487,5.526,1612,3.016,1613,4.043,1749,3.412,2021,6.066,2027,3.777,2032,2.945,2300,3.301,2316,5.242,2819,4.255,3680,4.974,3762,6.407,3873,3.823,4350,3.505,5880,5.467,7568,5.183,8228,6.038,8272,4.971,8300,9.277,8301,8.524,8302,5.898,8303,8.524,8304,5.898,8305,8.524,8306,5.898,8307,5.898,8308,5.898,8309,10.163,8310,9.277,8311,5.898,8312,5.898,8313,5.467,8314,7.49,8315,5.898,8316,5.898,8317,8.524,8318,5.898,8319,8.524,8320,5.898,8321,5.898]],["t/2152",[44,1.321,85,2.102,117,1.242,126,2.905,164,3.034,167,4.226,172,2.622,186,3.011,243,1.927,433,6.338,470,2.276,557,2.746,621,2.17,752,5.898,802,3.465,820,2.655,957,4.297,1003,3.873,1028,3.608,1036,4.064,1322,5.467,1612,3.8,1646,5.871,1712,4.035,1772,3.8,1790,4.557,1820,5.871,2187,5.175,2440,5.463,2466,5.175,2538,5.093,2819,5.361,2985,6.53,4270,4.006,4350,7.207,8272,6.262,8309,10.503,8310,6.888,8322,10.017,8323,10.017,8324,7.431,8325,10.017,8326,6.888,8327,7.431,8328,7.431,8329,7.431,8330,7.431,8331,7.431]],["t/2154",[16,3.044,72,2.63,85,1.539,86,2.444,87,2.756,88,3.726,96,3.164,97,2.949,106,2.642,139,1.6,150,2.264,186,2.205,209,2.213,228,5.265,240,1.824,258,2.077,259,1.99,271,4.913,279,3.729,315,4.06,391,2.293,398,4.147,401,4.084,427,5.557,474,2.004,487,3.197,489,3.755,491,2.328,513,2.998,520,2.817,521,2.347,539,6.54,544,4.036,575,3.293,610,2.701,627,3.496,637,2.817,668,2.03,787,2.282,892,2.817,908,2.011,923,2.11,998,2.358,1029,4.569,1055,3.027,1196,3.789,1214,4.188,1249,2.854,1272,3.729,1347,3.527,1401,4.272,1418,2.205,1421,3.923,1586,2.732,1816,5.444,1829,3.305,2016,2.912,2126,4.585,2217,6.892,2242,4.585,2249,6.348,2275,3.527,2301,3.925,2319,4.428,2519,3.483,2853,4.109,2959,7.612,2976,4.089,3098,3.264,3306,3.729,8158,6.54]],["t/2156",[44,1.798,214,3.528,219,3.337,297,2.974,521,4.363,575,4.144,681,4.537,745,7.391,794,7.295,892,5.236,1715,4.098,1924,4.363,1953,7.63,2218,7.782,2220,7.163,2225,9.373,2237,6.731,3506,4.579]],["t/2158",[30,1.349,72,2.158,91,3.042,128,3.027,141,3.955,148,1.681,196,1.971,201,3.392,218,3.714,240,1.496,267,1.615,271,2.429,290,6.929,320,3.529,391,1.881,402,2.56,427,4.554,491,2.821,496,3.579,529,3.228,652,3.118,670,2.944,712,6.496,748,2.525,809,2.147,820,2.355,892,4.777,908,3.41,991,2.893,1015,3.254,1056,3.846,1140,3.718,1331,2.661,1344,3.66,1401,3.505,1596,3.933,1727,2.341,1816,2.868,1817,5.366,1961,3.201,1976,5.314,2049,9.352,2355,5.932,2443,5.122,2449,3.955,2812,4.591,2900,4.221,4969,7.289,7391,5.792,8134,5.073,8135,5.366,8332,6.592,8333,10.685,8334,6.592,8335,6.592,8336,6.592,8337,6.592,8338,6.592,8339,6.592,8340,6.592,8341,10.643,8342,6.11,8343,6.592]],["t/2160",[2,4.16,85,2.86,96,3.981,165,4.363,208,2.981,214,3.528,538,3.208,627,4.4,652,4.783,830,5.9,954,8.798,1205,4.6,1218,5.305,1277,5.34,1331,4.083,1838,5.9,2249,9.636,8344,10.112]],["t/2162",[4,3.056,5,2.123,7,1.866,11,3.419,85,2.069,115,3.877,117,0.802,138,2.257,211,2.703,219,2.414,240,1.661,257,4.869,259,1.38,267,1.792,285,3.267,297,2.915,463,2.495,509,5.381,510,2.136,511,3.328,529,2.56,538,2.321,576,2.363,585,6.2,607,2.005,649,4.35,652,5.699,668,3.698,831,3.571,953,3.169,998,2.146,1009,2.605,1013,3.46,1037,4.433,1070,4.978,1090,3.631,1150,4.938,1177,2.427,1205,5.113,1256,5.277,1331,5.084,1778,3.442,1799,5.503,1805,5.013,1829,3.009,1854,5.779,1924,4.276,2182,4.195,2449,4.389,2462,5.498,8295,5.779,8345,5.277,8346,6.78]],["t/2164",[2,3.911,7,1.756,10,2.504,11,4.052,46,7.511,117,1.194,138,2.124,148,1.756,187,3.08,227,4.13,259,1.298,264,3.207,297,3.625,391,2.713,411,1.593,412,3.714,489,2.296,509,5.064,510,2.777,521,2.97,538,2.184,564,4.016,597,2.655,622,3.635,652,3.256,678,6.288,767,4.053,768,5.407,787,2.887,834,2.568,875,2.218,953,2.983,998,2.02,1009,2.452,1132,4.647,1204,2.81,1277,3.635,1331,2.779,1732,3.499,1819,5.125,1924,2.97,1967,3.437,2183,8.641,2295,3.765,2469,4.582,2490,4.091,2853,3.52,3063,5.297,6090,5.801,8048,6.38,8295,7.511,8347,6.884,8348,8.812,8349,6.884,8350,6.884,8351,6.884,8352,7.316,8353,6.38]],["t/2166",[2,4.015,11,4.117,15,4.902,46,7.711,297,3.511,461,5.022,489,3.256,607,2.676,623,5.856,652,4.616,668,3.642,821,6.689,1070,4.902,1253,4.991,1331,3.94,1489,5.12,1847,7.181,1924,4.211,1967,4.874,2211,7.944,2401,8.225,2490,5.801,8354,9.046]],["t/2168",[84,5.23,117,1.142,137,4.251,259,1.964,297,3.062,597,4.016,652,5.871,668,3.885,1205,5.647,1331,5.011,1799,5.782,1805,7.137,3063,8.013]],["t/2170",[2,4.072,11,3.414,16,5.539,44,1.76,46,7.82,461,5.093,489,3.302,568,4.832,638,6.588,652,4.682,668,3.693,834,3.693,1070,4.971,1253,5.062,1331,3.996,1799,5.496,1805,6.784,1924,4.271,8069,7.82,8354,9.174,8355,9.898,8356,9.898,8357,9.898]],["t/2172",[44,2.049,568,5.627,834,4.301]],["t/2174",[3082,6.664]],["t/2176",[5,1.17,7,2.056,11,3.889,15,2.743,26,2.81,43,1.9,106,4.65,115,1.884,117,1.293,148,1.393,160,2.727,165,2.357,203,2.407,210,2.666,229,1.863,262,3.755,297,2.37,391,2.3,408,3.081,489,3.194,510,2.353,511,2.485,525,2.711,538,1.733,544,2.743,555,1.981,560,2.387,574,3.344,582,3.009,612,1.595,621,1.595,622,2.884,624,2.727,651,3.635,652,2.583,670,2.44,759,2.508,767,3.216,792,3.687,821,3.743,838,5.062,867,1.686,890,2.532,987,1.951,991,2.397,1104,5.523,1146,2.865,1203,4.509,1213,3.056,1231,2.652,1253,2.793,1266,3.379,1268,4.203,1283,3.056,1331,2.205,1345,3.803,1364,3.497,1418,2.213,1421,2.666,1489,2.865,1553,4.018,1555,4.203,1586,4.81,1596,3.539,1636,4.105,1799,3.032,1816,3.506,1827,4.203,1829,4.349,1847,4.018,1888,8.68,1918,2.828,1921,3.132,1924,2.357,1926,2.924,2183,5.929,2401,4.602,2425,2.965,2443,3.032,2449,3.277,2469,3.635,2490,3.246,2506,3.586,2896,4.203,3503,3.869,4394,4.105,4472,3.635,6116,4.602,7351,5.062,8070,4.446,8075,4.446,8106,4.799,8295,4.315,8345,3.94,8346,5.062,8348,5.062,8358,8.876,8359,5.462,8360,5.462,8361,5.462,8362,5.462]],["t/2178",[3082,6.664]],["t/2180",[3082,6.664]],["t/2182",[3082,6.664]],["t/2184",[3082,6.664]],["t/2186",[997,4.039,1332,5.536,2026,8.343,8363,9.23,8364,9.556]],["t/2188",[5,2.048,19,4.951,21,2.747,44,1.7,115,3.298,181,4.233,208,2.818,554,6.658,571,4.72,575,3.918,584,4.433,668,3.567,729,6.772,875,3.081,997,3.405,1071,4.982,1219,7.782,1390,8.861,1443,4.026,1701,6.553,2211,7.782,2518,5.437,2872,5.981,2944,6.658,7001,7.553,8365,7.357,8366,9.561,8367,8.057]],["t/2190",[1,1.574,12,2.07,13,3.792,30,1.318,33,2.114,73,1.917,75,3.472,83,2.075,86,1.959,122,2.629,138,1.988,141,3.865,151,3.576,180,2.07,181,4.018,193,2.373,196,2.714,203,4.001,204,4.562,205,4.562,210,2.131,240,2.06,263,2.003,391,1.838,398,3.344,411,1.49,438,3.094,470,1.973,487,2.563,597,2.484,598,2.986,621,1.881,659,2.475,660,2.756,742,3.828,759,2.958,925,4.562,980,2.802,997,2.294,1025,3.216,1055,2.427,1732,3.274,1733,4.841,1829,2.649,1871,4.175,1873,4.229,1918,3.335,2003,4.348,2059,4.928,2180,2.484,2353,3.401,2403,4.414,2619,3.11,2815,3.549,2881,2.581,2910,4.287,2924,5.427,3036,3.943,3511,3.357,3662,4.124,3665,3.792,3672,4.287,3695,4.738,4270,3.472,4272,4.841,4542,4.175,4788,5.242,4858,4.841,5060,5.427,5140,5.088,5473,4.029,5479,4.562,5644,5.427,5980,5.242,6087,5.427,6144,4.956,6246,4.841,6247,4.738,7043,5.242,7179,5.242,7701,5.97,7702,5.659,7704,5.97,8114,4.562,8368,5.659,8369,5.97,8370,6.441,8371,6.441,8372,5.97,8373,6.441,8374,5.427]],["t/2192",[138,3.557,584,5.344,696,8.48]],["t/2194",[74,7.293,1952,6.787,4100,7.38]],["t/2196",[1,2.022,2,2.328,5,1.772,14,3.009,16,3.167,20,2.551,21,1.627,28,2.826,30,1.158,40,2.969,83,1.633,87,1.941,117,1.072,138,2.553,172,1.31,208,2.439,210,1.873,211,2.092,249,2.612,250,2.269,259,1.56,264,2.637,271,3.048,285,2.528,296,2.584,297,3.163,330,4.856,445,3.073,467,4.164,470,1.734,473,1.665,498,4.607,501,3.465,502,3.246,506,3.051,514,2.843,528,2.719,560,2.473,562,3.377,576,3.159,610,4.854,612,1.653,618,4.524,668,3.087,731,3.396,735,4.398,753,2.346,781,1.432,787,3.469,803,3.879,809,2.694,923,1.487,978,1.787,980,2.463,991,2.484,997,3.831,1013,3.913,1024,2.563,1069,2.913,1072,2.86,1135,3.581,1143,4.009,1177,1.878,1231,4.017,1267,3.364,1307,5.308,1489,2.969,1557,4.472,1921,3.246,1926,3.03,1927,4.607,1976,2.826,2156,4.164,2178,6.086,2188,5.761,2440,2.442,2662,3.193,2910,3.767,3259,3.541,4261,4.785,4262,4.827,4322,3.942,4593,3.502,8375,5.66,8376,4.254,8377,4.77,8378,5.246,8379,4.973,8380,5.66,8381,5.66]],["t/2198",[86,3.34,138,3.39,196,3.284,492,5.061,997,3.912,1304,6.95,8365,8.453,8382,10.984]],["t/2200",[21,3.037,180,3.397,181,4.68,203,4.659,411,2.446,474,3.894,775,3.094,877,5.915,985,3.168,1013,4.999,1204,4.315,1477,5.473,1988,3.87,2451,7.035]],["t/2202",[138,3.528,148,2.916,584,5.301,696,8.411]],["t/2204",[997,4.039,1332,5.536,3070,7.351,5443,10.511,8363,9.23]],["t/2206",[1,2.133,7,2.226,12,2.805,14,4.64,83,1.723,86,3.385,93,4.066,150,3.631,196,2.609,208,2.573,240,1.981,250,3.498,296,2.307,297,2.567,330,3.704,412,2.976,502,5.004,527,2.903,560,4.864,584,4.046,597,3.365,627,3.797,648,4.64,809,2.842,868,4.284,997,3.108,1013,4.128,1401,4.64,1853,5.343,1923,6.495,1976,4.358,2924,7.354,4261,5.047,4262,5.092,8045,7.668,8144,6.895,8376,6.559,8383,8.727,8384,8.727]],["t/2209",[12,2.61,27,3.922,83,1.603,87,3.644,96,3.197,97,2.506,117,0.89,139,2.388,178,3.922,202,5.752,209,3.303,235,3.901,245,3.186,290,6.525,398,2.991,506,4.377,550,5.332,597,3.131,655,5.332,754,5.655,891,3.964,986,7.776,991,3.564,998,2.383,1008,3.366,1011,4.232,1055,4.003,1169,4.696,1180,4.474,1182,5.565,1208,4.856,1246,6.609,1439,4.921,1722,3.747,1853,7.691,2012,7.135,2304,3.627,2521,5.858,3595,5.138,3808,6.415,4282,5.752,6907,6.609,8385,8.12,8386,8.12]],["t/2212",[4,2.919,5,2.058,7,1.782,11,2.41,12,2.245,19,3.618,21,2.008,34,4.37,35,4.234,43,3.342,83,1.38,93,3.255,97,3.824,123,2.151,136,3.121,137,2.852,172,2.223,175,4.59,181,3.093,206,3.821,219,2.305,227,4.192,267,2.353,271,3.539,276,3.392,391,1.994,463,2.383,473,2.825,474,2.574,501,4.277,506,3.766,510,2.04,511,3.178,521,3.015,560,4.197,564,4.077,576,2.257,597,2.694,598,3.239,611,2.93,654,2.831,670,3.121,748,2.676,781,1.768,909,4.323,1104,4.788,1140,3.941,1253,4.912,1364,4.473,1557,5.52,1709,7.818,1970,6.139,1976,4.796,2192,3.909,2815,3.85,2909,6.689,3337,3.411,3593,6.139,3680,6.405,3703,5.887,4270,3.766,4476,4.717,8387,6.987,8388,6.987]],["t/2214",[1,2.466,5,2.161,30,1.537,51,3.772,73,2.235,83,1.483,95,2.839,117,1.393,175,3.589,211,2.776,212,5.78,229,2.561,241,4.049,257,4.999,259,2.149,271,4.487,285,3.355,461,3.865,474,2.767,490,3.09,510,2.946,511,3.417,597,2.896,618,4.108,648,3.993,659,3.878,668,2.802,802,2.598,912,3.534,998,2.204,1031,4.382,1070,3.772,1187,3.608,1191,4.932,1352,4.932,1577,4.552,1636,5.645,1640,3.355,1659,5.934,1722,3.466,1792,4.698,1923,4.382,1976,3.75,2152,4.17,2173,5.78,2391,5.071,3680,4.382,4270,4.049,4440,5.32,4573,5.645,7203,5.32,8365,5.78,8377,6.329,8378,6.961,8389,7.511]],["t/2217",[11,3.438,43,3.468,136,4.453,150,4.148,172,2.307,180,3.204,203,4.394,243,3.136,250,3.995,267,2.962,397,5.817,473,2.932,506,5.374,543,8.759,611,5.071,820,3.561,2192,5.578,2909,6.942,8390,7.191]],["t/2220",[21,3.084,73,3.194,138,3.312,150,4.466,151,5.959,181,4.751,250,4.301,474,3.954,538,3.405,622,5.667,1918,5.557,1921,6.154]],["t/2222",[21,3.015,138,3.238,150,4.365,181,4.644,262,4.888,391,2.994,488,3.538,809,3.416,1010,7.306,1097,4.299,1271,5.503,1815,7.568,2254,7.211,8391,10.491]],["t/2224",[21,2.885,22,3.82,48,3.898,151,5.574,172,2.323,180,3.227,181,4.445,412,3.424,573,5.757,733,7.386,997,3.576,1281,5.491,1443,4.227,1714,6.508,1816,4.369,1918,5.199,1921,5.757,1976,5.013,1977,7.726,3465,7.242,8392,10.04]],["t/2226",[26,4.789,30,1.905,72,3.046,122,3.799,180,2.991,181,4.12,208,2.743,240,2.113,259,1.755,262,4.336,391,2.656,560,4.067,576,3.007,618,5.09,980,4.049,1025,4.647,1211,3.919,1417,5.531,1486,6.592,1816,4.049,1829,3.828,1923,5.43,2178,6.847,2440,4.016,4261,6.704,4262,6.763,4264,6.995,8144,7.352,8376,6.995,8393,8.626]],["t/2229",[5,2.377,11,2.087,21,1.739,24,2.971,26,3.114,30,1.777,51,3.039,85,1.711,87,2.075,95,2.287,117,1.113,183,3.195,196,1.809,208,2.993,209,2.461,240,2.305,259,1.638,263,1.881,296,3.329,297,2.986,330,4.709,349,4.365,350,3.47,351,4.681,360,4.548,391,1.727,411,2.35,412,2.064,425,3.47,470,1.854,474,2.229,510,1.767,527,2.013,557,2.236,576,2.805,588,4.452,610,4.311,618,3.31,621,1.767,627,2.633,636,3.114,659,2.326,735,4.616,786,3.239,820,2.162,861,3.631,997,2.155,1025,3.022,1033,3.057,1037,3.667,1055,2.28,1069,3.114,1071,3.154,1143,4.286,1187,2.907,1205,2.753,1211,2.548,1249,3.174,1260,3.785,1401,3.217,1546,3.874,1701,4.147,1732,3.076,1934,3.334,1946,4.548,1988,2.215,2154,3.133,2188,6.047,2337,3.195,2443,3.36,2456,3.667,2466,4.214,2518,3.441,2531,3.923,2666,3.531,2928,4.028,4085,4.365,8365,4.657,8376,6.526,8394,6.051,8395,4.657,8396,6.051,8397,4.781]],["t/2231",[1,2.881,117,1.292,212,9.07,259,1.803,296,3.115,330,5.003,411,2.727,425,5.482,621,2.792,627,4.16,831,4.667,1115,5.629,1246,7.782,1248,5.437,1277,5.048,2059,5.191,4267,9.594,4316,8.057,4504,8.057,8398,9.561,8399,8.401]],["t/2233",[10,3.724,25,3.949,26,3.949,74,4.856,83,2.274,117,0.841,123,2.363,156,2.487,169,3.492,208,2.263,259,2.172,263,2.386,267,2.507,287,3.563,296,2.029,330,3.258,414,2.081,474,2.828,483,2.92,521,3.312,637,3.974,734,4.167,743,5.345,787,3.219,955,4.869,998,2.252,1066,3.789,1177,2.546,1211,4.31,1268,5.906,1286,4.053,1455,4.365,1528,5.109,1640,4.572,1812,3.925,1819,4.138,1841,3.759,2191,4.699,2380,3.576,2608,4.975,2666,4.478,2909,5.345,3502,4.519,3594,6.064,3642,6.744,4472,5.109,7179,6.247]],["t/2235",[3,2.52,4,2.55,5,1.308,20,2.751,30,1.788,38,2.242,40,3.202,47,2.194,74,3.862,75,3.291,76,2.964,83,2.015,85,1.726,95,2.307,96,2.403,106,2.964,117,0.669,126,2.386,139,3.001,219,2.014,224,2.964,239,2.887,259,1.648,263,1.898,267,1.495,288,3.5,296,2.309,297,2.569,320,3.268,330,2.591,391,1.742,463,2.082,488,2.059,502,3.5,510,2.552,527,2.906,529,2.136,560,2.667,576,3.297,737,2.777,742,5.192,759,4.686,825,4.822,862,3.908,909,3.777,997,3.634,1013,4.826,1016,4.822,1017,5.465,1062,2.764,1066,3.013,1067,4.184,1097,2.501,1122,5.658,1140,3.443,1197,4.968,1208,2.79,1235,4.822,1238,4.324,1306,5.144,1478,3.268,1686,5.144,1721,5.144,1732,4.441,1901,5.363,2104,4.822,2178,4.491,2191,3.737,2206,4.491,2234,4.251,2300,3.416,2451,4.063,2924,5.144,3098,3.663,3652,4.491,4472,4.063,4586,5.144,4820,5.363,6654,4.968,8117,4.588,8374,7.362,8376,4.588,8400,6.104,8401,6.104,8402,4.184,8403,6.104,8404,6.104,8405,8.737]],["t/2237",[87,3.653,138,3.287,492,4.208,573,6.107,598,4.938,997,3.794,1304,6.739,1618,4.253,2016,5.701,3316,7.683,8365,8.196,8406,10.651,8407,10.651]],["t/2239",[117,1.15,155,5.365,239,4.962,576,4.028,980,4.565,1018,6.8,1714,6.8,1921,7.15,1977,8.073,2254,7.211,3345,6.423,4502,6.889]],["t/2241",[997,4.039,1332,5.536,3067,7.446,3068,8.727,4145,8.727]],["t/2243",[240,2.263,241,5.374,296,3.196,391,2.845,411,2.307,492,3.938,502,5.716,535,5.623,584,4.622,621,2.911,627,4.338,834,3.719,997,3.551,1035,5.766,1062,4.514,1069,5.13,1141,7.875,2909,6.942,4261,5.766,4262,5.817,8408,9.239]],["t/2245",[1,1.634,5,2.297,83,1.84,85,1.891,88,4.32,106,3.247,116,3.1,172,1.547,180,2.149,187,2.166,193,2.463,203,2.947,219,2.206,240,1.518,243,1.734,250,2.68,287,1.809,296,3.066,297,2.74,330,3.955,398,2.463,411,2.156,421,2.511,425,5.343,473,1.966,474,2.463,483,2.544,492,2.642,527,3.1,535,3.771,557,2.471,634,3.937,666,2.761,809,3.034,820,2.389,868,3.282,895,3.657,967,4.183,980,2.909,985,2.793,997,4.132,998,2.734,1097,2.74,1169,3.867,1395,5.875,2154,3.462,2155,4.052,2192,5.214,2304,2.987,2386,4.583,2396,3.937,2684,4.583,2717,5.026,2775,4.736,2776,4.736,2785,5.026,2789,4.334,2790,4.052,2881,2.68,2965,3.802,2988,6.197,3107,5.635,3337,3.264,5801,5.875,7151,6.197,7893,5.443,8409,6.687,8410,6.687,8411,6.687,8412,6.687,8413,6.687,8414,6.687]],["t/2248",[1,1.261,7,1.971,12,1.658,13,3.038,14,4.107,21,1.483,22,1.963,24,2.533,30,1.056,41,2.326,48,2.003,73,1.536,83,1.019,91,2.381,94,1.74,117,1.015,126,2.017,172,2.143,208,1.521,219,1.703,240,1.754,243,1.338,245,3.031,250,3.711,259,0.973,262,2.404,271,2.846,285,3.451,296,3.054,349,3.722,350,2.959,391,2.205,397,4.508,411,2.379,419,3.531,438,3.711,445,2.802,457,2.315,466,3.388,469,2.934,492,2.039,510,1.507,514,2.592,560,2.255,576,1.667,618,2.822,645,2.139,668,1.925,694,2.519,759,2.37,809,2.516,822,2.068,909,3.193,925,5.472,980,2.245,985,2.775,987,1.843,998,2.267,1014,2.428,1035,2.984,1037,3.127,1056,3.011,1069,4.765,1140,2.91,1151,2.959,1181,2.623,1211,2.173,1260,3.228,1334,3.388,1518,3.345,1547,4.052,1618,2.061,1732,3.927,1791,2.576,1816,2.245,1916,3.388,1918,4,1929,4.783,1967,2.576,1976,3.857,1988,2.828,2380,2.404,2493,4.077,2942,4.077,3072,3.722,3075,4.077,3077,4.783,3137,3.434,3666,4.534,4261,2.984,4262,3.011,4264,3.878,4270,2.782,4311,4.077,5835,4.534,6116,4.348,6243,4.783,6247,3.796,7033,6.288,7038,6.288,7043,4.2,7575,7.16,7580,6.51,8114,3.655,8372,4.783,8415,4.783,8416,5.16,8417,5.16,8418,4.783,8419,5.16,8420,5.16,8421,4.783,8422,4.534]],["t/2250",[11,2.471,27,3.46,33,2.352,38,2.631,86,2.972,87,3.352,103,4.645,117,1.31,122,2.925,136,3.2,178,3.46,180,2.303,181,5.535,207,4.482,208,2.112,229,2.444,240,1.627,245,2.811,250,2.872,290,5.385,296,1.894,391,2.045,398,2.64,414,1.943,419,3.275,473,2.107,490,2.947,514,3.599,531,3.557,610,3.557,638,4.769,649,3.145,659,2.754,679,3.62,759,3.29,775,2.097,781,1.813,818,3.664,875,3.149,978,2.262,985,2.148,997,2.552,998,2.102,1013,3.389,1062,3.244,1069,3.687,1070,3.599,1218,3.759,1332,3.498,1661,6.296,1846,4.342,1853,5.983,2118,3.948,2185,4.99,2254,4.144,2304,3.2,2416,4.769,3005,4.99,5406,6.296,7159,6.641,7563,6.296,8374,6.038,8393,6.641,8423,6.641,8424,6.641]],["t/2253",[5,1.824,85,2.408,93,3.967,117,0.933,138,2.628,148,2.172,156,2.069,172,1.97,243,2.208,250,3.413,267,2.086,296,2.896,297,2.504,330,3.614,391,2.43,411,2.803,419,3.892,470,3.357,473,2.504,474,3.137,571,4.203,600,5.013,607,2.334,817,4.558,875,2.744,985,3.284,997,3.033,1028,4.134,1069,4.381,1231,4.134,1449,4.277,1595,7.482,1844,5.213,1988,3.117,2145,4.803,2670,5.93,2864,7.482,4400,6.4,8376,6.4,8415,7.892,8425,7.482]],["t/2255",[43,3.259,116,4.344,117,1.276,123,2.884,156,2.277,194,3.541,203,4.13,250,4.665,391,2.674,411,2.693,626,3.589,781,2.37,877,6.513,957,3.553,1185,5.419,1647,5.467,2192,5.242,2415,6.32,3103,6.421,3506,4.242,4743,6.524,4851,9.474,4858,8.749,5030,7.402]],["t/2257",[2,4.043,83,1.941,117,1.077,145,5.544,240,2.231,250,3.939,271,3.621,414,2.665,568,4.798,681,5.379,809,3.2,998,2.884,1168,6.148,1181,4.996,1988,3.598,2060,6.057,2257,6.962,3680,5.735,7038,8,8426,9.829,8427,9.829,8428,9.829]],["t/2259",[26,3.949,84,5.141,117,1.122,180,3.29,181,3.398,203,3.383,211,2.837,219,3.378,240,1.742,243,1.991,250,3.076,411,1.776,482,4.167,568,3.747,659,3.934,681,5.168,785,5.267,923,2.016,997,2.734,998,2.252,1146,4.026,1201,6.468,1307,4.167,1418,3.11,1547,4.026,1615,4,1722,3.542,1733,5.769,1734,6.031,2060,5.172,2180,2.96,2450,8.556,2467,4.561,2535,5.906,3506,5.961,4269,6.744,6146,6.744,8368,6.744,8429,6.468,8430,7.675,8431,7.114,8432,7.114,8433,7.114,8434,7.114]],["t/2261",[5,2.247,22,3.992,138,3.238,180,3.372,181,4.644,196,3.137,219,3.462,414,2.845,488,3.538,1015,5.179,1055,3.953,2062,4.584,4788,8.539,8435,10.491,8436,8.841]],["t/2263",[30,1.764,115,2.973,117,0.945,156,2.094,175,4.119,240,1.957,243,2.235,245,3.382,250,4.426,271,3.175,285,3.85,338,4.185,421,3.237,492,3.406,752,5.075,764,3.659,775,2.523,802,2.982,955,3.644,985,2.584,1014,4.056,1090,4.279,1147,6.341,1177,2.86,1344,4.786,1401,4.582,1518,5.587,1717,5.333,1793,6.81,2060,4.355,2145,4.862,2154,5.719,2155,5.223,2415,5.996,3206,6.81,3337,4.208,3680,5.029,4627,6.106,8313,7.989,8437,7.574,8438,7.264]],["t/2265",[1,1.699,2,2.86,3,2.871,5,1.489,11,3.776,13,4.093,30,1.423,83,1.89,136,4.276,139,2.045,156,1.689,169,4.355,208,2.822,212,5.35,233,5.015,240,1.578,258,2.654,259,1.805,266,2.987,287,2.59,296,2.894,297,2.045,349,7.897,350,6.278,351,3.748,398,2.561,411,1.609,414,1.885,488,2.345,489,2.319,495,4.015,576,3.092,627,3.025,631,4.256,636,4.926,1070,3.492,1075,4.021,1097,2.849,1182,4.765,1248,3.953,1418,2.817,1455,5.443,1812,3.555,1816,3.025,1841,2.553,1923,4.056,2133,4.627,2171,2.963,2182,3.986,2191,4.256,2380,3.239,2666,4.056,2928,4.627,3126,5.015,3316,5.015,3707,8.067,6086,5.492,7513,5.858,8376,5.225,8439,5.659,8440,6.443,8441,6.443,8442,6.443,8443,6.443]],["t/2267",[5,2.076,6,4.927,85,2.741,87,3.324,138,2.991,492,3.83,573,5.558,598,4.494,997,4.234,1304,6.133,1618,3.871,1698,5.874,1988,3.549,2016,5.189,2909,6.75,3037,5.656,3067,6.365,3069,6.75,3316,6.992,8365,7.459,8424,8.984,8444,9.693,8445,8.517,8446,8.984,8447,8.517]],["t/2270",[568,5.28,885,6.368,953,4.686,1186,8.322,1372,7.01,1490,7.531,1528,7.198,2163,8.322,2909,7.531,3069,7.531,7434,10.024]],["t/2272",[4,3.994,8,6.278,11,3.298,19,4.951,20,4.309,21,2.747,22,3.638,27,4.617,29,5.35,116,4.433,118,3.567,222,5.437,467,7.034,499,6.121,562,3.903,563,6.897,576,3.089,756,4.522,790,5.853,867,2.95,1110,6.049,1234,7.457,1640,5.265,1641,7.553,1791,4.774,1846,5.794]],["t/2274",[997,4.039,1332,5.536,3067,7.446,3070,7.351,5441,8.959]],["t/2276",[7,2.472,13,5.707,14,5.153,90,3.56,128,4.451,208,2.857,339,4.389,391,2.766,502,5.558,557,3.582,584,4.494,668,3.617,735,5.153,809,3.156,997,3.452,1069,4.988,1104,6.643,1278,5.118,1732,4.927,2075,4.868,2188,6.75,2770,4.165,3069,6.75,8144,7.658,8422,8.517,8448,9.693]],["t/2278",[5,2.421,33,2.426,74,4.677,83,1.971,85,2.091,88,3.427,106,3.589,116,3.427,180,2.376,203,3.258,240,1.678,243,1.917,250,2.963,296,3.34,297,3.559,330,3.137,398,2.723,411,2.31,473,2.174,474,2.723,527,3.76,557,3.689,809,2.407,868,3.629,967,4.624,997,4.501,998,3.316,1045,4.792,1069,3.804,1169,4.275,1211,3.112,2075,5.013,2180,3.849,2192,5.585,2770,4.289,2809,6.851,3107,6.229,3337,3.609,3428,5.236,4914,5.148,5140,5.84,7152,6.851,7893,6.017,8449,7.392,8450,7.392,8451,7.392,8452,7.392]],["t/2281",[1,2.084,3,2.436,14,4.532,16,5.601,20,2.659,21,1.695,40,4.471,43,2.052,44,1.049,83,1.976,115,2.035,117,1.202,141,3.539,169,2.683,183,3.115,196,1.764,203,2.6,208,1.739,209,2.399,211,2.18,221,2.819,240,2.489,259,1.112,266,4.711,271,3.14,285,3.807,345,4.178,349,7.22,350,5.74,351,5.396,360,4.433,419,2.696,438,2.833,483,2.244,486,2.647,487,2.347,510,1.723,525,2.928,528,4.095,557,2.18,571,2.912,576,3.542,582,3.25,607,1.617,648,3.136,668,3.181,735,4.532,744,3.136,802,2.04,877,3.301,937,3.982,998,1.731,1045,3.823,1125,2.79,1211,2.484,1244,5.183,1257,3.926,1261,4.043,1331,2.381,1421,4.161,1620,4.971,1750,3.412,1771,4.433,1799,3.275,1832,3.873,1918,5.183,1976,2.945,2006,3.878,2170,4.433,2177,3.505,2234,4.108,2363,3.823,2571,3.982,2942,4.66,3694,4.66,4270,3.18,4311,4.66,4411,3.926,4479,3.732,4542,3.823,7001,4.66,8055,3.777,8453,5.898,8454,5.898,8455,5.183]],["t/2283",[5,1.212,11,2.853,20,2.551,21,1.627,25,2.913,28,2.826,73,1.684,83,1.633,85,1.601,86,2.516,87,1.941,117,1.072,118,2.112,128,3.799,136,3.695,138,1.747,180,2.659,181,4.761,187,1.833,207,3.541,229,1.93,239,2.677,240,1.878,243,2.145,250,4.585,259,1.844,267,1.386,287,2.239,296,3.344,297,2.875,330,4.15,391,1.615,411,2.262,414,1.535,419,2.587,473,1.665,487,2.252,489,2.76,490,2.328,495,2.374,521,2.442,529,1.981,538,1.796,574,5.065,576,1.829,631,3.465,679,2.86,759,2.599,820,2.022,875,2.666,908,2.092,923,1.487,997,2.947,998,2.869,1013,2.677,1021,3.274,1056,3.303,1069,2.913,1071,2.95,1135,3.581,1169,3.274,1290,4.607,1732,2.877,1816,4.254,1846,3.43,1934,3.119,1942,3.274,2060,2.86,2075,2.843,2176,4.77,2182,3.246,2186,3.396,2254,3.274,2304,2.528,2416,3.767,2915,3.879,3005,3.942,3069,3.942,3706,4.607,5498,2.86,7024,4.356,7563,4.973,7564,5.246,7922,4.083,8374,4.77,8423,5.246,8425,4.973,8445,4.973]],["t/2286",[5,2.062,85,2.722,118,3.592,128,5.886,138,2.971,168,3.211,267,2.358,296,3.628,297,2.831,330,4.086,411,2.739,419,4.4,473,2.831,474,3.546,881,5.776,997,3.429,2062,4.206,2440,4.153,2909,6.704,3069,6.704]],["t/2288",[43,3.396,44,2.122,124,5.801,712,5.225,720,6.496,753,4.046,923,2.563,957,3.701,1004,5.893,1618,3.898,1776,5.087,2356,4.961,2859,8.225,3632,7.944,4411,6.496,5058,8.576,7402,8.576,7418,9.046,8456,11.937,8457,9.76,8458,9.76,8459,9.76]],["t/2290",[240,2.617,681,5.172,8368,10.128]],["t/2292",[26,3.345,51,3.265,75,4.925,77,3.582,78,3.265,84,4.588,94,2.192,117,1.256,180,3.395,181,2.878,211,2.402,219,3.015,240,2.398,243,1.686,250,2.605,391,1.855,411,1.504,415,4.022,482,3.529,521,2.805,540,5.478,568,4.46,659,3.511,681,5.141,785,4.701,809,2.117,818,3.324,845,5.291,869,3.667,877,3.637,897,8.027,923,1.707,997,3.254,998,2.68,1146,3.41,1307,4.96,1418,2.634,1483,5.652,1609,3.304,1613,4.455,1615,3.388,1722,2.999,1733,4.886,1734,5.625,2060,4.616,2192,3.637,2450,7.979,2467,3.863,2535,5.002,2959,4.689,3506,5.669,3665,3.827,3710,7.217,4788,8.598,6144,5.002,8431,6.025,8432,6.025,8433,6.025,8434,6.025,8460,6.5,8461,6.5]],["t/2294",[3,3.768,6,5.819,22,3.472,36,4.991,51,4.583,85,2.581,86,2.775,88,4.231,93,4.251,94,3.077,116,4.231,123,2.809,126,3.567,128,4.19,139,2.684,259,2.159,267,2.235,488,3.861,560,3.987,600,5.373,786,4.885,825,7.209,834,4.272,868,4.479,997,4.078,1181,4.638,1829,3.753,1988,3.341,3037,5.324,8447,8.018]],["t/2296",[12,3.011,21,2.692,118,3.496,128,5.345,249,4.323,267,2.295,296,3.076,297,2.755,330,4.94,421,3.518,422,4.733,495,3.929,580,6.758,612,2.736,867,2.891,1029,5.328,1090,4.651,1114,5.467,1177,3.108,1273,3.663,1443,3.945,1584,6.152,1696,7.895,2429,5.998,2841,8.683,2990,7.626,3027,7.042,3037,5.467]],["t/2298",[1,1.604,2,2.699,3,2.709,5,1.405,11,3.662,13,3.863,30,1.343,83,1.816,136,4.107,139,1.93,156,2.234,169,4.183,208,3.392,212,5.049,233,4.733,240,1.489,258,2.505,259,1.734,266,2.819,287,2.488,296,2.806,297,1.93,349,7.658,350,6.088,351,3.537,398,2.417,411,1.518,414,2.494,488,2.213,489,2.189,495,3.857,576,2.971,627,2.855,631,4.017,636,4.732,1045,4.253,1069,3.376,1070,3.295,1075,3.795,1097,2.689,1182,4.497,1248,3.731,1418,2.659,1455,5.229,1618,2.62,1812,5.429,1816,2.855,1841,3.377,1923,3.828,2133,4.367,2143,4.43,2171,2.796,2182,3.762,2191,4.017,2380,4.284,2666,3.828,2928,4.367,3126,4.733,3316,4.733,3707,7.749,6086,5.184,7513,5.529,8376,4.932,8439,5.341,8440,6.081,8441,6.081,8442,6.081,8443,6.081]],["t/2300",[5,2.062,6,4.893,85,2.722,87,3.301,138,2.971,492,3.803,573,5.52,598,4.463,997,4.216,1304,6.091,1618,3.844,1698,5.833,1988,3.524,2016,5.153,2915,6.598,3037,5.617,3069,6.704,3071,6.336,3316,6.944,8365,7.408,8445,8.458,8462,9.626,8463,8.922,8464,9.626,8465,8.458]],["t/2302",[76,5.333,94,3.705,122,4.484,180,3.53,208,3.238,809,3.577,1518,7.12,1801,5.762,8466,10.984]],["t/2304",[4,4.383,8,6.889,11,3.619,19,6.456,22,3.992,27,5.066,116,4.864,222,5.966,467,7.718,499,6.717,562,4.283,652,4.962,790,6.423,1846,6.358]],["t/2306",[3,3.372,4,4.961,17,3.6,19,4.229,23,5.514,30,1.672,44,1.452,48,3.171,75,4.403,106,3.966,126,3.193,463,2.785,474,3.009,504,4.467,507,6.883,521,3.524,529,2.858,568,3.987,576,3.837,648,4.342,756,3.863,911,5.294,1062,4.829,1071,4.256,1081,5.785,1121,5.785,1203,4.57,1204,4.354,1234,6.748,1351,5,1546,5.229,1730,6.453,2191,5,2928,5.436,3069,5.688,3078,4.949,4169,4.5,6468,6.883,6654,6.648,8295,6.453,8439,6.648,8467,8.167,8468,7.57,8469,7.57,8470,7.57,8471,6.883]],["t/2308",[997,4.039,1332,5.536,3068,8.727,3071,6.07,4336,6.943]],["t/2310",[3,3.724,4,3.767,5,1.367,11,2.201,12,2.051,14,3.393,21,3.005,26,3.284,30,1.846,41,2.877,74,4.038,83,1.26,117,0.7,139,2.652,163,3.034,172,1.477,180,2.051,181,2.825,208,1.881,209,4.253,219,2.106,259,2.464,287,2.44,296,1.687,297,1.877,330,2.709,411,1.477,414,1.731,462,3.66,469,3.629,473,1.877,486,2.863,501,3.907,557,2.359,562,2.605,571,3.15,576,3.379,612,1.864,633,4.604,734,5.678,745,3.867,759,2.931,768,3.629,820,2.28,825,5.042,910,6.275,923,1.676,991,2.801,997,3.212,1019,2.959,1055,2.404,1097,2.615,1151,3.66,1168,3.992,1216,4.695,1260,3.992,1286,3.37,1290,5.195,1490,4.444,1546,4.086,1559,4.911,1581,5.378,1582,4.695,1584,4.191,1614,3.992,2161,4.521,2163,4.911,2186,3.829,2300,3.571,2305,3.49,2915,4.374,3594,5.042,4169,3.517,4506,4.604,6086,5.042,8472,7.34,8473,5.042]],["t/2312",[1,1.683,5,1.475,11,3.279,72,2.253,78,5.47,83,1.359,85,1.947,94,2.322,95,2.602,106,3.342,123,2.927,128,4.366,180,3.056,203,3.034,208,2.029,214,2.402,219,3.137,243,1.785,250,2.759,255,4.171,259,1.298,296,1.819,297,2.024,391,1.965,398,2.536,412,2.348,414,2.578,415,5.883,487,2.739,489,3.171,521,2.97,527,2.29,530,3.021,557,2.544,607,1.887,775,2.015,787,2.887,825,5.438,909,4.259,967,4.306,978,2.173,985,2.063,997,4.184,998,2.79,1013,3.256,1063,5.297,1071,3.587,1169,3.981,1211,2.898,1249,4.987,1357,5.438,1372,4.462,1490,4.794,1612,3.52,1988,2.52,2059,3.737,2144,3.737,2152,3.822,2180,3.666,2192,5.32,2744,5.438,2915,4.718,4914,4.794,5140,5.438,6011,5.801,7169,5.801,8474,6.884,8475,6.884]],["t/2315",[10,1.731,11,3.04,12,1.529,22,2.764,30,0.974,43,1.655,48,1.847,72,1.557,83,1.434,85,1.345,86,3.231,87,1.632,88,2.206,97,1.468,116,2.206,117,1.081,163,2.262,165,2.053,168,1.587,177,2.174,180,3.17,181,2.106,187,2.353,196,1.422,201,2.448,208,2.142,220,2.297,240,1.08,243,1.884,250,3.532,258,1.816,259,1.37,262,2.216,271,1.753,285,2.125,287,1.287,296,2.329,297,2.137,330,4.51,391,1.358,411,1.101,414,2.39,421,2.728,425,2.728,461,3.738,473,2.592,489,1.587,492,1.879,501,2.912,506,2.564,525,2.362,527,1.583,541,2.827,553,2.529,565,2.776,568,2.322,576,1.537,614,2.403,615,2.66,652,2.25,666,1.964,668,2.711,741,3.661,764,2.019,785,2.448,786,2.547,809,1.549,820,2.595,832,2.512,868,3.566,875,3.179,877,2.662,896,2.602,923,1.249,997,1.694,998,1.396,1011,2.479,1025,4.926,1045,3.084,1056,2.776,1062,2.154,1066,2.348,1069,2.448,1134,3.124,1168,2.976,1177,1.578,1214,2.479,1231,2.31,1290,3.872,1331,2.933,1618,1.9,1712,2.583,1773,2.564,1816,2.07,1829,1.957,1949,4.003,1976,2.375,1988,2.66,2062,2.079,2143,3.212,2152,2.641,2154,2.463,2155,2.883,2157,3.23,2168,3.5,2180,3.804,2667,3.872,2684,3.26,2703,3.124,2732,3.37,2815,2.621,2819,3.432,2903,3.046,3319,3.01,3678,3.973,4503,4.905,5362,5.739,6143,3.37,8352,3.661,8476,4.757,8477,4.757,8478,7.265]],["t/2317",[12,3.503,38,4.003,118,4.067,181,4.825,209,4.433,219,3.597,550,7.157,1222,7.862,1362,7.065,1618,4.352]],["t/2319",[11,3.39,85,2.78,116,4.557,118,3.667,128,6.185,180,3.159,296,3.419,330,4.172,411,2.774,487,3.911,489,3.999,541,5.841,668,3.667,1009,3.501,1249,5.156,1816,4.277,7169,8.283]],["t/2321",[11,2.605,15,3.793,45,5.555,83,1.999,84,3.793,89,4.406,116,3.501,117,1.252,136,3.373,139,2.978,145,4.259,180,2.427,211,2.791,250,3.026,296,1.996,330,3.205,487,3.005,489,3.378,505,4.042,615,2.765,626,3.879,659,3.892,681,5.477,869,4.259,908,2.791,957,2.864,991,3.314,1131,4.193,1618,3.016,1722,3.484,1734,5.992,2060,3.815,2450,8.5,2467,4.488,2607,6.363,2626,5.966,2856,8.897,2978,5.811,3069,5.259,3104,4.895,3258,6.999,3337,3.686,3579,5.966,5115,6.999,5574,6.635,7169,6.363,8479,7.551,8480,7.551,8481,7.551,8482,6.999]],["t/2324",[12,2.291,20,3.213,43,2.48,93,3.321,116,3.305,117,1.068,139,2.097,155,3.646,199,4.411,204,5.049,211,4.099,219,2.352,250,2.857,398,2.626,400,3.79,461,3.668,473,2.097,489,2.378,527,2.372,568,5.82,597,2.749,626,4.566,681,5.6,735,5.897,774,4.364,998,3.255,1332,3.48,1733,5.358,1952,4.197,1967,3.56,2003,4.813,2180,2.749,2188,7.725,2662,4.021,3067,4.681,3506,5.651,3510,5.632,4964,5.049,6002,6.607,8369,6.607,8421,6.607,8429,10.046,8483,5.358,8484,7.129,8485,7.129,8486,7.129,8487,7.129,8488,6.607,8489,7.129,8490,7.129,8491,7.129,8492,7.129]],["t/2326",[22,4.043,73,2.416,83,1.603,93,3.783,139,2.388,209,4.321,214,2.833,259,1.531,391,2.317,486,3.643,488,2.739,584,3.765,768,6.042,786,4.347,787,3.406,788,5.08,997,2.892,1055,3.059,1528,5.405,1829,4.37,1842,8.712,1988,2.973,2133,5.405,2185,5.655,2186,4.872,2353,4.288,2915,5.565,3037,4.738,3067,8.249,3069,5.655,3071,4.347,3078,4.921,3511,4.232,8436,10.987,8493,8.12,8494,8.12,8495,8.12,8496,7.526,8497,8.12,8498,8.12,8499,8.12]],["t/2328",[89,6.121,196,3.137,267,2.57,330,4.453,414,2.845,799,7.431,1185,6.068,2494,9.218,3336,9.724,8500,10.491,8501,10.491,8502,10.491,8503,10.491,8504,10.491,8505,10.491]],["t/2330",[1,2.293,5,1.446,7,1.722,11,3.235,15,3.391,21,1.94,30,1.382,47,2.426,83,1.333,87,2.315,117,1.028,148,1.722,177,3.085,187,2.187,196,2.805,208,3.434,214,2.356,218,2.356,233,4.87,259,1.769,263,2.916,267,1.654,287,3.586,288,5.379,315,3.411,398,2.487,473,1.985,487,2.686,489,2.252,490,2.777,492,2.667,527,2.246,541,4.012,557,2.495,575,2.766,576,2.181,597,2.603,607,1.851,621,1.972,627,2.937,638,4.493,648,3.589,652,3.193,663,2.925,764,2.865,775,1.976,816,2.756,817,3.614,887,4.177,896,3.692,912,3.177,1134,4.433,1222,4.87,1265,4.322,1307,3.665,1445,4.701,1734,3.314,1790,3.071,1812,3.452,2074,4.091,2350,4.177,2570,3.614,2662,3.808,4593,5.804,8144,5.333,8379,5.932,8506,6.751,8507,5.689,8508,6.751,8509,5.495,8510,6.751]],["t/2332",[5,2.062,15,4.835,20,5.335,87,4.059,117,1.055,167,5.474,180,3.094,259,1.815,445,5.226,488,3.247,492,3.803,541,5.721,786,5.153,788,6.022,1056,5.617,1072,4.863,2016,5.153,2169,7.235,2927,7.605,3028,5.893,3091,8.922,8463,8.922,8511,9.626,8512,9.626,8513,9.626]],["t/2334",[20,3.983,22,4.691,83,2.215,151,4.907,166,6.192,172,2.045,196,2.642,197,4.117,199,7.628,214,3.083,296,2.336,297,3.3,330,3.751,490,3.635,526,3.297,576,3.625,607,2.423,612,2.581,668,3.297,787,3.706,997,3.148,1261,6.057,1829,3.635,1942,5.111,1948,4.984,1952,5.203,2468,4.731,2913,6.501,2915,6.057,3028,5.41,8514,8.191]],["t/2336",[4,4.383,8,6.889,11,3.619,19,6.456,22,3.992,27,5.066,116,4.864,222,5.966,467,7.718,499,6.717,562,4.283,652,4.962,790,6.423,1846,6.358]],["t/2338",[3,3.392,4,4.975,19,4.254,23,7.228,24,4.033,30,1.681,48,3.19,51,4.126,75,4.429,106,3.989,126,3.212,360,6.175,508,4.752,521,3.545,529,2.875,553,4.368,557,3.036,576,3.459,660,3.515,911,5.325,1062,4.848,1071,4.281,1081,5.819,1082,4.929,1097,3.367,1187,3.946,1203,4.597,1204,3.354,1234,6.774,1351,5.03,1386,5.03,1546,5.26,1730,6.49,2191,5.03,2915,5.631,2928,5.468,2934,4.711,3078,4.978,4169,4.527,4318,6.044,6654,6.687,8439,6.687,8469,7.614,8470,7.614,8471,6.923,8515,8.215]],["t/2340",[284,8.959,1738,9.556,2359,6.943,2754,6.113,4297,7.656]],["t/2342",[7,1.081,11,1.462,20,1.911,21,1.909,30,1.36,33,2.181,43,1.475,71,2.748,73,1.261,75,2.285,76,2.058,77,2.336,83,1.832,85,1.199,96,3.226,117,1.017,118,1.582,122,1.731,123,1.305,138,1.308,139,2.41,148,1.081,168,1.414,172,2.331,187,2.152,203,1.868,208,2.97,209,1.724,245,1.663,249,1.956,259,0.799,262,1.975,267,1.038,271,4.262,285,4.5,398,3.019,414,1.802,461,4.217,473,3.143,474,1.562,488,1.43,510,1.238,541,2.519,542,2.821,555,1.538,574,2.595,576,2.647,597,2.562,621,1.238,624,2.117,659,3.15,668,2.479,710,2.952,781,1.681,814,1.43,830,3.877,837,2.784,890,1.965,908,1.567,955,1.792,978,3.18,980,2.891,987,1.514,994,4.068,1008,1.757,1014,1.995,1030,2.209,1064,2.623,1115,2.496,1135,2.682,1176,5.113,1177,1.406,1181,3.377,1184,3.349,1187,3.937,1204,1.731,1214,2.209,1231,2.058,1248,2.411,1249,2.224,1253,2.168,1267,2.519,1273,1.657,1355,2.623,1374,2.748,1417,2.519,1439,2.569,1449,3.337,1475,2.748,1477,3.441,1485,2.748,1599,1.75,1607,2.644,1640,1.893,1678,2.129,1732,3.377,1778,1.995,1816,1.845,1871,2.748,1961,3.226,1966,2.142,1985,2.905,2062,1.852,2137,3.003,2140,3.349,2157,1.885,2177,4.87,2230,1.893,2257,3.003,2317,3.186,2318,3.003,2380,1.975,2415,2.302,2440,3.536,2443,2.354,2531,2.748,2674,2.254,2751,2.496,2881,2.663,2899,2.318,2925,3.349,2975,2.336,3030,2.682,3659,2.318,3810,2.411,4298,5.599,4299,3.725,4300,3.725,4301,3.186,4302,3.45,4303,3.349,4304,3.725,4305,3.572,4306,3.725,4307,3.058,4308,3.349,4309,3.725,4310,3.572,4311,3.349,4312,3.119]],["t/2344",[1,3.114,38,3.487,77,5.232,83,2.318,95,3.589,117,1.287,151,5.272,156,2.852,229,3.238,259,1.791,287,3.176,414,3.183,433,6.008,576,3.068,1062,4.3,1208,4.34,1213,5.313,1799,5.272,1841,3.487,1961,4.611,2674,5.048,2992,8.002]],["t/2346",[1,2.961,22,2.497,30,1.343,83,1.296,117,0.719,137,2.679,138,2.838,166,3.295,187,2.125,194,4.013,208,3.392,210,2.171,221,3.135,267,1.607,271,3.388,285,4.107,297,3.122,473,1.93,578,3.615,624,3.276,646,4.565,647,3.828,648,3.488,649,2.88,660,2.808,665,4.017,734,3.562,737,2.985,775,3.108,802,2.27,817,4.922,912,3.088,964,3.671,971,3.488,980,2.855,998,1.925,1011,3.419,1030,3.419,1071,3.419,1177,2.177,1208,2.999,1277,3.465,1397,4.733,1412,5.184,1449,3.295,1521,3.731,1530,3.828,1678,3.295,2033,4.43,2055,4.43,2060,3.315,2138,4.569,2210,4.733,2316,2.957,2506,4.308,2581,4.762,2703,4.308,2881,4.611,2899,3.589,3797,3.828,4313,4.569,4314,4.648,4315,7.658,4316,5.529,4317,4.932,4318,4.827,4319,7.485,4320,4.497,4321,5.529,4322,4.569]],["t/2348",[1,2.926,7,2.501,72,2.358,80,3.555,83,2.364,85,2.037,86,2.19,94,2.429,116,3.339,117,1.075,139,2.118,153,4.062,177,3.292,183,3.803,187,2.333,206,5.364,208,3.529,217,4.03,250,2.886,263,3.049,271,2.653,607,2.689,626,2.759,659,2.768,775,2.871,781,1.822,786,3.855,869,4.062,887,4.456,912,5.248,993,4.3,998,2.113,1013,3.406,1024,3.261,1097,2.951,1205,3.276,1231,3.497,1455,5.577,1791,3.596,1987,4.13,2171,3.069,2388,4.862,2570,5.25,2581,5.078,2881,2.886,2913,5.298,3502,4.24,4100,4.611,4323,6.328,4324,6.328,4325,6.44,4326,6.328,4327,5.015]],["t/2350",[1,1.312,17,1.028,30,2.4,33,3.441,38,0.857,41,1.052,44,2.025,73,1.908,77,2.232,83,2.344,84,1.172,96,1.595,117,0.796,123,0.718,138,0.72,150,2.234,156,1.764,157,3.118,169,1.843,172,0.937,173,1.46,175,1.115,186,0.945,187,0.756,201,2.763,214,1.414,219,1.337,241,1.258,243,1.051,245,3.122,259,0.44,263,2.657,267,0.572,414,1.456,437,1.967,462,1.338,463,0.796,486,1.047,488,3.325,490,2.637,555,3.576,562,1.654,576,1.309,597,1.562,611,2.252,612,0.681,615,1.483,619,2.442,621,0.681,624,2.023,646,2.011,649,1.024,659,0.897,666,0.963,671,2,712,4.26,723,3.254,732,0.735,739,1.414,748,0.894,753,3.75,786,2.169,814,0.787,832,2.139,834,0.871,837,1.532,875,0.752,923,0.613,937,1.575,942,1.179,953,1.011,957,0.885,964,1.306,969,1.165,971,1.24,978,1.279,980,1.763,994,1.428,1004,3.928,1009,2.585,1021,1.35,1036,1.276,1097,0.956,1162,1.35,1187,1.121,1204,0.953,1300,1.444,1331,3.45,1431,1.093,1440,1.553,1443,0.982,1446,3.254,1460,4.934,1465,1.826,1489,1.224,1490,1.625,1559,1.796,1596,2.941,1644,1.717,1712,1.267,1722,1.077,1727,0.829,1753,2.011,1776,4.147,1777,1.512,1830,1.258,1841,2.355,1878,1.428,1904,2.047,1946,1.754,1974,1.186,2018,1.158,2062,2.346,2154,2.78,2157,4.216,2230,1.042,2260,2.851,2271,1.145,2275,1.024,2305,1.276,2391,1.575,2581,5.105,2673,1.414,2674,2.154,2693,4.542,2751,3.161,2768,1.717,2770,1.741,2785,1.754,2819,1.683,2861,4.923,2872,1.46,2881,3.425,2892,1.717,2893,1.754,2918,2.87,2940,1.683,2965,3.053,2975,4.385,3030,5.407,3078,2.455,3102,1.599,3135,2.821,3220,1.653,3318,2.455,3511,1.216,3659,2.936,3810,4.86,3893,1.754,4270,3.456,4315,1.683,4325,1.532,4328,10.162,4329,2.05,4330,2.05,4331,2.05,4332,1.843,4333,5.634,4334,4.37,4335,3.298,4336,1.428,4337,1.843,4338,4.718,4339,4.132,4340,2.05,4341,1.532,4342,2.05,4343,3.298,4344,3.201,4345,1.966,4346,2.05,4347,2.05,4348,2.05,4349,1.899,4350,1.387,4351,2.05,4352,1.966,4353,2.05,4354,2.05,4355,1.843,4356,2.05,4357,2.05,4358,1.717,4359,2.05,4360,1.754,4361,2.05,4362,2.05,4363,2.05,4364,2.05,4365,2.05,4366,2.05,4367,3.56,4368,3.56,4369,2.05,4370,2.05,4371,1.966]],["t/2352",[1,2.698,30,1.325,44,0.729,71,2.659,72,2.626,79,4.562,80,3.96,81,5.425,83,2.179,84,3.252,86,1.248,96,1.615,97,1.266,117,0.999,123,1.263,129,3.457,130,3.457,134,3.241,139,1.905,144,3.653,145,2.314,146,2.152,148,1.046,151,2.278,156,1.949,160,4.549,164,1.675,169,1.866,170,2.212,173,2.566,175,3.834,177,1.875,183,3.42,187,1.329,194,2.448,210,3.015,224,1.992,226,1.911,238,4.64,243,1.679,255,2.486,263,2.013,267,2.232,271,2.386,285,2.893,297,1.905,339,1.858,401,2.085,419,1.875,436,4.862,443,2.716,470,1.257,473,1.207,490,1.688,501,2.512,510,1.198,525,2.037,528,1.971,529,1.436,538,2.055,576,2.092,598,1.902,615,1.502,622,2.166,645,1.701,649,2.842,668,1.531,678,2.196,737,1.866,744,2.181,748,1.571,770,3.443,781,2.03,814,1.384,867,1.999,911,2.659,912,1.931,978,2.044,1009,1.461,1021,2.373,1024,1.858,1028,1.992,1049,3.713,1090,2.037,1170,1.748,1205,1.866,1247,3.241,1312,2.566,1341,3.018,1355,2.538,1402,2.462,1404,2.627,1457,2.373,1596,1.516,1618,1.638,1643,2.731,1717,2.538,1722,1.893,1841,1.507,1904,2.073,1958,2.227,1985,2.812,1988,1.502,2074,2.486,2157,1.824,2181,2.731,2230,2.893,2363,2.659,2451,2.731,2506,2.694,2518,2.333,2569,3.084,2581,2.124,2587,4.51,2608,2.659,2768,3.018,2881,1.644,2885,2.959,2886,3.157,2887,3.157,2892,3.018,2893,6.03,2923,2.627,2931,3.157,2934,2.353,2973,2.596,2975,2.261,3102,2.812,3481,3.157,3486,3.457,3516,6.245,4372,3.605,4373,3.605,4374,3.605,4375,3.241,4376,3.241,4377,3.339,4378,3.605,4379,3.457,4380,3.457,4381,3.339,4382,3.605,4383,3.339,4384,3.605,4385,3.605,4386,3.241,4387,3.605,4388,3.605,4389,3.605,4390,3.605,4391,3.241,4392,3.605,4393,3.241]],["t/2354",[1,2.777,5,1.6,7,1.906,44,1.328,77,4.117,91,3.447,115,2.577,117,0.819,123,2.3,144,4.214,148,1.906,166,5.049,175,4.804,222,4.248,240,1.696,259,1.409,267,2.462,411,1.729,438,3.589,445,4.056,465,5.389,495,3.133,497,4.783,529,2.614,579,2.761,660,3.197,668,2.787,670,3.337,697,3.516,737,3.399,748,2.862,781,1.89,875,2.407,969,3.73,985,2.239,1014,3.516,1024,3.383,1273,2.921,1281,4.086,1618,2.983,1801,3.919,1942,6.572,1943,4.359,2074,4.527,2152,4.148,2254,4.321,2377,5.749,2396,4.399,2581,3.869,2662,4.214,2881,4.029,3516,5.12,4386,5.902,4394,5.615,4395,6.081,4396,6.081,4397,5.749,4398,6.564,4399,4.148,4400,5.615,4401,6.564]],["t/2356",[1,1.71,3,2.27,12,1.076,30,1.83,33,2.296,34,2.094,35,2.029,38,1.229,40,1.756,44,0.595,47,1.203,48,1.3,72,1.096,79,1.904,80,1.653,83,2.094,85,0.947,94,1.129,106,1.626,113,1.953,114,3.366,117,0.767,123,1.031,124,1.99,148,0.854,156,1.336,165,1.445,175,2.627,208,2.062,210,3.634,219,1.105,222,1.904,224,1.626,229,1.142,240,0.76,242,1.681,243,0.868,250,2.203,263,1.041,271,3.295,276,1.626,285,3.995,291,1.873,298,3.402,339,1.516,391,0.955,403,2.228,412,1.142,414,0.908,420,3.798,423,1.888,470,1.026,488,1.129,491,2.353,492,2.764,511,1.523,520,1.734,529,2.834,530,2.413,535,1.888,555,1.214,562,2.244,576,1.082,584,1.552,612,1.606,613,1.672,615,1.226,618,1.831,619,1.523,649,2.413,659,1.287,660,1.433,693,1.953,694,2.684,710,3.829,720,3.659,737,1.523,770,1.78,775,2.618,785,1.723,794,2.415,814,1.854,820,1.196,834,2.61,875,1.771,879,1.936,890,1.552,923,0.879,957,2.085,973,2.295,978,1.057,1008,1.388,1009,1.192,1036,1.831,1062,2.489,1064,2.071,1085,4.045,1177,1.824,1187,1.608,1195,1.971,1200,1.78,1208,1.53,1211,1.41,1219,4.475,1245,1.99,1248,1.904,1265,2.143,1278,1.768,1399,1.634,1411,2.576,1440,2.228,1443,1.41,1453,4.343,1489,1.756,1518,2.17,1607,1.332,1617,1.99,1640,1.495,1644,2.463,1678,2.761,1715,1.357,1717,2.071,1722,1.545,1751,1.92,1762,2.821,1776,1.745,1777,2.17,1788,1.904,1807,4.319,1825,1.953,1878,2.05,1904,2.778,1914,1.672,1923,1.953,1948,1.888,1953,2.094,1961,1.626,2010,2.094,2027,2.143,2118,1.845,2157,1.489,2186,2.009,2220,2.371,2230,2.456,2260,1.489,2295,3.007,2304,1.495,2313,1.936,2331,2.05,2356,5.162,2415,4.856,2608,2.17,2649,2.371,2674,3.719,2751,1.971,2815,1.845,2881,1.342,2965,3.126,2975,1.845,3005,2.331,3030,2.118,3032,2.029,3087,2.645,3104,2.17,3469,3.894,3770,2.415,3810,3.126,3931,2.118,4100,2.143,4170,2.071,4327,5.639,4393,2.645,4399,4.496,4402,2.942,4403,2.942,4404,5.797,4405,2.942,4406,2.645,4407,2.942,4408,2.942,4409,2.645,4410,2.645,4411,2.228,4412,5.526,4413,2.576,4414,2.942,4415,2.821,4416,2.645,4417,2.516,4418,2.942,4419,2.516,4420,2.645,4421,2.645,4422,2.645,4423,2.942]],["t/2358",[1,2.45,5,1.593,6,3.781,7,1.252,22,1.867,26,3.828,38,1.802,39,2.944,44,0.872,83,1.979,85,1.388,90,2.732,94,1.655,117,0.815,186,1.988,208,1.447,210,1.624,229,1.674,259,1.403,263,2.313,271,2.74,338,3.612,412,2.537,420,2.664,470,1.503,473,2.642,510,2.172,514,3.736,530,2.154,576,2.403,579,1.813,612,1.433,619,3.384,649,3.264,760,2.37,770,2.609,771,3.476,775,2.177,787,2.058,809,1.598,814,3.381,834,2.775,837,3.222,878,4.822,879,4.302,912,2.309,978,2.835,987,1.753,1016,5.876,1024,2.222,1049,2.814,1072,2.479,1081,3.476,1090,2.436,1115,2.889,1167,3.877,1177,1.628,1180,2.704,1193,4.135,1486,3.476,1672,3.363,1727,1.743,1778,2.309,1807,2.37,1825,2.863,1841,2.732,1846,2.974,1904,2.479,1915,3.54,2018,3.693,2021,6.074,2027,3.142,2033,3.313,2118,2.704,2138,3.417,2157,2.182,2161,3.476,2206,3.61,2223,3.105,2230,2.192,2261,3.363,2284,3.54,2295,4.913,2305,2.684,2356,4.566,2415,4.877,2451,3.266,2570,2.627,2881,4.317,2975,2.704,3609,3.363,3810,2.79,4170,3.036,4312,3.61,4325,4.884,4399,4.988,4424,3.776,4425,3.61,4426,3.994,4427,4.312,4428,9.466,4429,3.476,4430,3.877,4431,4.312,4432,4.312,4433,4.312,4434,4.312,4435,4.312,4436,4.312,4437,4.312,4438,4.312,4439,3.688]],["t/2360",[1,0.552,7,1.599,17,0.995,26,1.162,30,0.806,33,2.334,38,2.302,44,2.425,47,0.812,48,0.877,72,1.289,77,2.17,80,1.115,83,1.034,84,1.134,87,0.774,96,2.061,97,1.215,114,2.411,115,1.358,117,0.432,124,2.34,148,1.335,150,1.638,156,0.549,169,1.791,170,2.123,172,1.645,173,1.413,175,2.995,196,0.675,199,1.397,208,1.161,210,0.747,214,0.788,240,0.513,250,0.905,263,2.904,267,0.964,271,1.929,285,1.009,291,5.794,335,5.633,350,2.258,412,0.77,420,2.138,470,0.692,483,0.859,488,0.762,510,1.15,555,0.819,557,0.835,562,0.922,565,1.318,575,0.925,576,0.73,579,0.835,612,1.15,613,1.128,615,0.827,617,2.079,619,1.027,621,0.659,649,0.991,659,2.012,663,1.706,670,1.759,671,1.115,705,1.629,710,1.573,712,1.209,719,1.004,720,4.172,722,1.525,723,2.386,748,1.508,770,3.333,775,2.286,781,0.571,787,0.947,802,0.781,814,2.114,820,1.87,830,1.318,834,2.339,837,1.483,882,1.141,886,1.254,906,1.966,923,0.593,957,0.856,959,1.573,969,1.128,978,1.243,1009,2.533,1019,1.826,1028,1.096,1052,5.98,1075,1.306,1090,1.121,1204,2.559,1208,1.032,1273,0.883,1278,1.192,1404,1.446,1446,1.368,1460,3.03,1465,1.018,1471,1.121,1473,2.491,1483,4.399,1530,1.318,1565,1.483,1596,0.835,1672,1.548,1698,2.386,1773,2.822,1776,4.07,1777,2.552,1788,3.565,1790,1.027,1807,1.091,1841,0.829,1848,1.738,1874,1.318,1896,1.274,1904,1.141,1974,1.148,2004,1.903,2019,1.573,2026,1.661,2043,1.525,2062,0.987,2157,2.328,2232,1.503,2240,1.413,2288,1.254,2295,2.153,2327,1.629,2328,2.491,2356,4.269,2391,2.658,2415,2.843,2440,0.974,2468,1.209,2519,1.446,2634,6.663,2674,2.093,2751,3.691,2861,6.015,2872,1.413,2923,1.446,2973,1.429,2974,1.838,2975,2.885,3041,1.661,3058,1.599,3102,2.699,3366,2.277,3596,1.838,3659,1.235,3701,2.239,3768,1.738,3810,3.565,3918,2.34,3931,1.429,4169,1.244,4322,1.573,4360,1.697,4399,3.948,4404,2.552,4409,1.784,4410,1.784,4411,4.733,4412,3.111,4413,4.029,4440,1.599,4441,1.573,4442,3.318,4443,3.352,4444,1.984,4445,1.984,4446,1.984,4447,1.984,4448,4.261,4449,1.738,4450,5.508,4451,1.984,4452,5.472,4453,1.984,4454,7.824,4455,1.984,4456,1.984,4457,6.133,4458,1.984,4459,7.38,4460,1.984,4461,1.984,4462,1.984,4463,1.984,4464,1.984,4465,1.984,4466,3.46,4467,4.6,4468,3.111,4469,1.984,4470,1.984,4471,2.658,4472,1.503,4473,1.738,4474,1.984,4475,1.984,4476,1.525,4477,1.784,4478,1.784,4479,1.429,4480,1.903,4481,3.852,4482,1.984,4483,1.784,4484,1.483,4485,1.784,4486,3.852,4487,1.784,4488,1.984,4489,3.46,4490,1.984,4491,1.984,4492,1.984,4493,1.984]],["t/2362",[7,2.174,22,2.244,28,2.945,38,3.13,85,1.668,114,3.611,169,2.683,194,2.23,208,2.513,211,4.052,241,3.18,249,2.722,268,3.442,297,1.735,298,3.65,470,2.611,473,1.735,510,1.723,529,2.983,576,1.906,612,1.723,615,2.159,659,4.214,660,4.283,734,3.203,759,5.035,770,3.136,775,1.727,830,3.442,867,1.82,906,2.945,955,2.494,957,2.237,966,4.433,978,1.862,1014,2.776,1091,3.301,1181,2.998,1204,2.408,1211,3.589,1239,3.412,1253,3.016,1283,3.301,1308,2.98,1477,5.183,1483,3.65,1530,4.974,1678,2.962,1698,3.574,1749,3.412,1776,5.714,1807,2.849,1870,4.66,2230,3.807,2232,5.674,2240,5.332,2295,6.63,2305,5.474,2317,4.433,2478,3.157,2723,3.035,2899,4.662,2973,6.333,2999,4.043,3366,4.93,3918,3.505,4399,3.275,4404,5.526,4443,5.458,4481,6.271,4483,4.66,4486,6.271,4494,5.183,4495,6.734,4496,4.66,4497,5.183,4498,5.183]],["t/2364",[12,2.279,26,3.65,30,2.264,38,2.605,83,1.4,94,2.392,114,4.342,117,0.778,139,2.854,165,4.187,194,3.668,210,3.211,211,2.621,221,3.389,224,3.444,229,2.419,271,2.613,276,3.444,285,4.335,402,4.295,469,4.033,473,2.086,514,3.562,659,3.73,660,3.035,737,3.226,770,3.771,775,2.841,867,2.995,886,3.938,978,2.239,1014,3.338,1028,3.444,1030,3.696,1200,3.771,1211,2.986,1355,4.388,1443,2.986,1535,5.116,1807,3.425,2118,3.908,2181,4.721,2230,3.168,2295,3.879,2316,3.197,2581,3.673,2881,2.843,2973,4.488,3103,4.861,3797,4.138,3918,4.215,4399,5.388,4443,4.541,4481,5.218,4485,5.603,4486,7.14,4487,7.667,4495,5.603,4499,6.232,4500,6.232,4501,6.232,4502,4.657,4503,4.789,4504,5.977]],["t/2367",[12,2.871,36,3.443,72,2.061,73,1.874,85,2.526,90,2.312,117,1.238,123,1.938,136,2.812,137,2.57,138,1.943,169,2.864,172,1.457,229,2.147,240,1.429,245,2.47,267,2.188,271,2.319,473,1.852,505,3.37,529,3.126,562,2.57,612,2.608,614,3.181,621,2.608,654,2.551,723,3.815,760,3.041,764,2.672,781,2.26,820,3.191,867,1.943,875,2.878,890,2.919,966,4.732,1036,3.443,1051,5.125,1056,3.674,1062,4.044,1115,3.707,1200,3.347,1283,3.523,1373,7.008,1473,8.062,1521,3.58,1530,6.057,1640,2.812,1678,3.162,1844,3.855,1976,3.144,2021,3.815,2145,3.551,2230,4.636,2234,4.384,2271,3.091,2288,3.496,2356,3.2,2581,3.26,2881,2.523,3246,5.125,3463,7.488,4399,4.959,4440,6.327,4443,4.031,4472,4.191,4477,4.974,4478,4.974,4505,5.532,4506,4.542,4507,7.848,4508,5.532,4509,4.845,4510,4.081,4511,5.306]],["t/2369",[1,1.406,22,2.189,30,2.02,38,2.113,49,4.324,83,1.653,84,2.889,85,1.627,115,1.984,117,0.631,123,1.771,137,3.418,138,1.775,148,3.164,150,5.001,156,2.034,172,1.331,175,2.749,187,1.864,190,2.84,193,2.119,195,3.729,196,3.593,197,2.681,199,3.56,200,3.683,206,3.147,214,2.007,236,3.56,240,1.306,473,1.692,504,3.147,529,2.013,530,2.525,586,2.581,612,1.68,628,4.683,630,3.147,659,2.211,660,2.462,764,2.442,781,1.455,809,1.873,881,3.452,955,2.432,957,2.182,978,1.816,1015,2.84,1115,4.929,1162,3.327,1175,3.778,1177,2.777,1211,2.422,1332,2.809,1471,2.856,1480,3.219,1596,2.126,1736,4.683,1819,3.101,1923,3.357,1943,3.357,1948,3.245,1990,4.324,2239,3.56,2271,2.824,2295,5.397,2466,4.006,2468,4.481,2649,4.075,2662,3.245,3058,4.075,3469,5.93,3770,4.15,3918,5.865,4399,5.479,4420,4.545,4421,4.545,4422,4.545,4440,4.075,4512,5.055,4513,5.055,4514,5.055,4515,4.848,4516,3.943,4517,7.796,4518,5.055,4519,4.848,4520,5.055,4521,5.055,4522,5.055,4523,5.055,4524,5.055]],["t/2371",[138,3.528,285,5.106,4406,9.032,4525,10.045]],["t/2373",[5,1.653,44,2.053,72,3.363,77,4.253,79,6.568,80,6.509,87,2.647,88,3.578,115,2.662,148,1.969,240,1.752,267,1.89,291,4.319,437,3.747,584,3.578,620,3.544,748,2.956,820,4.126,906,5.13,1281,4.221,1988,2.825,2388,5.21,2674,4.103,2861,4.775,3086,5.374,3366,5.942,4479,7.791,4484,5.068,4526,6.781,4527,6.781,4528,6.781,4529,10.148,4530,6.781,4531,6.097,4532,6.781,4533,6.781,4534,5.678,4535,6.781,4536,6.097,4537,6.781,4538,6.781,4539,6.781,4540,6.781,4541,6.781]],["t/2375",[44,2.019,72,2.949,79,5.122,80,6.14,115,3.107,148,2.298,267,2.206,525,4.472,719,4.005,781,2.279,820,4.666,906,5.671,1003,5.919,1273,3.522,1925,6.627,2062,3.936,2260,4.005,2284,6.498,3366,6.568,4484,5.915,4542,8.727,4543,7.915,4544,9.979]],["t/2377",[73,2.905,138,3.012,267,2.391,271,3.596,470,2.99,491,4.177,510,2.85,660,4.177,759,4.482,802,3.376,906,4.874,957,3.701,1530,5.695,1618,3.898,1788,5.55,2295,5.338,2723,5.022,2905,6.914,3516,6.689,3873,6.327,3918,5.801,4399,5.419,4443,6.249,4479,6.175,4542,6.327]],["t/2379",[1,1.625,5,0.527,7,1.696,27,2.7,30,0.504,34,1.539,38,0.904,39,1.476,44,1.792,48,0.955,51,1.236,72,0.805,73,0.732,79,2.412,80,4.047,85,0.696,87,0.844,88,1.141,95,0.93,115,0.849,117,0.822,126,0.962,138,2.052,139,0.724,148,1.696,150,1.024,152,1.893,153,1.388,156,1.031,160,1.228,172,2.147,174,3.452,187,1.811,194,1.603,198,2.094,201,1.266,202,1.743,206,1.346,210,1.403,213,1.062,214,0.858,218,1.48,219,1.4,229,0.839,236,1.522,238,1.423,240,0.559,243,1.1,245,1.664,248,1.336,250,2.241,259,1.254,262,1.146,263,1.319,267,1.369,285,1.894,291,1.377,297,1.644,338,2.059,402,0.955,421,1.593,436,1.491,437,1.195,443,2.345,452,1.104,470,2.036,481,2.597,488,0.83,492,2.963,495,1.032,514,1.236,529,1.484,530,1.08,532,1.522,560,1.075,562,2.282,565,1.436,576,1.37,582,1.356,584,1.141,586,1.104,602,1.539,612,1.239,613,1.228,614,1.243,620,1.948,636,2.182,649,1.861,660,1.815,666,1.016,668,1.583,671,1.215,688,1.743,748,1.625,753,1.02,769,2.475,781,1.073,794,4.033,802,2.594,820,2.375,821,1.686,822,1.7,861,1.476,867,0.759,875,1.801,886,1.366,890,1.141,895,1.346,906,2.118,908,3.03,923,0.646,942,2.143,953,1.838,967,1.539,969,1.228,991,1.08,993,2.563,1003,1.282,1009,1.991,1010,1.713,1019,1.141,1024,1.114,1027,1.539,1028,1.195,1030,1.282,1033,1.243,1049,1.411,1062,1.114,1149,3.12,1156,1.638,1169,2.453,1170,1.049,1172,2.073,1177,1.407,1187,2.686,1208,1.124,1211,1.036,1214,1.282,1231,2.059,1253,1.258,1271,2.225,1273,0.962,1279,1.411,1281,1.346,1327,1.377,1344,1.366,1417,1.462,1425,2.003,1431,1.152,1443,1.036,1449,1.236,1475,1.595,1476,1.944,1489,3.933,1552,3.537,1566,1.849,1599,1.751,1606,1.944,1613,1.686,1618,0.982,1629,1.539,1647,1.436,1701,1.686,1727,0.874,1778,1.158,1791,1.228,1807,1.188,1921,2.432,1935,1.661,1957,2.716,1967,2.791,1976,4.847,1984,2.954,1988,0.901,1989,1.423,2021,2.57,2032,1.228,2055,1.661,2074,2.57,2075,1.236,2218,1.893,2220,1.743,2230,1.099,2254,1.423,2271,2.082,2295,1.346,2298,1.661,2300,1.377,2304,1.894,2309,2.073,2313,2.453,2416,1.638,2468,1.317,2478,1.317,2569,3.188,2599,2.073,2813,2.716,2861,1.522,2903,4.256,2926,1.893,3028,1.506,3086,1.713,3104,3.624,3154,1.713,3249,1.893,3318,1.491,3366,2.453,3516,2.907,3847,2.003,4080,1.944,4270,5.233,4308,1.944,4339,1.893,4350,2.521,4416,1.944,4468,1.944,4479,1.557,4484,1.616,4503,1.661,4531,1.944,4534,1.81,4542,1.595,4545,2.162,4546,2.162,4547,2.162,4548,2.162,4549,2.162,4550,2.162,4551,2.162,4552,1.944,4553,2.162,4554,2.162,4555,2.162,4556,2.162,4557,2.162,4558,3.727,4559,2.162,4560,2.162,4561,1.944,4562,2.162,4563,3.727,4564,2.162,4565,2.162,4566,2.162,4567,2.162,4568,2.162,4569,2.162,4570,2.162,4571,1.944,4572,2.162,4573,3.188,4574,1.893,4575,2.162,4576,1.944,4577,2.162,4578,2.162,4579,2.073,4580,2.162,4581,2.162,4582,6.589,4583,2.162,4584,1.686,4585,2.073,4586,3.574,4587,1.893,4588,2.003,4589,3.574,4590,3.574,4591,3.727,4592,2.162,4593,1.522,4594,2.073,4595,2.162,4596,2.162,4597,2.162,4598,2.162,4599,2.162,4600,1.25]],["t/2381",[7,1.122,27,3.303,30,0.9,44,2.227,48,3.258,72,3.098,73,1.309,79,5.83,80,6.438,86,1.338,87,2.878,117,0.92,141,2.639,145,2.481,148,2.14,155,2.249,156,1.069,160,4.19,172,1.583,194,1.663,201,2.263,240,0.999,243,1.774,249,2.03,250,1.763,285,1.965,436,4.145,437,2.136,443,1.845,470,3.141,489,1.467,491,3.591,576,1.421,612,1.285,620,3.853,621,1.997,722,5.665,737,2.001,781,1.73,812,2.722,820,1.571,904,3.475,906,4.726,908,1.626,993,2.637,1003,2.292,1007,3.236,1009,1.567,1347,5.439,1417,2.614,1431,2.06,1449,2.209,1471,2.184,1547,2.307,1591,3.116,1599,1.816,1607,2.721,1617,2.614,1799,2.442,1949,3.769,1961,2.136,1967,2.196,1976,2.196,1984,3.063,1988,1.61,2075,2.209,2154,2.278,2254,2.544,2396,2.59,2557,3.015,2813,2.816,2932,3.58,3082,2.501,3102,5.751,3126,3.173,3366,4.853,3493,3.707,4270,5.851,4479,6.487,4536,5.403,4542,7.036,4552,8.1,4561,3.475,4571,3.475,4574,3.385,4576,3.475,4601,3.865,4602,3.865,4603,3.865,4604,3.865,4605,3.865,4606,7.373,4607,3.865,4608,3.865,4609,3.865,4610,6.01,4611,5.763,4612,3.865,4613,3.865,4614,3.306,4615,5.763,4616,3.58,4617,3.865,4618,3.865,4619,3.865,4620,3.865,4621,3.865,4622,3.58]],["t/2383",[115,3.463,142,6.778,172,2.323,249,4.633,461,5.166,463,3.424,491,4.296,538,3.185,802,3.473,817,5.374,969,5.013,978,3.169,1449,5.043,1599,4.146,1732,5.103,1735,6.428,2440,4.332,2581,5.199,2881,4.024,3078,6.084,4303,7.932]],["t/2385",[22,3.427,48,3.497,72,2.949,83,1.779,94,3.83,128,4.136,138,2.78,221,4.304,240,2.045,249,4.156,271,3.318,285,4.023,391,2.571,861,5.405,870,5.405,1015,4.446,1151,5.165,1178,6.77,1273,3.522,1629,5.635,1790,4.098,1844,5.515,1988,4.158,2223,5.699,2260,5.05,2298,6.081,3037,5.256,4270,4.856,4336,5.515,4337,7.116,4623,7.915,4624,7.915,4625,7.915,4626,7.915]],["t/2387",[83,1.968,85,2.819,138,3.076,271,3.672,285,4.453,491,4.266,520,5.162,645,4.132,694,4.867,759,4.578,868,4.894,906,4.978,908,3.684,978,3.147,1069,5.13,1776,5.195,1871,6.462,1988,3.649,2295,5.452,2723,5.13,3657,6.635,3918,5.924]],["t/2389",[43,2.685,115,2.662,142,5.21,144,4.353,148,2.946,150,3.211,172,1.786,187,2.5,193,3.785,197,3.596,265,4.19,267,1.89,412,2.632,483,2.936,529,2.701,620,3.544,659,2.966,668,2.88,787,3.237,802,3.995,820,2.757,834,2.88,978,3.887,1015,3.81,1024,4.652,1030,4.022,1033,6.221,1066,3.81,1132,5.21,1162,4.464,1177,2.56,1449,3.876,1715,3.127,1807,3.727,2055,5.21,2468,4.131,2478,4.131,3058,5.467,3236,4.883,4270,4.16,4317,5.801,4479,4.883,4484,5.068,4516,5.289,4517,6.097,4573,7.722,4627,5.467,4628,6.781,4629,6.282,4630,5.567]],["t/2392",[1,2.306,138,2.911,178,4.555,193,3.475,197,4.395,245,3.7,298,5.836,491,4.036,562,4.772,666,3.895,867,2.911,923,2.477,1904,4.765,1974,4.794,1976,4.709,2318,6.681,2570,5.049,2581,6.052,2881,4.684,2965,5.364,3078,5.716,3284,7.948,4399,5.237,4404,6.114,4449,7.258,4584,8.011]],["t/2394",[1,1.516,6,3.153,7,0.991,12,1.249,17,1.713,22,1.479,30,0.795,33,1.276,38,2.278,42,4.252,73,1.846,77,2.141,83,1.225,85,1.099,90,1.427,91,1.793,114,2.379,117,0.969,138,1.914,139,1.824,148,0.991,150,3.678,155,1.987,156,1.507,165,1.677,187,2.009,194,2.926,205,4.394,211,1.436,216,2.025,221,3.7,240,0.882,242,1.952,245,1.525,249,2.862,267,0.952,271,1.432,298,2.405,402,4.195,412,1.325,414,1.054,473,1.824,474,2.285,491,1.663,492,1.535,510,1.135,529,2.171,562,3.161,565,2.268,576,1.256,584,1.802,594,2.379,613,1.941,615,1.423,619,2.822,621,1.135,649,1.706,659,3.712,670,2.771,697,1.829,734,4.799,737,1.768,753,1.611,760,1.877,763,2.459,770,2.066,775,2.827,785,2,802,1.344,978,2.444,1004,4.363,1009,1.384,1033,1.963,1037,2.355,1049,2.229,1066,1.918,1071,2.025,1072,1.963,1097,2.542,1143,2.753,1174,2.706,1177,1.289,1199,2.921,1200,2.066,1211,2.612,1231,1.887,1260,2.431,1386,2.379,1431,1.82,1473,2.459,1477,3.212,1483,4.79,1489,2.039,1521,2.21,1535,2.803,1629,2.431,1685,2.706,1698,4.692,1717,2.405,1727,1.38,1735,2.488,1755,3.07,1791,1.941,1807,1.877,1871,2.519,1904,3.134,1948,4.985,1974,1.975,2062,2.711,2145,2.192,2151,2.859,2157,2.759,2171,1.656,2230,2.771,2260,1.728,2295,3.393,2305,2.126,2328,2.459,2380,2.89,2395,3.163,2496,2.552,2881,4.497,2923,2.488,2965,3.528,2973,4.899,2975,3.418,3078,2.355,3128,2.803,3266,6.524,3659,2.126,3741,2.431,4322,2.706,4341,2.552,4358,2.859,4399,4.299,4404,4.021,4439,2.921,4443,2.488,4452,2.991,4471,2.624,4584,2.664,4631,2.859,4632,3.07,4633,3.415,4634,5.451,4635,3.415,4636,3.415,4637,3.415,4638,3.415,4639,3.415,4640,3.415,4641,5.451,4642,3.415,4643,3.415,4644,3.415,4645,3.415,4646,3.415]],["t/2396",[1,2.219,6,4.613,26,4.67,30,1.318,83,1.272,90,3.86,117,0.995,151,3.576,156,1.565,161,5.242,172,2.1,221,3.078,229,2.197,240,1.462,245,2.527,267,2.574,427,3.179,470,1.973,473,2.669,508,5.25,612,1.881,615,2.358,649,3.983,659,2.475,770,5.588,787,2.701,809,2.097,814,3.061,911,4.175,978,3.797,993,4.053,1014,3.031,1072,3.254,1097,2.639,1099,4.287,1231,3.127,1239,3.725,1331,2.6,1415,4.348,1449,3.235,1717,3.985,1760,4.956,1791,3.216,1807,3.11,1825,3.758,1838,3.758,1974,3.274,1976,3.216,1988,2.358,2032,3.216,2121,3.943,2157,2.864,2179,4.414,2230,4.054,2232,4.287,2316,4.737,2415,3.497,2570,3.448,2619,3.11,2624,5.088,2812,4.485,2815,3.549,2881,2.581,2888,5.088,2934,3.693,2975,3.549,3662,4.124,3931,4.075,4391,5.088,4430,5.088,4632,7.171,4647,5.659,4648,5.088,4649,5.659]],["t/2398",[997,4.039,1332,5.536,2754,6.113,3070,7.351,3071,6.07]],["t/2400",[172,2.258,208,2.877,209,3.97,257,6.496,259,2.644,287,2.641,734,5.299,820,3.487,910,5.856,997,4.252,1168,6.106,1612,4.991,1614,6.106,1773,5.262,2163,7.511,2183,7.181,3594,7.711,8472,9.716]],["t/2403",[1,2.094,11,2.955,21,2.462,83,1.692,86,3.345,93,3.992,180,2.753,199,5.301,243,2.222,245,3.361,250,4.409,487,3.409,489,2.858,496,4.651,557,3.166,621,2.502,646,4.253,668,3.196,809,2.79,820,3.061,868,4.205,882,4.328,1988,3.136,2152,4.757,2180,4.242,2815,6.061,4691,6.439,4914,5.966,5035,6.973,5649,7.219,6143,7.792,8516,7.94,8517,8.567,8518,8.567,8519,7.219,8520,8.567,8521,8.567,8522,7.94,8523,8.567,8524,7.528]],["t/2405",[1,1.448,5,1.269,44,1.053,48,2.3,77,3.264,78,4.294,83,1.688,86,3.051,93,2.76,117,1.1,193,2.182,196,1.771,240,1.345,243,1.536,250,4.669,268,3.456,271,2.182,285,2.646,296,3.308,297,2.951,323,3.107,400,5.334,411,2.542,414,1.606,415,5.29,421,2.224,425,3.397,461,3.048,526,2.21,527,2.844,576,2.762,579,2.189,735,4.546,744,3.149,786,3.171,788,3.705,809,3.794,819,3.59,985,1.775,998,1.738,1037,3.59,1104,4.06,1211,2.494,1334,3.89,1712,3.216,1727,2.104,1801,4.485,1816,2.577,1841,2.175,1942,3.426,2154,3.067,2155,3.59,2157,2.634,2164,5.205,2165,3.89,2168,4.358,2188,5.954,2263,2.72,2456,3.59,2484,3.488,2578,4.125,2668,5.954,2674,3.149,2684,5.86,2717,4.452,2768,4.358,2784,4.452,2819,4.273,3036,3.626,3046,5.49,3110,5.49,3114,5.49,3182,5.49,3325,5.205,5035,4.821,5997,4.68,8114,4.196,8525,5.923,8526,5.923,8527,5.923,8528,5.923,8529,5.923,8530,5.923]],["t/2407",[2,5.012,12,3.549,30,1.764,87,2.956,89,5.029,117,0.945,235,4.141,259,1.626,266,3.704,287,2.332,296,3.511,297,2.535,470,2.641,473,2.535,487,4.394,527,2.867,561,7.264,659,3.313,735,4.582,741,6.633,749,7.016,767,5.075,785,4.435,809,2.807,875,2.777,909,5.333,997,3.07,1239,4.985,1307,4.68,1486,6.106,1816,4.805,2188,6.003,2191,5.277,2316,3.885,3465,6.218]],["t/2409",[11,2.263,12,2.955,14,3.488,19,3.398,30,1.343,72,2.148,73,1.953,83,2.096,84,3.295,93,3.057,115,3.172,117,0.719,118,2.448,123,2.02,175,4.394,180,2.955,210,2.171,219,2.165,250,4.255,259,1.237,262,3.057,265,3.562,287,1.775,296,1.734,297,1.93,318,4.104,411,2.128,429,4.733,438,3.152,473,1.93,489,2.189,492,2.592,528,3.152,545,6.12,597,2.53,626,3.522,659,2.522,735,3.488,757,3.169,809,2.136,818,3.355,834,2.448,882,4.646,998,2.698,1055,2.472,1069,5.463,1125,4.349,1185,3.795,1401,3.488,1455,3.731,1487,4.253,1618,4.239,1753,3.257,1841,3.377,1918,3.398,1921,3.762,1937,5.529,1949,3.615,1950,4.733,1977,5.049,2062,2.867,2182,3.762,2188,4.569,2522,4.648,2915,4.497,3508,5.341,3607,5.887,3680,3.828,5984,5.765,6029,7.485,6043,4.932,6571,6.081,8075,5.341,8402,4.497]],["t/2411",[1,3.034,21,2.992,181,4.61,208,3.07,250,4.173,473,3.062,1056,6.076,1074,6.667,1125,4.925,1732,5.293,2152,5.782,6996,8.476,7002,9.651,8531,9.15,8532,10.413]],["t/2413",[21,2.785,117,1.063,196,2.898,208,2.857,214,3.382,219,3.198,250,4.764,290,5.341,354,6.75,398,3.571,487,3.857,627,4.218,639,5.019,663,4.2,818,4.957,978,3.06,1332,4.732,1490,6.75,1559,7.459,2191,5.934,2257,6.866,3324,8.517,3592,8.517,8533,9.693,8534,8.984]],["t/2415",[11,3.789,85,3.107,116,5.093,128,5.044,180,3.53,487,4.371,489,4.273,5035,8.941]],["t/2417",[47,3.771,93,4.888,116,4.864,180,3.372,240,2.382,681,5.594,967,6.563,3071,5.616,3506,4.75,8447,9.218,8483,7.885,8535,10.491,8536,10.491,8537,10.491]],["t/2420",[85,3.292,89,5.467,93,4.365,116,4.344,177,4.282,180,3.741,240,2.127,410,6.421,489,3.125,568,4.574,619,4.262,659,4.473,663,4.059,681,5.222,853,8.683,923,2.46,993,3.613,1370,5.467,1477,4.851,1618,3.741,3506,5.27,5061,8.683,7702,10.227,8483,7.042,8538,9.369]],["t/2422",[3,3.768,22,4.761,83,1.802,93,4.251,139,2.684,209,3.711,259,1.721,488,3.077,787,3.827,997,3.25,1612,4.666,1629,5.708,1829,4.71,1842,8.423,2185,6.354,2186,5.475,2619,4.407,3071,7.024,3709,7.209,6143,6.463,8436,11.389,8465,8.018,8539,9.125,8540,9.125]],["t/2424",[5,1.955,22,3.472,48,3.543,85,2.581,93,4.251,154,7.973,180,2.933,193,3.362,196,2.728,296,2.412,297,2.684,330,3.873,474,3.362,487,3.631,489,3.044,649,4.005,775,2.671,786,4.885,809,2.971,997,3.25,1014,4.294,1135,5.773,1185,5.278,1477,4.725,1599,3.768,1708,6.858,2143,6.16,2180,3.519,2440,3.937,2456,5.53,3075,7.209,3236,7.244,4914,6.354]],["t/2426",[1,1.658,11,2.34,12,2.18,25,3.491,27,3.276,86,2.063,87,2.327,94,2.288,139,1.995,156,2.287,172,1.57,193,2.499,196,2.028,208,2,209,2.759,219,3.566,243,1.759,259,1.775,287,3.691,288,3.89,304,3.796,318,4.244,330,2.879,400,3.606,414,2.931,463,2.314,489,2.263,495,2.845,544,3.407,576,2.192,598,3.145,607,2.58,637,3.513,652,4.451,668,3.512,679,3.427,761,4.805,775,1.986,801,4.197,908,2.507,923,1.782,1031,3.958,1045,6.101,1055,3.546,1118,4.454,1273,2.652,1331,2.739,1445,4.724,1640,3.03,1732,3.448,1841,3.969,1924,2.927,2174,4.723,2337,3.582,2879,4.805,2923,4.343,3252,3.71,7128,6.924,8295,5.359,8541,6.784,8542,4.58,8543,5.961,8544,5.522]],["t/2428",[30,2.231,87,4.373,428,10.102,573,6.25,788,6.818,2016,6.826,3092,9.577,8545,10.899]],["t/2430",[41,5.195,1257,7.672,4100,7.38]],["t/2432",[4,4.383,8,6.889,11,3.619,19,6.456,22,3.992,27,5.066,116,4.864,222,5.966,467,7.718,499,6.717,562,4.283,652,4.962,790,6.423,1846,6.358]],["t/2434",[3,3.626,4,3.668,12,2.822,19,4.547,20,3.958,24,4.311,51,4.411,106,4.264,126,3.433,139,2.583,178,4.241,214,3.064,411,2.032,429,6.335,538,2.786,560,3.837,668,3.277,911,5.692,1033,4.437,1070,4.411,1071,4.577,1169,5.079,1239,5.079,1260,5.493,1263,7.148,1654,7.4,1730,6.938,2191,5.376,3582,7.716,3584,7.716,3585,8.139,3586,8.139,3587,8.139,8439,7.148,8546,7.4,8547,11.176,8548,8.782,8549,8.139,8550,8.139,8551,8.782]],["t/2436",[21,2.948,85,3.48,350,7.557,576,3.315,681,4.604,760,4.955,997,4.977,1025,5.123,1923,5.987,2168,7.549,8552,10.261]],["t/2451",[4,4.383,8,6.889,11,3.619,19,6.456,22,3.992,27,5.066,116,4.864,222,5.966,467,7.718,499,6.717,562,4.283,652,4.962,790,6.423,1846,6.358]],["t/2454",[259,2.105,420,6.059,997,3.975,1528,7.428,2359,6.832,2754,6.016,3068,8.588]],["t/2456",[12,2.933,172,2.111,208,2.69,209,3.711,219,3.011,257,6.073,259,2.669,287,2.469,420,6.216,520,4.725,599,5.842,734,4.954,820,3.26,910,5.475,997,4.457,1168,5.708,1614,5.708,1773,4.919,2163,7.022,2183,6.713,2237,6.073,8472,7.427,8553,9.125,8554,9.125,8555,9.125]],["t/2459",[11,3.21,83,1.838,86,3.525,180,2.991,243,2.414,487,3.703,489,3.104,557,3.439,735,4.948,923,2.444,986,6.111,999,7.352,1055,3.506,1829,3.828,1988,3.407,2133,6.194,2180,4.868,2188,6.481,2815,6.387,4914,6.481,4942,6.481,4998,7.162,5143,7.162,6143,8.211,8556,8.626,8557,9.307,8558,9.307]],["t/2461",[2,5.588,5,1.777,7,1.45,12,2.667,30,2.006,83,1.935,90,2.087,106,4.758,117,1.074,128,2.61,208,2.446,209,2.311,296,3.756,297,2.44,315,5.444,330,2.412,411,1.92,414,2.658,452,2.55,497,3.639,527,3.26,538,1.803,546,3.316,571,2.805,576,2.68,612,2.423,615,2.081,618,3.108,630,3.108,781,2.099,818,4.243,914,2.462,953,2.462,971,3.021,985,2.937,997,3.49,1131,4.607,1147,4.181,1185,3.287,1205,2.585,1352,3.732,1417,3.378,1421,2.774,1586,4.167,1829,3.413,1958,3.086,1988,3.038,2163,4.373,2174,2.483,2182,3.259,2184,8.258,2340,4.994,2345,4.272,2662,3.206,2720,5.267,2812,3.958,2815,3.132,2854,3.41,3117,4.49,3509,4.789,8559,5.683,8560,5.267]],["t/2463",[1,1.539,2,3.674,11,2.172,30,1.828,32,4.384,72,3.698,117,0.979,122,2.57,148,1.606,166,3.162,203,4.575,204,4.46,208,1.856,209,2.561,240,1.429,271,4.162,279,4.315,290,6.827,296,1.664,391,1.797,398,3.29,402,2.445,427,4.409,463,2.147,487,2.505,489,2.1,495,2.64,521,2.717,526,3.333,527,2.971,557,2.327,607,1.726,622,3.325,626,3.421,696,4.632,734,3.418,735,3.347,748,2.412,759,2.891,802,3.09,814,3.012,816,2.57,873,3.26,877,4.998,923,1.653,1035,3.641,1055,3.911,1185,5.166,1362,4.081,1396,3.58,1618,4.145,1624,4.845,1668,4.384,1829,2.59,1853,3.855,1935,4.251,1961,3.057,1988,2.305,2133,4.191,2188,4.384,2271,4.385,2456,3.815,2881,3.58,3460,5.532,3463,4.542,3695,4.632,4310,5.306,4948,4.732,8117,4.732,8342,5.835,8561,6.296,8562,6.296,8563,6.296]],["t/2465",[250,4.236,259,1.993,414,3.396,526,3.944,1055,3.982,1918,6.485,1919,6.471,1951,8.351,1957,6.768,1988,3.87,2467,6.282,8564,10.57]],["t/2468",[1,1.546,2,2.602,7,1.613,11,2.181,12,2.033,72,2.07,73,3.097,83,1.769,89,3.69,114,3.872,117,0.693,118,2.36,170,3.409,180,3.344,211,2.337,219,2.957,221,4.973,250,2.535,271,4.17,285,5.056,297,1.86,391,1.805,411,1.463,414,2.822,421,2.375,422,3.195,427,3.122,487,2.517,489,2.11,511,2.877,527,2.104,615,2.315,748,2.422,785,3.254,814,2.133,1014,2.976,1045,4.1,1069,3.254,1170,2.695,1181,3.215,1211,2.663,1231,3.071,1238,4.48,1579,4.1,1618,2.526,1791,3.158,1808,4.562,1838,3.69,1918,3.275,1973,5.148,2022,4.404,2121,6.371,2230,2.825,2260,2.812,2443,3.511,2518,3.596,2531,4.1,2619,3.054,2751,3.724,2812,4.404,2815,3.485,2871,5.329,2881,2.535,2888,7.079,2907,5.669,2910,5.964,2944,4.404,2974,5.148,3098,3.795,3366,3.658,3767,4.996,3931,4.002,4266,5.964,4404,4.1,4484,4.153,4503,4.27,8062,4.562,8565,6.324,8566,6.324,8567,5.329,8568,6.324]],["t/2470",[2,5.017,27,4.884,30,2.07,123,3.113,208,3.595,209,4.113,296,3.224,315,5.109,666,5.036,1097,4.144,1104,6.931,1829,4.16,2292,7.989,2340,8.886,2345,7.601,2468,5.413]],["t/2472",[19,4.787,83,1.825,93,4.308,211,3.417,240,2.099,259,2.177,287,2.502,297,2.719,351,4.984,408,5.215,411,2.139,438,4.441,443,3.877,454,5.85,472,5.919,513,5.094,526,3.449,528,4.441,576,2.987,626,3.541,629,4.59,822,3.705,831,4.513,875,2.979,912,4.351,997,3.293,998,2.713,1307,5.02,1640,4.129,1923,5.394,3337,4.513,5498,4.671]],["t/2474",[1,2.174,24,4.366,25,4.576,34,5.563,35,5.389,48,3.453,83,1.756,87,3.05,97,2.745,177,4.065,208,2.622,210,2.943,240,2.019,259,1.677,296,2.35,297,3.636,397,6.573,402,3.453,411,2.058,463,3.033,526,4.203,527,2.958,532,5.502,668,4.203,678,4.761,820,3.177,1069,4.576,1918,4.605,2573,7.721,5282,7.239,8220,7.494,8569,8.243,8570,8.243]],["t/2476",[7,2.377,12,2.149,14,6.167,19,3.462,21,1.921,30,1.368,48,2.596,73,1.99,83,1.32,93,3.115,117,1.021,155,3.419,168,3.108,180,2.149,181,2.96,187,2.166,219,2.206,224,3.247,245,3.656,250,2.68,259,2.023,304,5.214,391,1.908,411,1.547,438,4.476,443,2.804,474,2.463,526,4.328,530,2.934,541,3.974,555,2.425,576,2.16,579,2.471,607,1.833,626,2.561,660,2.861,740,3.071,781,2.357,908,2.471,1011,3.485,1029,3.802,1069,3.441,1252,4.334,1439,4.052,1465,3.014,1473,4.231,1519,3.771,1809,4.919,1816,2.909,1916,6.118,1918,6.007,1919,6.566,1927,5.443,1943,3.902,1949,5.134,1950,8.799,1951,5.283,1954,3.462,1957,4.281,2215,4.514,2243,5.146,2467,5.538,2573,4.583,8571,6.687]],["t/2478",[11,3.789,85,3.107,116,5.093,128,5.044,180,3.53,487,4.371,489,4.273,4998,8.453]],["t/2480",[47,4.011,93,5.199,116,5.174,180,3.586,681,5.801,8483,8.388]],["t/2482",[2,3.635,5,1.893,17,5.434,18,5.966,19,4.576,20,3.983,73,2.63,93,4.117,117,0.969,180,2.84,211,3.266,240,2.006,296,2.336,391,2.522,410,6.057,461,4.547,473,2.599,529,3.092,568,4.314,626,3.385,759,4.058,766,5.658,822,3.542,1055,3.329,1071,4.605,1211,3.721,1214,4.605,1445,6.154,1477,4.576,1701,6.057,2178,6.501,2221,7.193,3506,5.081,3507,7.765,8422,7.765,8572,8.191,8573,8.837]],["t/2484",[4,3.493,22,4.57,28,4.176,73,2.489,168,2.79,209,3.401,221,3.996,410,7.423,488,4.051,551,6.435,564,4.879,668,3.12,735,4.446,786,4.476,997,2.979,1042,7.047,1055,3.151,1075,4.837,1231,4.06,1249,4.387,1490,5.824,1843,8.109,1988,3.061,2062,3.654,2142,6.607,2168,6.152,2186,5.018,2815,4.608,2898,9.516,3037,4.879,4713,4.924,5950,5.174,6143,5.923,6682,7.348,8436,7.047,8574,7.047,8575,8.362,8576,8.362,8577,7.047,8578,8.362,8579,8.362]],["t/2486",[2,3.175,7,1.969,11,2.662,47,2.774,115,2.662,123,2.376,179,4.544,208,3.405,211,2.852,218,2.693,229,2.632,249,3.561,259,1.456,296,2.04,336,10.023,419,3.527,487,4.088,488,3.465,521,3.33,526,2.88,538,2.449,597,2.976,627,4.471,646,3.831,734,4.19,764,3.276,816,3.151,887,4.775,1011,4.022,1069,3.971,1249,4.048,1290,6.282,1307,4.19,1374,5.003,1618,3.082,1712,4.19,1732,3.923,1813,4.426,1829,4.226,1853,4.725,2210,5.567,2440,3.33,3076,5.374,4317,5.801,7901,6.097,8037,8.331,8138,9.028,8258,6.781,8395,5.939,8580,7.718,8581,7.718]],["t/2489",[19,5.162,73,2.967,93,4.645,213,4.301,259,1.88,263,3.099,297,2.932,438,4.789,443,5.071,762,6.832,786,6.473,896,5.452,997,3.551,998,2.925,1214,5.195,1276,6.832,1307,5.412,1640,4.453,1878,6.103,3028,6.103]],["t/2491",[24,4.859,95,4.551,139,2.911,187,3.206,220,4.78,287,2.678,420,5.374,473,3.541,496,5.374,562,4.041,637,5.125,652,5.694,679,5.001,745,5.998,1071,5.158,1260,6.192,1449,4.971,2662,5.583,2926,7.617,4593,6.124]],["t/2493",[0,6.62,1,2.321,2,4.828,83,1.875,123,2.923,187,3.076,245,3.725,259,1.791,271,3.498,296,2.51,297,2.793,427,4.688,471,5.591,1069,4.886,1566,7.137,1916,6.235,1923,5.541,2171,4.047,2183,6.986,2921,6.613,3595,6.008,8582,9.496,8583,9.496,8584,9.496,8585,11.737,8586,9.496]],["t/2495",[7,2.598,12,3.274,21,3.52,196,3.046,207,6.372,211,3.764,250,4.082,304,5.7,621,2.975,626,3.902,641,8.154,781,2.577,1019,4.723,1029,5.792,1519,5.745,2215,6.877,3675,7.348]],["t/2497",[1,1.876,11,2.647,12,2.467,15,5.785,172,1.776,180,2.467,208,3.395,209,3.122,243,1.991,259,2.172,287,3.563,315,3.878,419,3.508,452,3.444,473,2.257,487,4.073,489,2.56,513,4.229,527,2.553,568,3.747,576,3.307,627,3.34,649,3.368,781,1.942,895,4.198,953,3.326,955,3.245,969,3.832,1013,3.63,1045,4.975,1069,3.949,1089,6.845,1131,4.262,1267,4.561,1278,4.053,1294,6.064,1417,4.561,1591,5.437,1618,3.065,1831,6.247,2174,3.354,3259,4.801,3506,3.475,4169,4.229,8144,6.064,8572,9.488,8587,7.675,8588,7.675]],["t/2499",[87,3.653,97,3.287,117,1.168,259,2.009,409,9.871,420,5.783,492,4.208,923,2.797,997,3.794,2016,5.701,2669,8.196,4998,8.196,8534,9.871]],["t/2502",[1,1.699,5,1.489,6,3.533,22,4.488,30,1.423,72,2.276,83,1.373,93,3.239,117,1.049,180,3.518,214,3.34,217,5.356,240,1.578,271,4.033,285,4.89,469,5.443,505,3.721,576,2.246,770,3.696,786,3.721,955,4.047,978,3.022,991,3.051,1014,3.271,1170,2.963,1233,4.693,1286,3.671,1640,3.105,1708,5.225,1791,4.78,1988,2.545,2060,3.512,2152,3.86,2164,6.108,2230,3.105,2260,4.257,2316,4.935,2415,6.716,2812,7.624,2815,5.275,2888,5.492,2910,4.627,3030,6.057,3037,4.056,3931,4.399,3945,6.108,4311,5.492,4448,5.659,6335,6.443,8589,9.572,8590,6.952,8591,6.952,8592,4.924,8593,6.952,8594,6.952]],["t/2504",[2,2.86,5,1.489,7,1.773,11,2.398,20,3.133,28,3.471,83,1.373,93,4.46,117,1.049,128,3.192,194,2.628,214,2.426,219,2.294,229,2.371,240,1.578,241,3.748,296,2.53,297,2.045,315,6.25,316,4.451,323,3.647,330,2.951,391,2.732,410,4.765,411,1.609,421,2.611,422,3.512,461,3.577,463,2.371,473,2.815,482,3.774,488,2.345,535,3.921,555,2.522,612,2.03,621,2.03,628,5.659,681,3.119,734,3.774,818,3.555,822,2.786,868,3.413,985,2.084,997,3.899,998,2.04,1014,3.271,1018,4.506,1055,3.606,1131,5.315,1170,2.963,1208,3.177,1214,3.623,1307,5.197,1727,2.469,1816,3.025,1829,2.86,2062,3.038,2154,3.6,2174,4.784,2186,4.171,2386,4.765,2396,4.093,2668,4.841,3507,6.108,3508,5.659,3671,4.213,8595,6.952]],["t/2506",[7,2.839,14,4.64,25,4.491,51,4.383,139,2.567,168,2.911,186,3.536,239,4.128,240,1.981,250,3.498,259,1.646,391,2.491,445,4.738,463,2.976,473,2.567,495,5.14,526,4.153,554,6.077,564,5.092,607,2.393,629,4.333,671,4.308,775,2.555,867,2.693,1015,4.308,1205,3.97,1308,4.409,1579,5.657,1599,4.596,1761,7.668,1918,5.764,1919,5.343,2484,5.138,3654,8.089,4266,5.809,8012,7.354]],["t/2508",[4,4.383,8,6.889,11,3.619,19,6.456,22,3.992,27,5.066,116,4.864,222,5.966,467,7.718,499,6.717,562,4.283,652,4.962,790,6.423,1846,6.358]],["t/2510",[5,1.955,22,3.472,28,5.717,43,3.983,93,4.251,117,1,123,2.809,128,4.19,139,2.684,163,5.443,208,3.688,209,4.657,212,7.022,233,6.582,398,3.362,410,6.254,670,4.076,734,4.954,809,3.728,997,3.25,1062,4.132,1231,4.43,1478,4.885,1623,7.209,1792,5.708,2186,5.475,2999,6.254,8468,8.457]],["t/2512",[3082,6.664]],["t/2514",[0,4.001,1,2.704,2,2.918,3,2.929,4,2.963,5,2.37,15,3.562,30,1.452,118,2.646,139,2.086,172,2.246,211,2.621,214,2.475,235,3.407,240,1.61,259,1.83,287,3.371,288,4.067,418,3.562,452,3.182,463,2.419,473,2.854,474,2.613,483,2.699,491,3.035,495,4.64,527,2.36,531,3.521,540,5.977,579,2.621,583,5.773,585,4.437,638,6.46,668,2.646,729,5.024,756,3.355,820,3.467,879,4.102,912,4.567,1273,2.773,1349,4.001,1369,5.218,1398,5.343,1623,5.603,1711,4.001,1712,3.851,1769,5.116,1812,3.627,2007,5.977,2117,5.218,2191,4.342,2363,4.598,2940,5.116,2943,5.773,3337,3.463,3503,5.024,3581,5.773,4651,6.574,8596,7.093,8597,7.093,8598,6.232]],["t/2516",[24,5.392,86,3.34,138,3.39,259,2.072,474,4.047,495,4.607,496,5.964,1398,6.186]],["t/2518",[1,2.369,21,2.785,116,4.494,208,3.504,240,2.2,287,2.623,449,6.866,473,2.851,474,3.571,495,4.065,520,5.019,654,3.928,764,4.114,998,2.844,1031,5.656,1070,4.868,1386,5.934,1398,4.681,1418,3.928,1552,6.133,1769,6.992,1812,4.957,1959,6.992,3337,4.732,7893,7.889]],["t/2520",[1,3.231,3,2.761,4,2.793,5,1.432,12,2.149,15,3.358,33,2.195,44,1.189,47,2.403,105,4.514,123,2.058,156,1.625,180,2.149,208,1.971,221,3.195,233,6.721,234,11.099,259,2.023,263,2.079,266,2.873,288,3.834,345,4.736,349,4.823,350,3.834,486,3,487,3.708,490,4.772,495,2.804,526,4.551,559,5.443,606,3.937,1134,4.391,1398,3.229,1546,4.281,1808,4.823,2608,4.334,3270,5.635,3798,5.026,4325,4.391,4448,9.928,5282,7.584,7513,5.635,7517,6.197,8599,6.197,8600,6.687,8601,6.687,8602,6.687,8603,6.687,8604,6.687,8605,6.687,8606,6.687,8607,6.687,8608,6.687,8609,6.687,8610,6.687,8611,6.687,8612,6.687,8613,9.318,8614,6.687,8615,6.687,8616,6.687,8617,6.687]],["t/2522",[0,5.59,1,1.788,3,3.02,5,1.567,15,4.978,86,3.418,88,4.595,172,1.693,194,2.765,240,2.25,259,2.448,287,2.682,315,5.007,402,2.84,418,3.674,420,3.972,469,4.16,481,4.478,486,3.282,487,3.944,495,5.053,513,4.031,514,4.978,527,2.433,531,3.631,579,3.663,612,2.136,627,3.183,638,4.869,787,4.157,874,3.972,987,2.613,1052,4.683,1114,4.268,1177,2.427,1398,6.081,1421,3.571,1923,4.268,1989,4.231,3337,3.571,3501,5.181,3503,5.181,3506,3.312,4285,4.869,5498,3.696,8598,6.427,8618,6.78,8619,6.78,8620,6.78]],["t/2524",[0,4.953,1,2.732,2,3.612,4,3.668,21,2.523,86,2.67,88,4.072,90,3.225,209,3.572,257,5.845,258,3.352,259,2.318,287,3.024,398,3.235,585,5.493,607,2.408,732,2.765,745,5.322,1148,6.22,1273,3.433,1327,4.914,1778,4.133,1924,3.789,2024,5.692,2174,3.837,2197,5.766,2453,6.408,3037,5.124,3067,5.766,3506,3.976,3528,6.758,4285,5.845,4600,4.463,8621,9.417,8622,6.938]],["t/2526",[0,6.224,1,2.902,2,3.978,15,3.544,21,2.028,43,2.455,88,4.484,118,2.633,123,2.172,137,2.881,187,2.286,259,2.48,266,3.032,287,3.365,469,4.013,495,2.96,531,3.503,564,4.118,582,3.888,636,3.631,637,3.654,638,4.697,745,4.276,754,4.914,809,2.298,840,3.804,892,3.654,1131,3.918,1272,4.837,1273,2.759,1302,4.194,1574,5.947,1586,3.544,1605,5.947,1832,4.634,1908,5.744,1970,6.201,2060,3.565,2174,5.434,2182,4.047,2237,4.697,2723,6.108,3506,4.379,4265,4.697,5498,4.886,8621,5.947,8622,5.575,8623,5.575,8624,5.431,8625,5.304,8626,6.201,8627,5.947,8628,5.947,8629,6.201]],["t/2528",[86,3.12,88,4.757,90,3.768,259,2.32,732,3.231,1131,5.697,2174,4.484,2453,7.056,3071,5.493,3506,4.646,4297,6.927,4600,5.215,5012,7.549,5498,5.184,8626,10.811]],["t/2530",[0,5.113,1,2.216,86,3.468,90,3.329,259,2.151,287,2.453,474,3.34,495,4.782,560,3.962,575,3.715,585,5.671,597,3.496,627,3.945,732,2.854,740,4.163,816,3.701,840,4.887,1418,3.674,1421,4.426,1910,5.338,1923,5.29,2074,5.494,2174,3.962,2197,5.953,2453,5.199,3506,4.105,4600,4.608,5498,4.58,8622,7.162,8627,9.609,8630,7.162,8631,7.966]],["t/2532",[86,3.314,90,4.003,259,2.056,732,3.432,2174,4.763,2453,6.25,3506,4.935,4600,5.54,5498,5.506,8628,9.184]],["t/2534",[86,3.053,90,3.687,259,2.29,544,5.043,560,4.387,732,3.161,768,5.709,809,3.269,1778,4.725,1924,5.24,2174,4.387,2197,6.593,3506,4.546,4265,6.683,4600,5.103,5498,5.072,8629,10.671,8632,10.04]],["t/2536",[5,1.583,15,3.713,43,2.572,83,1.46,86,2.248,88,3.427,90,2.715,123,2.276,156,2.425,259,2.383,287,3.42,338,3.589,402,2.87,404,4.136,406,3.67,492,2.92,513,4.073,546,4.313,571,3.649,668,2.758,671,3.649,732,2.327,753,3.064,809,2.407,822,4,1118,4.854,1131,4.104,1273,2.89,1402,4.435,1841,4.15,2024,4.792,2169,5.556,2174,3.23,2770,3.176,3067,4.854,3070,4.792,3071,6.478,3256,3.57,3506,5.117,3600,7.745,3656,5.236,3932,4.991,4297,4.991,4506,5.332,4600,3.757,5012,5.438,5419,5.438,5441,5.84,5444,5.84,8622,5.84,8633,6.229,8634,5.556]],["t/2538",[86,3.421,90,4.131,471,6.623,3506,5.094,4600,5.718,8635,9.156]],["t/2540",[12,2.414,17,3.311,86,3.068,88,3.482,90,2.758,94,2.533,115,2.591,117,0.823,122,4.651,123,2.312,126,2.936,187,2.433,259,1.903,287,3.083,402,3.917,414,2.037,463,2.561,488,3.403,599,4.809,732,2.365,753,3.113,875,2.42,985,2.251,998,2.96,1083,4.552,1170,3.201,1263,6.113,1273,3.944,1422,5.526,1723,4.271,1727,2.667,1750,4.344,1961,3.647,2171,3.201,2174,3.282,2204,5.418,2238,5.78,2359,4.598,3256,3.627,3506,3.401,3671,4.552,3745,5.526,3746,5.148,4297,5.071,4600,3.818,8542,8.579,8634,5.645,8636,8.502,8637,7.511,8638,6.961,8639,6.329,8640,7.511,8641,7.511]],["t/2542",[86,3.421,90,4.131,471,6.623,3506,5.094,4600,5.718,8635,9.156]],["t/2544",[1,1.424,11,2.914,12,1.872,33,1.912,85,2.389,88,3.917,122,2.378,156,1.415,168,1.943,193,2.146,201,2.997,208,2.49,210,1.927,240,1.322,243,1.511,259,2.612,266,2.503,287,3.517,398,3.112,411,1.348,414,2.291,469,3.312,487,2.318,488,3.352,542,3.877,555,3.064,585,3.644,599,3.729,611,2.443,627,3.676,732,2.66,743,4.056,814,2.849,816,2.378,1118,3.825,1131,3.234,1148,4.126,1272,3.992,1273,2.277,1605,4.909,1778,2.741,1841,3.65,1924,3.645,2006,2.65,2060,2.943,2130,3.825,2174,5.769,2380,2.714,2723,5.609,3252,3.186,3506,3.825,3600,3.992,5498,4.268,8542,3.933,8623,4.602,8624,4.482,8625,4.378,8635,6.876,8636,4.909,8642,5.118,8643,6.5,8644,4.909,8645,4.909,8646,4.909,8647,4.602,8648,5.118,8649,5.118,8650,5.118,8651,5.118]],["t/2546",[1,1.876,5,1.644,7,1.958,10,2.793,12,2.467,86,2.334,88,3.559,90,2.819,115,2.647,137,3.133,156,1.865,170,4.138,187,2.486,201,3.949,241,4.138,259,1.931,287,3.117,338,3.727,401,3.901,411,1.776,414,3.332,457,3.444,474,2.828,546,4.478,549,5.182,557,2.837,607,2.104,668,2.864,732,2.417,735,4.08,742,4.561,743,5.345,822,3.076,910,4.605,1055,2.892,1273,4.002,1279,4.401,1605,6.468,1988,3.748,2006,3.492,2052,6.247,2174,3.354,2197,5.04,2380,5.366,2723,3.949,3067,5.04,3506,3.475,4600,3.901,5444,6.064,8622,6.064,8630,6.064,8644,8.626,8652,7.675]],["t/2548",[0,4.377,1,2.521,2,3.192,7,1.979,21,2.23,73,3.069,86,2.36,88,3.598,90,2.85,94,2.617,122,3.168,123,3.175,148,1.979,164,3.168,259,2.184,287,2.79,288,4.45,391,2.215,414,3.141,454,4.91,531,3.853,547,4.969,560,3.391,575,3.18,585,4.855,621,2.266,732,2.443,743,5.404,757,3.748,816,4.21,840,4.183,875,2.501,1218,4.071,1273,4.032,1422,5.709,1439,4.703,1589,4.855,1732,3.944,2074,4.703,2136,6.131,2174,3.391,2353,4.098,2359,4.751,2468,4.154,3506,3.514,4297,5.239,4600,3.944,5441,6.131,8646,8.69,8653,5.833,8654,7.76]],["t/2550",[1,1.876,10,2.793,51,3.855,83,1.516,86,2.334,88,3.559,90,2.819,94,3.452,123,2.363,168,3.842,259,2.172,287,3.117,391,2.191,404,5.728,406,3.81,408,4.329,474,2.828,531,3.81,547,4.914,575,3.145,588,5.647,671,3.789,732,3.869,757,4.944,781,1.942,998,2.252,1273,3.001,1362,4.975,1399,3.747,1402,4.605,1841,4.23,2006,3.492,2163,5.906,2174,3.354,2197,5.04,2359,4.699,2770,3.298,3259,4.801,3506,3.475,3625,6.247,3629,6.247,4297,5.182,4600,3.901,8074,6.064,8634,5.769,8645,8.626,8655,7.114,8656,7.114,8657,7.675]],["t/2552",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8649,9.503]],["t/2554",[86,3.214,88,4.901,90,3.882,259,1.993,732,3.328,1778,4.974,1924,4.561,2174,4.619,3071,5.658,3506,4.786,4600,5.373,5012,7.776,5419,7.776,8647,8.351]],["t/2556",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8648,9.503]],["t/2558",[86,3.314,90,4.003,259,2.056,287,2.949,732,3.432,2174,4.763,3506,4.935,4600,5.54,5498,5.506,8650,9.577]],["t/2560",[10,3.601,95,3.741,117,1.085,148,2.525,172,2.29,318,6.192,508,6.963,529,3.464,575,4.056,612,2.891,620,4.545,787,4.151,875,3.189,953,4.289,978,3.124,1401,6.401,1806,8.057,3148,7.617,5479,8.528,8658,9.174]],["t/2562",[30,2.085,126,3.982,148,2.598,165,4.395,875,3.282,987,3.639,1401,6.984,1552,6.445,1607,4.053,1806,10.693,1813,5.841,5479,9.306,8659,10.186]],["t/2564",[10,3.195,43,3.055,44,2.428,117,0.963,126,4.369,148,2.24,156,2.716,188,4.411,197,4.092,318,6.991,505,5.982,508,7.11,744,4.669,745,5.322,802,3.038,1156,5.845,1404,5.622,1552,5.556,1596,3.245,2903,5.622,3148,6.758,5479,7.916,5844,7.716,8660,8.782,8661,8.782,8662,8.782,8663,11.176,8664,8.139]],["t/2566",[7,0.287,33,0.689,36,0.616,44,2.049,86,0.342,90,0.771,117,0.123,139,0.617,156,2.141,178,2.102,188,7.339,240,0.476,266,0.902,404,0.63,412,1.005,443,0.472,474,0.415,505,0.603,508,0.651,555,0.408,617,0.595,626,0.431,732,3.697,905,0.89,987,0.402,1002,0.749,1003,0.587,1304,0.712,1331,1.491,1399,1.438,1465,1.962,1473,0.712,1528,1.396,1727,1.546,1813,0.646,2179,0.772,2259,1.461,2260,0.933,2275,0.494,2429,0.721,2587,4.725,2590,6.625,2608,0.73,2711,3.005,2903,0.721,3030,1.328,3248,0.989,3607,0.721,3662,0.721,3750,0.846,3770,0.812,3774,0.89,3810,1.193,3880,0.949,3893,1.577,3969,8.572,4171,0.916,4184,0.989,4322,0.784,4350,0.669,5758,1.044,5863,6.563,7969,0.989,7972,0.989,8472,3.005,8488,1.044,8664,11.169,8665,1.126,8666,12.051,8667,3.692,8668,1.126,8669,4.354,8670,4.354,8671,2.098,8672,2.946,8673,2.946,8674,2.946,8675,1.126,8676,1.126,8677,2.098,8678,1.126,8679,1.126,8680,1.126,8681,1.126,8682,1.126,8683,1.126,8684,1.126,8685,1.126,8686,1.126,8687,2.098,8688,2.098,8689,2.098,8690,2.098,8691,2.098,8692,1.126,8693,1.126,8694,1.126,8695,1.126,8696,2.098,8697,10.336,8698,2.098,8699,2.946,8700,2.946,8701,1.126,8702,3.692,8703,1.126,8704,1.126,8705,1.126,8706,1.126,8707,2.946,8708,2.946,8709,2.946,8710,2.946,8711,2.098,8712,2.098,8713,2.098,8714,2.098,8715,2.098,8716,2.098,8717,2.098,8718,2.098,8719,2.098,8720,2.098,8721,2.098,8722,2.098,8723,1.126,8724,2.946,8725,3.692,8726,2.098,8727,2.098,8728,3.692,8729,4.944,8730,4.944,8731,2.946,8732,1.126,8733,1.126,8734,1.126,8735,2.098,8736,2.946,8737,2.946,8738,1.126,8739,2.946,8740,1.126,8741,1.126,8742,1.126,8743,1.126,8744,1.126,8745,1.126,8746,1.126,8747,1.126,8748,1.126,8749,1.126,8750,5.474,8751,1.126,8752,0.989,8753,1.126,8754,2.098,8755,1.126,8756,2.098,8757,1.126,8758,1.126,8759,1.126,8760,1.126,8761,1.126,8762,2.098,8763,9.024,8764,1.126,8765,1.126,8766,1.126,8767,1.126,8768,1.126,8769,1.126,8770,1.126,8771,1.126,8772,1.126,8773,1.126,8774,1.126,8775,1.126,8776,1.126,8777,1.126,8778,2.946,8779,1.126,8780,1.126,8781,2.098,8782,2.098,8783,1.126,8784,1.126,8785,1.126,8786,1.126,8787,1.126,8788,1.126,8789,1.126,8790,1.126,8791,1.126,8792,1.126,8793,1.126,8794,2.098,8795,2.098,8796,1.126,8797,1.126,8798,1.126,8799,1.126,8800,1.126,8801,1.126,8802,1.126,8803,1.126,8804,1.126,8805,1.126,8806,1.126,8807,1.126,8808,4.354,8809,4.944,8810,2.946,8811,1.126,8812,1.126,8813,1.126,8814,1.126,8815,1.126,8816,1.126,8817,1.126,8818,2.098,8819,1.126,8820,1.126,8821,3.692,8822,3.692,8823,4.354,8824,3.692,8825,3.692,8826,3.692,8827,3.692,8828,3.692,8829,3.692,8830,3.692,8831,2.946,8832,2.946,8833,2.098,8834,2.098,8835,1.126,8836,2.946,8837,3.692,8838,3.692,8839,3.692,8840,3.692,8841,2.098,8842,2.098,8843,3.692,8844,3.692,8845,1.126,8846,1.126,8847,1.126,8848,1.126,8849,1.126,8850,1.126,8851,1.126,8852,1.126,8853,1.126,8854,1.126,8855,1.126,8856,1.126,8857,1.126,8858,2.098,8859,2.098,8860,2.098,8861,2.098,8862,2.098,8863,2.098,8864,7.788,8865,1.126,8866,1.126,8867,1.126,8868,1.126,8869,1.126,8870,1.126,8871,1.126,8872,1.126,8873,1.126,8874,1.126,8875,1.126,8876,1.126,8877,1.126,8878,1.126,8879,1.126,8880,1.126,8881,1.126,8882,1.126,8883,1.126,8884,1.126,8885,1.126,8886,1.126,8887,1.126,8888,2.098,8889,1.126,8890,1.126,8891,1.126,8892,2.098,8893,1.126,8894,1.126,8895,1.126,8896,1.126,8897,1.126,8898,1.126,8899,2.098,8900,1.126,8901,1.126,8902,1.126,8903,1.126,8904,1.126,8905,1.126,8906,2.098,8907,1.126,8908,1.126,8909,4.944,8910,1.126,8911,1.126,8912,1.126,8913,1.126,8914,1.126,8915,1.126,8916,1.126,8917,2.098,8918,2.098,8919,2.098,8920,2.098,8921,4.354,8922,1.126,8923,1.126,8924,1.126,8925,1.126,8926,1.126,8927,1.126,8928,1.126,8929,2.098,8930,2.098,8931,1.126,8932,1.126,8933,1.126,8934,1.126,8935,1.126,8936,1.126,8937,1.126,8938,1.126,8939,1.126,8940,1.126,8941,1.126,8942,1.126,8943,1.126,8944,1.126,8945,1.126,8946,1.126,8947,1.126,8948,1.126,8949,1.126,8950,1.126,8951,1.126,8952,1.126,8953,1.126,8954,1.126,8955,1.126,8956,1.126,8957,1.126,8958,1.126,8959,1.126,8960,1.126]],["t/2568",[44,2.401,73,2.504,117,0.922,126,4.251,156,3.204,263,2.616,297,2.474,318,6.801,508,7.365,529,2.944,867,2.596,905,8.589,987,3.005,1156,5.599,1330,4.866,1401,4.472,1528,8.018,1530,6.344,1813,4.824,2903,6.961,8961,8.413,8962,10.73,8963,10.872,8964,7.797,8965,8.413]],["t/2570",[44,1.879,126,4.132,156,3.043,318,6.612,1528,7.035,8962,10.554,8964,9.797,8966,10.57,8967,12.524,8968,10.57,8969,10.57]],["t/2572",[86,3.314,90,4.003,259,2.056,287,2.949,732,3.432,2174,4.763,3506,4.935,4600,5.54,5498,5.506,8651,9.577]],["t/2574",[1,1.817,5,1.592,7,2.555,14,3.951,22,2.827,88,4.644,156,1.806,187,3.245,210,2.459,219,2.452,240,1.687,259,2.137,266,3.193,287,2.711,304,4.158,411,2.318,438,3.57,443,3.117,469,4.226,488,2.506,513,4.095,526,2.773,528,5.443,565,4.336,599,4.758,607,2.037,622,3.924,624,3.711,626,2.846,743,5.175,781,1.88,892,3.848,989,4.261,1127,4.702,1146,3.898,1273,2.905,1809,5.467,1931,5.719,2060,3.754,2062,3.247,2136,5.871,2174,4.952,2201,6.888,2723,6.24,3506,4.536,5498,5.061,5499,6.262,8623,5.871,8624,5.719,8625,5.585,8970,7.431,8971,6.53,8972,6.53,8973,6.888]],["t/2576",[0,3.98,1,1.725,2,2.903,5,2.072,7,2.467,14,3.752,83,1.393,86,2.146,88,3.272,90,2.592,117,1.06,183,3.726,186,2.86,187,2.286,203,3.111,211,2.608,240,1.602,248,3.832,258,3.692,259,2.422,265,3.832,267,2.369,287,2.617,411,1.633,483,2.685,526,2.633,528,5.702,530,3.097,542,4.697,547,4.518,560,3.084,607,1.935,622,3.726,624,3.524,626,2.703,646,4.801,732,2.222,809,2.298,816,2.881,1024,3.195,1213,3.949,1281,3.86,1519,3.98,1778,3.321,1809,5.192,1912,5.304,1918,3.654,1919,4.32,1924,3.045,1931,5.431,1935,4.764,1936,5.431,1954,3.654,2062,3.084,2145,3.98,2174,3.084,2192,3.949,2197,4.634,3071,3.778,3506,3.195,4600,3.587,5012,5.192,5441,5.575,8971,8.498]],["t/2578",[86,3.314,90,4.003,259,2.056,287,2.949,732,3.432,2174,4.763,3506,4.935,4600,5.54,5498,5.506,5499,9.184]],["t/2580",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8972,9.503]],["t/2582",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8974,9.503]],["t/2584",[86,2.989,88,4.557,90,3.61,259,2.261,287,3.244,732,3.095,1131,5.457,2174,4.295,2359,7.339,3071,5.261,3506,5.428,4297,8.733,4600,4.996,8364,8.283,8634,9.01,8975,9.758]],["t/2586",[86,2.558,88,3.901,90,3.089,187,2.725,221,4.02,224,4.085,240,1.91,243,3.124,259,2.05,287,3.26,315,4.25,527,2.799,530,3.692,607,2.306,732,2.649,802,2.91,809,2.739,814,2.837,888,4.671,1021,4.866,1273,3.289,1286,4.442,1727,2.987,2006,3.827,2032,4.201,2144,4.568,2174,3.676,2197,5.524,2337,4.442,2486,6.189,2625,5.858,2770,3.615,3071,4.503,3427,8.849,3506,3.809,4297,5.68,4600,4.276,5418,6.847,8976,9.553,8977,7.797,8978,7.797]],["t/2588",[86,3.314,90,4.003,259,2.056,287,2.949,732,3.432,2174,4.763,3506,4.935,4600,5.54,5498,5.506,8979,9.577]],["t/2590",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8980,9.503]],["t/2592",[1,1.46,2,2.457,11,2.061,12,1.92,15,3,16,3.343,24,2.933,76,2.901,86,1.817,88,3.989,117,0.655,123,1.839,193,2.201,196,3.015,208,2.536,240,1.356,243,1.549,259,2.585,266,2.567,287,2.985,296,2.915,315,4.346,330,2.536,391,1.705,400,4.574,411,1.382,469,3.397,488,2.901,513,3.292,527,4.05,607,2.359,627,2.599,822,2.394,985,2.578,998,1.753,1131,3.317,1146,3.134,1195,3.517,1273,2.336,1308,3.018,1812,3.055,2060,3.018,2121,3.657,2134,3.976,2136,4.72,2174,5.802,2197,3.923,2337,3.155,2666,3.486,2723,5.675,2775,4.231,2776,4.231,3506,3.895,5498,4.346,7921,5.034,8623,4.72,8624,4.597,8625,4.49,8974,5.249,8975,4.862,8976,5.249,8979,5.249,8980,5.249,8981,5.034,8982,5.034,8983,5.249,8984,5.249,8985,5.249,8986,4.094,8987,5.249]],["t/2594",[86,3.239,88,4.938,90,3.911,259,2.009,287,2.882,732,3.353,2174,4.654,2359,6.52,3506,4.823,4297,7.191,4600,5.413,8634,8.005,8982,8.975]],["t/2596",[86,3.314,90,4.003,259,2.056,287,2.949,732,3.432,2174,4.763,3506,4.935,4600,5.54,5498,5.506,8985,9.577]],["t/2598",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8987,9.503]],["t/2600",[86,3.314,90,4.003,259,2.056,287,2.949,732,3.432,2174,4.763,3506,4.935,4600,5.54,5498,5.506,8983,9.577]],["t/2602",[1,2.544,5,1.919,11,2.181,12,2.88,30,1.294,88,4.154,115,2.181,117,0.693,123,1.947,150,2.632,201,3.254,210,2.093,240,2.034,259,2.406,266,2.717,271,2.33,287,2.816,315,3.195,318,5.605,401,3.215,411,1.463,427,3.122,487,2.517,488,2.133,489,2.11,513,3.485,544,3.176,545,4.209,557,2.337,571,3.122,597,4.013,627,2.752,652,5.354,688,4.48,743,4.404,802,3.099,1055,2.383,1125,2.991,1249,3.318,1330,3.658,1331,4.57,1443,2.663,1589,3.956,1614,3.956,1924,4.49,1967,3.158,2060,3.195,2174,5.575,2723,5.824,3037,3.69,3506,4.057,4476,4.27,5498,4.527,6246,4.754,8352,4.867,8623,4.996,8624,4.867,8625,4.754,8988,5.557,8989,5.557,8990,5.557,8991,5.557,8992,5.148,8993,5.148,8994,5.557,8995,5.862]],["t/2604",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8984,9.503]],["t/2606",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8988,9.503]],["t/2608",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8989,9.503]],["t/2610",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8992,8.803]],["t/2612",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8990,9.503]],["t/2614",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8993,8.803]],["t/2617",[0,6.354,1,3.023,2,4.634,3,3.672,5,1.905,16,4.976,117,0.975,257,5.919,259,2.332,287,2.406,391,2.538,398,3.276,452,3.99,509,6.543,576,2.873,585,5.563,668,3.318,732,2.8,754,6.193,756,4.206,817,4.761,891,4.342,1031,5.189,1214,4.635,1327,4.976,1711,5.016,1712,6.116,3661,8.243,8113,8.243,8996,8.893,8997,8.893,8998,8.243]],["t/2619",[21,2.992,94,3.512,483,3.962,607,2.855,621,3.041,753,4.316,1312,6.514,1607,4.143,1911,10.907,1938,8.476,2215,8.38,2274,9.15,8999,9.651,9000,7.512]],["t/2621",[0,6.196,1,2.685,21,3.156,259,2.072,287,2.972,584,5.093,610,5.453,612,3.208,754,7.649]],["t/2623",[1,2.423,4,3.056,11,3.419,21,3.619,28,3.652,85,2.803,91,3.375,137,4.046,208,2.156,209,2.975,219,2.414,259,2.448,267,1.792,287,3.655,463,3.38,470,2.241,473,2.151,483,2.783,560,3.196,575,2.998,580,5.277,596,4.938,631,4.478,732,2.303,735,5.269,740,3.359,743,5.094,764,3.105,891,3.571,914,3.169,1029,4.16,1049,4.195,1146,3.837,1577,4.433,1607,3.944,1778,4.664,1924,5.199,2187,5.094,2453,5.683,3250,5.498,8643,7.627,9001,6.78,9002,7.315,9003,6.78]],["t/2625",[5,0.773,21,3.867,27,1.742,38,2.704,44,0.641,74,5.884,86,3.027,87,1.237,88,3.414,94,1.216,117,0.807,148,1.49,156,2.057,165,1.556,188,1.811,194,1.363,196,1.078,223,2.4,226,1.68,229,1.23,242,1.811,259,1.977,263,2.289,266,1.55,287,0.976,304,3.269,315,2.951,339,1.633,412,1.23,437,1.751,463,1.23,469,4.187,470,1.789,471,2.123,473,1.061,483,1.372,486,1.618,487,2.324,492,4.923,510,1.053,521,1.556,531,1.79,574,2.208,579,3.679,584,1.672,602,2.256,607,2.993,612,2.716,621,1.053,654,1.461,658,3.944,732,1.839,740,3.381,754,4.068,764,1.531,785,5.122,834,2.18,867,1.803,875,1.882,880,3.888,909,2.231,923,1.534,1024,1.633,1029,3.322,1131,2.002,1180,1.987,1255,2.935,1263,2.935,1300,2.231,1304,2.282,1331,3.755,1332,4.86,1357,5.817,1370,2.104,1397,2.601,1446,2.185,1471,1.79,1566,2.711,1591,2.554,1607,1.435,1614,2.256,1722,1.664,1772,3.765,1778,1.697,1841,2.704,1854,4.615,1924,1.556,1938,2.935,1948,2.034,2173,4.495,2241,2.653,2275,1.583,2356,1.833,2380,1.68,2453,2.068,2502,2.601,2505,2.849,2519,3.74,2571,3.944,2723,1.856,3306,2.472,3506,3.833,3701,2.051,4411,2.4,4439,2.711,5409,6.824,5498,1.822,7124,3.039,8023,7.438,8196,3.169,8643,7.157,8655,3.343,9000,2.601,9004,3.606,9005,3.343,9006,3.606,9007,3.606,9008,7.845,9009,3.343,9010,6.824,9011,3.606,9012,3.606,9013,3.169,9014,3.606,9015,3.169,9016,3.606,9017,6.687,9018,3.039,9019,3.169,9020,3.606,9021,3.039]],["t/2627",[3,3.031,5,1.572,11,1.663,21,3.779,22,2.793,25,3.777,28,2.408,41,2.174,93,3.42,94,2.998,117,0.805,168,1.609,196,2.658,208,2.164,232,4.237,259,1.384,287,3.047,320,4.758,408,2.72,452,3.294,470,1.477,474,3.274,483,2.793,489,2.449,536,4.956,538,2.329,564,2.814,573,4.21,576,1.558,579,2.713,593,3.21,598,2.236,606,5.233,621,2.144,679,2.436,732,1.518,822,1.933,867,1.488,892,5.144,908,5.118,914,2.09,923,2.958,1024,4.024,1025,2.408,1030,3.826,1031,2.814,1055,3.349,1191,3.167,1208,2.204,1213,2.699,1277,3.876,1457,2.789,1478,2.582,1593,5.975,1607,4.481,1686,4.064,1778,4.183,1792,3.017,1807,3.545,1812,4.545,1924,5.206,2039,4.237,2445,5.8,2506,3.167,2529,4.237,2569,3.625,2878,3.625,2999,3.305,3098,2.894,6664,6.45,8472,3.925,8514,4.47,9017,3.81,9022,5.975,9023,4.823]],["t/2629",[4,3.334,12,2.565,21,3.019,51,6.267,88,3.701,90,2.931,187,2.585,240,2.385,259,1.981,304,4.466,315,4.032,398,2.94,411,1.847,457,3.581,469,4.539,471,4.699,487,3.176,527,2.655,528,3.834,533,5.389,555,2.895,564,7.281,576,4.031,923,2.759,1008,3.308,1370,4.657,1869,7.398,1924,3.444,2173,6.142,2257,5.653,2519,5.11,2999,7.2,3501,5.653,3506,3.614,4285,5.312,4318,5.872,5498,5.308,8358,9.737,8643,6.142,9003,7.398,9017,6.306]],["t/2631",[4,2.591,11,1.341,21,3.948,23,4.188,25,2,27,2.996,30,1.27,38,1.427,48,1.509,74,5.592,85,1.754,86,1.886,87,2.128,88,4.098,89,2.268,90,2.843,91,1.793,117,0.426,136,1.736,148,2.626,156,2.727,172,1.435,188,1.952,194,2.345,196,1.162,202,4.394,213,4.442,219,3.187,220,4.972,221,2.964,224,1.887,226,1.811,227,2.332,259,2.284,263,1.208,287,2.392,402,1.509,412,2.116,469,4.403,470,1.191,471,6.811,489,2.069,492,4.269,520,2.012,521,1.677,555,1.41,575,1.593,598,1.802,607,1.065,612,2.261,663,1.684,668,1.45,695,4.901,732,1.224,739,2.355,748,2.376,754,4.32,760,1.877,762,2.664,785,3.984,874,2.11,963,2.332,987,1.388,997,1.384,1118,4.073,1177,1.289,1189,4.188,1214,2.025,1300,3.838,1307,2.11,1331,1.569,1351,2.379,1440,2.587,1480,2.175,1618,1.552,1772,1.987,1773,3.344,1778,1.829,1790,1.768,1798,3.275,1801,2.039,1831,3.163,1841,3.547,1914,1.941,1988,3.236,2174,1.698,2380,3.607,2440,1.677,2978,2.991,2999,2.664,3103,2.664,3137,2.587,3506,1.76,3600,4.252,5498,3.134,8023,5.451,8635,5.049,8643,6.801,8981,3.275,9008,5.75,9010,7.176,9015,5.451,9021,3.275,9024,3.886,9025,3.886,9026,3.415,9027,3.602,9028,6.204,9029,3.886,9030,3.602]],["t/2633",[4,3.94,11,3.253,18,6.368,21,3.65,26,4.853,179,5.553,209,3.836,213,4.07,220,4.555,259,2.395,457,4.232,470,3.581,511,4.291,997,4.163,1024,4.271,1300,5.836,1446,5.716,1547,4.948,2012,8.288,2959,6.804,2999,6.464,8981,7.948,9031,9.432,9032,8.742]],["t/2635",[11,4.028,21,3.948,30,1.615,43,2.746,88,3.659,89,4.605,117,0.865,208,2.326,214,3.638,219,3.441,239,3.732,259,1.488,287,2.822,470,3.577,489,2.632,492,3.118,576,2.549,610,3.918,612,2.305,618,4.316,650,5.693,743,5.496,760,3.811,907,5.409,914,3.419,923,2.073,954,5.693,955,3.336,1070,3.963,1191,5.182,1205,3.59,1282,7.671,1331,3.186,1446,4.782,1615,4.113,1812,5.332,2215,5.328,2216,6.235,3337,3.853,3506,3.573,4600,5.3,8643,6.073]],["t/2637",[21,3.744,45,6.584,90,3.287,172,2.071,188,5.681,211,3.308,214,3.123,263,2.783,473,2.632,520,4.634,568,5.522,580,6.456,612,2.614,663,3.878,785,4.605,914,3.878,1024,4.053,1026,7.864,1185,5.176,1331,3.613,1332,4.369,2166,7.864,2242,7.542,2380,4.17,3506,5.122,3510,7.071,9018,7.542,9021,7.542,9032,8.295,9033,9.939,9034,8.295]],["t/2639",[21,3.775,188,5.116,214,3.554,259,1.921,263,3.167,287,2.756,470,3.12,473,2.996,612,2.975,681,4.57,785,5.241,1331,4.112,2380,4.746,8981,8.584,9017,8.047,9021,8.584,9030,9.441]],["t/2642",[11,3.646,21,3.599,239,4.999,287,2.86,469,6.011,490,4.348,607,3.434,612,3.087,1177,3.507,2959,7.625,3762,7.945,4600,5.373]],["t/2644",[21,2.97,88,4.792,218,3.606,267,2.532,470,3.166,867,3.19,908,3.82,1312,6.466,1446,6.264,1480,5.784,2879,7.321,6996,8.413,7502,9.082,7663,9.58,9035,10.336,9036,9.58,9037,10.336]],["t/2647",[13,3.228,17,2.417,21,3.395,74,6.073,86,3.813,88,3.747,90,3.525,117,0.886,145,3.093,168,2.696,198,2.707,209,2.23,239,2.593,255,3.323,259,1.998,287,2.187,320,2.935,408,4.558,429,3.955,463,1.87,466,3.6,470,3.46,471,3.228,489,2.696,492,4.185,504,2.999,510,2.36,514,2.754,538,2.564,562,2.238,565,4.716,571,3.99,579,2.026,607,2.216,612,1.601,665,3.357,693,3.199,756,2.593,759,2.518,762,3.758,787,2.3,813,3.818,866,2.438,867,2.494,881,3.29,890,3.747,915,4.62,987,1.959,997,3.419,1013,2.593,1055,2.066,1079,4.62,1133,4.034,1186,4.219,1191,3.6,1197,4.463,1249,2.876,1251,4.121,1265,3.511,1278,2.895,1283,3.068,1300,3.393,1304,3.469,1370,3.199,1446,5.816,1578,4.219,1715,2.222,1772,2.804,1825,3.199,1913,4.463,2241,4.034,2840,4.219,2899,2.999,2999,3.758,3465,3.955,4502,3.6,4600,5.384,5498,2.77,6929,5.082,8438,4.62,9009,5.082,9027,7.491,9038,8.082,9039,5.483,9040,5.483,9041,5.483,9042,5.483,9043,5.483,9044,5.483]],["t/2649",[21,3.156,287,2.972,515,8.678,1272,7.528,1528,7.311,8621,9.256,9005,10.181,9045,7.649,9046,10.984]],["t/2651",[0,4.426,1,2.539,2,3.228,5,1.681,11,2.707,12,2.522,83,1.549,86,2.386,90,2.882,115,2.707,139,2.308,214,2.738,258,2.996,259,2.338,267,2.544,287,3.354,318,6.499,483,2.986,487,4.134,525,3.896,526,2.928,560,3.429,627,4.52,688,5.558,732,2.471,740,4.771,778,5.898,792,5.298,802,3.593,1003,4.09,1014,3.693,1015,3.874,1829,3.228,2062,3.429,2174,3.429,3214,5.898,3506,3.553,3670,5.661,4600,3.989,5205,7.273,5479,7.358,5498,3.965,8402,5.378,8994,9.128,9047,6.387]],["t/2653",[86,3.289,90,3.972,259,2.04,732,3.405,1778,5.089,1924,4.666,2174,4.726,3506,4.897,4600,5.497,5498,5.464,8991,9.503]],["t/2656",[47,4.254,87,3.301,89,5.617,142,6.499,287,2.605,511,4.379,544,4.835,598,5.943,637,6.637,714,9.634,1778,4.53,1792,6.022,1812,6.053,1924,4.153,2165,6.321,2237,6.407,2581,4.985,8544,7.835,9048,8.922,9049,9.626]],["t/2658",[21,2.865,47,3.583,95,3.768,492,3.938,529,3.488,607,2.733,645,4.132,670,4.453,732,3.139,745,6.041,784,7.875,787,4.181,1014,4.691,1069,5.13,1159,5.195,1267,5.924,1292,7.671,1812,5.098,1989,5.766,2884,9.239,4866,8.114,9050,9.239]],["t/2660",[21,2.462,30,1.753,47,3.079,117,0.939,208,3.582,214,2.989,229,2.922,287,3.288,408,4.832,495,3.593,529,2.998,597,3.304,598,5.1,627,3.728,637,4.436,645,3.551,670,3.827,679,4.328,695,6.768,696,6.303,714,6.973,756,4.052,764,3.636,790,5.245,1067,7.539,1185,6.362,1812,5.625,2237,5.702,2304,3.827,2520,6.768,3103,5.872,4415,7.219,5498,5.558,8544,6.973,8630,6.768,9048,7.94]],["t/2663",[0,4.953,1,2.147,2,3.612,7,2.24,10,3.195,21,3.211,117,0.963,187,2.844,223,5.845,259,1.656,287,2.376,513,4.839,534,6.461,575,3.599,598,4.072,599,5.622,689,6.758,745,5.322,831,4.287,867,2.71,869,4.953,882,4.437,1135,5.556,1170,3.742,1418,3.558,1577,5.322,1579,5.692,1669,6.938,1711,4.953,1829,4.597,1830,4.734,1832,5.766,2453,5.036,3037,5.124,3075,6.938,3594,6.938,8194,8.139,8642,7.716,9051,7.4]],["t/2665",[4,4.455,17,3.6,19,4.229,21,3.065,24,4.009,93,3.805,97,2.521,117,0.895,123,3.283,136,3.648,139,2.402,207,5.109,256,6.139,257,5.436,258,3.118,259,2.24,391,2.331,456,6.648,461,4.203,512,6.453,531,4.055,541,4.854,544,4.102,547,5.229,745,4.949,756,3.863,827,6.139,867,2.521,1074,5.229,1121,5.785,1222,5.892,1266,5.053,1368,5.785,1418,3.31,1422,6.009,1574,6.883,1577,4.949,1607,3.25,1686,6.883,2185,5.688,2217,5.892,2878,6.139,7619,7.57,8402,5.598,9052,8.167,9053,8.167,9054,6.648,9055,8.167]],["t/2667",[21,3.929,28,4.741,83,1.875,106,4.611,249,4.381,259,1.791,401,4.826,461,4.886,514,4.769,526,3.543,571,4.688,575,3.891,613,4.741,651,6.32,655,6.235,756,4.491,978,2.997,1035,5.492,1332,4.636,1829,4.828,2781,8.344,7944,6.726,9056,9.496,9057,8.801]],["t/2669",[21,3.505,118,3.773,259,1.907,489,3.373,607,2.772,745,6.128,765,7.782,792,6.827,908,3.737,1216,7.44,1577,6.128,1647,5.9,2062,4.419,2448,7.44,2723,5.204,3148,7.782,8630,7.989,9058,10.112,9059,10.112]],["t/2671",[5,0.804,7,0.957,12,1.206,21,1.078,33,1.231,38,1.378,44,2.678,97,2.333,118,4.265,122,1.531,128,1.723,137,1.531,150,1.561,187,1.215,193,1.382,196,1.122,207,5.418,259,1.426,271,1.382,287,1.015,296,0.991,297,1.103,304,2.099,330,1.592,350,5.812,391,1.071,411,1.75,412,3.236,445,2.037,456,3.053,471,2.209,487,1.493,528,1.802,544,3.798,558,2.819,627,2.624,735,1.994,745,3.654,766,3.861,812,2.321,895,2.052,923,0.985,997,1.336,1013,4.096,1593,3.053,1829,3.903,1838,2.189,1877,3.161,1910,2.209,2137,2.657,2144,4.702,2171,1.599,2217,2.706,2723,1.93,2867,3.477,3642,3.296,4170,2.321,4285,2.497,8345,2.706,9060,3.477,9061,3.751]],["t/2673",[5,1.606,7,2.571,19,3.883,21,2.896,22,1.887,23,3.348,25,2.552,44,2.46,72,2.454,103,3.215,118,2.798,137,3.061,168,1.654,172,1.735,207,3.102,208,1.462,209,2.017,255,3.005,258,1.893,259,1.901,266,2.131,267,2.214,320,2.655,401,2.521,456,4.036,463,1.691,470,1.519,471,4.415,513,2.733,538,1.573,544,2.491,550,3.256,552,2.462,554,3.453,576,1.602,579,1.833,582,2.733,600,2.92,601,4.596,602,3.102,603,4.596,604,2.976,605,4.596,606,4.415,607,2.479,608,6.957,609,3.399,610,2.462,611,3.145,612,2.64,613,3.744,614,2.505,615,1.816,616,4.596,617,2.619,621,1.448,735,3.986,745,4.544,766,3.175,781,2.287,812,3.068,895,2.712,908,2.771,914,2.149,923,1.969,957,1.881,963,2.976,978,1.565,1013,2.346,1055,2.825,1175,3.256,1191,4.923,1218,2.601,1249,2.601,1253,3.834,1302,2.947,1348,3.816,1521,2.82,1829,4.145,1838,2.894,1877,4.179,1910,2.92,1961,3.641,2008,4.596,2062,2.167,2144,2.693,2217,3.577,2250,4.596,2440,2.14,2723,2.552,3098,2.976,3294,3.577,4170,3.068,8367,4.179,8390,3.577,9060,4.596,9062,4.959,9063,4.959,9064,4.959,9065,4.959,9066,4.959,9067,4.959,9068,4.959,9069,4.596,9070,4.959,9071,4.959]],["t/2675",[7,1.486,10,2.119,11,2.914,16,4.727,21,3.665,30,2.034,43,2.027,72,1.907,86,1.771,87,3.409,93,2.714,96,3.913,106,2.828,115,2.009,140,4.202,168,1.943,209,2.369,220,4.8,223,5.622,235,2.798,259,1.874,267,1.427,287,1.576,391,1.662,401,2.961,411,1.348,461,2.997,463,1.987,474,2.146,489,1.943,507,4.909,510,1.701,526,2.173,544,2.926,553,3.097,560,2.545,571,2.875,597,2.246,637,5.645,638,3.877,651,5.622,652,3.995,655,5.547,656,3.825,658,3.933,659,3.246,667,8.09,668,2.173,679,2.943,680,5.118,809,1.897,822,2.335,827,4.378,868,2.859,875,1.877,982,4.909,996,4.741,1062,2.638,1150,3.933,1168,3.644,1196,4.056,1213,3.259,1263,4.741,1273,2.277,1302,3.462,1372,3.776,1386,3.566,1418,2.36,1552,3.685,1581,4.909,1610,4.741,1790,2.65,1829,4.088,1832,3.825,1958,3.163,2021,3.53,2121,3.566,2142,4.602,2217,4.202,2238,4.482,2506,3.825,3599,5.118,6460,5.118,8642,5.118,9072,5.825,9073,5.825,9074,5.118,9075,5.399,9076,5.399,9077,5.825,9078,5.825]],["t/2677",[5,1.28,10,2.174,21,2.472,27,2.885,47,2.147,87,2.049,96,2.352,117,0.943,118,2.229,137,2.439,148,3.275,164,3.512,178,2.885,187,1.935,213,3.712,220,4.155,221,2.855,235,2.87,258,2.281,320,4.605,414,2.333,461,3.074,473,1.757,510,1.745,531,2.966,547,3.825,575,2.448,584,2.77,611,4.626,655,3.923,658,7.446,679,3.018,694,4.2,740,3.95,746,9.15,758,4.395,770,3.176,771,4.231,772,7.965,774,5.267,775,2.518,776,10.271,777,7.974,778,4.49,779,5.537,780,5.537,781,1.511,782,7.559,783,3.78,784,4.72,785,3.074,787,2.505,788,3.737,790,3.657,914,2.588,955,2.525,1025,2.983,1273,2.336,1362,3.872,1393,5.443,1478,3.198,1577,3.62,1615,4.483,1832,3.923,1894,4.395,1910,3.517,1958,3.243,2350,3.696,2531,5.576,3345,3.657,8074,4.72,8262,7.974,9079,5.974,9080,5.974,9081,5.974]],["t/2679",[]],["t/2681",[]],["t/2684",[0,5.284,1,3.095,2,3.854,5,2.007,12,3.011,15,5.846,21,2.692,22,3.565,24,4.599,240,2.875,259,2.388,315,4.733,398,3.451,463,3.195,474,3.451,487,3.728,495,4.882,527,3.117,612,2.736,660,4.009,1398,4.525,9026,8.232,9082,9.369]],["t/2686",[12,3.476,15,6.375,259,2.394,315,5.464,487,4.303,495,4.536,529,3.784,1398,5.223,1959,7.801]],["t/2688",[1,2.396,6,1.774,12,2.668,15,1.753,20,1.573,22,2.739,44,0.62,47,3.286,51,1.753,86,1.061,90,2.089,94,1.177,117,0.383,136,2.54,137,1.425,139,2.117,145,1.968,148,0.89,150,1.452,169,1.587,187,1.842,194,2.15,208,3.048,210,1.155,211,2.102,213,2.454,219,1.152,229,1.19,239,1.65,249,3.83,258,1.332,259,2.331,263,1.085,265,3.088,267,0.855,268,2.036,287,0.944,288,2.001,290,1.923,339,1.58,398,2.095,449,4.029,472,2.234,473,1.026,474,1.286,475,4.377,490,3.761,495,5.369,511,1.587,538,1.107,552,1.732,578,1.923,579,1.29,607,1.974,627,1.518,636,1.796,652,4.324,668,1.302,679,1.763,734,3.088,739,2.115,760,2.747,763,2.208,764,2.414,775,2.107,786,1.868,787,1.463,833,2.472,867,2.222,868,1.713,887,2.159,903,2.208,905,2.757,952,2.567,993,1.346,998,1.024,1008,1.446,1025,3.594,1027,2.183,1031,3.318,1055,2.143,1074,2.234,1092,5.193,1125,1.65,1177,2.388,1205,1.587,1208,1.595,1213,1.953,1232,2.623,1276,2.392,1295,2.472,1331,2.906,1332,3.514,1351,2.136,1374,2.262,1398,3.476,1418,2.305,1477,1.807,1483,2.159,1485,2.262,1552,2.208,1598,2.941,1616,3.234,1663,4.793,1697,4.184,1732,2.891,1769,2.517,1771,2.623,1791,4.145,1801,1.83,1815,2.517,1830,4.475,1917,2.685,1926,1.868,1948,1.968,2126,2.941,2187,2.43,2215,2.356,2257,2.472,2316,1.573,2345,2.623,2429,2.234,2674,1.855,2927,2.757,2943,2.84,2989,4.377,3037,2.036,3078,2.115,3104,3.687,3337,1.704,3462,5.271,3582,4.997,3583,5.271,3707,2.941,3873,2.262,4079,2.392,4588,4.629,4593,4.454,4657,2.941,5421,2.757,6250,3.066,6256,2.941,7130,2.757,7765,2.757,8062,2.517,8390,4.103,8549,5.271,8599,3.234,9017,2.757,9026,3.066,9057,3.234,9083,3.234,9084,3.234,9085,3.49,9086,2.84,9087,3.066,9088,3.234,9089,5.687,9090,3.49,9091,3.066,9092,5.687,9093,3.234,9094,3.49,9095,3.49,9096,3.49,9097,3.49]],["t/2692",[15,4.674,21,3.628,86,2.83,91,4.294,95,3.518,209,3.785,250,3.73,259,2.186,474,3.429,483,3.541,489,3.867,495,5.295,520,4.819,573,5.337,1029,5.292,1067,6.378,1249,4.882,1398,5.598,1421,5.659,1926,4.982,2174,4.067,2669,7.162,8627,7.843,9083,8.626]],["t/2695",[6,4.762,15,4.705,85,2.65,95,3.541,138,2.891,156,2.277,259,1.767,287,2.535,411,2.168,470,2.87,486,4.204,502,5.372,866,4.166,890,4.344,969,4.678,997,3.337,1014,4.409,1029,5.328,1131,6.463,1214,4.883,1239,5.419,2169,7.042,2174,5.086,2460,7.626,3501,6.636,5700,8.683,7977,7.21,9047,7.626,9098,8.683]],["t/2697",[1,1.252,5,1.646,7,1.307,10,2.795,12,1.646,20,2.309,25,2.636,30,1.048,43,1.782,51,2.573,83,1.82,85,1.449,95,1.936,117,1.31,123,1.577,156,2.8,163,2.435,167,2.913,168,1.709,172,1.185,194,1.936,198,2.529,211,1.893,259,1.449,263,1.593,267,2.258,268,2.989,287,2.079,398,1.887,402,2.983,404,4.299,406,3.814,470,1.569,474,1.887,492,2.024,501,3.136,510,1.496,526,2.867,529,1.792,564,2.989,573,2.937,576,1.655,582,2.822,588,3.768,593,3.409,597,2.963,627,2.229,666,2.115,668,1.911,671,2.529,734,2.781,737,3.495,753,2.123,809,2.502,822,3.695,834,1.911,866,2.278,892,2.652,969,2.558,987,1.83,998,1.503,1090,2.543,1162,2.963,1181,3.905,1205,2.33,1208,2.341,1248,2.913,1256,5.542,1304,3.241,1402,3.074,1418,2.076,1478,2.742,1480,2.866,1489,2.687,1516,4.047,1582,3.768,1599,3.172,1640,2.288,1659,6.07,1715,2.076,1750,2.963,1825,2.989,1841,4.89,1967,2.558,1983,4.169,2006,2.33,2062,2.238,2770,3.961,3252,2.801,3256,2.474,3259,3.204,3359,6.136,3495,3.695,3641,4.169,3656,3.628,4689,2.937,4713,3.016,5950,3.169,5997,4.047,7516,3.567,8055,3.28,8062,3.695,9099,4.047,9100,4.748,9101,4.316,9102,3.942,9103,4.748]],["t/2700",[12,2.191,25,3.508,33,2.237,43,3.77,115,2.351,117,0.747,138,2.104,156,2.842,172,1.577,226,3.176,263,2.119,264,3.176,266,4.058,404,3.814,406,3.384,474,3.479,492,3.731,496,3.701,526,2.543,529,2.385,535,3.845,625,4.917,668,2.543,729,4.828,732,2.973,752,4.014,875,3.043,923,1.79,978,2.152,998,2,1177,2.262,1187,3.275,1304,5.975,1443,3.976,1599,2.815,1657,5.385,1832,4.476,1841,2.503,1858,3.977,2006,4.296,2060,3.444,2304,3.045,2337,3.6,2770,2.929,2853,3.486,2881,2.732,3247,4.917,3256,5.649,3495,4.917,3638,5.781,3701,3.876,3797,3.977,4169,5.203,4261,3.943,4262,3.977,4506,4.917,4689,3.909,4713,4.014,5950,4.218,8473,5.385,9104,5.99,9105,5.548,9106,5.385,9107,5.123,9108,5.99,9109,6.318,9110,6.318,9111,6.318,9112,6.318]],["t/2702",[44,1.903,85,3.028,96,3.234,124,4.882,138,2.535,156,1.996,188,4.126,242,4.126,259,2.019,264,3.828,406,4.079,492,3.246,562,3.354,621,3.127,732,2.587,867,2.535,880,5.468,1019,3.809,1090,4.079,1841,3.932,1858,4.794,1958,5.813,2281,5.139,2356,4.176,2505,6.49,2669,6.322,2770,3.53,3256,3.967,3610,5.926,3611,4.794,4516,5.631,5074,6.687,5832,5.468,8114,7.583,9113,7.219,9114,7.614,9115,7.614,9116,7.219,9117,8.215,9118,7.614,9119,7.614,9120,7.614,9121,6.687,9122,6.687,9123,6.687]],["t/2705",[5,1.341,11,2.159,44,1.387,51,1.974,75,2.119,85,1.77,97,1.213,117,0.975,138,1.213,219,1.297,221,2.991,243,1.623,258,1.5,259,2.125,264,1.831,267,1.533,404,6.304,411,1.448,412,1.34,419,2.861,457,1.763,463,1.34,473,1.841,481,2.406,482,3.398,483,1.495,486,4.869,488,2.111,491,1.682,492,1.553,568,1.919,614,3.941,623,2.358,634,3.685,636,2.022,649,1.725,654,1.592,732,1.237,820,3.178,834,1.466,867,1.213,868,1.929,871,4.331,937,2.653,986,2.581,997,1.4,1019,1.822,1021,4.511,1066,1.94,1083,2.382,1149,2.891,1177,1.304,1209,2.954,1227,2.458,1282,2.891,1307,2.134,1374,2.547,1396,2.235,1443,3.284,1471,1.951,1478,2.104,1586,4.878,1607,1.564,1643,5.191,1715,1.592,1722,1.813,1750,2.273,1772,3.201,1776,2.048,1838,2.293,1841,1.443,1843,2.653,1858,5.19,1954,3.241,1979,2.581,1988,2.291,2018,1.951,2060,1.986,2304,1.755,2357,4.511,2508,6.096,2673,2.382,2723,2.022,2754,3.374,2934,3.589,2970,5.094,3256,5.241,3259,2.458,3638,2.406,3671,2.382,3672,2.616,3701,4.435,4411,2.616,4496,3.105,4593,5.503,4713,2.314,4863,4.945,5832,5.92,7913,3.024,8455,3.453,8592,2.784,8986,2.693,9000,2.835,9045,2.737,9124,3.312,9125,4.433,9126,3.453,9127,4.433,9128,3.453,9129,3.312,9130,3.453,9131,3.453,9132,8.534,9133,3.453,9134,3.453,9135,7.815,9136,3.105,9137,3.199,9138,6.853,9139,2.891,9140,5.738,9141,3.642,9142,4.433,9143,3.453,9144,3.453,9145,3.453,9146,3.453,9147,3.453,9148,3.453,9149,2.653,9150,7.558,9151,3.642,9152,3.642,9153,3.642,9154,3.642]],["t/2707",[1,1.897,5,1.662,44,1.38,97,2.395,117,1.27,164,3.168,229,2.647,259,2.491,291,4.342,486,3.482,654,3.145,820,2.772,875,2.501,1015,3.831,1037,4.703,1064,4.802,1204,3.168,1399,3.789,1772,3.969,1858,6.017,2161,5.497,3640,4.969,4457,5.096,4689,7.077,5832,6.864,8986,5.319,9000,5.598,9127,5.497,9149,8.917,9150,9.197,9155,8.52,9156,9.061,9157,6.819,9158,7.193,9159,7.193,9160,7.193,9161,7.193]],["t/2709",[1,2.597,5,1.503,7,1.79,30,1.972,33,1.812,44,0.598,48,2.143,85,0.951,95,1.272,97,1.038,115,1.16,117,0.983,124,3.28,148,0.858,164,2.865,165,1.451,193,2.992,213,1.451,242,2.772,249,1.552,259,2.44,262,1.567,267,1.352,338,3.408,402,1.306,414,2.202,445,1.826,473,0.989,486,5.753,504,1.84,510,0.982,530,2.422,586,1.509,594,2.059,634,1.981,665,2.059,666,3.702,671,2.725,732,3.034,759,1.545,767,1.981,814,3.25,817,1.801,818,1.72,870,5.781,875,1.084,886,3.064,976,2.128,985,1.008,1035,3.192,1064,2.081,1090,1.67,1097,1.378,1120,3.811,1177,1.116,1205,1.53,1248,1.913,1274,2.589,1377,2.427,1399,5.528,1421,1.642,1488,2.427,1612,1.72,1640,3.135,1715,1.363,1772,1.72,1788,3.139,1790,1.53,1791,1.68,1888,2.475,1926,1.801,1989,4.697,2032,1.68,2170,2.528,2278,2.018,2281,2.104,2328,3.492,2337,1.776,2356,4.557,2754,1.813,2769,3.844,2770,5.602,2771,2.343,2789,3.578,2790,2.039,2853,2.823,2905,2.383,2971,3.726,3252,3.838,3312,2.475,3640,2.154,3648,3.844,3659,4.904,3739,3.783,3818,3.415,3899,2.475,3918,1.999,4170,2.081,4419,2.528,4616,4.492,4687,2.018,5289,2.835,6524,2.383,6867,2.427,8010,2.738,8986,2.306,9129,4.651,9149,8.733,9150,2.343,9162,2.835,9163,2.835,9164,2.956,9165,2.738,9166,2.589,9167,4.36,9168,2.956,9169,3.118,9170,5.116,9171,4.36,9172,3.118,9173,3.118,9174,3.118,9175,3.118,9176,3.118,9177,2.835,9178,2.835,9179,3.118,9180,3.118]],["t/2711",[1,1.493,30,1.564,33,1.251,44,1.701,83,0.753,85,2.162,117,0.418,164,1.556,169,1.734,214,1.33,229,1.3,259,2.623,287,2.068,338,3.711,402,1.48,404,2.133,405,6.316,406,3.033,412,2.607,414,1.034,445,2.07,486,3.922,578,2.101,579,1.409,598,1.768,612,1.113,732,1.2,757,2.95,814,2.06,832,2.013,834,2.279,875,1.968,879,2.205,1009,2.176,1074,2.441,1090,3.033,1097,1.562,1170,1.625,1181,1.938,1187,1.831,1231,1.851,1399,4.268,1418,2.475,1444,3.103,1478,2.041,1519,2.15,1612,3.909,1640,3.414,1727,2.169,1753,1.893,1773,2.055,1841,3.938,1946,2.865,1974,1.938,2018,5.068,2123,2.266,2145,2.15,2171,1.625,2186,2.288,2278,5.245,2281,5.468,2356,1.938,2357,2.205,2619,2.95,2673,6.186,2754,4.712,2769,4.254,2770,4.607,2872,2.385,2881,2.448,2944,2.655,3256,2.95,3609,6.997,3610,7.364,3611,6.256,3612,6.192,3638,2.334,3639,2.412,3640,2.441,3659,3.341,3805,2.805,3818,2.359,3918,2.266,4169,2.101,4344,3.012,4424,2.934,4425,5.623,4502,2.503,5498,1.926,5832,2.537,7007,3.213,7977,2.934,8010,3.103,8062,2.75,9045,2.655,9124,3.213,9125,2.7,9127,2.7,9167,4.826,9181,3.533,9182,3.533,9183,3.533,9184,3.533,9185,3.533,9186,3.533,9187,3.533,9188,3.533,9189,3.533,9190,3.533,9191,3.533,9192,3.533,9193,5.148,9194,3.533,9195,3.533,9196,3.533,9197,3.35,9198,3.35,9199,3.35,9200,3.012,9201,3.35,9202,3.533,9203,3.35,9204,3.35]],["t/2713",[1,1.114,5,1.838,9,2.917,10,1.658,11,2.424,16,2.549,18,3.076,25,2.344,34,2.85,38,1.673,85,1.289,95,1.722,96,1.794,117,0.499,139,1.34,156,2.532,168,2.344,177,3.212,236,2.819,239,2.155,242,2.288,257,3.032,259,2.478,264,2.123,265,2.474,287,1.233,288,4.03,291,2.549,404,2.549,405,2.819,406,3.489,412,2.926,463,1.554,473,2.067,474,1.678,483,2.674,487,1.813,488,1.537,490,1.874,491,1.95,495,1.911,510,1.331,511,3.197,546,2.658,576,1.472,611,1.911,629,2.262,630,2.492,631,2.789,634,2.683,748,1.745,867,1.406,874,2.474,875,2.265,896,2.492,908,1.684,909,2.819,923,2.253,1015,2.249,1029,2.591,1064,2.819,1106,3.424,1162,2.635,1187,3.376,1208,2.082,1211,1.918,1227,4.396,1252,2.953,1271,2.39,1277,2.406,1304,6.593,1418,4.65,1424,3.352,1443,2.959,1471,2.262,1475,2.953,1586,2.288,1589,2.85,1612,2.33,1615,2.374,1640,3.139,1722,3.243,1750,2.635,1769,3.287,1772,2.33,1773,2.456,1801,2.39,1841,4.465,1926,2.439,1954,4.443,1958,3.816,2006,2.073,2197,2.992,2278,2.734,2281,2.85,2357,2.635,2934,2.613,3076,3.173,3252,2.492,3259,2.85,3312,3.352,3609,3.123,3612,3.227,3638,2.789,3639,2.883,3701,2.591,3797,4.101,4457,2.992,4689,2.613,5832,4.678,6378,3.708,8633,3.839,8653,3.424,9101,3.839,9140,3.352,9142,3.227,9155,3.352,9205,3.839,9206,4.223,9207,4.223,9208,4.556,9209,4.223,9210,4.223,9211,4.003,9212,4.003,9213,4.003,9214,4.003,9215,4.003,9216,4.003]],["t/2715",[1,2.406,47,3.537,71,4.693,81,3.959,83,2.208,97,2.234,117,0.794,123,3.03,156,3.145,164,2.955,168,2.415,173,6.156,263,3.476,287,1.959,288,5.643,297,2.129,404,4.051,406,3.594,465,5.222,491,3.098,597,2.792,656,4.754,659,4.297,660,3.098,712,3.875,744,3.849,757,3.496,759,3.324,822,2.901,980,3.15,1025,3.615,1063,5.571,1075,4.187,1252,4.693,1273,2.83,1393,4.58,1596,2.675,1674,5.571,1776,5.129,1841,4.863,2006,3.293,2770,3.111,3076,5.041,4318,5.326,4350,4.302,8055,4.635,9217,6.71,9218,5.892,9219,6.71,9220,5.128,9221,6.1,9222,7.239]],["t/2717",[30,2.266,83,2.186,259,2.088,287,2.996,411,2.562,757,5.347,1841,4.726]],["t/2719",[5,2.249,26,2.383,41,2.087,43,2.476,48,1.798,85,2.452,95,1.751,117,0.95,156,2.693,168,1.545,169,2.107,172,2.006,194,3.276,229,1.579,267,1.743,291,2.592,299,3.127,401,2.354,411,1.072,452,2.078,457,2.078,473,2.861,474,2.622,501,2.835,521,1.998,526,2.656,535,2.612,538,2.258,568,2.261,571,2.286,612,1.353,614,2.34,668,1.728,732,2.241,740,2.127,764,1.966,775,1.356,787,1.942,809,2.822,816,3.971,822,4.208,866,2.059,867,2.675,874,2.515,875,1.492,880,3.083,890,2.147,895,2.533,963,2.779,987,2.543,1014,2.179,1015,2.286,1034,3.659,1137,3.77,1140,2.612,1181,3.617,1187,2.225,1195,2.727,1245,2.752,1266,2.866,1271,2.429,1273,1.811,1362,3.002,1382,3.225,1402,5.201,1418,3.512,1441,2.93,1442,3.407,1443,1.95,1644,3.407,1727,3.078,1749,2.679,1772,5.369,1789,3.041,1841,3.855,1868,3.225,1888,3.407,1958,4.706,2060,2.34,2100,3.903,2357,2.679,2571,4.805,2853,2.368,2899,2.533,2944,3.225,3256,3.437,3426,5.349,3652,6.377,3656,6.14,3671,4.313,3797,2.702,4169,2.552,4307,3.341,4375,3.659,4457,3.041,4506,3.341,4510,5.619,4516,3.174,4689,2.656,4713,2.727,4900,5.477,5950,2.866,8546,3.903,9216,6.254,9223,4.293,9224,4.631,9225,4.293,9226,4.293,9227,3.77,9228,4.293,9229,5.793,9230,4.293,9231,4.631,9232,4.631,9233,4.069,9234,3.77]],["t/2721",[1,2.107,97,2.66,115,3.809,243,2.235,259,2.298,486,5.467,923,2.264,987,3.079,1418,3.493,1457,4.985,1615,4.492,1715,3.493,1772,4.408,1896,4.862,3671,7.384,3672,8.111,3673,6.81,3700,8.989,3701,4.902,4261,6.387,4262,6.444,7713,6.479,9107,6.479,9149,8.227,9150,6.003,9235,7.264,9236,7.574,9237,7.574,9238,7.989,9239,7.264]],["t/2723",[30,1.3,44,1.598,94,3.032,97,1.961,122,5.073,156,1.544,239,3.005,259,2.257,338,3.085,402,3.49,486,5.37,551,4.889,607,1.742,621,1.855,629,3.154,654,2.574,737,2.89,781,1.607,809,3.897,820,3.211,867,1.961,875,2.047,895,3.475,998,1.864,1074,5.755,1097,2.603,1715,2.574,1717,3.931,1841,4.395,2061,7.525,2072,6.618,2133,4.229,2144,4.881,2304,2.838,2881,2.546,3256,4.341,3638,5.503,3671,5.447,3672,4.229,4261,5.199,4262,5.245,4713,5.293,5950,5.562,8574,7.575,9149,8.08,9240,8.332,9241,7.898,9242,7.898,9243,5.582,9244,5.888,9245,5.888,9246,5.888,9247,5.888,9248,5.888,9249,5.582]],["t/2725",[5,1.012,43,4.044,44,0.84,48,3.408,89,4.217,94,1.594,97,1.458,156,1.148,163,2.246,164,3.583,168,2.411,222,4.11,259,2.365,339,3.273,412,2.465,473,1.39,474,2.663,486,5.804,597,1.822,723,4.38,834,2.697,880,3.145,1312,2.956,1382,5.033,1403,6.455,1478,4.698,1586,4.937,1596,1.746,1715,3.556,1858,4.217,1896,2.665,2275,4.314,2337,3.816,2521,3.408,2971,3.19,3256,3.49,3636,3.846,3638,5.373,3639,5.553,3701,4.11,3818,2.924,4261,2.733,4262,2.757,4358,6.457,4713,5.168,5950,4.472,8592,3.347,9105,3.846,9106,5.71,9123,5.883,9139,6.457,9149,8.466,9150,3.29,9227,3.846,9239,3.982,9250,6.09,9251,9.816,9252,4.379,9253,4.152,9254,5.71,9255,4.152,9256,3.846,9257,8.622,9258,4.152,9259,4.152,9260,3.733,9261,4.152,9262,6.35,9263,4.152,9264,4.152,9265,4.379,9266,4.379,9267,4.152,9268,4.152,9269,4.152,9270,6.35,9271,4.152,9272,4.152,9273,4.379,9274,4.379,9275,4.379,9276,4.379,9277,4.379,9278,6.699,9279,4.379,9280,3.846]],["t/2727",[43,3.107,44,2.203,48,2.445,85,2.526,124,5.308,136,2.812,169,2.864,226,2.933,229,2.147,267,1.542,350,5.952,457,2.825,463,2.147,511,2.864,553,3.347,576,2.034,621,2.608,757,3.041,880,4.191,1015,3.108,1074,4.031,1403,7.418,1443,3.761,1565,7.418,1750,3.641,1772,5.308,1858,3.674,2171,4.814,2356,5.742,2853,5.308,2922,5.125,3345,3.855,3648,4.384,3656,6.327,3818,5.526,4429,4.46,4689,3.61,4713,5.259,5950,5.526,7944,4.46,9234,5.125,9280,5.125,9281,8.932,9282,8.932,9283,8.278,9284,7.056,9285,7.848,9286,7.056,9287,5.532,9288,5.532,9289,5.532,9290,5.532,9291,5.532,9292,5.532,9293,5.532,9294,5.835,9295,5.835,9296,5.532,9297,5.532,9298,5.532,9299,5.532,9300,5.835,9301,5.532,9302,5.532,9303,5.532,9304,5.532]],["t/2729",[33,3.393,164,4.22,267,2.532,408,5.83,473,3.04,491,4.423,654,4.188,1349,5.83,1431,4.84,1772,5.286,1789,6.787,1958,6.71,2394,8.71,9102,7.954,9178,8.71,9305,9.082]],["t/2731",[1,2.224,5,2.329,33,1.645,34,3.135,43,1.744,44,0.891,48,1.946,51,2.517,73,1.492,85,1.418,95,1.895,117,0.549,138,1.547,156,2.211,164,2.046,168,3.035,211,1.852,213,3.261,216,2.612,229,1.709,236,3.101,239,2.371,240,1.716,259,2.156,263,1.558,266,2.154,267,2.482,287,2.045,411,1.16,414,2.05,452,2.249,463,1.709,471,2.951,473,2.223,474,3.733,482,4.104,489,1.672,491,2.145,502,2.874,510,1.464,526,3.781,562,2.046,612,1.464,621,1.464,668,1.87,670,2.239,732,2.38,739,3.037,816,2.046,867,1.547,875,2.932,1008,2.078,1014,2.359,1024,2.27,1036,2.741,1071,2.612,1082,3.008,1097,3.097,1211,2.11,1213,2.805,1242,4.224,1387,3.616,1418,4.406,1442,3.688,1553,3.688,1591,3.55,1640,3.376,1772,2.563,1792,3.135,1841,4.485,1924,2.163,1926,2.683,2006,4.139,2074,3.037,2122,3.688,2178,3.688,2281,4.728,2300,2.805,2770,2.154,3256,2.421,3426,3.767,3495,5.453,3611,6.344,3671,3.037,3797,2.925,4325,3.291,4510,3.249,4713,2.951,5950,3.101,8168,4.404,8592,3.55,9139,3.688,9260,3.96,9306,5.453,9307,4.404,9308,10.078,9309,4.646,9310,4.646,9311,5.012,9312,4.404,9313,4.404,9314,4.08]],["t/2733",[33,2.205,97,2.073,259,2.386,404,5.231,405,4.157,406,6.28,412,3.188,486,4.195,666,4.44,814,2.266,834,2.507,1586,4.695,1612,3.436,1954,6.019,2018,3.335,2337,3.548,2619,3.245,2770,4.62,2838,4.759,3252,3.675,3609,4.605,3611,5.455,3638,4.113,3639,6.803,3659,3.675,4425,4.943,4687,5.61,7106,5.469,9045,4.679,9102,5.17,9121,5.469,9122,5.469,9125,4.759,9127,4.759,9140,4.943,9142,4.759,9149,4.536,9150,4.679,9155,4.943,9171,5.308,9177,5.662,9200,5.308,9218,5.469,9254,5.308,9256,5.469,9284,5.308,9286,5.308,9315,5.903,9316,6.227,9317,6.227,9318,5.903,9319,6.227,9320,5.903,9321,5.903,9322,5.903,9323,6.227,9324,6.227,9325,5.903,9326,5.662,9327,5.903,9328,6.227,9329,5.469,9330,5.903,9331,6.227,9332,5.903]],["t/2735",[5,1.016,21,1.362,25,2.44,38,1.741,44,2.187,86,2.204,89,5.132,95,1.792,117,1.226,138,1.463,156,2.828,164,1.936,169,4.826,194,1.792,208,1.398,221,2.266,227,2.845,242,2.381,259,1.367,263,1.474,267,1.775,287,1.283,398,1.747,412,3.358,470,1.452,483,1.804,487,1.886,526,1.769,527,1.577,529,1.659,580,3.42,597,2.794,611,1.988,621,2.116,649,2.081,669,3.859,681,2.127,737,2.157,752,4.266,757,4.756,764,2.012,790,2.903,799,3.358,834,2.704,867,1.463,875,1.528,881,2.845,923,1.245,987,1.694,1025,2.367,1033,2.395,1089,2.818,1098,5.309,1131,6.211,1149,3.488,1177,1.573,1186,3.648,1189,3.201,1204,1.936,1208,2.167,1211,1.996,1271,2.487,1273,1.854,1300,2.933,1312,2.966,1441,3,1480,2.653,1735,6.305,1788,5.001,1792,2.966,1838,2.766,1841,4.408,1979,3.113,2060,2.395,2170,3.563,2174,4.303,2230,3.237,2234,5.046,2288,6.211,3103,3.249,3214,3.563,3220,5.133,3316,3.42,3337,2.315,3501,3.358,4429,3.358,4900,6.768,5442,9.427,7126,3.995,9013,4.166,9229,3.859,9333,4.166,9334,4.394,9335,4.394,9336,4.394,9337,4.394,9338,4.394,9339,4.394,9340,4.394,9341,4.394,9342,4.394]],["t/2737",[1,1.94,5,2.667,30,1.624,44,1.411,48,3.081,52,5.527,73,2.362,83,2.067,93,4.876,117,0.87,136,3.545,138,2.449,156,1.928,167,4.513,204,5.621,214,2.769,217,4.441,259,1.974,287,2.832,349,5.725,350,4.551,445,4.309,473,2.334,490,3.265,510,2.318,555,2.879,570,5.282,576,3.381,597,3.06,737,3.61,809,2.584,818,4.058,890,3.68,1015,3.918,1147,5.839,1352,5.211,1418,3.216,1439,4.809,1637,6.688,1841,4.301,1983,6.46,2006,3.61,2060,4.01,2942,6.27,3277,6.973,8055,5.081,9306,5.725,9343,7.356]],["t/2740",[6,4.762,15,4.705,85,2.65,95,3.541,138,2.891,156,2.277,259,1.767,287,2.535,411,2.168,470,2.87,502,5.372,866,4.166,890,4.344,969,4.678,997,3.337,1014,4.409,1029,5.328,1131,6.463,1214,4.883,1239,5.419,1612,4.791,2169,7.042,2174,5.086,2460,7.626,3501,6.636,7977,7.21,9047,7.626,9098,8.683,9344,9.369]],["t/2742",[5,1.683,7,1.346,10,2.858,12,1.696,20,2.378,25,2.715,30,1.08,43,1.836,51,2.65,83,1.853,85,1.492,95,1.994,117,1.323,123,1.624,156,2.831,163,2.508,167,3.001,168,1.76,194,1.994,198,2.605,211,1.95,259,0.995,263,1.641,267,1.924,268,3.079,287,2.126,398,1.944,402,3.05,404,4.396,406,3.9,470,1.616,474,1.944,492,2.085,501,3.23,510,1.541,526,2.931,529,1.846,564,3.079,573,3.026,576,1.705,582,2.907,588,3.882,593,3.512,597,3.029,627,2.296,666,2.179,668,1.969,671,2.605,734,2.865,737,3.573,753,2.187,809,2.558,822,3.761,834,1.969,866,2.346,892,2.732,969,2.635,987,1.885,1090,2.62,1162,3.052,1181,3.993,1205,2.4,1208,2.412,1248,3.001,1256,5.666,1304,3.339,1402,3.166,1418,2.138,1478,2.825,1480,2.953,1489,2.768,1516,4.169,1582,3.882,1599,3.244,1640,2.357,1659,6.206,1715,2.138,1750,3.052,1825,3.079,1841,4.867,1967,2.635,1983,4.295,2006,2.4,2062,2.306,2770,4.032,3252,2.886,3256,2.548,3359,5.228,3495,3.806,3641,4.295,3656,3.738,4689,3.026,4713,3.107,5950,3.265,5997,4.169,7516,3.675,8055,3.378,8062,3.806,9099,4.169,9100,4.891,9101,4.446,9102,4.061,9103,4.891]],["t/2745",[12,2.191,25,3.508,33,2.237,43,3.77,115,2.351,117,0.747,138,2.104,156,2.842,172,1.577,226,3.176,263,2.119,264,3.176,266,4.058,404,3.814,406,3.384,474,3.479,492,3.731,496,3.701,526,2.543,529,2.385,535,3.845,625,4.917,668,2.543,729,4.828,732,2.973,752,4.014,875,3.043,923,1.79,978,2.152,998,2,1177,2.262,1187,3.275,1304,5.975,1443,3.976,1599,2.815,1657,5.385,1832,4.476,1841,2.503,1858,3.977,2006,4.296,2060,3.444,2304,3.045,2337,3.6,2770,2.929,2853,3.486,2881,2.732,3247,4.917,3256,5.649,3495,4.917,3638,5.781,3701,3.876,3797,3.977,4169,5.203,4261,3.943,4262,3.977,4506,4.917,4689,3.909,4713,4.014,5950,4.218,8473,5.385,9104,5.99,9105,5.548,9106,5.385,9107,5.123,9108,5.99,9109,6.318,9110,6.318,9111,6.318,9112,6.318]],["t/2747",[44,1.903,85,3.028,96,3.234,124,4.882,138,2.535,156,1.996,188,4.126,242,4.126,259,2.019,264,3.828,406,4.079,492,3.246,562,3.354,621,3.127,732,2.587,867,2.535,880,5.468,1019,3.809,1090,4.079,1841,3.932,1858,4.794,1958,5.813,2281,5.139,2356,4.176,2505,6.49,2669,6.322,2770,3.53,3256,3.967,3610,5.926,3611,4.794,4516,5.631,5074,6.687,5832,5.468,8114,7.583,9113,7.219,9114,7.614,9115,7.614,9116,7.219,9118,7.614,9119,7.614,9120,7.614,9121,6.687,9122,6.687,9123,6.687,9345,8.215]],["t/2750",[5,1.835,11,2.576,44,1.328,51,1.849,75,1.985,85,1.68,93,1.716,97,1.136,117,1.102,138,1.136,219,1.215,221,2.839,227,2.209,243,0.955,258,2.851,259,2.142,264,1.716,267,0.902,391,1.051,404,6.156,411,1.375,412,1.256,419,2.715,457,1.652,463,1.256,473,1.747,481,2.254,482,4.054,483,1.401,486,4.744,488,2.003,491,2.542,492,1.455,520,1.907,529,1.288,568,1.798,614,3.773,634,3.498,636,1.895,654,1.492,732,1.159,774,3.637,786,1.971,820,3.061,834,1.374,867,1.136,868,1.808,871,4.146,874,1.999,891,1.798,937,2.486,997,1.312,998,1.743,1019,1.707,1021,4.319,1066,1.818,1083,2.231,1149,2.709,1177,1.222,1209,2.768,1227,2.303,1282,2.709,1300,2.278,1307,1.999,1349,2.077,1374,2.387,1396,2.094,1443,3.144,1471,1.828,1478,1.971,1586,5.047,1607,1.465,1643,3.954,1715,1.492,1722,1.699,1727,1.308,1750,2.13,1772,3.038,1774,2.33,1776,1.919,1838,2.148,1841,1.352,1843,2.486,1858,5.485,1926,1.971,1954,3.076,1979,2.418,1988,2.175,2018,1.828,2171,1.569,2304,1.645,2357,4.319,2508,5.872,2673,2.231,2723,1.895,2754,3.202,2899,2.014,2934,3.406,2970,4.835,3256,5.106,3259,2.303,3638,2.254,3671,2.231,3672,2.451,3701,4.246,4411,2.451,4496,2.909,4593,5.301,4713,2.168,4863,4.693,5832,5.703,7913,2.834,8455,3.235,8592,2.608,8986,2.524,9000,2.656,9045,2.564,9091,3.235,9125,4.208,9126,3.235,9127,4.208,9128,3.235,9129,3.103,9130,3.235,9131,3.235,9132,8.259,9133,3.235,9134,3.235,9135,7.529,9136,2.909,9137,2.997,9138,6.561,9139,2.709,9140,5.493,9141,3.413,9142,4.208,9143,3.235,9144,3.235,9145,3.235,9146,3.235,9147,3.235,9148,3.235,9149,2.486,9150,7.362,9151,3.413,9152,3.413,9153,3.413,9154,3.413]],["t/2752",[1,1.897,5,1.662,44,1.38,97,2.395,117,1.27,164,3.168,229,2.647,259,2.491,291,4.342,486,3.482,654,3.145,820,2.772,875,2.501,1015,3.831,1037,4.703,1064,4.802,1204,3.168,1399,3.789,1772,3.969,1858,6.017,2161,5.497,3640,4.969,4457,5.096,4689,7.077,5832,6.864,8986,5.319,9000,5.598,9127,5.497,9149,8.917,9150,9.197,9155,8.52,9156,9.061,9157,6.819,9158,7.193,9159,7.193,9160,7.193,9161,7.193]],["t/2754",[1,2.383,5,1.529,7,1.821,30,1.687,33,1.848,44,0.613,48,2.186,85,0.975,95,1.303,97,1.064,115,1.189,117,0.782,124,3.346,148,0.879,164,2.914,165,1.487,168,1.15,193,3.036,213,1.487,242,2.828,249,1.59,259,2.431,262,1.606,267,1.379,338,3.466,402,1.338,414,2.235,445,1.871,473,1.014,486,5.668,489,1.15,504,1.885,510,1.007,530,2.471,586,1.546,594,2.11,607,0.945,634,2.029,665,2.11,666,3.403,671,2.779,732,2.86,759,1.583,767,2.029,768,1.96,814,3.063,817,1.845,818,1.763,870,4.945,875,1.111,886,3.126,976,2.181,985,1.033,1021,1.993,1035,3.256,1064,2.133,1090,1.711,1097,1.412,1120,3.875,1177,1.143,1205,1.568,1248,1.96,1274,2.652,1377,2.486,1399,5.237,1421,1.683,1455,1.96,1488,2.486,1612,1.763,1640,3.188,1715,1.397,1772,1.763,1778,1.622,1788,3.202,1790,1.568,1791,1.721,1841,1.266,1888,2.536,1924,1.487,1926,1.845,1989,3.256,2032,1.721,2170,2.591,2278,2.068,2281,2.156,2328,3.562,2337,1.82,2356,4.617,2625,2.4,2754,1.858,2769,3.921,2770,5.628,2771,2.4,2789,3.65,2790,2.089,2853,2.879,2905,2.441,2971,3.801,3252,4.507,3312,2.536,3640,2.207,3648,3.921,3659,4.968,3739,3.859,3818,3.484,3899,2.536,3918,2.048,4170,2.133,4419,2.591,4687,3.378,5289,2.904,6524,3.988,6867,2.486,8010,2.805,8647,2.723,8986,2.362,9149,8.619,9150,2.4,9162,2.904,9163,2.904,9164,3.028,9165,2.805,9166,2.652,9167,4.448,9168,3.028,9169,3.195,9170,5.218,9171,4.448,9172,3.195,9173,3.195,9174,3.195,9175,3.195,9176,3.195,9177,2.904,9178,2.904,9179,3.195,9180,3.195]],["t/2756",[1,1.163,5,1.888,9,3.046,11,1.641,18,3.212,25,2.448,33,1.561,34,2.976,38,2.668,44,1.292,85,1.345,117,0.796,139,1.399,156,2.831,168,1.587,177,2.174,236,2.943,239,2.25,259,2.409,264,2.216,288,2.728,291,2.662,402,1.847,404,2.662,405,2.943,406,4.375,412,3.624,463,1.622,473,1.399,474,1.753,486,3.26,488,1.604,490,1.957,491,3.109,495,1.995,511,3.305,546,2.776,576,1.537,629,2.362,634,2.801,666,1.964,748,1.822,757,2.297,799,3.37,814,1.604,867,1.468,875,1.533,909,2.943,923,1.908,1015,2.348,1029,2.705,1064,2.943,1118,3.124,1162,2.751,1187,2.285,1208,2.174,1211,2.003,1227,2.976,1240,4.18,1252,3.084,1304,5.576,1418,4.539,1424,3.5,1443,3.059,1449,2.389,1475,3.084,1586,2.389,1589,2.976,1612,3.715,1640,3.245,1722,3.352,1772,2.433,1801,2.495,1812,2.433,1841,4.114,1954,3.762,1958,4.785,2006,2.164,2018,2.362,2197,3.124,2216,5.739,2278,2.854,2357,2.751,2673,4.402,2754,2.564,2934,2.728,3076,3.313,3252,3.973,3259,2.976,3312,3.5,3609,3.26,3612,3.37,3640,6.316,3701,2.705,3797,4.239,4457,3.124,4687,2.854,4689,2.728,5832,3.166,6378,3.872,8633,4.009,8653,3.576,9140,3.5,9142,3.37,9155,3.5,9205,4.009,9206,4.409,9207,4.409,9209,6.733,9210,4.409,9211,4.18,9212,4.18,9213,4.18,9214,4.18,9215,4.18,9346,4.757,9347,4.409,9348,4.757]],["t/2758",[5,2.216,26,2.307,41,2.021,43,2.415,48,1.741,85,2.402,95,1.695,117,1.048,122,1.83,156,2.658,168,1.495,169,2.039,172,1.965,194,3.21,229,1.529,267,1.7,291,2.509,299,3.027,401,2.279,411,1.037,452,2.012,457,2.012,473,2.812,474,2.557,491,1.918,501,2.745,521,1.934,526,2.59,535,2.529,538,2.202,568,2.189,571,2.213,612,2.027,613,2.239,614,2.265,621,1.309,654,1.817,668,1.673,732,2.185,740,2.059,756,2.12,764,1.903,775,1.312,787,1.88,809,2.765,816,3.904,822,4.145,866,1.994,867,2.621,874,2.434,875,1.445,880,2.984,890,2.079,895,2.452,963,2.69,987,2.48,1014,2.11,1015,2.213,1034,3.542,1137,3.649,1140,2.529,1156,2.984,1181,3.528,1187,2.154,1195,2.64,1245,2.664,1266,2.774,1271,2.352,1273,1.753,1362,2.906,1382,3.122,1402,5.096,1418,3.441,1441,2.837,1442,3.298,1443,1.888,1644,3.298,1727,3.016,1749,2.593,1772,5.289,1789,2.944,1830,2.417,1841,3.798,1858,4.05,1868,3.122,1888,3.298,1958,5.192,2060,2.265,2100,3.778,2357,2.593,2571,4.686,2853,2.293,2899,2.452,2944,3.122,3256,3.352,3426,5.217,3652,6.248,3656,6.016,3671,4.206,3797,2.616,4169,2.47,4307,3.234,4375,3.542,4457,2.944,4506,3.234,4510,5.505,4516,3.073,4689,2.571,4713,2.64,5950,2.774,8546,3.778,9102,3.45,9223,4.155,9226,4.155,9227,3.649,9228,4.155,9229,5.65,9230,4.155,9233,3.939,9234,3.649,9349,4.483,9350,4.483,9351,6.941]],["t/2760",[1,2.081,97,2.628,115,3.779,243,2.208,259,2.285,486,5.436,740,3.91,923,2.236,987,3.042,1418,3.45,1457,4.925,1615,4.438,1715,3.45,1772,4.354,1896,4.803,3671,7.342,3672,8.064,3673,6.727,3700,8.919,3701,4.842,4261,6.337,4262,6.393,7713,6.4,9107,6.4,9149,8.18,9150,5.93,9235,7.175,9236,7.482,9237,7.482,9238,7.892,9239,7.175,9352,8.515]],["t/2762",[30,1.289,44,1.588,94,3.012,97,1.943,122,5.058,156,1.53,239,2.978,259,2.25,338,3.057,402,3.468,486,5.352,551,4.845,607,1.726,621,1.839,629,3.126,654,2.551,737,2.864,740,2.891,781,1.593,809,3.884,820,3.191,867,1.943,875,2.029,895,3.443,998,1.847,1074,5.719,1097,2.58,1715,2.551,1717,3.896,1841,4.38,2061,7.488,2072,6.591,2133,4.191,2144,4.849,2304,2.812,2881,2.523,3256,4.313,3638,5.468,3671,5.413,3672,4.191,4261,5.166,4262,5.212,4713,5.259,5950,5.526,8574,7.527,9149,8.053,9240,9.621,9241,7.848,9242,7.848,9243,5.532,9244,5.835,9245,5.835,9246,5.835,9247,5.835,9248,5.835,9249,5.532]],["t/2764",[5,0.847,43,3.784,44,0.703,48,3.04,85,1.118,89,3.668,94,1.333,97,1.22,117,0.433,156,0.96,163,1.879,164,3.196,168,2.097,222,3.575,259,2.248,263,1.229,339,2.847,412,2.144,414,1.072,473,1.849,474,1.456,486,5.641,528,1.899,538,1.254,544,1.985,594,2.42,597,1.524,614,1.997,621,1.154,629,1.962,723,3.81,737,1.798,740,1.815,819,2.395,834,2.346,875,1.273,880,2.63,882,1.997,890,1.832,923,1.038,991,1.734,1181,2.009,1312,2.472,1382,6.214,1403,5.141,1471,1.962,1478,4.191,1586,5.209,1596,2.323,1715,2.548,1750,2.286,1858,3.668,1868,2.752,1896,2.229,1958,2.146,2275,3.916,2337,3.32,2353,2.087,2356,2.009,2425,2.146,2521,2.851,2571,2.668,2816,3.33,2820,3.473,2934,2.266,2971,2.668,3148,3.041,3256,1.909,3337,1.929,3636,3.217,3638,5.963,3639,6.162,3701,3.575,3742,5.452,3818,4.844,4261,2.286,4262,2.306,4358,4.625,4510,2.562,4713,3.702,5950,4.844,6378,3.217,8592,2.799,9105,3.217,9106,4.967,9123,5.117,9139,4.625,9149,8.049,9150,2.752,9227,5.117,9239,3.33,9250,5.298,9251,9.919,9252,3.663,9253,5.524,9254,4.967,9255,3.473,9256,3.217,9257,7.927,9258,3.473,9259,3.473,9260,3.122,9261,3.473,9262,3.473,9263,3.473,9264,3.473,9265,3.663,9266,3.663,9267,6.879,9268,3.473,9269,3.473,9270,5.524,9271,3.473,9272,3.473,9273,3.663,9274,3.663,9275,3.663,9276,3.663,9277,3.663,9278,5.827,9279,3.663,9280,3.217,9327,3.473,9353,3.952,9354,6.287,9355,7.829,9356,3.952]],["t/2766",[5,1.126,43,3.257,44,1.393,48,2.041,85,2.215,97,1.622,122,2.146,124,3.124,136,2.348,138,1.622,168,2.613,169,4.259,226,2.449,229,1.793,259,0.991,264,2.449,267,1.288,350,5.369,408,2.965,457,4.656,463,1.793,473,1.546,474,1.937,492,2.077,511,2.391,553,4.164,562,2.146,575,3.837,576,1.698,621,2.288,663,2.278,740,2.414,757,2.539,880,5.214,969,2.625,1015,2.595,1074,3.366,1382,3.661,1403,6.813,1443,3.942,1457,3.04,1565,7.64,1750,3.04,1772,4.006,1841,1.931,1858,3.067,1888,3.867,1958,2.854,2171,3.338,2356,4.759,2853,5.95,2922,4.279,3345,3.218,3639,3.326,3648,5.455,3656,7.35,3818,5.793,4085,3.792,4429,3.724,4689,4.492,4713,4.612,4900,6.028,5419,3.867,5950,4.847,7944,3.724,9022,4.279,9193,4.43,9280,4.279,9284,6.189,9285,4.619,9286,7.397,9287,4.619,9288,4.619,9289,4.619,9290,4.619,9291,4.619,9292,4.619,9293,4.619,9294,4.872,9295,4.872,9296,4.619,9297,4.619,9298,4.619,9299,4.619,9300,4.872,9301,4.619,9302,4.619,9303,4.619,9304,4.619,9326,4.43,9357,5.257,9358,5.257,9359,5.257,9360,5.257,9361,5.257,9362,5.257,9363,5.257,9364,5.257,9365,5.257]],["t/2768",[33,3.343,164,4.158,267,2.495,408,5.745,473,2.996,491,4.359,654,4.128,740,4.678,1349,5.745,1431,4.769,1772,5.209,1789,6.688,1958,7.133,2394,8.584,9102,7.839,9178,8.584,9305,8.95]],["t/2770",[1,2.22,5,2.325,33,1.639,34,3.124,43,1.738,44,0.888,48,1.939,51,2.508,73,1.486,85,1.413,95,1.888,117,0.548,138,1.541,156,2.206,164,2.039,168,3.029,211,1.846,213,3.918,216,2.603,229,1.703,236,3.09,239,2.362,240,1.711,259,2.153,263,1.553,266,2.146,267,2.477,287,2.04,411,1.156,414,2.044,452,2.241,463,1.703,471,2.941,473,2.217,474,3.726,482,4.093,489,1.666,491,2.137,502,2.864,526,3.774,562,2.039,612,1.459,621,1.459,668,1.864,670,2.231,732,2.373,739,3.027,816,2.039,867,1.541,875,2.926,1008,2.07,1014,2.35,1024,2.262,1036,2.732,1071,2.603,1082,2.997,1097,3.089,1211,2.103,1213,2.795,1242,4.209,1273,1.953,1387,3.603,1418,4.399,1442,3.674,1553,3.674,1591,3.538,1640,3.367,1772,2.554,1792,3.124,1841,4.585,1924,2.155,1926,2.674,2006,4.131,2074,3.027,2122,3.674,2178,3.674,2281,4.716,2770,2.146,3256,2.412,3426,3.754,3495,5.438,3611,6.334,3671,3.027,3797,2.914,4325,3.28,4510,3.237,4713,2.941,5950,3.09,8168,4.389,8592,3.538,9139,3.674,9260,3.946,9306,5.438,9307,4.389,9308,10.062,9309,4.629,9310,4.629,9312,4.389,9313,4.389,9314,4.065,9366,4.994]],["t/2772",[33,2.205,97,2.073,259,2.386,404,5.231,405,4.157,406,6.28,412,3.188,486,4.195,666,4.44,814,2.266,834,2.507,1586,4.695,1612,3.436,1954,6.019,2018,3.335,2337,3.548,2619,3.245,2770,4.62,2838,4.759,3252,3.675,3609,4.605,3611,5.455,3638,4.113,3639,6.803,3659,3.675,4425,4.943,4687,5.61,7106,5.469,9045,4.679,9102,5.17,9121,5.469,9122,5.469,9125,4.759,9127,4.759,9140,4.943,9142,4.759,9149,4.536,9150,4.679,9155,4.943,9171,5.308,9177,5.662,9200,5.308,9218,5.469,9254,5.308,9256,5.469,9284,5.308,9286,5.308,9315,5.903,9316,6.227,9317,6.227,9318,5.903,9319,6.227,9320,5.903,9321,5.903,9322,5.903,9323,6.227,9324,6.227,9325,5.903,9326,5.662,9327,5.903,9328,6.227,9329,5.469,9330,5.903,9331,6.227,9332,5.903]],["t/2774",[25,2.44,38,1.741,44,2.187,86,2.995,89,5.132,95,1.792,117,1.226,138,1.463,156,2.828,164,1.936,169,4.826,194,1.792,196,1.418,208,1.398,221,2.266,227,2.845,242,2.381,259,1.367,263,2.253,267,1.775,287,1.961,398,1.747,412,3.358,470,1.452,483,1.804,487,1.886,527,1.577,529,1.659,580,3.42,597,2.794,611,1.988,621,2.116,649,2.081,669,3.859,681,2.127,737,2.157,752,4.266,757,4.756,764,2.012,790,2.903,799,3.358,834,2.704,867,1.463,875,1.528,923,1.245,978,1.497,987,1.694,1025,2.367,1033,2.395,1089,2.818,1098,5.309,1131,5.891,1149,3.488,1177,1.573,1185,2.742,1186,3.648,1189,3.201,1204,1.936,1208,2.167,1211,1.996,1271,2.487,1300,2.933,1312,2.966,1441,3,1735,6.305,1773,2.556,1788,5.001,1838,2.766,1841,4.518,1979,3.113,2060,2.395,2174,3.843,2230,3.237,2234,5.046,2288,6.211,3103,3.249,3214,3.563,3220,5.133,3316,3.42,3337,2.315,4429,3.358,4900,6.768,5442,9.427,5828,4.394,7126,3.995,9013,4.166,9229,3.859,9333,4.166,9334,4.394,9335,4.394,9336,4.394,9337,4.394,9338,4.394,9339,4.394,9340,4.394,9341,4.394,9342,4.394,9367,4.741]],["t/2776",[1,1.94,5,2.667,30,1.624,44,1.411,48,3.081,52,5.527,73,2.362,83,2.067,93,4.876,117,0.87,136,3.545,138,2.449,156,1.928,167,4.513,204,5.621,214,2.769,217,4.441,259,1.974,287,2.832,349,5.725,350,4.551,445,4.309,473,2.334,490,3.265,510,2.318,555,2.879,570,5.282,576,3.381,597,3.06,737,3.61,809,2.584,818,4.058,890,3.68,1015,3.918,1147,5.839,1352,5.211,1418,3.216,1439,4.809,1637,6.688,1841,4.301,1983,6.46,2006,3.61,2060,4.01,2942,6.27,3277,6.973,8055,5.081,9306,5.725,9343,7.356]],["t/2779",[11,3.343,21,2.785,74,6.133,86,2.948,208,2.857,214,3.382,267,2.374,287,2.623,668,3.617,991,4.254,1118,6.365,1131,5.382,1177,3.216,1180,6.55,1187,5.71,1249,5.084,1609,4.927,1692,8.517,1819,5.225,1989,5.606,2174,4.236,2453,5.558,4614,7.285,9033,8.517]],["t/2781",[38,3.972,156,3.085,259,2.04,287,2.927,1304,6.843,1678,5.432,1812,5.531,1841,3.972,2104,8.544,9368,10.024]],["t/2783",[1,1.751,30,1.466,39,4.299,43,2.493,47,2.575,71,4.645,73,2.908,81,3.919,83,2.196,117,0.785,123,2.206,138,2.211,156,3.038,172,2.261,173,4.482,208,2.112,263,2.228,266,4.199,288,4.109,401,3.642,411,1.658,473,2.107,474,2.64,496,3.89,597,2.763,612,2.093,613,3.578,615,2.623,652,3.389,659,2.754,660,3.066,687,4.705,696,5.271,712,3.836,799,6.922,831,3.498,840,3.863,1015,3.537,1025,3.578,1075,4.144,1118,4.705,1159,3.734,1170,3.054,1489,3.759,1596,2.648,1617,4.258,1674,5.514,1776,3.734,1799,3.978,1830,5.268,1841,4.936,2839,6.296,2896,5.514,3701,4.075,8390,5.169,9369,7.165,9370,7.165,9371,7.165,9372,7.165]],["t/2786",[38,3.146,43,2.98,44,1.523,156,2.952,211,3.166,239,4.052,259,1.616,406,4.253,463,2.922,483,3.26,799,6.068,890,5.1,923,2.889,961,7.322,1075,6.362,1399,4.182,1715,4.457,1841,4.04,1914,4.278,2006,5.004,2230,5.427,2571,5.784,2703,5.625,2770,3.681,3256,5.312,3428,6.068,3671,5.192,3873,7.13,8055,7.043,9373,11]],["t/2788",[2425,6.31,4614,8.735]],["t/2790",[1,2.527,47,3.715,83,2.041,123,3.182,156,3.003,164,4.22,173,6.466,287,2.797,288,5.927,297,3.04,465,7.456,659,3.972,1841,3.796,2006,4.702,4350,6.143,9221,8.71]],["t/2792",[731,7.032]],["t/2795",[0,5.357,1,2.513,2,1.821,3,2.838,5,0.948,12,1.423,15,5.164,22,3.206,36,2.421,41,3.098,85,1.252,86,2.562,90,1.626,106,2.149,117,0.485,148,1.129,152,3.406,172,1.024,208,1.305,211,1.636,214,1.544,240,1.913,259,2.366,287,1.86,304,2.477,315,4.256,338,2.149,391,1.263,398,1.631,402,2.669,418,2.223,420,2.403,457,3.084,469,2.517,470,1.356,481,2.71,483,1.684,486,1.986,487,4.518,495,5.581,496,2.403,506,2.386,509,3.257,513,2.439,514,3.452,527,1.473,575,1.814,579,3.114,582,2.439,584,2.052,585,2.769,612,2.007,627,3.666,654,1.794,732,1.394,737,2.014,756,2.094,787,3.983,840,2.386,867,1.366,991,3.016,1045,2.869,1052,2.834,1079,3.73,1089,2.631,1131,2.458,1191,2.907,1271,2.322,1275,6.37,1327,2.477,1398,5.669,1418,2.785,1421,4.113,1480,2.477,1607,1.761,1640,1.977,1674,3.406,1711,2.497,1712,3.732,1715,2.785,1778,2.083,1910,2.606,1914,2.21,1923,4.916,1924,1.91,1989,2.56,2024,2.869,2174,1.934,2571,2.989,2669,3.406,2723,4.887,2899,2.421,3068,3.406,3071,4.51,3148,3.406,3469,4.868,3503,3.135,3932,2.989,4145,3.406,4169,2.439,4441,3.083,4502,2.907,5444,3.497,7913,3.406,8117,3.327,8363,3.603,8399,3.889,8598,3.889,8618,4.103,8619,4.103,9034,4.103,9374,4.427]],["t/2797",[5,2.443,21,2.605,136,4.049,148,2.312,197,4.224,207,5.671,229,3.092,259,1.71,287,2.453,288,5.199,454,5.736,495,4.782,510,2.648,560,3.962,575,3.715,584,4.203,597,3.496,734,4.922,757,4.378,816,3.701,840,4.887,923,2.381,987,3.239,1398,5.507,1715,3.674,1778,4.266,1924,3.912,1926,4.853,1989,5.243,2074,5.494,4285,6.034,8390,6.54,8631,7.966]],["t/2799",[5,2.433,7,2.298,21,3.263,22,3.427,87,3.089,88,4.176,163,4.282,259,1.699,263,2.801,287,3.073,397,5.256,457,4.041,492,3.559,495,3.778,520,4.664,668,3.361,757,4.35,785,4.635,910,5.405,1184,7.116,1271,4.725,1398,4.35,1579,5.839,1596,3.329,1708,6.77,1778,4.239,1924,3.886,5498,4.551,8473,7.116,8622,7.116,9017,7.116,9375,9.007,9376,9.007,9377,9.007]],["t/2801",[5,2.007,7,2.39,123,2.884,219,3.092,257,6.236,259,1.767,287,3.15,391,2.674,470,2.87,495,5.555,875,3.019,1177,3.108,1364,5.998,1396,5.328,1398,5.621,1478,5.015,1591,6.636,1609,4.762,1617,5.568,1732,4.762,1778,4.409,2304,4.185,3463,6.758,4285,6.236,6250,8.232,8631,8.232]],["t/2803",[5,2.182,21,2.927,30,2.085,43,3.544,47,3.661,123,3.136,207,6.372,221,4.868,287,2.756,495,4.272,597,3.928,668,3.801,816,4.158,1398,4.919,1607,4.053,1610,8.291,1799,5.656,2074,6.173,8390,7.348]],["t/2805",[3,4.417,21,1.912,47,3.845,86,3.253,97,2.054,138,2.866,148,1.697,156,2.257,168,2.22,196,2.777,208,1.962,226,3.101,229,2.27,259,1.751,262,3.101,263,2.887,264,4.984,266,3.99,315,3.362,437,4.509,495,5.107,579,2.459,580,4.8,584,3.086,597,4.125,689,7.147,732,2.924,753,4.798,801,4.118,840,5.767,868,3.267,912,3.132,923,2.439,1025,3.323,1359,7.12,1398,5.166,1519,5.238,1607,2.648,1640,2.972,1647,3.883,1778,3.132,1910,5.468,1954,3.446,2033,4.493,2271,5.683,7287,9.423,9378,9.287,9379,6.168,9380,6.168,9381,6.168]],["t/2807",[11,2.662,15,5.801,86,2.347,97,2.382,156,2.497,194,2.917,258,2.946,259,2.178,262,3.596,264,3.596,265,5.578,266,3.316,437,4.989,487,3.071,491,3.303,495,5.733,598,3.578,627,3.358,732,2.43,753,3.199,801,4.775,868,3.789,875,2.487,882,5.191,955,3.263,1025,5.13,1079,6.504,1191,5.068,1271,4.048,1359,6.838,1398,6.193,1421,5.016,1715,3.127,1838,4.503,1910,6.8,3337,5.016,4441,5.374,8174,6.781]],["t/2809",[41,5.051,85,2.494,86,4.117,88,2.868,97,1.909,117,0.678,142,4.176,188,5.162,194,3.334,221,2.956,227,5.292,243,1.604,263,2.742,266,2.658,287,2.781,420,3.358,470,1.895,473,1.819,481,3.786,486,2.775,514,3.106,597,2.385,612,3.002,627,2.691,689,4.759,719,2.75,732,1.947,740,4.05,753,2.564,757,4.259,760,2.987,787,2.594,874,3.358,875,2.842,955,2.615,991,2.714,1024,2.8,1114,3.609,1118,4.061,1150,4.176,1177,3.41,1214,3.223,1271,3.244,1332,6.188,1357,6.968,1359,4.117,1519,3.488,1715,2.506,1735,3.96,1769,4.461,1772,4.51,2024,4.009,2165,4.061,2360,4.239,2429,3.96,2723,4.538,3067,4.061,3070,5.717,3071,3.311,3215,5.434,3506,2.8,7287,5.034,9018,8.662,9019,9.846,9382,6.185]],["t/2811",[10,2.887,36,4.34,44,1.861,47,4.209,86,3.183,90,2.915,97,2.449,156,3.025,169,3.61,211,2.933,227,7.471,243,2.058,262,3.698,263,3.254,266,3.41,287,3.596,437,5.082,462,4.551,531,3.94,579,2.933,621,2.318,627,3.453,649,3.483,689,6.107,732,2.499,753,3.29,757,5.655,801,4.91,868,3.896,907,5.439,1025,3.963,1359,7.794,1830,4.278,1841,3.844,7287,6.46,9383,7.936]],["t/2813",[6,2.512,44,1.329,47,4.474,73,1.471,85,1.398,86,1.503,97,2.308,117,0.989,123,1.521,156,1.201,169,2.248,173,4.678,188,3.756,198,2.439,208,2.204,223,3.289,224,2.399,226,2.302,227,2.965,243,1.939,249,3.45,258,2.855,259,0.932,266,3.213,267,1.21,268,2.883,287,2.024,288,4.288,335,5.394,414,2.028,437,2.399,481,4.578,483,1.88,488,1.667,495,2.072,530,2.169,578,2.723,579,1.826,580,3.565,584,2.291,597,1.906,612,1.443,613,2.467,614,2.497,615,1.809,617,2.609,621,3.32,633,3.565,659,1.899,663,3.24,666,2.04,732,2.354,753,3.739,757,2.386,758,5.501,764,2.097,775,1.447,799,3.5,809,1.609,907,5.125,908,3.334,912,2.325,923,1.298,959,3.441,967,3.091,1008,2.048,1025,5.023,1093,3.904,1114,2.883,1286,2.609,1307,2.683,1322,3.636,1349,2.787,1359,7.566,1398,2.386,1465,2.227,1487,3.203,1519,4.218,1596,2.764,1614,3.091,1615,2.575,1732,3.801,1792,3.091,1830,2.664,1841,1.815,1874,2.883,1895,3.387,1909,3.164,2271,5.58,2363,3.203,2392,3.714,3136,4.342,3237,4.342,3321,3.904,3701,2.81,4070,3.164,4593,3.058,5211,6.302,7287,4.022,9087,4.342,9220,5.297,9257,4.022,9380,4.58,9381,4.58,9384,6.931,9385,4.942,9386,4.942,9387,7.478]],["t/2815",[3,3.138,15,3.817,17,2.225,44,2.226,47,3.92,48,1.96,86,3.616,88,2.341,90,1.854,136,2.255,156,3.1,172,2.353,173,6.361,211,1.866,243,1.309,259,1.433,276,2.451,287,3.218,335,3.642,338,2.451,414,3.108,437,4.938,470,1.547,487,3.024,576,1.631,621,1.474,663,3.96,757,3.67,758,7.481,785,2.598,834,1.884,907,6.264,1118,4.99,1131,4.22,1204,2.061,1332,3.71,1465,4.119,1487,5.924,1776,2.631,1830,2.721,1831,4.109,1841,3.735,1910,2.972,1923,2.946,2024,4.926,2168,3.714,2174,2.206,2271,2.478,2360,3.46,2380,2.352,2971,3.408,3067,4.99,3469,7.203,3600,3.46,3701,2.871,5211,7.701,5498,2.551,8174,6.678,8363,7.439,8364,4.254,8628,4.254,8634,3.795,9015,4.436,9018,6.404,9019,8.935,9033,4.436,9220,5.383,9379,4.679,9384,4.679,9388,5.048,9389,5.048,9390,5.048,9391,5.048,9392,5.048,9393,5.048]],["t/2817",[22,3.201,29,4.707,45,6.189,51,4.225,73,2.504,85,2.379,86,3.306,88,3.901,165,3.63,213,5.689,220,6.367,263,2.616,457,3.775,495,3.528,579,4.018,612,3.175,627,3.661,630,4.601,923,2.209,1351,5.15,1373,5.68,1396,4.784,1398,4.063,1487,5.453,1629,7.535,2999,5.766,3337,5.308,3506,3.809,4285,5.599,4318,6.189,5419,6.189,5498,4.25,6730,10.077]],["t/2820",[1,2.321,21,2.729,40,4.981,117,1.041,196,2.839,267,2.326,443,3.982,575,3.891,597,3.662,638,6.32,654,3.848,668,4.379,740,4.361,809,3.822,840,6.327,971,5.048,1062,4.3,1213,5.313,1418,3.848,1711,5.356,1712,5.156,1718,7.137,2074,5.754,8114,6.726,9045,6.613,9099,7.502]],["t/2822",[44,1.747,52,6.845,117,1.077,165,4.241,211,3.632,250,3.939,263,3.056,267,2.407,287,3.244,495,5.425,506,5.298,612,2.87,875,3.167,977,6.962,1008,4.969,1189,6.636,1341,7.231,1471,4.88,1519,5.544,1615,5.122]],["t/2824",[87,3.493,208,3.873,259,2.478,288,5.841,495,4.272,597,3.928,637,5.275,645,4.222,687,6.688,764,4.323,775,2.982,840,5.491,1878,6.236,2350,6.302,9220,7.215]],["t/2827",[20,4.951,21,3.156,287,2.972,490,4.518,515,8.678,1272,7.528,1528,7.311,9045,7.649,9394,10.984]],["t/2830",[15,5.191,85,2.923,95,3.907,259,1.949,287,2.797,470,3.166,866,4.596,969,5.161,997,3.682,1014,4.864,1029,5.878,1214,5.387,1239,5.978,2169,7.769,2275,4.536,2460,8.413,8004,9.58]],["t/2832",[1,1.683,5,1.475,7,1.756,10,3.459,12,2.212,25,3.542,43,2.395,51,3.457,83,2.151,117,1.042,123,2.119,156,2.646,163,3.272,167,3.914,172,1.593,194,2.602,259,1.793,263,2.14,267,2.329,402,3.691,404,3.852,406,3.417,470,2.109,474,2.536,492,2.72,510,2.01,526,3.547,564,4.016,582,3.793,588,5.064,668,2.568,671,3.398,753,2.853,809,2.241,822,3.81,866,3.061,987,2.459,998,2.02,1090,3.417,1181,3.499,1205,3.131,1248,3.914,1304,4.355,1402,4.13,1418,2.789,1478,3.685,1516,5.438,1599,3.926,1715,2.789,1841,4.963,1967,3.437,2770,4.085,3256,3.324,3259,4.306,3359,6.328,3495,4.966,3656,4.876,4689,3.947,5997,5.438,7516,4.794,8062,4.966,9099,5.438,9395,6.884]],["t/2835",[33,2.745,43,4.179,115,2.884,138,2.581,264,3.896,266,4.654,404,4.679,406,4.152,492,4.279,535,4.717,732,3.41,752,4.924,923,2.196,998,2.454,1443,4.56,1599,3.453,1620,7.047,1657,6.607,1858,4.879,2337,4.416,2770,3.593,2853,4.276,2881,3.352,3256,6.135,3638,6.63,3701,4.755,4169,5.968,4261,4.837,4262,4.879,4689,4.795,4713,4.924,5950,5.174,9104,7.348,9105,6.807,9106,6.607,9107,6.285,9108,7.348,9396,8.362]],["t/2837",[44,1.677,85,2.668,96,3.713,124,5.605,242,4.737,259,1.779,492,3.726,621,3.709,732,2.97,822,3.78,1402,5.659,1858,5.503,2356,5.941,2770,4.053,3256,4.555,5074,7.677,9113,8.288,9116,8.288,9235,7.948,9397,9.432,9398,9.432,9399,9.432,9400,9.432,9401,8.742,9402,9.432,9403,9.432,9404,7.948]],["t/2840",[5,0.96,11,2.394,44,1.51,51,2.252,75,2.417,85,1.963,97,1.384,117,1.048,138,1.384,219,1.479,221,3.317,243,1.163,258,1.711,259,2.223,264,2.089,404,6.121,411,1.606,412,1.529,419,3.172,445,2.434,457,2.012,463,1.529,473,2.041,481,2.745,482,3.769,483,1.706,488,2.341,491,1.918,568,2.189,614,4.291,623,2.69,634,4.087,636,2.307,654,1.817,732,1.412,820,3.034,867,1.384,868,2.201,871,3.854,937,3.027,986,2.944,997,1.597,1019,2.079,1021,4.912,1066,2.213,1083,2.717,1177,1.487,1209,3.37,1227,2.804,1282,3.298,1374,2.906,1396,2.549,1443,3.576,1471,2.226,1478,2.4,1586,5.195,1640,3.1,1643,4.62,1715,1.817,1750,2.593,1772,3.549,1776,2.336,1838,2.616,1843,3.027,1858,5.579,1954,3.594,1979,2.944,1988,1.641,2018,2.226,2304,2.002,2357,4.912,2508,4.757,2723,2.307,2754,3.742,2934,3.98,2970,5.65,3256,5.283,3259,2.804,3638,2.745,3701,3.947,4411,2.984,4496,3.542,4593,5.255,4713,2.64,4863,5.484,5832,6.364,8592,3.176,8986,3.073,9000,3.234,9045,3.122,9125,4.916,9126,3.939,9127,4.916,9128,3.939,9129,3.778,9130,3.939,9131,3.939,9132,8.402,9133,3.939,9134,3.939,9135,7.463,9136,3.542,9137,3.649,9138,6.099,9139,3.298,9140,5.106,9142,4.916,9143,3.939,9144,3.939,9145,3.939,9146,3.939,9147,3.939,9148,3.939,9405,3.542,9406,4.483,9407,4.483,9408,4.483,9409,4.483,9410,4.483,9411,4.483]],["t/2842",[1,2.044,5,1.791,44,1.487,94,2.82,97,2.581,117,1.187,164,3.414,229,2.852,259,2.543,291,4.679,654,3.389,820,2.987,875,2.695,1015,4.128,1037,5.068,1064,5.174,1399,4.082,1640,3.735,1772,4.276,1858,4.879,2161,5.923,3640,5.354,4457,5.491,4689,6.888,5832,7.208,8986,5.731,9000,6.032,9155,8.837,9156,7.348,9157,7.348,9405,6.607,9412,7.348,9413,8.362,9414,8.362,9415,8.362,9416,8.362,9417,8.362,9418,8.362]],["t/2844",[1,2.705,5,1.289,7,1.535,30,2.072,33,1.975,44,1.342,48,2.336,85,1.058,97,1.155,115,1.29,117,0.948,124,3.576,148,0.954,164,3.081,193,2.781,213,1.614,242,3.022,249,1.726,259,2.49,262,1.743,267,1.474,339,1.694,387,8.326,402,1.453,414,2.345,445,2.031,473,1.1,504,2.046,510,1.093,530,2.641,586,1.679,594,2.29,634,2.203,665,2.29,666,3.913,671,2.97,732,3.187,759,1.718,767,2.203,814,3.414,817,2.003,818,1.913,870,6.074,875,1.205,886,3.341,976,2.367,985,1.121,1064,2.315,1090,1.857,1097,1.533,1120,4.098,1177,1.241,1205,1.702,1248,2.127,1274,2.879,1399,5.402,1488,2.699,1640,2.688,1715,1.516,1772,1.913,1788,3.422,1790,1.702,1791,1.868,1888,2.752,1926,2.003,1989,5.001,2032,1.868,2170,2.812,2328,3.807,2337,1.976,2356,4.395,2769,4.19,2770,5.63,2789,3.9,2790,2.267,2853,3.077,2905,2.65,2971,4.062,3252,4.128,3312,2.752,3640,2.395,3648,4.19,3659,5.183,3739,4.124,3818,3.723,4419,2.812,4616,4.898,4687,2.245,5289,3.153,6524,2.65,6867,2.699,8986,2.564,9107,7.998,9162,3.153,9163,3.153,9164,3.287,9165,3.045,9166,2.879,9167,4.754,9168,3.287,9171,4.754,9404,5.07,9405,2.956,9419,8.015,9420,7.548,9421,6.017,9422,10.122,9423,3.287,9424,3.467,9425,6.017,9426,3.741]],["t/2846",[1,2.147,97,2.71,115,3.855,243,2.277,259,2.318,923,2.306,987,3.137,1418,3.558,1457,5.079,1615,4.577,1715,3.558,1772,4.491,1896,4.953,3671,7.449,3672,8.182,3673,6.938,3700,9.096,3701,4.994,4261,6.464,4262,6.521,7713,6.6,9107,9.239,9235,7.4,9236,7.716,9237,7.716,9405,9.711,9423,7.716]],["t/2848",[30,1.452,44,1.261,94,3.273,97,2.189,122,5.086,156,1.723,239,3.355,259,2.243,402,3.768,551,5.458,607,1.945,621,2.071,629,3.521,654,2.874,737,3.226,781,1.794,809,3.873,820,2.534,867,2.189,875,2.285,998,2.081,1074,6.214,1097,2.906,1715,2.874,1717,4.388,1841,4.575,2061,7.001,2072,6.941,2144,5.269,2881,2.843,3256,4.687,3638,5.942,3671,5.881,3672,4.721,3700,5.773,4261,4.102,4262,4.138,4713,4.176,5950,4.388,8574,5.977,9241,6.232,9242,6.232,9243,6.232,9249,6.232,9401,11.547,9419,11.026,9427,7.093]],["t/2850",[5,1.126,43,4.193,48,3.635,89,4.571,94,1.773,97,1.622,156,1.277,163,2.499,164,3.198,168,2.613,222,4.455,259,2.43,339,3.547,387,8.227,412,2.671,473,1.546,474,2.886,486,3.515,597,2.027,723,3.186,834,2.923,1312,3.288,1382,5.455,1403,6.148,1478,5.012,1586,4.703,1596,1.943,1715,3.794,1858,4.571,1896,2.965,2275,4.554,2337,4.136,2521,3.792,2971,3.549,3256,3.783,3636,4.279,3638,5.732,3639,5.924,3701,2.989,3818,3.253,4358,6.888,4713,3.095,5950,3.253,8592,3.724,9106,4.153,9107,8.34,9123,6.376,9139,5.763,9227,4.279,9250,6.601,9251,9.75,9253,4.619,9254,6.189,9255,4.619,9256,4.279,9257,9.032,9258,4.619,9259,4.619,9260,4.153,9261,4.619,9262,4.619,9263,4.619,9264,4.619,9267,4.619,9268,4.619,9269,4.619,9270,4.619,9271,4.619,9272,4.619,9405,10.18,9423,6.883,9428,7.833]],["t/2852",[5,2.028,33,1.758,43,2.764,44,2.214,48,3.085,85,2.678,94,1.807,95,2.025,124,4.721,136,2.393,137,2.187,156,1.93,164,2.187,169,2.437,194,2.025,222,4.518,226,2.496,229,1.827,267,1.946,350,4.556,457,2.404,463,1.827,473,1.576,491,2.292,510,1.565,511,2.437,553,2.848,576,1.731,621,2.765,629,2.66,654,2.171,757,2.587,880,3.566,912,2.521,1015,2.645,1074,3.43,1227,3.351,1349,3.022,1403,6.877,1441,3.39,1443,3.345,1565,6.877,1750,3.098,1772,5.356,1841,3.846,1858,3.126,1958,4.313,2171,4.463,2356,4.813,2853,4.842,2922,4.361,3345,3.28,3495,3.865,3648,3.731,3656,5.627,3818,4.915,4100,3.43,4429,3.795,4506,3.865,4510,3.473,4689,3.072,4713,4.678,5950,4.915,7944,3.795,8055,3.43,8524,4.707,9234,4.361,9280,4.361,9283,7.363,9284,6.276,9285,6.98,9286,6.276,9287,4.707,9288,4.707,9289,4.707,9290,4.707,9291,4.707,9292,4.707,9293,4.707,9296,4.707,9297,4.707,9298,4.707,9299,4.707,9301,4.707,9302,4.707,9303,4.707,9304,4.707,9305,4.707,9306,3.865,9404,4.514,9429,5.357,9430,7.944,9431,5.357]],["t/2854",[33,2.293,97,2.156,259,2.415,404,5.375,406,6.357,412,3.276,486,3.135,666,4.532,814,2.356,834,2.607,1586,4.824,1954,6.121,2018,3.469,2337,3.689,2619,3.374,2770,4.716,2838,4.949,3252,3.821,3611,4.077,3638,4.277,3639,6.077,3659,3.821,4687,5.763,7106,5.687,9045,4.865,9121,5.687,9122,5.687,9125,4.949,9127,4.949,9140,5.14,9142,4.949,9155,5.14,9171,5.52,9200,5.52,9218,5.687,9225,6.476,9254,5.52,9284,5.52,9286,5.52,9315,6.139,9318,6.139,9320,6.139,9321,6.139,9322,6.139,9325,6.139,9326,5.887,9329,5.687,9330,6.139,9332,6.139,9404,5.887,9405,5.52,9424,6.476,9432,6.987,9433,6.987,9434,6.987,9435,6.987,9436,6.987,9437,6.987,9438,6.987,9439,6.987]],["t/2856",[1,1.648,30,1.697,33,1.417,44,1.807,83,0.852,85,2.345,117,0.473,164,1.763,169,1.964,214,1.506,229,1.472,259,2.655,287,1.824,338,2.096,402,1.676,404,2.416,406,3.346,414,1.171,445,2.344,578,2.379,579,1.596,598,2.002,612,1.261,732,1.359,757,3.255,814,2.273,832,2.28,875,2.172,879,2.497,1009,2.401,1074,2.764,1090,3.346,1170,1.84,1181,2.194,1187,2.074,1231,2.096,1399,4.574,1418,2.731,1444,3.514,1478,2.311,1519,2.435,1612,2.208,1640,4.185,1727,2.394,1753,2.143,1773,2.327,1841,3.956,1946,3.245,1974,2.194,2123,2.566,2145,2.435,2171,1.84,2278,2.591,2281,2.701,2356,2.194,2357,2.497,2619,3.255,2754,2.327,2769,4.694,2770,4.834,2872,2.701,2881,2.702,3256,3.255,3611,2.519,3638,2.643,3639,2.732,3640,2.764,3659,3.687,3805,3.176,3818,2.671,3918,2.566,4169,2.379,4285,2.874,4344,3.411,4424,3.322,4502,2.835,5498,2.181,5832,2.874,7007,3.638,7977,3.322,8010,3.514,8062,3.114,9045,3.007,9124,3.638,9125,3.058,9127,3.058,9167,3.411,9181,4.002,9182,4.002,9183,4.002,9184,4.002,9185,4.002,9186,4.002,9187,4.002,9188,4.002,9189,4.002,9190,4.002,9191,4.002,9192,4.002,9194,4.002,9195,4.002,9196,4.002,9197,3.794,9198,3.794,9199,3.794,9200,3.411,9201,3.794,9202,6.248,9203,3.794,9204,3.794,9440,4.317,9441,4.317,9442,4.317,9443,4.317,9444,4.317,9445,4.317,9446,4.317,9447,4.002,9448,4.317,9449,4.317,9450,4.317,9451,4.317,9452,4.317,9453,4.317,9454,4.317,9455,4.317,9456,4.317,9457,4.317,9458,4.317,9459,4.317,9460,4.317,9461,4.317,9462,4.317,9463,6.741,9464,4.317,9465,4.317,9466,4.317]],["t/2858",[1,1.143,5,1.536,10,1.702,11,2.474,16,2.617,18,3.158,25,2.407,34,2.926,85,2.028,95,1.768,96,1.842,156,2.376,168,1.56,177,3.278,236,2.894,239,2.212,242,2.349,257,3.113,259,2.359,265,2.54,287,1.266,291,2.617,404,2.617,406,3.56,412,1.595,463,1.595,473,2.109,474,1.723,483,2.729,487,1.861,488,2.419,490,1.924,491,2.002,495,1.962,510,1.366,511,3.263,546,2.729,630,2.558,631,2.864,634,2.754,748,1.792,822,1.875,867,3.018,874,3.894,875,2.311,880,3.113,896,2.558,908,1.729,909,2.894,923,2.291,963,2.807,1015,2.309,1029,2.66,1064,2.894,1162,2.705,1187,3.445,1208,2.138,1211,1.97,1252,3.032,1277,2.47,1304,6.672,1418,4.694,1424,3.441,1443,3.02,1475,3.032,1586,2.349,1589,2.926,1615,2.438,1640,3.203,1722,3.309,1749,2.705,1769,3.374,1772,2.392,1773,2.522,1801,2.454,1841,4.389,1888,3.441,1926,2.504,1954,3.714,1958,2.54,2006,2.128,2100,3.942,2197,3.072,2281,2.926,2357,2.705,2466,3.258,2571,3.158,2853,2.392,2934,2.682,3076,3.258,3252,2.558,3259,2.926,3312,3.441,3638,2.864,3639,2.96,3656,3.313,3701,2.66,3797,4.185,4375,3.696,4457,3.072,4516,3.206,4689,2.682,4900,5.519,5832,4.773,6143,3.313,6378,3.807,7106,3.807,8546,3.942,8633,3.942,8653,3.516,9101,3.942,9140,3.441,9142,3.313,9155,3.441,9205,3.942,9211,4.11,9212,4.11,9213,4.11,9214,4.11,9215,4.11,9216,4.11,9233,4.11,9234,3.807,9447,4.336,9467,4.678,9468,4.678,9469,4.678,9470,4.678]],["t/2860",[1,2.279,5,2.37,33,1.713,34,3.264,43,1.815,44,0.928,48,2.026,51,2.621,85,1.476,95,1.972,117,0.572,138,1.61,156,2.265,164,2.13,168,3.109,213,4.022,216,2.719,229,1.779,236,3.228,239,2.468,240,1.768,259,2.188,263,1.622,266,2.242,267,2.532,287,1.412,411,1.207,414,1.415,452,2.341,463,1.779,471,3.072,473,2.291,474,3.808,482,4.229,489,1.74,491,2.233,502,2.992,526,3.857,562,2.13,612,1.524,621,1.524,668,1.947,670,2.331,732,2.453,739,3.162,816,2.13,867,1.61,875,3.004,1008,2.163,1014,2.455,1024,2.363,1036,2.854,1071,2.719,1082,3.131,1097,3.192,1211,2.197,1213,2.92,1242,4.397,1273,2.04,1387,3.764,1418,4.482,1442,3.839,1553,3.839,1591,3.696,1640,4.164,1772,2.668,1792,3.264,1841,4.64,1924,2.251,1926,2.793,2006,4.24,2074,3.162,2122,3.839,2178,3.839,2770,2.242,3256,2.52,3426,3.922,3495,5.619,3671,3.162,3797,3.044,4325,3.426,4510,3.382,4713,3.072,5950,3.228,8592,3.696,9139,3.839,9260,4.122,9306,5.619,9307,4.585,9312,4.585,9313,4.585,9314,4.247,9471,5.218,9472,9.322,9473,5.218,9474,5.218,9475,5.218]],["t/2862",[1,2.188,71,5.801,81,4.895,83,2.233,117,0.981,123,2.755,156,3.013,168,2.985,173,5.599,263,3.517,288,5.132,597,3.451,656,5.877,659,4.347,660,3.83,712,4.791,980,3.894,1025,4.469,1063,6.887,1075,5.176,1273,3.499,1393,5.663,1596,3.308,1674,6.887,1776,5.895,1841,4.554,9217,8.295,9218,7.285,9219,8.295,9220,6.34]],["t/2864",[5,2.537,23,5.482,117,0.89,139,2.388,156,2.878,240,1.843,242,5.336,259,2.369,287,3.205,345,5.752,349,8.543,350,6.791,463,2.769,487,3.231,489,2.709,495,3.406,555,2.945,559,8.648,576,2.623,596,5.482,607,2.226,670,3.627,735,4.317,785,4.178,1097,3.328,1099,5.405,1148,5.752,1159,4.232,1211,3.419,1239,4.696,1304,5.138,1418,3.29,1838,4.738,1841,3.902,2881,3.254,3498,5.752,9476,8.12,9477,8.12]],["t/2868",[115,4.448,117,1.309,137,4.873,196,2.918,214,3.406,351,5.262,574,5.975,668,3.642,1374,7.738,1398,4.714,1546,6.249,1711,5.505,3247,7.041,4169,7.106,8542,8.059,9478,9.76,9479,9.046]],["t/2870",[12,3.741,30,1.917,48,3.638,229,3.195,463,3.195,488,3.16,586,4.204,753,3.883,775,2.742,967,5.861,998,2.749,1091,5.242,1177,3.108,1187,4.501,1205,4.262,1344,5.202,1449,4.705,2900,5.998,4169,5.162,4472,6.236,8496,8.683,8542,7.858,8638,8.683,9045,6.524,9480,9.369,9481,8.683,9482,9.369,9483,8.683,9484,7.895]],["t/2872",[6,2.702,16,2.975,25,2.736,43,2.748,44,1.404,48,3.067,73,2.351,74,3.364,75,5.625,85,1.504,93,2.477,115,2.725,117,0.583,122,3.225,126,3.685,138,1.641,156,1.292,165,2.294,250,2.131,401,2.702,402,2.064,414,1.442,463,2.694,473,1.564,488,1.793,492,3.121,578,2.93,604,3.19,611,2.23,612,1.553,630,2.908,647,3.102,660,2.275,668,1.984,775,1.556,874,2.887,882,2.686,912,2.502,955,2.248,998,2.318,999,4.2,1002,3.539,1055,2.976,1069,2.736,1071,2.771,1083,6.757,1085,3.911,1150,3.589,1156,6.274,1177,2.621,1231,2.581,1245,5.602,1261,3.644,1374,3.446,1417,3.16,1482,4.672,1484,4.2,1646,4.2,1753,2.639,1840,4.091,1954,4.881,1961,3.836,2144,2.887,2186,3.19,2256,3.16,2770,3.394,2838,3.766,3208,3.491,3247,6.8,3256,4.552,3374,5.937,3742,3.702,3797,3.102,4169,2.93,4614,3.996,4656,4.48,5421,4.2,6064,4.928,7920,4.672,8542,7.044,8625,3.996,8639,4.48,9076,4.928,9329,4.327,9479,4.928,9485,5.317,9486,5.317,9487,5.317,9488,5.317,9489,5.317,9490,5.317,9491,4.928,9492,4.928,9493,4.928,9494,9.797,9495,7.322,9496,5.317,9497,5.317,9498,4.327,9499,4.672,9500,5.317,9501,5.317,9502,4.672,9503,5.317]],["t/2874",[73,1.934,85,1.838,117,1.158,122,4.928,126,4.13,145,3.667,148,2.33,154,4.527,187,2.106,196,1.944,211,3.376,227,3.9,229,2.217,263,2.021,402,4.101,454,4.113,473,1.912,483,2.473,491,3.909,553,3.456,576,2.1,578,3.582,612,1.898,621,1.898,645,2.694,660,2.782,816,2.654,820,2.322,887,4.022,998,2.68,1002,4.327,1015,3.209,1032,5.291,1083,5.536,1085,4.782,1150,4.389,1156,4.327,1245,3.863,1265,4.162,1349,5.153,1727,3.244,1871,5.922,1961,3.156,2518,3.697,3256,4.412,3297,5.136,3374,4.886,3746,6.261,4511,5.478,8542,8.452,9494,11.299,9495,6.025,9498,5.291,9499,5.712,9502,8.027,9504,8.467,9505,5.712,9506,6.5,9507,6.5,9508,6.5,9509,6.5,9510,6.5,9511,6.5,9512,6.5]],["t/2876",[40,5.462,90,3.824,122,4.251,126,4.071,287,2.818,402,4.043,491,4.456,998,3.055,1062,4.715,1205,4.737,1265,6.667,1273,4.071,1599,4.3,8542,8.38,9513,10.413]],["t/2879",[94,3.315,172,2.274,614,4.966,621,2.87,678,6.417,875,3.167,923,3.148,1114,6.995,1481,7.765,1723,6.817,1841,3.61,1948,5.544,2718,8,4169,5.416,6256,8.283,8542,6.636,9504,9.11,9514,8.636,9515,9.829,9516,9.829]],["t/2881",[7,2.24,10,3.195,17,3.871,72,2.875,73,2.613,86,2.67,94,3.769,117,1.225,287,2.376,401,4.463,414,3.509,597,3.386,757,4.241,769,5.124,907,6.019,978,2.772,991,3.854,1083,5.322,1421,4.287,1723,4.994,1753,4.36,1914,4.385,2216,6.938,2256,5.219,2380,4.092,2899,4.803,3374,6.6,3745,6.461,3746,7.659,8639,7.4,9498,9.096,9502,10.801]],["t/2883",[5,2.12,73,2.946,117,1.085,187,3.206,463,3.376,985,3.609,1418,4.011,1961,5.846,2171,5.131,2903,6.337,3256,4.78,3671,5.998,3742,6.893,8542,6.683,9329,8.057,9491,9.174,9492,9.174,9493,9.174,9494,8.697,9498,8.057]],["t/2886",[1,2.12,5,2.375,7,2.828,12,2.787,48,3.367,115,2.992,117,1.34,168,2.893,196,2.593,240,1.969,276,4.211,287,2.347,408,4.892,411,2.566,414,3.493,490,3.568,510,2.533,521,3.742,802,3,803,5.944,875,2.795,910,5.204,967,5.425,1062,3.927,1418,3.514,1632,7.621,1640,3.874,1672,5.944,2006,3.945,2451,5.773,3741,5.425,6043,8.333,9517,8.673,9518,8.673]],["t/2888",[195,6.904,241,5.741,414,3.412,582,6.932,607,2.92,735,5.662,822,4.269,1231,5.171,2006,4.845,8630,8.414,9519,10.651]],["t/2890",[5,1.739,36,4.441,76,5.159,78,4.078,86,3.231,94,2.739,114,4.971,156,2.878,168,2.709,170,4.377,229,2.769,236,5.024,239,3.841,264,3.783,266,3.489,287,2.197,414,2.881,473,2.388,474,2.991,488,2.739,538,2.576,553,4.317,748,3.11,786,4.347,822,3.254,868,3.986,1009,2.892,1055,4.003,1146,5.573,1421,3.964,1475,5.264,1988,3.89,2018,4.031,2197,5.332,2256,4.826,2570,4.347,2744,6.415,3028,4.971,3801,6.415,4298,6.843,6014,7.135,6930,7.526,9520,8.12,9521,8.12,9522,8.12,9523,8.12]],["t/2892",[21,2.091,44,1.756,83,2.214,85,2.058,94,4.055,117,1.229,122,2.971,161,5.923,172,1.684,196,2.176,198,3.592,414,3.261,544,3.655,563,5.249,607,1.995,757,3.514,809,2.369,822,3.958,923,2.594,1008,3.016,1024,3.295,1271,3.817,1374,4.717,1399,3.552,1607,2.896,1772,3.721,2006,5.469,2144,3.951,2770,4.244,2771,5.067,2881,3.958,3640,7.178,3740,5.154,3743,5.353,3744,5.154,3745,5.353,3747,5.353,3748,5.353,3750,5.469,3774,5.749,4153,6.394,4321,6.132,6398,6.745,9524,7.277,9525,7.277,9526,7.277,9527,6.745,9528,7.277,9529,7.277,9530,7.277,9531,7.277,9532,7.277,9533,7.277,9534,7.277]],["t/2895",[1,0.996,5,2.482,6,2.071,7,1.039,10,0.855,12,1.31,22,2.773,35,1.423,38,1.496,41,1.059,44,0.418,48,0.912,73,1.917,75,1.266,76,1.141,85,1.526,86,0.714,89,3.149,93,3.001,94,1.82,97,0.725,106,1.979,115,0.81,137,0.959,156,2.206,170,1.266,172,0.943,187,1.748,188,4.559,194,0.888,196,1.218,208,0.692,219,2.405,222,1.336,229,1.39,239,1.111,241,1.266,258,0.897,264,1.094,268,5.004,339,1.064,411,0.544,414,3.597,427,1.16,445,1.275,452,1.054,470,1.248,473,0.691,475,1.808,481,1.438,488,2.172,489,0.784,490,2.22,492,0.928,501,2.495,510,1.19,514,1.18,520,1.216,536,1.586,552,1.166,563,1.694,571,1.16,614,4.036,621,1.19,649,1.031,654,0.952,679,1.187,735,1.249,737,1.069,740,1.079,757,1.134,760,3.857,774,2.495,785,5.087,786,1.257,866,1.045,868,1.153,869,1.325,874,1.275,878,2.641,882,1.187,896,1.285,912,1.105,953,1.018,976,1.486,978,0.741,997,1.451,998,0.689,1008,0.974,1014,1.105,1017,1.469,1019,1.089,1024,1.064,1025,3.639,1055,1.535,1066,1.16,1067,4.995,1070,1.18,1090,1.166,1097,0.963,1106,3.063,1132,1.586,1142,1.563,1146,1.232,1177,1.79,1181,2.071,1208,1.074,1252,1.523,1278,1.24,1286,1.24,1308,1.187,1312,1.469,1332,3.899,1351,1.438,1382,3.758,1403,1.542,1421,1.989,1430,1.979,1431,1.908,1441,1.486,1449,2.71,1487,2.641,1528,3.592,1584,1.542,1596,2.38,1607,0.935,1615,1.224,1629,2.549,1715,2.61,1749,1.359,1750,1.359,1772,4.642,1791,1.173,1843,1.586,1844,1.438,1974,1.194,1988,3.944,1989,1.359,1994,4.742,2006,1.854,2021,1.423,2022,1.636,2026,1.728,2032,2.035,2060,2.059,2162,1.979,2198,4.23,2256,2.422,2258,2.064,2275,1.031,2330,1.808,2350,4.509,2356,3.274,2360,2.793,2425,2.212,2649,1.664,2662,3.633,2674,1.249,2902,1.856,3037,1.371,3063,1.808,3067,2.676,3070,1.523,3075,1.856,3103,3.699,3154,1.636,3316,1.694,3506,1.845,3751,5.932,3752,5.932,3753,6.501,3932,1.586,4154,2.064,4341,6.244,4441,1.636,4593,2.521,4679,2.177,5012,1.728,5418,1.912,5419,5.362,5444,1.856,6129,4.393,7196,2.177,7568,3.58,8363,7.388,8364,3.434,8397,5.089,8408,2.177,8446,2.177,8483,4.841,8634,1.766,9086,5.243,9087,2.064,9136,1.856,9137,1.912,9535,2.349,9536,6.441,9537,2.349,9538,4.075,9539,2.349,9540,2.349,9541,2.349,9542,2.064,9543,2.349,9544,2.349,9545,4.742,9546,4.742,9547,2.349,9548,2.349,9549,2.349,9550,2.349,9551,2.349,9552,2.349,9553,2.349]],["t/2897",[5,1.527,21,2.048,41,5.373,85,3.137,91,3.289,93,5.168,94,2.404,106,3.461,117,0.781,126,2.787,146,5.819,148,1.818,172,1.65,194,2.695,229,2.431,267,2.385,320,5.938,414,3.692,437,4.729,473,2.097,496,3.871,575,2.921,652,5.246,668,2.66,757,4.703,802,2.466,810,4.681,885,4.197,997,2.539,998,2.092,1159,5.075,1169,4.123,1247,5.632,1359,4.745,1372,4.621,1393,4.51,1418,2.889,1471,3.539,1607,2.837,1718,5.358,1772,3.646,1799,3.958,2016,3.816,2074,4.32,3318,4.32,3764,8.557,3766,7.694,7776,6.607,8061,6.607,8064,6.607,9554,7.129]],["t/2899",[5,1.258,7,2.168,12,3.209,26,3.022,40,3.081,43,2.957,44,1.044,73,1.748,85,1.661,94,3.691,106,4.126,115,3.444,117,0.932,138,1.813,148,2.168,155,3.004,156,1.427,160,2.933,168,1.959,172,2.311,186,2.38,188,2.95,214,2.049,243,2.204,245,2.304,264,2.737,267,2.082,414,3.149,449,4.161,489,1.959,511,2.672,621,1.715,740,2.697,753,2.435,757,4.104,801,3.634,810,3.857,955,2.483,997,2.092,1004,2.9,1055,3.202,1090,4.219,1177,1.949,1208,2.685,1222,4.237,1265,3.761,1277,3.102,1331,3.431,1332,5.342,1351,3.596,1385,4.237,1421,2.868,1596,2.171,1607,3.382,1640,2.624,1722,2.71,1790,2.672,1865,4.321,1871,3.807,2016,3.144,2180,2.265,2256,6.901,2304,2.624,2425,3.189,2649,4.161,3763,5.161,3765,7.467,4515,4.95,4810,5.444,6129,6.917,9545,7.467,9546,7.467,9555,5.874,9556,9.986,9557,8.498,9558,5.874,9559,5.874,9560,5.874,9561,5.874,9562,5.874,9563,5.874]],["t/2901",[1,1.14,5,2.38,22,1.774,35,2.825,73,1.387,75,2.513,85,2.462,114,2.854,117,1.154,170,5.262,172,1.655,187,1.51,188,4.371,194,1.762,196,2.603,198,3.531,206,2.55,215,3.195,228,2.569,229,2.44,240,1.058,267,1.142,268,2.72,414,3.447,488,1.572,526,3.929,538,1.479,607,2.887,614,2.355,621,3.379,631,2.854,654,1.889,719,2.073,742,7.275,757,3.455,786,4.659,809,2.834,831,2.276,867,1.439,874,2.531,882,2.355,942,2.355,991,2.046,1013,2.205,1024,2.111,1049,2.673,1055,3.678,1056,4.174,1062,2.111,1090,3.551,1104,5.965,1175,3.061,1177,1.547,1269,3.929,1311,3.504,1332,2.276,1403,6.914,1442,3.43,1547,2.446,1772,4.992,1773,2.513,1841,1.712,1847,3.43,1910,2.745,1974,2.37,1988,2.619,2006,3.959,2020,3.929,2143,3.148,2561,3.795,2649,3.302,3028,2.854,3037,5.696,3108,3.795,3319,2.95,4282,3.302,6108,9.252,6129,3.795,7716,3.795,8005,4.321,8397,3.683,9545,4.097,9546,4.097,9564,7.154,9565,4.662,9566,7.154,9567,7.154,9568,7.154,9569,4.662,9570,8.067,9571,4.662,9572,4.662,9573,4.662,9574,4.662]],["t/2903",[1,2.545,47,3.743,263,3.238,414,3.596,531,5.17,579,3.848,659,4.002,757,5.029,758,7.661,759,4.782,781,2.634,1873,6.838,2006,4.737,9220,7.376]],["t/2906",[44,2.15,172,2.307,414,3.53,1150,6.73,1204,4.936,1208,4.556,1449,5.007,1723,5.669,1841,4.441,2881,3.995,3256,4.814,3745,7.334,3746,6.832,4100,6.382,9514,8.759,9575,9.969,9576,9.969]],["t/2909",[47,4.327,83,1.954,196,2.96,208,2.918,267,2.424,402,3.843,414,3.265,490,4.072,568,4.832,612,2.891,649,4.344,769,5.775,817,5.299,914,4.289,1029,5.629,1075,5.725,1177,3.284,1404,7.708,1443,4.168,2881,3.967]],["t/2911",[44,1.882,48,3.135,85,2.283,91,3.725,148,2.059,187,2.615,196,2.414,208,2.38,240,1.833,339,3.656,414,2.189,492,3.19,553,4.292,731,4.844,775,2.363,787,3.386,832,4.263,834,3.012,923,2.78,961,7.86,998,2.369,1075,4.669,1083,4.892,1179,5.939,1404,5.169,1596,2.984,1776,4.207,1961,3.92,1981,6.571,2032,4.031,2230,3.606,2591,5.719,2703,6.95,2881,3.236,2923,5.169,3256,3.899,3855,5.824,3899,7.787,4441,5.622,4452,6.213,5406,7.094,8542,5.451,8639,6.803,9498,6.571,9499,7.094,9577,8.073,9578,8.073,9579,8.073,9580,8.073]],["t/2913",[7,2.254,47,4.033,85,2.499,138,2.727,148,2.254,287,2.391,414,3.343,607,2.423,720,5.882,768,5.025,769,5.156,787,3.706,866,3.93,923,2.321,961,5.882,991,3.878,1075,5.111,1083,5.355,1098,4.764,1150,5.966,1208,4.039,1273,3.455,1421,4.314,1723,6.381,1841,3.245,1979,7.368,2230,3.947,2256,5.252,2380,4.117,2703,5.803,3745,6.501,3746,6.057,9514,7.765,9581,8.837,9582,8.191]],["t/2915",[47,3.948,83,2.169,245,4.309,659,4.222,908,4.059,1443,4.625,1607,4.371,8542,7.416,9220,7.781]],["t/2917",[2425,6.363]],["t/2921",[1,2.188,5,1.917,7,2.283,10,4.115,12,2.876,51,4.495,83,2.449,123,2.755,163,4.255,167,5.089,172,2.071,259,1.688,263,2.783,267,2.77,402,3.475,470,2.742,526,3.339,588,6.584,987,3.197,998,2.626,1090,4.443,1181,4.549,1248,5.089,1418,3.627,1478,4.791,1841,5.04,3259,5.599,3359,7.528]],["t/2923",[33,1.928,138,1.813,156,2.065,172,1.359,218,2.049,259,1.883,264,2.737,287,2.3,408,4.793,412,2.898,497,3.761,607,1.61,612,2.482,614,2.968,621,2.482,671,2.9,809,2.767,817,3.144,818,3.004,834,2.192,882,2.968,908,2.171,923,1.543,963,5.099,1021,3.397,1031,3.427,1072,2.968,1097,2.407,1177,1.949,1359,3.909,1374,3.807,1402,3.524,1452,4.781,1455,3.34,1586,5.832,1640,2.624,1672,4.026,1715,4.046,1776,3.061,1788,3.34,1841,4.584,1914,2.933,1954,4.401,2174,2.567,2216,4.64,2275,2.578,2304,2.624,2328,3.716,2356,5.562,2357,3.397,2625,4.09,2754,3.166,2770,4.291,2840,4.52,2881,2.354,3078,3.559,3252,3.212,3256,4.104,3337,4.875,3625,4.781,3629,4.781,3701,3.34,3818,3.634,3899,4.321,4411,3.909,4419,4.415,4587,4.52,4593,3.634,4687,3.524,4863,4.64,6163,4.64,6524,4.161,6867,4.237,8050,6.917,8647,4.64,8656,5.444,9125,4.161,9583,5.874,9584,8.498,9585,5.874,9586,5.874,9587,8.498,9588,5.874,9589,8.498,9590,5.874]],["t/2925",[1,2.584,85,2.989,214,4.37,259,1.993,287,2.86,483,4.022,923,2.776,1424,7.776,1841,4.599,3638,6.471,3639,6.688,9591,9.797]],["t/2927",[94,1.956,156,1.41,259,2.611,404,4.713,405,7.457,406,2.88,412,4.11,486,5.918,504,7.518,671,2.864,732,2.652,834,4.497,1586,6.952,2018,6.324,2278,5.053,2673,6.593,2754,4.54,2770,3.619,2771,4.04,3252,4.606,3609,6.796,3610,7.848,3611,7.577,3612,5.965,3640,3.714,4425,4.268,4587,4.464,9193,4.888]],["t/2929",[94,1.909,156,1.375,259,2.56,338,5.222,404,4.629,405,7.393,406,2.81,412,4.075,486,5.537,504,7.352,671,2.794,732,2.605,834,4.269,1586,6.817,1612,5.5,2018,6.281,2278,7.17,2281,7.475,2673,5.925,2754,6.442,2770,3.555,2771,3.942,3609,6.701,3610,7.053,3611,7.201,3612,5.86,3640,3.624,4425,4.164,4587,4.356,9193,4.77]],["t/2931",[5,1.729,94,3.57,156,2.572,172,2.733,404,4.518,406,4.008,483,3.072,492,3.19,504,4.415,579,2.984,612,2.358,671,3.985,732,3.946,744,4.292,785,4.154,923,2.12,953,3.498,1074,6.777,1131,4.483,1397,5.824,1399,3.941,1457,4.669,1471,4.008,1586,5.316,1596,2.984,1830,4.352,1841,2.965,2006,3.673,2101,7.483,2174,3.528,2770,5.074,3252,4.415,3256,3.899,3337,3.941,3625,6.571,3627,7.094,3629,8.615,4169,4.449,4587,6.213,9306,5.824,9592,10.585,9593,8.073]],["t/2933",[1,1.384,30,2.001,33,2.715,44,2.034,83,1.118,85,2.34,94,1.909,117,0.907,164,2.311,169,2.575,229,1.93,259,1.56,287,2.239,402,2.198,404,4.629,406,4.107,412,1.93,414,1.535,445,3.073,578,3.119,579,2.092,598,2.624,612,1.653,666,2.337,671,2.794,732,1.782,787,2.374,814,3.297,832,2.989,834,2.112,874,3.073,875,2.666,879,3.274,1009,2.947,1019,2.624,1055,2.133,1074,3.624,1090,2.81,1097,2.319,1170,2.412,1181,2.877,1187,2.719,1231,2.748,1399,4.773,1418,3.352,1478,3.03,1519,3.193,1640,3.695,1727,2.938,1753,2.81,1841,4.388,1946,4.254,1974,2.877,2123,3.364,2171,2.412,2186,3.396,2357,3.274,2619,3.995,2769,5.761,2770,5.437,2881,3.316,2944,3.942,3252,3.096,3256,2.734,3609,3.879,3611,3.303,3640,3.624,3659,4.524,3805,4.164,4169,3.119,4344,4.472,4424,4.356,4425,4.164,4502,3.717,5832,3.767,7007,4.77,8062,4.083,9124,4.77,9125,4.009,9127,4.009,9162,4.77,9163,4.77,9167,6.536,9197,4.973,9198,4.973,9199,4.973,9200,4.472,9201,4.973,9203,4.973,9204,4.973]],["t/2935",[5,1.791,20,3.769,24,4.105,37,5.566,47,3.006,72,2.737,83,1.651,94,3.653,148,2.133,150,3.48,198,4.128,208,2.465,239,3.955,245,3.281,263,2.6,408,6.109,613,4.176,615,3.061,659,3.214,678,4.476,757,5.23,796,3.996,840,4.508,867,2.581,882,4.225,1075,6.947,1109,5.354,1402,6.498,1443,3.521,1841,4.833,1874,4.879,1878,5.12,1979,5.491,2230,5.365,2241,6.152,9221,7.047,9594,7.751]],["t/2937",[30,2.163,43,3.677,83,2.087,259,1.993,287,2.86,411,2.898,586,4.743,757,5.105,1841,4.901,1846,6.405,9595,10.57]],["t/2939",[10,2.839,11,2.692,15,3.919,85,2.207,86,2.373,94,3.917,117,0.855,156,2.515,163,3.71,259,1.952,263,3.218,268,4.553,287,3.347,339,3.533,470,2.391,495,3.273,521,3.367,607,2.139,654,3.162,671,5.109,786,4.177,787,3.273,923,2.049,967,4.882,978,2.463,1070,3.919,1118,5.124,1185,4.513,1208,3.567,1211,3.286,1399,3.81,1618,3.116,1715,3.162,1841,4.726,2006,3.55,2060,3.943,2169,5.865,2174,3.41,2521,5.629,2770,4.447,3098,4.682,3252,5.661,3600,5.348,8055,4.996,8647,6.165,9596,7.804]],["t/2942",[1,2.628,5,1.439,10,2.444,11,3.709,15,3.374,16,3.759,44,1.194,122,2.743,156,1.633,187,2.176,193,3.444,196,2.795,197,3.13,200,4.302,259,2.304,287,2.909,398,2.475,412,2.291,419,4.914,473,1.976,487,5.034,489,2.241,492,2.654,496,3.648,526,2.507,529,2.351,557,3.455,578,3.702,579,2.483,607,1.842,627,4.068,631,5.724,666,2.774,757,3.245,759,3.085,834,2.507,875,2.165,895,3.675,998,1.971,1015,5.308,1055,3.522,1062,3.042,1181,3.415,1231,3.262,1418,4.357,1421,3.28,1618,2.683,1778,3.162,1841,4.269,1924,2.899,2195,7.488,2881,2.693,2927,5.308,3252,3.675,4302,5.469,8653,5.05,9597,9.349]],["t/2944",[1,1.107,5,0.97,10,1.647,11,1.561,12,1.455,21,1.301,22,1.722,33,3.41,48,1.758,73,1.347,88,2.099,94,1.527,117,0.496,165,1.953,172,1.047,187,1.466,193,4.356,196,2.091,210,1.498,211,2.584,219,1.494,227,2.716,229,1.544,241,2.44,258,1.728,259,1.319,267,1.109,287,1.892,296,2.902,297,1.331,330,3.627,402,1.758,411,1.047,419,2.069,421,3.209,422,4.317,427,2.235,463,2.385,466,2.972,470,2.618,482,3.797,487,2.783,489,1.51,497,2.898,510,1.322,511,2.059,521,1.953,527,1.506,530,1.987,578,2.494,579,1.673,584,2.099,607,1.917,612,1.322,627,3.718,666,2.887,668,1.689,732,1.425,760,2.186,775,1.325,802,2.419,867,1.397,892,2.344,895,2.476,978,1.429,985,2.096,998,1.328,1055,1.705,1062,2.05,1090,2.247,1104,3.102,1177,1.502,1205,2.059,1218,2.374,1227,2.832,1231,2.198,1271,3.668,1272,3.102,1273,1.77,1342,4.196,1370,2.641,1443,2.944,1449,2.273,1470,3.815,1566,3.402,1678,2.273,1712,2.458,1732,2.301,1749,4.044,1816,1.97,1819,5.601,1841,2.568,1948,2.553,1967,3.492,1987,2.596,2006,2.059,2103,4.196,2133,3.013,2177,4.156,2180,2.697,2198,2.972,2304,2.022,2320,3.152,2522,3.206,2538,3.102,2545,4.281,2553,3.206,2608,2.934,2633,3.977,2789,7.665,2790,2.743,2973,2.864,2991,3.402,3036,6.36,3050,6.955,3254,3.977,3687,4.196,4473,3.483,4516,3.102,6045,3.977,6163,3.576,6524,3.206,6731,4.196,6909,3.684,8189,3.402,8471,3.815,9598,4.527,9599,4.196,9600,4.527]],["t/2947",[5,0.408,8,1.251,11,1.916,12,0.612,13,1.122,22,1.29,26,0.98,30,0.39,33,1.503,40,0.999,44,1.254,48,1.778,73,0.567,75,2.469,85,0.539,88,0.883,90,2.591,94,0.643,96,0.75,117,1.06,128,0.875,148,0.486,150,0.793,156,1.113,170,1.027,172,1.285,193,4.065,208,0.562,213,0.822,214,1.183,217,1.066,221,0.91,229,0.65,241,1.027,243,0.879,245,0.747,258,0.727,259,0.359,267,1.122,296,2.38,297,0.56,330,1.439,338,0.925,406,0.946,408,1.075,419,1.549,421,2.872,422,3.863,445,1.034,452,0.855,463,1.156,469,1.083,470,1.951,473,0.56,482,2.486,483,1.742,489,1.131,491,0.815,504,1.042,510,0.556,511,0.867,514,1.702,530,2.794,531,0.946,538,2.02,575,1.877,576,0.615,584,0.883,586,0.855,607,1.523,610,2.274,612,2.061,621,1.622,627,0.829,634,1.122,652,0.901,654,1.374,660,1.451,666,3.554,671,2.261,681,0.855,689,1.466,759,2.103,764,1.944,802,2.441,813,1.327,815,1.605,817,2.451,818,0.974,819,1.154,820,0.681,832,1.79,867,2.178,875,0.614,881,2.748,912,1.595,953,0.825,955,1.433,971,1.013,978,1.753,980,0.829,985,3.403,998,0.559,1014,2.996,1019,2.123,1024,0.863,1031,1.112,1033,1.713,1036,1.042,1037,2.054,1062,1.535,1063,1.466,1070,1.702,1071,0.993,1083,1.154,1089,2.722,1090,3.796,1099,1.268,1108,1.766,1109,1.22,1115,1.122,1151,1.092,1157,1.551,1162,1.961,1167,1.505,1177,1.125,1187,0.915,1195,1.122,1204,0.778,1205,2.083,1208,2.093,1211,0.802,1223,1.766,1233,1.286,1249,0.999,1255,2.759,1271,0.999,1273,1.79,1277,1.006,1278,1.006,1308,0.962,1334,1.251,1369,1.402,1382,1.327,1399,1.655,1418,1.374,1443,2.339,1449,0.957,1455,2.604,1485,1.235,1486,1.349,1579,1.235,1618,0.761,1629,2.865,1646,1.505,1678,0.957,1712,1.034,1715,0.772,1735,1.22,1749,3.683,1750,1.961,1753,3.796,1760,2.609,1791,2.287,1819,3.432,1825,1.112,1841,2.04,1868,1.327,1878,1.166,1947,1.306,1966,0.962,1967,4.298,1974,0.968,2032,0.951,2043,2.289,2055,1.286,2062,2.427,2138,1.327,2144,1.84,2166,1.674,2170,1.432,2177,4.849,2180,0.735,2187,1.327,2198,1.251,2263,0.875,2304,0.851,2305,1.042,2318,1.349,2462,3.442,2466,1.327,2490,1.132,2508,1.306,2518,1.083,2545,1.166,2553,6.377,2570,2.451,2571,4.299,2598,2.759,2619,0.92,2625,5.682,2723,0.98,2770,1.968,2789,4.957,2790,2.775,2853,2.342,2899,1.042,2905,1.349,2934,1.944,2970,1.551,2973,2.145,2979,3.142,2991,1.432,3036,6.645,3037,1.978,3050,1.551,3072,3.303,3078,1.154,3126,1.374,3149,1.674,3156,1.766,3250,1.432,3252,1.854,3253,1.674,3254,6.2,3256,0.92,3257,4.024,3259,1.192,3260,1.766,3465,1.374,3646,3.244,3659,1.042,3714,1.605,4169,1.05,4312,1.402,4320,2.323,4400,1.432,4502,1.251,4629,1.551,4630,2.445,4687,2.034,4689,1.944,5221,2.979,6029,1.551,6056,3.142,6524,1.349,6863,1.551,7302,3.142,7328,1.766,8042,1.605,8189,2.548,8252,1.551,8326,1.766,8471,1.605,8483,1.432,8620,1.766,9074,1.674,9205,1.605,9601,3.39,9602,1.905,9603,1.674,9604,1.905,9605,1.905,9606,1.905,9607,3.39,9608,3.39,9609,1.905,9610,1.905,9611,1.905,9612,1.905,9613,1.905,9614,1.905,9615,1.905,9616,1.905,9617,1.905,9618,1.766,9619,1.905,9620,1.905,9621,7.056,9622,1.905,9623,1.766,9624,1.905,9625,1.905,9626,1.905,9627,1.766,9628,1.905]],["t/2949",[1,1.378,5,2.089,7,1.438,30,1.154,33,1.85,36,3.083,40,2.957,44,1.002,95,2.131,117,0.618,156,1.37,186,2.284,187,1.826,193,3.593,211,2.083,219,3.219,229,2.813,259,2.024,287,1.525,288,3.233,330,2.393,406,2.799,421,2.117,445,3.061,452,2.529,463,1.923,473,2.426,483,2.145,486,2.529,487,2.243,488,1.901,557,2.083,614,2.848,627,2.453,647,3.289,649,2.474,666,4.432,732,1.775,753,2.337,757,3.983,767,3.319,787,3.459,802,2.853,809,2.686,819,3.416,867,1.74,879,3.261,881,3.383,953,2.443,985,1.69,987,2.014,1009,2.008,1021,3.261,1062,2.553,1075,3.261,1090,2.799,1248,3.206,1252,3.654,1273,2.204,1369,4.147,1418,2.284,1455,4.69,1579,3.654,1618,2.251,1715,3.342,1773,3.039,1819,3.039,1841,3.942,1967,2.815,2055,3.806,2075,2.831,2144,3.061,2278,3.383,2571,3.806,2624,4.454,2625,5.744,2673,3.416,2754,3.039,2769,3.926,2770,2.422,2789,3.654,2881,3.306,3036,3.451,3252,5.335,3259,3.527,3610,4.067,3611,3.289,3899,4.147,4170,3.488,4441,3.926,4502,3.702,4687,4.949,6163,4.454,6524,5.843,6858,5.225,6969,5.225,8189,4.237,8255,5.225,9629,5.637,9630,5.637,9631,5.637]],["t/2951",[5,1.243,30,1.187,33,1.904,43,2.018,44,1.031,83,1.663,156,1.41,193,4.257,198,2.864,208,1.71,218,2.024,219,1.914,235,2.787,262,2.703,267,2.063,408,5.593,411,1.342,463,1.978,473,2.477,506,3.127,521,3.634,535,3.272,538,1.84,568,2.832,571,2.864,578,3.196,580,4.184,586,2.603,612,1.694,629,2.88,666,4.771,679,2.931,781,2.131,809,3.229,817,5.824,818,5.564,821,3.976,895,3.173,985,1.739,1008,2.404,1024,2.627,1062,2.627,1081,4.109,1097,2.377,1146,3.043,1181,2.948,1200,3.084,1222,6.075,1271,3.043,1443,2.442,1615,3.023,1636,4.36,1727,3.864,1749,4.871,1753,2.88,1772,2.966,1774,3.67,1819,4.54,1841,3.996,1895,3.976,1974,2.948,2060,2.931,2144,3.15,2179,3.976,2304,2.591,2380,2.703,2545,3.551,2770,4.26,2881,4.36,2904,6.33,3036,3.551,3257,5.097,3259,3.629,3648,5.865,3652,4.268,3657,3.861,3671,3.515,6356,5.376,6524,4.109,7931,4.04,8055,3.714,8567,4.888,9632,5.801,9633,5.097]],["t/2953",[5,1.929,11,3.107,30,1.843,73,4.007,83,1.779,91,4.156,193,3.318,240,2.045,408,5.081,411,2.084,491,3.854,510,2.631,607,2.469,629,4.472,665,5.515,666,3.719,764,3.823,814,3.038,896,4.926,1133,6.627,1227,5.635,1518,5.839,1750,5.21,2570,4.822,2619,5.485,2789,5.839,3511,4.694,4441,6.273,4502,5.915,4673,7.915,8653,6.77,9314,7.332]],["t/2955",[7,1.916,94,2.533,156,2.452,193,2.767,198,3.708,213,3.241,287,3.617,483,2.858,520,3.889,521,3.241,536,5.071,538,3.201,568,5.562,607,3.123,732,3.177,757,3.627,817,5.401,818,5.826,822,3.01,875,2.42,906,3.75,997,2.675,1118,4.932,1181,3.818,1443,3.162,1455,4.271,1618,2.999,1772,3.841,1788,4.271,1841,4.805,1924,3.241,1967,3.75,2380,4.701,2625,5.23,2770,3.227,2789,4.869,2881,3.01,2904,7.583,3036,4.598,3294,5.418,6524,5.32,6836,6.6,8055,4.809,9634,7.511,9635,7.511]],["t/2957",[47,3.436,208,2.818,259,1.803,263,2.973,267,2.342,271,3.522,402,3.712,408,5.393,495,4.01,520,6.103,521,5.086,607,3.503,757,4.617,882,4.83,1134,6.278,1618,3.818,1812,4.889,1816,4.16,1841,3.511,2626,7.553,3682,8.057,6524,6.772,8544,7.782,9636,9.561]],["t/2960",[5,1.118,7,1.331,30,2.116,33,1.713,83,1.03,90,1.916,91,2.408,95,1.972,117,1.022,122,3.18,168,1.74,193,4.429,194,2.944,214,1.821,240,1.184,243,1.353,259,1.469,299,5.259,391,1.489,406,2.59,411,1.207,414,2.112,418,2.621,473,2.741,510,1.524,529,1.826,538,1.655,549,3.523,551,4.015,576,1.686,593,3.473,612,1.524,643,7.606,649,2.29,732,3.483,769,3.044,781,1.32,802,1.805,814,4.459,816,2.13,818,3.984,866,2.32,867,1.61,881,3.131,890,2.419,955,2.206,985,1.564,987,1.864,1030,2.719,1049,2.992,1062,2.363,1067,3.576,1125,2.468,1134,3.426,1170,2.224,1187,2.506,1200,4.141,1204,2.13,1238,3.696,1253,2.668,1267,3.101,1429,4.836,1485,3.382,1727,3.928,1790,2.374,1896,2.943,1924,2.251,1962,5.185,1966,5.589,1974,2.652,2171,2.224,2182,4.467,2240,3.264,2380,2.431,2442,4.585,2490,4.629,2619,2.52,2662,2.943,2838,3.696,2881,4.954,3671,4.721,3797,3.044,3929,4.397,4320,3.576,4413,4.015,4472,3.473,4510,3.382,5206,4.122,5550,3.839,9084,4.836,9637,7.79,9638,5.218]],["t/2962",[7,2.002,10,2.855,30,1.606,43,2.73,83,1.549,94,2.647,97,2.422,117,0.86,168,2.618,198,3.874,287,2.123,452,3.521,466,5.153,529,2.746,582,4.324,621,2.292,629,3.896,649,3.444,732,4.171,769,4.579,781,2.628,814,4.729,870,4.709,890,3.638,896,4.292,969,3.918,971,4.172,987,2.803,1231,5.654,1352,5.153,1399,3.831,1807,3.79,1966,5.249,2031,6.387,2075,3.941,2545,4.804,3157,5.898,4307,5.661,5501,6.895,8367,6.613,9639,6.895,9640,7.273]],["t/2964",[7,2.455,12,3.094,25,4.953,83,1.901,93,4.485,156,2.339,209,3.915,211,3.557,213,4.153,287,2.605,529,3.369,582,5.304,614,4.863,732,3.031,814,3.247,923,2.528,953,4.171,1072,4.863,1486,6.819,1807,4.649,1924,4.153,2052,7.835,2223,6.091,3359,6.407,8055,6.163,9641,9.626,9642,9.626]],["t/2966",[5,1.8,7,2.771,10,0.936,25,1.324,39,1.544,40,3.033,41,1.16,50,1.69,83,1.142,85,0.728,90,1.619,91,2.668,93,1.199,94,0.868,95,0.973,97,1.36,115,0.888,117,1.125,137,1.051,138,1.785,148,0.656,156,1.405,165,3.324,168,1.47,172,0.595,187,0.833,193,1.624,197,2.694,198,3.803,209,1.047,211,1.629,214,0.898,240,0.584,257,1.713,258,0.982,263,0.8,266,1.894,267,1.416,287,2.274,408,2.486,418,1.292,421,0.966,452,1.155,457,2.595,474,0.948,487,1.024,488,0.868,491,1.101,492,1.742,510,2.454,511,2.005,521,1.902,538,2.666,549,1.737,553,2.344,562,1.051,575,1.054,576,2.213,582,1.418,586,1.155,600,1.515,612,2.001,615,0.942,619,2.005,621,3.556,629,1.277,636,1.324,639,1.332,732,3.743,737,1.171,745,1.559,753,1.067,781,2.504,787,1.079,802,0.89,814,4.423,818,2.254,822,1.767,825,2.033,866,1.144,867,0.794,881,1.544,882,2.227,890,2.044,896,2.411,953,1.115,957,2.922,973,1.764,976,1.628,985,1.321,987,3.21,989,1.476,991,1.129,993,3.24,998,1.293,1017,1.61,1024,1.996,1045,1.668,1049,1.476,1062,2.618,1071,2.297,1072,2.227,1091,1.44,1181,2.939,1187,2.118,1191,2.895,1200,3.074,1204,1.8,1211,1.083,1231,1.249,1238,3.122,1257,1.713,1260,2.758,1267,2.62,1286,2.328,1348,1.98,1399,1.256,1402,2.645,1465,1.16,1477,1.332,1480,1.44,1489,1.35,1577,1.559,1596,1.629,1607,1.024,1614,3.617,1668,1.792,1711,1.451,1714,1.668,1727,0.914,1807,1.243,1825,1.501,1914,2.201,1948,1.451,1966,5,1974,2.241,2075,3.441,2144,2.393,2171,1.097,2180,1.7,2237,1.713,2238,1.98,2522,1.823,2538,3.963,2545,5.144,2570,2.36,2619,2.793,2662,1.451,2881,1.031,2904,7.714,2927,2.033,3104,1.668,3157,1.934,3359,3.849,3502,2.595,3511,3.014,4320,1.764,4327,4.771,6108,5.081,7906,2.168,8055,2.822,8189,1.934,8658,2.385,9166,1.98,9306,1.856,9314,2.094,9643,2.385,9644,2.573,9645,6.638,9646,2.261,9647,2.573,9648,4.408,9649,5.36,9650,2.573,9651,2.573,9652,2.385,9653,2.573,9654,2.385,9655,2.573]],["t/2968",[5,2.805,7,3.111,117,1.109,137,4.128,267,2.477,492,3.995,621,2.953,768,5.751,987,3.613,1031,5.9,1151,5.799,1599,4.176,2538,6.931,2545,7.467,2904,7.601,9656,10.112]],["t/2970",[10,3.043,25,4.303,44,1.925,94,3.653,136,3.735,156,2.032,170,4.508,267,2.653,287,2.931,391,2.387,492,3.304,576,4.104,582,4.608,621,3.71,814,2.82,993,3.225,1066,4.128,1260,6.775,1380,5.646,1607,4.78,1807,4.039,1966,6.069,2075,4.2,2538,5.731,2545,6.63,2904,6.285,4327,5.824,8055,5.354,9306,7.812,9640,7.751,9649,7.751,9657,8.362]],["t/2972",[97,3.472,136,5.024,562,4.592,621,3.285,1231,5.462,9658,11.249]],["t/2975",[0,6.484,1,3.068,2,3.778,5,1.967,6,4.668,94,3.098,117,1.007,122,3.75,126,3.591,156,2.232,259,2.168,287,2.485,391,2.621,398,3.384,414,3.118,509,6.757,534,6.757,585,5.745,732,2.892,756,4.344,816,3.75,1271,4.818,1327,5.139,1418,3.722,1711,5.18,1712,6.242,2235,7.74,8653,6.903]],["t/2977",[5,1.955,21,2.622,94,3.077,97,2.816,126,3.567,136,4.076,148,2.327,197,4.251,229,3.112,259,1.721,263,2.837,287,3.098,288,5.232,414,2.475,454,5.773,461,4.695,560,3.987,575,3.739,584,4.231,597,3.519,621,2.665,639,4.725,734,4.954,757,4.407,786,4.885,816,3.725,840,6.172,923,3.007,1715,3.698,1926,4.885,2074,5.53,8390,6.582]],["t/2979",[73,3.269,117,1.204,414,2.979,557,4.059,875,3.539,1107,9.256,1146,5.762,2353,5.8,2468,5.88]],["t/2981",[148,2.656,196,3.114,197,5.784,263,3.238,264,4.852,414,2.824,579,3.848,612,3.041,753,4.316,787,4.367,840,5.613,1370,6.076,1596,3.848,1607,4.143,2104,8.227]],["t/2983",[38,2.982,73,2.416,77,4.474,94,3.583,97,3.279,126,4.63,138,2.506,156,2.878,165,3.504,168,2.709,242,5.948,262,3.783,263,2.525,264,3.783,266,3.489,287,2.197,414,3.407,437,3.943,538,2.576,612,2.371,621,2.371,732,2.557,753,3.366,757,5.131,882,5.368,923,2.133,1331,4.289,1359,8.361,1607,3.231,1715,3.29,1830,5.728,2006,3.694,2380,3.783,2674,4.317,3766,6.415,9659,7.526]],["t/2985",[38,2.592,73,3.284,78,4.857,94,3.262,97,2.985,126,4.314,138,2.178,156,3.022,165,3.045,168,2.354,242,5.542,262,3.288,263,2.194,264,3.288,266,3.032,414,3.219,437,3.426,538,2.239,612,2.824,621,2.061,732,2.222,744,5.142,753,2.925,757,4.671,882,3.565,923,1.853,1331,3.905,1359,8.277,1386,6.755,1659,8.717,1715,2.86,1830,5.948,2006,3.21,2019,4.914,2104,7.641,2337,3.726,2897,6.629,3766,5.575,9660,8.964,9661,10.227,9662,7.057,9663,6.541,9664,6.541,9665,6.541,9666,7.057]],["t/2987",[1,1.788,5,2.123,77,6.194,78,6.52,86,3.418,94,3.343,97,2.257,126,5.076,156,3.06,242,3.674,297,2.151,330,3.105,414,3.048,415,6.132,425,6.446,527,2.433,757,4.786,787,4.157,875,2.357,1331,4.001,2019,5.094,2024,4.742,2674,3.889,2744,5.779,2897,5.013,3776,9.807,4161,6.427,4441,5.094,9659,6.78,9660,6.78,9661,6.78,9663,6.78,9664,6.78,9665,6.78,9667,7.315,9668,7.315,9669,7.315,9670,7.315,9671,7.315,9672,7.315,9673,7.315,9674,7.315]],["t/2990",[30,1.691,43,2.875,72,2.705,86,2.513,126,3.231,148,2.741,156,2.611,168,3.984,211,3.054,214,3.75,219,3.941,239,3.909,242,4.15,470,3.874,473,2.43,495,4.507,578,4.553,586,3.708,607,2.266,630,4.52,639,4.279,650,5.961,681,3.708,744,4.393,757,3.991,840,5.793,912,3.889,955,3.493,1025,5.366,1063,6.359,1191,5.426,1304,5.229,1331,3.336,1618,3.3,1812,4.226,2723,4.252,2878,6.211,9675,8.264]],["t/2992",[1,2.094,5,2.356,12,3.535,26,4.408,85,2.423,86,3.345,90,3.146,94,2.889,123,3.74,168,2.858,198,4.229,219,2.827,239,4.052,287,2.977,414,3.596,491,3.666,510,2.502,514,4.303,538,2.718,612,2.502,621,2.502,757,5.868,760,4.137,817,5.888,978,2.704,1307,4.651,1424,6.303,1599,3.537,3063,6.593,3337,4.182,9591,7.94,9676,7.94]],["t/2994",[5,1.791,20,3.769,24,4.105,37,7.208,47,3.006,72,2.737,83,1.651,94,3.653,148,2.133,150,3.48,168,2.79,198,4.128,208,2.465,239,3.955,245,3.281,263,2.6,414,3.656,613,4.176,615,3.061,659,3.214,678,4.476,757,5.23,783,5.291,796,3.996,840,4.508,882,4.225,1075,6.947,1443,3.521,1812,4.276,1874,4.879,1878,5.12,1979,5.491,2104,6.607,2230,5.365,2241,6.152,3766,6.607,9221,7.047]],["t/2996",[30,2.18,83,2.103,148,2.717,259,2.009,287,2.882,411,2.464,414,3.631,757,5.143,840,5.741,1203,5.96,1830,5.741]],["t/2999",[7,2.002,10,2.855,21,2.255,33,4.068,117,1.359,168,2.618,170,4.23,258,2.996,259,2.338,287,2.123,412,2.676,473,2.308,537,5.773,544,5.218,549,5.298,560,3.429,571,3.874,576,2.535,600,4.62,606,4.62,607,2.151,617,4.144,768,4.462,809,4.036,987,2.803,1024,3.553,1072,3.965,1260,4.909,1579,5.087,1753,3.896,1924,3.386,2197,5.153,2899,4.292,2921,7.234,3595,7.368,4265,8.582,4849,6.2,9677,7.847,9678,10.388]],["t/3001",[36,5.961,83,2.152,95,4.12,259,2.056,1031,6.359,1069,5.608,2921,7.59,2928,7.254,3595,6.896,4265,7.254]],["t/3003",[33,4.311,73,2.09,83,1.903,117,1.206,166,3.527,218,2.45,240,2.188,249,3.24,267,1.72,320,3.759,421,2.637,422,3.547,598,4.469,607,2.642,775,2.821,781,2.997,809,2.286,867,2.974,890,3.256,923,1.844,986,8.421,1007,5.166,1009,3.433,1062,3.179,1211,2.956,1277,3.708,1330,4.061,1368,4.974,1386,4.299,1477,3.636,1727,2.494,1987,4.026,2144,3.812,2581,4.991,2921,4.89,3665,6.48,3675,6.953,3705,8.469,4261,4.061,4262,4.097,4265,4.673,4295,6.508,4694,7.845,7088,6.508,9679,7.022,9680,9.638,9681,7.022,9682,9.638,9683,7.022]],["t/3005",[4,4.049,33,3.181,83,1.914,126,3.789,180,3.82,259,1.828,391,2.766,520,5.019,547,6.206,552,4.812,560,4.236,597,3.738,781,3.253,809,3.156,925,8.42,986,6.365,2123,5.76,3238,10.444,4265,6.451,4280,7.131,8418,8.984]],["t/3007",[33,3.683,136,3.947,196,2.642,210,4.079,391,2.522,421,4.214,422,5.669,520,4.576,604,5.302,985,3.363,1248,5.025,1283,6.278,1445,6.154,1622,7.193,1727,3.138,1958,4.798,2123,5.252,2144,4.798,2815,7.146,2921,6.154,2928,5.882,3005,6.154,3665,5.203,4265,7.468,6143,6.26,8507,7.447,9684,11.22,9685,8.837]],["t/3009",[11,3.73,75,5.83,95,4.088,214,3.773,259,2.04,571,5.339,809,3.522,987,3.864,1180,5.959,1187,5.195,4265,7.198]],["t/3011",[2,1.527,4,4.885,5,1.281,7,2.705,15,1.864,19,3.887,20,3.384,30,0.76,33,1.218,36,2.03,72,1.215,75,2.001,76,5.53,77,2.045,86,1.818,87,2.05,93,2.786,103,2.406,106,1.802,117,1.035,139,1.092,168,1.994,170,2.001,209,3.501,214,1.295,219,1.225,259,2.562,262,1.729,267,1.839,339,2.707,391,1.059,411,0.859,412,1.266,414,1.006,421,2.245,422,1.875,461,4.429,470,2.891,486,1.665,501,5.27,506,2.001,510,1.084,521,1.601,532,2.296,535,2.093,538,1.177,549,2.506,557,2.774,560,1.622,565,2.166,571,2.951,597,1.431,604,5.663,607,1.018,612,1.084,617,3.157,621,2.946,623,2.227,665,3.66,748,2.29,792,4.036,809,3.284,818,1.898,822,2.396,834,1.385,867,1.145,875,1.196,890,1.721,891,1.812,969,2.985,986,2.437,991,2.624,997,2.129,998,1.089,1013,1.755,1019,1.721,1035,2.147,1055,1.398,1069,3.076,1070,1.864,1071,1.934,1072,3.02,1133,2.73,1135,2.348,1169,3.458,1180,2.045,1204,1.515,1211,2.517,1222,2.677,1330,2.147,1403,2.437,1452,3.021,1479,4.866,1553,2.73,1586,1.864,1596,1.372,1617,2.206,1954,3.096,2304,1.658,2462,2.79,2785,2.79,2815,2.045,2921,4.163,2928,2.47,2934,2.128,3595,2.348,4265,9.161,4280,6.943,8367,3.128,8395,4.601,9047,3.021,9074,3.261,9250,3.128,9686,3.711,9687,3.711,9688,3.128,9689,3.711,9690,3.711,9691,3.711,9692,3.711]],["t/3014",[4,4.617,40,3.147,43,2.087,76,2.913,86,3.073,117,0.946,139,1.764,145,3.384,165,2.589,210,2.855,219,1.98,263,3.142,276,2.913,338,4.19,339,2.717,420,3.257,462,3.44,479,4.617,482,3.257,496,3.257,552,2.978,573,3.44,607,2.366,614,4.36,635,4.509,649,2.633,732,1.889,760,2.897,774,3.673,792,6.823,809,1.954,822,2.405,834,2.238,867,1.851,890,4.001,945,4.883,987,3.083,997,3.6,1057,5.561,1062,2.717,1071,3.127,1114,3.501,1135,3.796,1156,3.993,1158,6.348,1177,3.353,1180,3.306,1211,2.526,1234,3.796,1248,3.412,1277,3.168,1286,3.168,1298,5.272,1373,4.05,1403,6.636,1584,3.939,1750,3.47,1923,3.501,2016,3.212,2144,3.257,2557,4.112,2754,3.234,2943,4.883,2998,4.328,3253,5.272,3901,4.617,3932,4.05,4265,6.726,4280,4.414,4593,6.253,5431,5.561,6909,4.883,6926,5.272,8138,5.272,8395,6.641,8473,4.74,9633,5.272,9693,5.999,9694,5.999,9695,5.999,9696,5.999,9697,5.999,9698,5.999,9699,5.999,9700,5.999,9701,5.999,9702,5.999]],["t/3016",[4,4.696,5,1.567,7,1.866,19,3.788,20,3.297,51,3.674,72,2.394,76,3.552,91,3.375,93,4.618,94,2.467,117,0.802,168,2.44,209,2.975,210,2.42,259,2.448,339,3.312,487,2.911,499,4.683,510,2.136,549,4.938,576,2.363,579,2.703,600,5.835,604,4.389,617,3.863,621,2.136,748,3.796,792,6.691,809,2.382,869,4.126,875,3.193,890,3.392,987,2.613,1013,3.46,1035,4.231,1132,4.938,1135,4.628,1177,2.427,1204,2.986,1217,6.427,1251,5.498,1308,3.696,1403,4.803,1445,5.094,1586,3.674,1617,4.347,2129,6.78,2144,5.381,2785,5.498,3554,5.954,4265,8.381,4280,5.381,8395,7.627,9703,6.78]],["t/3018",[4,4.553,259,2.056,764,4.626,1125,5.155,2520,10.074,2921,7.59,3595,6.896,4265,8.487]],["t/3021",[5,1.905,7,2.268,21,2.556,30,1.82,73,2.647,83,2.224,117,0.975,122,4.599,239,4.206,240,2.019,262,4.144,297,2.615,402,3.453,463,3.033,579,3.287,614,4.493,731,5.336,732,2.8,814,4.17,816,3.631,822,4.515,887,5.502,1253,4.548,1819,4.794,1966,4.493,2075,4.466,2235,7.494,2238,6.844,2288,4.938,2545,5.445,2838,6.299,3359,5.919,9704,8.243,9705,8.893]],["t/3023",[17,3.823,21,2.492,30,1.775,33,2.847,83,1.713,117,0.951,122,3.541,193,3.195,197,4.041,210,2.87,240,1.969,287,2.347,521,3.742,553,4.611,582,4.779,643,6.381,732,2.731,814,4.667,822,4.898,923,2.278,998,2.545,1030,5.778,1271,4.549,1715,3.514,1914,4.331,1966,4.382,2185,6.04,2238,6.674,2838,6.143,2904,6.519,3337,4.234,3502,5.107,4327,6.04,8125,7.059]],["t/3025",[7,3.163,30,1.832,44,1.591,95,3.383,167,5.089,239,4.233,259,1.688,287,3.061,452,4.016,463,3.052,524,6.6,529,3.132,582,4.932,668,3.339,732,3.561,814,4.182,822,3.587,887,5.538,1271,4.695,1369,6.584,1485,5.801,1582,6.584,1718,6.727,1847,6.584,2075,4.495,2182,5.132,2197,5.877,2545,5.479,3359,5.957,9001,8.295,9706,8.95]],["t/3027",[287,2.972,474,4.047,562,4.484,732,3.458,814,3.705,978,3.467,1778,5.169,1792,6.871,1924,4.74]],["t/3029",[7,2.146,30,1.722,44,1.496,83,1.661,90,3.089,95,3.18,198,4.153,208,2.48,258,3.212,266,3.615,287,2.276,391,2.401,457,3.775,582,7.265,612,2.457,615,3.08,732,4.009,814,4.294,923,2.209,957,3.19,1052,5.386,1089,5,1177,2.791,1271,4.413,1349,6.132,1582,6.189,1609,4.276,1830,4.535,1866,6.069,3359,5.599,4169,4.635,8055,5.386,9707,8.413,9708,8.413,9709,8.413,9710,8.413,9711,7.797]],["t/3031",[94,3.874,117,1.118,165,3.294,193,2.812,258,2.914,266,4.383,287,3.108,402,2.964,538,2.422,579,2.821,582,7.04,607,2.093,612,2.979,619,4.64,732,3.86,737,3.473,802,2.641,814,4.433,867,2.356,923,2.005,987,2.727,1014,3.592,1024,3.456,1028,3.706,1072,3.857,1089,6.062,1174,5.316,1347,4.948,1457,4.415,2032,3.812,2075,5.769,2144,4.145,2180,2.944,2545,7.032,2625,5.316,7922,5.507,8624,5.874,9712,6.707,9713,7.075,9714,7.075]],["t/3033",[1,2.133,7,2.226,10,3.175,30,1.786,35,5.289,83,2.198,123,2.687,156,2.705,168,2.911,243,2.263,287,2.362,391,3.498,566,6.295,607,2.393,732,4.065,767,5.138,769,5.092,814,4.354,866,4.95,882,4.409,912,4.107,980,3.797,1110,5.522,1308,4.409,1484,6.895,1640,3.898,1722,4.027,2006,3.97,2619,4.215,6535,9.781]],["t/3035",[168,3.723,211,4.124,287,3.02,607,3.059,732,3.514,814,3.764,1271,5.854]],["t/3037",[94,3.705,287,2.972,473,3.23,612,3.208,732,3.458,814,3.705,822,4.402,2075,5.517,2545,6.725]],["t/3039",[1,2.275,5,2.483,7,2.957,95,3.518,117,1.02,156,2.261,235,4.471,240,2.113,266,3.999,287,2.518,529,3.257,562,3.799,582,6.387,621,2.718,732,3.975,814,4.258,911,6.033,991,4.084,1607,4.612,1778,4.38,1924,4.016,2195,6.481,2350,5.758,8055,5.959]],["t/3042",[5,1.453,7,1.73,38,2.491,44,2.621,83,1.339,97,2.093,117,0.744,156,1.648,172,1.57,188,3.407,258,2.59,263,2.109,266,4.044,421,2.547,463,2.314,483,2.581,538,2.152,562,2.769,582,5.186,619,3.086,621,1.981,639,3.513,719,3.017,732,2.963,753,2.812,781,1.716,783,4.292,814,3.937,993,2.616,1283,3.796,1399,3.312,1465,3.058,1596,2.507,2075,5.428,2425,5.11,3617,5.716,7922,7.796,8055,4.343,8752,5.961,9643,6.287,9712,8.27,9715,6.287,9716,6.287,9717,6.287,9718,6.287,9719,6.287,9720,6.287]],["t/3044",[5,1.75,7,2.083,38,2.999,73,2.431,90,2.999,94,2.755,95,3.087,97,2.521,117,0.895,164,3.334,165,3.524,198,5.265,211,3.018,263,2.539,266,3.509,267,2,463,2.785,483,3.108,582,5.877,636,4.203,732,3.739,781,2.066,787,3.425,802,2.825,814,4.246,896,5.833,985,2.448,1089,4.854,1181,4.151,1191,5.363,1283,4.57,1294,6.453,1348,6.285,1790,3.715,1966,4.126,2006,3.715,2180,3.15,2538,5.598,2545,7.271,4320,5.598,9166,6.285,9306,5.892,9713,7.57]],["t/3046",[44,2.629,94,2.266,117,0.737,156,1.633,188,3.374,266,2.887,287,1.818,452,3.014,521,4.034,531,3.335,562,2.743,594,4.113,612,1.962,679,3.394,719,2.988,732,3.385,741,5.17,767,3.956,781,1.7,802,2.324,814,3.626,923,1.764,998,1.971,1177,2.229,1273,2.627,1465,3.028,1596,2.483,1732,3.415,1966,3.394,1989,5.407,2006,3.056,2075,4.695,2180,2.591,2425,5.076,2538,4.605,2545,6.583,3617,5.662,6867,4.847,7922,6.744,8752,5.903,9712,5.903,9715,6.227,9716,6.227,9717,6.227,9718,6.227,9719,6.227,9720,6.227]],["t/3048",[21,3.285,1778,5.38,1924,4.933,3337,5.581]],["t/3050",[20,3.725,38,3.035,83,1.632,94,2.787,96,3.253,123,2.544,208,3.168,242,4.15,245,3.242,259,1.559,263,2.569,266,3.551,462,6.163,474,3.044,538,2.622,579,4.414,612,2.413,659,3.176,732,3.76,760,3.991,814,3.625,822,4.307,882,4.175,907,5.664,923,2.17,1052,5.291,1098,5.793,1397,5.961,1443,3.48,1471,5.335,1607,3.288,1878,5.059,1904,4.175,2216,6.529,2230,3.691,2234,5.755,2241,6.08,2244,7.659,9220,5.853,9721,8.264,9722,8.264]],["t/3053",[5,2.645,7,1.765,43,2.407,51,3.474,117,0.758,208,4.077,211,2.556,216,3.605,218,2.414,259,2.22,287,2.581,296,2.521,297,2.034,330,4.049,351,3.729,354,7.604,398,2.548,411,2.207,452,3.104,483,2.632,487,2.753,511,3.147,521,2.985,527,3.174,568,3.377,597,2.668,600,4.073,607,2.615,625,4.99,638,4.604,663,4.133,775,2.025,875,2.229,881,4.151,1031,4.036,1070,3.474,1169,4.001,1204,2.824,1205,3.147,1478,3.703,1609,3.516,1640,3.09,1801,3.629,1812,3.538,1819,5.143,1926,3.703,2449,4.151,2467,5.669,2666,7.205,6090,5.829,8390,6.882]],["t/3055",[5,1.895,30,1.271,43,2.161,95,2.348,117,0.97,148,3.146,168,2.072,172,1.437,179,3.658,196,1.858,197,2.894,208,4.034,214,2.168,218,2.168,258,2.372,267,2.167,296,2.338,330,3.755,414,1.685,423,5.812,560,2.715,565,3.625,579,2.296,584,2.88,604,3.728,607,1.703,639,3.217,654,2.517,659,2.388,695,4.908,756,2.938,760,3,764,5.507,775,2.59,783,3.931,882,3.139,912,4.163,923,2.324,969,3.102,1045,4.027,1204,3.612,1331,3.572,1430,5.235,1812,3.177,2072,3.625,2239,3.844,2242,5.235,2305,3.398,2467,6.124,2484,6.067,2496,6.766,2666,6.552,2723,3.197,2840,4.781,3579,6.99,3652,6.509,4168,4.4,4631,4.57,6090,5.235,8201,5.459,9723,6.212]],["t/3057",[5,1.98,21,2.657,25,4.757,30,1.892,87,3.171,97,3.563,139,2.719,206,5.056,259,1.744,264,4.308,571,5.699,579,3.417,612,2.7,619,4.206,654,4.678,670,4.129,895,5.056,908,3.417,987,3.303,1195,5.443,1308,4.671,2185,6.438,2350,5.72,2467,7.48,2577,7.525,2666,6.736,9054,7.525]],["t/3059",[5,1.793,10,2.093,21,2.836,30,1.177,52,4.006,87,1.973,97,1.775,117,0.918,139,2.462,177,2.629,208,3.656,210,1.904,216,2.998,235,4.021,239,2.721,241,3.101,259,1.579,266,3.597,296,2.213,315,2.907,354,8.851,473,1.692,474,2.119,483,2.189,502,5.659,527,3.831,554,4.006,574,3.522,593,3.829,623,3.452,625,4.15,638,8.762,663,2.493,668,3.124,775,1.684,831,4.818,875,1.854,912,2.707,977,5.93,1072,2.907,1133,4.233,1170,2.452,1180,3.17,1207,4.427,1349,3.245,1480,3.219,1489,3.018,1607,2.289,1801,4.391,1812,2.942,1829,2.367,1874,4.885,2059,3.124,2187,4.006,2206,4.233,2221,4.683,2304,2.57,2316,2.593,2445,4.545,2453,3.299,2467,4.975,2518,3.272,2666,5.758,3066,4.683,3465,4.15,4313,4.006,4314,4.075,8240,4.848,8429,7.055,9623,5.332,9654,5.332,9724,5.753,9725,5.753,9726,8.372,9727,5.753,9728,5.753,9729,5.753]],["t/3061",[5,2.114,11,2.888,86,1.75,87,2.871,93,2.681,97,2.584,106,4.065,117,1.317,139,2.462,148,1.467,168,1.919,196,1.72,208,3.747,209,2.34,214,2.007,216,2.998,239,2.721,255,3.486,259,1.579,315,2.907,330,2.442,354,9.168,398,2.119,412,2.855,414,1.56,469,3.272,470,2.564,492,2.273,502,4.8,521,3.612,526,2.147,527,3.998,568,2.809,574,3.522,575,3.431,607,1.577,611,2.413,621,2.445,638,6.568,645,2.385,665,3.522,697,3.939,710,4.006,745,3.486,923,1.511,952,7.26,980,2.503,991,3.674,1045,5.426,1099,3.829,1133,4.233,1349,3.245,1364,5.36,1489,3.018,1615,2.998,1734,2.824,2221,4.683,2446,5.332,2467,3.419,2666,4.885,2872,5.237,3082,3.272,4169,3.17,4313,4.006,4314,4.075,5835,7.356,9730,5.753,9731,5.753,9732,5.753,9733,5.753,9734,5.753,9735,5.753,9736,5.753,9737,5.753]],["t/3063",[3,2.531,5,1.313,11,2.115,43,2.133,113,6.889,117,0.961,148,1.564,186,2.484,193,2.259,196,1.833,208,4.024,222,3.486,243,1.59,258,2.34,267,2.147,296,2.316,297,1.803,330,3.72,400,3.259,411,1.419,414,1.663,492,2.422,510,2.56,514,3.079,538,2.781,546,3.577,571,3.026,576,1.981,579,2.266,607,1.681,621,1.79,638,6.808,648,3.259,654,4.145,659,3.368,663,4.836,668,3.27,734,3.329,764,2.602,809,1.996,870,3.679,879,3.546,991,2.691,998,1.799,1181,3.116,1204,3.578,1211,2.581,1349,3.458,1609,3.116,1778,2.885,1812,3.135,1819,4.725,1865,4.51,1924,4.413,2195,4.269,2221,4.99,2239,3.793,2337,3.237,2467,3.643,2468,3.282,2484,3.61,2666,6.513,3579,8.818,4313,4.269,4314,4.343,4614,4.608,6163,4.843,7128,4.51,8524,5.387,9738,6.131]],["t/3065",[5,2.105,6,4.996,7,2.507,95,4.531,117,1.314,208,2.897,209,3.998,412,3.352,414,3.251,452,4.41,621,3.501,666,4.058,834,3.667,908,3.632,923,2.581,1528,6.542,1640,4.39,2467,5.841,2666,5.735,9739,9.829]],["t/3067",[73,3.122,106,5.094,196,3.137,229,3.578,400,5.577,414,3.381,490,4.315,607,2.876,998,3.078,1070,5.269,1386,6.423,1528,6.983,1818,6.121,1982,7.718]],["t/3069",[30,1.662,76,3.943,95,3.069,117,1.165,187,2.63,196,2.428,208,3.491,219,2.68,249,3.747,255,4.921,296,2.146,400,4.317,414,3.407,421,3.049,452,4.767,457,4.767,470,2.487,510,2.371,527,2.701,571,5.245,647,4.738,666,4.387,775,2.377,875,2.616,912,3.821,914,3.518,985,2.434,987,2.901,993,3.131,1125,5.025,1132,5.482,1177,2.694,1818,6.199,1982,7.817,2305,4.441,2468,5.687,2679,5.752,3259,5.08,3294,5.858,9652,7.526]],["t/3071",[1,0.893,5,2.005,10,1.329,11,2.562,20,3.844,30,0.748,43,2.584,47,2.67,87,2.025,97,1.822,113,3.444,117,0.814,142,2.466,148,0.932,154,2.544,168,1.219,179,2.151,208,4.032,209,3.021,210,1.953,211,1.35,214,1.275,222,2.078,241,1.969,258,1.395,259,1.609,287,2.01,288,3.385,296,1.963,297,1.736,315,4.73,320,1.956,330,2.505,339,1.654,351,1.969,354,7.339,398,2.736,412,2.013,452,2.649,457,1.639,470,2.275,491,2.526,501,2.237,513,2.013,521,1.576,526,1.363,527,3.87,538,2.357,568,2.882,571,3.667,573,2.095,575,1.497,576,1.18,584,1.694,597,1.409,613,1.824,621,2.734,623,2.192,638,6.665,648,1.942,649,1.603,659,1.404,663,2.558,697,1.719,745,3.577,764,1.551,787,1.532,809,1.19,820,1.305,831,1.784,834,2.202,866,1.625,867,3.59,870,2.192,882,1.846,891,2.882,914,1.583,952,4.343,953,1.583,955,1.544,980,1.59,991,1.603,1002,2.432,1024,1.654,1072,1.846,1091,2.044,1125,3.513,1141,2.886,1170,2.516,1175,2.399,1182,2.504,1218,1.916,1249,3.096,1364,2.339,1418,1.48,1489,3.896,1553,2.688,1578,2.811,1607,2.349,1609,3,1715,2.392,1724,2.811,1778,1.719,1812,4.362,1819,3.182,1924,2.547,1989,2.113,2223,2.312,2316,1.647,2449,2.192,2467,5.069,2522,2.588,2666,5.843,3005,2.544,3337,1.784,3646,2.588,3837,2.811,4168,2.588,4170,2.26,4480,4.974,6829,2.974,7914,3.21,7931,2.544,8042,3.079,8201,3.21,8390,4.258,8395,2.811,9645,2.886,9740,3.653,9741,3.653,9742,3.386]],["t/3074",[5,1.846,7,2.199,30,2.63,33,4,83,1.702,122,3.519,139,3.779,168,2.875,172,1.995,243,2.235,245,3.382,487,3.43,488,4.334,521,3.719,555,4.42,579,3.185,611,3.615,867,2.66,875,2.777,891,4.208,998,2.529,1134,5.66,1715,3.493,1751,4.943,1926,4.614,2259,6.003,2260,3.833,2881,3.455,2940,6.218,3428,6.106,7896,7.264]],["t/3076",[1,2.245,7,2.343,12,2.952,33,3.015,44,1.633,83,1.814,117,1.007,172,2.125,488,4.232,521,3.963,530,4.031,555,4.17,611,5.516,626,3.518,989,5.267,993,4.433,1457,6.649,1987,5.267,2157,5.112,9743,9.914,9744,10.215]],["t/3078",[30,2.388,33,1.952,83,1.693,139,3.432,168,1.984,210,1.968,214,2.076,218,2.076,226,3.996,243,3.326,258,2.271,276,2.888,287,1.61,297,1.749,398,2.191,452,3.848,483,2.263,488,4.687,526,3.753,552,4.258,555,5.041,574,3.642,579,2.198,611,5.098,612,1.737,614,3.005,660,2.545,760,2.873,886,3.303,890,2.758,910,3.569,923,1.562,987,2.125,989,3.411,997,2.119,1014,2.799,1028,4.164,1035,3.44,1150,4.016,1170,2.535,1180,3.278,1187,2.858,1247,4.7,1480,3.329,1599,2.456,1615,3.1,1790,3.901,1934,4.726,2138,4.143,2881,3.437,3345,3.642,4168,6.075,7896,5.013,7955,4.842,9036,5.513,9627,5.513,9745,8.576]],["t/3080",[7,2.537,30,2.036,33,2.413,83,1.452,123,2.264,139,2.925,164,3.002,172,2.301,217,4.115,218,3.47,243,3.372,258,2.807,287,1.99,463,2.508,471,4.329,487,2.926,488,4.385,555,4.576,611,5.453,626,2.817,647,4.29,781,1.86,831,3.59,890,3.409,987,2.627,989,4.217,997,2.619,998,2.157,1014,3.46,1028,3.57,1110,4.652,1231,3.57,1609,3.737,1790,4.525,2259,5.121,2260,3.27,2300,4.115,2478,3.936,2881,4.517,4942,5.121,8117,5.527,8425,6.461,9744,8.096,9746,7.353]],["t/3082",[3,2.831,5,0.945,7,2.418,20,3.09,30,0.903,40,3.596,41,1.989,47,1.586,83,1.66,86,1.342,95,2.592,117,0.484,118,1.646,139,1.298,142,2.979,172,1.946,194,1.668,211,1.631,214,2.392,218,1.54,221,2.109,243,3.302,250,1.769,259,0.832,267,1.679,287,2.566,297,2.016,391,1.259,411,1.586,457,3.772,470,3.145,473,2.473,488,4.521,510,1.289,538,1.4,542,2.937,555,4.679,568,2.154,571,2.178,589,3.246,594,2.701,600,4.037,607,2.305,611,5.623,647,2.575,781,1.734,787,1.851,832,2.33,867,2.116,875,3.055,882,2.229,886,2.45,914,1.912,978,2.993,989,2.53,991,3.69,993,2.644,997,2.995,1019,2.046,1028,2.142,1069,2.271,1110,4.338,1196,3.073,1238,3.126,1421,3.347,1751,5.437,1866,3.183,1875,3.592,2145,2.489,2154,2.285,2260,4.216,2478,2.362,2630,4.09,2881,1.769,2899,3.75,2934,2.53,3683,3.877,4261,2.552,4509,3.396,4942,3.073,5649,3.718,7185,3.877,7897,3.396,7902,3.073,8516,4.09,8556,4.09,8653,3.317,8986,3.024,9333,3.877,9747,7.388,9748,4.413]],["t/3084",[7,2.493,10,2.607,11,2.471,83,1.415,86,2.179,166,3.599,218,3.881,219,2.364,243,3.346,287,2.644,473,2.107,488,4.217,510,2.093,526,3.646,538,3.101,555,4.535,574,4.387,607,1.964,611,5.538,612,2.093,636,5.029,866,3.186,871,3.978,874,3.89,875,2.309,987,2.56,997,2.552,1055,2.7,1062,4.425,1267,4.258,1271,3.759,1292,5.514,1750,4.144,1751,4.109,1790,3.259,2260,3.186,2478,3.836,2881,2.872,2899,3.919,4441,4.99,4866,5.832,4942,4.99,7115,5.832,9744,9.053,9747,6.296,9749,7.165,9750,7.165,9751,7.165]],["t/3086",[117,0.88,194,3.034,243,3.458,452,3.602,457,3.602,488,4.748,555,5.106,611,5.448,636,4.13,875,4.03,1751,7.171,2036,5.905,2154,5.46,2320,5.59,2693,7.469,2899,4.39,7897,6.177,7902,7.343,8519,8.886]],["t/3088",[44,2.675,83,0.801,117,0.703,194,1.533,201,2.087,243,2.065,263,1.261,488,3.326,526,1.513,555,3.804,611,1.701,719,4.664,875,1.307,885,2.388,890,1.88,923,1.065,942,3.242,1457,2.345,1465,1.828,1712,3.484,1751,3.679,2036,4.721,2062,1.772,2154,4.123,2157,2.853,2260,1.803,2275,2.816,2320,4.468,2425,6.523,2688,5.407,2693,4.545,2927,3.204,4334,3.301,7897,6.127,8519,5.407,9752,3.758,9753,3.758,9754,3.758,9755,3.758,9756,3.758,9757,3.758,9758,3.758,9759,3.758,9760,3.758,9761,3.758,9762,4.055,9763,4.055,9764,4.055,9765,4.055,9766,4.055,9767,4.055,9768,4.055,9769,4.055,9770,4.055,9771,4.055]],["t/3090",[83,2.056,96,4.887,210,3.445,235,5.963,243,2.701,408,5.873,473,3.062,488,4.186,555,4.502,611,4.367,781,2.634,3098,6.248]],["t/3092",[9,5.354,24,4.105,44,2.135,47,3.892,83,1.651,85,2.365,95,3.161,118,3.12,172,1.935,194,3.161,208,3.193,209,3.401,243,2.809,263,2.6,287,2.263,469,4.755,488,4.051,555,4.357,611,5.519,874,4.54,875,2.695,997,2.979,1751,6.21,1812,4.276,2154,4.33,2235,7.047,2478,4.476,2899,4.574,3665,4.924,4942,5.824,7897,8.334,8069,6.607,9704,7.751,9744,6.807]],["t/3094",[44,2.358,85,2.945,118,3.885,209,4.235,243,2.701,469,5.921,488,3.512,555,3.777,611,4.367,997,3.709,2478,5.574,3665,6.131,4942,7.252,9744,8.476]],["t/3097",[21,2.539,25,4.547,30,1.809,33,2.901,83,1.745,122,3.608,139,2.599,172,2.045,187,2.862,210,2.924,218,3.083,245,3.467,287,2.391,414,2.396,449,6.26,452,3.965,487,3.516,488,4.158,490,3.635,538,2.804,555,4.472,611,3.706,732,2.782,814,2.98,816,3.608,866,4.989,1421,4.314,1457,5.111,1841,3.245,2157,3.93,2260,3.93,2877,6.982,3318,5.355,3428,6.26,9772,8.191]],["t/3099",[1,2.008,7,2.096,12,2.64,33,3.514,44,1.461,83,1.622,117,0.901,122,3.354,139,2.416,172,1.901,187,3.468,210,2.718,218,2.866,245,3.223,258,3.136,398,3.027,421,4.02,455,7.614,488,4.017,489,2.74,504,4.493,530,3.605,555,4.32,557,3.036,611,5.292,626,4.101,816,3.354,892,4.254,989,4.711,993,3.168,1146,4.309,1455,4.672,1830,4.429,2260,3.653,3665,6.304,3905,7.535,9743,6.49,9773,8.215]],["t/3101",[30,1.743,83,1.681,122,3.476,139,3.222,164,3.476,194,3.219,217,4.765,243,3.317,470,2.608,473,2.504,488,4.569,555,4.998,598,3.948,607,2.334,611,3.571,612,2.487,816,3.476,832,4.496,866,3.786,874,4.623,875,2.744,1431,3.987,1618,4.376,1715,3.45,1751,4.883,2478,4.558,3428,6.031,4509,6.553,7902,5.93,9774,8.515]],["t/3103",[3,3.08,5,1.055,7,3.098,12,1.583,33,2.448,38,1.808,41,2.219,50,4.897,95,1.861,117,0.818,139,1.448,163,2.341,168,1.643,172,2.324,218,2.602,243,2.604,258,1.88,267,1.827,287,2.436,391,2.129,397,2.873,411,1.139,418,2.473,419,2.251,443,2.065,463,1.679,473,1.448,488,4.575,510,1.438,526,3.359,530,2.161,555,4.921,558,3.701,579,1.82,589,5.487,611,3.128,623,2.955,624,2.459,697,2.317,764,3.166,766,3.153,781,2.73,867,1.52,909,3.047,914,2.134,976,3.116,987,1.759,1003,3.887,1004,2.431,1024,2.23,1059,3.789,1071,2.566,1072,2.488,1091,2.755,1097,2.018,1177,1.634,1204,2.01,1211,2.073,1231,2.391,1271,2.583,1274,3.789,1308,2.488,1311,3.701,1421,2.404,1643,3.278,1698,2.984,1717,4.615,1722,2.272,1750,2.848,1751,2.824,2010,3.08,2032,2.459,2145,2.777,2260,3.316,2313,2.848,2597,4.15,2723,2.534,2881,2.989,2899,4.923,3028,3.015,3135,3.429,4317,3.701,4519,4.15,4662,6.766,4863,3.89,5896,3.375,9645,3.89,9688,4.15,9775,4.924,9776,6.913,9777,4.924,9778,4.924,9779,4.924,9780,4.924,9781,4.924,9782,4.924]],["t/3105",[7,2.108,21,2.375,30,1.691,33,3.527,43,2.875,75,4.455,94,2.787,95,4.062,117,0.906,139,3.719,166,4.15,206,4.52,267,2.024,418,4.15,419,3.777,488,4.615,504,5.878,555,4.875,596,5.579,621,2.413,748,3.165,987,2.952,1127,5.229,1200,4.393,1398,3.991,1989,4.78,2142,6.529,2195,5.755,2448,6.08,2703,5.426,2971,5.579,3250,6.211,3428,5.853,3905,5.229]],["t/3107",[30,1.573,44,2.671,83,0.759,96,1.513,117,0.674,139,1.808,168,1.282,201,1.978,243,2.657,263,1.195,488,3.628,526,2.294,555,4.18,562,1.569,607,1.054,611,3.223,719,4.556,885,2.263,942,3.107,978,1.213,1017,2.404,1072,1.942,1140,2.168,1465,1.732,1478,2.058,1712,3.339,2036,4.524,2062,1.68,2154,3.184,2157,2.734,2260,1.709,2275,2.699,2320,4.282,2425,6.418,2478,2.058,2688,5.182,2693,4.356,2940,2.773,4334,3.129,7897,4.732,8519,5.182,9752,3.563,9753,3.563,9754,3.563,9755,3.563,9756,3.563,9757,3.563,9758,3.563,9759,3.563,9760,3.563,9761,3.563,9783,3.563,9784,3.844,9785,3.844,9786,3.844,9787,3.844,9788,3.844,9789,3.844,9790,3.844,9791,3.844,9792,3.844,9793,3.844,9794,3.129,9795,3.844]],["t/3109",[1,0.697,7,1.227,30,0.583,33,3.256,44,2.65,48,1.107,83,1.232,117,0.312,139,2.609,156,1.169,166,1.432,168,0.951,178,3.538,187,1.558,188,2.415,197,3.812,210,0.943,258,1.088,263,0.886,265,1.548,276,1.384,299,1.925,411,1.113,443,1.196,463,1.64,488,2.992,502,1.635,504,4.853,538,0.904,555,3.746,611,1.196,619,1.297,732,1.514,993,1.855,1055,1.074,1072,1.44,1089,1.694,1132,1.925,1134,1.872,1156,1.897,1231,1.384,1250,3.349,1271,1.495,1449,1.432,1465,3.302,1596,1.777,1685,1.985,1827,2.194,2478,1.526,2587,3.349,3032,1.727,3428,2.019,3895,6.149,3897,4.226,3905,5.176,4168,2.019,4429,2.019,4866,2.32,8112,2.402,9688,4.053,9783,5.781,9796,2.851,9797,2.851,9798,9.92,9799,2.851,9800,2.851,9801,2.851,9802,2.851,9803,2.851,9804,4.809,9805,2.851,9806,2.851,9807,2.851,9808,2.851,9809,2.851,9810,4.809,9811,4.809,9812,4.809,9813,2.642,9814,2.851,9815,2.851,9816,2.851,9817,2.851,9818,2.851,9819,2.851,9820,2.851,9821,2.851,9822,2.851,9823,2.851,9824,6.237,9825,6.237,9826,6.237,9827,6.237,9828,4.809,9829,4.809,9830,4.809,9831,4.809,9832,6.237,9833,4.809,9834,2.851,9835,2.851,9836,2.851,9837,2.851,9838,2.851,9839,2.851,9840,2.851,9841,2.851,9842,2.851,9843,2.851,9844,2.851,9845,2.851,9846,2.851,9847,2.851,9848,2.851,9849,2.851,9850,2.851,9851,2.851,9852,2.851,9853,2.851,9854,2.851,9855,2.851,9856,2.851,9857,2.851,9858,2.851,9859,2.851,9860,2.851,9861,2.851,9862,2.851,9863,2.851,9864,2.851,9865,2.851,9866,2.851,9867,2.851,9868,2.851,9869,2.851,9870,2.851,9871,2.851,9872,2.851,9873,2.851,9874,2.851,9875,2.851]],["t/3111",[5,1.739,7,2.071,40,4.26,94,3.583,95,3.069,117,1.165,118,3.964,139,3.694,172,2.459,206,4.441,259,1.531,488,4.511,555,4.851,579,3.001,596,5.482,611,3.406,621,3.103,866,3.611,875,2.616,882,4.102,973,5.565,978,2.563,980,3.533,993,4.097,1231,3.943,1271,5.573,1273,3.175,1398,3.922,1402,4.872,2478,4.347,2878,6.103,9876,8.12,9877,7.526,9878,8.12]],["t/3113",[5,2.007,7,2.39,30,2.382,33,3.075,95,3.541,118,3.496,172,2.168,224,4.549,243,3.019,267,2.295,418,4.705,419,4.282,488,3.926,526,3.496,530,4.112,542,6.236,555,4.593,607,2.569,766,5.998,1055,3.53,1127,5.928,1722,4.323,2142,7.402,2284,6.758,2881,3.755,4631,6.893]],["t/3115",[7,2.071,10,2.954,30,1.662,33,2.665,97,2.506,117,1.165,118,3.03,139,2.388,166,4.078,206,4.441,243,2.106,287,2.197,339,3.677,412,2.769,488,4.511,504,4.441,538,2.576,542,5.405,549,5.482,555,4.729,558,6.103,607,2.226,611,4.456,621,3.458,834,3.03,989,4.656,1231,3.943,1398,3.922,1478,5.687,1547,4.26,1701,5.565,1722,3.747,2210,5.858,2275,3.564,2478,4.347,2573,5.565,2899,4.441,3294,5.858,3905,5.138,9639,7.135]],["t/3117",[7,2.617,216,5.347,228,5.654,243,2.661,262,4.781,287,2.777,421,3.853,488,4.445,555,4.78,611,4.303,768,5.835,923,2.695,1063,7.896,2878,7.712]],["t/3119",[44,2.159,118,3.746,243,3.149,287,2.717,488,4.403,555,4.736,611,5.093,790,7.435,953,4.35,3665,5.911,3905,6.352,5498,5.072,8069,7.932]],["t/3121",[44,2.288,243,2.871,488,3.734,555,4.016,611,4.643,3665,6.519,3905,7.005]],["t/3124",[5,1.907,6,3.186,17,2.763,22,3.388,48,2.434,86,3.621,137,2.559,138,1.934,139,2.618,165,2.704,172,1.45,209,2.549,216,3.266,219,2.068,235,3.011,287,1.696,339,2.838,412,2.138,414,1.7,461,4.581,473,1.843,481,3.837,486,2.812,488,2.114,527,3.75,552,3.112,557,2.316,565,5.195,614,3.167,649,2.751,764,2.66,809,3.877,834,3.322,845,5.102,874,3.403,912,4.19,953,2.716,997,4.712,1008,2.598,1055,3.354,1067,4.296,1114,6.578,1134,4.116,1142,4.172,1150,4.232,1584,4.116,1586,3.148,1801,3.288,1807,3.027,1829,2.578,1842,4.611,1914,4.446,1988,2.295,1989,3.625,2143,6.991,2186,3.761,2198,4.116,2256,6.7,2674,3.332,2944,4.365,3782,5.282,4593,6.407,5419,4.611,9086,5.102,9879,6.268,9880,5.102,9881,5.809]],["t/3126",[4,2.539,5,2.18,7,2.222,10,2.211,22,2.312,48,2.36,86,3.835,93,2.832,114,5.332,117,0.666,128,4,139,1.787,168,2.027,172,1.406,179,3.578,219,3.359,259,1.146,267,1.489,287,1.645,296,1.606,419,2.778,482,3.3,488,2.937,506,3.276,527,3.386,529,2.127,565,3.546,575,2.491,631,3.721,636,4.482,649,2.667,656,3.991,668,3.25,737,2.765,768,3.456,809,3.62,817,3.253,820,3.112,822,3.491,923,1.596,978,3.213,997,3.96,998,1.783,1008,2.519,1055,2.29,1070,3.052,1114,6.487,1132,4.103,1146,4.569,1151,3.485,1211,2.559,1238,4.305,1273,2.376,1332,4.252,1478,3.253,1599,3.596,1609,3.089,1715,2.463,1773,3.276,1793,4.801,1801,3.188,1988,2.225,2060,3.071,2062,2.656,2186,3.647,2256,3.612,2496,3.991,3028,3.721,3035,7.089,3154,6.065,6907,4.947,7516,4.232,7931,4.232,8438,5.121,8543,5.34,9882,5.633]],["t/3128",[5,2.459,6,2.9,18,3.853,44,1.014,48,3.231,86,3.996,93,2.659,94,2.807,117,0.626,126,3.253,169,2.596,194,2.157,208,2.453,219,3.241,229,1.946,354,3.974,398,2.102,412,1.946,481,3.494,486,2.56,488,1.925,511,2.596,514,2.866,527,4.116,557,2.109,606,3.36,610,2.833,649,2.504,652,2.699,654,3.372,786,4.455,809,3.902,822,2.287,834,2.129,868,4.822,955,2.412,978,2.627,997,4.088,1069,2.936,1114,6.698,1125,2.699,1177,3.259,1279,3.272,1332,5.27,1334,3.747,1431,3.897,1449,4.18,1487,3.699,1607,2.271,1615,5.119,1778,2.685,1801,4.365,1842,7.942,2018,2.833,2143,3.853,2191,3.494,2198,5.464,2256,5.837,2257,4.042,2944,3.974,3028,3.494,3805,4.198,4593,3.531,9136,6.574,9137,4.645,9883,5.289,9884,5.706]],["t/3130",[21,3.084,86,3.264,139,3.156,235,5.155,527,4.204,652,5.076,768,6.103,997,4.501,1066,5.298,1801,5.63]],["t/3132",[24,4.081,37,5.533,47,3.877,86,2.528,93,3.873,94,2.804,148,2.12,150,3.459,172,1.924,208,2.451,211,3.072,214,2.9,239,3.932,245,3.261,287,2.249,296,3.166,474,3.062,527,3.589,579,3.072,607,2.279,611,5.509,612,2.428,659,4.146,757,5.21,796,3.972,809,2.707,997,2.961,1075,4.808,1106,8.109,1331,3.356,1443,3.5,1615,4.332,1909,5.322,1953,5.2,2230,3.713,2240,5.2,2241,6.116,2354,7.005,9885,8.313]],["t/3135",[1,2.275,5,1.994,10,3.386,21,2.674,73,2.77,117,1.271,172,2.154,193,4.651,213,4.016,296,2.46,527,3.096,574,5.698,607,2.551,612,2.718,769,5.43,867,3.577,1008,3.858,1120,5.053,1140,6.538,1732,4.73,1790,4.234,2006,4.234,2490,5.531,3427,9.435,3503,6.592,9886,8.626]],["t/3137",[10,3.627,21,2.865,172,2.307,243,3.136,769,5.817,867,3.076,886,6.714,1033,5.036,1140,5.623,1177,3.307,1232,7.493,1914,4.978,2006,4.535,2923,6.382,3035,8.114,3427,10.594,9886,9.239,9887,9.969]],["t/3139",[93,4.781,117,1.125,156,2.493,243,3.418,287,3.329,527,3.413,607,2.813,923,2.695,1020,9.016,1070,5.153,2337,5.418,2449,6.157,2486,7.549,3427,8.352,8977,9.51]],["t/3141",[187,2.809,193,4.502,221,4.145,258,3.311,418,5.568,527,3.688,530,3.806,666,3.581,802,3,809,2.824,814,4.489,888,4.815,891,4.234,985,3.323,1021,5.016,1033,6.174,1286,4.58,1727,3.937,2032,4.331,2144,4.709,2449,5.204,2625,6.04,2770,3.727,2881,3.476,3428,6.143,3646,7.853,4285,5.773,4327,6.04,8978,8.039,9888,8.673]],["t/3143",[43,3.705,526,3.974,634,6.271,768,6.057,786,5.701,1097,4.364,1442,7.835,1443,4.484,1640,4.757,3259,6.662,9889,10.651,9890,10.651,9891,10.651]],["t/3145",[21,3.681,30,2.248,892,5.688,1200,5.84,1204,4.484,1443,4.625,1607,4.371,2006,4.997]],["t/3147",[9257,9.539]],["t/3150",[1,1.962,7,2.048,24,5.176,97,2.477,123,2.471,186,3.253,187,4.051,196,3.521,218,2.801,220,3.877,228,4.423,229,3.596,240,2.394,296,2.122,351,4.327,398,2.957,400,6.261,414,2.86,421,3.014,449,5.686,452,3.602,496,4.358,527,2.67,560,3.508,612,2.344,734,4.358,820,2.868,822,3.217,1018,5.203,1283,4.492,1330,4.643,1370,4.684,1418,3.253,1711,4.528,1712,4.358,1727,3.745,1734,3.94,1813,4.603,1816,3.493,1926,4.297,2233,4.914,4441,5.59,8211,6.534,9646,7.053]],["t/3152",[1,2.472,5,2.805,30,2.07,115,3.488,137,4.128,210,3.346,228,5.572,240,2.296,411,2.34,461,5.204,528,5.859,1276,6.931,1919,6.191,2171,4.31,3595,6.398,9743,9.636]],["t/3154",[5,1.69,11,3.597,21,2.268,117,1.28,139,2.321,164,3.222,167,4.488,168,2.632,196,3.118,224,3.832,228,6.435,240,1.791,259,2.202,267,1.933,287,2.135,391,2.252,398,2.907,400,7.055,401,4.011,457,3.541,489,2.632,526,2.944,564,4.605,607,2.164,612,2.305,630,4.316,631,4.831,735,4.195,867,3.604,987,2.819,1013,3.732,1089,4.69,1200,4.195,1218,4.14,1418,4.225,1715,3.198,1816,3.434,2445,6.235,2573,5.409,3318,7.077,9892,7.892]],["t/3156",[10,3.601,47,3.558,196,2.96,259,1.867,285,4.421,316,6.337,400,6.401,557,3.658,578,5.454,607,3.301,619,4.503,787,4.151,822,4.825,923,2.6,1599,4.087,1816,4.307,2557,6.784,2989,7.617,3075,7.82,9582,9.174]],["t/3158",[3,5.471,4,3.278,10,3.78,13,4.62,17,3.459,20,3.537,21,2.985,47,3.734,126,4.061,139,3.645,167,4.462,172,1.816,196,2.346,209,3.192,211,2.9,264,3.656,285,5.759,316,7.456,400,4.172,488,2.647,511,3.57,575,4.257,598,3.638,822,3.145,955,3.317,998,2.302,1013,3.712,1017,4.909,1089,6.174,1158,5.773,1216,5.773,1599,3.24,1609,3.989,1816,3.415,2557,7.981,2989,6.039,3589,5.773,4276,6.039]],["t/3160",[5,0.729,7,2.302,10,1.239,11,1.174,12,1.791,17,1.501,20,2.512,43,1.185,44,0.605,48,1.322,51,1.71,73,1.659,76,1.653,95,2.107,113,1.987,115,2.822,117,0.897,138,1.051,139,1.001,146,1.786,150,2.32,165,2.405,168,1.136,172,1.638,186,1.38,187,1.806,193,2.054,194,1.287,196,3.4,203,1.501,210,1.127,220,1.644,221,2.664,229,3.305,240,0.773,248,1.849,259,0.642,271,1.254,276,1.653,287,0.921,296,0.9,316,2.18,391,1.591,400,6.53,402,2.164,411,1.638,414,2.895,421,2.658,427,1.681,457,1.528,483,2.121,488,1.88,490,1.401,492,1.345,499,2.18,511,1.549,527,1.133,528,3.4,530,1.494,535,4.614,538,2.595,557,1.258,558,4.19,560,3.575,578,1.876,597,1.313,607,2.243,610,1.69,621,0.994,622,4.765,624,1.7,626,2.135,629,2.767,648,1.81,654,2.259,668,1.27,679,1.72,681,1.528,753,2.311,760,1.644,775,0.997,783,2.154,802,1.178,809,2.664,818,1.741,819,4.957,820,1.991,822,3.884,869,1.92,875,1.097,888,1.89,890,2.585,908,1.258,912,1.602,955,1.439,982,2.869,987,1.216,989,1.952,1013,1.61,1015,1.681,1025,1.7,1052,2.18,1062,1.542,1069,2.868,1111,3.156,1146,1.786,1177,1.13,1200,1.81,1257,2.266,1261,2.334,1273,1.331,1281,1.862,1300,2.107,1302,2.023,1344,1.89,1349,1.92,1401,1.81,1421,1.662,1519,1.92,1607,1.355,1609,1.731,1617,2.023,1732,1.731,1778,1.602,1801,1.786,1816,3.08,1829,1.401,1830,1.835,1843,3.763,1919,2.084,1943,1.987,1949,3.9,1982,2.505,1987,3.196,2016,2.984,2032,1.7,2033,2.299,2060,1.72,2121,2.084,2145,1.92,2177,2.023,2263,1.564,2301,2.456,2350,2.107,2363,2.207,2383,2.456,2434,2.505,2452,1.905,2493,5.591,2545,4.333,2546,2.771,2553,2.412,2581,1.763,2597,2.869,2598,2.771,2790,3.378,2853,1.741,2942,2.69,2976,2.559,3032,2.063,3306,2.334,3318,2.063,3556,2.456,3595,2.154,3657,2.266,3675,2.456,4319,2.771,4600,1.731,6453,2.869,8012,2.869,8037,2.456,8062,2.456,8063,2.869,9747,2.992,9893,3.405,9894,3.405,9895,2.992,9896,3.156,9897,3.405,9898,3.156,9899,3.156]],["t/3162",[5,2.338,10,3.079,21,3.136,74,5.355,94,2.854,96,3.332,117,1.196,168,2.823,172,2.526,196,2.531,263,2.631,391,2.415,400,6.422,491,3.622,538,2.685,544,4.251,607,3.499,822,5.294,867,2.612,1008,3.508,1024,4.942,1089,6.486,1178,6.361,1187,4.066,1238,5.995,1349,4.774,1477,4.383,1609,4.302,1816,3.683,2181,5.633,3236,5.355,7956,6.889]],["t/3164",[285,5.191,2557,7.965]],["t/3167",[5,1.944,22,3.453,30,1.318,43,2.241,86,3.196,90,2.365,93,3.001,96,3.573,137,2.629,138,2.801,139,1.894,216,3.357,267,1.578,287,1.743,339,4.11,412,2.197,414,1.747,461,4.67,481,3.943,488,2.172,514,3.235,527,4.152,557,2.38,611,2.701,614,3.254,768,3.663,809,2.955,834,3.387,868,3.162,912,3.031,953,4.944,978,2.033,997,4.568,1008,2.67,1055,2.427,1067,4.414,1090,3.198,1114,5.296,1142,4.287,1177,2.137,1482,5.659,1562,5.659,1584,4.229,1586,3.235,1607,2.563,1819,3.472,1829,2.649,1842,4.738,1914,4.532,1924,2.779,1988,2.358,2143,7.704,2186,3.865,2198,4.229,2256,6.246,2674,3.424,3071,3.448,3469,4.562,3611,3.758,4593,6.503,5419,4.738,7516,4.485,9086,5.242,9880,5.242,9881,8.412]],["t/3169",[5,2.403,7,2.254,11,3.048,22,3.362,86,2.687,93,4.117,117,0.969,128,4.058,139,2.599,208,2.605,219,3.703,259,1.667,296,2.966,488,2.98,514,4.438,527,4.314,529,3.092,631,5.41,636,4.547,768,5.025,786,4.731,822,3.542,978,2.789,997,3.148,1177,2.932,1208,4.039,1273,3.455,1332,4.314,1793,6.982,2062,3.862,3028,5.41,3035,7.193,7516,6.154,9882,8.191]],["t/3171",[5,2.59,44,1.772,86,3.677,208,2.939,481,6.103,486,4.473,868,5.936,997,4.307,1157,8.114,1431,5.662,1842,7.334,2018,4.949,2143,6.73,2198,6.546,2256,5.924,4593,6.168,9136,7.875]],["t/3173",[21,3.06,86,3.239,139,3.132,235,5.116,527,4.185,652,5.037,768,6.057,997,4.481,1066,5.258,1599,4.398,1801,5.587]],["t/3175",[5,2.034,30,1.943,84,4.769,86,2.888,148,2.422,208,3.755,296,2.51,330,4.982,607,2.603,617,5.014,620,4.361,659,4.896,660,4.063,881,5.698,912,4.469,1025,4.741,1204,3.877,1607,3.778,1812,4.856,1874,5.541,1909,6.08,8543,8.344,9220,6.726,9900,9.496]],["t/3178",[5,1.719,7,2.048,76,3.897,115,2.769,165,4.55,172,1.857,179,6.209,196,2.4,214,2.801,296,3.305,402,3.117,411,1.857,421,4.696,422,6.318,423,6.642,482,4.358,508,4.643,510,2.344,527,2.67,531,3.985,612,2.344,654,3.253,660,3.435,775,2.35,816,4.808,817,4.297,985,3.53,1090,3.985,1480,4.492,1609,4.08,1829,3.302,1924,4.55,2304,3.585,2450,5.59,2484,4.726,2519,5.139,2703,5.271,7944,5.686]],["t/3180",[10,3.156,21,2.492,117,0.951,122,4.989,196,3.315,297,2.551,391,2.475,411,2.007,419,3.964,421,3.257,422,4.382,423,4.892,525,4.306,526,3.236,553,4.611,627,3.774,629,4.306,816,4.989,923,2.278,1015,4.281,1030,5.778,1276,5.944,1715,3.514,1727,3.937,1778,4.081,1924,3.742,2134,5.773,2171,3.696,2185,6.04,4261,7.068,4262,7.131,4285,5.773]],["t/3182",[5,1.905,10,2.838,28,3.125,30,0.804,76,3.787,115,1.356,117,0.975,123,1.21,165,3.838,167,2.235,172,0.909,188,3.143,194,1.485,196,1.175,210,1.3,229,1.34,240,0.892,241,2.119,259,0.741,267,1.533,287,1.063,296,2.351,339,1.779,419,3.565,421,2.929,422,3.941,423,2.217,452,1.763,473,1.156,482,5.618,489,1.311,511,2.847,526,1.466,527,2.959,531,1.951,538,1.986,544,1.974,557,1.452,573,2.254,576,2.022,599,2.516,607,2.138,610,1.951,611,2.625,623,2.358,654,3.604,668,1.466,744,4.147,752,5.237,753,2.594,775,1.832,787,1.648,816,3.184,820,1.404,822,4.515,867,1.213,875,3.334,908,2.313,980,1.71,985,3.706,987,2.236,991,1.725,998,2.288,1036,4.266,1089,2.336,1125,2.96,1180,2.165,1200,2.089,1267,3.72,1273,1.536,1431,1.84,1480,3.502,1596,2.313,1607,1.564,1609,1.997,1611,5.862,1615,4.065,1640,1.755,1668,2.737,1715,1.592,1722,1.813,1791,1.962,1830,2.119,1833,2.954,1838,2.293,1914,3.125,2078,4.704,2123,2.336,2304,2.796,2484,7.154,2518,2.235,2775,6.3,2776,9.208,2777,5.5,2853,3.201,3128,2.835,3297,3.105,4320,4.29,4629,3.199,4680,6.002,5891,3.453,6907,3.199,7905,4.704,9166,3.024,9901,3.93,9902,3.312,9903,3.93,9904,6.259,9905,3.93,9906,3.93,9907,3.93,9908,3.93]],["t/3184",[2,1.39,5,1.745,18,2.282,40,1.773,41,1.524,76,4.689,95,1.278,97,1.043,115,1.166,117,1.167,138,1.043,165,3.038,168,1.128,172,0.782,194,1.278,211,1.249,226,1.575,259,0.637,267,1.357,296,2.376,330,2.352,339,1.531,398,2.041,402,1.312,412,1.89,419,1.545,421,4.454,422,5.87,423,5.07,443,1.418,452,1.517,454,2.139,457,1.517,466,2.22,473,1.63,486,1.517,489,1.128,502,1.938,506,2.987,526,1.261,527,2.71,531,1.678,536,2.282,538,1.072,554,2.354,567,2.848,571,1.669,574,2.069,594,2.069,606,3.263,607,2.465,612,2.057,619,1.538,621,0.987,623,2.028,636,2.851,646,2.751,654,2.853,752,1.99,756,1.599,759,2.545,775,1.622,787,2.324,816,4.346,820,1.208,822,1.355,834,1.261,873,1.75,882,1.708,978,1.067,980,2.411,985,3.674,987,3.643,998,2.992,1017,2.114,1036,3.031,1151,3.177,1180,1.863,1187,1.624,1211,1.423,1233,2.282,1267,2.009,1273,1.321,1286,2.926,1308,1.708,1312,2.114,1387,2.438,1388,2.848,1421,2.705,1480,3.101,1521,1.922,1599,1.396,1609,2.816,1611,2.541,1612,1.729,1617,3.293,1668,6.26,1678,1.698,1715,3.3,1727,1.968,1791,2.767,1829,1.39,1830,1.822,1868,2.354,1870,2.67,1989,3.205,2032,3.516,2144,1.835,2161,2.394,2304,4.314,2469,2.25,2484,5.293,2545,2.069,2573,2.317,2625,2.354,2775,7.541,2776,7.807,2777,2.97,2853,2.834,2934,1.938,3036,3.392,3236,4.455,3237,2.97,3294,2.438,3426,2.541,3502,3.263,3536,2.751,3646,5.769,3805,2.487,4318,2.487,4320,2.317,4680,2.601,7905,2.541,7908,2.751,8117,2.541,8397,2.67,8592,2.394,9166,2.601,9229,2.751,9909,3.38,9910,3.38,9911,3.38,9912,3.38]],["t/3186",[1,1.378,5,2.447,7,2.104,10,3.001,76,5.794,85,1.594,94,1.901,137,2.301,165,4.631,221,2.694,229,1.923,239,2.666,287,2.232,296,2.578,398,3.039,419,2.577,421,3.663,422,4.928,423,4.652,488,1.901,510,1.646,526,2.103,538,1.789,549,3.806,557,2.083,568,2.752,607,3.132,611,2.364,612,1.646,621,1.646,627,2.453,636,2.901,639,2.919,654,4.35,665,3.451,745,3.416,752,4.857,772,4.454,804,4.751,816,3.367,867,1.74,985,3.424,987,3.485,998,1.654,1014,2.653,1070,2.831,1074,3.609,1125,2.666,1231,2.737,1286,2.977,1519,3.18,1577,3.416,1599,2.328,1611,6.2,1614,3.527,1668,5.744,1807,2.723,1829,3.393,2032,4.119,2130,5.416,2161,5.843,2230,2.518,2304,4.794,2469,3.752,2775,5.843,2776,5.843,2853,2.883,2971,3.806,3502,3.319,3646,5.843,3762,4.237,4319,4.589,4680,6.347,6021,4.953,7944,3.993,8189,4.237,9913,5.637,9914,5.637,9915,5.637]],["t/3188",[1,2.369,2,3.987,21,2.785,123,2.984,259,1.828,339,4.389,412,3.306,486,4.349,527,3.954,834,3.617,998,3.488,1388,8.168,1612,4.957,2775,6.866,2776,8.42,2790,7.203,2853,6.079,3036,5.934,3536,7.889,4327,6.75,7905,7.285]],["t/3191",[5,1.7,7,2.67,76,3.853,153,4.476,165,4.516,172,1.836,179,6.162,214,2.769,296,3.291,402,3.081,411,2.422,419,4.783,421,4.676,422,5.916,423,5.903,482,4.309,488,2.677,508,4.59,510,2.318,527,2.64,531,3.94,612,2.318,654,3.216,660,3.396,775,2.323,816,3.24,985,3.879,1017,4.964,1090,3.94,1480,4.441,1609,4.034,1829,4.305,1924,3.424,2304,3.545,2450,5.527,2484,4.673,2703,5.211,7944,5.621,9794,6.46]],["t/3193",[10,3.215,21,2.539,117,0.969,122,5.033,196,3.355,297,2.599,391,2.522,411,2.045,419,4.039,421,3.319,422,4.465,423,4.984,525,4.387,526,3.297,627,3.845,629,4.387,816,5.033,923,2.321,1015,4.362,1030,5.847,1276,6.057,1715,3.581,1727,3.985,2134,5.882,2171,3.766,2185,6.154,4261,7.13,4262,7.194,4285,5.882]],["t/3195",[5,1.653,7,2.621,12,3.712,76,3.747,90,2.834,123,2.376,126,3.017,165,3.33,196,2.308,296,3.255,421,2.898,422,3.899,463,2.632,511,3.511,527,2.567,538,2.449,610,3.831,646,3.831,654,3.127,802,2.67,866,3.432,998,2.264,1013,3.65,1151,4.426,1177,2.56,1286,4.075,1487,6.66,1521,4.389,1599,3.187,1609,3.923,1611,5.801,1617,6.106,1678,3.876,1715,4.163,1829,3.175,2032,6.148,2144,4.19,2230,3.447,2304,3.447,2317,5.801,2459,6.781,2570,4.131,2625,5.374,2853,3.947,3502,4.544,4320,5.289,4680,5.939,8080,7.153,9776,7.153,9916,6.781,9917,7.718]],["t/3197",[5,2.089,10,3.549,21,2.803,76,2.737,95,2.131,115,1.944,117,0.618,136,3.684,168,1.881,172,1.304,179,3.319,240,1.28,259,1.063,267,1.381,287,1.525,296,2.18,398,2.077,457,2.529,463,2.813,466,3.702,492,2.227,501,3.451,511,2.565,527,2.744,530,2.474,574,3.451,579,2.083,598,2.614,606,3.319,612,1.646,629,2.799,665,3.451,668,3.078,802,2.853,813,3.926,816,3.982,862,3.609,881,3.383,882,2.848,903,3.567,910,3.383,914,2.443,923,1.481,972,4.953,978,1.779,985,1.69,998,2.42,1008,2.337,1017,5.16,1030,2.938,1036,3.083,1195,4.857,1228,4.751,1248,4.69,1266,3.488,1276,3.864,1286,2.977,1308,4.167,1521,3.206,1599,2.328,1607,3.282,1609,4.192,1611,4.237,1614,3.527,1617,3.35,1668,5.744,1716,4.953,1778,2.653,1791,2.815,1792,3.527,1807,3.983,1838,4.813,1870,4.454,1924,2.432,2032,4.87,2144,3.061,2171,2.403,2304,2.518,2608,3.654,2775,3.993,2776,3.993,2853,2.883,2879,3.993,3502,6.725,3554,4.589,3646,3.993,4282,3.993,4680,4.338,4725,5.225,5839,4.953,6829,4.589,7944,3.993,8052,5.225,9099,4.454,9918,5.637,9919,5.637,9920,5.637,9921,5.637,9922,5.637,9923,5.637]],["t/3199",[5,2.712,7,1.571,48,2.391,76,5.43,94,3.772,117,0.675,123,1.896,165,3.793,259,1.161,287,3.026,296,1.627,398,2.268,402,2.391,418,3.093,419,2.814,421,3.302,422,4.442,423,6.308,457,2.763,473,1.811,510,1.798,527,3.411,564,3.593,576,1.989,579,4.133,607,1.688,612,1.798,621,1.798,654,3.563,741,4.739,752,3.626,775,1.802,816,2.514,820,2.2,879,3.561,923,1.617,953,2.668,955,2.603,985,3.686,998,1.807,1025,3.075,1146,3.23,1195,3.626,1308,3.111,1609,3.13,1611,6.608,1646,4.865,1668,4.288,1715,2.495,1772,3.149,1924,2.657,1925,4.53,2032,5.584,2123,5.225,2304,4.58,2775,4.362,2776,4.362,3502,7.242,3676,5.411,3677,5.707,4680,6.766,8114,4.362,9924,6.158,9925,6.158]],["t/3201",[5,1.905,7,2.268,47,3.196,76,5.47,137,3.631,148,2.268,172,2.058,229,3.033,330,3.775,422,4.493,557,3.287,659,4.33,731,5.336,737,4.046,752,6.633,867,2.745,882,4.493,985,3.896,998,3.305,1098,4.794,1099,5.919,1904,4.493,1909,5.694,2230,3.972,2234,7.845,6829,7.239,8205,8.243,9220,6.299,9926,8.893,9927,8.893,9928,8.893]],["t/3204",[2,4.438,5,1.781,25,4.277,117,0.911,123,2.559,137,3.394,168,2.773,208,3.872,240,1.887,267,2.036,296,2.851,398,3.062,452,3.73,471,6.352,487,3.308,510,2.428,513,4.58,587,6.248,597,3.206,598,3.854,600,4.895,666,3.433,735,4.419,1019,3.854,1218,4.361,1579,5.388,1614,6.749,1734,4.081,1768,6.567,1792,5.2,1816,3.617,1913,6.766,1924,3.587,2062,3.633,2105,6.567,2124,7.705,2137,5.888,2205,7.705,3268,7.005,7931,5.789,9069,7.705,9929,7.705]],["t/3206",[2,2.903,5,2.751,23,4.764,41,3.181,123,2.172,165,3.045,168,2.354,178,3.408,208,4.005,248,5.251,267,1.728,271,2.6,296,1.865,411,1.633,461,3.631,462,4.047,487,3.848,510,2.824,535,3.98,538,2.239,563,5.091,575,2.892,635,5.304,646,3.503,666,2.914,735,3.752,775,2.066,914,3.058,987,2.521,1019,3.272,1035,4.082,1055,2.659,1097,3.963,1110,4.465,1196,4.914,1208,3.225,1234,4.465,1286,3.726,1336,5.947,1366,6.541,1579,4.574,1614,4.414,1766,4.837,1947,4.837,2118,3.888,2182,4.047,2204,5.091,2211,5.744,2239,4.366,2461,6.201,2514,5.431,2571,4.764,2900,4.518,3503,4.999,3584,6.201,4282,4.999,8429,5.947,9091,6.201,9599,6.541,9883,6.541,9930,7.057,9931,7.057,9932,7.057]],["t/3208",[2,2.069,5,2.174,22,1.914,28,2.512,43,1.75,103,3.261,117,0.551,123,1.549,150,2.093,163,2.391,168,2.528,187,2.455,208,3.983,209,3.083,210,2.508,218,1.755,224,2.442,241,2.712,245,1.974,255,5.526,258,1.92,271,3.36,296,1.33,462,2.885,463,1.716,473,1.479,483,1.914,511,2.288,535,4.275,538,1.596,545,3.348,550,3.303,575,3.106,597,1.94,599,4.853,607,2.078,610,2.497,629,3.763,635,3.781,646,2.497,663,3.284,666,2.077,756,2.379,775,2.219,786,2.693,792,3.396,809,2.468,820,2.708,867,1.552,875,1.621,980,2.189,1008,2.085,1019,2.332,1035,2.909,1069,2.588,1097,4.16,1125,2.379,1132,3.396,1177,2.515,1205,2.288,1208,2.299,1215,3.871,1234,3.183,1273,2.963,1278,2.656,1327,2.815,1439,3.048,1657,3.974,1749,2.909,1766,5.195,1768,7.205,1792,3.147,1816,5.633,1947,3.448,2118,4.176,2121,3.08,2125,4.239,2177,2.99,2186,4.548,2204,3.629,2514,5.832,2571,3.396,3072,5.467,3259,3.147,3268,4.239,3428,3.563,3657,5.045,3689,4.662,3797,2.935,4169,2.772,4282,5.369,7516,3.503,7765,3.974,7932,3.781,8507,4.239,8509,4.094,9075,4.662,9711,4.662,9933,5.03,9934,5.03,9935,4.42,9936,5.03]],["t/3210",[2,2.686,5,1.963,12,2.099,15,4.603,16,3.654,22,2.485,24,3.206,29,3.654,44,1.161,115,2.253,117,0.716,123,3.26,165,2.818,187,2.115,208,3.874,209,2.656,245,2.562,255,3.958,271,3.377,296,1.726,471,3.845,511,2.971,546,3.811,597,2.518,607,2.513,629,3.242,646,3.242,663,2.83,666,4.373,775,1.912,809,3.448,816,2.666,822,2.617,875,3.412,888,3.626,923,1.715,1008,2.707,1097,3.756,1125,3.089,1215,5.026,1273,3.583,1327,3.654,1418,2.646,1422,4.805,1443,4.459,1749,3.777,1766,4.476,1816,5.718,1923,3.811,2118,5.05,2145,3.684,2514,7.053,2723,3.36,2853,3.34,3072,4.711,3206,5.159,4276,5.026,4282,4.626,7516,4.548,7765,7.241,8395,5.026,8509,5.316,9937,5.738]],["t/3212",[2,4.221,5,2.198,25,5.28,96,4.04,117,1.349,123,3.159,208,3.025,296,2.712,487,4.083,571,6.074,666,4.237,787,5.16,1283,5.741,4313,7.145,4314,7.268]],["t/3214",[5,1.802,24,4.13,123,3.347,208,3.754,248,5.903,271,3.099,411,1.947,461,4.329,538,2.669,607,2.981,610,4.176,629,4.176,635,6.323,775,2.463,861,5.048,978,2.655,1008,4.507,1177,2.791,1182,5.766,1281,4.601,1283,6.084,1286,4.442,1396,4.784,1579,5.453,1766,5.766,1832,5.524,1947,5.766,2118,4.635,2514,6.474,2518,4.784,2900,5.386,4313,5.858,4314,5.959,6842,7.797,8509,6.847,9772,7.797,9794,6.847,9877,7.797,9937,7.392,9938,6.847]],["t/3216",[5,1.942,35,5.494,123,2.791,208,3.677,271,3.34,535,5.113,560,3.962,610,4.501,663,3.928,766,5.804,809,3.713,861,5.44,909,5.609,1019,4.203,1035,5.243,1097,3.715,1157,7.379,1362,5.876,1734,4.45,1766,6.213,1947,6.213,1982,6.67,2003,6.121,2118,4.995,2518,5.155,2803,7.162,2991,6.814,3041,6.67,4282,6.422,4313,6.313,4314,6.422,9938,7.379,9939,9.066]],["t/3218",[5,1.896,12,2.844,30,1.811,41,2.159,74,3.03,115,3.415,117,0.525,122,2.981,123,3.798,148,1.222,170,2.582,196,2.96,208,2.918,210,1.585,240,1.087,241,2.582,258,1.828,262,3.402,391,1.367,401,3.712,411,1.69,414,1.98,463,1.633,471,2.82,473,2.603,483,1.822,499,3.067,504,2.62,535,2.702,552,2.378,557,1.77,563,3.455,571,4.369,582,2.639,597,2.816,598,2.221,600,2.82,607,2.002,610,5.291,612,1.399,627,3.178,636,2.465,666,4.088,737,2.179,748,1.835,764,2.033,816,2.981,822,1.92,861,5.94,895,2.62,914,2.075,969,2.392,985,1.436,1019,2.221,1062,2.169,1091,5.54,1110,4.62,1135,4.62,1170,2.041,1182,3.283,1233,3.234,1239,2.77,1277,2.529,1283,2.68,1286,2.529,1577,4.425,1579,3.105,1599,1.978,1609,2.434,1643,4.861,1727,1.701,1734,5.232,1768,3.784,1815,3.455,1816,2.084,1828,3.455,1895,3.283,2032,2.392,2121,2.932,2137,3.393,2177,2.846,2518,6.387,2522,3.393,2723,2.465,2840,3.686,2872,4.568,2913,5.372,2928,3.188,3041,3.524,3594,3.784,7899,4.209,7913,3.686,8252,3.899,8254,3.899,9051,4.036,9054,3.899,9938,7.204,9940,7.303,9941,4.439,9942,4.79,9943,4.79,9944,4.79,9945,4.439,9946,4.439,9947,4.439,9948,4.036,9949,4.79]],["t/3220",[5,1.76,12,2.64,30,1.681,115,2.834,122,3.354,123,3.296,196,3.561,210,2.718,262,4.988,267,2.012,391,2.345,411,1.901,473,3.503,552,4.079,557,3.957,610,4.079,816,3.354,822,3.293,861,4.929,875,2.647,895,4.493,980,3.575,1055,3.095,1277,4.338,1278,4.338,1283,4.597,1286,4.338,1577,4.978,1734,4.033,1768,6.49,1816,4.658,1895,5.631,2518,4.672,2872,5.139,3041,6.044,3074,7.614,4313,5.721,4314,5.819,7949,6.687,8254,6.687,8507,6.923,9051,6.923,9054,6.687,9948,6.923]],["t/3222",[2,2.932,5,1.527,29,3.989,117,0.781,122,3.976,123,3.415,136,3.184,172,1.65,208,2.871,210,2.359,296,1.884,316,4.564,454,4.51,471,6.531,473,2.097,483,2.712,499,4.564,513,3.928,538,2.262,552,3.539,557,4.099,571,4.807,597,3.756,600,5.734,607,1.954,610,3.539,621,2.082,665,4.364,731,4.277,812,4.411,816,3.976,861,5.843,895,3.899,908,2.635,998,2.092,1019,3.305,1125,3.372,1133,5.245,1182,4.886,1283,6.207,1349,4.021,1577,4.32,1589,4.459,1620,6.007,1734,4.781,1750,4.123,1773,3.843,1816,3.102,1830,3.843,2003,4.813,2121,4.364,2138,4.964,2518,5.538,2872,4.459,3005,4.964,8154,6.607,8252,5.802,8254,5.802,9742,6.607,9938,5.802,9948,6.007]],["t/3224",[2,3.551,5,1.517,12,2.276,23,3.106,48,1.786,95,1.739,103,2.982,115,2.978,117,0.504,122,2.891,123,3.66,197,2.144,208,3.504,210,1.522,240,1.044,262,3.299,267,2.114,296,2.282,316,2.946,398,1.695,462,2.638,463,2.415,471,2.709,473,2.539,487,2.818,499,2.946,502,2.638,511,2.093,538,1.46,552,2.284,553,2.446,557,2.617,570,3.062,571,4.786,587,3.458,597,2.731,598,2.133,599,2.946,600,4.169,607,1.941,610,3.516,617,2.43,629,2.284,634,2.709,635,3.458,636,2.367,665,2.817,666,3.564,731,2.761,735,3.765,764,1.953,766,2.946,792,3.106,816,2.891,820,1.644,822,1.844,861,5.18,882,2.324,914,1.994,1019,3.283,1037,2.788,1089,2.734,1097,1.885,1125,2.176,1135,2.911,1177,1.526,1182,3.153,1185,2.661,1215,3.541,1271,2.413,1273,2.768,1283,4.83,1308,2.324,1418,2.869,1577,2.788,1578,3.541,1579,2.982,1589,5.4,1643,3.062,1734,3.476,1750,2.661,1830,2.48,1895,3.153,1913,5.764,1953,2.878,2121,4.335,2137,3.259,2145,2.595,2177,2.734,2202,4.043,2206,3.385,2304,2.055,2496,3.021,2518,4.909,2723,2.367,2870,4.264,2926,3.541,3041,3.385,3076,3.204,3098,2.761,4282,3.259,7130,3.635,7765,3.635,7905,3.458,8041,4.264,8252,5.764,8254,5.764,8397,5.594,8509,5.764,8577,3.877,9051,3.877,9054,3.745,9645,3.635,9794,3.745,9937,4.043,9938,5.764,9945,4.264,9946,4.264,9947,4.264,9948,5.967,9950,4.601,9951,4.601,9952,4.601,9953,4.601]],["t/3227",[5,1.7,48,3.081,117,0.87,178,3.833,219,2.619,267,2.563,296,2.766,391,2.265,470,2.431,488,4.199,511,3.61,526,2.961,527,3.896,538,3.321,578,4.373,586,3.561,595,5.282,636,4.084,654,3.216,766,5.081,781,2.648,822,4.195,866,3.529,867,3.23,989,4.551,1151,4.551,1238,5.621,1266,4.91,1274,6.107,1286,5.527,1386,4.859,1577,4.809,1682,6.973,1714,5.144,1715,3.216,1750,6.053,1988,2.905,2152,4.406,2508,5.439,3465,5.725,7901,8.268,8377,6.688,9142,5.621,9954,7.936]],["t/3229",[213,4.595,488,3.592,495,5.276,624,5.318,627,4.634,1030,5.551,1281,5.825,1540,9.871,1715,4.316,1942,6.16,2254,6.16,9955,8.975]],["t/3231",[117,0.957,206,4.773,229,2.976,296,2.942,297,2.567,466,5.73,488,4.134,511,3.97,521,3.765,527,3.703,622,4.608,624,4.358,654,3.536,781,2.816,887,5.4,980,3.797,987,4.612,1015,4.308,1017,5.459,1062,3.952,1204,3.563,1278,4.608,1283,4.883,1521,6.33,1926,5.959,2440,3.765,2453,5.004,2484,5.138,2508,5.981,3345,5.343,5367,8.089,6829,7.103]],["t/3234",[4,2.807,5,2.617,7,1.714,30,1.375,97,2.073,117,1.025,148,2.385,172,1.555,250,2.693,267,2.634,296,3.072,297,2.749,330,2.852,411,1.555,421,4.365,473,1.976,488,2.266,489,2.241,495,5.443,527,3.11,538,2.132,654,3.788,753,2.785,761,4.759,820,3.34,831,3.28,895,3.675,923,1.764,1009,3.33,1071,3.501,1120,3.648,1261,6.407,1281,7.098,1530,3.92,1609,3.415,1618,2.683,1773,3.622,1942,7.067,2184,5.662,2254,3.886,2301,4.847,2304,3.001,2396,3.956,2440,2.899,2468,3.596,2484,3.956,2751,3.956,9955,10.297,9956,6.719,9957,6.227]],["t/3236",[4,1.522,5,1.588,7,2.172,28,1.819,30,0.746,38,2.163,41,1.642,47,1.31,48,1.415,73,1.753,85,1.031,115,1.257,166,4.696,168,1.965,172,1.716,177,3.892,178,1.76,187,2.758,201,1.875,210,2.453,213,3.674,235,1.75,240,1.933,243,1.923,248,1.978,263,1.133,267,0.892,296,1.96,297,3.563,391,1.04,411,1.363,421,2.212,452,1.635,457,1.635,482,1.978,483,1.386,488,2.872,495,2.47,511,1.658,527,2.833,538,1.156,555,1.322,557,1.347,571,2.908,575,1.493,598,1.689,622,5.786,624,5.652,626,3.262,646,1.809,654,3.004,660,2.521,668,1.36,678,1.951,731,2.186,744,1.937,781,0.922,820,2.104,831,1.779,867,1.125,870,2.186,871,2.023,875,1.898,888,2.023,914,1.579,923,0.957,955,2.49,973,2.497,978,1.15,980,1.586,985,1.092,987,1.302,991,1.599,998,1.728,1003,1.899,1009,2.641,1011,4.438,1015,1.799,1017,2.279,1021,2.107,1045,2.362,1053,2.966,1090,2.924,1091,2.039,1097,1.493,1125,2.786,1127,3.727,1151,2.089,1204,1.488,1209,2.739,1213,2.039,1218,1.911,1238,2.581,1457,2.107,1599,2.432,1617,2.166,1640,1.628,1712,1.978,1751,2.089,1790,1.658,1829,2.423,1835,2.804,1854,2.879,1909,2.333,1912,2.739,1943,2.126,1949,2.008,2055,2.46,2072,2.126,2075,2.958,2152,2.023,2181,2.425,2187,2.538,2254,3.407,2260,3.787,2364,5.46,2508,2.497,2570,3.153,2897,4.037,2918,7.085,3036,2.231,3905,2.305,8353,6.872,9142,4.172,9412,3.202,9941,3.377,9958,3.377,9959,3.644,9960,3.644,9961,3.644,9962,3.644,9963,3.644,9964,8.71,9965,3.644,9966,3.644,9967,5.46,9968,3.644,9969,3.644,9970,3.644,9971,3.644,9972,3.644,9973,3.644,9974,3.644,9975,3.644,9976,3.644,9977,3.644,9978,3.377,9979,3.644,9980,3.644,9981,3.644,9982,3.644,9983,3.644,9984,3.644]],["t/3238",[5,2.521,7,2.433,12,2.223,95,2.615,117,0.758,165,2.985,166,4.791,187,2.241,218,2.414,235,4.583,243,1.794,267,1.694,287,1.872,296,2.521,297,2.034,351,3.729,421,3.582,488,3.97,495,4.001,526,2.581,527,3.174,536,4.67,576,2.235,607,1.897,622,6.216,624,5.877,654,4.425,768,3.934,781,1.75,820,3.408,908,3.526,978,2.184,980,3.01,1011,4.972,1092,4.99,1204,2.824,1239,5.518,1278,3.653,1374,4.484,1615,3.605,1714,4.484,1751,5.47,1942,4.001,2075,3.474,2254,6.316,2440,2.985,3031,6.412,3297,5.465,3905,4.377,5839,6.078,8189,5.199,8986,4.741,9902,5.829,9957,6.412,9958,6.412,9964,5.323]],["t/3240",[187,3.299,296,3.238,411,2.357,421,3.825,488,4.431,527,4.075,622,6.469,624,5.086,1361,7.656,1558,9.441,2254,5.891,9964,7.839,9985,10.186,9986,10.186]],["t/3242",[22,4.315,208,3.343,881,6.804,1200,6.029,1812,5.799]],["t/3245",[1,1.335,5,1.17,7,2.876,17,2.407,25,2.81,40,2.865,72,1.788,97,1.686,117,1.159,137,2.23,138,1.686,183,2.884,186,2.213,187,3.102,193,2.012,210,1.807,224,2.652,228,4.44,229,2.748,240,2.4,248,5.74,259,2.488,265,2.965,267,1.338,304,3.056,398,2.012,411,1.264,419,3.683,427,2.696,461,2.81,474,2.012,483,3.066,496,2.965,526,4.207,528,5.079,544,2.743,547,3.497,557,3.539,560,2.387,586,2.451,622,2.884,623,3.277,624,2.727,626,2.092,627,2.376,646,5.248,666,2.255,809,1.778,816,2.23,862,3.497,867,1.686,886,3.032,991,2.397,993,2.106,1014,2.57,1031,3.187,1049,3.132,1072,2.759,1140,3.081,1147,4.018,1162,3.159,1175,5.292,1187,2.624,1211,2.3,1213,3.056,1218,2.865,1302,3.246,1312,3.417,1414,5.062,1451,4.446,1452,4.446,1519,3.081,1809,4.018,1816,2.376,1829,2.247,1912,4.105,1919,3.344,1924,2.357,1954,2.828,2003,3.687,2145,3.081,2490,3.246,2561,6.559,3080,4.602,3108,4.446,3236,3.456,4622,4.446,7931,3.803,9165,4.446,9987,5.062,9988,5.462,9989,5.462,9990,5.462,9991,5.062,9992,5.062]],["t/3247",[2,2.918,5,2.37,7,1.809,11,2.446,21,2.038,41,3.197,117,1.064,164,2.896,165,3.06,168,3.237,201,4.994,240,2.7,245,2.783,248,3.851,259,2.243,267,1.737,452,3.182,462,4.067,487,2.822,521,3.06,524,5.663,525,3.521,528,4.662,606,4.176,607,1.945,612,2.071,622,3.745,624,3.541,627,4.223,630,3.879,631,4.342,646,3.521,735,3.771,775,2.841,1011,3.696,1013,3.355,1089,4.215,1140,4.001,1169,4.102,1175,4.657,1218,3.721,1266,4.388,1546,4.541,1807,3.425,1816,3.086,1912,5.331,1916,4.657,1919,6.773,1921,5.565,1927,5.773,1931,7.468,1935,4.789,1936,5.458,1954,3.673,2573,4.861,3080,5.977,4472,4.721,9022,7.899,9991,6.574]],["t/3249",[7,1.628,11,2.201,21,1.834,73,1.899,90,2.344,103,4.137,117,0.7,123,1.965,168,3.008,187,2.067,211,2.359,227,3.829,229,3.876,240,2.722,241,3.44,259,1.204,267,2.209,298,3.949,330,2.709,351,5.638,391,1.821,397,3.724,402,2.478,411,1.477,422,3.224,487,2.539,489,2.129,504,4.932,510,2.634,521,2.754,525,3.168,526,3.365,527,2.123,528,3.066,576,2.062,593,4.248,607,1.75,612,2.634,626,2.445,636,3.284,649,2.801,668,3.365,735,3.393,775,1.868,781,2.281,802,2.208,822,2.558,895,3.49,969,3.187,1028,3.099,1120,3.465,1177,2.117,1208,2.917,1211,2.687,1302,3.793,1311,4.797,1519,3.6,1547,3.348,1589,3.992,1792,3.992,1805,4.374,1808,4.604,1816,2.777,1819,3.44,1829,2.625,1918,3.305,1919,6.402,1954,3.305,1966,3.224,1967,3.187,2010,3.992,2121,3.907,2123,5.359,2215,6.088,2442,5.608,3236,4.038,3676,5.608,4266,4.248,4277,5.608,9993,6.382]],["t/3251",[1,0.474,3,1.422,4,2.692,5,1.38,7,2.215,8,1.273,11,1.941,12,0.623,14,3.426,16,1.085,17,1.518,19,1.783,21,0.557,22,1.31,24,0.952,25,0.998,27,2.243,30,0.705,36,1.884,38,0.712,41,0.874,44,0.345,73,0.577,76,0.942,83,1.409,84,0.974,86,1.047,93,1.605,94,0.654,113,1.132,115,1.188,117,1.176,118,0.724,126,1.816,138,0.599,139,2.773,140,1.399,165,2.004,166,2.333,168,1.149,169,0.882,172,1.302,177,3.26,178,2.243,181,0.859,187,0.628,193,0.714,201,3.316,203,0.855,209,2.288,211,2.079,213,1.486,219,1.533,226,0.904,229,1.919,240,2.061,243,0.893,245,1.822,248,1.053,259,1.345,263,1.071,265,3.055,267,0.844,287,0.932,296,0.513,297,2.422,304,1.927,316,1.242,320,1.844,351,1.045,391,0.553,411,1.651,418,0.974,427,0.957,438,0.932,443,1.444,445,1.053,452,2.084,457,0.87,461,3.316,463,0.661,469,1.958,470,1.055,473,0.57,490,0.798,510,1.357,521,0.837,525,0.963,526,3.518,527,1.545,528,3.957,530,1.511,532,1.2,538,1.093,557,1.717,558,1.458,560,0.847,571,0.957,573,1.975,574,2.844,576,1.113,579,0.717,582,1.069,586,0.87,598,0.899,604,1.164,606,1.142,610,1.71,612,0.566,622,1.024,624,2.319,626,1.319,629,1.71,631,1.187,645,0.804,646,2.793,647,1.132,649,0.851,655,1.273,660,0.83,663,0.84,666,0.801,668,1.285,687,1.273,732,0.611,739,1.175,748,0.743,759,0.891,778,1.458,781,1.954,792,1.309,802,0.671,809,3.264,813,1.351,816,0.792,822,1.38,866,1.531,867,0.599,875,1.11,890,0.899,891,0.947,906,1.72,908,0.717,912,0.913,923,0.509,969,0.968,978,0.612,980,0.844,987,0.693,989,2.664,998,0.569,1003,2.421,1014,0.913,1017,1.213,1028,0.942,1031,1.132,1035,1.122,1056,1.132,1066,0.957,1069,0.998,1097,0.795,1120,1.053,1127,1.227,1150,1.309,1168,1.213,1175,1.273,1177,1.867,1180,1.069,1181,1.75,1186,1.492,1191,1.273,1204,0.792,1205,0.882,1208,0.886,1218,1.017,1235,1.532,1252,3.011,1256,4.059,1266,1.2,1278,1.024,1279,1.112,1283,1.085,1327,3.605,1362,1.257,1418,3.338,1445,2.398,1475,1.257,1478,1.038,1480,1.085,1485,2.232,1489,1.807,1519,2.62,1618,1.375,1624,1.492,1643,1.291,1672,1.329,1696,1.634,1708,1.458,1711,1.094,1715,0.786,1718,1.458,1722,0.895,1753,1.71,1769,1.399,1805,1.329,1809,1.427,1816,0.844,1819,1.857,1895,1.329,1912,2.589,1916,1.273,1918,5.323,1919,5.965,1921,2.664,1924,0.837,1926,1.038,1927,2.803,1931,5.49,1934,1.898,1935,1.309,1936,1.492,1943,1.132,1945,1.579,1949,1.069,1950,4.648,1956,1.797,1958,1.053,1966,3.604,1967,1.72,1977,1.492,2024,1.257,2121,2.108,2145,1.094,2182,1.975,2191,1.187,2195,1.351,2220,2.439,2233,1.187,2339,1.797,2363,1.257,2380,0.904,2401,1.634,2469,3.092,2550,1.579,2561,1.579,2789,1.257,2872,2.154,2878,1.458,2989,1.492,3028,1.187,3071,1.038,3076,1.351,3154,1.351,3250,1.458,3501,1.374,3504,1.704,3556,1.399,3568,1.797,3607,1.242,3668,1.532,3690,2.65,3694,3.67,3797,1.132,4302,1.579,4400,1.458,5282,1.579,5420,3.026,5901,1.797,6043,1.458,7516,1.351,7977,1.492,7994,1.797,8012,1.634,8035,3.026,8070,7.675,8081,2.902,8220,1.634,8379,1.704,8465,1.704,9994,1.939,9995,1.939,9996,1.939,9997,1.939,9998,1.939,9999,1.939,10000,1.939,10001,1.939,10002,1.939,10003,1.939,10004,1.704,10005,1.939,10006,1.939,10007,1.939,10008,1.797,10009,1.797,10010,1.939,10011,1.939,10012,1.939,10013,3.444,10014,1.939,10015,1.939,10016,1.939]],["t/3253",[11,3.067,12,2.858,14,4.728,30,1.82,83,1.756,181,3.937,201,4.576,229,3.842,259,1.677,267,2.759,391,2.538,418,4.466,452,5.055,496,4.828,562,3.631,600,5.236,612,2.597,621,3.29,769,5.189,809,3.668,875,2.866,987,4.025,1249,4.665,1924,3.837,1932,7.814,1933,7.494,1934,4.9,2440,3.837,2922,7.239,3236,5.627,8070,7.239,8141,7.814,10017,8.893]],["t/3255",[2,2.686,11,3.96,14,5.63,21,1.877,51,3.28,83,1.29,117,1.161,203,2.879,211,4.243,227,3.919,229,3.126,259,1.997,265,4.976,299,4.409,304,3.654,391,1.864,443,2.739,452,2.93,489,2.178,495,2.739,496,3.546,510,3.353,511,2.971,521,2.818,560,2.854,564,3.811,612,1.907,621,2.677,624,3.261,626,2.502,646,3.242,668,2.437,781,1.652,809,2.127,923,1.715,976,4.132,998,1.916,1024,2.957,1066,3.224,1070,3.28,1099,4.347,1177,2.167,1185,3.777,1191,6.018,1208,4.189,1213,3.654,1281,3.572,1283,3.654,1328,6.053,1519,3.684,1701,4.476,1753,3.242,1830,3.521,1918,5.483,1919,6.483,1924,2.818,1935,4.409,1936,5.026,1943,3.811,1985,4.476,2039,5.738,2177,3.881,2192,3.654,2215,4.409,2254,3.777,2496,4.288,4285,4.347,8042,5.503,8220,5.503,10018,6.531,10019,6.531,10020,6.531]],["t/3257",[14,6.179,10021,11.622]],["t/3262",[36,4.685,74,5.42,123,2.637,216,4.465,221,4.094,259,1.616,287,2.318,296,3.389,398,3.156,510,2.502,511,3.897,527,3.659,538,2.718,610,4.253,646,4.253,654,3.471,655,5.625,822,3.434,866,3.809,912,4.031,1091,4.794,1097,3.511,1164,7.528,1286,4.524,1443,3.607,1521,6.255,2032,4.278,2121,5.245,2232,5.702,2508,5.872,2570,4.586,2934,4.913,3072,6.18,3098,5.14,4473,6.593,7901,6.768,9165,6.973,9484,7.219,10022,8.567,10023,8.567]],["t/3264",[21,2.729,22,3.613,117,1.041,213,5.064,218,3.313,287,2.57,495,5.581,528,4.562,553,5.048,624,4.741,654,3.848,923,2.494,1030,6.117,1261,6.508,1276,6.508,1281,5.193,1327,5.313,1566,8.822,1715,3.848,1942,5.492,2185,6.613,6664,8.344,9955,8.002]],["t/3266",[5,1.644,41,3.459,86,2.334,95,2.901,178,3.707,240,1.742,276,3.727,287,2.077,296,3.247,297,2.257,488,2.589,495,3.219,527,3.832,610,3.81,624,3.832,646,3.81,654,3.11,783,4.856,822,4.103,923,2.016,978,2.423,987,2.742,1011,4,1014,4.817,1019,3.559,1059,5.906,1062,4.635,1090,3.81,1177,2.546,1180,4.229,1199,5.769,1209,5.769,1278,4.053,1521,4.365,1724,5.906,1942,4.439,1947,5.26,1966,3.878,1967,3.832,2062,3.354,2121,6.267,2263,3.525,2429,4.914,2501,5.769,2897,5.26,3036,7.052,3236,4.856,7901,6.064,8045,6.744,8399,6.744,9125,5.437,10024,7.675,10025,7.675]],["t/3268",[5,2.353,172,2.542,267,2.69,287,2.972,598,5.093,654,4.451,1792,6.871,3805,8.081,9645,8.678]],["t/3270",[5,1.709,21,2.605,28,2.031,33,1.335,85,1.15,86,1.237,95,2.431,96,1.601,117,0.446,163,3.057,165,1.755,168,1.357,194,1.537,210,1.346,213,5.293,216,2.119,221,1.943,235,3.089,236,2.516,240,1.46,267,0.996,296,1.075,297,3.536,421,4.515,457,1.825,463,1.387,468,7.198,473,2.346,474,2.369,480,3.213,508,2.352,511,2.926,513,2.241,527,3.286,557,1.503,560,1.777,574,2.49,611,1.706,647,2.373,654,3.233,759,1.868,765,3.13,781,1.029,819,2.464,822,3.197,832,2.147,869,3.627,923,2.095,987,2.298,998,1.887,1002,2.707,1008,1.686,1009,4.444,1019,4.869,1024,1.841,1055,1.532,1062,2.912,1107,5.42,1114,2.373,1177,1.349,1195,2.395,1211,1.712,1227,5.672,1231,1.975,1238,2.881,1274,3.13,1286,3.396,1300,2.516,1349,2.294,1374,2.636,1418,1.648,1421,1.985,1521,2.313,1598,3.427,1599,2.656,1609,2.067,1614,2.544,1615,2.119,1617,2.417,1716,3.573,1751,2.332,1801,2.133,1872,3.427,1895,2.787,1948,2.294,2043,2.746,2072,3.753,2179,5.467,2232,2.707,2237,2.707,2422,6.493,2462,4.834,2501,6.815,2502,2.934,2508,2.787,2851,2.992,2853,2.08,3098,4.787,3248,3.573,3262,3.057,3297,3.213,3554,3.31,3785,3.573,4169,2.241,4473,3.13,4630,2.934,5160,5.42,5550,2.992,6029,3.31,6162,3.573,7446,3.769,7902,2.832,8276,7.967,8567,5.42,8577,3.427,9902,3.427,9967,3.769,10026,4.067,10027,5.961,10028,3.769,10029,7.009,10030,7.977,10031,4.067]],["t/3272",[5,1.883,12,2.825,21,1.769,31,5.773,48,2.391,73,1.832,76,4.269,90,2.261,95,2.328,115,3.032,137,2.514,148,2.243,163,2.927,172,1.425,186,3.563,187,1.995,206,3.368,235,2.958,243,1.597,267,2.153,296,3.421,411,1.425,461,3.169,473,1.811,527,2.925,531,3.057,538,1.954,636,3.169,654,2.495,753,2.552,781,1.558,783,3.896,802,2.13,816,2.514,822,2.468,862,3.942,888,4.881,914,3.809,1019,2.855,1031,3.593,1033,4.442,1035,3.561,1067,4.22,1091,3.446,1104,4.22,1114,3.593,1208,2.814,1589,5.5,1596,2.276,1711,3.473,1820,6.946,1835,4.739,1865,4.53,1967,3.075,2032,3.075,2072,3.593,2130,4.043,2177,3.659,2508,4.22,2546,5.012,2770,2.646,2923,3.942,3036,8.281,3037,5.983,3038,5.411,3377,5.411,4322,4.288,8314,9.827,10032,9.504,10033,6.158,10034,5.411]],["t/3274",[21,2.17,26,3.886,31,4.958,40,3.961,90,4.195,95,2.854,117,0.828,128,3.468,137,3.083,165,4.369,209,3.071,211,2.791,235,3.627,267,1.85,296,3.019,412,2.575,481,4.623,492,2.983,499,4.835,538,2.396,575,3.094,654,4.103,802,3.503,978,3.196,987,2.698,991,3.314,1033,5.772,1114,4.406,1151,4.33,1177,3.79,1208,3.451,1278,3.987,1305,6.363,1489,3.961,1584,4.958,1599,3.118,1715,3.06,1773,4.071,1844,4.623,1865,5.555,1952,4.446,2032,3.771,2263,5.846,2316,3.404,2452,4.225,3036,6.994,3154,5.259,9594,6.999,10035,6.999]],["t/3276",[4,1.575,5,1.861,21,1.74,26,1.941,28,1.883,44,1.077,47,1.355,85,1.713,95,1.426,96,1.485,97,2.342,117,0.832,136,1.685,137,1.54,138,1.164,148,0.962,156,0.916,172,2.01,213,1.627,235,2.909,249,4.926,258,1.44,259,0.711,267,2.128,287,1.021,296,2.933,297,1.109,391,1.728,412,1.286,421,2.274,452,2.717,483,1.435,488,1.272,489,1.258,495,5.738,527,3.551,538,1.197,557,1.394,575,1.545,576,1.218,597,3.35,607,1.034,613,1.883,615,2.778,624,1.883,654,3.075,719,2.693,759,1.732,761,7.196,781,1.532,820,2.164,831,1.841,875,1.215,907,2.585,923,0.99,957,1.43,993,1.454,1008,1.563,1009,1.343,1014,1.775,1114,3.534,1131,2.094,1162,2.181,1174,2.626,1175,2.476,1177,2.009,1204,1.54,1281,3.312,1294,2.979,1302,2.241,1308,1.905,1599,1.557,1607,1.501,1615,1.965,1662,2.835,1715,1.528,1722,1.74,1732,1.917,1790,4.621,1807,1.821,1816,1.641,1844,3.708,1874,2.201,1896,2.127,1926,2.019,1942,5.025,1959,2.72,1988,2.217,2032,1.883,2059,3.288,2072,2.201,2254,3.503,2355,3.905,2396,4.468,2429,4.859,2570,2.019,2907,8.232,2990,6.177,2991,8.024,3236,2.386,3345,2.309,3506,1.708,3554,3.07,3872,5.321,4266,5.051,7525,3.495,8975,3.07,9955,9.353,9964,6.685,10036,3.771,10037,3.771,10038,3.771,10039,3.771,10040,3.771,10041,3.771,10042,3.771,10043,3.771]],["t/3278",[165,4.527,296,2.773,488,3.538,527,3.49,582,5.781,647,6.121,822,4.205,1031,6.121,1267,6.235,1278,5.54,1445,7.306,1480,5.87,1924,4.527,2121,6.423,10044,10.491]],["t/3280",[17,4.053,94,3.101,117,0.719,123,2.02,172,2.128,210,2.171,213,5.418,218,2.289,221,3.135,267,1.607,296,3.202,297,3.122,391,2.624,418,3.295,421,2.464,473,1.93,480,5.184,482,3.562,492,2.592,527,3.827,607,1.799,654,3.726,732,2.066,781,2.326,822,2.63,895,3.589,914,2.843,923,2.415,957,3.487,1009,3.781,1019,4.922,1021,3.795,1107,5.529,1286,3.465,1344,3.643,1364,4.201,1530,3.828,1596,2.425,1640,2.931,1711,3.701,2043,4.43,2179,4.497,2376,5.341,2422,5.341,2462,4.932,2501,4.932,2516,5.765,2897,4.497,2982,5.765,3297,5.184,4320,4.497,5160,7.749,7902,4.569,8276,5.765,8567,5.529,9484,5.529,9902,5.529,10027,8.523,10028,6.081,10029,5.765,10034,5.765,10045,6.561,10046,6.561,10047,6.561,10048,6.561,10049,6.561,10050,6.561]],["t/3282",[26,4.821,31,6.152,44,2.069,172,2.168,586,4.204,770,4.981,831,4.574,888,5.202,923,2.46,978,3.674,1071,4.883,1114,5.467,1278,4.947,1714,6.073,1820,9.196,1844,5.736,2546,7.626,3036,7.752,4662,7.042,8314,11.126,10032,10.788,10034,8.232,10051,9.369]],["t/3284",[12,2.494,33,2.547,94,3.478,136,3.466,193,2.859,229,2.647,296,2.051,338,3.768,339,3.514,412,2.647,475,5.972,481,6.313,488,3.478,492,3.066,499,4.969,514,3.898,612,3.604,654,3.145,760,3.748,834,3.848,978,3.255,980,3.377,1033,3.921,1114,4.528,1125,3.67,1177,2.575,1187,3.728,1204,4.21,1364,6.602,1487,5.03,1584,5.096,1844,4.751,2020,6.54,2022,5.404,2027,6.602,2060,3.921,2075,3.898,2162,6.54,2263,5.667,2304,3.466,2456,4.703,2662,4.377,3036,4.751,4355,6.131,4593,4.802,7921,6.54,9086,6.317,10035,7.193]],["t/3286",[94,3.018,172,2.071,259,1.688,287,2.422,296,2.365,495,5.201,530,3.928,607,2.454,867,2.762,1008,3.71,1014,5.836,1191,5.877,1332,4.369,1609,4.549,1617,5.319,1714,5.801,1829,3.681,1844,6.925,1942,7.173,2003,6.042,2162,7.542,2177,5.319,2429,7.94,2907,7.157,2990,9.206,5211,7.542,10052,8.295]],["t/3288",[128,4.545,249,4.567,421,3.717,468,6.784,495,5.442,1019,4.589,1790,4.503,1942,5.725,2059,5.374,2254,5.725,2396,5.828,2501,7.44,2907,7.618,2990,8.057,2991,7.44,3036,7.371,3037,5.775,9964,7.617,10029,8.697]],["t/3290",[208,3.398,621,3.366,1812,5.894]],["t/3293",[3,3.581,17,3.823,21,2.492,123,2.67,126,3.391,139,2.551,186,3.514,187,2.809,196,3.654,220,4.188,229,2.958,240,1.969,259,1.636,287,2.347,296,2.292,398,3.195,400,6.847,414,3.007,488,2.925,527,2.885,546,5.061,557,3.205,560,3.79,606,5.107,607,3.04,734,4.709,768,4.932,820,3.098,822,3.476,1151,4.973,1330,5.016,1813,4.973,2233,5.31,3098,5.204,10053,8.673,10054,8.039]],["t/3295",[1,3.152,3,4.03,5,2.557,126,3.816,139,2.87,209,3.97,210,3.229,228,5.378,240,2.216,1272,6.689,1276,6.689,1327,5.462,1727,3.466,2171,5.496,2191,5.975,2195,8.313,3595,6.175,9743,9.431]],["t/3297",[5,1.929,11,3.917,21,2.588,117,0.987,139,2.649,172,2.628,196,3.719,259,2.346,287,2.437,400,6.943,489,3.788,532,5.573,546,5.256,607,3.41,654,3.65,668,3.361,759,4.136,870,5.405,1008,3.734,1055,3.394,1091,5.04,1417,5.353,1615,4.694,1924,3.886,2557,6.173]],["t/3299",[3,4.805,4,2.737,7,0.507,11,0.686,17,4.049,19,3.751,20,3.265,21,2.399,22,3.176,24,3.216,25,1.812,27,3.784,29,2.652,37,3.814,38,0.73,40,1.847,41,1.587,43,0.692,44,1.695,47,2.604,73,2.837,86,1.071,87,1.208,88,1.633,95,1.331,117,0.628,123,1.459,126,2.561,136,2.117,138,0.614,139,3.668,140,1.435,165,0.858,169,2.156,186,0.806,196,1.713,207,1.244,209,2.331,211,0.735,212,1.531,216,1.037,217,1.971,229,2.234,235,1.692,241,1.899,256,1.495,258,1.809,259,0.375,263,2.595,264,0.927,285,2.926,287,1.283,316,2.255,323,3.8,338,0.966,400,1.057,449,1.409,461,3.371,471,1.171,472,3.035,488,2.643,489,0.663,490,0.818,492,0.786,530,0.873,552,0.987,555,0.721,565,1.16,575,4.035,577,5.035,587,1.495,598,2.657,607,0.545,610,4.144,612,0.581,618,1.088,619,1.602,634,2.074,654,0.806,668,3.114,670,0.888,742,2.817,745,1.205,772,1.571,775,1.387,790,2.902,792,3.2,820,0.711,822,1.9,834,1.768,876,3.744,879,1.15,892,1.824,896,1.926,908,0.735,912,2.23,923,1.245,987,0.711,998,2.299,1013,2.71,1017,4.098,1019,0.922,1024,2.967,1025,1.759,1055,0.749,1062,2.595,1066,2.829,1069,1.812,1099,3.814,1121,5.913,1130,3.647,1146,1.043,1148,1.409,1158,4.216,1159,1.037,1204,0.812,1216,3.487,1231,0.966,1234,4.584,1235,1.571,1245,1.182,1265,1.273,1267,1.182,1282,1.463,1327,2.652,1347,1.289,1373,3.2,1396,1.131,1418,1.427,1421,2.797,1455,1.131,1473,2.228,1485,1.289,1584,1.306,1586,2.878,1607,2.883,1609,2.409,1612,1.017,1711,1.986,1749,1.15,1764,3.264,1815,1.435,1828,1.435,1924,0.858,1954,1.824,1976,0.993,1979,1.306,1985,6.94,1989,1.15,2019,1.385,2032,1.759,2062,1.539,2191,3.508,2204,1.435,2220,2.495,2224,2.968,2278,1.193,2281,2.203,2304,0.888,2557,4.965,2903,1.273,2989,5.042,2998,2.541,3334,1.748,3589,4.216,3918,1.182,3932,1.343,4276,1.531,4280,1.463,4313,2.453,4336,1.218,5550,2.591,6577,1.676,6967,1.843,6991,1.843,7580,2.968,7932,1.495,7955,1.619,8081,2.968,8377,1.676,8522,1.843,8550,3.264,9088,3.264,9895,1.748,10004,3.095,10055,4.393,10056,1.989,10057,1.989,10058,5.311,10059,1.989,10060,3.264,10061,4.74,10062,1.989,10063,1.989,10064,4.74,10065,1.989,10066,4.74,10067,3.522,10068,1.989,10069,4.165,10070,1.989,10071,1.989,10072,6.073,10073,3.522,10074,3.522,10075,1.989,10076,1.843,10077,3.522,10078,1.989,10079,1.843,10080,1.843]],["t/3301",[3,3.579,4,2.249,5,0.805,7,0.958,10,0.992,11,1.598,12,1.73,13,1.606,16,0.837,17,1.202,19,0.775,20,0.674,21,1.547,27,0.723,33,0.491,36,1.491,40,0.785,41,0.674,44,2.371,45,2.006,47,1.35,48,0.581,73,1.118,76,2.249,85,0.423,86,0.455,87,1.289,88,1.264,90,0.549,96,1.074,106,2.249,115,0.516,117,0.725,123,0.461,126,3.117,138,0.462,139,3.135,146,0.785,150,0.623,165,1.177,167,1.551,169,1.709,172,1.246,177,1.717,186,0.606,187,0.485,193,3.193,194,0.566,196,2.682,198,1.346,200,1.746,203,0.659,204,1.06,206,0.818,209,0.609,211,1.008,219,0.9,221,0.715,228,2.07,229,1.58,239,1.777,240,0.34,248,1.481,259,0.282,263,1.44,271,1.005,285,2.953,297,0.44,299,1.841,316,3.447,323,5.507,391,0.427,400,4.239,402,0.581,408,0.844,411,0.346,414,1.637,421,0.562,423,0.844,438,0.719,445,0.812,449,1.06,452,0.671,461,0.77,463,0.51,473,1.105,483,1.429,488,2.036,491,0.64,504,2.055,510,0.796,511,0.681,513,0.824,526,1.017,527,0.498,528,0.719,529,0.524,530,1.649,538,1.192,542,0.996,544,0.751,557,1.99,558,1.125,560,3.484,561,1.261,571,0.739,575,0.613,578,2.07,579,0.553,581,1.315,582,0.824,584,1.264,587,1.125,598,0.694,599,1.746,600,0.881,607,1.476,610,2.299,611,1.144,612,1.097,618,2.533,621,0.437,622,1.984,624,0.747,629,2.673,630,0.818,634,0.881,648,0.795,666,1.551,668,1.017,679,2.34,744,0.795,759,0.687,763,0.947,772,1.182,774,0.916,781,0.379,787,0.627,809,2.318,819,2.277,820,0.535,822,4.065,832,1.44,867,0.462,875,0.879,888,1.514,890,0.694,895,0.818,896,0.818,908,1.008,910,0.898,923,0.987,973,1.869,987,0.535,989,0.858,997,0.533,998,0.439,1003,1.421,1011,0.78,1013,1.29,1017,1.706,1024,2.097,1025,2.313,1043,2.764,1062,0.677,1066,1.855,1069,1.403,1070,0.751,1089,1.621,1099,0.996,1121,2.661,1135,0.947,1146,0.785,1158,2.764,1159,0.78,1175,0.982,1211,1.148,1213,1.526,1248,1.551,1257,1.815,1261,2.575,1267,0.889,1273,0.585,1286,0.79,1302,0.889,1307,0.812,1308,1.378,1327,0.837,1349,2.119,1364,0.958,1373,1.01,1399,1.331,1401,2.462,1418,1.877,1421,2.947,1449,0.751,1455,1.551,1457,2.173,1480,0.837,1486,1.06,1546,2.405,1599,0.618,1613,1.025,1615,0.78,1711,1.538,1712,1.481,1715,0.606,1722,0.69,1727,0.531,1732,1.386,1734,1.844,1749,0.865,1773,0.807,1790,0.681,1805,1.025,1816,2.343,1828,1.079,1843,3.635,1921,0.858,1924,0.646,1949,2.07,1966,2.34,1967,1.876,1985,1.869,1987,2.154,1989,0.865,2016,1.46,2032,1.362,2123,0.889,2181,0.996,2188,1.899,2191,2.3,2204,1.079,2206,1.101,2220,2.661,2237,0.996,2263,0.687,2288,0.831,2304,0.668,2313,0.865,2429,0.958,2434,2.006,2443,1.514,2447,2.396,2449,2.779,2450,2.616,2452,0.837,2461,1.315,2493,3.659,2521,1.967,2531,1.768,2535,2.098,2545,1.669,2546,2.22,2557,3.174,2581,0.775,2582,1.261,2790,2.277,2872,0.936,2899,2.055,2926,2.098,2976,2.824,2998,1.079,3032,0.907,3206,1.182,3318,0.907,3334,1.315,3506,1.235,3556,3.341,3589,1.101,3595,1.725,3648,1.042,3680,2.192,3690,2.098,4276,1.151,4280,2.764,4307,1.079,6043,2.05,6926,1.315,7516,1.042,7955,1.218,7956,1.218,8037,3.884,8063,2.298,8081,3.166,8473,2.968,8560,3.482,9618,1.387,9646,1.315,9895,2.396,9896,1.387,9898,2.527,9899,6.597,9929,1.387,10004,1.315,10009,1.387,10054,2.527,10058,2.527,10060,2.527,10069,7.326,10072,8.313,10076,1.387,10079,3.482,10080,1.387,10081,1.496,10082,2.727,10083,1.496,10084,4.632,10085,3.757,10086,1.496,10087,1.387,10088,1.496,10089,1.496,10090,1.496,10091,2.727,10092,1.496,10093,1.496,10094,1.496,10095,1.496,10096,1.496,10097,1.496,10098,1.496,10099,1.496]],["t/3303",[11,3.39,21,2.824,47,3.533,48,3.816,117,1.077,139,2.891,196,3.585,259,1.854,285,4.39,323,5.156,400,6.373,489,3.279,538,3.118,557,3.632,607,3.287,870,5.898,882,4.966,1013,4.649,1816,4.277,2557,6.736,9368,9.11]],["t/3305",[196,3.364,323,5.901,400,5.98,607,3.084,10069,9.884,10100,11.249]],["t/3308",[10,2.762,12,2.44,30,2.08,117,1.114,137,3.1,139,2.233,198,3.748,214,2.649,219,2.505,229,2.589,240,1.724,259,1.432,267,1.86,398,3.744,418,3.813,461,3.907,521,3.276,529,3.556,538,2.409,539,6.18,607,2.081,652,5.786,809,2.472,873,3.931,881,4.556,882,3.836,978,2.397,1089,4.512,1140,5.732,1205,5.211,1302,4.512,1331,5.149,1577,4.601,1678,3.813,1816,3.304,1848,5.842,2144,4.122,2168,5.585,2182,4.354,2189,7.037,2275,3.332,2520,5.998,2899,4.152,3067,4.985,4297,5.126,4315,5.477,4320,5.203,5012,5.585,8035,8.929,9645,5.998,10101,7.592]],["t/3310",[4,2.834,19,4.874,21,1.949,30,1.388,90,2.491,93,4.385,117,1.032,139,3.433,207,4.244,208,2,214,4.278,219,2.239,235,3.259,263,2.926,264,3.161,267,1.662,461,3.491,501,4.153,510,2.749,529,2.374,538,3.429,557,2.507,562,2.769,576,3.041,612,1.981,652,4.451,654,2.749,759,3.115,767,3.994,809,2.209,867,2.905,870,4.07,876,7.435,907,4.649,955,2.868,976,5.955,1070,3.407,1071,3.535,1089,4.032,1099,4.515,1205,4.916,1267,4.032,1300,4.197,1331,3.8,1351,4.153,1449,3.407,1546,4.343,1842,4.991,1924,4.061,1952,3.994,2130,4.454,2256,4.032,2521,4.893,2998,6.789,4307,4.893,4584,4.649,7114,6.287,7128,4.991,8397,5.359,10055,8.723,10102,6.784,10103,6.784,10104,6.784]],["t/3312",[11,3.933,21,2.605,30,1.855,117,0.994,139,2.666,194,3.427,214,3.163,461,4.665,483,4.339,489,3.804,498,7.379,501,5.55,511,4.124,538,3.618,544,4.553,549,6.121,557,3.35,598,4.203,607,2.485,744,4.82,764,3.848,767,5.338,867,2.798,978,2.862,1070,4.553,1205,4.124,1211,3.817,1239,5.243,1553,6.67,1924,3.912,2256,5.388,2278,5.44]],["t/3314",[1,0.731,7,1.647,10,3.059,12,2.702,36,3.532,39,1.794,43,1.04,44,1.495,48,1.161,73,1.49,86,0.909,95,2.441,97,0.923,103,1.939,115,1.032,117,0.708,118,1.116,137,2.636,139,0.88,148,0.763,151,1.66,168,1.67,187,1.622,198,1.476,214,1.043,219,0.987,228,4.161,229,2.202,235,1.437,240,0.679,241,1.612,243,0.776,255,4.577,271,1.844,285,2.236,297,0.88,316,1.915,320,2.68,350,1.715,402,1.161,411,1.159,421,1.123,433,3.168,436,1.812,452,1.342,458,5.674,463,1.02,470,0.916,483,1.138,508,2.896,510,1.462,528,1.437,529,2.643,535,1.687,538,0.949,550,1.964,552,1.485,555,1.085,557,1.85,578,1.648,597,1.153,598,1.387,602,1.871,607,0.82,614,3.816,622,1.579,626,1.918,630,1.636,639,3.911,646,1.485,652,5.609,668,1.868,678,1.601,732,0.942,760,1.444,763,3.168,764,1.269,781,0.757,796,4.345,809,1.63,812,1.85,816,1.221,827,2.248,830,1.745,840,1.612,867,0.923,875,3.391,882,2.529,896,2.738,961,4.298,971,3.433,980,1.301,987,1.068,1003,1.559,1008,2.075,1013,1.414,1014,1.407,1032,2.434,1052,1.915,1072,1.511,1090,1.485,1140,2.824,1147,2.2,1169,1.73,1177,1.661,1180,2.759,1205,3.824,1248,1.701,1267,1.777,1271,2.626,1330,1.73,1331,5.322,1344,1.66,1351,1.831,1372,3.245,1373,2.019,1398,1.444,1440,3.332,1486,2.118,1489,1.569,1678,1.502,1718,2.248,1727,1.062,1755,2.363,1771,5.676,1790,1.36,1799,1.66,1807,1.444,1819,1.612,1825,1.745,1829,4.47,1921,1.715,1934,1.648,1935,2.019,1943,1.745,1948,1.687,1949,1.648,1976,1.493,1988,3.979,2072,1.745,2117,2.2,2156,2.2,2196,2.434,2230,1.336,2237,1.991,2288,1.66,2304,2.236,2502,2.157,2519,1.915,2899,2.738,2900,1.915,3002,2.772,3037,1.745,3157,2.248,3215,2.628,3236,1.892,3503,2.118,3508,2.434,3556,4.658,3905,1.892,4327,2.083,4345,2.52,4397,2.301,4615,2.52,5984,2.628,6032,2.628,6109,2.772,6453,2.52,7126,6.364,7902,2.083,8040,2.628,8196,2.628,8345,3.612,8438,2.52,9093,2.772,10008,2.772,10052,2.772,10105,5.007,10106,2.991,10107,2.991,10108,2.991,10109,2.991,10110,2.991,10111,2.991,10112,2.991,10113,2.991,10114,2.991,10115,2.991,10116,2.991,10117,2.991,10118,5.007,10119,2.991,10120,2.991,10121,2.991,10122,5.007]],["t/3316",[4,1.162,5,1.009,7,1.202,17,2.077,21,1.354,22,1.059,27,3.896,30,0.57,44,2.664,72,1.542,86,0.846,117,0.305,137,1.136,139,3.008,219,0.918,228,1.533,255,2.855,267,1.154,271,1.025,297,1.802,335,3.399,339,1.26,411,1.418,433,1.761,436,3.714,457,1.249,466,1.827,483,1.793,526,1.038,545,1.852,552,1.382,555,1.009,557,2.982,562,1.136,620,2.814,639,1.441,646,1.382,652,5.004,664,2.265,666,1.149,678,1.49,694,2.992,740,1.278,763,1.761,774,4.415,781,0.704,796,1.33,809,2.627,827,3.542,834,1.038,858,2.579,879,1.609,891,1.359,903,1.761,915,2.345,969,1.389,987,0.994,1008,3.344,1009,0.991,1019,1.29,1043,2.047,1081,1.971,1150,3.181,1187,1.337,1196,3.281,1203,1.557,1253,3.134,1330,1.609,1331,2.474,1372,1.804,1473,1.761,1489,1.46,1530,1.624,1584,1.827,1612,1.423,1727,0.988,1799,2.616,1829,1.938,1904,1.406,1921,2.702,1934,2.596,1943,1.624,1988,2.244,1994,2.445,2072,1.624,2271,2.313,2335,2.141,2443,1.545,2450,1.938,2511,8.121,2518,1.582,2519,1.782,2531,1.804,2662,4.068,2998,2.007,3463,3.399,3510,2.198,3556,2.007,4315,2.007,4457,1.827,4472,1.852,4593,3.792,5420,2.445,7343,2.579,9570,2.579,10123,2.783,10124,2.783,10125,2.783,10126,2.783,10127,2.783,10128,2.783,10129,2.783,10130,2.783,10131,2.783,10132,8.068,10133,2.783,10134,2.783,10135,7.212,10136,2.783,10137,2.783]],["t/3319",[7,2.696,83,2.087,139,3.109,156,2.568,219,3.488,228,5.824,443,4.433,526,3.944,623,6.342,769,6.168,1233,7.136,1239,6.113,2354,8.907,4661,9.797]],["t/3321",[7,2.759,28,5.4,30,2.213,83,2.135,117,1.186,156,2.628,443,4.536,457,4.852,555,3.923,1120,5.872,2052,8.803]],["t/3323",[621,3.423]],["t/3325",[5,1.092,7,2.934,11,1.054,14,4.07,21,1.465,28,1.526,30,2.442,83,2.356,85,0.864,95,1.155,106,1.484,115,1.054,116,1.417,117,1.008,123,0.941,139,3.692,156,2.068,168,1.7,172,0.707,177,1.397,180,0.982,181,1.353,186,1.238,187,2.124,188,1.535,194,1.155,206,1.671,210,1.011,211,1.129,217,6.129,219,2.808,226,1.424,229,1.739,236,3.154,239,1.445,242,3.294,243,0.793,248,2.768,258,2.922,265,2.768,266,1.313,267,0.748,438,2.449,443,5.079,489,1.019,510,1.489,526,4.519,528,2.449,555,4.598,571,1.508,579,1.884,597,1.178,621,1.489,626,3.521,660,2.181,745,1.852,748,3.521,781,0.773,816,1.248,834,1.902,862,1.956,867,1.573,875,0.985,914,2.209,923,1.722,969,1.526,993,4.436,1014,1.438,1030,1.593,1170,3.262,1177,1.014,1196,2.128,1386,1.871,1398,2.462,1465,3.45,1519,2.875,1530,2.974,1618,2.619,1723,1.738,1807,1.476,1809,2.248,1819,1.647,1895,2.094,1918,3.396,1921,3.761,1949,4.218,1950,8.112,2885,4.731,2962,2.575,3078,1.852,5563,2.352,6464,4.027,7931,2.128,8031,2.685,10138,3.056,10139,3.056,10140,3.056,10141,3.056,10142,3.056,10143,3.056,10144,3.056,10145,2.832,10146,3.056,10147,3.056,10148,3.056,10149,3.056,10150,3.056,10151,6.559,10152,7.655,10153,9.193,10154,5.098,10155,7.655,10156,5.098,10157,5.098,10158,3.056,10159,3.056,10160,3.056,10161,3.056,10162,3.056,10163,3.056,10164,3.056,10165,3.056]],["t/3327",[94,3.952]],["t/3329",[1924,5.057]],["t/3331",[21,3.312,621,3.366,892,5.969]],["t/3333",[208,3.398,621,3.366,1812,5.894]],["t/3336",[10,4.06,21,3.207,408,6.294,1070,5.605,1792,6.981,1924,4.815,8352,8.588]],["t/3338",[21,2.992,94,3.512,483,3.962,607,2.855,621,3.041,753,4.316,1312,6.514,1607,4.143,1911,10.907,1938,8.476,2215,8.38,2274,9.15,8999,9.651,9000,7.512]],["t/3340",[103,6.904,197,4.962,213,4.595,216,5.551,297,3.132,408,6.007,538,3.991,598,4.938,649,4.674,910,6.391,1070,5.349,1213,5.96]],["t/3343",[5,1.264,10,2.146,11,2.035,30,1.207,36,3.226,43,2.966,97,1.82,117,1.202,156,1.433,163,2.804,188,2.962,197,4.664,210,3.628,213,2.545,223,7.298,224,4.86,267,1.445,297,1.735,401,2.998,418,2.962,470,2.611,511,2.683,512,4.66,524,6.398,553,3.136,607,1.617,612,1.723,623,3.539,647,3.442,649,2.589,654,3.454,732,3.662,767,3.473,802,2.949,1055,3.212,1125,2.79,1203,6.136,1273,2.306,1277,3.115,1281,3.226,1349,3.327,1362,3.823,1370,3.442,1465,4.942,1596,3.15,1607,2.347,1618,2.356,1712,4.628,1829,3.506,1873,3.873,2145,3.327,2217,4.255,2223,6.333,2275,2.589,2278,3.539,2350,3.65,2519,3.777,2718,4.801,2840,4.539,3137,7.741,4168,4.178,4341,3.873,4419,6.407,4849,6.734,7185,5.183,7944,4.178,8345,4.255,10166,5.467,10167,5.898,10168,7.49,10169,8.524,10170,5.467,10171,5.898,10172,5.898,10173,5.898]],["t/3345",[10,3.817,117,1.15,156,2.549,188,5.269,197,4.888,213,5.38,216,6.498,397,6.121,452,4.707,732,3.303,6138,8.288,10166,9.724,10174,10.491]],["t/3347",[12,2.376,13,4.352,90,2.715,188,6.686,194,2.794,196,3.981,197,5.266,210,3.739,213,5.221,216,5.202,224,3.589,262,3.444,470,3.058,491,3.163,530,3.244,607,2.027,611,3.1,617,5.271,732,3.81,875,2.382,923,1.941,957,3.785,1125,3.496,1465,5.87,1596,2.732,1862,5.556,1988,2.706,2215,4.991,3137,8.412,3762,5.556,4849,7.886,6138,9.56]],["t/3349",[156,2.628,166,5.432,197,5.039,511,4.92,514,5.432,530,4.746,617,5.711,1370,6.31,8074,8.544,10175,10.815,10176,10.815]],["t/3351",[12,2.737,30,1.743,43,4.45,89,4.968,117,0.933,188,4.277,219,2.81,241,4.59,263,3.977,457,3.82,470,2.608,489,4.267,530,4.809,612,3.2,654,4.44,745,5.16,1055,4.128,1109,5.452,1273,3.329,1489,4.467,1830,4.59,1926,4.558,1988,3.117,2204,6.142,2257,6.031,2316,3.838,2999,8.767,8345,6.142,9000,6.142,10177,8.515]],["t/3353",[115,3.32,137,3.93,210,3.916,224,4.674,239,4.553,418,4.835,598,4.463,752,6.969,971,5.118,1214,5.017,1718,7.235,1724,7.408,1829,4.869,1953,6.022,1974,4.893,2078,7.235,2178,7.082,2198,6.321,2380,4.485,3675,6.944,4849,7.605,6043,7.235,8630,7.605,10178,9.626]],["t/3355",[10,3.061,22,3.201,36,4.601,90,3.089,97,2.596,165,4.691,245,3.3,263,2.616,489,3.627,579,4.018,732,3.423,890,3.901,892,4.356,987,3.005,1008,3.487,1074,5.386,1443,3.542,1629,6.801,1829,5.728,2223,8.342,2350,5.205,2522,5.959,3651,6.847,8345,9.741,10168,7.392,10170,7.797,10179,8.413]],["t/3357",[6,2.9,12,2.674,36,7.073,38,2.096,41,3.751,44,2.518,97,1.761,115,1.968,117,0.626,152,4.391,156,1.387,172,1.32,196,1.706,211,2.109,214,1.991,223,3.798,224,2.771,229,1.946,412,3.682,512,4.508,586,3.734,866,2.537,1019,4.554,1024,2.584,1201,4.809,1596,5.024,1613,3.911,1618,2.279,1712,4.518,1715,2.312,1750,3.3,1773,3.076,1959,4.116,2200,7.312,2223,3.61,2275,3.652,2278,7.19,2281,5.206,2851,4.198,3037,4.856,3651,4.645,3901,6.404,4325,5.464,5430,5.289,5442,4.809,5466,7.713,5467,5.289,5977,5.014,6688,4.809,10168,7.312,10180,9.822,10181,5.706,10182,8.322,10183,8.322,10184,9.822,10185,10.796,10186,5.706]],["t/3359",[17,4.659,30,2.163,211,3.906,263,3.894,678,5.658,1629,6.612,1829,5.49,2223,8.444,8345,7.625]],["t/3361",[30,1.711,43,2.909,91,4.997,117,1.317,166,4.2,188,4.2,197,3.896,210,4.354,213,4.673,216,4.358,219,4.192,223,5.566,224,5.258,226,3.896,229,2.852,263,2.6,297,2.459,660,3.578,732,2.633,867,2.581,1009,2.979,1055,3.151,1170,3.564,1372,7.02,1465,4.881,1815,6.032,1873,5.491,1878,6.63,2215,5.646,3137,7.208,3149,7.348,4341,5.491,6138,6.607]],["t/3363",[13,5.48,41,4.195,86,2.83,89,5.43,90,4.257,117,1.02,177,4.253,210,3.835,213,5.001,219,3.071,224,5.628,267,2.279,452,4.176,470,3.551,668,3.472,991,4.084,1009,3.315,1150,6.283,1177,3.088,1256,6.713,1277,4.914,1344,5.167,1952,6.825,2256,5.531,2871,7.843,2896,7.162]],["t/3365",[117,1.469,197,5.99,210,3.207,213,4.182,243,2.514,262,5.538,607,2.657,759,4.451,862,6.206,1002,6.451,1199,7.285,1256,6.992,1988,4.907,2256,7.064,2896,7.459,9412,8.517]],["t/3367",[297,3.7,408,6.007,418,5.349,488,3.592,622,5.624,624,5.318,1009,3.794,1055,4.013,1949,5.869,8075,8.669,8106,9.358,10187,10.651]],["t/3370",[1,2.02,2,3.399,5,2.302,21,2.375,25,4.252,30,1.691,83,1.632,117,1.178,186,3.349,210,3.556,228,4.553,240,1.876,258,4.103,259,2.027,318,6.723,463,3.665,508,4.78,589,6.08,764,3.508,802,4.131,903,5.229,1177,2.742,1211,3.48,1213,4.624,1218,4.335,1233,5.579,1257,5.5,1295,5.853,1521,4.699,1678,4.15,1967,4.126,1979,5.426,3063,6.359,3670,5.961,4627,5.853,6246,6.211,8402,5.664,8483,6.211,9603,7.261,10188,7.659,10189,8.264,10190,7.659]],["t/3372",[1,1.76,30,1.474,97,2.223,168,2.402,186,2.918,210,3.961,258,2.749,318,4.505,402,4.33,406,3.575,463,2.456,492,2.845,526,2.687,530,4.894,555,2.612,575,2.951,602,4.505,648,3.829,753,2.985,802,3.857,963,4.321,1066,3.555,1090,3.575,1125,4.638,1154,5.69,1177,3.7,1200,3.829,1218,3.778,1295,5.101,1401,6.87,1618,2.876,1772,5.015,1953,4.505,1967,5.568,2006,3.276,2171,3.069,2769,7.766,3256,4.736,3680,4.202,3770,5.195,4169,3.968,4426,5.862,4542,4.668,4627,7.899,8333,6.675,8402,4.936,10191,6.328,10192,7.202,10193,7.202,10194,6.069,10195,7.202]],["t/3374",[1,2.627,2,3.399,5,1.77,7,2.108,12,2.656,117,1.178,139,2.43,142,5.579,210,2.734,248,4.487,259,1.559,318,7.471,418,4.15,496,4.487,606,4.866,607,2.946,612,2.413,648,4.393,649,3.627,753,3.425,802,4.131,987,3.839,1177,3.962,1213,4.624,1218,4.335,1485,5.357,1589,5.169,1599,3.412,1910,4.866,1967,6.315,2133,5.5,2449,4.959,4627,7.612,7716,6.726,8569,7.659,8570,7.659,9714,7.659]],["t/3376",[3,2.856,5,1.482,26,4.909,28,3.454,33,2.271,89,4.036,95,2.615,117,0.758,126,2.704,179,4.073,186,2.803,193,2.548,197,3.223,210,3.895,211,2.556,214,2.414,229,3.253,232,6.078,241,3.729,267,2.337,452,3.104,470,3.345,511,3.147,599,6.108,607,1.897,610,3.434,681,3.104,732,2.178,742,4.111,802,3.3,809,2.252,814,2.333,867,2.135,875,2.229,881,4.151,912,3.255,923,1.817,963,4.151,978,2.184,987,3.408,998,2.03,1125,3.272,1137,5.631,1177,2.295,1260,5.968,1399,3.377,1401,6.258,1421,3.377,1640,4.261,1774,4.377,1967,3.454,2123,4.111,2232,4.604,2619,3.341,3250,5.199,4312,5.089,4350,4.111,4627,4.9,8402,4.741,10191,9.595,10194,5.829,10196,6.918,10197,6.078,10198,6.412,10199,6.918,10200,6.412]],["t/3378",[11,3.616,22,2.439,30,1.312,83,1.266,94,2.162,117,1.404,139,2.661,210,2.121,216,3.341,221,3.064,239,3.032,271,3.333,296,1.694,318,4.011,483,2.439,510,1.872,526,3.376,538,2.034,599,4.105,607,1.758,621,1.872,668,2.392,742,3.81,752,3.775,775,1.877,809,3.414,867,2.792,874,3.481,998,1.881,1024,2.903,1099,4.267,1135,4.056,1177,3.478,1183,5.942,1187,3.08,1197,5.218,1279,3.676,1401,5.574,1465,4.078,1640,2.864,1669,5.065,1685,4.465,1701,6.201,1711,5.103,1967,5.235,2177,3.81,2853,5.361,2877,5.065,3595,4.056,3680,6.645,4169,3.533,4542,5.864,4627,7.426,6246,6.8,7716,5.218,8345,4.625,9050,5.942,9481,5.942,10191,7.949,10194,7.624,10200,5.942,10201,6.411,10202,9.717,10203,6.411]],["t/3380",[11,3.168,13,5.408,44,1.633,117,1.007,209,3.736,267,2.25,501,5.623,510,3.357,526,3.427,546,5.359,576,2.967,607,2.518,767,5.408,879,5.312,1071,4.787,1089,5.458,1286,4.85,1334,6.031,1615,4.787,2123,5.458,2520,7.256,2934,5.267,3066,7.476,3680,5.359,4169,5.061,4573,6.903,6246,6.903,6907,7.476,7905,6.903,8402,6.295,9992,8.513,10194,7.74,10202,8.513]],["t/3382",[50,6.593,117,1.101,137,4.958,186,4.068,210,3.322,229,3.424,267,2.459,402,3.898,470,3.076,508,5.807,814,3.386,870,6.024,1159,5.232,1399,4.901,1841,3.687,2380,4.678,3741,6.281,4473,7.726,10197,10.671]],["t/3384",[259,2.174,2174,5.037,8993,9.382]],["t/3386",[1778,5.424,1924,4.973,2425,6.258]],["t/3389",[1,1.512,5,2.202,12,2.834,17,2.726,22,2.353,28,3.088,33,2.03,48,2.401,51,4.429,76,3.003,106,3.003,115,4.086,117,0.678,122,2.525,150,3.67,187,2.003,209,2.516,210,2.046,213,3.805,229,2.109,240,2.544,267,1.515,285,2.763,398,2.278,411,1.431,427,4.354,468,4.239,473,1.819,492,2.444,505,3.311,508,3.577,526,3.291,528,2.971,557,3.259,568,3.019,576,1.998,610,3.07,670,2.763,732,1.947,802,3.876,816,2.525,957,2.346,987,3.151,1013,2.925,1055,3.873,1066,3.053,1072,5.662,1125,2.925,1177,2.052,1204,2.525,1205,4.012,1271,3.244,1273,2.418,1331,2.497,1351,3.786,1370,3.609,1401,3.288,1418,4.165,1421,3.019,1530,3.609,1661,5.434,1914,3.088,2171,2.636,2210,4.461,2233,3.786,2238,4.759,2508,4.239,2928,4.117,2976,4.649,3157,4.649,3256,2.987,3463,4.461,3670,6.362,4476,4.176,4584,4.239,4627,4.381,8345,4.461,9483,5.732,9505,5.434]],["t/3391",[2,3.192,11,3.557,30,1.588,36,5.64,83,1.532,90,2.85,136,3.466,175,3.708,211,2.868,228,4.276,240,1.762,259,1.464,267,2.526,271,2.859,296,3.262,297,2.282,427,5.09,445,4.213,471,4.569,473,3.033,483,2.953,487,3.088,489,3.44,520,4.018,526,3.848,527,2.582,531,3.853,544,3.898,571,3.831,576,2.507,597,2.993,627,5.039,668,2.896,802,2.684,1013,3.67,1368,5.497,1599,3.204,1816,3.377,1829,3.192,1923,4.528,2298,5.239,2304,3.466,3680,4.528,4270,4.183,4397,5.972,8130,5.833,8544,6.317,9484,6.54,10204,7.76,10205,7.76]],["t/3393",[2,4.528,5,2.154,33,1.952,90,2.185,115,2.052,117,0.652,150,3.569,168,1.984,175,4.098,190,2.936,210,2.838,228,5.542,240,1.947,243,1.543,245,2.334,267,2.101,296,1.572,330,3.64,398,2.191,406,2.953,419,2.719,421,3.777,422,4.333,427,6.186,521,2.567,526,3.2,527,2.853,607,2.351,618,3.253,634,3.502,775,1.741,802,4.037,809,1.937,891,2.904,923,1.562,985,1.783,998,1.745,1003,4.47,1013,2.813,1031,3.471,1055,2.241,1066,2.936,1332,2.904,1401,6.819,1557,4.7,1641,4.7,1926,3.184,2130,3.906,2154,3.08,2223,3.764,2230,2.657,2319,8.96,2396,5.05,2429,3.809,2484,3.502,2501,4.471,2770,2.556,2803,4.7,2853,3.042,3256,2.873,3670,8.418,4476,4.016,4631,4.376,8437,5.227,9542,5.227,9964,6.6,10087,5.513,10206,7.949,10207,5.513,10208,5.227]],["t/3395",[2,4.529,10,1.877,12,1.658,72,1.689,95,1.95,96,2.031,117,1.207,154,3.593,172,1.194,186,4.166,197,3.599,210,2.556,220,3.731,228,4.257,243,1.338,259,1.457,267,1.892,271,1.901,279,6.346,296,3.329,330,2.19,391,1.473,397,3.011,398,1.901,402,3,411,1.194,419,2.358,427,6.429,472,3.304,483,1.963,521,2.226,526,4.311,527,3.42,538,1.637,544,4.651,557,3.422,579,1.907,582,2.843,610,2.562,627,2.245,629,2.562,646,3.835,668,1.925,802,2.672,891,2.519,985,1.547,1030,4.026,1066,2.547,1125,2.441,1249,2.707,1253,2.639,1260,3.228,1330,4.468,1398,2.492,1401,4.107,1418,3.13,1449,2.592,1577,3.127,1599,2.131,1958,2.802,2476,5.38,2934,2.959,3012,4.348,3098,3.096,3680,6.742,3797,3.011,4270,2.782,4289,4.783,4350,4.591,4476,6.941,6043,3.878,7786,4.783,8130,3.878,8179,4.534,8228,8.485,9639,4.534,10208,6.788,10209,5.16,10210,5.16,10211,5.16]],["t/3397",[2,4.225,10,2.247,11,2.13,15,1.941,30,1.264,83,0.763,94,1.303,117,0.677,154,4.301,165,1.668,175,3.686,180,1.985,181,3.415,193,1.424,195,4.003,200,2.475,214,3.074,220,1.867,239,1.828,240,2.187,259,1.165,271,2.842,279,4.233,285,3.935,296,2.849,315,5.982,323,3.24,330,2.621,391,3.791,400,3.283,402,1.501,411,0.894,418,1.941,427,6.077,487,3.506,513,2.13,521,1.668,527,2.055,531,1.919,538,1.959,539,5.027,544,1.941,557,3.256,571,1.908,576,1.995,579,1.428,598,1.792,610,1.919,620,1.775,621,1.129,627,3.834,659,1.485,757,1.867,781,3.115,787,1.621,802,1.337,822,1.549,890,1.792,923,1.015,971,3.283,980,2.687,1009,1.377,1020,3.396,1030,2.014,1097,1.584,1120,2.098,1125,1.828,1330,2.235,1331,1.56,1401,4.684,1441,2.445,1449,1.941,1599,1.596,1640,1.726,1694,2.788,1727,2.193,1790,2.81,1799,2.146,1805,2.649,1829,2.541,1954,2.001,1976,5.128,2032,1.93,2152,2.146,2275,2.711,2304,1.726,2316,1.742,2434,2.843,2476,2.691,2881,1.549,2923,2.475,3680,5.141,3810,2.198,4350,3.67,4476,5.208,4510,2.505,4662,2.905,7203,2.738,8130,2.905,8169,3.582,8228,8.179,8232,3.582,8240,6.5,8258,3.396,8270,5.724,8300,3.582,8482,3.582,9813,3.582,10212,3.865,10213,6.176,10214,3.865]],["t/3400",[2,1.886,5,1.513,12,1.474,33,2.318,35,2.779,72,1.501,90,1.684,97,1.415,117,0.774,150,1.908,154,3.194,168,1.53,175,3.375,178,2.215,190,2.264,210,1.517,216,2.39,228,4.747,240,1.041,245,1.799,258,1.751,262,2.137,267,1.73,271,2.602,279,3.143,285,2.048,296,2.277,315,4.352,330,2.998,398,2.602,406,3.507,411,1.993,412,1.564,419,3.937,421,3.235,422,3.569,423,2.587,427,3.487,452,2.058,461,2.36,466,3.011,506,2.472,521,3.048,526,4.119,527,2.866,538,1.455,544,2.303,553,2.438,562,1.872,578,2.527,607,1.257,618,2.508,630,2.508,732,2.224,756,2.169,764,1.946,802,3.348,831,3.448,834,1.711,910,2.752,923,1.204,939,3.864,961,3.052,964,2.566,980,1.995,985,2.901,987,2.523,1003,3.681,1008,2.928,1066,2.264,1071,2.39,1091,2.566,1109,2.936,1120,2.49,1125,2.169,1168,2.869,1177,1.521,1191,3.011,1332,2.239,1348,3.529,1380,3.096,1401,6.115,1418,1.858,1440,3.052,1449,2.303,1471,2.277,1641,3.623,1700,4.25,2130,3.011,2154,2.375,2230,2.048,2304,2.048,2396,4.159,2429,2.936,2434,3.374,2484,2.7,2501,3.447,2703,3.011,2770,1.97,2803,3.623,2899,3.863,3012,5.952,3108,3.733,3256,3.411,4100,2.936,4476,6.534,4503,3.096,4631,3.374,6468,3.864,6867,3.308,7496,4.25,7905,3.447,8040,6.206,8179,4.029,8437,4.029,8577,3.864,9542,6.206,9964,5.436,10206,6.547,10207,4.25,10208,4.029,10215,4.586,10216,4.586,10217,4.586,10218,4.586,10219,4.586,10220,4.586,10221,4.586]],["t/3403",[10,3.653,11,4.189,117,1.431,297,2.953,408,5.663,489,4.051,555,3.642,652,4.749,867,3.098,1070,5.043,1205,4.567,1214,5.232,1331,4.053,1924,4.332,8352,7.726,10222,10.04,10223,10.04]],["t/3405",[7,2.717,11,3.674,117,1.516,489,3.553,524,6.214,555,3.863,969,5.318,1214,5.551,1546,6.819,1711,6.007]],["t/3408",[1,2.26,11,3.189,33,3.034,43,3.216,117,1.013,123,2.846,227,5.547,287,2.502,297,3.395,408,5.215,531,4.59,652,4.373,668,3.449,821,6.336,1009,4.112,1125,4.373,1158,6.802,1176,7.115,1205,4.206,1256,6.669,1331,3.733,1388,7.791,1489,6.055,1711,5.215,1805,6.336,1847,6.802,2171,3.94,2923,5.919,8352,7.115,9527,8.569]],["t/3410",[4,3.94,17,4.157,24,4.63,47,3.39,123,2.904,139,2.774,169,4.291,259,1.779,285,4.213,668,3.519,742,5.605,775,2.761,879,5.455,980,5.086,1158,6.939,1187,4.531,1952,5.553,1967,5.836,2123,5.605,2182,5.409,2522,6.681,2550,10.338,2557,6.464,2923,6.039,2998,6.804,8189,7.089]],["t/3413",[0,4.862,1,2.7,2,3.546,5,2.366,7,2.199,43,2.999,50,5.66,115,2.973,117,0.945,139,2.535,210,3.654,240,2.507,245,4.333,259,1.626,271,3.175,287,2.332,398,3.175,487,3.43,513,4.75,525,5.483,526,3.216,627,3.751,654,3.493,775,2.523,1125,4.077,1140,4.862,1177,2.86,1214,4.492,1598,7.264,1654,7.264,1987,4.943,2703,5.66,3652,6.341,4169,4.75,4320,5.908,8998,7.989,9347,7.989,9633,7.574]],["t/3415",[1,1.951,5,2.25,7,2.036,11,2.753,12,3.376,21,2.294,43,2.777,83,1.576,95,3.971,115,4.304,259,2.353,287,2.16,469,4.539,487,4.18,489,2.662,525,5.215,526,2.978,538,2.532,560,3.488,627,5.11,630,4.365,654,3.234,668,2.978,740,3.665,987,2.851,991,3.503,1040,7.013,1072,5.308,1159,5.475,1168,4.993,1178,7.896,1351,4.886,1484,6.306,2215,5.389,8074,6.306,8402,8.048,9047,6.496,9916,7.013,10224,7.981]],["t/3417",[10,3.789,11,3.592,24,5.112,267,2.551,287,2.818,496,5.654,582,5.738,621,3.041,654,4.22,740,5.7,908,3.848,987,3.72,1024,4.715,4282,7.376,10225,10.413]],["t/3419",[5,1.719,10,2.921,11,2.769,41,3.618,83,1.585,117,1.291,139,3.101,164,3.277,259,1.514,267,1.966,318,7.366,537,5.905,557,2.967,621,3.08,641,5.343,665,4.914,688,5.686,740,5.965,778,8.851,802,4.326,952,5.905,967,5.021,1003,5.495,1056,4.684,1200,5.606,1208,3.669,1302,4.771,1807,3.877,1829,3.302,1924,3.463,2032,4.008,2520,6.342,3214,6.033,3670,5.79,4397,6.177,5479,7.469,8211,6.534,10226,8.027]],["t/3421",[2425,6.363]],["t/3423",[7,2.083,22,3.108,83,1.613,91,3.769,117,1.169,264,3.805,267,2.612,318,6.672,398,3.009,470,2.502,473,2.402,510,3.115,560,3.569,571,4.032,607,2.239,627,4.641,740,5.782,778,6.139,802,2.825,923,2.145,976,6.748,1003,4.256,1015,4.032,1082,4.901,1140,4.607,1208,3.733,1235,6.453,1607,3.25,1749,4.724,1829,3.36,1839,7.57,2010,5.109,2449,4.901,2785,6.139,3214,8.016,5479,8.918,7906,6.883,9688,6.883,10227,10.665]],["t/3425",[259,2.45,2174,5.676,8992,9.156,8993,9.156]],["t/3427",[2425,6.363]],["t/3429",[44,1.342,83,1.491,85,2.136,86,2.296,88,3.501,90,3.719,96,3.986,156,1.835,259,2.401,287,3.091,414,2.746,568,4.943,954,7.304,1118,7.501,1199,5.676,1295,5.349,1398,3.647,1455,4.294,1831,6.146,1841,3.719,2026,5.555,2171,3.218,2174,5.563,2359,6.199,2360,5.175,2380,3.518,2492,5.098,2723,5.21,3071,4.042,3506,5.173,3528,5.811,3600,5.175,3932,5.098,4297,5.098,4600,5.806,5012,5.555,8542,5.098,8636,6.363,8644,6.363,8645,6.363,8646,6.363,10228,10.126]],["t/3431",[44,1.948,76,4.134,85,2.408,86,3.332,88,3.948,90,4.024,96,4.314,259,2.066,287,2.304,527,4.03,568,5.349,954,7.904,985,2.552,998,2.498,1131,6.727,1146,4.467,1199,6.4,1295,6.031,1398,4.112,1812,4.354,2174,5.294,2191,5.213,2492,5.749,2723,4.381,3506,4.961,4600,6.158,5498,5.536,8975,6.931,8982,7.175]],["t/3434",[1,2.7,2,3.546,5,2.366,21,2.477,25,4.435,30,1.764,83,1.702,117,1.211,210,3.654,228,4.75,240,2.507,318,5.392,463,3.766,508,4.985,589,6.341,764,3.659,802,3.82,903,5.454,998,2.529,1070,4.329,1211,3.629,1218,4.522,1233,5.819,1257,5.737,1295,6.106,1521,4.902,1678,4.329,1816,3.751,1979,5.66,2496,5.66,3063,6.633,3670,6.218,8402,7.569,8483,6.479,9603,7.574,10188,7.989]],["t/3436",[1,2.02,17,3.642,30,1.691,43,4.155,115,4.12,168,2.757,210,2.734,220,5.19,318,6.723,411,1.912,468,8.668,526,3.083,533,5.579,557,4.674,575,3.386,648,4.393,739,5.008,802,4.733,1125,3.909,1140,6.062,1170,3.522,1218,4.335,1330,6.216,1530,6.271,2305,4.52,2769,5.755,4426,8.748,8402,7.366]],["t/3438",[1,2.928,2,4.438,5,2.566,7,2.12,11,2.867,12,2.672,43,2.892,115,4.131,117,1.183,139,2.445,164,3.394,210,2.751,259,2.259,271,3.062,318,5.2,411,1.924,418,4.175,474,3.062,525,4.127,526,3.102,607,2.279,649,3.648,802,2.876,892,4.305,991,3.648,1159,4.332,1180,4.58,1218,4.361,1589,5.2,1599,3.433,1640,3.713,1910,4.895,2133,5.533,2182,4.767,2183,6.116,2449,6.473,7716,6.766,8402,7.394]],["t/3440",[1,2.353,5,2.535,186,3.901,197,4.485,214,3.359,229,4.037,240,2.185,470,3.626,575,3.945,607,2.639,814,3.247,923,2.528,987,3.439,1125,4.553,1137,7.835,1399,4.699,1401,6.814,1640,4.3,2123,5.721,2619,4.649,3250,7.235,10198,8.922]],["t/3442",[11,3.067,115,3.886,117,0.975,216,4.635,228,4.9,297,2.615,318,7.047,468,8.909,508,6.516,557,4.804,775,2.603,802,3.076,1134,5.84,1208,4.065,1218,4.665,1265,7.213,1330,7.151,1382,6.193,1571,8.243,1806,10.064,7128,6.543,8402,6.095,8962,7.494,9916,7.814,10197,7.814]],["t/3444",[11,3.619,24,5.15,194,3.965,267,2.57,562,4.283,732,3.303,781,2.654,914,4.546,991,4.604,998,3.078,1029,5.966,1330,6.068,1530,6.121,8962,10.507]],["t/3446",[5,1.929,50,7.457,145,5.081,219,2.972,267,2.782,468,7.784,470,3.81,473,2.649,557,4.197,802,4.302,809,2.933,875,2.902,987,3.218,1140,6.406,1177,2.988,1187,4.327,1330,5.21,1382,6.273,1485,5.839,1552,7.186,1640,4.023,1806,9.244,2123,5.353,2200,7.915,2234,6.273,2877,7.116]],["t/3448",[259,2.174,2174,5.037,8992,9.382]],["t/3450",[1778,5.424,1924,4.973,2425,6.258]],["t/3453",[1,2.069,5,2.338,11,2.919,83,2.385,95,3.199,153,4.774,168,2.823,219,2.793,240,1.921,243,2.195,258,3.231,259,2.058,265,4.595,297,2.489,304,4.736,351,4.562,411,2.953,438,4.066,443,5.352,489,2.823,526,3.158,528,4.066,529,2.962,607,2.32,626,4.181,629,4.202,781,2.761,993,3.264,1014,3.983,1028,4.109,3098,5.078,3206,6.686,3345,5.182,3715,6.105,10229,7.844]],["t/3455",[1,2.324,5,2.037,7,3.144,21,1.978,83,2.668,117,0.755,139,3.203,187,3.08,210,2.278,228,5.239,240,1.563,287,1.863,304,6.094,398,2.536,411,2.52,438,6.276,443,4.568,454,4.355,528,3.307,553,3.66,555,3.95,557,2.544,593,4.582,602,4.306,614,6.228,626,4.882,923,1.808,993,3.666,1030,5.676,1715,2.789,2185,4.794,3715,4.966,3905,8.065,8125,5.603,10145,6.38,10230,6.884]],["t/3457",[1,1.596,7,3.085,83,1.29,139,1.921,178,3.154,218,3.198,219,3.494,226,5.634,228,3.599,240,2.404,243,1.694,258,3.499,265,3.546,287,2.866,297,1.921,304,5.129,351,5.709,411,2.657,438,4.403,443,5.258,470,2.001,510,1.907,521,2.818,526,3.42,528,3.137,533,4.409,553,3.472,555,2.369,614,5.35,621,1.907,626,2.502,629,3.242,630,5.013,760,3.154,764,3.89,781,2.679,820,2.333,831,3.188,875,2.104,963,3.919,1097,2.676,1120,3.546,1125,3.089,1146,3.426,1213,3.654,1277,3.449,1692,5.738,1790,2.971,1808,4.711,1987,3.745,2187,4.548,3098,5.5,3312,4.805,3715,8.723,9505,5.738,9987,6.053]],["t/3459",[7,2.959,10,2.433,11,2.306,20,3.014,83,1.84,117,0.733,139,3.412,206,3.657,210,2.212,219,2.206,226,4.997,240,2.115,243,2.781,258,3.557,287,2.521,297,1.966,304,5.214,351,5.023,411,2.684,438,5.572,443,5.116,454,4.231,457,3,463,2.28,526,3.477,538,2.121,544,3.358,555,3.38,626,4.672,629,3.32,768,3.802,781,2.713,831,3.264,875,2.155,887,4.137,892,3.462,964,3.742,993,4.136,1019,3.1,1028,3.247,1146,3.507,1181,3.399,1201,5.635,1267,3.974,1286,3.531,1398,4.5,1774,4.231,1958,3.63,2062,2.922,2820,5.875,3345,5.705,3715,4.823,6110,5.875]],["t/3461",[1,2.839,7,3.155,30,2.377,117,0.855,139,2.295,218,2.723,226,4.822,240,1.771,258,3.951,287,2.112,304,4.367,351,4.207,391,2.227,411,2.978,438,3.749,443,5.747,473,2.295,526,3.862,555,2.83,578,5.703,579,2.884,612,2.279,614,3.943,626,3.964,629,3.874,781,1.974,991,3.425,993,4.478,1146,4.093,1205,3.55,1271,4.093,1953,4.882,1988,2.857,2316,3.517,3337,5.053]],["t/3463",[7,2.771,10,3.952,30,1.402,44,1.218,139,2.015,168,3.161,187,2.219,210,2.266,214,2.39,219,2.26,226,4.415,228,5.221,239,4.482,258,2.615,265,3.719,287,1.854,411,3.124,443,5.789,555,2.485,606,4.033,626,5.171,809,2.23,831,3.344,887,4.238,964,3.833,989,6.229,993,2.642,1072,3.461,1127,4.334,1141,5.412,1205,3.116,1296,6.349,1398,5.246,1715,2.776,1917,5.271,1987,3.928,2483,5.576,2872,4.285,3076,6.599,3345,4.194,3715,8.455,4429,4.852,6110,6.019,9978,6.349]],["t/3465",[7,2.813,11,2.672,13,3.049,30,1.585,36,2.833,47,1.861,73,1.541,83,2.177,93,2.413,117,0.849,139,3.029,148,1.976,168,1.728,214,3.238,219,3.399,226,5.138,240,1.176,258,1.977,265,2.812,297,3.403,411,2.383,438,4.948,443,4.625,454,3.277,457,4.164,470,1.587,488,1.747,538,1.643,544,2.601,553,4.118,555,1.879,571,2.557,575,2.122,579,1.914,621,1.513,626,5.112,649,2.273,764,2.198,781,1.96,783,3.277,875,1.669,977,3.668,989,2.97,993,3.972,1017,3.24,1019,2.401,1028,2.515,1029,2.945,1055,1.951,1127,3.277,1146,5.403,1151,2.97,1204,2.114,1286,4.091,1352,3.401,1398,4.974,1715,3.139,1829,2.13,1848,3.985,1908,4.216,1953,3.24,2010,3.24,2062,2.263,2117,3.81,2196,4.216,3062,4.8,3076,3.607,3098,3.108,3465,3.736,3715,5.588,3905,5.872,4394,3.893,6863,4.216,8123,7.18,8125,4.216,9099,4.092,9794,4.216,10231,5.179,10232,5.179,10233,5.179,10234,5.179,10235,5.179]],["t/3468",[7,1.876,41,4.483,73,2.96,83,2.384,138,3.893,228,4.052,263,3.092,264,4.634,265,3.992,287,1.99,411,2.919,412,2.508,443,5.748,571,3.63,611,4.171,619,4.525,626,4.981,764,4.784,831,3.59,834,2.744,871,4.083,923,1.931,1015,3.63,1019,3.409,1282,5.41,1398,3.551,1607,2.926,2198,4.828,2223,4.652,2380,5.251,2723,3.784,5564,6.461,5570,6.461,5896,6.817,9935,6.461,10236,7.353,10237,7.353]],["t/3470",[30,2.196,73,3.194,156,2.608,218,3.745,264,5,297,3.156,411,2.483,438,5.155,626,4.111,824,8.735,1028,5.211,1146,5.63]],["t/3472",[7,1.406,10,0.562,11,0.533,13,0.91,15,0.776,22,0.588,30,0.316,44,2.12,73,0.836,83,1.218,85,1.092,91,1.296,97,0.867,117,0.308,123,0.865,136,0.69,138,0.477,139,1.135,148,0.394,154,1.076,156,0.938,164,1.576,165,1.212,168,1.288,196,0.84,198,0.763,213,1.666,217,0.865,218,0.539,219,0.51,226,3.144,228,2.127,240,0.638,243,1.429,255,0.937,258,3.097,259,0.292,263,0.481,264,1.309,267,1.163,276,0.751,316,0.99,351,1.514,398,0.569,411,2.56,438,0.743,443,5.001,462,0.886,470,1.183,483,0.588,488,0.521,489,0.516,491,0.661,514,0.776,521,1.212,526,1.048,544,0.776,553,0.822,555,1.4,557,0.571,570,1.029,575,0.633,579,0.571,596,1.044,598,0.717,607,0.424,611,3.932,623,0.927,624,0.772,626,4.335,629,1.394,643,1.137,649,1.233,697,0.727,720,2.569,744,0.822,748,0.592,757,1.864,764,0.656,768,0.879,781,0.711,867,0.477,870,0.927,875,1.776,885,0.91,891,1.371,908,2.681,923,1.014,987,1.003,993,2.125,997,1.375,1017,0.967,1018,1.002,1028,1.364,1029,0.879,1055,1.058,1072,0.781,1092,2.026,1109,0.99,1146,3.539,1150,1.044,1203,3.084,1205,0.703,1278,0.816,1307,0.839,1344,2.143,1351,0.946,1398,0.746,1421,2.319,1449,0.776,1465,0.697,1480,0.865,1615,0.806,1618,0.617,1647,1.639,1722,0.713,1775,3.142,1789,1.015,1807,1.356,1808,1.115,1838,0.902,1866,2.026,1873,1.015,1934,1.548,1958,0.839,2003,1.044,2031,1.258,2169,1.162,2181,1.029,2196,2.286,2350,0.956,2577,1.258,2832,1.258,3098,0.927,3319,0.978,3345,0.946,3359,1.87,3501,1.095,3815,1.358,3905,0.978,4502,1.015,4662,2.111,5501,1.358,5502,1.433,5503,1.433,5504,1.433,5505,11.528,5506,11.13,5507,3.578,5508,1.433,5509,1.433,5510,1.433,5511,1.433,5512,1.433,5513,3.578,5514,1.433,5515,8.922,5516,2.603,5517,1.433,5518,11.13,5519,1.433,5520,1.433,5521,1.433,5522,1.433,5523,8.161,5524,1.433,5525,1.433,5526,1.433,5527,1.433,5528,1.433,5529,8.438,5530,1.433,5531,6.725,5532,9.332,5533,3.578,5534,3.578,5535,1.433,5536,1.433,5537,1.433,5538,1.433,5539,1.433,5540,1.433,5541,1.433,5542,1.433,5543,1.433,5544,1.433,5545,1.433,5546,1.433,5547,1.433,5548,1.433,5549,1.433,5550,1.137,5551,1.433,5552,1.433,5553,1.433,5554,6.495,5555,2.468,5556,2.603,5558,1.433,5559,1.433,5560,11.053,5561,1.433,5562,1.433,5563,1.189,5564,1.358,5565,10.597,5566,1.433,5567,1.433,5568,1.433,5569,1.433,5570,1.358,5571,1.433,5572,1.433,5573,1.433,5574,1.358,5575,1.433,5576,3.578,5577,1.433,5578,1.433,5579,3.578,5580,1.433,5581,1.433,5582,1.433,5583,1.433,5584,1.433,5585,1.433,5586,1.433,5587,1.433,5588,1.433,5589,1.433,5590,1.433,5591,1.433,5592,5.719,5593,1.433,5594,1.433,5595,1.433,5596,1.433,5597,1.433,5598,1.433,5599,1.433,5600,1.433,5601,1.433,5602,1.433,5603,1.433,5604,7.856,5605,1.433,5606,1.433,5607,1.433,5608,1.433,5609,1.433,5610,1.433,5611,1.433,5612,1.433,5613,4.402,5614,1.433,5615,1.433,5616,1.433,5617,1.433,5618,1.433,5619,1.433,5620,1.433,5621,1.433,5622,1.433,5623,1.433,5624,1.433,5625,1.433,5626,1.433,5627,1.433,5628,1.433,5629,1.433,5630,1.433,5631,1.433,5632,1.433,5633,1.433,5634,1.433,5635,1.433,5636,1.433,5637,1.433,5638,1.433,5639,1.433,5640,1.433,5641,1.433,5642,1.433,5899,1.433,7928,1.258,8114,1.095,8124,1.433,10238,1.546,10239,3.86,10240,1.546,10241,1.546,10242,1.546,10243,1.546,10244,1.546,10245,1.546,10246,1.546]],["t/3475",[11,3.01,22,3.321,93,4.066,115,3.01,139,2.567,198,4.308,206,4.773,226,4.066,266,3.75,320,4.672,411,2.019,443,4.668,544,4.383,584,4.046,595,5.809,626,4.695,649,4.885,993,5.142,1075,5.047,1127,5.522,1208,3.989,1398,5.919,1421,5.434,2130,5.73,3028,6.815,3345,6.815,10247,8.727,10248,7.668,10249,7.668]],["t/3477",[21,2.639,83,2.27,93,4.279,139,2.701,240,2.085,243,2.982,266,3.946,320,4.917,411,2.125,443,3.852,488,3.098,513,5.061,531,4.56,542,6.113,626,4.807,735,4.883,809,2.991,1148,6.506,1203,5.139,1398,5.552,1421,5.612,1877,7.74,2359,5.623,3098,5.511,3905,5.811,4614,6.903,8531,8.07,9880,7.476]],["t/3479",[10,3.32,83,1.802,116,4.231,117,1,208,3.688,245,3.58,248,4.954,287,2.469,288,5.232,297,2.684,411,2.649,438,4.383,443,5.503,474,3.362,710,6.354,787,3.827,980,3.97,1146,4.786,1398,4.407,1404,5.842,1614,5.708,1961,4.43,2363,5.915,3337,4.455,3465,6.582,7893,7.427,8390,8.259,9220,6.463]],["t/3482",[7,0.758,10,1.812,19,2.579,21,2.161,22,1.895,28,1.484,29,4.209,44,2.105,51,4.207,52,5.238,83,1.654,93,4.223,96,1.17,117,0.705,123,0.915,138,0.917,139,0.874,156,1.828,178,1.435,187,0.963,198,1.467,201,3.87,207,1.859,213,1.282,214,1.037,217,1.663,219,0.981,226,1.385,228,4.616,229,1.013,240,1.459,243,1.292,258,1.901,263,0.924,265,1.613,287,2.453,304,5.072,320,4.026,351,1.602,398,1.095,408,1.676,411,3.079,421,1.116,438,3.613,443,5.454,462,4.313,470,1.526,473,0.874,487,2.993,488,1.68,489,2.509,506,1.602,510,0.868,526,2.398,528,1.427,531,1.475,555,2.728,557,1.098,560,1.299,570,1.978,571,1.467,575,1.218,578,2.744,594,1.819,598,1.378,612,0.868,613,1.484,623,1.783,626,4.869,629,1.475,735,1.58,739,1.801,781,1.26,822,1.191,831,4.09,870,2.988,875,2.424,890,2.309,891,1.451,961,1.978,976,1.88,978,1.572,987,1.779,991,1.304,993,2.901,998,0.872,1014,1.398,1019,1.378,1029,1.69,1055,1.12,1148,2.105,1181,1.51,1205,1.352,1211,1.251,1214,2.595,1249,1.559,1332,3.672,1347,4.876,1364,1.903,1398,3.104,1418,1.204,1439,3.895,1618,1.187,1722,2.298,1908,2.419,1924,5.019,2010,1.859,2168,2.186,2330,2.287,2359,1.819,2360,3.413,3028,3.049,3068,2.287,3070,1.926,3071,3.441,3098,2.988,3103,2.037,3337,1.451,3345,1.819,3428,2.105,3905,3.151,4168,2.105,4866,2.419,5418,2.419,8069,2.348,8112,4.197,8531,2.611,8634,3.743,9676,4.616,9703,2.754,9880,2.419,9935,2.611,10190,6.972,10229,2.754,10248,4.376,10249,2.611,10250,7.522,10251,4.98,10252,2.972,10253,2.972,10254,2.972,10255,2.754,10256,2.754]],["t/3484",[21,3.684,44,2.412,83,2.531,117,0.939,138,2.644,187,2.775,207,5.359,240,1.945,243,2.222,421,3.217,438,5.284,443,3.593,488,2.889,531,4.253,557,3.166,626,3.281,735,4.554,993,3.304,1148,6.068,1205,3.897,1398,5.312,3028,6.734,3337,4.182,3345,5.245,3905,5.42,9880,6.973,10248,9.665,10249,7.528,10255,7.94,10256,7.94]],["t/3487",[21,3.259,564,6.617,1187,5.447,1593,9.23,3797,6.617]],["t/3489",[97,4.008,266,4.834,3056,9.479,9022,9.156,9743,8.887]],["t/3491",[22,4.28,138,3.472,470,3.446,1709,9.156,1924,4.854,2445,8.887]],["t/3493",[471,6.519,536,7.475,812,6.85,1055,4.171,1208,5.06,1709,9.011,1924,5.553]],["t/3495",[470,3.474,473,3.335,520,5.872,909,7.016,1636,8.523]],["t/3497",[21,3.312,621,3.366,892,5.969]],["t/3500",[1593,9.539]],["t/3502",[97,4.008,266,4.834,3056,9.479,9022,9.156,9743,8.887]],["t/3504",[2445,9.259]],["t/3506",[621,3.423]],["t/3508",[266,5.479,412,4.349,621,4.07,834,4.758]],["t/3510",[94,3.952]],["t/3512",[287,3.069,1028,5.506,1585,10.511,1647,6.617,8625,8.523]],["t/3514",[21,3.312,621,3.366,892,5.969]],["t/3516",[208,3.398,621,3.366,1812,5.894]],["t/3518",[0,2.814,1,1.841,2,2.052,3,1.23,4,1.244,5,1.069,7,0.76,11,2.598,14,1.583,15,1.496,25,1.532,30,0.609,51,1.496,76,1.446,85,1.411,86,1.517,88,2.313,115,1.027,117,0.326,126,1.164,138,0.919,156,1.212,193,1.097,196,1.492,208,2.22,209,1.211,214,1.039,219,0.983,240,0.676,243,1.294,259,2.671,264,1.387,266,1.28,287,3.205,296,1.702,304,3.602,315,5.881,318,3.121,330,1.264,391,0.85,400,2.652,401,1.514,411,0.689,414,1.353,427,1.47,438,1.431,443,1.249,461,1.532,469,2.837,487,4.436,488,2.171,489,0.993,495,1.249,526,1.111,527,2.506,528,1.431,544,1.496,555,1.81,557,1.101,571,1.47,607,1.765,611,1.249,627,1.296,636,1.532,637,1.542,652,3.045,688,2.109,732,1.571,754,2.074,781,1.262,802,1.726,809,0.97,814,1.683,822,1.194,840,1.605,985,1.495,998,0.874,1013,1.408,1055,1.122,1110,1.884,1118,1.955,1125,1.408,1131,3.575,1146,1.562,1271,1.562,1330,1.722,1331,2.599,1457,1.722,1546,1.907,1586,1.496,1778,1.401,1809,2.191,1812,1.523,1829,1.225,1841,2.364,1908,2.424,1924,3.619,1931,2.292,1967,1.487,2006,1.355,2060,1.505,2121,1.823,2171,1.269,2173,7.416,2174,6.001,2337,1.572,2380,1.387,2519,5.37,2666,1.738,2723,3.876,2775,2.109,2776,2.109,3252,1.629,3259,1.863,3337,1.454,3506,2.259,3600,2.041,4265,1.982,5498,2.52,5499,2.509,6246,2.238,7130,2.353,7913,2.292,8352,2.292,8542,2.01,8621,2.509,8623,2.353,8624,2.292,8625,2.238,8626,2.617,8627,2.509,8628,2.509,8629,2.617,8635,4.061,8636,2.509,8643,3.839,8644,2.509,8645,2.509,8646,2.509,8647,2.353,8648,2.617,8649,2.617,8650,2.617,8651,2.617,8971,2.617,8972,2.617,8973,2.76,8974,2.617,8975,2.424,8976,2.617,8979,2.617,8980,2.617,8982,2.509,8983,2.617,8984,2.617,8985,2.617,8986,2.041,8987,2.617,8988,2.617,8989,2.617,8990,2.617,8991,2.617,8992,2.424,8993,2.424,8994,2.617,8995,2.76,10257,2.978]]],"invertedIndex":[["",{"_index":44,"t":{"4":{"position":[[536,1]]},"10":{"position":[[1056,1],[1078,1],[1103,1],[1125,1],[1148,1],[1168,1],[1191,1],[1354,1],[1478,2],[1517,1]]},"18":{"position":[[312,4]]},"23":{"position":[[411,1]]},"25":{"position":[[638,1],[775,1]]},"27":{"position":[[155,1],[255,1],[330,1],[418,1],[490,1],[813,1],[899,1],[984,1],[1163,1],[1252,1],[1339,1],[1524,1],[1605,1],[1715,1],[1878,1],[1960,1],[3160,1],[3245,1],[3350,1]]},"30":{"position":[[208,1]]},"32":{"position":[[138,1],[219,1],[294,1]]},"65":{"position":[[85,1]]},"87":{"position":[[167,1],[179,1]]},"105":{"position":[[723,1],[747,1],[945,1],[967,1],[978,1],[980,1],[1007,2],[1102,1],[1168,3],[1172,2],[1238,1],[1274,1],[1298,2],[1424,2],[1427,1],[1443,1],[1479,2],[1522,1],[1543,1],[1591,2],[1636,1],[1690,2],[1739,1],[1776,1],[1821,2],[1876,1],[1934,1],[1952,2],[1955,2],[2010,1],[2086,2],[2142,1],[2199,2]]},"114":{"position":[[96,1],[98,1],[218,1],[220,1],[805,1],[861,1]]},"129":{"position":[[53,1]]},"131":{"position":[[280,1],[380,1],[482,1],[484,2],[487,2],[490,1],[525,1],[726,1]]},"139":{"position":[[473,3],[513,3],[535,3]]},"141":{"position":[[364,2],[383,2],[506,3],[537,3],[560,3]]},"143":{"position":[[197,3],[212,3],[230,3],[247,3],[263,3],[283,3],[293,3],[313,3],[330,3],[357,1],[371,3],[401,3],[431,3],[564,3],[579,3],[597,3],[614,3]]},"147":{"position":[[431,2],[448,3],[474,1],[495,3]]},"158":{"position":[[45,1],[70,1]]},"166":{"position":[[579,1]]},"168":{"position":[[51,1],[88,1],[316,1]]},"170":{"position":[[130,1],[284,1],[743,1],[782,1],[1340,1],[1640,1]]},"174":{"position":[[58,1]]},"176":{"position":[[63,1],[358,1],[484,1]]},"178":{"position":[[239,1],[415,1],[583,1],[1102,3],[1686,1]]},"191":{"position":[[12,1],[14,1],[38,1],[40,1],[180,1],[182,1],[207,1],[209,1],[239,1],[241,1],[339,1],[341,1],[422,1],[424,1],[445,1],[447,1]]},"193":{"position":[[13,1],[15,1],[53,1],[55,1],[121,1],[123,1],[170,1],[172,1],[220,1],[222,1],[294,1],[296,1],[333,1],[335,1],[358,1],[360,1],[383,1],[385,1],[425,1],[427,1],[496,1],[498,1],[574,1],[576,1],[732,1],[734,1],[765,1],[767,1]]},"195":{"position":[[12,1],[14,1],[98,1],[100,1],[143,1],[145,1]]},"198":{"position":[[130,1]]},"202":{"position":[[12,1],[14,1],[117,1],[119,1],[209,1],[211,1],[264,1],[266,1],[342,1],[344,1],[415,1],[417,1],[442,1],[444,1],[497,1],[499,1],[645,1],[647,1]]},"204":{"position":[[376,1]]},"208":{"position":[[44,1]]},"210":{"position":[[12,1],[14,1],[395,1],[397,1],[485,1],[487,1],[532,1],[534,1],[576,1],[618,1],[620,1],[655,1],[657,1],[716,1],[718,1],[802,1],[804,1],[844,1],[846,1],[947,1],[949,1],[984,1],[986,1],[1007,1],[1009,1]]},"212":{"position":[[89,1]]},"214":{"position":[[12,1],[14,1],[53,1],[55,1],[95,1],[97,1],[149,1],[151,1],[185,1],[187,1],[287,1],[289,1],[357,1],[359,1],[388,1],[390,1],[404,1]]},"225":{"position":[[12,1],[14,1],[46,1],[48,1],[143,1],[145,1],[190,1],[192,1],[275,1],[277,1],[342,1],[344,1]]},"227":{"position":[[12,1],[14,1],[46,1],[48,1],[69,1],[71,1],[142,1],[144,1],[285,1],[294,1],[308,1],[310,1],[381,1],[383,1],[404,1],[406,1],[444,1],[465,1],[467,1],[489,1]]},"229":{"position":[[12,1],[14,1],[30,1],[32,1],[98,1],[100,1],[140,1],[142,1],[198,1],[200,1],[229,1],[243,1],[245,1],[281,1],[283,1],[311,1],[313,1],[333,1],[335,1],[352,1],[354,1]]},"231":{"position":[[12,1],[14,1],[72,1],[74,1],[102,1],[104,1],[161,1],[163,1],[216,1],[218,1],[251,1],[253,1],[283,1],[285,1],[323,1],[325,1],[345,1],[357,1],[359,1],[378,1],[380,1],[401,1],[403,1],[415,1],[417,1],[475,1],[477,1],[531,1],[533,1]]},"233":{"position":[[12,1],[14,1],[85,1],[87,1],[123,1],[125,1],[155,1],[157,1],[192,1],[194,1],[248,1],[250,1],[274,1],[276,1]]},"235":{"position":[[67,1]]},"251":{"position":[[168,1]]},"257":{"position":[[190,1]]},"263":{"position":[[61,3],[256,3]]},"284":{"position":[[184,1],[724,1],[810,3],[871,3],[920,3],[940,3],[949,1],[977,1],[998,1],[1015,3],[1039,2],[1150,3],[1188,2],[1203,1]]},"286":{"position":[[326,3],[435,2]]},"302":{"position":[[1671,2]]},"317":{"position":[[378,1],[415,1],[417,3],[439,1],[489,3],[503,3],[531,1],[564,3],[578,3]]},"319":{"position":[[235,6],[272,3]]},"323":{"position":[[114,1],[437,1],[528,1],[600,1]]},"325":{"position":[[372,1],[2606,1],[3567,3],[3595,4],[6487,1],[6790,1],[7768,1],[7869,2],[7896,3],[7900,1]]},"368":{"position":[[277,1]]},"381":{"position":[[262,1],[335,1],[426,1],[495,1],[548,1],[596,1],[679,1],[692,1],[701,1],[775,1],[860,1],[934,1],[1017,1],[1031,1],[1039,1],[1100,1],[1107,1],[1254,1],[1352,1],[1359,1],[1367,1],[1377,1],[1462,1]]},"393":{"position":[[1320,1],[1391,3],[1413,3],[1431,3]]},"404":{"position":[[124,3],[627,3]]},"407":{"position":[[292,1]]},"409":{"position":[[0,1],[30,1]]},"411":{"position":[[39,1]]},"413":{"position":[[688,1]]},"415":{"position":[[119,1]]},"427":{"position":[[444,1],[506,1],[523,1],[571,1],[596,1],[631,1],[662,1],[687,1],[706,1],[1134,1],[1234,1],[1271,1],[1279,1]]},"428":{"position":[[356,1],[1338,1]]},"432":{"position":[[292,1]]},"436":{"position":[[864,1],[924,1],[932,1],[1260,1],[1285,1],[1289,1],[1293,1]]},"440":{"position":[[317,1]]},"442":{"position":[[408,1]]},"467":{"position":[[1201,1],[1236,1],[1249,1],[1356,1],[1358,1],[1366,1],[1374,1],[1376,1],[1389,1],[1496,1],[1498,1],[1507,1],[1529,1],[1531,1],[1539,1],[1646,1],[1648,1],[1661,1],[1676,1],[1678,1],[1687,1],[1713,1],[1715,1],[1726,1],[1733,1],[1735,1],[1745,1],[1757,1],[1759,1],[1772,1],[1879,1],[2132,1],[2176,1]]},"471":{"position":[[624,1],[647,1],[664,1],[748,1],[773,1],[808,1],[924,1],[1140,1],[1164,2],[1574,1],[1591,1],[1639,1],[1664,1],[1699,1],[1730,1],[1755,1],[1774,1]]},"472":{"position":[[2096,1],[2155,1],[2605,3]]},"474":{"position":[[189,1],[347,1],[510,1],[670,1],[825,1],[1041,1]]},"479":{"position":[[38,3]]},"485":{"position":[[253,2],[316,2],[497,1],[530,1],[744,1]]},"487":{"position":[[749,2],[909,2],[1148,2],[1196,2],[1656,2],[1851,2],[1953,2],[2097,2],[2381,2],[2484,2],[3321,1],[3323,1],[3422,1],[3431,1],[3461,2],[4369,2],[4378,2]]},"491":{"position":[[416,3],[431,3],[445,1],[447,3],[464,1],[466,3],[488,1],[490,3],[503,1],[505,3],[519,1],[521,1],[523,3]]},"497":{"position":[[790,1],[792,1],[852,1],[867,1]]},"499":{"position":[[387,1],[404,3],[412,4],[1433,4],[2171,4]]},"503":{"position":[[839,4]]},"509":{"position":[[558,1],[590,1]]},"513":{"position":[[638,1],[1309,4],[1992,4]]},"521":{"position":[[0,1],[68,1],[132,1],[209,1],[287,1],[368,1],[428,1]]},"557":{"position":[[311,2]]},"590":{"position":[[521,1],[563,1],[734,1],[785,1],[906,2],[985,2],[1281,1],[1523,1],[1620,3],[1806,3]]},"596":{"position":[[247,1],[3022,1],[3039,1],[3059,1]]},"598":{"position":[[1031,1],[1046,1],[1061,1],[1078,1]]},"604":{"position":[[147,2],[5066,2],[5135,2],[6111,2],[6180,2]]},"606":{"position":[[179,3]]},"609":{"position":[[1990,2],[4792,2],[6405,1],[6444,1]]},"615":{"position":[[28,2]]},"627":{"position":[[3096,3]]},"629":{"position":[[489,1]]},"633":{"position":[[3398,3]]},"635":{"position":[[871,2],[1391,1],[1490,1],[1515,1],[1526,1],[2012,2],[2102,1],[2259,2],[2327,2],[2330,1],[2332,4],[2337,1],[2348,2],[2396,1],[2402,1],[2415,1],[2426,1],[2465,1],[2520,2],[2588,2],[2591,1],[2593,4],[2598,1],[2609,2],[2639,1],[2645,1],[2658,1],[2669,1],[2712,1],[2767,2],[2833,2],[2836,1],[2838,4],[2843,1],[2854,2],[2902,1],[2908,1],[2921,1],[2932,1],[2971,1],[3026,2],[3092,2],[3095,1],[3097,4],[3102,1],[3113,2],[3143,1],[3149,1],[3162,1],[3173,1],[3216,1]]},"639":{"position":[[270,1]]},"641":{"position":[[70,1],[72,1],[87,3],[105,3],[188,1],[316,1],[574,1],[833,1],[1591,1],[1769,1],[1843,1],[1878,1],[2027,1],[2039,1]]},"644":{"position":[[93,1],[183,1],[707,1]]},"646":{"position":[[425,1],[643,1],[1066,1],[1068,1],[1140,1],[1389,1],[1838,1],[2080,1]]},"658":{"position":[[171,2],[227,1]]},"660":{"position":[[37,1],[66,1],[93,1],[120,1],[149,1],[415,1],[1213,1],[1406,1],[1452,2],[1461,1],[1531,1],[3075,1],[3268,1],[3417,1]]},"665":{"position":[[5,2]]},"667":{"position":[[610,2],[683,2]]},"669":{"position":[[565,1],[949,1]]},"728":{"position":[[357,1],[510,1]]},"730":{"position":[[450,1],[526,2],[537,85],[623,1],[680,1],[682,1],[714,1],[716,1],[775,1],[777,1],[821,1],[823,1],[860,1],[862,96],[1041,1],[1146,1],[1241,1],[1248,1],[1294,1],[1301,1],[1347,1],[1354,1],[1401,1],[1408,1],[1435,3],[1542,1],[1583,1],[1637,1],[1666,1],[1796,1],[1798,1],[1806,1],[1814,1],[1816,1],[1845,1],[1975,1],[1977,1],[2004,1],[2012,1],[2014,1],[2042,1],[2046,1],[2048,1],[2069,1],[2076,1],[2078,1],[2092,1],[2099,1],[2101,1],[2108,1],[2113,1],[2115,1],[2120,1],[2159,1],[2161,1],[2168,1],[2183,1],[2185,1],[2214,1],[2221,1],[2223,1],[2236,1],[2366,1],[2368,1],[2374,1],[2381,1],[2383,1],[2397,1],[2403,1],[2405,1],[2412,1],[2416,1],[2418,1],[2426,1],[2430,1],[2432,1],[2461,1],[2591,1]]},"732":{"position":[[429,1]]},"738":{"position":[[438,2],[445,1]]},"748":{"position":[[58,1]]},"762":{"position":[[0,1],[486,1]]},"766":{"position":[[31,1]]},"786":{"position":[[267,1],[1197,1],[1244,1],[1323,1]]},"790":{"position":[[378,1],[417,1],[429,1],[473,1],[533,1],[1087,2]]},"796":{"position":[[832,2]]},"798":{"position":[[790,2]]},"819":{"position":[[349,1],[354,1],[384,1],[406,1],[422,1],[441,1],[462,1],[484,1],[502,1],[518,1],[536,1],[559,1],[582,1],[606,1],[628,1],[656,1],[686,1],[700,1],[724,1],[748,1],[768,1],[786,1],[811,1],[836,1],[862,1],[886,1],[918,1],[931,1],[947,1],[969,1],[1005,1],[1039,1],[1067,1],[1105,1],[1159,1],[1213,1],[1267,1],[1297,1],[1308,1],[4037,1],[4097,1],[4114,1],[4137,1],[4172,1],[4174,1],[4181,1],[4189,1],[4194,1],[4196,1],[4213,1],[4236,1],[4271,1],[4273,1],[4282,1],[4296,1],[4331,1],[4333,1],[4343,1],[4365,1],[4400,1],[4402,1],[4410,1],[4430,1],[4465,1],[4467,1],[4484,1],[4503,1],[4505,1],[4507,1],[4524,1],[4547,1],[4582,1],[4613,1],[4691,1],[4702,1],[4728,1],[4763,1],[4765,1],[4772,1],[4780,1],[4785,1],[4787,1],[4798,1],[4824,1],[4859,1],[4861,1],[4870,1],[4884,1],[4919,1],[4921,1],[4931,1],[4953,1],[4988,1],[4990,1],[4997,1],[5023,1],[5058,1],[5060,1],[5071,1],[5090,1],[5092,1],[5094,1],[5105,1],[5131,1],[5166,1],[5216,1],[5299,1],[5310,1],[5331,1],[5366,1],[5368,1],[5375,1],[5383,1],[5388,1],[5390,1],[5401,1],[5422,1],[5457,1],[5459,1],[5468,1],[5482,1],[5517,1],[5519,1],[5529,1],[5550,1],[5585,1],[5587,1],[5598,1],[5619,1],[5654,1],[5994,1],[6164,1],[6499,1],[7077,1],[7136,1],[7146,1],[7168,1],[7203,1],[7205,1],[7212,1],[7220,1],[7225,1],[7227,1],[7237,1],[7259,1],[7294,1],[7296,1],[7305,1],[7319,1],[7354,1],[7356,1],[7366,1],[7387,1],[7422,1],[7424,1],[7434,1],[7456,1],[7491,1],[8128,1],[8188,1],[8198,1],[8220,1],[8255,1],[8257,1],[8264,1],[8272,1],[8277,1],[8279,1],[8289,1],[8311,1],[8346,1],[8348,1],[8357,1],[8371,1],[8406,1],[8408,1],[8418,1],[8440,1],[8475,1],[8477,1],[8487,1],[8509,1],[8544,1]]},"821":{"position":[[414,1],[419,1],[449,1],[471,1],[491,1],[507,1],[526,1],[547,1],[565,1],[577,1],[601,1],[622,1],[646,1],[660,1],[684,1],[698,1],[721,1],[2016,1],[2085,1],[2092,1],[2118,1],[2177,1],[2184,1],[2218,1],[2277,1],[2284,1],[2318,1],[2364,1],[2423,1],[2430,1],[3030,1],[3037,1],[3104,1],[3111,1],[3178,1],[3185,1],[3251,1],[3258,1],[3360,1],[3367,1],[3481,1],[3488,1],[3523,1],[3582,1],[3589,1],[3624,1],[3670,1],[3729,1],[3736,1],[4366,1],[4373,1],[4441,1],[4448,1],[4516,1],[4523,1],[4590,1],[4597,1],[4700,1],[4707,1],[4822,1],[4829,1],[4864,1],[4923,1],[4930,1],[4965,1],[5011,1],[5070,1],[5077,1],[5683,1],[5690,1],[5758,1],[5765,1],[5833,1],[5840,1],[5907,1],[5914,1],[6017,1],[6024,1]]},"823":{"position":[[141,1],[241,1],[256,1]]},"838":{"position":[[41,1],[95,1],[102,1],[191,1],[198,1]]},"840":{"position":[[0,1],[44,1],[51,1]]},"842":{"position":[[0,1],[44,1],[51,1],[67,1],[96,1],[103,1],[122,1],[149,1],[156,1],[175,1],[204,1],[211,1],[230,1],[260,1],[267,1],[286,1],[315,1],[322,1],[341,1],[374,1],[381,1],[400,1],[433,1],[440,1],[459,1],[495,1],[502,1],[521,1],[561,1],[568,1],[586,1],[614,1],[621,1],[639,1],[653,5],[659,1],[675,1],[695,1],[734,1],[769,1],[771,1],[785,1],[800,1],[814,1],[827,1],[829,1],[845,1],[865,1],[904,1],[939,1],[941,1],[951,1],[958,1],[997,1],[1032,1],[1034,1],[1044,1],[1051,1],[1090,1],[1125,1],[1127,1],[1137,1],[1144,1],[1183,1],[1218,1],[1220,1],[1230,1],[1237,1],[1276,1],[1311,1],[1313,1],[1323,1],[1332,1],[1371,1],[1406,1],[1408,1],[1418,1],[1427,1],[1466,1],[1501,1],[1503,1],[1513,1],[1523,1],[1562,1],[1597,1],[1599,1],[1609,1],[1619,1],[1658,1],[1693,1],[1695,1],[1705,1],[1714,1],[1753,1],[1788,1],[1790,1],[1800,1],[1809,1],[1848,1],[1883,1],[1885,1],[1895,1],[1904,1],[1943,1],[1978,1],[1980,1],[1990,1],[2003,1],[2042,1],[2077,1],[2079,1],[2089,1],[2102,1],[2141,1],[2176,1],[2178,5],[2184,1],[2194,1],[2214,1],[2253,1],[2288,1],[2290,1],[2300,1],[2320,1],[2359,1],[2394,1],[2396,1],[2406,1],[2426,1],[2465,1],[2500,1],[2502,1],[2511,1],[2525,1],[2560,1],[2595,1],[2597,1],[2606,1],[2620,1],[2655,1],[2690,1],[2692,1],[2701,1],[2715,1],[2750,1],[2785,1],[2787,1],[2796,1],[2810,1],[2845,1],[2880,1],[2882,1],[2891,1],[2905,1],[2940,1],[2975,1],[2977,1],[2986,1],[2995,1],[3034,1],[3069,1],[3071,1],[3087,1],[3107,1],[3146,1],[3181,1]]},"850":{"position":[[59,2],[70,143],[214,1],[245,1],[247,1],[286,1],[288,1],[375,1],[377,1],[464,1],[466,1],[569,1],[571,1],[658,1],[660,1],[778,1],[780,1],[845,1],[847,1],[948,1],[950,1],[987,1],[989,154],[1620,1],[1667,1],[1674,1],[1746,1],[1753,1],[1825,1],[1832,1],[2014,1],[2021,1],[2149,1],[2156,1],[2328,1],[2335,1],[2457,1],[2464,1],[2653,1],[2660,1],[2789,1],[2796,1],[2888,1],[2895,1],[2967,1],[2974,1],[3040,1],[3047,1],[3201,1],[3208,1],[3340,1],[3347,1],[3594,1],[3601,1],[3794,1],[3801,1],[3887,1],[3894,1],[3960,1],[3967,1],[4133,1],[4140,1],[4278,1],[4285,1],[4538,1],[4545,1],[4738,1],[4745,1],[5151,1],[5158,1],[5234,1],[5241,1],[5305,1],[5312,1],[5475,1],[5482,1],[5654,1],[5661,1],[5838,1],[5845,1],[5974,1],[5981,1],[6065,1],[6072,1],[6144,1],[6151,1],[6220,1],[6227,1],[6369,1],[6376,1],[6497,1],[6504,1],[6672,1],[6679,1],[6808,1],[6815,1],[6904,1],[6911,1],[6988,1],[6995,1],[7162,1],[7169,1],[7307,1],[7314,1],[7490,1],[7497,1],[7626,1],[7633,1],[7730,1],[7737,1],[7806,1],[7813,1],[7955,1],[7962,1],[8083,1],[8090,1],[8258,1],[8265,1],[8394,1],[8401,1],[9460,2]]},"859":{"position":[[316,1],[352,1],[357,1],[369,1],[385,1],[415,1],[434,1],[455,1],[465,1],[476,1],[494,1],[507,1],[523,1],[545,1],[565,1],[585,1],[615,1],[629,1],[641,1],[654,1],[669,1],[682,1],[693,1],[711,1],[733,1],[751,1],[781,1],[801,1],[812,1],[844,1],[872,1],[2398,1],[2538,1],[2545,1],[2592,1],[2599,1],[2611,1],[2670,1],[2677,1],[2727,1],[2734,1],[2745,1],[2804,1],[2811,1],[2859,1],[2866,1],[2879,1],[2938,1],[2945,1],[2999,1],[3006,1],[3060,1],[3067,1],[3163,1],[3170,1],[3266,1],[3273,1],[3292,1],[3385,1],[3392,1],[3411,1],[3504,1],[3511,1],[3604,1],[3611,1],[3719,1],[3726,1],[3819,1],[3826,1],[3934,1],[3941,1],[3995,1],[4002,1],[4056,1],[4063,1],[4159,1],[4166,1],[4262,1],[4269,1],[4288,1],[4381,1],[4388,1],[4407,1],[4500,1],[4507,1],[4600,1],[4607,1],[4715,1],[4722,1],[4815,1],[4822,1],[4930,1],[4937,1],[4991,1],[4998,1],[5094,1],[5101,1],[5155,1],[5162,1],[5258,1],[5265,1],[5284,1],[5377,1],[5384,1],[5403,1],[5496,1],[5503,1],[5596,1],[5603,1],[5696,1],[5703,1],[5811,1],[5818,1],[5926,1],[5933,1],[6008,1],[6015,1],[6090,1],[6097,1],[6172,1],[6179,1],[6254,1],[6261,1],[6336,1],[6343,1],[6418,1],[6425,1]]},"861":{"position":[[125,1],[220,1],[244,1],[262,1],[275,1],[286,1],[303,1],[330,1]]},"865":{"position":[[180,1],[314,1],[439,1],[467,1],[530,1]]},"878":{"position":[[180,1],[314,1],[439,1],[467,1],[530,1]]},"903":{"position":[[1770,1],[2868,1],[2883,2],[2964,1],[2976,1],[2987,2],[3024,1],[3036,1],[3046,2],[3089,1],[3104,2],[3171,1],[3187,1],[3193,2],[3198,2],[3345,1]]},"905":{"position":[[506,1]]},"907":{"position":[[471,5]]},"909":{"position":[[2033,4]]},"911":{"position":[[859,3]]},"913":{"position":[[295,1],[314,1],[439,1],[487,1],[550,1],[610,2],[620,1],[728,1],[793,4],[798,1],[938,1],[1020,2],[1057,1],[1067,4],[1072,1],[1083,1],[1151,1],[1182,1],[1226,1],[1257,1],[1300,1],[1331,1],[1375,1],[1406,1],[1455,1],[1486,1],[1529,1],[1560,1],[1611,1],[1642,1],[1837,32],[1940,32],[2057,1],[2059,1],[2069,4],[2074,1],[2114,32],[2218,32],[2256,1],[2358,4],[2423,4],[2676,1],[2732,1],[2903,1],[3094,1],[3241,4]]},"926":{"position":[[337,1],[536,1],[572,1]]},"928":{"position":[[180,1],[200,1]]},"932":{"position":[[307,1],[512,1],[567,1],[968,1],[1017,1],[1215,1],[1242,1],[1354,1],[1449,1],[1478,1]]},"934":{"position":[[174,2],[507,2],[559,2],[650,2],[704,2],[792,2],[844,2],[1211,1],[1244,2],[1550,2],[1585,2]]},"1012":{"position":[[251,1],[281,5]]},"1014":{"position":[[591,2]]},"1027":{"position":[[59,2],[81,3],[111,1],[137,3]]},"1029":{"position":[[57,2],[78,3],[107,1],[132,3]]},"1037":{"position":[[119,1]]},"1039":{"position":[[286,20],[439,20],[592,20]]},"1041":{"position":[[664,3],[682,3],[775,2]]},"1043":{"position":[[191,1],[227,1],[254,1],[301,1],[332,1]]},"1055":{"position":[[2947,58],[3006,1],[3113,58],[3172,1],[3205,58],[3264,1],[3398,1],[3671,3]]},"1063":{"position":[[288,1],[315,1],[342,1],[369,1]]},"1065":{"position":[[161,1],[269,1],[347,1],[386,1],[399,1],[401,1],[450,1]]},"1067":{"position":[[2944,1],[3010,1],[3104,1],[3167,1],[3249,1],[3310,1],[3368,1],[3429,1],[3520,1],[3578,1],[3643,1],[3701,1],[3765,1],[3860,1],[3923,1],[4009,1],[4069,1],[4233,1],[4388,1],[4540,1],[4606,1],[4681,1],[4764,1],[4992,1],[5009,1],[5038,1],[5055,1],[5087,1],[5110,1],[5140,1],[5169,1],[5190,1],[5254,1],[5323,1],[5342,1],[5392,1],[5452,1],[5528,1],[5548,1],[5555,1],[5562,1],[5569,1]]},"1071":{"position":[[177,2],[1333,2],[1541,1]]},"1077":{"position":[[532,1],[573,1],[580,1],[681,1],[688,1],[999,1],[1039,1],[1046,1],[1146,1],[1153,1]]},"1080":{"position":[[687,2],[702,1],[889,1],[934,1]]},"1084":{"position":[[616,3],[707,5],[746,5],[785,5],[797,4],[809,3]]},"1089":{"position":[[836,1],[906,1],[968,2],[987,2],[1000,2],[1020,2],[1030,2],[1080,2],[1092,2],[1144,2],[1158,2],[1212,2],[1224,2],[1276,2],[1286,2],[1336,2],[1345,2],[1394,2],[1745,2],[1852,2],[1963,2],[2074,2],[2181,2],[2285,2],[2617,1]]},"1091":{"position":[[267,1],[283,1],[309,1],[332,1],[342,1],[356,1],[448,1],[465,1],[506,1],[523,1],[549,1],[563,1],[573,1],[616,1]]},"1098":{"position":[[153,58],[212,1],[248,58],[307,1],[344,58],[403,1],[601,58],[660,1],[858,58],[917,1],[944,3],[967,3]]},"1106":{"position":[[235,1],[272,1],[276,1],[315,1],[319,1],[352,1],[356,1],[391,3],[414,3],[418,1],[519,1]]},"1108":{"position":[[434,3],[465,3],[1822,58],[1881,1]]},"1110":{"position":[[161,3],[195,3],[208,3],[242,3],[285,3],[321,3],[369,3],[404,3]]},"1112":{"position":[[1316,1],[1798,1],[2114,1],[2435,1],[2447,1],[2480,1],[2835,1],[2847,1],[2885,1],[3514,1],[3542,1],[3566,1],[3689,1],[4834,1],[4862,1],[4918,1],[5022,1],[5200,1],[5373,1]]},"1114":{"position":[[959,1],[961,1],[1031,1],[1083,1],[2082,1],[2339,1],[2586,1],[2614,5],[3330,1],[3460,1],[3466,1],[3520,1],[3570,1],[4561,1],[4563,1],[4633,1],[4685,1],[5525,1],[5843,1],[6142,1],[6170,5]]},"1116":{"position":[[441,1]]},"1118":{"position":[[641,2],[672,1],[770,2],[773,2],[872,2],[965,2],[968,2],[1002,2],[1012,2],[1059,2],[1062,2],[1138,2],[1148,2],[1165,1]]},"1120":{"position":[[1280,26],[1307,1]]},"1122":{"position":[[239,3],[307,3],[375,3],[443,3],[518,3]]},"1124":{"position":[[556,1],[611,1],[756,1],[791,1],[996,1]]},"1144":{"position":[[412,1]]},"1146":{"position":[[344,1],[368,1],[370,1],[445,2],[516,2],[587,2],[653,1],[655,1]]},"1150":{"position":[[520,1],[562,1],[601,1],[674,1],[748,1],[5957,1],[5996,1],[6079,1],[6152,1],[6334,1],[6478,1],[6541,1],[6577,1],[6648,1],[6765,1],[6824,1],[6870,3],[6900,1],[7020,1],[7078,1],[7157,1],[7328,1],[8098,1],[9072,1],[9143,1],[9213,1],[9215,1],[9394,1],[9576,1],[9733,1],[10717,1],[12657,1],[12686,1],[12700,1],[12712,1],[12750,1],[12760,1],[12774,1],[12809,1],[12811,1],[12819,1],[12827,1],[12829,1],[12843,1],[12878,1],[12880,1],[12894,1],[12916,1],[12918,1],[12930,1],[12937,1],[12939,1],[12944,1],[12979,1],[12981,1],[12988,1],[12998,1],[13000,1],[13010,1],[13012,2],[13015,1],[13017,1],[13031,1],[13066,1],[13157,1],[13186,1],[13197,1],[13211,1],[13227,1]]},"1159":{"position":[[212,1],[307,1],[415,1],[516,2],[619,1],[720,1],[819,1],[898,2],[977,1],[1113,1],[1216,1],[1299,2],[1376,2],[1461,1],[1562,1],[1651,2],[1721,2],[1808,1],[1908,1],[2006,1],[2123,1],[2214,1],[2306,1],[2546,1],[2652,1],[2756,1],[2854,1],[2976,1]]},"1161":{"position":[[1818,1],[1827,1],[1834,2],[1875,2],[4022,1]]},"1163":{"position":[[80,2],[101,2],[133,2],[154,2],[171,2],[192,2],[215,2],[232,2],[252,2],[273,2],[302,2],[337,2],[368,2],[385,2],[406,2],[431,2],[461,2],[486,2],[503,2],[528,2],[545,2]]},"1165":{"position":[[1415,1],[1675,1],[1710,1],[1746,1],[1869,1],[2748,2],[2780,2],[2807,1],[2813,2],[2847,2],[2874,1],[2879,2],[2887,2],[2914,1],[2920,2],[2929,2],[3147,1],[3149,2],[3176,2],[3589,1]]},"1167":{"position":[[349,3],[397,3],[441,3],[496,3],[580,3],[757,1],[924,2],[941,1],[964,1],[973,2],[976,2],[1003,1],[1016,1],[1020,1],[1025,1],[1045,1],[1064,1],[1075,2],[1123,3],[1133,1],[1149,1],[1181,3],[1199,3],[1209,1],[1225,1],[1257,3],[1275,3],[1303,3],[1337,3],[1374,5],[1386,1],[1408,5],[1431,5],[1443,4],[1455,3],[1515,3],[1552,5],[1564,1],[1586,1],[1618,5],[1641,5],[1653,4],[1665,3],[1680,2],[1699,2],[1726,2],[1739,2],[1804,2],[1827,2],[3466,1],[3468,1],[3619,2],[4145,1],[4214,1],[4216,1],[4354,1],[4356,2],[4374,1],[4376,1],[4459,2],[4462,1],[4551,1],[4553,1],[4555,1],[4782,1],[4851,1],[4853,1],[4991,1],[4993,2],[5011,1],[5013,1],[5096,2],[5099,1],[5188,1],[5190,1],[5192,1]]},"1169":{"position":[[132,3],[171,1],[177,3],[212,3],[251,1],[257,3],[502,2],[531,3]]},"1174":{"position":[[32,1]]},"1176":{"position":[[34,1]]},"1180":{"position":[[188,1]]},"1182":{"position":[[178,1]]},"1184":{"position":[[1202,1],[1237,1],[1753,58],[1812,1],[2078,58],[2137,1]]},"1201":{"position":[[83,58],[142,1],[259,3],[281,3]]},"1203":{"position":[[86,58],[145,1]]},"1205":{"position":[[109,58],[168,1]]},"1213":{"position":[[513,1],[543,5]]},"1224":{"position":[[1479,1],[1864,1],[2046,1],[2110,1],[3177,2],[3356,2]]},"1234":{"position":[[2087,1]]},"1240":{"position":[[374,5]]},"1242":{"position":[[144,1]]},"1244":{"position":[[288,1]]},"1250":{"position":[[37,1]]},"1256":{"position":[[969,1],[999,1],[1023,1],[1044,1]]},"1258":{"position":[[102,4]]},"1260":{"position":[[102,4]]},"1264":{"position":[[182,8]]},"1273":{"position":[[466,1],[481,3],[490,3],[522,3],[574,3],[586,3]]},"1275":{"position":[[27,1],[53,1]]},"1277":{"position":[[29,1],[62,1]]},"1279":{"position":[[306,1],[328,1],[351,1],[497,1],[520,1]]},"1282":{"position":[[0,1],[26,1],[64,1],[90,1]]},"1284":{"position":[[324,1]]},"1286":{"position":[[1132,2],[1398,2],[1413,1],[2763,2]]},"1298":{"position":[[304,1],[443,1],[485,2]]},"1305":{"position":[[0,1]]},"1307":{"position":[[0,1]]},"1311":{"position":[[0,1],[34,1],[41,1],[115,1],[182,1],[199,1],[201,1],[208,1],[222,1],[224,1],[291,1],[308,1],[310,1],[317,1],[325,1],[327,1],[338,1],[346,1],[348,1],[358,1],[366,1],[368,1],[386,1],[394,1],[396,1],[409,1],[417,1],[419,1],[434,1],[444,1],[446,1],[455,1],[463,1],[465,1],[478,1],[486,1],[488,1],[499,1],[507,1],[509,1],[518,1],[526,1],[528,1],[540,1],[548,1],[550,1],[566,1],[574,1],[576,1],[583,1],[591,1],[593,1],[602,1],[610,1],[612,1],[622,1],[630,1],[632,1],[642,1],[650,1],[652,1],[659,1],[667,1],[669,1],[679,1],[687,1],[689,1],[698,1],[706,1],[708,1],[716,1],[724,1],[726,3]]},"1315":{"position":[[275,1],[341,1],[406,1]]},"1317":{"position":[[0,1],[107,75],[309,41],[746,1],[767,1],[803,1],[808,1],[820,1],[876,1],[887,1],[895,1],[905,1],[935,1],[953,1],[955,1],[960,1],[969,1],[976,1],[987,1],[995,1],[1005,1],[1015,1],[1026,1],[1028,1],[1033,1],[1045,1],[1101,1],[1112,1],[1120,1],[1130,1],[1160,1],[1178,1],[1180,1],[1185,1],[1197,1],[1217,1],[1222,1],[1227,1],[1232,1],[1262,1],[1280,1],[1282,1],[1287,1],[1299,1],[1355,1],[1366,1],[1374,1],[1384,1],[1414,1],[1432,1],[1453,1],[1464,1],[1507,1],[1509,1],[1517,1],[1525,1],[1527,1],[1538,1],[1581,1],[1583,1],[1588,1],[1593,1],[1595,1],[1604,1],[1647,1],[1649,1],[1658,1],[1670,1],[1672,1],[1679,1],[1699,1],[1701,1],[1712,1],[1745,1],[1747,1],[1757,1],[1787,1],[1789,1],[1797,1],[1827,1],[1829,1],[1840,1],[1858,1],[1860,1],[1868,1],[1899,1],[1901,1],[1912,1],[1955,1],[1973,1],[1979,1],[1991,1],[2001,1],[2035,1],[2112,1],[2123,1],[2153,1],[2171,1],[2173,1],[2178,1],[2187,1],[2197,1],[2206,1],[2213,1],[2224,1],[2234,1],[2245,1],[2247,1],[2253,1],[2265,1],[2275,1],[2309,1],[2386,1],[2397,1],[2427,1],[2445,1],[2447,1],[2453,1],[2465,1],[2469,1],[2476,1],[2485,1],[2502,1],[2507,1],[2537,1],[2555,1],[2557,1],[2563,1],[2575,1],[2579,1],[2586,1],[2595,1],[2638,1],[2643,1],[2673,1],[2691,1],[2693,1],[2699,1],[2711,1],[2715,1],[2730,1],[2739,1],[2761,1],[2766,1],[2796,1],[2814,1],[2816,1],[2822,1],[2834,1],[2838,1],[2853,1],[2862,1],[2888,1],[2893,1],[2923,1],[2941,1],[2943,1],[2949,1],[2961,1],[2965,1],[2976,1],[2985,1],[3029,1],[3034,1],[3064,1],[3082,1],[3084,1],[3090,1],[3102,1],[3106,1],[3117,1],[3126,1],[3168,1],[3173,1],[3203,1],[3221,1],[3223,1],[3229,1],[3241,1],[3245,1],[3252,1],[3261,1],[3325,1],[3330,1],[3360,1],[3378,1],[3380,1],[3386,1],[3398,1],[3402,1],[3413,1],[3422,1],[3461,1],[3466,1],[3496,1],[3514,1],[3516,1],[3522,1],[3534,1],[3538,1],[3549,1],[3558,1],[3600,1],[3605,1],[3635,1],[3653,1],[3655,1],[3661,1],[3673,1],[3677,1],[3688,1],[3697,1],[3726,1],[3731,1],[3761,1],[3779,1],[3781,1],[3787,1],[3799,1],[3803,1],[3810,1],[3819,1],[3861,1],[3866,1],[3896,1],[3914,1],[3916,1],[3922,1],[3934,1],[3938,1],[3945,1],[3954,1],[3996,1],[4001,1],[4031,1],[4049,1],[4051,1],[4057,1],[4069,1],[4073,1],[4080,1],[4089,1],[4131,1],[4136,1],[4166,1],[4184,1],[4186,1],[4192,1],[4204,1],[4208,1],[4215,1],[4224,1],[4265,1],[4270,1],[4300,1],[4318,1],[4320,1],[4326,1],[4338,1],[4342,1],[4353,1],[4362,1],[4408,1],[4413,1],[4443,1],[4461,1],[4463,1],[4469,1],[4481,1],[4485,1],[4492,1],[4512,1],[4521,1],[4561,1],[4566,1],[4596,1],[4614,1],[4616,1],[4622,1],[4634,1],[4638,1],[4645,1],[4665,1],[4674,1],[4722,1],[4727,1],[4757,1],[4775,1],[4777,1],[4783,1],[4795,1],[4799,1],[4806,1],[4826,1],[4835,1],[4872,1],[4877,1],[4907,1],[4925,1],[4927,1],[4933,1],[4945,1],[4949,1],[4965,1],[4974,1],[4990,1],[4995,1],[5025,1],[5043,1],[5045,1],[5051,1],[5063,1],[5067,1],[5074,1],[5083,1],[5119,1],[5124,1],[5154,1],[5172,1],[5174,1],[5180,1],[5192,1],[5196,1],[5212,1],[5221,1],[5237,1],[5242,1],[5272,1],[5290,1],[5292,1],[5298,1],[5310,1],[5320,1],[5354,1],[5431,1],[5442,1],[5472,1],[5490,1],[5512,1],[5523,1],[5566,1],[5568,1],[5576,1],[5584,1],[5586,1],[5597,1],[5640,1],[5642,1],[5647,1],[5653,1],[5655,1],[5662,1],[5701,1],[5703,1],[5712,1],[5755,1],[5757,1],[5764,1],[5773,1],[5790,1],[5792,1],[5801,1],[5808,1],[5810,1],[5819,1],[5831,1],[5833,1],[5840,1],[5881,1],[5883,1],[5892,1],[5896,1],[5898,1],[5908,1],[5938,1],[5940,1],[5948,1],[5978,1],[5980,1],[5991,1],[6009,1],[6011,1],[6018,1],[6031,1],[6033,1],[6043,1],[6051,1],[6053,1],[6064,1],[6107,1],[6129,1],[6134,1],[6146,1],[6178,1],[6187,1],[6205,1],[6257,1],[6265,1],[6275,1],[6283,1],[6313,1],[6331,1],[6333,1],[6338,1],[6347,1],[6360,1],[6367,1],[6385,1],[6392,1],[6400,1],[6410,1],[6418,1],[6428,1],[6439,1],[6441,1],[6446,1],[6458,1],[6490,1],[6499,1],[6517,1],[6569,1],[6577,1],[6587,1],[6595,1],[6625,1],[6643,1],[6645,1],[6650,1],[6662,1],[6694,1],[6703,1],[6713,1],[6741,1],[6746,1],[6751,1],[6755,1],[6785,1],[6803,1],[6805,1],[6810,1],[6822,1],[6854,1],[6863,1],[6881,1],[6933,1],[6941,1],[6951,1],[6959,1],[6989,1],[7007,1],[7032,1],[7084,1],[7092,1],[7109,1],[7126,1],[7134,1],[7144,1],[7152,1],[7164,1],[7173,1],[7183,1],[7185,1],[7197,1],[7205,1],[7222,1],[7237,1],[7245,1],[7255,1],[7263,1],[7275,1],[7284,1],[7294,1],[7296,1],[7348,1],[7356,1],[7373,1],[7390,1],[7398,1],[7408,1],[7416,1],[7428,1],[7437,1],[7447,1],[7449,1],[7477,1],[7481,1],[7498,1],[7515,1],[7520,1],[7526,1],[7531,1],[7535,1],[7539,1],[7543,1],[7545,1],[7597,1],[7605,1],[7622,1],[7639,1],[7647,1],[7657,1],[7665,1],[7677,1],[7686,1],[7696,1],[7714,1],[7720,1],[7756,1],[7767,1],[7777,1],[7786,1],[7791,1],[7801,1],[7815,1],[7845,1],[7847,1],[7852,1],[7859,1],[7870,1],[7880,1],[7889,1],[7894,1],[7904,1],[7918,1],[7928,1],[7930,1],[7936,1],[7972,1],[7983,1],[7993,1],[8002,1],[8007,1],[8017,1],[8031,1],[8061,1],[8063,1],[8069,1],[8104,1],[8109,1],[8113,1],[8117,1],[8122,1],[8126,1],[8130,1],[8160,1],[8162,1],[8168,1],[8204,1],[8209,1],[8213,1],[8217,1],[8222,1],[8226,1],[8230,1],[8260,1],[8262,1],[8268,1],[8303,1],[8308,1],[8312,1],[8316,1],[8321,1],[8325,1],[8329,1],[8359,1],[8361,1],[8367,1],[8402,1],[8407,1],[8411,1],[8415,1],[8420,1],[8424,1],[8428,1],[8458,1],[8460,1],[8466,1],[8498,1],[8503,1],[8507,1],[8511,1],[8515,1],[8519,1],[8523,1],[8553,1],[8555,1],[8561,1],[8597,1],[8608,1],[8618,1],[8627,1],[8632,1],[8642,1],[8656,1],[8686,1],[8708,1],[8722,1],[8765,1],[8767,1],[8775,1],[8783,1],[8785,1],[8799,1],[8842,1],[8844,1],[8849,1],[8855,1],[8857,1],[8866,1],[8909,1],[8911,1],[8918,1],[8953,1],[8955,1],[8965,1],[8969,1],[8971,1],[8980,1],[8984,1],[8986,1],[8991,1],[8996,1],[8998,1],[9008,1],[9012,1],[9014,1],[9028,1],[9032,1],[9034,1],[9044,1],[9074,1],[9076,1],[9090,1],[9133,1]]},"1319":{"position":[[0,1],[45,5],[51,4],[90,4],[134,4],[171,4],[190,4],[202,4],[219,3],[252,3],[284,3],[288,2],[298,2],[314,2],[317,1],[382,1]]},"1321":{"position":[[36,1],[59,3],[70,1],[225,1],[317,1],[332,3],[343,1],[757,1],[882,1],[974,1],[1391,3],[1402,1],[1440,1],[1478,3],[1767,2],[1941,1],[2090,3],[2101,1],[2139,1],[2174,1],[2206,3],[2495,2],[2634,3]]},"1325":{"position":[[39,1],[57,1],[93,1],[95,1],[102,1],[104,1],[140,1],[142,1],[178,1],[180,1],[215,1],[217,1],[252,1],[254,1],[289,1],[291,1],[327,1],[414,1],[443,1],[479,1],[481,1],[488,1],[490,1],[526,1],[528,1],[564,1],[566,1],[602,1],[604,1],[633,1],[668,1],[670,1],[677,1],[679,1],[714,1],[716,1],[751,1],[753,1],[788,1],[790,1],[825,1],[827,1],[862,1]]},"1327":{"position":[[133,1],[201,1],[237,1],[252,1],[269,1],[271,1],[278,1],[289,1],[297,1],[299,69],[369,1],[405,1],[420,1],[437,1],[439,1],[475,1],[490,1],[507,1]]},"1329":{"position":[[122,1],[195,1],[231,1],[254,1],[265,1],[267,1],[274,1],[281,1],[289,1],[291,71],[363,1],[399,1],[422,1],[433,1],[435,1],[471,1],[494,1],[505,1]]},"1333":{"position":[[27,1],[118,1],[193,1],[203,1],[210,2]]},"1335":{"position":[[89,1]]},"1337":{"position":[[33,1],[123,3],[161,1],[213,1],[302,1]]},"1339":{"position":[[19,1]]},"1342":{"position":[[67,1],[90,1],[129,1],[155,1],[166,1],[195,1],[243,1],[245,1],[254,1],[259,1],[266,1],[275,1],[288,1],[300,1],[302,1],[325,1],[364,1],[390,1],[401,1],[430,1],[478,1],[480,1],[503,1],[542,1],[566,1],[575,1],[604,1],[626,2],[652,1],[654,1],[677,1],[716,1],[742,1],[751,1],[780,1],[803,3],[807,1],[809,1],[832,1],[871,1],[897,1],[908,1],[937,1],[985,1]]},"1347":{"position":[[0,1],[49,1],[68,1],[104,1],[115,1],[125,1],[133,1],[162,1],[164,1],[173,1],[180,1],[187,1],[196,1],[204,1],[217,1],[219,1],[238,1],[274,1],[285,1],[295,1],[303,1],[332,1],[334,1],[353,1],[370,1],[381,1],[391,1],[396,1],[425,1],[427,1],[446,1],[463,1],[474,1],[484,1],[489,1],[518,1],[520,1],[539,1],[556,1],[567,1],[577,1],[582,1],[611,1],[613,1],[629,1],[652,1],[659,1],[669,1],[676,1],[705,1],[707,1],[723,1],[746,1],[753,1],[763,1],[770,1],[799,1],[801,1],[817,1],[840,1],[847,1],[857,1],[864,1],[893,1],[895,1],[914,1],[950,1],[961,1],[971,1],[979,1],[1008,1],[1010,1],[1163,1],[1316,1],[1469,1],[1518,1],[1537,1],[1573,1],[1584,1],[1594,1],[1602,1],[1631,1],[1633,1],[1642,1],[1649,1],[1656,1],[1665,1],[1673,1],[1686,1],[1688,1],[1707,1],[1743,1],[1754,1],[1764,1],[1772,1],[1801,1],[1803,1],[1822,1],[1839,1],[1850,1],[1860,1],[1865,1],[1894,1],[1896,1],[1915,1],[1932,1],[1943,1],[1953,1],[1958,1],[1987,1],[1989,1],[2008,1],[2025,1],[2036,1],[2046,1],[2051,1],[2080,1],[2082,1],[2101,1],[2137,1],[2148,1],[2158,1],[2166,1],[2195,1]]},"1349":{"position":[[168,1],[251,1]]},"1351":{"position":[[150,1],[197,1],[215,1],[247,1],[280,1],[290,1],[303,1],[349,1],[351,1],[359,1],[367,1],[369,1],[382,1],[428,1],[430,1],[441,1],[448,1],[450,1],[455,1],[494,1],[496,1],[503,1],[513,1],[515,1],[528,1],[574,1],[576,1],[589,1],[635,1],[637,1],[682,1],[721,1],[731,1],[742,1],[757,1],[803,1],[805,1],[810,1],[817,1],[828,1],[843,1],[856,1],[858,1],[897,1],[907,1],[918,1],[933,1],[979,1],[981,1],[1020,1],[1030,1],[1037,1],[1039,1],[1085,1],[1087,1],[1126,1],[1136,1],[1147,1],[1162,1],[1208,1],[1277,1],[1347,1],[1392,1],[1431,1],[1441,1],[1452,1],[1467,1],[1513,1],[1515,1],[1520,1],[1527,1],[1538,1],[1553,1],[1566,1],[1568,1],[1607,1],[1617,1],[1628,1],[1643,1],[1689,1],[1691,1],[1730,1],[1740,1],[1747,1],[1761,1],[1807,1],[1809,1],[1848,1],[1858,1],[1869,1],[1884,1],[1930,1],[2042,1],[2086,1],[2118,1],[2151,1],[2161,1],[2206,1],[2245,1],[2255,1],[2266,1],[2281,1],[2327,1],[2329,1],[2334,1],[2341,1],[2352,1],[2367,1],[2380,1],[2382,1],[2421,1],[2431,1],[2442,1],[2457,1],[2503,1],[2505,1],[2544,1],[2554,1],[2561,1],[2575,1],[2621,1],[2623,1],[2662,1],[2672,1],[2683,1],[2698,1],[2744,1]]},"1353":{"position":[[67,1],[154,1],[163,1],[175,1],[183,1],[195,1],[204,1],[213,1],[225,1],[227,1],[234,1],[241,1],[249,1],[259,1],[268,1],[277,1],[289,1],[291,1],[300,1],[312,1],[320,1],[332,1],[341,1],[350,1],[362,1],[364,1],[373,1],[385,1],[387,1],[399,1],[401,1],[403,1],[411,1],[413,1],[422,1],[434,1],[442,1],[454,1],[463,1],[472,1],[484,1]]},"1358":{"position":[[171,1],[394,2]]},"1360":{"position":[[1109,1],[1251,2],[1379,2],[1504,2],[1639,2],[1784,2],[1929,2],[2066,2],[2199,2],[2328,2],[2452,2],[2593,2],[2831,2],[2939,2],[3049,2]]},"1362":{"position":[[417,1],[664,1],[726,1],[765,1],[782,1],[792,1],[803,1],[814,1],[822,1],[851,1],[853,1],[858,1],[867,1],[874,1],[881,1],[890,1],[898,1],[911,1],[913,1],[952,1],[969,1],[979,1],[990,1],[1001,1],[1009,1],[1038,1],[1040,1],[1079,1],[1094,1],[1101,1],[1108,1],[1118,1],[1125,1],[1154,1],[1156,1],[1195,1],[1212,1],[1222,1],[1233,1],[1244,1],[1252,1],[1281,1],[1283,1],[1576,1],[1636,1],[1675,1],[1698,1],[1708,1],[1728,1],[1736,1],[1744,1],[1773,1],[1775,1],[1780,1],[1793,1],[1800,1],[1820,1],[1828,1],[1836,1],[1845,1],[1847,1],[1886,1],[1909,1],[1919,1],[1939,1],[1947,1],[1955,1],[1984,1],[1986,1],[2025,1],[2046,1],[2053,1],[2055,1],[2057,1],[2059,1],[2061,1],[2066,1],[2095,1],[2097,1],[2104,1],[2127,1],[2134,1],[2136,1],[2138,1],[2140,1],[2142,1],[2147,1],[2164,1],[2166,1],[2205,1],[2228,1],[2238,1],[2258,1],[2266,1],[2274,1],[2303,1],[2305,1],[2392,1]]},"1364":{"position":[[56,1],[586,1],[650,1],[758,1],[806,1]]},"1366":{"position":[[178,1]]},"1368":{"position":[[222,1],[224,4],[334,1],[336,4],[496,1],[562,1],[997,1],[1063,1],[1464,1],[1558,1],[1918,1],[1925,1],[2140,1],[2234,1],[2597,1],[2604,1]]},"1373":{"position":[[125,1]]},"1375":{"position":[[166,1],[205,1],[222,1],[240,1],[251,1],[262,1],[270,1],[299,1],[352,1],[366,1],[368,1],[373,1],[382,1],[389,1],[396,1],[405,1],[413,1],[426,1],[444,1],[458,1],[460,1],[499,1],[516,1],[534,1],[545,1],[556,1],[564,1],[593,1],[646,1],[660,1],[662,1],[701,1],[716,1],[733,1],[740,1],[751,1],[756,1],[785,1],[799,1],[807,1],[809,1],[848,1],[865,1],[883,1],[894,1],[905,1],[913,1],[942,1],[995,1],[1009,1],[1143,1],[1182,1],[1199,1],[1217,1],[1228,1],[1239,1],[1247,1],[1276,1],[1278,1],[1283,1],[1292,1],[1299,1],[1306,1],[1315,1],[1323,1],[1336,1],[1338,1],[1377,1],[1394,1],[1412,1],[1423,1],[1434,1],[1442,1],[1471,1],[1473,1],[1512,1],[1527,1],[1544,1],[1551,1],[1561,1],[1566,1],[1595,1],[1597,1],[1636,1],[1653,1],[1671,1],[1682,1],[1693,1],[1701,1],[1730,1]]},"1377":{"position":[[167,1],[206,1],[223,1],[241,1],[252,1],[263,1],[271,1],[300,1],[353,1],[367,1],[369,1],[374,1],[383,1],[390,1],[397,1],[406,1],[414,1],[427,1],[445,1],[459,1],[461,1],[500,1],[517,1],[535,1],[546,1],[557,1],[565,1],[594,1],[647,1],[661,1],[663,1],[702,1],[717,1],[734,1],[741,1],[752,1],[759,1],[788,1],[795,1],[802,1],[804,1],[843,1],[860,1],[878,1],[889,1],[900,1],[908,1],[937,1],[990,1],[1004,1],[1171,1],[1210,1],[1227,1],[1245,1],[1256,1],[1267,1],[1275,1],[1304,1],[1357,1],[1371,1],[1373,1],[1378,1],[1387,1],[1394,1],[1401,1],[1410,1],[1418,1],[1431,1],[1449,1],[1463,1],[1465,1],[1504,1],[1521,1],[1539,1],[1550,1],[1561,1],[1569,1],[1598,1],[1651,1],[1665,1],[1667,1],[1706,1],[1721,1],[1738,1],[1745,1],[1756,1],[1761,1],[1790,1],[1797,1],[1805,1],[1807,1],[1846,1],[1863,1],[1881,1],[1892,1],[1903,1],[1911,1],[1940,1],[1993,1],[2007,1]]},"1379":{"position":[[0,1],[196,1],[334,1],[488,1],[699,1],[832,1]]},"1383":{"position":[[543,3],[557,3],[568,3],[583,3],[593,3],[613,3]]},"1386":{"position":[[131,1],[133,1]]},"1400":{"position":[[623,1],[631,1],[651,1],[678,1],[688,1],[695,1],[714,1]]},"1402":{"position":[[0,1],[37,1]]},"1404":{"position":[[0,1],[23,1],[51,1],[76,1]]},"1409":{"position":[[0,1],[8,1],[19,1],[28,1],[40,1],[46,1],[52,1]]},"1411":{"position":[[0,1],[23,1]]},"1413":{"position":[[0,1]]},"1415":{"position":[[50,1]]},"1417":{"position":[[50,1],[81,1],[107,1]]},"1419":{"position":[[70,1],[368,1],[434,1],[654,1],[763,1]]},"1422":{"position":[[0,1]]},"1424":{"position":[[0,1],[20,1]]},"1428":{"position":[[248,1],[287,1],[323,1],[347,1],[378,1],[412,1]]},"1430":{"position":[[25,1],[684,1],[720,1],[818,1],[1368,1],[1461,1],[1830,1]]},"1432":{"position":[[0,1],[24,1],[55,1]]},"1434":{"position":[[42,1],[68,1],[94,1]]},"1438":{"position":[[75,1],[90,1]]},"1440":{"position":[[0,1]]},"1442":{"position":[[0,1],[23,1]]},"1444":{"position":[[43,1],[72,1],[97,1],[139,2],[145,1]]},"1446":{"position":[[0,1]]},"1450":{"position":[[0,1]]},"1452":{"position":[[0,1]]},"1454":{"position":[[0,1]]},"1456":{"position":[[0,1]]},"1458":{"position":[[69,1],[135,1],[144,1],[190,1]]},"1460":{"position":[[75,1]]},"1462":{"position":[[546,1]]},"1464":{"position":[[0,1],[72,1],[144,1]]},"1466":{"position":[[0,1]]},"1471":{"position":[[377,1],[398,1],[424,1],[449,1],[476,1],[498,1],[713,1],[725,1],[777,1],[907,1],[940,1],[1172,1],[1184,1],[1200,1],[1432,1],[1444,1],[1460,1],[1723,1],[1735,1],[1778,1],[1847,1],[2061,1],[2073,1],[2089,1]]},"1473":{"position":[[288,1],[354,1],[415,1],[516,1],[640,1],[706,1],[880,1],[934,1],[1004,1],[1027,1],[1051,1],[1074,1],[1102,1],[1129,1],[1404,1],[1467,1],[1575,1],[1608,1],[1655,1],[1714,1]]},"1475":{"position":[[0,1],[234,1],[241,5],[266,5],[279,1],[548,1],[580,5],[616,5],[876,1],[878,1]]},"1484":{"position":[[59,2],[70,143],[214,1],[245,1],[247,1],[286,1],[288,1],[375,1],[377,1],[464,1],[466,1],[569,1],[571,1],[658,1],[660,1],[778,1],[780,1],[845,1],[847,1],[948,1],[950,1],[987,1],[989,154],[1620,1],[1667,1],[1674,1],[1746,1],[1753,1],[1825,1],[1832,1],[2014,1],[2021,1],[2149,1],[2156,1],[2328,1],[2335,1],[2457,1],[2464,1],[2653,1],[2660,1],[2789,1],[2796,1],[2888,1],[2895,1],[2967,1],[2974,1],[3040,1],[3047,1],[3201,1],[3208,1],[3340,1],[3347,1],[3594,1],[3601,1],[3794,1],[3801,1],[3887,1],[3894,1],[3960,1],[3967,1],[4133,1],[4140,1],[4278,1],[4285,1],[4538,1],[4545,1],[4738,1],[4745,1],[5151,1],[5158,1],[5234,1],[5241,1],[5305,1],[5312,1],[5475,1],[5482,1],[5654,1],[5661,1],[5838,1],[5845,1],[5974,1],[5981,1],[6065,1],[6072,1],[6144,1],[6151,1],[6220,1],[6227,1],[6369,1],[6376,1],[6497,1],[6504,1],[6672,1],[6679,1],[6808,1],[6815,1],[6904,1],[6911,1],[6988,1],[6995,1],[7162,1],[7169,1],[7307,1],[7314,1],[7490,1],[7497,1],[7626,1],[7633,1],[7730,1],[7737,1],[7806,1],[7813,1],[7955,1],[7962,1],[8083,1],[8090,1],[8258,1],[8265,1],[8394,1],[8401,1],[9460,2]]},"1489":{"position":[[357,1],[510,1]]},"1491":{"position":[[450,1],[526,2],[537,85],[623,1],[680,1],[682,1],[714,1],[716,1],[775,1],[777,1],[821,1],[823,1],[860,1],[862,96],[1041,1],[1146,1],[1241,1],[1248,1],[1294,1],[1301,1],[1347,1],[1354,1],[1401,1],[1408,1],[1435,3],[1542,1],[1583,1],[1637,1],[1666,1],[1796,1],[1798,1],[1806,1],[1814,1],[1816,1],[1845,1],[1975,1],[1977,1],[2004,1],[2012,1],[2014,1],[2042,1],[2046,1],[2048,1],[2069,1],[2076,1],[2078,1],[2092,1],[2099,1],[2101,1],[2108,1],[2113,1],[2115,1],[2120,1],[2159,1],[2161,1],[2168,1],[2183,1],[2185,1],[2214,1],[2221,1],[2223,1],[2236,1],[2366,1],[2368,1],[2374,1],[2381,1],[2383,1],[2397,1],[2403,1],[2405,1],[2412,1],[2416,1],[2418,1],[2426,1],[2430,1],[2432,1],[2461,1],[2591,1]]},"1493":{"position":[[429,1]]},"1509":{"position":[[349,1],[354,1],[384,1],[406,1],[422,1],[441,1],[462,1],[484,1],[502,1],[518,1],[536,1],[559,1],[582,1],[606,1],[628,1],[656,1],[686,1],[700,1],[724,1],[748,1],[768,1],[786,1],[811,1],[836,1],[862,1],[886,1],[918,1],[931,1],[947,1],[969,1],[1005,1],[1039,1],[1067,1],[1105,1],[1159,1],[1213,1],[1267,1],[1297,1],[1308,1],[4037,1],[4097,1],[4114,1],[4137,1],[4172,1],[4174,1],[4181,1],[4189,1],[4194,1],[4196,1],[4213,1],[4236,1],[4271,1],[4273,1],[4282,1],[4296,1],[4331,1],[4333,1],[4343,1],[4365,1],[4400,1],[4402,1],[4410,1],[4430,1],[4465,1],[4467,1],[4484,1],[4503,1],[4505,1],[4507,1],[4524,1],[4547,1],[4582,1],[4613,1],[4691,1],[4702,1],[4728,1],[4763,1],[4765,1],[4772,1],[4780,1],[4785,1],[4787,1],[4798,1],[4824,1],[4859,1],[4861,1],[4870,1],[4884,1],[4919,1],[4921,1],[4931,1],[4953,1],[4988,1],[4990,1],[4997,1],[5023,1],[5058,1],[5060,1],[5071,1],[5090,1],[5092,1],[5094,1],[5105,1],[5131,1],[5166,1],[5216,1],[5299,1],[5310,1],[5331,1],[5366,1],[5368,1],[5375,1],[5383,1],[5388,1],[5390,1],[5401,1],[5422,1],[5457,1],[5459,1],[5468,1],[5482,1],[5517,1],[5519,1],[5529,1],[5550,1],[5585,1],[5587,1],[5598,1],[5619,1],[5654,1],[5994,1],[6164,1],[6499,1],[7077,1],[7136,1],[7146,1],[7168,1],[7203,1],[7205,1],[7212,1],[7220,1],[7225,1],[7227,1],[7237,1],[7259,1],[7294,1],[7296,1],[7305,1],[7319,1],[7354,1],[7356,1],[7366,1],[7387,1],[7422,1],[7424,1],[7434,1],[7456,1],[7491,1],[8128,1],[8188,1],[8198,1],[8220,1],[8255,1],[8257,1],[8264,1],[8272,1],[8277,1],[8279,1],[8289,1],[8311,1],[8346,1],[8348,1],[8357,1],[8371,1],[8406,1],[8408,1],[8418,1],[8440,1],[8475,1],[8477,1],[8487,1],[8509,1],[8544,1]]},"1511":{"position":[[414,1],[419,1],[449,1],[471,1],[491,1],[507,1],[526,1],[547,1],[565,1],[577,1],[601,1],[622,1],[646,1],[660,1],[684,1],[698,1],[721,1],[2016,1],[2085,1],[2092,1],[2118,1],[2177,1],[2184,1],[2218,1],[2277,1],[2284,1],[2318,1],[2364,1],[2423,1],[2430,1],[3030,1],[3037,1],[3104,1],[3111,1],[3178,1],[3185,1],[3251,1],[3258,1],[3360,1],[3367,1],[3481,1],[3488,1],[3523,1],[3582,1],[3589,1],[3624,1],[3670,1],[3729,1],[3736,1],[4366,1],[4373,1],[4441,1],[4448,1],[4516,1],[4523,1],[4590,1],[4597,1],[4700,1],[4707,1],[4822,1],[4829,1],[4864,1],[4923,1],[4930,1],[4965,1],[5011,1],[5070,1],[5077,1],[5683,1],[5690,1],[5758,1],[5765,1],[5833,1],[5840,1],[5907,1],[5914,1],[6017,1],[6024,1]]},"1513":{"position":[[141,1],[241,1],[256,1]]},"1523":{"position":[[267,1],[1197,1],[1244,1],[1323,1]]},"1527":{"position":[[378,1],[417,1],[429,1],[473,1],[533,1],[1087,2]]},"1533":{"position":[[832,2]]},"1535":{"position":[[790,2]]},"1553":{"position":[[41,1],[95,1],[102,1],[191,1],[198,1]]},"1555":{"position":[[0,1],[44,1],[51,1]]},"1557":{"position":[[0,1],[44,1],[51,1],[67,1],[96,1],[103,1],[122,1],[149,1],[156,1],[175,1],[204,1],[211,1],[230,1],[260,1],[267,1],[286,1],[315,1],[322,1],[341,1],[374,1],[381,1],[400,1],[433,1],[440,1],[459,1],[495,1],[502,1],[521,1],[561,1],[568,1],[586,1],[614,1],[621,1],[639,1],[653,5],[659,1],[675,1],[695,1],[734,1],[769,1],[771,1],[785,1],[800,1],[814,1],[827,1],[829,1],[845,1],[865,1],[904,1],[939,1],[941,1],[951,1],[958,1],[997,1],[1032,1],[1034,1],[1044,1],[1051,1],[1090,1],[1125,1],[1127,1],[1137,1],[1144,1],[1183,1],[1218,1],[1220,1],[1230,1],[1237,1],[1276,1],[1311,1],[1313,1],[1323,1],[1332,1],[1371,1],[1406,1],[1408,1],[1418,1],[1427,1],[1466,1],[1501,1],[1503,1],[1513,1],[1523,1],[1562,1],[1597,1],[1599,1],[1609,1],[1619,1],[1658,1],[1693,1],[1695,1],[1705,1],[1714,1],[1753,1],[1788,1],[1790,1],[1800,1],[1809,1],[1848,1],[1883,1],[1885,1],[1895,1],[1904,1],[1943,1],[1978,1],[1980,1],[1990,1],[2003,1],[2042,1],[2077,1],[2079,1],[2089,1],[2102,1],[2141,1],[2176,1],[2178,5],[2184,1],[2194,1],[2214,1],[2253,1],[2288,1],[2290,1],[2300,1],[2320,1],[2359,1],[2394,1],[2396,1],[2406,1],[2426,1],[2465,1],[2500,1],[2502,1],[2511,1],[2525,1],[2560,1],[2595,1],[2597,1],[2606,1],[2620,1],[2655,1],[2690,1],[2692,1],[2701,1],[2715,1],[2750,1],[2785,1],[2787,1],[2796,1],[2810,1],[2845,1],[2880,1],[2882,1],[2891,1],[2905,1],[2940,1],[2975,1],[2977,1],[2986,1],[2995,1],[3034,1],[3069,1],[3071,1],[3087,1],[3107,1],[3146,1],[3181,1]]},"1560":{"position":[[0,2]]},"1571":{"position":[[449,1]]},"1578":{"position":[[352,1]]},"1585":{"position":[[795,60],[1547,1],[1555,1],[1595,5]]},"1591":{"position":[[983,1]]},"1603":{"position":[[316,1],[352,1],[357,1],[369,1],[385,1],[415,1],[434,1],[455,1],[465,1],[476,1],[494,1],[507,1],[523,1],[545,1],[565,1],[585,1],[615,1],[629,1],[641,1],[654,1],[669,1],[682,1],[693,1],[711,1],[733,1],[751,1],[781,1],[801,1],[812,1],[844,1],[872,1],[2398,1],[2538,1],[2545,1],[2592,1],[2599,1],[2611,1],[2670,1],[2677,1],[2727,1],[2734,1],[2745,1],[2804,1],[2811,1],[2859,1],[2866,1],[2879,1],[2938,1],[2945,1],[2999,1],[3006,1],[3060,1],[3067,1],[3163,1],[3170,1],[3266,1],[3273,1],[3292,1],[3385,1],[3392,1],[3411,1],[3504,1],[3511,1],[3604,1],[3611,1],[3719,1],[3726,1],[3819,1],[3826,1],[3934,1],[3941,1],[3995,1],[4002,1],[4056,1],[4063,1],[4159,1],[4166,1],[4262,1],[4269,1],[4288,1],[4381,1],[4388,1],[4407,1],[4500,1],[4507,1],[4600,1],[4607,1],[4715,1],[4722,1],[4815,1],[4822,1],[4930,1],[4937,1],[4991,1],[4998,1],[5094,1],[5101,1],[5155,1],[5162,1],[5258,1],[5265,1],[5284,1],[5377,1],[5384,1],[5403,1],[5496,1],[5503,1],[5596,1],[5603,1],[5696,1],[5703,1],[5811,1],[5818,1],[5926,1],[5933,1],[6008,1],[6015,1],[6090,1],[6097,1],[6172,1],[6179,1],[6254,1],[6261,1],[6336,1],[6343,1],[6418,1],[6425,1]]},"1605":{"position":[[125,1],[220,1],[244,1],[262,1],[275,1],[286,1],[303,1],[330,1]]},"1625":{"position":[[1770,1],[2868,1],[2883,2],[2964,1],[2976,1],[2987,2],[3024,1],[3036,1],[3046,2],[3089,1],[3104,2],[3171,1],[3187,1],[3193,2],[3198,2],[3345,1]]},"1627":{"position":[[506,1]]},"1629":{"position":[[471,5]]},"1631":{"position":[[2033,4]]},"1633":{"position":[[859,3]]},"1635":{"position":[[295,1],[314,1],[439,1],[487,1],[550,1],[610,2],[620,1],[728,1],[793,4],[798,1],[938,1],[1020,2],[1057,1],[1067,4],[1072,1],[1083,1],[1151,1],[1182,1],[1226,1],[1257,1],[1300,1],[1331,1],[1375,1],[1406,1],[1455,1],[1486,1],[1529,1],[1560,1],[1611,1],[1642,1],[1837,32],[1940,32],[2057,1],[2059,1],[2069,4],[2074,1],[2114,32],[2218,32],[2256,1],[2358,4],[2423,4],[2676,1],[2732,1],[2903,1],[3094,1],[3241,4]]},"1648":{"position":[[337,1],[536,1],[572,1]]},"1650":{"position":[[180,1],[200,1]]},"1654":{"position":[[307,1],[512,1],[567,1],[968,1],[1017,1],[1215,1],[1242,1],[1354,1],[1449,1],[1478,1]]},"1656":{"position":[[174,2],[507,2],[559,2],[650,2],[704,2],[792,2],[844,2],[1211,1],[1244,2],[1550,2],[1585,2]]},"1674":{"position":[[619,1]]},"1676":{"position":[[453,1],[473,1],[815,1],[867,1]]},"1678":{"position":[[134,1],[151,1],[166,1],[181,1],[196,1]]},"1684":{"position":[[231,1],[620,1],[1137,1],[1456,1],[1776,1],[2102,1],[2429,1],[2751,1],[3070,1],[3391,1]]},"1686":{"position":[[87,1],[360,1]]},"1697":{"position":[[474,3],[514,3],[536,3]]},"1699":{"position":[[179,2],[198,2],[321,3],[352,3],[375,3]]},"1701":{"position":[[421,2],[438,3],[464,1],[485,3]]},"1713":{"position":[[97,1]]},"1717":{"position":[[113,1]]},"1721":{"position":[[16,3],[47,1],[68,1],[123,1],[138,1],[175,1],[204,1],[225,1],[309,1],[324,1],[464,1],[479,1],[616,1],[631,1],[770,1],[785,1],[936,1],[951,1],[1104,1],[1119,1],[1256,1],[1271,1],[1411,1],[1426,1],[1573,1],[1588,1],[1726,1],[1741,1],[1879,1],[1894,1],[2033,1],[2048,1],[2188,1],[2203,1],[2343,1],[2358,1],[2497,1],[2512,1],[2650,1],[2665,1],[2807,1],[2822,1],[2967,1],[2982,1],[3112,1],[3127,1],[3264,1],[3279,1],[3415,1],[3430,1],[3459,1],[3474,1],[3483,4],[3488,4],[3493,4],[3525,1],[3540,1],[3634,1],[3649,1],[3684,1],[3699,1],[3701,1],[3730,1],[3745,1],[3801,1],[3816,1],[3882,1],[3897,1],[3957,1],[3972,1],[4010,1],[4025,1],[4092,1],[4107,1],[4109,1],[4111,3]]},"1723":{"position":[[0,2]]},"1728":{"position":[[90,1],[103,5],[274,1],[674,1],[684,5],[744,5],[750,1],[1030,1],[1047,1],[1232,1],[1249,1],[1263,5],[1501,1],[1599,1]]},"1731":{"position":[[370,1],[415,1],[441,1],[451,1],[762,1],[807,1],[833,1],[843,1],[903,1],[1584,2]]},"1734":{"position":[[24,1],[54,35],[123,2],[407,1]]},"1743":{"position":[[759,3],[857,3],[867,3],[877,3],[889,2],[939,2],[950,2],[1045,3],[1055,3],[1075,3],[1087,2],[1225,3],[1235,3],[1255,3],[1267,2],[1334,3],[1343,3],[1363,3],[1372,3],[1456,3],[1466,3],[1478,3],[1489,3],[1500,3],[1510,3],[1524,3],[1536,3],[1546,3],[1560,3],[1573,3],[1585,3],[1618,3],[1630,2],[1655,3],[1669,3],[1744,3],[1781,3],[2066,3],[2304,3],[2325,3],[2417,3],[2431,3],[2493,3],[2507,3],[2546,3],[2560,3],[2616,3]]},"1747":{"position":[[488,1],[509,1]]},"1749":{"position":[[510,3],[545,3],[668,3],[686,3],[698,3],[716,3]]},"1758":{"position":[[894,2],[921,1],[1088,1],[1257,1],[1426,1],[1584,1]]},"1764":{"position":[[217,1],[257,1],[289,1],[370,1],[402,1],[483,1],[515,1],[596,1],[628,1],[709,1],[741,1],[822,1],[854,1],[935,1],[967,1],[1048,1],[1080,1],[1161,1],[1193,1],[1274,1],[1306,1],[1387,1],[1419,1],[1500,1],[1532,1],[1613,1],[1645,1],[1726,1],[1758,1],[1839,1],[1869,1],[1950,1],[1980,1],[2061,1],[2091,1],[2172,1],[2202,1],[2283,1],[2313,1],[2394,1],[2424,1],[2505,1],[2535,1],[2616,1],[2646,1],[2727,1],[2757,1],[2838,1],[2868,1],[2949,1],[2979,1],[3060,1],[3090,1]]},"1768":{"position":[[203,1]]},"1773":{"position":[[1009,1],[1038,1],[1067,1],[1081,1],[1109,1],[1133,1],[1162,1],[1196,1],[1231,1]]},"1775":{"position":[[140,1]]},"1779":{"position":[[5390,1],[5607,4]]},"1787":{"position":[[262,1]]},"1791":{"position":[[897,1],[1284,1],[1720,1],[2069,1],[2118,1],[2172,1],[2204,1],[2230,1],[2288,1],[2310,1],[2335,1],[2369,1],[2392,1],[2422,1],[2534,1],[2874,1],[2923,1],[2977,1],[3009,1],[3035,1],[3093,1],[3115,1],[3140,1],[3174,1],[3197,1],[3227,1],[3339,1],[3382,1],[3396,1]]},"1794":{"position":[[650,1],[897,1],[1179,1],[1209,1]]},"1805":{"position":[[0,1],[170,3],[368,1],[379,1]]},"1816":{"position":[[0,1],[606,1]]},"1820":{"position":[[335,1]]},"1825":{"position":[[850,2],[865,1],[1052,1],[1097,1],[2335,2]]},"1833":{"position":[[231,1],[779,1],[969,1]]},"1837":{"position":[[171,1]]},"1843":{"position":[[797,1],[836,1],[867,1],[876,1],[878,1],[883,1],[890,1],[899,1],[901,1],[940,1],[971,1],[980,1],[982,1],[1021,1],[1042,1],[1051,1],[1053,1],[1092,1],[1113,1],[1122,1],[1124,1],[1163,1],[1194,1],[1203,1]]},"1845":{"position":[[726,1],[765,1],[783,1],[814,1],[849,1],[856,1],[858,1],[863,1],[870,1],[884,1],[894,1],[901,1],[903,1],[942,1],[960,1],[991,1],[1026,1],[1033,1],[1035,1],[1074,1],[1084,1],[1109,1],[1144,1],[1146,2],[1149,1],[1151,1],[1190,1],[1200,1],[1227,1],[1262,1],[1264,2],[1267,1],[1269,1],[1308,1],[1326,1],[1357,1],[1392,1],[1399,1],[1682,1],[1721,1],[1741,1],[1780,1],[1782,1],[1787,1],[1794,1],[1804,1],[1806,1],[1845,1],[1865,1],[1904,1],[1906,1],[1945,1],[1959,1],[1998,1],[2000,1],[2039,1],[2050,1],[2089,1],[2091,1],[2130,1],[2150,1],[2189,1],[2191,1],[2230,1],[2250,1],[2289,1],[2545,1],[2614,1],[2670,1],[2747,1],[2863,1]]},"1847":{"position":[[22,1],[61,1],[80,1],[90,1],[125,1],[152,1],[164,1],[166,1],[171,1],[178,1],[187,1],[198,1],[206,1],[215,1],[217,1],[256,1],[275,1],[285,1],[320,1],[347,1],[359,1],[361,1],[400,1],[415,1],[424,1],[450,1],[477,1],[489,1],[491,1],[530,1],[549,1],[559,1],[594,1],[621,1],[633,1],[752,1],[763,1],[802,1],[841,1],[848,1],[873,1],[912,1],[951,1],[953,1],[962,1],[974,1],[986,1],[992,1],[1017,1],[1033,1],[1059,1],[1061,1],[1072,1],[1111,1],[1150,1],[1157,1],[1182,1],[1221,1],[1260,1],[1262,1],[1273,1],[1312,1],[1351,1],[1358,1],[1366,1],[1405,1],[1444,1],[1446,1],[1457,1],[1496,1],[1535,1],[1542,1],[1550,1],[1589,1],[1628,1],[1630,1],[1641,1],[1680,1],[1719,1],[1726,1],[1751,1],[1790,1],[1829,1]]},"1849":{"position":[[106,1],[117,1],[209,1],[211,1],[219,1],[227,1],[229,1],[240,1],[332,1],[334,1],[345,1],[351,1],[353,1],[360,1],[368,1],[370,1],[376,1],[468,1],[470,1],[481,1],[573,1]]},"1859":{"position":[[741,5]]},"1865":{"position":[[442,5]]},"1900":{"position":[[280,1]]},"1904":{"position":[[409,1],[458,1],[527,1]]},"1906":{"position":[[618,1],[754,1],[786,1]]},"1908":{"position":[[768,3],[1241,3],[2812,3]]},"1913":{"position":[[803,1],[1029,1],[1088,1],[1401,1],[1405,1],[1432,1],[1485,1],[1487,1]]},"1921":{"position":[[741,5]]},"1927":{"position":[[442,5]]},"1982":{"position":[[1080,1],[1377,1],[1704,1]]},"1984":{"position":[[690,1],[987,1],[1314,1]]},"2016":{"position":[[280,1]]},"2020":{"position":[[409,1],[458,1],[527,1]]},"2022":{"position":[[618,1],[754,1],[786,1]]},"2024":{"position":[[768,3],[1241,3],[2812,3]]},"2029":{"position":[[803,1],[1029,1],[1088,1],[1401,1],[1405,1],[1432,1],[1485,1],[1487,1]]},"2033":{"position":[[579,1],[581,1],[669,6],[709,6],[745,1],[923,3],[936,3],[1526,1],[1537,3]]},"2051":{"position":[[571,1]]},"2061":{"position":[[243,1]]},"2063":{"position":[[261,1]]},"2065":{"position":[[249,1]]},"2067":{"position":[[1697,1]]},"2069":{"position":[[370,1]]},"2093":{"position":[[513,2]]},"2096":{"position":[[576,1],[594,1],[635,1],[825,1],[1283,1]]},"2098":{"position":[[1600,1],[1716,1],[1718,1],[1806,2],[1809,1],[1863,1],[1902,1],[2027,1],[2029,1],[2114,2],[2117,1],[2171,1],[3232,1],[3274,1],[3325,1]]},"2106":{"position":[[701,1],[706,1],[708,1],[710,3],[714,1],[1047,1],[1108,1],[1170,1],[1244,1]]},"2116":{"position":[[820,2]]},"2118":{"position":[[498,1],[733,1],[770,1],[781,1],[841,1],[2225,1],[2404,3]]},"2142":{"position":[[214,1]]},"2148":{"position":[[149,1]]},"2152":{"position":[[185,1]]},"2156":{"position":[[164,1]]},"2170":{"position":[[217,1]]},"2172":{"position":[[14,1]]},"2188":{"position":[[231,3]]},"2281":{"position":[[871,1]]},"2288":{"position":[[191,2],[215,2]]},"2306":{"position":[[179,3]]},"2350":{"position":[[1770,1],[2868,1],[2883,2],[2964,1],[2976,1],[2987,2],[3024,1],[3036,1],[3046,2],[3089,1],[3104,2],[3171,1],[3187,1],[3193,2],[3198,2],[3345,1]]},"2352":{"position":[[506,1]]},"2354":{"position":[[471,5]]},"2356":{"position":[[2033,4]]},"2358":{"position":[[859,3]]},"2360":{"position":[[295,1],[314,1],[439,1],[487,1],[550,1],[610,2],[620,1],[728,1],[793,4],[798,1],[938,1],[1020,2],[1057,1],[1067,4],[1072,1],[1083,1],[1151,1],[1182,1],[1226,1],[1257,1],[1300,1],[1331,1],[1375,1],[1406,1],[1455,1],[1486,1],[1529,1],[1560,1],[1611,1],[1642,1],[1837,32],[1940,32],[2057,1],[2059,1],[2069,4],[2074,1],[2114,32],[2218,32],[2256,1],[2358,4],[2423,4],[2676,1],[2732,1],[2903,1],[3094,1],[3241,4]]},"2373":{"position":[[337,1],[536,1],[572,1]]},"2375":{"position":[[180,1],[200,1]]},"2379":{"position":[[307,1],[512,1],[567,1],[968,1],[1017,1],[1215,1],[1242,1],[1354,1],[1449,1],[1478,1]]},"2381":{"position":[[174,2],[507,2],[559,2],[650,2],[704,2],[792,2],[844,2],[1211,1],[1244,2],[1550,2],[1585,2]]},"2405":{"position":[[90,2]]},"2520":{"position":[[206,1]]},"2564":{"position":[[36,1],[66,1],[136,1],[153,1],[157,3],[161,1]]},"2566":{"position":[[1113,3],[1233,3],[1337,3],[1522,1],[1816,1],[2285,1],[2488,1],[2498,3],[2764,3],[3515,1],[3599,1],[3609,3],[5005,3],[5370,1],[5568,1],[7583,1],[7777,1],[7900,3],[8044,3],[8184,3],[8322,3],[8468,3],[8582,3],[8737,3],[8904,3],[9064,3],[9219,3],[9374,3],[9537,3],[10421,3],[11120,3],[11831,1],[11947,1],[12255,3],[12353,3],[12562,3],[12768,3],[12913,3]]},"2568":{"position":[[34,1],[60,3],[64,1],[101,1],[141,1],[167,1]]},"2570":{"position":[[44,3]]},"2625":{"position":[[235,1]]},"2671":{"position":[[246,3],[263,3],[283,1],[285,3],[298,1],[300,3],[319,1],[321,3],[342,3],[357,1],[359,3],[372,1],[374,1],[376,3],[393,1],[395,1],[397,3],[409,1],[411,1],[413,3],[425,1],[427,1],[429,3],[443,1],[445,1],[447,3],[459,1],[461,3],[485,1],[487,1],[489,3],[503,1],[505,1],[507,1],[509,3],[522,1],[524,1],[526,1],[528,3],[541,1],[543,1],[545,3],[549,3],[553,1],[555,1],[557,1],[559,3],[572,1],[574,1],[576,1],[578,3],[591,1],[593,1],[595,3],[609,1],[611,1],[613,3],[626,1],[628,1],[630,3],[643,1],[645,3],[656,1],[658,1],[660,3],[672,1],[674,1],[676,1],[678,3],[682,1],[684,1],[686,3],[698,1],[700,3],[715,1],[717,3],[733,1],[735,1],[737,3],[741,1],[743,3],[759,3],[779,1],[781,3],[794,1],[796,1],[798,3],[815,1],[817,1],[819,3],[823,3],[827,1],[829,3],[847,1],[849,1],[851,3],[864,1],[866,1],[868,3],[881,1],[883,1],[885,3],[899,1],[901,3],[912,1],[914,1],[916,3],[928,1],[930,1],[932,3],[936,3],[940,1],[942,1],[944,3],[956,1],[958,3],[973,1],[975,3],[1004,1],[1006,1],[1008,3],[1012,1],[1014,3],[1030,3],[1048,1],[1050,3],[1063,1],[1065,3],[1076,1],[1078,1],[1080,3],[1092,1],[1094,1],[1096,3],[1100,3],[1104,1],[1106,1],[1108,3],[1120,1],[1122,3],[1137,1],[1139,3],[1163,1],[1165,3],[1176,1],[1178,3],[1220,1],[1231,1],[1233,3],[1245,3],[1286,3],[1299,3],[1313,3],[1321,3]]},"2673":{"position":[[246,1],[248,3],[262,1],[264,1],[266,3],[282,1],[284,1],[286,3],[306,1],[308,1],[310,3],[328,1],[330,1],[332,3],[353,1],[355,1],[357,3],[804,1],[816,1]]},"2688":{"position":[[2877,1]]},"2702":{"position":[[12,1],[96,1]]},"2705":{"position":[[1569,1],[1582,1],[1689,1]]},"2707":{"position":[[198,3]]},"2709":{"position":[[251,1]]},"2711":{"position":[[624,1],[736,1],[757,3],[1028,1],[1329,1]]},"2723":{"position":[[629,4],[903,4]]},"2725":{"position":[[1200,1]]},"2727":{"position":[[87,1],[93,1],[183,1],[189,1],[447,4],[530,3]]},"2731":{"position":[[1469,1]]},"2735":{"position":[[135,2],[152,1],[331,2],[471,1],[520,3],[582,1],[631,3],[1438,1],[1572,1]]},"2737":{"position":[[558,4]]},"2747":{"position":[[12,1],[96,1]]},"2750":{"position":[[1871,1],[1884,1],[1991,1]]},"2752":{"position":[[198,3]]},"2754":{"position":[[251,1]]},"2756":{"position":[[89,1],[336,1]]},"2762":{"position":[[642,4],[916,4]]},"2764":{"position":[[1770,1]]},"2766":{"position":[[647,4],[730,3]]},"2770":{"position":[[1492,1]]},"2774":{"position":[[271,2],[288,1],[467,2],[607,1],[656,3],[718,1],[767,3],[1440,1],[1574,1]]},"2776":{"position":[[558,4]]},"2786":{"position":[[108,1]]},"2811":{"position":[[59,1],[72,1]]},"2813":{"position":[[1257,2],[1280,2]]},"2815":{"position":[[313,1],[369,1],[569,1],[1060,1],[1221,4],[1240,1],[1374,4],[1393,1],[1528,4]]},"2822":{"position":[[189,1]]},"2837":{"position":[[137,1]]},"2840":{"position":[[1217,1],[1230,1],[1337,1]]},"2842":{"position":[[197,3]]},"2844":{"position":[[179,1],[867,1],[897,1]]},"2848":{"position":[[628,4]]},"2852":{"position":[[29,1],[466,1],[472,1],[562,1],[568,1],[801,5],[871,5],[877,3]]},"2856":{"position":[[602,1],[714,1],[735,3],[1006,1],[1307,1]]},"2860":{"position":[[1465,1]]},"2872":{"position":[[523,1],[536,1]]},"2892":{"position":[[470,1],[489,1]]},"2895":{"position":[[1727,3]]},"2899":{"position":[[836,1]]},"2906":{"position":[[209,1],[239,1]]},"2911":{"position":[[352,1],[370,1]]},"2933":{"position":[[96,1],[208,1],[229,3],[557,1],[860,1]]},"2942":{"position":[[235,1]]},"2947":{"position":[[2268,1],[3258,1],[4125,5],[4373,1],[5098,1],[5681,1]]},"2949":{"position":[[590,1]]},"2951":{"position":[[1147,1]]},"2970":{"position":[[353,1],[433,1]]},"3025":{"position":[[377,1]]},"3029":{"position":[[444,4]]},"3042":{"position":[[401,1],[422,1],[581,1],[583,1],[591,1],[599,1],[601,1],[622,1],[781,1],[783,1],[804,1],[811,1],[813,1],[827,1],[878,1],[880,1],[885,1],[924,1],[926,1],[938,1],[945,1],[947,1],[954,1],[961,1],[963,1],[978,1],[985,1],[987,1],[1008,1],[1167,1]]},"3046":{"position":[[251,1],[272,1],[431,1],[433,1],[441,1],[449,1],[451,1],[472,1],[631,1],[633,1],[654,1],[661,1],[663,1],[677,1],[825,1],[827,1],[832,1],[871,1],[873,1],[885,1],[892,1],[894,1],[901,1],[927,1],[929,1],[942,1],[944,1],[946,1],[961,1],[968,1],[970,1],[991,1],[1150,1]]},"3076":{"position":[[202,1]]},"3088":{"position":[[128,1],[173,1],[200,1],[214,1],[226,1],[238,1],[251,1],[263,1],[287,1],[310,1],[343,1],[375,1],[377,1],[382,1],[396,1],[408,1],[419,1],[432,1],[444,1],[468,1],[491,1],[524,1],[556,1],[558,1],[585,1],[599,1],[611,1],[623,1],[636,1],[648,1],[672,1],[695,1],[728,1],[760,1],[762,1],[789,1],[796,1],[803,1],[810,1],[812,1],[821,1],[828,1],[835,1],[842,1],[849,1],[851,1],[866,1],[868,1],[870,1],[872,1],[874,1],[876,1],[878,1],[880,1],[882,1],[884,1],[886,1],[913,1],[920,1],[927,1],[939,1],[941,1],[950,1],[957,1],[964,1],[971,1],[978,1],[980,1],[995,1],[997,1],[999,1],[1001,1],[1003,1],[1005,1],[1007,1],[1009,1],[1011,1],[1013,1],[1015,1],[1042,1],[1049,1],[1056,1],[1068,1],[1070,1],[1080,1],[1089,1],[1096,1],[1103,1],[1111,1],[1113,1],[1128,1],[1130,1],[1132,1],[1134,1],[1136,1],[1138,1],[1140,1],[1142,1],[1144,1],[1146,1],[1148,1],[1175,1],[1182,1],[1189,1],[1196,1],[1198,1],[1208,1],[1217,1],[1224,1],[1231,1],[1239,1],[1241,1],[1256,1],[1258,1],[1260,1],[1262,1],[1264,1],[1266,1],[1268,1],[1270,1],[1272,1],[1274,1],[1276,1],[1303,1],[1317,1],[1329,1],[1341,1],[1354,1],[1366,1],[1390,1],[1413,1],[1446,1],[1478,1]]},"3092":{"position":[[396,1],[430,1],[458,1]]},"3094":{"position":[[54,1],[88,1],[116,1]]},"3099":{"position":[[269,1]]},"3107":{"position":[[278,1],[303,1],[317,1],[329,1],[341,1],[354,1],[366,1],[390,1],[413,1],[446,1],[478,1],[480,1],[485,1],[499,1],[511,1],[522,1],[535,1],[547,1],[571,1],[594,1],[627,1],[659,1],[661,1],[686,1],[700,1],[712,1],[724,1],[737,1],[749,1],[773,1],[796,1],[829,1],[861,1],[863,1],[885,1],[892,1],[899,1],[906,1],[908,1],[917,1],[924,1],[931,1],[938,1],[945,1],[947,1],[967,1],[969,1],[971,1],[973,1],[975,1],[977,1],[979,1],[981,1],[983,1],[985,1],[987,1],[1009,1],[1016,1],[1023,1],[1030,1],[1032,1],[1042,1],[1051,1],[1058,1],[1065,1],[1073,1],[1075,1],[1095,1],[1097,1],[1099,1],[1101,1],[1103,1],[1105,1],[1107,1],[1109,1],[1111,1],[1113,1],[1115,1],[1137,1],[1144,1],[1151,1],[1163,1],[1165,1],[1174,1],[1181,1],[1188,1],[1195,1],[1202,1],[1204,1],[1224,1],[1226,1],[1228,1],[1230,1],[1232,1],[1234,1],[1236,1],[1238,1],[1240,1],[1242,1],[1244,1],[1266,1],[1273,1],[1280,1],[1292,1],[1294,1],[1304,1],[1313,1],[1320,1],[1327,1],[1335,1],[1337,1],[1357,1],[1359,1],[1361,1],[1363,1],[1365,1],[1367,1],[1369,1],[1371,1],[1373,1],[1375,1],[1377,1],[1402,1],[1416,1],[1428,1],[1440,1],[1453,1],[1465,1],[1489,1],[1512,1],[1545,1],[1577,1]]},"3109":{"position":[[428,1],[448,1],[487,1],[489,1],[497,1],[505,1],[507,1],[527,1],[566,1],[568,1],[577,1],[596,1],[598,1],[603,1],[642,1],[644,1],[656,1],[695,1],[697,1],[711,1],[728,1],[730,1],[743,1],[778,1],[780,1],[800,1],[802,1],[804,1],[806,1],[826,1],[865,1],[1460,1],[1490,1],[1507,1],[1537,1],[1558,1],[1560,1],[1565,1],[1579,1],[1591,1],[1600,1],[1602,1],[1632,1],[1649,1],[1679,1],[1700,1],[1702,1],[1729,1],[1746,1],[1773,1],[1792,1],[1794,1],[1809,1],[1811,1],[1826,1],[1828,1],[1830,1],[1857,1],[1874,1],[1901,1],[1920,1],[1922,1],[1937,1],[1939,1],[1954,1],[1956,1],[1958,1],[1985,1],[1995,1],[2022,1],[2041,1],[2043,1],[2058,1],[2060,1],[2075,1],[2077,1],[2079,1],[2106,1],[2116,1],[2143,1],[2164,1],[2166,1],[2181,1],[2183,1],[2198,1],[2200,1],[2202,1],[2229,1],[2242,1],[2269,1],[2288,1],[2290,1],[2305,1],[2307,1],[2322,1],[2324,1],[2326,1],[2353,1],[2366,1],[2393,1],[2412,1],[2414,1],[2429,1],[2431,1],[2446,1],[2448,1],[2450,1],[2480,1],[2497,1],[2527,1],[2548,1],[2642,1],[2662,1],[2701,1],[2703,1],[2711,1],[2719,1],[2721,1],[2741,1],[2780,1],[2782,1],[2791,1],[2810,1],[2812,1],[2817,1],[2856,1],[2858,1],[2870,1],[2909,1],[2911,1],[2925,1],[2942,1],[2944,1],[2957,1],[2992,1],[2994,1],[3014,1],[3016,1],[3018,1],[3020,1],[3040,1],[3079,1]]},"3119":{"position":[[143,1],[158,1]]},"3121":{"position":[[29,1],[44,1]]},"3128":{"position":[[485,2]]},"3160":{"position":[[2677,5]]},"3171":{"position":[[181,2]]},"3210":{"position":[[787,1]]},"3251":{"position":[[4831,1]]},"3276":{"position":[[669,1],[703,1]]},"3282":{"position":[[261,1],[298,1]]},"3299":{"position":[[496,2],[593,1],[815,1],[1126,2],[2606,2],[3829,1],[4973,1],[5234,1],[5325,1],[5466,1],[5575,1]]},"3301":{"position":[[5774,1],[5776,1],[5778,1],[5816,1],[5833,1],[5850,1],[5876,1],[5910,1],[5948,1],[5979,1],[5981,1],[5983,1],[5996,1],[6021,1],[6053,5],[6075,1],[6100,1],[6115,1],[6123,1],[6154,1],[6163,1],[6172,1],[6188,1],[6217,1],[6246,1],[6294,1],[6296,1],[6298,1],[6311,1],[6341,1],[6388,1],[6426,1],[6428,1],[6430,1],[6453,1],[6455,1],[6457,1],[6471,1],[6473,1],[6541,1],[6560,1],[6591,1],[6622,1],[6643,1],[6658,1],[6673,1],[6692,1],[6723,1],[6751,1],[6784,1],[6807,1],[6830,1],[6869,1],[6901,1],[6903,1],[6952,1],[6991,1],[7018,1],[7075,1],[7111,1],[7139,1]]},"3314":{"position":[[517,1],[642,4],[930,1],[1341,1],[3243,3]]},"3316":{"position":[[92,1],[103,1],[105,1],[117,1],[119,1],[132,1],[152,1],[195,1],[197,1],[199,1],[201,1],[203,1],[205,1],[207,1],[235,1],[237,1],[239,1],[241,1],[243,1],[245,1],[247,1],[271,3],[275,3],[295,1],[297,1],[299,1],[301,1],[303,1],[305,1],[307,1],[309,3],[343,1],[345,1],[347,1],[349,1],[351,1],[353,1],[355,1],[357,3],[389,1],[391,1],[393,1],[395,1],[397,1],[399,1],[401,1],[403,3],[443,1],[445,1],[447,1],[449,1],[451,1],[453,1],[455,1],[469,3],[473,1],[475,1],[477,1],[479,1],[491,1],[493,1],[506,1],[508,3],[522,1],[524,1],[526,1],[528,1],[530,1],[532,1],[534,1],[536,3],[567,1],[569,1],[571,1],[573,1],[575,1],[577,1],[579,1],[581,3],[602,1],[604,1],[635,1],[653,1],[655,1],[667,1],[669,1],[696,1],[771,1],[791,1],[817,1],[837,1],[839,1],[841,1],[884,1],[891,1],[932,1],[934,1],[936,1],[938,1],[940,1],[977,3],[981,1],[983,1],[1006,1],[1008,1],[1010,1],[1012,1],[1014,1],[1016,3],[1034,1],[1036,1],[1038,1],[1040,1],[1042,1],[1044,1],[1046,1],[1081,1],[1083,1],[1085,1],[1087,1],[1089,1],[1091,1],[1093,1],[1119,1],[1142,1],[1144,1],[1146,1],[1148,1],[1150,1],[1152,1],[1369,1],[1371,1],[1373,1],[1375,1],[1377,1],[1379,1],[1381,1],[1399,1],[1401,1],[1403,1],[1405,1],[1407,1],[1417,1],[1435,1],[1477,1],[1479,1],[1481,1],[1483,1],[1485,1],[1487,1],[1489,1],[1508,1],[1510,1],[1512,1],[1514,1],[1516,1],[1518,1],[1557,1],[1575,1],[1599,1],[1621,1],[1644,1],[1667,1],[1687,1],[1707,1],[1758,1],[1764,1],[1785,1],[1787,1],[1789,1],[1791,1],[1796,1],[1830,1],[1832,1],[1834,1],[1836,1],[1838,1],[1840,1],[1842,1]]},"3357":{"position":[[376,3],[380,1],[416,1],[421,3],[425,1],[481,1],[486,3],[490,1],[496,2],[561,2],[573,1],[575,1],[619,2],[622,1],[666,2],[669,1],[709,2],[712,1],[752,1],[754,1]]},"3380":{"position":[[263,1]]},"3429":{"position":[[201,1]]},"3431":{"position":[[201,1],[293,1]]},"3463":{"position":[[658,1]]},"3472":{"position":[[370,1],[412,1],[451,1],[524,1],[598,1],[5800,1],[5839,1],[5922,1],[5995,1],[6143,1],[6287,1],[6350,1],[6386,1],[6457,1],[6574,1],[6633,1],[6679,3],[6709,1],[6829,1],[6887,1],[6966,1],[7137,1],[7907,1],[8881,1],[8952,1],[9022,1],[9024,1],[9203,1],[9385,1],[9542,1],[10526,1]]},"3482":{"position":[[729,1],[740,1],[1979,1],[1990,1],[2382,1],[2393,1],[2780,1],[2791,1],[2937,1],[2987,1],[3057,1],[3132,1],[3182,1],[3271,1]]},"3484":{"position":[[60,1],[110,1],[180,1],[255,1],[305,1],[394,1]]}}}],["0",{"_index":2275,"t":{"381":{"position":[[497,2],[681,1]]},"428":{"position":[[500,1]]},"474":{"position":[[310,1],[473,1],[636,1],[1141,1]]},"485":{"position":[[787,1],[846,1]]},"487":{"position":[[1625,2],[3280,2]]},"590":{"position":[[1674,1],[1738,1],[1782,1]]},"604":{"position":[[2319,4]]},"644":{"position":[[277,1],[373,1],[577,1]]},"660":{"position":[[2807,1],[2849,1]]},"730":{"position":[[2044,1],[2414,1]]},"805":{"position":[[249,1]]},"821":{"position":[[2486,2],[2594,2],[2610,2],[2643,2],[2670,2],[2690,3],[2720,2],[2734,2],[2745,2],[2763,2],[2776,2],[2797,2],[2823,2],[2836,2],[2853,3],[2888,2],[2902,2],[2965,2],[4230,2],[4244,2],[4260,2],[4287,2],[4303,2],[4317,3],[5430,2]]},"859":{"position":[[2977,1],[3140,2],[3362,2],[3581,2],[3696,2]]},"903":{"position":[[3196,1]]},"1031":{"position":[[568,1]]},"1039":{"position":[[325,1]]},"1063":{"position":[[876,4]]},"1071":{"position":[[1473,1],[1543,1],[1581,1]]},"1089":{"position":[[2761,2]]},"1106":{"position":[[313,1]]},"1110":{"position":[[854,1]]},"1112":{"position":[[5128,1],[5198,1],[5289,1],[5306,1],[5354,1],[5371,1]]},"1114":{"position":[[2188,1],[2258,1],[2428,1],[2445,1],[2493,1],[2510,1],[2561,1],[5631,1],[5701,1],[5771,1],[5841,1],[5932,1],[5948,1],[5996,1],[6012,1],[6060,1],[6076,1],[6124,1],[6140,1]]},"1124":{"position":[[433,2],[459,1],[713,1],[787,3],[822,3],[1036,2],[1047,1],[1055,1],[1170,1],[1193,1],[1411,1],[1415,2]]},"1184":{"position":[[78,2],[711,2],[962,1]]},"1305":{"position":[[206,1],[284,1],[286,1],[357,1],[506,1],[508,1]]},"1317":{"position":[[2467,1],[7537,1],[7541,1],[8111,1],[8115,1],[8128,1],[8211,1],[8215,1],[8228,1],[8310,1],[8314,1],[8327,1],[8409,1],[8413,1],[8426,1],[8505,1],[8509,1],[8513,1],[8517,1],[8521,1],[8967,1],[8982,1],[9030,1]]},"1319":{"position":[[35,1]]},"1321":{"position":[[131,1],[206,1],[464,1],[628,1],[863,1],[1316,1],[1456,2],[2155,2]]},"1333":{"position":[[71,1],[158,1],[191,1],[242,1],[302,1],[352,1]]},"1335":{"position":[[203,2]]},"1337":{"position":[[121,1]]},"1339":{"position":[[59,1],[155,4],[272,1]]},"1347":{"position":[[368,1],[1837,1]]},"1366":{"position":[[339,1],[362,1]]},"1368":{"position":[[836,2],[1093,1],[1118,1],[1862,1],[1889,1],[2541,1],[2568,1]]},"1371":{"position":[[74,1]]},"1373":{"position":[[90,1]]},"1375":{"position":[[96,1],[731,1],[1080,1],[1542,1]]},"1377":{"position":[[97,1],[732,1],[1101,1],[1736,1]]},"1379":{"position":[[41,1],[62,1],[82,1],[104,1],[122,1],[140,1],[158,1],[191,1],[328,1],[330,1],[332,1],[347,1],[349,1],[351,1],[529,1],[550,1],[570,1],[632,1],[650,1],[826,1],[828,1],[830,1]]},"1397":{"position":[[336,2]]},"1430":{"position":[[144,1],[146,1],[490,2],[815,2],[937,1],[939,1],[1129,1],[1157,1],[1190,1],[1580,1],[1582,1],[1772,1]]},"1444":{"position":[[142,2]]},"1491":{"position":[[2044,1],[2414,1]]},"1511":{"position":[[2486,2],[2594,2],[2610,2],[2643,2],[2670,2],[2690,3],[2720,2],[2734,2],[2745,2],[2763,2],[2776,2],[2797,2],[2823,2],[2836,2],[2853,3],[2888,2],[2902,2],[2965,2],[4230,2],[4244,2],[4260,2],[4287,2],[4303,2],[4317,3],[5430,2]]},"1542":{"position":[[249,1]]},"1603":{"position":[[2977,1],[3140,2],[3362,2],[3581,2],[3696,2]]},"1625":{"position":[[3196,1]]},"1734":{"position":[[111,3],[404,2],[436,2],[452,4],[506,4]]},"1779":{"position":[[3572,1]]},"1787":{"position":[[763,1]]},"1789":{"position":[[536,2]]},"1833":{"position":[[256,1],[304,1],[352,1],[398,1],[439,1],[441,1],[487,1],[765,1],[804,1],[923,1],[994,1]]},"2108":{"position":[[250,1]]},"2114":{"position":[[98,1]]},"2130":{"position":[[246,1]]},"2148":{"position":[[236,1]]},"2154":{"position":[[1258,1],[1302,1]]},"2350":{"position":[[3196,1]]},"2566":{"position":[[380,2]]},"2625":{"position":[[1599,1]]},"2725":{"position":[[383,1],[639,1],[723,1],[829,1]]},"2764":{"position":[[604,1],[860,1],[944,1],[1050,1]]},"2830":{"position":[[42,2]]},"2850":{"position":[[292,1],[532,1],[616,1],[722,1]]},"2895":{"position":[[2606,1]]},"2923":{"position":[[638,2]]},"3088":{"position":[[805,4],[1191,4]]},"3107":{"position":[[901,4],[1025,4]]},"3115":{"position":[[85,3]]},"3308":{"position":[[543,1]]},"3343":{"position":[[950,1]]},"3357":{"position":[[373,2],[785,1]]},"3397":{"position":[[13,1],[658,1]]}}}],["0,1",{"_index":5414,"t":{"1124":{"position":[[718,5]]}}}],["0,2,4,6,8,10,12,14,16",{"_index":5412,"t":{"1124":{"position":[[587,23],[642,23]]}}}],["0.0",{"_index":6878,"t":{"1428":{"position":[[283,3]]},"1430":{"position":[[716,3],[752,3]]}}}],["0.0.0.0",{"_index":5341,"t":{"1116":{"position":[[301,7]]}}}],["0.0.0.0/0",{"_index":2688,"t":{"483":{"position":[[793,13]]},"1743":{"position":[[1129,9],[1308,9]]},"3088":{"position":[[929,9],[1058,9]]},"3107":{"position":[[1153,9],[1282,9]]}}}],["0.001",{"_index":6406,"t":{"1321":{"position":[[700,8]]}}}],["0.001253",{"_index":6444,"t":{"1321":{"position":[[1962,8]]}}}],["0.01949",{"_index":6884,"t":{"1430":{"position":[[152,7],[191,7],[261,7],[300,7],[370,7],[409,7],[945,7],[984,7],[1054,7],[1093,7],[1588,7],[1627,7],[1697,7],[1736,7]]}}}],["0.03897",{"_index":6883,"t":{"1430":{"position":[[118,7],[227,7],[336,7],[911,7],[1020,7],[1554,7],[1663,7]]}}}],["0.07794",{"_index":6892,"t":{"1430":{"position":[[887,7],[1530,7]]}}}],["0.11691",{"_index":6882,"t":{"1430":{"position":[[94,7]]}}}],["0.20240403.0",{"_index":3732,"t":{"790":{"position":[[475,16]]},"1527":{"position":[[475,16]]}}}],["0.4",{"_index":8396,"t":{"2229":{"position":[[492,3]]}}}],["0.4.5",{"_index":8164,"t":{"2096":{"position":[[588,5]]}}}],["0.4.x",{"_index":8384,"t":{"2206":{"position":[[401,7]]}}}],["0.5",{"_index":9331,"t":{"2733":{"position":[[485,3]]},"2772":{"position":[[485,3]]}}}],["0.5.x",{"_index":8412,"t":{"2245":{"position":[[189,6]]}}}],["0.5gib",{"_index":9332,"t":{"2733":{"position":[[497,6]]},"2772":{"position":[[497,6]]},"2854":{"position":[[498,6]]}}}],["0.6.0",{"_index":3754,"t":{"790":{"position":[[1111,7],[1192,5]]},"1364":{"position":[[160,5],[841,5]]},"1527":{"position":[[1111,7],[1192,5]]}}}],["0.6.1",{"_index":6647,"t":{"1364":{"position":[[237,5],[888,5]]}}}],["0.6.2",{"_index":6653,"t":{"1364":{"position":[[314,5],[935,5]]}}}],["0.6.x",{"_index":8450,"t":{"2278":{"position":[[180,6]]}}}],["0.9.0",{"_index":2681,"t":{"483":{"position":[[581,5]]}}}],["0.testbed.osism.xyz",{"_index":4825,"t":{"1039":{"position":[[349,19]]},"1055":{"position":[[2075,19],[2219,19]]},"1114":{"position":[[794,19],[1011,19],[4396,19],[4613,19]]},"1184":{"position":[[1095,20]]},"1279":{"position":[[186,19],[369,19],[414,19],[538,19]]},"1317":{"position":[[8382,19]]},"1325":{"position":[[195,19],[731,19]]},"1787":{"position":[[730,19]]}}}],["0.testbed.osism.xyz.yml",{"_index":5968,"t":{"1184":{"position":[[1018,23]]}}}],["0.testbed.osism.xyz:1984",{"_index":7603,"t":{"1789":{"position":[[559,24]]}}}],["0.yml",{"_index":5967,"t":{"1184":{"position":[[848,5],[1747,5],[2072,5]]}}}],["0/100/1c.1/0",{"_index":7067,"t":{"1585":{"position":[[1041,13]]}}}],["0/100/1c.4/0",{"_index":7069,"t":{"1585":{"position":[[1100,13]]}}}],["0/100/1c.4/0.1",{"_index":7072,"t":{"1585":{"position":[[1159,15]]}}}],["0/100/1c.4/0.2",{"_index":7074,"t":{"1585":{"position":[[1220,15]]}}}],["0/100/1c.4/0.3",{"_index":7076,"t":{"1585":{"position":[[1281,15]]}}}],["0/100/1c/0",{"_index":7064,"t":{"1585":{"position":[[984,11]]}}}],["0/100/2.2/0",{"_index":7057,"t":{"1585":{"position":[[856,12]]}}}],["0/100/2.2/0.1",{"_index":7062,"t":{"1585":{"position":[[919,14]]}}}],["0/fluentd",{"_index":6461,"t":{"1337":{"position":[[79,9],[473,9]]}}}],["0/nova.conf",{"_index":5970,"t":{"1184":{"position":[[1168,11]]}}}],["00",{"_index":7294,"t":{"1728":{"position":[[456,2],[459,2],[462,2],[465,2],[483,2],[486,2],[489,2],[495,2],[498,2]]}}}],["0000",{"_index":2648,"t":{"472":{"position":[[2446,5]]}}}],["000000",{"_index":7409,"t":{"1747":{"position":[[656,6]]}}}],["00000000004f",{"_index":6342,"t":{"1317":{"position":[[5688,12]]}}}],["000072374c3f",{"_index":4219,"t":{"859":{"position":[[3215,12],[3453,12],[3768,12],[3883,12],[6048,12]]},"1603":{"position":[[3215,12],[3453,12],[3768,12],[3883,12],[6048,12]]}}}],["0001",{"_index":8621,"t":{"2524":{"position":[[4,4],[360,4]]},"2526":{"position":[[538,4]]},"2649":{"position":[[41,5]]},"3518":{"position":[[631,4]]}}}],["0002",{"_index":8626,"t":{"2526":{"position":[[582,4]]},"2528":{"position":[[45,4],[88,4]]},"3518":{"position":[[682,4]]}}}],["0003",{"_index":8627,"t":{"2526":{"position":[[634,4]]},"2530":{"position":[[4,4],[352,4]]},"2692":{"position":[[371,4]]},"3518":{"position":[[741,4]]}}}],["0004",{"_index":8628,"t":{"2526":{"position":[[683,4]]},"2532":{"position":[[45,4]]},"2815":{"position":[[815,4]]},"3518":{"position":[[797,4]]}}}],["002",{"_index":5645,"t":{"1156":{"position":[[167,3]]}}}],["0056b89c",{"_index":7623,"t":{"1791":{"position":[[2251,8],[3056,8]]}}}],["00950",{"_index":8578,"t":{"2484":{"position":[[453,5]]}}}],["00:00:00",{"_index":4421,"t":{"909":{"position":[[2290,8]]},"922":{"position":[[293,8]]},"1631":{"position":[[2290,8]]},"1644":{"position":[[293,8]]},"2356":{"position":[[2290,8]]},"2369":{"position":[[293,8]]}}}],["00:00:00.858586",{"_index":6309,"t":{"1317":{"position":[[4033,15]]}}}],["00:00:00.877270",{"_index":6312,"t":{"1317":{"position":[[4168,15]]}}}],["00:00:00.939663",{"_index":6306,"t":{"1317":{"position":[[3898,15]]}}}],["00:00:00.950605",{"_index":6331,"t":{"1317":{"position":[[5027,15]]}}}],["00:00:01.022530",{"_index":6324,"t":{"1317":{"position":[[4759,15]]}}}],["00:00:01.039468",{"_index":6271,"t":{"1317":{"position":[[2675,15]]}}}],["00:00:01.074853",{"_index":6321,"t":{"1317":{"position":[[4598,15]]}}}],["00:00:01.076976",{"_index":6275,"t":{"1317":{"position":[[2798,15]]}}}],["00:00:01.166032",{"_index":6337,"t":{"1317":{"position":[[5274,15]]}}}],["00:00:01.231630",{"_index":6286,"t":{"1317":{"position":[[3205,15]]}}}],["00:00:01.255475",{"_index":6294,"t":{"1317":{"position":[[3498,15]]}}}],["00:00:01.263370",{"_index":6289,"t":{"1317":{"position":[[3362,15]]}}}],["00:00:01.315217",{"_index":6315,"t":{"1317":{"position":[[4302,15]]}}}],["00:00:01.327607",{"_index":6282,"t":{"1317":{"position":[[3066,15]]}}}],["00:00:01.392765",{"_index":6298,"t":{"1317":{"position":[[3637,15]]}}}],["00:00:01.826039",{"_index":6303,"t":{"1317":{"position":[[3763,15]]}}}],["00:00:01.926842",{"_index":6334,"t":{"1317":{"position":[[5156,15]]}}}],["00:00:02.031647",{"_index":6318,"t":{"1317":{"position":[[4445,15]]}}}],["00:00:02.040932",{"_index":6327,"t":{"1317":{"position":[[4909,15]]}}}],["00:00:02.146165",{"_index":6278,"t":{"1317":{"position":[[2925,15]]}}}],["00:00:02.552006",{"_index":6267,"t":{"1317":{"position":[[2539,15],[5993,15]]}}}],["00:00:38.238032",{"_index":6258,"t":{"1317":{"position":[[1264,15],[1842,15]]}}}],["00:00:39.135309",{"_index":6350,"t":{"1317":{"position":[[6787,15]]}}}],["00d7c2a2",{"_index":4028,"t":{"842":{"position":[[2005,8]]},"1557":{"position":[[2005,8]]}}}],["00de553df86949b49365baee6375fb5a",{"_index":396,"t":{"32":{"position":[[221,32]]}}}],["01",{"_index":3469,"t":{"646":{"position":[[1620,2]]},"909":{"position":[[2284,2],[2287,2]]},"922":{"position":[[287,2],[290,2]]},"1631":{"position":[[2284,2],[2287,2]]},"1644":{"position":[[287,2],[290,2]]},"1728":{"position":[[468,2]]},"2356":{"position":[[2284,2],[2287,2]]},"2369":{"position":[[287,2],[290,2]]},"2795":{"position":[[1728,2],[1731,2]]},"2815":{"position":[[1199,2],[1326,2],[1480,2],[1506,2]]},"3167":{"position":[[214,2]]}}}],["0100",{"_index":3600,"t":{"726":{"position":[[187,5]]},"730":{"position":[[1002,5]]},"732":{"position":[[375,5]]},"1487":{"position":[[187,5]]},"1491":{"position":[[1002,5]]},"1493":{"position":[[375,5]]},"2536":{"position":[[403,4],[457,4],[511,4]]},"2544":{"position":[[545,4]]},"2631":{"position":[[613,4],[666,4]]},"2815":{"position":[[523,4]]},"2939":{"position":[[396,4]]},"3429":{"position":[[355,5]]},"3518":{"position":[[923,4]]}}}],["0101",{"_index":8636,"t":{"2540":{"position":[[8,4],[624,4]]},"2544":{"position":[[649,4]]},"3429":{"position":[[385,5]]},"3518":{"position":[[1032,4]]}}}],["0102",{"_index":8644,"t":{"2544":{"position":[[733,4]]},"2546":{"position":[[8,4],[562,4]]},"3429":{"position":[[406,5]]},"3518":{"position":[[1121,4]]}}}],["0103",{"_index":8645,"t":{"2544":{"position":[[779,4]]},"2550":{"position":[[8,4],[576,4]]},"3429":{"position":[[437,5]]},"3518":{"position":[[1172,4]]}}}],["0104",{"_index":8646,"t":{"2544":{"position":[[833,4]]},"2548":{"position":[[8,4],[555,4]]},"3429":{"position":[[467,5]]},"3518":{"position":[[1231,4]]}}}],["0110",{"_index":8647,"t":{"2544":{"position":[[871,4]]},"2554":{"position":[[45,4]]},"2754":{"position":[[858,4]]},"2923":{"position":[[769,4]]},"2939":{"position":[[644,4]]},"3518":{"position":[[1274,4]]}}}],["0111",{"_index":8648,"t":{"2544":{"position":[[901,4]]},"2556":{"position":[[45,4]]},"3518":{"position":[[1309,4]]}}}],["0112",{"_index":8629,"t":{"2526":{"position":[[756,4]]},"2534":{"position":[[5,4],[140,4]]},"3518":{"position":[[877,4]]}}}],["0113",{"_index":8649,"t":{"2544":{"position":[[958,4]]},"2552":{"position":[[45,4]]},"3518":{"position":[[1371,4]]}}}],["0114",{"_index":8650,"t":{"2544":{"position":[[1008,4]]},"2558":{"position":[[45,4]]},"3518":{"position":[[1426,4]]}}}],["0115",{"_index":8651,"t":{"2544":{"position":[[1047,4]]},"2572":{"position":[[45,4]]},"3518":{"position":[[1470,4]]}}}],["0190",{"_index":9014,"t":{"2625":{"position":[[1283,4]]}}}],["01t08:53:14.000000",{"_index":6512,"t":{"1347":{"position":[[406,18]]}}}],["01t08:53:15.000000",{"_index":6513,"t":{"1347":{"position":[[499,18],[592,18]]}}}],["01t08:56:24.000000",{"_index":6520,"t":{"1347":{"position":[[1875,18]]}}}],["01t08:56:25.000000",{"_index":6521,"t":{"1347":{"position":[[1968,18],[2061,18]]}}}],["02",{"_index":4297,"t":{"893":{"position":[[19,2]]},"1077":{"position":[[561,2],[669,2],[1027,2],[1134,2]]},"1615":{"position":[[19,2]]},"2340":{"position":[[19,2]]},"2528":{"position":[[76,2]]},"2536":{"position":[[490,2]]},"2540":{"position":[[653,2]]},"2548":{"position":[[584,2]]},"2550":{"position":[[605,2]]},"2584":{"position":[[78,2],[89,2],[128,2]]},"2586":{"position":[[444,2]]},"2594":{"position":[[74,2]]},"3308":{"position":[[531,2]]},"3429":{"position":[[266,2]]}}}],["0200",{"_index":8974,"t":{"2582":{"position":[[45,4]]},"2592":{"position":[[501,4]]},"3518":{"position":[[1527,4]]}}}],["0210",{"_index":8975,"t":{"2584":{"position":[[45,4],[99,4]]},"2592":{"position":[[561,4]]},"3276":{"position":[[2002,4]]},"3431":{"position":[[299,5]]},"3518":{"position":[[1592,4]]}}}],["0211",{"_index":8976,"t":{"2586":{"position":[[8,4],[415,4]]},"2592":{"position":[[603,4]]},"3518":{"position":[[1639,4]]}}}],["0212",{"_index":8979,"t":{"2588":{"position":[[45,4]]},"2592":{"position":[[652,4]]},"3518":{"position":[[1693,4]]}}}],["0213",{"_index":8980,"t":{"2590":{"position":[[45,4]]},"2592":{"position":[[708,4]]},"3518":{"position":[[1754,4]]}}}],["0214",{"_index":8982,"t":{"2592":{"position":[[757,4]]},"2594":{"position":[[45,4]]},"3431":{"position":[[341,5]]},"3518":{"position":[[1808,4]]}}}],["0215",{"_index":8983,"t":{"2592":{"position":[[821,4]]},"2600":{"position":[[45,4]]},"3518":{"position":[[1877,4]]}}}],["0216",{"_index":8984,"t":{"2592":{"position":[[883,4]]},"2604":{"position":[[45,4]]},"3518":{"position":[[1944,4]]}}}],["0217",{"_index":8985,"t":{"2592":{"position":[[941,4]]},"2596":{"position":[[45,4]]},"3518":{"position":[[2007,4]]}}}],["0218",{"_index":8987,"t":{"2592":{"position":[[996,4]]},"2598":{"position":[[45,4]]},"3518":{"position":[[2067,4]]}}}],["021af0688c594bf88ed675b942d3bea8",{"_index":346,"t":{"27":{"position":[[1607,32]]}}}],["0242ac1f",{"_index":6338,"t":{"1317":{"position":[[5664,8]]}}}],["02:30:00",{"_index":3043,"t":{"596":{"position":[[355,8]]}}}],["02ef8579",{"_index":9838,"t":{"3109":{"position":[[1997,8]]}}}],["03",{"_index":3068,"t":{"598":{"position":[[139,3],[207,3],[235,3],[303,3]]},"1298":{"position":[[560,2],[708,2]]},"2241":{"position":[[20,2]]},"2308":{"position":[[20,2]]},"2454":{"position":[[41,2]]},"2795":{"position":[[1792,2]]},"3482":{"position":[[89,2]]}}}],["0300",{"_index":8971,"t":{"2574":{"position":[[518,4]]},"2576":{"position":[[8,4],[715,4]]},"3518":{"position":[[2141,4]]}}}],["0301",{"_index":8972,"t":{"2574":{"position":[[577,4]]},"2580":{"position":[[45,4]]},"3518":{"position":[[2204,4]]}}}],["0302",{"_index":5499,"t":{"1150":{"position":[[158,4]]},"2574":{"position":[[665,4]]},"2578":{"position":[[45,4]]},"3518":{"position":[[2296,4]]}}}],["030f",{"_index":7624,"t":{"1791":{"position":[[2260,4],[3065,4]]}}}],["03262e57eb94",{"_index":4063,"t":{"842":{"position":[[3021,12]]},"1557":{"position":[[3021,12]]}}}],["0333",{"_index":7881,"t":{"1847":{"position":[[1600,4]]}}}],["03783b4952344c849af37d26818d19f0",{"_index":374,"t":{"27":{"position":[[2690,32]]}}}],["0390",{"_index":9028,"t":{"2631":{"position":[[2181,4],[2224,4]]}}}],["04",{"_index":2360,"t":{"404":{"position":[[143,2]]},"472":{"position":[[2182,2],[2340,2],[2421,2],[2509,2]]},"821":{"position":[[2066,2],[2158,2],[2258,2],[2404,2],[3011,2],[3085,2],[3159,2],[3232,2],[3341,2],[3462,2],[3563,2],[3710,2],[4347,2],[4422,2],[4497,2],[4571,2],[4681,2],[4803,2],[4904,2],[5051,2],[5664,2],[5739,2],[5814,2],[5888,2],[5998,2]]},"850":{"position":[[1652,2],[1731,2],[1810,2],[1999,2],[2134,2],[2313,2],[2442,2],[2638,2],[2774,2],[2873,2],[2952,2],[3025,2],[3186,2],[3325,2],[3579,2],[3779,2],[3872,2],[3945,2],[4118,2],[4263,2],[4523,2],[4723,2],[5136,2],[5219,2],[5290,2],[5460,2],[5639,2],[5823,2],[5959,2],[6050,2],[6129,2],[6205,2],[6354,2],[6482,2],[6657,2],[6793,2],[6889,2],[6973,2],[7147,2],[7292,2],[7475,2],[7611,2],[7715,2],[7791,2],[7940,2],[8068,2],[8243,2],[8379,2],[9703,2]]},"859":{"position":[[2523,2],[2577,2],[2655,2],[2712,2],[2789,2],[2844,2],[2923,2],[2984,2],[3045,2],[3148,2],[3251,2],[3370,2],[3489,2],[3589,2],[3704,2],[3804,2],[3919,2],[3980,2],[4041,2],[4144,2],[4247,2],[4366,2],[4485,2],[4585,2],[4700,2],[4800,2],[4915,2],[4976,2],[5079,2],[5140,2],[5243,2],[5362,2],[5481,2],[5581,2],[5681,2],[5796,2],[5911,2],[5993,2],[6075,2],[6157,2],[6239,2],[6321,2],[6403,2]]},"1484":{"position":[[1652,2],[1731,2],[1810,2],[1999,2],[2134,2],[2313,2],[2442,2],[2638,2],[2774,2],[2873,2],[2952,2],[3025,2],[3186,2],[3325,2],[3579,2],[3779,2],[3872,2],[3945,2],[4118,2],[4263,2],[4523,2],[4723,2],[5136,2],[5219,2],[5290,2],[5460,2],[5639,2],[5823,2],[5959,2],[6050,2],[6129,2],[6205,2],[6354,2],[6482,2],[6657,2],[6793,2],[6889,2],[6973,2],[7147,2],[7292,2],[7475,2],[7611,2],[7715,2],[7791,2],[7940,2],[8068,2],[8243,2],[8379,2],[9703,2]]},"1511":{"position":[[2066,2],[2158,2],[2258,2],[2404,2],[3011,2],[3085,2],[3159,2],[3232,2],[3341,2],[3462,2],[3563,2],[3710,2],[4347,2],[4422,2],[4497,2],[4571,2],[4681,2],[4803,2],[4904,2],[5051,2],[5664,2],[5739,2],[5814,2],[5888,2],[5998,2]]},"1603":{"position":[[2523,2],[2577,2],[2655,2],[2712,2],[2789,2],[2844,2],[2923,2],[2984,2],[3045,2],[3148,2],[3251,2],[3370,2],[3489,2],[3589,2],[3704,2],[3804,2],[3919,2],[3980,2],[4041,2],[4144,2],[4247,2],[4366,2],[4485,2],[4585,2],[4700,2],[4800,2],[4915,2],[4976,2],[5079,2],[5140,2],[5243,2],[5362,2],[5481,2],[5581,2],[5681,2],[5796,2],[5911,2],[5993,2],[6075,2],[6157,2],[6239,2],[6321,2],[6403,2]]},"2809":{"position":[[399,2]]},"2815":{"position":[[1196,2]]},"2895":{"position":[[1399,2],[1652,2]]},"3429":{"position":[[291,2]]},"3482":{"position":[[2119,2],[2525,2]]}}}],["0400",{"_index":8988,"t":{"2602":{"position":[[533,4]]},"2606":{"position":[[45,4]]},"3518":{"position":[[2360,4]]}}}],["0401",{"_index":8989,"t":{"2602":{"position":[[579,4]]},"2608":{"position":[[45,4]]},"3518":{"position":[[2410,4]]}}}],["0402",{"_index":8990,"t":{"2602":{"position":[[643,4]]},"2612":{"position":[[45,4]]},"3518":{"position":[[2478,4]]}}}],["0403",{"_index":8991,"t":{"2602":{"position":[[690,4]]},"2653":{"position":[[45,4]]},"3518":{"position":[[2529,4]]}}}],["0410",{"_index":8992,"t":{"2602":{"position":[[792,4]]},"2610":{"position":[[45,4]]},"3425":{"position":[[4,4]]},"3448":{"position":[[4,4]]},"3518":{"position":[[2635,4]]}}}],["0411",{"_index":8993,"t":{"2602":{"position":[[843,4]]},"2614":{"position":[[45,4]]},"3384":{"position":[[4,4]]},"3425":{"position":[[16,4]]},"3518":{"position":[[2690,4]]}}}],["0412",{"_index":8994,"t":{"2602":{"position":[[906,4]]},"2651":{"position":[[8,4],[536,4]]},"3518":{"position":[[2757,4]]}}}],["04483f95",{"_index":7880,"t":{"1847":{"position":[[1591,8]]}}}],["047fc23516dd",{"_index":9822,"t":{"3109":{"position":[[1796,12]]}}}],["049bf974",{"_index":4210,"t":{"859":{"position":[[3088,8],[3310,8],[3529,8],[3644,8],[5942,8]]},"1603":{"position":[[3088,8],[3310,8],[3529,8],[3644,8],[5942,8]]}}}],["04dac2927f744479a5d4c23dd0a3c378",{"_index":364,"t":{"27":{"position":[[2170,32]]}}}],["05",{"_index":9538,"t":{"2895":{"position":[[1480,2],[1664,2]]}}}],["05b9f996",{"_index":4242,"t":{"859":{"position":[[5019,8],[5302,8],[5521,8],[5736,8],[6270,8]]},"1603":{"position":[[5019,8],[5302,8],[5521,8],[5736,8],[6270,8]]}}}],["05d9",{"_index":9860,"t":{"3109":{"position":[[2253,4]]}}}],["06",{"_index":5012,"t":{"1077":{"position":[[558,2],[666,2],[1024,2],[1131,2]]},"1298":{"position":[[563,2],[711,2]]},"2528":{"position":[[79,2]]},"2536":{"position":[[540,2]]},"2554":{"position":[[81,2]]},"2576":{"position":[[751,2]]},"2895":{"position":[[1676,2]]},"3308":{"position":[[528,2]]},"3429":{"position":[[255,2]]}}}],["0600",{"_index":4377,"t":{"905":{"position":[[1011,4]]},"1089":{"position":[[297,4]]},"1167":{"position":[[4347,6],[4984,6]]},"1627":{"position":[[1011,4]]},"2352":{"position":[[1011,4]]}}}],["0604607fccee",{"_index":5297,"t":{"1114":{"position":[[3643,12]]}}}],["0608c701",{"_index":4034,"t":{"842":{"position":[[2104,8]]},"1557":{"position":[[2104,8]]}}}],["0640",{"_index":4611,"t":{"934":{"position":[[718,4],[858,4]]},"1656":{"position":[[718,4],[858,4]]},"1749":{"position":[[384,6]]},"2381":{"position":[[718,4],[858,4]]}}}],["0644",{"_index":904,"t":{"139":{"position":[[569,4]]},"650":{"position":[[1775,6]]},"934":{"position":[[573,4]]},"1656":{"position":[[573,4]]},"1697":{"position":[[570,4]]},"2381":{"position":[[573,4]]}}}],["0660",{"_index":5854,"t":{"1167":{"position":[[642,6]]}}}],["07",{"_index":8364,"t":{"2186":{"position":[[20,2]]},"2584":{"position":[[81,2]]},"2815":{"position":[[1477,2]]},"2895":{"position":[[1688,2],[1700,2]]}}}],["0714",{"_index":4193,"t":{"859":{"position":[[2622,4]]},"1603":{"position":[[2622,4]]}}}],["0755",{"_index":7415,"t":{"1749":{"position":[[232,4]]}}}],["078061ce3e23",{"_index":4054,"t":{"842":{"position":[[2452,12]]},"1557":{"position":[[2452,12]]}}}],["08",{"_index":8634,"t":{"2536":{"position":[[439,2]]},"2540":{"position":[[656,2]]},"2550":{"position":[[608,2]]},"2584":{"position":[[92,2],[131,2]]},"2594":{"position":[[77,2]]},"2815":{"position":[[1352,2]]},"2895":{"position":[[1721,2]]},"3482":{"position":[[2116,2],[2522,2]]}}}],["085c",{"_index":6749,"t":{"1368":{"position":[[2591,5],[2606,4],[2741,4],[2746,5]]}}}],["08a06812e381",{"_index":7800,"t":{"1843":{"position":[[1079,12]]}}}],["08a06812e381,source_type=image,destination_type=volume,volume_size=20",{"_index":7845,"t":{"1845":{"position":[[2793,69]]}}}],["08a983bde692",{"_index":6497,"t":{"1342":{"position":[[529,12]]}}}],["09",{"_index":3070,"t":{"598":{"position":[[159,3],[187,3],[255,3],[283,3]]},"730":{"position":[[1226,2],[1279,2],[1332,2],[1386,2]]},"790":{"position":[[1315,2]]},"1311":{"position":[[19,2]]},"1317":{"position":[[1239,2],[1764,2],[1804,2],[2514,2],[2650,2],[2773,2],[2900,2],[3041,2],[3180,2],[3337,2],[3473,2],[3612,2],[3738,2],[3873,2],[4008,2],[4143,2],[4277,2],[4420,2],[4573,2],[4734,2],[4884,2],[5002,2],[5131,2],[5249,2],[5915,2],[5955,2],[6762,2],[8137,2],[8237,2],[8336,2],[8435,2],[8530,2],[9051,2]]},"1342":{"position":[[582,2],[758,2]]},"1347":{"position":[[683,2],[777,2],[871,2]]},"1491":{"position":[[1226,2],[1279,2],[1332,2],[1386,2]]},"1527":{"position":[[1315,2]]},"1728":{"position":[[471,2]]},"2204":{"position":[[20,2]]},"2274":{"position":[[20,2]]},"2398":{"position":[[20,2]]},"2536":{"position":[[436,2]]},"2809":{"position":[[299,2],[402,2]]},"2895":{"position":[[4398,2]]},"3482":{"position":[[945,2]]}}}],["099",{"_index":5372,"t":{"1120":{"position":[[1186,4]]}}}],["09:09:08.320738572",{"_index":2647,"t":{"472":{"position":[[2427,18]]}}}],["09:29:44",{"_index":4081,"t":{"850":{"position":[[1658,8],[1737,8],[1816,8],[2005,8],[2140,8],[2319,8],[2448,8],[2644,8],[2780,8],[2879,8],[2958,8],[3031,8],[3192,8]]},"1484":{"position":[[1658,8],[1737,8],[1816,8],[2005,8],[2140,8],[2319,8],[2448,8],[2644,8],[2780,8],[2879,8],[2958,8],[3031,8],[3192,8]]}}}],["09:29:45",{"_index":4105,"t":{"850":{"position":[[3331,8],[3585,8],[3785,8],[3878,8],[3951,8],[4124,8]]},"1484":{"position":[[3331,8],[3585,8],[3785,8],[3878,8],[3951,8],[4124,8]]}}}],["09:29:46",{"_index":4113,"t":{"850":{"position":[[4269,8],[4529,8],[4729,8],[5142,8],[5225,8],[5296,8],[5466,8]]},"1484":{"position":[[4269,8],[4529,8],[4729,8],[5142,8],[5225,8],[5296,8],[5466,8]]}}}],["09:29:47",{"_index":4127,"t":{"850":{"position":[[5645,8],[5829,8],[5965,8],[6056,8],[6135,8],[6211,8],[6360,8],[6488,8],[6663,8],[6799,8],[6895,8],[6979,8],[7153,8]]},"1484":{"position":[[5645,8],[5829,8],[5965,8],[6056,8],[6135,8],[6211,8],[6360,8],[6488,8],[6663,8],[6799,8],[6895,8],[6979,8],[7153,8]]}}}],["09:29:48",{"_index":4137,"t":{"850":{"position":[[7298,8],[7481,8],[7617,8],[7721,8],[7797,8],[7946,8],[8074,8],[8249,8],[8385,8]]},"1484":{"position":[[7298,8],[7481,8],[7617,8],[7721,8],[7797,8],[7946,8],[8074,8],[8249,8],[8385,8]]}}}],["09aa934bab86",{"_index":4043,"t":{"842":{"position":[[2240,12]]},"1557":{"position":[[2240,12]]}}}],["09d4",{"_index":4227,"t":{"859":{"position":[[4093,4],[4315,4],[4749,4],[4864,4],[6197,4]]},"1603":{"position":[[4093,4],[4315,4],[4749,4],[4864,4],[6197,4]]}}}],["0:00",{"_index":6470,"t":{"1337":{"position":[[166,4],[402,4],[425,4]]}}}],["0:00:01.053565",{"_index":7265,"t":{"1721":{"position":[[3756,17]]}}}],["0:01:26.967216",{"_index":6354,"t":{"1317":{"position":[[7500,14]]}}}],["0:02:53.934432",{"_index":6353,"t":{"1317":{"position":[[7483,14]]}}}],["0@rbd",{"_index":6514,"t":{"1347":{"position":[[644,5],[1095,5],[1146,5]]}}}],["0a5708ea",{"_index":6632,"t":{"1362":{"position":[[1988,8],[2355,8]]}}}],["0b3c75f80b6743778daccec0da423465",{"_index":368,"t":{"27":{"position":[[2378,32]]}}}],["0cd16262",{"_index":4012,"t":{"842":{"position":[[1716,8]]},"1557":{"position":[[1716,8]]}}}],["0cda",{"_index":4003,"t":{"842":{"position":[[1534,4]]},"1557":{"position":[[1534,4]]}}}],["0d",{"_index":8311,"t":{"2150":{"position":[[453,2]]}}}],["0d00b3d40b4f",{"_index":3440,"t":{"644":{"position":[[409,12]]}}}],["0d502fdb",{"_index":7815,"t":{"1845":{"position":[[1961,8]]}}}],["0e3ec450b668",{"_index":6588,"t":{"1360":{"position":[[1702,12]]}}}],["0ea1",{"_index":6638,"t":{"1364":{"position":[[119,4]]}}}],["0fa3c3559f0d4f39ba7aa70c7f7188ca",{"_index":337,"t":{"27":{"position":[[1433,32]]}}}],["0s",{"_index":8294,"t":{"2148":{"position":[[250,2]]}}}],["0vk4ptyfibgk5dmzwvndzdkqs/qokooupmuobcpapmm11do4ymjbdpeinjayoro6vxttx",{"_index":2090,"t":{"325":{"position":[[4634,69]]}}}],["0x0",{"_index":7300,"t":{"1728":{"position":[[589,3]]}}}],["0x0:(read",{"_index":7299,"t":{"1728":{"position":[[572,10]]}}}],["0~ubuntu",{"_index":7479,"t":{"1764":{"position":[[1854,8],[1965,8],[2076,8],[2187,8],[2298,8],[2409,8],[2520,8],[2631,8],[2742,8],[2853,8],[2964,8],[3075,8]]}}}],["1",{"_index":412,"t":{"37":{"position":[[178,1]]},"40":{"position":[[176,1]]},"131":{"position":[[347,3]]},"202":{"position":[[258,3]]},"214":{"position":[[138,1]]},"321":{"position":[[846,2]]},"393":{"position":[[881,1],[916,1],[1000,1],[1297,1],[1350,1],[1382,1],[1449,1]]},"404":{"position":[[416,1]]},"436":{"position":[[403,3],[442,1],[1287,1]]},"447":{"position":[[302,1]]},"449":{"position":[[406,1]]},"456":{"position":[[114,1]]},"458":{"position":[[181,1]]},"472":{"position":[[2153,1]]},"487":{"position":[[1578,1]]},"586":{"position":[[460,1]]},"609":{"position":[[2854,2]]},"635":{"position":[[2404,2],[2647,2],[2910,2],[3151,2]]},"641":{"position":[[970,1],[972,1],[1057,1],[1059,1]]},"644":{"position":[[469,1]]},"650":{"position":[[1148,4]]},"652":{"position":[[724,2]]},"660":{"position":[[1398,1],[2650,1],[2796,1]]},"750":{"position":[[468,1]]},"790":{"position":[[816,1]]},"813":{"position":[[537,1],[653,1]]},"821":{"position":[[5243,2],[5386,2],[5508,3]]},"857":{"position":[[307,1],[320,1],[429,1],[445,1]]},"859":{"position":[[3038,1],[3243,2],[3481,2],[3796,2],[3911,2]]},"909":{"position":[[931,1]]},"911":{"position":[[86,1],[1577,1]]},"913":{"position":[[618,1]]},"942":{"position":[[84,3]]},"947":{"position":[[2048,1]]},"982":{"position":[[803,1]]},"990":{"position":[[526,1]]},"1031":{"position":[[500,1],[635,1]]},"1039":{"position":[[478,1]]},"1063":{"position":[[850,4]]},"1071":{"position":[[1458,1],[1491,1],[1507,1]]},"1112":{"position":[[5285,1],[5287,1],[5350,1],[5352,1]]},"1114":{"position":[[2424,1],[2426,1],[2489,1],[2491,1],[2557,1],[3458,1],[5928,1],[5930,1],[5992,1],[5994,1],[6056,1],[6058,1],[6120,1],[6122,1]]},"1122":{"position":[[661,1],[690,1],[755,1]]},"1124":{"position":[[1039,2],[1057,1],[1216,1],[1349,1],[1372,1],[1413,1],[1424,2]]},"1144":{"position":[[54,2]]},"1165":{"position":[[2877,1]]},"1167":{"position":[[1066,1],[1073,1],[2975,1],[3006,1]]},"1184":{"position":[[477,1]]},"1213":{"position":[[1119,2]]},"1219":{"position":[[285,2]]},"1234":{"position":[[2784,2]]},"1256":{"position":[[1876,2]]},"1298":{"position":[[456,1],[499,1],[607,1],[662,1]]},"1305":{"position":[[194,1],[196,1],[280,1],[351,1],[353,1],[355,1],[436,1],[438,1],[440,1],[502,1],[504,1]]},"1317":{"position":[[3801,1],[3936,1],[4071,1],[4206,1]]},"1321":{"position":[[99,2],[1084,1]]},"1337":{"position":[[159,1]]},"1339":{"position":[[196,1]]},"1347":{"position":[[461,1],[650,1],[744,1],[838,1],[1101,1],[1152,1],[1254,1],[1305,1],[1407,1],[1458,1],[1930,1]]},"1366":{"position":[[497,1],[520,1]]},"1368":{"position":[[932,2],[1345,1],[1370,1]]},"1430":{"position":[[92,1],[253,1],[255,1],[885,1],[1046,1],[1048,1],[1528,1],[1689,1],[1691,1]]},"1503":{"position":[[537,1],[653,1]]},"1511":{"position":[[5243,2],[5386,2],[5508,3]]},"1527":{"position":[[816,1]]},"1562":{"position":[[123,1],[509,1],[576,1],[678,1]]},"1566":{"position":[[239,1]]},"1571":{"position":[[92,1]]},"1585":{"position":[[1724,1]]},"1587":{"position":[[791,1]]},"1601":{"position":[[307,1],[320,1],[429,1],[445,1]]},"1603":{"position":[[3038,1],[3243,2],[3481,2],[3796,2],[3911,2]]},"1631":{"position":[[931,1]]},"1633":{"position":[[86,1],[1577,1]]},"1635":{"position":[[618,1]]},"1664":{"position":[[84,3]]},"1669":{"position":[[2048,1]]},"1690":{"position":[[2185,1],[2256,1]]},"1721":{"position":[[3980,2]]},"1728":{"position":[[737,1],[810,1],[872,1]]},"1731":{"position":[[1389,1],[1536,1],[1673,1],[1793,1],[1917,1],[2052,1],[2204,1],[2328,1],[2471,1],[2601,1],[2724,1],[2871,1]]},"1764":{"position":[[3818,1],[4289,2]]},"1775":{"position":[[166,1],[211,1],[225,1],[276,1],[286,1],[306,1]]},"1787":{"position":[[825,1]]},"1789":{"position":[[625,2]]},"1805":{"position":[[190,1]]},"1822":{"position":[[194,1]]},"1833":{"position":[[258,1],[806,1],[996,1]]},"1855":{"position":[[1028,2]]},"1917":{"position":[[1028,2]]},"1974":{"position":[[559,1]]},"1982":{"position":[[1191,1]]},"1984":{"position":[[801,1]]},"2096":{"position":[[1274,1]]},"2098":{"position":[[1852,10],[2160,10]]},"2116":{"position":[[746,1],[878,1]]},"2150":{"position":[[412,1]]},"2164":{"position":[[208,3],[523,2],[814,2]]},"2206":{"position":[[23,1]]},"2224":{"position":[[209,1]]},"2229":{"position":[[815,3]]},"2312":{"position":[[348,1]]},"2356":{"position":[[931,1]]},"2358":{"position":[[86,1],[1577,1]]},"2360":{"position":[[618,1]]},"2389":{"position":[[84,3]]},"2394":{"position":[[2048,1]]},"2566":{"position":[[333,2],[336,3],[384,3]]},"2625":{"position":[[1606,1]]},"2631":{"position":[[467,2],[1823,2]]},"2671":{"position":[[501,1],[670,1],[731,1],[926,1],[1090,1]]},"2705":{"position":[[604,3]]},"2711":{"position":[[547,2],[557,1],[642,1]]},"2713":{"position":[[339,1],[396,1],[502,2]]},"2725":{"position":[[424,1],[438,1]]},"2733":{"position":[[189,1],[489,1]]},"2735":{"position":[[8,1],[372,1],[1070,2],[1267,1]]},"2750":{"position":[[604,3]]},"2756":{"position":[[438,2],[506,1],[511,2],[537,1],[585,1]]},"2764":{"position":[[645,1],[659,1]]},"2772":{"position":[[189,1],[489,1]]},"2774":{"position":[[144,1],[508,1],[1072,2],[1269,1]]},"2840":{"position":[[499,3]]},"2850":{"position":[[333,1],[347,1]]},"2854":{"position":[[189,1],[490,1]]},"2858":{"position":[[499,2]]},"2923":{"position":[[111,1],[388,3]]},"2927":{"position":[[77,1],[221,1],[388,1],[465,1],[467,1],[482,1]]},"2929":{"position":[[80,1],[233,1],[425,1],[537,1],[541,1],[556,1]]},"2933":{"position":[[114,1]]},"2942":{"position":[[561,1]]},"2999":{"position":[[83,1]]},"3011":{"position":[[7,2]]},"3061":{"position":[[906,2],[1252,2]]},"3065":{"position":[[85,1]]},"3071":{"position":[[2464,1],[2478,2]]},"3115":{"position":[[129,2]]},"3124":{"position":[[934,1]]},"3128":{"position":[[325,1]]},"3167":{"position":[[430,1]]},"3184":{"position":[[628,3],[1642,3]]},"3188":{"position":[[43,1]]},"3274":{"position":[[588,1]]},"3276":{"position":[[2721,1]]},"3284":{"position":[[217,1]]},"3357":{"position":[[244,1],[418,2],[445,2],[483,2]]},"3400":{"position":[[416,1]]},"3468":{"position":[[504,1]]},"3508":{"position":[[7,2],[17,1]]}}}],["1%02d",{"_index":3229,"t":{"609":{"position":[[3257,8],[3371,8],[3929,8],[4043,8],[5757,8],[5871,8]]},"635":{"position":[[3610,8]]}}}],["1)[f:5",{"_index":6452,"t":{"1333":{"position":[[160,9],[304,9]]}}}],["1,3",{"_index":5410,"t":{"1124":{"position":[[516,3]]}}}],["1.0",{"_index":3634,"t":{"730":{"position":[[2399,3]]},"1165":{"position":[[1712,3],[1748,3]]},"1491":{"position":[[2399,3]]}}}],["1.0.0",{"_index":9023,"t":{"2627":{"position":[[1007,6]]}}}],["1.0.x",{"_index":8411,"t":{"2245":{"position":[[129,5]]}}}],["1.00000",{"_index":6886,"t":{"1430":{"position":[[169,7],[177,7],[208,7],[216,7],[278,7],[286,7],[317,7],[325,7],[387,7],[395,7],[426,7],[434,7],[962,7],[970,7],[1001,7],[1009,7],[1071,7],[1079,7],[1110,7],[1118,7],[1168,7],[1176,7],[1201,7],[1209,7],[1605,7],[1613,7],[1644,7],[1652,7],[1714,7],[1722,7],[1753,7],[1761,7]]}}}],["1.1",{"_index":7708,"t":{"1825":{"position":[[370,4]]}}}],["1.12.4",{"_index":3406,"t":{"641":{"position":[[653,6]]}}}],["1.13",{"_index":9967,"t":{"3236":{"position":[[688,5],[816,5]]},"3270":{"position":[[1100,4]]}}}],["1.14/samples/bookinfo/platform/kube/bookinfo.yaml",{"_index":3388,"t":{"637":{"position":[[442,49]]}}}],["1.16",{"_index":2458,"t":{"421":{"position":[[685,4]]},"465":{"position":[[565,4]]}}}],["1.18.x",{"_index":2252,"t":{"379":{"position":[[167,6]]}}}],["1.2",{"_index":2255,"t":{"379":{"position":[[404,3]]},"1825":{"position":[[567,4]]}}}],["1.2.x",{"_index":8449,"t":{"2278":{"position":[[120,5]]}}}],["1.20",{"_index":2580,"t":{"465":{"position":[[108,4]]}}}],["1.21.5",{"_index":8383,"t":{"2206":{"position":[[228,8]]}}}],["1.22",{"_index":8409,"t":{"2245":{"position":[[33,4]]}}}],["1.23",{"_index":8410,"t":{"2245":{"position":[[42,4]]}}}],["1.25",{"_index":2809,"t":{"487":{"position":[[4372,5]]},"2278":{"position":[[33,4]]}}}],["1.25.11",{"_index":2743,"t":{"487":{"position":[[928,8]]}}}],["1.25.latest",{"_index":2664,"t":{"479":{"position":[[26,11]]}}}],["1.26.6",{"_index":2742,"t":{"487":{"position":[[920,7]]}}}],["1.27",{"_index":8526,"t":{"2405":{"position":[[93,4]]}}}],["1.27.3",{"_index":2741,"t":{"487":{"position":[[912,7]]}}}],["1.28",{"_index":3521,"t":{"660":{"position":[[800,6],[1363,4]]}}}],["1.28.latest",{"_index":2665,"t":{"479":{"position":[[42,12]]}}}],["1.3",{"_index":7709,"t":{"1825":{"position":[[772,4]]}}}],["1.3.0",{"_index":3787,"t":{"798":{"position":[[814,7],[1171,5]]},"1535":{"position":[[814,7],[1171,5]]}}}],["1.4",{"_index":7710,"t":{"1825":{"position":[[1801,4]]}}}],["1.4.0",{"_index":3790,"t":{"798":{"position":[[917,7],[1187,5]]},"1535":{"position":[[917,7],[1187,5]]}}}],["1.4.1",{"_index":3792,"t":{"798":{"position":[[1020,7],[1203,5]]},"1535":{"position":[[1020,7],[1203,5]]}}}],["1.5",{"_index":9209,"t":{"2713":{"position":[[495,3]]},"2756":{"position":[[431,3],[457,3]]}}}],["1.5n",{"_index":9180,"t":{"2709":{"position":[[2202,4]]},"2754":{"position":[[2157,4]]}}}],["1.6.3",{"_index":2677,"t":{"483":{"position":[[504,5]]}}}],["1.8.0",{"_index":3380,"t":{"635":{"position":[[3855,5]]}}}],["1.8.1",{"_index":3382,"t":{"635":{"position":[[3884,6]]}}}],["1.9.0",{"_index":2402,"t":{"409":{"position":[[249,5]]}}}],["1.92",{"_index":4698,"t":{"984":{"position":[[300,4]]},"990":{"position":[[307,4]]}}}],["1.de.pool.ntp.org",{"_index":4994,"t":{"1067":{"position":[[5725,17]]}}}],["1.docker.io",{"_index":3354,"t":{"635":{"position":[[1411,12]]}}}],["1.iso",{"_index":7004,"t":{"1569":{"position":[[372,5]]}}}],["1.testbed.osism.xyz",{"_index":4826,"t":{"1039":{"position":[[502,19]]},"1055":{"position":[[2112,19],[2252,19]]},"1317":{"position":[[8283,19]]},"1325":{"position":[[232,19],[768,19]]},"1787":{"position":[[792,19]]}}}],["1.testbed.osism.xyz:1984",{"_index":7604,"t":{"1789":{"position":[[648,24]]}}}],["1/1",{"_index":3411,"t":{"641":{"position":[[966,3],[1053,3],[1199,3],[1237,3]]}}}],["1/100m",{"_index":9607,"t":{"2947":{"position":[[1985,8],[2491,7]]}}}],["1/19",{"_index":4907,"t":{"1063":{"position":[[833,6]]}}}],["1/250m",{"_index":9611,"t":{"2947":{"position":[[2509,7]]}}}],["1/4",{"_index":9364,"t":{"2766":{"position":[[1203,3]]}}}],["10",{"_index":338,"t":{"27":{"position":[[1481,2]]},"321":{"position":[[1525,3]]},"381":{"position":[[777,3],[821,2],[1019,2]]},"472":{"position":[[2424,2]]},"483":{"position":[[1166,2]]},"588":{"position":[[68,2]]},"738":{"position":[[462,4]]},"821":{"position":[[5416,3]]},"838":{"position":[[80,2],[176,2]]},"857":{"position":[[225,2]]},"911":{"position":[[431,2],[547,2]]},"932":{"position":[[2340,2],[2370,2]]},"954":{"position":[[293,2]]},"1055":{"position":[[1472,2]]},"1091":{"position":[[479,2]]},"1106":{"position":[[349,2]]},"1112":{"position":[[862,2]]},"1120":{"position":[[1774,2]]},"1124":{"position":[[1075,2],[1418,2],[1430,2]]},"1217":{"position":[[715,2]]},"1234":{"position":[[2089,3],[2821,3]]},"1317":{"position":[[7528,2]]},"1321":{"position":[[162,2],[427,2],[591,2],[819,2],[1047,2],[1279,2]]},"1347":{"position":[[403,2],[496,2],[589,2],[1872,2],[1965,2],[2058,2]]},"1386":{"position":[[55,2]]},"1511":{"position":[[5416,3]]},"1553":{"position":[[80,2],[176,2]]},"1585":{"position":[[907,2],[972,2]]},"1601":{"position":[[225,2]]},"1633":{"position":[[431,2],[547,2]]},"1654":{"position":[[2340,2],[2370,2]]},"1764":{"position":[[4052,3],[4314,3]]},"1783":{"position":[[589,2]]},"1808":{"position":[[806,2]]},"2148":{"position":[[507,4]]},"2150":{"position":[[553,2]]},"2263":{"position":[[177,3]]},"2358":{"position":[[431,2],[547,2]]},"2379":{"position":[[2340,2],[2370,2]]},"2536":{"position":[[447,2]]},"2546":{"position":[[591,2]]},"2709":{"position":[[39,3],[1481,3],[1583,2]]},"2711":{"position":[[97,3],[224,2],[360,2]]},"2723":{"position":[[653,2]]},"2754":{"position":[[39,3],[1622,3],[1724,2]]},"2762":{"position":[[666,2]]},"2795":{"position":[[1747,2]]},"2815":{"position":[[1323,2]]},"2856":{"position":[[99,3]]},"2929":{"position":[[77,2],[96,2],[266,2],[285,2]]},"2947":{"position":[[2063,2]]},"3014":{"position":[[92,2],[128,2]]},"3284":{"position":[[160,2]]},"3299":{"position":[[3767,3]]}}}],["10.0.0.0/24",{"_index":2692,"t":{"483":{"position":[[936,11]]}}}],["10.00g",{"_index":5280,"t":{"1114":{"position":[[2331,7],[2578,7]]}}}],["10.1.0.2",{"_index":6705,"t":{"1368":{"position":[[679,10]]}}}],["10.1.0.40",{"_index":6714,"t":{"1368":{"position":[[966,11]]}}}],["10.1.0.43",{"_index":6711,"t":{"1368":{"position":[[870,11]]}}}],["10.1.0.45",{"_index":6708,"t":{"1368":{"position":[[774,11]]}}}],["10.1.0.79",{"_index":6806,"t":{"1386":{"position":[[192,9]]}}}],["10.10.0.100",{"_index":6142,"t":{"1282":{"position":[[92,11]]}}}],["10.10.129.64:9155",{"_index":6615,"t":{"1360":{"position":[[2727,17]]}}}],["10.10.42.10",{"_index":5123,"t":{"1098":{"position":[[236,11],[708,11]]}}}],["10.10.42.10/32",{"_index":5127,"t":{"1098":{"position":[[558,14]]}}}],["10.109.57.148",{"_index":3417,"t":{"641":{"position":[[1695,13]]}}}],["10.15.0.33",{"_index":6025,"t":{"1224":{"position":[[3448,10]]}}}],["10.3.0.1",{"_index":5107,"t":{"1091":{"position":[[385,8]]}}}],["10.3.0.5/23",{"_index":5105,"t":{"1091":{"position":[[269,13]]}}}],["10.3.98.5/24",{"_index":5111,"t":{"1091":{"position":[[508,14]]}}}],["10.3.99.5/24",{"_index":5109,"t":{"1091":{"position":[[450,14]]}}}],["10.50.40.230",{"_index":7721,"t":{"1829":{"position":[[206,14]]}}}],["10.8.0.0/20",{"_index":2726,"t":{"487":{"position":[[124,11]]}}}],["10.96.0.0/12",{"_index":2730,"t":{"487":{"position":[[301,12]]}}}],["10/",{"_index":9610,"t":{"2947":{"position":[[2499,6]]}}}],["10/19",{"_index":4925,"t":{"1063":{"position":[[1108,7]]}}}],["10/20",{"_index":4889,"t":{"1061":{"position":[[524,7]]}}}],["100",{"_index":2278,"t":{"381":{"position":[[550,4],[590,5],[694,6],[1109,4]]},"633":{"position":[[713,3]]},"694":{"position":[[96,4]]},"821":{"position":[[2979,5]]},"1165":{"position":[[1417,3],[2809,3],[3591,3]]},"1224":{"position":[[3406,3]]},"1234":{"position":[[2551,3]]},"1511":{"position":[[2979,5]]},"1571":{"position":[[468,3]]},"1859":{"position":[[633,4]]},"1921":{"position":[[633,4]]},"2709":{"position":[[51,4]]},"2711":{"position":[[109,4],[308,3],[447,3],[532,3]]},"2713":{"position":[[806,5]]},"2754":{"position":[[51,4]]},"2756":{"position":[[1274,5]]},"2856":{"position":[[111,4]]},"2927":{"position":[[155,4],[177,3]]},"2929":{"position":[[191,3],[212,3],[381,3],[403,3],[499,3],[520,3]]},"2949":{"position":[[54,4]]},"3299":{"position":[[3362,4]]},"3312":{"position":[[175,4]]},"3343":{"position":[[955,3]]},"3357":{"position":[[492,3],[748,3],[859,4],[875,3],[946,3],[1051,3]]}}}],["100.88.40.231",{"_index":2424,"t":{"413":{"position":[[392,13]]},"442":{"position":[[311,13]]}}}],["100.92.14.168",{"_index":2418,"t":{"413":{"position":[[285,13]]},"442":{"position":[[204,13]]}}}],["1000",{"_index":3899,"t":{"821":{"position":[[2918,5]]},"1351":{"position":[[114,4],[133,4],[1958,4],[1995,4]]},"1368":{"position":[[1817,4],[2496,4]]},"1511":{"position":[[2918,5]]},"2709":{"position":[[66,5]]},"2754":{"position":[[66,5]]},"2911":{"position":[[299,4],[365,4]]},"2923":{"position":[[681,4]]},"2949":{"position":[[490,4]]}}}],["10000baset/ful",{"_index":7079,"t":{"1585":{"position":[[1579,15]]}}}],["10001",{"_index":7385,"t":{"1743":{"position":[[2516,5]]}}}],["1000gb",{"_index":9181,"t":{"2711":{"position":[[124,7]]},"2856":{"position":[[126,7]]}}}],["100g",{"_index":4693,"t":{"982":{"position":[[709,4]]},"984":{"position":[[576,4]]},"986":{"position":[[308,4],[340,4]]},"988":{"position":[[414,4]]},"990":{"position":[[477,4]]},"995":{"position":[[32,4],[578,4],[781,5]]},"997":{"position":[[0,5]]}}}],["100m",{"_index":9609,"t":{"2947":{"position":[[2303,5]]}}}],["1024",{"_index":3910,"t":{"821":{"position":[[4091,5],[4158,5]]},"1511":{"position":[[4091,5],[4158,5]]}}}],["10240",{"_index":3884,"t":{"821":{"position":[[2520,6],[3829,6],[5168,6]]},"1511":{"position":[[2520,6],[3829,6],[5168,6]]}}}],["10250",{"_index":9963,"t":{"3236":{"position":[[606,5]]}}}],["10251",{"_index":9966,"t":{"3236":{"position":[[657,5]]}}}],["10251/10259",{"_index":9965,"t":{"3236":{"position":[[630,11]]}}}],["10252",{"_index":9970,"t":{"3236":{"position":[[785,5]]}}}],["10252/10257",{"_index":9969,"t":{"3236":{"position":[[749,11]]}}}],["10255",{"_index":9976,"t":{"3236":{"position":[[1008,6]]}}}],["10257",{"_index":9971,"t":{"3236":{"position":[[854,5]]}}}],["10259",{"_index":9968,"t":{"3236":{"position":[[726,5]]}}}],["1039",{"_index":6445,"t":{"1321":{"position":[[1971,6]]}}}],["10483679",{"_index":5311,"t":{"1114":{"position":[[3886,8]]}}}],["1048576",{"_index":4803,"t":{"1031":{"position":[[676,7]]},"1379":{"position":[[666,7]]}}}],["10485760",{"_index":5300,"t":{"1114":{"position":[[3715,8],[3772,8],[3829,8]]}}}],["10487807",{"_index":5299,"t":{"1114":{"position":[[3706,8]]}}}],["10487808",{"_index":5303,"t":{"1114":{"position":[[3754,8]]}}}],["105.0b",{"_index":6407,"t":{"1321":{"position":[[709,8]]}}}],["107.4460",{"_index":4256,"t":{"859":{"position":[[6436,9]]},"1603":{"position":[[6436,9]]}}}],["1073741824",{"_index":5481,"t":{"1144":{"position":[[43,10]]},"1379":{"position":[[336,10],[834,10]]}}}],["10:09:25",{"_index":6242,"t":{"1311":{"position":[[25,8]]}}}],["10:45:36",{"_index":6383,"t":{"1321":{"position":[[109,8]]}}}],["10:52:44",{"_index":5013,"t":{"1077":{"position":[[564,8],[672,8]]}}}],["10:53:08",{"_index":5020,"t":{"1077":{"position":[[1030,8],[1137,8]]}}}],["10:57:33",{"_index":6441,"t":{"1321":{"position":[[1926,9]]}}}],["10^9",{"_index":9525,"t":{"2892":{"position":[[472,4]]}}}],["10_bms_hwv",{"_index":9246,"t":{"2723":{"position":[[823,10]]},"2762":{"position":[[836,10]]}}}],["10_bms_z3",{"_index":9173,"t":{"2709":{"position":[[1621,9]]},"2754":{"position":[[1762,9]]}}}],["10_hwv",{"_index":9245,"t":{"2723":{"position":[[776,6]]},"2762":{"position":[[789,6]]}}}],["10_hwv_xen",{"_index":9248,"t":{"2723":{"position":[[917,10]]},"2762":{"position":[[930,10]]}}}],["10_kvm_hwv",{"_index":9244,"t":{"2723":{"position":[[715,10]]},"2762":{"position":[[728,10]]}}}],["10d",{"_index":8304,"t":{"2150":{"position":[[61,3]]}}}],["10g",{"_index":4720,"t":{"993":{"position":[[24,4]]}}}],["10gb",{"_index":9171,"t":{"2709":{"position":[[1542,4],[2180,4]]},"2733":{"position":[[68,4]]},"2754":{"position":[[1683,4],[2135,4]]},"2772":{"position":[[68,4]]},"2844":{"position":[[1336,4],[1973,4]]},"2854":{"position":[[68,4]]}}}],["10gib",{"_index":9157,"t":{"2707":{"position":[[202,7]]},"2752":{"position":[[202,7]]},"2842":{"position":[[201,7]]}}}],["10k",{"_index":9630,"t":{"2949":{"position":[[654,4]]}}}],["10m",{"_index":6007,"t":{"1217":{"position":[[249,3],[739,4]]}}}],["10n",{"_index":9150,"t":{"2705":{"position":[[2056,3],[2069,3],[2082,3],[2095,3],[2109,3],[2123,3],[2158,3]]},"2707":{"position":[[384,3],[399,3],[413,3],[427,3],[442,3],[457,3]]},"2709":{"position":[[1468,3]]},"2721":{"position":[[265,3]]},"2725":{"position":[[994,3]]},"2733":{"position":[[26,3]]},"2750":{"position":[[2358,3],[2371,3],[2384,3],[2397,3],[2411,3],[2425,3],[2460,3]]},"2752":{"position":[[384,3],[399,3],[413,3],[427,3],[442,3],[457,3]]},"2754":{"position":[[1609,3]]},"2760":{"position":[[277,3]]},"2764":{"position":[[1569,3]]},"2772":{"position":[[26,3]]}}}],["10n_bm",{"_index":9238,"t":{"2721":{"position":[[278,7]]},"2760":{"position":[[290,7]]}}}],["10n_bms_z",{"_index":9277,"t":{"2725":{"position":[[1073,9]]},"2764":{"position":[[1648,9]]}}}],["10n_bms_z3",{"_index":9278,"t":{"2725":{"position":[[1092,10],[1112,10]]},"2764":{"position":[[1667,10],[1687,10]]}}}],["10n_bms_z3h",{"_index":9239,"t":{"2721":{"position":[[295,11]]},"2725":{"position":[[1132,11]]},"2760":{"position":[[307,11]]},"2764":{"position":[[1707,11]]}}}],["10n_bms_z3hh",{"_index":9279,"t":{"2725":{"position":[[1153,12]]},"2764":{"position":[[1728,12]]}}}],["10n_z",{"_index":9273,"t":{"2725":{"position":[[1007,5]]},"2764":{"position":[[1582,5]]}}}],["10n_z3",{"_index":9274,"t":{"2725":{"position":[[1022,6]]},"2764":{"position":[[1597,6]]}}}],["10n_z3h",{"_index":9275,"t":{"2725":{"position":[[1038,7]]},"2764":{"position":[[1613,7]]}}}],["10n_z3hh",{"_index":9276,"t":{"2725":{"position":[[1055,8]]},"2764":{"position":[[1630,8]]}}}],["10s_bms_z3",{"_index":9169,"t":{"2709":{"position":[[1494,10]]},"2754":{"position":[[1635,10]]}}}],["11",{"_index":2024,"t":{"321":{"position":[[1602,3]]},"840":{"position":[[32,2]]},"842":{"position":[[32,2],[84,2],[137,2],[192,2],[248,2],[303,2],[362,2],[421,2],[483,2],[549,2],[602,2]]},"850":{"position":[[3017,2],[3155,2],[3395,2],[3835,2],[9706,2]]},"1124":{"position":[[1078,2]]},"1298":{"position":[[621,2]]},"1484":{"position":[[3017,2],[3155,2],[3395,2],[3835,2],[9706,2]]},"1555":{"position":[[32,2]]},"1557":{"position":[[32,2],[84,2],[137,2],[192,2],[248,2],[303,2],[362,2],[421,2],[483,2],[549,2],[602,2]]},"1721":{"position":[[25,2],[101,2],[153,2],[182,2],[287,2],[442,2],[594,2],[748,2],[914,2],[1082,2],[1234,2],[1389,2],[1551,2],[1704,2],[1857,2],[2011,2],[2166,2],[2321,2],[2475,2],[2628,2],[2785,2],[2945,2],[3090,2],[3242,2],[3393,2],[3437,2],[3503,2],[3612,2],[3662,2],[3708,2],[3779,2],[3831,2],[3860,2],[3935,2],[3988,2],[4042,2],[4070,2]]},"2524":{"position":[[391,2]]},"2536":{"position":[[501,2]]},"2795":{"position":[[1811,2]]},"2809":{"position":[[296,2]]},"2815":{"position":[[1349,2],[1503,2]]},"2987":{"position":[[661,3]]},"3251":{"position":[[3029,3]]}}}],["11/19",{"_index":4926,"t":{"1063":{"position":[[1177,7]]}}}],["11/20",{"_index":4893,"t":{"1061":{"position":[[618,7]]}}}],["110b1bea",{"_index":9818,"t":{"3109":{"position":[[1748,8]]}}}],["110d",{"_index":4706,"t":{"988":{"position":[[209,4]]}}}],["111",{"_index":7354,"t":{"1734":{"position":[[291,4]]}}}],["112",{"_index":7525,"t":{"1775":{"position":[[142,3]]},"3276":{"position":[[2667,4]]}}}],["11:19:57",{"_index":6399,"t":{"1321":{"position":[[382,8],[546,8]]}}}],["11:19:58",{"_index":6413,"t":{"1321":{"position":[[766,8],[996,8],[1234,8]]}}}],["11:47:16",{"_index":4189,"t":{"859":{"position":[[2529,8]]},"1603":{"position":[[2529,8]]}}}],["11:47:17",{"_index":4190,"t":{"859":{"position":[[2583,8],[2661,8],[2718,8],[2795,8]]},"1603":{"position":[[2583,8],[2661,8],[2718,8],[2795,8]]}}}],["11:47:18",{"_index":4203,"t":{"859":{"position":[[2850,8],[2929,8],[2990,8],[3051,8],[3154,8]]},"1603":{"position":[[2850,8],[2929,8],[2990,8],[3051,8],[3154,8]]}}}],["11:47:28",{"_index":4220,"t":{"859":{"position":[[3257,8]]},"1603":{"position":[[3257,8]]}}}],["11:47:29",{"_index":4221,"t":{"859":{"position":[[3376,8]]},"1603":{"position":[[3376,8]]}}}],["11:47:39",{"_index":4222,"t":{"859":{"position":[[3495,8],[3595,8],[3710,8]]},"1603":{"position":[[3495,8],[3595,8],[3710,8]]}}}],["11:47:40",{"_index":4223,"t":{"859":{"position":[[3810,8]]},"1603":{"position":[[3810,8]]}}}],["11:47:49",{"_index":4224,"t":{"859":{"position":[[3925,8]]},"1603":{"position":[[3925,8]]}}}],["11:47:50",{"_index":4225,"t":{"859":{"position":[[3986,8],[4047,8]]},"1603":{"position":[[3986,8],[4047,8]]}}}],["11:47:51",{"_index":4231,"t":{"859":{"position":[[4150,8]]},"1603":{"position":[[4150,8]]}}}],["11:48:00",{"_index":4237,"t":{"859":{"position":[[4253,8]]},"1603":{"position":[[4253,8]]}}}],["11:48:01",{"_index":4238,"t":{"859":{"position":[[4372,8]]},"1603":{"position":[[4372,8]]}}}],["11:48:11",{"_index":4239,"t":{"859":{"position":[[4491,8]]},"1603":{"position":[[4491,8]]}}}],["11:48:12",{"_index":4240,"t":{"859":{"position":[[4591,8],[4706,8],[4806,8]]},"1603":{"position":[[4591,8],[4706,8],[4806,8]]}}}],["11:48:22",{"_index":4241,"t":{"859":{"position":[[4921,8],[4982,8],[5085,8]]},"1603":{"position":[[4921,8],[4982,8],[5085,8]]}}}],["11:48:23",{"_index":4247,"t":{"859":{"position":[[5146,8]]},"1603":{"position":[[5146,8]]}}}],["11:48:43",{"_index":4253,"t":{"859":{"position":[[5249,8],[5368,8]]},"1603":{"position":[[5249,8],[5368,8]]}}}],["11:48:55",{"_index":4254,"t":{"859":{"position":[[5487,8],[5587,8],[5687,8],[5802,8]]},"1603":{"position":[[5487,8],[5587,8],[5687,8],[5802,8]]}}}],["11:49:05",{"_index":4255,"t":{"859":{"position":[[5917,8],[5999,8],[6081,8],[6163,8],[6245,8],[6327,8],[6409,8]]},"1603":{"position":[[5917,8],[5999,8],[6081,8],[6163,8],[6245,8],[6327,8],[6409,8]]}}}],["11dd",{"_index":4206,"t":{"859":{"position":[[2890,4]]},"1603":{"position":[[2890,4]]},"1845":{"position":[[1917,4],[2694,4]]}}}],["11m",{"_index":3410,"t":{"641":{"position":[[930,3],[974,3],[1020,3],[1061,3],[1103,3],[1147,3],[1203,3],[1241,3],[1279,3],[1723,3]]}}}],["12",{"_index":2674,"t":{"483":{"position":[[376,3]]},"838":{"position":[[83,2],[179,2]]},"840":{"position":[[29,2]]},"842":{"position":[[29,2],[81,2],[134,2],[189,2],[245,2],[300,2],[359,2],[418,2],[480,2],[546,2],[599,2]]},"850":{"position":[[3937,2],[4081,2],[4333,2],[5083,2],[9070,2],[9104,2],[9377,4],[9640,2],[9937,2]]},"895":{"position":[[359,2]]},"897":{"position":[[21,2]]},"903":{"position":[[1690,2],[1751,3]]},"909":{"position":[[849,3],[874,3],[2773,2]]},"913":{"position":[[359,3],[384,3]]},"926":{"position":[[30,3]]},"1124":{"position":[[1081,2]]},"1362":{"position":[[1132,2]]},"1375":{"position":[[763,2],[1573,2]]},"1377":{"position":[[766,2],[1768,2]]},"1484":{"position":[[3937,2],[4081,2],[4333,2],[5083,2],[9070,2],[9104,2],[9377,4],[9640,2],[9937,2]]},"1553":{"position":[[83,2],[179,2]]},"1555":{"position":[[29,2]]},"1557":{"position":[[29,2],[81,2],[134,2],[189,2],[245,2],[300,2],[359,2],[418,2],[480,2],[546,2],[599,2]]},"1617":{"position":[[359,2]]},"1619":{"position":[[21,2]]},"1625":{"position":[[1690,2],[1751,3]]},"1631":{"position":[[849,3],[874,3],[2773,2]]},"1635":{"position":[[359,3],[384,3]]},"1648":{"position":[[30,3]]},"2033":{"position":[[1716,3]]},"2342":{"position":[[359,2]]},"2344":{"position":[[21,2]]},"2350":{"position":[[1690,2],[1751,3]]},"2356":{"position":[[849,3],[874,3],[2773,2]]},"2360":{"position":[[359,3],[384,3]]},"2373":{"position":[[30,3]]},"2405":{"position":[[448,3]]},"2688":{"position":[[1546,2]]},"2895":{"position":[[4424,2]]},"2983":{"position":[[67,3]]},"2987":{"position":[[530,3]]},"3124":{"position":[[382,2]]},"3167":{"position":[[684,2]]}}}],["12.qcow2",{"_index":4164,"t":{"850":{"position":[[10128,8]]},"1484":{"position":[[10128,8]]}}}],["12/19",{"_index":4927,"t":{"1063":{"position":[[1205,7]]}}}],["12/20",{"_index":4895,"t":{"1061":{"position":[[646,7]]}}}],["12/20240411",{"_index":4163,"t":{"850":{"position":[[10109,11]]},"1484":{"position":[[10109,11]]}}}],["120",{"_index":4355,"t":{"903":{"position":[[2879,3]]},"1571":{"position":[[173,3],[293,3]]},"1625":{"position":[[2879,3]]},"1779":{"position":[[4038,3]]},"2350":{"position":[[2879,3]]},"3284":{"position":[[184,3]]}}}],["121c",{"_index":4696,"t":{"982":{"position":[[920,4]]},"990":{"position":[[643,4]]}}}],["123",{"_index":7535,"t":{"1779":{"position":[[1489,3]]}}}],["1234",{"_index":9039,"t":{"2647":{"position":[[781,4]]}}}],["1264",{"_index":5239,"t":{"1112":{"position":[[4354,4],[4528,4],[4579,4],[5153,4],[5322,4],[5578,4],[5620,4]]}}}],["127.0.0.1",{"_index":5112,"t":{"1091":{"position":[[551,11]]}}}],["127.0.0.1:8080",{"_index":3420,"t":{"641":{"position":[[1827,14]]}}}],["128",{"_index":3890,"t":{"821":{"position":[[2631,4],[3944,4],[5280,4]]},"982":{"position":[[591,3]]},"990":{"position":[[413,3],[431,3]]},"1511":{"position":[[2631,4],[3944,4],[5280,4]]}}}],["12g",{"_index":9204,"t":{"2711":{"position":[[1578,3]]},"2856":{"position":[[1556,3]]},"2933":{"position":[[1109,3]]}}}],["13",{"_index":5418,"t":{"1124":{"position":[[1084,2]]},"1728":{"position":[[602,2],[890,2]]},"2586":{"position":[[447,2]]},"2895":{"position":[[1724,2]]},"3482":{"position":[[92,2]]}}}],["13/19",{"_index":4928,"t":{"1063":{"position":[[1233,7]]}}}],["13:03:14",{"_index":3608,"t":{"730":{"position":[[1232,8],[1285,8],[1338,8],[1392,8]]},"1491":{"position":[[1232,8],[1285,8],[1338,8],[1392,8]]}}}],["13k",{"_index":10063,"t":{"3299":{"position":[[2011,4]]}}}],["13m",{"_index":3458,"t":{"646":{"position":[[564,3],[765,3],[1537,3]]}}}],["14",{"_index":5419,"t":{"1124":{"position":[[1087,2]]},"1317":{"position":[[8119,2],[8318,2],[8417,2],[8993,2]]},"2536":{"position":[[543,2]]},"2554":{"position":[[84,2]]},"2766":{"position":[[1085,2]]},"2817":{"position":[[429,2]]},"2895":{"position":[[1402,2],[1483,3],[1655,3],[1667,3],[1691,3]]},"3124":{"position":[[371,2]]},"3167":{"position":[[663,2]]}}}],["14/19",{"_index":4931,"t":{"1063":{"position":[[1269,7]]}}}],["140",{"_index":9578,"t":{"2911":{"position":[[267,3]]}}}],["14062414.575715",{"_index":7280,"t":{"1728":{"position":[[109,17]]}}}],["14062414.575722",{"_index":7286,"t":{"1728":{"position":[[218,17]]}}}],["14062414.575725",{"_index":7288,"t":{"1728":{"position":[[312,17]]}}}],["14062414.575728",{"_index":7290,"t":{"1728":{"position":[[393,17]]}}}],["14062414.575730",{"_index":7297,"t":{"1728":{"position":[[501,17]]}}}],["143f",{"_index":9800,"t":{"3109":{"position":[[614,4]]}}}],["146",{"_index":6751,"t":{"1368":{"position":[[2730,3]]}}}],["149.112.112.112",{"_index":4937,"t":{"1063":{"position":[[1358,18]]},"1071":{"position":[[1056,15]]}}}],["14:0:5:0",{"_index":7281,"t":{"1728":{"position":[[130,9],[239,9],[333,9],[414,9]]}}}],["14:24:02.873",{"_index":3879,"t":{"821":{"position":[[2072,12]]},"1511":{"position":[[2072,12]]}}}],["14:24:04.886",{"_index":3881,"t":{"821":{"position":[[2164,12],[2264,12]]},"1511":{"position":[[2164,12],[2264,12]]}}}],["14:24:04.953",{"_index":3882,"t":{"821":{"position":[[2410,12],[3017,12]]},"1511":{"position":[[2410,12],[3017,12]]}}}],["14:24:05.048",{"_index":3902,"t":{"821":{"position":[[3091,12]]},"1511":{"position":[[3091,12]]}}}],["14:24:05.175",{"_index":3903,"t":{"821":{"position":[[3165,12]]},"1511":{"position":[[3165,12]]}}}],["14:24:05.286",{"_index":3904,"t":{"821":{"position":[[3238,12]]},"1511":{"position":[[3238,12]]}}}],["14:24:05.349",{"_index":3906,"t":{"821":{"position":[[3347,12]]},"1511":{"position":[[3347,12]]}}}],["14:24:06.081",{"_index":3907,"t":{"821":{"position":[[3468,12],[3569,12]]},"1511":{"position":[[3468,12],[3569,12]]}}}],["14:24:06.131",{"_index":3908,"t":{"821":{"position":[[3716,12],[4353,12]]},"1511":{"position":[[3716,12],[4353,12]]}}}],["14:24:06.212",{"_index":3911,"t":{"821":{"position":[[4428,12]]},"1511":{"position":[[4428,12]]}}}],["14:24:06.330",{"_index":3912,"t":{"821":{"position":[[4503,12]]},"1511":{"position":[[4503,12]]}}}],["14:24:06.467",{"_index":3913,"t":{"821":{"position":[[4577,12]]},"1511":{"position":[[4577,12]]}}}],["14:24:06.589",{"_index":3914,"t":{"821":{"position":[[4687,12]]},"1511":{"position":[[4687,12]]}}}],["14:24:06.840",{"_index":3915,"t":{"821":{"position":[[4809,12],[4910,12]]},"1511":{"position":[[4809,12],[4910,12]]}}}],["14:24:06.915",{"_index":3916,"t":{"821":{"position":[[5057,12],[5670,12]]},"1511":{"position":[[5057,12],[5670,12]]}}}],["14:24:06.993",{"_index":3919,"t":{"821":{"position":[[5745,12]]},"1511":{"position":[[5745,12]]}}}],["14:24:07.114",{"_index":3920,"t":{"821":{"position":[[5820,12]]},"1511":{"position":[[5820,12]]}}}],["14:24:07.254",{"_index":3921,"t":{"821":{"position":[[5894,12]]},"1511":{"position":[[5894,12]]}}}],["14:24:07.334",{"_index":3922,"t":{"821":{"position":[[6004,12]]},"1511":{"position":[[6004,12]]}}}],["14:38:14.149756",{"_index":7212,"t":{"1721":{"position":[[31,15]]}}}],["14:38:18.717886",{"_index":7213,"t":{"1721":{"position":[[107,15]]}}}],["14:38:18.723062",{"_index":7214,"t":{"1721":{"position":[[159,15]]}}}],["14:38:18.723137",{"_index":7215,"t":{"1721":{"position":[[188,15]]}}}],["14:38:18.878508",{"_index":7271,"t":{"1721":{"position":[[4048,16]]}}}],["14:38:19.138060",{"_index":7216,"t":{"1721":{"position":[[293,15]]}}}],["14:38:19.151965",{"_index":7219,"t":{"1721":{"position":[[448,15]]}}}],["14:38:19.163608",{"_index":7221,"t":{"1721":{"position":[[600,15]]}}}],["14:38:19.187772",{"_index":7223,"t":{"1721":{"position":[[754,15]]}}}],["14:38:19.192695",{"_index":7225,"t":{"1721":{"position":[[920,15]]}}}],["14:38:19.219694",{"_index":7227,"t":{"1721":{"position":[[1088,15]]}}}],["14:38:19.230577",{"_index":7229,"t":{"1721":{"position":[[1240,15]]}}}],["14:38:19.275681",{"_index":7231,"t":{"1721":{"position":[[1395,15]]}}}],["14:38:19.300350",{"_index":7233,"t":{"1721":{"position":[[1557,15]]}}}],["14:38:19.310641",{"_index":7235,"t":{"1721":{"position":[[1710,15]]}}}],["14:38:19.318096",{"_index":7237,"t":{"1721":{"position":[[1863,15]]}}}],["14:38:19.329099",{"_index":7239,"t":{"1721":{"position":[[2017,15]]}}}],["14:38:19.344766",{"_index":7241,"t":{"1721":{"position":[[2172,15]]}}}],["14:38:19.358190",{"_index":7243,"t":{"1721":{"position":[[2327,15]]}}}],["14:38:19.363578",{"_index":7245,"t":{"1721":{"position":[[2481,15]]}}}],["14:38:19.389205",{"_index":7247,"t":{"1721":{"position":[[2634,15]]}}}],["14:38:19.406360",{"_index":7249,"t":{"1721":{"position":[[2791,15]]}}}],["14:38:19.415046",{"_index":7251,"t":{"1721":{"position":[[2951,15]]}}}],["14:38:19.473508",{"_index":7253,"t":{"1721":{"position":[[3096,15]]}}}],["14:38:19.908963",{"_index":7255,"t":{"1721":{"position":[[3248,15]]}}}],["14:38:19.914395",{"_index":7257,"t":{"1721":{"position":[[3399,15]]}}}],["14:38:19.914412",{"_index":7258,"t":{"1721":{"position":[[3443,15]]}}}],["14:38:19.914419",{"_index":7260,"t":{"1721":{"position":[[3509,15]]}}}],["14:38:19.932073",{"_index":7267,"t":{"1721":{"position":[[3837,17]]}}}],["14:38:20.249358",{"_index":7261,"t":{"1721":{"position":[[3618,15]]}}}],["14:38:20.249501",{"_index":7262,"t":{"1721":{"position":[[3668,15]]}}}],["14:38:20.249533",{"_index":7263,"t":{"1721":{"position":[[3714,15]]}}}],["14:38:20.249553",{"_index":7266,"t":{"1721":{"position":[[3785,15]]}}}],["14:38:20.249571",{"_index":7268,"t":{"1721":{"position":[[3866,15]]}}}],["14:38:20.249587",{"_index":7269,"t":{"1721":{"position":[[3941,15]]}}}],["14:38:20.249603",{"_index":7270,"t":{"1721":{"position":[[3994,15]]}}}],["14:38:20.249618",{"_index":7272,"t":{"1721":{"position":[[4076,15]]}}}],["14h",{"_index":9362,"t":{"2766":{"position":[[1027,3]]}}}],["14t14:20:24.000000",{"_index":6759,"t":{"1375":{"position":[[766,18]]},"1377":{"position":[[1771,18]]}}}],["14t14:21:47.000000",{"_index":6762,"t":{"1377":{"position":[[769,18]]}}}],["14t14:22:54.000000",{"_index":6760,"t":{"1375":{"position":[[1576,18]]}}}],["15",{"_index":2026,"t":{"321":{"position":[[1660,2]]},"913":{"position":[[3252,3]]},"1091":{"position":[[421,2]]},"1124":{"position":[[1090,2]]},"1635":{"position":[[3252,3]]},"2186":{"position":[[23,3]]},"2360":{"position":[[3252,3]]},"2895":{"position":[[1679,3]]},"3429":{"position":[[258,2]]}}}],["15.3",{"_index":9520,"t":{"2890":{"position":[[83,5]]}}}],["15.x",{"_index":4299,"t":{"895":{"position":[[65,4]]},"1617":{"position":[[65,4]]},"2342":{"position":[[65,4]]}}}],["15/19",{"_index":4934,"t":{"1063":{"position":[[1305,7]]}}}],["1500",{"_index":4962,"t":{"1067":{"position":[[2657,4],[4918,4]]},"1188":{"position":[[181,4]]},"1585":{"position":[[1738,4]]}}}],["150688b82efa44a5ac452d2b937f16e5",{"_index":4058,"t":{"842":{"position":[[2717,32],[2752,32],[2812,32],[2847,32]]},"1557":{"position":[[2717,32],[2752,32],[2812,32],[2847,32]]}}}],["152",{"_index":6355,"t":{"1317":{"position":[[7522,3]]}}}],["15477",{"_index":3049,"t":{"596":{"position":[[641,6]]}}}],["155",{"_index":237,"t":{"23":{"position":[[16,4]]}}}],["156f",{"_index":7866,"t":{"1847":{"position":[[1416,4]]}}}],["158",{"_index":7644,"t":{"1794":{"position":[[1274,3]]}}}],["1589fd5242e8",{"_index":4252,"t":{"859":{"position":[[5207,12],[5445,12],[5645,12],[5875,12],[6376,12]]},"1603":{"position":[[5207,12],[5445,12],[5645,12],[5875,12],[6376,12]]}}}],["15:05",{"_index":477,"t":{"63":{"position":[[37,5]]}}}],["15:40",{"_index":484,"t":{"63":{"position":[[116,5]]}}}],["15a835a3",{"_index":7870,"t":{"1847":{"position":[[1498,8]]}}}],["15d",{"_index":8306,"t":{"2150":{"position":[[88,3]]}}}],["15dde7b9ce85",{"_index":4202,"t":{"859":{"position":[[2771,12]]},"1603":{"position":[[2771,12]]}}}],["15f2ab0eaa5b4372b759bde609e86224",{"_index":9811,"t":{"3109":{"position":[[745,32],[2959,32]]}}}],["15m",{"_index":3529,"t":{"660":{"position":[[1416,3]]}}}],["15t15:20:07z",{"_index":2361,"t":{"404":{"position":[[146,12]]}}}],["16",{"_index":3611,"t":{"730":{"position":[[1370,2]]},"813":{"position":[[442,2]]},"990":{"position":[[553,2]]},"1124":{"position":[[1093,2]]},"1252":{"position":[[708,2]]},"1491":{"position":[[1370,2]]},"1503":{"position":[[442,2]]},"1721":{"position":[[28,2],[104,2],[156,2],[185,2],[290,2],[445,2],[597,2],[751,2],[917,2],[1085,2],[1237,2],[1392,2],[1554,2],[1707,2],[1860,2],[2014,2],[2169,2],[2324,2],[2478,2],[2631,2],[2788,2],[2948,2],[3093,2],[3245,2],[3396,2],[3440,2],[3506,2],[3615,2],[3665,2],[3711,2],[3782,2],[3834,2],[3863,2],[3938,2],[3991,2],[4045,2],[4073,2]]},"1773":{"position":[[1019,2]]},"1775":{"position":[[252,2]]},"1808":{"position":[[401,2]]},"1845":{"position":[[230,3],[2542,2]]},"1847":{"position":[[486,2]]},"2702":{"position":[[354,2]]},"2711":{"position":[[265,3],[276,2],[401,3],[412,2],[489,3],[500,2],[881,2]]},"2731":{"position":[[641,2],[666,2],[681,2],[702,2],[886,2]]},"2733":{"position":[[289,2],[391,2]]},"2747":{"position":[[354,2]]},"2770":{"position":[[641,2],[666,2],[681,2],[702,2],[886,2]]},"2772":{"position":[[289,2],[391,2]]},"2854":{"position":[[289,2]]},"2856":{"position":[[859,2]]},"2927":{"position":[[125,2],[142,2],[152,2],[174,2],[330,2],[347,2],[361,2],[411,2],[428,2]]},"2929":{"position":[[149,2],[169,2],[338,2],[358,2],[385,2],[457,2],[477,2]]},"2933":{"position":[[284,2]]},"2949":{"position":[[51,2]]},"3167":{"position":[[217,4]]}}}],["16/19",{"_index":4935,"t":{"1063":{"position":[[1338,7]]}}}],["161",{"_index":6359,"t":{"1317":{"position":[[8164,3]]}}}],["162",{"_index":6363,"t":{"1317":{"position":[[8363,3]]}}}],["163",{"_index":6361,"t":{"1317":{"position":[[8264,3]]}}}],["164",{"_index":6357,"t":{"1317":{"position":[[8065,3],[8704,3],[8851,3]]}}}],["165",{"_index":6365,"t":{"1317":{"position":[[8462,3]]}}}],["1654.raw",{"_index":4108,"t":{"850":{"position":[[3426,8]]},"1484":{"position":[[3426,8]]}}}],["1657832",{"_index":6222,"t":{"1305":{"position":[[198,7]]}}}],["1668",{"_index":8539,"t":{"2422":{"position":[[174,4]]}}}],["16777216",{"_index":4794,"t":{"1031":{"position":[[387,8],[423,8]]}}}],["167a",{"_index":9716,"t":{"3042":{"position":[[896,4]]},"3046":{"position":[[843,4]]}}}],["168e",{"_index":4040,"t":{"842":{"position":[[2225,4]]},"1557":{"position":[[2225,4]]}}}],["16:32",{"_index":9192,"t":{"2711":{"position":[[418,5]]},"2856":{"position":[[420,5]]}}}],["16:43:52.547",{"_index":6799,"t":{"1386":{"position":[[61,12]]}}}],["16gb",{"_index":7802,"t":{"1845":{"position":[[265,4]]}}}],["16gib",{"_index":9121,"t":{"2702":{"position":[[418,5]]},"2733":{"position":[[441,5]]},"2747":{"position":[[418,5]]},"2772":{"position":[[441,5]]},"2854":{"position":[[442,5]]}}}],["16m",{"_index":6971,"t":{"1475":{"position":[[219,5]]}}}],["16t",{"_index":9323,"t":{"2733":{"position":[[267,3]]},"2772":{"position":[[267,3]]}}}],["16t:64:200",{"_index":9435,"t":{"2854":{"position":[[267,11]]}}}],["16v",{"_index":9193,"t":{"2711":{"position":[[428,3],[440,3]]},"2766":{"position":[[1011,3]]},"2927":{"position":[[354,3]]},"2929":{"position":[[374,3]]}}}],["16v:32",{"_index":9455,"t":{"2856":{"position":[[430,7]]}}}],["16v:32:100",{"_index":9456,"t":{"2856":{"position":[[442,10]]}}}],["17",{"_index":5420,"t":{"1124":{"position":[[1096,2]]},"3251":{"position":[[258,2],[2558,3]]},"3316":{"position":[[1589,2]]}}}],["17/19",{"_index":4938,"t":{"1063":{"position":[[1377,7]]}}}],["1714.qcow2",{"_index":4160,"t":{"850":{"position":[[9974,10]]},"1484":{"position":[[9974,10]]}}}],["1714/debian",{"_index":4158,"t":{"850":{"position":[[9925,11]]},"1484":{"position":[[9925,11]]}}}],["1717440342.qp.xbc.xbs.gz",{"_index":6206,"t":{"1298":{"position":[[719,24]]}}}],["1717440409.qp.xbc.xbs.gz",{"_index":6202,"t":{"1298":{"position":[[571,24]]}}}],["1727.raw",{"_index":4115,"t":{"850":{"position":[[4370,8],[5120,10]]},"1484":{"position":[[4370,8],[5120,10]]}}}],["1727/debian",{"_index":4121,"t":{"850":{"position":[[5071,11]]},"1484":{"position":[[5071,11]]}}}],["1761",{"_index":6443,"t":{"1321":{"position":[[1957,4]]}}}],["176a7858fcca",{"_index":4032,"t":{"842":{"position":[[2029,12]]},"1557":{"position":[[2029,12]]}}}],["17:55:54.252250",{"_index":6499,"t":{"1342":{"position":[[588,15]]}}}],["17t09:02:08.320514706z",{"_index":2636,"t":{"472":{"position":[[2185,23]]}}}],["17t09:09:08.321004645z",{"_index":2644,"t":{"472":{"position":[[2343,23]]}}}],["17t09:09:08.331433127z",{"_index":2652,"t":{"472":{"position":[[2512,23]]}}}],["18",{"_index":5421,"t":{"1124":{"position":[[1099,2]]},"1298":{"position":[[545,2]]},"1317":{"position":[[8219,2]]},"1721":{"position":[[3573,2]]},"2688":{"position":[[1196,2]]},"2872":{"position":[[1349,4]]}}}],["18/19",{"_index":4941,"t":{"1063":{"position":[[1415,7]]}}}],["1800",{"_index":2050,"t":{"325":{"position":[[754,4]]}}}],["1846709967a744b69f9eb48cac89bb04",{"_index":353,"t":{"27":{"position":[[1794,32]]}}}],["185.150.99.255",{"_index":2707,"t":{"485":{"position":[[513,16]]}}}],["1885",{"_index":6503,"t":{"1342":{"position":[[688,4]]}}}],["18:00:31.215879",{"_index":6508,"t":{"1342":{"position":[[764,15]]}}}],["18:14:15",{"_index":6454,"t":{"1333":{"position":[[213,8]]}}}],["18:15:39",{"_index":6487,"t":{"1339":{"position":[[103,8]]}}}],["18:16:25",{"_index":6488,"t":{"1339":{"position":[[167,8]]}}}],["18:45",{"_index":6203,"t":{"1298":{"position":[[630,5],[690,5]]}}}],["18:46",{"_index":6198,"t":{"1298":{"position":[[437,5],[527,5]]}}}],["18:47",{"_index":6199,"t":{"1298":{"position":[[479,5]]}}}],["18b0",{"_index":3971,"t":{"842":{"position":[[969,4]]},"1557":{"position":[[969,4]]}}}],["18m",{"_index":3474,"t":{"646":{"position":[[2228,3]]}}}],["19",{"_index":3878,"t":{"821":{"position":[[2069,2],[2161,2],[2261,2],[2407,2],[3014,2],[3088,2],[3162,2],[3235,2],[3344,2],[3465,2],[3566,2],[3713,2],[4350,2],[4425,2],[4500,2],[4574,2],[4684,2],[4806,2],[4907,2],[5054,2],[5667,2],[5742,2],[5817,2],[5891,2],[6001,2]]},"1124":{"position":[[1102,2]]},"1511":{"position":[[2069,2],[2161,2],[2261,2],[2407,2],[3014,2],[3088,2],[3162,2],[3235,2],[3344,2],[3465,2],[3566,2],[3713,2],[4350,2],[4425,2],[4500,2],[4574,2],[4684,2],[4806,2],[4907,2],[5054,2],[5667,2],[5742,2],[5817,2],[5891,2],[6001,2]]}}}],["19/19",{"_index":4943,"t":{"1063":{"position":[[1451,7]]}}}],["190",{"_index":9013,"t":{"2625":{"position":[[1174,4]]},"2735":{"position":[[341,4]]},"2774":{"position":[[477,4]]}}}],["192.168.0.0/16",{"_index":2728,"t":{"487":{"position":[[212,14]]}}}],["192.168.112.0/20",{"_index":6560,"t":{"1356":{"position":[[345,18]]}}}],["192.168.112.100",{"_index":6558,"t":{"1356":{"position":[[305,17]]}}}],["192.168.112.200",{"_index":6556,"t":{"1356":{"position":[[248,17]]}}}],["192.168.112.5",{"_index":6563,"t":{"1356":{"position":[[421,15]]}}}],["192.168.16.1",{"_index":4961,"t":{"1067":{"position":[[2637,14],[4898,14]]}}}],["192.168.16.10",{"_index":4955,"t":{"1067":{"position":[[1948,13],[4302,13],[4453,13]]},"1084":{"position":[[497,13]]},"1108":{"position":[[1905,13]]},"1167":{"position":[[2871,13],[2937,13],[3103,13],[3162,13]]},"1319":{"position":[[515,14]]},"1321":{"position":[[1895,13],[1987,17]]},"1368":{"position":[[1137,15]]},"1787":{"position":[[703,13]]}}}],["192.168.16.10/20",{"_index":4959,"t":{"1067":{"position":[[2608,18],[4869,18]]}}}],["192.168.16.100",{"_index":7594,"t":{"1787":{"position":[[1323,14]]}}}],["192.168.16.11",{"_index":5048,"t":{"1084":{"position":[[513,13]]},"1368":{"position":[[1389,15]]},"1787":{"position":[[765,13]]}}}],["192.168.16.12",{"_index":5049,"t":{"1084":{"position":[[529,13]]},"1368":{"position":[[1263,15]]},"1787":{"position":[[827,13]]}}}],["192.168.16.13",{"_index":7583,"t":{"1787":{"position":[[889,13]]}}}],["192.168.16.14",{"_index":7584,"t":{"1787":{"position":[[951,13]]}}}],["192.168.16.15",{"_index":7585,"t":{"1787":{"position":[[1013,13]]}}}],["192.168.16.16",{"_index":7586,"t":{"1787":{"position":[[1075,13]]}}}],["192.168.16.17",{"_index":7588,"t":{"1787":{"position":[[1137,13]]}}}],["192.168.16.18",{"_index":7590,"t":{"1787":{"position":[[1199,13]]}}}],["192.168.16.19",{"_index":7592,"t":{"1787":{"position":[[1261,13]]}}}],["192.168.16.254",{"_index":7596,"t":{"1787":{"position":[[1374,14]]}}}],["192.168.16.5",{"_index":6450,"t":{"1327":{"position":[[422,14]]},"1339":{"position":[[122,12]]},"1787":{"position":[[284,12],[323,12],[364,12],[409,12],[452,12],[497,12],[560,12],[603,12]]}}}],["192.168.16.5:8000",{"_index":7323,"t":{"1731":{"position":[[1489,17]]}}}],["192.168.16.9",{"_index":7582,"t":{"1787":{"position":[[656,12]]}}}],["192.168.192.0/24",{"_index":4331,"t":{"903":{"position":[[769,16]]},"1625":{"position":[[769,16]]},"2350":{"position":[[769,16]]}}}],["192.168.23.0/24",{"_index":7098,"t":{"1585":{"position":[[3251,15]]}}}],["192.168.23.1",{"_index":7105,"t":{"1585":{"position":[[3372,12]]}}}],["192.168.23.100",{"_index":7101,"t":{"1585":{"position":[[3309,14]]}}}],["192.168.23.200",{"_index":7103,"t":{"1585":{"position":[[3345,14]]}}}],["192.168.24.200",{"_index":4874,"t":{"1055":{"position":[[3307,14]]}}}],["192.168.32.9",{"_index":4933,"t":{"1063":{"position":[[1289,15]]},"1071":{"position":[[790,12]]}}}],["192.168.64.0/20",{"_index":5001,"t":{"1071":{"position":[[76,15]]}}}],["192.168.96.9",{"_index":4930,"t":{"1063":{"position":[[1253,15]]},"1071":{"position":[[702,12]]}}}],["196aad32",{"_index":5233,"t":{"1112":{"position":[[4289,8],[4413,8],[4464,8],[5074,8],[5248,8],[5461,8],[5503,8]]}}}],["1970",{"_index":4420,"t":{"909":{"position":[[2279,4]]},"922":{"position":[[282,4]]},"1631":{"position":[[2279,4]]},"1644":{"position":[[282,4]]},"2356":{"position":[[2279,4]]},"2369":{"position":[[282,4]]}}}],["1:1",{"_index":7977,"t":{"1911":{"position":[[459,3]]},"2027":{"position":[[459,3]]},"2695":{"position":[[278,3]]},"2711":{"position":[[536,3]]},"2740":{"position":[[278,3]]},"2856":{"position":[[538,3]]},"3251":{"position":[[1830,3]]}}}],["1:2",{"_index":9188,"t":{"2711":{"position":[[312,3]]},"2856":{"position":[[314,3]]}}}],["1:4",{"_index":9184,"t":{"2711":{"position":[[201,3]]},"2856":{"position":[[203,3]]}}}],["1:8",{"_index":9194,"t":{"2711":{"position":[[451,3]]},"2856":{"position":[[453,3]]}}}],["1@rbd",{"_index":6517,"t":{"1347":{"position":[[832,5],[1248,5],[1299,5]]}}}],["1]:8080",{"_index":3422,"t":{"641":{"position":[[1866,10]]}}}],["1b03f50fc9bb",{"_index":5237,"t":{"1112":{"position":[[4313,12],[4437,12],[4488,12],[5098,12],[5272,12],[5485,12],[5527,12]]}}}],["1b6bb583fc5e40e49f2a7e9b4301de65",{"_index":289,"t":{"25":{"position":[[777,32]]}}}],["1bff2e29923b",{"_index":6595,"t":{"1360":{"position":[[1983,12]]}}}],["1c",{"_index":9346,"t":{"2756":{"position":[[428,2]]}}}],["1c9be759fe85",{"_index":6646,"t":{"1364":{"position":[[211,12]]}}}],["1d",{"_index":9208,"t":{"2713":{"position":[[492,2]]}}}],["1d:1.5:8",{"_index":9469,"t":{"2858":{"position":[[489,9]]}}}],["1db5b4429a69",{"_index":3433,"t":{"644":{"position":[[313,12]]}}}],["1e6d",{"_index":3977,"t":{"842":{"position":[[1062,4]]},"1557":{"position":[[1062,4]]}}}],["1efbebfb086b",{"_index":9788,"t":{"3107":{"position":[[1082,12]]}}}],["1g",{"_index":4716,"t":{"993":{"position":[[0,3]]}}}],["1gb",{"_index":6223,"t":{"1305":{"position":[[208,3]]}}}],["1gi",{"_index":3394,"t":{"641":{"position":[[144,6],[163,6]]},"644":{"position":[[326,3],[626,3]]}}}],["1gib",{"_index":9320,"t":{"2733":{"position":[[222,4]]},"2772":{"position":[[222,4]]},"2854":{"position":[[222,4]]}}}],["1h",{"_index":8312,"t":{"2150":{"position":[[598,2]]}}}],["1hr",{"_index":485,"t":{"65":{"position":[[21,6]]}}}],["1k",{"_index":10070,"t":{"3299":{"position":[[3374,3]]}}}],["1l",{"_index":4425,"t":{"911":{"position":[[83,2]]},"1633":{"position":[[83,2]]},"2358":{"position":[[83,2]]},"2711":{"position":[[544,2],[554,2],[639,2]]},"2733":{"position":[[181,2]]},"2772":{"position":[[181,2]]},"2927":{"position":[[462,2]]},"2929":{"position":[[534,2]]},"2933":{"position":[[111,2]]}}}],["1l:1",{"_index":9463,"t":{"2856":{"position":[[546,5],[617,4]]}}}],["1l:1:5",{"_index":9464,"t":{"2856":{"position":[[556,6]]}}}],["1l:1u:5",{"_index":9434,"t":{"2854":{"position":[[181,7]]}}}],["1m",{"_index":6969,"t":{"1475":{"position":[[209,4]]},"2949":{"position":[[586,3]]}}}],["1rcp3npuqss5wmulcn6y5g",{"_index":6221,"t":{"1305":{"position":[[171,22]]}}}],["1s",{"_index":8326,"t":{"2152":{"position":[[337,2]]},"2947":{"position":[[2555,2]]}}}],["1st",{"_index":6187,"t":{"1298":{"position":[[247,3]]},"1585":{"position":[[170,3]]},"1805":{"position":[[257,3]]}}}],["1t",{"_index":9206,"t":{"2713":{"position":[[393,2]]},"2756":{"position":[[503,2]]}}}],["1t:1:5n",{"_index":9468,"t":{"2858":{"position":[[394,7]]}}}],["1tb",{"_index":3719,"t":{"786":{"position":[[269,3]]},"1523":{"position":[[269,3]]},"1587":{"position":[[859,4]]}}}],["1u",{"_index":9319,"t":{"2733":{"position":[[184,2]]},"2772":{"position":[[184,2]]}}}],["1v",{"_index":3609,"t":{"730":{"position":[[1261,2]]},"911":{"position":[[49,2]]},"1491":{"position":[[1261,2]]},"1633":{"position":[[49,2]]},"2358":{"position":[[49,2]]},"2711":{"position":[[209,2],[219,2],[320,2],[330,2],[459,2],[469,2]]},"2713":{"position":[[336,2]]},"2733":{"position":[[482,2]]},"2756":{"position":[[582,2]]},"2772":{"position":[[482,2]]},"2927":{"position":[[72,2],[216,2],[383,2]]},"2929":{"position":[[72,2],[226,2],[417,2]]},"2933":{"position":[[1034,2]]}}}],["1v:0.5",{"_index":9439,"t":{"2854":{"position":[[483,6]]}}}],["1v:1:20",{"_index":8105,"t":{"2033":{"position":[[1737,8]]}}}],["1v:2",{"_index":9202,"t":{"2711":{"position":[[1503,4]]},"2856":{"position":[[322,5],[1481,4]]}}}],["1v:2:5",{"_index":9448,"t":{"2856":{"position":[[332,6]]}}}],["1v:4",{"_index":9440,"t":{"2856":{"position":[[211,5]]}}}],["1v:4:10",{"_index":9441,"t":{"2856":{"position":[[221,7]]}}}],["1v:8",{"_index":9457,"t":{"2856":{"position":[[461,5]]}}}],["1v:8:20",{"_index":9458,"t":{"2856":{"position":[[471,7]]}}}],["1vl:1:5",{"_index":9467,"t":{"2858":{"position":[[336,7]]}}}],["1~ubuntu.22.04~jammi",{"_index":7462,"t":{"1764":{"position":[[268,20],[381,20],[494,20],[607,20],[720,20],[833,20],[946,20],[1059,20],[1172,20],[1285,20],[1398,20],[1511,20],[1624,20],[1737,20]]}}}],["2",{"_index":834,"t":{"131":{"position":[[357,3]]},"214":{"position":[[180,2]]},"288":{"position":[[78,2]]},"321":{"position":[[971,2]]},"460":{"position":[[392,1]]},"557":{"position":[[314,1]]},"604":{"position":[[8033,2]]},"609":{"position":[[1593,2]]},"641":{"position":[[926,1],[928,1],[1016,1],[1018,1],[1099,1],[1101,1],[1143,1],[1145,1]]},"644":{"position":[[747,1],[764,1]]},"652":{"position":[[964,1],[1020,1]]},"730":{"position":[[2428,1]]},"734":{"position":[[210,1]]},"738":{"position":[[322,1]]},"821":{"position":[[5491,2]]},"840":{"position":[[136,1]]},"859":{"position":[[2347,1],[2499,1],[3973,1],[4136,2],[4358,2],[4792,2],[4907,2]]},"861":{"position":[[277,1]]},"903":{"position":[[3153,1]]},"909":{"position":[[2605,1],[2628,1],[2727,1]]},"911":{"position":[[52,1],[447,1]]},"913":{"position":[[2313,1],[2339,1],[2397,1],[2502,1]]},"942":{"position":[[273,3]]},"982":{"position":[[758,1]]},"988":{"position":[[332,1]]},"1039":{"position":[[631,1]]},"1061":{"position":[[397,2]]},"1089":{"position":[[1517,1],[1619,2]]},"1112":{"position":[[1379,1],[2259,1],[2314,1],[2674,1],[3214,1],[3269,1]]},"1114":{"position":[[266,1],[481,1],[1131,1],[2559,1]]},"1118":{"position":[[1129,1]]},"1124":{"position":[[915,1],[1028,1],[1059,1]]},"1144":{"position":[[414,1]]},"1167":{"position":[[1018,1]]},"1219":{"position":[[322,2]]},"1234":{"position":[[2127,2]]},"1292":{"position":[[500,1]]},"1298":{"position":[[412,1]]},"1305":{"position":[[282,1]]},"1317":{"position":[[7479,1],[7533,1],[8124,1],[8224,1],[8323,1],[8422,1],[9010,1]]},"1321":{"position":[[404,1],[568,1],[788,1],[1018,1],[1256,1]]},"1335":{"position":[[206,2]]},"1347":{"position":[[554,1],[2023,1]]},"1360":{"position":[[1642,1],[1657,1]]},"1368":{"position":[[740,2],[1219,1],[1244,1],[1827,3],[2506,3]]},"1373":{"position":[[225,1]]},"1430":{"position":[[362,1],[364,1],[1149,1],[1151,1],[1792,1],[1867,1],[1907,2]]},"1491":{"position":[[2428,1]]},"1495":{"position":[[210,1]]},"1511":{"position":[[5491,2]]},"1555":{"position":[[136,1]]},"1562":{"position":[[817,1]]},"1603":{"position":[[2347,1],[2499,1],[3973,1],[4136,2],[4358,2],[4792,2],[4907,2]]},"1605":{"position":[[277,1]]},"1625":{"position":[[3153,1]]},"1631":{"position":[[2605,1],[2628,1],[2727,1]]},"1633":{"position":[[52,1],[447,1]]},"1635":{"position":[[2313,1],[2339,1],[2397,1],[2502,1]]},"1664":{"position":[[273,3]]},"1674":{"position":[[97,1]]},"1728":{"position":[[616,1]]},"1787":{"position":[[887,1]]},"1789":{"position":[[714,2]]},"1833":{"position":[[306,1],[354,1],[400,1],[489,1],[767,1],[925,1]]},"1974":{"position":[[587,2]]},"2067":{"position":[[1699,2]]},"2069":{"position":[[372,2]]},"2098":{"position":[[418,1],[2263,1]]},"2142":{"position":[[261,1]]},"2150":{"position":[[684,1]]},"2164":{"position":[[267,3]]},"2170":{"position":[[219,2]]},"2172":{"position":[[16,2]]},"2243":{"position":[[23,1]]},"2294":{"position":[[63,2],[279,1]]},"2350":{"position":[[3153,1]]},"2356":{"position":[[2605,1],[2628,1],[2727,1]]},"2358":{"position":[[52,1],[447,1]]},"2360":{"position":[[2313,1],[2339,1],[2397,1],[2502,1]]},"2389":{"position":[[273,3]]},"2409":{"position":[[307,1]]},"2625":{"position":[[1207,1],[1613,1]]},"2697":{"position":[[1283,1]]},"2705":{"position":[[2117,1]]},"2711":{"position":[[323,2],[333,1]]},"2725":{"position":[[469,1],[488,1]]},"2733":{"position":[[30,1]]},"2735":{"position":[[912,1],[1460,2]]},"2742":{"position":[[1182,1]]},"2750":{"position":[[2419,1]]},"2764":{"position":[[690,1],[709,1]]},"2772":{"position":[[30,1]]},"2774":{"position":[[914,1],[1462,2]]},"2815":{"position":[[1030,1]]},"2850":{"position":[[378,1],[397,1]]},"2854":{"position":[[30,1]]},"2911":{"position":[[271,1]]},"2923":{"position":[[116,2]]},"2927":{"position":[[102,1],[219,1],[235,1],[246,1],[275,1],[414,1]]},"2929":{"position":[[117,1],[229,1],[247,1],[269,1],[463,1]]},"2933":{"position":[[1037,1]]},"2942":{"position":[[341,1]]},"3011":{"position":[[1041,2]]},"3014":{"position":[[479,1]]},"3065":{"position":[[173,1]]},"3071":{"position":[[1781,1],[1795,2]]},"3115":{"position":[[519,1]]},"3124":{"position":[[441,1],[936,1]]},"3128":{"position":[[624,1]]},"3167":{"position":[[432,1],[741,1]]},"3184":{"position":[[774,3]]},"3188":{"position":[[89,1]]},"3284":{"position":[[243,1],[303,1]]},"3299":{"position":[[1225,1],[2711,1],[3931,1]]},"3316":{"position":[[1658,1]]},"3325":{"position":[[3581,2],[3591,1]]},"3400":{"position":[[422,1]]},"3468":{"position":[[510,2]]},"3508":{"position":[[38,2],[48,1]]}}}],["2+1))/ge",{"_index":3230,"t":{"609":{"position":[[3266,13],[3380,13],[3938,13],[4052,13],[5766,13],[5880,13]]},"635":{"position":[[3619,13]]}}}],["2.0",{"_index":1936,"t":{"298":{"position":[[487,3]]},"970":{"position":[[205,4]]},"1947":{"position":[[371,3]]},"2576":{"position":[[605,3]]},"3247":{"position":[[261,3]]},"3251":{"position":[[1307,4]]},"3255":{"position":[[603,3]]}}}],["2.12",{"_index":6761,"t":{"1377":{"position":[[52,4],[1058,4]]}}}],["2.14.10",{"_index":6348,"t":{"1317":{"position":[[6705,7]]}}}],["2.4.x",{"_index":2251,"t":{"379":{"position":[[152,5]]}}}],["2.5",{"_index":9613,"t":{"2947":{"position":[[2561,5]]}}}],["2.6.25",{"_index":7722,"t":{"1829":{"position":[[320,6]]}}}],["2.67",{"_index":6458,"t":{"1333":{"position":[[277,4]]}}}],["2.71",{"_index":6491,"t":{"1339":{"position":[[230,4]]}}}],["2.75ghz",{"_index":9268,"t":{"2725":{"position":[[914,8]]},"2764":{"position":[[1489,8]]},"2850":{"position":[[807,8]]}}}],["2.85",{"_index":6489,"t":{"1339":{"position":[[218,5]]}}}],["2.90",{"_index":7846,"t":{"1845":{"position":[[2890,4]]}}}],["2.de.pool.ntp.org",{"_index":4995,"t":{"1067":{"position":[[5745,17]]}}}],["2.iso",{"_index":7005,"t":{"1569":{"position":[[450,5]]}}}],["2.testbed.osism.xyz",{"_index":4827,"t":{"1039":{"position":[[655,19]]},"1055":{"position":[[1518,19],[1638,19]]},"1317":{"position":[[8084,19],[8933,19]]},"1325":{"position":[[269,19],[805,19]]},"1787":{"position":[[854,19]]}}}],["2.testbed.osism.xyz:1984",{"_index":7605,"t":{"1789":{"position":[[737,24]]}}}],["2/19",{"_index":4909,"t":{"1063":{"position":[[855,6]]}}}],["2/2",{"_index":3409,"t":{"641":{"position":[[922,3],[1012,3],[1095,3],[1139,3],[1275,3]]}}}],["20",{"_index":2754,"t":{"487":{"position":[[1385,3],[1489,3],[1988,2],[2125,2]]},"730":{"position":[[1229,2],[1282,2],[1335,2],[1389,2],[1633,3],[2110,2],[2179,3],[2361,4]]},"734":{"position":[[134,3],[192,3]]},"819":{"position":[[6127,2]]},"821":{"position":[[5397,3],[5477,3],[5574,3]]},"859":{"position":[[2515,2]]},"861":{"position":[[332,2]]},"893":{"position":[[22,2]]},"1031":{"position":[[466,2]]},"1041":{"position":[[108,2]]},"1114":{"position":[[3370,2]]},"1124":{"position":[[1224,2],[1421,2],[1427,2]]},"1491":{"position":[[1229,2],[1282,2],[1335,2],[1389,2],[1633,3],[2110,2],[2179,3],[2361,4]]},"1495":{"position":[[134,3],[192,3]]},"1509":{"position":[[6127,2]]},"1511":{"position":[[5397,3],[5477,3],[5574,3]]},"1603":{"position":[[2515,2]]},"1605":{"position":[[332,2]]},"1615":{"position":[[22,2]]},"1721":{"position":[[3542,2]]},"1845":{"position":[[474,2],[2611,2]]},"2340":{"position":[[22,2]]},"2398":{"position":[[23,3]]},"2454":{"position":[[44,3]]},"2705":{"position":[[319,3],[1691,3]]},"2709":{"position":[[43,3]]},"2711":{"position":[[101,3],[250,2],[386,2],[474,2]]},"2750":{"position":[[319,3],[1993,3]]},"2754":{"position":[[43,3]]},"2756":{"position":[[643,3]]},"2840":{"position":[[227,3],[1339,3]]},"2856":{"position":[[103,3]]},"2923":{"position":[[315,3]]},"2927":{"position":[[271,3],[291,2]]},"2929":{"position":[[114,2],[133,2],[303,2],[322,2],[422,2],[441,2]]},"2949":{"position":[[36,3]]},"3014":{"position":[[95,3]]}}}],["20.00g",{"_index":5251,"t":{"1112":{"position":[[5120,7],[5190,7],[5298,7],[5363,7],[5551,7],[5659,7]]},"1114":{"position":[[2180,7],[2250,7],[2323,7],[2437,7],[2502,7],[2570,7],[2720,7],[2828,7]]}}}],["20.04",{"_index":2744,"t":{"487":{"position":[[944,5]]},"499":{"position":[[397,6]]},"604":{"position":[[469,5]]},"2312":{"position":[[534,6]]},"2890":{"position":[[100,6]]},"2987":{"position":[[408,6]]}}}],["20.10.24",{"_index":7491,"t":{"1764":{"position":[[3221,8]]}}}],["200",{"_index":3918,"t":{"821":{"position":[[5602,4]]},"913":{"position":[[69,5],[3174,3]]},"915":{"position":[[226,3]]},"917":{"position":[[835,4]]},"922":{"position":[[669,3],[1126,3],[1295,3]]},"930":{"position":[[248,3]]},"940":{"position":[[156,3]]},"1511":{"position":[[5602,4]]},"1635":{"position":[[69,5],[3174,3]]},"1637":{"position":[[226,3]]},"1639":{"position":[[835,4]]},"1644":{"position":[[669,3],[1126,3],[1295,3]]},"1652":{"position":[[248,3]]},"1662":{"position":[[156,3]]},"2360":{"position":[[69,5],[3174,3]]},"2362":{"position":[[226,3]]},"2364":{"position":[[835,4]]},"2369":{"position":[[669,3],[1126,3],[1295,3]]},"2377":{"position":[[248,3]]},"2387":{"position":[[156,3]]},"2709":{"position":[[56,4]]},"2711":{"position":[[114,4]]},"2754":{"position":[[56,4]]},"2856":{"position":[[116,4]]},"3299":{"position":[[4585,4]]}}}],["200,404",{"_index":5356,"t":{"1118":{"position":[[838,7]]}}}],["2000",{"_index":5366,"t":{"1118":{"position":[[1119,4]]},"1351":{"position":[[1966,4],[2003,4]]}}}],["20000",{"_index":10047,"t":{"3280":{"position":[[863,5]]}}}],["2000gb",{"_index":9182,"t":{"2711":{"position":[[132,7]]},"2856":{"position":[[134,7]]}}}],["2001:db8::10:10:42:10",{"_index":5134,"t":{"1098":{"position":[[737,21]]}}}],["2001:db8::10:10:42:10/128",{"_index":5128,"t":{"1098":{"position":[[575,25]]}}}],["2003",{"_index":7349,"t":{"1734":{"position":[[223,6]]}}}],["200gb",{"_index":9325,"t":{"2733":{"position":[[322,5]]},"2772":{"position":[[322,5]]},"2854":{"position":[[322,5]]}}}],["200s_gna",{"_index":9324,"t":{"2733":{"position":[[274,8]]},"2772":{"position":[[274,8]]}}}],["200th",{"_index":4646,"t":{"947":{"position":[[2212,5]]},"1669":{"position":[[2212,5]]},"2394":{"position":[[2212,5]]}}}],["2012r2",{"_index":9521,"t":{"2890":{"position":[[138,8]]}}}],["2020",{"_index":10089,"t":{"3301":{"position":[[4324,4]]}}}],["2021",{"_index":8363,"t":{"2186":{"position":[[15,4]]},"2204":{"position":[[15,4]]},"2795":{"position":[[1723,4]]},"2815":{"position":[[1318,4],[1472,4],[1498,4]]},"2895":{"position":[[1394,4],[1475,4],[1647,4],[1659,4],[1671,4],[1683,4],[1695,4],[1716,4]]}}}],["2022",{"_index":3067,"t":{"598":{"position":[[133,5],[153,5],[181,5]]},"790":{"position":[[1310,4]]},"1144":{"position":[[95,4]]},"1527":{"position":[[1310,4]]},"2241":{"position":[[15,4]]},"2267":{"position":[[193,4]]},"2274":{"position":[[15,4]]},"2324":{"position":[[762,5]]},"2326":{"position":[[128,4],[159,4],[177,4],[267,4]]},"2524":{"position":[[386,4]]},"2536":{"position":[[431,4]]},"2546":{"position":[[586,4]]},"2809":{"position":[[291,4]]},"2815":{"position":[[1191,4],[1344,4]]},"2895":{"position":[[4584,5],[4695,4]]},"3308":{"position":[[523,4]]}}}],["2023",{"_index":3071,"t":{"598":{"position":[[201,5],[229,5],[249,5],[277,5]]},"730":{"position":[[1221,4],[1274,4],[1327,4],[1381,4]]},"838":{"position":[[75,4],[171,4]]},"840":{"position":[[24,4]]},"842":{"position":[[24,4],[76,4],[129,4],[184,4],[240,4],[295,4],[354,4],[413,4],[475,4],[541,4],[594,4]]},"1311":{"position":[[14,4]]},"1317":{"position":[[1234,4],[1759,4],[1799,4],[2509,4],[2645,4],[2768,4],[2895,4],[3036,4],[3175,4],[3332,4],[3468,4],[3607,4],[3733,4],[3868,4],[4003,4],[4138,4],[4272,4],[4415,4],[4568,4],[4729,4],[4879,4],[4997,4],[5126,4],[5244,4],[5910,4],[5950,4],[6757,4],[8132,4],[8232,4],[8331,4],[8430,4],[8525,4],[9046,4]]},"1321":{"position":[[157,4],[422,4],[586,4],[814,4],[1042,4],[1274,4]]},"1339":{"position":[[112,4]]},"1342":{"position":[[577,4],[753,4]]},"1347":{"position":[[398,4],[491,4],[584,4],[678,4],[772,4],[866,4],[1867,4],[1960,4],[2053,4]]},"1362":{"position":[[1127,4]]},"1375":{"position":[[758,4],[1568,4]]},"1377":{"position":[[761,4],[1763,4]]},"1386":{"position":[[50,4]]},"1491":{"position":[[1221,4],[1274,4],[1327,4],[1381,4]]},"1553":{"position":[[75,4],[171,4]]},"1555":{"position":[[24,4]]},"1557":{"position":[[24,4],[76,4],[129,4],[184,4],[240,4],[295,4],[354,4],[413,4],[475,4],[541,4],[594,4]]},"1721":{"position":[[20,4],[96,4],[148,4],[177,4],[282,4],[437,4],[589,4],[743,4],[909,4],[1077,4],[1229,4],[1384,4],[1546,4],[1699,4],[1852,4],[2006,4],[2161,4],[2316,4],[2470,4],[2623,4],[2780,4],[2940,4],[3085,4],[3237,4],[3388,4],[3432,4],[3498,4],[3607,4],[3657,4],[3703,4],[3774,4],[3825,5],[3855,4],[3930,4],[3983,4],[4036,5],[4065,4]]},"2300":{"position":[[189,4],[260,5]]},"2308":{"position":[[15,4]]},"2326":{"position":[[236,4]]},"2398":{"position":[[15,4]]},"2417":{"position":[[193,5]]},"2422":{"position":[[125,4],[169,4],[212,4],[275,4]]},"2528":{"position":[[71,4]]},"2536":{"position":[[442,4],[485,4],[496,4],[535,4]]},"2554":{"position":[[76,4]]},"2576":{"position":[[746,4]]},"2584":{"position":[[73,4]]},"2586":{"position":[[439,4]]},"2795":{"position":[[1742,4],[1787,4],[1806,4]]},"2809":{"position":[[394,4]]},"3167":{"position":[[208,5]]},"3251":{"position":[[3033,5]]},"3429":{"position":[[250,4]]},"3482":{"position":[[940,4],[2111,4],[2517,4]]}}}],["2023.1",{"_index":5649,"t":{"1156":{"position":[[355,8],[469,8]]},"1812":{"position":[[210,6]]},"2403":{"position":[[69,6]]},"3082":{"position":[[10,6]]}}}],["2023.10.31",{"_index":6381,"t":{"1321":{"position":[[82,10],[355,10],[1414,10],[2113,10]]}}}],["2023.2",{"_index":4942,"t":{"1063":{"position":[[1441,9]]},"1071":{"position":[[1367,6]]},"1130":{"position":[[124,8]]},"1796":{"position":[[83,6],[122,6]]},"1808":{"position":[[683,6]]},"1812":{"position":[[227,6]]},"2459":{"position":[[107,6]]},"3080":{"position":[[236,6]]},"3082":{"position":[[208,6]]},"3084":{"position":[[159,6]]},"3092":{"position":[[423,6]]},"3094":{"position":[[81,6]]}}}],["20230416",{"_index":416,"t":{"37":{"position":[[222,10]]}}}],["20231211",{"_index":430,"t":{"40":{"position":[[220,10]]}}}],["2024",{"_index":2359,"t":{"404":{"position":[[138,4]]},"598":{"position":[[297,5]]},"821":{"position":[[2061,4],[2153,4],[2253,4],[2399,4],[3006,4],[3080,4],[3154,4],[3227,4],[3336,4],[3457,4],[3558,4],[3705,4],[4342,4],[4417,4],[4492,4],[4566,4],[4676,4],[4798,4],[4899,4],[5046,4],[5659,4],[5734,4],[5809,4],[5883,4],[5993,4]]},"850":{"position":[[1647,4],[1726,4],[1805,4],[1994,4],[2129,4],[2308,4],[2437,4],[2633,4],[2769,4],[2868,4],[2947,4],[3020,4],[3181,4],[3320,4],[3574,4],[3774,4],[3867,4],[3940,4],[4113,4],[4258,4],[4518,4],[4718,4],[5131,4],[5214,4],[5285,4],[5455,4],[5634,4],[5818,4],[5954,4],[6045,4],[6124,4],[6200,4],[6349,4],[6477,4],[6652,4],[6788,4],[6884,4],[6968,4],[7142,4],[7287,4],[7470,4],[7606,4],[7710,4],[7786,4],[7935,4],[8063,4],[8238,4],[8374,4],[9698,4]]},"859":{"position":[[2518,4],[2572,4],[2650,4],[2707,4],[2784,4],[2839,4],[2918,4],[2979,4],[3040,4],[3143,4],[3246,4],[3365,4],[3484,4],[3584,4],[3699,4],[3799,4],[3914,4],[3975,4],[4036,4],[4139,4],[4242,4],[4361,4],[4480,4],[4580,4],[4695,4],[4795,4],[4910,4],[4971,4],[5074,4],[5135,4],[5238,4],[5357,4],[5476,4],[5576,4],[5676,4],[5791,4],[5906,4],[5988,4],[6070,4],[6152,4],[6234,4],[6316,4],[6398,4]]},"893":{"position":[[14,4]]},"1077":{"position":[[553,4],[661,4],[1019,4],[1126,4]]},"1298":{"position":[[566,4],[714,4]]},"1484":{"position":[[1647,4],[1726,4],[1805,4],[1994,4],[2129,4],[2308,4],[2437,4],[2633,4],[2769,4],[2868,4],[2947,4],[3020,4],[3181,4],[3320,4],[3574,4],[3774,4],[3867,4],[3940,4],[4113,4],[4258,4],[4518,4],[4718,4],[5131,4],[5214,4],[5285,4],[5455,4],[5634,4],[5818,4],[5954,4],[6045,4],[6124,4],[6200,4],[6349,4],[6477,4],[6652,4],[6788,4],[6884,4],[6968,4],[7142,4],[7287,4],[7470,4],[7606,4],[7710,4],[7786,4],[7935,4],[8063,4],[8238,4],[8374,4],[9698,4]]},"1511":{"position":[[2061,4],[2153,4],[2253,4],[2399,4],[3006,4],[3080,4],[3154,4],[3227,4],[3336,4],[3457,4],[3558,4],[3705,4],[4342,4],[4417,4],[4492,4],[4566,4],[4676,4],[4798,4],[4899,4],[5046,4],[5659,4],[5734,4],[5809,4],[5883,4],[5993,4]]},"1603":{"position":[[2518,4],[2572,4],[2650,4],[2707,4],[2784,4],[2839,4],[2918,4],[2979,4],[3040,4],[3143,4],[3246,4],[3365,4],[3484,4],[3584,4],[3699,4],[3799,4],[3914,4],[3975,4],[4036,4],[4139,4],[4242,4],[4361,4],[4480,4],[4580,4],[4695,4],[4795,4],[4910,4],[4971,4],[5074,4],[5135,4],[5238,4],[5357,4],[5476,4],[5576,4],[5676,4],[5791,4],[5906,4],[5988,4],[6070,4],[6152,4],[6234,4],[6316,4],[6398,4]]},"1615":{"position":[[14,4]]},"2340":{"position":[[14,4]]},"2454":{"position":[[36,4]]},"2540":{"position":[[648,4]]},"2548":{"position":[[579,4]]},"2550":{"position":[[600,4]]},"2584":{"position":[[84,4],[123,4]]},"2594":{"position":[[69,4]]},"3429":{"position":[[261,4],[286,4]]},"3477":{"position":[[161,4]]},"3482":{"position":[[84,4]]}}}],["2024.04.17",{"_index":6220,"t":{"1305":{"position":[[160,10]]},"1307":{"position":[[61,10]]}}}],["2024.1",{"_index":7699,"t":{"1812":{"position":[[254,6]]}}}],["20240211",{"_index":4107,"t":{"850":{"position":[[3417,8]]},"1484":{"position":[[3417,8]]}}}],["20240411",{"_index":4159,"t":{"850":{"position":[[9965,8],[10146,10]]},"1484":{"position":[[9965,8],[10146,10]]}}}],["20240416",{"_index":3775,"t":{"796":{"position":[[856,10],[1119,10],[1219,10]]},"1533":{"position":[[856,10],[1119,10],[1219,10]]}}}],["20240422",{"_index":3780,"t":{"796":{"position":[[962,10],[1280,10]]},"1533":{"position":[[962,10],[1280,10]]}}}],["20240422.0.x86_64.qcow2",{"_index":4094,"t":{"850":{"position":[[2284,23],[2413,23],[2534,23]]},"1484":{"position":[[2284,23],[2413,23],[2534,23]]}}}],["20240423",{"_index":4144,"t":{"850":{"position":[[8449,11]]},"1484":{"position":[[8449,11]]}}}],["20240424",{"_index":4114,"t":{"850":{"position":[[4361,8],[4793,11],[5111,8]]},"1484":{"position":[[4361,8],[4793,11],[5111,8]]}}}],["2025",{"_index":9702,"t":{"3014":{"position":[[904,5]]}}}],["2048",{"_index":3786,"t":{"798":{"position":[[634,4]]},"1114":{"position":[[3701,4]]},"1379":{"position":[[174,4]]},"1535":{"position":[[634,4]]}}}],["2088",{"_index":8540,"t":{"2422":{"position":[[280,5]]}}}],["208b",{"_index":6228,"t":{"1305":{"position":[[293,4],[515,4]]}}}],["2097152",{"_index":6776,"t":{"1379":{"position":[[320,7],[818,7]]}}}],["20973567",{"_index":5304,"t":{"1114":{"position":[[3763,8]]}}}],["20973568",{"_index":5306,"t":{"1114":{"position":[[3811,8]]}}}],["20gb",{"_index":3641,"t":{"734":{"position":[[258,4]]},"1495":{"position":[[258,4]]},"1845":{"position":[[406,5],[542,5]]},"2697":{"position":[[1313,4]]},"2742":{"position":[[1212,4]]}}}],["20gigabyt",{"_index":4187,"t":{"859":{"position":[[2385,12]]},"1603":{"position":[[2385,12]]}}}],["20m",{"_index":3549,"t":{"660":{"position":[[3203,3]]}}}],["20p",{"_index":9348,"t":{"2756":{"position":[[663,3]]}}}],["20th",{"_index":8537,"t":{"2417":{"position":[[187,5]]}}}],["21",{"_index":5441,"t":{"1124":{"position":[[1227,2]]},"1317":{"position":[[1224,2],[1880,3],[6743,2]]},"2274":{"position":[[23,3]]},"2536":{"position":[[493,2]]},"2548":{"position":[[587,2]]},"2576":{"position":[[754,2]]}}}],["2119",{"_index":8999,"t":{"2619":{"position":[[188,5]]},"3338":{"position":[[188,5]]}}}],["213.131.230.203.nip.io",{"_index":3457,"t":{"646":{"position":[[533,22]]}}}],["2147483648",{"_index":5486,"t":{"1144":{"position":[[401,10]]}}}],["21474836480",{"_index":5284,"t":{"1114":{"position":[[3378,11]]}}}],["2179636dfb42",{"_index":5025,"t":{"1077":{"position":[[1077,12],[1208,12]]}}}],["218d",{"_index":9845,"t":{"3109":{"position":[[2090,4]]}}}],["219.traefik.m",{"_index":7645,"t":{"1794":{"position":[[1281,14]]}}}],["21:00:38",{"_index":3934,"t":{"838":{"position":[[86,8],[182,8]]},"1553":{"position":[[86,8],[182,8]]}}}],["21d7",{"_index":6733,"t":{"1368":{"position":[[1905,5],[1927,4],[2062,4],[2067,5]]}}}],["21m",{"_index":3009,"t":{"590":{"position":[[1392,3],[1546,3],[1710,3]]}}}],["21t11:53:00.000000",{"_index":6631,"t":{"1362":{"position":[[1135,18]]}}}],["22",{"_index":4336,"t":{"903":{"position":[[1059,2]]},"938":{"position":[[396,3]]},"1039":{"position":[[233,2],[386,2],[539,2],[692,2]]},"1041":{"position":[[444,2]]},"1061":{"position":[[518,5]]},"1063":{"position":[[1102,5]]},"1071":{"position":[[448,2]]},"1124":{"position":[[1230,2]]},"1224":{"position":[[3464,3]]},"1240":{"position":[[1555,2]]},"1386":{"position":[[74,2]]},"1625":{"position":[[1059,2]]},"1660":{"position":[[396,3]]},"1743":{"position":[[329,2],[1384,2]]},"1857":{"position":[[319,2]]},"1863":{"position":[[631,2]]},"1919":{"position":[[319,2]]},"1925":{"position":[[631,2]]},"2308":{"position":[[23,3]]},"2350":{"position":[[1059,2]]},"2385":{"position":[[396,3]]},"3299":{"position":[[2328,3]]}}}],["22.04",{"_index":415,"t":{"37":{"position":[[216,5]]},"40":{"position":[[214,5]]},"483":{"position":[[311,5],[360,5]]},"487":{"position":[[872,5]]},"604":{"position":[[485,5]]},"850":{"position":[[6194,5],[6954,5],[7109,5],[7362,5],[7667,5]]},"857":{"position":[[208,5]]},"1232":{"position":[[129,6],[159,5]]},"1234":{"position":[[121,5],[250,5],[414,5]]},"1236":{"position":[[881,5]]},"1484":{"position":[[6194,5],[6954,5],[7109,5],[7362,5],[7667,5]]},"1569":{"position":[[837,6]]},"1601":{"position":[[208,5]]},"1743":{"position":[[40,5],[623,5]]},"1773":{"position":[[1091,6],[1119,6]]},"1808":{"position":[[445,5],[463,5],[510,5],[528,5]]},"1831":{"position":[[181,5]]},"2292":{"position":[[430,6]]},"2312":{"position":[[438,5],[577,5]]},"2405":{"position":[[390,6],[432,5]]},"2987":{"position":[[24,6],[978,5]]}}}],["22.04.1",{"_index":6059,"t":{"1234":{"position":[[297,7]]}}}],["22.09",{"_index":8476,"t":{"2315":{"position":[[405,6]]}}}],["2204",{"_index":9660,"t":{"2985":{"position":[[77,4],[161,4]]},"2987":{"position":[[362,4]]}}}],["222",{"_index":4636,"t":{"947":{"position":[[951,3]]},"1669":{"position":[[951,3]]},"2394":{"position":[[951,3]]}}}],["223",{"_index":4639,"t":{"947":{"position":[[1156,3]]},"1669":{"position":[[1156,3]]},"2394":{"position":[[1156,3]]}}}],["2237c767cf5f456da19359ed31c1c16b",{"_index":294,"t":{"27":{"position":[[74,32]]}}}],["224",{"_index":4640,"t":{"947":{"position":[[1204,3]]},"1669":{"position":[[1204,3]]},"2394":{"position":[[1204,3]]}}}],["22m",{"_index":3019,"t":{"590":{"position":[[1685,3]]}}}],["23",{"_index":4145,"t":{"850":{"position":[[8498,4]]},"859":{"position":[[2526,2],[2580,2],[2658,2],[2715,2],[2792,2],[2847,2],[2926,2],[2987,2],[3048,2],[3151,2],[3254,2],[3373,2],[3492,2],[3592,2],[3707,2],[3807,2],[3922,2],[3983,2],[4044,2],[4147,2],[4250,2],[4369,2],[4488,2],[4588,2],[4703,2],[4803,2],[4918,2],[4979,2],[5082,2],[5143,2],[5246,2],[5365,2],[5484,2],[5584,2],[5684,2],[5799,2],[5914,2],[5996,2],[6078,2],[6160,2],[6242,2],[6324,2],[6406,2]]},"1124":{"position":[[1233,2]]},"1484":{"position":[[8498,4]]},"1603":{"position":[[2526,2],[2580,2],[2658,2],[2715,2],[2792,2],[2847,2],[2926,2],[2987,2],[3048,2],[3151,2],[3254,2],[3373,2],[3492,2],[3592,2],[3707,2],[3807,2],[3922,2],[3983,2],[4044,2],[4147,2],[4250,2],[4369,2],[4488,2],[4588,2],[4703,2],[4803,2],[4918,2],[4979,2],[5082,2],[5143,2],[5246,2],[5365,2],[5484,2],[5584,2],[5684,2],[5799,2],[5914,2],[5996,2],[6078,2],[6160,2],[6242,2],[6324,2],[6406,2]]},"2241":{"position":[[23,3]]},"2795":{"position":[[1795,2]]}}}],["23.0.6",{"_index":8564,"t":{"2465":{"position":[[26,7]]}}}],["23.06.1",{"_index":8517,"t":{"2403":{"position":[[189,8]]}}}],["232a24047f94",{"_index":7753,"t":{"1833":{"position":[[890,12]]}}}],["2340a73644ca47189329061e9c2a0bf",{"_index":370,"t":{"27":{"position":[[2482,32]]}}}],["2379",{"_index":9961,"t":{"3236":{"position":[[567,4]]}}}],["238",{"_index":6482,"t":{"1337":{"position":[[389,3]]}}}],["2380",{"_index":9962,"t":{"3236":{"position":[[572,4]]}}}],["23:09:44",{"_index":3947,"t":{"840":{"position":[[35,8]]},"1555":{"position":[[35,8]]}}}],["23:11:16",{"_index":3956,"t":{"842":{"position":[[35,8]]},"1557":{"position":[[35,8]]}}}],["23:11:21",{"_index":3957,"t":{"842":{"position":[[87,8]]},"1557":{"position":[[87,8]]}}}],["23:11:23",{"_index":3958,"t":{"842":{"position":[[140,8],[195,8]]},"1557":{"position":[[140,8],[195,8]]}}}],["23:11:24",{"_index":3959,"t":{"842":{"position":[[251,8],[306,8],[365,8],[424,8]]},"1557":{"position":[[251,8],[306,8],[365,8],[424,8]]}}}],["23:11:26",{"_index":3962,"t":{"842":{"position":[[486,8]]},"1557":{"position":[[486,8]]}}}],["23:11:27",{"_index":3964,"t":{"842":{"position":[[552,8]]},"1557":{"position":[[552,8]]}}}],["23:11:30",{"_index":3965,"t":{"842":{"position":[[605,8]]},"1557":{"position":[[605,8]]}}}],["23db",{"_index":6409,"t":{"1321":{"position":[[728,4]]}}}],["23m",{"_index":3014,"t":{"590":{"position":[[1519,3]]}}}],["24",{"_index":4080,"t":{"850":{"position":[[1655,2],[1734,2],[1813,2],[2002,2],[2137,2],[2316,2],[2445,2],[2641,2],[2777,2],[2876,2],[2955,2],[3028,2],[3189,2],[3328,2],[3582,2],[3782,2],[3875,2],[3948,2],[4121,2],[4266,2],[4526,2],[4726,2],[4842,4],[5139,2],[5222,2],[5293,2],[5463,2],[5642,2],[5826,2],[5962,2],[6053,2],[6132,2],[6208,2],[6357,2],[6485,2],[6660,2],[6796,2],[6892,2],[6976,2],[7150,2],[7295,2],[7478,2],[7614,2],[7718,2],[7794,2],[7943,2],[8071,2],[8246,2],[8382,2]]},"932":{"position":[[3848,3]]},"1124":{"position":[[1236,2]]},"1484":{"position":[[1655,2],[1734,2],[1813,2],[2002,2],[2137,2],[2316,2],[2445,2],[2641,2],[2777,2],[2876,2],[2955,2],[3028,2],[3189,2],[3328,2],[3582,2],[3782,2],[3875,2],[3948,2],[4121,2],[4266,2],[4526,2],[4726,2],[4842,4],[5139,2],[5222,2],[5293,2],[5463,2],[5642,2],[5826,2],[5962,2],[6053,2],[6132,2],[6208,2],[6357,2],[6485,2],[6660,2],[6796,2],[6892,2],[6976,2],[7150,2],[7295,2],[7478,2],[7614,2],[7718,2],[7794,2],[7943,2],[8071,2],[8246,2],[8382,2]]},"1654":{"position":[[3848,3]]},"2379":{"position":[[3848,3]]}}}],["24.0.6",{"_index":7492,"t":{"1764":{"position":[[3233,7]]}}}],["24.03.1",{"_index":8558,"t":{"2459":{"position":[[277,7]]}}}],["24.04",{"_index":3772,"t":{"796":{"position":[[585,5],[818,7],[1113,5],[1137,5],[1213,5],[1253,5],[1274,5],[1320,5]]},"850":{"position":[[7780,5]]},"1484":{"position":[[7780,5]]},"1533":{"position":[[585,5],[818,7],[1113,5],[1137,5],[1213,5],[1253,5],[1274,5],[1320,5]]}}}],["24194",{"_index":6388,"t":{"1321":{"position":[[219,5]]}}}],["2467806f",{"_index":9834,"t":{"3109":{"position":[[1960,8]]}}}],["247",{"_index":6484,"t":{"1337":{"position":[[412,3]]}}}],["2482",{"_index":9763,"t":{"3088":{"position":[[1026,4]]}}}],["24:28",{"_index":6473,"t":{"1337":{"position":[[218,5]]}}}],["24h",{"_index":2628,"t":{"472":{"position":[[1682,3]]}}}],["24h0m0",{"_index":2639,"t":{"472":{"position":[[2250,8]]}}}],["24hr",{"_index":4515,"t":{"922":{"position":[[463,5]]},"1644":{"position":[[463,5]]},"2369":{"position":[[463,5]]},"2899":{"position":[[90,5]]}}}],["25",{"_index":3901,"t":{"821":{"position":[[2948,3]]},"1124":{"position":[[1239,2]]},"1337":{"position":[[299,2]]},"1386":{"position":[[58,2]]},"1511":{"position":[[2948,3]]},"3014":{"position":[[186,2]]},"3357":{"position":[[616,2],[790,2]]}}}],["250",{"_index":10062,"t":{"3299":{"position":[[1981,4]]}}}],["250m",{"_index":3255,"t":{"615":{"position":[[827,7]]}}}],["25224",{"_index":6416,"t":{"1321":{"position":[[876,5]]}}}],["255",{"_index":3886,"t":{"821":{"position":[[2555,4],[3864,4],[5203,4]]},"1511":{"position":[[2555,4],[3864,4],[5203,4]]}}}],["256",{"_index":3855,"t":{"819":{"position":[[5970,3]]},"821":{"position":[[3793,4],[3903,4],[3921,4],[3988,4],[4010,5],[4042,4],[4058,4],[4071,4],[4107,4],[4130,4],[4174,4],[4193,5]]},"982":{"position":[[645,3],[663,3]]},"1031":{"position":[[847,3],[950,3]]},"1252":{"position":[[754,3]]},"1509":{"position":[[5970,3]]},"1511":{"position":[[3793,4],[3903,4],[3921,4],[3988,4],[4010,5],[4042,4],[4058,4],[4071,4],[4107,4],[4130,4],[4174,4],[4193,5]]},"1900":{"position":[[265,3]]},"2016":{"position":[[265,3]]},"2911":{"position":[[216,3]]}}}],["25fa8b012e40",{"_index":9854,"t":{"3109":{"position":[[2185,12]]}}}],["25ff9702e0e5",{"_index":6591,"t":{"1360":{"position":[[1839,12]]}}}],["25g",{"_index":4692,"t":{"982":{"position":[[702,3]]},"984":{"position":[[569,3]]},"988":{"position":[[407,3]]},"990":{"position":[[470,3]]},"995":{"position":[[622,3],[641,3],[685,3],[747,4]]}}}],["25m",{"_index":3553,"t":{"660":{"position":[[3544,3]]}}}],["26",{"_index":5442,"t":{"1124":{"position":[[1242,2]]},"2735":{"position":[[1121,2],[1158,2],[1198,2],[1225,2],[1343,2],[1426,2]]},"2774":{"position":[[1123,2],[1160,2],[1200,2],[1227,2],[1345,2],[1428,2]]},"3357":{"position":[[810,2]]}}}],["262144",{"_index":3909,"t":{"821":{"position":[[3956,7]]},"1031":{"position":[[233,6]]},"1511":{"position":[[3956,7]]}}}],["26234859",{"_index":5161,"t":{"1106":{"position":[[263,8]]}}}],["264",{"_index":3079,"t":{"600":{"position":[[1024,6]]}}}],["26595dd3",{"_index":4226,"t":{"859":{"position":[[4084,8],[4306,8],[4740,8],[4855,8],[6188,8]]},"1603":{"position":[[4084,8],[4306,8],[4740,8],[4855,8],[6188,8]]}}}],["266",{"_index":6736,"t":{"1368":{"position":[[2051,3]]}}}],["27",{"_index":2330,"t":{"393":{"position":[[883,2],[918,2],[1002,2],[1299,2],[1352,2],[1384,2],[1451,2]]},"404":{"position":[[418,2]]},"1124":{"position":[[1245,2]]},"1339":{"position":[[100,2]]},"1342":{"position":[[585,2],[761,2]]},"2895":{"position":[[1703,2]]},"3482":{"position":[[948,2]]}}}],["270",{"_index":6397,"t":{"1321":{"position":[[296,3],[953,3]]}}}],["2733nt",{"_index":4715,"t":{"988":{"position":[[474,6]]}}}],["28",{"_index":3528,"t":{"660":{"position":[[1400,2],[2652,2],[2798,2]]},"790":{"position":[[1318,2]]},"1124":{"position":[[1248,2]]},"1527":{"position":[[1318,2]]},"1775":{"position":[[131,2]]},"2524":{"position":[[394,2]]},"3429":{"position":[[269,2]]}}}],["29",{"_index":5443,"t":{"1124":{"position":[[1251,2]]},"2204":{"position":[[23,3]]}}}],["29404",{"_index":5482,"t":{"1144":{"position":[[100,6]]}}}],["2:**4:10n",{"_index":9410,"t":{"2840":{"position":[[1765,9]]}}}],["2:16",{"_index":9195,"t":{"2711":{"position":[[477,4]]},"2856":{"position":[[479,4]]}}}],["2:4",{"_index":9189,"t":{"2711":{"position":[[337,3]]},"2856":{"position":[[339,3]]}}}],["2:8",{"_index":9185,"t":{"2711":{"position":[[227,3]]},"2856":{"position":[[229,3]]}}}],["2>/dev/nul",{"_index":4482,"t":{"913":{"position":[[3125,11]]},"1635":{"position":[[3125,11]]},"2360":{"position":[[3125,11]]}}}],["2@2(peon).osd",{"_index":6421,"t":{"1321":{"position":[[1103,13]]}}}],["2@rbd",{"_index":6516,"t":{"1347":{"position":[[738,5],[1401,5],[1452,5]]}}}],["2].testbed.osism.xyz",{"_index":5099,"t":{"1089":{"position":[[2764,20]]}}}],["2^30",{"_index":9526,"t":{"2892":{"position":[[491,4]]}}}],["2a12b545",{"_index":7791,"t":{"1843":{"position":[[984,8]]},"1845":{"position":[[2555,8]]}}}],["2a33a889",{"_index":6801,"t":{"1386":{"position":[[147,8]]}}}],["2a4a82a879bb",{"_index":5267,"t":{"1114":{"position":[[1174,12],[1545,12],[1751,12],[2301,12],[2544,12],[2912,12],[3018,12]]}}}],["2c",{"_index":9149,"t":{"2705":{"position":[[2051,2]]},"2707":{"position":[[379,2],[392,2],[407,2],[421,2],[435,2],[450,2]]},"2709":{"position":[[1463,2],[1476,2],[1489,2],[1509,2],[1556,2],[1578,2],[1616,2],[1635,2],[1704,2],[1721,2],[1766,2],[1783,2],[1811,2],[1824,2],[1929,2],[1945,2],[2044,2],[2131,2],[2197,2]]},"2721":{"position":[[260,2],[273,2],[290,2]]},"2723":{"position":[[648,2],[710,2],[771,2],[818,2],[912,2]]},"2725":{"position":[[989,2],[1002,2],[1017,2],[1033,2],[1050,2],[1068,2],[1087,2],[1107,2],[1127,2],[1148,2]]},"2733":{"position":[[21,2]]},"2750":{"position":[[2353,2]]},"2752":{"position":[[379,2],[392,2],[407,2],[421,2],[435,2],[450,2]]},"2754":{"position":[[1604,2],[1617,2],[1630,2],[1650,2],[1697,2],[1719,2],[1757,2],[1776,2],[1845,2],[1862,2],[1907,2],[1924,2],[1952,2],[1965,2],[2070,2],[2086,2],[2152,2]]},"2760":{"position":[[272,2],[285,2],[302,2]]},"2762":{"position":[[661,2],[723,2],[784,2],[831,2],[925,2]]},"2764":{"position":[[1564,2],[1577,2],[1592,2],[1608,2],[1625,2],[1643,2],[1662,2],[1682,2],[1702,2],[1723,2]]},"2772":{"position":[[21,2]]}}}],["2c9e0e4ef8d44c36807df50b06b3c81d",{"_index":307,"t":{"27":{"position":[[596,32]]}}}],["2c:3.5:10n",{"_index":9414,"t":{"2842":{"position":[[366,10]]}}}],["2c:4",{"_index":9422,"t":{"2844":{"position":[[1515,5],[1560,5],[1577,5],[1605,5],[1618,4],[1723,4]]}}}],["2c:4:1.5n",{"_index":9426,"t":{"2844":{"position":[[1990,9]]}}}],["2c:4:10",{"_index":9419,"t":{"2844":{"position":[[1270,8],[1283,8],[1372,7],[1410,7]]},"2848":{"position":[[647,7],[709,7],[729,7],[776,7]]}}}],["2c:4:10n",{"_index":9405,"t":{"2840":{"position":[[1699,8]]},"2842":{"position":[[353,8]]},"2844":{"position":[[1257,8]]},"2846":{"position":[[260,8],[273,8],[290,8]]},"2850":{"position":[[882,8],[895,8],[910,8],[926,8],[943,8],[961,8],[980,8],[1000,8],[1020,8],[1041,8]]},"2854":{"position":[[21,8]]}}}],["2c:4:3x",{"_index":9425,"t":{"2844":{"position":[[1739,7],[1837,8]]}}}],["2c:4:3x10",{"_index":9420,"t":{"2844":{"position":[[1303,10],[1350,10],[1924,9]]}}}],["2c:4:n",{"_index":9421,"t":{"2844":{"position":[[1429,6],[1498,6]]}}}],["2c:4o:10n",{"_index":9416,"t":{"2842":{"position":[[395,9]]}}}],["2c:4ou:10n",{"_index":9418,"t":{"2842":{"position":[[424,10]]}}}],["2c:4u:10n",{"_index":9415,"t":{"2842":{"position":[[381,9]]}}}],["2c:4uo:10n",{"_index":9417,"t":{"2842":{"position":[[409,10]]}}}],["2d",{"_index":8302,"t":{"2150":{"position":[[35,2]]}}}],["2d08e835",{"_index":7865,"t":{"1847":{"position":[[1407,8]]}}}],["2dfc3916",{"_index":7825,"t":{"1845":{"position":[[2052,8]]}}}],["2e0e",{"_index":5269,"t":{"1114":{"position":[[1244,4],[1379,4],[1430,4],[1478,4],[2143,4],[2396,4],[2639,4],[2681,4],[2852,4]]}}}],["2e6227aa",{"_index":6674,"t":{"1366":{"position":[[232,8]]}}}],["2f25f55f",{"_index":5014,"t":{"1077":{"position":[[587,8],[719,8]]}}}],["2gib",{"_index":9604,"t":{"2947":{"position":[[1522,4]]}}}],["2it",{"_index":9154,"t":{"2705":{"position":[[2152,3]]},"2750":{"position":[[2454,3]]}}}],["2it:4:10n",{"_index":9411,"t":{"2840":{"position":[[1800,9]]}}}],["2k",{"_index":10075,"t":{"3299":{"position":[[4597,3]]}}}],["2l",{"_index":9152,"t":{"2705":{"position":[[2090,2]]},"2750":{"position":[[2392,2]]}}}],["2l:4:10n",{"_index":9408,"t":{"2840":{"position":[[1738,8]]}}}],["2li",{"_index":9153,"t":{"2705":{"position":[[2103,3]]},"2750":{"position":[[2405,3]]}}}],["2li:4:10n",{"_index":9409,"t":{"2840":{"position":[[1751,9]]}}}],["2m",{"_index":3647,"t":{"738":{"position":[[441,3]]}}}],["2m51",{"_index":2421,"t":{"413":{"position":[[341,5],[421,5]]},"442":{"position":[[260,5],[340,5]]}}}],["2nd",{"_index":3716,"t":{"780":{"position":[[529,3]]},"1562":{"position":[[737,3]]},"1585":{"position":[[682,3],[1758,3],[2212,3],[3546,3]]}}}],["2t",{"_index":9151,"t":{"2705":{"position":[[2064,2]]},"2750":{"position":[[2366,2]]}}}],["2t:4:10n",{"_index":9406,"t":{"2840":{"position":[[1712,8]]}}}],["2v",{"_index":2673,"t":{"483":{"position":[[242,2]]},"487":{"position":[[1380,2],[1484,2]]},"660":{"position":[[100,2],[127,2]]},"730":{"position":[[1314,2],[1628,2],[2174,2],[2356,2]]},"734":{"position":[[129,2],[187,2]]},"857":{"position":[[171,2]]},"859":{"position":[[2451,2],[2567,2]]},"861":{"position":[[292,2]]},"903":{"position":[[2072,2]]},"1491":{"position":[[1314,2],[1628,2],[2174,2],[2356,2]]},"1495":{"position":[[129,2],[187,2]]},"1601":{"position":[[171,2]]},"1603":{"position":[[2451,2],[2567,2]]},"1605":{"position":[[292,2]]},"1625":{"position":[[2072,2]]},"2350":{"position":[[2072,2]]},"2705":{"position":[[2077,2]]},"2711":{"position":[[235,2],[245,2],[345,2],[355,2],[486,2],[497,2]]},"2750":{"position":[[2379,2]]},"2756":{"position":[[638,2],[658,2]]},"2927":{"position":[[97,2],[241,2],[266,2],[408,2]]},"2929":{"position":[[109,2],[261,2],[454,2]]},"2949":{"position":[[31,2]]}}}],["2v:16",{"_index":9459,"t":{"2856":{"position":[[488,6]]}}}],["2v:16:50",{"_index":9460,"t":{"2856":{"position":[[499,8]]}}}],["2v:4",{"_index":9449,"t":{"2856":{"position":[[347,5]]}}}],["2v:4:10",{"_index":9450,"t":{"2856":{"position":[[357,7]]}}}],["2v:4:10n",{"_index":9407,"t":{"2840":{"position":[[1725,8]]}}}],["2v:4:20",{"_index":413,"t":{"37":{"position":[[194,7],[306,7]]},"40":{"position":[[192,7],[304,7]]},"730":{"position":[[2328,10]]},"1491":{"position":[[2328,10]]}}}],["2v:8",{"_index":9442,"t":{"2856":{"position":[[237,5]]}}}],["2v:8:20",{"_index":9443,"t":{"2856":{"position":[[247,7]]}}}],["2vcpu",{"_index":4185,"t":{"859":{"position":[[2297,6]]},"1603":{"position":[[2297,6]]}}}],["2x",{"_index":4683,"t":{"982":{"position":[[486,2]]},"984":{"position":[[214,2],[278,2]]},"986":{"position":[[225,2]]},"988":{"position":[[225,2],[289,2]]},"990":{"position":[[278,2]]},"995":{"position":[[682,2]]},"1080":{"position":[[911,3]]},"1825":{"position":[[1074,3]]}}}],["2x200gb",{"_index":9330,"t":{"2733":{"position":[[452,7]]},"2772":{"position":[[452,7]]},"2854":{"position":[[453,7]]}}}],["2x200p_a1",{"_index":9328,"t":{"2733":{"position":[[394,9]]},"2772":{"position":[[394,9]]}}}],["3",{"_index":339,"t":{"27":{"position":[[1484,1],[1522,1]]},"37":{"position":[[284,1],[314,1]]},"40":{"position":[[282,1],[312,1]]},"131":{"position":[[637,1]]},"166":{"position":[[997,1]]},"170":{"position":[[1138,1],[2031,1]]},"253":{"position":[[1528,2],[1587,1]]},"321":{"position":[[1063,2],[1588,1]]},"487":{"position":[[1811,1]]},"507":{"position":[[376,1]]},"590":{"position":[[1525,3],[1689,3]]},"609":{"position":[[882,1]]},"615":{"position":[[31,1]]},"635":{"position":[[1654,3]]},"650":{"position":[[571,1],[2463,2]]},"652":{"position":[[392,1],[970,1],[1144,1]]},"819":{"position":[[7924,1]]},"850":{"position":[[9431,1]]},"859":{"position":[[4034,1],[4239,2],[4477,2],[4577,2],[4692,2]]},"905":{"position":[[346,1]]},"909":{"position":[[2788,1]]},"1031":{"position":[[317,1],[358,1]]},"1108":{"position":[[614,3]]},"1124":{"position":[[461,1],[715,2],[1061,1]]},"1167":{"position":[[1022,2],[2034,1]]},"1169":{"position":[[248,2]]},"1217":{"position":[[263,1],[809,1],[832,1]]},"1219":{"position":[[362,2]]},"1288":{"position":[[271,1]]},"1298":{"position":[[435,1],[477,1],[525,1],[628,1],[688,1]]},"1305":{"position":[[442,1]]},"1430":{"position":[[116,1],[294,1],[909,1],[1087,1],[1552,1],[1730,1]]},"1475":{"position":[[277,1],[546,1]]},"1484":{"position":[[9431,1]]},"1509":{"position":[[7924,1]]},"1603":{"position":[[4034,1],[4239,2],[4477,2],[4577,2],[4692,2]]},"1627":{"position":[[346,1]]},"1631":{"position":[[2788,1]]},"1775":{"position":[[156,2],[235,1]]},"1787":{"position":[[949,1]]},"1791":{"position":[[2420,1],[3225,1]]},"1808":{"position":[[643,1],[663,1]]},"1974":{"position":[[737,2]]},"2100":{"position":[[944,1]]},"2276":{"position":[[23,1]]},"2352":{"position":[[346,1]]},"2356":{"position":[[2788,1]]},"2625":{"position":[[1619,1]]},"2688":{"position":[[1387,1]]},"2725":{"position":[[520,1],[535,1]]},"2764":{"position":[[741,1],[756,1]]},"2844":{"position":[[1509,1]]},"2850":{"position":[[429,1],[444,1]]},"2895":{"position":[[1515,1]]},"2911":{"position":[[290,1]]},"2939":{"position":[[92,2]]},"3011":{"position":[[1548,2],[1646,2]]},"3014":{"position":[[504,1]]},"3016":{"position":[[35,2]]},"3071":{"position":[[2543,1]]},"3115":{"position":[[525,3]]},"3124":{"position":[[794,1]]},"3167":{"position":[[256,1],[561,1]]},"3182":{"position":[[1328,3]]},"3184":{"position":[[2414,1]]},"3188":{"position":[[118,1]]},"3284":{"position":[[272,1]]},"3316":{"position":[[1613,1]]}}}],["3.0",{"_index":5828,"t":{"1165":{"position":[[1677,3],[1825,3]]},"2774":{"position":[[32,3]]}}}],["3.0.0",{"_index":8414,"t":{"2245":{"position":[[785,5]]}}}],["3.0.1",{"_index":8477,"t":{"2315":{"position":[[444,6]]}}}],["3.04",{"_index":6490,"t":{"1339":{"position":[[224,5]]}}}],["3.07",{"_index":6457,"t":{"1333":{"position":[[271,5]]}}}],["3.10",{"_index":3734,"t":{"790":{"position":[[535,6]]},"1527":{"position":[[535,6]]},"1777":{"position":[[174,5]]}}}],["3.14159",{"_index":849,"t":{"131":{"position":[[605,7]]}}}],["3.2.0",{"_index":8518,"t":{"2403":{"position":[[203,7]]}}}],["3.2.7",{"_index":2404,"t":{"409":{"position":[[314,5]]}}}],["3.25ghz",{"_index":9270,"t":{"2725":{"position":[[935,8],[1202,7]]},"2764":{"position":[[1510,8],[1772,7]]},"2850":{"position":[[828,8]]}}}],["3.26.x",{"_index":8529,"t":{"2405":{"position":[[495,8]]}}}],["3.3.0",{"_index":8557,"t":{"2459":{"position":[[267,5]]}}}],["3.5",{"_index":9156,"t":{"2707":{"position":[[134,5],[395,3]]},"2752":{"position":[[134,5],[395,3]]},"2842":{"position":[[140,5]]}}}],["3.64",{"_index":7946,"t":{"1896":{"position":[[386,5],[438,4]]},"2012":{"position":[[386,5],[438,4]]}}}],["3.75ghz",{"_index":9272,"t":{"2725":{"position":[[957,8]]},"2764":{"position":[[1532,8]]},"2850":{"position":[[850,8]]}}}],["3.9kb",{"_index":6232,"t":{"1305":{"position":[[365,5]]}}}],["3.de.pool.ntp.org",{"_index":4996,"t":{"1067":{"position":[[5765,17]]}}}],["3.testbed.osism.xyz",{"_index":5389,"t":{"1120":{"position":[[1834,19]]},"1787":{"position":[[916,19]]}}}],["3/19",{"_index":4911,"t":{"1063":{"position":[[881,6]]}}}],["30",{"_index":3932,"t":{"838":{"position":[[32,2],[163,2]]},"1112":{"position":[[1940,2],[1994,2],[2658,2],[3022,2],[3076,2]]},"1114":{"position":[[396,2],[1911,2]]},"1124":{"position":[[1254,2]]},"1234":{"position":[[2284,3]]},"1311":{"position":[[22,2]]},"1553":{"position":[[32,2],[163,2]]},"1808":{"position":[[783,2]]},"2536":{"position":[[504,2]]},"2795":{"position":[[1814,2]]},"2895":{"position":[[4401,3]]},"3014":{"position":[[131,2]]},"3299":{"position":[[3344,3]]},"3429":{"position":[[294,2]]}}}],["30.04.2024",{"_index":382,"t":{"27":{"position":[[3078,10]]}}}],["30.09.2024",{"_index":361,"t":{"27":{"position":[[2055,10],[2159,10],[2263,10],[2367,10],[2471,10],[2575,10],[2679,10],[2783,10],[2887,10],[2991,10]]}}}],["30.11.2024",{"_index":293,"t":{"25":{"position":[[875,10]]},"27":{"position":[[1422,10],[1783,10]]}}}],["300",{"_index":5844,"t":{"1165":{"position":[[2916,3]]},"1321":{"position":[[1953,3]]},"2564":{"position":[[62,3]]}}}],["3000",{"_index":4337,"t":{"903":{"position":[[1361,4]]},"938":{"position":[[418,6]]},"1625":{"position":[[1361,4]]},"1660":{"position":[[418,6]]},"2350":{"position":[[1361,4]]},"2385":{"position":[[418,6]]}}}],["30000",{"_index":9972,"t":{"3236":{"position":[[877,5]]}}}],["302",{"_index":6405,"t":{"1321":{"position":[[694,5]]}}}],["30t10:14:01.410334z",{"_index":6349,"t":{"1317":{"position":[[6765,19]]}}}],["30t10:14:01.731212z",{"_index":6257,"t":{"1317":{"position":[[1242,19],[1767,19]]}}}],["30t10:14:03.054547z",{"_index":6336,"t":{"1317":{"position":[[5252,19]]}}}],["30t10:14:04.801633z",{"_index":6333,"t":{"1317":{"position":[[5134,19]]}}}],["30t10:14:07.019883z",{"_index":6330,"t":{"1317":{"position":[[5005,19]]}}}],["30t10:14:08.551850z",{"_index":6326,"t":{"1317":{"position":[[4887,19]]}}}],["30t10:14:10.895833z",{"_index":6323,"t":{"1317":{"position":[[4737,19]]}}}],["30t10:14:12.216984z",{"_index":6320,"t":{"1317":{"position":[[4576,19]]}}}],["30t10:14:13.588195z",{"_index":6317,"t":{"1317":{"position":[[4423,19]]}}}],["30t10:14:15.911699z",{"_index":6314,"t":{"1317":{"position":[[4280,19]]}}}],["30t10:14:16.932135z",{"_index":6366,"t":{"1317":{"position":[[8533,19]]}}}],["30t10:14:17.542234z",{"_index":6311,"t":{"1317":{"position":[[4146,19]]}}}],["30t10:14:18.711171z",{"_index":6308,"t":{"1317":{"position":[[4011,19]]}}}],["30t10:14:19.859670z",{"_index":6305,"t":{"1317":{"position":[[3876,19]]}}}],["30t10:14:21.085351z",{"_index":6302,"t":{"1317":{"position":[[3741,19]]}}}],["30t10:14:23.199518z",{"_index":6297,"t":{"1317":{"position":[[3615,19]]}}}],["30t10:14:24.880329z",{"_index":6293,"t":{"1317":{"position":[[3476,19]]}}}],["30t10:14:26.422535z",{"_index":6288,"t":{"1317":{"position":[[3340,19]]}}}],["30t10:14:27.979869z",{"_index":6285,"t":{"1317":{"position":[[3183,19]]}}}],["30t10:14:29.500998z",{"_index":6281,"t":{"1317":{"position":[[3044,19]]}}}],["30t10:14:31.411916z",{"_index":6277,"t":{"1317":{"position":[[2903,19]]}}}],["30t10:14:34.134312z",{"_index":6274,"t":{"1317":{"position":[[2776,19]]}}}],["30t10:14:35.502754z",{"_index":6270,"t":{"1317":{"position":[[2653,19]]}}}],["30t10:14:37.126872z",{"_index":6266,"t":{"1317":{"position":[[2517,19],[5918,19]]}}}],["30t10:14:39.678878z",{"_index":6345,"t":{"1317":{"position":[[5958,19]]}}}],["30t10:14:39.969244z",{"_index":6263,"t":{"1317":{"position":[[1807,19]]}}}],["30t10:14:40.279181z",{"_index":6364,"t":{"1317":{"position":[[8438,19]]}}}],["30t10:14:40.280601z",{"_index":6362,"t":{"1317":{"position":[[8339,19]]}}}],["30t10:14:40.283581z",{"_index":6360,"t":{"1317":{"position":[[8240,19]]}}}],["30t10:14:40.543599z",{"_index":6358,"t":{"1317":{"position":[[8140,19],[9054,19]]}}}],["30t18:50:05.000000",{"_index":6515,"t":{"1347":{"position":[[686,18],[780,18]]}}}],["30t18:50:08.000000",{"_index":6518,"t":{"1347":{"position":[[874,18]]}}}],["31",{"_index":5444,"t":{"1124":{"position":[[1257,2]]},"1321":{"position":[[106,2],[379,2],[543,2],[763,2],[993,2],[1231,2]]},"2536":{"position":[[450,2]]},"2546":{"position":[[594,2]]},"2795":{"position":[[1750,2]]},"2895":{"position":[[4427,3]]}}}],["31.12.2023",{"_index":273,"t":{"25":{"position":[[353,10]]},"27":{"position":[[1070,10]]}}}],["31.12.2024",{"_index":281,"t":{"25":{"position":[[500,10]]},"27":{"position":[[585,10],[708,10]]}}}],["31/oct/2023",{"_index":6440,"t":{"1321":{"position":[[1913,12]]}}}],["31248d71ab7d",{"_index":6579,"t":{"1360":{"position":[[1304,12]]}}}],["3128",{"_index":5988,"t":{"1201":{"position":[[230,8]]},"1203":{"position":[[206,8],[254,8]]},"1205":{"position":[[230,8],[294,8]]}}}],["31459327",{"_index":5307,"t":{"1114":{"position":[[3820,8]]}}}],["31459328",{"_index":5309,"t":{"1114":{"position":[[3868,8]]}}}],["3194",{"_index":5325,"t":{"1114":{"position":[[4791,4],[5079,4],[5130,4],[5657,4],[5964,4],[6302,4],[6344,4]]}}}],["31t10:45:35.498718+0000",{"_index":6385,"t":{"1321":{"position":[[165,23]]}}}],["31t11:19:56.329684+0000",{"_index":6415,"t":{"1321":{"position":[[822,23]]}}}],["31t11:19:57.650+0000",{"_index":6401,"t":{"1321":{"position":[[430,20],[594,20]]}}}],["31t11:19:58.566+0000",{"_index":6418,"t":{"1321":{"position":[[1050,20]]}}}],["31t11:19:58.710+0000",{"_index":6430,"t":{"1321":{"position":[[1282,20]]}}}],["32",{"_index":405,"t":{"37":{"position":[[118,2]]},"40":{"position":[[116,2]]},"730":{"position":[[1424,2]]},"790":{"position":[[827,2]]},"982":{"position":[[791,2]]},"988":{"position":[[308,2]]},"1124":{"position":[[1260,2]]},"1252":{"position":[[676,2]]},"1475":{"position":[[613,2]]},"1491":{"position":[[1424,2]]},"1527":{"position":[[827,2]]},"1562":{"position":[[325,2]]},"1773":{"position":[[1048,2]]},"1808":{"position":[[426,2]]},"2711":{"position":[[294,3],[305,2],[432,3],[444,2],[518,3],[529,2]]},"2713":{"position":[[803,2]]},"2733":{"position":[[94,2]]},"2756":{"position":[[1271,2]]},"2772":{"position":[[94,2]]},"2927":{"position":[[192,2],[209,2],[358,2],[376,2],[438,2],[455,2]]},"2929":{"position":[[188,2],[209,2],[378,2],[400,2],[496,2],[517,2]]}}}],["321",{"_index":6392,"t":{"1321":{"position":[[255,3],[264,3],[912,3],[921,3]]}}}],["322961408",{"_index":6429,"t":{"1321":{"position":[[1217,9]]}}}],["3261",{"_index":9870,"t":{"3109":{"position":[[2377,4]]}}}],["32767",{"_index":9973,"t":{"3236":{"position":[[883,5]]}}}],["32768",{"_index":5963,"t":{"1180":{"position":[[190,5]]}}}],["32d",{"_index":4735,"t":{"997":{"position":[[66,3]]}}}],["32gib",{"_index":9318,"t":{"2733":{"position":[[150,5]]},"2772":{"position":[[150,5]]},"2854":{"position":[[150,5]]}}}],["32x",{"_index":4731,"t":{"995":{"position":[[812,3]]},"997":{"position":[[31,3]]}}}],["33",{"_index":5445,"t":{"1124":{"position":[[1263,2]]},"1333":{"position":[[234,2]]}}}],["3306/tcp",{"_index":7336,"t":{"1731":{"position":[[2447,8]]}}}],["330a",{"_index":4013,"t":{"842":{"position":[[1725,4]]},"1557":{"position":[[1725,4]]}}}],["330e",{"_index":3619,"t":{"730":{"position":[[2131,4]]},"1491":{"position":[[2131,4]]}}}],["338bcf4dde7c",{"_index":4001,"t":{"842":{"position":[[1453,12]]},"1557":{"position":[[1453,12]]}}}],["33f1",{"_index":6675,"t":{"1366":{"position":[[241,4]]}}}],["34",{"_index":5446,"t":{"1124":{"position":[[1266,2]]}}}],["3463cc7b81e0",{"_index":4246,"t":{"859":{"position":[[5043,12],[5326,12],[5545,12],[5760,12],[6294,12]]},"1603":{"position":[[5043,12],[5326,12],[5545,12],[5760,12],[6294,12]]}}}],["348127232",{"_index":6426,"t":{"1321":{"position":[[1175,9],[1197,9]]}}}],["35",{"_index":5447,"t":{"1124":{"position":[[1269,2]]},"1339":{"position":[[188,2]]}}}],["35.1kb",{"_index":6236,"t":{"1305":{"position":[[451,6]]}}}],["3501db829014406884990a1016f3e25d",{"_index":308,"t":{"27":{"position":[[719,32]]}}}],["3519:55",{"_index":6478,"t":{"1337":{"position":[[307,7]]}}}],["3593b2a409a4",{"_index":4214,"t":{"859":{"position":[[3112,12],[3334,12],[3553,12],[3668,12],[5966,12]]},"1603":{"position":[[3112,12],[3334,12],[3553,12],[3668,12],[5966,12]]}}}],["36",{"_index":5448,"t":{"1124":{"position":[[1272,2]]},"1364":{"position":[[377,2]]}}}],["3600",{"_index":4772,"t":{"1017":{"position":[[496,5]]},"1758":{"position":[[487,4]]}}}],["3602",{"_index":8494,"t":{"2326":{"position":[[164,4]]}}}],["3614d94f46fd",{"_index":7834,"t":{"1845":{"position":[[2117,12]]}}}],["36c3",{"_index":7755,"t":{"1833":{"position":[[941,4]]}}}],["37",{"_index":5449,"t":{"1124":{"position":[[1275,2]]}}}],["374",{"_index":8076,"t":{"2031":{"position":[[44,4]]}}}],["3786",{"_index":8495,"t":{"2326":{"position":[[182,4]]}}}],["38",{"_index":5450,"t":{"1124":{"position":[[1278,2]]}}}],["3829cc7c8f034fc985f5055a1df6f247",{"_index":302,"t":{"27":{"position":[[332,32]]}}}],["3867",{"_index":6340,"t":{"1317":{"position":[[5678,4]]}}}],["39",{"_index":5451,"t":{"1124":{"position":[[1281,2]]}}}],["394d8e71",{"_index":9799,"t":{"3109":{"position":[[605,8]]}}}],["3a96207b719643ae9ea9a81d95116e9",{"_index":4044,"t":{"842":{"position":[[2255,32]]},"1557":{"position":[[2255,32]]}}}],["3am",{"_index":2847,"t":{"493":{"position":[[1740,3]]}}}],["3b585d348820",{"_index":9771,"t":{"3088":{"position":[[1243,12]]}}}],["3bf43ae5a94f",{"_index":6605,"t":{"1360":{"position":[[2369,12]]}}}],["3c249ba0e010",{"_index":9832,"t":{"3109":{"position":[[1924,12],[2629,12],[2843,12]]}}}],["3c5bae4a233c4a9d8ae2e4b799d757c9",{"_index":372,"t":{"27":{"position":[[2586,32]]}}}],["3cd241ff",{"_index":7860,"t":{"1847":{"position":[[1368,8]]}}}],["3cfa8679f5d8429382b95d4d2dd80f79",{"_index":3975,"t":{"842":{"position":[[999,32],[1092,32],[1373,32],[1660,32],[1755,32],[2361,32]]},"1557":{"position":[[999,32],[1092,32],[1373,32],[1660,32],[1755,32],[2361,32]]}}}],["3k",{"_index":10059,"t":{"3299":{"position":[[1399,3]]}}}],["3rd",{"_index":2561,"t":{"456":{"position":[[8,3]]},"780":{"position":[[536,3]]},"2901":{"position":[[2048,3]]},"3245":{"position":[[429,3],[524,3]]},"3251":{"position":[[574,3]]}}}],["3x",{"_index":9129,"t":{"2705":{"position":[[428,2]]},"2709":{"position":[[1950,2],[2049,3]]},"2750":{"position":[[428,2]]},"2840":{"position":[[336,2]]}}}],["3x/thread",{"_index":9144,"t":{"2705":{"position":[[1584,9]]},"2750":{"position":[[1886,9]]},"2840":{"position":[[1232,9]]}}}],["3x10",{"_index":9170,"t":{"2709":{"position":[[1514,5],[2136,4]]},"2754":{"position":[[1655,5],[2091,4]]}}}],["3x10s_bms_z3",{"_index":9172,"t":{"2709":{"position":[[1561,12]]},"2754":{"position":[[1702,12]]}}}],["4",{"_index":486,"t":{"65":{"position":[[42,1]]},"321":{"position":[[1114,2]]},"483":{"position":[[245,1]]},"487":{"position":[[1383,1],[1487,1]]},"650":{"position":[[2470,3]]},"660":{"position":[[103,2],[130,2]]},"730":{"position":[[1264,1],[1631,1],[2177,1],[2359,1]]},"734":{"position":[[132,1],[190,1]]},"750":{"position":[[483,1]]},"821":{"position":[[5134,2],[5259,2],[5322,2],[5342,3],[5372,2],[5620,2],[5634,3]]},"850":{"position":[[4839,2],[8495,2]]},"859":{"position":[[4969,1],[5071,2],[5354,2],[5573,2],[5788,2]]},"903":{"position":[[2075,1]]},"1112":{"position":[[5019,2]]},"1122":{"position":[[632,1],[719,1]]},"1124":{"position":[[1063,1]]},"1182":{"position":[[180,1]]},"1219":{"position":[[407,2]]},"1288":{"position":[[240,1]]},"1317":{"position":[[2577,1],[2713,1],[2836,1],[2963,1],[3104,1],[3243,1],[3400,1],[3536,1],[3675,1],[4340,1],[4483,1],[4636,1],[4797,1],[4947,1],[5065,1],[5194,1]]},"1430":{"position":[[185,1],[978,1],[1621,1]]},"1473":{"position":[[1205,2]]},"1484":{"position":[[4839,2],[8495,2]]},"1491":{"position":[[1264,1],[1631,1],[2177,1],[2359,1]]},"1495":{"position":[[132,1],[190,1]]},"1511":{"position":[[5134,2],[5259,2],[5322,2],[5342,3],[5372,2],[5620,2],[5634,3]]},"1562":{"position":[[137,1]]},"1571":{"position":[[320,1]]},"1603":{"position":[[4969,1],[5071,2],[5354,2],[5573,2],[5788,2]]},"1625":{"position":[[2075,1]]},"1775":{"position":[[119,1]]},"1787":{"position":[[1011,1]]},"2118":{"position":[[1324,3]]},"2281":{"position":[[980,3]]},"2310":{"position":[[8,1]]},"2326":{"position":[[23,1]]},"2350":{"position":[[2075,1]]},"2520":{"position":[[316,2]]},"2522":{"position":[[748,1]]},"2625":{"position":[[1625,1]]},"2695":{"position":[[42,2]]},"2705":{"position":[[2054,1],[2067,1],[2080,1],[2093,1],[2107,1],[2119,3],[2156,1]]},"2707":{"position":[[382,1]]},"2709":{"position":[[1466,1],[1479,1],[1492,1],[1512,1],[1559,1],[1581,1],[1619,1],[1638,1],[1707,1],[1724,1],[1769,1],[1786,1],[1814,1],[1827,1],[1948,1],[2047,1],[2134,1],[2200,1]]},"2711":{"position":[[212,2],[222,1],[348,2],[358,1]]},"2721":{"position":[[263,1],[276,1],[293,1]]},"2723":{"position":[[651,1],[713,1],[774,1],[821,1],[915,1]]},"2725":{"position":[[568,1],[590,1],[992,1],[1005,1],[1020,1],[1036,1],[1053,1],[1071,1],[1090,1],[1110,1],[1130,1],[1151,1]]},"2733":{"position":[[24,1],[404,1]]},"2750":{"position":[[2356,1],[2369,1],[2382,1],[2395,1],[2409,1],[2421,3],[2458,1]]},"2752":{"position":[[382,1]]},"2754":{"position":[[1607,1],[1620,1],[1633,1],[1653,1],[1700,1],[1722,1],[1760,1],[1779,1],[1848,1],[1865,1],[1910,1],[1927,1],[1955,1],[1968,1],[2089,1],[2155,1]]},"2756":{"position":[[641,1],[661,1]]},"2760":{"position":[[275,1],[288,1],[305,1]]},"2762":{"position":[[664,1],[726,1],[787,1],[834,1],[928,1]]},"2764":{"position":[[789,1],[811,1],[1138,1],[1567,1],[1580,1],[1595,1],[1611,1],[1628,1],[1646,1],[1665,1],[1685,1],[1705,1],[1726,1]]},"2772":{"position":[[24,1],[404,1]]},"2795":{"position":[[1907,1]]},"2809":{"position":[[1012,1]]},"2850":{"position":[[477,1],[483,1]]},"2854":{"position":[[405,1]]},"2927":{"position":[[75,1],[91,1],[128,1],[160,1],[244,1],[260,1],[269,1],[289,1],[307,1],[441,1]]},"2929":{"position":[[75,1],[94,1],[155,1],[264,1],[283,1],[306,1],[503,1]]},"2949":{"position":[[34,1]]},"3011":{"position":[[2290,2]]},"3124":{"position":[[753,1]]},"3128":{"position":[[245,1]]},"3171":{"position":[[48,1]]},"3184":{"position":[[2899,3]]},"3188":{"position":[[148,1]]}}}],["4.0",{"_index":1783,"t":{"253":{"position":[[1673,4]]},"286":{"position":[[322,3]]},"734":{"position":[[238,3]]},"949":{"position":[[1192,3]]},"1495":{"position":[[238,3]]},"1671":{"position":[[1192,3]]},"1865":{"position":[[950,3]]},"1913":{"position":[[2169,3]]}}}],["4.0.0",{"_index":8451,"t":{"2278":{"position":[[499,5]]}}}],["4.00",{"_index":6456,"t":{"1333":{"position":[[265,5]]}}}],["4.2.0",{"_index":7180,"t":{"1678":{"position":[[1943,7]]}}}],["4.5.2",{"_index":2400,"t":{"409":{"position":[[181,5]]}}}],["4.de.pool.ntp.org",{"_index":4997,"t":{"1067":{"position":[[5785,17]]}}}],["4.testbed.osism.xyz",{"_index":5390,"t":{"1120":{"position":[[1867,19]]},"1787":{"position":[[978,19]]}}}],["4/",{"_index":9612,"t":{"2947":{"position":[[2517,5]]}}}],["4/19",{"_index":4913,"t":{"1063":{"position":[[919,6]]}}}],["4/2024",{"_index":1900,"t":{"286":{"position":[[281,6]]}}}],["40",{"_index":479,"t":{"63":{"position":[[48,3]]},"821":{"position":[[5543,3]]},"1124":{"position":[[1105,2]]},"1167":{"position":[[1937,3],[3085,3]]},"1511":{"position":[[5543,3]]},"2150":{"position":[[305,2]]},"3014":{"position":[[51,2]]}}}],["400g",{"_index":4732,"t":{"997":{"position":[[35,5]]}}}],["403",{"_index":8032,"t":{"1957":{"position":[[4356,4]]}}}],["4036",{"_index":4234,"t":{"859":{"position":[[4201,4],[4439,4],[4539,4],[4654,4],[6120,4]]},"1603":{"position":[[4201,4],[4439,4],[4539,4],[4654,4],[6120,4]]}}}],["403b",{"_index":4200,"t":{"859":{"position":[[2761,4]]},"1603":{"position":[[2761,4]]}}}],["404",{"_index":5347,"t":{"1118":{"position":[[385,3],[529,3],[868,3]]}}}],["4062",{"_index":9867,"t":{"3109":{"position":[[2342,4]]}}}],["408f",{"_index":6504,"t":{"1342":{"position":[[693,4]]}}}],["4096",{"_index":3632,"t":{"730":{"position":[[2376,4]]},"1031":{"position":[[530,4]]},"1298":{"position":[[426,4],[468,4]]},"1491":{"position":[[2376,4]]},"2288":{"position":[[183,4]]}}}],["4096m",{"_index":5399,"t":{"1122":{"position":[[586,7]]}}}],["40b0",{"_index":6639,"t":{"1364":{"position":[[124,4]]}}}],["40c3",{"_index":4009,"t":{"842":{"position":[[1635,4]]},"1557":{"position":[[1635,4]]}}}],["40cc",{"_index":4061,"t":{"842":{"position":[[3011,4]]},"1557":{"position":[[3011,4]]}}}],["40e1",{"_index":3438,"t":{"644":{"position":[[399,4]]}}}],["40e4",{"_index":3443,"t":{"644":{"position":[[495,4]]}}}],["40g",{"_index":6046,"t":{"1226":{"position":[[1500,4]]}}}],["41",{"_index":5422,"t":{"1124":{"position":[[1108,2]]}}}],["41048563",{"_index":6738,"t":{"1368":{"position":[[2109,8]]}}}],["41049332",{"_index":6732,"t":{"1368":{"position":[[1768,8]]}}}],["41063293",{"_index":6753,"t":{"1368":{"position":[[2788,8]]}}}],["41063820",{"_index":6748,"t":{"1368":{"position":[[2447,8]]}}}],["410b",{"_index":6410,"t":{"1321":{"position":[[733,4]]}}}],["414",{"_index":3327,"t":{"633":{"position":[[2011,5]]}}}],["416b",{"_index":6239,"t":{"1305":{"position":[[510,4]]}}}],["417",{"_index":3326,"t":{"633":{"position":[[1851,5]]}}}],["41943006",{"_index":5310,"t":{"1114":{"position":[[3877,8]]}}}],["41943040",{"_index":5285,"t":{"1114":{"position":[[3397,8]]}}}],["41cf",{"_index":5264,"t":{"1114":{"position":[[1159,4],[1530,4],[1736,4],[2286,4],[2529,4],[2897,4],[3003,4]]}}}],["42",{"_index":5423,"t":{"1124":{"position":[[1111,2]]}}}],["4210042010",{"_index":5131,"t":{"1098":{"position":[[680,10]]}}}],["4212",{"_index":7848,"t":{"1847":{"position":[[372,4],[724,4],[1284,4],[1468,4]]},"1849":{"position":[[78,4]]}}}],["422e",{"_index":7756,"t":{"1833":{"position":[[946,4]]}}}],["424",{"_index":3088,"t":{"604":{"position":[[408,5]]}}}],["42434",{"_index":6196,"t":{"1298":{"position":[[414,5],[420,5],[501,5],[507,5],[609,5],[615,5],[664,5],[670,5]]}}}],["425a",{"_index":7838,"t":{"1845":{"position":[[2166,4]]}}}],["4282",{"_index":7798,"t":{"1843":{"position":[[1069,4]]},"1845":{"position":[[2783,4]]}}}],["429",{"_index":2513,"t":{"436":{"position":[[957,5]]}}}],["42a6",{"_index":9857,"t":{"3109":{"position":[[2218,4]]}}}],["43",{"_index":5424,"t":{"1124":{"position":[[1114,2]]}}}],["4318",{"_index":7811,"t":{"1845":{"position":[[1167,4],[2647,4]]}}}],["4336346b4b18",{"_index":3974,"t":{"842":{"position":[[984,12]]},"1557":{"position":[[984,12]]}}}],["4340",{"_index":6803,"t":{"1386":{"position":[[161,4]]}}}],["434a",{"_index":7849,"t":{"1847":{"position":[[377,4],[729,4],[1289,4],[1473,4]]},"1849":{"position":[[83,4]]}}}],["4359",{"_index":4244,"t":{"859":{"position":[[5033,4],[5316,4],[5535,4],[5750,4],[6284,4]]},"1603":{"position":[[5033,4],[5316,4],[5535,4],[5750,4],[6284,4]]}}}],["44",{"_index":5425,"t":{"1124":{"position":[[1117,2]]}}}],["443",{"_index":2262,"t":{"379":{"position":[[755,3]]},"646":{"position":[[560,3]]},"1037":{"position":[[227,3]]},"1161":{"position":[[1905,6]]},"1743":{"position":[[280,3],[1394,3]]},"1863":{"position":[[976,3]]},"1925":{"position":[[976,3]]}}}],["443/tcp",{"_index":2426,"t":{"413":{"position":[[413,7]]},"442":{"position":[[332,7]]}}}],["4454144360",{"_index":7298,"t":{"1728":{"position":[[558,10]]}}}],["4476bf7afe9f",{"_index":5277,"t":{"1114":{"position":[[1326,12],[1600,12],[1651,12],[1699,12],[2228,12],[2476,12],[2762,12],[2804,12],[2973,12]]}}}],["44ad",{"_index":4014,"t":{"842":{"position":[[1730,4]]},"1557":{"position":[[1730,4]]}}}],["44d1",{"_index":7827,"t":{"1845":{"position":[[2066,4]]}}}],["44d2",{"_index":3937,"t":{"838":{"position":[[126,4],[222,4]]},"1553":{"position":[[126,4],[222,4]]}}}],["45",{"_index":5426,"t":{"1124":{"position":[[1120,2]]}}}],["4506",{"_index":9836,"t":{"3109":{"position":[[1974,4]]}}}],["4530618",{"_index":6200,"t":{"1298":{"position":[[513,7]]}}}],["4532",{"_index":7822,"t":{"1845":{"position":[[2016,4]]}}}],["457a",{"_index":7817,"t":{"1845":{"position":[[1975,4]]}}}],["458c",{"_index":4217,"t":{"859":{"position":[[3205,4],[3443,4],[3758,4],[3873,4],[6038,4]]},"1603":{"position":[[3205,4],[3443,4],[3758,4],[3873,4],[6038,4]]}}}],["45a49",{"_index":6702,"t":{"1368":{"position":[[625,6]]}}}],["45ab",{"_index":9786,"t":{"3107":{"position":[[1003,4]]}}}],["45e0a707",{"_index":9855,"t":{"3109":{"position":[[2204,8]]}}}],["45f8",{"_index":2371,"t":{"404":{"position":[[472,4]]}}}],["46",{"_index":5427,"t":{"1124":{"position":[[1123,2]]},"1317":{"position":[[7517,2]]},"1794":{"position":[[1278,2]]}}}],["4618",{"_index":4207,"t":{"859":{"position":[[2895,4]]},"1603":{"position":[[2895,4]]},"1845":{"position":[[1922,4],[2699,4]]}}}],["4644",{"_index":5295,"t":{"1114":{"position":[[3633,4]]}}}],["464d",{"_index":4019,"t":{"842":{"position":[[1825,4]]},"1557":{"position":[[1825,4]]}}}],["4679",{"_index":4025,"t":{"842":{"position":[[1920,4]]},"1557":{"position":[[1920,4]]}}}],["467f",{"_index":4212,"t":{"859":{"position":[[3102,4],[3324,4],[3543,4],[3658,4],[5956,4]]},"1603":{"position":[[3102,4],[3324,4],[3543,4],[3658,4],[5956,4]]}}}],["46f9",{"_index":9825,"t":{"3109":{"position":[[1841,4],[2614,4],[2828,4]]}}}],["47",{"_index":5428,"t":{"1124":{"position":[[1126,2]]}}}],["470a",{"_index":3972,"t":{"842":{"position":[[974,4]]},"1557":{"position":[[974,4]]}}}],["4712",{"_index":4036,"t":{"842":{"position":[[2118,4]]},"1557":{"position":[[2118,4]]}}}],["4728",{"_index":7887,"t":{"1849":{"position":[[445,4]]}}}],["4756",{"_index":5023,"t":{"1077":{"position":[[1067,4],[1198,4]]}}}],["4758",{"_index":4228,"t":{"859":{"position":[[4098,4],[4320,4],[4754,4],[4869,4],[6202,4]]},"1603":{"position":[[4098,4],[4320,4],[4754,4],[4869,4],[6202,4]]}}}],["4762",{"_index":6676,"t":{"1366":{"position":[[246,4]]}}}],["476672f1023b4bac8837f95a76881757",{"_index":362,"t":{"27":{"position":[[2066,32]]}}}],["4769",{"_index":5150,"t":{"1102":{"position":[[253,4]]}}}],["47951",{"_index":8498,"t":{"2326":{"position":[[272,5]]}}}],["47a9",{"_index":9807,"t":{"3109":{"position":[[672,4]]}}}],["47b929fd",{"_index":9752,"t":{"3088":{"position":[[764,8]]},"3107":{"position":[[865,8]]}}}],["47ef",{"_index":6628,"t":{"1362":{"position":[[1056,4],[1349,4]]}}}],["48",{"_index":2258,"t":{"379":{"position":[[631,2]]},"1124":{"position":[[1129,2]]},"2895":{"position":[[2724,2]]}}}],["480",{"_index":4684,"t":{"982":{"position":[[507,3]]},"984":{"position":[[243,3]]},"986":{"position":[[254,3]]},"988":{"position":[[254,3]]}}}],["483c",{"_index":7857,"t":{"1847":{"position":[[1328,4]]}}}],["486b",{"_index":7625,"t":{"1791":{"position":[[2265,4],[3070,4]]}}}],["48920d26",{"_index":6527,"t":{"1351":{"position":[[457,8],[983,8],[1693,8],[2507,8]]}}}],["48a8",{"_index":9861,"t":{"3109":{"position":[[2258,4]]}}}],["48ea",{"_index":7856,"t":{"1847":{"position":[[1323,4]]}}}],["48hr",{"_index":9543,"t":{"2895":{"position":[[2790,6]]}}}],["49",{"_index":5429,"t":{"1124":{"position":[[1132,2]]},"1317":{"position":[[1219,2],[1714,4],[2504,2],[2640,2],[2763,2],[2890,2],[3031,2],[3170,2],[3327,2],[3463,2],[3602,2],[3728,2],[3863,2],[3998,2],[4133,2],[4267,2],[4410,2],[4563,2],[4724,2],[4874,2],[4992,2],[5121,2],[5239,2],[6647,2],[8106,2],[8206,2],[8305,2],[8404,2],[8500,2]]}}}],["4920",{"_index":6529,"t":{"1351":{"position":[[471,4],[997,4],[1707,4],[2521,4]]}}}],["4925967416894fd78be6701689059653",{"_index":274,"t":{"25":{"position":[[364,32]]}}}],["4972",{"_index":6756,"t":{"1375":{"position":[[678,4],[1489,4]]},"1377":{"position":[[679,4],[1683,4]]}}}],["49a8",{"_index":7872,"t":{"1847":{"position":[[1512,4]]}}}],["49b8",{"_index":7751,"t":{"1833":{"position":[[880,4]]}}}],["49c9",{"_index":4052,"t":{"842":{"position":[[2442,4]]},"1557":{"position":[[2442,4]]}}}],["49cc3d72fbdf41fe8dc407f57f026dbf",{"_index":286,"t":{"25":{"position":[[640,32]]}}}],["49d4",{"_index":7877,"t":{"1847":{"position":[[1566,4]]}}}],["49f153ffbcef",{"_index":5323,"t":{"1114":{"position":[[4749,12],[4988,12],[5039,12],[5602,12],[6043,12],[6424,12],[6466,12]]}}}],["4:16",{"_index":9186,"t":{"2711":{"position":[[253,4]]},"2856":{"position":[[255,4]]}}}],["4:32",{"_index":9196,"t":{"2711":{"position":[[506,4]]},"2856":{"position":[[508,4]]}}}],["4:8",{"_index":9190,"t":{"2711":{"position":[[363,3]]},"2856":{"position":[[365,3]]}}}],["4_bms_z3",{"_index":9179,"t":{"2709":{"position":[[1932,8]]},"2754":{"position":[[2073,8]]}}}],["4a01",{"_index":9840,"t":{"3109":{"position":[[2011,4]]}}}],["4a581354983f",{"_index":9864,"t":{"3109":{"position":[[2309,12]]}}}],["4a68",{"_index":3989,"t":{"842":{"position":[[1253,4]]},"1557":{"position":[[1253,4]]}}}],["4a6c",{"_index":5016,"t":{"1077":{"position":[[601,4],[733,4]]}}}],["4a8e",{"_index":3999,"t":{"842":{"position":[[1443,4]]},"1557":{"position":[[1443,4]]}}}],["4aa0",{"_index":9717,"t":{"3042":{"position":[[901,4]]},"3046":{"position":[[848,4]]}}}],["4afb",{"_index":4250,"t":{"859":{"position":[[5197,4],[5435,4],[5635,4],[5865,4],[6366,4]]},"1603":{"position":[[5197,4],[5435,4],[5635,4],[5865,4],[6366,4]]}}}],["4b37",{"_index":7882,"t":{"1847":{"position":[[1605,4]]}}}],["4ba0",{"_index":6495,"t":{"1342":{"position":[[519,4]]}}}],["4bb1",{"_index":7862,"t":{"1847":{"position":[[1382,4]]}}}],["4bc3",{"_index":3942,"t":{"838":{"position":[[275,4]]},"1553":{"position":[[275,4]]}}}],["4c",{"_index":9327,"t":{"2733":{"position":[[388,2]]},"2764":{"position":[[1156,2]]},"2772":{"position":[[388,2]]}}}],["4c0a",{"_index":9830,"t":{"3109":{"position":[[1890,4],[2886,4]]}}}],["4c24",{"_index":4041,"t":{"842":{"position":[[2230,4]]},"1557":{"position":[[2230,4]]}}}],["4c28",{"_index":3950,"t":{"840":{"position":[[74,4],[172,4]]},"1555":{"position":[[74,4],[172,4]]}}}],["4c55",{"_index":4194,"t":{"859":{"position":[[2627,4]]},"1603":{"position":[[2627,4]]}}}],["4c5b",{"_index":9801,"t":{"3109":{"position":[[619,4]]}}}],["4c73",{"_index":7832,"t":{"1845":{"position":[[2107,4]]}}}],["4c:16:2x200p",{"_index":9436,"t":{"2854":{"position":[[389,12]]}}}],["4ca1",{"_index":7793,"t":{"1843":{"position":[[998,4]]},"1845":{"position":[[2569,4]]}}}],["4cd2",{"_index":9826,"t":{"3109":{"position":[[1846,4],[2619,4],[2833,4]]}}}],["4ceqrvb5pxnjywdzk9_gtjziz31a7sd4lpiy82o5n9nrydodw",{"_index":7636,"t":{"1791":{"position":[[3640,49]]}}}],["4d06",{"_index":3983,"t":{"842":{"position":[[1160,4]]},"1557":{"position":[[1160,4]]}}}],["4d1f",{"_index":9791,"t":{"3107":{"position":[[1260,4]]}}}],["4d39a5",{"_index":6706,"t":{"1368":{"position":[[695,6],[1315,8]]}}}],["4d3e",{"_index":3431,"t":{"644":{"position":[[303,4]]}}}],["4d45",{"_index":4004,"t":{"842":{"position":[[1539,4]]},"1557":{"position":[[1539,4]]}}}],["4d4a",{"_index":3978,"t":{"842":{"position":[[1067,4]]},"1557":{"position":[[1067,4]]}}}],["4d5d",{"_index":4047,"t":{"842":{"position":[[2336,4]]},"1557":{"position":[[2336,4]]}}}],["4d61",{"_index":9816,"t":{"3109":{"position":[[1718,4]]}}}],["4daa",{"_index":9846,"t":{"3109":{"position":[[2095,4]]}}}],["4db3",{"_index":9850,"t":{"3109":{"position":[[2132,4]]}}}],["4de5",{"_index":6644,"t":{"1364":{"position":[[201,4]]}}}],["4df2",{"_index":9871,"t":{"3109":{"position":[[2382,4]]}}}],["4e1e",{"_index":6650,"t":{"1364":{"position":[[278,4]]}}}],["4e42",{"_index":9769,"t":{"3088":{"position":[[1164,4]]}}}],["4ea22ba875474d039cb57d20b7f710b5",{"_index":358,"t":{"27":{"position":[[1962,32]]}}}],["4ec1",{"_index":9764,"t":{"3088":{"position":[[1031,4]]}}}],["4ee3",{"_index":3620,"t":{"730":{"position":[[2136,4]]},"1491":{"position":[[2136,4]]}}}],["4f16",{"_index":3449,"t":{"644":{"position":[[603,4]]}}}],["4f22",{"_index":9754,"t":{"3088":{"position":[[778,4]]},"3107":{"position":[[879,4]]}}}],["4f33dfa66c14",{"_index":6612,"t":{"1360":{"position":[[2644,12]]}}}],["4f40",{"_index":4030,"t":{"842":{"position":[[2019,4]]},"1557":{"position":[[2019,4]]}}}],["4f5a",{"_index":7805,"t":{"1845":{"position":[[1051,4]]}}}],["4f71",{"_index":7867,"t":{"1847":{"position":[[1421,4]]}}}],["4f9a",{"_index":6802,"t":{"1386":{"position":[[156,4]]}}}],["4fb7",{"_index":9820,"t":{"3109":{"position":[[1762,4]]}}}],["4fc08287809f",{"_index":4236,"t":{"859":{"position":[[4211,12],[4449,12],[4549,12],[4664,12],[6130,12]]},"1603":{"position":[[4211,12],[4449,12],[4549,12],[4664,12],[6130,12]]}}}],["4fd1",{"_index":3994,"t":{"842":{"position":[[1348,4]]},"1557":{"position":[[1348,4]]}}}],["4fd1d060",{"_index":7803,"t":{"1845":{"position":[[1037,8]]}}}],["4fef",{"_index":9759,"t":{"3088":{"position":[[902,4]]},"3107":{"position":[[1131,4]]}}}],["4gib",{"_index":9315,"t":{"2733":{"position":[[58,4]]},"2772":{"position":[[58,4]]},"2854":{"position":[[58,4]]}}}],["4k",{"_index":6967,"t":{"1475":{"position":[[198,4]]},"3299":{"position":[[2000,3]]}}}],["4m",{"_index":6970,"t":{"1475":{"position":[[214,4]]}}}],["4o",{"_index":9159,"t":{"2707":{"position":[[424,2]]},"2752":{"position":[[424,2]]}}}],["4ou",{"_index":9161,"t":{"2707":{"position":[[453,3]]},"2752":{"position":[[453,3]]}}}],["4th",{"_index":7166,"t":{"1676":{"position":[[1016,3]]}}}],["4u",{"_index":9158,"t":{"2707":{"position":[[410,2]]},"2752":{"position":[[410,2]]}}}],["4uo",{"_index":9160,"t":{"2707":{"position":[[438,3]]},"2752":{"position":[[438,3]]}}}],["4v",{"_index":3610,"t":{"730":{"position":[[1367,2]]},"1491":{"position":[[1367,2]]},"1773":{"position":[[1016,2]]},"1808":{"position":[[398,2]]},"2702":{"position":[[351,2]]},"2711":{"position":[[262,2],[273,2],[371,2],[381,2],[515,2],[526,2]]},"2747":{"position":[[351,2]]},"2927":{"position":[[122,2],[149,2],[302,2],[435,2]]},"2929":{"position":[[146,2],[298,2],[493,2]]},"2949":{"position":[[48,2]]}}}],["4v:16",{"_index":9444,"t":{"2856":{"position":[[264,6]]}}}],["4v:16:50",{"_index":9445,"t":{"2856":{"position":[[275,8]]}}}],["4v:32",{"_index":9461,"t":{"2856":{"position":[[517,6]]}}}],["4v:32:100",{"_index":9462,"t":{"2856":{"position":[[528,9]]}}}],["4v:8",{"_index":9451,"t":{"2856":{"position":[[373,5]]}}}],["4v:8:20",{"_index":9452,"t":{"2856":{"position":[[383,7]]}}}],["4vcpu",{"_index":9120,"t":{"2702":{"position":[[378,6]]},"2747":{"position":[[378,6]]}}}],["4x",{"_index":4686,"t":{"982":{"position":[[542,2]]},"995":{"position":[[638,2]]}}}],["5",{"_index":1612,"t":{"242":{"position":[[386,2]]},"321":{"position":[[1164,2]]},"436":{"position":[[1199,2],[1291,1],[1295,2]]},"487":{"position":[[3701,1]]},"609":{"position":[[893,1]]},"650":{"position":[[2371,2]]},"746":{"position":[[55,1]]},"821":{"position":[[2578,2],[3887,2],[5226,2],[5451,2]]},"859":{"position":[[5133,1],[5235,2],[5473,2],[5673,2],[5903,2]]},"1114":{"position":[[351,1],[492,1],[1116,1]]},"1118":{"position":[[1136,1]]},"1124":{"position":[[1065,1]]},"1169":{"position":[[168,2],[313,1]]},"1219":{"position":[[449,2]]},"1234":{"position":[[2163,2]]},"1288":{"position":[[246,1]]},"1317":{"position":[[6753,1]]},"1321":{"position":[[372,2],[1465,1],[2193,1]]},"1360":{"position":[[1254,1],[1271,1]]},"1368":{"position":[[1720,1]]},"1430":{"position":[[225,1],[403,1],[1018,1],[1184,1],[1661,1]]},"1511":{"position":[[2578,2],[3887,2],[5226,2],[5451,2]]},"1571":{"position":[[587,1]]},"1603":{"position":[[5133,1],[5235,2],[5473,2],[5673,2],[5903,2]]},"1764":{"position":[[3318,2]]},"1787":{"position":[[1073,1]]},"2150":{"position":[[414,2]]},"2152":{"position":[[187,2]]},"2312":{"position":[[554,2]]},"2400":{"position":[[38,1]]},"2422":{"position":[[23,1]]},"2709":{"position":[[36,2]]},"2711":{"position":[[94,2],[335,1],[559,1]]},"2713":{"position":[[341,1]]},"2733":{"position":[[187,1]]},"2740":{"position":[[42,2]]},"2754":{"position":[[36,2]]},"2756":{"position":[[548,1],[587,2]]},"2772":{"position":[[187,1]]},"2856":{"position":[[96,2]]},"2929":{"position":[[231,1],[249,1],[539,1],[558,1]]},"3184":{"position":[[2503,3]]},"3188":{"position":[[192,1]]},"3299":{"position":[[5104,3]]},"3316":{"position":[[1635,1]]}}}],["5.0",{"_index":5834,"t":{"1165":{"position":[[1962,3]]}}}],["5.0.0",{"_index":7169,"t":{"1678":{"position":[[153,5],[159,5],[879,6],[2625,6]]},"2312":{"position":[[139,5]]},"2319":{"position":[[65,5]]},"2321":{"position":[[609,5]]}}}],["5.0.0/openstack.yml",{"_index":7174,"t":{"1678":{"position":[[847,19],[1207,19]]}}}],["5.0.0a",{"_index":7167,"t":{"1678":{"position":[[126,6],[1802,8],[1973,8]]}}}],["5.0.0b",{"_index":7168,"t":{"1678":{"position":[[136,6],[143,6]]}}}],["5.0.x",{"_index":8512,"t":{"2332":{"position":[[207,7]]}}}],["5.00g",{"_index":5281,"t":{"1114":{"position":[[2936,5],[3042,5],[5624,6],[5694,6],[5764,6],[5834,6],[5941,6],[6005,6],[6069,6],[6133,6],[6276,6],[6383,6],[6490,6],[6597,6]]}}}],["5.1.0",{"_index":7170,"t":{"1678":{"position":[[168,5],[174,5]]}}}],["5.1.66.255",{"_index":2706,"t":{"485":{"position":[[499,13]]}}}],["5.17",{"_index":9503,"t":{"2872":{"position":[[1344,4]]}}}],["5.18",{"_index":8639,"t":{"2540":{"position":[[203,4]]},"2872":{"position":[[1245,5]]},"2881":{"position":[[70,4]]},"2911":{"position":[[241,6]]}}}],["5.2.0",{"_index":7171,"t":{"1678":{"position":[[183,5],[189,5]]}}}],["5.3.0",{"_index":7172,"t":{"1678":{"position":[[198,5]]}}}],["5.4",{"_index":9489,"t":{"2872":{"position":[[303,3]]}}}],["5.testbed.osism.xyz",{"_index":5391,"t":{"1120":{"position":[[1900,19]]},"1787":{"position":[[1040,19]]}}}],["5.x",{"_index":8513,"t":{"2332":{"position":[[278,6]]}}}],["5/19",{"_index":4915,"t":{"1063":{"position":[[949,6]]}}}],["50",{"_index":2281,"t":{"381":{"position":[[862,3],[905,2],[1033,5]]},"485":{"position":[[828,2]]},"1124":{"position":[[1135,2]]},"1234":{"position":[[2207,3]]},"1728":{"position":[[480,2]]},"1773":{"position":[[1022,3],[1051,3]]},"1808":{"position":[[404,2],[429,2]]},"2702":{"position":[[357,2]]},"2709":{"position":[[47,3]]},"2711":{"position":[[105,3],[279,2],[415,2],[503,2]]},"2713":{"position":[[521,3]]},"2731":{"position":[[644,2],[889,2]]},"2747":{"position":[[357,2]]},"2754":{"position":[[47,3]]},"2770":{"position":[[644,2],[889,2]]},"2856":{"position":[[107,3]]},"2858":{"position":[[518,3]]},"2929":{"position":[[152,2],[172,2],[341,2],[361,2],[460,2],[480,2]]},"3299":{"position":[[2838,3],[4567,3]]},"3357":{"position":[[663,2],[816,2]]}}}],["500",{"_index":8010,"t":{"1957":{"position":[[1948,4]]},"2709":{"position":[[61,4]]},"2711":{"position":[[119,4]]},"2754":{"position":[[61,4]]},"2856":{"position":[[121,4]]}}}],["5000",{"_index":2982,"t":{"557":{"position":[[266,4]]},"669":{"position":[[751,5]]},"3280":{"position":[[874,4]]}}}],["500mb",{"_index":8292,"t":{"2148":{"position":[[210,7]]}}}],["500s_gna",{"_index":9361,"t":{"2766":{"position":[[1018,8]]}}}],["503",{"_index":2509,"t":{"436":{"position":[[763,3]]}}}],["50gb",{"_index":9122,"t":{"2702":{"position":[[434,4]]},"2733":{"position":[[161,4]]},"2747":{"position":[[434,4]]},"2772":{"position":[[161,4]]},"2854":{"position":[[161,4]]}}}],["50n",{"_index":9309,"t":{"2731":{"position":[[669,4]]},"2770":{"position":[[669,4]]}}}],["50n_a2",{"_index":9311,"t":{"2731":{"position":[[705,6]]}}}],["50n_i2",{"_index":9310,"t":{"2731":{"position":[[684,6]]},"2770":{"position":[[684,6]]}}}],["50n_z2",{"_index":9366,"t":{"2770":{"position":[[705,6]]}}}],["50p_i1",{"_index":9317,"t":{"2733":{"position":[[97,6]]},"2772":{"position":[[97,6]]}}}],["51",{"_index":5430,"t":{"1124":{"position":[[1138,2]]},"3357":{"position":[[832,2]]}}}],["51.1kb",{"_index":6235,"t":{"1305":{"position":[[444,6]]}}}],["511680",{"_index":5440,"t":{"1124":{"position":[[1201,6]]}}}],["511865",{"_index":5472,"t":{"1124":{"position":[[1380,6]]}}}],["512",{"_index":3773,"t":{"796":{"position":[[640,3]]},"850":{"position":[[9156,3]]},"1114":{"position":[[3462,3],[3468,3],[3510,3],[3522,3],[3560,3],[3572,3]]},"1379":{"position":[[592,3],[612,3],[845,3],[849,3],[853,3]]},"1484":{"position":[[9156,3]]},"1533":{"position":[[640,3]]}}}],["5149",{"_index":7871,"t":{"1847":{"position":[[1507,4]]}}}],["515581",{"_index":5439,"t":{"1124":{"position":[[1178,6]]}}}],["516078",{"_index":5471,"t":{"1124":{"position":[[1357,6]]}}}],["51e1",{"_index":5294,"t":{"1114":{"position":[[3628,4]]}}}],["52",{"_index":5431,"t":{"1124":{"position":[[1141,2]]},"3014":{"position":[[54,2]]}}}],["5212",{"_index":5321,"t":{"1114":{"position":[[4739,4],[4978,4],[5029,4],[5592,4],[6033,4],[6414,4],[6456,4]]}}}],["522e",{"_index":5265,"t":{"1114":{"position":[[1164,4],[1535,4],[1741,4],[2291,4],[2534,4],[2902,4],[3008,4]]}}}],["5258",{"_index":9785,"t":{"3107":{"position":[[998,4]]}}}],["525d",{"_index":5270,"t":{"1114":{"position":[[1249,4],[1384,4],[1435,4],[1483,4],[2148,4],[2401,4],[2644,4],[2686,4],[2857,4]]}}}],["5296",{"_index":7861,"t":{"1847":{"position":[[1377,4]]}}}],["52dd",{"_index":5275,"t":{"1114":{"position":[[1316,4],[1590,4],[1641,4],[1689,4],[2218,4],[2466,4],[2752,4],[2794,4],[2963,4]]}}}],["53",{"_index":5432,"t":{"1124":{"position":[[1144,2]]}}}],["5350",{"_index":5235,"t":{"1112":{"position":[[4303,4],[4427,4],[4478,4],[5088,4],[5262,4],[5475,4],[5517,4]]}}}],["5358",{"_index":9758,"t":{"3088":{"position":[[897,4]]},"3107":{"position":[[1126,4]]}}}],["536870912",{"_index":6783,"t":{"1379":{"position":[[686,9]]}}}],["53ee",{"_index":3993,"t":{"842":{"position":[[1343,4]]},"1557":{"position":[[1343,4]]}}}],["54",{"_index":5433,"t":{"1124":{"position":[[1147,2]]},"1368":{"position":[[1831,3]]}}}],["5411763",{"_index":6205,"t":{"1298":{"position":[[676,7]]}}}],["5428",{"_index":9835,"t":{"3109":{"position":[[1969,4]]}}}],["54t",{"_index":4719,"t":{"993":{"position":[[20,3],[54,3]]}}}],["55",{"_index":5434,"t":{"1124":{"position":[[1150,2]]}}}],["559e5176695c",{"_index":6574,"t":{"1360":{"position":[[1175,12]]}}}],["56",{"_index":5435,"t":{"1124":{"position":[[1153,2]]}}}],["561f8f76",{"_index":3970,"t":{"842":{"position":[[960,8]]},"1557":{"position":[[960,8]]}}}],["5626",{"_index":5336,"t":{"1114":{"position":[[4910,4],[5296,4],[5347,4],[5802,4],[5905,4],[6200,4],[6242,4]]}}}],["5672",{"_index":5053,"t":{"1084":{"position":[[757,10]]}}}],["56f7b5bc",{"_index":5334,"t":{"1114":{"position":[[4896,8],[5282,8],[5333,8],[5788,8],[5891,8],[6186,8],[6228,8]]}}}],["56x",{"_index":4728,"t":{"995":{"position":[[777,3]]}}}],["57",{"_index":5436,"t":{"1124":{"position":[[1156,2]]}}}],["5752b6701026478f9cac122fc54eb9cb",{"_index":3850,"t":{"819":{"position":[[4955,32]]},"821":{"position":[[4866,32],[4967,33]]},"1509":{"position":[[4955,32]]},"1511":{"position":[[4866,32],[4967,33]]}}}],["5764",{"_index":5326,"t":{"1114":{"position":[[4796,4],[5084,4],[5135,4],[5662,4],[5969,4],[6307,4],[6349,4]]}}}],["577",{"_index":6395,"t":{"1321":{"position":[[282,3],[939,3]]}}}],["5775",{"_index":8281,"t":{"2142":{"position":[[393,4]]}}}],["57b1dfc8639f",{"_index":9833,"t":{"3109":{"position":[[1941,12],[2896,12]]}}}],["58",{"_index":5437,"t":{"1124":{"position":[[1159,2]]}}}],["5815",{"_index":5240,"t":{"1112":{"position":[[4359,4],[4533,4],[4584,4],[5158,4],[5327,4],[5583,4],[5625,4]]}}}],["5823",{"_index":5331,"t":{"1114":{"position":[[4853,4],[5190,4],[5241,4],[5732,4],[6097,4],[6521,4],[6563,4]]}}}],["58732",{"_index":6446,"t":{"1321":{"position":[[2005,6]]}}}],["58a40b681d11",{"_index":4230,"t":{"859":{"position":[[4108,12],[4330,12],[4764,12],[4879,12],[6212,12]]},"1603":{"position":[[4108,12],[4330,12],[4764,12],[4879,12],[6212,12]]}}}],["59",{"_index":5438,"t":{"1124":{"position":[[1162,2]]}}}],["5:20.10.13~3",{"_index":7490,"t":{"1764":{"position":[[3062,12]]}}}],["5:20.10.14~3",{"_index":7489,"t":{"1764":{"position":[[2951,12]]}}}],["5:20.10.15~3",{"_index":7488,"t":{"1764":{"position":[[2840,12]]}}}],["5:20.10.16~3",{"_index":7487,"t":{"1764":{"position":[[2729,12]]}}}],["5:20.10.17~3",{"_index":7486,"t":{"1764":{"position":[[2618,12]]}}}],["5:20.10.18~3",{"_index":7485,"t":{"1764":{"position":[[2507,12]]}}}],["5:20.10.19~3",{"_index":7484,"t":{"1764":{"position":[[2396,12]]}}}],["5:20.10.20~3",{"_index":7483,"t":{"1764":{"position":[[2285,12]]}}}],["5:20.10.21~3",{"_index":7482,"t":{"1764":{"position":[[2174,12]]}}}],["5:20.10.22~3",{"_index":7481,"t":{"1764":{"position":[[2063,12]]}}}],["5:20.10.23~3",{"_index":7480,"t":{"1764":{"position":[[1952,12]]}}}],["5:20.10.24",{"_index":7458,"t":{"1764":{"position":[[128,12]]}}}],["5:20.10.24~3",{"_index":7478,"t":{"1764":{"position":[[1841,12]]}}}],["5:23.0.0",{"_index":7477,"t":{"1764":{"position":[[1728,8]]}}}],["5:23.0.1",{"_index":7476,"t":{"1764":{"position":[[1615,8]]}}}],["5:23.0.2",{"_index":7475,"t":{"1764":{"position":[[1502,8]]}}}],["5:23.0.3",{"_index":7474,"t":{"1764":{"position":[[1389,8]]}}}],["5:23.0.4",{"_index":7473,"t":{"1764":{"position":[[1276,8]]}}}],["5:23.0.5",{"_index":7472,"t":{"1764":{"position":[[1163,8]]}}}],["5:23.0.6",{"_index":7471,"t":{"1764":{"position":[[1050,8]]}}}],["5:24.0.0",{"_index":7470,"t":{"1764":{"position":[[937,8]]}}}],["5:24.0.1",{"_index":7469,"t":{"1764":{"position":[[824,8]]}}}],["5:24.0.2",{"_index":7468,"t":{"1764":{"position":[[711,8]]}}}],["5:24.0.3",{"_index":7467,"t":{"1764":{"position":[[598,8]]}}}],["5:24.0.4",{"_index":7466,"t":{"1764":{"position":[[485,8]]}}}],["5:24.0.5",{"_index":7465,"t":{"1764":{"position":[[372,8]]}}}],["5:24.0.6",{"_index":7461,"t":{"1764":{"position":[[259,8]]}}}],["5a06",{"_index":4243,"t":{"859":{"position":[[5028,4],[5311,4],[5530,4],[5745,4],[6279,4]]},"1603":{"position":[[5028,4],[5311,4],[5530,4],[5745,4],[6279,4]]}}}],["5a19",{"_index":2370,"t":{"404":{"position":[[467,4]]}}}],["5b81",{"_index":4035,"t":{"842":{"position":[[2113,4]]},"1557":{"position":[[2113,4]]}}}],["5c6d4d7183834eafbc20108ad647a9c0",{"_index":376,"t":{"27":{"position":[[2794,32]]}}}],["5d09",{"_index":7792,"t":{"1843":{"position":[[993,4]]},"1845":{"position":[[2564,4]]}}}],["5d91",{"_index":7837,"t":{"1845":{"position":[[2161,4]]}}}],["5f22e42",{"_index":9828,"t":{"3109":{"position":[[1876,8],[2872,8]]}}}],["5fde",{"_index":6634,"t":{"1362":{"position":[[2002,4],[2369,4]]}}}],["5ftj",{"_index":3015,"t":{"590":{"position":[[1580,6]]}}}],["5g",{"_index":5301,"t":{"1114":{"position":[[3724,2],[3781,2],[3838,2],[3895,2]]}}}],["5gb",{"_index":9321,"t":{"2733":{"position":[[241,3]]},"2772":{"position":[[241,3]]},"2854":{"position":[[241,3]]}}}],["5gi",{"_index":3397,"t":{"641":{"position":[[182,5]]},"644":{"position":[[422,3],[518,3]]}}}],["5m",{"_index":5880,"t":{"1167":{"position":[[1770,4],[3036,2]]},"2150":{"position":[[314,2]]}}}],["5m11",{"_index":3446,"t":{"644":{"position":[[541,5]]}}}],["5n",{"_index":9207,"t":{"2713":{"position":[[398,2]]},"2756":{"position":[[508,2]]}}}],["5th",{"_index":1604,"t":{"242":{"position":[[12,3],[256,3]]}}}],["5x",{"_index":9128,"t":{"2705":{"position":[[412,2]]},"2750":{"position":[[412,2]]},"2840":{"position":[[320,2]]}}}],["5x/core",{"_index":9143,"t":{"2705":{"position":[[1571,7]]},"2750":{"position":[[1873,7]]},"2840":{"position":[[1219,7]]}}}],["6",{"_index":420,"t":{"37":{"position":[[271,1]]},"40":{"position":[[269,1]]},"321":{"position":[[1227,2]]},"633":{"position":[[727,1]]},"650":{"position":[[2378,3]]},"859":{"position":[[2336,1],[2486,1]]},"861":{"position":[[264,1]]},"909":{"position":[[907,1],[2712,1],[2732,1]]},"911":{"position":[[658,2]]},"913":{"position":[[2318,1],[2402,1]]},"1031":{"position":[[277,1]]},"1067":{"position":[[278,1]]},"1112":{"position":[[1906,1],[1983,1],[2225,1],[2302,1],[2599,1],[2647,1],[2988,1],[3065,1],[3180,1],[3257,1]]},"1124":{"position":[[1067,1]]},"1184":{"position":[[1580,1]]},"1360":{"position":[[1382,1],[1399,1],[1507,1],[1524,1],[1787,1],[1802,1],[1932,1],[1947,1],[2069,1],[2084,1],[2202,1],[2217,1],[2331,1],[2346,1]]},"1368":{"position":[[1948,1],[2396,1]]},"1603":{"position":[[2336,1],[2486,1]]},"1605":{"position":[[264,1]]},"1631":{"position":[[907,1],[2712,1],[2732,1]]},"1633":{"position":[[658,2]]},"1635":{"position":[[2318,1],[2402,1]]},"1674":{"position":[[38,1]]},"1775":{"position":[[298,1]]},"1787":{"position":[[1135,1]]},"2356":{"position":[[907,1],[2712,1],[2732,1]]},"2358":{"position":[[658,2]]},"2360":{"position":[[2318,1],[2402,1]]},"2454":{"position":[[12,1]]},"2456":{"position":[[38,1],[120,1]]},"2491":{"position":[[46,1]]},"2499":{"position":[[102,2]]},"2522":{"position":[[753,1]]},"2795":{"position":[[1912,1]]},"2809":{"position":[[1017,1]]},"3014":{"position":[[113,1]]}}}],["6+n",{"_index":4423,"t":{"909":{"position":[[2423,3]]},"1631":{"position":[[2423,3]]},"2356":{"position":[[2423,3]]}}}],["6.0.0",{"_index":5035,"t":{"1080":{"position":[[1286,6]]},"1825":{"position":[[1449,6]]},"2403":{"position":[[52,6]]},"2405":{"position":[[67,5]]},"2415":{"position":[[65,5]]}}}],["6.0.0b",{"_index":7158,"t":{"1676":{"position":[[455,6]]}}}],["6.1.0",{"_index":5061,"t":{"1089":{"position":[[12,6]]},"2420":{"position":[[301,7]]}}}],["6.3.0",{"_index":4323,"t":{"901":{"position":[[595,5]]},"1623":{"position":[[595,5]]},"2348":{"position":[[595,5]]}}}],["6.4.0",{"_index":4324,"t":{"901":{"position":[[605,5]]},"1623":{"position":[[605,5]]},"2348":{"position":[[605,5]]}}}],["6.testbed.osism.xyz",{"_index":7587,"t":{"1787":{"position":[[1102,19]]}}}],["6/19",{"_index":4917,"t":{"1063":{"position":[[976,6]]}}}],["60",{"_index":5452,"t":{"1124":{"position":[[1284,2]]},"1321":{"position":[[310,2],[319,2],[967,2],[976,2]]},"1477":{"position":[[237,3]]}}}],["600",{"_index":3118,"t":{"604":{"position":[[3121,4]]},"662":{"position":[[5,5]]},"857":{"position":[[384,3]]},"1601":{"position":[[384,3]]}}}],["602778bad3d3470cbe58c4f7611e8eb7",{"_index":309,"t":{"27":{"position":[[815,32]]}}}],["602832daf237",{"_index":6598,"t":{"1360":{"position":[[2112,12]]}}}],["604379.969424455",{"_index":2650,"t":{"472":{"position":[[2459,17]]}}}],["61",{"_index":5453,"t":{"1124":{"position":[[1287,2]]}}}],["62",{"_index":5454,"t":{"1124":{"position":[[1290,2]]},"1368":{"position":[[2510,3]]}}}],["62.138.222.111",{"_index":3512,"t":{"660":{"position":[[151,18]]}}}],["62.138.222.222",{"_index":3513,"t":{"660":{"position":[[170,17]]}}}],["624b",{"_index":6227,"t":{"1305":{"position":[[288,4]]}}}],["6292",{"_index":3555,"t":{"662":{"position":[[511,5]]}}}],["62cdj",{"_index":3016,"t":{"590":{"position":[[1613,6]]}}}],["62d6ad2a",{"_index":4002,"t":{"842":{"position":[[1525,8]]},"1557":{"position":[[1525,8]]}}}],["62e2",{"_index":4024,"t":{"842":{"position":[[1915,4]]},"1557":{"position":[[1915,4]]}}}],["63",{"_index":5455,"t":{"1124":{"position":[[1293,2]]}}}],["6379/tcp",{"_index":7342,"t":{"1731":{"position":[[2845,8]]}}}],["63b8fea6",{"_index":4007,"t":{"842":{"position":[[1621,8]]},"1557":{"position":[[1621,8]]}}}],["64",{"_index":3639,"t":{"734":{"position":[[224,2]]},"982":{"position":[[830,2]]},"990":{"position":[[360,2]]},"1110":{"position":[[819,2]]},"1124":{"position":[[1296,2]]},"1252":{"position":[[534,2]]},"1495":{"position":[[224,2]]},"2711":{"position":[[62,4]]},"2713":{"position":[[40,2]]},"2725":{"position":[[221,4],[341,3],[356,3]]},"2733":{"position":[[53,4],[271,2],[351,2]]},"2764":{"position":[[273,2],[295,2],[321,2],[562,3],[577,3]]},"2766":{"position":[[1015,2]]},"2772":{"position":[[53,4],[271,2],[351,2]]},"2850":{"position":[[221,4],[250,3],[265,3]]},"2854":{"position":[[53,4],[352,2]]},"2856":{"position":[[64,4]]},"2858":{"position":[[40,2]]},"2925":{"position":[[66,4]]}}}],["6443",{"_index":9960,"t":{"3236":{"position":[[533,5]]}}}],["645538bf67664cfeaed32476d58f95fb",{"_index":3845,"t":{"819":{"position":[[4367,32]]},"1509":{"position":[[4367,32]]}}}],["64_ib",{"_index":9177,"t":{"2709":{"position":[[1801,5]]},"2733":{"position":[[283,5]]},"2754":{"position":[[1942,5]]},"2772":{"position":[[283,5]]}}}],["64cb",{"_index":3430,"t":{"644":{"position":[[298,4]]}}}],["64gb",{"_index":407,"t":{"37":{"position":[[126,4]]},"40":{"position":[[124,4]]}}}],["64gib",{"_index":9200,"t":{"2711":{"position":[[893,5]]},"2733":{"position":[[311,5]]},"2772":{"position":[[311,5]]},"2854":{"position":[[311,5]]},"2856":{"position":[[871,5]]},"2933":{"position":[[296,5]]}}}],["64k",{"_index":6968,"t":{"1475":{"position":[[203,5]]}}}],["64m",{"_index":6972,"t":{"1475":{"position":[[225,5]]}}}],["65",{"_index":5456,"t":{"1124":{"position":[[1299,2]]}}}],["6510",{"_index":6339,"t":{"1317":{"position":[[5673,4]]}}}],["652e",{"_index":9790,"t":{"3107":{"position":[[1255,4]]}}}],["652e3a6c",{"_index":3618,"t":{"730":{"position":[[2122,8]]},"1491":{"position":[[2122,8]]}}}],["654.4mb",{"_index":6224,"t":{"1305":{"position":[[212,7]]}}}],["65401",{"_index":5137,"t":{"1098":{"position":[[809,5]]}}}],["65402",{"_index":5138,"t":{"1098":{"position":[[852,5]]}}}],["65ac",{"_index":9866,"t":{"3109":{"position":[[2337,4]]}}}],["66",{"_index":5457,"t":{"1124":{"position":[[1302,2]]}}}],["66595ea9fb21",{"_index":9719,"t":{"3042":{"position":[[911,12]]},"3046":{"position":[[858,12]]}}}],["666097e396fd4f9392d6aa55c76d8267",{"_index":3853,"t":{"819":{"position":[[5552,32]]},"1509":{"position":[[5552,32]]}}}],["6674",{"_index":4029,"t":{"842":{"position":[[2014,4]]},"1557":{"position":[[2014,4]]}}}],["667649d6",{"_index":4198,"t":{"859":{"position":[[2747,8]]},"1603":{"position":[[2747,8]]}}}],["669c",{"_index":5149,"t":{"1102":{"position":[[248,4]]}}}],["67",{"_index":5458,"t":{"1124":{"position":[[1305,2]]}}}],["68",{"_index":5459,"t":{"1124":{"position":[[1308,2]]},"1317":{"position":[[1229,2],[1895,3],[6748,2]]}}}],["69",{"_index":5460,"t":{"1124":{"position":[[1311,2]]},"1317":{"position":[[1182,2],[1450,2],[1590,2]]}}}],["690dee14",{"_index":4017,"t":{"842":{"position":[[1811,8]]},"1557":{"position":[[1811,8]]}}}],["6a",{"_index":326,"t":{"27":{"position":[[1213,2]]}}}],["6ac9a526",{"_index":5021,"t":{"1077":{"position":[[1053,8],[1184,8]]}}}],["6ace51bb",{"_index":9784,"t":{"3107":{"position":[[989,8]]}}}],["6c47b9d8537b",{"_index":7859,"t":{"1847":{"position":[[1338,12]]}}}],["6c6eba43f616bc6b.yaml",{"_index":7189,"t":{"1684":{"position":[[409,21]]}}}],["6d15",{"_index":6724,"t":{"1368":{"position":[[1567,4],[1630,4],[1959,4],[1964,5]]}}}],["6d159e",{"_index":6727,"t":{"1368":{"position":[[1635,8]]}}}],["6d1986e4",{"_index":3976,"t":{"842":{"position":[[1053,8]]},"1557":{"position":[[1053,8]]}}}],["6d57f39aacbe485d87733865b1e79d03",{"_index":3865,"t":{"819":{"position":[[7389,32]]},"821":{"position":[[2220,32],[2320,33]]},"1509":{"position":[[7389,32]]},"1511":{"position":[[2220,32],[2320,33]]}}}],["6ee4b373cb6d42a5bb59d5080987b70d",{"_index":355,"t":{"27":{"position":[[1880,32]]}}}],["6ef6",{"_index":7797,"t":{"1843":{"position":[[1064,4]]},"1845":{"position":[[2778,4]]}}}],["6f89488ef3a4",{"_index":7829,"t":{"1845":{"position":[[2076,12]]}}}],["6m12",{"_index":3435,"t":{"644":{"position":[[349,5],[445,5],[649,5]]}}}],["7",{"_index":403,"t":{"37":{"position":[[109,1]]},"40":{"position":[[107,1]]},"321":{"position":[[1296,2]]},"909":{"position":[[1395,2]]},"1124":{"position":[[1069,1]]},"1184":{"position":[[1884,2]]},"1246":{"position":[[17,2]]},"1337":{"position":[[211,1]]},"1360":{"position":[[2455,1],[2470,1],[2596,1],[2611,1],[2704,1],[2719,1],[2834,1],[2849,1],[2942,1],[2957,1],[3052,1],[3067,1]]},"1368":{"position":[[2627,1]]},"1430":{"position":[[334,1],[1127,1],[1770,1],[1886,1]]},"1576":{"position":[[887,2]]},"1631":{"position":[[1395,2]]},"1787":{"position":[[1197,1]]},"2356":{"position":[[1395,2]]}}}],["7,2",{"_index":9585,"t":{"2923":{"position":[[395,3]]}}}],["7.0",{"_index":7719,"t":{"1829":{"position":[[13,3]]}}}],["7.0.0",{"_index":4998,"t":{"1069":{"position":[[166,8]]},"1080":{"position":[[690,5],[704,5]]},"1286":{"position":[[1135,6],[1401,5],[1415,5]]},"1825":{"position":[[853,5],[867,5]]},"2459":{"position":[[52,5]]},"2478":{"position":[[65,5]]},"2499":{"position":[[60,5]]}}}],["7.0.2",{"_index":5026,"t":{"1080":{"position":[[169,5]]},"1825":{"position":[[169,5]]}}}],["7.0.3",{"_index":6161,"t":{"1290":{"position":[[23,5]]},"1292":{"position":[[23,5]]},"2093":{"position":[[516,5]]}}}],["7.0.4",{"_index":4904,"t":{"1063":{"position":[[674,8],[1329,8]]},"1071":{"position":[[899,5]]}}}],["7.0.5",{"_index":4848,"t":{"1055":{"position":[[42,6]]},"1080":{"position":[[178,6],[215,5],[1864,6]]},"1825":{"position":[[178,6],[297,5],[2036,6],[2338,5]]}}}],["7.0.6",{"_index":5753,"t":{"1161":{"position":[[1300,6]]},"1298":{"position":[[131,6]]},"1356":{"position":[[62,6]]}}}],["7.2h",{"_index":9145,"t":{"2705":{"position":[[1708,4]]},"2750":{"position":[[2010,4]]},"2840":{"position":[[1356,4]]}}}],["7.2h/month",{"_index":9131,"t":{"2705":{"position":[[611,12]]},"2750":{"position":[[611,12]]},"2840":{"position":[[506,12]]}}}],["7.68",{"_index":4700,"t":{"984":{"position":[[512,4]]}}}],["7.8kb",{"_index":6231,"t":{"1305":{"position":[[359,5]]}}}],["7.testbed.osism.xyz",{"_index":7589,"t":{"1787":{"position":[[1164,19]]}}}],["7/19",{"_index":4920,"t":{"1063":{"position":[[1014,6]]}}}],["70",{"_index":5461,"t":{"1124":{"position":[[1314,2]]},"1587":{"position":[[767,2]]}}}],["7000",{"_index":5343,"t":{"1116":{"position":[[330,4]]},"1118":{"position":[[1099,7]]}}}],["709b8c6c",{"_index":5293,"t":{"1114":{"position":[[3619,8]]}}}],["71",{"_index":5462,"t":{"1124":{"position":[[1317,2]]}}}],["718964b4b87446688ac04b151519fb51",{"_index":394,"t":{"32":{"position":[[74,32]]}}}],["718aecaddde1",{"_index":6619,"t":{"1360":{"position":[[2862,12]]}}}],["718b",{"_index":7876,"t":{"1847":{"position":[[1561,4]]}}}],["71902b03",{"_index":7855,"t":{"1847":{"position":[[1314,8]]}}}],["71a8b930",{"_index":7847,"t":{"1847":{"position":[[363,8],[715,8],[1275,8],[1459,8]]},"1849":{"position":[[69,8]]}}}],["72",{"_index":5463,"t":{"1124":{"position":[[1320,2]]}}}],["73",{"_index":5464,"t":{"1124":{"position":[[1323,2]]}}}],["734f9b6a",{"_index":3441,"t":{"644":{"position":[[481,8]]}}}],["73967e73",{"_index":7809,"t":{"1845":{"position":[[1153,8],[2633,8]]}}}],["73edb86b",{"_index":9848,"t":{"3109":{"position":[[2118,8]]}}}],["74",{"_index":5465,"t":{"1124":{"position":[[1326,2]]}}}],["7413",{"_index":9815,"t":{"3109":{"position":[[1713,4]]}}}],["74f9bddc",{"_index":3981,"t":{"842":{"position":[[1146,8]]},"1557":{"position":[[1146,8]]}}}],["75",{"_index":5466,"t":{"1124":{"position":[[1329,2]]},"3357":{"position":[[706,2],[838,2]]}}}],["7514191fecc",{"_index":4196,"t":{"859":{"position":[[2637,12]]},"1603":{"position":[[2637,12]]}}}],["75279777029847ab9b399390c0dd6042",{"_index":366,"t":{"27":{"position":[[2274,32]]}}}],["758ee36fb132",{"_index":6630,"t":{"1362":{"position":[[1066,12],[1359,12]]}}}],["75960289",{"_index":5268,"t":{"1114":{"position":[[1235,8],[1370,8],[1421,8],[1469,8],[2134,8],[2387,8],[2630,8],[2672,8],[2843,8]]}}}],["76",{"_index":5467,"t":{"1124":{"position":[[1332,2]]},"3357":{"position":[[853,2]]}}}],["7636",{"_index":1939,"t":{"298":{"position":[[569,5]]},"306":{"position":[[156,5]]}}}],["77",{"_index":5468,"t":{"1124":{"position":[[1335,2]]}}}],["7725",{"_index":3988,"t":{"842":{"position":[[1248,4]]},"1557":{"position":[[1248,4]]}}}],["78",{"_index":5469,"t":{"1124":{"position":[[1338,2]]}}}],["79",{"_index":5470,"t":{"1124":{"position":[[1341,2]]}}}],["792e9b3665d8",{"_index":3451,"t":{"644":{"position":[[613,12]]}}}],["79eb6088a9a1",{"_index":7819,"t":{"1845":{"position":[[1985,12]]}}}],["7c",{"_index":7295,"t":{"1728":{"position":[[474,2]]}}}],["7c8bd5a49fdd",{"_index":6758,"t":{"1375":{"position":[[688,12],[1499,12]]},"1377":{"position":[[689,12],[1693,12]]}}}],["7cc4",{"_index":5234,"t":{"1112":{"position":[[4298,4],[4422,4],[4473,4],[5083,4],[5257,4],[5470,4],[5512,4]]}}}],["7d4f64d10909",{"_index":9756,"t":{"3088":{"position":[[853,12]]},"3107":{"position":[[954,12]]}}}],["7d7b",{"_index":4008,"t":{"842":{"position":[[1630,4]]},"1557":{"position":[[1630,4]]}}}],["7e18881932f749baa7d547ebd407b8d8",{"_index":378,"t":{"27":{"position":[[2898,32]]}}}],["7fa7e7c88700",{"_index":6402,"t":{"1321":{"position":[[451,12],[615,12]]}}}],["7fa7eb48f700",{"_index":6431,"t":{"1321":{"position":[[1303,12]]}}}],["7fdbc9728700",{"_index":6419,"t":{"1321":{"position":[[1071,12]]}}}],["7ff828230b8e",{"_index":7869,"t":{"1847":{"position":[[1431,12]]}}}],["8",{"_index":2018,"t":{"321":{"position":[[1377,2]]},"635":{"position":[[3284,2]]},"730":{"position":[[1317,1]]},"796":{"position":[[629,1]]},"798":{"position":[[623,1]]},"821":{"position":[[5558,2]]},"850":{"position":[[9145,1]]},"857":{"position":[[174,1]]},"859":{"position":[[2454,1],[2570,1]]},"861":{"position":[[295,1]]},"903":{"position":[[1162,1]]},"911":{"position":[[452,2],[503,1]]},"1122":{"position":[[784,1]]},"1124":{"position":[[1071,1]]},"1234":{"position":[[573,1],[2857,2]]},"1317":{"position":[[5894,1]]},"1484":{"position":[[9145,1]]},"1491":{"position":[[1317,1]]},"1511":{"position":[[5558,2]]},"1533":{"position":[[629,1]]},"1535":{"position":[[623,1]]},"1562":{"position":[[388,1]]},"1571":{"position":[[141,1],[1262,1]]},"1578":{"position":[[45,1]]},"1601":{"position":[[174,1]]},"1603":{"position":[[2454,1],[2570,1]]},"1605":{"position":[[295,1]]},"1625":{"position":[[1162,1]]},"1633":{"position":[[452,2],[503,1]]},"1678":{"position":[[2284,2]]},"1787":{"position":[[1259,1]]},"1805":{"position":[[302,1],[417,2],[442,2],[459,2],[485,2],[511,2],[536,2],[558,2]]},"1845":{"position":[[246,1]]},"1913":{"position":[[1479,5]]},"2029":{"position":[[1479,5]]},"2350":{"position":[[1162,1]]},"2358":{"position":[[452,2],[503,1]]},"2705":{"position":[[830,2]]},"2711":{"position":[[238,2],[248,1],[374,2],[384,1],[462,2],[472,1]]},"2733":{"position":[[104,1]]},"2750":{"position":[[845,2]]},"2756":{"position":[[470,1]]},"2772":{"position":[[104,1]]},"2840":{"position":[[735,2]]},"2854":{"position":[[104,1]]},"2890":{"position":[[118,3]]},"2927":{"position":[[100,1],[116,1],[195,1],[305,1],[321,1],[333,1],[386,1],[402,1]]},"2929":{"position":[[112,1],[131,1],[195,1],[301,1],[320,1],[344,1],[420,1],[439,1]]},"3128":{"position":[[488,1]]},"3171":{"position":[[184,2]]}}}],["8.8.4.4",{"_index":5106,"t":{"1091":{"position":[[322,9]]}}}],["8.8.8.8",{"_index":4991,"t":{"1067":{"position":[[5645,7]]},"1091":{"position":[[311,10]]},"1585":{"position":[[3404,7]]},"1808":{"position":[[312,11]]}}}],["8.testbed.osism.xyz",{"_index":7591,"t":{"1787":{"position":[[1226,19]]}}}],["8/19",{"_index":4923,"t":{"1063":{"position":[[1056,6]]}}}],["8/20",{"_index":4885,"t":{"1061":{"position":[[472,6]]}}}],["80",{"_index":2261,"t":{"379":{"position":[[741,2]]},"646":{"position":[[556,3]]},"911":{"position":[[700,3]]},"1161":{"position":[[1864,5]]},"1333":{"position":[[225,2]]},"1339":{"position":[[179,2]]},"1633":{"position":[[700,3]]},"1728":{"position":[[492,2]]},"1743":{"position":[[273,2],[1389,2]]},"1794":{"position":[[1271,2]]},"1863":{"position":[[802,2]]},"1925":{"position":[[802,2]]},"2358":{"position":[[700,3]]}}}],["80/tcp",{"_index":3418,"t":{"641":{"position":[[1716,6]]}}}],["8000/tcp",{"_index":7324,"t":{"1731":{"position":[[1507,9],[1651,8]]}}}],["805460b998ce",{"_index":4027,"t":{"842":{"position":[[1930,12]]},"1557":{"position":[[1930,12]]}}}],["8080",{"_index":3421,"t":{"641":{"position":[[1845,4],[1880,4]]}}}],["8080/tcp",{"_index":6616,"t":{"1360":{"position":[[2745,9]]}}}],["8080:80",{"_index":2498,"t":{"434":{"position":[[163,7]]},"641":{"position":[[1803,7]]}}}],["8086",{"_index":4544,"t":{"928":{"position":[[148,4],[202,7]]},"1650":{"position":[[148,4],[202,7]]},"2375":{"position":[[148,4],[202,7]]}}}],["80:30799/tcp,443:32482/tcp",{"_index":2420,"t":{"413":{"position":[[314,26]]},"442":{"position":[[233,26]]}}}],["80af",{"_index":9827,"t":{"3109":{"position":[[1851,4],[2624,4],[2838,4]]}}}],["81.163.194.219",{"_index":2419,"t":{"413":{"position":[[299,14]]},"442":{"position":[[218,14]]}}}],["8132",{"_index":7888,"t":{"1849":{"position":[[450,4]]}}}],["8140",{"_index":5359,"t":{"1118":{"position":[[928,5]]}}}],["8155",{"_index":6651,"t":{"1364":{"position":[[283,4]]}}}],["8186",{"_index":4539,"t":{"926":{"position":[[538,7]]},"1648":{"position":[[538,7]]},"2373":{"position":[[538,7]]}}}],["8187",{"_index":6635,"t":{"1362":{"position":[[2007,4],[2374,4]]}}}],["8192",{"_index":3917,"t":{"821":{"position":[[5292,5]]},"1031":{"position":[[608,4]]},"1511":{"position":[[5292,5]]}}}],["822665f46070",{"_index":9761,"t":{"3088":{"position":[[982,12]]},"3107":{"position":[[1211,12]]}}}],["8268b05ef24b41d8806c0fe417576610",{"_index":3986,"t":{"842":{"position":[[1185,32],[1278,32],[1468,32],[1564,32],[1945,32]]},"1557":{"position":[[1185,32],[1278,32],[1468,32],[1564,32],[1945,32]]}}}],["82b0",{"_index":5335,"t":{"1114":{"position":[[4905,4],[5291,4],[5342,4],[5797,4],[5900,4],[6195,4],[6237,4]]}}}],["82b7",{"_index":9851,"t":{"3109":{"position":[[2137,4]]}}}],["8381",{"_index":4062,"t":{"842":{"position":[[3016,4]]},"1557":{"position":[[3016,4]]}}}],["84a4",{"_index":7878,"t":{"1847":{"position":[[1571,4]]}}}],["84a5",{"_index":6804,"t":{"1386":{"position":[[166,4]]}}}],["84d52cf6c60b",{"_index":3996,"t":{"842":{"position":[[1358,12]]},"1557":{"position":[[1358,12]]}}}],["84dd86f598",{"_index":3020,"t":{"590":{"position":[[1744,10],[1788,10]]}}}],["84ea",{"_index":6757,"t":{"1375":{"position":[[683,4],[1494,4]]},"1377":{"position":[[684,4],[1688,4]]}}}],["8518d3a2",{"_index":5324,"t":{"1114":{"position":[[4782,8],[5070,8],[5121,8],[5648,8],[5955,8],[6293,8],[6335,8]]}}}],["854e7c55",{"_index":4023,"t":{"842":{"position":[[1906,8]]},"1557":{"position":[[1906,8]]}}}],["8593",{"_index":3439,"t":{"644":{"position":[[404,4]]}}}],["8601",{"_index":1358,"t":{"187":{"position":[[629,4]]}}}],["8651",{"_index":9831,"t":{"3109":{"position":[[1895,4],[2891,4]]}}}],["8659",{"_index":4053,"t":{"842":{"position":[[2447,4]]},"1557":{"position":[[2447,4]]}}}],["8678",{"_index":7818,"t":{"1845":{"position":[[1980,4]]}}}],["868b",{"_index":3990,"t":{"842":{"position":[[1258,4]]},"1557":{"position":[[1258,4]]}}}],["87d6",{"_index":6729,"t":{"1368":{"position":[[1730,4],[1741,4],[1912,5],[1920,4],[2004,4],[2009,5]]}}}],["87dabc34ba56",{"_index":7879,"t":{"1847":{"position":[[1576,12]]}}}],["87e3",{"_index":7833,"t":{"1845":{"position":[[2112,4]]}}}],["88",{"_index":7293,"t":{"1728":{"position":[[453,2]]}}}],["8831",{"_index":6677,"t":{"1366":{"position":[[251,4]]}}}],["8833",{"_index":5322,"t":{"1114":{"position":[[4744,4],[4983,4],[5034,4],[5597,4],[6038,4],[6419,4],[6461,4]]}}}],["8871",{"_index":4201,"t":{"859":{"position":[[2766,4]]},"1603":{"position":[[2766,4]]}}}],["8891",{"_index":7850,"t":{"1847":{"position":[[382,4],[734,4],[1294,4],[1478,4]]},"1849":{"position":[[88,4]]}}}],["88ca",{"_index":4048,"t":{"842":{"position":[[2341,4]]},"1557":{"position":[[2341,4]]}}}],["890",{"_index":6335,"t":{"1317":{"position":[[5176,3]]},"2502":{"position":[[158,4]]}}}],["891",{"_index":6332,"t":{"1317":{"position":[[5047,3]]}}}],["892",{"_index":6328,"t":{"1317":{"position":[[4929,3]]}}}],["893",{"_index":6325,"t":{"1317":{"position":[[4779,3]]}}}],["893d",{"_index":9841,"t":{"3109":{"position":[[2016,4]]}}}],["894",{"_index":6322,"t":{"1317":{"position":[[4618,3]]}}}],["895",{"_index":6319,"t":{"1317":{"position":[[4465,3]]}}}],["896",{"_index":6316,"t":{"1317":{"position":[[4322,3]]}}}],["897",{"_index":6313,"t":{"1317":{"position":[[4188,3]]}}}],["898",{"_index":6310,"t":{"1317":{"position":[[4053,3]]}}}],["899",{"_index":6307,"t":{"1317":{"position":[[3918,3]]}}}],["8:16",{"_index":9191,"t":{"2711":{"position":[[389,4]]},"2856":{"position":[[391,4]]}}}],["8:32",{"_index":9187,"t":{"2711":{"position":[[282,4]]},"2856":{"position":[[284,4]]}}}],["8a2ad60c",{"_index":3436,"t":{"644":{"position":[[385,8]]}}}],["8a45",{"_index":5236,"t":{"1112":{"position":[[4308,4],[4432,4],[4483,4],[5093,4],[5267,4],[5480,4],[5522,4]]}}}],["8a553e69",{"_index":6493,"t":{"1342":{"position":[[505,8]]}}}],["8a69cc7a",{"_index":6408,"t":{"1321":{"position":[[718,9]]}}}],["8b03",{"_index":9868,"t":{"3109":{"position":[[2347,4]]}}}],["8bb5",{"_index":5271,"t":{"1114":{"position":[[1254,4],[1389,4],[1440,4],[1488,4],[2153,4],[2406,4],[2649,4],[2691,4],[2862,4]]}}}],["8bit",{"_index":6481,"t":{"1337":{"position":[[357,4]]}}}],["8bit:ascii",{"_index":6480,"t":{"1337":{"position":[[346,10]]}}}],["8c",{"_index":4707,"t":{"988":{"position":[[214,2]]}}}],["8c42",{"_index":5332,"t":{"1114":{"position":[[4858,4],[5195,4],[5246,4],[5737,4],[6102,4],[6526,4],[6568,4]]}}}],["8c73",{"_index":9872,"t":{"3109":{"position":[[2387,4]]}}}],["8c95",{"_index":7868,"t":{"1847":{"position":[[1426,4]]}}}],["8c:16:50",{"_index":9475,"t":{"2860":{"position":[[844,8]]}}}],["8d1f",{"_index":4229,"t":{"859":{"position":[[4103,4],[4325,4],[4759,4],[4874,4],[6207,4]]},"1603":{"position":[[4103,4],[4325,4],[4759,4],[4874,4],[6207,4]]}}}],["8d372de6",{"_index":4248,"t":{"859":{"position":[[5183,8],[5421,8],[5621,8],[5851,8],[6352,8]]},"1603":{"position":[[5183,8],[5421,8],[5621,8],[5851,8],[6352,8]]}}}],["8d7e",{"_index":5266,"t":{"1114":{"position":[[1169,4],[1540,4],[1746,4],[2296,4],[2539,4],[2907,4],[3013,4]]}}}],["8df1b7",{"_index":6709,"t":{"1368":{"position":[[791,6],[1189,8]]}}}],["8e23",{"_index":9837,"t":{"3109":{"position":[[1979,4]]}}}],["8e2b",{"_index":7873,"t":{"1847":{"position":[[1517,4]]}}}],["8e80",{"_index":7806,"t":{"1845":{"position":[[1056,4]]}}}],["8e8bd5227ebf\",\"apiversion\":\"infrastructure.clusterstack.x",{"_index":2373,"t":{"404":{"position":[[482,57]]}}}],["8ed4",{"_index":6530,"t":{"1351":{"position":[[476,4],[1002,4],[1712,4],[2526,4]]}}}],["8f53",{"_index":3995,"t":{"842":{"position":[[1353,4]]},"1557":{"position":[[1353,4]]}}}],["8fb231442edc",{"_index":5333,"t":{"1114":{"position":[[4863,12],[5200,12],[5251,12],[5742,12],[6107,12],[6531,12],[6573,12]]}}}],["8fe7d0",{"_index":6701,"t":{"1368":{"position":[[594,7]]}}}],["8gib",{"_index":9101,"t":{"2697":{"position":[[1292,4]]},"2713":{"position":[[540,4]]},"2742":{"position":[[1191,4]]},"2858":{"position":[[537,4]]}}}],["8gigabyt",{"_index":4186,"t":{"859":{"position":[[2308,10]]},"1603":{"position":[[2308,10]]}}}],["8h",{"_index":10051,"t":{"3282":{"position":[[300,2]]}}}],["8min",{"_index":3286,"t":{"627":{"position":[[2109,7]]}}}],["8s",{"_index":9210,"t":{"2713":{"position":[[499,2]]},"2756":{"position":[[435,2]]}}}],["8t",{"_index":9308,"t":{"2731":{"position":[[638,2],[663,2],[678,2],[699,2],[883,2]]},"2770":{"position":[[638,2],[663,2],[678,2],[699,2],[883,2]]}}}],["8t:16:50",{"_index":9471,"t":{"2860":{"position":[[599,8]]}}}],["8t:16:50n",{"_index":9472,"t":{"2860":{"position":[[624,10],[639,9],[660,9]]}}}],["8th",{"_index":8489,"t":{"2324":{"position":[[754,3]]}}}],["8ti",{"_index":9316,"t":{"2733":{"position":[[90,3]]},"2772":{"position":[[90,3]]}}}],["8ti:32:50p",{"_index":9432,"t":{"2854":{"position":[[90,10]]}}}],["8v",{"_index":3612,"t":{"730":{"position":[[1421,2]]},"1491":{"position":[[1421,2]]},"1773":{"position":[[1045,2]]},"1808":{"position":[[423,2]]},"1845":{"position":[[227,2],[2539,2]]},"1847":{"position":[[483,2]]},"2711":{"position":[[291,2],[302,2],[398,2],[409,2]]},"2713":{"position":[[800,2]]},"2756":{"position":[[1268,2]]},"2927":{"position":[[189,2],[327,2]]},"2929":{"position":[[185,2],[335,2]]}}}],["8v:16",{"_index":9453,"t":{"2856":{"position":[[400,6]]}}}],["8v:16:100",{"_index":424,"t":{"37":{"position":[[329,9]]},"40":{"position":[[327,9]]}}}],["8v:16:50",{"_index":9454,"t":{"2856":{"position":[[411,8]]}}}],["8v:32",{"_index":9446,"t":{"2856":{"position":[[293,6]]}}}],["8v:32:100",{"_index":9447,"t":{"2856":{"position":[[304,9]]},"2858":{"position":[[638,11]]}}}],["9",{"_index":2019,"t":{"321":{"position":[[1464,2]]},"850":{"position":[[1803,1],[1958,1],[2282,1],[2411,1],[2532,1],[2837,1],[5283,1],[5420,1],[5590,1],[5708,1]]},"913":{"position":[[963,5]]},"1124":{"position":[[1073,1]]},"1484":{"position":[[1803,1],[1958,1],[2282,1],[2411,1],[2532,1],[2837,1],[5283,1],[5420,1],[5590,1],[5708,1]]},"1635":{"position":[[963,5]]},"1775":{"position":[[177,1]]},"1787":{"position":[[1321,1]]},"2360":{"position":[[963,5]]},"2985":{"position":[[189,6]]},"2987":{"position":[[226,6]]},"3299":{"position":[[4257,2]]}}}],["9.0",{"_index":9544,"t":{"2895":{"position":[[2874,3]]}}}],["9.1",{"_index":6182,"t":{"1294":{"position":[[973,4]]},"1822":{"position":[[785,4]]}}}],["9.2",{"_index":7707,"t":{"1822":{"position":[[1140,4]]}}}],["9.9.9.9",{"_index":4992,"t":{"1067":{"position":[[5655,7]]},"1585":{"position":[[3414,7]]},"1808":{"position":[[324,10]]}}}],["9.testbed.osism.xyz",{"_index":7593,"t":{"1787":{"position":[[1288,19]]}}}],["9/19",{"_index":4924,"t":{"1063":{"position":[[1086,6]]}}}],["9/20",{"_index":4887,"t":{"1061":{"position":[[502,6]]}}}],["90",{"_index":6688,"t":{"1366":{"position":[[612,2],[637,2]]},"1775":{"position":[[187,2]]},"1779":{"position":[[4035,2]]},"3357":{"position":[[1105,3]]}}}],["900",{"_index":6304,"t":{"1317":{"position":[[3783,3]]}}}],["9000",{"_index":5120,"t":{"1094":{"position":[[189,4]]}}}],["9008d3d7",{"_index":3940,"t":{"838":{"position":[[261,8]]},"1553":{"position":[[261,8]]}}}],["901",{"_index":6299,"t":{"1317":{"position":[[3657,3]]}}}],["902",{"_index":6295,"t":{"1317":{"position":[[3518,3]]}}}],["903",{"_index":6290,"t":{"1317":{"position":[[3382,3]]}}}],["90345eb5",{"_index":6626,"t":{"1362":{"position":[[1042,8],[1335,8]]}}}],["904",{"_index":6287,"t":{"1317":{"position":[[3225,3]]}}}],["905",{"_index":6283,"t":{"1317":{"position":[[3086,3]]}}}],["906",{"_index":6279,"t":{"1317":{"position":[[2945,3]]}}}],["9066",{"_index":9718,"t":{"3042":{"position":[[906,4]]},"3046":{"position":[[853,4]]}}}],["907",{"_index":6276,"t":{"1317":{"position":[[2818,3]]}}}],["908",{"_index":6272,"t":{"1317":{"position":[[2695,3]]}}}],["909",{"_index":6268,"t":{"1317":{"position":[[2559,3]]}}}],["90a5",{"_index":5337,"t":{"1114":{"position":[[4915,4],[5301,4],[5352,4],[5807,4],[5910,4],[6205,4],[6247,4]]}}}],["90n20",{"_index":334,"t":{"27":{"position":[[1389,5]]}}}],["910",{"_index":6264,"t":{"1317":{"position":[[2449,3],[5508,3],[5649,3]]}}}],["9100",{"_index":5125,"t":{"1098":{"position":[[508,4],[532,4]]},"1585":{"position":[[1748,5],[2024,4]]}}}],["91091d4039a6457db27d48d58bb1b4e4",{"_index":313,"t":{"27":{"position":[[901,32]]}}}],["9160",{"_index":4015,"t":{"842":{"position":[[1735,4]]},"1557":{"position":[[1735,4]]}}}],["9196",{"_index":7752,"t":{"1833":{"position":[[885,4]]}}}],["91c0",{"_index":6755,"t":{"1375":{"position":[[673,4],[1484,4]]},"1377":{"position":[[674,4],[1678,4]]}}}],["9200",{"_index":5043,"t":{"1082":{"position":[[405,4]]},"1167":{"position":[[3050,4]]}}}],["921",{"_index":8591,"t":{"2502":{"position":[[374,5]]}}}],["922b",{"_index":3621,"t":{"730":{"position":[[2141,4]]},"1491":{"position":[[2141,4]]}}}],["925",{"_index":8594,"t":{"2502":{"position":[[676,5]]}}}],["9262",{"_index":6505,"t":{"1342":{"position":[[698,4]]}}}],["926f952f",{"_index":4192,"t":{"859":{"position":[[2613,8]]},"1603":{"position":[[2613,8]]}}}],["9292030d706c",{"_index":6581,"t":{"1360":{"position":[[1432,12]]}}}],["92a79600",{"_index":9757,"t":{"3088":{"position":[[888,8]]},"3107":{"position":[[1117,8]]}}}],["92c2",{"_index":4195,"t":{"859":{"position":[[2632,4]]},"1603":{"position":[[2632,4]]}}}],["92cd",{"_index":3973,"t":{"842":{"position":[[979,4]]},"1557":{"position":[[979,4]]}}}],["92e6",{"_index":7883,"t":{"1847":{"position":[[1610,4]]}}}],["9325",{"_index":4005,"t":{"842":{"position":[[1544,4]]},"1557":{"position":[[1544,4]]}}}],["93956190702b4a7d8a8886806d57713f",{"_index":317,"t":{"27":{"position":[[986,32]]}}}],["93e35d0c",{"_index":9762,"t":{"3088":{"position":[[1017,8]]}}}],["941c",{"_index":3943,"t":{"838":{"position":[[280,4]]},"1553":{"position":[[280,4]]}}}],["942b",{"_index":4000,"t":{"842":{"position":[[1448,4]]},"1557":{"position":[[1448,4]]}}}],["94ff",{"_index":4233,"t":{"859":{"position":[[4196,4],[4434,4],[4534,4],[4649,4],[6115,4]]},"1603":{"position":[[4196,4],[4434,4],[4534,4],[4649,4],[6115,4]]}}}],["952d",{"_index":4218,"t":{"859":{"position":[[3210,4],[3448,4],[3763,4],[3878,4],[6043,4]]},"1603":{"position":[[3210,4],[3448,4],[3763,4],[3878,4],[6043,4]]}}}],["95a07c43",{"_index":3935,"t":{"838":{"position":[[112,8],[208,8]]},"1553":{"position":[[112,8],[208,8]]}}}],["95dc",{"_index":9829,"t":{"3109":{"position":[[1885,4],[2881,4]]}}}],["960",{"_index":4688,"t":{"982":{"position":[[564,3]]}}}],["961d",{"_index":3979,"t":{"842":{"position":[[1072,4]]},"1557":{"position":[[1072,4]]}}}],["963b8eb67000",{"_index":4006,"t":{"842":{"position":[[1549,12]]},"1557":{"position":[[1549,12]]}}}],["9688192e",{"_index":4205,"t":{"859":{"position":[[2881,8]]},"1603":{"position":[[2881,8]]},"1845":{"position":[[1908,8]]}}}],["96ae",{"_index":5015,"t":{"1077":{"position":[[596,4],[728,4]]}}}],["971c",{"_index":4046,"t":{"842":{"position":[[2331,4]]},"1557":{"position":[[2331,4]]}}}],["9728",{"_index":6193,"t":{"1298":{"position":[[396,4]]}}}],["972f",{"_index":7826,"t":{"1845":{"position":[[2061,4]]}}}],["97507e4c",{"_index":9814,"t":{"3109":{"position":[[1704,8]]}}}],["97d372945bb1",{"_index":3980,"t":{"842":{"position":[[1077,12]]},"1557":{"position":[[1077,12]]}}}],["982221c1",{"_index":3429,"t":{"644":{"position":[[289,8]]}}}],["98842b77",{"_index":7820,"t":{"1845":{"position":[[2002,8]]}}}],["989b",{"_index":4037,"t":{"842":{"position":[[2123,4]]},"1557":{"position":[[2123,4]]}}}],["99",{"_index":4863,"t":{"1055":{"position":[[1932,2]]},"2705":{"position":[[336,4],[574,4]]},"2750":{"position":[[336,4],[574,4]]},"2840":{"position":[[244,4],[469,4]]},"2923":{"position":[[332,4]]},"3103":{"position":[[1287,3]]}}}],["99,9",{"_index":2058,"t":{"325":{"position":[[1586,5]]}}}],["99.x",{"_index":9097,"t":{"2688":{"position":[[2872,4]]}}}],["9917",{"_index":9839,"t":{"3109":{"position":[[2006,4]]}}}],["997bb0c2",{"_index":9789,"t":{"3107":{"position":[[1246,8]]}}}],["99d3267f630a",{"_index":4209,"t":{"859":{"position":[[2905,12]]},"1603":{"position":[[2905,12]]},"1845":{"position":[[1932,12]]}}}],["99d3267f630a,v4",{"_index":7842,"t":{"1845":{"position":[[2709,15]]}}}],["99d588c4e947",{"_index":7824,"t":{"1845":{"position":[[2026,12]]}}}],["9:00",{"_index":1353,"t":{"187":{"position":[[521,4]]}}}],["9\\.]*\\)'.*\\$@\\1",{"_index":4364,"t":{"903":{"position":[[3372,18]]},"1625":{"position":[[3372,18]]},"2350":{"position":[[3372,18]]}}}],["9])/printf",{"_index":3228,"t":{"609":{"position":[[3246,10],[3360,10],[3918,10],[4032,10],[5746,10],[5860,10]]},"635":{"position":[[3599,10]]}}}],["9]*_",{"_index":4459,"t":{"913":{"position":[[1176,5],[1251,5],[1325,5],[1400,5],[1480,5],[1554,5],[1636,5]]},"1635":{"position":[[1176,5],[1251,5],[1325,5],[1400,5],[1480,5],[1554,5],[1636,5]]},"2360":{"position":[[1176,5],[1251,5],[1325,5],[1400,5],[1480,5],[1554,5],[1636,5]]}}}],["9]+(.[0",{"_index":9665,"t":{"2985":{"position":[[181,7]]},"2987":{"position":[[218,7]]}}}],["9].[0",{"_index":9664,"t":{"2985":{"position":[[175,5]]},"2987":{"position":[[212,5]]}}}],["9][0",{"_index":3227,"t":{"609":{"position":[[3241,4],[3355,4],[3913,4],[4027,4],[5741,4],[5855,4]]},"635":{"position":[[3594,4]]}}}],["9a",{"_index":6659,"t":{"1364":{"position":[[594,2]]}}}],["9a1576af59644a2dbbace773ad17158d",{"_index":269,"t":{"25":{"position":[[235,32]]}}}],["9a76",{"_index":7794,"t":{"1843":{"position":[[1003,4]]},"1845":{"position":[[2574,4]]}}}],["9b18",{"_index":4026,"t":{"842":{"position":[[1925,4]]},"1557":{"position":[[1925,4]]}}}],["9b1f6342dc60",{"_index":6617,"t":{"1360":{"position":[[2766,12]]}}}],["9b39",{"_index":9753,"t":{"3088":{"position":[[773,4]]},"3107":{"position":[[874,4]]}}}],["9b5f7f8ed70d410c81e3f45bf4e36498",{"_index":4064,"t":{"842":{"position":[[3036,32]]},"1557":{"position":[[3036,32]]}}}],["9b7140bfe628468ab9b86b365f9ac4c2",{"_index":5643,"t":{"1150":{"position":[[12946,32]]}}}],["9b7a73e516be4cd1acbd63d543985c52",{"_index":300,"t":{"27":{"position":[[257,32]]}}}],["9ba0",{"_index":7863,"t":{"1847":{"position":[[1387,4]]}}}],["9ba9",{"_index":9787,"t":{"3107":{"position":[[1077,4]]}}}],["9bfa",{"_index":3982,"t":{"842":{"position":[[1155,4]]},"1557":{"position":[[1155,4]]}}}],["9c31",{"_index":4010,"t":{"842":{"position":[[1640,4]]},"1557":{"position":[[1640,4]]}}}],["9cb2",{"_index":5241,"t":{"1112":{"position":[[4364,4],[4538,4],[4589,4],[5163,4],[5332,4],[5588,4],[5630,4]]}}}],["9cee",{"_index":3442,"t":{"644":{"position":[[490,4]]}}}],["9de7d8dc2d674e52be44904d6b338b0b",{"_index":306,"t":{"27":{"position":[[492,32]]}}}],["9deeb06b",{"_index":7875,"t":{"1847":{"position":[[1552,8]]}}}],["9e1c",{"_index":3444,"t":{"644":{"position":[[500,4]]}}}],["9e80",{"_index":4251,"t":{"859":{"position":[[5202,4],[5440,4],[5640,4],[5870,4],[6371,4]]},"1603":{"position":[[5202,4],[5440,4],[5640,4],[5870,4],[6371,4]]}}}],["9e8799a",{"_index":5319,"t":{"1114":{"position":[[4725,8],[4964,8],[5015,8],[5578,8],[6019,8],[6400,8],[6442,8]]}}}],["9ed4",{"_index":5296,"t":{"1114":{"position":[[3638,4]]}}}],["9ed6",{"_index":9808,"t":{"3109":{"position":[[677,4]]}}}],["9eea",{"_index":6341,"t":{"1317":{"position":[[5683,4]]}}}],["9f93",{"_index":2372,"t":{"404":{"position":[[477,4]]}}}],["9f95",{"_index":4031,"t":{"842":{"position":[[2024,4]]},"1557":{"position":[[2024,4]]}}}],["9fbd",{"_index":9765,"t":{"3088":{"position":[[1036,4]]}}}],["9fc7",{"_index":9821,"t":{"3109":{"position":[[1767,4]]}}}],["9wvgt",{"_index":10041,"t":{"3276":{"position":[[2661,5]]}}}],["_",{"_index":7126,"t":{"1591":{"position":[[989,3]]},"2735":{"position":[[138,1]]},"2774":{"position":[[274,1]]},"3314":{"position":[[848,1],[1106,1],[1259,1],[1434,1]]}}}],["_('openstack",{"_index":5493,"t":{"1146":{"position":[[381,12],[528,12]]}}}],["_/g",{"_index":9337,"t":{"2735":{"position":[[485,5]]},"2774":{"position":[[621,5]]}}}],["_[g/g]x[n",{"_index":9357,"t":{"2766":{"position":[[8,11]]}}}],["__default",{"_index":6534,"t":{"1351":{"position":[[1254,9]]}}}],["__default__",{"_index":6535,"t":{"1351":{"position":[[1335,11],[1749,11],[2563,11]]},"1808":{"position":[[821,11]]},"3033":{"position":[[196,12],[467,12]]}}}],["__main__",{"_index":1891,"t":{"284":{"position":[[1191,11]]}}}],["__name__",{"_index":1890,"t":{"284":{"position":[[1179,8]]}}}],["_api",{"_index":10111,"t":{"3314":{"position":[[1081,4]]}}}],["_arch[n][h",{"_index":9353,"t":{"2764":{"position":[[8,11]]}}}],["_bms_z3",{"_index":9175,"t":{"2709":{"position":[[1771,7]]},"2754":{"position":[[1912,7]]}}}],["_bms_z3h_gna",{"_index":9176,"t":{"2709":{"position":[[1788,12]]},"2754":{"position":[[1929,12]]}}}],["_ext",{"_index":9118,"t":{"2702":{"position":[[114,6]]},"2747":{"position":[[114,6]]}}}],["_g",{"_index":9351,"t":{"2758":{"position":[[1999,2],[2039,2]]}}}],["_gx[n",{"_index":9281,"t":{"2727":{"position":[[0,7],[108,7]]}}}],["_hwv",{"_index":9240,"t":{"2723":{"position":[[127,4],[452,4]]},"2762":{"position":[[8,4],[140,4],[465,4]]}}}],["_hyp",{"_index":9352,"t":{"2760":{"position":[[8,4]]}}}],["_hyp][_hwv][_[arch[n][h][_[g/g]x[n",{"_index":9231,"t":{"2719":{"position":[[1678,37]]}}}],["_hyp][_hwv][_arch[n][h]][_[g/g]x[n",{"_index":9349,"t":{"2758":{"position":[[1679,37]]}}}],["_ib",{"_index":9178,"t":{"2709":{"position":[[1816,3]]},"2729":{"position":[[0,3]]},"2754":{"position":[[1957,3]]},"2768":{"position":[[8,3]]}}}],["_set_new_cache_s",{"_index":6423,"t":{"1321":{"position":[[1121,20]]}}}],["_test",{"_index":1851,"t":{"282":{"position":[[24,5],[446,5]]}}}],["_thi",{"_index":10112,"t":{"3314":{"position":[[1201,5]]}}}],["_to",{"_index":10108,"t":{"3314":{"position":[[690,3]]}}}],["_web",{"_index":10114,"t":{"3314":{"position":[[1391,4]]}}}],["_without",{"_index":9466,"t":{"2856":{"position":[[1278,8]]}}}],["a)gplv3",{"_index":1241,"t":{"176":{"position":[[1149,8]]}}}],["a.k.a",{"_index":8178,"t":{"2098":{"position":[[448,6]]}}}],["a001",{"_index":7799,"t":{"1843":{"position":[[1074,4]]},"1845":{"position":[[2788,4]]}}}],["a06e7496fec3",{"_index":7813,"t":{"1845":{"position":[[1177,12],[2657,12]]}}}],["a07c811315ad40f585945b2939ef12dd",{"_index":352,"t":{"27":{"position":[[1717,32]]}}}],["a098cc12",{"_index":4232,"t":{"859":{"position":[[4187,8],[4425,8],[4525,8],[4640,8],[6106,8]]},"1603":{"position":[[4187,8],[4425,8],[4525,8],[4640,8],[6106,8]]}}}],["a0da232a",{"_index":5329,"t":{"1114":{"position":[[4839,8],[5176,8],[5227,8],[5718,8],[6083,8],[6507,8],[6549,8]]}}}],["a1",{"_index":9437,"t":{"2854":{"position":[[402,2]]}}}],["a147",{"_index":3984,"t":{"842":{"position":[[1165,4]]},"1557":{"position":[[1165,4]]}}}],["a18c",{"_index":4208,"t":{"859":{"position":[[2900,4]]},"1603":{"position":[[2900,4]]},"1845":{"position":[[1927,4],[2704,4]]}}}],["a2",{"_index":9474,"t":{"2860":{"position":[[670,2]]}}}],["a2a9",{"_index":7823,"t":{"1845":{"position":[[2021,4]]}}}],["a30",{"_index":9365,"t":{"2766":{"position":[[1213,4]]}}}],["a32c",{"_index":5151,"t":{"1102":{"position":[[258,4]]}}}],["a390",{"_index":9760,"t":{"3088":{"position":[[907,4]]},"3107":{"position":[[1206,4]]}}}],["a5558f7338f94adea5f41858636256b5",{"_index":3870,"t":{"819":{"position":[[8442,32]]},"821":{"position":[[3525,32],[3626,33]]},"1509":{"position":[[8442,32]]},"1511":{"position":[[3525,32],[3626,33]]}}}],["a5a0adfc24e5",{"_index":7889,"t":{"1849":{"position":[[455,12]]}}}],["a5cc",{"_index":3450,"t":{"644":{"position":[[608,4]]}}}],["a5d4",{"_index":6496,"t":{"1342":{"position":[[524,4]]}}}],["a5db",{"_index":6645,"t":{"1364":{"position":[[206,4]]}}}],["a6a3",{"_index":7858,"t":{"1847":{"position":[[1333,4]]}}}],["a6ad",{"_index":7626,"t":{"1791":{"position":[[2270,4],[3075,4]]}}}],["a71x/neon2",{"_index":9263,"t":{"2725":{"position":[[545,10]]},"2764":{"position":[[766,10]]},"2850":{"position":[[454,10]]}}}],["a72f",{"_index":9802,"t":{"3109":{"position":[[624,4]]}}}],["a740c178148d",{"_index":3944,"t":{"838":{"position":[[285,12]]},"1553":{"position":[[285,12]]}}}],["a76",{"_index":9256,"t":{"2725":{"position":[[416,3]]},"2733":{"position":[[428,4]]},"2764":{"position":[[637,3]]},"2772":{"position":[[428,4]]},"2850":{"position":[[325,3]]}}}],["a76/neon1",{"_index":9259,"t":{"2725":{"position":[[449,9]]},"2764":{"position":[[670,9]]},"2850":{"position":[[358,9]]}}}],["a77d",{"_index":3432,"t":{"644":{"position":[[308,4]]}}}],["a78",{"_index":9438,"t":{"2854":{"position":[[429,4]]}}}],["a78/x1/neov1",{"_index":9261,"t":{"2725":{"position":[[497,12]]},"2764":{"position":[[718,12]]},"2850":{"position":[[406,12]]}}}],["a81ef8097c35",{"_index":7874,"t":{"1847":{"position":[[1522,12]]}}}],["a8549ef5d3d14f938b127a1cdefe3788",{"_index":3844,"t":{"819":{"position":[[4298,32],[4886,32],[5484,32],[7321,32],[8373,32]]},"821":{"position":[[2120,32],[2366,32],[3672,32],[5013,32]]},"1509":{"position":[[4298,32],[4886,32],[5484,32],[7321,32],[8373,32]]},"1511":{"position":[[2120,32],[2366,32],[3672,32],[5013,32]]}}}],["a873c27ec818",{"_index":4021,"t":{"842":{"position":[[1835,12]]},"1557":{"position":[[1835,12]]}}}],["a911",{"_index":4020,"t":{"842":{"position":[[1830,4]]},"1557":{"position":[[1830,4]]}}}],["a989e52427fa",{"_index":3939,"t":{"838":{"position":[[136,12],[232,12]]},"1553":{"position":[[136,12],[232,12]]}}}],["a99a",{"_index":3448,"t":{"644":{"position":[[598,4]]}}}],["a='[0",{"_index":6658,"t":{"1364":{"position":[[588,5]]}}}],["a=amper",{"_index":9293,"t":{"2727":{"position":[[421,9]]},"2766":{"position":[[621,9]]},"2852":{"position":[[791,9]]}}}],["aa",{"_index":8380,"t":{"2196":{"position":[[886,3]]}}}],["aaaab",{"_index":4838,"t":{"1043":{"position":[[182,8]]}}}],["aabd",{"_index":4213,"t":{"859":{"position":[[3107,4],[3329,4],[3548,4],[3663,4],[5961,4]]},"1603":{"position":[[3107,4],[3329,4],[3548,4],[3663,4],[5961,4]]}}}],["aarch64",{"_index":9253,"t":{"2725":{"position":[[362,9]]},"2764":{"position":[[341,7],[583,9]]},"2850":{"position":[[271,9]]}}}],["ab21",{"_index":9817,"t":{"3109":{"position":[[1723,4]]}}}],["ab40",{"_index":4042,"t":{"842":{"position":[[2235,4]]},"1557":{"position":[[2235,4]]}}}],["ab678ce7272d",{"_index":6678,"t":{"1366":{"position":[[256,12]]}}}],["abandon",{"_index":10103,"t":{"3310":{"position":[[960,9]]}}}],["abbe6561cf6248b6af395334aa09af85",{"_index":322,"t":{"27":{"position":[[1081,32]]}}}],["abbr",{"_index":9743,"t":{"3076":{"position":[[15,6],[103,6],[179,6]]},"3099":{"position":[[128,6]]},"3152":{"position":[[23,6],[103,6]]},"3295":{"position":[[23,6],[119,6]]},"3489":{"position":[[8,6]]},"3502":{"position":[[8,6]]}}}],["abbrev",{"_index":6657,"t":{"1364":{"position":[[577,8],[808,6]]},"1368":{"position":[[564,6],[1065,6],[1560,6],[2236,6]]}}}],["abbrevi",{"_index":6664,"t":{"1364":{"position":[[684,10],[725,10]]},"2627":{"position":[[580,14],[1692,14]]},"3264":{"position":[[77,12]]}}}],["abc5",{"_index":9755,"t":{"3088":{"position":[[783,4]]},"3107":{"position":[[949,4]]}}}],["abid",{"_index":9893,"t":{"3160":{"position":[[357,5]]}}}],["abil",{"_index":535,"t":{"71":{"position":[[399,7]]},"170":{"position":[[78,7]]},"245":{"position":[[1444,7]]},"247":{"position":[[799,8]]},"880":{"position":[[856,7]]},"909":{"position":[[2642,7]]},"1631":{"position":[[2642,7]]},"1857":{"position":[[1082,7]]},"1919":{"position":[[1082,7]]},"1951":{"position":[[724,7]]},"2096":{"position":[[2484,7]]},"2108":{"position":[[35,7]]},"2118":{"position":[[917,7]]},"2130":{"position":[[35,7]]},"2243":{"position":[[126,7]]},"2245":{"position":[[423,7]]},"2356":{"position":[[2642,7]]},"2504":{"position":[[336,7]]},"2700":{"position":[[317,7]]},"2719":{"position":[[879,7]]},"2745":{"position":[[317,7]]},"2758":{"position":[[877,7]]},"2835":{"position":[[258,7]]},"2951":{"position":[[505,7]]},"3011":{"position":[[1223,7]]},"3160":{"position":[[419,7],[1932,7],[2463,7],[2820,7]]},"3206":{"position":[[537,7]]},"3208":{"position":[[1651,7],[1732,7]]},"3216":{"position":[[46,7]]},"3218":{"position":[[487,7]]},"3314":{"position":[[1772,7]]}}}],["abnorm",{"_index":9483,"t":{"2870":{"position":[[217,10]]},"3389":{"position":[[930,11]]}}}],["abondend",{"_index":10137,"t":{"3316":{"position":[[1722,8]]}}}],["abort",{"_index":4483,"t":{"913":{"position":[[3235,5]]},"915":{"position":[[891,5]]},"1635":{"position":[[3235,5]]},"1637":{"position":[[891,5]]},"2360":{"position":[[3235,5]]},"2362":{"position":[[891,5]]}}}],["abov",{"_index":491,"t":{"65":{"position":[[148,5]]},"67":{"position":[[235,5]]},"184":{"position":[[509,5],[696,5],[824,5]]},"242":{"position":[[434,5]]},"247":{"position":[[1967,5]]},"421":{"position":[[1594,5]]},"465":{"position":[[607,6]]},"487":{"position":[[5577,6]]},"495":{"position":[[103,5]]},"596":{"position":[[2858,6]]},"604":{"position":[[4549,6],[7403,5],[8194,5],[8339,6],[9060,5]]},"633":{"position":[[2021,5]]},"635":{"position":[[3258,5],[3967,5]]},"909":{"position":[[1746,6],[2454,5]]},"930":{"position":[[180,6]]},"934":{"position":[[453,7],[1056,5],[2037,5]]},"936":{"position":[[84,5]]},"940":{"position":[[232,5]]},"945":{"position":[[123,6]]},"947":{"position":[[1658,5]]},"1161":{"position":[[320,7]]},"1364":{"position":[[740,5]]},"1406":{"position":[[269,5]]},"1473":{"position":[[252,6]]},"1477":{"position":[[267,5]]},"1631":{"position":[[1746,6],[2454,5]]},"1652":{"position":[[180,6]]},"1656":{"position":[[453,7],[1056,5],[2037,5]]},"1658":{"position":[[84,5]]},"1662":{"position":[[232,5]]},"1667":{"position":[[123,6]]},"1669":{"position":[[1658,5]]},"1779":{"position":[[1635,6]]},"1896":{"position":[[951,6]]},"1898":{"position":[[112,6]]},"1900":{"position":[[675,6]]},"1904":{"position":[[191,6]]},"1982":{"position":[[574,6]]},"1984":{"position":[[184,6]]},"2012":{"position":[[951,6]]},"2014":{"position":[[112,6]]},"2016":{"position":[[675,6]]},"2020":{"position":[[191,6]]},"2093":{"position":[[698,5]]},"2138":{"position":[[839,5]]},"2154":{"position":[[1445,5]]},"2158":{"position":[[733,5]]},"2356":{"position":[[1746,6],[2454,5]]},"2377":{"position":[[180,6]]},"2381":{"position":[[453,7],[1056,5],[2037,5]]},"2383":{"position":[[84,5]]},"2387":{"position":[[232,5]]},"2392":{"position":[[123,6]]},"2394":{"position":[[1658,5]]},"2514":{"position":[[680,6]]},"2705":{"position":[[824,5]]},"2713":{"position":[[1601,5]]},"2715":{"position":[[655,5]]},"2729":{"position":[[158,5]]},"2731":{"position":[[114,5]]},"2750":{"position":[[839,5],[1396,6]]},"2756":{"position":[[138,6],[278,5]]},"2758":{"position":[[1832,5]]},"2768":{"position":[[181,5]]},"2770":{"position":[[114,5]]},"2807":{"position":[[37,6]]},"2840":{"position":[[729,5]]},"2852":{"position":[[1257,5]]},"2858":{"position":[[1363,5]]},"2860":{"position":[[114,5]]},"2874":{"position":[[95,6],[145,5]]},"2876":{"position":[[10,6]]},"2947":{"position":[[2297,5]]},"2953":{"position":[[326,5]]},"2966":{"position":[[4363,5]]},"2992":{"position":[[569,6]]},"3071":{"position":[[1353,6],[1662,5]]},"3162":{"position":[[383,5]]},"3301":{"position":[[794,5]]},"3347":{"position":[[735,6]]},"3472":{"position":[[13105,5]]}}}],["absenc",{"_index":9704,"t":{"3021":{"position":[[317,7]]},"3092":{"position":[[43,7]]}}}],["absolut",{"_index":4589,"t":{"932":{"position":[[3504,8],[3659,8]]},"1654":{"position":[[3504,8],[3659,8]]},"1974":{"position":[[440,10]]},"2379":{"position":[[3504,8],[3659,8]]}}}],["abstain",{"_index":10237,"t":{"3468":{"position":[[644,7]]}}}],["abstract",{"_index":593,"t":{"79":{"position":[[639,8]]},"284":{"position":[[660,8]]},"327":{"position":[[746,11]]},"883":{"position":[[138,11],[840,12],[865,9],[1088,11]]},"888":{"position":[[108,11]]},"1974":{"position":[[423,12]]},"1982":{"position":[[35,13],[533,9]]},"1984":{"position":[[143,9]]},"2627":{"position":[[1280,8]]},"2697":{"position":[[1612,11]]},"2742":{"position":[[1511,11]]},"2960":{"position":[[95,9]]},"3059":{"position":[[298,8]]},"3249":{"position":[[411,11]]},"3455":{"position":[[411,8]]}}}],["abus",{"_index":1296,"t":{"178":{"position":[[2400,6]]},"3463":{"position":[[523,5]]}}}],["ac",{"_index":6039,"t":{"1226":{"position":[[984,2]]}}}],["ac12",{"_index":4018,"t":{"842":{"position":[[1820,4]]},"1557":{"position":[[1820,4]]}}}],["acceler",{"_index":551,"t":{"73":{"position":[[271,11]]},"1226":{"position":[[299,11]]},"2484":{"position":[[279,12]]},"2723":{"position":[[68,11]]},"2762":{"position":[[81,11]]},"2848":{"position":[[68,11]]},"2960":{"position":[[1211,12]]}}}],["accept",{"_index":1300,"t":{"178":{"position":[[2507,10],[2585,6]]},"247":{"position":[[1298,11],[1998,6]]},"756":{"position":[[92,7]]},"903":{"position":[[3844,6]]},"1108":{"position":[[286,8],[333,8]]},"1213":{"position":[[221,8]]},"1321":{"position":[[1978,8]]},"1473":{"position":[[1276,6]]},"1625":{"position":[[3844,6]]},"2118":{"position":[[1921,8],[2158,8]]},"2350":{"position":[[3844,6]]},"2625":{"position":[[609,10]]},"2631":{"position":[[956,10],[1206,8]]},"2633":{"position":[[173,10]]},"2647":{"position":[[1300,10]]},"2735":{"position":[[816,6]]},"2750":{"position":[[1659,8]]},"2774":{"position":[[818,6]]},"3160":{"position":[[228,10]]},"3270":{"position":[[587,8]]},"3310":{"position":[[708,6]]}}}],["access",{"_index":187,"t":{"12":{"position":[[95,6],[286,6]]},"18":{"position":[[11,6]]},"23":{"position":[[550,6]]},"25":{"position":[[104,6],[182,6]]},"30":{"position":[[41,6]]},"71":{"position":[[163,6]]},"101":{"position":[[51,6],[81,6],[190,6]]},"158":{"position":[[190,6]]},"176":{"position":[[197,8]]},"198":{"position":[[167,14]]},"302":{"position":[[599,6],[627,6],[1027,6]]},"306":{"position":[[33,7]]},"315":{"position":[[212,6]]},"335":{"position":[[993,10]]},"387":{"position":[[298,6]]},"404":{"position":[[702,6]]},"434":{"position":[[171,6]]},"467":{"position":[[324,6],[398,6],[591,6],[860,6],[903,6],[1500,6],[2246,6]]},"483":{"position":[[826,6]]},"487":{"position":[[3344,6],[3448,6]]},"495":{"position":[[305,6],[447,7],[502,6],[1192,6],[1334,7],[1389,6]]},"497":{"position":[[25,6],[261,6]]},"499":{"position":[[1731,6],[1874,6],[2036,6]]},"505":{"position":[[1125,6]]},"519":{"position":[[9,6]]},"590":{"position":[[170,6]]},"596":{"position":[[2208,6],[2911,6]]},"609":{"position":[[960,6],[1813,6],[4615,6]]},"617":{"position":[[909,6]]},"627":{"position":[[4744,6]]},"631":{"position":[[757,6]]},"641":{"position":[[1484,6],[1555,6]]},"644":{"position":[[229,6]]},"646":{"position":[[2034,6]]},"648":{"position":[[478,6]]},"660":{"position":[[226,7],[307,6],[363,6]]},"744":{"position":[[364,6],[724,6],[778,6]]},"762":{"position":[[146,6]]},"764":{"position":[[422,6]]},"776":{"position":[[345,8]]},"819":{"position":[[6822,6],[6982,6],[7034,6],[8104,6]]},"850":{"position":[[298,6],[320,6]]},"865":{"position":[[316,6],[359,6]]},"878":{"position":[[316,6],[359,6]]},"895":{"position":[[1463,6],[1640,6]]},"899":{"position":[[363,6]]},"901":{"position":[[387,6]]},"903":{"position":[[922,6]]},"905":{"position":[[245,6]]},"922":{"position":[[472,8]]},"932":{"position":[[1165,7],[1721,6],[4353,6]]},"942":{"position":[[600,6]]},"947":{"position":[[318,8],[753,10]]},"1065":{"position":[[829,6]]},"1184":{"position":[[98,8]]},"1199":{"position":[[133,10]]},"1205":{"position":[[64,7]]},"1224":{"position":[[2482,6],[2631,6],[3048,12],[3123,10],[3298,10],[3865,12]]},"1240":{"position":[[845,8],[1019,8],[1205,8]]},"1252":{"position":[[824,10],[930,6],[1332,10]]},"1256":{"position":[[152,6]]},"1279":{"position":[[269,10]]},"1294":{"position":[[182,6]]},"1388":{"position":[[68,6],[250,6],[322,6]]},"1484":{"position":[[298,6],[320,6]]},"1509":{"position":[[6822,6],[6982,6],[7034,6],[8104,6]]},"1560":{"position":[[394,10]]},"1562":{"position":[[717,7]]},"1569":{"position":[[1145,6]]},"1576":{"position":[[15,6]]},"1585":{"position":[[600,10]]},"1617":{"position":[[1463,6],[1640,6]]},"1621":{"position":[[363,6]]},"1623":{"position":[[387,6]]},"1625":{"position":[[922,6]]},"1627":{"position":[[245,6]]},"1644":{"position":[[472,8]]},"1654":{"position":[[1165,7],[1721,6],[4353,6]]},"1664":{"position":[[600,6]]},"1669":{"position":[[318,8],[753,10]]},"1743":{"position":[[294,10]]},"1745":{"position":[[1027,6]]},"1777":{"position":[[100,6]]},"1779":{"position":[[77,6],[138,6],[422,6],[441,6]]},"1783":{"position":[[271,6]]},"1787":{"position":[[21,6]]},"1789":{"position":[[206,6]]},"1791":{"position":[[1335,6]]},"1829":{"position":[[177,6],[462,6]]},"1831":{"position":[[44,6],[309,6]]},"1841":{"position":[[561,6]]},"1849":{"position":[[757,11]]},"1882":{"position":[[809,10]]},"1913":{"position":[[1569,10]]},"1953":{"position":[[275,6],[380,6]]},"1957":{"position":[[65,6],[4423,6]]},"1972":{"position":[[494,6],[717,6]]},"1982":{"position":[[321,6]]},"1998":{"position":[[809,10]]},"2029":{"position":[[1569,10]]},"2041":{"position":[[341,6]]},"2096":{"position":[[2417,6],[2495,6],[2655,6]]},"2108":{"position":[[46,6]]},"2118":{"position":[[928,6]]},"2130":{"position":[[46,6]]},"2138":{"position":[[672,6]]},"2164":{"position":[[837,6],[869,6]]},"2245":{"position":[[703,6]]},"2283":{"position":[[976,6]]},"2315":{"position":[[1494,6],[1693,6]]},"2330":{"position":[[496,6]]},"2342":{"position":[[1463,6],[1640,6]]},"2346":{"position":[[363,6]]},"2348":{"position":[[387,6]]},"2350":{"position":[[922,6]]},"2352":{"position":[[245,6]]},"2369":{"position":[[472,8]]},"2379":{"position":[[1165,7],[1721,6],[4353,6]]},"2389":{"position":[[600,6]]},"2394":{"position":[[318,8],[753,10]]},"2476":{"position":[[861,6]]},"2491":{"position":[[146,10]]},"2493":{"position":[[32,6]]},"2526":{"position":[[334,10]]},"2540":{"position":[[332,9]]},"2546":{"position":[[364,7]]},"2574":{"position":[[40,6],[301,6]]},"2576":{"position":[[168,6]]},"2586":{"position":[[274,6]]},"2629":{"position":[[464,6]]},"2663":{"position":[[441,6]]},"2671":{"position":[[1262,6]]},"2677":{"position":[[187,10]]},"2688":{"position":[[615,6],[1015,7]]},"2874":{"position":[[1060,6]]},"2883":{"position":[[56,9]]},"2895":{"position":[[478,10],[3739,10],[4643,10]]},"2901":{"position":[[1202,6]]},"2911":{"position":[[497,9]]},"2942":{"position":[[531,6]]},"2944":{"position":[[401,6]]},"2949":{"position":[[1024,10]]},"2966":{"position":[[2339,10]]},"3069":{"position":[[433,6]]},"3097":{"position":[[221,11]]},"3099":{"position":[[212,6],[290,6]]},"3109":{"position":[[64,6],[904,6]]},"3141":{"position":[[34,6]]},"3150":{"position":[[72,9],[305,10],[417,6],[455,7]]},"3160":{"position":[[816,6],[848,6]]},"3208":{"position":[[859,7],[1551,6]]},"3210":{"position":[[1028,13]]},"3236":{"position":[[1218,6],[1563,6],[1692,6],[2152,6]]},"3238":{"position":[[618,6]]},"3240":{"position":[[57,6]]},"3245":{"position":[[94,6],[1056,6],[1331,6]]},"3249":{"position":[[120,6]]},"3251":{"position":[[4729,6]]},"3272":{"position":[[119,8]]},"3293":{"position":[[72,9]]},"3301":{"position":[[3343,6]]},"3314":{"position":[[172,6],[218,6]]},"3325":{"position":[[886,6],[1027,6],[1964,6]]},"3389":{"position":[[155,6]]},"3455":{"position":[[101,6],[385,6]]},"3463":{"position":[[182,6]]},"3482":{"position":[[2913,6]]},"3484":{"position":[[36,6]]}}}],["access:is_publ",{"_index":3623,"t":{"730":{"position":[[2197,16]]},"1491":{"position":[[2197,16]]}}}],["access_as_extern",{"_index":9852,"t":{"3109":{"position":[[2145,18]]}}}],["access_as_shar",{"_index":9798,"t":{"3109":{"position":[[370,16],[579,16],[1775,16],[1903,16],[2024,16],[2271,16],[2395,16],[2793,16]]}}}],["access_floatingip",{"_index":7693,"t":{"1808":{"position":[[1122,17]]}}}],["access_ipv4",{"_index":7694,"t":{"1808":{"position":[[1140,11]]}}}],["access_ipv6",{"_index":7695,"t":{"1808":{"position":[[1152,11]]}}}],["access_project_id",{"_index":3617,"t":{"730":{"position":[[2050,18]]},"1491":{"position":[[2050,18]]},"3042":{"position":[[785,18]]},"3046":{"position":[[635,18]]}}}],["accesskey",{"_index":2527,"t":{"442":{"position":[[482,11]]}}}],["accessmod",{"_index":2480,"t":{"427":{"position":[[1244,12],[1281,11]]}}}],["accommod",{"_index":8194,"t":{"2100":{"position":[[226,13]]},"2663":{"position":[[114,11]]}}}],["accompani",{"_index":9093,"t":{"2688":{"position":[[2402,11]]},"3314":{"position":[[2462,11]]}}}],["accomplish",{"_index":9076,"t":{"2675":{"position":[[910,12]]},"2872":{"position":[[1270,12]]}}}],["accord",{"_index":1615,"t":{"245":{"position":[[444,9]]},"278":{"position":[[131,9]]},"513":{"position":[[2387,9]]},"519":{"position":[[93,9]]},"631":{"position":[[206,9]]},"734":{"position":[[40,9]]},"883":{"position":[[1950,9]]},"1165":{"position":[[3045,9]]},"1224":{"position":[[972,9],[2335,9]]},"1234":{"position":[[1347,9]]},"1256":{"position":[[645,9]]},"1413":{"position":[[185,9]]},"1495":{"position":[[40,9]]},"2043":{"position":[[660,9]]},"2071":{"position":[[454,9]]},"2110":{"position":[[79,9],[232,9]]},"2138":{"position":[[228,9],[365,9],[466,9]]},"2259":{"position":[[20,9]]},"2292":{"position":[[20,9]]},"2635":{"position":[[275,9]]},"2677":{"position":[[707,9],[1120,9]]},"2713":{"position":[[98,9]]},"2721":{"position":[[139,9]]},"2760":{"position":[[151,9]]},"2813":{"position":[[1370,9]]},"2822":{"position":[[131,10]]},"2846":{"position":[[139,9]]},"2858":{"position":[[98,9]]},"2895":{"position":[[3090,10]]},"2951":{"position":[[1111,9]]},"3061":{"position":[[1138,9]]},"3078":{"position":[[967,9]]},"3128":{"position":[[490,9],[1030,9],[1100,9]]},"3132":{"position":[[299,9]]},"3182":{"position":[[550,9],[1079,9],[1502,9]]},"3238":{"position":[[339,9]]},"3270":{"position":[[816,9]]},"3276":{"position":[[1503,9]]},"3297":{"position":[[124,10]]},"3301":{"position":[[1066,9]]},"3380":{"position":[[16,9]]},"3472":{"position":[[13143,9]]}}}],["accordingli",{"_index":1647,"t":{"247":{"position":[[223,12]]},"499":{"position":[[1033,12]]},"786":{"position":[[204,11]]},"932":{"position":[[3752,12]]},"1110":{"position":[[752,12]]},"1167":{"position":[[2539,11],[4098,12]]},"1184":{"position":[[964,12]]},"1240":{"position":[[638,12]]},"1523":{"position":[[204,11]]},"1585":{"position":[[1707,12]]},"1654":{"position":[[3752,12]]},"1705":{"position":[[273,11]]},"1764":{"position":[[3301,12]]},"1794":{"position":[[460,12]]},"1896":{"position":[[1197,11]]},"1902":{"position":[[418,12]]},"1906":{"position":[[253,12]]},"2012":{"position":[[1197,11]]},"2018":{"position":[[418,12]]},"2022":{"position":[[253,12]]},"2118":{"position":[[320,13]]},"2255":{"position":[[348,12]]},"2379":{"position":[[3752,12]]},"2669":{"position":[[80,12]]},"2805":{"position":[[909,12]]},"3472":{"position":[[12651,12],[14699,12]]},"3512":{"position":[[53,12]]}}}],["account",{"_index":248,"t":{"23":{"position":[[253,8]]},"259":{"position":[[54,7]]},"261":{"position":[[152,7]]},"302":{"position":[[1164,9]]},"413":{"position":[[654,8]]},"499":{"position":[[1954,8]]},"646":{"position":[[721,7],[950,7]]},"776":{"position":[[308,9]]},"817":{"position":[[332,8]]},"819":{"position":[[3856,7],[3905,7]]},"932":{"position":[[3694,7]]},"1043":{"position":[[75,8]]},"1108":{"position":[[800,7]]},"1234":{"position":[[1031,8],[1162,7],[1272,8]]},"1256":{"position":[[67,7],[312,7]]},"1388":{"position":[[394,8]]},"1462":{"position":[[243,8]]},"1507":{"position":[[332,8]]},"1509":{"position":[[3856,7],[3905,7]]},"1654":{"position":[[3694,7]]},"1743":{"position":[[236,7]]},"1773":{"position":[[37,7]]},"1957":{"position":[[163,9],[353,9],[445,9],[534,8],[1378,9],[1423,9],[2442,9],[2634,9],[2666,8],[3522,7],[3724,9],[3898,9],[4394,7]]},"2379":{"position":[[3694,7]]},"2576":{"position":[[317,9]]},"3160":{"position":[[772,7]]},"3206":{"position":[[235,7],[366,7]]},"3214":{"position":[[163,7],[271,8]]},"3236":{"position":[[1417,8]]},"3245":{"position":[[722,7],[827,7],[1221,11],[1266,8]]},"3247":{"position":[[138,8]]},"3251":{"position":[[2849,7]]},"3301":{"position":[[5824,8],[5841,8]]},"3325":{"position":[[1900,8],[2121,9]]},"3374":{"position":[[25,11]]},"3479":{"position":[[153,9]]}}}],["accounts/people/compani",{"_index":1378,"t":{"193":{"position":[[63,25]]}}}],["accumul",{"_index":7918,"t":{"1870":{"position":[[90,11]]},"1874":{"position":[[54,11]]},"1986":{"position":[[90,11]]},"1990":{"position":[[54,11]]}}}],["accur",{"_index":8254,"t":{"2118":{"position":[[1716,10]]},"3218":{"position":[[1398,8]]},"3220":{"position":[[22,8]]},"3222":{"position":[[406,8]]},"3224":{"position":[[777,11],[1057,8]]}}}],["accuraci",{"_index":8142,"t":{"2077":{"position":[[569,9]]}}}],["achiev",{"_index":636,"t":{"103":{"position":[[128,7]]},"166":{"position":[[330,7],[731,7]]},"178":{"position":[[2757,7]]},"235":{"position":[[149,9]]},"276":{"position":[[361,7]]},"288":{"position":[[100,9]]},"290":{"position":[[301,7]]},"325":{"position":[[908,7]]},"366":{"position":[[1682,9]]},"393":{"position":[[777,8]]},"398":{"position":[[405,8]]},"511":{"position":[[261,9]]},"740":{"position":[[617,7]]},"883":{"position":[[2143,7]]},"888":{"position":[[2298,7]]},"932":{"position":[[4578,10],[4681,10]]},"956":{"position":[[2486,10]]},"982":{"position":[[432,9]]},"1654":{"position":[[4578,10],[4681,10]]},"1937":{"position":[[303,7]]},"2100":{"position":[[371,7]]},"2229":{"position":[[417,7]]},"2265":{"position":[[244,7],[336,8]]},"2298":{"position":[[244,7],[336,8]]},"2379":{"position":[[4578,10],[4681,10]]},"2526":{"position":[[704,9]]},"2688":{"position":[[1099,9]]},"2705":{"position":[[366,8]]},"2750":{"position":[[366,8]]},"2840":{"position":[[274,8]]},"2966":{"position":[[4724,7]]},"3044":{"position":[[203,9]]},"3084":{"position":[[714,7],[745,8]]},"3086":{"position":[[260,8]]},"3126":{"position":[[376,7],[536,11]]},"3169":{"position":[[47,7]]},"3184":{"position":[[267,7],[545,9]]},"3186":{"position":[[336,8]]},"3218":{"position":[[1383,7]]},"3224":{"position":[[1838,7]]},"3227":{"position":[[191,7]]},"3249":{"position":[[756,10]]},"3272":{"position":[[782,8]]},"3518":{"position":[[825,9]]}}}],["achiv",{"_index":8658,"t":{"2560":{"position":[[176,7]]},"2966":{"position":[[2825,6]]}}}],["acid",{"_index":9620,"t":{"2947":{"position":[[3304,4]]}}}],["acknowledg",{"_index":8471,"t":{"2306":{"position":[[591,11]]},"2338":{"position":[[547,11]]},"2944":{"position":[[506,12]]},"2947":{"position":[[3237,13]]}}}],["acknowledged\":tru",{"_index":6241,"t":{"1307":{"position":[[72,21]]}}}],["acl",{"_index":5765,"t":{"1161":{"position":[[1987,3],[2158,3],[2325,3],[2499,3],[2678,3],[2837,3],[3012,3],[3191,3],[3358,3],[3529,3],[3692,3]]}}}],["acl_cinder.services.a.regiocloud.tech",{"_index":5789,"t":{"1161":{"position":[[3195,37],[3320,37]]}}}],["acl_console.services.a.regiocloud.tech",{"_index":5783,"t":{"1161":{"position":[[2841,38],[2973,38]]}}}],["acl_designate.services.a.regiocloud.tech",{"_index":5786,"t":{"1161":{"position":[[3016,40],[3150,40]]}}}],["acl_glance.services.a.regiocloud.tech",{"_index":5771,"t":{"1161":{"position":[[2162,37],[2287,37]]}}}],["acl_ironic.services.a.regiocloud.tech",{"_index":5797,"t":{"1161":{"position":[[3696,37],[3821,37]]}}}],["acl_keystone.services.a.regiocloud.tech",{"_index":5766,"t":{"1161":{"position":[[1991,39],[2118,39]]}}}],["acl_neutron.services.a.regiocloud.tech",{"_index":5774,"t":{"1161":{"position":[[2329,38],[2460,38]]}}}],["acl_nova.services.a.regiocloud.tech",{"_index":5780,"t":{"1161":{"position":[[2682,35],[2801,35]]}}}],["acl_octavia.services.a.regiocloud.tech",{"_index":5792,"t":{"1161":{"position":[[3362,38],[3490,38]]}}}],["acl_placement.services.a.regiocloud.tech",{"_index":5777,"t":{"1161":{"position":[[2503,40],[2637,40]]}}}],["acl_swift.services.a.regiocloud.tech",{"_index":5795,"t":{"1161":{"position":[[3533,36],[3655,36]]}}}],["acm",{"_index":3461,"t":{"646":{"position":[[716,4],[753,4],[774,4],[1610,4]]}}}],["acquir",{"_index":9376,"t":{"2799":{"position":[[223,7]]}}}],["act",{"_index":1179,"t":{"172":{"position":[[502,3]]},"530":{"position":[[485,4]]},"1067":{"position":[[3117,3]]},"1444":{"position":[[194,9],[266,3]]},"1878":{"position":[[18,3]]},"1892":{"position":[[658,3]]},"1994":{"position":[[18,3]]},"2008":{"position":[[658,3]]},"2911":{"position":[[399,3]]}}}],["action",{"_index":178,"t":{"10":{"position":[[1886,6]]},"124":{"position":[[14,7]]},"170":{"position":[[673,6]]},"212":{"position":[[237,7]]},"245":{"position":[[436,7]]},"268":{"position":[[73,7]]},"319":{"position":[[454,7]]},"391":{"position":[[1023,6]]},"472":{"position":[[53,7]]},"604":{"position":[[7965,6],[8200,6]]},"694":{"position":[[156,6]]},"756":{"position":[[275,8],[329,7]]},"833":{"position":[[121,6]]},"835":{"position":[[107,6]]},"945":{"position":[[63,6]]},"1167":{"position":[[3900,7]]},"1267":{"position":[[69,7]]},"1317":{"position":[[2199,6],[5794,6]]},"1430":{"position":[[1305,6]]},"1548":{"position":[[121,6]]},"1550":{"position":[[107,6]]},"1667":{"position":[[63,6]]},"1678":{"position":[[996,6],[1507,6]]},"1731":{"position":[[92,7],[564,7]]},"1734":{"position":[[140,7]]},"1736":{"position":[[165,6]]},"1880":{"position":[[47,6],[580,6]]},"1890":{"position":[[236,7]]},"1906":{"position":[[73,6]]},"1908":{"position":[[47,7]]},"1911":{"position":[[21,6],[562,6]]},"1996":{"position":[[47,6],[580,6]]},"2006":{"position":[[236,7]]},"2022":{"position":[[73,6]]},"2024":{"position":[[47,7]]},"2027":{"position":[[21,6],[562,6]]},"2049":{"position":[[32,7]]},"2053":{"position":[[64,6]]},"2059":{"position":[[32,7]]},"2118":{"position":[[2361,7]]},"2209":{"position":[[77,7]]},"2250":{"position":[[457,7]]},"2392":{"position":[[63,6]]},"2434":{"position":[[275,7]]},"2566":{"position":[[6120,7],[6835,7],[9830,7],[10775,7],[13911,7]]},"2677":{"position":[[953,7]]},"3109":{"position":[[363,6],[570,6],[1593,6],[2784,6]]},"3206":{"position":[[97,6]]},"3227":{"position":[[172,6]]},"3236":{"position":[[2647,8]]},"3251":{"position":[[3746,7],[3872,7],[6028,7]]},"3266":{"position":[[113,7]]},"3400":{"position":[[1580,6]]},"3457":{"position":[[589,6]]},"3482":{"position":[[2438,6]]}}}],["action.auto_create_index",{"_index":5887,"t":{"1167":{"position":[[1941,25],[2806,25]]}}}],["action.pi",{"_index":3928,"t":{"833":{"position":[[93,9]]},"835":{"position":[[89,9]]},"1548":{"position":[[93,9]]},"1550":{"position":[[89,9]]}}}],["activ",{"_index":17,"t":{"4":{"position":[[174,8]]},"79":{"position":[[57,10]]},"210":{"position":[[1011,8]]},"238":{"position":[[335,6]]},"245":{"position":[[674,6]]},"323":{"position":[[172,9]]},"342":{"position":[[129,6]]},"398":{"position":[[417,6]]},"503":{"position":[[548,6],[597,6]]},"505":{"position":[[111,7]]},"509":{"position":[[354,6]]},"511":{"position":[[213,6]]},"780":{"position":[[625,10],[702,8]]},"790":{"position":[[838,6]]},"796":{"position":[[652,6]]},"798":{"position":[[647,6]]},"800":{"position":[[343,6]]},"850":{"position":[[9168,6]]},"903":{"position":[[2978,8]]},"913":{"position":[[3572,8]]},"947":{"position":[[278,6]]},"954":{"position":[[247,8]]},"956":{"position":[[1691,7]]},"1025":{"position":[[127,8]]},"1082":{"position":[[169,9]]},"1084":{"position":[[127,9]]},"1118":{"position":[[114,6],[280,6]]},"1294":{"position":[[411,7]]},"1321":{"position":[[503,6],[1355,6]]},"1342":{"position":[[568,6],[744,6]]},"1364":{"position":[[174,6],[251,6],[328,6],[855,6],[902,6],[949,6]]},"1373":{"position":[[103,6]]},"1484":{"position":[[9168,6]]},"1527":{"position":[[838,6]]},"1533":{"position":[[652,6]]},"1535":{"position":[[647,6]]},"1537":{"position":[[343,6]]},"1569":{"position":[[656,9]]},"1585":{"position":[[1372,8]]},"1591":{"position":[[555,10]]},"1625":{"position":[[2978,8]]},"1635":{"position":[[3572,8]]},"1669":{"position":[[278,6]]},"1728":{"position":[[1471,8]]},"1843":{"position":[[1044,6],[1115,6]]},"1847":{"position":[[417,6]]},"1892":{"position":[[1027,6]]},"2008":{"position":[[1027,6]]},"2083":{"position":[[184,6],[255,6]]},"2306":{"position":[[243,6]]},"2350":{"position":[[2978,8]]},"2360":{"position":[[3572,8]]},"2394":{"position":[[278,6]]},"2482":{"position":[[308,6],[405,8],[452,8]]},"2540":{"position":[[222,10]]},"2647":{"position":[[299,6]]},"2665":{"position":[[44,8]]},"2815":{"position":[[1296,6]]},"2881":{"position":[[213,8]]},"3023":{"position":[[270,8]]},"3124":{"position":[[150,8]]},"3158":{"position":[[549,8]]},"3160":{"position":[[467,8]]},"3245":{"position":[[1445,6]]},"3251":{"position":[[1463,6],[3182,6]]},"3280":{"position":[[484,8],[918,8]]},"3293":{"position":[[462,6]]},"3299":{"position":[[947,8],[1972,8],[2271,8],[3335,8],[3514,8],[3785,8],[4558,8],[5055,8],[5508,8],[5617,8]]},"3301":{"position":[[530,8],[4274,6]]},"3316":{"position":[[1676,10],[1696,10]]},"3359":{"position":[[166,6]]},"3389":{"position":[[582,6]]},"3410":{"position":[[218,6]]},"3436":{"position":[[66,8]]}}}],["active+clean",{"_index":6394,"t":{"1321":{"position":[[268,13],[925,13]]}}}],["active/standbi",{"_index":5345,"t":{"1118":{"position":[[30,14]]}}}],["actual",{"_index":1277,"t":{"178":{"position":[[1497,8],[2284,8]]},"284":{"position":[[1379,8]]},"325":{"position":[[1698,6],[7691,8]]},"374":{"position":[[986,6]]},"491":{"position":[[360,6]]},"513":{"position":[[2290,8]]},"576":{"position":[[131,8]]},"596":{"position":[[790,6]]},"780":{"position":[[172,8]]},"899":{"position":[[319,8]]},"1349":{"position":[[92,8]]},"1395":{"position":[[631,8]]},"1397":{"position":[[298,8]]},"1419":{"position":[[1136,8]]},"1444":{"position":[[431,6]]},"1585":{"position":[[1462,8]]},"1587":{"position":[[877,6]]},"1621":{"position":[[319,8]]},"1715":{"position":[[105,8]]},"1911":{"position":[[692,6]]},"1978":{"position":[[394,8],[792,6]]},"2027":{"position":[[692,6]]},"2033":{"position":[[1852,6],[2019,6]]},"2118":{"position":[[63,6]]},"2160":{"position":[[143,8]]},"2164":{"position":[[39,6]]},"2231":{"position":[[209,8]]},"2346":{"position":[[319,8]]},"2627":{"position":[[276,6],[1460,6]]},"2713":{"position":[[369,8]]},"2858":{"position":[[370,8]]},"2899":{"position":[[299,6]]},"2947":{"position":[[996,8]]},"3003":{"position":[[60,6]]},"3014":{"position":[[820,8]]},"3218":{"position":[[1337,6]]},"3220":{"position":[[214,6]]},"3343":{"position":[[93,6]]},"3363":{"position":[[274,6]]},"3457":{"position":[[882,6]]}}}],["actuallydelete=tru",{"_index":2651,"t":{"472":{"position":[[2477,20]]}}}],["acura",{"_index":7718,"t":{"1827":{"position":[[632,5]]}}}],["ad",{"_index":1618,"t":{"245":{"position":[[562,5]]},"253":{"position":[[1742,6]]},"306":{"position":[[128,5]]},"472":{"position":[[150,5]]},"481":{"position":[[158,5]]},"499":{"position":[[1924,5]]},"604":{"position":[[5314,6],[5821,5]]},"627":{"position":[[2855,5]]},"796":{"position":[[1163,6],[1399,6]]},"798":{"position":[[1229,6],[1280,5]]},"800":{"position":[[116,5],[145,5]]},"883":{"position":[[1752,6]]},"905":{"position":[[1483,6]]},"907":{"position":[[720,6]]},"930":{"position":[[82,6]]},"932":{"position":[[4381,6]]},"984":{"position":[[440,5]]},"1012":{"position":[[381,5]]},"1014":{"position":[[517,5]]},"1043":{"position":[[701,5],[896,5]]},"1052":{"position":[[142,5]]},"1055":{"position":[[801,5],[1435,5]]},"1067":{"position":[[571,5],[1377,5],[4757,6]]},"1080":{"position":[[1358,5]]},"1112":{"position":[[1207,5],[4659,5]]},"1114":{"position":[[122,5],[3986,5]]},"1120":{"position":[[1744,5]]},"1150":{"position":[[12621,5]]},"1161":{"position":[[153,5],[299,5],[1575,6]]},"1184":{"position":[[1494,5],[1666,5],[1991,5]]},"1213":{"position":[[278,5],[975,5]]},"1224":{"position":[[1051,5]]},"1240":{"position":[[1417,5]]},"1256":{"position":[[1615,5]]},"1286":{"position":[[1646,5]]},"1288":{"position":[[201,5],[570,5]]},"1290":{"position":[[177,5],[214,6]]},"1292":{"position":[[150,6]]},"1462":{"position":[[167,6],[188,6]]},"1469":{"position":[[33,5]]},"1533":{"position":[[1163,6],[1399,6]]},"1535":{"position":[[1229,6],[1280,5]]},"1537":{"position":[[116,5],[145,5]]},"1585":{"position":[[2308,6]]},"1627":{"position":[[1483,6]]},"1629":{"position":[[720,6]]},"1652":{"position":[[82,6]]},"1654":{"position":[[4381,6]]},"1674":{"position":[[492,5],[822,5]]},"1678":{"position":[[813,5],[1042,6]]},"1684":{"position":[[1073,6]]},"1770":{"position":[[488,5]]},"1794":{"position":[[864,5]]},"1825":{"position":[[1521,5]]},"1855":{"position":[[119,6]]},"1857":{"position":[[1103,5],[1209,5]]},"1859":{"position":[[121,5],[382,5],[569,5],[651,5]]},"1865":{"position":[[254,5],[351,5]]},"1917":{"position":[[119,6]]},"1919":{"position":[[1103,5],[1209,5]]},"1921":{"position":[[121,5],[382,5],[569,5],[651,5]]},"1927":{"position":[[254,5],[351,5]]},"2065":{"position":[[356,6]]},"2237":{"position":[[59,5]]},"2248":{"position":[[493,5]]},"2267":{"position":[[59,5]]},"2288":{"position":[[72,6]]},"2298":{"position":[[967,6]]},"2300":{"position":[[59,5]]},"2315":{"position":[[183,5]]},"2317":{"position":[[112,6]]},"2321":{"position":[[436,5]]},"2352":{"position":[[1483,6]]},"2354":{"position":[[720,6]]},"2377":{"position":[[82,6]]},"2379":{"position":[[4381,6]]},"2409":{"position":[[74,6],[334,6],[557,5]]},"2420":{"position":[[170,5]]},"2463":{"position":[[621,5],[963,5],[1036,5]]},"2468":{"position":[[256,5]]},"2486":{"position":[[471,6]]},"2497":{"position":[[520,6]]},"2631":{"position":[[2028,6]]},"2939":{"position":[[619,6]]},"2942":{"position":[[752,6]]},"2947":{"position":[[3804,6]]},"2949":{"position":[[63,5]]},"2955":{"position":[[20,5]]},"2957":{"position":[[65,5]]},"2990":{"position":[[215,6]]},"3101":{"position":[[87,5],[184,6]]},"3234":{"position":[[314,5]]},"3251":{"position":[[2235,5],[5107,5]]},"3325":{"position":[[207,5],[1917,5],[2145,5]]},"3343":{"position":[[1112,5]]},"3357":{"position":[[237,6]]},"3372":{"position":[[346,6]]},"3472":{"position":[[14647,6]]},"3482":{"position":[[1416,6]]}}}],["ad1cc1",{"_index":9869,"t":{"3109":{"position":[[2368,8]]}}}],["ad848454",{"_index":3948,"t":{"840":{"position":[[60,8],[158,8]]},"1555":{"position":[[60,8],[158,8]]}}}],["adapt",{"_index":1364,"t":{"189":{"position":[[120,9]]},"247":{"position":[[3228,7]]},"505":{"position":[[368,5]]},"583":{"position":[[313,10]]},"1400":{"position":[[733,7]]},"1462":{"position":[[58,5]]},"1743":{"position":[[495,5]]},"1855":{"position":[[174,5]]},"1917":{"position":[[174,5]]},"2176":{"position":[[422,10]]},"2212":{"position":[[141,7]]},"2801":{"position":[[278,5]]},"3061":{"position":[[87,7],[466,7]]},"3071":{"position":[[2392,5]]},"3280":{"position":[[401,7]]},"3284":{"position":[[66,5],[419,7]]},"3301":{"position":[[2352,8]]},"3482":{"position":[[1640,5]]}}}],["adcd",{"_index":3998,"t":{"842":{"position":[[1438,4]]},"1557":{"position":[[1438,4]]}}}],["add",{"_index":748,"t":{"114":{"position":[[56,3]]},"116":{"position":[[166,3]]},"118":{"position":[[184,3]]},"129":{"position":[[277,3]]},"141":{"position":[[45,3]]},"147":{"position":[[266,3]]},"170":{"position":[[1440,3]]},"263":{"position":[[409,4],[480,3]]},"319":{"position":[[679,3]]},"325":{"position":[[1298,3],[4241,3]]},"381":{"position":[[598,3],[936,3]]},"427":{"position":[[281,3]]},"436":{"position":[[1590,4]]},"497":{"position":[[545,3]]},"499":{"position":[[342,3]]},"519":{"position":[[327,3]]},"600":{"position":[[1392,3]]},"604":{"position":[[4392,3],[4981,3],[6035,3]]},"627":{"position":[[2999,3],[3198,3],[5130,4]]},"648":{"position":[[674,3]]},"667":{"position":[[461,3]]},"786":{"position":[[695,3]]},"819":{"position":[[2227,3],[7518,3]]},"825":{"position":[[55,3]]},"903":{"position":[[838,3]]},"905":{"position":[[1561,3]]},"907":{"position":[[397,3]]},"913":{"position":[[2574,3],[3521,3]]},"926":{"position":[[45,3]]},"932":{"position":[[1970,3],[2455,3]]},"1012":{"position":[[60,3]]},"1014":{"position":[[56,3]]},"1027":{"position":[[222,3]]},"1029":{"position":[[215,3]]},"1037":{"position":[[45,3]]},"1041":{"position":[[188,3],[778,3]]},"1065":{"position":[[0,3],[62,3],[392,3]]},"1071":{"position":[[1024,3],[1190,3]]},"1108":{"position":[[0,3],[1250,3],[1355,3]]},"1112":{"position":[[431,3]]},"1114":{"position":[[842,3],[4444,3]]},"1146":{"position":[[92,3]]},"1150":{"position":[[6866,3],[13193,3]]},"1248":{"position":[[85,3]]},"1256":{"position":[[3241,3],[3282,3],[3320,3]]},"1288":{"position":[[484,3],[732,3]]},"1360":{"position":[[0,3],[687,3],[876,3]]},"1406":{"position":[[420,3],[450,3],[520,3]]},"1509":{"position":[[2227,3],[7518,3]]},"1515":{"position":[[55,3]]},"1523":{"position":[[695,3]]},"1585":{"position":[[2512,4],[3021,3],[3216,3],[3241,3],[3596,3]]},"1608":{"position":[[15,3],[229,3],[364,3],[447,3],[532,3],[638,3],[769,3],[900,3]]},"1610":{"position":[[13,3]]},"1625":{"position":[[838,3]]},"1627":{"position":[[1561,3]]},"1629":{"position":[[397,3]]},"1635":{"position":[[2574,3],[3521,3]]},"1648":{"position":[[45,3]]},"1654":{"position":[[1970,3],[2455,3]]},"1678":{"position":[[489,3],[1350,3],[1642,3],[2408,3]]},"1684":{"position":[[2431,3],[2753,3],[3072,3],[3393,3]]},"1699":{"position":[[38,3]]},"1701":{"position":[[256,3]]},"1728":{"position":[[358,4]]},"1743":{"position":[[1703,3],[2251,3],[2378,3],[2456,3]]},"1747":{"position":[[586,3]]},"1779":{"position":[[2232,3],[2608,3]]},"1794":{"position":[[473,3]]},"1833":{"position":[[646,3]]},"1843":{"position":[[401,3],[474,3]]},"1855":{"position":[[1253,3]]},"1859":{"position":[[431,3]]},"1865":{"position":[[534,3],[626,3]]},"1902":{"position":[[339,3]]},"1917":{"position":[[1253,3]]},"1921":{"position":[[431,3]]},"1927":{"position":[[534,3],[626,3]]},"1957":{"position":[[2484,4]]},"2018":{"position":[[339,3]]},"2053":{"position":[[1127,3]]},"2055":{"position":[[15,3]]},"2065":{"position":[[398,3]]},"2067":{"position":[[489,3],[586,3],[944,3],[1044,3]]},"2096":{"position":[[1857,3]]},"2098":{"position":[[2919,3],[3000,3]]},"2106":{"position":[[823,3]]},"2128":{"position":[[10,3]]},"2138":{"position":[[855,3]]},"2158":{"position":[[252,3]]},"2212":{"position":[[640,3]]},"2350":{"position":[[838,3]]},"2352":{"position":[[1561,3]]},"2354":{"position":[[397,3]]},"2360":{"position":[[2574,3],[3521,3]]},"2373":{"position":[[45,3]]},"2379":{"position":[[1970,3],[2455,3]]},"2463":{"position":[[916,4]]},"2468":{"position":[[846,3]]},"2631":{"position":[[212,3],[1647,3]]},"2713":{"position":[[1868,3]]},"2756":{"position":[[1614,3]]},"2858":{"position":[[1604,3]]},"2890":{"position":[[179,3]]},"3011":{"position":[[1588,3],[1740,3]]},"3016":{"position":[[75,3],[488,3]]},"3105":{"position":[[336,3]]},"3218":{"position":[[1121,3]]},"3251":{"position":[[5765,3]]},"3325":{"position":[[1684,3],[1767,3],[2059,3],[2255,3],[2722,3],[3371,3]]},"3472":{"position":[[6675,3]]}}}],["add2",{"_index":9768,"t":{"3088":{"position":[[1159,4]]}}}],["add_clust",{"_index":3300,"t":{"627":{"position":[[5095,11]]}}}],["addit",{"_index":483,"t":{"63":{"position":[[87,10]]},"129":{"position":[[281,10]]},"147":{"position":[[270,10]]},"166":{"position":[[212,10],[892,10]]},"298":{"position":[[610,8]]},"325":{"position":[[2411,10],[6079,10]]},"337":{"position":[[285,10]]},"370":{"position":[[587,10]]},"374":{"position":[[512,9]]},"381":{"position":[[1670,10]]},"447":{"position":[[443,10]]},"449":{"position":[[562,10]]},"451":{"position":[[242,10]]},"456":{"position":[[261,10]]},"458":{"position":[[328,10]]},"460":{"position":[[28,10]]},"472":{"position":[[167,10]]},"501":{"position":[[883,10]]},"633":{"position":[[956,10],[1159,10],[1410,10]]},"646":{"position":[[590,10]]},"728":{"position":[[270,10]]},"744":{"position":[[281,10]]},"764":{"position":[[310,8]]},"772":{"position":[[291,8]]},"786":{"position":[[699,10]]},"819":{"position":[[5175,10]]},"850":{"position":[[8718,10]]},"913":{"position":[[441,10]]},"942":{"position":[[245,10]]},"988":{"position":[[386,10]]},"1014":{"position":[[490,10]]},"1041":{"position":[[782,10]]},"1043":{"position":[[59,10]]},"1052":{"position":[[101,10]]},"1055":{"position":[[363,10],[2361,10],[2810,10],[3681,10]]},"1108":{"position":[[1036,10]]},"1110":{"position":[[631,10]]},"1116":{"position":[[221,10]]},"1161":{"position":[[79,10],[1383,10],[1551,10],[3859,10]]},"1165":{"position":[[2356,10]]},"1178":{"position":[[84,10]]},"1213":{"position":[[81,10]]},"1484":{"position":[[8718,10]]},"1489":{"position":[[270,10]]},"1509":{"position":[[5175,10]]},"1523":{"position":[[699,10]]},"1585":{"position":[[2801,10],[2846,10],[2929,10],[3119,10],[3426,10],[3504,10]]},"1635":{"position":[[441,10]]},"1664":{"position":[[245,10]]},"1701":{"position":[[260,10]]},"1745":{"position":[[528,8]]},"1845":{"position":[[504,10],[1591,10]]},"1855":{"position":[[1136,10]]},"1857":{"position":[[132,10]]},"1880":{"position":[[163,8]]},"1917":{"position":[[1136,10]]},"1919":{"position":[[132,10]]},"1955":{"position":[[302,8]]},"1996":{"position":[[163,8]]},"2077":{"position":[[583,10]]},"2083":{"position":[[557,10]]},"2100":{"position":[[1315,10]]},"2140":{"position":[[533,10]]},"2233":{"position":[[246,8]]},"2245":{"position":[[682,8]]},"2281":{"position":[[249,8]]},"2360":{"position":[[441,10]]},"2389":{"position":[[245,10]]},"2514":{"position":[[393,9]]},"2576":{"position":[[292,10]]},"2619":{"position":[[197,9]]},"2623":{"position":[[623,10]]},"2625":{"position":[[1630,8]]},"2627":{"position":[[598,9],[1829,9]]},"2651":{"position":[[430,10]]},"2692":{"position":[[225,10]]},"2705":{"position":[[1801,10]]},"2713":{"position":[[1475,10],[1567,10]]},"2735":{"position":[[1375,8]]},"2750":{"position":[[2103,10]]},"2774":{"position":[[1377,8]]},"2786":{"position":[[324,9]]},"2795":{"position":[[974,9]]},"2813":{"position":[[581,10]]},"2840":{"position":[[1449,10]]},"2858":{"position":[[1247,10],[1329,10]]},"2874":{"position":[[959,9]]},"2925":{"position":[[131,10]]},"2931":{"position":[[144,9]]},"2947":{"position":[[1661,10],[5904,10],[6003,10]]},"2949":{"position":[[309,10]]},"2955":{"position":[[294,10]]},"3042":{"position":[[314,10]]},"3044":{"position":[[612,10]]},"3053":{"position":[[790,10]]},"3059":{"position":[[1319,8]]},"3078":{"position":[[657,10]]},"3160":{"position":[[2312,10],[2371,8]]},"3208":{"position":[[1138,10]]},"3218":{"position":[[1125,10]]},"3222":{"position":[[621,8]]},"3236":{"position":[[1842,10]]},"3245":{"position":[[701,10],[1080,8]]},"3276":{"position":[[1622,10]]},"3301":{"position":[[4863,9],[6753,10],[7542,10]]},"3312":{"position":[[263,10],[372,8]]},"3314":{"position":[[2477,10]]},"3316":{"position":[[420,10],[1154,10]]},"3338":{"position":[[197,9]]},"3378":{"position":[[944,9]]},"3391":{"position":[[255,10]]},"3395":{"position":[[324,8]]},"3472":{"position":[[13705,8]]}}}],["addition",{"_index":783,"t":{"122":{"position":[[291,12]]},"499":{"position":[[1232,13]]},"530":{"position":[[346,13]]},"662":{"position":[[92,12]]},"819":{"position":[[7493,12]]},"1167":{"position":[[2008,12]]},"1509":{"position":[[7493,12]]},"1859":{"position":[[201,13],[340,12]]},"1921":{"position":[[201,13],[340,12]]},"1957":{"position":[[3077,12]]},"2122":{"position":[[364,13]]},"2677":{"position":[[874,13]]},"2994":{"position":[[330,13]]},"3042":{"position":[[181,12]]},"3055":{"position":[[1018,13]]},"3160":{"position":[[2279,12]]},"3266":{"position":[[569,13]]},"3272":{"position":[[548,13]]},"3465":{"position":[[1014,13]]}}}],["additional.sh",{"_index":7656,"t":{"1798":{"position":[[601,13]]},"1800":{"position":[[413,13]]}}}],["additionallabel",{"_index":8183,"t":{"2098":{"position":[[1811,20],[2119,20]]}}}],["additionalprometheusrulesmap",{"_index":8182,"t":{"2098":{"position":[[1750,32],[2061,32]]}}}],["addon",{"_index":3509,"t":{"658":{"position":[[301,5]]},"660":{"position":[[3068,6],[3167,5],[3509,5]]},"1980":{"position":[[174,7]]},"2461":{"position":[[266,6]]}}}],["address",{"_index":2062,"t":{"325":{"position":[[2403,7]]},"413":{"position":[[127,7],[517,7]]},"442":{"position":[[46,7]]},"483":{"position":[[953,7]]},"487":{"position":[[141,7],[232,7],[319,7]]},"552":{"position":[[319,9]]},"586":{"position":[[301,10]]},"633":{"position":[[742,7]]},"646":{"position":[[475,7],[1677,7],[1778,7]]},"656":{"position":[[385,7]]},"756":{"position":[[59,9]]},"895":{"position":[[894,9]]},"903":{"position":[[3620,7],[3662,9],[3730,8]]},"913":{"position":[[505,9]]},"928":{"position":[[192,7]]},"947":{"position":[[908,8],[1057,7]]},"1055":{"position":[[2605,7],[2700,7],[2832,7]]},"1067":{"position":[[1633,7],[1773,7],[1799,7],[1883,8],[2595,10],[4241,7],[4400,7],[4856,10]]},"1071":{"position":[[43,7],[369,7],[655,7],[743,7]]},"1082":{"position":[[225,7]]},"1091":{"position":[[256,10],[298,10],[437,10],[495,10],[538,10]]},"1098":{"position":[[545,10]]},"1108":{"position":[[1787,7]]},"1116":{"position":[[198,7]]},"1282":{"position":[[37,8],[49,7],[71,7],[82,7]]},"1368":{"position":[[648,10],[743,10],[839,10],[935,10],[1644,8],[2320,8]]},"1388":{"position":[[17,7],[443,7]]},"1569":{"position":[[1636,7]]},"1571":{"position":[[733,7],[1580,7]]},"1574":{"position":[[325,7]]},"1585":{"position":[[396,9],[3562,7]]},"1591":{"position":[[891,7]]},"1617":{"position":[[894,9]]},"1625":{"position":[[3620,7],[3662,9],[3730,8]]},"1635":{"position":[[505,9]]},"1650":{"position":[[192,7]]},"1669":{"position":[[908,8],[1057,7]]},"1783":{"position":[[153,9]]},"1785":{"position":[[535,7]]},"1787":{"position":[[240,7]]},"1794":{"position":[[101,8],[257,7]]},"1810":{"position":[[174,9]]},"1829":{"position":[[198,7]]},"1845":{"position":[[1553,8]]},"1855":{"position":[[671,7]]},"1917":{"position":[[671,7]]},"1951":{"position":[[74,9],[506,9]]},"2039":{"position":[[666,10]]},"2261":{"position":[[117,10]]},"2286":{"position":[[170,7]]},"2315":{"position":[[1014,10]]},"2342":{"position":[[894,9]]},"2350":{"position":[[3620,7],[3662,9],[3730,8]]},"2360":{"position":[[505,9]]},"2375":{"position":[[192,7]]},"2394":{"position":[[908,8],[1057,7]]},"2409":{"position":[[91,10]]},"2484":{"position":[[106,9]]},"2504":{"position":[[704,7]]},"2574":{"position":[[189,9]]},"2576":{"position":[[132,9]]},"2651":{"position":[[22,9]]},"2669":{"position":[[0,10]]},"2673":{"position":[[478,10]]},"2697":{"position":[[1064,7]]},"2742":{"position":[[963,7]]},"2947":{"position":[[1807,7],[2250,7],[3068,7],[5819,9]]},"3088":{"position":[[477,7]]},"3107":{"position":[[580,7]]},"3126":{"position":[[743,9]]},"3169":{"position":[[206,7]]},"3204":{"position":[[141,7]]},"3266":{"position":[[244,10]]},"3299":{"position":[[3277,7],[4500,7]]},"3459":{"position":[[627,7]]},"3465":{"position":[[759,10]]}}}],["address=$fixedip,subnet=oshm",{"_index":4366,"t":{"903":{"position":[[3437,28]]},"1625":{"position":[[3437,28]]},"2350":{"position":[[3437,28]]}}}],["addressed.(k8",{"_index":8501,"t":{"2328":{"position":[[44,14]]}}}],["addresses/flo",{"_index":3704,"t":{"772":{"position":[[143,18]]}}}],["adequ",{"_index":8637,"t":{"2540":{"position":[[38,8]]}}}],["adf6078ceba6",{"_index":5338,"t":{"1114":{"position":[[4920,12],[5306,12],[5357,12],[5812,12],[5915,12],[6210,12],[6252,12]]}}}],["adher",{"_index":596,"t":{"81":{"position":[[80,7]]},"245":{"position":[[920,6],[2004,6]]},"247":{"position":[[21,6]]},"253":{"position":[[1710,6]]},"284":{"position":[[1297,8]]},"366":{"position":[[459,6]]},"374":{"position":[[1221,7]]},"706":{"position":[[71,8]]},"1705":{"position":[[81,6]]},"2623":{"position":[[110,8]]},"2864":{"position":[[66,6]]},"3105":{"position":[[209,6]]},"3111":{"position":[[10,8]]},"3472":{"position":[[13315,7]]}}}],["adipisc",{"_index":59,"t":{"6":{"position":[[40,10]]}}}],["adit",{"_index":10164,"t":{"3325":{"position":[[3379,9]]}}}],["adjust",{"_index":1028,"t":{"166":{"position":[[612,6]]},"176":{"position":[[153,6]]},"304":{"position":[[83,8]]},"333":{"position":[[320,12]]},"519":{"position":[[74,6]]},"627":{"position":[[673,6]]},"631":{"position":[[295,6]]},"635":{"position":[[3417,8]]},"819":{"position":[[6069,9]]},"905":{"position":[[818,8]]},"913":{"position":[[3935,6]]},"917":{"position":[[208,6]]},"932":{"position":[[454,12]]},"1080":{"position":[[79,11]]},"1252":{"position":[[1212,11]]},"1430":{"position":[[543,10]]},"1509":{"position":[[6069,9]]},"1627":{"position":[[818,8]]},"1635":{"position":[[3935,6]]},"1639":{"position":[[208,6]]},"1654":{"position":[[454,12]]},"1764":{"position":[[3878,6]]},"1766":{"position":[[1501,11]]},"1814":{"position":[[84,12]]},"1825":{"position":[[79,11]]},"1841":{"position":[[427,6],[446,6]]},"1853":{"position":[[704,8]]},"1915":{"position":[[704,8]]},"1947":{"position":[[349,11]]},"2041":{"position":[[125,9],[560,12]]},"2043":{"position":[[364,6],[801,11]]},"2047":{"position":[[295,11],[344,8],[625,7]]},"2067":{"position":[[1586,11]]},"2069":{"position":[[259,11]]},"2106":{"position":[[394,11]]},"2118":{"position":[[279,6],[1599,9]]},"2152":{"position":[[168,10]]},"2253":{"position":[[110,9]]},"2352":{"position":[[818,8]]},"2360":{"position":[[3935,6]]},"2364":{"position":[[208,6]]},"2379":{"position":[[454,12]]},"3031":{"position":[[145,9]]},"3078":{"position":[[1041,8],[1196,8]]},"3080":{"position":[[299,9]]},"3082":{"position":[[1793,9]]},"3249":{"position":[[174,11]]},"3251":{"position":[[768,8]]},"3453":{"position":[[247,11]]},"3459":{"position":[[791,11]]},"3465":{"position":[[1061,8]]},"3470":{"position":[[76,11]]},"3472":{"position":[[13134,8],[14009,9]]},"3512":{"position":[[38,6]]}}}],["adjustments.(k8",{"_index":8504,"t":{"2328":{"position":[[145,16]]}}}],["admin",{"_index":993,"t":{"158":{"position":[[464,5]]},"288":{"position":[[56,5],[265,5]]},"434":{"position":[[258,5]]},"596":{"position":[[2102,6]]},"627":{"position":[[2016,6]]},"629":{"position":[[411,5]]},"641":{"position":[[1885,5],[1903,5]]},"648":{"position":[[472,5]]},"730":{"position":[[353,5],[768,6],[1565,5],[1606,5]]},"756":{"position":[[218,5]]},"813":{"position":[[77,5],[107,5],[131,5],[146,5]]},"815":{"position":[[135,5],[165,5]]},"817":{"position":[[294,5],[326,5]]},"819":{"position":[[357,5],[394,5],[472,5],[712,5],[736,5],[1408,5],[1434,5],[1456,5],[1474,5],[2093,5],[2111,5],[2553,5],[2588,5],[2610,5],[2645,5],[3850,5],[3899,5],[4404,5],[4424,5],[6807,5],[7544,5],[7609,6],[7735,6],[7814,5],[8094,5]]},"821":{"position":[[422,5],[459,5],[672,5],[801,5],[827,5],[849,5],[867,5],[1786,5],[1821,5]]},"823":{"position":[[243,5]]},"830":{"position":[[189,5]]},"901":{"position":[[30,5],[537,5],[675,5]]},"932":{"position":[[1159,5],[1217,5],[1830,5],[4484,6]]},"934":{"position":[[1323,5],[1711,5]]},"949":{"position":[[358,6],[487,5],[681,5]]},"1086":{"position":[[5,5]]},"1108":{"position":[[265,6],[312,6],[342,5],[356,7],[378,5],[417,5],[483,5],[523,5],[562,5]]},"1116":{"position":[[17,5],[167,5],[360,5]]},"1126":{"position":[[9,5]]},"1128":{"position":[[7,5]]},"1132":{"position":[[10,5]]},"1134":{"position":[[11,5]]},"1136":{"position":[[7,5]]},"1138":{"position":[[5,5]]},"1140":{"position":[[7,5]]},"1142":{"position":[[8,5]]},"1148":{"position":[[9,5]]},"1150":{"position":[[6131,6],[6349,6],[7343,6],[8113,6],[12680,5],[13180,5]]},"1153":{"position":[[7,5]]},"1171":{"position":[[5,5]]},"1186":{"position":[[8,5],[129,5],[264,5]]},"1188":{"position":[[472,5]]},"1190":{"position":[[7,5]]},"1192":{"position":[[8,5]]},"1197":{"position":[[16,5]]},"1211":{"position":[[10,5]]},"1347":{"position":[[23,5],[1492,5]]},"1351":{"position":[[173,5],[660,5],[1300,5],[1370,5],[2065,5],[2184,5]]},"1353":{"position":[[90,5]]},"1356":{"position":[[387,5]]},"1358":{"position":[[342,5],[458,5]]},"1362":{"position":[[687,5],[1306,5],[1599,5],[2328,5],[2415,5]]},"1364":{"position":[[79,5],[781,5]]},"1371":{"position":[[21,5]]},"1373":{"position":[[37,5],[193,5]]},"1375":{"position":[[21,5],[132,5],[1032,5],[1116,5]]},"1377":{"position":[[21,5],[133,5],[1027,5],[1137,5]]},"1383":{"position":[[516,5]]},"1388":{"position":[[100,5]]},"1491":{"position":[[353,5],[768,6],[1565,5],[1606,5]]},"1503":{"position":[[77,5],[107,5],[131,5],[146,5]]},"1505":{"position":[[135,5],[165,5]]},"1507":{"position":[[294,5],[326,5]]},"1509":{"position":[[357,5],[394,5],[472,5],[712,5],[736,5],[1408,5],[1434,5],[1456,5],[1474,5],[2093,5],[2111,5],[2553,5],[2588,5],[2610,5],[2645,5],[3850,5],[3899,5],[4404,5],[4424,5],[6807,5],[7544,5],[7609,6],[7735,6],[7814,5],[8094,5]]},"1511":{"position":[[422,5],[459,5],[672,5],[801,5],[827,5],[849,5],[867,5],[1786,5],[1821,5]]},"1513":{"position":[[243,5]]},"1545":{"position":[[189,5]]},"1576":{"position":[[215,5],[320,5],[463,5],[504,5],[654,5],[999,5],[1045,5]]},"1578":{"position":[[129,5]]},"1585":{"position":[[2987,5],[3175,5]]},"1623":{"position":[[30,5],[537,5],[675,5]]},"1654":{"position":[[1159,5],[1217,5],[1830,5],[4484,6]]},"1656":{"position":[[1323,5],[1711,5]]},"1671":{"position":[[358,6],[487,5],[681,5]]},"1758":{"position":[[372,6],[423,5]]},"1789":{"position":[[397,5],[499,5],[940,5],[1096,5],[1151,5],[1259,5],[1401,5]]},"1791":{"position":[[1727,5]]},"1957":{"position":[[3280,5],[3442,5],[3991,5],[4459,5]]},"2033":{"position":[[1460,5],[1501,5],[1683,5]]},"2041":{"position":[[362,5]]},"2049":{"position":[[84,5]]},"2096":{"position":[[2772,5]]},"2108":{"position":[[213,5]]},"2130":{"position":[[209,5]]},"2138":{"position":[[722,5]]},"2348":{"position":[[30,5],[537,5],[675,5]]},"2379":{"position":[[1159,5],[1217,5],[1830,5],[4484,6]]},"2381":{"position":[[1323,5],[1711,5]]},"2396":{"position":[[358,6],[487,5],[681,5]]},"2420":{"position":[[318,7]]},"2688":{"position":[[314,5]]},"2966":{"position":[[105,5],[199,5],[2058,7],[3607,5],[3887,6],[4422,6]]},"2970":{"position":[[435,5]]},"3042":{"position":[[93,5]]},"3069":{"position":[[44,5]]},"3076":{"position":[[186,6],[240,5]]},"3082":{"position":[[405,6],[586,7]]},"3099":{"position":[[393,5]]},"3109":{"position":[[135,6],[1126,6]]},"3111":{"position":[[97,5],[464,6]]},"3245":{"position":[[534,5]]},"3276":{"position":[[1602,5]]},"3325":{"position":[[453,5],[479,5],[668,6],[806,7],[1052,7],[1178,5],[1222,5],[1315,5],[1442,5],[1883,5],[1938,6],[2176,6]]},"3453":{"position":[[346,5]]},"3455":{"position":[[634,5],[695,5]]},"3459":{"position":[[62,5],[186,5],[365,5]]},"3461":{"position":[[10,5],[138,5],[253,5]]},"3463":{"position":[[726,7]]},"3465":{"position":[[22,5],[155,5],[323,5],[643,5]]},"3472":{"position":[[5974,6],[6158,6],[7152,6],[7922,6],[13396,7]]},"3475":{"position":[[81,5],[142,5],[186,5],[279,5],[361,7]]},"3482":{"position":[[1427,7],[2631,7],[2684,5],[2954,7]]},"3484":{"position":[[77,7]]}}}],["admin@$clusternam",{"_index":3288,"t":{"627":{"position":[[2194,18]]}}}],["admin@.svc",{"_index":8279,"t":{"2142":{"position":[[356,22]]}}}],["agent.conf",{"_index":6301,"t":{"1317":{"position":[[3715,10]]}}}],["agent/bin/rubi",{"_index":6475,"t":{"1337":{"position":[[232,14],[323,14]]}}}],["agent:22.0.3.20230919",{"_index":6586,"t":{"1360":{"position":[[1597,21]]}}}],["agent@testb",{"_index":6463,"t":{"1337":{"position":[[102,13]]}}}],["agent_host",{"_index":8278,"t":{"2142":{"position":[[334,13]]}}}],["agent_port",{"_index":8280,"t":{"2142":{"position":[[379,13]]}}}],["aggreg",{"_index":3652,"t":{"742":{"position":[[5,10],[136,10],[283,10],[329,9],[529,10],[577,9],[726,10],[1096,10]]},"1317":{"position":[[7187,9]]},"1383":{"position":[[5,10],[106,11],[145,10],[321,10],[467,9]]},"2235":{"position":[[345,11]]},"2719":{"position":[[1182,11],[1555,12],[1635,10]]},"2758":{"position":[[1180,11],[1556,12],[1636,10]]},"2951":{"position":[[134,10]]},"3055":{"position":[[270,10],[424,11]]},"3413":{"position":[[436,9]]}}}],["aggregate1",{"_index":6791,"t":{"1383":{"position":[[398,10]]}}}],["aggregates.yml",{"_index":6788,"t":{"1383":{"position":[[282,14]]}}}],["aggress",{"_index":6041,"t":{"1226":{"position":[[1095,10]]}}}],["agil",{"_index":2129,"t":{"327":{"position":[[575,5]]},"3016":{"position":[[262,5]]}}}],["agnost",{"_index":10216,"t":{"3400":{"position":[[389,8]]}}}],["ago",{"_index":6577,"t":{"1360":{"position":[[1264,3],[1392,3],[1517,3],[1650,3],[1795,3],[1940,3],[2077,3],[2210,3],[2339,3],[2463,3],[2604,3],[2712,3],[2842,3],[2950,3],[3060,3]]},"1368":{"position":[[1780,4],[2058,3],[2121,3],[2459,4],[2737,3],[2800,3]]},"1731":{"position":[[1212,3],[1345,3],[1457,3],[1619,3],[1743,3],[1870,3],[1991,3],[2155,3],[2280,3],[2415,3],[2551,3],[2678,3],[2813,3],[2947,3],[3080,3],[3195,3]]},"3299":{"position":[[4266,4]]}}}],["agpl",{"_index":1054,"t":{"168":{"position":[[244,6],[1350,5]]},"172":{"position":[[477,6],[677,4]]},"174":{"position":[[681,5]]},"178":{"position":[[2224,5]]}}}],["agpl'",{"_index":1284,"t":{"178":{"position":[[1933,7]]}}}],["agplv3",{"_index":1039,"t":{"166":{"position":[[999,8]]},"172":{"position":[[853,7]]},"253":{"position":[[2133,7]]}}}],["agre",{"_index":1268,"t":{"178":{"position":[[763,6]]},"193":{"position":[[144,5]]},"247":{"position":[[2090,5]]},"253":{"position":[[946,5]]},"1957":{"position":[[203,5]]},"2176":{"position":[[1297,8]]},"2233":{"position":[[552,6]]}}}],["agreement",{"_index":1269,"t":{"178":{"position":[[879,10]]},"182":{"position":[[453,11]]},"255":{"position":[[123,11]]},"2901":{"position":[[198,10]]}}}],["ah00558",{"_index":6375,"t":{"1319":{"position":[[420,8]]}}}],["ahead",{"_index":2166,"t":{"339":{"position":[[332,6]]},"2637":{"position":[[89,5]]},"2947":{"position":[[3584,5]]}}}],["aicard",{"_index":7895,"t":{"1851":{"position":[[306,7]]}}}],["aid",{"_index":5205,"t":{"1112":{"position":[[174,3]]},"2651":{"position":[[165,3]]}}}],["aim",{"_index":513,"t":{"69":{"position":[[323,3]]},"71":{"position":[[298,3]]},"91":{"position":[[33,3]]},"93":{"position":[[0,3]]},"103":{"position":[[4,3]]},"235":{"position":[[142,3]]},"276":{"position":[[175,3]]},"339":{"position":[[448,4]]},"366":{"position":[[102,5]]},"417":{"position":[[10,4]]},"460":{"position":[[10,4]]},"462":{"position":[[10,4],[529,3]]},"489":{"position":[[858,4]]},"2039":{"position":[[428,6]]},"2100":{"position":[[273,3]]},"2154":{"position":[[16,4]]},"2472":{"position":[[70,6]]},"2497":{"position":[[573,3]]},"2522":{"position":[[646,3]]},"2536":{"position":[[299,4]]},"2574":{"position":[[266,6]]},"2592":{"position":[[185,3]]},"2602":{"position":[[261,6]]},"2663":{"position":[[325,4]]},"2673":{"position":[[1297,3]]},"2795":{"position":[[1844,3]]},"3071":{"position":[[878,3]]},"3204":{"position":[[477,3]]},"3222":{"position":[[709,3]]},"3270":{"position":[[1179,4]]},"3301":{"position":[[1969,3]]},"3397":{"position":[[1436,4]]},"3413":{"position":[[375,4]]},"3477":{"position":[[106,4]]}}}],["air",{"_index":5984,"t":{"1199":{"position":[[432,3]]},"2409":{"position":[[697,3]]},"3314":{"position":[[1322,3]]}}}],["airgap",{"_index":8478,"t":{"2315":{"position":[[531,9],[591,6]]}}}],["aj6iosqsowhqn_nnbeog",{"_index":6238,"t":{"1305":{"position":[[481,20]]}}}],["ajax",{"_index":8153,"t":{"2083":{"position":[[351,4]]}}}],["aka",{"_index":4622,"t":{"934":{"position":[[1974,4]]},"1368":{"position":[[602,4],[702,4],[798,4],[894,4]]},"1656":{"position":[[1974,4]]},"2381":{"position":[[1974,4]]},"3245":{"position":[[1182,4]]}}}],["akafazov",{"_index":381,"t":{"27":{"position":[[3043,8],[3052,8],[3061,8]]}}}],["alarm",{"_index":4322,"t":{"899":{"position":[[967,6]]},"913":{"position":[[527,6]]},"947":{"position":[[193,5]]},"1621":{"position":[[967,6]]},"1635":{"position":[[527,6]]},"1669":{"position":[[193,5]]},"2196":{"position":[[1295,8]]},"2346":{"position":[[967,6]]},"2360":{"position":[[527,6]]},"2394":{"position":[[193,5]]},"2566":{"position":[[14430,9]]},"3272":{"position":[[419,6]]}}}],["alarm_email_address",{"_index":4477,"t":{"913":{"position":[[2831,19]]},"920":{"position":[[971,21]]},"1635":{"position":[[2831,19]]},"1642":{"position":[[971,21]]},"2360":{"position":[[2831,19]]},"2367":{"position":[[971,21]]}}}],["alasca",{"_index":9343,"t":{"2737":{"position":[[181,6]]},"2776":{"position":[[181,6]]}}}],["albeit",{"_index":9481,"t":{"2870":{"position":[[34,6]]},"3378":{"position":[[655,6]]}}}],["alert",{"_index":4476,"t":{"913":{"position":[[2817,8]]},"1635":{"position":[[2817,8]]},"2071":{"position":[[206,6]]},"2096":{"position":[[23,7],[177,6]]},"2098":{"position":[[365,7],[396,7],[1133,6],[1215,7],[1300,7]]},"2118":{"position":[[2340,6]]},"2212":{"position":[[317,6]]},"2360":{"position":[[2817,8]]},"2602":{"position":[[218,7]]},"3389":{"position":[[834,8]]},"3393":{"position":[[877,8]]},"3395":{"position":[[1383,8],[1432,6],[1451,6],[1527,6]]},"3397":{"position":[[1548,6],[1611,6],[2433,6]]},"3400":{"position":[[1392,6],[1474,6],[1493,6],[1517,5]]}}}],["alertmanag",{"_index":8130,"t":{"2071":{"position":[[53,12],[161,12],[301,12],[397,12],[581,12],[627,12]]},"2108":{"position":[[66,12],[412,12]]},"2110":{"position":[[709,12],[816,13],[853,12]]},"2130":{"position":[[66,12],[408,12]]},"2138":{"position":[[306,12]]},"3391":{"position":[[144,12]]},"3395":{"position":[[197,13]]},"3397":{"position":[[1282,12]]}}}],["alertmanager/matrix",{"_index":8132,"t":{"2071":{"position":[[281,19],[377,19]]}}}],["alertmanagerspec",{"_index":8235,"t":{"2110":{"position":[[830,16]]}}}],["algorithm",{"_index":1840,"t":{"280":{"position":[[167,11]]},"284":{"position":[[1347,9]]},"1894":{"position":[[676,9]]},"1900":{"position":[[238,9],[371,10]]},"2010":{"position":[[676,9]]},"2016":{"position":[[238,9],[371,10]]},"2872":{"position":[[1255,9]]}}}],["alia",{"_index":2962,"t":{"534":{"position":[[197,5]]},"1317":{"position":[[183,5]]},"1957":{"position":[[1095,5],[1231,6]]},"3325":{"position":[[2847,7]]}}}],["alias",{"_index":3277,"t":{"627":{"position":[[104,8]]},"2737":{"position":[[269,7]]},"2776":{"position":[[269,7]]}}}],["alic",{"_index":7608,"t":{"1789":{"position":[[872,5]]},"1791":{"position":[[378,5],[505,6],[1900,5],[2304,5],[3109,5]]},"1959":{"position":[[1285,6]]}}}],["align",{"_index":570,"t":{"79":{"position":[[47,5],[251,5],[352,5]]},"245":{"position":[[426,5]]},"366":{"position":[[249,8],[1218,6]]},"372":{"position":[[316,9]]},"374":{"position":[[774,6]]},"726":{"position":[[155,9]]},"1487":{"position":[[155,9]]},"1900":{"position":[[524,5]]},"1951":{"position":[[140,10],[544,7]]},"2016":{"position":[[524,5]]},"2737":{"position":[[212,10]]},"2776":{"position":[[212,10]]},"3224":{"position":[[1622,6]]},"3472":{"position":[[168,5]]},"3482":{"position":[[48,5]]}}}],["alik",{"_index":455,"t":{"58":{"position":[[103,6]]},"3099":{"position":[[249,6]]}}}],["aliquam",{"_index":69,"t":{"6":{"position":[[133,7]]}}}],["aliv",{"_index":4312,"t":{"895":{"position":[[2221,5]]},"911":{"position":[[584,5]]},"1362":{"position":[[1822,5]]},"1617":{"position":[[2221,5]]},"1633":{"position":[[584,5]]},"2342":{"position":[[2221,5]]},"2358":{"position":[[584,5]]},"2947":{"position":[[1064,5]]},"3376":{"position":[[721,5]]}}}],["all:!manag",{"_index":6019,"t":{"1224":{"position":[[2911,14],[3728,14]]}}}],["allevi",{"_index":8392,"t":{"2224":{"position":[[171,11]]}}}],["allianc",{"_index":3582,"t":{"694":{"position":[[78,8]]},"2434":{"position":[[147,8]]},"2688":{"position":[[1805,8],[1911,8]]}}}],["alloc",{"_index":2769,"t":{"487":{"position":[[2057,9],[2187,9]]},"956":{"position":[[1360,10]]},"1165":{"position":[[1486,10]]},"2709":{"position":[[790,8],[910,10]]},"2711":{"position":[[1154,8],[1410,9]]},"2754":{"position":[[931,8],[1051,10]]},"2844":{"position":[[718,8],[838,10]]},"2856":{"position":[[1131,8],[1388,9]]},"2933":{"position":[[683,8],[941,9]]},"2949":{"position":[[1128,9]]},"3372":{"position":[[307,10],[701,10],[756,10]]},"3436":{"position":[[373,10]]}}}],["allocation_pool_end",{"_index":7102,"t":{"1585":{"position":[[3324,20]]}}}],["allocation_pool_start",{"_index":7100,"t":{"1585":{"position":[[3286,22]]}}}],["alloct",{"_index":3816,"t":{"819":{"position":[[163,9]]},"1509":{"position":[[163,9]]}}}],["allow",{"_index":875,"t":{"135":{"position":[[49,7]]},"151":{"position":[[25,7]]},"170":{"position":[[683,8],[2121,5]]},"174":{"position":[[1376,5]]},"178":{"position":[[1166,6]]},"184":{"position":[[489,5],[809,5]]},"200":{"position":[[111,7]]},"210":{"position":[[758,5]]},"247":{"position":[[2245,5]]},"282":{"position":[[622,5]]},"298":{"position":[[43,5]]},"331":{"position":[[109,6]]},"335":{"position":[[768,8]]},"379":{"position":[[705,5]]},"428":{"position":[[1823,5]]},"436":{"position":[[431,5]]},"471":{"position":[[1006,5]]},"483":{"position":[[807,6]]},"485":{"position":[[1587,5]]},"487":{"position":[[3182,6],[3325,6]]},"501":{"position":[[171,5]]},"513":{"position":[[669,5],[2513,5]]},"530":{"position":[[872,6]]},"583":{"position":[[294,6]]},"596":{"position":[[2510,7],[2594,7],[2673,7]]},"604":{"position":[[5452,5],[5462,5],[5513,5],[5524,5]]},"609":{"position":[[1636,8]]},"627":{"position":[[2945,8]]},"633":{"position":[[94,6],[784,6],[2096,7],[2450,5]]},"635":{"position":[[1875,6]]},"654":{"position":[[220,6]]},"660":{"position":[[2274,5],[2295,5]]},"740":{"position":[[169,6]]},"744":{"position":[[357,6]]},"772":{"position":[[457,6]]},"774":{"position":[[203,6]]},"883":{"position":[[186,6],[582,6],[1539,6],[2272,6]]},"888":{"position":[[1337,6],[2009,6],[2419,6]]},"903":{"position":[[902,6]]},"907":{"position":[[492,5]]},"909":{"position":[[584,6],[2133,6]]},"920":{"position":[[558,8],[814,6]]},"932":{"position":[[1285,5],[4264,5],[4519,6]]},"956":{"position":[[254,6],[892,6]]},"977":{"position":[[532,8],[1344,8],[2185,6]]},"1025":{"position":[[106,6]]},"1089":{"position":[[2481,5]]},"1124":{"position":[[691,5]]},"1150":{"position":[[6336,5],[7330,5],[8100,5],[9074,5],[10719,5]]},"1165":{"position":[[1956,5],[3185,6]]},"1184":{"position":[[1345,5]]},"1201":{"position":[[5,6]]},"1203":{"position":[[5,6]]},"1323":{"position":[[50,6]]},"1331":{"position":[[54,6]]},"1351":{"position":[[107,6]]},"1625":{"position":[[902,6]]},"1629":{"position":[[492,5]]},"1631":{"position":[[584,6],[2133,6]]},"1642":{"position":[[558,8],[814,6]]},"1654":{"position":[[1285,5],[4264,5],[4519,6]]},"1695":{"position":[[49,7]]},"1745":{"position":[[211,6]]},"1766":{"position":[[790,6]]},"1853":{"position":[[141,8],[234,5]]},"1855":{"position":[[159,5],[770,6]]},"1857":{"position":[[360,5],[1186,8]]},"1863":{"position":[[317,5],[493,6],[661,6],[833,6],[1009,6]]},"1888":{"position":[[289,5]]},"1915":{"position":[[141,8],[234,5]]},"1917":{"position":[[159,5],[770,6]]},"1919":{"position":[[360,5],[1186,8]]},"1925":{"position":[[317,5],[493,6],[661,6],[833,6],[1009,6]]},"1939":{"position":[[105,6]]},"1953":{"position":[[250,5]]},"1955":{"position":[[231,5],[449,5]]},"1963":{"position":[[514,6]]},"2004":{"position":[[289,5]]},"2047":{"position":[[180,6],[645,5]]},"2075":{"position":[[484,6]]},"2079":{"position":[[302,6]]},"2085":{"position":[[152,8],[619,6]]},"2164":{"position":[[181,5]]},"2188":{"position":[[146,5]]},"2250":{"position":[[25,5],[732,6]]},"2253":{"position":[[425,8]]},"2283":{"position":[[964,8],[1231,6]]},"2315":{"position":[[521,5],[1239,5],[1412,6],[1477,6]]},"2350":{"position":[[902,6]]},"2354":{"position":[[492,5]]},"2356":{"position":[[584,6],[2133,6]]},"2367":{"position":[[558,8],[814,6]]},"2379":{"position":[[1285,5],[4264,5],[4519,6]]},"2407":{"position":[[378,5]]},"2472":{"position":[[80,5]]},"2540":{"position":[[388,6]]},"2548":{"position":[[293,8]]},"2560":{"position":[[110,5]]},"2562":{"position":[[80,6]]},"2625":{"position":[[240,5],[272,8]]},"2675":{"position":[[465,6]]},"2700":{"position":[[674,6],[755,6]]},"2707":{"position":[[99,7]]},"2709":{"position":[[435,5]]},"2711":{"position":[[651,6],[841,6]]},"2713":{"position":[[165,6],[272,7]]},"2719":{"position":[[1506,5]]},"2723":{"position":[[806,7]]},"2731":{"position":[[282,5],[896,5],[1196,5]]},"2735":{"position":[[319,5]]},"2745":{"position":[[674,6],[755,6]]},"2752":{"position":[[99,7]]},"2754":{"position":[[435,5]]},"2756":{"position":[[346,7]]},"2758":{"position":[[1507,5]]},"2762":{"position":[[819,7]]},"2764":{"position":[[1317,6]]},"2770":{"position":[[282,5],[896,5],[1219,5]]},"2774":{"position":[[455,5]]},"2801":{"position":[[262,6]]},"2807":{"position":[[291,8]]},"2809":{"position":[[778,9],[857,9]]},"2822":{"position":[[19,6]]},"2842":{"position":[[105,7]]},"2844":{"position":[[363,5]]},"2848":{"position":[[764,7]]},"2856":{"position":[[629,6],[819,6]]},"2858":{"position":[[165,6],[272,7]]},"2860":{"position":[[282,5],[857,5],[1192,5]]},"2879":{"position":[[148,7]]},"2886":{"position":[[155,5]]},"2933":{"position":[[123,6],[244,6]]},"2942":{"position":[[241,6]]},"2947":{"position":[[5644,6]]},"2955":{"position":[[656,5]]},"2979":{"position":[[32,7]]},"2987":{"position":[[798,9]]},"3011":{"position":[[482,5]]},"3016":{"position":[[246,5],[334,8]]},"3053":{"position":[[446,6]]},"3059":{"position":[[758,6]]},"3069":{"position":[[216,6]]},"3074":{"position":[[149,8]]},"3082":{"position":[[704,5],[806,8],[1787,5],[1854,8]]},"3084":{"position":[[614,5]]},"3086":{"position":[[72,5],[191,5],[339,5],[514,5]]},"3088":{"position":[[95,7]]},"3092":{"position":[[201,7]]},"3101":{"position":[[487,5]]},"3111":{"position":[[262,7]]},"3160":{"position":[[1625,6]]},"3182":{"position":[[529,6],[699,5],[926,6],[1346,5],[1614,5],[1731,5]]},"3208":{"position":[[1443,5]]},"3210":{"position":[[150,6],[486,8],[557,5]]},"3220":{"position":[[85,6]]},"3236":{"position":[[1935,5],[2040,6]]},"3251":{"position":[[1138,6],[6244,5]]},"3253":{"position":[[303,5]]},"3276":{"position":[[2528,6]]},"3301":{"position":[[2202,5],[3389,6]]},"3314":{"position":[[478,5],[588,6],[881,7],[951,5],[1113,6],[1212,6],[1758,5],[2244,5],[3128,5]]},"3325":{"position":[[2607,5]]},"3347":{"position":[[46,6]]},"3376":{"position":[[745,5]]},"3446":{"position":[[99,6]]},"3457":{"position":[[200,6]]},"3459":{"position":[[879,8]]},"3465":{"position":[[942,6]]},"3472":{"position":[[6145,5],[7139,5],[7909,5],[8883,5],[10528,5]]},"3482":{"position":[[843,5],[1158,5],[1856,8],[2249,8]]}}}],["allow_org_cr",{"_index":4570,"t":{"932":{"position":[[1461,16]]},"1654":{"position":[[1461,16]]},"2379":{"position":[[1461,16]]}}}],["allow_sign_up",{"_index":4569,"t":{"932":{"position":[[1435,13]]},"1654":{"position":[[1435,13]]},"2379":{"position":[[1435,13]]}}}],["allowlist",{"_index":9750,"t":{"3084":{"position":[[552,12]]}}}],["almalinux",{"_index":3800,"t":{"805":{"position":[[256,9]]},"1542":{"position":[[256,9]]}}}],["alon",{"_index":3066,"t":{"596":{"position":[[2790,5]]},"1857":{"position":[[64,5]]},"1919":{"position":[[64,5]]},"3059":{"position":[[150,5]]},"3380":{"position":[[303,5]]}}}],["along",{"_index":2466,"t":{"427":{"position":[[33,5]]},"471":{"position":[[33,5]]},"499":{"position":[[1154,5],[2751,5]]},"513":{"position":[[1392,5]]},"744":{"position":[[508,5]]},"922":{"position":[[199,5]]},"1644":{"position":[[199,5]]},"2152":{"position":[[745,5]]},"2229":{"position":[[496,5]]},"2369":{"position":[[199,5]]},"2858":{"position":[[1203,5]]},"2947":{"position":[[2031,5]]}}}],["alongsid",{"_index":2163,"t":{"339":{"position":[[248,9]]},"2270":{"position":[[0,9]]},"2310":{"position":[[29,9]]},"2400":{"position":[[59,9]]},"2456":{"position":[[59,9]]},"2461":{"position":[[627,9]]},"2550":{"position":[[288,9]]}}}],["alpha",{"_index":2167,"t":{"339":{"position":[[413,5]]}}}],["alphebet",{"_index":9710,"t":{"3029":{"position":[[498,14]]}}}],["alpin",{"_index":7341,"t":{"1731":{"position":[[2762,6]]}}}],["alreadi",{"_index":991,"t":{"158":{"position":[[306,7]]},"170":{"position":[[803,7]]},"325":{"position":[[1131,7],[7373,7]]},"349":{"position":[[730,7]]},"398":{"position":[[212,7]]},"590":{"position":[[2449,7]]},"604":{"position":[[2397,7],[5976,7],[10573,7]]},"650":{"position":[[1456,7]]},"772":{"position":[[724,7]]},"796":{"position":[[320,7]]},"932":{"position":[[2828,8]]},"1041":{"position":[[572,7]]},"1043":{"position":[[535,7]]},"1067":{"position":[[2277,7]]},"1108":{"position":[[900,7]]},"1213":{"position":[[389,7]]},"1224":{"position":[[231,7],[409,7],[625,7],[3265,7]]},"1258":{"position":[[397,7]]},"1284":{"position":[[567,7]]},"1292":{"position":[[439,7]]},"1344":{"position":[[161,7]]},"1477":{"position":[[139,7]]},"1533":{"position":[[320,7]]},"1654":{"position":[[2828,8]]},"1820":{"position":[[572,7]]},"1829":{"position":[[75,7]]},"1845":{"position":[[571,7],[2382,7],[2470,7]]},"1849":{"position":[[888,7]]},"1855":{"position":[[381,7],[700,7],[1418,7]]},"1857":{"position":[[570,7]]},"1908":{"position":[[884,7]]},"1917":{"position":[[381,7],[700,7],[1418,7]]},"1919":{"position":[[570,7]]},"1974":{"position":[[525,8]]},"1978":{"position":[[403,7]]},"1980":{"position":[[470,8]]},"2024":{"position":[[884,7]]},"2039":{"position":[[658,7]]},"2071":{"position":[[702,7]]},"2089":{"position":[[83,7]]},"2110":{"position":[[1080,7]]},"2120":{"position":[[630,7]]},"2146":{"position":[[152,7],[247,7]]},"2158":{"position":[[858,7]]},"2176":{"position":[[1464,8]]},"2196":{"position":[[6,7]]},"2209":{"position":[[135,7]]},"2310":{"position":[[800,7]]},"2321":{"position":[[684,7]]},"2379":{"position":[[2828,8]]},"2502":{"position":[[723,7]]},"2764":{"position":[[1285,7]]},"2779":{"position":[[244,7]]},"2795":{"position":[[1067,7],[1314,7]]},"2809":{"position":[[678,7]]},"2881":{"position":[[100,7]]},"2901":{"position":[[1145,7]]},"2913":{"position":[[283,7]]},"2966":{"position":[[2595,7]]},"3011":{"position":[[942,7],[2672,7]]},"3039":{"position":[[169,7]]},"3061":{"position":[[33,7],[792,7]]},"3063":{"position":[[977,7]]},"3071":{"position":[[1098,7]]},"3082":{"position":[[640,7],[1157,7],[1641,7]]},"3182":{"position":[[994,7]]},"3236":{"position":[[170,7]]},"3245":{"position":[[327,7]]},"3274":{"position":[[345,7]]},"3363":{"position":[[331,7]]},"3415":{"position":[[56,7]]},"3438":{"position":[[287,7]]},"3444":{"position":[[176,7]]},"3461":{"position":[[111,7]]},"3482":{"position":[[585,7]]}}}],["alright",{"_index":8065,"t":{"1978":{"position":[[657,8]]}}}],["alsoi",{"_index":3864,"t":{"819":{"position":[[6785,5]]},"1509":{"position":[[6785,5]]}}}],["alter",{"_index":2865,"t":{"499":{"position":[[254,8]]}}}],["altern",{"_index":145,"t":{"10":{"position":[[1369,13]]},"75":{"position":[[72,12]]},"282":{"position":[[247,14]]},"331":{"position":[[30,11]]},"393":{"position":[[1499,11]]},"407":{"position":[[85,14]]},"432":{"position":[[85,14]]},"905":{"position":[[428,14]]},"934":{"position":[[397,11]]},"1150":{"position":[[12590,14]]},"1165":{"position":[[2935,11]]},"1224":{"position":[[1222,13],[1601,13]]},"1627":{"position":[[428,14]]},"1656":{"position":[[397,11]]},"1908":{"position":[[1048,11]]},"1947":{"position":[[414,12]]},"1970":{"position":[[85,11]]},"1982":{"position":[[1209,14]]},"1984":{"position":[[819,14]]},"2024":{"position":[[1048,11]]},"2096":{"position":[[2159,14]]},"2098":{"position":[[3470,14]]},"2257":{"position":[[223,11]]},"2321":{"position":[[220,12]]},"2352":{"position":[[428,14]]},"2381":{"position":[[397,11]]},"2647":{"position":[[3,11]]},"2688":{"position":[[714,14]]},"2874":{"position":[[212,14]]},"3014":{"position":[[728,13]]},"3446":{"position":[[324,13]]}}}],["although",{"_index":2138,"t":{"331":{"position":[[193,8]]},"333":{"position":[[247,8]]},"349":{"position":[[773,8]]},"899":{"position":[[449,8]]},"911":{"position":[[1106,8]]},"1621":{"position":[[449,8]]},"1633":{"position":[[1106,8]]},"2346":{"position":[[449,8]]},"2358":{"position":[[1106,8]]},"2947":{"position":[[625,8]]},"3078":{"position":[[995,8]]},"3222":{"position":[[263,8]]}}}],["altogeth",{"_index":9383,"t":{"2811":{"position":[[61,10]]}}}],["alway",{"_index":866,"t":{"133":{"position":[[186,6],[311,6]]},"135":{"position":[[11,6]]},"139":{"position":[[52,6],[174,6]]},"143":{"position":[[16,6]]},"147":{"position":[[35,6]]},"313":{"position":[[161,6]]},"325":{"position":[[5559,6],[5801,6],[7236,6],[7611,6]]},"460":{"position":[[308,6],[437,6]]},"598":{"position":[[1415,6]]},"615":{"position":[[799,6]]},"631":{"position":[[949,6]]},"819":{"position":[[7581,6]]},"846":{"position":[[89,6]]},"888":{"position":[[1653,6]]},"980":{"position":[[129,6],[301,6]]},"986":{"position":[[327,6]]},"995":{"position":[[21,6]]},"1055":{"position":[[387,6]]},"1063":{"position":[[617,6]]},"1069":{"position":[[109,6]]},"1073":{"position":[[27,6]]},"1080":{"position":[[8,6]]},"1112":{"position":[[1045,6]]},"1120":{"position":[[316,6]]},"1167":{"position":[[3649,6]]},"1224":{"position":[[3685,6]]},"1234":{"position":[[371,6]]},"1256":{"position":[[261,6],[821,6]]},"1292":{"position":[[568,6]]},"1480":{"position":[[89,6]]},"1509":{"position":[[7581,6]]},"1610":{"position":[[302,6]]},"1690":{"position":[[1856,6]]},"1695":{"position":[[11,6]]},"1697":{"position":[[52,6],[175,6]]},"1701":{"position":[[33,6]]},"1736":{"position":[[64,6]]},"1766":{"position":[[1101,6]]},"1783":{"position":[[483,6]]},"1825":{"position":[[8,6]]},"1827":{"position":[[123,6],[353,6]]},"1835":{"position":[[405,6]]},"1853":{"position":[[873,6]]},"1857":{"position":[[78,6]]},"1863":{"position":[[104,6]]},"1915":{"position":[[873,6]]},"1919":{"position":[[78,6]]},"1925":{"position":[[104,6]]},"2647":{"position":[[1030,6]]},"2695":{"position":[[92,6]]},"2697":{"position":[[922,6]]},"2719":{"position":[[634,6]]},"2740":{"position":[[92,6]]},"2742":{"position":[[821,6]]},"2758":{"position":[[632,6]]},"2830":{"position":[[92,6]]},"2832":{"position":[[922,6]]},"2895":{"position":[[126,6]]},"2913":{"position":[[366,6]]},"2960":{"position":[[434,6]]},"2966":{"position":[[891,6]]},"3033":{"position":[[9,6],[134,6]]},"3071":{"position":[[678,6]]},"3084":{"position":[[489,6]]},"3097":{"position":[[205,6],[300,6]]},"3101":{"position":[[174,6]]},"3111":{"position":[[405,6]]},"3195":{"position":[[231,6]]},"3227":{"position":[[50,6]]},"3251":{"position":[[698,6],[1970,6]]},"3262":{"position":[[76,6]]},"3357":{"position":[[955,6]]}}}],["alwaysallow",{"_index":9981,"t":{"3236":{"position":[[2544,11]]}}}],["amazon",{"_index":3681,"t":{"756":{"position":[[188,6]]}}}],["amber",{"_index":4416,"t":{"909":{"position":[[1502,5]]},"932":{"position":[[3571,5]]},"1631":{"position":[[1502,5]]},"1654":{"position":[[3571,5]]},"2356":{"position":[[1502,5]]},"2379":{"position":[[3571,5]]}}}],["ambigu",{"_index":9036,"t":{"2644":{"position":[[146,9]]},"3078":{"position":[[63,10]]}}}],["amd",{"_index":5950,"t":{"1174":{"position":[[18,3]]},"2484":{"position":[[463,3]]},"2697":{"position":[[1380,3]]},"2700":{"position":[[396,4]]},"2719":{"position":[[920,3]]},"2723":{"position":[[248,5],[898,4]]},"2725":{"position":[[279,3],[347,4]]},"2727":{"position":[[314,3],[456,3]]},"2731":{"position":[[800,3]]},"2742":{"position":[[1279,3]]},"2745":{"position":[[396,4]]},"2758":{"position":[[918,3]]},"2762":{"position":[[261,5],[911,4]]},"2764":{"position":[[307,3],[568,4],[1755,3]]},"2766":{"position":[[472,3],[656,3]]},"2770":{"position":[[800,3]]},"2835":{"position":[[337,4]]},"2848":{"position":[[248,5]]},"2850":{"position":[[256,4]]},"2852":{"position":[[691,3],[807,3]]},"2860":{"position":[[761,3]]}}}],["amd64",{"_index":4106,"t":{"850":{"position":[[3411,5],[4097,5],[4349,5],[5099,5],[9656,5],[9953,5]]},"1484":{"position":[[3411,5],[4097,5],[4349,5],[5099,5],[9656,5],[9953,5]]},"1764":{"position":[[345,5],[458,5],[571,5],[684,5],[797,5],[910,5],[1023,5],[1136,5],[1249,5],[1362,5],[1475,5],[1588,5],[1701,5],[1814,5],[1925,5],[2036,5],[2147,5],[2258,5],[2369,5],[2480,5],[2591,5],[2702,5],[2813,5],[2924,5],[3035,5],[3146,5]]}}}],["amd64.img",{"_index":3779,"t":{"796":{"position":[[941,9],[1047,9]]},"850":{"position":[[6339,9],[6567,9],[7132,9],[7385,9],[7925,9],[8153,9],[8667,11]]},"1484":{"position":[[6339,9],[6567,9],[7132,9],[7385,9],[7925,9],[8153,9],[8667,11]]},"1533":{"position":[[941,9],[1047,9]]}}}],["amd64.iso",{"_index":6060,"t":{"1234":{"position":[[317,9]]}}}],["amd64.raw",{"_index":4103,"t":{"850":{"position":[[3171,9]]},"1484":{"position":[[3171,9]]}}}],["amd64.tar.gz",{"_index":2602,"t":{"469":{"position":[[524,12],[568,12]]}}}],["amd64/velero",{"_index":2606,"t":{"469":{"position":[[610,12]]}}}],["amend",{"_index":9634,"t":{"2955":{"position":[[435,5]]}}}],["america",{"_index":10071,"t":{"3299":{"position":[[3578,8]]}}}],["amet",{"_index":57,"t":{"6":{"position":[[22,5],[174,4]]}}}],["amhpora",{"_index":7560,"t":{"1779":{"position":[[6203,7]]}}}],["amongst",{"_index":2988,"t":{"583":{"position":[[141,7]]},"2245":{"position":[[285,7]]}}}],["amount",{"_index":4169,"t":{"853":{"position":[[195,6]]},"913":{"position":[[48,6]]},"1562":{"position":[[98,6]]},"1597":{"position":[[195,6]]},"1635":{"position":[[48,6]]},"1810":{"position":[[408,6]]},"2306":{"position":[[363,6]]},"2310":{"position":[[991,6]]},"2338":{"position":[[319,6]]},"2360":{"position":[[48,6]]},"2497":{"position":[[43,6]]},"2700":{"position":[[247,6],[261,6]]},"2711":{"position":[[1252,6]]},"2719":{"position":[[1318,6]]},"2745":{"position":[[247,6],[261,6]]},"2758":{"position":[[1316,6]]},"2795":{"position":[[841,7]]},"2835":{"position":[[188,6],[202,6]]},"2856":{"position":[[1229,6]]},"2868":{"position":[[108,6],[185,6],[250,6]]},"2870":{"position":[[233,6]]},"2872":{"position":[[37,6]]},"2879":{"position":[[156,6]]},"2931":{"position":[[48,6]]},"2933":{"position":[[783,6]]},"2947":{"position":[[3008,6]]},"3029":{"position":[[570,6]]},"3061":{"position":[[815,6]]},"3208":{"position":[[938,6]]},"3270":{"position":[[546,6]]},"3372":{"position":[[742,6]]},"3378":{"position":[[618,6]]},"3380":{"position":[[157,6]]},"3413":{"position":[[219,6]]}}}],["amper",{"_index":9326,"t":{"2733":{"position":[[373,6]]},"2766":{"position":[[1073,6]]},"2772":{"position":[[373,6]]},"2854":{"position":[[374,6]]}}}],["amphora",{"_index":3931,"t":{"838":{"position":[[12,8],[104,7],[200,7]]},"909":{"position":[[1076,8]]},"913":{"position":[[2714,7]]},"949":{"position":[[740,8]]},"1294":{"position":[[985,7],[1034,7]]},"1386":{"position":[[139,7]]},"1388":{"position":[[48,7],[119,7],[261,8],[458,8]]},"1553":{"position":[[12,8],[104,7],[200,7]]},"1566":{"position":[[56,7],[144,7]]},"1631":{"position":[[1076,8]]},"1635":{"position":[[2714,7]]},"1671":{"position":[[740,8]]},"1779":{"position":[[5966,7]]},"1822":{"position":[[797,7],[846,7],[1145,7],[1197,7]]},"2356":{"position":[[1076,8]]},"2360":{"position":[[2714,7]]},"2396":{"position":[[740,8]]},"2468":{"position":[[232,7]]},"2502":{"position":[[500,7]]}}}],["amplifi",{"_index":9053,"t":{"2665":{"position":[[218,10]]}}}],["amqp",{"_index":5051,"t":{"1084":{"position":[[662,11]]}}}],["an",{"_index":9687,"t":{"3011":{"position":[[1115,3]]}}}],["analysi",{"_index":8141,"t":{"2077":{"position":[[421,9]]},"2083":{"position":[[241,9]]},"3253":{"position":[[363,8]]}}}],["analyz",{"_index":4584,"t":{"932":{"position":[[2918,8]]},"945":{"position":[[73,7],[235,7]]},"947":{"position":[[2326,10]]},"1654":{"position":[[2918,8]]},"1667":{"position":[[73,7],[235,7]]},"1669":{"position":[[2326,10]]},"1963":{"position":[[588,7]]},"2077":{"position":[[124,9],[216,9]]},"2379":{"position":[[2918,8]]},"2392":{"position":[[73,7],[235,7]]},"2394":{"position":[[2326,10]]},"3310":{"position":[[291,8]]},"3389":{"position":[[764,7]]}}}],["ancient",{"_index":9243,"t":{"2723":{"position":[[330,7]]},"2762":{"position":[[343,7]]},"2848":{"position":[[330,7]]}}}],["and/or",{"_index":536,"t":{"71":{"position":[[433,6]]},"489":{"position":[[578,6]]},"594":{"position":[[295,6]]},"596":{"position":[[1137,6]]},"633":{"position":[[1428,6],[2635,6]]},"1419":{"position":[[244,6]]},"1585":{"position":[[2643,6]]},"2100":{"position":[[647,6]]},"2627":{"position":[[1168,6],[1798,6]]},"2895":{"position":[[4616,6]]},"2955":{"position":[[694,6]]},"3184":{"position":[[42,6]]},"3238":{"position":[[705,6]]},"3493":{"position":[[42,6]]}}}],["anjastrunk",{"_index":348,"t":{"27":{"position":[[1666,10]]}}}],["annot",{"_index":2486,"t":{"428":{"position":[[467,8]]},"436":{"position":[[346,12],[683,10],[986,12]]},"474":{"position":[[1108,8]]},"505":{"position":[[478,10]]},"507":{"position":[[109,11]]},"646":{"position":[[1281,10]]},"662":{"position":[[573,10],[745,10],[985,10]]},"2586":{"position":[[235,11]]},"3139":{"position":[[95,11]]}}}],["announc",{"_index":45,"t":{"4":{"position":[[538,13]]},"58":{"position":[[26,9]]},"257":{"position":[[192,13]]},"261":{"position":[[11,13]]},"263":{"position":[[495,12]]},"2321":{"position":[[719,9]]},"2637":{"position":[[79,9]]},"2817":{"position":[[419,9]]},"3301":{"position":[[7292,9],[7581,9]]}}}],["announce@lists.scs.commun",{"_index":1803,"t":{"261":{"position":[[44,28]]}}}],["annoy",{"_index":10116,"t":{"3314":{"position":[[1515,6]]}}}],["anomali",{"_index":7496,"t":{"1764":{"position":[[4184,10]]},"3400":{"position":[[1344,7]]}}}],["anonhugepag",{"_index":6764,"t":{"1379":{"position":[[26,14],[514,14]]}}}],["anonym",{"_index":8353,"t":{"2164":{"position":[[827,9]]},"3236":{"position":[[2047,9],[2248,9],[2305,9]]}}}],["anoth",{"_index":1200,"t":{"174":{"position":[[298,7]]},"247":{"position":[[1393,7]]},"417":{"position":[[304,7],[414,8],[704,8]]},"428":{"position":[[67,7]]},"497":{"position":[[549,7]]},"588":{"position":[[0,7]]},"635":{"position":[[1168,7],[1547,7]]},"909":{"position":[[1697,7]]},"917":{"position":[[749,7]]},"920":{"position":[[474,7]]},"947":{"position":[[1562,7]]},"1055":{"position":[[234,7]]},"1120":{"position":[[185,7]]},"1419":{"position":[[1061,7]]},"1631":{"position":[[1697,7]]},"1639":{"position":[[749,7]]},"1642":{"position":[[474,7]]},"1669":{"position":[[1562,7]]},"1684":{"position":[[1370,7],[1689,7],[2010,7],[2341,7],[2663,7],[2985,7],[3306,7],[3622,7]]},"1779":{"position":[[1545,7]]},"1849":{"position":[[1038,7]]},"1951":{"position":[[472,7]]},"2104":{"position":[[174,7]]},"2126":{"position":[[575,7]]},"2356":{"position":[[1697,7]]},"2364":{"position":[[749,7]]},"2367":{"position":[[474,7]]},"2394":{"position":[[1562,7]]},"2951":{"position":[[719,7]]},"2960":{"position":[[1065,7],[1197,7]]},"2966":{"position":[[1670,7],[1860,7],[3099,7]]},"3105":{"position":[[125,7]]},"3145":{"position":[[85,7]]},"3154":{"position":[[354,7]]},"3160":{"position":[[2489,7]]},"3182":{"position":[[1180,7]]},"3242":{"position":[[37,7]]},"3372":{"position":[[712,7]]},"3419":{"position":[[289,7],[376,7]]}}}],["ansibl",{"_index":203,"t":{"14":{"position":[[36,7]]},"133":{"position":[[35,7],[98,7],[201,7],[357,7]]},"141":{"position":[[160,7]]},"147":{"position":[[169,7]]},"270":{"position":[[581,7]]},"272":{"position":[[108,8]]},"311":{"position":[[38,7]]},"313":{"position":[[113,7]]},"353":{"position":[[313,8]]},"489":{"position":[[220,7],[493,7]]},"491":{"position":[[319,7]]},"752":{"position":[[21,7]]},"895":{"position":[[834,7]]},"1008":{"position":[[47,7]]},"1052":{"position":[[4,7]]},"1067":{"position":[[473,7],[1610,7],[4186,7]]},"1073":{"position":[[522,7]]},"1098":{"position":[[214,7]]},"1120":{"position":[[1001,7]]},"1150":{"position":[[12633,7]]},"1165":{"position":[[49,7],[411,7]]},"1207":{"position":[[47,7]]},"1221":{"position":[[47,7]]},"1252":{"position":[[282,7]]},"1256":{"position":[[121,7],[2326,7],[2353,7],[2466,7],[2504,7],[2615,7],[2811,7],[3003,7],[3063,7]]},"1258":{"position":[[36,7],[156,7],[302,7]]},"1260":{"position":[[36,7],[156,7],[279,7]]},"1264":{"position":[[13,7],[158,7]]},"1267":{"position":[[161,7]]},"1269":{"position":[[56,7]]},"1271":{"position":[[52,7]]},"1292":{"position":[[321,7]]},"1315":{"position":[[5,7],[39,7],[140,7],[206,7],[299,7],[364,7],[430,7]]},"1317":{"position":[[12,7],[779,7]]},"1333":{"position":[[11,7],[50,7],[88,7]]},"1335":{"position":[[58,7]]},"1342":{"position":[[495,7],[669,7]]},"1383":{"position":[[229,7]]},"1608":{"position":[[63,7],[237,7],[264,7],[372,7],[455,7],[675,7]]},"1617":{"position":[[834,7]]},"1678":{"position":[[587,7],[666,7],[1292,7],[1562,7],[1598,7],[1634,7]]},"1684":{"position":[[167,7],[194,7],[249,7],[388,7]]},"1690":{"position":[[868,7],[1230,7],[1407,7],[1587,7],[1632,7],[1742,7],[1791,7],[1913,7],[2073,7]]},"1693":{"position":[[38,7],[90,7]]},"1731":{"position":[[1119,7],[1189,7],[1250,7],[1322,7],[2985,7],[3057,7]]},"1738":{"position":[[324,7]]},"1745":{"position":[[269,7]]},"1749":{"position":[[1298,7]]},"1777":{"position":[[202,7],[249,7],[342,7]]},"1779":{"position":[[2773,7],[4125,7]]},"1791":{"position":[[935,7]]},"1803":{"position":[[0,7]]},"1805":{"position":[[15,7],[86,7]]},"1812":{"position":[[104,8],[191,8],[306,8]]},"1825":{"position":[[2207,7],[2675,7]]},"2043":{"position":[[908,8]]},"2098":{"position":[[70,7],[1232,7],[1548,7],[1607,7],[1790,7],[2349,8],[3088,7],[3363,7]]},"2176":{"position":[[1003,9]]},"2190":{"position":[[45,7],[181,10]]},"2200":{"position":[[84,7]]},"2217":{"position":[[24,7]]},"2245":{"position":[[837,8]]},"2255":{"position":[[294,7]]},"2259":{"position":[[130,7]]},"2278":{"position":[[552,8]]},"2281":{"position":[[106,7]]},"2312":{"position":[[192,8]]},"2342":{"position":[[834,7]]},"2463":{"position":[[612,8],[652,7],[690,7]]},"2576":{"position":[[661,8]]},"3160":{"position":[[2889,7]]},"3251":{"position":[[609,7]]},"3255":{"position":[[788,8]]},"3301":{"position":[[7113,8]]}}}],["ansible&pipeline=period",{"_index":7450,"t":{"1758":{"position":[[1048,25],[1217,25],[1386,25]]}}}],["ansible.builtin.add_host",{"_index":7376,"t":{"1743":{"position":[[1712,25]]}}}],["ansible.builtin.apt",{"_index":4771,"t":{"1017":{"position":[[345,19]]},"1743":{"position":[[2020,20],[2131,20]]}}}],["ansible.builtin.copi",{"_index":898,"t":{"139":{"position":[[446,21]]},"1697":{"position":[[447,21]]},"1749":{"position":[[282,21]]}}}],["ansible.builtin.fil",{"_index":7414,"t":{"1749":{"position":[[142,21]]}}}],["ansible.builtin.group",{"_index":7383,"t":{"1743":{"position":[[2388,22]]}}}],["ansible.builtin.shel",{"_index":6127,"t":{"1273":{"position":[[443,22]]}}}],["ansible.builtin.us",{"_index":7381,"t":{"1743":{"position":[[2276,21],[2465,21]]}}}],["ansible.builtin.wait_for_connect",{"_index":7379,"t":{"1743":{"position":[[1955,36]]}}}],["ansible.manager_default",{"_index":6347,"t":{"1317":{"position":[[6670,23],[8474,23]]}}}],["ansible.netcommon",{"_index":948,"t":{"143":{"position":[[931,17]]}}}],["ansible.posix.synchron",{"_index":917,"t":{"141":{"position":[[405,26]]},"1699":{"position":[[220,26]]}}}],["ansible.yaml",{"_index":8191,"t":{"2098":{"position":[[2756,12],[3066,12]]}}}],["ansible/check",{"_index":7665,"t":{"1805":{"position":[[46,13]]}}}],["ansible/kolla",{"_index":6261,"t":{"1317":{"position":[[1719,14],[6715,14],[7451,14]]}}}],["ansible/latest/admin/mariadb",{"_index":6208,"t":{"1300":{"position":[[33,28]]}}}],["ansible/logs/ansible.log",{"_index":6248,"t":{"1315":{"position":[[315,25],[380,25],[446,25]]}}}],["ansible/pull/215/fil",{"_index":7142,"t":{"1608":{"position":[[746,22]]}}}],["ansible/roles/common/tasks/deploy.yml",{"_index":6343,"t":{"1317":{"position":[[5842,38]]}}}],["ansible:2023.2",{"_index":7321,"t":{"1731":{"position":[[1278,14]]}}}],["ansible:latest",{"_index":7344,"t":{"1731":{"position":[[3013,14]]}}}],["ansible:quinci",{"_index":7319,"t":{"1731":{"position":[[1146,14]]}}}],["ansible](https://zuul.services.betacloud.xyz/t/osism/builds?project=osism%2fcontain",{"_index":7449,"t":{"1758":{"position":[[951,85],[1119,85],[1288,85]]}}}],["ansible_architectur",{"_index":6451,"t":{"1329":{"position":[[174,20],[401,20]]}}}],["ansible_ask_pass",{"_index":6098,"t":{"1256":{"position":[[1231,16],[2565,16]]},"1258":{"position":[[70,17]]},"1260":{"position":[[70,17]]}}}],["ansible_ask_pass=tru",{"_index":6096,"t":{"1256":{"position":[[1001,21],[1506,21]]}}}],["ansible_ask_vault_pass",{"_index":6101,"t":{"1256":{"position":[[1427,22],[2755,22]]},"1258":{"position":[[188,22]]}}}],["ansible_ask_vault_pass=tru",{"_index":6095,"t":{"1256":{"position":[[971,27],[1811,27],[2396,27]]},"1258":{"position":[[237,27]]},"1260":{"position":[[195,27]]},"1764":{"position":[[4600,27]]}}}],["ansible_become_ask_pass",{"_index":6100,"t":{"1256":{"position":[[1349,23],[2864,23]]},"1258":{"position":[[44,25]]},"1260":{"position":[[44,25]]}}}],["ansible_become_ask_pass=tru",{"_index":6094,"t":{"1256":{"position":[[940,28]]}}}],["ansible_collection_services_vers",{"_index":7191,"t":{"1686":{"position":[[270,37]]}}}],["ansible_date_time.d",{"_index":919,"t":{"141":{"position":[[483,22]]},"1699":{"position":[[298,22]]}}}],["ansible_facts.processor_vcpu",{"_index":5914,"t":{"1169":{"position":[[136,31],[216,31]]}}}],["ansible_facts['memtotal_mb",{"_index":5393,"t":{"1122":{"position":[[243,28],[311,28],[379,28],[447,28],[522,28]]}}}],["ansible_host",{"_index":4954,"t":{"1067":{"position":[[1934,13],[4288,13]]},"1098":{"position":[[222,13]]},"1327":{"position":[[188,12],[407,12]]}}}],["ansible_host=192.0.2.2",{"_index":7431,"t":{"1749":{"position":[[1206,22]]}}}],["ansible_local.osism.bootstrap",{"_index":6120,"t":{"1271":{"position":[[66,29]]}}}],["ansible_local.osism.mainten",{"_index":6118,"t":{"1269":{"position":[[70,31]]}}}],["ansible_os_famili",{"_index":900,"t":{"139":{"position":[[477,17]]},"1697":{"position":[[478,17]]}}}],["ansible_playbooks_manager_vers",{"_index":7192,"t":{"1686":{"position":[[312,36]]}}}],["ansible_ssh_arg",{"_index":6105,"t":{"1256":{"position":[[2089,16],[2187,18],[2948,16]]}}}],["ansible_ssh_us",{"_index":7382,"t":{"1743":{"position":[[2308,16]]}}}],["ansible_us",{"_index":6091,"t":{"1256":{"position":[[281,12],[690,12],[805,12],[1197,12],[1312,12],[1714,12],[3034,12]]},"1258":{"position":[[88,13]]},"1260":{"position":[[88,13]]},"1743":{"position":[[1798,13]]}}}],["ansible_user=os",{"_index":6097,"t":{"1256":{"position":[[1025,18],[1968,18]]}}}],["ansible_user=ubuntu",{"_index":7432,"t":{"1749":{"position":[[1229,19]]}}}],["ansible_vers",{"_index":6346,"t":{"1317":{"position":[[6369,15]]}}}],["ansibleundefin",{"_index":7664,"t":{"1803":{"position":[[72,17]]}}}],["answer",{"_index":1348,"t":{"187":{"position":[[363,6]]},"225":{"position":[[127,8]]},"235":{"position":[[774,6]]},"2673":{"position":[[602,9]]},"2966":{"position":[[2723,7]]},"3044":{"position":[[84,7]]},"3400":{"position":[[151,8]]}}}],["antelop",{"_index":8516,"t":{"2403":{"position":[[76,10]]},"3082":{"position":[[25,10]]}}}],["anti",{"_index":2775,"t":{"487":{"position":[[2278,4]]},"631":{"position":[[593,4]]},"2245":{"position":[[387,4]]},"2592":{"position":[[730,4]]},"3182":{"position":[[412,4],[912,4],[1188,5],[2254,4]]},"3184":{"position":[[28,4],[93,4],[137,4],[440,4],[1136,5],[1365,4],[1664,4],[2543,4]]},"3186":{"position":[[137,4],[1432,4]]},"3188":{"position":[[104,4]]},"3197":{"position":[[107,4]]},"3199":{"position":[[1104,6]]},"3518":{"position":[[1781,4]]}}}],["anti_affin",{"_index":2773,"t":{"487":{"position":[[2227,13],[2440,13],[2539,13]]}}}],["anticip",{"_index":9992,"t":{"3245":{"position":[[1474,11]]},"3380":{"position":[[175,11]]}}}],["anyhow",{"_index":4431,"t":{"911":{"position":[[1098,7]]},"1633":{"position":[[1098,7]]},"2358":{"position":[[1098,7]]}}}],["anymor",{"_index":3510,"t":{"658":{"position":[[425,7]]},"1908":{"position":[[2503,8]]},"2024":{"position":[[2503,8]]},"2324":{"position":[[730,8]]},"2637":{"position":[[336,8]]},"3316":{"position":[[1812,7]]}}}],["anyon",{"_index":2211,"t":{"366":{"position":[[1548,6]]},"499":{"position":[[1933,6]]},"2166":{"position":[[149,6]]},"2188":{"position":[[152,6]]},"3206":{"position":[[130,7]]}}}],["anyth",{"_index":1355,"t":{"187":{"position":[[581,8]]},"206":{"position":[[331,8]]},"214":{"position":[[335,8]]},"272":{"position":[[19,8]]},"325":{"position":[[1272,8],[1458,8]]},"654":{"position":[[693,8]]},"821":{"position":[[1600,8]]},"895":{"position":[[215,8]]},"905":{"position":[[1941,8]]},"917":{"position":[[610,8]]},"1041":{"position":[[351,8]]},"1397":{"position":[[351,8]]},"1466":{"position":[[124,8]]},"1511":{"position":[[1600,8]]},"1617":{"position":[[215,8]]},"1627":{"position":[[1941,8]]},"1639":{"position":[[610,8]]},"1833":{"position":[[182,9]]},"2342":{"position":[[215,8]]},"2352":{"position":[[1941,8]]},"2364":{"position":[[610,8]]}}}],["anyway",{"_index":10227,"t":{"3423":{"position":[[136,6],[327,7]]}}}],["anywher",{"_index":1721,"t":{"247":{"position":[[3102,9]]},"1080":{"position":[[515,8]]},"1825":{"position":[[663,8]]},"2235":{"position":[[116,9]]}}}],["aodh",{"_index":5060,"t":{"1086":{"position":[[0,4],[17,4],[42,4]]},"1169":{"position":[[631,4],[761,4]]},"1311":{"position":[[312,4]]},"2190":{"position":[[758,5]]}}}],["aodh_api_public_port",{"_index":5655,"t":{"1159":{"position":[[241,21]]}}}],["aodh_api_work",{"_index":5916,"t":{"1169":{"position":[[549,16],[863,16]]}}}],["aodh_external_fqdn",{"_index":5653,"t":{"1159":{"position":[[193,18]]}}}],["aodh_public_endpoint",{"_index":5652,"t":{"1159":{"position":[[172,20]]}}}],["aov",{"_index":8613,"t":{"2520":{"position":[[534,3],[568,3]]}}}],["apach",{"_index":1130,"t":{"170":{"position":[[1150,6],[2072,6]]},"176":{"position":[[767,6]]},"253":{"position":[[1410,6]]},"298":{"position":[[216,6],[386,6],[769,6],[852,6]]},"379":{"position":[[133,6]]},"970":{"position":[[190,6]]},"3299":{"position":[[1218,6],[2704,6],[3924,6]]}}}],["apache2",{"_index":6376,"t":{"1319":{"position":[[429,8]]}}}],["apache_lock_dir=/var/lock/apache2",{"_index":6367,"t":{"1319":{"position":[[56,33]]}}}],["apache_log_dir=/var/log/apache2",{"_index":6368,"t":{"1319":{"position":[[102,31],[139,31]]}}}],["apart",{"_index":6090,"t":{"1252":{"position":[[1277,5]]},"2164":{"position":[[475,6]]},"3053":{"position":[[387,5]]},"3055":{"position":[[872,5]]}}}],["api",{"_index":297,"t":{"27":{"position":[[206,3],[234,3]]},"44":{"position":[[51,3]]},"51":{"position":[[46,3]]},"67":{"position":[[195,3]]},"71":{"position":[[495,3]]},"105":{"position":[[191,3]]},"174":{"position":[[282,3]]},"306":{"position":[[29,3]]},"325":{"position":[[5678,3]]},"333":{"position":[[176,3]]},"335":{"position":[[46,3],[366,3]]},"344":{"position":[[59,3],[121,3]]},"349":{"position":[[12,3],[157,3],[693,3]]},"363":{"position":[[166,3]]},"421":{"position":[[901,3],[1124,4],[1177,3],[1254,3],[1420,3],[1522,3]]},"423":{"position":[[75,3]]},"465":{"position":[[207,3]]},"467":{"position":[[75,3],[198,4],[601,4],[628,4],[2596,4]]},"481":{"position":[[89,3]]},"483":{"position":[[35,3],[533,3],[610,3]]},"485":{"position":[[965,3]]},"487":{"position":[[3365,3],[4871,4],[4908,3],[5106,3],[5199,3]]},"489":{"position":[[20,3]]},"491":{"position":[[99,3],[281,3]]},"493":{"position":[[78,3],[188,3],[323,3],[464,3],[605,3],[984,3],[1119,3],[1260,3],[1401,3],[1768,3]]},"495":{"position":[[64,3],[132,3],[247,3],[586,3],[848,3],[1031,3],[1134,3],[1473,3],[1723,3]]},"501":{"position":[[129,3],[164,3]]},"509":{"position":[[678,4]]},"513":{"position":[[644,3],[752,3],[1141,3],[1336,3],[1379,3],[2456,3]]},"530":{"position":[[560,4],[588,3],[682,3]]},"552":{"position":[[407,3]]},"554":{"position":[[215,4]]},"590":{"position":[[113,4]]},"594":{"position":[[173,3]]},"598":{"position":[[71,3]]},"600":{"position":[[48,3]]},"604":{"position":[[510,3],[639,3],[1053,3],[1704,3],[1730,3],[1781,4],[2494,3],[2517,3],[2761,3],[3554,3],[5578,3]]},"609":{"position":[[433,3],[787,3],[1875,3],[2690,3],[2716,3],[4677,3],[5390,3],[5416,3]]},"617":{"position":[[8,3],[1130,3]]},"627":{"position":[[3275,3],[3447,3]]},"631":{"position":[[519,3]]},"633":{"position":[[3688,3]]},"635":{"position":[[739,3],[3732,3]]},"637":{"position":[[75,3],[277,3]]},"650":{"position":[[33,3],[274,3],[1051,3]]},"654":{"position":[[216,3]]},"656":{"position":[[21,3]]},"667":{"position":[[53,3],[244,3],[360,3]]},"738":{"position":[[152,4]]},"740":{"position":[[129,3]]},"744":{"position":[[423,4],[707,5],[737,3],[792,3]]},"746":{"position":[[154,3]]},"756":{"position":[[9,3],[125,3],[179,4],[199,4],[224,3]]},"764":{"position":[[491,4]]},"768":{"position":[[302,3]]},"774":{"position":[[189,3]]},"776":{"position":[[365,4]]},"800":{"position":[[496,3]]},"865":{"position":[[301,3]]},"878":{"position":[[301,3]]},"883":{"position":[[373,4],[435,4],[525,3],[578,3],[861,3],[1122,3],[1222,3],[1664,3],[1840,4],[2120,4]]},"899":{"position":[[171,3],[427,3],[917,3]]},"905":{"position":[[333,3],[2196,3]]},"915":{"position":[[600,3]]},"932":{"position":[[3307,3],[4127,3],[4632,3]]},"982":{"position":[[92,3]]},"984":{"position":[[81,3]]},"1055":{"position":[[1111,3]]},"1063":{"position":[[1035,4]]},"1067":{"position":[[3431,3]]},"1071":{"position":[[287,3],[333,3],[342,3],[670,3],[758,3]]},"1082":{"position":[[354,3]]},"1108":{"position":[[246,6],[600,3]]},"1167":{"position":[[1127,5],[1203,5],[1380,5],[1558,5]]},"1169":{"position":[[636,4]]},"1184":{"position":[[1421,3]]},"1248":{"position":[[19,3]]},"1294":{"position":[[174,4]]},"1377":{"position":[[40,3],[1046,3]]},"1537":{"position":[[496,3]]},"1562":{"position":[[268,3],[467,3]]},"1621":{"position":[[171,3],[427,3],[917,3]]},"1627":{"position":[[333,3],[2196,3]]},"1637":{"position":[[600,3]]},"1654":{"position":[[3307,3],[4127,3],[4632,3]]},"1731":{"position":[[1385,3],[1433,4],[1438,3]]},"1734":{"position":[[265,5]]},"1779":{"position":[[5954,3]]},"1787":{"position":[[669,3],[695,3],[1411,3]]},"1791":{"position":[[2408,3],[3213,3]]},"1794":{"position":[[40,4],[206,4],[616,4],[990,4],[1216,4],[1267,3]]},"1814":{"position":[[126,3]]},"1822":{"position":[[106,3],[153,5]]},"1845":{"position":[[2878,3]]},"1878":{"position":[[991,3],[1157,3]]},"1880":{"position":[[43,3],[576,3]]},"1882":{"position":[[85,4],[722,3]]},"1884":{"position":[[47,3]]},"1894":{"position":[[128,4],[362,3]]},"1896":{"position":[[369,3],[426,3]]},"1900":{"position":[[79,3]]},"1908":{"position":[[43,3]]},"1911":{"position":[[43,3]]},"1972":{"position":[[233,3],[292,4],[323,3],[542,3],[628,4],[653,3],[799,3],[1095,3],[1155,3]]},"1974":{"position":[[42,3],[181,4],[636,3],[678,3]]},"1976":{"position":[[33,3],[105,3],[155,3],[187,3],[612,3]]},"1978":{"position":[[39,3],[206,3]]},"1980":{"position":[[49,4],[94,3]]},"1982":{"position":[[128,3],[344,3],[436,3],[1286,3],[1642,3]]},"1984":{"position":[[46,3],[896,3],[1252,3]]},"1994":{"position":[[991,3],[1157,3]]},"1996":{"position":[[43,3],[576,3]]},"1998":{"position":[[85,4],[722,3]]},"2000":{"position":[[47,3]]},"2010":{"position":[[128,4],[362,3]]},"2012":{"position":[[369,3],[426,3]]},"2016":{"position":[[79,3]]},"2024":{"position":[[43,3]]},"2027":{"position":[[43,3]]},"2031":{"position":[[182,3]]},"2041":{"position":[[148,3]]},"2043":{"position":[[32,3],[172,3]]},"2047":{"position":[[460,3]]},"2067":{"position":[[1647,3]]},"2069":{"position":[[320,3]]},"2085":{"position":[[714,5]]},"2096":{"position":[[358,3],[786,4],[1028,3],[1073,3]]},"2118":{"position":[[1085,3],[1876,3],[2101,3],[2564,3]]},"2144":{"position":[[75,4],[146,4],[317,3]]},"2156":{"position":[[84,3]]},"2162":{"position":[[543,4],[737,3]]},"2164":{"position":[[20,3],[296,3],[408,3],[647,3],[708,3]]},"2166":{"position":[[87,3],[173,3]]},"2168":{"position":[[89,3]]},"2176":{"position":[[598,3],[1075,5]]},"2196":{"position":[[365,3],[946,3],[1029,3],[1178,3]]},"2206":{"position":[[381,3]]},"2229":{"position":[[95,3],[177,3],[485,3]]},"2235":{"position":[[1087,3],[1112,3]]},"2245":{"position":[[80,3],[166,3]]},"2253":{"position":[[189,3]]},"2265":{"position":[[38,3]]},"2278":{"position":[[71,3],[157,3],[210,3],[314,3]]},"2283":{"position":[[260,3],[353,3],[514,3]]},"2286":{"position":[[75,3]]},"2296":{"position":[[281,3]]},"2298":{"position":[[38,3]]},"2310":{"position":[[900,3]]},"2312":{"position":[[749,3]]},"2315":{"position":[[1452,4],[1519,3]]},"2334":{"position":[[16,3],[59,3]]},"2346":{"position":[[171,3],[427,3],[917,3]]},"2352":{"position":[[333,3],[2196,3]]},"2362":{"position":[[600,3]]},"2379":{"position":[[3307,3],[4127,3],[4632,3]]},"2405":{"position":[[291,3],[318,3],[564,3]]},"2407":{"position":[[92,3]]},"2409":{"position":[[880,3]]},"2424":{"position":[[303,3]]},"2461":{"position":[[650,3],[717,3]]},"2468":{"position":[[694,3]]},"2472":{"position":[[142,4]]},"2474":{"position":[[73,4],[98,3],[321,3]]},"2489":{"position":[[50,3]]},"2493":{"position":[[28,3]]},"2504":{"position":[[493,3]]},"2568":{"position":[[459,4]]},"2671":{"position":[[991,3]]},"2715":{"position":[[461,3]]},"2790":{"position":[[60,3]]},"2944":{"position":[[1087,3]]},"2947":{"position":[[2416,3]]},"2987":{"position":[[914,3]]},"3021":{"position":[[427,4]]},"3053":{"position":[[21,3]]},"3063":{"position":[[729,3]]},"3071":{"position":[[412,3],[513,3]]},"3078":{"position":[[198,4]]},"3082":{"position":[[312,4],[425,4]]},"3180":{"position":[[273,3]]},"3193":{"position":[[249,3]]},"3231":{"position":[[242,5]]},"3234":{"position":[[23,3],[478,3]]},"3236":{"position":[[210,3],[550,3],[596,3],[620,3],[996,3],[1149,3],[1228,3],[1267,4],[2401,3],[2722,3],[2779,3],[2929,3]]},"3238":{"position":[[534,3]]},"3251":{"position":[[515,3],[1711,3],[2068,3],[2697,3],[3803,5],[4479,3],[5040,4],[5256,4]]},"3266":{"position":[[260,3]]},"3270":{"position":[[295,3],[464,3],[497,3],[648,3],[1235,3],[1339,3],[1671,3],[1834,3],[1868,3],[2003,3]]},"3276":{"position":[[1070,3]]},"3280":{"position":[[40,3],[58,3],[942,3]]},"3301":{"position":[[2268,4]]},"3314":{"position":[[1060,3]]},"3316":{"position":[[457,3],[502,3],[1760,3]]},"3340":{"position":[[119,3]]},"3343":{"position":[[414,4]]},"3361":{"position":[[449,3]]},"3367":{"position":[[4,3],[103,3]]},"3391":{"position":[[422,3]]},"3403":{"position":[[52,3]]},"3408":{"position":[[43,3],[98,3]]},"3442":{"position":[[307,3]]},"3453":{"position":[[464,3]]},"3457":{"position":[[36,3]]},"3459":{"position":[[780,3]]},"3465":{"position":[[903,3],[985,3],[1081,3],[1279,3],[1360,3],[1486,3]]},"3470":{"position":[[57,3]]},"3479":{"position":[[91,3]]}}}],["api'",{"_index":4394,"t":{"907":{"position":[[14,5]]},"1629":{"position":[[14,5]]},"1972":{"position":[[311,5],[935,6],[968,5]]},"1982":{"position":[[1490,6],[1610,5]]},"1984":{"position":[[1100,6],[1220,5]]},"2176":{"position":[[122,6]]},"2354":{"position":[[14,5]]},"3465":{"position":[[1043,5]]}}}],["api(capi",{"_index":2946,"t":{"515":{"position":[[87,10]]}}}],["api.osism.xyz",{"_index":4919,"t":{"1063":{"position":[[997,16]]},"1071":{"position":[[296,13]]}}}],["api.scs.commun",{"_index":8091,"t":{"2033":{"position":[[892,17]]}}}],["api.scs.community/v1alpha1",{"_index":8099,"t":{"2033":{"position":[[1401,26],[1557,26]]}}}],["api.sigs.k8s.io/tasks/experiment",{"_index":3239,"t":{"609":{"position":[[6148,34]]}}}],["api.sigs.k8s.io/user/troubleshooting.html",{"_index":3026,"t":{"590":{"position":[[2334,42]]}}}],["api.testbed.osism.com",{"_index":4876,"t":{"1055":{"position":[[3343,21]]}}}],["api.testbed.osism.xyz",{"_index":7597,"t":{"1787":{"position":[[1389,21]]}}}],["api/cli",{"_index":8454,"t":{"2281":{"position":[[590,7]]}}}],["api/releas",{"_index":3101,"t":{"604":{"position":[[1875,13]]}}}],["api:v1.6.2",{"_index":3121,"t":{"604":{"position":[[3277,10]]}}}],["api_interfac",{"_index":4973,"t":{"1067":{"position":[[4994,14]]},"1163":{"position":[[157,13],[218,13],[354,13],[489,13],[531,13]]}}}],["api_monitor.sh",{"_index":4399,"t":{"907":{"position":[[498,14]]},"909":{"position":[[340,14],[878,16],[2042,14],[2822,14]]},"911":{"position":[[10,14],[380,14],[1585,14]]},"913":{"position":[[18,14],[1893,16],[2170,16],[2284,16],[2368,16]]},"915":{"position":[[47,15]]},"917":{"position":[[34,14],[405,14]]},"920":{"position":[[15,14],[1043,15]]},"922":{"position":[[0,14],[318,14],[805,15]]},"930":{"position":[[123,14]]},"945":{"position":[[220,14]]},"947":{"position":[[80,14],[1426,14],[1887,14]]},"1629":{"position":[[498,14]]},"1631":{"position":[[340,14],[878,16],[2042,14],[2822,14]]},"1633":{"position":[[10,14],[380,14],[1585,14]]},"1635":{"position":[[18,14],[1893,16],[2170,16],[2284,16],[2368,16]]},"1637":{"position":[[47,15]]},"1639":{"position":[[34,14],[405,14]]},"1642":{"position":[[15,14],[1043,15]]},"1644":{"position":[[0,14],[318,14],[805,15]]},"1652":{"position":[[123,14]]},"1667":{"position":[[220,14]]},"1669":{"position":[[80,14],[1426,14],[1887,14]]},"2354":{"position":[[498,14]]},"2356":{"position":[[340,14],[878,16],[2042,14],[2822,14]]},"2358":{"position":[[10,14],[380,14],[1585,14]]},"2360":{"position":[[18,14],[1893,16],[2170,16],[2284,16],[2368,16]]},"2362":{"position":[[47,15]]},"2364":{"position":[[34,14],[405,14]]},"2367":{"position":[[15,14],[1043,15]]},"2369":{"position":[[0,14],[318,14],[805,15]]},"2377":{"position":[[123,14]]},"2392":{"position":[[220,14]]},"2394":{"position":[[80,14],[1426,14],[1887,14]]}}}],["apigroup",{"_index":8090,"t":{"2033":{"position":[[879,10],[1146,9]]}}}],["apimon",{"_index":4486,"t":{"913":{"position":[[3466,6],[3703,6],[3733,6]]},"915":{"position":[[1101,6],[1326,7]]},"917":{"position":[[227,6],[262,6]]},"1635":{"position":[[3466,6],[3703,6],[3733,6]]},"1637":{"position":[[1101,6],[1326,7]]},"1639":{"position":[[227,6],[262,6]]},"2360":{"position":[[3466,6],[3703,6],[3733,6]]},"2362":{"position":[[1101,6],[1326,7]]},"2364":{"position":[[227,6],[262,6]]}}}],["apimonitor",{"_index":4638,"t":{"947":{"position":[[1013,10]]},"1669":{"position":[[1013,10]]},"2394":{"position":[[1013,10]]}}}],["apimonitor_[0",{"_index":4454,"t":{"913":{"position":[[948,14],[1161,14],[1236,14],[1310,14],[1385,14],[1465,14],[1539,14],[1621,14]]},"1635":{"position":[[948,14],[1161,14],[1236,14],[1310,14],[1385,14],[1465,14],[1539,14],[1621,14]]},"2360":{"position":[[948,14],[1161,14],[1236,14],[1310,14],[1385,14],[1465,14],[1539,14],[1621,14]]}}}],["apimonitor_timestamp",{"_index":4418,"t":{"909":{"position":[[2066,20]]},"1631":{"position":[[2066,20]]},"2356":{"position":[[2066,20]]}}}],["apimonitor_timestamp.log",{"_index":4512,"t":{"922":{"position":[[47,25]]},"1644":{"position":[[47,25]]},"2369":{"position":[[47,25]]}}}],["apimonitor_xxxxx_jh.pem",{"_index":4633,"t":{"947":{"position":[[775,23]]},"1669":{"position":[[775,23]]},"2394":{"position":[[775,23]]}}}],["apimonitor_xxxxx_vm.pem",{"_index":4635,"t":{"947":{"position":[[924,23]]},"1669":{"position":[[924,23]]},"2394":{"position":[[924,23]]}}}],["apiserv",{"_index":5982,"t":{"1195":{"position":[[8,9]]}}}],["apivers",{"_index":2376,"t":{"404":{"position":[[790,11]]},"471":{"position":[[1171,11]]},"660":{"position":[[663,11],[857,11],[996,11],[1571,11]]},"2033":{"position":[[179,11],[242,11],[457,11],[788,11],[944,11],[1030,11],[1389,11],[1545,11]]},"3280":{"position":[[793,11]]}}}],["api’",{"_index":4288,"t":{"883":{"position":[[1512,5]]}}}],["app",{"_index":1345,"t":{"187":{"position":[[162,3]]},"251":{"position":[[254,4]]},"325":{"position":[[2496,3]]},"637":{"position":[[366,4]]},"1747":{"position":[[363,3],[392,3],[624,3]]},"1756":{"position":[[123,3],[227,3]]},"1886":{"position":[[168,3]]},"1892":{"position":[[420,3]]},"2002":{"position":[[168,3]]},"2008":{"position":[[420,3]]},"2083":{"position":[[307,3]]},"2176":{"position":[[644,3]]}}}],["app=harbor,component=nginx,release=harbor",{"_index":3419,"t":{"641":{"position":[[1727,41]]}}}],["app_credential_cloud_conf",{"_index":2066,"t":{"325":{"position":[[2677,25],[3441,25]]}}}],["app_id",{"_index":7421,"t":{"1749":{"position":[[690,7]]}}}],["app_key",{"_index":7422,"t":{"1749":{"position":[[720,8]]}}}],["appar",{"_index":8553,"t":{"2456":{"position":[[133,8]]}}}],["appcr",{"_index":2890,"t":{"501":{"position":[[586,8],[673,7],[737,9],[835,8]]}}}],["appcred_id",{"_index":4382,"t":{"905":{"position":[[1338,10]]},"1627":{"position":[[1338,10]]},"2352":{"position":[[1338,10]]}}}],["appcred_secret",{"_index":4384,"t":{"905":{"position":[[1380,16]]},"1627":{"position":[[1380,16]]},"2352":{"position":[[1380,16]]}}}],["appcredenti",{"_index":2882,"t":{"501":{"position":[[232,13]]}}}],["appctl",{"_index":6720,"t":{"1368":{"position":[[1492,6],[2168,6]]}}}],["appear",{"_index":1156,"t":{"170":{"position":[[2110,7]]},"247":{"position":[[708,11]]},"499":{"position":[[1085,7]]},"932":{"position":[[3182,7]]},"1444":{"position":[[656,7]]},"1654":{"position":[[3182,7]]},"1684":{"position":[[656,6]]},"2379":{"position":[[3182,7]]},"2564":{"position":[[296,8]]},"2568":{"position":[[354,7]]},"2758":{"position":[[1799,6]]},"2872":{"position":[[691,7],[852,6],[1190,6]]},"2874":{"position":[[507,7]]},"3014":{"position":[[444,7]]},"3109":{"position":[[1390,7]]}}}],["append",{"_index":1789,"t":{"253":{"position":[[1904,6]]},"325":{"position":[[6144,9]]},"485":{"position":[[1459,8]]},"652":{"position":[[727,9]]},"796":{"position":[[428,8]]},"798":{"position":[[500,8]]},"1533":{"position":[[428,8]]},"1535":{"position":[[500,8]]},"1743":{"position":[[2344,7],[2577,7]]},"1764":{"position":[[4006,6]]},"1825":{"position":[[2314,9]]},"2719":{"position":[[297,8]]},"2729":{"position":[[76,8]]},"2758":{"position":[[295,8]]},"2768":{"position":[[99,8]]},"3472":{"position":[[13793,8]]}}}],["appendix",{"_index":7928,"t":{"1880":{"position":[[420,8]]},"1896":{"position":[[1326,8]]},"1996":{"position":[[420,8]]},"2012":{"position":[[1326,8]]},"3472":{"position":[[12841,8]]}}}],["appl",{"_index":1505,"t":{"219":{"position":[[76,6]]}}}],["apple'",{"_index":110,"t":{"10":{"position":[[672,7]]}}}],["appli",{"_index":218,"t":{"18":{"position":[[94,5]]},"139":{"position":[[267,7]]},"172":{"position":[[40,5],[239,5],[602,7]]},"191":{"position":[[485,5]]},"379":{"position":[[616,7]]},"381":{"position":[[1752,5]]},"389":{"position":[[141,5],[301,5],[367,7]]},"409":{"position":[[10,5],[414,5],[448,5]]},"411":{"position":[[77,5],[116,5]]},"413":{"position":[[793,5]]},"415":{"position":[[282,5]]},"434":{"position":[[0,5],[60,5]]},"442":{"position":[[514,5]]},"471":{"position":[[1434,5],[1463,5]]},"493":{"position":[[224,7],[369,7],[507,7],[1014,7],[1159,7],[1297,7]]},"499":{"position":[[598,5],[673,8],[1640,7],[2743,7]]},"576":{"position":[[53,5]]},"598":{"position":[[895,8],[1140,5]]},"604":{"position":[[2890,5],[2963,5],[3198,5],[3420,5],[4385,6],[7879,7]]},"609":{"position":[[2805,5],[5534,5]]},"627":{"position":[[1289,5],[3758,7],[4153,7]]},"633":{"position":[[895,7]]},"635":{"position":[[3295,8]]},"637":{"position":[[379,5],[540,5]]},"650":{"position":[[2194,7]]},"660":{"position":[[646,5],[1560,5],[3251,5]]},"669":{"position":[[68,5]]},"752":{"position":[[43,7]]},"754":{"position":[[277,7]]},"800":{"position":[[211,7]]},"819":{"position":[[5857,8]]},"821":{"position":[[21,7],[266,5],[348,5]]},"932":{"position":[[3122,6],[3161,6]]},"1012":{"position":[[422,5]]},"1014":{"position":[[185,7],[231,7],[260,5]]},"1055":{"position":[[3749,5]]},"1075":{"position":[[176,5]]},"1077":{"position":[[540,5],[1007,5]]},"1089":{"position":[[2431,7],[2558,7],[2610,6],[2805,5],[2849,5]]},"1112":{"position":[[3522,5],[3574,5],[3697,5],[4049,5],[4218,5],[4842,5],[4926,5]]},"1114":{"position":[[648,5],[688,5],[1975,5],[4250,5],[4290,5],[5446,5]]},"1116":{"position":[[449,5]]},"1118":{"position":[[1155,5],[1173,5]]},"1120":{"position":[[1988,5],[2105,5]]},"1146":{"position":[[230,5]]},"1169":{"position":[[740,5]]},"1199":{"position":[[525,5]]},"1213":{"position":[[361,5]]},"1224":{"position":[[540,7],[676,5],[1455,5],[1840,5],[2022,5],[2509,5],[2658,5],[2763,5],[2895,5],[3067,5],[3531,5],[3560,5],[3712,5],[3884,5],[3952,5],[4006,5]]},"1226":{"position":[[18,7],[37,5],[62,7]]},"1242":{"position":[[420,5],[447,5],[479,5],[512,5],[543,5],[569,5],[597,5],[627,5],[658,5],[687,5],[716,5],[744,5]]},"1246":{"position":[[220,5],[276,5]]},"1248":{"position":[[68,5],[193,5]]},"1250":{"position":[[214,5],[245,5],[279,5],[310,5],[341,5],[369,5]]},"1258":{"position":[[818,5]]},"1273":{"position":[[299,5]]},"1275":{"position":[[6,5]]},"1277":{"position":[[6,5]]},"1279":{"position":[[293,5],[484,5]]},"1284":{"position":[[25,5],[57,5],[597,5],[621,5]]},"1286":{"position":[[959,5],[1006,5],[1053,5],[1148,5],[1198,5],[1427,5],[1469,5],[1492,5],[1583,5],[2360,5],[2878,5],[2951,5]]},"1288":{"position":[[379,5],[439,5],[455,5],[684,5],[705,5],[776,5],[795,5],[851,5]]},"1290":{"position":[[309,5]]},"1292":{"position":[[643,5]]},"1294":{"position":[[503,5],[540,5],[569,5],[597,5],[624,5],[653,5],[683,5],[715,5],[745,5],[774,5],[801,5],[828,5],[856,5],[881,5],[906,5],[931,5],[959,5],[1342,5],[1370,5]]},"1298":{"position":[[68,5],[144,5]]},"1302":{"position":[[6,5]]},"1311":{"position":[[8,5]]},"1317":{"position":[[754,5],[1199,5],[1681,5]]},"1356":{"position":[[75,5]]},"1358":{"position":[[213,5]]},"1360":{"position":[[28,5],[84,5],[185,5],[257,5],[284,5],[315,5],[370,5],[402,5],[426,5],[489,5],[538,5],[600,5],[665,5],[735,5],[800,5],[860,5],[923,5]]},"1362":{"position":[[135,5],[2471,5],[2517,5],[2577,5],[2646,5],[2729,5]]},"1368":{"position":[[1880,8],[2559,8]]},"1383":{"position":[[82,5]]},"1430":{"position":[[1376,5]]},"1509":{"position":[[5857,8]]},"1511":{"position":[[21,7],[266,5],[348,5]]},"1537":{"position":[[211,7]]},"1582":{"position":[[192,5]]},"1585":{"position":[[2063,8],[2078,5],[2105,5],[2576,5],[2600,5],[2616,5],[3485,5]]},"1654":{"position":[[3122,6],[3161,6]]},"1697":{"position":[[268,7]]},"1705":{"position":[[225,8]]},"1731":{"position":[[3332,5]]},"1745":{"position":[[260,8]]},"1760":{"position":[[6,5],[59,5]]},"1762":{"position":[[82,5],[113,5],[158,5],[189,5],[220,5],[248,5]]},"1764":{"position":[[3755,5]]},"1766":{"position":[[1948,5]]},"1768":{"position":[[171,5],[469,5],[496,5],[539,5],[572,5],[614,5],[640,5],[679,5],[709,5],[751,5],[780,5],[820,5],[848,5]]},"1779":{"position":[[5416,5],[5435,5],[5460,5],[5483,5],[6476,5]]},"1803":{"position":[[194,5]]},"1820":{"position":[[25,5],[57,5],[602,5],[626,5]]},"1822":{"position":[[227,5],[264,5],[293,5],[332,5],[359,5],[399,5],[429,5],[472,5],[502,5],[542,5],[569,5],[607,5],[635,5],[671,5],[696,5],[732,5],[760,5],[1293,5],[1321,5]]},"1825":{"position":[[2115,5],[2481,5],[2648,5]]},"1853":{"position":[[797,5]]},"1857":{"position":[[578,7]]},"1882":{"position":[[32,5]]},"1904":{"position":[[27,7]]},"1915":{"position":[[797,5]]},"1919":{"position":[[578,7]]},"1939":{"position":[[42,5],[194,5]]},"1998":{"position":[[32,5]]},"2020":{"position":[[27,7]]},"2039":{"position":[[179,7]]},"2047":{"position":[[490,5]]},"2071":{"position":[[361,5]]},"2093":{"position":[[718,5],[751,5],[774,5]]},"2096":{"position":[[2209,8]]},"2098":{"position":[[1446,5],[3520,8]]},"2110":{"position":[[427,5]]},"2116":{"position":[[487,5]]},"2138":{"position":[[0,5],[65,5],[96,5],[128,5]]},"2142":{"position":[[99,7]]},"2158":{"position":[[444,5],[503,5],[552,5]]},"2330":{"position":[[255,5]]},"2379":{"position":[[3122,6],[3161,6]]},"2486":{"position":[[128,8]]},"2644":{"position":[[40,7]]},"2923":{"position":[[263,6]]},"2951":{"position":[[423,5]]},"3003":{"position":[[156,6]]},"3053":{"position":[[488,5]]},"3055":{"position":[[156,7]]},"3078":{"position":[[1104,7]]},"3080":{"position":[[517,7],[596,7]]},"3082":{"position":[[1401,5]]},"3084":{"position":[[29,7],[465,7],[519,5]]},"3097":{"position":[[73,7]]},"3099":{"position":[[47,7]]},"3103":{"position":[[831,5],[1036,8]]},"3150":{"position":[[403,5]]},"3208":{"position":[[543,7]]},"3238":{"position":[[855,7]]},"3264":{"position":[[238,5]]},"3280":{"position":[[742,8]]},"3457":{"position":[[0,8],[862,8]]},"3461":{"position":[[119,8]]},"3470":{"position":[[111,8]]},"3472":{"position":[[31,7]]}}}],["applianc",{"_index":7002,"t":{"1564":{"position":[[329,9]]},"2411":{"position":[[102,10]]}}}],["applic",{"_index":1205,"t":{"174":{"position":[[559,12],[918,12],[1011,11]]},"245":{"position":[[1059,10]]},"327":{"position":[[320,13]]},"331":{"position":[[179,13]]},"467":{"position":[[549,11],[994,11]]},"495":{"position":[[933,11],[1808,11]]},"497":{"position":[[101,11],[234,11]]},"501":{"position":[[20,11]]},"513":{"position":[[146,13]]},"530":{"position":[[172,11]]},"669":{"position":[[660,12]]},"740":{"position":[[543,11]]},"780":{"position":[[309,12]]},"883":{"position":[[244,12],[2060,13],[2301,11]]},"888":{"position":[[2483,13]]},"901":{"position":[[327,11]]},"905":{"position":[[1066,11]]},"977":{"position":[[911,12]]},"1110":{"position":[[325,12]]},"1226":{"position":[[2036,10]]},"1317":{"position":[[267,11]]},"1458":{"position":[[85,11],[160,11],[208,11]]},"1623":{"position":[[327,11]]},"1627":{"position":[[1066,11]]},"1747":{"position":[[105,12]]},"1779":{"position":[[1642,11],[1695,11],[1879,11],[1986,11],[2241,11]]},"1865":{"position":[[183,10]]},"1927":{"position":[[183,10]]},"1963":{"position":[[186,11],[399,11]]},"1972":{"position":[[421,10]]},"2081":{"position":[[142,13],[230,11]]},"2083":{"position":[[62,11],[144,13],[376,11],[458,11]]},"2160":{"position":[[78,11]]},"2162":{"position":[[166,12],[418,11],[642,11]]},"2168":{"position":[[50,11],[157,12]]},"2229":{"position":[[590,11]]},"2348":{"position":[[327,11]]},"2352":{"position":[[1066,11]]},"2461":{"position":[[279,12]]},"2506":{"position":[[25,11]]},"2635":{"position":[[137,12]]},"2688":{"position":[[1956,11]]},"2697":{"position":[[782,13]]},"2709":{"position":[[594,12]]},"2742":{"position":[[681,13]]},"2754":{"position":[[594,12]]},"2832":{"position":[[782,13]]},"2844":{"position":[[522,12]]},"2870":{"position":[[54,11]]},"2876":{"position":[[74,13]]},"2944":{"position":[[222,11]]},"2947":{"position":[[4197,11],[5477,12],[5595,11]]},"3053":{"position":[[145,12]]},"3208":{"position":[[607,14]]},"3251":{"position":[[4817,13]]},"3308":{"position":[[351,12],[463,11],[661,12]]},"3310":{"position":[[196,12],[262,12],[452,12]]},"3312":{"position":[[527,12]]},"3314":{"position":[[16,11],[1162,13],[2573,11],[2752,11],[2956,11]]},"3389":{"position":[[217,12],[746,11]]},"3403":{"position":[[251,10]]},"3408":{"position":[[16,11]]},"3461":{"position":[[304,10]]},"3463":{"position":[[447,10]]},"3472":{"position":[[13494,10]]},"3482":{"position":[[3098,12]]},"3484":{"position":[[221,12]]}}}],["application/json",{"_index":8248,"t":{"2118":{"position":[[1143,17],[1930,17],[2167,17]]}}}],["application/octet",{"_index":7942,"t":{"1894":{"position":[[454,18]]},"1913":{"position":[[934,18]]},"2010":{"position":[[454,18]]},"2029":{"position":[[934,18]]}}}],["application_credential_id",{"_index":4381,"t":{"905":{"position":[[1311,26]]},"1627":{"position":[[1311,26]]},"1779":{"position":[[2078,26]]},"2033":{"position":[[640,28]]},"2352":{"position":[[1311,26]]}}}],["application_credential_secret",{"_index":4383,"t":{"905":{"position":[[1349,30]]},"1627":{"position":[[1349,30]]},"1779":{"position":[[2108,30],[2359,30]]},"2033":{"position":[[676,32]]},"2352":{"position":[[1349,30]]}}}],["application_nam",{"_index":6918,"t":{"1458":{"position":[[116,18]]}}}],["applicaton",{"_index":10107,"t":{"3314":{"position":[[460,10]]}}}],["apply_*.sh",{"_index":3478,"t":{"648":{"position":[[538,10]]}}}],["apply_cert_manager.sh",{"_index":2824,"t":{"487":{"position":[[5275,21]]}}}],["apply_metrics.sh",{"_index":2805,"t":{"487":{"position":[[4063,16]]}}}],["apply_nginx_ingress.sh",{"_index":2807,"t":{"487":{"position":[[4188,22],[4597,22]]},"505":{"position":[[762,23]]}}}],["appoint",{"_index":1740,"t":{"249":{"position":[[461,12]]},"2039":{"position":[[438,7]]},"2053":{"position":[[261,7]]},"2067":{"position":[[320,7]]}}}],["appreci",{"_index":467,"t":{"58":{"position":[[366,12]]},"355":{"position":[[184,10]]},"2196":{"position":[[640,10]]},"2272":{"position":[[3,10]]},"2304":{"position":[[3,10]]},"2336":{"position":[[3,10]]},"2432":{"position":[[3,10]]},"2451":{"position":[[3,10]]},"2508":{"position":[[3,10]]}}}],["approach",{"_index":571,"t":{"79":{"position":[[72,8]]},"245":{"position":[[550,8]]},"308":{"position":[[30,8]]},"598":{"position":[[1121,8]]},"639":{"position":[[338,8]]},"883":{"position":[[674,8],[2195,8]]},"888":{"position":[[231,8],[2343,8]]},"956":{"position":[[2343,8]]},"977":{"position":[[868,8]]},"1827":{"position":[[199,8]]},"1982":{"position":[[489,11]]},"1984":{"position":[[99,11]]},"2075":{"position":[[231,8]]},"2188":{"position":[[60,8]]},"2253":{"position":[[247,8]]},"2281":{"position":[[76,8]]},"2310":{"position":[[758,8]]},"2461":{"position":[[98,8]]},"2536":{"position":[[53,8]]},"2602":{"position":[[859,8]]},"2647":{"position":[[399,8],[673,8]]},"2667":{"position":[[41,9]]},"2675":{"position":[[616,8]]},"2719":{"position":[[350,8]]},"2758":{"position":[[348,8]]},"2895":{"position":[[2632,8]]},"2951":{"position":[[408,8]]},"2999":{"position":[[127,10]]},"3009":{"position":[[91,10]]},"3011":{"position":[[47,9],[468,8]]},"3057":{"position":[[20,10],[155,10]]},"3063":{"position":[[748,8]]},"3069":{"position":[[135,10],[529,11]]},"3071":{"position":[[1786,8],[2469,8],[2644,10]]},"3082":{"position":[[452,8]]},"3184":{"position":[[717,10]]},"3212":{"position":[[14,10],[167,11]]},"3218":{"position":[[940,8],[1510,8],[1543,8]]},"3222":{"position":[[88,9],[683,9]]},"3224":{"position":[[99,11],[930,9],[957,8],[1764,8]]},"3236":{"position":[[105,10],[2439,10]]},"3251":{"position":[[6002,8]]},"3301":{"position":[[5198,8]]},"3325":{"position":[[3,8]]},"3391":{"position":[[426,8]]},"3397":{"position":[[133,9]]},"3423":{"position":[[491,8]]},"3465":{"position":[[687,8]]},"3468":{"position":[[4,8]]},"3482":{"position":[[469,8]]},"3518":{"position":[[2710,8]]}}}],["appropri",{"_index":1774,"t":{"253":{"position":[[517,11]]},"427":{"position":[[48,11]]},"471":{"position":[[48,11]]},"499":{"position":[[1264,13]]},"627":{"position":[[1705,11],[2879,11]]},"669":{"position":[[130,11]]},"750":{"position":[[526,11]]},"1165":{"position":[[399,11]]},"1406":{"position":[[71,11]]},"1676":{"position":[[78,11]]},"1855":{"position":[[1072,11]]},"1878":{"position":[[371,11]]},"1917":{"position":[[1072,11]]},"1947":{"position":[[323,11]]},"1994":{"position":[[371,11]]},"2750":{"position":[[1305,11]]},"2951":{"position":[[107,11]]},"3376":{"position":[[820,11]]},"3459":{"position":[[759,11]]}}}],["approv",{"_index":761,"t":{"114":{"position":[[613,8]]},"166":{"position":[[423,8]]},"184":{"position":[[241,8],[313,9]]},"233":{"position":[[73,9],[234,11]]},"253":{"position":[[1313,9]]},"499":{"position":[[1054,9]]},"2053":{"position":[[151,8]]},"2067":{"position":[[175,8]]},"2426":{"position":[[907,8]]},"3234":{"position":[[482,7]]},"3276":{"position":[[2087,8],[2164,9],[2255,8],[2346,7],[2566,9],[2607,9]]}}}],["approxim",{"_index":1022,"t":{"166":{"position":[[400,14]]},"2118":{"position":[[1309,14]]}}}],["april",{"_index":8465,"t":{"2300":{"position":[[254,5]]},"2422":{"position":[[119,5]]},"3251":{"position":[[3023,5]]}}}],["apt",{"_index":79,"t":{"10":{"position":[[97,4],[107,3],[492,3]]},"485":{"position":[[1512,3],[1565,3]]},"604":{"position":[[132,3],[155,3],[320,3]]},"635":{"position":[[2351,4],[2857,4]]},"905":{"position":[[56,3],[76,3],[121,3]]},"909":{"position":[[40,3]]},"926":{"position":[[53,3],[393,3],[409,3]]},"928":{"position":[[29,3]]},"932":{"position":[[363,3],[379,3]]},"934":{"position":[[21,4],[135,3],[163,3],[182,3],[308,3]]},"1017":{"position":[[396,3]]},"1203":{"position":[[12,3]]},"1238":{"position":[[5,3]]},"1475":{"position":[[2,3]]},"1571":{"position":[[1050,3],[1066,3]]},"1587":{"position":[[1481,3]]},"1627":{"position":[[56,3],[76,3],[121,3]]},"1631":{"position":[[40,3]]},"1648":{"position":[[53,3],[393,3],[409,3]]},"1650":{"position":[[29,3]]},"1654":{"position":[[363,3],[379,3]]},"1656":{"position":[[21,4],[135,3],[163,3],[182,3],[308,3]]},"1764":{"position":[[188,3],[219,3]]},"1831":{"position":[[187,3]]},"2352":{"position":[[56,3],[76,3],[121,3]]},"2356":{"position":[[40,3]]},"2373":{"position":[[53,3],[393,3],[409,3]]},"2375":{"position":[[29,3]]},"2379":{"position":[[363,3],[379,3]]},"2381":{"position":[[21,4],[135,3],[163,3],[182,3],[308,3]]}}}],["apt_cache_valid_tim",{"_index":4768,"t":{"1017":{"position":[[258,20]]}}}],["aqua",{"_index":2562,"t":{"456":{"position":[[52,4]]}}}],["aquir",{"_index":9650,"t":{"2966":{"position":[[3711,7]]}}}],["ara",{"_index":6247,"t":{"1315":{"position":[[97,3]]},"1317":{"position":[[20,5],[787,5],[1434,5],[1957,5],[5492,5],[6109,5],[7009,5],[7698,5],[8688,5]]},"1576":{"position":[[114,3],[154,3]]},"1731":{"position":[[162,3],[1525,3],[1593,3]]},"1779":{"position":[[4144,3],[4326,3],[4358,3]]},"1787":{"position":[[319,3]]},"1789":{"position":[[306,3],[340,3]]},"2190":{"position":[[309,4]]},"2248":{"position":[[1447,4]]}}}],["ara.sh",{"_index":7542,"t":{"1779":{"position":[[4226,7],[4400,7]]}}}],["ara.testbed.osism.xyz",{"_index":7573,"t":{"1787":{"position":[[297,21]]}}}],["arbitrari",{"_index":3654,"t":{"742":{"position":[[160,9]]},"2506":{"position":[[226,9]]}}}],["arch",{"_index":9250,"t":{"2725":{"position":[[0,4],[178,4]]},"2764":{"position":[[98,6],[173,4]]},"2850":{"position":[[0,4],[178,4]]},"3011":{"position":[[131,4]]}}}],["arch[n][h",{"_index":9402,"t":{"2837":{"position":[[150,12]]}}}],["architect",{"_index":2212,"t":{"366":{"position":[[1570,10]]}}}],["architectur",{"_index":544,"t":{"73":{"position":[[82,12]]},"274":{"position":[[141,12]]},"363":{"position":[[537,12]]},"444":{"position":[[371,12]]},"712":{"position":[[118,12]]},"790":{"position":[[884,13]]},"796":{"position":[[696,13]]},"798":{"position":[[692,13]]},"850":{"position":[[9212,13]]},"870":{"position":[[8,12],[29,12],[50,12],[72,12],[99,12]]},"880":{"position":[[680,13]]},"883":{"position":[[1526,12]]},"888":{"position":[[1996,12]]},"970":{"position":[[54,12]]},"1484":{"position":[[9212,13]]},"1527":{"position":[[884,13]]},"1533":{"position":[[696,13]]},"1535":{"position":[[692,13]]},"1953":{"position":[[156,13]]},"2039":{"position":[[7,13],[860,13]]},"2134":{"position":[[24,12]]},"2154":{"position":[[1085,12],[1584,12]]},"2176":{"position":[[615,12]]},"2426":{"position":[[523,13]]},"2534":{"position":[[19,13]]},"2602":{"position":[[695,12]]},"2656":{"position":[[105,12]]},"2665":{"position":[[334,13]]},"2671":{"position":[[92,13],[380,12],[802,12]]},"2673":{"position":[[92,13]]},"2675":{"position":[[581,12]]},"2764":{"position":[[241,12]]},"2892":{"position":[[237,13]]},"2999":{"position":[[495,15],[546,13]]},"3162":{"position":[[565,13]]},"3182":{"position":[[1950,13]]},"3245":{"position":[[1401,13]]},"3301":{"position":[[5508,13]]},"3312":{"position":[[398,12]]},"3391":{"position":[[674,12]]},"3395":{"position":[[249,13],[1038,13],[1082,12]]},"3397":{"position":[[89,12]]},"3400":{"position":[[1649,12]]},"3459":{"position":[[309,13]]},"3465":{"position":[[241,13]]},"3472":{"position":[[13203,12]]},"3475":{"position":[[54,13]]},"3518":{"position":[[2538,12]]}}}],["archiv",{"_index":915,"t":{"141":{"position":[[346,8],[510,8]]},"1699":{"position":[[161,8],[325,8]]},"2647":{"position":[[1314,10]]},"3316":{"position":[[1709,8]]}}}],["archive_compat.key",{"_index":4529,"t":{"926":{"position":[[148,18],[199,18],[268,19]]},"1648":{"position":[[148,18],[199,18],[268,19]]},"2373":{"position":[[148,18],[199,18],[268,19]]}}}],["archtitectur",{"_index":10211,"t":{"3395":{"position":[[598,14]]}}}],["area",{"_index":1445,"t":{"206":{"position":[[50,5],[64,5],[79,5]]},"223":{"position":[[48,6],[61,6],[77,5]]},"1077":{"position":[[264,6]]},"1252":{"position":[[952,5]]},"2051":{"position":[[287,4]]},"2330":{"position":[[56,5]]},"2426":{"position":[[490,4]]},"2482":{"position":[[337,4]]},"3007":{"position":[[391,4]]},"3016":{"position":[[734,5]]},"3251":{"position":[[4432,6],[5058,5]]},"3278":{"position":[[175,6]]}}}],["aren't",{"_index":1680,"t":{"247":{"position":[[1291,6]]},"1397":{"position":[[569,6]]}}}],["arg",{"_index":9384,"t":{"2813":{"position":[[987,4],[1152,5]]},"2815":{"position":[[902,5]]}}}],["arguabl",{"_index":9749,"t":{"3084":{"position":[[293,8]]}}}],["argument",{"_index":1874,"t":{"284":{"position":[[448,9]]},"427":{"position":[[298,8],[399,9]]},"467":{"position":[[2524,8]]},"596":{"position":[[2406,9],[2480,9],[2848,9]]},"627":{"position":[[4079,9]]},"662":{"position":[[865,9]]},"819":{"position":[[1767,9]]},"821":{"position":[[1219,9]]},"859":{"position":[[1285,9],[6740,9]]},"913":{"position":[[2563,10]]},"1224":{"position":[[1988,9]]},"1256":{"position":[[3023,10]]},"1342":{"position":[[290,9]]},"1383":{"position":[[126,9]]},"1509":{"position":[[1767,9]]},"1511":{"position":[[1219,9]]},"1603":{"position":[[1285,9],[6740,9]]},"1635":{"position":[[2563,10]]},"1865":{"position":[[408,9]]},"1927":{"position":[[408,9]]},"2360":{"position":[[2563,10]]},"2813":{"position":[[1021,9]]},"2935":{"position":[[131,9]]},"2994":{"position":[[129,9]]},"3059":{"position":[[606,9],[867,9]]},"3175":{"position":[[319,10]]},"3276":{"position":[[1436,9]]}}}],["aris",{"_index":7932,"t":{"1880":{"position":[[848,6]]},"1890":{"position":[[439,6]]},"1892":{"position":[[1267,6]]},"1996":{"position":[[848,6]]},"2006":{"position":[[439,6]]},"2008":{"position":[[1267,6]]},"3208":{"position":[[1511,5]]},"3299":{"position":[[2557,7]]}}}],["arm",{"_index":9105,"t":{"2700":{"position":[[401,4]]},"2725":{"position":[[300,3]]},"2745":{"position":[[401,4]]},"2764":{"position":[[333,3]]},"2835":{"position":[[342,4]]}}}],["arm64",{"_index":9329,"t":{"2733":{"position":[[416,5]]},"2772":{"position":[[416,5]]},"2854":{"position":[[417,5]]},"2872":{"position":[[471,7]]},"2883":{"position":[[121,7]]}}}],["armv9",{"_index":9264,"t":{"2725":{"position":[[556,7]]},"2764":{"position":[[777,7]]},"2850":{"position":[[465,7]]}}}],["around",{"_index":565,"t":{"77":{"position":[[41,6]]},"101":{"position":[[31,6]]},"202":{"position":[[550,7]]},"229":{"position":[[149,6]]},"550":{"position":[[259,7]]},"615":{"position":[[1058,6],[1197,6]]},"780":{"position":[[636,6]]},"913":{"position":[[3051,6]]},"932":{"position":[[2977,6]]},"947":{"position":[[1398,6]]},"1448":{"position":[[75,6]]},"1587":{"position":[[760,6],[969,7]]},"1635":{"position":[[3051,6]]},"1654":{"position":[[2977,6]]},"1669":{"position":[[1398,6]]},"2093":{"position":[[439,6]]},"2315":{"position":[[1716,7]]},"2360":{"position":[[3051,6]]},"2379":{"position":[[2977,6]]},"2394":{"position":[[1398,6]]},"2574":{"position":[[20,6]]},"2647":{"position":[[1153,6],[1275,6]]},"3011":{"position":[[1312,6]]},"3055":{"position":[[609,6]]},"3124":{"position":[[364,6],[746,6]]},"3126":{"position":[[673,6]]},"3299":{"position":[[5064,6]]}}}],["array",{"_index":689,"t":{"105":{"position":[[1204,5]]},"485":{"position":[[532,5]]},"2663":{"position":[[133,5]]},"2805":{"position":[[400,5],[637,5]]},"2809":{"position":[[112,5]]},"2811":{"position":[[442,5]]},"2947":{"position":[[5203,6]]}}}],["arriv",{"_index":1482,"t":{"210":{"position":[[744,7],[792,7],[855,7]]},"2872":{"position":[[1445,7]]},"3167":{"position":[[423,6]]}}}],["arrow",{"_index":1754,"t":{"251":{"position":[[274,6]]}}}],["art",{"_index":9034,"t":{"2637":{"position":[[332,3]]},"2795":{"position":[[1427,3]]}}}],["artcodix",{"_index":8611,"t":{"2520":{"position":[[519,8]]}}}],["artefact",{"_index":7175,"t":{"1678":{"position":[[955,8],[1468,9]]}}}],["articl",{"_index":1559,"t":{"233":{"position":[[144,8]]},"903":{"position":[[2394,8]]},"1144":{"position":[[217,7]]},"1625":{"position":[[2394,8]]},"2310":{"position":[[1006,8]]},"2350":{"position":[[2394,8]]},"2413":{"position":[[229,8]]}}}],["articul",{"_index":9068,"t":{"2673":{"position":[[539,12]]}}}],["artifact",{"_index":2493,"t":{"428":{"position":[[986,9]]},"513":{"position":[[2064,9]]},"1963":{"position":[[334,10]]},"2248":{"position":[[312,9]]},"3160":{"position":[[2302,9],[2323,9],[2387,10]]},"3301":{"position":[[6774,9],[6796,10],[6819,10],[7563,10]]}}}],["artifactori",{"_index":10078,"t":{"3299":{"position":[[5339,11]]}}}],["as4610",{"_index":4718,"t":{"993":{"position":[[13,6]]}}}],["as5835",{"_index":4722,"t":{"993":{"position":[[47,6]]}}}],["as7326",{"_index":4727,"t":{"995":{"position":[[770,6]]}}}],["as7726",{"_index":4730,"t":{"995":{"position":[[805,6]]},"997":{"position":[[24,6]]}}}],["as9716",{"_index":4734,"t":{"997":{"position":[[59,6]]}}}],["asahi",{"_index":1725,"t":{"247":{"position":[[3245,5]]}}}],["ascii",{"_index":7124,"t":{"1591":{"position":[[969,5]]},"1913":{"position":[[163,5]]},"2029":{"position":[[163,5]]},"2625":{"position":[[728,5]]}}}],["asd",{"_index":807,"t":{"129":{"position":[[167,3],[171,3]]}}}],["asdasdasdasd",{"_index":806,"t":{"129":{"position":[[154,12]]}}}],["ask",{"_index":739,"t":{"109":{"position":[[167,3]]},"118":{"position":[[115,3]]},"204":{"position":[[260,3],[283,3]]},"247":{"position":[[3,3],[1906,4]]},"263":{"position":[[155,6]]},"313":{"position":[[38,3]]},"315":{"position":[[243,3]]},"590":{"position":[[332,3]]},"631":{"position":[[507,3]]},"903":{"position":[[2301,5]]},"1256":{"position":[[2361,3]]},"1625":{"position":[[2301,5]]},"1825":{"position":[[2291,3]]},"2067":{"position":[[375,3]]},"2350":{"position":[[2301,5]]},"2631":{"position":[[1081,5]]},"2688":{"position":[[2017,3]]},"2731":{"position":[[1215,3]]},"2770":{"position":[[1238,3]]},"2860":{"position":[[1211,3]]},"3251":{"position":[[3402,5]]},"3436":{"position":[[215,3]]},"3482":{"position":[[568,5]]}}}],["asl2",{"_index":1155,"t":{"170":{"position":[[2096,7]]}}}],["aspect",{"_index":582,"t":{"79":{"position":[[396,7]]},"511":{"position":[[644,7]]},"600":{"position":[[1154,7]]},"932":{"position":[[3101,6]]},"1654":{"position":[[3101,6]]},"1863":{"position":[[38,7]]},"1925":{"position":[[38,7]]},"2176":{"position":[[1315,6]]},"2281":{"position":[[1041,7]]},"2379":{"position":[[3101,6]]},"2526":{"position":[[253,7]]},"2673":{"position":[[1523,7]]},"2697":{"position":[[813,7]]},"2742":{"position":[[712,7]]},"2795":{"position":[[747,7]]},"2832":{"position":[[813,7]]},"2888":{"position":[[105,7],[143,7]]},"2962":{"position":[[162,7]]},"2964":{"position":[[308,7]]},"2966":{"position":[[510,6]]},"2970":{"position":[[0,6]]},"3023":{"position":[[231,6]]},"3025":{"position":[[250,7]]},"3029":{"position":[[59,8],[226,7],[276,8],[475,7],[523,6]]},"3031":{"position":[[32,7],[162,6],[183,6],[449,7],[536,7]]},"3039":{"position":[[10,7],[411,8]]},"3042":{"position":[[260,6],[325,9]]},"3044":{"position":[[557,6],[623,9]]},"3218":{"position":[[455,6]]},"3251":{"position":[[2709,7]]},"3278":{"position":[[37,7]]},"3301":{"position":[[697,8]]},"3395":{"position":[[1221,6]]},"3417":{"position":[[160,7]]}}}],["aspect2",{"_index":9708,"t":{"3029":{"position":[[435,8]]}}}],["aspectn",{"_index":9709,"t":{"3029":{"position":[[449,11]]}}}],["assembl",{"_index":4820,"t":{"1039":{"position":[[112,9]]},"1041":{"position":[[323,9]]},"2235":{"position":[[881,10]]}}}],["assert",{"_index":1240,"t":{"176":{"position":[[1098,6]]},"286":{"position":[[402,6]]},"2756":{"position":[[50,10]]}}}],["assess",{"_index":2989,"t":{"583":{"position":[[468,8]]},"2081":{"position":[[106,11]]},"2688":{"position":[[1751,10],[2115,10]]},"3156":{"position":[[107,6]]},"3158":{"position":[[571,10]]},"3251":{"position":[[5624,6]]},"3299":{"position":[[265,10],[1096,10],[2366,10],[3621,10],[4718,10]]}}}],["asset",{"_index":2345,"t":{"396":{"position":[[90,6],[231,5]]},"786":{"position":[[77,6]]},"1523":{"position":[[77,6]]},"1872":{"position":[[736,6]]},"1988":{"position":[[736,6]]},"2461":{"position":[[1110,6]]},"2470":{"position":[[123,6]]},"2688":{"position":[[2452,7]]}}}],["assign",{"_index":226,"t":{"18":{"position":[[206,6]]},"101":{"position":[[317,8]]},"178":{"position":[[48,11],[1146,11],[1617,11]]},"302":{"position":[[168,6]]},"325":{"position":[[5945,8]]},"742":{"position":[[260,6]]},"754":{"position":[[230,8]]},"762":{"position":[[259,8]]},"813":{"position":[[100,6]]},"815":{"position":[[158,6]]},"819":{"position":[[387,6],[1449,6],[1467,6],[2581,6]]},"821":{"position":[[452,6],[842,6],[860,6],[1814,6]]},"905":{"position":[[2106,8]]},"1043":{"position":[[483,8]]},"1067":{"position":[[1752,6],[1807,8]]},"1077":{"position":[[150,8]]},"1112":{"position":[[1457,8]]},"1124":{"position":[[959,8]]},"1150":{"position":[[6157,6],[7145,11],[9111,11],[9236,10],[9415,10],[9596,10],[9753,10],[13136,9]]},"1351":{"position":[[1210,6]]},"1353":{"position":[[42,8],[101,10]]},"1503":{"position":[[100,6]]},"1505":{"position":[[158,6]]},"1509":{"position":[[387,6],[1449,6],[1467,6],[2581,6]]},"1511":{"position":[[452,6],[842,6],[860,6],[1814,6]]},"1627":{"position":[[2106,8]]},"1728":{"position":[[981,8]]},"1740":{"position":[[196,9]]},"1853":{"position":[[378,8],[441,11],[526,8],[841,8]]},"1861":{"position":[[58,8]]},"1865":{"position":[[28,8]]},"1915":{"position":[[378,8],[441,11],[526,8],[841,8]]},"1923":{"position":[[58,8]]},"1927":{"position":[[28,8]]},"2037":{"position":[[218,11]]},"2039":{"position":[[75,9],[809,6]]},"2047":{"position":[[44,6],[249,6]]},"2053":{"position":[[588,10],[1039,6]]},"2067":{"position":[[5,11],[105,8],[416,12],[429,9],[531,9],[656,10],[768,10],[870,12],[883,9],[988,9],[1116,10],[1231,10]]},"2352":{"position":[[2106,8]]},"2625":{"position":[[77,8]]},"2631":{"position":[[1027,8]]},"2700":{"position":[[586,9]]},"2727":{"position":[[195,9]]},"2745":{"position":[[586,9]]},"2766":{"position":[[217,9]]},"2805":{"position":[[745,10]]},"2813":{"position":[[1396,10]]},"2852":{"position":[[574,9]]},"3078":{"position":[[527,8],[588,8]]},"3184":{"position":[[1555,6]]},"3251":{"position":[[4970,6]]},"3325":{"position":[[1637,6]]},"3361":{"position":[[463,6]]},"3457":{"position":[[177,9],[294,11],[424,6],[484,9],[724,9]]},"3459":{"position":[[169,12],[247,8],[423,8]]},"3461":{"position":[[327,7],[578,11]]},"3463":{"position":[[372,6],[538,10]]},"3465":{"position":[[42,11],[135,6],[569,11],[1202,11],[1536,11]]},"3472":{"position":[[6000,6],[6954,11],[8920,11],[9045,10],[9224,10],[9405,10],[9562,10]]},"3475":{"position":[[197,10]]},"3482":{"position":[[383,8]]}}}],["assign/revok",{"_index":10251,"t":{"3482":{"position":[[896,13],[1067,13]]}}}],["assigne",{"_index":1262,"t":{"178":{"position":[[349,10]]}}}],["assigned/revok",{"_index":10244,"t":{"3472":{"position":[[13665,16]]}}}],["assist",{"_index":3599,"t":{"722":{"position":[[65,11]]},"780":{"position":[[440,7]]},"2675":{"position":[[251,7]]}}}],["associ",{"_index":1614,"t":{"245":{"position":[[147,10]]},"372":{"position":[[627,10]]},"467":{"position":[[722,10]]},"982":{"position":[[115,10]]},"1351":{"position":[[830,12],[1317,9],[1540,12],[2354,12]]},"1728":{"position":[[1186,10]]},"2138":{"position":[[207,10]]},"2310":{"position":[[48,10]]},"2400":{"position":[[78,10]]},"2456":{"position":[[78,10]]},"2602":{"position":[[65,10]]},"2625":{"position":[[320,10]]},"2813":{"position":[[469,9]]},"2966":{"position":[[3548,10],[3907,10],[4039,11]]},"3186":{"position":[[1524,10]]},"3197":{"position":[[418,10]]},"3204":{"position":[[164,10],[454,10]]},"3206":{"position":[[312,10]]},"3270":{"position":[[1215,10]]},"3479":{"position":[[290,10]]}}}],["assum",{"_index":1896,"t":{"286":{"position":[[0,8]]},"315":{"position":[[277,6]]},"423":{"position":[[11,7]]},"467":{"position":[[11,7]]},"525":{"position":[[11,7]]},"598":{"position":[[1310,7]]},"604":{"position":[[10870,6]]},"627":{"position":[[5205,8]]},"654":{"position":[[35,7]]},"790":{"position":[[1360,7]]},"913":{"position":[[3804,7]]},"1061":{"position":[[210,7]]},"1165":{"position":[[541,8]]},"1188":{"position":[[162,7]]},"1199":{"position":[[33,7]]},"1236":{"position":[[839,7]]},"1252":{"position":[[548,6]]},"1395":{"position":[[583,6]]},"1527":{"position":[[1360,7]]},"1635":{"position":[[3804,7]]},"1791":{"position":[[907,8],[1866,8]]},"1957":{"position":[[0,6],[392,8],[2238,6]]},"2360":{"position":[[3804,7]]},"2721":{"position":[[26,7]]},"2725":{"position":[[715,7]]},"2760":{"position":[[39,7]]},"2764":{"position":[[936,7]]},"2846":{"position":[[26,7]]},"2850":{"position":[[608,7]]},"2960":{"position":[[410,6]]},"3276":{"position":[[1864,7]]}}}],["assumpt",{"_index":9165,"t":{"2709":{"position":[[284,11]]},"2754":{"position":[[284,11]]},"2844":{"position":[[212,11]]},"3245":{"position":[[4,10]]},"3262":{"position":[[62,10]]}}}],["assur",{"_index":1290,"t":{"178":{"position":[[2164,9]]},"2283":{"position":[[443,6]]},"2310":{"position":[[643,8]]},"2315":{"position":[[87,6]]},"2486":{"position":[[458,9]]}}}],["asterisk",{"_index":1763,"t":{"251":{"position":[[495,8]]}}}],["asynchron",{"_index":2565,"t":{"458":{"position":[[102,12]]},"2075":{"position":[[218,12]]}}}],["atm",{"_index":244,"t":{"23":{"position":[[168,3]]}}}],["atom",{"_index":6032,"t":{"1226":{"position":[[400,6],[450,6],[465,6],[517,6]]},"1587":{"position":[[1373,6]]},"3314":{"position":[[1748,4]]}}}],["attach",{"_index":1974,"t":{"302":{"position":[[1456,8]]},"552":{"position":[[641,8]]},"570":{"position":[[5,6],[56,6]]},"615":{"position":[[1489,10]]},"774":{"position":[[156,8]]},"903":{"position":[[3216,6]]},"913":{"position":[[3780,6]]},"945":{"position":[[159,6]]},"947":{"position":[[2037,6]]},"949":{"position":[[446,8]]},"1625":{"position":[[3216,6]]},"1635":{"position":[[3780,6]]},"1667":{"position":[[159,6]]},"1669":{"position":[[2037,6]]},"1671":{"position":[[446,8]]},"1779":{"position":[[6410,8]]},"1829":{"position":[[352,8]]},"1845":{"position":[[1427,8]]},"1847":{"position":[[646,8],[1019,10]]},"1872":{"position":[[337,8]]},"1880":{"position":[[145,8],[298,8]]},"1886":{"position":[[30,8],[195,8]]},"1890":{"position":[[12,8]]},"1892":{"position":[[73,8],[256,8]]},"1911":{"position":[[137,9],[183,8],[347,9]]},"1988":{"position":[[337,8]]},"1996":{"position":[[145,8],[298,8]]},"2002":{"position":[[30,8],[195,8]]},"2006":{"position":[[12,8]]},"2008":{"position":[[73,8],[256,8]]},"2027":{"position":[[137,9],[183,8],[347,9]]},"2350":{"position":[[3216,6]]},"2360":{"position":[[3780,6]]},"2392":{"position":[[159,6]]},"2394":{"position":[[2037,6]]},"2396":{"position":[[446,8]]},"2711":{"position":[[1315,8]]},"2856":{"position":[[1293,8]]},"2895":{"position":[[427,9]]},"2901":{"position":[[298,8]]},"2933":{"position":[[846,8]]},"2947":{"position":[[6087,8]]},"2951":{"position":[[194,8]]},"2960":{"position":[[1053,8]]},"2966":{"position":[[1557,8],[2232,6]]},"3353":{"position":[[246,8]]}}}],["attack",{"_index":1059,"t":{"168":{"position":[[439,8]]},"247":{"position":[[2292,7]]},"436":{"position":[[712,7]]},"1857":{"position":[[783,9]]},"1919":{"position":[[783,9]]},"3103":{"position":[[956,7]]},"3266":{"position":[[560,8]]}}}],["attain",{"_index":9082,"t":{"2684":{"position":[[274,6]]}}}],["attempt",{"_index":1232,"t":{"176":{"position":[[728,8]]},"302":{"position":[[288,7]]},"1234":{"position":[[2504,7]]},"1256":{"position":[[1754,10]]},"1791":{"position":[[677,7]]},"1957":{"position":[[1738,7]]},"2688":{"position":[[2948,7]]},"3137":{"position":[[254,8]]}}}],["attent",{"_index":1696,"t":{"247":{"position":[[1824,10]]},"325":{"position":[[2936,10]]},"2296":{"position":[[168,9]]},"3251":{"position":[[4240,9]]}}}],["attr",{"_index":5246,"t":{"1112":{"position":[[5043,4],[5226,4],[5390,4]]},"1114":{"position":[[2103,4],[2365,4],[2603,4],[5546,4],[5869,4],[6159,4]]}}}],["attract",{"_index":9646,"t":{"2966":{"position":[[752,10]]},"3150":{"position":[[529,7]]},"3301":{"position":[[4223,8]]}}}],["attribut",{"_index":1723,"t":{"247":{"position":[[3184,12]]},"633":{"position":[[1123,11],[1141,9],[1392,9]]},"796":{"position":[[165,9]]},"798":{"position":[[225,9]]},"949":{"position":[[1180,11]]},"1031":{"position":[[65,10],[184,9],[804,9]]},"1533":{"position":[[165,9]]},"1535":{"position":[[225,9]]},"1671":{"position":[[1180,11]]},"1865":{"position":[[938,11]]},"1872":{"position":[[555,9]]},"1878":{"position":[[734,9]]},"1894":{"position":[[623,10]]},"1900":{"position":[[355,10],[534,10]]},"1904":{"position":[[583,9]]},"1908":{"position":[[2079,9],[2156,10],[2678,9]]},"1913":{"position":[[2157,11]]},"1959":{"position":[[954,9],[1018,9]]},"1988":{"position":[[555,9]]},"1994":{"position":[[734,9]]},"2010":{"position":[[623,10]]},"2016":{"position":[[355,10],[534,10]]},"2020":{"position":[[583,9]]},"2024":{"position":[[2079,9],[2156,10],[2678,9]]},"2540":{"position":[[258,9]]},"2879":{"position":[[54,10],[99,10]]},"2881":{"position":[[226,9]]},"2906":{"position":[[154,10]]},"2913":{"position":[[87,9],[140,9]]},"3325":{"position":[[3443,10]]}}}],["audienc",{"_index":1390,"t":{"193":{"position":[[543,9]]},"2188":{"position":[[87,8]]}}}],["audio/video",{"_index":1759,"t":{"251":{"position":[[372,12]]}}}],["audit",{"_index":558,"t":{"75":{"position":[[94,5]]},"1234":{"position":[[2809,6]]},"2671":{"position":[[1169,6]]},"3103":{"position":[[424,8]]},"3115":{"position":[[197,7]]},"3160":{"position":[[408,5],[444,9]]},"3251":{"position":[[4100,5]]},"3301":{"position":[[5763,5]]}}}],["audit_period_begin",{"_index":8707,"t":{"2566":{"position":[[1358,23],[11143,23],[12979,23]]}}}],["audit_period_end",{"_index":8709,"t":{"2566":{"position":[[1436,20],[11221,20],[13057,20]]}}}],["augment",{"_index":7904,"t":{"1857":{"position":[[117,9]]},"1919":{"position":[[117,9]]}}}],["auth",{"_index":436,"t":{"44":{"position":[[55,4]]},"51":{"position":[[50,4]]},"302":{"position":[[1566,6]]},"650":{"position":[[436,5]]},"819":{"position":[[7742,5]]},"905":{"position":[[369,5],[594,5],[1305,5]]},"932":{"position":[[4507,6]]},"934":{"position":[[1400,4],[2019,4]]},"1108":{"position":[[762,4]]},"1509":{"position":[[7742,5]]},"1627":{"position":[[369,5],[594,5],[1305,5]]},"1654":{"position":[[4507,6]]},"1656":{"position":[[1400,4],[2019,4]]},"1745":{"position":[[396,4]]},"1758":{"position":[[304,4],[436,4],[494,4]]},"1779":{"position":[[2072,5],[2353,5],[2459,5],[2708,5]]},"1791":{"position":[[2125,4],[2179,4],[2930,4],[2984,4]]},"2110":{"position":[[168,6]]},"2352":{"position":[[369,5],[594,5],[1305,5]]},"2379":{"position":[[4507,6]]},"2381":{"position":[[1400,4],[2019,4]]},"3314":{"position":[[1448,4]]},"3316":{"position":[[597,4],[606,4],[648,4]]}}}],["auth.github",{"_index":4571,"t":{"932":{"position":[[1518,13]]},"934":{"position":[[1447,13]]},"1654":{"position":[[1518,13]]},"1656":{"position":[[1447,13]]},"2379":{"position":[[1518,13]]},"2381":{"position":[[1447,13]]}}}],["auth=fals",{"_index":9979,"t":{"3236":{"position":[[2315,11]]}}}],["auth_token=token",{"_index":7438,"t":{"1758":{"position":[[261,16]]}}}],["auth_typ",{"_index":4379,"t":{"905":{"position":[[1270,10]]},"1627":{"position":[[1270,10]]},"1779":{"position":[[2146,10]]},"2352":{"position":[[1270,10]]}}}],["auth_url",{"_index":3481,"t":{"650":{"position":[[442,9]]},"819":{"position":[[7748,9]]},"905":{"position":[[375,9]]},"1509":{"position":[[7748,9]]},"1627":{"position":[[375,9]]},"2033":{"position":[[583,11]]},"2352":{"position":[[375,9]]}}}],["authent",{"_index":622,"t":{"101":{"position":[[131,12],[636,14]]},"249":{"position":[[336,15]]},"290":{"position":[[577,14]]},"296":{"position":[[29,14]]},"298":{"position":[[297,14]]},"302":{"position":[[387,14]]},"467":{"position":[[573,14],[609,12]]},"501":{"position":[[104,12],[300,14]]},"530":{"position":[[217,14]]},"633":{"position":[[1478,14]]},"762":{"position":[[62,14],[437,14]]},"905":{"position":[[1123,13]]},"1256":{"position":[[2061,14],[2164,15],[2690,15]]},"1591":{"position":[[907,15]]},"1627":{"position":[[1123,13]]},"1791":{"position":[[0,14],[261,12],[688,12]]},"1857":{"position":[[480,14]]},"1919":{"position":[[480,14]]},"1957":{"position":[[741,14],[3693,14],[3940,14]]},"1972":{"position":[[560,14],[670,14]]},"2083":{"position":[[414,14],[470,14]]},"2110":{"position":[[476,14]]},"2164":{"position":[[855,13]]},"2176":{"position":[[172,15]]},"2220":{"position":[[25,14]]},"2352":{"position":[[1123,13]]},"2463":{"position":[[335,14]]},"2574":{"position":[[135,15]]},"2576":{"position":[[362,14]]},"3160":{"position":[[507,14],[555,14],[672,14],[717,14],[1039,12]]},"3231":{"position":[[266,14]]},"3236":{"position":[[1042,14],[1111,14],[1168,12],[1391,13],[1543,12],[2327,14],[2478,14],[2616,13]]},"3238":{"position":[[567,14],[654,13],[803,14],[980,15]]},"3240":{"position":[[102,14],[135,14]]},"3245":{"position":[[918,14]]},"3247":{"position":[[315,15]]},"3251":{"position":[[3499,14]]},"3301":{"position":[[1222,16],[5780,14],[5852,14]]},"3314":{"position":[[406,14]]},"3367":{"position":[[37,14]]}}}],["authentication/author",{"_index":8048,"t":{"1972":{"position":[[360,30]]},"2164":{"position":[[438,28]]}}}],["authn",{"_index":8106,"t":{"2033":{"position":[[1872,5]]},"2176":{"position":[[767,5]]},"3367":{"position":[[52,7]]}}}],["authn/authz",{"_index":8047,"t":{"1972":{"position":[[348,11],[841,11]]},"1976":{"position":[[293,11]]}}}],["authn/authz/rest",{"_index":8053,"t":{"1974":{"position":[[689,18]]}}}],["author",{"_index":624,"t":{"101":{"position":[[164,14]]},"178":{"position":[[118,6],[421,7],[1786,13]]},"276":{"position":[[308,7]]},"278":{"position":[[5,7]]},"280":{"position":[[5,7],[336,7]]},"294":{"position":[[144,13]]},"296":{"position":[[48,13]]},"298":{"position":[[491,13]]},"302":{"position":[[861,13]]},"306":{"position":[[85,13]]},"404":{"position":[[293,9]]},"762":{"position":[[381,13]]},"895":{"position":[[95,6]]},"899":{"position":[[825,6]]},"903":{"position":[[4,6],[282,6]]},"949":{"position":[[1142,7]]},"1617":{"position":[[95,6]]},"1621":{"position":[[825,6]]},"1625":{"position":[[4,6],[282,6]]},"1671":{"position":[[1142,7]]},"1789":{"position":[[163,9]]},"1865":{"position":[[900,7]]},"1913":{"position":[[2119,7]]},"1939":{"position":[[303,13]]},"1949":{"position":[[49,13]]},"1957":{"position":[[4409,10]]},"2176":{"position":[[188,14]]},"2342":{"position":[[95,6]]},"2346":{"position":[[825,6]]},"2350":{"position":[[4,6],[282,6]]},"2574":{"position":[[151,14]]},"2576":{"position":[[450,14]]},"3103":{"position":[[1100,9]]},"3160":{"position":[[791,13]]},"3229":{"position":[[57,9]]},"3231":{"position":[[248,13]]},"3236":{"position":[[1061,14],[1130,14],[1185,9],[1641,13],[2497,14],[2520,13],[2701,13],[2821,13],[2959,13]]},"3238":{"position":[[586,11],[740,13],[822,13],[1000,15]]},"3240":{"position":[[121,13]]},"3245":{"position":[[1021,13]]},"3247":{"position":[[151,14]]},"3251":{"position":[[3518,13],[5136,13],[5295,13]]},"3255":{"position":[[657,13]]},"3264":{"position":[[110,9]]},"3266":{"position":[[334,9]]},"3276":{"position":[[116,9]]},"3301":{"position":[[5965,13]]},"3367":{"position":[[64,13]]},"3472":{"position":[[14539,9]]}}}],["authorit",{"_index":9003,"t":{"2623":{"position":[[725,14]]},"2629":{"position":[[583,14]]}}}],["authorization.k8s.io/v1beta1",{"_index":9982,"t":{"3236":{"position":[[2750,28]]}}}],["authorized_key",{"_index":6012,"t":{"1224":{"position":[[1084,15]]}}}],["authz",{"_index":8075,"t":{"1982":{"position":[[1689,6]]},"1984":{"position":[[1299,6]]},"2176":{"position":[[784,5]]},"2409":{"position":[[139,5]]},"3367":{"position":[[78,7]]}}}],["auto",{"_index":1820,"t":{"270":{"position":[[303,4]]},"487":{"position":[[4774,4]]},"509":{"position":[[592,7]]},"2152":{"position":[[608,5]]},"3272":{"position":[[1040,4],[1061,4]]},"3282":{"position":[[240,4],[272,4]]}}}],["autodetect",{"_index":2719,"t":{"485":{"position":[[854,13]]}}}],["autogener",{"_index":2780,"t":{"487":{"position":[[2423,13],[2522,13]]}}}],["autoinstal",{"_index":7003,"t":{"1569":{"position":[[345,11],[423,11]]}}}],["autom",{"_index":1732,"t":{"249":{"position":[[137,9]]},"335":{"position":[[0,9],[59,9]]},"344":{"position":[[63,9]]},"513":{"position":[[1086,10],[1438,10]]},"583":{"position":[[166,9]]},"604":{"position":[[532,10]]},"883":{"position":[[772,8],[1863,8],[1984,10],[2160,10]]},"888":{"position":[[1428,9],[1467,9],[1588,10],[2318,9]]},"895":{"position":[[777,11],[814,8]]},"936":{"position":[[67,8]]},"956":{"position":[[447,9],[586,10]]},"1184":{"position":[[515,8]]},"1587":{"position":[[138,9]]},"1617":{"position":[[777,11],[814,8]]},"1658":{"position":[[67,8]]},"1878":{"position":[[1176,9]]},"1955":{"position":[[484,8]]},"1963":{"position":[[88,10],[657,9]]},"1982":{"position":[[62,10]]},"1994":{"position":[[1176,9]]},"2073":{"position":[[32,9]]},"2077":{"position":[[431,10],[475,9]]},"2085":{"position":[[551,9]]},"2116":{"position":[[979,9]]},"2164":{"position":[[586,11]]},"2190":{"position":[[6,9]]},"2229":{"position":[[670,10]]},"2235":{"position":[[144,10],[837,8]]},"2248":{"position":[[1144,10],[1160,10]]},"2276":{"position":[[109,9]]},"2283":{"position":[[411,9]]},"2342":{"position":[[777,11],[814,8]]},"2383":{"position":[[67,8]]},"2411":{"position":[[134,9]]},"2426":{"position":[[75,9]]},"2486":{"position":[[682,9]]},"2548":{"position":[[387,9]]},"2688":{"position":[[2713,9],[2846,9]]},"2801":{"position":[[317,10]]},"2813":{"position":[[643,9],[664,9]]},"2944":{"position":[[1091,12]]},"3046":{"position":[[87,9]]},"3135":{"position":[[129,11]]},"3160":{"position":[[864,10]]},"3276":{"position":[[2223,8]]},"3301":{"position":[[5985,10],[7165,11]]}}}],["automat",{"_index":1790,"t":{"253":{"position":[[1916,13]]},"280":{"position":[[264,13]]},"290":{"position":[[495,13]]},"302":{"position":[[530,13]]},"325":{"position":[[2996,13]]},"387":{"position":[[191,13]]},"391":{"position":[[633,14]]},"460":{"position":[[665,14]]},"491":{"position":[[9,13]]},"499":{"position":[[2006,13]]},"586":{"position":[[141,13],[155,9]]},"600":{"position":[[1361,13]]},"604":{"position":[[1505,13]]},"639":{"position":[[402,13],[789,13]]},"644":{"position":[[835,13]]},"646":{"position":[[291,13]]},"805":{"position":[[23,13]]},"913":{"position":[[3331,13]]},"938":{"position":[[61,14]]},"977":{"position":[[1456,13]]},"1089":{"position":[[2439,14],[2855,13]]},"1112":{"position":[[1213,14]]},"1217":{"position":[[921,14]]},"1232":{"position":[[212,13],[461,13]]},"1234":{"position":[[2898,9]]},"1258":{"position":[[725,14]]},"1386":{"position":[[242,13]]},"1419":{"position":[[334,13]]},"1542":{"position":[[23,13]]},"1560":{"position":[[459,14]]},"1591":{"position":[[170,9]]},"1635":{"position":[[3331,13]]},"1660":{"position":[[61,14]]},"1705":{"position":[[46,13],[124,13]]},"1719":{"position":[[54,13]]},"1779":{"position":[[2806,13]]},"1791":{"position":[[77,13]]},"1904":{"position":[[684,14]]},"1951":{"position":[[192,13]]},"2020":{"position":[[684,14]]},"2061":{"position":[[267,13]]},"2063":{"position":[[285,13]]},"2065":{"position":[[273,13]]},"2096":{"position":[[1659,9]]},"2152":{"position":[[158,9],[650,13]]},"2330":{"position":[[786,13]]},"2360":{"position":[[3331,13]]},"2385":{"position":[[61,14]]},"2631":{"position":[[2437,13]]},"2675":{"position":[[799,13]]},"2709":{"position":[[900,9]]},"2754":{"position":[[1041,9]]},"2844":{"position":[[828,9]]},"2899":{"position":[[1160,13]]},"2960":{"position":[[708,13]]},"3044":{"position":[[369,9]]},"3078":{"position":[[342,13],[510,13]]},"3080":{"position":[[146,13],[503,13]]},"3084":{"position":[[451,13]]},"3135":{"position":[[97,13]]},"3236":{"position":[[1479,13]]},"3276":{"position":[[323,14],[456,14],[944,9],[1683,13],[1764,10],[2017,9]]},"3288":{"position":[[167,9]]},"3301":{"position":[[3913,13]]},"3314":{"position":[[2913,13]]},"3397":{"position":[[1937,9],[2172,9]]},"3457":{"position":[[410,13]]}}}],["autonom",{"_index":3697,"t":{"768":{"position":[[91,9]]}}}],["autonomi",{"_index":2127,"t":{"327":{"position":[[503,8]]},"366":{"position":[[397,8]]}}}],["autosc",{"_index":6923,"t":{"1462":{"position":[[6,11]]}}}],["autoscal",{"_index":6915,"t":{"1454":{"position":[[16,9]]}}}],["autosubscrib",{"_index":3522,"t":{"660":{"position":[[823,14],[1298,13]]}}}],["avail",{"_index":998,"t":{"158":{"position":[[681,9]]},"168":{"position":[[357,9],[851,9],[934,10]]},"172":{"position":[[185,9],[519,9],[649,9]]},"174":{"position":[[1235,9]]},"176":{"position":[[284,10]]},"198":{"position":[[0,14]]},"202":{"position":[[328,11]]},"204":{"position":[[57,13]]},"206":{"position":[[6,9],[30,9],[156,10]]},"210":{"position":[[98,9]]},"212":{"position":[[67,9],[134,14]]},"223":{"position":[[187,9]]},"247":{"position":[[1623,10]]},"311":{"position":[[196,10]]},"321":{"position":[[110,9],[401,9],[780,9],[823,9]]},"323":{"position":[[777,9]]},"349":{"position":[[571,9]]},"391":{"position":[[1328,9]]},"423":{"position":[[82,9]]},"438":{"position":[[122,9]]},"444":{"position":[[214,9]]},"467":{"position":[[82,9]]},"485":{"position":[[647,9],[705,12]]},"489":{"position":[[311,9],[421,10]]},"495":{"position":[[352,12],[1239,12]]},"505":{"position":[[205,12]]},"590":{"position":[[215,9]]},"594":{"position":[[17,9]]},"604":{"position":[[1015,9],[2437,15],[2468,9]]},"627":{"position":[[1733,9]]},"639":{"position":[[503,9]]},"641":{"position":[[880,9]]},"654":{"position":[[166,12],[270,12]]},"669":{"position":[[57,10]]},"698":{"position":[[22,9]]},"730":{"position":[[1474,9]]},"732":{"position":[[33,9]]},"734":{"position":[[73,9]]},"738":{"position":[[57,12],[337,9]]},"740":{"position":[[3,12],[151,12],[302,12],[445,12],[630,12]]},"742":{"position":[[593,12],[690,12],[882,12],[928,12],[1012,12],[1068,12]]},"746":{"position":[[102,12]]},"803":{"position":[[145,12]]},"805":{"position":[[69,9],[142,9]]},"827":{"position":[[44,9]]},"859":{"position":[[1004,12],[1752,12],[2075,12]]},"880":{"position":[[590,12]]},"888":{"position":[[1684,12],[1735,12]]},"899":{"position":[[492,9]]},"901":{"position":[[482,12]]},"956":{"position":[[1537,9],[1680,10]]},"977":{"position":[[1278,12],[1440,12],[1823,13],[2617,12]]},"980":{"position":[[351,9]]},"982":{"position":[[372,12]]},"995":{"position":[[157,10]]},"1055":{"position":[[21,9]]},"1065":{"position":[[786,9]]},"1067":{"position":[[1482,9],[4023,9]]},"1071":{"position":[[856,9]]},"1073":{"position":[[90,9]]},"1089":{"position":[[881,9]]},"1112":{"position":[[344,10]]},"1120":{"position":[[1136,9]]},"1124":{"position":[[826,9],[1017,10]]},"1156":{"position":[[123,9]]},"1217":{"position":[[850,10]]},"1224":{"position":[[4066,9]]},"1226":{"position":[[268,10]]},"1232":{"position":[[513,9],[663,9]]},"1234":{"position":[[393,9]]},"1240":{"position":[[529,9]]},"1290":{"position":[[389,10]]},"1292":{"position":[[832,10]]},"1321":{"position":[[326,5],[983,5]]},"1323":{"position":[[17,9]]},"1331":{"position":[[21,9]]},"1351":{"position":[[2775,10]]},"1356":{"position":[[29,9],[98,9]]},"1362":{"position":[[1802,12]]},"1400":{"position":[[668,9]]},"1491":{"position":[[1474,9]]},"1493":{"position":[[33,9]]},"1495":{"position":[[73,9]]},"1517":{"position":[[44,9]]},"1540":{"position":[[145,12]]},"1542":{"position":[[69,9],[142,9]]},"1562":{"position":[[527,9],[634,9]]},"1578":{"position":[[286,12]]},"1580":{"position":[[168,9]]},"1585":{"position":[[3600,9]]},"1594":{"position":[[180,9]]},"1603":{"position":[[1004,12],[1752,12],[2075,12]]},"1621":{"position":[[492,9]]},"1623":{"position":[[482,12]]},"1678":{"position":[[934,9],[1112,9],[1449,9],[2772,10]]},"1684":{"position":[[1357,9],[1676,9],[1997,9],[2328,9],[2650,9],[2972,9],[3293,9],[3609,9]]},"1690":{"position":[[147,9],[384,12]]},"1738":{"position":[[255,9]]},"1764":{"position":[[4529,9]]},"1773":{"position":[[809,9]]},"1779":{"position":[[3987,10],[4309,9]]},"1785":{"position":[[741,9]]},"1791":{"position":[[1062,9],[1102,9]]},"1829":{"position":[[83,9]]},"1845":{"position":[[301,9]]},"1849":{"position":[[685,10]]},"1882":{"position":[[336,9]]},"1888":{"position":[[41,9]]},"1890":{"position":[[132,10]]},"1892":{"position":[[828,9]]},"1908":{"position":[[1427,11],[2577,10],[2898,11],[3103,11]]},"1998":{"position":[[336,9]]},"2004":{"position":[[41,9]]},"2006":{"position":[[132,10]]},"2008":{"position":[[828,9]]},"2024":{"position":[[1427,11],[2577,10],[2898,11],[3103,11]]},"2049":{"position":[[40,9]]},"2059":{"position":[[40,9]]},"2067":{"position":[[1545,12]]},"2069":{"position":[[218,12]]},"2087":{"position":[[95,9]]},"2096":{"position":[[1475,9]]},"2098":{"position":[[161,9]]},"2112":{"position":[[95,9]]},"2132":{"position":[[121,9]]},"2154":{"position":[[852,9],[1522,9]]},"2162":{"position":[[248,10]]},"2164":{"position":[[603,12]]},"2209":{"position":[[143,10]]},"2214":{"position":[[425,9]]},"2233":{"position":[[488,12]]},"2245":{"position":[[91,9],[240,9]]},"2248":{"position":[[1034,9],[1296,9]]},"2250":{"position":[[653,9]]},"2257":{"position":[[248,9]]},"2259":{"position":[[653,9]]},"2278":{"position":[[82,9],[397,10],[626,10]]},"2281":{"position":[[1243,9]]},"2283":{"position":[[771,9],[933,9],[1152,9]]},"2292":{"position":[[409,9],[771,9]]},"2312":{"position":[[37,10],[695,9]]},"2315":{"position":[[105,9]]},"2324":{"position":[[442,9],[528,9],[637,9]]},"2346":{"position":[[492,9]]},"2348":{"position":[[482,12]]},"2405":{"position":[[46,9]]},"2409":{"position":[[818,10],[902,9]]},"2472":{"position":[[315,9]]},"2489":{"position":[[190,9]]},"2504":{"position":[[33,9]]},"2518":{"position":[[210,9]]},"2540":{"position":[[58,9],[476,12]]},"2550":{"position":[[437,12]]},"2592":{"position":[[795,12]]},"2688":{"position":[[2589,9]]},"2697":{"position":[[477,9]]},"2700":{"position":[[278,9]]},"2723":{"position":[[257,10]]},"2745":{"position":[[278,9]]},"2750":{"position":[[1353,10],[1454,9]]},"2762":{"position":[[270,10]]},"2832":{"position":[[477,9]]},"2835":{"position":[[219,9]]},"2848":{"position":[[257,10]]},"2870":{"position":[[151,9]]},"2872":{"position":[[270,10],[392,10]]},"2874":{"position":[[641,9],[922,9]]},"2876":{"position":[[142,9]]},"2895":{"position":[[2531,9]]},"2897":{"position":[[549,9]]},"2911":{"position":[[523,9]]},"2921":{"position":[[369,9]]},"2942":{"position":[[92,9]]},"2944":{"position":[[918,9]]},"2947":{"position":[[6062,9]]},"2966":{"position":[[1083,12],[1103,12]]},"3011":{"position":[[2493,9]]},"3023":{"position":[[326,12]]},"3046":{"position":[[772,12]]},"3063":{"position":[[985,9]]},"3067":{"position":[[22,9]]},"3074":{"position":[[325,9]]},"3080":{"position":[[336,9]]},"3126":{"position":[[779,9]]},"3158":{"position":[[305,9]]},"3182":{"position":[[183,13],[216,12],[1874,13]]},"3184":{"position":[[315,12],[408,12],[614,13],[693,9],[2282,12],[2380,12],[2484,12]]},"3186":{"position":[[891,12]]},"3188":{"position":[[16,12],[61,12]]},"3195":{"position":[[465,13]]},"3197":{"position":[[168,12],[261,9]]},"3199":{"position":[[123,9]]},"3201":{"position":[[59,9],[297,9]]},"3222":{"position":[[244,9]]},"3236":{"position":[[735,9],[863,9]]},"3251":{"position":[[5361,9]]},"3255":{"position":[[972,9]]},"3270":{"position":[[523,9],[885,9]]},"3299":{"position":[[1198,9],[1651,9],[2684,9],[3020,9],[3904,9],[4161,9],[4783,9]]},"3301":{"position":[[3040,9]]},"3376":{"position":[[801,9]]},"3378":{"position":[[973,9]]},"3393":{"position":[[1023,9]]},"3431":{"position":[[380,12]]},"3434":{"position":[[421,9]]},"3444":{"position":[[32,12]]},"3482":{"position":[[1506,9]]},"3518":{"position":[[1851,12]]}}}],["availab",{"_index":9509,"t":{"2874":{"position":[[764,8]]}}}],["availability_zon",{"_index":2711,"t":{"485":{"position":[[657,17]]},"660":{"position":[[48,17]]},"1773":{"position":[[1144,17]]},"1808":{"position":[[176,17]]},"2566":{"position":[[1134,18],[1912,18],[3118,18],[12005,18]]}}}],["availbl",{"_index":3645,"t":{"738":{"position":[[245,11],[360,11]]},"742":{"position":[[672,11]]}}}],["averag",{"_index":6455,"t":{"1333":{"position":[[256,8]]},"1339":{"position":[[209,8]]}}}],["avoid",{"_index":1014,"t":{"166":{"position":[[173,6],[823,5]]},"168":{"position":[[861,6]]},"174":{"position":[[363,5]]},"178":{"position":[[2306,5]]},"284":{"position":[[536,5]]},"325":{"position":[[3985,5]]},"417":{"position":[[485,8]]},"487":{"position":[[3027,5]]},"606":{"position":[[60,5],[125,5]]},"633":{"position":[[2651,5]]},"652":{"position":[[755,8]]},"895":{"position":[[369,6]]},"907":{"position":[[569,5]]},"915":{"position":[[725,5]]},"917":{"position":[[474,6]]},"949":{"position":[[183,5]]},"1120":{"position":[[1077,5]]},"1286":{"position":[[1340,6]]},"1397":{"position":[[324,5]]},"1617":{"position":[[369,6]]},"1629":{"position":[[569,5]]},"1637":{"position":[[725,5]]},"1639":{"position":[[474,6]]},"1671":{"position":[[183,5]]},"2248":{"position":[[398,8]]},"2263":{"position":[[115,5]]},"2342":{"position":[[369,6]]},"2354":{"position":[[569,5]]},"2362":{"position":[[725,5]]},"2364":{"position":[[474,6]]},"2396":{"position":[[183,5]]},"2424":{"position":[[125,5]]},"2468":{"position":[[795,5]]},"2502":{"position":[[476,6]]},"2504":{"position":[[347,5]]},"2651":{"position":[[408,8]]},"2658":{"position":[[204,8]]},"2695":{"position":[[133,5]]},"2719":{"position":[[1357,5]]},"2731":{"position":[[384,5]]},"2740":{"position":[[133,5]]},"2758":{"position":[[1355,5]]},"2770":{"position":[[384,5]]},"2830":{"position":[[133,5]]},"2860":{"position":[[384,5]]},"2895":{"position":[[4053,5]]},"2947":{"position":[[125,8],[1345,5],[1861,5],[3959,6],[5262,6]]},"3031":{"position":[[363,5]]},"3078":{"position":[[57,5]]},"3080":{"position":[[718,5]]},"3186":{"position":[[404,8]]},"3245":{"position":[[653,6]]},"3251":{"position":[[2121,5]]},"3266":{"position":[[360,9],[460,8]]},"3276":{"position":[[220,5]]},"3286":{"position":[[13,8],[104,5],[288,5]]},"3314":{"position":[[3473,5]]},"3325":{"position":[[2988,5]]},"3453":{"position":[[313,5]]},"3482":{"position":[[2650,5]]}}}],["aw",{"_index":182,"t":{"12":{"position":[[7,3]]},"427":{"position":[[519,3]]},"467":{"position":[[2067,6],[2275,3],[2355,3],[2545,3],[2601,3]]},"471":{"position":[[660,3],[1587,3]]},"883":{"position":[[1006,5]]},"888":{"position":[[1231,4]]}}}],["awar",{"_index":1257,"t":{"178":{"position":[[128,5]]},"270":{"position":[[10,5]]},"428":{"position":[[182,5]]},"472":{"position":[[1322,5]]},"596":{"position":[[2876,5]]},"609":{"position":[[1292,5],[4288,5]]},"1943":{"position":[[332,5]]},"2039":{"position":[[475,5]]},"2281":{"position":[[1203,6]]},"2430":{"position":[[20,5]]},"2966":{"position":[[922,5]]},"3160":{"position":[[1256,5]]},"3301":{"position":[[5281,5],[5471,5]]},"3370":{"position":[[227,5]]},"3434":{"position":[[227,5]]}}}],["away",{"_index":9103,"t":{"2697":{"position":[[1556,4]]},"2742":{"position":[[1455,4]]}}}],["awesom",{"_index":10102,"t":{"3310":{"position":[[513,7]]}}}],["aws/credenti",{"_index":2473,"t":{"427":{"position":[[612,18]]},"467":{"position":[[2025,18],[2078,19]]},"471":{"position":[[330,18],[789,18],[1680,18]]}}}],["aws:v1.6.1",{"_index":2472,"t":{"427":{"position":[[560,10]]},"471":{"position":[[1628,10]]}}}],["aws:v1.6.1,velero/velero",{"_index":2611,"t":{"471":{"position":[[701,24]]}}}],["aws_access_key_id",{"_index":2584,"t":{"467":{"position":[[1509,19],[1892,17],[2114,17],[2134,19]]}}}],["aws_secret_access_key",{"_index":2588,"t":{"467":{"position":[[1689,23],[1914,21],[2154,21],[2178,23]]}}}],["awscli",{"_index":2594,"t":{"467":{"position":[[2410,6],[2417,6]]}}}],["ax",{"_index":6465,"t":{"1337":{"position":[[130,2],[433,2]]},"1358":{"position":[[168,2]]},"1362":{"position":[[414,2]]}}}],["az",{"_index":4327,"t":{"901":{"position":[[730,2]]},"909":{"position":[[2488,5],[2562,2],[2758,2],[2790,2]]},"1623":{"position":[[730,2]]},"1631":{"position":[[2488,5],[2562,2],[2758,2],[2790,2]]},"2348":{"position":[[730,2]]},"2356":{"position":[[2488,5],[2562,2],[2758,2],[2790,2]]},"2966":{"position":[[1295,4],[1451,4],[1491,3],[1583,4]]},"2970":{"position":[[136,3]]},"3023":{"position":[[323,2]]},"3141":{"position":[[356,3]]},"3188":{"position":[[160,2]]},"3314":{"position":[[636,5]]}}}],["az'",{"_index":9888,"t":{"3141":{"position":[[438,4]]}}}],["azur",{"_index":2555,"t":{"451":{"position":[[295,8]]},"507":{"position":[[610,5]]},"883":{"position":[[1012,6]]},"888":{"position":[[1236,6]]}}}],["b",{"_index":720,"t":{"105":{"position":[[1986,1]]},"204":{"position":[[104,2]]},"253":{"position":[[413,3],[886,3]]},"604":{"position":[[3289,1]]},"669":{"position":[[517,2]]},"909":{"position":[[913,1],[916,1]]},"913":{"position":[[2331,1],[2334,1],[2415,1],[2418,1]]},"1150":{"position":[[5967,2]]},"1631":{"position":[[913,1],[916,1]]},"1635":{"position":[[2331,1],[2334,1],[2415,1],[2418,1]]},"2288":{"position":[[181,1]]},"2356":{"position":[[913,1],[916,1]]},"2360":{"position":[[2331,1],[2334,1],[2415,1],[2418,1]]},"2913":{"position":[[352,3]]},"3472":{"position":[[5810,2],[12598,2],[12885,2]]}}}],["b/f",{"_index":8370,"t":{"2190":{"position":[[394,4]]}}}],["b/w",{"_index":9312,"t":{"2731":{"position":[[773,3]]},"2770":{"position":[[773,3]]},"2860":{"position":[[734,3]]}}}],["b00a",{"_index":7831,"t":{"1845":{"position":[[2102,4]]}}}],["b05c",{"_index":7839,"t":{"1845":{"position":[[2171,4]]}}}],["b07ad6a84982471b9a344ef9947f0e0f",{"_index":383,"t":{"27":{"position":[[3089,32]]}}}],["b0a7",{"_index":9770,"t":{"3088":{"position":[[1169,4]]}}}],["b0fd",{"_index":4211,"t":{"859":{"position":[[3097,4],[3319,4],[3538,4],[3653,4],[5951,4]]},"1603":{"position":[[3097,4],[3319,4],[3538,4],[3653,4],[5951,4]]}}}],["b222",{"_index":9847,"t":{"3109":{"position":[[2100,4]]}}}],["b31a79db26c3956b473f026038e71e9aba7819b8",{"_index":3349,"t":{"635":{"position":[[775,40]]}}}],["b342f37804f14459bdf703573169bf79",{"_index":332,"t":{"27":{"position":[[1341,32]]}}}],["b34744f7",{"_index":7796,"t":{"1843":{"position":[[1055,8]]}}}],["b43cfafbcf1f4eb08865b2886c29e09b",{"_index":295,"t":{"27":{"position":[[157,32]]}}}],["b495",{"_index":4245,"t":{"859":{"position":[[5038,4],[5321,4],[5540,4],[5755,4],[6289,4]]},"1603":{"position":[[5038,4],[5321,4],[5540,4],[5755,4],[6289,4]]}}}],["b49c3c093062",{"_index":3622,"t":{"730":{"position":[[2146,12]]},"1491":{"position":[[2146,12]]}}}],["b5139b",{"_index":6700,"t":{"1368":{"position":[[578,6]]}}}],["b55a",{"_index":5327,"t":{"1114":{"position":[[4801,4],[5089,4],[5140,4],[5667,4],[5974,4],[6312,4],[6354,4]]}}}],["b57f",{"_index":5276,"t":{"1114":{"position":[[1321,4],[1595,4],[1646,4],[1694,4],[2223,4],[2471,4],[2757,4],[2799,4],[2968,4]]}}}],["b57f8d2489be",{"_index":7795,"t":{"1843":{"position":[[1008,12]]},"1845":{"position":[[2579,12]]}}}],["b621",{"_index":7812,"t":{"1845":{"position":[[1172,4],[2652,4]]}}}],["b682eb90fb834278afb1182018dd2133",{"_index":342,"t":{"27":{"position":[[1526,32]]}}}],["b6a3834a",{"_index":9805,"t":{"3109":{"position":[[658,8]]}}}],["b744",{"_index":6411,"t":{"1321":{"position":[[738,4]]}}}],["b76a",{"_index":4060,"t":{"842":{"position":[[3006,4]]},"1557":{"position":[[3006,4]]}}}],["b77c5aeb",{"_index":6754,"t":{"1375":{"position":[[664,8],[1475,8]]},"1377":{"position":[[665,8],[1669,8]]}}}],["b7a6",{"_index":7757,"t":{"1833":{"position":[[951,4]]}}}],["b7e9d7b848f4",{"_index":5152,"t":{"1102":{"position":[[263,12]]}}}],["b8210b4e",{"_index":7836,"t":{"1845":{"position":[[2152,8]]}}}],["b879",{"_index":6640,"t":{"1364":{"position":[[129,4]]}}}],["b910",{"_index":9792,"t":{"3107":{"position":[[1339,4]]}}}],["b93f",{"_index":9858,"t":{"3109":{"position":[[2223,4]]}}}],["b959d9f7b7cf",{"_index":3445,"t":{"644":{"position":[[505,12]]}}}],["b97d38bf128b4479981c4dbe2ef70cd5",{"_index":303,"t":{"27":{"position":[[420,32]]}}}],["b98e46fc7bcf",{"_index":6641,"t":{"1364":{"position":[[134,12]]}}}],["b9a8",{"_index":3951,"t":{"840":{"position":[[79,4],[177,4]]},"1555":{"position":[[79,4],[177,4]]}}}],["b9bf5ecbcb2f",{"_index":6652,"t":{"1364":{"position":[[288,12]]}}}],["b=$a$a",{"_index":6660,"t":{"1364":{"position":[[604,6]]}}}],["ba03cdcc255d",{"_index":4038,"t":{"842":{"position":[[2128,12]]},"1557":{"position":[[2128,12]]}}}],["ba1f",{"_index":3949,"t":{"840":{"position":[[69,4],[167,4]]},"1555":{"position":[[69,4],[167,4]]}}}],["ba8b",{"_index":6633,"t":{"1362":{"position":[[1997,4],[2364,4]]}}}],["back",{"_index":1033,"t":{"166":{"position":[[756,4]]},"168":{"position":[[996,4]]},"342":{"position":[[102,7]]},"421":{"position":[[1056,5]]},"428":{"position":[[548,4],[1511,6]]},"447":{"position":[[775,6]]},"465":{"position":[[31,4]]},"469":{"position":[[38,4],[117,4]]},"471":{"position":[[572,4]]},"472":{"position":[[619,6],[944,6]]},"474":{"position":[[65,4],[810,4],[982,4],[1189,4]]},"499":{"position":[[1202,4]]},"552":{"position":[[387,4]]},"594":{"position":[[63,7]]},"596":{"position":[[1769,6]]},"604":{"position":[[3820,7]]},"932":{"position":[[3139,4]]},"942":{"position":[[256,7],[306,4],[428,4],[615,6]]},"947":{"position":[[2357,4]]},"1406":{"position":[[122,4],[215,4]]},"1654":{"position":[[3139,4]]},"1664":{"position":[[256,7],[306,4],[428,4],[615,6]]},"1669":{"position":[[2357,4]]},"1731":{"position":[[282,6]]},"1773":{"position":[[691,6]]},"1791":{"position":[[432,4]]},"1878":{"position":[[159,6]]},"1880":{"position":[[227,6],[509,6]]},"1957":{"position":[[2606,4]]},"1982":{"position":[[174,7],[900,6]]},"1984":{"position":[[510,6]]},"1994":{"position":[[159,6]]},"1996":{"position":[[227,6],[509,6]]},"2031":{"position":[[313,6]]},"2229":{"position":[[208,4]]},"2379":{"position":[[3139,4]]},"2389":{"position":[[256,7],[306,4],[428,4],[615,6]]},"2394":{"position":[[2357,4]]},"2434":{"position":[[404,4]]},"2735":{"position":[[536,4]]},"2774":{"position":[[672,4]]},"2947":{"position":[[14,7],[3132,6]]},"3137":{"position":[[122,4]]},"3141":{"position":[[231,6],[305,6],[390,6]]},"3272":{"position":[[611,4],[688,4]]},"3274":{"position":[[36,6],[202,6],[276,4]]},"3284":{"position":[[24,6]]}}}],["backend",{"_index":1966,"t":{"302":{"position":[[826,7]]},"423":{"position":[[107,7]]},"451":{"position":[[6,7],[285,9],[391,7]]},"467":{"position":[[107,7]]},"505":{"position":[[91,7]]},"507":{"position":[[500,7]]},"509":{"position":[[78,7],[157,7]]},"530":{"position":[[765,8]]},"764":{"position":[[297,9]]},"774":{"position":[[332,8],[426,8],[471,8],[554,7]]},"776":{"position":[[140,7]]},"786":{"position":[[291,8],[966,7]]},"788":{"position":[[55,7]]},"895":{"position":[[1684,8]]},"1161":{"position":[[1500,9]]},"1184":{"position":[[1281,7]]},"1288":{"position":[[748,7]]},"1317":{"position":[[4536,7],[4689,7]]},"1523":{"position":[[291,8],[966,7]]},"1525":{"position":[[55,7]]},"1564":{"position":[[585,7]]},"1617":{"position":[[1684,8]]},"1872":{"position":[[523,7],[624,7]]},"1882":{"position":[[786,8]]},"1890":{"position":[[413,8]]},"1892":{"position":[[1241,8]]},"1978":{"position":[[270,7]]},"1988":{"position":[[523,7],[624,7]]},"1998":{"position":[[786,8]]},"2006":{"position":[[413,8]]},"2008":{"position":[[1241,8]]},"2098":{"position":[[1417,8]]},"2140":{"position":[[131,8]]},"2342":{"position":[[1684,8]]},"2947":{"position":[[705,7]]},"2960":{"position":[[150,9],[190,7],[463,7],[1416,7],[1600,8]]},"2962":{"position":[[345,7],[532,7]]},"2966":{"position":[[621,7],[682,9],[803,7],[1342,8],[1695,7],[2220,8],[2964,8],[4315,7],[4522,7]]},"2970":{"position":[[117,7],[169,7],[278,7]]},"3021":{"position":[[204,8]]},"3023":{"position":[[169,7]]},"3044":{"position":[[334,8]]},"3046":{"position":[[73,8]]},"3249":{"position":[[935,7]]},"3251":{"position":[[983,8],[1441,7],[1900,7],[2909,8],[5349,8],[5429,7]]},"3266":{"position":[[684,7]]},"3301":{"position":[[5059,7],[5365,8],[5500,7],[7460,7]]}}}],["backfil",{"_index":10194,"t":{"3372":{"position":[[318,12]]},"3376":{"position":[[74,12]]},"3378":{"position":[[642,12],[831,12]]},"3380":{"position":[[251,11]]}}}],["background",{"_index":1648,"t":{"247":{"position":[[343,11],[2868,12]]},"472":{"position":[[1527,10],[1894,10]]},"1315":{"position":[[258,10]]}}}],["backport",{"_index":2164,"t":{"339":{"position":[[268,9]]},"2405":{"position":[[878,10]]},"2502":{"position":[[711,8]]}}}],["backup",{"_index":2263,"t":{"379":{"position":[[810,6],[831,7],[907,6]]},"419":{"position":[[24,6],[141,6]]},"421":{"position":[[556,6],[1232,6]]},"423":{"position":[[185,6]]},"427":{"position":[[589,6],[710,6],[861,6],[937,6]]},"428":{"position":[[90,6],[237,6],[336,6],[583,6],[604,6],[708,6],[742,6],[1170,6],[1331,6],[1352,6],[1432,6],[1446,6],[1940,7]]},"460":{"position":[[315,6]]},"462":{"position":[[53,6],[148,6],[673,7],[691,6],[975,7],[1037,6],[1123,6],[1451,8],[1475,6]]},"465":{"position":[[501,6]]},"467":{"position":[[2680,6]]},"471":{"position":[[243,6],[766,6],[812,6],[1523,6],[1657,6],[1778,6]]},"472":{"position":[[24,6],[78,6],[1042,6],[1147,6],[1277,6],[1430,6],[1824,6],[2071,7]]},"474":{"position":[[32,6],[117,7],[853,6],[883,6],[904,6],[1034,6],[1211,6],[1232,6],[1292,6]]},"596":{"position":[[135,7],[1792,6],[2228,6],[2252,7]]},"609":{"position":[[1926,6],[2029,6],[4728,6],[4831,6]]},"635":{"position":[[816,6]]},"667":{"position":[[219,7]]},"821":{"position":[[2891,10],[4233,10],[5547,10]]},"977":{"position":[[1234,6],[1837,6],[1888,6],[1923,7],[1960,7]]},"1224":{"position":[[2714,6]]},"1258":{"position":[[433,8]]},"1298":{"position":[[30,7],[55,6],[101,6],[269,7],[381,8]]},"1300":{"position":[[62,6],[96,7]]},"1511":{"position":[[2891,10],[4233,10],[5547,10]]},"1870":{"position":[[69,7]]},"1876":{"position":[[269,6]]},"1878":{"position":[[25,6],[105,6],[271,6],[350,6],[643,6],[971,6],[1207,6],[1237,6]]},"1880":{"position":[[389,8],[869,6],[957,6]]},"1882":{"position":[[78,6],[95,7],[264,7],[278,7],[480,6],[566,7],[608,7],[685,7],[715,6],[779,6],[820,6],[911,6]]},"1884":{"position":[[0,7],[40,6],[116,6],[157,7],[227,7],[281,6]]},"1886":{"position":[[19,7],[110,7],[222,7],[310,6],[359,7],[429,7],[483,6]]},"1888":{"position":[[19,6],[110,6],[197,6],[258,7],[300,6],[359,6]]},"1890":{"position":[[146,6],[353,6],[460,6],[548,6]]},"1892":{"position":[[113,7],[665,6],[855,6],[1181,6],[1288,6],[1376,6]]},"1896":{"position":[[244,6]]},"1898":{"position":[[78,7]]},"1900":{"position":[[623,6]]},"1902":{"position":[[18,7],[113,6],[217,6]]},"1904":{"position":[[44,7]]},"1906":{"position":[[34,7]]},"1908":{"position":[[11,6],[89,7],[130,7],[193,6],[241,7],[289,6],[321,6],[427,6],[458,6],[619,6],[695,8],[721,6],[911,6],[975,6],[1033,8],[1112,6],[1180,6],[1378,7],[1520,6],[1535,8],[1568,6],[1704,6],[1925,6],[1978,6],[2310,6],[2544,6],[2727,7],[2929,6],[2962,6],[3054,7]]},"1986":{"position":[[69,7]]},"1992":{"position":[[269,6]]},"1994":{"position":[[25,6],[105,6],[271,6],[350,6],[643,6],[971,6],[1207,6],[1237,6]]},"1996":{"position":[[389,8],[869,6],[957,6]]},"1998":{"position":[[78,6],[95,7],[264,7],[278,7],[480,6],[566,7],[608,7],[685,7],[715,6],[779,6],[820,6],[911,6]]},"2000":{"position":[[0,7],[40,6],[116,6],[157,7],[227,7],[281,6]]},"2002":{"position":[[19,7],[110,7],[222,7],[310,6],[359,7],[429,7],[483,6]]},"2004":{"position":[[19,6],[110,6],[197,6],[258,7],[300,6],[359,6]]},"2006":{"position":[[146,6],[353,6],[460,6],[548,6]]},"2008":{"position":[[113,7],[665,6],[855,6],[1181,6],[1288,6],[1376,6]]},"2012":{"position":[[244,6]]},"2014":{"position":[[78,7]]},"2016":{"position":[[623,6]]},"2018":{"position":[[18,7],[113,6],[217,6]]},"2020":{"position":[[44,7]]},"2022":{"position":[[34,7]]},"2024":{"position":[[11,6],[89,7],[130,7],[193,6],[241,7],[289,6],[321,6],[427,6],[458,6],[619,6],[695,8],[721,6],[911,6],[975,6],[1033,8],[1112,6],[1180,6],[1378,7],[1520,6],[1535,8],[1568,6],[1704,6],[1925,6],[1978,6],[2310,6],[2544,6],[2727,7],[2929,6],[2962,6],[3054,7]]},"2405":{"position":[[1019,7]]},"2947":{"position":[[1421,6]]},"3160":{"position":[[1278,6]]},"3266":{"position":[[315,6]]},"3274":{"position":[[333,7],[433,6],[499,7],[590,7],[663,6]]},"3284":{"position":[[97,7],[336,7],[365,6],[531,7]]},"3301":{"position":[[6275,6]]}}}],["backup'",{"_index":7971,"t":{"1908":{"position":[[2060,8],[2655,8]]},"2024":{"position":[[2060,8],[2655,8]]}}}],["backup.keyr",{"_index":6155,"t":{"1286":{"position":[[2114,14]]}}}],["backup.velero.io/backup",{"_index":2488,"t":{"428":{"position":[[502,23]]},"474":{"position":[[1143,23]]}}}],["backup.xz",{"_index":3060,"t":{"596":{"position":[[1899,10]]}}}],["backup/ceph.client.cind",{"_index":6154,"t":{"1286":{"position":[[2088,25]]}}}],["backup/ceph.client.cinder.keyr",{"_index":6153,"t":{"1286":{"position":[[2006,33]]}}}],["backup/manag",{"_index":7315,"t":{"1731":{"position":[[463,15],[855,15]]}}}],["backup/restor",{"_index":2482,"t":{"428":{"position":[[153,14]]}}}],["backup=tru",{"_index":2659,"t":{"474":{"position":[[335,11],[498,11],[798,11]]}}}],["backup_gigabyt",{"_index":3898,"t":{"821":{"position":[[2867,20],[4209,20],[5522,20]]},"1511":{"position":[[2867,20],[4209,20],[5522,20]]}}}],["backup_id",{"_index":7973,"t":{"1908":{"position":[[2240,11],[2259,13],[2322,10]]},"2024":{"position":[[2240,11],[2259,13],[2322,10]]}}}],["backup_name_or_id",{"_index":7968,"t":{"1908":{"position":[[736,18],[1203,18],[2985,18]]},"2024":{"position":[[736,18],[1203,18],[2985,18]]}}}],["backup_s",{"_index":7976,"t":{"1908":{"position":[[2766,12]]},"2024":{"position":[[2766,12]]}}}],["backupstorageloc",{"_index":2479,"t":{"427":{"position":[[1089,21],[1203,22]]}}}],["backward",{"_index":2169,"t":{"339":{"position":[[459,8]]},"2332":{"position":[[244,9]]},"2536":{"position":[[126,8]]},"2695":{"position":[[99,9]]},"2740":{"position":[[99,9]]},"2830":{"position":[[99,9]]},"2939":{"position":[[520,9]]},"3472":{"position":[[12904,9]]}}}],["bad",{"_index":1167,"t":{"170":{"position":[[2308,3]]},"178":{"position":[[1999,3]]},"911":{"position":[[1063,3]]},"1633":{"position":[[1063,3]]},"2358":{"position":[[1063,3]]},"2947":{"position":[[4356,3]]}}}],["badg",{"_index":1467,"t":{"208":{"position":[[51,5],[69,6]]}}}],["balanc",{"_index":2900,"t":{"503":{"position":[[497,8],[506,7]]},"505":{"position":[[132,8]]},"509":{"position":[[30,8]]},"511":{"position":[[53,9]]},"646":{"position":[[1705,8]]},"650":{"position":[[2560,9]]},"652":{"position":[[261,9]]},"754":{"position":[[293,10]]},"772":{"position":[[310,9]]},"1226":{"position":[[532,8]]},"1430":{"position":[[580,9]]},"1566":{"position":[[5,9],[206,9]]},"1972":{"position":[[283,8]]},"2158":{"position":[[383,8]]},"2870":{"position":[[316,10]]},"3206":{"position":[[342,7]]},"3214":{"position":[[247,7]]},"3314":{"position":[[3232,10]]}}}],["balancer_memb",{"_index":3815,"t":{"815":{"position":[[395,15]]},"1505":{"position":[[395,15]]},"3472":{"position":[[13748,16]]}}}],["balancer_member':%(target.role.name)",{"_index":5556,"t":{"1150":{"position":[[6261,37]]},"3472":{"position":[[6104,38],[13900,37]]}}}],["balenaetch",{"_index":7006,"t":{"1569":{"position":[[514,12]]}}}],["ballpen",{"_index":1461,"t":{"208":{"position":[[0,8]]}}}],["banana",{"_index":1506,"t":{"219":{"position":[[83,7]]}}}],["bandwidth",{"_index":3648,"t":{"738":{"position":[[452,9]]},"995":{"position":[[147,9],[224,9],[420,9]]},"1351":{"position":[[2950,9],[3029,9]]},"1779":{"position":[[3974,9]]},"2709":{"position":[[534,9],[645,9]]},"2727":{"position":[[714,9]]},"2754":{"position":[[534,9],[645,9]]},"2766":{"position":[[914,9],[1108,9]]},"2844":{"position":[[462,9],[573,9]]},"2852":{"position":[[1060,9]]},"2951":{"position":[[177,9],[471,9]]},"3301":{"position":[[2133,9]]}}}],["bandwidth_poll_interv",{"_index":5840,"t":{"1165":{"position":[[2678,23],[2783,23],[2850,23],[2890,23],[3007,23],[3123,23],[3152,23]]}}}],["bar",{"_index":1412,"t":{"200":{"position":[[0,3],[126,4],[180,4]]},"251":{"position":[[296,3]]},"899":{"position":[[373,7]]},"1621":{"position":[[373,7]]},"1957":{"position":[[473,4],[550,5],[1129,4],[1396,6],[1441,5],[2460,6],[2652,6],[2682,5],[3647,4],[3916,6],[4235,4]]},"2346":{"position":[[373,7]]}}}],["bar/endpoint",{"_index":8018,"t":{"1957":{"position":[[3063,13]]}}}],["barbican",{"_index":5473,"t":{"1126":{"position":[[0,8],[21,8],[50,8]]},"1311":{"position":[[329,8]]},"1814":{"position":[[333,8]]},"1872":{"position":[[682,10],[783,8]]},"1876":{"position":[[223,8]]},"1878":{"position":[[896,9],[919,8]]},"1882":{"position":[[241,8],[316,8]]},"1894":{"position":[[31,8],[165,8],[290,8],[554,8]]},"1896":{"position":[[117,9],[208,8],[534,8],[838,8],[929,8]]},"1900":{"position":[[27,8],[70,8],[435,9]]},"1913":{"position":[[37,8]]},"1988":{"position":[[682,10],[783,8]]},"1992":{"position":[[223,8]]},"1994":{"position":[[896,9],[919,8]]},"1998":{"position":[[241,8],[316,8]]},"2010":{"position":[[31,8],[165,8],[290,8],[554,8]]},"2012":{"position":[[117,9],[208,8],[534,8],[838,8],[929,8]]},"2016":{"position":[[27,8],[70,8],[435,9]]},"2029":{"position":[[37,8]]},"2190":{"position":[[779,9]]}}}],["barbican_api_work",{"_index":5917,"t":{"1169":{"position":[[880,20]]}}}],["barbican_public_endpoint",{"_index":5733,"t":{"1161":{"position":[[365,25]]}}}],["barbican_tag",{"_index":5648,"t":{"1156":{"position":[[341,13]]}}}],["barbican_worker_tag",{"_index":5650,"t":{"1156":{"position":[[448,20]]}}}],["barbicancli",{"_index":135,"t":{"10":{"position":[[1200,14]]}}}],["bare",{"_index":4261,"t":{"865":{"position":[[91,4]]},"878":{"position":[[91,4]]},"1219":{"position":[[385,4],[427,4]]},"1224":{"position":[[498,4]]},"1226":{"position":[[486,4]]},"1560":{"position":[[210,4]]},"1587":{"position":[[122,4]]},"2100":{"position":[[1210,4]]},"2196":{"position":[[36,4],[70,4]]},"2206":{"position":[[249,4]]},"2226":{"position":[[11,4],[159,4]]},"2243":{"position":[[59,4]]},"2248":{"position":[[1174,4]]},"2700":{"position":[[428,4]]},"2721":{"position":[[89,4],[228,4]]},"2723":{"position":[[293,4],[844,4]]},"2725":{"position":[[1168,4]]},"2745":{"position":[[428,4]]},"2760":{"position":[[101,4],[240,4]]},"2762":{"position":[[306,4],[857,4]]},"2764":{"position":[[1743,4]]},"2835":{"position":[[369,4]]},"2846":{"position":[[89,4],[228,4]]},"2848":{"position":[[293,4]]},"3003":{"position":[[773,4]]},"3082":{"position":[[916,6]]},"3180":{"position":[[110,4],[190,4],[370,4]]},"3193":{"position":[[86,4],[166,4],[346,4]]}}}],["baremet",{"_index":4656,"t":{"956":{"position":[[44,9],[932,9],[1611,9],[1906,9],[2033,9]]},"1084":{"position":[[7,9]]},"2093":{"position":[[525,10]]},"2872":{"position":[[15,9]]}}}],["baremetal.sh",{"_index":7654,"t":{"1798":{"position":[[531,12]]},"1800":{"position":[[342,12]]}}}],["barrier",{"_index":635,"t":{"103":{"position":[[89,7]]},"174":{"position":[[1359,7]]},"198":{"position":[[154,7]]},"3014":{"position":[[1030,7]]},"3206":{"position":[[71,7]]},"3208":{"position":[[1305,7]]},"3214":{"position":[[198,7]]},"3224":{"position":[[1705,7]]}}}],["barrier=0",{"_index":2788,"t":{"487":{"position":[[2982,9]]},"615":{"position":[[1115,9]]}}}],["base",{"_index":557,"t":{"75":{"position":[[67,4]]},"168":{"position":[[1085,4]]},"178":{"position":[[1990,5]]},"249":{"position":[[158,5]]},"251":{"position":[[63,5]]},"253":{"position":[[437,5]]},"282":{"position":[[268,5]]},"294":{"position":[[168,5]]},"321":{"position":[[197,5],[1489,5],[1550,5],[1629,5]]},"325":{"position":[[341,4],[390,4],[1056,6],[1105,4],[1144,4],[2588,4],[6757,4],[6966,4]]},"339":{"position":[[353,5]]},"347":{"position":[[522,5]]},"349":{"position":[[404,5],[790,5]]},"366":{"position":[[1429,4]]},"372":{"position":[[123,5]]},"396":{"position":[[164,5]]},"421":{"position":[[1513,5]]},"436":{"position":[[497,5]]},"444":{"position":[[328,5]]},"472":{"position":[[317,5]]},"487":{"position":[[5621,5]]},"495":{"position":[[312,4],[509,4],[1199,4],[1396,4]]},"497":{"position":[[32,5]]},"499":{"position":[[1278,5]]},"596":{"position":[[596,5]]},"598":{"position":[[75,5]]},"609":{"position":[[4405,5],[4437,5]]},"619":{"position":[[674,4]]},"662":{"position":[[395,5],[412,5]]},"694":{"position":[[44,5]]},"708":{"position":[[26,5]]},"742":{"position":[[151,5]]},"880":{"position":[[116,5]]},"913":{"position":[[2722,5]]},"970":{"position":[[31,5]]},"977":{"position":[[222,5],[510,5],[905,5],[1006,5]]},"1055":{"position":[[1329,4]]},"1089":{"position":[[809,4]]},"1120":{"position":[[866,4]]},"1150":{"position":[[585,4]]},"1165":{"position":[[30,5]]},"1226":{"position":[[346,5],[437,5],[962,4]]},"1240":{"position":[[39,5]]},"1252":{"position":[[1148,5]]},"1286":{"position":[[1503,4]]},"1587":{"position":[[728,4]]},"1610":{"position":[[344,5]]},"1635":{"position":[[2722,5]]},"1812":{"position":[[90,5],[176,5],[293,5]]},"1855":{"position":[[489,5]]},"1857":{"position":[[165,5]]},"1892":{"position":[[633,5]]},"1902":{"position":[[232,5]]},"1908":{"position":[[228,5]]},"1917":{"position":[[489,5]]},"1919":{"position":[[165,5]]},"1951":{"position":[[855,5]]},"1953":{"position":[[106,5]]},"1972":{"position":[[711,5]]},"1978":{"position":[[129,4]]},"2008":{"position":[[633,5]]},"2018":{"position":[[232,5]]},"2024":{"position":[[228,5]]},"2079":{"position":[[36,5]]},"2116":{"position":[[664,5]]},"2152":{"position":[[664,5]]},"2229":{"position":[[1043,5]]},"2245":{"position":[[744,4]]},"2276":{"position":[[169,5]]},"2278":{"position":[[458,4],[577,5]]},"2281":{"position":[[1065,5]]},"2310":{"position":[[299,5]]},"2312":{"position":[[98,4]]},"2330":{"position":[[699,5]]},"2338":{"position":[[170,4]]},"2360":{"position":[[2722,5]]},"2403":{"position":[[37,5]]},"2459":{"position":[[37,5]]},"2463":{"position":[[67,5]]},"2546":{"position":[[94,5]]},"2602":{"position":[[853,5]]},"2942":{"position":[[354,6],[567,6]]},"2949":{"position":[[200,4]]},"2979":{"position":[[40,5]]},"3011":{"position":[[177,5],[896,5],[1997,5]]},"3099":{"position":[[206,5]]},"3124":{"position":[[594,4]]},"3128":{"position":[[474,4]]},"3156":{"position":[[129,5]]},"3160":{"position":[[810,5]]},"3167":{"position":[[856,4]]},"3182":{"position":[[966,5]]},"3186":{"position":[[85,4]]},"3201":{"position":[[126,5]]},"3218":{"position":[[1504,5]]},"3220":{"position":[[314,5],[500,5]]},"3222":{"position":[[82,5],[206,5],[677,5]]},"3224":{"position":[[924,5],[1758,5]]},"3236":{"position":[[1686,5]]},"3245":{"position":[[111,5],[245,5],[307,5]]},"3251":{"position":[[289,5],[1419,5],[6011,5]]},"3270":{"position":[[2221,5]]},"3276":{"position":[[1842,5]]},"3293":{"position":[[392,5]]},"3301":{"position":[[166,5],[2064,5],[5445,5],[6562,5],[6593,5]]},"3303":{"position":[[0,5]]},"3310":{"position":[[555,4]]},"3312":{"position":[[0,5]]},"3314":{"position":[[212,5],[1442,5]]},"3316":{"position":[[591,5],[773,5],[819,5],[1824,5],[1854,5]]},"3389":{"position":[[810,5],[942,5]]},"3395":{"position":[[44,5],[243,5],[592,5]]},"3397":{"position":[[0,4],[83,5],[127,5],[183,5]]},"3419":{"position":[[145,5]]},"3436":{"position":[[5,5],[27,5],[111,5],[133,5]]},"3442":{"position":[[5,5],[27,5],[195,5],[219,5]]},"3446":{"position":[[67,5],[254,5]]},"3455":{"position":[[95,5]]},"3472":{"position":[[435,4]]},"3482":{"position":[[2907,5]]},"3484":{"position":[[30,5]]},"3518":{"position":[[2704,5]]}}}],["base.yml",{"_index":5033,"t":{"1080":{"position":[[1229,8]]},"1676":{"position":[[499,8],[779,8]]},"1825":{"position":[[1392,8]]}}}],["base/harbor",{"_index":2430,"t":{"413":{"position":[[663,11]]},"415":{"position":[[39,11]]},"442":{"position":[[383,11]]}}}],["base64",{"_index":3424,"t":{"641":{"position":[[2029,6]]},"650":{"position":[[1986,6],[2270,6]]}}}],["base_",{"_index":10239,"t":{"3472":{"position":[[144,8],[12394,8],[12679,8]]}}}],["base_.bkp",{"_index":3350,"t":{"635":{"position":[[895,18]]}}}],["cluster_name>/clust",{"_index":3567,"t":{"667":{"position":[[304,24]]}}}],["cluster_name>/clusterctl.yaml",{"_index":3209,"t":{"609":{"position":[[150,32],[3022,30],[3162,30],[3283,30],[3397,30],[3694,30],[3834,30],[3955,30],[4069,30],[5783,30],[5897,30]]},"667":{"position":[[613,32]]}}}],["cluster_name}/clusterctl.yaml",{"_index":3130,"t":{"604":{"position":[[5000,34]]},"660":{"position":[[1497,33]]}}}],["cluster_topology=tru",{"_index":3116,"t":{"604":{"position":[[3032,21]]},"609":{"position":[[5493,21]]}}}],["clusteraddon",{"_index":3548,"t":{"660":{"position":[[3108,12],[3450,12]]}}}],["clusterapi",{"_index":567,"t":{"77":{"position":[[117,10]]},"1248":{"position":[[74,10]]},"1779":{"position":[[6275,10]]},"3184":{"position":[[2082,10]]}}}],["clusterapi_vers",{"_index":2676,"t":{"483":{"position":[[481,18]]}}}],["clusterclass",{"_index":3117,"t":{"604":{"position":[[3100,12]]},"609":{"position":[[4424,12],[5570,12]]},"658":{"position":[[22,12]]},"662":{"position":[[37,12],[203,12],[421,12],[958,14]]},"1980":{"position":[[111,15],[354,15],[417,12]]},"2461":{"position":[[770,12]]}}}],["clusterctl",{"_index":2679,"t":{"483":{"position":[[543,10]]},"513":{"position":[[1340,12]]},"583":{"position":[[277,11]]},"590":{"position":[[32,10],[1070,10],[1283,10]]},"598":{"position":[[1569,10]]},"602":{"position":[[155,10]]},"604":{"position":[[1809,10],[1917,10],[2010,10],[2143,10],[2171,10],[2324,10],[2944,10],[3179,10],[3401,10]]},"606":{"position":[[356,10]]},"609":{"position":[[1045,10],[2762,10],[2786,10],[5462,10],[5515,10]]},"660":{"position":[[1463,10]]},"3069":{"position":[[32,11]]}}}],["clusterctl.cluster.x",{"_index":2381,"t":{"404":{"position":[[907,20]]}}}],["clusterctl.yaml",{"_index":2670,"t":{"483":{"position":[[104,15]]},"485":{"position":[[89,15]]},"487":{"position":[[57,15],[3974,15]]},"501":{"position":[[1036,16]]},"513":{"position":[[2466,15]]},"604":{"position":[[4130,15],[4652,15],[4916,16],[5763,16],[6918,15],[7051,15],[8575,15],[8708,15]]},"627":{"position":[[521,15],[2522,15]]},"631":{"position":[[153,15],[963,15]]},"635":{"position":[[3636,15],[4082,15]]},"648":{"position":[[804,16]]},"667":{"position":[[557,15]]},"2253":{"position":[[150,15]]}}}],["clusterinfrastructur",{"_index":3010,"t":{"590":{"position":[[1396,23]]}}}],["clusterip",{"_index":2423,"t":{"413":{"position":[[382,9]]},"442":{"position":[[301,9]]},"641":{"position":[[1316,9],[1685,9]]},"646":{"position":[[345,9]]}}}],["clusternam",{"_index":3279,"t":{"627":{"position":[[452,11],[846,12],[1604,11],[2117,12],[4851,14],[4920,13],[5118,11],[5192,12]]},"631":{"position":[[803,11]]}}}],["clustername/$clusternam",{"_index":3282,"t":{"627":{"position":[[1107,25]]}}}],["clustername/$clustername.yaml",{"_index":3285,"t":{"627":{"position":[[2039,33]]}}}],["clustername/clust",{"_index":3281,"t":{"627":{"position":[[988,20]]}}}],["clustername/clusterctl.yaml",{"_index":3280,"t":{"627":{"position":[[919,31],[1054,28]]}}}],["clustername/deploy",{"_index":3291,"t":{"627":{"position":[[2365,23],[4189,23]]}}}],["clusternetwork",{"_index":3532,"t":{"660":{"position":[[1660,15]]}}}],["clusterrol",{"_index":8089,"t":{"2033":{"position":[[835,11],[1188,11]]}}}],["clustershel",{"_index":6459,"t":{"1335":{"position":[[11,12]]}}}],["clusterstack",{"_index":569,"t":{"77":{"position":[[158,13]]},"339":{"position":[[362,13]]},"389":{"position":[[40,12],[151,12],[307,12],[351,12],[388,12],[458,12]]},"391":{"position":[[688,12],[822,12],[863,12]]},"393":{"position":[[1522,13],[1679,12]]},"396":{"position":[[358,12],[405,12]]},"660":{"position":[[712,12],[1246,12],[1273,12]]}}}],["clusterstack.x",{"_index":3518,"t":{"660":{"position":[[675,14]]}}}],["clusterstack.yaml",{"_index":2315,"t":{"391":{"position":[[771,19]]},"393":{"position":[[1395,17]]}}}],["clusterstackreleas",{"_index":2306,"t":{"389":{"position":[[405,19]]}}}],["clusterstacks/capi",{"_index":8066,"t":{"1980":{"position":[[268,19]]}}}],["clustertopology=tru",{"_index":3560,"t":{"662":{"position":[[834,20]]}}}],["cm",{"_index":2511,"t":{"436":{"position":[[879,2]]},"3316":{"position":[[787,3],[833,3],[1200,4],[1224,3],[1257,4],[1281,3]]}}}],["cmctl",{"_index":3305,"t":{"627":{"position":[[5443,6]]}}}],["cmd",{"_index":2793,"t":{"487":{"position":[[3155,4]]}}}],["cmd_age=1",{"_index":7285,"t":{"1728":{"position":[[207,10]]}}}],["cmdline",{"_index":171,"t":{"10":{"position":[[1771,7]]}}}],["cncf",{"_index":2191,"t":{"353":{"position":[[281,4]]},"479":{"position":[[85,4]]},"487":{"position":[[5015,4]]},"513":{"position":[[2017,4]]},"561":{"position":[[173,5]]},"669":{"position":[[793,4]]},"2233":{"position":[[220,4]]},"2235":{"position":[[450,4]]},"2265":{"position":[[79,4]]},"2298":{"position":[[79,4]]},"2306":{"position":[[485,5]]},"2338":{"position":[[441,5]]},"2407":{"position":[[354,4]]},"2413":{"position":[[127,4]]},"2434":{"position":[[346,5]]},"2514":{"position":[[182,4]]},"3128":{"position":[[758,4]]},"3251":{"position":[[3059,4]]},"3295":{"position":[[126,5]]},"3299":{"position":[[1704,4],[1727,4],[3074,4],[3096,4]]},"3301":{"position":[[1704,4],[4305,4],[4494,4]]},"3431":{"position":[[265,4]]}}}],["cnd",{"_index":8610,"t":{"2520":{"position":[[487,4]]}}}],["cni",{"_index":2732,"t":{"487":{"position":[[407,3],[572,3]]},"513":{"position":[[1947,4]]},"604":{"position":[[7791,3],[7980,3],[8428,3],[8517,4],[9963,3]]},"609":{"position":[[1383,3]]},"611":{"position":[[6,3]]},"627":{"position":[[1347,4]]},"631":{"position":[[666,4]]},"637":{"position":[[203,3]]},"658":{"position":[[275,3],[289,3]]},"669":{"position":[[1102,3]]},"2315":{"position":[[1396,3]]}}}],["coc",{"_index":1633,"t":{"245":{"position":[[1594,3]]}}}],["cockpit",{"_index":8368,"t":{"2190":{"position":[[322,8]]},"2259":{"position":[[57,7]]},"2290":{"position":[[4,7]]}}}],["cockroachdb",{"_index":10013,"t":{"3251":{"position":[[5451,11],[5567,12]]}}}],["cocktail",{"_index":1496,"t":{"217":{"position":[[57,8]]}}}],["code",{"_index":20,"t":{"4":{"position":[[218,5]]},"122":{"position":[[189,4]]},"131":{"position":[[330,4],[425,4]]},"133":{"position":[[233,4]]},"141":{"position":[[122,4],[245,4]]},"166":{"position":[[761,4],[875,5],[936,5],[1257,5]]},"168":{"position":[[120,4],[182,4],[556,4],[626,4],[710,4]]},"170":{"position":[[772,4],[1071,4],[1565,4],[1674,4]]},"172":{"position":[[110,4]]},"174":{"position":[[176,4],[625,4],[1401,4]]},"176":{"position":[[192,4],[824,4],[904,4],[932,4]]},"178":{"position":[[927,4],[1110,5],[1354,4],[1814,5],[1952,4]]},"184":{"position":[[22,4]]},"240":{"position":[[20,4]]},"245":{"position":[[974,5],[1034,4],[2038,5],[2106,4]]},"247":{"position":[[3202,4],[3257,4],[3302,4]]},"253":{"position":[[149,4],[1467,5],[1552,4]]},"298":{"position":[[505,4]]},"313":{"position":[[344,4]]},"349":{"position":[[135,4]]},"353":{"position":[[101,5],[344,4]]},"374":{"position":[[560,4]]},"381":{"position":[[38,4]]},"391":{"position":[[532,5]]},"436":{"position":[[774,4],[804,4],[951,5]]},"513":{"position":[[272,4]]},"694":{"position":[[197,5]]},"738":{"position":[[527,4]]},"815":{"position":[[465,5]]},"895":{"position":[[987,5]]},"1226":{"position":[[1910,4]]},"1505":{"position":[[465,5]]},"1617":{"position":[[987,5]]},"1699":{"position":[[115,4]]},"1705":{"position":[[26,4],[73,4]]},"1719":{"position":[[5,4],[86,5]]},"1721":{"position":[[234,4],[3923,6]]},"1957":{"position":[[1911,5],[1940,4],[2214,5],[4351,4]]},"1963":{"position":[[233,4],[345,5]]},"2077":{"position":[[261,4],[298,5]]},"2096":{"position":[[1545,4]]},"2196":{"position":[[624,5]]},"2235":{"position":[[766,5]]},"2272":{"position":[[201,4]]},"2281":{"position":[[1235,4]]},"2283":{"position":[[331,4]]},"2324":{"position":[[317,4]]},"2332":{"position":[[4,4],[163,4]]},"2334":{"position":[[20,4]]},"2342":{"position":[[987,5]]},"2434":{"position":[[332,4]]},"2482":{"position":[[383,4]]},"2504":{"position":[[579,4]]},"2688":{"position":[[2435,4]]},"2697":{"position":[[1171,4]]},"2742":{"position":[[1070,4]]},"2827":{"position":[[108,5]]},"2935":{"position":[[441,4]]},"2994":{"position":[[461,4]]},"3011":{"position":[[327,4],[398,4],[1176,4]]},"3016":{"position":[[409,4]]},"3050":{"position":[[406,4]]},"3071":{"position":[[300,4],[787,4],[2032,5],[2715,5]]},"3082":{"position":[[100,5],[160,4]]},"3158":{"position":[[419,5]]},"3160":{"position":[[2814,5],[2867,5]]},"3299":{"position":[[1181,4],[1926,4],[2667,4],[3289,4],[3887,4],[4512,4]]},"3301":{"position":[[3971,4]]},"3459":{"position":[[303,5]]}}}],["code/community/development/design",{"_index":10081,"t":{"3301":{"position":[[433,33]]}}}],["code_block",{"_index":829,"t":{"131":{"position":[[266,13],[471,10],[512,12]]}}}],["codebas",{"_index":1073,"t":{"168":{"position":[[1031,8]]}}}],["codeblock",{"_index":823,"t":{"131":{"position":[[42,11],[118,11]]}}}],["codecentric/keycloakx",{"_index":8565,"t":{"2468":{"position":[[147,21]]}}}],["coexist",{"_index":4504,"t":{"917":{"position":[[892,11]]},"1639":{"position":[[892,11]]},"2231":{"position":[[182,7]]},"2364":{"position":[[892,11]]}}}],["coffe",{"_index":1536,"t":{"225":{"position":[[391,7]]},"229":{"position":[[293,6]]},"231":{"position":[[260,6],[300,7]]}}}],["cognit",{"_index":1343,"t":{"187":{"position":[[142,9]]}}}],["coher",{"_index":9055,"t":{"2665":{"position":[[361,9]]}}}],["cold",{"_index":9635,"t":{"2955":{"position":[[701,4]]}}}],["colis",{"_index":10159,"t":{"3325":{"position":[[3001,10]]}}}],["collabor",{"_index":256,"t":{"23":{"position":[[397,13]]},"58":{"position":[[275,15]]},"69":{"position":[[81,13]]},"235":{"position":[[94,13]]},"245":{"position":[[507,14]]},"366":{"position":[[375,13]]},"2665":{"position":[[15,13]]},"3299":{"position":[[2137,12]]}}}],["collaborativli",{"_index":1597,"t":{"238":{"position":[[140,15]]}}}],["collect",{"_index":648,"t":{"105":{"position":[[374,10]]},"143":{"position":[[0,11],[86,10],[473,12],[712,11],[910,12]]},"145":{"position":[[100,10]]},"168":{"position":[[668,10]]},"202":{"position":[[507,10]]},"214":{"position":[[22,10]]},"233":{"position":[[16,7]]},"242":{"position":[[87,11]]},"259":{"position":[[277,9]]},"513":{"position":[[2197,10]]},"627":{"position":[[4176,9]]},"899":{"position":[[302,7]]},"1008":{"position":[[55,10]]},"1207":{"position":[[55,10]]},"1221":{"position":[[55,10]]},"1256":{"position":[[2283,10]]},"1258":{"position":[[310,12]]},"1260":{"position":[[287,12]]},"1608":{"position":[[272,10],[329,10]]},"1621":{"position":[[302,7]]},"1676":{"position":[[138,10],[171,10],[205,10]]},"1690":{"position":[[1108,10],[1143,10],[1181,10],[1701,10]]},"1721":{"position":[[381,10],[536,10],[688,10],[842,10],[1008,10],[1176,10],[1328,10],[1483,10],[1645,10],[1798,10],[1951,10],[2105,10],[2260,10],[2415,10],[2569,10],[2722,10],[2879,10],[3039,10],[3184,10],[3336,10]]},"2077":{"position":[[277,8]]},"2096":{"position":[[990,10],[1398,9]]},"2118":{"position":[[410,7]]},"2206":{"position":[[126,11]]},"2214":{"position":[[124,10]]},"2281":{"position":[[266,10]]},"2306":{"position":[[83,9]]},"2330":{"position":[[139,9]]},"2346":{"position":[[302,7]]},"3063":{"position":[[359,10]]},"3071":{"position":[[250,7]]},"3160":{"position":[[2008,10]]},"3301":{"position":[[6632,10]]},"3372":{"position":[[178,10]]},"3374":{"position":[[511,9]]},"3436":{"position":[[244,10]]}}}],["collectd",{"_index":6245,"t":{"1311":{"position":[[490,8]]}}}],["collections/ansible.posix.git",{"_index":951,"t":{"143":{"position":[[1019,29]]}}}],["collectiv",{"_index":1583,"t":{"235":{"position":[[801,16]]}}}],["colletar",{"_index":10020,"t":{"3255":{"position":[[905,10]]}}}],["colon",{"_index":9593,"t":{"2931":{"position":[[303,6]]}}}],["color",{"_index":794,"t":{"127":{"position":[[32,6]]},"247":{"position":[[480,6]]},"909":{"position":[[1508,7]]},"932":{"position":[[3633,6],[3778,6],[3904,6]]},"1591":{"position":[[646,6]]},"1631":{"position":[[1508,7]]},"1654":{"position":[[3633,6],[3778,6],[3904,6]]},"2156":{"position":[[108,5]]},"2356":{"position":[[1508,7]]},"2379":{"position":[[3633,6],[3778,6],[3904,6]]}}}],["column",{"_index":8624,"t":{"2526":{"position":[[376,6]]},"2544":{"position":[[383,6]]},"2574":{"position":[[356,6]]},"2592":{"position":[[339,6]]},"2602":{"position":[[371,6]]},"3031":{"position":[[83,6]]},"3518":{"position":[[463,6]]}}}],["column'",{"_index":7630,"t":{"1791":{"position":[[2758,8]]}}}],["com1",{"_index":5825,"t":{"1165":{"position":[[1519,5]]}}}],["combin",{"_index":647,"t":{"105":{"position":[[330,8]]},"168":{"position":[[638,8]]},"176":{"position":[[953,11]]},"302":{"position":[[1349,12]]},"306":{"position":[[165,11]]},"342":{"position":[[26,8]]},"899":{"position":[[894,8]]},"977":{"position":[[2486,8]]},"1621":{"position":[[894,8]]},"1684":{"position":[[1229,8],[1548,8],[1869,8],[2200,8],[2522,8],[2844,8],[3165,8],[3481,8]]},"1756":{"position":[[61,11]]},"1853":{"position":[[596,8]]},"1855":{"position":[[908,11],[1084,11]]},"1863":{"position":[[268,9]]},"1915":{"position":[[596,8]]},"1917":{"position":[[908,11],[1084,11]]},"1925":{"position":[[268,9]]},"2346":{"position":[[894,8]]},"2872":{"position":[[891,8]]},"2949":{"position":[[369,12]]},"3069":{"position":[[509,11]]},"3080":{"position":[[370,11]]},"3082":{"position":[[1908,11]]},"3251":{"position":[[6173,8]]},"3270":{"position":[[413,11]]},"3278":{"position":[[20,7]]},"3343":{"position":[[549,11]]}}}],["come",{"_index":496,"t":{"69":{"position":[[20,4]]},"105":{"position":[[725,6]]},"170":{"position":[[1082,5]]},"178":{"position":[[2617,4]]},"204":{"position":[[338,4]]},"247":{"position":[[2808,5]]},"335":{"position":[[1057,4]]},"383":{"position":[[312,5]]},"417":{"position":[[1083,4]]},"462":{"position":[[1562,4]]},"465":{"position":[[424,4]]},"481":{"position":[[44,5]]},"604":{"position":[[10235,4]]},"669":{"position":[[274,4]]},"760":{"position":[[337,5]]},"1395":{"position":[[431,5]]},"1473":{"position":[[818,4]]},"1766":{"position":[[69,4]]},"1959":{"position":[[1083,5]]},"2158":{"position":[[100,5]]},"2403":{"position":[[305,5]]},"2491":{"position":[[18,4]]},"2516":{"position":[[17,4]]},"2700":{"position":[[647,4]]},"2745":{"position":[[647,4]]},"2783":{"position":[[29,5]]},"2795":{"position":[[1567,4]]},"2897":{"position":[[397,4]]},"2942":{"position":[[700,5]]},"3014":{"position":[[806,6]]},"3150":{"position":[[268,4]]},"3245":{"position":[[335,4]]},"3253":{"position":[[375,4]]},"3255":{"position":[[896,5]]},"3374":{"position":[[418,4]]},"3417":{"position":[[112,4]]}}}],["comma",{"_index":5408,"t":{"1124":{"position":[[300,5]]}}}],["command",{"_index":615,"t":{"91":{"position":[[128,7]]},"158":{"position":[[512,7]]},"253":{"position":[[1881,7]]},"374":{"position":[[1091,7]]},"391":{"position":[[307,9],[1271,8]]},"462":{"position":[[189,9],[399,8],[568,8]]},"467":{"position":[[1995,7],[2494,7]]},"471":{"position":[[212,7]]},"472":{"position":[[212,9]]},"474":{"position":[[742,7]]},"485":{"position":[[1525,9]]},"554":{"position":[[69,7]]},"576":{"position":[[59,8]]},"590":{"position":[[43,8],[297,8],[1026,7]]},"596":{"position":[[1954,7]]},"600":{"position":[[406,8],[861,8]]},"604":{"position":[[2135,7],[2935,8]]},"615":{"position":[[150,7],[272,8]]},"619":{"position":[[128,7],[150,9]]},"627":{"position":[[119,9],[868,7]]},"646":{"position":[[1829,8]]},"669":{"position":[[78,8]]},"813":{"position":[[14,7],[66,8]]},"819":{"position":[[5,7],[271,8],[1870,7],[2070,7],[3779,8],[5938,7]]},"821":{"position":[[13,7],[205,9],[235,7],[332,7],[1322,7],[1522,7]]},"823":{"position":[[113,7]]},"857":{"position":[[12,7],[64,8]]},"859":{"position":[[1388,7],[1588,7],[6843,7]]},"861":{"position":[[97,7]]},"903":{"position":[[1815,7],[3972,8]]},"905":{"position":[[1622,7]]},"909":{"position":[[1158,7]]},"913":{"position":[[2550,7]]},"915":{"position":[[1108,8]]},"947":{"position":[[1902,7]]},"949":{"position":[[267,8]]},"1017":{"position":[[127,7]]},"1082":{"position":[[9,7],[108,7]]},"1120":{"position":[[1994,8]]},"1167":{"position":[[4147,10],[4611,7],[4784,10]]},"1256":{"position":[[170,8]]},"1290":{"position":[[451,8]]},"1292":{"position":[[894,8]]},"1317":{"position":[[42,8],[279,8]]},"1319":{"position":[[333,8]]},"1323":{"position":[[6,7]]},"1331":{"position":[[10,7]]},"1333":{"position":[[128,9]]},"1337":{"position":[[151,7]]},"1360":{"position":[[1140,7]]},"1400":{"position":[[14,8]]},"1469":{"position":[[111,8]]},"1477":{"position":[[213,7]]},"1503":{"position":[[14,7],[66,8]]},"1509":{"position":[[5,7],[271,8],[1870,7],[2070,7],[3779,8],[5938,7]]},"1511":{"position":[[13,7],[205,9],[235,7],[332,7],[1322,7],[1522,7]]},"1513":{"position":[[113,7]]},"1578":{"position":[[257,7]]},"1582":{"position":[[26,8]]},"1587":{"position":[[1171,7]]},"1601":{"position":[[12,7],[64,8]]},"1603":{"position":[[1388,7],[1588,7],[6843,7]]},"1605":{"position":[[97,7]]},"1625":{"position":[[1815,7],[3972,8]]},"1627":{"position":[[1622,7]]},"1631":{"position":[[1158,7]]},"1635":{"position":[[2550,7]]},"1637":{"position":[[1108,8]]},"1669":{"position":[[1902,7]]},"1671":{"position":[[267,8]]},"1713":{"position":[[5,7]]},"1731":{"position":[[1077,7]]},"1764":{"position":[[4513,7]]},"1794":{"position":[[1127,8]]},"1837":{"position":[[80,7]]},"1855":{"position":[[1452,8]]},"1859":{"position":[[471,8],[695,8]]},"1861":{"position":[[316,7]]},"1865":{"position":[[588,7],[726,7]]},"1880":{"position":[[98,8],[625,8]]},"1884":{"position":[[89,9],[255,8]]},"1886":{"position":[[457,8]]},"1894":{"position":[[376,8]]},"1902":{"position":[[347,7],[410,7]]},"1904":{"position":[[347,7]]},"1908":{"position":[[59,8],[2188,7]]},"1917":{"position":[[1452,8]]},"1921":{"position":[[471,8],[695,8]]},"1923":{"position":[[316,7]]},"1927":{"position":[[588,7],[726,7]]},"1996":{"position":[[98,8],[625,8]]},"2000":{"position":[[89,9],[255,8]]},"2002":{"position":[[457,8]]},"2010":{"position":[[376,8]]},"2018":{"position":[[347,7],[410,7]]},"2020":{"position":[[347,7]]},"2024":{"position":[[59,8],[2188,7]]},"2045":{"position":[[174,8]]},"2051":{"position":[[617,9],[653,8]]},"2057":{"position":[[94,7]]},"2061":{"position":[[150,8],[182,8]]},"2063":{"position":[[159,8],[194,8]]},"2065":{"position":[[153,8],[186,8]]},"2096":{"position":[[2252,8]]},"2098":{"position":[[1473,8],[3563,8]]},"2118":{"position":[[453,8]]},"2315":{"position":[[76,7],[270,8]]},"2321":{"position":[[170,7]]},"2350":{"position":[[1815,7],[3972,8]]},"2352":{"position":[[1622,7]]},"2356":{"position":[[1158,7]]},"2360":{"position":[[2550,7]]},"2362":{"position":[[1108,8]]},"2394":{"position":[[1902,7]]},"2396":{"position":[[267,8]]},"2461":{"position":[[406,8]]},"2468":{"position":[[275,8]]},"2673":{"position":[[1346,7]]},"2783":{"position":[[48,7]]},"2813":{"position":[[1008,7]]},"2935":{"position":[[118,7]]},"2966":{"position":[[299,9]]},"2994":{"position":[[116,7]]},"3029":{"position":[[252,9]]},"3276":{"position":[[660,8],[1423,7],[2301,8]]}}}],["commandlin",{"_index":7118,"t":{"1591":{"position":[[528,11]]}}}],["comment",{"_index":1347,"t":{"187":{"position":[[280,7]]},"321":{"position":[[946,7]]},"325":{"position":[[7359,7]]},"493":{"position":[[294,7],[435,7],[576,7],[1090,7],[1231,7],[1372,7]]},"499":{"position":[[1223,8],[1509,10],[1608,9],[1908,8],[2780,7]]},"625":{"position":[[186,7]]},"660":{"position":[[2981,7]]},"934":{"position":[[1218,7],[1280,7],[1429,7]]},"1256":{"position":[[1154,7]]},"1656":{"position":[[1218,7],[1280,7],[1429,7]]},"1794":{"position":[[875,8]]},"2114":{"position":[[125,8]]},"2154":{"position":[[1317,9]]},"2381":{"position":[[1218,7],[1280,7],[1429,7]]},"3031":{"position":[[227,7]]},"3299":{"position":[[244,9]]},"3482":{"position":[[731,8],[1981,8],[2384,8],[2782,8]]}}}],["commerci",{"_index":7716,"t":{"1827":{"position":[[526,10]]},"2901":{"position":[[773,10]]},"3374":{"position":[[86,12]]},"3378":{"position":[[986,10]]},"3438":{"position":[[74,12]]}}}],["commit",{"_index":774,"t":{"120":{"position":[[119,10]]},"170":{"position":[[537,10]]},"178":{"position":[[1719,9]]},"184":{"position":[[332,7]]},"245":{"position":[[354,9]]},"253":{"position":[[1773,6],[1799,6],[1938,6],[1958,6],[1981,6],[2046,7]]},"530":{"position":[[1356,7]]},"635":{"position":[[684,6]]},"1061":{"position":[[131,9]]},"1065":{"position":[[407,6],[426,6],[480,9]]},"1080":{"position":[[1638,6],[1820,6]]},"1368":{"position":[[1851,10],[2530,10]]},"1686":{"position":[[24,6]]},"1764":{"position":[[3363,6]]},"1825":{"position":[[1806,6],[1992,6]]},"2324":{"position":[[744,6]]},"2677":{"position":[[511,10],[544,7]]},"2750":{"position":[[1270,7],[1434,6]]},"2895":{"position":[[2701,11],[2760,7]]},"3014":{"position":[[34,8]]},"3301":{"position":[[3979,10]]},"3316":{"position":[[1582,6],[1606,6],[1628,6],[1651,6]]}}}],["committe",{"_index":9880,"t":{"3124":{"position":[[554,10]]},"3167":{"position":[[816,10]]},"3477":{"position":[[274,9]]},"3482":{"position":[[3204,9]]},"3484":{"position":[[327,9]]}}}],["committee'",{"_index":9476,"t":{"2864":{"position":[[166,11]]}}}],["commment",{"_index":10254,"t":{"3482":{"position":[[2842,8]]}}}],["commod",{"_index":4283,"t":{"880":{"position":[[874,9]]}}}],["common",{"_index":524,"t":{"71":{"position":[[15,6]]},"253":{"position":[[1659,7]]},"327":{"position":[[408,6]]},"372":{"position":[[187,6]]},"746":{"position":[[140,6]]},"954":{"position":[[325,6],[349,7]]},"1077":{"position":[[546,6],[624,8],[756,8]]},"1226":{"position":[[2110,6]]},"1242":{"position":[[0,6],[164,6],[434,6],[453,6]]},"1250":{"position":[[0,6]]},"1294":{"position":[[0,6]]},"1311":{"position":[[511,6]]},"1317":{"position":[[684,6],[760,6],[1210,6],[1692,6],[2478,6],[2588,6],[2732,6],[2855,6],[2870,6],[2978,6],[3119,6],[3254,6],[3415,6],[3551,6],[3690,6],[3812,6],[3947,6],[4082,6],[4217,6],[4355,6],[4514,6],[4667,6],[4828,6],[4967,6],[5076,6],[5214,6],[5766,6],[6020,10]]},"1342":{"position":[[616,9]]},"1360":{"position":[[263,6]]},"1676":{"position":[[149,7]]},"1690":{"position":[[1154,8]]},"1768":{"position":[[223,6],[483,6],[513,6]]},"1779":{"position":[[5422,6]]},"1870":{"position":[[24,6]]},"1986":{"position":[[24,6]]},"2075":{"position":[[548,6]]},"2148":{"position":[[706,6]]},"3025":{"position":[[65,6],[243,6]]},"3247":{"position":[[199,7],[616,6]]},"3343":{"position":[[33,6],[53,6],[235,6],[844,6]]},"3405":{"position":[[54,6]]}}}],["common.yml",{"_index":6262,"t":{"1317":{"position":[[1734,10],[6730,10],[7466,10]]}}}],["commonli",{"_index":1256,"t":{"178":{"position":[[90,8]]},"1863":{"position":[[344,8],[434,8]]},"1925":{"position":[[344,8],[434,8]]},"2162":{"position":[[110,8]]},"2697":{"position":[[1139,8],[1571,8]]},"2742":{"position":[[1038,8],[1470,8]]},"3251":{"position":[[24,8],[820,8],[1781,8],[3485,8]]},"3363":{"position":[[5,8]]},"3365":{"position":[[25,8]]},"3408":{"position":[[290,8]]}}}],["commun",{"_index":4,"t":{"4":{"position":[[33,9],[370,9],[479,10],[588,9]]},"18":{"position":[[73,9]]},"23":{"position":[[510,9]]},"25":{"position":[[192,9]]},"27":{"position":[[31,9],[119,9],[137,9]]},"30":{"position":[[51,9]]},"32":{"position":[[31,9]]},"67":{"position":[[173,9]]},"69":{"position":[[47,9],[114,10],[172,9],[238,9],[288,9]]},"73":{"position":[[184,9]]},"103":{"position":[[215,9]]},"109":{"position":[[114,9]]},"118":{"position":[[47,10]]},"170":{"position":[[350,9]]},"174":{"position":[[401,9]]},"176":{"position":[[376,9]]},"235":{"position":[[242,10],[932,9],[1164,9]]},"238":{"position":[[12,10],[209,9]]},"240":{"position":[[325,10],[345,9]]},"242":{"position":[[241,10],[395,9]]},"245":{"position":[[693,10],[791,9],[907,9],[1220,10],[1272,10],[1482,10]]},"247":{"position":[[292,9],[913,9],[1000,9],[1114,9],[2060,10],[2334,9],[2434,9],[2536,10],[2829,10]]},"257":{"position":[[24,9],[133,10]]},"342":{"position":[[148,9]]},"505":{"position":[[995,11]]},"513":{"position":[[910,9]]},"619":{"position":[[564,9]]},"646":{"position":[[1213,13]]},"650":{"position":[[245,13]]},"722":{"position":[[42,9],[85,10]]},"760":{"position":[[24,11],[100,12]]},"770":{"position":[[264,10]]},"774":{"position":[[269,11]]},"796":{"position":[[1465,9]]},"800":{"position":[[548,10],[577,9]]},"949":{"position":[[1154,10]]},"1067":{"position":[[2022,13]]},"1533":{"position":[[1465,9]]},"1537":{"position":[[548,10],[577,9]]},"1671":{"position":[[1154,10]]},"1845":{"position":[[664,11]]},"1855":{"position":[[502,13],[578,13],[617,13]]},"1865":{"position":[[912,10]]},"1913":{"position":[[2131,10]]},"1917":{"position":[[502,13],[578,13],[617,13]]},"1957":{"position":[[859,11],[2591,11]]},"1970":{"position":[[418,11]]},"2079":{"position":[[132,9],[547,9]]},"2162":{"position":[[38,11]]},"2212":{"position":[[604,10]]},"2235":{"position":[[86,12]]},"2272":{"position":[[75,9]]},"2304":{"position":[[75,9]]},"2306":{"position":[[60,10],[262,9],[442,12]]},"2310":{"position":[[959,9],[1066,9]]},"2336":{"position":[[75,9]]},"2338":{"position":[[60,10],[142,9],[398,12]]},"2432":{"position":[[75,9]]},"2434":{"position":[[14,9]]},"2451":{"position":[[75,9]]},"2484":{"position":[[383,9]]},"2508":{"position":[[75,9]]},"2514":{"position":[[37,9]]},"2520":{"position":[[538,9]]},"2524":{"position":[[157,10]]},"2623":{"position":[[100,9]]},"2629":{"position":[[512,9]]},"2631":{"position":[[61,9],[1496,9]]},"2633":{"position":[[56,10]]},"2665":{"position":[[144,9],[473,9]]},"3005":{"position":[[40,11]]},"3011":{"position":[[196,9],[909,9],[957,9],[1119,9],[1609,10],[1785,9],[2170,9],[2212,9],[2631,9],[2758,9]]},"3014":{"position":[[0,9],[159,9],[884,9],[920,9]]},"3016":{"position":[[96,10],[206,10],[583,9]]},"3018":{"position":[[58,9]]},"3126":{"position":[[601,12]]},"3158":{"position":[[447,9]]},"3234":{"position":[[192,13]]},"3236":{"position":[[214,13]]},"3251":{"position":[[106,9],[371,9],[412,9],[3252,9],[3375,9]]},"3276":{"position":[[23,13]]},"3299":{"position":[[1235,9],[1311,14],[2161,11],[2721,9],[3941,9]]},"3301":{"position":[[1690,9],[2689,9],[4081,9],[4173,9],[4463,9]]},"3310":{"position":[[115,9]]},"3316":{"position":[[1884,11]]},"3410":{"position":[[225,9]]},"3518":{"position":[[332,9]]}}}],["community.general.timezon",{"_index":4807,"t":{"1033":{"position":[[128,26]]}}}],["compact",{"_index":8314,"t":{"2150":{"position":[[987,10],[1094,10]]},"3272":{"position":[[537,10],[1045,10],[1066,10],[1110,10]]},"3282":{"position":[[160,7],[245,10],[277,10]]}}}],["compact.concurr",{"_index":8316,"t":{"2150":{"position":[[1039,19]]}}}],["compact.concurrency=3",{"_index":8307,"t":{"2150":{"position":[[108,21]]}}}],["compaction/defragment",{"_index":10024,"t":{"3266":{"position":[[283,26]]}}}],["compactor",{"_index":8300,"t":{"2150":{"position":[[0,10],[187,10],[939,9]]},"3397":{"position":[[1097,9]]}}}],["compani",{"_index":1121,"t":{"170":{"position":[[897,9],[1008,7],[1253,7],[1498,9],[1732,9],[2150,9],[2312,9]]},"172":{"position":[[83,7]]},"178":{"position":[[1004,9],[2373,9]]},"191":{"position":[[106,9]]},"235":{"position":[[670,10]]},"696":{"position":[[156,9]]},"1234":{"position":[[1360,7]]},"2306":{"position":[[162,9]]},"2665":{"position":[[123,9]]},"3299":{"position":[[2066,9],[2511,10],[3428,9],[3705,9],[3723,9],[3771,9],[4648,9],[4937,10]]},"3301":{"position":[[1785,9],[2968,9],[4261,9]]}}}],["company/organ",{"_index":603,"t":{"87":{"position":[[134,21]]},"2673":{"position":[[771,21]]}}}],["compar",{"_index":2872,"t":{"499":{"position":[[1579,8]]},"744":{"position":[[331,8]]},"903":{"position":[[3900,7]]},"913":{"position":[[2428,8]]},"1564":{"position":[[382,8]]},"1625":{"position":[[3900,7]]},"1635":{"position":[[2428,8]]},"1978":{"position":[[308,10]]},"2188":{"position":[[222,8]]},"2350":{"position":[[3900,7]]},"2360":{"position":[[2428,8]]},"2711":{"position":[[946,8]]},"2856":{"position":[[924,8]]},"3061":{"position":[[887,8],[1233,8]]},"3218":{"position":[[737,9],[1306,9]]},"3220":{"position":[[479,8]]},"3222":{"position":[[349,8]]},"3251":{"position":[[3704,8],[4779,8]]},"3301":{"position":[[1572,8]]},"3463":{"position":[[742,10]]}}}],["comparison",{"_index":2521,"t":{"436":{"position":[[1523,10]]},"1055":{"position":[[1128,10]]},"1120":{"position":[[616,10]]},"2209":{"position":[[432,10]]},"2725":{"position":[[801,11]]},"2764":{"position":[[1022,11]]},"2850":{"position":[[694,11]]},"2939":{"position":[[147,10]]},"3301":{"position":[[3586,10],[4543,10]]},"3310":{"position":[[355,10]]}}}],["compat",{"_index":15,"t":{"4":{"position":[[150,10]]},"174":{"position":[[730,11],[1051,12]]},"182":{"position":[[204,10]]},"245":{"position":[[286,11]]},"276":{"position":[[151,10]]},"288":{"position":[[114,10]]},"339":{"position":[[468,11]]},"351":{"position":[[29,10]]},"368":{"position":[[225,10]]},"374":{"position":[[279,13]]},"423":{"position":[[64,10]]},"462":{"position":[[1423,10]]},"467":{"position":[[64,10],[187,10]]},"706":{"position":[[197,10]]},"768":{"position":[[269,10]]},"956":{"position":[[1175,13]]},"1108":{"position":[[218,8]]},"1982":{"position":[[1362,14]]},"1984":{"position":[[972,14]]},"2166":{"position":[[236,10]]},"2176":{"position":[[1258,14]]},"2321":{"position":[[123,10]]},"2330":{"position":[[269,11]]},"2332":{"position":[[254,10]]},"2497":{"position":[[143,10],[170,10],[448,10]]},"2514":{"position":[[255,14]]},"2520":{"position":[[91,10]]},"2522":{"position":[[206,10],[397,10]]},"2526":{"position":[[718,10]]},"2536":{"position":[[135,13]]},"2592":{"position":[[264,10]]},"2684":{"position":[[88,10],[142,10]]},"2686":{"position":[[63,10],[86,10]]},"2688":{"position":[[2217,14]]},"2692":{"position":[[91,10]]},"2695":{"position":[[109,12]]},"2740":{"position":[[109,12]]},"2795":{"position":[[398,10],[589,10],[1294,10],[1693,10],[1757,10]]},"2807":{"position":[[48,11],[572,10],[664,10]]},"2815":{"position":[[146,10],[246,10]]},"2830":{"position":[[109,12]]},"2939":{"position":[[530,13]]},"2942":{"position":[[305,10]]},"3011":{"position":[[1816,13]]},"3210":{"position":[[261,14],[299,10]]},"3397":{"position":[[807,10]]},"3472":{"position":[[12914,13]]},"3518":{"position":[[839,10]]}}}],["compet",{"_index":9632,"t":{"2951":{"position":[[163,9]]}}}],["competit",{"_index":1575,"t":{"235":{"position":[[530,11]]}}}],["competitor",{"_index":1138,"t":{"170":{"position":[[1373,11]]}}}],["compil",{"_index":3692,"t":{"764":{"position":[[166,7]]}}}],["complain",{"_index":6955,"t":{"1473":{"position":[[1339,8]]}}}],["complement",{"_index":3592,"t":{"702":{"position":[[13,10]]},"1980":{"position":[[72,13]]},"2413":{"position":[[23,11]]}}}],["complet",{"_index":759,"t":{"114":{"position":[[583,8]]},"168":{"position":[[1071,8]]},"229":{"position":[[390,13]]},"284":{"position":[[22,8]]},"372":{"position":[[728,8]]},"381":{"position":[[1273,10],[1335,11],[1413,9]]},"499":{"position":[[968,10]]},"523":{"position":[[43,11]]},"557":{"position":[[302,8]]},"583":{"position":[[457,10]]},"596":{"position":[[1623,9]]},"819":{"position":[[4020,8]]},"850":{"position":[[792,10],[811,10],[856,10],[872,10]]},"915":{"position":[[245,9],[836,9],[1197,9],[1265,9]]},"930":{"position":[[263,10]]},"940":{"position":[[176,10]]},"1067":{"position":[[2394,8]]},"1077":{"position":[[68,8]]},"1106":{"position":[[86,10]]},"1184":{"position":[[2243,10]]},"1224":{"position":[[582,10]]},"1234":{"position":[[1220,10],[3137,11]]},"1258":{"position":[[551,10]]},"1279":{"position":[[241,9],[468,9]]},"1286":{"position":[[817,10]]},"1317":{"position":[[351,8],[1187,9],[1660,9],[2455,9],[2565,9],[2701,9],[2824,9],[2951,9],[3092,9],[3231,9],[3388,9],[3524,9],[3663,9],[3789,9],[3924,9],[4059,9],[4194,9],[4328,9],[4471,9],[4624,9],[4785,9],[4935,9],[5053,9],[5182,9],[5821,9],[6652,9],[7265,9]]},"1428":{"position":[[311,11]]},"1484":{"position":[[792,10],[811,10],[856,10],[872,10]]},"1509":{"position":[[4020,8]]},"1637":{"position":[[245,9],[836,9],[1197,9],[1265,9]]},"1652":{"position":[[263,10]]},"1662":{"position":[[176,10]]},"1678":{"position":[[709,10]]},"1779":{"position":[[3053,10],[5371,8]]},"1781":{"position":[[19,9]]},"1841":{"position":[[18,10]]},"2041":{"position":[[78,9]]},"2176":{"position":[[251,8]]},"2190":{"position":[[827,8]]},"2235":{"position":[[167,8],[251,8],[672,8]]},"2248":{"position":[[1268,8]]},"2250":{"position":[[712,8]]},"2283":{"position":[[1211,8]]},"2310":{"position":[[265,10]]},"2362":{"position":[[245,9],[836,9],[1197,9],[1265,9]]},"2377":{"position":[[263,10]]},"2387":{"position":[[176,10]]},"2463":{"position":[[560,8]]},"2482":{"position":[[121,12]]},"2647":{"position":[[820,10]]},"2709":{"position":[[983,11]]},"2715":{"position":[[589,12]]},"2754":{"position":[[1124,11]]},"2844":{"position":[[911,11]]},"2903":{"position":[[108,12]]},"2942":{"position":[[435,8]]},"2947":{"position":[[1253,8],[3057,10],[5397,8]]},"3184":{"position":[[933,8],[1439,8]]},"3251":{"position":[[716,8]]},"3270":{"position":[[1440,10]]},"3276":{"position":[[2372,8]]},"3297":{"position":[[30,8]]},"3301":{"position":[[3710,10]]},"3310":{"position":[[422,8]]},"3365":{"position":[[263,8]]}}}],["complex",{"_index":1577,"t":{"235":{"position":[[572,7]]},"327":{"position":[[793,10]]},"880":{"position":[[1067,11]]},"883":{"position":[[269,12],[2354,12]]},"888":{"position":[[2526,12]]},"956":{"position":[[1976,7]]},"977":{"position":[[2196,7]]},"1851":{"position":[[112,7]]},"2214":{"position":[[257,10]]},"2623":{"position":[[360,7]]},"2663":{"position":[[37,7]]},"2665":{"position":[[233,11]]},"2669":{"position":[[15,10]]},"2677":{"position":[[317,7]]},"2966":{"position":[[3440,8]]},"3186":{"position":[[1513,10]]},"3218":{"position":[[966,12],[1136,10]]},"3220":{"position":[[341,10]]},"3222":{"position":[[300,10]]},"3224":{"position":[[988,10]]},"3227":{"position":[[606,10]]},"3308":{"position":[[48,7]]},"3395":{"position":[[940,10]]}}}],["compli",{"_index":741,"t":{"112":{"position":[[227,6]]},"133":{"position":[[238,8]]},"379":{"position":[[994,6]]},"2315":{"position":[[115,6]]},"2407":{"position":[[433,6]]},"3046":{"position":[[162,6]]},"3199":{"position":[[254,6]]}}}],["complianc",{"_index":288,"t":{"25":{"position":[[758,10]]},"27":{"position":[[3288,10],[3320,10]]},"30":{"position":[[191,10]]},"170":{"position":[[421,10]]},"276":{"position":[[60,10]]},"370":{"position":[[65,10],[83,10],[350,11],[439,10],[645,10]]},"379":{"position":[[971,11]]},"706":{"position":[[51,10]]},"2081":{"position":[[476,10]]},"2235":{"position":[[858,10]]},"2330":{"position":[[380,10],[447,11]]},"2426":{"position":[[676,10]]},"2514":{"position":[[501,10]]},"2520":{"position":[[139,10]]},"2548":{"position":[[412,10]]},"2688":{"position":[[268,10]]},"2713":{"position":[[698,11],[1349,10]]},"2715":{"position":[[364,10],[574,10]]},"2756":{"position":[[1066,10]]},"2783":{"position":[[553,10]]},"2790":{"position":[[173,11]]},"2797":{"position":[[334,10]]},"2813":{"position":[[778,10],[825,10]]},"2824":{"position":[[39,10]]},"2862":{"position":[[364,10]]},"2949":{"position":[[254,10]]},"2977":{"position":[[328,10]]},"3071":{"position":[[1038,11],[1626,10]]},"3479":{"position":[[179,10]]}}}],["compliance_check",{"_index":2025,"t":{"321":{"position":[[1606,17]]},"323":{"position":[[239,18]]}}}],["compliant",{"_index":631,"t":{"101":{"position":[[693,9]]},"361":{"position":[[11,10],[43,10]]},"366":{"position":[[786,9]]},"377":{"position":[[181,9]]},"379":{"position":[[1072,9]]},"381":{"position":[[173,9]]},"708":{"position":[[63,10]]},"1947":{"position":[[375,9]]},"1955":{"position":[[125,9]]},"2265":{"position":[[595,9]]},"2283":{"position":[[549,10]]},"2298":{"position":[[595,9]]},"2623":{"position":[[192,9]]},"2713":{"position":[[26,9]]},"2858":{"position":[[26,9]]},"2901":{"position":[[908,10]]},"2942":{"position":[[114,9],[200,9]]},"3126":{"position":[[804,9]]},"3154":{"position":[[624,9]]},"3169":{"position":[[273,9]]},"3247":{"position":[[437,9]]},"3251":{"position":[[3579,9]]}}}],["complic",{"_index":3074,"t":{"598":{"position":[[737,12]]},"3220":{"position":[[467,11]]}}}],["compon",{"_index":1829,"t":{"274":{"position":[[191,11]]},"333":{"position":[[147,9]]},"344":{"position":[[4,9]]},"355":{"position":[[33,10]]},"368":{"position":[[395,10]]},"427":{"position":[[22,10],[332,10]]},"471":{"position":[[22,10]]},"485":{"position":[[969,10],[1271,10]]},"530":{"position":[[61,10]]},"602":{"position":[[79,9]]},"604":{"position":[[2196,10],[3013,11],[3134,10],[10392,10]]},"641":{"position":[[776,10]]},"644":{"position":[[123,10]]},"658":{"position":[[114,9]]},"762":{"position":[[117,11]]},"768":{"position":[[62,9]]},"772":{"position":[[977,11]]},"876":{"position":[[33,10],[664,11]]},"888":{"position":[[1043,10]]},"990":{"position":[[166,10]]},"1080":{"position":[[612,11]]},"1188":{"position":[[97,10]]},"1234":{"position":[[2997,10]]},"1252":{"position":[[315,11]]},"1294":{"position":[[153,10],[229,10]]},"1674":{"position":[[213,10],[543,10]]},"1825":{"position":[[760,11]]},"1947":{"position":[[137,9]]},"1955":{"position":[[218,9]]},"1972":{"position":[[41,10]]},"2087":{"position":[[5,9]]},"2093":{"position":[[376,10]]},"2100":{"position":[[586,11]]},"2104":{"position":[[261,10]]},"2106":{"position":[[46,10],[133,10],[793,9]]},"2110":{"position":[[501,11],[978,10]]},"2112":{"position":[[5,9]]},"2118":{"position":[[2393,10]]},"2120":{"position":[[251,9]]},"2122":{"position":[[446,10]]},"2126":{"position":[[662,10]]},"2140":{"position":[[466,10]]},"2142":{"position":[[120,10]]},"2146":{"position":[[64,10]]},"2154":{"position":[[1464,10],[1619,10]]},"2162":{"position":[[763,10]]},"2176":{"position":[[660,12],[755,11],[866,12],[941,10]]},"2190":{"position":[[878,10]]},"2226":{"position":[[236,11]]},"2294":{"position":[[146,11]]},"2315":{"position":[[1278,11]]},"2326":{"position":[[104,11],[291,10]]},"2334":{"position":[[122,9]]},"2422":{"position":[[104,11],[253,9]]},"2459":{"position":[[85,11]]},"2461":{"position":[[175,10],[965,9]]},"2463":{"position":[[146,11]]},"2470":{"position":[[12,9]]},"2486":{"position":[[181,10],[244,10]]},"2504":{"position":[[148,10]]},"2651":{"position":[[479,11]]},"2663":{"position":[[78,10],[195,11]]},"2667":{"position":[[60,10],[75,10]]},"2671":{"position":[[704,10],[721,9],[747,9],[962,10],[1018,9]]},"2673":{"position":[[252,9],[933,10],[1142,10],[1538,10]]},"2675":{"position":[[705,10],[720,10],[1269,10]]},"3059":{"position":[[1137,11]]},"3124":{"position":[[628,9]]},"3160":{"position":[[1967,10]]},"3167":{"position":[[890,9]]},"3178":{"position":[[372,10]]},"3184":{"position":[[295,11]]},"3186":{"position":[[464,11],[490,9]]},"3191":{"position":[[366,10],[552,9]]},"3195":{"position":[[614,9]]},"3236":{"position":[[303,10],[1319,11]]},"3245":{"position":[[1499,9]]},"3249":{"position":[[582,9]]},"3286":{"position":[[89,11]]},"3314":{"position":[[263,10],[654,10],[732,9],[791,9],[861,9],[934,9],[1668,10],[1935,9],[2049,9],[2442,9]]},"3316":{"position":[[249,10],[1358,10]]},"3343":{"position":[[1036,9],[1090,10]]},"3353":{"position":[[35,11],[258,11]]},"3355":{"position":[[57,10],[70,9],[154,11],[244,10],[330,9],[443,10],[549,10],[599,10]]},"3359":{"position":[[0,10],[113,10],[124,10]]},"3391":{"position":[[240,10]]},"3397":{"position":[[276,9],[414,11]]},"3419":{"position":[[297,9]]},"3423":{"position":[[102,9]]},"3465":{"position":[[425,11]]},"3518":{"position":[[85,10]]}}}],["component'",{"_index":9070,"t":{"2673":{"position":[[1729,11]]}}}],["component(",{"_index":8359,"t":{"2176":{"position":[[823,12]]}}}],["component/compon",{"_index":9067,"t":{"2673":{"position":[[455,19]]}}}],["component=registri",{"_index":2632,"t":{"472":{"position":[[2114,18]]}}}],["component>_s",{"_index":3452,"t":{"644":{"position":[[709,18]]}}}],["components/servic",{"_index":2564,"t":{"458":{"position":[[55,19]]}}}],["compos",{"_index":2450,"t":{"417":{"position":[[881,8]]},"1344":{"position":[[318,7],[338,7]]},"1731":{"position":[[579,7],[950,7]]},"1738":{"position":[[397,8]]},"1743":{"position":[[116,7],[2179,7]]},"2259":{"position":[[541,7],[593,7],[627,7],[674,7]]},"2292":{"position":[[659,7],[711,7],[745,7],[792,7]]},"2321":{"position":[[244,7],[321,7],[399,7],[517,8]]},"3178":{"position":[[122,8]]},"3191":{"position":[[115,8]]},"3301":{"position":[[6961,8],[7000,8],[7027,8]]},"3316":{"position":[[94,8]]}}}],["compose@manager.servic",{"_index":7310,"t":{"1731":{"position":[[227,23],[682,23]]}}}],["composit",{"_index":8058,"t":{"1978":{"position":[[48,14],[67,10]]},"1982":{"position":[[868,10],[923,13],[1151,10]]},"1984":{"position":[[478,10],[533,13],[761,10]]}}}],["comprehend",{"_index":9060,"t":{"2671":{"position":[[136,10]]},"2673":{"position":[[136,10]]}}}],["comprehens",{"_index":1832,"t":{"276":{"position":[[228,14]]},"363":{"position":[[416,13]]},"368":{"position":[[466,18]]},"499":{"position":[[700,13]]},"977":{"position":[[434,13],[2542,13]]},"2081":{"position":[[92,13],[450,13]]},"2083":{"position":[[289,13]]},"2085":{"position":[[398,13]]},"2281":{"position":[[62,13]]},"2526":{"position":[[224,17]]},"2663":{"position":[[237,14]]},"2675":{"position":[[320,13]]},"2677":{"position":[[202,15]]},"2700":{"position":[[501,13]]},"2745":{"position":[[501,13]]},"3214":{"position":[[6,13]]}}}],["compress",{"_index":3058,"t":{"596":{"position":[[1817,10]]},"913":{"position":[[146,8]]},"922":{"position":[[701,11]]},"942":{"position":[[113,10]]},"1635":{"position":[[146,8]]},"1644":{"position":[[701,11]]},"1664":{"position":[[113,10]]},"2148":{"position":[[612,8]]},"2360":{"position":[[146,8]]},"2369":{"position":[[701,11]]},"2389":{"position":[[113,10]]}}}],["compris",{"_index":3594,"t":{"712":{"position":[[15,9]]},"2233":{"position":[[60,9]]},"2310":{"position":[[88,9]]},"2400":{"position":[[118,9]]},"2663":{"position":[[56,9]]},"3218":{"position":[[1015,8]]}}}],["compromis",{"_index":7908,"t":{"1857":{"position":[[796,10]]},"1919":{"position":[[796,10]]},"1982":{"position":[[1650,10]]},"1984":{"position":[[1260,10]]},"3184":{"position":[[900,11]]}}}],["comput",{"_index":2171,"t":{"342":{"position":[[53,9]]},"366":{"position":[[854,10]]},"710":{"position":[[67,9]]},"726":{"position":[[136,7]]},"740":{"position":[[55,7],[186,7]]},"742":{"position":[[49,7],[481,7],[798,7],[834,7]]},"744":{"position":[[392,7]]},"748":{"position":[[85,7]]},"750":{"position":[[2,7],[43,7],[84,7],[121,7],[335,7]]},"756":{"position":[[171,7]]},"760":{"position":[[92,7]]},"770":{"position":[[32,8],[185,7]]},"813":{"position":[[558,7]]},"819":{"position":[[1125,7],[3365,7],[3415,7]]},"821":{"position":[[2464,11],[3140,7],[3771,11],[4478,7],[5112,11],[5795,7]]},"833":{"position":[[32,7],[55,7]]},"835":{"position":[[28,7],[51,7]]},"857":{"position":[[112,7]]},"859":{"position":[[388,7],[970,7],[996,7]]},"868":{"position":[[0,7]]},"870":{"position":[[0,7]]},"874":{"position":[[14,7]]},"901":{"position":[[507,7]]},"947":{"position":[[403,7]]},"956":{"position":[[800,7]]},"984":{"position":[[0,7]]},"995":{"position":[[278,7],[321,7],[391,7],[449,7],[600,7],[649,7],[693,7],[714,7]]},"1031":{"position":[[637,7]]},"1067":{"position":[[3488,7],[3601,9]]},"1165":{"position":[[1506,7]]},"1178":{"position":[[44,7],[123,7]]},"1184":{"position":[[52,7],[309,7],[685,7],[797,7],[2316,7],[2425,7]]},"1226":{"position":[[77,7],[876,7],[901,7]]},"1358":{"position":[[42,7],[152,7],[194,7],[268,7],[305,7],[348,7],[407,7],[421,7],[464,7],[512,7]]},"1360":{"position":[[515,7],[691,7],[880,7],[966,7]]},"1362":{"position":[[43,7],[197,7],[288,7],[398,7],[448,7],[472,7],[648,7],[693,7],[1086,7],[1312,7],[1415,7],[2600,7],[2684,7]]},"1375":{"position":[[27,7],[103,7],[138,7],[708,7],[1038,7],[1087,7],[1122,7],[1519,7]]},"1377":{"position":[[32,7],[57,7],[104,7],[139,7],[709,7],[1038,7],[1063,7],[1108,7],[1143,7],[1713,7]]},"1386":{"position":[[338,7]]},"1487":{"position":[[136,7]]},"1503":{"position":[[558,7]]},"1509":{"position":[[1125,7],[3365,7],[3415,7]]},"1511":{"position":[[2464,11],[3140,7],[3771,11],[4478,7],[5112,11],[5795,7]]},"1548":{"position":[[32,7],[55,7]]},"1550":{"position":[[28,7],[51,7]]},"1601":{"position":[[112,7]]},"1603":{"position":[[388,7],[970,7],[996,7]]},"1623":{"position":[[507,7]]},"1669":{"position":[[403,7]]},"1845":{"position":[[2870,7]]},"1880":{"position":[[35,7],[568,7]]},"1911":{"position":[[35,7]]},"1974":{"position":[[199,7]]},"1996":{"position":[[35,7],[568,7]]},"2027":{"position":[[35,7]]},"2265":{"position":[[275,8]]},"2298":{"position":[[275,8]]},"2348":{"position":[[507,7]]},"2394":{"position":[[403,7]]},"2493":{"position":[[105,9]]},"2540":{"position":[[286,7]]},"2671":{"position":[[401,7]]},"2711":{"position":[[903,7]]},"2727":{"position":[[73,7],[169,7],[264,7],[636,7]]},"2750":{"position":[[1587,7]]},"2766":{"position":[[476,7],[836,7]]},"2852":{"position":[[452,7],[548,7],[641,7],[983,6]]},"2856":{"position":[[881,7]]},"2883":{"position":[[0,7],[191,7]]},"2933":{"position":[[306,7]]},"2960":{"position":[[633,7]]},"2966":{"position":[[1208,7]]},"3152":{"position":[[65,9]]},"3180":{"position":[[393,13]]},"3193":{"position":[[369,13]]},"3197":{"position":[[749,11]]},"3295":{"position":[[65,9],[98,9],[207,9]]},"3372":{"position":[[621,7]]},"3389":{"position":[[85,7]]},"3408":{"position":[[325,9]]},"3429":{"position":[[325,7]]},"3518":{"position":[[107,9]]}}}],["compute.conf",{"_index":5961,"t":{"1180":{"position":[[141,12]]},"1182":{"position":[[136,12]]}}}],["compute.inst",{"_index":8665,"t":{"2566":{"position":[[18,20]]}}}],["compute.instance.create.end",{"_index":8701,"t":{"2566":{"position":[[1077,27]]}}}],["compute.instance.exist",{"_index":8706,"t":{"2566":{"position":[[1305,23]]}}}],["compute.instance.upd",{"_index":8703,"t":{"2566":{"position":[[1201,23]]}}}],["compute:20.0.1.20230919",{"_index":6590,"t":{"1360":{"position":[[1740,23]]}}}],["compute:27.1.1.20230919",{"_index":6576,"t":{"1360":{"position":[[1207,23]]}}}],["compute_id",{"_index":6807,"t":{"1386":{"position":[[269,10]]}}}],["compute_zon",{"_index":4174,"t":{"859":{"position":[[401,13],[983,12]]},"1603":{"position":[[401,13],[983,12]]}}}],["con",{"_index":4314,"t":{"899":{"position":[[19,4]]},"1621":{"position":[[19,4]]},"1947":{"position":[[472,5]]},"2346":{"position":[[19,4]]},"3059":{"position":[[861,5]]},"3061":{"position":[[1010,5]]},"3063":{"position":[[1061,5]]},"3212":{"position":[[149,4]]},"3214":{"position":[[133,5]]},"3216":{"position":[[206,5]]},"3220":{"position":[[257,5]]}}}],["concept",{"_index":574,"t":{"79":{"position":[[169,8]]},"313":{"position":[[248,8]]},"363":{"position":[[458,8],[524,8]]},"876":{"position":[[4,7]]},"895":{"position":[[2023,8]]},"1617":{"position":[[2023,8]]},"1978":{"position":[[547,8]]},"1980":{"position":[[238,8]]},"2176":{"position":[[404,8]]},"2283":{"position":[[106,7],[318,8]]},"2342":{"position":[[2023,8]]},"2625":{"position":[[248,7]]},"2868":{"position":[[13,7]]},"3059":{"position":[[1371,8]]},"3061":{"position":[[1378,8]]},"3078":{"position":[[27,8]]},"3084":{"position":[[565,7]]},"3135":{"position":[[205,7]]},"3184":{"position":[[2126,7]]},"3197":{"position":[[624,7]]},"3251":{"position":[[1036,7],[1637,7],[4707,7]]},"3270":{"position":[[2296,7]]}}}],["concepts/api's/autom",{"_index":8362,"t":{"2176":{"position":[[1214,25]]}}}],["conceptu",{"_index":10145,"t":{"3325":{"position":[[688,10]]},"3455":{"position":[[424,10]]}}}],["concern",{"_index":7921,"t":{"1874":{"position":[[112,8]]},"1990":{"position":[[112,8]]},"2592":{"position":[[28,9]]},"3284":{"position":[[453,8]]}}}],["concis",{"_index":2250,"t":{"379":{"position":[[34,7]]},"2673":{"position":[[1085,7]]}}}],["conclus",{"_index":9645,"t":{"2966":{"position":[[482,11],[1038,11],[1933,11],[2551,11],[3152,11],[4116,11]]},"3071":{"position":[[649,10]]},"3103":{"position":[[1536,11]]},"3224":{"position":[[1459,11]]},"3268":{"position":[[22,10]]},"3308":{"position":[[607,10]]}}}],["concret",{"_index":1405,"t":{"195":{"position":[[110,8]]},"704":{"position":[[30,8]]}}}],["concurr",{"_index":2514,"t":{"436":{"position":[[1013,10]]},"458":{"position":[[121,12]]},"609":{"position":[[6109,12],[6233,10]]},"3206":{"position":[[910,10]]},"3208":{"position":[[1600,10],[1666,10]]},"3210":{"position":[[657,12],[721,12]]},"3214":{"position":[[500,10]]}}}],["condit",{"_index":907,"t":{"141":{"position":[[28,9],[191,9]]},"240":{"position":[[90,9]]},"590":{"position":[[1918,9]]},"596":{"position":[[768,10]]},"1165":{"position":[[2412,12],[2956,12]]},"2635":{"position":[[164,10]]},"2811":{"position":[[313,9]]},"2813":{"position":[[207,9],[262,9]]},"2815":{"position":[[548,10],[841,10],[991,10]]},"2881":{"position":[[87,9]]},"3050":{"position":[[470,10]]},"3276":{"position":[[2647,9]]},"3310":{"position":[[877,10]]}}}],["conduc",{"_index":7329,"t":{"1731":{"position":[[1836,8]]}}}],["conduct",{"_index":1641,"t":{"245":{"position":[[2047,7]]},"247":{"position":[[1149,7],[3210,7],[3265,7],[3310,8]]},"379":{"position":[[935,9]]},"2272":{"position":[[209,7]]},"3393":{"position":[[13,9]]},"3400":{"position":[[13,9]]}}}],["conductor",{"_index":3663,"t":{"744":{"position":[[528,9],[553,9],[587,11]]},"1731":{"position":[[1783,9],[1845,9]]}}}],["conect",{"_index":8033,"t":{"1959":{"position":[[564,8]]}}}],["conf",{"_index":3836,"t":{"819":{"position":[[1565,8]]},"821":{"position":[[1017,8]]},"859":{"position":[[1081,8],[6540,6]]},"1509":{"position":[[1565,8]]},"1511":{"position":[[1017,8]]},"1603":{"position":[[1081,8],[6540,6]]}}}],["confer",{"_index":1764,"t":{"251":{"position":[[522,10]]},"3299":{"position":[[2303,12],[3546,12]]}}}],["conferenc",{"_index":1729,"t":{"249":{"position":[[51,13]]}}}],["confid",{"_index":1571,"t":{"235":{"position":[[399,11]]},"3442":{"position":[[131,9]]}}}],["confidenti",{"_index":8584,"t":{"2493":{"position":[[92,12]]}}}],["config",{"_index":620,"t":{"95":{"position":[[21,6]]},"325":{"position":[[3397,6]]},"427":{"position":[[726,6]]},"471":{"position":[[828,6],[946,6],[1794,6]]},"487":{"position":[[3879,6],[5630,7]]},"489":{"position":[[355,6]]},"497":{"position":[[172,6],[357,6],[576,6],[724,6],[915,6]]},"602":{"position":[[221,6]]},"604":{"position":[[6294,6],[6396,6]]},"606":{"position":[[206,7],[349,6]]},"627":{"position":[[1095,6],[2263,6]]},"629":{"position":[[132,6]]},"633":{"position":[[829,6],[981,6],[1184,6],[1866,6],[2231,10],[2921,6]]},"635":{"position":[[827,6],[964,7],[1020,6]]},"650":{"position":[[1501,6],[1701,6],[2258,6]]},"652":{"position":[[350,6]]},"660":{"position":[[524,6],[1202,6],[1490,6],[2435,6]]},"728":{"position":[[306,6]]},"819":{"position":[[425,6],[444,6],[1515,6],[1540,6],[1754,6],[1886,6],[1913,6],[1942,6]]},"821":{"position":[[510,6],[529,6],[967,6],[992,6],[1206,6],[1338,6],[1365,6],[1394,6]]},"823":{"position":[[4,6],[174,6]]},"859":{"position":[[418,6],[437,6],[1031,6],[1056,6],[1271,6],[1404,6],[1431,6],[1460,6],[6454,6],[6515,6],[6727,6],[6878,6]]},"861":{"position":[[4,6],[158,6]]},"926":{"position":[[440,6]]},"932":{"position":[[6,7],[406,6]]},"934":{"position":[[358,6],[894,6],[1100,6]]},"942":{"position":[[465,6]]},"1035":{"position":[[70,6]]},"1055":{"position":[[3799,6]]},"1112":{"position":[[206,6]]},"1165":{"position":[[380,6],[2343,6],[2432,6]]},"1167":{"position":[[169,6],[257,6],[314,6],[2667,6]]},"1305":{"position":[[321,6]]},"1317":{"position":[[3272,6],[3588,6],[3848,6],[3983,6],[4118,6],[4252,6],[5094,6]]},"1460":{"position":[[361,6]]},"1489":{"position":[[306,6]]},"1509":{"position":[[425,6],[444,6],[1515,6],[1540,6],[1754,6],[1886,6],[1913,6],[1942,6]]},"1511":{"position":[[510,6],[529,6],[967,6],[992,6],[1206,6],[1338,6],[1365,6],[1394,6]]},"1513":{"position":[[4,6],[174,6]]},"1574":{"position":[[178,6],[340,6]]},"1603":{"position":[[418,6],[437,6],[1031,6],[1056,6],[1271,6],[1404,6],[1431,6],[1460,6],[6454,6],[6515,6],[6727,6],[6878,6]]},"1605":{"position":[[4,6],[158,6]]},"1648":{"position":[[440,6]]},"1654":{"position":[[6,7],[406,6]]},"1656":{"position":[[358,6],[894,6],[1100,6]]},"1664":{"position":[[465,6]]},"1749":{"position":[[970,6]]},"1754":{"position":[[4,6],[145,6]]},"1758":{"position":[[499,6],[677,6],[796,6]]},"1785":{"position":[[700,6],[823,6]]},"1841":{"position":[[381,6]]},"1939":{"position":[[221,6]]},"2033":{"position":[[154,6]]},"2104":{"position":[[21,6],[128,6]]},"2126":{"position":[[408,6],[529,6]]},"2140":{"position":[[337,6]]},"2148":{"position":[[686,6]]},"2373":{"position":[[440,6]]},"2379":{"position":[[6,7],[406,6]]},"2381":{"position":[[358,6],[894,6],[1100,6]]},"2389":{"position":[[465,6]]},"2560":{"position":[[210,6]]},"3175":{"position":[[223,6]]},"3316":{"position":[[698,6],[793,6],[851,6]]},"3397":{"position":[[2359,6]]}}}],["config.json",{"_index":5904,"t":{"1167":{"position":[[3864,11],[4564,11]]},"1317":{"position":[[4377,11]]}}}],["config.yaml",{"_index":2414,"t":{"413":{"position":[[42,11]]},"627":{"position":[[1133,11]]},"2104":{"position":[[32,11]]},"2126":{"position":[[429,11]]}}}],["config.yaml.templ",{"_index":9900,"t":{"3175":{"position":[[253,22]]}}}],["config/cspo",{"_index":2302,"t":{"389":{"position":[[79,11]]}}}],["config/openstack",{"_index":2952,"t":{"519":{"position":[[374,19]]},"617":{"position":[[1038,20]]}}}],["config/openstack/clouds.yaml",{"_index":2892,"t":{"501":{"position":[[928,31]]},"600":{"position":[[1312,32]]},"648":{"position":[[719,31]]},"903":{"position":[[115,31]]},"905":{"position":[[255,31]]},"1625":{"position":[[115,31]]},"1627":{"position":[[255,31]]},"2350":{"position":[[115,31]]},"2352":{"position":[[255,31]]}}}],["config/openstack/secure.yaml",{"_index":4378,"t":{"905":{"position":[[1016,32]]},"1627":{"position":[[1016,32]]},"2352":{"position":[[1016,32]]}}}],["config/systemd/us",{"_index":4489,"t":{"913":{"position":[[3602,23],[3655,23]]},"1635":{"position":[[3602,23],[3655,23]]},"2360":{"position":[[3602,23],[3655,23]]}}}],["config=\"config",{"_index":8290,"t":{"2148":{"position":[[181,16]]}}}],["config_fil",{"_index":5910,"t":{"1167":{"position":[[4198,15],[4835,15]]}}}],["config_path",{"_index":3365,"t":{"635":{"position":[[2090,11]]}}}],["configfil",{"_index":4257,"t":{"859":{"position":[[6476,11]]},"1603":{"position":[[6476,11]]}}}],["configmap",{"_index":2510,"t":{"436":{"position":[[853,10]]},"2071":{"position":[[328,9],[501,10]]},"2116":{"position":[[650,9],[673,9],[785,10],[925,9]]}}}],["configur",{"_index":781,"t":{"122":{"position":[[247,13]]},"139":{"position":[[414,13]]},"143":{"position":[[119,9]]},"147":{"position":[[205,13]]},"187":{"position":[[166,13],[441,10]]},"249":{"position":[[203,13]]},"298":{"position":[[405,10]]},"302":{"position":[[1228,10],[1393,9]]},"311":{"position":[[273,10]]},"315":{"position":[[159,14],[189,13]]},"317":{"position":[[145,13],[672,13],[759,13]]},"319":{"position":[[11,10]]},"321":{"position":[[71,14],[326,13],[494,15]]},"323":{"position":[[755,13]]},"325":{"position":[[5492,13]]},"333":{"position":[[306,13]]},"349":{"position":[[289,13],[385,14]]},"379":{"position":[[385,14],[691,10]]},"383":{"position":[[148,9],[322,11]]},"393":{"position":[[1752,13],[1809,13]]},"398":{"position":[[95,13]]},"427":{"position":[[847,9]]},"436":{"position":[[1112,10],[1461,10]]},"444":{"position":[[348,14]]},"472":{"position":[[337,14],[1776,13]]},"485":{"position":[[1597,13]]},"487":{"position":[[4417,9],[5890,13]]},"491":{"position":[[45,13],[395,13]]},"513":{"position":[[2412,13]]},"557":{"position":[[51,13]]},"559":{"position":[[44,13]]},"561":{"position":[[50,13]]},"563":{"position":[[46,13]]},"565":{"position":[[42,13]]},"600":{"position":[[1113,11],[1226,13],[1295,13]]},"604":{"position":[[4050,13],[7138,13],[7283,13],[7530,12],[7589,13],[7911,13],[8091,13],[8234,13],[8310,13],[8795,13],[8940,13],[9240,12],[9299,13],[9479,13]]},"609":{"position":[[1953,13],[2063,13],[2156,13],[2298,12],[2357,13],[4755,13],[4865,13],[4958,13],[5153,12],[5212,13]]},"619":{"position":[[684,13],[729,13],[794,13],[836,13]]},"627":{"position":[[487,13]]},"633":{"position":[[101,11],[218,13],[348,9],[467,9],[845,9],[878,13],[2400,10],[2992,9],[3034,10],[3482,10]]},"635":{"position":[[1816,13],[1861,13]]},"637":{"position":[[152,14]]},"644":{"position":[[679,10]]},"730":{"position":[[202,13]]},"742":{"position":[[908,9]]},"792":{"position":[[4,13],[199,14]]},"796":{"position":[[1062,13]]},"798":{"position":[[1117,13]]},"817":{"position":[[567,13]]},"821":{"position":[[128,10]]},"850":{"position":[[1232,10]]},"876":{"position":[[322,13],[385,11]]},"883":{"position":[[809,15],[1939,10]]},"895":{"position":[[624,13],[656,11]]},"901":{"position":[[129,9]]},"905":{"position":[[224,9],[1397,9],[2379,9]]},"907":{"position":[[135,9]]},"913":{"position":[[489,9]]},"920":{"position":[[501,10],[723,10]]},"922":{"position":[[1365,12]]},"928":{"position":[[61,13]]},"932":{"position":[[1145,9],[1810,10]]},"934":{"position":[[331,13],[1626,13]]},"956":{"position":[[545,13],[1480,14],[2458,14]]},"977":{"position":[[1106,14]]},"980":{"position":[[28,14]]},"1012":{"position":[[563,13]]},"1021":{"position":[[46,9]]},"1037":{"position":[[63,13]]},"1041":{"position":[[797,13]]},"1052":{"position":[[155,13]]},"1055":{"position":[[292,13],[500,13],[929,13],[2580,9],[2874,10],[3551,14],[3625,14]]},"1057":{"position":[[4,13],[96,13]]},"1059":{"position":[[29,13],[131,13],[229,13]]},"1061":{"position":[[182,13],[702,13]]},"1063":{"position":[[1472,16]]},"1065":{"position":[[16,13],[761,13]]},"1067":{"position":[[4,13],[192,13],[241,13],[337,13],[584,13],[2129,13],[2252,14],[2411,13],[2478,13],[2507,13],[3798,14]]},"1071":{"position":[[482,13],[1399,13],[1434,13]]},"1073":{"position":[[2,13],[105,13],[161,13],[211,13],[530,13]]},"1075":{"position":[[43,13],[124,13],[182,14],[240,13]]},"1077":{"position":[[36,13],[77,13],[857,13],[1285,13]]},"1080":{"position":[[265,13],[655,13],[1392,13],[1669,13],[1758,13]]},"1082":{"position":[[536,13]]},"1086":{"position":[[22,13],[47,13]]},"1089":{"position":[[124,13],[822,13],[1547,13],[1669,13],[1716,14],[2409,13],[2537,13]]},"1091":{"position":[[61,15]]},"1094":{"position":[[121,14]]},"1098":{"position":[[8,13],[38,13],[127,13]]},"1108":{"position":[[14,13],[1185,13],[1225,13],[1369,13]]},"1112":{"position":[[294,9],[437,13],[883,9],[3435,13],[3457,13],[3528,13],[3596,13],[3665,13],[3708,9],[3755,13],[3886,13],[3942,13],[4060,9],[4229,9],[4769,13],[4797,13],[4848,13]]},"1114":{"position":[[586,13],[614,9],[699,9],[980,13],[1051,9],[4188,13],[4216,9],[4301,9],[4582,13],[4653,9]]},"1118":{"position":[[45,14],[338,10],[555,13]]},"1120":{"position":[[243,13],[378,13]]},"1126":{"position":[[30,13],[59,13]]},"1128":{"position":[[26,13],[53,13]]},"1132":{"position":[[32,13],[62,13]]},"1134":{"position":[[34,13]]},"1136":{"position":[[26,13]]},"1138":{"position":[[22,13]]},"1140":{"position":[[26,13]]},"1142":{"position":[[28,13],[56,13]]},"1144":{"position":[[203,13]]},"1148":{"position":[[30,13]]},"1150":{"position":[[178,13],[208,9],[354,13],[548,13]]},"1153":{"position":[[26,13],[53,13]]},"1159":{"position":[[71,10]]},"1161":{"position":[[90,13],[1402,13],[3875,13]]},"1165":{"position":[[298,13],[938,10],[1338,13],[1446,9],[2015,13],[2185,14],[2575,9],[3217,13],[3342,13],[3520,13]]},"1167":{"position":[[59,13],[2050,13],[2707,13],[3287,13],[3912,11]]},"1169":{"position":[[72,10],[375,14]]},"1171":{"position":[[22,13],[47,13]]},"1184":{"position":[[281,13],[628,13]]},"1186":{"position":[[28,13],[56,13],[165,13],[209,13],[291,13]]},"1188":{"position":[[354,13],[430,13],[489,13]]},"1190":{"position":[[26,13]]},"1192":{"position":[[28,13],[56,13]]},"1195":{"position":[[18,13]]},"1197":{"position":[[44,13]]},"1209":{"position":[[117,9]]},"1211":{"position":[[32,13],[62,13]]},"1213":{"position":[[128,13],[1040,13]]},"1217":{"position":[[298,10],[545,10],[907,13]]},"1219":{"position":[[156,13],[189,13],[259,13]]},"1224":{"position":[[2527,13],[2678,14],[2742,14],[2863,13],[3911,13]]},"1226":{"position":[[929,9]]},"1234":{"position":[[655,9],[815,9],[1834,9]]},"1236":{"position":[[59,13],[92,13],[162,13],[324,13]]},"1240":{"position":[[50,13],[185,13],[246,13],[278,13],[301,13],[384,13],[485,13],[820,13],[994,13],[1180,13],[1304,13]]},"1248":{"position":[[116,13]]},"1254":{"position":[[54,13]]},"1256":{"position":[[2474,13]]},"1258":{"position":[[382,14],[492,13],[639,13],[769,13],[839,13]]},"1262":{"position":[[13,13],[48,13]]},"1273":{"position":[[52,13],[193,13]]},"1286":{"position":[[752,13],[890,13],[1659,13],[2813,13]]},"1288":{"position":[[353,9]]},"1292":{"position":[[99,13]]},"1360":{"position":[[835,13]]},"1362":{"position":[[7,13],[84,13],[141,13],[2552,13]]},"1400":{"position":[[282,13]]},"1469":{"position":[[291,13]]},"1484":{"position":[[1232,10]]},"1491":{"position":[[202,13]]},"1507":{"position":[[567,13]]},"1511":{"position":[[128,10]]},"1529":{"position":[[4,13],[199,14]]},"1533":{"position":[[1062,13]]},"1535":{"position":[[1117,13]]},"1569":{"position":[[1177,13]]},"1582":{"position":[[198,13]]},"1585":{"position":[[15,14],[1677,14],[1790,10],[1812,13],[2119,13],[2665,11],[2699,10]]},"1587":{"position":[[415,13]]},"1617":{"position":[[624,13],[656,11]]},"1623":{"position":[[129,9]]},"1627":{"position":[[224,9],[1397,9],[2379,9]]},"1629":{"position":[[135,9]]},"1635":{"position":[[489,9]]},"1642":{"position":[[501,10],[723,10]]},"1644":{"position":[[1365,12]]},"1650":{"position":[[61,13]]},"1654":{"position":[[1145,9],[1810,10]]},"1656":{"position":[[331,13],[1626,13]]},"1674":{"position":[[782,13]]},"1684":{"position":[[273,13]]},"1686":{"position":[[374,13]]},"1697":{"position":[[415,13]]},"1701":{"position":[[195,13]]},"1743":{"position":[[168,9]]},"1747":{"position":[[367,14]]},"1749":{"position":[[1686,14]]},"1754":{"position":[[53,13]]},"1758":{"position":[[169,13]]},"1764":{"position":[[3399,13],[4393,13]]},"1766":{"position":[[218,13],[425,10]]},"1779":{"position":[[401,9]]},"1785":{"position":[[561,13],[655,14],[719,13]]},"1791":{"position":[[91,10],[1040,13],[2520,13],[3325,13]]},"1794":{"position":[[774,13]]},"1808":{"position":[[30,9]]},"1810":{"position":[[4,13],[87,13]]},"1825":{"position":[[344,13],[408,13],[818,13],[1555,13],[1841,13],[1930,13],[2063,13],[2121,13]]},"1833":{"position":[[1303,13]]},"1841":{"position":[[287,13]]},"1845":{"position":[[2390,10]]},"1857":{"position":[[143,13],[452,13],[946,14]]},"1874":{"position":[[293,13]]},"1919":{"position":[[143,13],[452,13],[946,14]]},"1939":{"position":[[86,13],[343,10]]},"1947":{"position":[[188,10],[335,13]]},"1955":{"position":[[77,9]]},"1957":{"position":[[1676,14],[4190,10]]},"1959":{"position":[[60,13],[791,10],[830,10]]},"1963":{"position":[[570,13]]},"1972":{"position":[[685,14]]},"1990":{"position":[[293,13]]},"2037":{"position":[[399,13]]},"2039":{"position":[[121,13]]},"2041":{"position":[[26,13],[159,13],[251,13]]},"2047":{"position":[[70,10]]},"2053":{"position":[[199,13]]},"2067":{"position":[[1371,13],[1429,13],[1558,13]]},"2069":{"position":[[44,13],[102,13],[231,13]]},"2081":{"position":[[389,14]]},"2096":{"position":[[312,13],[791,9],[867,11],[1911,14]]},"2098":{"position":[[347,13],[2969,14]]},"2106":{"position":[[375,14]]},"2120":{"position":[[346,10]]},"2122":{"position":[[109,13]]},"2138":{"position":[[660,11],[814,14]]},"2140":{"position":[[207,10],[273,13],[381,13],[443,13]]},"2142":{"position":[[27,13],[78,13]]},"2196":{"position":[[1064,10]]},"2212":{"position":[[19,13]]},"2250":{"position":[[110,13]]},"2255":{"position":[[165,13]]},"2342":{"position":[[624,13],[656,11]]},"2348":{"position":[[129,9]]},"2352":{"position":[[224,9],[1397,9],[2379,9]]},"2354":{"position":[[135,9]]},"2360":{"position":[[489,9]]},"2367":{"position":[[501,10],[723,10]]},"2369":{"position":[[1365,12]]},"2375":{"position":[[61,13]]},"2379":{"position":[[1145,9],[1810,10]]},"2381":{"position":[[331,13],[1626,13]]},"2461":{"position":[[239,14],[851,12]]},"2476":{"position":[[535,9],[685,14]]},"2495":{"position":[[162,13]]},"2497":{"position":[[324,14]]},"2550":{"position":[[225,14]]},"2574":{"position":[[685,13]]},"2673":{"position":[[1195,14],[1464,14],[1510,12]]},"2677":{"position":[[829,13]]},"2723":{"position":[[387,10]]},"2762":{"position":[[400,10]]},"2848":{"position":[[387,10]]},"2903":{"position":[[61,10]]},"2951":{"position":[[247,10],[1013,13]]},"2960":{"position":[[1571,13]]},"2962":{"position":[[362,14],[548,14]]},"2966":{"position":[[64,10],[248,14],[2135,13],[2280,10],[2946,10],[3399,9],[3736,13],[4484,13],[4656,14]]},"3003":{"position":[[39,13],[243,11],[285,13],[525,9]]},"3005":{"position":[[82,13],[226,13],[283,13]]},"3042":{"position":[[52,10]]},"3044":{"position":[[220,13]]},"3046":{"position":[[24,10]]},"3080":{"position":[[197,10]]},"3082":{"position":[[391,10],[572,10]]},"3090":{"position":[[25,15]]},"3103":{"position":[[289,10],[376,10],[510,13],[659,9],[1667,10]]},"3227":{"position":[[247,14],[350,14]]},"3231":{"position":[[31,13],[106,13]]},"3236":{"position":[[2081,14]]},"3238":{"position":[[900,13]]},"3249":{"position":[[377,9],[896,13]]},"3251":{"position":[[1192,13],[1879,11],[2179,13],[2774,13],[3997,10],[4621,14],[5075,14]]},"3255":{"position":[[104,13]]},"3270":{"position":[[1515,14]]},"3272":{"position":[[889,13]]},"3276":{"position":[[991,10],[1137,13]]},"3280":{"position":[[497,9],[779,13]]},"3301":{"position":[[3899,10]]},"3314":{"position":[[1453,13]]},"3316":{"position":[[682,13]]},"3325":{"position":[[3105,10]]},"3397":{"position":[[863,10],[912,10],[952,10],[995,10],[1079,10],[1123,10],[1168,10],[1215,10],[1260,10],[1311,10],[1368,10],[1416,10]]},"3444":{"position":[[87,13]]},"3453":{"position":[[211,13],[295,14]]},"3457":{"position":[[47,13],[352,13],[827,13]]},"3459":{"position":[[15,13],[609,14],[865,13]]},"3461":{"position":[[50,13]]},"3465":{"position":[[1261,10],[1371,13]]},"3472":{"position":[[398,13],[12960,10]]},"3482":{"position":[[1520,10],[2184,13]]},"3518":{"position":[[159,11],[2320,13]]}}}],["configuration.md",{"_index":9065,"t":{"2673":{"position":[[336,16]]}}}],["configuration.yml",{"_index":4851,"t":{"1055":{"position":[[543,18],[2403,17]]},"1112":{"position":[[3848,18]]},"1114":{"position":[[823,18],[4425,18]]},"1120":{"position":[[421,18]]},"2255":{"position":[[17,17],[141,19]]}}}],["configuration_vers",{"_index":7678,"t":{"1808":{"position":[[245,21]]}}}],["configuraton",{"_index":10010,"t":{"3251":{"position":[[4564,12]]}}}],["configure_containerd.sh",{"_index":3358,"t":{"635":{"position":[[1693,23],[1737,23]]}}}],["configurt",{"_index":6115,"t":{"1258":{"position":[[577,13]]}}}],["confirm",{"_index":1470,"t":{"210":{"position":[[152,9],[257,13]]},"381":{"position":[[615,7],[953,7]]},"1569":{"position":[[774,13]]},"2944":{"position":[[546,9]]}}}],["conflict",{"_index":3206,"t":{"606":{"position":[[71,9]]},"1571":{"position":[[934,11]]},"2263":{"position":[[51,9]]},"3210":{"position":[[765,10]]},"3301":{"position":[[669,9]]},"3453":{"position":[[319,8]]}}}],["conform",{"_index":1812,"t":{"265":{"position":[[138,11]]},"276":{"position":[[31,11],[291,11]]},"278":{"position":[[41,11]]},"280":{"position":[[82,11],[108,11],[524,11],[589,11],[647,11],[793,11]]},"284":{"position":[[251,11],[682,11]]},"288":{"position":[[0,11],[284,11]]},"479":{"position":[[90,11]]},"487":{"position":[[5020,11]]},"493":{"position":[[205,11],[340,11],[481,11],[622,11],[1785,11],[1869,11]]},"495":{"position":[[149,11],[180,11],[603,11],[776,11]]},"499":{"position":[[781,11]]},"513":{"position":[[2022,11]]},"561":{"position":[[11,11],[104,11],[155,10]]},"615":{"position":[[241,11]]},"669":{"position":[[798,11]]},"2233":{"position":[[300,11]]},"2265":{"position":[[84,11]]},"2298":{"position":[[84,11],[848,11],[918,11]]},"2330":{"position":[[281,11]]},"2514":{"position":[[198,12]]},"2518":{"position":[[73,7]]},"2592":{"position":[[530,11]]},"2627":{"position":[[311,11],[376,11],[421,11]]},"2635":{"position":[[235,11],[539,10]]},"2656":{"position":[[213,11],[248,11]]},"2658":{"position":[[63,11]]},"2660":{"position":[[114,11],[286,7]]},"2756":{"position":[[107,7]]},"2781":{"position":[[46,7]]},"2957":{"position":[[193,10]]},"2990":{"position":[[169,10]]},"2994":{"position":[[379,7]]},"3053":{"position":[[801,11]]},"3055":{"position":[[559,11]]},"3059":{"position":[[1344,11]]},"3063":{"position":[[165,11]]},"3071":{"position":[[9,11],[898,11],[1287,11],[1475,11]]},"3092":{"position":[[4,11]]},"3175":{"position":[[4,11]]},"3242":{"position":[[0,11]]},"3290":{"position":[[0,11]]},"3333":{"position":[[0,11]]},"3431":{"position":[[281,11]]},"3516":{"position":[[0,11]]},"3518":{"position":[[1561,11]]}}}],["confront",{"_index":1631,"t":{"245":{"position":[[1513,8],[1768,8]]}}}],["confus",{"_index":4866,"t":{"1055":{"position":[[2437,9]]},"2658":{"position":[[28,9]]},"3084":{"position":[[780,7]]},"3109":{"position":[[1197,7]]},"3482":{"position":[[2656,9]]}}}],["congest",{"_index":10026,"t":{"3270":{"position":[[152,10]]}}}],["conjunct",{"_index":2820,"t":{"487":{"position":[[4947,11]]},"2764":{"position":[[472,11]]},"3459":{"position":[[742,11]]}}}],["conn",{"_index":6016,"t":{"1224":{"position":[[1364,4],[1483,4],[2114,4]]}}}],["connect",{"_index":245,"t":{"23":{"position":[[193,9]]},"249":{"position":[[257,8]]},"251":{"position":[[0,7],[504,9],[600,12],[639,12]]},"259":{"position":[[3,7]]},"290":{"position":[[278,7],[332,10]]},"292":{"position":[[109,7]]},"294":{"position":[[102,7]]},"296":{"position":[[139,7]]},"298":{"position":[[143,7],[350,7],[1059,9]]},"304":{"position":[[48,7],[143,7]]},"323":{"position":[[65,10]]},"325":{"position":[[2357,7]]},"377":{"position":[[145,10]]},"379":{"position":[[442,12]]},"381":{"position":[[137,10]]},"436":{"position":[[1024,12]]},"487":{"position":[[1280,7],[4497,11]]},"489":{"position":[[865,10]]},"501":{"position":[[599,9]]},"507":{"position":[[402,11],[482,10],[554,11]]},"513":{"position":[[1727,9]]},"600":{"position":[[359,10]]},"669":{"position":[[1055,12]]},"738":{"position":[[403,9],[476,12]]},"750":{"position":[[176,8]]},"762":{"position":[[417,10]]},"774":{"position":[[220,7]]},"895":{"position":[[1529,12]]},"903":{"position":[[446,9],[473,8],[1377,7],[2605,7],[3739,7],[3820,11]]},"920":{"position":[[525,11]]},"932":{"position":[[1502,10],[1937,12]]},"945":{"position":[[130,7]]},"947":{"position":[[1163,7]]},"949":{"position":[[1007,10]]},"984":{"position":[[188,7]]},"1037":{"position":[[156,7]]},"1165":{"position":[[3409,10]]},"1224":{"position":[[3206,11],[3432,7]]},"1234":{"position":[[195,13]]},"1368":{"position":[[82,10],[1891,12],[2570,12]]},"1383":{"position":[[349,11]]},"1388":{"position":[[133,7]]},"1562":{"position":[[784,13]]},"1569":{"position":[[1070,7],[1435,11]]},"1571":{"position":[[761,7]]},"1574":{"position":[[244,7]]},"1585":{"position":[[891,10],[956,10],[1030,10],[1089,10],[1148,10],[1209,10],[1270,10],[1331,10],[2889,11]]},"1617":{"position":[[1529,12]]},"1625":{"position":[[446,9],[473,8],[1377,7],[2605,7],[3739,7],[3820,11]]},"1642":{"position":[[525,11]]},"1654":{"position":[[1502,10],[1937,12]]},"1667":{"position":[[130,7]]},"1669":{"position":[[1163,7]]},"1671":{"position":[[1007,10]]},"1734":{"position":[[238,7],[296,10]]},"1747":{"position":[[318,11]]},"1783":{"position":[[207,7]]},"1785":{"position":[[462,7]]},"1791":{"position":[[27,7],[1797,7],[2587,8]]},"1843":{"position":[[165,7]]},"1849":{"position":[[628,10]]},"1853":{"position":[[198,8]]},"1857":{"position":[[379,12]]},"1915":{"position":[[198,8]]},"1919":{"position":[[379,12]]},"1937":{"position":[[280,7],[334,10]]},"1945":{"position":[[90,8]]},"1947":{"position":[[161,7]]},"1951":{"position":[[910,7]]},"1957":{"position":[[675,7],[1078,7],[1322,7]]},"1959":{"position":[[126,7],[189,7],[847,9]]},"2209":{"position":[[364,10]]},"2248":{"position":[[1001,7],[1390,11]]},"2250":{"position":[[37,7]]},"2263":{"position":[[193,10]]},"2342":{"position":[[1529,12]]},"2350":{"position":[[446,9],[473,8],[1377,7],[2605,7],[3739,7],[3820,11]]},"2367":{"position":[[525,11]]},"2379":{"position":[[1502,10],[1937,12]]},"2392":{"position":[[130,7]]},"2394":{"position":[[1163,7]]},"2396":{"position":[[1007,10]]},"2403":{"position":[[383,13]]},"2476":{"position":[[568,7],[814,7]]},"2493":{"position":[[51,7]]},"2899":{"position":[[584,7]]},"2915":{"position":[[28,8]]},"2935":{"position":[[141,7]]},"2947":{"position":[[4102,10]]},"2994":{"position":[[139,7]]},"3050":{"position":[[58,8]]},"3074":{"position":[[206,8]]},"3097":{"position":[[96,7]]},"3099":{"position":[[64,10]]},"3132":{"position":[[65,10]]},"3208":{"position":[[699,11]]},"3210":{"position":[[645,11]]},"3247":{"position":[[275,7]]},"3251":{"position":[[2511,9],[3610,7],[5652,9]]},"3355":{"position":[[272,12]]},"3393":{"position":[[286,12]]},"3400":{"position":[[927,12]]},"3413":{"position":[[311,10],[411,10]]},"3479":{"position":[[65,8]]}}}],["connect/auth?client_id=secur",{"_index":8022,"t":{"1957":{"position":[[3410,31]]}}}],["connect/auth?scope=openid",{"_index":8026,"t":{"1957":{"position":[[3793,30]]}}}],["consectetur",{"_index":58,"t":{"6":{"position":[[28,11]]}}}],["consensu",{"_index":8358,"t":{"2176":{"position":[[379,9],[498,9],[529,9]]},"2629":{"position":[[168,10],[217,9]]}}}],["consequ",{"_index":2878,"t":{"499":{"position":[[2064,13]]},"1791":{"position":[[666,10]]},"2627":{"position":[[1895,12]]},"2665":{"position":[[245,13]]},"2990":{"position":[[463,12]]},"3111":{"position":[[68,12]]},"3117":{"position":[[92,12]]},"3251":{"position":[[1576,12]]}}}],["consequat",{"_index":70,"t":{"6":{"position":[[141,10]]}}}],["conserv",{"_index":4585,"t":{"932":{"position":[[3211,10]]},"1397":{"position":[[487,12]]},"1654":{"position":[[3211,10]]},"2379":{"position":[[3211,10]]}}}],["consid",{"_index":1024,"t":{"166":{"position":[[460,10],[516,8],[1145,8]]},"172":{"position":[[489,8]]},"174":{"position":[[213,10],[327,10],[606,11],[762,10],[909,8]]},"178":{"position":[[787,10]]},"202":{"position":[[295,9]]},"204":{"position":[[14,8]]},"206":{"position":[[207,9]]},"238":{"position":[[231,10]]},"321":{"position":[[553,10]]},"325":{"position":[[2174,10]]},"374":{"position":[[10,10]]},"379":{"position":[[1057,10]]},"421":{"position":[[1612,8]]},"487":{"position":[[5054,10],[5206,10]]},"499":{"position":[[1523,8]]},"604":{"position":[[3810,9]]},"667":{"position":[[209,9]]},"770":{"position":[[282,10]]},"901":{"position":[[631,8]]},"905":{"position":[[1474,8]]},"907":{"position":[[711,8]]},"911":{"position":[[272,8]]},"932":{"position":[[3765,8]]},"942":{"position":[[43,8],[411,8]]},"1448":{"position":[[110,11]]},"1623":{"position":[[631,8]]},"1627":{"position":[[1474,8]]},"1629":{"position":[[711,8]]},"1633":{"position":[[272,8]]},"1654":{"position":[[3765,8]]},"1664":{"position":[[43,8],[411,8]]},"1963":{"position":[[159,11]]},"2096":{"position":[[1226,8]]},"2098":{"position":[[2491,8]]},"2196":{"position":[[435,8]]},"2348":{"position":[[631,8]]},"2352":{"position":[[1474,8]]},"2354":{"position":[[711,8]]},"2358":{"position":[[272,8]]},"2379":{"position":[[3765,8]]},"2389":{"position":[[43,8],[411,8]]},"2576":{"position":[[476,11]]},"2625":{"position":[[2345,10]]},"2627":{"position":[[650,11],[767,10],[1881,11]]},"2633":{"position":[[84,10]]},"2637":{"position":[[295,10]]},"2731":{"position":[[1503,10]]},"2770":{"position":[[1526,10]]},"2809":{"position":[[272,10]]},"2860":{"position":[[1487,10]]},"2892":{"position":[[215,10]]},"2895":{"position":[[1535,10]]},"2901":{"position":[[551,10]]},"2947":{"position":[[4538,10]]},"2951":{"position":[[705,10]]},"2966":{"position":[[828,10],[1269,9]]},"2999":{"position":[[25,10]]},"3031":{"position":[[44,10]]},"3071":{"position":[[925,11]]},"3103":{"position":[[0,11]]},"3162":{"position":[[230,10],[397,11]]},"3255":{"position":[[317,10]]},"3270":{"position":[[452,11]]},"3299":{"position":[[552,10],[774,10],[1020,10],[1755,10],[3123,10]]},"3301":{"position":[[1742,10],[1912,10],[2718,8],[5383,9]]},"3357":{"position":[[1155,10]]},"3378":{"position":[[314,10]]},"3417":{"position":[[74,11]]}}}],["consider",{"_index":1792,"t":{"253":{"position":[[2097,14]]},"778":{"position":[[214,12]]},"1982":{"position":[[560,13]]},"1984":{"position":[[170,13]]},"2214":{"position":[[750,14]]},"2510":{"position":[[12,12]]},"2627":{"position":[[671,14]]},"2656":{"position":[[83,15]]},"2731":{"position":[[1010,14]]},"2735":{"position":[[635,14]]},"2770":{"position":[[1010,14]]},"2813":{"position":[[1551,15]]},"2860":{"position":[[971,14]]},"3027":{"position":[[4,14]]},"3197":{"position":[[12,14]]},"3204":{"position":[[54,14]]},"3208":{"position":[[496,13]]},"3249":{"position":[[792,14]]},"3268":{"position":[[55,14]]},"3336":{"position":[[37,14]]}}}],["considerations.md",{"_index":1794,"t":{"253":{"position":[[2196,18]]}}}],["consist",{"_index":531,"t":{"71":{"position":[[233,10]]},"184":{"position":[[627,10]]},"245":{"position":[[1919,8]]},"253":{"position":[[1169,10]]},"276":{"position":[[213,10]]},"335":{"position":[[293,11]]},"444":{"position":[[252,8]]},"472":{"position":[[241,8]]},"738":{"position":[[24,8]]},"746":{"position":[[34,8]]},"792":{"position":[[18,8]]},"817":{"position":[[441,8]]},"883":{"position":[[1181,10],[1351,11],[2184,10]]},"888":{"position":[[312,10],[689,10],[1350,10],[2332,10]]},"1507":{"position":[[441,8]]},"1529":{"position":[[18,8]]},"1705":{"position":[[93,10]]},"1886":{"position":[[149,10],[172,11]]},"1892":{"position":[[401,10],[424,11]]},"1911":{"position":[[603,8]]},"1972":{"position":[[100,10],[170,10],[248,10],[1084,10],[1144,10]]},"1974":{"position":[[31,10]]},"2002":{"position":[[149,10],[172,11]]},"2008":{"position":[[401,10],[424,11]]},"2027":{"position":[[603,8]]},"2100":{"position":[[930,10]]},"2250":{"position":[[565,10]]},"2514":{"position":[[549,8]]},"2522":{"position":[[39,10]]},"2526":{"position":[[198,12]]},"2548":{"position":[[459,11]]},"2550":{"position":[[454,11]]},"2625":{"position":[[701,7]]},"2665":{"position":[[388,10]]},"2677":{"position":[[433,10]]},"2811":{"position":[[24,8]]},"2903":{"position":[[125,11]]},"2947":{"position":[[4155,11]]},"3046":{"position":[[756,11]]},"3178":{"position":[[54,8]]},"3182":{"position":[[2019,13]]},"3184":{"position":[[1266,7]]},"3191":{"position":[[54,8]]},"3272":{"position":[[19,11]]},"3391":{"position":[[94,10]]},"3397":{"position":[[665,7]]},"3408":{"position":[[28,8]]},"3477":{"position":[[306,10]]},"3482":{"position":[[3236,10]]},"3484":{"position":[[359,10]]}}}],["consol",{"_index":2965,"t":{"540":{"position":[[59,7],[117,7],[160,7]]},"542":{"position":[[5,7],[63,7],[147,7],[187,7]]},"557":{"position":[[152,8]]},"903":{"position":[[2573,7],[2657,7],[3933,7]]},"909":{"position":[[619,7],[1612,7]]},"945":{"position":[[202,7]]},"947":{"position":[[524,7],[549,7]]},"1089":{"position":[[2625,7]]},"1197":{"position":[[8,7],[36,7]]},"1226":{"position":[[1530,7],[1558,7]]},"1331":{"position":[[2,7]]},"1333":{"position":[[19,7],[35,7],[96,8],[330,7]]},"1335":{"position":[[97,7],[232,7]]},"1337":{"position":[[41,7],[452,7]]},"1339":{"position":[[27,7],[251,7]]},"1569":{"position":[[1725,8]]},"1571":{"position":[[711,7],[1669,8]]},"1625":{"position":[[2573,7],[2657,7],[3933,7]]},"1631":{"position":[[619,7],[1612,7]]},"1667":{"position":[[202,7]]},"1669":{"position":[[524,7],[549,7]]},"1734":{"position":[[415,7]]},"1779":{"position":[[3551,7]]},"1849":{"position":[[23,7],[52,7],[803,7]]},"1957":{"position":[[3286,7],[3448,9],[3997,7],[4465,8]]},"2245":{"position":[[724,7]]},"2350":{"position":[[2573,7],[2657,7],[3933,7]]},"2356":{"position":[[619,7],[1612,7]]},"2392":{"position":[[202,7]]},"2394":{"position":[[524,7],[549,7]]}}}],["console.log('insid",{"_index":839,"t":{"131":{"position":[[492,19]]}}}],["console.services.a.regiocloud.tech",{"_index":5784,"t":{"1161":{"position":[[2893,34]]}}}],["console=capi",{"_index":2963,"t":{"540":{"position":[[9,12]]},"542":{"position":[[13,12]]}}}],["consolid",{"_index":8201,"t":{"2106":{"position":[[4,12]]},"3055":{"position":[[71,12]]},"3071":{"position":[[278,11]]}}}],["const",{"_index":673,"t":{"105":{"position":[[936,5],[961,5],[1086,5],[1226,5],[1262,5],[1429,5],[1503,5],[1613,5],[1713,5],[1859,5],[1988,5],[2118,5]]},"131":{"position":[[465,5]]}}}],["constitut",{"_index":1190,"t":{"174":{"position":[[13,11]]}}}],["constrain",{"_index":8193,"t":{"2100":{"position":[[127,11]]}}}],["constraint",{"_index":7905,"t":{"1857":{"position":[[171,12]]},"1919":{"position":[[171,12]]},"3182":{"position":[[937,10],[1036,10]]},"3184":{"position":[[2888,10]]},"3188":{"position":[[136,11]]},"3224":{"position":[[307,12]]},"3380":{"position":[[285,13]]},"3400":{"position":[[1829,11]]}}}],["constru",{"_index":9496,"t":{"2872":{"position":[[769,9]]}}}],["construct",{"_index":1674,"t":{"247":{"position":[[1082,12],[2741,15]]},"282":{"position":[[392,11]]},"627":{"position":[[1956,14]]},"2715":{"position":[[84,9]]},"2783":{"position":[[129,9]]},"2795":{"position":[[2048,12]]},"2862":{"position":[[84,9]]}}}],["consult",{"_index":7893,"t":{"1851":{"position":[[133,11]]},"2245":{"position":[[559,7]]},"2278":{"position":[[290,7]]},"2518":{"position":[[282,7]]},"3479":{"position":[[278,7]]}}}],["consum",{"_index":1140,"t":{"170":{"position":[[1403,7]]},"172":{"position":[[95,7]]},"174":{"position":[[145,9]]},"178":{"position":[[1925,7]]},"180":{"position":[[317,9]]},"298":{"position":[[56,7]]},"513":{"position":[[201,8]]},"780":{"position":[[213,8],[230,8],[239,8],[344,8]]},"1351":{"position":[[201,8],[432,8],[819,8],[1529,8],[2343,8]]},"1566":{"position":[[230,8]]},"1740":{"position":[[16,7]]},"1745":{"position":[[637,8]]},"1810":{"position":[[426,9]]},"2096":{"position":[[1044,10]]},"2158":{"position":[[204,7]]},"2212":{"position":[[399,10]]},"2235":{"position":[[808,9]]},"2248":{"position":[[962,7]]},"2719":{"position":[[517,9]]},"2758":{"position":[[515,9]]},"3107":{"position":[[1651,9]]},"3135":{"position":[[8,9],[290,9]]},"3137":{"position":[[19,9]]},"3245":{"position":[[592,7]]},"3247":{"position":[[636,7]]},"3308":{"position":[[74,8],[294,9]]},"3314":{"position":[[1549,8],[1684,8]]},"3413":{"position":[[204,8]]},"3423":{"position":[[586,10]]},"3436":{"position":[[96,9],[193,9]]},"3446":{"position":[[216,9],[280,8]]}}}],["consumpt",{"_index":6043,"t":{"1226":{"position":[[1209,11],[1340,12],[1679,11]]},"1566":{"position":[[286,11]]},"2409":{"position":[[579,11]]},"2886":{"position":[[322,12],[447,12]]},"3251":{"position":[[5329,11]]},"3301":{"position":[[6579,11],[6610,11]]},"3353":{"position":[[199,12]]},"3395":{"position":[[964,11]]}}}],["contact",{"_index":215,"t":{"18":{"position":[[49,7]]},"25":{"position":[[202,7]]},"27":{"position":[[41,7]]},"30":{"position":[[61,7]]},"32":{"position":[[41,7]]},"191":{"position":[[83,7]]},"229":{"position":[[34,7]]},"245":{"position":[[1827,7]]},"249":{"position":[[352,8]]},"413":{"position":[[586,7]]},"646":{"position":[[910,7]]},"1773":{"position":[[333,7]]},"2901":{"position":[[1835,7]]}}}],["contain",{"_index":196,"t":{"12":{"position":[[249,12]]},"23":{"position":[[63,7]]},"65":{"position":[[66,9]]},"77":{"position":[[9,9],[48,10]]},"101":{"position":[[98,9],[493,9]]},"112":{"position":[[16,10],[78,7],[131,10]]},"116":{"position":[[15,7]]},"118":{"position":[[15,7]]},"170":{"position":[[811,7]]},"178":{"position":[[1127,8]]},"253":{"position":[[2061,7]]},"270":{"position":[[129,10],[229,10],[570,10]]},"272":{"position":[[163,11]]},"274":{"position":[[89,7]]},"280":{"position":[[142,7]]},"294":{"position":[[11,9]]},"298":{"position":[[748,9]]},"317":{"position":[[259,10]]},"321":{"position":[[954,8]]},"325":{"position":[[7668,8]]},"327":{"position":[[4,9],[97,9],[344,9]]},"329":{"position":[[63,9],[254,9]]},"331":{"position":[[4,9],[206,9],[258,10],[366,9]]},"333":{"position":[[40,9]]},"335":{"position":[[488,10],[534,9],[570,9],[604,9],[671,9]]},"337":{"position":[[226,10]]},"339":{"position":[[4,9],[582,9]]},"344":{"position":[[84,9],[158,9]]},"347":{"position":[[428,9]]},"349":{"position":[[52,9]]},"391":{"position":[[607,9]]},"393":{"position":[[172,9]]},"396":{"position":[[111,9]]},"404":{"position":[[689,8]]},"417":{"position":[[88,9],[569,8],[848,10]]},"428":{"position":[[1637,7]]},"430":{"position":[[52,9]]},"434":{"position":[[103,9],[189,9]]},"436":{"position":[[71,9]]},"438":{"position":[[93,9]]},"451":{"position":[[25,9]]},"460":{"position":[[72,9]]},"462":{"position":[[79,9],[817,9]]},"467":{"position":[[389,8],[2502,8]]},"472":{"position":[[1938,9],[2019,9]]},"487":{"position":[[5871,9]]},"491":{"position":[[342,7]]},"493":{"position":[[723,8],[1519,8]]},"497":{"position":[[215,8]]},"501":{"position":[[577,8]]},"503":{"position":[[300,9]]},"505":{"position":[[299,9]]},"513":{"position":[[1507,8]]},"594":{"position":[[112,8]]},"617":{"position":[[146,11],[229,10]]},"627":{"position":[[1653,7],[2407,7],[3461,8]]},"633":{"position":[[14,9],[167,9],[193,9],[425,9],[500,9],[571,9],[628,9],[805,9],[1753,9],[1813,9],[1986,9],[2207,9],[2306,9],[2379,8],[2471,9],[2614,9],[2719,9],[2786,9],[3049,9],[3444,9],[3497,9],[3574,9]]},"635":{"position":[[1088,9],[1187,9],[1566,9],[3684,8]]},"639":{"position":[[46,9],[694,9],[764,9],[863,9]]},"650":{"position":[[642,8]]},"652":{"position":[[813,7]]},"662":{"position":[[855,9]]},"714":{"position":[[15,9],[61,9]]},"732":{"position":[[180,8]]},"776":{"position":[[202,11],[330,10]]},"796":{"position":[[288,9]]},"798":{"position":[[349,9]]},"876":{"position":[[679,8]]},"913":{"position":[[653,9]]},"922":{"position":[[76,8],[509,7],[856,9],[975,9],[1083,9],[1254,8]]},"954":{"position":[[168,10],[403,9]]},"977":{"position":[[144,11],[284,11],[722,11],[786,11],[1073,11],[1488,10],[1942,11]]},"1008":{"position":[[13,8]]},"1055":{"position":[[530,8]]},"1063":{"position":[[160,10]]},"1065":{"position":[[692,8]]},"1091":{"position":[[26,8]]},"1120":{"position":[[408,8]]},"1124":{"position":[[279,9],[357,9]]},"1167":{"position":[[117,10],[793,9],[3352,9],[3815,10],[3848,9]]},"1205":{"position":[[19,10]]},"1207":{"position":[[13,8]]},"1213":{"position":[[928,11]]},"1217":{"position":[[400,9],[750,8],[870,10]]},"1221":{"position":[[13,8]]},"1256":{"position":[[90,10]]},"1277":{"position":[[19,9]]},"1294":{"position":[[132,8]]},"1317":{"position":[[2877,10]]},"1319":{"position":[[12,9]]},"1337":{"position":[[56,9]]},"1360":{"position":[[941,10],[1032,9],[1121,9]]},"1493":{"position":[[180,8]]},"1533":{"position":[[288,9]]},"1535":{"position":[[349,9]]},"1608":{"position":[[95,9],[545,9],[646,9],[683,9],[777,9]]},"1610":{"position":[[23,9],[225,9],[327,9],[362,9]]},"1635":{"position":[[653,9]]},"1644":{"position":[[76,8],[509,7],[856,9],[975,9],[1083,9],[1254,8]]},"1678":{"position":[[761,9],[979,9],[1491,9]]},"1684":{"position":[[448,8]]},"1690":{"position":[[24,9],[423,9],[467,9],[573,9],[876,9],[1238,9],[1415,9],[1750,10],[1839,9]]},"1734":{"position":[[355,10]]},"1745":{"position":[[110,8]]},"1749":{"position":[[1114,10]]},"1764":{"position":[[3661,10]]},"1766":{"position":[[102,11],[298,10],[749,10],[809,10]]},"1773":{"position":[[873,8]]},"1791":{"position":[[1602,8],[2779,8]]},"1822":{"position":[[56,10]]},"1855":{"position":[[845,8],[952,7]]},"1878":{"position":[[507,7]]},"1880":{"position":[[734,10]]},"1896":{"position":[[480,7],[815,8]]},"1902":{"position":[[307,9],[368,9]]},"1917":{"position":[[845,8],[952,7]]},"1951":{"position":[[886,9]]},"1953":{"position":[[194,9]]},"1963":{"position":[[365,9]]},"1976":{"position":[[695,9]]},"1994":{"position":[[507,7]]},"1996":{"position":[[734,10]]},"2012":{"position":[[480,7],[815,8]]},"2018":{"position":[[307,9],[368,9]]},"2031":{"position":[[52,8]]},"2071":{"position":[[10,8]]},"2089":{"position":[[91,8]]},"2096":{"position":[[146,8]]},"2098":{"position":[[409,8],[1332,8]]},"2100":{"position":[[608,8]]},"2106":{"position":[[352,8]]},"2120":{"position":[[10,8]]},"2140":{"position":[[10,8]]},"2146":{"position":[[10,8]]},"2158":{"position":[[10,8]]},"2190":{"position":[[266,11],[868,9]]},"2198":{"position":[[34,10]]},"2206":{"position":[[348,9]]},"2229":{"position":[[4,9]]},"2261":{"position":[[18,9]]},"2281":{"position":[[696,7]]},"2315":{"position":[[492,9]]},"2328":{"position":[[86,9]]},"2330":{"position":[[313,9],[653,9]]},"2334":{"position":[[346,10]]},"2360":{"position":[[653,9]]},"2369":{"position":[[76,8],[509,7],[856,9],[975,9],[1083,9],[1254,8]]},"2405":{"position":[[610,9]]},"2413":{"position":[[96,9]]},"2424":{"position":[[171,9]]},"2426":{"position":[[443,9]]},"2495":{"position":[[22,8]]},"2592":{"position":[[225,10],[674,9],[1001,9]]},"2625":{"position":[[853,7]]},"2627":{"position":[[261,10],[342,8],[1445,10]]},"2631":{"position":[[926,10]]},"2671":{"position":[[763,9]]},"2774":{"position":[[36,9]]},"2805":{"position":[[114,7],[499,7]]},"2820":{"position":[[258,9]]},"2868":{"position":[[217,9]]},"2874":{"position":[[806,8]]},"2886":{"position":[[121,7]]},"2892":{"position":[[55,9]]},"2895":{"position":[[2356,8],[2982,7]]},"2901":{"position":[[742,7],[1136,8],[1789,8]]},"2909":{"position":[[167,7]]},"2911":{"position":[[198,7]]},"2942":{"position":[[280,9],[343,10]]},"2944":{"position":[[774,9],[936,9]]},"2981":{"position":[[19,7]]},"3007":{"position":[[204,11]]},"3055":{"position":[[920,9]]},"3061":{"position":[[371,10]]},"3063":{"position":[[629,9]]},"3067":{"position":[[45,9]]},"3069":{"position":[[197,9]]},"3150":{"position":[[2,9],[82,9],[247,9]]},"3154":{"position":[[223,9],[537,9]]},"3156":{"position":[[59,9]]},"3158":{"position":[[330,9]]},"3160":{"position":[[2,9],[333,9],[980,9],[1095,9],[1455,9],[1651,9],[1829,9],[2599,9],[2724,9],[2838,9]]},"3162":{"position":[[32,9]]},"3178":{"position":[[492,10]]},"3180":{"position":[[226,9],[339,11]]},"3182":{"position":[[107,8]]},"3193":{"position":[[202,9],[315,11]]},"3195":{"position":[[555,8]]},"3218":{"position":[[126,11],[175,7],[306,10],[678,11]]},"3220":{"position":[[245,11],[304,9],[427,11]]},"3293":{"position":[[2,9],[82,9],[291,9]]},"3297":{"position":[[183,9],[359,9],[424,9]]},"3299":{"position":[[392,9],[1059,8],[1390,8],[2829,8]]},"3301":{"position":[[53,9],[300,9],[904,9],[1031,9],[1165,8],[1448,9],[2032,9],[2553,9],[3523,9],[4407,9],[5107,9],[5402,9],[7499,9]]},"3303":{"position":[[57,9],[214,9]]},"3305":{"position":[[18,9]]},"3347":{"position":[[129,7],[285,7],[354,7],[440,7],[489,8],[590,7],[641,7]]},"3357":{"position":[[11,8]]},"3472":{"position":[[13384,7],[13533,7]]},"3518":{"position":[[1720,9],[2077,9]]}}}],["container",{"_index":2137,"t":{"331":{"position":[[165,13]]},"865":{"position":[[532,16]]},"878":{"position":[[532,16]]},"895":{"position":[[863,13]]},"977":{"position":[[300,17]]},"1617":{"position":[[863,13]]},"2342":{"position":[[863,13]]},"2671":{"position":[[325,16]]},"3204":{"position":[[289,16]]},"3218":{"position":[[593,16]]},"3224":{"position":[[544,16]]}}}],["container.servic",{"_index":6625,"t":{"1362":{"position":[[515,17],[567,17],[619,17],[1476,17],[1530,17]]}}}],["container_action=restart",{"_index":6137,"t":{"1277":{"position":[[67,24]]}}}],["container_http_proxi",{"_index":5990,"t":{"1205":{"position":[[176,21]]}}}],["container_https_proxi",{"_index":5991,"t":{"1205":{"position":[[239,22]]}}}],["container_name=nova_comput",{"_index":6136,"t":{"1277":{"position":[[34,27]]}}}],["container_no_proxi",{"_index":5992,"t":{"1205":{"position":[[303,19]]}}}],["containerd",{"_index":2803,"t":{"487":{"position":[[3853,10]]},"633":{"position":[[0,10],[243,10],[358,10],[477,10],[855,11],[867,10],[998,10],[1201,11],[1467,10],[1712,10],[2896,10],[3002,10]]},"635":{"position":[[424,11],[944,10],[1000,10],[1047,10],[1176,10],[1555,10],[1609,10],[1805,10],[1882,10]]},"3216":{"position":[[240,10]]},"3393":{"position":[[439,10]]},"3400":{"position":[[1275,10]]}}}],["containerd.servic",{"_index":3367,"t":{"635":{"position":[[2177,18],[2691,20],[3195,20]]}}}],["containerd/host",{"_index":3351,"t":{"635":{"position":[[1223,16],[1329,16]]}}}],["containerd/hosts/docker.io",{"_index":3352,"t":{"635":{"position":[[1350,27]]}}}],["containerd_conf_append",{"_index":3360,"t":{"635":{"position":[[1935,22],[1972,23]]}}}],["containerd_registry_fil",{"_index":2801,"t":{"487":{"position":[[3768,25]]},"633":{"position":[[1037,25],[1667,25]]}}}],["contemporari",{"_index":9072,"t":{"2675":{"position":[[26,12]]}}}],["content",{"_index":679,"t":{"105":{"position":[[1019,8],[1968,7]]},"114":{"position":[[306,7],[821,8]]},"120":{"position":[[25,7]]},"127":{"position":[[123,7],[162,7],[202,7],[245,7],[287,7]]},"193":{"position":[[37,7],[242,7],[269,7],[306,7]]},"253":{"position":[[1624,7]]},"286":{"position":[[174,7]]},"325":{"position":[[5135,7],[6441,7],[6499,7],[7798,7]]},"393":{"position":[[642,7]]},"485":{"position":[[1436,7]]},"604":{"position":[[1272,7]]},"650":{"position":[[1443,7],[1975,7]]},"790":{"position":[[299,8]]},"1059":{"position":[[12,7]]},"1061":{"position":[[52,7]]},"1065":{"position":[[465,7],[624,8]]},"1073":{"position":[[82,7]]},"1108":{"position":[[203,7]]},"1112":{"position":[[4002,7],[4136,7],[4612,7],[4743,8]]},"1114":{"position":[[100,7],[851,7],[3965,7],[4453,7]]},"1165":{"position":[[19,7],[1373,8],[1627,8],[3555,8]]},"1167":{"position":[[2690,7]]},"1228":{"position":[[45,7]]},"1230":{"position":[[45,7]]},"1240":{"position":[[1406,7]]},"1527":{"position":[[299,8]]},"1684":{"position":[[545,8],[645,7],[726,7]]},"1745":{"position":[[309,8]]},"1874":{"position":[[276,8]]},"1894":{"position":[[280,9]]},"1990":{"position":[[276,8]]},"2010":{"position":[[280,9]]},"2118":{"position":[[1128,8]]},"2250":{"position":[[763,8]]},"2283":{"position":[[1262,8]]},"2426":{"position":[[780,7]]},"2491":{"position":[[79,7]]},"2627":{"position":[[1029,9]]},"2660":{"position":[[24,8]]},"2675":{"position":[[1218,7]]},"2677":{"position":[[444,7]]},"2688":{"position":[[1515,7]]},"2895":{"position":[[3656,7]]},"2951":{"position":[[831,8]]},"3046":{"position":[[707,7]]},"3160":{"position":[[997,7]]},"3301":{"position":[[1263,7],[3298,7],[6125,7],[7255,7]]}}}],["contentfrom",{"_index":3492,"t":{"650":{"position":[[1640,12]]}}}],["context",{"_index":606,"t":{"87":{"position":[[199,7]]},"176":{"position":[[1559,7]]},"325":{"position":[[3159,7]]},"366":{"position":[[1503,7]]},"374":{"position":[[1161,7]]},"609":{"position":[[1108,7]]},"627":{"position":[[133,7],[193,7],[1204,8],[4572,7],[4668,7]]},"631":{"position":[[795,7],[912,7]]},"669":{"position":[[106,7],[144,7]]},"760":{"position":[[589,8]]},"1874":{"position":[[17,7]]},"1990":{"position":[[17,7]]},"2067":{"position":[[1348,7]]},"2069":{"position":[[21,7]]},"2520":{"position":[[215,7]]},"2627":{"position":[[93,7],[1068,8],[1352,7]]},"2673":{"position":[[594,7],[836,7]]},"2999":{"position":[[47,7]]},"3128":{"position":[[429,8]]},"3184":{"position":[[1220,7],[1686,7]]},"3197":{"position":[[704,7]]},"3247":{"position":[[820,7]]},"3251":{"position":[[5682,7]]},"3293":{"position":[[350,7]]},"3374":{"position":[[535,8]]},"3463":{"position":[[689,7]]}}}],["context=${clusternam",{"_index":3287,"t":{"627":{"position":[[2171,22]]}}}],["context=}.tfvar",{"_index":2948,"t":{"519":{"position":[[156,28]]}}}],["default.tfvar",{"_index":3275,"t":{"625":{"position":[[87,14]]}}}],["default=1",{"_index":8319,"t":{"2150":{"position":[[1195,10],[1366,10]]}}}],["default=24h",{"_index":8296,"t":{"2148":{"position":[[417,12]]}}}],["default=48h",{"_index":8315,"t":{"2150":{"position":[[1026,12]]}}}],["default_backend",{"_index":5763,"t":{"1161":{"position":[[1958,15]]}}}],["default_project_id",{"_index":260,"t":{"23":{"position":[[472,18]]},"25":{"position":[[30,18]]}}}],["defaults/${cloud_provid",{"_index":3490,"t":{"650":{"position":[[1208,26]]},"652":{"position":[[476,26]]}}}],["defaults/cloud.conf",{"_index":3140,"t":{"604":{"position":[[6124,19]]}}}],["defaults/clust",{"_index":3491,"t":{"650":{"position":[[1337,16],[1862,16]]},"667":{"position":[[430,16]]}}}],["defaults/clusterctl.yaml",{"_index":3132,"t":{"604":{"position":[[5079,24]]},"648":{"position":[[159,24]]},"667":{"position":[[696,24]]}}}],["defaults/harbor",{"_index":3398,"t":{"641":{"position":[[332,15]]}}}],["defect",{"_index":8155,"t":{"2085":{"position":[[15,6]]}}}],["defens",{"_index":1254,"t":{"176":{"position":[[1540,11]]}}}],["defin",{"_index":10,"t":{"4":{"position":[[88,9]]},"71":{"position":[[4,8],[193,6]]},"103":{"position":[[159,6]]},"122":{"position":[[232,7]]},"124":{"position":[[205,7]]},"131":{"position":[[73,6]]},"141":{"position":[[605,7]]},"143":{"position":[[23,7],[731,6]]},"147":{"position":[[42,7]]},"174":{"position":[[50,7]]},"210":{"position":[[848,6],[928,6]]},"245":{"position":[[224,9]]},"270":{"position":[[145,7],[505,7]]},"319":{"position":[[763,6]]},"321":{"position":[[275,7],[450,6]]},"325":{"position":[[980,6],[1520,6],[2146,7],[2764,7],[2907,7],[3377,7]]},"366":{"position":[[1092,7],[1342,8]]},"368":{"position":[[197,6]]},"396":{"position":[[197,7]]},"398":{"position":[[175,7]]},"421":{"position":[[1441,7]]},"483":{"position":[[1076,7]]},"489":{"position":[[191,7],[257,7],[625,6]]},"495":{"position":[[33,7],[402,7],[1289,7]]},"497":{"position":[[67,7]]},"596":{"position":[[663,6]]},"633":{"position":[[1151,7],[1278,7],[1402,7],[1512,7],[1536,7],[1899,7]]},"650":{"position":[[1464,7]]},"736":{"position":[[79,6]]},"774":{"position":[[408,8]]},"865":{"position":[[59,7],[144,7]]},"878":{"position":[[59,7],[144,7]]},"880":{"position":[[32,7]]},"883":{"position":[[598,6]]},"977":{"position":[[169,7],[2322,7]]},"1055":{"position":[[1270,8]]},"1067":{"position":[[1099,7],[2718,7]]},"1080":{"position":[[1194,7]]},"1089":{"position":[[1519,7],[1648,7]]},"1108":{"position":[[1979,7]]},"1110":{"position":[[19,7]]},"1120":{"position":[[758,8]]},"1159":{"position":[[128,7],[2453,7]]},"1165":{"position":[[2981,6]]},"1167":{"position":[[4599,7]]},"1325":{"position":[[14,7],[343,7]]},"1335":{"position":[[43,7]]},"1364":{"position":[[531,6]]},"1428":{"position":[[475,7]]},"1699":{"position":[[420,7]]},"1701":{"position":[[40,7]]},"1745":{"position":[[422,7]]},"1747":{"position":[[262,7]]},"1764":{"position":[[27,7]]},"1766":{"position":[[1215,7]]},"1779":{"position":[[769,7]]},"1825":{"position":[[1357,7]]},"1859":{"position":[[585,7]]},"1861":{"position":[[273,7]]},"1921":{"position":[[585,7]]},"1923":{"position":[[273,7]]},"1976":{"position":[[231,8]]},"1982":{"position":[[937,8]]},"1984":{"position":[[547,8]]},"2037":{"position":[[4,7]]},"2047":{"position":[[202,8]]},"2067":{"position":[[143,7]]},"2164":{"position":[[734,7]]},"2233":{"position":[[36,7],[225,7]]},"2315":{"position":[[728,7]]},"2546":{"position":[[488,7]]},"2550":{"position":[[203,7]]},"2560":{"position":[[69,7]]},"2564":{"position":[[247,8]]},"2663":{"position":[[333,6]]},"2675":{"position":[[1283,7]]},"2677":{"position":[[1143,7]]},"2697":{"position":[[45,6],[105,7]]},"2713":{"position":[[141,6]]},"2742":{"position":[[45,6],[105,7]]},"2811":{"position":[[74,6]]},"2832":{"position":[[45,6],[105,7]]},"2858":{"position":[[141,6]]},"2881":{"position":[[143,7]]},"2895":{"position":[[2817,7]]},"2921":{"position":[[45,6],[105,7]]},"2939":{"position":[[629,7]]},"2942":{"position":[[4,7]]},"2944":{"position":[[14,7]]},"2962":{"position":[[141,6]]},"2966":{"position":[[2869,7]]},"2970":{"position":[[309,7]]},"2999":{"position":[[456,6]]},"3033":{"position":[[38,7]]},"3059":{"position":[[734,7]]},"3071":{"position":[[976,8]]},"3084":{"position":[[693,6]]},"3115":{"position":[[171,7]]},"3126":{"position":[[64,7]]},"3135":{"position":[[247,6]]},"3137":{"position":[[266,6]]},"3156":{"position":[[201,7]]},"3158":{"position":[[168,7],[393,7]]},"3160":{"position":[[313,8]]},"3162":{"position":[[81,7]]},"3180":{"position":[[295,7]]},"3182":{"position":[[641,7],[802,7],[1231,7]]},"3186":{"position":[[27,6],[738,6]]},"3193":{"position":[[271,7]]},"3197":{"position":[[667,7],[1102,7],[1440,7]]},"3301":{"position":[[3170,7],[4685,7]]},"3308":{"position":[[495,7]]},"3314":{"position":[[598,6],[647,6],[721,6],[782,6],[988,7]]},"3336":{"position":[[6,8]]},"3343":{"position":[[5,7]]},"3345":{"position":[[74,7]]},"3355":{"position":[[10,7]]},"3395":{"position":[[1105,7]]},"3397":{"position":[[1559,7],[2444,7]]},"3403":{"position":[[56,7]]},"3417":{"position":[[12,6]]},"3419":{"position":[[464,7]]},"3459":{"position":[[655,7]]},"3463":{"position":[[468,7],[639,7],[842,7]]},"3472":{"position":[[13483,6]]},"3479":{"position":[[239,7]]},"3482":{"position":[[593,7],[1172,6]]}}}],["definit",{"_index":1203,"t":{"174":{"position":[[498,12],[1334,12]]},"315":{"position":[[525,11]]},"319":{"position":[[86,11],[728,11]]},"730":{"position":[[652,12]]},"732":{"position":[[21,11],[91,10],[160,10],[193,11],[288,11],[404,10]]},"790":{"position":[[656,10]]},"796":{"position":[[19,10],[219,11],[353,11]]},"798":{"position":[[19,10],[280,11],[410,11]]},"883":{"position":[[1599,11]]},"1150":{"position":[[702,11]]},"1462":{"position":[[454,10]]},"1491":{"position":[[652,12]]},"1493":{"position":[[21,11],[91,10],[160,10],[193,11],[288,11],[404,10]]},"1527":{"position":[[656,10]]},"1533":{"position":[[19,10],[219,11],[353,11]]},"1535":{"position":[[19,10],[280,11],[410,11]]},"1779":{"position":[[928,10]]},"1957":{"position":[[1052,10]]},"1976":{"position":[[412,12],[442,11]]},"1978":{"position":[[87,12]]},"1982":{"position":[[888,11],[1171,11]]},"1984":{"position":[[498,11],[781,11]]},"2043":{"position":[[43,11],[443,11],[525,12],[568,10]]},"2047":{"position":[[135,12]]},"2176":{"position":[[554,10],[1424,12]]},"2306":{"position":[[572,10]]},"2338":{"position":[[528,10]]},"2996":{"position":[[101,11]]},"3316":{"position":[[260,10]]},"3343":{"position":[[60,11],[107,11],[242,11],[283,11]]},"3472":{"position":[[103,11],[153,11],[333,10],[552,11],[12408,11]]},"3477":{"position":[[49,11]]}}}],["definition'",{"_index":3769,"t":{"796":{"position":[[397,12]]},"798":{"position":[[469,12]]},"1533":{"position":[[397,12]]},"1535":{"position":[[469,12]]}}}],["definiton",{"_index":5501,"t":{"1150":{"position":[[590,10]]},"2962":{"position":[[312,9]]},"3472":{"position":[[440,10]]}}}],["defint",{"_index":10242,"t":{"3472":{"position":[[12862,10]]}}}],["defrag",{"_index":3038,"t":{"596":{"position":[[109,11],[460,6],[701,10],[1511,10],[1645,10]]},"604":{"position":[[5236,6]]},"3272":{"position":[[585,13]]}}}],["defrag.servic",{"_index":3042,"t":{"596":{"position":[[307,14]]}}}],["defrag.sh",{"_index":3039,"t":{"596":{"position":[[181,9],[735,9],[3012,9]]}}}],["defrag.tim",{"_index":3044,"t":{"596":{"position":[[379,12]]}}}],["defragment",{"_index":3046,"t":{"596":{"position":[[411,15],[797,15],[1074,15],[1470,15],[1607,15],[1708,15],[2427,15],[2529,15],[2613,15],[2692,15],[2813,15],[2957,15]]},"2405":{"position":[[999,15]]}}}],["degre",{"_index":9512,"t":{"2874":{"position":[[948,7]]}}}],["del",{"_index":5757,"t":{"1161":{"position":[[1705,3]]}}}],["delay",{"_index":8313,"t":{"2150":{"position":[[710,5]]},"2263":{"position":[[181,6]]}}}],["deleg",{"_index":1912,"t":{"290":{"position":[[63,8]]},"298":{"position":[[288,8]]},"1937":{"position":[[65,8]]},"2576":{"position":[[351,10]]},"3236":{"position":[[2692,8]]},"3245":{"position":[[909,8]]},"3247":{"position":[[306,8]]},"3251":{"position":[[4719,9],[4882,9]]}}}],["delegate_to",{"_index":920,"t":{"141":{"position":[[524,12]]},"1699":{"position":[[339,12]]}}}],["delet",{"_index":2316,"t":{"391":{"position":[[811,6],[856,6],[947,6],[1061,6],[1154,8],[1204,6]]},"427":{"position":[[974,7]]},"428":{"position":[[965,8]]},"471":{"position":[[1226,6]]},"499":{"position":[[812,9],[935,9]]},"604":{"position":[[6281,6],[6376,6],[6557,6],[6656,6],[6765,6]]},"627":{"position":[[4243,6],[4318,6]]},"639":{"position":[[938,8]]},"660":{"position":[[3328,6],[3409,7]]},"730":{"position":[[402,6]]},"796":{"position":[[1496,7]]},"819":{"position":[[208,6]]},"821":{"position":[[3319,7],[3427,7],[4768,7],[6085,7]]},"840":{"position":[[144,6]]},"857":{"position":[[146,6]]},"859":{"position":[[468,7],[1612,6],[1875,6],[3513,8],[3625,8],[3728,8],[3840,8],[4509,8],[4621,8],[4724,8],[4836,8],[5505,8],[5605,8],[5717,8],[5832,8]]},"883":{"position":[[733,8],[1336,9]]},"899":{"position":[[790,7]]},"917":{"position":[[484,6]]},"949":{"position":[[401,8],[534,6],[624,7]]},"1043":{"position":[[878,8]]},"1089":{"position":[[596,7]]},"1234":{"position":[[1206,7]]},"1307":{"position":[[10,6]]},"1317":{"position":[[382,6],[396,6],[463,6],[480,6],[531,6],[570,6]]},"1344":{"position":[[454,6]]},"1362":{"position":[[637,6],[1328,6],[1548,6],[2348,6],[2435,6]]},"1386":{"position":[[256,7],[319,6]]},"1460":{"position":[[18,6],[91,6],[180,6]]},"1491":{"position":[[402,6]]},"1509":{"position":[[208,6]]},"1511":{"position":[[3319,7],[3427,7],[4768,7],[6085,7]]},"1533":{"position":[[1496,7]]},"1555":{"position":[[144,6]]},"1589":{"position":[[64,6]]},"1601":{"position":[[146,6]]},"1603":{"position":[[468,7],[1612,6],[1875,6],[3513,8],[3625,8],[3728,8],[3840,8],[4509,8],[4621,8],[4724,8],[4836,8],[5505,8],[5605,8],[5717,8],[5832,8]]},"1621":{"position":[[790,7]]},"1639":{"position":[[484,6]]},"1671":{"position":[[401,8],[534,6],[624,7]]},"1684":{"position":[[602,8]]},"1731":{"position":[[515,6]]},"1756":{"position":[[205,6]]},"1779":{"position":[[6565,8]]},"1847":{"position":[[994,6]]},"1859":{"position":[[766,6],[932,6]]},"1892":{"position":[[1042,6],[1101,6],[1152,6]]},"1904":{"position":[[658,7],[675,8],[771,7],[818,8]]},"1921":{"position":[[766,6],[932,6]]},"2008":{"position":[[1042,6],[1101,6],[1152,6]]},"2020":{"position":[[658,7],[675,8],[771,7],[818,8]]},"2061":{"position":[[216,7]]},"2063":{"position":[[234,7],[341,8],[377,8]]},"2065":{"position":[[222,7]]},"2116":{"position":[[230,7],[370,7]]},"2118":{"position":[[2458,6],[2515,6],[2611,6]]},"2150":{"position":[[703,6],[794,8],[806,7],[837,8],[965,8]]},"2346":{"position":[[790,7]]},"2364":{"position":[[484,6]]},"2396":{"position":[[401,8],[534,6],[624,7]]},"2407":{"position":[[52,6]]},"2502":{"position":[[380,8],[459,6],[559,8]]},"2688":{"position":[[1532,7]]},"3059":{"position":[[803,8]]},"3071":{"position":[[228,8]]},"3274":{"position":[[397,7]]},"3351":{"position":[[113,6]]},"3397":{"position":[[1478,8]]},"3461":{"position":[[523,7]]}}}],["delete_cluster.sh",{"_index":3298,"t":{"627":{"position":[[4833,17]]},"648":{"position":[[512,17]]}}}],["deleted=0",{"_index":2655,"t":{"472":{"position":[[2580,10]]}}}],["deleted_at",{"_index":8699,"t":{"2566":{"position":[[1009,11],[4124,11],[12815,11]]}}}],["deletionpolici",{"_index":2617,"t":{"471":{"position":[[1210,15]]}}}],["deliber",{"_index":1692,"t":{"247":{"position":[[1726,12]]},"2779":{"position":[[81,12]]},"3457":{"position":[[578,10]]}}}],["deliv",{"_index":2133,"t":{"329":{"position":[[228,10]]},"507":{"position":[[749,7]]},"880":{"position":[[699,8]]},"888":{"position":[[2443,10]]},"1564":{"position":[[540,9]]},"2265":{"position":[[557,7]]},"2298":{"position":[[557,7]]},"2326":{"position":[[358,9]]},"2459":{"position":[[62,8]]},"2463":{"position":[[123,8]]},"2723":{"position":[[621,7]]},"2762":{"position":[[634,7]]},"2944":{"position":[[1434,9]]},"3374":{"position":[[143,7]]},"3438":{"position":[[131,7]]}}}],["deliver",{"_index":10257,"t":{"3518":{"position":[[23,11]]}}}],["deliveri",{"_index":1542,"t":{"227":{"position":[[296,9]]},"229":{"position":[[69,8]]},"883":{"position":[[2048,8]]}}}],["delta",{"_index":7264,"t":{"1721":{"position":[[3747,8]]}}}],["delv",{"_index":8576,"t":{"2484":{"position":[[407,7]]}}}],["demand",{"_index":2122,"t":{"327":{"position":[[171,6],[550,7]]},"329":{"position":[[101,6]]},"366":{"position":[[830,7]]},"513":{"position":[[37,6]]},"880":{"position":[[766,6]]},"1951":{"position":[[411,7]]},"2731":{"position":[[271,6]]},"2770":{"position":[[271,6]]},"2860":{"position":[[271,6]]}}}],["demo",{"_index":749,"t":{"114":{"position":[[108,5],[194,5]]},"349":{"position":[[756,4]]},"650":{"position":[[520,4]]},"669":{"position":[[642,4]]},"2407":{"position":[[304,5]]}}}],["democompani",{"_index":3843,"t":{"819":{"position":[[4070,11],[4284,11],[4345,11],[4412,11],[4646,11],[4872,11],[4933,11],[4999,11],[5249,11],[5470,11],[5531,11],[6049,11],[6226,11],[6555,11],[7110,11],[7307,11],[7368,11],[7723,11],[7802,11],[7890,11],[8161,11],[8359,11],[8420,11]]},"821":{"position":[[2049,11],[2094,11],[2186,11],[2286,11],[2432,11],[3039,11],[3113,11],[3187,11],[3260,11],[3369,11],[3435,12],[3490,11],[3591,11],[3738,11],[4375,11],[4450,11],[4525,11],[4599,11],[4709,11],[4776,12],[4831,11],[4932,11],[5079,11],[5692,11],[5767,11],[5842,11],[5916,11],[6026,11],[6093,12]]},"823":{"position":[[258,11]]},"1509":{"position":[[4070,11],[4284,11],[4345,11],[4412,11],[4646,11],[4872,11],[4933,11],[4999,11],[5249,11],[5470,11],[5531,11],[6049,11],[6226,11],[6555,11],[7110,11],[7307,11],[7368,11],[7723,11],[7802,11],[7890,11],[8161,11],[8359,11],[8420,11]]},"1511":{"position":[[2049,11],[2094,11],[2186,11],[2286,11],[2432,11],[3039,11],[3113,11],[3187,11],[3260,11],[3369,11],[3435,12],[3490,11],[3591,11],[3738,11],[4375,11],[4450,11],[4525,11],[4599,11],[4709,11],[4776,12],[4831,11],[4932,11],[5079,11],[5692,11],[5767,11],[5842,11],[5916,11],[6026,11],[6093,12]]},"1513":{"position":[[258,11]]}}}],["democompany.conf",{"_index":3924,"t":{"823":{"position":[[208,16]]},"1513":{"position":[[208,16]]}}}],["demonstr",{"_index":7001,"t":{"1564":{"position":[[87,15]]},"1608":{"position":[[154,12]]},"1863":{"position":[[383,11]]},"1925":{"position":[[383,11]]},"2188":{"position":[[27,11]]},"2281":{"position":[[1004,12]]}}}],["deni",{"_index":10030,"t":{"3270":{"position":[[1367,6],[1433,6],[2061,4]]}}}],["denial",{"_index":10025,"t":{"3266":{"position":[[540,7]]}}}],["denot",{"_index":2669,"t":{"481":{"position":[[123,7]]},"2053":{"position":[[941,6]]},"2499":{"position":[[83,6]]},"2692":{"position":[[293,9]]},"2702":{"position":[[198,7]]},"2747":{"position":[[198,7]]},"2795":{"position":[[1977,6]]}}}],["dep",{"_index":7706,"t":{"1816":{"position":[[559,4]]}}}],["depart",{"_index":1012,"t":{"166":{"position":[[119,12]]},"738":{"position":[[225,11]]}}}],["depend",{"_index":1008,"t":{"162":{"position":[[110,13]]},"227":{"position":[[242,9]]},"268":{"position":[[156,13]]},"284":{"position":[[367,10]]},"337":{"position":[[10,11]]},"487":{"position":[[5671,12]]},"501":{"position":[[462,9]]},"503":{"position":[[794,9]]},"654":{"position":[[434,9]]},"700":{"position":[[97,10]]},"728":{"position":[[281,12]]},"790":{"position":[[546,12]]},"895":{"position":[[202,9]]},"909":{"position":[[1407,9]]},"980":{"position":[[136,7],[308,7]]},"982":{"position":[[714,10]]},"984":{"position":[[462,7],[581,10],[648,7]]},"986":{"position":[[380,7],[430,7]]},"990":{"position":[[482,10]]},"995":{"position":[[296,7],[464,9]]},"1073":{"position":[[369,12]]},"1178":{"position":[[57,7]]},"1184":{"position":[[1531,9]]},"1234":{"position":[[696,9],[1502,9],[2017,9],[2665,9]]},"1242":{"position":[[377,6]]},"1267":{"position":[[35,9]]},"1294":{"position":[[1260,9]]},"1430":{"position":[[590,9]]},"1462":{"position":[[330,9]]},"1471":{"position":[[268,9]]},"1473":{"position":[[567,9]]},"1489":{"position":[[281,12]]},"1527":{"position":[[546,12]]},"1569":{"position":[[1396,9]]},"1617":{"position":[[202,9]]},"1631":{"position":[[1407,9]]},"1684":{"position":[[1326,6],[1645,6],[1966,6],[2297,6],[2619,6],[2941,6],[3262,6],[3578,6]]},"1690":{"position":[[408,7]]},"1731":{"position":[[994,9]]},"1766":{"position":[[360,7]]},"1768":{"position":[[426,6]]},"1777":{"position":[[324,12]]},"1779":{"position":[[2834,12],[3954,7],[5265,12],[5626,9]]},"1816":{"position":[[138,12]]},"1822":{"position":[[1072,9]]},"1827":{"position":[[130,7]]},"1833":{"position":[[1373,7]]},"1882":{"position":[[762,9]]},"1906":{"position":[[113,9]]},"1957":{"position":[[1207,9],[4153,6]]},"1963":{"position":[[351,13]]},"1998":{"position":[[762,9]]},"2022":{"position":[[113,9]]},"2039":{"position":[[354,9]]},"2043":{"position":[[756,9]]},"2053":{"position":[[104,9],[562,7],[850,9]]},"2067":{"position":[[1484,9]]},"2069":{"position":[[157,9]]},"2118":{"position":[[564,12],[796,12]]},"2209":{"position":[[283,13]]},"2342":{"position":[[202,9]]},"2356":{"position":[[1407,9]]},"2629":{"position":[[227,7]]},"2688":{"position":[[428,9]]},"2731":{"position":[[1103,6]]},"2770":{"position":[[1122,6]]},"2813":{"position":[[609,9]]},"2822":{"position":[[38,9],[236,10]]},"2860":{"position":[[1095,6]]},"2892":{"position":[[8,9]]},"2895":{"position":[[1789,6]]},"2951":{"position":[[999,9]]},"3124":{"position":[[565,10]]},"3126":{"position":[[957,6]]},"3135":{"position":[[324,9]]},"3162":{"position":[[510,9]]},"3167":{"position":[[827,10]]},"3197":{"position":[[1113,9]]},"3208":{"position":[[164,12]]},"3210":{"position":[[225,12]]},"3214":{"position":[[323,10],[399,13]]},"3270":{"position":[[1485,7]]},"3276":{"position":[[2459,9]]},"3286":{"position":[[390,9]]},"3297":{"position":[[232,12]]},"3314":{"position":[[83,6],[2988,6]]},"3316":{"position":[[76,10],[158,12],[705,7],[1205,7],[1262,7]]},"3355":{"position":[[214,9]]},"3400":{"position":[[531,9],[1399,9]]}}}],["dependencies.yaml",{"_index":2843,"t":{"491":{"position":[[470,17]]},"495":{"position":[[643,17],[1524,17]]}}}],["dependend",{"_index":9640,"t":{"2962":{"position":[[505,9]]},"2970":{"position":[[177,9]]}}}],["deploy",{"_index":391,"t":{"27":{"position":[[3339,10]]},"34":{"position":[[65,8]]},"73":{"position":[[308,11]]},"77":{"position":[[101,11],[142,11]]},"249":{"position":[[147,10]]},"290":{"position":[[407,7],[486,8]]},"308":{"position":[[105,12]]},"313":{"position":[[357,10]]},"327":{"position":[[278,11]]},"329":{"position":[[164,11]]},"335":{"position":[[657,10],[789,10],[970,10]]},"347":{"position":[[80,6],[644,10]]},"349":{"position":[[41,6]]},"366":{"position":[[978,10]]},"387":{"position":[[84,11],[218,9]]},"389":{"position":[[503,6]]},"417":{"position":[[160,8],[741,11],[936,11],[1160,11]]},"438":{"position":[[38,9]]},"444":{"position":[[89,8]]},"447":{"position":[[147,8],[271,8],[600,8]]},"449":{"position":[[248,8],[375,8],[712,8]]},"456":{"position":[[83,8],[296,8]]},"458":{"position":[[151,8],[165,10],[368,8]]},"460":{"position":[[144,8],[205,8]]},"462":{"position":[[471,10],[964,10],[1264,11],[1639,11]]},"465":{"position":[[302,8]]},"471":{"position":[[154,10],[1054,6]]},"487":{"position":[[686,8],[2616,6],[2858,6],[3941,8],[4080,6],[4211,6],[4652,6],[4856,6],[5297,6],[5429,6],[5500,6],[5598,10],[5651,10]]},"489":{"position":[[743,6]]},"503":{"position":[[58,10]]},"505":{"position":[[414,8],[437,10],[685,8]]},"507":{"position":[[11,6]]},"513":{"position":[[114,6],[1212,9],[1318,9],[1559,8],[1756,8],[1828,6]]},"530":{"position":[[452,8]]},"544":{"position":[[5,6],[26,6]]},"546":{"position":[[5,6],[27,6]]},"548":{"position":[[175,10]]},"550":{"position":[[219,10]]},"590":{"position":[[1932,10],[2542,10]]},"600":{"position":[[19,8]]},"602":{"position":[[122,6]]},"604":{"position":[[546,8],[9954,6],[10379,6],[10985,12],[11091,8]]},"615":{"position":[[540,6]]},"617":{"position":[[475,10],[580,10]]},"627":{"position":[[2419,8],[2782,8],[5554,8]]},"629":{"position":[[113,8]]},"631":{"position":[[651,9]]},"635":{"position":[[289,9],[539,11],[3707,8]]},"637":{"position":[[233,9],[285,6],[346,6]]},"639":{"position":[[65,10],[146,6],[219,6],[286,6],[416,7]]},"641":{"position":[[27,8],[529,9],[791,8],[803,11],[1299,6]]},"644":{"position":[[163,8],[849,9]]},"646":{"position":[[15,6],[146,8],[305,9],[380,11],[415,9],[633,9],[1152,11]]},"656":{"position":[[129,12]]},"660":{"position":[[0,6],[188,6],[209,6],[271,6],[326,6],[3335,10]]},"662":{"position":[[813,11]]},"669":{"position":[[422,10],[626,6]]},"690":{"position":[[166,8]]},"744":{"position":[[62,12],[314,12]]},"766":{"position":[[63,10]]},"876":{"position":[[107,6],[237,9]]},"883":{"position":[[76,11],[234,9],[919,10]]},"888":{"position":[[46,11],[600,10],[1178,10]]},"909":{"position":[[2565,12]]},"938":{"position":[[52,8]]},"954":{"position":[[183,10]]},"956":{"position":[[509,10]]},"986":{"position":[[85,11]]},"990":{"position":[[36,6],[51,10],[96,10]]},"1055":{"position":[[3507,6]]},"1059":{"position":[[487,6]]},"1065":{"position":[[68,6],[115,6],[738,6]]},"1067":{"position":[[951,10],[1365,8],[3150,10]]},"1075":{"position":[[26,8]]},"1108":{"position":[[1632,9],[1963,8],[2049,8]]},"1112":{"position":[[5699,10],[5734,9],[5761,6]]},"1118":{"position":[[136,11]]},"1120":{"position":[[2037,6]]},"1146":{"position":[[210,8]]},"1150":{"position":[[384,10]]},"1184":{"position":[[2513,9]]},"1199":{"position":[[207,8]]},"1219":{"position":[[9,8],[83,6],[127,10],[452,10]]},"1224":{"position":[[188,6],[338,6],[2381,10],[4079,6]]},"1232":{"position":[[16,10],[256,10]]},"1236":{"position":[[30,10]]},"1242":{"position":[[19,9],[276,10],[304,12],[365,11]]},"1244":{"position":[[165,6],[227,8]]},"1246":{"position":[[158,6],[190,6],[237,6]]},"1248":{"position":[[0,6]]},"1250":{"position":[[19,9],[173,8]]},"1252":{"position":[[26,9],[152,6]]},"1254":{"position":[[101,10],[157,6]]},"1258":{"position":[[473,6]]},"1262":{"position":[[62,6],[181,6],[297,6]]},"1284":{"position":[[512,10],[535,10]]},"1286":{"position":[[97,6],[132,8],[467,10],[566,6],[736,11],[911,6],[928,6],[975,6],[1022,6],[1165,6],[2862,9]]},"1288":{"position":[[0,10],[80,8],[157,10],[222,11],[343,9],[403,6],[526,10],[591,10],[668,9]]},"1290":{"position":[[59,8],[247,8]]},"1292":{"position":[[370,8]]},"1294":{"position":[[19,9],[121,10],[284,8]]},"1360":{"position":[[145,6],[203,6],[340,6],[508,6],[557,6],[625,6],[1058,8]]},"1368":{"position":[[437,10]]},"1469":{"position":[[55,10],[253,8]]},"1564":{"position":[[314,8],[510,8]]},"1569":{"position":[[1246,10],[1328,10]]},"1571":{"position":[[1267,6]]},"1582":{"position":[[124,10]]},"1585":{"position":[[2050,8],[2538,9]]},"1591":{"position":[[573,10]]},"1608":{"position":[[913,10]]},"1631":{"position":[[2565,12]]},"1660":{"position":[[52,8]]},"1678":{"position":[[1737,6],[1772,6],[1913,6],[2327,6]]},"1738":{"position":[[119,6]]},"1743":{"position":[[183,6],[450,6]]},"1745":{"position":[[44,11]]},"1749":{"position":[[258,6],[1262,6],[1348,6]]},"1768":{"position":[[83,9]]},"1770":{"position":[[75,10],[579,11]]},"1779":{"position":[[43,6],[2745,11],[3186,6],[3236,6],[3266,6],[3574,6],[3595,10],[3622,10],[3672,6],[3821,6],[3911,9],[4099,9],[4261,10],[4516,11],[4582,10],[5116,10],[5161,6],[5286,8],[5517,11],[5616,9],[5654,10],[5746,6],[5779,10],[6089,10]]},"1781":{"position":[[0,10]]},"1783":{"position":[[18,10]]},"1794":{"position":[[827,9],[914,10]]},"1812":{"position":[[68,10],[149,10],[265,10]]},"1816":{"position":[[378,6],[420,6],[456,6],[483,6],[490,6]]},"1818":{"position":[[77,6],[92,6],[112,6]]},"1845":{"position":[[1498,6]]},"1855":{"position":[[556,7]]},"1917":{"position":[[556,7]]},"1939":{"position":[[16,8],[168,8],[391,8]]},"1941":{"position":[[10,8]]},"1945":{"position":[[28,11]]},"1953":{"position":[[26,9]]},"1959":{"position":[[506,11]]},"1963":{"position":[[472,8]]},"1976":{"position":[[517,11],[650,10]]},"2043":{"position":[[773,10]]},"2071":{"position":[[342,6]]},"2093":{"position":[[502,10],[619,8]]},"2096":{"position":[[78,8],[203,8],[1766,11],[1788,7]]},"2098":{"position":[[89,9],[135,10],[228,10],[1068,9],[1150,10],[1569,10],[2327,10],[2819,11],[2841,7],[3096,11],[3384,10]]},"2100":{"position":[[388,6],[905,6],[1221,12]]},"2110":{"position":[[387,6]]},"2116":{"position":[[51,6]]},"2118":{"position":[[372,10]]},"2120":{"position":[[307,8]]},"2122":{"position":[[33,9],[191,10],[410,9]]},"2132":{"position":[[37,6]]},"2138":{"position":[[153,6],[295,6],[432,6]]},"2146":{"position":[[289,11]]},"2154":{"position":[[597,10],[904,10]]},"2158":{"position":[[235,11]]},"2164":{"position":[[121,11],[575,10]]},"2176":{"position":[[203,10],[981,12]]},"2190":{"position":[[254,8]]},"2212":{"position":[[354,10]]},"2222":{"position":[[17,11]]},"2226":{"position":[[37,8]]},"2229":{"position":[[387,10]]},"2235":{"position":[[219,8]]},"2243":{"position":[[70,10]]},"2248":{"position":[[1133,10],[1185,10]]},"2250":{"position":[[161,10]]},"2253":{"position":[[303,6]]},"2255":{"position":[[399,10]]},"2276":{"position":[[64,10]]},"2283":{"position":[[1069,8]]},"2292":{"position":[[173,12]]},"2312":{"position":[[382,11]]},"2315":{"position":[[205,10]]},"2326":{"position":[[407,12]]},"2356":{"position":[[2565,12]]},"2385":{"position":[[52,8]]},"2463":{"position":[[429,10]]},"2468":{"position":[[119,7]]},"2476":{"position":[[86,7]]},"2482":{"position":[[211,9]]},"2504":{"position":[[176,10],[795,12]]},"2506":{"position":[[313,12]]},"2548":{"position":[[231,12]]},"2550":{"position":[[494,10]]},"2592":{"position":[[113,10]]},"2617":{"position":[[163,8]]},"2665":{"position":[[512,10]]},"2671":{"position":[[465,10]]},"2675":{"position":[[164,9]]},"2750":{"position":[[1444,9]]},"2795":{"position":[[166,8]]},"2801":{"position":[[306,10]]},"2960":{"position":[[387,11]]},"2970":{"position":[[320,8]]},"2975":{"position":[[166,8]]},"3005":{"position":[[122,12]]},"3007":{"position":[[72,12]]},"3011":{"position":[[950,6]]},"3029":{"position":[[18,10]]},"3033":{"position":[[62,11],[169,11],[301,9]]},"3082":{"position":[[176,12]]},"3103":{"position":[[1294,11],[1342,10]]},"3154":{"position":[[293,6]]},"3160":{"position":[[2683,10],[2715,6]]},"3162":{"position":[[128,11]]},"3180":{"position":[[303,7]]},"3193":{"position":[[279,7]]},"3218":{"position":[[750,11]]},"3220":{"position":[[221,11]]},"3227":{"position":[[82,6]]},"3236":{"position":[[1807,7]]},"3249":{"position":[[506,8]]},"3251":{"position":[[2618,11]]},"3253":{"position":[[31,10]]},"3255":{"position":[[811,7]]},"3276":{"position":[[518,11],[2187,8]]},"3280":{"position":[[588,8],[682,11]]},"3301":{"position":[[6928,10]]},"3395":{"position":[[1579,10]]},"3397":{"position":[[781,10],[795,8],[899,8],[939,8],[982,8],[1014,11],[1066,8],[1110,8],[1155,8],[1202,8],[1247,8],[1298,8],[1355,8],[1403,8],[1766,8],[2075,8],[2098,7],[2288,8],[2320,6]]},"3461":{"position":[[16,7]]},"3518":{"position":[[171,8]]}}}],["deploy,st",{"_index":3407,"t":{"641":{"position":[[847,10]]}}}],["deploy.sh",{"_index":7020,"t":{"1571":{"position":[[1215,9],[1821,9]]},"1587":{"position":[[1095,9]]},"1591":{"position":[[391,9]]}}}],["deploy_cert_manag",{"_index":2823,"t":{"487":{"position":[[5225,19],[5245,19]]}}}],["deploy_cindercsi",{"_index":2786,"t":{"487":{"position":[[2815,16],[2832,16]]}}}],["deploy_flux",{"_index":2826,"t":{"487":{"position":[[5377,11],[5389,11]]}}}],["deploy_gateway_api",{"_index":2817,"t":{"487":{"position":[[4790,18],[4809,18]]},"637":{"position":[[104,18]]}}}],["deploy_harbor",{"_index":2828,"t":{"487":{"position":[[5459,13]]},"639":{"position":[[256,13]]}}}],["deploy_harbor.sh",{"_index":2829,"t":{"487":{"position":[[5483,16]]}}}],["deploy_harbor=tru",{"_index":3399,"t":{"641":{"position":[[357,18]]}}}],["deploy_metr",{"_index":2804,"t":{"487":{"position":[[4024,14],[4039,14]]}}}],["deploy_monitor",{"_index":7679,"t":{"1808":{"position":[[272,17]]}}}],["deploy_nginx_ingress",{"_index":2806,"t":{"487":{"position":[[4137,20],[4158,20]]},"505":{"position":[[705,21]]}}}],["deploy_nginx_ingress=tru",{"_index":3379,"t":{"635":{"position":[[3755,26]]}}}],["deploy_occm",{"_index":2783,"t":{"487":{"position":[[2583,11],[2595,11]]}}}],["deploy_xxx",{"_index":3283,"t":{"627":{"position":[[1462,10]]}}}],["deployment.app",{"_index":3552,"t":{"660":{"position":[[3376,15]]}}}],["deployment.apps/harbor",{"_index":3408,"t":{"641":{"position":[[894,22],[934,22],[978,22],[1024,22],[1065,22],[1107,22]]}}}],["depoy",{"_index":6088,"t":{"1244":{"position":[[26,8]]}}}],["deprec",{"_index":3506,"t":{"656":{"position":[[87,10]]},"1674":{"position":[[400,13]]},"1684":{"position":[[2086,13],[2109,12]]},"2156":{"position":[[153,10]]},"2255":{"position":[[39,11]]},"2259":{"position":[[0,12],[37,11],[68,10],[141,10],[217,10],[373,10]]},"2292":{"position":[[0,12],[37,11],[87,10],[562,10],[859,11],[1016,10]]},"2324":{"position":[[44,11],[96,11],[200,11],[263,10],[885,10]]},"2417":{"position":[[143,10]]},"2420":{"position":[[44,11],[255,10]]},"2482":{"position":[[269,11],[350,12]]},"2497":{"position":[[697,12]]},"2522":{"position":[[627,11]]},"2524":{"position":[[345,10]]},"2526":{"position":[[439,10],[522,11]]},"2528":{"position":[[30,10]]},"2530":{"position":[[337,10]]},"2532":{"position":[[30,10]]},"2534":{"position":[[125,10]]},"2536":{"position":[[388,10],[420,10],[474,10]]},"2538":{"position":[[25,10]]},"2540":{"position":[[609,10]]},"2542":{"position":[[25,10]]},"2544":{"position":[[446,10],[529,11]]},"2546":{"position":[[547,10]]},"2548":{"position":[[540,10]]},"2550":{"position":[[561,10]]},"2552":{"position":[[30,10]]},"2554":{"position":[[30,10]]},"2556":{"position":[[30,10]]},"2558":{"position":[[30,10]]},"2572":{"position":[[30,10]]},"2574":{"position":[[419,10],[502,11]]},"2576":{"position":[[700,10]]},"2578":{"position":[[30,10]]},"2580":{"position":[[30,10]]},"2582":{"position":[[30,10]]},"2584":{"position":[[30,10],[62,10]]},"2586":{"position":[[400,10]]},"2588":{"position":[[30,10]]},"2590":{"position":[[30,10]]},"2592":{"position":[[402,10],[485,11]]},"2594":{"position":[[30,10]]},"2596":{"position":[[30,10]]},"2598":{"position":[[30,10]]},"2600":{"position":[[30,10]]},"2602":{"position":[[434,10],[517,11]]},"2604":{"position":[[30,10]]},"2606":{"position":[[30,10]]},"2608":{"position":[[30,10]]},"2610":{"position":[[30,10]]},"2612":{"position":[[30,10]]},"2614":{"position":[[30,10]]},"2625":{"position":[[1886,11],[2137,10],[2203,11],[2517,10]]},"2629":{"position":[[93,11]]},"2631":{"position":[[1980,11]]},"2635":{"position":[[719,11]]},"2637":{"position":[[45,11],[191,11]]},"2651":{"position":[[521,10]]},"2653":{"position":[[30,10]]},"2809":{"position":[[686,10]]},"2817":{"position":[[105,11]]},"2895":{"position":[[3356,11],[3862,11]]},"3276":{"position":[[1492,10]]},"3301":{"position":[[7306,11],[7595,11]]},"3429":{"position":[[144,10],[215,10],[272,10]]},"3431":{"position":[[144,10],[241,10]]},"3518":{"position":[[526,10],[615,11]]}}}],["deprecated_at",{"_index":9018,"t":{"2625":{"position":[[2101,13]]},"2637":{"position":[[129,13]]},"2809":{"position":[[302,13],[506,13],[717,15]]},"2815":{"position":[[1329,14],[1483,14]]}}}],["depric",{"_index":975,"t":{"151":{"position":[[249,11]]}}}],["depth",{"_index":8577,"t":{"2484":{"position":[[434,6]]},"3224":{"position":[[1356,5]]},"3270":{"position":[[2335,5]]},"3400":{"position":[[576,5]]}}}],["dequeu",{"_index":7446,"t":{"1758":{"position":[[690,7],[809,7]]},"3270":{"position":[[2079,7]]}}}],["deriv",{"_index":625,"t":{"101":{"position":[[235,7]]},"168":{"position":[[772,7]]},"172":{"position":[[67,7],[260,7]]},"174":{"position":[[25,7],[233,7],[636,7],[961,7]]},"178":{"position":[[1220,7]]},"619":{"position":[[296,7]]},"2700":{"position":[[699,6]]},"2745":{"position":[[699,6]]},"3053":{"position":[[277,7]]},"3059":{"position":[[915,7]]}}}],["descib",{"_index":9644,"t":{"2966":{"position":[[384,8]]}}}],["describ",{"_index":1607,"t":{"242":{"position":[[137,9],[424,9]]},"263":{"position":[[513,10]]},"280":{"position":[[772,9]]},"290":{"position":[[626,8]]},"296":{"position":[[271,8]]},"302":{"position":[[1303,9]]},"436":{"position":[[10,9]]},"444":{"position":[[18,9]]},"460":{"position":[[264,10]]},"462":{"position":[[485,9],[745,9],[881,9]]},"493":{"position":[[13,9]]},"495":{"position":[[13,9]]},"590":{"position":[[372,8],[531,8],[744,8],[1081,8],[1294,8]]},"604":{"position":[[4539,9],[8329,9]]},"609":{"position":[[1056,8]]},"633":{"position":[[263,9]]},"635":{"position":[[324,9]]},"648":{"position":[[241,8]]},"895":{"position":[[1720,9],[2036,9]]},"909":{"position":[[513,9]]},"934":{"position":[[443,9],[2027,9]]},"1073":{"position":[[68,9]]},"1080":{"position":[[1895,9]]},"1089":{"position":[[848,9]]},"1112":{"position":[[1022,9]]},"1188":{"position":[[447,9]]},"1219":{"position":[[242,9]]},"1232":{"position":[[686,9]]},"1234":{"position":[[59,9]]},"1236":{"position":[[145,9]]},"1288":{"position":[[122,9]]},"1473":{"position":[[227,9]]},"1578":{"position":[[27,9]]},"1594":{"position":[[309,9]]},"1617":{"position":[[1720,9],[2036,9]]},"1631":{"position":[[513,9]]},"1656":{"position":[[443,9],[2027,9]]},"1684":{"position":[[504,9],[1044,10]]},"1690":{"position":[[180,9]]},"1723":{"position":[[29,8]]},"1773":{"position":[[263,8]]},"1779":{"position":[[13,9]]},"1808":{"position":[[13,9]]},"1825":{"position":[[251,9]]},"1874":{"position":[[39,9]]},"1876":{"position":[[260,8]]},"1880":{"position":[[938,9]]},"1890":{"position":[[529,9]]},"1892":{"position":[[207,9],[1357,9]]},"1990":{"position":[[39,9]]},"1992":{"position":[[260,8]]},"1996":{"position":[[938,9]]},"2006":{"position":[[529,9]]},"2008":{"position":[[207,9],[1357,9]]},"2041":{"position":[[238,8],[414,9],[507,9]]},"2043":{"position":[[58,9]]},"2049":{"position":[[23,8]]},"2059":{"position":[[23,8]]},"2067":{"position":[[1576,9]]},"2069":{"position":[[249,9]]},"2342":{"position":[[1720,9],[2036,9]]},"2356":{"position":[[513,9]]},"2381":{"position":[[443,9],[2027,9]]},"2562":{"position":[[36,9]]},"2619":{"position":[[171,9]]},"2623":{"position":[[38,9],[153,9]]},"2625":{"position":[[1531,9]]},"2627":{"position":[[227,9],[523,9],[1368,10],[1635,9],[1916,10],[1966,10]]},"2665":{"position":[[495,8]]},"2705":{"position":[[69,8]]},"2750":{"position":[[69,8]]},"2795":{"position":[[1943,9]]},"2803":{"position":[[175,9]]},"2805":{"position":[[442,10]]},"2892":{"position":[[138,9]]},"2895":{"position":[[568,9]]},"2897":{"position":[[516,10]]},"2899":{"position":[[465,8],[809,9]]},"2915":{"position":[[74,9]]},"2966":{"position":[[4369,9]]},"2970":{"position":[[144,8],[205,8],[491,9]]},"2981":{"position":[[114,9]]},"2983":{"position":[[488,9]]},"3039":{"position":[[145,10],[235,9]]},"3050":{"position":[[302,9]]},"3059":{"position":[[561,9]]},"3071":{"position":[[1343,9],[1652,9]]},"3128":{"position":[[907,9]]},"3145":{"position":[[23,8]]},"3160":{"position":[[103,9]]},"3167":{"position":[[13,8]]},"3175":{"position":[[148,8]]},"3182":{"position":[[2009,9]]},"3197":{"position":[[610,9],[715,9]]},"3276":{"position":[[1972,9]]},"3299":{"position":[[360,9],[1471,9],[1607,9],[1877,9],[2910,9],[4053,9]]},"3338":{"position":[[171,9]]},"3343":{"position":[[1192,9]]},"3423":{"position":[[42,9]]},"3468":{"position":[[13,9]]}}}],["descript",{"_index":266,"t":{"25":{"position":[[210,11]]},"27":{"position":[[49,11],[1693,11]]},"30":{"position":[[69,11]]},"32":{"position":[[49,11]]},"91":{"position":[[173,11]]},"97":{"position":[[0,11]]},"114":{"position":[[226,11]]},"143":{"position":[[317,12]]},"321":{"position":[[758,11]]},"323":{"position":[[515,12]]},"325":{"position":[[359,12],[1189,11],[2593,12]]},"654":{"position":[[388,12]]},"730":{"position":[[2080,11]]},"780":{"position":[[8,11]]},"1008":{"position":[[86,11]]},"1033":{"position":[[224,11]]},"1041":{"position":[[18,11]]},"1055":{"position":[[705,11]]},"1071":{"position":[[10,11]]},"1073":{"position":[[263,11]]},"1089":{"position":[[1489,11]]},"1150":{"position":[[12716,11],[12882,11]]},"1163":{"position":[[18,11]]},"1226":{"position":[[287,11]]},"1256":{"position":[[2553,11]]},"1375":{"position":[[59,11]]},"1491":{"position":[[2080,11]]},"1585":{"position":[[783,11]]},"1608":{"position":[[209,11]]},"1743":{"position":[[898,12]]},"1798":{"position":[[7,11]]},"1800":{"position":[[7,11]]},"1808":{"position":[[849,11],[1110,11]]},"1818":{"position":[[57,11]]},"1845":{"position":[[872,11]]},"1955":{"position":[[55,11]]},"2265":{"position":[[487,12]]},"2281":{"position":[[671,12],[706,11],[1109,12],[1268,11]]},"2298":{"position":[[487,12]]},"2407":{"position":[[157,11]]},"2520":{"position":[[113,11]]},"2526":{"position":[[486,11]]},"2544":{"position":[[493,11]]},"2566":{"position":[[3433,12],[10649,12]]},"2574":{"position":[[466,11]]},"2592":{"position":[[449,11]]},"2602":{"position":[[481,11]]},"2625":{"position":[[1752,11]]},"2673":{"position":[[1391,11]]},"2700":{"position":[[127,12],[145,11]]},"2731":{"position":[[544,12]]},"2745":{"position":[[127,12],[145,11]]},"2770":{"position":[[544,12]]},"2783":{"position":[[196,12],[715,11]]},"2805":{"position":[[151,11],[536,11]]},"2807":{"position":[[501,11]]},"2809":{"position":[[9,11]]},"2811":{"position":[[142,11]]},"2813":{"position":[[68,11],[690,11]]},"2835":{"position":[[68,12],[86,11]]},"2860":{"position":[[506,11]]},"2890":{"position":[[487,11]]},"2966":{"position":[[969,11],[4692,11]]},"2983":{"position":[[9,11]]},"2985":{"position":[[9,11]]},"3029":{"position":[[367,11]]},"3031":{"position":[[104,11],[215,11]]},"3039":{"position":[[260,11]]},"3042":{"position":[[227,11],[815,11]]},"3044":{"position":[[524,11]]},"3046":{"position":[[665,11]]},"3050":{"position":[[149,11]]},"3059":{"position":[[677,11],[942,11]]},"3325":{"position":[[3593,11]]},"3475":{"position":[[0,12]]},"3477":{"position":[[0,12]]},"3489":{"position":[[31,11]]},"3502":{"position":[[31,11]]},"3508":{"position":[[19,11],[50,11]]},"3518":{"position":[[579,11]]}}}],["descriptor",{"_index":7287,"t":{"1728":{"position":[[299,12]]},"2805":{"position":[[430,11],[565,10],[698,11],[878,10]]},"2809":{"position":[[154,11]]},"2811":{"position":[[508,10]]},"2813":{"position":[[47,11]]}}}],["design",{"_index":598,"t":{"83":{"position":[[36,6]]},"189":{"position":[[18,8]]},"191":{"position":[[501,7]]},"193":{"position":[[749,6]]},"240":{"position":[[160,7],[189,9]]},"284":{"position":[[9,6]]},"333":{"position":[[256,8]]},"335":{"position":[[1098,8]]},"337":{"position":[[34,6]]},"444":{"position":[[244,7]]},"472":{"position":[[233,7]]},"586":{"position":[[288,8]]},"742":{"position":[[560,9]]},"880":{"position":[[57,8],[151,8],[386,8]]},"888":{"position":[[292,8],[472,7],[1876,6]]},"905":{"position":[[1916,8]]},"970":{"position":[[67,6],[149,6]]},"977":{"position":[[101,8]]},"990":{"position":[[71,10]]},"1132":{"position":[[0,9],[22,9],[52,9]]},"1294":{"position":[[637,9],[667,9],[689,9]]},"1311":{"position":[[530,9]]},"1627":{"position":[[1916,8]]},"1814":{"position":[[360,9]]},"1822":{"position":[[383,9],[413,9],[446,9]]},"2079":{"position":[[489,8]]},"2096":{"position":[[1368,8]]},"2126":{"position":[[36,8]]},"2190":{"position":[[720,10]]},"2212":{"position":[[870,6]]},"2237":{"position":[[112,9]]},"2267":{"position":[[112,9]]},"2300":{"position":[[112,9]]},"2352":{"position":[[1916,8]]},"2426":{"position":[[541,8]]},"2627":{"position":[[664,6]]},"2631":{"position":[[1167,6]]},"2656":{"position":[[43,6],[76,6],[176,6]]},"2660":{"position":[[5,6],[194,6]]},"2663":{"position":[[102,8]]},"2711":{"position":[[834,6]]},"2807":{"position":[[308,11]]},"2856":{"position":[[812,6]]},"2933":{"position":[[237,6]]},"3003":{"position":[[16,7],[148,7]]},"3101":{"position":[[329,6]]},"3158":{"position":[[507,6]]},"3197":{"position":[[5,6]]},"3204":{"position":[[47,6]]},"3218":{"position":[[141,7]]},"3224":{"position":[[1486,6]]},"3236":{"position":[[1018,6]]},"3251":{"position":[[1525,6]]},"3268":{"position":[[48,6]]},"3299":{"position":[[1514,6],[2953,6],[4090,6],[5162,6]]},"3301":{"position":[[5022,7]]},"3312":{"position":[[411,6]]},"3314":{"position":[[61,6]]},"3340":{"position":[[109,6]]},"3353":{"position":[[118,8]]},"3397":{"position":[[492,8]]},"3472":{"position":[[14527,11]]},"3482":{"position":[[1884,11]]}}}],["designate.services.a.regiocloud.tech",{"_index":5787,"t":{"1161":{"position":[[3070,36]]}}}],["designate_api_external_back",{"_index":5788,"t":{"1161":{"position":[[3119,27]]}}}],["designate_api_work",{"_index":5919,"t":{"1169":{"position":[[920,21]]}}}],["designate_central_work",{"_index":5922,"t":{"1169":{"position":[[994,25]]}}}],["designate_mdns_work",{"_index":5924,"t":{"1169":{"position":[[1043,22]]}}}],["designate_producer_work",{"_index":5921,"t":{"1169":{"position":[[967,26]]}}}],["designate_public_endpoint",{"_index":5736,"t":{"1161":{"position":[[506,26]]}}}],["designate_sink_work",{"_index":5923,"t":{"1169":{"position":[[1020,22]]}}}],["designate_worker_work",{"_index":5920,"t":{"1169":{"position":[[942,24]]}}}],["designatecli",{"_index":130,"t":{"10":{"position":[[1087,15]]},"905":{"position":[[208,15]]},"1627":{"position":[[208,15]]},"2352":{"position":[[208,15]]}}}],["desir",{"_index":578,"t":{"79":{"position":[[280,10]]},"195":{"position":[[42,7]]},"413":{"position":[[68,7]]},"469":{"position":[[274,7]]},"883":{"position":[[609,7]]},"899":{"position":[[252,10]]},"1621":{"position":[[252,10]]},"1861":{"position":[[192,7]]},"1908":{"position":[[798,7],[2842,7]]},"1913":{"position":[[299,7]]},"1923":{"position":[[192,7]]},"2024":{"position":[[798,7],[2842,7]]},"2029":{"position":[[299,7]]},"2053":{"position":[[867,7]]},"2346":{"position":[[252,10]]},"2688":{"position":[[917,7]]},"2711":{"position":[[1191,7]]},"2813":{"position":[[1224,8]]},"2856":{"position":[[1168,7]]},"2872":{"position":[[1064,8]]},"2874":{"position":[[1035,8]]},"2933":{"position":[[720,7]]},"2942":{"position":[[522,8]]},"2944":{"position":[[175,9]]},"2951":{"position":[[589,10]]},"2990":{"position":[[608,8]]},"3156":{"position":[[184,7]]},"3160":{"position":[[2259,9]]},"3227":{"position":[[501,9]]},"3301":{"position":[[550,7],[952,9],[994,7]]},"3314":{"position":[[3462,7]]},"3400":{"position":[[700,7]]},"3461":{"position":[[156,7],[234,8]]},"3482":{"position":[[1779,7],[2342,7]]}}}],["desktop",{"_index":988,"t":{"158":{"position":[[182,7],[247,7]]},"251":{"position":[[15,7]]},"1226":{"position":[[663,7],[688,7],[705,7],[739,7]]},"1234":{"position":[[3110,7]]}}}],["despit",{"_index":1149,"t":{"170":{"position":[[1895,7]]},"596":{"position":[[2443,7]]},"932":{"position":[[2110,8],[2749,7]]},"1654":{"position":[[2110,8],[2749,7]]},"2379":{"position":[[2110,8],[2749,7]]},"2705":{"position":[[1367,7]]},"2735":{"position":[[852,8]]},"2750":{"position":[[1601,7]]},"2774":{"position":[[854,8]]}}}],["dest",{"_index":901,"t":{"139":{"position":[[507,5]]},"141":{"position":[[456,5]]},"1167":{"position":[[574,5],[4274,7],[4911,7]]},"1697":{"position":[[508,5]]},"1699":{"position":[[271,5]]},"1749":{"position":[[321,5]]}}}],["destin",{"_index":5897,"t":{"1167":{"position":[[3521,14]]},"1829":{"position":[[22,12],[100,11],[381,11]]}}}],["destination_ip",{"_index":8771,"t":{"2566":{"position":[[4431,15]]}}}],["destroy",{"_index":6851,"t":{"1415":{"position":[[18,7]]},"1417":{"position":[[18,7]]},"1419":{"position":[[18,7]]},"1569":{"position":[[756,9]]},"1816":{"position":[[63,7]]},"2118":{"position":[[2374,10]]}}}],["detach",{"_index":2986,"t":{"572":{"position":[[5,6],[56,6]]},"1890":{"position":[[155,8]]},"2006":{"position":[[155,8]]}}}],["detail",{"_index":474,"t":{"60":{"position":[[151,8]]},"65":{"position":[[158,8]]},"67":{"position":[[245,8]]},"170":{"position":[[1535,8]]},"292":{"position":[[126,7]]},"333":{"position":[[515,8]]},"366":{"position":[[667,8]]},"385":{"position":[[140,8]]},"421":{"position":[[714,7],[1578,8]]},"436":{"position":[[1501,8]]},"447":{"position":[[820,7]]},"467":{"position":[[1146,9]]},"471":{"position":[[435,7]]},"487":{"position":[[3914,8],[5934,8]]},"489":{"position":[[607,7]]},"523":{"position":[[166,8]]},"598":{"position":[[982,8]]},"609":{"position":[[2754,7],[5454,7]]},"617":{"position":[[1392,8]]},"641":{"position":[[1467,8]]},"786":{"position":[[1081,8]]},"895":{"position":[[1744,6]]},"947":{"position":[[157,7],[495,8]]},"1012":{"position":[[460,7]]},"1059":{"position":[[197,7]]},"1061":{"position":[[855,8]]},"1063":{"position":[[472,6]]},"1067":{"position":[[2446,7]]},"1112":{"position":[[97,7],[5723,7]]},"1144":{"position":[[130,7]]},"1184":{"position":[[261,7]]},"1256":{"position":[[2424,7]]},"1317":{"position":[[97,9]]},"1400":{"position":[[115,8],[155,6],[273,8],[313,6]]},"1448":{"position":[[53,6]]},"1450":{"position":[[19,6]]},"1477":{"position":[[75,7],[354,7]]},"1523":{"position":[[1081,8]]},"1594":{"position":[[548,6]]},"1617":{"position":[[1744,6]]},"1669":{"position":[[157,7],[495,8]]},"1684":{"position":[[973,8],[1094,7],[1437,8],[1756,8],[2077,8],[2408,8],[2730,8],[3052,8],[3373,8],[3689,8]]},"1728":{"position":[[657,7],[764,6]]},"1777":{"position":[[233,8]]},"1779":{"position":[[1140,8],[1771,7]]},"1791":{"position":[[1078,8]]},"1859":{"position":[[850,7]]},"1872":{"position":[[596,7]]},"1880":{"position":[[449,8]]},"1882":{"position":[[942,8]]},"1921":{"position":[[850,7]]},"1941":{"position":[[88,7]]},"1943":{"position":[[313,8]]},"1945":{"position":[[177,7]]},"1955":{"position":[[37,8]]},"1957":{"position":[[793,7],[1793,7],[2507,7],[2858,7],[4145,7]]},"1974":{"position":[[290,8],[390,8]]},"1988":{"position":[[596,7]]},"1996":{"position":[[449,8]]},"1998":{"position":[[942,8]]},"2043":{"position":[[734,7]]},"2051":{"position":[[237,8]]},"2077":{"position":[[412,8]]},"2081":{"position":[[420,8]]},"2098":{"position":[[2629,8]]},"2118":{"position":[[1441,8]]},"2134":{"position":[[15,8]]},"2154":{"position":[[1056,7]]},"2200":{"position":[[109,7]]},"2212":{"position":[[778,8]]},"2214":{"position":[[641,8]]},"2220":{"position":[[84,7]]},"2229":{"position":[[893,8]]},"2233":{"position":[[449,9]]},"2245":{"position":[[612,8]]},"2253":{"position":[[225,8]]},"2278":{"position":[[350,8]]},"2286":{"position":[[111,8]]},"2306":{"position":[[93,8]]},"2342":{"position":[[1744,6]]},"2394":{"position":[[157,7],[495,8]]},"2424":{"position":[[250,8]]},"2476":{"position":[[674,6]]},"2514":{"position":[[785,7]]},"2516":{"position":[[71,8]]},"2518":{"position":[[239,7]]},"2530":{"position":[[165,9]]},"2546":{"position":[[304,8]]},"2550":{"position":[[364,6]]},"2566":{"position":[[14627,7]]},"2627":{"position":[[185,7],[729,7],[881,9]]},"2675":{"position":[[559,8]]},"2684":{"position":[[199,7]]},"2688":{"position":[[1074,7]]},"2692":{"position":[[251,7]]},"2697":{"position":[[559,7]]},"2700":{"position":[[799,8],[824,8]]},"2713":{"position":[[845,7]]},"2719":{"position":[[585,7],[1487,8]]},"2725":{"position":[[5,7],[26,7]]},"2731":{"position":[[81,7],[331,8],[573,8],[1294,7]]},"2742":{"position":[[458,7]]},"2745":{"position":[[799,8],[824,8]]},"2756":{"position":[[1313,7]]},"2758":{"position":[[583,7],[1488,8]]},"2764":{"position":[[49,7]]},"2766":{"position":[[55,7]]},"2770":{"position":[[81,7],[331,8],[573,8],[1317,7]]},"2783":{"position":[[257,8]]},"2832":{"position":[[559,7]]},"2850":{"position":[[5,7],[26,7]]},"2858":{"position":[[683,7]]},"2860":{"position":[[81,7],[331,8],[534,8],[1290,7]]},"2890":{"position":[[188,8]]},"2966":{"position":[[351,7]]},"3027":{"position":[[39,6]]},"3050":{"position":[[507,8]]},"3059":{"position":[[579,6]]},"3132":{"position":[[76,7]]},"3245":{"position":[[1415,7]]},"3270":{"position":[[993,7],[1535,7]]},"3438":{"position":[[452,7]]},"3479":{"position":[[315,8]]}}}],["detect",{"_index":2703,"t":{"485":{"position":[[328,8]]},"899":{"position":[[987,6]]},"1585":{"position":[[1606,9]]},"1621":{"position":[[987,6]]},"2077":{"position":[[192,10]]},"2079":{"position":[[79,9]]},"2315":{"position":[[1000,9]]},"2346":{"position":[[987,6]]},"2786":{"position":[[28,8]]},"2911":{"position":[[66,8],[457,8]]},"2913":{"position":[[28,8]]},"3105":{"position":[[411,6]]},"3178":{"position":[[305,9]]},"3191":{"position":[[298,9]]},"3400":{"position":[[1352,9]]},"3413":{"position":[[345,6]]}}}],["determin",{"_index":731,"t":{"109":{"position":[[0,9]]},"191":{"position":[[426,9]]},"202":{"position":[[16,9]]},"227":{"position":[[408,9]]},"235":{"position":[[728,11]]},"472":{"position":[[2033,9]]},"742":{"position":[[434,9]]},"1319":{"position":[[457,9]]},"1728":{"position":[[1018,11],[1172,9]]},"1872":{"position":[[576,11]]},"1908":{"position":[[2031,10],[2554,9]]},"1913":{"position":[[626,9]]},"1980":{"position":[[200,10],[493,11]]},"1988":{"position":[[576,11]]},"2024":{"position":[[2031,10],[2554,9]]},"2029":{"position":[[626,9]]},"2196":{"position":[[405,10]]},"2792":{"position":[[6,11]]},"2911":{"position":[[322,10]]},"3021":{"position":[[145,10]]},"3201":{"position":[[115,10]]},"3222":{"position":[[195,10]]},"3224":{"position":[[1423,9]]},"3236":{"position":[[2945,9]]}}}],["determinist",{"_index":6042,"t":{"1226":{"position":[[1152,13],[1283,13]]}}}],["detour",{"_index":7935,"t":{"1892":{"position":[[151,6]]},"2008":{"position":[[151,6]]}}}],["detriment",{"_index":3251,"t":{"615":{"position":[[343,11]]}}}],["dev",{"_index":105,"t":{"10":{"position":[[553,3],[646,3]]},"27":{"position":[[306,3],[885,3],[965,3],[1045,3],[1226,3],[1325,3],[1497,3]]},"407":{"position":[[111,3]]},"432":{"position":[[111,3]]},"728":{"position":[[323,3]]},"790":{"position":[[492,4]]},"810":{"position":[[136,3],[153,3]]},"1112":{"position":[[1178,5]]},"1489":{"position":[[323,3]]},"1500":{"position":[[136,3],[153,3]]},"1527":{"position":[[492,4]]},"1585":{"position":[[1426,3]]},"1728":{"position":[[542,3]]},"2520":{"position":[[173,3]]}}}],["dev/cirros/releases/download/0.6.0/cirro",{"_index":3756,"t":{"790":{"position":[[1150,41]]},"1527":{"position":[[1150,41]]}}}],["dev/hwrng",{"_index":9495,"t":{"2872":{"position":[[702,11],[862,11]]},"2874":{"position":[[518,11]]}}}],["dev/loop0p1",{"_index":7783,"t":{"1841":{"position":[[626,12]]}}}],["dev/mapper/decrypted_imag",{"_index":7988,"t":{"1913":{"position":[[1583,28],[1823,27]]},"2029":{"position":[[1583,28],[1823,27]]}}}],["dev/mapper/vg00",{"_index":7731,"t":{"1833":{"position":[[207,16],[260,16],[308,16],[356,16],[402,16]]}}}],["dev/mapper/vgdata",{"_index":7741,"t":{"1833":{"position":[[443,18]]}}}],["dev/nul",{"_index":4446,"t":{"913":{"position":[[599,10]]},"1635":{"position":[[599,10]]},"2360":{"position":[[599,10]]}}}],["dev/nvme0n1",{"_index":6999,"t":{"1562":{"position":[[552,13]]},"1569":{"position":[[484,13]]}}}],["dev/nvmexni",{"_index":6848,"t":{"1411":{"position":[[40,12]]},"1413":{"position":[[16,12]]},"1415":{"position":[[76,12]]},"1417":{"position":[[68,12],[94,12],[125,12]]}}}],["dev/random",{"_index":9499,"t":{"2872":{"position":[[1203,11]]},"2874":{"position":[[405,11]]},"2911":{"position":[[340,11]]}}}],["dev/sd",{"_index":7760,"t":{"1833":{"position":[[1061,8]]},"1843":{"position":[[325,8]]}}}],["dev/sda",{"_index":5259,"t":{"1114":{"position":[[166,8]]},"1562":{"position":[[540,8]]},"1569":{"position":[[406,9]]},"1833":{"position":[[516,8]]},"1847":{"position":[[1264,8]]}}}],["dev/sda1",{"_index":5312,"t":{"1114":{"position":[[4037,10]]},"1833":{"position":[[735,9]]}}}],["dev/sda2",{"_index":7748,"t":{"1833":{"position":[[769,9]]}}}],["dev/sdb",{"_index":5249,"t":{"1112":{"position":[[5060,8]]},"1114":{"position":[[179,8],[2120,8],[3267,8],[3346,8],[3360,9]]},"1847":{"position":[[1448,8]]}}}],["dev/sdb1",{"_index":5298,"t":{"1114":{"position":[[3691,9],[4048,10],[5563,9]]}}}],["dev/sdb2",{"_index":5302,"t":{"1114":{"position":[[3744,9],[5633,9]]}}}],["dev/sdb3",{"_index":5305,"t":{"1114":{"position":[[3801,9],[5703,9]]}}}],["dev/sdb4",{"_index":5308,"t":{"1114":{"position":[[3858,9],[5773,9]]}}}],["dev/sdc",{"_index":5252,"t":{"1112":{"position":[[5130,8]]},"1114":{"position":[[2190,8]]}}}],["dev/sdc1",{"_index":5313,"t":{"1114":{"position":[[4059,9]]}}}],["dev/sdd",{"_index":5260,"t":{"1114":{"position":[[224,8],[297,8],[2260,8]]},"1810":{"position":[[226,10]]}}}],["dev/sdd1",{"_index":5314,"t":{"1114":{"position":[[4073,10]]}}}],["dev/sdx",{"_index":6846,"t":{"1411":{"position":[[14,8]]},"1419":{"position":[[82,8],[425,8],[446,8],[717,8],[817,8]]}}}],["dev/urandom",{"_index":9500,"t":{"2872":{"position":[[1219,13]]}}}],["dev/vd",{"_index":7759,"t":{"1833":{"position":[[1049,8]]}}}],["devel",{"_index":100,"t":{"10":{"position":[[429,5]]}}}],["develop",{"_index":209,"t":{"16":{"position":[[48,11]]},"73":{"position":[[194,10]]},"79":{"position":[[551,10]]},"103":{"position":[[52,9],[194,9]]},"105":{"position":[[491,9],[774,11]]},"114":{"position":[[921,11]]},"153":{"position":[[98,11]]},"164":{"position":[[26,11]]},"170":{"position":[[598,10]]},"178":{"position":[[1648,9]]},"235":{"position":[[366,9],[903,12]]},"238":{"position":[[192,7],[310,12]]},"240":{"position":[[217,12],[280,11]]},"245":{"position":[[120,11],[2095,10]]},"253":{"position":[[4,9]]},"265":{"position":[[15,9]]},"274":{"position":[[125,11],[292,11]]},"280":{"position":[[739,11]]},"327":{"position":[[256,12],[476,11],[596,11]]},"329":{"position":[[142,12]]},"349":{"position":[[482,11]]},"366":{"position":[[4,11],[723,7],[905,11]]},"374":{"position":[[1358,10]]},"381":{"position":[[1697,10]]},"383":{"position":[[0,10],[221,11]]},"387":{"position":[[9,11]]},"389":{"position":[[185,11]]},"487":{"position":[[5126,11]]},"489":{"position":[[759,11]]},"499":{"position":[[500,9],[1651,10]]},"513":{"position":[[99,8]]},"530":{"position":[[916,11]]},"635":{"position":[[407,9]]},"648":{"position":[[64,9]]},"780":{"position":[[674,9],[692,9]]},"883":{"position":[[219,10],[2313,12]]},"895":{"position":[[4,11]]},"954":{"position":[[256,9]]},"1560":{"position":[[188,11]]},"1564":{"position":[[72,10]]},"1591":{"position":[[16,11]]},"1617":{"position":[[4,11]]},"1690":{"position":[[53,11],[266,11]]},"1738":{"position":[[214,9]]},"1943":{"position":[[264,10]]},"1951":{"position":[[95,11],[173,11],[527,11],[574,11]]},"2079":{"position":[[561,10]]},"2100":{"position":[[639,7]]},"2154":{"position":[[435,9]]},"2209":{"position":[[17,11]]},"2229":{"position":[[365,12]]},"2281":{"position":[[138,9]]},"2310":{"position":[[19,9],[276,9],[610,11]]},"2317":{"position":[[68,10]]},"2326":{"position":[[25,11],[460,11]]},"2342":{"position":[[4,11]]},"2400":{"position":[[49,9]]},"2422":{"position":[[25,11]]},"2426":{"position":[[791,9]]},"2456":{"position":[[49,9]]},"2461":{"position":[[23,11]]},"2463":{"position":[[417,11]]},"2470":{"position":[[85,11]]},"2484":{"position":[[14,11]]},"2497":{"position":[[78,10]]},"2510":{"position":[[85,11],[236,12]]},"2524":{"position":[[222,11]]},"2623":{"position":[[325,11]]},"2633":{"position":[[31,9]]},"2647":{"position":[[354,11]]},"2673":{"position":[[1741,12]]},"2675":{"position":[[731,9]]},"2692":{"position":[[281,11]]},"2964":{"position":[[171,12]]},"2966":{"position":[[865,11]]},"3011":{"position":[[270,9],[1160,7],[1234,7],[1555,8]]},"3016":{"position":[[42,8]]},"3061":{"position":[[860,7]]},"3065":{"position":[[205,11]]},"3071":{"position":[[1198,9],[2002,11],[2289,11]]},"3092":{"position":[[354,11]]},"3094":{"position":[[12,11]]},"3124":{"position":[[202,12]]},"3158":{"position":[[478,11]]},"3208":{"position":[[1066,11],[1449,10]]},"3210":{"position":[[157,10]]},"3251":{"position":[[78,9],[485,12],[3189,11],[3362,12]]},"3274":{"position":[[461,9]]},"3295":{"position":[[160,8]]},"3299":{"position":[[1416,11],[2855,11],[3994,11],[5127,11]]},"3301":{"position":[[4246,10]]},"3380":{"position":[[93,11]]},"3389":{"position":[[683,9]]},"3518":{"position":[[300,9]]}}}],["developers/review",{"_index":2868,"t":{"499":{"position":[[424,20]]}}}],["deviat",{"_index":9016,"t":{"2625":{"position":[[1321,7]]}}}],["devic",{"_index":1753,"t":{"251":{"position":[[227,7]]},"306":{"position":[[78,6]]},"740":{"position":[[378,8]]},"768":{"position":[[337,7],[358,8]]},"778":{"position":[[66,6]]},"786":{"position":[[470,7],[488,7]]},"903":{"position":[[2085,6],[2361,7]]},"984":{"position":[[425,7]]},"986":{"position":[[372,7],[453,7]]},"995":{"position":[[198,7]]},"1067":{"position":[[5520,7]]},"1089":{"position":[[1818,6],[1925,6],[2036,6],[2147,6],[2254,6],[2358,6]]},"1094":{"position":[[6,7],[99,6]]},"1112":{"position":[[56,7],[243,7],[336,7],[492,7],[897,7],[1068,6],[1096,6],[1475,6],[1488,7],[1549,6],[1586,7],[1646,6],[1682,7],[1707,6],[1737,6],[1763,7],[1803,6],[1822,6],[1851,7],[1889,6],[2008,6],[2038,6],[2064,7],[2120,6],[2139,6],[2169,7],[2208,6],[2327,6],[2357,6],[2384,7],[2440,6],[2453,6],[2466,6],[2499,6],[2528,6],[2545,7],[2581,7],[2687,6],[2717,6],[2743,6],[2769,7],[2840,6],[2853,6],[2871,6],[2904,6],[2933,7],[2971,6],[3094,6],[3124,7],[3163,6],[3282,6],[3312,6],[3338,6],[3364,7],[4909,8],[4948,7]]},"1114":{"position":[[20,8],[158,7],[204,8],[217,6],[249,6],[312,7],[427,6],[579,6],[1997,7],[3260,6],[3656,6],[4181,6],[5468,7]]},"1188":{"position":[[334,6],[388,7]]},"1234":{"position":[[1802,7],[1844,7]]},"1273":{"position":[[121,7],[578,7]]},"1400":{"position":[[705,8]]},"1415":{"position":[[42,7]]},"1417":{"position":[[42,7]]},"1419":{"position":[[42,7],[57,6],[575,6],[585,6],[886,7],[960,7],[1126,6]]},"1424":{"position":[[203,7]]},"1430":{"position":[[1339,7]]},"1523":{"position":[[470,7],[488,7]]},"1569":{"position":[[396,6],[474,6],[969,6],[1235,6],[1542,7]]},"1571":{"position":[[1486,7]]},"1585":{"position":[[770,6],[1385,6],[1629,6]]},"1625":{"position":[[2085,6],[2361,7]]},"1728":{"position":[[10,6],[930,6],[1004,6],[1037,6],[1203,6],[1239,6]]},"1833":{"position":[[1073,7],[1159,7],[1192,6],[1264,8]]},"1843":{"position":[[334,6]]},"1845":{"position":[[489,6],[515,6],[2757,6]]},"1847":{"position":[[955,6]]},"1913":{"position":[[1887,6]]},"1939":{"position":[[296,6]]},"1949":{"position":[[42,6]]},"2029":{"position":[[1887,6]]},"2350":{"position":[[2085,6],[2361,7]]},"2409":{"position":[[132,6]]},"2711":{"position":[[1516,6]]},"2856":{"position":[[1494,6]]},"2872":{"position":[[500,6]]},"2881":{"position":[[373,6]]},"2933":{"position":[[1047,6]]},"2947":{"position":[[3504,7],[4959,7],[5060,6],[5091,6],[5115,7],[5383,6],[5550,7]]},"2951":{"position":[[217,8]]},"2999":{"position":[[348,7]]},"3251":{"position":[[5129,6],[5287,7]]},"3255":{"position":[[650,6]]}}}],["device_id",{"_index":6874,"t":{"1424":{"position":[[179,10]]}}}],["device_path",{"_index":6875,"t":{"1424":{"position":[[190,12]]}}}],["devicenam",{"_index":7746,"t":{"1833":{"position":[[688,12],[718,10],[1324,11],[1356,11]]}}}],["devis",{"_index":572,"t":{"79":{"position":[[138,6]]}}}],["devop",{"_index":588,"t":{"79":{"position":[[539,6]]},"245":{"position":[[543,6]]},"513":{"position":[[81,6],[246,6]]},"2229":{"position":[[279,6]]},"2550":{"position":[[517,6]]},"2697":{"position":[[317,7]]},"2742":{"position":[[317,7]]},"2832":{"position":[[317,7]]},"2921":{"position":[[317,7]]}}}],["devops/sysop",{"_index":2131,"t":{"329":{"position":[[0,13]]}}}],["devstack",{"_index":3479,"t":{"650":{"position":[[404,9]]}}}],["dewey",{"_index":855,"t":{"131":{"position":[[663,5]]}}}],["dex",{"_index":8361,"t":{"2176":{"position":[[1013,4]]}}}],["df",{"_index":6824,"t":{"1400":{"position":[[254,2],[354,2]]}}}],["df4af5376bbd4de587c4335622149be7",{"_index":392,"t":{"30":{"position":[[94,32]]}}}],["dfdf",{"_index":6747,"t":{"1368":{"position":[[2406,4],[2584,5],[2599,4],[2683,4],[2688,5]]}}}],["dforeground",{"_index":6374,"t":{"1319":{"position":[[365,16],[408,11]]}}}],["dhcp",{"_index":3713,"t":{"772":{"position":[[1001,4]]},"1067":{"position":[[1705,4],[1820,4]]},"1282":{"position":[[66,4]]},"1562":{"position":[[698,5]]},"1569":{"position":[[1172,4],[1507,4],[1675,4]]},"1571":{"position":[[1451,4],[1619,4]]},"1585":{"position":[[1846,6],[3816,4]]},"1841":{"position":[[410,4]]}}}],["dhcp4",{"_index":7083,"t":{"1585":{"position":[[2001,6]]}}}],["diagnos",{"_index":9936,"t":{"3208":{"position":[[1481,9]]}}}],["diagram",{"_index":8262,"t":{"2134":{"position":[[37,7]]},"2677":{"position":[[218,9],[264,9]]}}}],["dial",{"_index":1739,"t":{"249":{"position":[[429,4]]},"251":{"position":[[550,4]]}}}],["dialogu",{"_index":1675,"t":{"247":{"position":[[1095,9]]}}}],["diataxi",{"_index":9058,"t":{"2669":{"position":[[113,8]]}}}],["dibn5+debivnwihdocs+bkptvmetxojnkuobzhe8dweb/rqiguvjyeq5yoamz/y+qgvq",{"_index":2089,"t":{"325":{"position":[[4564,69]]}}}],["dicover",{"_index":9641,"t":{"2964":{"position":[[254,11]]}}}],["dict",{"_index":1882,"t":{"284":{"position":[[862,8]]}}}],["dictionari",{"_index":5158,"t":{"1106":{"position":[[47,11],[63,10],[187,10]]},"1217":{"position":[[649,11]]},"1764":{"position":[[3919,10]]}}}],["dicuss",{"_index":9477,"t":{"2864":{"position":[[247,10]]}}}],["didn't",{"_index":2037,"t":{"325":{"position":[[153,6]]}}}],["differ",{"_index":987,"t":{"158":{"position":[[114,9],[762,9]]},"166":{"position":[[311,6]]},"178":{"position":[[1242,9]]},"235":{"position":[[1258,9]]},"247":{"position":[[2005,9],[2725,9],[2777,10],[2881,9],[2903,9]]},"253":{"position":[[748,9]]},"290":{"position":[[347,9]]},"372":{"position":[[17,9],[70,9]]},"421":{"position":[[86,9],[135,9],[195,9],[839,7],[920,9]]},"462":{"position":[[1013,11]]},"499":{"position":[[223,9]]},"507":{"position":[[316,9]]},"583":{"position":[[343,9]]},"600":{"position":[[795,9]]},"602":{"position":[[14,9]]},"604":{"position":[[9918,9]]},"606":{"position":[[86,9]]},"627":{"position":[[3204,9]]},"648":{"position":[[695,9],[856,9]]},"654":{"position":[[370,9]]},"692":{"position":[[49,9]]},"736":{"position":[[127,9]]},"738":{"position":[[210,9]]},"740":{"position":[[588,9]]},"742":{"position":[[709,6]]},"762":{"position":[[330,9]]},"792":{"position":[[30,9]]},"883":{"position":[[1447,9],[2243,9]]},"895":{"position":[[324,9]]},"911":{"position":[[776,11]]},"1080":{"position":[[1587,11]]},"1112":{"position":[[2860,10]]},"1165":{"position":[[2601,12]]},"1184":{"position":[[1523,7]]},"1232":{"position":[[582,9],[632,6]]},"1234":{"position":[[360,10]]},"1267":{"position":[[17,9],[59,9]]},"1286":{"position":[[583,9]]},"1360":{"position":[[993,7]]},"1529":{"position":[[30,9]]},"1564":{"position":[[466,12],[618,11]]},"1574":{"position":[[358,9]]},"1585":{"position":[[551,11]]},"1617":{"position":[[324,9]]},"1633":{"position":[[776,11]]},"1690":{"position":[[288,9]]},"1764":{"position":[[3531,12]]},"1785":{"position":[[586,9]]},"1822":{"position":[[22,9]]},"1825":{"position":[[1750,11]]},"1855":{"position":[[47,9]]},"1859":{"position":[[75,9]]},"1863":{"position":[[28,9],[111,6]]},"1872":{"position":[[148,9]]},"1917":{"position":[[47,9]]},"1921":{"position":[[75,9]]},"1925":{"position":[[28,9],[111,6]]},"1937":{"position":[[349,9]]},"1972":{"position":[[958,9],[1048,11],[1111,9]]},"1988":{"position":[[148,9]]},"2043":{"position":[[322,9]]},"2053":{"position":[[474,9],[835,9]]},"2083":{"position":[[444,9]]},"2085":{"position":[[341,9]]},"2098":{"position":[[321,11],[1346,12]]},"2140":{"position":[[113,9]]},"2176":{"position":[[452,9]]},"2248":{"position":[[107,9]]},"2342":{"position":[[324,9]]},"2358":{"position":[[776,11]]},"2522":{"position":[[57,9]]},"2562":{"position":[[147,9]]},"2566":{"position":[[14754,9]]},"2568":{"position":[[393,9]]},"2631":{"position":[[2299,11]]},"2647":{"position":[[831,9]]},"2697":{"position":[[52,9]]},"2719":{"position":[[976,9],[1029,9]]},"2721":{"position":[[64,9]]},"2735":{"position":[[42,9]]},"2742":{"position":[[52,9]]},"2758":{"position":[[974,9],[1027,9]]},"2760":{"position":[[76,9]]},"2774":{"position":[[178,9]]},"2797":{"position":[[173,9]]},"2832":{"position":[[52,9]]},"2846":{"position":[[64,9]]},"2921":{"position":[[52,9]]},"2949":{"position":[[1078,9]]},"2960":{"position":[[132,9]]},"2962":{"position":[[457,9]]},"2966":{"position":[[672,9],[1332,9],[1386,9],[1434,9],[2807,9],[3378,9],[4474,9]]},"2968":{"position":[[18,9]]},"2999":{"position":[[102,9]]},"3009":{"position":[[10,9]]},"3014":{"position":[[455,9],[845,9]]},"3016":{"position":[[364,9]]},"3031":{"position":[[504,9]]},"3057":{"position":[[10,9]]},"3069":{"position":[[160,9]]},"3078":{"position":[[150,9]]},"3080":{"position":[[771,9]]},"3084":{"position":[[209,9]]},"3103":{"position":[[63,9]]},"3105":{"position":[[186,9]]},"3154":{"position":[[30,9]]},"3160":{"position":[[1735,9]]},"3182":{"position":[[351,9],[654,9]]},"3184":{"position":[[1341,9],[1570,9],[1935,9],[2023,9],[2370,9],[2416,9],[2648,9]]},"3186":{"position":[[523,9],[543,9],[1122,9]]},"3206":{"position":[[756,9]]},"3231":{"position":[[70,9],[197,9],[232,9],[363,9]]},"3236":{"position":[[95,9]]},"3251":{"position":[[1260,9]]},"3253":{"position":[[106,10],[224,10]]},"3266":{"position":[[66,9]]},"3270":{"position":[[2176,9],[2241,9]]},"3274":{"position":[[244,9]]},"3299":{"position":[[2491,6]]},"3301":{"position":[[4529,10]]},"3314":{"position":[[2655,9]]},"3316":{"position":[[1437,9]]},"3355":{"position":[[199,9]]},"3374":{"position":[[398,9],[428,9]]},"3376":{"position":[[389,9],[438,9]]},"3389":{"position":[[416,9],[505,9]]},"3400":{"position":[[1853,9],[1875,9]]},"3415":{"position":[[69,9]]},"3417":{"position":[[122,9]]},"3440":{"position":[[116,9]]},"3446":{"position":[[27,9]]},"3472":{"position":[[277,6],[13227,9]]},"3482":{"position":[[1543,6],[1649,9]]}}}],["differenci",{"_index":10138,"t":{"3325":{"position":[[113,13]]}}}],["differenti",{"_index":4510,"t":{"920":{"position":[[828,13]]},"1642":{"position":[[828,13]]},"1853":{"position":[[295,15]]},"1888":{"position":[[346,12]]},"1915":{"position":[[295,15]]},"2004":{"position":[[346,12]]},"2116":{"position":[[334,13]]},"2367":{"position":[[828,13]]},"2719":{"position":[[65,14],[895,13],[1123,15]]},"2731":{"position":[[217,13]]},"2758":{"position":[[65,14],[893,13],[1121,15]]},"2764":{"position":[[1112,13]]},"2770":{"position":[[217,13]]},"2852":{"position":[[144,15]]},"2860":{"position":[[217,13]]},"2960":{"position":[[295,15]]},"3397":{"position":[[1444,13]]}}}],["difficult",{"_index":1636,"t":{"245":{"position":[[1747,9]]},"598":{"position":[[1276,10]]},"1882":{"position":[[633,9]]},"1998":{"position":[[633,9]]},"2176":{"position":[[285,10]]},"2214":{"position":[[328,9]]},"2951":{"position":[[788,9]]},"3495":{"position":[[28,9]]}}}],["difficulti",{"_index":9772,"t":{"3097":{"position":[[353,12]]},"3214":{"position":[[478,10]]}}}],["dig",{"_index":9375,"t":{"2799":{"position":[[0,7]]}}}],["digest",{"_index":1337,"t":{"184":{"position":[[972,7]]}}}],["digit",{"_index":1566,"t":{"235":{"position":[[159,7],[700,7],[1098,7]]},"932":{"position":[[4616,5]]},"1654":{"position":[[4616,5]]},"2379":{"position":[[4616,5]]},"2493":{"position":[[118,7]]},"2625":{"position":[[1517,5]]},"2944":{"position":[[1888,5]]},"3264":{"position":[[156,7],[250,7]]}}}],["dignissim",{"_index":63,"t":{"6":{"position":[[80,9]]}}}],["dilig",{"_index":8403,"t":{"2235":{"position":[[510,8]]}}}],["dimens",{"_index":8618,"t":{"2522":{"position":[[143,11]]},"2795":{"position":[[335,11]]}}}],["diminish",{"_index":9691,"t":{"3011":{"position":[[2714,10]]}}}],["dimm",{"_index":4709,"t":{"988":{"position":[[292,4],[334,4]]}}}],["dir",{"_index":2951,"t":{"519":{"position":[[366,4]]},"819":{"position":[[432,3],[436,4],[1522,3],[1526,3]]},"821":{"position":[[517,3],[521,4],[974,3],[978,3]]},"859":{"position":[[425,3],[429,4],[1038,3],[1042,3],[6885,3],[6905,3]]},"1509":{"position":[[432,3],[436,4],[1522,3],[1526,3]]},"1511":{"position":[[517,3],[521,4],[974,3],[978,3]]},"1603":{"position":[[425,3],[429,4],[1038,3],[1042,3],[6885,3],[6905,3]]},"1711":{"position":[[24,4]]}}}],["direct",{"_index":885,"t":{"139":{"position":[[11,9],[199,9],[286,10]]},"180":{"position":[[160,10]]},"245":{"position":[[1182,8],[1241,6]]},"247":{"position":[[1376,8]]},"337":{"position":[[196,6]]},"370":{"position":[[666,6]]},"507":{"position":[[547,6],[579,6]]},"509":{"position":[[51,6]]},"1118":{"position":[[249,6]]},"1144":{"position":[[184,9]]},"1252":{"position":[[923,6]]},"1319":{"position":[[551,9]]},"1475":{"position":[[259,6],[467,6],[598,6],[796,6]]},"1697":{"position":[[11,9],[200,9],[287,10]]},"1699":{"position":[[28,9]]},"1783":{"position":[[237,6]]},"1853":{"position":[[338,11]]},"1855":{"position":[[631,10]]},"1915":{"position":[[338,11]]},"1917":{"position":[[631,10]]},"2083":{"position":[[271,7]]},"2270":{"position":[[76,10]]},"2897":{"position":[[639,6]]},"3088":{"position":[[434,9]]},"3107":{"position":[[537,9]]},"3472":{"position":[[13823,10]]}}}],["direct=1",{"_index":6978,"t":{"1475":{"position":[[366,8],[695,8]]}}}],["directli",{"_index":91,"t":{"10":{"position":[[319,8]]},"23":{"position":[[184,8]]},"253":{"position":[[831,8]]},"302":{"position":[[689,8]]},"325":{"position":[[88,8],[4315,9]]},"331":{"position":[[230,8]]},"353":{"position":[[236,8]]},"370":{"position":[[94,8],[325,8]]},"372":{"position":[[618,8]]},"374":{"position":[[201,8]]},"393":{"position":[[1081,8]]},"497":{"position":[[147,8]]},"525":{"position":[[52,8]]},"604":{"position":[[7555,8],[9265,8]]},"609":{"position":[[1521,8],[2323,8],[5178,8]]},"617":{"position":[[870,9]]},"619":{"position":[[662,8]]},"621":{"position":[[9,9]]},"623":{"position":[[9,9]]},"772":{"position":[[1046,8]]},"786":{"position":[[346,8]]},"907":{"position":[[557,8]]},"947":{"position":[[744,8]]},"956":{"position":[[270,8]]},"982":{"position":[[673,9]]},"990":{"position":[[441,9]]},"1075":{"position":[[224,8]]},"1118":{"position":[[264,8]]},"1279":{"position":[[45,9]]},"1286":{"position":[[597,8]]},"1523":{"position":[[346,8]]},"1585":{"position":[[591,8],[3650,8]]},"1594":{"position":[[347,8]]},"1629":{"position":[[557,8]]},"1669":{"position":[[744,8]]},"1872":{"position":[[100,8]]},"1890":{"position":[[48,8],[190,8]]},"1892":{"position":[[20,8]]},"1913":{"position":[[54,8]]},"1951":{"position":[[779,9]]},"1988":{"position":[[100,8]]},"2006":{"position":[[48,8],[190,8]]},"2008":{"position":[[20,8]]},"2029":{"position":[[54,8]]},"2053":{"position":[[427,8]]},"2096":{"position":[[2646,8]]},"2118":{"position":[[1059,8],[1850,8],[2075,8],[2538,8]]},"2140":{"position":[[344,9],[395,8]]},"2158":{"position":[[195,8]]},"2248":{"position":[[322,8]]},"2354":{"position":[[557,8]]},"2394":{"position":[[744,8]]},"2623":{"position":[[421,8]]},"2631":{"position":[[1215,8]]},"2692":{"position":[[190,8]]},"2897":{"position":[[685,8]]},"2911":{"position":[[466,9]]},"2953":{"position":[[43,8]]},"2960":{"position":[[678,8]]},"2966":{"position":[[1751,8],[3580,8],[4615,9]]},"3016":{"position":[[546,8]]},"3361":{"position":[[193,8],[278,9]]},"3423":{"position":[[454,9]]},"3472":{"position":[[13418,8],[13511,9]]}}}],["directori",{"_index":645,"t":{"105":{"position":[[254,10],[866,9],[1393,9]]},"112":{"position":[[88,9]]},"114":{"position":[[394,9],[411,9],[499,10],[592,9]]},"116":{"position":[[205,10]]},"118":{"position":[[75,10],[223,10]]},"162":{"position":[[20,9]]},"280":{"position":[[686,9]]},"317":{"position":[[445,9],[656,9],[713,9],[898,9]]},"389":{"position":[[91,9]]},"393":{"position":[[215,10],[1127,10],[1159,9],[1766,10]]},"434":{"position":[[41,10]]},"447":{"position":[[433,9]]},"449":{"position":[[552,9]]},"451":{"position":[[126,9],[211,9]]},"456":{"position":[[251,9]]},"458":{"position":[[224,9],[297,9]]},"472":{"position":[[1603,11]]},"530":{"position":[[1253,10]]},"596":{"position":[[237,9],[1855,10]]},"604":{"position":[[652,10],[1374,9]]},"606":{"position":[[273,11]]},"617":{"position":[[1012,9]]},"627":{"position":[[410,10],[3423,9]]},"631":{"position":[[57,9],[465,9]]},"633":{"position":[[1346,9],[1602,9],[2966,10],[3164,11]]},"635":{"position":[[834,9],[930,9],[1240,10]]},"650":{"position":[[1188,9],[1925,9]]},"667":{"position":[[66,9]]},"730":{"position":[[56,9]]},"790":{"position":[[712,9]]},"817":{"position":[[56,9]]},"819":{"position":[[1547,9],[1810,9]]},"821":{"position":[[999,9],[1262,9]]},"859":{"position":[[56,9],[1063,9],[1328,9],[6461,9],[6522,9],[6783,9]]},"905":{"position":[[564,10]]},"940":{"position":[[61,9]]},"1035":{"position":[[94,9]]},"1041":{"position":[[129,9],[215,10],[709,9]]},"1045":{"position":[[67,10]]},"1047":{"position":[[116,9]]},"1055":{"position":[[242,9],[275,9],[483,9],[619,11]]},"1061":{"position":[[118,9],[744,9]]},"1063":{"position":[[4,9],[100,9]]},"1065":{"position":[[573,9],[682,9]]},"1067":{"position":[[554,9]]},"1071":{"position":[[1424,9]]},"1073":{"position":[[588,10]]},"1077":{"position":[[340,9]]},"1098":{"position":[[110,9]]},"1110":{"position":[[550,10]]},"1112":{"position":[[4191,9],[4646,9]]},"1114":{"position":[[736,9],[4338,9]]},"1120":{"position":[[193,9],[226,9],[361,9]]},"1167":{"position":[[2721,9],[3301,9]]},"1184":{"position":[[730,9],[871,9],[920,9],[1063,9]]},"1254":{"position":[[37,9]]},"1256":{"position":[[1679,9]]},"1286":{"position":[[2432,10]]},"1317":{"position":[[3279,11],[5101,11]]},"1491":{"position":[[56,9]]},"1507":{"position":[[56,9]]},"1509":{"position":[[1547,9],[1810,9]]},"1511":{"position":[[999,9],[1262,9]]},"1527":{"position":[[712,9]]},"1603":{"position":[[56,9],[1063,9],[1328,9],[6461,9],[6522,9],[6783,9]]},"1627":{"position":[[564,10]]},"1662":{"position":[[61,9]]},"1676":{"position":[[383,10]]},"1678":{"position":[[9,9],[267,10]]},"1713":{"position":[[57,9]]},"1717":{"position":[[25,11]]},"1731":{"position":[[597,9],[968,9]]},"1745":{"position":[[612,9]]},"1747":{"position":[[461,9]]},"1749":{"position":[[171,9]]},"1758":{"position":[[201,10]]},"1773":{"position":[[849,10]]},"1837":{"position":[[234,10]]},"2096":{"position":[[1584,10],[2609,10]]},"2118":{"position":[[228,9]]},"2248":{"position":[[218,12]]},"2352":{"position":[[564,10]]},"2387":{"position":[[61,9]]},"2658":{"position":[[5,9]]},"2660":{"position":[[400,10]]},"2824":{"position":[[72,9]]},"2874":{"position":[[673,9]]},"3061":{"position":[[568,11]]},"3251":{"position":[[1470,10]]}}}],["directory/fil",{"_index":5006,"t":{"1073":{"position":[[248,14]]}}}],["directoy",{"_index":7767,"t":{"1835":{"position":[[316,8]]}}}],["disabl",{"_index":871,"t":{"133":{"position":[[407,7]]},"141":{"position":[[286,7]]},"151":{"position":[[36,7],[105,7]]},"247":{"position":[[720,11]]},"487":{"position":[[2801,7]]},"505":{"position":[[1061,8]]},"635":{"position":[[3782,7]]},"833":{"position":[[111,7]]},"850":{"position":[[1277,8]]},"1118":{"position":[[857,7]]},"1161":{"position":[[1256,9]]},"1226":{"position":[[364,8]]},"1279":{"position":[[151,9]]},"1358":{"position":[[379,7]]},"1375":{"position":[[49,7],[428,8],[742,8]]},"1377":{"position":[[429,8],[743,8],[1433,8],[1747,8]]},"1428":{"position":[[390,7]]},"1432":{"position":[[67,7]]},"1471":{"position":[[528,7],[656,8],[750,7],[789,7],[990,7],[1115,8],[1212,7],[1259,7],[1375,8],[1472,7],[1519,7],[1637,8],[1790,7],[2004,8],[2101,7]]},"1484":{"position":[[1277,8]]},"1548":{"position":[[111,7]]},"1571":{"position":[[926,7]]},"1728":{"position":[[1562,7]]},"1779":{"position":[[4155,9]]},"1841":{"position":[[317,7]]},"1982":{"position":[[1446,7]]},"1984":{"position":[[1056,7]]},"2705":{"position":[[1329,8],[1909,8],[1991,8]]},"2750":{"position":[[1088,8],[2211,8],[2293,8]]},"2840":{"position":[[1557,8],[1639,8]]},"3084":{"position":[[811,7]]},"3236":{"position":[[2240,7]]},"3468":{"position":[[728,9]]}}}],["disabled:dis",{"_index":3614,"t":{"730":{"position":[[1986,17]]},"1491":{"position":[[1986,17]]}}}],["disadvantag",{"_index":1133,"t":{"170":{"position":[[1225,12]]},"178":{"position":[[815,16]]},"1585":{"position":[[306,12]]},"2647":{"position":[[651,13]]},"2953":{"position":[[219,12]]},"3011":{"position":[[2579,14]]},"3059":{"position":[[507,13]]},"3061":{"position":[[1305,13]]},"3222":{"position":[[496,14]]}}}],["disagr",{"_index":1702,"t":{"247":{"position":[[2114,12],[2588,14],[2707,13]]}}}],["disagre",{"_index":1707,"t":{"247":{"position":[[2555,9]]}}}],["disallow",{"_index":4567,"t":{"932":{"position":[[1392,8]]},"1654":{"position":[[1392,8]]},"2379":{"position":[[1392,8]]}}}],["disambigu",{"_index":9004,"t":{"2625":{"position":[[106,12]]}}}],["disast",{"_index":2597,"t":{"469":{"position":[[146,8]]},"596":{"position":[[2313,8]]},"3103":{"position":[[1326,8]]},"3160":{"position":[[1321,8]]}}}],["disc",{"_index":6057,"t":{"1232":{"position":[[646,4]]},"1831":{"position":[[274,4]]},"1833":{"position":[[85,5]]},"1835":{"position":[[126,4],[335,4],[434,5],[544,4]]},"1837":{"position":[[259,4]]},"1839":{"position":[[301,4]]}}}],["disc0",{"_index":7771,"t":{"1837":{"position":[[285,5]]},"1843":{"position":[[770,5],[1036,5]]}}}],["disc0.raw",{"_index":7777,"t":{"1839":{"position":[[265,9]]},"1841":{"position":[[599,9]]},"1843":{"position":[[741,9]]}}}],["disc0.vmdk",{"_index":7774,"t":{"1837":{"position":[[338,10]]},"1839":{"position":[[241,10]]}}}],["disc1",{"_index":7775,"t":{"1837":{"position":[[362,5]]},"1843":{"position":[[1107,5]]}}}],["disc1.vmdk",{"_index":7773,"t":{"1837":{"position":[[314,10]]}}}],["discard",{"_index":3062,"t":{"596":{"position":[[1967,8]]},"3465":{"position":[[700,9]]}}}],["disclosur",{"_index":10061,"t":{"3299":{"position":[[1838,10],[3233,10],[4456,10]]}}}],["disconnect",{"_index":6734,"t":{"1368":{"position":[[1932,15],[2611,15]]}}}],["discontinu",{"_index":4654,"t":{"954":{"position":[[526,12]]}}}],["discourag",{"_index":9412,"t":{"2842":{"position":[[161,11]]},"3236":{"position":[[1098,12]]},"3365":{"position":[[237,10]]}}}],["discov",{"_index":3359,"t":{"635":{"position":[[1896,8]]},"786":{"position":[[63,8]]},"1150":{"position":[[6639,8],[6902,8]]},"1523":{"position":[[63,8]]},"2085":{"position":[[323,10]]},"2697":{"position":[[257,10],[533,11],[1024,11]]},"2742":{"position":[[257,10],[923,11]]},"2832":{"position":[[257,10],[533,11]]},"2921":{"position":[[257,10],[419,11]]},"2964":{"position":[[223,9]]},"2966":{"position":[[3050,9],[3846,8],[3978,11]]},"3021":{"position":[[354,10]]},"3025":{"position":[[346,10]]},"3029":{"position":[[213,8]]},"3472":{"position":[[6448,8],[6711,8]]}}}],["discover",{"_index":8055,"t":{"1976":{"position":[[500,12]]},"2281":{"position":[[942,13]]},"2697":{"position":[[1210,15]]},"2715":{"position":[[690,12]]},"2737":{"position":[[462,15]]},"2742":{"position":[[1109,15]]},"2776":{"position":[[462,15]]},"2786":{"position":[[147,12],[424,12]]},"2852":{"position":[[267,13]]},"2939":{"position":[[291,16]]},"2951":{"position":[[1254,15]]},"2955":{"position":[[531,15]]},"2964":{"position":[[18,12]]},"2966":{"position":[[2608,12],[2903,12]]},"2970":{"position":[[20,15]]},"3029":{"position":[[72,15]]},"3039":{"position":[[190,12]]},"3042":{"position":[[200,12]]}}}],["discoveri",{"_index":1951,"t":{"300":{"position":[[38,9],[584,9]]},"1791":{"position":[[2429,9],[3234,9]]},"1957":{"position":[[1282,9]]},"1959":{"position":[[300,9],[1232,9]]},"2465":{"position":[[86,9]]},"2476":{"position":[[121,9]]}}}],["discovery.seed_host",{"_index":5875,"t":{"1167":{"position":[[1493,21],[2913,21]]}}}],["discret",{"_index":9110,"t":{"2700":{"position":[[598,8]]},"2745":{"position":[[598,8]]}}}],["discriminatori",{"_index":1683,"t":{"247":{"position":[[1409,14],[1704,14]]}}}],["discuss",{"_index":25,"t":{"4":{"position":[[282,11]]},"60":{"position":[[36,7]]},"75":{"position":[[111,7]]},"79":{"position":[[35,7]]},"151":{"position":[[384,11]]},"176":{"position":[[464,9]]},"178":{"position":[[2718,10]]},"195":{"position":[[102,7]]},"245":{"position":[[1143,11]]},"1974":{"position":[[492,11]]},"1982":{"position":[[401,11]]},"1984":{"position":[[11,11]]},"2233":{"position":[[423,10]]},"2283":{"position":[[22,11]]},"2426":{"position":[[805,9]]},"2474":{"position":[[82,10]]},"2506":{"position":[[381,7]]},"2627":{"position":[[900,10],[985,10]]},"2631":{"position":[[1257,10]]},"2673":{"position":[[1838,12]]},"2697":{"position":[[940,11]]},"2700":{"position":[[5,11]]},"2713":{"position":[[1856,7]]},"2735":{"position":[[352,11]]},"2742":{"position":[[839,11]]},"2745":{"position":[[5,11]]},"2756":{"position":[[1602,7]]},"2774":{"position":[[488,11]]},"2832":{"position":[[940,11]]},"2858":{"position":[[1592,7]]},"2872":{"position":[[985,9]]},"2964":{"position":[[347,9]]},"2966":{"position":[[3343,10]]},"2970":{"position":[[460,11]]},"3057":{"position":[[70,9]]},"3097":{"position":[[420,9]]},"3204":{"position":[[21,7]]},"3212":{"position":[[128,7]]},"3245":{"position":[[1452,11]]},"3251":{"position":[[3441,12]]},"3299":{"position":[[5534,9],[5643,9]]},"3370":{"position":[[373,9]]},"3434":{"position":[[373,9]]},"3518":{"position":[[289,10]]}}}],["discworld",{"_index":938,"t":{"143":{"position":[[524,9],[652,9],[668,9]]}}}],["dish",{"_index":1549,"t":{"229":{"position":[[323,7]]}}}],["disk",{"_index":2770,"t":{"487":{"position":[[2079,4],[2209,4]]},"660":{"position":[[2975,5]]},"730":{"position":[[2103,4]]},"742":{"position":[[228,4]]},"764":{"position":[[217,5]]},"774":{"position":[[112,6]]},"778":{"position":[[122,5]]},"786":{"position":[[899,5]]},"903":{"position":[[2292,4],[2431,6]]},"1114":{"position":[[3355,4],[3414,4],[3602,4]]},"1165":{"position":[[1468,5]]},"1226":{"position":[[1940,4],[1999,5]]},"1234":{"position":[[1676,5]]},"1252":{"position":[[766,4]]},"1419":{"position":[[310,4]]},"1491":{"position":[[2103,4]]},"1523":{"position":[[899,5]]},"1569":{"position":[[742,5],[1230,4]]},"1571":{"position":[[51,4]]},"1587":{"position":[[582,4],[662,4],[884,4],[1020,4],[1273,4]]},"1589":{"position":[[27,4]]},"1625":{"position":[[2292,4],[2431,6]]},"1843":{"position":[[695,4]]},"1870":{"position":[[165,6]]},"1872":{"position":[[87,4],[221,4],[320,4],[359,4]]},"1876":{"position":[[113,6]]},"1880":{"position":[[197,5],[476,5],[800,4]]},"1902":{"position":[[299,4],[391,4]]},"1911":{"position":[[342,4],[389,5]]},"1986":{"position":[[165,6]]},"1988":{"position":[[87,4],[221,4],[320,4],[359,4]]},"1992":{"position":[[113,6]]},"1996":{"position":[[197,5],[476,5],[800,4]]},"2018":{"position":[[299,4],[391,4]]},"2027":{"position":[[342,4],[389,5]]},"2118":{"position":[[1531,4]]},"2276":{"position":[[153,4]]},"2278":{"position":[[561,4],[600,4]]},"2350":{"position":[[2292,4],[2431,6]]},"2536":{"position":[[217,5]]},"2550":{"position":[[276,4]]},"2586":{"position":[[338,4]]},"2697":{"position":[[659,5],[748,5],[1322,4]]},"2700":{"position":[[357,6]]},"2702":{"position":[[439,4]]},"2709":{"position":[[0,4],[72,4],[137,4],[176,4],[224,4],[337,4],[655,4],[705,4],[742,4],[801,4],[951,4],[1192,5],[1202,4],[1286,4],[1324,5],[1602,4],[1658,4],[1743,4],[1970,4],[2230,4]]},"2711":{"position":[[77,4],[761,5],[1017,4],[1083,6],[1170,4],[1232,4],[1324,4]]},"2715":{"position":[[736,5]]},"2731":{"position":[[748,5]]},"2733":{"position":[[81,4],[245,4],[512,4]]},"2742":{"position":[[558,5],[647,5],[1221,4]]},"2745":{"position":[[357,6]]},"2747":{"position":[[439,4]]},"2754":{"position":[[0,4],[72,4],[137,4],[176,4],[224,4],[337,4],[655,4],[705,4],[781,5],[883,4],[942,4],[1092,4],[1333,5],[1343,4],[1427,4],[1465,5],[1743,4],[1799,4],[1884,4],[2185,4]]},"2770":{"position":[[748,5]]},"2772":{"position":[[81,4],[245,4],[512,4]]},"2786":{"position":[[206,4]]},"2832":{"position":[[659,5],[748,5]]},"2835":{"position":[[298,6]]},"2837":{"position":[[56,4]]},"2844":{"position":[[0,4],[65,4],[104,4],[152,4],[265,4],[583,4],[633,4],[670,4],[729,4],[879,4],[1120,5],[1130,4],[1214,4],[1396,4],[1452,4],[1537,4],[1763,4],[2023,4]]},"2854":{"position":[[81,4],[245,4],[513,4]]},"2856":{"position":[[79,4],[739,5],[995,4],[1061,6],[1147,4],[1209,4],[1302,4]]},"2860":{"position":[[709,5]]},"2872":{"position":[[122,4],[138,4]]},"2892":{"position":[[433,4],[503,4]]},"2923":{"position":[[661,4],[838,4],[927,4]]},"2927":{"position":[[48,4],[58,4]]},"2929":{"position":[[48,4],[58,4]]},"2931":{"position":[[68,4],[447,4],[522,4]]},"2933":{"position":[[392,5],[450,5],[488,5],[546,4],[612,6],[699,4],[763,4],[855,4]]},"2939":{"position":[[351,5],[603,5]]},"2947":{"position":[[5188,5],[5228,7],[5860,4]]},"2949":{"position":[[722,6]]},"2951":{"position":[[657,4],[853,5],[1105,5]]},"2955":{"position":[[232,4]]},"3141":{"position":[[126,4]]},"3272":{"position":[[616,4]]},"3393":{"position":[[267,5]]},"3400":{"position":[[908,5]]}}}],["disk.img",{"_index":3757,"t":{"790":{"position":[[1205,8]]},"1527":{"position":[[1205,8]]}}}],["disk/bi",{"_index":5216,"t":{"1112":{"position":[[1115,7],[1145,7]]}}}],["disk[gb",{"_index":9397,"t":{"2837":{"position":[[37,8]]}}}],["disk[gb]&typ",{"_index":9114,"t":{"2702":{"position":[[40,13]]},"2747":{"position":[[40,13]]}}}],["disk_gb",{"_index":8680,"t":{"2566":{"position":[[435,8]]}}}],["disklabel",{"_index":5291,"t":{"1114":{"position":[[3582,9]]}}}],["diskless",{"_index":2768,"t":{"487":{"position":[[1994,8],[2131,8]]},"604":{"position":[[382,8]]},"903":{"position":[[2373,8]]},"905":{"position":[[2156,8]]},"1625":{"position":[[2373,8]]},"1627":{"position":[[2156,8]]},"2350":{"position":[[2373,8]]},"2352":{"position":[[2156,8]]},"2405":{"position":[[914,8]]}}}],["diskn",{"_index":9589,"t":{"2923":{"position":[[794,5],[947,5]]}}}],["diskspec",{"_index":7111,"t":{"1587":{"position":[[1285,8]]}}}],["dislik",{"_index":1224,"t":{"176":{"position":[[397,8]]}}}],["dismiss",{"_index":1328,"t":{"184":{"position":[[286,7]]},"3255":{"position":[[457,10]]}}}],["disord",{"_index":9478,"t":{"2868":{"position":[[118,8]]}}}],["dispar",{"_index":9940,"t":{"3218":{"position":[[708,11],[1278,11]]}}}],["dispatch",{"_index":2030,"t":{"323":{"position":[[274,10]]}}}],["display",{"_index":3104,"t":{"604":{"position":[[2040,7]]},"909":{"position":[[1587,11]]},"932":{"position":[[2503,10],[2685,11],[2728,10]]},"1077":{"position":[[521,10],[988,10]]},"1124":{"position":[[864,9]]},"1256":{"position":[[1130,10]]},"1400":{"position":[[162,7]]},"1631":{"position":[[1587,11]]},"1654":{"position":[[2503,10],[2685,11],[2728,10]]},"1728":{"position":[[633,9]]},"1764":{"position":[[173,9]]},"1816":{"position":[[38,7]]},"2321":{"position":[[466,8]]},"2356":{"position":[[1587,11]]},"2379":{"position":[[2503,10],[2685,11],[2728,10]]},"2688":{"position":[[1214,9],[2346,7]]},"2966":{"position":[[4143,10]]}}}],["display_nam",{"_index":8673,"t":{"2566":{"position":[[175,13],[1965,13],[12936,13]]}}}],["displaynam",{"_index":10185,"t":{"3357":{"position":[[577,14],[624,14],[671,14],[714,14]]}}}],["disproportion",{"_index":1100,"t":{"170":{"position":[[267,16]]}}}],["disput",{"_index":4432,"t":{"911":{"position":[[1145,8]]},"1633":{"position":[[1145,8]]},"2358":{"position":[[1145,8]]}}}],["disregard",{"_index":8067,"t":{"1982":{"position":[[0,12]]}}}],["disrupt",{"_index":3072,"t":{"598":{"position":[[412,11],[1450,10]]},"627":{"position":[[4375,10]]},"669":{"position":[[846,10]]},"1430":{"position":[[1294,10]]},"1731":{"position":[[81,10],[553,10]]},"2248":{"position":[[410,7]]},"2947":{"position":[[3339,11],[4058,10],[4409,11]]},"3208":{"position":[[840,9],[1703,10]]},"3210":{"position":[[750,11]]},"3262":{"position":[[196,9]]}}}],["distanc",{"_index":1437,"t":{"204":{"position":[[226,8]]},"1124":{"position":[[1395,10]]}}}],["distil",{"_index":657,"t":{"105":{"position":[[548,8]]},"114":{"position":[[736,10],[863,7]]}}}],["distinct",{"_index":3148,"t":{"604":{"position":[[8350,11]]},"1963":{"position":[[120,11]]},"2560":{"position":[[135,8]]},"2564":{"position":[[276,8]]},"2669":{"position":[[173,8]]},"2764":{"position":[[1426,11]]},"2795":{"position":[[1621,8]]}}}],["distinguish",{"_index":7955,"t":{"1900":{"position":[[774,11]]},"2016":{"position":[[774,11]]},"3078":{"position":[[95,11]]},"3299":{"position":[[4862,11]]},"3301":{"position":[[2893,11]]}}}],["distribut",{"_index":76,"t":{"10":{"position":[[55,14]]},"178":{"position":[[393,11],[658,11]]},"231":{"position":[[76,10]]},"469":{"position":[[324,12]]},"617":{"position":[[769,13]]},"740":{"position":[[569,11]]},"768":{"position":[[23,11],[101,11],[156,11],[381,11]]},"770":{"position":[[144,11]]},"796":{"position":[[250,12]]},"798":{"position":[[311,12]]},"846":{"position":[[118,14]]},"850":{"position":[[1363,12],[1465,12]]},"880":{"position":[[668,11]]},"888":{"position":[[1751,12]]},"895":{"position":[[285,13]]},"977":{"position":[[1709,11]]},"1480":{"position":[[118,14]]},"1484":{"position":[[1363,12],[1465,12]]},"1533":{"position":[[250,12]]},"1535":{"position":[[311,12]]},"1574":{"position":[[653,13]]},"1587":{"position":[[559,13]]},"1617":{"position":[[285,13]]},"1785":{"position":[[188,13]]},"1982":{"position":[[145,12]]},"2093":{"position":[[23,12]]},"2100":{"position":[[30,12],[175,13]]},"2126":{"position":[[135,14]]},"2235":{"position":[[424,14]]},"2302":{"position":[[0,11]]},"2342":{"position":[[285,13]]},"2592":{"position":[[778,12]]},"2890":{"position":[[39,13],[302,13]]},"2895":{"position":[[2581,13]]},"3011":{"position":[[14,12],[82,12],[156,12],[206,13],[595,12],[783,12],[859,12],[919,13],[1983,13]]},"3014":{"position":[[334,14]]},"3016":{"position":[[458,12]]},"3069":{"position":[[228,12]]},"3160":{"position":[[2615,12]]},"3178":{"position":[[418,11]]},"3182":{"position":[[316,11],[1802,10],[2317,12]]},"3184":{"position":[[1318,12],[1719,12],[2213,10],[2347,11],[2631,11],[2798,11]]},"3186":{"position":[[764,11],[865,11],[922,11],[976,11],[1009,11],[1105,11]]},"3191":{"position":[[412,11]]},"3195":{"position":[[378,11]]},"3197":{"position":[[241,12]]},"3199":{"position":[[49,12],[474,11],[797,11],[1012,12]]},"3201":{"position":[[20,12],[277,12]]},"3251":{"position":[[273,12]]},"3272":{"position":[[31,11],[133,11]]},"3301":{"position":[[2042,12],[2231,12],[2448,12],[4897,12]]},"3389":{"position":[[789,11]]},"3431":{"position":[[363,12]]},"3518":{"position":[[1834,12]]}}}],["distributor",{"_index":9540,"t":{"2895":{"position":[[1831,13]]}}}],["distro",{"_index":4148,"t":{"850":{"position":[[8901,7],[8947,7]]},"1484":{"position":[[8901,7],[8947,7]]}}}],["dito",{"_index":2811,"t":{"487":{"position":[[4410,6],[5857,6]]}}}],["dive",{"_index":8250,"t":{"2118":{"position":[[1397,4]]}}}],["diverg",{"_index":8425,"t":{"2253":{"position":[[65,8]]},"2283":{"position":[[493,7]]},"3080":{"position":[[724,10]]}}}],["divers",{"_index":4276,"t":{"880":{"position":[[259,7]]},"954":{"position":[[276,7]]},"956":{"position":[[1196,7]]},"3158":{"position":[[469,8]]},"3210":{"position":[[386,7]]},"3299":{"position":[[4916,9]]},"3301":{"position":[[2947,9]]}}}],["divid",{"_index":1867,"t":{"284":{"position":[[244,6]]},"740":{"position":[[206,7]]},"762":{"position":[[138,7]]}}}],["dm",{"_index":7990,"t":{"1913":{"position":[[1772,2]]},"2029":{"position":[[1772,2]]}}}],["dmesg",{"_index":7279,"t":{"1728":{"position":[[97,5]]}}}],["dmidecod",{"_index":4748,"t":{"1014":{"position":[[361,9]]}}}],["dn",{"_index":2416,"t":{"413":{"position":[[146,3]]},"442":{"position":[[65,3]]},"646":{"position":[[1727,3]]},"932":{"position":[[731,3]]},"1023":{"position":[[74,3]]},"1067":{"position":[[406,3],[5576,3]]},"1161":{"position":[[0,3],[1473,3]]},"1654":{"position":[[731,3]]},"1783":{"position":[[128,3]]},"1787":{"position":[[189,3],[215,3]]},"1794":{"position":[[1044,3],[1093,3],[1167,3]]},"2120":{"position":[[202,4]]},"2250":{"position":[[340,3]]},"2283":{"position":[[910,3]]},"2379":{"position":[[731,3]]}}}],["dnation",{"_index":279,"t":{"25":{"position":[[459,7]]},"27":{"position":[[559,7],[670,7],[856,7],[877,7],[1295,7],[1317,7]]},"2096":{"position":[[1939,7],[2274,7]]},"2098":{"position":[[3121,7],[3585,7]]},"2106":{"position":[[934,7]]},"2128":{"position":[[121,7]]},"2138":{"position":[[966,7]]},"2146":{"position":[[196,7]]},"2154":{"position":[[470,7]]},"2463":{"position":[[76,7]]},"3395":{"position":[[11,7],[54,7],[1443,7]]},"3397":{"position":[[37,7],[196,7]]},"3400":{"position":[[1485,7]]}}}],["dnationcloud",{"_index":8209,"t":{"2106":{"position":[[827,12],[898,12]]},"2128":{"position":[[14,12],[85,12]]},"2138":{"position":[[859,12],[930,12]]}}}],["dnationcloud/dn",{"_index":8172,"t":{"2096":{"position":[[1975,20],[2310,20]]},"2098":{"position":[[3157,20],[3621,20]]},"2106":{"position":[[970,20]]},"2128":{"position":[[157,20]]},"2138":{"position":[[1002,20]]}}}],["dnf",{"_index":99,"t":{"10":{"position":[[401,3]]},"374":{"position":[[411,3]]}}}],["dns.domain.cr",{"_index":8896,"t":{"2566":{"position":[[10498,21]]}}}],["dns.domain.delet",{"_index":8898,"t":{"2566":{"position":[[10541,20]]}}}],["dns.domain.exist",{"_index":8908,"t":{"2566":{"position":[[11094,17]]}}}],["dns.domain.upd",{"_index":8897,"t":{"2566":{"position":[[10520,20]]}}}],["dns_domain_trait",{"_index":8899,"t":{"2566":{"position":[[10570,18],[11124,18]]}}}],["dns_interfac",{"_index":4975,"t":{"1067":{"position":[[5040,14]]},"1163":{"position":[[371,13]]}}}],["dns_nameserv",{"_index":2704,"t":{"485":{"position":[[450,15]]},"660":{"position":[[133,15],[1812,15]]},"1585":{"position":[[3385,16]]},"1808":{"position":[[296,15]]}}}],["dnsauth",{"_index":4555,"t":{"932":{"position":[[800,8]]},"1654":{"position":[[800,8]]},"2379":{"position":[[800,8]]}}}],["dnsdist",{"_index":8420,"t":{"2248":{"position":[[1323,8]]}}}],["do",{"_index":812,"t":{"129":{"position":[[262,5]]},"263":{"position":[[48,5]]},"313":{"position":[[278,5]]},"428":{"position":[[1930,5]]},"552":{"position":[[248,5]]},"576":{"position":[[140,5]]},"583":{"position":[[230,5]]},"604":{"position":[[9605,5]]},"609":{"position":[[821,5]]},"786":{"position":[[680,5]]},"934":{"position":[[412,5]]},"1397":{"position":[[422,5]]},"1406":{"position":[[23,5]]},"1523":{"position":[[680,5]]},"1656":{"position":[[412,5]]},"2381":{"position":[[412,5]]},"2671":{"position":[[109,5]]},"2673":{"position":[[109,5]]},"3222":{"position":[[696,5]]},"3314":{"position":[[3247,7]]},"3493":{"position":[[49,6]]}}}],["doc",{"_index":637,"t":{"103":{"position":[[149,4]]},"105":{"position":[[12,4],[77,4],[249,4],[283,4],[292,4],[527,3],[718,4],[1374,4],[1963,4]]},"112":{"position":[[104,4],[112,5]]},"114":{"position":[[31,4],[177,7],[468,4]]},"116":{"position":[[5,3],[146,4]]},"118":{"position":[[5,3],[164,4]]},"153":{"position":[[79,4]]},"160":{"position":[[10,4]]},"162":{"position":[[88,5]]},"265":{"position":[[52,5]]},"274":{"position":[[27,5]]},"347":{"position":[[564,4]]},"393":{"position":[[1851,5]]},"419":{"position":[[160,4]]},"421":{"position":[[782,5],[1561,4]]},"423":{"position":[[204,4]]},"427":{"position":[[236,4]]},"447":{"position":[[806,4]]},"460":{"position":[[516,5]]},"462":{"position":[[163,4],[770,4],[906,4]]},"469":{"position":[[231,4]]},"471":{"position":[[535,5]]},"472":{"position":[[379,4],[1640,6]]},"487":{"position":[[3905,4],[5925,4]]},"489":{"position":[[590,4]]},"497":{"position":[[487,6]]},"509":{"position":[[489,5]]},"633":{"position":[[284,5]]},"1067":{"position":[[4766,5],[5454,5]]},"2071":{"position":[[489,4]]},"2098":{"position":[[1014,5],[2395,4]]},"2104":{"position":[[307,5]]},"2126":{"position":[[708,5]]},"2154":{"position":[[1331,4]]},"2233":{"position":[[575,3]]},"2426":{"position":[[756,3]]},"2491":{"position":[[4,4]]},"2526":{"position":[[598,4]]},"2656":{"position":[[8,4],[50,5],[68,4]]},"2660":{"position":[[201,5]]},"2675":{"position":[[82,4],[1033,4],[1188,4],[1231,4]]},"2824":{"position":[[19,4]]},"3518":{"position":[[705,4]]}}}],["doc/*.md",{"_index":751,"t":{"114":{"position":[[155,11]]}}}],["doc/sorce/not",{"_index":7182,"t":{"1678":{"position":[[2440,16]]}}}],["docker",{"_index":1734,"t":{"249":{"position":[[176,6]]},"272":{"position":[[156,6]]},"349":{"position":[[824,6]]},"383":{"position":[[132,6]]},"385":{"position":[[8,6]]},"417":{"position":[[841,6],[874,6]]},"617":{"position":[[139,6],[222,6]]},"1043":{"position":[[247,6],[852,6]]},"1055":{"position":[[3174,6]]},"1063":{"position":[[171,6],[277,6]]},"1167":{"position":[[3430,6]]},"1174":{"position":[[181,6]]},"1176":{"position":[[189,6]]},"1201":{"position":[[12,6]]},"1215":{"position":[[62,7]]},"1217":{"position":[[0,6],[502,6]]},"1234":{"position":[[2310,7],[2485,6]]},"1236":{"position":[[716,7]]},"1298":{"position":[[211,6],[306,6]]},"1315":{"position":[[277,6],[343,6],[408,6]]},"1344":{"position":[[311,6],[331,6],[525,6]]},"1347":{"position":[[1012,6],[1165,6],[1318,6]]},"1349":{"position":[[170,6],[253,6]]},"1360":{"position":[[1111,6]]},"1366":{"position":[[180,6]]},"1368":{"position":[[498,6],[999,6],[1466,6],[2142,6]]},"1582":{"position":[[242,6]]},"1690":{"position":[[1761,6],[1892,6],[2132,6],[2212,6]]},"1731":{"position":[[220,6],[354,6],[572,6],[675,6],[746,6],[943,6],[2369,7],[2769,7]]},"1738":{"position":[[390,6]]},"1743":{"position":[[109,6],[132,6],[208,6],[2172,6],[2197,6],[2263,6],[2337,6]]},"1758":{"position":[[387,6]]},"1764":{"position":[[4,6],[206,6],[237,6],[247,6],[360,6],[473,6],[586,6],[699,6],[812,6],[925,6],[1038,6],[1151,6],[1264,6],[1377,6],[1490,6],[1603,6],[1716,6],[1829,6],[1940,6],[2051,6],[2162,6],[2273,6],[2384,6],[2495,6],[2606,6],[2717,6],[2828,6],[2939,6],[3050,6],[3201,6],[3451,6],[3491,6],[3597,6],[3761,6],[3996,6],[4141,6],[4306,7],[4445,6],[4506,6],[4637,6]]},"1766":{"position":[[20,6],[332,6],[835,6],[1008,6],[1074,6],[1133,6],[1293,6],[1715,6],[1954,6]]},"1810":{"position":[[356,6]]},"1957":{"position":[[2068,6]]},"2100":{"position":[[805,7]]},"2118":{"position":[[1567,6]]},"2126":{"position":[[366,7]]},"2259":{"position":[[534,6],[612,7],[620,6],[667,6]]},"2292":{"position":[[652,6],[730,7],[738,6],[785,6]]},"2321":{"position":[[237,6],[343,6],[392,6],[510,6]]},"2330":{"position":[[646,6]]},"3061":{"position":[[358,6]]},"3150":{"position":[[326,6]]},"3204":{"position":[[267,6]]},"3216":{"position":[[274,7]]},"3218":{"position":[[6,6],[119,6],[299,6],[467,6],[848,6]]},"3220":{"position":[[493,6]]},"3222":{"position":[[25,6],[361,7]]},"3224":{"position":[[467,6],[896,6]]},"3301":{"position":[[6954,6],[6993,6],[7020,6]]}}}],["docker'",{"_index":9952,"t":{"3224":{"position":[[795,8]]}}}],["docker.io",{"_index":3332,"t":{"633":{"position":[[2808,9]]},"1743":{"position":[[99,9],[2160,9]]}}}],["docker:!manag",{"_index":7493,"t":{"1764":{"position":[[3771,17]]}}}],["docker[844686",{"_index":6414,"t":{"1321":{"position":[[790,15],[1020,15]]}}}],["docker[847573",{"_index":6384,"t":{"1321":{"position":[[133,15]]}}}],["docker[880827",{"_index":6400,"t":{"1321":{"position":[[406,15],[570,15],[1258,15]]}}}],["docker_allow_restart",{"_index":7504,"t":{"1766":{"position":[[1674,21],[1760,20]]}}}],["docker_allow_restart=fals",{"_index":7505,"t":{"1766":{"position":[[1964,26]]}}}],["docker_configure_proxi",{"_index":5985,"t":{"1201":{"position":[[150,23]]}}}],["docker_host",{"_index":962,"t":{"147":{"position":[[300,12],[434,13]]},"1701":{"position":[[290,12],[424,13]]}}}],["docker_hosts_default",{"_index":958,"t":{"147":{"position":[[79,21],[356,22],[452,21]]},"1701":{"position":[[77,21],[346,22],[442,21]]}}}],["docker_hosts_extra",{"_index":960,"t":{"147":{"position":[[231,18],[411,19],[476,18]]},"1701":{"position":[[221,18],[401,19],[466,18]]}}}],["docker_ignore_restart_groupnam",{"_index":7503,"t":{"1766":{"position":[[1241,32],[1366,31],[1563,31],[1614,32]]}}}],["docker_live_restor",{"_index":7499,"t":{"1766":{"position":[[454,20],[538,19],[603,20],[635,20]]}}}],["docker_log_driv",{"_index":6004,"t":{"1217":{"position":[[168,18],[314,18]]}}}],["docker_log_level",{"_index":6005,"t":{"1217":{"position":[[199,17],[560,17]]}}}],["docker_log_opt",{"_index":6006,"t":{"1217":{"position":[[222,16],[633,15]]}}}],["docker_namespac",{"_index":4872,"t":{"1055":{"position":[[3181,17]]}}}],["docker_proxy_http",{"_index":5986,"t":{"1201":{"position":[[179,18],[239,19],[263,17]]}}}],["docker_vers",{"_index":7457,"t":{"1764":{"position":[[53,14],[112,15],[3241,14]]}}}],["dockerfil",{"_index":10086,"t":{"3301":{"position":[[3797,11]]}}}],["dockerhub",{"_index":3325,"t":{"633":{"position":[[1803,9],[1969,9]]},"635":{"position":[[1138,10]]},"2405":{"position":[[723,9]]}}}],["dockerhub'",{"_index":3320,"t":{"633":{"position":[[682,11]]}}}],["docs.count",{"_index":6215,"t":{"1305":{"position":[[94,10]]}}}],["docs.delet",{"_index":6216,"t":{"1305":{"position":[[105,12]]}}}],["docs.package.json",{"_index":680,"t":{"105":{"position":[[1035,19]]},"114":{"position":[[77,18]]},"2675":{"position":[[1298,17]]}}}],["docs.scs.commun",{"_index":730,"t":{"107":{"position":[[114,19]]}}}],["docs/tool",{"_index":9048,"t":{"2656":{"position":[[183,11]]},"2660":{"position":[[12,11]]}}}],["document",{"_index":21,"t":{"4":{"position":[[224,13]]},"16":{"position":[[5,8]]},"18":{"position":[[161,8]]},"34":{"position":[[5,8]]},"60":{"position":[[128,13]]},"67":{"position":[[155,13]]},"73":{"position":[[30,14]]},"103":{"position":[[20,13],[247,13]]},"105":{"position":[[360,13]]},"107":{"position":[[51,13],[76,14]]},"109":{"position":[[27,13],[74,13],[100,13],[124,13]]},"112":{"position":[[31,13],[146,13],[170,13]]},"114":{"position":[[786,13]]},"133":{"position":[[111,14]]},"166":{"position":[[1034,14]]},"170":{"position":[[567,8]]},"178":{"position":[[898,11],[1758,8]]},"253":{"position":[[1610,13]]},"274":{"position":[[97,13],[217,10]]},"276":{"position":[[263,8]]},"290":{"position":[[559,13]]},"296":{"position":[[98,10]]},"300":{"position":[[64,9]]},"302":{"position":[[1362,9]]},"319":{"position":[[820,13]]},"321":{"position":[[1726,13]]},"323":{"position":[[725,13]]},"325":{"position":[[2209,13],[6306,14],[6329,13],[6354,13]]},"333":{"position":[[548,14]]},"366":{"position":[[1378,8]]},"377":{"position":[[38,8],[200,10]]},"379":{"position":[[14,8]]},"400":{"position":[[5,8]]},"407":{"position":[[182,14]]},"417":{"position":[[555,13]]},"432":{"position":[[182,14]]},"440":{"position":[[207,14]]},"523":{"position":[[148,8]]},"527":{"position":[[193,13]]},"588":{"position":[[153,13]]},"598":{"position":[[5,8],[317,8]]},"619":{"position":[[850,14]]},"698":{"position":[[66,13]]},"786":{"position":[[441,13],[1058,13]]},"800":{"position":[[375,13],[500,14]]},"895":{"position":[[683,10],[2089,14]]},"949":{"position":[[1056,8]]},"1008":{"position":[[26,13]]},"1063":{"position":[[458,10]]},"1065":{"position":[[92,10]]},"1073":{"position":[[236,11]]},"1091":{"position":[[12,13]]},"1100":{"position":[[18,13],[133,13]]},"1112":{"position":[[147,14]]},"1150":{"position":[[136,13]]},"1165":{"position":[[65,14]]},"1207":{"position":[[26,13]]},"1217":{"position":[[7,14],[509,14]]},"1219":{"position":[[65,10]]},"1221":{"position":[[26,13]]},"1224":{"position":[[147,10],[292,10]]},"1236":{"position":[[855,13]]},"1242":{"position":[[79,10]]},"1244":{"position":[[122,10]]},"1250":{"position":[[81,10]]},"1252":{"position":[[114,10]]},"1254":{"position":[[139,10]]},"1256":{"position":[[2512,14]]},"1292":{"position":[[329,14]]},"1294":{"position":[[52,10]]},"1317":{"position":[[31,10]]},"1383":{"position":[[176,13]]},"1395":{"position":[[18,13],[130,13],[383,13],[533,13]]},"1448":{"position":[[36,13]]},"1462":{"position":[[428,14]]},"1523":{"position":[[441,13],[1058,13]]},"1537":{"position":[[375,13],[500,14]]},"1574":{"position":[[626,13],[681,13]]},"1594":{"position":[[484,10],[518,14],[603,10],[637,14]]},"1617":{"position":[[683,10],[2089,14]]},"1671":{"position":[[1056,8]]},"1678":{"position":[[2587,11]]},"1693":{"position":[[103,14]]},"1726":{"position":[[18,13],[135,13]]},"1738":{"position":[[161,13]]},"1779":{"position":[[1069,13]]},"1785":{"position":[[161,13],[216,13]]},"1791":{"position":[[1149,13]]},"1810":{"position":[[134,13]]},"1827":{"position":[[187,8]]},"1865":{"position":[[834,8]]},"1898":{"position":[[101,10]]},"1908":{"position":[[2520,13]]},"1913":{"position":[[2053,8]]},"1955":{"position":[[272,13],[333,13],[525,13]]},"1957":{"position":[[1845,9]]},"1959":{"position":[[14,8]]},"2014":{"position":[[101,10]]},"2024":{"position":[[2520,13]]},"2035":{"position":[[19,13]]},"2138":{"position":[[275,13],[412,13],[513,13]]},"2188":{"position":[[116,10]]},"2196":{"position":[[989,13]]},"2200":{"position":[[142,14]]},"2212":{"position":[[877,9]]},"2220":{"position":[[108,14]]},"2222":{"position":[[130,13]]},"2224":{"position":[[89,10]]},"2229":{"position":[[1087,10]]},"2248":{"position":[[231,13]]},"2272":{"position":[[220,8]]},"2281":{"position":[[613,10]]},"2283":{"position":[[809,10]]},"2296":{"position":[[251,10]]},"2310":{"position":[[525,13],[702,13],[780,13]]},"2330":{"position":[[109,11]]},"2342":{"position":[[683,10],[2089,14]]},"2403":{"position":[[265,10]]},"2411":{"position":[[0,13]]},"2413":{"position":[[207,11]]},"2436":{"position":[[5,8]]},"2476":{"position":[[639,13]]},"2495":{"position":[[4,13],[47,8]]},"2518":{"position":[[308,9]]},"2524":{"position":[[86,10]]},"2526":{"position":[[84,14]]},"2548":{"position":[[366,8]]},"2619":{"position":[[137,8]]},"2621":{"position":[[78,10]]},"2623":{"position":[[29,8],[144,8],[464,8],[504,13],[539,9]]},"2625":{"position":[[8,9],[65,8],[308,8],[448,9],[499,9],[522,8],[627,8],[918,8],[1028,8],[1089,9],[1149,8],[1452,8],[1480,8],[1561,8],[1659,8],[2024,9],[2060,8],[2332,8],[2458,8],[2569,9],[2598,9],[2634,9],[2655,8]]},"2627":{"position":[[24,8],[108,8],[202,8],[551,9],[712,10],[936,9],[1087,9],[1185,10],[1234,8],[1340,9],[1663,9],[1717,9],[1815,10]]},"2629":{"position":[[24,8],[255,9]]},"2631":{"position":[[18,9],[49,9],[232,9],[294,8],[395,8],[418,8],[476,8],[792,9],[907,9],[1150,9],[1342,8],[1370,8],[1434,9],[1484,9],[1667,9],[1706,8],[1746,8],[1887,8],[1970,9],[2008,8],[2118,8],[2144,8],[2189,9],[2355,10],[2389,8]]},"2633":{"position":[[19,8],[191,9],[338,9]]},"2635":{"position":[[9,8],[94,8],[385,10],[437,10],[484,8],[608,8],[644,8],[700,8]]},"2637":{"position":[[9,8],[279,8],[372,9],[390,8]]},"2639":{"position":[[5,8],[131,9],[149,8]]},"2642":{"position":[[14,8],[169,10]]},"2644":{"position":[[60,9]]},"2647":{"position":[[162,9],[231,9],[452,8],[786,8],[960,9],[1095,9]]},"2649":{"position":[[5,8]]},"2658":{"position":[[115,8]]},"2660":{"position":[[350,9]]},"2663":{"position":[[252,13],[386,14]]},"2665":{"position":[[263,13],[420,13]]},"2667":{"position":[[27,13],[107,14],[135,13],[252,9],[280,13]]},"2669":{"position":[[55,13],[149,13]]},"2671":{"position":[[14,13]]},"2673":{"position":[[14,13],[380,8],[431,8],[1650,8]]},"2675":{"position":[[184,14],[199,13],[295,14],[521,14],[628,14],[687,13],[866,13],[1141,13]]},"2677":{"position":[[28,13],[159,10]]},"2684":{"position":[[190,8]]},"2692":{"position":[[16,8],[236,10],[358,8]]},"2735":{"position":[[759,9]]},"2779":{"position":[[193,8]]},"2797":{"position":[[290,8]]},"2799":{"position":[[134,9],[176,8]]},"2803":{"position":[[32,9]]},"2805":{"position":[[288,8]]},"2820":{"position":[[19,8]]},"2827":{"position":[[5,8]]},"2892":{"position":[[171,14]]},"2897":{"position":[[876,8]]},"2944":{"position":[[1755,11]]},"2977":{"position":[[284,8]]},"2999":{"position":[[524,8]]},"3021":{"position":[[295,9]]},"3023":{"position":[[62,9]]},"3048":{"position":[[30,8]]},"3057":{"position":[[144,10]]},"3059":{"position":[[251,13],[696,13],[961,14]]},"3097":{"position":[[438,9]]},"3105":{"position":[[270,13]]},"3130":{"position":[[4,9]]},"3135":{"position":[[362,13]]},"3137":{"position":[[245,8]]},"3145":{"position":[[5,8],[93,8]]},"3154":{"position":[[475,8]]},"3158":{"position":[[194,9],[209,8]]},"3162":{"position":[[97,9],[347,9]]},"3173":{"position":[[14,9]]},"3180":{"position":[[69,9]]},"3188":{"position":[[29,13]]},"3193":{"position":[[45,9]]},"3197":{"position":[[147,9],[567,8],[1464,9]]},"3247":{"position":[[690,8]]},"3249":{"position":[[236,8]]},"3251":{"position":[[2681,10]]},"3255":{"position":[[739,10]]},"3264":{"position":[[62,9]]},"3270":{"position":[[842,15],[1031,10],[1573,10],[2304,13]]},"3272":{"position":[[1157,13]]},"3274":{"position":[[703,14]]},"3276":{"position":[[853,13],[2795,14]]},"3293":{"position":[[263,8]]},"3297":{"position":[[306,8]]},"3299":{"position":[[51,8],[1501,8],[1676,8],[1913,8],[2403,8],[2940,8],[4081,8],[5218,10]]},"3301":{"position":[[876,8],[3186,9],[4128,10],[4701,8],[5722,9]]},"3303":{"position":[[156,9]]},"3310":{"position":[[393,8]]},"3312":{"position":[[418,14]]},"3316":{"position":[[1744,13],[1771,13]]},"3325":{"position":[[641,9],[789,8]]},"3331":{"position":[[8,10]]},"3336":{"position":[[89,11]]},"3338":{"position":[[137,8]]},"3370":{"position":[[364,8]]},"3415":{"position":[[459,8]]},"3434":{"position":[[364,8]]},"3455":{"position":[[62,9]]},"3477":{"position":[[295,10]]},"3482":{"position":[[2887,14],[2999,14],[3069,14],[3225,10]]},"3484":{"position":[[10,14],[122,14],[192,14],[348,10]]},"3487":{"position":[[48,9]]},"3497":{"position":[[8,10]]},"3514":{"position":[[8,10]]}}}],["documentation'",{"_index":7619,"t":{"1791":{"position":[[1473,15]]},"2665":{"position":[[579,15]]}}}],["docusauru",{"_index":667,"t":{"105":{"position":[[763,10],[1835,10]]},"127":{"position":[[79,11],[91,10]]},"131":{"position":[[171,10]]},"153":{"position":[[34,10]]},"2675":{"position":[[12,11],[97,10],[224,11]]}}}],["doe",{"_index":841,"t":{"131":{"position":[[544,4]]}}}],["doesn't",{"_index":1714,"t":{"247":{"position":[[2994,7],[3087,7]]},"317":{"position":[[211,7]]},"331":{"position":[[222,7],[382,7]]},"374":{"position":[[47,7]]},"436":{"position":[[105,7]]},"786":{"position":[[847,7]]},"1236":{"position":[[446,7]]},"1397":{"position":[[272,7]]},"1523":{"position":[[847,7]]},"1791":{"position":[[626,7]]},"2224":{"position":[[43,7]]},"2239":{"position":[[12,7]]},"2966":{"position":[[1960,7]]},"3227":{"position":[[574,7]]},"3238":{"position":[[914,7]]},"3282":{"position":[[70,7]]},"3286":{"position":[[333,7]]}}}],["dojo",{"_index":8156,"t":{"2085":{"position":[[22,4]]}}}],["dolor",{"_index":55,"t":{"6":{"position":[[12,5],[164,5]]}}}],["domain",{"_index":443,"t":{"46":{"position":[[75,6]]},"53":{"position":[[48,6]]},"302":{"position":[[1116,6],[1483,7]]},"740":{"position":[[606,7]]},"808":{"position":[[64,8]]},"813":{"position":[[83,6],[171,6],[206,6]]},"815":{"position":[[117,6],[141,6],[210,6]]},"817":{"position":[[362,8]]},"819":{"position":[[42,8],[94,6],[303,7],[363,6],[494,7],[521,6],[528,7],[539,6],[760,7],[1414,6],[1440,6],[2131,6],[2145,6],[2185,6],[2192,6],[2199,6],[2208,6],[2231,6],[2667,6],[2698,6],[2790,6],[3723,6],[3810,7],[3839,7],[3944,6],[4029,7],[4063,6],[4275,6],[4639,6],[4863,6],[5242,6],[5461,6],[6707,6],[6800,6],[6852,6],[6964,6],[7103,6],[7298,6],[7526,6],[7537,6],[8057,7],[8087,6],[8154,6],[8350,6]]},"821":{"position":[[428,6],[550,6],[557,7],[807,6],[833,6],[1538,6],[1545,6],[1552,6],[2003,6],[2042,6]]},"823":{"position":[[249,6]]},"905":{"position":[[528,6],[1199,6]]},"932":{"position":[[505,6],[756,6],[831,6]]},"934":{"position":[[1230,6]]},"1063":{"position":[[956,6]]},"1071":{"position":[[218,6],[229,6]]},"1108":{"position":[[384,8]]},"1150":{"position":[[163,6],[230,6],[526,6],[785,6],[5970,6],[6007,6],[6124,6],[6188,6],[6342,6],[6378,6],[6594,6],[6650,7],[7336,6],[7379,6],[8106,6],[8152,6],[9080,6],[9136,6],[9262,6],[9442,6],[9578,6],[9735,6],[10725,6],[10771,6],[12728,7],[12896,6],[13094,6],[13126,6],[13215,6]]},"1319":{"position":[[496,6]]},"1353":{"position":[[261,6]]},"1498":{"position":[[64,8]]},"1503":{"position":[[83,6],[171,6],[206,6]]},"1505":{"position":[[117,6],[141,6],[210,6]]},"1507":{"position":[[362,8]]},"1509":{"position":[[42,8],[94,6],[303,7],[363,6],[494,7],[521,6],[528,7],[539,6],[760,7],[1414,6],[1440,6],[2131,6],[2145,6],[2185,6],[2192,6],[2199,6],[2208,6],[2231,6],[2667,6],[2698,6],[2790,6],[3723,6],[3810,7],[3839,7],[3944,6],[4029,7],[4063,6],[4275,6],[4639,6],[4863,6],[5242,6],[5461,6],[6707,6],[6800,6],[6852,6],[6964,6],[7103,6],[7298,6],[7526,6],[7537,6],[8057,7],[8087,6],[8154,6],[8350,6]]},"1511":{"position":[[428,6],[550,6],[557,7],[807,6],[833,6],[1538,6],[1545,6],[1552,6],[2003,6],[2042,6]]},"1513":{"position":[[249,6]]},"1576":{"position":[[519,7],[595,7]]},"1587":{"position":[[1228,6]]},"1627":{"position":[[528,6],[1199,6]]},"1654":{"position":[[505,6],[756,6],[831,6]]},"1656":{"position":[[1230,6]]},"1779":{"position":[[2527,6],[2552,6]]},"1783":{"position":[[61,6],[102,6]]},"1787":{"position":[[42,8]]},"1789":{"position":[[955,7],[1034,7]]},"1951":{"position":[[259,8]]},"1955":{"position":[[135,7]]},"1957":{"position":[[119,6],[136,7],[173,8],[187,7],[301,7],[363,7],[415,7],[455,7],[543,6],[908,7],[958,6],[1388,7],[1433,7],[2452,7],[2644,7],[2675,6],[2813,6],[2971,6],[3237,7],[3734,7],[3908,7],[4022,8]]},"1959":{"position":[[978,6]]},"2037":{"position":[[16,6],[146,6],[239,7],[360,7],[434,6]]},"2039":{"position":[[146,6],[245,8],[268,7],[415,7],[446,6],[541,6],[642,7],[761,6]]},"2041":{"position":[[47,6]]},"2043":{"position":[[79,6]]},"2047":{"position":[[25,6],[60,6],[156,6],[230,6],[276,6],[519,6],[697,6],[822,6]]},"2051":{"position":[[54,6],[81,8],[96,6],[168,8],[215,6],[300,7],[332,6],[430,6],[444,7],[549,6],[574,7],[700,6],[724,6]]},"2053":{"position":[[24,6],[51,6],[165,6],[225,6],[277,6],[304,6],[365,6],[400,6],[459,6],[484,7],[496,6],[505,6],[638,6],[649,6],[720,6],[805,6],[812,7],[882,6],[928,7],[959,6],[1009,6],[1068,6],[1104,7],[1151,6],[1158,7]]},"2055":{"position":[[39,6],[46,7]]},"2057":{"position":[[59,6],[157,6],[164,7]]},"2059":{"position":[[53,6]]},"2061":{"position":[[25,7],[57,6],[64,7],[101,6],[246,7],[295,6],[306,6]]},"2063":{"position":[[28,7],[63,6],[70,7],[110,6],[264,7],[313,6],[324,6]]},"2065":{"position":[[26,7],[59,6],[66,7],[104,6],[252,7],[301,6],[312,6]]},"2067":{"position":[[30,6],[188,6],[282,6],[334,6],[558,6],[592,6],[599,7],[751,6],[816,6],[823,7],[1016,6],[1050,6],[1057,7],[1214,6],[1280,6],[1287,7]]},"2352":{"position":[[528,6],[1199,6]]},"2379":{"position":[[505,6],[756,6],[831,6]]},"2381":{"position":[[1230,6]]},"2472":{"position":[[2,6]]},"2476":{"position":[[50,7]]},"2489":{"position":[[29,7],[67,7]]},"2566":{"position":[[5906,7]]},"2574":{"position":[[670,6]]},"2820":{"position":[[268,7]]},"3103":{"position":[[904,6]]},"3109":{"position":[[273,8]]},"3184":{"position":[[2146,9]]},"3251":{"position":[[1842,8],[4407,7]]},"3255":{"position":[[1038,8]]},"3319":{"position":[[130,7]]},"3321":{"position":[[103,7]]},"3325":{"position":[[127,7],[327,7],[446,6],[585,7],[660,7],[798,7],[922,6],[1044,7],[1097,6],[1171,6],[1295,6],[1308,6],[1349,6],[1930,7],[1998,7]]},"3453":{"position":[[41,6],[145,7],[410,7],[472,8]]},"3455":{"position":[[323,6],[340,6],[512,7]]},"3457":{"position":[[164,7],[215,6],[245,6],[435,6],[645,7],[693,6]]},"3459":{"position":[[265,6],[443,6],[669,6],[712,6],[943,8]]},"3461":{"position":[[28,6],[164,7],[315,7],[366,6],[408,6],[445,7],[475,6],[603,7]]},"3463":{"position":[[4,6],[94,6],[105,6],[157,7],[224,6],[235,6],[328,6],[487,6],[789,6],[870,6],[890,6]]},"3465":{"position":[[91,7],[188,6],[544,6],[1391,6],[1557,7]]},"3468":{"position":[[136,6],[196,6],[247,7],[271,6],[343,6],[529,7],[570,6],[702,6],[742,6]]},"3472":{"position":[[376,6],[5813,6],[5850,6],[5967,6],[6031,6],[6151,6],[6187,6],[6403,6],[6459,7],[7145,6],[7188,6],[7915,6],[7961,6],[8889,6],[8945,6],[9071,6],[9251,6],[9387,6],[9544,6],[10534,6],[10580,6],[12532,6],[12766,6],[13272,6],[13687,6],[14149,6],[14193,6],[14249,7],[14342,6],[14438,7],[14512,6]]},"3475":{"position":[[233,6],[323,6]]},"3477":{"position":[[234,6]]},"3479":{"position":[[25,6],[112,7],[138,6],[221,6]]},"3482":{"position":[[25,6],[135,6],[185,7],[454,6],[522,6],[877,6],[917,7],[1048,6],[1110,6],[1201,6],[1260,6],[1475,6],[1587,6],[1899,6],[2044,6],[2160,6],[2258,6],[2293,7],[2481,6],[2566,6],[2602,7],[2623,7],[3044,6]]},"3484":{"position":[[167,6]]},"3518":{"position":[[2305,6]]}}}],["domain1.example.com",{"_index":5113,"t":{"1091":{"position":[[575,20]]}}}],["domain2.example.com",{"_index":5114,"t":{"1091":{"position":[[596,19]]}}}],["domain_id",{"_index":3880,"t":{"821":{"position":[[2108,9],[2354,9],[3660,9],[5001,9]]},"1150":{"position":[[12920,9]]},"1511":{"position":[[2108,9],[2354,9],[3660,9],[5001,9]]},"2566":{"position":[[5728,10]]}}}],["domain_id:%(target.domain.id)",{"_index":5531,"t":{"1150":{"position":[[2732,31],[2926,32],[3252,31],[3446,32],[3694,31],[3886,32],[4211,31],[4403,32]]},"3472":{"position":[[2575,31],[2769,32],[3095,31],[3289,32],[3537,31],[3729,32],[4054,31],[4246,32]]}}}],["domain_id:%(target.domain_id)",{"_index":5513,"t":{"1150":{"position":[[1212,32],[1824,32],[4599,32]]},"3472":{"position":[[1055,32],[1667,32],[4442,32]]}}}],["domain_id:%(target.group.domain_id)",{"_index":5532,"t":{"1150":{"position":[[2784,36],[2885,36],[3304,36],[3405,36],[3745,36],[3845,36],[4262,36],[4362,36],[4708,38],[4821,38],[4935,38],[5049,38],[5163,38],[5432,38],[5556,36],[5719,36],[5878,36]]},"3472":{"position":[[2627,36],[2728,36],[3147,36],[3248,36],[3588,36],[3688,36],[4105,36],[4205,36],[4551,38],[4664,38],[4778,38],[4892,38],[5006,38],[5275,38],[5399,36],[5562,36],[5721,36]]}}}],["domain_id:%(target.project.domain_id)",{"_index":5523,"t":{"1150":{"position":[[1933,39],[2087,40],[2205,40],[2323,40],[2632,39],[2825,39],[3152,39],[3345,39],[3595,39],[3786,39],[4112,39],[4303,39]]},"3472":{"position":[[1776,39],[1930,40],[2048,40],[2166,40],[2475,39],[2668,39],[2995,39],[3188,39],[3438,39],[3629,39],[3955,39],[4146,39]]}}}],["domain_id:%(target.role.domain_id)",{"_index":5533,"t":{"1150":{"position":[[2963,36],[3923,36],[4440,36]]},"3472":{"position":[[2806,36],[3766,36],[4283,36]]}}}],["domain_id:%(target.user.domain_id)",{"_index":5529,"t":{"1150":{"position":[[2447,36],[2592,35],[2692,35],[3112,35],[3212,35],[3555,35],[3654,35],[4072,35],[4171,35],[5287,36],[5597,37],[5760,37],[5919,37]]},"3472":{"position":[[2290,36],[2435,35],[2535,35],[2955,35],[3055,35],[3398,35],[3497,35],[3915,35],[4014,35],[5130,36],[5440,37],[5603,37],[5762,37]]}}}],["domain_manager_gr",{"_index":5607,"t":{"1150":{"position":[[9887,23]]},"3472":{"position":[[9696,23]]}}}],["domain_nam",{"_index":2832,"t":{"487":{"position":[[5747,16]]},"641":{"position":[[74,12]]},"646":{"position":[[97,11],[236,11],[1070,12],[1747,12]]},"1150":{"position":[[6601,12]]},"3472":{"position":[[6410,12]]}}}],["domainnam",{"_index":3867,"t":{"819":{"position":[[7598,10]]},"1509":{"position":[[7598,10]]}}}],["domains/groups/roles/project",{"_index":8973,"t":{"2574":{"position":[[593,28]]},"3518":{"position":[[2224,28]]}}}],["domains3",{"_index":10232,"t":{"3465":{"position":[[853,9]]}}}],["domains5",{"_index":10236,"t":{"3468":{"position":[[172,8]]}}}],["don't",{"_index":737,"t":{"109":{"position":[[148,5]]},"118":{"position":[[96,5]]},"166":{"position":[[1182,5]]},"187":{"position":[[465,5]]},"225":{"position":[[377,6]]},"247":{"position":[[3027,5]]},"319":{"position":[[467,5]]},"321":{"position":[[603,5]]},"325":{"position":[[1081,5]]},"355":{"position":[[225,5]]},"487":{"position":[[2795,5]]},"501":{"position":[[327,5]]},"552":{"position":[[684,5]]},"574":{"position":[[101,5]]},"586":{"position":[[343,5],[660,5]]},"590":{"position":[[995,5]]},"600":{"position":[[427,5]]},"615":{"position":[[1419,5]]},"627":{"position":[[694,5],[717,5]]},"646":{"position":[[1786,6]]},"669":{"position":[[287,5]]},"899":{"position":[[101,5]]},"905":{"position":[[1141,5]]},"907":{"position":[[30,5]]},"909":{"position":[[958,5]]},"917":{"position":[[192,5]]},"934":{"position":[[977,5]]},"947":{"position":[[875,5]]},"1055":{"position":[[2427,5]]},"1217":{"position":[[881,5]]},"1621":{"position":[[101,5]]},"1627":{"position":[[1141,5]]},"1629":{"position":[[30,5]]},"1631":{"position":[[958,5]]},"1639":{"position":[[192,5]]},"1656":{"position":[[977,5]]},"1669":{"position":[[875,5]]},"1865":{"position":[[147,5]]},"1878":{"position":[[82,5]]},"1927":{"position":[[147,5]]},"1957":{"position":[[1134,5]]},"1994":{"position":[[82,5]]},"2235":{"position":[[549,5]]},"2346":{"position":[[101,5]]},"2352":{"position":[[1141,5]]},"2354":{"position":[[30,5]]},"2356":{"position":[[958,5]]},"2364":{"position":[[192,5]]},"2381":{"position":[[977,5]]},"2394":{"position":[[875,5]]},"2697":{"position":[[1356,5],[1492,5]]},"2723":{"position":[[548,5]]},"2735":{"position":[[313,5]]},"2737":{"position":[[367,5]]},"2742":{"position":[[1255,5],[1391,5]]},"2762":{"position":[[561,5]]},"2764":{"position":[[1106,5]]},"2774":{"position":[[449,5]]},"2776":{"position":[[367,5]]},"2795":{"position":[[641,5]]},"2848":{"position":[[548,5]]},"2895":{"position":[[3473,5]]},"2966":{"position":[[2524,5]]},"3031":{"position":[[487,5]]},"3126":{"position":[[476,5]]},"3201":{"position":[[447,5]]},"3218":{"position":[[169,5]]}}}],["done",{"_index":1204,"t":{"174":{"position":[[551,4]]},"290":{"position":[[647,5]]},"313":{"position":[[132,4]]},"315":{"position":[[133,4]]},"325":{"position":[[1869,4]]},"383":{"position":[[198,5]]},"391":{"position":[[14,4]]},"436":{"position":[[1538,4]]},"507":{"position":[[121,4]]},"598":{"position":[[1425,5]]},"600":{"position":[[351,4]]},"604":{"position":[[4568,5]]},"609":{"position":[[4483,4]]},"617":{"position":[[465,4]]},"627":{"position":[[2642,4],[3935,4],[5048,5]]},"629":{"position":[[53,4]]},"635":{"position":[[238,4]]},"652":{"position":[[983,4]]},"662":{"position":[[1114,5]]},"790":{"position":[[245,4]]},"819":{"position":[[250,4]]},"876":{"position":[[455,4]]},"895":{"position":[[48,4]]},"903":{"position":[[3166,4]]},"913":{"position":[[1026,4],[1973,4],[2251,4],[3261,4]]},"915":{"position":[[801,4]]},"1063":{"position":[[555,4]]},"1069":{"position":[[47,4]]},"1089":{"position":[[2462,4]]},"1150":{"position":[[446,4]]},"1184":{"position":[[2484,5]]},"1213":{"position":[[346,4],[397,4]]},"1224":{"position":[[284,4]]},"1284":{"position":[[495,5],[585,5]]},"1286":{"position":[[1229,4]]},"1373":{"position":[[227,4]]},"1406":{"position":[[198,4]]},"1473":{"position":[[83,4]]},"1475":{"position":[[942,4],[947,4]]},"1509":{"position":[[250,4]]},"1527":{"position":[[245,4]]},"1574":{"position":[[531,4]]},"1608":{"position":[[51,4]]},"1617":{"position":[[48,4]]},"1625":{"position":[[3166,4]]},"1635":{"position":[[1026,4],[1973,4],[2251,4],[3261,4]]},"1637":{"position":[[801,4]]},"1764":{"position":[[3466,4]]},"1779":{"position":[[4173,4]]},"1785":{"position":[[66,4]]},"1820":{"position":[[506,5],[590,5]]},"1849":{"position":[[896,4]]},"1857":{"position":[[416,4]]},"1919":{"position":[[416,4]]},"1959":{"position":[[77,5],[719,4]]},"2033":{"position":[[1881,4]]},"2043":{"position":[[120,4]]},"2045":{"position":[[124,4]]},"2114":{"position":[[154,4]]},"2164":{"position":[[470,4]]},"2200":{"position":[[42,4]]},"2306":{"position":[[25,4],[281,4]]},"2338":{"position":[[25,4]]},"2342":{"position":[[48,4]]},"2350":{"position":[[3166,4]]},"2360":{"position":[[1026,4],[1973,4],[2251,4],[3261,4]]},"2362":{"position":[[801,4]]},"2707":{"position":[[169,4]]},"2735":{"position":[[548,4]]},"2752":{"position":[[169,4]]},"2774":{"position":[[684,4]]},"2815":{"position":[[1146,4]]},"2906":{"position":[[41,4],[64,6]]},"2947":{"position":[[2184,4]]},"2960":{"position":[[1588,4]]},"2966":{"position":[[2050,4],[3236,4]]},"3011":{"position":[[1292,4]]},"3016":{"position":[[541,4]]},"3053":{"position":[[749,4]]},"3055":{"position":[[328,6],[860,6]]},"3063":{"position":[[419,6],[1158,4]]},"3103":{"position":[[555,4]]},"3145":{"position":[[77,4]]},"3175":{"position":[[204,4]]},"3231":{"position":[[126,4]]},"3236":{"position":[[1669,4]]},"3238":{"position":[[762,4]]},"3251":{"position":[[5616,4]]},"3276":{"position":[[2287,4]]},"3284":{"position":[[380,4],[584,4]]},"3299":{"position":[[280,4]]},"3389":{"position":[[347,4]]},"3465":{"position":[[388,4]]}}}],["don´t",{"_index":936,"t":{"143":{"position":[[442,5]]}}}],["dot",{"_index":1476,"t":{"210":{"position":[[388,4]]},"317":{"position":[[923,3]]},"932":{"position":[[3034,4]]},"1444":{"position":[[500,3]]},"1654":{"position":[[3034,4]]},"2379":{"position":[[3034,4]]}}}],["doubl",{"_index":3237,"t":{"609":{"position":[[6035,6]]},"2813":{"position":[[1248,8]]},"3184":{"position":[[1025,6]]}}}],["down",{"_index":1678,"t":{"247":{"position":[[1223,4]]},"284":{"position":[[561,4]]},"391":{"position":[[907,4],[1171,4]]},"467":{"position":[[1887,4]]},"895":{"position":[[1203,4]]},"899":{"position":[[399,5]]},"909":{"position":[[490,5],[1524,5]]},"915":{"position":[[1216,4]]},"920":{"position":[[692,5]]},"1226":{"position":[[1983,4]]},"1344":{"position":[[326,4]]},"1347":{"position":[[671,4],[765,4],[859,4]]},"1362":{"position":[[1120,4]]},"1375":{"position":[[453,4]]},"1377":{"position":[[79,4],[454,4],[754,4],[1458,4]]},"1471":{"position":[[969,4]]},"1473":{"position":[[1364,5],[1637,4]]},"1617":{"position":[[1203,4]]},"1621":{"position":[[399,5]]},"1631":{"position":[[490,5],[1524,5]]},"1637":{"position":[[1216,4]]},"1642":{"position":[[692,5]]},"1731":{"position":[[620,4]]},"1791":{"position":[[1210,4]]},"1894":{"position":[[604,4]]},"1904":{"position":[[268,4]]},"1908":{"position":[[655,5]]},"1957":{"position":[[1254,4]]},"2010":{"position":[[604,4]]},"2020":{"position":[[268,4]]},"2024":{"position":[[655,5]]},"2051":{"position":[[765,4]]},"2108":{"position":[[309,4]]},"2130":{"position":[[305,4]]},"2342":{"position":[[1203,4]]},"2346":{"position":[[399,5]]},"2356":{"position":[[490,5],[1524,5]]},"2362":{"position":[[1216,4]]},"2367":{"position":[[692,5]]},"2781":{"position":[[82,4]]},"2944":{"position":[[1672,4]]},"2947":{"position":[[1110,4]]},"3184":{"position":[[1487,5]]},"3195":{"position":[[244,4]]},"3308":{"position":[[515,4]]},"3314":{"position":[[3497,4]]},"3370":{"position":[[207,5]]},"3434":{"position":[[207,5]]}}}],["downgrad",{"_index":8528,"t":{"2405":{"position":[[223,11]]}}}],["download",{"_index":146,"t":{"10":{"position":[[1391,8]]},"114":{"position":[[714,12]]},"393":{"position":[[743,11],[828,8],[935,8],[1069,8]]},"396":{"position":[[73,8],[212,10]]},"557":{"position":[[109,8]]},"568":{"position":[[49,8]]},"604":{"position":[[1794,8],[10431,8],[10551,8],[10614,11],[10742,8]]},"609":{"position":[[294,10]]},"850":{"position":[[1860,8],[3075,8],[3995,8],[5340,8],[6255,8],[7023,8],[7841,8]]},"905":{"position":[[881,8]]},"1146":{"position":[[48,8],[117,9],[434,10],[576,10]]},"1184":{"position":[[1354,8]]},"1203":{"position":[[31,10]]},"1232":{"position":[[527,8]]},"1234":{"position":[[209,8]]},"1484":{"position":[[1860,8],[3075,8],[3995,8],[5340,8],[6255,8],[7023,8],[7841,8]]},"1569":{"position":[[21,8],[280,8]]},"1627":{"position":[[881,8]]},"1743":{"position":[[482,8]]},"1747":{"position":[[443,10]]},"1785":{"position":[[550,10],[632,8]]},"1789":{"position":[[113,9]]},"1835":{"position":[[368,11]]},"1878":{"position":[[180,10],[1047,9]]},"1880":{"position":[[916,8],[970,8]]},"1888":{"position":[[170,10]]},"1890":{"position":[[507,8],[561,8]]},"1892":{"position":[[1335,8],[1389,8]]},"1894":{"position":[[15,10],[140,11],[314,10]]},"1913":{"position":[[516,8],[712,8],[1055,10]]},"1994":{"position":[[180,10],[1047,9]]},"1996":{"position":[[916,8],[970,8]]},"2004":{"position":[[170,10]]},"2006":{"position":[[507,8],[561,8]]},"2008":{"position":[[1335,8],[1389,8]]},"2010":{"position":[[15,10],[140,11],[314,10]]},"2029":{"position":[[516,8],[712,8],[1055,10]]},"2352":{"position":[[881,8]]},"2897":{"position":[[90,11],[194,12],[530,8]]},"3160":{"position":[[2628,9]]},"3301":{"position":[[2103,8]]}}}],["downloads/mi",{"_index":7403,"t":{"1747":{"position":[[514,14]]}}}],["downsampl",{"_index":8309,"t":{"2150":{"position":[[317,11],[513,11],[601,11],[1264,12]]},"2152":{"position":[[34,12],[136,12],[628,10]]}}}],["downsample.concurr",{"_index":8320,"t":{"2150":{"position":[[1206,22]]}}}],["downsample.concurrency=3",{"_index":8308,"t":{"2150":{"position":[[134,24]]}}}],["downsid",{"_index":9688,"t":{"3011":{"position":[[1455,8]]},"3103":{"position":[[687,9]]},"3109":{"position":[[1070,9],[3093,9]]},"3423":{"position":[[474,8]]}}}],["downstream",{"_index":1235,"t":{"176":{"position":[[875,10]]},"180":{"position":[[58,10],[306,10]]},"2235":{"position":[[797,10]]},"3251":{"position":[[651,10]]},"3299":{"position":[[4814,10]]},"3423":{"position":[[575,10]]}}}],["downtim",{"_index":1947,"t":{"298":{"position":[[920,8]]},"652":{"position":[[764,8]]},"888":{"position":[[1893,8]]},"977":{"position":[[1565,9]]},"1822":{"position":[[137,8],[164,8]]},"2067":{"position":[[1672,8]]},"2069":{"position":[[345,8]]},"2947":{"position":[[394,9]]},"3206":{"position":[[882,8]]},"3208":{"position":[[1717,9]]},"3214":{"position":[[465,8]]},"3216":{"position":[[36,9]]},"3266":{"position":[[469,9]]}}}],["dox",{"_index":1689,"t":{"247":{"position":[[1574,11]]}}}],["dozen",{"_index":3246,"t":{"615":{"position":[[198,5]]},"648":{"position":[[601,6]]},"920":{"position":[[308,6]]},"1642":{"position":[[308,6]]},"2367":{"position":[[308,6]]}}}],["dpdk_tunnel_interfac",{"_index":5808,"t":{"1163":{"position":[[409,21]]}}}],["dpu",{"_index":9701,"t":{"3014":{"position":[[756,5]]}}}],["draft",{"_index":5498,"t":{"1150":{"position":[[34,5]]},"2035":{"position":[[75,5]]},"2283":{"position":[[100,5]]},"2472":{"position":[[57,5]]},"2522":{"position":[[608,6]]},"2526":{"position":[[393,6],[498,5]]},"2528":{"position":[[107,5]]},"2530":{"position":[[371,5]]},"2532":{"position":[[64,5]]},"2534":{"position":[[164,5]]},"2544":{"position":[[400,6],[505,5]]},"2552":{"position":[[69,5]]},"2556":{"position":[[69,5]]},"2558":{"position":[[62,5]]},"2572":{"position":[[62,5]]},"2574":{"position":[[373,6],[478,5]]},"2578":{"position":[[62,5]]},"2580":{"position":[[69,5]]},"2582":{"position":[[69,5]]},"2588":{"position":[[62,5]]},"2590":{"position":[[69,5]]},"2592":{"position":[[356,6],[461,5]]},"2596":{"position":[[62,5]]},"2598":{"position":[[69,5]]},"2600":{"position":[[62,5]]},"2602":{"position":[[388,6],[493,5]]},"2604":{"position":[[69,5]]},"2606":{"position":[[69,5]]},"2608":{"position":[[69,5]]},"2610":{"position":[[69,5]]},"2612":{"position":[[69,5]]},"2614":{"position":[[69,5]]},"2625":{"position":[[1871,6]]},"2629":{"position":[[78,6],[549,5]]},"2631":{"position":[[1382,5],[2412,5]]},"2647":{"position":[[279,5]]},"2651":{"position":[[553,5]]},"2653":{"position":[[69,5]]},"2660":{"position":[[210,8],[393,6]]},"2711":{"position":[[967,7]]},"2799":{"position":[[32,6]]},"2815":{"position":[[336,5]]},"2817":{"position":[[86,6]]},"2856":{"position":[[945,7]]},"3119":{"position":[[65,5]]},"3431":{"position":[[215,5],[221,5]]},"3518":{"position":[[480,6],[591,5]]}}}],["dragon",{"_index":4822,"t":{"1039":{"position":[[221,6],[374,6],[527,6],[680,6]]},"1043":{"position":[[349,6],[671,6]]},"1234":{"position":[[1069,6]]},"1256":{"position":[[268,7],[835,6]]},"1264":{"position":[[120,6]]},"1317":{"position":[[6696,6]]},"1569":{"position":[[1578,6]]},"1571":{"position":[[1522,6]]}}}],["dragon@ip_from_your_serv",{"_index":7010,"t":{"1569":{"position":[[1753,26]]},"1571":{"position":[[1697,26]]}}}],["dragon@ip_from_your_server:/home/dragon/wireguard",{"_index":7027,"t":{"1574":{"position":[[388,49]]}}}],["dragon@manag",{"_index":7054,"t":{"1585":{"position":[[711,17],[1480,17]]}}}],["dragon@testb",{"_index":6112,"t":{"1256":{"position":[[3372,14]]},"1333":{"position":[[138,14],[282,14]]},"1339":{"position":[[135,14]]}}}],["dragonfli",{"_index":10069,"t":{"3299":{"position":[[2609,9],[2619,9],[2803,11]]},"3301":{"position":[[96,10],[780,9],[1603,10],[1632,9],[2332,9],[2500,9],[4972,10],[5227,9],[5753,9],[6871,9],[7420,10]]},"3305":{"position":[[47,9]]}}}],["dragonfly'",{"_index":10083,"t":{"3301":{"position":[[2432,11]]}}}],["drastic",{"_index":9501,"t":{"2872":{"position":[[1308,11]]}}}],["drawback",{"_index":9929,"t":{"3204":{"position":[[444,9]]},"3301":{"position":[[3574,8]]}}}],["dri",{"_index":1509,"t":{"219":{"position":[[103,5]]},"576":{"position":[[5,3],[29,3]]},"792":{"position":[[240,3]]},"815":{"position":[[225,3]]},"821":{"position":[[568,3],[1575,3],[1861,3]]},"850":{"position":[[251,3]]},"1484":{"position":[[251,3]]},"1505":{"position":[[225,3]]},"1511":{"position":[[568,3],[1575,3],[1861,3]]},"1529":{"position":[[240,3]]},"1715":{"position":[[49,3]]}}}],["drill",{"_index":8216,"t":{"2108":{"position":[[303,5]]},"2130":{"position":[[299,5]]}}}],["drink",{"_index":1435,"t":{"204":{"position":[[209,6]]},"223":{"position":[[230,6]]},"225":{"position":[[351,7]]},"227":{"position":[[394,7]]},"229":{"position":[[251,6]]},"231":{"position":[[226,6]]}}}],["drive",{"_index":2838,"t":{"489":{"position":[[62,5]]},"1419":{"position":[[1028,5],[1052,5]]},"1587":{"position":[[802,5]]},"2035":{"position":[[159,5]]},"2733":{"position":[[471,6]]},"2772":{"position":[[471,6]]},"2854":{"position":[[472,6]]},"2872":{"position":[[143,6]]},"2960":{"position":[[33,7]]},"3021":{"position":[[22,5]]},"3023":{"position":[[120,5]]}}}],["drive'",{"_index":7014,"t":{"1571":{"position":[[530,7]]}}}],["driven",{"_index":2007,"t":{"321":{"position":[[190,6],[862,6],[986,6],[1078,6],[1128,6],[1183,6],[1252,6],[1333,6],[1420,6]]},"513":{"position":[[1452,6]]},"2079":{"position":[[142,6]]},"2514":{"position":[[47,6]]}}}],["driver",{"_index":2581,"t":{"465":{"position":[[154,6],[396,7]]},"471":{"position":[[1233,7]]},"604":{"position":[[10049,6]]},"899":{"position":[[35,6],[586,6]]},"901":{"position":[[70,6],[170,6]]},"903":{"position":[[267,6],[678,6],[1907,6],[2208,6],[2595,6],[2679,7],[2792,7],[2933,6],[3317,6],[4016,6]]},"905":{"position":[[1832,6]]},"907":{"position":[[342,6]]},"917":{"position":[[61,6]]},"920":{"position":[[434,6]]},"936":{"position":[[4,6]]},"945":{"position":[[145,6],[271,6]]},"956":{"position":[[1021,8],[1087,8],[1141,8]]},"1130":{"position":[[140,6]]},"1217":{"position":[[273,6],[372,6],[474,7],[601,6]]},"1234":{"position":[[2543,7]]},"1294":{"position":[[1042,6],[1080,7]]},"1566":{"position":[[64,6],[152,7]]},"1621":{"position":[[35,6],[586,6]]},"1623":{"position":[[70,6],[170,6]]},"1625":{"position":[[267,6],[678,6],[1907,6],[2208,6],[2595,6],[2679,7],[2792,7],[2933,6],[3317,6],[4016,6]]},"1627":{"position":[[1832,6]]},"1629":{"position":[[342,6]]},"1639":{"position":[[61,6]]},"1642":{"position":[[434,6]]},"1658":{"position":[[4,6]]},"1667":{"position":[[145,6],[271,6]]},"1749":{"position":[[638,7],[803,7]]},"1779":{"position":[[5974,6]]},"1822":{"position":[[854,6],[892,7],[1205,6],[1243,7]]},"2346":{"position":[[35,6],[586,6]]},"2348":{"position":[[70,6],[170,6]]},"2350":{"position":[[267,6],[678,6],[1907,6],[2208,6],[2595,6],[2679,7],[2792,7],[2933,6],[3317,6],[4016,6]]},"2352":{"position":[[1832,6]]},"2354":{"position":[[342,6]]},"2364":{"position":[[61,6]]},"2367":{"position":[[434,6]]},"2383":{"position":[[4,6]]},"2392":{"position":[[145,6],[271,6]]},"2656":{"position":[[266,6]]},"3003":{"position":[[319,7],[495,6]]},"3160":{"position":[[1270,7]]},"3301":{"position":[[5295,7]]}}}],["driver.html",{"_index":5478,"t":{"1130":{"position":[[330,11]]}}}],["driverbyte=driver_ok",{"_index":7284,"t":{"1728":{"position":[[186,20]]}}}],["drop",{"_index":845,"t":{"131":{"position":[[581,4]]},"615":{"position":[[786,5]]},"2033":{"position":[[1958,7]]},"2292":{"position":[[234,7]]},"3124":{"position":[[292,7]]}}}],["dropdown",{"_index":4581,"t":{"932":{"position":[[2634,8]]},"1654":{"position":[[2634,8]]},"2379":{"position":[[2634,8]]}}}],["drumbeat",{"_index":1423,"t":{"202":{"position":[[358,9]]}}}],["drwxr",{"_index":6194,"t":{"1298":{"position":[[401,5],[445,5]]}}}],["dsr",{"_index":2920,"t":{"507":{"position":[[601,4]]}}}],["dst",{"_index":4335,"t":{"903":{"position":[[1050,3],[1352,3]]},"1625":{"position":[[1050,3],[1352,3]]},"1863":{"position":[[622,3],[793,3],[967,3]]},"1925":{"position":[[622,3],[793,3],[967,3]]},"2350":{"position":[[1050,3],[1352,3]]}}}],["dual",{"_index":4690,"t":{"982":{"position":[[683,4]]},"984":{"position":[[550,4]]},"986":{"position":[[289,4]]},"988":{"position":[[397,4]]},"990":{"position":[[451,4]]}}}],["due",{"_index":1286,"t":{"178":{"position":[[1957,4]]},"251":{"position":[[89,3]]},"298":{"position":[[720,3]]},"372":{"position":[[756,3]]},"604":{"position":[[3093,3],[5891,3]]},"665":{"position":[[15,3]]},"778":{"position":[[251,3]]},"1344":{"position":[[27,3]]},"1404":{"position":[[295,3]]},"1444":{"position":[[730,3],[779,3]]},"1566":{"position":[[97,3]]},"1766":{"position":[[205,3]]},"1803":{"position":[[106,3]]},"1833":{"position":[[1249,3]]},"2039":{"position":[[0,3]]},"2233":{"position":[[619,3]]},"2310":{"position":[[342,3]]},"2502":{"position":[[588,3]]},"2586":{"position":[[324,3]]},"2813":{"position":[[1535,3]]},"2895":{"position":[[1487,3]]},"2966":{"position":[[2113,3],[3367,3]]},"3014":{"position":[[981,3]]},"3141":{"position":[[89,3]]},"3184":{"position":[[912,3],[1052,3]]},"3186":{"position":[[1467,3]]},"3195":{"position":[[88,3]]},"3197":{"position":[[279,3]]},"3206":{"position":[[725,3]]},"3214":{"position":[[384,3]]},"3218":{"position":[[570,3]]},"3220":{"position":[[352,3]]},"3227":{"position":[[0,3],[226,3]]},"3262":{"position":[[138,3]]},"3270":{"position":[[145,3],[1374,3]]},"3280":{"position":[[162,3]]},"3301":{"position":[[608,3]]},"3380":{"position":[[243,4]]},"3459":{"position":[[291,3]]},"3465":{"position":[[234,3],[669,3]]}}}],["dumb",{"_index":6471,"t":{"1337":{"position":[[171,4]]},"1360":{"position":[[1231,5],[1359,5],[1484,5],[1619,5],[1764,5],[1909,5],[2046,5],[2179,5],[2308,5],[2432,5],[2573,5],[2811,5],[2919,5],[3029,5]]}}}],["dummi",{"_index":5115,"t":{"1094":{"position":[[0,5]]},"2321":{"position":[[414,5]]}}}],["dummy0",{"_index":5119,"t":{"1094":{"position":[[164,6]]},"1098":{"position":[[337,6],[463,6],[537,7]]}}}],["dump",{"_index":6899,"t":{"1438":{"position":[[85,4],[100,4]]},"1444":{"position":[[53,4],[288,4]]},"1452":{"position":[[22,4]]}}}],["duplic",{"_index":7944,"t":{"1896":{"position":[[194,10]]},"2012":{"position":[[194,10]]},"2667":{"position":[[181,12]]},"2727":{"position":[[758,10]]},"2766":{"position":[[958,10]]},"2852":{"position":[[1104,10]]},"3178":{"position":[[403,10]]},"3186":{"position":[[440,9]]},"3191":{"position":[[397,10]]},"3197":{"position":[[550,12]]},"3343":{"position":[[161,12]]}}}],["duplo",{"_index":1501,"t":{"219":{"position":[[50,6]]}}}],["durat",{"_index":6256,"t":{"1317":{"position":[[1017,8],[1831,8],[2236,8],[5982,8],[6430,8]]},"1402":{"position":[[26,10]]},"2688":{"position":[[1333,8]]},"2879":{"position":[[264,8]]}}}],["duration_avg",{"_index":6352,"t":{"1317":{"position":[[7224,12]]}}}],["duration_tot",{"_index":6351,"t":{"1317":{"position":[[7207,14]]}}}],["dure",{"_index":28,"t":{"4":{"position":[[317,6]]},"421":{"position":[[986,6]]},"427":{"position":[[1015,6]]},"487":{"position":[[1170,6]]},"530":{"position":[[530,6]]},"586":{"position":[[242,6]]},"627":{"position":[[1558,6]]},"641":{"position":[[271,6]]},"650":{"position":[[1254,6],[2108,6]]},"656":{"position":[[410,6]]},"810":{"position":[[46,6]]},"915":{"position":[[744,6]]},"1014":{"position":[[193,6]]},"1061":{"position":[[908,6]]},"1234":{"position":[[1087,6],[1134,6],[2648,6]]},"1473":{"position":[[38,6]]},"1500":{"position":[[46,6]]},"1571":{"position":[[1798,6]]},"1637":{"position":[[744,6]]},"1674":{"position":[[574,6]]},"1764":{"position":[[3627,6]]},"1766":{"position":[[1023,6]]},"1779":{"position":[[2892,6]]},"1859":{"position":[[164,6]]},"1861":{"position":[[218,6]]},"1865":{"position":[[297,6]]},"1921":{"position":[[164,6]]},"1923":{"position":[[218,6]]},"1927":{"position":[[297,6]]},"1951":{"position":[[682,6]]},"2196":{"position":[[257,6]]},"2283":{"position":[[165,6]]},"2362":{"position":[[744,6]]},"2484":{"position":[[0,6]]},"2504":{"position":[[729,6]]},"2510":{"position":[[71,6],[331,6]]},"2623":{"position":[[314,6]]},"2627":{"position":[[974,6]]},"2667":{"position":[[262,6]]},"3182":{"position":[[1920,6],[2407,6]]},"3208":{"position":[[1517,6]]},"3236":{"position":[[1493,6]]},"3270":{"position":[[778,6]]},"3276":{"position":[[1211,6]]},"3321":{"position":[[34,6]]},"3325":{"position":[[2774,6]]},"3376":{"position":[[158,6]]},"3389":{"position":[[653,6]]},"3482":{"position":[[483,6]]}}}],["dvr",{"_index":8466,"t":{"2302":{"position":[[28,5]]}}}],["dynam",{"_index":3675,"t":{"750":{"position":[[393,11]]},"1186":{"position":[[88,7],[113,7],[149,7],[193,7]]},"1859":{"position":[[127,11]]},"1921":{"position":[[127,11]]},"1963":{"position":[[391,7],[434,7]]},"2083":{"position":[[54,7]]},"2495":{"position":[[99,7]]},"3003":{"position":[[277,7],[513,11]]},"3160":{"position":[[634,7]]},"3353":{"position":[[288,12]]}}}],["e",{"_index":2288,"t":{"381":{"position":[[1459,2],[1613,5]]},"913":{"position":[[3187,1]]},"920":{"position":[[796,2]]},"1063":{"position":[[291,1],[318,1]]},"1080":{"position":[[321,1]]},"1114":{"position":[[1827,1],[2006,1]]},"1224":{"position":[[2927,1],[3744,1]]},"1273":{"position":[[306,1]]},"1275":{"position":[[30,1],[56,1]]},"1277":{"position":[[32,1],[65,1]]},"1279":{"position":[[309,1],[331,1],[500,1]]},"1290":{"position":[[326,1]]},"1292":{"position":[[660,1]]},"1298":{"position":[[166,1]]},"1342":{"position":[[629,1]]},"1358":{"position":[[235,1]]},"1368":{"position":[[196,1],[308,1]]},"1383":{"position":[[89,1]]},"1430":{"position":[[1399,1],[1420,1]]},"1585":{"position":[[3492,1]]},"1635":{"position":[[3187,1]]},"1642":{"position":[[796,2]]},"1760":{"position":[[33,1]]},"1764":{"position":[[4014,1]]},"1766":{"position":[[1962,1]]},"1825":{"position":[[464,1]]},"2360":{"position":[[3187,1]]},"2367":{"position":[[796,2]]},"2735":{"position":[[478,1],[492,1],[505,1],[589,1],[603,1],[616,1]]},"2774":{"position":[[614,1],[628,1],[641,1],[725,1],[739,1],[752,1]]},"3021":{"position":[[66,3]]},"3301":{"position":[[6046,1]]},"3314":{"position":[[1633,1]]}}}],["e.g",{"_index":229,"t":{"18":{"position":[[243,5]]},"178":{"position":[[1985,4]]},"187":{"position":[[617,4]]},"247":{"position":[[1866,4]]},"288":{"position":[[190,6],[408,6]]},"302":{"position":[[1617,4]]},"374":{"position":[[565,6],[911,6]]},"407":{"position":[[124,4]]},"409":{"position":[[400,5]]},"417":{"position":[[372,4]]},"421":{"position":[[158,5]]},"428":{"position":[[1655,5]]},"432":{"position":[[124,4]]},"436":{"position":[[359,4],[1093,4]]},"447":{"position":[[113,5]]},"462":{"position":[[1167,5],[1362,5]]},"472":{"position":[[2079,4]]},"485":{"position":[[1037,3]]},"487":{"position":[[5331,5]]},"495":{"position":[[693,4],[1574,4]]},"499":{"position":[[1501,4]]},"513":{"position":[[1871,4],[2011,5]]},"530":{"position":[[601,5],[774,5]]},"604":{"position":[[3173,5],[5391,4],[6069,5],[6362,5],[7428,4],[7647,5],[9085,4],[9357,5],[9905,4]]},"609":{"position":[[2196,4],[2415,5],[4998,4],[5270,5]]},"633":{"position":[[342,5],[677,4],[2006,4],[2104,4],[3113,4]]},"641":{"position":[[565,4]]},"646":{"position":[[1816,4]]},"650":{"position":[[390,5],[1625,5],[2541,4]]},"652":{"position":[[242,4]]},"660":{"position":[[16,5]]},"662":{"position":[[145,4]]},"742":{"position":[[612,4]]},"772":{"position":[[486,4],[989,4]]},"897":{"position":[[266,5]]},"909":{"position":[[293,5]]},"911":{"position":[[438,5]]},"917":{"position":[[122,4]]},"920":{"position":[[1059,4]]},"932":{"position":[[4117,4]]},"949":{"position":[[161,4]]},"1067":{"position":[[2155,4]]},"1080":{"position":[[164,4]]},"1120":{"position":[[826,4]]},"1124":{"position":[[707,5]]},"1167":{"position":[[2458,4]]},"1234":{"position":[[540,5],[902,4]]},"1240":{"position":[[352,5]]},"1286":{"position":[[2496,5]]},"1400":{"position":[[377,4]]},"1406":{"position":[[547,5]]},"1466":{"position":[[91,4]]},"1619":{"position":[[266,5]]},"1631":{"position":[[293,5]]},"1633":{"position":[[438,5]]},"1639":{"position":[[122,4]]},"1642":{"position":[[1059,4]]},"1654":{"position":[[4117,4]]},"1671":{"position":[[161,4]]},"1674":{"position":[[597,5]]},"1676":{"position":[[102,5]]},"1678":{"position":[[2620,4]]},"1766":{"position":[[1168,5]]},"1783":{"position":[[314,5]]},"1803":{"position":[[66,5]]},"1825":{"position":[[164,4]]},"1841":{"position":[[311,5]]},"1880":{"position":[[54,5]]},"1913":{"position":[[1894,5]]},"1957":{"position":[[708,4],[1116,4],[2824,5]]},"1963":{"position":[[259,4]]},"1972":{"position":[[203,4]]},"1978":{"position":[[455,4]]},"1996":{"position":[[54,5]]},"2029":{"position":[[1894,5]]},"2096":{"position":[[1269,4]]},"2098":{"position":[[2478,4]]},"2116":{"position":[[840,4],[989,4]]},"2118":{"position":[[1106,5],[1897,5],[2134,5],[2597,5]]},"2142":{"position":[[131,4]]},"2176":{"position":[[1273,4]]},"2214":{"position":[[665,4]]},"2250":{"position":[[742,4]]},"2283":{"position":[[1241,4]]},"2344":{"position":[[266,5]]},"2356":{"position":[[293,5]]},"2358":{"position":[[438,5]]},"2364":{"position":[[122,4]]},"2367":{"position":[[1059,4]]},"2379":{"position":[[4117,4]]},"2396":{"position":[[161,4]]},"2486":{"position":[[122,5]]},"2504":{"position":[[167,4]]},"2625":{"position":[[2069,6]]},"2660":{"position":[[461,4]]},"2688":{"position":[[372,6]]},"2707":{"position":[[128,5]]},"2711":{"position":[[1461,4]]},"2719":{"position":[[890,4]]},"2727":{"position":[[682,5]]},"2731":{"position":[[985,4]]},"2752":{"position":[[128,5]]},"2758":{"position":[[888,4]]},"2766":{"position":[[882,5]]},"2770":{"position":[[985,4]]},"2797":{"position":[[322,5]]},"2805":{"position":[[61,4]]},"2842":{"position":[[134,5]]},"2852":{"position":[[1028,5]]},"2856":{"position":[[1439,4]]},"2860":{"position":[[946,4]]},"2870":{"position":[[289,5]]},"2874":{"position":[[1044,5]]},"2890":{"position":[[63,4]]},"2895":{"position":[[395,5],[2092,4]]},"2897":{"position":[[680,4]]},"2901":{"position":[[103,5],[2059,4]]},"2933":{"position":[[992,4]]},"2944":{"position":[[624,4]]},"2947":{"position":[[925,5]]},"2949":{"position":[[386,4],[1035,5]]},"2977":{"position":[[316,5]]},"3067":{"position":[[99,5]]},"3128":{"position":[[552,6]]},"3150":{"position":[[140,4],[291,4]]},"3160":{"position":[[170,5],[904,4],[1219,4],[2398,4],[2551,5],[2884,4]]},"3182":{"position":[[1762,5]]},"3186":{"position":[[856,4]]},"3201":{"position":[[435,4]]},"3231":{"position":[[227,4]]},"3245":{"position":[[409,4],[499,4]]},"3249":{"position":[[186,4],[423,4],[684,5],[696,4]]},"3251":{"position":[[1481,6],[1617,4],[2812,5],[3011,5]]},"3253":{"position":[[63,4],[153,4]]},"3255":{"position":[[644,5],[883,4]]},"3284":{"position":[[131,4]]},"3293":{"position":[[140,4]]},"3299":{"position":[[917,5],[1335,4],[2316,4],[2771,4],[3559,4]]},"3301":{"position":[[3835,4],[5067,5],[5251,4],[7468,5]]},"3308":{"position":[[83,5]]},"3314":{"position":[[1312,5],[1867,4],[2152,4]]},"3325":{"position":[[2480,4],[3012,4]]},"3357":{"position":[[1063,4]]},"3361":{"position":[[134,4]]},"3376":{"position":[[510,5],[568,5]]},"3382":{"position":[[145,5]]},"3389":{"position":[[556,4]]},"3440":{"position":[[188,5],[246,5]]},"3482":{"position":[[397,4]]}}}],["e.v",{"_index":3583,"t":{"694":{"position":[[87,4]]},"2688":{"position":[[1814,5],[1920,5]]}}}],["e0ded111a007",{"_index":6506,"t":{"1342":{"position":[[703,12]]}}}],["e12c89f88b44",{"_index":9793,"t":{"3107":{"position":[[1344,12]]}}}],["e2",{"_index":354,"t":{"27":{"position":[[1843,3],[1860,3]]},"321":{"position":[[1167,3],[1230,3],[1317,3],[1398,3]]},"493":{"position":[[100,3],[132,3],[201,3],[256,3],[336,3],[397,3],[477,3],[538,3],[618,3],[668,3],[747,3],[826,3],[857,3],[884,3],[922,3],[997,3],[1046,3],[1132,3],[1187,3],[1273,3],[1328,3],[1414,3],[1458,3],[1543,3],[1628,3],[1659,3],[1781,3],[1865,3]]},"495":{"position":[[145,3],[599,3],[993,3],[1044,3],[1486,3],[1868,3]]},"497":{"position":[[49,3]]},"499":{"position":[[85,3],[576,3],[684,4],[714,3],[824,4],[856,3],[955,3],[1179,3],[1299,3],[1346,3],[1369,3],[1394,3],[1416,3],[1469,3],[2156,3],[2246,3],[2400,4],[2440,4],[2512,3],[2541,3],[2610,3],[2648,4],[2717,4]]},"2413":{"position":[[132,3]]},"3053":{"position":[[226,3],[421,3],[555,3]]},"3059":{"position":[[45,3],[210,3],[450,3],[540,3],[710,3],[1175,3],[1291,3],[1419,3]]},"3061":{"position":[[22,3],[135,3],[258,3],[386,3],[782,3],[930,3],[999,3],[1272,3],[1344,3],[1416,3]]},"3071":{"position":[[597,3],[628,3],[730,3],[1124,3],[1236,3],[1820,3],[1951,3]]},"3128":{"position":[[763,3]]}}}],["e2e.yaml",{"_index":2844,"t":{"491":{"position":[[494,8]]},"495":{"position":[[731,8],[1612,8]]}}}],["e485697f",{"_index":4215,"t":{"859":{"position":[[3191,8],[3429,8],[3744,8],[3859,8],[6024,8]]},"1603":{"position":[[3191,8],[3429,8],[3744,8],[3859,8],[6024,8]]}}}],["e514c2c8",{"_index":9865,"t":{"3109":{"position":[[2328,8]]}}}],["e533",{"_index":7886,"t":{"1849":{"position":[[440,4]]}}}],["e58a7a8af17",{"_index":6805,"t":{"1386":{"position":[[171,12]]}}}],["e5b8",{"_index":5330,"t":{"1114":{"position":[[4848,4],[5185,4],[5236,4],[5727,4],[6092,4],[6516,4],[6558,4]]}}}],["e74",{"_index":6422,"t":{"1321":{"position":[[1117,3]]}}}],["e7622c1048ac4520a2d050ae141e826b",{"_index":324,"t":{"27":{"position":[[1165,32]]}}}],["e7c4b05c",{"_index":4059,"t":{"842":{"position":[[2997,8]]},"1557":{"position":[[2997,8]]}}}],["e828",{"_index":4199,"t":{"859":{"position":[[2756,4]]},"1603":{"position":[[2756,4]]}}}],["e85f",{"_index":6528,"t":{"1351":{"position":[[466,4],[992,4],[1702,4],[2516,4]]}}}],["e89ac8c9f66f46b5a983b2a05d2a66ec",{"_index":385,"t":{"27":{"position":[[3162,32]]}}}],["e8d5",{"_index":7810,"t":{"1845":{"position":[[1162,4],[2642,4]]}}}],["each",{"_index":579,"t":{"79":{"position":[[295,4]]},"105":{"position":[[1307,4]]},"139":{"position":[[78,4]]},"247":{"position":[[933,4],[3076,4]]},"270":{"position":[[333,4]]},"284":{"position":[[353,5]]},"300":{"position":[[130,4]]},"302":{"position":[[1068,4]]},"325":{"position":[[816,4],[963,4],[2796,4],[3865,4]]},"499":{"position":[[1852,4]]},"501":{"position":[[757,4]]},"586":{"position":[[478,4]]},"596":{"position":[[205,4],[343,4]]},"633":{"position":[[1359,4],[1615,4]]},"732":{"position":[[86,4]]},"738":{"position":[[240,4]]},"744":{"position":[[168,4],[428,4]]},"760":{"position":[[41,4]]},"774":{"position":[[466,4]]},"796":{"position":[[517,4]]},"798":{"position":[[129,4]]},"859":{"position":[[2358,4]]},"907":{"position":[[615,4]]},"911":{"position":[[458,4]]},"913":{"position":[[100,4]]},"982":{"position":[[772,4]]},"1080":{"position":[[1482,4]]},"1112":{"position":[[359,4],[1914,4],[2233,4],[2996,4],[3188,4],[3778,4],[3960,4]]},"1114":{"position":[[278,4]]},"1165":{"position":[[2548,4]]},"1167":{"position":[[3347,4]]},"1184":{"position":[[2420,4]]},"1240":{"position":[[0,4],[427,4]]},"1256":{"position":[[32,4]]},"1315":{"position":[[0,4]]},"1400":{"position":[[531,4],[720,4]]},"1430":{"position":[[505,4],[538,4]]},"1471":{"position":[[149,4],[574,4],[924,4],[1054,4],[1314,4],[1574,4],[1755,4],[1943,4]]},"1473":{"position":[[343,4],[470,4],[485,4],[695,4],[1437,4],[1592,4],[1687,4]]},"1493":{"position":[[86,4]]},"1533":{"position":[[517,4]]},"1535":{"position":[[129,4]]},"1566":{"position":[[196,4],[216,4]]},"1574":{"position":[[371,4]]},"1603":{"position":[[2358,4]]},"1629":{"position":[[615,4]]},"1633":{"position":[[458,4]]},"1635":{"position":[[100,4]]},"1684":{"position":[[4,4],[525,4]]},"1697":{"position":[[78,4]]},"1754":{"position":[[210,4]]},"1764":{"position":[[4061,4]]},"1773":{"position":[[744,4]]},"1783":{"position":[[499,4]]},"1785":{"position":[[599,4]]},"1825":{"position":[[1645,4]]},"1839":{"position":[[296,4]]},"1859":{"position":[[142,4]]},"1865":{"position":[[178,4]]},"1876":{"position":[[291,4]]},"1880":{"position":[[293,4]]},"1911":{"position":[[178,4]]},"1921":{"position":[[142,4]]},"1927":{"position":[[178,4]]},"1947":{"position":[[427,4]]},"1972":{"position":[[144,4]]},"1974":{"position":[[126,4]]},"1992":{"position":[[291,4]]},"1996":{"position":[[293,4]]},"2027":{"position":[[178,4]]},"2051":{"position":[[250,4]]},"2073":{"position":[[63,4],[118,4]]},"2098":{"position":[[1258,4]]},"2140":{"position":[[461,4]]},"2354":{"position":[[615,4]]},"2358":{"position":[[458,4]]},"2360":{"position":[[100,4]]},"2405":{"position":[[656,4]]},"2476":{"position":[[386,4]]},"2514":{"position":[[611,4]]},"2522":{"position":[[436,4],[570,4]]},"2625":{"position":[[60,4],[299,4],[443,4],[517,4],[1422,4],[1654,4]]},"2627":{"position":[[10,4],[1213,4]]},"2647":{"position":[[157,4]]},"2673":{"position":[[375,4]]},"2688":{"position":[[0,4]]},"2711":{"position":[[1271,4]]},"2795":{"position":[[818,4],[1540,4],[1593,4]]},"2805":{"position":[[0,4]]},"2811":{"position":[[483,4]]},"2813":{"position":[[1316,4]]},"2817":{"position":[[178,4],[229,4]]},"2856":{"position":[[1248,4]]},"2903":{"position":[[89,4]]},"2931":{"position":[[259,4]]},"2933":{"position":[[802,4]]},"2942":{"position":[[105,4]]},"2944":{"position":[[1128,4]]},"2981":{"position":[[77,4]]},"3016":{"position":[[447,4]]},"3021":{"position":[[106,4]]},"3031":{"position":[[531,4]]},"3050":{"position":[[124,4],[229,4],[259,4]]},"3055":{"position":[[962,4]]},"3057":{"position":[[183,4]]},"3063":{"position":[[504,4]]},"3074":{"position":[[451,4]]},"3078":{"position":[[910,4]]},"3103":{"position":[[1773,4]]},"3111":{"position":[[137,4]]},"3132":{"position":[[155,4]]},"3197":{"position":[[792,4]]},"3199":{"position":[[655,4],[700,4],[751,4],[888,4]]},"3251":{"position":[[4027,4]]},"3301":{"position":[[5319,4]]},"3325":{"position":[[2431,4],[2584,4]]},"3355":{"position":[[166,4],[325,4]]},"3395":{"position":[[263,4]]},"3397":{"position":[[580,4]]},"3461":{"position":[[292,4]]},"3465":{"position":[[1028,4]]},"3472":{"position":[[14413,4]]}}}],["earli",{"_index":1848,"t":{"280":{"position":[[373,5]]},"513":{"position":[[1600,5]]},"913":{"position":[[4146,5]]},"1635":{"position":[[4146,5]]},"2360":{"position":[[4146,5]]},"3308":{"position":[[401,5]]},"3465":{"position":[[710,6]]}}}],["earlier",{"_index":1865,"t":{"284":{"position":[[135,7]]},"379":{"position":[[463,7]]},"471":{"position":[[284,7]]},"1065":{"position":[[529,7]]},"1344":{"position":[[355,7]]},"2899":{"position":[[236,8]]},"3063":{"position":[[324,8]]},"3272":{"position":[[740,8]]},"3274":{"position":[[117,7]]}}}],["eas",{"_index":1147,"t":{"170":{"position":[[1874,4]]},"335":{"position":[[781,4]]},"658":{"position":[[46,4]]},"2263":{"position":[[347,4]]},"2461":{"position":[[802,4]]},"2737":{"position":[[312,4]]},"2776":{"position":[[312,4]]},"3245":{"position":[[457,4]]},"3314":{"position":[[694,4]]}}}],["eascii",{"_index":6479,"t":{"1337":{"position":[[339,6]]}}}],["easi",{"_index":255,"t":{"23":{"position":[[392,4]]},"83":{"position":[[47,5]]},"91":{"position":[[140,4]]},"149":{"position":[[119,4]]},"170":{"position":[[152,4]]},"284":{"position":[[230,4]]},"335":{"position":[[637,4]]},"583":{"position":[[308,4]]},"819":{"position":[[158,4]]},"905":{"position":[[1678,4]]},"1509":{"position":[[158,4]]},"1627":{"position":[[1678,4]]},"2312":{"position":[[233,4]]},"2352":{"position":[[1678,4]]},"2647":{"position":[[419,4]]},"2673":{"position":[[1358,4]]},"3061":{"position":[[1020,4]]},"3069":{"position":[[223,4]]},"3208":{"position":[[68,4],[1331,4],[1389,4]]},"3210":{"position":[[828,4]]},"3314":{"position":[[499,4],[1033,4],[1973,4],[2600,4]]},"3316":{"position":[[181,4],[313,4]]},"3472":{"position":[[12707,4]]}}}],["easier",{"_index":909,"t":{"141":{"position":[[127,6]]},"168":{"position":[[956,6]]},"280":{"position":[[434,6]]},"284":{"position":[[1329,6]]},"349":{"position":[[438,6]]},"501":{"position":[[567,6]]},"883":{"position":[[762,6]]},"1594":{"position":[[710,7]]},"1699":{"position":[[120,6]]},"2212":{"position":[[392,6]]},"2235":{"position":[[786,6]]},"2248":{"position":[[380,7]]},"2312":{"position":[[645,6]]},"2407":{"position":[[388,6]]},"2625":{"position":[[509,7]]},"2713":{"position":[[951,6]]},"2756":{"position":[[1419,6]]},"2858":{"position":[[761,6]]},"3103":{"position":[[462,6]]},"3216":{"position":[[138,6]]},"3495":{"position":[[13,6]]}}}],["easiest",{"_index":1796,"t":{"259":{"position":[[106,7]]}}}],["easili",{"_index":2182,"t":{"349":{"position":[[34,6]]},"552":{"position":[[373,6]]},"627":{"position":[[2962,6]]},"880":{"position":[[432,6]]},"977":{"position":[[2042,6]]},"1719":{"position":[[148,6]]},"1745":{"position":[[225,6]]},"1857":{"position":[[1096,6]]},"1880":{"position":[[536,6]]},"1882":{"position":[[802,6]]},"1919":{"position":[[1096,6]]},"1957":{"position":[[1451,6]]},"1996":{"position":[[536,6]]},"1998":{"position":[[802,6]]},"2077":{"position":[[452,6]]},"2162":{"position":[[495,6]]},"2265":{"position":[[226,6]]},"2283":{"position":[[644,6]]},"2298":{"position":[[226,6]]},"2409":{"position":[[604,7]]},"2461":{"position":[[697,7]]},"2526":{"position":[[327,6]]},"2960":{"position":[[1043,6],[1130,7]]},"3025":{"position":[[370,6]]},"3206":{"position":[[174,6]]},"3251":{"position":[[2361,6],[5758,6]]},"3308":{"position":[[310,6]]},"3410":{"position":[[259,6]]},"3438":{"position":[[492,6]]}}}],["east",{"_index":8520,"t":{"2403":{"position":[[216,4]]}}}],["eb7522b1",{"_index":5263,"t":{"1114":{"position":[[1150,8],[1521,8],[1727,8],[2277,8],[2520,8],[2888,8],[2994,8]]}}}],["ebc048b02ab2",{"_index":6609,"t":{"1360":{"position":[[2509,12]]}}}],["ec",{"_index":6052,"t":{"1226":{"position":[[1869,3]]}}}],["ec2",{"_index":184,"t":{"12":{"position":[[43,3]]},"423":{"position":[[154,3]]},"467":{"position":[[257,3],[665,3],[702,3],[788,3],[964,3],[1043,3],[1173,3],[1213,3],[1972,3]]},"471":{"position":[[303,3]]},"639":{"position":[[575,3],[877,3]]},"756":{"position":[[195,3]]}}}],["ec2/:3000",{"_index":4619,"t":{"934":{"position":[[1677,23]]},"1656":{"position":[[1677,23]]},"2381":{"position":[[1677,23]]}}}],["http.port",{"_index":5876,"t":{"1167":{"position":[[1669,10],[3039,10]]}}}],["http.respons",{"_index":8893,"t":{"2566":{"position":[[10396,16]]}}}],["http.yaml",{"_index":3390,"t":{"637":{"position":[[638,9]]}}}],["http/1.1",{"_index":6442,"t":{"1321":{"position":[[1943,9]]}}}],["http://10.10.10.10:3128",{"_index":2721,"t":{"485":{"position":[[1041,23]]}}}],["http://127.0.0.1:8080/api/clust",{"_index":8249,"t":{"2118":{"position":[[1161,35],[1948,35]]}}}],["http://127.0.0.1:8080/api/clusters/?name=kaa",{"_index":8257,"t":{"2118":{"position":[[2618,45]]}}}],["http://127.0.0.1:8080/api/clusters/kaa",{"_index":8256,"t":{"2118":{"position":[[2185,39]]}}}],["http://127.0.0.1:8080/kaa",{"_index":8247,"t":{"2118":{"position":[[969,26]]}}}],["http://127.0.0.1:8086",{"_index":4541,"t":{"926":{"position":[[574,25]]},"1648":{"position":[[574,25]]},"2373":{"position":[[574,25]]}}}],["http://192.168.16.10:7000",{"_index":6403,"t":{"1321":{"position":[[510,28],[1362,28]]}}}],["http://ara",{"_index":6259,"t":{"1317":{"position":[[1606,10],[5714,10],[8868,10]]}}}],["http://localhost:10351",{"_index":2299,"t":{"387":{"position":[[331,22]]}}}],["http://localhost:30000",{"_index":8176,"t":{"2096":{"position":[[2620,22]]},"2108":{"position":[[149,22]]},"2130":{"position":[[145,22]]}}}],["http://localhost:30000/d/monitoring/infrastructur",{"_index":8217,"t":{"2108":{"position":[[341,50]]},"2130":{"position":[[337,50]]}}}],["http://localhost:30000/d/openstack",{"_index":8177,"t":{"2096":{"position":[[2687,34]]}}}],["http://localhost:30001",{"_index":8218,"t":{"2108":{"position":[[428,22]]},"2130":{"position":[[424,22]]}}}],["http://localhost:30002",{"_index":8219,"t":{"2108":{"position":[[465,22]]},"2130":{"position":[[457,22]]}}}],["http://localhost:8080",{"_index":2500,"t":{"434":{"position":[[286,21]]},"641":{"position":[[1568,22]]}}}],["http://localhost:8086",{"_index":4576,"t":{"932":{"position":[[2088,21]]},"934":{"position":[[1825,21]]},"1654":{"position":[[2088,21]]},"1656":{"position":[[1825,21]]},"2379":{"position":[[2088,21]]},"2381":{"position":[[1825,21]]}}}],["http://localhost:8088/post_json",{"_index":8964,"t":{"2568":{"position":[[206,31]]},"2570":{"position":[[174,31]]}}}],["http://manager.systems.in",{"_index":7031,"t":{"1576":{"position":[[172,25],[343,25],[677,25]]}}}],["http://testb",{"_index":7602,"t":{"1789":{"position":[[539,14],[628,14],[717,14],[1174,14]]}}}],["http_audit",{"_index":8888,"t":{"2566":{"position":[[9661,11],[10425,11]]}}}],["http_proxi",{"_index":2720,"t":{"485":{"position":[[868,10],[1127,10],[1180,10],[1543,10]]},"2461":{"position":[[840,10]]}}}],["httpchk",{"_index":5355,"t":{"1118":{"position":[[805,7]]}}}],["httpd",{"_index":5483,"t":{"1144":{"position":[[197,5]]}}}],["httplog",{"_index":5759,"t":{"1161":{"position":[[1741,7]]}}}],["https://10.0.3.15/ident",{"_index":3482,"t":{"650":{"position":[[452,26]]}}}],["https://10.0.3.15/identity/v3/auth/token",{"_index":2362,"t":{"404":{"position":[[177,44]]}}}],["https://ansible.readthedocs.io/projects/lint/rul",{"_index":865,"t":{"133":{"position":[[126,52]]}}}],["https://api",{"_index":5180,"t":{"1108":{"position":[[638,12]]},"1305":{"position":[[7,11]]},"1307":{"position":[[17,11]]},"1789":{"position":[[358,11],[460,11],[1362,11],[1425,11]]}}}],["https://api.gx",{"_index":439,"t":{"44":{"position":[[76,14],[154,14]]},"467":{"position":[[1550,15],[2620,14]]},"2033":{"position":[[595,15]]}}}],["https://api.in",{"_index":7035,"t":{"1576":{"position":[[288,14],[477,14],[558,14],[747,14],[937,14],[1013,14],[1083,14]]}}}],["https://api.testbed.osism.xyz",{"_index":7607,"t":{"1789":{"position":[[842,29],[910,29],[994,29]]}}}],["https://api.testbed.osism.xyz:5000/v3",{"_index":7621,"t":{"1791":{"position":[[2134,37],[2939,37]]}}}],["https://api.testbed.osism.xyz:5601",{"_index":7613,"t":{"1789":{"position":[[1296,34]]}}}],["https://api.wavestack.de:5000",{"_index":447,"t":{"51":{"position":[[71,29]]}}}],["https://app.element.io/#/regist",{"_index":1800,"t":{"259":{"position":[[206,34]]}}}],["https://ara.services.in",{"_index":7029,"t":{"1576":{"position":[[118,23]]}}}],["https://ara.testbed.osism.xyz",{"_index":7598,"t":{"1789":{"position":[[310,29]]}}}],["https://bar.com/auth/realms/osism/.wel",{"_index":8008,"t":{"1957":{"position":[[1623,39]]}}}],["https://bar.com/auth/realms/osism/protocol/openid",{"_index":8025,"t":{"1957":{"position":[[3742,50]]}}}],["https://barbican.services.a.regiocloud.tech",{"_index":5734,"t":{"1161":{"position":[[391,43]]}}}],["https://bugs.debian.org/cgi",{"_index":8460,"t":{"2292":{"position":[[250,28]]}}}],["https://bugs.launchpad.net/keystone/+bug/2041611",{"_index":8116,"t":{"2039":{"position":[[943,48]]}}}],["https://cdimage.debian.org/cdimage/cloud/bookworm",{"_index":9672,"t":{"2987":{"position":[[594,50]]}}}],["https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240411",{"_index":4157,"t":{"850":{"position":[[9860,64]]},"1484":{"position":[[9860,64]]}}}],["https://cdimage.debian.org/cdimage/cloud/bookworm/daily/20240424",{"_index":4120,"t":{"850":{"position":[[5005,65]]},"1484":{"position":[[5005,65]]}}}],["https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/debian",{"_index":4110,"t":{"850":{"position":[[4011,69],[9570,69]]},"1484":{"position":[[4011,69],[9570,69]]}}}],["https://cdimage.debian.org/cdimage/cloud/bookworm/daily/latest/sha512sum",{"_index":4112,"t":{"850":{"position":[[4184,73],[9484,73]]},"1484":{"position":[[4184,73],[9484,73]]}}}],["https://cdimage.debian.org/cdimage/cloud/bullsey",{"_index":9674,"t":{"2987":{"position":[[725,50]]}}}],["https://cdimage.debian.org/cdimage/cloud/bullseye/latest/debian",{"_index":4102,"t":{"850":{"position":[[3091,63]]},"1484":{"position":[[3091,63]]}}}],["https://cdimage.debian.org/cdimage/cloud/bullseye/latest/sha512sum",{"_index":4104,"t":{"850":{"position":[[3252,67]]},"1484":{"position":[[3252,67]]}}}],["https://cinder.services.a.regiocloud.tech",{"_index":5735,"t":{"1161":{"position":[[464,41]]}}}],["https://cloud",{"_index":3776,"t":{"796":{"position":[[872,13],[978,13]]},"850":{"position":[[6271,13],[6420,13],[7039,13],[7213,13],[7857,13],[8006,13],[8597,14]]},"1484":{"position":[[6271,13],[6420,13],[7039,13],[7213,13],[7857,13],[8006,13],[8597,14]]},"1533":{"position":[[872,13],[978,13]]},"2987":{"position":[[41,13],[91,13],[425,13],[475,13]]}}}],["https://cloud.centos.org/centos/9",{"_index":4087,"t":{"850":{"position":[[1876,33],[2065,33],[2200,33]]},"1484":{"position":[[1876,33],[2065,33],[2200,33]]}}}],["https://cloud.debian.org/images/cloud/bookworm",{"_index":9659,"t":{"2983":{"position":[[180,49]]},"2987":{"position":[[544,47]]}}}],["https://cloud.debian.org/images/cloud/bullsey",{"_index":9673,"t":{"2987":{"position":[[675,47]]}}}],["https://cluster",{"_index":3025,"t":{"590":{"position":[[2317,16]]},"609":{"position":[[6132,15]]}}}],["https://console.services.a.regiocloud.tech/vnc_lite.html",{"_index":5804,"t":{"1161":{"position":[[4024,56]]}}}],["https://dashboard.wavestack.d",{"_index":446,"t":{"51":{"position":[[14,31]]}}}],["https://designate.services.a.regiocloud.tech",{"_index":5737,"t":{"1161":{"position":[[533,44]]}}}],["https://developercertificate.org",{"_index":1323,"t":{"182":{"position":[[331,32]]},"255":{"position":[[0,33]]}}}],["https://dnationcloud.github.io/helm",{"_index":8210,"t":{"2106":{"position":[[840,35]]},"2128":{"position":[[27,35]]},"2138":{"position":[[872,35]]}}}],["https://docs.ceph.com/en/latest/rados/configur",{"_index":5139,"t":{"1100":{"position":[[46,52]]}}}],["https://docs.ceph.com/en/latest/rados/configuration/mon",{"_index":6921,"t":{"1460":{"position":[[305,55]]}}}],["https://docs.ceph.com/en/latest/rados/oper",{"_index":6813,"t":{"1395":{"position":[[46,49]]}}}],["https://docs.ceph.com/en/latest/rados/operations/pool",{"_index":6914,"t":{"1448":{"position":[[231,55]]}}}],["https://docs.ceph.com/en/latest/rados/troubleshoot",{"_index":7273,"t":{"1726":{"position":[[46,54]]}}}],["https://docs.ceph.com/en/latest/rados/troubleshooting/troubleshoot",{"_index":6913,"t":{"1446":{"position":[[224,69]]}}}],["https://docs.ceph.com/en/latest/releas",{"_index":6819,"t":{"1397":{"position":[[67,41]]}}}],["https://docs.ceph.com/en/pacific/rados/configur",{"_index":5141,"t":{"1100":{"position":[[185,53]]}}}],["https://docs.ceph.com/en/pacific/rados/oper",{"_index":6814,"t":{"1395":{"position":[[182,50]]}}}],["https://docs.ceph.com/en/pacific/rados/troubleshoot",{"_index":7274,"t":{"1726":{"position":[[187,55]]}}}],["https://docs.ceph.com/en/quincy/rados/configur",{"_index":5142,"t":{"1100":{"position":[[248,52]]}}}],["https://docs.ceph.com/en/quincy/rados/oper",{"_index":6815,"t":{"1395":{"position":[[242,49]]}}}],["https://docs.ceph.com/en/quincy/rados/troubleshoot",{"_index":7275,"t":{"1726":{"position":[[252,54]]}}}],["https://docs.ceph.com/en/reef/rados/configur",{"_index":5144,"t":{"1100":{"position":[[308,50]]}}}],["https://docs.ceph.com/en/reef/rados/oper",{"_index":6816,"t":{"1395":{"position":[[299,47]]}}}],["https://docs.ceph.com/en/reef/rados/troubleshoot",{"_index":7276,"t":{"1726":{"position":[[314,52]]}}}],["https://docs.docker.com/config/containers/logging/configur",{"_index":6003,"t":{"1217":{"position":[[22,60]]}}}],["https://docs.influxdata.com/influxdb/v1/introduction/install/#instal",{"_index":4601,"t":{"934":{"position":[[26,72]]},"1656":{"position":[[26,72]]},"2381":{"position":[[26,72]]}}}],["https://docs.k3s.io/datastore/ha",{"_index":8197,"t":{"2100":{"position":[[1106,32]]}}}],["https://docs.openstack.org/cinder/latest/admin/bas",{"_index":6522,"t":{"1351":{"position":[[0,52]]}}}],["https://docs.openstack.org/cinder/latest/configuration/block",{"_index":5476,"t":{"1130":{"position":[[240,60]]}}}],["https://docs.openstack.org/kolla",{"_index":6207,"t":{"1300":{"position":[[0,32]]}}}],["https://docs.openstack.org/neutron/latest/admin/config",{"_index":6812,"t":{"1391":{"position":[[0,54]]}}}],["https://docs.openstack.org/nova/latest/admin/resourc",{"_index":6784,"t":{"1381":{"position":[[0,53]]}}}],["https://docs.openstack.org/nova/latest/configuration/config.html#default.reserved_host_cpu",{"_index":5964,"t":{"1182":{"position":[[0,91]]}}}],["https://docs.openstack.org/nova/latest/configuration/config.html#default.reserved_host_memory_mb",{"_index":5960,"t":{"1180":{"position":[[0,96]]}}}],["https://docs.ovn.org/en/stable/tutorials/ovn",{"_index":6668,"t":{"1364":{"position":[[964,44]]},"1368":{"position":[[0,44]]}}}],["https://docs.scs.commun",{"_index":653,"t":{"105":{"position":[[428,27]]}}}],["https://download.docker.com/linux/ubuntu",{"_index":7463,"t":{"1764":{"position":[[291,40],[404,40],[517,40],[630,40],[743,40],[856,40],[969,40],[1082,40],[1195,40],[1308,40],[1421,40],[1534,40],[1647,40],[1760,40],[1871,40],[1982,40],[2093,40],[2204,40],[2315,40],[2426,40],[2537,40],[2648,40],[2759,40],[2870,40],[2981,40],[3092,40]]}}}],["https://download.rockylinux.org/pub/rocky/9/images/x86_64/rocki",{"_index":4124,"t":{"850":{"position":[[5356,63],[5526,63]]},"1484":{"position":[[5356,63],[5526,63]]}}}],["https://en.wikipedia.org/wiki/comparison_of_free_and_open",{"_index":1314,"t":{"182":{"position":[[0,57]]}}}],["https://en.wikipedia.org/wiki/software_patents_and_free_softwar",{"_index":1316,"t":{"182":{"position":[[83,64]]}}}],["https://flavors.scs.commun",{"_index":9371,"t":{"2783":{"position":[[344,31]]}}}],["https://flower.services.in",{"_index":7034,"t":{"1576":{"position":[[237,26]]}}}],["https://flower.testbed.osism.xyz",{"_index":7600,"t":{"1789":{"position":[[419,32]]}}}],["https://fluxcd.io/flux/installation/#instal",{"_index":2387,"t":{"407":{"position":[[197,44]]},"432":{"position":[[197,44]]},"440":{"position":[[222,44]]}}}],["https://fluxcd.io/install.sh",{"_index":2389,"t":{"407":{"position":[[263,28]]},"432":{"position":[[263,28]]},"440":{"position":[[288,28]]}}}],["https://foo.com/auth/admin/osism/consol",{"_index":8020,"t":{"1957":{"position":[[3315,40]]}}}],["https://foo.com/auth/realms/os",{"_index":8019,"t":{"1957":{"position":[[3159,36]]}}}],["https://foo.com/auth/realms/osism/broker/oidc",{"_index":8017,"t":{"1957":{"position":[[3014,45]]}}}],["https://foo.com/auth/realms/osism/protocol/openid",{"_index":8021,"t":{"1957":{"position":[[3360,49]]}}}],["https://galaxy.ansible.com",{"_index":949,"t":{"143":{"position":[[957,26]]}}}],["https://gist.github.com/djoreilly/c5ea44663c133b246dd9d42b921f7646",{"_index":6670,"t":{"1366":{"position":[[0,66]]}}}],["https://github.com",{"_index":692,"t":{"105":{"position":[[1276,21]]}}}],["https://github.com/ans",{"_index":950,"t":{"143":{"position":[[992,26]]}}}],["https://github.com/cirro",{"_index":3755,"t":{"790":{"position":[[1124,25]]},"1527":{"position":[[1124,25]]}}}],["https://github.com/kubernet",{"_index":3099,"t":{"604":{"position":[[1832,29]]}}}],["https://github.com/m3dbx/prometheus_remote_client_golang",{"_index":8238,"t":{"2116":{"position":[[577,57]]}}}],["https://github.com/metio/matrix",{"_index":8131,"t":{"2071":{"position":[[129,31]]}}}],["https://github.com/openstack/cinder/blob/master/cinder/volume/drivers/pure.pi",{"_index":5475,"t":{"1130":{"position":[[162,77]]}}}],["https://github.com/os",{"_index":7433,"t":{"1749":{"position":[[1459,24]]}}}],["https://github.com/osism/ans",{"_index":7133,"t":{"1608":{"position":[[296,32],[389,32]]}}}],["https://github.com/osism/cfg",{"_index":7136,"t":{"1608":{"position":[[479,28]]}}}],["https://github.com/osism/cloud",{"_index":7016,"t":{"1571":{"position":[[866,30]]}}}],["https://github.com/osism/contain",{"_index":7141,"t":{"1608":{"position":[[699,34]]},"1610":{"position":[[140,34]]}}}],["https://github.com/osism/defaults/pull/54/fil",{"_index":7145,"t":{"1608":{"position":[[852,47]]}}}],["https://github.com/osism/issu",{"_index":979,"t":{"151":{"position":[[328,31]]}}}],["https://github.com/osism/kolla",{"_index":8387,"t":{"2212":{"position":[[223,30]]}}}],["https://github.com/osism/openstack",{"_index":3806,"t":{"810":{"position":[[179,34]]},"830":{"position":[[57,34]]},"848":{"position":[[47,34]]},"855":{"position":[[54,34]]},"1482":{"position":[[47,34]]},"1500":{"position":[[179,34]]},"1545":{"position":[[57,34]]},"1599":{"position":[[54,34]]}}}],["https://github.com/osism/release/pull/278/fil",{"_index":7139,"t":{"1608":{"position":[[590,47]]}}}],["https://github.com/osism/testb",{"_index":7529,"t":{"1779":{"position":[[303,32]]}}}],["https://github.com/osism/testbed/pull/1043/fil",{"_index":7146,"t":{"1608":{"position":[[939,48]]}}}],["https://github.com/rancher/os/releases/download/v1.3.0/ranchero",{"_index":3788,"t":{"798":{"position":[[827,64]]},"1535":{"position":[[827,64]]}}}],["https://github.com/rancher/os/releases/download/v1.4.0/ranchero",{"_index":3791,"t":{"798":{"position":[[930,64]]},"1535":{"position":[[930,64]]}}}],["https://github.com/rancher/os/releases/download/v1.4.1/ranchero",{"_index":3793,"t":{"798":{"position":[[1033,64]]},"1535":{"position":[[1033,64]]}}}],["https://github.com/sovereigncloudstack/clust",{"_index":2967,"t":{"544":{"position":[[114,46]]},"546":{"position":[[125,46]]}}}],["https://github.com/sovereigncloudstack/docs.git",{"_index":1005,"t":{"160":{"position":[[79,47]]}}}],["https://github.com/sovereigncloudstack/openstack",{"_index":4406,"t":{"909":{"position":[[105,48]]},"924":{"position":[[4,48]]},"1631":{"position":[[105,48]]},"1646":{"position":[[4,48]]},"2356":{"position":[[105,48]]},"2371":{"position":[[4,48]]}}}],["https://github.com/sovereigncloudstack/standards/blob/main/tests/iaa",{"_index":9675,"t":{"2990":{"position":[[41,71]]}}}],["https://github.com/sovereigncloudstack/standards/tree/main/drafts/iam",{"_index":10021,"t":{"3257":{"position":[[0,69]]}}}],["https://github.com/sovereigncloudstack/zuul",{"_index":8386,"t":{"2209":{"position":[[592,43]]}}}],["https://github.com/stackhpc/capi",{"_index":2987,"t":{"583":{"position":[[83,32]]}}}],["https://github.com/testing.key",{"_index":4843,"t":{"1043":{"position":[[384,31]]}}}],["https://github.com/vmwar",{"_index":2600,"t":{"469":{"position":[[438,25]]}}}],["https://glance.services.a.regiocloud.tech",{"_index":5739,"t":{"1161":{"position":[[602,41]]}}}],["https://grafana.com/docs/grafana/latest/setup",{"_index":4602,"t":{"934":{"position":[[220,45]]},"1656":{"position":[[220,45]]},"2381":{"position":[[220,45]]}}}],["https://grafana.com/grafana/dashboards/21085",{"_index":8170,"t":{"2096":{"position":[[1488,45]]}}}],["https://harbor.example.com",{"_index":3473,"t":{"646":{"position":[[2051,28]]}}}],["https://health.yourcloud.sovereignit.de:3000",{"_index":4572,"t":{"932":{"position":[[1746,44]]},"1654":{"position":[[1746,44]]},"2379":{"position":[[1746,44]]}}}],["https://homer.services.in",{"_index":7039,"t":{"1576":{"position":[[411,25]]}}}],["https://homer.testbed.osism.xyz",{"_index":7606,"t":{"1789":{"position":[[787,31]]}}}],["https://ironic.services.a.regiocloud.tech",{"_index":5741,"t":{"1161":{"position":[[668,41]]}}}],["https://joinup.ec.europa.eu/collection/eupl/matrix",{"_index":1317,"t":{"182":{"position":[[148,50]]}}}],["https://julien.ponge.org/blog/develop",{"_index":1324,"t":{"182":{"position":[[364,39]]},"255":{"position":[[34,39]]}}}],["https://keycloak..servic",{"_index":6945,"t":{"1471":{"position":[[1812,11]]},"1473":{"position":[[555,11]]}}}],["id_rsa.neutron",{"_index":8459,"t":{"2288":{"position":[[197,14]]}}}],["id_rsa.oper",{"_index":6111,"t":{"1256":{"position":[[3155,16],[3356,15]]}}}],["idea",{"_index":2573,"t":{"460":{"position":[[783,4]]},"472":{"position":[[1984,4]]},"590":{"position":[[2278,4]]},"627":{"position":[[4465,4]]},"1764":{"position":[[4111,4]]},"1943":{"position":[[4,4]]},"1959":{"position":[[36,4]]},"2474":{"position":[[54,4],[300,5]]},"2476":{"position":[[143,4]]},"3115":{"position":[[152,4]]},"3154":{"position":[[450,4]]},"3184":{"position":[[2535,4]]},"3247":{"position":[[479,4]]}}}],["ideal",{"_index":2506,"t":{"436":{"position":[[697,5]]},"513":{"position":[[796,7]]},"615":{"position":[[1025,8]]},"778":{"position":[[141,5]]},"880":{"position":[[751,5]]},"899":{"position":[[886,7]]},"905":{"position":[[2304,8]]},"977":{"position":[[880,5],[2649,5]]},"1252":{"position":[[1195,6]]},"1621":{"position":[[886,7]]},"1627":{"position":[[2304,8]]},"2176":{"position":[[1444,7]]},"2346":{"position":[[886,7]]},"2352":{"position":[[2304,8]]},"2627":{"position":[[404,7]]},"2675":{"position":[[121,5]]}}}],["idempot",{"_index":3125,"t":{"604":{"position":[[3961,10]]},"631":{"position":[[1023,10]]},"667":{"position":[[776,10]]},"1571":{"position":[[1756,10]]}}}],["iden",{"_index":10158,"t":{"3325":{"position":[[2756,7]]}}}],["ident",{"_index":528,"t":{"71":{"position":[[150,8]]},"101":{"position":[[38,8],[252,8],[411,10],[582,10],[621,10],[703,8]]},"247":{"position":[[359,11],[603,8],[655,8],[1797,9]]},"290":{"position":[[95,10],[435,8]]},"292":{"position":[[137,8]]},"298":{"position":[[28,11],[64,10]]},"302":{"position":[[235,10]]},"748":{"position":[[26,8]]},"762":{"position":[[16,8]]},"865":{"position":[[305,8]]},"870":{"position":[[63,8]]},"878":{"position":[[305,8]]},"905":{"position":[[324,8]]},"1041":{"position":[[529,8]]},"1256":{"position":[[3216,8]]},"1627":{"position":[[324,8]]},"1779":{"position":[[727,9],[1420,10],[1933,9]]},"1791":{"position":[[2342,8],[2399,8],[3147,8],[3204,8]]},"1816":{"position":[[411,8],[432,8]]},"1937":{"position":[[97,10],[465,8]]},"1947":{"position":[[169,8]]},"1951":{"position":[[763,8]]},"1955":{"position":[[164,8]]},"1957":{"position":[[1007,8],[4209,8]]},"1959":{"position":[[213,8],[728,8],[770,8]]},"1972":{"position":[[480,9]]},"1982":{"position":[[641,8],[678,8],[737,8]]},"1984":{"position":[[251,8],[288,8],[347,8]]},"2037":{"position":[[97,8],[291,8]]},"2039":{"position":[[326,10]]},"2196":{"position":[[221,8]]},"2281":{"position":[[414,8],[442,10]]},"2352":{"position":[[324,8]]},"2409":{"position":[[36,8]]},"2472":{"position":[[133,8]]},"2574":{"position":[[27,8],[222,9],[544,8]]},"2576":{"position":[[69,8],[389,8],[507,11],[556,8]]},"2629":{"position":[[451,8]]},"2671":{"position":[[1249,8]]},"2764":{"position":[[1268,10]]},"3152":{"position":[[85,8],[159,8]]},"3160":{"position":[[532,10],[577,10],[642,8]]},"3245":{"position":[[615,10],[945,8],[1097,10],[1197,11]]},"3247":{"position":[[447,8],[658,11]]},"3249":{"position":[[25,8]]},"3251":{"position":[[1047,9],[1163,8],[1365,8],[1939,9],[3953,8],[4142,8],[4185,8],[5276,10]]},"3264":{"position":[[258,8]]},"3301":{"position":[[5805,10]]},"3314":{"position":[[2824,9]]},"3325":{"position":[[2801,8],[3069,8]]},"3389":{"position":[[142,8]]},"3453":{"position":[[275,8]]},"3455":{"position":[[372,8]]},"3457":{"position":[[810,11]]},"3482":{"position":[[2759,8]]},"3518":{"position":[[2171,8]]}}}],["identif",{"_index":10167,"t":{"3343":{"position":[[355,14]]}}}],["identifi",{"_index":224,"t":{"18":{"position":[[184,10]]},"25":{"position":[[148,10]]},"27":{"position":[[7,10]]},"30":{"position":[[7,10]]},"32":{"position":[[7,10]]},"247":{"position":[[1550,11]]},"282":{"position":[[607,11]]},"286":{"position":[[301,11]]},"355":{"position":[[11,8]]},"905":{"position":[[2235,8]]},"909":{"position":[[2143,8]]},"917":{"position":[[601,8]]},"1102":{"position":[[31,10],[63,10]]},"1114":{"position":[[3607,11]]},"1585":{"position":[[659,8]]},"1627":{"position":[[2235,8]]},"1631":{"position":[[2143,8]]},"1639":{"position":[[601,8]]},"1835":{"position":[[184,8]]},"1855":{"position":[[420,8]]},"1878":{"position":[[717,10]]},"1890":{"position":[[99,10]]},"1896":{"position":[[302,11]]},"1900":{"position":[[726,11]]},"1906":{"position":[[298,10]]},"1917":{"position":[[420,8]]},"1963":{"position":[[524,8]]},"1994":{"position":[[717,10]]},"2006":{"position":[[99,10]]},"2012":{"position":[[302,11]]},"2016":{"position":[[726,11]]},"2022":{"position":[[298,10]]},"2075":{"position":[[54,11]]},"2077":{"position":[[91,11],[307,8]]},"2083":{"position":[[109,11]]},"2148":{"position":[[527,8]]},"2235":{"position":[[732,11]]},"2352":{"position":[[2235,8]]},"2356":{"position":[[2143,8]]},"2364":{"position":[[601,8]]},"2476":{"position":[[280,8]]},"2586":{"position":[[171,10]]},"2631":{"position":[[990,10]]},"2813":{"position":[[98,10]]},"3113":{"position":[[225,11]]},"3154":{"position":[[50,10]]},"3208":{"position":[[1471,9]]},"3245":{"position":[[129,11]]},"3343":{"position":[[498,11],[572,11],[587,8]]},"3347":{"position":[[221,8]]},"3353":{"position":[[11,11]]},"3357":{"position":[[68,11]]},"3361":{"position":[[107,10],[324,11]]},"3363":{"position":[[143,11],[317,10]]}}}],["identit",{"_index":9991,"t":{"3245":{"position":[[1171,10]]},"3247":{"position":[[563,10]]}}}],["identitiesonly=y",{"_index":6106,"t":{"1256":{"position":[[2208,19],[3334,18]]}}}],["identity.authent",{"_index":8819,"t":{"2566":{"position":[[6011,21]]}}}],["identity.endpoint",{"_index":8804,"t":{"2566":{"position":[[5524,22]]}}}],["identity.group",{"_index":8798,"t":{"2566":{"position":[[5413,19]]}}}],["identity.o",{"_index":8800,"t":{"2566":{"position":[[5452,12]]}}}],["identity.polici",{"_index":8805,"t":{"2566":{"position":[[5547,20]]}}}],["identity.project",{"_index":8797,"t":{"2566":{"position":[[5391,21]]}}}],["identity.region",{"_index":8802,"t":{"2566":{"position":[[5481,20]]}}}],["identity.rol",{"_index":8799,"t":{"2566":{"position":[[5433,18]]}}}],["identity.role_assign",{"_index":8812,"t":{"2566":{"position":[[5789,26]]}}}],["identity.servic",{"_index":8803,"t":{"2566":{"position":[[5502,21]]}}}],["identity.us",{"_index":8796,"t":{"2566":{"position":[[5372,18]]}}}],["identity:.yml",{"_index":5207,"t":{"1112":{"position":[[396,34]]}}}],["inventory/host_vars/node01.yml",{"_index":4966,"t":{"1067":{"position":[[4202,30],[4332,30],[4483,30],[4650,30],[4937,30],[5223,30],[5361,30]]}}}],["inventory/host_vars/testb",{"_index":5974,"t":{"1184":{"position":[[1714,27],[2039,27]]}}}],["inventory_hostnam",{"_index":921,"t":{"141":{"position":[[541,18]]},"1167":{"position":[[536,18],[670,18],[2233,18]]},"1699":{"position":[[356,18]]}}}],["inventory_reconcil",{"_index":7202,"t":{"1690":{"position":[[2164,20],[2235,20]]},"1731":{"position":[[2031,20],[2119,20]]}}}],["invers",{"_index":3841,"t":{"819":{"position":[[2568,7],[2625,7],[2678,7],[2725,7],[2777,7],[2836,7],[2896,7],[2955,7],[3020,7],[3074,7]]},"821":{"position":[[1801,7],[1848,7],[1894,7],[1952,7]]},"859":{"position":[[1793,7],[1828,7],[1862,7],[1899,7],[1936,7],[1969,7]]},"1509":{"position":[[2568,7],[2625,7],[2678,7],[2725,7],[2777,7],[2836,7],[2896,7],[2955,7],[3020,7],[3074,7]]},"1511":{"position":[[1801,7],[1848,7],[1894,7],[1952,7]]},"1603":{"position":[[1793,7],[1828,7],[1862,7],[1899,7],[1936,7],[1969,7]]}}}],["invest",{"_index":8395,"t":{"2229":{"position":[[454,9]]},"2486":{"position":[[3,8]]},"3011":{"position":[[2532,6],[2695,6]]},"3014":{"position":[[246,10],[1001,10]]},"3016":{"position":[[174,10],[714,11]]},"3071":{"position":[[2368,10]]},"3210":{"position":[[963,10]]}}}],["investig",{"_index":3005,"t":{"590":{"position":[[1053,13]]},"654":{"position":[[652,13]]},"669":{"position":[[367,11]]},"909":{"position":[[663,11]]},"1444":{"position":[[683,11]]},"1631":{"position":[[663,11]]},"2250":{"position":[[747,11]]},"2283":{"position":[[1246,11]]},"2356":{"position":[[663,11]]},"3007":{"position":[[408,14]]},"3071":{"position":[[608,13]]},"3222":{"position":[[112,11]]}}}],["invit",{"_index":518,"t":{"69":{"position":[[389,6]]},"210":{"position":[[670,6]]}}}],["invoic",{"_index":4426,"t":{"911":{"position":[[153,7]]},"1633":{"position":[[153,7]]},"2358":{"position":[[153,7]]},"3372":{"position":[[252,8]]},"3436":{"position":[[318,8],[451,8]]}}}],["involv",{"_index":1368,"t":{"191":{"position":[[116,9]]},"253":{"position":[[1228,9]]},"361":{"position":[[90,8]]},"366":{"position":[[952,8]]},"499":{"position":[[869,9]]},"1878":{"position":[[1223,9]]},"1994":{"position":[[1223,9]]},"2063":{"position":[[583,9]]},"2665":{"position":[[92,11]]},"3003":{"position":[[746,8]]},"3391":{"position":[[283,8]]}}}],["io",{"_index":3257,"t":{"615":{"position":[[856,2]]},"2947":{"position":[[2784,2],[2848,2],[2936,2]]},"2951":{"position":[[662,2]]}}}],["iod32",{"_index":6988,"t":{"1475":{"position":[[803,5]]}}}],["iodepth",{"_index":6986,"t":{"1475":{"position":[[605,7]]}}}],["iodepth=32",{"_index":6987,"t":{"1475":{"position":[[682,10]]}}}],["ioengine=\"libaio",{"_index":6960,"t":{"1475":{"position":[[80,17]]}}}],["ioengine=${ioengin",{"_index":6975,"t":{"1475":{"position":[[321,20],[637,20]]}}}],["iop",{"_index":6524,"t":{"1351":{"position":[[124,4],[144,5],[1948,4],[1985,4],[2796,4],[2867,4]]},"2709":{"position":[[635,5]]},"2754":{"position":[[635,5],[797,4]]},"2844":{"position":[[563,5]]},"2923":{"position":[[697,4]]},"2944":{"position":[[1811,4]]},"2947":{"position":[[4996,4]]},"2949":{"position":[[506,4],[671,5]]},"2951":{"position":[[485,4]]},"2955":{"position":[[127,4]]},"2957":{"position":[[209,4]]}}}],["iotop",{"_index":4750,"t":{"1014":{"position":[[383,5]]}}}],["ip",{"_index":2157,"t":{"335":{"position":[[1225,2]]},"413":{"position":[[124,2],[220,2],[232,2]]},"436":{"position":[[465,2],[487,2]]},"442":{"position":[[43,2],[139,2],[151,2]]},"483":{"position":[[1062,2],[1169,4]]},"487":{"position":[[4452,2],[4725,3]]},"503":{"position":[[773,3],[791,2]]},"505":{"position":[[876,4],[1023,3],[1357,4]]},"507":{"position":[[273,4]]},"509":{"position":[[188,4]]},"511":{"position":[[295,4]]},"552":{"position":[[316,2],[517,3]]},"633":{"position":[[739,2]]},"641":{"position":[[1642,2],[1654,2]]},"646":{"position":[[1674,2],[1775,2]]},"754":{"position":[[193,3]]},"772":{"position":[[140,2],[162,4],[178,2],[216,2]]},"895":{"position":[[1394,5]]},"903":{"position":[[3234,2],[3431,2],[3434,2],[3533,2],[3601,2],[3617,2],[3659,2],[3687,3],[3727,2]]},"905":{"position":[[2051,3]]},"909":{"position":[[1941,3]]},"911":{"position":[[753,4]]},"913":{"position":[[814,3],[855,2],[925,2]]},"947":{"position":[[905,2],[1054,2]]},"949":{"position":[[206,4]]},"1055":{"position":[[2602,2],[2697,2],[2829,2]]},"1067":{"position":[[1630,2],[1770,2],[1880,2]]},"1071":{"position":[[652,2],[740,2]]},"1116":{"position":[[195,2]]},"1282":{"position":[[33,3],[46,2],[79,2]]},"1368":{"position":[[1133,3],[1259,3],[1385,3]]},"1386":{"position":[[189,2]]},"1388":{"position":[[14,2],[440,2]]},"1400":{"position":[[690,2]]},"1569":{"position":[[1633,2]]},"1571":{"position":[[730,2],[1577,2]]},"1574":{"position":[[322,2]]},"1585":{"position":[[393,2],[1411,2],[1809,2],[3559,2]]},"1617":{"position":[[1394,5]]},"1625":{"position":[[3234,2],[3431,2],[3434,2],[3533,2],[3601,2],[3617,2],[3659,2],[3687,3],[3727,2]]},"1627":{"position":[[2051,3]]},"1631":{"position":[[1941,3]]},"1633":{"position":[[753,4]]},"1635":{"position":[[814,3],[855,2],[925,2]]},"1669":{"position":[[905,2],[1054,2]]},"1671":{"position":[[206,4]]},"1756":{"position":[[14,2],[146,2],[169,2]]},"1775":{"position":[[222,2]]},"1785":{"position":[[532,2]]},"1787":{"position":[[237,2]]},"1791":{"position":[[1752,2]]},"1794":{"position":[[98,2],[254,2]]},"1829":{"position":[[512,2]]},"1833":{"position":[[1501,3],[1515,2]]},"1841":{"position":[[378,2],[424,2]]},"2075":{"position":[[97,2],[434,2]]},"2098":{"position":[[3028,3]]},"2106":{"position":[[466,3],[545,4]]},"2315":{"position":[[1526,2],[1635,3]]},"2342":{"position":[[1394,5]]},"2350":{"position":[[3234,2],[3431,2],[3434,2],[3533,2],[3601,2],[3617,2],[3659,2],[3687,3],[3727,2]]},"2352":{"position":[[2051,3]]},"2356":{"position":[[1941,3]]},"2358":{"position":[[753,4]]},"2360":{"position":[[814,3],[855,2],[925,2]]},"2394":{"position":[[905,2],[1054,2]]},"2396":{"position":[[206,4]]},"2405":{"position":[[1056,2]]},"3076":{"position":[[33,2],[128,2]]},"3088":{"position":[[384,2],[410,2]]},"3097":{"position":[[48,2]]},"3107":{"position":[[487,2],[513,2]]}}}],["ip=10.50.40.230",{"_index":7843,"t":{"1845":{"position":[[2731,15]]}}}],["ip>:/.yaml",{"_index":3243,"t":{"609":{"position":[[6304,45]]}}}],["kubeconfig=testcluster/testcluster.yaml",{"_index":3143,"t":{"604":{"position":[[6420,39],[6717,39],[6825,39]]}}}],["kubeconfig=~/${cluster_name}/${cluster_name}.yaml",{"_index":3551,"t":{"660":{"position":[[3270,49]]}}}],["kubeconfig=~/clustername/clustername.yaml",{"_index":3315,"t":{"631":{"position":[[832,41]]}}}],["kubectl",{"_index":2355,"t":{"404":{"position":[[60,7]]},"409":{"position":[[2,7],[406,7],[440,7]]},"411":{"position":[[69,7],[108,7]]},"413":{"position":[[169,7],[785,7]]},"415":{"position":[[274,7]]},"427":{"position":[[1136,7]]},"428":{"position":[[404,7]]},"434":{"position":[[52,7],[131,7]]},"436":{"position":[[866,7]]},"440":{"position":[[361,7]]},"442":{"position":[[88,7],[506,7]]},"471":{"position":[[1455,7]]},"472":{"position":[[2098,7]]},"474":{"position":[[261,7],[419,7],[584,7],[750,7],[1089,7]]},"487":{"position":[[4120,7]]},"513":{"position":[[1246,9]]},"517":{"position":[[5,7]]},"521":{"position":[[460,7]]},"590":{"position":[[20,7],[364,7],[523,7],[736,7],[843,7],[913,7],[1985,7],[2173,7]]},"592":{"position":[[34,7],[129,7]]},"600":{"position":[[1218,7]]},"604":{"position":[[172,8],[6368,7],[6648,7],[6757,7]]},"606":{"position":[[341,7]]},"609":{"position":[[1098,7]]},"627":{"position":[[96,7],[1975,7],[2216,7],[4235,7],[4531,7],[4612,7]]},"631":{"position":[[785,7],[874,8]]},"637":{"position":[[371,7],[532,7]]},"641":{"position":[[751,7],[835,7],[1593,7],[1771,7],[1958,7]]},"644":{"position":[[185,7]]},"646":{"position":[[427,7],[645,7],[1391,7],[1840,7],[2082,7]]},"660":{"position":[[462,7],[619,7],[1215,7],[1533,7],[3077,7],[3320,7],[3419,7]]},"669":{"position":[[163,7],[231,8]]},"1768":{"position":[[126,7]]},"2033":{"position":[[1319,7]]},"2071":{"position":[[353,7]]},"2102":{"position":[[9,7]]},"2110":{"position":[[419,7]]},"2116":{"position":[[479,7]]},"2118":{"position":[[2408,7]]},"2124":{"position":[[19,7]]},"2136":{"position":[[150,7]]},"2138":{"position":[[57,7],[88,7],[120,7]]},"2158":{"position":[[436,7],[495,7],[544,7],[595,7]]},"3276":{"position":[[2310,7],[2326,7],[2512,7]]}}}],["kubectx",{"_index":3202,"t":{"604":{"position":[[11927,7]]}}}],["kubelet",{"_index":9964,"t":{"3236":{"position":[[612,7],[988,7],[2025,8],[2228,8],[2272,7],[2470,7],[2512,7],[2802,7],[2891,7]]},"3238":{"position":[[870,8]]},"3240":{"position":[[94,7]]},"3276":{"position":[[976,7],[1159,8],[2152,7],[2824,8]]},"3288":{"position":[[86,7]]},"3393":{"position":[[427,7],[554,8]]},"3400":{"position":[[1105,8],[1263,7]]}}}],["kubernet",{"_index":527,"t":{"71":{"position":[[135,10]]},"77":{"position":[[63,11],[90,10]]},"294":{"position":[[50,11],[110,10]]},"327":{"position":[[122,10],[202,10],[626,11],[726,10]]},"331":{"position":[[318,10]]},"333":{"position":[[28,11]]},"335":{"position":[[125,10],[716,10],[922,10],[1037,10]]},"339":{"position":[[75,10],[227,10]]},"349":{"position":[[306,10],[410,10]]},"363":{"position":[[133,10],[337,10]]},"368":{"position":[[414,10]]},"374":{"position":[[1053,10]]},"407":{"position":[[0,10]]},"417":{"position":[[130,10],[278,10],[312,10],[435,10]]},"421":{"position":[[96,10],[288,10],[380,10],[666,10],[788,10],[890,10],[1113,10],[1243,10],[1409,10]]},"430":{"position":[[87,10]]},"432":{"position":[[0,10]]},"440":{"position":[[0,10]]},"444":{"position":[[103,10]]},"447":{"position":[[208,10]]},"449":{"position":[[309,10]]},"460":{"position":[[114,10]]},"462":{"position":[[1368,10]]},"465":{"position":[[89,10],[318,10],[546,10]]},"469":{"position":[[177,10]]},"471":{"position":[[78,10]]},"487":{"position":[[667,10],[3354,10]]},"495":{"position":[[205,10],[1092,10]]},"515":{"position":[[40,10]]},"521":{"position":[[332,10]]},"530":{"position":[[430,10],[697,10],[837,10]]},"548":{"position":[[224,10]]},"586":{"position":[[411,10]]},"590":{"position":[[94,10],[192,10],[336,10]]},"592":{"position":[[223,10],[311,10]]},"594":{"position":[[51,11],[302,10]]},"598":{"position":[[52,10]]},"600":{"position":[[1082,10]]},"604":{"position":[[7119,10],[7736,10],[8011,10],[8393,10],[8466,10],[8776,10],[9148,10],[10459,12]]},"609":{"position":[[1256,10],[1483,10],[1557,10],[1602,10],[1707,10],[2526,10],[2622,10],[2835,10],[3455,10],[3523,10],[4137,10],[4252,10],[4312,10],[5061,10]]},"617":{"position":[[33,10],[113,10],[191,10],[394,10]]},"627":{"position":[[3076,10]]},"629":{"position":[[182,10]]},"637":{"position":[[56,10]]},"669":{"position":[[550,11]]},"865":{"position":[[186,10],[212,10],[257,10]]},"878":{"position":[[186,10],[212,10],[257,10]]},"883":{"position":[[0,10],[114,10],[390,10],[480,10],[933,10],[1267,10],[2083,10],[2216,10],[2379,10]]},"888":{"position":[[0,10],[85,10],[213,10],[250,10],[454,10],[510,10],[563,10],[635,10],[711,10],[1361,10],[1505,10],[2255,10],[2364,10]]},"954":{"position":[[584,10]]},"1246":{"position":[[47,10],[170,10],[226,10],[248,10],[282,10]]},"1560":{"position":[[148,11]]},"1562":{"position":[[244,10],[443,10]]},"1768":{"position":[[0,10],[50,10]]},"1779":{"position":[[5935,10]]},"1812":{"position":[[279,10],[315,10]]},"1814":{"position":[[210,10]]},"1953":{"position":[[95,10],[282,11],[324,10]]},"1970":{"position":[[193,10]]},"1972":{"position":[[591,11],[608,11],[642,10]]},"1974":{"position":[[565,10]]},"1976":{"position":[[94,10],[144,10],[329,10],[538,10]]},"1978":{"position":[[28,10],[114,10],[253,10],[502,11],[799,10]]},"1982":{"position":[[1049,10]]},"1984":{"position":[[659,10]]},"2031":{"position":[[332,10]]},"2033":{"position":[[14,10]]},"2089":{"position":[[59,10]]},"2091":{"position":[[56,10],[190,10]]},"2093":{"position":[[39,10],[591,10],[757,10],[780,10]]},"2096":{"position":[[1947,10],[1996,10],[2282,10],[2331,10]]},"2098":{"position":[[3129,10],[3178,10],[3593,10],[3642,10]]},"2100":{"position":[[19,10]]},"2104":{"position":[[182,10]]},"2106":{"position":[[21,10],[204,10],[942,10],[991,10]]},"2122":{"position":[[85,10],[323,10],[549,10],[635,10]]},"2124":{"position":[[0,10]]},"2126":{"position":[[59,10],[124,10],[168,11],[241,10],[351,11],[583,10]]},"2128":{"position":[[129,10],[178,10]]},"2136":{"position":[[0,10]]},"2138":{"position":[[974,10],[1023,10]]},"2206":{"position":[[217,10]]},"2229":{"position":[[76,10]]},"2235":{"position":[[1049,10],[1068,10]]},"2245":{"position":[[22,10],[61,10]]},"2278":{"position":[[22,10],[52,10],[191,10]]},"2312":{"position":[[730,10]]},"2315":{"position":[[1508,10]]},"2324":{"position":[[588,10]]},"2330":{"position":[[603,10]]},"2405":{"position":[[4,10],[73,10]]},"2407":{"position":[[59,10]]},"2461":{"position":[[189,10],[228,10],[311,10]]},"2463":{"position":[[84,10],[204,10]]},"2468":{"position":[[2,10]]},"2474":{"position":[[214,10]]},"2497":{"position":[[347,10]]},"2514":{"position":[[187,10]]},"2522":{"position":[[311,10]]},"2586":{"position":[[87,10]]},"2592":{"position":[[43,10],[148,10],[713,10],[762,10],[850,10],[946,10]]},"2629":{"position":[[352,10]]},"2684":{"position":[[158,11]]},"2735":{"position":[[192,10]]},"2774":{"position":[[328,10]]},"2795":{"position":[[503,10]]},"2944":{"position":[[763,10]]},"2987":{"position":[[897,10]]},"3053":{"position":[[215,10],[410,10]]},"3059":{"position":[[74,10],[109,10],[199,10],[524,11],[843,11]]},"3061":{"position":[[247,10],[589,10],[766,11],[983,11],[1076,10],[1328,11]]},"3069":{"position":[[99,10]]},"3071":{"position":[[90,10],[582,10],[715,10],[776,10],[1144,10],[1225,10],[1804,11],[1940,10],[2021,10],[2115,10]]},"3124":{"position":[[4,10],[327,10],[681,11],[714,10]]},"3126":{"position":[[0,10],[507,10],[877,10]]},"3128":{"position":[[44,10],[115,10],[843,10],[920,10],[947,10],[1047,10],[1117,10]]},"3130":{"position":[[68,10],[108,10]]},"3132":{"position":[[106,10],[231,10]]},"3135":{"position":[[351,10]]},"3139":{"position":[[117,10]]},"3141":{"position":[[186,10],[262,10]]},"3150":{"position":[[226,10]]},"3160":{"position":[[593,10]]},"3167":{"position":[[75,10],[147,10],[222,10],[287,10],[512,10],[600,10]]},"3169":{"position":[[0,10],[123,10],[306,11],[386,10]]},"3173":{"position":[[78,10],[117,10]]},"3178":{"position":[[2,10]]},"3182":{"position":[[459,10],[771,10],[2225,10],[2473,10]]},"3184":{"position":[[597,11],[1165,10],[1233,10],[2810,10]]},"3188":{"position":[[0,10],[45,10]]},"3191":{"position":[[2,10]]},"3195":{"position":[[321,10]]},"3197":{"position":[[90,10],[136,10]]},"3199":{"position":[[65,10],[133,10],[519,10]]},"3227":{"position":[[100,11],[306,10],[477,10]]},"3231":{"position":[[0,10],[438,10]]},"3234":{"position":[[0,10],[689,10]]},"3236":{"position":[[21,10],[190,10],[539,10],[1796,10]]},"3238":{"position":[[47,10],[523,10]]},"3240":{"position":[[64,10],[156,10]]},"3249":{"position":[[673,10]]},"3251":{"position":[[2633,10],[5526,10],[5861,10]]},"3262":{"position":[[0,10],[346,10]]},"3266":{"position":[[21,10],[438,10],[700,10]]},"3270":{"position":[[223,10],[393,10],[486,10],[1114,10],[1823,10]]},"3272":{"position":[[239,11],[965,10]]},"3276":{"position":[[42,10],[779,10],[1077,11],[1579,10],[2201,10],[2476,10],[2784,10]]},"3278":{"position":[[101,10]]},"3280":{"position":[[47,10],[264,10],[604,10],[931,10]]},"3293":{"position":[[226,10]]},"3301":{"position":[[3840,11]]},"3391":{"position":[[332,10]]},"3393":{"position":[[84,10],[174,10]]},"3395":{"position":[[151,10],[1177,10],[1415,10],[1568,10]]},"3397":{"position":[[45,10],[302,10]]},"3400":{"position":[[84,10],[220,10],[1457,10]]},"3431":{"position":[[270,10],[305,10],[347,10]]},"3518":{"position":[[1764,10],[1818,10],[1911,10],[2017,10]]}}}],["kubernetes.io/hostnam",{"_index":9926,"t":{"3201":{"position":[[146,23]]}}}],["kubernetes.io/kubelet",{"_index":10042,"t":{"3276":{"position":[[2672,21]]}}}],["kubernetes.sh",{"_index":7551,"t":{"1779":{"position":[[4697,13]]}}}],["kubernetes/clust",{"_index":9732,"t":{"3061":{"position":[[612,18]]}}}],["kubernetes/config",{"_index":3289,"t":{"627":{"position":[[2242,20]]}}}],["kubernetes/crossplan",{"_index":8068,"t":{"1982":{"position":[[356,22]]}}}],["kubernetes/hack/conform",{"_index":9736,"t":{"3061":{"position":[[705,27]]}}}],["kubernetes/hack/mak",{"_index":9737,"t":{"3061":{"position":[[733,20]]}}}],["kubernetes/kubernetes/test/e2e/framework",{"_index":9727,"t":{"3059":{"position":[[357,42]]}}}],["kubernetes/test/conformance/imag",{"_index":9731,"t":{"3061":{"position":[[428,33]]}}}],["kubernetes/test/conformance/image/go",{"_index":9734,"t":{"3061":{"position":[[661,36]]}}}],["kubernetes/test/e2e/framework",{"_index":9733,"t":{"3061":{"position":[[631,29]]}}}],["kubernetes_verion",{"_index":2740,"t":{"487":{"position":[[796,20]]}}}],["kubernetes_vers",{"_index":2737,"t":{"487":{"position":[[616,18],[635,18]]},"548":{"position":[[58,19]]},"609":{"position":[[226,18]]},"660":{"position":[[2667,21]]}}}],["kubernetesvers",{"_index":3520,"t":{"660":{"position":[[781,18]]}}}],["kubest",{"_index":10207,"t":{"3393":{"position":[[512,9]]},"3400":{"position":[[1063,9]]}}}],["kubevirt",{"_index":9945,"t":{"3218":{"position":[[1578,9]]},"3224":{"position":[[1179,9]]}}}],["kuma",{"_index":10117,"t":{"3314":{"position":[[1538,5]]}}}],["kurt",{"_index":1738,"t":{"249":{"position":[[361,4]]},"893":{"position":[[0,4]]},"1615":{"position":[[0,4]]},"2340":{"position":[[0,4]]}}}],["kustom",{"_index":2494,"t":{"434":{"position":[[6,13]]},"604":{"position":[[181,10]]},"2328":{"position":[[18,9]]}}}],["kv_alloc",{"_index":6428,"t":{"1321":{"position":[[1207,9]]}}}],["kvm",{"_index":3672,"t":{"750":{"position":[[101,3]]},"770":{"position":[[230,4],[275,3],[330,5]]},"977":{"position":[[210,3],[464,3],[506,3],[606,3],[2516,3]]},"1174":{"position":[[14,3]]},"1176":{"position":[[14,3]]},"1226":{"position":[[2226,3]]},"2190":{"position":[[493,4]]},"2705":{"position":[[985,3]]},"2721":{"position":[[40,4],[185,3],[189,3]]},"2723":{"position":[[728,3]]},"2750":{"position":[[964,3]]},"2760":{"position":[[53,4],[197,3],[201,3]]},"2762":{"position":[[741,3]]},"2846":{"position":[[40,4],[185,3],[189,3]]},"2848":{"position":[[717,3]]}}}],["kvm_amd",{"_index":5955,"t":{"1174":{"position":[[107,7],[129,7]]}}}],["kvm_intel",{"_index":5958,"t":{"1176":{"position":[[109,9],[133,9]]}}}],["l",{"_index":2357,"t":{"404":{"position":[[89,1]]},"472":{"position":[[2112,1]]},"590":{"position":[[2014,1],[2202,1]]},"1055":{"position":[[1823,1]]},"1114":{"position":[[3344,1]]},"1224":{"position":[[2909,1],[3726,1]]},"1256":{"position":[[3287,2]]},"1279":{"position":[[354,1],[523,1]]},"1325":{"position":[[433,1],[623,1]]},"1358":{"position":[[227,1]]},"1360":{"position":[[53,1],[101,1],[196,1],[271,1],[302,1],[333,1],[389,1],[413,1],[441,1],[500,1],[550,1],[618,1],[680,1],[753,1]]},"1362":{"position":[[2664,1]]},"1400":{"position":[[693,1]]},"1764":{"position":[[3769,1]]},"1841":{"position":[[618,1]]},"2106":{"position":[[580,1]]},"2705":{"position":[[173,1],[523,1],[1536,1]]},"2711":{"position":[[695,3]]},"2713":{"position":[[1060,2]]},"2719":{"position":[[735,1]]},"2750":{"position":[[173,1],[523,1],[1838,1]]},"2756":{"position":[[777,2]]},"2758":{"position":[[733,1]]},"2840":{"position":[[81,1],[431,1],[1184,1]]},"2856":{"position":[[673,3]]},"2858":{"position":[[870,2]]},"2923":{"position":[[526,4]]},"2933":{"position":[[167,3]]}}}],["l)gplv2",{"_index":1117,"t":{"170":{"position":[[763,8]]}}}],["l,v,t,c",{"_index":9104,"t":{"2700":{"position":[[227,7]]},"2745":{"position":[[227,7]]},"2835":{"position":[[168,7]]}}}],["l/a/gpl",{"_index":1119,"t":{"170":{"position":[[790,7]]}}}],["l/v/t/c[i",{"_index":9398,"t":{"2837":{"position":[[98,10]]}}}],["l0",{"_index":10213,"t":{"3397":{"position":[[1694,2],[1748,2]]}}}],["l1",{"_index":8343,"t":{"2158":{"position":[[757,2]]}}}],["l1_support_contact",{"_index":9573,"t":{"2901":{"position":[[1770,18]]}}}],["l1tf",{"_index":9135,"t":{"2705":{"position":[[726,5],[1030,4],[1404,5],[1936,4]]},"2750":{"position":[[726,5],[1027,4],[1636,4],[2238,4]]},"2840":{"position":[[619,5],[894,4],[1584,4]]}}}],["l3",{"_index":2816,"t":{"487":{"position":[[4698,4]]},"772":{"position":[[994,2]]},"1067":{"position":[[3703,2]]},"2764":{"position":[[1170,2]]}}}],["l=ada",{"_index":9294,"t":{"2727":{"position":[[431,5]]},"2766":{"position":[[631,5]]}}}],["la",{"_index":6191,"t":{"1298":{"position":[[378,2]]}}}],["label",{"_index":752,"t":{"114":{"position":[[185,8],[211,6],[483,5],[489,5]]},"151":{"position":[[378,5]]},"229":{"position":[[337,5]]},"325":{"position":[[796,6]]},"404":{"position":[[899,7]]},"471":{"position":[[1346,7]]},"474":{"position":[[136,5],[182,6],[191,5],[280,5],[349,5],[438,5],[672,5],[758,5]]},"493":{"position":[[141,5],[239,5],[384,5],[522,5],[756,5],[866,5],[937,5],[1029,5],[1174,5],[1312,5],[1558,5],[1674,5]]},"499":{"position":[[615,5],[657,6],[1256,7],[1322,6],[1455,7],[1535,6],[1621,6],[2085,5],[2457,5],[2665,5],[2734,5]]},"662":{"position":[[996,6]]},"1740":{"position":[[75,5],[130,5],[181,5],[239,5],[326,5]]},"2116":{"position":[[722,5]]},"2152":{"position":[[698,5],[706,6]]},"2263":{"position":[[308,6]]},"2700":{"position":[[328,5]]},"2735":{"position":[[235,7],[243,6]]},"2745":{"position":[[328,5]]},"2774":{"position":[[371,7],[379,6]]},"2835":{"position":[[269,5]]},"3182":{"position":[[611,6],[979,6],[1098,6],[1996,8]]},"3184":{"position":[[3023,8]]},"3186":{"position":[[1214,7],[1277,6]]},"3199":{"position":[[1076,8]]},"3201":{"position":[[139,6],[440,6]]},"3353":{"position":[[0,6],[212,6]]},"3378":{"position":[[504,5]]}}}],["label=prometheus_replica",{"_index":8324,"t":{"2152":{"position":[[65,24]]}}}],["lack",{"_index":1643,"t":{"247":{"position":[[102,6]]},"251":{"position":[[367,4],[586,4]]},"337":{"position":[[188,4]]},"760":{"position":[[631,5]]},"905":{"position":[[932,5]]},"1627":{"position":[[932,5]]},"2122":{"position":[[391,5]]},"2352":{"position":[[932,5]]},"2705":{"position":[[1254,7],[1619,4],[1901,4]]},"2750":{"position":[[1921,4],[2203,4]]},"2840":{"position":[[1267,4],[1549,4]]},"3103":{"position":[[895,4]]},"3218":{"position":[[317,4],[474,5]]},"3224":{"position":[[636,4]]},"3251":{"position":[[5731,7]]}}}],["laid",{"_index":9368,"t":{"2781":{"position":[[77,4]]},"3303":{"position":[[26,4]]}}}],["lake",{"_index":9139,"t":{"2705":{"position":[[1058,5]]},"2725":{"position":[[479,4],[526,4],[1190,4]]},"2731":{"position":[[791,4]]},"2750":{"position":[[1055,5]]},"2764":{"position":[[700,4],[747,4]]},"2770":{"position":[[791,4]]},"2840":{"position":[[922,5]]},"2850":{"position":[[388,4],[435,4]]},"2860":{"position":[[752,4]]}}}],["lakritz",{"_index":1515,"t":{"221":{"position":[[29,8]]}}}],["lan",{"_index":6141,"t":{"1282":{"position":[[16,3]]}}}],["land",{"_index":1384,"t":{"193":{"position":[[342,7]]}}}],["landscap",{"_index":561,"t":{"75":{"position":[[247,9]]},"235":{"position":[[1106,10]]},"2407":{"position":[[359,9]]},"3301":{"position":[[4479,10]]}}}],["lang",{"_index":6370,"t":{"1319":{"position":[[214,4]]}}}],["lang=\"en_us.utf",{"_index":7670,"t":{"1805":{"position":[[401,15]]}}}],["lang=c",{"_index":6369,"t":{"1319":{"position":[[183,6],[195,6]]}}}],["languag",{"_index":821,"t":{"131":{"position":[[20,8],[84,8],[217,8]]},"170":{"position":[[819,8]]},"193":{"position":[[553,9]]},"247":{"position":[[264,9],[1367,8],[1434,9]]},"372":{"position":[[241,10]]},"932":{"position":[[2034,9]]},"1234":{"position":[[443,9],[501,8]]},"1654":{"position":[[2034,9]]},"2166":{"position":[[201,9]]},"2176":{"position":[[141,10]]},"2379":{"position":[[2034,9]]},"2951":{"position":[[41,9]]},"3408":{"position":[[274,8]]}}}],["lang|local",{"_index":7669,"t":{"1805":{"position":[[389,11]]}}}],["lanyard",{"_index":1462,"t":{"208":{"position":[[9,8]]}}}],["laptop",{"_index":3268,"t":{"617":{"position":[[551,7]]},"1226":{"position":[[977,6],[1010,6],[1036,6],[1070,6]]},"3204":{"position":[[415,7]]},"3208":{"position":[[114,7]]}}}],["larg",{"_index":1248,"t":{"176":{"position":[[1328,5]]},"245":{"position":[[1897,5]]},"744":{"position":[[46,5],[308,5],[376,5]]},"880":{"position":[[480,5]]},"895":{"position":[[1096,5]]},"909":{"position":[[2782,5]]},"995":{"position":[[311,5],[481,5],[732,5]]},"1091":{"position":[[37,5]]},"1430":{"position":[[607,5]]},"1444":{"position":[[23,5],[309,5],[399,6]]},"1617":{"position":[[1096,5]]},"1631":{"position":[[2782,5]]},"2231":{"position":[[61,5]]},"2265":{"position":[[702,7]]},"2298":{"position":[[702,7]]},"2342":{"position":[[1096,5]]},"2356":{"position":[[2782,5]]},"2697":{"position":[[208,5]]},"2709":{"position":[[833,5]]},"2742":{"position":[[208,5]]},"2754":{"position":[[974,5]]},"2832":{"position":[[208,5]]},"2844":{"position":[[761,5]]},"2921":{"position":[[208,5]]},"2949":{"position":[[411,5]]},"3007":{"position":[[60,5]]},"3014":{"position":[[617,7]]},"3197":{"position":[[204,5],[595,5]]},"3301":{"position":[[4154,5],[4446,5]]},"3314":{"position":[[95,5]]}}}],["larger",{"_index":1064,"t":{"168":{"position":[[652,6]]},"487":{"position":[[3268,6]]},"895":{"position":[[793,6]]},"909":{"position":[[2536,6]]},"986":{"position":[[78,6]]},"995":{"position":[[185,6]]},"1234":{"position":[[2079,7]]},"1617":{"position":[[793,6]]},"1631":{"position":[[2536,6]]},"1835":{"position":[[456,6]]},"2342":{"position":[[793,6]]},"2356":{"position":[[2536,6]]},"2707":{"position":[[178,6]]},"2709":{"position":[[1692,7]]},"2713":{"position":[[812,6]]},"2752":{"position":[[178,6]]},"2754":{"position":[[1833,7]]},"2756":{"position":[[1280,6]]},"2842":{"position":[[177,6]]},"2844":{"position":[[1486,7]]},"2858":{"position":[[650,6]]}}}],["largest",{"_index":7728,"t":{"1831":{"position":[[261,7]]}}}],["last",{"_index":2662,"t":{"474":{"position":[[737,4]]},"760":{"position":[[440,4]]},"796":{"position":[[1341,4],[1428,4]]},"850":{"position":[[9426,4]]},"907":{"position":[[273,4]]},"922":{"position":[[1290,4]]},"1167":{"position":[[2294,4]]},"1224":{"position":[[3401,4]]},"1339":{"position":[[80,4]]},"1368":{"position":[[1746,4],[2042,4],[2100,4],[2425,4],[2721,4],[2779,4]]},"1413":{"position":[[44,4]]},"1484":{"position":[[9426,4]]},"1533":{"position":[[1341,4],[1428,4]]},"1629":{"position":[[273,4]]},"1644":{"position":[[1290,4]]},"1678":{"position":[[26,4],[2790,4]]},"1845":{"position":[[2294,4]]},"1913":{"position":[[1303,4]]},"2029":{"position":[[1303,4]]},"2196":{"position":[[268,4]]},"2324":{"position":[[739,4]]},"2330":{"position":[[4,4]]},"2354":{"position":[[273,4]]},"2369":{"position":[[1290,4]]},"2461":{"position":[[783,5]]},"2491":{"position":[[41,4]]},"2895":{"position":[[3466,4],[3680,4],[3691,4],[4098,4]]},"2960":{"position":[[901,4]]},"2966":{"position":[[2977,4]]},"3284":{"position":[[179,4]]},"3316":{"position":[[1577,4],[1601,4],[1623,4],[1646,4]]}}}],["last_full_d",{"_index":6204,"t":{"1298":{"position":[[636,14]]}}}],["lastnam",{"_index":8030,"t":{"1957":{"position":[[4131,9]]}}}],["late",{"_index":1551,"t":{"231":{"position":[[144,4]]}}}],["latenc",{"_index":2789,"t":{"487":{"position":[[3041,8]]},"615":{"position":[[513,10],[754,9],[1003,7],[1212,10],[1473,7]]},"738":{"position":[[430,7]]},"880":{"position":[[732,8]]},"956":{"position":[[2428,8]]},"1226":{"position":[[380,7],[1119,7],[1262,7],[1368,7]]},"2144":{"position":[[233,7]]},"2245":{"position":[[529,7]]},"2709":{"position":[[489,7],[621,7]]},"2754":{"position":[[489,7],[621,7]]},"2844":{"position":[[417,7],[549,7]]},"2944":{"position":[[471,8],[600,7],[1242,10],[1267,9],[1292,9],[1389,7],[1478,7],[1853,9]]},"2947":{"position":[[1914,10],[2287,9],[2673,8],[3818,8],[3970,7],[5306,8],[6018,7]]},"2949":{"position":[[567,7]]},"2953":{"position":[[293,8]]},"2955":{"position":[[332,7]]},"3251":{"position":[[736,7]]}}}],["latency/bandwidth/iop",{"_index":9889,"t":{"3143":{"position":[[30,26]]}}}],["later",{"_index":1431,"t":{"202":{"position":[[713,5]]},"423":{"position":[[242,5]]},"467":{"position":[[286,5]]},"509":{"position":[[468,6]]},"606":{"position":[[118,6]]},"627":{"position":[[2861,5]]},"635":{"position":[[3875,5]]},"650":{"position":[[1520,5],[2147,6]]},"652":{"position":[[923,6]]},"819":{"position":[[1988,5],[7671,5]]},"821":{"position":[[1440,5]]},"846":{"position":[[219,5]]},"859":{"position":[[1506,5]]},"903":{"position":[[1403,6]]},"932":{"position":[[1532,6]]},"934":{"position":[[1493,6]]},"947":{"position":[[1546,5]]},"984":{"position":[[446,6]]},"988":{"position":[[354,5]]},"1012":{"position":[[392,5]]},"1065":{"position":[[816,6]]},"1067":{"position":[[1852,5]]},"1082":{"position":[[481,6]]},"1234":{"position":[[1044,5],[2642,5],[3046,5]]},"1248":{"position":[[151,5]]},"1258":{"position":[[740,5]]},"1288":{"position":[[291,5],[616,5]]},"1290":{"position":[[183,5]]},"1471":{"position":[[202,6]]},"1480":{"position":[[219,5]]},"1509":{"position":[[1988,5],[7671,5]]},"1511":{"position":[[1440,5]]},"1603":{"position":[[1506,5]]},"1625":{"position":[[1403,6]]},"1654":{"position":[[1532,6]]},"1656":{"position":[[1493,6]]},"1669":{"position":[[1546,5]]},"1686":{"position":[[223,5]]},"1779":{"position":[[3100,5]]},"1843":{"position":[[483,5]]},"1853":{"position":[[484,5]]},"1894":{"position":[[563,5]]},"1900":{"position":[[758,5]]},"1915":{"position":[[484,5]]},"2010":{"position":[[563,5]]},"2016":{"position":[[758,5]]},"2041":{"position":[[543,5]]},"2053":{"position":[[324,5]]},"2096":{"position":[[2152,6]]},"2098":{"position":[[3463,6]]},"2350":{"position":[[1403,6]]},"2379":{"position":[[1532,6]]},"2381":{"position":[[1493,6]]},"2394":{"position":[[1546,5]]},"2729":{"position":[[90,5]]},"2768":{"position":[[113,5]]},"2895":{"position":[[1464,5],[1522,5]]},"3101":{"position":[[42,5]]},"3128":{"position":[[234,5],[314,5]]},"3171":{"position":[[37,5],[108,5]]},"3182":{"position":[[2504,5]]}}}],["latest",{"_index":868,"t":{"133":{"position":[[326,6]]},"158":{"position":[[814,6],[891,6]]},"462":{"position":[[317,6]]},"487":{"position":[[727,6],[2694,6],[2879,6]]},"530":{"position":[[1436,6]]},"604":{"position":[[1265,6],[1755,6],[2453,6],[11033,6]]},"627":{"position":[[3559,6]]},"660":{"position":[[1319,6]]},"790":{"position":[[312,6]]},"796":{"position":[[547,6]]},"805":{"position":[[62,6]]},"846":{"position":[[96,6]]},"850":{"position":[[1402,6],[1853,6],[2182,6],[2361,6],[3068,6],[3988,6],[5333,6],[6248,6],[7016,6],[7834,6],[8822,6],[8955,6]]},"940":{"position":[[82,6]]},"1063":{"position":[[531,6],[635,6],[683,6],[733,6]]},"1069":{"position":[[23,6],[127,6],[175,6],[225,6]]},"1071":{"position":[[180,8],[1336,8]]},"1234":{"position":[[222,6],[386,6]]},"1252":{"position":[[1112,6]]},"1480":{"position":[[96,6]]},"1484":{"position":[[1402,6],[1853,6],[2182,6],[2361,6],[3068,6],[3988,6],[5333,6],[6248,6],[7016,6],[7834,6],[8822,6],[8955,6]]},"1527":{"position":[[312,6]]},"1533":{"position":[[547,6]]},"1542":{"position":[[62,6]]},"1560":{"position":[[63,6]]},"1569":{"position":[[46,6]]},"1662":{"position":[[82,6]]},"1676":{"position":[[376,6],[445,6]]},"1743":{"position":[[2077,6]]},"1779":{"position":[[3243,6]]},"1808":{"position":[[589,6]]},"2206":{"position":[[160,6]]},"2245":{"position":[[15,6]]},"2278":{"position":[[15,6]]},"2294":{"position":[[94,6]]},"2315":{"position":[[1294,6],[1366,6]]},"2387":{"position":[[82,6]]},"2403":{"position":[[167,6]]},"2504":{"position":[[563,6]]},"2675":{"position":[[1026,6]]},"2688":{"position":[[2972,7]]},"2705":{"position":[[650,6]]},"2750":{"position":[[650,6]]},"2805":{"position":[[261,6]]},"2807":{"position":[[616,6]]},"2811":{"position":[[253,6]]},"2840":{"position":[[543,6]]},"2890":{"position":[[421,6]]},"2895":{"position":[[141,6]]},"3128":{"position":[[37,6],[193,6],[273,6]]},"3167":{"position":[[554,6]]},"3171":{"position":[[13,6],[84,6]]}}}],["latest_checksum_url",{"_index":4147,"t":{"850":{"position":[[8868,19],[9463,20]]},"1484":{"position":[[8868,19],[9463,20]]}}}],["latest_url",{"_index":4149,"t":{"850":{"position":[[8923,10],[9558,11]]},"1484":{"position":[[8923,10],[9558,11]]}}}],["latter",{"_index":4441,"t":{"913":{"position":[[227,6]]},"1635":{"position":[[227,6]]},"2360":{"position":[[227,6]]},"2795":{"position":[[1344,6]]},"2807":{"position":[[200,6]]},"2895":{"position":[[2452,6]]},"2911":{"position":[[382,6]]},"2949":{"position":[[182,6]]},"2953":{"position":[[98,6]]},"2987":{"position":[[937,6]]},"3084":{"position":[[431,6]]},"3150":{"position":[[383,6]]}}}],["launch",{"_index":3682,"t":{"756":{"position":[[361,9]]},"1785":{"position":[[349,8]]},"2118":{"position":[[123,6],[843,6]]},"2957":{"position":[[273,8]]}}}],["launched_at",{"_index":8696,"t":{"2566":{"position":[[953,12],[11512,12]]}}}],["launcher",{"_index":7393,"t":{"1745":{"position":[[797,8]]}}}],["launchpad",{"_index":10248,"t":{"3475":{"position":[[346,9]]},"3482":{"position":[[2939,9],[3156,9]]},"3484":{"position":[[62,9],[279,9]]}}}],["law",{"_index":1193,"t":{"174":{"position":[[102,3]]},"911":{"position":[[1255,3]]},"1633":{"position":[[1255,3]]},"2358":{"position":[[1255,3]]}}}],["lawyer",{"_index":1163,"t":{"170":{"position":[[2250,7]]},"178":{"position":[[2056,7]]}}}],["layer",{"_index":627,"t":{"101":{"position":[[446,6],[503,7]]},"116":{"position":[[52,5]]},"327":{"position":[[14,5],[354,5]]},"329":{"position":[[73,5]]},"331":{"position":[[14,5],[216,5],[376,5]]},"333":{"position":[[288,6],[482,5],[542,5]]},"335":{"position":[[580,5]]},"339":{"position":[[14,5],[110,5],[592,6]]},"344":{"position":[[22,5],[94,5],[182,5],[221,5]]},"347":{"position":[[438,5]]},"349":{"position":[[62,5]]},"472":{"position":[[441,6]]},"507":{"position":[[370,5],[709,6]]},"590":{"position":[[2525,6]]},"708":{"position":[[19,6]]},"738":{"position":[[316,5]]},"744":{"position":[[741,5]]},"772":{"position":[[671,6]]},"1073":{"position":[[463,8]]},"1770":{"position":[[235,5],[393,6]]},"1913":{"position":[[218,6]]},"1953":{"position":[[204,5],[409,6]]},"2029":{"position":[[218,6]]},"2089":{"position":[[35,5]]},"2093":{"position":[[433,5]]},"2100":{"position":[[361,6]]},"2108":{"position":[[244,5]]},"2114":{"position":[[55,5]]},"2116":{"position":[[35,5]]},"2118":{"position":[[39,5]]},"2130":{"position":[[240,5]]},"2154":{"position":[[1406,5],[1435,5]]},"2160":{"position":[[45,8]]},"2206":{"position":[[358,5]]},"2229":{"position":[[14,5]]},"2231":{"position":[[45,5]]},"2243":{"position":[[108,5]]},"2265":{"position":[[141,5]]},"2298":{"position":[[141,5]]},"2330":{"position":[[330,6]]},"2413":{"position":[[106,5]]},"2486":{"position":[[56,5],[641,6]]},"2497":{"position":[[358,6]]},"2522":{"position":[[246,6]]},"2530":{"position":[[153,7]]},"2544":{"position":[[9,5],[132,6]]},"2592":{"position":[[67,6]]},"2602":{"position":[[773,5]]},"2651":{"position":[[209,5],[453,6]]},"2660":{"position":[[79,6]]},"2671":{"position":[[351,5],[773,5]]},"2688":{"position":[[2250,5]]},"2697":{"position":[[1624,5]]},"2742":{"position":[[1523,5]]},"2795":{"position":[[438,6],[685,6],[810,7]]},"2807":{"position":[[189,6]]},"2809":{"position":[[186,5]]},"2811":{"position":[[96,5]]},"2817":{"position":[[222,6]]},"2942":{"position":[[290,5],[546,5]]},"2944":{"position":[[234,6],[692,5],[855,5]]},"2947":{"position":[[5607,6]]},"2949":{"position":[[280,5]]},"3180":{"position":[[250,5]]},"3186":{"position":[[276,6]]},"3193":{"position":[[226,5]]},"3218":{"position":[[927,7],[1051,7]]},"3229":{"position":[[27,5]]},"3245":{"position":[[1388,6]]},"3247":{"position":[[25,7],[596,6]]},"3391":{"position":[[25,5],[356,5],[518,5]]},"3395":{"position":[[1188,5]]},"3397":{"position":[[313,6],[1808,6],[1924,5],[2232,5]]},"3413":{"position":[[95,6]]},"3415":{"position":[[343,5],[428,5],[528,6]]},"3423":{"position":[[260,6],[321,5]]},"3518":{"position":[[2616,5]]}}}],["layout",{"_index":5005,"t":{"1073":{"position":[[47,7]]},"1112":{"position":[[22,6]]},"1232":{"position":[[651,7]]},"1234":{"position":[[606,6]]},"1571":{"position":[[56,6]]}}}],["lb",{"_index":2812,"t":{"487":{"position":[[4427,2],[4494,2]]},"505":{"position":[[80,4],[575,2],[909,2]]},"507":{"position":[[334,2],[440,2],[629,2]]},"509":{"position":[[654,2]]},"949":{"position":[[781,4]]},"1368":{"position":[[607,2]]},"1671":{"position":[[781,4]]},"2158":{"position":[[462,2]]},"2396":{"position":[[781,4]]},"2461":{"position":[[868,2]]},"2468":{"position":[[740,2]]},"2502":{"position":[[243,2],[305,2],[556,2]]}}}],["lb_network_ip",{"_index":6808,"t":{"1388":{"position":[[25,15],[411,13]]}}}],["lba",{"_index":6850,"t":{"1413":{"position":[[61,4]]}}}],["lbaa",{"_index":6998,"t":{"1562":{"position":[[219,7],[417,7]]}}}],["lbaf=.servic",{"_index":6942,"t":{"1471":{"position":[[1231,18]]},"1473":{"position":[[1497,18]]}}}],["mds_group_nam",{"_index":5380,"t":{"1120":{"position":[[1442,15]]}}}],["meal",{"_index":1532,"t":{"225":{"position":[[309,5]]}}}],["mean",{"_index":1715,"t":{"247":{"position":[[3002,4]]},"288":{"position":[[161,6]]},"325":{"position":[[3052,5],[3172,5]]},"347":{"position":[[226,5]]},"374":{"position":[[321,5]]},"436":{"position":[[407,5],[1205,5]]},"481":{"position":[[20,5]]},"483":{"position":[[139,7],[908,5]]},"485":{"position":[[124,7],[848,5]]},"487":{"position":[[92,7],[721,5],[3408,5],[3433,5],[4016,7]]},"561":{"position":[[116,7]]},"694":{"position":[[184,5]]},"772":{"position":[[833,5]]},"909":{"position":[[1139,7]]},"942":{"position":[[212,5]]},"1397":{"position":[[280,4]]},"1428":{"position":[[453,4]]},"1442":{"position":[[98,4]]},"1460":{"position":[[144,4]]},"1589":{"position":[[11,5]]},"1631":{"position":[[1139,7]]},"1664":{"position":[[212,5]]},"1684":{"position":[[953,4],[1417,4],[1736,4],[2057,4],[2388,4],[2710,4],[3032,4],[3353,4],[3669,4]]},"1766":{"position":[[597,5]]},"1845":{"position":[[240,5]]},"1865":{"position":[[103,5]]},"1894":{"position":[[68,5]]},"1927":{"position":[[103,5]]},"1945":{"position":[[74,5]]},"1955":{"position":[[146,5]]},"2010":{"position":[[68,5]]},"2033":{"position":[[1905,7]]},"2039":{"position":[[298,7]]},"2047":{"position":[[546,5]]},"2067":{"position":[[269,7],[1356,5]]},"2069":{"position":[[29,5]]},"2106":{"position":[[86,5]]},"2156":{"position":[[114,8]]},"2356":{"position":[[1139,7]]},"2389":{"position":[[212,5]]},"2647":{"position":[[975,5]]},"2697":{"position":[[424,7]]},"2705":{"position":[[99,7]]},"2709":{"position":[[82,7]]},"2721":{"position":[[177,7]]},"2723":{"position":[[188,5]]},"2725":{"position":[[183,5],[837,7],[904,7]]},"2742":{"position":[[424,7]]},"2750":{"position":[[99,7]]},"2754":{"position":[[82,7]]},"2760":{"position":[[189,7]]},"2762":{"position":[[201,5]]},"2764":{"position":[[1058,7],[1479,7]]},"2786":{"position":[[225,7],[464,7]]},"2795":{"position":[[1499,5],[2010,5]]},"2797":{"position":[[49,5]]},"2807":{"position":[[170,6]]},"2809":{"position":[[738,5]]},"2832":{"position":[[424,7]]},"2840":{"position":[[7,7]]},"2844":{"position":[[10,7]]},"2846":{"position":[[177,7]]},"2848":{"position":[[188,5]]},"2850":{"position":[[183,5],[730,7],[797,7]]},"2895":{"position":[[75,5],[796,7],[3604,7],[4446,5]]},"2923":{"position":[[144,5],[295,5],[641,5]]},"2939":{"position":[[410,5]]},"2947":{"position":[[5354,7]]},"2949":{"position":[[553,5],[607,5]]},"2977":{"position":[[79,5]]},"2983":{"position":[[306,7]]},"2985":{"position":[[424,7]]},"3023":{"position":[[77,7]]},"3071":{"position":[[1055,5],[1892,4]]},"3074":{"position":[[262,5]]},"3101":{"position":[[270,6]]},"3126":{"position":[[406,7]]},"3154":{"position":[[186,5]]},"3180":{"position":[[84,7]]},"3182":{"position":[[1026,5]]},"3184":{"position":[[125,6],[307,7],[1703,5],[1964,7]]},"3193":{"position":[[60,7]]},"3195":{"position":[[238,5],[630,4]]},"3199":{"position":[[909,7]]},"3227":{"position":[[594,4]]},"3229":{"position":[[5,7]]},"3251":{"position":[[362,5]]},"3264":{"position":[[90,7]]},"3274":{"position":[[540,7]]},"3276":{"position":[[1814,5]]},"3301":{"position":[[5081,5]]},"3357":{"position":[[761,6]]},"3455":{"position":[[77,7]]},"3463":{"position":[[697,5]]},"3465":{"position":[[348,7],[1301,5]]}}}],["meaning",{"_index":7185,"t":{"1684":{"position":[[80,10]]},"3082":{"position":[[2109,10]]},"3343":{"position":[[132,10]]}}}],["meant",{"_index":4502,"t":{"917":{"position":[[592,5]]},"1639":{"position":[[592,5]]},"1855":{"position":[[547,5]]},"1917":{"position":[[547,5]]},"2035":{"position":[[98,5]]},"2239":{"position":[[49,5]]},"2364":{"position":[[592,5]]},"2647":{"position":[[884,5]]},"2711":{"position":[[1341,5]]},"2795":{"position":[[1125,5]]},"2856":{"position":[[1319,5]]},"2933":{"position":[[872,5]]},"2947":{"position":[[5455,5]]},"2949":{"position":[[117,5]]},"2953":{"position":[[345,5]]},"3472":{"position":[[12697,5]]}}}],["meanwhil",{"_index":1244,"t":{"176":{"position":[[1219,9]]},"774":{"position":[[302,10]]},"2281":{"position":[[200,10]]}}}],["measur",{"_index":1374,"t":{"191":{"position":[[369,8]]},"195":{"position":[[131,9]]},"895":{"position":[[1566,9]]},"1617":{"position":[[1566,9]]},"2085":{"position":[[185,12]]},"2342":{"position":[[1566,9]]},"2486":{"position":[[147,10]]},"2688":{"position":[[2033,8]]},"2705":{"position":[[582,8]]},"2750":{"position":[[582,8]]},"2840":{"position":[[477,8]]},"2868":{"position":[[89,11],[173,7]]},"2872":{"position":[[249,9]]},"2892":{"position":[[455,8]]},"2923":{"position":[[350,8]]},"3238":{"position":[[161,8]]},"3270":{"position":[[700,7]]}}}],["mechan",{"_index":1926,"t":{"296":{"position":[[84,10]]},"467":{"position":[[681,10]]},"499":{"position":[[2091,9],[2269,10]]},"505":{"position":[[37,9]]},"742":{"position":[[22,9]]},"1165":{"position":[[910,10]]},"1591":{"position":[[51,10]]},"1791":{"position":[[115,10]]},"1853":{"position":[[62,10]]},"1888":{"position":[[366,11]]},"1915":{"position":[[62,10]]},"1972":{"position":[[391,11]]},"2004":{"position":[[366,11]]},"2031":{"position":[[268,9]]},"2083":{"position":[[485,11]]},"2176":{"position":[[773,10]]},"2196":{"position":[[1304,9]]},"2688":{"position":[[811,9]]},"2692":{"position":[[266,10]]},"2709":{"position":[[1112,9]]},"2713":{"position":[[150,9]]},"2731":{"position":[[1167,9]]},"2750":{"position":[[1684,9]]},"2754":{"position":[[1253,9]]},"2770":{"position":[[1190,9]]},"2797":{"position":[[35,9]]},"2844":{"position":[[1040,9]]},"2858":{"position":[[150,9]]},"2860":{"position":[[1163,9]]},"2977":{"position":[[103,9]]},"3053":{"position":[[352,10]]},"3074":{"position":[[69,10]]},"3150":{"position":[[432,10]]},"3231":{"position":[[314,11],[383,10]]},"3251":{"position":[[5920,10]]},"3276":{"position":[[1249,10]]},"3351":{"position":[[244,8]]},"3393":{"position":[[886,9]]}}}],["media",{"_index":1377,"t":{"193":{"position":[[24,5],[500,5],[578,5]]},"202":{"position":[[375,6]]},"210":{"position":[[430,6]]},"214":{"position":[[209,6]]},"233":{"position":[[210,5]]},"774":{"position":[[100,5],[259,5]]},"1562":{"position":[[838,5]]},"1569":{"position":[[141,5]]},"2709":{"position":[[1378,6]]},"2754":{"position":[[1519,6]]}}}],["medium",{"_index":2943,"t":{"513":{"position":[[2267,6]]},"1728":{"position":[[276,6],[528,6]]},"2514":{"position":[[371,6]]},"2688":{"position":[[503,7]]},"3014":{"position":[[606,6]]}}}],["meet",{"_index":29,"t":{"4":{"position":[[336,9],[647,5]]},"58":{"position":[[4,8]]},"65":{"position":[[12,8]]},"67":{"position":[[26,8],[61,4]]},"69":{"position":[[8,8]]},"75":{"position":[[44,5]]},"191":{"position":[[287,9]]},"193":{"position":[[465,8]]},"202":{"position":[[391,9]]},"206":{"position":[[56,4]]},"210":{"position":[[449,9]]},"223":{"position":[[83,4]]},"227":{"position":[[457,5]]},"235":{"position":[[1201,8],[1268,8]]},"245":{"position":[[1133,9]]},"249":{"position":[[27,4],[189,4],[404,7]]},"251":{"position":[[249,4]]},"366":{"position":[[144,4]]},"374":{"position":[[662,4]]},"465":{"position":[[597,5]]},"627":{"position":[[582,4]]},"880":{"position":[[439,7]]},"883":{"position":[[1671,4]]},"888":{"position":[[2150,4]]},"1951":{"position":[[393,4]]},"2093":{"position":[[689,4]]},"2272":{"position":[[320,4]]},"2817":{"position":[[293,8]]},"3210":{"position":[[29,4]]},"3222":{"position":[[540,4]]},"3299":{"position":[[1151,5],[2637,5],[3857,5]]},"3482":{"position":[[764,7],[2014,7],[2415,7],[2813,7]]}}}],["meetup",{"_index":1363,"t":{"189":{"position":[[70,8]]},"242":{"position":[[528,7]]}}}],["meltdown",{"_index":9134,"t":{"2705":{"position":[[716,9]]},"2750":{"position":[[716,9]]},"2840":{"position":[[609,9]]}}}],["member",{"_index":217,"t":{"18":{"position":[[83,7]]},"58":{"position":[[95,7]]},"79":{"position":[[527,6]]},"245":{"position":[[888,7],[1205,7]]},"247":{"position":[[408,7],[894,7],[2415,7],[2489,7]]},"286":{"position":[[35,7]]},"499":{"position":[[1963,7],[2136,7]]},"505":{"position":[[99,7]]},"507":{"position":[[508,7]]},"509":{"position":[[86,7],[361,7]]},"511":{"position":[[220,8]]},"596":{"position":[[878,6],[955,6],[1006,6],[1542,7],[1638,6],[1683,6],[1759,6],[2555,6],[2647,7],[2727,7]]},"815":{"position":[[379,6]]},"901":{"position":[[372,6]]},"1108":{"position":[[303,8]]},"1325":{"position":[[377,6]]},"1353":{"position":[[55,6],[132,6],[366,6]]},"1368":{"position":[[1692,6],[2368,6]]},"1505":{"position":[[379,6]]},"1623":{"position":[[372,6]]},"2047":{"position":[[656,6]]},"2348":{"position":[[372,6]]},"2502":{"position":[[308,7],[419,7]]},"2737":{"position":[[188,7]]},"2776":{"position":[[188,7]]},"2947":{"position":[[1051,6]]},"3080":{"position":[[76,6]]},"3101":{"position":[[317,8]]},"3299":{"position":[[1403,8],[2842,8]]},"3325":{"position":[[1207,6],[1266,6],[1403,6],[1579,6],[1705,6],[1804,6],[2077,6],[2289,6],[3242,6],[3284,7]]},"3472":{"position":[[13729,8]]},"3482":{"position":[[1124,8]]}}}],["member':%(target.role.name)",{"_index":5555,"t":{"1150":{"position":[[6221,30]]},"2047":{"position":[[740,30]]},"3472":{"position":[[6064,30],[13860,30]]}}}],["member@lists.scs.commun",{"_index":1810,"t":{"263":{"position":[[429,26]]}}}],["membership",{"_index":247,"t":{"23":{"position":[[241,11]]},"302":{"position":[[124,11],[666,10],[724,11]]},"2065":{"position":[[344,11]]}}}],["memcach",{"_index":6087,"t":{"1242":{"position":[[581,9],[611,9],[633,9]]},"1768":{"position":[[663,9],[693,9],[726,9]]},"1814":{"position":[[229,9]]},"2190":{"position":[[585,10]]}}}],["memori",{"_index":4689,"t":{"982":{"position":[[601,6]]},"984":{"position":[[496,6],[641,6]]},"986":{"position":[[423,6]]},"990":{"position":[[369,6]]},"995":{"position":[[380,6]]},"1122":{"position":[[148,6],[195,6]]},"1124":{"position":[[666,6]]},"1566":{"position":[[250,7]]},"1913":{"position":[[1750,6]]},"2029":{"position":[[1750,6]]},"2148":{"position":[[265,7]]},"2697":{"position":[[769,6]]},"2700":{"position":[[271,6]]},"2707":{"position":[[41,7],[49,6],[185,6],[299,6]]},"2713":{"position":[[1130,6]]},"2719":{"position":[[745,6]]},"2727":{"position":[[728,6]]},"2742":{"position":[[668,6]]},"2745":{"position":[[271,6]]},"2752":{"position":[[41,7],[49,6],[185,6],[299,6]]},"2756":{"position":[[847,6]]},"2758":{"position":[[743,6]]},"2766":{"position":[[928,6],[1118,6]]},"2832":{"position":[[769,6]]},"2835":{"position":[[212,6]]},"2842":{"position":[[47,7],[55,6],[184,6]]},"2852":{"position":[[1074,6]]},"2858":{"position":[[940,6]]},"2947":{"position":[[918,6],[1589,7]]}}}],["memory_mb",{"_index":8678,"t":{"2566":{"position":[[388,10]]}}}],["mental",{"_index":1667,"t":{"247":{"position":[[779,6]]}}}],["mention",{"_index":1349,"t":{"187":{"position":[[374,7]]},"193":{"position":[[100,9]]},"323":{"position":[[354,9]]},"472":{"position":[[1445,9]]},"497":{"position":[[525,9]]},"596":{"position":[[2345,9]]},"604":{"position":[[7564,9],[9274,9]]},"609":{"position":[[2332,9],[5187,9]]},"633":{"position":[[3020,9]]},"635":{"position":[[709,9]]},"1876":{"position":[[10,9]]},"1992":{"position":[[10,9]]},"2071":{"position":[[471,9]]},"2138":{"position":[[829,9]]},"2514":{"position":[[670,9]]},"2729":{"position":[[164,9]]},"2750":{"position":[[1386,9]]},"2768":{"position":[[187,9]]},"2813":{"position":[[1104,10]]},"2852":{"position":[[1263,9]]},"2874":{"position":[[85,9],[135,9]]},"3029":{"position":[[465,9],[545,9]]},"3059":{"position":[[415,9]]},"3061":{"position":[[508,9]]},"3063":{"position":[[314,9]]},"3160":{"position":[[2769,10]]},"3162":{"position":[[373,9]]},"3222":{"position":[[566,9]]},"3270":{"position":[[330,9]]},"3301":{"position":[[4995,10],[7357,9],[7651,9]]},"3343":{"position":[[324,9]]}}}],["mentor",{"_index":1671,"t":{"247":{"position":[[926,6]]}}}],["menu",{"_index":5487,"t":{"1146":{"position":[[143,4]]}}}],["merch",{"_index":1394,"t":{"193":{"position":[[623,6]]},"195":{"position":[[33,5]]},"202":{"position":[[433,6],[455,5],[477,5]]}}}],["merchandis",{"_index":1550,"t":{"231":{"position":[[87,12]]}}}],["mere",{"_index":9002,"t":{"2623":{"position":[[697,6]]}}}],["merg",{"_index":762,"t":{"114":{"position":[[626,7]]},"184":{"position":[[182,7],[278,7],[388,7],[437,7]]},"270":{"position":[[268,5],[308,5]]},"319":{"position":[[168,5],[188,6],[523,5],[633,5]]},"491":{"position":[[192,5]]},"1165":{"position":[[2007,7],[2271,6]]},"1167":{"position":[[181,6],[2275,7],[2620,5]]},"1678":{"position":[[481,7],[2849,6]]},"1684":{"position":[[737,6]]},"2043":{"position":[[495,5]]},"2489":{"position":[[147,6]]},"2631":{"position":[[1316,6]]},"2647":{"position":[[267,6]]}}}],["merge_yaml",{"_index":5847,"t":{"1167":{"position":[[326,11]]}}}],["messag",{"_index":505,"t":{"69":{"position":[[205,7]]},"187":{"position":[[311,9]]},"253":{"position":[[1780,9],[1806,7],[1945,8],[1988,8]]},"347":{"position":[[331,7]]},"374":{"position":[[67,8],[394,7],[446,7],[624,9],[863,8],[961,7],[997,8],[1325,7]]},"409":{"position":[[94,7]]},"590":{"position":[[1359,7]]},"615":{"position":[[92,8]]},"641":{"position":[[638,7]]},"660":{"position":[[1337,7],[3151,7],[3493,7]]},"730":{"position":[[842,7]]},"744":{"position":[[206,7]]},"748":{"position":[[247,7]]},"760":{"position":[[64,7],[170,7],[238,7],[270,7],[445,7]]},"819":{"position":[[1389,7]]},"821":{"position":[[782,7]]},"850":{"position":[[969,7]]},"859":{"position":[[916,7]]},"920":{"position":[[60,8]]},"1077":{"position":[[510,7],[977,7]]},"1256":{"position":[[2039,7],[2240,7]]},"1319":{"position":[[587,7]]},"1400":{"position":[[409,8]]},"1444":{"position":[[645,7]]},"1484":{"position":[[969,7]]},"1491":{"position":[[842,7]]},"1509":{"position":[[1389,7]]},"1511":{"position":[[782,7]]},"1603":{"position":[[916,7]]},"1642":{"position":[[60,8]]},"1734":{"position":[[214,8]]},"1957":{"position":[[4316,7]]},"2321":{"position":[[491,7]]},"2367":{"position":[[60,8]]},"2502":{"position":[[108,7]]},"2564":{"position":[[261,7],[336,7]]},"2566":{"position":[[14806,7]]},"3389":{"position":[[625,8]]}}}],["messages/month",{"_index":9693,"t":{"3014":{"position":[[134,14]]}}}],["met",{"_index":9098,"t":{"2695":{"position":[[232,3]]},"2740":{"position":[[232,3]]}}}],["meta",{"_index":3741,"t":{"790":{"position":[[878,5]]},"794":{"position":[[116,4]]},"796":{"position":[[690,5]]},"798":{"position":[[686,5]]},"800":{"position":[[125,5],[181,4]]},"850":{"position":[[9206,5]]},"947":{"position":[[380,4]]},"1112":{"position":[[5419,5]]},"1317":{"position":[[2471,4],[5803,4]]},"1484":{"position":[[9206,5]]},"1527":{"position":[[878,5]]},"1531":{"position":[[116,4]]},"1533":{"position":[[690,5]]},"1535":{"position":[[686,5]]},"1537":{"position":[[125,5],[181,4]]},"1669":{"position":[[380,4]]},"1743":{"position":[[1639,5]]},"2394":{"position":[[380,4]]},"2886":{"position":[[129,4]]},"3382":{"position":[[43,4]]}}}],["metadata",{"_index":2380,"t":{"404":{"position":[[889,9]]},"449":{"position":[[25,8]]},"471":{"position":[[1292,9]]},"472":{"position":[[977,8]]},"627":{"position":[[1838,8]]},"660":{"position":[[725,9],[1097,9],[1622,9]]},"742":{"position":[[308,8]]},"764":{"position":[[356,8],[442,8]]},"776":{"position":[[266,8]]},"794":{"position":[[59,8],[280,8],[386,8]]},"895":{"position":[[1499,8]]},"947":{"position":[[425,9],[1324,8]]},"1360":{"position":[[1588,8]]},"1362":{"position":[[2031,8],[2080,8]]},"1424":{"position":[[11,8],[31,8]]},"1531":{"position":[[59,8],[280,8],[386,8]]},"1617":{"position":[[1499,8]]},"1669":{"position":[[425,9],[1324,8]]},"1874":{"position":[[311,8]]},"1878":{"position":[[794,8]]},"1880":{"position":[[342,9]]},"1900":{"position":[[495,8]]},"1906":{"position":[[335,8]]},"1908":{"position":[[2669,8]]},"1911":{"position":[[252,9],[615,8]]},"1913":{"position":[[616,9]]},"1957":{"position":[[1330,8],[1759,8]]},"1990":{"position":[[311,8]]},"1994":{"position":[[794,8]]},"1996":{"position":[[342,9]]},"2016":{"position":[[495,8]]},"2022":{"position":[[335,8]]},"2024":{"position":[[2669,8]]},"2027":{"position":[[252,9],[615,8]]},"2029":{"position":[[616,9]]},"2033":{"position":[[210,9],[304,9],[485,9],[847,9],[980,9],[1089,9],[1444,9],[1601,9]]},"2144":{"position":[[216,8]]},"2233":{"position":[[154,8]]},"2248":{"position":[[850,8]]},"2265":{"position":[[689,8]]},"2298":{"position":[[689,8],[949,8]]},"2342":{"position":[[1499,8]]},"2394":{"position":[[425,9],[1324,8]]},"2544":{"position":[[748,8]]},"2546":{"position":[[19,8],[75,8],[496,8]]},"2625":{"position":[[1686,9]]},"2631":{"position":[[734,8],[1912,9],[2051,8]]},"2637":{"position":[[444,8]]},"2639":{"position":[[203,8]]},"2815":{"position":[[723,8]]},"2881":{"position":[[164,8]]},"2913":{"position":[[420,8]]},"2951":{"position":[[1245,8]]},"2955":{"position":[[522,8],[633,8]]},"2960":{"position":[[1151,8]]},"2983":{"position":[[511,8]]},"3251":{"position":[[2803,8]]},"3353":{"position":[[23,8]]},"3382":{"position":[[90,8]]},"3429":{"position":[[418,8]]},"3468":{"position":[[229,8],[431,8],[513,8]]},"3518":{"position":[[1141,8]]}}}],["metadata.md",{"_index":9392,"t":{"2815":{"position":[[829,11]]}}}],["metadata.yaml",{"_index":2336,"t":{"393":{"position":[[1417,13]]}}}],["metadata_item",{"_index":3889,"t":{"821":{"position":[[2613,17],[3926,17],[5262,17]]},"1511":{"position":[[2613,17],[3926,17],[5262,17]]}}}],["metadef",{"_index":9313,"t":{"2731":{"position":[[1158,8]]},"2770":{"position":[[1181,8]]},"2860":{"position":[[1154,8]]}}}],["metal",{"_index":4262,"t":{"865":{"position":[[96,5]]},"878":{"position":[[96,5]]},"1219":{"position":[[390,5],[432,5]]},"1224":{"position":[[503,5]]},"1226":{"position":[[491,5]]},"1560":{"position":[[215,5]]},"1587":{"position":[[127,6]]},"2100":{"position":[[1215,5]]},"2196":{"position":[[41,6],[75,5]]},"2206":{"position":[[254,5]]},"2226":{"position":[[16,5],[164,5]]},"2243":{"position":[[64,5]]},"2248":{"position":[[1179,5]]},"2700":{"position":[[433,5]]},"2721":{"position":[[94,5],[233,5]]},"2723":{"position":[[298,5],[849,5]]},"2725":{"position":[[1173,6]]},"2745":{"position":[[433,5]]},"2760":{"position":[[106,5],[245,5]]},"2762":{"position":[[311,5],[862,5]]},"2764":{"position":[[1748,6]]},"2835":{"position":[[374,5]]},"2846":{"position":[[94,5],[233,5]]},"2848":{"position":[[298,5]]},"3003":{"position":[[778,5]]},"3180":{"position":[[115,5],[195,5],[375,5]]},"3193":{"position":[[91,5],[171,5],[351,5]]}}}],["meter",{"_index":318,"t":{"27":{"position":[[1027,8]]},"2409":{"position":[[829,8]]},"2426":{"position":[[567,8]]},"2560":{"position":[[45,8]]},"2564":{"position":[[112,7],[138,6]]},"2568":{"position":[[369,6],[450,8]]},"2570":{"position":[[34,7]]},"2602":{"position":[[821,8],[930,8]]},"2651":{"position":[[85,8],[398,9]]},"3370":{"position":[[392,8],[530,8]]},"3372":{"position":[[168,9]]},"3374":{"position":[[226,8],[261,8],[526,8]]},"3378":{"position":[[407,8]]},"3419":{"position":[[118,9],[167,8],[421,8]]},"3423":{"position":[[158,8],[352,8]]},"3434":{"position":[[392,8]]},"3436":{"position":[[234,9],[475,8]]},"3438":{"position":[[214,8]]},"3442":{"position":[[61,8],[298,8]]},"3518":{"position":[[2668,8],[2785,8]]}}}],["meter_sink",{"_index":8967,"t":{"2570":{"position":[[57,10],[83,10]]}}}],["meter_sourc",{"_index":8966,"t":{"2570":{"position":[[21,12]]}}}],["method",{"_index":1002,"t":{"160":{"position":[[45,7]]},"298":{"position":[[599,7]]},"319":{"position":[[606,8]]},"1165":{"position":[[1997,6]]},"1234":{"position":[[1311,6]]},"1745":{"position":[[70,6]]},"2043":{"position":[[784,6]]},"2077":{"position":[[367,8]]},"2098":{"position":[[78,6],[146,6],[239,8]]},"2566":{"position":[[13526,7]]},"2872":{"position":[[211,7]]},"2874":{"position":[[127,7]]},"3071":{"position":[[2580,7]]},"3270":{"position":[[434,7]]},"3365":{"position":[[135,6]]}}}],["metric",{"_index":1401,"t":{"193":{"position":[[773,7],[818,8]]},"487":{"position":[[4087,7]]},"604":{"position":[[7679,7],[9389,7],[10087,7],[11877,7]]},"609":{"position":[[2447,7],[5302,7]]},"613":{"position":[[7,7]]},"627":{"position":[[1372,7],[3888,7]]},"631":{"position":[[712,7]]},"660":{"position":[[3045,7],[3361,7],[3392,8]]},"1317":{"position":[[365,7],[496,7],[582,7],[7024,7]]},"2085":{"position":[[382,8],[471,8]]},"2096":{"position":[[11,7],[1001,7],[1199,8],[1390,7]]},"2098":{"position":[[275,7],[384,7],[440,7],[560,8],[658,7],[803,8],[833,7],[886,7],[934,7],[2582,7]]},"2104":{"position":[[218,6]]},"2106":{"position":[[101,7]]},"2108":{"position":[[333,7]]},"2116":{"position":[[67,6],[119,6],[428,7],[506,6],[536,6],[705,6],[833,6]]},"2118":{"position":[[70,7]]},"2126":{"position":[[619,6]]},"2130":{"position":[[329,7]]},"2154":{"position":[[89,7],[173,7]]},"2158":{"position":[[217,8]]},"2206":{"position":[[117,8]]},"2229":{"position":[[554,7]]},"2263":{"position":[[296,7]]},"2409":{"position":[[591,7]]},"2560":{"position":[[4,7],[144,7]]},"2562":{"position":[[51,7],[157,7],[218,7]]},"2568":{"position":[[295,7]]},"3160":{"position":[[1492,7]]},"3301":{"position":[[381,7],[6324,8],[6354,8],[6401,8]]},"3372":{"position":[[415,7],[465,6],[559,8],[579,7],[664,6],[720,6]]},"3376":{"position":[[399,7],[478,7],[540,7],[645,7]]},"3378":{"position":[[475,8],[510,7],[628,6]]},"3389":{"position":[[465,8]]},"3393":{"position":[[299,7],[329,7],[369,7],[377,7],[522,8],[614,7],[691,7],[865,7]]},"3395":{"position":[[383,7],[812,7]]},"3397":{"position":[[852,7],[1384,6],[1588,7],[2475,7]]},"3400":{"position":[[940,7],[970,7],[1018,7],[1073,8],[1165,7],[1205,7],[1213,7]]},"3440":{"position":[[63,7],[156,7],[218,7]]}}}],["mgmt",{"_index":2671,"t":{"483":{"position":[[212,4],[282,4],[336,4]]},"485":{"position":[[562,4],[734,4],[801,4]]},"641":{"position":[[225,4]]},"1368":{"position":[[610,4]]}}}],["mgmt_cidr",{"_index":2691,"t":{"483":{"position":[[922,9],[1084,9]]}}}],["mgmt_ip_rang",{"_index":2695,"t":{"483":{"position":[[1006,13]]}}}],["mgmtcluster",{"_index":2964,"t":{"540":{"position":[[22,11],[198,12]]},"542":{"position":[[26,11],[225,12]]},"604":{"position":[[2305,13]]}}}],["mgr",{"_index":5362,"t":{"1118":{"position":[[996,5]]},"1286":{"position":[[987,3],[1017,4]]},"1469":{"position":[[93,3],[208,5]]},"1471":{"position":[[1276,3],[1456,3]]},"1473":{"position":[[657,3]]},"2315":{"position":[[243,3],[367,5]]}}}],["mgr.5184",{"_index":6387,"t":{"1321":{"position":[[208,10],[865,10]]}}}],["mgr.testb",{"_index":6386,"t":{"1321":{"position":[[189,11],[846,11]]}}}],["mgr@.servic",{"_index":6943,"t":{"1471":{"position":[[1491,18]]}}}],["mgr_group_nam",{"_index":5381,"t":{"1120":{"position":[[1473,15]]}}}],["mib",{"_index":6398,"t":{"1321":{"position":[[300,3],[957,3]]},"2892":{"position":[[303,4]]}}}],["micro)servic",{"_index":2532,"t":{"444":{"position":[[273,15]]},"472":{"position":[[262,15]]}}}],["microcod",{"_index":9132,"t":{"2705":{"position":[[657,9],[739,9],[1210,9],[1738,10],[1890,10]]},"2750":{"position":[[657,9],[754,9],[1464,9],[2040,10],[2192,10]]},"2840":{"position":[[550,9],[647,9],[1386,10],[1538,10]]}}}],["microphon",{"_index":1757,"t":{"251":{"position":[[333,10]]}}}],["microservic",{"_index":3577,"t":{"669":{"position":[[647,12]]}}}],["microsoft",{"_index":1057,"t":{"168":{"position":[[414,9]]},"3014":{"position":[[648,10]]}}}],["microvers",{"_index":7945,"t":{"1896":{"position":[[373,12]]},"2012":{"position":[[373,12]]}}}],["mid",{"_index":7998,"t":{"1953":{"position":[[301,3]]}}}],["middl",{"_index":2630,"t":{"472":{"position":[[1856,6]]},"3082":{"position":[[1765,6]]}}}],["middlewar",{"_index":8282,"t":{"2144":{"position":[[98,14]]}}}],["midnight&skip=0",{"_index":7454,"t":{"1758":{"position":[[1567,16]]}}}],["migrat",{"_index":818,"t":{"129":{"position":[[367,9]]},"339":{"position":[[500,9]]},"417":{"position":[[68,9],[185,9],[377,9],[601,7],[663,7],[1052,10]]},"419":{"position":[[61,9]]},"421":{"position":[[5,9],[49,7],[420,7],[997,9]]},"423":{"position":[[261,10]]},"428":{"position":[[19,7]]},"460":{"position":[[646,10],[744,9],[795,9],[914,9],[954,9]]},"469":{"position":[[169,7]]},"604":{"position":[[7984,9]]},"609":{"position":[[1234,7],[1438,8],[1530,8],[1657,9],[1770,7],[4230,7],[4384,7],[4572,7],[5559,7],[5583,7]]},"656":{"position":[[225,7]]},"658":{"position":[[10,8],[55,9],[338,10]]},"660":{"position":[[1420,7]]},"662":{"position":[[334,8],[487,8],[661,9],[699,7],[760,10]]},"667":{"position":[[80,7]]},"786":{"position":[[785,9]]},"833":{"position":[[5,7],[133,7]]},"977":{"position":[[1262,10]]},"1358":{"position":[[5,7]]},"1362":{"position":[[160,7]]},"1523":{"position":[[785,9]]},"1548":{"position":[[5,7],[133,7]]},"1827":{"position":[[52,9],[100,9],[325,10],[338,9],[560,9],[649,10]]},"1829":{"position":[[278,7]]},"1845":{"position":[[2343,8]]},"2250":{"position":[[424,9]]},"2292":{"position":[[186,9]]},"2409":{"position":[[754,9]]},"2413":{"position":[[175,8]]},"2461":{"position":[[758,8],[811,9]]},"2504":{"position":[[657,9]]},"2709":{"position":[[457,10]]},"2737":{"position":[[317,10]]},"2754":{"position":[[457,10]]},"2776":{"position":[[317,10]]},"2844":{"position":[[385,10]]},"2923":{"position":[[998,10]]},"2947":{"position":[[1332,9]]},"2951":{"position":[[737,9],[913,9],[1066,9],[1194,9]]},"2955":{"position":[[611,9],[684,9],[706,9]]},"2960":{"position":[[1112,8],[1228,9]]},"2966":{"position":[[1467,9],[2003,9]]},"3011":{"position":[[990,9]]},"3160":{"position":[[1348,9]]}}}],["migration_interfac",{"_index":4977,"t":{"1067":{"position":[[5089,20]]},"1163":{"position":[[195,19]]}}}],["milan",{"_index":9227,"t":{"2719":{"position":[[924,5]]},"2725":{"position":[[537,7]]},"2758":{"position":[[922,5]]},"2764":{"position":[[758,7],[1759,5]]},"2850":{"position":[[446,7]]}}}],["milk",{"_index":1538,"t":{"225":{"position":[[404,5]]},"231":{"position":[[308,5]]}}}],["mimic",{"_index":9938,"t":{"3214":{"position":[[83,5]]},"3216":{"position":[[295,5]]},"3218":{"position":[[251,5],[498,5],[1854,5]]},"3222":{"position":[[804,6]]},"3224":{"position":[[736,5],[1579,6]]}}}],["mimick",{"_index":7949,"t":{"1896":{"position":[[1188,8]]},"1913":{"position":[[1337,8]]},"2012":{"position":[[1188,8]]},"2029":{"position":[[1337,8]]},"3220":{"position":[[204,9]]}}}],["min",{"_index":480,"t":{"63":{"position":[[52,5]]},"1169":{"position":[[173,3],[253,3]]},"1333":{"position":[[237,4]]},"1339":{"position":[[191,4]]},"3270":{"position":[[968,3]]},"3280":{"position":[[337,3]]}}}],["min_disk",{"_index":3739,"t":{"790":{"position":[[806,9]]},"796":{"position":[[619,9]]},"798":{"position":[[613,9]]},"800":{"position":[[222,8]]},"850":{"position":[[9135,9]]},"1484":{"position":[[9135,9]]},"1527":{"position":[[806,9]]},"1533":{"position":[[619,9]]},"1535":{"position":[[613,9]]},"1537":{"position":[[222,8]]},"2709":{"position":[[874,9],[1668,9]]},"2754":{"position":[[1015,9],[1809,9]]},"2844":{"position":[[802,9],[1462,9]]}}}],["min_disk_s",{"_index":9524,"t":{"2892":{"position":[[267,13]]}}}],["min_ram",{"_index":3740,"t":{"790":{"position":[[818,8]]},"796":{"position":[[631,8]]},"798":{"position":[[625,8]]},"800":{"position":[[235,7]]},"850":{"position":[[9147,8]]},"1484":{"position":[[9147,8]]},"1527":{"position":[[818,8]]},"1533":{"position":[[631,8]]},"1535":{"position":[[625,8]]},"1537":{"position":[[235,7]]},"2892":{"position":[[291,7]]}}}],["min_siz",{"_index":5199,"t":{"1110":{"position":[[275,9]]}}}],["min_step",{"_index":8329,"t":{"2152":{"position":[[517,9]]}}}],["mind",{"_index":2156,"t":{"335":{"position":[[1125,5]]},"427":{"position":[[127,4]]},"428":{"position":[[902,4]]},"487":{"position":[[5088,4]]},"513":{"position":[[604,4]]},"590":{"position":[[126,4]]},"1791":{"position":[[562,5]]},"2196":{"position":[[708,4]]},"3314":{"position":[[3540,4]]}}}],["mindset",{"_index":9695,"t":{"3014":{"position":[[273,9]]}}}],["mineri",{"_index":333,"t":{"27":{"position":[[1382,6]]}}}],["minim",{"_index":103,"t":{"10":{"position":[[512,7]]},"89":{"position":[[5,7]]},"319":{"position":[[98,7]]},"850":{"position":[[6960,7],[7115,7],[7368,7],[7673,7]]},"888":{"position":[[1883,9]]},"977":{"position":[[929,7],[1557,7]]},"980":{"position":[[229,7]]},"1234":{"position":[[2008,8]]},"1484":{"position":[[6960,7],[7115,7],[7368,7],[7673,7]]},"2250":{"position":[[143,9]]},"2673":{"position":[[1025,7]]},"3011":{"position":[[1426,7]]},"3208":{"position":[[155,8]]},"3224":{"position":[[287,9]]},"3249":{"position":[[663,9]]},"3314":{"position":[[1981,8]]},"3340":{"position":[[22,7]]}}}],["minimalist",{"_index":6995,"t":{"1560":{"position":[[30,12]]}}}],["minimum",{"_index":3762,"t":{"792":{"position":[[79,7]]},"1379":{"position":[[288,7],[786,7]]},"1529":{"position":[[79,7]]},"1562":{"position":[[59,7],[178,7],[298,7]]},"2150":{"position":[[265,7],[573,7]]},"2642":{"position":[[112,7]]},"3186":{"position":[[632,7]]},"3347":{"position":[[602,7]]}}}],["minimum/optim",{"_index":5290,"t":{"1114":{"position":[[3541,18]]}}}],["minio",{"_index":4069,"t":{"850":{"position":[[292,5],[314,5],[381,5],[403,5],[470,5],[488,5],[575,5],[593,5]]},"1484":{"position":[[292,5],[314,5],[381,5],[403,5],[470,5],[488,5],[575,5],[593,5]]}}}],["minio.services.osism.tech",{"_index":8535,"t":{"2417":{"position":[[82,25]]}}}],["minio_access_key",{"_index":4071,"t":{"850":{"position":[[341,17]]},"1484":{"position":[[341,17]]}}}],["minio_bucket",{"_index":4075,"t":{"850":{"position":[[616,13]]},"1484":{"position":[[616,13]]}}}],["minio_secret_key",{"_index":4072,"t":{"850":{"position":[[430,17]]},"1484":{"position":[[430,17]]}}}],["minio_serv",{"_index":4073,"t":{"850":{"position":[[511,13]]},"1484":{"position":[[511,13]]}}}],["ministri",{"_index":3586,"t":{"694":{"position":[[122,8]]},"2434":{"position":[[233,8]]}}}],["minor",{"_index":2143,"t":{"333":{"position":[[300,5]]},"460":{"position":[[394,5]]},"604":{"position":[[8036,5]]},"609":{"position":[[1596,5],[2857,5]]},"1610":{"position":[[266,5]]},"1674":{"position":[[48,5],[111,5],[265,5],[312,5],[359,5]]},"2298":{"position":[[896,5]]},"2315":{"position":[[1077,5]]},"2424":{"position":[[9,5]]},"2901":{"position":[[1242,7]]},"3124":{"position":[[131,5],[232,5],[796,5]]},"3128":{"position":[[200,5]]},"3167":{"position":[[258,5],[401,5],[456,5],[563,5]]},"3171":{"position":[[20,5]]}}}],["minut",{"_index":2027,"t":{"321":{"position":[[1663,7]]},"391":{"position":[[1108,8]]},"487":{"position":[[3759,8]]},"909":{"position":[[1398,8]]},"911":{"position":[[322,6]]},"1360":{"position":[[1256,7],[1273,7],[1384,7],[1401,7],[1509,7],[1526,7]]},"1569":{"position":[[870,8]]},"1631":{"position":[[1398,8]]},"1633":{"position":[[322,6]]},"1731":{"position":[[1205,6],[1227,6],[1338,6],[1360,6],[1450,6],[1472,6],[1612,6],[1634,6],[1736,6],[1758,6],[1863,6],[1885,6],[1984,6],[2006,6],[2148,6],[2170,6],[2273,6],[2295,6],[2408,6],[2430,6],[2544,6],[2566,6],[2671,6],[2693,6],[2806,6],[2828,6],[2940,6],[2962,6],[3073,6],[3095,6],[3188,6],[3210,6]]},"1779":{"position":[[4042,7]]},"1822":{"position":[[196,7]]},"2096":{"position":[[1276,6]]},"2118":{"position":[[1301,7]]},"2150":{"position":[[417,8]]},"2356":{"position":[[1398,8]]},"2358":{"position":[[322,6]]},"3284":{"position":[[163,7],[188,8]]}}}],["mirror",{"_index":3319,"t":{"633":{"position":[[519,6],[1793,6],[3598,6]]},"635":{"position":[[1128,6]]},"788":{"position":[[7,6],[91,6]]},"803":{"position":[[70,6]]},"805":{"position":[[124,8]]},"846":{"position":[[140,6],[182,7]]},"850":{"position":[[1258,9],[9019,6]]},"1480":{"position":[[140,6],[182,7]]},"1484":{"position":[[1258,9],[9019,6]]},"1525":{"position":[[7,6],[91,6]]},"1540":{"position":[[70,6]]},"1542":{"position":[[124,8]]},"1982":{"position":[[1260,8]]},"1984":{"position":[[870,8]]},"2031":{"position":[[82,6]]},"2033":{"position":[[99,6]]},"2315":{"position":[[618,8]]},"2901":{"position":[[1421,8]]},"3472":{"position":[[12441,6]]}}}],["mirror_url",{"_index":4150,"t":{"850":{"position":[[8968,10],[9985,11]]},"1484":{"position":[[8968,10],[9985,11]]}}}],["misconfigur",{"_index":9776,"t":{"3103":{"position":[[329,16],[755,16]]},"3195":{"position":[[131,18]]}}}],["mislead",{"_index":9910,"t":{"3184":{"position":[[1202,10]]}}}],["mismatch",{"_index":9373,"t":{"2786":{"position":[[114,8],[387,8]]}}}],["miss",{"_index":1979,"t":{"311":{"position":[[216,7]]},"631":{"position":[[414,7]]},"1386":{"position":[[205,7]]},"1779":{"position":[[3092,7]]},"1833":{"position":[[1256,7]]},"2705":{"position":[[2140,7]]},"2735":{"position":[[1213,7]]},"2750":{"position":[[2442,7]]},"2774":{"position":[[1215,7]]},"2840":{"position":[[1788,7]]},"2913":{"position":[[75,7],[128,7]]},"2935":{"position":[[256,7]]},"2994":{"position":[[219,7]]},"3299":{"position":[[684,7]]},"3370":{"position":[[23,7]]},"3434":{"position":[[23,7]]}}}],["mission",{"_index":519,"t":{"69":{"position":[[418,7]]},"166":{"position":[[36,7]]},"954":{"position":[[129,7]]}}}],["mistak",{"_index":1608,"t":{"242":{"position":[[311,8],[359,7]]},"247":{"position":[[3174,9]]},"280":{"position":[[364,8]]},"427":{"position":[[1007,7]]}}}],["mistral_api_public_port",{"_index":5695,"t":{"1159":{"position":[[1591,24]]}}}],["mistral_external_fqdn",{"_index":5694,"t":{"1159":{"position":[[1540,21]]}}}],["mistral_public_endpoint",{"_index":5693,"t":{"1159":{"position":[[1516,23]]}}}],["mit",{"_index":1153,"t":{"170":{"position":[[2041,3]]}}}],["mitig",{"_index":2508,"t":{"436":{"position":[[720,11]]},"2096":{"position":[[1211,8]]},"2705":{"position":[[917,11],[1239,10],[1313,11],[1765,11]]},"2750":{"position":[[896,11],[1317,11],[1706,12],[2067,11]]},"2840":{"position":[[804,11],[1413,11]]},"2947":{"position":[[1434,8]]},"3227":{"position":[[403,9]]},"3231":{"position":[[338,8]]},"3236":{"position":[[2659,8]]},"3262":{"position":[[315,8]]},"3270":{"position":[[1187,8]]},"3272":{"position":[[488,8]]},"3389":{"position":[[1026,8]]}}}],["mix",{"_index":9639,"t":{"2962":{"position":[[300,3]]},"3115":{"position":[[504,4]]},"3395":{"position":[[1408,3]]}}}],["mixin",{"_index":8179,"t":{"2098":{"position":[[1185,6],[2405,6],[2445,6],[2677,5]]},"3395":{"position":[[1426,5]]},"3400":{"position":[[1468,5]]}}}],["mixin/prometheus_alerts.yml",{"_index":8181,"t":{"2098":{"position":[[1688,27]]}}}],["mixtur",{"_index":2884,"t":{"501":{"position":[[353,7]]},"2658":{"position":[[104,7]]}}}],["mkdir",{"_index":2327,"t":{"393":{"position":[[849,5]]},"467":{"position":[[2061,5]]},"635":{"position":[[1320,5]]},"913":{"position":[[3593,5]]},"1063":{"position":[[116,5]]},"1475":{"position":[[119,5]]},"1635":{"position":[[3593,5]]},"1747":{"position":[[490,5]]},"1779":{"position":[[261,5]]},"2360":{"position":[[3593,5]]}}}],["mkk9fdv9wujiqtuyhaofmd+uys/hqvsf/hm9scuvfhw02gtdzkcxliwhfhjoj7rbduumk",{"_index":2091,"t":{"325":{"position":[[4704,69]]}}}],["ml",{"_index":6229,"t":{"1305":{"position":[[318,2]]}}}],["ml2",{"_index":9680,"t":{"3003":{"position":[[307,3],[483,3]]}}}],["mm",{"_index":9546,"t":{"2895":{"position":[[3005,2],[3764,2],[3818,2]]},"2899":{"position":[[45,2],[59,2]]},"2901":{"position":[[1679,2]]}}}],["mnt/test",{"_index":7784,"t":{"1841":{"position":[[639,10]]}}}],["mobil",{"_index":1752,"t":{"251":{"position":[[220,6]]}}}],["mock",{"_index":8240,"t":{"2116":{"position":[[1006,4]]},"2118":{"position":[[139,4],[551,4],[859,4],[944,4]]},"3059":{"position":[[1116,4]]},"3397":{"position":[[2024,6],[2051,4],[2264,6]]}}}],["mod_auth_mellon",{"_index":1930,"t":{"298":{"position":[[269,15]]}}}],["mod_auth_openidc",{"_index":1928,"t":{"298":{"position":[[236,17]]}}}],["mod_oauth2",{"_index":1929,"t":{"298":{"position":[[254,10]]},"2248":{"position":[[1072,10]]}}}],["mode",{"_index":888,"t":{"139":{"position":[[165,5],[563,5]]},"270":{"position":[[274,4]]},"319":{"position":[[174,5],[529,4]]},"393":{"position":[[38,6],[115,4],[247,4],[300,5],[689,4]]},"428":{"position":[[300,4],[888,5],[925,4],[1258,4],[1877,5],[1982,4],[2035,4]]},"474":{"position":[[27,4],[1337,4]]},"491":{"position":[[198,5]]},"507":{"position":[[632,6]]},"557":{"position":[[195,4],[233,4]]},"559":{"position":[[93,4]]},"561":{"position":[[99,4]]},"644":{"position":[[236,5]]},"1089":{"position":[[2689,4]]},"1161":{"position":[[1682,4]]},"1167":{"position":[[636,5],[3567,7]]},"1335":{"position":[[165,4]]},"1585":{"position":[[1572,6]]},"1697":{"position":[[166,5],[564,5]]},"1749":{"position":[[226,5],[378,5]]},"1775":{"position":[[159,6]]},"1894":{"position":[[709,4]]},"1900":{"position":[[271,4],[394,4]]},"2010":{"position":[[709,4]]},"2016":{"position":[[271,4],[394,4]]},"2100":{"position":[[1160,4]]},"2586":{"position":[[281,4]]},"3141":{"position":[[41,4]]},"3160":{"position":[[1503,4]]},"3210":{"position":[[582,5]]},"3236":{"position":[[2569,5]]},"3272":{"position":[[479,5],[1056,4]]},"3282":{"position":[[256,4]]},"3301":{"position":[[1317,5],[6421,4]]}}}],["mode=webhook",{"_index":9983,"t":{"3236":{"position":[[2835,12]]}}}],["model",{"_index":1266,"t":{"178":{"position":[[680,6]]},"327":{"position":[[661,6]]},"449":{"position":[[44,7]]},"472":{"position":[[996,7]]},"513":{"position":[[595,5],[614,5],[984,5]]},"883":{"position":[[50,5]]},"980":{"position":[[17,6]]},"984":{"position":[[387,5]]},"1112":{"position":[[767,6]]},"1114":{"position":[[3419,6]]},"1165":{"position":[[2538,6]]},"1587":{"position":[[474,5]]},"1974":{"position":[[46,9]]},"2176":{"position":[[164,7]]},"2665":{"position":[[348,5]]},"2719":{"position":[[207,7]]},"2758":{"position":[[206,7]]},"3197":{"position":[[1135,5]]},"3227":{"position":[[545,6]]},"3247":{"position":[[128,6]]},"3251":{"position":[[4333,6]]}}}],["moder",{"_index":1736,"t":{"249":{"position":[[277,9]]},"922":{"position":[[517,10]]},"1165":{"position":[[1871,9]]},"1644":{"position":[[517,10]]},"2369":{"position":[[517,10]]}}}],["modern",{"_index":1176,"t":{"172":{"position":[[338,6]]},"366":{"position":[[841,6]]},"895":{"position":[[272,6],[1952,7]]},"1617":{"position":[[272,6],[1952,7]]},"1963":{"position":[[32,6]]},"2342":{"position":[[272,6],[1952,7]]},"3408":{"position":[[255,6]]}}}],["modif",{"_index":1053,"t":{"168":{"position":[[147,14],[343,13]]},"253":{"position":[[614,14]]},"726":{"position":[[51,13]]},"1487":{"position":[[51,13]]},"3236":{"position":[[1941,12]]}}}],["modifi",{"_index":963,"t":{"147":{"position":[[329,8]]},"240":{"position":[[53,8]]},"253":{"position":[[912,8]]},"635":{"position":[[351,6]]},"817":{"position":[[355,6]]},"819":{"position":[[35,6]]},"1165":{"position":[[3383,6]]},"1507":{"position":[[355,6]]},"1509":{"position":[[35,6]]},"1701":{"position":[[319,8]]},"1715":{"position":[[114,9]]},"1805":{"position":[[225,6]]},"1951":{"position":[[735,6]]},"2071":{"position":[[432,6]]},"2110":{"position":[[222,6],[587,8],[700,8],[789,8],[882,8]]},"2631":{"position":[[1950,6]]},"2673":{"position":[[1605,6]]},"2719":{"position":[[1826,9]]},"2758":{"position":[[1942,9]]},"2858":{"position":[[1730,9]]},"2923":{"position":[[459,8],[843,9]]},"3372":{"position":[[357,9]]},"3376":{"position":[[217,6]]},"3457":{"position":[[23,8]]}}}],["modify_at",{"_index":8929,"t":{"2566":{"position":[[12459,10],[12672,10]]}}}],["modprob",{"_index":5954,"t":{"1174":{"position":[[95,8],[120,8]]},"1176":{"position":[[97,8],[124,8]]}}}],["modul",{"_index":604,"t":{"87":{"position":[[172,6]]},"105":{"position":[[128,7]]},"166":{"position":[[563,7]]},"282":{"position":[[4,6],[63,6],[290,6],[382,6],[413,6],[564,6]]},"284":{"position":[[213,7]]},"286":{"position":[[50,6]]},"298":{"position":[[223,7],[393,7],[825,8]]},"568":{"position":[[85,8]]},"762":{"position":[[25,6]]},"772":{"position":[[25,6],[566,6]]},"876":{"position":[[48,7],[222,7],[293,7],[370,7]]},"988":{"position":[[317,8]]},"1017":{"position":[[365,7],[377,6]]},"1033":{"position":[[155,7]]},"1383":{"position":[[237,7]]},"1721":{"position":[[82,6]]},"2098":{"position":[[867,7]]},"2673":{"position":[[809,6]]},"2872":{"position":[[640,6]]},"3007":{"position":[[197,6]]},"3011":{"position":[[247,8],[1577,7],[1692,7],[1714,6],[1842,7]]},"3016":{"position":[[64,7]]},"3055":{"position":[[281,7]]},"3251":{"position":[[591,6]]}}}],["modular",{"_index":4289,"t":{"883":{"position":[[1518,7]]},"3395":{"position":[[1118,7]]}}}],["moment",{"_index":566,"t":{"77":{"position":[[82,7]]},"850":{"position":[[1250,7],[1293,7]]},"1055":{"position":[[3477,6]]},"1077":{"position":[[701,6],[1166,6]]},"1089":{"position":[[1609,6]]},"1246":{"position":[[87,7]]},"1484":{"position":[[1250,7],[1293,7]]},"1560":{"position":[[269,6]]},"1582":{"position":[[142,7]]},"3033":{"position":[[285,7]]}}}],["momentj",{"_index":1356,"t":{"187":{"position":[[595,8]]}}}],["mon",{"_index":4503,"t":{"917":{"position":[[764,3]]},"932":{"position":[[917,3]]},"1120":{"position":[[2053,3]]},"1286":{"position":[[940,3],[970,4]]},"1469":{"position":[[85,3],[178,5]]},"1471":{"position":[[1905,3],[2085,3]]},"1473":{"position":[[305,3]]},"1639":{"position":[[764,3]]},"1654":{"position":[[917,3]]},"2315":{"position":[[235,3],[337,5]]},"2364":{"position":[[764,3]]},"2379":{"position":[[917,3]]},"2468":{"position":[[877,3]]},"3400":{"position":[[1734,3]]}}}],["mon.testb",{"_index":6420,"t":{"1321":{"position":[[1086,11]]}}}],["mon@.servic",{"_index":6947,"t":{"1471":{"position":[[2120,18]]}}}],["mon_allow_pool_delet",{"_index":6920,"t":{"1460":{"position":[[246,21]]}}}],["mon_group_nam",{"_index":5382,"t":{"1120":{"position":[[1498,15]]}}}],["money",{"_index":1298,"t":{"178":{"position":[[2476,6]]},"694":{"position":[[178,5]]},"3014":{"position":[[694,5]]}}}],["monitor",{"_index":271,"t":{"25":{"position":[[284,10],[342,10],[630,7]]},"27":{"position":[[410,7],[784,10],[3299,7],[3331,7]]},"32":{"position":[[130,7],[184,7],[211,7],[286,7]]},"40":{"position":[[0,11]]},"67":{"position":[[90,10]]},"75":{"position":[[33,10],[123,10],[203,10]]},"313":{"position":[[411,7]]},"344":{"position":[[40,10]]},"347":{"position":[[355,10]]},"505":{"position":[[177,7],[355,7],[559,7]]},"509":{"position":[[234,9],[264,8],[310,7],[394,8]]},"511":{"position":[[25,7],[341,7],[515,10],[565,10]]},"772":{"position":[[340,8]]},"853":{"position":[[129,7]]},"865":{"position":[[428,10]]},"868":{"position":[[56,10]]},"878":{"position":[[428,10]]},"895":{"position":[[36,7],[1045,7],[1628,7],[1808,7],[1859,10],[1992,10],[2053,10],[2125,7]]},"899":{"position":[[646,7],[812,8]]},"901":{"position":[[667,7]]},"905":{"position":[[1895,7],[2367,7]]},"909":{"position":[[26,8],[161,7],[189,7],[394,7],[799,7]]},"911":{"position":[[176,10],[848,10]]},"913":{"position":[[2270,7],[3856,10],[3925,9]]},"917":{"position":[[670,7]]},"920":{"position":[[137,11]]},"930":{"position":[[21,7]]},"938":{"position":[[137,8]]},"940":{"position":[[53,7]]},"947":{"position":[[1604,11]]},"949":{"position":[[1122,7]]},"990":{"position":[[184,10]]},"1067":{"position":[[3214,10],[3280,10],[3323,12],[3930,7]]},"1244":{"position":[[290,10]]},"1250":{"position":[[39,10]]},"1252":{"position":[[569,10]]},"1360":{"position":[[718,10],[755,10]]},"1362":{"position":[[2629,10],[2666,10]]},"1460":{"position":[[222,8]]},"1597":{"position":[[129,7]]},"1617":{"position":[[36,7],[1045,7],[1628,7],[1808,7],[1859,10],[1992,10],[2053,10],[2125,7]]},"1621":{"position":[[646,7],[812,8]]},"1623":{"position":[[667,7]]},"1627":{"position":[[1895,7],[2367,7]]},"1631":{"position":[[26,8],[161,7],[189,7],[394,7],[799,7]]},"1633":{"position":[[176,10],[848,10]]},"1635":{"position":[[2270,7],[3856,10],[3925,9]]},"1639":{"position":[[670,7]]},"1642":{"position":[[137,11]]},"1652":{"position":[[21,7]]},"1660":{"position":[[137,8]]},"1662":{"position":[[53,7]]},"1669":{"position":[[1604,11]]},"1671":{"position":[[1122,7]]},"1779":{"position":[[4947,10],[5172,10],[5235,10],[5323,10]]},"1798":{"position":[[653,10]]},"2087":{"position":[[147,10]]},"2089":{"position":[[12,10],[104,10]]},"2091":{"position":[[22,10],[157,10]]},"2093":{"position":[[162,10],[268,10],[632,10],[791,10]]},"2096":{"position":[[1694,10],[1755,10],[1837,10],[1958,10],[2007,10],[2293,10],[2342,10]]},"2098":{"position":[[208,10],[2808,10],[2899,10],[3008,10],[3140,10],[3189,10],[3604,10],[3653,10]]},"2100":{"position":[[491,7],[686,10],[1336,10]]},"2106":{"position":[[243,10],[416,7],[750,10],[953,10],[1002,10]]},"2108":{"position":[[118,10],[287,11],[401,10]]},"2114":{"position":[[61,11],[166,10],[199,10]]},"2116":{"position":[[12,10],[268,11],[320,10],[452,10]]},"2118":{"position":[[16,10],[95,10],[171,10],[1240,10],[1277,11],[2329,10]]},"2120":{"position":[[268,10]]},"2122":{"position":[[56,10],[218,10],[476,11],[623,7]]},"2126":{"position":[[13,10]]},"2128":{"position":[[140,10],[189,10]]},"2130":{"position":[[114,10],[283,11],[397,10]]},"2132":{"position":[[91,10]]},"2138":{"position":[[169,10],[759,10],[985,10],[1034,10]]},"2146":{"position":[[204,10]]},"2154":{"position":[[42,10],[244,10],[412,10],[478,10],[624,10],[707,10],[792,10],[926,10],[1002,11],[1186,10],[1383,10],[1412,10]]},"2158":{"position":[[58,10]]},"2196":{"position":[[1136,7],[1161,7]]},"2212":{"position":[[649,10],[802,10]]},"2214":{"position":[[49,7],[182,10],[452,7],[549,7]]},"2248":{"position":[[608,7],[676,7]]},"2257":{"position":[[151,10]]},"2263":{"position":[[104,7]]},"2281":{"position":[[47,7],[228,7]]},"2315":{"position":[[917,7]]},"2342":{"position":[[36,7],[1045,7],[1628,7],[1808,7],[1859,10],[1992,10],[2053,10],[2125,7]]},"2346":{"position":[[646,7],[812,8]]},"2348":{"position":[[667,7]]},"2352":{"position":[[1895,7],[2367,7]]},"2356":{"position":[[26,8],[161,7],[189,7],[394,7],[799,7]]},"2358":{"position":[[176,10],[848,10]]},"2360":{"position":[[2270,7],[3856,10],[3925,9]]},"2364":{"position":[[670,7]]},"2367":{"position":[[137,11]]},"2377":{"position":[[21,7]]},"2385":{"position":[[137,8]]},"2387":{"position":[[53,7]]},"2394":{"position":[[1604,11]]},"2405":{"position":[[984,9]]},"2463":{"position":[[95,10],[158,10],[292,10],[355,10]]},"2468":{"position":[[386,8],[401,10],[456,8],[750,7]]},"2493":{"position":[[179,10]]},"2502":{"position":[[216,8],[334,8],[400,7]]},"2602":{"position":[[110,11]]},"2671":{"position":[[1126,10]]},"2957":{"position":[[309,10]]},"3160":{"position":[[1368,10]]},"3206":{"position":[[806,10]]},"3208":{"position":[[1336,10],[1394,10],[1582,10]]},"3210":{"position":[[776,10],[850,10]]},"3214":{"position":[[429,10]]},"3216":{"position":[[180,10]]},"3301":{"position":[[1383,13],[6300,10]]},"3314":{"position":[[2167,11],[3193,10]]},"3316":{"position":[[1134,7]]},"3378":{"position":[[268,10],[776,11]]},"3391":{"position":[[197,10]]},"3395":{"position":[[62,10]]},"3397":{"position":[[56,10],[1530,10],[1797,10]]},"3400":{"position":[[1673,10],[1781,10]]},"3413":{"position":[[322,10]]},"3438":{"position":[[574,10]]}}}],["monitor/blob/main/dashboard/readme.md",{"_index":4525,"t":{"924":{"position":[[60,37]]},"1646":{"position":[[60,37]]},"2371":{"position":[[60,37]]}}}],["monitor_address",{"_index":4982,"t":{"1067":{"position":[[5325,16]]}}}],["monitoring.scs.community/alertmanag",{"_index":8233,"t":{"2110":{"position":[[751,37]]}}}],["monitoring.scs.community/thano",{"_index":8229,"t":{"2110":{"position":[[555,31]]}}}],["monitoring1",{"_index":272,"t":{"25":{"position":[[307,11]]},"27":{"position":[[764,11]]}}}],["monolith",{"_index":8346,"t":{"2162":{"position":[[627,10]]},"2176":{"position":[[628,11]]}}}],["monorepo",{"_index":4879,"t":{"1057":{"position":[[82,9]]}}}],["month",{"_index":4593,"t":{"932":{"position":[[4057,6]]},"1654":{"position":[[4057,6]]},"1674":{"position":[[40,7]]},"2196":{"position":[[277,7]]},"2330":{"position":[[9,6],[938,6]]},"2379":{"position":[[4057,6]]},"2491":{"position":[[48,7]]},"2688":{"position":[[1199,6],[1389,7],[1549,6]]},"2705":{"position":[[598,5],[784,5],[1280,6],[1717,7]]},"2750":{"position":[[598,5],[799,5],[1528,5],[2019,7]]},"2813":{"position":[[350,6]]},"2840":{"position":[[493,5],[689,5],[1365,7]]},"2895":{"position":[[980,5],[4515,5]]},"2923":{"position":[[382,5]]},"3014":{"position":[[61,6],[491,6],[506,6]]},"3124":{"position":[[374,7],[443,6],[755,7]]},"3128":{"position":[[247,6]]},"3167":{"position":[[666,7],[687,6],[743,6]]},"3171":{"position":[[50,6]]},"3284":{"position":[[274,7]]},"3316":{"position":[[1592,6],[1637,6],[1660,6]]}}}],["monthli",{"_index":9086,"t":{"2688":{"position":[[544,8]]},"2895":{"position":[[926,7],[1433,8],[1613,7],[2212,8]]},"3124":{"position":[[860,8]]},"3167":{"position":[[349,8]]},"3284":{"position":[[291,7]]}}}],["months/year",{"_index":8552,"t":{"2436":{"position":[[92,12]]}}}],["more",{"_index":473,"t":{"60":{"position":[[146,4]]},"69":{"position":[[303,4]]},"168":{"position":[[1261,4]]},"180":{"position":[[205,4]]},"202":{"position":[[693,4]]},"204":{"position":[[326,4]]},"235":{"position":[[35,4]]},"238":{"position":[[43,4]]},"292":{"position":[[121,4]]},"321":{"position":[[1691,4]]},"325":{"position":[[1503,4]]},"327":{"position":[[570,4]]},"329":{"position":[[305,4]]},"331":{"position":[[120,4]]},"361":{"position":[[135,4]]},"370":{"position":[[544,4]]},"393":{"position":[[1789,4]]},"436":{"position":[[1298,4]]},"447":{"position":[[815,4]]},"471":{"position":[[504,4]]},"485":{"position":[[419,4]]},"499":{"position":[[1550,4]]},"505":{"position":[[881,4]]},"513":{"position":[[1002,4]]},"523":{"position":[[161,4]]},"525":{"position":[[219,4]]},"527":{"position":[[211,4]]},"600":{"position":[[236,4]]},"617":{"position":[[1387,4]]},"619":{"position":[[767,4]]},"627":{"position":[[951,4],[3348,4],[4495,4]]},"629":{"position":[[348,4]]},"654":{"position":[[365,4]]},"738":{"position":[[52,4]]},"742":{"position":[[510,4]]},"786":{"position":[[1076,4]]},"817":{"position":[[507,4],[562,4]]},"840":{"position":[[126,4]]},"883":{"position":[[2293,4]]},"895":{"position":[[716,4],[772,4],[1739,4],[1947,4],[1974,4],[2184,5]]},"899":{"position":[[151,5]]},"905":{"position":[[1644,4]]},"911":{"position":[[537,4],[596,4],[1057,5]]},"915":{"position":[[687,4]]},"917":{"position":[[289,4]]},"920":{"position":[[921,4]]},"922":{"position":[[141,4]]},"947":{"position":[[336,4],[490,4]]},"949":{"position":[[753,4],[786,4]]},"956":{"position":[[1971,4]]},"984":{"position":[[526,4]]},"995":{"position":[[172,4],[219,4],[344,4],[375,4],[415,4]]},"1055":{"position":[[224,4]]},"1059":{"position":[[437,4]]},"1061":{"position":[[850,4]]},"1071":{"position":[[1028,4],[1194,4]]},"1089":{"position":[[912,4]]},"1110":{"position":[[411,4]]},"1112":{"position":[[4,4]]},"1120":{"position":[[175,4]]},"1124":{"position":[[388,4]]},"1184":{"position":[[256,4],[436,4]]},"1217":{"position":[[759,5]]},"1226":{"position":[[1090,4]]},"1279":{"position":[[101,4]]},"1349":{"position":[[19,4]]},"1358":{"position":[[118,4]]},"1362":{"position":[[364,4]]},"1364":{"position":[[562,4]]},"1473":{"position":[[119,4]]},"1507":{"position":[[507,4],[562,4]]},"1523":{"position":[[1076,4]]},"1555":{"position":[[126,4]]},"1562":{"position":[[145,4],[334,4]]},"1587":{"position":[[954,4]]},"1594":{"position":[[374,4]]},"1617":{"position":[[716,4],[772,4],[1739,4],[1947,4],[1974,4],[2184,5]]},"1621":{"position":[[151,5]]},"1627":{"position":[[1644,4]]},"1633":{"position":[[537,4],[596,4],[1057,5]]},"1637":{"position":[[687,4]]},"1639":{"position":[[289,4]]},"1642":{"position":[[921,4]]},"1644":{"position":[[141,4]]},"1669":{"position":[[336,4],[490,4]]},"1671":{"position":[[753,4],[786,4]]},"1764":{"position":[[4127,4]]},"1770":{"position":[[643,4]]},"1779":{"position":[[4295,4]]},"1810":{"position":[[101,4]]},"1851":{"position":[[107,4]]},"1855":{"position":[[777,4],[1211,4],[1316,4]]},"1882":{"position":[[797,4]]},"1917":{"position":[[777,4],[1211,4],[1316,4]]},"1943":{"position":[[298,4]]},"1998":{"position":[[797,4]]},"2043":{"position":[[729,4]]},"2047":{"position":[[850,4]]},"2051":{"position":[[232,4]]},"2098":{"position":[[2624,4]]},"2118":{"position":[[1436,4]]},"2144":{"position":[[118,4],[182,4]]},"2196":{"position":[[107,4]]},"2212":{"position":[[644,4],[773,4]]},"2217":{"position":[[152,4]]},"2245":{"position":[[607,4]]},"2250":{"position":[[181,4]]},"2253":{"position":[[220,4]]},"2278":{"position":[[345,4]]},"2283":{"position":[[639,4]]},"2286":{"position":[[106,4]]},"2310":{"position":[[914,4]]},"2315":{"position":[[1129,4],[1146,4],[1273,4]]},"2324":{"position":[[286,4]]},"2330":{"position":[[977,4]]},"2342":{"position":[[716,4],[772,4],[1739,4],[1947,4],[1974,4],[2184,5]]},"2346":{"position":[[151,5]]},"2352":{"position":[[1644,4]]},"2358":{"position":[[537,4],[596,4],[1057,5]]},"2362":{"position":[[687,4]]},"2364":{"position":[[289,4]]},"2367":{"position":[[921,4]]},"2369":{"position":[[141,4]]},"2394":{"position":[[336,4],[490,4]]},"2396":{"position":[[753,4],[786,4]]},"2407":{"position":[[333,4]]},"2409":{"position":[[599,4]]},"2411":{"position":[[129,4]]},"2482":{"position":[[146,4]]},"2491":{"position":[[74,4],[141,4]]},"2497":{"position":[[532,4]]},"2504":{"position":[[235,4],[374,4]]},"2506":{"position":[[174,4]]},"2514":{"position":[[693,4],[780,4]]},"2518":{"position":[[234,4]]},"2623":{"position":[[774,4]]},"2625":{"position":[[861,4]]},"2637":{"position":[[355,4]]},"2639":{"position":[[114,4]]},"2677":{"position":[[182,4]]},"2688":{"position":[[3085,4]]},"2705":{"position":[[472,4],[1698,4]]},"2709":{"position":[[556,4]]},"2713":{"position":[[525,4],[840,4]]},"2719":{"position":[[273,5],[664,4],[1482,4],[1616,4]]},"2725":{"position":[[21,4]]},"2729":{"position":[[37,4]]},"2731":{"position":[[172,4],[949,4]]},"2737":{"position":[[291,4]]},"2750":{"position":[[472,4],[2000,4]]},"2754":{"position":[[556,4]]},"2756":{"position":[[1308,4]]},"2758":{"position":[[271,5],[662,4],[1483,4],[1617,4]]},"2764":{"position":[[44,4],[1380,4]]},"2766":{"position":[[50,4]]},"2768":{"position":[[60,4]]},"2770":{"position":[[172,4],[949,4]]},"2776":{"position":[[291,4]]},"2783":{"position":[[252,4]]},"2809":{"position":[[749,4]]},"2840":{"position":[[380,4],[1346,4]]},"2844":{"position":[[484,4]]},"2850":{"position":[[21,4]]},"2852":{"position":[[1181,4]]},"2858":{"position":[[522,4],[678,4]]},"2860":{"position":[[172,4],[910,4]]},"2872":{"position":[[199,4]]},"2874":{"position":[[115,4]]},"2890":{"position":[[183,4]]},"2895":{"position":[[1307,4]]},"2897":{"position":[[634,4]]},"2942":{"position":[[626,4]]},"2947":{"position":[[2109,4]]},"2949":{"position":[[364,4],[480,4]]},"2951":{"position":[[395,4],[783,4]]},"2960":{"position":[[284,4],[1125,4],[1518,4]]},"2990":{"position":[[288,4]]},"2999":{"position":[[180,4]]},"3037":{"position":[[40,4]]},"3059":{"position":[[574,4]]},"3082":{"position":[[815,4],[1037,4],[1443,4]]},"3084":{"position":[[312,4]]},"3090":{"position":[[98,4]]},"3101":{"position":[[59,4]]},"3103":{"position":[[1594,4]]},"3124":{"position":[[645,4]]},"3182":{"position":[[1910,4]]},"3184":{"position":[[1709,4],[2560,4]]},"3199":{"position":[[676,4]]},"3208":{"position":[[729,4]]},"3218":{"position":[[1393,4],[1705,4],[1841,4]]},"3220":{"position":[[17,4],[275,4],[462,4]]},"3222":{"position":[[401,4]]},"3224":{"position":[[1052,4],[1126,4],[1881,4]]},"3234":{"position":[[155,4]]},"3251":{"position":[[5839,4]]},"3270":{"position":[[988,4],[1530,4],[2327,4]]},"3272":{"position":[[1087,4]]},"3280":{"position":[[698,4]]},"3301":{"position":[[4232,4],[4241,4],[4784,4]]},"3389":{"position":[[678,4]]},"3391":{"position":[[370,4],[379,4]]},"3423":{"position":[[408,4]]},"3446":{"position":[[81,4]]},"3461":{"position":[[274,4]]},"3482":{"position":[[1186,4]]},"3495":{"position":[[23,4]]}}}],["moreov",{"_index":9741,"t":{"3071":{"position":[[1563,9]]}}}],["mostli",{"_index":6907,"t":{"1444":{"position":[[714,6]]},"2209":{"position":[[96,9]]},"3126":{"position":[[439,6]]},"3182":{"position":[[2129,6]]},"3380":{"position":[[42,6]]}}}],["motiv",{"_index":2445,"t":{"417":{"position":[[340,10]]},"2627":{"position":[[160,10],[1402,10]]},"3059":{"position":[[432,10]]},"3154":{"position":[[17,9]]},"3491":{"position":[[44,10]]},"3504":{"position":[[0,10]]}}}],["motto",{"_index":1400,"t":{"193":{"position":[[756,6]]}}}],["mount",{"_index":2321,"t":{"393":{"position":[[136,5]]},"447":{"position":[[399,6]]},"449":{"position":[[508,6]]},"451":{"position":[[224,7]]},"456":{"position":[[211,6]]},"458":{"position":[[310,7]]},"615":{"position":[[1125,5]]},"650":{"position":[[894,7],[2493,5]]},"1167":{"position":[[3336,7],[3456,9]]},"1184":{"position":[[399,7],[580,5]]},"1379":{"position":[[276,6],[774,6]]},"1571":{"position":[[115,7],[438,7]]},"1731":{"position":[[374,5],[766,5]]},"1833":{"position":[[108,8],[133,7],[503,7],[571,8],[1109,6]]},"1841":{"position":[[241,8],[494,5],[533,5],[620,5],[664,5]]},"1913":{"position":[[1900,7]]},"2029":{"position":[[1900,7]]},"2116":{"position":[[642,7]]}}}],["mountpoint",{"_index":6068,"t":{"1234":{"position":[[1946,11]]},"1841":{"position":[[325,11]]},"1843":{"position":[[354,12]]},"1847":{"position":[[673,12]]}}}],["mous",{"_index":4592,"t":{"932":{"position":[[4029,6]]},"1654":{"position":[[4029,6]]},"2379":{"position":[[4029,6]]}}}],["move",{"_index":1185,"t":{"172":{"position":[[772,5]]},"393":{"position":[[1107,4]]},"400":{"position":[[23,6]]},"417":{"position":[[235,6]]},"598":{"position":[[1036,5],[1051,5],[1066,4],[1083,5],[1209,6],[1499,4],[1580,5]]},"602":{"position":[[166,4]]},"604":{"position":[[4887,5]]},"606":{"position":[[367,4]]},"720":{"position":[[46,4]]},"1112":{"position":[[5425,4]]},"1228":{"position":[[17,6]]},"1230":{"position":[[17,6]]},"1466":{"position":[[74,4]]},"1833":{"position":[[63,5]]},"1851":{"position":[[285,4]]},"1953":{"position":[[84,5]]},"2255":{"position":[[236,5]]},"2328":{"position":[[74,4]]},"2409":{"position":[[785,6]]},"2424":{"position":[[102,4]]},"2461":{"position":[[740,5]]},"2463":{"position":[[709,5],[792,5]]},"2637":{"position":[[170,6]]},"2660":{"position":[[0,4],[315,4]]},"2774":{"position":[[104,5]]},"2939":{"position":[[366,5]]},"3224":{"position":[[882,6]]},"3255":{"position":[[76,4]]}}}],["movement",{"_index":7764,"t":{"1835":{"position":[[40,8]]}}}],["mpl",{"_index":1087,"t":{"168":{"position":[[1375,3]]}}}],["mqtt",{"_index":2029,"t":{"323":{"position":[[60,4],[146,4],[642,5]]}}}],["ms",{"_index":6045,"t":{"1226":{"position":[[1240,2]]},"1368":{"position":[[1777,2],[2055,2],[2118,2],[2456,2],[2734,2],[2797,2]]},"2944":{"position":[[1894,2]]}}}],["msg",{"_index":2119,"t":{"325":{"position":[[7839,4]]},"1224":{"position":[[3199,6],[3378,6]]},"1368":{"position":[[2047,3],[2105,3],[2726,3],[2784,3]]},"1721":{"position":[[3899,6]]},"1734":{"position":[[157,4]]}}}],["msg=\"purg",{"_index":2653,"t":{"472":{"position":[[2547,10]]}}}],["msg=\"purgeupload",{"_index":2645,"t":{"472":{"position":[[2378,17]]}}}],["msg=\"start",{"_index":2638,"t":{"472":{"position":[[2220,13]]}}}],["mssql",{"_index":6044,"t":{"1226":{"position":[[1221,5]]}}}],["mta",{"_index":4508,"t":{"920":{"position":[[482,4]]},"1642":{"position":[[482,4]]},"2367":{"position":[[482,4]]}}}],["mtr",{"_index":4753,"t":{"1014":{"position":[[414,3]]}}}],["mtu",{"_index":2716,"t":{"485":{"position":[[789,3]]},"1067":{"position":[[2652,4],[4913,4]]},"1094":{"position":[[175,3]]},"1098":{"position":[[503,4],[527,4]]},"1188":{"position":[[17,3],[73,3],[191,3],[288,4],[341,3]]},"1585":{"position":[[1703,3],[2019,4]]}}}],["mtu_valu",{"_index":2715,"t":{"485":{"position":[[773,9]]}}}],["muc",{"_index":2710,"t":{"485":{"position":[[612,3]]}}}],["much",{"_index":1071,"t":{"168":{"position":[[951,4]]},"327":{"position":[[758,4]]},"387":{"position":[[150,4]]},"503":{"position":[[623,4]]},"899":{"position":[[518,4]]},"947":{"position":[[1380,4]]},"980":{"position":[[149,4],[321,4]]},"984":{"position":[[491,4]]},"995":{"position":[[516,4]]},"1178":{"position":[[70,4]]},"1562":{"position":[[206,4]]},"1621":{"position":[[518,4]]},"1669":{"position":[[1380,4]]},"1779":{"position":[[3969,4]]},"1827":{"position":[[143,4]]},"1955":{"position":[[422,4]]},"1976":{"position":[[359,4]]},"2188":{"position":[[74,4]]},"2229":{"position":[[618,4]]},"2283":{"position":[[634,4]]},"2306":{"position":[[289,4]]},"2312":{"position":[[640,4]]},"2338":{"position":[[254,4]]},"2346":{"position":[[518,4]]},"2394":{"position":[[1380,4]]},"2434":{"position":[[412,4]]},"2482":{"position":[[141,4]]},"2491":{"position":[[136,4]]},"2731":{"position":[[1365,5]]},"2770":{"position":[[1388,5]]},"2860":{"position":[[1361,5]]},"2872":{"position":[[1357,4]]},"2947":{"position":[[1625,4]]},"2966":{"position":[[1973,4],[4298,4]]},"3011":{"position":[[1911,4]]},"3014":{"position":[[1050,4]]},"3103":{"position":[[1083,4]]},"3234":{"position":[[150,4]]},"3282":{"position":[[90,4]]},"3310":{"position":[[24,4]]},"3380":{"position":[[187,4]]},"3400":{"position":[[1323,4]]}}}],["multi",{"_index":2790,"t":{"487":{"position":[[3058,5]]},"615":{"position":[[943,5],[1383,5],[1582,5],[1671,5]]},"790":{"position":[[865,6]]},"796":{"position":[[175,6],[678,6]]},"798":{"position":[[235,6],[673,6]]},"850":{"position":[[9194,6]]},"888":{"position":[[1122,5],[1314,5]]},"1484":{"position":[[9194,6]]},"1527":{"position":[[865,6]]},"1533":{"position":[[175,6],[678,6]]},"1535":{"position":[[235,6],[673,6]]},"1978":{"position":[[584,5],[756,5]]},"1980":{"position":[[224,5],[455,5]]},"2031":{"position":[[293,5]]},"2245":{"position":[[478,5]]},"2709":{"position":[[1174,5]]},"2754":{"position":[[1315,5]]},"2844":{"position":[[1102,5]]},"2944":{"position":[[798,5]]},"2947":{"position":[[508,5],[959,5],[4317,5]]},"3160":{"position":[[1081,5],[1243,5]]},"3188":{"position":[[154,5],[167,5]]},"3301":{"position":[[5268,5],[6174,5],[7380,5]]}}}],["multiattach",{"_index":9649,"t":{"2966":{"position":[[2183,12],[2496,12],[2538,12]]},"2970":{"position":[[187,11]]}}}],["multipl",{"_index":165,"t":{"10":{"position":[[1679,8]]},"339":{"position":[[37,8]]},"396":{"position":[[379,9]]},"444":{"position":[[264,8]]},"472":{"position":[[253,8]]},"495":{"position":[[984,8],[1859,8]]},"596":{"position":[[759,8]]},"631":{"position":[[1049,8]]},"740":{"position":[[46,8]]},"762":{"position":[[299,8]]},"774":{"position":[[417,8]]},"819":{"position":[[1933,8]]},"821":{"position":[[1385,8]]},"859":{"position":[[1451,8]]},"888":{"position":[[1786,8],[2391,8]]},"909":{"position":[[265,8]]},"917":{"position":[[12,8],[332,8]]},"947":{"position":[[1682,8]]},"956":{"position":[[1003,8]]},"977":{"position":[[554,9],[1353,8]]},"1071":{"position":[[982,8],[1148,8]]},"1509":{"position":[[1933,8]]},"1511":{"position":[[1385,8]]},"1574":{"position":[[286,8]]},"1603":{"position":[[1451,8]]},"1631":{"position":[[265,8]]},"1639":{"position":[[12,8],[332,8]]},"1669":{"position":[[1682,8]]},"1785":{"position":[[496,8]]},"1791":{"position":[[832,8]]},"1853":{"position":[[494,8]]},"1865":{"position":[[40,8],[314,8]]},"1915":{"position":[[494,8]]},"1927":{"position":[[40,8],[314,8]]},"2075":{"position":[[269,8]]},"2142":{"position":[[111,8]]},"2148":{"position":[[371,8]]},"2160":{"position":[[13,8]]},"2176":{"position":[[651,8]]},"2315":{"position":[[853,8]]},"2356":{"position":[[265,8]]},"2364":{"position":[[12,8],[332,8]]},"2394":{"position":[[1682,8]]},"2562":{"position":[[97,8]]},"2625":{"position":[[2076,8]]},"2709":{"position":[[1315,8]]},"2754":{"position":[[1456,8]]},"2817":{"position":[[155,8]]},"2822":{"position":[[227,8]]},"2872":{"position":[[900,8]]},"2944":{"position":[[1007,8]]},"2966":{"position":[[1279,8],[1569,8],[2251,8],[2687,8],[4098,8]]},"2983":{"position":[[250,8]]},"2985":{"position":[[368,8]]},"3014":{"position":[[318,8]]},"3031":{"position":[[431,8]]},"3044":{"position":[[44,8]]},"3124":{"position":[[33,8]]},"3160":{"position":[[708,8],[1131,8]]},"3178":{"position":[[363,8],[435,8]]},"3182":{"position":[[67,8],[116,8],[333,8],[2353,8]]},"3184":{"position":[[1277,8],[1737,8],[2234,8]]},"3186":{"position":[[745,8],[939,8],[993,8],[1026,8]]},"3191":{"position":[[357,8],[429,8]]},"3195":{"position":[[395,8]]},"3199":{"position":[[491,8],[814,8]]},"3206":{"position":[[460,8]]},"3210":{"position":[[706,8]]},"3238":{"position":[[152,8]]},"3247":{"position":[[8,8]]},"3251":{"position":[[1891,8],[4176,8],[5049,8]]},"3270":{"position":[[243,8]]},"3274":{"position":[[212,8],[631,9]]},"3278":{"position":[[28,8]]},"3299":{"position":[[2753,8]]},"3301":{"position":[[5171,8],[6694,8]]},"3355":{"position":[[99,8],[145,8]]},"3397":{"position":[[2108,8]]},"3472":{"position":[[13240,8],[13595,8]]}}}],["multipli",{"_index":2517,"t":{"436":{"position":[[1167,11],[1274,10]]},"813":{"position":[[526,10],[547,10],[580,10],[613,10]]},"819":{"position":[[1076,10],[1114,10],[1168,10],[1222,10],[3301,10],[3335,10],[3354,10],[3404,10],[3431,10],[3481,10],[3508,10],[3558,10],[5896,10],[5956,10],[6113,10],[6326,10]]},"1503":{"position":[[526,10],[547,10],[580,10],[613,10]]},"1509":{"position":[[1076,10],[1114,10],[1168,10],[1222,10],[3301,10],[3335,10],[3354,10],[3404,10],[3431,10],[3481,10],[3508,10],[3558,10],[5896,10],[5956,10],[6113,10],[6326,10]]}}}],["multiprocessor",{"_index":9359,"t":{"2766":{"position":[[448,15]]}}}],["multitail",{"_index":4765,"t":{"1017":{"position":[[190,9]]}}}],["multitud",{"_index":2160,"t":{"339":{"position":[[128,9]]}}}],["mutabl",{"_index":7900,"t":{"1853":{"position":[[666,7]]},"1915":{"position":[[666,7]]}}}],["mutat",{"_index":10028,"t":{"3270":{"position":[[941,8]]},"3280":{"position":[[310,8]]}}}],["mute",{"_index":6830,"t":{"1402":{"position":[[14,4]]}}}],["mv",{"_index":2605,"t":{"469":{"position":[[586,2]]}}}],["mvp",{"_index":539,"t":{"71":{"position":[[513,4]]},"2114":{"position":[[94,3]]},"2154":{"position":[[1254,3],[1298,3]]},"3308":{"position":[[539,3]]},"3397":{"position":[[9,3],[654,3]]}}}],["mwf8uclkgrunvsylsmgupb163l89",{"_index":7633,"t":{"1791":{"position":[[3521,28]]}}}],["mx",{"_index":9168,"t":{"2709":{"position":[[1233,2]]},"2754":{"position":[[1374,2]]},"2844":{"position":[[1161,2]]}}}],["mx]n",{"_index":9399,"t":{"2837":{"position":[[118,8]]}}}],["mx]n[n/h/s/p",{"_index":9345,"t":{"2747":{"position":[[98,15]]}}}],["mx]n[n/s/l/p",{"_index":9117,"t":{"2702":{"position":[[98,15]]}}}],["mxmxchere",{"_index":327,"t":{"27":{"position":[[1216,9]]}}}],["my_corp_net",{"_index":7814,"t":{"1845":{"position":[[1646,12],[1947,11]]}}}],["my_job",{"_index":2002,"t":{"319":{"position":[[264,7]]}}}],["my_job1",{"_index":1999,"t":{"319":{"position":[[217,7]]}}}],["my_job2",{"_index":2000,"t":{"319":{"position":[[227,7]]}}}],["my_network=10.50.40.230",{"_index":7852,"t":{"1847":{"position":[[426,23]]}}}],["my_other_corp_net",{"_index":7835,"t":{"1845":{"position":[[2132,17]]}}}],["my_pipeline1",{"_index":1998,"t":{"319":{"position":[[195,13]]}}}],["my_pipeline2",{"_index":2001,"t":{"319":{"position":[[242,13]]}}}],["mycirro",{"_index":3736,"t":{"790":{"position":[[750,8]]},"1527":{"position":[[750,8]]}}}],["mycloud",{"_index":174,"t":{"10":{"position":[[1821,7]]},"932":{"position":[[2443,7],[2651,7]]},"1654":{"position":[[2443,7],[2651,7]]},"1743":{"position":[[584,7]]},"2379":{"position":[[2443,7],[2651,7]]}}}],["myclust",{"_index":3476,"t":{"648":{"position":[[319,9],[377,10]]}}}],["mycluster/clusterctl.yaml",{"_index":3475,"t":{"648":{"position":[[192,27]]}}}],["mycluster/mycluster.yaml",{"_index":3477,"t":{"648":{"position":[[425,27]]}}}],["mydomain.xyz",{"_index":7363,"t":{"1743":{"position":[[702,13]]}}}],["myfile.pi",{"_index":7205,"t":{"1709":{"position":[[6,9]]},"1715":{"position":[[144,9]]}}}],["myfirsttestjob",{"_index":2111,"t":{"325":{"position":[[6734,14],[7031,14],[7099,14]]}}}],["myflavor",{"_index":7358,"t":{"1743":{"position":[[600,8]]}}}],["mykeypair",{"_index":7359,"t":{"1743":{"position":[[638,9]]}}}],["myprivatenet",{"_index":7360,"t":{"1743":{"position":[[657,12]]}}}],["myproject",{"_index":7361,"t":{"1743":{"position":[[679,9]]}}}],["myriad",{"_index":9954,"t":{"3227":{"position":[[237,6]]}}}],["mysecondtestjob",{"_index":2114,"t":{"325":{"position":[[6942,15],[7061,15],[7158,15]]}}}],["mysql",{"_index":7351,"t":{"1734":{"position":[[249,5]]},"2176":{"position":[[914,7]]}}}],["mysql_db",{"_index":7347,"t":{"1734":{"position":[[148,8]]}}}],["mysqlbackup",{"_index":6201,"t":{"1298":{"position":[[548,11],[696,11]]}}}],["mytest.conf",{"_index":4259,"t":{"861":{"position":[[192,11]]},"1605":{"position":[[192,11]]}}}],["n",{"_index":2356,"t":{"404":{"position":[[74,1]]},"409":{"position":[[54,1]]},"413":{"position":[[186,1]]},"427":{"position":[[1145,1]]},"428":{"position":[[413,1]]},"436":{"position":[[883,1]]},"442":{"position":[[105,1]]},"474":{"position":[[270,1],[428,1],[593,1],[1098,1]]},"497":{"position":[[773,1]]},"590":{"position":[[1999,1],[2187,1]]},"604":{"position":[[6404,1],[6699,1],[6807,1]]},"609":{"position":[[6383,1]]},"641":{"position":[[598,1]]},"646":{"position":[[1849,1]]},"660":{"position":[[484,1],[628,1],[1224,1],[1542,1],[3086,1],[3347,1],[3428,1]]},"909":{"position":[[905,1],[2465,2],[2626,1],[2710,1],[2725,1],[2730,1],[2771,1]]},"911":{"position":[[62,1],[445,1],[450,1]]},"913":{"position":[[978,1],[2311,1],[2316,1],[2395,1],[2400,1],[2500,1],[3222,1]]},"920":{"position":[[373,1]]},"1112":{"position":[[5295,1],[5360,1]]},"1114":{"position":[[2434,1],[2499,1],[2567,1],[5938,1],[6002,1],[6066,1],[6130,1]]},"1631":{"position":[[905,1],[2465,2],[2626,1],[2710,1],[2725,1],[2730,1],[2771,1]]},"1633":{"position":[[62,1],[445,1],[450,1]]},"1635":{"position":[[978,1],[2311,1],[2316,1],[2395,1],[2400,1],[2500,1],[3222,1]]},"1642":{"position":[[373,1]]},"2033":{"position":[[1374,1]]},"2288":{"position":[[189,1]]},"2356":{"position":[[905,1],[2465,2],[2626,1],[2710,1],[2725,1],[2730,1],[2771,1]]},"2358":{"position":[[62,1],[445,1],[450,1]]},"2360":{"position":[[978,1],[2311,1],[2316,1],[2395,1],[2400,1],[2500,1],[3222,1]]},"2367":{"position":[[373,1]]},"2625":{"position":[[1045,1]]},"2702":{"position":[[131,1]]},"2709":{"position":[[90,1],[403,1],[511,1],[665,1],[1640,1]]},"2711":{"position":[[811,1]]},"2727":{"position":[[64,1],[160,1],[303,1],[353,1]]},"2747":{"position":[[131,1]]},"2754":{"position":[[90,1],[403,1],[511,1],[665,1],[1781,1]]},"2764":{"position":[[116,3]]},"2766":{"position":[[143,3],[429,1],[553,1]]},"2837":{"position":[[96,1],[197,1]]},"2844":{"position":[[18,1],[331,1],[439,1],[593,1]]},"2852":{"position":[[443,1],[539,1],[680,1]]},"2856":{"position":[[789,1]]},"2895":{"position":[[3471,1],[3685,1],[3696,1],[4103,1]]},"2923":{"position":[[106,1],[602,1],[666,1],[901,4]]}}}],["n/a",{"_index":7853,"t":{"1847":{"position":[[452,3]]}}}],["n/s/l/p",{"_index":9400,"t":{"2837":{"position":[[127,9]]}}}],["n[u][o",{"_index":9116,"t":{"2702":{"position":[[88,7]]},"2747":{"position":[[88,7]]},"2837":{"position":[[109,8]]}}}],["n_bms_3",{"_index":9174,"t":{"2709":{"position":[[1709,7]]},"2754":{"position":[[1850,7]]}}}],["naabu",{"_index":8136,"t":{"2075":{"position":[[15,5]]}}}],["name",{"_index":156,"t":{"10":{"position":[[1493,5]]},"25":{"position":[[172,4]]},"27":{"position":[[26,4]]},"30":{"position":[[31,4]]},"32":{"position":[[26,4]]},"105":{"position":[[1759,4]]},"112":{"position":[[98,5]]},"135":{"position":[[23,6],[84,4],[122,5],[183,5]]},"139":{"position":[[221,4],[395,5]]},"141":{"position":[[216,4],[340,5]]},"143":{"position":[[113,5],[257,5],[511,5],[646,5],[789,5],[925,5],[986,5]]},"208":{"position":[[46,4],[64,4]]},"247":{"position":[[1762,5]]},"270":{"position":[[259,4]]},"280":{"position":[[204,5]]},"282":{"position":[[344,6],[362,4],[547,4]]},"286":{"position":[[251,4]]},"302":{"position":[[1500,5]]},"319":{"position":[[126,5],[364,4]]},"323":{"position":[[477,5]]},"325":{"position":[[335,5],[777,5],[833,4],[939,4],[2565,5],[2651,5],[2816,4],[3435,5],[4368,5],[4374,6],[5210,6],[5254,4],[5324,6],[5422,5],[5572,4],[5733,4],[5775,4],[6117,5],[6202,4],[6261,4],[6521,5],[6728,5],[6773,5],[6796,4],[6936,5]]},"389":{"position":[[292,5]]},"393":{"position":[[450,4]]},"404":{"position":[[948,5]]},"409":{"position":[[64,4]]},"413":{"position":[[202,4]]},"421":{"position":[[1462,4]]},"428":{"position":[[388,4],[1371,5]]},"442":{"position":[[121,4]]},"471":{"position":[[165,5],[1302,5]]},"474":{"position":[[245,4],[403,4],[520,4],[568,4],[710,4],[770,4],[860,4],[1073,4]]},"483":{"position":[[442,4]]},"485":{"position":[[177,4]]},"487":{"position":[[823,4],[1253,4],[3217,5]]},"499":{"position":[[2410,6],[2450,6],[2658,6],[2727,6]]},"519":{"position":[[442,4]]},"521":{"position":[[29,4],[51,4],[141,4]]},"527":{"position":[[114,4]]},"568":{"position":[[163,4]]},"590":{"position":[[1326,4]]},"600":{"position":[[935,4]]},"604":{"position":[[2533,4],[5305,5],[5442,4],[5503,4],[10509,5],[10699,5],[10815,5],[10893,6]]},"606":{"position":[[66,4]]},"615":{"position":[[658,5]]},"619":{"position":[[269,4],[313,4],[379,4],[468,4]]},"621":{"position":[[143,4]]},"623":{"position":[[161,4]]},"627":{"position":[[4071,4]]},"629":{"position":[[454,5]]},"631":{"position":[[121,4],[493,4]]},"641":{"position":[[608,4],[858,4],[1151,4],[1624,4]]},"644":{"position":[[201,4]]},"646":{"position":[[458,4],[673,4],[1416,4],[2107,4]]},"648":{"position":[[372,4],[572,4]]},"650":{"position":[[1673,5]]},"660":{"position":[[735,5],[771,5],[958,5],[1107,5],[1174,5],[1259,4],[1632,5],[1806,5],[1866,5],[1941,5],[2003,5],[2070,5],[2126,5],[2186,5],[2224,5],[2343,5],[2388,5],[2444,5],[2517,5],[2582,5],[2813,5],[3121,4],[3463,4]]},"662":{"position":[[638,4]]},"726":{"position":[[200,6]]},"730":{"position":[[348,4],[627,4],[637,4],[737,4],[1015,6],[1120,6],[2163,4]]},"732":{"position":[[340,4],[388,6],[458,4]]},"734":{"position":[[34,5],[120,4],[166,5]]},"772":{"position":[[615,4]]},"790":{"position":[[424,4],[744,5],[1392,4]]},"794":{"position":[[166,4]]},"796":{"position":[[335,4],[572,5]]},"798":{"position":[[392,4],[551,6],[568,5]]},"800":{"position":[[65,4]]},"813":{"position":[[213,4],[380,4]]},"815":{"position":[[324,4]]},"817":{"position":[[289,4]]},"819":{"position":[[546,4],[689,4],[694,5],[798,4],[2215,4],[2238,4],[2268,4],[2520,4],[2525,4],[2761,4],[2797,4],[3643,5],[4084,4],[4176,4],[4660,4],[4767,4],[5263,4],[5370,4],[7124,4],[7207,4],[7588,5],[8175,4],[8259,4]]},"821":{"position":[[649,4],[654,5],[945,4],[1743,4],[1748,4]]},"850":{"position":[[9057,5]]},"859":{"position":[[288,4],[963,4]]},"897":{"position":[[153,5],[169,5]]},"903":{"position":[[583,5],[1738,4],[1970,4],[2923,4],[3307,4]]},"905":{"position":[[1206,5],[2035,5],[2089,5]]},"909":{"position":[[1846,4],[2121,6]]},"913":{"position":[[3961,4]]},"922":{"position":[[42,4],[876,4]]},"932":{"position":[[2013,5],[2164,4]]},"934":{"position":[[1860,4]]},"947":{"position":[[586,4],[1118,4]]},"949":{"position":[[87,5]]},"1012":{"position":[[221,5]]},"1031":{"position":[[907,5]]},"1033":{"position":[[334,4]]},"1043":{"position":[[155,5],[284,4],[358,5],[448,4]]},"1055":{"position":[[332,5],[402,4],[1338,4],[1364,4]]},"1067":{"position":[[1186,4],[1233,4],[1310,4],[2805,4],[2852,4]]},"1071":{"position":[[617,4],[1387,4]]},"1091":{"position":[[243,5]]},"1106":{"position":[[237,5],[278,5],[321,5],[358,5]]},"1110":{"position":[[138,5]]},"1112":{"position":[[1075,5],[3822,5]]},"1116":{"position":[[155,4]]},"1120":{"position":[[283,5],[331,4],[875,4],[901,4],[1152,4]]},"1146":{"position":[[372,8],[519,8]]},"1150":{"position":[[6661,4],[6920,4],[7198,4],[12983,4]]},"1167":{"position":[[276,5]]},"1184":{"position":[[718,4],[755,4],[830,4],[908,4],[989,4],[1051,4]]},"1213":{"position":[[483,5]]},"1234":{"position":[[974,4],[1639,4]]},"1240":{"position":[[815,4],[989,4],[1175,4]]},"1256":{"position":[[232,4]]},"1273":{"position":[[336,5],[408,5]]},"1317":{"position":[[971,4],[1674,4],[2208,4],[5759,4],[7854,4],[8913,4]]},"1319":{"position":[[503,5]]},"1342":{"position":[[261,4]]},"1344":{"position":[[111,5]]},"1351":{"position":[[498,4],[812,4],[1522,4],[2336,4]]},"1353":{"position":[[119,5]]},"1360":{"position":[[1169,5]]},"1364":{"position":[[147,5],[224,5],[301,5],[828,5],[875,5],[922,5]]},"1368":{"position":[[1572,5],[2248,5]]},"1383":{"position":[[303,5],[392,5],[449,5],[537,5]]},"1406":{"position":[[558,4],[629,5],[707,5]]},"1413":{"position":[[55,5]]},"1430":{"position":[[62,4],[855,4],[1498,4],[1888,4]]},"1458":{"position":[[220,5]]},"1471":{"position":[[120,5],[614,4],[693,4],[963,5],[1073,4],[1152,4],[1333,4],[1412,4],[1593,5],[1674,5],[1962,4],[2041,4]]},"1473":{"position":[[66,6],[145,6],[1631,5]]},"1484":{"position":[[9057,5]]},"1487":{"position":[[200,6]]},"1491":{"position":[[348,4],[627,4],[637,4],[737,4],[1015,6],[1120,6],[2163,4]]},"1493":{"position":[[340,4],[388,6],[458,4]]},"1495":{"position":[[34,5],[120,4],[166,5]]},"1503":{"position":[[213,4],[380,4]]},"1505":{"position":[[324,4]]},"1507":{"position":[[289,4]]},"1509":{"position":[[546,4],[689,4],[694,5],[798,4],[2215,4],[2238,4],[2268,4],[2520,4],[2525,4],[2761,4],[2797,4],[3643,5],[4084,4],[4176,4],[4660,4],[4767,4],[5263,4],[5370,4],[7124,4],[7207,4],[7588,5],[8175,4],[8259,4]]},"1511":{"position":[[649,4],[654,5],[945,4],[1743,4],[1748,4]]},"1527":{"position":[[424,4],[744,5],[1392,4]]},"1531":{"position":[[166,4]]},"1533":{"position":[[335,4],[572,5]]},"1535":{"position":[[392,4],[551,6],[568,5]]},"1537":{"position":[[65,4]]},"1576":{"position":[[82,4],[923,4]]},"1585":{"position":[[672,4],[2833,5],[2916,5],[3008,5],[3106,5],[3196,5],[3584,4]]},"1591":{"position":[[942,4]]},"1603":{"position":[[288,4],[963,4]]},"1619":{"position":[[153,5],[169,5]]},"1625":{"position":[[583,5],[1738,4],[1970,4],[2923,4],[3307,4]]},"1627":{"position":[[1206,5],[2035,5],[2089,5]]},"1631":{"position":[[1846,4],[2121,6]]},"1635":{"position":[[3961,4]]},"1644":{"position":[[42,4],[876,4]]},"1654":{"position":[[2013,5],[2164,4]]},"1656":{"position":[[1860,4]]},"1669":{"position":[[586,4],[1118,4]]},"1671":{"position":[[87,5]]},"1676":{"position":[[439,5]]},"1678":{"position":[[120,5],[508,4],[1723,5],[1863,5]]},"1684":{"position":[[106,4],[225,5]]},"1690":{"position":[[361,5]]},"1695":{"position":[[23,6],[84,4],[122,5],[183,5]]},"1697":{"position":[[222,4],[396,5]]},"1699":{"position":[[155,5]]},"1731":{"position":[[1066,4]]},"1743":{"position":[[530,5],[790,5],[871,5],[961,5],[1141,5],[1400,5],[1540,5],[1697,5],[1738,5],[1821,5],[1913,5],[1994,5],[2060,5],[2099,5],[2152,5],[2245,5],[2298,5],[2372,5],[2411,5],[2450,5],[2487,5]]},"1745":{"position":[[1117,5]]},"1747":{"position":[[330,5],[471,5]]},"1749":{"position":[[35,5],[113,5],[252,5],[406,5],[481,5],[571,5],[789,5],[868,5],[884,4]]},"1752":{"position":[[20,6]]},"1773":{"position":[[406,4],[886,4]]},"1779":{"position":[[1199,4],[1239,4],[1321,4],[1366,4],[1406,5],[1463,4],[1615,4],[1802,4],[1964,4]]},"1789":{"position":[[274,4]]},"1794":{"position":[[1048,5]]},"1808":{"position":[[844,4],[1105,4]]},"1818":{"position":[[52,4]]},"1833":{"position":[[1199,5]]},"1843":{"position":[[341,5],[885,4]]},"1845":{"position":[[865,4],[1789,4],[2330,4]]},"1847":{"position":[[173,4]]},"1880":{"position":[[666,4]]},"1900":{"position":[[330,4],[882,5],[1044,4]]},"1908":{"position":[[806,4],[879,4],[2433,4],[2850,4]]},"1943":{"position":[[58,5]]},"1957":{"position":[[216,4],[482,4],[1110,5],[2764,4]]},"1996":{"position":[[666,4]]},"2016":{"position":[[330,4],[882,5],[1044,4]]},"2024":{"position":[[806,4],[879,4],[2433,4],[2850,4]]},"2033":{"position":[[220,5],[233,4],[314,5],[327,4],[391,5],[404,4],[495,5],[508,4],[739,5],[857,5],[990,5],[1021,4],[1099,5],[1132,4],[1200,5],[1246,5],[1277,4],[1383,5],[1454,5],[1484,4],[1495,5],[1611,5],[1646,4],[1657,5]]},"2039":{"position":[[223,5],[401,4],[548,5],[619,6]]},"2051":{"position":[[61,5],[146,5],[222,5]]},"2118":{"position":[[242,4],[484,4],[1200,9],[2019,4],[2490,4]]},"2126":{"position":[[472,4]]},"2233":{"position":[[96,6],[143,6]]},"2253":{"position":[[4,5]]},"2255":{"position":[[100,4]]},"2263":{"position":[[46,4]]},"2265":{"position":[[672,6]]},"2298":{"position":[[672,6],[880,6]]},"2344":{"position":[[153,5],[169,5]]},"2350":{"position":[[583,5],[1738,4],[1970,4],[2923,4],[3307,4]]},"2352":{"position":[[1206,5],[2035,5],[2089,5]]},"2356":{"position":[[1846,4],[2121,6]]},"2360":{"position":[[3961,4]]},"2369":{"position":[[42,4],[876,4]]},"2379":{"position":[[2013,5],[2164,4]]},"2381":{"position":[[1860,4]]},"2394":{"position":[[586,4],[1118,4]]},"2396":{"position":[[87,5]]},"2426":{"position":[[137,7],[284,6]]},"2520":{"position":[[108,4]]},"2536":{"position":[[15,6],[66,6]]},"2544":{"position":[[561,6]]},"2546":{"position":[[182,6]]},"2564":{"position":[[15,5],[46,5]]},"2566":{"position":[[3340,5],[3981,5],[4731,5],[4919,5],[7920,5],[8064,5],[8204,5],[8342,5],[8602,5],[8757,5],[8924,5],[9084,5],[9239,5],[9394,5],[10806,5],[11978,5],[13228,5]]},"2568":{"position":[[15,5],[44,5],[109,5],[124,5],[149,5]]},"2570":{"position":[[15,5],[77,5]]},"2574":{"position":[[582,6]]},"2625":{"position":[[903,4],[1238,7],[1265,4],[1735,4]]},"2631":{"position":[[349,5],[515,7],[532,4],[648,4],[681,6],[2208,4],[2239,6],[2292,6]]},"2695":{"position":[[313,7]]},"2697":{"position":[[343,6],[404,5],[590,5],[1117,4],[1431,5],[1544,5]]},"2700":{"position":[[565,5],[706,5],[772,5],[840,6]]},"2702":{"position":[[331,5]]},"2713":{"position":[[558,5],[781,5],[1514,6],[1714,6],[1757,6]]},"2715":{"position":[[101,6],[270,4],[323,5],[419,5],[554,5],[764,5]]},"2719":{"position":[[343,6],[455,4],[698,5],[813,5],[1460,5],[1496,5]]},"2723":{"position":[[569,5]]},"2725":{"position":[[792,4]]},"2731":{"position":[[55,6],[420,5],[1318,5]]},"2735":{"position":[[52,6],[226,5],[282,6],[381,5],[831,5],[1366,5],[1523,5]]},"2737":{"position":[[517,5]]},"2740":{"position":[[313,7]]},"2742":{"position":[[343,6],[404,5],[489,5],[1016,4],[1330,5],[1443,5]]},"2745":{"position":[[565,5],[706,5],[772,5],[840,6]]},"2747":{"position":[[331,5]]},"2756":{"position":[[68,4],[95,4],[216,5],[307,4],[493,5],[1249,5],[1501,6]]},"2758":{"position":[[341,6],[453,4],[696,5],[811,5],[1461,5],[1497,5]]},"2762":{"position":[[582,5]]},"2764":{"position":[[1013,4]]},"2770":{"position":[[55,6],[420,5],[1341,5]]},"2774":{"position":[[188,6],[362,5],[418,6],[517,5],[833,5],[1368,5],[1525,5]]},"2776":{"position":[[517,5]]},"2781":{"position":[[19,4],[63,6]]},"2783":{"position":[[105,6],[148,4],[226,6],[517,5],[578,5]]},"2786":{"position":[[85,4],[240,4],[479,5]]},"2790":{"position":[[18,5],[153,5]]},"2805":{"position":[[171,4],[188,4]]},"2807":{"position":[[521,4],[538,4]]},"2811":{"position":[[162,4],[179,4],[218,6],[306,6]]},"2813":{"position":[[569,4]]},"2815":{"position":[[0,5],[136,5],[415,5],[428,6],[631,4],[684,4],[711,5],[1215,5],[1368,5],[1522,5]]},"2832":{"position":[[343,6],[404,5],[590,5]]},"2848":{"position":[[569,5]]},"2850":{"position":[[685,4]]},"2852":{"position":[[106,5],[373,5]]},"2858":{"position":[[619,5],[1286,6],[1450,6],[1493,6]]},"2860":{"position":[[55,6],[420,5],[1314,5]]},"2862":{"position":[[101,6],[270,4],[323,5]]},"2864":{"position":[[120,6],[339,6],[492,6]]},"2872":{"position":[[187,4]]},"2890":{"position":[[33,5],[219,5],[296,5]]},"2895":{"position":[[116,4],[197,4],[772,5],[1196,4],[3064,4],[4082,5],[4327,4],[4492,4]]},"2899":{"position":[[696,4]]},"2923":{"position":[[123,4],[482,6]]},"2927":{"position":[[12,4]]},"2929":{"position":[[12,4]]},"2931":{"position":[[244,5],[341,5]]},"2939":{"position":[[59,6],[189,5]]},"2942":{"position":[[27,6]]},"2947":{"position":[[5625,6],[5750,4],[5796,7]]},"2949":{"position":[[87,6]]},"2951":{"position":[[1135,6]]},"2955":{"position":[[61,6],[212,6]]},"2964":{"position":[[63,6]]},"2966":{"position":[[629,5],[791,4],[960,4]]},"2970":{"position":[[125,4]]},"2975":{"position":[[263,6]]},"2983":{"position":[[29,4],[41,4],[430,4]]},"2985":{"position":[[29,4],[41,4],[148,4],[543,4],[622,4]]},"2987":{"position":[[10,5],[150,5],[394,5],[516,5],[647,5]]},"2990":{"position":[[231,4],[293,5]]},"3033":{"position":[[191,4],[461,5]]},"3039":{"position":[[252,4]]},"3042":{"position":[[949,4]]},"3046":{"position":[[896,4]]},"3109":{"position":[[1327,4],[1362,5]]},"3139":{"position":[[163,4]]},"3276":{"position":[[2617,4]]},"3319":{"position":[[106,5]]},"3321":{"position":[[9,6]]},"3325":{"position":[[15,7],[27,6],[194,4],[2379,7],[2994,6]]},"3343":{"position":[[143,6]]},"3345":{"position":[[136,5]]},"3349":{"position":[[18,5]]},"3357":{"position":[[22,5]]},"3429":{"position":[[368,6]]},"3470":{"position":[[7,5]]},"3472":{"position":[[6470,4],[6729,4],[7007,4]]},"3482":{"position":[[11,6],[165,5],[2467,6],[2596,5]]},"3518":{"position":[[944,6],[2213,6]]}}}],["name/id",{"_index":2702,"t":{"485":{"position":[[256,7]]}}}],["name/sc",{"_index":8108,"t":{"2033":{"position":[[1989,8]]}}}],["name/ten",{"_index":8107,"t":{"2033":{"position":[[1939,11]]}}}],["name:ten",{"_index":8098,"t":{"2033":{"position":[[1361,11]]}}}],["name=bench",{"_index":6981,"t":{"1475":{"position":[[403,10],[732,10]]}}}],["name>.servic",{"_index":6949,"t":{"1473":{"position":[[394,13],[746,13]]}}}],["name_based_external_front",{"_index":5751,"t":{"1161":{"position":[[1134,25],[1656,25]]}}}],["name_schem",{"_index":9661,"t":{"2985":{"position":[[88,11],[589,12],[668,12]]},"2987":{"position":[[176,12]]}}}],["name_serv",{"_index":4936,"t":{"1063":{"position":[[1346,11]]},"1071":{"position":[[905,11]]}}}],["names.pi",{"_index":1861,"t":{"282":{"position":[[713,9]]}}}],["nameserv",{"_index":2708,"t":{"485":{"position":[[541,11]]},"1071":{"position":[[917,11],[938,10],[1033,11]]},"1091":{"position":[[285,12],[525,12]]}}}],["namespac",{"_index":2383,"t":{"404":{"position":[[966,10]]},"428":{"position":[[370,9],[665,10],[779,9],[1531,9],[1610,9]]},"471":{"position":[[117,9]]},"474":{"position":[[227,9],[385,9],[550,9],[839,9],[921,10],[1055,9],[1249,10]]},"604":{"position":[[2538,9],[6327,10]]},"609":{"position":[[1348,10]]},"633":{"position":[[1261,10]]},"2031":{"position":[[151,10],[244,10],[434,9]]},"2033":{"position":[[200,9],[362,10],[525,10],[1003,10],[1114,10],[1259,10],[1466,10],[1628,10]]},"3160":{"position":[[1166,11]]}}}],["namev1",{"_index":9336,"t":{"2735":{"position":[[461,9]]},"2774":{"position":[[597,9]]}}}],["namev1=$(echo",{"_index":9339,"t":{"2735":{"position":[[558,13]]},"2774":{"position":[[694,13]]}}}],["namev2",{"_index":9340,"t":{"2735":{"position":[[572,9]]},"2774":{"position":[[708,9]]}}}],["namev2=$(echo",{"_index":9335,"t":{"2735":{"position":[[447,13]]},"2774":{"position":[[583,13]]}}}],["naming.md",{"_index":9015,"t":{"2625":{"position":[[1298,10]]},"2631":{"position":[[578,10],[628,10]]},"2815":{"position":[[538,9]]}}}],["namingstrategi",{"_index":3564,"t":{"665":{"position":[[22,14]]}}}],["napkin",{"_index":1526,"t":{"223":{"position":[[352,8]]}}}],["napl",{"_index":9258,"t":{"2725":{"position":[[440,8]]},"2764":{"position":[[661,8]]},"2850":{"position":[[349,8]]}}}],["nation",{"_index":1652,"t":{"247":{"position":[[449,8]]}}}],["nativ",{"_index":2195,"t":{"363":{"position":[[170,6]]},"619":{"position":[[247,7]]},"888":{"position":[[224,6],[465,6]]},"977":{"position":[[624,6]]},"1982":{"position":[[1515,6]]},"1984":{"position":[[1125,6]]},"2942":{"position":[[367,6],[580,6],[652,7]]},"3039":{"position":[[181,8]]},"3063":{"position":[[1070,8]]},"3105":{"position":[[53,6]]},"3251":{"position":[[2610,7]]},"3295":{"position":[[91,6],[200,6]]}}}],["natur",{"_index":7913,"t":{"1863":{"position":[[201,6]]},"1925":{"position":[[201,6]]},"2705":{"position":[[84,7]]},"2750":{"position":[[84,7]]},"2795":{"position":[[1396,10]]},"3218":{"position":[[581,6]]},"3518":{"position":[[407,9]]}}}],["navig",{"_index":456,"t":{"58":{"position":[[118,8]]},"2118":{"position":[[1219,8]]},"2665":{"position":[[595,10]]},"2671":{"position":[[32,10]]},"2673":{"position":[[32,10]]}}}],["nb",{"_index":6690,"t":{"1368":{"position":[[68,2],[481,2],[1453,2]]}}}],["nbctl",{"_index":6699,"t":{"1368":{"position":[[525,5]]}}}],["nbde",{"_index":8452,"t":{"2278":{"position":[[616,6]]}}}],["nc",{"_index":4816,"t":{"1037":{"position":[[150,2]]}}}],["ncdu",{"_index":4766,"t":{"1017":{"position":[[202,4]]}}}],["near",{"_index":4668,"t":{"977":{"position":[[619,4]]},"1953":{"position":[[177,4]]}}}],["nearli",{"_index":864,"t":{"133":{"position":[[7,6]]}}}],["neccess",{"_index":9990,"t":{"3245":{"position":[[664,10]]}}}],["necess",{"_index":7931,"t":{"1880":{"position":[[838,9]]},"1890":{"position":[[429,9]]},"1892":{"position":[[1257,9]]},"1996":{"position":[[838,9]]},"2006":{"position":[[429,9]]},"2008":{"position":[[1257,9]]},"2951":{"position":[[624,9]]},"3071":{"position":[[2789,10]]},"3126":{"position":[[174,9]]},"3204":{"position":[[33,9]]},"3245":{"position":[[1130,9]]},"3325":{"position":[[3310,9]]}}}],["necessari",{"_index":914,"t":{"141":{"position":[[314,10]]},"204":{"position":[[158,9]]},"206":{"position":[[415,10]]},"223":{"position":[[158,9]]},"225":{"position":[[177,10]]},"227":{"position":[[169,10],[472,9]]},"229":{"position":[[219,9]]},"231":{"position":[[203,10],[270,10]]},"274":{"position":[[274,9]]},"325":{"position":[[1247,9]]},"366":{"position":[[1668,9]]},"379":{"position":[[716,9]]},"625":{"position":[[118,9]]},"650":{"position":[[954,9]]},"986":{"position":[[65,9]]},"988":{"position":[[70,9]]},"1063":{"position":[[70,9]]},"1073":{"position":[[359,9]]},"1080":{"position":[[95,10],[994,10]]},"1114":{"position":[[1784,9],[5390,9]]},"1156":{"position":[[16,9]]},"1213":{"position":[[719,9]]},"1224":{"position":[[2417,9],[2566,9]]},"1226":{"position":[[1473,9]]},"1234":{"position":[[3087,9]]},"1240":{"position":[[1289,10]]},"1246":{"position":[[145,9]]},"1258":{"position":[[142,10]]},"1260":{"position":[[142,10]]},"1262":{"position":[[116,9],[234,9]]},"1264":{"position":[[329,10]]},"1286":{"position":[[84,9],[786,9],[1112,9],[1539,9]]},"1292":{"position":[[167,9]]},"1294":{"position":[[1017,9],[1105,10]]},"1344":{"position":[[441,9]]},"1419":{"position":[[993,9]]},"1444":{"position":[[848,10]]},"1564":{"position":[[231,9]]},"1574":{"position":[[98,9]]},"1608":{"position":[[136,9]]},"1610":{"position":[[291,10]]},"1674":{"position":[[758,10]]},"1678":{"position":[[215,9]]},"1731":{"position":[[16,9]]},"1768":{"position":[[24,9]]},"1779":{"position":[[1752,9],[2824,9],[3068,9],[5553,9]]},"1787":{"position":[[138,10]]},"1794":{"position":[[307,9],[740,9]]},"1822":{"position":[[829,9],[917,10],[1180,9],[1268,10]]},"1825":{"position":[[95,10],[1157,10],[2362,10]]},"1857":{"position":[[980,9]]},"1861":{"position":[[167,9]]},"1908":{"position":[[1867,9]]},"1919":{"position":[[980,9]]},"1923":{"position":[[167,9]]},"2024":{"position":[[1867,9]]},"2106":{"position":[[365,9]]},"2461":{"position":[[292,9]]},"2623":{"position":[[234,9]]},"2627":{"position":[[240,10]]},"2635":{"position":[[627,10]]},"2637":{"position":[[306,9]]},"2673":{"position":[[894,9]]},"2677":{"position":[[253,10]]},"2909":{"position":[[77,9]]},"3069":{"position":[[386,9]]},"3071":{"position":[[2379,9]]},"3082":{"position":[[2030,9]]},"3103":{"position":[[1268,9]]},"3197":{"position":[[983,9]]},"3206":{"position":[[278,9]]},"3218":{"position":[[327,9]]},"3224":{"position":[[1410,9]]},"3236":{"position":[[351,9]]},"3272":{"position":[[332,9],[808,9]]},"3280":{"position":[[762,10]]},"3325":{"position":[[1624,9],[3422,9]]},"3444":{"position":[[8,9]]}}}],["necessarili",{"_index":1274,"t":{"178":{"position":[[1321,11]]},"2709":{"position":[[522,11]]},"2754":{"position":[[522,11]]},"2844":{"position":[[450,11]]},"3103":{"position":[[1139,11]]},"3227":{"position":[[582,11]]},"3270":{"position":[[1714,11]]}}}],["necessit",{"_index":9075,"t":{"2675":{"position":[[594,12]]},"3208":{"position":[[328,13]]}}}],["necsessarili",{"_index":10223,"t":{"3403":{"position":[[238,12]]}}}],["need",{"_index":267,"t":{"25":{"position":[[222,6]]},"27":{"position":[[61,6]]},"30":{"position":[[81,6]]},"32":{"position":[[61,6]]},"46":{"position":[[24,5]]},"53":{"position":[[24,5]]},"75":{"position":[[134,5]]},"79":{"position":[[604,4]]},"87":{"position":[[29,4]]},"89":{"position":[[31,4]]},"101":{"position":[[123,4]]},"139":{"position":[[38,6],[93,5]]},"141":{"position":[[7,4],[99,7]]},"158":{"position":[[484,4],[755,4]]},"168":{"position":[[918,4],[1058,5],[1107,6]]},"170":{"position":[[1016,5]]},"174":{"position":[[38,5]]},"176":{"position":[[179,5]]},"178":{"position":[[755,4],[1058,6],[2174,6],[2199,4],[2569,4],[2901,4]]},"202":{"position":[[534,4]]},"206":{"position":[[233,4],[340,5]]},"249":{"position":[[373,4]]},"259":{"position":[[46,4]]},"270":{"position":[[168,4],[523,4]]},"272":{"position":[[48,4]]},"302":{"position":[[356,5],[1444,5]]},"311":{"position":[[228,4]]},"315":{"position":[[207,4],[420,4]]},"321":{"position":[[296,4],[609,4],[684,5]]},"325":{"position":[[825,5],[972,4],[1290,4],[1424,4],[1601,4],[2336,5],[2808,5],[3343,5]]},"327":{"position":[[243,5]]},"361":{"position":[[32,4]]},"383":{"position":[[90,4]]},"385":{"position":[[108,5]]},"393":{"position":[[698,4],[1708,4]]},"411":{"position":[[47,5]]},"413":{"position":[[709,4]]},"442":{"position":[[429,4]]},"447":{"position":[[764,4]]},"460":{"position":[[550,6]]},"471":{"position":[[1046,4]]},"474":{"position":[[128,4]]},"483":{"position":[[633,6]]},"501":{"position":[[200,6],[455,6]]},"505":{"position":[[514,6],[889,7]]},"507":{"position":[[764,7]]},"509":{"position":[[138,6],[327,6]]},"513":{"position":[[415,6],[789,6]]},"519":{"position":[[4,4]]},"530":{"position":[[1348,4]]},"548":{"position":[[121,4]]},"552":{"position":[[690,4]]},"583":{"position":[[219,6]]},"586":{"position":[[21,4],[635,4]]},"600":{"position":[[433,4]]},"604":{"position":[[3064,6],[5719,5],[10709,4]]},"609":{"position":[[388,7],[4471,5]]},"617":{"position":[[601,4],[783,6],[1244,4]]},"619":{"position":[[717,4]]},"621":{"position":[[221,4]]},"623":{"position":[[245,4]]},"625":{"position":[[238,6]]},"627":{"position":[[592,6],[700,4],[1772,6],[3109,4],[3632,4]]},"631":{"position":[[224,6],[325,6],[636,7]]},"633":{"position":[[1456,6]]},"635":{"position":[[226,5],[3429,4]]},"637":{"position":[[92,4],[176,4]]},"646":{"position":[[1657,4]]},"650":{"position":[[349,5]]},"652":{"position":[[51,5],[361,5],[972,4]]},"654":{"position":[[503,4]]},"669":{"position":[[1137,4]]},"708":{"position":[[40,5]]},"718":{"position":[[70,6]]},"817":{"position":[[556,5]]},"819":{"position":[[7016,4],[7510,4]]},"880":{"position":[[451,5]]},"895":{"position":[[147,6]]},"899":{"position":[[977,6]]},"903":{"position":[[3836,4]]},"905":{"position":[[3,4],[807,4],[1147,4],[2095,4]]},"907":{"position":[[96,4],[635,4]]},"913":{"position":[[674,4],[3493,4]]},"920":{"position":[[448,5],[547,4]]},"926":{"position":[[37,4]]},"928":{"position":[[230,6]]},"930":{"position":[[4,4]]},"932":{"position":[[443,5],[653,4],[2054,4]]},"942":{"position":[[236,4]]},"947":{"position":[[1994,4]]},"949":{"position":[[332,4],[493,5],[665,5]]},"977":{"position":[[399,6]]},"1067":{"position":[[131,5]]},"1089":{"position":[[71,5]]},"1150":{"position":[[6395,4],[6496,6],[6781,6],[7034,6]]},"1165":{"position":[[1538,5],[3451,5]]},"1205":{"position":[[50,4]]},"1232":{"position":[[278,4]]},"1234":{"position":[[1178,6],[3023,4]]},"1236":{"position":[[512,6]]},"1256":{"position":[[199,4],[2726,4]]},"1284":{"position":[[484,4]]},"1286":{"position":[[2590,4]]},"1471":{"position":[[169,4]]},"1473":{"position":[[17,4]]},"1507":{"position":[[556,5]]},"1509":{"position":[[7016,4],[7510,4]]},"1560":{"position":[[120,6]]},"1569":{"position":[[999,6]]},"1587":{"position":[[814,5]]},"1591":{"position":[[89,4]]},"1617":{"position":[[147,6]]},"1621":{"position":[[977,6]]},"1625":{"position":[[3836,4]]},"1627":{"position":[[3,4],[807,4],[1147,4],[2095,4]]},"1629":{"position":[[96,4],[635,4]]},"1635":{"position":[[674,4],[3493,4]]},"1642":{"position":[[448,5],[547,4]]},"1648":{"position":[[37,4]]},"1650":{"position":[[230,6]]},"1652":{"position":[[4,4]]},"1654":{"position":[[443,5],[653,4],[2054,4]]},"1664":{"position":[[236,4]]},"1669":{"position":[[1994,4]]},"1671":{"position":[[332,4],[493,5],[665,5]]},"1674":{"position":[[74,6],[811,4],[865,4]]},"1684":{"position":[[592,6],[844,5],[1287,5],[1606,5],[1927,5],[2258,5],[2580,5],[2902,5],[3223,5],[3539,5]]},"1697":{"position":[[38,6],[93,5]]},"1699":{"position":[[7,4],[92,7]]},"1745":{"position":[[6,4],[541,4],[580,5]]},"1747":{"position":[[81,4]]},"1754":{"position":[[231,5]]},"1779":{"position":[[6547,7]]},"1791":{"position":[[1615,6]]},"1820":{"position":[[495,4]]},"1833":{"position":[[167,4],[1438,5]]},"1835":{"position":[[279,4]]},"1839":{"position":[[316,4]]},"1843":{"position":[[17,4]]},"1845":{"position":[[31,4],[440,4],[611,6],[1459,4],[2418,4]]},"1849":{"position":[[706,4]]},"1851":{"position":[[64,4],[127,5]]},"1855":{"position":[[42,4],[482,6],[795,6],[1131,4]]},"1857":{"position":[[106,4],[217,6],[1017,7]]},"1865":{"position":[[153,4]]},"1882":{"position":[[544,6]]},"1894":{"position":[[515,5]]},"1906":{"position":[[232,4]]},"1908":{"position":[[1665,5]]},"1913":{"position":[[239,5]]},"1917":{"position":[[42,4],[482,6],[795,6],[1131,4]]},"1919":{"position":[[106,4],[217,6],[1017,7]]},"1927":{"position":[[153,4]]},"1939":{"position":[[156,5]]},"1957":{"position":[[195,4],[3126,4]]},"1959":{"position":[[179,6],[1205,6]]},"1963":{"position":[[146,6]]},"1998":{"position":[[544,6]]},"2010":{"position":[[515,5]]},"2022":{"position":[[232,4]]},"2024":{"position":[[1665,5]]},"2029":{"position":[[239,5]]},"2043":{"position":[[822,4]]},"2045":{"position":[[74,5]]},"2079":{"position":[[365,6]]},"2106":{"position":[[406,6]]},"2110":{"position":[[250,6],[689,4],[870,5]]},"2114":{"position":[[142,5]]},"2158":{"position":[[175,6]]},"2162":{"position":[[606,4]]},"2212":{"position":[[115,4],[167,5]]},"2217":{"position":[[82,4],[122,6]]},"2233":{"position":[[283,4],[541,4]]},"2235":{"position":[[555,4]]},"2253":{"position":[[391,4]]},"2283":{"position":[[715,5]]},"2286":{"position":[[188,6]]},"2294":{"position":[[26,4]]},"2296":{"position":[[156,4]]},"2328":{"position":[[138,6]]},"2330":{"position":[[490,5]]},"2342":{"position":[[147,6]]},"2346":{"position":[[977,6]]},"2350":{"position":[[3836,4]]},"2352":{"position":[[3,4],[807,4],[1147,4],[2095,4]]},"2354":{"position":[[96,4],[635,4]]},"2360":{"position":[[674,4],[3493,4]]},"2367":{"position":[[448,5],[547,4]]},"2373":{"position":[[37,4]]},"2375":{"position":[[230,6]]},"2377":{"position":[[4,4]]},"2379":{"position":[[443,5],[653,4],[2054,4]]},"2389":{"position":[[236,4]]},"2394":{"position":[[1994,4]]},"2396":{"position":[[332,4],[493,5],[665,5]]},"2576":{"position":[[146,4],[283,4]]},"2623":{"position":[[387,5]]},"2644":{"position":[[171,4]]},"2651":{"position":[[36,4],[421,4]]},"2673":{"position":[[666,4],[1046,6],[1626,6]]},"2675":{"position":[[444,6]]},"2688":{"position":[[863,4]]},"2697":{"position":[[37,4],[522,4],[1509,4]]},"2705":{"position":[[41,4],[1228,6]]},"2709":{"position":[[612,4],[1835,4]]},"2719":{"position":[[564,4],[1295,4]]},"2727":{"position":[[550,4]]},"2729":{"position":[[130,4]]},"2731":{"position":[[209,4],[1262,4],[1358,6],[1450,4]]},"2735":{"position":[[985,5],[1497,4]]},"2742":{"position":[[37,4],[1408,4]]},"2750":{"position":[[41,4]]},"2754":{"position":[[612,4],[1976,4]]},"2758":{"position":[[562,4],[1293,4]]},"2766":{"position":[[750,4]]},"2768":{"position":[[153,4]]},"2770":{"position":[[209,4],[1285,4],[1381,6],[1473,4]]},"2774":{"position":[[987,5],[1499,4]]},"2779":{"position":[[124,6]]},"2813":{"position":[[1236,5]]},"2820":{"position":[[79,4]]},"2822":{"position":[[82,4]]},"2832":{"position":[[37,4],[522,4]]},"2844":{"position":[[540,4],[1629,4]]},"2852":{"position":[[897,4],[1229,4]]},"2860":{"position":[[209,4],[1258,4],[1354,6],[1446,4]]},"2897":{"position":[[24,5],[236,5]]},"2899":{"position":[[28,5],[262,5]]},"2901":{"position":[[1019,4]]},"2909":{"position":[[12,4]]},"2921":{"position":[[37,4],[407,4]]},"2944":{"position":[[888,6]]},"2947":{"position":[[1229,5],[4655,4],[4982,4]]},"2951":{"position":[[235,5],[864,4]]},"2957":{"position":[[35,5]]},"2966":{"position":[[549,4],[2391,5],[3314,4]]},"2968":{"position":[[173,6]]},"2970":{"position":[[77,6],[446,5]]},"3003":{"position":[[793,7]]},"3011":{"position":[[820,7],[1026,7],[1874,4]]},"3044":{"position":[[406,4]]},"3055":{"position":[[682,4],[1048,4]]},"3063":{"position":[[339,4],[1113,6]]},"3082":{"position":[[1313,4],[1459,7]]},"3103":{"position":[[1251,6],[1461,5]]},"3105":{"position":[[464,5]]},"3113":{"position":[[281,5]]},"3126":{"position":[[992,4]]},"3154":{"position":[[596,5]]},"3167":{"position":[[41,4]]},"3182":{"position":[[1481,4],[1985,4]]},"3184":{"position":[[534,4],[1771,5]]},"3197":{"position":[[472,5]]},"3204":{"position":[[363,4]]},"3206":{"position":[[224,7]]},"3220":{"position":[[363,4]]},"3224":{"position":[[46,6],[424,4],[824,4]]},"3227":{"position":[[158,5],[392,4]]},"3234":{"position":[[302,5],[409,4],[832,4]]},"3236":{"position":[[1859,4]]},"3238":{"position":[[170,4]]},"3245":{"position":[[768,5]]},"3247":{"position":[[796,5]]},"3249":{"position":[[60,5],[882,4]]},"3251":{"position":[[2131,4],[2223,5]]},"3253":{"position":[[93,4],[340,4]]},"3268":{"position":[[70,4]]},"3270":{"position":[[1455,4]]},"3272":{"position":[[107,5],[296,5]]},"3274":{"position":[[449,5]]},"3276":{"position":[[282,4],[2076,4],[2554,5],[2596,4]]},"3280":{"position":[[416,5]]},"3308":{"position":[[368,4]]},"3310":{"position":[[733,7]]},"3316":{"position":[[858,6],[1121,5]]},"3325":{"position":[[2712,6]]},"3343":{"position":[[211,5]]},"3363":{"position":[[257,4]]},"3376":{"position":[[93,4],[198,4]]},"3380":{"position":[[120,7]]},"3382":{"position":[[187,4]]},"3389":{"position":[[279,5]]},"3391":{"position":[[532,7],[691,6]]},"3393":{"position":[[37,5],[722,4]]},"3395":{"position":[[114,6],[1317,5]]},"3400":{"position":[[37,5],[602,6]]},"3417":{"position":[[63,4]]},"3419":{"position":[[271,4]]},"3423":{"position":[[118,5],[294,4]]},"3444":{"position":[[119,6]]},"3446":{"position":[[6,4],[271,4]]},"3472":{"position":[[6204,4],[6305,6],[6590,6],[6843,6]]}}}],["neg",{"_index":4623,"t":{"938":{"position":[[98,10]]},"1660":{"position":[[98,10]]},"2385":{"position":[[98,10]]}}}],["neglig",{"_index":1095,"t":{"170":{"position":[[212,11],[974,11]]}}}],["negoti",{"_index":1616,"t":{"245":{"position":[[472,10]]},"2688":{"position":[[3048,10]]}}}],["ness",{"_index":10249,"t":{"3475":{"position":[[369,4]]},"3482":{"position":[[2962,4]]},"3484":{"position":[[85,4]]}}}],["nest",{"_index":2061,"t":{"325":{"position":[[2041,9]]},"1174":{"position":[[63,6]]},"1176":{"position":[[65,6]]},"1587":{"position":[[214,6],[352,6],[385,6],[489,6]]},"1773":{"position":[[208,6]]},"1896":{"position":[[772,6]]},"2012":{"position":[[772,6]]},"2723":{"position":[[409,6],[535,8],[745,6]]},"2762":{"position":[[422,6],[548,8],[758,6]]},"2848":{"position":[[409,6],[535,8]]}}}],["nested=i",{"_index":5951,"t":{"1174":{"position":[[22,9]]},"1176":{"position":[[24,9]]}}}],["net",{"_index":4188,"t":{"859":{"position":[[2434,3],[2835,3]]},"861":{"position":[[251,3]]},"1368":{"position":[[615,4]]},"1603":{"position":[[2434,3],[2835,3]]},"1605":{"position":[[251,3]]},"1845":{"position":[[2678,3]]}}}],["net.core.rmem_max",{"_index":4795,"t":{"1031":{"position":[[405,17]]}}}],["net.core.somaxconn",{"_index":4798,"t":{"1031":{"position":[[511,18]]}}}],["net.core.wmem_max",{"_index":4793,"t":{"1031":{"position":[[369,17]]}}}],["net.ipv4.tcp_fin_timeout",{"_index":4796,"t":{"1031":{"position":[[441,24]]}}}],["net.ipv4.tcp_keepalive_intvl",{"_index":4791,"t":{"1031":{"position":[[288,28]]}}}],["net.ipv4.tcp_keepalive_prob",{"_index":4792,"t":{"1031":{"position":[[328,29]]}}}],["net.ipv4.tcp_keepalive_tim",{"_index":4790,"t":{"1031":{"position":[[249,27]]}}}],["net.ipv4.tcp_max_syn_backlog",{"_index":4800,"t":{"1031":{"position":[[579,28]]}}}],["net.ipv4.tcp_syncooki",{"_index":4799,"t":{"1031":{"position":[[544,23]]}}}],["net.ipv4.tcp_tw_reus",{"_index":4797,"t":{"1031":{"position":[[478,21]]}}}],["net.netfilter.nf_conntrack_max",{"_index":4802,"t":{"1031":{"position":[[645,30]]}}}],["net003",{"_index":6022,"t":{"1224":{"position":[[3154,9],[3333,9]]}}}],["netbox",{"_index":925,"t":{"143":{"position":[[129,6]]},"1073":{"position":[[298,6]]},"1262":{"position":[[192,6],[251,6],[290,6]]},"1576":{"position":[[608,6]]},"1731":{"position":[[2464,6],[2521,7],[2529,6]]},"1787":{"position":[[490,6]]},"1789":{"position":[[1111,6]]},"1814":{"position":[[239,6]]},"2190":{"position":[[314,7]]},"2248":{"position":[[1226,6],[1412,7]]},"3005":{"position":[[135,6],[179,6]]}}}],["netbox.netbox",{"_index":924,"t":{"143":{"position":[[60,13],[488,13]]}}}],["netbox.netbox.netbox_manufactur",{"_index":927,"t":{"143":{"position":[[150,34]]}}}],["netbox.testbed.osism.xyz",{"_index":7578,"t":{"1787":{"position":[[465,24]]}}}],["netbox:latest",{"_index":7338,"t":{"1731":{"position":[[2493,13]]}}}],["netbox_data_manufactur",{"_index":935,"t":{"143":{"position":[[405,25]]}}}],["netbox_sit",{"_index":940,"t":{"143":{"position":[[539,12]]}}}],["netbox_token",{"_index":929,"t":{"143":{"position":[[216,13],[234,12],[583,13],[601,12]]}}}],["netbox_url",{"_index":928,"t":{"143":{"position":[[185,11],[201,10],[552,11],[568,10]]}}}],["netcat",{"_index":4403,"t":{"909":{"position":[[66,6]]},"1631":{"position":[[66,6]]},"2356":{"position":[[66,6]]}}}],["netdata",{"_index":4272,"t":{"865":{"position":[[500,7]]},"878":{"position":[[500,7]]},"1067":{"position":[[4467,7],[4590,7]]},"1360":{"position":[[632,7],[671,7]]},"1576":{"position":[[669,7]]},"1789":{"position":[[1166,7]]},"1814":{"position":[[246,7]]},"2190":{"position":[[331,8]]}}}],["netdata_host_typ",{"_index":4968,"t":{"1067":{"position":[[4514,18],[4608,18]]}}}],["netlifi",{"_index":10135,"t":{"3316":{"position":[[1216,7],[1273,7],[1343,7],[1846,7]]}}}],["netowrk",{"_index":5117,"t":{"1094":{"position":[[91,7]]}}}],["netplan",{"_index":5062,"t":{"1089":{"position":[[49,7],[112,7],[759,7],[2602,7],[2797,7],[2841,7]]},"1091":{"position":[[4,7]]},"1094":{"position":[[113,7]]},"1098":{"position":[[427,7]]},"1585":{"position":[[2097,7]]}}}],["netplan(5",{"_index":5076,"t":{"1089":{"position":[[934,11]]}}}],["netweav",{"_index":6050,"t":{"1226":{"position":[[1767,9],[1794,9]]}}}],["network",{"_index":33,"t":{"4":{"position":[[400,8]]},"168":{"position":[[226,9]]},"172":{"position":[[388,9],[786,9]]},"174":{"position":[[274,7]]},"176":{"position":[[1199,7]]},"245":{"position":[[33,7],[1165,8]]},"284":{"position":[[798,11]]},"485":{"position":[[299,8],[346,7],[384,9],[442,7]]},"487":{"position":[[4637,10]]},"503":{"position":[[419,7]]},"507":{"position":[[359,10],[692,10]]},"530":{"position":[[119,9]]},"590":{"position":[[2581,8]]},"615":{"position":[[727,7]]},"627":{"position":[[5169,7]]},"712":{"position":[[56,7]]},"738":{"position":[[324,8]]},"740":{"position":[[370,7]]},"746":{"position":[[206,7]]},"748":{"position":[[125,11],[145,10],[432,7]]},"750":{"position":[[146,10],[206,8]]},"754":{"position":[[13,7],[28,7],[129,8],[164,7],[215,7]]},"760":{"position":[[145,7]]},"772":{"position":[[14,10],[53,10],[117,9],[279,8],[418,9],[555,10],[741,10]]},"813":{"position":[[244,7],[271,7],[354,7],[454,7],[499,7],[591,7]]},"819":{"position":[[573,8],[597,8],[667,7],[827,8],[853,8],[899,7],[1015,7],[1179,7],[1319,7],[2286,7],[2305,7],[2342,7],[2362,7],[2471,7],[2500,7],[2824,7],[2860,7],[2884,7],[2921,7],[2998,7],[3041,7],[3217,7],[3247,7],[3442,7],[3492,7],[3659,7],[3701,7]]},"821":{"position":[[37,8],[2694,10],[2723,10],[3066,7],[4016,10],[4047,10],[4403,7],[5346,10],[5375,10],[5720,7]]},"842":{"position":[[232,7],[1515,7],[1611,7]]},"853":{"position":[[225,8]]},"857":{"position":[[256,7],[280,7]]},"859":{"position":[[568,7],[576,8],[588,7],[1700,7],[1708,7],[1718,7],[1744,7],[2421,7],[2822,7]]},"861":{"position":[[236,7]]},"865":{"position":[[152,10]]},"868":{"position":[[73,7]]},"870":{"position":[[42,7]]},"874":{"position":[[42,7],[79,7]]},"878":{"position":[[152,10]]},"895":{"position":[[1333,7],[1366,9]]},"903":{"position":[[376,7],[404,7],[417,7],[519,8],[547,7],[702,7],[722,7],[788,7],[801,7],[1943,7],[1956,7],[3336,8]]},"909":{"position":[[1893,8],[2607,8],[2689,9]]},"913":{"position":[[1362,7],[1733,8],[1742,8],[2021,8],[2485,8]]},"947":{"position":[[1195,8]]},"956":{"position":[[832,11],[1819,7],[1882,10],[1957,9],[1984,10],[2092,7]]},"977":{"position":[[1098,7],[2079,11],[2120,10],[2204,7],[2244,7],[2330,11],[2365,7]]},"984":{"position":[[115,7],[153,7]]},"988":{"position":[[12,7],[35,7],[121,8],[147,7]]},"1067":{"position":[[1982,7],[2244,7],[2363,7],[2403,7],[2470,7],[2499,7],[3611,7],[3645,7],[3790,7],[3813,9],[4634,7]]},"1071":{"position":[[68,7]]},"1089":{"position":[[31,7],[862,7],[950,8],[1661,7],[2401,7],[2529,7]]},"1098":{"position":[[405,7]]},"1118":{"position":[[237,7]]},"1188":{"position":[[48,7],[89,7],[127,7],[223,8],[280,7],[326,7],[380,7]]},"1224":{"position":[[2670,7],[2734,7],[2769,7],[2855,7],[3138,8],[3317,8]]},"1226":{"position":[[1254,7],[1376,7],[1396,7],[1438,7],[1505,8]]},"1234":{"position":[[187,7],[677,7],[730,7],[829,7]]},"1244":{"position":[[272,7]]},"1252":{"position":[[944,7]]},"1258":{"position":[[374,7],[484,7],[515,7],[538,7],[569,7],[690,7],[761,7],[831,7]]},"1284":{"position":[[88,7],[211,7],[376,7]]},"1356":{"position":[[9,7],[81,7]]},"1360":{"position":[[122,7],[347,7]]},"1362":{"position":[[1391,7],[1559,7],[1605,7],[2334,7],[2421,7]]},"1366":{"position":[[85,7],[112,7]]},"1388":{"position":[[212,7]]},"1400":{"position":[[725,7]]},"1503":{"position":[[244,7],[271,7],[354,7],[454,7],[499,7],[591,7]]},"1509":{"position":[[573,8],[597,8],[667,7],[827,8],[853,8],[899,7],[1015,7],[1179,7],[1319,7],[2286,7],[2305,7],[2342,7],[2362,7],[2471,7],[2500,7],[2824,7],[2860,7],[2884,7],[2921,7],[2998,7],[3041,7],[3217,7],[3247,7],[3442,7],[3492,7],[3659,7],[3701,7]]},"1511":{"position":[[37,8],[2694,10],[2723,10],[3066,7],[4016,10],[4047,10],[4403,7],[5346,10],[5375,10],[5720,7]]},"1557":{"position":[[232,7],[1515,7],[1611,7]]},"1562":{"position":[[661,7],[680,7],[741,7]]},"1564":{"position":[[249,9]]},"1569":{"position":[[1088,7],[1534,7]]},"1571":{"position":[[1478,7]]},"1585":{"position":[[130,7],[174,7],[625,8],[686,7],[746,7],[874,7],[939,7],[1001,7],[1022,7],[1060,7],[1081,7],[1119,7],[1140,7],[1180,7],[1201,7],[1241,7],[1262,7],[1302,7],[1323,7],[1669,7],[1762,7],[2084,7],[2216,7],[2864,7],[2947,7],[3444,7],[3522,8],[3667,8],[3789,7]]},"1597":{"position":[[225,8]]},"1601":{"position":[[256,7],[280,7]]},"1603":{"position":[[568,7],[576,8],[588,7],[1700,7],[1708,7],[1718,7],[1744,7],[2421,7],[2822,7]]},"1605":{"position":[[236,7]]},"1617":{"position":[[1333,7],[1366,9]]},"1625":{"position":[[376,7],[404,7],[417,7],[519,8],[547,7],[702,7],[722,7],[788,7],[801,7],[1943,7],[1956,7],[3336,8]]},"1631":{"position":[[1893,8],[2607,8],[2689,9]]},"1635":{"position":[[1362,7],[1733,8],[1742,8],[2021,8],[2485,8]]},"1669":{"position":[[1195,8]]},"1743":{"position":[[648,8],[1564,8],[1577,7]]},"1773":{"position":[[722,7],[905,8]]},"1775":{"position":[[278,7]]},"1779":{"position":[[5010,8],[6424,7]]},"1820":{"position":[[99,7],[222,7],[387,7]]},"1829":{"position":[[267,7],[515,7]]},"1833":{"position":[[1529,8]]},"1845":{"position":[[1478,7],[1669,7]]},"1847":{"position":[[189,8]]},"1849":{"position":[[724,7],[859,7]]},"1853":{"position":[[45,7],[159,7],[215,8],[249,7]]},"1857":{"position":[[18,7]]},"1874":{"position":[[237,7]]},"1915":{"position":[[45,7],[159,7],[215,8],[249,7]]},"1919":{"position":[[18,7]]},"1972":{"position":[[222,10]]},"1990":{"position":[[237,7]]},"2081":{"position":[[121,9],[218,7]]},"2190":{"position":[[93,10]]},"2250":{"position":[[74,7]]},"2278":{"position":[[586,7]]},"2342":{"position":[[1333,7],[1366,9]]},"2350":{"position":[[376,7],[404,7],[417,7],[519,8],[547,7],[702,7],[722,7],[788,7],[801,7],[1943,7],[1956,7],[3336,8]]},"2356":{"position":[[1893,8],[2607,8],[2689,9]]},"2360":{"position":[[1362,7],[1733,8],[1742,8],[2021,8],[2485,8]]},"2394":{"position":[[1195,8]]},"2520":{"position":[[403,7]]},"2544":{"position":[[197,11]]},"2566":{"position":[[7585,12],[7882,9]]},"2671":{"position":[[451,7]]},"2700":{"position":[[364,7]]},"2709":{"position":[[92,7],[806,8]]},"2711":{"position":[[1066,9]]},"2729":{"position":[[25,11]]},"2731":{"position":[[740,7]]},"2733":{"position":[[73,7]]},"2745":{"position":[[364,7]]},"2754":{"position":[[92,7],[947,8]]},"2756":{"position":[[554,7]]},"2768":{"position":[[48,11]]},"2770":{"position":[[740,7]]},"2772":{"position":[[73,7]]},"2835":{"position":[[305,7]]},"2844":{"position":[[20,7],[734,8]]},"2852":{"position":[[1169,11]]},"2854":{"position":[[73,7]]},"2856":{"position":[[1044,9]]},"2860":{"position":[[701,7]]},"2923":{"position":[[893,7]]},"2933":{"position":[[442,7],[595,9]]},"2944":{"position":[[276,9],[411,9],[1222,7],[1259,7],[1413,9]]},"2947":{"position":[[3117,9],[5273,7],[6026,9]]},"2949":{"position":[[943,9]]},"2951":{"position":[[808,9]]},"2960":{"position":[[546,7]]},"2999":{"position":[[63,11],[240,8],[340,7],[389,7]]},"3003":{"position":[[8,7],[67,7],[140,7],[200,8],[222,7],[539,7],[729,7]]},"3005":{"position":[[218,7]]},"3007":{"position":[[140,7],[243,7]]},"3011":{"position":[[2400,7]]},"3023":{"position":[[153,7]]},"3074":{"position":[[52,7],[167,7],[223,8]]},"3076":{"position":[[65,7]]},"3078":{"position":[[187,10]]},"3080":{"position":[[746,7]]},"3097":{"position":[[127,8]]},"3099":{"position":[[99,8],[256,7]]},"3103":{"position":[[563,10],[1739,7]]},"3105":{"position":[[142,7],[431,7]]},"3109":{"position":[[4,7],[79,7],[319,7],[1233,7],[1435,7],[1987,7],[2108,7],[2587,7]]},"3113":{"position":[[250,7]]},"3115":{"position":[[99,7]]},"3270":{"position":[[1730,7]]},"3284":{"position":[[478,7]]},"3301":{"position":[[2244,7]]},"3376":{"position":[[173,7]]},"3389":{"position":[[126,11]]},"3393":{"position":[[273,7]]},"3400":{"position":[[627,7],[914,7]]},"3408":{"position":[[307,7]]}}}],["network.host",{"_index":5868,"t":{"1167":{"position":[[1185,13],[3089,13]]}}}],["network.id",{"_index":4204,"t":{"859":{"position":[[2868,10]]},"1603":{"position":[[2868,10]]}}}],["network.sh",{"_index":3301,"t":{"627":{"position":[[5107,10],[5272,10]]}}}],["network.yml",{"_index":7091,"t":{"1585":{"position":[[2819,11]]}}}],["network=$(openstack",{"_index":4462,"t":{"913":{"position":[[1342,19]]},"1635":{"position":[[1342,19]]},"2360":{"position":[[1342,19]]}}}],["network_allow_service_restart",{"_index":5101,"t":{"1089":{"position":[[2920,29],[2999,30]]}}}],["network_availability_zon",{"_index":7524,"t":{"1773":{"position":[[1205,25]]},"1808":{"position":[[596,25]]}}}],["network_bond",{"_index":5089,"t":{"1089":{"position":[[1731,13]]}}}],["network_bonds|to_nice_yaml(indent=4)|indent(4",{"_index":5079,"t":{"1089":{"position":[[1033,46]]}}}],["network_bridg",{"_index":5092,"t":{"1089":{"position":[[1836,15]]}}}],["network_bridges|to_nice_yaml(indent=4)|indent(4",{"_index":5080,"t":{"1089":{"position":[[1095,48]]}}}],["network_dummy_interfac",{"_index":5118,"t":{"1094":{"position":[[136,25]]},"1098":{"position":[[435,25]]}}}],["network_dummy_interface_mtu",{"_index":5121,"t":{"1094":{"position":[[224,28]]}}}],["network_ethernet",{"_index":4958,"t":{"1067":{"position":[[2570,18],[4831,18]]},"1089":{"position":[[1945,17]]},"1091":{"position":[[173,18]]},"1098":{"position":[[470,18]]},"1585":{"position":[[1976,18]]}}}],["network_ethernets|to_nice_yaml(indent=4)|indent(4",{"_index":5082,"t":{"1089":{"position":[[1161,50]]}}}],["network_external_allocation_pool_end",{"_index":6555,"t":{"1356":{"position":[[211,36]]}}}],["network_external_allocation_pool_start",{"_index":6557,"t":{"1356":{"position":[[266,38]]}}}],["network_external_cidr",{"_index":6559,"t":{"1356":{"position":[[323,21]]}}}],["network_external_cloud",{"_index":6561,"t":{"1356":{"position":[[364,22]]}}}],["network_external_gateway_ip",{"_index":6562,"t":{"1356":{"position":[[393,27]]}}}],["network_external_nam",{"_index":6564,"t":{"1356":{"position":[[437,21]]}}}],["network_external_provider_network_typ",{"_index":6565,"t":{"1356":{"position":[[466,38]]}}}],["network_external_provider_physical_network",{"_index":6566,"t":{"1356":{"position":[[510,42]]}}}],["network_external_st",{"_index":6568,"t":{"1356":{"position":[[562,22]]}}}],["network_interfac",{"_index":4972,"t":{"1067":{"position":[[4968,18]]},"1098":{"position":[[925,18]]},"1163":{"position":[[30,17],[83,17],[136,17],[174,17],[255,17],[388,17]]}}}],["network_nam",{"_index":7097,"t":{"1585":{"position":[[3220,13]]}}}],["network_netplan_fil",{"_index":5067,"t":{"1089":{"position":[[239,20]]}}}],["network_netplan_managed_files_extra",{"_index":5072,"t":{"1089":{"position":[[607,36]]}}}],["network_netplan_path",{"_index":5066,"t":{"1089":{"position":[[214,20]]}}}],["network_netplan_permiss",{"_index":5069,"t":{"1089":{"position":[[338,27]]}}}],["network_netplan_remove_unmanaged_fil",{"_index":5071,"t":{"1089":{"position":[[472,38]]}}}],["network_render",{"_index":5078,"t":{"1089":{"position":[[1003,16],[1622,16]]}}}],["network_trait",{"_index":8864,"t":{"2566":{"position":[[7787,15],[7904,15],[8048,15],[8188,15],[8326,15],[8472,15],[8586,15],[8741,15],[8908,15],[9068,15],[9223,15],[9378,15],[9541,15]]}}}],["network_tunnel",{"_index":5093,"t":{"1089":{"position":[[2058,15]]}}}],["network_tunnels|to_nice_yaml(indent=4)|indent(4",{"_index":5084,"t":{"1089":{"position":[[1227,48]]}}}],["network_typ",{"_index":5063,"t":{"1089":{"position":[[98,13]]},"1096":{"position":[[38,12],[108,13]]},"1098":{"position":[[413,13]]}}}],["network_vers",{"_index":5077,"t":{"1089":{"position":[[971,15],[1501,15]]}}}],["network_vlan",{"_index":5094,"t":{"1089":{"position":[[2167,13]]},"1091":{"position":[[394,14]]}}}],["network_vlans|to_nice_yaml(indent=4)|indent(4",{"_index":5085,"t":{"1089":{"position":[[1289,46]]}}}],["network_vrf",{"_index":5095,"t":{"1089":{"position":[[2272,12]]}}}],["network_vrfs|to_nice_yaml(indent=4)|indent(4",{"_index":5087,"t":{"1089":{"position":[[1348,45]]}}}],["network_workload_interfac",{"_index":7084,"t":{"1585":{"position":[[2166,26],[2438,27]]}}}],["network_zon",{"_index":4175,"t":{"859":{"position":[[601,13],[1731,12]]},"1603":{"position":[[601,13],[1731,12]]}}}],["networkcard",{"_index":7724,"t":{"1829":{"position":[[369,11]]},"1841":{"position":[[395,11]]}}}],["networkd",{"_index":5088,"t":{"1089":{"position":[[1639,8]]}}}],["neutron",{"_index":3665,"t":{"746":{"position":[[214,10]]},"772":{"position":[[32,7],[87,7],[349,7],[428,7],[591,10],[678,7],[969,7],[1021,7]]},"842":{"position":[[114,7],[167,7],[222,7],[278,7],[333,7],[392,7],[451,7],[513,7],[943,7],[1036,7],[1129,7],[1222,7],[1315,7],[1410,7],[1505,7],[1601,7],[1697,7],[1792,7],[1887,7],[1982,7],[2081,7],[2186,7],[2292,7],[2398,7]]},"956":{"position":[[820,7],[1863,7]]},"1067":{"position":[[3684,8]]},"1186":{"position":[[0,7],[20,7],[48,7],[80,7],[105,7],[141,7],[185,7],[233,7],[249,7],[276,7]]},"1188":{"position":[[0,7],[232,7],[464,7]]},"1284":{"position":[[326,7]]},"1294":{"position":[[814,7],[842,7],[862,7]]},"1360":{"position":[[432,7]]},"1362":{"position":[[2068,7]]},"1368":{"position":[[585,8]]},"1557":{"position":[[114,7],[167,7],[222,7],[278,7],[333,7],[392,7],[451,7],[513,7],[943,7],[1036,7],[1129,7],[1222,7],[1315,7],[1410,7],[1505,7],[1601,7],[1697,7],[1792,7],[1887,7],[1982,7],[2081,7],[2186,7],[2292,7],[2398,7]]},"1585":{"position":[[2137,7],[2622,7]]},"1814":{"position":[[420,7]]},"1820":{"position":[[337,7]]},"1822":{"position":[[593,7],[621,7],[652,7]]},"2190":{"position":[[665,8]]},"2292":{"position":[[105,7]]},"3003":{"position":[[97,7],[311,7],[487,7]]},"3007":{"position":[[41,7]]},"3092":{"position":[[415,7]]},"3094":{"position":[[73,7]]},"3099":{"position":[[271,7],[346,7]]},"3119":{"position":[[145,7]]},"3121":{"position":[[31,7]]}}}],["neutron.services.a.regiocloud.tech",{"_index":5775,"t":{"1161":{"position":[[2381,34]]}}}],["neutron_api_work",{"_index":5938,"t":{"1169":{"position":[[1330,19]]}}}],["neutron_availability_zone_hints_network",{"_index":7687,"t":{"1808":{"position":[[910,39]]}}}],["neutron_availability_zone_hints_rout",{"_index":7688,"t":{"1808":{"position":[[950,38]]}}}],["neutron_bridge_nam",{"_index":7085,"t":{"1585":{"position":[[2285,19],[2481,20]]}}}],["neutron_external_interfac",{"_index":4978,"t":{"1067":{"position":[[5112,27]]},"1163":{"position":[[53,26],[434,26]]}}}],["neutron_floatingip",{"_index":7696,"t":{"1808":{"position":[[1185,18]]}}}],["neutron_metadata_work",{"_index":5939,"t":{"1169":{"position":[[1350,24]]}}}],["neutron_ovn_metadata_ag",{"_index":6587,"t":{"1360":{"position":[[1675,26]]},"1362":{"position":[[1449,26]]}}}],["neutron_plugin_ag",{"_index":6145,"t":{"1284":{"position":[[156,20],[334,21],[421,20]]},"1820":{"position":[[167,20],[345,21],[432,20]]}}}],["neutron_public_endpoint",{"_index":5745,"t":{"1161":{"position":[[841,24]]}}}],["neutron_router_enable_snat",{"_index":7689,"t":{"1808":{"position":[[989,26]]}}}],["neutron_server_external_back",{"_index":5776,"t":{"1161":{"position":[[2428,28]]}}}],["neutron_ssh_key",{"_index":8456,"t":{"2288":{"position":[[48,15],[79,16]]}}}],["neutroncli",{"_index":132,"t":{"10":{"position":[[1134,13]]}}}],["never",{"_index":878,"t":{"135":{"position":[[89,5]]},"139":{"position":[[134,5]]},"147":{"position":[[323,5]]},"604":{"position":[[4116,5]]},"790":{"position":[[1034,5]]},"911":{"position":[[526,5],[1125,5]]},"1292":{"position":[[609,5]]},"1395":{"position":[[577,5]]},"1527":{"position":[[1034,5]]},"1633":{"position":[[526,5],[1125,5]]},"1695":{"position":[[89,5]]},"1697":{"position":[[135,5]]},"1701":{"position":[[313,5]]},"1758":{"position":[[47,5]]},"2039":{"position":[[803,5]]},"2358":{"position":[[526,5],[1125,5]]},"2895":{"position":[[1166,5],[1206,5]]}}}],["nevertheless",{"_index":1238,"t":{"176":{"position":[[1078,12]]},"2235":{"position":[[635,13]]},"2468":{"position":[[465,13]]},"2960":{"position":[[1546,12]]},"2966":{"position":[[2361,12],[3354,12]]},"3082":{"position":[[935,12]]},"3126":{"position":[[830,12]]},"3162":{"position":[[277,12]]},"3227":{"position":[[112,13]]},"3236":{"position":[[262,13]]},"3270":{"position":[[665,12]]}}}],["new",{"_index":219,"t":{"18":{"position":[[106,3]]},"58":{"position":[[316,3]]},"79":{"position":[[218,3],[373,3]]},"184":{"position":[[328,3]]},"247":{"position":[[95,3]]},"249":{"position":[[318,3]]},"278":{"position":[[24,3]]},"280":{"position":[[496,4]]},"321":{"position":[[457,3]]},"325":{"position":[[205,3],[7563,3]]},"339":{"position":[[341,3]]},"467":{"position":[[2458,3]]},"471":{"position":[[1063,3],[1444,3]]},"507":{"position":[[478,3]]},"548":{"position":[[200,3]]},"568":{"position":[[126,3]]},"583":{"position":[[192,3],[367,3]]},"598":{"position":[[1541,3]]},"602":{"position":[[131,3]]},"604":{"position":[[1580,3],[1805,3],[2425,3],[3445,3],[3916,3],[4510,3],[4826,3],[6587,3],[6600,3],[7224,3],[7700,3],[8881,3],[9418,3],[9936,3],[10532,3],[10547,3],[10909,4]]},"606":{"position":[[21,3]]},"609":{"position":[[1409,3]]},"627":{"position":[[4350,3]]},"631":{"position":[[768,3]]},"652":{"position":[[851,4],[903,3]]},"656":{"position":[[125,3]]},"662":{"position":[[78,3],[375,5],[888,3]]},"667":{"position":[[18,3],[165,3],[196,3]]},"774":{"position":[[495,3]]},"796":{"position":[[1295,3]]},"798":{"position":[[1214,3],[1265,3]]},"819":{"position":[[3835,3]]},"825":{"position":[[59,3]]},"850":{"position":[[4766,3],[8422,3]]},"903":{"position":[[1557,3],[3855,3]]},"909":{"position":[[648,3]]},"932":{"position":[[1974,3],[2257,4]]},"954":{"position":[[624,3]]},"956":{"position":[[675,3]]},"1043":{"position":[[429,3]]},"1059":{"position":[[154,3],[212,3]]},"1061":{"position":[[146,3]]},"1073":{"position":[[157,3],[207,3]]},"1080":{"position":[[238,3]]},"1112":{"position":[[3751,3],[4739,3]]},"1144":{"position":[[147,3]]},"1217":{"position":[[895,3]]},"1234":{"position":[[987,3]]},"1244":{"position":[[197,3]]},"1290":{"position":[[164,3],[194,3]]},"1292":{"position":[[131,3]]},"1339":{"position":[[70,3]]},"1395":{"position":[[466,3]]},"1397":{"position":[[116,3],[556,3]]},"1462":{"position":[[174,3],[693,3]]},"1466":{"position":[[147,3]]},"1484":{"position":[[4766,3],[8422,3]]},"1509":{"position":[[3835,3]]},"1515":{"position":[[59,3]]},"1533":{"position":[[1295,3]]},"1535":{"position":[[1214,3],[1265,3]]},"1571":{"position":[[553,3]]},"1608":{"position":[[21,3]]},"1610":{"position":[[19,3]]},"1625":{"position":[[1557,3],[3855,3]]},"1631":{"position":[[648,3]]},"1654":{"position":[[1974,3],[2257,4]]},"1674":{"position":[[460,3]]},"1676":{"position":[[435,3]]},"1678":{"position":[[116,3],[263,3],[520,3],[2079,3],[2414,3],[2705,3]]},"1684":{"position":[[238,3],[344,3],[1144,3]]},"1740":{"position":[[293,3]]},"1756":{"position":[[244,3]]},"1766":{"position":[[214,3]]},"1825":{"position":[[383,3]]},"1833":{"position":[[1022,3],[1352,3],[1525,3]]},"1843":{"position":[[387,3]]},"1845":{"position":[[686,3]]},"1855":{"position":[[1216,3]]},"1892":{"position":[[612,3]]},"1900":{"position":[[119,3]]},"1904":{"position":[[233,3]]},"1908":{"position":[[217,3],[443,3],[676,3],[818,3],[1074,3],[1641,3],[2604,3],[2862,3]]},"1917":{"position":[[1216,3]]},"1957":{"position":[[1039,3]]},"1959":{"position":[[1134,3]]},"2008":{"position":[[612,3]]},"2016":{"position":[[119,3]]},"2020":{"position":[[233,3]]},"2024":{"position":[[217,3],[443,3],[676,3],[818,3],[1074,3],[1641,3],[2604,3],[2862,3]]},"2075":{"position":[[622,3]]},"2081":{"position":[[334,3]]},"2083":{"position":[[617,3]]},"2148":{"position":[[536,3]]},"2156":{"position":[[181,3]]},"2162":{"position":[[402,3]]},"2212":{"position":[[414,3]]},"2235":{"position":[[478,4]]},"2245":{"position":[[218,3]]},"2248":{"position":[[1283,3]]},"2259":{"position":[[256,3],[589,3]]},"2261":{"position":[[88,3]]},"2292":{"position":[[707,3],[1055,3]]},"2310":{"position":[[698,3]]},"2312":{"position":[[378,3],[669,3]]},"2317":{"position":[[50,3]]},"2324":{"position":[[912,3]]},"2350":{"position":[[1557,3],[3855,3]]},"2356":{"position":[[648,3]]},"2379":{"position":[[1974,3],[2257,4]]},"2409":{"position":[[299,3]]},"2413":{"position":[[189,3]]},"2426":{"position":[[2,3],[104,3],[217,3]]},"2456":{"position":[[318,3]]},"2468":{"position":[[397,3],[608,3]]},"2476":{"position":[[37,3]]},"2504":{"position":[[791,3]]},"2574":{"position":[[638,3]]},"2623":{"position":[[442,3]]},"2631":{"position":[[14,3],[41,3],[2114,3],[2351,3],[2385,3]]},"2635":{"position":[[640,3],[660,3]]},"2688":{"position":[[1664,3]]},"2705":{"position":[[795,3]]},"2750":{"position":[[810,3]]},"2801":{"position":[[335,3]]},"2840":{"position":[[700,3]]},"2895":{"position":[[303,3],[335,3],[2420,3],[2773,3],[4472,3]]},"2944":{"position":[[1538,3]]},"2949":{"position":[[4,3],[526,3],[1143,3]]},"2951":{"position":[[898,3]]},"2990":{"position":[[192,3],[429,3],[558,3]]},"2992":{"position":[[469,3]]},"3011":{"position":[[1242,3]]},"3014":{"position":[[435,3]]},"3069":{"position":[[265,3]]},"3084":{"position":[[83,3]]},"3124":{"position":[[228,3]]},"3126":{"position":[[248,3],[554,3],[757,3]]},"3128":{"position":[[166,3],[601,3],[663,3]]},"3169":{"position":[[245,3],[382,3]]},"3227":{"position":[[57,3]]},"3251":{"position":[[2204,3],[2266,3],[2385,3]]},"3301":{"position":[[3933,3],[3967,3]]},"3308":{"position":[[643,3]]},"3310":{"position":[[178,3]]},"3314":{"position":[[1952,3]]},"3316":{"position":[[332,3]]},"3319":{"position":[[26,3]]},"3325":{"position":[[289,3],[1304,3],[1438,3],[1657,3],[2731,3]]},"3351":{"position":[[184,3]]},"3361":{"position":[[31,3],[80,3],[166,3],[257,3]]},"3363":{"position":[[189,3]]},"3446":{"position":[[200,3]]},"3453":{"position":[[395,3]]},"3457":{"position":[[90,3],[498,3],[738,3]]},"3459":{"position":[[665,3]]},"3463":{"position":[[314,3]]},"3465":{"position":[[877,3],[953,3],[1326,3],[1387,3]]},"3472":{"position":[[12979,3]]},"3482":{"position":[[641,3]]},"3518":{"position":[[2269,3]]}}}],["newcom",{"_index":453,"t":{"58":{"position":[[69,9]]}}}],["newer",{"_index":3154,"t":{"604":{"position":[[10756,5]]},"796":{"position":[[1148,5]]},"932":{"position":[[2376,6]]},"1462":{"position":[[738,5]]},"1533":{"position":[[1148,5]]},"1654":{"position":[[2376,6]]},"1829":{"position":[[309,5]]},"2379":{"position":[[2376,6]]},"2895":{"position":[[3709,5]]},"3126":{"position":[[198,5],[1036,5]]},"3251":{"position":[[3112,5]]},"3274":{"position":[[327,5]]}}}],["newest",{"_index":3215,"t":{"609":{"position":[[589,6]]},"2809":{"position":[[850,6]]},"3314":{"position":[[3023,6]]}}}],["newli",{"_index":2940,"t":{"513":{"position":[[1553,5]]},"667":{"position":[[469,5]]},"903":{"position":[[4002,5]]},"1625":{"position":[[4002,5]]},"1745":{"position":[[760,5]]},"2116":{"position":[[213,5]]},"2350":{"position":[[4002,5]]},"2514":{"position":[[215,5]]},"3074":{"position":[[302,5]]},"3107":{"position":[[159,5]]}}}],["newslett",{"_index":1381,"t":{"193":{"position":[[224,10],[395,10]]},"202":{"position":[[401,11]]},"210":{"position":[[437,11]]},"214":{"position":[[250,11]]}}}],["next",{"_index":1307,"t":{"178":{"position":[[2713,4]]},"187":{"position":[[682,4]]},"263":{"position":[[531,4]]},"321":{"position":[[712,4]]},"383":{"position":[[142,5]]},"462":{"position":[[502,4]]},"530":{"position":[[416,5]]},"548":{"position":[[170,4]]},"604":{"position":[[2569,4],[3856,4]]},"654":{"position":[[743,4]]},"656":{"position":[[174,4],[421,4]]},"667":{"position":[[721,4]]},"1234":{"position":[[857,4]]},"1674":{"position":[[700,4]]},"1678":{"position":[[1751,4],[1892,4],[2245,4]]},"1783":{"position":[[584,4]]},"1913":{"position":[[592,5]]},"2029":{"position":[[592,5]]},"2053":{"position":[[1033,5]]},"2096":{"position":[[1729,4]]},"2196":{"position":[[172,4],[823,4],[1321,4]]},"2259":{"position":[[306,4]]},"2292":{"position":[[366,4],[1105,4]]},"2330":{"position":[[933,4]]},"2407":{"position":[[141,4]]},"2472":{"position":[[332,4]]},"2486":{"position":[[575,4]]},"2489":{"position":[[207,4]]},"2504":{"position":[[740,4],[840,4]]},"2631":{"position":[[1041,4]]},"2705":{"position":[[0,4]]},"2750":{"position":[[0,4]]},"2813":{"position":[[412,4]]},"2992":{"position":[[248,4]]},"3301":{"position":[[7242,4]]},"3472":{"position":[[349,4]]}}}],["nextcloud",{"_index":1188,"t":{"172":{"position":[[826,9]]},"261":{"position":[[142,9]]},"263":{"position":[[10,9],[346,9],[383,9]]}}}],["nexu",{"_index":7580,"t":{"1787":{"position":[[597,5]]},"1789":{"position":[[1221,5]]},"2248":{"position":[[1349,6],[1405,6]]},"3299":{"position":[[5236,5],[5242,5]]}}}],["nexus.testbed.osism.xyz",{"_index":7579,"t":{"1787":{"position":[[573,23]]}}}],["nf",{"_index":4672,"t":{"977":{"position":[[1685,5]]},"1831":{"position":[[305,3]]},"1841":{"position":[[356,3]]}}}],["nfs_group_nam",{"_index":5383,"t":{"1120":{"position":[[1523,15]]}}}],["nginx",{"_index":2155,"t":{"335":{"position":[[1083,5]]},"379":{"position":[[161,5]]},"409":{"position":[[175,5]]},"413":{"position":[[94,5],[196,5],[255,5],[355,5]]},"436":{"position":[[259,6],[281,5],[638,5],[828,5],[893,5],[907,5],[1321,5],[1385,5]]},"442":{"position":[[13,5],[115,5],[174,5],[274,5]]},"487":{"position":[[4218,5],[4434,5],[5707,5]]},"503":{"position":[[15,5],[294,5],[337,5],[462,5],[816,5]]},"505":{"position":[[423,5],[652,5],[927,5],[1296,5]]},"507":{"position":[[28,5]]},"513":{"position":[[1952,5]]},"604":{"position":[[6478,5],[6572,5],[6675,5],[6709,5],[6784,5],[6817,5],[7661,5],[9371,5],[10123,5],[11725,5]]},"609":{"position":[[2429,5],[5284,5]]},"613":{"position":[[0,6]]},"627":{"position":[[1388,5],[2468,5],[3907,5]]},"631":{"position":[[723,5]]},"635":{"position":[[3693,5],[3802,5]]},"641":{"position":[[1047,5]]},"646":{"position":[[281,5],[374,5],[508,5],[1859,5],[1881,5]]},"2245":{"position":[[372,5]]},"2263":{"position":[[4,5]]},"2315":{"position":[[1599,5]]},"2405":{"position":[[235,5]]}}}],["nginx.ingress.kubernetes.io/limit",{"_index":2503,"t":{"436":{"position":[[364,33],[1127,33]]}}}],["nginx/examples/auth/oauth",{"_index":8222,"t":{"2110":{"position":[[133,25]]}}}],["nginx_ingress_proxi",{"_index":2810,"t":{"487":{"position":[[4381,19]]},"604":{"position":[[5898,19]]}}}],["nginx_use_proxi",{"_index":2914,"t":{"505":{"position":[[1249,16]]}}}],["nic",{"_index":4691,"t":{"982":{"position":[[693,3]]},"984":{"position":[[560,3]]},"986":{"position":[[299,3]]},"988":{"position":[[419,3]]},"990":{"position":[[461,3]]},"1833":{"position":[[1289,3]]},"1845":{"position":[[1583,3],[1602,4],[2674,3]]},"2403":{"position":[[366,3]]}}}],["nice",{"_index":1486,"t":{"212":{"position":[[256,4]]},"600":{"position":[[1136,6]]},"911":{"position":[[1731,7]]},"1633":{"position":[[1731,7]]},"2226":{"position":[[216,6]]},"2358":{"position":[[1731,7]]},"2407":{"position":[[338,6]]},"2947":{"position":[[2630,10]]},"2964":{"position":[[215,4]]},"3301":{"position":[[1101,4]]},"3314":{"position":[[237,4]]}}}],["nightli",{"_index":8599,"t":{"2520":{"position":[[43,7]]},"2688":{"position":[[494,8]]}}}],["nip.io",{"_index":3470,"t":{"646":{"position":[[1801,6]]}}}],["nl/v/t/c[i",{"_index":9115,"t":{"2702":{"position":[[75,11]]},"2747":{"position":[[75,11]]}}}],["nn",{"_index":3212,"t":{"609":{"position":[[501,2]]}}}],["no1",{"_index":3018,"t":{"590":{"position":[[1676,3],[1740,3],[1784,3]]},"660":{"position":[[2809,3],[2851,4]]}}}],["no_proxi",{"_index":2722,"t":{"485":{"position":[[1065,8],[1225,8],[1447,8]]}}}],["noassign",{"_index":3821,"t":{"819":{"position":[[703,8],[2544,8]]},"821":{"position":[[663,8],[1777,8]]},"1509":{"position":[[703,8],[2544,8]]},"1511":{"position":[[663,8],[1777,8]]}}}],["nobackfil",{"_index":6896,"t":{"1434":{"position":[[57,10]]},"1471":{"position":[[413,10]]},"1473":{"position":[[1091,10]]}}}],["nobl",{"_index":4141,"t":{"850":{"position":[[8131,5]]},"1484":{"position":[[8131,5]]}}}],["nocleanup",{"_index":4176,"t":{"859":{"position":[[618,10],[1779,9]]},"1603":{"position":[[618,10],[1779,9]]}}}],["nocreat",{"_index":3822,"t":{"819":{"position":[[727,8],[751,8],[771,8],[2601,8],[2658,8],[2707,8]]},"1509":{"position":[[727,8],[751,8],[771,8],[2601,8],[2658,8],[2707,8]]}}}],["node",{"_index":985,"t":{"158":{"position":[[49,4],[843,5],[1007,4]]},"325":{"position":[[528,5],[768,6],[1542,5],[7743,6]]},"363":{"position":[[253,4]]},"396":{"position":[[237,4]]},"427":{"position":[[695,4]]},"447":{"position":[[180,4]]},"449":{"position":[[281,4]]},"471":{"position":[[1763,4]]},"483":{"position":[[217,4]]},"485":{"position":[[590,6],[739,4]]},"487":{"position":[[184,5],[858,6],[1308,5],[1425,5],[1522,5],[1604,5],[1721,4],[1830,5],[1902,4],[2038,6],[2168,6],[2321,5],[3018,5],[4106,5]]},"495":{"position":[[380,5],[1267,5]]},"503":{"position":[[279,4],[531,4],[604,4]]},"505":{"position":[[261,5],[338,5]]},"513":{"position":[[1241,4],[1568,4],[1715,4]]},"521":{"position":[[263,4],[514,5]]},"552":{"position":[[661,5]]},"588":{"position":[[223,5]]},"590":{"position":[[2166,6],[2700,6]]},"592":{"position":[[122,6],[187,5]]},"596":{"position":[[1239,4],[1260,4],[1383,5],[2151,5],[2269,5],[2780,5],[2936,4]]},"604":{"position":[[9777,4],[9800,5],[9885,4]]},"609":{"position":[[275,4],[811,5],[884,4],[920,4],[1156,5],[1836,4],[2924,4],[2947,5],[3596,4],[3619,5],[4638,4],[5687,5],[6053,5]]},"615":{"position":[[41,6],[559,5]]},"627":{"position":[[1244,5],[1261,6],[1929,5],[2990,5],[5164,4]]},"631":{"position":[[608,4]]},"633":{"position":[[1381,4],[1637,4]]},"635":{"position":[[583,6],[3372,6],[3514,5]]},"648":{"position":[[134,5]]},"650":{"position":[[883,6],[1597,6],[2440,5]]},"652":{"position":[[1170,5]]},"654":{"position":[[60,5],[93,5]]},"740":{"position":[[63,6]]},"742":{"position":[[57,5],[489,5],[842,6]]},"744":{"position":[[400,5],[638,6],[821,6]]},"746":{"position":[[66,6],[289,5],[338,6]]},"748":{"position":[[12,4],[93,6],[298,4],[405,4]]},"758":{"position":[[134,5]]},"770":{"position":[[193,6]]},"833":{"position":[[40,4],[63,4]]},"835":{"position":[[36,4],[59,4]]},"874":{"position":[[8,5],[22,5],[36,5],[50,5],[64,5]]},"876":{"position":[[137,5]]},"907":{"position":[[209,4]]},"956":{"position":[[1621,5],[1916,6],[2043,5]]},"977":{"position":[[1508,5]]},"982":{"position":[[10,4],[142,5],[250,5],[351,5],[479,6]]},"984":{"position":[[8,5]]},"986":{"position":[[20,4],[357,6]]},"988":{"position":[[20,4],[155,6]]},"990":{"position":[[12,5],[43,4],[62,5]]},"995":{"position":[[72,6],[119,6],[329,5],[399,5],[457,6],[657,4],[701,4],[722,5]]},"1012":{"position":[[92,5],[352,5],[446,5]]},"1014":{"position":[[74,4]]},"1023":{"position":[[91,5]]},"1025":{"position":[[77,4]]},"1031":{"position":[[106,5],[859,5]]},"1033":{"position":[[86,5]]},"1039":{"position":[[75,4],[320,4],[344,4],[473,4],[497,4],[626,4],[650,4]]},"1041":{"position":[[58,5]]},"1043":{"position":[[89,5]]},"1047":{"position":[[192,4]]},"1052":{"position":[[283,6]]},"1055":{"position":[[1513,4],[1633,4],[1698,5],[1846,5],[2070,4],[2107,4],[2214,4],[2247,4]]},"1059":{"position":[[291,5]]},"1065":{"position":[[811,4]]},"1067":{"position":[[930,4],[999,4],[1084,4],[1199,4],[1245,4],[1322,4],[1651,4],[1696,5],[1788,6],[2432,5],[2703,4],[2818,4],[2864,4],[3021,5],[3106,5],[3161,5],[3251,5],[3370,5],[3580,5],[3735,6],[3862,5],[4259,4],[4573,4],[5287,4],[5425,4],[5446,5]]},"1075":{"position":[[114,5],[280,5]]},"1084":{"position":[[255,5]]},"1089":{"position":[[2707,6],[2756,4]]},"1098":{"position":[[28,5],[92,4]]},"1106":{"position":[[512,6]]},"1108":{"position":[[1592,5],[1717,5],[1923,5],[2078,7]]},"1112":{"position":[[377,4],[3783,4],[3817,4],[3965,5]]},"1114":{"position":[[152,5],[761,4],[789,4],[1006,4],[2076,5],[4016,5],[4363,4],[4391,4],[4608,4],[5519,5]]},"1120":{"position":[[1032,5],[1829,4],[1862,4],[1895,4]]},"1124":{"position":[[36,5],[673,5],[841,5],[852,4],[922,6],[990,5],[1030,5],[1042,4],[1165,4],[1188,4],[1211,4],[1344,4],[1367,4],[1390,4],[1406,4]]},"1165":{"position":[[1514,4]]},"1178":{"position":[[52,4],[131,5]]},"1184":{"position":[[60,4],[73,4],[317,5],[693,4],[706,4],[805,4],[843,4],[957,4],[1013,4],[1090,4],[1163,4],[1742,4],[2067,4],[2324,5],[2433,4]]},"1199":{"position":[[111,5],[153,5],[315,4],[346,5],[370,5]]},"1209":{"position":[[88,5]]},"1213":{"position":[[337,5],[426,6]]},"1219":{"position":[[312,4],[352,4],[396,5],[438,5]]},"1224":{"position":[[43,5],[74,4],[114,4],[210,5],[363,5],[509,6],[565,6],[615,5],[1075,5],[2496,6],[2645,6],[3940,5],[4035,5]]},"1226":{"position":[[85,5]]},"1232":{"position":[[87,5],[199,5],[351,5],[488,5]]},"1234":{"position":[[907,4],[1736,6],[2034,4],[2261,6],[2586,4],[2682,4]]},"1236":{"position":[[192,4],[251,5],[266,4],[359,4],[383,4],[494,4],[552,4],[591,4],[753,4],[907,5]]},"1240":{"position":[[551,5]]},"1244":{"position":[[85,6],[113,5]]},"1246":{"position":[[73,6]]},"1252":{"position":[[48,4],[63,5],[81,4],[178,4],[464,5],[633,4],[895,4],[1174,4],[1357,4]]},"1254":{"position":[[91,5],[124,4],[183,5]]},"1256":{"position":[[37,5],[163,6],[194,4],[367,5],[1500,5],[1591,5],[1636,4],[1962,5]]},"1258":{"position":[[418,4],[593,4],[870,6]]},"1260":{"position":[[390,5],[434,5]]},"1264":{"position":[[65,5],[106,4],[279,6],[295,4]]},"1267":{"position":[[2,4],[135,4],[198,4]]},"1269":{"position":[[22,4],[51,4]]},"1271":{"position":[[20,4],[47,4]]},"1273":{"position":[[168,5]]},"1279":{"position":[[28,4],[121,4],[168,4],[181,4],[364,4],[396,4],[409,4],[533,4]]},"1290":{"position":[[206,4]]},"1292":{"position":[[241,5],[502,5],[559,4],[706,5]]},"1298":{"position":[[259,5]]},"1317":{"position":[[8079,4],[8278,4],[8377,4],[8928,4]]},"1319":{"position":[[30,4]]},"1321":{"position":[[126,4],[201,4],[399,4],[563,4],[783,4],[858,4],[1013,4],[1098,4],[1251,4],[1451,4],[2150,4]]},"1325":{"position":[[190,4],[227,4],[264,4],[726,4],[763,4],[800,4]]},"1327":{"position":[[32,4],[128,4]]},"1329":{"position":[[28,4],[117,4]]},"1333":{"position":[[66,4],[153,4],[186,4],[297,4],[347,4]]},"1335":{"position":[[183,6],[198,4]]},"1337":{"position":[[74,4],[116,4],[468,4]]},"1339":{"position":[[54,4],[150,4],[267,4]]},"1347":{"position":[[363,4],[456,4],[549,4],[639,4],[733,4],[827,4],[1090,4],[1141,4],[1243,4],[1294,4],[1396,4],[1447,4],[1832,4],[1925,4],[2018,4]]},"1358":{"position":[[50,4],[160,4],[202,4],[229,4],[276,4],[397,4],[492,4]]},"1360":{"position":[[55,4],[103,4],[198,4],[273,4],[304,4],[335,4],[391,4],[415,4],[443,4],[502,5],[552,4],[620,4],[682,4],[699,4],[888,4],[974,5],[2150,4]]},"1362":{"position":[[51,4],[205,4],[296,4],[406,4],[480,4],[721,4],[1096,4],[1423,4],[1631,4],[2048,4],[2099,4],[2129,4],[2442,4],[2608,4],[2692,4]]},"1366":{"position":[[93,4]]},"1368":{"position":[[735,4],[831,4],[927,4],[1088,4],[1113,4],[1214,4],[1239,4],[1340,4],[1365,4]]},"1371":{"position":[[69,4]]},"1373":{"position":[[85,4]]},"1375":{"position":[[91,4],[726,4],[1075,4],[1537,4]]},"1377":{"position":[[92,4],[727,4],[1096,4],[1731,4]]},"1388":{"position":[[155,5],[220,6]]},"1400":{"position":[[536,4]]},"1406":{"position":[[114,4]]},"1428":{"position":[[29,6],[101,4]]},"1430":{"position":[[20,4],[139,4],[248,4],[357,4],[482,4],[932,4],[1041,4],[1144,4],[1278,5],[1575,4],[1684,4],[1787,4],[1805,4],[1862,4],[1902,4],[1936,4],[2042,4]]},"1462":{"position":[[178,5]]},"1469":{"position":[[417,4]]},"1471":{"position":[[154,5],[564,5],[583,5],[707,5],[1036,5],[1059,5],[1166,5],[1296,5],[1319,5],[1426,5],[1556,5],[1579,5],[1689,4],[1925,5],[1948,5],[2055,5]]},"1473":{"position":[[325,5],[348,5],[452,5],[475,5],[507,4],[607,4],[677,5],[700,5],[1442,4],[1692,4]]},"1548":{"position":[[40,4],[63,4]]},"1550":{"position":[[36,4],[59,4]]},"1564":{"position":[[376,5]]},"1591":{"position":[[158,4]]},"1629":{"position":[[209,4]]},"1728":{"position":[[959,4],[1226,5],[1557,4]]},"1734":{"position":[[106,4],[386,4],[399,4],[431,4],[447,4],[501,4]]},"1738":{"position":[[367,4]]},"1745":{"position":[[892,6],[1041,5]]},"1758":{"position":[[352,4]]},"1764":{"position":[[4217,5],[4235,6]]},"1768":{"position":[[138,5],[159,5]]},"1779":{"position":[[3229,6],[3507,5],[3567,4]]},"1787":{"position":[[725,4],[758,4],[787,4],[820,4],[849,4],[882,4],[911,4],[944,4],[973,4],[1006,4],[1035,4],[1068,4],[1097,4],[1130,4],[1159,4],[1192,4],[1221,4],[1254,4],[1283,4],[1316,4]]},"1789":{"position":[[531,4],[554,4],[620,4],[643,4],[709,4],[732,4]]},"1794":{"position":[[1151,4]]},"1825":{"position":[[2103,5],[2177,5],[2527,4]]},"1941":{"position":[[34,5]]},"1980":{"position":[[127,4]]},"2093":{"position":[[391,6]]},"2100":{"position":[[960,5],[991,4],[1249,4]]},"2106":{"position":[[461,4],[540,4],[573,5],[582,4]]},"2200":{"position":[[64,4]]},"2245":{"position":[[409,5],[495,4]]},"2248":{"position":[[23,4],[294,4],[466,5]]},"2250":{"position":[[69,4]]},"2253":{"position":[[327,5],[461,5]]},"2263":{"position":[[142,6]]},"2312":{"position":[[289,4]]},"2354":{"position":[[209,4]]},"2405":{"position":[[363,4]]},"2461":{"position":[[215,4],[1049,4],[1124,4]]},"2504":{"position":[[402,4]]},"2540":{"position":[[294,5]]},"2592":{"position":[[724,5],[773,4]]},"2709":{"position":[[721,4]]},"2754":{"position":[[721,4]]},"2844":{"position":[[649,4]]},"2883":{"position":[[8,5],[199,5]]},"2944":{"position":[[1034,5],[1122,5]]},"2947":{"position":[[4,4],[80,5],[119,5],[163,4],[348,4],[514,4],[548,4],[604,4],[765,4],[965,4],[1115,5],[1169,5],[1307,5],[2143,5],[4323,4],[4387,4],[4433,4],[4488,6],[4604,4],[5415,4]]},"2949":{"position":[[156,5]]},"2951":{"position":[[9,5]]},"2960":{"position":[[1089,4]]},"2966":{"position":[[1233,6],[2778,4]]},"3007":{"position":[[148,6],[251,6]]},"3044":{"position":[[138,4]]},"3069":{"position":[[58,5]]},"3141":{"position":[[197,4],[273,4]]},"3178":{"position":[[102,6],[174,5],[217,5]]},"3182":{"position":[[132,5],[268,5],[342,5],[489,4],[507,4],[621,6],[731,6],[1015,5],[1074,4],[1204,5],[1820,6],[1970,5]]},"3184":{"position":[[477,6],[500,5],[864,4],[1351,5],[1476,5],[1580,6],[2007,5],[2203,5],[2332,5],[2518,6],[2596,5],[2957,5],[3059,5],[3088,5]]},"3186":{"position":[[298,4],[533,4],[1077,5],[1198,5],[1461,5]]},"3191":{"position":[[95,6],[167,5],[210,5],[438,5],[510,5]]},"3197":{"position":[[101,5]]},"3199":{"position":[[76,5],[460,5],[769,5],[880,4],[929,5],[1007,4]]},"3201":{"position":[[15,4],[53,5],[233,4],[307,5]]},"3218":{"position":[[997,4]]},"3236":{"position":[[1370,6]]},"3393":{"position":[[399,4]]},"3395":{"position":[[1590,7]]},"3400":{"position":[[339,5],[673,6],[1026,4],[1235,4]]},"3431":{"position":[[358,4]]},"3518":{"position":[[1775,5],[1829,4]]}}}],["node'",{"_index":3040,"t":{"596":{"position":[[224,6]]}}}],["node.data",{"_index":5874,"t":{"1167":{"position":[[1477,10],[3117,10]]}}}],["node.j",{"_index":982,"t":{"155":{"position":[[4,7]]},"158":{"position":[[29,7],[124,7],[898,7]]},"2675":{"position":[[943,7]]},"3160":{"position":[[2409,8]]}}}],["node.mast",{"_index":5873,"t":{"1167":{"position":[[1459,12],[2355,12],[2463,12],[2582,12],[3133,12]]}}}],["node.nam",{"_index":5865,"t":{"1167":{"position":[[1112,10],[3151,10]]}}}],["node.systems.osism.xyz",{"_index":6065,"t":{"1234":{"position":[[932,23]]}}}],["node01",{"_index":4951,"t":{"1067":{"position":[[1089,6],[1593,6],[2708,6],[3065,6],[3207,6]]}}}],["node_cidr",{"_index":2725,"t":{"487":{"position":[[100,9],[110,9]]},"660":{"position":[[2192,9],[2209,12]]}}}],["node_config_directori",{"_index":5853,"t":{"1167":{"position":[[584,21]]}}}],["node_custom_config",{"_index":5850,"t":{"1167":{"position":[[401,18],[445,18],[500,18]]}}}],["node_ips=$(kubectl",{"_index":8204,"t":{"2106":{"position":[[550,18]]}}}],["nodeaffin",{"_index":9905,"t":{"3182":{"position":[[835,12]]}}}],["nodebug",{"_index":4177,"t":{"859":{"position":[[632,8],[1816,7]]},"1603":{"position":[[632,8],[1816,7]]}}}],["nodeep",{"_index":6833,"t":{"1404":{"position":[[38,6],[93,6]]}}}],["nodeimag",{"_index":2347,"t":{"396":{"position":[[186,10]]}}}],["nodelet",{"_index":4178,"t":{"859":{"position":[[644,9],[1849,8]]},"1603":{"position":[[644,9],[1849,8]]}}}],["nodenam",{"_index":5231,"t":{"1112":{"position":[[3828,10]]}}}],["nodepool",{"_index":7391,"t":{"1745":{"position":[[698,9],[729,8],[788,8],[930,8],[1006,8]]},"1749":{"position":[[1666,8]]},"2158":{"position":[[571,8]]}}}],["nodepool.pub",{"_index":7394,"t":{"1745":{"position":[[970,13]]},"1749":{"position":[[529,15]]}}}],["nodeport",{"_index":9974,"t":{"3236":{"position":[[889,8]]}}}],["nodes/disk",{"_index":8253,"t":{"2118":{"position":[[1660,10]]}}}],["nodes_boot_from_imag",{"_index":7690,"t":{"1808":{"position":[[1016,21]]}}}],["nodes_boot_from_volum",{"_index":7691,"t":{"1808":{"position":[[1038,22]]}}}],["nodes_use_ephemeral_storag",{"_index":7692,"t":{"1808":{"position":[[1061,27]]}}}],["nodeselector",{"_index":9903,"t":{"3182":{"position":[[782,13]]}}}],["nodeset",{"_index":2042,"t":{"325":{"position":[[541,8],[759,8],[1529,8]]},"1678":{"position":[[1826,8],[1982,8]]}}}],["nodomain",{"_index":3823,"t":{"819":{"position":[[789,8],[2752,8]]},"1509":{"position":[[789,8],[2752,8]]}}}],["nodown",{"_index":6938,"t":{"1471":{"position":[[491,6]]},"1473":{"position":[[1044,6]]}}}],["nodri",{"_index":3875,"t":{"821":{"position":[[687,5],[1834,5]]},"1511":{"position":[[687,5],[1834,5]]}}}],["nofloat",{"_index":4179,"t":{"859":{"position":[[657,11],[1884,10]]},"1603":{"position":[[657,11],[1884,10]]}}}],["noha",{"_index":3824,"t":{"819":{"position":[[814,5],[839,5],[865,5],[2811,5],[2870,5],[2931,5]]},"1509":{"position":[[814,5],[839,5],[865,5],[2811,5],[2870,5],[2931,5]]}}}],["nomanag",{"_index":3825,"t":{"819":{"position":[[889,9],[2988,9]]},"821":{"position":[[701,8],[724,8],[1871,8],[1926,8]]},"1509":{"position":[[889,9],[2988,9]]},"1511":{"position":[[701,8],[724,8],[1871,8],[1926,8]]}}}],["non",{"_index":239,"t":{"23":{"position":[[38,3]]},"172":{"position":[[727,3]]},"174":{"position":[[155,4],[1386,3]]},"245":{"position":[[468,3]]},"280":{"position":[[155,3]]},"288":{"position":[[261,3]]},"317":{"position":[[944,3]]},"370":{"position":[[79,3],[435,3],[514,3]]},"374":{"position":[[546,3]]},"379":{"position":[[1068,3]]},"596":{"position":[[862,3],[1526,3],[2711,3]]},"669":{"position":[[842,3]]},"752":{"position":[[122,3]]},"1224":{"position":[[3583,4]]},"1226":{"position":[[549,3]]},"1721":{"position":[[3906,4]]},"1787":{"position":[[226,3]]},"1902":{"position":[[287,3]]},"1908":{"position":[[377,3],[1604,3]]},"2018":{"position":[[287,3]]},"2024":{"position":[[377,3],[1604,3]]},"2118":{"position":[[1631,3]]},"2122":{"position":[[165,3]]},"2235":{"position":[[314,3]]},"2239":{"position":[[79,3]]},"2283":{"position":[[455,3]]},"2506":{"position":[[151,3]]},"2635":{"position":[[535,3]]},"2642":{"position":[[150,3]]},"2647":{"position":[[1204,3]]},"2688":{"position":[[737,3]]},"2713":{"position":[[1115,3]]},"2723":{"position":[[326,3]]},"2731":{"position":[[515,3]]},"2756":{"position":[[832,3]]},"2762":{"position":[[339,3]]},"2770":{"position":[[515,3]]},"2786":{"position":[[408,3]]},"2848":{"position":[[326,3]]},"2858":{"position":[[925,3]]},"2860":{"position":[[477,3]]},"2890":{"position":[[264,3]]},"2895":{"position":[[3208,3]]},"2935":{"position":[[454,3]]},"2990":{"position":[[165,3]]},"2992":{"position":[[227,3]]},"2994":{"position":[[474,3]]},"3021":{"position":[[388,3]]},"3025":{"position":[[279,3]]},"3059":{"position":[[932,3]]},"3061":{"position":[[913,3]]},"3132":{"position":[[488,3]]},"3186":{"position":[[861,3]]},"3301":{"position":[[6518,4],[6645,3],[6660,3]]},"3325":{"position":[[1879,3]]},"3353":{"position":[[130,3]]},"3378":{"position":[[1089,3]]},"3397":{"position":[[1026,3]]},"3463":{"position":[[388,3],[660,4]]}}}],["none",{"_index":2425,"t":{"413":{"position":[[406,6]]},"442":{"position":[[325,6]]},"467":{"position":[[1728,4]]},"487":{"position":[[3424,6]]},"641":{"position":[[1709,6]]},"730":{"position":[[2071,4],[2094,4]]},"790":{"position":[[1055,4],[1076,4]]},"819":{"position":[[2031,5]]},"821":{"position":[[1483,5]]},"850":{"position":[[369,5],[458,5],[9449,4]]},"859":{"position":[[1549,5]]},"1150":{"position":[[12932,4]]},"1234":{"position":[[3,4]]},"1377":{"position":[[790,4],[1792,4]]},"1484":{"position":[[369,5],[458,5],[9449,4]]},"1491":{"position":[[2071,4],[2094,4]]},"1509":{"position":[[2031,5]]},"1511":{"position":[[1483,5]]},"1527":{"position":[[1055,4],[1076,4]]},"1603":{"position":[[1549,5]]},"1833":{"position":[[426,4]]},"1847":{"position":[[1353,4],[1537,4]]},"2176":{"position":[[1177,4]]},"2764":{"position":[[254,6]]},"2788":{"position":[[0,4]]},"2895":{"position":[[3271,5],[3612,4]]},"2899":{"position":[[672,4]]},"2917":{"position":[[0,5]]},"3042":{"position":[[806,4],[980,4]]},"3046":{"position":[[656,4],[963,4]]},"3088":{"position":[[791,4],[823,4],[830,4],[915,4],[952,4],[959,4],[1044,4],[1091,4],[1177,4],[1219,4]]},"3107":{"position":[[887,4],[919,4],[926,4],[1011,4],[1053,4],[1139,4],[1176,4],[1183,4],[1268,4],[1315,4]]},"3386":{"position":[[0,4]]},"3421":{"position":[[0,5]]},"3427":{"position":[[0,5]]},"3450":{"position":[[0,4]]}}}],["none:%(target.role.domain_id)",{"_index":5534,"t":{"1150":{"position":[[3003,32],[3963,32],[4480,32]]},"3472":{"position":[[2846,32],[3806,32],[4323,32]]}}}],["nonlead",{"_index":3065,"t":{"596":{"position":[[2663,9],[3068,10]]}}}],["nonneg",{"_index":9588,"t":{"2923":{"position":[[609,11]]}}}],["nonono",{"_index":2779,"t":{"487":{"position":[[2416,6],[2515,6]]}}}],["nonsens",{"_index":9932,"t":{"3206":{"position":[[680,11]]}}}],["noop",{"_index":2056,"t":{"325":{"position":[[1355,4]]}}}],["noout",{"_index":6838,"t":{"1406":{"position":[[52,5],[171,5],[239,5],[424,5],[454,5],[476,5],[505,5],[524,5],[609,5],[642,5],[687,5]]},"1471":{"position":[[392,5]]},"1473":{"position":[[1068,5]]}}}],["nopasswd",{"_index":6017,"t":{"1224":{"position":[[1591,9]]}}}],["noqa",{"_index":913,"t":{"141":{"position":[[306,4]]},"151":{"position":[[163,5]]}}}],["norandom",{"_index":3826,"t":{"819":{"position":[[921,9],[3061,8]]},"1509":{"position":[[921,9],[3061,8]]}}}],["norebal",{"_index":6898,"t":{"1434":{"position":[[109,11]]},"1471":{"position":[[464,11]]},"1473":{"position":[[1146,11]]}}}],["norecov",{"_index":6937,"t":{"1471":{"position":[[439,9]]},"1473":{"position":[[1119,9]]}}}],["norecoveri",{"_index":6897,"t":{"1434":{"position":[[83,10]]}}}],["nori",{"_index":7517,"t":{"1773":{"position":[[716,5]]},"2520":{"position":[[397,5]]}}}],["noris/wavecon",{"_index":8510,"t":{"2330":{"position":[[761,13]]}}}],["norm",{"_index":8981,"t":{"2592":{"position":[[84,5]]},"2631":{"position":[[2470,9]]},"2633":{"position":[[101,9]]},"2639":{"position":[[34,9]]}}}],["normal",{"_index":2570,"t":{"460":{"position":[[358,8]]},"588":{"position":[[52,9]]},"600":{"position":[[490,6]]},"604":{"position":[[70,6],[120,6],[1544,8]]},"609":{"position":[[729,6]]},"784":{"position":[[154,6]]},"901":{"position":[[250,6],[358,6]]},"911":{"position":[[1318,8]]},"945":{"position":[[46,6]]},"949":{"position":[[250,6]]},"988":{"position":[[61,8]]},"1055":{"position":[[1146,6]]},"1080":{"position":[[981,8]]},"1094":{"position":[[84,6]]},"1120":{"position":[[634,6]]},"1388":{"position":[[187,8]]},"1473":{"position":[[1381,6]]},"1521":{"position":[[154,6]]},"1623":{"position":[[250,6],[358,6]]},"1633":{"position":[[1318,8]]},"1667":{"position":[[46,6]]},"1671":{"position":[[250,6]]},"1684":{"position":[[3076,6]]},"1825":{"position":[[1144,8]]},"1957":{"position":[[4370,6]]},"2330":{"position":[[536,7]]},"2348":{"position":[[250,6],[358,6]]},"2358":{"position":[[1318,8]]},"2392":{"position":[[46,6]]},"2396":{"position":[[250,6]]},"2890":{"position":[[157,8]]},"2947":{"position":[[457,6],[1502,8],[3562,8]]},"2953":{"position":[[180,6]]},"2966":{"position":[[1656,6],[2924,6]]},"3195":{"position":[[3,6]]},"3236":{"position":[[1459,8],[1658,10]]},"3262":{"position":[[215,6]]},"3276":{"position":[[144,9]]}}}],["north",{"_index":8522,"t":{"2403":{"position":[[230,5]]},"3299":{"position":[[3572,5]]}}}],["noscrub",{"_index":6832,"t":{"1404":{"position":[[15,7],[68,7]]}}}],["noset",{"_index":6117,"t":{"1269":{"position":[[33,5]]},"1271":{"position":[[31,5]]}}}],["nosuid",{"_index":6071,"t":{"1234":{"position":[[2333,6]]}}}],["notabl",{"_index":7906,"t":{"1857":{"position":[[184,7]]},"1919":{"position":[[184,7]]},"2966":{"position":[[4648,7]]},"3423":{"position":[[466,7]]}}}],["notari",{"_index":10098,"t":{"3301":{"position":[[7321,6]]}}}],["notat",{"_index":2694,"t":{"483":{"position":[[973,9]]},"487":{"position":[[161,9],[252,9],[339,9]]},"2075":{"position":[[453,10]]}}}],["note",{"_index":85,"t":{"10":{"position":[[233,7],[707,7]]},"23":{"position":[[163,4],[384,4]]},"127":{"position":[[43,5],[113,4]]},"359":{"position":[[16,5]]},"381":{"position":[[1634,5]]},"393":{"position":[[226,7],[673,7]]},"409":{"position":[[364,5]]},"417":{"position":[[523,4],[890,4]]},"421":{"position":[[1711,4]]},"447":{"position":[[701,5]]},"456":{"position":[[397,5]]},"462":{"position":[[1218,4]]},"467":{"position":[[692,4],[2470,4]]},"471":{"position":[[185,4],[360,4]]},"472":{"position":[[0,4],[577,4]]},"487":{"position":[[5155,4]]},"489":{"position":[[671,4]]},"501":{"position":[[860,4]]},"509":{"position":[[600,4],[745,4]]},"513":{"position":[[561,4],[2176,4]]},"530":{"position":[[957,4],[1109,4]]},"534":{"position":[[174,5]]},"548":{"position":[[0,4]]},"557":{"position":[[245,5]]},"583":{"position":[[396,4]]},"590":{"position":[[0,5],[809,4]]},"594":{"position":[[146,5]]},"596":{"position":[[527,4]]},"598":{"position":[[962,4]]},"602":{"position":[[214,6]]},"604":{"position":[[663,4],[1447,4],[3930,4],[6955,7],[7489,4],[7722,4],[8612,7],[9199,4]]},"609":{"position":[[2257,4],[2501,5],[5112,4],[5364,5],[5998,5]]},"627":{"position":[[599,4],[1594,4],[2702,4],[2915,4]]},"631":{"position":[[931,4]]},"656":{"position":[[363,6]]},"660":{"position":[[2937,5]]},"662":{"position":[[188,5]]},"819":{"position":[[187,4]]},"850":{"position":[[1144,4]]},"895":{"position":[[538,5]]},"901":{"position":[[688,6]]},"909":{"position":[[1211,6]]},"911":{"position":[[0,4]]},"915":{"position":[[434,4]]},"920":{"position":[[567,4],[850,5]]},"922":{"position":[[308,4]]},"932":{"position":[[3619,4]]},"940":{"position":[[103,4]]},"947":{"position":[[1664,5]]},"1027":{"position":[[141,4]]},"1029":{"position":[[136,4]]},"1067":{"position":[[4235,5],[4390,5],[4542,5],[4683,5],[5256,5],[5394,5]]},"1080":{"position":[[32,5],[123,5]]},"1114":{"position":[[377,4]]},"1165":{"position":[[1752,4]]},"1199":{"position":[[383,4]]},"1234":{"position":[[2420,4]]},"1286":{"position":[[166,5]]},"1395":{"position":[[347,4]]},"1413":{"position":[[29,4]]},"1419":{"position":[[826,4]]},"1442":{"position":[[51,4]]},"1446":{"position":[[24,4]]},"1448":{"position":[[0,4]]},"1460":{"position":[[152,4]]},"1462":{"position":[[594,4]]},"1471":{"position":[[102,5],[676,4],[1135,4],[1395,4],[1657,4],[2024,4]]},"1473":{"position":[[26,5]]},"1484":{"position":[[1144,4]]},"1509":{"position":[[187,4]]},"1562":{"position":[[105,4]]},"1576":{"position":[[109,4]]},"1582":{"position":[[87,4]]},"1617":{"position":[[538,5]]},"1623":{"position":[[688,6]]},"1631":{"position":[[1211,6]]},"1633":{"position":[[0,4]]},"1637":{"position":[[434,4]]},"1642":{"position":[[567,4],[850,5]]},"1644":{"position":[[308,4]]},"1654":{"position":[[3619,4]]},"1662":{"position":[[103,4]]},"1669":{"position":[[1664,5]]},"1678":{"position":[[2426,5]]},"1680":{"position":[[34,6]]},"1684":{"position":[[43,4],[119,5],[348,5],[1000,4],[1038,5],[1255,5],[1574,5],[1791,5],[1895,5],[2122,5],[2226,5],[2444,5],[2548,5],[2766,5],[2870,5],[3191,5],[3403,5],[3507,5]]},"1688":{"position":[[25,5]]},"1738":{"position":[[0,4]]},"1764":{"position":[[4084,4]]},"1773":{"position":[[411,4]]},"1775":{"position":[[114,4]]},"1789":{"position":[[301,4]]},"1808":{"position":[[171,4]]},"1825":{"position":[[32,5],[123,5]]},"1835":{"position":[[0,4]]},"1839":{"position":[[0,4]]},"1841":{"position":[[0,4]]},"1882":{"position":[[90,4],[434,4]]},"1886":{"position":[[0,4]]},"1888":{"position":[[240,4]]},"1892":{"position":[[224,4]]},"1894":{"position":[[599,4]]},"1896":{"position":[[966,4]]},"1900":{"position":[[0,4],[5,4],[348,6]]},"1902":{"position":[[185,4]]},"1904":{"position":[[263,4]]},"1908":{"position":[[302,4]]},"1913":{"position":[[1612,4]]},"1998":{"position":[[90,4],[434,4]]},"2002":{"position":[[0,4]]},"2004":{"position":[[240,4]]},"2008":{"position":[[224,4]]},"2010":{"position":[[599,4]]},"2012":{"position":[[966,4]]},"2016":{"position":[[0,4],[5,4],[348,6]]},"2018":{"position":[[185,4]]},"2020":{"position":[[263,4]]},"2024":{"position":[[302,4]]},"2029":{"position":[[1612,4]]},"2053":{"position":[[754,4]]},"2061":{"position":[[83,4]]},"2063":{"position":[[92,4],[360,4]]},"2065":{"position":[[86,4]]},"2096":{"position":[[857,4],[2084,5]]},"2098":{"position":[[3395,5]]},"2100":{"position":[[858,4]]},"2106":{"position":[[429,4]]},"2118":{"position":[[1521,5]]},"2148":{"position":[[273,5]]},"2150":{"position":[[159,5],[827,4]]},"2152":{"position":[[90,5]]},"2154":{"position":[[229,4]]},"2160":{"position":[[98,4]]},"2162":{"position":[[361,4]]},"2229":{"position":[[969,6]]},"2235":{"position":[[1005,5]]},"2245":{"position":[[597,5]]},"2253":{"position":[[210,5]]},"2267":{"position":[[142,4]]},"2278":{"position":[[335,5]]},"2283":{"position":[[237,5]]},"2286":{"position":[[96,5]]},"2294":{"position":[[261,4]]},"2300":{"position":[[142,4]]},"2312":{"position":[[837,6]]},"2315":{"position":[[578,5]]},"2319":{"position":[[79,6]]},"2342":{"position":[[538,5]]},"2348":{"position":[[688,6]]},"2356":{"position":[[1211,6]]},"2358":{"position":[[0,4]]},"2362":{"position":[[434,4]]},"2367":{"position":[[567,4],[850,5]]},"2369":{"position":[[308,4]]},"2379":{"position":[[3619,4]]},"2387":{"position":[[103,4]]},"2394":{"position":[[1664,5]]},"2415":{"position":[[79,6]]},"2420":{"position":[[77,5],[156,4]]},"2424":{"position":[[324,6]]},"2436":{"position":[[110,4],[169,5]]},"2478":{"position":[[79,6]]},"2544":{"position":[[630,5],[714,5]]},"2623":{"position":[[210,4],[682,6]]},"2631":{"position":[[714,5],[1144,5]]},"2695":{"position":[[45,4]]},"2697":{"position":[[968,4]]},"2702":{"position":[[121,4],[274,4]]},"2705":{"position":[[215,4],[624,4]]},"2709":{"position":[[214,4]]},"2711":{"position":[[561,4],[685,5],[940,5]]},"2713":{"position":[[1157,4]]},"2719":{"position":[[542,4],[1389,4],[1568,4]]},"2727":{"position":[[205,4],[534,6]]},"2731":{"position":[[0,4]]},"2740":{"position":[[45,4]]},"2742":{"position":[[867,4]]},"2747":{"position":[[121,4],[274,4]]},"2750":{"position":[[215,4],[624,4]]},"2754":{"position":[[214,4]]},"2756":{"position":[[874,4]]},"2758":{"position":[[540,4],[1387,4],[1569,4]]},"2764":{"position":[[1098,4]]},"2766":{"position":[[306,4],[734,6]]},"2770":{"position":[[0,4]]},"2795":{"position":[[628,4]]},"2809":{"position":[[527,4],[931,5]]},"2813":{"position":[[1435,5]]},"2817":{"position":[[117,4]]},"2830":{"position":[[45,4]]},"2837":{"position":[[186,5]]},"2840":{"position":[[123,4],[519,4]]},"2844":{"position":[[142,4]]},"2852":{"position":[[0,4],[584,4],[881,6]]},"2856":{"position":[[563,4],[663,5],[918,5]]},"2858":{"position":[[967,4],[1632,4]]},"2860":{"position":[[0,4]]},"2872":{"position":[[714,4]]},"2874":{"position":[[616,5]]},"2892":{"position":[[427,5]]},"2895":{"position":[[1251,4],[3964,4],[4088,4]]},"2897":{"position":[[102,6],[278,5],[366,4]]},"2899":{"position":[[1113,4]]},"2901":{"position":[[321,4],[419,4],[1871,4]]},"2911":{"position":[[372,5]]},"2913":{"position":[[172,4]]},"2925":{"position":[[71,4]]},"2933":{"position":[[33,4],[157,5]]},"2939":{"position":[[308,4]]},"2947":{"position":[[5804,4]]},"2966":{"position":[[4206,6]]},"2992":{"position":[[19,4]]},"3092":{"position":[[406,5]]},"3094":{"position":[[64,5]]},"3186":{"position":[[1388,6]]},"3236":{"position":[[523,5]]},"3270":{"position":[[1640,5]]},"3276":{"position":[[1564,4],[2422,6]]},"3301":{"position":[[7158,6]]},"3325":{"position":[[511,4]]},"3429":{"position":[[0,4]]},"3431":{"position":[[0,4]]},"3472":{"position":[[12346,4],[12806,5],[13972,4]]},"3518":{"position":[[1013,5],[1102,5]]}}}],["note_email_address",{"_index":4478,"t":{"913":{"position":[[2855,18]]},"920":{"position":[[997,20]]},"1635":{"position":[[2855,18]]},"1642":{"position":[[997,20]]},"2360":{"position":[[2855,18]]},"2367":{"position":[[997,20]]}}}],["noteabl",{"_index":9648,"t":{"2966":{"position":[[2099,9],[2575,9]]}}}],["notepad",{"_index":1463,"t":{"208":{"position":[[18,8]]}}}],["noteworthi",{"_index":8423,"t":{"2250":{"position":[[215,10]]},"2283":{"position":[[867,10]]}}}],["noth",{"_index":4100,"t":{"850":{"position":[[2854,7],[3853,7],[6031,7],[6870,7],[7696,7]]},"901":{"position":[[0,7]]},"909":{"position":[[1562,7]]},"1055":{"position":[[216,7]]},"1067":{"position":[[3757,7]]},"1120":{"position":[[167,7]]},"1234":{"position":[[1538,7]]},"1484":{"position":[[2854,7],[3853,7],[6031,7],[6870,7],[7696,7]]},"1623":{"position":[[0,7]]},"1631":{"position":[[1562,7]]},"1721":{"position":[[262,7]]},"2194":{"position":[[0,7]]},"2348":{"position":[[0,7]]},"2356":{"position":[[1562,7]]},"2430":{"position":[[0,7]]},"2852":{"position":[[281,7]]},"2906":{"position":[[23,7]]},"3400":{"position":[[1550,7]]}}}],["notic",{"_index":8483,"t":{"2324":{"position":[[56,7]]},"2417":{"position":[[60,8]]},"2420":{"position":[[56,8]]},"2480":{"position":[[60,8]]},"2895":{"position":[[3315,7],[3368,6],[3824,6],[3874,6]]},"2947":{"position":[[2122,6]]},"3370":{"position":[[15,7]]},"3434":{"position":[[15,7]]}}}],["notif",{"_index":3463,"t":{"646":{"position":[[992,12]]},"920":{"position":[[160,12],[620,13],[764,13]]},"1642":{"position":[[160,12],[620,13],[764,13]]},"2071":{"position":[[81,13],[640,13]]},"2138":{"position":[[334,13]]},"2367":{"position":[[160,12],[620,13],[764,13]]},"2463":{"position":[[315,13]]},"2801":{"position":[[212,12]]},"3316":{"position":[[366,12],[1464,12]]},"3389":{"position":[[874,13]]}}}],["notifi",{"_index":905,"t":{"139":{"position":[[574,7]]},"1167":{"position":[[764,7]]},"1697":{"position":[[575,7]]},"2566":{"position":[[14780,8]]},"2568":{"position":[[192,11],[340,8]]},"2688":{"position":[[2918,8]]}}}],["nov'23",{"_index":8583,"t":{"2493":{"position":[[84,7]]}}}],["nova",{"_index":3511,"t":{"660":{"position":[[68,6]]},"742":{"position":[[416,4],[777,4]]},"744":{"position":[[97,4],[140,4],[523,4],[548,4]]},"764":{"position":[[144,4]]},"770":{"position":[[0,4]]},"776":{"position":[[58,5]]},"842":{"position":[[62,4]]},"857":{"position":[[125,4],[293,4]]},"903":{"position":[[2307,4]]},"956":{"position":[[791,4]]},"1055":{"position":[[3656,6]]},"1067":{"position":[[3559,4]]},"1161":{"position":[[3870,4]]},"1165":{"position":[[961,7],[989,5],[1055,5],[1222,4],[2474,4]]},"1171":{"position":[[0,4],[17,4],[42,4]]},"1184":{"position":[[93,4],[276,4],[2291,5],[2396,4],[2523,5]]},"1286":{"position":[[312,5]]},"1294":{"position":[[870,4],[895,4],[912,4]]},"1347":{"position":[[654,4],[748,4],[842,4]]},"1358":{"position":[[402,4],[507,4]]},"1360":{"position":[[544,4]]},"1362":{"position":[[1081,4],[1103,4]]},"1375":{"position":[[98,4],[703,4],[735,4],[1082,4],[1514,4],[1546,4]]},"1377":{"position":[[99,4],[704,4],[736,4],[1103,4],[1708,4],[1740,4]]},"1557":{"position":[[62,4]]},"1601":{"position":[[125,4],[293,4]]},"1625":{"position":[[2307,4]]},"1773":{"position":[[1164,6],[1198,6],[1233,6]]},"1808":{"position":[[194,4],[622,4],[761,4]]},"1814":{"position":[[428,4]]},"1822":{"position":[[660,4],[685,4],[713,4]]},"1872":{"position":[[63,5],[142,5]]},"1876":{"position":[[156,4]]},"1906":{"position":[[1041,4]]},"1988":{"position":[[63,5],[142,5]]},"1992":{"position":[[156,4]]},"2022":{"position":[[1041,4]]},"2190":{"position":[[643,5]]},"2326":{"position":[[302,4]]},"2350":{"position":[[2307,4]]},"2953":{"position":[[56,4]]},"2966":{"position":[[1134,4],[1578,4],[1775,4]]}}}],["nova.conf",{"_index":5800,"t":{"1161":{"position":[[3892,9]]},"1165":{"position":[[492,9],[579,9]]},"1184":{"position":[[618,9]]}}}],["nova.services.a.regiocloud.tech",{"_index":5781,"t":{"1161":{"position":[[2731,31]]}}}],["nova_api_external_back",{"_index":5782,"t":{"1161":{"position":[[2775,22]]}}}],["nova_api_public_port",{"_index":5728,"t":{"1159":{"position":[[2883,21]]}}}],["nova_api_work",{"_index":5940,"t":{"1169":{"position":[[1375,16]]}}}],["nova_backend",{"_index":5975,"t":{"1184":{"position":[[1973,13],[2189,13]]}}}],["nova_cell_conductor_work",{"_index":5944,"t":{"1169":{"position":[[1469,27]]}}}],["nova_comput",{"_index":6578,"t":{"1360":{"position":[[1291,12]]},"1362":{"position":[[606,12]]}}}],["nova_external_fqdn",{"_index":5727,"t":{"1159":{"position":[[2835,18]]}}}],["nova_instance_datadir_volum",{"_index":5973,"t":{"1184":{"position":[[1634,28],[1820,29],[1940,28],[2145,29]]}}}],["nova_instance_id",{"_index":8912,"t":{"2566":{"position":[[11642,17]]}}}],["nova_legacy_public_endpoint",{"_index":5696,"t":{"1159":{"position":[[1623,27]]}}}],["nova_libvirt",{"_index":5957,"t":{"1174":{"position":[[196,12]]},"1176":{"position":[[204,12]]},"1360":{"position":[[1419,12]]},"1362":{"position":[[554,12]]}}}],["nova_metadata_api_work",{"_index":5942,"t":{"1169":{"position":[[1420,25]]}}}],["nova_novncproxy_external_back",{"_index":5785,"t":{"1161":{"position":[[2940,29]]}}}],["nova_public_base_endpoint",{"_index":5697,"t":{"1159":{"position":[[1654,25],[1724,25],[2809,25]]},"1161":{"position":[[909,26]]}}}],["nova_public_endpoint",{"_index":5699,"t":{"1159":{"position":[[1700,20]]}}}],["nova_scheduler_work",{"_index":5943,"t":{"1169":{"position":[[1446,22]]}}}],["nova_ssh",{"_index":6583,"t":{"1360":{"position":[[1544,8]]},"1362":{"position":[[506,8]]}}}],["nova_superconductor_work",{"_index":5941,"t":{"1169":{"position":[[1392,27]]}}}],["nova_volume_id",{"_index":8925,"t":{"2566":{"position":[[12164,15]]}}}],["novacli",{"_index":133,"t":{"10":{"position":[[1157,10]]}}}],["novemb",{"_index":8493,"t":{"2326":{"position":[[119,8]]}}}],["novnc",{"_index":5801,"t":{"1161":{"position":[[3937,5]]},"1849":{"position":[[362,5]]},"2245":{"position":[[694,5]]}}}],["novncproxy_base_url",{"_index":5803,"t":{"1161":{"position":[[4002,19]]}}}],["novolum",{"_index":4180,"t":{"859":{"position":[[672,9],[1923,8]]},"1603":{"position":[[672,9],[1923,8]]}}}],["now",{"_index":250,"t":{"23":{"position":[[291,4]]},"114":{"position":[[807,3]]},"158":{"position":[[873,3]]},"164":{"position":[[8,3]]},"247":{"position":[[2217,3]]},"272":{"position":[[222,4]]},"325":{"position":[[2250,3]]},"331":{"position":[[353,4]]},"339":{"position":[[62,3]]},"393":{"position":[[526,4]]},"604":{"position":[[2036,3],[2121,3],[2886,3],[5937,4]]},"609":{"position":[[718,3]]},"615":{"position":[[795,3]]},"631":{"position":[[354,3]]},"662":{"position":[[198,4],[674,3]]},"730":{"position":[[1467,3]]},"850":{"position":[[2196,3],[2380,3],[8700,3]]},"901":{"position":[[752,5]]},"909":{"position":[[246,4],[807,4]]},"913":{"position":[[2258,3]]},"932":{"position":[[1546,3],[1706,3],[2571,3]]},"934":{"position":[[1473,3]]},"954":{"position":[[522,3]]},"1065":{"position":[[476,3]]},"1112":{"position":[[4148,3],[5681,3]]},"1224":{"position":[[4045,3]]},"1228":{"position":[[32,3]]},"1230":{"position":[[32,3]]},"1264":{"position":[[213,3]]},"1388":{"position":[[235,3]]},"1397":{"position":[[406,3]]},"1419":{"position":[[486,3],[520,3]]},"1471":{"position":[[799,3],[1222,3],[1482,3],[2111,3]]},"1473":{"position":[[375,3],[537,3],[727,3],[1221,3],[1392,4],[1488,3],[1735,3]]},"1484":{"position":[[2196,3],[2380,3],[8700,3]]},"1491":{"position":[[1467,3]]},"1571":{"position":[[1387,3]]},"1585":{"position":[[1620,3],[2111,3],[2630,3],[3456,3],[3540,3]]},"1623":{"position":[[752,5]]},"1631":{"position":[[246,4],[807,4]]},"1635":{"position":[[2258,3]]},"1654":{"position":[[1546,3],[1706,3],[2571,3]]},"1656":{"position":[[1473,3]]},"1678":{"position":[[2761,3]]},"1747":{"position":[[582,3]]},"1839":{"position":[[5,3]]},"1841":{"position":[[140,3]]},"1843":{"position":[[153,3]]},"1845":{"position":[[1451,3]]},"1849":{"position":[[653,3],[941,3]]},"1892":{"position":[[1207,3]]},"1913":{"position":[[1565,3],[1855,3]]},"1957":{"position":[[2304,4]]},"1982":{"position":[[304,4]]},"2008":{"position":[[1207,3]]},"2029":{"position":[[1565,3],[1855,3]]},"2031":{"position":[[6,4]]},"2033":{"position":[[1782,4]]},"2118":{"position":[[2237,4]]},"2196":{"position":[[537,4]]},"2206":{"position":[[385,4]]},"2217":{"position":[[6,3]]},"2220":{"position":[[66,3]]},"2245":{"position":[[87,3]]},"2248":{"position":[[31,3],[299,3],[1068,3]]},"2250":{"position":[[3,3]]},"2253":{"position":[[420,4]]},"2255":{"position":[[56,3],[379,3]]},"2257":{"position":[[244,3]]},"2259":{"position":[[416,4]]},"2263":{"position":[[86,3],[263,3]]},"2278":{"position":[[78,3]]},"2283":{"position":[[128,4],[630,3],[781,4],[805,3],[929,3]]},"2292":{"position":[[605,4]]},"2312":{"position":[[705,3]]},"2315":{"position":[[1235,3],[1473,3],[1554,3]]},"2321":{"position":[[353,3]]},"2324":{"position":[[349,3]]},"2348":{"position":[[752,5]]},"2356":{"position":[[246,4],[807,4]]},"2360":{"position":[[2258,3]]},"2379":{"position":[[1546,3],[1706,3],[2571,3]]},"2381":{"position":[[1473,3]]},"2403":{"position":[[111,3],[301,3]]},"2405":{"position":[[375,3],[476,4],[633,3],[775,3],[860,3]]},"2409":{"position":[[408,3],[453,3],[667,3]]},"2411":{"position":[[116,3]]},"2413":{"position":[[19,3],[261,4]]},"2465":{"position":[[60,3]]},"2468":{"position":[[115,3]]},"2476":{"position":[[82,3]]},"2495":{"position":[[18,3]]},"2506":{"position":[[127,3]]},"2692":{"position":[[6,4]]},"2822":{"position":[[268,4]]},"2872":{"position":[[1436,3]]},"3082":{"position":[[269,3]]},"3234":{"position":[[587,3]]}}}],["nowait",{"_index":4181,"t":{"859":{"position":[[685,7],[1958,6]]},"1603":{"position":[[685,7],[1958,6]]}}}],["npm",{"_index":664,"t":{"105":{"position":[[670,3]]},"158":{"position":[[939,4]]},"162":{"position":[[124,3]]},"164":{"position":[[65,3]]},"3316":{"position":[[154,3]]}}}],["npm/github/zapi",{"_index":10130,"t":{"3316":{"position":[[134,17]]}}}],["nr=1048576",{"_index":5169,"t":{"1106":{"position":[[567,10]]}}}],["ns",{"_index":6849,"t":{"1413":{"position":[[10,2]]}}}],["nscd",{"_index":4782,"t":{"1029":{"position":[[28,4]]}}}],["nsllaalighht17",{"_index":7632,"t":{"1791":{"position":[[3506,14]]}}}],["ntp",{"_index":3669,"t":{"748":{"position":[[266,4]]},"1067":{"position":[[418,3],[5663,3]]},"1071":{"position":[[1083,3],[1104,3],[1199,3]]},"1209":{"position":[[71,3]]}}}],["ntp_server",{"_index":4939,"t":{"1063":{"position":[[1385,10]]},"1071":{"position":[[1072,10]]}}}],["nuclei",{"_index":8143,"t":{"2079":{"position":[[15,6]]}}}],["null",{"_index":2038,"t":{"325":{"position":[[354,4]]}}}],["num",{"_index":2654,"t":{"472":{"position":[[2576,3],[2591,3]]},"1462":{"position":[[599,3]]}}}],["num_nod",{"_index":5859,"t":{"1167":{"position":[[931,9],[1005,10],[1054,9],[1729,9]]}}}],["num_osd",{"_index":5222,"t":{"1112":{"position":[[1318,9],[1389,8],[1973,9],[2292,9],[2637,9],[3055,9],[3247,9]]},"1114":{"position":[[471,9],[1121,9]]}}}],["num_pg",{"_index":6928,"t":{"1462":{"position":[[584,9]]}}}],["numa",{"_index":5407,"t":{"1124":{"position":[[31,4],[742,4],[836,4],[917,4],[985,4]]}}}],["numactl",{"_index":5417,"t":{"1124":{"position":[[879,8],[998,7]]}}}],["number",{"_index":492,"t":{"67":{"position":[[12,6]]},"151":{"position":[[223,8]]},"178":{"position":[[1571,6]]},"212":{"position":[[212,7]]},"325":{"position":[[5879,6]]},"436":{"position":[[1037,6]]},"487":{"position":[[1580,6],[1813,6]]},"513":{"position":[[378,6]]},"548":{"position":[[243,7]]},"590":{"position":[[2643,6]]},"600":{"position":[[112,6]]},"604":{"position":[[2068,6]]},"627":{"position":[[2980,6]]},"744":{"position":[[382,6]]},"764":{"position":[[514,6]]},"768":{"position":[[189,6]]},"770":{"position":[[165,6]]},"857":{"position":[[300,6],[422,6]]},"859":{"position":[[696,6],[703,7],[822,6],[1989,6],[1996,6],[2136,6],[2479,6]]},"861":{"position":[[255,6]]},"909":{"position":[[2241,6],[2478,6],[2525,6]]},"932":{"position":[[900,6],[3513,7],[3543,7],[3668,7],[4622,6]]},"947":{"position":[[990,6]]},"1055":{"position":[[90,6]]},"1091":{"position":[[43,6]]},"1112":{"position":[[1430,6]]},"1120":{"position":[[41,6]]},"1124":{"position":[[424,8]]},"1165":{"position":[[1766,7]]},"1169":{"position":[[4,6],[605,6]]},"1234":{"position":[[346,6]]},"1290":{"position":[[404,6]]},"1292":{"position":[[231,6],[847,6]]},"1294":{"position":[[143,6]]},"1462":{"position":[[205,6],[307,6],[525,6],[657,6]]},"1473":{"position":[[584,6]]},"1601":{"position":[[300,6],[422,6]]},"1603":{"position":[[696,6],[703,7],[822,6],[1989,6],[1996,6],[2136,6],[2479,6]]},"1605":{"position":[[255,6]]},"1631":{"position":[[2241,6],[2478,6],[2525,6]]},"1654":{"position":[[900,6],[3513,7],[3543,7],[3668,7],[4622,6]]},"1669":{"position":[[990,6]]},"1770":{"position":[[518,6]]},"1853":{"position":[[262,7]]},"1855":{"position":[[608,8]]},"1915":{"position":[[262,7]]},"1917":{"position":[[608,8]]},"2118":{"position":[[1645,7]]},"2150":{"position":[[1061,6],[1231,6]]},"2198":{"position":[[12,9],[58,6]]},"2237":{"position":[[12,9]]},"2243":{"position":[[179,6]]},"2245":{"position":[[208,6]]},"2248":{"position":[[797,6]]},"2263":{"position":[[275,6]]},"2267":{"position":[[12,9]]},"2300":{"position":[[12,9]]},"2315":{"position":[[981,6]]},"2330":{"position":[[967,6]]},"2332":{"position":[[24,6]]},"2356":{"position":[[2241,6],[2478,6],[2525,6]]},"2379":{"position":[[900,6],[3513,7],[3543,7],[3668,7],[4622,6]]},"2394":{"position":[[990,6]]},"2409":{"position":[[2,6]]},"2499":{"position":[[2,6]]},"2536":{"position":[[186,6]]},"2625":{"position":[[95,7],[205,7],[352,7],[379,6],[400,6],[415,9],[743,7],[1037,7],[1167,6],[1200,6],[1410,7],[1461,6],[1585,6],[1646,7]]},"2631":{"position":[[303,6],[404,6],[1017,6],[1053,7],[1136,7],[1715,6],[1793,6]]},"2635":{"position":[[664,6]]},"2647":{"position":[[145,6],[539,7],[639,7],[1063,6]]},"2658":{"position":[[43,6]]},"2697":{"position":[[632,6]]},"2700":{"position":[[183,6],[197,6]]},"2702":{"position":[[160,7]]},"2705":{"position":[[12,6]]},"2742":{"position":[[531,6]]},"2745":{"position":[[183,6],[197,6]]},"2747":{"position":[[160,7]]},"2750":{"position":[[12,6]]},"2766":{"position":[[147,6]]},"2799":{"position":[[127,6]]},"2832":{"position":[[632,6]]},"2835":{"position":[[124,6],[138,6]]},"2837":{"position":[[226,7]]},"2872":{"position":[[569,6],[1177,7]]},"2895":{"position":[[228,7]]},"2911":{"position":[[252,6]]},"2931":{"position":[[31,7]]},"2942":{"position":[[59,6]]},"2966":{"position":[[3120,6],[3271,6]]},"2968":{"position":[[154,6]]},"2970":{"position":[[329,6]]},"3061":{"position":[[57,6]]},"3063":{"position":[[1021,6]]},"3160":{"position":[[2131,6]]},"3197":{"position":[[730,6]]},"3274":{"position":[[489,6]]},"3280":{"position":[[4,6]]},"3284":{"position":[[404,7]]},"3299":{"position":[[2446,6]]},"3372":{"position":[[686,6]]},"3389":{"position":[[572,6]]}}}],["number_of_nod",{"_index":7681,"t":{"1808":{"position":[[627,15]]}}}],["number_of_volum",{"_index":7682,"t":{"1808":{"position":[[645,17]]}}}],["numer",{"_index":3075,"t":{"598":{"position":[[764,8]]},"2248":{"position":[[59,8]]},"2424":{"position":[[0,8]]},"2663":{"position":[[69,8]]},"2895":{"position":[[2367,9]]},"3156":{"position":[[10,8]]}}}],["nut",{"_index":1507,"t":{"219":{"position":[[91,4]]}}}],["nv",{"_index":5831,"t":{"1165":{"position":[[1866,2]]}}}],["nvidia",{"_index":9286,"t":{"2727":{"position":[[305,6],[330,7]]},"2733":{"position":[[366,6]]},"2766":{"position":[[431,6],[530,7],[1066,6]]},"2772":{"position":[[366,6]]},"2852":{"position":[[682,6],[724,6]]},"2854":{"position":[[367,6]]}}}],["nvm",{"_index":984,"t":{"158":{"position":[[41,3],[334,3],[365,3],[410,3],[432,4],[437,3],[551,3],[572,3],[618,3],[705,3],[849,3],[865,3]]}}}],["nvme",{"_index":4687,"t":{"982":{"position":[[545,4]]},"984":{"position":[[224,4],[281,4],[420,4]]},"986":{"position":[[235,4]]},"988":{"position":[[235,4]]},"990":{"position":[[288,4]]},"1014":{"position":[[420,4]]},"1409":{"position":[[30,4]]},"1411":{"position":[[25,4]]},"1413":{"position":[[2,4]]},"1415":{"position":[[52,4]]},"1417":{"position":[[52,4],[109,4]]},"1464":{"position":[[213,4]]},"1466":{"position":[[110,4]]},"1773":{"position":[[682,4]]},"2709":{"position":[[199,4]]},"2733":{"position":[[172,4],[466,4]]},"2754":{"position":[[199,4],[776,4]]},"2756":{"position":[[697,4]]},"2772":{"position":[[172,4],[466,4]]},"2844":{"position":[[127,4]]},"2854":{"position":[[172,4],[467,4]]},"2923":{"position":[[871,4]]},"2947":{"position":[[5110,4],[5697,4]]},"2949":{"position":[[735,5],[873,5]]}}}],["nvme0n1",{"_index":5228,"t":{"1112":{"position":[[1814,7],[1964,8],[2050,7],[2102,7],[2131,7],[2283,8],[2369,7],[2423,7],[2491,7],[2628,8],[2729,7],[2754,7],[2807,7],[2823,7],[2896,7],[3046,8],[3324,7],[3402,7]]}}}],["nvme1n1",{"_index":5229,"t":{"1112":{"position":[[3086,7],[3238,8],[3349,7],[3418,7]]}}}],["nwipe",{"_index":6868,"t":{"1419":{"position":[[1229,6]]}}}],["nydu",{"_index":10095,"t":{"3301":{"position":[[6913,6]]}}}],["o",{"_index":291,"t":{"25":{"position":[[844,1]]},"27":{"position":[[310,1],[1767,1]]},"592":{"position":[[194,1]]},"609":{"position":[[1163,1],[6398,1]]},"641":{"position":[[1617,1],[1993,1]]},"646":{"position":[[666,1],[1409,1],[1899,1],[2100,1]]},"909":{"position":[[896,1]]},"913":{"position":[[946,1],[1159,1],[1234,1],[1308,1],[1383,1],[1463,1],[1537,1],[1619,1],[1911,1],[2188,1],[2302,1],[2386,1]]},"926":{"position":[[168,1]]},"932":{"position":[[132,1]]},"1163":{"position":[[305,2]]},"1256":{"position":[[2206,1],[3332,1]]},"1337":{"position":[[267,1],[382,1]]},"1368":{"position":[[193,1],[305,1]]},"1631":{"position":[[896,1]]},"1635":{"position":[[946,1],[1159,1],[1234,1],[1308,1],[1383,1],[1463,1],[1537,1],[1619,1],[1911,1],[2188,1],[2302,1],[2386,1]]},"1648":{"position":[[168,1]]},"1654":{"position":[[132,1]]},"1839":{"position":[[121,1],[222,1]]},"2106":{"position":[[626,1]]},"2356":{"position":[[896,1]]},"2360":{"position":[[946,1],[1159,1],[1234,1],[1308,1],[1383,1],[1463,1],[1537,1],[1619,1],[1911,1],[2188,1],[2302,1],[2386,1]]},"2373":{"position":[[168,1]]},"2379":{"position":[[132,1]]},"2707":{"position":[[355,1]]},"2713":{"position":[[1154,2]]},"2719":{"position":[[761,1]]},"2752":{"position":[[355,1]]},"2756":{"position":[[871,2]]},"2758":{"position":[[759,1]]},"2842":{"position":[[328,1]]},"2858":{"position":[[964,2]]}}}],["o'clock",{"_index":2023,"t":{"321":{"position":[[1590,7]]}}}],["o'reilli",{"_index":3571,"t":{"669":{"position":[[498,8]]}}}],["oaep",{"_index":2086,"t":{"325":{"position":[[4417,4],[5927,5],[6587,4],[6642,4],[6697,4]]}}}],["oauth",{"_index":1935,"t":{"298":{"position":[[481,5]]},"932":{"position":[[4501,5]]},"1654":{"position":[[4501,5]]},"1947":{"position":[[365,5]]},"1953":{"position":[[364,5]]},"2110":{"position":[[470,5],[1026,5]]},"2138":{"position":[[443,5]]},"2379":{"position":[[4501,5]]},"2463":{"position":[[329,5]]},"2576":{"position":[[599,5]]},"3247":{"position":[[255,5]]},"3251":{"position":[[1301,5]]},"3255":{"position":[[597,5]]},"3314":{"position":[[179,7]]}}}],["oauth/oauth2",{"_index":8223,"t":{"2110":{"position":[[194,12],[436,12]]}}}],["oauth2",{"_index":8220,"t":{"2110":{"position":[[10,6],[394,6]]},"2474":{"position":[[254,6]]},"3251":{"position":[[3556,7]]},"3255":{"position":[[144,6]]}}}],["oauth2_proxy_client_id",{"_index":8225,"t":{"2110":{"position":[[292,22]]}}}],["oauth2_proxy_client_secret",{"_index":8226,"t":{"2110":{"position":[[315,26]]}}}],["oauth2_proxy_cookie_secret",{"_index":8227,"t":{"2110":{"position":[[342,26]]}}}],["obfusc",{"_index":9915,"t":{"3186":{"position":[[1291,10]]}}}],["object",{"_index":197,"t":{"12":{"position":[[266,7],[298,6]]},"44":{"position":[[118,6]]},"51":{"position":[[101,6]]},"73":{"position":[[122,9]]},"389":{"position":[[425,6]]},"404":{"position":[[323,9]]},"423":{"position":[[43,6]]},"427":{"position":[[991,6]]},"451":{"position":[[270,6]]},"462":{"position":[[1434,6]]},"467":{"position":[[43,6],[238,6],[511,6],[2583,6]]},"590":{"position":[[643,6]]},"633":{"position":[[1107,6]]},"639":{"position":[[487,6],[834,6]]},"646":{"position":[[1381,7]]},"662":{"position":[[1078,6]]},"748":{"position":[[336,6]]},"764":{"position":[[227,6]]},"768":{"position":[[113,6],[131,6],[256,6]]},"774":{"position":[[286,6]]},"776":{"position":[[23,6],[170,7],[248,7],[318,7]]},"778":{"position":[[11,7]]},"788":{"position":[[40,6]]},"819":{"position":[[228,8]]},"880":{"position":[[93,7],[964,7]]},"922":{"position":[[911,6]]},"942":{"position":[[140,6]]},"945":{"position":[[301,6]]},"1444":{"position":[[34,8],[320,7],[411,7],[438,7],[795,8]]},"1509":{"position":[[228,8]]},"1525":{"position":[[40,6]]},"1644":{"position":[[911,6]]},"1664":{"position":[[140,6]]},"1667":{"position":[[301,6]]},"1974":{"position":[[640,7]]},"1982":{"position":[[962,7],[981,7]]},"1984":{"position":[[572,7],[591,7]]},"2138":{"position":[[686,6]]},"2334":{"position":[[230,7]]},"2369":{"position":[[911,6]]},"2389":{"position":[[140,6]]},"2392":{"position":[[301,6]]},"2564":{"position":[[371,7]]},"2797":{"position":[[103,11]]},"2942":{"position":[[316,6]]},"2966":{"position":[[3514,7],[3528,7],[4232,7]]},"2977":{"position":[[137,11]]},"2981":{"position":[[68,8],[82,6]]},"3023":{"position":[[374,6]]},"3055":{"position":[[9,9]]},"3109":{"position":[[1246,7],[1344,6],[1382,7],[1567,6],[1581,6]]},"3224":{"position":[[1851,10]]},"3340":{"position":[[123,8]]},"3343":{"position":[[100,6],[276,6],[788,7]]},"3345":{"position":[[4,7]]},"3347":{"position":[[15,7],[114,8],[658,7]]},"3349":{"position":[[67,8]]},"3361":{"position":[[494,8]]},"3365":{"position":[[54,8],[202,6],[272,7]]},"3376":{"position":[[516,6]]},"3395":{"position":[[562,6],[905,6]]},"3440":{"position":[[194,6]]}}}],["object_id",{"_index":9804,"t":{"3109":{"position":[[646,9],[2860,9]]}}}],["object_typ",{"_index":9810,"t":{"3109":{"position":[[699,11],[2913,11]]}}}],["objectstore.http.request",{"_index":8845,"t":{"2566":{"position":[[6725,24]]}}}],["objectstore_request",{"_index":8846,"t":{"2566":{"position":[[6758,20]]}}}],["oblig",{"_index":1068,"t":{"168":{"position":[[820,10]]},"170":{"position":[[176,11]]}}}],["observ",{"_index":427,"t":{"40":{"position":[[69,13]]},"75":{"position":[[218,13]]},"168":{"position":[[1132,8]]},"225":{"position":[[248,8]]},"245":{"position":[[1560,7],[1641,12]]},"319":{"position":[[25,7],[297,7]]},"615":{"position":[[56,8]]},"949":{"position":[[861,8]]},"1305":{"position":[[243,13]]},"1671":{"position":[[861,8]]},"2033":{"position":[[1746,7]]},"2071":{"position":[[102,8],[668,8]]},"2087":{"position":[[194,7]]},"2093":{"position":[[231,8],[310,8],[327,8],[414,9]]},"2096":{"position":[[1124,7],[2065,8],[2398,8]]},"2098":{"position":[[1501,8],[1877,8],[2185,8],[2708,8],[2742,8],[3052,8],[3249,8],[3291,8],[3709,8],[3749,8]]},"2100":{"position":[[301,13],[330,8],[403,13],[663,8],[839,8]]},"2104":{"position":[[77,8]]},"2106":{"position":[[323,8],[1029,8]]},"2108":{"position":[[109,8]]},"2110":{"position":[[1046,8]]},"2114":{"position":[[218,8]]},"2116":{"position":[[92,8],[259,8],[311,8],[443,8],[887,9]]},"2118":{"position":[[86,8],[162,8],[250,8],[363,8],[489,8],[1268,8]]},"2120":{"position":[[325,8],[596,8]]},"2122":{"position":[[47,8],[209,8],[288,8],[578,8]]},"2126":{"position":[[4,8],[420,8],[477,8]]},"2130":{"position":[[105,8]]},"2132":{"position":[[82,8]]},"2138":{"position":[[551,8],[1061,8]]},"2144":{"position":[[138,7]]},"2146":{"position":[[275,13]]},"2154":{"position":[[33,8],[301,13],[403,8],[615,8],[783,8]]},"2158":{"position":[[76,8],[824,8]]},"2396":{"position":[[861,8]]},"2463":{"position":[[0,14],[19,13]]},"2468":{"position":[[576,8]]},"2493":{"position":[[161,13]]},"2602":{"position":[[739,13]]},"2895":{"position":[[2046,8]]},"2944":{"position":[[1316,8]]},"3160":{"position":[[1379,13]]},"3245":{"position":[[258,11]]},"3251":{"position":[[944,8]]},"3389":{"position":[[355,9],[385,13]]},"3391":{"position":[[74,13],[486,13]]},"3393":{"position":[[198,13],[931,13],[990,13],[1037,13],[1073,7],[1088,8],[1195,13]]},"3395":{"position":[[19,13],[127,13],[365,8],[695,13],[1024,13],[1056,13],[1165,7],[1245,9],[1259,13],[1341,7],[1353,13]]},"3397":{"position":[[147,13],[204,13],[228,13],[345,7],[462,13],[538,8],[570,9],[700,13],[772,8],[1970,13],[2152,8],[2210,13]]},"3400":{"position":[[585,13],[1593,13]]},"3518":{"position":[[2582,13]]}}}],["observabiltiy",{"_index":10219,"t":{"3400":{"position":[[741,13]]}}}],["observer.yaml",{"_index":8134,"t":{"2071":{"position":[[567,13]]},"2096":{"position":[[2228,14],[2369,13]]},"2098":{"position":[[3539,14],[3680,13]]},"2110":{"position":[[947,13]]},"2120":{"position":[[525,14]]},"2128":{"position":[[216,13]]},"2158":{"position":[[695,13]]}}}],["observer_id",{"_index":8843,"t":{"2566":{"position":[[6670,12],[7528,12],[10010,12],[14324,12]]}}}],["observer_typeuri",{"_index":8841,"t":{"2566":{"position":[[6619,17],[14365,17]]}}}],["obsolet",{"_index":9033,"t":{"2637":{"position":[[25,9],[57,11]]},"2779":{"position":[[252,8]]},"2815":{"position":[[1420,8]]}}}],["obtain",{"_index":1959,"t":{"302":{"position":[[56,8],[307,8]]},"641":{"position":[[1929,8]]},"1569":{"position":[[1622,6]]},"1571":{"position":[[1566,6]]},"1939":{"position":[[124,6],[273,6]]},"1957":{"position":[[2944,8]]},"2518":{"position":[[41,6]]},"2686":{"position":[[23,6]]},"3276":{"position":[[1005,6]]},"3357":{"position":[[249,6]]}}}],["obviou",{"_index":9099,"t":{"2697":{"position":[[623,8]]},"2742":{"position":[[522,8]]},"2820":{"position":[[290,8]]},"2832":{"position":[[623,8]]},"3197":{"position":[[292,7]]},"3465":{"position":[[108,7]]}}}],["obvious",{"_index":2055,"t":{"325":{"position":[[1229,9]]},"600":{"position":[[542,9]]},"899":{"position":[[91,9]]},"932":{"position":[[3936,10]]},"942":{"position":[[345,10]]},"1621":{"position":[[91,9]]},"1654":{"position":[[3936,10]]},"1664":{"position":[[345,10]]},"2346":{"position":[[91,9]]},"2379":{"position":[[3936,10]]},"2389":{"position":[[345,10]]},"2947":{"position":[[1793,9]]},"2949":{"position":[[329,9]]},"3236":{"position":[[2104,9]]}}}],["oc",{"_index":2798,"t":{"487":{"position":[[3609,2]]}}}],["occasion",{"_index":1760,"t":{"251":{"position":[[385,13]]},"615":{"position":[[65,10]]},"760":{"position":[[610,13]]},"949":{"position":[[880,13]]},"1671":{"position":[[880,13]]},"2396":{"position":[[880,13]]},"2947":{"position":[[1898,10],[2270,10]]}}}],["occm",{"_index":2784,"t":{"487":{"position":[[2644,4]]},"509":{"position":[[484,4]]},"511":{"position":[[76,4]]},"604":{"position":[[10026,7]]},"611":{"position":[[0,5]]},"650":{"position":[[914,4],[2474,4]]},"652":{"position":[[224,4]]},"2405":{"position":[[260,4]]}}}],["occur",{"_index":2033,"t":{"323":{"position":[[317,9]]},"760":{"position":[[603,6]]},"899":{"position":[[743,5]]},"911":{"position":[[1645,7]]},"1184":{"position":[[2502,5]]},"1256":{"position":[[1803,7],[1906,7]]},"1621":{"position":[[743,5]]},"1633":{"position":[[1645,7]]},"1779":{"position":[[2885,6]]},"1957":{"position":[[2193,8]]},"2346":{"position":[[743,5]]},"2358":{"position":[[1645,7]]},"2805":{"position":[[678,5]]},"3160":{"position":[[1586,5]]}}}],["occurr",{"_index":9380,"t":{"2805":{"position":[[833,10]]},"2813":{"position":[[1321,10]]}}}],["oci",{"_index":9898,"t":{"3160":{"position":[[2383,3]]},"3301":{"position":[[6792,3],[6815,3]]}}}],["oci://registry.scs.community/openstack",{"_index":8162,"t":{"2096":{"position":[[498,38]]}}}],["oct",{"_index":6382,"t":{"1321":{"position":[[102,3],[375,3],[539,3],[759,3],[989,3],[1227,3]]}}}],["oct'23",{"_index":8582,"t":{"2493":{"position":[[0,7]]}}}],["octavia",{"_index":2910,"t":{"505":{"position":[[901,7]]},"617":{"position":[[721,7]]},"1192":{"position":[[0,7],[20,7],[48,7]]},"1294":{"position":[[917,7],[945,7],[965,7],[1156,7],[1320,7]]},"1366":{"position":[[152,7]]},"1368":{"position":[[707,7],[803,7],[899,7]]},"1388":{"position":[[178,8]]},"1566":{"position":[[18,7]]},"1779":{"position":[[5994,7],[6195,7]]},"1814":{"position":[[452,7]]},"1822":{"position":[[718,7],[746,7],[777,7],[968,7],[1132,7]]},"2190":{"position":[[674,8]]},"2196":{"position":[[1105,9]]},"2468":{"position":[[224,7],[303,7]]},"2502":{"position":[[21,10]]}}}],["octavia.amphorae.drivers.health.heartbeat_udp",{"_index":6800,"t":{"1386":{"position":[[85,45]]}}}],["octavia.services.a.regiocloud.tech",{"_index":5793,"t":{"1161":{"position":[[3414,34]]}}}],["octavia/amphora",{"_index":6183,"t":{"1294":{"position":[[1183,15]]},"1822":{"position":[[995,15]]}}}],["octavia_api_external_back",{"_index":5794,"t":{"1161":{"position":[[3461,25]]}}}],["octavia_api_work",{"_index":5945,"t":{"1169":{"position":[[1497,19]]}}}],["octavia_healthmanager_health_work",{"_index":5946,"t":{"1169":{"position":[[1517,36]]}}}],["octavia_healthmanager_stats_work",{"_index":5947,"t":{"1169":{"position":[[1554,35]]}}}],["octavia_network_interfac",{"_index":4979,"t":{"1067":{"position":[[5142,26]]},"1163":{"position":[[276,25]]}}}],["octavia_network_typ",{"_index":5807,"t":{"1163":{"position":[[316,20]]}}}],["octavia_public_endpoint",{"_index":5748,"t":{"1161":{"position":[[976,24]]}}}],["octaviacli",{"_index":134,"t":{"10":{"position":[[1177,13]]},"517":{"position":[[58,13]]},"617":{"position":[[738,14]]},"905":{"position":[[166,13]]},"1627":{"position":[[166,13]]},"2352":{"position":[[166,13]]}}}],["octo",{"_index":1339,"t":{"187":{"position":[[94,4]]}}}],["octob",{"_index":8447,"t":{"2267":{"position":[[258,8]]},"2294":{"position":[[340,8]]},"2417":{"position":[[179,7]]}}}],["odss",{"_index":6925,"t":{"1462":{"position":[[347,4]]}}}],["off",{"_index":8570,"t":{"2474":{"position":[[291,4]]},"3374":{"position":[[444,5]]}}}],["offens",{"_index":1628,"t":{"245":{"position":[[1386,8]]}}}],["offer",{"_index":1418,"t":{"202":{"position":[[104,6]]},"235":{"position":[[28,6],[708,9]]},"276":{"position":[[88,8]]},"300":{"position":[[9,6]]},"327":{"position":[[59,6],[694,5]]},"331":{"position":[[390,5]]},"335":{"position":[[442,8]]},"339":{"position":[[66,8]]},"467":{"position":[[177,6]]},"637":{"position":[[36,6]]},"690":{"position":[[143,9]]},"692":{"position":[[123,5]]},"712":{"position":[[79,7]]},"714":{"position":[[55,5]]},"716":{"position":[[79,8]]},"750":{"position":[[295,5]]},"768":{"position":[[213,6]]},"772":{"position":[[686,6]]},"956":{"position":[[317,8]]},"977":{"position":[[1603,6]]},"1055":{"position":[[1096,6]]},"1146":{"position":[[36,7]]},"1413":{"position":[[157,6]]},"1827":{"position":[[612,9]]},"1882":{"position":[[60,6]]},"1888":{"position":[[325,5]]},"1908":{"position":[[26,6]]},"1937":{"position":[[438,6]]},"1957":{"position":[[4041,5]]},"1970":{"position":[[133,10],[182,10],[217,9],[252,10]]},"1972":{"position":[[1121,9]]},"1974":{"position":[[628,7]]},"1998":{"position":[[60,6]]},"2004":{"position":[[325,5]]},"2024":{"position":[[26,6]]},"2037":{"position":[[128,6],[275,5]]},"2081":{"position":[[191,6]]},"2083":{"position":[[512,6]]},"2085":{"position":[[391,6]]},"2116":{"position":[[961,9]]},"2154":{"position":[[74,5]]},"2176":{"position":[[307,8]]},"2259":{"position":[[482,7]]},"2265":{"position":[[632,10]]},"2292":{"position":[[460,7]]},"2298":{"position":[[632,10]]},"2518":{"position":[[29,8]]},"2530":{"position":[[98,10]]},"2663":{"position":[[409,8]]},"2665":{"position":[[283,5]]},"2675":{"position":[[313,6]]},"2688":{"position":[[593,5],[984,5]]},"2697":{"position":[[200,5]]},"2711":{"position":[[715,7],[921,5]]},"2713":{"position":[[67,5],[743,5],[834,5],[908,5],[1469,5],[1561,5],[1654,5]]},"2719":{"position":[[52,5],[391,5],[1203,5]]},"2721":{"position":[[58,5]]},"2731":{"position":[[237,9],[625,8],[650,8],[758,5],[854,5]]},"2737":{"position":[[373,5]]},"2742":{"position":[[200,5]]},"2756":{"position":[[17,5],[246,5],[609,5],[1211,5],[1302,5],[1376,5]]},"2758":{"position":[[52,5],[389,5],[1201,5]]},"2760":{"position":[[70,5]]},"2770":{"position":[[237,9],[625,8],[650,8],[758,5],[854,5]]},"2776":{"position":[[373,5]]},"2795":{"position":[[143,9],[247,5]]},"2820":{"position":[[140,6]]},"2832":{"position":[[200,5]]},"2846":{"position":[[58,5]]},"2856":{"position":[[693,7],[899,5]]},"2858":{"position":[[67,5],[581,5],[672,5],[718,5],[1241,5],[1323,5],[1390,5]]},"2860":{"position":[[237,9],[586,8],[611,8],[719,5],[815,5]]},"2864":{"position":[[21,5]]},"2883":{"position":[[33,5]]},"2886":{"position":[[12,5]]},"2897":{"position":[[889,5]]},"2921":{"position":[[200,5]]},"2933":{"position":[[187,7],[324,5]]},"2942":{"position":[[129,9],[145,8],[225,9]]},"2947":{"position":[[5294,6],[5777,7]]},"2949":{"position":[[353,5]]},"2975":{"position":[[143,9]]},"3071":{"position":[[1369,6]]},"3150":{"position":[[478,5]]},"3154":{"position":[[126,8],[209,5]]},"3210":{"position":[[441,5]]},"3224":{"position":[[342,6],[1256,8]]},"3251":{"position":[[501,6],[801,6],[1027,6],[2670,8],[3462,6],[3739,6],[4280,6],[5026,8]]},"3270":{"position":[[2318,6]]},"3299":{"position":[[5278,6],[5436,7]]},"3301":{"position":[[1491,7],[1991,5],[2164,6],[5393,8]]},"3389":{"position":[[24,5],[241,7],[328,10]]},"3395":{"position":[[79,6],[1475,5]]},"3400":{"position":[[231,9]]},"3482":{"position":[[1684,8]]}}}],["offic",{"_index":1229,"t":{"176":{"position":[[591,7]]}}}],["offici",{"_index":1801,"t":{"259":{"position":[[294,8]]},"319":{"position":[[811,8]]},"321":{"position":[[1717,8]]},"323":{"position":[[711,8]]},"325":{"position":[[2200,8],[6297,8]]},"417":{"position":[[537,8]]},"460":{"position":[[179,8],[507,8]]},"462":{"position":[[132,8]]},"469":{"position":[[222,8]]},"471":{"position":[[519,8]]},"472":{"position":[[69,8],[1178,8],[1268,8]]},"489":{"position":[[801,8]]},"590":{"position":[[2301,8]]},"592":{"position":[[302,8]]},"594":{"position":[[263,8]]},"596":{"position":[[673,8]]},"772":{"position":[[207,8]]},"883":{"position":[[381,8]]},"907":{"position":[[79,8]]},"1100":{"position":[[4,8]]},"1395":{"position":[[4,8]]},"1594":{"position":[[502,8],[621,8]]},"1629":{"position":[[79,8]]},"1726":{"position":[[4,8]]},"2302":{"position":[[41,10]]},"2354":{"position":[[79,8]]},"2405":{"position":[[102,10],[166,10]]},"2631":{"position":[[1357,8]]},"2688":{"position":[[255,8]]},"2713":{"position":[[1879,8]]},"2756":{"position":[[1625,8]]},"2858":{"position":[[1615,8]]},"3053":{"position":[[206,8]]},"3059":{"position":[[190,8],[812,8]]},"3124":{"position":[[249,10]]},"3126":{"position":[[498,8]]},"3128":{"position":[[887,8],[1000,8]]},"3130":{"position":[[59,8]]},"3160":{"position":[[2749,10]]},"3173":{"position":[[69,8]]},"3270":{"position":[[833,8]]}}}],["offlin",{"_index":7765,"t":{"1835":{"position":[[84,8]]},"1841":{"position":[[186,7]]},"2688":{"position":[[1425,8]]},"3208":{"position":[[622,7]]},"3210":{"position":[[520,7],[574,7]]},"3224":{"position":[[349,7]]}}}],["og",{"_index":4340,"t":{"903":{"position":[[1509,2]]},"1625":{"position":[[1509,2]]},"2350":{"position":[[1509,2]]}}}],["ogth7hi2zywrs5tnaik/qlvsb7am+lqrp7lmlm4jmd6woyr7dishu7omd1gqem2zumgga",{"_index":2088,"t":{"325":{"position":[[4494,69]]}}}],["oh",{"_index":7259,"t":{"1721":{"position":[[3476,2]]}}}],["ohm0",{"_index":6672,"t":{"1366":{"position":[[172,5],[645,4],[660,4]]}}}],["oidc",{"_index":1921,"t":{"290":{"position":[[597,5]]},"298":{"position":[[707,4]]},"300":{"position":[[25,4]]},"302":{"position":[[1213,4]]},"306":{"position":[[73,4]]},"308":{"position":[[77,4]]},"932":{"position":[[1497,4],[4225,4]]},"1654":{"position":[[1497,4],[4225,4]]},"1791":{"position":[[35,6],[110,4],[170,5],[195,5],[646,4],[1860,5]]},"1939":{"position":[[131,4],[209,4]]},"1943":{"position":[[144,4]]},"1947":{"position":[[38,4]]},"1951":{"position":[[290,4]]},"1957":{"position":[[229,5],[321,4],[383,4],[495,5],[514,4],[713,4],[1121,4],[2365,5],[2776,4],[2830,4],[3552,4],[3639,4],[4227,4]]},"1959":{"position":[[647,4],[1096,4]]},"2033":{"position":[[1890,4]]},"2176":{"position":[[710,4]]},"2196":{"position":[[241,5]]},"2220":{"position":[[45,4]]},"2224":{"position":[[68,4]]},"2239":{"position":[[0,4],[35,4]]},"2379":{"position":[[1497,4],[4225,4]]},"2409":{"position":[[60,4]]},"3247":{"position":[[283,6],[404,5]]},"3251":{"position":[[1018,5],[3550,5],[3972,6]]},"3301":{"position":[[5900,5]]},"3314":{"position":[[187,6]]},"3316":{"position":[[661,5],[1412,4]]},"3325":{"position":[[2569,4],[3487,4],[3522,4]]}}}],["oif",{"_index":8439,"t":{"2265":{"position":[[158,3]]},"2298":{"position":[[158,3]]},"2306":{"position":[[508,4]]},"2338":{"position":[[464,4]]},"2434":{"position":[[356,3]]}}}],["oin",{"_index":1243,"t":{"176":{"position":[[1207,5],[1736,3]]}}}],["ojsonpath",{"_index":3004,"t":{"590":{"position":[[879,12],[958,12]]}}}],["ok",{"_index":6356,"t":{"1317":{"position":[[7891,2],[8988,2]]},"2951":{"position":[[1079,2]]}}}],["okay",{"_index":9656,"t":{"2968":{"position":[[199,4]]}}}],["okd",{"_index":8260,"t":{"2126":{"position":[[180,4]]}}}],["old",{"_index":89,"t":{"10":{"position":[[297,3]]},"602":{"position":[[205,3]]},"604":{"position":[[1983,3],[2301,3],[3795,3],[3835,3]]},"609":{"position":[[20,3]]},"652":{"position":[[843,3],[934,3],[1192,3]]},"662":{"position":[[348,5]]},"1756":{"position":[[142,3],[216,3]]},"1833":{"position":[[1188,3]]},"1900":{"position":[[161,3]]},"2016":{"position":[[161,3]]},"2321":{"position":[[377,3]]},"2328":{"position":[[14,3]]},"2407":{"position":[[4,3]]},"2420":{"position":[[92,3]]},"2468":{"position":[[435,3]]},"2631":{"position":[[1883,3]]},"2635":{"position":[[696,3]]},"2656":{"position":[[4,3]]},"2725":{"position":[[661,3],[856,3]]},"2735":{"position":[[827,3],[1181,3],[1516,3]]},"2764":{"position":[[882,3],[1077,3]]},"2774":{"position":[[829,3],[1183,3],[1518,3]]},"2850":{"position":[[554,3],[749,3]]},"2895":{"position":[[372,3],[3978,3],[4590,3]]},"3351":{"position":[[213,3]]},"3363":{"position":[[164,3]]},"3376":{"position":[[783,3]]}}}],["old_instance_s",{"_index":8931,"t":{"2566":{"position":[[12609,18]]}}}],["old_stat",{"_index":8704,"t":{"2566":{"position":[[1254,10]]}}}],["old_volume_s",{"_index":8927,"t":{"2566":{"position":[[12400,16]]}}}],["older",{"_index":2165,"t":{"339":{"position":[[308,5]]},"604":{"position":[[1670,5],[10979,5]]},"796":{"position":[[445,5]]},"798":{"position":[[1334,5]]},"838":{"position":[[21,5],[152,5]]},"1017":{"position":[[415,5]]},"1112":{"position":[[757,5]]},"1226":{"position":[[1486,5]]},"1462":{"position":[[765,5]]},"1533":{"position":[[445,5]]},"1535":{"position":[[1334,5]]},"1553":{"position":[[21,5],[152,5]]},"1569":{"position":[[237,5]]},"2405":{"position":[[202,5]]},"2656":{"position":[[99,5]]},"2809":{"position":[[581,5]]}}}],["olderthan=2023",{"_index":2646,"t":{"472":{"position":[[2406,14]]}}}],["oldest",{"_index":9879,"t":{"3124":{"position":[[274,6]]}}}],["olso",{"_index":10234,"t":{"3465":{"position":[[1119,4]]}}}],["omap",{"_index":6902,"t":{"1444":{"position":[[29,4],[315,4],[406,4]]}}}],["omit",{"_index":3312,"t":{"629":{"position":[[868,4]]},"652":{"position":[[1025,8]]},"2709":{"position":[[243,7]]},"2713":{"position":[[1167,8]]},"2754":{"position":[[243,7]]},"2756":{"position":[[884,8]]},"2844":{"position":[[171,7]]},"2858":{"position":[[977,8]]},"3457":{"position":[[660,8]]}}}],["on",{"_index":612,"t":{"91":{"position":[[115,3],[160,3],[211,3]]},"101":{"position":[[656,3],[679,3]]},"105":{"position":[[348,3]]},"174":{"position":[[65,3]]},"178":{"position":[[104,4]]},"184":{"position":[[237,3]]},"193":{"position":[[212,5],[839,5]]},"231":{"position":[[515,3]]},"247":{"position":[[2410,4]]},"251":{"position":[[424,3]]},"284":{"position":[[341,3]]},"317":{"position":[[126,3],[248,3],[612,3]]},"321":{"position":[[39,3],[665,3]]},"325":{"position":[[209,4],[5472,3],[5962,3]]},"327":{"position":[[415,4]]},"342":{"position":[[66,3]]},"370":{"position":[[226,4]]},"374":{"position":[[343,3],[390,3],[477,3]]},"393":{"position":[[45,3]]},"396":{"position":[[401,3]]},"413":{"position":[[76,4]]},"417":{"position":[[274,3],[392,3],[688,3]]},"428":{"position":[[48,3]]},"474":{"position":[[724,3]]},"485":{"position":[[371,3],[429,3]]},"487":{"position":[[5011,3]]},"497":{"position":[[557,3]]},"501":{"position":[[84,3],[612,3]]},"509":{"position":[[688,3]]},"513":{"position":[[628,3],[640,3]]},"525":{"position":[[35,3]]},"602":{"position":[[209,4]]},"604":{"position":[[708,3],[3161,3],[3168,4],[3839,3],[4352,3]]},"627":{"position":[[4354,3]]},"633":{"position":[[3637,3]]},"646":{"position":[[1173,3]]},"648":{"position":[[643,3],[896,3]]},"652":{"position":[[938,3]]},"654":{"position":[[69,3]]},"700":{"position":[[111,3]]},"716":{"position":[[100,3]]},"718":{"position":[[51,3]]},"732":{"position":[[55,3],[71,3]]},"738":{"position":[[45,3],[148,3],[188,3]]},"742":{"position":[[520,3],[552,3]]},"744":{"position":[[263,3]]},"762":{"position":[[255,3]]},"780":{"position":[[57,3]]},"798":{"position":[[170,3]]},"883":{"position":[[305,3]]},"903":{"position":[[2275,3]]},"909":{"position":[[411,3],[761,3]]},"911":{"position":[[863,3]]},"913":{"position":[[2728,3],[2751,3]]},"915":{"position":[[143,3]]},"920":{"position":[[217,3],[931,3]]},"922":{"position":[[1316,3]]},"932":{"position":[[2961,3],[3097,3]]},"934":{"position":[[1007,4]]},"949":{"position":[[841,4]]},"954":{"position":[[309,3]]},"1055":{"position":[[1257,3],[2590,3]]},"1071":{"position":[[934,3],[1100,3]]},"1110":{"position":[[421,3],[454,3]]},"1124":{"position":[[398,3]]},"1165":{"position":[[2655,3]]},"1184":{"position":[[446,3]]},"1252":{"position":[[1157,3]]},"1292":{"position":[[585,3],[732,3]]},"1388":{"position":[[144,3]]},"1462":{"position":[[780,3],[845,3]]},"1493":{"position":[[55,3],[71,3]]},"1535":{"position":[[170,3]]},"1564":{"position":[[132,3]]},"1569":{"position":[[289,3]]},"1578":{"position":[[83,3]]},"1585":{"position":[[515,3]]},"1608":{"position":[[253,3]]},"1625":{"position":[[2275,3]]},"1631":{"position":[[411,3],[761,3]]},"1633":{"position":[[863,3]]},"1635":{"position":[[2728,3],[2751,3]]},"1637":{"position":[[143,3]]},"1642":{"position":[[217,3],[931,3]]},"1644":{"position":[[1316,3]]},"1654":{"position":[[2961,3],[3097,3]]},"1656":{"position":[[1007,4]]},"1671":{"position":[[841,4]]},"1676":{"position":[[611,3],[637,3]]},"1747":{"position":[[258,3]]},"1756":{"position":[[248,4]]},"1764":{"position":[[3854,3],[4137,3]]},"1773":{"position":[[48,3]]},"1779":{"position":[[3836,3]]},"1827":{"position":[[274,3],[601,3]]},"1829":{"position":[[286,3],[365,3]]},"1835":{"position":[[463,4]]},"1845":{"position":[[185,3],[383,4],[633,3]]},"1855":{"position":[[1204,3],[1309,3]]},"1857":{"position":[[1025,3]]},"1880":{"position":[[747,3],[754,3]]},"1908":{"position":[[157,3]]},"1911":{"position":[[126,3]]},"1917":{"position":[[1204,3],[1309,3]]},"1919":{"position":[[1025,3]]},"1951":{"position":[[304,3]]},"1955":{"position":[[384,3]]},"1957":{"position":[[46,3],[159,3],[3541,3]]},"1959":{"position":[[933,4]]},"1982":{"position":[[845,3]]},"1984":{"position":[[455,3]]},"1996":{"position":[[747,3],[754,3]]},"2024":{"position":[[157,3]]},"2027":{"position":[[126,3]]},"2053":{"position":[[845,4]]},"2098":{"position":[[1452,3]]},"2100":{"position":[[980,3]]},"2150":{"position":[[504,3]]},"2176":{"position":[[260,3]]},"2196":{"position":[[812,3]]},"2296":{"position":[[73,3]]},"2310":{"position":[[558,3]]},"2334":{"position":[[190,3]]},"2350":{"position":[[2275,3]]},"2356":{"position":[[411,3],[761,3]]},"2358":{"position":[[863,3]]},"2360":{"position":[[2728,3],[2751,3]]},"2362":{"position":[[143,3]]},"2367":{"position":[[217,3],[931,3]]},"2369":{"position":[[1316,3]]},"2379":{"position":[[2961,3],[3097,3]]},"2381":{"position":[[1007,4]]},"2396":{"position":[[841,4]]},"2461":{"position":[[395,3],[415,3]]},"2504":{"position":[[384,3]]},"2522":{"position":[[666,3]]},"2560":{"position":[[100,3]]},"2621":{"position":[[0,3]]},"2625":{"position":[[435,3],[871,3],[1778,3],[1854,3],[1925,3]]},"2631":{"position":[[224,3],[937,3],[1659,3]]},"2635":{"position":[[415,3]]},"2637":{"position":[[348,3]]},"2639":{"position":[[107,3]]},"2642":{"position":[[65,3]]},"2647":{"position":[[108,3]]},"2673":{"position":[[1333,3],[1378,3],[1429,3]]},"2684":{"position":[[304,3]]},"2711":{"position":[[1297,3]]},"2719":{"position":[[1626,3]]},"2731":{"position":[[978,3]]},"2758":{"position":[[1627,3],[1775,4]]},"2770":{"position":[[978,3]]},"2783":{"position":[[694,3]]},"2795":{"position":[[1202,5],[1598,3]]},"2809":{"position":[[759,3],[880,3],[960,3]]},"2813":{"position":[[321,3]]},"2817":{"position":[[127,3],[218,3]]},"2822":{"position":[[34,3]]},"2856":{"position":[[1274,3]]},"2860":{"position":[[939,3]]},"2872":{"position":[[1007,3]]},"2874":{"position":[[490,4]]},"2909":{"position":[[184,3]]},"2923":{"position":[[169,3],[378,3]]},"2931":{"position":[[285,3]]},"2933":{"position":[[828,3]]},"2944":{"position":[[1359,3]]},"2947":{"position":[[0,3],[62,3],[110,3],[1039,3],[2724,4],[4383,3]]},"2951":{"position":[[727,4]]},"2960":{"position":[[1528,3]]},"2966":{"position":[[1362,3],[1903,3],[4031,3],[4055,3]]},"2981":{"position":[[93,3]]},"2983":{"position":[[546,3]]},"2985":{"position":[[511,3],[723,3]]},"2992":{"position":[[211,3]]},"3011":{"position":[[1744,3]]},"3029":{"position":[[580,4]]},"3031":{"position":[[464,3],[558,3]]},"3037":{"position":[[33,3]]},"3046":{"position":[[0,3]]},"3050":{"position":[[273,3]]},"3057":{"position":[[171,3]]},"3078":{"position":[[485,3]]},"3084":{"position":[[438,4]]},"3101":{"position":[[52,3]]},"3132":{"position":[[191,3]]},"3135":{"position":[[311,3]]},"3150":{"position":[[316,4]]},"3154":{"position":[[100,3]]},"3178":{"position":[[163,3]]},"3184":{"position":[[860,3],[1460,3],[2480,3]]},"3186":{"position":[[814,4]]},"3191":{"position":[[156,3]]},"3197":{"position":[[1050,3]]},"3199":{"position":[[613,3]]},"3218":{"position":[[445,3]]},"3247":{"position":[[166,3]]},"3249":{"position":[[781,3],[985,3]]},"3251":{"position":[[4861,3]]},"3253":{"position":[[117,3]]},"3255":{"position":[[272,3]]},"3284":{"position":[[202,3],[229,3],[257,3],[287,3]]},"3299":{"position":[[460,3]]},"3301":{"position":[[2208,3],[3570,3],[4337,3]]},"3310":{"position":[[499,4]]},"3343":{"position":[[217,3]]},"3351":{"position":[[188,3],[217,3]]},"3374":{"position":[[391,3]]},"3461":{"position":[[267,3]]},"3482":{"position":[[1179,3]]}}}],["on_behalf_of",{"_index":8954,"t":{"2566":{"position":[[14549,13]]}}}],["on_image_delet",{"_index":7962,"t":{"1904":{"position":[[722,18]]},"2020":{"position":[[722,18]]}}}],["onboar",{"_index":10140,"t":{"3325":{"position":[[232,9]]}}}],["onboard",{"_index":1809,"t":{"263":{"position":[[327,7],[366,10],[393,10]]},"988":{"position":[[490,7]]},"2476":{"position":[[26,10]]},"2574":{"position":[[627,10]]},"2576":{"position":[[255,10]]},"3245":{"position":[[462,10]]},"3251":{"position":[[2256,7]]},"3325":{"position":[[302,9]]},"3518":{"position":[[2258,10]]}}}],["onc",{"_index":760,"t":{"114":{"position":[[602,4]]},"158":{"position":[[648,4]]},"164":{"position":[[75,4]]},"225":{"position":[[73,4]]},"383":{"position":[[186,4]]},"389":{"position":[[342,4]]},"396":{"position":[[496,4]]},"398":{"position":[[390,4]]},"513":{"position":[[891,4]]},"530":{"position":[[242,4]]},"586":{"position":[[106,4]]},"604":{"position":[[1294,4]]},"627":{"position":[[1877,4],[5028,4]]},"805":{"position":[[220,4]]},"819":{"position":[[215,4]]},"911":{"position":[[1691,4]]},"920":{"position":[[709,4]]},"947":{"position":[[2109,4]]},"1075":{"position":[[0,4]]},"1236":{"position":[[205,4]]},"1471":{"position":[[1841,5]]},"1509":{"position":[[215,4]]},"1542":{"position":[[220,4]]},"1633":{"position":[[1691,4]]},"1642":{"position":[[709,4]]},"1669":{"position":[[2109,4]]},"1740":{"position":[[166,4]]},"1783":{"position":[[198,4]]},"1894":{"position":[[105,4]]},"1908":{"position":[[1451,4],[2874,4],[3127,4]]},"1957":{"position":[[1691,4]]},"2010":{"position":[[105,4]]},"2024":{"position":[[1451,4],[2874,4],[3127,4]]},"2041":{"position":[[453,4]]},"2045":{"position":[[106,5]]},"2144":{"position":[[0,4]]},"2358":{"position":[[1691,4]]},"2367":{"position":[[709,4]]},"2394":{"position":[[2109,4]]},"2436":{"position":[[132,4]]},"2631":{"position":[[2105,4]]},"2635":{"position":[[0,4]]},"2688":{"position":[[1054,4],[2058,4]]},"2809":{"position":[[405,4]]},"2895":{"position":[[848,4],[909,4],[971,4],[1030,4],[1087,4],[4506,4]]},"2944":{"position":[[519,4]]},"2992":{"position":[[415,4]]},"3014":{"position":[[474,4]]},"3050":{"position":[[248,6]]},"3055":{"position":[[355,4]]},"3078":{"position":[[364,4]]},"3160":{"position":[[2211,4]]},"3284":{"position":[[385,4]]},"3314":{"position":[[801,5]]},"3457":{"position":[[172,4]]}}}],["ones—to",{"_index":8597,"t":{"2514":{"position":[[229,7]]}}}],["ongo",{"_index":9740,"t":{"3071":{"position":[[957,7]]}}}],["onlin",{"_index":4657,"t":{"956":{"position":[[687,7]]},"1406":{"position":[[127,6]]},"1473":{"position":[[823,6]]},"2688":{"position":[[1318,6]]}}}],["onto",{"_index":7115,"t":{"1591":{"position":[[149,4]]},"1908":{"position":[[626,4],[1720,4],[2936,4]]},"2024":{"position":[[626,4],[1720,4],[2936,4]]},"2073":{"position":[[113,4]]},"3084":{"position":[[37,4]]}}}],["onward",{"_index":6162,"t":{"1290":{"position":[[29,8]]},"1292":{"position":[[29,8]]},"3270":{"position":[[1105,8]]}}}],["op",{"_index":2173,"t":{"344":{"position":[[18,3]]},"1728":{"position":[[569,2]]},"1957":{"position":[[388,3],[1126,2],[3060,2],[3557,2],[3644,2],[4232,2]]},"2214":{"position":[[439,3]]},"2625":{"position":[[1621,3],[1957,3]]},"2629":{"position":[[383,4]]},"3518":{"position":[[2365,3],[2415,3],[2483,3],[2534,3],[2640,3],[2695,3],[2762,3]]}}}],["open",{"_index":3,"t":{"4":{"position":[[28,4],[133,5],[365,4]]},"69":{"position":[[153,4],[276,4]]},"71":{"position":[[120,4]]},"79":{"position":[[407,8]]},"151":{"position":[[304,4]]},"164":{"position":[[166,4]]},"166":{"position":[[432,4]]},"168":{"position":[[1298,4]]},"170":{"position":[[338,4],[1287,4],[1662,4],[1795,4],[1928,4],[2185,4]]},"176":{"position":[[364,4],[693,4],[1184,4],[1350,4],[1463,4],[1582,4]]},"178":{"position":[[9,4],[365,4],[516,4],[2359,5]]},"180":{"position":[[25,4]]},"182":{"position":[[215,4]]},"184":{"position":[[716,4]]},"235":{"position":[[108,4],[253,4],[1126,4]]},"238":{"position":[[33,5],[165,5]]},"240":{"position":[[0,4],[27,4],[155,4],[172,4],[212,4],[320,4]]},"242":{"position":[[16,4],[28,4],[260,4],[341,4],[389,5],[416,4],[512,4]]},"245":{"position":[[269,5],[377,6],[391,4],[502,4],[578,5],[584,4],[623,4]]},"249":{"position":[[308,7]]},"253":{"position":[[367,4],[529,4],[687,4],[1205,4],[1323,4]]},"257":{"position":[[19,4]]},"263":{"position":[[183,7]]},"325":{"position":[[7260,5]]},"342":{"position":[[136,4]]},"366":{"position":[[363,4],[1265,4]]},"368":{"position":[[383,4]]},"379":{"position":[[804,5]]},"393":{"position":[[531,4]]},"436":{"position":[[152,4]]},"469":{"position":[[90,4]]},"493":{"position":[[154,6],[950,6]]},"542":{"position":[[48,4],[121,5],[167,4]]},"633":{"position":[[3620,4]]},"694":{"position":[[57,4]]},"766":{"position":[[4,4]]},"768":{"position":[[11,4]]},"772":{"position":[[769,4]]},"880":{"position":[[11,4],[803,4]]},"909":{"position":[[643,4],[1692,4]]},"954":{"position":[[4,4]]},"977":{"position":[[47,4],[2445,4]]},"988":{"position":[[345,4]]},"1284":{"position":[[0,4],[75,4],[549,4]]},"1286":{"position":[[647,4]]},"1305":{"position":[[150,4],[226,4],[304,4],[377,4],[464,4]]},"1364":{"position":[[20,4]]},"1366":{"position":[[67,4]]},"1594":{"position":[[79,4]]},"1631":{"position":[[643,4],[1692,4]]},"1773":{"position":[[547,4]]},"1791":{"position":[[201,4]]},"1820":{"position":[[0,4],[86,4],[554,4]]},"1827":{"position":[[456,4]]},"1857":{"position":[[329,6]]},"1919":{"position":[[329,6]]},"1957":{"position":[[556,4],[806,4],[971,4],[2688,4],[3251,4]]},"1970":{"position":[[22,4],[473,4]]},"1972":{"position":[[29,4]]},"2075":{"position":[[66,4]]},"2235":{"position":[[74,4]]},"2265":{"position":[[416,5]]},"2281":{"position":[[180,4]]},"2294":{"position":[[134,4]]},"2298":{"position":[[416,5]]},"2306":{"position":[[373,4]]},"2310":{"position":[[293,5],[335,6]]},"2338":{"position":[[329,4]]},"2356":{"position":[[643,4],[1692,4]]},"2422":{"position":[[145,4]]},"2434":{"position":[[320,4]]},"2514":{"position":[[270,9]]},"2520":{"position":[[252,4]]},"2522":{"position":[[221,4]]},"2617":{"position":[[267,8]]},"2627":{"position":[[836,4],[895,4]]},"2795":{"position":[[413,4],[1237,4]]},"2805":{"position":[[70,4],[223,4],[376,4]]},"2815":{"position":[[10,4],[107,4]]},"3063":{"position":[[782,4]]},"3082":{"position":[[1042,4],[1435,4]]},"3103":{"position":[[934,7],[1063,7]]},"3158":{"position":[[246,4],[413,5],[434,4],[460,4],[501,5],[525,5]]},"3251":{"position":[[94,4],[3243,4]]},"3293":{"position":[[449,4]]},"3295":{"position":[[169,4]]},"3299":{"position":[[6,4],[923,4],[1167,6],[1189,4],[1248,5],[1439,4],[1532,4],[2653,6],[2675,4],[2734,4],[2878,4],[2971,4],[3873,6],[3895,4],[3954,4],[4017,4],[4108,4],[4224,4],[5188,5],[5254,4],[5368,4]]},"3301":{"position":[[41,4],[201,4],[257,4],[395,4],[476,4],[1019,4],[1655,4],[2595,4],[3494,4],[4068,4],[4114,4],[4564,4]]},"3376":{"position":[[832,4]]},"3518":{"position":[[64,4]]}}}],["open('image.key",{"_index":7982,"t":{"1913":{"position":[[1407,17]]},"2029":{"position":[[1407,17]]}}}],["openapi",{"_index":8352,"t":{"2164":{"position":[[751,7],[779,7]]},"2315":{"position":[[762,7]]},"2602":{"position":[[660,7]]},"3336":{"position":[[19,7]]},"3403":{"position":[[71,7]]},"3408":{"position":[[138,7]]},"3518":{"position":[[2499,7]]}}}],["opendev",{"_index":7425,"t":{"1749":{"position":[[795,7]]},"1951":{"position":[[165,7],[566,7]]}}}],["opendevorg",{"_index":7424,"t":{"1749":{"position":[[777,11],[897,11]]}}}],["opendistro",{"_index":6233,"t":{"1305":{"position":[[382,11]]}}}],["openid",{"_index":1916,"t":{"290":{"position":[[271,6]]},"292":{"position":[[102,6]]},"296":{"position":[[132,6]]},"298":{"position":[[136,6],[343,6]]},"304":{"position":[[41,6],[136,6]]},"1791":{"position":[[20,6],[1790,6],[2385,6],[2580,6],[3190,6],[3346,6],[3359,7]]},"1937":{"position":[[273,6]]},"1945":{"position":[[83,6]]},"1947":{"position":[[154,6]]},"1951":{"position":[[903,6]]},"1957":{"position":[[668,6],[1071,6],[1315,6]]},"2248":{"position":[[994,6]]},"2476":{"position":[[560,7],[807,6]]},"2493":{"position":[[44,6]]},"3247":{"position":[[268,6]]},"3251":{"position":[[3603,6]]}}}],["openinfra",{"_index":4651,"t":{"954":{"position":[[39,9]]},"2514":{"position":[[141,9]]}}}],["openldap",{"_index":9998,"t":{"3251":{"position":[[1449,9]]}}}],["openrc",{"_index":147,"t":{"10":{"position":[[1403,6]]},"1146":{"position":[[21,6]]}}}],["openrc.sh",{"_index":159,"t":{"10":{"position":[[1540,9]]},"467":{"position":[[495,9]]},"1843":{"position":[[79,9]]}}}],["opensearch",{"_index":5038,"t":{"1082":{"position":[[27,10],[80,10],[138,10],[214,10]]},"1167":{"position":[[32,10],[77,10],[150,10],[238,10],[295,10],[519,16],[782,10],[872,10],[1978,11],[2427,10],[2648,10],[3369,10],[3445,10],[4325,13],[4691,10],[4962,13]]},"1250":{"position":[[132,10],[143,10],[191,10],[228,10],[251,10]]},"1305":{"position":[[231,11]]},"1321":{"position":[[0,10],[48,10]]},"1564":{"position":[[171,11],[492,10]]},"1576":{"position":[[725,10],[779,10]]},"1762":{"position":[[0,10],[11,10],[59,10],[96,10],[130,10]]},"1779":{"position":[[5466,10]]},"1789":{"position":[[1274,10],[1331,10]]},"1814":{"position":[[254,10]]}}}],["opensearch.yml",{"_index":5851,"t":{"1167":{"position":[[420,18],[555,18],[2252,17],[2567,14]]}}}],["opensearch.yml.j2",{"_index":5858,"t":{"1167":{"position":[[825,17],[897,17],[2402,17]]}}}],["opensearch/opensearch.yml",{"_index":5852,"t":{"1167":{"position":[[464,29],[606,29]]}}}],["opensearch:opensearch",{"_index":5912,"t":{"1167":{"position":[[4418,24],[4510,24],[5055,24],[5147,24]]}}}],["opensearch_cluster_nam",{"_index":5870,"t":{"1167":{"position":[[1279,23]]}}}],["opensearch_port",{"_index":5877,"t":{"1167":{"position":[[1683,15]]}}}],["opensearch_services['opensearch'].en",{"_index":5856,"t":{"1167":{"position":[[715,41]]}}}],["openshift",{"_index":3048,"t":{"596":{"position":[[508,9]]},"954":{"position":[[650,9]]}}}],["openssh",{"_index":4774,"t":{"1019":{"position":[[146,7]]},"1234":{"position":[[2924,7]]},"1339":{"position":[[11,7]]}}}],["openssl",{"_index":8496,"t":{"2326":{"position":[[190,7]]},"2870":{"position":[[300,7]]}}}],["openst",{"_index":7339,"t":{"1731":{"position":[[2644,8]]}}}],["openstack",{"_index":83,"t":{"10":{"position":[[164,9],[1247,9],[1499,9],[1568,9],[1616,9],[1761,9],[1800,9],[1856,9],[1866,9]]},"12":{"position":[[33,9]]},"14":{"position":[[0,9]]},"48":{"position":[[25,9]]},"55":{"position":[[26,9]]},"105":{"position":[[148,9]]},"288":{"position":[[212,9]]},"292":{"position":[[54,10],[77,9],[161,10]]},"298":{"position":[[372,9]]},"302":{"position":[[894,9],[989,9],[1106,9],[1320,9],[1473,9]]},"306":{"position":[[11,9]]},"325":{"position":[[2439,9]]},"333":{"position":[[223,9],[355,9],[439,9]]},"335":{"position":[[339,10],[424,12],[1112,9]]},"337":{"position":[[0,9],[60,9]]},"347":{"position":[[388,9]]},"353":{"position":[[296,10]]},"363":{"position":[[27,9],[289,10],[380,9]]},"368":{"position":[[429,10]]},"383":{"position":[[34,9]]},"391":{"position":[[159,10],[1085,10]]},"393":{"position":[[986,9],[1283,9],[1435,9]]},"398":{"position":[[79,9],[243,9],[274,9]]},"404":{"position":[[721,9],[954,11]]},"421":{"position":[[164,9]]},"467":{"position":[[155,9],[339,9],[366,9],[459,9],[1203,9],[1962,9],[2567,9]]},"481":{"position":[[102,10]]},"483":{"position":[[179,9],[623,9]]},"485":{"position":[[289,9]]},"487":{"position":[[3723,9],[4259,9]]},"495":{"position":[[295,9],[330,9],[437,9],[492,9],[1182,9],[1217,9],[1324,9],[1379,9]]},"497":{"position":[[15,9],[91,9],[224,9],[272,9]]},"501":{"position":[[154,9]]},"505":{"position":[[524,10]]},"507":{"position":[[659,9]]},"509":{"position":[[247,9],[446,9]]},"513":{"position":[[1256,9],[1361,9],[1876,9]]},"519":{"position":[[22,9]]},"521":{"position":[[297,9]]},"530":{"position":[[780,11]]},"536":{"position":[[5,9],[29,9]]},"540":{"position":[[49,9]]},"542":{"position":[[53,9]]},"546":{"position":[[61,10]]},"552":{"position":[[66,9]]},"554":{"position":[[115,9]]},"590":{"position":[[658,9],[2515,9]]},"600":{"position":[[1068,9],[1285,9]]},"604":{"position":[[1712,9],[2819,9],[5373,9],[5411,9],[5472,9],[9991,9]]},"606":{"position":[[299,9]]},"609":{"position":[[2698,9],[5398,9]]},"617":{"position":[[244,9],[670,9],[860,9],[1108,9],[1151,9]]},"619":{"position":[[236,10]]},"627":{"position":[[1295,9],[1803,10],[3853,9]]},"639":{"position":[[530,9],[564,10],[683,10],[818,9]]},"650":{"position":[[0,9],[264,9]]},"660":{"position":[[761,9],[1349,9],[1384,9],[2636,9],[2782,9]]},"726":{"position":[[4,9]]},"728":{"position":[[4,9],[209,9],[371,9],[463,9]]},"730":{"position":[[76,9],[452,9],[491,9],[1043,9],[1148,9],[1492,9],[1544,9],[1585,9]]},"732":{"position":[[247,9],[431,9]]},"740":{"position":[[176,9]]},"744":{"position":[[52,9],[87,9],[148,9]]},"756":{"position":[[161,9]]},"760":{"position":[[5,9],[579,9]]},"762":{"position":[[6,9],[107,9]]},"764":{"position":[[4,9],[102,9]]},"766":{"position":[[88,9]]},"772":{"position":[[4,9],[76,10],[184,9],[545,9],[858,9]]},"774":{"position":[[0,9]]},"782":{"position":[[4,9],[68,9]]},"784":{"position":[[57,9],[125,9],[200,9]]},"786":{"position":[[4,9],[500,10],[1041,9]]},"790":{"position":[[57,9],[100,9],[137,9],[192,9],[330,9],[449,9],[1329,9],[1397,9],[1434,9],[1466,9]]},"800":{"position":[[472,9]]},"808":{"position":[[4,9],[54,9]]},"810":{"position":[[19,9],[233,9]]},"815":{"position":[[89,9],[343,9]]},"817":{"position":[[76,9],[403,9]]},"819":{"position":[[176,10],[261,9],[3954,9],[5737,9],[5767,9],[5996,9],[6166,9],[6501,9],[7066,10]]},"821":{"position":[[81,9],[172,9]]},"830":{"position":[[19,9],[112,9],[276,9]]},"846":{"position":[[4,9]]},"848":{"position":[[100,9]]},"850":{"position":[[640,9],[1436,9]]},"853":{"position":[[4,9],[60,9]]},"855":{"position":[[19,9],[106,9]]},"859":{"position":[[76,9],[2230,9]]},"865":{"position":[[40,9]]},"878":{"position":[[40,9]]},"880":{"position":[[236,9]]},"883":{"position":[[1040,12]]},"888":{"position":[[1261,10]]},"895":{"position":[[19,9],[1028,9],[1791,9],[2108,9]]},"897":{"position":[[80,9],[284,11]]},"899":{"position":[[629,9]]},"901":{"position":[[439,9],[472,9],[567,9],[651,9]]},"903":{"position":[[39,9],[589,9],[625,9],[692,9],[730,9],[821,9],[929,9],[969,9],[1070,9],[1231,9],[1271,9],[1435,9],[1917,9],[2563,9],[2647,9],[2716,9],[2740,9],[2765,9],[3514,9]]},"905":{"position":[[23,9],[706,9],[1612,9],[1717,9],[1738,9],[1761,9],[1878,9]]},"909":{"position":[[9,9],[172,9],[377,9],[782,9],[1444,9],[1794,9],[1822,9],[2102,9]]},"911":{"position":[[1438,9],[1461,9],[1498,9],[1527,9]]},"913":{"position":[[557,9],[577,9],[3906,11]]},"917":{"position":[[368,9]]},"922":{"position":[[180,9],[1073,9]]},"938":{"position":[[120,9]]},"940":{"position":[[36,9]]},"947":{"position":[[112,9],[539,9]]},"949":{"position":[[257,9]]},"954":{"position":[[110,10],[214,9],[388,10],[546,9],[574,9],[628,9]]},"956":{"position":[[0,9],[399,9],[712,10],[763,9],[970,9],[2125,9]]},"970":{"position":[[44,9]]},"982":{"position":[[61,9]]},"1067":{"position":[[3549,9],[3674,9]]},"1071":{"position":[[1271,10]]},"1084":{"position":[[59,9],[264,10],[370,9],[577,9],[846,9]]},"1118":{"position":[[169,9]]},"1130":{"position":[[114,9]]},"1150":{"position":[[575,9],[729,9],[7106,9],[12575,9],[12659,9],[13159,9]]},"1159":{"position":[[45,9]]},"1165":{"position":[[2123,9]]},"1213":{"position":[[865,9],[918,9]]},"1242":{"position":[[65,9],[97,9]]},"1244":{"position":[[306,9]]},"1248":{"position":[[160,9]]},"1250":{"position":[[99,9]]},"1286":{"position":[[2619,9]]},"1288":{"position":[[109,9],[307,9],[492,9],[632,9]]},"1294":{"position":[[29,9],[70,9],[111,9],[219,9],[369,9],[480,9],[1277,9]]},"1347":{"position":[[2,9],[1471,9]]},"1351":{"position":[[152,9],[639,9],[1279,9],[1349,9],[2044,9],[2163,9]]},"1353":{"position":[[69,9]]},"1356":{"position":[[127,9]]},"1358":{"position":[[76,9],[321,9],[437,9]]},"1360":{"position":[[1080,9]]},"1362":{"position":[[231,9],[322,9],[438,9],[666,9],[1285,9],[1381,9],[1578,9],[2307,9],[2394,9]]},"1364":{"position":[[0,10],[58,9],[760,9]]},"1371":{"position":[[0,9]]},"1373":{"position":[[14,11],[172,9]]},"1375":{"position":[[0,9],[111,9],[1011,9],[1095,9]]},"1377":{"position":[[0,9],[112,9],[1006,9],[1116,9]]},"1383":{"position":[[91,9]]},"1388":{"position":[[79,9]]},"1480":{"position":[[4,9]]},"1482":{"position":[[100,9]]},"1484":{"position":[[640,9],[1436,9]]},"1487":{"position":[[4,9]]},"1489":{"position":[[4,9],[209,9],[371,9],[463,9]]},"1491":{"position":[[76,9],[452,9],[491,9],[1043,9],[1148,9],[1492,9],[1544,9],[1585,9]]},"1493":{"position":[[247,9],[431,9]]},"1498":{"position":[[4,9],[54,9]]},"1500":{"position":[[19,9],[233,9]]},"1505":{"position":[[89,9],[343,9]]},"1507":{"position":[[76,9],[403,9]]},"1509":{"position":[[176,10],[261,9],[3954,9],[5737,9],[5767,9],[5996,9],[6166,9],[6501,9],[7066,10]]},"1511":{"position":[[81,9],[172,9]]},"1519":{"position":[[4,9],[68,9]]},"1521":{"position":[[57,9],[125,9],[200,9]]},"1523":{"position":[[4,9],[500,10],[1041,9]]},"1527":{"position":[[57,9],[100,9],[137,9],[192,9],[330,9],[449,9],[1329,9],[1397,9],[1434,9],[1466,9]]},"1537":{"position":[[472,9]]},"1545":{"position":[[19,9],[112,9],[276,9]]},"1571":{"position":[[1297,9]]},"1576":{"position":[[386,9],[970,9]]},"1578":{"position":[[235,9],[265,10],[276,9],[309,9],[330,9]]},"1580":{"position":[[4,9]]},"1585":{"position":[[3494,9]]},"1597":{"position":[[4,9],[60,9]]},"1599":{"position":[[19,9],[106,9]]},"1603":{"position":[[76,9],[2230,9]]},"1617":{"position":[[19,9],[1028,9],[1791,9],[2108,9]]},"1619":{"position":[[80,9],[284,11]]},"1621":{"position":[[629,9]]},"1623":{"position":[[439,9],[472,9],[567,9],[651,9]]},"1625":{"position":[[39,9],[589,9],[625,9],[692,9],[730,9],[821,9],[929,9],[969,9],[1070,9],[1231,9],[1271,9],[1435,9],[1917,9],[2563,9],[2647,9],[2716,9],[2740,9],[2765,9],[3514,9]]},"1627":{"position":[[23,9],[706,9],[1612,9],[1717,9],[1738,9],[1761,9],[1878,9]]},"1631":{"position":[[9,9],[172,9],[377,9],[782,9],[1444,9],[1794,9],[1822,9],[2102,9]]},"1633":{"position":[[1438,9],[1461,9],[1498,9],[1527,9]]},"1635":{"position":[[557,9],[577,9],[3906,11]]},"1639":{"position":[[368,9]]},"1644":{"position":[[180,9],[1073,9]]},"1660":{"position":[[120,9]]},"1662":{"position":[[36,9]]},"1669":{"position":[[112,9],[539,9]]},"1671":{"position":[[257,9]]},"1674":{"position":[[232,10],[603,9],[621,9]]},"1676":{"position":[[534,9],[615,9],[834,9],[869,9]]},"1731":{"position":[[2591,9],[2653,9]]},"1743":{"position":[[415,9]]},"1770":{"position":[[101,9]]},"1773":{"position":[[69,9],[154,9]]},"1779":{"position":[[151,9],[4079,9],[4881,9],[4978,9],[5380,9],[5535,9],[5984,9],[6185,9],[6261,9],[6496,9]]},"1789":{"position":[[584,9],[673,9],[762,9],[1465,9]]},"1791":{"position":[[126,9],[222,9],[512,9],[1553,9],[1636,9],[1733,9],[1760,9],[1825,9],[2017,9],[2042,9],[2059,9],[2549,9],[2822,9],[2847,9],[2864,9],[3696,9],[3738,9]]},"1794":{"position":[[30,9],[53,9],[196,9],[219,9],[606,9],[629,9],[956,9],[980,9],[1003,9]]},"1796":{"position":[[62,9],[101,9]]},"1798":{"position":[[377,9],[443,9],[512,9],[582,9]]},"1800":{"position":[[186,9],[253,9],[323,9],[394,9]]},"1812":{"position":[[30,9],[163,9],[200,9],[217,9],[244,9]]},"1814":{"position":[[322,10]]},"1822":{"position":[[32,9],[204,9],[1089,9]]},"1827":{"position":[[89,10],[113,9],[590,10]]},"1829":{"position":[[35,9],[393,9],[485,9]]},"1831":{"position":[[88,9]]},"1833":{"position":[[1034,9]]},"1839":{"position":[[182,10]]},"1841":{"position":[[227,10]]},"1843":{"position":[[27,9],[129,9],[277,9],[449,9],[536,9],[558,9],[776,9]]},"1845":{"position":[[167,10],[332,9],[421,9],[696,9],[1659,9],[2502,9]]},"1847":{"position":[[0,9],[686,9]]},"1849":{"position":[[42,9],[818,9]]},"1853":{"position":[[19,9]]},"1859":{"position":[[480,9],[704,9],[902,9]]},"1861":{"position":[[337,9]]},"1863":{"position":[[522,9],[558,9],[692,9],[729,9],[865,9],[903,9],[1040,9],[1077,9]]},"1865":{"position":[[418,9],[609,9],[747,9]]},"1878":{"position":[[1002,9],[1070,9]]},"1880":{"position":[[68,9],[608,9],[634,9]]},"1884":{"position":[[72,9],[99,9],[264,9]]},"1886":{"position":[[293,9],[466,9]]},"1890":{"position":[[244,9]]},"1892":{"position":[[527,9],[680,9],[893,9],[1084,9],[1126,9]]},"1894":{"position":[[385,9],[544,9],[643,9]]},"1896":{"position":[[392,9],[627,9],[1088,9],[1254,10]]},"1900":{"position":[[213,9],[813,9],[1020,9]]},"1902":{"position":[[126,9]]},"1904":{"position":[[362,9]]},"1906":{"position":[[350,9],[568,9],[704,9]]},"1908":{"position":[[704,9],[1163,9],[2357,9],[2735,9],[2945,9]]},"1911":{"position":[[47,10]]},"1913":{"position":[[91,9],[136,9],[318,10],[536,9],[741,9],[873,9],[1149,9]]},"1915":{"position":[[19,9]]},"1921":{"position":[[480,9],[704,9],[902,9]]},"1923":{"position":[[337,9]]},"1925":{"position":[[522,9],[558,9],[692,9],[729,9],[865,9],[903,9],[1040,9],[1077,9]]},"1927":{"position":[[418,9],[609,9],[747,9]]},"1943":{"position":[[214,9],[419,9]]},"1947":{"position":[[226,9]]},"1949":{"position":[[16,9]]},"1951":{"position":[[249,9]]},"1959":{"position":[[1052,9]]},"1972":{"position":[[212,9],[268,9],[301,9],[439,9]]},"1974":{"position":[[189,9]]},"1978":{"position":[[460,9],[700,9]]},"1982":{"position":[[196,9],[334,9]]},"1994":{"position":[[1002,9],[1070,9]]},"1996":{"position":[[68,9],[608,9],[634,9]]},"2000":{"position":[[72,9],[99,9],[264,9]]},"2002":{"position":[[293,9],[466,9]]},"2006":{"position":[[244,9]]},"2008":{"position":[[527,9],[680,9],[893,9],[1084,9],[1126,9]]},"2010":{"position":[[385,9],[544,9],[643,9]]},"2012":{"position":[[392,9],[627,9],[1088,9],[1254,10]]},"2016":{"position":[[213,9],[813,9],[1020,9]]},"2018":{"position":[[126,9]]},"2020":{"position":[[362,9]]},"2022":{"position":[[350,9],[568,9],[704,9]]},"2024":{"position":[[704,9],[1163,9],[2357,9],[2735,9],[2945,9]]},"2027":{"position":[[47,10]]},"2029":{"position":[[91,9],[136,9],[318,10],[536,9],[741,9],[873,9],[1149,9]]},"2031":{"position":[[104,9]]},"2033":{"position":[[60,9],[106,9]]},"2037":{"position":[[78,9]]},"2039":{"position":[[55,9],[911,9]]},"2041":{"position":[[352,9]]},"2045":{"position":[[183,9]]},"2051":{"position":[[420,9]]},"2053":{"position":[[696,9],[1112,9]]},"2055":{"position":[[0,9]]},"2057":{"position":[[115,9]]},"2061":{"position":[[33,9]]},"2063":{"position":[[36,9]]},"2065":{"position":[[34,9],[382,9],[450,9]]},"2067":{"position":[[474,9],[571,9],[680,9],[792,9],[929,9],[1029,9],[1141,9],[1256,9]]},"2087":{"position":[[225,9]]},"2096":{"position":[[35,9],[101,9],[348,9],[479,9],[557,9],[776,9],[1018,9],[1189,9],[1416,9],[1444,9],[1865,9],[2428,9],[2522,9],[2581,9],[2666,9]]},"2190":{"position":[[227,9],[610,10],[700,9]]},"2196":{"position":[[1075,9],[1119,9]]},"2206":{"position":[[197,10]]},"2209":{"position":[[382,9]]},"2212":{"position":[[579,9]]},"2214":{"position":[[32,9]]},"2233":{"position":[[206,9],[340,9],[366,9]]},"2235":{"position":[[439,10],[1125,9],[1140,9]]},"2245":{"position":[[179,9],[621,9]]},"2248":{"position":[[591,9]]},"2257":{"position":[[0,9]]},"2265":{"position":[[131,9],[256,10]]},"2278":{"position":[[170,9],[359,9]]},"2281":{"position":[[30,9],[211,9],[1055,9]]},"2283":{"position":[[400,10],[459,9]]},"2298":{"position":[[131,9],[256,10]]},"2310":{"position":[[837,9]]},"2312":{"position":[[0,9]]},"2315":{"position":[[4,9],[900,9]]},"2321":{"position":[[151,9],[178,9]]},"2326":{"position":[[281,9]]},"2330":{"position":[[589,9]]},"2334":{"position":[[49,9],[112,9]]},"2342":{"position":[[19,9],[1028,9],[1791,9],[2108,9]]},"2344":{"position":[[80,9],[284,11]]},"2346":{"position":[[629,9]]},"2348":{"position":[[439,9],[472,9],[567,9],[651,9]]},"2350":{"position":[[39,9],[589,9],[625,9],[692,9],[730,9],[821,9],[929,9],[969,9],[1070,9],[1231,9],[1271,9],[1435,9],[1917,9],[2563,9],[2647,9],[2716,9],[2740,9],[2765,9],[3514,9]]},"2352":{"position":[[23,9],[706,9],[1612,9],[1717,9],[1738,9],[1761,9],[1878,9]]},"2356":{"position":[[9,9],[172,9],[377,9],[782,9],[1444,9],[1794,9],[1822,9],[2102,9]]},"2358":{"position":[[1438,9],[1461,9],[1498,9],[1527,9]]},"2360":{"position":[[557,9],[577,9],[3906,11]]},"2364":{"position":[[368,9]]},"2369":{"position":[[180,9],[1073,9]]},"2385":{"position":[[120,9]]},"2387":{"position":[[36,9]]},"2394":{"position":[[112,9],[539,9]]},"2396":{"position":[[257,9]]},"2403":{"position":[[59,9]]},"2405":{"position":[[335,9],[793,9]]},"2409":{"position":[[102,9],[270,9],[425,9]]},"2422":{"position":[[243,9]]},"2459":{"position":[[97,9]]},"2461":{"position":[[921,9],[1031,9],[1072,9]]},"2468":{"position":[[369,9],[439,9]]},"2472":{"position":[[203,9]]},"2474":{"position":[[183,9]]},"2476":{"position":[[842,9]]},"2493":{"position":[[18,9]]},"2502":{"position":[[436,9]]},"2504":{"position":[[353,9]]},"2536":{"position":[[93,9]]},"2550":{"position":[[102,9]]},"2576":{"position":[[641,9]]},"2651":{"position":[[351,9]]},"2667":{"position":[[17,9]]},"2697":{"position":[[3,9],[165,9],[268,10]]},"2711":{"position":[[1466,9]]},"2715":{"position":[[188,9],[287,11],[451,9]]},"2717":{"position":[[4,9]]},"2737":{"position":[[146,9],[240,9]]},"2742":{"position":[[3,9],[165,9],[268,10]]},"2776":{"position":[[146,9],[240,9]]},"2783":{"position":[[385,9],[481,11],[631,9]]},"2790":{"position":[[50,9]]},"2832":{"position":[[3,9],[165,9],[268,10]]},"2856":{"position":[[1444,9]]},"2862":{"position":[[188,9],[287,11]]},"2892":{"position":[[87,12],[155,9],[522,9]]},"2909":{"position":[[213,10]]},"2915":{"position":[[40,9]]},"2921":{"position":[[3,9],[165,9],[268,10]]},"2933":{"position":[[997,9]]},"2935":{"position":[[155,9]]},"2937":{"position":[[4,9]]},"2951":{"position":[[31,9],[119,9]]},"2953":{"position":[[17,9]]},"2960":{"position":[[11,9]]},"2962":{"position":[[566,10]]},"2964":{"position":[[161,9]]},"2966":{"position":[[471,10],[562,10],[635,9]]},"2994":{"position":[[153,9]]},"2996":{"position":[[4,9]]},"3001":{"position":[[46,9]]},"3003":{"position":[[28,10],[87,9]]},"3005":{"position":[[30,9]]},"3021":{"position":[[95,10],[417,9]]},"3023":{"position":[[92,9]]},"3029":{"position":[[242,9]]},"3033":{"position":[[52,9],[159,9]]},"3042":{"position":[[369,9]]},"3050":{"position":[[73,9]]},"3074":{"position":[[24,11]]},"3076":{"position":[[215,9]]},"3078":{"position":[[177,9],[1156,9]]},"3080":{"position":[[391,9]]},"3082":{"position":[[90,9],[1172,9],[1612,9]]},"3084":{"position":[[54,9]]},"3088":{"position":[[130,9]]},"3090":{"position":[[142,9]]},"3092":{"position":[[131,9]]},"3097":{"position":[[24,11]]},"3099":{"position":[[425,10]]},"3101":{"position":[[339,9]]},"3107":{"position":[[235,9]]},"3109":{"position":[[309,9],[1425,9],[2577,9]]},"3251":{"position":[[2315,9],[5238,9],[5902,9],[6065,9],[6120,9],[6162,10]]},"3253":{"position":[[169,9]]},"3255":{"position":[[753,9]]},"3319":{"position":[[120,9]]},"3321":{"position":[[93,9]]},"3325":{"position":[[159,9],[575,9],[741,9],[1339,9],[1371,9],[1483,9],[1532,9],[1669,9],[1752,9],[2006,9],[2043,9],[2191,9],[2239,9],[3344,9]]},"3370":{"position":[[64,10]]},"3378":{"position":[[78,9]]},"3391":{"position":[[230,9]]},"3397":{"position":[[404,9]]},"3415":{"position":[[313,10]]},"3419":{"position":[[37,9]]},"3423":{"position":[[170,10]]},"3429":{"position":[[307,9]]},"3434":{"position":[[64,10]]},"3453":{"position":[[135,9],[201,9],[360,9]]},"3455":{"position":[[132,9],[159,9],[203,9],[245,9],[287,9],[330,9],[534,9],[603,9],[640,9]]},"3457":{"position":[[781,9]]},"3459":{"position":[[200,9],[338,10]]},"3465":{"position":[[284,9],[415,9],[726,11],[923,9],[1033,9]]},"3468":{"position":[[185,10],[260,10],[389,10],[460,10]]},"3472":{"position":[[194,9],[226,9],[425,9],[579,9],[6915,9],[12479,9]]},"3477":{"position":[[86,9],[254,9]]},"3479":{"position":[[81,9]]},"3482":{"position":[[222,11],[2877,9],[2989,9],[3059,9],[3184,9]]},"3484":{"position":[[0,9],[112,9],[182,9],[307,9]]}}}],["openstack'",{"_index":3683,"t":{"758":{"position":[[11,11]]},"1084":{"position":[[332,11]]},"3082":{"position":[[594,11]]}}}],["openstack.cloud.host_aggreg",{"_index":6786,"t":{"1383":{"position":[[198,30],[477,31]]}}}],["openstack.cloud.keypair",{"_index":7417,"t":{"1749":{"position":[[440,24]]}}}],["openstack.cloud.network",{"_index":7092,"t":{"1585":{"position":[[2955,24]]}}}],["openstack.cloud.security_group",{"_index":7368,"t":{"1743":{"position":[[818,31]]}}}],["openstack.cloud.security_group_rul",{"_index":7369,"t":{"1743":{"position":[[1001,36],[1181,36]]}}}],["openstack.cloud.serv",{"_index":7373,"t":{"1743":{"position":[[1425,23]]}}}],["openstack.cloud.subnet",{"_index":7096,"t":{"1585":{"position":[[3144,23]]}}}],["openstack.html",{"_index":6689,"t":{"1368":{"position":[[45,14]]}}}],["openstack.html#shorten",{"_index":6669,"t":{"1364":{"position":[[1009,25]]}}}],["openstack.img",{"_index":3789,"t":{"798":{"position":[[892,13],[995,13],[1098,13]]},"1535":{"position":[[892,13],[995,13],[1098,13]]}}}],["openstack.pi",{"_index":9221,"t":{"2715":{"position":[[425,12]]},"2790":{"position":[[24,12]]},"2935":{"position":[[19,12]]},"2994":{"position":[[18,12]]}}}],["openstack.upbound.io/v1beta1",{"_index":8082,"t":{"2033":{"position":[[254,28]]}}}],["openstack.yml",{"_index":7160,"t":{"1676":{"position":[[698,13],[852,13]]}}}],["openstack/arch",{"_index":4666,"t":{"970":{"position":[[134,14]]}}}],["openstack/keycloak",{"_index":8073,"t":{"1982":{"position":[[1467,22],[1522,22]]},"1984":{"position":[[1077,22],[1132,22]]}}}],["openstack/kolla",{"_index":7201,"t":{"1690":{"position":[[1616,15]]}}}],["openstack/sc",{"_index":3643,"t":{"738":{"position":[[3,13]]},"742":{"position":[[110,13]]},"746":{"position":[[3,14]]},"754":{"position":[[89,14]]},"756":{"position":[[34,13]]}}}],["openstack_anti_affin",{"_index":2774,"t":{"487":{"position":[[2241,23]]}}}],["openstack_cacert",{"_index":6001,"t":{"1213":{"position":[[1257,17]]}}}],["openstack_cinder_extra001_pool",{"_index":5192,"t":{"1110":{"position":[[106,31],[373,30]]}}}],["openstack_cloud",{"_index":2699,"t":{"485":{"position":[[147,15]]},"501":{"position":[[1004,15]]},"648":{"position":[[777,15]]},"660":{"position":[[2367,18]]}}}],["openstack_cloud_cacert_b64",{"_index":3496,"t":{"650":{"position":[[2014,26]]}}}],["openstack_cluster_gen",{"_index":2795,"t":{"487":{"position":[[3464,21]]},"667":{"position":[[578,23],[651,23]]}}}],["openstack_control_plane_machine_flavor",{"_index":2753,"t":{"487":{"position":[[1332,38]]},"660":{"position":[[1897,41]]}}}],["openstack_dns_nameserv",{"_index":2705,"t":{"485":{"position":[[466,25]]},"660":{"position":[[1835,28]]}}}],["openstack_external_network_id",{"_index":2701,"t":{"485":{"position":[[218,29]]},"660":{"position":[[2151,32]]}}}],["openstack_failure_domain",{"_index":2712,"t":{"485":{"position":[[675,24]]},"660":{"position":[[2905,27]]}}}],["openstack_image_nam",{"_index":2739,"t":{"487":{"position":[[752,20]]},"609":{"position":[[249,21]]}}}],["openstack_image_raw",{"_index":2746,"t":{"487":{"position":[[976,19]]}}}],["openstack_image_registation_extra_flag",{"_index":2749,"t":{"487":{"position":[[1104,39]]}}}],["openstack_node_machine_flavor",{"_index":2756,"t":{"487":{"position":[[1445,29]]},"660":{"position":[[1968,32]]}}}],["openstack_pool_default_min_s",{"_index":5200,"t":{"1110":{"position":[[289,31],[822,31]]}}}],["openstack_pool_default_pg_num",{"_index":5195,"t":{"1110":{"position":[[165,29],[212,29],[789,29]]}}}],["openstack_pools_extra",{"_index":5190,"t":{"1110":{"position":[[35,21],[344,22]]}}}],["openstack_security_group",{"_index":3540,"t":{"660":{"position":[[2230,25]]}}}],["openstack_service_rpc_work",{"_index":5915,"t":{"1169":{"position":[[181,30]]}}}],["openstack_service_work",{"_index":5913,"t":{"1169":{"position":[[105,26],[277,25],[505,25]]}}}],["openstack_srvgrp_control",{"_index":2778,"t":{"487":{"position":[[2384,27]]},"660":{"position":[[2484,30]]}}}],["openstack_srvgrp_work",{"_index":2782,"t":{"487":{"position":[[2487,23]]},"660":{"position":[[2553,26]]}}}],["openstack_ssh_key_nam",{"_index":2750,"t":{"487":{"position":[[1199,22]]},"660":{"position":[[2603,25]]}}}],["openstack_vers",{"_index":4905,"t":{"1063":{"position":[[782,17],[1423,17]]},"1069":{"position":[[274,17]]},"1071":{"position":[[1238,17]]},"1080":{"position":[[427,17]]},"1808":{"position":[[665,17]]},"1825":{"position":[[575,17]]}}}],["openstackcli",{"_index":71,"t":{"10":{"position":[[4,15],[127,15],[216,16],[1040,15],[1289,16]]},"517":{"position":[[33,16]]},"617":{"position":[[689,16]]},"895":{"position":[[1129,15]]},"905":{"position":[[100,15]]},"1294":{"position":[[509,15]]},"1617":{"position":[[1129,15]]},"1627":{"position":[[100,15]]},"1743":{"position":[[147,15],[2214,15]]},"1822":{"position":[[233,15]]},"1831":{"position":[[222,15]]},"2045":{"position":[[138,15]]},"2342":{"position":[[1129,15]]},"2352":{"position":[[100,15]]},"2715":{"position":[[215,16]]},"2783":{"position":[[412,16]]},"2862":{"position":[[215,16]]}}}],["openstackclust",{"_index":3001,"t":{"590":{"position":[[626,16],[753,16],[925,16]]}}}],["openstackcluster/testclust",{"_index":3011,"t":{"590":{"position":[[1422,28]]}}}],["openstackclusterstackreleas",{"_index":2343,"t":{"396":{"position":[[4,28],[451,28]]}}}],["openstackclusterstackreleasetempl",{"_index":3525,"t":{"660":{"position":[[921,36],[1060,36]]}}}],["openstackclustertempl",{"_index":2797,"t":{"487":{"position":[[3524,24]]},"662":{"position":[[932,25]]},"667":{"position":[[513,24]]}}}],["openstacknodeimagereleas",{"_index":2346,"t":{"396":{"position":[[128,25],[292,25],[513,26]]},"398":{"position":[[4,25],[348,25]]}}}],["openstackproviderclientnotset",{"_index":2375,"t":{"404":{"position":[[594,32]]}}}],["openstack’",{"_index":4660,"t":{"956":{"position":[[1310,11]]}}}],["opensus",{"_index":4298,"t":{"895":{"position":[[56,8],[238,8]]},"1617":{"position":[[56,8],[238,8]]},"2342":{"position":[[56,8],[238,8]]},"2890":{"position":[[68,9]]}}}],["opentelekomcloud",{"_index":7511,"t":{"1773":{"position":[[506,16]]}}}],["opentofu",{"_index":2854,"t":{"495":{"position":[[698,9],[1579,9]]},"501":{"position":[[0,8]]},"513":{"position":[[1097,10],[1429,8]]},"517":{"position":[[13,8]]},"550":{"position":[[92,8]]},"552":{"position":[[169,8]]},"554":{"position":[[184,8]]},"568":{"position":[[31,9]]},"570":{"position":[[81,8],[154,8],[190,9]]},"572":{"position":[[83,8],[156,8],[205,9]]},"574":{"position":[[35,8]]},"576":{"position":[[44,8],[107,8]]},"578":{"position":[[29,8],[84,8]]},"580":{"position":[[54,9],[103,8]]},"604":{"position":[[4222,8]]},"617":{"position":[[625,8],[927,8]]},"633":{"position":[[1063,8],[2087,8]]},"635":{"position":[[306,9]]},"639":{"position":[[238,8]]},"650":{"position":[[1245,8]]},"1779":{"position":[[2785,8],[3141,9]]},"1808":{"position":[[105,8]]},"1816":{"position":[[91,9],[205,9]]},"2461":{"position":[[749,8]]}}}],["opentracing.trac",{"_index":8266,"t":{"2140":{"position":[[156,18]]}}}],["openva",{"_index":8146,"t":{"2081":{"position":[[38,8]]}}}],["openvirtualnetwork\"(ovn",{"_index":3712,"t":{"772":{"position":[[895,25]]}}}],["openvswitch",{"_index":6144,"t":{"1284":{"position":[[39,11],[63,11],[401,12],[452,12]]},"1360":{"position":[[376,11]]},"1585":{"position":[[2582,11]]},"1814":{"position":[[265,11]]},"1820":{"position":[[39,11],[74,11],[412,12],[463,12]]},"2190":{"position":[[514,12]]},"2292":{"position":[[199,11]]}}}],["openvswitch_db",{"_index":6611,"t":{"1360":{"position":[[2629,14]]}}}],["openvswitch_vswitchd",{"_index":6608,"t":{"1360":{"position":[[2488,20]]},"1366":{"position":[[196,20]]}}}],["oper",{"_index":12,"t":{"4":{"position":[[115,9]]},"65":{"position":[[101,10]]},"73":{"position":[[220,9]]},"75":{"position":[[147,10]]},"83":{"position":[[87,7]]},"109":{"position":[[88,11]]},"116":{"position":[[23,11],[104,10]]},"166":{"position":[[58,9]]},"235":{"position":[[380,8],[692,7],[821,11],[1131,10]]},"242":{"position":[[33,10],[517,10]]},"245":{"position":[[132,10],[251,9],[589,11]]},"288":{"position":[[377,9]]},"290":{"position":[[50,9],[228,8]]},"327":{"position":[[294,9],[781,11]]},"329":{"position":[[108,10]]},"331":{"position":[[137,9]]},"333":{"position":[[340,7]]},"335":{"position":[[178,11],[213,11],[281,11]]},"342":{"position":[[114,8]]},"363":{"position":[[73,8]]},"366":{"position":[[917,9]]},"379":{"position":[[255,9]]},"383":{"position":[[44,8]]},"387":{"position":[[0,8]]},"391":{"position":[[624,8]]},"409":{"position":[[19,10],[240,8],[305,8],[387,9]]},"417":{"position":[[114,8]]},"421":{"position":[[335,8]]},"460":{"position":[[98,8]]},"513":{"position":[[125,7]]},"530":{"position":[[518,11]]},"544":{"position":[[51,9]]},"594":{"position":[[318,9]]},"596":{"position":[[1306,10]]},"598":{"position":[[821,9]]},"604":{"position":[[0,9],[77,9],[422,9]]},"617":{"position":[[55,8],[369,9]]},"726":{"position":[[92,8]]},"764":{"position":[[377,9]]},"780":{"position":[[24,8],[41,8],[74,8],[121,10],[157,8],[283,8],[396,9],[566,9]]},"784":{"position":[[42,8],[185,8]]},"876":{"position":[[401,10],[591,10]]},"880":{"position":[[1055,11]]},"883":{"position":[[1371,11],[1766,11],[1794,11],[2014,11],[2342,11]]},"888":{"position":[[489,8],[674,10],[1607,11]]},"909":{"position":[[500,9]]},"917":{"position":[[934,11]]},"920":{"position":[[83,8],[582,9]]},"947":{"position":[[2078,9]]},"954":{"position":[[204,9],[595,10]]},"956":{"position":[[523,9]]},"977":{"position":[[664,9]]},"982":{"position":[[525,9]]},"984":{"position":[[261,9]]},"986":{"position":[[272,9]]},"988":{"position":[[272,9]]},"990":{"position":[[266,11],[326,9]]},"1035":{"position":[[111,8]]},"1165":{"position":[[1250,8],[1428,8],[1529,8],[3196,8],[3442,8]]},"1224":{"position":[[655,8],[682,8],[1017,8],[1461,8],[1846,8],[2028,8]]},"1234":{"position":[[1055,8],[1882,9],[2655,9],[2708,9]]},"1236":{"position":[[780,9]]},"1256":{"position":[[4,8],[244,8],[745,8],[1055,8],[1082,8],[2143,8],[3115,8]]},"1331":{"position":[[101,8]]},"1360":{"position":[[34,8]]},"1386":{"position":[[296,8]]},"1388":{"position":[[380,8]]},"1448":{"position":[[25,10]]},"1462":{"position":[[104,9]]},"1471":{"position":[[334,10]]},"1473":{"position":[[993,10],[1185,10]]},"1487":{"position":[[92,8]]},"1521":{"position":[[42,8],[185,8]]},"1569":{"position":[[183,9],[812,9]]},"1591":{"position":[[121,9]]},"1631":{"position":[[500,9]]},"1639":{"position":[[934,11]]},"1642":{"position":[[83,8],[582,9]]},"1669":{"position":[[2078,9]]},"1676":{"position":[[337,10]]},"1690":{"position":[[1327,10],[1371,10],[1504,10],[1548,10]]},"1791":{"position":[[1774,10],[1973,9],[3710,10]]},"1857":{"position":[[252,7],[272,9],[593,9]]},"1913":{"position":[[1652,9]]},"1919":{"position":[[252,7],[272,9],[593,9]]},"1937":{"position":[[52,9],[230,8]]},"1955":{"position":[[363,9]]},"1957":{"position":[[1407,8],[2426,8],[2618,8]]},"1959":{"position":[[384,9]]},"2029":{"position":[[1652,9]]},"2049":{"position":[[57,9]]},"2051":{"position":[[739,9]]},"2098":{"position":[[126,8]]},"2126":{"position":[[48,7]]},"2190":{"position":[[297,11]]},"2206":{"position":[[97,11]]},"2209":{"position":[[553,8]]},"2212":{"position":[[254,12]]},"2248":{"position":[[518,10]]},"2296":{"position":[[142,9]]},"2310":{"position":[[210,9]]},"2315":{"position":[[946,9]]},"2317":{"position":[[54,9]]},"2324":{"position":[[608,9]]},"2356":{"position":[[500,9]]},"2364":{"position":[[934,11]]},"2367":{"position":[[83,8],[582,9]]},"2394":{"position":[[2078,9]]},"2407":{"position":[[125,8],[222,8]]},"2409":{"position":[[309,10],[725,9]]},"2426":{"position":[[694,10]]},"2434":{"position":[[40,10]]},"2456":{"position":[[167,8]]},"2461":{"position":[[607,8],[951,8]]},"2468":{"position":[[198,9]]},"2476":{"position":[[344,9]]},"2495":{"position":[[188,10]]},"2497":{"position":[[93,9]]},"2520":{"position":[[125,8]]},"2540":{"position":[[102,10]]},"2544":{"position":[[284,10]]},"2546":{"position":[[100,9]]},"2592":{"position":[[138,9]]},"2602":{"position":[[0,11],[242,11]]},"2629":{"position":[[408,10]]},"2651":{"position":[[175,9]]},"2671":{"position":[[1034,9]]},"2684":{"position":[[260,9]]},"2686":{"position":[[3,9]]},"2688":{"position":[[229,8],[970,8],[2136,8],[2900,8]]},"2697":{"position":[[120,9]]},"2700":{"position":[[24,9]]},"2742":{"position":[[120,9]]},"2745":{"position":[[24,9]]},"2795":{"position":[[696,10]]},"2832":{"position":[[120,9]]},"2870":{"position":[[101,10],[184,10]]},"2886":{"position":[[27,9]]},"2895":{"position":[[162,9],[3955,8]]},"2899":{"position":[[557,9],[716,9],[773,9]]},"2921":{"position":[[120,9]]},"2944":{"position":[[1685,9]]},"2947":{"position":[[1201,9]]},"2964":{"position":[[100,10]]},"2992":{"position":[[106,8],[503,8]]},"3076":{"position":[[193,8]]},"3099":{"position":[[455,9]]},"3103":{"position":[[473,9]]},"3160":{"position":[[176,7],[1414,9]]},"3195":{"position":[[21,10],[59,11],[258,10]]},"3210":{"position":[[323,9]]},"3218":{"position":[[190,9],[616,9],[1812,9]]},"3220":{"position":[[101,9]]},"3224":{"position":[[649,9],[1287,9]]},"3238":{"position":[[294,9]]},"3251":{"position":[[4503,9]]},"3253":{"position":[[313,9]]},"3272":{"position":[[469,9],[701,8]]},"3284":{"position":[[602,9]]},"3301":{"position":[[4399,7],[5030,8],[6982,8],[7009,8],[7431,8]]},"3308":{"position":[[89,10]]},"3314":{"position":[[1897,9],[2209,9],[2258,8],[2623,8],[3002,8]]},"3347":{"position":[[572,10]]},"3351":{"position":[[130,10]]},"3357":{"position":[[592,14],[768,11]]},"3374":{"position":[[99,9]]},"3389":{"position":[[894,10],[974,10]]},"3395":{"position":[[178,9]]},"3400":{"position":[[450,11]]},"3415":{"position":[[41,10],[381,9]]},"3438":{"position":[[87,9]]}}}],["operat",{"_index":6569,"t":{"1360":{"position":[[8,8]]}}}],["operato",{"_index":8003,"t":{"1957":{"position":[[883,7]]}}}],["operator'",{"_index":2929,"t":{"513":{"position":[[439,10]]},"990":{"position":[[222,10]]}}}],["operator_public_key",{"_index":6013,"t":{"1224":{"position":[[1158,19]]}}}],["operator_us",{"_index":4835,"t":{"1041":{"position":[[668,13]]}}}],["operators/develop",{"_index":8349,"t":{"2164":{"position":[[187,20]]}}}],["operators/postgr",{"_index":2406,"t":{"409":{"position":[[457,19]]}}}],["operators/redi",{"_index":2405,"t":{"409":{"position":[[423,16]]}}}],["opinion",{"_index":2183,"t":{"349":{"position":[[267,11]]},"1972":{"position":[[737,11]]},"1976":{"position":[[170,11],[201,8]]},"2164":{"position":[[87,11],[326,9],[419,7],[631,11]]},"2176":{"position":[[107,8],[328,11]]},"2400":{"position":[[237,11]]},"2456":{"position":[[293,11]]},"2493":{"position":[[195,11]]},"3438":{"position":[[417,11]]}}}],["opm",{"_index":3866,"t":{"819":{"position":[[7594,3],[7719,3]]},"1509":{"position":[[7594,3],[7719,3]]}}}],["opportun",{"_index":1139,"t":{"170":{"position":[[1388,11]]},"240":{"position":[[234,11]]},"2118":{"position":[[2255,11]]}}}],["oppos",{"_index":8347,"t":{"2164":{"position":[[28,7]]}}}],["opposit",{"_index":1313,"t":{"180":{"position":[[151,8]]}}}],["opsi",{"_index":9548,"t":{"2895":{"position":[[4332,5]]}}}],["opt",{"_index":8114,"t":{"2039":{"position":[[723,3]]},"2104":{"position":[[93,3]]},"2126":{"position":[[493,3]]},"2190":{"position":[[348,4]]},"2248":{"position":[[1306,4]]},"2405":{"position":[[568,4]]},"2702":{"position":[[54,4],[228,4]]},"2747":{"position":[[54,4],[228,4]]},"2820":{"position":[[87,3]]},"3199":{"position":[[347,3]]},"3472":{"position":[[14065,3]]}}}],["opt/ansible/secrets/id_rsa.oper",{"_index":4824,"t":{"1039":{"position":[[249,36],[402,36],[555,36],[708,36]]},"1041":{"position":[[488,36]]}}}],["opt/cloud",{"_index":7015,"t":{"1571":{"position":[[831,10],[906,10],[997,10],[1166,10],[1312,10]]}}}],["opt/configur",{"_index":6148,"t":{"1286":{"position":[[1557,19]]},"1796":{"position":[[6,18]]}}}],["opt/configuration/environments/manag",{"_index":7497,"t":{"1764":{"position":[[4560,39]]}}}],["opt/configuration/environments/manager/group_vars/manager.yml",{"_index":7082,"t":{"1585":{"position":[[1913,62],[2375,62]]}}}],["opt/configuration/environments/openstack/playbook",{"_index":7090,"t":{"1585":{"position":[[2750,50]]}}}],["opt/configuration/inventory/group_vars/generic/network.yml",{"_index":7081,"t":{"1585":{"position":[[1853,59],[2315,59]]}}}],["opt/configuration/scripts/bootstrap.sh",{"_index":7557,"t":{"1779":{"position":[[5049,40]]}}}],["opt/configuration/scripts/bootstrap/301",{"_index":7559,"t":{"1779":{"position":[[6144,40]]}}}],["opt/configuration/scripts/bootstrap/302",{"_index":7562,"t":{"1779":{"position":[[6220,40]]}}}],["opt/configuration/scripts/check.sh",{"_index":7558,"t":{"1779":{"position":[[5808,36]]}}}],["opt/configuration/scripts/deploy/000",{"_index":7648,"t":{"1798":{"position":[[19,37]]}}}],["opt/configuration/scripts/deploy/001",{"_index":7548,"t":{"1779":{"position":[[4602,37]]},"1798":{"position":[[76,37]]}}}],["opt/configuration/scripts/deploy/005",{"_index":7550,"t":{"1779":{"position":[[4659,37]]}}}],["opt/configuration/scripts/deploy/100",{"_index":7552,"t":{"1779":{"position":[[4711,37]]},"1798":{"position":[[133,37]]}}}],["opt/configuration/scripts/deploy/200",{"_index":7554,"t":{"1779":{"position":[[4772,37]]},"1798":{"position":[[194,37]]}}}],["opt/configuration/scripts/deploy/210",{"_index":7650,"t":{"1798":{"position":[[265,37]]}}}],["opt/configuration/scripts/deploy/300",{"_index":7555,"t":{"1779":{"position":[[4843,37]]},"1798":{"position":[[339,37]]}}}],["opt/configuration/scripts/deploy/310",{"_index":7652,"t":{"1798":{"position":[[405,37]]}}}],["opt/configuration/scripts/deploy/320",{"_index":7653,"t":{"1798":{"position":[[474,37]]}}}],["opt/configuration/scripts/deploy/330",{"_index":7655,"t":{"1798":{"position":[[544,37]]}}}],["opt/configuration/scripts/deploy/400",{"_index":7556,"t":{"1779":{"position":[[4909,37],[5197,37]]},"1798":{"position":[[615,37]]}}}],["opt/configuration/scripts/dis",{"_index":7541,"t":{"1779":{"position":[[4191,34]]}}}],["opt/configuration/scripts/en",{"_index":7543,"t":{"1779":{"position":[[4366,33]]}}}],["opt/configuration/scripts/pul",{"_index":7545,"t":{"1779":{"position":[[4466,31]]}}}],["opt/configuration/scripts/upgrade/100",{"_index":7657,"t":{"1800":{"position":[[19,38]]}}}],["opt/configuration/scripts/upgrade/200",{"_index":7658,"t":{"1800":{"position":[[75,38]]}}}],["opt/configuration/scripts/upgrade/300",{"_index":7659,"t":{"1800":{"position":[[147,38]]}}}],["opt/configuration/scripts/upgrade/310",{"_index":7660,"t":{"1800":{"position":[[214,38]]}}}],["opt/configuration/scripts/upgrade/320",{"_index":7661,"t":{"1800":{"position":[[284,38]]}}}],["opt/configuration/scripts/upgrade/330",{"_index":7662,"t":{"1800":{"position":[[355,38]]}}}],["opt/configuration/secrets/become_password",{"_index":6018,"t":{"1224":{"position":[[1685,43],[1762,42],[1885,42],[2067,42]]}}}],["opt/configuration/secrets/conn_password",{"_index":6015,"t":{"1224":{"position":[[1306,41],[1379,40],[1498,40],[2129,40]]}}}],["opt/configuration/upgrade.sh",{"_index":7050,"t":{"1582":{"position":[[212,29]]}}}],["opt/manag",{"_index":6510,"t":{"1344":{"position":[[298,12]]},"1731":{"position":[[607,12],[978,12]]},"1794":{"position":[[1188,12]]}}}],["opt/reports/valid",{"_index":6935,"t":{"1469":{"position":[[425,23]]}}}],["opt/td",{"_index":6474,"t":{"1337":{"position":[[224,7],[315,7]]}}}],["optim",{"_index":545,"t":{"73":{"position":[[99,7]]},"333":{"position":[[210,9]]},"349":{"position":[[279,9]]},"381":{"position":[[828,7],[912,7]]},"662":{"position":[[253,7]]},"778":{"position":[[280,13]]},"888":{"position":[[1668,10]]},"956":{"position":[[1401,7]]},"1226":{"position":[[413,8],[477,8],[596,8],[671,8],[884,8],[997,8],[1061,8],[1139,8],[1227,8],[1270,8],[1415,8],[1514,8],[1538,8],[1578,8],[1615,8],[1656,8],[1700,8],[1741,8],[1777,8],[1821,8],[1873,9],[1945,8],[2148,8],[2205,8]]},"1947":{"position":[[211,9]]},"2100":{"position":[[43,9]]},"2409":{"position":[[380,8],[615,8]]},"2602":{"position":[[271,8]]},"3208":{"position":[[975,9]]},"3316":{"position":[[1299,9]]}}}],["option",{"_index":621,"t":{"95":{"position":[[28,7]]},"99":{"position":[[10,8]]},"129":{"position":[[130,6]]},"166":{"position":[[480,8]]},"189":{"position":[[109,10]]},"210":{"position":[[327,6]]},"253":{"position":[[1894,6]]},"294":{"position":[[91,10]]},"323":{"position":[[769,7]]},"335":{"position":[[889,8]]},"368":{"position":[[184,9]]},"428":{"position":[[845,11]]},"436":{"position":[[317,7],[1421,6]]},"444":{"position":[[224,8]]},"460":{"position":[[856,6]]},"471":{"position":[[462,8]]},"487":{"position":[[3923,8],[5904,8]]},"519":{"position":[[85,7],[283,6]]},"521":{"position":[[87,6]]},"552":{"position":[[705,8]]},"557":{"position":[[161,10]]},"596":{"position":[[2397,8],[2471,8],[2839,8]]},"600":{"position":[[730,6]]},"604":{"position":[[10069,10]]},"615":{"position":[[1131,7],[1636,6]]},"617":{"position":[[966,10]]},"619":{"position":[[808,7]]},"627":{"position":[[1356,10]]},"631":{"position":[[686,8]]},"633":{"position":[[232,7]]},"635":{"position":[[1149,11],[1528,11]]},"639":{"position":[[313,8]]},"641":{"position":[[47,8],[196,7],[1291,7]]},"646":{"position":[[109,7],[793,8],[848,7],[876,6]]},"660":{"position":[[240,8]]},"730":{"position":[[282,8],[516,9],[529,7]]},"732":{"position":[[329,8]]},"742":{"position":[[540,11],[787,7]]},"748":{"position":[[271,11]]},"762":{"position":[[452,7]]},"774":{"position":[[398,6]]},"786":{"position":[[571,6]]},"788":{"position":[[115,8]]},"813":{"position":[[38,7]]},"817":{"position":[[223,8]]},"819":{"position":[[1354,8],[1668,7],[1795,7],[1842,6],[2042,6]]},"821":{"position":[[747,8],[1120,7],[1247,7],[1294,6],[1494,6]]},"823":{"position":[[126,7]]},"850":{"position":[[49,9],[62,7]]},"857":{"position":[[36,7]]},"859":{"position":[[221,8],[881,8],[1184,7],[1313,7],[1360,6],[1560,6],[6641,7],[6768,7],[6815,6]]},"861":{"position":[[110,7]]},"895":{"position":[[1591,12]]},"903":{"position":[[2518,10]]},"913":{"position":[[2936,7]]},"920":{"position":[[382,8],[788,6]]},"934":{"position":[[1237,6],[1299,7]]},"947":{"position":[[1570,6]]},"977":{"position":[[1583,8],[2630,7]]},"1055":{"position":[[756,9]]},"1073":{"position":[[305,8]]},"1080":{"position":[[961,11]]},"1112":{"position":[[554,8],[1253,8],[1354,8],[1500,8],[1598,8]]},"1118":{"position":[[798,6]]},"1150":{"position":[[13002,7]]},"1161":{"position":[[1734,6],[1749,6]]},"1165":{"position":[[1093,6],[1128,6]]},"1174":{"position":[[5,8]]},"1176":{"position":[[5,8]]},"1224":{"position":[[2392,11],[2541,11],[2784,11],[3588,10]]},"1234":{"position":[[2239,9]]},"1246":{"position":[[109,9]]},"1262":{"position":[[98,8],[216,8]]},"1288":{"position":[[38,9]]},"1321":{"position":[[684,9]]},"1360":{"position":[[168,10],[583,10],[648,10],[1071,8]]},"1366":{"position":[[377,8],[535,8]]},"1368":{"position":[[1153,8],[1279,8],[1405,8]]},"1406":{"position":[[371,6]]},"1484":{"position":[[49,9],[62,7]]},"1491":{"position":[[282,8],[516,9],[529,7]]},"1493":{"position":[[329,8]]},"1503":{"position":[[38,7]]},"1507":{"position":[[223,8]]},"1509":{"position":[[1354,8],[1668,7],[1795,7],[1842,6],[2042,6]]},"1511":{"position":[[747,8],[1120,7],[1247,7],[1294,6],[1494,6]]},"1513":{"position":[[126,7]]},"1523":{"position":[[571,6]]},"1525":{"position":[[115,8]]},"1562":{"position":[[728,8]]},"1571":{"position":[[391,6]]},"1601":{"position":[[36,7]]},"1603":{"position":[[221,8],[881,8],[1184,7],[1313,7],[1360,6],[1560,6],[6641,7],[6768,7],[6815,6]]},"1605":{"position":[[110,7]]},"1617":{"position":[[1591,12]]},"1625":{"position":[[2518,10]]},"1635":{"position":[[2936,7]]},"1642":{"position":[[382,8],[788,6]]},"1656":{"position":[[1237,6],[1299,7]]},"1669":{"position":[[1570,6]]},"1715":{"position":[[31,6]]},"1717":{"position":[[73,7]]},"1736":{"position":[[96,9]]},"1779":{"position":[[520,12],[4426,6],[5882,9],[6460,9]]},"1825":{"position":[[1124,11]]},"1839":{"position":[[93,10]]},"1841":{"position":[[29,8]]},"1845":{"position":[[1519,10]]},"1855":{"position":[[646,10]]},"1900":{"position":[[707,8]]},"1904":{"position":[[596,9]]},"1917":{"position":[[646,10]]},"2016":{"position":[[707,8]]},"2020":{"position":[[596,9]]},"2096":{"position":[[326,8],[2120,6]]},"2098":{"position":[[3431,6]]},"2118":{"position":[[735,8],[772,8]]},"2122":{"position":[[123,7],[420,8]]},"2152":{"position":[[541,7]]},"2176":{"position":[[214,7]]},"2190":{"position":[[691,8]]},"2229":{"position":[[545,8]]},"2231":{"position":[[77,11]]},"2243":{"position":[[189,8]]},"2330":{"position":[[230,9]]},"2342":{"position":[[1591,12]]},"2350":{"position":[[2518,10]]},"2360":{"position":[[2936,7]]},"2367":{"position":[[382,8],[788,6]]},"2381":{"position":[[1237,6],[1299,7]]},"2394":{"position":[[1570,6]]},"2403":{"position":[[345,6]]},"2495":{"position":[[176,7]]},"2504":{"position":[[139,8]]},"2548":{"position":[[156,8]]},"2619":{"position":[[118,10]]},"2625":{"position":[[2617,8]]},"2627":{"position":[[622,8],[1853,8]]},"2673":{"position":[[1557,8]]},"2702":{"position":[[30,9],[178,8]]},"2723":{"position":[[148,8]]},"2727":{"position":[[282,9],[611,8]]},"2731":{"position":[[1331,8]]},"2735":{"position":[[904,6],[1062,6]]},"2747":{"position":[[30,9],[178,8]]},"2758":{"position":[[1757,9]]},"2762":{"position":[[161,8]]},"2764":{"position":[[161,7]]},"2766":{"position":[[386,9],[811,8]]},"2770":{"position":[[1354,8]]},"2774":{"position":[[906,6],[1064,6]]},"2811":{"position":[[394,9]]},"2813":{"position":[[224,10],[286,9],[296,8],[444,8],[891,8],[999,8]]},"2815":{"position":[[1002,8]]},"2837":{"position":[[27,9],[46,9],[66,9]]},"2848":{"position":[[148,8]]},"2852":{"position":[[20,8],[659,9],[958,8]]},"2860":{"position":[[1327,8]]},"2874":{"position":[[371,10]]},"2879":{"position":[[114,9]]},"2895":{"position":[[2336,8],[4262,9]]},"2899":{"position":[[735,9]]},"2901":{"position":[[575,9],[794,9],[1069,9],[1403,11],[1430,9],[1646,9],[1760,9]]},"2923":{"position":[[501,7],[859,7]]},"2947":{"position":[[1645,6],[4691,6],[4746,6],[6141,7]]},"2962":{"position":[[583,7]]},"2966":{"position":[[41,6],[901,6],[1258,7],[1593,6],[1678,6],[1712,8],[1916,7],[2149,7],[2379,6],[2621,7],[2982,6],[3186,6],[3254,6],[3388,7],[3618,8],[3639,8],[4189,6],[4356,6],[4498,7]]},"2968":{"position":[[28,7]]},"2970":{"position":[[156,8],[217,8],[367,9],[504,8]]},"2972":{"position":[[49,7]]},"2977":{"position":[[199,8]]},"2983":{"position":[[85,9]]},"2985":{"position":[[210,9]]},"2992":{"position":[[142,8]]},"3011":{"position":[[0,6],[1034,6],[1541,6],[1639,6],[2283,6],[2331,6]]},"3016":{"position":[[28,6]]},"3039":{"position":[[80,9]]},"3042":{"position":[[29,6]]},"3061":{"position":[[899,6],[1245,6]]},"3063":{"position":[[199,6]]},"3065":{"position":[[78,6],[166,6]]},"3071":{"position":[[1579,7],[1728,7],[1773,7],[2456,7],[2535,7]]},"3105":{"position":[[109,8]]},"3111":{"position":[[492,6],[575,7]]},"3115":{"position":[[77,7],[121,7],[512,6]]},"3160":{"position":[[287,8]]},"3184":{"position":[[216,8]]},"3186":{"position":[[846,9]]},"3199":{"position":[[851,8]]},"3222":{"position":[[254,8]]},"3253":{"position":[[144,8],[261,8]]},"3255":{"position":[[328,7],[475,6]]},"3290":{"position":[[19,8]]},"3301":{"position":[[4789,7]]},"3323":{"position":[[0,8]]},"3325":{"position":[[3574,6],[3584,6]]},"3331":{"position":[[19,8]]},"3333":{"position":[[19,8]]},"3338":{"position":[[118,10]]},"3378":{"position":[[1007,8]]},"3397":{"position":[[2310,6]]},"3417":{"position":[[43,7]]},"3419":{"position":[[400,7],[511,6]]},"3457":{"position":[[944,9]]},"3465":{"position":[[116,6]]},"3497":{"position":[[19,8]]},"3506":{"position":[[0,8]]},"3508":{"position":[[0,6],[10,6],[31,6],[41,6]]},"3514":{"position":[[19,8]]},"3516":{"position":[[19,8]]}}}],["optionali",{"_index":2149,"t":{"335":{"position":[[740,9]]}}}],["optmiz",{"_index":6034,"t":{"1226":{"position":[[723,7]]}}}],["oracl",{"_index":6047,"t":{"1226":{"position":[[1571,6],[1591,6]]}}}],["orchestr",{"_index":2134,"t":{"329":{"position":[[264,13]]},"333":{"position":[[50,14]]},"627":{"position":[[3282,11]]},"714":{"position":[[71,13]]},"726":{"position":[[123,12]]},"748":{"position":[[352,13]]},"756":{"position":[[315,13]]},"780":{"position":[[296,12]]},"888":{"position":[[584,11]]},"1487":{"position":[[123,12]]},"1678":{"position":[[1843,12],[1999,12]]},"1976":{"position":[[705,13]]},"2592":{"position":[[208,13]]},"3180":{"position":[[236,13]]},"3193":{"position":[[212,13]]}}}],["orchestration.stack",{"_index":8775,"t":{"2566":{"position":[[4541,21]]}}}],["orchestration_crud",{"_index":8776,"t":{"2566":{"position":[[4571,19]]}}}],["order",{"_index":654,"t":{"105":{"position":[[459,5]]},"120":{"position":[[3,5]]},"137":{"position":[[17,5]]},"195":{"position":[[81,5]]},"202":{"position":[[419,5]]},"225":{"position":[[283,5]]},"227":{"position":[[150,5]]},"321":{"position":[[283,5]]},"389":{"position":[[132,5]]},"421":{"position":[[1549,6]]},"471":{"position":[[997,5]]},"499":{"position":[[1102,5]]},"586":{"position":[[35,5]]},"615":{"position":[[1165,8]]},"617":{"position":[[1086,7]]},"819":{"position":[[1648,5]]},"821":{"position":[[1100,5]]},"859":{"position":[[1164,5],[6621,5]]},"920":{"position":[[394,5]]},"1112":{"position":[[165,5]]},"1244":{"position":[[250,6]]},"1460":{"position":[[160,5]]},"1471":{"position":[[3,5]]},"1473":{"position":[[155,5]]},"1477":{"position":[[317,5]]},"1509":{"position":[[1648,5]]},"1511":{"position":[[1100,5]]},"1585":{"position":[[2239,5]]},"1603":{"position":[[1164,5],[6621,5]]},"1642":{"position":[[394,5]]},"1745":{"position":[[625,5]]},"1747":{"position":[[3,5]]},"1783":{"position":[[602,5]]},"1896":{"position":[[235,5],[1212,5]]},"1982":{"position":[[1085,5]]},"1984":{"position":[[695,5]]},"2012":{"position":[[235,5],[1212,5]]},"2212":{"position":[[368,5]]},"2367":{"position":[[394,5]]},"2518":{"position":[[3,5]]},"2625":{"position":[[461,5]]},"2705":{"position":[[2169,5]]},"2707":{"position":[[468,5]]},"2723":{"position":[[945,8]]},"2729":{"position":[[174,6]]},"2750":{"position":[[2471,5]]},"2752":{"position":[[468,5]]},"2758":{"position":[[1813,5]]},"2762":{"position":[[958,8]]},"2768":{"position":[[197,6]]},"2795":{"position":[[933,5]]},"2820":{"position":[[3,5]]},"2840":{"position":[[1817,5]]},"2842":{"position":[[442,5]]},"2848":{"position":[[809,8]]},"2852":{"position":[[1273,6]]},"2895":{"position":[[4805,6]]},"2901":{"position":[[1558,5]]},"2939":{"position":[[277,5]]},"2947":{"position":[[3280,5],[3681,9]]},"3055":{"position":[[533,5]]},"3057":{"position":[[89,5],[191,5]]},"3063":{"position":[[233,5],[537,6],[675,5]]},"3128":{"position":[[3,5],[1206,5]]},"3160":{"position":[[216,5],[2518,5]]},"3178":{"position":[[532,5]]},"3182":{"position":[[141,5],[200,5],[690,5],[2374,5]]},"3184":{"position":[[258,5],[2448,5],[3068,5]]},"3186":{"position":[[60,5],[201,5],[1145,5],[1305,5]]},"3191":{"position":[[519,5]]},"3195":{"position":[[423,5]]},"3199":{"position":[[85,5],[1088,5]]},"3227":{"position":[[182,5]]},"3231":{"position":[[329,5]]},"3234":{"position":[[258,5],[621,5]]},"3236":{"position":[[3,5],[1198,5],[2936,5]]},"3238":{"position":[[69,5],[232,5],[485,5]]},"3262":{"position":[[297,5]]},"3264":{"position":[[229,5]]},"3266":{"position":[[647,5]]},"3268":{"position":[[3,5]]},"3270":{"position":[[349,5],[1967,5],[2048,5]]},"3272":{"position":[[254,5]]},"3274":{"position":[[49,5],[230,5]]},"3276":{"position":[[3,5],[211,5],[2363,5]]},"3280":{"position":[[88,5],[197,5]]},"3284":{"position":[[542,5]]},"3297":{"position":[[3,5]]},"3299":{"position":[[63,5]]},"3310":{"position":[[541,5]]},"3343":{"position":[[745,6],[767,5]]},"3351":{"position":[[65,6],[457,5]]},"3413":{"position":[[105,5]]},"3415":{"position":[[360,5]]},"3417":{"position":[[3,5]]}}}],["org",{"_index":246,"t":{"23":{"position":[[237,3]]},"1747":{"position":[[529,3],[569,3],[683,3]]}}}],["org/mi",{"_index":1996,"t":{"319":{"position":[[135,6]]}}}],["org/zuul_demo_config",{"_index":7429,"t":{"1749":{"position":[[992,21]]}}}],["org/zuul_demo_repo",{"_index":7430,"t":{"1749":{"position":[[1057,18]]}}}],["organ",{"_index":1327,"t":{"184":{"position":[[138,13]]},"202":{"position":[[219,10],[446,8]]},"206":{"position":[[352,10]]},"227":{"position":[[385,8],[446,10],[491,8]]},"245":{"position":[[44,13]]},"247":{"position":[[466,13]]},"290":{"position":[[189,13]]},"353":{"position":[[212,13],[400,13]]},"489":{"position":[[910,13]]},"499":{"position":[[1746,13],[1989,12],[2123,12]]},"690":{"position":[[203,13]]},"883":{"position":[[1635,13],[1845,13]]},"888":{"position":[[2110,13]]},"932":{"position":[[4326,12]]},"956":{"position":[[2143,13]]},"977":{"position":[[2406,13]]},"1654":{"position":[[4326,12]]},"1752":{"position":[[62,13]]},"1937":{"position":[[191,13]]},"1978":{"position":[[166,14]]},"2379":{"position":[[4326,12]]},"2524":{"position":[[186,13]]},"2617":{"position":[[200,13]]},"2795":{"position":[[203,13]]},"2975":{"position":[[203,13]]},"3208":{"position":[[1162,12]]},"3210":{"position":[[998,13]]},"3251":{"position":[[4032,12],[4306,12],[4539,13],[4865,12],[4912,14]]},"3264":{"position":[[131,12]]},"3295":{"position":[[132,12]]},"3299":{"position":[[1274,9],[2739,9],[3959,9]]},"3301":{"position":[[3556,13]]}}}],["organis",{"_index":754,"t":{"114":{"position":[[263,12]]},"325":{"position":[[5369,12]]},"883":{"position":[[193,13],[2125,13]]},"888":{"position":[[2280,13]]},"1240":{"position":[[783,12],[957,12],[1131,12]]},"2209":{"position":[[210,12]]},"2526":{"position":[[607,12]]},"2617":{"position":[[371,12]]},"2621":{"position":[[36,12]]},"2625":{"position":[[130,13],[475,12]]},"2631":{"position":[[176,13],[1611,13]]},"3518":{"position":[[714,12]]}}}],["organisation'",{"_index":9044,"t":{"2647":{"position":[[1528,14]]}}}],["organisation/demo",{"_index":750,"t":{"114":{"position":[[114,17]]}}}],["organiz",{"_index":1913,"t":{"290":{"position":[[113,14]]},"1937":{"position":[[115,14]]},"2647":{"position":[[1216,14]]},"3204":{"position":[[558,14]]},"3224":{"position":[[31,14],[1638,14]]}}}],["organization#permiss",{"_index":2876,"t":{"499":{"position":[[1823,24]]}}}],["organization'",{"_index":1336,"t":{"184":{"position":[[856,14]]},"245":{"position":[[1428,15]]},"379":{"position":[[1091,14]]},"3206":{"position":[[8,14]]}}}],["organization/compani",{"_index":601,"t":{"87":{"position":[[83,20]]},"2673":{"position":[[720,20]]}}}],["orgs/sovereigncloudstack/data.yaml",{"_index":1335,"t":{"184":{"position":[[744,35]]}}}],["orient",{"_index":1661,"t":{"247":{"position":[[635,12]]},"2250":{"position":[[197,9]]},"3389":{"position":[[693,8]]}}}],["origin",{"_index":1279,"t":{"178":{"position":[[1674,6],[1771,6]]},"182":{"position":[[419,6]]},"247":{"position":[[458,7]]},"253":{"position":[[29,6]]},"255":{"position":[[89,6]]},"503":{"position":[[757,8]]},"932":{"position":[[3151,9]]},"1112":{"position":[[5406,6]]},"1654":{"position":[[3151,9]]},"1882":{"position":[[203,8]]},"1900":{"position":[[554,8],[641,10]]},"1902":{"position":[[202,8],[250,11]]},"1904":{"position":[[62,10]]},"1906":{"position":[[138,8]]},"1908":{"position":[[332,10],[2003,8],[2445,8]]},"1998":{"position":[[203,8]]},"2016":{"position":[[554,8],[641,10]]},"2018":{"position":[[202,8],[250,11]]},"2020":{"position":[[62,10]]},"2022":{"position":[[138,8]]},"2024":{"position":[[332,10],[2003,8],[2445,8]]},"2053":{"position":[[673,10],[875,6]]},"2096":{"position":[[2190,8]]},"2098":{"position":[[3501,8]]},"2379":{"position":[[3151,9]]},"2546":{"position":[[274,7]]},"3128":{"position":[[532,8]]},"3251":{"position":[[2857,10]]},"3378":{"position":[[63,7]]}}}],["orphan",{"_index":2627,"t":{"472":{"position":[[1572,8]]},"2063":{"position":[[549,8]]}}}],["os",{"_index":170,"t":{"10":{"position":[[1744,2],[1812,2]]},"379":{"position":[[299,2],[539,2]]},"385":{"position":[[55,3]]},"730":{"position":[[1556,2],[1597,2],[1979,2],[2016,2],[2187,2]]},"905":{"position":[[727,2]]},"913":{"position":[[3119,2],[3194,2]]},"1150":{"position":[[12671,2],[13171,2]]},"1347":{"position":[[14,2],[1483,2]]},"1351":{"position":[[164,2],[651,2],[1291,2],[1361,2],[2056,2],[2175,2]]},"1353":{"position":[[81,2]]},"1358":{"position":[[333,2],[449,2]]},"1362":{"position":[[678,2],[1297,2],[1590,2],[2319,2],[2406,2]]},"1364":{"position":[[70,2],[772,2]]},"1371":{"position":[[12,2]]},"1373":{"position":[[28,2],[184,2]]},"1375":{"position":[[12,2],[123,2],[1023,2],[1107,2]]},"1377":{"position":[[12,2],[29,2],[124,2],[1018,2],[1035,2],[1128,2]]},"1388":{"position":[[91,2]]},"1491":{"position":[[1556,2],[1597,2],[1979,2],[2016,2],[2187,2]]},"1627":{"position":[[727,2]]},"1635":{"position":[[3119,2],[3194,2]]},"1791":{"position":[[2073,2],[2122,2],[2176,2],[2208,2],[2234,2],[2292,2],[2314,2],[2339,2],[2373,2],[2396,2],[2426,2],[2878,2],[2927,2],[2981,2],[3013,2],[3039,2],[3097,2],[3119,2],[3144,2],[3178,2],[3201,2],[3231,2],[3343,2]]},"1845":{"position":[[2867,2]]},"1896":{"position":[[416,2]]},"2012":{"position":[[416,2]]},"2352":{"position":[[727,2]]},"2360":{"position":[[3119,2],[3194,2]]},"2468":{"position":[[867,2]]},"2546":{"position":[[384,2]]},"2890":{"position":[[17,2]]},"2895":{"position":[[1845,2]]},"2901":{"position":[[218,2],[1545,2],[1715,2],[2068,2]]},"2947":{"position":[[4069,3]]},"2970":{"position":[[289,2]]},"2999":{"position":[[333,2]]},"3011":{"position":[[1340,2]]},"3218":{"position":[[642,3]]}}}],["os:operatingsystem",{"_index":9563,"t":{"2899":{"position":[[1216,18]]}}}],["os_architectur",{"_index":8692,"t":{"2566":{"position":[[738,16]]}}}],["os_cacert",{"_index":4488,"t":{"913":{"position":[[3505,10]]},"1635":{"position":[[3505,10]]},"2360":{"position":[[3505,10]]}}}],["os_cacert=/home/debian/ca",{"_index":4444,"t":{"913":{"position":[[396,25]]},"1635":{"position":[[396,25]]},"2360":{"position":[[396,25]]}}}],["os_cacert=/path/to/cacert.crt",{"_index":4401,"t":{"907":{"position":[[681,29]]},"1629":{"position":[[681,29]]},"2354":{"position":[[681,29]]}}}],["os_cloud",{"_index":173,"t":{"10":{"position":[[1790,9]]},"485":{"position":[[168,8]]},"519":{"position":[[606,8]]},"619":{"position":[[227,8],[439,8]]},"903":{"position":[[184,8]]},"905":{"position":[[771,9]]},"913":{"position":[[3442,8]]},"1578":{"position":[[199,9]]},"1625":{"position":[[184,8]]},"1627":{"position":[[771,9]]},"1635":{"position":[[3442,8]]},"2350":{"position":[[184,8]]},"2352":{"position":[[771,9]]},"2360":{"position":[[3442,8]]},"2715":{"position":[[232,9],[495,8]]},"2783":{"position":[[429,9]]},"2790":{"position":[[94,8]]},"2813":{"position":[[966,9],[976,10]]},"2815":{"position":[[280,8],[650,9],[660,12],[911,10]]},"2862":{"position":[[232,9]]}}}],["os_cloud=.servic",{"_index":6941,"t":{"1471":{"position":[[808,22]]},"1473":{"position":[[1744,22]]}}}],["radosgw_address",{"_index":4983,"t":{"1067":{"position":[[5344,16]]},"1108":{"position":[[1664,15],[1888,16]]}}}],["radowsgw_interfac",{"_index":5189,"t":{"1108":{"position":[[1642,18],[1744,18]]}}}],["raft",{"_index":4681,"t":{"982":{"position":[[442,4]]}}}],["raid",{"_index":3714,"t":{"778":{"position":[[185,5],[275,4]]},"1184":{"position":[[472,4]]},"1234":{"position":[[1429,4],[1480,5],[1569,6]]},"2947":{"position":[[5198,4]]}}}],["rais",{"_index":1251,"t":{"176":{"position":[[1406,5]]},"247":{"position":[[956,5]]},"284":{"position":[[622,5]]},"355":{"position":[[44,5]]},"381":{"position":[[1481,7]]},"1458":{"position":[[45,6]]},"2647":{"position":[[1258,6]]},"3016":{"position":[[660,6]]}}}],["ralli",{"_index":8372,"t":{"2190":{"position":[[454,6]]},"2248":{"position":[[658,6]]}}}],["ram",{"_index":406,"t":{"37":{"position":[[121,4]]},"40":{"position":[[119,4]]},"730":{"position":[[2370,3]]},"734":{"position":[[246,3]]},"750":{"position":[[491,3]]},"792":{"position":[[87,3]]},"821":{"position":[[2636,6],[3949,6],[5285,6]]},"859":{"position":[[2322,4]]},"1165":{"position":[[1482,3]]},"1252":{"position":[[540,3]]},"1491":{"position":[[2370,3]]},"1495":{"position":[[246,3]]},"1511":{"position":[[2636,6],[3949,6],[5285,6]]},"1529":{"position":[[87,3]]},"1562":{"position":[[312,3]]},"1603":{"position":[[2322,4]]},"1775":{"position":[[152,3]]},"1845":{"position":[[273,4]]},"1874":{"position":[[272,3]]},"1990":{"position":[[272,3]]},"2536":{"position":[[203,4]]},"2550":{"position":[[262,4]]},"2697":{"position":[[649,4],[1300,4]]},"2700":{"position":[[257,3]]},"2702":{"position":[[424,3]]},"2711":{"position":[[899,3],[1262,4]]},"2713":{"position":[[530,3],[1123,3]]},"2715":{"position":[[731,4]]},"2733":{"position":[[63,4],[156,4],[227,3],[317,4],[447,4],[504,4]]},"2742":{"position":[[548,4],[1199,4]]},"2745":{"position":[[257,3]]},"2747":{"position":[[424,3]]},"2756":{"position":[[465,4],[543,4],[840,3]]},"2772":{"position":[[63,4],[156,4],[227,3],[317,4],[447,4],[504,4]]},"2786":{"position":[[198,3]]},"2832":{"position":[[649,4]]},"2835":{"position":[[198,3]]},"2854":{"position":[[63,4],[156,4],[227,3],[317,4],[448,4],[505,4]]},"2856":{"position":[[877,3],[1239,4]]},"2858":{"position":[[527,3],[933,3]]},"2927":{"position":[[33,3]]},"2929":{"position":[[33,3]]},"2931":{"position":[[58,4]]},"2933":{"position":[[302,3],[793,4]]},"2947":{"position":[[851,3]]},"2949":{"position":[[843,3]]},"2960":{"position":[[1172,3]]},"3372":{"position":[[752,3]]},"3393":{"position":[[262,4]]},"3400":{"position":[[614,4],[903,4]]}}}],["ram[gib",{"_index":9113,"t":{"2702":{"position":[[21,8]]},"2747":{"position":[[21,8]]},"2837":{"position":[[18,8]]}}}],["ran",{"_index":10033,"t":{"3272":{"position":[[723,3]]}}}],["rancher",{"_index":3785,"t":{"798":{"position":[[605,7]]},"1535":{"position":[[605,7]]},"3270":{"position":[[1584,7]]}}}],["rancher/k3s:v1.28.8",{"_index":8199,"t":{"2104":{"position":[[52,19]]}}}],["ranchero",{"_index":3784,"t":{"798":{"position":[[574,9],[1161,9],[1177,9],[1193,9],[1289,9]]},"1535":{"position":[[574,9],[1161,9],[1177,9],[1193,9],[1289,9]]}}}],["random",{"_index":3247,"t":{"615":{"position":[[207,6]]},"813":{"position":[[331,6]]},"819":{"position":[[1300,7],[3087,6],[3620,6],[3636,6]]},"1503":{"position":[[331,6]]},"1509":{"position":[[1300,7],[3087,6],[3620,6],[3636,6]]},"1585":{"position":[[2252,7]]},"2700":{"position":[[558,6]]},"2745":{"position":[[558,6]]},"2868":{"position":[[130,10]]},"2872":{"position":[[79,10],[562,6],[1170,6]]}}}],["randomli",{"_index":3055,"t":{"596":{"position":[[1585,8]]}}}],["randread",{"_index":6965,"t":{"1475":{"position":[[174,10]]}}}],["randwrit",{"_index":6964,"t":{"1475":{"position":[[155,11]]}}}],["rang",{"_index":1712,"t":{"247":{"position":[[2859,5]]},"327":{"position":[[379,5]]},"381":{"position":[[1161,7],[1224,5]]},"483":{"position":[[961,5],[1065,5]]},"487":{"position":[[149,5],[240,5],[327,5]]},"690":{"position":[[57,5],[194,5]]},"903":{"position":[[763,5]]},"956":{"position":[[1053,5]]},"1071":{"position":[[51,5]]},"1124":{"position":[[341,5]]},"1625":{"position":[[763,5]]},"1855":{"position":[[679,7]]},"1917":{"position":[[679,7]]},"2075":{"position":[[100,6],[437,7],[476,7],[514,6]]},"2079":{"position":[[207,5]]},"2081":{"position":[[175,5]]},"2083":{"position":[[521,5]]},"2152":{"position":[[311,5]]},"2315":{"position":[[1529,7]]},"2350":{"position":[[763,5]]},"2405":{"position":[[1059,7]]},"2486":{"position":[[17,5]]},"2514":{"position":[[328,5]]},"2617":{"position":[[57,5],[191,5]]},"2795":{"position":[[57,5],[194,5]]},"2820":{"position":[[60,5]]},"2944":{"position":[[1870,5]]},"2947":{"position":[[4279,5]]},"2975":{"position":[[57,5],[194,5]]},"3088":{"position":[[413,5],[426,5]]},"3107":{"position":[[516,5],[529,5]]},"3150":{"position":[[491,5]]},"3236":{"position":[[509,5]]},"3301":{"position":[[32,5],[224,5]]},"3343":{"position":[[937,7],[1317,5]]},"3357":{"position":[[161,5],[510,5]]}}}],["range(4",{"_index":835,"t":{"131":{"position":[[370,9]]}}}],["range.respons",{"_index":8289,"t":{"2148":{"position":[[160,14],[665,14]]}}}],["range.split",{"_index":8284,"t":{"2148":{"position":[[37,11],[323,11]]}}}],["rapid",{"_index":9266,"t":{"2725":{"position":[[579,6]]},"2764":{"position":[[800,6]]}}}],["rare",{"_index":1137,"t":{"170":{"position":[[1347,6]]},"2719":{"position":[[832,6]]},"2758":{"position":[[830,6]]},"3376":{"position":[[561,6]]},"3440":{"position":[[239,6]]}}}],["rate",{"_index":2501,"t":{"436":{"position":[[28,4],[121,4],[303,4],[672,4],[1327,4],[1440,4],[1486,4],[1597,4]]},"633":{"position":[[699,4],[1950,4],[2657,4]]},"3266":{"position":[[264,4]]},"3270":{"position":[[0,4],[723,4],[1592,4],[2271,4]]},"3280":{"position":[[716,4]]},"3288":{"position":[[13,4]]},"3393":{"position":[[603,5]]},"3400":{"position":[[1154,5]]}}}],["ratelimit",{"_index":8276,"t":{"2142":{"position":[[279,14]]},"3270":{"position":[[277,9],[375,9],[1055,9],[1196,9]]},"3280":{"position":[[509,9]]}}}],["ratio",{"_index":1444,"t":{"204":{"position":[[390,5]]},"212":{"position":[[103,5]]},"1165":{"position":[[1497,5]]},"2711":{"position":[[177,5]]},"2856":{"position":[[179,5]]}}}],["rational",{"_index":10190,"t":{"3370":{"position":[[466,9]]},"3482":{"position":[[202,10],[1491,10],[2301,10],[2639,10]]}}}],["raw",{"_index":801,"t":{"129":{"position":[[79,3]]},"284":{"position":[[785,3],[840,3]]},"487":{"position":[[1024,3]]},"786":{"position":[[358,4],[520,3],[1028,4],[1199,3],[1325,3]]},"1184":{"position":[[1204,3],[1337,4]]},"1523":{"position":[[358,4],[520,3],[1028,4],[1199,3],[1325,3]]},"1839":{"position":[[39,3],[137,3],[224,3]]},"1841":{"position":[[254,3],[504,3]]},"1843":{"position":[[707,3]]},"1872":{"position":[[217,3]]},"1878":{"position":[[519,3]]},"1913":{"position":[[1035,3],[1877,3]]},"1988":{"position":[[217,3]]},"1994":{"position":[[519,3]]},"2029":{"position":[[1035,3],[1877,3]]},"2150":{"position":[[242,3]]},"2426":{"position":[[776,3]]},"2805":{"position":[[268,3]]},"2807":{"position":[[623,3]]},"2811":{"position":[[260,3]]},"2899":{"position":[[1070,3]]}}}],["raw/direct",{"_index":9622,"t":{"2947":{"position":[[3487,10]]}}}],["ray",{"_index":844,"t":{"131":{"position":[[573,4]]}}}],["rb",{"_index":7983,"t":{"1913":{"position":[[1425,6]]},"2029":{"position":[[1425,6]]}}}],["rbac",{"_index":3905,"t":{"821":{"position":[[3299,4],[3407,4],[4639,4],[4748,4],[5956,4],[6065,4]]},"1511":{"position":[[3299,4],[3407,4],[4639,4],[4748,4],[5956,4],[6065,4]]},"1972":{"position":[[700,4]]},"2033":{"position":[[753,4]]},"3099":{"position":[[196,4],[264,4],[279,4]]},"3105":{"position":[[150,4]]},"3109":{"position":[[12,4],[327,4],[1241,4],[1443,4],[2595,4]]},"3115":{"position":[[107,4]]},"3119":{"position":[[153,4]]},"3121":{"position":[[39,4]]},"3236":{"position":[[1707,7]]},"3238":{"position":[[793,5]]},"3314":{"position":[[201,4]]},"3455":{"position":[[85,4],[193,4],[234,4],[277,4],[318,4],[363,4]]},"3465":{"position":[[376,4],[1049,4],[1256,4]]},"3472":{"position":[[12990,4]]},"3477":{"position":[[336,4]]},"3482":{"position":[[284,4],[3266,4]]},"3484":{"position":[[389,4]]}}}],["rbac.authorization.k8s.io",{"_index":8096,"t":{"2033":{"position":[[1156,25]]}}}],["rbac.authorization.k8s.io/v1",{"_index":8088,"t":{"2033":{"position":[[800,28],[1042,28]]}}}],["rbac_polici",{"_index":3894,"t":{"821":{"position":[[2748,14],[4076,14],[5401,14]]},"1511":{"position":[[2748,14],[4076,14],[5401,14]]}}}],["rbacpolici",{"_index":3960,"t":{"842":{"position":[[402,10],[1992,10],[2091,10]]},"1557":{"position":[[402,10],[1992,10],[2091,10]]}}}],["rbd",{"_index":805,"t":{"129":{"position":[[149,4]]},"786":{"position":[[590,4]]},"1110":{"position":[[338,5]]},"1184":{"position":[[1394,3]]},"1458":{"position":[[186,3],[231,4]]},"1523":{"position":[[590,4]]}}}],["rbdmirror_group_nam",{"_index":5385,"t":{"1120":{"position":[[1579,21]]}}}],["rc",{"_index":157,"t":{"10":{"position":[[1509,2]]},"467":{"position":[[376,2],[469,2]]},"903":{"position":[[3180,3],[3189,3]]},"1146":{"position":[[541,2]]},"1625":{"position":[[3180,3],[3189,3]]},"1721":{"position":[[3974,5]]},"2350":{"position":[[3180,3],[3189,3]]}}}],["rc=0",{"_index":4352,"t":{"903":{"position":[[2857,4]]},"1333":{"position":[[205,4]]},"1625":{"position":[[2857,4]]},"2350":{"position":[[2857,4]]}}}],["rc=1",{"_index":4357,"t":{"903":{"position":[[3070,5]]},"1625":{"position":[[3070,5]]},"2350":{"position":[[3070,5]]}}}],["rc=2",{"_index":4359,"t":{"903":{"position":[[3131,5]]},"1625":{"position":[[3131,5]]},"2350":{"position":[[3131,5]]}}}],["rdbm",{"_index":6048,"t":{"1226":{"position":[[1598,5]]}}}],["rdna1=1",{"_index":9298,"t":{"2727":{"position":[[471,8]]},"2766":{"position":[[671,8]]},"2852":{"position":[[823,8]]}}}],["rdna2=2",{"_index":9299,"t":{"2727":{"position":[[480,8]]},"2766":{"position":[[680,8]]},"2852":{"position":[[832,9]]}}}],["rdna3=3",{"_index":9300,"t":{"2727":{"position":[[489,8]]},"2766":{"position":[[689,8]]}}}],["rdrand",{"_index":9492,"t":{"2872":{"position":[[442,6]]},"2883":{"position":[[93,6]]}}}],["rdseed",{"_index":9491,"t":{"2872":{"position":[[432,6]]},"2883":{"position":[[83,6]]}}}],["re",{"_index":2010,"t":{"321":{"position":[[933,2]]},"497":{"position":[[509,2]]},"604":{"position":[[10611,2],[10739,2]]},"627":{"position":[[2660,2]]},"631":{"position":[[983,2]]},"635":{"position":[[286,2],[536,2]]},"909":{"position":[[2811,2]]},"1112":{"position":[[4826,2]]},"1344":{"position":[[80,2]]},"1358":{"position":[[291,2]]},"1631":{"position":[[2811,2]]},"1779":{"position":[[4348,2]]},"1900":{"position":[[46,2]]},"2016":{"position":[[46,2]]},"2356":{"position":[[2811,2]]},"3103":{"position":[[357,2]]},"3249":{"position":[[374,2]]},"3423":{"position":[[181,2]]},"3465":{"position":[[0,2]]},"3482":{"position":[[812,2]]}}}],["reach",{"_index":1352,"t":{"187":{"position":[[428,8]]},"274":{"position":[[346,5]]},"1067":{"position":[[1663,7],[4271,7]]},"1236":{"position":[[573,5]]},"1585":{"position":[[282,5],[372,7]]},"1794":{"position":[[1030,7]]},"1892":{"position":[[816,7],[1015,7]]},"1908":{"position":[[2890,7]]},"2008":{"position":[[816,7],[1015,7]]},"2024":{"position":[[2890,7]]},"2214":{"position":[[247,7]]},"2461":{"position":[[72,7]]},"2737":{"position":[[126,8]]},"2776":{"position":[[126,8]]},"2962":{"position":[[408,7]]},"3465":{"position":[[356,8]]}}}],["reachabl",{"_index":4315,"t":{"899":{"position":[[125,12],[921,12],[998,12]]},"903":{"position":[[3245,9]]},"1224":{"position":[[2972,9],[3789,9]]},"1621":{"position":[[125,12],[921,12],[998,12]]},"1625":{"position":[[3245,9]]},"1743":{"position":[[1945,9]]},"2346":{"position":[[125,12],[921,12],[998,12]]},"2350":{"position":[[3245,9]]},"3308":{"position":[[231,9]]},"3316":{"position":[[1802,9]]}}}],["reactiv",{"_index":3796,"t":{"800":{"position":[[312,13]]},"1537":{"position":[[312,13]]}}}],["read",{"_index":678,"t":{"105":{"position":[[1010,4]]},"235":{"position":[[1117,4]]},"325":{"position":[[4109,8]]},"347":{"position":[[538,4],[617,4]]},"393":{"position":[[1784,4]]},"421":{"position":[[1556,4]]},"427":{"position":[[897,4]]},"428":{"position":[[121,4]]},"489":{"position":[[792,4]]},"497":{"position":[[477,5]]},"525":{"position":[[214,4]]},"609":{"position":[[2471,4],[5334,4]]},"627":{"position":[[3230,4]]},"760":{"position":[[370,4]]},"905":{"position":[[989,4]]},"986":{"position":[[179,4]]},"1065":{"position":[[128,4]]},"1080":{"position":[[15,4],[106,4]]},"1351":{"position":[[119,4],[1943,4]]},"1446":{"position":[[174,4]]},"1448":{"position":[[5,4]]},"1462":{"position":[[465,4]]},"1475":{"position":[[167,6]]},"1627":{"position":[[989,4]]},"1684":{"position":[[924,4]]},"1728":{"position":[[382,4],[728,5],[801,5],[863,5],[893,5]]},"1825":{"position":[[15,4],[106,4]]},"2098":{"position":[[992,4]]},"2164":{"position":[[497,4],[512,4],[817,4],[844,4]]},"2352":{"position":[[989,4]]},"2474":{"position":[[270,4]]},"2879":{"position":[[193,4],[278,4]]},"2935":{"position":[[37,4]]},"2994":{"position":[[36,4]]},"3236":{"position":[[978,4]]},"3314":{"position":[[349,4]]},"3316":{"position":[[481,4]]},"3359":{"position":[[62,4]]}}}],["read(16",{"_index":7292,"t":{"1728":{"position":[[444,8]]}}}],["read/writ",{"_index":9485,"t":{"2872":{"position":[[97,10]]}}}],["read_bytes_sec",{"_index":6546,"t":{"1351":{"position":[[2972,14]]}}}],["read_bytes_sec_max",{"_index":6549,"t":{"1351":{"position":[[3051,18]]}}}],["read_iops_sec",{"_index":6540,"t":{"1351":{"position":[[2813,13]]}}}],["read_iops_sec='1000",{"_index":6532,"t":{"1351":{"position":[[530,21],[1041,21],[1763,21]]}}}],["read_iops_sec='2000",{"_index":6538,"t":{"1351":{"position":[[2577,21]]}}}],["read_iops_sec=1000",{"_index":6525,"t":{"1351":{"position":[[228,18]]}}}],["read_iops_sec=2000",{"_index":6536,"t":{"1351":{"position":[[2099,18]]}}}],["read_iops_sec_max",{"_index":6543,"t":{"1351":{"position":[[2884,17]]}}}],["readabl",{"_index":2074,"t":{"325":{"position":[[3641,8]]},"368":{"position":[[450,11]]},"905":{"position":[[1649,8]]},"907":{"position":[[368,8]]},"932":{"position":[[1075,8],[1135,9]]},"1364":{"position":[[415,12],[567,9]]},"1627":{"position":[[1649,8]]},"1629":{"position":[[368,8]]},"1654":{"position":[[1075,8],[1135,9]]},"2330":{"position":[[192,8]]},"2352":{"position":[[1649,8]]},"2354":{"position":[[368,8]]},"2379":{"position":[[1075,8],[1135,9]]},"2530":{"position":[[237,8]]},"2548":{"position":[[357,8]]},"2731":{"position":[[527,8]]},"2770":{"position":[[527,8]]},"2797":{"position":[[281,8]]},"2803":{"position":[[23,8]]},"2820":{"position":[[147,11]]},"2860":{"position":[[489,8]]},"2897":{"position":[[300,8]]},"2977":{"position":[[275,8]]}}}],["reader",{"_index":2577,"t":{"462":{"position":[[413,7]]},"2047":{"position":[[667,6]]},"2122":{"position":[[521,6]]},"3057":{"position":[[236,7]]},"3472":{"position":[[13645,8]]}}}],["reader':%(target.role.name)",{"_index":8124,"t":{"2047":{"position":[[774,30]]},"3472":{"position":[[13941,30]]}}}],["readfilesync('./docs.package.json",{"_index":684,"t":{"105":{"position":[[1107,36]]}}}],["readi",{"_index":618,"t":{"93":{"position":[[20,5]]},"231":{"position":[[134,5],[194,5]]},"335":{"position":[[1143,5]]},"349":{"position":[[818,5]]},"389":{"position":[[438,6],[488,6]]},"396":{"position":[[490,5],[549,5]]},"398":{"position":[[384,5]]},"409":{"position":[[88,5]]},"590":{"position":[[727,6],[1163,9],[1331,5]]},"641":{"position":[[632,5],[863,5],[1156,5]]},"646":{"position":[[678,5],[1421,5],[1564,6],[2015,6],[2112,5]]},"660":{"position":[[3134,5],[3476,5]]},"738":{"position":[[535,6]]},"909":{"position":[[748,5]]},"954":{"position":[[162,5]]},"1112":{"position":[[5685,5]]},"1224":{"position":[[633,5],[4024,6]]},"1264":{"position":[[191,6]]},"1569":{"position":[[1481,5]]},"1571":{"position":[[1425,5]]},"1631":{"position":[[748,5]]},"1829":{"position":[[152,6]]},"2079":{"position":[[482,6]]},"2196":{"position":[[479,6],[794,5]]},"2214":{"position":[[95,5]]},"2226":{"position":[[270,6]]},"2229":{"position":[[254,5]]},"2248":{"position":[[909,5]]},"2356":{"position":[[748,5]]},"2461":{"position":[[675,5]]},"2635":{"position":[[28,5]]},"3299":{"position":[[1810,5]]},"3301":{"position":[[1534,5],[3732,5],[4754,5],[6534,6]]},"3393":{"position":[[346,6]]},"3400":{"position":[[987,6]]}}}],["readili",{"_index":9511,"t":{"2874":{"position":[[914,7]]}}}],["readm",{"_index":696,"t":{"105":{"position":[[1347,6],[1700,6]]},"280":{"position":[[811,7]]},"393":{"position":[[1568,6]]},"1232":{"position":[[703,6]]},"2192":{"position":[[9,7]]},"2202":{"position":[[9,6]]},"2463":{"position":[[537,6]]},"2660":{"position":[[162,6]]},"2783":{"position":[[241,6]]}}}],["readme.md",{"_index":710,"t":{"105":{"position":[[1764,11]]},"895":{"position":[[1771,9]]},"909":{"position":[[530,9],[1200,10]]},"913":{"position":[[3425,9]]},"1617":{"position":[[1771,9]]},"1631":{"position":[[530,9],[1200,10]]},"1635":{"position":[[3425,9]]},"2342":{"position":[[1771,9]]},"2356":{"position":[[530,9],[1200,10]]},"2360":{"position":[[3425,9]]},"3061":{"position":[[1151,10]]},"3479":{"position":[[301,9]]}}}],["readonli",{"_index":2481,"t":{"427":{"position":[[1260,10],[1293,8]]},"428":{"position":[[291,8],[879,8],[916,8],[1249,8],[1868,8],[1916,8],[1973,8],[2026,8]]},"474":{"position":[[18,8],[1328,8]]}}}],["readonlyport",{"_index":9975,"t":{"3236":{"position":[[953,12]]}}}],["readwriteonc",{"_index":8978,"t":{"2586":{"position":[[260,13]]},"3141":{"position":[[0,13]]}}}],["real",{"_index":2518,"t":{"436":{"position":[[1345,4]]},"487":{"position":[[4447,4],[4713,4]]},"505":{"position":[[1011,4]]},"507":{"position":[[261,4]]},"511":{"position":[[283,4]]},"604":{"position":[[4356,4]]},"905":{"position":[[523,4]]},"982":{"position":[[839,4]]},"984":{"position":[[675,4]]},"988":{"position":[[162,4]]},"990":{"position":[[562,4]]},"1395":{"position":[[684,4]]},"1462":{"position":[[88,4]]},"1627":{"position":[[523,4]]},"1783":{"position":[[97,4]]},"2188":{"position":[[193,4]]},"2229":{"position":[[755,4]]},"2352":{"position":[[523,4]]},"2468":{"position":[[588,4]]},"2874":{"position":[[485,4]]},"2947":{"position":[[3447,4]]},"3059":{"position":[[1215,4]]},"3182":{"position":[[2281,4]]},"3214":{"position":[[89,4]]},"3216":{"position":[[311,4]]},"3218":{"position":[[257,4],[504,4],[765,5],[1210,4],[1425,4],[1862,4]]},"3220":{"position":[[49,4]]},"3222":{"position":[[447,4],[811,4]]},"3224":{"position":[[742,4],[1084,4],[1586,4]]},"3316":{"position":[[846,4]]}}}],["realist",{"_index":8252,"t":{"2118":{"position":[[1635,9]]},"2947":{"position":[[1563,9]]},"3218":{"position":[[1721,9]]},"3222":{"position":[[750,9]]},"3224":{"position":[[842,9],[1517,9]]}}}],["realiti",{"_index":8255,"t":{"2118":{"position":[[1739,8]]},"2949":{"position":[[819,7]]}}}],["realiz",{"_index":5037,"t":{"1080":{"position":[[1578,8]]},"1825":{"position":[[1741,8]]}}}],["realli",{"_index":803,"t":{"129":{"position":[[98,6]]},"151":{"position":[[62,6]]},"786":{"position":[[539,6]]},"821":{"position":[[1590,6]]},"1364":{"position":[[37,6]]},"1397":{"position":[[391,7],[399,6]]},"1428":{"position":[[446,6]]},"1460":{"position":[[130,6],[137,6]]},"1511":{"position":[[1590,6]]},"1523":{"position":[[539,6]]},"1756":{"position":[[42,6]]},"2196":{"position":[[633,6]]},"2886":{"position":[[94,6]]}}}],["realm",{"_index":1950,"t":{"298":{"position":[[1022,5]]},"300":{"position":[[177,6],[399,5],[473,7]]},"1791":{"position":[[864,5],[882,5],[1204,5]]},"1957":{"position":[[570,5],[985,5],[1359,5],[1481,5],[2702,5],[3302,5]]},"1959":{"position":[[112,5],[160,6],[201,7],[249,6],[353,5],[472,5],[523,5],[545,5],[596,5],[639,5],[685,5],[704,6],[760,6],[815,6],[874,6],[1125,6],[1179,6]]},"1974":{"position":[[310,5]]},"2409":{"position":[[185,5]]},"2476":{"position":[[209,5],[307,5],[375,6],[467,5],[498,6]]},"3251":{"position":[[1659,9],[1799,6],[1918,5],[2021,5],[4800,7]]},"3325":{"position":[[2408,6],[2498,5],[2598,5],[2641,6],[2700,6],[2744,5],[2932,5],[2964,5],[3153,5],[3472,5],[3540,5]]}}}],["realtim",{"_index":4271,"t":{"865":{"position":[[477,8]]},"878":{"position":[[477,8]]},"1226":{"position":[[1691,8],[1713,8]]}}}],["ream",{"_index":8571,"t":{"2476":{"position":[[521,4]]}}}],["reanim",{"_index":9090,"t":{"2688":{"position":[[1613,10]]}}}],["reason",{"_index":1208,"t":{"174":{"position":[[895,10]]},"176":{"position":[[447,7]]},"298":{"position":[[961,6]]},"370":{"position":[[503,6]]},"404":{"position":[[584,9]]},"503":{"position":[[450,7]]},"586":{"position":[[555,10]]},"590":{"position":[[1226,7],[1346,6]]},"604":{"position":[[10776,6]]},"660":{"position":[[1330,6],[3144,6],[3486,6]]},"742":{"position":[[636,7]]},"772":{"position":[[532,8]]},"897":{"position":[[104,10]]},"899":{"position":[[552,7]]},"909":{"position":[[1307,8]]},"913":{"position":[[3994,6]]},"932":{"position":[[3787,10]]},"1358":{"position":[[387,6]]},"1368":{"position":[[1785,7],[2464,7]]},"1375":{"position":[[437,6]]},"1377":{"position":[[438,6],[1442,6]]},"1462":{"position":[[296,10]]},"1619":{"position":[[104,10]]},"1621":{"position":[[552,7]]},"1631":{"position":[[1307,8]]},"1635":{"position":[[3994,6]]},"1654":{"position":[[3787,10]]},"1955":{"position":[[26,10]]},"2100":{"position":[[1009,6]]},"2116":{"position":[[471,7]]},"2209":{"position":[[247,7],[320,7]]},"2235":{"position":[[299,6]]},"2344":{"position":[[104,10]]},"2346":{"position":[[552,7]]},"2356":{"position":[[1307,8]]},"2360":{"position":[[3994,6]]},"2379":{"position":[[3787,10]]},"2504":{"position":[[447,7]]},"2627":{"position":[[1528,9]]},"2688":{"position":[[2547,7]]},"2697":{"position":[[1399,10]]},"2713":{"position":[[1272,6]]},"2735":{"position":[[158,6]]},"2742":{"position":[[1298,10]]},"2756":{"position":[[989,6]]},"2774":{"position":[[294,6]]},"2858":{"position":[[1082,6]]},"2895":{"position":[[1950,6]]},"2899":{"position":[[403,7]]},"2906":{"position":[[109,10]]},"2913":{"position":[[267,8]]},"2939":{"position":[[544,8]]},"2947":{"position":[[2196,10],[4021,6],[4844,8]]},"3169":{"position":[[349,10]]},"3206":{"position":[[469,7]]},"3208":{"position":[[921,10]]},"3249":{"position":[[163,10]]},"3251":{"position":[[855,12]]},"3255":{"position":[[445,7],[556,8]]},"3272":{"position":[[186,8]]},"3274":{"position":[[423,7]]},"3419":{"position":[[551,7]]},"3423":{"position":[[77,8]]},"3442":{"position":[[120,10]]},"3475":{"position":[[264,6]]},"3493":{"position":[[76,9]]}}}],["reason_cod",{"_index":8894,"t":{"2566":{"position":[[10437,12]]}}}],["reassign",{"_index":7357,"t":{"1740":{"position":[[276,10]]}}}],["reattach",{"_index":4408,"t":{"909":{"position":[[605,10]]},"1631":{"position":[[605,10]]},"2356":{"position":[[605,10]]}}}],["rebal",{"_index":6879,"t":{"1428":{"position":[[298,9]]}}}],["rebalanc",{"_index":6954,"t":{"1473":{"position":[[1298,11]]},"1728":{"position":[[1409,11]]}}}],["reboot",{"_index":5096,"t":{"1089":{"position":[[2576,9]]},"1224":{"position":[[2777,6],[2800,6],[2901,6],[3098,9],[3278,8],[3576,6],[3671,6],[3718,6]]},"1258":{"position":[[598,6],[671,6],[856,6]]},"1260":{"position":[[415,6],[449,6]]},"1279":{"position":[[11,6],[36,8],[161,6],[225,6],[299,6],[389,6],[458,6],[490,6]]},"1358":{"position":[[183,6],[219,6],[284,6]]},"1379":{"position":[[481,6]]},"1571":{"position":[[677,8]]},"1766":{"position":[[1186,8]]}}}],["reboot_wait=tru",{"_index":6139,"t":{"1279":{"position":[[311,16]]}}}],["rebuilt",{"_index":3767,"t":{"796":{"position":[[58,7]]},"798":{"position":[[62,8],[198,7]]},"1533":{"position":[[58,7]]},"1535":{"position":[[62,8],[198,7]]},"1731":{"position":[[3295,8]]},"2468":{"position":[[343,7]]}}}],["recal",{"_index":2116,"t":{"325":{"position":[[7439,6]]}}}],["receiv",{"_index":1056,"t":{"168":{"position":[[395,8]]},"180":{"position":[[107,8]]},"379":{"position":[[307,8]]},"509":{"position":[[369,7]]},"513":{"position":[[1649,8]]},"627":{"position":[[3547,7]]},"920":{"position":[[300,7]]},"1256":{"position":[[2011,7]]},"1642":{"position":[[300,7]]},"1894":{"position":[[110,8],[236,9]]},"1900":{"position":[[107,9]]},"1904":{"position":[[223,7]]},"2010":{"position":[[110,8],[236,9]]},"2016":{"position":[[107,9]]},"2020":{"position":[[223,7]]},"2071":{"position":[[174,8]]},"2116":{"position":[[764,9]]},"2158":{"position":[[418,8]]},"2248":{"position":[[688,8]]},"2283":{"position":[[651,7]]},"2315":{"position":[[1052,8]]},"2332":{"position":[[56,7]]},"2367":{"position":[[300,7]]},"2411":{"position":[[120,8]]},"2901":{"position":[[1346,7],[1567,7]]},"3251":{"position":[[4941,7]]},"3419":{"position":[[192,8]]}}}],["received:\\nssh",{"_index":6024,"t":{"1224":{"position":[[3416,15]]}}}],["receiver.yaml",{"_index":8133,"t":{"2071":{"position":[[314,13],[410,13]]}}}],["receiver_project",{"_index":8766,"t":{"2566":{"position":[[4261,17]]}}}],["receiver_us",{"_index":8768,"t":{"2566":{"position":[[4314,14]]}}}],["recenc",{"_index":8543,"t":{"2426":{"position":[[381,8]]},"3126":{"position":[[1099,7]]},"3175":{"position":[[52,7]]}}}],["recent",{"_index":1150,"t":{"170":{"position":[[1921,6]]},"2162":{"position":[[222,6]]},"2675":{"position":[[859,6]]},"2809":{"position":[[898,6]]},"2872":{"position":[[204,6]]},"2874":{"position":[[120,6]]},"2906":{"position":[[120,7]]},"2913":{"position":[[382,6]]},"3078":{"position":[[1149,6]]},"3124":{"position":[[124,6]]},"3251":{"position":[[5093,8]]},"3316":{"position":[[1669,6],[1689,6]]},"3363":{"position":[[281,6]]},"3472":{"position":[[12472,6]]}}}],["recheck",{"_index":2011,"t":{"321":{"position":[[963,7]]},"325":{"position":[[7424,7]]}}}],["reciev",{"_index":9813,"t":{"3109":{"position":[[973,8]]},"3397":{"position":[[970,8]]}}}],["recip",{"_index":9892,"t":{"3154":{"position":[[281,8]]}}}],["recipi",{"_index":1051,"t":{"168":{"position":[[94,9],[305,10]]},"176":{"position":[[886,10]]},"920":{"position":[[935,10]]},"1642":{"position":[[935,10]]},"2367":{"position":[[935,10]]}}}],["reciproc",{"_index":1048,"t":{"168":{"position":[[31,10],[523,11]]},"170":{"position":[[1095,10],[1687,10]]},"172":{"position":[[4,11]]}}}],["recit",{"_index":3720,"t":{"786":{"position":[[419,7]]},"1523":{"position":[[419,7]]}}}],["recogn",{"_index":2840,"t":{"491":{"position":[[23,10]]},"1783":{"position":[[637,10]]},"2647":{"position":[[427,9]]},"2923":{"position":[[30,11]]},"3055":{"position":[[373,11]]},"3218":{"position":[[92,9]]},"3343":{"position":[[484,10]]}}}],["recognis",{"_index":9395,"t":{"2832":{"position":[[897,13]]}}}],["recogniz",{"_index":9100,"t":{"2697":{"position":[[897,13]]},"2742":{"position":[[796,13]]}}}],["recommend",{"_index":94,"t":{"10":{"position":[[358,9],[799,9],[866,11]]},"158":{"position":[[6,11],[787,11]]},"170":{"position":[[1842,15]]},"202":{"position":[[47,15]]},"251":{"position":[[77,11]]},"325":{"position":[[378,11]]},"363":{"position":[[470,9]]},"368":{"position":[[119,13],[157,13]]},"370":{"position":[[278,16]]},"379":{"position":[[890,11]]},"381":{"position":[[1149,11],[1212,11]]},"413":{"position":[[470,11]]},"428":{"position":[[1208,11]]},"460":{"position":[[484,15]]},"483":{"position":[[1133,11]]},"487":{"position":[[3125,12]]},"519":{"position":[[419,11]]},"552":{"position":[[228,11]]},"583":{"position":[[551,9]]},"596":{"position":[[489,11],[2745,9]]},"598":{"position":[[437,11],[655,11]]},"604":{"position":[[6018,9],[6519,9]]},"609":{"position":[[1973,13],[4775,13]]},"615":{"position":[[527,9],[668,9]]},"635":{"position":[[69,9]]},"639":{"position":[[326,11]]},"646":{"position":[[864,11]]},"650":{"position":[[98,11]]},"656":{"position":[[210,11]]},"660":{"position":[[253,12]]},"730":{"position":[[781,11],[800,11],[1082,11],[1175,11],[1443,11]]},"732":{"position":[[135,11]]},"901":{"position":[[294,11]]},"909":{"position":[[1731,14]]},"911":{"position":[[1371,9]]},"917":{"position":[[313,11]]},"938":{"position":[[6,11],[243,11]]},"980":{"position":[[441,14]]},"984":{"position":[[329,11]]},"986":{"position":[[202,15],[317,9]]},"995":{"position":[[6,11]]},"1055":{"position":[[1314,11]]},"1114":{"position":[[3122,11]]},"1120":{"position":[[851,11]]},"1150":{"position":[[87,12]]},"1184":{"position":[[221,11],[500,11]]},"1224":{"position":[[1241,13],[1620,13],[2699,11],[2824,11]]},"1232":{"position":[[312,11]]},"1234":{"position":[[1404,11],[1437,12],[1597,12],[1620,11],[1961,12]]},"1236":{"position":[[761,12]]},"1260":{"position":[[355,12]]},"1286":{"position":[[551,11]]},"1419":{"position":[[1156,11]]},"1491":{"position":[[781,11],[800,11],[1082,11],[1175,11],[1443,11]]},"1493":{"position":[[135,11]]},"1571":{"position":[[1148,12]]},"1594":{"position":[[658,11]]},"1623":{"position":[[294,11]]},"1631":{"position":[[1731,14]]},"1633":{"position":[[1371,9]]},"1639":{"position":[[313,11]]},"1660":{"position":[[6,11],[243,11]]},"1736":{"position":[[112,11]]},"1764":{"position":[[4248,11]]},"1766":{"position":[[1803,11]]},"1779":{"position":[[3863,11]]},"1791":{"position":[[1311,11]]},"1857":{"position":[[505,11]]},"1894":{"position":[[579,11]]},"1919":{"position":[[505,11]]},"2010":{"position":[[579,11]]},"2051":{"position":[[21,11]]},"2098":{"position":[[2253,9]]},"2118":{"position":[[690,12]]},"2126":{"position":[[330,9]]},"2140":{"position":[[354,11]]},"2146":{"position":[[19,11]]},"2148":{"position":[[777,15]]},"2150":{"position":[[1141,15],[1312,15]]},"2248":{"position":[[764,11]]},"2292":{"position":[[214,12]]},"2294":{"position":[[211,9]]},"2302":{"position":[[91,12]]},"2312":{"position":[[447,11]]},"2348":{"position":[[294,11]]},"2356":{"position":[[1731,14]]},"2358":{"position":[[1371,9]]},"2364":{"position":[[313,11]]},"2385":{"position":[[6,11],[243,11]]},"2426":{"position":[[310,15]]},"2540":{"position":[[171,10]]},"2548":{"position":[[139,12]]},"2550":{"position":[[45,11],[179,11]]},"2619":{"position":[[92,14]]},"2625":{"position":[[2492,11]]},"2627":{"position":[[453,9],[962,11],[1565,9]]},"2688":{"position":[[578,11]]},"2723":{"position":[[516,9],[789,12]]},"2725":{"position":[[610,11]]},"2762":{"position":[[529,9],[802,12]]},"2764":{"position":[[831,11]]},"2842":{"position":[[86,12]]},"2848":{"position":[[516,9],[747,12]]},"2850":{"position":[[503,11]]},"2852":{"position":[[37,11]]},"2879":{"position":[[6,11]]},"2881":{"position":[[6,11],[189,11]]},"2890":{"position":[[166,9]]},"2892":{"position":[[103,9],[362,12],[414,12],[571,11]]},"2895":{"position":[[6,11],[351,11],[2177,9]]},"2897":{"position":[[331,11]]},"2899":{"position":[[140,11],[903,12],[1060,9],[1199,11]]},"2927":{"position":[[0,11]]},"2929":{"position":[[0,11]]},"2931":{"position":[[232,11],[329,11]]},"2933":{"position":[[751,11]]},"2935":{"position":[[69,11],[348,11]]},"2939":{"position":[[217,16],[375,11],[487,9]]},"2944":{"position":[[1820,12]]},"2947":{"position":[[201,11]]},"2955":{"position":[[464,15]]},"2962":{"position":[[616,12]]},"2966":{"position":[[4632,10]]},"2970":{"position":[[60,11],[238,11]]},"2975":{"position":[[363,12]]},"2977":{"position":[[182,12]]},"2983":{"position":[[115,11],[127,13]]},"2985":{"position":[[240,11],[252,13]]},"2987":{"position":[[380,11],[947,12]]},"2992":{"position":[[391,11]]},"2994":{"position":[[68,11],[310,11]]},"3016":{"position":[[10,10]]},"3031":{"position":[[246,11],[308,11],[664,15]]},"3037":{"position":[[14,10]]},"3044":{"position":[[504,15]]},"3046":{"position":[[124,15]]},"3050":{"position":[[322,11]]},"3105":{"position":[[290,11]]},"3111":{"position":[[220,11],[519,9]]},"3128":{"position":[[576,11],[1149,11]]},"3132":{"position":[[441,11]]},"3162":{"position":[[290,9]]},"3186":{"position":[[1087,11]]},"3199":{"position":[[305,11],[584,11],[685,11],[779,11]]},"3251":{"position":[[5507,11]]},"3280":{"position":[[651,11],[903,11]]},"3284":{"position":[[51,11],[504,11]]},"3286":{"position":[[247,11]]},"3327":{"position":[[0,11]]},"3338":{"position":[[92,14]]},"3378":{"position":[[435,14]]},"3397":{"position":[[613,14]]},"3510":{"position":[[0,11]]}}}],["reconcil",{"_index":3024,"t":{"590":{"position":[[2102,10]]},"1112":{"position":[[3550,10],[4870,10]]},"1114":{"position":[[666,10],[1953,10],[4268,10],[5424,10]]},"1585":{"position":[[2554,10]]},"1678":{"position":[[627,10]]},"1690":{"position":[[2026,10]]},"1731":{"position":[[3310,10]]}}}],["reconciled/handl",{"_index":8054,"t":{"1976":{"position":[[269,19]]}}}],["reconciler:latest",{"_index":7331,"t":{"1731":{"position":[[2078,17]]}}}],["reconcili",{"_index":2398,"t":{"409":{"position":[[142,14],[206,14],[274,14],[339,14]]},"513":{"position":[[2308,14]]},"629":{"position":[[210,15]]},"641":{"position":[[679,14]]}}}],["reconfigur",{"_index":1945,"t":{"298":{"position":[[834,13]]},"1118":{"position":[[1182,11]]},"1146":{"position":[[239,11]]},"1169":{"position":[[656,11],[749,11]]},"3251":{"position":[[2368,12]]}}}],["reconnaiss",{"_index":8137,"t":{"2075":{"position":[[127,14]]}}}],["reconnect",{"_index":1762,"t":{"251":{"position":[[454,12]]},"909":{"position":[[318,10]]},"1631":{"position":[[318,10]]},"2356":{"position":[[318,10]]}}}],["record",{"_index":1778,"t":{"253":{"position":[[1013,6]]},"413":{"position":[[150,6]]},"442":{"position":[[69,6]]},"646":{"position":[[1731,6]]},"895":{"position":[[1240,9]]},"911":{"position":[[1389,7]]},"932":{"position":[[739,7]]},"1161":{"position":[[4,7],[1477,7]]},"1317":{"position":[[389,6],[446,6],[504,6]]},"1617":{"position":[[1240,9]]},"1633":{"position":[[1389,7]]},"1654":{"position":[[739,7]]},"1783":{"position":[[132,7]]},"1794":{"position":[[1097,7],[1171,7]]},"2162":{"position":[[481,7]]},"2342":{"position":[[1240,9]]},"2358":{"position":[[1389,7]]},"2379":{"position":[[739,7]]},"2524":{"position":[[110,7]]},"2534":{"position":[[157,6]]},"2544":{"position":[[988,6]]},"2552":{"position":[[62,6]]},"2554":{"position":[[62,6]]},"2556":{"position":[[62,6]]},"2576":{"position":[[732,6]]},"2580":{"position":[[62,6]]},"2582":{"position":[[62,6]]},"2590":{"position":[[62,6]]},"2598":{"position":[[62,6]]},"2604":{"position":[[62,6]]},"2606":{"position":[[62,6]]},"2608":{"position":[[62,6]]},"2610":{"position":[[62,6]]},"2612":{"position":[[62,6]]},"2614":{"position":[[62,6]]},"2623":{"position":[[296,7],[566,7]]},"2625":{"position":[[1816,7]]},"2627":{"position":[[1205,7],[1227,6],[1427,7]]},"2631":{"position":[[1174,6]]},"2653":{"position":[[62,6]]},"2656":{"position":[[127,7]]},"2754":{"position":[[847,6]]},"2795":{"position":[[1936,6]]},"2797":{"position":[[14,6]]},"2799":{"position":[[157,8]]},"2801":{"position":[[198,9]]},"2805":{"position":[[26,8]]},"2942":{"position":[[736,6]]},"3027":{"position":[[62,6]]},"3039":{"position":[[69,6]]},"3048":{"position":[[23,6]]},"3063":{"position":[[889,7]]},"3071":{"position":[[1715,6]]},"3128":{"position":[[545,6]]},"3160":{"position":[[430,6]]},"3180":{"position":[[62,6]]},"3197":{"position":[[83,6]]},"3386":{"position":[[25,8]]},"3450":{"position":[[25,8]]},"3518":{"position":[[1406,6]]}}}],["recov",{"_index":4629,"t":{"942":{"position":[[371,7]]},"1664":{"position":[[371,7]]},"2389":{"position":[[371,7]]},"2947":{"position":[[4445,9]]},"3182":{"position":[[2496,7]]}}}],["recover",{"_index":2264,"t":{"379":{"position":[[955,15]]}}}],["recover_after_nod",{"_index":5860,"t":{"1167":{"position":[[983,19],[1807,19]]}}}],["recoveri",{"_index":2598,"t":{"469":{"position":[[155,9]]},"596":{"position":[[2322,8]]},"1446":{"position":[[29,8],[124,8]]},"2947":{"position":[[634,8],[4245,8]]},"3160":{"position":[[1330,8]]}}}],["recreat",{"_index":3142,"t":{"604":{"position":[[6351,10]]},"627":{"position":[[3641,10],[3700,10]]},"667":{"position":[[149,10]]},"1865":{"position":[[164,9]]},"1927":{"position":[[164,9]]}}}],["recur",{"_index":6113,"t":{"1258":{"position":[[276,9]]},"1260":{"position":[[253,9]]}}}],["recurs",{"_index":718,"t":{"105":{"position":[[1936,10]]},"1167":{"position":[[4443,10],[4535,10],[5080,10],[5172,10]]}}}],["red",{"_index":2220,"t":{"370":{"position":[[234,4]]},"909":{"position":[[1573,3]]},"932":{"position":[[3581,3]]},"1631":{"position":[[1573,3]]},"1654":{"position":[[3581,3]]},"2156":{"position":[[148,4]]},"2356":{"position":[[1573,3]]},"2379":{"position":[[3581,3]]},"3251":{"position":[[125,3],[170,3]]},"3299":{"position":[[4281,3],[4309,3]]},"3301":{"position":[[2629,3],[2788,3],[3071,3]]}}}],["redact",{"_index":4514,"t":{"922":{"position":[[404,6]]},"1644":{"position":[[404,6]]},"2369":{"position":[[404,6]]}}}],["redcarpet",{"_index":859,"t":{"131":{"position":[[705,11]]}}}],["redcarpet.new(\"hello",{"_index":860,"t":{"131":{"position":[[728,20]]}}}],["redeploy",{"_index":3077,"t":{"598":{"position":[[1333,8],[1366,11]]},"2248":{"position":[[444,10]]}}}],["redfish",{"_index":4659,"t":{"956":{"position":[[1112,8]]}}}],["redhat",{"_index":4655,"t":{"954":{"position":[[539,6],[665,7]]},"1144":{"position":[[232,6]]}}}],["redi",{"_index":2403,"t":{"409":{"position":[[299,5]]},"428":{"position":[[327,5],[494,5],[834,5]]},"447":{"position":[[389,5],[505,5],[515,5],[585,5],[727,5],[744,5]]},"472":{"position":[[560,6],[587,5],[679,5],[769,5]]},"474":{"position":[[108,5],[146,5],[208,6],[304,5],[366,6],[467,5],[528,5],[630,5],[688,6],[1025,5],[1135,5]]},"641":{"position":[[1231,5],[1372,5]]},"644":{"position":[[145,6],[271,5]]},"1242":{"position":[[531,5],[557,5],[575,5]]},"1344":{"position":[[386,5],[465,5]]},"1731":{"position":[[2718,5],[2792,5]]},"1768":{"position":[[602,5],[628,5],[657,5]]},"1814":{"position":[[316,5]]},"2190":{"position":[[551,6]]}}}],["redirect",{"_index":2243,"t":{"374":{"position":[[711,8]]},"1118":{"position":[[98,8]]},"1321":{"position":[[488,11],[1340,11]]},"1791":{"position":[[300,10],[421,10]]},"1957":{"position":[[1149,8],[2574,8],[2915,8],[3112,8],[3664,8],[3977,10]]},"1959":{"position":[[320,8]]},"2476":{"position":[[441,8]]}}}],["redis.type.extern",{"_index":2542,"t":{"447":{"position":[[553,20]]}}}],["redis.type.intern",{"_index":2536,"t":{"447":{"position":[[250,20]]}}}],["redis_s",{"_index":3395,"t":{"641":{"position":[[151,11]]}}}],["redis_size:\"1gi",{"_index":2836,"t":{"487":{"position":[[5821,17]]}}}],["redistribut",{"_index":1220,"t":{"176":{"position":[[209,12]]},"178":{"position":[[561,12],[1089,12]]},"253":{"position":[[1155,13]]}}}],["redon",{"_index":7537,"t":{"1779":{"position":[[3046,6]]}}}],["reduc",{"_index":2145,"t":{"335":{"position":[[165,8]]},"633":{"position":[[2579,6]]},"696":{"position":[[54,7]]},"700":{"position":[[89,7]]},"880":{"position":[[893,7],[1046,8]]},"883":{"position":[[1363,7],[1890,6]]},"888":{"position":[[1599,7]]},"920":{"position":[[346,7]]},"947":{"position":[[1951,6]]},"956":{"position":[[628,8]]},"1430":{"position":[[442,6]]},"1642":{"position":[[346,7]]},"1669":{"position":[[1951,6]]},"1736":{"position":[[211,7]]},"1810":{"position":[[396,7]]},"1970":{"position":[[502,8]]},"2253":{"position":[[412,7]]},"2263":{"position":[[267,7]]},"2367":{"position":[[346,7]]},"2394":{"position":[[1951,6]]},"2576":{"position":[[270,8]]},"2711":{"position":[[991,7]]},"2856":{"position":[[969,7]]},"3082":{"position":[[870,8]]},"3103":{"position":[[322,6]]},"3160":{"position":[[2120,6]]},"3210":{"position":[[216,8]]},"3224":{"position":[[320,7]]},"3245":{"position":[[751,7]]},"3251":{"position":[[4747,7]]},"3343":{"position":[[154,6]]}}}],["redund",{"_index":3646,"t":{"738":{"position":[[416,9]]},"740":{"position":[[280,10]]},"776":{"position":[[88,9]]},"880":{"position":[[525,10]]},"977":{"position":[[1803,10]]},"2947":{"position":[[25,9],[724,9],[5343,10]]},"3071":{"position":[[290,9]]},"3141":{"position":[[328,9],[413,9]]},"3184":{"position":[[49,10],[880,10],[1608,9],[1894,9]]},"3186":{"position":[[188,9],[322,10]]},"3197":{"position":[[341,11]]}}}],["redundantli",{"_index":3679,"t":{"752":{"position":[[126,12]]},"768":{"position":[[168,11]]}}}],["reef",{"_index":5143,"t":{"1100":{"position":[[301,4]]},"1395":{"position":[[292,4]]},"1726":{"position":[[307,4]]},"1796":{"position":[[163,4],[195,4]]},"1812":{"position":[[140,4]]},"2098":{"position":[[499,4]]},"2459":{"position":[[164,4]]}}}],["reelect",{"_index":9608,"t":{"2947":{"position":[[1998,10],[2531,10]]}}}],["ref",{"_index":6922,"t":{"1460":{"position":[[368,3]]},"1758":{"position":[[758,3],[874,3]]}}}],["refactor",{"_index":1850,"t":{"280":{"position":[[513,10]]}}}],["refer",{"_index":489,"t":{"65":{"position":[[119,5]]},"67":{"position":[[206,5]]},"73":{"position":[[250,9]]},"79":{"position":[[685,9]]},"81":{"position":[[13,9]]},"114":{"position":[[243,9]]},"247":{"position":[[1739,9]]},"325":{"position":[[2877,10],[3534,9]]},"333":{"position":[[524,5]]},"347":{"position":[[187,9],[494,9]]},"349":{"position":[[227,9],[600,9],[656,9]]},"368":{"position":[[555,8]]},"419":{"position":[[93,6]]},"421":{"position":[[754,5]]},"423":{"position":[[127,5]]},"425":{"position":[[53,5]]},"436":{"position":[[585,9]]},"438":{"position":[[56,9]]},"462":{"position":[[264,10]]},"489":{"position":[[548,5]]},"491":{"position":[[212,10]]},"501":{"position":[[982,9]]},"523":{"position":[[138,9]]},"527":{"position":[[10,9]]},"627":{"position":[[2442,9]]},"633":{"position":[[60,9],[759,9],[1233,9],[2325,9],[2490,9]]},"648":{"position":[[755,9]]},"656":{"position":[[55,9],[262,9]]},"704":{"position":[[0,9]]},"706":{"position":[[14,9],[129,9]]},"714":{"position":[[5,6]]},"720":{"position":[[61,9]]},"722":{"position":[[0,5]]},"772":{"position":[[194,6]]},"934":{"position":[[1047,5]]},"1059":{"position":[[469,5]]},"1061":{"position":[[836,9]]},"1063":{"position":[[497,10]]},"1080":{"position":[[1023,9]]},"1086":{"position":[[61,9]]},"1108":{"position":[[1239,10]]},"1126":{"position":[[73,9]]},"1128":{"position":[[67,9]]},"1132":{"position":[[76,9]]},"1134":{"position":[[48,9]]},"1136":{"position":[[40,9]]},"1138":{"position":[[36,9]]},"1140":{"position":[[40,9]]},"1142":{"position":[[70,9]]},"1148":{"position":[[44,9]]},"1153":{"position":[[67,9]]},"1159":{"position":[[2400,5]]},"1171":{"position":[[61,9]]},"1186":{"position":[[70,9],[223,9]]},"1188":{"position":[[245,10]]},"1190":{"position":[[40,9]]},"1192":{"position":[[70,9]]},"1195":{"position":[[32,9]]},"1197":{"position":[[58,9]]},"1211":{"position":[[76,9]]},"1286":{"position":[[676,5]]},"1656":{"position":[[1047,5]]},"1770":{"position":[[167,9]]},"1779":{"position":[[854,9]]},"1785":{"position":[[377,10]]},"1825":{"position":[[1186,9]]},"1878":{"position":[[863,10],[906,5]]},"1896":{"position":[[574,9]]},"1906":{"position":[[926,9]]},"1911":{"position":[[665,11]]},"1913":{"position":[[640,9]]},"1937":{"position":[[413,9]]},"1947":{"position":[[264,9]]},"1994":{"position":[[863,10],[906,5]]},"2012":{"position":[[574,9]]},"2022":{"position":[[926,9]]},"2027":{"position":[[665,11]]},"2029":{"position":[[640,9]]},"2035":{"position":[[33,6]]},"2047":{"position":[[805,5]]},"2051":{"position":[[774,10]]},"2087":{"position":[[68,9]]},"2098":{"position":[[13,9]]},"2100":{"position":[[1096,6]]},"2104":{"position":[[294,5]]},"2106":{"position":[[270,5]]},"2112":{"position":[[68,9]]},"2126":{"position":[[268,5],[695,5]]},"2132":{"position":[[52,9]]},"2140":{"position":[[256,9]]},"2154":{"position":[[825,9],[987,8],[1043,5],[1284,6],[1495,9]]},"2164":{"position":[[343,9]]},"2166":{"position":[[43,9]]},"2170":{"position":[[43,9]]},"2176":{"position":[[340,9],[841,9],[1132,9]]},"2265":{"position":[[767,9]]},"2283":{"position":[[284,9],[375,9]]},"2298":{"position":[[767,9]]},"2312":{"position":[[406,9],[753,9]]},"2315":{"position":[[66,9]]},"2319":{"position":[[13,9],[46,5]]},"2321":{"position":[[557,9],[590,5]]},"2324":{"position":[[22,5]]},"2330":{"position":[[716,9]]},"2381":{"position":[[1047,5]]},"2403":{"position":[[9,9]]},"2409":{"position":[[862,9]]},"2415":{"position":[[13,9],[46,5]]},"2420":{"position":[[22,5]]},"2424":{"position":[[268,5]]},"2426":{"position":[[870,9]]},"2459":{"position":[[9,9]]},"2463":{"position":[[39,9]]},"2468":{"position":[[83,9]]},"2478":{"position":[[13,9],[46,5]]},"2497":{"position":[[252,9]]},"2602":{"position":[[596,9]]},"2627":{"position":[[1111,10],[1741,10]]},"2631":{"position":[[430,6],[1870,5]]},"2635":{"position":[[350,9]]},"2647":{"position":[[801,5],[1075,9]]},"2669":{"position":[[211,11]]},"2675":{"position":[[677,9]]},"2692":{"position":[[212,9],[345,5]]},"2731":{"position":[[435,5]]},"2754":{"position":[[829,5]]},"2770":{"position":[[435,5]]},"2860":{"position":[[435,5]]},"2864":{"position":[[464,9]]},"2895":{"position":[[728,9]]},"2899":{"position":[[1000,10]]},"2942":{"position":[[395,9]]},"2944":{"position":[[320,9]]},"2947":{"position":[[2429,9],[4714,9]]},"3099":{"position":[[146,10]]},"3154":{"position":[[420,9]]},"3182":{"position":[[598,9]]},"3184":{"position":[[580,9]]},"3234":{"position":[[854,9]]},"3249":{"position":[[535,9]]},"3255":{"position":[[47,9]]},"3276":{"position":[[385,9]]},"3297":{"position":[[62,9],[388,9]]},"3299":{"position":[[109,9]]},"3303":{"position":[[245,9]]},"3312":{"position":[[302,9],[443,9]]},"3325":{"position":[[715,9]]},"3351":{"position":[[298,10],[367,11],[382,9],[490,9]]},"3355":{"position":[[414,9],[457,6]]},"3391":{"position":[[42,9],[299,9]]},"3403":{"position":[[8,9],[154,9]]},"3405":{"position":[[6,9]]},"3415":{"position":[[328,9]]},"3453":{"position":[[381,5]]},"3472":{"position":[[13551,9]]},"3482":{"position":[[742,11],[1992,11],[2395,11],[2793,11]]},"3518":{"position":[[2431,9]]}}}],["referec",{"_index":10171,"t":{"3343":{"position":[[1136,9]]}}}],["referenc",{"_index":2350,"t":{"398":{"position":[[125,10]]},"650":{"position":[[1123,10]]},"1749":{"position":[[1407,11]]},"1880":{"position":[[318,10]]},"1900":{"position":[[146,11]]},"1904":{"position":[[628,10],[745,10],[800,11]]},"1911":{"position":[[216,10]]},"1996":{"position":[[318,10]]},"2016":{"position":[[146,11]]},"2020":{"position":[[628,10],[745,10],[800,11]]},"2027":{"position":[[216,10]]},"2330":{"position":[[341,10]]},"2677":{"position":[[376,10]]},"2824":{"position":[[146,10]]},"2895":{"position":[[92,11],[754,10],[1182,10],[3564,12],[4067,11]]},"3039":{"position":[[109,10]]},"3057":{"position":[[315,10]]},"3160":{"position":[[2078,10]]},"3343":{"position":[[1010,10]]},"3355":{"position":[[533,10]]},"3472":{"position":[[12616,10]]}}}],["refin",{"_index":543,"t":{"73":{"position":[[57,8]]},"79":{"position":[[149,6]]},"2217":{"position":[[101,7]]}}}],["reflect",{"_index":1074,"t":{"168":{"position":[[1045,8]]},"615":{"position":[[628,7]]},"2118":{"position":[[1727,7]]},"2411":{"position":[[64,10]]},"2665":{"position":[[546,7]]},"2688":{"position":[[2657,9]]},"2711":{"position":[[1035,8]]},"2723":{"position":[[108,9],[578,7]]},"2727":{"position":[[580,7]]},"2762":{"position":[[121,9],[591,7]]},"2766":{"position":[[780,7]]},"2848":{"position":[[108,9],[578,7]]},"2852":{"position":[[927,7]]},"2856":{"position":[[1013,8]]},"2931":{"position":[[392,10],[507,10]]},"2933":{"position":[[564,8]]},"3186":{"position":[[1225,7]]},"3355":{"position":[[311,7]]}}}],["reformat",{"_index":6864,"t":{"1419":{"position":[[947,8]]},"1721":{"position":[[332,8],[487,8],[639,8],[793,8],[959,8],[1127,8],[1279,8],[1434,8],[1596,8],[1749,8],[1902,8],[2056,8],[2211,8],[2366,8],[2520,8],[2673,8],[2830,8],[2990,8],[3135,8],[3287,8],[3560,12]]}}}],["refrain",{"_index":8115,"t":{"2039":{"position":[[730,7]]}}}],["refresh",{"_index":3085,"t":{"604":{"position":[[298,8]]},"1224":{"position":[[3510,7]]},"1360":{"position":[[766,7],[812,7]]},"1362":{"position":[[2447,7],[2483,7],[2529,7]]},"1825":{"position":[[2450,7]]}}}],["refriger",{"_index":1548,"t":{"229":{"position":[[265,13]]}}}],["refs/heads/main",{"_index":7448,"t":{"1758":{"position":[[762,15],[878,15]]}}}],["refstack",{"_index":7179,"t":{"1678":{"position":[[1811,9]]},"1779":{"position":[[5795,8]]},"1808":{"position":[[721,8]]},"2190":{"position":[[461,8]]},"2233":{"position":[[401,10]]}}}],["refus",{"_index":1474,"t":{"210":{"position":[[337,8]]},"1734":{"position":[[307,11]]}}}],["regard",{"_index":768,"t":{"118":{"position":[[33,9]]},"120":{"position":[[44,9]]},"124":{"position":[[182,9]]},"274":{"position":[[111,9],[252,9]]},"374":{"position":[[1041,9]]},"472":{"position":[[408,9]]},"1972":{"position":[[1285,7]]},"1974":{"position":[[534,9]]},"1976":{"position":[[636,9]]},"1978":{"position":[[746,9]]},"2051":{"position":[[189,9]]},"2164":{"position":[[111,9],[240,9]]},"2310":{"position":[[514,7]]},"2326":{"position":[[145,9],[253,9]]},"2534":{"position":[[53,7]]},"2754":{"position":[[787,9]]},"2913":{"position":[[198,9]]},"2968":{"position":[[124,9]]},"2999":{"position":[[573,7]]},"3117":{"position":[[105,9]]},"3126":{"position":[[122,7]]},"3130":{"position":[[14,9]]},"3143":{"position":[[20,9]]},"3167":{"position":[[164,9]]},"3169":{"position":[[295,7]]},"3173":{"position":[[24,9]]},"3238":{"position":[[114,6]]},"3293":{"position":[[503,6]]},"3459":{"position":[[546,7]]},"3472":{"position":[[13977,9]]}}}],["regardless",{"_index":595,"t":{"79":{"position":[[663,10]]},"242":{"position":[[179,10]]},"247":{"position":[[1586,10]]},"883":{"position":[[1138,10]]},"888":{"position":[[1383,10]]},"1690":{"position":[[2046,10]]},"1892":{"position":[[137,11]]},"1908":{"position":[[1299,10]]},"1911":{"position":[[275,10]]},"2008":{"position":[[137,11]]},"2024":{"position":[[1299,10]]},"2027":{"position":[[275,10]]},"2051":{"position":[[627,10]]},"3227":{"position":[[511,10]]},"3475":{"position":[[160,10]]}}}],["regener",{"_index":7565,"t":{"1783":{"position":[[527,11]]}}}],["regex",{"_index":9662,"t":{"2985":{"position":[[107,7]]}}}],["regio",{"_index":7515,"t":{"1773":{"position":[[661,5]]}}}],["regio.cloud",{"_index":3798,"t":{"803":{"position":[[99,12]]},"1540":{"position":[[99,12]]},"1770":{"position":[[141,12]]},"1773":{"position":[[614,11],[643,11],[981,12]]},"1779":{"position":[[1149,11]]},"1794":{"position":[[397,11]]},"1808":{"position":[[141,12]]},"2520":{"position":[[430,11]]}}}],["regiocloud",{"_index":6079,"t":{"1240":{"position":[[772,10],[946,10],[1120,10]]},"1773":{"position":[[632,10]]},"1779":{"position":[[1271,10],[1478,10],[1530,11],[1576,10],[2040,11],[2061,10],[2341,11],[2427,11],[2448,10],[2696,11]]},"1808":{"position":[[234,10]]}}}],["regiocloud.conf",{"_index":7570,"t":{"1785":{"position":[[774,16]]}}}],["regiocloud/configur",{"_index":4892,"t":{"1061":{"position":[[593,24],[781,24]]}}}],["region",{"_index":2608,"t":{"471":{"position":[[374,6]]},"627":{"position":[[5248,8]]},"738":{"position":[[17,6],[304,7],[392,6],[489,7]]},"744":{"position":[[343,8]]},"746":{"position":[[164,7]]},"756":{"position":[[81,7]]},"905":{"position":[[362,6]]},"909":{"position":[[2799,7]]},"1627":{"position":[[362,6]]},"1631":{"position":[[2799,7]]},"2233":{"position":[[479,8]]},"2352":{"position":[[362,6]]},"2356":{"position":[[2799,7]]},"2520":{"position":[[319,8]]},"2566":{"position":[[11786,7]]},"2944":{"position":[[1369,7]]},"3197":{"position":[[1313,8]]}}}],["region'",{"_index":3650,"t":{"740":{"position":[[88,8]]}}}],["region=regionone,enablesharedconfig=tru",{"_index":2613,"t":{"471":{"position":[[953,40]]}}}],["region=regionone,s3forcepathstyle=\"true\",s3url=https://api.gx",{"_index":2477,"t":{"427":{"position":[[733,61]]},"471":{"position":[[835,61],[1801,61]]}}}],["region_nam",{"_index":3486,"t":{"650":{"position":[[573,12]]},"905":{"position":[[348,13]]},"1627":{"position":[[348,13]]},"2352":{"position":[[348,13]]}}}],["regionon",{"_index":3487,"t":{"650":{"position":[[586,9]]}}}],["regist",{"_index":1441,"t":{"204":{"position":[[346,11]]},"210":{"position":[[226,8]]},"259":{"position":[[132,8]]},"487":{"position":[[1005,8]]},"489":{"position":[[117,10]]},"548":{"position":[[84,11],[189,8]]},"609":{"position":[[374,10]]},"627":{"position":[[1783,9]]},"646":{"position":[[733,10]]},"1743":{"position":[[1673,9]]},"2116":{"position":[[187,9]]},"2122":{"position":[[271,8]]},"2719":{"position":[[1428,8]]},"2735":{"position":[[1327,11]]},"2758":{"position":[[1429,8]]},"2774":{"position":[[1329,11]]},"2852":{"position":[[313,11]]},"2895":{"position":[[1754,10]]},"3397":{"position":[[2135,8]]}}}],["registr",{"_index":1385,"t":{"193":{"position":[[362,12]]},"210":{"position":[[171,13],[244,12]]},"227":{"position":[[227,14]]},"487":{"position":[[1183,12]]},"631":{"position":[[619,12]]},"1773":{"position":[[276,12]]},"1900":{"position":[[948,12]]},"2016":{"position":[[948,12]]},"2041":{"position":[[181,12]]},"2899":{"position":[[1185,13]]}}}],["registri",{"_index":400,"t":{"37":{"position":[[65,8]]},"335":{"position":[[544,8],[614,9]]},"344":{"position":[[168,8]]},"417":{"position":[[98,9]]},"430":{"position":[[62,8]]},"434":{"position":[[113,8],[199,8]]},"436":{"position":[[81,9]]},"438":{"position":[[103,9]]},"447":{"position":[[57,8]]},"451":{"position":[[102,8]]},"460":{"position":[[82,9]]},"462":{"position":[[89,8]]},"472":{"position":[[1485,8],[1622,9],[1767,8],[1929,8],[2010,8],[2136,8]]},"487":{"position":[[3864,8],[5881,8]]},"633":{"position":[[177,8],[203,8],[435,8],[510,8],[581,9],[638,8],[815,8],[967,8],[1170,8],[1247,8],[1501,10],[1763,8],[1823,9],[1996,9],[2217,8],[2316,8],[2481,8],[2558,11],[2624,10],[2692,11],[2729,8],[2796,11],[2907,8],[3059,8],[3454,8],[3507,8],[3584,8]]},"635":{"position":[[436,9],[955,8],[1011,8],[1098,8],[1197,8],[1576,8],[1620,8],[1905,8]]},"639":{"position":[[56,8],[741,10]]},"641":{"position":[[1130,8]]},"2324":{"position":[[837,8]]},"2405":{"position":[[620,8],[693,8],[740,11]]},"2426":{"position":[[453,8]]},"2592":{"position":[[684,10],[1011,8]]},"3063":{"position":[[663,8]]},"3067":{"position":[[55,9]]},"3069":{"position":[[207,8]]},"3150":{"position":[[12,8],[128,8],[257,10]]},"3154":{"position":[[146,10],[233,10],[310,8],[399,8],[547,8],[634,9]]},"3156":{"position":[[69,8],[118,10]]},"3158":{"position":[[340,8]]},"3160":{"position":[[12,8],[134,8],[343,8],[1105,8],[1465,8],[1592,8],[1676,10],[1721,10],[1839,8],[1906,8],[1991,8],[2342,8],[2734,8],[2848,8]]},"3162":{"position":[[42,8],[264,9],[420,8]]},"3293":{"position":[[12,8],[128,8],[301,13],[334,8]]},"3297":{"position":[[112,8],[193,12],[369,8],[434,9]]},"3299":{"position":[[402,13]]},"3301":{"position":[[63,8],[310,8],[914,12],[1041,8],[1323,8],[1458,8],[2563,8],[4417,10],[5412,8],[6432,8]]},"3303":{"position":[[67,13],[224,8]]},"3305":{"position":[[28,11]]},"3397":{"position":[[2417,8],[2466,8]]},"3518":{"position":[[1730,10],[2087,8]]}}}],["registry.gitlab.com",{"_index":3335,"t":{"633":{"position":[[2834,19]]}}}],["registry.k8s.io",{"_index":3336,"t":{"633":{"position":[[2854,15]]},"2328":{"position":[[122,15]]}}}],["registry.scs.commun",{"_index":3324,"t":{"633":{"position":[[1730,22]]},"635":{"position":[[1065,22]]},"2413":{"position":[[143,22]]}}}],["registry.upload_purging.interv",{"_index":2629,"t":{"472":{"position":[[1699,34]]}}}],["registry/registri",{"_index":7143,"t":{"1608":{"position":[[793,19]]}}}],["regress",{"_index":1836,"t":{"280":{"position":[[57,10],[564,10]]}}}],["regul",{"_index":1908,"t":{"288":{"position":[[84,11]]},"2526":{"position":[[688,11]]},"3465":{"position":[[1227,9]]},"3482":{"position":[[1817,10]]},"3518":{"position":[[809,11]]}}}],["regular",{"_index":1386,"t":{"193":{"position":[[414,8]]},"263":{"position":[[291,7]]},"379":{"position":[[823,7]]},"462":{"position":[[683,7]]},"796":{"position":[[69,7]]},"947":{"position":[[1596,7]]},"1533":{"position":[[69,7]]},"1669":{"position":[[1596,7]]},"1878":{"position":[[1199,7]]},"1902":{"position":[[59,7]]},"1994":{"position":[[1199,7]]},"2018":{"position":[[59,7]]},"2081":{"position":[[263,7],[538,7]]},"2338":{"position":[[162,7]]},"2394":{"position":[[1596,7]]},"2518":{"position":[[147,7]]},"2675":{"position":[[883,7]]},"2985":{"position":[[115,7],[560,7],[639,7]]},"3003":{"position":[[602,7]]},"3067":{"position":[[87,7]]},"3227":{"position":[[11,7]]},"3325":{"position":[[1871,7]]}}}],["regularli",{"_index":1844,"t":{"280":{"position":[[282,9]]},"586":{"position":[[439,9]]},"596":{"position":[[99,9]]},"920":{"position":[[698,10]]},"938":{"position":[[283,9]]},"1294":{"position":[[1127,9]]},"1642":{"position":[[698,10]]},"1660":{"position":[[283,9]]},"1822":{"position":[[939,9]]},"2075":{"position":[[571,9]]},"2079":{"position":[[572,9]]},"2083":{"position":[[594,9]]},"2085":{"position":[[729,9]]},"2253":{"position":[[333,9]]},"2367":{"position":[[698,10]]},"2385":{"position":[[283,9]]},"2895":{"position":[[51,9]]},"3274":{"position":[[26,9]]},"3276":{"position":[[301,9],[1901,10]]},"3282":{"position":[[24,10]]},"3284":{"position":[[34,10]]},"3286":{"position":[[154,10],[275,9]]}}}],["regulatori",{"_index":2213,"t":{"366":{"position":[[1584,10]]}}}],["reinstal",{"_index":7009,"t":{"1569":{"position":[[1056,13]]}}}],["reinvent",{"_index":8044,"t":{"1970":{"position":[[360,11]]}}}],["reject",{"_index":9017,"t":{"2625":{"position":[[1901,8],[2397,8],[2471,8],[2531,9]]},"2627":{"position":[[823,9]]},"2629":{"position":[[109,9]]},"2639":{"position":[[94,9]]},"2688":{"position":[[2004,6]]},"2799":{"position":[[60,8]]}}}],["rejected_at",{"_index":9020,"t":{"2625":{"position":[[2363,11]]}}}],["rel",{"_index":1093,"t":{"170":{"position":[[141,10]]},"187":{"position":[[646,8]]},"393":{"position":[[309,10]]},"633":{"position":[[3138,8]]},"1791":{"position":[[1362,10]]},"2813":{"position":[[749,9]]}}}],["relat",{"_index":892,"t":{"139":{"position":[[278,7]]},"317":{"position":[[953,7]]},"396":{"position":[[505,7]]},"413":{"position":[[638,7]]},"421":{"position":[[767,7]]},"427":{"position":[[228,7]]},"449":{"position":[[17,7]]},"462":{"position":[[762,7],[898,7]]},"487":{"position":[[3897,7],[5917,7]]},"590":{"position":[[668,7]]},"594":{"position":[[126,7]]},"596":{"position":[[618,7]]},"609":{"position":[[2734,7],[5434,7]]},"633":{"position":[[276,7],[1837,7]]},"635":{"position":[[446,7]]},"1428":{"position":[[176,8]]},"1566":{"position":[[301,8]]},"1697":{"position":[[279,7]]},"2039":{"position":[[371,8]]},"2071":{"position":[[541,7],[616,7]]},"2098":{"position":[[894,7],[1001,7]]},"2110":{"position":[[920,7],[1015,7]]},"2114":{"position":[[117,7]]},"2120":{"position":[[499,7],[553,7]]},"2138":{"position":[[180,7],[348,7],[449,7],[650,6]]},"2154":{"position":[[1309,7]]},"2156":{"position":[[47,7]]},"2158":{"position":[[669,7],[794,7]]},"2526":{"position":[[118,7]]},"2574":{"position":[[206,7]]},"2627":{"position":[[1079,7],[1122,7],[1709,7],[1752,7]]},"2697":{"position":[[1095,7]]},"2742":{"position":[[994,7]]},"2944":{"position":[[629,10]]},"3099":{"position":[[354,7]]},"3145":{"position":[[44,7]]},"3299":{"position":[[5551,7],[5660,7]]},"3331":{"position":[[0,7]]},"3355":{"position":[[22,8]]},"3438":{"position":[[322,8]]},"3459":{"position":[[147,8]]},"3497":{"position":[[0,7]]},"3514":{"position":[[0,7]]}}}],["relationship",{"_index":9047,"t":{"2651":{"position":[[261,12]]},"2695":{"position":[[282,12]]},"2740":{"position":[[282,12]]},"3011":{"position":[[2021,13]]},"3415":{"position":[[118,13]]}}}],["relax",{"_index":1413,"t":{"200":{"position":[[22,7]]},"212":{"position":[[44,7]]},"662":{"position":[[544,7]]}}}],["releas",{"_index":997,"t":{"158":{"position":[[634,7]]},"168":{"position":[[190,7]]},"172":{"position":[[276,9],[557,9]]},"193":{"position":[[702,9]]},"325":{"position":[[1823,7]]},"339":{"position":[[176,7],[440,7]]},"353":{"position":[[52,8]]},"359":{"position":[[8,7]]},"379":{"position":[[643,8]]},"393":{"position":[[927,7],[1118,8]]},"396":{"position":[[82,7],[223,7],[371,7]]},"409":{"position":[[134,7],[198,7],[266,7],[331,7]]},"469":{"position":[[415,7]]},"487":{"position":[[740,8]]},"505":{"position":[[1090,9]]},"596":{"position":[[2070,7]]},"598":{"position":[[491,8],[610,8]]},"604":{"position":[[2429,7],[2460,7],[6947,7],[8042,9],[8604,7]]},"609":{"position":[[2493,7],[2863,7],[5356,7]]},"635":{"position":[[51,7],[144,8]]},"641":{"position":[[671,7]]},"656":{"position":[[179,7],[355,7],[426,7]]},"658":{"position":[[163,7],[219,7]]},"772":{"position":[[868,8]]},"798":{"position":[[134,7]]},"846":{"position":[[103,7]]},"850":{"position":[[1409,7],[8829,7]]},"1071":{"position":[[152,7],[872,8],[1308,7]]},"1080":{"position":[[24,7],[115,7],[207,7],[582,7],[1170,8]]},"1150":{"position":[[739,8]]},"1294":{"position":[[1287,7]]},"1397":{"position":[[17,8],[143,8],[339,8]]},"1480":{"position":[[103,7]]},"1484":{"position":[[1409,7],[8829,7]]},"1535":{"position":[[134,7]]},"1560":{"position":[[83,7]]},"1569":{"position":[[200,7],[243,8]]},"1608":{"position":[[571,7]]},"1674":{"position":[[24,7],[54,8],[117,8],[271,8],[451,8],[509,8],[589,7]]},"1676":{"position":[[398,7],[544,8],[588,8],[663,9],[738,8],[770,8],[990,7]]},"1678":{"position":[[35,7],[66,8],[79,7],[314,7],[351,7],[383,7],[410,7],[524,7],[904,7],[971,7],[1707,8],[2418,7],[2506,7],[2688,7],[2750,7],[2802,7]]},"1680":{"position":[[26,7]]},"1684":{"position":[[35,7],[698,8],[992,7],[1080,7],[1247,7],[1566,7],[1887,7],[2218,7],[2540,7],[2862,7],[3183,7],[3499,7]]},"1688":{"position":[[17,7]]},"1690":{"position":[[800,7]]},"1752":{"position":[[76,7]]},"1764":{"position":[[4473,7]]},"1766":{"position":[[902,8]]},"1777":{"position":[[210,7]]},"1812":{"position":[[40,8]]},"1822":{"position":[[1099,7]]},"1825":{"position":[[24,7],[115,7],[231,7],[289,7],[329,7],[730,7],[1333,8]]},"2039":{"position":[[929,9]]},"2098":{"position":[[504,7]]},"2186":{"position":[[0,8]]},"2188":{"position":[[268,7]]},"2190":{"position":[[915,7]]},"2196":{"position":[[177,9],[772,7],[828,9],[1326,9]]},"2198":{"position":[[4,7]]},"2204":{"position":[[0,8]]},"2206":{"position":[[15,7]]},"2224":{"position":[[201,7]]},"2229":{"position":[[961,7]]},"2235":{"position":[[957,8],[997,7],[1158,7]]},"2237":{"position":[[4,7]]},"2241":{"position":[[0,8]]},"2243":{"position":[[15,7]]},"2245":{"position":[[47,9],[121,7],[589,7],[636,7]]},"2250":{"position":[[678,7]]},"2253":{"position":[[202,7]]},"2259":{"position":[[311,7]]},"2267":{"position":[[4,7],[160,7]]},"2274":{"position":[[0,8]]},"2276":{"position":[[15,7]]},"2278":{"position":[[38,9],[112,7],[327,7],[374,7],[420,7]]},"2283":{"position":[[229,7],[1177,7]]},"2286":{"position":[[88,7]]},"2292":{"position":[[377,8],[1110,7]]},"2294":{"position":[[55,7],[271,7]]},"2300":{"position":[[4,7],[160,7]]},"2308":{"position":[[0,8]]},"2310":{"position":[[0,7],[443,9]]},"2312":{"position":[[14,7],[60,7],[546,7],[829,7]]},"2315":{"position":[[657,8]]},"2326":{"position":[[15,7]]},"2334":{"position":[[279,8]]},"2398":{"position":[[0,8]]},"2400":{"position":[[21,8],[30,7]]},"2407":{"position":[[146,8]]},"2422":{"position":[[15,7]]},"2424":{"position":[[316,7]]},"2436":{"position":[[51,7],[62,7],[80,8],[137,7],[150,8]]},"2454":{"position":[[4,7]]},"2456":{"position":[[21,8],[30,7],[112,7]]},"2461":{"position":[[482,8],[999,8],[1060,7]]},"2472":{"position":[[341,8]]},"2484":{"position":[[200,8]]},"2489":{"position":[[216,8]]},"2499":{"position":[[94,7]]},"2504":{"position":[[517,8],[745,7],[845,7]]},"2510":{"position":[[346,7]]},"2631":{"position":[[2497,8]]},"2633":{"position":[[123,8],[147,7]]},"2647":{"position":[[489,9],[522,8],[863,7]]},"2671":{"position":[[1290,8]]},"2695":{"position":[[34,7]]},"2705":{"position":[[799,8]]},"2740":{"position":[[34,7]]},"2750":{"position":[[814,8]]},"2830":{"position":[[34,7]]},"2840":{"position":[[704,8]]},"2895":{"position":[[1360,8],[4548,8]]},"2897":{"position":[[270,7]]},"2899":{"position":[[117,8]]},"2955":{"position":[[105,8]]},"3011":{"position":[[1674,9],[1860,8]]},"3014":{"position":[[370,7],[425,9],[521,9]]},"3078":{"position":[[1166,9]]},"3080":{"position":[[243,8]]},"3082":{"position":[[17,7],[215,7],[1024,7]]},"3084":{"position":[[176,9]]},"3092":{"position":[[398,7]]},"3094":{"position":[[56,7]]},"3124":{"position":[[42,7],[137,8],[260,9],[351,8],[725,7],[802,8],[838,8],[962,7],[981,7]]},"3126":{"position":[[72,7],[133,8],[518,9],[571,8]]},"3128":{"position":[[179,9],[260,8],[338,8],[654,8],[1128,8]]},"3130":{"position":[[36,9],[119,8]]},"3132":{"position":[[242,9]]},"3167":{"position":[[264,8],[298,7],[320,7],[407,7],[462,7],[481,7],[626,7]]},"3169":{"position":[[134,9]]},"3171":{"position":[[63,7],[132,7]]},"3173":{"position":[[46,9],[128,8]]},"3301":{"position":[[7247,7]]},"3472":{"position":[[236,7],[589,8],[12489,9]]}}}],["release.pi",{"_index":7164,"t":{"1676":{"position":[[903,11],[950,10]]}}}],["release/openstack",{"_index":2329,"t":{"393":{"position":[[858,18],[893,18],[1327,18],[1359,18]]}}}],["release=6.0.0b",{"_index":7165,"t":{"1676":{"position":[[915,14]]}}}],["releasenotes/config.yaml",{"_index":7186,"t":{"1684":{"position":[[296,27]]}}}],["releasenotes/notes/remov",{"_index":7188,"t":{"1684":{"position":[[362,25]]}}}],["releases.ubuntu.com",{"_index":6058,"t":{"1234":{"position":[[261,20]]}}}],["relev",{"_index":573,"t":{"79":{"position":[[160,8]]},"105":{"position":[[566,8]]},"149":{"position":[[84,8]]},"170":{"position":[[751,8]]},"206":{"position":[[294,8]]},"235":{"position":[[1039,10]]},"355":{"position":[[72,8]]},"491":{"position":[[383,8]]},"590":{"position":[[1190,8]]},"604":{"position":[[593,8],[1139,8],[4702,8]]},"635":{"position":[[675,8]]},"646":{"position":[[117,8]]},"784":{"position":[[25,8]]},"1165":{"position":[[1145,8]]},"1462":{"position":[[478,8]]},"1521":{"position":[[25,8]]},"2224":{"position":[[158,8]]},"2237":{"position":[[87,8]]},"2267":{"position":[[87,8]]},"2300":{"position":[[87,8]]},"2428":{"position":[[0,8]]},"2627":{"position":[[138,8],[1389,8]]},"2692":{"position":[[173,9]]},"2697":{"position":[[986,8]]},"2742":{"position":[[885,8]]},"3014":{"position":[[766,8]]},"3071":{"position":[[2167,8]]},"3182":{"position":[[2097,9]]},"3251":{"position":[[2288,8],[5206,8]]}}}],["reli",{"_index":4472,"t":{"913":{"position":[[2508,4]]},"920":{"position":[[645,4]]},"1635":{"position":[[2508,4]]},"1642":{"position":[[645,4]]},"1908":{"position":[[2512,4]]},"2024":{"position":[[2512,4]]},"2176":{"position":[[702,4]]},"2233":{"position":[[198,4]]},"2235":{"position":[[379,4]]},"2360":{"position":[[2508,4]]},"2367":{"position":[[645,4]]},"2870":{"position":[[79,6]]},"2960":{"position":[[989,7]]},"3247":{"position":[[388,7]]},"3316":{"position":[[747,6]]}}}],["reliabl",{"_index":1589,"t":{"235":{"position":[[1050,12]]},"276":{"position":[[203,9]]},"329":{"position":[[310,8]]},"335":{"position":[[309,12]]},"366":{"position":[[776,9]]},"505":{"position":[[1328,8]]},"768":{"position":[[81,9]]},"888":{"position":[[1919,11]]},"1319":{"position":[[448,8]]},"2548":{"position":[[475,11]]},"2602":{"position":[[284,12]]},"2713":{"position":[[1223,11]]},"2756":{"position":[[940,11]]},"2858":{"position":[[1033,11]]},"3222":{"position":[[736,9]]},"3224":{"position":[[1131,8],[1503,9],[1900,8]]},"3249":{"position":[[83,9]]},"3272":{"position":[[75,8],[270,9]]},"3374":{"position":[[217,8]]},"3438":{"position":[[205,8]]}}}],["relicens",{"_index":1303,"t":{"178":{"position":[[2632,11]]}}}],["religion",{"_index":1666,"t":{"247":{"position":[[765,9]]}}}],["reload",{"_index":3375,"t":{"635":{"position":[[2630,8],[3134,8]]}}}],["remain",{"_index":1067,"t":{"168":{"position":[[803,6]]},"393":{"position":[[1179,7]]},"652":{"position":[[1176,6]]},"1855":{"position":[[984,9]]},"1917":{"position":[[984,9]]},"2235":{"position":[[687,8]]},"2660":{"position":[[169,6],[379,6]]},"2692":{"position":[[141,9]]},"2895":{"position":[[470,7],[3732,6],[3841,6],[3917,6],[4636,6]]},"2960":{"position":[[887,6]]},"3124":{"position":[[431,9]]},"3167":{"position":[[731,9]]},"3272":{"position":[[263,6]]}}}],["remedi",{"_index":8147,"t":{"2081":{"position":[[491,11]]}}}],["rememb",{"_index":1644,"t":{"247":{"position":[[160,8],[2318,8],[2757,8]]},"903":{"position":[[3704,8]]},"909":{"position":[[1712,9]]},"1625":{"position":[[3704,8]]},"1631":{"position":[[1712,9]]},"2350":{"position":[[3704,8]]},"2356":{"position":[[1712,9]]},"2719":{"position":[[1728,8]]},"2758":{"position":[[1844,8]]}}}],["remind",{"_index":1340,"t":{"187":{"position":[[99,8],[263,9],[293,7],[494,9],[541,8]]}}}],["remot",{"_index":2320,"t":{"393":{"position":[[108,6],[240,6]]},"635":{"position":[[638,6]]},"977":{"position":[[1996,6]]},"1397":{"position":[[360,8]]},"1585":{"position":[[2737,6]]},"1982":{"position":[[730,6]]},"1984":{"position":[[340,6]]},"2100":{"position":[[98,6]]},"2944":{"position":[[1406,6]]},"3086":{"position":[[370,6]]},"3088":{"position":[[446,6],[470,6]]},"3107":{"position":[[549,6],[573,6]]}}}],["remote_a",{"_index":5136,"t":{"1098":{"position":[[798,10],[841,10]]}}}],["remote_ip=\"192.168.16.11",{"_index":6686,"t":{"1366":{"position":[[568,26]]}}}],["remote_ip=\"192.168.16.12",{"_index":6685,"t":{"1366":{"position":[[410,26]]}}}],["remote_ip_prefix",{"_index":7370,"t":{"1743":{"position":[[1111,17],[1290,17]]}}}],["remov",{"_index":681,"t":{"105":{"position":[[1064,6],[1324,6],[1594,6],[1693,6],[2089,6]]},"472":{"position":[[1564,7]]},"493":{"position":[[838,7],[1640,7]]},"499":{"position":[[2417,6],[2674,7]]},"627":{"position":[[2753,6],[4261,6],[4901,6],[4947,6],[5037,7],[5066,6]]},"639":{"position":[[901,7]]},"652":{"position":[[949,8]]},"656":{"position":[[155,6]]},"726":{"position":[[69,7]]},"800":{"position":[[18,7]]},"819":{"position":[[283,6]]},"853":{"position":[[261,7]]},"1080":{"position":[[544,8]]},"1089":{"position":[[426,8]]},"1161":{"position":[[252,8],[1540,7]]},"1317":{"position":[[737,8]]},"1347":{"position":[[1061,6],[1154,8],[1214,6],[1307,8],[1367,6],[1460,8]]},"1362":{"position":[[32,6],[2593,6],[2677,6]]},"1406":{"position":[[469,6],[635,6]]},"1419":{"position":[[348,7]]},"1428":{"position":[[8,7],[113,7],[192,7],[208,7],[526,8]]},"1430":{"position":[[785,7],[1217,6],[1452,8],[1794,6],[1847,6],[1869,7],[1925,6],[1980,6]]},"1444":{"position":[[204,7]]},"1473":{"position":[[953,8],[969,6]]},"1487":{"position":[[69,7]]},"1509":{"position":[[283,6]]},"1537":{"position":[[18,7]]},"1569":{"position":[[946,6]]},"1597":{"position":[[261,7]]},"1674":{"position":[[414,9],[876,8]]},"1676":{"position":[[462,6],[514,6]]},"1678":{"position":[[2291,7]]},"1684":{"position":[[178,8],[187,6],[242,6],[1166,6],[1485,6],[1806,6],[2137,6],[2459,6],[2781,6],[3102,6],[3418,6]]},"1686":{"position":[[121,8],[458,7]]},"1728":{"position":[[1353,7]]},"1740":{"position":[[259,7]]},"1758":{"position":[[82,7],[610,6]]},"1825":{"position":[[692,8]]},"1849":{"position":[[949,6]]},"1855":{"position":[[129,8]]},"1857":{"position":[[1116,7],[1275,7]]},"1859":{"position":[[232,7]]},"1865":{"position":[[677,6],[764,6]]},"1917":{"position":[[129,8]]},"1919":{"position":[[1116,7],[1275,7]]},"1921":{"position":[[232,7]]},"1927":{"position":[[677,6],[764,6]]},"2057":{"position":[[130,6]]},"2063":{"position":[[491,7]]},"2065":{"position":[[420,8],[466,6]]},"2067":{"position":[[695,6],[807,6],[1156,6],[1271,6]]},"2156":{"position":[[166,7]]},"2257":{"position":[[106,8],[208,8]]},"2259":{"position":[[291,7],[402,7],[561,7]]},"2290":{"position":[[29,8]]},"2292":{"position":[[349,7],[591,7],[679,7],[1090,7]]},"2321":{"position":[[36,7],[534,8],[615,8],[708,7]]},"2324":{"position":[[365,7],[394,7],[482,7],[568,7],[677,7]]},"2417":{"position":[[17,8],[52,7]]},"2420":{"position":[[131,7],[278,7]]},"2436":{"position":[[123,8]]},"2480":{"position":[[17,8],[52,7]]},"2504":{"position":[[821,6]]},"2639":{"position":[[17,7]]},"2735":{"position":[[1505,6]]},"2774":{"position":[[1507,6]]},"2947":{"position":[[1098,6]]},"2990":{"position":[[409,8]]},"3160":{"position":[[2019,8]]},"3376":{"position":[[776,6]]}}}],["remove_clust",{"_index":3302,"t":{"627":{"position":[[5257,14]]}}}],["removegitcommand",{"_index":704,"t":{"105":{"position":[[1619,16]]}}}],["removereadmecommand",{"_index":709,"t":{"105":{"position":[[1719,19]]}}}],["removerepocommand",{"_index":726,"t":{"105":{"position":[[2124,17]]}}}],["renam",{"_index":3103,"t":{"604":{"position":[[1997,8],[10717,6]]},"772":{"position":[[583,7]]},"917":{"position":[[97,6]]},"1574":{"position":[[157,6]]},"1639":{"position":[[97,6]]},"2255":{"position":[[323,7]]},"2364":{"position":[[97,6]]},"2631":{"position":[[1090,6]]},"2660":{"position":[[187,6]]},"2735":{"position":[[1532,6]]},"2774":{"position":[[1534,6]]},"2895":{"position":[[387,7],[4032,7],[4623,8]]},"3482":{"position":[[658,6]]}}}],["render",{"_index":650,"t":{"105":{"position":[[399,8]]},"129":{"position":[[317,6]]},"627":{"position":[[1086,6]]},"786":{"position":[[735,6]]},"1089":{"position":[[990,9]]},"1523":{"position":[[735,6]]},"1684":{"position":[[762,8],[1265,9],[1584,9],[1905,9],[2236,9],[2558,9],[2880,9],[3201,9],[3517,9]]},"2098":{"position":[[1274,8]]},"2635":{"position":[[503,6]]},"2990":{"position":[[135,6]]}}}],["renew",{"_index":2990,"t":{"586":{"position":[[177,7],[214,6],[391,7],[574,5],[616,5],[701,5]]},"2296":{"position":[[103,7]]},"3276":{"position":[[693,5],[818,5],[1787,10]]},"3286":{"position":[[262,5],[369,8]]},"3288":{"position":[[189,7]]}}}],["reno",{"_index":7184,"t":{"1680":{"position":[[7,4]]},"1682":{"position":[[0,4],[81,4]]},"1684":{"position":[[64,5],[233,4]]}}}],["reno.yaml",{"_index":7187,"t":{"1684":{"position":[[324,11]]}}}],["renov",{"_index":7159,"t":{"1676":{"position":[[475,8]]},"2250":{"position":[[499,8]]}}}],["reoncil",{"_index":7199,"t":{"1690":{"position":[[563,9]]}}}],["reopen",{"_index":2009,"t":{"321":{"position":[[924,8]]},"325":{"position":[[7276,6]]}}}],["rep",{"_index":6214,"t":{"1305":{"position":[[90,3]]}}}],["repair",{"_index":6912,"t":{"1446":{"position":[[10,6]]},"1728":{"position":[[719,8],[792,8],[854,8],[899,7]]}}}],["repeat",{"_index":1697,"t":{"247":{"position":[[1835,8]]},"1684":{"position":[[958,9],[1422,9],[1741,9],[2062,9],[2393,9],[2715,9],[3037,9],[3358,9],[3674,9]]},"1839":{"position":[[275,6]]},"1845":{"position":[[1570,6]]},"1865":{"position":[[377,9]]},"1927":{"position":[[377,9]]},"2041":{"position":[[534,8]]},"2118":{"position":[[1457,6]]},"2688":{"position":[[1045,8],[3023,8]]}}}],["repeatedli",{"_index":8129,"t":{"2067":{"position":[[1400,10]]},"2069":{"position":[[73,10]]}}}],["repetit",{"_index":4290,"t":{"883":{"position":[[1872,10]]}}}],["replac",{"_index":785,"t":{"122":{"position":[[336,7]]},"325":{"position":[[5846,8]]},"349":{"position":[[636,7]]},"413":{"position":[[0,7],[485,7]]},"428":{"position":[[358,7],[1340,7]]},"474":{"position":[[215,7],[373,7],[538,7],[695,7],[827,7],[1043,7]]},"485":{"position":[[597,7]]},"609":{"position":[[791,7]]},"758":{"position":[[181,7]]},"772":{"position":[[948,8]]},"909":{"position":[[1003,7]]},"947":{"position":[[967,7]]},"1089":{"position":[[679,8]]},"1112":{"position":[[3919,7],[4721,8]]},"1114":{"position":[[945,9],[4547,9]]},"1240":{"position":[[583,7]]},"1388":{"position":[[403,7]]},"1631":{"position":[[1003,7]]},"1669":{"position":[[967,7]]},"1678":{"position":[[367,8]]},"1684":{"position":[[622,7]]},"1779":{"position":[[1568,7]]},"1833":{"position":[[593,7]]},"1880":{"position":[[366,7]]},"1980":{"position":[[22,7]]},"1996":{"position":[[366,7]]},"2138":{"position":[[623,8]]},"2259":{"position":[[240,8],[573,8]]},"2292":{"position":[[691,8],[1039,8]]},"2315":{"position":[[1111,7]]},"2356":{"position":[[1003,7]]},"2394":{"position":[[967,7]]},"2407":{"position":[[104,8]]},"2468":{"position":[[423,7]]},"2625":{"position":[[998,8],[1050,8],[1108,8],[2585,7],[2608,8],[2664,9]]},"2631":{"position":[[318,8],[1109,7],[1903,8]]},"2637":{"position":[[360,11]]},"2639":{"position":[[119,11]]},"2677":{"position":[[913,7]]},"2799":{"position":[[47,8]]},"2815":{"position":[[1442,8]]},"2864":{"position":[[280,7]]},"2895":{"position":[[830,8],[891,8],[953,8],[1012,8],[1069,8],[1132,8],[1292,7],[1452,8],[3715,11],[4753,7]]},"2931":{"position":[[289,8]]}}}],["replace(/\\s/g",{"_index":686,"t":{"105":{"position":[[1152,15]]}}}],["replace/append",{"_index":3500,"t":{"652":{"position":[[426,14]]}}}],["replace_frequ",{"_index":3751,"t":{"790":{"position":[[1015,18]]},"850":{"position":[[9382,18]]},"1484":{"position":[[9382,18]]},"1527":{"position":[[1015,18]]},"2895":{"position":[[597,18],[669,18],[778,17],[3108,18],[4203,17]]}}}],["replace_frequency=monthli",{"_index":9550,"t":{"2895":{"position":[[4351,26]]}}}],["replaced_bi",{"_index":9021,"t":{"2625":{"position":[[2480,11]]},"2631":{"position":[[2039,11]]},"2637":{"position":[[432,11]]},"2639":{"position":[[191,11]]}}}],["replic",{"_index":2545,"t":{"449":{"position":[[81,11]]},"880":{"position":[[545,12]]},"977":{"position":[[1770,11]]},"982":{"position":[[329,9]]},"1456":{"position":[[54,10]]},"1464":{"position":[[29,10],[101,10],[173,10]]},"2944":{"position":[[188,11],[425,10]]},"2947":{"position":[[5517,11]]},"2951":{"position":[[875,10]]},"2962":{"position":[[284,10]]},"2966":{"position":[[2629,12],[2642,11],[2832,10],[3080,10],[3164,11],[3409,11]]},"2968":{"position":[[111,12],[134,12]]},"2970":{"position":[[226,11],[394,11]]},"3021":{"position":[[233,12]]},"3025":{"position":[[104,12]]},"3031":{"position":[[296,11],[349,10],[634,11]]},"3037":{"position":[[87,12]]},"3044":{"position":[[0,11],[184,11],[379,12]]},"3046":{"position":[[97,11],[695,11],[723,10]]},"3160":{"position":[[1601,11],[1613,11],[1641,9]]},"3184":{"position":[[1517,9]]},"3301":{"position":[[1332,12],[6441,11]]}}}],["replica",{"_index":2538,"t":{"447":{"position":[[304,7]]},"449":{"position":[[408,7]]},"456":{"position":[[116,7]]},"458":{"position":[[183,7]]},"644":{"position":[[749,9]]},"660":{"position":[[2703,9],[2856,9]]},"2152":{"position":[[727,7]]},"2944":{"position":[[532,8]]},"2966":{"position":[[2696,8],[3130,9],[3281,8]]},"2968":{"position":[[164,8]]},"2970":{"position":[[339,9]]},"3044":{"position":[[53,8]]},"3046":{"position":[[913,8]]}}}],["replicat",{"_index":4304,"t":{"895":{"position":[[721,13]]},"1617":{"position":[[721,13]]},"2342":{"position":[[721,13]]}}}],["replicated_hdd",{"_index":6931,"t":{"1464":{"position":[[40,14]]}}}],["replicated_nvm",{"_index":6933,"t":{"1464":{"position":[[184,15]]}}}],["replicated_rul",{"_index":5198,"t":{"1110":{"position":[[257,17]]}}}],["replicated_ssd",{"_index":6932,"t":{"1464":{"position":[[112,14]]}}}],["replication/redund",{"_index":9598,"t":{"2944":{"position":[[248,22]]}}}],["replication_statu",{"_index":8726,"t":{"2566":{"position":[[2008,19],[2654,19]]}}}],["repo",{"_index":141,"t":{"10":{"position":[[1311,4]]},"105":{"position":[[1232,5]]},"114":{"position":[[65,4],[100,7],[238,4],[478,4]]},"270":{"position":[[43,4]]},"319":{"position":[[142,4]]},"321":{"position":[[545,4]]},"325":{"position":[[505,5]]},"393":{"position":[[384,4],[946,4],[1019,4]]},"544":{"position":[[79,4]]},"546":{"position":[[90,4]]},"609":{"position":[[446,5]]},"850":{"position":[[1568,4]]},"934":{"position":[[139,4]]},"1484":{"position":[[1568,4]]},"1656":{"position":[[139,4]]},"1749":{"position":[[1395,5],[1444,5]]},"1752":{"position":[[32,5]]},"2106":{"position":[[818,4],[886,4]]},"2128":{"position":[[5,4],[73,4]]},"2138":{"position":[[850,4],[918,4]]},"2158":{"position":[[256,4]]},"2190":{"position":[[923,4]]},"2281":{"position":[[1290,4]]},"2381":{"position":[[139,4]]}}}],["repo.repo",{"_index":702,"t":{"105":{"position":[[1545,10]]}}}],["repo.target}/${repo.label",{"_index":716,"t":{"105":{"position":[[1878,30]]}}}],["repo_to_be_edit",{"_index":727,"t":{"105":{"position":[[2152,18]]}}}],["repo_to_be_edited/${repo.label",{"_index":700,"t":{"105":{"position":[[1445,33]]}}}],["repodir",{"_index":699,"t":{"105":{"position":[[1435,7],[1556,11],[1747,10]]}}}],["repodir}/${repo.sourc",{"_index":724,"t":{"105":{"position":[[2019,25]]}}}],["repodir}/.git",{"_index":707,"t":{"105":{"position":[[1646,16]]}}}],["report",{"_index":1075,"t":{"168":{"position":[[1145,8]]},"280":{"position":[[242,8]]},"323":{"position":[[41,7],[121,8],[151,9],[262,7],[404,7],[444,7],[497,7],[581,7],[607,7],[798,10]]},"590":{"position":[[2457,8]]},"615":{"position":[[106,8]]},"913":{"position":[[2909,9]]},"1317":{"position":[[1597,6],[5705,6],[8859,6]]},"1469":{"position":[[368,6]]},"1635":{"position":[[2909,9]]},"1715":{"position":[[61,7]]},"2081":{"position":[[429,10],[464,7]]},"2085":{"position":[[202,9],[368,9],[412,9]]},"2265":{"position":[[105,8]]},"2298":{"position":[[105,8]]},"2360":{"position":[[2909,9]]},"2484":{"position":[[59,8]]},"2715":{"position":[[338,6]]},"2783":{"position":[[532,6]]},"2786":{"position":[[41,8],[361,8]]},"2862":{"position":[[338,6]]},"2909":{"position":[[201,8]]},"2911":{"position":[[79,8]]},"2913":{"position":[[41,8]]},"2935":{"position":[[280,8],[399,8],[518,9]]},"2949":{"position":[[788,8]]},"2994":{"position":[[242,8],[419,8],[545,9]]},"3132":{"position":[[364,8]]},"3475":{"position":[[26,6]]}}}],["repos.foreach((repo",{"_index":698,"t":{"105":{"position":[[1403,20]]}}}],["repositori",{"_index":87,"t":{"10":{"position":[[261,10]]},"97":{"position":[[57,10]]},"105":{"position":[[65,11],[224,10],[313,12],[531,12],[913,11],[1213,12],[1312,11],[1492,10],[2107,10]]},"112":{"position":[[5,10],[67,10]]},"114":{"position":[[41,10],[132,12],[200,10],[280,10]]},"116":{"position":[[151,10]]},"118":{"position":[[169,10]]},"120":{"position":[[33,10]]},"147":{"position":[[186,11],[219,11]]},"151":{"position":[[360,10]]},"160":{"position":[[15,10]]},"162":{"position":[[77,10]]},"184":{"position":[[107,12],[608,12],[785,12],[890,12]]},"187":{"position":[[205,11]]},"263":{"position":[[217,12]]},"268":{"position":[[122,10]]},"270":{"position":[[24,10]]},"280":{"position":[[717,11]]},"311":{"position":[[0,10],[179,10],[262,10]]},"315":{"position":[[24,11],[71,10],[311,10]]},"317":{"position":[[46,12],[87,10],[159,12],[347,12],[977,11]]},"319":{"position":[[38,10],[353,10]]},"321":{"position":[[43,10],[340,10],[385,11],[510,11]]},"325":{"position":[[951,11],[3404,11],[5691,10],[5787,10],[7643,11]]},"349":{"position":[[761,11]]},"353":{"position":[[159,12]]},"355":{"position":[[81,10],[169,11]]},"389":{"position":[[117,11]]},"428":{"position":[[974,11]]},"497":{"position":[[179,10],[364,10],[583,10],[731,10]]},"499":{"position":[[146,11],[1782,10],[1863,10],[2050,13]]},"513":{"position":[[296,10],[1589,10],[2491,12]]},"530":{"position":[[334,11],[1464,11]]},"583":{"position":[[72,10]]},"604":{"position":[[606,11],[1066,11]]},"633":{"position":[[3658,13]]},"656":{"position":[[34,10]]},"662":{"position":[[16,10],[176,11]]},"728":{"position":[[409,10]]},"730":{"position":[[216,11]]},"817":{"position":[[157,11]]},"830":{"position":[[303,10]]},"859":{"position":[[155,11]]},"913":{"position":[[3892,10]]},"926":{"position":[[57,10]]},"932":{"position":[[2311,11]]},"934":{"position":[[312,10],[380,10],[1024,11]]},"949":{"position":[[1130,11]]},"1052":{"position":[[169,10]]},"1055":{"position":[[306,10],[514,10]]},"1057":{"position":[[110,11]]},"1059":{"position":[[43,10],[243,10]]},"1061":{"position":[[37,10],[154,11],[196,10],[320,10],[806,11]]},"1065":{"position":[[43,11],[501,10],[608,11],[775,10]]},"1067":{"position":[[18,10],[351,11],[598,11]]},"1071":{"position":[[496,10],[579,10],[1413,10]]},"1073":{"position":[[16,10],[119,11],[175,10],[225,10]]},"1075":{"position":[[57,10],[138,10],[254,10]]},"1077":{"position":[[50,10],[91,11],[871,11],[1299,10]]},"1080":{"position":[[279,11],[669,11],[1074,11],[1264,11],[1406,10],[1683,11],[1772,11]]},"1098":{"position":[[141,11]]},"1112":{"position":[[3471,10],[4811,10]]},"1120":{"position":[[257,10],[392,10],[1228,11]]},"1150":{"position":[[368,11]]},"1165":{"position":[[312,11],[1352,10],[3356,11],[3534,10]]},"1167":{"position":[[2064,11]]},"1213":{"position":[[1054,11]]},"1219":{"position":[[170,11],[203,10]]},"1232":{"position":[[560,11],[739,11]]},"1236":{"position":[[73,11],[106,10],[338,11]]},"1240":{"position":[[64,11],[153,11],[199,10],[260,10],[315,10],[398,10],[499,10],[743,10],[917,10],[1091,10],[1370,11]]},"1248":{"position":[[130,10]]},"1254":{"position":[[68,10]]},"1262":{"position":[[27,11]]},"1273":{"position":[[66,11],[207,10]]},"1286":{"position":[[1673,10],[2827,11]]},"1362":{"position":[[21,10],[98,10]]},"1489":{"position":[[409,10]]},"1491":{"position":[[216,11]]},"1507":{"position":[[157,11]]},"1545":{"position":[[303,10]]},"1560":{"position":[[341,10]]},"1571":{"position":[[815,10]]},"1580":{"position":[[235,11]]},"1591":{"position":[[324,10],[795,10],[880,10]]},"1594":{"position":[[210,11]]},"1603":{"position":[[155,11]]},"1608":{"position":[[283,12],[579,10],[841,10]]},"1610":{"position":[[69,11]]},"1635":{"position":[[3892,10]]},"1648":{"position":[[57,10]]},"1654":{"position":[[2311,11]]},"1656":{"position":[[312,10],[380,10],[1024,11]]},"1671":{"position":[[1130,11]]},"1676":{"position":[[7,12]]},"1678":{"position":[[546,13],[750,10],[822,10],[1140,11],[1253,10],[1329,12],[1393,12],[1424,11],[2146,11],[2227,10],[2548,11],[2660,11],[2734,11],[2877,10]]},"1684":{"position":[[21,11]]},"1686":{"position":[[59,11],[388,13]]},"1688":{"position":[[48,13]]},"1690":{"position":[[250,12],[534,10],[640,10],[711,10],[778,10],[843,10],[943,10],[1020,10],[1204,12],[1305,10],[1382,10],[1482,10],[1559,10],[1640,10]]},"1701":{"position":[[176,11],[209,11]]},"1740":{"position":[[359,13]]},"1747":{"position":[[46,12]]},"1764":{"position":[[3413,10]]},"1779":{"position":[[192,11],[208,10]]},"1794":{"position":[[788,10]]},"1825":{"position":[[358,11],[422,11],[832,11],[1237,11],[1427,11],[1569,10],[1855,11],[1944,11],[2077,10]]},"1865":{"position":[[888,11]]},"1913":{"position":[[2107,11]]},"2031":{"position":[[16,10]]},"2098":{"position":[[1321,10]]},"2146":{"position":[[215,13]]},"2154":{"position":[[5,10],[549,10]]},"2196":{"position":[[959,10]]},"2209":{"position":[[170,12],[562,10]]},"2229":{"position":[[190,10]]},"2237":{"position":[[96,12]]},"2250":{"position":[[592,13],[686,10]]},"2267":{"position":[[96,12]]},"2283":{"position":[[1185,10]]},"2300":{"position":[[96,12]]},"2315":{"position":[[800,11]]},"2330":{"position":[[170,11]]},"2332":{"position":[[38,12],[85,12]]},"2360":{"position":[[3892,10]]},"2373":{"position":[[57,10]]},"2379":{"position":[[2311,11]]},"2381":{"position":[[312,10],[380,10],[1024,11]]},"2407":{"position":[[231,13]]},"2426":{"position":[[850,11]]},"2428":{"position":[[9,12],[65,12]]},"2474":{"position":[[325,10]]},"2499":{"position":[[12,12]]},"2625":{"position":[[645,11]]},"2631":{"position":[[138,10],[1573,10]]},"2656":{"position":[[13,10]]},"2675":{"position":[[828,13],[1198,11],[1236,10]]},"2677":{"position":[[452,11]]},"2799":{"position":[[18,10]]},"2824":{"position":[[8,10]]},"3011":{"position":[[349,12],[2180,13]]},"3057":{"position":[[293,11]]},"3059":{"position":[[400,11]]},"3061":{"position":[[600,11],[1087,10]]},"3071":{"position":[[1155,11],[2126,10]]},"3299":{"position":[[3812,10],[4825,11]]},"3301":{"position":[[3087,11],[3230,12],[3949,12]]}}}],["repositories/manag",{"_index":2874,"t":{"499":{"position":[[1760,21]]}}}],["repository'",{"_index":4310,"t":{"895":{"position":[[1758,12]]},"1617":{"position":[[1758,12]]},"2342":{"position":[[1758,12]]},"2463":{"position":[[524,12]]}}}],["reposjson",{"_index":683,"t":{"105":{"position":[[1092,9]]}}}],["repostori",{"_index":4665,"t":{"970":{"position":[[124,9]]}}}],["repres",{"_index":1953,"t":{"300":{"position":[[120,9]]},"302":{"position":[[765,11],[1058,9]]},"370":{"position":[[268,9]]},"374":{"position":[[886,10]]},"421":{"position":[[273,10],[358,10]]},"778":{"position":[[45,10]]},"909":{"position":[[2248,12]]},"1566":{"position":[[263,10]]},"1631":{"position":[[2248,12]]},"1770":{"position":[[713,9]]},"1872":{"position":[[293,12]]},"1988":{"position":[[293,12]]},"2156":{"position":[[5,10],[97,10]]},"2356":{"position":[[2248,12]]},"3132":{"position":[[178,12]]},"3224":{"position":[[1803,10]]},"3353":{"position":[[59,9]]},"3372":{"position":[[472,10]]},"3461":{"position":[[394,9]]},"3465":{"position":[[175,12]]}}}],["represent",{"_index":9054,"t":{"2665":{"position":[[312,14]]},"3057":{"position":[[214,14]]},"3218":{"position":[[1407,14]]},"3220":{"position":[[31,14]]},"3224":{"position":[[1066,14]]}}}],["reproduc",{"_index":7130,"t":{"1594":{"position":[[356,13]]},"1913":{"position":[[251,10]]},"2029":{"position":[[251,10]]},"2688":{"position":[[874,10]]},"3224":{"position":[[832,9]]},"3518":{"position":[[213,15]]}}}],["req",{"_index":2512,"t":{"436":{"position":[[940,3]]}}}],["request",{"_index":213,"t":{"18":{"position":[[3,7],[140,7]]},"60":{"position":[[103,9]]},"114":{"position":[[12,7]]},"116":{"position":[[127,7]]},"118":{"position":[[145,7]]},"120":{"position":[[139,8]]},"124":{"position":[[44,7]]},"184":{"position":[[167,7],[262,8],[305,7],[728,7]]},"187":{"position":[[341,8],[415,7]]},"212":{"position":[[175,7]]},"245":{"position":[[1097,9]]},"253":{"position":[[2018,7]]},"263":{"position":[[246,9]]},"280":{"position":[[483,7]]},"321":{"position":[[893,7]]},"325":{"position":[[7290,8],[7395,7]]},"436":{"position":[[444,7],[1083,9]]},"458":{"position":[[82,8]]},"499":{"position":[[1111,10]]},"503":{"position":[[224,8]]},"509":{"position":[[377,9]]},"604":{"position":[[10522,7]]},"742":{"position":[[472,8]]},"932":{"position":[[4456,7]]},"956":{"position":[[1454,7],[1523,8]]},"1061":{"position":[[379,9]]},"1063":{"position":[[428,10]]},"1150":{"position":[[6532,8],[6815,8],[7069,8]]},"1161":{"position":[[1697,7],[1772,7]]},"1321":{"position":[[646,8]]},"1594":{"position":[[30,8],[134,9],[429,8]]},"1654":{"position":[[4456,7]]},"1678":{"position":[[455,7]]},"1779":{"position":[[69,7]]},"1857":{"position":[[907,9]]},"1863":{"position":[[682,9],[855,9],[1030,9]]},"1878":{"position":[[1161,7]]},"1892":{"position":[[518,8]]},"1919":{"position":[[907,9]]},"1925":{"position":[[682,9],[855,9],[1030,9]]},"1957":{"position":[[4324,7]]},"1994":{"position":[[1161,7]]},"2008":{"position":[[518,8]]},"2077":{"position":[[399,8]]},"2096":{"position":[[975,10]]},"2379":{"position":[[4456,7]]},"2489":{"position":[[109,10]]},"2631":{"position":[[98,7],[199,7],[1301,7],[1533,7],[1634,7],[1931,7]]},"2633":{"position":[[371,9]]},"2677":{"position":[[531,8],[983,7]]},"2688":{"position":[[894,7],[1446,7]]},"2709":{"position":[[411,9]]},"2731":{"position":[[301,7],[1403,7]]},"2754":{"position":[[411,9]]},"2770":{"position":[[301,7],[1096,9],[1426,7]]},"2817":{"position":[[136,7],[188,7],[239,7],[333,7],[386,7]]},"2844":{"position":[[339,9]]},"2860":{"position":[[301,7],[1069,9],[1399,7]]},"2947":{"position":[[2882,9]]},"2955":{"position":[[671,7]]},"2964":{"position":[[89,7]]},"3135":{"position":[[22,7]]},"3229":{"position":[[91,7]]},"3236":{"position":[[1731,7],[2057,8],[2258,9],[2978,8]]},"3251":{"position":[[1771,9],[3316,8]]},"3264":{"position":[[206,7],[218,7]]},"3270":{"position":[[53,8],[565,8],[751,8],[919,8],[950,8],[972,7],[1270,8],[1354,8],[1933,8],[2066,8],[2200,7]]},"3276":{"position":[[1203,7]]},"3280":{"position":[[14,8],[184,9],[288,8],[319,8],[341,7],[1081,9]]},"3340":{"position":[[132,8]]},"3343":{"position":[[1026,9]]},"3345":{"position":[[49,7],[162,8]]},"3347":{"position":[[62,7],[250,8],[324,7],[551,8]]},"3361":{"position":[[15,8],[353,8]]},"3363":{"position":[[20,8],[85,8]]},"3365":{"position":[[8,8]]},"3389":{"position":[[589,9],[772,7]]},"3472":{"position":[[6341,8],[6624,8],[6878,8]]},"3482":{"position":[[787,7]]}}}],["request_method",{"_index":6436,"t":{"1321":{"position":[[1607,15],[2335,15],[2763,15]]}}}],["requestor",{"_index":10040,"t":{"3276":{"position":[[2637,9]]}}}],["requestpath",{"_index":8889,"t":{"2566":{"position":[[9969,12]]}}}],["requests_ca_bundl",{"_index":5998,"t":{"1213":{"position":[[622,18],[803,19]]}}}],["requet",{"_index":7131,"t":{"1594":{"position":[[473,7]]}}}],["requir",{"_index":607,"t":{"89":{"position":[[13,12]]},"91":{"position":[[8,12]]},"131":{"position":[[697,7]]},"166":{"position":[[1237,9]]},"172":{"position":[[589,7]]},"174":{"position":[[696,9],[997,9],[1186,7]]},"176":{"position":[[815,8]]},"178":{"position":[[30,7],[303,8],[1403,7]]},"180":{"position":[[194,7]]},"184":{"position":[[152,7],[220,7],[351,7],[396,7],[468,9]]},"191":{"position":[[382,8]]},"210":{"position":[[16,8]]},"249":{"position":[[327,8]]},"253":{"position":[[1726,12]]},"288":{"position":[[321,7]]},"325":{"position":[[1481,8]]},"337":{"position":[[277,7]]},"366":{"position":[[483,11]]},"368":{"position":[[55,9],[204,12]]},"370":{"position":[[175,12]]},"379":{"position":[[49,12],[98,13],[1012,12]]},"387":{"position":[[21,8]]},"393":{"position":[[1043,12]]},"396":{"position":[[177,8]]},"417":{"position":[[1026,8]]},"462":{"position":[[1317,8]]},"485":{"position":[[394,8]]},"499":{"position":[[567,8]]},"509":{"position":[[715,8]]},"527":{"position":[[64,7],[180,12]]},"554":{"position":[[223,8]]},"568":{"position":[[62,8]]},"583":{"position":[[353,13]]},"586":{"position":[[363,12]]},"600":{"position":[[617,7]]},"604":{"position":[[350,8],[7948,7],[9644,8]]},"615":{"position":[[1455,12]]},"617":{"position":[[12,8],[559,12]]},"639":{"position":[[443,12]]},"706":{"position":[[62,8]]},"728":{"position":[[121,9]]},"748":{"position":[[410,8]]},"766":{"position":[[118,8]]},"786":{"position":[[40,8],[372,8],[1095,8]]},"788":{"position":[[66,9]]},"790":{"position":[[507,10]]},"810":{"position":[[86,8]]},"883":{"position":[[1685,13]]},"888":{"position":[[2164,12]]},"901":{"position":[[21,8],[187,8]]},"956":{"position":[[657,8],[2398,7]]},"980":{"position":[[161,12],[333,13]]},"984":{"position":[[176,8],[663,11]]},"986":{"position":[[395,11]]},"988":{"position":[[373,9]]},"995":{"position":[[237,9],[433,8]]},"1055":{"position":[[650,8],[2387,8],[3400,8]]},"1057":{"position":[[18,8]]},"1065":{"position":[[843,9]]},"1067":{"position":[[873,8]]},"1084":{"position":[[91,9]]},"1112":{"position":[[29,12]]},"1114":{"position":[[565,8],[4167,8]]},"1161":{"position":[[1453,8],[3905,8]]},"1165":{"position":[[1842,12],[3063,12]]},"1188":{"position":[[345,8]]},"1213":{"position":[[112,8]]},"1224":{"position":[[1945,8]]},"1234":{"position":[[1865,8]]},"1242":{"position":[[53,8]]},"1248":{"position":[[141,9]]},"1252":{"position":[[435,12]]},"1256":{"position":[[721,8],[1467,8],[1558,8]]},"1258":{"position":[[23,8]]},"1260":{"position":[[23,8]]},"1286":{"position":[[847,8]]},"1288":{"position":[[256,9]]},"1292":{"position":[[69,9],[407,8]]},"1388":{"position":[[289,8]]},"1419":{"position":[[315,10]]},"1458":{"position":[[0,9]]},"1489":{"position":[[121,9]]},"1500":{"position":[[86,8]]},"1523":{"position":[[40,8],[372,8],[1095,8]]},"1525":{"position":[[66,9]]},"1527":{"position":[[507,10]]},"1562":{"position":[[67,13]]},"1571":{"position":[[1115,8]]},"1587":{"position":[[746,8]]},"1594":{"position":[[244,12]]},"1610":{"position":[[3,9]]},"1623":{"position":[[21,8],[187,8]]},"1684":{"position":[[145,12],[202,12],[257,12],[396,12],[1005,8]]},"1736":{"position":[[229,8]]},"1738":{"position":[[66,8]]},"1743":{"position":[[390,9],[2113,8]]},"1758":{"position":[[295,8]]},"1766":{"position":[[268,8]]},"1775":{"position":[[18,8]]},"1779":{"position":[[5911,8],[6134,9]]},"1794":{"position":[[548,8]]},"1816":{"position":[[176,8]]},"1835":{"position":[[477,9]]},"1839":{"position":[[151,8]]},"1849":{"position":[[999,8]]},"1855":{"position":[[79,12],[875,8],[994,8],[1175,13],[1261,8],[1355,13]]},"1857":{"position":[[35,13]]},"1917":{"position":[[79,12],[875,8],[994,8],[1175,13],[1261,8],[1355,13]]},"1919":{"position":[[35,13]]},"1939":{"position":[[61,8]]},"1945":{"position":[[154,8]]},"1957":{"position":[[1784,8]]},"1980":{"position":[[143,9],[296,9]]},"2031":{"position":[[413,8]]},"2041":{"position":[[317,8]]},"2043":{"position":[[678,12]]},"2061":{"position":[[124,8],[231,7]]},"2063":{"position":[[133,8],[249,7]]},"2065":{"position":[[127,8],[237,7]]},"2067":{"position":[[1613,7]]},"2069":{"position":[[286,7]]},"2085":{"position":[[665,12]]},"2093":{"position":[[704,13]]},"2096":{"position":[[2127,8]]},"2098":{"position":[[1589,10],[3438,8]]},"2100":{"position":[[1306,8]]},"2162":{"position":[[450,13]]},"2166":{"position":[[141,7]]},"2253":{"position":[[102,7]]},"2281":{"position":[[814,12]]},"2312":{"position":[[591,9]]},"2330":{"position":[[216,8]]},"2334":{"position":[[78,7]]},"2348":{"position":[[21,8],[187,8]]},"2426":{"position":[[352,12],[423,12]]},"2463":{"position":[[493,13]]},"2476":{"position":[[738,8]]},"2506":{"position":[[40,8]]},"2524":{"position":[[33,13]]},"2546":{"position":[[212,13]]},"2574":{"position":[[523,12]]},"2576":{"position":[[31,12]]},"2586":{"position":[[46,8]]},"2592":{"position":[[657,12],[888,12]]},"2619":{"position":[[34,11]]},"2625":{"position":[[1740,11],[1769,8],[1845,8],[1916,8],[1973,8],[2115,8],[2242,8],[2375,8]]},"2631":{"position":[[1271,9]]},"2642":{"position":[[48,7],[102,7]]},"2647":{"position":[[1018,8],[1352,7]]},"2658":{"position":[[130,8]]},"2669":{"position":[[33,8]]},"2673":{"position":[[852,13],[982,8],[1033,12]]},"2688":{"position":[[306,7],[937,8],[2362,9]]},"2723":{"position":[[554,7]]},"2754":{"position":[[748,12]]},"2762":{"position":[[567,7]]},"2848":{"position":[[554,7]]},"2864":{"position":[[513,12]]},"2888":{"position":[[64,12]]},"2892":{"position":[[839,9]]},"2901":{"position":[[12,7],[460,7],[674,8],[764,8],[1500,8]]},"2913":{"position":[[186,11]]},"2923":{"position":[[210,12]]},"2939":{"position":[[450,11]]},"2942":{"position":[[180,11]]},"2944":{"position":[[1733,12],[1838,8]]},"2947":{"position":[[812,12],[1319,7],[1652,8],[3268,8]]},"2953":{"position":[[306,12]]},"2955":{"position":[[147,12],[340,12],[492,13]]},"2957":{"position":[[168,13],[226,12],[244,7]]},"2990":{"position":[[418,8]]},"2999":{"position":[[208,7]]},"3003":{"position":[[116,9],[209,8]]},"3011":{"position":[[569,7]]},"3014":{"position":[[207,8],[676,8]]},"3031":{"position":[[190,11]]},"3033":{"position":[[241,12]]},"3035":{"position":[[34,7]]},"3053":{"position":[[331,8],[819,8]]},"3055":{"position":[[653,9]]},"3061":{"position":[[490,13]]},"3063":{"position":[[212,7]]},"3067":{"position":[[77,7]]},"3082":{"position":[[120,7],[1206,8],[1683,7]]},"3084":{"position":[[534,13]]},"3101":{"position":[[297,8]]},"3107":{"position":[[1722,11]]},"3113":{"position":[[326,12]]},"3115":{"position":[[65,11]]},"3132":{"position":[[33,8]]},"3135":{"position":[[149,12]]},"3139":{"position":[[175,8]]},"3154":{"position":[[503,12]]},"3156":{"position":[[142,12],[262,13]]},"3160":{"position":[[90,12],[274,8],[389,8],[2180,8]]},"3162":{"position":[[69,11],[140,7],[179,8],[473,8]]},"3175":{"position":[[89,8]]},"3182":{"position":[[1365,10],[1643,12],[1902,7]]},"3184":{"position":[[13,7],[160,8],[778,8],[1016,8],[2686,12]]},"3186":{"position":[[419,8],[640,12],[821,11],[1410,8],[1478,12]]},"3199":{"position":[[29,11]]},"3208":{"position":[[307,12],[1541,9]]},"3210":{"position":[[56,13],[941,7]]},"3214":{"position":[[139,8],[224,8]]},"3218":{"position":[[1090,7],[1231,7]]},"3222":{"position":[[553,12]]},"3224":{"position":[[63,13],[1242,13]]},"3238":{"position":[[362,13]]},"3247":{"position":[[718,12]]},"3249":{"position":[[281,11]]},"3276":{"position":[[477,8]]},"3280":{"position":[[546,8]]},"3286":{"position":[[188,7]]},"3293":{"position":[[272,14],[315,12]]},"3297":{"position":[[140,12],[164,14],[287,13]]},"3299":{"position":[[373,14]]},"3301":{"position":[[885,14],[938,9],[1083,12],[1129,8],[1403,12]]},"3303":{"position":[[13,12],[38,14]]},"3305":{"position":[[0,13]]},"3308":{"position":[[434,12]]},"3312":{"position":[[347,12]]},"3314":{"position":[[3524,12]]},"3338":{"position":[[34,11]]},"3343":{"position":[[1257,7]]},"3347":{"position":[[31,9]]},"3365":{"position":[[185,7]]},"3374":{"position":[[245,12],[330,9]]},"3376":{"position":[[14,12]]},"3378":{"position":[[115,12]]},"3380":{"position":[[62,13]]},"3393":{"position":[[47,12],[157,11]]},"3400":{"position":[[47,12]]},"3423":{"position":[[237,8]]},"3438":{"position":[[233,12]]},"3440":{"position":[[14,12]]},"3453":{"position":[[229,8]]},"3472":{"position":[[13160,12]]},"3518":{"position":[[1703,12],[1954,12],[2150,12]]}}}],["require('child_process",{"_index":677,"t":{"105":{"position":[[982,24]]}}}],["require('f",{"_index":675,"t":{"105":{"position":[[947,13]]}}}],["required_packages_default",{"_index":4747,"t":{"1014":{"position":[[325,26]]}}}],["required_packages_distribut",{"_index":4759,"t":{"1017":{"position":[[36,30],[93,31]]},"1019":{"position":[[36,30],[93,31]]}}}],["required_packages_extra",{"_index":4758,"t":{"1014":{"position":[[531,23],[566,24]]}}}],["requirements.md",{"_index":9063,"t":{"2673":{"position":[[290,15]]}}}],["requirements.txt",{"_index":5007,"t":{"1073":{"position":[[314,16],[338,16]]},"1080":{"position":[[753,16]]},"1825":{"position":[[916,16]]},"2118":{"position":[[824,16]]}}}],["requirements.yml",{"_index":943,"t":{"143":{"position":[[748,17]]},"145":{"position":[[118,16]]},"1686":{"position":[[93,18]]}}}],["reschedul",{"_index":2908,"t":{"505":{"position":[[312,11]]}}}],["research",{"_index":2520,"t":{"436":{"position":[[1510,8]]},"2660":{"position":[[470,8]]},"3018":{"position":[[0,8],[68,8]]},"3308":{"position":[[564,8]]},"3380":{"position":[[29,9]]},"3419":{"position":[[438,10]]}}}],["resembl",{"_index":7896,"t":{"1853":{"position":[[102,8]]},"1915":{"position":[[102,8]]},"3074":{"position":[[109,8]]},"3078":{"position":[[881,8]]}}}],["reserv",{"_index":1415,"t":{"200":{"position":[[147,12],[192,7],[250,12]]},"202":{"position":[[72,7]]},"204":{"position":[[310,12]]},"210":{"position":[[494,12],[559,7]]},"212":{"position":[[200,11]]},"225":{"position":[[153,13]]},"483":{"position":[[1148,7]]},"750":{"position":[[499,8]]},"949":{"position":[[413,8]]},"1052":{"position":[[67,8]]},"1178":{"position":[[31,7]]},"1671":{"position":[[413,8]]},"2053":{"position":[[71,8]]},"2396":{"position":[[413,8]]}}}],["reserved_host_cpu",{"_index":5965,"t":{"1182":{"position":[[159,18]]}}}],["reserved_host_memory_mb",{"_index":5962,"t":{"1180":{"position":[[164,23]]}}}],["reset",{"_index":3749,"t":{"790":{"position":[[991,5]]},"796":{"position":[[782,5]]},"798":{"position":[[778,5]]},"850":{"position":[[9319,5]]},"1430":{"position":[[1361,6]]},"1484":{"position":[[9319,5]]},"1527":{"position":[[991,5]]},"1533":{"position":[[782,5]]},"1535":{"position":[[778,5]]},"1731":{"position":[[29,5]]},"2096":{"position":[[2026,5],[2096,5]]},"2098":{"position":[[3208,5],[3407,5]]}}}],["reshard",{"_index":6910,"t":{"1444":{"position":[[809,10]]}}}],["resid",{"_index":643,"t":{"105":{"position":[[204,6]]},"282":{"position":[[511,6]]},"1890":{"position":[[384,6]]},"1892":{"position":[[1211,7]]},"2006":{"position":[[384,6]]},"2008":{"position":[[1211,7]]},"2960":{"position":[[217,6],[441,8],[619,8],[1022,8]]},"3023":{"position":[[140,7]]},"3472":{"position":[[14556,6]]}}}],["resili",{"_index":1590,"t":{"235":{"position":[[1067,10]]},"880":{"position":[[499,11]]},"888":{"position":[[1701,11],[1859,11]]}}}],["resist",{"_index":9909,"t":{"3184":{"position":[[381,9]]}}}],["resolut",{"_index":8310,"t":{"2150":{"position":[[401,10],[484,10],[673,10]]},"2152":{"position":[[639,10]]}}}],["resolv",{"_index":1708,"t":{"247":{"position":[[2699,7],[3141,7]]},"487":{"position":[[4518,8]]},"876":{"position":[[547,7]]},"1071":{"position":[[674,9],[762,9]]},"2424":{"position":[[31,9]]},"2502":{"position":[[754,7]]},"2799":{"position":[[270,7]]},"3251":{"position":[[5979,7]]}}}],["resolv.conf",{"_index":7779,"t":{"1841":{"position":[[434,11]]}}}],["resolvconf_fil",{"_index":916,"t":{"141":{"position":[[367,15]]},"1699":{"position":[[182,15]]}}}],["resolvconf_nameserv",{"_index":4990,"t":{"1067":{"position":[[5620,22]]}}}],["resourc",{"_index":210,"t":{"16":{"position":[[66,9]]},"21":{"position":[[32,9]]},"71":{"position":[[110,9],[423,9]]},"101":{"position":[[197,9]]},"184":{"position":[[928,9]]},"325":{"position":[[1846,10]]},"368":{"position":[[250,10]]},"391":{"position":[[719,10],[1121,9]]},"396":{"position":[[154,9],[318,9]]},"421":{"position":[[1065,9]]},"427":{"position":[[1111,8]]},"428":{"position":[[756,9],[1645,9]]},"469":{"position":[[196,10]]},"483":{"position":[[189,9]]},"487":{"position":[[1726,10],[1907,10],[3549,9]]},"501":{"position":[[190,9]]},"550":{"position":[[117,9],[244,9]]},"552":{"position":[[132,9],[419,9]]},"554":{"position":[[98,9]]},"570":{"position":[[65,8],[134,8]]},"572":{"position":[[65,8],[136,8]]},"580":{"position":[[33,9]]},"602":{"position":[[175,9]]},"627":{"position":[[3240,10]]},"662":{"position":[[892,9],[1032,10]]},"692":{"position":[[129,9]]},"710":{"position":[[77,9]]},"712":{"position":[[64,10]]},"718":{"position":[[142,9]]},"740":{"position":[[408,10],[555,9]]},"813":{"position":[[362,9]]},"819":{"position":[[675,10],[907,10],[2479,9],[2508,9],[3006,9],[3049,9]]},"830":{"position":[[29,8],[92,8],[122,8],[286,8]]},"883":{"position":[[1590,8]]},"899":{"position":[[768,9]]},"905":{"position":[[2020,9],[2135,8],[2244,9],[2456,8]]},"909":{"position":[[451,9],[1104,11],[1769,9],[1804,8],[1832,8],[1855,8],[2112,8],[2164,9],[2391,10]]},"911":{"position":[[936,10]]},"913":{"position":[[752,9]]},"917":{"position":[[460,9],[710,9]]},"932":{"position":[[3328,10],[4149,8]]},"956":{"position":[[942,9],[1257,8],[1433,10],[1547,10]]},"977":{"position":[[2252,10]]},"1067":{"position":[[3653,9],[3976,8],[4100,9]]},"1122":{"position":[[0,8]]},"1178":{"position":[[9,9]]},"1273":{"position":[[159,8],[370,8]]},"1294":{"position":[[204,10],[309,9]]},"1358":{"position":[[86,8]]},"1362":{"position":[[241,8],[332,8]]},"1503":{"position":[[362,9]]},"1509":{"position":[[675,10],[907,10],[2479,9],[2508,9],[3006,9],[3049,9]]},"1545":{"position":[[29,8],[92,8],[122,8],[286,8]]},"1562":{"position":[[89,8]]},"1566":{"position":[[116,9]]},"1621":{"position":[[768,9]]},"1627":{"position":[[2020,9],[2135,8],[2244,9],[2456,8]]},"1631":{"position":[[451,9],[1104,11],[1769,9],[1804,8],[1832,8],[1855,8],[2112,8],[2164,9],[2391,10]]},"1633":{"position":[[936,10]]},"1635":{"position":[[752,9]]},"1639":{"position":[[460,9],[710,9]]},"1654":{"position":[[3328,10],[4149,8]]},"1740":{"position":[[33,9]]},"1775":{"position":[[105,8]]},"1779":{"position":[[4988,9],[6046,9]]},"1853":{"position":[[674,10],[887,9]]},"1865":{"position":[[49,9],[194,8]]},"1870":{"position":[[111,9]]},"1872":{"position":[[51,8],[192,8],[284,8],[705,8]]},"1874":{"position":[[75,9],[329,10]]},"1876":{"position":[[305,9]]},"1878":{"position":[[50,9]]},"1898":{"position":[[69,8]]},"1900":{"position":[[136,9]]},"1915":{"position":[[674,10],[887,9]]},"1927":{"position":[[49,9],[194,8]]},"1953":{"position":[[387,9]]},"1957":{"position":[[126,9],[291,9],[405,9],[898,9],[949,8],[2962,8],[3227,9],[4012,9]]},"1972":{"position":[[749,8],[857,8],[945,9]]},"1974":{"position":[[67,9],[137,8]]},"1976":{"position":[[219,8],[403,8],[592,8]]},"1978":{"position":[[78,8],[239,8],[482,9],[710,9]]},"1982":{"position":[[879,8],[1162,8]]},"1984":{"position":[[489,8],[772,8]]},"1986":{"position":[[111,9]]},"1988":{"position":[[51,8],[192,8],[284,8],[705,8]]},"1990":{"position":[[75,9],[329,10]]},"1992":{"position":[[305,9]]},"1994":{"position":[[50,9]]},"2014":{"position":[[69,8]]},"2016":{"position":[[136,9]]},"2031":{"position":[[138,9],[162,9]]},"2033":{"position":[[116,9],[910,10],[1289,8],[1766,9]]},"2063":{"position":[[421,9],[526,9]]},"2100":{"position":[[118,8]]},"2176":{"position":[[545,8],[1414,9]]},"2190":{"position":[[111,9]]},"2196":{"position":[[1221,9]]},"2346":{"position":[[768,9]]},"2352":{"position":[[2020,9],[2135,8],[2244,9],[2456,8]]},"2356":{"position":[[451,9],[1104,11],[1769,9],[1804,8],[1832,8],[1855,8],[2112,8],[2164,9],[2391,10]]},"2358":{"position":[[936,10]]},"2360":{"position":[[752,9]]},"2364":{"position":[[460,9],[710,9]]},"2379":{"position":[[3328,10],[4149,8]]},"2409":{"position":[[280,8]]},"2474":{"position":[[159,10]]},"2544":{"position":[[232,10]]},"2574":{"position":[[317,9]]},"2602":{"position":[[345,10]]},"2688":{"position":[[447,8]]},"2944":{"position":[[904,9]]},"3007":{"position":[[127,9],[230,9],[351,8]]},"3014":{"position":[[237,8],[1015,10]]},"3016":{"position":[[165,8]]},"3023":{"position":[[102,9]]},"3059":{"position":[[781,8]]},"3071":{"position":[[240,9],[811,9]]},"3078":{"position":[[160,9]]},"3090":{"position":[[130,8]]},"3097":{"position":[[157,9]]},"3099":{"position":[[362,9]]},"3109":{"position":[[96,9]]},"3152":{"position":[[75,9]]},"3160":{"position":[[1951,8]]},"3182":{"position":[[1747,8]]},"3208":{"position":[[181,8],[353,8]]},"3218":{"position":[[658,9]]},"3220":{"position":[[280,8]]},"3222":{"position":[[334,8]]},"3224":{"position":[[1022,8]]},"3236":{"position":[[1925,9],[1963,10],[2192,9]]},"3245":{"position":[[1349,9]]},"3270":{"position":[[1311,9]]},"3280":{"position":[[573,8]]},"3295":{"position":[[75,9]]},"3325":{"position":[[969,9]]},"3343":{"position":[[373,10],[602,8],[698,8],[720,9]]},"3347":{"position":[[240,9],[271,8],[339,9]]},"3353":{"position":[[71,8],[87,8]]},"3361":{"position":[[35,10],[84,9],[125,8],[170,8],[261,8]]},"3363":{"position":[[69,9],[126,9]]},"3365":{"position":[[155,9]]},"3370":{"position":[[158,8],[238,8]]},"3372":{"position":[[287,9],[506,9],[550,8],[609,9]]},"3374":{"position":[[45,9]]},"3376":{"position":[[124,9],[299,10],[342,8],[727,10]]},"3378":{"position":[[521,8]]},"3382":{"position":[[81,8]]},"3389":{"position":[[93,9]]},"3393":{"position":[[490,9],[1124,8]]},"3395":{"position":[[955,8],[1616,10]]},"3400":{"position":[[1041,9]]},"3413":{"position":[[229,9],[455,8]]},"3434":{"position":[[158,8],[238,8]]},"3436":{"position":[[353,9]]},"3438":{"position":[[33,9]]},"3455":{"position":[[470,9]]},"3459":{"position":[[92,9]]},"3463":{"position":[[192,9]]}}}],["resource=/credentials/o",{"_index":2585,"t":{"467":{"position":[[1566,60]]}}}],["scs.sovereignit.cloud:8080",{"_index":442,"t":{"44":{"position":[[169,26]]},"427":{"position":[[795,26]]},"467":{"position":[[2635,26]]},"471":{"position":[[897,26],[1863,26]]}}}],["scs.tfvar",{"_index":3272,"t":{"621":{"position":[[128,10],[312,10]]},"623":{"position":[[336,10]]}}}],["scs.yaml",{"_index":8135,"t":{"2071":{"position":[[677,8]]},"2110":{"position":[[1055,8]]},"2120":{"position":[[605,8]]},"2138":{"position":[[560,8],[1070,8]]},"2158":{"position":[[833,8]]}}}],["scs/brand.yaml",{"_index":8264,"t":{"2138":{"position":[[105,14]]}}}],["scs/issuer.yaml",{"_index":8265,"t":{"2138":{"position":[[137,15]]}}}],["scs/k8",{"_index":3344,"t":{"633":{"position":[[3672,7],[3702,7]]}}}],["scs/logo.yaml",{"_index":8263,"t":{"2138":{"position":[[74,13]]}}}],["scs/zuul",{"_index":2858,"t":{"497":{"position":[[163,8],[348,8],[567,8],[715,8]]}}}],["scs:aspect1",{"_index":9707,"t":{"3029":{"position":[[421,13]]}}}],["scs:cpu",{"_index":3625,"t":{"730":{"position":[[2261,7]]},"1491":{"position":[[2261,7]]},"2550":{"position":[[328,7]]},"2923":{"position":[[270,7]]},"2931":{"position":[[347,7]]}}}],["scs:disk0",{"_index":3627,"t":{"730":{"position":[[2289,9]]},"1491":{"position":[[2289,9]]},"2931":{"position":[[418,9]]}}}],["scs:diskn",{"_index":8656,"t":{"2550":{"position":[[346,9]]},"2923":{"position":[[576,9]]}}}],["scs:encrypt",{"_index":9712,"t":{"3031":{"position":[[258,17]]},"3042":{"position":[[280,15],[829,15]]},"3046":{"position":[[679,15]]}}}],["scs:name",{"_index":3629,"t":{"730":{"position":[[2311,8],[2339,8]]},"1491":{"position":[[2311,8],[2339,8]]},"2550":{"position":[[315,8]]},"2923":{"position":[[82,8]]},"2931":{"position":[[213,8],[310,8]]}}}],["scs:replic",{"_index":9713,"t":{"3031":{"position":[[320,18]]},"3044":{"position":[[577,16]]}}}],["scs_dev_project",{"_index":10153,"t":{"3325":{"position":[[1516,15],[1563,15],[1730,15],[1788,15],[1829,15],[2273,15]]}}}],["scs_release_r1",{"_index":8407,"t":{"2237":{"position":[[126,15]]}}}],["scs_release_r2",{"_index":8444,"t":{"2267":{"position":[[126,15]]}}}],["scs_release_r3",{"_index":8462,"t":{"2300":{"position":[[126,15]]}}}],["scsi",{"_index":3744,"t":{"790":{"position":[[918,4],[966,4]]},"796":{"position":[[730,4],[757,4]]},"798":{"position":[[726,4],[753,4]]},"850":{"position":[[9246,4],[9294,4]]},"1484":{"position":[[9246,4],[9294,4]]},"1527":{"position":[[918,4],[966,4]]},"1533":{"position":[[730,4],[757,4]]},"1535":{"position":[[726,4],[753,4]]},"1829":{"position":[[336,4]]},"1843":{"position":[[652,4]]},"2892":{"position":[[356,5]]}}}],["scss",{"_index":8632,"t":{"2534":{"position":[[0,4]]}}}],["sd",{"_index":4260,"t":{"865":{"position":[[75,5]]},"878":{"position":[[75,5]]},"1728":{"position":[[127,2],[236,2],[330,2],[411,2]]}}}],["sda",{"_index":5215,"t":{"1112":{"position":[[1089,3],[1703,3],[1789,4],[2004,3],[2090,4],[2323,3],[2410,4],[2683,3],[2795,4],[3278,3],[3390,4]]}}}],["sda,snapshot=external,file=/var/lib/libvirt/images/ub2022_cib_boostrap.qcow2",{"_index":7112,"t":{"1587":{"position":[[1294,76]]}}}],["sda=imguuid:image:12:tru",{"_index":9203,"t":{"2711":{"position":[[1531,25]]},"2856":{"position":[[1509,25]]},"2933":{"position":[[1062,25]]}}}],["sdb",{"_index":4986,"t":{"1067":{"position":[[5550,4]]},"1112":{"position":[[4112,4],[4270,4]]},"1114":{"position":[[515,4],[1205,4]]}}}],["sdb1",{"_index":5315,"t":{"1114":{"position":[[4125,5],[4705,5]]}}}],["sdb2",{"_index":5316,"t":{"1114":{"position":[[4131,5],[4762,5]]}}}],["sdb3",{"_index":5317,"t":{"1114":{"position":[[4137,5],[4819,5]]}}}],["sdb4",{"_index":5318,"t":{"1114":{"position":[[4143,5],[4876,5]]}}}],["sdc",{"_index":4987,"t":{"1067":{"position":[[5557,4]]},"1112":{"position":[[4117,4],[4326,4]]},"1114":{"position":[[531,4],[1272,4]]}}}],["sdd",{"_index":4988,"t":{"1067":{"position":[[5564,4]]},"1114":{"position":[[466,4],[527,3],[543,3],[1102,4],[1217,3],[1284,3]]}}}],["sde",{"_index":4989,"t":{"1067":{"position":[[5571,4]]}}}],["sdf",{"_index":7277,"t":{"1728":{"position":[[17,3],[140,5],[249,5],[343,5],[424,5],[546,4],[937,3]]}}}],["sdk",{"_index":5574,"t":{"1150":{"position":[[7116,3]]},"2321":{"position":[[161,4]]},"3472":{"position":[[6925,3]]}}}],["sdn",{"_index":2921,"t":{"507":{"position":[[703,5]]},"865":{"position":[[163,5]]},"878":{"position":[[163,5]]},"977":{"position":[[2308,3]]},"1360":{"position":[[474,3]]},"2493":{"position":[[247,3]]},"2999":{"position":[[85,3],[141,3]]},"3001":{"position":[[14,3]]},"3003":{"position":[[692,3]]},"3007":{"position":[[52,4]]},"3011":{"position":[[1259,4],[2848,3]]},"3018":{"position":[[9,3]]}}}],["seagate_st16000nm004j_zr604zdz0000c210pwe9",{"_index":7308,"t":{"1728":{"position":[[1068,42],[1269,42]]}}}],["seamless",{"_index":8642,"t":{"2544":{"position":[[252,9]]},"2663":{"position":[[418,8]]},"2675":{"position":[[653,8]]}}}],["seamlessli",{"_index":2148,"t":{"335":{"position":[[399,10]]},"880":{"position":[[193,10]]},"956":{"position":[[741,10],[2056,10]]},"977":{"position":[[2292,10]]},"1943":{"position":[[493,11]]},"2079":{"position":[[505,10]]},"2085":{"position":[[504,10]]}}}],["search",{"_index":784,"t":{"122":{"position":[[329,6]]},"604":{"position":[[1392,6]]},"1091":{"position":[[334,7],[565,7]]},"1591":{"position":[[666,6]]},"2658":{"position":[[139,9]]},"2677":{"position":[[906,6]]}}}],["sec",{"_index":357,"t":{"27":{"position":[[1956,3]]}}}],["secgrp",{"_index":4467,"t":{"913":{"position":[[1791,7],[1799,8],[2048,8]]},"1635":{"position":[[1791,7],[1799,8],[2048,8]]},"2360":{"position":[[1791,7],[1799,8],[2048,8]]}}}],["secgrps=$(openstack",{"_index":4465,"t":{"913":{"position":[[1571,19]]},"1635":{"position":[[1571,19]]},"2360":{"position":[[1571,19]]}}}],["second",{"_index":1948,"t":{"298":{"position":[[940,8]]},"302":{"position":[[1538,6]]},"436":{"position":[[472,7],[1061,6],[1414,6]]},"505":{"position":[[387,8]]},"857":{"position":[[228,9],[388,9]]},"909":{"position":[[2265,7]]},"922":{"position":[[268,7]]},"947":{"position":[[1178,6],[1628,6],[1724,6],[2260,6]]},"1017":{"position":[[472,7]]},"1055":{"position":[[1554,6],[1717,6],[1859,6]]},"1124":{"position":[[482,7],[532,6]]},"1477":{"position":[[241,7]]},"1601":{"position":[[228,9],[388,9]]},"1631":{"position":[[2265,7]]},"1644":{"position":[[268,7]]},"1669":{"position":[[1178,6],[1628,6],[1724,6],[2260,6]]},"1690":{"position":[[372,7]]},"1736":{"position":[[179,6]]},"1957":{"position":[[152,6]]},"2098":{"position":[[816,6]]},"2334":{"position":[[310,6]]},"2356":{"position":[[2265,7]]},"2369":{"position":[[268,7]]},"2394":{"position":[[1178,6],[1628,6],[1724,6],[2260,6]]},"2625":{"position":[[1510,6]]},"2688":{"position":[[2934,6]]},"2879":{"position":[[293,8]]},"2944":{"position":[[1630,8]]},"2966":{"position":[[2078,6]]},"3270":{"position":[[1285,6]]},"3314":{"position":[[1383,7]]}}}],["secondari",{"_index":8524,"t":{"2403":{"position":[[356,9]]},"2852":{"position":[[349,9]]},"3063":{"position":[[870,9]]}}}],["secondli",{"_index":8060,"t":{"1978":{"position":[[181,9]]},"1982":{"position":[[697,9]]},"1984":{"position":[[307,9]]}}}],["secret",{"_index":190,"t":{"12":{"position":[[136,6]]},"311":{"position":[[127,8]]},"325":{"position":[[2234,9],[2531,7],[2640,8],[2669,7],[2735,7],[2787,8],[2801,6],[2870,6],[2892,6],[2970,6],[3351,7],[3363,6],[3427,7],[3489,6],[3548,6],[3619,6],[3694,8],[3726,7],[3921,8],[4360,7],[5174,7],[5247,6],[5402,6],[5476,6],[5552,6],[5632,6],[5966,7],[6029,6],[6090,7],[6222,7],[6321,7],[6513,7],[6762,8],[6808,6],[6865,7],[7520,7],[7860,8],[7940,7]]},"398":{"position":[[118,6]]},"404":{"position":[[675,7],[746,6],[882,6]]},"413":{"position":[[436,7]]},"427":{"position":[[600,6]]},"442":{"position":[[355,7]]},"467":{"position":[[1680,6],[2257,6]]},"471":{"position":[[777,6],[1668,6]]},"497":{"position":[[75,6],[130,6],[321,6],[535,6],[693,7],[782,7]]},"604":{"position":[[6301,6],[6383,6]]},"641":{"position":[[1947,6],[1970,6],[1984,7]]},"646":{"position":[[1427,6],[1515,6],[2118,6]]},"650":{"position":[[1472,6],[1653,7],[2229,6]]},"652":{"position":[[321,6],[1046,6]]},"654":{"position":[[425,8]]},"660":{"position":[[439,6],[476,6],[1167,6]]},"850":{"position":[[387,6],[409,6]]},"922":{"position":[[367,7]]},"1065":{"position":[[565,7],[674,7]]},"1067":{"position":[[363,7],[447,8],[546,7]]},"1256":{"position":[[1789,7]]},"1484":{"position":[[387,6],[409,6]]},"1560":{"position":[[280,7],[433,7]]},"1644":{"position":[[367,7]]},"1745":{"position":[[22,7],[249,7],[371,6]]},"1779":{"position":[[2139,6],[2264,6],[2390,6]]},"1791":{"position":[[2244,6],[3049,6]]},"1872":{"position":[[693,6]]},"1876":{"position":[[212,7]]},"1878":{"position":[[928,7]]},"1894":{"position":[[7,7],[83,6],[152,7],[299,7],[395,6],[508,6],[653,6],[697,6]]},"1896":{"position":[[281,6],[543,7],[567,6],[847,7],[1003,6]]},"1900":{"position":[[36,6],[100,6],[165,6],[223,6],[284,6],[403,6],[483,6],[563,7],[616,6],[751,6],[794,7],[977,6],[1030,6]]},"1904":{"position":[[148,6],[211,6],[296,6],[639,6],[756,6]]},"1913":{"position":[[883,6]]},"1957":{"position":[[851,7],[2394,6]]},"1988":{"position":[[693,6]]},"1992":{"position":[[212,7]]},"1994":{"position":[[928,7]]},"2010":{"position":[[7,7],[83,6],[152,7],[299,7],[395,6],[508,6],[653,6],[697,6]]},"2012":{"position":[[281,6],[543,7],[567,6],[847,7],[1003,6]]},"2016":{"position":[[36,6],[100,6],[165,6],[223,6],[284,6],[403,6],[483,6],[563,7],[616,6],[751,6],[794,7],[977,6],[1030,6]]},"2020":{"position":[[148,6],[211,6],[296,6],[639,6],[756,6]]},"2029":{"position":[[883,6]]},"2033":{"position":[[446,6],[478,6]]},"2138":{"position":[[16,7]]},"2369":{"position":[[367,7]]},"3393":{"position":[[830,7]]},"3400":{"position":[[1301,8]]}}}],["secret'",{"_index":7940,"t":{"1894":{"position":[[271,8]]},"2010":{"position":[[271,8]]}}}],["secret.bash",{"_index":2409,"t":{"411":{"position":[[27,11]]},"413":{"position":[[751,11]]},"415":{"position":[[27,11],[85,11]]}}}],["secret_id",{"_index":7943,"t":{"1894":{"position":[[481,10],[664,11]]},"1904":{"position":[[329,10]]},"1913":{"position":[[853,12],[961,10]]},"2010":{"position":[[481,10],[664,11]]},"2020":{"position":[[329,10]]},"2029":{"position":[[853,12],[961,10]]}}}],["secret_k8s_cluster_api_provid",{"_index":2099,"t":{"325":{"position":[[5738,32]]}}}],["secret_nam",{"_index":3542,"t":{"660":{"position":[[2394,11]]},"1900":{"position":[[335,12],[682,12],[1049,12]]},"2016":{"position":[[335,12],[682,12],[1049,12]]}}}],["secret_repository_nam",{"_index":2097,"t":{"325":{"position":[[5589,23],[6527,22],[6873,22]]}}}],["secret_repository_name_foobar",{"_index":2106,"t":{"325":{"position":[[6266,30]]}}}],["secretkey",{"_index":2528,"t":{"442":{"position":[[494,11]]}}}],["secretnam",{"_index":2112,"t":{"325":{"position":[[6779,10]]}}}],["secretname.secretvalue1",{"_index":2120,"t":{"325":{"position":[[7872,23]]}}}],["secretref",{"_index":8084,"t":{"2033":{"position":[[351,10]]}}}],["secrets.bash",{"_index":2431,"t":{"413":{"position":[[675,12]]},"415":{"position":[[51,12]]},"442":{"position":[[395,12]]}}}],["secrets.yml",{"_index":4853,"t":{"1055":{"position":[[577,11]]},"1120":{"position":[[455,11]]}}}],["secrets/id_rsa.configuration.pub",{"_index":4947,"t":{"1065":{"position":[[889,32]]}}}],["secrets/vaultpass",{"_index":4949,"t":{"1067":{"position":[[517,18]]},"1256":{"position":[[1398,17]]}}}],["secretvalue1",{"_index":2107,"t":{"325":{"position":[[6556,13]]}}}],["secretvalue2",{"_index":2109,"t":{"325":{"position":[[6611,13]]}}}],["secretvalue3",{"_index":2110,"t":{"325":{"position":[[6666,13]]}}}],["section",{"_index":908,"t":{"141":{"position":[[65,7]]},"265":{"position":[[25,7]]},"270":{"position":[[121,7],[221,7]]},"274":{"position":[[38,7]]},"284":{"position":[[53,7]]},"286":{"position":[[95,8]]},"290":{"position":[[617,8]]},"292":{"position":[[69,7]]},"296":{"position":[[262,8]]},"302":{"position":[[1586,8]]},"347":{"position":[[655,7]]},"361":{"position":[[157,8]]},"417":{"position":[[1003,7]]},"419":{"position":[[85,7],[121,7]]},"423":{"position":[[170,7]]},"427":{"position":[[241,7]]},"428":{"position":[[109,7]]},"462":{"position":[[244,8],[507,9],[1527,9]]},"472":{"position":[[1308,7]]},"493":{"position":[[5,7]]},"495":{"position":[[5,7]]},"523":{"position":[[114,7]]},"594":{"position":[[104,7]]},"604":{"position":[[5876,8],[7713,8],[9431,8]]},"609":{"position":[[2742,7],[5442,7]]},"722":{"position":[[21,7]]},"784":{"position":[[98,7]]},"800":{"position":[[457,7]]},"895":{"position":[[2064,7]]},"932":{"position":[[496,8],[945,8],[1176,7],[1316,9],[1417,7],[4439,7]]},"934":{"position":[[1461,7]]},"940":{"position":[[253,8]]},"1008":{"position":[[5,7]]},"1067":{"position":[[1618,7],[1970,7],[2371,7],[4194,7],[4324,7],[4475,7],[4642,7],[4929,7],[5215,7]]},"1073":{"position":[[60,7],[138,7]]},"1150":{"position":[[564,7],[816,8],[5959,7]]},"1165":{"position":[[1154,8],[2029,8]]},"1184":{"position":[[1679,7],[2004,7]]},"1207":{"position":[[5,7]]},"1221":{"position":[[5,7]]},"1224":{"position":[[474,7]]},"1228":{"position":[[5,7]]},"1230":{"position":[[5,7]]},"1234":{"position":[[51,7]]},"1473":{"position":[[244,7]]},"1521":{"position":[[98,7]]},"1537":{"position":[[457,7]]},"1617":{"position":[[2064,7]]},"1654":{"position":[[496,8],[945,8],[1176,7],[1316,9],[1417,7],[4439,7]]},"1656":{"position":[[1461,7]]},"1662":{"position":[[253,8]]},"1684":{"position":[[681,7],[1178,8],[1217,7],[1378,8],[1497,8],[1536,7],[1697,8],[1818,8],[1857,7],[2018,8],[2149,8],[2188,7],[2349,8],[2471,8],[2510,7],[2671,8],[2793,8],[2832,7],[2993,8],[3114,8],[3153,7],[3314,8],[3430,8],[3469,7],[3630,8]]},"1699":{"position":[[58,7]]},"1747":{"position":[[286,8]]},"1749":{"position":[[1648,8]]},"1754":{"position":[[169,8],[223,7]]},"1779":{"position":[[5,7]]},"1791":{"position":[[1190,8],[1531,8]]},"1808":{"position":[[5,7]]},"1859":{"position":[[871,7]]},"1863":{"position":[[370,7]]},"1876":{"position":[[246,8]]},"1878":{"position":[[936,7]]},"1880":{"position":[[429,7]]},"1882":{"position":[[885,7]]},"1896":{"position":[[1335,8]]},"1898":{"position":[[14,8]]},"1904":{"position":[[14,7]]},"1921":{"position":[[871,7]]},"1925":{"position":[[370,7]]},"1943":{"position":[[252,7]]},"1945":{"position":[[103,7]]},"1955":{"position":[[13,7]]},"1957":{"position":[[3473,7]]},"1992":{"position":[[246,8]]},"1994":{"position":[[936,7]]},"1996":{"position":[[429,7]]},"1998":{"position":[[885,7]]},"2012":{"position":[[1335,8]]},"2014":{"position":[[14,8]]},"2020":{"position":[[14,7]]},"2041":{"position":[[229,8]]},"2043":{"position":[[252,7]]},"2049":{"position":[[14,8]]},"2051":{"position":[[749,7]]},"2053":{"position":[[919,8]]},"2059":{"position":[[14,8]]},"2071":{"position":[[549,7],[594,8],[607,8]]},"2096":{"position":[[411,8]]},"2110":{"position":[[928,8],[1006,8]]},"2118":{"position":[[1671,9],[1700,8]]},"2120":{"position":[[507,7],[544,8]]},"2154":{"position":[[1336,9]]},"2158":{"position":[[677,7],[785,8]]},"2283":{"position":[[214,7]]},"2321":{"position":[[624,8]]},"2342":{"position":[[2064,7]]},"2379":{"position":[[496,8],[945,8],[1176,7],[1316,9],[1417,7],[4439,7]]},"2381":{"position":[[1461,7]]},"2387":{"position":[[253,8]]},"2426":{"position":[[741,7]]},"2476":{"position":[[620,7]]},"2627":{"position":[[57,9],[171,7],[253,7],[329,7],[477,9],[501,7],[631,8],[686,7],[851,7],[951,7],[1097,7],[1267,9],[1360,7],[1437,7],[1500,7],[1589,9],[1613,7],[1727,7],[1862,8],[1908,7]]},"2644":{"position":[[196,8]]},"2669":{"position":[[182,9]]},"2673":{"position":[[871,7],[1484,7]]},"2713":{"position":[[124,8]]},"2813":{"position":[[429,7],[458,7],[495,9]]},"2858":{"position":[[124,8]]},"2915":{"position":[[92,8]]},"2923":{"position":[[226,7]]},"3057":{"position":[[342,8]]},"3065":{"position":[[14,7]]},"3160":{"position":[[121,8]]},"3182":{"position":[[870,8],[1319,8]]},"3222":{"position":[[592,8]]},"3238":{"position":[[412,7],[972,7]]},"3251":{"position":[[422,7]]},"3299":{"position":[[2210,7]]},"3301":{"position":[[16,8],[1564,7]]},"3417":{"position":[[188,8]]},"3472":{"position":[[354,7],[414,7],[659,8],[5802,7],[12420,9],[12589,8],[12668,7],[12876,8]]}}}],["sector",{"_index":5286,"t":{"1114":{"position":[[3406,7],[3447,7],[3478,6],[3673,7]]},"1728":{"position":[[551,6]]}}}],["secur",{"_index":488,"t":{"65":{"position":[[87,8]]},"202":{"position":[[621,8]]},"235":{"position":[[740,7]]},"325":{"position":[[3757,6]]},"339":{"position":[[203,8]]},"366":{"position":[[192,8],[640,6]]},"379":{"position":[[79,6],[324,8],[502,8],[571,8],[1106,8]]},"456":{"position":[[57,8]]},"499":{"position":[[1555,6]]},"501":{"position":[[551,8]]},"530":{"position":[[129,8]]},"586":{"position":[[566,7]]},"604":{"position":[[5290,8],[5421,8],[5482,8]]},"631":{"position":[[576,8]]},"646":{"position":[[53,6]]},"750":{"position":[[271,8]]},"772":{"position":[[407,6],[496,8]]},"895":{"position":[[1400,8]]},"903":{"position":[[882,8],[939,8],[979,8],[1080,8],[1204,8],[1241,8],[1281,8],[1986,8],[2011,8],[2036,8]]},"909":{"position":[[2001,8]]},"913":{"position":[[1591,8]]},"932":{"position":[[1184,11]]},"1144":{"position":[[73,8]]},"1366":{"position":[[294,6]]},"1419":{"position":[[224,8],[260,8],[400,8],[466,9],[610,8],[686,8],[747,8],[795,8],[931,6]]},"1560":{"position":[[364,7]]},"1617":{"position":[[1400,8]]},"1625":{"position":[[882,8],[939,8],[979,8],[1080,8],[1204,8],[1241,8],[1281,8],[1986,8],[2011,8],[2036,8]]},"1631":{"position":[[2001,8]]},"1635":{"position":[[1591,8]]},"1654":{"position":[[1184,11]]},"1684":{"position":[[2739,9],[2757,8]]},"1743":{"position":[[803,8],[920,8],[974,8],[1154,8]]},"1775":{"position":[[237,8],[255,8]]},"1794":{"position":[[557,8]]},"1829":{"position":[[47,8]]},"1845":{"position":[[581,8],[706,8],[1094,8],[1212,8],[2618,8]]},"1853":{"position":[[0,8],[53,8],[358,8],[503,8],[646,8],[765,8],[909,8]]},"1855":{"position":[[138,8],[717,8],[755,8],[830,8],[931,8],[1108,8],[1220,8],[1321,8],[1402,8]]},"1857":{"position":[[26,8],[295,8],[1040,8],[1171,8]]},"1859":{"position":[[0,8],[92,8],[297,8],[359,8],[437,8],[490,8],[541,8],[660,8],[714,8],[786,8],[886,8],[912,8]]},"1861":{"position":[[40,8],[134,8],[200,8],[286,8],[347,8]]},"1863":{"position":[[49,8],[83,8],[151,8],[211,8],[296,8],[414,8],[471,8],[532,8],[568,8],[640,8],[702,8],[739,8],[812,8],[875,8],[913,8],[988,8],[1050,8],[1087,8]]},"1865":{"position":[[5,8],[114,8],[234,8],[323,8],[393,8],[450,8],[485,8],[540,8],[630,8],[686,8],[771,8]]},"1894":{"position":[[191,6],[250,8]]},"1913":{"position":[[477,6]]},"1915":{"position":[[0,8],[53,8],[358,8],[503,8],[646,8],[765,8],[909,8]]},"1917":{"position":[[138,8],[717,8],[755,8],[830,8],[931,8],[1108,8],[1220,8],[1321,8],[1402,8]]},"1919":{"position":[[26,8],[295,8],[1040,8],[1171,8]]},"1921":{"position":[[0,8],[92,8],[297,8],[359,8],[437,8],[490,8],[541,8],[660,8],[714,8],[786,8],[886,8],[912,8]]},"1923":{"position":[[40,8],[134,8],[200,8],[286,8],[347,8]]},"1925":{"position":[[49,8],[83,8],[151,8],[211,8],[296,8],[414,8],[471,8],[532,8],[568,8],[640,8],[702,8],[739,8],[812,8],[875,8],[913,8],[988,8],[1050,8],[1087,8]]},"1927":{"position":[[5,8],[114,8],[234,8],[323,8],[393,8],[450,8],[485,8],[540,8],[630,8],[686,8],[771,8]]},"1947":{"position":[[77,8]]},"1951":{"position":[[402,8]]},"1957":{"position":[[926,6]]},"1963":{"position":[[0,8],[198,8],[411,8]]},"1982":{"position":[[136,8]]},"2010":{"position":[[191,6],[250,8]]},"2029":{"position":[[477,6]]},"2079":{"position":[[435,8]]},"2083":{"position":[[74,8],[634,8]]},"2085":{"position":[[32,8],[133,8],[449,8],[799,9]]},"2222":{"position":[[9,7]]},"2235":{"position":[[584,8]]},"2261":{"position":[[142,8]]},"2265":{"position":[[354,8]]},"2294":{"position":[[10,8],[187,8]]},"2298":{"position":[[354,8]]},"2326":{"position":[[71,8]]},"2332":{"position":[[192,8]]},"2342":{"position":[[1400,8]]},"2350":{"position":[[882,8],[939,8],[979,8],[1080,8],[1204,8],[1241,8],[1281,8],[1986,8],[2011,8],[2036,8]]},"2356":{"position":[[2001,8]]},"2360":{"position":[[1591,8]]},"2379":{"position":[[1184,11]]},"2422":{"position":[[71,8]]},"2484":{"position":[[38,8],[82,8],[347,8]]},"2486":{"position":[[449,8],[478,8]]},"2504":{"position":[[300,8]]},"2540":{"position":[[121,6],[554,8]]},"2544":{"position":[[277,6],[963,8],[1070,8]]},"2574":{"position":[[109,6]]},"2592":{"position":[[252,7],[974,8]]},"2602":{"position":[[314,8]]},"2705":{"position":[[1174,6],[1192,8]]},"2713":{"position":[[1213,9]]},"2750":{"position":[[1174,6],[1192,8]]},"2756":{"position":[[930,9]]},"2813":{"position":[[1542,8]]},"2840":{"position":[[1036,6],[1054,8]]},"2858":{"position":[[423,7],[1023,9]]},"2870":{"position":[[129,6]]},"2872":{"position":[[1163,6]]},"2890":{"position":[[437,8]]},"2895":{"position":[[2113,8],[2287,8],[2830,8],[4782,8]]},"2901":{"position":[[1223,8]]},"2949":{"position":[[1044,8]]},"2966":{"position":[[841,8]]},"3074":{"position":[[0,8],[60,8],[277,8],[416,8]]},"3076":{"position":[[0,8],[73,9],[83,8]]},"3078":{"position":[[211,8],[233,8],[256,8],[287,8],[318,8],[428,8],[562,8],[635,8],[668,8],[734,8],[777,8],[821,8],[851,8],[915,8],[1019,8]]},"3080":{"position":[[15,8],[117,8],[271,8],[444,8],[659,8],[754,8]]},"3082":{"position":[[48,8],[244,8],[364,8],[497,8],[624,8],[681,9],[749,8],[848,8],[985,8],[1131,8],[1264,8],[1353,8],[1407,8],[1529,8],[1717,8],[1985,8],[2089,8]]},"3084":{"position":[[112,8],[227,8],[367,8],[402,8],[576,8]]},"3086":{"position":[[12,8],[49,8],[109,8],[137,8],[166,8],[313,8],[377,8],[434,8],[462,8],[491,8]]},"3088":{"position":[[79,8],[148,8],[453,8],[509,8],[541,8]]},"3090":{"position":[[57,8],[109,8]]},"3092":{"position":[[109,8],[149,8],[442,8]]},"3094":{"position":[[100,8]]},"3097":{"position":[[0,8],[280,8],[393,8]]},"3099":{"position":[[0,8],[108,8],[180,8]]},"3101":{"position":[[64,8],[117,8],[154,8],[208,8],[400,8],[463,8]]},"3103":{"position":[[40,8],[124,8],[246,8],[300,8],[387,8],[433,8],[532,8],[612,8],[729,8],[847,8],[1000,8],[1227,8],[1317,8],[1452,8],[1570,8],[1747,8]]},"3105":{"position":[[3,8],[164,8],[240,8],[302,8],[377,8],[532,8],[553,6]]},"3107":{"position":[[80,8],[253,8],[556,8],[612,8],[644,8],[1623,8],[1673,8]]},"3109":{"position":[[114,8],[189,8],[925,8],[1033,8],[1171,8],[3116,8]]},"3111":{"position":[[44,8],[117,8],[232,8],[301,8],[367,8],[535,8]]},"3113":{"position":[[174,8],[194,6]]},"3115":{"position":[[12,8],[205,8],[286,8],[336,8],[436,8],[489,8]]},"3117":{"position":[[57,8],[115,8],[198,8]]},"3119":{"position":[[28,8],[87,8],[122,8]]},"3121":{"position":[[8,8]]},"3124":{"position":[[536,8]]},"3126":{"position":[[272,8],[714,8]]},"3128":{"position":[[79,8]]},"3158":{"position":[[540,8]]},"3160":{"position":[[206,6],[952,8]]},"3167":{"position":[[798,8]]},"3169":{"position":[[214,8]]},"3186":{"position":[[238,8]]},"3191":{"position":[[602,8]]},"3227":{"position":[[61,8],[211,6],[470,6],[565,8]]},"3229":{"position":[[33,8]]},"3231":{"position":[[80,8],[147,8],[424,8]]},"3234":{"position":[[245,9]]},"3236":{"position":[[12,6],[714,6],[842,6],[2116,8]]},"3238":{"position":[[32,8],[124,9],[494,6],[556,7]]},"3240":{"position":[[26,8],[75,8],[167,8]]},"3266":{"position":[[666,6]]},"3276":{"position":[[12,6]]},"3278":{"position":[[63,9]]},"3284":{"position":[[434,8],[551,6]]},"3293":{"position":[[513,9]]},"3299":{"position":[[1816,8],[1829,8],[1904,8],[3211,8],[3224,8],[4434,8],[4447,8]]},"3301":{"position":[[516,9],[1213,8],[1512,6],[2024,7],[3211,8],[4428,8]]},"3367":{"position":[[122,7]]},"3465":{"position":[[599,8]]},"3472":{"position":[[12983,6]]},"3477":{"position":[[321,6]]},"3482":{"position":[[1808,8],[3251,6]]},"3484":{"position":[[374,6]]},"3518":{"position":[[1381,8],[1498,8],[2045,8]]}}}],["secure.yaml",{"_index":2893,"t":{"501":{"position":[[965,12]]},"617":{"position":[[977,11]]},"903":{"position":[[151,11]]},"905":{"position":[[539,11],[966,11],[1237,13]]},"1625":{"position":[[151,11]]},"1627":{"position":[[539,11],[966,11],[1237,13]]},"2350":{"position":[[151,11]]},"2352":{"position":[[539,11],[966,11],[1237,13]]}}}],["secure.yml",{"_index":3605,"t":{"730":{"position":[[33,10]]},"817":{"position":[[33,10]]},"830":{"position":[[213,10]]},"859":{"position":[[33,10]]},"1491":{"position":[[33,10]]},"1507":{"position":[[33,10]]},"1545":{"position":[[213,10]]},"1603":{"position":[[33,10]]}}}],["secure.yml.sampl",{"_index":3926,"t":{"830":{"position":[[251,17]]},"1545":{"position":[[251,17]]}}}],["security3",{"_index":9748,"t":{"3082":{"position":[[1584,10]]}}}],["security_group",{"_index":3895,"t":{"821":{"position":[[2779,17],[4112,17],[5433,17]]},"1511":{"position":[[2779,17],[4112,17],[5433,17]]},"1743":{"position":[[1059,15],[1239,15],[1589,16]]},"1859":{"position":[[512,15],[747,15]]},"1865":{"position":[[658,15],[799,15]]},"1921":{"position":[[512,15],[747,15]]},"1927":{"position":[[658,15],[799,15]]},"3109":{"position":[[394,14],[713,14],[1731,14],[1859,14],[2927,14]]}}}],["security_group_1",{"_index":7915,"t":{"1865":{"position":[[465,17]]},"1927":{"position":[[465,17]]}}}],["security_group_2",{"_index":7916,"t":{"1865":{"position":[[500,17]]},"1927":{"position":[[500,17]]}}}],["security_group_rul",{"_index":3896,"t":{"821":{"position":[[2800,22],[4135,22],[5454,22]]},"1511":{"position":[[2800,22],[4135,22],[5454,22]]}}}],["securitygroup",{"_index":3961,"t":{"842":{"position":[[461,13]]},"1557":{"position":[[461,13]]}}}],["securitygrouprul",{"_index":3963,"t":{"842":{"position":[[523,17],[2196,17],[2302,17],[2408,17]]},"1557":{"position":[[523,17],[2196,17],[2302,17],[2408,17]]}}}],["sed",{"_index":3220,"t":{"609":{"position":[[2953,3],[3053,3],[3193,3],[3314,3],[3625,3],[3725,3],[3865,3],[3986,3],[5693,3],[5814,3]]},"635":{"position":[[3553,3],[4014,3]]},"903":{"position":[[3347,3]]},"1080":{"position":[[313,3]]},"1364":{"position":[[619,3]]},"1625":{"position":[[3347,3]]},"1825":{"position":[[456,3]]},"2106":{"position":[[716,3]]},"2350":{"position":[[3347,3]]},"2735":{"position":[[473,3],[584,3]]},"2774":{"position":[[609,3],[720,3]]}}}],["see",{"_index":138,"t":{"10":{"position":[[1239,3]]},"12":{"position":[[228,3]]},"48":{"position":[[0,3]]},"55":{"position":[[0,4]]},"60":{"position":[[113,3]]},"101":{"position":[[182,3]]},"129":{"position":[[390,4]]},"158":{"position":[[369,3]]},"164":{"position":[[192,3]]},"168":{"position":[[787,3]]},"191":{"position":[[391,4]]},"195":{"position":[[160,4]]},"202":{"position":[[162,4],[237,4],[472,4]]},"210":{"position":[[585,4]]},"214":{"position":[[416,4]]},"227":{"position":[[100,4]]},"231":{"position":[[479,3]]},"238":{"position":[[78,3]]},"288":{"position":[[73,4]]},"292":{"position":[[65,3]]},"302":{"position":[[1612,4]]},"311":{"position":[[136,3]]},"319":{"position":[[807,3]]},"321":{"position":[[397,3],[1713,3]]},"323":{"position":[[375,3]]},"325":{"position":[[2196,3],[5535,3]]},"355":{"position":[[269,3]]},"357":{"position":[[7,3]]},"359":{"position":[[0,3]]},"385":{"position":[[114,3]]},"391":{"position":[[556,3]]},"417":{"position":[[1014,3]]},"421":{"position":[[882,3]]},"436":{"position":[[148,3],[1571,3]]},"444":{"position":[[363,3]]},"447":{"position":[[119,3],[786,3]]},"460":{"position":[[275,3]]},"462":{"position":[[1504,4]]},"467":{"position":[[1132,4]]},"472":{"position":[[352,3],[1632,3]]},"487":{"position":[[488,3],[3893,3],[5913,3]]},"489":{"position":[[386,3]]},"491":{"position":[[379,3]]},"495":{"position":[[557,3],[1444,3]]},"505":{"position":[[861,3]]},"509":{"position":[[173,3],[475,3]]},"527":{"position":[[155,4]]},"540":{"position":[[141,3]]},"576":{"position":[[98,3]]},"578":{"position":[[75,3]]},"580":{"position":[[94,3]]},"590":{"position":[[654,3],[1550,3],[1714,3]]},"604":{"position":[[1011,3],[6942,4],[7696,3],[8599,4],[9414,3]]},"609":{"position":[[1645,3],[2517,3],[2730,3],[5430,3],[6128,3]]},"617":{"position":[[1360,3]]},"619":{"position":[[743,3]]},"627":{"position":[[1484,3],[3407,3],[4403,4],[4583,3]]},"633":{"position":[[1833,3]]},"641":{"position":[[1389,3]]},"654":{"position":[[739,3]]},"656":{"position":[[344,3]]},"662":{"position":[[105,3]]},"669":{"position":[[256,3]]},"786":{"position":[[808,4],[1033,3]]},"819":{"position":[[6871,3]]},"895":{"position":[[2147,3]]},"899":{"position":[[423,3],[841,3]]},"903":{"position":[[2369,3]]},"920":{"position":[[679,4]]},"922":{"position":[[109,3]]},"924":{"position":[[0,3]]},"930":{"position":[[175,4]]},"932":{"position":[[2716,3],[3295,3],[3391,3],[4096,3]]},"938":{"position":[[146,3]]},"940":{"position":[[228,3]]},"945":{"position":[[118,4]]},"947":{"position":[[674,3],[1654,3]]},"1061":{"position":[[818,3]]},"1089":{"position":[[930,3]]},"1161":{"position":[[305,4]]},"1234":{"position":[[2731,3]]},"1460":{"position":[[300,4]]},"1473":{"position":[[1196,3]]},"1509":{"position":[[6871,3]]},"1523":{"position":[[808,4],[1033,3]]},"1617":{"position":[[2147,3]]},"1621":{"position":[[423,3],[841,3]]},"1625":{"position":[[2369,3]]},"1642":{"position":[[679,4]]},"1644":{"position":[[109,3]]},"1646":{"position":[[0,3]]},"1652":{"position":[[175,4]]},"1654":{"position":[[2716,3],[3295,3],[3391,3],[4096,3]]},"1660":{"position":[[146,3]]},"1662":{"position":[[228,3]]},"1667":{"position":[[118,4]]},"1669":{"position":[[674,3],[1654,3]]},"1728":{"position":[[41,3]]},"1791":{"position":[[1456,3],[1994,3],[2799,3]]},"1833":{"position":[[69,3]]},"1847":{"position":[[638,3]]},"1880":{"position":[[398,3]]},"1882":{"position":[[574,3],[877,3]]},"1896":{"position":[[1265,3]]},"1951":{"position":[[118,3]]},"1967":{"position":[[0,3]]},"1982":{"position":[[272,3]]},"1996":{"position":[[398,3]]},"1998":{"position":[[574,3],[877,3]]},"2012":{"position":[[1265,3]]},"2033":{"position":[[79,4],[126,4]]},"2039":{"position":[[207,3],[939,3]]},"2043":{"position":[[708,3]]},"2051":{"position":[[138,3],[177,3],[716,3]]},"2096":{"position":[[2243,3]]},"2098":{"position":[[2620,3],[3554,3]]},"2162":{"position":[[464,3]]},"2164":{"position":[[526,3]]},"2190":{"position":[[804,3]]},"2192":{"position":[[0,3]]},"2196":{"position":[[520,4],[570,3]]},"2198":{"position":[[0,3]]},"2202":{"position":[[0,3]]},"2220":{"position":[[92,3]]},"2222":{"position":[[114,3]]},"2237":{"position":[[0,3]]},"2253":{"position":[[173,3]]},"2261":{"position":[[134,3]]},"2267":{"position":[[0,3]]},"2283":{"position":[[186,3]]},"2286":{"position":[[59,3]]},"2300":{"position":[[0,3]]},"2342":{"position":[[2147,3]]},"2346":{"position":[[423,3],[841,3]]},"2350":{"position":[[2369,3]]},"2367":{"position":[[679,4]]},"2369":{"position":[[109,3]]},"2371":{"position":[[0,3]]},"2377":{"position":[[175,4]]},"2379":{"position":[[2716,3],[3295,3],[3391,3],[4096,3]]},"2385":{"position":[[146,3]]},"2387":{"position":[[228,3]]},"2392":{"position":[[118,4]]},"2394":{"position":[[674,3],[1654,3]]},"2516":{"position":[[43,3]]},"2695":{"position":[[170,4]]},"2700":{"position":[[235,4]]},"2702":{"position":[[248,3]]},"2705":{"position":[[1473,4]]},"2731":{"position":[[110,3]]},"2735":{"position":[[334,3]]},"2737":{"position":[[419,3]]},"2740":{"position":[[170,4]]},"2745":{"position":[[235,4]]},"2747":{"position":[[248,3]]},"2750":{"position":[[1775,4]]},"2766":{"position":[[227,3]]},"2770":{"position":[[110,3]]},"2774":{"position":[[470,3]]},"2776":{"position":[[419,3]]},"2783":{"position":[[233,3]]},"2805":{"position":[[460,4],[615,4]]},"2835":{"position":[[176,4]]},"2840":{"position":[[1121,4]]},"2860":{"position":[[110,3]]},"2872":{"position":[[1329,4]]},"2899":{"position":[[437,4]]},"2913":{"position":[[320,4]]},"2923":{"position":[[761,3]]},"2966":{"position":[[238,3],[327,3],[3899,3]]},"2983":{"position":[[277,4]]},"2985":{"position":[[395,4]]},"3124":{"position":[[970,4]]},"3160":{"position":[[1215,3]]},"3167":{"position":[[282,4],[470,4]]},"3184":{"position":[[3077,3]]},"3245":{"position":[[1122,3]]},"3251":{"position":[[5393,4]]},"3276":{"position":[[1759,4]]},"3299":{"position":[[2186,4]]},"3301":{"position":[[1842,3]]},"3468":{"position":[[123,4],[164,3],[330,4],[371,3],[772,3]]},"3472":{"position":[[344,4]]},"3482":{"position":[[3134,3]]},"3484":{"position":[[257,3]]},"3491":{"position":[[29,6]]},"3518":{"position":[[369,4]]}}}],["seed",{"_index":4294,"t":{"888":{"position":[[745,5],[860,4],[1092,5],[1795,4]]},"1047":{"position":[[68,4]]},"1059":{"position":[[482,4]]},"1067":{"position":[[994,4]]},"1219":{"position":[[307,4]]},"1236":{"position":[[187,4],[261,4],[354,4],[489,4],[547,4],[748,4],[902,4]]},"1240":{"position":[[546,4]]},"1252":{"position":[[58,4],[76,4],[132,4],[890,4],[1352,4]]},"1254":{"position":[[86,4],[119,4],[178,4]]},"1264":{"position":[[290,4]]},"1686":{"position":[[185,4]]}}}],["seek",{"_index":1637,"t":{"245":{"position":[[1796,4]]},"366":{"position":[[712,7]]},"2737":{"position":[[199,4]]},"2776":{"position":[[199,4]]}}}],["seem",{"_index":1099,"t":{"170":{"position":[[261,5],[907,4]]},"505":{"position":[[15,4]]},"949":{"position":[[908,4]]},"1473":{"position":[[1252,5]]},"1671":{"position":[[908,4]]},"2396":{"position":[[908,4]]},"2864":{"position":[[212,4]]},"2947":{"position":[[1741,4]]},"3061":{"position":[[1173,5]]},"3201":{"position":[[453,4]]},"3255":{"position":[[336,4]]},"3299":{"position":[[4994,5],[5177,4],[5478,5],[5587,5]]},"3301":{"position":[[1948,6]]},"3310":{"position":[[922,6]]},"3378":{"position":[[873,5]]}}}],["seemingli",{"_index":9724,"t":{"3059":{"position":[[4,9]]}}}],["seen",{"_index":1045,"t":{"166":{"position":[[1229,4]]},"436":{"position":[[1372,4]]},"1406":{"position":[[566,4]]},"1863":{"position":[[233,4]]},"1925":{"position":[[233,4]]},"2278":{"position":[[245,4]]},"2281":{"position":[[240,4]]},"2298":{"position":[[891,4]]},"2315":{"position":[[32,4]]},"2426":{"position":[[499,4],[719,4]]},"2468":{"position":[[527,4]]},"2497":{"position":[[193,4]]},"2795":{"position":[[1137,4]]},"2966":{"position":[[1607,4]]},"3055":{"position":[[505,4]]},"3061":{"position":[[951,4],[1293,4]]},"3236":{"position":[[467,4]]}}}],["segment",{"_index":7088,"t":{"1585":{"position":[[2634,8]]},"3003":{"position":[[185,7]]}}}],["select",{"_index":167,"t":{"10":{"position":[[1702,6]]},"251":{"position":[[317,6]]},"568":{"position":[[107,6]]},"596":{"position":[[1594,8]]},"635":{"position":[[2339,8],[2600,8],[2845,8],[3104,8]]},"742":{"position":[[656,9]]},"774":{"position":[[528,8]]},"984":{"position":[[403,8]]},"988":{"position":[[506,11]]},"1226":{"position":[[955,6]]},"1234":{"position":[[771,6],[801,6]]},"1321":{"position":[[63,6],[336,6],[1395,6],[2094,6]]},"1571":{"position":[[366,9]]},"1578":{"position":[[76,6]]},"1585":{"position":[[1692,6]]},"1791":{"position":[[254,6],[1235,6]]},"1845":{"position":[[178,6],[358,6]]},"2152":{"position":[[620,7]]},"2332":{"position":[[234,9]]},"2697":{"position":[[214,9]]},"2737":{"position":[[589,9]]},"2742":{"position":[[214,9]]},"2776":{"position":[[589,9]]},"2832":{"position":[[214,9]]},"2921":{"position":[[214,9]]},"3025":{"position":[[361,8]]},"3154":{"position":[[384,9]]},"3158":{"position":[[277,8]]},"3182":{"position":[[718,9]]},"3301":{"position":[[1439,8],[1585,8]]}}}],["select(.kind",{"_index":3369,"t":{"635":{"position":[[2245,13],[2506,13],[2753,13],[3012,13]]}}}],["select(.stat_sum.num_large_omap_object",{"_index":6904,"t":{"1444":{"position":[[99,39]]}}}],["selector",{"_index":3416,"t":{"641":{"position":[[1669,8]]}}}],["self",{"_index":351,"t":{"27":{"position":[[1688,4]]},"101":{"position":[[544,4]]},"235":{"position":[[723,4]]},"249":{"position":[[9,4]]},"270":{"position":[[140,4],[500,4]]},"300":{"position":[[227,4]]},"327":{"position":[[429,4]]},"467":{"position":[[1541,8]]},"513":{"position":[[228,4],[971,4]]},"617":{"position":[[1217,5]]},"880":{"position":[[290,4],[307,4]]},"1012":{"position":[[482,4],[531,4]]},"1108":{"position":[[993,4]]},"1213":{"position":[[11,4],[192,4]]},"1368":{"position":[[1997,6],[2676,6]]},"1789":{"position":[[84,4]]},"1955":{"position":[[237,4]]},"2037":{"position":[[311,4]]},"2051":{"position":[[274,4]]},"2229":{"position":[[47,4],[348,4]]},"2265":{"position":[[482,4]]},"2281":{"position":[[666,4],[1104,4],[1263,4]]},"2298":{"position":[[482,4]]},"2472":{"position":[[86,4]]},"2868":{"position":[[212,4]]},"3053":{"position":[[504,4]]},"3071":{"position":[[1432,4]]},"3150":{"position":[[340,4]]},"3238":{"position":[[195,4]]},"3249":{"position":[[127,4],[308,5],[720,5]]},"3251":{"position":[[4687,4]]},"3453":{"position":[[99,4]]},"3457":{"position":[[128,4],[325,4],[547,4]]},"3459":{"position":[[516,4],[896,4]]},"3461":{"position":[[204,4]]},"3472":{"position":[[14276,4],[14611,4]]},"3482":{"position":[[1754,4]]}}}],["selinux",{"_index":4767,"t":{"1017":{"position":[[234,7]]}}}],["sell",{"_index":1297,"t":{"178":{"position":[[2433,4]]}}}],["semant",{"_index":8050,"t":{"1972":{"position":[[828,9],[909,12]]},"1974":{"position":[[16,14]]},"1982":{"position":[[1351,10]]},"1984":{"position":[[961,10]]},"2923":{"position":[[71,10],[1076,9]]}}}],["semaphor",{"_index":2850,"t":{"495":{"position":[[417,9],[427,9],[1304,9],[1314,9]]}}}],["semver",{"_index":9038,"t":{"2647":{"position":[[70,6],[1375,6]]}}}],["send",{"_index":1530,"t":{"225":{"position":[[112,5]]},"229":{"position":[[144,4]]},"233":{"position":[[100,4]]},"899":{"position":[[961,5]]},"913":{"position":[[519,7]]},"915":{"position":[[444,7],[1154,4]]},"920":{"position":[[34,4],[410,7],[907,4]]},"930":{"position":[[44,4]]},"1082":{"position":[[56,4]]},"1621":{"position":[[961,5]]},"1635":{"position":[[519,7]]},"1637":{"position":[[444,7],[1154,4]]},"1642":{"position":[[34,4],[410,7],[907,4]]},"1652":{"position":[[44,4]]},"2346":{"position":[[961,5]]},"2360":{"position":[[519,7]]},"2362":{"position":[[444,7],[1154,4]]},"2367":{"position":[[34,4],[410,7],[907,4]]},"2377":{"position":[[44,4]]},"2568":{"position":[[327,4],[380,4]]},"3234":{"position":[[445,4]]},"3280":{"position":[[23,4]]},"3316":{"position":[[1020,4]]},"3325":{"position":[[3188,4],[3335,4]]},"3389":{"position":[[865,4]]},"3436":{"position":[[75,5],[440,7]]},"3444":{"position":[[48,7]]}}}],["senlin",{"_index":7704,"t":{"1814":{"position":[[460,6]]},"2190":{"position":[[771,7]]}}}],["sens",{"_index":976,"t":{"151":{"position":[[273,5]]},"503":{"position":[[628,6]]},"786":{"position":[[309,5]]},"995":{"position":[[559,5]]},"1146":{"position":[[78,5]]},"1213":{"position":[[1075,5]]},"1523":{"position":[[309,5]]},"1684":{"position":[[913,5]]},"1728":{"position":[[264,5],[363,6]]},"2709":{"position":[[393,5]]},"2754":{"position":[[393,5]]},"2844":{"position":[[321,5]]},"2895":{"position":[[3488,7]]},"2966":{"position":[[1978,5]]},"3103":{"position":[[97,5]]},"3255":{"position":[[254,5]]},"3310":{"position":[[615,5],[769,5]]},"3423":{"position":[[207,6],[413,5]]},"3482":{"position":[[426,5]]}}}],["sensibl",{"_index":804,"t":{"129":{"position":[[114,8]]},"786":{"position":[[555,8]]},"1523":{"position":[[555,8]]},"3186":{"position":[[805,8]]}}}],["sensit",{"_index":4516,"t":{"922":{"position":[[528,9]]},"942":{"position":[[560,9]]},"1644":{"position":[[528,9]]},"1664":{"position":[[560,9]]},"1779":{"position":[[1810,9]]},"2369":{"position":[[528,9]]},"2389":{"position":[[560,9]]},"2702":{"position":[[305,10]]},"2719":{"position":[[1759,10]]},"2747":{"position":[[305,10]]},"2758":{"position":[[1875,10]]},"2858":{"position":[[1663,10]]},"2944":{"position":[[1197,9]]}}}],["sent",{"_index":1425,"t":{"202":{"position":[[545,4]]},"760":{"position":[[457,5]]},"932":{"position":[[2813,4]]},"1654":{"position":[[2813,4]]},"2379":{"position":[[2813,4]]}}}],["sentinel",{"_index":2541,"t":{"447":{"position":[[521,9]]}}}],["sep",{"_index":6486,"t":{"1339":{"position":[[96,3]]}}}],["separ",{"_index":1480,"t":{"210":{"position":[[684,11]]},"298":{"position":[[673,8]]},"300":{"position":[[149,8]]},"409":{"position":[[378,8]]},"460":{"position":[[891,9]]},"740":{"position":[[345,8]]},"744":{"position":[[184,8]]},"922":{"position":[[1160,9]]},"1124":{"position":[[306,9],[331,9]]},"1644":{"position":[[1160,9]]},"1684":{"position":[[771,10]]},"1779":{"position":[[613,8]]},"1945":{"position":[[19,8]]},"1955":{"position":[[112,8]]},"2369":{"position":[[1160,9]]},"2631":{"position":[[2065,8]]},"2644":{"position":[[178,8]]},"2697":{"position":[[1082,8]]},"2735":{"position":[[750,8]]},"2742":{"position":[[981,8]]},"2795":{"position":[[662,8]]},"2966":{"position":[[1194,10]]},"3059":{"position":[[172,8]]},"3078":{"position":[[708,8]]},"3178":{"position":[[541,8]]},"3182":{"position":[[446,9],[2295,10]]},"3184":{"position":[[486,10],[1920,9]]},"3191":{"position":[[528,8]]},"3251":{"position":[[552,10]]},"3278":{"position":[[143,9]]},"3301":{"position":[[5348,8]]},"3472":{"position":[[12796,9]]}}}],["sepat",{"_index":1971,"t":{"302":{"position":[[1087,8]]}}}],["seper",{"_index":644,"t":{"105":{"position":[[240,8]]}}}],["seperatli",{"_index":9647,"t":{"2966":{"position":[[1150,9]]}}}],["septemb",{"_index":8446,"t":{"2267":{"position":[[183,9]]},"2895":{"position":[[4574,9]]}}}],["sequenc",{"_index":1430,"t":{"202":{"position":[[655,8]]},"1833":{"position":[[1226,8]]},"2895":{"position":[[1585,8]]},"3055":{"position":[[794,8]]}}}],["sequenti",{"_index":6163,"t":{"1290":{"position":[[68,13]]},"1400":{"position":[[418,12]]},"2923":{"position":[[686,10]]},"2944":{"position":[[1800,10]]},"2949":{"position":[[495,10]]},"3063":{"position":[[526,10]]}}}],["seri",{"_index":4627,"t":{"942":{"position":[[293,6]]},"1219":{"position":[[23,6]]},"1664":{"position":[[293,6]]},"2263":{"position":[[413,6]]},"2389":{"position":[[293,6]]},"3370":{"position":[[510,6]]},"3372":{"position":[[11,6],[398,6],[437,6]]},"3374":{"position":[[311,6],[359,6]]},"3376":{"position":[[38,6]]},"3378":{"position":[[33,6],[234,6],[742,6]]},"3389":{"position":[[487,6]]}}}],["serial",{"_index":4171,"t":{"853":{"position":[[250,6]]},"1226":{"position":[[1523,6],[1551,6]]},"1597":{"position":[[250,6]]},"1764":{"position":[[3801,6]]},"2566":{"position":[[11049,7]]}}}],["serial=10",{"_index":7495,"t":{"1764":{"position":[[4016,10]]}}}],["seriou",{"_index":1230,"t":{"176":{"position":[[671,7]]}}}],["serious.md",{"_index":9029,"t":{"2631":{"position":[[2260,11]]}}}],["serv",{"_index":1302,"t":{"178":{"position":[[2596,7]]},"284":{"position":[[335,5]]},"366":{"position":[[868,6],[1417,6]]},"513":{"position":[[740,5]]},"530":{"position":[[668,6]]},"617":{"position":[[263,6]]},"736":{"position":[[10,6]]},"746":{"position":[[88,5]]},"750":{"position":[[353,6]]},"772":{"position":[[224,6]]},"990":{"position":[[208,6]]},"1067":{"position":[[3381,5],[3873,5]]},"1252":{"position":[[183,6]]},"1972":{"position":[[1259,6],[1301,6]]},"2100":{"position":[[192,6]]},"2526":{"position":[[159,6]]},"2673":{"position":[[389,6]]},"2675":{"position":[[108,6]]},"3160":{"position":[[1125,5]]},"3245":{"position":[[1359,6]]},"3249":{"position":[[336,6]]},"3276":{"position":[[2694,7]]},"3301":{"position":[[5164,6]]},"3308":{"position":[[182,7]]},"3419":{"position":[[73,6]]}}}],["server",{"_index":1009,"t":{"164":{"position":[[38,6],[84,6]]},"249":{"position":[[103,6],[122,6]]},"377":{"position":[[58,6]]},"379":{"position":[[90,7],[116,6],[145,6],[206,6],[277,6],[528,6],[850,6],[1044,6]]},"427":{"position":[[15,6],[256,7],[325,6]]},"471":{"position":[[15,6]]},"483":{"position":[[50,6],[74,7],[287,6],[341,7],[851,6]]},"485":{"position":[[39,6],[567,6],[636,7],[806,7]]},"487":{"position":[[2292,6]]},"501":{"position":[[700,6],[1136,7]]},"507":{"position":[[586,6]]},"513":{"position":[[343,6],[491,6],[690,6],[1156,6],[2597,7]]},"525":{"position":[[90,7],[198,7]]},"530":{"position":[[39,6],[686,6],[1175,7],[1336,7]]},"534":{"position":[[43,7]]},"538":{"position":[[45,7]]},"540":{"position":[[89,7]]},"542":{"position":[[89,6]]},"550":{"position":[[43,6]]},"583":{"position":[[18,7]]},"588":{"position":[[275,6],[334,7]]},"590":{"position":[[2653,7]]},"604":{"position":[[7687,8],[9397,7],[10095,6],[11885,6]]},"609":{"position":[[2455,8],[5310,7]]},"613":{"position":[[15,7]]},"617":{"position":[[293,6],[455,6],[836,6]]},"627":{"position":[[54,7],[374,7],[1186,6],[1380,7],[1576,6],[3670,6],[3896,6],[4891,6],[5150,6],[5398,6]]},"629":{"position":[[78,6],[255,6],[383,7],[780,6]]},"631":{"position":[[18,6]]},"635":{"position":[[1384,6]]},"641":{"position":[[230,6]]},"646":{"position":[[758,6]]},"648":{"position":[[658,7],[911,7]]},"650":{"position":[[758,6],[1181,6],[1276,6]]},"660":{"position":[[3053,6],[3369,6],[3401,7]]},"742":{"position":[[194,6]]},"744":{"position":[[488,6]]},"752":{"position":[[150,11]]},"768":{"position":[[199,8]]},"796":{"position":[[925,6],[1031,6]]},"842":{"position":[[69,6]]},"850":{"position":[[476,6],[494,6],[6323,6],[6551,6],[7909,6],[8137,6],[8651,6]]},"853":{"position":[[205,7]]},"859":{"position":[[2338,8],[2956,6],[3017,6],[3081,6],[3184,6],[3522,6],[3637,6],[3737,6],[3852,6],[3952,6],[4013,6],[4077,6],[4180,6],[4518,6],[4633,6],[4733,6],[4848,6],[4948,6],[5012,6],[5112,6],[5176,6],[5514,6],[5614,6],[5729,6],[5844,6],[5935,6],[6017,6],[6099,6],[6181,6],[6263,6],[6345,6]]},"903":{"position":[[1927,6],[2750,6],[2775,6],[2909,6],[3293,6]]},"905":{"position":[[1771,6]]},"909":{"position":[[1924,7]]},"913":{"position":[[587,6],[1139,6],[1681,7],[1689,8],[1993,9]]},"932":{"position":[[487,8],[1602,7],[1687,7]]},"934":{"position":[[1619,6]]},"947":{"position":[[122,6]]},"956":{"position":[[374,8],[486,8],[679,7],[1383,8]]},"977":{"position":[[59,6],[598,7],[1370,7]]},"1023":{"position":[[78,7]]},"1067":{"position":[[410,7],[422,7],[4598,7],[4627,6],[5580,8],[5667,8]]},"1071":{"position":[[393,6],[441,6],[1087,7],[1108,6],[1203,7]]},"1118":{"position":[[1005,6]]},"1209":{"position":[[75,7]]},"1226":{"position":[[1247,6],[1639,6],[1804,6],[1834,6],[1923,7],[2117,6]]},"1234":{"position":[[310,6],[475,7],[2932,6]]},"1240":{"position":[[345,6]]},"1252":{"position":[[976,6]]},"1321":{"position":[[2012,6]]},"1368":{"position":[[1619,6],[1950,8],[2295,6],[2629,8]]},"1371":{"position":[[27,6]]},"1373":{"position":[[4,6],[43,6],[157,6],[164,7],[199,6],[211,7]]},"1484":{"position":[[476,6],[494,6],[6323,6],[6551,6],[7909,6],[8137,6],[8651,6]]},"1533":{"position":[[925,6],[1031,6]]},"1557":{"position":[[69,6]]},"1569":{"position":[[1680,6]]},"1571":{"position":[[1624,6]]},"1578":{"position":[[340,6],[386,7]]},"1597":{"position":[[205,7]]},"1603":{"position":[[2338,8],[2956,6],[3017,6],[3081,6],[3184,6],[3522,6],[3637,6],[3737,6],[3852,6],[3952,6],[4013,6],[4077,6],[4180,6],[4518,6],[4633,6],[4733,6],[4848,6],[4948,6],[5012,6],[5112,6],[5176,6],[5514,6],[5614,6],[5729,6],[5844,6],[5935,6],[6017,6],[6099,6],[6181,6],[6263,6],[6345,6]]},"1625":{"position":[[1927,6],[2750,6],[2775,6],[2909,6],[3293,6]]},"1627":{"position":[[1771,6]]},"1631":{"position":[[1924,7]]},"1635":{"position":[[587,6],[1139,6],[1681,7],[1689,8],[1993,9]]},"1654":{"position":[[487,8],[1602,7],[1687,7]]},"1656":{"position":[[1619,6]]},"1669":{"position":[[122,6]]},"1731":{"position":[[1529,6],[1597,6]]},"1734":{"position":[[255,6]]},"1743":{"position":[[9,6],[33,6],[466,7],[547,6],[1418,6],[1843,6]]},"1749":{"position":[[1161,7],[1279,6]]},"1756":{"position":[[32,6]]},"1783":{"position":[[288,7]]},"1791":{"position":[[1128,6]]},"1833":{"position":[[1026,7]]},"1841":{"position":[[360,6]]},"1845":{"position":[[68,6],[157,6],[1443,7],[1615,7],[2323,6],[2512,6]]},"1847":{"position":[[10,6],[696,6],[964,6]]},"1849":{"position":[[661,6]]},"1865":{"position":[[428,6],[619,6],[757,6]]},"1870":{"position":[[158,6]]},"1872":{"position":[[44,6]]},"1880":{"position":[[78,6],[644,6]]},"1911":{"position":[[58,6]]},"1927":{"position":[[428,6],[619,6],[757,6]]},"1986":{"position":[[158,6]]},"1988":{"position":[[44,6]]},"1996":{"position":[[78,6],[644,6]]},"2027":{"position":[[58,6]]},"2063":{"position":[[431,9]]},"2077":{"position":[[56,6],[153,8],[231,7]]},"2096":{"position":[[1159,6]]},"2100":{"position":[[966,9]]},"2162":{"position":[[741,6]]},"2164":{"position":[[537,6]]},"2319":{"position":[[237,7]]},"2350":{"position":[[1927,6],[2750,6],[2775,6],[2909,6],[3293,6]]},"2352":{"position":[[1771,6]]},"2356":{"position":[[1924,7]]},"2360":{"position":[[587,6],[1139,6],[1681,7],[1689,8],[1993,9]]},"2379":{"position":[[487,8],[1602,7],[1687,7]]},"2381":{"position":[[1619,6]]},"2394":{"position":[[122,6]]},"2711":{"position":[[1130,6],[1476,6]]},"2856":{"position":[[1107,6],[1454,6]]},"2890":{"position":[[131,6]]},"2933":{"position":[[659,6],[1007,6]]},"2949":{"position":[[226,7]]},"3003":{"position":[[625,7],[713,7]]},"3234":{"position":[[355,7],[557,6]]},"3236":{"position":[[554,6],[582,6],[2726,6]]},"3270":{"position":[[74,6],[299,7],[468,6],[501,6],[603,7],[652,7],[907,7],[1239,6],[1343,7],[1675,6],[1838,6],[2007,7]]},"3276":{"position":[[1382,6]]},"3280":{"position":[[62,6],[109,6],[885,6]]},"3316":{"position":[[720,6]]},"3361":{"position":[[453,6]]},"3363":{"position":[[305,7]]},"3367":{"position":[[107,6]]},"3397":{"position":[[1237,6]]},"3408":{"position":[[47,6],[102,7]]}}}],["server'",{"_index":6377,"t":{"1319":{"position":[[471,8]]}}}],["server.crt",{"_index":7395,"t":{"1745":{"position":[[1123,11]]}}}],["server/ml2_conf.ini",{"_index":6693,"t":{"1368":{"position":[[133,19],[249,21],[361,21]]}}}],["server:3.1.2.20230919",{"_index":6610,"t":{"1360":{"position":[[2551,21]]}}}],["server:8000/playbooks/49.html",{"_index":6260,"t":{"1317":{"position":[[1617,29],[5725,29],[8879,29]]}}}],["server:latest",{"_index":7326,"t":{"1731":{"position":[[1556,13]]}}}],["server_group",{"_index":3892,"t":{"821":{"position":[[2673,16],[3993,16],[5325,16]]},"1511":{"position":[[2673,16],[3993,16],[5325,16]]}}}],["server_group_memb",{"_index":3891,"t":{"821":{"position":[[2646,23],[3964,23],[5298,23]]},"1511":{"position":[[2646,23],[3964,23],[5298,23]]}}}],["server_nam",{"_index":7917,"t":{"1865":{"position":[[518,12],[645,12],[786,12]]},"1927":{"position":[[518,12],[645,12],[786,12]]}}}],["server_name_or_id",{"_index":7930,"t":{"1880":{"position":[[683,18]]},"1996":{"position":[[683,18]]}}}],["serverless",{"_index":2139,"t":{"331":{"position":[[247,10]]},"337":{"position":[[215,10]]}}}],["serverless/funct",{"_index":2158,"t":{"337":{"position":[[145,20]]}}}],["servernam",{"_index":6379,"t":{"1319":{"position":[[538,12]]}}}],["servers=$(openstack",{"_index":4458,"t":{"913":{"position":[[1119,19]]},"1635":{"position":[[1119,19]]},"2360":{"position":[[1119,19]]}}}],["servertlsbootstrap",{"_index":10037,"t":{"3276":{"position":[[1105,19]]}}}],["servi",{"_index":5823,"t":{"1165":{"position":[[1061,7]]}}}],["servic",{"_index":240,"t":{"23":{"position":[[42,8]]},"25":{"position":[[0,7],[159,7],[323,7],[467,7],[604,7],[729,7],[851,7]]},"30":{"position":[[18,7],[162,7]]},"34":{"position":[[52,8]]},"37":{"position":[[51,9]]},"40":{"position":[[55,9]]},"71":{"position":[[440,9]]},"79":{"position":[[564,7]]},"101":{"position":[[549,7]]},"139":{"position":[[598,7]]},"166":{"position":[[81,7]]},"168":{"position":[[236,7]]},"172":{"position":[[398,7],[796,9]]},"174":{"position":[[859,8],[1598,9]]},"284":{"position":[[1419,8]]},"290":{"position":[[459,8]]},"292":{"position":[[30,7]]},"294":{"position":[[26,7]]},"300":{"position":[[30,7],[232,7]]},"302":{"position":[[999,8]]},"325":{"position":[[2379,8]]},"327":{"position":[[307,8],[434,8],[643,9],[737,8]]},"329":{"position":[[180,7],[206,7],[330,8]]},"331":{"position":[[65,7],[287,8]]},"335":{"position":[[817,8],[1004,9]]},"337":{"position":[[171,7],[256,7]]},"339":{"position":[[91,7]]},"347":{"position":[[403,9]]},"366":{"position":[[415,9],[571,8],[758,8],[1013,8]]},"368":{"position":[[352,9]]},"398":{"position":[[291,7]]},"428":{"position":[[1661,8]]},"434":{"position":[[122,8]]},"454":{"position":[[13,8]]},"458":{"position":[[34,7]]},"460":{"position":[[625,7]]},"462":{"position":[[1353,8],[1553,8]]},"467":{"position":[[524,7]]},"487":{"position":[[353,8],[3932,8],[4095,7]]},"503":{"position":[[179,7]]},"505":{"position":[[225,7],[470,7],[850,7],[933,7],[1310,7]]},"507":{"position":[[43,8]]},"509":{"position":[[165,7]]},"511":{"position":[[118,8]]},"513":{"position":[[133,8],[233,8],[450,7],[976,7]]},"596":{"position":[[284,7]]},"627":{"position":[[3007,8]]},"631":{"position":[[695,8]]},"641":{"position":[[1326,7],[1506,7]]},"646":{"position":[[355,7]]},"652":{"position":[[781,9]]},"660":{"position":[[1710,9]]},"692":{"position":[[102,7]]},"710":{"position":[[36,8]]},"712":{"position":[[99,9]]},"714":{"position":[[30,8]]},"716":{"position":[[125,7]]},"718":{"position":[[88,7]]},"738":{"position":[[114,9]]},"744":{"position":[[538,9],[563,9],[649,8],[747,8]]},"746":{"position":[[252,9]]},"748":{"position":[[35,8],[50,7],[211,8],[380,9]]},"750":{"position":[[157,7],[237,8],[458,9]]},"752":{"position":[[98,8]]},"756":{"position":[[140,7]]},"760":{"position":[[15,8],[132,8],[153,8],[252,8]]},"764":{"position":[[20,8],[54,7]]},"766":{"position":[[33,7],[127,8]]},"772":{"position":[[64,7]]},"786":{"position":[[20,7],[107,9]]},"800":{"position":[[488,7]]},"813":{"position":[[236,7],[491,7]]},"819":{"position":[[589,7],[845,7],[1311,7],[2334,7],[2354,7],[2876,7],[2913,7],[3651,7],[3693,7],[3988,7],[7943,8],[8002,9],[8180,7],[8432,7]]},"821":{"position":[[3399,7],[3448,8],[3502,7],[3603,7],[3750,7],[4387,7],[4462,7],[4537,7],[4611,7],[4721,7],[4740,7],[4789,8],[6057,7],[6106,8]]},"865":{"position":[[20,7],[107,7],[228,7],[273,7]]},"878":{"position":[[20,7],[107,7],[228,7],[273,7]]},"883":{"position":[[16,7],[42,7],[2099,7]]},"888":{"position":[[16,7],[2271,8]]},"907":{"position":[[539,7]]},"909":{"position":[[992,7]]},"913":{"position":[[4081,7]]},"920":{"position":[[173,7]]},"922":{"position":[[926,7]]},"926":{"position":[[616,7]]},"932":{"position":[[1562,8]]},"934":{"position":[[1508,9]]},"938":{"position":[[345,8]]},"947":{"position":[[390,7]]},"949":{"position":[[899,8]]},"954":{"position":[[638,8]]},"956":{"position":[[59,7],[773,9],[865,9],[1893,8]]},"982":{"position":[[71,8],[96,8],[582,8]]},"984":{"position":[[85,9],[103,8]]},"986":{"position":[[43,9],[120,8]]},"988":{"position":[[43,9]]},"990":{"position":[[122,9],[195,9],[351,8]]},"1025":{"position":[[63,8],[140,8],[175,8]]},"1027":{"position":[[232,9]]},"1029":{"position":[[225,9]]},"1055":{"position":[[153,7],[1115,9],[3617,7],[3791,7]]},"1061":{"position":[[278,7]]},"1067":{"position":[[977,7],[1348,7],[3291,8],[3938,7]]},"1082":{"position":[[91,8]]},"1084":{"position":[[17,7]]},"1108":{"position":[[499,9],[538,9],[1615,7],[1946,7],[2036,8]]},"1120":{"position":[[104,7],[2057,8]]},"1122":{"position":[[40,8]]},"1124":{"position":[[78,8]]},"1150":{"position":[[423,7]]},"1156":{"position":[[77,7],[110,8],[302,8],[409,8]]},"1159":{"position":[[55,8]]},"1161":{"position":[[220,8],[270,8],[1527,8],[1562,8],[3943,8]]},"1165":{"position":[[564,8],[981,7],[1005,8],[1029,7],[1237,8],[2059,8],[2133,9],[2165,8],[3248,9],[3428,9]]},"1167":{"position":[[43,7],[161,7],[249,7],[306,7],[883,7],[2380,7],[2438,7],[2659,7],[2760,8],[3380,7],[3638,7],[4583,7]]},"1169":{"position":[[46,8],[435,9],[700,8]]},"1178":{"position":[[95,8]]},"1199":{"position":[[192,7],[510,8]]},"1209":{"position":[[138,7]]},"1213":{"position":[[583,7],[684,7]]},"1219":{"position":[[470,8]]},"1224":{"position":[[4086,9]]},"1242":{"position":[[44,8],[207,8],[405,8]]},"1244":{"position":[[39,8],[214,8]]},"1248":{"position":[[177,9]]},"1250":{"position":[[50,8]]},"1252":{"position":[[580,8],[667,8]]},"1256":{"position":[[59,7]]},"1258":{"position":[[698,8]]},"1262":{"position":[[81,8],[141,7],[199,8],[258,7],[316,8]]},"1275":{"position":[[19,7]]},"1279":{"position":[[133,8]]},"1286":{"position":[[918,9],[944,8],[991,8],[1038,8],[1183,8],[1382,9]]},"1288":{"position":[[27,7],[65,7],[326,7],[371,7],[423,9],[651,7]]},"1290":{"position":[[46,8],[108,7],[234,8],[293,9]]},"1292":{"position":[[48,7],[208,8],[357,8],[534,8]]},"1294":{"position":[[39,8],[263,8],[434,8]]},"1315":{"position":[[13,7],[101,7]]},"1317":{"position":[[4399,8],[4494,7],[4647,7],[4808,7]]},"1344":{"position":[[267,7],[392,7],[471,7],[516,8]]},"1347":{"position":[[36,7],[1053,7],[1103,7],[1206,7],[1256,7],[1359,7],[1409,7],[1505,7]]},"1358":{"position":[[313,7],[356,7],[429,7],[472,7],[499,7]]},"1360":{"position":[[160,7],[218,7],[355,8],[523,8],[574,8],[640,7],[1100,8]]},"1362":{"position":[[456,8],[656,7],[701,7],[1320,7],[1399,8],[1567,8]]},"1366":{"position":[[160,7]]},"1375":{"position":[[35,7],[146,7],[1046,7],[1130,7]]},"1377":{"position":[[65,7],[147,7],[1071,7],[1151,7]]},"1386":{"position":[[346,8]]},"1469":{"position":[[97,9]]},"1471":{"position":[[548,8],[1020,8],[1280,8],[1540,8],[1909,8]]},"1473":{"position":[[309,8],[436,8],[661,8],[1425,8],[1675,8]]},"1477":{"position":[[305,8]]},"1503":{"position":[[236,7],[491,7]]},"1509":{"position":[[589,7],[845,7],[1311,7],[2334,7],[2354,7],[2876,7],[2913,7],[3651,7],[3693,7],[3988,7],[7943,8],[8002,9],[8180,7],[8432,7]]},"1511":{"position":[[3399,7],[3448,8],[3502,7],[3603,7],[3750,7],[4387,7],[4462,7],[4537,7],[4611,7],[4721,7],[4740,7],[4789,8],[6057,7],[6106,8]]},"1523":{"position":[[20,7],[107,9]]},"1537":{"position":[[488,7]]},"1560":{"position":[[101,8]]},"1564":{"position":[[415,8]]},"1571":{"position":[[946,8],[1274,8]]},"1576":{"position":[[26,8]]},"1608":{"position":[[25,7]]},"1629":{"position":[[539,7]]},"1631":{"position":[[992,7]]},"1635":{"position":[[4081,7]]},"1642":{"position":[[173,7]]},"1644":{"position":[[926,7]]},"1648":{"position":[[616,7]]},"1654":{"position":[[1562,8]]},"1656":{"position":[[1508,9]]},"1660":{"position":[[345,8]]},"1669":{"position":[[390,7]]},"1671":{"position":[[899,8]]},"1674":{"position":[[831,8]]},"1676":{"position":[[182,8]]},"1690":{"position":[[1119,9],[1712,8],[1810,8],[2037,8],[2081,8]]},"1697":{"position":[[599,7]]},"1728":{"position":[[1578,7]]},"1731":{"position":[[54,8],[166,8],[192,7],[334,7],[534,8],[646,7],[924,7],[1024,7],[1085,7],[1425,7],[1709,7],[1953,7],[2240,7],[2907,7],[3234,7]]},"1736":{"position":[[261,8]]},"1738":{"position":[[28,7],[51,7]]},"1764":{"position":[[3604,7],[4148,7],[4452,8]]},"1766":{"position":[[27,7],[159,9],[339,7],[1015,7],[1081,7],[1140,7],[1300,7],[1722,7]]},"1768":{"position":[[266,8],[454,8]]},"1770":{"position":[[220,7],[385,7],[455,8]]},"1779":{"position":[[3585,9],[3640,8],[3683,8],[3925,8],[4754,8],[4825,8],[4891,8],[5183,8],[5334,8],[5578,8],[6002,7]]},"1785":{"position":[[395,9]]},"1789":{"position":[[16,8],[217,8]]},"1794":{"position":[[816,7],[940,7],[966,9],[1058,7]]},"1796":{"position":[[247,7]]},"1798":{"position":[[176,8],[247,8],[318,8],[387,8],[453,8],[522,8],[592,8]]},"1800":{"position":[[129,8],[196,8],[263,8],[333,8],[404,8]]},"1814":{"position":[[14,8]]},"1816":{"position":[[402,8],[441,9],[473,9]]},"1822":{"position":[[42,9],[110,9]]},"1825":{"position":[[209,7],[2154,7]]},"1855":{"position":[[532,8]]},"1872":{"position":[[254,8],[407,8],[792,8]]},"1878":{"position":[[112,7],[213,7]]},"1882":{"position":[[325,7]]},"1908":{"position":[[18,7],[115,8],[200,7],[918,7]]},"1917":{"position":[[532,8]]},"1937":{"position":[[489,8]]},"1955":{"position":[[242,7]]},"1970":{"position":[[174,7],[209,7],[244,7]]},"1972":{"position":[[61,7],[449,9]]},"1982":{"position":[[182,8]]},"1988":{"position":[[254,8],[407,8],[792,8]]},"1994":{"position":[[112,7],[213,7]]},"1998":{"position":[[325,7]]},"2024":{"position":[[18,7],[115,8],[200,7],[918,7]]},"2037":{"position":[[316,7]]},"2043":{"position":[[176,8]]},"2051":{"position":[[279,7]]},"2067":{"position":[[1651,7],[1688,8]]},"2069":{"position":[[324,7],[361,8]]},"2108":{"position":[[278,8],[392,8]]},"2116":{"position":[[147,7],[1011,7]]},"2118":{"position":[[144,8],[291,7],[556,7],[864,7],[949,7],[1077,7],[1868,7],[2093,7],[2556,7]]},"2120":{"position":[[75,7],[133,7],[432,7]]},"2130":{"position":[[274,8],[388,8]]},"2154":{"position":[[964,9],[1032,10]]},"2158":{"position":[[427,8]]},"2162":{"position":[[0,7]]},"2190":{"position":[[237,8],[710,9]]},"2206":{"position":[[260,8]]},"2226":{"position":[[22,7]]},"2229":{"position":[[52,8],[353,7],[574,9]]},"2243":{"position":[[198,9]]},"2245":{"position":[[231,8]]},"2248":{"position":[[859,9],[1287,8]]},"2250":{"position":[[285,8]]},"2257":{"position":[[196,7]]},"2259":{"position":[[333,8]]},"2263":{"position":[[211,7]]},"2265":{"position":[[624,7]]},"2278":{"position":[[233,7]]},"2281":{"position":[[745,9],[768,8],[862,8],[1164,8]]},"2283":{"position":[[983,8],[1058,7]]},"2290":{"position":[[12,7]]},"2292":{"position":[[333,7],[522,8],[912,7]]},"2298":{"position":[[624,7]]},"2315":{"position":[[247,8]]},"2354":{"position":[[539,7]]},"2356":{"position":[[992,7]]},"2360":{"position":[[4081,7]]},"2367":{"position":[[173,7]]},"2369":{"position":[[926,7]]},"2373":{"position":[[616,7]]},"2379":{"position":[[1562,8]]},"2381":{"position":[[1508,9]]},"2385":{"position":[[345,8]]},"2394":{"position":[[390,7]]},"2396":{"position":[[899,8]]},"2405":{"position":[[1048,7]]},"2417":{"position":[[73,8]]},"2420":{"position":[[242,8]]},"2463":{"position":[[187,8]]},"2472":{"position":[[91,7]]},"2474":{"position":[[150,8]]},"2482":{"position":[[230,7]]},"2502":{"position":[[13,7]]},"2504":{"position":[[198,8]]},"2506":{"position":[[140,7]]},"2514":{"position":[[305,8]]},"2518":{"position":[[21,7]]},"2522":{"position":[[296,7],[327,7]]},"2544":{"position":[[124,7]]},"2566":{"position":[[340,8],[13195,8]]},"2574":{"position":[[331,9]]},"2576":{"position":[[179,8]]},"2586":{"position":[[103,7]]},"2592":{"position":[[59,7]]},"2602":{"position":[[332,8],[722,7]]},"2629":{"position":[[311,7],[368,7]]},"2684":{"position":[[125,8],[175,9],[219,7]]},"2731":{"position":[[536,7],[927,8]]},"2770":{"position":[[536,7],[927,8]]},"2795":{"position":[[488,7],[519,7],[910,7]]},"2860":{"position":[[498,7],[888,8]]},"2864":{"position":[[30,8]]},"2886":{"position":[[284,7]]},"2901":{"position":[[1916,7]]},"2911":{"position":[[105,7]]},"2953":{"position":[[79,8]]},"2960":{"position":[[73,7]]},"2966":{"position":[[3465,7]]},"3003":{"position":[[105,7],[591,7]]},"3021":{"position":[[260,8]]},"3023":{"position":[[366,7]]},"3039":{"position":[[352,7]]},"3150":{"position":[[42,7],[369,9]]},"3152":{"position":[[6,7]]},"3154":{"position":[[256,7]]},"3160":{"position":[[1426,7]]},"3182":{"position":[[1942,7]]},"3197":{"position":[[1015,8]]},"3204":{"position":[[214,7]]},"3218":{"position":[[435,9]]},"3224":{"position":[[242,7]]},"3236":{"position":[[442,7],[898,8],[907,7],[1409,7]]},"3245":{"position":[[117,8],[445,8],[1067,9],[1212,8]]},"3247":{"position":[[17,7],[182,8],[340,7],[588,7]]},"3249":{"position":[[13,7],[52,7],[132,8],[314,8],[323,7]]},"3251":{"position":[[1429,8],[1608,8],[2098,8],[2171,7],[2301,8],[2426,8],[2446,7],[2526,7],[4450,8],[4692,10]]},"3266":{"position":[[551,8]]},"3270":{"position":[[123,7],[205,7]]},"3293":{"position":[[42,7]]},"3295":{"position":[[6,7]]},"3301":{"position":[[5427,8]]},"3308":{"position":[[216,7]]},"3314":{"position":[[112,8]]},"3370":{"position":[[118,7]]},"3389":{"position":[[6,7],[196,8],[249,8],[262,7]]},"3391":{"position":[[348,7]]},"3393":{"position":[[100,8],[190,7]]},"3397":{"position":[[1427,8],[1846,8],[2013,7],[2064,7],[2253,7]]},"3400":{"position":[[100,8]]},"3413":{"position":[[80,7],[333,8]]},"3434":{"position":[[118,7],[444,7]]},"3440":{"position":[[84,7]]},"3453":{"position":[[104,7]]},"3455":{"position":[[563,7]]},"3457":{"position":[[133,7],[330,8],[552,7]]},"3459":{"position":[[521,7],[901,7]]},"3461":{"position":[[209,7]]},"3465":{"position":[[786,8]]},"3472":{"position":[[14281,7],[14616,7]]},"3477":{"position":[[96,9]]},"3482":{"position":[[1759,7],[2744,7],[3033,8]]},"3484":{"position":[[156,8]]},"3518":{"position":[[2565,7]]}}}],["service.sh",{"_index":7649,"t":{"1798":{"position":[[65,10]]}}}],["service.yaml",{"_index":8340,"t":{"2158":{"position":[[465,12]]}}}],["service/data",{"_index":9920,"t":{"3197":{"position":[[1148,12]]}}}],["service=registri",{"_index":2642,"t":{"472":{"position":[[2295,16]]}}}],["service_address",{"_index":4538,"t":{"926":{"position":[[520,15]]},"1648":{"position":[[520,15]]},"2373":{"position":[[520,15]]}}}],["service_cidr",{"_index":2729,"t":{"487":{"position":[[271,12],[284,12]]},"660":{"position":[[1732,19]]}}}],["service_id",{"_index":8914,"t":{"2566":{"position":[[11693,11]]}}}],["service_nam",{"_index":8277,"t":{"2142":{"position":[[294,15]]}}}],["service_name=rsysloc",{"_index":6134,"t":{"1275":{"position":[[32,20]]}}}],["service_network_cidr",{"_index":3835,"t":{"819":{"position":[[1332,21],[3672,20]]},"1509":{"position":[[1332,21],[3672,20]]}}}],["service_state=restart",{"_index":6135,"t":{"1275":{"position":[[58,23]]}}}],["serviceaccount",{"_index":8093,"t":{"2033":{"position":[[965,14],[1231,14],[1824,14],[1917,14]]}}}],["servicedomain",{"_index":3534,"t":{"660":{"position":[[1752,14]]}}}],["servicemonitor.scrapetimeout=1m",{"_index":8166,"t":{"2096":{"position":[[672,33],[1290,35]]}}}],["servicenam",{"_index":3967,"t":{"842":{"position":[[773,11]]},"1557":{"position":[[773,11]]}}}],["services.sh",{"_index":7549,"t":{"1779":{"position":[[4647,11],[4958,11],[5246,12]]},"1798":{"position":[[121,11],[664,11]]},"1800":{"position":[[63,11]]}}}],["services/deploy",{"_index":3293,"t":{"627":{"position":[[2791,20]]}}}],["services/molecule/delegated/tests/adminer.pi",{"_index":7218,"t":{"1721":{"position":[[392,44]]}}}],["services/molecule/delegated/tests/auditd.pi",{"_index":7222,"t":{"1721":{"position":[[699,43]]}}}],["services/molecule/delegated/tests/bird.pi",{"_index":7220,"t":{"1721":{"position":[[547,41]]}}}],["services/molecule/delegated/tests/cephclient/container.pi",{"_index":7226,"t":{"1721":{"position":[[1019,57]]}}}],["services/molecule/delegated/tests/cephclient/package.pi",{"_index":7224,"t":{"1721":{"position":[[853,55]]}}}],["services/molecule/delegated/tests/cgit.pi",{"_index":7228,"t":{"1721":{"position":[[1187,41]]}}}],["services/molecule/delegated/tests/dnsdist.pi",{"_index":7230,"t":{"1721":{"position":[[1339,44]]}}}],["services/molecule/delegated/tests/docker.pi",{"_index":7238,"t":{"1721":{"position":[[1962,43]]}}}],["services/molecule/delegated/tests/hddtemp/redhat.pi",{"_index":7232,"t":{"1721":{"position":[[1494,51]]}}}],["services/molecule/delegated/tests/homer.pi",{"_index":7234,"t":{"1721":{"position":[[1656,42]]}}}],["services/molecule/delegated/tests/lldpd.pi",{"_index":7236,"t":{"1721":{"position":[[1809,42]]}}}],["services/molecule/delegated/tests/osquery.pi",{"_index":7240,"t":{"1721":{"position":[[2116,44]]}}}],["services/molecule/delegated/tests/rsyslog.pi",{"_index":7242,"t":{"1721":{"position":[[2271,44]]}}}],["services/molecule/delegated/tests/smartd.pi",{"_index":7244,"t":{"1721":{"position":[[2426,43]]}}}],["services/molecule/delegated/tests/tuned.pi",{"_index":7246,"t":{"1721":{"position":[[2580,42]]}}}],["services/molecule/delegated/tests/util/util.pi",{"_index":7248,"t":{"1721":{"position":[[2733,46]]}}}],["services/plugins/filter/address.pi",{"_index":7252,"t":{"1721":{"position":[[3050,34]]}}}],["services/plugins/modules/kolla_container_facts.pi",{"_index":7250,"t":{"1721":{"position":[[2890,49]]}}}],["services/plugins/modules/kolla_docker.pi",{"_index":7256,"t":{"1721":{"position":[[3347,40]]}}}],["services/plugins/modules/kolla_toolbox.pi",{"_index":7254,"t":{"1721":{"position":[[3195,41]]}}}],["services/pod",{"_index":8202,"t":{"2106":{"position":[[215,14]]}}}],["services/pull/578/fil",{"_index":7134,"t":{"1608":{"position":[[340,23]]}}}],["services_requir",{"_index":4779,"t":{"1027":{"position":[[62,18],[146,17]]}}}],["services_required_default",{"_index":4777,"t":{"1027":{"position":[[0,26],[85,25]]}}}],["services_required_extra",{"_index":4778,"t":{"1027":{"position":[[34,24],[113,23],[195,23]]}}}],["services_warn",{"_index":4784,"t":{"1029":{"position":[[60,17],[141,16]]}}}],["services_warning_default",{"_index":4781,"t":{"1029":{"position":[[0,25],[82,24]]}}}],["services_warning_extra",{"_index":4783,"t":{"1029":{"position":[[33,23],[109,22],[189,22]]}}}],["services|commons|valid",{"_index":7200,"t":{"1690":{"position":[[1042,30]]}}}],["session",{"_index":298,"t":{"27":{"position":[[210,7],[247,7]]},"67":{"position":[[47,8]]},"304":{"position":[[151,7]]},"447":{"position":[[40,7]]},"472":{"position":[[725,8]]},"909":{"position":[[238,7],[627,8]]},"915":{"position":[[1230,8]]},"945":{"position":[[178,7]]},"947":{"position":[[177,8]]},"1582":{"position":[[51,8]]},"1631":{"position":[[238,7],[627,8]]},"1637":{"position":[[1230,8]]},"1667":{"position":[[178,7]]},"1669":{"position":[[177,8]]},"1779":{"position":[[3902,8]]},"1791":{"position":[[1163,7]]},"2356":{"position":[[238,7],[627,8]]},"2362":{"position":[[1230,8]]},"2392":{"position":[[178,7]]},"2394":{"position":[[177,8]]},"3249":{"position":[[964,7]]}}}],["set",{"_index":172,"t":{"10":{"position":[[1782,7]]},"12":{"position":[[176,3]]},"23":{"position":[[491,3]]},"25":{"position":[[49,3]]},"114":{"position":[[543,3]]},"139":{"position":[[29,3],[59,3]]},"147":{"position":[[101,4]]},"184":{"position":[[515,8],[638,3]]},"191":{"position":[[184,3],[449,3]]},"193":{"position":[[745,3]]},"210":{"position":[[806,3]]},"223":{"position":[[258,3]]},"249":{"position":[[287,4]]},"253":{"position":[[2029,3]]},"319":{"position":[[345,3],[413,3],[427,3],[515,3]]},"325":{"position":[[558,4],[3010,3],[3139,3],[3298,3]]},"347":{"position":[[241,3]]},"366":{"position":[[306,3]]},"379":{"position":[[42,3]]},"393":{"position":[[549,3]]},"396":{"position":[[254,3]]},"398":{"position":[[340,3]]},"427":{"position":[[1236,3]]},"428":{"position":[[273,3],[1889,3]]},"430":{"position":[[28,3]]},"436":{"position":[[49,3],[493,3],[1230,3]]},"444":{"position":[[173,8]]},"447":{"position":[[138,8],[454,8]]},"449":{"position":[[239,8],[573,8]]},"451":{"position":[[61,8],[253,8]]},"456":{"position":[[74,8],[272,8]]},"458":{"position":[[142,8],[339,8]]},"462":{"position":[[1336,3]]},"467":{"position":[[413,3]]},"471":{"position":[[220,4]]},"472":{"position":[[1675,3]]},"474":{"position":[[0,3]]},"481":{"position":[[36,7],[141,7]]},"485":{"position":[[824,3],[890,7],[916,3],[1085,7],[1145,3],[1154,7],[1194,4],[1285,3],[1487,7],[1557,3]]},"487":{"position":[[440,3],[611,4],[3189,7],[3612,8],[4530,7],[4767,3],[5568,8]]},"489":{"position":[[180,3]]},"501":{"position":[[1020,7]]},"503":{"position":[[0,7],[118,7],[370,7]]},"505":{"position":[[697,7]]},"509":{"position":[[530,7],[730,9],[821,8]]},"513":{"position":[[1667,3],[2130,8]]},"519":{"position":[[322,4],[434,3]]},"521":{"position":[[2,3],[104,3]]},"525":{"position":[[114,8]]},"527":{"position":[[103,3]]},"530":{"position":[[1021,3]]},"534":{"position":[[79,3]]},"540":{"position":[[148,7]]},"542":{"position":[[175,7]]},"574":{"position":[[74,4]]},"604":{"position":[[4904,8],[5436,3],[5497,3]]},"619":{"position":[[43,3]]},"627":{"position":[[817,10],[905,8],[1040,8]]},"633":{"position":[[1294,3],[1552,3],[2741,3]]},"637":{"position":[[100,3]]},"639":{"position":[[234,3],[353,3]]},"641":{"position":[[348,8]]},"644":{"position":[[27,3],[61,3],[808,3]]},"646":{"position":[[89,3],[251,4],[828,3],[1023,8],[1195,3]]},"648":{"position":[[793,7]]},"650":{"position":[[341,7],[1072,7]]},"667":{"position":[[545,8]]},"669":{"position":[[152,7],[983,5]]},"732":{"position":[[114,3]]},"770":{"position":[[299,3]]},"786":{"position":[[200,3]]},"792":{"position":[[50,9]]},"794":{"position":[[109,3],[155,3]]},"796":{"position":[[190,4]]},"798":{"position":[[251,4]]},"800":{"position":[[523,3],[559,3],[595,3],[629,3]]},"815":{"position":[[372,3]]},"819":{"position":[[1596,3],[1697,3],[1857,3],[2057,3],[5656,3],[5712,3],[5804,4],[5884,3],[5950,3],[6014,3],[6184,3],[6350,3],[6519,3],[6724,3],[6780,4]]},"821":{"position":[[190,3],[1048,3],[1149,3],[1309,3],[1509,3]]},"823":{"position":[[105,3]]},"846":{"position":[[133,3]]},"859":{"position":[[1112,3],[1214,3],[1375,3],[1575,3],[6569,3],[6670,3],[6830,3]]},"861":{"position":[[89,3]]},"895":{"position":[[299,7],[1154,3],[1312,4],[1607,3],[2296,3]]},"903":{"position":[[256,3],[642,3]]},"913":{"position":[[331,8],[452,8],[541,3],[2477,3],[3501,3]]},"920":{"position":[[1067,7]]},"922":{"position":[[765,3]]},"932":{"position":[[467,3],[550,3],[954,3],[1196,3],[2073,3],[2147,3],[2411,8],[3002,7]]},"934":{"position":[[1198,3],[1257,3]]},"936":{"position":[[41,3]]},"942":{"position":[[188,8]]},"949":{"position":[[502,3],[690,3]]},"956":{"position":[[571,9],[1204,3]]},"977":{"position":[[2564,4]]},"1017":{"position":[[304,3],[465,3]]},"1021":{"position":[[98,3]]},"1031":{"position":[[139,3],[726,3],[800,3]]},"1043":{"position":[[328,3]]},"1063":{"position":[[624,3],[726,3],[774,3]]},"1069":{"position":[[116,3],[218,3],[266,3]]},"1071":{"position":[[952,3],[1118,3]]},"1080":{"position":[[230,3],[465,3],[566,4]]},"1082":{"position":[[250,4]]},"1084":{"position":[[140,7],[287,3]]},"1089":{"position":[[83,3],[468,3],[1704,3]]},"1091":{"position":[[239,3]]},"1094":{"position":[[182,3],[216,3]]},"1096":{"position":[[70,3]]},"1102":{"position":[[77,3]]},"1106":{"position":[[18,3]]},"1108":{"position":[[1066,4],[1688,3]]},"1112":{"position":[[636,3],[698,3],[1541,3],[1638,3]]},"1114":{"position":[[1862,3]]},"1116":{"position":[[53,3],[213,3]]},"1118":{"position":[[645,3]]},"1120":{"position":[[1108,3]]},"1122":{"position":[[56,3]]},"1124":{"position":[[94,3]]},"1144":{"position":[[36,3]]},"1156":{"position":[[216,3]]},"1161":{"position":[[1780,3]]},"1165":{"position":[[1116,7],[1179,3],[2666,7],[3035,3]]},"1167":{"position":[[927,3],[979,3],[2454,3],[4094,3]]},"1169":{"position":[[306,3],[597,3],[808,3]]},"1184":{"position":[[1330,3],[1457,3]]},"1205":{"position":[[6,8]]},"1213":{"position":[[649,3]]},"1217":{"position":[[620,3],[708,3]]},"1224":{"position":[[999,3],[2362,3]]},"1226":{"position":[[184,3]]},"1234":{"position":[[868,3],[956,3],[997,3],[1249,3],[2325,3]]},"1244":{"position":[[184,7]]},"1256":{"position":[[323,3],[672,3],[828,3],[898,3],[1536,4],[1849,4],[2085,3],[2488,8],[2746,8],[2975,4]]},"1258":{"position":[[225,4],[365,4]]},"1260":{"position":[[237,4],[342,4]]},"1264":{"position":[[139,3]]},"1269":{"position":[[6,3]]},"1271":{"position":[[6,3]]},"1284":{"position":[[180,3],[244,3],[394,3],[445,3]]},"1317":{"position":[[253,3]]},"1319":{"position":[[530,3]]},"1351":{"position":[[2082,3]]},"1358":{"position":[[364,3]]},"1375":{"position":[[43,3],[1054,3]]},"1377":{"position":[[73,3],[1079,3]]},"1404":{"position":[[11,3],[34,3],[163,7]]},"1406":{"position":[[40,7],[167,3],[283,3],[599,3]]},"1419":{"position":[[280,3],[409,3]]},"1434":{"position":[[53,3],[79,3],[105,3]]},"1460":{"position":[[234,7]]},"1462":{"position":[[562,3],[796,3]]},"1466":{"position":[[16,3]]},"1471":{"position":[[363,7],[388,3],[409,3],[435,3],[460,3],[487,3],[509,3]]},"1480":{"position":[[133,3]]},"1493":{"position":[[114,3]]},"1505":{"position":[[372,3]]},"1509":{"position":[[1596,3],[1697,3],[1857,3],[2057,3],[5656,3],[5712,3],[5804,4],[5884,3],[5950,3],[6014,3],[6184,3],[6350,3],[6519,3],[6724,3],[6780,4]]},"1511":{"position":[[190,3],[1048,3],[1149,3],[1309,3],[1509,3]]},"1513":{"position":[[105,3]]},"1523":{"position":[[200,3]]},"1529":{"position":[[50,9]]},"1531":{"position":[[109,3],[155,3]]},"1533":{"position":[[190,4]]},"1535":{"position":[[251,4]]},"1537":{"position":[[523,3],[559,3],[595,3],[629,3]]},"1578":{"position":[[140,3]]},"1585":{"position":[[1419,3],[1511,8],[3702,4]]},"1591":{"position":[[826,7]]},"1603":{"position":[[1112,3],[1214,3],[1375,3],[1575,3],[6569,3],[6670,3],[6830,3]]},"1605":{"position":[[89,3]]},"1617":{"position":[[299,7],[1154,3],[1312,4],[1607,3],[2296,3]]},"1625":{"position":[[256,3],[642,3]]},"1635":{"position":[[331,8],[452,8],[541,3],[2477,3],[3501,3]]},"1642":{"position":[[1067,7]]},"1644":{"position":[[765,3]]},"1654":{"position":[[467,3],[550,3],[954,3],[1196,3],[2073,3],[2147,3],[2411,8],[3002,7]]},"1656":{"position":[[1198,3],[1257,3]]},"1658":{"position":[[41,3]]},"1664":{"position":[[188,8]]},"1671":{"position":[[502,3],[690,3]]},"1678":{"position":[[2215,3],[2635,3]]},"1686":{"position":[[150,3]]},"1697":{"position":[[29,3],[59,3]]},"1701":{"position":[[99,4]]},"1738":{"position":[[340,3]]},"1743":{"position":[[0,3],[225,3]]},"1747":{"position":[[89,3]]},"1749":{"position":[[41,3]]},"1754":{"position":[[24,3],[123,3]]},"1764":{"position":[[3811,3]]},"1766":{"position":[[530,3],[1401,3],[1439,3],[1598,3],[1784,3],[1818,3]]},"1779":{"position":[[709,8],[870,8],[983,8]]},"1791":{"position":[[888,8],[1275,8],[1295,9]]},"1794":{"position":[[679,3]]},"1796":{"position":[[93,3],[171,3]]},"1805":{"position":[[156,7]]},"1820":{"position":[[191,3],[255,3],[405,3],[456,3]]},"1825":{"position":[[375,3],[613,3],[714,4],[2730,3]]},"1841":{"position":[[177,8]]},"1853":{"position":[[111,4]]},"1855":{"position":[[262,8]]},"1859":{"position":[[85,3]]},"1863":{"position":[[243,3]]},"1904":{"position":[[715,3]]},"1915":{"position":[[111,4]]},"1917":{"position":[[262,8]]},"1921":{"position":[[85,3]]},"1925":{"position":[[243,3]]},"1957":{"position":[[2539,8],[2882,8],[3137,3]]},"1959":{"position":[[893,3],[969,4]]},"1972":{"position":[[535,3]]},"1982":{"position":[[627,7]]},"1984":{"position":[[237,7]]},"2020":{"position":[[715,3]]},"2037":{"position":[[171,3]]},"2047":{"position":[[215,3],[324,3]]},"2061":{"position":[[202,4]]},"2063":{"position":[[217,4]]},"2065":{"position":[[207,4]]},"2067":{"position":[[151,3]]},"2071":{"position":[[445,8]]},"2096":{"position":[[378,3],[639,3],[668,3],[828,3],[1286,3]]},"2106":{"position":[[771,3],[1051,3],[1112,3],[1174,3],[1248,3]]},"2110":{"position":[[3,3],[463,3]]},"2126":{"position":[[218,3]]},"2146":{"position":[[45,3]]},"2150":{"position":[[437,7],[737,3]]},"2152":{"position":[[377,3],[406,7],[555,3]]},"2196":{"position":[[1006,3]]},"2212":{"position":[[304,3],[544,3]]},"2217":{"position":[[165,3]]},"2224":{"position":[[137,8]]},"2245":{"position":[[355,8]]},"2248":{"position":[[94,8],[125,4],[150,8]]},"2253":{"position":[[19,8]]},"2310":{"position":[[41,3]]},"2334":{"position":[[368,3]]},"2342":{"position":[[299,7],[1154,3],[1312,4],[1607,3],[2296,3]]},"2350":{"position":[[256,3],[642,3]]},"2360":{"position":[[331,8],[452,8],[541,3],[2477,3],[3501,3]]},"2367":{"position":[[1067,7]]},"2369":{"position":[[765,3]]},"2379":{"position":[[467,3],[550,3],[954,3],[1196,3],[2073,3],[2147,3],[2411,8],[3002,7]]},"2381":{"position":[[1198,3],[1257,3]]},"2383":{"position":[[41,3]]},"2389":{"position":[[188,8]]},"2396":{"position":[[502,3],[690,3]]},"2400":{"position":[[71,3]]},"2426":{"position":[[20,3]]},"2456":{"position":[[71,3]]},"2497":{"position":[[383,3]]},"2514":{"position":[[77,3],[653,3]]},"2522":{"position":[[464,3]]},"2560":{"position":[[187,7]]},"2631":{"position":[[825,3],[890,3]]},"2637":{"position":[[117,7]]},"2673":{"position":[[1128,3],[1581,8]]},"2697":{"position":[[462,3]]},"2700":{"position":[[607,3]]},"2719":{"position":[[80,3],[994,3],[1533,3]]},"2745":{"position":[[607,3]]},"2758":{"position":[[80,3],[992,3],[1534,3]]},"2783":{"position":[[676,3],[735,4]]},"2795":{"position":[[854,3]]},"2815":{"position":[[394,3],[1159,3],[1261,3],[1400,3]]},"2832":{"position":[[462,3]]},"2879":{"position":[[255,4]]},"2892":{"position":[[384,7]]},"2895":{"position":[[3264,3],[3308,3]]},"2897":{"position":[[121,3]]},"2899":{"position":[[274,3],[665,3],[763,3]]},"2901":{"position":[[973,8],[1905,3]]},"2906":{"position":[[176,4]]},"2921":{"position":[[354,3]]},"2923":{"position":[[809,7]]},"2931":{"position":[[187,3],[437,3],[475,3]]},"2944":{"position":[[1040,3]]},"2947":{"position":[[2056,3],[4589,3],[4784,9],[5936,3]]},"2966":{"position":[[129,3]]},"3042":{"position":[[117,3]]},"3055":{"position":[[975,7]]},"3074":{"position":[[118,4]]},"3076":{"position":[[26,3]]},"3080":{"position":[[264,3],[693,3]]},"3082":{"position":[[531,3],[1520,3],[2120,4]]},"3092":{"position":[[253,3]]},"3097":{"position":[[40,4]]},"3099":{"position":[[17,3]]},"3103":{"position":[[239,3],[272,3],[709,3],[1555,3]]},"3111":{"position":[[110,3],[360,3]]},"3113":{"position":[[34,3]]},"3124":{"position":[[742,3]]},"3126":{"position":[[656,3]]},"3132":{"position":[[90,3]]},"3135":{"position":[[259,3]]},"3137":{"position":[[205,3]]},"3158":{"position":[[103,4]]},"3160":{"position":[[49,4],[304,3],[2547,3]]},"3162":{"position":[[196,3],[326,3]]},"3178":{"position":[[68,3]]},"3182":{"position":[[1525,4]]},"3184":{"position":[[677,3]]},"3191":{"position":[[68,3]]},"3197":{"position":[[1235,3]]},"3201":{"position":[[464,4]]},"3222":{"position":[[170,3]]},"3234":{"position":[[843,3]]},"3236":{"position":[[1756,3],[2427,3],[2537,3]]},"3251":{"position":[[1699,3],[2056,3],[4467,3],[6270,8]]},"3268":{"position":[[81,3]]},"3272":{"position":[[1013,3]]},"3276":{"position":[[188,3],[1101,3],[1260,7],[1449,3]]},"3280":{"position":[[255,3],[638,8]]},"3282":{"position":[[226,3]]},"3286":{"position":[[341,3]]},"3297":{"position":[[153,3],[245,3]]},"3301":{"position":[[1010,4],[3111,3],[3817,3],[4215,3],[5558,4]]},"3325":{"position":[[2865,3]]},"3357":{"position":[[1098,3]]},"3395":{"position":[[1512,3]]}}}],["set_configs.pi",{"_index":5903,"t":{"1167":{"position":[[3696,15]]}}}],["settin",{"_index":8007,"t":{"1957":{"position":[[1487,7]]}}}],["settings.yaml",{"_index":2324,"t":{"393":{"position":[[463,13],[512,13]]}}}],["settings.yaml.exampl",{"_index":2323,"t":{"393":{"position":[[394,21],[485,21]]}}}],["setup",{"_index":980,"t":{"153":{"position":[[28,5]]},"263":{"position":[[65,5]]},"280":{"position":[[729,5]]},"296":{"position":[[284,6]]},"337":{"position":[[137,7]]},"339":{"position":[[524,7]]},"379":{"position":[[661,6]]},"389":{"position":[[25,5]]},"393":{"position":[[1243,6]]},"530":{"position":[[46,6],[541,6]]},"600":{"position":[[1175,6]]},"609":{"position":[[925,6]]},"615":{"position":[[1405,6]]},"617":{"position":[[71,6]]},"817":{"position":[[581,6]]},"819":{"position":[[7637,5]]},"823":{"position":[[201,6]]},"861":{"position":[[185,6]]},"895":{"position":[[189,5],[581,5]]},"899":{"position":[[654,6]]},"903":{"position":[[22,5],[384,5]]},"956":{"position":[[613,5],[1995,7]]},"1395":{"position":[[661,5]]},"1507":{"position":[[581,6]]},"1509":{"position":[[7637,5]]},"1513":{"position":[[201,6]]},"1589":{"position":[[32,5]]},"1605":{"position":[[185,6]]},"1617":{"position":[[189,5],[581,5]]},"1621":{"position":[[654,6]]},"1625":{"position":[[22,5],[384,5]]},"1743":{"position":[[536,5]]},"1745":{"position":[[1171,5]]},"1749":{"position":[[1369,5],[1593,5]]},"1770":{"position":[[736,5]]},"1779":{"position":[[701,7]]},"1833":{"position":[[1404,5]]},"1849":{"position":[[732,5],[849,5]]},"1851":{"position":[[120,6]]},"1863":{"position":[[358,6]]},"1925":{"position":[[358,6]]},"1945":{"position":[[135,5]]},"1955":{"position":[[497,6]]},"1959":{"position":[[433,5]]},"2033":{"position":[[0,5],[139,5],[747,5]]},"2037":{"position":[[392,6]]},"2100":{"position":[[471,5]]},"2190":{"position":[[33,6]]},"2196":{"position":[[81,5]]},"2226":{"position":[[202,5]]},"2239":{"position":[[87,6]]},"2245":{"position":[[500,6]]},"2248":{"position":[[1277,5]]},"2342":{"position":[[189,5],[581,5]]},"2346":{"position":[[654,6]]},"2350":{"position":[[22,5],[384,5]]},"2715":{"position":[[242,5]]},"2862":{"position":[[242,5]]},"2947":{"position":[[464,5]]},"3033":{"position":[[109,5]]},"3061":{"position":[[401,5]]},"3071":{"position":[[825,5]]},"3111":{"position":[[201,5]]},"3182":{"position":[[1931,5]]},"3184":{"position":[[1618,5],[1904,6]]},"3208":{"position":[[372,6]]},"3220":{"position":[[447,5]]},"3231":{"position":[[449,6]]},"3236":{"position":[[1504,5]]},"3238":{"position":[[103,5]]},"3251":{"position":[[5494,6]]},"3284":{"position":[[443,5]]},"3314":{"position":[[1333,7]]},"3397":{"position":[[1947,5],[2182,5]]},"3400":{"position":[[1844,5]]},"3410":{"position":[[136,6],[153,7]]},"3479":{"position":[[324,5]]}}}],["sever",{"_index":36,"t":{"4":{"position":[[431,7],[624,7]]},"101":{"position":[[438,7]]},"257":{"position":[[88,7]]},"296":{"position":[[76,7]]},"298":{"position":[[932,7]]},"374":{"position":[[1278,8]]},"590":{"position":[[1337,8]]},"633":{"position":[[2388,7]]},"654":{"position":[[417,7]]},"669":{"position":[[43,7]]},"746":{"position":[[94,7]]},"920":{"position":[[239,7]]},"1224":{"position":[[3012,7],[3829,7]]},"1642":{"position":[[239,7]]},"1684":{"position":[[478,7]]},"1837":{"position":[[208,7]]},"1851":{"position":[[177,7]]},"2294":{"position":[[3,6]]},"2367":{"position":[[239,7]]},"2566":{"position":[[14592,9]]},"2795":{"position":[[1575,7]]},"2811":{"position":[[36,7]]},"2890":{"position":[[354,7]]},"2949":{"position":[[646,7]]},"3001":{"position":[[75,7]]},"3011":{"position":[[2571,7]]},"3251":{"position":[[354,7],[2897,7]]},"3262":{"position":[[486,7]]},"3301":{"position":[[363,7],[683,7]]},"3314":{"position":[[830,7],[961,7],[3100,7]]},"3343":{"position":[[1059,8]]},"3355":{"position":[[582,8]]},"3357":{"position":[[2,8],[130,9],[519,8],[901,8],[919,8],[995,8],[1026,8],[1080,8],[1182,9]]},"3391":{"position":[[168,7],[222,7]]},"3465":{"position":[[592,6]]}}}],["severel",{"_index":9642,"t":{"2964":{"position":[[300,7]]}}}],["severity'",{"_index":10180,"t":{"3357":{"position":[[144,10],[204,10],[298,10]]}}}],["severitya",{"_index":10181,"t":{"3357":{"position":[[215,11]]}}}],["severitya.valu",{"_index":10183,"t":{"3357":{"position":[[382,16],[399,16]]}}}],["severityb",{"_index":10182,"t":{"3357":{"position":[[309,11],[539,9]]}}}],["severityb.valu",{"_index":10184,"t":{"3357":{"position":[[427,15],[448,16],[465,15]]}}}],["severityvalu",{"_index":10168,"t":{"3343":{"position":[[884,14],[901,13]]},"3355":{"position":[[483,13]]},"3357":{"position":[[84,13],[1133,13]]}}}],["sex",{"_index":1656,"t":{"247":{"position":[[575,3]]}}}],["sexist",{"_index":1691,"t":{"247":{"position":[[1683,7]]}}}],["sexual",{"_index":1660,"t":{"247":{"position":[[628,6],[1452,8],[1817,6]]}}}],["sfp",{"_index":7061,"t":{"1585":{"position":[[914,4],[979,4]]}}}],["sg",{"_index":9744,"t":{"3076":{"position":[[22,3],[110,2],[161,3]]},"3080":{"position":[[179,2],[482,2]]},"3084":{"position":[[264,2],[278,4],[854,4]]},"3092":{"position":[[387,2]]},"3094":{"position":[[45,2]]}}}],["sh",{"_index":992,"t":{"158":{"position":[[414,2],[622,2]]},"1731":{"position":[[1570,3]]}}}],["sha256",{"_index":9560,"t":{"2899":{"position":[[952,6]]}}}],["sha256:32a9d30d18803da72f5936cf2b7b9efcb4d0bb63c67933f17e3bdfd1751de3f3",{"_index":4142,"t":{"850":{"position":[[8166,71],[8515,74]]},"1484":{"position":[[8166,71],[8515,74]]}}}],["sha256:47dd9ad7048afe96bc6cc0b3fd8922f290e99c29d251affcd22d0afecfe0e337",{"_index":4097,"t":{"850":{"position":[[2561,71],[2697,71]]},"1484":{"position":[[2561,71],[2697,71]]}}}],["sha256:62af6445fd2c31f68a069151938a7dcb49158644cae531dd22efc36c1c15a710",{"_index":4133,"t":{"850":{"position":[[6580,71],[6716,71]]},"1484":{"position":[[6580,71],[6716,71]]}}}],["sha256:7713278c37f29b0341b0a841ca3ec5c3724df86b4d97e7ee4a2a85def9b2e651",{"_index":4128,"t":{"850":{"position":[[5746,71],[5882,71]]},"1484":{"position":[[5746,71],[5882,71]]}}}],["sha256:94e1e2c94dbbae7d4bdc38e68590a1daf73c9de2d03dd693857b4b0a042548e8",{"_index":3759,"t":{"790":{"position":[[1224,73]]},"1527":{"position":[[1224,73]]}}}],["sha256:bd99c64ad9d926eb5769f9f2cfd96ae4989a029bd64bd3e7e7deb8cff4251c65",{"_index":4138,"t":{"850":{"position":[[7398,71],[7534,71]]},"1484":{"position":[[7398,71],[7534,71]]}}}],["sha256:d7ba8d5d1d073f2dc8351973bf4f35157c846a0ea6ee16fb2a9f45a78953e4a7",{"_index":4143,"t":{"850":{"position":[[8302,71]]},"1484":{"position":[[8302,71]]}}}],["sha512",{"_index":9561,"t":{"2899":{"position":[[962,6]]}}}],["sha512:3d6f26616e2c8b705993ddef874232887cebe42f1e70fcc020827ac88e8990177d537d34538c71ae2afd3b8baca953fff71eaa7ef71e752e82532c93dcdca436",{"_index":4156,"t":{"850":{"position":[[9719,135]]},"1484":{"position":[[9719,135]]}}}],["sha512:5401f8c6361bb2a82c2c24b4b4606d95e77229152a80e61f9c613bc88e25de9257057d0ed68b0256b745c4059162a54970fe4a8daf456b2eb67b4f5db5c97fcc",{"_index":4117,"t":{"850":{"position":[[4582,135]]},"1484":{"position":[[4582,135]]}}}],["sha512:bdccf01b778a602024918e27bb8cfd84be32104609651f457ac1db10ee5d2a490d0c60e21ce3c0a7704e7ca439281724d0d7e48d279c9fc3a5133a7283e321e4",{"_index":4109,"t":{"850":{"position":[[3438,135],[3638,135]]},"1484":{"position":[[3438,135],[3638,135]]}}}],["sha512:f4850b3910adb80801649399d4f89be08974a05a198aba7093f6e72d38d82183bc5b36183fb8dd34cd48a3e226d46802d8a8d85e8b5714b67c52e7ea642f085",{"_index":4116,"t":{"850":{"position":[[4382,135],[4859,138]]},"1484":{"position":[[4382,135],[4859,138]]}}}],["shadow",{"_index":1960,"t":{"302":{"position":[[258,8],[1150,8]]}}}],["shall",{"_index":2215,"t":{"368":{"position":[[65,7],[91,5]]},"1943":{"position":[[88,5],[186,5]]},"1953":{"position":[[75,5],[210,5],[335,5]]},"2476":{"position":[[653,5]]},"2495":{"position":[[133,5]]},"2619":{"position":[[46,8],[55,6]]},"2635":{"position":[[671,5]]},"2688":{"position":[[2909,5]]},"3249":{"position":[[103,5],[592,5]]},"3255":{"position":[[998,5]]},"3338":{"position":[[46,8],[55,6]]},"3347":{"position":[[528,5]]},"3361":{"position":[[362,5]]},"3415":{"position":[[468,5]]}}}],["shape",{"_index":498,"t":{"69":{"position":[[37,5]]},"75":{"position":[[193,5]]},"238":{"position":[[350,7]]},"2196":{"position":[[381,6]]},"3312":{"position":[[140,5]]}}}],["share",{"_index":504,"t":{"69":{"position":[[195,5]]},"263":{"position":[[33,7]]},"396":{"position":[[424,5]]},"421":{"position":[[483,5]]},"738":{"position":[[81,5],[142,5],[182,5]]},"746":{"position":[[195,6]]},"800":{"position":[[587,7],[613,6]]},"813":{"position":[[290,6]]},"819":{"position":[[613,6],[871,6],[2391,6],[2409,6],[2937,6],[2972,6],[6634,5],[6745,6],[7986,5]]},"922":{"position":[[572,5]]},"977":{"position":[[804,5],[1670,6]]},"1286":{"position":[[2425,6]]},"1503":{"position":[[290,6]]},"1509":{"position":[[613,6],[871,6],[2391,6],[2409,6],[2937,6],[2972,6],[6634,5],[6745,6],[7986,5]]},"1537":{"position":[[587,7],[613,6]]},"1644":{"position":[[572,5]]},"1731":{"position":[[264,6],[479,5],[508,6],[731,6],[871,5]]},"1972":{"position":[[317,5]]},"2306":{"position":[[172,6]]},"2369":{"position":[[572,5]]},"2647":{"position":[[316,6]]},"2709":{"position":[[100,6]]},"2754":{"position":[[100,6]]},"2844":{"position":[[28,6]]},"2927":{"position":[[79,6],[104,6],[130,6],[162,6],[197,6],[223,6],[248,6],[277,6],[309,6],[335,6],[364,6],[390,6],[416,6],[443,6]]},"2929":{"position":[[82,6],[119,6],[157,6],[197,6],[235,6],[271,6],[308,6],[346,6],[388,6],[427,6],[465,6],[505,6]]},"2931":{"position":[[363,6]]},"2947":{"position":[[564,6]]},"3099":{"position":[[340,5]]},"3105":{"position":[[78,7],[158,5]]},"3109":{"position":[[54,5],[181,5],[985,6],[1165,5],[1375,6],[3134,7]]},"3115":{"position":[[279,6]]},"3218":{"position":[[650,7]]},"3249":{"position":[[890,5],[928,6]]},"3301":{"position":[[5127,6],[5485,6],[7519,6]]}}}],["share.cr",{"_index":8740,"t":{"2566":{"position":[[2876,18]]}}}],["share.delet",{"_index":8741,"t":{"2566":{"position":[[2895,17]]}}}],["share.extend",{"_index":8742,"t":{"2566":{"position":[[2913,17]]}}}],["share.shrink",{"_index":8743,"t":{"2566":{"position":[[2931,17]]}}}],["share_group_id",{"_index":8748,"t":{"2566":{"position":[[3256,15]]}}}],["share_id",{"_index":8745,"t":{"2566":{"position":[[2971,9]]}}}],["share_trait",{"_index":8744,"t":{"2566":{"position":[[2957,13]]}}}],["sheer",{"_index":1094,"t":{"170":{"position":[[206,5]]}}}],["sheet",{"_index":1558,"t":{"233":{"position":[[114,6]]},"3240":{"position":[[182,5]]}}}],["shell",{"_index":994,"t":{"158":{"position":[[470,6]]},"790":{"position":[[586,5],[635,5]]},"810":{"position":[[281,5]]},"830":{"position":[[161,5]]},"848":{"position":[[146,5]]},"850":{"position":[[838,6],[899,6]]},"855":{"position":[[152,5]]},"895":{"position":[[981,5],[1102,5]]},"903":{"position":[[303,6]]},"1317":{"position":[[218,5]]},"1482":{"position":[[146,5]]},"1484":{"position":[[838,6],[899,6]]},"1500":{"position":[[281,5]]},"1527":{"position":[[586,5],[635,5]]},"1545":{"position":[[161,5]]},"1599":{"position":[[152,5]]},"1617":{"position":[[981,5],[1102,5]]},"1625":{"position":[[303,6]]},"1743":{"position":[[2522,6]]},"1843":{"position":[[118,6]]},"2342":{"position":[[981,5],[1102,5]]},"2350":{"position":[[303,6]]}}}],["shelv",{"_index":1863,"t":{"284":{"position":[[36,7]]}}}],["shield",{"_index":2933,"t":{"513":{"position":[[842,6]]}}}],["shift",{"_index":2442,"t":{"417":{"position":[[62,5]]},"2960":{"position":[[1186,7]]},"3249":{"position":[[601,7]]}}}],["shim",{"_index":10224,"t":{"3415":{"position":[[512,4]]}}}],["shini",{"_index":6822,"t":{"1397":{"position":[[550,5]]}}}],["ship",{"_index":8377,"t":{"2196":{"position":[[741,4]]},"2214":{"position":[[393,8]]},"3227":{"position":[[317,5]]},"3299":{"position":[[5354,7]]}}}],["shmemhugepag",{"_index":6766,"t":{"1379":{"position":[[46,15],[534,15]]}}}],["shoot",{"_index":4293,"t":{"888":{"position":[[738,6],[772,5],[917,5],[1102,6]]}}}],["short",{"_index":3797,"t":{"803":{"position":[[55,5]]},"899":{"position":[[756,5]]},"917":{"position":[[881,5]]},"1540":{"position":[[55,5]]},"1585":{"position":[[755,5]]},"1621":{"position":[[756,5]]},"1639":{"position":[[881,5]]},"1822":{"position":[[131,5]]},"2148":{"position":[[380,5]]},"2346":{"position":[[756,5]]},"2364":{"position":[[881,5]]},"2700":{"position":[[766,5]]},"2713":{"position":[[753,6],[918,5]]},"2719":{"position":[[1454,5]]},"2731":{"position":[[42,5]]},"2745":{"position":[[766,5]]},"2756":{"position":[[1221,6],[1386,5]]},"2758":{"position":[[1455,5]]},"2770":{"position":[[42,5]]},"2858":{"position":[[591,6],[728,5]]},"2860":{"position":[[42,5]]},"2872":{"position":[[598,6]]},"2960":{"position":[[521,5]]},"3208":{"position":[[932,5]]},"3251":{"position":[[2472,5]]},"3395":{"position":[[459,5]]},"3487":{"position":[[5,5]]}}}],["shortcom",{"_index":1183,"t":{"172":{"position":[[696,11]]},"3378":{"position":[[361,12]]}}}],["shortcut",{"_index":4301,"t":{"895":{"position":[[389,9]]},"1317":{"position":[[257,9]]},"1333":{"position":[[314,9]]},"1335":{"position":[[216,9]]},"1337":{"position":[[436,9]]},"1339":{"position":[[235,9]]},"1617":{"position":[[389,9]]},"2342":{"position":[[389,9]]}}}],["shorten",{"_index":9934,"t":{"3208":{"position":[[1058,7]]}}}],["shorter",{"_index":9883,"t":{"3128":{"position":[[377,7]]},"3206":{"position":[[589,7]]}}}],["shortli",{"_index":8514,"t":{"2334":{"position":[[288,7]]},"2627":{"position":[[1627,7]]}}}],["shortnam",{"_index":4152,"t":{"850":{"position":[[9086,10]]},"1484":{"position":[[9086,10]]}}}],["shoulder",{"_index":8400,"t":{"2235":{"position":[[16,9]]}}}],["shouldn't",{"_index":3554,"t":{"662":{"position":[[466,9]]},"3016":{"position":[[687,9]]},"3197":{"position":[[1427,9]]},"3270":{"position":[[678,9]]},"3276":{"position":[[1402,9]]}}}],["show",{"_index":619,"t":{"95":{"position":[[0,7]]},"153":{"position":[[11,5]]},"164":{"position":[[129,4]]},"247":{"position":[[1047,5]]},"308":{"position":[[3,4]]},"389":{"position":[[471,5]]},"430":{"position":[[11,5]]},"515":{"position":[[11,5]]},"540":{"position":[[44,4]]},"578":{"position":[[5,4],[20,4]]},"730":{"position":[[832,4],[1619,4]]},"819":{"position":[[1374,4]]},"821":{"position":[[767,4]]},"850":{"position":[[851,4],[867,4],[959,4]]},"859":{"position":[[901,4]]},"903":{"position":[[2585,4],[2669,4],[2782,4]]},"909":{"position":[[1841,4]]},"911":{"position":[[1478,4],[1550,4]]},"913":{"position":[[928,4]]},"947":{"position":[[129,5],[561,4]]},"1091":{"position":[[99,5]]},"1150":{"position":[[12707,4]]},"1165":{"position":[[2649,5]]},"1317":{"position":[[410,4],[427,4],[511,4],[605,4],[619,4],[641,4],[1445,4],[5503,4],[8699,4]]},"1366":{"position":[[227,4]]},"1368":{"position":[[557,4],[1058,4]]},"1413":{"position":[[83,4]]},"1484":{"position":[[851,4],[867,4],[959,4]]},"1491":{"position":[[832,4],[1619,4]]},"1509":{"position":[[1374,4]]},"1511":{"position":[[767,4]]},"1603":{"position":[[901,4]]},"1625":{"position":[[2585,4],[2669,4],[2782,4]]},"1631":{"position":[[1841,4]]},"1633":{"position":[[1478,4],[1550,4]]},"1635":{"position":[[928,4]]},"1669":{"position":[[129,5],[561,4]]},"1827":{"position":[[268,5]]},"1839":{"position":[[79,4]]},"1849":{"position":[[64,4]]},"1861":{"position":[[362,4]]},"1896":{"position":[[409,4],[643,4]]},"1906":{"position":[[366,4]]},"1908":{"position":[[2317,4],[2374,4]]},"1913":{"position":[[757,4]]},"1923":{"position":[[362,4]]},"1957":{"position":[[1863,5],[1925,5]]},"2012":{"position":[[409,4],[643,4]]},"2022":{"position":[[366,4]]},"2024":{"position":[[2317,4],[2374,4]]},"2029":{"position":[[757,4]]},"2144":{"position":[[225,7]]},"2350":{"position":[[2585,4],[2669,4],[2782,4]]},"2356":{"position":[[1841,4]]},"2358":{"position":[[1478,4],[1550,4]]},"2360":{"position":[[928,4]]},"2394":{"position":[[129,5],[561,4]]},"2420":{"position":[[191,7]]},"2966":{"position":[[294,4],[779,7]]},"3031":{"position":[[20,5],[90,5]]},"3042":{"position":[[391,4]]},"3057":{"position":[[166,4]]},"3109":{"position":[[2600,4]]},"3156":{"position":[[251,4]]},"3184":{"position":[[1112,6]]},"3299":{"position":[[2412,5],[3756,5]]},"3468":{"position":[[278,5],[476,5]]}}}],["show_keystone_v2_rc",{"_index":5491,"t":{"1146":{"position":[[324,19]]}}}],["showcas",{"_index":9739,"t":{"3065":{"position":[[22,9]]}}}],["shown",{"_index":954,"t":{"145":{"position":[[140,5]]},"742":{"position":[[754,5]]},"760":{"position":[[506,5]]},"1165":{"position":[[1774,5]]},"1894":{"position":[[634,5]]},"2010":{"position":[[634,5]]},"2160":{"position":[[131,5],[185,5]]},"2635":{"position":[[327,5]]},"3429":{"position":[[30,5],[97,5]]},"3431":{"position":[[30,5],[97,5]]}}}],["showstopp",{"_index":10056,"t":{"3299":{"position":[[888,12]]}}}],["shrink",{"_index":6894,"t":{"1430":{"position":[[1387,6]]}}}],["shut",{"_index":9603,"t":{"2947":{"position":[[1105,4]]},"3370":{"position":[[199,4]]},"3434":{"position":[[199,4]]}}}],["shutdown",{"_index":3262,"t":{"615":{"position":[[1329,9]]},"1471":{"position":[[18,8]]},"1473":{"position":[[45,8],[213,8]]},"1569":{"position":[[906,9],[1310,8]]},"1571":{"position":[[1350,8],[1375,8]]},"1835":{"position":[[5,8]]},"1849":{"position":[[927,9]]},"3270":{"position":[[213,9]]}}}],["side",{"_index":154,"t":{"10":{"position":[[1473,4]]},"389":{"position":[[279,4]]},"1585":{"position":[[2744,5]]},"1878":{"position":[[1271,5]]},"1994":{"position":[[1271,5]]},"2424":{"position":[[78,4],[181,5]]},"2874":{"position":[[611,4]]},"3071":{"position":[[2255,4]]},"3395":{"position":[[666,4]]},"3397":{"position":[[556,4],[564,5]]},"3400":{"position":[[1697,4]]},"3472":{"position":[[14579,4]]}}}],["sidebar",{"_index":8002,"t":{"1957":{"position":[[607,7],[1502,7],[2739,7]]}}}],["sidecar",{"_index":8270,"t":{"2142":{"position":[[168,8]]},"3397":{"position":[[2198,7],[2334,7]]}}}],["sidenot",{"_index":4345,"t":{"903":{"position":[[1798,9]]},"1625":{"position":[[1798,9]]},"2350":{"position":[[1798,9]]},"3314":{"position":[[3432,9]]}}}],["siena",{"_index":9356,"t":{"2764":{"position":[[1183,5]]}}}],["sig",{"_index":52,"t":{"4":{"position":[[642,4]]},"25":{"position":[[280,3],[303,3],[338,3]]},"27":{"position":[[461,3],[473,3],[760,3],[780,3]]},"67":{"position":[[22,3],[86,3],[113,3],[151,3],[169,3],[183,3]]},"71":{"position":[[450,3]]},"75":{"position":[[27,5]]},"235":{"position":[[1316,3]]},"2737":{"position":[[169,3]]},"2776":{"position":[[169,3]]},"2822":{"position":[[169,3]]},"3059":{"position":[[855,5]]},"3482":{"position":[[2138,3],[2407,3],[2544,3],[2805,3]]}}}],["sign",{"_index":1281,"t":{"178":{"position":[[1692,6]]},"206":{"position":[[244,6]]},"253":{"position":[[1107,4],[1691,4],[1751,6],[1814,6],[2077,6]]},"298":{"position":[[698,4]]},"355":{"position":[[241,4]]},"404":{"position":[[275,6]]},"588":{"position":[[270,4]]},"615":{"position":[[436,4]]},"617":{"position":[[1193,6],[1223,6]]},"907":{"position":[[66,6]]},"926":{"position":[[228,7]]},"932":{"position":[[213,7]]},"1012":{"position":[[487,6],[536,6]]},"1108":{"position":[[998,6]]},"1213":{"position":[[16,6],[197,6]]},"1629":{"position":[[66,6]]},"1648":{"position":[[228,7]]},"1654":{"position":[[213,7]]},"1783":{"position":[[403,6]]},"1789":{"position":[[70,6],[89,6]]},"1791":{"position":[[582,4],[796,4]]},"1957":{"position":[[3506,4],[3597,4]]},"2224":{"position":[[9,4]]},"2354":{"position":[[66,6]]},"2373":{"position":[[228,7]]},"2379":{"position":[[213,7]]},"2576":{"position":[[55,4]]},"3160":{"position":[[1073,7]]},"3214":{"position":[[148,7]]},"3229":{"position":[[83,7]]},"3234":{"position":[[69,6],[498,4],[531,6],[734,7],[783,7],[815,7],[925,4]]},"3255":{"position":[[951,7]]},"3264":{"position":[[198,7]]},"3276":{"position":[[81,6],[1021,6]]},"3343":{"position":[[1338,6]]}}}],["signal",{"_index":2242,"t":{"374":{"position":[[639,9]]},"2154":{"position":[[315,7]]},"2637":{"position":[[208,7]]},"3055":{"position":[[807,6]]}}}],["signer.sh",{"_index":2994,"t":{"588":{"position":[[240,9]]}}}],["signernam",{"_index":10039,"t":{"3276":{"position":[[2626,10]]}}}],["signifi",{"_index":2231,"t":{"372":{"position":[[694,7]]}}}],["signific",{"_index":1135,"t":{"170":{"position":[[1266,11]]},"178":{"position":[[1470,11]]},"339":{"position":[[282,11]]},"615":{"position":[[767,11]]},"617":{"position":[[1249,11]]},"895":{"position":[[2155,11]]},"1617":{"position":[[2155,11]]},"2196":{"position":[[304,11]]},"2283":{"position":[[10,11]]},"2342":{"position":[[2155,11]]},"2424":{"position":[[233,12]]},"2663":{"position":[[277,11]]},"3011":{"position":[[629,11]]},"3014":{"position":[[216,11]]},"3016":{"position":[[702,11]]},"3218":{"position":[[22,11],[1026,11]]},"3224":{"position":[[185,11]]},"3301":{"position":[[4517,11]]},"3378":{"position":[[606,11]]}}}],["significantli",{"_index":1222,"t":{"176":{"position":[[316,13]]},"178":{"position":[[2518,14]]},"335":{"position":[[151,13]]},"1736":{"position":[[197,13]]},"2317":{"position":[[21,13]]},"2330":{"position":[[912,13]]},"2665":{"position":[[154,13]]},"2899":{"position":[[320,13]]},"2951":{"position":[[769,13],[951,13]]},"3011":{"position":[[1199,13]]}}}],["signup",{"_index":4568,"t":{"932":{"position":[[1406,6]]},"1654":{"position":[[1406,6]]},"2379":{"position":[[1406,6]]}}}],["sigs/clust",{"_index":3100,"t":{"604":{"position":[[1862,12]]}}}],["sigs/e2",{"_index":9726,"t":{"3059":{"position":[[85,8],[120,8]]}}}],["silver",{"_index":1309,"t":{"178":{"position":[[2798,6]]}}}],["similar",{"_index":1180,"t":{"172":{"position":[[546,7]]},"176":{"position":[[1164,7]]},"191":{"position":[[328,8]]},"231":{"position":[[61,8]]},"404":{"position":[[765,7]]},"507":{"position":[[178,7]]},"509":{"position":[[119,7]]},"511":{"position":[[624,8]]},"590":{"position":[[1264,7]]},"598":{"position":[[1190,7]]},"604":{"position":[[8270,7]]},"639":{"position":[[165,7]]},"911":{"position":[[714,7]]},"1477":{"position":[[297,7]]},"1587":{"position":[[676,7]]},"1633":{"position":[[714,7]]},"1957":{"position":[[3003,7]]},"1982":{"position":[[1041,7]]},"1984":{"position":[[651,7]]},"2209":{"position":[[452,7]]},"2358":{"position":[[714,7]]},"2625":{"position":[[150,7]]},"2779":{"position":[[68,8],[166,7]]},"3009":{"position":[[71,7]]},"3011":{"position":[[105,7]]},"3014":{"position":[[1073,7]]},"3059":{"position":[[331,7]]},"3078":{"position":[[129,7]]},"3182":{"position":[[756,7]]},"3184":{"position":[[737,8]]},"3251":{"position":[[5541,7]]},"3266":{"position":[[146,7]]},"3314":{"position":[[619,7],[2719,7]]},"3438":{"position":[[537,7]]}}}],["similarli",{"_index":9347,"t":{"2756":{"position":[[590,10]]},"3413":{"position":[[260,9]]}}}],["similiar",{"_index":9775,"t":{"3103":{"position":[[31,8]]}}}],["simpl",{"_index":971,"t":{"149":{"position":[[66,6]]},"187":{"position":[[241,7]]},"393":{"position":[[320,6],[814,6]]},"654":{"position":[[713,6]]},"669":{"position":[[415,6],[726,6]]},"853":{"position":[[14,6]]},"855":{"position":[[29,6],[89,6],[116,6]]},"857":{"position":[[96,6],[264,6],[331,6],[360,6]]},"859":{"position":[[86,6],[293,6],[2210,6],[2963,6],[3024,6],[3125,7],[3228,7],[3347,7],[3466,7],[3566,7],[3681,7],[3781,7],[3896,7],[3959,6],[4020,6],[4121,7],[4224,7],[4343,7],[4462,7],[4562,7],[4677,7],[4777,7],[4892,7],[4955,6],[5056,7],[5119,6],[5220,7],[5339,7],[5458,7],[5558,7],[5658,7],[5773,7],[5888,7]]},"861":{"position":[[222,6]]},"865":{"position":[[508,6]]},"878":{"position":[[508,6]]},"899":{"position":[[910,6]]},"903":{"position":[[2827,6]]},"1059":{"position":[[116,6]]},"1165":{"position":[[1106,6]]},"1597":{"position":[[14,6]]},"1599":{"position":[[29,6],[89,6],[116,6]]},"1601":{"position":[[96,6],[264,6],[331,6],[360,6]]},"1603":{"position":[[86,6],[293,6],[2210,6],[2963,6],[3024,6],[3125,7],[3228,7],[3347,7],[3466,7],[3566,7],[3681,7],[3781,7],[3896,7],[3959,6],[4020,6],[4121,7],[4224,7],[4343,7],[4462,7],[4562,7],[4677,7],[4777,7],[4892,7],[4955,6],[5056,7],[5119,6],[5220,7],[5339,7],[5458,7],[5558,7],[5658,7],[5773,7],[5888,7]]},"1605":{"position":[[222,6]]},"1621":{"position":[[910,6]]},"1625":{"position":[[2827,6]]},"1749":{"position":[[1357,6]]},"1791":{"position":[[1953,6]]},"1851":{"position":[[82,6]]},"1853":{"position":[[119,6]]},"1915":{"position":[[119,6]]},"2116":{"position":[[140,6]]},"2122":{"position":[[184,6]]},"2346":{"position":[[910,6]]},"2350":{"position":[[2827,6]]},"2461":{"position":[[399,6]]},"2820":{"position":[[97,6]]},"2947":{"position":[[5833,6]]},"2962":{"position":[[80,6]]},"3314":{"position":[[194,6],[488,6],[529,7]]},"3353":{"position":[[223,6]]},"3397":{"position":[[1006,7],[2352,6]]}}}],["simpler",{"_index":2297,"t":{"387":{"position":[[155,7]]}}}],["simplest",{"_index":2992,"t":{"586":{"position":[[316,8]]},"897":{"position":[[213,8]]},"1619":{"position":[[213,8]]},"2344":{"position":[[213,8]]}}}],["simpli",{"_index":1160,"t":{"170":{"position":[[2223,6]]},"187":{"position":[[273,6]]},"325":{"position":[[2757,6]]},"604":{"position":[[3391,6]]},"609":{"position":[[1091,6]]},"641":{"position":[[715,6]]},"1902":{"position":[[30,6]]},"1906":{"position":[[42,6]]},"1913":{"position":[[1731,6]]},"2018":{"position":[[30,6]]},"2022":{"position":[[42,6]]},"2029":{"position":[[1731,6]]},"2120":{"position":[[357,6]]}}}],["simplif",{"_index":3658,"t":{"742":{"position":[[621,14]]}}}],["simplifi",{"_index":1362,"t":{"189":{"position":[[30,8]]},"290":{"position":[[323,8]]},"744":{"position":[[19,10]]},"880":{"position":[[1011,11]]},"883":{"position":[[61,10],[683,10]]},"888":{"position":[[31,10]]},"1690":{"position":[[44,8]]},"1937":{"position":[[325,8]]},"2317":{"position":[[35,10]]},"2463":{"position":[[465,10]]},"2550":{"position":[[478,11]]},"2677":{"position":[[308,8]]},"2719":{"position":[[475,11]]},"2758":{"position":[[473,11]]},"3216":{"position":[[169,10]]},"3251":{"position":[[4367,8]]},"3343":{"position":[[80,8]]}}}],["simplist",{"_index":10105,"t":{"3314":{"position":[[38,10],[121,11]]}}}],["simul",{"_index":7052,"t":{"1585":{"position":[[111,9]]}}}],["simulcast/svc",{"_index":1745,"t":{"251":{"position":[[132,13]]}}}],["simultan",{"_index":7898,"t":{"1853":{"position":[[551,14]]},"1865":{"position":[[59,14]]},"1915":{"position":[[551,14]]},"1927":{"position":[[59,14]]}}}],["singl",{"_index":530,"t":{"71":{"position":[[202,6]]},"114":{"position":[[387,6]]},"298":{"position":[[1001,6]]},"300":{"position":[[378,6]]},"317":{"position":[[822,6]]},"447":{"position":[[173,6]]},"449":{"position":[[274,6]]},"596":{"position":[[999,6],[1218,6],[1253,6],[2503,6],[2548,6],[3031,7]]},"600":{"position":[[256,6]]},"615":{"position":[[1525,6]]},"617":{"position":[[215,6]]},"648":{"position":[[116,6]]},"742":{"position":[[875,6]]},"744":{"position":[[416,6]]},"786":{"position":[[159,6]]},"880":{"position":[[994,6]]},"909":{"position":[[2555,6],[2751,6]]},"911":{"position":[[1705,6]]},"922":{"position":[[173,6]]},"932":{"position":[[4609,6]]},"977":{"position":[[582,6],[1128,7],[1397,6]]},"980":{"position":[[76,6]]},"1055":{"position":[[132,6]]},"1057":{"position":[[71,6]]},"1120":{"position":[[83,6]]},"1286":{"position":[[1289,6]]},"1290":{"position":[[444,6]]},"1292":{"position":[[887,6]]},"1337":{"position":[[183,6]]},"1360":{"position":[[1244,6],[1372,6],[1497,6],[1632,6],[1777,6],[1922,6],[2059,6],[2192,6],[2321,6],[2445,6],[2586,6],[2824,6],[2932,6],[3042,6]]},"1406":{"position":[[313,6]]},"1428":{"position":[[18,6],[82,6]]},"1444":{"position":[[240,6]]},"1523":{"position":[[159,6]]},"1564":{"position":[[369,6]]},"1631":{"position":[[2555,6],[2751,6]]},"1633":{"position":[[1705,6]]},"1644":{"position":[[173,6]]},"1654":{"position":[[4609,6]]},"1738":{"position":[[360,6]]},"1779":{"position":[[3609,6],[5505,6]]},"1791":{"position":[[789,6]]},"1978":{"position":[[640,6]]},"2031":{"position":[[325,6]]},"2100":{"position":[[1242,6]]},"2106":{"position":[[64,6]]},"2312":{"position":[[273,6]]},"2356":{"position":[[2555,6],[2751,6]]},"2358":{"position":[[1705,6]]},"2369":{"position":[[173,6]]},"2379":{"position":[[4609,6]]},"2476":{"position":[[185,6]]},"2576":{"position":[[48,6]]},"2586":{"position":[[331,6]]},"2709":{"position":[[698,6],[714,6]]},"2754":{"position":[[698,6],[714,6]]},"2813":{"position":[[1179,6]]},"2844":{"position":[[626,6],[642,6]]},"2944":{"position":[[1881,6]]},"2947":{"position":[[156,6],[341,6],[541,6],[597,6],[758,6]]},"3076":{"position":[[121,6]]},"3099":{"position":[[159,6]]},"3103":{"position":[[777,6]]},"3113":{"position":[[271,6]]},"3141":{"position":[[119,6]]},"3160":{"position":[[495,6]]},"3197":{"position":[[1256,6]]},"3251":{"position":[[2040,6],[4459,7]]},"3286":{"position":[[82,6]]},"3299":{"position":[[2572,6]]},"3301":{"position":[[624,6],[5044,6],[7445,6]]},"3347":{"position":[[264,6]]},"3349":{"position":[[60,6]]},"3351":{"position":[[394,6],[502,6]]},"3372":{"position":[[425,6],[485,6],[602,6]]}}}],["sink",{"_index":8962,"t":{"2568":{"position":[[81,6],[103,5],[115,6],[143,5]]},"2570":{"position":[[48,6],[68,6]]},"3442":{"position":[[98,4]]},"3444":{"position":[[67,6],[139,4]]}}}],["sit",{"_index":56,"t":{"6":{"position":[[18,3],[170,3]]},"200":{"position":[[30,7]]},"212":{"position":[[288,7]]}}}],["site",{"_index":939,"t":{"143":{"position":[[534,4]]},"200":{"position":[[97,4]]},"206":{"position":[[319,4]]},"3400":{"position":[[1885,5]]}}}],["situat",{"_index":1233,"t":{"176":{"position":[[752,10]]},"189":{"position":[[137,10]]},"499":{"position":[[2821,10]]},"980":{"position":[[197,10]]},"1344":{"position":[[234,9]]},"1404":{"position":[[151,11]]},"1434":{"position":[[30,11]]},"2502":{"position":[[540,10]]},"2947":{"position":[[3323,10]]},"3184":{"position":[[2581,10]]},"3218":{"position":[[1073,10]]},"3319":{"position":[[70,9]]},"3370":{"position":[[91,10]]},"3434":{"position":[[91,10]]}}}],["six",{"_index":8598,"t":{"2514":{"position":[[561,3]]},"2522":{"position":[[53,3]]},"2795":{"position":[[253,3]]}}}],["size",{"_index":1399,"t":{"193":{"position":[[719,5]]},"247":{"position":[[690,4]]},"487":{"position":[[2084,4],[2214,4]]},"644":{"position":[[659,4],[728,8]]},"857":{"position":[[440,4]]},"859":{"position":[[854,4],[2166,4],[2377,4],[2510,4]]},"861":{"position":[[325,4]]},"909":{"position":[[2853,7]]},"984":{"position":[[457,4]]},"1112":{"position":[[1282,4]]},"1114":{"position":[[1928,4],[3485,4],[3536,4],[3681,4]]},"1124":{"position":[[1172,5],[1351,5]]},"1165":{"position":[[3404,4]]},"1217":{"position":[[243,5],[685,4],[733,5]]},"1234":{"position":[[1978,4]]},"1351":{"position":[[3127,5]]},"1379":{"position":[[283,4],[781,4]]},"1562":{"position":[[306,5]]},"1566":{"position":[[323,5]]},"1571":{"position":[[285,4],[460,4],[506,4]]},"1601":{"position":[[440,4]]},"1603":{"position":[[854,4],[2166,4],[2377,4],[2510,4]]},"1605":{"position":[[325,4]]},"1631":{"position":[[2853,7]]},"1845":{"position":[[466,4],[534,4]]},"1906":{"position":[[622,4],[790,4]]},"1908":{"position":[[963,4],[2664,4],[2701,4],[2761,4]]},"2022":{"position":[[622,4],[790,4]]},"2024":{"position":[[963,4],[2664,4],[2701,4],[2761,4]]},"2356":{"position":[[2853,7]]},"2550":{"position":[[281,6]]},"2566":{"position":[[2583,5],[3303,5],[4178,5]]},"2707":{"position":[[192,5]]},"2709":{"position":[[5,5],[30,5],[747,4],[956,5],[1207,4],[1663,4],[1757,4],[1984,4],[2069,4],[2235,5]]},"2711":{"position":[[82,5],[1022,5],[1182,4],[1237,5]]},"2752":{"position":[[192,5]]},"2754":{"position":[[5,5],[30,5],[888,4],[1097,5],[1348,4],[1804,4],[1898,4],[2190,5]]},"2786":{"position":[[211,5]]},"2842":{"position":[[191,5]]},"2844":{"position":[[675,4],[884,5],[1135,4],[1457,4],[1551,4],[1777,4],[1862,4],[2028,5]]},"2856":{"position":[[84,5],[1000,5],[1159,4],[1214,5]]},"2892":{"position":[[438,5]]},"2931":{"position":[[73,5]]},"2933":{"position":[[551,5],[711,4],[768,5]]},"2939":{"position":[[341,4]]},"2947":{"position":[[1530,5],[1615,5]]},"2962":{"position":[[99,4]]},"2966":{"position":[[158,5]]},"3042":{"position":[[146,5]]},"3301":{"position":[[3551,4],[4473,5]]},"3376":{"position":[[588,7]]},"3382":{"position":[[176,7]]},"3440":{"position":[[266,7]]}}}],["size=$s",{"_index":6976,"t":{"1475":{"position":[[344,10],[660,10]]}}}],["size=1g",{"_index":6962,"t":{"1475":{"position":[[111,7]]}}}],["size_iops_sec",{"_index":6552,"t":{"1351":{"position":[[3133,13]]}}}],["skeleton",{"_index":9725,"t":{"3059":{"position":[[49,9]]}}}],["skill",{"_index":1573,"t":{"235":{"position":[[453,6],[553,7]]}}}],["skip",{"_index":2760,"t":{"487":{"position":[[1628,5]]},"596":{"position":[[2382,7]]},"635":{"position":[[3985,4]]},"784":{"position":[[88,4]]},"1234":{"position":[[2495,4]]},"1286":{"position":[[2693,4]]},"1317":{"position":[[7896,7],[9000,7]]},"1360":{"position":[[478,4]]},"1521":{"position":[[88,4]]},"1571":{"position":[[31,4]]}}}],["skydiv",{"_index":8369,"t":{"2190":{"position":[[340,7]]},"2324":{"position":[[618,7]]}}}],["skylak",{"_index":9254,"t":{"2725":{"position":[[389,7],[426,7]]},"2733":{"position":[[141,8]]},"2764":{"position":[[610,7],[647,7]]},"2772":{"position":[[141,8]]},"2850":{"position":[[298,7],[335,7]]},"2854":{"position":[[141,8]]}}}],["skylin",{"_index":5981,"t":{"1195":{"position":[[0,7]]},"1197":{"position":[[0,7],[28,7]]},"1576":{"position":[[989,7],[1060,7]]},"1814":{"position":[[467,7]]}}}],["skyline_apiserver_external_fqdn",{"_index":5730,"t":{"1159":{"position":[[2944,31]]}}}],["skyline_apiserver_public_base_endpoint",{"_index":5729,"t":{"1159":{"position":[[2905,38]]}}}],["skyline_apiserver_public_port",{"_index":5731,"t":{"1159":{"position":[[3005,30]]}}}],["skyline_gunicorn_work",{"_index":5949,"t":{"1169":{"position":[[1612,24]]}}}],["sl",{"_index":6472,"t":{"1337":{"position":[[215,2],[304,2]]}}}],["sla",{"_index":9542,"t":{"2895":{"position":[[2654,5]]},"3393":{"position":[[768,3]]},"3400":{"position":[[1412,4],[1421,3]]}}}],["slack",{"_index":10058,"t":{"3299":{"position":[[1340,6],[1376,5],[2776,6],[2815,5]]},"3301":{"position":[[6014,6],[6039,6]]}}}],["slc",{"_index":9631,"t":{"2949":{"position":[[850,3]]}}}],["sleep",{"_index":4360,"t":{"903":{"position":[[3147,5]]},"913":{"position":[[3246,5]]},"1373":{"position":[[219,5]]},"1625":{"position":[[3147,5]]},"1635":{"position":[[3246,5]]},"1731":{"position":[[3151,6]]},"2350":{"position":[[3147,5]]},"2360":{"position":[[3246,5]]}}}],["slightli",{"_index":9229,"t":{"2719":{"position":[[967,8],[1020,8]]},"2735":{"position":[[33,8]]},"2758":{"position":[[965,8],[1018,8]]},"2774":{"position":[[169,8]]},"3184":{"position":[[1193,8]]}}}],["slot",{"_index":4710,"t":{"988":{"position":[[297,5],[339,5],[445,5]]}}}],["slow",{"_index":4473,"t":{"913":{"position":[[2608,4]]},"1635":{"position":[[2608,4]]},"2360":{"position":[[2608,4]]},"2944":{"position":[[1667,4]]},"3262":{"position":[[252,4]]},"3270":{"position":[[177,4]]},"3382":{"position":[[119,4]]}}}],["slow/network",{"_index":2791,"t":{"487":{"position":[[3087,14]]}}}],["slowdown",{"_index":9606,"t":{"2947":{"position":[[1848,9]]}}}],["slower",{"_index":3253,"t":{"615":{"position":[[810,6]]},"2947":{"position":[[2954,6]]},"3014":{"position":[[974,6]]}}}],["slug",{"_index":931,"t":{"143":{"position":[[287,5],[662,5]]}}}],["slugifi",{"_index":9008,"t":{"2625":{"position":[[542,9],[563,9],[1126,9],[1215,9]]},"2631":{"position":[[492,9],[1830,9]]}}}],["sm",{"_index":9284,"t":{"2727":{"position":[[89,3],[185,3]]},"2733":{"position":[[380,3]]},"2766":{"position":[[464,5],[1088,3]]},"2772":{"position":[[380,3]]},"2852":{"position":[[468,3],[564,3]]},"2854":{"position":[[381,3]]}}}],["small",{"_index":879,"t":{"135":{"position":[[109,5]]},"231":{"position":[[46,5]]},"317":{"position":[[776,5]]},"321":{"position":[[752,5]]},"853":{"position":[[33,5]]},"859":{"position":[[2200,5]]},"880":{"position":[[460,5]]},"909":{"position":[[2745,5]]},"911":{"position":[[30,5],[203,6]]},"1364":{"position":[[502,5]]},"1597":{"position":[[33,5]]},"1603":{"position":[[2200,5]]},"1631":{"position":[[2745,5]]},"1633":{"position":[[30,5],[203,6]]},"1695":{"position":[[109,5]]},"2356":{"position":[[2745,5]]},"2358":{"position":[[30,5],[203,6]]},"2514":{"position":[[361,5]]},"2711":{"position":[[852,5]]},"2856":{"position":[[830,5]]},"2933":{"position":[[255,5]]},"2949":{"position":[[211,5]]},"3063":{"position":[[1015,5]]},"3199":{"position":[[199,5]]},"3299":{"position":[[1090,5]]},"3316":{"position":[[70,5]]},"3380":{"position":[[87,5]]},"3410":{"position":[[130,5]]}}}],["smaller",{"_index":1868,"t":{"284":{"position":[[282,8]]},"485":{"position":[[837,8]]},"1041":{"position":[[260,7]]},"1080":{"position":[[830,7]]},"1562":{"position":[[606,7]]},"1825":{"position":[[993,7]]},"1835":{"position":[[442,7]]},"2719":{"position":[[856,7]]},"2758":{"position":[[854,7]]},"2764":{"position":[[1197,7]]},"2947":{"position":[[1630,9]]},"3184":{"position":[[2716,7]]}}}],["smallest",{"_index":9197,"t":{"2711":{"position":[[630,8]]},"2856":{"position":[[608,8]]},"2933":{"position":[[102,8]]}}}],["smart",{"_index":6847,"t":{"1411":{"position":[[30,5]]}}}],["smartctl",{"_index":6845,"t":{"1411":{"position":[[2,8]]}}}],["smartnic",{"_index":9700,"t":{"3014":{"position":[[742,9]]}}}],["smooth",{"_index":2170,"t":{"339":{"position":[[493,6]]},"652":{"position":[[880,6]]},"2281":{"position":[[574,6]]},"2709":{"position":[[445,6]]},"2735":{"position":[[681,6]]},"2754":{"position":[[445,6]]},"2844":{"position":[[373,6]]},"2947":{"position":[[4290,6]]}}}],["smoother",{"_index":3590,"t":{"696":{"position":[[94,8]]}}}],["smoothli",{"_index":8559,"t":{"2461":{"position":[[537,9]]}}}],["smt",{"_index":9126,"t":{"2705":{"position":[[143,5]]},"2750":{"position":[[143,5]]},"2840":{"position":[[51,5]]}}}],["smt/ht",{"_index":9130,"t":{"2705":{"position":[[447,6]]},"2750":{"position":[[447,6]]},"2840":{"position":[[355,6]]}}}],["smt/hyperthread",{"_index":5833,"t":{"1165":{"position":[[1926,19]]}}}],["sn",{"_index":5253,"t":{"1112":{"position":[[5222,3]]},"1114":{"position":[[2361,3],[5865,3]]}}}],["snack",{"_index":1468,"t":{"208":{"position":[[76,6]]},"212":{"position":[[149,6]]},"214":{"position":[[397,6],[421,6]]},"223":{"position":[[265,7],[375,7]]},"227":{"position":[[93,6],[131,8]]},"229":{"position":[[20,7]]},"231":{"position":[[22,6],[347,7]]}}}],["snap",{"_index":82,"t":{"10":{"position":[[159,4],[203,4]]},"485":{"position":[[1520,4],[1573,4]]},"604":{"position":[[239,6],[293,4]]},"617":{"position":[[655,5]]}}}],["snapclass",{"_index":2620,"t":{"471":{"position":[[1319,9]]}}}],["snapclass.yaml",{"_index":2615,"t":{"471":{"position":[[1104,14],[1149,14],[1479,14]]}}}],["snapshot",{"_index":2456,"t":{"421":{"position":[[570,9]]},"462":{"position":[[775,9],[801,8],[851,8],[1048,9],[1208,9],[1402,8]]},"465":{"position":[[19,8],[187,9],[244,10],[259,8],[350,8]]},"471":{"position":[[560,8],[928,8],[1032,10]]},"474":{"position":[[53,8],[942,8]]},"821":{"position":[[2952,12],[4290,12],[5607,12]]},"1511":{"position":[[2952,12],[4290,12],[5607,12]]},"1587":{"position":[[1025,9],[1185,10],[1207,8]]},"1872":{"position":[[425,8],[467,9]]},"1880":{"position":[[264,8]]},"1892":{"position":[[171,9],[243,9],[325,9],[445,8],[544,8],[646,8],[706,8],[1074,9],[1143,8]]},"1911":{"position":[[149,8],[656,8]]},"1913":{"position":[[1928,11]]},"1988":{"position":[[425,8],[467,9]]},"1996":{"position":[[264,8]]},"2008":{"position":[[171,9],[243,9],[325,9],[445,8],[544,8],[646,8],[706,8],[1074,9],[1143,8]]},"2027":{"position":[[149,8],[656,8]]},"2029":{"position":[[1928,11]]},"2229":{"position":[[518,8]]},"2405":{"position":[[836,9]]},"2424":{"position":[[206,9]]},"2463":{"position":[[1094,9]]},"3284":{"position":[[144,9]]}}}],["snapshot.cr",{"_index":8720,"t":{"2566":{"position":[[1691,20],[3536,20]]}}}],["snapshot.delet",{"_index":8721,"t":{"2566":{"position":[[1712,20],[3557,20]]}}}],["snapshot.exist",{"_index":8719,"t":{"2566":{"position":[[1672,18],[3517,18]]}}}],["snapshot.storage.k8s.io/v1",{"_index":2616,"t":{"471":{"position":[[1183,26]]}}}],["snapshot.transfer.accept.end",{"_index":8724,"t":{"2566":{"position":[[1784,31],[2456,31],[2723,32]]}}}],["snapshot.upd",{"_index":8722,"t":{"2566":{"position":[[1733,20],[3578,20]]}}}],["snapshot_id",{"_index":8747,"t":{"2566":{"position":[[3077,12]]}}}],["snapshot_nam",{"_index":7936,"t":{"1892":{"position":[[588,14],[715,14],[1159,14]]},"2008":{"position":[[588,14],[715,14],[1159,14]]}}}],["snapshots=fals",{"_index":2474,"t":{"427":{"position":[[646,15]]},"471":{"position":[[1714,15]]}}}],["snat",{"_index":4329,"t":{"903":{"position":[[498,6]]},"1625":{"position":[[498,6]]},"2350":{"position":[[498,6]]}}}],["sneak",{"_index":7891,"t":{"1851":{"position":[[41,5]]}}}],["snowflak",{"_index":4303,"t":{"895":{"position":[[571,9]]},"936":{"position":[[19,10]]},"1617":{"position":[[571,9]]},"1658":{"position":[[19,10]]},"2342":{"position":[[571,9]]},"2383":{"position":[[19,10]]}}}],["socat",{"_index":3371,"t":{"635":{"position":[[2387,8],[2893,8]]},"1014":{"position":[[452,5]]}}}],["social",{"_index":1376,"t":{"193":{"position":[[17,6]]},"202":{"position":[[368,6]]},"210":{"position":[[423,6]]},"214":{"position":[[201,7]]},"233":{"position":[[203,6]]},"245":{"position":[[1158,6]]},"247":{"position":[[507,6],[2608,6]]}}}],["socket",{"_index":1456,"t":{"206":{"position":[[404,7]]},"982":{"position":[[764,7],[809,6]]},"984":{"position":[[629,7]]},"986":{"position":[[411,7]]},"990":{"position":[[532,6]]},"1562":{"position":[[125,6]]}}}],["sockets/cor",{"_index":4724,"t":{"995":{"position":[[353,13]]}}}],["soft",{"_index":2777,"t":{"487":{"position":[[2340,5]]},"3182":{"position":[[1424,6],[1594,4]]},"3184":{"position":[[88,4]]}}}],["softwar",{"_index":1013,"t":{"166":{"position":[[152,8],[269,8],[1126,9]]},"168":{"position":[[198,8],[404,9],[591,8],[659,8],[696,9]]},"170":{"position":[[38,8],[1157,8],[2079,8]]},"172":{"position":[[295,8],[352,8],[571,8],[625,8]]},"176":{"position":[[5,8],[114,8],[164,8],[226,8],[295,8],[406,8],[539,8],[635,8],[774,8],[1362,8],[1681,8]]},"178":{"position":[[837,8]]},"235":{"position":[[52,8],[330,8],[894,8]]},"240":{"position":[[32,8],[203,8]]},"253":{"position":[[1417,8]]},"284":{"position":[[0,8]]},"333":{"position":[[119,9],[138,8]]},"379":{"position":[[123,9],[213,8]]},"505":{"position":[[1148,8]]},"604":{"position":[[7504,8],[9214,8]]},"609":{"position":[[2272,8],[5127,8]]},"692":{"position":[[9,8]]},"772":{"position":[[752,8]]},"865":{"position":[[50,8],[135,8]]},"878":{"position":[[50,8],[135,8]]},"880":{"position":[[23,8]]},"901":{"position":[[145,8]]},"977":{"position":[[160,8],[2312,9]]},"1184":{"position":[[463,8]]},"1234":{"position":[[1471,8],[2942,8],[2988,8]]},"1623":{"position":[[145,8]]},"1816":{"position":[[129,8],[572,8]]},"1947":{"position":[[109,9],[128,8]]},"2081":{"position":[[584,8]]},"2100":{"position":[[259,9]]},"2116":{"position":[[178,8]]},"2162":{"position":[[527,9]]},"2196":{"position":[[558,8],[800,8]]},"2200":{"position":[[13,8]]},"2206":{"position":[[188,8]]},"2235":{"position":[[193,8],[260,8],[825,8]]},"2250":{"position":[[632,8]]},"2283":{"position":[[1131,8]]},"2312":{"position":[[713,8]]},"2348":{"position":[[145,8]]},"2497":{"position":[[69,8]]},"2647":{"position":[[1427,8]]},"2671":{"position":[[532,8],[582,8],[634,8],[872,8]]},"2673":{"position":[[954,9]]},"2901":{"position":[[750,8]]},"3011":{"position":[[2438,8]]},"3016":{"position":[[387,8]]},"3154":{"position":[[577,8]]},"3158":{"position":[[349,8]]},"3160":{"position":[[2497,8]]},"3195":{"position":[[122,8]]},"3247":{"position":[[777,8]]},"3299":{"position":[[933,9],[5264,8],[5378,8],[5414,8]]},"3301":{"position":[[269,8],[407,8]]},"3303":{"position":[[119,8]]},"3314":{"position":[[52,8]]},"3389":{"position":[[637,8]]},"3391":{"position":[[266,8]]},"3393":{"position":[[1152,8]]},"3518":{"position":[[76,8]]}}}],["sole",{"_index":2031,"t":{"323":{"position":[[285,6]]},"1963":{"position":[[691,6]]},"2053":{"position":[[555,6]]},"2962":{"position":[[218,6]]},"3472":{"position":[[14563,6]]}}}],["solid",{"_index":8189,"t":{"2098":{"position":[[2552,5]]},"2944":{"position":[[724,5]]},"2947":{"position":[[5079,5],[5242,5]]},"2949":{"position":[[194,5]]},"2966":{"position":[[504,5]]},"3186":{"position":[[79,5]]},"3238":{"position":[[88,5]]},"3410":{"position":[[241,5]]}}}],["solut",{"_index":1816,"t":{"268":{"position":[[224,9]]},"290":{"position":[[392,10]]},"298":{"position":[[99,10]]},"300":{"position":[[291,10]]},"327":{"position":[[75,8]]},"335":{"position":[[1164,8]]},"465":{"position":[[462,9]]},"507":{"position":[[288,8]]},"513":{"position":[[1039,8]]},"596":{"position":[[682,8]]},"598":{"position":[[100,8]]},"637":{"position":[[27,8]]},"716":{"position":[[187,10]]},"764":{"position":[[242,9]]},"768":{"position":[[43,9]]},"888":{"position":[[187,8],[2138,8]]},"895":{"position":[[1846,8]]},"977":{"position":[[360,8],[2011,10],[2342,9]]},"1617":{"position":[[1846,8]]},"1734":{"position":[[319,9]]},"1937":{"position":[[394,10]]},"1955":{"position":[[600,9]]},"1970":{"position":[[34,9]]},"1982":{"position":[[1575,10]]},"1984":{"position":[[1185,10]]},"2043":{"position":[[890,9]]},"2067":{"position":[[1527,8]]},"2069":{"position":[[200,8]]},"2071":{"position":[[111,9]]},"2091":{"position":[[33,8],[168,8]]},"2093":{"position":[[173,9],[279,9]]},"2096":{"position":[[1705,8]]},"2100":{"position":[[339,8],[417,8],[672,8],[697,8],[848,9]]},"2122":{"position":[[67,8],[229,9],[587,8]]},"2126":{"position":[[24,8]]},"2132":{"position":[[102,9]]},"2148":{"position":[[713,8]]},"2154":{"position":[[53,8],[255,8],[423,8],[489,9],[635,9],[718,8],[803,8],[1197,8]]},"2158":{"position":[[85,9]]},"2176":{"position":[[273,8],[462,9]]},"2224":{"position":[[223,8]]},"2226":{"position":[[129,8]]},"2248":{"position":[[623,8]]},"2265":{"position":[[61,8]]},"2283":{"position":[[79,9],[478,9],[616,9]]},"2298":{"position":[[61,8]]},"2315":{"position":[[1164,8]]},"2319":{"position":[[113,8]]},"2342":{"position":[[1846,8]]},"2405":{"position":[[34,8]]},"2407":{"position":[[315,8],[411,9]]},"2476":{"position":[[602,9]]},"2504":{"position":[[624,8]]},"2944":{"position":[[294,8]]},"2957":{"position":[[320,9]]},"3150":{"position":[[468,9]]},"3154":{"position":[[586,9]]},"3156":{"position":[[78,9]]},"3158":{"position":[[315,10]]},"3160":{"position":[[2506,8],[2576,8],[2873,10]]},"3162":{"position":[[429,8]]},"3204":{"position":[[86,8]]},"3208":{"position":[[12,8],[33,8],[139,8],[420,8],[527,8],[650,8],[958,8],[1094,8],[1107,8],[1365,8],[1623,8]]},"3210":{"position":[[13,8],[93,8],[280,8],[425,8],[541,8],[674,8],[804,8],[921,8]]},"3218":{"position":[[1463,8]]},"3220":{"position":[[320,10],[506,9]]},"3222":{"position":[[524,8]]},"3245":{"position":[[361,8]]},"3247":{"position":[[786,9]]},"3249":{"position":[[817,8]]},"3251":{"position":[[42,8]]},"3276":{"position":[[2495,8]]},"3301":{"position":[[1540,9],[2055,8],[2773,9],[4946,9],[5436,8]]},"3303":{"position":[[128,9]]},"3308":{"position":[[585,9]]},"3391":{"position":[[500,8]]},"3434":{"position":[[499,9]]}}}],["solv",{"_index":3294,"t":{"627":{"position":[[3341,6]]},"1477":{"position":[[161,5]]},"1723":{"position":[[45,5]]},"1805":{"position":[[195,5]]},"1943":{"position":[[401,6]]},"2673":{"position":[[568,6]]},"2955":{"position":[[322,5]]},"3069":{"position":[[463,6]]},"3115":{"position":[[142,5]]},"3184":{"position":[[986,6]]}}}],["some_job",{"_index":2064,"t":{"325":{"position":[[2571,8]]}}}],["some_secret_pass",{"_index":4563,"t":{"932":{"position":[[1244,16],[1845,16]]},"1654":{"position":[[1244,16],[1845,16]]},"2379":{"position":[[1244,16],[1845,16]]}}}],["somebodi",{"_index":9517,"t":{"2886":{"position":[[431,8]]}}}],["someexample.yaml",{"_index":4151,"t":{"850":{"position":[[9026,16]]},"1484":{"position":[[9026,16]]}}}],["somehow",{"_index":1301,"t":{"178":{"position":[[2577,7]]},"633":{"position":[[647,7]]},"1972":{"position":[[978,7]]}}}],["someon",{"_index":1632,"t":{"245":{"position":[[1522,7]]},"247":{"position":[[1898,7],[2968,7]]},"2886":{"position":[[404,7]]}}}],["someth",{"_index":1825,"t":{"272":{"position":[[61,9]]},"313":{"position":[[419,9]]},"325":{"position":[[1381,9],[2321,9],[2481,9],[3668,9]]},"391":{"position":[[670,9]]},"909":{"position":[[1870,9]]},"911":{"position":[[1189,9]]},"949":{"position":[[46,9]]},"1112":{"position":[[1130,11]]},"1574":{"position":[[193,9]]},"1631":{"position":[[1870,9]]},"1633":{"position":[[1189,9]]},"1671":{"position":[[46,9]]},"1684":{"position":[[70,9]]},"1690":{"position":[[1924,9]]},"1803":{"position":[[25,9]]},"1833":{"position":[[821,9]]},"1957":{"position":[[3144,9]]},"1972":{"position":[[1169,9]]},"2356":{"position":[[1870,9]]},"2358":{"position":[[1189,9]]},"2396":{"position":[[46,9]]},"2647":{"position":[[810,9]]},"2697":{"position":[[1246,9]]},"2742":{"position":[[1145,9]]},"2947":{"position":[[1545,9]]},"2966":{"position":[[3298,9]]},"3314":{"position":[[3337,9]]}}}],["sometim",{"_index":1049,"t":{"168":{"position":[[53,9]]},"170":{"position":[[294,9]]},"178":{"position":[[992,9]]},"550":{"position":[[151,9]]},"770":{"position":[[399,9]]},"905":{"position":[[1663,9],[2079,9]]},"911":{"position":[[788,9]]},"932":{"position":[[2697,10]]},"947":{"position":[[247,9]]},"1067":{"position":[[3132,10]]},"1156":{"position":[[0,9]]},"1165":{"position":[[340,9]]},"1292":{"position":[[38,9]]},"1344":{"position":[[0,9]]},"1627":{"position":[[1663,9],[2079,9]]},"1633":{"position":[[788,9]]},"1654":{"position":[[2697,10]]},"1669":{"position":[[247,9]]},"1731":{"position":[[0,9]]},"1758":{"position":[[0,9]]},"2352":{"position":[[1663,9],[2079,9]]},"2358":{"position":[[788,9]]},"2379":{"position":[[2697,10]]},"2394":{"position":[[247,9]]},"2623":{"position":[[304,9]]},"2901":{"position":[[151,9]]},"2960":{"position":[[1398,9]]},"2966":{"position":[[1002,9]]},"3245":{"position":[[317,9]]}}}],["somewhat",{"_index":3156,"t":{"604":{"position":[[10970,8]]},"2947":{"position":[[1471,9]]}}}],["somewher",{"_index":7782,"t":{"1841":{"position":[[542,9]]}}}],["sonic",{"_index":4265,"t":{"865":{"position":[[174,5]]},"878":{"position":[[174,5]]},"2526":{"position":[[761,5]]},"2534":{"position":[[64,5]]},"2999":{"position":[[0,5],[255,5],[420,6],[467,5],[584,5]]},"3001":{"position":[[88,5]]},"3003":{"position":[[371,5]]},"3005":{"position":[[116,5]]},"3007":{"position":[[155,5],[307,5]]},"3009":{"position":[[25,5]]},"3011":{"position":[[30,6],[98,6],[190,5],[380,5],[517,5],[611,6],[875,6],[981,6],[1012,5],[1061,5],[1141,5],[1319,5],[1398,5],[1513,5],[1603,5],[1665,5],[1854,5],[1936,5],[2133,6],[2312,5],[2394,5],[2474,5],[2625,5],[2705,5],[2768,5],[2799,5],[2838,5]]},"3014":{"position":[[703,5],[894,5],[914,5]]},"3016":{"position":[[90,5],[286,6],[452,5],[527,5],[644,5]]},"3018":{"position":[[33,5],[52,5]]},"3518":{"position":[[889,5]]}}}],["sonobuoy",{"_index":2666,"t":{"479":{"position":[[76,8]]},"495":{"position":[[171,8],[767,8],[1064,8],[1648,8]]},"499":{"position":[[772,8],[907,8],[1131,8]]},"513":{"position":[[2039,10]]},"557":{"position":[[86,9]]},"559":{"position":[[79,8]]},"561":{"position":[[85,8]]},"563":{"position":[[81,8]]},"565":{"position":[[77,8]]},"604":{"position":[[11345,8]]},"615":{"position":[[232,8]]},"627":{"position":[[5459,9]]},"669":{"position":[[673,8],[969,8],[1009,8]]},"2229":{"position":[[656,8]]},"2233":{"position":[[323,8]]},"2265":{"position":[[117,9]]},"2298":{"position":[[117,9]]},"2592":{"position":[[512,8]]},"3053":{"position":[[158,8],[368,8],[432,8],[698,9],[715,8]]},"3055":{"position":[[22,8],[101,8],[197,8],[582,8]]},"3057":{"position":[[43,8],[244,8]]},"3059":{"position":[[1103,8],[1282,8],[1399,8]]},"3061":{"position":[[13,8],[1392,8]]},"3063":{"position":[[0,8],[279,8],[697,8],[1090,9]]},"3065":{"position":[[55,8]]},"3071":{"position":[[542,8],[1360,8],[1515,8],[1546,8],[2505,8],[2754,8]]},"3518":{"position":[[1543,8]]}}}],["sonobuoy.sh",{"_index":3578,"t":{"669":{"position":[[868,11]]}}}],["sonomod",{"_index":2981,"t":{"557":{"position":[[11,12],[221,10]]}}}],["soon",{"_index":1134,"t":{"170":{"position":[[1241,4]]},"172":{"position":[[248,4]]},"347":{"position":[[417,6]]},"1904":{"position":[[782,4]]},"2020":{"position":[[782,4]]},"2031":{"position":[[401,4]]},"2098":{"position":[[171,5]]},"2315":{"position":[[1173,5]]},"2330":{"position":[[995,5]]},"2520":{"position":[[589,6]]},"2957":{"position":[[117,4]]},"2960":{"position":[[729,4]]},"3074":{"position":[[467,4]]},"3109":{"position":[[3106,4]]},"3124":{"position":[[218,4]]},"3442":{"position":[[106,4]]}}}],["sop",{"_index":6953,"t":{"1473":{"position":[[1216,4]]}}}],["sort",{"_index":1052,"t":{"168":{"position":[[138,5]]},"819":{"position":[[1603,7]]},"821":{"position":[[1055,7]]},"859":{"position":[[1119,7],[6576,7]]},"913":{"position":[[1074,4],[1184,4],[1259,4],[1333,4],[1408,4],[1488,4],[1562,4],[1644,4],[2076,4]]},"1509":{"position":[[1603,7]]},"1511":{"position":[[1055,7]]},"1603":{"position":[[1119,7],[6576,7]]},"1635":{"position":[[1074,4],[1184,4],[1259,4],[1333,4],[1408,4],[1488,4],[1562,4],[1644,4],[2076,4]]},"1972":{"position":[[240,4],[1136,4]]},"1976":{"position":[[584,4]]},"2360":{"position":[[1074,4],[1184,4],[1259,4],[1333,4],[1408,4],[1488,4],[1562,4],[1644,4],[2076,4]]},"2522":{"position":[[127,6]]},"2795":{"position":[[319,6]]},"3029":{"position":[[491,6]]},"3050":{"position":[[220,8]]},"3160":{"position":[[1575,4]]},"3314":{"position":[[2930,6]]}}}],["sound",{"_index":9627,"t":{"2947":{"position":[[4366,6]]},"3078":{"position":[[137,8]]}}}],["sourc",{"_index":126,"t":{"10":{"position":[[969,6],[1519,6]]},"69":{"position":[[281,6]]},"114":{"position":[[145,9],[291,6],[528,6]]},"143":{"position":[[949,7]]},"166":{"position":[[437,6]]},"168":{"position":[[1303,6]]},"170":{"position":[[343,6],[1064,6],[1292,6],[1667,6],[1800,6],[1933,6],[2190,6]]},"174":{"position":[[169,6]]},"176":{"position":[[185,6],[369,6],[698,6],[1355,6],[1468,6],[1587,6]]},"178":{"position":[[14,6],[370,6],[521,6],[2365,7]]},"180":{"position":[[30,6]]},"182":{"position":[[220,6]]},"184":{"position":[[15,6]]},"193":{"position":[[563,8]]},"235":{"position":[[113,6],[258,6]]},"240":{"position":[[5,7],[13,6]]},"253":{"position":[[372,6],[534,6],[692,6],[1210,6],[1328,6]]},"335":{"position":[[1218,6]]},"342":{"position":[[141,6]]},"366":{"position":[[368,6],[1270,6]]},"368":{"position":[[388,6]]},"415":{"position":[[182,6]]},"421":{"position":[[1299,6],[1475,6]]},"467":{"position":[[446,8],[478,6],[2264,6],[2302,6]]},"469":{"position":[[95,6]]},"489":{"position":[[540,7]]},"503":{"position":[[784,6]]},"590":{"position":[[1874,6]]},"694":{"position":[[62,6]]},"728":{"position":[[493,6]]},"766":{"position":[[9,6]]},"768":{"position":[[16,6]]},"790":{"position":[[363,10]]},"833":{"position":[[45,6],[148,6]]},"835":{"position":[[41,6],[131,6]]},"880":{"position":[[16,6],[808,7]]},"932":{"position":[[1302,7]]},"949":{"position":[[1041,6]]},"954":{"position":[[9,6]]},"970":{"position":[[85,7]]},"977":{"position":[[52,6],[2450,6]]},"1167":{"position":[[203,7],[338,8],[3486,9],[4218,9],[4855,9]]},"1282":{"position":[[57,6]]},"1286":{"position":[[652,6]]},"1364":{"position":[[956,7]]},"1489":{"position":[[493,6]]},"1527":{"position":[[363,10]]},"1548":{"position":[[45,6],[148,6]]},"1550":{"position":[[41,6],[131,6]]},"1654":{"position":[[1302,7]]},"1671":{"position":[[1041,6]]},"1749":{"position":[[889,7]]},"1794":{"position":[[1181,6]]},"1827":{"position":[[461,6]]},"1829":{"position":[[0,7]]},"1843":{"position":[[98,6]]},"1865":{"position":[[819,6]]},"1892":{"position":[[672,7]]},"1906":{"position":[[105,7],[479,6]]},"1908":{"position":[[1957,6],[2474,6]]},"1913":{"position":[[2038,6]]},"1951":{"position":[[772,6]]},"1970":{"position":[[27,6]]},"1972":{"position":[[34,6]]},"2008":{"position":[[672,7]]},"2022":{"position":[[105,7],[479,6]]},"2024":{"position":[[1957,6],[2474,6]]},"2033":{"position":[[438,7]]},"2096":{"position":[[1538,6],[1641,6]]},"2098":{"position":[[429,7],[533,6],[823,6],[1205,6],[2265,7]]},"2118":{"position":[[744,6]]},"2152":{"position":[[198,6]]},"2235":{"position":[[79,6]]},"2248":{"position":[[1244,6]]},"2294":{"position":[[139,6]]},"2306":{"position":[[378,6]]},"2338":{"position":[[334,6]]},"2379":{"position":[[1302,7]]},"2434":{"position":[[325,6]]},"2540":{"position":[[429,7]]},"2562":{"position":[[106,7]]},"2564":{"position":[[4,8],[38,7]]},"2568":{"position":[[4,8],[36,7]]},"2570":{"position":[[4,8]]},"2872":{"position":[[62,7],[909,7],[977,7]]},"2874":{"position":[[66,7],[363,7],[988,7]]},"2876":{"position":[[22,7]]},"2897":{"position":[[428,7]]},"2975":{"position":[[274,8]]},"2977":{"position":[[237,6]]},"2983":{"position":[[141,6],[169,6],[576,7]]},"2985":{"position":[[266,6],[294,6],[753,7]]},"2987":{"position":[[31,7],[233,7],[415,7],[534,7],[665,7],[808,6]]},"2990":{"position":[[392,6]]},"3005":{"position":[[198,6]]},"3128":{"position":[[896,7],[1009,7]]},"3158":{"position":[[251,6],[439,7]]},"3195":{"position":[[202,6]]},"3251":{"position":[[99,6],[153,6],[1374,8]]},"3293":{"position":[[454,7]]},"3295":{"position":[[174,6]]},"3299":{"position":[[11,6],[1174,6],[2660,6],[3880,6],[4229,6]]},"3301":{"position":[[46,6],[206,6],[262,6],[400,6],[1024,6],[1660,6],[2600,6],[3499,6],[4073,7],[4569,6]]},"3376":{"position":[[837,6]]},"3518":{"position":[[69,6]]}}}],["source=manager_share,target=/shar",{"_index":7311,"t":{"1731":{"position":[[380,34],[772,34]]}}}],["source_software_lic",{"_index":1315,"t":{"182":{"position":[[58,24]]}}}],["source_volume_id",{"_index":7975,"t":{"1908":{"position":[[2396,19]]},"2024":{"position":[[2396,19]]}}}],["source_volume_id=\"$(openstack",{"_index":7974,"t":{"1908":{"position":[[2273,29]]},"2024":{"position":[[2273,29]]}}}],["south",{"_index":8523,"t":{"2403":{"position":[[236,5]]}}}],["sovereign",{"_index":0,"t":{"4":{"position":[[0,9]]},"101":{"position":[[366,9]]},"166":{"position":[[3,9]]},"235":{"position":[[0,9],[961,9]]},"245":{"position":[[0,9],[174,9]]},"253":{"position":[[183,9],[1263,9]]},"274":{"position":[[161,9]]},"327":{"position":[[31,9]]},"342":{"position":[[4,9]]},"366":{"position":[[51,9],[651,10],[742,9],[1694,9]]},"690":{"position":[[4,9],[127,9]]},"780":{"position":[[647,9],[752,9]]},"1770":{"position":[[53,9],[248,9]]},"1937":{"position":[[0,9]]},"2493":{"position":[[62,9],[126,9]]},"2514":{"position":[[4,9]]},"2522":{"position":[[230,9],[420,9]]},"2524":{"position":[[129,9]]},"2526":{"position":[[133,9],[543,9],[639,9]]},"2530":{"position":[[82,9]]},"2548":{"position":[[75,9]]},"2576":{"position":[[100,9]]},"2617":{"position":[[4,9],[127,9]]},"2621":{"position":[[53,9]]},"2651":{"position":[[125,9]]},"2663":{"position":[[4,9]]},"2684":{"position":[[4,9]]},"2795":{"position":[[4,9],[127,9],[422,9],[612,9]]},"2975":{"position":[[4,9],[127,9]]},"3413":{"position":[[4,9]]},"3518":{"position":[[643,9],[753,9]]}}}],["sovereigncloudstack",{"_index":202,"t":{"14":{"position":[[10,19]]},"23":{"position":[[210,19]]},"276":{"position":[[0,19]]},"290":{"position":[[0,19]]},"325":{"position":[[5349,19]]},"355":{"position":[[99,19]]},"932":{"position":[[4306,19]]},"1654":{"position":[[4306,19]]},"2209":{"position":[[190,19]]},"2379":{"position":[[4306,19]]},"2631":{"position":[[156,19],[1591,19]]}}}],["sovereigncloudstack/clust",{"_index":2333,"t":{"393":{"position":[[951,27]]}}}],["sovereigncloudstack/doc",{"_index":640,"t":{"105":{"position":[[40,24],[883,24]]},"1865":{"position":[[863,24]]},"1913":{"position":[[2082,24]]}}}],["sovereigncloudstack/k8",{"_index":2098,"t":{"325":{"position":[[5646,23]]}}}],["sovereigncloudstack/openstack",{"_index":4650,"t":{"949":{"position":[[1085,29]]},"1671":{"position":[[1085,29]]}}}],["sovereigncloudstack/plusserv",{"_index":230,"t":{"18":{"position":[[249,32]]}}}],["sovereigncloudstack/repo",{"_index":2081,"t":{"325":{"position":[[4216,24]]}}}],["sovereigncloudstack/vp06c",{"_index":399,"t":{"37":{"position":[[24,26]]},"40":{"position":[[28,26]]}}}],["sovereigncloudstack/wavecon",{"_index":231,"t":{"18":{"position":[[282,29]]}}}],["sovereignit.cloud",{"_index":4556,"t":{"932":{"position":[[813,17]]},"1654":{"position":[[813,17]]},"2379":{"position":[[813,17]]}}}],["sovereignti",{"_index":583,"t":{"79":{"position":[[420,12]]},"235":{"position":[[167,12]]},"366":{"position":[[205,12],[1249,11]]},"368":{"position":[[331,11]]},"2514":{"position":[[284,11]]}}}],["spa",{"_index":10136,"t":{"3316":{"position":[[1326,3]]}}}],["space",{"_index":31,"t":{"4":{"position":[[380,5]]},"202":{"position":[[322,5]]},"204":{"position":[[50,6]]},"206":{"position":[[0,5],[24,5]]},"212":{"position":[[77,5]]},"257":{"position":[[34,5]]},"355":{"position":[[128,6]]},"977":{"position":[[855,7]]},"1112":{"position":[[1296,5]]},"1252":{"position":[[771,5]]},"1571":{"position":[[385,5],[538,5]]},"1587":{"position":[[587,5],[703,6],[889,5]]},"1831":{"position":[[248,5]]},"3272":{"position":[[621,5],[734,5]]},"3274":{"position":[[125,5]]},"3282":{"position":[[95,6]]}}}],["span",{"_index":3504,"t":{"654":{"position":[[265,4]]},"2144":{"position":[[197,5]]},"3251":{"position":[[2478,4]]}}}],["spare",{"_index":9685,"t":{"3007":{"position":[[220,5]]}}}],["sparingli",{"_index":6835,"t":{"1404":{"position":[[123,9]]}}}],["spawn",{"_index":2128,"t":{"327":{"position":[[515,5]]},"407":{"position":[[100,5]]},"417":{"position":[[863,7]]},"432":{"position":[[100,5]]},"487":{"position":[[4249,6]]},"495":{"position":[[224,7],[740,6],[1111,7],[1621,6]]},"604":{"position":[[7215,8],[8872,8]]}}}],["spdx",{"_index":1901,"t":{"286":{"position":[[288,4]]},"1678":{"position":[[1366,4]]},"2235":{"position":[[719,4]]}}}],["speak",{"_index":4519,"t":{"922":{"position":[[1001,6]]},"1644":{"position":[[1001,6]]},"2369":{"position":[[1001,6]]},"3103":{"position":[[204,6]]}}}],["speaker",{"_index":1756,"t":{"251":{"position":[[324,8]]}}}],["spec",{"_index":408,"t":{"37":{"position":[[131,5]]},"40":{"position":[[129,5]]},"427":{"position":[[1273,5]]},"604":{"position":[[9890,6]]},"660":{"position":[[745,5],[1126,5],[1142,5],[1654,5]]},"2033":{"position":[[332,5],[1489,5],[1651,5]]},"2176":{"position":[[602,4]]},"2472":{"position":[[253,4]]},"2550":{"position":[[304,5]]},"2627":{"position":[[398,5]]},"2647":{"position":[[1382,5],[1396,4]]},"2660":{"position":[[152,5]]},"2729":{"position":[[113,5]]},"2766":{"position":[[1176,5]]},"2768":{"position":[[136,5]]},"2886":{"position":[[339,4]]},"2923":{"position":[[20,5],[489,5]]},"2935":{"position":[[237,5],[385,5]]},"2947":{"position":[[5632,4]]},"2951":{"position":[[689,4],[1142,4],[1270,4]]},"2953":{"position":[[332,4]]},"2957":{"position":[[109,4]]},"2966":{"position":[[1625,5],[1839,5]]},"3090":{"position":[[4,4]]},"3301":{"position":[[7230,4]]},"3336":{"position":[[27,4]]},"3340":{"position":[[4,4]]},"3367":{"position":[[8,4]]},"3403":{"position":[[79,4]]},"3408":{"position":[[146,5]]},"3482":{"position":[[2768,5]]}}}],["spec.identityref",{"_index":2351,"t":{"398":{"position":[[139,16]]}}}],["spec.imag",{"_index":2352,"t":{"398":{"position":[[186,10]]}}}],["spec.mandatoryflavors.yaml",{"_index":9636,"t":{"2957":{"position":[[82,26]]}}}],["spec.topolog",{"_index":3562,"t":{"662":{"position":[[1090,14]]}}}],["specfiy",{"_index":7934,"t":{"1886":{"position":[[261,10]]},"2002":{"position":[[261,10]]}}}],["special",{"_index":553,"t":{"75":{"position":[[4,7]]},"79":{"position":[[8,7]]},"193":{"position":[[387,7]]},"202":{"position":[[425,7]]},"210":{"position":[[696,8]]},"225":{"position":[[221,7]]},"331":{"position":[[396,11]]},"503":{"position":[[145,7]]},"646":{"position":[[1273,7]]},"662":{"position":[[557,7],[737,7]]},"756":{"position":[[210,7]]},"819":{"position":[[6575,7],[6610,7],[7926,7],[7962,7]]},"1055":{"position":[[324,7]]},"1120":{"position":[[275,7]]},"1150":{"position":[[6030,7]]},"1226":{"position":[[553,11]]},"1469":{"position":[[10,7]]},"1509":{"position":[[6575,7],[6610,7],[7926,7],[7962,7]]},"2037":{"position":[[55,7]]},"2315":{"position":[[160,7]]},"2338":{"position":[[75,7]]},"2675":{"position":[[536,7]]},"2727":{"position":[[701,7]]},"2766":{"position":[[901,7],[1128,9]]},"2852":{"position":[[1047,7]]},"2874":{"position":[[665,7]]},"2890":{"position":[[225,7]]},"2911":{"position":[[138,7]]},"2966":{"position":[[719,7],[931,7]]},"3023":{"position":[[14,7]]},"3180":{"position":[[14,7]]},"3224":{"position":[[433,11]]},"3264":{"position":[[14,7]]},"3343":{"position":[[316,7]]},"3400":{"position":[[1821,7]]},"3455":{"position":[[14,7]]},"3457":{"position":[[207,7]]},"3465":{"position":[[340,7],[453,7]]},"3472":{"position":[[5873,7]]}}}],["specialis",{"_index":10192,"t":{"3372":{"position":[[46,11]]}}}],["specif",{"_index":168,"t":{"10":{"position":[[1713,8]]},"25":{"position":[[58,8]]},"105":{"position":[[119,8]]},"168":{"position":[[471,12]]},"191":{"position":[[190,8]]},"300":{"position":[[464,8]]},"302":{"position":[[904,8]]},"325":{"position":[[7724,8]]},"363":{"position":[[277,8]]},"366":{"position":[[277,14]]},"372":{"position":[[355,8]]},"374":{"position":[[1316,8]]},"393":{"position":[[1588,8]]},"467":{"position":[[770,8]]},"471":{"position":[[413,9]]},"474":{"position":[[173,8]]},"493":{"position":[[1906,8]]},"499":{"position":[[606,8]]},"505":{"position":[[501,12]]},"530":{"position":[[360,8]]},"586":{"position":[[354,8]]},"592":{"position":[[234,8]]},"604":{"position":[[5754,8],[8450,12],[10500,8],[10690,8],[10806,8]]},"619":{"position":[[9,8]]},"732":{"position":[[279,8]]},"736":{"position":[[209,8]]},"742":{"position":[[365,14]]},"794":{"position":[[214,8],[324,8]]},"821":{"position":[[1994,8]]},"853":{"position":[[216,8]]},"883":{"position":[[1676,8]]},"888":{"position":[[2155,8]]},"895":{"position":[[224,8]]},"956":{"position":[[1132,8],[1462,8],[2440,8]]},"980":{"position":[[88,13]]},"1025":{"position":[[166,8]]},"1043":{"position":[[623,8],[716,8],[816,8]]},"1052":{"position":[[25,12]]},"1077":{"position":[[255,8]]},"1080":{"position":[[1035,8]]},"1120":{"position":[[1047,8]]},"1124":{"position":[[254,8]]},"1150":{"position":[[9160,8]]},"1156":{"position":[[68,8],[90,8],[269,8],[370,8],[389,8]]},"1184":{"position":[[2438,12]]},"1234":{"position":[[1368,14]]},"1244":{"position":[[241,8]]},"1252":{"position":[[306,8]]},"1286":{"position":[[342,8]]},"1292":{"position":[[222,8],[252,8]]},"1323":{"position":[[67,8]]},"1325":{"position":[[389,8]]},"1327":{"position":[[23,8],[96,8],[119,8]]},"1329":{"position":[[19,8],[89,8],[108,8]]},"1331":{"position":[[61,8]]},"1349":{"position":[[233,8]]},"1430":{"position":[[1996,8]]},"1493":{"position":[[279,8]]},"1511":{"position":[[1994,8]]},"1531":{"position":[[214,8],[324,8]]},"1591":{"position":[[718,8]]},"1594":{"position":[[235,8]]},"1597":{"position":[[216,8]]},"1617":{"position":[[224,8]]},"1749":{"position":[[1607,8]]},"1779":{"position":[[919,8],[974,8]]},"1825":{"position":[[1198,8]]},"1833":{"position":[[1418,8]]},"1853":{"position":[[150,8],[240,8]]},"1855":{"position":[[199,12],[1147,8]]},"1915":{"position":[[150,8],[240,8]]},"1917":{"position":[[199,12],[1147,8]]},"1943":{"position":[[49,8]]},"1951":{"position":[[240,8],[427,8]]},"1976":{"position":[[24,8]]},"1978":{"position":[[278,8]]},"2075":{"position":[[381,14],[500,8]]},"2079":{"position":[[344,8]]},"2106":{"position":[[283,8]]},"2286":{"position":[[154,12]]},"2315":{"position":[[770,13]]},"2342":{"position":[[224,8]]},"2476":{"position":[[298,8],[480,8]]},"2484":{"position":[[320,8]]},"2506":{"position":[[304,8]]},"2544":{"position":[[73,14]]},"2550":{"position":[[57,14],[216,8],[384,15]]},"2627":{"position":[[786,8]]},"2647":{"position":[[1411,8],[1503,9]]},"2673":{"position":[[398,8]]},"2675":{"position":[[1098,14]]},"2697":{"position":[[1047,13]]},"2713":{"position":[[668,13],[765,8]]},"2715":{"position":[[147,13]]},"2719":{"position":[[419,8]]},"2725":{"position":[[41,8],[133,8]]},"2731":{"position":[[322,8],[954,8],[1223,8]]},"2742":{"position":[[946,13]]},"2754":{"position":[[739,8]]},"2756":{"position":[[1233,8]]},"2758":{"position":[[417,8]]},"2764":{"position":[[64,8],[410,8]]},"2766":{"position":[[70,8],[254,8]]},"2770":{"position":[[322,8],[954,8],[1246,8]]},"2805":{"position":[[786,8]]},"2850":{"position":[[41,8],[133,8]]},"2858":{"position":[[603,8]]},"2860":{"position":[[322,8],[915,8],[1219,8]]},"2862":{"position":[[147,13]]},"2886":{"position":[[226,13]]},"2890":{"position":[[255,8]]},"2899":{"position":[[783,8]]},"2960":{"position":[[1424,8]]},"2962":{"position":[[353,8]]},"2966":{"position":[[1703,8],[4323,8]]},"2983":{"position":[[322,13]]},"2985":{"position":[[440,13]]},"2990":{"position":[[196,14],[248,13],[343,13]]},"2992":{"position":[[181,13]]},"2994":{"position":[[396,14]]},"2999":{"position":[[185,12]]},"3011":{"position":[[238,8],[1568,8]]},"3016":{"position":[[55,8]]},"3033":{"position":[[411,8]]},"3035":{"position":[[68,14]]},"3055":{"position":[[319,8]]},"3061":{"position":[[868,8]]},"3071":{"position":[[836,8]]},"3074":{"position":[[158,8]]},"3078":{"position":[[397,8]]},"3103":{"position":[[1443,8]]},"3107":{"position":[[63,8]]},"3109":{"position":[[87,8]]},"3126":{"position":[[967,8]]},"3154":{"position":[[518,8]]},"3160":{"position":[[32,8]]},"3162":{"position":[[527,8]]},"3184":{"position":[[1527,8]]},"3197":{"position":[[874,8]]},"3204":{"position":[[400,12]]},"3206":{"position":[[707,8]]},"3208":{"position":[[397,8],[472,8]]},"3236":{"position":[[1240,8],[1916,8]]},"3247":{"position":[[110,8],[733,8]]},"3249":{"position":[[396,8],[437,8]]},"3251":{"position":[[1552,8],[1690,8]]},"3270":{"position":[[1302,8]]},"3314":{"position":[[1659,8],[3184,8]]},"3325":{"position":[[732,8],[2158,8]]},"3372":{"position":[[223,8]]},"3393":{"position":[[847,8]]},"3400":{"position":[[1009,8]]},"3436":{"position":[[289,8]]},"3453":{"position":[[238,8]]},"3463":{"position":[[85,8],[379,8]]},"3465":{"position":[[1454,8]]},"3472":{"position":[[8969,8],[12547,8],[12781,8]]}}}],["specifi",{"_index":164,"t":{"10":{"position":[[1671,7]]},"187":{"position":[[471,7]]},"193":{"position":[[528,7]]},"374":{"position":[[1148,9]]},"385":{"position":[[85,7]]},"398":{"position":[[233,9]]},"404":{"position":[[640,7]]},"415":{"position":[[141,10]]},"436":{"position":[[332,9]]},"485":{"position":[[1014,7]]},"487":{"position":[[2743,7]]},"519":{"position":[[579,7]]},"521":{"position":[[34,9]]},"530":{"position":[[320,9]]},"540":{"position":[[105,7]]},"542":{"position":[[135,7]]},"544":{"position":[[194,10]]},"546":{"position":[[205,10]]},"557":{"position":[[185,7]]},"574":{"position":[[53,9]]},"619":{"position":[[403,9],[506,9]]},"730":{"position":[[264,9]]},"740":{"position":[[428,7]]},"742":{"position":[[297,10],[1001,7]]},"817":{"position":[[205,9]]},"819":{"position":[[1729,9],[1962,10]]},"821":{"position":[[1181,9],[1414,10]]},"859":{"position":[[203,9],[1246,9],[1480,10],[6702,9]]},"905":{"position":[[1155,7]]},"1061":{"position":[[335,9],[427,7]]},"1112":{"position":[[1408,9]]},"1120":{"position":[[1969,9]]},"1124":{"position":[[16,10],[975,9]]},"1150":{"position":[[6081,7]]},"1156":{"position":[[29,7]]},"1165":{"position":[[1040,9]]},"1217":{"position":[[811,9]]},"1224":{"position":[[1117,9],[1438,10],[1823,10]]},"1256":{"position":[[1701,9]]},"1462":{"position":[[490,10]]},"1466":{"position":[[162,10]]},"1491":{"position":[[264,9]]},"1507":{"position":[[205,9]]},"1509":{"position":[[1729,9],[1962,10]]},"1511":{"position":[[1181,9],[1414,10]]},"1603":{"position":[[203,9],[1246,9],[1480,10],[6702,9]]},"1627":{"position":[[1155,7]]},"1855":{"position":[[1426,9]]},"1861":{"position":[[7,9],[180,7]]},"1902":{"position":[[98,10]]},"1904":{"position":[[613,10]]},"1906":{"position":[[84,7],[243,9],[873,7]]},"1917":{"position":[[1426,9]]},"1923":{"position":[[7,9],[180,7]]},"1951":{"position":[[271,9]]},"2018":{"position":[[98,10]]},"2020":{"position":[[613,10]]},"2022":{"position":[[84,7],[243,9],[873,7]]},"2043":{"position":[[397,9]]},"2152":{"position":[[283,10]]},"2352":{"position":[[1155,7]]},"2548":{"position":[[117,10]]},"2677":{"position":[[730,9],[812,9]]},"2707":{"position":[[110,7]]},"2709":{"position":[[1266,10],[1843,7],[2222,7]]},"2711":{"position":[[781,9]]},"2715":{"position":[[478,9]]},"2725":{"position":[[167,10],[252,7],[646,10]]},"2729":{"position":[[141,9]]},"2731":{"position":[[715,7]]},"2735":{"position":[[1451,7]]},"2752":{"position":[[110,7]]},"2754":{"position":[[1407,10],[1984,7],[2177,7]]},"2764":{"position":[[459,9],[867,10],[1327,7]]},"2768":{"position":[[164,9]]},"2770":{"position":[[715,7]]},"2774":{"position":[[1453,7]]},"2790":{"position":[[77,9]]},"2842":{"position":[[116,7]]},"2844":{"position":[[1194,10],[1637,7],[2015,7]]},"2850":{"position":[[167,10],[539,10]]},"2852":{"position":[[1240,9]]},"2856":{"position":[[759,9]]},"2860":{"position":[[676,7]]},"2933":{"position":[[412,9]]},"3044":{"position":[[417,9]]},"3080":{"position":[[459,10]]},"3101":{"position":[[132,9]]},"3154":{"position":[[490,7]]},"3247":{"position":[[705,7]]},"3419":{"position":[[476,9]]},"3438":{"position":[[560,9]]},"3472":{"position":[[5924,7],[13006,10],[13219,7]]}}}],["spectr",{"_index":9133,"t":{"2705":{"position":[[706,9]]},"2750":{"position":[[706,9]]},"2840":{"position":[[599,9]]}}}],["spectrum",{"_index":6053,"t":{"1226":{"position":[[1887,8]]},"2081":{"position":[[206,8]]}}}],["spectrumscal",{"_index":6051,"t":{"1226":{"position":[[1855,13]]}}}],["speed",{"_index":3657,"t":{"742":{"position":[[233,6]]},"940":{"position":[[195,5]]},"1226":{"position":[[949,5]]},"1286":{"position":[[1307,6]]},"1587":{"position":[[1108,5]]},"1662":{"position":[[195,5]]},"1736":{"position":[[127,5]]},"1779":{"position":[[4112,5]]},"2075":{"position":[[211,6]]},"2077":{"position":[[181,5],[562,6]]},"2148":{"position":[[725,5]]},"2387":{"position":[[195,5]]},"2951":{"position":[[303,5]]},"3160":{"position":[[2638,5]]},"3208":{"position":[[213,5],[1771,5]]}}}],["spent",{"_index":8375,"t":{"2196":{"position":[[298,5]]}}}],["spi",{"_index":10007,"t":{"3251":{"position":[[3725,5]]}}}],["spice",{"_index":8413,"t":{"2245":{"position":[[665,5]]}}}],["spider",{"_index":8152,"t":{"2083":{"position":[[340,6],[356,6]]}}}],["spike",{"_index":10015,"t":{"3251":{"position":[[5605,7]]}}}],["spin",{"_index":6056,"t":{"1226":{"position":[[1974,8]]},"2947":{"position":[[5179,8],[5219,8]]}}}],["spindown",{"_index":6055,"t":{"1226":{"position":[[1931,8]]}}}],["spirit",{"_index":1564,"t":{"235":{"position":[[120,7]]},"245":{"position":[[934,7],[1623,7]]}}}],["split",{"_index":8295,"t":{"2148":{"position":[[346,6]]},"2162":{"position":[[709,5]]},"2164":{"position":[[487,9],[795,5]]},"2176":{"position":[[517,5]]},"2306":{"position":[[119,5]]},"2426":{"position":[[272,5]]}}}],["sponsor",{"_index":9994,"t":{"3251":{"position":[[212,7]]}}}],["sponsorship",{"_index":1366,"t":{"191":{"position":[[24,11]]},"3206":{"position":[[387,12]]}}}],["spot",{"_index":9944,"t":{"3218":{"position":[[1201,5]]}}}],["spread",{"_index":1388,"t":{"193":{"position":[[446,6]]},"3184":{"position":[[2881,6]]},"3188":{"position":[[129,6]]},"3408":{"position":[[196,6]]}}}],["spuriou",{"_index":4495,"t":{"915":{"position":[[626,8],[692,8]]},"917":{"position":[[795,8]]},"1637":{"position":[[626,8],[692,8]]},"1639":{"position":[[795,8]]},"2362":{"position":[[626,8],[692,8]]},"2364":{"position":[[795,8]]}}}],["sql",{"_index":3668,"t":{"748":{"position":[[231,3]]},"1082":{"position":[[61,3]]},"1226":{"position":[[1243,3]]},"1321":{"position":[[31,4]]},"1791":{"position":[[2731,3]]},"3251":{"position":[[2905,3]]}}}],["sqlite",{"_index":8198,"t":{"2100":{"position":[[1280,6]]}}}],["squash",{"_index":1997,"t":{"319":{"position":[[180,7],[626,6]]}}}],["squid",{"_index":5983,"t":{"1199":{"position":[[50,5],[186,5],[504,5],[531,5]]},"1224":{"position":[[2515,5]]}}}],["src",{"_index":899,"t":{"139":{"position":[[468,4]]},"141":{"position":[[432,4]]},"143":{"position":[[841,4]]},"1697":{"position":[[469,4]]},"1699":{"position":[[247,4]]},"1749":{"position":[[304,4]]}}}],["src/amphora.pi",{"_index":3933,"t":{"838":{"position":[[51,14]]},"1553":{"position":[[51,14]]}}}],["src/create.pi",{"_index":3817,"t":{"819":{"position":[[318,13],[4047,13],[4623,13],[5226,13],[7087,13],[8138,13]]},"1509":{"position":[[318,13],[4047,13],[4623,13],[5226,13],[7087,13],[8138,13]]}}}],["src/github.com/os",{"_index":7528,"t":{"1779":{"position":[[270,22]]}}}],["src/github.com/osism/testb",{"_index":7530,"t":{"1779":{"position":[[336,30],[370,30]]}}}],["src/host",{"_index":3927,"t":{"833":{"position":[[84,8]]},"835":{"position":[[80,8]]},"1548":{"position":[[84,8]]},"1550":{"position":[[80,8]]}}}],["src/main.pi",{"_index":4173,"t":{"859":{"position":[[325,11],[2407,11],[6864,11]]},"1603":{"position":[[325,11],[2407,11],[6864,11]]}}}],["src/manage.pi",{"_index":3874,"t":{"821":{"position":[[383,13],[2026,13]]},"1511":{"position":[[383,13],[2026,13]]}}}],["src/orphan.pi",{"_index":3955,"t":{"842":{"position":[[10,13]]},"1557":{"position":[[10,13]]}}}],["src/prepar",{"_index":7163,"t":{"1676":{"position":[[891,11],[938,11]]}}}],["src/volume.pi",{"_index":3946,"t":{"840":{"position":[[10,13]]},"1555":{"position":[[10,13]]}}}],["srv",{"_index":7743,"t":{"1833":{"position":[[468,4]]}}}],["ss",{"_index":6469,"t":{"1337":{"position":[[163,2],[399,2]]}}}],["ssd",{"_index":3252,"t":{"615":{"position":[[606,3],[1034,5]]},"734":{"position":[[254,3]]},"982":{"position":[[489,3]]},"984":{"position":[[217,3]]},"986":{"position":[[228,3]]},"988":{"position":[[228,3]]},"990":{"position":[[281,3]]},"1112":{"position":[[733,3],[763,3],[799,4]]},"1184":{"position":[[25,3],[333,3],[456,4]]},"1464":{"position":[[140,3]]},"1466":{"position":[[103,3]]},"1495":{"position":[[254,3]]},"1773":{"position":[[687,3],[1069,5]]},"2426":{"position":[[221,3]]},"2544":{"position":[[876,3]]},"2697":{"position":[[1318,3]]},"2709":{"position":[[172,3],[1547,4],[2098,3]]},"2713":{"position":[[545,5]]},"2733":{"position":[[334,4]]},"2742":{"position":[[1217,3]]},"2754":{"position":[[172,3],[768,3],[863,3],[1688,4]]},"2756":{"position":[[476,4],[716,5]]},"2772":{"position":[[334,4]]},"2844":{"position":[[100,3],[1341,4],[1891,3]]},"2854":{"position":[[334,4]]},"2858":{"position":[[542,5]]},"2923":{"position":[[777,3]]},"2927":{"position":[[181,3],[294,3]]},"2931":{"position":[[482,3]]},"2933":{"position":[[375,3]]},"2939":{"position":[[593,4],[652,3]]},"2942":{"position":[[833,3]]},"2947":{"position":[[5103,3],[5738,3]]},"2949":{"position":[[423,5],[729,5],[866,3]]},"3518":{"position":[[1284,3]]}}}],["ssds/nvme",{"_index":9629,"t":{"2949":{"position":[[613,10]]}}}],["ssh",{"_index":1004,"t":{"160":{"position":[[59,3],[127,3]]},"487":{"position":[[1245,3]]},"513":{"position":[[1744,3]]},"534":{"position":[[5,3],[19,3]]},"550":{"position":[[16,3]]},"600":{"position":[[387,3]]},"604":{"position":[[5458,3],[5468,3]]},"627":{"position":[[17,3]]},"629":{"position":[[266,4],[290,4]]},"631":{"position":[[42,5]]},"660":{"position":[[2280,4]]},"903":{"position":[[909,3],[1399,3],[1423,3],[3757,3],[3761,3],[3859,3]]},"947":{"position":[[331,4],[439,3],[768,3],[917,3]]},"1017":{"position":[[250,3]]},"1035":{"position":[[66,3]]},"1037":{"position":[[59,3]]},"1041":{"position":[[451,3],[793,3]]},"1043":{"position":[[174,3]]},"1065":{"position":[[704,3],[864,3]]},"1067":{"position":[[1675,3],[4283,4]]},"1224":{"position":[[1033,3],[3907,3],[3977,3]]},"1236":{"position":[[600,4]]},"1240":{"position":[[858,4],[1032,4],[1218,4],[1318,3],[1448,3]]},"1252":{"position":[[1366,3]]},"1256":{"position":[[1162,3],[1276,3],[1547,3],[2047,4],[2152,3],[2677,3],[3019,3],[3206,3],[3237,3],[3278,3],[3316,3],[3327,3]]},"1339":{"position":[[42,3]]},"1360":{"position":[[824,3]]},"1362":{"position":[[2541,3]]},"1388":{"position":[[243,3],[472,3]]},"1569":{"position":[[1560,4],[1749,3]]},"1571":{"position":[[754,3],[1504,4],[1693,3]]},"1625":{"position":[[909,3],[1399,3],[1423,3],[3757,3],[3761,3],[3859,3]]},"1669":{"position":[[331,4],[439,3],[768,3],[917,3]]},"1743":{"position":[[351,3]]},"1745":{"position":[[902,3],[1051,4]]},"1779":{"position":[[3447,4]]},"1783":{"position":[[320,3]]},"1831":{"position":[[19,3]]},"1835":{"position":[[177,3],[498,4]]},"1837":{"position":[[8,3]]},"1845":{"position":[[2433,3]]},"1857":{"position":[[206,3],[210,3],[375,3],[448,3],[760,3]]},"1863":{"position":[[509,3],[554,3],[634,3]]},"1919":{"position":[[206,3],[210,3],[375,3],[448,3],[760,3]]},"1925":{"position":[[509,3],[554,3],[634,3]]},"2033":{"position":[[1529,3]]},"2288":{"position":[[125,3],[162,3]]},"2350":{"position":[[909,3],[1399,3],[1423,3],[3757,3],[3761,3],[3859,3]]},"2394":{"position":[[331,4],[439,3],[768,3],[917,3]]},"2899":{"position":[[622,3]]},"3103":{"position":[[166,4]]}}}],["ssh'ing",{"_index":2945,"t":{"513":{"position":[[2571,7]]}}}],["ssh.github.com",{"_index":4818,"t":{"1037":{"position":[[212,14]]}}}],["ssh/authorized_key",{"_index":6102,"t":{"1256":{"position":[[1644,22]]}}}],["ssh/config",{"_index":4813,"t":{"1037":{"position":[[84,11]]},"1041":{"position":[[162,11],[333,11],[723,11],[829,11]]},"1240":{"position":[[1426,13]]}}}],["ssh/config.d",{"_index":4830,"t":{"1041":{"position":[[115,13]]}}}],["ssh/id_rsa.configur",{"_index":6084,"t":{"1240":{"position":[[1476,28],[1571,27]]}}}],["ssh/oshm",{"_index":4338,"t":{"903":{"position":[[1474,11],[1514,11],[3768,11]]},"1625":{"position":[[1474,11],[1514,11],[3768,11]]},"2350":{"position":[[1474,11],[1514,11],[3768,11]]}}}],["ssh://git@git.services.osism.tech:regiocloud/configuration.git",{"_index":6082,"t":{"1240":{"position":[[1223,62]]}}}],["ssh://git@github.com:regiocloud/configuration.git",{"_index":6080,"t":{"1240":{"position":[[863,49]]}}}],["ssh://git@github.com:your_org/your_new_configuration_repository.git",{"_index":6078,"t":{"1240":{"position":[[661,67]]}}}],["ssh://git@gitlab.com:regiocloud/configuration.git",{"_index":6081,"t":{"1240":{"position":[[1037,49]]}}}],["ssh:27.1.1.20230919",{"_index":6582,"t":{"1360":{"position":[[1464,19]]}}}],["ssh_key",{"_index":3545,"t":{"660":{"position":[[2588,7]]}}}],["ssh_usernam",{"_index":2675,"t":{"483":{"position":[[395,12],[418,12]]}}}],["sshconfig",{"_index":6027,"t":{"1224":{"position":[[3958,9]]},"1360":{"position":[[866,9]]},"1362":{"position":[[2583,9]]}}}],["sshconfig_extra",{"_index":4812,"t":{"1037":{"position":[[4,15],[102,16]]},"1041":{"position":[[759,15]]}}}],["sshconfig_groupnam",{"_index":4828,"t":{"1041":{"position":[[30,19]]}}}],["sshconfig_ord",{"_index":4829,"t":{"1041":{"position":[[92,15],[273,15],[396,15]]}}}],["sshconfig_port",{"_index":4831,"t":{"1041":{"position":[[429,14]]}}}],["sshconfig_private_key_fil",{"_index":4832,"t":{"1041":{"position":[[461,26]]}}}],["sshconfig_us",{"_index":4834,"t":{"1041":{"position":[[649,14]]}}}],["sshd",{"_index":4626,"t":{"938":{"position":[[385,4]]},"1660":{"position":[[385,4]]},"2385":{"position":[[385,4]]}}}],["sshpass",{"_index":6076,"t":{"1238":{"position":[[56,7]]}}}],["sshping",{"_index":4333,"t":{"903":{"position":[[961,7],[1062,7],[1164,7],[2026,7]]},"1625":{"position":[[961,7],[1062,7],[1164,7],[2026,7]]},"2350":{"position":[[961,7],[1062,7],[1164,7],[2026,7]]}}}],["sshuttl",{"_index":7527,"t":{"1777":{"position":[[50,8]]},"1785":{"position":[[853,9],[922,9],[941,8],[981,8]]},"1816":{"position":[[296,8],[317,8]]}}}],["ssl",{"_index":1941,"t":{"298":{"position":[[632,3]]},"379":{"position":[[455,3]]},"1055":{"position":[[847,3]]},"1067":{"position":[[430,3],[5803,3]]},"1108":{"position":[[700,5],[1005,3],[1128,5],[1154,5]]},"1118":{"position":[[674,4]]},"1161":{"position":[[1912,3]]},"1745":{"position":[[1059,3]]},"1789":{"position":[[4,3]]},"1947":{"position":[[65,3]]}}}],["ssl/tl",{"_index":3453,"t":{"646":{"position":[[68,7]]},"650":{"position":[[67,7]]}}}],["ssl_fc",{"_index":5761,"t":{"1161":{"position":[[1820,6]]}}}],["sso",{"_index":1931,"t":{"298":{"position":[[317,3]]},"1949":{"position":[[12,3]]},"2574":{"position":[[540,3]]},"2576":{"position":[[63,5]]},"3247":{"position":[[236,3],[498,3]]},"3251":{"position":[[178,3],[834,3],[1280,3],[2086,3],[2389,3],[3139,3]]},"3518":{"position":[[2167,3]]}}}],["sst",{"_index":6038,"t":{"1226":{"position":[[925,3]]}}}],["stabil",{"_index":4600,"t":{"932":{"position":[[4589,10]]},"1654":{"position":[[4589,10]]},"2379":{"position":[[4589,10]]},"2524":{"position":[[334,10]]},"2528":{"position":[[19,10]]},"2530":{"position":[[326,10]]},"2532":{"position":[[19,10]]},"2534":{"position":[[114,10]]},"2536":{"position":[[377,10]]},"2538":{"position":[[14,10]]},"2540":{"position":[[598,10]]},"2542":{"position":[[14,10]]},"2546":{"position":[[536,10]]},"2548":{"position":[[529,10]]},"2550":{"position":[[550,10]]},"2552":{"position":[[19,10]]},"2554":{"position":[[19,10]]},"2556":{"position":[[19,10]]},"2558":{"position":[[19,10]]},"2572":{"position":[[19,10]]},"2576":{"position":[[689,10]]},"2578":{"position":[[19,10]]},"2580":{"position":[[19,10]]},"2582":{"position":[[19,10]]},"2584":{"position":[[19,10]]},"2586":{"position":[[389,10]]},"2588":{"position":[[19,10]]},"2590":{"position":[[19,10]]},"2594":{"position":[[19,10]]},"2596":{"position":[[19,10]]},"2598":{"position":[[19,10]]},"2600":{"position":[[19,10]]},"2604":{"position":[[19,10]]},"2606":{"position":[[19,10]]},"2608":{"position":[[19,10]]},"2610":{"position":[[19,10]]},"2612":{"position":[[19,10]]},"2614":{"position":[[19,10]]},"2635":{"position":[[204,12],[454,14]]},"2642":{"position":[[26,11]]},"2647":{"position":[[42,13],[335,10],[593,13],[733,14]]},"2651":{"position":[[510,10]]},"2653":{"position":[[19,10]]},"3160":{"position":[[2648,10]]},"3429":{"position":[[44,10],[111,10],[236,10]]},"3431":{"position":[[44,10],[111,10],[227,10]]}}}],["stabilized_at",{"_index":9019,"t":{"2625":{"position":[[2228,13]]},"2809":{"position":[[192,13],[426,13],[587,14],[905,13]]},"2815":{"position":[[374,14],[1176,14],[1303,14],[1457,14]]}}}],["stabl",{"_index":88,"t":{"10":{"position":[[286,6]]},"158":{"position":[[821,6]]},"462":{"position":[[324,6]]},"635":{"position":[[137,6]]},"660":{"position":[[816,6],[1368,6]]},"926":{"position":[[324,6]]},"932":{"position":[[294,6]]},"1063":{"position":[[642,6]]},"1069":{"position":[[134,6]]},"1071":{"position":[[139,6],[1295,6]]},"1080":{"position":[[575,6]]},"1397":{"position":[[125,6],[260,8]]},"1560":{"position":[[70,6]]},"1648":{"position":[[324,6]]},"1654":{"position":[[294,6]]},"1676":{"position":[[983,6]]},"1678":{"position":[[59,6],[344,6],[1744,6],[1885,6],[2057,6],[2083,6],[2334,6],[2356,6],[2378,6],[2401,6],[2902,6]]},"1779":{"position":[[3275,6]]},"1812":{"position":[[14,6]]},"1818":{"position":[[119,6],[141,6],[201,6]]},"1825":{"position":[[224,6],[723,6]]},"2154":{"position":[[590,6],[761,6]]},"2245":{"position":[[106,6],[471,6]]},"2278":{"position":[[97,6]]},"2294":{"position":[[101,6]]},"2315":{"position":[[1312,6]]},"2373":{"position":[[324,6]]},"2379":{"position":[[294,6]]},"2522":{"position":[[615,7],[678,6]]},"2524":{"position":[[379,6]]},"2526":{"position":[[400,6],[504,7]]},"2528":{"position":[[64,6]]},"2536":{"position":[[528,6]]},"2540":{"position":[[641,6]]},"2544":{"position":[[407,6],[511,7]]},"2546":{"position":[[579,6]]},"2548":{"position":[[572,6]]},"2550":{"position":[[593,6]]},"2554":{"position":[[69,6]]},"2574":{"position":[[380,6],[484,7]]},"2576":{"position":[[739,6]]},"2584":{"position":[[116,6]]},"2586":{"position":[[432,6]]},"2592":{"position":[[363,6],[467,7]]},"2594":{"position":[[62,6]]},"2602":{"position":[[395,6],[499,7]]},"2625":{"position":[[1878,7],[2270,6],[2356,6]]},"2629":{"position":[[85,7]]},"2631":{"position":[[1229,6],[1427,6],[1473,6],[2130,7]]},"2635":{"position":[[79,7]]},"2644":{"position":[[53,6]]},"2647":{"position":[[224,6],[245,6]]},"2799":{"position":[[39,7]]},"2809":{"position":[[283,7]]},"2815":{"position":[[1254,6]]},"2817":{"position":[[93,7]]},"2944":{"position":[[578,6]]},"2947":{"position":[[3215,6]]},"3299":{"position":[[1772,7],[3134,6]]},"3301":{"position":[[1753,7],[2012,7]]},"3429":{"position":[[20,6]]},"3431":{"position":[[20,6]]},"3518":{"position":[[487,6],[597,7]]}}}],["stack",{"_index":2,"t":{"4":{"position":[[16,5]]},"27":{"position":[[1945,6]]},"71":{"position":[[125,5]]},"101":{"position":[[382,5],[460,5]]},"103":{"position":[[174,5]]},"116":{"position":[[65,5]]},"166":{"position":[[19,5],[161,6]]},"235":{"position":[[16,5],[61,5],[977,6]]},"245":{"position":[[16,5]]},"253":{"position":[[199,6],[1279,5]]},"274":{"position":[[177,5]]},"327":{"position":[[47,5]]},"342":{"position":[[20,5]]},"344":{"position":[[151,6]]},"349":{"position":[[179,7],[204,7],[508,6],[719,6]]},"363":{"position":[[12,5],[67,5],[100,7],[578,7]]},"366":{"position":[[67,5]]},"383":{"position":[[19,5]]},"393":{"position":[[24,6],[154,6],[208,6],[591,6],[719,6],[763,6],[979,6],[1313,6],[1746,5]]},"544":{"position":[[45,5],[104,6],[161,8]]},"546":{"position":[[46,5],[115,6],[172,8]]},"656":{"position":[[244,6]]},"660":{"position":[[612,6]]},"662":{"position":[[169,6]]},"690":{"position":[[20,5]]},"692":{"position":[[18,5]]},"770":{"position":[[63,5]]},"780":{"position":[[663,6],[768,6]]},"1770":{"position":[[69,5],[264,5]]},"1937":{"position":[[16,5]]},"1957":{"position":[[2098,5],[2146,5]]},"1972":{"position":[[161,5]]},"1980":{"position":[[8,6]]},"2096":{"position":[[1848,5],[1969,5],[2018,5],[2304,5],[2353,5]]},"2098":{"position":[[1742,7],[2053,7],[2910,5],[3151,5],[3200,5],[3615,5],[3664,5]]},"2106":{"position":[[761,5],[964,5],[1013,5]]},"2120":{"position":[[279,6]]},"2128":{"position":[[151,5],[200,5]]},"2138":{"position":[[770,5],[996,5],[1045,5]]},"2160":{"position":[[90,7]]},"2164":{"position":[[171,6],[320,5]]},"2166":{"position":[[112,5]]},"2170":{"position":[[116,5]]},"2196":{"position":[[342,5]]},"2257":{"position":[[162,5]]},"2265":{"position":[[213,5]]},"2298":{"position":[[213,5]]},"2407":{"position":[[197,6],[216,5],[297,6]]},"2461":{"position":[[50,6],[139,6],[437,6],[570,6],[601,5],[832,7],[879,6],[910,6],[945,5],[993,5],[1016,5],[1103,6],[1150,6]]},"2463":{"position":[[33,5],[106,5]]},"2468":{"position":[[412,5]]},"2470":{"position":[[33,6],[116,6]]},"2482":{"position":[[172,7]]},"2486":{"position":[[655,5]]},"2493":{"position":[[78,5],[232,6]]},"2504":{"position":[[687,8]]},"2514":{"position":[[20,5]]},"2524":{"position":[[145,5]]},"2526":{"position":[[149,6],[274,6]]},"2548":{"position":[[91,5]]},"2576":{"position":[[116,5]]},"2592":{"position":[[921,6]]},"2617":{"position":[[20,5],[143,6]]},"2651":{"position":[[141,5]]},"2663":{"position":[[20,5]]},"2684":{"position":[[20,5]]},"2795":{"position":[[20,5]]},"2975":{"position":[[20,5]]},"3011":{"position":[[2447,6]]},"3184":{"position":[[750,8]]},"3188":{"position":[[76,7]]},"3204":{"position":[[115,7],[530,6]]},"3206":{"position":[[664,6]]},"3208":{"position":[[293,5]]},"3210":{"position":[[184,6]]},"3212":{"position":[[45,6]]},"3222":{"position":[[792,6]]},"3224":{"position":[[146,6],[1559,6],[1917,5]]},"3247":{"position":[[99,5]]},"3255":{"position":[[239,5]]},"3370":{"position":[[55,5]]},"3374":{"position":[[159,5]]},"3391":{"position":[[88,5]]},"3393":{"position":[[945,5],[1004,5],[1051,5],[1209,5]]},"3395":{"position":[[33,5],[73,5],[141,5],[1204,6],[1238,6]]},"3397":{"position":[[67,6],[161,5],[218,5],[242,5],[375,5],[476,5]]},"3400":{"position":[[847,6]]},"3413":{"position":[[20,5]]},"3434":{"position":[[55,5]]},"3438":{"position":[[147,5],[585,6]]},"3518":{"position":[[117,6],[1987,6]]}}}],["stack.kubecontrollermanager.endpoints=$node_ip",{"_index":8214,"t":{"2106":{"position":[[1195,48]]}}}],["stack.kubeetcd.endpoints=$node_ip",{"_index":8212,"t":{"2106":{"position":[[1072,35]]}}}],["stack.kubeproxy.endpoints=$node_ip",{"_index":8213,"t":{"2106":{"position":[[1133,36]]}}}],["stack.kubescheduler.endpoints=$node_ip",{"_index":8215,"t":{"2106":{"position":[[1269,40]]}}}],["stack@devstack:~/devstack",{"_index":9783,"t":{"3107":{"position":[[208,26]]},"3109":{"position":[[282,26],[1398,26],[2550,26]]}}}],["staff",{"_index":9989,"t":{"3245":{"position":[[540,6]]}}}],["stage",{"_index":772,"t":{"120":{"position":[[100,6]]},"122":{"position":[[25,6],[68,6]]},"2677":{"position":[[491,6],[580,6],[659,6]]},"3186":{"position":[[754,6]]},"3299":{"position":[[1001,5]]},"3301":{"position":[[6512,5]]}}}],["stakehold",{"_index":2205,"t":{"366":{"position":[[699,12]]},"3204":{"position":[[607,13]]}}}],["stale",{"_index":1329,"t":{"184":{"position":[[294,5]]}}}],["stall",{"_index":9482,"t":{"2870":{"position":[[199,5]]}}}],["stand",{"_index":2206,"t":{"366":{"position":[[811,8]]},"710":{"position":[[5,6]]},"911":{"position":[[1131,5]]},"1633":{"position":[[1131,5]]},"2235":{"position":[[3,5]]},"2358":{"position":[[1131,5]]},"3059":{"position":[[144,5]]},"3224":{"position":[[474,6]]},"3301":{"position":[[3367,6]]}}}],["standalon",{"_index":8482,"t":{"2321":{"position":[[381,10]]},"3397":{"position":[[265,10]]}}}],["standard",{"_index":287,"t":{"25":{"position":[[685,9],[748,9]]},"30":{"position":[[131,9],[145,9],[181,9]]},"32":{"position":[[258,9]]},"67":{"position":[[117,15]]},"77":{"position":[[177,8]]},"79":{"position":[[84,15],[266,9],[377,10],[454,9],[620,8]]},"81":{"position":[[104,10]]},"101":{"position":[[683,9]]},"129":{"position":[[35,8]]},"166":{"position":[[1085,8]]},"172":{"position":[[448,8]]},"174":{"position":[[850,8],[1492,8],[1585,12]]},"245":{"position":[[161,12]]},"278":{"position":[[70,8]]},"280":{"position":[[707,9]]},"282":{"position":[[313,8]]},"300":{"position":[[16,8]]},"329":{"position":[[241,12]]},"335":{"position":[[200,12],[239,9]]},"342":{"position":[[78,9]]},"361":{"position":[[147,9]]},"366":{"position":[[161,9],[296,9],[1072,9],[1351,9]]},"368":{"position":[[4,9],[267,9]]},"370":{"position":[[123,8],[341,8],[414,8]]},"372":{"position":[[160,8]]},"374":{"position":[[305,10],[669,9],[743,8]]},"377":{"position":[[78,9],[191,8]]},"381":{"position":[[183,8]]},"505":{"position":[[28,8]]},"513":{"position":[[1843,12]]},"583":{"position":[[573,8]]},"627":{"position":[[1847,10]]},"631":{"position":[[90,8]]},"646":{"position":[[1601,8]]},"690":{"position":[[41,9]]},"696":{"position":[[2,12]]},"698":{"position":[[8,9],[39,9]]},"700":{"position":[[42,16]]},"702":{"position":[[57,15]]},"704":{"position":[[75,9]]},"706":{"position":[[87,10],[165,9]]},"718":{"position":[[116,9]]},"720":{"position":[[27,9]]},"726":{"position":[[174,8]]},"730":{"position":[[1022,9],[1127,9]]},"732":{"position":[[395,8]]},"734":{"position":[[61,8]]},"736":{"position":[[197,11]]},"780":{"position":[[85,12],[250,12],[471,12]]},"883":{"position":[[1226,12]]},"897":{"position":[[115,9],[188,10]]},"1150":{"position":[[104,8],[123,8]]},"1165":{"position":[[2236,9]]},"1188":{"position":[[172,8]]},"1419":{"position":[[738,8]]},"1487":{"position":[[174,8]]},"1491":{"position":[[1022,9],[1127,9]]},"1493":{"position":[[395,8]]},"1495":{"position":[[61,8]]},"1619":{"position":[[115,9],[188,10]]},"1970":{"position":[[478,9]]},"2035":{"position":[[49,8]]},"2037":{"position":[[31,9],[449,9]]},"2039":{"position":[[161,8]]},"2043":{"position":[[94,9],[464,8],[716,8]]},"2047":{"position":[[171,8],[837,8]]},"2075":{"position":[[530,8]]},"2233":{"position":[[44,9],[74,10],[107,8],[124,8],[163,8],[233,9]]},"2245":{"position":[[222,8]]},"2265":{"position":[[567,8],[651,9]]},"2283":{"position":[[44,11],[198,15]]},"2298":{"position":[[567,8],[651,9]]},"2310":{"position":[[109,12],[547,10]]},"2315":{"position":[[141,8]]},"2330":{"position":[[40,15],[78,9],[125,9],[160,9],[240,9],[580,8],[842,9],[878,15]]},"2344":{"position":[[115,9],[188,10]]},"2400":{"position":[[139,12]]},"2407":{"position":[[456,10]]},"2409":{"position":[[476,9]]},"2426":{"position":[[108,10],[178,8],[249,9],[295,8],[334,9],[648,9],[666,9],[731,9],[840,9],[920,10]]},"2456":{"position":[[183,12]]},"2472":{"position":[[48,8]]},"2491":{"position":[[174,9]]},"2497":{"position":[[4,9],[299,9],[390,9],[430,9],[615,10],[634,9]]},"2514":{"position":[[118,10],[523,10],[660,9],[807,9],[836,10]]},"2518":{"position":[[88,9]]},"2522":{"position":[[471,10],[491,9]]},"2524":{"position":[[64,10],[304,10]]},"2526":{"position":[[40,9],[477,8],[559,9],[587,10],[655,9]]},"2530":{"position":[[22,9]]},"2536":{"position":[[22,8],[290,8],[411,8],[465,8],[519,8]]},"2540":{"position":[[21,8],[162,8],[632,8]]},"2544":{"position":[[15,9],[156,9],[484,8],[568,8],[757,8],[788,8],[842,8],[936,8],[1025,8]]},"2546":{"position":[[28,8],[161,8],[570,8]]},"2548":{"position":[[13,8],[563,8]]},"2550":{"position":[[13,8],[405,8],[584,8]]},"2558":{"position":[[53,8]]},"2572":{"position":[[53,8]]},"2574":{"position":[[64,10],[457,8]]},"2576":{"position":[[13,8],[331,8]]},"2578":{"position":[[53,8]]},"2584":{"position":[[53,8],[107,8]]},"2586":{"position":[[13,8],[123,8],[423,8]]},"2588":{"position":[[53,8]]},"2592":{"position":[[0,9],[175,9],[440,8],[1028,8]]},"2594":{"position":[[53,8]]},"2596":{"position":[[53,8]]},"2600":{"position":[[53,8]]},"2602":{"position":[[20,9],[190,9],[472,8]]},"2617":{"position":[[41,9]]},"2621":{"position":[[69,8]]},"2623":{"position":[[119,9],[131,8],[175,8],[276,10],[348,9],[446,9],[609,8],[799,8]]},"2625":{"position":[[1797,9]]},"2627":{"position":[[0,9],[15,8],[283,15],[698,8],[1130,9],[1760,9]]},"2631":{"position":[[128,9],[249,9],[1563,9],[1684,9]]},"2635":{"position":[[120,8],[403,8]]},"2639":{"position":[[58,10]]},"2642":{"position":[[154,8]]},"2647":{"position":[[1476,8],[1518,9]]},"2649":{"position":[[72,9]]},"2651":{"position":[[13,8],[47,12],[287,8],[544,8]]},"2656":{"position":[[151,10]]},"2660":{"position":[[267,9],[301,9],[333,11]]},"2663":{"position":[[316,8]]},"2671":{"position":[[1303,9]]},"2675":{"position":[[87,9]]},"2688":{"position":[[1089,9]]},"2695":{"position":[[12,8]]},"2697":{"position":[[1122,16],[1518,15]]},"2711":{"position":[[37,8],[588,8],[1057,8]]},"2713":{"position":[[77,8]]},"2715":{"position":[[564,9]]},"2717":{"position":[[51,9]]},"2731":{"position":[[128,8],[478,13]]},"2735":{"position":[[17,8]]},"2737":{"position":[[73,8],[444,13]]},"2740":{"position":[[12,8]]},"2742":{"position":[[1021,16],[1417,15]]},"2770":{"position":[[128,8],[478,13]]},"2774":{"position":[[115,8],[153,8]]},"2776":{"position":[[73,8],[444,13]]},"2779":{"position":[[32,8]]},"2781":{"position":[[94,9]]},"2790":{"position":[[163,9]]},"2795":{"position":[[41,9],[861,9]]},"2797":{"position":[[155,9]]},"2799":{"position":[[69,9],[210,9]]},"2801":{"position":[[0,9],[339,9]]},"2803":{"position":[[185,10]]},"2809":{"position":[[89,9],[102,9],[145,8]]},"2811":{"position":[[14,9],[44,9],[102,8],[202,8],[290,8],[354,9]]},"2813":{"position":[[253,8],[856,8]]},"2815":{"position":[[402,10],[1166,9],[1202,10],[1268,9],[1355,10],[1407,9],[1509,10]]},"2822":{"position":[[5,8],[173,15]]},"2827":{"position":[[56,9]]},"2830":{"position":[[12,8]]},"2856":{"position":[[39,8],[1035,8]]},"2858":{"position":[[77,8]]},"2860":{"position":[[128,8]]},"2864":{"position":[[80,10],[127,9],[499,8]]},"2876":{"position":[[93,8]]},"2881":{"position":[[173,9]]},"2886":{"position":[[18,8]]},"2890":{"position":[[268,8]]},"2913":{"position":[[429,9]]},"2923":{"position":[[180,8],[234,9]]},"2925":{"position":[[41,8]]},"2933":{"position":[[60,8],[586,8]]},"2937":{"position":[[51,9]]},"2939":{"position":[[12,8],[66,8],[168,9],[566,9]]},"2942":{"position":[[34,8],[69,8],[711,10]]},"2944":{"position":[[22,8],[833,9]]},"2949":{"position":[[94,9]]},"2955":{"position":[[68,9],[219,8],[253,11],[396,11],[446,8],[547,8],[642,8]]},"2962":{"position":[[11,11]]},"2964":{"position":[[31,9]]},"2966":{"position":[[523,13],[1069,13],[1987,12],[2170,12],[3199,13],[4261,15]]},"2970":{"position":[[7,12],[409,12]]},"2975":{"position":[[41,9]]},"2977":{"position":[[33,9],[54,8]]},"2983":{"position":[[520,9]]},"2992":{"position":[[34,8],[267,8]]},"2996":{"position":[[50,9]]},"2999":{"position":[[320,12]]},"3023":{"position":[[53,8]]},"3025":{"position":[[135,12],[189,8]]},"3027":{"position":[[89,9]]},"3029":{"position":[[163,8]]},"3031":{"position":[[63,9],[202,12],[688,9]]},"3033":{"position":[[214,8]]},"3035":{"position":[[16,8]]},"3037":{"position":[[5,8]]},"3039":{"position":[[136,8]]},"3046":{"position":[[201,9]]},"3053":{"position":[[294,9],[646,9]]},"3071":{"position":[[985,9],[1082,9],[1304,8]]},"3078":{"position":[[44,8]]},"3080":{"position":[[633,8]]},"3082":{"position":[[463,8],[544,12],[950,8],[1739,8]]},"3084":{"position":[[5,8],[324,8]]},"3092":{"position":[[217,9]]},"3097":{"position":[[381,8]]},"3103":{"position":[[106,11],[215,13],[716,12]]},"3115":{"position":[[43,12]]},"3117":{"position":[[32,8]]},"3119":{"position":[[8,11]]},"3124":{"position":[[402,8]]},"3126":{"position":[[1055,8]]},"3132":{"position":[[330,9]]},"3139":{"position":[[145,13],[208,9]]},"3154":{"position":[[5,8]]},"3160":{"position":[[251,9]]},"3167":{"position":[[702,8]]},"3182":{"position":[[2198,8]]},"3186":{"position":[[11,8],[697,9]]},"3197":{"position":[[35,8]]},"3199":{"position":[[5,8],[271,9],[317,9],[363,8]]},"3238":{"position":[[5,8]]},"3251":{"position":[[897,8],[2047,8]]},"3262":{"position":[[421,10]]},"3264":{"position":[[53,8]]},"3266":{"position":[[203,9]]},"3268":{"position":[[33,9]]},"3276":{"position":[[1989,8]]},"3286":{"position":[[324,8]]},"3293":{"position":[[254,8]]},"3297":{"position":[[206,8]]},"3299":{"position":[[1952,8],[3315,8],[4538,8]]},"3408":{"position":[[221,9]]},"3413":{"position":[[366,8]]},"3415":{"position":[[484,8]]},"3417":{"position":[[21,9]]},"3429":{"position":[[297,9],[443,8],[473,8]]},"3431":{"position":[[255,9]]},"3455":{"position":[[53,8]]},"3457":{"position":[[14,8],[392,8],[853,8]]},"3459":{"position":[[646,8],[818,12]]},"3461":{"position":[[89,8]]},"3463":{"position":[[858,8]]},"3468":{"position":[[31,8]]},"3479":{"position":[[197,8]]},"3482":{"position":[[1001,8],[1142,8],[1318,8],[1377,8],[1602,8],[2175,8]]},"3512":{"position":[[28,9]]},"3518":{"position":[[0,9],[46,13],[275,9],[564,8],[659,9],[694,10],[769,9],[951,8],[1150,8],[1186,8],[1245,8],[1349,8],[1448,8],[2104,8]]}}}],["standard'",{"_index":8654,"t":{"2548":{"position":[[338,10]]}}}],["standard6",{"_index":10243,"t":{"3472":{"position":[[12995,10]]}}}],["standardis",{"_index":8998,"t":{"2617":{"position":[[331,12]]},"3413":{"position":[[45,11]]}}}],["standards—includ",{"_index":8596,"t":{"2514":{"position":[[84,19]]}}}],["standbi",{"_index":5346,"t":{"1118":{"position":[[75,7],[392,7]]}}}],["standpoint",{"_index":9931,"t":{"3206":{"position":[[438,11]]}}}],["stanza",{"_index":7435,"t":{"1754":{"position":[[88,7],[264,7]]}}}],["star",{"_index":10064,"t":{"3299":{"position":[[2023,5],[3385,5],[4608,5]]}}}],["start",{"_index":38,"t":{"4":{"position":[[452,5],[497,8]]},"48":{"position":[[12,7]]},"55":{"position":[[13,7]]},"103":{"position":[[100,5]]},"135":{"position":[[95,6]]},"158":{"position":[[492,5]]},"164":{"position":[[69,5]]},"174":{"position":[[289,8]]},"195":{"position":[[54,5]]},"202":{"position":[[213,5],[501,5]]},"210":{"position":[[729,5]]},"214":{"position":[[16,5]]},"257":{"position":[[109,5],[151,8]]},"286":{"position":[[187,8]]},"315":{"position":[[336,8]]},"347":{"position":[[6,5]]},"387":{"position":[[265,5]]},"389":{"position":[[9,5]]},"393":{"position":[[1228,5]]},"428":{"position":[[10,5]]},"472":{"position":[[1913,6],[2396,9]]},"489":{"position":[[816,5]]},"637":{"position":[[0,8],[323,8]]},"650":{"position":[[1844,7]]},"652":{"position":[[1149,7]]},"716":{"position":[[159,5]]},"720":{"position":[[0,5]]},"742":{"position":[[817,7]]},"756":{"position":[[344,8]]},"790":{"position":[[13,7]]},"853":{"position":[[176,5]]},"859":{"position":[[2327,8]]},"897":{"position":[[6,5]]},"903":{"position":[[4008,7]]},"909":{"position":[[213,5]]},"911":{"position":[[350,7]]},"913":{"position":[[249,5],[3382,7],[3727,5],[4134,7]]},"915":{"position":[[1283,5],[1320,5]]},"917":{"position":[[283,5]]},"922":{"position":[[796,8]]},"932":{"position":[[3082,5]]},"947":{"position":[[1620,5],[1716,5]]},"982":{"position":[[413,8]]},"984":{"position":[[376,6]]},"1077":{"position":[[774,7],[1238,7]]},"1114":{"position":[[3663,5]]},"1184":{"position":[[1864,8]]},"1286":{"position":[[718,8]]},"1317":{"position":[[1007,7],[1749,7],[2226,7],[5900,7],[6420,7]]},"1342":{"position":[[277,5]]},"1344":{"position":[[279,5]]},"1368":{"position":[[1760,7],[2439,7]]},"1442":{"position":[[174,6]]},"1446":{"position":[[48,5]]},"1473":{"position":[[290,5],[417,5],[642,5],[1406,5],[1516,5],[1657,5]]},"1527":{"position":[[13,7]]},"1566":{"position":[[184,7]]},"1569":{"position":[[849,5],[926,5],[1262,6],[1447,5]]},"1571":{"position":[[1391,5],[1843,5]]},"1574":{"position":[[715,5]]},"1576":{"position":[[867,8]]},"1585":{"position":[[3642,7]]},"1587":{"position":[[1567,5]]},"1591":{"position":[[238,6]]},"1597":{"position":[[176,5]]},"1603":{"position":[[2327,8]]},"1619":{"position":[[6,5]]},"1625":{"position":[[4008,7]]},"1631":{"position":[[213,5]]},"1633":{"position":[[350,7]]},"1635":{"position":[[249,5],[3382,7],[3727,5],[4134,7]]},"1637":{"position":[[1283,5],[1320,5]]},"1639":{"position":[[283,5]]},"1644":{"position":[[796,8]]},"1654":{"position":[[3082,5]]},"1669":{"position":[[1620,5],[1716,5]]},"1676":{"position":[[998,8]]},"1695":{"position":[[95,6]]},"1721":{"position":[[4027,8]]},"1731":{"position":[[345,8],[628,5],[669,5]]},"1740":{"position":[[158,7]]},"1745":{"position":[[809,5]]},"1764":{"position":[[3619,7],[3679,7]]},"1785":{"position":[[250,5]]},"1835":{"position":[[362,5],[572,5]]},"1845":{"position":[[147,5],[2370,8]]},"1896":{"position":[[344,8]]},"1970":{"position":[[330,8]]},"1976":{"position":[[679,8]]},"2012":{"position":[[344,8]]},"2098":{"position":[[2558,8]]},"2235":{"position":[[704,7]]},"2250":{"position":[[416,7]]},"2317":{"position":[[91,5]]},"2344":{"position":[[6,5]]},"2350":{"position":[[4008,7]]},"2356":{"position":[[213,5]]},"2358":{"position":[[350,7]]},"2360":{"position":[[249,5],[3382,7],[3727,5],[4134,7]]},"2362":{"position":[[1283,5],[1320,5]]},"2364":{"position":[[283,5]]},"2369":{"position":[[796,8]]},"2379":{"position":[[3082,5]]},"2394":{"position":[[1620,5],[1716,5]]},"2625":{"position":[[425,6],[776,5],[807,5]]},"2631":{"position":[[2398,6]]},"2671":{"position":[[275,7]]},"2713":{"position":[[1622,8]]},"2735":{"position":[[1557,5]]},"2756":{"position":[[73,6],[321,5]]},"2774":{"position":[[1559,5]]},"2781":{"position":[[24,6]]},"2786":{"position":[[90,8]]},"2895":{"position":[[1336,8],[4521,9]]},"2983":{"position":[[535,5]]},"2985":{"position":[[712,5]]},"3042":{"position":[[246,5]]},"3044":{"position":[[543,5]]},"3050":{"position":[[161,6]]},"3103":{"position":[[1786,5]]},"3236":{"position":[[2290,7],[2789,8]]},"3251":{"position":[[236,8]]},"3299":{"position":[[4249,7]]},"3357":{"position":[[260,8]]}}}],["start:\"10.0.0.11",{"_index":2696,"t":{"483":{"position":[[1024,19]]}}}],["started.yml",{"_index":3735,"t":{"790":{"position":[[687,11]]},"1527":{"position":[[687,11]]}}}],["startup",{"_index":4484,"t":{"913":{"position":[[3417,7]]},"926":{"position":[[679,8]]},"928":{"position":[[300,8]]},"932":{"position":[[1648,8]]},"942":{"position":[[500,7]]},"1635":{"position":[[3417,7]]},"1648":{"position":[[679,8]]},"1650":{"position":[[300,8]]},"1654":{"position":[[1648,8]]},"1664":{"position":[[500,7]]},"2360":{"position":[[3417,7]]},"2373":{"position":[[679,8]]},"2375":{"position":[[300,8]]},"2379":{"position":[[1648,8]]},"2389":{"position":[[500,7]]},"2468":{"position":[[859,7]]}}}],["startup/apimon.servic",{"_index":4490,"t":{"913":{"position":[[3632,22]]},"1635":{"position":[[3632,22]]},"2360":{"position":[[3632,22]]}}}],["startup/kil",{"_index":4501,"t":{"917":{"position":[[249,12]]},"1639":{"position":[[249,12]]},"2364":{"position":[[249,12]]}}}],["startup/run",{"_index":4485,"t":{"913":{"position":[[3454,11]]},"917":{"position":[[215,11]]},"1635":{"position":[[3454,11]]},"1639":{"position":[[215,11]]},"2360":{"position":[[3454,11]]},"2364":{"position":[[215,11]]}}}],["starvat",{"_index":4702,"t":{"986":{"position":[[144,10]]}}}],["stat",{"_index":6468,"t":{"1337":{"position":[[141,4]]},"1400":{"position":[[330,5]]},"2306":{"position":[[102,5]]},"3400":{"position":[[1031,5]]}}}],["stat_resolvconf_file.stat.islnk",{"_index":922,"t":{"141":{"position":[[570,31],[621,31]]},"1699":{"position":[[385,31],[436,31]]}}}],["stat_sum.num_large_omap_object",{"_index":6905,"t":{"1444":{"position":[[155,33]]}}}],["state",{"_index":90,"t":{"10":{"position":[[301,6]]},"143":{"position":[[375,6],[678,6]]},"317":{"position":[[198,6]]},"339":{"position":[[419,6]]},"570":{"position":[[90,6]]},"572":{"position":[[92,6]]},"574":{"position":[[5,5],[44,5],[125,5]]},"578":{"position":[[38,6]]},"598":{"position":[[163,5],[211,5],[259,5],[307,5],[1528,5]]},"602":{"position":[[228,5]]},"606":{"position":[[228,5]]},"615":{"position":[[1274,5]]},"627":{"position":[[4704,5]]},"665":{"position":[[73,6]]},"760":{"position":[[380,5]]},"883":{"position":[[617,5]]},"911":{"position":[[1008,5],[1411,5]]},"920":{"position":[[124,5]]},"947":{"position":[[69,6]]},"949":{"position":[[422,5],[510,5],[589,5]]},"956":{"position":[[1571,7],[1656,7],[1721,5]]},"982":{"position":[[226,6]]},"1065":{"position":[[30,5]]},"1226":{"position":[[393,6]]},"1267":{"position":[[27,7],[52,6],[123,6]]},"1269":{"position":[[102,5]]},"1271":{"position":[[96,5]]},"1347":{"position":[[198,5],[1667,5]]},"1362":{"position":[[892,5],[1830,5]]},"1373":{"position":[[97,5]]},"1375":{"position":[[407,5],[1317,5]]},"1377":{"position":[[408,5],[1412,5]]},"1383":{"position":[[522,6]]},"1469":{"position":[[333,6]]},"1477":{"position":[[44,5]]},"1569":{"position":[[53,5]]},"1585":{"position":[[2993,6],[3181,6]]},"1633":{"position":[[1008,5],[1411,5]]},"1642":{"position":[[124,5]]},"1669":{"position":[[69,6]]},"1671":{"position":[[422,5],[510,5],[589,5]]},"1743":{"position":[[2070,6]]},"1749":{"position":[[164,6]]},"1886":{"position":[[61,5]]},"1892":{"position":[[345,5]]},"1908":{"position":[[1386,5],[1439,5],[1824,6],[2910,6],[3062,5],[3115,5]]},"2002":{"position":[[61,5]]},"2008":{"position":[[345,5]]},"2024":{"position":[[1386,5],[1439,5],[1824,6],[2910,6],[3062,5],[3115,5]]},"2035":{"position":[[81,6]]},"2276":{"position":[[192,5]]},"2358":{"position":[[1008,5],[1411,5]]},"2367":{"position":[[124,5]]},"2394":{"position":[[69,6]]},"2396":{"position":[[422,5],[510,5],[589,5]]},"2461":{"position":[[82,5]]},"2524":{"position":[[328,5]]},"2528":{"position":[[13,5]]},"2530":{"position":[[320,5]]},"2532":{"position":[[13,5]]},"2534":{"position":[[108,5]]},"2536":{"position":[[371,5]]},"2538":{"position":[[8,5]]},"2540":{"position":[[592,5]]},"2542":{"position":[[8,5]]},"2546":{"position":[[530,5]]},"2548":{"position":[[523,5]]},"2550":{"position":[[544,5]]},"2552":{"position":[[13,5]]},"2554":{"position":[[13,5]]},"2556":{"position":[[13,5]]},"2558":{"position":[[13,5]]},"2566":{"position":[[709,6],[11613,6]]},"2572":{"position":[[13,5]]},"2576":{"position":[[683,5]]},"2578":{"position":[[13,5]]},"2580":{"position":[[13,5]]},"2582":{"position":[[13,5]]},"2584":{"position":[[13,5]]},"2586":{"position":[[383,5]]},"2588":{"position":[[13,5]]},"2590":{"position":[[13,5]]},"2594":{"position":[[13,5]]},"2596":{"position":[[13,5]]},"2598":{"position":[[13,5]]},"2600":{"position":[[13,5]]},"2604":{"position":[[13,5]]},"2606":{"position":[[13,5]]},"2608":{"position":[[13,5]]},"2610":{"position":[[13,5]]},"2612":{"position":[[13,5]]},"2614":{"position":[[13,5]]},"2629":{"position":[[555,6]]},"2631":{"position":[[1236,6],[1388,6],[2418,5]]},"2637":{"position":[[319,5]]},"2647":{"position":[[252,5],[285,5],[306,5]]},"2651":{"position":[[504,5]]},"2653":{"position":[[13,5]]},"2688":{"position":[[1132,5],[2192,5]]},"2795":{"position":[[1414,5]]},"2811":{"position":[[330,5]]},"2815":{"position":[[342,5]]},"2876":{"position":[[3,6]]},"2947":{"position":[[1282,6],[1455,5],[4135,5],[4523,5],[5085,5],[5248,5]]},"2960":{"position":[[906,5]]},"2966":{"position":[[2654,7],[3491,6]]},"2992":{"position":[[562,6]]},"3029":{"position":[[336,6]]},"3044":{"position":[[12,6]]},"3167":{"position":[[502,6]]},"3195":{"position":[[568,5]]},"3249":{"position":[[972,6]]},"3272":{"position":[[710,6]]},"3274":{"position":[[105,5],[165,5],[263,6]]},"3301":{"position":[[5616,5]]},"3310":{"position":[[680,6]]},"3347":{"position":[[728,6]]},"3355":{"position":[[381,7]]},"3363":{"position":[[168,5],[193,5]]},"3391":{"position":[[643,6]]},"3393":{"position":[[337,8]]},"3400":{"position":[[978,8]]},"3429":{"position":[[14,5],[209,5]]},"3431":{"position":[[14,5],[209,5]]}}}],["statefulset",{"_index":2537,"t":{"447":{"position":[[285,11]]},"449":{"position":[[389,11]]},"456":{"position":[[97,11]]},"641":{"position":[[819,13]]}}}],["statefulset.apps/harbor",{"_index":3413,"t":{"641":{"position":[[1166,23],[1207,23],[1245,23]]}}}],["stateless",{"_index":2560,"t":{"454":{"position":[[26,9]]},"1344":{"position":[[408,10]]}}}],["statement",{"_index":1424,"t":{"202":{"position":[[518,10],[567,11],[585,11],[609,11],[630,12]]},"227":{"position":[[22,10]]},"282":{"position":[[651,10]]},"1745":{"position":[[195,10]]},"2713":{"position":[[1449,11]]},"2756":{"position":[[1166,11]]},"2858":{"position":[[1221,11]]},"2925":{"position":[[86,9]]},"2992":{"position":[[285,9]]}}}],["static",{"_index":651,"t":{"105":{"position":[[413,6]]},"114":{"position":[[769,6]]},"302":{"position":[[1545,8]]},"798":{"position":[[512,6]]},"1067":{"position":[[1873,6],[2237,6],[2383,6]]},"1535":{"position":[[512,6]]},"1585":{"position":[[1835,6]]},"1787":{"position":[[110,6]]},"1810":{"position":[[46,7]]},"1833":{"position":[[1508,6]]},"1963":{"position":[[179,6],[327,6]]},"2140":{"position":[[428,6]]},"2176":{"position":[[678,6]]},"2667":{"position":[[273,6]]},"2675":{"position":[[39,6],[1070,6]]}}}],["station",{"_index":1409,"t":{"198":{"position":[[104,7]]}}}],["statist",{"_index":4440,"t":{"913":{"position":[[134,11]]},"920":{"position":[[39,10],[856,12]]},"922":{"position":[[1272,10]]},"1364":{"position":[[428,14]]},"1635":{"position":[[134,11]]},"1642":{"position":[[39,10],[856,12]]},"1644":{"position":[[1272,10]]},"2214":{"position":[[650,10]]},"2360":{"position":[[134,11]]},"2367":{"position":[[39,10],[856,12]]},"2369":{"position":[[1272,10]]}}}],["stats.starttim",{"_index":4523,"t":{"922":{"position":[[1189,15]]},"1644":{"position":[[1189,15]]},"2369":{"position":[[1189,15]]}}}],["statsd",{"_index":8332,"t":{"2158":{"position":[[127,6]]}}}],["statu",{"_index":1331,"t":{"184":{"position":[[359,6],[445,6]]},"247":{"position":[[499,7],[527,7],[739,7]]},"253":{"position":[[2001,6]]},"344":{"position":[[28,6]]},"374":{"position":[[231,6]]},"396":{"position":[[480,6]]},"398":{"position":[[374,6],[424,6]]},"436":{"position":[[767,6],[797,6],[944,6]]},"590":{"position":[[408,6],[1173,6],[1943,6]]},"641":{"position":[[557,7]]},"644":{"position":[[206,6]]},"646":{"position":[[684,6],[1441,6],[2132,6]]},"790":{"position":[[830,7]]},"796":{"position":[[644,7]]},"798":{"position":[[639,7]]},"800":{"position":[[261,7],[290,6],[333,6]]},"840":{"position":[[115,6]]},"850":{"position":[[9160,7]]},"903":{"position":[[2733,6],[2952,8],[2966,9],[3000,10],[3026,9],[3059,10],[3094,9]]},"949":{"position":[[698,6]]},"1118":{"position":[[378,6],[831,6]]},"1150":{"position":[[40,7]]},"1305":{"position":[[68,6]]},"1317":{"position":[[962,6],[1651,6],[2180,6],[5812,6],[6340,6]]},"1342":{"position":[[268,6]]},"1347":{"position":[[189,6],[1658,6]]},"1360":{"position":[[1156,6]]},"1362":{"position":[[883,6]]},"1364":{"position":[[166,7],[243,7],[320,7],[847,7],[894,7],[941,7]]},"1368":{"position":[[1456,7],[1676,7],[2132,7],[2352,7]]},"1375":{"position":[[398,6],[1308,6]]},"1377":{"position":[[399,6],[1403,6]]},"1397":{"position":[[44,6]]},"1400":{"position":[[56,6],[94,6]]},"1404":{"position":[[208,7]]},"1430":{"position":[[67,6],[860,6],[1503,6]]},"1446":{"position":[[110,6]]},"1454":{"position":[[26,6]]},"1469":{"position":[[66,6]]},"1473":{"position":[[770,6],[848,6]]},"1484":{"position":[[9160,7]]},"1527":{"position":[[830,7]]},"1533":{"position":[[644,7]]},"1535":{"position":[[639,7]]},"1537":{"position":[[261,7],[290,6],[333,6]]},"1555":{"position":[[115,6]]},"1591":{"position":[[544,6],[685,6]]},"1625":{"position":[[2733,6],[2952,8],[2966,9],[3000,10],[3026,9],[3059,10],[3094,9]]},"1671":{"position":[[698,6]]},"1731":{"position":[[1101,6]]},"1843":{"position":[[892,6]]},"1847":{"position":[[180,6]]},"1890":{"position":[[119,6]]},"1892":{"position":[[838,7],[1034,7]]},"1957":{"position":[[1904,6],[4344,6]]},"2006":{"position":[[119,6]]},"2008":{"position":[[838,7],[1034,7]]},"2077":{"position":[[254,6],[291,6]]},"2118":{"position":[[1801,7]]},"2158":{"position":[[522,6]]},"2160":{"position":[[66,6]]},"2162":{"position":[[54,6],[148,7],[286,6],[406,6],[583,6]]},"2164":{"position":[[8,6]]},"2166":{"position":[[75,6]]},"2168":{"position":[[8,6],[77,6]]},"2170":{"position":[[74,6]]},"2176":{"position":[[1063,6]]},"2281":{"position":[[636,6]]},"2315":{"position":[[216,6],[706,6]]},"2350":{"position":[[2733,6],[2952,8],[2966,9],[3000,10],[3026,9],[3059,10],[3094,9]]},"2396":{"position":[[698,6]]},"2426":{"position":[[599,6]]},"2566":{"position":[[2063,7],[3171,7],[4008,7],[10589,7]]},"2602":{"position":[[204,6],[538,6],[584,6],[648,6]]},"2625":{"position":[[1838,6],[2127,6],[2254,6],[2387,6],[2507,6]]},"2631":{"position":[[810,6]]},"2635":{"position":[[58,6]]},"2637":{"position":[[181,6]]},"2639":{"position":[[73,6]]},"2688":{"position":[[1269,6],[2490,6],[2686,6]]},"2899":{"position":[[484,7],[829,6]]},"2983":{"position":[[71,6],[358,6]]},"2985":{"position":[[196,6],[476,6]]},"2987":{"position":[[130,7],[372,7]]},"2990":{"position":[[321,6]]},"3055":{"position":[[952,6],[985,6]]},"3132":{"position":[[497,6]]},"3308":{"position":[[146,6],[337,7],[379,7],[449,7],[647,7]]},"3310":{"position":[[182,7],[521,6]]},"3314":{"position":[[4,6],[448,6],[571,6],[850,6],[1002,7],[1010,6],[1134,6],[1565,6],[1617,6],[1700,6],[1956,6],[2037,6],[2126,6],[2230,6],[2355,6],[2369,6],[2394,6],[2428,6],[2525,6],[2561,6],[2740,6],[2944,6],[3279,6],[3375,6],[3479,6]]},"3316":{"position":[[45,6],[336,6],[1061,6]]},"3389":{"position":[[606,7]]},"3397":{"position":[[390,6]]},"3403":{"position":[[40,6]]},"3408":{"position":[[4,6]]},"3518":{"position":[[2369,6],[2419,6],[2487,6]]}}}],["status",{"_index":3002,"t":{"590":{"position":[[676,8]]},"3314":{"position":[[969,9]]}}}],["status.phas",{"_index":3000,"t":{"590":{"position":[[568,13],[892,13]]}}}],["status.readi",{"_index":3003,"t":{"590":{"position":[[790,13],[971,13]]}}}],["status=\"$(openstack",{"_index":4356,"t":{"903":{"position":[[2889,19]]},"1625":{"position":[[2889,19]]},"2350":{"position":[[2889,19]]}}}],["statusfi",{"_index":10128,"t":{"3316":{"position":[[52,8]]}}}],["stay",{"_index":1063,"t":{"168":{"position":[[605,4]]},"2312":{"position":[[516,7]]},"2715":{"position":[[125,4]]},"2862":{"position":[[125,4]]},"2947":{"position":[[1058,5]]},"2990":{"position":[[509,4]]},"3117":{"position":[[147,4]]}}}],["stderr",{"_index":2244,"t":{"374":{"position":[[758,9]]},"3050":{"position":[[550,7]]}}}],["stdin",{"_index":2079,"t":{"325":{"position":[[4123,5]]}}}],["stdout",{"_index":2057,"t":{"325":{"position":[[1394,6],[4144,8]]},"458":{"position":[[579,6]]}}}],["steer",{"_index":9901,"t":{"3182":{"position":[[383,7]]}}}],["step",{"_index":2440,"t":{"417":{"position":[[30,4],[38,4]]},"438":{"position":[[14,5]]},"460":{"position":[[526,4],[534,4]]},"462":{"position":[[30,4],[38,4]]},"469":{"position":[[363,5]]},"471":{"position":[[278,5]]},"472":{"position":[[31,5],[462,5]]},"495":{"position":[[619,6],[1500,6]]},"598":{"position":[[27,5],[457,4],[465,4],[627,4],[635,4],[718,5],[773,5],[991,5],[1101,5],[1198,5]]},"604":{"position":[[7998,4],[8006,4]]},"609":{"position":[[1667,5],[1749,5],[4551,5]]},"646":{"position":[[1187,4]]},"650":{"position":[[991,5],[2365,5],[2457,5]]},"652":{"position":[[394,5],[719,4],[958,5],[1015,4],[1139,4]]},"895":{"position":[[494,4],[502,4],[800,5]]},"913":{"position":[[3404,5]]},"936":{"position":[[90,6]]},"1061":{"position":[[392,4]]},"1112":{"position":[[5014,4]]},"1213":{"position":[[1114,4]]},"1219":{"position":[[44,6],[55,5],[280,4],[317,4],[357,4],[402,4],[444,4]]},"1224":{"position":[[530,5]]},"1234":{"position":[[862,5]]},"1256":{"position":[[795,5],[934,5]]},"1258":{"position":[[123,4],[454,5]]},"1260":{"position":[[123,4]]},"1284":{"position":[[470,4]]},"1286":{"position":[[832,5],[1099,4],[1234,4],[1242,4],[1296,5]]},"1288":{"position":[[234,5],[266,4],[611,4]]},"1294":{"position":[[1004,4],[1093,4]]},"1428":{"position":[[52,5]]},"1471":{"position":[[77,6]]},"1473":{"position":[[1200,4]]},"1477":{"position":[[128,5]]},"1571":{"position":[[1257,4]]},"1578":{"position":[[40,4]]},"1591":{"position":[[740,6]]},"1594":{"position":[[704,5]]},"1608":{"position":[[126,5]]},"1617":{"position":[[494,4],[502,4],[800,5]]},"1635":{"position":[[3404,5]]},"1658":{"position":[[90,6]]},"1676":{"position":[[968,5],[1020,5]]},"1678":{"position":[[2250,5],[2278,5]]},"1736":{"position":[[186,5]]},"1779":{"position":[[23,4],[31,4],[3616,5],[3692,4],[3700,4],[5512,4],[5850,4],[6452,4]]},"1820":{"position":[[481,4]]},"1822":{"position":[[816,4],[905,4],[1167,4],[1256,4]]},"1839":{"position":[[287,4]]},"1841":{"position":[[10,4]]},"1843":{"position":[[223,6]]},"1855":{"position":[[317,6]]},"1913":{"position":[[466,5],[1308,4]]},"1917":{"position":[[317,6]]},"1939":{"position":[[240,5]]},"1945":{"position":[[163,5]]},"1974":{"position":[[474,6]]},"1982":{"position":[[790,6]]},"1984":{"position":[[400,6]]},"2029":{"position":[[466,5],[1308,4]]},"2096":{"position":[[1734,5],[1783,4]]},"2098":{"position":[[2836,4]]},"2122":{"position":[[243,5]]},"2132":{"position":[[14,5]]},"2152":{"position":[[179,5],[302,4],[365,4],[430,4],[498,4]]},"2196":{"position":[[119,5]]},"2226":{"position":[[299,5]]},"2286":{"position":[[182,5]]},"2342":{"position":[[494,4],[502,4],[800,5]]},"2360":{"position":[[3404,5]]},"2383":{"position":[[90,6]]},"2424":{"position":[[60,5]]},"2486":{"position":[[580,4]]},"2631":{"position":[[2074,5]]},"2673":{"position":[[1222,6]]},"3231":{"position":[[373,5]]},"3234":{"position":[[403,5]]},"3238":{"position":[[836,5]]},"3253":{"position":[[158,5]]}}}],["stick",{"_index":1512,"t":{"219":{"position":[[123,6]]},"1562":{"position":[[802,5]]},"1569":{"position":[[558,5],[613,6],[714,6],[985,5]]}}}],["sticker",{"_index":1464,"t":{"208":{"position":[[27,8]]}}}],["still",{"_index":1211,"t":{"174":{"position":[[1180,5]]},"227":{"position":[[207,5]]},"372":{"position":[[514,5],[570,5]]},"381":{"position":[[1238,5]]},"421":{"position":[[1737,5]]},"428":{"position":[[1964,5]]},"509":{"position":[[321,5]]},"609":{"position":[[2572,5]]},"627":{"position":[[1941,5]]},"708":{"position":[[50,5]]},"744":{"position":[[686,5]]},"909":{"position":[[2595,5]]},"915":{"position":[[504,5],[928,5]]},"917":{"position":[[865,5]]},"922":{"position":[[499,5]]},"932":{"position":[[34,6]]},"947":{"position":[[1412,5],[2147,5]]},"1150":{"position":[[25,5]]},"1184":{"position":[[1255,5],[2354,5]]},"1246":{"position":[[103,5]]},"1258":{"position":[[216,5]]},"1260":{"position":[[228,5]]},"1294":{"position":[[405,5]]},"1587":{"position":[[808,5]]},"1631":{"position":[[2595,5]]},"1637":{"position":[[504,5],[928,5]]},"1639":{"position":[[865,5]]},"1644":{"position":[[499,5]]},"1654":{"position":[[34,6]]},"1669":{"position":[[1412,5],[2147,5]]},"1849":{"position":[[747,5]]},"1882":{"position":[[350,5]]},"1908":{"position":[[1985,5]]},"1943":{"position":[[363,5]]},"1951":{"position":[[19,5]]},"1980":{"position":[[188,5]]},"1982":{"position":[[1300,5]]},"1984":{"position":[[910,5]]},"1998":{"position":[[350,5]]},"2024":{"position":[[1985,5]]},"2035":{"position":[[66,5]]},"2150":{"position":[[908,5]]},"2226":{"position":[[309,5]]},"2229":{"position":[[976,5]]},"2233":{"position":[[54,5],[535,5]]},"2248":{"position":[[738,5]]},"2278":{"position":[[439,5]]},"2281":{"position":[[536,5]]},"2312":{"position":[[79,5]]},"2356":{"position":[[2595,5]]},"2362":{"position":[[504,5],[928,5]]},"2364":{"position":[[865,5]]},"2369":{"position":[[499,5]]},"2379":{"position":[[34,6]]},"2394":{"position":[[1412,5],[2147,5]]},"2405":{"position":[[507,5]]},"2468":{"position":[[495,5]]},"2482":{"position":[[10,5]]},"2713":{"position":[[897,5]]},"2731":{"position":[[848,5]]},"2735":{"position":[[810,5]]},"2756":{"position":[[1365,5]]},"2770":{"position":[[848,5]]},"2774":{"position":[[812,5]]},"2858":{"position":[[707,5]]},"2860":{"position":[[809,5]]},"2864":{"position":[[95,5]]},"2939":{"position":[[481,5]]},"2947":{"position":[[2314,5]]},"2966":{"position":[[3334,5]]},"3003":{"position":[[740,5]]},"3011":{"position":[[1384,5],[2464,5]]},"3014":{"position":[[781,5]]},"3063":{"position":[[1148,5]]},"3103":{"position":[[1707,5]]},"3126":{"position":[[906,5]]},"3184":{"position":[[1394,5]]},"3245":{"position":[[1436,5]]},"3249":{"position":[[250,5]]},"3270":{"position":[[1766,5]]},"3301":{"position":[[2837,5],[3642,5]]},"3312":{"position":[[226,5]]},"3370":{"position":[[170,5]]},"3434":{"position":[[170,5]]},"3482":{"position":[[1678,5]]}}}],["sto1001",{"_index":7306,"t":{"1728":{"position":[[964,8]]}}}],["sto1001:sdf",{"_index":7307,"t":{"1728":{"position":[[1054,13],[1111,11],[1312,11]]}}}],["stone",{"_index":8588,"t":{"2497":{"position":[[563,6]]}}}],["stop",{"_index":1698,"t":{"247":{"position":[[1875,8],[1918,5]]},"913":{"position":[[3114,4],[3189,4]]},"915":{"position":[[1096,4]]},"947":{"position":[[1587,4],[2069,4],[2391,7]]},"1226":{"position":[[388,4]]},"1344":{"position":[[250,4]]},"1362":{"position":[[429,4],[495,4],[543,4],[595,4],[1372,4],[1438,4],[1504,4]]},"1373":{"position":[[148,8],[206,4]]},"1428":{"position":[[359,4]]},"1432":{"position":[[36,4]]},"1471":{"position":[[209,4],[519,4],[762,4],[831,4],[1002,4],[1250,4],[1510,4],[1824,4],[1859,4],[1891,4]]},"1635":{"position":[[3114,4],[3189,4]]},"1637":{"position":[[1096,4]]},"1669":{"position":[[1587,4],[2069,4],[2391,7]]},"1728":{"position":[[1616,4]]},"1731":{"position":[[175,4],[215,4]]},"2116":{"position":[[412,7]]},"2267":{"position":[[202,4]]},"2300":{"position":[[198,4]]},"2360":{"position":[[3114,4],[3189,4]]},"2362":{"position":[[1096,4]]},"2394":{"position":[[1587,4],[2069,4],[2391,7]]},"3103":{"position":[[1403,8]]}}}],["storag",{"_index":193,"t":{"12":{"position":[[200,7]]},"44":{"position":[[125,7]]},"51":{"position":[[108,7]]},"423":{"position":[[99,7]]},"428":{"position":[[816,8]]},"447":{"position":[[16,7]]},"451":{"position":[[14,7],[136,8],[277,7],[399,7]]},"462":{"position":[[827,7]]},"467":{"position":[[99,7],[245,7]]},"471":{"position":[[481,7]]},"487":{"position":[[3033,7],[3102,8]]},"563":{"position":[[11,7],[97,8]]},"574":{"position":[[63,7]]},"596":{"position":[[5,7],[2085,8]]},"615":{"position":[[610,7],[1017,7],[1204,7],[1481,7]]},"712":{"position":[[43,8]]},"748":{"position":[[327,8],[343,8]]},"750":{"position":[[385,7]]},"760":{"position":[[124,7]]},"764":{"position":[[234,7],[289,7]]},"768":{"position":[[35,7],[244,8]]},"774":{"position":[[16,7],[57,7],[92,7],[141,7],[251,7],[293,8],[324,7],[546,7]]},"776":{"position":[[30,7],[103,8]]},"778":{"position":[[19,7],[58,7]]},"786":{"position":[[283,7]]},"788":{"position":[[47,7]]},"813":{"position":[[624,7]]},"819":{"position":[[1233,7],[3519,7],[3569,7],[6098,7],[6302,8]]},"857":{"position":[[347,7]]},"859":{"position":[[754,7],[2041,7],[2067,7]]},"865":{"position":[[67,7]]},"870":{"position":[[21,7]]},"874":{"position":[[28,7]]},"878":{"position":[[67,7]]},"880":{"position":[[40,7],[122,7],[948,7],[1023,7]]},"922":{"position":[[918,7]]},"942":{"position":[[75,8],[147,7]]},"945":{"position":[[308,8]]},"977":{"position":[[177,8],[1085,8],[1575,7],[1619,7],[1661,8],[1677,7],[1721,7],[1762,7],[2003,7]]},"984":{"position":[[95,7],[321,7]]},"986":{"position":[[12,7],[35,7],[112,7],[349,7],[364,7],[445,7]]},"995":{"position":[[64,7],[111,7]]},"1067":{"position":[[4015,7]]},"1106":{"position":[[504,7]]},"1112":{"position":[[369,7]]},"1130":{"position":[[106,7],[322,7]]},"1184":{"position":[[117,7],[1273,7],[2341,8],[2460,8]]},"1226":{"position":[[785,7]]},"1234":{"position":[[2253,7]]},"1286":{"position":[[292,7]]},"1349":{"position":[[30,7]]},"1400":{"position":[[209,7],[235,7]]},"1503":{"position":[[624,7]]},"1509":{"position":[[1233,7],[3519,7],[3569,7],[6098,7],[6302,8]]},"1523":{"position":[[283,7]]},"1525":{"position":[[47,7]]},"1562":{"position":[[492,7],[623,7]]},"1564":{"position":[[577,7]]},"1569":{"position":[[961,7]]},"1601":{"position":[[347,7]]},"1603":{"position":[[754,7],[2041,7],[2067,7]]},"1644":{"position":[[918,7]]},"1664":{"position":[[75,8],[147,7]]},"1667":{"position":[[308,8]]},"1728":{"position":[[951,7],[1218,7],[1549,7]]},"1764":{"position":[[4209,7]]},"1775":{"position":[[203,7]]},"1831":{"position":[[347,7]]},"1872":{"position":[[79,7],[92,7],[312,7],[515,7],[588,7]]},"1874":{"position":[[131,7]]},"1876":{"position":[[138,7]]},"1878":{"position":[[390,8],[1244,7]]},"1880":{"position":[[189,7],[468,7],[792,7]]},"1888":{"position":[[26,7]]},"1890":{"position":[[405,7]]},"1892":{"position":[[1233,7]]},"1911":{"position":[[334,7],[381,7],[414,7],[520,7]]},"1988":{"position":[[79,7],[92,7],[312,7],[515,7],[588,7]]},"1990":{"position":[[131,7]]},"1992":{"position":[[138,7]]},"1994":{"position":[[390,8],[1244,7]]},"1996":{"position":[[189,7],[468,7],[792,7]]},"2004":{"position":[[26,7]]},"2006":{"position":[[405,7]]},"2008":{"position":[[1233,7]]},"2027":{"position":[[334,7],[381,7],[414,7],[520,7]]},"2100":{"position":[[1088,7]]},"2190":{"position":[[84,8]]},"2245":{"position":[[543,8]]},"2369":{"position":[[918,7]]},"2389":{"position":[[75,8],[147,7]]},"2392":{"position":[[308,8]]},"2405":{"position":[[828,7]]},"2424":{"position":[[198,7]]},"2426":{"position":[[398,7]]},"2544":{"position":[[188,8]]},"2592":{"position":[[625,7]]},"2671":{"position":[[417,7]]},"2709":{"position":[[107,7],[304,7],[667,7],[1370,7]]},"2754":{"position":[[107,7],[304,7],[667,7],[1511,7]]},"2844":{"position":[[35,7],[232,7],[595,7]]},"2942":{"position":[[323,8],[849,8]]},"2944":{"position":[[77,8],[157,7],[286,7],[436,7],[585,8],[1234,7],[1381,7],[1423,7]]},"2947":{"position":[[35,9],[713,7],[868,8],[3139,8],[3222,7],[3463,7],[3909,7],[4116,8],[4872,8],[4900,7],[4951,7],[5052,7],[5254,7],[5702,7],[5742,7],[5978,8],[6045,7],[6109,7]]},"2949":{"position":[[439,7],[953,8],[1115,7]]},"2951":{"position":[[83,7],[209,7],[429,7],[758,7],[818,8]]},"2953":{"position":[[6,7]]},"2955":{"position":[[265,7]]},"2960":{"position":[[65,7],[142,7],[345,7],[455,7],[554,8],[573,7],[611,7]]},"2966":{"position":[[1225,7],[3754,7]]},"3023":{"position":[[161,7]]},"3031":{"position":[[612,7]]},"3063":{"position":[[938,7]]},"3135":{"position":[[41,7],[141,7],[266,7]]},"3141":{"position":[[247,7],[338,7],[423,7]]},"3160":{"position":[[1200,7],[1262,7]]},"3245":{"position":[[1341,7]]},"3251":{"position":[[2754,7]]},"3284":{"position":[[467,7]]},"3301":{"position":[[5051,7],[5096,7],[5287,7],[5357,7],[5492,7],[6202,7],[6231,7],[6260,7],[6571,7],[6602,7],[7452,7],[7488,7]]},"3376":{"position":[[765,7]]},"3397":{"position":[[830,7]]},"3518":{"position":[[1666,7]]}}}],["storage/drivers/pur",{"_index":5477,"t":{"1130":{"position":[[301,20]]}}}],["storage_interfac",{"_index":4980,"t":{"1067":{"position":[[5171,18]]}}}],["storage_zon",{"_index":4182,"t":{"859":{"position":[[767,13],[2054,12]]},"1603":{"position":[[767,13],[2054,12]]}}}],["storageclass",{"_index":3427,"t":{"644":{"position":[[242,12]]},"2586":{"position":[[71,12],[157,13]]},"3135":{"position":[[216,15],[232,14]]},"3137":{"position":[[43,12],[101,12],[301,12]]},"3139":{"position":[[12,12]]}}}],["storageclass.kubernetes.io/i",{"_index":8977,"t":{"2586":{"position":[[189,30]]},"3139":{"position":[[51,29]]}}}],["storageclassnam",{"_index":9887,"t":{"3137":{"position":[[181,16]]}}}],["store",{"_index":186,"t":{"12":{"position":[[85,5],[305,5]]},"187":{"position":[[183,6]]},"302":{"position":[[803,6]]},"423":{"position":[[50,5]]},"427":{"position":[[998,5]]},"444":{"position":[[300,5]]},"449":{"position":[[6,6],[162,5]]},"451":{"position":[[92,6]]},"456":{"position":[[425,6]]},"458":{"position":[[191,5],[483,6]]},"462":{"position":[[1441,5]]},"467":{"position":[[50,5],[518,5],[2007,5],[2590,5]]},"472":{"position":[[289,5],[759,6],[960,6]]},"497":{"position":[[140,6]]},"513":{"position":[[2426,6]]},"532":{"position":[[72,5]]},"574":{"position":[[115,5]]},"594":{"position":[[37,5],[71,5]]},"604":{"position":[[10667,6]]},"639":{"position":[[494,5],[756,7],[841,6]]},"764":{"position":[[350,5]]},"768":{"position":[[120,7],[138,5],[263,5]]},"776":{"position":[[182,6],[260,5]]},"786":{"position":[[135,6]]},"794":{"position":[[22,6],[246,6],[356,6]]},"903":{"position":[[1570,7]]},"911":{"position":[[1417,6]]},"977":{"position":[[1975,6]]},"1052":{"position":[[259,5]]},"1057":{"position":[[59,6]]},"1061":{"position":[[22,5],[757,6]]},"1065":{"position":[[590,6],[640,6],[875,6]]},"1067":{"position":[[507,6],[629,5]]},"1098":{"position":[[55,6]]},"1110":{"position":[[708,6]]},"1167":{"position":[[2024,6]]},"1224":{"position":[[1148,6],[1275,6],[1654,6]]},"1240":{"position":[[329,6],[1466,6]]},"1298":{"position":[[281,6]]},"1349":{"position":[[47,6]]},"1523":{"position":[[135,6]]},"1531":{"position":[[22,6],[246,6],[356,6]]},"1560":{"position":[[292,6]]},"1625":{"position":[[1570,7]]},"1633":{"position":[[1417,6]]},"1779":{"position":[[484,6],[590,5],[1765,5]]},"1872":{"position":[[209,7],[489,6],[714,7]]},"1874":{"position":[[164,6]]},"1876":{"position":[[80,6],[146,6],[169,6],[202,6]]},"1878":{"position":[[225,6]]},"1880":{"position":[[858,5]]},"1890":{"position":[[449,5]]},"1892":{"position":[[1277,5]]},"1894":{"position":[[259,7]]},"1896":{"position":[[107,6],[587,6]]},"1900":{"position":[[230,5]]},"1913":{"position":[[27,6]]},"1951":{"position":[[627,6]]},"1988":{"position":[[209,7],[489,6],[714,7]]},"1990":{"position":[[164,6]]},"1992":{"position":[[80,6],[146,6],[169,6],[202,6]]},"1994":{"position":[[225,6]]},"1996":{"position":[[858,5]]},"2006":{"position":[[449,5]]},"2008":{"position":[[1277,5]]},"2010":{"position":[[259,7]]},"2012":{"position":[[107,6],[587,6]]},"2016":{"position":[[230,5]]},"2029":{"position":[[27,6]]},"2106":{"position":[[512,5]]},"2138":{"position":[[693,5]]},"2150":{"position":[[894,5]]},"2152":{"position":[[231,5]]},"2154":{"position":[[205,7]]},"2350":{"position":[[1570,7]]},"2358":{"position":[[1417,6]]},"2506":{"position":[[93,6]]},"2576":{"position":[[206,6]]},"2899":{"position":[[1046,6]]},"2949":{"position":[[833,6]]},"3063":{"position":[[617,6]]},"3150":{"position":[[60,7]]},"3160":{"position":[[2362,5]]},"3245":{"position":[[178,6]]},"3272":{"position":[[53,5],[91,5]]},"3293":{"position":[[60,7]]},"3299":{"position":[[4800,6]]},"3301":{"position":[[3057,6]]},"3325":{"position":[[3119,5]]},"3370":{"position":[[416,6]]},"3372":{"position":[[62,7]]},"3376":{"position":[[523,5]]},"3382":{"position":[[113,5]]},"3395":{"position":[[540,6],[569,5],[674,5],[912,6]]},"3440":{"position":[[201,5]]}}}],["store.s",{"_index":6217,"t":{"1305":{"position":[[118,10]]}}}],["storegateway",{"_index":10212,"t":{"3397":{"position":[[1186,12]]}}}],["stori",{"_index":2190,"t":{"353":{"position":[[76,8]]}}}],["straight",{"_index":8064,"t":{"1978":{"position":[[613,8]]},"2897":{"position":[[402,8]]}}}],["straightforward",{"_index":548,"t":{"73":{"position":[[149,15]]},"335":{"position":[[954,15]]},"370":{"position":[[40,15]]},"383":{"position":[[62,16]]}}}],["strang",{"_index":4583,"t":{"932":{"position":[[2851,7]]},"1654":{"position":[[2851,7]]},"2379":{"position":[[2851,7]]}}}],["strategi",{"_index":499,"t":{"69":{"position":[[57,8]]},"462":{"position":[[641,10],[939,8]]},"596":{"position":[[427,8],[550,8]]},"662":{"position":[[453,9]]},"2098":{"position":[[1161,10],[2338,10]]},"2272":{"position":[[30,8]]},"2304":{"position":[[30,8]]},"2336":{"position":[[30,8]]},"2432":{"position":[[30,8]]},"2451":{"position":[[30,8]]},"2508":{"position":[[30,8]]},"3016":{"position":[[231,8]]},"3160":{"position":[[1306,10]]},"3218":{"position":[[1680,8]]},"3222":{"position":[[142,9]]},"3224":{"position":[[1826,8]]},"3274":{"position":[[440,8]]},"3284":{"position":[[74,8]]}}}],["stream",{"_index":4085,"t":{"850":{"position":[[1796,6],[1938,6],[2262,6],[2391,6],[2512,6],[2830,6]]},"1224":{"position":[[3393,7]]},"1226":{"position":[[1428,9]]},"1484":{"position":[[1796,6],[1938,6],[2262,6],[2391,6],[2512,6],[2830,6]]},"1894":{"position":[[473,7]]},"1913":{"position":[[953,7]]},"2010":{"position":[[473,7]]},"2029":{"position":[[953,7]]},"2229":{"position":[[880,8]]},"2766":{"position":[[438,9]]}}}],["stream/x86_64/images/cento",{"_index":4088,"t":{"850":{"position":[[1910,27],[2234,27]]},"1484":{"position":[[1910,27],[2234,27]]}}}],["stream/x86_64/images/checksum",{"_index":4092,"t":{"850":{"position":[[2099,29]]},"1484":{"position":[[2099,29]]}}}],["streamlin",{"_index":2136,"t":{"331":{"position":[[125,11]]},"956":{"position":[[597,11]]},"2085":{"position":[[103,11]]},"2548":{"position":[[219,11]]},"2574":{"position":[[290,10]]},"2592":{"position":[[239,12]]}}}],["strength",{"_index":1710,"t":{"247":{"position":[[2792,8]]}}}],["strengthen",{"_index":8045,"t":{"1970":{"position":[[434,13]]},"2206":{"position":[[38,13]]},"3266":{"position":[[611,12]]}}}],["stress",{"_index":4165,"t":{"853":{"position":[[21,6],[39,6]]},"855":{"position":[[36,7],[96,6],[123,6]]},"857":{"position":[[103,6],[271,6],[338,6],[367,6]]},"859":{"position":[[93,6],[300,6],[2970,6],[3031,6],[3133,6],[3236,6],[3355,6],[3474,6],[3574,6],[3689,6],[3789,6],[3904,6],[3966,6],[4027,6],[4129,6],[4232,6],[4351,6],[4470,6],[4570,6],[4685,6],[4785,6],[4900,6],[4962,6],[5064,6],[5126,6],[5228,6],[5347,6],[5466,6],[5566,6],[5666,6],[5781,6],[5896,6]]},"861":{"position":[[229,6]]},"1597":{"position":[[21,6],[39,6]]},"1599":{"position":[[36,7],[96,6],[123,6]]},"1601":{"position":[[103,6],[271,6],[338,6],[367,6]]},"1603":{"position":[[93,6],[300,6],[2970,6],[3031,6],[3133,6],[3236,6],[3355,6],[3474,6],[3574,6],[3689,6],[3789,6],[3904,6],[3966,6],[4027,6],[4129,6],[4232,6],[4351,6],[4470,6],[4570,6],[4685,6],[4785,6],[4900,6],[4962,6],[5064,6],[5126,6],[5228,6],[5347,6],[5466,6],[5566,6],[5666,6],[5781,6],[5896,6]]},"1605":{"position":[[229,6]]}}}],["strict",{"_index":9747,"t":{"3082":{"position":[[1165,6],[1649,6],[1964,6]]},"3084":{"position":[[317,6]]},"3160":{"position":[[841,6]]}}}],["strict/strong",{"_index":10018,"t":{"3255":{"position":[[431,13]]}}}],["stricter",{"_index":9333,"t":{"2735":{"position":[[273,8]]},"2774":{"position":[[409,8]]},"3082":{"position":[[1836,8]]}}}],["strictli",{"_index":8112,"t":{"2039":{"position":[[595,8]]},"2051":{"position":[[520,8]]},"3109":{"position":[[1104,8]]},"3482":{"position":[[1021,8],[1398,8]]}}}],["string",{"_index":1359,"t":{"187":{"position":[[634,6],[655,6]]},"325":{"position":[[7417,6]]},"497":{"position":[[701,6]]},"1256":{"position":[[2965,6],[3047,6]]},"1364":{"position":[[390,7]]},"1766":{"position":[[584,7]]},"2805":{"position":[[176,6],[237,6],[646,6]]},"2807":{"position":[[526,6],[592,6]]},"2809":{"position":[[37,6]]},"2811":{"position":[[167,6],[229,6],[323,6]]},"2813":{"position":[[91,6],[217,6],[314,6],[437,6],[721,6],[992,6]]},"2897":{"position":[[132,6]]},"2923":{"position":[[136,7]]},"2983":{"position":[[34,6],[78,6],[148,6],[242,7]]},"2985":{"position":[[34,6],[100,6],[203,6],[273,6],[360,7]]}}}],["stringdata",{"_index":8086,"t":{"2033":{"position":[[554,11]]}}}],["stringdata\":{\"cloudname\":\"'\"${prefix",{"_index":3517,"t":{"660":{"position":[[534,40]]}}}],["stringent",{"_index":2203,"t":{"366":{"position":[[473,9]]}}}],["strive",{"_index":509,"t":{"69":{"position":[[256,6]]},"247":{"position":[[277,6]]},"690":{"position":[[97,7]]},"2031":{"position":[[222,8]]},"2162":{"position":[[263,7]]},"2164":{"position":[[676,7]]},"2617":{"position":[[97,7]]},"2795":{"position":[[97,7]]},"2975":{"position":[[97,7]]}}}],["strong",{"_index":1103,"t":{"170":{"position":[[373,6]]},"174":{"position":[[775,6]]},"178":{"position":[[223,6]]},"1857":{"position":[[534,6]]},"1919":{"position":[[534,6]]}}}],["strongli",{"_index":1835,"t":{"280":{"position":[[17,8]]},"1100":{"position":[[105,8]]},"1395":{"position":[[102,8],[485,8]]},"1397":{"position":[[160,8]]},"1726":{"position":[[107,8]]},"3236":{"position":[[1089,8]]},"3272":{"position":[[10,8]]}}}],["structur",{"_index":745,"t":{"112":{"position":[[283,9]]},"317":{"position":[[479,9]]},"393":{"position":[[1169,9],[1271,11]]},"1779":{"position":[[564,10]]},"2156":{"position":[[70,9],[138,9]]},"2310":{"position":[[770,9]]},"2491":{"position":[[117,10]]},"2524":{"position":[[22,10]]},"2526":{"position":[[73,10]]},"2564":{"position":[[223,9]]},"2658":{"position":[[15,9]]},"2663":{"position":[[344,9]]},"2665":{"position":[[562,9]]},"2669":{"position":[[69,10]]},"2671":{"position":[[71,9],[221,9]]},"2673":{"position":[[71,9],[221,9]]},"2966":{"position":[[1371,10]]},"3061":{"position":[[178,10]]},"3071":{"position":[[377,10],[2064,9]]},"3186":{"position":[[1340,10]]},"3299":{"position":[[1254,10]]},"3325":{"position":[[273,9]]},"3351":{"position":[[267,10]]}}}],["stuck",{"_index":3688,"t":{"760":{"position":[[411,5]]},"1344":{"position":[[20,6]]},"1758":{"position":[[19,5]]},"1833":{"position":[[1242,6]]}}}],["studi",{"_index":1219,"t":{"176":{"position":[[143,5]]},"909":{"position":[[1129,5],[1599,8]]},"1631":{"position":[[1129,5],[1599,8]]},"2188":{"position":[[173,5]]},"2356":{"position":[[1129,5],[1599,8]]}}}],["stuff",{"_index":2054,"t":{"325":{"position":[[1180,6]]},"1978":{"position":[[740,5]]}}}],["style",{"_index":1894,"t":{"284":{"position":[[1314,5]]},"317":{"position":[[455,5],[666,5]]},"513":{"position":[[936,5],[2460,5],[2533,5]]},"617":{"position":[[517,5]]},"627":{"position":[[3381,5]]},"819":{"position":[[5268,6],[5543,6]]},"1509":{"position":[[5268,6],[5543,6]]},"1705":{"position":[[104,6]]},"2677":{"position":[[1188,5]]}}}],["styleguid",{"_index":747,"t":{"112":{"position":[[317,10]]}}}],["sub",{"_index":4849,"t":{"1055":{"position":[[167,3],[187,3],[340,3],[664,3],[994,3],[1226,3],[1376,3],[2296,3],[3757,3]]},"1120":{"position":[[118,3],[138,3],[291,3],[502,3],[712,3],[913,3],[1941,3],[2082,3],[2113,3]]},"2999":{"position":[[75,3]]},"3343":{"position":[[598,3],[694,3]]},"3347":{"position":[[234,5],[335,3]]},"3353":{"position":[[83,3]]}}}],["subcommand",{"_index":2341,"t":{"393":{"position":[[1658,10]]},"1791":{"position":[[2709,10]]}}}],["subdirectori",{"_index":714,"t":{"105":{"position":[[1846,12]]},"627":{"position":[[430,12],[734,13],[2352,12]]},"1713":{"position":[[75,15]]},"2656":{"position":[[30,12],[195,12]]},"2660":{"position":[[55,14]]}}}],["subdirpath",{"_index":715,"t":{"105":{"position":[[1865,10],[2045,14]]}}}],["subetwork",{"_index":7526,"t":{"1775":{"position":[[288,9]]}}}],["subject",{"_index":580,"t":{"79":{"position":[[312,8]]},"2033":{"position":[[1213,9]]},"2296":{"position":[[33,7]]},"2623":{"position":[[756,7]]},"2637":{"position":[[257,7]]},"2735":{"position":[[262,7]]},"2774":{"position":[[398,7]]},"2805":{"position":[[802,7]]},"2813":{"position":[[1415,7]]},"2951":{"position":[[1225,7]]}}}],["subjectaccessreview",{"_index":9984,"t":{"3236":{"position":[[2909,19]]}}}],["submiss",{"_index":9071,"t":{"2673":{"position":[[1787,11]]}}}],["submit",{"_index":1771,"t":{"253":{"position":[[138,6],[347,6],[592,6],[733,6],[1078,6]]},"263":{"position":[[230,10]]},"458":{"position":[[75,6]]},"627":{"position":[[1164,9],[2605,6]]},"1678":{"position":[[435,9]]},"2281":{"position":[[1134,9]]},"2688":{"position":[[788,9]]},"3314":{"position":[[1223,10],[1348,10],[1824,6],[2672,6]]}}}],["subnet",{"_index":3030,"t":{"590":{"position":[[2592,7]]},"772":{"position":[[127,8]]},"821":{"position":[[2826,9],[4164,9],[5481,9]]},"842":{"position":[[288,6],[1707,6],[1802,6],[1897,6]]},"895":{"position":[[1376,8]]},"903":{"position":[[438,7],[740,6],[756,6],[814,6],[842,6],[866,6],[3466,6]]},"909":{"position":[[1902,7]]},"1511":{"position":[[2826,9],[4164,9],[5481,9]]},"1557":{"position":[[288,6],[1707,6],[1802,6],[1897,6]]},"1585":{"position":[[2650,7],[3137,6],[3202,6]]},"1617":{"position":[[1376,8]]},"1625":{"position":[[438,7],[740,6],[756,6],[814,6],[842,6],[866,6],[3466,6]]},"1631":{"position":[[1902,7]]},"1845":{"position":[[1796,7]]},"2342":{"position":[[1376,8]]},"2350":{"position":[[438,7],[740,6],[756,6],[814,6],[842,6],[866,6],[3466,6]]},"2356":{"position":[[1902,7]]},"2502":{"position":[[129,6],[278,7]]},"2566":{"position":[[7598,11],[8027,8]]}}}],["subnetid",{"_index":8590,"t":{"2502":{"position":[[249,9]]}}}],["subnetpool",{"_index":3897,"t":{"821":{"position":[[2839,13],[4179,13],[5494,13]]},"1511":{"position":[[2839,13],[4179,13],[5494,13]]},"3109":{"position":[[2231,10],[2355,10]]}}}],["subscrib",{"_index":458,"t":{"58":{"position":[[164,9]]},"261":{"position":[[85,9]]},"3314":{"position":[[1590,9],[1725,9],[2323,11]]}}}],["subscript",{"_index":9570,"t":{"2901":{"position":[[1167,12],[1273,12],[1523,12]]},"3316":{"position":[[956,12]]}}}],["subscription_includ",{"_index":9568,"t":{"2901":{"position":[[486,22],[1079,21]]}}}],["subscription_requir",{"_index":9571,"t":{"2901":{"position":[[1440,21]]}}}],["subsect",{"_index":9582,"t":{"2913":{"position":[[325,10]]},"3156":{"position":[[239,11]]}}}],["subsequ",{"_index":3306,"t":{"629":{"position":[[4,10]]},"1884":{"position":[[188,12]]},"1886":{"position":[[390,12]]},"1888":{"position":[[154,12]]},"1900":{"position":[[988,12]]},"2000":{"position":[[188,12]]},"2002":{"position":[[390,12]]},"2004":{"position":[[154,12]]},"2016":{"position":[[988,12]]},"2093":{"position":[[183,13]]},"2154":{"position":[[974,12]]},"2625":{"position":[[875,10]]},"3160":{"position":[[2218,10]]}}}],["subset",{"_index":2117,"t":{"325":{"position":[[7733,6]]},"467":{"position":[[1098,6]]},"501":{"position":[[436,6]]},"669":{"position":[[689,6]]},"1855":{"position":[[861,6]]},"1917":{"position":[[861,6]]},"2514":{"position":[[639,6]]},"3314":{"position":[[296,6]]},"3465":{"position":[[1463,6]]}}}],["substitut",{"_index":9381,"t":{"2805":{"position":[[897,11]]},"2813":{"position":[[1354,11]]}}}],["subsystem",{"_index":119,"t":{"10":{"position":[[823,9]]}}}],["subtl",{"_index":1194,"t":{"174":{"position":[[114,7]]}}}],["subvert",{"_index":1223,"t":{"176":{"position":[[330,7]]},"2947":{"position":[[4003,8]]}}}],["succe",{"_index":3249,"t":{"615":{"position":[[296,9]]},"932":{"position":[[2199,8]]},"1654":{"position":[[2199,8]]},"1791":{"position":[[719,7]]},"1908":{"position":[[1853,7]]},"2024":{"position":[[1853,7]]},"2379":{"position":[[2199,8]]}}}],["succeed",{"_index":2399,"t":{"409":{"position":[[157,9],[221,9],[289,9],[354,9]]},"493":{"position":[[356,9],[1146,9]]},"615":{"position":[[163,11]]},"641":{"position":[[694,9]]}}}],["success",{"_index":1082,"t":{"168":{"position":[[1199,10]]},"172":{"position":[[815,10]]},"178":{"position":[[2554,10]]},"193":{"position":[[792,7]]},"245":{"position":[[1727,10]]},"302":{"position":[[850,10]]},"381":{"position":[[1379,7]]},"417":{"position":[[1041,10]]},"462":{"position":[[1464,10]]},"493":{"position":[[245,10],[736,10],[815,10],[846,10],[1035,10],[1532,10],[1617,10],[1648,10]]},"499":{"position":[[1334,11],[1357,11],[2235,10],[2320,10],[2428,11],[2501,10],[2636,11]]},"590":{"position":[[2065,10]]},"592":{"position":[[258,10]]},"669":{"position":[[1174,10]]},"1219":{"position":[[33,10]]},"1855":{"position":[[1047,10]]},"1900":{"position":[[937,10]]},"1917":{"position":[[1047,10]]},"2016":{"position":[[937,10]]},"2338":{"position":[[264,10]]},"2731":{"position":[[177,10]]},"2770":{"position":[[177,10]]},"2860":{"position":[[177,10]]},"3423":{"position":[[147,10]]}}}],["successful",{"_index":1000,"t":{"158":{"position":[[979,11]]}}}],["successfulli",{"_index":1143,"t":{"170":{"position":[[1747,12]]},"381":{"position":[[1423,14]]},"391":{"position":[[1141,12]]},"590":{"position":[[2128,12],[2145,12]]},"660":{"position":[[3238,12]]},"947":{"position":[[30,13]]},"1669":{"position":[[30,13]]},"1678":{"position":[[2184,12]]},"2196":{"position":[[1192,12]]},"2229":{"position":[[703,12]]},"2394":{"position":[[30,13]]}}}],["successor",{"_index":4306,"t":{"895":{"position":[[925,9]]},"1617":{"position":[[925,9]]},"2342":{"position":[[925,9]]}}}],["successul",{"_index":8027,"t":{"1957":{"position":[[3929,10]]}}}],["such",{"_index":463,"t":{"58":{"position":[[329,4]]},"105":{"position":[[136,4]]},"129":{"position":[[233,5]]},"166":{"position":[[540,4],[594,4]]},"168":{"position":[[1338,4]]},"170":{"position":[[2014,4]]},"172":{"position":[[532,4]]},"174":{"position":[[1127,5]]},"184":{"position":[[938,4]]},"187":{"position":[[662,4]]},"245":{"position":[[2077,4]]},"249":{"position":[[220,4]]},"265":{"position":[[122,4]]},"276":{"position":[[139,4]]},"278":{"position":[[107,4]]},"319":{"position":[[322,4]]},"347":{"position":[[313,4]]},"353":{"position":[[147,5]]},"368":{"position":[[406,4]]},"372":{"position":[[779,4]]},"379":{"position":[[733,4]]},"436":{"position":[[999,4]]},"499":{"position":[[1046,4]]},"507":{"position":[[624,4]]},"513":{"position":[[1862,5]]},"600":{"position":[[574,4]]},"604":{"position":[[7972,4],[9897,4]]},"609":{"position":[[1328,4]]},"615":{"position":[[1710,4]]},"631":{"position":[[704,4]]},"728":{"position":[[294,4]]},"742":{"position":[[186,4]]},"748":{"position":[[220,4]]},"756":{"position":[[353,4]]},"762":{"position":[[460,4]]},"764":{"position":[[252,4],[365,4],[532,4]]},"766":{"position":[[136,4]]},"772":{"position":[[382,4],[761,4]]},"786":{"position":[[651,5]]},"792":{"position":[[60,4]]},"883":{"position":[[1699,4]]},"903":{"position":[[3121,4]]},"936":{"position":[[164,4]]},"956":{"position":[[783,4],[1664,4]]},"1067":{"position":[[3693,4]]},"1112":{"position":[[1081,4],[1107,4]]},"1188":{"position":[[396,4]]},"1205":{"position":[[30,4]]},"1294":{"position":[[304,4]]},"1489":{"position":[[294,4]]},"1523":{"position":[[651,5]]},"1529":{"position":[[60,4]]},"1585":{"position":[[61,4]]},"1594":{"position":[[322,4]]},"1625":{"position":[[3121,4]]},"1658":{"position":[[164,4]]},"1674":{"position":[[224,4]]},"1684":{"position":[[1387,4],[1706,4],[2027,4],[2358,4],[2680,4],[3002,4],[3323,4],[3639,4]]},"1770":{"position":[[123,4]]},"1853":{"position":[[573,4]]},"1865":{"position":[[74,5]]},"1870":{"position":[[121,4]]},"1872":{"position":[[616,4],[743,4]]},"1874":{"position":[[229,4]]},"1878":{"position":[[60,5],[698,4]]},"1888":{"position":[[133,4]]},"1890":{"position":[[79,4]]},"1892":{"position":[[124,4]]},"1896":{"position":[[157,4]]},"1908":{"position":[[534,4]]},"1915":{"position":[[573,4]]},"1927":{"position":[[74,5]]},"1955":{"position":[[584,4]]},"1976":{"position":[[389,4],[532,5]]},"1978":{"position":[[349,5]]},"1986":{"position":[[121,4]]},"1988":{"position":[[616,4],[743,4]]},"1990":{"position":[[229,4]]},"1994":{"position":[[60,5],[698,4]]},"2004":{"position":[[133,4]]},"2006":{"position":[[79,4]]},"2008":{"position":[[124,4]]},"2012":{"position":[[157,4]]},"2024":{"position":[[534,4]]},"2043":{"position":[[353,4],[900,4]]},"2063":{"position":[[521,4]]},"2096":{"position":[[1104,4]]},"2120":{"position":[[181,4]]},"2122":{"position":[[306,4]]},"2162":{"position":[[573,5]]},"2212":{"position":[[716,4]]},"2235":{"position":[[410,4]]},"2306":{"position":[[235,4]]},"2350":{"position":[[3121,4]]},"2383":{"position":[[164,4]]},"2426":{"position":[[119,4]]},"2463":{"position":[[196,4]]},"2474":{"position":[[93,4]]},"2504":{"position":[[159,4]]},"2506":{"position":[[408,4]]},"2514":{"position":[[129,4]]},"2540":{"position":[[113,4]]},"2623":{"position":[[521,4],[647,4]]},"2625":{"position":[[166,5]]},"2647":{"position":[[391,4]]},"2673":{"position":[[1549,4]]},"2675":{"position":[[343,4]]},"2684":{"position":[[281,4]]},"2705":{"position":[[282,5]]},"2713":{"position":[[787,5]]},"2727":{"position":[[735,4]]},"2731":{"position":[[1058,4]]},"2750":{"position":[[282,5]]},"2756":{"position":[[1255,5]]},"2766":{"position":[[935,4]]},"2770":{"position":[[1051,4]]},"2786":{"position":[[279,4]]},"2840":{"position":[[190,5]]},"2852":{"position":[[1081,4]]},"2858":{"position":[[625,5]]},"2860":{"position":[[1028,4]]},"2864":{"position":[[242,4]]},"2870":{"position":[[112,4]]},"2872":{"position":[[337,4],[814,4]]},"2883":{"position":[[74,5]]},"2944":{"position":[[108,4],[824,4]]},"2947":{"position":[[4259,4],[5490,4]]},"2949":{"position":[[773,4]]},"2951":{"position":[[258,4]]},"3021":{"position":[[213,4]]},"3025":{"position":[[82,4]]},"3042":{"position":[[272,4]]},"3044":{"position":[[569,4]]},"3080":{"position":[[607,4]]},"3103":{"position":[[987,4]]},"3109":{"position":[[106,4],[1336,4]]},"3195":{"position":[[212,4]]},"3197":{"position":[[773,4],[1072,4]]},"3208":{"position":[[104,4]]},"3218":{"position":[[1068,4]]},"3224":{"position":[[1171,4],[1274,4]]},"3251":{"position":[[3542,4]]},"3270":{"position":[[270,4]]},"3301":{"position":[[3868,4]]},"3314":{"position":[[1176,4]]},"3370":{"position":[[271,4],[387,4]]},"3372":{"position":[[516,4]]},"3434":{"position":[[271,4],[387,4]]},"3459":{"position":[[102,4]]}}}],["sudo",{"_index":80,"t":{"10":{"position":[[102,4],[198,4],[396,4],[487,4],[598,4]]},"407":{"position":[[294,4]]},"432":{"position":[[294,4]]},"440":{"position":[[319,4]]},"469":{"position":[[581,4]]},"600":{"position":[[657,4]]},"604":{"position":[[127,4],[150,4],[288,4],[315,4]]},"901":{"position":[[196,4]]},"905":{"position":[[51,4],[71,4],[116,4]]},"909":{"position":[[35,4]]},"913":{"position":[[3740,4]]},"926":{"position":[[92,4],[339,4],[388,4],[404,4],[624,5],[688,4]]},"928":{"position":[[24,4],[242,4],[309,4]]},"932":{"position":[[118,4],[309,4],[358,4],[374,4],[1571,4],[1657,4]]},"934":{"position":[[158,4],[177,4],[461,4],[510,4],[562,4],[606,4],[653,4],[707,4],[749,4],[795,4],[847,4],[1518,4],[1553,4],[1588,4]]},"1089":{"position":[[2792,4]]},"1112":{"position":[[5024,4],[5202,4],[5375,4]]},"1114":{"position":[[2084,4],[2341,4],[2588,4],[3332,4],[5527,4],[5845,4],[6144,4]]},"1174":{"position":[[34,4],[90,4],[115,4]]},"1176":{"position":[[36,4],[92,4],[119,4]]},"1224":{"position":[[946,4],[1574,4],[1963,4]]},"1238":{"position":[[0,4]]},"1256":{"position":[[619,4],[1333,4]]},"1282":{"position":[[2,4]]},"1379":{"position":[[198,4],[203,4],[701,4]]},"1388":{"position":[[281,4],[467,4]]},"1571":{"position":[[851,4],[992,4],[1045,4],[1061,4],[1161,4],[1307,4],[1370,4]]},"1574":{"position":[[743,4]]},"1585":{"position":[[729,4],[1406,4],[2092,4]]},"1587":{"position":[[1196,4],[1476,4],[1513,4],[1552,4]]},"1623":{"position":[[196,4]]},"1627":{"position":[[51,4],[71,4],[116,4]]},"1631":{"position":[[35,4]]},"1635":{"position":[[3740,4]]},"1648":{"position":[[92,4],[339,4],[388,4],[404,4],[624,5],[688,4]]},"1650":{"position":[[24,4],[242,4],[309,4]]},"1654":{"position":[[118,4],[309,4],[358,4],[374,4],[1571,4],[1657,4]]},"1656":{"position":[[158,4],[177,4],[461,4],[510,4],[562,4],[606,4],[653,4],[707,4],[749,4],[795,4],[847,4],[1518,4],[1553,4],[1588,4]]},"1728":{"position":[[92,4],[1601,4]]},"1731":{"position":[[200,4],[654,4]]},"1743":{"position":[[2572,4]]},"1913":{"position":[[1489,4],[1992,4]]},"2029":{"position":[[1489,4],[1992,4]]},"2348":{"position":[[196,4]]},"2352":{"position":[[51,4],[71,4],[116,4]]},"2356":{"position":[[35,4]]},"2360":{"position":[[3740,4]]},"2373":{"position":[[92,4],[339,4],[388,4],[404,4],[624,5],[688,4]]},"2375":{"position":[[24,4],[242,4],[309,4]]},"2379":{"position":[[118,4],[309,4],[358,4],[374,4],[1571,4],[1657,4]]},"2381":{"position":[[158,4],[177,4],[461,4],[510,4],[562,4],[606,4],[653,4],[707,4],[749,4],[795,4],[847,4],[1518,4],[1553,4],[1588,4]]}}}],["suffer",{"_index":3568,"t":{"669":{"position":[[293,6]]},"3251":{"position":[[729,6]]}}}],["sufffix",{"_index":9413,"t":{"2842":{"position":[[330,8]]}}}],["suffic",{"_index":9216,"t":{"2713":{"position":[[1785,9]]},"2719":{"position":[[726,8],[752,8]]},"2858":{"position":[[1521,9]]}}}],["suffici",{"_index":1265,"t":{"178":{"position":[[645,12],[1744,10]]},"600":{"position":[[520,11]]},"909":{"position":[[2360,10]]},"1065":{"position":[[149,11]]},"1236":{"position":[[402,10]]},"1252":{"position":[[688,10]]},"1286":{"position":[[508,11]]},"1631":{"position":[[2360,10]]},"1857":{"position":[[85,10]]},"1919":{"position":[[85,10]]},"2330":{"position":[[564,11]]},"2356":{"position":[[2360,10]]},"2647":{"position":[[916,11]]},"2874":{"position":[[937,10]]},"2876":{"position":[[115,10]]},"2899":{"position":[[891,11]]},"3299":{"position":[[2435,10]]},"3442":{"position":[[326,10],[362,10]]}}}],["suffix",{"_index":1858,"t":{"282":{"position":[[452,7]]},"487":{"position":[[1696,6],[1884,6]]},"627":{"position":[[3214,6]]},"646":{"position":[[1808,7]]},"796":{"position":[[488,8]]},"798":{"position":[[527,8]]},"1533":{"position":[[488,8]]},"1535":{"position":[[527,8]]},"2700":{"position":[[215,8]]},"2702":{"position":[[14,6]]},"2705":{"position":[[92,6],[1466,6],[1814,6],[2133,6]]},"2707":{"position":[[243,6],[357,7]]},"2725":{"position":[[887,9],[897,6]]},"2727":{"position":[[622,6]]},"2745":{"position":[[215,8]]},"2747":{"position":[[14,6]]},"2750":{"position":[[92,6],[1239,6],[1768,6],[2116,6],[2435,6]]},"2752":{"position":[[243,6],[357,7]]},"2758":{"position":[[724,8],[750,8]]},"2764":{"position":[[1462,9],[1472,6]]},"2766":{"position":[[822,6]]},"2835":{"position":[[156,8]]},"2837":{"position":[[11,6]]},"2840":{"position":[[0,6],[1114,6],[1462,6],[1781,6]]},"2842":{"position":[[242,6]]},"2850":{"position":[[780,9],[790,6]]},"2852":{"position":[[969,6]]}}}],["sufix",{"_index":10139,"t":{"3325":{"position":[[218,6]]}}}],["sugar",{"_index":1539,"t":{"225":{"position":[[410,7]]},"231":{"position":[[314,6]]}}}],["suggest",{"_index":236,"t":{"23":{"position":[[3,9]]},"189":{"position":[[93,11]]},"193":{"position":[[584,11]]},"922":{"position":[[557,7]]},"932":{"position":[[2134,12]]},"1644":{"position":[[557,7]]},"1654":{"position":[[2134,12]]},"1745":{"position":[[60,9]]},"1982":{"position":[[1420,9]]},"1984":{"position":[[1030,9]]},"2369":{"position":[[557,7]]},"2379":{"position":[[2134,12]]},"2713":{"position":[[1825,7]]},"2731":{"position":[[1025,7]]},"2756":{"position":[[1571,7]]},"2770":{"position":[[1025,7]]},"2858":{"position":[[1561,7]]},"2860":{"position":[[986,7]]},"2890":{"position":[[3,7]]},"3270":{"position":[[234,8]]},"3325":{"position":[[52,10],[2360,11]]}}}],["suit",{"_index":8390,"t":{"2217":{"position":[[112,4]]},"2673":{"position":[[1615,4]]},"2688":{"position":[[284,5],[656,5]]},"2783":{"position":[[23,5]]},"2797":{"position":[[350,5]]},"2803":{"position":[[132,5]]},"2977":{"position":[[344,5]]},"3053":{"position":[[185,5],[759,5]]},"3071":{"position":[[53,5],[561,5]]},"3479":{"position":[[16,5],[59,5]]}}}],["suitabl",{"_index":1485,"t":{"212":{"position":[[119,8]]},"229":{"position":[[86,9]]},"513":{"position":[[1403,8]]},"895":{"position":[[438,8]]},"1234":{"position":[[36,9]]},"1617":{"position":[[438,8]]},"1947":{"position":[[399,8]]},"2098":{"position":[[2304,8]]},"2342":{"position":[[438,8]]},"2688":{"position":[[1006,8]]},"2947":{"position":[[1692,8]]},"2960":{"position":[[1484,8]]},"3025":{"position":[[318,8]]},"3251":{"position":[[5844,8],[5967,8]]},"3299":{"position":[[77,8]]},"3374":{"position":[[472,8]]},"3446":{"position":[[86,9]]}}}],["summar",{"_index":1562,"t":{"233":{"position":[[278,9]]},"276":{"position":[[320,10]]},"3167":{"position":[[128,9]]}}}],["summari",{"_index":4511,"t":{"920":{"position":[[869,10]]},"1642":{"position":[[869,10]]},"2367":{"position":[[869,10]]},"2874":{"position":[[843,8]]}}}],["sun",{"_index":847,"t":{"131":{"position":[[596,4]]}}}],["sunday",{"_index":3799,"t":{"805":{"position":[[239,6]]},"1542":{"position":[[239,6]]}}}],["super",{"_index":2860,"t":{"497":{"position":[[686,6],[775,6]]},"744":{"position":[[580,6]]}}}],["superior",{"_index":1743,"t":{"251":{"position":[[96,8]]}}}],["supermicro",{"_index":4703,"t":{"988":{"position":[[182,10]]}}}],["supersed",{"_index":2942,"t":{"513":{"position":[[2227,10]]},"2248":{"position":[[581,9]]},"2281":{"position":[[20,9]]},"2737":{"position":[[61,11]]},"2776":{"position":[[61,11]]},"3160":{"position":[[2243,10]]}}}],["superserv",{"_index":4704,"t":{"988":{"position":[[193,11]]}}}],["supervis",{"_index":9723,"t":{"3055":{"position":[[213,10]]}}}],["supplement",{"_index":8643,"t":{"2544":{"position":[[591,11],[675,11]]},"2623":{"position":[[574,11],[588,10]]},"2625":{"position":[[1309,11],[1427,10],[1827,10],[1961,11],[2005,10]]},"2629":{"position":[[522,11]]},"2631":{"position":[[368,11],[595,10],[848,11],[864,11]]},"2635":{"position":[[426,10]]},"3518":{"position":[[974,11],[1063,11]]}}}],["suppli",{"_index":3651,"t":{"740":{"position":[[360,6]]},"1872":{"position":[[109,8]]},"1988":{"position":[[109,8]]},"3355":{"position":[[505,8]]},"3357":{"position":[[965,9]]}}}],["supplier",{"_index":1545,"t":{"229":{"position":[[47,8]]}}}],["support",{"_index":809,"t":{"129":{"position":[[215,9]]},"131":{"position":[[3,7],[158,9]]},"170":{"position":[[508,8]]},"245":{"position":[[1801,7]]},"247":{"position":[[320,8]]},"296":{"position":[[9,8]]},"298":{"position":[[9,8]]},"304":{"position":[[22,8]]},"306":{"position":[[3,7],[57,7],[134,7]]},"313":{"position":[[71,7]]},"319":{"position":[[594,7]]},"331":{"position":[[239,7]]},"337":{"position":[[51,8],[179,8],[203,7]]},"417":{"position":[[727,8]]},"421":{"position":[[1282,9]]},"436":{"position":[[113,7]]},"462":{"position":[[860,7],[1411,8]]},"465":{"position":[[172,7]]},"467":{"position":[[541,7]]},"471":{"position":[[471,9]]},"472":{"position":[[1161,9]]},"487":{"position":[[4354,10]]},"505":{"position":[[946,7]]},"507":{"position":[[616,7]]},"509":{"position":[[433,9],[772,7]]},"604":{"position":[[1662,7]]},"609":{"position":[[1391,9]]},"615":{"position":[[465,10]]},"637":{"position":[[79,8]]},"658":{"position":[[254,8]]},"722":{"position":[[13,7]]},"748":{"position":[[200,10]]},"756":{"position":[[148,8]]},"760":{"position":[[554,9]]},"762":{"position":[[404,8]]},"764":{"position":[[503,8]]},"770":{"position":[[212,9],[312,9]]},"772":{"position":[[362,8]]},"774":{"position":[[369,10]]},"780":{"position":[[546,7]]},"786":{"position":[[633,9],[855,7]]},"880":{"position":[[250,8],[926,8]]},"888":{"position":[[1151,8],[1169,8]]},"911":{"position":[[1236,9]]},"922":{"position":[[937,9]]},"949":{"position":[[337,7]]},"956":{"position":[[991,7],[1037,8],[1933,7]]},"977":{"position":[[497,8],[647,8],[1172,8],[1323,8],[1643,7],[1902,10],[2102,8]]},"1052":{"position":[[87,9]]},"1089":{"position":[[1592,9]]},"1165":{"position":[[443,9],[530,10],[2041,9],[2312,8]]},"1184":{"position":[[236,9]]},"1217":{"position":[[102,8],[460,9]]},"1232":{"position":[[168,9]]},"1234":{"position":[[2470,7]]},"1294":{"position":[[460,9]]},"1298":{"position":[[108,10]]},"1397":{"position":[[36,7]]},"1413":{"position":[[106,10]]},"1419":{"position":[[169,7],[592,8]]},"1471":{"position":[[642,9],[1101,9],[1361,9],[1623,9],[1990,9]]},"1523":{"position":[[633,9],[855,7]]},"1566":{"position":[[78,10]]},"1569":{"position":[[269,10]]},"1585":{"position":[[1530,9],[1557,9]]},"1587":{"position":[[332,7]]},"1633":{"position":[[1236,9]]},"1644":{"position":[[937,9]]},"1671":{"position":[[337,7]]},"1736":{"position":[[40,9]]},"1766":{"position":[[870,9]]},"1773":{"position":[[59,9]]},"1777":{"position":[[257,7]]},"1779":{"position":[[1128,7]]},"1808":{"position":[[482,9],[547,9]]},"1812":{"position":[[53,10]]},"1906":{"position":[[961,8]]},"1970":{"position":[[491,10]]},"1982":{"position":[[443,7]]},"1984":{"position":[[53,7]]},"2022":{"position":[[961,8]]},"2075":{"position":[[294,8]]},"2077":{"position":[[376,8]]},"2081":{"position":[[367,8]]},"2083":{"position":[[397,8]]},"2098":{"position":[[56,8],[105,7]]},"2140":{"position":[[104,8]]},"2158":{"position":[[111,7]]},"2196":{"position":[[210,10],[1097,7]]},"2206":{"position":[[237,7]]},"2222":{"position":[[38,8]]},"2245":{"position":[[3,7],[671,7]]},"2248":{"position":[[750,9],[1083,7]]},"2257":{"position":[[78,7]]},"2276":{"position":[[233,10]]},"2278":{"position":[[3,7]]},"2292":{"position":[[70,7]]},"2302":{"position":[[52,9]]},"2315":{"position":[[598,7]]},"2358":{"position":[[1236,9]]},"2369":{"position":[[937,9]]},"2396":{"position":[[337,7]]},"2403":{"position":[[242,7]]},"2405":{"position":[[113,10],[177,9],[513,10],[850,9],[935,9]]},"2407":{"position":[[395,7]]},"2409":{"position":[[685,7]]},"2424":{"position":[[155,8]]},"2510":{"position":[[148,7],[176,7]]},"2526":{"position":[[767,7]]},"2534":{"position":[[70,7]]},"2536":{"position":[[258,7]]},"2576":{"position":[[588,7]]},"2586":{"position":[[247,8]]},"2675":{"position":[[360,8]]},"2697":{"position":[[734,8],[1342,7]]},"2719":{"position":[[120,7],[219,7],[264,8]]},"2723":{"position":[[51,7],[401,7],[477,7],[673,7],[868,7]]},"2737":{"position":[[250,7]]},"2742":{"position":[[633,8],[1241,7]]},"2758":{"position":[[120,7],[218,7],[262,8]]},"2762":{"position":[[64,7],[414,7],[490,7],[686,7],[881,7]]},"2776":{"position":[[250,7]]},"2813":{"position":[[1525,9]]},"2820":{"position":[[117,9],[186,7]]},"2832":{"position":[[734,8]]},"2848":{"position":[[51,7],[401,7],[477,7],[672,7]]},"2892":{"position":[[604,11]]},"2901":{"position":[[1636,9],[1827,7],[1946,7]]},"2923":{"position":[[673,7],[985,7]]},"2949":{"position":[[472,7],[629,7]]},"2951":{"position":[[56,7],[1050,10],[1207,9]]},"2999":{"position":[[6,7],[216,7],[485,9],[590,7]]},"3003":{"position":[[761,7]]},"3005":{"position":[[250,8]]},"3009":{"position":[[31,7]]},"3011":{"position":[[523,7],[1053,7],[1095,8],[1404,7],[1924,7],[2383,10]]},"3014":{"position":[[177,8]]},"3016":{"position":[[633,7]]},"3063":{"position":[[1079,7]]},"3071":{"position":[[323,7]]},"3124":{"position":[[311,7],[338,8],[411,7],[470,7],[693,7]]},"3126":{"position":[[342,7],[865,7],[923,7],[1127,7]]},"3128":{"position":[[835,7],[931,7],[975,9],[1017,7],[1058,7],[1168,7]]},"3132":{"position":[[212,9]]},"3141":{"position":[[24,9]]},"3160":{"position":[[543,7],[622,7],[696,7],[2292,9]]},"3167":{"position":[[523,7],[711,7]]},"3208":{"position":[[666,7],[1639,7]]},"3210":{"position":[[109,7],[528,8],[690,7]]},"3216":{"position":[[228,7],[251,7]]},"3245":{"position":[[1143,7]]},"3251":{"position":[[617,7],[808,7],[975,7],[1270,9],[1391,8],[1870,8],[2888,8],[3469,7],[3632,7],[5113,7],[5317,7],[5419,9],[5787,8]]},"3253":{"position":[[42,7],[245,7]]},"3255":{"position":[[584,8]]},"3301":{"position":[[233,9],[838,10],[3779,8],[4010,9],[4609,9],[6764,9],[7191,7],[7553,9]]},"3308":{"position":[[118,9]]},"3310":{"position":[[103,7]]},"3314":{"position":[[250,7],[1302,9]]},"3316":{"position":[[461,7],[876,7],[969,7],[1073,7],[1111,7]]},"3376":{"position":[[66,7]]},"3378":{"position":[[102,8],[684,10],[823,7]]},"3393":{"position":[[738,7]]},"3446":{"position":[[14,7]]},"3463":{"position":[[32,7]]},"3477":{"position":[[124,7]]},"3518":{"position":[[895,7]]}}}],["suppos",{"_index":3063,"t":{"596":{"position":[[2117,8]]},"2164":{"position":[[66,8]]},"2168":{"position":[[32,8]]},"2895":{"position":[[2970,8]]},"2992":{"position":[[309,8]]},"3370":{"position":[[317,8]]},"3434":{"position":[[317,8]]}}}],["suppress",{"_index":6380,"t":{"1319":{"position":[[573,8]]}}}],["sure",{"_index":2300,"t":{"387":{"position":[[370,4]]},"393":{"position":[[1150,4]]},"427":{"position":[[923,4]]},"462":{"position":[[988,4]]},"627":{"position":[[1695,4]]},"932":{"position":[[3201,4]]},"1256":{"position":[[3177,4]]},"1419":{"position":[[1112,4]]},"1446":{"position":[[166,4]]},"1569":{"position":[[625,4]]},"1654":{"position":[[3201,4]]},"1743":{"position":[[59,4]]},"1766":{"position":[[1113,4]]},"1794":{"position":[[534,4],[726,4]]},"1894":{"position":[[179,4]]},"1900":{"position":[[516,4]]},"1906":{"position":[[865,4]]},"1908":{"position":[[849,4]]},"1913":{"position":[[439,4]]},"2010":{"position":[[179,4]]},"2016":{"position":[[516,4]]},"2022":{"position":[[865,4]]},"2024":{"position":[[849,4]]},"2029":{"position":[[439,4]]},"2043":{"position":[[478,4]]},"2063":{"position":[[401,4]]},"2150":{"position":[[723,4]]},"2235":{"position":[[541,4]]},"2310":{"position":[[678,4]]},"2379":{"position":[[3201,4]]},"2731":{"position":[[1074,4]]},"3080":{"position":[[566,4]]}}}],["surfac",{"_index":8417,"t":{"2248":{"position":[[786,8]]}}}],["surpris",{"_index":9891,"t":{"3143":{"position":[[140,10]]}}}],["surrog",{"_index":9580,"t":{"2911":{"position":[[406,10]]}}}],["surround",{"_index":7956,"t":{"1900":{"position":[[911,10]]},"2016":{"position":[[911,10]]},"2100":{"position":[[555,11]]},"3162":{"position":[[553,11]]},"3301":{"position":[[2677,11]]}}}],["survey",{"_index":10206,"t":{"3393":{"position":[[2,6],[129,6]]},"3400":{"position":[[2,6],[128,6]]}}}],["surviv",{"_index":9166,"t":{"2709":{"position":[[690,7]]},"2754":{"position":[[690,7]]},"2844":{"position":[[618,7]]},"2966":{"position":[[2768,7]]},"3044":{"position":[[128,7]]},"3182":{"position":[[2451,8]]},"3184":{"position":[[2457,7]]}}}],["suscept",{"_index":9138,"t":{"2705":{"position":[[1015,11],[1389,11],[1941,11]]},"2750":{"position":[[1012,11],[1621,11],[2243,11]]},"2840":{"position":[[879,11],[1589,11]]}}}],["suse",{"_index":108,"t":{"10":{"position":[[593,4]]}}}],["suspend",{"_index":2395,"t":{"409":{"position":[[78,9]]},"641":{"position":[[622,9]]},"947":{"position":[[1510,7]]},"1669":{"position":[[1510,7]]},"2394":{"position":[[1510,7]]}}}],["sustain",{"_index":9633,"t":{"2951":{"position":[[275,7]]},"3014":{"position":[[866,14]]},"3413":{"position":[[127,11]]}}}],["svc",{"_index":270,"t":{"25":{"position":[[276,3],[405,3],[552,3],[681,3],[818,3]]},"413":{"position":[[181,3]]},"442":{"position":[[100,3]]},"641":{"position":[[1605,3]]},"646":{"position":[[1869,3]]}}}],["svc,.svc.cluster,.svc.cluster.local,127.0.0.0/8,169.254.169.254/32,fd00:ec2::254/128,${var.node_cidr},${var.pod_cidr},${var.service_cidr",{"_index":2724,"t":{"485":{"position":[[1292,139]]}}}],["svc/harbor",{"_index":2497,"t":{"434":{"position":[[152,10]]},"641":{"position":[[1792,10]]}}}],["svc_user_project",{"_index":10157,"t":{"3325":{"position":[[2222,16],[2304,16]]}}}],["svm",{"_index":9242,"t":{"2723":{"position":[[244,3],[891,3]]},"2762":{"position":[[257,3],[904,3]]},"2848":{"position":[[244,3]]}}}],["sw",{"_index":7740,"t":{"1833":{"position":[[436,2]]}}}],["swagger",{"_index":8246,"t":{"2118":{"position":[[957,7],[1024,7],[1809,7],[2032,7],[2503,7]]}}}],["swap",{"_index":3635,"t":{"730":{"position":[[2407,4]]},"1234":{"position":[[2852,4],[2882,5]]},"1491":{"position":[[2407,4]]},"1571":{"position":[[149,4]]},"1833":{"position":[[431,4]]}}}],["swappi",{"_index":5156,"t":{"1106":{"position":[[4,10]]}}}],["swift",{"_index":199,"t":{"12":{"position":[[319,5]]},"451":{"position":[[317,8]]},"467":{"position":[[165,5],[232,5],[505,5],[2577,5]]},"639":{"position":[[481,5],[828,5],[857,5]]},"764":{"position":[[260,5]]},"768":{"position":[[289,5]]},"774":{"position":[[231,5]]},"776":{"position":[[0,5],[112,5]]},"850":{"position":[[664,5],[682,5]]},"913":{"position":[[647,5]]},"922":{"position":[[905,5]]},"1108":{"position":[[253,7],[794,5],[829,5]]},"1288":{"position":[[828,5]]},"1484":{"position":[[664,5],[682,5]]},"1635":{"position":[[647,5]]},"1644":{"position":[[905,5]]},"2324":{"position":[[425,5]]},"2334":{"position":[[173,5],[241,5],[340,5]]},"2360":{"position":[[647,5]]},"2369":{"position":[[905,5]]},"2403":{"position":[[316,5]]}}}],["swift.services.a.regiocloud.tech",{"_index":4074,"t":{"850":{"position":[[535,33]]},"1161":{"position":[[3583,32]]},"1484":{"position":[[535,33]]}}}],["swift/v1/auth_b182637428444b9aa302bb8d5a5a418c",{"_index":4077,"t":{"850":{"position":[[729,48]]},"1484":{"position":[[729,48]]}}}],["swift_api_external_back",{"_index":5796,"t":{"1161":{"position":[[3628,23]]}}}],["swift_prefix",{"_index":4076,"t":{"850":{"position":[[705,13]]},"1484":{"position":[[705,13]]}}}],["swiftclient",{"_index":4372,"t":{"905":{"position":[[188,11]]},"1627":{"position":[[188,11]]},"2352":{"position":[[188,11]]}}}],["swiftcontain",{"_index":4517,"t":{"922":{"position":[[741,14],[1100,15],[1345,15]]},"942":{"position":[[173,14]]},"1644":{"position":[[741,14],[1100,15],[1345,15]]},"1664":{"position":[[173,14]]},"2369":{"position":[[741,14],[1100,15],[1345,15]]},"2389":{"position":[[173,14]]}}}],["swiftcontainer=o",{"_index":4447,"t":{"913":{"position":[[698,17]]},"1635":{"position":[[698,17]]},"2360":{"position":[[698,17]]}}}],["swiftcontainer=oshm_log",{"_index":4520,"t":{"922":{"position":[[1047,25]]},"1644":{"position":[[1047,25]]},"2369":{"position":[[1047,25]]}}}],["switch",{"_index":986,"t":{"158":{"position":[[99,6]]},"393":{"position":[[277,9]]},"874":{"position":[[70,8]]},"982":{"position":[[739,8]]},"984":{"position":[[606,8]]},"990":{"position":[[507,8]]},"995":{"position":[[261,8],[583,8],[626,8]]},"1188":{"position":[[404,8]]},"1368":{"position":[[571,6]]},"2209":{"position":[[58,6],[232,8],[259,9]]},"2459":{"position":[[238,8]]},"2705":{"position":[[1071,6]]},"2840":{"position":[[933,6]]},"3003":{"position":[[230,6],[345,7],[390,9],[547,7],[576,6],[637,9]]},"3005":{"position":[[305,9]]},"3011":{"position":[[2778,6]]}}}],["swot",{"_index":10017,"t":{"3253":{"position":[[358,4]]}}}],["sy",{"_index":4705,"t":{"988":{"position":[[205,3]]}}}],["symlink",{"_index":3096,"t":{"604":{"position":[[1407,9]]},"1676":{"position":[[689,8]]}}}],["symmetr",{"_index":7953,"t":{"1900":{"position":[[296,9]]},"2016":{"position":[[296,9]]}}}],["sync",{"_index":656,"t":{"105":{"position":[[517,5]]},"114":{"position":[[856,4]]},"428":{"position":[[1083,4]]},"1080":{"position":[[624,4],[715,4]]},"1112":{"position":[[3561,4],[4881,4]]},"1114":{"position":[[677,4],[1964,4],[4279,4],[5435,4]]},"1349":{"position":[[217,4],[300,4]]},"1475":{"position":[[536,4],[871,4]]},"1585":{"position":[[2565,4]]},"1686":{"position":[[495,7]]},"1731":{"position":[[3321,4]]},"1825":{"position":[[777,4],[878,4]]},"2675":{"position":[[813,5]]},"2715":{"position":[[133,4]]},"2862":{"position":[[133,4]]},"3126":{"position":[[449,4]]}}}],["synchron",{"_index":9056,"t":{"2667":{"position":[[228,12]]}}}],["synonym",{"_index":3699,"t":{"770":{"position":[[20,7]]}}}],["syntax",{"_index":799,"t":{"127":{"position":[[145,7],[184,7],[224,7],[267,7],[309,7]]},"131":{"position":[[130,6]]},"1458":{"position":[[137,6]]},"1705":{"position":[[149,6]]},"2328":{"position":[[28,6]]},"2735":{"position":[[59,6]]},"2756":{"position":[[122,6]]},"2774":{"position":[[195,6]]},"2783":{"position":[[0,6],[546,6]]},"2786":{"position":[[67,6]]},"2813":{"position":[[574,6]]}}}],["sys.exit",{"_index":1892,"t":{"284":{"position":[[1211,11]]},"374":{"position":[[576,12]]}}}],["sys.exit(main(sys.argv",{"_index":1893,"t":{"284":{"position":[[1272,24]]}}}],["sys/devices/virtual/misc/hw_random",{"_index":9507,"t":{"2874":{"position":[[683,36]]}}}],["sys/module/kvm_amd/parameters/nest",{"_index":5956,"t":{"1174":{"position":[[141,37]]}}}],["sys/module/kvm_intel/parameters/nest",{"_index":5959,"t":{"1176":{"position":[[147,39]]}}}],["sysctl",{"_index":4786,"t":{"1031":{"position":[[94,6]]},"1106":{"position":[[424,6]]}}}],["sysctl_default",{"_index":4787,"t":{"1031":{"position":[[161,16]]}}}],["sysctl_extra",{"_index":4804,"t":{"1031":{"position":[[688,12],[882,13]]}}}],["sysstat",{"_index":4756,"t":{"1014":{"position":[[460,7]]}}}],["system",{"_index":115,"t":{"10":{"position":[[747,7]]},"158":{"position":[[255,6],[291,6]]},"174":{"position":[[449,6],[1505,6]]},"235":{"position":[[583,8]]},"288":{"position":[[387,6]]},"379":{"position":[[265,7]]},"404":{"position":[[81,6]]},"499":{"position":[[233,6]]},"590":{"position":[[2006,6],[2194,6]]},"596":{"position":[[1915,6]]},"604":{"position":[[10,7],[87,6],[432,6],[2623,6],[2711,6],[2770,6],[2834,6],[6320,6],[6411,6]]},"609":{"position":[[6390,6]]},"660":{"position":[[3354,6]]},"762":{"position":[[88,6],[370,6]]},"764":{"position":[[387,6]]},"768":{"position":[[398,7]]},"770":{"position":[[129,7]]},"880":{"position":[[143,7]]},"907":{"position":[[174,7]]},"913":{"position":[[3375,6],[4101,6]]},"922":{"position":[[641,7]]},"926":{"position":[[672,6]]},"928":{"position":[[293,6]]},"932":{"position":[[1641,6]]},"936":{"position":[[48,6]]},"942":{"position":[[4,6]]},"956":{"position":[[533,7]]},"977":{"position":[[674,8],[1729,8]]},"982":{"position":[[535,6]]},"984":{"position":[[271,6]]},"986":{"position":[[282,6]]},"988":{"position":[[282,6]]},"990":{"position":[[336,6]]},"1033":{"position":[[363,6]]},"1059":{"position":[[413,6]]},"1063":{"position":[[200,6]]},"1067":{"position":[[3530,7],[4042,7]]},"1089":{"position":[[899,6]]},"1102":{"position":[[9,6]]},"1124":{"position":[[747,8]]},"1184":{"position":[[373,6],[549,6]]},"1224":{"position":[[2960,7],[3036,7],[3078,6],[3254,6],[3777,7],[3853,7]]},"1226":{"position":[[497,7]]},"1234":{"position":[[1610,6],[1892,7],[1920,7],[2392,6],[3161,7]]},"1236":{"position":[[477,7],[790,7]]},"1252":{"position":[[356,6],[474,6],[781,6],[904,6],[983,7],[1090,6],[1141,6],[1270,6],[1315,6]]},"1279":{"position":[[259,6]]},"1353":{"position":[[270,6]]},"1366":{"position":[[316,6]]},"1397":{"position":[[541,8]]},"1419":{"position":[[839,7],[851,6],[1069,6]]},"1471":{"position":[[852,7],[899,7],[956,6]]},"1473":{"position":[[1534,7],[1567,7],[1624,6]]},"1560":{"position":[[200,6],[405,8]]},"1562":{"position":[[4,6]]},"1569":{"position":[[193,6],[822,6],[894,6],[939,6],[1034,6],[1200,6],[1298,6],[1457,6],[1471,6],[1741,7]]},"1571":{"position":[[269,6],[404,6],[662,6],[1363,6],[1401,6],[1415,6],[1685,7]]},"1574":{"position":[[274,6]]},"1578":{"position":[[122,6]]},"1582":{"position":[[249,6]]},"1585":{"position":[[430,6]]},"1589":{"position":[[93,6]]},"1591":{"position":[[131,6]]},"1629":{"position":[[174,7]]},"1635":{"position":[[3375,6],[4101,6]]},"1644":{"position":[[641,7]]},"1648":{"position":[[672,6]]},"1650":{"position":[[293,6]]},"1654":{"position":[[1641,6]]},"1658":{"position":[[48,6]]},"1664":{"position":[[4,6]]},"1743":{"position":[[1928,6]]},"1766":{"position":[[1179,6]]},"1773":{"position":[[134,7],[525,7]]},"1777":{"position":[[30,6],[85,6]]},"1805":{"position":[[339,6]]},"1833":{"position":[[1427,7]]},"1845":{"position":[[2352,7],[2401,6]]},"1857":{"position":[[282,7],[603,6],[709,6]]},"1919":{"position":[[282,7],[603,6],[709,6]]},"1978":{"position":[[598,7]]},"2031":{"position":[[306,6]]},"2033":{"position":[[384,6],[547,6]]},"2162":{"position":[[70,7],[197,6],[352,8]]},"2176":{"position":[[22,6]]},"2188":{"position":[[183,6]]},"2263":{"position":[[368,7]]},"2281":{"position":[[162,7]]},"2354":{"position":[[174,7]]},"2360":{"position":[[3375,6],[4101,6]]},"2369":{"position":[[641,7]]},"2373":{"position":[[672,6]]},"2375":{"position":[[293,6]]},"2379":{"position":[[1641,6]]},"2383":{"position":[[48,6]]},"2389":{"position":[[4,6]]},"2409":{"position":[[389,6],[624,6]]},"2486":{"position":[[288,6]]},"2540":{"position":[[547,6]]},"2546":{"position":[[110,6]]},"2602":{"position":[[753,6]]},"2651":{"position":[[274,8]]},"2675":{"position":[[1007,6]]},"2700":{"position":[[439,6]]},"2709":{"position":[[867,6]]},"2721":{"position":[[100,7],[239,6]]},"2745":{"position":[[439,6]]},"2754":{"position":[[1008,6]]},"2760":{"position":[[112,7],[251,6]]},"2835":{"position":[[380,6]]},"2844":{"position":[[795,6]]},"2846":{"position":[[100,7],[239,6]]},"2868":{"position":[[146,7],[227,7],[292,7]]},"2872":{"position":[[25,7],[673,8]]},"2886":{"position":[[37,6]]},"2895":{"position":[[172,6]]},"2899":{"position":[[567,6],[726,8],[1089,7]]},"2966":{"position":[[2469,7]]},"3152":{"position":[[115,6]]},"3160":{"position":[[525,6],[570,6],[732,7],[1534,6]]},"3178":{"position":[[582,7]]},"3182":{"position":[[2414,6]]},"3184":{"position":[[3032,6]]},"3197":{"position":[[271,7]]},"3210":{"position":[[333,7]]},"3218":{"position":[[200,6],[780,8],[877,6],[1822,6]]},"3220":{"position":[[111,6]]},"3224":{"position":[[659,6],[688,6],[1297,6]]},"3236":{"position":[[412,7]]},"3251":{"position":[[3300,7],[4008,6]]},"3272":{"position":[[145,6],[650,6]]},"3301":{"position":[[5798,6]]},"3314":{"position":[[1845,7]]},"3325":{"position":[[319,7]]},"3353":{"position":[[134,6]]},"3357":{"position":[[1012,7]]},"3389":{"position":[[399,7],[531,6],[801,8],[843,6],[915,6]]},"3393":{"position":[[212,7]]},"3413":{"position":[[422,7]]},"3415":{"position":[[79,7],[158,7],[260,7],[557,6]]},"3436":{"position":[[43,6],[149,6],[186,6]]},"3438":{"position":[[353,6],[475,6],[520,8]]},"3442":{"position":[[70,6],[241,6]]},"3475":{"position":[[129,6]]},"3518":{"position":[[2596,6]]}}}],["system/clust",{"_index":3120,"t":{"604":{"position":[[3262,14]]}}}],["system/kubeadm:v1.6.2",{"_index":3122,"t":{"604":{"position":[[3314,21],[3366,21]]}}}],["system/openstack:v0.9.0",{"_index":3119,"t":{"604":{"position":[[3226,23]]}}}],["system:node:work",{"_index":10043,"t":{"3276":{"position":[[2702,18]]}}}],["system:serviceaccount:ten",{"_index":8097,"t":{"2033":{"position":[[1332,28]]}}}],["system_scope:al",{"_index":5506,"t":{"1150":{"position":[[862,17],[1008,18],[1064,18],[1118,18],[1174,17],[1280,17],[1429,17],[1547,17],[1665,17],[1786,17],[1895,17],[2050,17],[2168,17],[2286,17],[2409,17],[2553,17],[3074,17],[3517,17],[4034,17],[4561,17],[4670,17],[4783,17],[4898,17],[5012,17],[5126,17],[5249,17],[5394,17],[5519,17],[5681,17],[5841,17],[10895,17],[11077,17]]},"3472":{"position":[[705,17],[851,18],[907,18],[961,18],[1017,17],[1123,17],[1272,17],[1390,17],[1508,17],[1629,17],[1738,17],[1893,17],[2011,17],[2129,17],[2252,17],[2396,17],[2917,17],[3360,17],[3877,17],[4404,17],[4513,17],[4626,17],[4741,17],[4855,17],[4969,17],[5092,17],[5237,17],[5362,17],[5524,17],[5684,17],[10704,17],[10886,17]]}}}],["systemat",{"_index":4506,"t":{"920":{"position":[[270,10]]},"1642":{"position":[[270,10]]},"2310":{"position":[[747,10]]},"2367":{"position":[[270,10]]},"2536":{"position":[[42,10]]},"2700":{"position":[[684,14]]},"2719":{"position":[[332,10]]},"2745":{"position":[[684,14]]},"2758":{"position":[[330,10]]},"2852":{"position":[[126,10]]}}}],["systemctl",{"_index":3366,"t":{"635":{"position":[[2159,9],[2612,10],[2671,11],[3116,10],[3175,11]]},"913":{"position":[[3679,9],[3710,9]]},"915":{"position":[[1079,9],[1303,9]]},"926":{"position":[[630,9],[693,9]]},"928":{"position":[[247,9],[314,9]]},"932":{"position":[[1576,9],[1662,9]]},"934":{"position":[[1523,9],[1558,9],[1593,9]]},"1362":{"position":[[485,9],[533,9],[585,9],[1428,9],[1494,9]]},"1428":{"position":[[349,9],[380,9]]},"1432":{"position":[[26,9],[57,9]]},"1471":{"position":[[715,9],[779,9],[1174,9],[1202,9],[1434,9],[1462,9],[1725,9],[1780,9],[1849,9],[2063,9],[2091,9]]},"1473":{"position":[[356,9],[518,9],[708,9],[1469,9],[1716,9]]},"1587":{"position":[[1518,9],[1557,9]]},"1635":{"position":[[3679,9],[3710,9]]},"1637":{"position":[[1079,9],[1303,9]]},"1648":{"position":[[630,9],[693,9]]},"1650":{"position":[[247,9],[314,9]]},"1654":{"position":[[1576,9],[1662,9]]},"1656":{"position":[[1523,9],[1558,9],[1593,9]]},"1728":{"position":[[1606,9]]},"1731":{"position":[[205,9],[659,9]]},"2360":{"position":[[3679,9],[3710,9]]},"2362":{"position":[[1079,9],[1303,9]]},"2373":{"position":[[630,9],[693,9]]},"2375":{"position":[[247,9],[314,9]]},"2379":{"position":[[1576,9],[1662,9]]},"2381":{"position":[[1523,9],[1558,9],[1593,9]]},"2468":{"position":[[901,9]]}}}],["systemd",{"_index":3041,"t":{"596":{"position":[[276,7],[392,7]]},"913":{"position":[[4073,7]]},"1635":{"position":[[4073,7]]},"1833":{"position":[[1396,7]]},"2360":{"position":[[4073,7]]},"3216":{"position":[[220,7]]},"3218":{"position":[[351,7]]},"3220":{"position":[[153,8]]},"3224":{"position":[[709,7]]}}}],["systemd.netdev",{"_index":5116,"t":{"1094":{"position":[[43,14]]}}}],["szubam4j+mayep+41vl0cpslu91gzxeatwmapin8onehf6qqiv0wb6vakd5aeayerisb3",{"_index":2094,"t":{"325":{"position":[[4914,69]]}}}],["t",{"_index":4411,"t":{"909":{"position":[[922,1]]},"913":{"position":[[1914,1],[2342,1],[2345,1],[2421,1],[2589,1]]},"1368":{"position":[[1500,1],[2176,1]]},"1631":{"position":[[922,1]]},"1635":{"position":[[1914,1],[2342,1],[2345,1],[2421,1],[2589,1]]},"1773":{"position":[[523,1]]},"2281":{"position":[[160,1]]},"2288":{"position":[[174,1]]},"2356":{"position":[[922,1]]},"2360":{"position":[[1914,1],[2342,1],[2345,1],[2421,1],[2589,1]]},"2625":{"position":[[1103,1]]},"2705":{"position":[[124,1]]},"2750":{"position":[[124,1]]},"2840":{"position":[[32,1]]},"2923":{"position":[[548,3]]}}}],["t&c",{"_index":4436,"t":{"911":{"position":[[1285,4]]},"1633":{"position":[[1285,4]]},"2358":{"position":[[1285,4]]}}}],["t.md",{"_index":9011,"t":{"2625":{"position":[[978,5]]}}}],["t=ture",{"_index":9292,"t":{"2727":{"position":[[411,9]]},"2766":{"position":[[611,9]]},"2852":{"position":[[781,9]]}}}],["tab",{"_index":7569,"t":{"1785":{"position":[[368,3]]},"1816":{"position":[[613,5],[619,5]]},"1957":{"position":[[815,3],[2548,3],[2878,3]]}}}],["tabl",{"_index":1457,"t":{"206":{"position":[[426,7]]},"210":{"position":[[578,6]]},"231":{"position":[[36,6]]},"905":{"position":[[1637,6]]},"1089":{"position":[[1436,5]]},"1161":{"position":[[314,5]]},"1169":{"position":[[493,5]]},"1311":{"position":[[96,5]]},"1627":{"position":[[1637,6]]},"1678":{"position":[[2479,5]]},"1773":{"position":[[778,6]]},"1779":{"position":[[1629,5]]},"1789":{"position":[[267,6]]},"1791":{"position":[[2735,6]]},"2352":{"position":[[1637,6]]},"2627":{"position":[[1019,6]]},"2721":{"position":[[166,6]]},"2760":{"position":[[178,6]]},"2766":{"position":[[231,5]]},"2846":{"position":[[166,6]]},"2931":{"position":[[25,5]]},"3031":{"position":[[14,5]]},"3076":{"position":[[36,5],[131,5]]},"3088":{"position":[[17,6]]},"3097":{"position":[[51,5]]},"3236":{"position":[[489,5]]},"3301":{"position":[[5539,6],[7374,5],[7668,5]]},"3518":{"position":[[387,5]]}}}],["table.pi",{"_index":7183,"t":{"1678":{"position":[[2514,8]]}}}],["tacker_external_fqdn",{"_index":5705,"t":{"1159":{"position":[[1887,20]]}}}],["tacker_public_endpoint",{"_index":5704,"t":{"1159":{"position":[[1864,22]]}}}],["tacker_server_public_port",{"_index":5706,"t":{"1159":{"position":[[1937,26]]}}}],["tactic",{"_index":1166,"t":{"170":{"position":[[2295,7]]},"178":{"position":[[2460,7]]}}}],["tag",{"_index":2016,"t":{"321":{"position":[[1117,4]]},"325":{"position":[[3225,3],[7018,4],[7127,3],[7532,3],[7567,3]]},"387":{"position":[[66,4]]},"393":{"position":[[1028,3]]},"428":{"position":[[996,4]]},"449":{"position":[[103,3]]},"493":{"position":[[1915,3]]},"790":{"position":[[1081,5]]},"796":{"position":[[826,5]]},"798":{"position":[[784,5]]},"800":{"position":[[249,5]]},"850":{"position":[[9454,5]]},"1080":{"position":[[1044,3]]},"1156":{"position":[[47,3],[144,4],[204,4],[278,3],[379,3]]},"1317":{"position":[[6013,4]]},"1484":{"position":[[9454,5]]},"1527":{"position":[[1081,5]]},"1533":{"position":[[826,5]]},"1535":{"position":[[784,5]]},"1537":{"position":[[249,5]]},"1676":{"position":[[98,3]]},"1678":{"position":[[495,3],[1018,4],[1307,6],[1529,5],[2208,3],[2615,4],[2709,3]]},"1825":{"position":[[1207,3]]},"1845":{"position":[[896,4]]},"1847":{"position":[[988,3]]},"2114":{"position":[[100,3]]},"2154":{"position":[[1304,4]]},"2237":{"position":[[69,3]]},"2267":{"position":[[69,3]]},"2300":{"position":[[69,3]]},"2332":{"position":[[75,4]]},"2428":{"position":[[32,6],[51,4]]},"2499":{"position":[[76,3]]},"2897":{"position":[[343,4]]},"2899":{"position":[[1211,4]]},"3014":{"position":[[439,4]]},"3160":{"position":[[2147,5],[2235,3]]},"3301":{"position":[[6703,3],[6730,3]]}}}],["tag#2120",{"_index":7282,"t":{"1728":{"position":[[146,8],[255,8],[349,8],[430,8]]}}}],["tail",{"_index":2633,"t":{"472":{"position":[[2147,4]]},"1315":{"position":[[307,4],[372,4],[438,4]]},"2944":{"position":[[1464,4]]}}}],["tailor",{"_index":2147,"t":{"335":{"position":[[382,8]]},"883":{"position":[[1653,6]]},"888":{"position":[[2127,6]]},"2079":{"position":[[321,8]]}}}],["take",{"_index":586,"t":{"79":{"position":[[495,4]]},"227":{"position":[[366,5]]},"272":{"position":[[14,4]]},"413":{"position":[[81,4]]},"436":{"position":[[182,4]]},"442":{"position":[[0,4]]},"501":{"position":[[271,4]]},"505":{"position":[[242,5]]},"511":{"position":[[463,4]]},"557":{"position":[[281,5]]},"586":{"position":[[506,4]]},"598":{"position":[[782,5]]},"627":{"position":[[2104,4],[4054,4]]},"631":{"position":[[563,4]]},"646":{"position":[[1665,4]]},"648":{"position":[[557,4]]},"654":{"position":[[612,4]]},"796":{"position":[[1193,5]]},"798":{"position":[[1248,5]]},"819":{"position":[[1820,4],[2000,6]]},"821":{"position":[[1272,4],[1452,6]]},"850":{"position":[[8759,4]]},"859":{"position":[[1338,4],[1518,6],[6793,4]]},"922":{"position":[[338,4]]},"932":{"position":[[3684,4]]},"1067":{"position":[[2056,4]]},"1077":{"position":[[693,5],[1158,5]]},"1112":{"position":[[3867,4]]},"1167":{"position":[[3724,5]]},"1395":{"position":[[359,4]]},"1430":{"position":[[668,4]]},"1442":{"position":[[142,4]]},"1446":{"position":[[76,4]]},"1471":{"position":[[92,4]]},"1473":{"position":[[619,4]]},"1484":{"position":[[8759,4]]},"1509":{"position":[[1820,4],[2000,6]]},"1511":{"position":[[1272,4],[1452,6]]},"1533":{"position":[[1193,5]]},"1535":{"position":[[1248,5]]},"1569":{"position":[[859,4],[1274,5],[1357,5]]},"1582":{"position":[[63,5]]},"1603":{"position":[[1338,4],[1518,6],[6793,4]]},"1644":{"position":[[338,4]]},"1654":{"position":[[3684,4]]},"1674":{"position":[[156,4],[429,4],[563,4]]},"1728":{"position":[[1430,4]]},"1779":{"position":[[3934,5],[5670,4],[5860,4]]},"1882":{"position":[[429,4]]},"1972":{"position":[[1020,4]]},"1978":{"position":[[677,5]]},"1998":{"position":[[429,4]]},"2067":{"position":[[1459,4]]},"2069":{"position":[[132,4]]},"2369":{"position":[[338,4]]},"2379":{"position":[[3684,4]]},"2709":{"position":[[275,4]]},"2754":{"position":[[275,4]]},"2844":{"position":[[203,4]]},"2870":{"position":[[209,4]]},"2937":{"position":[[95,5]]},"2947":{"position":[[2098,4]]},"2951":{"position":[[946,4]]},"2966":{"position":[[3942,4]]},"2990":{"position":[[541,4]]},"3227":{"position":[[167,4]]},"3245":{"position":[[796,6]]},"3251":{"position":[[4295,4]]},"3282":{"position":[[78,4]]},"3357":{"position":[[184,6],[279,6]]}}}],["taken",{"_index":2187,"t":{"349":{"position":[[519,5]]},"669":{"position":[[483,5]]},"1462":{"position":[[232,5]]},"1473":{"position":[[32,5]]},"1477":{"position":[[152,5]]},"2152":{"position":[[506,5]]},"2623":{"position":[[399,6]]},"2688":{"position":[[1419,5]]},"2947":{"position":[[1089,5]]},"3059":{"position":[[1089,5]]},"3236":{"position":[[123,6]]},"3457":{"position":[[602,5]]}}}],["talk",{"_index":465,"t":{"58":{"position":[[349,5]]},"63":{"position":[[108,4]]},"176":{"position":[[77,5]]},"627":{"position":[[1991,4],[2318,4]]},"772":{"position":[[1041,4]]},"907":{"position":[[527,4]]},"1629":{"position":[[527,4]]},"2354":{"position":[[527,4]]},"2715":{"position":[[438,5]]},"2790":{"position":[[37,5]]}}}],["tang",{"_index":8422,"t":{"2248":{"position":[[1356,4]]},"2276":{"position":[[178,4]]},"2482":{"position":[[225,4]]}}}],["tanzu/velero/releases/download/v1.10.2/velero",{"_index":2601,"t":{"469":{"position":[[464,45]]}}}],["tap8fe7d09b",{"_index":6687,"t":{"1366":{"position":[[600,11],[625,11]]}}}],["tar",{"_index":2603,"t":{"469":{"position":[[537,3]]},"1731":{"position":[[453,3],[845,3]]}}}],["target",{"_index":276,"t":{"25":{"position":[[435,6]]},"27":{"position":[[646,6],[678,6],[806,6]]},"105":{"position":[[1386,6]]},"114":{"position":[[167,9],[404,6]]},"193":{"position":[[536,6]]},"391":{"position":[[1343,8]]},"421":{"position":[[373,6],[1496,6]]},"523":{"position":[[86,7]]},"527":{"position":[[36,8],[56,7]]},"598":{"position":[[1012,8]]},"633":{"position":[[546,6],[621,6],[2544,6]]},"639":{"position":[[520,9]]},"669":{"position":[[935,7]]},"833":{"position":[[68,7],[163,6]]},"835":{"position":[[64,7],[146,6]]},"909":{"position":[[2846,6]]},"917":{"position":[[626,6]]},"1150":{"position":[[722,6]]},"1548":{"position":[[68,7],[163,6]]},"1550":{"position":[[64,7],[146,6]]},"1631":{"position":[[2846,6]]},"1639":{"position":[[626,6]]},"1690":{"position":[[298,7],[400,7]]},"1785":{"position":[[337,6],[707,7]]},"1816":{"position":[[24,8]]},"1878":{"position":[[32,7],[383,6],[1252,6]]},"1888":{"position":[[117,6]]},"1892":{"position":[[461,6],[1002,6]]},"1894":{"position":[[198,6]]},"1906":{"position":[[207,6]]},"1908":{"position":[[1100,7],[1775,6],[2636,6]]},"1994":{"position":[[32,7],[383,6],[1252,6]]},"2004":{"position":[[117,6]]},"2008":{"position":[[461,6],[1002,6]]},"2010":{"position":[[198,6]]},"2022":{"position":[[207,6]]},"2024":{"position":[[1100,7],[1775,6],[2636,6]]},"2053":{"position":[[443,6]]},"2075":{"position":[[82,6],[374,6]]},"2087":{"position":[[216,8]]},"2096":{"position":[[1884,6]]},"2098":{"position":[[2941,7],[3019,8]]},"2122":{"position":[[297,8]]},"2212":{"position":[[756,8]]},"2356":{"position":[[2846,6]]},"2364":{"position":[[626,6]]},"2815":{"position":[[1104,6]]},"2886":{"position":[[243,9]]},"3014":{"position":[[659,7]]},"3078":{"position":[[802,6]]},"3109":{"position":[[341,6]]},"3160":{"position":[[1881,6]]},"3266":{"position":[[139,6]]},"3472":{"position":[[572,6]]}}}],["target/sourc",{"_index":7903,"t":{"1855":{"position":[[657,13]]},"1917":{"position":[[657,13]]}}}],["target_act",{"_index":8848,"t":{"2566":{"position":[[7227,14]]}}}],["target_file_path",{"_index":7924,"t":{"1878":{"position":[[1098,17]]},"1894":{"position":[[413,17]]},"1994":{"position":[[1098,17]]},"2010":{"position":[[413,17]]}}}],["target_gid=\"$(id",{"_index":4899,"t":{"1063":{"position":[[320,16]]}}}],["target_id",{"_index":8839,"t":{"2566":{"position":[[6582,10],[7190,10],[10051,10],[14240,10]]}}}],["target_metadata_contain",{"_index":8854,"t":{"2566":{"position":[[7396,26]]}}}],["target_metadata_object",{"_index":8856,"t":{"2566":{"position":[[7465,23]]}}}],["target_metadata_path",{"_index":8850,"t":{"2566":{"position":[[7272,21]]}}}],["target_metadata_vers",{"_index":8852,"t":{"2566":{"position":[[7331,24]]}}}],["target_nam",{"_index":7969,"t":{"1908":{"position":[[755,12],[778,12],[2799,12],[2822,12],[3004,12]]},"2024":{"position":[[755,12],[778,12],[2799,12],[2822,12],[3004,12]]},"2566":{"position":[[10135,12]]}}}],["target_project_id",{"_index":9812,"t":{"3109":{"position":[[782,17],[2996,17]]}}}],["target_typeuri",{"_index":8837,"t":{"2566":{"position":[[6535,15],[7143,15],[10088,15],[14277,15]]}}}],["target_uid=\"$(id",{"_index":4898,"t":{"1063":{"position":[[293,16]]}}}],["task",{"_index":873,"t":{"135":{"position":[[0,5]]},"139":{"position":[[83,4],[231,4],[244,4],[366,4]]},"141":{"position":[[82,4],[211,4]]},"143":{"position":[[502,6]]},"191":{"position":[[5,4]]},"193":{"position":[[6,4]]},"195":{"position":[[5,4]]},"202":{"position":[[5,4]]},"210":{"position":[[5,4]]},"214":{"position":[[5,4]]},"225":{"position":[[5,4]]},"227":{"position":[[5,4]]},"229":{"position":[[5,4]]},"231":{"position":[[5,4]]},"233":{"position":[[5,4]]},"325":{"position":[[2286,6],[7681,5],[7823,6]]},"366":{"position":[[1312,6]]},"458":{"position":[[115,5]]},"491":{"position":[[350,5]]},"600":{"position":[[568,5]]},"876":{"position":[[442,5]]},"883":{"position":[[1883,6]]},"977":{"position":[[1204,6]]},"1077":{"position":[[582,4],[714,4],[1048,4],[1179,4]]},"1165":{"position":[[387,4]]},"1167":{"position":[[132,4],[269,4],[2630,4]]},"1273":{"position":[[399,6]]},"1315":{"position":[[269,5]]},"1317":{"position":[[458,4],[516,4],[577,4],[636,4],[989,5],[1870,9],[1963,4],[5498,4],[6394,5],[7239,5]]},"1342":{"position":[[25,5],[56,4]]},"1344":{"position":[[10,5],[177,5]]},"1383":{"position":[[440,6]]},"1585":{"position":[[2907,6]]},"1695":{"position":[[0,5]]},"1697":{"position":[[83,4],[232,4],[245,4],[367,4]]},"1699":{"position":[[75,4]]},"1721":{"position":[[49,4],[206,4]]},"1734":{"position":[[9,4]]},"1743":{"position":[[781,6],[1904,6]]},"2041":{"position":[[380,5],[473,5]]},"2463":{"position":[[731,5]]},"3184":{"position":[[1307,6]]},"3308":{"position":[[56,5]]}}}],["taskflow_executor",{"_index":3721,"t":{"786":{"position":[[1159,19]]},"1523":{"position":[[1159,19]]}}}],["taxonomi",{"_index":9059,"t":{"2669":{"position":[[122,9]]}}}],["tb",{"_index":7108,"t":{"1587":{"position":[[793,3]]}}}],["tbd",{"_index":9257,"t":{"2725":{"position":[[420,3],[465,3],[516,3],[564,3],[600,3]]},"2764":{"position":[[641,3],[686,3],[737,3],[785,3],[821,3]]},"2813":{"position":[[1581,3]]},"2850":{"position":[[329,3],[374,3],[425,3],[473,3],[493,3]]},"3147":{"position":[[0,3]]}}}],["tbyte",{"_index":4699,"t":{"984":{"position":[[305,5],[517,5]]},"990":{"position":[[312,5]]},"1562":{"position":[[511,5],[578,5]]}}}],["tcp",{"_index":2918,"t":{"507":{"position":[[396,5]]},"903":{"position":[[1044,3],[1346,3]]},"1625":{"position":[[1044,3],[1346,3]]},"1743":{"position":[[263,3],[1175,5],[1286,3]]},"1857":{"position":[[344,3]]},"1863":{"position":[[616,3],[787,3],[961,3]]},"1919":{"position":[[344,3]]},"1925":{"position":[[616,3],[787,3],[961,3]]},"2120":{"position":[[207,4]]},"2350":{"position":[[1044,3],[1346,3]]},"3236":{"position":[[529,3],[563,3],[602,3],[626,3],[745,3],[873,3]]}}}],["tcp:192.168.16.10:6643",{"_index":6728,"t":{"1368":{"position":[[1653,22],[1973,23]]}}}],["tcp:192.168.16.10:6644",{"_index":6746,"t":{"1368":{"position":[[2329,22],[2652,23]]}}}],["tcp:192.168.16.11:6643",{"_index":6735,"t":{"1368":{"position":[[2018,23]]}}}],["tcp:192.168.16.11:6644",{"_index":6750,"t":{"1368":{"position":[[2697,23]]}}}],["tcp:192.168.16.12:6643",{"_index":6737,"t":{"1368":{"position":[[2076,23]]}}}],["tcp:192.168.16.12:6644",{"_index":6752,"t":{"1368":{"position":[[2755,23]]}}}],["td",{"_index":6300,"t":{"1317":{"position":[[3712,2]]}}}],["tea",{"_index":1537,"t":{"225":{"position":[[399,4]]},"231":{"position":[[295,4]]}}}],["team",{"_index":51,"t":{"4":{"position":[[632,5]]},"18":{"position":[[238,4]]},"23":{"position":[[441,4]]},"63":{"position":[[16,5]]},"65":{"position":[[7,4],[44,6],[51,4],[61,4],[76,4],[96,4]]},"77":{"position":[[4,4]]},"79":{"position":[[343,5],[546,4]]},"101":{"position":[[4,4]]},"235":{"position":[[1196,4],[1307,4]]},"245":{"position":[[1128,4]]},"327":{"position":[[488,5]]},"329":{"position":[[14,6]]},"513":{"position":[[88,5],[253,4],[458,4]]},"694":{"position":[[30,4]]},"780":{"position":[[132,4],[141,4]]},"932":{"position":[[871,4]]},"954":{"position":[[284,4]]},"1654":{"position":[[871,4]]},"1951":{"position":[[107,4],[539,4]]},"2214":{"position":[[443,5]]},"2229":{"position":[[286,5]]},"2292":{"position":[[113,4]]},"2294":{"position":[[312,4]]},"2338":{"position":[[203,4]]},"2379":{"position":[[871,4]]},"2434":{"position":[[119,4]]},"2506":{"position":[[342,4]]},"2550":{"position":[[524,6]]},"2629":{"position":[[275,4],[336,4],[392,4],[435,4]]},"2688":{"position":[[708,5]]},"2697":{"position":[[325,7]]},"2705":{"position":[[1201,5]]},"2731":{"position":[[1532,5]]},"2742":{"position":[[325,7]]},"2750":{"position":[[1201,5]]},"2770":{"position":[[1555,5]]},"2817":{"position":[[288,4]]},"2832":{"position":[[325,7]]},"2840":{"position":[[1063,5]]},"2860":{"position":[[1516,5]]},"2921":{"position":[[325,7]]},"3016":{"position":[[5,4]]},"3053":{"position":[[620,5]]},"3160":{"position":[[1159,6]]},"3255":{"position":[[840,4]]},"3389":{"position":[[905,4],[985,4]]},"3482":{"position":[[111,4],[754,4],[967,4],[978,4],[2004,4]]},"3518":{"position":[[363,5]]}}}],["tear",{"_index":2317,"t":{"391":{"position":[[902,4],[1166,4]]},"895":{"position":[[1187,4]]},"915":{"position":[[1211,4]]},"1617":{"position":[[1187,4]]},"1637":{"position":[[1211,4]]},"2342":{"position":[[1187,4]]},"2362":{"position":[[1211,4]]},"3195":{"position":[[104,4]]}}}],["teardown",{"_index":2958,"t":{"523":{"position":[[105,8]]}}}],["tech",{"_index":46,"t":{"4":{"position":[[560,4]]},"257":{"position":[[214,4]]},"487":{"position":[[5067,4]]},"2164":{"position":[[166,4],[315,4]]},"2166":{"position":[[107,4]]},"2170":{"position":[[111,4]]}}}],["technic",{"_index":735,"t":{"109":{"position":[[64,9]]},"129":{"position":[[177,12]]},"168":{"position":[[754,13]]},"247":{"position":[[2619,10]]},"349":{"position":[[532,9]]},"366":{"position":[[267,9],[1560,9]]},"583":{"position":[[656,9]]},"780":{"position":[[726,9]]},"786":{"position":[[595,12]]},"1523":{"position":[[595,12]]},"1943":{"position":[[303,9],[374,9]]},"1951":{"position":[[375,9]]},"2196":{"position":[[606,9],[746,9]]},"2229":{"position":[[134,9],[985,9]]},"2276":{"position":[[203,9]]},"2281":{"position":[[721,9],[917,9]]},"2324":{"position":[[455,9],[541,9],[650,9]]},"2405":{"position":[[141,10],[580,9]]},"2407":{"position":[[249,9]]},"2409":{"position":[[915,9]]},"2459":{"position":[[186,9]]},"2463":{"position":[[383,9]]},"2484":{"position":[[424,9]]},"2546":{"position":[[202,9]]},"2623":{"position":[[165,9],[368,9]]},"2671":{"position":[[4,9]]},"2673":{"position":[[4,9],[991,9]]},"2864":{"position":[[156,9]]},"2888":{"position":[[54,9]]},"2895":{"position":[[262,12]]},"3154":{"position":[[527,9]]},"3204":{"position":[[577,9]]},"3206":{"position":[[428,9]]},"3224":{"position":[[53,9],[1657,9]]},"3247":{"position":[[742,9]]},"3249":{"position":[[561,11]]},"3477":{"position":[[264,9]]},"3482":{"position":[[3194,9]]},"3484":{"position":[[317,9]]}}}],["techniqu",{"_index":1872,"t":{"284":{"position":[[388,10]]},"633":{"position":[[2071,10]]},"772":{"position":[[371,10]]},"3270":{"position":[[2114,11]]}}}],["technlog",{"_index":10222,"t":{"3403":{"position":[[122,9]]}}}],["technolog",{"_index":1546,"t":{"229":{"position":[[108,10]]},"235":{"position":[[265,10]]},"242":{"position":[[477,12]]},"366":{"position":[[131,12],[1184,15]]},"1587":{"position":[[684,10]]},"1970":{"position":[[294,10]]},"2077":{"position":[[107,12]]},"2229":{"position":[[99,11]]},"2306":{"position":[[385,10]]},"2310":{"position":[[1084,10]]},"2338":{"position":[[341,10]]},"2520":{"position":[[648,12]]},"2868":{"position":[[69,11]]},"3247":{"position":[[85,13]]},"3301":{"position":[[2077,11],[3660,10],[6493,10]]},"3310":{"position":[[793,10]]},"3405":{"position":[[77,12]]},"3518":{"position":[[259,11]]}}}],["tediou",{"_index":2296,"t":{"387":{"position":[[117,8]]}}}],["tee",{"_index":4534,"t":{"926":{"position":[[344,3]]},"932":{"position":[[314,3]]},"1174":{"position":[[39,3]]},"1176":{"position":[[41,3]]},"1475":{"position":[[880,3]]},"1648":{"position":[[344,3]]},"1654":{"position":[[314,3]]},"2373":{"position":[[344,3]]},"2379":{"position":[[314,3]]}}}],["telegraf",{"_index":4479,"t":{"913":{"position":[[2927,8]]},"926":{"position":[[11,8],[424,8],[648,10],[710,9]]},"930":{"position":[[58,8]]},"932":{"position":[[2172,9]]},"934":{"position":[[120,8],[194,8],[946,9],[1541,8],[1865,9]]},"942":{"position":[[436,9]]},"1635":{"position":[[2927,8]]},"1648":{"position":[[11,8],[424,8],[648,10],[710,9]]},"1652":{"position":[[58,8]]},"1654":{"position":[[2172,9]]},"1656":{"position":[[120,8],[194,8],[946,9],[1541,8],[1865,9]]},"1664":{"position":[[436,9]]},"2281":{"position":[[282,8]]},"2360":{"position":[[2927,8]]},"2373":{"position":[[11,8],[424,8],[648,10],[710,9]]},"2377":{"position":[[58,8]]},"2379":{"position":[[2172,9]]},"2381":{"position":[[120,8],[194,8],[946,9],[1541,8],[1865,9]]},"2389":{"position":[[436,9]]}}}],["telekom",{"_index":8453,"t":{"2281":{"position":[[185,7]]}}}],["telemetri",{"_index":3670,"t":{"748":{"position":[[370,9]]},"865":{"position":[[441,9]]},"878":{"position":[[441,9]]},"1360":{"position":[[564,9],[1090,9]]},"2651":{"position":[[384,9]]},"3370":{"position":[[45,9]]},"3389":{"position":[[435,9],[955,9]]},"3393":{"position":[[220,9],[450,9],[644,9],[789,9],[1172,9]]},"3419":{"position":[[104,9]]},"3434":{"position":[[45,9]]}}}],["teleport",{"_index":4269,"t":{"865":{"position":[[410,8]]},"878":{"position":[[410,8]]},"2259":{"position":[[116,8]]}}}],["tell",{"_index":2905,"t":{"505":{"position":[[57,5]]},"552":{"position":[[592,4]]},"627":{"position":[[4866,4]]},"930":{"position":[[12,4]]},"1652":{"position":[[12,4]]},"1845":{"position":[[416,4],[1467,4]]},"2377":{"position":[[12,4]]},"2709":{"position":[[1043,4]]},"2754":{"position":[[1184,4]]},"2844":{"position":[[971,4]]},"2947":{"position":[[3845,4]]}}}],["temp",{"_index":3361,"t":{"635":{"position":[[1958,4],[2145,4]]}}}],["temp_volume_nam",{"_index":7937,"t":{"1892":{"position":[[730,17],[925,17],[1108,17]]},"2008":{"position":[[730,17],[925,17],[1108,17]]}}}],["tempest",{"_index":8416,"t":{"2248":{"position":[[646,7]]}}}],["templat",{"_index":1934,"t":{"298":{"position":[[445,9]]},"391":{"position":[[223,9]]},"481":{"position":[[59,9]]},"491":{"position":[[509,9]]},"503":{"position":[[69,9]]},"530":{"position":[[1203,9]]},"583":{"position":[[204,9]]},"600":{"position":[[122,10]]},"604":{"position":[[1109,9],[1487,9],[1676,10],[3449,10],[3486,8],[3799,10],[3920,9],[4178,8],[4764,9],[5582,10]]},"609":{"position":[[4411,9],[4443,9],[6087,9]]},"627":{"position":[[979,8],[4434,10]]},"641":{"position":[[208,9]]},"650":{"position":[[1526,9],[2136,10],[2180,9]]},"654":{"position":[[351,8],[678,10]]},"660":{"position":[[1132,9]]},"662":{"position":[[362,9],[401,10]]},"667":{"position":[[169,9]]},"764":{"position":[[154,8]]},"825":{"position":[[69,9]]},"850":{"position":[[1591,8]]},"1089":{"position":[[785,8],[1461,9]]},"1167":{"position":[[816,8],[915,8],[2393,8]]},"1317":{"position":[[2967,8],[3108,8],[3404,8],[3540,8],[3679,8],[4344,8]]},"1484":{"position":[[1591,8]]},"1515":{"position":[[69,9]]},"2079":{"position":[[27,8],[149,10],[184,8],[237,9],[283,8],[330,9],[589,9]]},"2229":{"position":[[1072,9]]},"2283":{"position":[[696,8]]},"3078":{"position":[[897,8],[985,9]]},"3251":{"position":[[4050,10],[4586,9]]},"3253":{"position":[[121,8]]},"3314":{"position":[[3138,9]]},"3316":{"position":[[865,10],[913,8]]},"3472":{"position":[[294,9],[13118,8]]}}}],["template.yaml",{"_index":3123,"t":{"604":{"position":[[3472,13],[4084,13],[4522,13],[4680,13],[5209,13],[6900,13],[7033,13],[8557,13],[8690,13],[9670,13]]},"609":{"position":[[45,14]]},"627":{"position":[[655,13],[1009,13]]},"635":{"position":[[1671,14],[1769,13],[1841,14],[2218,13],[2489,13],[2736,13],[2995,13],[3240,13]]},"650":{"position":[[1354,13],[1879,13]]},"654":{"position":[[21,13]]},"667":{"position":[[290,13],[329,13],[406,13],[447,13]]}}}],["template={{.spec.volumenam",{"_index":2661,"t":{"474":{"position":[[640,29]]}}}],["templates/opensearch.yml.j2",{"_index":5849,"t":{"1167":{"position":[[363,31]]}}}],["tempor",{"_index":67,"t":{"6":{"position":[[121,6]]}}}],["temporari",{"_index":2579,"t":{"462":{"position":[[1138,9]]},"596":{"position":[[1105,9]]},"1678":{"position":[[1654,9],[2260,9]]},"1892":{"position":[[616,9],[799,9],[875,9],[1053,9]]},"2008":{"position":[[616,9],[799,9],[875,9],[1053,9]]}}}],["temporarili",{"_index":7909,"t":{"1857":{"position":[[1005,11],[1215,11]]},"1908":{"position":[[1392,11],[3068,11]]},"1919":{"position":[[1005,11],[1215,11]]},"2024":{"position":[[1392,11],[3068,11]]}}}],["tenanc",{"_index":8063,"t":{"1978":{"position":[[590,7],[762,8]]},"1980":{"position":[[230,7],[461,8]]},"3160":{"position":[[1087,7]]},"3301":{"position":[[6180,7],[7386,8]]}}}],["tenant",{"_index":1987,"t":{"315":{"position":[[152,6]]},"325":{"position":[[877,7],[4195,6]]},"489":{"position":[[142,6]]},"497":{"position":[[856,6]]},"762":{"position":[[193,10],[206,6],[218,6],[318,6]]},"901":{"position":[[365,6]]},"1108":{"position":[[529,8],[737,9]]},"1163":{"position":[[340,8]]},"1623":{"position":[[365,6]]},"1743":{"position":[[425,6]]},"1749":{"position":[[860,7],[877,6],[1484,6],[1679,6]]},"1754":{"position":[[46,6]]},"1758":{"position":[[461,6]]},"1955":{"position":[[253,8],[319,6],[455,7]]},"2031":{"position":[[299,6]]},"2033":{"position":[[226,6],[320,6],[397,6],[501,6],[731,7],[762,7],[863,6],[996,6],[1014,6],[1125,6],[1206,6],[1252,6],[1270,6],[1307,6],[1376,6],[1477,6],[1639,6],[1859,7],[1932,6],[1982,6]]},"2037":{"position":[[340,7]]},"2039":{"position":[[836,6]]},"2051":{"position":[[255,6],[412,7],[499,6]]},"2053":{"position":[[798,6],[952,6],[1097,6]]},"2348":{"position":[[365,6]]},"2944":{"position":[[804,6]]},"3003":{"position":[[193,6]]},"3076":{"position":[[58,6]]},"3160":{"position":[[1140,7],[1249,6]]},"3301":{"position":[[5180,8],[5274,6],[7534,7]]},"3413":{"position":[[197,6]]},"3457":{"position":[[628,6]]},"3463":{"position":[[800,6]]}}}],["tenant'",{"_index":8110,"t":{"2039":{"position":[[317,8]]},"2051":{"position":[[540,8]]},"2053":{"position":[[450,8]]}}}],["tenant=os",{"_index":7439,"t":{"1758":{"position":[[278,12]]}}}],["tenant_id",{"_index":8668,"t":{"2566":{"position":[[64,10]]}}}],["tenant_nam",{"_index":8087,"t":{"2033":{"position":[[716,14]]}}}],["tend",{"_index":4321,"t":{"899":{"position":[[832,5]]},"1621":{"position":[[832,5]]},"2346":{"position":[[832,5]]},"2892":{"position":[[444,4]]}}}],["tender",{"_index":325,"t":{"27":{"position":[[1206,6],[1474,6]]}}}],["tens",{"_index":883,"t":{"135":{"position":[[151,5]]},"1695":{"position":[[151,5]]}}}],["terabyt",{"_index":4278,"t":{"880":{"position":[[409,9]]}}}],["term",{"_index":1030,"t":{"166":{"position":[[688,5]]},"168":{"position":[[382,5]]},"170":{"position":[[27,5],[885,6],[1634,5]]},"172":{"position":[[222,5]]},"178":{"position":[[2124,5]]},"247":{"position":[[1719,6]]},"462":{"position":[[1079,4]]},"513":{"position":[[2274,4]]},"596":{"position":[[1301,4]]},"736":{"position":[[86,5],[218,6]]},"895":{"position":[[1841,4]]},"899":{"position":[[526,5]]},"917":{"position":[[887,4]]},"932":{"position":[[4212,5]]},"942":{"position":[[70,4]]},"1368":{"position":[[1714,5],[2390,5]]},"1617":{"position":[[1841,4]]},"1621":{"position":[[526,5]]},"1639":{"position":[[887,4]]},"1654":{"position":[[4212,5]]},"1664":{"position":[[70,4]]},"1872":{"position":[[0,4]]},"1953":{"position":[[305,5]]},"1988":{"position":[[0,4]]},"2146":{"position":[[101,5]]},"2342":{"position":[[1841,4]]},"2346":{"position":[[526,5]]},"2364":{"position":[[887,4]]},"2379":{"position":[[4212,5]]},"2389":{"position":[[70,4]]},"2627":{"position":[[533,5],[1645,5]]},"2960":{"position":[[527,6]]},"3023":{"position":[[22,5],[72,4]]},"3180":{"position":[[22,5],[79,4]]},"3193":{"position":[[14,5],[55,4]]},"3197":{"position":[[656,4]]},"3229":{"position":[[0,4]]},"3264":{"position":[[22,5],[72,4]]},"3325":{"position":[[655,4]]},"3395":{"position":[[465,4],[491,4]]},"3397":{"position":[[847,4]]},"3455":{"position":[[22,5],[72,4],[453,5]]}}}],["termin",{"_index":1007,"t":{"162":{"position":[[42,8]]},"164":{"position":[[55,9],[115,8]]},"507":{"position":[[422,10]]},"934":{"position":[[1164,11]]},"988":{"position":[[130,9]]},"1656":{"position":[[1164,11]]},"1847":{"position":[[1004,12]]},"2381":{"position":[[1164,11]]},"3003":{"position":[[406,9]]}}}],["terminolog",{"_index":9022,"t":{"2627":{"position":[[489,11],[1601,11]]},"2766":{"position":[[263,11]]},"3247":{"position":[[364,12],[410,12]]},"3489":{"position":[[58,12]]},"3502":{"position":[[58,12]]}}}],["terrabyt",{"_index":7894,"t":{"1851":{"position":[[263,10]]}}}],["terraform",{"_index":204,"t":{"14":{"position":[[44,9]]},"519":{"position":[[356,9]]},"617":{"position":[[1022,12]]},"633":{"position":[[3154,9]]},"1978":{"position":[[324,9]]},"2190":{"position":[[53,10]]},"2324":{"position":[[333,9]]},"2463":{"position":[[599,9]]},"2737":{"position":[[547,10]]},"2776":{"position":[[547,10]]},"3301":{"position":[[7077,10]]}}}],["terraform/cloud",{"_index":7534,"t":{"1779":{"position":[[816,16]]}}}],["terraform/clouds.yaml",{"_index":7531,"t":{"1779":{"position":[[494,21],[942,22],[2010,21],[2288,22],[2397,21],[2643,22]]}}}],["terraform/clouds.yaml.sampl",{"_index":7533,"t":{"1779":{"position":[[638,28]]}}}],["terraform/environ",{"_index":7518,"t":{"1773":{"position":[[826,22]]}}}],["terraform/environments/environ",{"_index":2947,"t":{"519":{"position":[[121,34],[190,34]]},"621":{"position":[[274,34]]},"623":{"position":[[298,34]]}}}],["terraform/environments/regiocloud.tfvar",{"_index":7638,"t":{"1794":{"position":[[324,40]]}}}],["terraform/files/containerd",{"_index":3338,"t":{"633":{"position":[[2937,28]]}}}],["terraform/files/kubernet",{"_index":3414,"t":{"641":{"position":[[1393,26]]},"646":{"position":[[170,26]]}}}],["terraform/files/templ",{"_index":2960,"t":{"530":{"position":[[1228,24]]}}}],["terraform/secure.yaml",{"_index":7532,"t":{"1779":{"position":[[536,21],[2210,21],[2311,21],[2586,21],[2666,21]]}}}],["terribl",{"_index":6656,"t":{"1364":{"position":[[402,8]]}}}],["territori",{"_index":8555,"t":{"2456":{"position":[[322,9]]}}}],["tertiari",{"_index":9429,"t":{"2852":{"position":[[363,9]]}}}],["test",{"_index":208,"t":{"16":{"position":[[39,4]]},"25":{"position":[[487,4]]},"27":{"position":[[572,4],[702,5],[1864,4]]},"91":{"position":[[81,8]]},"114":{"position":[[902,4]]},"265":{"position":[[150,6]]},"272":{"position":[[121,4]]},"276":{"position":[[43,5],[193,5],[303,4]]},"278":{"position":[[0,4],[53,5],[168,4]]},"280":{"position":[[0,4],[68,5],[120,5],[251,7],[331,4],[415,4],[536,6],[575,5],[601,5],[659,6],[679,6],[763,5],[805,5]]},"282":{"position":[[58,4],[228,4],[262,5],[377,4],[431,6],[478,5]]},"284":{"position":[[166,6],[238,5],[263,5],[694,4],[1259,4],[1339,4]]},"286":{"position":[[25,4],[211,5]]},"288":{"position":[[12,5],[296,5]]},"313":{"position":[[349,7],[368,5]]},"321":{"position":[[1171,5],[1240,5],[1321,5],[1408,5]]},"325":{"position":[[2316,4],[7461,4]]},"327":{"position":[[269,8]]},"329":{"position":[[155,8]]},"347":{"position":[[255,4]]},"349":{"position":[[364,8]]},"366":{"position":[[34,5],[448,5],[1086,5],[1332,5]]},"368":{"position":[[279,5]]},"370":{"position":[[59,5]]},"372":{"position":[[3,4],[376,4],[445,5],[506,4],[562,4],[709,4]]},"374":{"position":[[2,4],[329,4],[524,4],[682,4]]},"381":{"position":[[49,4],[192,6]]},"428":{"position":[[1783,4]]},"460":{"position":[[425,7]]},"479":{"position":[[14,5],[102,6]]},"487":{"position":[[5032,5]]},"489":{"position":[[95,6]]},"491":{"position":[[370,8]]},"493":{"position":[[104,4],[136,4],[260,4],[401,4],[542,4],[672,4],[751,4],[830,4],[861,4],[894,4],[932,4],[1056,4],[1197,4],[1338,4],[1468,4],[1553,4],[1632,4],[1669,4],[1881,7]]},"495":{"position":[[192,4],[788,5],[1079,4],[1663,5]]},"497":{"position":[[307,8]]},"499":{"position":[[89,4],[216,4],[479,4],[580,8],[689,5],[718,8],[793,6],[835,5],[860,8],[916,6],[959,4],[1008,4],[1140,4],[1303,4],[1350,6],[1379,6],[1398,6],[1426,6],[2250,5],[2331,4],[2405,4],[2445,4],[2516,4],[2545,4],[2614,4],[2653,4],[2722,4]]},"513":{"position":[[108,5],[2005,5]]},"525":{"position":[[39,4],[146,4]]},"530":{"position":[[803,4],[859,4]]},"557":{"position":[[38,5],[271,5]]},"559":{"position":[[31,5]]},"561":{"position":[[37,5],[132,4]]},"563":{"position":[[33,5]]},"565":{"position":[[29,5]]},"583":{"position":[[481,6]]},"598":{"position":[[1001,6]]},"609":{"position":[[596,6]]},"615":{"position":[[6,7],[221,5]]},"635":{"position":[[172,7]]},"648":{"position":[[78,6]]},"669":{"position":[[3,4],[707,6],[766,4],[810,5],[831,7],[857,6],[978,4],[1029,6],[1068,4]]},"716":{"position":[[44,4],[232,4]]},"853":{"position":[[46,4],[105,5],[297,4]]},"859":{"position":[[2217,4],[2429,4],[2830,4],[3294,4],[3413,4],[4290,4],[4409,4],[5286,4],[5405,4],[6499,5]]},"861":{"position":[[246,4]]},"895":{"position":[[1084,4],[1175,4],[1482,6],[1555,6],[1696,7]]},"899":{"position":[[82,5],[107,4],[274,5],[934,4]]},"901":{"position":[[16,4],[105,5],[283,4],[410,5]]},"909":{"position":[[474,6],[1039,4],[2633,4]]},"911":{"position":[[814,4]]},"913":{"position":[[972,4],[3181,4]]},"915":{"position":[[127,7],[814,5]]},"1043":{"position":[[161,7]]},"1150":{"position":[[13206,4],[13222,4]]},"1351":{"position":[[505,7]]},"1353":{"position":[[149,4]]},"1395":{"position":[[505,4],[640,7],[656,4]]},"1576":{"position":[[545,4],[585,4],[590,4],[603,4],[1070,4],[1115,4],[1120,4]]},"1578":{"position":[[135,4]]},"1587":{"position":[[28,6]]},"1597":{"position":[[46,4],[105,5],[297,4]]},"1603":{"position":[[2217,4],[2429,4],[2830,4],[3294,4],[3413,4],[4290,4],[4409,4],[5286,4],[5405,4],[6499,5]]},"1605":{"position":[[246,4]]},"1617":{"position":[[1084,4],[1175,4],[1482,6],[1555,6],[1696,7]]},"1621":{"position":[[82,5],[107,4],[274,5],[934,4]]},"1623":{"position":[[16,4],[105,5],[283,4],[410,5]]},"1631":{"position":[[474,6],[1039,4],[2633,4]]},"1633":{"position":[[814,4]]},"1635":{"position":[[972,4],[3181,4]]},"1637":{"position":[[127,7],[814,5]]},"1678":{"position":[[2012,5],[2018,5],[2024,5],[2162,5]]},"1690":{"position":[[84,7],[1980,7]]},"1770":{"position":[[343,4]]},"1773":{"position":[[591,4]]},"1779":{"position":[[6325,4],[6345,4],[6506,4]]},"1789":{"position":[[1024,4],[1029,4],[1042,4]]},"1810":{"position":[[284,4]]},"1827":{"position":[[386,6]]},"1837":{"position":[[96,7],[272,7],[301,7],[325,7],[349,7]]},"1839":{"position":[[228,7],[252,7]]},"1841":{"position":[[586,7]]},"1843":{"position":[[728,7],[751,7],[1023,7],[1094,7]]},"1845":{"position":[[2895,7]]},"1847":{"position":[[402,7]]},"1851":{"position":[[158,7]]},"1957":{"position":[[3199,4],[4389,4]]},"1963":{"position":[[207,8],[420,8],[442,8],[550,4]]},"2033":{"position":[[6,7],[1617,7],[1663,7]]},"2035":{"position":[[154,4]]},"2075":{"position":[[157,8]]},"2081":{"position":[[184,6],[256,6]]},"2083":{"position":[[83,7],[279,9],[643,6]]},"2085":{"position":[[361,6]]},"2089":{"position":[[3,4]]},"2096":{"position":[[726,4]]},"2098":{"position":[[2236,6]]},"2100":{"position":[[654,4]]},"2116":{"position":[[3,4]]},"2126":{"position":[[101,6],[309,7]]},"2160":{"position":[[166,7]]},"2188":{"position":[[204,5]]},"2196":{"position":[[597,4],[869,4]]},"2206":{"position":[[62,4]]},"2226":{"position":[[100,4]]},"2229":{"position":[[378,8],[665,4],[766,7]]},"2233":{"position":[[312,5]]},"2248":{"position":[[819,4]]},"2250":{"position":[[437,7]]},"2265":{"position":[[96,5],[172,6]]},"2276":{"position":[[119,4]]},"2281":{"position":[[1182,5]]},"2298":{"position":[[96,5],[172,6],[860,4],[930,4]]},"2302":{"position":[[76,6]]},"2310":{"position":[[169,6]]},"2312":{"position":[[299,4]]},"2315":{"position":[[1301,6],[1419,7]]},"2330":{"position":[[413,4],[531,4],[779,6],[898,4]]},"2342":{"position":[[1084,4],[1175,4],[1482,6],[1555,6],[1696,7]]},"2346":{"position":[[82,5],[107,4],[274,5],[934,4]]},"2348":{"position":[[16,4],[105,5],[283,4],[410,5]]},"2356":{"position":[[474,6],[1039,4],[2633,4]]},"2358":{"position":[[814,4]]},"2360":{"position":[[972,4],[3181,4]]},"2362":{"position":[[127,7],[814,5]]},"2400":{"position":[[223,6]]},"2411":{"position":[[144,8]]},"2413":{"position":[[136,6]]},"2426":{"position":[[85,5]]},"2456":{"position":[[279,6]]},"2461":{"position":[[451,6],[1136,5]]},"2463":{"position":[[456,8]]},"2470":{"position":[[76,4],[149,6]]},"2474":{"position":[[353,4]]},"2486":{"position":[[38,5],[212,8],[704,8]]},"2497":{"position":[[222,4],[493,5],[537,5]]},"2510":{"position":[[224,7],[373,4],[395,7]]},"2518":{"position":[[137,6],[191,5]]},"2520":{"position":[[33,4]]},"2544":{"position":[[622,7],[706,7]]},"2592":{"position":[[542,5],[905,7]]},"2623":{"position":[[674,7]]},"2627":{"position":[[323,5],[433,4]]},"2635":{"position":[[247,5]]},"2660":{"position":[[36,6],[90,5],[179,7]]},"2673":{"position":[[1253,7]]},"2688":{"position":[[279,4],[352,4],[390,5],[651,4],[1161,4],[2723,5],[2856,5]]},"2735":{"position":[[1411,4]]},"2774":{"position":[[1413,4]]},"2779":{"position":[[147,4]]},"2783":{"position":[[18,4]]},"2795":{"position":[[731,5]]},"2805":{"position":[[816,6]]},"2813":{"position":[[370,4],[1429,5]]},"2824":{"position":[[66,5],[140,5],[193,6]]},"2895":{"position":[[2517,6]]},"2909":{"position":[[122,4]]},"2911":{"position":[[311,7]]},"2935":{"position":[[470,4]]},"2947":{"position":[[3093,5]]},"2951":{"position":[[650,6]]},"2957":{"position":[[252,4]]},"2994":{"position":[[490,4]]},"3029":{"position":[[3,4]]},"3050":{"position":[[99,5],[438,4]]},"3053":{"position":[[180,4],[230,6],[271,5],[344,7],[425,6],[478,5],[529,5],[559,4],[659,5],[754,4],[813,5]]},"3055":{"position":[[53,4],[125,4],[189,5],[250,4],[571,5],[631,4],[730,4],[785,5],[897,4],[967,4],[1036,5],[1109,5]]},"3059":{"position":[[214,6],[544,6],[1037,5],[1179,5],[1210,4],[1262,4],[1356,5]]},"3061":{"position":[[67,5],[139,5],[262,4],[390,6],[786,5],[881,5],[1003,6],[1348,6]]},"3063":{"position":[[36,5],[80,5],[177,5],[251,5],[373,4],[441,4],[509,4],[578,5],[588,4],[799,4],[1002,5],[1031,5]]},"3065":{"position":[[221,8]]},"3069":{"position":[[124,5],[244,5],[337,4]]},"3071":{"position":[[21,4],[48,4],[71,4],[142,4],[185,4],[312,4],[347,4],[556,4],[601,6],[632,4],[734,5],[746,4],[910,5],[1012,4],[1128,4],[1189,6],[1240,5],[1259,4],[1445,4],[1487,5],[1637,4],[1824,4],[1955,6],[2398,5],[2570,6],[2605,4]]},"3092":{"position":[[16,5],[278,5]]},"3128":{"position":[[684,6],[767,5]]},"3132":{"position":[[552,4]]},"3169":{"position":[[410,4]]},"3171":{"position":[[197,6]]},"3175":{"position":[[16,4],[179,5],[294,4]]},"3204":{"position":[[99,7],[180,7],[315,8],[371,4],[514,7]]},"3206":{"position":[[83,8],[200,7],[412,8],[510,8],[548,4],[578,5],[695,4],[831,5],[921,8]]},"3208":{"position":[[25,7],[241,6],[299,7],[630,7],[642,7],[674,7],[754,7],[806,5],[891,5],[1001,7],[1266,7],[1524,8],[1611,7],[1677,5],[1784,7]]},"3210":{"position":[[125,7],[171,4],[464,7],[513,6],[563,7],[597,5],[715,5],[861,4]]},"3212":{"position":[[29,7]]},"3214":{"position":[[20,7],[338,8],[371,7],[511,6]]},"3216":{"position":[[13,4],[57,4],[129,8]]},"3218":{"position":[[65,8],[1316,7],[1529,8],[1747,8]]},"3222":{"position":[[415,7],[760,7]]},"3224":{"position":[[91,7],[130,7],[328,7],[852,7],[1151,4],[1527,7],[1795,7],[1923,8]]},"3242":{"position":[[12,5]]},"3290":{"position":[[12,6]]},"3310":{"position":[[280,6]]},"3333":{"position":[[12,6]]},"3479":{"position":[[11,4],[54,4],[334,7]]},"3516":{"position":[[12,6]]},"3518":{"position":[[1005,7],[1094,7],[1573,5],[1971,7]]}}}],["test'",{"_index":1837,"t":{"280":{"position":[[94,6]]}}}],["test1",{"_index":3386,"t":{"635":{"position":[[4145,5]]}}}],["test@test",{"_index":6553,"t":{"1353":{"position":[[375,9],[389,9]]}}}],["test_",{"_index":1856,"t":{"282":{"position":[[217,5]]}}}],["test_failur",{"_index":1905,"t":{"286":{"position":[[460,15]]}}}],["test_success",{"_index":1902,"t":{"286":{"position":[[386,15]]}}}],["testb",{"_index":181,"t":{"10":{"position":[[1913,8]]},"27":{"position":[[1395,7],[3070,7],[3142,7]]},"300":{"position":[[313,7]]},"302":{"position":[[1663,7]]},"347":{"position":[[212,8],[556,7],[593,7]]},"349":{"position":[[82,7]]},"716":{"position":[[211,8]]},"1039":{"position":[[7,7],[80,7],[157,7],[182,7],[312,7],[336,7],[465,7],[489,7],[618,7],[642,7]]},"1055":{"position":[[1505,7],[1625,7],[2062,7],[2099,7],[2206,7],[2239,7]]},"1089":{"position":[[2714,7]]},"1114":{"position":[[781,7],[998,7],[4383,7],[4600,7]]},"1120":{"position":[[1821,7],[1854,7],[1887,7]]},"1184":{"position":[[65,7],[698,7],[835,7],[949,7],[1005,7],[1082,7]]},"1230":{"position":[[76,7]]},"1279":{"position":[[173,7],[356,7],[401,7],[525,7]]},"1317":{"position":[[8071,7],[8170,7],[8270,7],[8369,7],[8920,7]]},"1319":{"position":[[22,7]]},"1321":{"position":[[118,7],[391,7],[555,7],[775,7],[1005,7],[1243,7],[1442,8],[2141,8]]},"1325":{"position":[[144,7],[182,7],[219,7],[256,7],[530,7],[718,7],[755,7],[792,7]]},"1327":{"position":[[56,7],[154,7],[371,7]]},"1329":{"position":[[49,7],[140,7],[365,7]]},"1333":{"position":[[58,7],[178,7],[338,8]]},"1335":{"position":[[190,7]]},"1337":{"position":[[66,7],[460,7]]},"1339":{"position":[[46,7],[259,7]]},"1347":{"position":[[355,7],[448,7],[541,7],[631,7],[725,7],[819,7],[1082,7],[1133,7],[1235,7],[1286,7],[1388,7],[1439,7],[1824,7],[1917,7],[2010,7]]},"1366":{"position":[[332,6],[355,6],[490,6],[513,6]]},"1368":{"position":[[727,7],[823,7],[919,7],[1080,7],[1105,7],[1206,7],[1231,7],[1332,7],[1357,7]]},"1371":{"position":[[61,7]]},"1373":{"position":[[77,7]]},"1375":{"position":[[83,7],[718,7],[1067,7],[1529,7]]},"1377":{"position":[[84,7],[719,7],[1088,7],[1723,7]]},"1430":{"position":[[131,7],[240,7],[349,7],[924,7],[1033,7],[1136,7],[1567,7],[1676,7],[1779,7],[1854,7],[1893,8]]},"1608":{"position":[[931,7]]},"1678":{"position":[[1729,7],[1764,7],[1835,7],[1869,7],[1905,7],[1991,7],[2319,7],[2341,7],[2363,7],[2385,7]]},"1734":{"position":[[97,8],[391,7],[423,7],[439,7],[493,7]]},"1770":{"position":[[15,8],[295,7],[410,7]]},"1773":{"position":[[109,7]]},"1775":{"position":[[10,7]]},"1779":{"position":[[60,8],[1953,7],[3559,7],[6069,7],[6526,7]]},"1783":{"position":[[10,7],[181,8],[223,7],[324,7],[504,8]]},"1785":{"position":[[483,7],[766,7]]},"1787":{"position":[[270,7],[510,7],[544,7],[717,7],[750,7],[779,7],[812,7],[841,7],[874,7],[903,7],[936,7],[965,7],[998,7],[1027,7],[1060,7],[1089,7],[1122,7],[1151,7],[1184,7],[1213,7],[1246,7],[1275,7],[1308,7]]},"1789":{"position":[[42,7],[102,7],[522,8],[611,8],[700,8]]},"1796":{"position":[[28,7]]},"1808":{"position":[[64,8],[565,7],[697,7]]},"1810":{"position":[[200,8]]},"1814":{"position":[[60,7]]},"1818":{"position":[[69,7],[84,7],[104,7],[126,7],[148,7],[164,7],[185,7]]},"2093":{"position":[[536,7]]},"2100":{"position":[[1187,7]]},"2188":{"position":[[127,8]]},"2190":{"position":[[24,8],[808,7]]},"2200":{"position":[[134,7]]},"2212":{"position":[[346,7]]},"2220":{"position":[[100,7]]},"2222":{"position":[[122,7]]},"2224":{"position":[[109,8]]},"2226":{"position":[[194,7]]},"2250":{"position":[[131,7],[242,8],[302,7],[325,7],[348,7]]},"2259":{"position":[[508,7]]},"2261":{"position":[[46,7]]},"2283":{"position":[[839,7],[894,8],[918,7],[1085,7]]},"2292":{"position":[[486,7]]},"2310":{"position":[[872,7]]},"2315":{"position":[[455,7]]},"2317":{"position":[[4,7]]},"2411":{"position":[[17,7]]},"2476":{"position":[[236,8]]},"3251":{"position":[[5701,8]]},"3253":{"position":[[23,7]]},"3325":{"position":[[2678,8]]},"3397":{"position":[[2238,9],[2277,7],[2375,7]]}}}],["testbed.osism.xyz",{"_index":7563,"t":{"1783":{"position":[[68,18],[429,17],[451,20]]},"2250":{"position":[[356,19]]},"2283":{"position":[[943,20]]}}}],["testbed/deploy",{"_index":3597,"t":{"716":{"position":[[272,18]]}}}],["testclust",{"_index":2759,"t":{"487":{"position":[[1613,11],[1634,11],[1839,11],[3170,11]]},"521":{"position":[[343,12],[396,11],[448,11]]},"530":{"position":[[997,11]]},"532":{"position":[[56,11]]},"557":{"position":[[68,11]]},"559":{"position":[[61,11]]},"561":{"position":[[67,11]]},"563":{"position":[[63,11]]},"565":{"position":[[59,11]]},"590":{"position":[[1554,11],[1587,11],[1659,11],[1723,11],[1767,11]]},"600":{"position":[[969,12]]},"606":{"position":[[131,11]]},"627":{"position":[[201,11],[275,12],[1628,11],[2142,13],[4638,11]]},"629":{"position":[[439,11],[873,15],[905,13]]},"648":{"position":[[36,12]]},"660":{"position":[[3173,11],[3185,11],[3515,11],[3527,11]]},"669":{"position":[[94,11]]}}}],["testcluster.yaml..tfvar",{"_index":2949,"t":{"519":{"position":[[225,18],[537,19]]},"530":{"position":[[1088,20]]},"619":{"position":[[355,19]]}}}],["yourcloud>.tfvarsfil",{"_index":2961,"t":{"534":{"position":[[103,23]]}}}],["yourfil",{"_index":158,"t":{"10":{"position":[[1526,13]]}}}],["yourpassword",{"_index":3869,"t":{"819":{"position":[[7830,12]]},"1509":{"position":[[7830,12]]}}}],["yourself",{"_index":1488,"t":{"214":{"position":[[83,9]]},"313":{"position":[[42,8],[269,8]]},"363":{"position":[[494,8]]},"730":{"position":[[1521,8]]},"1224":{"position":[[1003,9],[2366,8]]},"1256":{"position":[[676,9]]},"1491":{"position":[[1521,8]]},"2709":{"position":[[1865,8]]},"2754":{"position":[[2006,8]]},"2844":{"position":[[1659,8]]}}}],["yq",{"_index":2855,"t":{"495":{"position":[[708,3],[1589,3]]},"517":{"position":[[22,2]]},"590":{"position":[[565,2],[787,2],[1006,2]]},"604":{"position":[[192,3]]},"617":{"position":[[634,2],[646,2],[652,2]]},"635":{"position":[[2242,2],[2503,2],[2750,2],[3009,2]]},"641":{"position":[[2041,2]]},"2098":{"position":[[1580,3],[1720,2],[2031,2]]}}}],["yum",{"_index":10094,"t":{"3301":{"position":[[6839,3]]}}}],["yy.mm",{"_index":7501,"t":{"1766":{"position":[[936,7]]}}}],["yy.mm.x",{"_index":7500,"t":{"1766":{"position":[[911,10]]}}}],["yyi",{"_index":162,"t":{"10":{"position":[[1611,4]]}}}],["yyyi",{"_index":9545,"t":{"2895":{"position":[[3000,4],[3759,4],[3813,4]]},"2899":{"position":[[40,4],[54,4]]},"2901":{"position":[[1674,4]]}}}],["z",{"_index":4358,"t":{"903":{"position":[[3092,1]]},"947":{"position":[[1526,2]]},"1625":{"position":[[3092,1]]},"1669":{"position":[[1526,2]]},"2350":{"position":[[3092,1]]},"2394":{"position":[[1526,2]]},"2725":{"position":[[241,2],[283,2],[345,1]]},"2764":{"position":[[305,1],[566,1]]},"2850":{"position":[[254,1],[904,1],[974,1]]}}}],["z3",{"_index":387,"t":{"27":{"position":[[3208,2],[3216,2]]},"2844":{"position":[[1296,2],[1365,2],[1422,2],[1570,2],[1732,2]]},"2850":{"position":[[919,2],[993,2],[1013,2]]}}}],["z3h",{"_index":9423,"t":{"2844":{"position":[[1587,3]]},"2846":{"position":[[303,3]]},"2850":{"position":[[935,3],[1033,3]]}}}],["z3hh",{"_index":9428,"t":{"2850":{"position":[[952,4],[1054,4]]}}}],["zabbix",{"_index":8427,"t":{"2257":{"position":[[90,6]]}}}],["zap",{"_index":8148,"t":{"2083":{"position":[[15,3]]}}}],["zed",{"_index":8474,"t":{"2312":{"position":[[10,3]]}}}],["zed.yml",{"_index":7162,"t":{"1676":{"position":[[844,7],[879,7]]}}}],["zen",{"_index":9251,"t":{"2725":{"position":[[294,5],[401,3],[434,3],[484,3],[531,3],[586,3]]},"2764":{"position":[[311,5],[622,3],[655,3],[705,3],[752,3],[807,3],[1134,3],[1152,3]]},"2850":{"position":[[310,3],[343,3],[393,3],[440,3],[479,3]]}}}],["zero",{"_index":2241,"t":{"374":{"position":[[550,4]]},"530":{"position":[[1045,4]]},"1721":{"position":[[3911,4]]},"2625":{"position":[[1016,4]]},"2647":{"position":[[207,4]]},"2935":{"position":[[458,4]]},"2994":{"position":[[478,4]]},"3050":{"position":[[414,4]]},"3132":{"position":[[492,4]]}}}],["zeromq",{"_index":3685,"t":{"760":{"position":[[205,6],[624,6]]}}}],["zip",{"_index":3311,"t":{"629":{"position":[[826,4]]}}}],["zitadel",{"_index":8070,"t":{"1982":{"position":[[480,8],[973,7],[1001,7]]},"1984":{"position":[[90,8],[583,7],[611,7]]},"2176":{"position":[[1035,9]]},"3251":{"position":[[3090,8],[3099,7],[3219,8],[3454,7],[3731,7],[5015,7],[5377,7],[5411,7],[5667,7],[5720,7],[6020,7]]},"3253":{"position":[[54,8]]}}}],["zone",{"_index":3502,"t":{"654":{"position":[[179,5],[283,5]]},"738":{"position":[[70,5],[257,4],[372,5]]},"740":{"position":[[16,4],[164,4],[315,6],[458,4]]},"742":{"position":[[606,5],[684,5],[703,5],[895,5],[941,4],[1025,5],[1081,4]]},"746":{"position":[[115,5]]},"857":{"position":[[120,4],[288,4],[355,4]]},"859":{"position":[[396,4],[596,4],[762,4],[978,4],[1017,4],[1726,4],[1765,4],[2049,4],[2088,4]]},"901":{"position":[[495,4]]},"988":{"position":[[105,6]]},"1347":{"position":[[182,4],[1651,4]]},"1362":{"position":[[876,4],[1815,4]]},"1375":{"position":[[391,4],[1301,4]]},"1377":{"position":[[392,4],[1396,4]]},"1578":{"position":[[299,4]]},"1601":{"position":[[120,4],[288,4],[355,4]]},"1603":{"position":[[396,4],[596,4],[762,4],[978,4],[1017,4],[1726,4],[1765,4],[2049,4],[2088,4]]},"1623":{"position":[[495,4]]},"2233":{"position":[[501,5]]},"2348":{"position":[[495,4]]},"2966":{"position":[[1096,6],[1116,5]]},"3023":{"position":[[339,4]]},"3184":{"position":[[2393,5],[2497,5]]},"3186":{"position":[[970,5]]},"3195":{"position":[[413,6]]},"3197":{"position":[[645,5],[904,4],[1062,5],[1087,4],[1220,5]]},"3199":{"position":[[669,6],[714,5],[756,5],[823,6],[902,6],[1148,7]]}}}],["zone(",{"_index":2713,"t":{"485":{"position":[[718,7]]}}}],["zookeep",{"_index":8342,"t":{"2158":{"position":[[623,9]]},"2463":{"position":[[1064,9]]}}}],["zoom",{"_index":4591,"t":{"932":{"position":[[3984,4],[4036,7]]},"1654":{"position":[[3984,4],[4036,7]]},"2379":{"position":[[3984,4],[4036,7]]}}}],["zstd",{"_index":4405,"t":{"909":{"position":[[90,4]]},"1631":{"position":[[90,4]]},"2356":{"position":[[90,4]]}}}],["zun_api_public_port",{"_index":5719,"t":{"1159":{"position":[[2335,20]]}}}],["zun_external_fqdn",{"_index":5718,"t":{"1159":{"position":[[2288,17]]}}}],["zun_public_endpoint",{"_index":5717,"t":{"1159":{"position":[[2268,19]]}}}],["zuse",{"_index":386,"t":{"27":{"position":[[3203,4],[3211,4]]}}}],["zuul",{"_index":290,"t":{"25":{"position":[[822,4],[839,4],[870,4]]},"27":{"position":[[1762,4],[1778,4]]},"268":{"position":[[198,4]]},"270":{"position":[[5,4]]},"272":{"position":[[0,4]]},"311":{"position":[[27,4],[77,4],[156,4],[287,5]]},"313":{"position":[[25,4],[143,5],[435,5]]},"315":{"position":[[91,4],[119,5],[226,4],[289,4]]},"317":{"position":[[0,4],[64,4],[270,4],[298,4],[948,4]]},"319":{"position":[[3,4],[287,4],[421,5],[539,4]]},"321":{"position":[[6,4],[807,5],[840,5]]},"323":{"position":[[8,4],[116,4],[439,4],[602,4],[720,4]]},"325":{"position":[[19,4],[263,4],[724,5],[1261,4],[3392,4],[3793,5],[3816,4],[3939,4],[4057,4],[4153,4],[4167,4],[5487,4]]},"489":{"position":[[42,4],[243,4],[350,4],[446,4],[515,4],[561,4],[585,4],[640,4],[714,4],[879,4]]},"491":{"position":[[4,4],[138,4],[227,4]]},"493":{"position":[[30,4]]},"495":{"position":[[23,4],[368,4],[412,4],[1255,4],[1299,4]]},"497":{"position":[[414,4],[441,4],[642,4],[666,4],[762,4],[794,4],[808,4]]},"1678":{"position":[[2115,4]]},"1738":{"position":[[12,4],[138,4],[235,4],[347,4]]},"1740":{"position":[[81,4],[321,4]]},"1743":{"position":[[252,4],[461,4],[542,4],[892,5],[953,5],[1090,5],[1270,5],[1413,4],[1633,5],[1793,4],[1838,4],[1857,4],[1899,4]]},"1745":{"position":[[387,4],[484,4],[653,4],[881,4],[1019,4]]},"1747":{"position":[[13,4],[687,4]]},"1749":{"position":[[48,4],[373,4],[493,4],[585,4],[601,4],[1156,4],[1274,4],[1364,4]]},"1758":{"position":[[339,4],[366,5],[418,4],[529,5],[659,4],[778,4]]},"1818":{"position":[[41,4]]},"2138":{"position":[[164,4]]},"2158":{"position":[[53,4],[95,4],[212,4],[478,4],[760,4],[805,4]]},"2209":{"position":[[88,4],[338,4],[545,4]]},"2250":{"position":[[386,4],[478,4]]},"2413":{"position":[[52,4]]},"2463":{"position":[[284,4],[401,5],[519,4],[698,4],[726,4],[809,4]]},"2688":{"position":[[379,6]]}}}],["zuul'",{"_index":1986,"t":{"315":{"position":[[145,6]]},"323":{"position":[[791,6]]}}}],["zuul.*.priv",{"_index":7404,"t":{"1747":{"position":[[533,14]]}}}],["zuul.conf",{"_index":7436,"t":{"1758":{"position":[[158,10]]}}}],["zuul.d",{"_index":1991,"t":{"317":{"position":[[429,9],[520,10]]}}}],["zuul.example.com",{"_index":7412,"t":{"1749":{"position":[[60,16],[1189,16]]}}}],["zuul.pem",{"_index":7406,"t":{"1747":{"position":[[573,8]]}}}],["zuul.scs.commun",{"_index":8533,"t":{"2413":{"position":[[0,18]]}}}],["zuul.services.betacloud.xyz",{"_index":7355,"t":{"1738":{"position":[[268,28]]}}}],["zuul.yaml",{"_index":1817,"t":{"270":{"position":[[62,10]]},"317":{"position":[[366,11],[402,12],[841,10]]},"325":{"position":[[6471,9],[6489,9]]},"491":{"position":[[34,10],[420,10]]},"2158":{"position":[[362,9]]}}}],["zuul/udp",{"_index":8339,"t":{"2158":{"position":[[453,8]]}}}],["zuul/valu",{"_index":8337,"t":{"2158":{"position":[[350,11]]}}}],["zuul/zuul",{"_index":2049,"t":{"325":{"position":[[730,9]]},"1749":{"position":[[931,9]]},"2158":{"position":[[512,9],[561,9],[613,9]]}}}],["zuul/{pipeline}/{project}/{branch}/{chang",{"_index":2034,"t":{"323":{"position":[[655,45]]}}}],["zuul01",{"_index":7367,"t":{"1743":{"position":[[774,6]]}}}],["zuul01.servic",{"_index":7365,"t":{"1743":{"position":[[727,19]]}}}],["zuul_auth_secret",{"_index":7387,"t":{"1745":{"position":[[353,17]]}}}],["zuul_config",{"_index":2866,"t":{"499":{"position":[[366,14]]}}}],["zuul_connect",{"_index":7420,"t":{"1749":{"position":[[612,17]]}}}],["zuul_domain",{"_index":7362,"t":{"1743":{"position":[[689,12],[747,11]]}}}],["zuul_fqdn",{"_index":7364,"t":{"1743":{"position":[[716,10]]}}}],["zuul_host",{"_index":7366,"t":{"1743":{"position":[[763,10],[1550,9],[1659,9]]}}}],["zuul_logserver_fqdn",{"_index":7398,"t":{"1745":{"position":[[1253,20]]}}}],["zuul_oper",{"_index":7441,"t":{"1758":{"position":[[506,13]]}}}],["zuul_schedul",{"_index":7440,"t":{"1758":{"position":[[403,14]]}}}],["zuul_serv",{"_index":7375,"t":{"1743":{"position":[[1683,11]]}}}],["zuul_server.openstack.accessipv4",{"_index":7377,"t":{"1743":{"position":[[1748,32]]}}}],["zuul_ten",{"_index":7428,"t":{"1749":{"position":[[844,13]]}}}],["zuul_url",{"_index":2080,"t":{"325":{"position":[[4176,8]]}}}],["zuul_us",{"_index":7378,"t":{"1743":{"position":[[1888,10],[2421,9],[2497,9],[2550,9],[2606,9]]}}}],["zuul_webserver_fqdn",{"_index":7397,"t":{"1745":{"position":[[1229,19]]}}}],["zxvf",{"_index":2604,"t":{"469":{"position":[[542,4]]}}}],["zypper",{"_index":109,"t":{"10":{"position":[[603,6]]}}}]],"pipeline":["stemmer"]}}] \ No newline at end of file diff --git a/search/index.html b/search/index.html new file mode 100644 index 0000000000..00120538c0 --- /dev/null +++ b/search/index.html @@ -0,0 +1,23 @@ + + + + + +Search the documentation + + + + + + + + + + + + + + +

Search the documentation

+ + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000000..2af9af614b --- /dev/null +++ b/sitemap.xml @@ -0,0 +1 @@ +https://docs.scs.community/blogweekly0.5https://docs.scs.community/blog/archiveweekly0.5https://docs.scs.community/blog/first-blog-postweekly0.5https://docs.scs.community/blog/tagsweekly0.5https://docs.scs.community/blog/tags/communityweekly0.5https://docs.scs.community/blog/tags/howtoweekly0.5https://docs.scs.community/searchweekly0.5https://docs.scs.community/community/weekly0.5https://docs.scs.community/community/category/contribute-to-docsweekly0.5https://docs.scs.community/community/category/toolsweekly0.5https://docs.scs.community/community/central-services/plusserver-gx-scsweekly0.5https://docs.scs.community/community/cloud-resources/weekly0.5https://docs.scs.community/community/cloud-resources/getting-started-openstackweekly0.5https://docs.scs.community/community/cloud-resources/plusserver-gx-scsweekly0.5https://docs.scs.community/community/cloud-resources/wavestackweekly0.5https://docs.scs.community/community/collaboration/weekly0.5https://docs.scs.community/community/collaboration/sig-central-apiweekly0.5https://docs.scs.community/community/collaboration/sig-communityweekly0.5https://docs.scs.community/community/collaboration/sig-documentationweekly0.5https://docs.scs.community/community/collaboration/sig-monitoringweekly0.5https://docs.scs.community/community/collaboration/sig-standardizationweekly0.5https://docs.scs.community/community/collaboration/team-containerweekly0.5https://docs.scs.community/community/collaboration/team-iaasweekly0.5https://docs.scs.community/community/collaboration/team-iamweekly0.5https://docs.scs.community/community/collaboration/team-opsweekly0.5https://docs.scs.community/community/contribute/adding-docs-guideweekly0.5https://docs.scs.community/community/contribute/doc-files-structure-guideweekly0.5https://docs.scs.community/community/contribute/docs-workflow-explanationweekly0.5https://docs.scs.community/community/contribute/linting-guideweekly0.5https://docs.scs.community/community/contribute/local-docusaurus-development-guideweekly0.5https://docs.scs.community/community/contribute/styleguideweekly0.5https://docs.scs.community/community/contribute/styleguides/ansible_styleguideweekly0.5https://docs.scs.community/community/hackathons/checklistweekly0.5https://docs.scs.community/community/license-considerationsweekly0.5https://docs.scs.community/community/mission-statementweekly0.5https://docs.scs.community/community/tools/github/branchprotectionweekly0.5https://docs.scs.community/community/tools/github/dco-and-licensesweekly0.5https://docs.scs.community/community/tools/github/tips-and-tricksweekly0.5https://docs.scs.community/community/tools/jitsiweekly0.5https://docs.scs.community/community/tools/mailinglistsweekly0.5https://docs.scs.community/community/tools/matrixweekly0.5https://docs.scs.community/community/tools/nextcloudweekly0.5https://docs.scs.community/community/tools/zuulweekly0.5https://docs.scs.community/contributor-docs/weekly0.5https://docs.scs.community/contributor-docs/development/weekly0.5https://docs.scs.community/contributor-docs/development/tests/rfc2119-keyword-test-guideweekly0.5https://docs.scs.community/contributor-docs/development/tests/test-implementation-guideweekly0.5https://docs.scs.community/contributor-docs/operations/iam/identity-federation-in-scsweekly0.5https://docs.scs.community/contributor-docs/operations/iam/openstack-federation-via-oidcweekly0.5https://docs.scs.community/contributor-docs/operations/operations/zuul-ci-cd-quickstart-user-guideweekly0.5https://docs.scs.community/docs/weekly0.5https://docs.scs.community/docs/category/automated-pentestingweekly0.5https://docs.scs.community/docs/category/central-apiweekly0.5https://docs.scs.community/docs/category/cluster-stacksweekly0.5https://docs.scs.community/docs/category/componentsweekly0.5https://docs.scs.community/docs/category/components-1weekly0.5https://docs.scs.community/docs/category/components-2weekly0.5https://docs.scs.community/docs/category/container-registryweekly0.5https://docs.scs.community/docs/category/guides-1weekly0.5https://docs.scs.community/docs/category/guides-2weekly0.5https://docs.scs.community/docs/category/iaas-layerweekly0.5https://docs.scs.community/docs/category/k8s-cluster-api-providerweekly0.5https://docs.scs.community/docs/category/meteringweekly0.5https://docs.scs.community/docs/category/monitoringweekly0.5https://docs.scs.community/docs/category/operating-scsweekly0.5https://docs.scs.community/docs/category/releasesweekly0.5https://docs.scs.community/docs/category/status-page-apiweekly0.5https://docs.scs.community/docs/container/weekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/controllersweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/developweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/overviewweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/quickstartweekly0.5https://docs.scs.community/docs/container/components/cluster-stacks/components/cluster-stack-provider-openstack/docs/troubleshootingweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/backup_and_restoreweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/ha-deploymentweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/migrationweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/persistenceweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/quickstartweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/rate_limitweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/scs-deploymentweekly0.5https://docs.scs.community/docs/container/components/container-registry/docs/upgradeweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/application-credentialsweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/configurationweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/continuous-integrationweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/LoadBalancer-ExtTrafficLocalweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/Maintenance_and_Troubleshootingweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/make-referenceweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/overviewweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/quickstartweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/requirementsweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/roadmapweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/Upgrade-Guideweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/usage/weekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/usage/cluster-mgmt-capi-mgmt-nodeweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/usage/containter-registry-configurationweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/usage/create-new-clusterweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/usage/custom-caweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/usage/gateway-apiweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/usage/harborweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/usage/managing-many-clustersweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-cluster-classweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/usage/migrate-to-kaas-v2weekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/usage/multi-az-and-multi-cloud-environmentsweekly0.5https://docs.scs.community/docs/container/components/k8s-cluster-api-provider/doc/usage/testingweekly0.5https://docs.scs.community/docs/container/deployment-examples/a/weekly0.5https://docs.scs.community/docs/container/deployment-examples/a/hardwareweekly0.5https://docs.scs.community/docs/container/deployment-examples/a/softwareweekly0.5https://docs.scs.community/docs/container/guides/guide1weekly0.5https://docs.scs.community/docs/container/overview/architectureweekly0.5https://docs.scs.community/docs/container/overview/knowledgeweekly0.5https://docs.scs.community/docs/faq/weekly0.5https://docs.scs.community/docs/getting-started/containerizationweekly0.5https://docs.scs.community/docs/getting-started/overviewweekly0.5https://docs.scs.community/docs/getting-started/virtualizationweekly0.5https://docs.scs.community/docs/glossaryweekly0.5https://docs.scs.community/docs/iaas/components/weekly0.5https://docs.scs.community/docs/iaas/components/flavor-managerweekly0.5https://docs.scs.community/docs/iaas/components/image-manager/weekly0.5https://docs.scs.community/docs/iaas/components/image-manager/updateweekly0.5https://docs.scs.community/docs/iaas/components/openstack-health-monitorweekly0.5https://docs.scs.community/docs/iaas/components/project-managerweekly0.5https://docs.scs.community/docs/iaas/components/resource-managerweekly0.5https://docs.scs.community/docs/iaas/components/sandbox-managerweekly0.5https://docs.scs.community/docs/iaas/components/simple-stressweekly0.5https://docs.scs.community/docs/iaas/guides/weekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/weekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/cephweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/clusterapiweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/gardenerweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/ironicweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/k3sweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/keycloakweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/netdataweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/openstackweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/prometheusweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/proxmoxweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/sonicweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/components/teleportweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/designweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/hardware-bomweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/layersweekly0.5https://docs.scs.community/docs/iaas/guides/concept-guide/use-casesweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/cephweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/weekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/certificatesweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/packagesweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/resolvconfweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/servicesweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/sshconfigweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/sysctlweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/timezoneweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/commons/userweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/configuration-repositoryweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/inventoryweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/loadbalancerweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/managerweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/networkweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/weekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/aodhweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/barbicanweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/ceilometerweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/cinderweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/designateweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/glanceweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/heatweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/horizonweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/ironicweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/keystoneweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/magnumweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/manilaweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/neutronweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/novaweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/octaviaweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/placementweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/openstack/skylineweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/proxyweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/self-signed-certificatesweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/services/weekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/services/chronyweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/services/dockerweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/services/tunedweekly0.5https://docs.scs.community/docs/iaas/guides/configuration-guide/validations/weekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/bootstrapweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/examples/weekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/examples/cloud-in-a-boxweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/examples/testbedweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/managerweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/provisioningweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/seedweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/weekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/cephweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/infrastructureweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/kubernetesweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/logging-monitoringweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/networkweekly0.5https://docs.scs.community/docs/iaas/guides/deploy-guide/services/openstackweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/cephweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/infrastructureweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/manager/weekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/manager/applyweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/manager/consoleweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/manager/getweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/manager/logweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/manager/taskweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/networkweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/weekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/cinderweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/keystoneweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/neutronweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/novaweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/octaviaweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/weekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/flavor-managerweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/image-manager/weekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/image-manager/updateweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/openstack-health-monitorweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/project-managerweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/resource-managerweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/sandbox-managerweekly0.5https://docs.scs.community/docs/iaas/guides/operations-guide/openstack/tools/simple-stressweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/weekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/cloud-in-a-boxweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/contributor-guideweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/developer-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/developer-guide/releasesweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/developer-guide/scriptsweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/developer-guide/zuulweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/style-guideweekly0.5https://docs.scs.community/docs/iaas/guides/other-guides/testbedweekly0.5https://docs.scs.community/docs/iaas/guides/troubleshooting-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/troubleshooting-guide/cephweekly0.5https://docs.scs.community/docs/iaas/guides/troubleshooting-guide/managerweekly0.5https://docs.scs.community/docs/iaas/guides/troubleshooting-guide/openstackweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/cephweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/dockerweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/infrastructureweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/logging-monitoringweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/managerweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/networkweekly0.5https://docs.scs.community/docs/iaas/guides/upgrade-guide/openstackweekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/weekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/migration-vmware-esixweekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/openstack/weekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/openstack/security-groupsweekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/openstack/user-data-backupsweekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/security-groups/weekly0.5https://docs.scs.community/docs/iaas/guides/user-guide/user-data-backupsweekly0.5https://docs.scs.community/docs/iaas/overview/architectureweekly0.5https://docs.scs.community/docs/iaas/overview/computeweekly0.5https://docs.scs.community/docs/iaas/overview/knowledgeweekly0.5https://docs.scs.community/docs/iaas/overview/networkweekly0.5https://docs.scs.community/docs/iaas/overview/storageweekly0.5https://docs.scs.community/docs/iam/weekly0.5https://docs.scs.community/docs/iam/domain-manager-setup-and-usageweekly0.5https://docs.scs.community/docs/iam/intra-SCS-federation-setup-description-for-osism-doc-operationsweekly0.5https://docs.scs.community/docs/iam/SCS-example-setup-configuration-descriptionweekly0.5https://docs.scs.community/docs/operating-scs/audits/weekly0.5https://docs.scs.community/docs/operating-scs/components/automated-pentesting/overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/automated-pentesting/toolsweekly0.5https://docs.scs.community/docs/operating-scs/components/central-api/overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/central-api/poc-setupweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/alertmanagerweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/iaasweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/infrastructure_servicesweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/k3sweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/kaasweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/oauthweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/quickstartweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/scs-deploymentweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/tracingweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/tuningweekly0.5https://docs.scs.community/docs/operating-scs/components/monitoring/docs/zuulweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page/docs/component_overviewweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page/docs/componentsweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page/docs/levels_of_consensusweekly0.5https://docs.scs.community/docs/operating-scs/components/status-page/docs/overviewweekly0.5https://docs.scs.community/docs/operating-scs/guides/openstack-health-monitor/Debian12-Installweekly0.5https://docs.scs.community/docs/operating-scs/incident-management/weekly0.5https://docs.scs.community/docs/operating-scs/lifecycle-management/weekly0.5https://docs.scs.community/docs/operating-scs/logging/weekly0.5https://docs.scs.community/docs/operating-scs/metering/meter_configurationweekly0.5https://docs.scs.community/docs/operating-scs/monitoring/weekly0.5https://docs.scs.community/docs/operating-scs/overviewweekly0.5https://docs.scs.community/docs/releases/Release0weekly0.5https://docs.scs.community/docs/releases/Release1weekly0.5https://docs.scs.community/docs/releases/Release2weekly0.5https://docs.scs.community/docs/releases/Release3weekly0.5https://docs.scs.community/docs/releases/Release4weekly0.5https://docs.scs.community/docs/releases/Release5weekly0.5https://docs.scs.community/docs/releases/Release6weekly0.5https://docs.scs.community/docs/releases/ReleaseXweekly0.5https://docs.scs.community/docs/standards/weekly0.5https://docs.scs.community/standards/weekly0.5https://docs.scs.community/standards/certification/overviewweekly0.5https://docs.scs.community/standards/certification/scopes-versionsweekly0.5https://docs.scs.community/standards/global/weekly0.5https://docs.scs.community/standards/global/scs-0001weekly0.5https://docs.scs.community/standards/global/scs-0002weekly0.5https://docs.scs.community/standards/global/scs-0003weekly0.5https://docs.scs.community/standards/global/scs-0004weekly0.5https://docs.scs.community/standards/global/scs-0112weekly0.5https://docs.scs.community/standards/iaas/weekly0.5https://docs.scs.community/standards/iaas/scs-0100weekly0.5https://docs.scs.community/standards/iaas/scs-0101weekly0.5https://docs.scs.community/standards/iaas/scs-0102weekly0.5https://docs.scs.community/standards/iaas/scs-0103weekly0.5https://docs.scs.community/standards/iaas/scs-0104weekly0.5https://docs.scs.community/standards/iaas/scs-0110weekly0.5https://docs.scs.community/standards/iaas/scs-0111weekly0.5https://docs.scs.community/standards/iaas/scs-0113weekly0.5https://docs.scs.community/standards/iaas/scs-0114weekly0.5https://docs.scs.community/standards/iaas/scs-0115weekly0.5https://docs.scs.community/standards/iam/weekly0.5https://docs.scs.community/standards/iam/scs-0300weekly0.5https://docs.scs.community/standards/iam/scs-0301weekly0.5https://docs.scs.community/standards/iam/scs-0302weekly0.5https://docs.scs.community/standards/kaas/weekly0.5https://docs.scs.community/standards/kaas/scs-0200weekly0.5https://docs.scs.community/standards/kaas/scs-0210weekly0.5https://docs.scs.community/standards/kaas/scs-0211weekly0.5https://docs.scs.community/standards/kaas/scs-0212weekly0.5https://docs.scs.community/standards/kaas/scs-0213weekly0.5https://docs.scs.community/standards/kaas/scs-0214weekly0.5https://docs.scs.community/standards/kaas/scs-0215weekly0.5https://docs.scs.community/standards/kaas/scs-0216weekly0.5https://docs.scs.community/standards/kaas/scs-0217weekly0.5https://docs.scs.community/standards/kaas/scs-0218weekly0.5https://docs.scs.community/standards/ops/weekly0.5https://docs.scs.community/standards/ops/scs-0400weekly0.5https://docs.scs.community/standards/ops/scs-0401weekly0.5https://docs.scs.community/standards/ops/scs-0402weekly0.5https://docs.scs.community/standards/ops/scs-0403weekly0.5https://docs.scs.community/standards/ops/scs-0410weekly0.5https://docs.scs.community/standards/ops/scs-0411weekly0.5https://docs.scs.community/standards/ops/scs-0412weekly0.5https://docs.scs.community/standards/scs-0001-v1-sovereign-cloud-standardsweekly0.5https://docs.scs.community/standards/scs-0002-v1-standards-docs-orgweekly0.5https://docs.scs.community/standards/scs-0002-v2-standards-docs-orgweekly0.5https://docs.scs.community/standards/scs-0003-v1-sovereign-cloud-standards-yamlweekly0.5https://docs.scs.community/standards/scs-0004-v1-achieving-certificationweekly0.5https://docs.scs.community/standards/scs-0100-v1-flavor-namingweekly0.5https://docs.scs.community/standards/scs-0100-v2-flavor-namingweekly0.5https://docs.scs.community/standards/scs-0100-v3-flavor-namingweekly0.5https://docs.scs.community/standards/scs-0100-w1-flavor-naming-implementation-testingweekly0.5https://docs.scs.community/standards/scs-0101-v1-entropyweekly0.5https://docs.scs.community/standards/scs-0101-w1-entropy-implementation-testingweekly0.5https://docs.scs.community/standards/scs-0102-v1-image-metadataweekly0.5https://docs.scs.community/standards/scs-0103-v1-standard-flavorsweekly0.5https://docs.scs.community/standards/scs-0104-v1-standard-imagesweekly0.5https://docs.scs.community/standards/scs-0110-v1-ssd-flavorsweekly0.5https://docs.scs.community/standards/scs-0111-v1-volume-type-decisionsweekly0.5https://docs.scs.community/standards/scs-0112-v1-sonicweekly0.5https://docs.scs.community/standards/scs-0113-v1-security-groups-decision-recordweekly0.5https://docs.scs.community/standards/scs-0114-v1-volume-type-standardweekly0.5https://docs.scs.community/standards/scs-0115-v1-default-rules-for-security-groupsweekly0.5https://docs.scs.community/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-testsweekly0.5https://docs.scs.community/standards/scs-0210-v1-k8s-new-version-policyweekly0.5https://docs.scs.community/standards/scs-0210-v2-k8s-version-policyweekly0.5https://docs.scs.community/standards/scs-0211-v1-kaas-default-storage-classweekly0.5https://docs.scs.community/standards/scs-0212-v1-requirements-for-container-registriesweekly0.5https://docs.scs.community/standards/scs-0213-v1-k8s-nodes-anti-affinityweekly0.5https://docs.scs.community/standards/scs-0214-v1-k8s-node-distributionweekly0.5https://docs.scs.community/standards/scs-0215-v1-robustness-featuresweekly0.5https://docs.scs.community/standards/scs-0216-v1-requirements-for-testing-cluster-stacksweekly0.5https://docs.scs.community/standards/scs-0217-v1-baseline-cluster-securityweekly0.5https://docs.scs.community/standards/scs-0218-v1-container-registry-for-scs-standard-implementationweekly0.5https://docs.scs.community/standards/scs-0300-v1-requirements-for-sso-identity-federationweekly0.5https://docs.scs.community/standards/scs-0301-v1-naming-conventionsweekly0.5https://docs.scs.community/standards/scs-0302-v1-domain-manager-roleweekly0.5https://docs.scs.community/standards/scs-0400-v1-status-page-create-decisionweekly0.5https://docs.scs.community/standards/scs-0401-v1-status-page-reference-implementation-decisionweekly0.5https://docs.scs.community/standards/scs-0402-v1-status-page-openapi-spec-decisionweekly0.5https://docs.scs.community/standards/scs-0403-v1-csp-kaas-observability-stackweekly0.5https://docs.scs.community/standards/scs-0410-v1-gnocchi-as-metering-databaseweekly0.5https://docs.scs.community/standards/scs-0411-v1-publishing_method_for_metering_dataweekly0.5https://docs.scs.community/standards/scs-0412-v1-metering-jsonweekly0.5https://docs.scs.community/standards/scs-compatible-iaasweekly0.5https://docs.scs.community/standards/scs-compatible-kaasweekly0.5https://docs.scs.community/standards/scs-XXXX-vN-decision-record-templateweekly0.5https://docs.scs.community/standards/scs-XXXX-vN-standard-templateweekly0.5https://docs.scs.community/standards/standards/overviewweekly0.5https://docs.scs.community/weekly0.5 \ No newline at end of file diff --git a/standards/certification/overview/index.html b/standards/certification/overview/index.html new file mode 100644 index 0000000000..0684aebc51 --- /dev/null +++ b/standards/certification/overview/index.html @@ -0,0 +1,29 @@ + + + + + +overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Certification

+

SCS certificates come with various scopes. See Scopes and Versions for details.

+

Becoming certified

+

In order for a cloud service offering to obtain a certificate, it has to conform to all standards of the respective scope, which will be tested at regular intervals, and the results of these tests will be made available publicly. For more details on how to become certified, please consult the corresponding document.

+

Compliant cloud environments

+

This is a list of clouds that we test on a nightly basis against the certificate scope SCS-compatible IaaS.

+
NameDescriptionOperatorIaaS Compliance CheckHealthMon
gx-scsDev environment provided for SCS & GAIA-X contextplusserver GmbHGitHub Workflow StatusHM
pluscloud open
- prod1
- prod2
- prod3
- prod4
Public cloud for customers (4 regions)plusserver GmbH 
GitHub Workflow Status
GitHub Workflow Status
GitHub Workflow Status
GitHub Workflow Status
 
HM1
HM2
HM3
HM4
WavestackPublic cloud for customersnoris network AG/Wavecon GmbHGitHub Workflow StatusHM
REGIO.cloudPublic cloud for customersOSISM GmbHGitHub Workflow Statusbroken
CNDSPublic cloud for customersartcodix UGGitHub Workflow StatusHM
aovCommunity cloud for customersaov IT.Services GmbH(soon)HM
PoC WG-Cloud OSBACloud PoC for FITKOCloud&Heat Technologies GmbHGitHub Workflow StatusHM
+ + \ No newline at end of file diff --git a/standards/certification/scopes-versions/index.html b/standards/certification/scopes-versions/index.html new file mode 100644 index 0000000000..48d266c1cd --- /dev/null +++ b/standards/certification/scopes-versions/index.html @@ -0,0 +1,43 @@ + + + + + +Scopes and versions | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Scopes and versions

+

SCS provides a certification framework consisting of six different kinds of certificates of varying scope. +These scopes can be sorted into two dimensions:

+
    +
  1. certification level, of which there are three: +
      +
    • SCS-compatible
    • +
    • SCS-open
    • +
    • SCS-sovereign
    • +
    +
  2. +
  3. cloud layer, of which there are two: +
      +
    • infastructure as a service (IaaS)
    • +
    • Kubernetes as a service (KaaS)
    • +
    +
  4. +
+

So, for instance, a certificate can have the scope SCS-compatible IaaS or SCS-sovereign KaaS.

+

Each scope corresponds to a set of standards. As these standards progress, so do the scopes, and we keep track of this by versioning. Each version undergoes a lifecycle of Draft, Stable, and Deprecated, and we aim to keep at most one version stable at the same time, with the exception of a transition period of 4 to 6 weeks.

+

Alt text

+ + \ No newline at end of file diff --git a/standards/global/index.html b/standards/global/index.html new file mode 100644 index 0000000000..6b41541cb5 --- /dev/null +++ b/standards/global/index.html @@ -0,0 +1,26 @@ + + + + + +Global Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Global Standards

+

This track encompasses the foundational standards that guide the overall structure, documentation, and general topics related to the Sovereign Cloud Stack. It serves as the core framework, ensuring consistency, clarity, and comprehensibility across all aspects of the cloud stack, fostering an environment where information is easily accessible and understood.

+

*Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective).

+
StandardDescriptionDraftStable*EffectiveDeprecated*
scs-0001Sovereign Cloud Standards--v1-
scs-0002Standards, Docs and Organisationv2-v1-
scs-0003Sovereign Cloud Standards YAMLv1---
scs-0004Regulations for achieving SCS-compatible certificationv1---
scs-0112SONiC Support in SCSv1---
+ + \ No newline at end of file diff --git a/standards/global/scs-0001/index.html b/standards/global/scs-0001/index.html new file mode 100644 index 0000000000..04000f14c1 --- /dev/null +++ b/standards/global/scs-0001/index.html @@ -0,0 +1,27 @@ + + + + + +scs-0001: Sovereign Cloud Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

scs-0001: Sovereign Cloud Standards

+

SCS-0001 outlines the structure, requirements, and lifecycle of standards, procedural documents, and decision +records within the Sovereign Cloud Stack (SCS) community, ensuring clarity, organization, and governance in +the development and maintenance of interoperable and transparent cloud infrastructure standards.

+
VersionTypeStatestabilizeddeprecated
scs-0001-v1ProceduralStable2022-11-28-
+ + \ No newline at end of file diff --git a/standards/global/scs-0002/index.html b/standards/global/scs-0002/index.html new file mode 100644 index 0000000000..a55b007350 --- /dev/null +++ b/standards/global/scs-0002/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0002: Standards, Docs and Organisation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/global/scs-0003/index.html b/standards/global/scs-0003/index.html new file mode 100644 index 0000000000..5ea58da4e3 --- /dev/null +++ b/standards/global/scs-0003/index.html @@ -0,0 +1,27 @@ + + + + + +scs-0003: Sovereign Cloud Standards YAML | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

scs-0003: Sovereign Cloud Standards YAML

+

SCS-0003 outlines the standards and certification processes for interoperable and sovereign cloud offerings, +categorizing certifications into levels and layers, and detailing their progression, prerequisites, and versioning +in a machine-readable YAML format for clarity, traceability, and tool integration.

+
VersionTypeStatestabilizeddeprecated
scs-0003-v1ProceduralDraft--
+ + \ No newline at end of file diff --git a/standards/global/scs-0004/index.html b/standards/global/scs-0004/index.html new file mode 100644 index 0000000000..bb0c65e8cf --- /dev/null +++ b/standards/global/scs-0004/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0004: Regulations for achieving SCS-compatible certification | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/global/scs-0112/index.html b/standards/global/scs-0112/index.html new file mode 100644 index 0000000000..3f5ab097c3 --- /dev/null +++ b/standards/global/scs-0112/index.html @@ -0,0 +1,25 @@ + + + + + +scs-0112: SONiC Support in SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

scs-0112: SONiC Support in SCS

+

SCSS-0112 outlines architectural decisions in SCS in regards to SONiC support and integration.

+
VersionTypeStatestabilizeddeprecated
scs-0112-v1Decision RecordDraft--
+ + \ No newline at end of file diff --git a/standards/iaas/index.html b/standards/iaas/index.html new file mode 100644 index 0000000000..560e9ab71f --- /dev/null +++ b/standards/iaas/index.html @@ -0,0 +1,26 @@ + + + + + +IaaS Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

IaaS Standards

+

The IaaS Layer Standards track focuses on the protocols, guidelines, and specifications that govern the infrastructure as a service layer. This encompasses standards for virtual machines, storage, networking, and other foundational resources, ensuring seamless, efficient, and secure operation, interoperability, and management of the underlying cloud infrastructure.

+

*Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective).

+
StandardDescriptionDraftStable*EffectiveDeprecated*
scs-0100SCS Flavor Naming Standard--v3v1, v2
Supplement: Implementation and Testing Notesw1---
scs-0101SCS Entropy--v1-
Supplement: Implementation and Testing Notesw1---
scs-0102SCS Image Metadata Standard--v1-
scs-0103SCS Standard Flavors and Properties--v1-
scs-0104SCS Standard Images--v1-
scs-0110SSD Flavors--v1-
scs-0111Decisions for the Volume Type Standardv1---
scs-0113Security Groups Decision Recordv1---
scs-0114Volume Type Standardv1---
scs-0115Default Rules for Security Groupsv1---
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0100/index.html b/standards/iaas/scs-0100/index.html new file mode 100644 index 0000000000..2678faaffb --- /dev/null +++ b/standards/iaas/scs-0100/index.html @@ -0,0 +1,30 @@ + + + + + +scs-0100: SCS Flavor Naming Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

scs-0100: SCS Flavor Naming Standard

+

The SCS Flavor Naming Standard provides a systematic approach for naming instance flavors in OpenStack +environments, ensuring backward compatibility and clarity on key features like the number of vCPUs, RAM, +and Root Disk, as well as extra features like GPU support and CPU generation. The standard aims for +usability and portability across all SCS flavors.

+
VersionTypeStatestabilizeddeprecated
scs-0100-v1StandardDeprecated2022-09-082023-10-31
scs-0100-v2StandardDeprecated2023-02-212023-11-30
scs-0100-v3StandardStable2023-06-14-
+

Supplement: Implementation and Testing Notes

+
VersionStatestabilizeddeprecated
w1Proposal--
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0101/index.html b/standards/iaas/scs-0101/index.html new file mode 100644 index 0000000000..03b22fab7c --- /dev/null +++ b/standards/iaas/scs-0101/index.html @@ -0,0 +1,32 @@ + + + + + +scs-0101: SCS Entropy | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

scs-0101: SCS Entropy

+

The SCS-0101 Entropy Standard ensures adequate entropy is available in virtual instances, crucial for operations +such as secure key creation in cryptography. The standard recommends using kernel version 5.18 or higher and +activating the hw_rng_model: virtio attribute for images, while compute nodes should employ CPUs with entropy +accessing instructions unfiltered by the hypervisor. It allows the infusion of the hosts entropy sources into +virtual instances and ensures the availability and quality of entropy in virtual environments, promoting system +security and efficiency.

+
VersionTypeStatestabilizeddeprecated
scs-0101-v1StandardStable2024-02-08-
+

Supplement: Implementation and Testing Notes

+
VersionStatestabilizeddeprecated
w1Proposal--
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0102/index.html b/standards/iaas/scs-0102/index.html new file mode 100644 index 0000000000..973233d137 --- /dev/null +++ b/standards/iaas/scs-0102/index.html @@ -0,0 +1,29 @@ + + + + + +scs-0102: SCS Image Metadata Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

scs-0102: SCS Image Metadata Standard

+

The SCS-0102 Image Metadata Standard outlines how to categorize and manage metadata for cloud-based operating +system images to ensure usability and clarity. The standard encompasses naming conventions, technical requirements, +image handling protocols including updating and origin, and licensing/support details. These guidelines ensure +that users can understand, access, and utilize OS images effectively, with clear information on features, updates, +and licensing provided through well-defined metadata properties.

+
VersionTypeStatestabilizeddeprecated
scs-0102-v1StandardStable2022-10-31-
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0103/index.html b/standards/iaas/scs-0103/index.html new file mode 100644 index 0000000000..dc08db8825 --- /dev/null +++ b/standards/iaas/scs-0103/index.html @@ -0,0 +1,29 @@ + + + + + +scs-0103: SCS Standard Flavors and Properties | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

scs-0103: SCS Standard Flavors and Properties

+

The SCS-0103 standard outlines mandatory and recommended specifications for flavors and properties in OpenStack +environments to ensure uniformity across SCS clouds. Mandatory and recommended flavors are defined with specific +configurations of vCPUs, vCPU types, RAM, and root disk sizes, alongside extra specs like scs:name-vN, scs:cpu-type, +and scs:diskN-type to detail the flavor's specifications. This standard facilitates guaranteed availability and +consistency of flavors, simplifying the deployment process for DevOps teams.

+
VersionTypeStatestabilizeddeprecated
scs-0103-v1StandardStable2024-02-08-
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0104/index.html b/standards/iaas/scs-0104/index.html new file mode 100644 index 0000000000..d39a66be5c --- /dev/null +++ b/standards/iaas/scs-0104/index.html @@ -0,0 +1,29 @@ + + + + + +scs-0104: SCS Standard Images | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

scs-0104: SCS Standard Images

+

The SCS-0104 standard establishes guidelines for virtual machine images in Sovereign Cloud Stack (SCS) environments, +specifying mandatory, recommended, and optional images via a YAML file, ensuring interoperability and streamlined +deployments. It mandates that image upload via Glance must be allowed, ensuring flexibility for users. The standard's +machine-readable document facilitates automated processing for compliance and integration purposes, promoting +consistency and reliability in cloud environments.

+
VersionTypeStatestabilizeddeprecated
scs-0104-v1StandardStable2024-02-21-
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0110/index.html b/standards/iaas/scs-0110/index.html new file mode 100644 index 0000000000..996bd3caea --- /dev/null +++ b/standards/iaas/scs-0110/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0110: SSD Flavors | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0111/index.html b/standards/iaas/scs-0111/index.html new file mode 100644 index 0000000000..a8a71e5b55 --- /dev/null +++ b/standards/iaas/scs-0111/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0111: Decisions for the Volume Type Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0113/index.html b/standards/iaas/scs-0113/index.html new file mode 100644 index 0000000000..90af55cd29 --- /dev/null +++ b/standards/iaas/scs-0113/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0113: Security Groups Decision Record | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0114/index.html b/standards/iaas/scs-0114/index.html new file mode 100644 index 0000000000..6e01e23695 --- /dev/null +++ b/standards/iaas/scs-0114/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0114: Volume Type Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iaas/scs-0115/index.html b/standards/iaas/scs-0115/index.html new file mode 100644 index 0000000000..f7a73dba17 --- /dev/null +++ b/standards/iaas/scs-0115/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0115: Default Rules for Security Groups | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iam/index.html b/standards/iam/index.html new file mode 100644 index 0000000000..32bffa8f09 --- /dev/null +++ b/standards/iam/index.html @@ -0,0 +1,26 @@ + + + + + +IAM Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

IAM Standards

+

This track revolves around Identity and Access Management (IAM) standards, providing guidelines for ensuring secure and efficient user authentication, authorization, and administration. It addresses issues related to user identity, permissions, roles, and policies, aiming to safeguard and streamline access to cloud resources and services.

+

*Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective).

+
StandardDescriptionDraftStable*EffectiveDeprecated*
scs-0300Requirements for SSO identity federation--v1-
scs-0301Naming for domains/groups/roles/project when onboarding new customersv1---
scs-0302Domain Manager configuration for Keystonev1---
+ + \ No newline at end of file diff --git a/standards/iam/scs-0300/index.html b/standards/iam/scs-0300/index.html new file mode 100644 index 0000000000..8ecca739c2 --- /dev/null +++ b/standards/iam/scs-0300/index.html @@ -0,0 +1,30 @@ + + + + + +scs-0300: Requirements for SSO identity federation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

scs-0300: Requirements for SSO identity federation

+

The SCS-0300 standard outlines requirements for Single Sign-On (SSO) identity federation within the Sovereign +Cloud Stack (SCS). It addresses the need for customers to access SCS services using credentials stored and managed +externally, facilitating user onboarding and reducing the need for additional dedicated SCS accounts. The standard +focuses on delegating authentication to external identity providers and mapping users to roles within SCS for +authorization, while also considering the use of machine identities. Keycloak is the current choice as an Identity +Provider (IdP) for its support of OAuth 2.0 grants and its integration with OpenStack and kolla-ansible.

+
VersionTypeStatestabilizeddeprecated
scs-0300-v1Decision RecordStable2023-06-21-
+ + \ No newline at end of file diff --git a/standards/iam/scs-0301/index.html b/standards/iam/scs-0301/index.html new file mode 100644 index 0000000000..3b3557ae6a --- /dev/null +++ b/standards/iam/scs-0301/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0301: Naming for domains/groups/roles/project when onboarding new customers | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/iam/scs-0302/index.html b/standards/iam/scs-0302/index.html new file mode 100644 index 0000000000..95c6c58a42 --- /dev/null +++ b/standards/iam/scs-0302/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0302: Domain Manager configuration for Keystone | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/index.html b/standards/index.html new file mode 100644 index 0000000000..e9138535e0 --- /dev/null +++ b/standards/index.html @@ -0,0 +1,27 @@ + + + + + +Introduction | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Introduction

+

The Sovereign Cloud Stack (SCS) is a community-driven project that curates a set of standards—including both existing standards, such as the OpenInfra interoperability guides or the CNCF Kubernetes conformance, and newly created ones—to enable and ensure compatibility, openness, and sovereignty of cloud services across a wide range of providers, particularly small and medium businesses.

+

In addition, SCS provides a certification framework that enables these providers to verify and advertise their compliance with these standards. This framework consists of six kinds of certificates of varying scope, where each scope corresponds to a subset of the set of standards mentioned above.

+

Alt text

+

Learn more about these scopes as well as the currently certified clouds under Certification. More details on individual standards can be found under Standards.

+ + \ No newline at end of file diff --git a/standards/kaas/index.html b/standards/kaas/index.html new file mode 100644 index 0000000000..bfcd859f8f --- /dev/null +++ b/standards/kaas/index.html @@ -0,0 +1,26 @@ + + + + + +KaaS Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

KaaS Standards

+

Standards in this track are concerned with Kubernetes as a Service layer, outlining norms and best practices for deploying, managing, and operating Kubernetes clusters. These standards aim to ensure that the orchestration of containers is streamlined, secure, and compatible across various cloud environments and platforms.

+

*Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective).

+
StandardDescriptionDraftStable*EffectiveDeprecated*
scs-0200Using Sonobuoy for KaaS conformance testsv1---
scs-0210SCS K8S Version Policy--v2v1
scs-0211SCS KaaS default storage class--v1-
scs-0212Requirements for container registriesv1---
scs-0213Kubernetes Nodes Anti Affinityv1---
scs-0214Kubernetes Node Distribution and Availability--v1-
scs-0215Robustness features for Kubernetes clustersv1---
scs-0216Requirements for testing cluster-stacksv1---
scs-0217Kubernetes cluster baseline securityv1---
scs-0218Container registry for SCS standard implementationv1---
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0200/index.html b/standards/kaas/scs-0200/index.html new file mode 100644 index 0000000000..b01b50f2c3 --- /dev/null +++ b/standards/kaas/scs-0200/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0200: Using Sonobuoy for KaaS conformance tests | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0210/index.html b/standards/kaas/scs-0210/index.html new file mode 100644 index 0000000000..5ad9cf9c72 --- /dev/null +++ b/standards/kaas/scs-0210/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0210: SCS K8S Version Policy | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0211/index.html b/standards/kaas/scs-0211/index.html new file mode 100644 index 0000000000..f261d9c125 --- /dev/null +++ b/standards/kaas/scs-0211/index.html @@ -0,0 +1,28 @@ + + + + + +scs-0211: SCS KaaS default storage class | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

scs-0211: SCS KaaS default storage class

+

The SCS-0211 standard outlines the properties required for the default StorageClass in Kubernetes as a Service (KaaS). +The standard ensures that the default StorageClass, identified by the "storageclass.kubernetes.io/is-default-class" +annotation, supports the ReadWriteOnce access mode and protects volume data against loss due to single disk or +host hardware failures.

+
VersionTypeStatestabilizeddeprecated
scs-0211-v1StandardStable2023-02-13-
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0212/index.html b/standards/kaas/scs-0212/index.html new file mode 100644 index 0000000000..1486f43ba2 --- /dev/null +++ b/standards/kaas/scs-0212/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0212: Requirements for container registries | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0213/index.html b/standards/kaas/scs-0213/index.html new file mode 100644 index 0000000000..0961bef1f5 --- /dev/null +++ b/standards/kaas/scs-0213/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0213: Kubernetes Nodes Anti Affinity | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0214/index.html b/standards/kaas/scs-0214/index.html new file mode 100644 index 0000000000..71e08e1e59 --- /dev/null +++ b/standards/kaas/scs-0214/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0214: Kubernetes Node Distribution and Availability | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0215/index.html b/standards/kaas/scs-0215/index.html new file mode 100644 index 0000000000..e6b391e2bd --- /dev/null +++ b/standards/kaas/scs-0215/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0215: Robustness features for Kubernetes clusters | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0216/index.html b/standards/kaas/scs-0216/index.html new file mode 100644 index 0000000000..71c9ce42dc --- /dev/null +++ b/standards/kaas/scs-0216/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0216: Requirements for testing cluster-stacks | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0217/index.html b/standards/kaas/scs-0217/index.html new file mode 100644 index 0000000000..e2195d4f35 --- /dev/null +++ b/standards/kaas/scs-0217/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0217: Kubernetes cluster baseline security | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/kaas/scs-0218/index.html b/standards/kaas/scs-0218/index.html new file mode 100644 index 0000000000..ef83deb6f8 --- /dev/null +++ b/standards/kaas/scs-0218/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0218: Container registry for SCS standard implementation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/ops/index.html b/standards/ops/index.html new file mode 100644 index 0000000000..0ac57e6341 --- /dev/null +++ b/standards/ops/index.html @@ -0,0 +1,26 @@ + + + + + +Ops Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Ops Standards

+

Operational Tooling Standards cover the protocols and guidelines associated with tools and utilities used for monitoring, management, and maintenance of the cloud environment. This includes standards for status pages, alerts, logs, and other operational tools, aiming to optimize the reliability, performance, and security of cloud services and resources.

+

*Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective).

+
StandardDescriptionDraftStable*EffectiveDeprecated*
scs-0400Status Page create decisionv1---
scs-0401Status page reference implementation decisionv1---
scs-0402Status page OpenAPI decisionv1---
scs-0403Architecture for the Cloud Service provider Observability System for the KaaS Layerv1---
scs-0410Gnocchi as database for meteringv1---
scs-0411Push-based approach for providing usage datav1---
scs-0412Exposition of IaaS metering data as JSONv1---
+ + \ No newline at end of file diff --git a/standards/ops/scs-0400/index.html b/standards/ops/scs-0400/index.html new file mode 100644 index 0000000000..fe36f97ea0 --- /dev/null +++ b/standards/ops/scs-0400/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0400: Status Page create decision | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/ops/scs-0401/index.html b/standards/ops/scs-0401/index.html new file mode 100644 index 0000000000..dee96593fb --- /dev/null +++ b/standards/ops/scs-0401/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0401: Status page reference implementation decision | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/ops/scs-0402/index.html b/standards/ops/scs-0402/index.html new file mode 100644 index 0000000000..d91710474c --- /dev/null +++ b/standards/ops/scs-0402/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0402: Status page OpenAPI decision | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/ops/scs-0403/index.html b/standards/ops/scs-0403/index.html new file mode 100644 index 0000000000..06f5bba9c1 --- /dev/null +++ b/standards/ops/scs-0403/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0403: Architecture for the Cloud Service provider Observability System for the KaaS Layer | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/ops/scs-0410/index.html b/standards/ops/scs-0410/index.html new file mode 100644 index 0000000000..e454ed7dae --- /dev/null +++ b/standards/ops/scs-0410/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0410: Gnocchi as database for metering | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/ops/scs-0411/index.html b/standards/ops/scs-0411/index.html new file mode 100644 index 0000000000..92f413568b --- /dev/null +++ b/standards/ops/scs-0411/index.html @@ -0,0 +1,24 @@ + + + + + +scs-0411: Push-based approach for providing usage data | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/standards/ops/scs-0412/index.html b/standards/ops/scs-0412/index.html new file mode 100644 index 0000000000..0497664e8a --- /dev/null +++ b/standards/ops/scs-0412/index.html @@ -0,0 +1,29 @@ + + + + + +scs-0412: Exposition of IaaS metering data as JSON | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

scs-0412: Exposition of IaaS metering data as JSON

+

The SCS-0412 standard addresses the need for a standardized interface to expose IaaS metering data in JSON format +within the Sovereign Cloud Stack (SCS). This is to aid cloud operators in integrating SCS IaaS layer data with +their existing billing and customer relationship systems. The standard adopts the Ceilometer HTTP hook format +provided by the OpenStack Ceilometer project for telemetry and metering, avoiding the need for additional translation +layers and implementation components.

+
VersionTypeStatestabilizeddeprecated
scs-0412-v1StandardDraft--
+ + \ No newline at end of file diff --git a/standards/scs-0001-v1-sovereign-cloud-standards/index.html b/standards/scs-0001-v1-sovereign-cloud-standards/index.html new file mode 100644 index 0000000000..7b388ee7c3 --- /dev/null +++ b/standards/scs-0001-v1-sovereign-cloud-standards/index.html @@ -0,0 +1,293 @@ + + + + + +Sovereign Cloud Standards | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Sovereign Cloud Standards

Introduction

+

The Sovereign Cloud Stack (SCS) provides standards +for a range of cloud infrastructure types. +It strives for interoperable and sovereign cloud stacks +which can be deployed and used by a wide range of organizations and individuals. +Wherever feasible, +transparency and openness both in respect to the inner workings of the platforms standardised by SCS, +as well as the SCS organisation itself +are a paradigm we intend to live.

+

Requirements

+

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

+

In addition, "FORBIDDEN" is to be interpreted equivalent to "MUST NOT".

+

Sovereign Cloud Standard documents

+

One of the main products of the SCS organisation are Sovereign Cloud Standard documents.

+

Types of documents

+

Procedural

+

A procedural SCS document describes a process, a policy or a guideline +to which the SCS community adheres.

+

Standard

+

A standard SCS document describes a technical standard for SCS compliant clouds. +Note that it may not be necessary for all clouds to implement all standards.

+

Decision Record

+

Sometimes during the development of the SCS standard, +a complex technical decision needs to be taken, +which does not directly result in a new standard.

+

The SCS document format formally integrates +the documentation of such decisions +as documents of type Decision Record.

+

Supplement

+

A supplement extends a Standard with additional information, such as implementation and testing notes, +that is merely informative, but not authoritative, and that may be subject to change more frequently +than the standard itself.

+

Document format

+

The SCS documents are provided in GitHub flavored markdown. +Each document is assigned a unique number. +To disambiguate with other organisations using similar schemes +(such as XEPs, PEPs or IETF RFCs), +the numbers are prefixed with SCS-.

+

To allow a concept to evolve while allowing breaking changes, +each SCS document is associated with a major version number. +This major version number is a positive number +and the numbering starts at one for each document.

+

In order to make organisation of the SCS documents easier, +each document also has a slugified title. +The slugified title MUST NOT be changed after the acceptance of the document into the repository, +as it is part of its canonical URL. +It MUST consist only of lower-case ASCII letters, numbers and hyphens. +It MUST NOT start with a hyphen and SHOULD start with a lower-case letter. +It SHOULD NOT contain more than one subsequent hyphen.

+

The file name of an SCS document is formed using the following pattern: +scs-XXXX-vN-T.md, where +XXXX is replaced with the zero-padded document number, +N is replaced with the major version of the document, and +T is replaced with the slugified title. +For a document with the number 190, with a major version number 2 and a slugified title flavor-naming, +the resulting file name would be scs-0190-v2-flavor-naming.md.

+

Supplements deviate from this pattern in that they employ a w instead of a v in front of the version +number, and each supplement uses the same document number as the main document it is extending.

+

The second digit in XXXX describes the track where the document belongs:

+
TrackNumber
Global0
IaaS1
KaaS2
IAM3
Ops4
+

In addition to the number, each document has the following metadata, +embedded in the markdown header.

+
Field nameRequirementDescription
typeREQUIREDone of Procedural, Standard, Decision Record, or Supplement
statusREQUIREDone of Proposal, Draft, Stable, Deprecated, or Rejected
trackREQUIREDone of Global, IaaS, KaaS, IAM, Ops
supplementsREQUIRED precisely when type is Supplementlist of documents that are extended by this document (e.g., multiple major versions)
deprecated_atREQUIRED if status is DeprecatedISO formatted date indicating the date after which the deprecation is in effect
stabilized_atREQUIRED if status was ever StableISO formatted date indicating the date after which the document was considered stable
rejected_atREQUIRED if status is RejectedISO formatted date indicating the date on which the document was rejected
replaced_byRECOMMENDED if status is Deprecated or Rejected, FORBIDDEN otherwiseList of documents which replace this document.
replacesOPTIONALList of documents which this document replaces.
+

Sections

+

Standard

+

Each Standard document MUST have the following sections:

+
    +
  • An Introduction providing context on the document and linking to other relevant materials.
  • +
  • A Motivation section which details why this document or the thing it describes is necessary.
  • +
  • A section containing the actual standardization decision.
  • +
  • A Conformance Tests section that contains hints on how to validate +conformance with this spec, ideally links to conformance test cases.
  • +
+

We also RECOMMEND the following sections:

+
    +
  • A Terminology section which briefly describes terms used in the document, including possible abbreviations.
  • +
+

In addition, the following OPTIONAL sections should be considered:

+
    +
  • A Design Considerations section for Standard type documents, +which details other choices +which have been considered for the specific feature +but were ultimately rejected.
  • +
  • An Open Questions section which links to issues +detailing any open discussion points with respect to a document. +This section is RECOMMENDED during the discussion phase (pre 1.0.0) +as a "table of contents" of things to work on in that context.
  • +
  • A Related Documents section which references related Standards +or Decisions, both upstream and/or other SCS documents.
  • +
+

Decision Record

+

Each Decision Record document MUST have the following sections:

+
    +
  • An Abstract providing a brief introduction on the topic of the document.
  • +
  • A Context section describing the issue relevant for motivating this Decision Record.
  • +
  • A section containing the actual decision that is introduced. The section should also include +reasoning for this decision.
  • +
+

We also RECOMMEND the following sections:

+
    +
  • A Terminology section which shortly describes terms used in the document, including possible abbreviations.
  • +
  • A Related Documents section which references related Standards +or Decisions, both upstream and/or other SCS documents.
  • +
+

In addition, the following OPTIONAL sections should be considered:

+
    +
  • A Consequences section describing outcomes from implementing the changes described.
  • +
+

Process

+

The lifecycle of an SCS document goes through the following phases: +Proposal, Draft, Stable, Deprecated, and Rejected.

+ +

All decisions for phase transitions follow loose consensus, +where the group which has to form the consensus depends on the track of the document:

+
    +
  • IaaS: The team working on infrastructure-as-a-service topics
  • +
  • KaaS: The team working on Kubernetes-as-a-service topics
  • +
  • Ops: The team working on operations topics
  • +
  • IAM: The team working on identity and access management topics
  • +
  • Global: The entire SCS community
  • +
+

Supplements may be kept in Draft state, because they are not authoritative.

+

Proposal phase

+

Proposal of a new document

+

To propose a new SCS document, +a community participant creates a pull request on GitHub +against the standards repository in the SovereignCloudStack organisation.

+

The pull request MUST add exactly one SCS document, +in the Standards folder. +In the proposal phase, +the document number MUST be replaced with xxxx in the file name, +except for a Supplement, which uses the document number of the document it refers to. +The major version MUST be 1.

+

For a document with a slugified title flavor-naming, +the file name would for instance be scs-xxxx-v1-flavor-naming.md; +for a Supplement of scs-0100-v3-flavor-naming.md, +the file name might be scs-0100-w1-flavor-naming-implementation-testing.md (note the w1!).

+

The metadata MUST indicate the intended track and type of the document, +and the status MUST be set to Proposal; +for a Supplement, the supplements field MUST be set +to a list of documents (usually containing one element).

+

Upon acceptance by the group of people identified by the track, +a number is assigned +(the next unused number) +and the proposer is asked +to rename the file to replace the xxxx with that number.

+

Note: +Documents on the Design Record track MAY be proposed or accepted directly into Stable state, +if no further discussion is required.

+

Hereafter, +the pull request can be merged +and henceforth the document is an official SCS document in Draft state.

+

Proposal of a major update to a stable document

+

To propose major update to a Stable SCS document, +a community participant creates a pull request on GitHub +against the standards repository in the SovereignCloudStack organisation.

+

The pull request MUST add exactly one SCS document, +in the Standards folder. +The document number MUST be the same as the document it is updating, +and the major version number MUST be incremented by 1. +The slugified title MAY be changed.

+

It MUST refer to the old document in its replaces metadata. +The pull request SHOULD NOT modify the previous document; +deprecation of the previous document +as well as adding the replaced_by metadata is a separate step, +and can only be executed once the new document is Stable.

+

For a document updating a hypothetical SCS-0390-v3 document, +the file name may be scs-0390-v4-flavor-naming-this-time-its-serious.md.

+

Other than the file naming difference, +the proposal process is the same as for new documents. +In particular, the new document starts out in Draft state +and does not automatically become part of the normative corpus of an SCS release.

+

Development phase (Draft)

+

In this phase, +the document is developed inside the SCS community.

+

It should not be considered to be normative for any SCS release, +even if an SCS release happens after the acceptance of the document.

+

Experimental and exploratory implementations are encouraged, +however, implementors must be prepared for breaking changes.

+

Changes to the documents are gated through pull requests.

+

Stabilized phase (Stable)

+

Once the document is deemed ready for production use, +its status is changed to Stable.

+

If the document in question is a Standard +(and if applicable), +the following conditions MUST all be satisfied before stabilizing:

+
    +
  • the corresponding conformance tests have been implemented +according to the general guidelines,
  • +
  • they have been shown to work with the reference implementation,
  • +
  • they are documented in the standard or one of its Supplement +documents.
  • +
+

After stabilization, +changes to the document which may render existing implementations non-conformant +MUST NOT be made.

+

If a breaking change to an existing SCS document is deemed necessary, +a new document with a new number shall be created +and the old document SHOULD be deprecated.

+

Deprecation phase (Deprecated)

+

Should a document become obsolete, +it can be deprecated.

+

Obsoletions SHOULD be announced ahead of their execution by setting the +deprecated_at field to a future date and moving the status to Deprecated. +This signals current and future implementors +that the subject matter of the document +is not considered necessary or state of the art anymore.

+

If one or more replacement documents for the document exists, +it MUST be listed in the replaced_by metadata field.

+

Rejection

+

If a document is removed from the normative corpus of SCS standards, +its status is changed to Rejected.

+

If one or more replacement documents for the document exists, +it MUST be listed in the replaced_by metadata field.

+

Open Questions

+

Stabilization criteria

+

When should a document be stabilized? +Should we require at least one public implementation? +Should we require a minimum experimental time? +What about non-Standard track documents?

+

Breaking change criteria

+

When is a change breaking and cannot be applied to a Stable document? +What about previously undefined behaviour (uncovered edge case)? +What about ambiguous wording? +Do we need a separate "Errata" section?

+

Design Considerations

+

Versioning

+

An alternative to the proposed scheme for stabilization +is the use of SemVer-like versioning.

+

In that case, one would have an individual version number with each document, +where a major version greater than zero indicates a stable document. +The Stable state would be merged with Draft state into an Active state +and shared between the stabilized and the development phase.

+

The advantages of such an approach are:

+
    +
  • It is easy to recognize whether an SCS document has changed between two SCS +releases, just by looking at the released version number.
  • +
  • It is possible to make breaking changes after stabilization by increasing the +major version number.
  • +
+

The disadvantages of that approach are:

+
    +
  • +

    It is possible to make breaking changes after stabilization. +Potentially, an hypothetical SCS-1234 document might refer to something completely different +in a hypothetical R15 release than what it meant in R5, +if there have been sufficient, gradual breaking changes to the document.

    +

    That means that for proper linking, +it would be required to always include the major version number +when referring to an SCS document.

    +

    This implies having to keep all former versions around in a canonical, linkable form. +This induces non-trivial organizational and editorial overhead +and raises questions around which changes are acceptable to "archived" versions, +if any.

    +
  • +
  • +

    It would require a clone of the SemVer spec, +as that spec is highly specific toward software +and does not fully +(at least not in the standard-as-written) +cover specifics of a standards organisation's use-cases.

    +
  • +
+

Acknowledgements

+

This document is heavily inspired by XEP-0001, as published by the XMPP Standards Foundation.

+ + \ No newline at end of file diff --git a/standards/scs-0002-v1-standards-docs-org/index.html b/standards/scs-0002-v1-standards-docs-org/index.html new file mode 100644 index 0000000000..86c921a0d1 --- /dev/null +++ b/standards/scs-0002-v1-standards-docs-org/index.html @@ -0,0 +1,51 @@ + + + + + +Standards, Docs and Organisation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Standards, Docs and Organisation

Introduction

+

The old Docs repository had a subdirectory Design-Docs/ which holds Docs on +Design Considerations, older Architecture Decision Records (ADRs) and even +Standards. It also has a Design-Docs/tools/ subdirectory with conformance +checks and our overall conformance check driver (from PR#182).

+

Motivation

+

This directory structure is confusing in a number of ways:

+
    +
  • The conformance checks are hard to find.
  • +
  • The mixture of document types requires searching at two or three places.
  • +
+

We want to improve this (while avoiding unnecessary churn).

+

Suggested cleanup (step 1)

+
    +
  • Move Design-Docs/tools/ contents to Tests/ +
      +
    • Also create subdirectories then for layers and test, while the overall +conformance check tool, certification specs and README remain in Tests/.
    • +
    +
  • +
  • Rename Design-Docs/ to Drafts/. +
      +
    • Use individual PRs to rewrite existing ADRs and Standards there to conform +to our standards and move them over to Standards/.
    • +
    +
  • +
+

Some documents with findings will remain in the Drafts directory. +We may want to categorize these and have a folder e.g. for research results.

+ + \ No newline at end of file diff --git a/standards/scs-0002-v2-standards-docs-org/index.html b/standards/scs-0002-v2-standards-docs-org/index.html new file mode 100644 index 0000000000..0da19b17bd --- /dev/null +++ b/standards/scs-0002-v2-standards-docs-org/index.html @@ -0,0 +1,103 @@ + + + + + +SCS Documentation structure | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Documentation structure

Introduction

+

The Sovereign Cloud Stack (SCS) is a complex ecosystem, comprised of numerous Components and packages designed to accommodate a wide array of use cases. Given the unique functionalities of these components, the creation of a unified and comprehensible documentation presents a significant challenge. This procedural standard aims to define the structure and maintenance process for our documentation, thereby offering seamless and efficient access to users.

+

Motivation

+

SCS promotes a collaborative environment by actively contributing to upstream projects. The involvement of individuals and companies within our community significantly enhances the SCS Bill of Materials (BOM), further amplifying its complexity. Consequently, our documentation must:

+
    +
  • Offer an overview and visual representation of the architectural model
  • +
  • Foster coherence by maintaining a consistent theme throughout the documentation
  • +
  • Facilitate a transparent and inclusive community environment
  • +
  • Describe various deployment examples and use cases
  • +
  • Reflect the SCS structure in the documentation's navigation
  • +
+

Distributed Documentation

+

In line with the OpenStack documentation approach, most SCS Components and components maintain independent documentation. To keep this documentation up-to-date and eliminate manual duplication, we utilize a custom workflow that synchronizes individual documents during the static documentation page's build process.

+

Methodology and Taxonomy

+

Addressing the complexity of SCS requires an effective documentation structure. Accordingly, we have adopted the Diataxis taxonomy, categorizing the documentation into four distinct sections: Tutorials, Guides, References, and Explanations.

+

Structure Template

+

The technical documentation and navigation should parallel the logical structure of the SCS Architecture. By doing so, users can better comprehend the information hierarchy and effectively visualize the SCS. The proposed structure is as follows:

+
├── Introduction
├── Getting Started
│ ├── Overview
│ ├── Virtualization
│ └── Containerization
├── IaaS Layer
│ ├── Overview
│ │ ├── Architecture
│ │ ├── Compute
│ │ ├── Storage
│ │ ├── Knowledge
│ │ └── Network
│ ├── Deployment Examples
│ │ ├── Example 1
│ │ │ ├── Hardware
│ │ │ └── Software
│ │ ├── ...
│ │ │ ├── Hardware
│ │ │ └── Software
│ │ └── Example x
│ │ ├── Hardware
│ │ └── Software
│ ├── Guides
│ │ ├── Guide 1
│ │ ├ ...
│ │ └── Guide x
│ └── Components
│ ├── Component 1
│ ├ ...
│ └── Component x
├── Container Layer
│ ├── Overview
│ │ ├── Architecture
│ │ └── ...
│ ├── Prerequisites
│ │ ├── Hardware
│ │ ├── Software
│ │ └── Knowledge
│ ├── Guides
│ │ ├── Guide 1
│ │ ├── ...
│ │ └── Guide x
│ └── Components
│ ├── k8s-cluster-api-provider
│ ├ ...
│ └── Component x
├── Operating SCS
│ ├── Overview
│ ├── Guides
│ │ ├── Guide 1
│ │ ├── ...
│ │ └── Guide x
│ ├── Monitoring
│ ├── Incident Management
│ ├── Audits
│ ├── Lifecycle Management: Patches/Updates & Upgrades
│ └── Logging
├── Identity and Access Management (IAM)
├── Releases
├── Standards
├── FAQ
└── Glossary
+

Single Component/Component

+

The technical documentation and navigation should parallel the logical structure of the SCS Architecture. By doing so, users can better comprehend the information hierarchy and effectively visualize the SCS. The proposed structure is as follows:

+
│        ├── Component
│ │ ├── overview.md
│ │ └── requirements.md
│ │ ├── quickstart.md
│ │ ├── configuration.md
│ │ ├── contribute.md
+

Each document serves a specific purpose:

+

Overview

+

This document introduces the Component/component by addressing the basic "Why," "How," and "What" questions, and articulating the problems it solves in the broader SCS context answering the following questions:

+
    +
  • What is it and for what do I need this? What benefits does it have for users?
  • +
  • What organization/company does this belong to? (Link to company/organization)
  • +
  • Where am I – as module – within the bigger context of SCS?
  • +
+

Requirements

+

This section enumerates the necessary prerequisites to utilize the component, including software, hardware, and any required technical knowledge. What are the minimal requirements needed for a quickstart?

+

Quickstart

+

A concise guide providing users with a quick set up of the component, covering installation instructions, basic configuration, and initial steps. Caution: it is only for testing and not for production.

+
    +
  • What is the aim of this quickstart guide?
  • +
  • Rule: one line per command for easy copy&paste and one line for description where possible
  • +
  • Rule: only one working path for installation.
  • +
+

Configuration

+

This section elaborates on the configurable aspects of the component, such as options, parameters, or settings that users can modify to suit their needs.

+

Contribute

+

This document provides instructions on how interested parties can contribute to the component's development. It includes information on issue submission, proposed changes, and participation in discussions.

+

Technical Implementation

+

SCS employs Docusaurus, a contemporary static website generator, to implement the Docs Standard. Docusaurus serves as an ideal platform for creating, managing, and deploying extensive documentation.

+

Documentation Framework

+

Docusaurus' robust toolkit assists in crafting and maintaining quality documentation. It offers comprehensive features such as Markdown support, customizable themes, and versioning, making it an excellent choice for our needs. This platform allows us to create user-friendly and visually engaging documentation.

+

Special Implementation Details

+

SCS's unique architecture necessitates a unique approach to documentation. To ensure seamless integration of reference documentation for Components and components developed for SCS, we have created a custom workflow. This workflow automatically syncs upstream repositories, pulling the most recent documentation at regular intervals.

+

We have accomplished this by utilizing a Node.js post-install script found here.

+

This script prompts the system to pull the latest docs every eight hours and build the static page. The workflow's specifications can be viewed here.

+

The SCS documentation is built by the tooling from the docs-page repository, pulling content from docs repository as well as many other components as defined in the docs.package.json here.

+

Writing Style and Format – Style Guide

+

Formatting and Linting

+

All documentation text files must be provided as markdown files with an .md extension. This prerequisite ensures uniformity across our documents, making them more accessible and comprehensible.

+

Diagrams, Charts, and Images

+

When necessary, diagrams, charts, and images can be used to simplify complex information. They should be properly captioned and referenced in the text.

+

Linting

+

To maintain a clean and consistent content repository, we enforce linting on:

+
    +
  • All staged files before committing
  • +
  • All Pull Requests
  • +
+
Pre Commit
+

We run markdownlint against staged Git files using the Husky Git hook. This process is facilitated by lint-staged and husky.

+

The markdown files are linted according to the rules specified by markdownlint-cli2 and formatted with prettier.

+

The linting rules are specified in the configuration file .markdownlint-cli2.jsonc. Additionally, markdownlint-rule-search-replace

+
GitHub Workflows
+

There are two actions running on every Pull Request on the main branch:

+
    +
  1. link-validator.yml validates every link in the markdown files.
  2. +
  3. pr-markdownlint.yml checks all markdown files according to the rules defined within .markdownlint-cli2.jsonc.
  4. +
+

The Style Guide can be found here.

+

Open Questions

+

--

+

Reference

+

--

+ + \ No newline at end of file diff --git a/standards/scs-0003-v1-sovereign-cloud-standards-yaml/index.html b/standards/scs-0003-v1-sovereign-cloud-standards-yaml/index.html new file mode 100644 index 0000000000..384453eef9 --- /dev/null +++ b/standards/scs-0003-v1-sovereign-cloud-standards-yaml/index.html @@ -0,0 +1,152 @@ + + + + + +Sovereign Cloud Standards YAML | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Sovereign Cloud Standards YAML

Introduction

+

The Sovereign Cloud Stack (SCS) provides standards for a range of cloud infrastructure types. +It strives for interoperable and sovereign cloud offerings which can be deployed and used by a wide range of organizations and individuals.

+

SCS plans to offer six kinds of certificates with varying scope. These scopes can be sorted into two dimensions:

+
    +
  1. certification level, of which there are three: +
      +
    • SCS-compatible
    • +
    • SCS-open
    • +
    • SCS-sovereign
    • +
    +
  2. +
  3. cloud layer, of which there are two: +
      +
    • infastructure as a service (IaaS)
    • +
    • Kubernetes as a service (KaaS)
    • +
    +
  4. +
+

So, for instance, a certificate can have the scope SCS-compatible IaaS or SCS-sovereign KaaS. +Note that we don't currently have separate certification layers for Operations and IAM. +We expect that tests for these aspects will exist, but be incorporated into the IaaS +and KaaS layers.

+

Each certificate scope amounts to a set of standards that have to be fulfilled by the cloud service in question in order for a certificate to be issued. +In addition, a certificate with a certain scope may only be issued if some other certificate is already held. +Case in point: the certification levels are meant to be seen as a progression, where the upper levels build on the lower ones, and +the certificate for "SCS-open IaaS" will only be issued if a certificate for "SCS-compatible IaaS" is already held. +We say that the latter certificate is a prerequisite of the former.

+

Naturally, as the state of the art progresses, so do our certificates. We keep track of the changes by means of versioning. +That is to say that each certificate scope can come in several versions, each one of them having its distinct timespan when it is in effect. +For instance, we might have

+
    +
  • SCS-compatible IaaS v1, effective 2021-01-01 through 2023-10-31
  • +
  • SCS-compatible IaaS v2, effective 2023-03-23 through 2023-11-30
  • +
+

and so on (but usually, we aim to keep at most two versions in effect, with an overlap of 4 to 6 weeks).

+

This decision record describes two main points:

+
    +
  1. How we denote our certificate scopes by means of a YAML file.
  2. +
  3. Our process for constructing and progressing the certificate scopes.
  4. +
+

Motivation

+

This decision record establishes a mechanism (by means of the YAML file) with the following three main objectives:

+
    +
  • to provide an overview of the mandatory standards for the different SCS certificate scopes
  • +
  • to make the lifecycle of certificate scopes traceable
  • +
  • to provide a machine-readable document for further processing (e.g. for a compliance tool suite or continuous integration).
  • +
+

Overview of mandatory SCS standards

+

Digging through a repository of draft, stable, replaced and rejected standards becomes increasingly challenging with a growing number +documents and decision records. A central document that lists all mandatory standards to acquire a certificate with a certain scope can +resolve this issue. It provides clarity for providers as well as users and helps to understand the value +proposition of SCS.

+

Lifecycle of certificate scopes

+

Standards and therefore certifications will evolve over time. To provide transparency and traceability for the lifecycle of SCS certificate +scopes, the whole history of our certifications should be recorded. Pre-notification of changes to our certificate scopes allows +users to adapt their environments or deployment automation to the new standards in advance.

+

Machine-readability for further processing

+

By providing a machine-readable document, we can generate web-friendly overviews of our certificate scopes as well as create a tool suite +that checks environments against all described standards.

+

SCS Certification YAML

+

Each certificate scope is recorded in a dedicated YAML file, e.g. scs-open-kaas.yaml.

+

The certification YAML MUST contain the following keys:

+
KeyTypeDescriptionExample
nameStringFull name of this certificate scopeSCS Open KaaS
urlStringValid URL to the latest raw version of this documenthttps://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/scs-open-kaas.yaml
versionsArray of mapsList of version descriptors (described below)(see below)
+

The certification YAML MAY contain the following keys:

+
KeyTypeDescription
prerequisiteMapDescriptor for the prerequisite certificate scope (see below)
variablesArray of StringLists variables that may occur in check tool descriptors
+

The main check tool will expect an assignment for these variables (which is specific to the subject under test), and every occurrence of the variable in the check tool descriptor will be substituted accordingly.

+

Prerequisite descriptor

+

A certificate within a certain level (above SCS-compatible) can only be granted if a valid corresponding certificate of the level below is presented, +where corresponding means: of the same layer. The latter certificate is said to be a prerequisite for the former.

+

We implement this logic by allowing for the designation of a certificate scope as a prerequisite; +then a certificate of that prerequisite scope has to be presented before the certificate of the scope in question can be granted.

+
KeyTypeDescriptionExample
nameStringFull name of the certificate scopeSCS Compatible IaaS
urlStringValid URL to the latest raw version of the certificate scopescs-compatible-iaas.yaml
+

Version descriptor

+
KeyTypeDescriptionExample
versionStringMandatory: Version of the particular list of standardsv3
standardsArray of mapsMandatory: List of standard descriptors for this particular layer
stabilized_atDateISO formatted date indicating the date after this version is considered stable.2022-11-09
deprecated_atDateISO formatted date indicating the date on which this version is expired.2023-04-09
+

Once a version has a stabilized_at field, this field may not be changed. The same holds true for the deprecated_at field.

+

Note that at any point in time, all versions that are older (stabilized_at is at or before this point) +can be certified against, unless the version is already deprecated (the point is after deprecated_at). +This means that more than one version may be allowable at a certain point in time. Tooling should default +to use the newest allowable version (the one with the most recent stabilized_at date) then.

+

Note: We intend to keep only one version in effect, except for a grace period of 4 to 6 weeks, when two versions +are effective at the same time.

+

Standard descriptor

+

Every list of standards consists of several standards that – altogether – define the particular layer standard in the given version.

+
KeyTypeDescriptionExample
nameStringFull name of the particular standardFlavor naming
urlStringValid URL to the latest raw version of the particular standardFlavor naming
conditionStringState of the particular standard, currently either mandatory or optional, default is mandatorymandatory
checksArrayList of all checks that must pass; each entry being a check descriptor
+

Check descriptor

+

The following fields are valid for every check descriptor:

+
KeyTypeDescriptionExample
idStringIdentifier for this check (immutable and unique within this version of the certificate scope)image-md-check
conditionStringOptionally overrides the per-standard condition (mandatory or optional)optional
lifetimeStringOne of: day (default), week, month, quarter; the test result is valid until the end of the next periodweek
sectionStringOptional what section to associate this check with (sections can be checked in isolation); default: equal to lifetimeflavor-name syntax
+

Additional fields are valid depending on whether the check is automated or manual.

+

Automated check

+
KeyTypeDescriptionExample
executableStringValid local filename (relative to the path of scs-compliance-check.py) of a script that verifies compliance with the particular standardimage-md-check.py
envMapOptional key-value map of environment variables (values may use variables)OS_CLOUD: {os_cloud}
argsStringOptional command-line arguments to be passed to the check_tool (may use variables)-v -k {kubeconfig}
+

As mentioned, variables may be used within env and args; they are enclosed in single braces, like so: {var}. +If a brace is desired, it needs to be doubled: {{ will be turned into {. When the main check tool is run, +each occurrence of a variable will be substituted for according to the variable assignment for the subject under test.

+

Note: the executable could in principle also be given via a URL; however, this is not yet supported due to security considerations.

+

Manual check

+

TBD

+

Basic Example

+
name: SCS Open IaaS
url: https://raw.githubusercontent.com/SovereignCloudStack/Docs/main/Certification/scs-open-iaas.yaml
prerequisite:
name: SCS Compatible IaaS
url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Tests/scs-compatible-iaas.yaml
variables:
- os_cloud
versions:
- version: v5 # This version is in a draft state and work in progress
# No stabilized_at: date set yet
standards:
- name: Flavor naming
url: https://raw.githubusercontent.com/SovereignCloudStack/standards/main/Standards/scs-0100-v2-flavor-naming.md
condition: mandatory # is default and can be left out
checks:
- executable: flavor-name-check.py
env:
OS_CLOUD: "{os_cloud}"
id: flavor-name-check
lifetime: day
- name: Image metadata
url: https://raw.githubusercontent.com/SovereignCloudStack/Docs/main/Standards/SCS-0004-v1-image-metadata.md
condition: mandatory
checks:
- executable: image-md-check.py
args: -c {os_cloud} -v
id: image-md-check
lifetime: day
- executable: image-md-check2.py
condition: optional
id: image-md-check-2
lifetime: day
- version: v4 # This is the upcoming version with a given target date. No further changes should be done to this set of standards
stabilized_at: 2022-04-01
standards:
- name: ....

- version: v3 # This is the stable set of standards that is currently active
stabilized_at: 2021-10-01
deprecated_at: 2022-11-08
standards:
- name: ....

- version: v2 # This set of standards is obsolete and has been replaced by v3
stabilized_at: 2021-07-01
deprecated_at: 2021-11-01
standards:
- name: ....
+

Process

+

The lifecycle any version of any certificate scope goes through the following phases: +Draft, Stable, and Deprecated.

+ +

Note that one pull request can affect multiple versions, but each pull request has to affect +at most one layer.

+

Each pull request is to be voted upon in the corresponding team meeting. The vote has to be +on the pull request only, i.e., it may not affect any other pull request or issue, and it +must be announced 14 days in advance via the corresponding mailing list.

+

Design Considerations

+

File format

+

In order to have a document that can be processed by a wide range of tools, we need to opt for a simple but yet well supported format. +YAML offers readability for humans as well as good support by many frameworks. Since YAML is heavily used in the cloud and container +domain, the choice is obvious.

+

Dependency graph for certifications

+

This standard only allows exactly one depending certification, otherwise we would need to use a list of mappings. Since this is +in accordance to the current plan of the SIG Standardization & Certification, we can safely ignore multiple dependency of +certification for now.

+

Tooling

+

The SCS repository Docs has a tool scs-compliance-check.py in the Tests directory +which parses the SCS Certification YAML and then runs the tests referenced there, returning the results +of the tests.

+

Open Questions

+

Acknowledgements

+

This document is heavily inspired by the publiccode.yml standard, as published by the Foundation for Public Code.

+ + \ No newline at end of file diff --git a/standards/scs-0004-v1-achieving-certification/index.html b/standards/scs-0004-v1-achieving-certification/index.html new file mode 100644 index 0000000000..6d98754395 --- /dev/null +++ b/standards/scs-0004-v1-achieving-certification/index.html @@ -0,0 +1,67 @@ + + + + + +Regulations for achieving SCS-compatible certification | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Regulations for achieving SCS-compatible certification

Introduction

+

The Sovereign Cloud Stack (SCS) issues certificates with various scopes, among them SCS-compatible IaaS (infrastructure as a service) and SCS-compatible KaaS (Kubernetes as a service).

+

This document details how a cloud service provider (henceforth also called operator) can attain such a certificate for one of their clouds.

+

Motivation

+

As operator, I want to obtain a certificate with the scope SCS-compatible IaaS or SCS-compatible KaaS.

+

Regulations

+
    +
  1. +

    Each certificate issued pertains to a given cloud, a given scope, and a given version of that scope with a fixed expiry date. The certificate is only valid for that cloud and for the time frame that ends on that expiry date.

    +
  2. +
  3. +

    The operator MUST include the official SCS compliance test suite (which does not require admin privileges) in their continuous test infrastructure (e.g., Zuul). The tests MUST be run at given intervals, depending on their resource-usage classification:

    +
      +
    • light: at least nightly,
    • +
    • medium: at least weekly,
    • +
    • heavy: at least monthly.
    • +
    +

    For public clouds, it is recommended to offer the SCS project access to the infrastructure so the test suite runs can be triggered continuously by the SCS team.

    +

    Alternatively, and for non-public clouds, the results (log files) MUST be submitted to SCS (by a mechanism of SCS' choice) at least weekly, and they need to be reproduced again on request by SCS.

    +
  4. +
  5. +

    If the desired certificate requires manual checks, then the operator MUST offer the SCS project suitable access. Manual checks MUST be repeated once every quarter.

    +
  6. +
  7. +

    Details on the standards achieved, as well as the current state and the history of all test and check results of the past 18 months will be displayed on a public webpage (henceforth, certificate status page) owned by SCS.

    +

    The page will be kept online for the duration of the certificate's validity, plus at least 3 months; afterwards, it can be taken offline, either upon request or in the course of maintenance cleanup. However, the page's content won't be deleted until 12 months after the certificate's expiration, for the page will be reanimated and reused if, within this timeframe, a new certificate is issued for the same scope and the same cloud.

    +
  8. +
  9. +

    The SCS certification assessment body (initially the SCS project in the OSB Alliance e.V., possibly further entities empowered to do so by the SCS trademark owner, currently the OSB Alliance e.V.) WILL review the certification application and either grant the certification, reject it or ask for further measures or information.

    +
  10. +
  11. +

    Once the certificate is granted by the SCS certification assessment body, the operator SHOULD use the corresponding logo and publicly state the certified "SCS compatibility" on the respective layer for the time of the validity of the certification. In case of a public cloud, this public display is even REQUIRED. In any case, the logo MUST be accompanied by a hyperlink (a QR code for printed assets) to the respective certificate status page.

    +
  12. +
  13. +

    If the certificate is to be revoked for any reason, it will be included in a publicly available Certificate Revokation List (CRL). This fact will also be reflected in the certificate status page.

    +
  14. +
  15. +

    If any of the automated tests or manual checks fail after the certificate has been issued, the certificate is not immediately revoked. Rather, the automated tests MUST pass 99.x % of the runs, and the operator SHALL be notified at the second failed attempt in a row at the latest. In case a manual check fails, it has to be repeated at a date to be negotiated with SCS. It MAY NOT fail more than two times in a row.

    +
  16. +
+

Design Considerations

+

Open Questions

+ +

As of now, this document pertains to the certificate scopes on the certification level SCS-compatible only. It will be extended to cover the remaining levels as they become relevant, either directly or by way of referring to additional documents.

+

For details on our mechanisms for developing, denoting, and versioning the certificate scopes, we refer to the document scs-0003-v1.

+ + \ No newline at end of file diff --git a/standards/scs-0100-v1-flavor-naming/index.html b/standards/scs-0100-v1-flavor-naming/index.html new file mode 100644 index 0000000000..dcf0958c32 --- /dev/null +++ b/standards/scs-0100-v1-flavor-naming/index.html @@ -0,0 +1,304 @@ + + + + + +SCS Flavor Naming Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Flavor Naming Standard

Introduction

+

This is the standard v1.0 for SCS Release 0. +Note that we intend to only extend it (so it's always backwards compatible), +but try to avoid changing in incompatible ways.

+

Motivation

+

In OpenStack environments there is a need to define different flavors for instances. +The flavors are pre-defined by the operator, the customer can not change these. +OpenStack providers thus typically offer a large selection of flavors.

+

While flavors can be discovered (openstack flavor list), it is helpful for users (DevOps teams), +to have

+
    +
  • A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere.
  • +
  • Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered.
  • +
+

While not all details will be encoded in the name, the key features should be obvious: +Number of vCPUs, RAM, Root Disk. +Extra features are important as well: There will be flavors with GPU support, fast disks for databases, +memory-heavy applications, and other useful aspects of an instance.

+

It may also be important to make the CPU generation clearly recognisable, as this is always a topic in +discussions with customers.

+

Proposal

+

Type of information included

+

We believe the following characteristics are important in a flavour description:

+
TypeDescription
GenerationCPU Generation
Number of CPUNumber of vCPUs - suffixed by L,V,T,C (see below)
Amount of RAMAmount of memory available for the VM
Performance ClassAbility to label high-performance CPUs, disks, network
CPU TypeX86-intel, X86-amd, ARM, RISC-V, Generic
"bms"Bare Metal System (no virtualization/hypervisor)
+

Complete Proposal

+
PrefixCPUSuffixRAM[GiB]optional: Disk[GB]optional: Disk typeoptional: extra features
SCS-NL/V/T/C[i]:N[u][o][:[Mx]N][n/s/l/p][-hyp][-hwv]-[arch[N][h][-[G/g]X[N][:M[h]]][-ib]
+

(Note that N and M are placeholders for numbers here).

+

Proposal Details

+

[REQUIRED] CPU Suffixes

+
SuffixMeaning
Cdedicated Core
Tdedicated Thread (SMT)
VvCPU (oversubscribed)
LvCPU (heavily oversubscribed)
+

Baseline

+

Note that vCPU oversubscription for a V vCPU should be implemented such, that we +can guarantee at least 20% of a core in >99% of the time; this can be achieved by +limiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled) +or by more advanced workload management logic. Otherwise L (low performance) must be +used. The >99% is measured over a month (1% is 7.2h/month).

+

Note that CPUs must use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.). +We expect that microcode gets updated within less than a month of a new release; for CVSS scores above 8, +we expect less than a week. +The provider must enable at least all mitigations that are enabled by default in the Linux kernel. CPUs that +are susceptible to L1TF (intel x86 pre Cascade Lake) must switch off hyperthreading OR (in the future) +use core scheduling implementations that are deemed to be secure by the SCS security team, or declare themselves +as insecure with the i suffix (see below).

+

Higher oversubscription

+

Must be indicated with a L vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and +the lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month).

+

Insufficient microcode

+

Not using these mitigations must be indicated by an additional i suffix for insecure +(weak protection against CPU vulns through insufficient microcode, lack of disabled hyperthreading +on L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor).

+

Examples

+
    +
  • SCS-2C:4:10n
  • +
  • SCS-2T:4:10n
  • +
  • SCS-2V:4:10n
  • +
  • SCS-2L:4:10n
  • +
  • SCS-2Li:4:10n
  • +
  • SCS-2:**4:10n - CPU suffix missing
  • +
  • SCS-2iT:4:10n - This order is forbidden
  • +
+

[REQUIRED] Memory

+

Baseline

+

We expect cloud providers to use ECC memory. +Memory oversubscription is not recommended. +It is allowed to specify half GiBs (e.g. 3.5), though this is discouraged for larger memory sizes (>= 10GiB).

+

No ECC

+

If no ECC is used, the u suffix must indicate this.

+

Enabled Oversubscription

+

You have to expose this with the o sufffix.

+

Examples

+
    +
  • SCS-2C:4:10n
  • +
  • SCS-2C:3.5:10n
  • +
  • SCS-2C:4u:10n
  • +
  • SCS-2C:4o:10n
  • +
  • SCS-2C:4uo:10n
  • +
  • SCS-2C:4ou:10n - This order is forbidden
  • +
+

[OPTIONAL] Disk sizes and types

+
Disk typeMeaning
nNetwork shared storage (ceph/cinder)
hLocal disk (HDD: SATA/SAS class)
sLocal SSD disk
pLocal high-perf NVMe
+

Baseline

+

Note that disk type might be omitted — the user then can not take any assumptions +on what storage is provided for the root disk (that the image gets provisioned to).

+

It does make sense for n to be requested explicitly to allow for smooth live migration. +h typically provides latency advantages vs n (but not necessarily bandwidth and +also is more likely to fail), s and p are for applications that need low +latency (high IOPS) and bandwidth disk I/O. n storage is expected to survive +single-disk and single-node failure.

+

If the disk size is left out, the cloud is expected to allocate a disk (network or local) +that is large enough to fit the root file system (min_disk in image). This automatic +allocation is indicated with : without a disk size. +If the : is left out completely, the user must create a boot volume manually and +tell the instance to boot from it or use the +block_device_mapping_v2 +mechanism explicitly to create the boot volume from an image.

+

Multi-provisioned Disk

+

The disk size can be prefixed with Mx prefix, where M is an integer specifying that the disk +is provisioned M times.

+

Examples

+
    +
  • SCS-2C:4:10n
  • +
  • SCS-2C:4:10s
  • +
  • SCS-2C:4:10s-bms-z3
  • +
  • SCS-2C:4:3x10s - Cloud creates three 10GB SSDs
  • +
  • SCS-2C:4:3x10s-bms-z3
  • +
  • SCS-2C:4:10 - Cloud decides disk type
  • +
  • SCS-2C:4:10-bms-z3
  • +
  • SCS-2C:4:n - Cloud decides disk size (min_disk from image or larger)
  • +
  • SCS-2C:4:n-bms-3
  • +
  • SCS-2C:4: - Cloud decides disk type and size
  • +
  • SCS-2C:4:-bms-z3
  • +
  • SCS-2C:4:-bms-z3h-GNa:64-ib
  • +
  • SCS-2C:4:-ib
  • +
  • SCS-2C:4 - You need to specify a boot volume yourself (boot from volume, or use block_device_mapping_v2)
  • +
  • SCS-2C:4-bms-z3
  • +
  • SCS-2C:4:3x - Cloud decides disk type and size and creates three of them (FIXME: Is this useful?)
  • +
  • SCS-2C:4:3xs - Cloud decides size and creates three local SSD volumes (FIXME: useful?)
  • +
  • SCS-2C:4:3x10 - Cloud decides type and creates three 10GB volumes
  • +
  • SCS-2C:4:1.5n - You must not specify disk sizes which are not in full GiBs
  • +
+

[OPTIONAL] Hypervisor

+

The default Hypervisor is assumed to be KVM. Clouds, that offer different hypervisors +or Bare Metal Systems should indicate the Hypervisor according to the following table:

+
hypMeaning
kvmKVM
xenXen
vmwVMware
hyvHyper-V
bmsBare Metal System
+

Examples

+
    +
  • SCS-2C:4:10n
  • +
  • SCS-2C:4:10n-bms
  • +
  • SCS-2C:4:10n-bms-z3h
  • +
+

[OPTIONAL] Hardware virtualization / Nested virtualization

+

If the instances that are created with this flavor support hardware-accelerated +virtualization, this can be reflected with the -hwv flag (after the optional +Hypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel) +or svm (AMD) is available. This will be the case on Bare Metal flavors on almost +all non-ancient x86 CPUs or if your virtualization hypervisor is configured to +support nested virtualization. +Flavors without the -hwv flag may or may not support hardware virtualization (as we +recommend enabling nesting, but don't require flavor names to reflect all +capabilities. Flavors may overdeliver ...)

+

Examples

+
    +
  • SCS-2C:4:10 - may or may not support HW virtualization in VMs
  • +
  • SCS-2C:4:10-kvm-hwv
  • +
  • SCS-2C:4:10-hwv - not recommended, but allowed
  • +
  • SCS-2C:4:10-hwv-xen - illegal, wrong ordering
  • +
+

[OPTIONAL] CPU Architecture Details

+

Arch details provide more details on the specific CPU:

+
    +
  • Vendor
  • +
  • Generation
  • +
  • Frequency
  • +
+

Generation and Vendor

+

The generations are vendor specific and can be left out. +Not specifying arch means that we have a generic CPU (x86-64).

+
Generationi (Intel x86-64)z (AMD x86-64) a (AArch64)r (RISC-V)
0pre Skylakepre Zenpre Cortex A76TBD
1SkylakeZen-1 (Naples)A76/NeoN1 classTBD
2Cascade LakeZen-2 (Rome)A78/x1/NeoV1 classTBD
3Ice LakeZen-3 (Milan)A71x/NeoN2 (ARMv9)TBD
4Zen-4 (Genoa)TBD
+

It is recommended to leave out the 0 when specifying the old generation; this will +help the parser tool, which assumes 0 for an unspecified value and does leave it +out when generating the name for comparison. In other words: 0 has a meaning of +"rather old or unspecified".

+

Frequency Suffixes

+
SuffixMeaning
h>2.75GHz all-core
hh>3.25GHz all-core
hhh>3.75GHz all-core
+

Examples

+
    +
  • SCS-2C:4:10n
  • +
  • SCS-2C:4:10n-z
  • +
  • SCS-2C:4:10n-z3
  • +
  • SCS-2C:4:10n-z3h
  • +
  • SCS-2C:4:10n-z3hh
  • +
  • SCS-2C:4:10n-bms-z
  • +
  • SCS-2C:4:10n-bms-z3
  • +
  • SCS-2C:4:10n-bms-z3
  • +
  • SCS-2C:4:10n-bms-z3h
  • +
  • SCS-2C:4:10n-bms-z3hh
  • +
+

[OPTIONAL] Extra features

+

Note that these are optional — it is recommended for providers to encode this information +into the flavor name, so there is a systematic way of differentiating flavors. +Providers could leave it out however, leaving it to extra_specs to make these flavor +capabilities discoverable. Nothing prevents providers from registering the same flavor +under a secondary (or tertiary) name.

+

-GX[N][:M[h]] indicates a Pass-Through GPU from vendor X of gen N with M compute units / SMs / EUs exposed. +-gX[N][:M[h]] indicates a vGPU from vendor X of gen N with M compute units / SMs / EUs assigned.

+

Note that the vendor letter is mandatory, generation and compute units are optional.

+
GPUVendor
NnVidia
AAMD
IIntel
+

Generations could be nVidia (f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, ...), +AMD (GCN-x=0.x, RDNA1=1, RDNA2=2), intel (Gen9=0.9, Xe(12.1)=1, ...), ... +(Note: This may need further work to properly reflect what's out there.)

+

The optional h suffix to the comput unit count indicates high-performance (e.g. high freq or special +high bandwidth gfx memory such as HBM); +h can be duplicated for even higher performance.

+

-ib indicates Inifinband networking.

+

More extensions will be forthcoming.

+

Extensions need to be specified in the above mentioned order.

+

Proposal Examples

+
ExampleDecoding
SCS-2C:4:10n2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk
SCS-8Ti:32:50p-i18 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe
SCS-1L:1u:51 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific)
SCS-16T:64:200s-GNa:64-ib16 dedicated threads, 64GiB RAM, 200GB local SSD, Inifiniband, 64 Passthrough nVidia Ampere SMs
SCS-4C:16:2x200p-a14 dedicated Arm64 cores (A78 class), 16GiB RAM, 2x200GB local NVMe drives
SCS-1V:0.51 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)
+

Standard SCS flavors

+

These are flavors expected to exist on standard SCS clouds (x86-64).

+

We expect disk sizes to be 5, 10, 20, 50, 100, 200, 500, 1000GB, 2000GB. +We expect a typical CPU

GiB
ratio of 1:4.

+
vCPU:RAM ratioMandatory Flavors
1:4SCS-1V:4, SCS-1V:4:10
2:8SCS-2V:8, SCS-2V:8:20
4:16SCS-4V:16, SCS-4V:16:50
8:32SCS-8V:32, SCS-8V:32:100
1:2SCS-1V:2, SCS-1V:2:5
2:4SCS-2V:4, SCS-2V:4:10
4:8SCS-4V:8, SCS-4V:8:20
8:16SCS-8V:16, SCS-8V:16:50
16:32SCS-16V:32, SCS-16V:32:100
1:8SCS-1V:8, SCS-1V:8:20
2:16SCS-2V:16, SCS-2V:16:50
4:32SCS-4V:32, SCS-4V:32:100
1:1SCS-1L:1, SCS-1L:1:5
+

Note that all vCPUs are oversubscribed — the smallest 1L:1 flavor allows +for heavy oversubscription (note the L), and thus can be offered very +cheaply — imagine jump hosts ... +Disks types are not specified (and expected to be n or h typically).

+

The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM +compute hosts) to offer all flavors.

+

Note: Compared to previous drafts, we have heavily reduced the variations +on disk sizes — this reflects that for the standard networked cinder +disks, you can pass blockdevice_mapping_v2 on server (VM) creation to +allocate a boot disk of any size you desire. We have scaled the few +mandatory disk sizes with the amount of RAM. For each flavor there is +also one _without a pre-attached disk — these are meant to be used +to boot from a volume (either created beforehand or allocated on-the-fly +with block_device_mapping_v2, e.g. +openstack server create --flavor SCS-1V:2 --block-device-mapping sda=IMGUUID:image:12:true +to create a bootable 12G cinder volume from image IMGUUID that gets tied to the VM +instance lifecycle.)

+

Naming policies

+

To be certified as an SCS compliant x86-64 IaaS platform, you must offer all standard SCS flavors +according to the previous section. (We may define a mechanism that allows exceptions to be +granted in a way that makes this very transparent and visible to clients.)

+

You are allowed to understate your performance; you may implement a SCS-1Vl:1:5 flavor with +a flavor that actually implements SCS-1T:1:5n (i.e. you dedicate a secured hyperthread instead +of high oversubscription) or even SCS-1D:1.5:8s (1 dedicated core, 50% more RAM and a 8GiB SSD).

+

We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V:32:100). +Larger providers that offer more details are expected to still also offer the short variants +for usability and easier portability, even beyond the mandated flavors.

+

You must be very careful to expose low vCPU guarantees (L instead ov V), insecure +hyperthreading/microcode i, non-ECC-RAM u, memory oversubscription o. Note that omitting these qualifiers is +overstating your security, reliability or performance properties and may be reason for +clients to feel betrayed or claim damages. It might in extreme cases also cause SCS to withdraw certification +along with public statements.

+

You may offer additional SCS- flavors, following the naming scheme outlined here.

+

You may offer additional flavors, not following above scheme.

+

You must not offer flavors with the SCS- prefix which do not follow this naming scheme. +You must not extend the SCS naming scheme with your own suffices; you are encouraged however +to suggest extensions that we can discuss and add to the official scheme.

+

Note that all letters are case-sensitive. +In case you wonder: Feature indicators are capitalized, modifiers are lower case. +(An exception is the uppercase -G for a passthrough GPU vs. lowercase -g for vGPU.)

+

Rationale

+

Note that we expect most clouds to prefer short flavor names, +not indicating CPU details or hypervisor types. See above list +of standard flavors to get a feeling.

+

However, more successful providers will often need to differentiate their +offerings in response to customer demand and allow customers to request +flavors with specific detailed properties. The goal of this proposal is to avoid +providers to invent their own names and then refer customers to extra_specs +or worse a non-machine-readable service description to find out the details.

+

So a cloud provider might well evolve from offering SCS-8T:16:50 to offering +SCS-8T:16:50n, SCS-8T:16:50n-i2 and SCS-8T:16:50n-a2 to specify that he +is using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome. +We would expect the cloud provider to still offer the generic flavor +SCS-8C:16:50 and allow the scheduler (placement service) to pick both more +specific types (or just one if e.g. capacity management considerations suggest +so). We would expect providers in such cases to ensure that the price of a requested +flavor does not depend on the scheduler decisions.

+

We are looking into the metadefs +mechanism and extra_specs +to allow customers to ask for specific flavor properties without the need to +encode all these flavor details into the flavor name, so the optional pieces +may not be needed much. However, there must be a way to request flavor +properties without encoding the need into an image — this indirection is +considered broken by the SCS team.

+

Validation

+

There is a script in flavor_name_check.py +which can be used to decode, validate and construct flavor names. +This script must stay in sync with the specification text.

+

Ensure you have your OpenStack tooling (python3-openstackclient, OS_CLOUD) setup and call +tools/flavor-name-check.py -c $(openstack flavor list -f value -c Name) to get a report +on the flavor list compliance of the cloud environment.

+

Beyond SCS: Gaia-X

+

Some providers might offer VM services ("IaaS") without trying to adhere to SCS standards, +yet still finding the flavor naming standards useful. The Gaia-X Technical Committee's +Provider Working Group (WG) would seem like a logical place for such dicussions then. +If so, we could +replace the SCS- prefix with a GX- prefix and transfer the naming scheme governance from +the SCS project to the Gaia-X Provider WG (where we participate). SCS certification would +then reference the Gaia-X flavor naming standard as a requirement.

+ + \ No newline at end of file diff --git a/standards/scs-0100-v2-flavor-naming/index.html b/standards/scs-0100-v2-flavor-naming/index.html new file mode 100644 index 0000000000..d8230c290a --- /dev/null +++ b/standards/scs-0100-v2-flavor-naming/index.html @@ -0,0 +1,392 @@ + + + + + +SCS Flavor Naming Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Flavor Naming Standard

Introduction

+

This is the standard v2.1 for SCS Release 4. +Note that we intend to only extend it (so it's always backwards compatible), +but try to avoid changing in incompatible ways. +(See at the end for the v1 to v2 transition where we have not met that +goal, but at least managed to have a 1:1 relationship between v1 and v2 names.)

+

Motivation

+

In OpenStack environments there is a need to define different flavors for instances. +The flavors are pre-defined by the operator, the customer can not change these. +OpenStack providers thus typically offer a large selection of flavors.

+

While flavors can be discovered (openstack flavor list), it is helpful for users (DevOps teams), +to have

+
    +
  • A naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere.
  • +
  • Have a guaranteed set of flavors available on all SCS clouds, so these do not need to be discovered.
  • +
+

While not all details will be encoded in the name, the key features should be obvious: +Number of vCPUs, RAM, Root Disk. +Extra features are important as well: There will be flavors with GPU support, fast disks for databases, +memory-heavy applications, and other useful aspects of an instance.

+

It may also be important to make the CPU generation clearly recognizable, as this is always a topic in +discussions with customers.

+

Note that not all relevant properties of flavors can be discovered; creating a specification +to address this is a separate but related effort to the name standardization. +Commonly used infrastructure-as-code tools do not provide a way to use discoverability +features to express something like "I want a flavor with 2 vCPUs, 8GiB of RAM, a local +20GB SSD disk and Infiniband support but I don't care whether it's AMD or intel" in a +reasonable manner. Using flavor names to express this will thus continue to be useful +and we don't expect the need for standardization of flavor names to go away until +the commonly used IaC tools work on a higher abstraction layer than they currently do.

+

Design Considerations

+

Type of information included

+

From discussions of our operators with their customers we learned that +the following characteristics are important in a flavor description:

+
TypeDescription
GenerationCPU Generation
Number of CPUNumber of vCPUs - suffixed by L,V,T,C (see below)
Amount of RAMAmount of memory available for the VM
Performance ClassAbility to label high-performance CPUs, disks, network
CPU TypeX86-intel, X86-amd, ARM, RISC-V, Generic
"bms"Bare Metal System (no virtualization/hypervisor)
+

This list is likely not comprehensive and will grow over time.

+

Rather than using random names s5a.medium and assigning a discrete set of properties +to them, we wanted to come up with a scheme that allows to systematically derive +names from properties and vice versa. The scheme allows for short names (by not +encoding all details) as well as very detailed longer names.

+

Complete Proposal for systematic flavor naming

+
PrefixCPUs & SuffixRAM[GiB]optional: Disk[GB]&typeopt: extensions
SCS-NL/V/T/C[i]-N[u][o][-[Mx]N[n/s/l/p]][_EXT]
+

Note that N and M are placeholders for numbers here. +The optional fields are denoted in brackets (and have opt: in the header. +See below for extensions.

+

Note that all letters are case-sensitive.

+

Typical flavor names look like SCS-4V-16-50 for a flavor with 4vCPUs (with limited +oversubscription), 16GiB RAM and a 50GB disk (of unspecified type).

+

Proposal Details

+

[REQUIRED] CPU Suffixes

+

Next to the number of vCPUs, these vCPUs need to be characterized ti describe their nature.

+
SuffixMeaning
Cdedicated Core
Tdedicated Thread (SMT)
VvCPU (oversubscribed)
LvCPU (heavily oversubscribed)
+

Baseline

+

Note that vCPU oversubscription for a V vCPU should be implemented such, that we +can guarantee at least 20% of a core in >99% of the time; this can be achieved by +limiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled) +or by more advanced workload management logic. Otherwise L (low performance) instead +of V must be used. The >99% is measured over a month (1% is 7.2h/month).

+

Note that CPUs should use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.). +Microcode must be updated within less than a month of a new release; for CVSS scores above 8, +providers should do it in less than a week. +The provider should enable at least all mitigations that are enabled by default in the Linux kernel and the +KVM hypervisor. CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) should switch off hyperthreading +OR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team.

+

If microcode updates needed for mitigation are lacking for longer than a month, default kernel/hypervisor +mitigations are disabled or hyperthreading is enabled despite the CPU being susceptible to L1TF, the +flavors must declare themselves insecure with the i suffix (see below).

+

Higher oversubscription

+

Must be indicated with a L vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and +the lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month).

+

Insufficient microcode

+

Not using these mitigations must be indicated by an additional i suffix for insecure +(weak protection against CPU vulns through insufficient microcode, lack of disabled hyperthreading +on L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor).

+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2T-4-10n
  • +
  • SCS-2V-4-10n
  • +
  • SCS-2L-4-10n
  • +
  • SCS-2Li-4-10n
  • +
  • SCS-2-**4-10n - CPU suffix missing
  • +
  • SCS-2iT-4-10n - This order is forbidden
  • +
+

[REQUIRED] Memory

+

Baseline

+

Cloud providers should use ECC memory. +Memory oversubscription should not be used. +It is allowed to specify half GiBs (e.g. 3.5), though this is should not be done for larger memory sizes (>= 10GiB).

+

No ECC

+

If no ECC is used, the u suffix must indicate this.

+

Enabled Oversubscription

+

If memory is oversubscribed, you must expose this with the o suffix.

+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-3.5-10n
  • +
  • SCS-2C-4u-10n
  • +
  • SCS-2C-4o-10n
  • +
  • SCS-2C-4uo-10n
  • +
  • SCS-2C-4ou-10n - This order is forbidden
  • +
+

[OPTIONAL] Disk sizes and types

+

Disk sizes (in GB) should use sizes 5, 10, 20, 50, 100, 200, 500, 1000.

+
Disk typeMeaning
nNetwork shared storage (ceph/cinder)
hLocal disk (HDD: SATA/SAS class)
sLocal SSD disk
pLocal high-perf NVMe
+

Baseline

+

Note that disk type might be omitted — the user then can not take any assumptions +on what storage is provided for the root disk (that the image gets provisioned to).

+

It does make sense for n to be requested explicitly to allow for smooth live migration. +h typically provides latency advantages vs n (but not necessarily bandwidth and +also is more likely to fail), s and p are for applications that need low +latency (high IOPS) and bandwidth disk I/O. n storage is expected to survive +single-disk and single-node failure.

+

If the disk size is left out, the cloud is expected to allocate a disk (network or local) +that is large enough to fit the root file system (min_disk in image). This automatic +allocation is indicated with - without a disk size. +If the - is left out completely, the user must create a boot volume manually and +tell the instance to boot from it or use the +block_device_mapping_v2 +mechanism explicitly to create the boot volume from an image.

+

Multi-provisioned Disk

+

The disk size can be prefixed with Mx prefix, where M is an integer specifying that the disk +is provisioned M times. Multiple disks provided this way should be independent storage media, +so users can expect some level of parallelism and independence.

+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-4-10s
  • +
  • SCS-2C-4-10s_bms_z3
  • +
  • SCS-2C-4-3x10s - Cloud creates three 10GB SSDs
  • +
  • SCS-2C-4-3x10s_bms_z3
  • +
  • SCS-2C-4-10 - Cloud decides disk type
  • +
  • SCS-2C-4-10_bms_z3
  • +
  • SCS-2C-4-n - Cloud decides disk size (min_disk from image or larger)
  • +
  • SCS-2C-4-n_bms_3
  • +
  • SCS-2C-4- - Cloud decides disk type and size
  • +
  • SCS-2C-4-_bms_z3
  • +
  • SCS-2C-4-_bms_z3h_GNa-64_ib
  • +
  • SCS-2C-4-_ib
  • +
  • SCS-2C-4 - You need to specify a boot volume yourself (boot from volume, or use block_device_mapping_v2)
  • +
  • SCS-2C-4_bms_z3
  • +
  • SCS-2C-4-3x- - Cloud decides disk type and size and creates three of them (FIXME: Is this useful?)
  • +
  • SCS-2C-4-3xs - Cloud decides size and creates three local SSD volumes (FIXME: useful?)
  • +
  • SCS-2C-4-3x10 - Cloud decides type and creates three 10GB volumes
  • +
  • SCS-2C-4-1.5n - You must not specify disk sizes which are not in full GiBs
  • +
+

Standard SCS flavors

+

These are flavors that must exist on standard SCS clouds (x86-64).

+

We expect disk sizes to be 5, 10, 20, 50, 100, 200, 500, 1000GB, 2000GB. +We expect a typical CPU

GiB
ratio of 1:4.

+
vCPU:RAM ratioMandatory Flavors
1:4SCS-1V-4, SCS-1V-4-10
2:8SCS-2V-8, SCS-2V-8-20
4:16SCS-4V-16, SCS-4V-16-50
8:32SCS-8V-32, SCS-8V-32-100
1:2SCS-1V-2, SCS-1V-2-5
2:4SCS-2V-4, SCS-2V-4-10
4:8SCS-4V-8, SCS-4V-8-20
8:16SCS-8V-16, SCS-8V-16-50
16:32SCS-16V-32, SCS-16V-32-100
1:8SCS-1V-8, SCS-1V-8-20
2:16SCS-2V-16, SCS-2V-16-50
4:32SCS-4V-32, SCS-4V-32-100
1:1SCS-1L-1, SCS-1L-1-5
+

Note that all vCPUs of SCS standard flavors are oversubscribed — the smallest 1L-1 +flavor allows for heavy oversubscription (note the L), and thus can be offered very +cheaply — imagine jump hosts ... +Disks types are not specified (and expected to be n or h typically).

+

The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM +compute hosts) to offer all flavors.

+

Note: Compared to previous drafts, we have heavily reduced the variations +on disk sizes — this reflects that for the standard networked cinder +disks, you can pass block_device_mapping_v2 on server (VM) creation to +allocate a boot disk of any size you desire. We have scaled the few +mandatory disk sizes with the amount of RAM. For each flavor there is +also one without a pre-attached disk — these are meant to be used +to boot from a volume (either created beforehand or allocated on-the-fly +with block_device_mapping_v2, e.g. +openstack server create --flavor SCS-1V:2 --block-device-mapping sda=IMGUUID:image:12:true +to create a bootable 12G cinder volume from image IMGUUID that gets tied to the VM +instance life cycle.)

+

Naming policy compliance

+

To be certified as an SCS compliant x86-64 IaaS platform, you must offer all standard SCS flavors +according to the previous section. (We may define a mechanism that allows exceptions to be +granted in a way that makes this very transparent and visible to clients.)

+

You are allowed to understate your performance; you may implement a SCS-1V-1-5 flavor with +a flavor that actually implements SCS-1T-1-5n (i.e. you dedicate a dedicated hyperthread instead +of higher oversubscription) or even SCS-1D-1.5-8s (1 dedicated core, 50% more RAM and a 8GiB SSD).

+

Flavor names indicating certain capabilities must at least provide these, otherwise they +are in violation of the SCS specification and prevent SCS compliance.

+

We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V-32-100). +Larger providers that offer more details (using the extension below) are expected to still also +offer the short variants for usability and easier portability, even beyond the mandated flavors.

+

You must be very careful to expose low vCPU guarantees (L instead of V), insecure +hyperthreading/microcode i, non-ECC-RAM u, memory oversubscription o. Note that omitting these qualifiers is +overstating your security, reliability or performance properties and may be reason for +clients to feel betrayed or claim damages. This would prevent SCS compliance and certification; +in extreme cases, the SCS project might be forced to work with public statements.

+

You may offer additional SCS- flavors, following the naming scheme and rules outlined here.

+

You may offer additional flavors, not following above scheme and not starting with SCS-

+

You must not offer flavors with the SCS- prefix which do not follow this naming scheme. +You must not extend the SCS naming scheme with your own suffices; you are encouraged however +to suggest extensions that we can discuss and add to the official scheme.

+

Validation

+

There is a script in flavor_name_check.py +which can be used to decode, validate and construct flavor names. +This script must stay in sync with the specification text.

+

Ensure you have your OpenStack tooling (python3-openstackclient, OS_CLOUD) setup and call +tools/flavor-name-check.py -c $(openstack flavor list -f value -c Name) to get a report +on the flavor list compliance of the cloud environment.

+

The script flavor-names-openstack.py talks to the OpenStack API of the +cloud specified by the OS_CLOUD environment and queries properties and checks +the names for standards compliance and completeness w.r.t. the mandatory +flavor list. It goes beyond the above example in checking that the discoverable +features of flavors (vCPUs, RAM, Disk) match what the flavor names claim.

+

Operational tooling

+

The openstack-flavor-manager is able to +create all standard, mandatory SCS flavors for you.

+

Extensions

+

Extensions provide a possibility for providers that offer a very differentiated set +of flavors to indicate hypervisors, support for hardware/nested virtuatlization, +CPU types and generations, high-frequency models, GPU support and GPU types as +well as Inifiniband support. (More extensions may be appended in the future.)

+

Using the systematic naming approach ensures that two providers that offer flavors +with the same specific features will use the same name for them, thus simplifying +life for their customers when consuming these flavors.

+

Note that there is no need to indicate all details and extra features this way. +Flavors may always perform better or have more features than indicated in a name. +Underperformance (CPU suffices L or i or memory suffices o and u) on the other +hand MUST be indicated in the name; this happens rarely in practice.

+

For smaller providers, the ability to e.g. differentiate between an AMD Milan and an intel +IceLake and exposed the slightly different feature set to customers and have slightly +different price points is often not worth the extra effort. This is because having +this extra differentiation causes fragmentation of the machines (host aggregates) +that can offer these flavors, thus resulting in a lower utilization (as the capacity +management will need to have a certain amount of headroom per machine pool to avoid +running out of capacity).

+

Note that it possible for providers to register both the generic short names and the +longer, more detailed names and allow them to use the same set of machines (host aggregates). +Note that machines (hypervisors) can be part of more than one host aggregate.

+

The extensions have the format:

+

[_hyp][_hwv][_[arch[N][h][_[G/g]X[N][-M[h]]][_ib]

+

Remember that letters are case-sensitive. +In case you wonder: Feature indicators are capitalized, modifiers are lower case. +(An exception is the uppercase -G for a pass-through GPU vs. lowercase -g for vGPU.)

+

[OPTIONAL] Hypervisor

+

The default Hypervisor is assumed to be KVM. Clouds, that offer different hypervisors +or Bare Metal Systems should indicate the Hypervisor according to the following table:

+
hypMeaning
kvmKVM
xenXen
vmwVMware
hyvHyper-V
bmsBare Metal System
+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-4-10n_bms
  • +
  • SCS-2C-4-10n_bms_z3h
  • +
+

[OPTIONAL] Hardware virtualization / Nested virtualization

+

If the instances that are created with this flavor support hardware-accelerated +virtualization, this can be reflected with the _hwv flag (after the optional +Hypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel) +or svm (AMD) is available. This will be the case on Bare Metal flavors on almost +all non-ancient x86 CPUs or if your virtualization hypervisor is configured to +support nested virtualization. +Flavors without the _hwv flag may or may not support hardware virtualization (as we +recommend enabling nesting, but don't require flavor names to reflect all +capabilities. Flavors may over-deliver ...)

+

Examples

+
    +
  • SCS-2C-4-10 - may or may not support HW virtualization in VMs
  • +
  • SCS-2C-4-10_kvm_hwv - kvm with enabled nested virtualization
  • +
  • SCS-2C-4-10_hwv - not recommended, but allowed
  • +
  • SCS-2C-4-10_bms_hwv - better: bare metal with HW virt support (VMX on intel, SVM on AMD, ...)
  • +
  • SCS-2C-4-10_hwv_xen - illegal, wrong ordering
  • +
+

[OPTIONAL] CPU Architecture Details

+

Arch details provide more details on the specific CPU:

+
    +
  • Vendor
  • +
  • Generation
  • +
  • Frequency
  • +
+

Generation and Vendor

+

The generations are vendor specific and can be left out. +Not specifying arch means that we have a generic CPU (x86-64). +The letters i, z, a and r specify the vendors Intel, +AMD (z like in Zen), ARM v8+, RISC-V.

+
Generationi (Intel x86-64)z (AMD x86-64) a (AArch64)r (RISC-V)
0pre Skylakepre Zenpre Cortex A76TBD
1SkylakeZen-1 (Naples)A76/NeoN1 classTBD
2Cascade LakeZen-2 (Rome)A78/x1/NeoV1 classTBD
3Ice LakeZen-3 (Milan)A71x/NeoN2 (ARMv9)TBD
4Sapphire RapidsZen-4 (Genoa)TBD
+

It is recommended to leave out the 0 when specifying the old generation; this will +help the parser tool, which assumes 0 for an unspecified value and does leave it +out when generating the name for comparison. In other words: 0 has a meaning of +"rather old or unspecified".

+

Frequency Suffixes

+
SuffixMeaning
h>2.75GHz all-core
hh>3.25GHz all-core
hhh>3.75GHz all-core
+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-4-10n_z
  • +
  • SCS-2C-4-10n_z3
  • +
  • SCS-2C-4-10n_z3h
  • +
  • SCS-2C-4-10n_z3hh
  • +
  • SCS-2C-4-10n_bms_z
  • +
  • SCS-2C-4-10n_bms_z3
  • +
  • SCS-2C-4-10n_bms_z3
  • +
  • SCS-2C-4-10n_bms_z3h
  • +
  • SCS-2C-4-10n_bms_z3hh - Bare Metal, Intel Ice Lake with > 3.25GHz all core freq
  • +
+

[OPTIONAL] GPU support

+

_GX[N][-M[h]] indicates a Pass-Through GPU from vendor X of gen N with M compute units / SMs / EUs exposed. +_gX[N][-M[h]] indicates a vGPU from vendor X of gen N with M compute units / SMs / EUs assigned.

+

Note that the vendor letter X is mandatory, generation and compute units are optional.

+
GPUVendor
NnVidia
AAMD
IIntel
+

For nVidia, the generation N can be f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, l=Ada Lovelace, ..., +for AMD GCN-x=0.x, RDNA1=1, RDNA2=2, RDNA3=3, for intel Gen9=0.9, Xe(12.1)=1, ... +(Note: This may need further work to properly reflect what's out there.)

+

The optional h suffix to the compute unit count indicates high-performance (e.g. high freq or special +high bandwidth gfx memory such as HBM); +h can be duplicated for even higher performance.

+

[OPTIONAL] Infiniband

+

_ib indicates Infiniband networking.

+

More extensions may be forthcoming and appended in a later revision of this spec.

+

Extensions need to be specified in the above mentioned order.

+

Naming options advice

+

Note that we expect most clouds to prefer short flavor names, +not indicating CPU details or hypervisor types. See above list +of standard flavors to get a feeling.

+

However, more successful providers will often need to differentiate their +offerings in response to customer demand and allow customers to request +flavors with specific detailed properties. The goal of this proposal is to avoid +providers to invent their own names and then refer customers to (currently +incompletely standardized) extra_specs +or worse a non-machine-readable service descriptions to find out the details.

+

So a cloud provider might well evolve from offering SCS-8T-16-50 to offering +SCS-8T-16-50n, SCS-8T-16-50n_i2 and SCS-8T-16-50n_a2 to specify that he +is using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome. +We would expect the cloud provider to still offer the generic flavor +SCS-8T-16-50 and allow the scheduler (placement service) to pick both more +specific types (or just one if e.g. capacity management considerations suggest +so). Providers should in such cases make sure that the price does not depend +on scheduler decisions.

+

We are looking into the metadefs +mechanism and extra_specs +to allow customers to ask for specific flavor properties without the need to +encode all these flavor details into the flavor name, so the optional pieces +may not be needed much. However, there must be a way to request flavor +properties without encoding the need into an image — the indirection via +an image is considered broken by the SCS team.

+

Proposal Examples

+
ExampleDecoding
SCS-2C-4-10n2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk
SCS-8Ti-32-50p_i18 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe
SCS-1L-1u-51 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific)
SCS-16T-64-200s_GNa-64_ib16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 64 Passthrough nVidia Ampere SMs
SCS-4C-16-2x200p_a14 dedicated Arm64 cores (A76 class), 16GiB RAM, 2x200GB local NVMe drives
SCS-1V-0.51 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)
+

Previous standard versions

+

Version 1 of the standard +used a slightly different naming syntax while the logic was exactly the same. +What is a - in v2 used to be a :; _ used to be -. The reason for +the change was certain Kubernetes tools using the flavor names as labels. +Labels however are subject to stricter naming rules and in particular don't +allow for a :. See PR #190 +for a discussion.

+

Version 1 flavor names can be translated to v2 using the following transformation:

+
NAMEV2=$(echo "$NAMEV1" | sed -e 's/\-/_/g' -e 's/:/-/g' -e 's/^SCS_/SCS-/')
+

and the way back can be done with

+
NAMEV1=$(echo "$NAMEV2" | sed -e 's/\-/:/g' -e 's/_/-/g' -e 's/^SCS:/SCS-/')
+

Considerations for how providers can ensure a smooth transition for their customers +from v1 to v2 are written in a separate document.

+

For the time being, the validation tools still accept the old names with a warning +(despite the unchanged SCS- prefix) unless you pass option -2 to them. They will +however not count v1 flavors towards fulfilling the needs against the corresponding +v2 mandatory flavor list unless you pass the option -1. +In other words: An IaaS infrastructure with the 26 +v1 mandatory flavors will produce 26 warnings (for using old flavors) and 26 +errors (for missing the 26 mandatory v2 flavors) unless you pass -1 in which +case no errors and no warnings will be produced. Registering the 26 mandatory +v2 flavor names in addition will result in passing the test with only 26 +warnings — unless you specify -2. If you do and want to pass you'll need +to remove the old v1 names or rename them to no longer start with SCS-.

+

Beyond SCS

+

The Gaia-X provider working group which could have created a superseding standard +does no longer exist.

+

However, we have been reaching out to the OpenStack Public Cloud SIG and the ALASCA +members to seek further alignment.

+

Getting upstream OpenStack support for flavor aliases would provide more flexibility +and ease migrations between providers, also providers that don't offer the SCS- +flavors.

+

We also would like to see upstream extra_specs standardizing the discoverability of some +properties exposed via the SCS names and work on IaC tooling (terraform ...) +to make use of these when selecting a flavor.

+ + \ No newline at end of file diff --git a/standards/scs-0100-v3-flavor-naming/index.html b/standards/scs-0100-v3-flavor-naming/index.html new file mode 100644 index 0000000000..49cc0691f1 --- /dev/null +++ b/standards/scs-0100-v3-flavor-naming/index.html @@ -0,0 +1,397 @@ + + + + + +SCS Flavor Naming Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Flavor Naming Standard

Introduction

+

This is the standard v3.1 for SCS Release 5. +Note that we intend to only extend it (so it's always backwards compatible), +but try to avoid changing in incompatible ways. +(See at the end for the v1 to v2 transition where we have not met that +goal, but at least managed to have a 1:1 relationship between v1 and v2 names.)

+

Motivation

+

In OpenStack environments there is a need to define different flavors for instances. +The flavors are pre-defined by the operator, the customer can not change these. +OpenStack providers thus typically offer a large selection of flavors.

+

While flavors can be discovered (openstack flavor list), it is helpful for users (DevOps teams), +to have a naming scheme that is used across all SCS flavors, so flavor names have the same meaning everywhere.

+

While not all details will be encoded in the name, the key features should be obvious: +Number of vCPUs, RAM, Root Disk. +Extra features are important as well: There will be flavors with GPU support, fast disks for databases, +memory-heavy applications, and other useful aspects of an instance.

+

It may also be important to make the CPU generation clearly recognizable, as this is always a topic in +discussions with customers.

+

Note that not all relevant properties of flavors can be discovered; creating a specification +to address this is a separate but related effort to the name standardization. +Commonly used infrastructure-as-code tools do not provide a way to use discoverability +features to express something like "I want a flavor with 2 vCPUs, 8GiB of RAM, a local +20GB SSD disk and Infiniband support but I don't care whether it's AMD or intel" in a +reasonable manner. Using flavor names to express this will thus continue to be useful +and we don't expect the need for standardization of flavor names to go away until +the commonly used IaC tools work on a higher abstraction layer than they currently do.

+

Design Considerations

+

Type of information included

+

From discussions of our operators with their customers we learned that +the following characteristics are important in a flavor description:

+
TypeDescription
GenerationCPU Generation
Number of CPUNumber of vCPUs - suffixed by L,V,T,C (see below)
Amount of RAMAmount of memory available for the VM
Performance ClassAbility to label high-performance CPUs, disks, network
CPU TypeX86-intel, X86-amd, ARM, RISC-V, Generic
"bms"Bare Metal System (no virtualization/hypervisor)
+

This list is likely not comprehensive and will grow over time.

+

Rather than using random names s5a.medium and assigning a discrete set of properties +to them, we wanted to come up with a scheme that allows to systematically derive +names from properties and vice versa. The scheme allows for short names (by not +encoding all details) as well as very detailed longer names.

+

Complete Proposal for systematic flavor naming

+
PrefixCPUs & SuffixRAM[GiB]optional: Disk[GB]&typeopt: extensions
SCS-NL/V/T/C[i]-N[u][o][-[Mx]N[n/h/s/p]][_EXT]
+

Note that N and M are placeholders for numbers here. +The optional fields are denoted in brackets (and have opt: in the header. +See below for extensions.

+

Note that all letters are case-sensitive.

+

Typical flavor names look like SCS-4V-16-50 for a flavor with 4vCPUs (with limited +oversubscription), 16GiB RAM and a 50GB disk (of unspecified type).

+

Proposal Details

+

[REQUIRED] CPU Suffixes

+

Next to the number of vCPUs, these vCPUs need to be characterized to describe their nature.

+
SuffixMeaning
Cdedicated Core
Tdedicated Thread (SMT)
VvCPU (oversubscribed)
LvCPU (heavily oversubscribed)
+

Baseline

+

Note that vCPU oversubscription for a V vCPU should be implemented such, that we +can guarantee at least 20% of a core in >99% of the time; this can be achieved by +limiting vCPU oversubscription to 5x per core (or 3x per thread when SMT/HT is enabled) +or by more advanced workload management logic. Otherwise L (low performance) instead +of V must be used. The >99% is measured over a month (1% is 7.2h/month).

+

Note that CPUs should use latest microcode to protect against CPU vulnerabilities (Spectre, Meltdown, L1TF, etc.). +In particular,

+
    +
  • microcode must be updated within less than a month of a new release; for CVSS scores above 8, +providers should do it in less than a week.
  • +
  • all mitigations that are enabled by default in the Linux kernel and the KVM hypervisor +should be enabled,
  • +
  • CPUs that are susceptible to L1TF (intel x86 pre Cascade Lake) should have hyperthreading +disabled OR (in the future) use core scheduling implementations that are deemed to be secure by the SCS security team.
  • +
+

That is to say, except when the suffix i is used, the provider commits itself to implementing the appropriate mitigations +if and when they become available, within the timeframes mentioned above.

+

If a provider does not want to commit to deploying available microcode fixes and upstream kernel/hypervisor updates within a month or +if the provider wants to enable hyperthreading on compute hosts despite having CPUs susceptible to L1TF there +(and no SCS-accepted core-scheduling mechanism is used for mitigation), +the flavors must be declared insecure with the i suffix (see below).

+

Higher oversubscription

+

Must be indicated with a L vCPU type (low performance for > 5x/core or > 3x/thread oversubscription and +the lack of workload management that would prevent worst case performance < 20% in more than 7.2h per month).

+

Insufficient microcode

+

Not using these mitigations must be indicated by an additional i suffix for insecure +(weak protection against CPU vulns through insufficient microcode, lack of disabled hyperthreading +on L1TF susceptible CPUs w/o effective core scheduling or disabled protections on the host/hypervisor).

+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2T-4-10n
  • +
  • SCS-2V-4-10n
  • +
  • SCS-2L-4-10n
  • +
  • SCS-2Li-4-10n
  • +
  • SCS-2-**4-10n - CPU suffix missing
  • +
  • SCS-2iT-4-10n - This order is forbidden
  • +
+

[REQUIRED] Memory

+

Baseline

+

Cloud providers should use ECC memory. +Memory oversubscription should not be used. +It is allowed to specify half GiBs (e.g. 3.5), though this is should not be done for larger memory sizes (>= 10GiB).

+

No ECC

+

If no ECC is used, the u suffix must indicate this.

+

Enabled Oversubscription

+

If memory is oversubscribed, you must expose this with the o suffix.

+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-3.5-10n
  • +
  • SCS-2C-4u-10n
  • +
  • SCS-2C-4o-10n
  • +
  • SCS-2C-4uo-10n
  • +
  • SCS-2C-4ou-10n - This order is forbidden
  • +
+

[OPTIONAL] Disk sizes and types

+

Disk sizes (in GB) should use sizes 5, 10, 20, 50, 100, 200, 500, 1000.

+
Disk typeMeaning
nNetwork shared storage (ceph/cinder)
hLocal disk (HDD: SATA/SAS class)
sLocal SSD disk
pLocal high-perf NVMe
+

Baseline

+

Note that disk type might be omitted — the user then can not take any assumptions +on what storage is provided for the root disk (that the image gets provisioned to).

+

It does make sense for n to be requested explicitly to allow for smooth live migration. +h typically provides latency advantages vs n (but not necessarily bandwidth and +also is more likely to fail), s and p are for applications that need low +latency (high IOPS) and bandwidth disk I/O. n storage is expected to survive +single-disk and single-node failure.

+

For specific requirements on the SSD and NVMe disks regarding IOPS and +power-loss protection, refer to Decision Record scs-0110-ssd-flavors.

+

If the disk size is left out, the cloud is expected to allocate a disk (network or local) +that is large enough to fit the root file system (min_disk in image). This automatic +allocation is indicated with - without a disk size. +If the - is left out completely, the user must create a boot volume manually and +tell the instance to boot from it or use the +block_device_mapping_v2 +mechanism explicitly to create the boot volume from an image.

+

Multi-provisioned Disk

+

The disk size can be prefixed with Mx prefix, where M is an integer specifying that the disk +is provisioned M times. Multiple disks provided this way should be independent storage media, +so users can expect some level of parallelism and independence.

+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-4-10s
  • +
  • SCS-2C-4-10s_bms_z3
  • +
  • SCS-2C-4-3x10s - Cloud creates three 10GB SSDs
  • +
  • SCS-2C-4-3x10s_bms_z3
  • +
  • SCS-2C-4-10 - Cloud decides disk type
  • +
  • SCS-2C-4-10_bms_z3
  • +
  • SCS-2C-4-n - Cloud decides disk size (min_disk from image or larger)
  • +
  • SCS-2C-4-n_bms_3
  • +
  • SCS-2C-4- - Cloud decides disk type and size
  • +
  • SCS-2C-4-_bms_z3
  • +
  • SCS-2C-4-_bms_z3h_GNa-64_ib
  • +
  • SCS-2C-4-_ib
  • +
  • SCS-2C-4 - You need to specify a boot volume yourself (boot from volume, or use block_device_mapping_v2)
  • +
  • SCS-2C-4_bms_z3
  • +
  • SCS-2C-4-3x10 - Cloud decides type and creates three 10GB volumes
  • +
  • SCS-2C-4-1.5n - You must not specify disk sizes which are not in full GiBs
  • +
+

Naming policy compliance

+

Every flavor you offer MUST satisfy the following assertion:

+
    +
  • If its name starts with SCS-, the name has to conform to the syntax outlined above, and +the flavor must at least provide the capabilities indicated by the name.
  • +
+

That is to say:

+
    +
  • +

    You may offer flavors not following the above scheme, as long as the name does not +start with SCS-.

    +
  • +
  • +

    You are allowed to understate your performance; for instance, a flavor that satisfies +SCS-1C-1.5-8s (1 dedicated core, 1.5 GiB RAM, 8 GiB SSD) may also be named +SCS-1T-1-5n (1 dedicated hyperthread, 1 GiB RAM, 5 GiB network volume) or even +SCS-1V-1-5. Similarly, you may offer the (v3 mandatory) SCS-2V-4-20s with a SCS-2V-4-20p +implementation (using a local NVMe instead of an SSD).

    +
  • +
+

You must be very careful to expose low vCPU guarantees (L instead of V), insecure +hyperthreading/microcode i, non-ECC-RAM u, memory oversubscription o. Note that omitting these qualifiers +is overstating your security, reliability or performance properties and may be reason for +clients to feel betrayed or claim damages. This would prevent SCS compliance and certification; +in extreme cases, the SCS project might be forced to work with public statements.

+

We expect all cloud providers to offer the short, less specific flavor names (such as SCS-8V-32-100). +Larger providers that offer more details (using the extension below) are expected to still also +offer the short variants for usability and easier portability, even beyond the mandated flavors.

+

You must not extend the SCS naming scheme with your own extensions; you are encouraged however +to suggest extensions that we can discuss and add to the official scheme.

+

Extensions

+

Extensions provide a possibility for providers that offer a very differentiated set +of flavors to indicate hypervisors, support for hardware/nested virtualization, +CPU types and generations, high-frequency models, GPU support and GPU types as +well as Infiniband support. (More extensions may be appended in the future.)

+

Using the systematic naming approach ensures that two providers that offer flavors +with the same specific features will use the same name for them, thus simplifying +life for their customers when consuming these flavors.

+

Note that there is no need to indicate all details and extra features this way. +Flavors may always perform better or have more features than indicated in a name. +Underperformance (CPU suffixes L or i or memory suffixes o and u) on the other +hand MUST be indicated in the name; this happens rarely in practice.

+

For smaller providers, the ability to e.g. differentiate between an AMD Milan and an intel +IceLake and exposed the slightly different feature set to customers and have slightly +different price points is often not worth the extra effort. This is because having +this extra differentiation causes fragmentation of the machines (host aggregates) +that can offer these flavors, thus resulting in a lower utilization (as the capacity +management will need to have a certain amount of headroom per machine pool to avoid +running out of capacity).

+

Note that it is possible for providers to register both the generic short names and the +longer, more detailed names and allow them to use the same set of machines (host aggregates). +Note that machines (hypervisors) can be part of more than one host aggregate.

+

The extensions have the format:

+

[_hyp][_hwv][_arch[N][h]][_[G/g]X[N][-M][h]][_ib]

+

Extensions are individually optional, but the ones that are used must appear in the order +given in the above line.

+

Remember that letters are case-sensitive. +In case you wonder: Feature indicators are capitalized, modifiers are lower case. +(An exception is the uppercase _G for a pass-through GPU vs. lowercase _g for vGPU.)

+

[OPTIONAL] Hypervisor

+

Format: _hyp

+

The default Hypervisor is assumed to be KVM. Clouds that offer different hypervisors +or Bare Metal Systems should indicate the Hypervisor according to the following table:

+
hypMeaning
kvmKVM
xenXen
vmwVMware
hyvHyper-V
bmsBare Metal System
+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-4-10n_bms
  • +
  • SCS-2C-4-10n_bms_z3h
  • +
+

[OPTIONAL] Hardware virtualization / Nested virtualization

+

Format: _hwv

+

If the instances that are created with this flavor support hardware-accelerated +virtualization, this can be reflected with the _hwv flag (after the optional +Hypervisor flag). On x86, this means that in the instance, the CPU flag vmx (intel) +or svm (AMD) is available. This will be the case on Bare Metal flavors on almost +all non-ancient x86 CPUs or if your virtualization hypervisor is configured to +support nested virtualization. +Flavors without the _hwv flag may or may not support hardware virtualization (as we +recommend enabling nesting, but don't require flavor names to reflect all +capabilities. Flavors may over-deliver ...)

+

Examples

+
    +
  • SCS-2C-4-10 - may or may not support HW virtualization in VMs
  • +
  • SCS-2C-4-10_kvm_hwv - kvm with enabled nested virtualization
  • +
  • SCS-2C-4-10_hwv - not recommended, but allowed
  • +
  • SCS-2C-4-10_bms_hwv - better: bare metal with HW virt support (VMX on intel, SVM on AMD, ...)
  • +
  • SCS-2C-4-10_hwv_xen - illegal, wrong ordering
  • +
+

[OPTIONAL] CPU Architecture Details

+

Format: _arch[N][h]

+

This extension provides more details on the specific CPU:

+
    +
  • vendor/architecture (arch)
  • +
  • generation (N)
  • +
  • frequency (h)
  • +
+

Generation and Vendor

+

The options for arch are as follows:

+
Lettervendor/architectureCorresponding image architecture
(none)Generic x86-64x86_64
iIntel x86-64x86_64
zAMD (Zen) x86-64x86_64
aARM v8+aarch64
rRISC-V(not yet listed in Glance)
+

The generation is vendor specific and can be left out, but it can only be specified in +conjunction with a vendor. At present, these values are possible:

+
Generationi (Intel x86-64)z (AMD x86-64) a (AArch64)r (RISC-V)
0pre Skylakepre Zenpre Cortex A76TBD
1SkylakeZen-1 (Naples)A76/NeoN1 classTBD
2Cascade LakeZen-2 (Rome)A78/x1/NeoV1 classTBD
3Ice LakeZen-3 (Milan)A71x/NeoN2 (ARMv9)TBD
4Sapphire RapidsZen-4 (Genoa)TBD
+

It is recommended to leave out the 0 when specifying the old generation; this will +help the parser tool, which assumes 0 for an unspecified value and does leave it +out when generating the name for comparison. In other words: 0 has a meaning of +"rather old or unspecified".

+
note

We don't differentiate between Zen-4 (Genoa) and Zen-4c (Bergamo); L3 cache per +Siena core is smaller on Bergamo and the frequency lower but the cores are otherwise +identical. As we already have a qualifier h that allows to specify higher frequencies +(which Genoa thus may use more and Bergamo less or not), we have enough distinction +capabilities.

+

Frequency Suffixes

+
SuffixMeaning
h>2.75GHz all-core
hh>3.25GHz all-core
hhh>3.75GHz all-core
+

Examples

+
    +
  • SCS-2C-4-10n
  • +
  • SCS-2C-4-10n_z
  • +
  • SCS-2C-4-10n_z3
  • +
  • SCS-2C-4-10n_z3h
  • +
  • SCS-2C-4-10n_z3hh
  • +
  • SCS-2C-4-10n_bms_z
  • +
  • SCS-2C-4-10n_bms_z3
  • +
  • SCS-2C-4-10n_bms_z3
  • +
  • SCS-2C-4-10n_bms_z3h
  • +
  • SCS-2C-4-10n_bms_z3hh - Bare Metal, AMD Milan with > 3.25GHz all core freq
  • +
+

[OPTIONAL] GPU support

+

Format: _[G/g]X[N][-M][h]

+

This extension provides more details on the specific GPU:

+
    +
  • pass-through (G) vs. virtual GPU (g)
  • +
  • vendor (X)
  • +
  • generation (N)
  • +
  • number (M) of processing units that are exposed (for pass-through) or assigned; see table below for vendor-specific terminology
  • +
  • high-performance indicator (h)
  • +
+

Note that the vendor letter X is mandatory, generation and processing units are optional.

+
letter Xvendorprocessing units
NnVidiastreaming multiprocessors (SMs)
AAMDcompute units (CUs)
IIntelexecution units (EUs)
+

For nVidia, the generation N can be f=Fermi, k=Kepler, m=Maxwell, p=Pascal, v=Volta, t=turing, a=Ampere, l=Ada Lovelace, ..., +for AMD GCN-x=0.x, RDNA1=1, RDNA2=2, RDNA3=3, +for Intel Gen9=0.9, Xe(12.1)=1, ... +(Note: This may need further work to properly reflect what's out there.)

+

The optional h suffix to the compute unit count indicates high-performance (e.g. high freq or special +high bandwidth gfx memory such as HBM); +h can be duplicated for even higher performance.

+

Example: SCS-16V-64-500s_GNa-14h +This flavor has a pass-through GPU nVidia Ampere with 14 SMs and either high-bandwidth memory or specially high frequencies. +Looking through GPU specs you could guess it's 1/4 of an A30.

+

[OPTIONAL] Infiniband

+

Format: _ib

+

This extension indicates Infiniband networking.

+

More extensions may be forthcoming and appended in a later revision of this spec.

+

Extensions need to be specified in the above-mentioned order.

+

Naming options advice

+

Note that we expect most clouds to prefer short flavor names, +not indicating CPU details or hypervisor types. See above list +of standard flavors to get a feeling.

+

However, more successful providers will often need to differentiate their +offerings in response to customer demand and allow customers to request +flavors with specific detailed properties. The goal of this proposal is to avoid +providers to invent their own names and then refer customers to (currently +incompletely standardized) extra_specs +or worse a non-machine-readable service descriptions to find out the details.

+

So a cloud provider might well evolve from offering SCS-8T-16-50 to offering +SCS-8T-16-50n, SCS-8T-16-50n_i2 and SCS-8T-16-50n_z2 to specify that he +is using network disks and offer a choice b/w intel Cascade-Lake and AMD Rome. +We would expect the cloud provider to still offer the generic flavor +SCS-8T-16-50 and allow the scheduler (placement service) to pick both more +specific types (or just one if e.g. capacity management considerations suggest +so). Providers in such cases should ensure that the price of a requested +flavor does not depend on the scheduler decisions.

+

We are looking into the metadefs +mechanism and extra_specs +to allow customers to ask for specific flavor properties without the need to +encode all these flavor details into the flavor name, so the optional pieces +may not be needed much. However, there must be a way to request flavor +properties without encoding the need into an image — the indirection via +an image is considered broken by the SCS team.

+

Proposal Examples

+
ExampleDecoding
SCS-2C-4-10n2 dedicated cores (x86-64), 4GiB RAM, 10GB network disk
SCS-8Ti-32-50p_i18 dedicated hyperthreads (insecure), Skylake, 32GiB RAM, 50GB local NVMe
SCS-1L-1u-51 vCPU (heavily oversubscribed), 1GiB Ram (no ECC), 5GB disk (unspecific)
SCS-16T-64-200s_GNa-64_ib16 dedicated threads, 64GiB RAM, 200GB local SSD, Infiniband, 64 Passthrough nVidia Ampere SMs
SCS-4C-16-2x200p_a14 dedicated Arm64 cores (A76 class), 16GiB RAM, 2x200GB local NVMe drives
SCS-1V-0.51 vCPU, 0.5GiB RAM, no disk (boot from cinder volume)
+

Previous standard versions

+

Previous versions up to version 3.0 contained the list of +mandatory/recommended flavors, which has been moved to +a standard of its own.

+

Version 1 of the standard +used a slightly different naming syntax while the logic was exactly the same. +What is a - in v2 used to be a :; _ used to be -. The reason for +the change was certain Kubernetes tools using the flavor names as labels. +Labels however are subject to stricter naming rules and in particular don't +allow for a :. See PR #190 +for a discussion.

+

Version 1 flavor names can be translated to v2 using the following transformation:

+
NAMEV2=$(echo "$NAMEV1" | sed -e 's/\-/_/g' -e 's/:/-/g' -e 's/^SCS_/SCS-/')
+

and the way back can be done with

+
NAMEV1=$(echo "$NAMEV2" | sed -e 's/\-/:/g' -e 's/_/-/g' -e 's/^SCS:/SCS-/')
+

For the time being, the validation tools still accept the old names with a warning +(despite the unchanged SCS- prefix) unless you pass option -2 to them. They will +however not count v1 flavors towards fulfilling the needs against the corresponding +v2 mandatory flavor list unless you pass the option -1. +In other words: An IaaS infrastructure with the 26 +v1 mandatory flavors will produce 26 warnings (for using old flavors) and 26 +errors (for missing the 26 mandatory v2 flavors) unless you pass -1 in which +case no errors and no warnings will be produced. Registering the 26 mandatory +v2 flavor names in addition will result in passing the test with only 26 +warnings — unless you specify -2. If you do and want to pass you'll need +to remove the old v1 names or rename them to no longer start with SCS-.

+

Beyond SCS

+

The Gaia-X provider working group which could have created a superseding standard +does no longer exist.

+

However, we have been reaching out to the OpenStack Public Cloud SIG and the ALASCA +members to seek further alignment.

+

Getting upstream OpenStack support for flavor aliases would provide more flexibility +and ease migrations between providers, also providers that don't offer the SCS- +flavors.

+

We also would like to see upstream extra_specs standardizing the discoverability of some +properties exposed via the SCS names and work on IaC tooling (terraform ...) +to make use of these when selecting a flavor.

+ + \ No newline at end of file diff --git a/standards/scs-0100-w1-flavor-naming-implementation-testing/index.html b/standards/scs-0100-w1-flavor-naming-implementation-testing/index.html new file mode 100644 index 0000000000..4f94e3e8e4 --- /dev/null +++ b/standards/scs-0100-w1-flavor-naming-implementation-testing/index.html @@ -0,0 +1,66 @@ + + + + + +SCS Flavor Naming Standard: Implementation and Testing Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Flavor Naming Standard: Implementation and Testing Notes

Introduction

+

The three major versions of the standard that exist so far are very similar, and deliberately so. +Therefore, the procedures needed to implement or test them are very similar as well. Yet, this document +will only cover v3, because v1 and v2 are already obsolete by the time of writing.

+

Implementation Notes

+

Every flavor whose name starts with SCS- must conform with the naming scheme laid down in the standard.

+

Operational Tooling

+

Syntax Check

+

The test suite +comes with a handy +command-line utility +that can be used to validate flavor names, to +interactively construct a flavor name via a questionnaire, and to generate prose descriptions for given +flavor names. See the +README +for more details.

+

The functionality of this script is also (partially) exposed via the web page +https://flavors.scs.community/.

+

With the OpenStack tooling (python3-openstackclient, OS_CLOUD) in place, you can call +cli.py -v parse v3 $(openstack flavor list -f value -c Name) to get a report +on the syntax compliance of the flavor names of the cloud environment.

+

Flavor Creation

+

The OpenStack Flavor Manager will create a whole set +of flavors in one go, given a YAML description of this set.

+

Automated Tests

+

Errors

+

The following items MUST be detected and reported as an error:

+
    +
  • any syntax error in a name starting with SCS-,
  • +
  • any mismatch between any immediately discoverable property of a flavor (currently, CPU, RAM and disk size) +and the meaning of its name (which is usually a lower bound), such as the CPU generation or hypervisor.
  • +
+

In addition, the following items MAY be reported as an error:

+
    +
  • any mismatch between any non-immediately discoverable property of flavor and the meaning of its name.
  • +
+

Warnings

+

None so far.

+

Implementation

+

The script flavor-names-openstack.py +talks to the OpenStack API of the cloud specified by the OS_CLOUD environment and queries properties and +checks the names for standards compliance.

+

Manual Tests

+

To be determined.

+ + \ No newline at end of file diff --git a/standards/scs-0101-v1-entropy/index.html b/standards/scs-0101-v1-entropy/index.html new file mode 100644 index 0000000000..a36add74f3 --- /dev/null +++ b/standards/scs-0101-v1-entropy/index.html @@ -0,0 +1,114 @@ + + + + + +SCS Entropy | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Entropy

Introduction

+

Entropy in information technology

+

Entropy is a concept that is widely used in the scope of information +technology. It is a measurement of the amount of disorder or randomness in +a system. Entropy is used to measure the amount of information in a +self-contained system, as well as the amount of incertitude that exists in this +system.

+

Real-world uses of entropy

+

Cryptography is a very prominent, albeit not the only application that +heavily relies on entropy for operations such as creating secure keys. +When the available entropy runs out, said operations can stall and +take an abnormally long amount of time, which in turn can lead to +malfunctions, e.g., with OpenSSL or load balancers.

+

Sources of entropy

+

In traditional baremetal systems the amount of incertitude is sourced +from the randomness of the read/write cycles of the disk heads of a disk drive, +bus timings, or keyboard timings, to name a few.

+

More recent methods of generating entropy include measuring IRQ jitter +(available in Linux since kernel 5.4 or, before that, via a daemon such as +HavegeD) as well as dedicated CPU +instructions (available in virtually all major CPUs: RDSEED or RDRAND +on x86_64 and RNDR on arm64).

+

Finally, a dedicated device can be utilized — if present — that is +called hardware random number generator or HRNG for short. For instance, +the Trusted Platform Module +includes a HRNG. On Linux systems, the HRNG appears as /dev/hwrng. +Note that, while the dedicated CPU instructions can be construed as +a HRNG, they are not treated as such by the kernel, i.e., they do not +appear as /dev/hwrng!

+

The Linux kernel combines multiple sources of entropy into a pool. To this +end, it will use all of the sources discussed so far with one exception: +the HRNG must be fed into the pool (if so desired) via the daemon rngd. +The kernel converts the entropy from the pool into cryptographically +secure random numbers that appear under /dev/random and /dev/urandom.

+

With kernel 5.18, the algorithm that accomplishes +said conversion has been drastically improved (see +linux-rng-5.17-18), +so much so that running out of entropy is virtually ruled out. +These patches have now also arrived in the upstream LTS images.

+

Entropy in virtual instances

+

Virtual instances or virtual machines do not have the traditional sources +of entropy mentioned above. However, the more recent methods mentioned +above do work just fine (the CPU instructions are not privileged).

+

Alternatively, a virtualized HRNG called virtio-rng can be established +that injects entropy from the host into the instance, where this +entropy can be sourced optionally from either the host's /dev/random or +some HRNG in the host. This virtualized HRNG behaves just like a real +one, that is, it appears as /dev/hwrng, and the daemon rngd must +be used to feed it into the kernel's entropy pool.

+

On a side note, the kernel exposes available HRNGs via the special +directory /sys/devices/virtual/misc/hw_random. In particular, the +file rng_available lists availabe HRNGs while the file rng_current +contains the HRNG currently used.

+

In summary, with current kernels and CPUs entropy in virtual instances +is readily available to a sufficient degree. In addition, the host's +entropy sources can be injected using virtio-rng if so desired, e.g., +to enable access to a HRNG.

+

Motivation

+

As stated above, good sources of entropy are paramount for many +important applications. This standard ensures that sufficient entropy +will be available in virtual instances.

+

Entropy in SCS clouds

+

Flavors

+

It is recommended that all flavors have the following attribute:

+
hw_rng:allowed=True
+

The following attributes are optional:

+
hw_rng:rate_bytes - The allowed amount of bytes for the the guest
to read from the host's entropy per period.
hw_rng:rate_period - Sets the duration of a read period in seconds.
+

Images

+

It is recommended to use images having a kernel (patch level) version 5.18 +or up. This condition is already satisfied by every mandatory image defined +in the Image Metadata Standard.

+

It is recommended that images activate the attribute hw_rng_model: virtio.

+

The daemon rngd must be installed (usually from rng-tools +or rng-utils).

+

The user may choose to use the virtio-rng device via rngd.

+

Compute nodes

+

Compute nodes must use CPUs that offer instructions for accessing +entropy (such as RDSEED or RDRAND on x86_64 or RNDR on arm64), and +these instructions may not be filtered by the hypervisor.

+

Compute nodes may provide a HRNG via rngd.

+ + \ No newline at end of file diff --git a/standards/scs-0101-w1-entropy-implementation-testing/index.html b/standards/scs-0101-w1-entropy-implementation-testing/index.html new file mode 100644 index 0000000000..843c750098 --- /dev/null +++ b/standards/scs-0101-w1-entropy-implementation-testing/index.html @@ -0,0 +1,66 @@ + + + + + +SCS Entropy: Implementation and Testing Notes | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Entropy: Implementation and Testing Notes

Implementation

+

We presume that almost nothing has to be done (or indeed can be done), as +long as the CPUs and VM images are reasonably recent; only the flavor and +image attributes have to be set:

+
    +
  • flavor: hw_rng:allowed=True ,
  • +
  • image: hw_rng_model: virtio .
  • +
+

Automated Tests

+

Images Sample

+

Some checks need to be performed on a live instance. For these checks, it is +necessary to choose a sample of VM images to test on.

+

For the time being, the sample MUST contain at least one public image reported +by OpenStack. This may be extended in the future.

+

Errors

+

For every image in the chosen sample, the following items MUST be detected and +reported as an error:

+
    +
  • the service rngd is not running,
  • +
  • the special file /proc/sys/kernel/random/entropy_avail does not contain +the value 256 (pinned since kernel 5.18),
  • +
  • the number of FIPS 140-2 failures exceeds 3 out of 1000 blocks +tested, as determined by cat /dev/random | rngtest -c 1000 .
  • +
+

Note: The latter two items act as surrogates for the following item, which +cannot be detected directly:

+
    +
  • CPU instructions for accessing entropy are not available to the VMs.
  • +
+

Warnings

+

The following items MUST be detected and reported as a warning:

+
    +
  • any flavor missing the attribute hw_rng:allowed=True,
  • +
  • any image missing the attribute hw_rng_model: virtio,
  • +
+

Note that the requirement regarding the kernel patch level will not be +checked, because of two reasons: (a) we already check the file entropy_avail +(see subsection on Errors), and (b) users can always choose a recent image, +as ensured by the image metadata standard.

+

Implementation

+

The script entropy-check.py +connects to OpenStack and performs the checks described in this section.

+

Manual Tests

+

None.

+ + \ No newline at end of file diff --git a/standards/scs-0102-v1-image-metadata/index.html b/standards/scs-0102-v1-image-metadata/index.html new file mode 100644 index 0000000000..4e5ecdc19f --- /dev/null +++ b/standards/scs-0102-v1-image-metadata/index.html @@ -0,0 +1,218 @@ + + + + + +SCS Image Metadata Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Image Metadata Standard

Motivation

+

Many clouds offer standard Operating System images for their users' convenience. +To make them really useful, they should contain meta data (properties) to allow +users to understand what they can expect using these images.

+

The specification is targeting images that are managed by the service provider, +provided for public consumption. The spec or parts of it however might turn out +to be useful whenever someone manages images for somebody else's consumption.

+

Overview

+

We categorize the image properties into a few buckets

+
    +
  • Technical requirements and features
  • +
  • Image handling aspects
  • +
  • Licensing/Maintenance/Support aspects
  • +
+

Naming

+

We suggest plain OS images to be named "Distribution Version", +e.g. "openSUSE Leap 15.3" or "Ubuntu 20.04" or "CentOS 8", "Windows Server 2012R2". +We do not normally recommend to add more detailed patch levels into the name.

+

Special variants that include specific non-standard features should be named +"Distribution Version Feature1 Feature2".

+

There are several policies possible to provide updated images to include the latest +bug- and security fixes. This is outlined in update policy description below.

+

Technical requirements and features

+

This is dependent on whether we deal with VM images or container images.

+

For VM images (OpenStack), we recommend to use the properties as described +in the OpenStack Image documentation.

+

The following properties are considered mandatory:

+
    +
  • architecture, hypervisor_type
  • +
  • min_disk_size (in GiB), min_ram (in MiB)
  • +
  • os_version, os_distro
  • +
  • hw_rng_model, hw_disk_bus (scsi recommended, and then setting hw_scsi_model is also recommended)
  • +
+

Note: Disk sizes tend to be measured in GB = 10^9 and not GiB = 2^30 in the disk industry, but OpenStack uses GiB.

+

The following properties are recommended (if the features are supported):

+
    +
  • os_secure_boot, hw_firmware_type
  • +
  • hw_watchdog_action, hw_mem_encryption, hw_pmu, hw_video_ram, hw_vif_multiqueue_enabled
  • +
+

The trait:XXX=required property can be used to indicate that certain virtual hardware +features XXX are required.

+

Image handling

+

Image updating

+

It is recommended that provider managed images are regularly updated. +This means that users referencing an image by name will always get the latest image for the +operating system indicated by that name (which includes a version number, but not the patch +level).

+

Technically, the thus updated image is a new image and will thus carry a new UUID. +It is recommended that the old image gets renamed (e.g. build date or patch level attached) +and hidden (os_hidden=true), but remains accessible via its (unchanged) UUID for some +time.

+

The update handling by the provider is described via the properties replace_frequency, +uuid_validity, provided_until, and hotfix_hours.

+

The replace_frequency, provided_until, and hotfix_hours fields reference to the image +as referenced by its name.

+
replace_frequencymeaning
yearlythe image will get replaced at least once per year
quarterlythe image will get replaced at least once per quarter
monthlythe image will get replaced at least once per month
weeklythe image will get replaced at least once per week
dailythe image will get replaced at least once per day
critical_bugthe image will get replaced for critical issues only
neverthe image referenced by name will never change (until the date provided_until)
+

Note the at least wording: Providers can replace images more often. +The frequency is starting from the first release; so an image published on 2021-04-14 with an +update frequency of monthly, should be replaced no later than 2021-05-14. Due to weekends +etc., up to 3 days later is not considered a violation of this policy. So a valid sequence +from an image with monthly update frequency might be 2021-04-14, 2021-05-14, 2021-06-15, +2021-07-14, 2021-07-27 (hotfix), 2021-08-13 ...

+

Promises to update the registered public images typically depend on upstream image providers +(Linux distributors, OS vendors) keeping their promises to build and provide updated images. +Failures from upstream are not a reason to claim the cloud provider to be in violation of his +promises. However, if the provider observes massive upstream failures (which can e.g. cause +increased security risks), we advise the provider to inform the users.

+

We recommend updating images at least monthly.

+

The hotfix_hours field indicates how providers deal with critical security issues +that affect the images; it is an optional field that contains a numerical value, indicating +how quickly (in hours) a new image is provided after the latter of the points in time that +the issue becomes public and a tested fix is available as maintenance update from the upstream +distribution. A value of 0 indicates a best-effort approach without firm SLAs; the field not +being present indicates no commitment. A value of 48 would indicate that the provider +commits to a new image within 48hrs. A critical issue is defined as a security vulnerability +with a CVSS score of 9.0 or higher that affects a package that is included in the image.

+

The provided_until field is supposed to contain a date in YYYY-MM-DD format that +indicates until when an image under this name will be provided and (according to the +replace_frequency) updated at least. (Providers are free to provide updates for +longer or leave the non-updated image visible for longer.) +If this field is set to none, no promises are made, if it is set to notice, updates +will be provided until a deprecation notice is published. (The values are the same as +for below uuid_validity, except that forever and last-N don't make any sense.)

+

The uuid_validity field indicates how long the public image will be referencable +by its UUID.

+
uuid_validitymeaning
noneUUID will only be valid as long as the content does not change
last-NThe last N images for newer replacement will remain accessible via UUID
YYYY-MM-DDUUID will be valid until at least the date YYYY-MM-DD
noticeUUID will remain valid until a deprecation notice will be published
foreverUUID will remain valid for as long as the cloud operates
+

Note that the old images must be hidden from the image catalogue or renamed (or both) +to avoid failing referencing by name. Note that last-N may be limited by the provided_until +date.

+

The three properties uuid_validity, provided_until and replace_frequency are mandatory; +the field hotfix_hours is optional.

+

All dates are in UTC.

+

Example

+

Providing an image with name OPSYS MAJ.MIN with +replace_frequency=monthly, provided_until=2022-09-30, uuid_validity=2022-12-31, +hotfix_hours=0 +means that we will have a new image with this name at least once per month (starting from +the initial release) until the end of September 2022. Old images will be hidden and/or +renamed, but remain accessible via their UUID until at least the end of 2022 (in Universal Time). +The provider makes an effort to replace images upon critical security issues out of order.

+

Image Origin

+
    +
  • +

    Mandatory: image_source needs to be a URL to point to a place from which the image can be downloaded. +(Note: This may be set to the string "private" to indicate that the image can not be freely +downloaded.)

    +
  • +
  • +

    Mandatory: image_description needs to be an URL (or text) with release notes and other human readable +data about the image.

    +
  • +
  • +

    Recommended tag: managed_by_VENDOR

    +
  • +
+

Note that for most images that come straight from an upstream source, image_description should point +to a an upstream web page where these images are described. If download links are available as well +on that page, image_source can point to the same page, otherwise a more direct link to the image +should be used, e.g. directly linking the .qcow2 or .img file. +If providers have their own image building machinery or do some post-processing on top of +upstream images, they should point to the place where they document and offer these images.

+

Image build info

+
    +
  • +

    Mandatory: image_build_date needs to be YYYY-MM-DD or YYYY-MM-DD hh:mm[:ss] (time in UTC, +24hrs clock). +All publicly released and generally recommended patches before this date must be included in the +image build. If the cutoff date is earlier, this cutoff date needs to be set instead, even +if the actual build happens significantly after the cutoff date. If not all patches can be +included for a good reason, then the patchlevel field (see below) must be used to describe +the patch status.

    +
  • +
  • +

    Mandatory: image_original_user is the default login user for the operating system which can connect +to the image via the injected SSH key or provided password. (This can be set to none if no default +user name exists for the operating system.)

    +
  • +
  • +

    Optional: patchlevel can be set to an operating specific patch level that describes the +patch status — typically we would expect the image_build_date to be sufficient.

    +
  • +
  • +

    Recommended: os_hash_algo and os_hash_value: The sha256 or sha512 hash +for the image file. (This references the image file in the format it is stored in, we +recommend raw over qcow2 for systems that use ceph.) Note that these values are +typically generated automatically upon image registration.

    +
  • +
  • +

    Recommended tag: os:OPERATINGSYSTEM

    +
  • +
+

Licensing / Maintenance subscription / Support

+

Some images require a license; in many cases the cloud providers include the license cost +by a per-use (e.g. hourly) fee. However, it is also possible sometimes that customers +use their own license agreements with the OS vendor with a bring-your-own-license (BYOL) +program. These properties may be attached to the image. Note that free Linux images +might not use any of these properties, except maybe maintained_until. Note that +Windows images would typically require license_included, subscription_included. +A boolean property that is not present is considered to be false.

+
    +
  • Optional: license_included (boolean) indicates whether or not the flavor fee +includes the licenses required to use this image. This field is mandatory for +images that contain software that requires commercial licenses.
  • +
  • Optional: license_required (boolean) indicates whether or not a customer must bring +its own license to be license compliant. This can not be true at the same time as the +previous setting. This field is mandatory IF customers need to bring their own +license to use the image.
  • +
  • Optional: subscription_included (boolean) indicates that the image contains already +a maintenance subscription which typically gives access to bug fixes, security +fixes and (minor) function updates. If a subscription is included, the CSP should +have prepared the image to also receive the provided maintenance updates from the +vendor (optionally via a mirror).
  • +
  • Optional: subscription_required (boolean) indicates that the customer requires +a maintenance subscription from the OS vendor in order to receive fixes +(which is often also a prerequisite to be eligible for support).
  • +
  • Optional: maintained_until: YYYY-MM-DD promises maintenance from the OS vendor +until at least this date (in UTC).
  • +
  • Optional: l1_support_contact contains a URI that provides customer support +contact for issues with this image. Note that this field must only be set if the +service provider does provide support for this image included in the image/flavor +pricing (but it might be provided by a contracted 3rd party, e.g. the OS vendor).
  • +
+

Conformance Tests

+

The script image-md-check.py retrieves the +image list from a configured cloud and checks each image for the +completeness and consistency of mandatory properties.

+ + \ No newline at end of file diff --git a/standards/scs-0103-v1-standard-flavors/index.html b/standards/scs-0103-v1-standard-flavors/index.html new file mode 100644 index 0000000000..cd64454468 --- /dev/null +++ b/standards/scs-0103-v1-standard-flavors/index.html @@ -0,0 +1,121 @@ + + + + + +SCS Standard Flavors and Properties | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Standard Flavors and Properties

Introduction

+

Motivation

+

In OpenStack environments there is a need to define different flavors for instances. +The flavors are pre-defined by the operator, the customer can not change these. +OpenStack providers thus typically offer a large selection of flavors.

+

While flavors can be discovered (openstack flavor list), it is helpful for users (DevOps teams), +to have a guaranteed set of flavors available on all SCS clouds, so these need not be discovered.

+

Properties (extra specs)

+

The following extra specs are recognized, together with the respective semantics:

+
    +
  • scs:name-vN=NAME (where N is 1 or 2, and NAME is some string) means that the +flavor is one of the +standard SCS flavors, and the requirements of Section "Standard SCS flavors" below apply.
  • +
  • scs:cpu-type=shared-core means that at least 20% of a core in >99% of the time, +measured over the course of one month (1% is 7,2 h/month). The cpu-type=shared-core +corresponds to the V cpu modifier in the flavor-naming spec, +other options are crowded-core (L), dedicated-thread (T) and dedicated-core (C).
  • +
  • scs:diskN-type=ssd (where N is a nonnegative integer, usually 0) means that the +root disk N must support 1000 sequential IOPS per VM and it must be equipped with +power-loss protection; see scs-0110-v1-ssd-flavors. +The diskN-type=ssd setting corresponds to the s disk modifier, other options +are nvme (p), hdd (h) and network (n). Only flavors without disk and +those with diskN-type=network can be expected to support live-migration.
  • +
+

Whenever ANY of these are present on ANY flavor, the corresponding semantics must be satisfied.

+

Standard SCS flavors

+

Following are flavors that must exist on standard SCS clouds (x86-64). +Note that this statement does not preclude the existence of additional flavors.

+

Mandatory

+
Recommended namevCPUsvCPU typeRAM [GiB]Root disk [GB]Disk type
SCS-1V-41shared-core4
SCS-2V-82shared-core8
SCS-4V-164shared-core16
SCS-4V-16-100s4shared-core16100ssd
SCS-8V-328shared-core32
SCS-1V-21shared-core2
SCS-2V-42shared-core4
SCS-2V-4-20s2shared-core420ssd
SCS-4V-84shared-core8
SCS-8V-168shared-core16
SCS-16V-3216shared-core32
SCS-1V-81shared-core8
SCS-2V-162shared-core16
SCS-4V-324shared-core32
SCS-1L-11crowded-core1
+ +
Recommended namevCPUsvCPU typeRAM [GiB]Root disk [GB]Disk type
SCS-1V-4-101shared-core410(any)
SCS-2V-8-202shared-core820(any)
SCS-4V-16-504shared-core1650(any)
SCS-8V-32-1008shared-core32100(any)
SCS-1V-2-51shared-core25(any)
SCS-2V-4-102shared-core410(any)
SCS-4V-8-204shared-core820(any)
SCS-8V-16-508shared-core1650(any)
SCS-16V-32-10016shared-core32100(any)
SCS-1V-8-201shared-core820(any)
SCS-2V-16-502shared-core1650(any)
SCS-4V-32-1004shared-core32100(any)
SCS-1L-1-51crowded-core15(any)
+

Guarantees and properties

+

The figures given in the table (number of CPUs, amount of RAM, root disk size) must match +precisely the corresponding figures in the flavor.

+

In addition, the following properties must be set (in the extra_specs):

+
    +
  • scs:name-v1 to the recommended name, but with each dash AFTER the first one replaced by a colon,
  • +
  • scs:name-v2 to the recommended name,
  • +
  • scs:cpu-type to shared-core or crowded-core, reflecting the vCPU type,
  • +
  • scs:disk0-type not set if no disk is provided, otherwise set to ssd or some other +value, reflecting the disk type.
  • +
+

Remarks

+

We expect the most used vCPU

GiB
ratio to be 1:4.

+

Note that all vCPUs of SCS standard flavors are oversubscribed — the smallest 1L-1 +flavor allows for heavy oversubscription (note the L), and thus can be offered very +cheaply — imagine jump hosts ...

+

The design allows for small clouds (with CPUs with 16 Threads, 64GiB RAM +compute hosts) to offer all flavors.

+

Except for the two flavors with SSD root volume, disks types are not specified +(and expected to be network disks (Ceph/Cinder) or local SATA/SAS disks typically).

+

We only included a limited variation of disk sizes — this reflects that +for the standard networked cinder +disks, you can pass block_device_mapping_v2 on server (VM) creation to +allocate a boot disk of any size you desire. We have scaled the few +recommended disk sizes with the amount of RAM. For each flavor there is +also one without a pre-attached disk — these are meant to be used +to boot from a volume (either created beforehand or allocated on-the-fly +with block_device_mapping_v2, e.g. +openstack server create --flavor SCS-1V-2 --block-device-mapping sda=IMGUUID:image:12:true +to create a bootable 12G cinder volume from image IMGUUID that gets tied to the VM +instance life cycle.)

+

Conformance Tests

+

The script flavors-openstack.py will read the lists of mandatory and recommended flavors +from a yaml file provided as command-line argument, connect to an OpenStack installation, +and check whether the flavors are present and their extra specs are correct. Missing +flavors will be reported on various logging channels: error for mandatory, info for +recommended flavors. Incorrect extra specs will be reported as error in any case. +The return code will be non-zero if the test could not be performed or if any error was +reported.

+

Operational tooling

+

The openstack-flavor-manager is able to +create all standard, mandatory SCS flavors for you. It takes input that can be generated by +flavor-manager-input.py.

+

Previous standard versions

+

The list of standard flavors used to be part of the flavor naming standard up until +version 3. The following changes have been made to +the list in comparison with said standard:

+
    +
  • the flavor names have been turned into recommendations, and
  • +
  • the properties have been introduced in order to help discoverability.
  • +
+

Note that the flavors with fixed size root disks have all moved to Recommended +with scs-0100-v3. +This means that they are not a certification requirement any longer, +but we still recommend implementing these for backwards compatibility reasons. +Also in that standard, two flavors with SSD+ root disks have been added, as defined in +scs-0110-v1-ssd-flavors.md

+ + \ No newline at end of file diff --git a/standards/scs-0104-v1-standard-images/index.html b/standards/scs-0104-v1-standard-images/index.html new file mode 100644 index 0000000000..d10d85a9a9 --- /dev/null +++ b/standards/scs-0104-v1-standard-images/index.html @@ -0,0 +1,99 @@ + + + + + +SCS Standard Images | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Standard Images

Introduction

+

The Sovereign Cloud Stack (SCS) provides standards for a range of cloud infrastructure types. +It strives for interoperable and sovereign cloud offerings which can be deployed and used by a wide range of organizations and individuals.

+

To this end, SCS unifies the naming and sourcing of virtual machine images, and for certain images their presence is mandated or recommended.

+

Motivation

+

Following the example of the SCS standards YAML, +this standard establishes, by means of a YAML file, a mechanism with the following main objectives:

+
    +
  • to maintain a list of mandatory, recommended, and optional images, which also fixes the source location,
  • +
  • to provide a machine-readable document for further processing (e.g. for a compliance tool suite or continuous integration).
  • +
+

Uploading custom images

+

Image upload via Glance MUST be allowed based on a fair-use policy.

+

Standard images YAML

+

The YAML file MUST contain the key images, whose value is a list of objects. Each object has one of two forms, as described below.

+

Image specification, single image

+
KeyTypeDescriptionExample
nameStringName of the image"Debian 12"
statusStringoptional: either mandatory or recommended"recommended"
sourceStringPrefix of the source URL"https://cloud.debian.org/images/cloud/bookworm/"
OR: List of stringsmultiple possible prefixes(see full example below)
+

The meaning of this specification is as follows.

+
    +
  1. If the status is mandatory, then the image MUST be present.
  2. +
  3. If an image by the name given is present, then its image_source property +(as described in the Image Metadata standard) +MUST start with one of the prefixes given via source.
  4. +
+

Image specification, class of images

+
KeyTypeDescriptionExample
nameStringName of the class of images"ubuntu-2204-kube"
name_schemeString (regex)Regular expression for the image name"ubuntu-2204-kube-v[0-9].[0-9]+(.[0-9]+)?"
statusStringoptional: either mandatory or recommended"recommended"
sourceStringPrefix of the source URL"https://swift.services.a.regiocloud.tech"
OR: List of stringsmultiple possible prefixes(see full example below)
+

The meaning of this specification is as follows:

+
    +
  1. If the status is mandatory, then at least one image MUST be present whose name +matches the regular expression given via name_scheme.
  2. +
  3. For any image whose name matches the regular expression given via name_scheme, +its image_source property MUST start with one of the prefixes given via source.
  4. +
+

Full example

+
images:
- name: "Ubuntu 22.04"
source:
- https://cloud-images.ubuntu.com/releases/jammy/
- https://cloud-images.ubuntu.com/jammy/
status: mandatory
- name: "ubuntu-capi-image"
name_scheme: "ubuntu-capi-image-v[0-9].[0-9]+(.[0-9]+)?"
source: https://swift.services.a.regiocloud.tech/swift/v1/AUTH_b182637428444b9aa302bb8d5a5a418c/openstack-k8s-capi-images/ubuntu-2204-kube
status: recommended
- name: "Ubuntu 20.04"
source:
- https://cloud-images.ubuntu.com/releases/focal/
- https://cloud-images.ubuntu.com/focal/
- name: "Debian 12"
source:
- https://cloud.debian.org/images/cloud/bookworm/
- https://cdimage.debian.org/cdimage/cloud/bookworm/
- name: "Debian 11"
source:
- https://cloud.debian.org/images/cloud/bullseye/
- https://cdimage.debian.org/cdimage/cloud/bullseye/
+

This example provides allowable source prefixes for two Debian versions, two Ubuntu +versions, and for any version of the Kubernetes cloud API provider. Only the latter is +recommended, while only Ubuntu 22.04 is mandatory.

+

Lifecycle considerations

+

YAML lifecycle

+

The YAML file is generally located under +https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/.

+

Any change that could render existing installations non-conformant (i.e., when new +specifications are added, when the name scheme of a specification is changed so as to +match more names than before, when the status of an existing specification changes to +mandatory, or when some source prefix is removed) requires a new YAML file to be created. +As a consequence, any currently valid certificates stay valid; the change can only take +effect in a new version of the certificate in question, if so desired.

+

Image lifecycle

+

It is important to note that this standard does not prohibit any images, and neither +does it preclude the operator from providing any and all optional images.

+

It is possible that a specification is mandatory in one version and non-mandatory in the +next version. This standard makes no statement as to what is supposed to happen to the +corresponding images in a live cloud environment. It is recommended to keep the +once-mandatory images in the live environment. As for new environments, it is up to the +operator whether to provide any or all of these images, as stated above.

+

Conformance Tests

+

The script images-openstack.py will read the lists of mandatory and recommended images +from a yaml file provided as command-line argument, connect to an OpenStack installation, +and check whether the images are present. Missing images will be reported on various +logging channels: error for mandatory, info for recommended images. Additionally, images +whose image_source does not conform with the specifications will be reported on the +error channel. The return code will be non-zero if the test could not be performed or +if any errors have been reported.

+

Operational tooling

+

The openstack-image-manager is able to +create all standard, mandatory SCS images for you given image definitions from a YAML file.

+ + \ No newline at end of file diff --git a/standards/scs-0110-v1-ssd-flavors/index.html b/standards/scs-0110-v1-ssd-flavors/index.html new file mode 100644 index 0000000000..070567ac1c --- /dev/null +++ b/standards/scs-0110-v1-ssd-flavors/index.html @@ -0,0 +1,226 @@ + + + + + +SSD Flavors | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SSD Flavors

Introduction

+

SCS defines an IaaS Flavor Naming standard that mandates a number of standard flavors +to be available in each SCS-compliant IaaS offering. While offering or exposing +IaaS is not a requirement for SCS-compliant infrastructure offerings — SCS allows +for platforms only exposing the container layer (plus S3 compatible object storage) +for wave 2 (container-based) cloud-native workloads -- +the SCS reference implementation does include a complete IaaS implementation that +many providers want to expose as they have customers desiring access at this layer +for wave 1 (VM-based) cloud-native workloads or for the virtualization of more +classical (not cloud-native) workloads. The IaaS implementation thus comes with +standards.

+

This Decision Record is about adding a few mandatory flavors on the IaaS level +that include flavors with local SSD (or better) storage.

+

Motivation

+

The currently defined standard flavors +do not include +flavors that use local storage. For certain workloads such as databases or big data +filesystems, local storage is highly desirable as replication may be handled at +the application layer, making replication/redundancy in a networked storage solution +(ceph in the SCS reference implementation) an unneeded and undesired property. +Furthermore, write access to networked and replicated storage typically incurs +a certain latency, as the writes can only be acknowledged once all the replicas +have confirmed that the data has hit stable storage. Write latency is critical +for e.g. relational database performance.

+

The main purpose for the IaaS layer in SCS is to perform as a solid foundation +to provide and manage kubernetes container clusters in a multi-tenant scenario. +As such the standards at the IaaS layer should ensure that all the needed +types of resources are available for the container clusters. This is not +currently the case: In a scenario with multiple k8s control-plane nodes set +up via kubeadm (as part of the k8s cluster-api automation), the control plane +nodes each run an etcd instance and together form an etcd cluster.

+

etcd is sensitive to scheduling, network and storage latencies. While network +latencies and scheduling latencies have not been observed to be an issue in +clusters within one cloud region, the storage latency is. With remote networked +storage as delivered from ceph, the long tail of write latency causes etcd +to often time out heartbeats, causing a new leader election with a leader +change, preventing control plane changes on k8s for a few seconds. Too many +leader changes can slow down cluster operation and even bring it to a halt.

+

The etcd requirements are well documented. +In particular, over a hundred of sequential IOPS are recommended. This +requires write latencies in the range of a single-digit ms (or better).

+

Design Considerations

+

Options considered

+

One-node etcd (backed by redundant storage)

+

If k8s uses only one control plane node, there will only be only one etcd node, +avoiding timed out heartbeats. Single node control planes are typically not +recommended for production workloads though. They are limited with respect +to control plane performance, have a higher chance to fail (as a single node failure +can create cluster control-plane downtime) and can not undergo rolling upgrades.

+

Though not the normal setup with kubeadm, it is possible to use a multi-node +control plane using a single-node etcd. This shares some of the challenges of +single-node control-planes, although recovery may be faster to perform at least +in scenarios where the etcd backend storage is redundant and not affected by the +single-node outage.

+

Neither scenario fulfills typical requirements for production workloads.

+

RAM (tmpfs) etcd storage

+

etcd could keep its database in volatile memory (e.g. on a tmpfs filesystem). +For multi-node etcd clusters, this could actually be made work, as long as at +least one cluster member stays alive and proper care is taken to remove shut-down +nodes from the cluster. A loss of power affecting all nodes or a hardware +maintenance operation not tracking etcd needs would result in a complete +loss of all cluster state. The control plane nodes would require live migration +to avoid this in the maintenance case. For the power loss scenario, a frequent +backup might mitigate the cluster state loss case somewhat.

+

The etcd database is normally limited to 2GiB in size, which is something +that is realistic to keep in main memory. (Typical database sizes are +much smaller.)

+

This option requires additional care and may not be suitable for all +production scenarios, but would seem a possible fallback position for +etcd. It does obviously not address the database scenario.

+

Heartbeat slowdown

+

To avoid causing too many fail-overs by occasional high latencies, the +frequency of heartbeats can be lowered from the default 1/100ms. +The reelection timeout should change along with it (typically set to +10 beats).

+

This will cause etcd to take a bit more time to notice the loss of a node, +which is not typically critical if done within reasonable limits. +This change however does not fully address the issue — occasional write latencies +above 100ms will still cause failed heartbeats, just less often.

+

This change has been implemented in SCS's +k8s-cluster-api-provider +reference implementation: The heartbeat has been changed from 1/100ms (10/s) +to 1/250ms (4/s) and the reelection timeout from 1s to 2.5s.

+

The etcd process also is afforded a higher CPU priority (lower niceness), +resulting in a lower scheduling latency, as high-prio processes preempt lower-prio +ones when they get woken up. The etcd process also gets its IO priority +increased to get treated preferentially in case the IO scheduler has many +outstanding requests. This has some positive effects with the CFQ IO scheduler.

+

The slower heartbeat and the priority tweaks do lower the amount of leader +changes but are insufficient to completely address the issue on the tests +performed against networked ceph-backed storage.

+

Filesystem tuning

+

Databases must ensure that certain data has hit stable storage before acknowledging +writes — this is required in order to live up to the ACID +guarantees in situations when disruptions might happen. Databases typically use +fsync() calls to ensure that write buffers are written to real persistent storage +unless they use raw/direct block devices circumventing Linux's page and buffer cache.

+

etcd normally uses a write-ahead-log (WOL) file that lives on a Linux filesystem and +uses fsync to ensure the correct write ordering. Trouble with fsync is that it +also causes unrelated data to be written out with most existing Linux filesystems, +adding to the latency.

+

It is possible to tell the Linux filesystems to not wait for all data to have hit +storage before returning from fsync() calls. This avoids the latency caused by +fsync but also subverts the very reason for using fsync: In case of a disruption +(OS crash, power outage, loss of connection to storage, ...), the state is likely +not consistent, as the kernel has lied to the application about data having been +written out. Recovery from such a scenario can range from smooth to impossible.

+

In a multi-node cluster, this may not be as bad as it sounds — if only one +node is affected by a disruption, the crashed node can be recovered by resyncing +the data from other nodes. In practice an inconsistent state would be considered +too risky and it should be preferred to set up a fresh node to join the +existing etcd cluster. This would need to be implemented to make this option +less risky.

+

The reference implementation has an option to use these unsafe filesystem settings. +However, they are not enabled by default for good reasons.

+

Flavors with local storage

+

Flavors with local storage will have their root filesystem on a local storage +device. To fulfill the need for high IOPS that etcd and especially databases +have, the local storage device should be a solid state device — an SSD or +NVMe device. While some use cases might even be fulfilled with local +spinning disks (or raid arrays of local spinning disks).

+

Local solid state storage avoids any network overhead and offers best latency. +It however is not typically redundant, meaning that the loss of the device +or the complete hardware node will result in data loss. So it is meant to +be used with applications such as database clusters, replicating filesystems +or block devices or etcd which can handle this at the application layer.

+

The flavor naming spec in SCS allows performance to be understated — a +flavor with NVMe storage can be advertised under the SSD storage name +(and of course can be offered under both names).

+

Note that this addresses the simple case where the root disk with the +root filesystem (and possibly additional filesystems that are set up +when first booting) uses the local storage. Scenarios where additional +low-latency networked or local storage are made available via cinder +and attached for database storage are possible and viable options for +some scenarios, but not covered here.

+

Decision

+

Two new mandatory flavors: SCS-2V-4-20s and SCS-4V-16-100s are added +to the SCS flavor naming standard. The first is meant to be a good fit for +k8s control nodes with etcd while the latter is a solid base for a +small database server. Clouds claiming SCS-compliance for their IaaS +layer MUST provide these two additional flavors.

+

Obviously providers MAY offer many more combinations and e.g. create +flavors with large local SSDs.

+

The local storage advertised this way MUST support more than +1000 sequential IOPS per VM of both new mandatory types (which means a +write latency lower than 1ms — this typically means SSDs/NVMEs that +support at least several 10ks of parallel IOPS, not a challenge for +current hardware).

+

Local disks, SSDs, NVMes MUST have Power-Loss-Protection such that +data reported to be written, but in reality being stored in RAM or SLC +cache of an SSD or NVMe, is guaranteed to not be lost in case of a power +loss.

+

Like with networked storage, the provider must ensure that data +from previous users is not accessible (e.g. by securely erasing it +or by using a different encryption key) when local storage gets +allocated to a new VM.

+

Out of Scope

+

Hardware nodes (hypervisors in OpenStack language) that support flavors +with local storage (are part of an appropriate OpenStack host aggregate) +may have many VMs competing for bandwidth to the attached local storage +devices; the host needs to be configured such that it can sustain VMs +writing at full speed without causing the host to be overloaded or +to cause huge queues for these writes.

+

A more generic approach is to apply storage QoS policies to the VMs to +manage bandwidth and IOPS and create the ability to have better +performance isolation with certain guarantees. While this is desirable, +it has not been found a necessity for etcd in our tests. +Disk IO QoS is not part of this spec but may be considered in another one.

+

Live-migration with local storage is significantly more difficult than with +networked storage: The contents of the local disks also need to be replicated +over to the new host. Live-migration for these VMs may thus take significantly +longer or not be possible at all, depending the configuration from the provider. +Not supporting live-migration is OK for flavors with local disks according +to the flavor naming spec — a capability to indicate whether or not +live-migration is supported will be subject to a flavor-metadata discoverability +spec that is planned for the future.

+

Implementation note

+

Local storage in OpenStack can be provided directly via nova or via the +cinder service. While the latter has the advantage of making volumes +visible and manageable via most of the normal cinder capabilities, it +has the disadvantage of creating an indirection via iSCSI. This +results in higher latency. The requirements in the above spec are +not meant to mandate or prevent the implementation via either route.

+ +

The flavors will be added as mandatory flavors to the +flavor-naming standard, +which will thus have to be released in a v3.

+

The IOPS and Power-Loss requirements from this decision should become +part of the flavor-naming standard for disk type s.

+

When we standardize storage types in the future, additional possibilities +to solve the latency requirements for databases and etcd may emerge.

+

When we standardize QoS features there, we may amend this standard with +QoS recommendations or possibly requirements.

+

A future flavor metadata discoverability standard will indicate whether or not +these flavors can be live-migrated. A future VM metadata standard will allow +users to request live-migration and/or cold migration or restart to be or to +not be performed.

+

Conformance Tests

+

The list of mandatory flavors that needs to be present should be added to the +SCS-Spec.MandatoryFlavors.yaml +spec as soon as this ADR becomes part of the certification requirements.

+

Checks for conforming with IOPS and purging requirements will require +test instances to be launched and might become part of a monitoring +solution.

+ + \ No newline at end of file diff --git a/standards/scs-0111-v1-volume-type-decisions/index.html b/standards/scs-0111-v1-volume-type-decisions/index.html new file mode 100644 index 0000000000..eff6b5a39a --- /dev/null +++ b/standards/scs-0111-v1-volume-type-decisions/index.html @@ -0,0 +1,72 @@ + + + + + +Decisions for the Volume Type Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Decisions for the Volume Type Standard

Introduction

+

Volumes in OpenStack are virtual drives. They are managed by the storage service Cinder, which abstracts creation and usage of many different storage backends. While it is possible to use a backend like lvm which can reside on the same host as the hypervisor, the SCS wants to make a more clear differentiation between volumes and the ephemeral storage of a virtual machine. For all SCS deployments we want to assume that volumes are always residing in a storage backend that is NOT on the same host as a hypervisor - in short terms: Volumes are network storage. Ephemeral storage on the other hand is the only storage residing on a compute host. It is created by creating a VM directly from an Image and is automatically los as soon as the VM cease to exist. Volumes on the other hand have to be created from Images and only after that can be used for VMs. They are persistent and will remain in the last state a VM has written on them before they cease to exit. Being persistent and not relying on the host where the VM resides, Volumes can easily be attached to another VM in case of a node outage and VMs be migrated way more easily, because only metadata and data in RAM has to be shifted to another host, accelerating any migration or evacuation of a VM.

+

Volume Types are used to classify volumes and provide a basic decision for what kind of volume should be created. These volume types can sometimes very be backend-specific and it might be hard for a user to choose the most suitable volume type, if there is more than one default type. Nevertheless the most of configuration is done in the backends themself, so volume types only work as a rough classification.

+

Motivation

+

We want to standardize a few varieties of volume types. While a user can choose simple things like size when creating a volume, Volume Types define a few broader aspects of volume. Encryption of volumes for example is solely decided by the volume type. And whether the volume will be replicated is a mix between definiton in the volume type and backend specific configuration, but it's visiblity can only be reached in the volume type.

+

In General: what the different volume types are capable of is highly dependend on both the used backend and the configurations of OpenStack. A few options are worth being at least recommended.

+

Design Considerations

+

We want to have a discoverable Standard. So there should be no naming conventions as per request by operators.

+

This first decision will have impacts on upstream OpenStack development, as those things, that would be nice to discover, may not be currently dicoverable by users or not at all.

+

There are severel aspects of volume types, which will be discussed in the following:

+

Options considered

+

Encryption

+

Encryption for volumes is an option which has to be configured within the volume type. As an admin it is possible to set encryption-provider, key size, cipher and control location. As an admin it is also currently possible to see these configurations in a volume type with list and show commands. A user should not see these parameters in detail, but a boolean value that descibes whether encryption is used or not. Currently this is not possible in upstream OpenStack.

+

Conclusion: This is a solid aspect to be standardized. But it will need work on OpenStack, to have a boolean value presented to the users.

+

Backend Name

+

OpenStack Cinder works with a lot of different backends. They all have some kind of special features, which might be attractive for a user. But showing the name of the backend to users is also considered a security risk by Cinder developers. Overall it is always an option to make users aware of special features through the name and description of a volume type and sometimes even through extra_specs.

+

Conclusion: This should not be standardized.

+

Availability Zones

+

Availability Zones are used in Nova and Cinder seperatly to provide an often also physical separation of compute hosts or storage nodes. This leads to two options to consider:

+
    +
  1. +

    Multiple Volume AZs: This might be used if there are different backends present in one IaaS structure. The different volume types are usually used for the different volume AZs. This makes migration between those AZs only be possible for administrators.

    +
  2. +
  3. +

    Volume Types that can be attached to multiple Nova Azs: This option can be seen in the extra specs of a volume type also by normal users. Another option is to use backend specific options, as for example with ceph that directly interacts with nova for this. In that case there will not be any visible extra specs for the users.

    +
  4. +
+

Another question is how many providers use one of these options or both.

+

Conclusion: The first part doesn't make much sense to standardize, as migration between the volume types can only be done by admins. However the second part might be noteable, but due to the variety of configuration options very hard to standardize.

+

Multiattach

+

It is possible in a few backends to attach a volume to multiple VMs. This has to be configured in the Volume Type and this information is also accessable for users. Nevertheless this option also needs a lot of work from users, as those types of volumes have to have a file system, that is capable of multiattach. Many providers don't provide multiattach.

+

Conclusion: It might be noteable, that this already is a discoverable option.

+

Replication

+

Replication states, whether or not there are multiple replicas of a volume. Thus answers the question, whether the data could survive a node outage. Again there are different ways to achive replicated volumes. It can either be defined in the volume type and is discoverable also by normal users or it is configured in the backend. The last option is usually used with ceph for example. This makes it hard to discover, whether a volume is replicated or not. Another point is the number of replicas, that exist.

+

Conclusion: Replication is a good option to be standardized. Whether this should be done as a boolean option or if the number of replicas is also something users need to know should still be discussed. Nevertheless due to the different options to configure replication this will be quite complex.

+

QoS

+

Quality of Service parameters can be stated in a volume qos object. These objects can then be associated to a volume type (or directly to a volume as an admin only option). But this is optional and thus even good or very good volume QoS parameters that are aquired through hardware configuration and storage parameters, might go by unmentioned. +Furthermore the indirection makes it harder to discover the qos for a volume type. Only admins will see the associated qos ID and will have to take a closer look at the qos after discovering the volume type. PLUS: there can only be one qos association for one volume type. But a qos can be used for multiple volumes.

+

Conclusion: The benefit of displaying qos parameters is clear, thus this option should be noted. But are volume qos objects widely used? If not, standardization process would be too much work.

+

Other Backend-specific Highlights

+

While every option above described things, that can at least be partly or for admins only visible in volume types, there are many different configuration options in hardware and backend providers can make use of. It is sadly not possible to get them into the volume type directly, but we recommend, that notable configurations are written into the description of a volume type to achieve transparency for the users.

+

Open questions

+
    +
  1. How often are the different options used by providers and users respectively? Especially important for qos and replication!
  2. +
  3. Regarding Replication: Is the number of replicas needed by users and is it okay for providers to provide this information?
  4. +
+

Decision

+
AspectStandardize?Discoverabilityother Things
encryptionRecommendedwork neededextra_spec: encrypted=True/False
Backend name---
AZs--describe as optional and backend-dependend
multiattach-yesdescribe as optional
ReplicationRecommendedlot of workeither get from backend to OS or as extra_spec defined by deployer
Number of Replicas, etc?lot of workoptional, work on it after Replication is standardized
Volume QoS?admin onlyneeds further discussion, should be at least described as optional
+ +

This is an etherpad with a further look into the Options and a few examples.

+ + \ No newline at end of file diff --git a/standards/scs-0112-v1-sonic/index.html b/standards/scs-0112-v1-sonic/index.html new file mode 100644 index 0000000000..8f894c1e5a --- /dev/null +++ b/standards/scs-0112-v1-sonic/index.html @@ -0,0 +1,93 @@ + + + + + +SONiC Support in SCS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SONiC Support in SCS

Introduction

+

SONiC support in SCS was considered within the context of VP04 Networking, sub-lot 1 SDN scalability. Different challenges and approaches to SDN scalability have been explored and more specifically those who require support in the underlay network. Using SONiC in the underlay can have benefits for SCS users by using a standardized OS for network devices and also having a clear path for network scalability when using SONiC. For this to work, we have to define how SONiC is used and supported architecturally in SCS. This document outlines the architectural decisions in regards to SONiC support and integration in SCS.

+

Motivation

+

In respect to SDN scalability improvements in Openstack and SCS, there are several ways SONiC can be leveraged.

+

SONiC as a network OS where dynamic network configuration in Openstack is required

+

In many network designs for Openstack, configuration of the actual network hardware by Openstack Neutron service is required. The following network designs apply:

+
    +
  • +

    VLANs. Uisng VLANs to segment tenant networks requires the network switch to be configured. This can be manual or dynamic configuration via the ML2 Neutron driver.

    +
  • +
  • +

    EVPN/VXLAN on the switch. In this use case, SONiC runs on leaf switches. Leafs terminate VXLAN endpoints and run BGP/EVPN for the control plane. Again, the ML2 Neutron driver is used to dynamically configure the network switch. The link between the switch and the service is regular VLAN.

    +
  • +
  • +

    VXLAN on servers and switches. This is a hybrid use case, where most of the SDN is pushed to the server, but the network is still involved where support for bare metal hosts is needed.

    +
  • +
+

Automation and tooling for SONiC

+

There is no tooling in SCS or Openstack communities to facilitate the rollout and configuration of enterprise scale SONiC deployments. Netbox and OSISM can be integrated, so that Netbox becomes the source of truth for network configuration and OSISM supports the initial rollout and configuration for the switches.

+

OVN for SONiC

+

OVN and OVS are extensively leveraged in Neutron to SDN. In large scale deployments, OVN can become a bottleneck by exhausting resources on network nodes. SONiC can host the OVN control plane as a module (container) and spare the resources in network nodes. There is however a potential other bottleneck on SONiC hardware, as OVN control plane can be resource intensive. This is a potential area for further investigation.

+

Design Considerations

+

There are different ways SONiC support can be implemented in SCS, very similar to existing approaches with Linux.

+

Options considered

+

Option 1: SCS distribution of SONiC

+

With this approach, SCS will create it's own distribution of SONiC, similar to what Debian or Arch are for Linux. This distribution will be based on the SONiC community distribution, but will have SCS specific modules, which will be developed and maintained by SCS. SCS will contribute its code to dedicated SCS repositories and build its own SONiC images. The code can eventually be pushed upstream, but not as top priority. This approach will allow SCS to have a clear path for SONiC support and integration in SCS, but will also require SCS to maintain a distribution of SONiC, which is a significant effort. Upstream/downstream changes will have to be managed and maintained. However the advantage is that SCS will have full control over the distribution and can make changes as needed. Users will have to use the SCS distribution of SONiC, which will be based on the community distribution. If users already deploy community or enterprise SONiC, a migration path to SCS SONiC will be needed.

+

Option 2: SCS will support SONiC but will not change it

+

SCS supports enterprise ans community versions of SONiC but will not develop its own code for it. This will significantly limit the ability to develop new features for SDN, because all changes will be done in the tooling around SONiC and not in the OS itself. The advantages are that SCS will still improve SONiC support and will have minimal effort for this. The downside is that some features like OVN control plane for SONiC will not be possible.

+

Option 3: SCS develops SCS-specific modules as add-on for any SONiC (Community or Enterprise)

+

In option 3, SCS will change SONiC by releasing its own modules for it. Those module can be provided as add-ons and installed on top of any version, community or enterprise. While compatability between the modules the SONiC releases will need to be maintained, there will be much broader support for SONiC and users will be able to pick and chose distributions based on their existing relationships and experience and use SCS independent of this. In cases where SCS provides contributions to core SONiC, those can be made in upstream Community repositories, so that the whole community including the propriatory vendors can adopt them eventually.

+

Option 4: SCS does not adopt SONiC at all

+

This option entails no dedicated effort on SCS's part in supporting SONiC network equipement for it's users and software stack. Users can still use SONiC from what is available by other projects or if they invest the effort themselves. This has several disadvantages:

+
    +
  • SCS is not contributing to the SONiC community
  • +
  • the value for SCS by users who already use or plan to invest in SONiC is diminished
  • +
  • users have less incentive to use community SONiC and switch to Enterprise SONiC
  • +
  • SCS will not be able to leverage SONiC for SDN scalability improvements
  • +
+

Open questions

+

State of SONiC community?

+

community version: mature or not?

+

Commits: between 40-52 per month. Contributors to master: 10-20. Mailing list: 6 lists, about 10-30 messages/month for list. Community version supports 25 hardware vendors. Requires significant time and resource investment and "Explorer's mindset".

+

enterprise version: mature or not?

+

Multiple vendor distributions. Expensive in general

+
    +
  • release schedule - how often are features and bugfixes released?
  • +
+

New tags appears on different periods, once 2 times per month, other 3 months between releases.

+
    +
  • adoption penetration - how many vendors use it? What type of venders (big, medium and large)?
  • +
+

Good initial adoption: Microsoft, Target. Adoption requires time and money

+
    +
  • Is SONiC being overtaken by alternatives: SmartNICs and DPUs? How relevant is it still and will be in the coming years?
  • +
+

Actually not, because of different use cases.

+
    +
  • Sustainability of community SONIC for 2025+
  • +
+

The SONiC community is healthy and growing, however progress is slower due to factors like investment of resources. The barrier of entry is much higher than other similar OSS projects.

+

Decision

+

IaaS team recommends to use Option 3: SCS develops SCS-specific modules as add-on for any SONiC (Community or Enterprise). It has the best tradeoff between time and resource investment and benefits for the community. Adopting this strategy would allow SCS to be agile and quickly adopt SONiC, by providing users with clear path while allowing the freedom to chose different hardware and software vendors. SCS code can be packaged independently of each SONiC distribution and installed as add-on. Also SCS contributions to core SONiC will be done directly upstream, so that the whole community can benefit from them.

+

Work on hardware support in SONiC should be raised in upstream and SCS shouldn't make significant investments in this area.

+ +
+ + \ No newline at end of file diff --git a/standards/scs-0113-v1-security-groups-decision-record/index.html b/standards/scs-0113-v1-security-groups-decision-record/index.html new file mode 100644 index 0000000000..51e4a043f5 --- /dev/null +++ b/standards/scs-0113-v1-security-groups-decision-record/index.html @@ -0,0 +1,123 @@ + + + + + +Security Groups Decision Record | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Security Groups Decision Record

Introduction

+

Security Groups in IaaS (OpenStack) are sets of ip table rules, that are applied to ports which connect a virtual machine to a network. +In contrast to other resources like flavors or volume types that are always publicly accessible, or images that can be both public and private, security groups are always bound to the project level. +That creates some difficulties for a possible standard of Security Groups, which are discussed in this document.

+

Terminology

+

Security Group +A set of iptables rules that is applied to ports connecting a virtual machine and a network.

+

Security Group Rule (abbr. Rule) +This references a single rule within a security group.

+

RBAC +Role Based Access Control used for policies and alike.

+

network rbac / neutron rbac +These access controls will let administrators and users share neutron related resources with other projects.

+

admin +The most powerful role in OpenStack. Only given to some Operators of the Cloud Infrastructure.

+

Context

+

While creating a virtual machine and also later on, one or more security groups can be added to it. +When there is no security group specified the default security group will always be added. +Like every other security group, the default group is also project bound. +That means, it can be edited as required by project members. +By design of OpenStack and when not changed, default rules in the default security group block all incoming traffic except from the same Security Group and only allow outgoing traffic1.

+

Reasons for and against a standard for security groups

+

Considering having most likely similiar security groups within different projects, it might make sense to standardize a few security groups for often used cases like ssh, http, https and maybe icmp. +What speaks for standardizing a certain set of security groups:

+
    +
  1. Having a set of correctly configured security groups could reduce misconfiguration from users
  2. +
  3. Re-using correctly configured security groups saves time for users
  4. +
  5. Auditing security groups would be way easier for operators when helping customers
  6. +
  7. The configuration for the Security Groups can be done by networking experts, which may result in a higher security level as when users without expertise configure them
  8. +
+

What are the downsides of having a set of standardized security groups:

+
    +
  1. A bug or misconfiguration is a single point of failure for ALL customers
  2. +
  3. Users might apply the wrong security group to their port or VM because they lack the domain knowledge, unknowingly opening themselves to attacks
  4. +
  5. Users will not inspect such default security groups: this may result in applying a wrong group and opening traffic too much
  6. +
  7. the central authority managing the groups does not necessarily know the usecase of the user, the user/operator must know best what kind of security their workload needs. What is a necessary port for 99% of deployments might be a security disaster for my deployment
  8. +
  9. Providing default groups could have the effect of stopping customers to think about their specific security needs and instead just copying default groups and or rules
  10. +
+

This leads to a conclusion, that a set of default security groups is only more valuable than harmful for users:

+
    +
  1. when the rules in those groups are configured correctly
  2. +
  3. and when the users still have to think about their network security on their own for each VM they start
  4. +
+

Technical limitations

+

As security groups are project bound and there is no native way to them to be shared, we are left with three options:

+
    +
  1. To use another endpoint network rbac to share security groups among different projects.
  2. +
  3. To adhere to the project scope of security groups and only give documentation about recommended security groups to users.
  4. +
  5. To only add a tutorial on how to create your own security group in general, how to detect what kind of network permissions your project needs for most frequent (linux) workloads and how to craft your own security groups in a secure way.
  6. +
+

Option 0: Pre-Requirement: default rules for the (default) security group

+

For every project that is created there will also be a project-specific default security group created. +The default rules for the default groups and all other newly created groups can be looked up like this:

+
stack@devstack:~/devstack$ openstack default security group rule list
+------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+
| ID | IP Protocol | Ethertype | IP Range | Port Range | Direction | Remote Security Group | Remote Address Group | Used in default Security Group | Used in custom Security Group |
+------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+
| 47b929fd-9b39-4f22- | None | IPv6 | ::/0 | | egress | None | None | True | True |
| abc5-7d4f64d10909 | | | | | | | | | |
| 6ace51bb-5258-45ab- | None | IPv6 | ::/0 | | ingress | PARENT | None | True | False |
| 9ba9-1efbebfb086b | | | | | | | | | |
| 92a79600-5358-4fef- | None | IPv4 | 0.0.0.0/0 | | egress | None | None | True | True |
| a390-822665f46070 | | | | | | | | | |
| 997bb0c2-652e-4d1f- | None | IPv4 | 0.0.0.0/0 | | ingress | PARENT | None | True | False |
| b910-e12c89f88b44 | | | | | | | | | |
+------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+
+

Those rules can be edited, which may pose a security risk for customers consuming the default security group. +This should be adressed as a pre-requirement here.

+

Option 1: operator usage of network rbac

+

The network rbac endpoint2 manages the possibitity to share and access certain network-specific resources such as security groups. +For admins it is possible to use this endpoint to share a security group with ALL projects within the the cloud including ALL projects of ALL domains:

+
stack@devstack:~/devstack$ openstack network rbac create --target-all-projects --action access_as_shared --type security_group group-for-everyone
+-------------------+--------------------------------------+
| Field | Value |
+-------------------+--------------------------------------+
| action | access_as_shared |
| id | 394d8e71-143f-4c5b-a72f-cd10af3222df |
| object_id | b6a3834a-f89c-47a9-9ed6-ca89e93701c4 |
| object_type | security_group |
| project_id | 15f2ab0eaa5b4372b759bde609e86224 |
| target_project_id | * |
+-------------------+--------------------------------------+
+

This would fulfill our goal to grant access to predefined security groups for all projects and all groups recieved as shared do not count into the projects quota for security groups. +But there are a few downsides to this:

+
    +
  1. This should be strictly bound to the admin: no other user should be able to share security groups so to not confuse user.
  2. +
  3. The managing of those network rbac objects can get out of hand pretty quickly, because there neither is an explicit name for such an object nor do the names of the shared objects appear:
  4. +
+
stack@devstack:~/devstack$ openstack network rbac list --long
+-----------------------------+----------------+-----------------------------+--------------------+
| ID | Object Type | Object ID | Action |
+-----------------------------+----------------+-----------------------------+--------------------+
| 97507e4c-7413-4d61-ab21- | security_group | 110b1bea-f0e0-4fb7-9fc7- | access_as_shared |
| 047fc23516dd | | cda1b6f927b0 | |
| bc22a865-46f9-4cd2-80af- | security_group | 5f22e42e-95dc-4c0a-8651- | access_as_shared |
| 3c249ba0e010 | | 57b1dfc8639f | |
| 2467806f-5428-4506-8e23- | network | 02ef8579-9917-4a01-893d- | access_as_shared |
| f4690db04e01 | | cb2f9f3d5f98 | |
| ed40996e-218d-4daa-b222- | network | 73edb86b-d7ab-4db3-82b7- | access_as_external |
| f3c603a5b8a6 | | 25fa8b012e40 | |
| 45e0a707-af82-42a6-b93f- | subnetpool | cd7addd1-05d9-48a8-bc38- | access_as_shared |
| efde18216f13 | | 4a581354983f | |
| e514c2c8-65ac-4062-8b03- | subnetpool | ad1cc1ed-3261-4df2-8c73- | access_as_shared |
| fe24f6fc4656 | | c3dd72d59061 | |
+-----------------------------+----------------+-----------------------------+--------------------+
stack@devstack:~/devstack$ openstack network rbac show bc22a865-46f9-4cd2-80af-3c249ba0e010
+-------------------+--------------------------------------+
| Field | Value |
+-------------------+--------------------------------------+
| action | access_as_shared |
| id | bc22a865-46f9-4cd2-80af-3c249ba0e010 |
| object_id | 5f22e42e-95dc-4c0a-8651-57b1dfc8639f |
| object_type | security_group |
| project_id | 15f2ab0eaa5b4372b759bde609e86224 |
| target_project_id | * |
+-------------------+--------------------------------------+
+

The biggest downside: As soon as a security group is shared, everyone from every project, can edit the rules of this group.

+

Option 2: stay project-scoped

+

Using and adhering the project scope of the security groups has the consequence, that:

+
    +
  1. either an admin has to set up security groups for each project
  2. +
  3. or the SCS project only provides a guide on how to setup and use some recommended security groups.
  4. +
+

As users are allowed to, will and should edit their security groups, there is no way to ensure, that a certain set of security groups with certain rules is always present in a project. +So packing an extra burden on admins is unreasonable. +The option to give a guide and recommend a few security groups however is a quite good option.

+

Option 3: security-focused guide

+

Instead of providing users with a set of default groups or the knowledge about how to create default groups, there could be a guide created that focuses on the crafting of a security group in a secure way. +That would include identifying what kind of network permission a single VM needs and how to proceed after gathering all requirements of the customers workload.

+

Decisions

+

The default Security Group Rules should be standardized as a pre-requirement (Option 0).

+

Using the network rbac endpoint (Option 1) would not solve the idea of having pre-defined and administrator audited Security Groups, because it is possible for any user to edit the rules of shared Security Groups. +Instead the project-scope of the Security Groups should by focused and a guide prepared, that gives insight about creating and using Security Groups with a few examples but with a clear security focus (Mix of Option 2 and 3).

+

Consequences

+

Any CSP will have to follow the standard for the default Security Group Rules. +There are no consequences regarding Security Groups as it and users stay in full control and responsible for their own Security Groups

+ +

A PR to standardize default Security Group Rules +A PR to a first draft for a guide for security groups

+ +

Footnotes

+
    +
  1. +

    Default Security Group Rules

    +
  2. +
  3. +

    Neutron RBAC

    +
  4. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0114-v1-volume-type-standard/index.html b/standards/scs-0114-v1-volume-type-standard/index.html new file mode 100644 index 0000000000..e58746c10e --- /dev/null +++ b/standards/scs-0114-v1-volume-type-standard/index.html @@ -0,0 +1,84 @@ + + + + + +Volume Type Standard | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Volume Type Standard

Introduction

+

A volume is a virtual drive that is to be used by an instance (i. e., a virtual machine). With OpenStack, +each volume is created per a type that determines basic features of the volume as provided by the backend, +such as encryption, replication, or quality of service. As of the writing of this document, presence or absence of these +features can not be discovered with full certainty by non-privileged users via the OpenStack API.

+

Glossary

+

The following special terms are used throughout this standard document:

+
TermMeaning
volumeOpenStack resource, virtual drive which usually resides in a network storage backend
volume featureA certain feature a volume can possess
aspectPart of a volume type that will activate a corresponding feature in a created volume
AZAvailability Zone
Volume QoSQuality of Service object for Volumes
+

Motivation

+

As an SCS user, I want to be able to create volumes with certain common features, such as encryption or +replication, and to do so in a standardized manner as well as programmatically. +This standard outlines a way of formally advertising these common aspects for a volume type to +non-privileged users, so that the most suitable volume type can be discovered and selected easily — both by +the human user and by a program.

+

Design Considerations

+

All considerations can be looked up in detail in the Decision Record for the Volume Type Standard.

+

Systematic Description of Volume Types

+

To test whether a deployment has volume types with certain aspects, the discoverability of the parameters in the volume type has to be given. As for the time this standard is created, there is no way for users to discover all aspects through OpenStack commands. Therefore the aspects, that are fulfilled within a volume type, should be stated in the beginning of the description of a volume type in the following manner:

+

[scs:aspect1, aspect2, ..., aspectN]...

+

The mentioned aspects MUST be sorted alphebetically and every aspect should only be mentioned to the maximal amount of one.

+

Standardized Aspects

+

The following table shows which aspects are considered in this standard. The third column shows how the description of the volume type has to be adjusted, if the aspect is fulfilled:

+
AspectRequirementstandardized descriptioncomment
EncryptionRecommended"[scs:encrypted]"volume is encrypted
ReplicationRecommended"[scs:replicated]"volume is replicated to avoid data loss in a case of hardware failure
+

It is possible to use multiple of those aspects within one volume type. There don't have to be different volume types for each aspect. +For instance, one volume type that uses LUKS-encryption with a ceph storage with inherent replication would fulfill all recommendations of this standard.

+

DEFAULT volume type

+

There is always a default volume type defined in an OpenStack deployment. This volume type is created in the setup of cinder and will always be present in any OpenStack deployments under the name __default__. This standard does not have any requirements about this volume type at this moment, instead deployers are free to choose what fits best in their environment. Conversely, a cloud user can not expect any specific behavior or properties from volume types named __default__.

+

REQUIRED volume types

+

Currently, this standard will not require volume types with certain specification.

+ +

This standard recommends to have one or more volume types, that feature encryption and replication.

+

OPTIONAL volume types

+

Any other aspects of volume types, that can be found in the decision record are OPTIONAL. They SHOULD NOT be referenced in the way this standard describes. Some of them already are natively discoverable by users, while others could be described in the name or description of a volume type. Users should look into the provided volume types of the Cloud Service Providers, if they want to use some of these other aspects.

+

Implementation Details

+

Encryption

+

Encryption for volumes is an option which has to be configured within the volume type. As an admin it is possible to set encryption-provider, key size, cipher and control location. Additionally to be discoverable by users, the description should start with an aspect list such as [scs:encrypted] (potentially with additional aspects). It should look like this example:

+
openstack volume type show LUKS
+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| access_project_ids | None |
| description | [scs:encrypted] This volume uses LUKS-encryption |
| id | d63307fb-167a-4aa0-9066-66595ea9fb21 |
| is_public | True |
| name | LUKS |
| qos_specs_id | None |
+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+

Replication

+

Replication states whether or not there are multiple replicas of a volume. Thus, it answers the question whether the data could survive a node outage. Unfortunately there are two ways replication can be achieved:

+
    +
  1. In the configuration of a volume type. It then is visible as extra_spec in the properties of a volume type.
  2. +
  3. Via the used backend. Ceph for example provides automatic replication, that does not need to be specified in the volume type. This is currently not visible for users.
  4. +
+

To fulfill this recommendation, the description should start with an aspect list such as [scs:replicated] (potentially with additional aspects).

+

Example

+

One volume type that is configured as an encrypted volume type in a ceph backend, with automated replication would fit both recommendations and will be enough to comply to this part of the volume type standard.

+

It should look like the following part:

+
+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| access_project_ids | None |
| description | [scs:encrypted, replicated] Content will be replicated three times to ensure consistency and availability for your data. LUKS encryption is used. |
| id | d63307fb-167a-4aa0-9066-66595ea9fb21 |
| is_public | True |
| name | hdd-three-replicas-LUKS |
| properties | |
| qos_specs_id | None |
+--------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ + +

Conformance Tests

+

The script /Tests/iaas/volume-types/volume-types-check.py connects to an OpenStack environment and tests +the following:

+
    +
  • for each volume type: if its description starts with [scs:....], then this prefix is a feature list +(sorted, each entry at most once), and each entry is one of the possible features described here,
  • +
  • the recommended volume types are present (otherwise, a WARNING is produced).
  • +
+

The return code is zero precisely when the test could be performed and the conditions are satisfied. +Otherwise, detailed errors and warnings are output to stderr.

+ + \ No newline at end of file diff --git a/standards/scs-0115-v1-default-rules-for-security-groups/index.html b/standards/scs-0115-v1-default-rules-for-security-groups/index.html new file mode 100644 index 0000000000..4a6fd0659b --- /dev/null +++ b/standards/scs-0115-v1-default-rules-for-security-groups/index.html @@ -0,0 +1,117 @@ + + + + + +Default Rules for Security Groups | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Default Rules for Security Groups

Introduction

+

Security Groups in IaaS (OpenStack) are part of the network security mechanisms provided for the users. +They resemble sets of virtual firewall rules allowing specific network traffic at a port of a VM that connects it to a network. +They are project-bound, which means that all Security Groups that are newly created are only available to the project in which they were created. +This is also the case for the default Security Group that is created for each project as soon as the project itself is created.

+

Terminology

+

Security Group (abbr. SG) +Set of ip table rules, used for tenant network security.

+

Security Group Rule (abbr. SG Rule) +A single ip table rule, that is part of a SG.

+

Administrator (abbr. Admin) +Operator = User of an OpenStack cloud with the admin role.

+

Default Security Groups, Custom Security Groups and default Security Group Rules

+

To properly understand the concepts in this standard and avoid ambiguity, is very important to distinguish between the following similar-sounding but different resources in the OpenStack Networking API:

+
    +
  1. default Security Group
  2. +
  3. custom Security Group
  4. +
  5. default Security Group Rules
  6. +
+

A default Security Group is a predefined Security Group which is automatically created once a project is created and is specific to that project. +This Security Group is called "default" and there exists only one per project. +It will automatically be assigned to VMs that have no other Security Group explicitly assigned to it, when a VM is created.

+

A custom Security Group is any additional Security Group created within a project separate from the default Security Group of the project.

+

The default Security Group Rules may target the default Security Groups or the custom Security Groups or both. +They resemble a rule template and each Security Group will be initially created with rules according to this template.

+

Although the rules of a Security Group may be adjusted freely after its creation, these default rule presets applied on initialization are predefined. +In recent OpenStack releases, both presets can be adjusted independently by administrators of the infrastructure.

+

Motivation

+

The rules of a Security Group can be edited by default by any user with the member role within a project. +But when a Security Group is created it automatically incorporates a few SG rules that are configured as default rules. +Since the 2023.2 release, the default set of Security Group rules can be adjusted. +This functionality is only available to administrators12. +In combination with the OpenStack behavior that when a VM is created with no Security Group specified, the default SG of the project is automatically applied to the ports of the VM, +a user cannot be sure which firewall rules are applied to such a VM.

+

Therefore this standard proposes default Security Group rules that MUST be set by administrators to avoid divergence in default network security between different IaaS environments.

+

Design Considerations

+

Up to the 2023.1 release (antelope) the default Security Group rules are hardcoded in the OpenStack code. +We should not require to change this behavior through code changes in deployments.

+

Beginning with the 2023.2 release (bobcat) the default Security Group rules can now be edited by administrators through an API. +All rules that should be present as default in Security Groups have to be configured by admins through this API.

+

There are two ways to approach a standard for the default rules of Security Groups.

+
    +
  1. +

    There could be a set of rules standardized that has to be configured by admins.

    +

    OpenStack's default rules for Security Groups already provide a good baseline for port security, because they allow all egress traffic and for the default Security Group only ingress traffic from the same group.

    +

    Allowing more rules would not benefit the security level, while reducing or limiting the existing rules would barely improve it. +Nevertheless a standard could hold up the current security level against possible future release with more open default rules. +Changing the default rules will not change the rules of any existing Security Groups.

    +
  2. +
  3. +

    With the already strict OpenStack default rules users are required in most use cases to create and manage their own Security Groups.

    +

    This has the benefit that users need to explicitly think about the port security of their VMs and may be less likely to apply Security Groups which rules open up more ports than needed. +There is also a guide from the SCS project on how to set up a Security Group that also focuses on having a good port security3.

    +

    With the default OpenStack behavior of having already strict rules, which in most cases require users to manage their own Security Groups, this standard should mandate a middle way: +It should allow adjusting the default rules, but only to a stricter version.

    +
  4. +
+

Allowing all outgoing traffic in the default rules in combination with blocking all incoming traffic would be strict enough from a security point of view. +And it would make it necessary for users to check and change the rules of their Security Group to a meaningful set.

+

Further Annotations

+

This standard should only be applied onto versions of OpenStack that implement the new endpoint for the default Security Group rules, which would only include 2023.2 or higher releases.

+

It is possible to have different default Security Group rules for the default SG and custom SGs. +And it is arguable to have a more strict standard for default rules for the default Security Group than for the custom Security Groups. +Because the latter ones are not automatically applied to a VM but are always edited by the users to apply to their requirements.

+

The allowlisting concept of Security Group rules makes it hard to allow traffic with an exception of certain ports. +It would be possible to just define many rules to achieve what a blocklist would achieve. +But having many rules may confuse users and they may not disable unnecessary default rules in their SGs.

+

Standard

+

The default Security Group rules for the default Security Groups SHOULD allow incoming traffic from the same Security Group. +The default Security Group rules for ALL Security Groups MUST NOT allow any other incoming traffic. Neither IPv4 nor IPv6. +This can be achieved through having ingress rules in the default Security Group rules that allow ingress traffic from the Remote Security Group "PARENT" but are only used in the default Security Group.

+

The default Security Group rules for ALL Security Groups SHOULD allow egress Traffic for both IPv4 and IPv6.

+

Example

+

In the following table, there is only ingress traffic between the same default Security Groups allowed plus all egress traffic:

+
$ openstack default security group rule list
+--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+
| ID | IP Protocol | Ethertype | IP Range | Port Range | Direction | Remote Security Group | Remote Address Group | Used in default Security Group | Used in custom Security Group |
+--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+
| 47b929fd-9b39-4f22-abc5- | None | IPv6 | ::/0 | | egress | None | None | True | True |
| 7d4f64d10909 | | | | | | | | | |
| 92a79600-5358-4fef-a390- | None | IPv4 | 0.0.0.0/0 | | egress | None | None | True | True |
| 822665f46070 | | | | | | | | | |
| 93e35d0c-2482-4ec1-9fbd- | None | IPv4 | 0.0.0.0/0 | | ingress | PARENT | None | True | False |
| fd8c9a21a04e | | | | | | | | | |
| ed5cd662-add2-4e42-b0a7- | None | IPv6 | ::/0 | | ingress | PARENT | None | True | False |
| 3b585d348820 | | | | | | | | | |
+--------------------------+-------------+-----------+-----------+------------+-----------+-----------------------+----------------------+--------------------------------+-------------------------------+
+ +

The spec for introducing configurability for the default Security Groups Rules can be found here.

+

More about Security Groups as a resource in OpenStack can be found here.

+

Conformance Tests

+

The conformance tests should check for the absence of any ingress traffic rules except traffic from the same Security Group in the openstack default security group rule list. +As having egress rules is allowed by this standard, but not forced and can be set in various ways, the tests should check for presence of any egress rules.

+ +

Footnotes

+
    +
  1. +

    Tracking of development for editable default SG rules

    +
  2. +
  3. +

    Release Notes of Neutron 2023.2

    +
  4. +
  5. +

    Guide for Security Groups

    +
  6. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests/index.html b/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests/index.html new file mode 100644 index 0000000000..cf5cacccc4 --- /dev/null +++ b/standards/scs-0200-v1-using-sonobuoy-for-kaas-conformance-tests/index.html @@ -0,0 +1,206 @@ + + + + + +Using Sonobuoy for KaaS conformance tests | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Using Sonobuoy for KaaS conformance tests

Motivation

+

With the k8s-cluster-api-provider, the SCS provides a tool to generate +and manage k8s clusters on top of its IaaS infrastructure. As part of +the application, Sonobuoy is used as a test suite to execute the +official Kubernetes e2e tests. +We expect that current and future tests derived from SCS standards +will benefit from (or even require) the testing mechanisms that Sonobuoy provides.

+

Apart from running the Kubernetes e2e tests, Sonobuoy also allows users to write +their own tests and apply them as a self-managed plugin. +All tests not provided by the e2e test plugin could therefore +be written by the respective SCS teams responsible for the standards or tests and +then be made executable with Sonobuoy. Hence, Sonobuoy could provide both a pre-done +test suite and a framework to write additional conformance tests required for SCS.

+

Short Sonobuoy Introduction

+

The main objective of Sonobuoy plugins is to present test +results in a consolidated way. To do this, Sonobuoy integrates the test into a pod, +which is then applied to the K8s cluster under test. A Sonobuoy worker supervises +this pod and forwards all test results to the aggregator module. It does this by +waiting for a specific "Done" file to be created. Once this file is recognized, +the worker forwards the results to the aggregator, using a predefined location +for the results file within a folder, as seen in following image: +image search api

+

In order to use the existing conformance tests as a Sonobuoy plugin, a wrapper +around the individual test scripts would be required. This wrapper would need to +have the following effects:

+
    +
  • gathers all test results and provides them in the results file
  • +
  • run tests in sequence and signal the worker when it's finished by generating a "Done" file
  • +
+

Apart from providing the test results, a plugin container must also forward the +status of each test by setting a status flag in the results file. +Additionally, the tests would need to be able to run inside a pod in the K8s cluster under test.

+

Design Considerations

+

There are different approaches to create a Sonobuoy plugin, which are discussed +below in order to find a best practice for the SCS project. The documented approaches +show one example each in order to give a better representation to the reader.

+

Sonobuoy provides plugin examples in the plugins repository, +which are referenced throughout this section.

+

Option 1 Golang based approach 1: Pick a framework from the Sonobuoy plugin examples

+

The seemingly most interesting plugin is the e2e-skeleton, which uses +the kubernetes-sigs/e2e-framework. The kubernetes-sigs/e2e-framework +is a stand-alone project that is separate from the official Kubernetes e2e tests. +The framework provides proper documentation as well as helper functions that abstract +client functionalities, similar to those found in "kubernetes/kubernetes/test/e2e/framework" repository.

+

As mentioned in the motivation of the e2e-framework, +the project was created to circumvent the disadvantages of Kubernetes' own e2e-tests, +which are described in more detail in the goals.

+

PROS:

+
    +
  • arguments in favor of this framework can also be found under the goals description of the documentation
  • +
  • e2e-framework is a well-defined framework, that allows the handling of resource creation and deletion
  • +
  • official framework provided by "Kubernetes-sigs"
  • +
+

CONS:

+
    +
  • arguments not in favor of this framework can be derived from the Non-Goals description of the documentation: +
      +
    • "no responsibility for bootstrapping or the execution of the tests themselves" can be ignored, as this is partly taken over by Sonobuoy
    • +
    • "no mock or fake cluster components" can be ignored, since the e2e tests of SCS should be used to test real clusters and their functionality
    • +
    • for this test procedure, the Sonobuoy e2e plugin should be run in addition to the SCS KaaS conformance tests
    • +
    +
  • +
+
+

proof of concept: ../Tests/kaas/kaas-sonobuoy-go-example-e2e-framework/

+
+

Option 2 Golang based approach 2: Reuse the Kubernetes own e2e test infrastructure and framework

+

The existing Sonobuoy e2e plugin already provides a vast number of tests that could +be adapted or reused for the SCS project.

+

If these e2e tests are to be reused in a customized structure, a framework like ginkgo +must be used as it is used by the Kubernetes e2e test infrastructure. +This could use the implementation of the build process responsible for the Docker +image containing the e2e tests. The setup could be copied from kubernetes/test/conformance/image +and adapted to the projects requirements. The mentioned build process must use the +files of the following directories from the Kubernetes repository:

+ +

PROS:

+ +

CONS:

+
    +
  • not easy to implement, as we would have to copy part of the Kubernetes repository and track the changes from the upstream
  • +
  • according to README.md, part of it seems to be outdated and might change with a future version + +
  • +
+
+

TODO: provide proof of concept: kaas-sonobuoy-go-example-k8s-e2e

+
+

Option 3 Write Python scripts for tests

+

Sonobuoy makes it possible to write tests in Python and execute them like other +tests in a pod on the K8s cluster. It would therefore be possible to keep on writing +conformance tests in Python.

+

This option would require a wrapper in order to make the tests scripts executable +as Sonobuoy plugins. This wrapper, as mentioned earlier, would need to capture +the collection of test results as well as the generation of the "Done" file after +the test execution is finished. This could be managed by executing each test script +in a sequential order.

+

The wrapper as well as the python tests and test framework could then be stored +in a container image and uploaded to a registry in order to be usable by Sonobuoy +within the k8s-cluster-api-provider.

+

This approach also leaves the decision open as to which test framework should be +used for Python, which should be decided in a secondary Decision Record.

+
+

proof of work: ../Tests/kaas/k8s-default-storage-class

+
+

PROS:

+
    +
  • continue using the already available Python tests +
      +
    • only a small number of tests is implemented thus far
    • +
    +
  • +
+

CONS:

+
    +
  • no "native" support in Sonobuoy, a wrapper is needed
  • +
  • decision for a framework is still not done
  • +
+

Approaches to providing a Sonobuoy plugin image

+

The following section showcases both ways to provide a Sonobuoy plugin image. +Option 1 would most likely be used, if an image is published to be used by an end user. +Option 2 is the expected way for local development and testing.

+

Option 1 Public container registry

+

The image can be made available via a public container registry, which would require +a regular job (e.g. CI/CD) to build and publish the image.

+

Option 2 Local image upload

+

Create the image locally on the "clusterctl admin control node" and then upload +it manually to the Kubernetes cluster under test.

+

Both approaches are useful in different ways. While the usage of a container registry +allows easy distribution of tests and guarantees new images through the usage of a +CI/CD job, it also makes it harder to test changes quickly, since a wait time could be +necessary to let the CI/CD job run through and access the image. This can be solved +by using the "Local image upload" or a combination of both approaches.

+

Decision

+

The KaaS conformance test MUST be provided as a test suite holding the +test cases for the Kubernetes clusters to be checked. +Furthermore, the test cases themselves MUST be wrapped by a test framework to:

+
    +
  • handle the creation and deletion of resources
  • +
  • collect and present results
  • +
  • consolidate redundant code across test cases
  • +
  • support the creation of test cases through predefined structures
  • +
+

As with the k8s-cluster-api-provider the SCS provides a tooling to generate +its KaaS infrastructure. Part of the k8s-cluster-api-provider is the usage +of Sonobuoy as a test suite to execute the Kubernetes own e2e tests. +Investigating those e2e test lead to the conclusion that they are not always reusable. +The main purpose of Kubernetes own e2e tests is to test the functionality of +the Kubernetes code itself and not the resources and setup of a specific KaaS infrastructure +as it is the aim of the SCS KaaS conformance test.

+

However, considering that the SCS has an ongoing process of defining standards and +implementing test cases to check their compliance, that means in some cases future standards +might already be covered by the e2e test inside the Kubernetes repository. +Hence, before writing tests, a developer SHOULD check the Kubernetes e2e tests for +existing test cases that might cover conformance of a standard currently being worked on.

+

As described above, Sonobuoy offers the possibility to generate custom plugins +that provide self-created test cases. Therefore, future conformance tests MUST +be executable by Sonobuoy by wrapping them in a Sonobuoy plugin. +Moreover, three options for the implementation of the SCS KaaS compliance test +cases are described above so that it can be decided within this decision record which +options should be used.

+

As a first decision, "Option 2 Go Approach 2: Reuse Kubernetes' own e2e test infrastructure and framework" +is the least viable, as it would mean copying almost all the files used from +the Kubernetes e2e tests. This framework is closely linked to the development of +the Kubernetes code. Therefore, changes to its structure mainly are in line with its usage +in the Kubernetes repository itself and is most likely not relevant for other parties. +Changes in the framework cloud have a greater impact on our side as they are +predictable. The development effort gained by reusing these examples could be +outweighed by the investment necessary to adapt tests to the corresponding framework changes.

+

This leaves "Option 1 Go approach 1: Pick framework from the Sonobuoy plugin examples" +and "Option 3 Write Python scripts for tests" as methods for implementing test cases. +It is possible to use both approaches in parallel, which would enable usage of both Python +and Go code. This could possibly generate two Sonobuoy plugins, but this isn't a necessity.

+ + \ No newline at end of file diff --git a/standards/scs-0210-v1-k8s-new-version-policy/index.html b/standards/scs-0210-v1-k8s-new-version-policy/index.html new file mode 100644 index 0000000000..5b9f86a2bc --- /dev/null +++ b/standards/scs-0210-v1-k8s-new-version-policy/index.html @@ -0,0 +1,65 @@ + + + + + +SCS K8S Version Policy for new Kubernetes versions | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS K8S Version Policy for new Kubernetes versions

Introduction

+

Here we will describe how fast providers need to keep up with the upstream Kubernetes version.

+

To create a informed decision we summarize here the Kubernetes rules regarding versioning at the time of writing (2023-01-16):

+

Kubernetes usually provides about 3 minor releases per year (see Kubernetes Release Cycle).

+

Patch release cadence is typically monthly. However, the first patches after the first minor release usually arrive 1-2 weeks after the first minor release +(see Patch Release Cadence).

+

As stated in Kubernetes Support Period, in general the latest 3 minor versions are maintained by the Kubernetes project. +Every release will be maintained for about 14 months. +The first 12 months are the standard support period. +The remaining 2 months are only for:

+
    +
  • CVEs (under the advisement of the Security Response Committee)
  • +
  • dependency issues (including base image updates)
  • +
  • critical core component issues
  • +
+

Motivation

+

Kubernetes is a fast-paced project. +We want to achieve that providers keep up to date with upstream and do not fall behind Kubernetes releases. +This ensures that users are able to upgrade their clusters to address security issues, bug fixes and new features when using SCS compliant clusters in regards of Kubernetes. +However, providers should have reasonable time to implement the new Kubernetes versions and test them.

+

Decision

+
    +
  • Must provide latest minor version no later than 4 months after release
  • +
  • Must provide latest patch version no later than a week after release
  • +
  • Should be faster for critical CVEs (CVSS >= 8)
  • +
  • Should be tested
  • +
+ +

All important documents regarding versioning, releases, etc. for the official Kubernetes project can be found on the Kubernetes Releases page.

+

Conformance Tests

+

The conformance test is written in the 'k8s-version-recency-check.py' script. The script requires the path to a valid +kubeconfig file, which should describe the k8s cluster under test. This can either be done by creating a config from +the also provided 'config.yaml.template' or by calling the test script with its cli arguments.

+ + \ No newline at end of file diff --git a/standards/scs-0210-v2-k8s-version-policy/index.html b/standards/scs-0210-v2-k8s-version-policy/index.html new file mode 100644 index 0000000000..100dc07c8b --- /dev/null +++ b/standards/scs-0210-v2-k8s-version-policy/index.html @@ -0,0 +1,91 @@ + + + + + +SCS K8S Version Policy | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS K8S Version Policy

Introduction

+

The Kubernetes project maintains multiple release versions including their patched versions. +In the project, the three most recent minor releases are actively maintained, with a fourth +version being in development. As soon as a new minor version is officially released, +the oldest version is dropped out of the support period. +Kubernetes supports its releases for around 14 months. 12 of these are the standard +support period. The remaining 2 months are the end-of-life support period for things like:

+
    +
  • CVEs (under the advisement of the Security Response Committee)
  • +
  • dependency issues (including base image updates)
  • +
  • critical core component issues
  • +
+

More information can be found under [Kubernetes Support Period].

+

The Kubernetes release cycle is set around 4 months, which +usually results in about 3 minor releases per year.

+

Patches to these releases are provided monthly, with the exception of the first patch, +which is usually provided 1-2 weeks after the initial release (see Patch Release +Cadence).

+

Motivation

+

Kubernetes is a living, fast-paced project, which follows a pre-defined release cycle. +This enables forward planning with regards to releases and patches, but also implies a +necessity to upgrade to newer versions quickly, since these often include new features, +important security updates or especially if a previous version falls out of the support +period window.

+

We want to achieve an up-to-date policy, meaning that providers should be mostly in +sync with the upstream and don't fall behind the official Kubernetes releases. +This is achievable, since new versions are released periodical on a well communicated +schedule, enabling providers and users to set up processes around it. +Being up to date ensures that security issues and bugs are addressed and new features +are made available when using SCS compliant clusters.

+

It is nevertheless important to at least support all Kubernetes versions that are still +inside the support period, since users could depend on specific versions or may need +longer to upgrade their workloads to a newer version.

+

The standard therefore should provide a version recency policy as well as a support +window period.

+

Decision

+

In order to keep up-to-date with the latest Kubernetes features, bug fixes and security improvements, +the provided Kubernetes versions should be kept up-to-date with new upstream releases:

+
    +
  • The latest minor version MUST be provided no later than 4 months after release.
  • +
  • The latest patch version MUST be provided no later than 1 week after release.
  • +
  • This time period MUST be even shorter for patches that fix critical CVEs. +In this context, a critical CVE is a CVE with a CVSS base score >= 8 according +to the CVSS version used in the original CVE record (e.g., CVSSv3.1). +It is RECOMMENDED to provide a new patch version in a 2 day time period after their release.
  • +
  • New versions MUST be tested before being rolled out on productive infrastructure; +at least the CNCF E2E tests should be passed beforehand.
  • +
+

At the same time, providers must support Kubernetes versions at least as long as the +official sources as described in Kubernetes Support Period:

+
    +
  • Kubernetes versions MUST be supported as long as the official sources support them +according to the Kubernetes Support Period and their end-of-life +date according to the Kubernetes Releases page.
  • +
  • It is RECOMMENDED to not support versions after this period in order to not encourage +usage of out-of-date versions.
  • +
+ +

All documents regarding versioning, releases, etc. for the official Kubernetes projects can +be found on the Kubernetes Releases page.

+

Conformance Tests

+

The script k8s_version_policy.py requires a kubeconfig file with connection details for +a set of existing Kubernetes clusters that should be checked, with each of these clusters +representing one of the currently supported upstream Kubernetes releases. +It will check the encountered cluster versions according to the rules of this standard. +Rule violations will be reported on various logging channels: ERROR for mandatory rules +and INFO for recommended rules. +The script will exit with a non-zero status if a mandatory rule has been violated or if +the test could not be performed.

+ + \ No newline at end of file diff --git a/standards/scs-0211-v1-kaas-default-storage-class/index.html b/standards/scs-0211-v1-kaas-default-storage-class/index.html new file mode 100644 index 0000000000..f6b50710f6 --- /dev/null +++ b/standards/scs-0211-v1-kaas-default-storage-class/index.html @@ -0,0 +1,61 @@ + + + + + +SCS KaaS default storage class | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS KaaS default storage class

Introduction

+

Cluster consumers can request persistent storage via PersistentVolumeClaims which is provisioned automatically by cloud-provided automation. +Storage requirements may vary across use cases, so there is the concept of StorageClasses. StorageClasses define some set of storage properties. So, consumers can choose one of these depending on the use case.

+

Kubernetes documentation

+

Motivation

+

While often times, consumers will choose a StorageClass explicitly, usually, there is also a default StorageClass to fall back on in case it is not chosen explicitly (that is, when storageClassName is not set on the PersistentVolumeClaim).

+

This document attempts to define the properties this default StorageClass should have.

+

Decision

+

The default StorageClass is made default using the storageclass.kubernetes.io/is-default-class annotation, following Kubernetes upstream. Hence, standardizing its name is not required for the intents of this standard.

+ +
    +
  • ReadWriteOnce must be a supported access mode
  • +
  • volume must be protected against data loss due to hardware failures of a single disk or host
  • +
  • volume must not be bound to the lifecycle of a Kubernetes Node
  • +
+

Hence,

+
    +
  • ...volume must not be backed by local storage on the Kubernetes Node VM itself
  • +
  • ...volume may be backed by some kind of redundant storage within an AZ, across hosts
  • +
  • ...volume may be backed by some kind of redundant storage across AZ's
  • +
+ +
    +
  • NO fixed guarantees regarding latency/bandwidth/IOPS/...
  • +
+

Generally, customers should be able to expect low-tier performance without pricing surprises.

+ +

This document does not describe performance related properties. +This will be done in another document which is yet to be created.

+

Conformance Tests

+

TBD

+ + \ No newline at end of file diff --git a/standards/scs-0212-v1-requirements-for-container-registries/index.html b/standards/scs-0212-v1-requirements-for-container-registries/index.html new file mode 100644 index 0000000000..733d5359e6 --- /dev/null +++ b/standards/scs-0212-v1-requirements-for-container-registries/index.html @@ -0,0 +1,185 @@ + + + + + +Requirements for container registries | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Requirements for container registries

Introduction

+

A container registry is an infrastructure service to enable storing and accessing container +images. Images can be pushed to the registry by e.g. Continuous integration pipelines and +be pulled from by runtime environments like Kubernetes clusters.

+

Container registries come in various forms, e.g. publicly accessible ones like Docker Hub or +self-hosted and cloud-hosted services. The latter examples may apply various access control +mechanisms to restrict access. Both solutions offer a wide range of features that may or may not +attract potential users and CSPs.

+

Terminology

+

Cloud Service Provider (abbr. CSP) +Entity that provides scalable computing resources

+

Identity Provider (abbr. IdP) +System that creates, maintains, and manages identity information

+

Motivation

+

This standard is motivated by different use cases identified through the topics in the SCS project. +One use case would be the offering of private registries for customers by CSPs, which means that a CSP could +offer private container registries either as a service or as a provided "recipe" to deploy a private registry +utilizing the CSPs infrastructure. +Another use case would be the selection of a registry for the SCS reference implementation.

+

The idea and purpose of this document is to specify what requirements a specific technical container +registry implementation (i.e. software solution) needs to fulfill for an SCS-compliant registry.

+

Design considerations

+

There are numerous features that should be evaluated for a container registry solution. +It is important to assess the registries based on the requirements of the OSS health checks and +desired features defined by the SCS. The following two subsections show these requirements.

+

OSS health check

+

It is important to evaluate the health of a project before even evaluating the project for its feature set. +A project should therefore fulfill all OSS health checks be defined by the +OSS-Health document. +This document evaluates the health of the open-source projects that were selected from +the currently available solutions. The container registry software must fulfill all OSS +health checks defined below:

+
    +
  • Four Opens (code is fully open source, community is open and diverse, development process is open, design process is open)
  • +
  • Maturity
  • +
  • Security
  • +
  • Activity
  • +
  • Lock-in risk assessment
  • +
+

Required and desirable features check

+

A container registry provides a specific feature set, which can be mapped out against the requirements +described in this section. The registry should generally be robust (e.g. operate under heavy load) and +secure in order to be acceptable for the SCS standard. Therefore, a required and optional feature set +were defined, to which a container registry must abide and be evaluated against.

+

Required features

+
    +
  • Audit Logs +
      +
    • ability to record use in auditable logs so that activity can be traced to a single user
    • +
    +
  • +
  • Authentication of system identities +
      +
    • support for authenticating system identities like Kubernetes clusters
    • +
    • possibly support for dynamic identity tokens from some IdP
    • +
    +
  • +
  • Authentication of users +
      +
    • support for multiple authentication systems (IdM integration)
    • +
    • user and user account management
    • +
    +
  • +
  • Authorization +
      +
    • role-based access control to ensure strict access controls
    • +
    +
  • +
  • Automation +
      +
    • integration with CI/CD tools e.g. via webhooks
    • +
    +
  • +
  • Vulnerability scanning +
      +
    • reveal security vulnerabilities in container images
    • +
    +
  • +
  • Content Trust and Validation +
      +
    • verify image authenticity before running
    • +
    • image signing
    • +
    +
  • +
  • Multi-tenancy +
      +
    • container registry is able to serve multiple tenants (projects, teams, namespaces)
    • +
    • implementation on the storage level, see e.g. Keppel, which uses +multi-tenant-aware storage drivers
    • +
    +
  • +
  • Backup and restore +
      +
    • possible strategies for disaster recovery and data migration scenarios
    • +
    +
  • +
  • Monitoring +
      +
    • observability is a key feature for operating a service in production so the container registry should expose key metrics
    • +
    +
  • +
  • HA mode +
      +
    • enable the possibility of system uptime, even if a failure of some sort could occur
    • +
    +
  • +
  • Registry replication +
      +
    • replication allows users to replicate container images between registries of the same instances and between registries of different instances as well
    • +
    +
  • +
  • Proxy cache (pull-through cache) +
      +
    • Proxy cache enables the use of a container registry to proxy and cache images from a target public or private registry
    • +
    +
  • +
  • Quota management +
      +
    • ability to control resource use of components or the whole registry
    • +
    +
  • +
  • Garbage collection +
      +
    • removing blobs from the filesystem when they are no longer referenced by a manifest
    • +
    +
  • +
  • Retention policy +
      +
    • reduce the number of image tags, many of which might not be required after a given time or once a subsequent image tag has superseded them
    • +
    +
  • +
+

Desirable features

+
    +
  • Additionally supported artifacts +
      +
    • Additional artifacts that the registry is able to store in addition to OCI artifacts, e.g. Java, Node.js, or Python packages
    • +
    +
  • +
  • Integration possibilities +
      +
    • Ability to cooperate with another software solution in order to improve own feature set (e.g. integration of P2P solution for improving container image distribution (download speed and stability, high scalability, ...))
    • +
    +
  • +
  • Deployment capabilities +
      +
    • ways to deploy a container registry (only "official" ways are mentioned)
    • +
    +
  • +
  • Administration capabilities "as a code" +
      +
    • ability to manage container registry via "as a code" solutions, e.g. Ansible role
    • +
    +
  • +
+

Standard

+

It is very unlikely, that every Container registry can fulfill every requirement defined by this document, and probably +not all deployments require every feature listed here. The required feature set should therefore be carefully considered +by the provider of the registry. We nevertheless RECOMMEND using most of the feature set provided in this document.

+

If the features mentioned above are all considered, a possible registry solution SHOULD fulfill the majority of +the required features. But this is again dependent on the specific use case and the surrounding architecture.

+ +

OSS-Health

+ + \ No newline at end of file diff --git a/standards/scs-0213-v1-k8s-nodes-anti-affinity/index.html b/standards/scs-0213-v1-k8s-nodes-anti-affinity/index.html new file mode 100644 index 0000000000..f5935d8918 --- /dev/null +++ b/standards/scs-0213-v1-k8s-nodes-anti-affinity/index.html @@ -0,0 +1,140 @@ + + + + + +Kubernetes Nodes Anti Affinity | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Kubernetes Nodes Anti Affinity

Introduction

+

A Kubernetes instance is provided as a cluster, which consists of a set of worker machines, +so called nodes. A cluster is composed of a control plane and at least one worker node. +The control plane manages the worker nodes and therefore the pods in the cluster by making +decisions about scheduling, event detection and global decisions. Inside the control plane, +multiple components exist, which can be duplicated and distributed over multiple machines +inside the cluster. Typically, no user containers are run on these machines in order to +separate the control plane from the live system.

+

Glossary

+

The following special terms are used throughout this decision record document:

+
TermMeaning
WorkerVirtual or bare-metal machine, which hosts workloads of customers
Control PlaneVirtual or bare-metal machine, which hosts the container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers.
MachineVirtual or bare-metal entity with computational capabilities
+

Motivation

+

In a productive environment, the control plane usually runs across multiple machines and +a cluster usually contains multiple worker nodes in order to provide fault-tolerance and +high availability.

+

In order to ensure availability and scaling of workloads, even if some nodes in the cluster +could fail, they should be distributed over multiple nodes on different machines. +This can be steered with the Affinity or Anti Affinity features, which are separated by +Kubernetes into two features:

+

Node Affinity +The Node Affinity feature allows to match pods according to logical matches of +key-value-pairs referring to labels of nodes. +These can be defined with different weights or preferences in order to allow fine-grained +selection of nodes. The feature works similar to the Kubernetes nodeSelector. +It is defined in the PodSpec using the nodeAffinity field in the affinity section.

+

Pod Affinity +Pod Affinity or Pod Anti Affinity allows the constraint of pod scheduling based on the +labels of pods already running on a node. +This means the constraint will match other pods on a node according to their labels key-value-pairs +and then either schedule the pod to the same (Affinity) or another (Anti Affinity) node. +This feature is also defined in the PodSpec using the podAffinity and podAntiAffinity +fields in the affinity section. [3]

+

Both features allow the usage of "required" or "preferred" keywords, which create +"hard" or "soft" affinities. By using a hard affinity, a pod would need to be scheduled +according to the rules set. If this possibility is not given, the pod can't be scheduled. +A soft affinity would allow scheduling even if the requirements are not fulfilled, but +they would be preferred if possible.

+

These features allow efficient resource usage (e.g. by scheduling workloads to evenly +distribute across nodes) and provide fault-tolerance and therefore high availability. +But they also require more work during the setup of a service architecture, since nodes +and pods need to be labelled and described consistently.

+

In the case of SCS, affinity of the workloads themselves is not relevant, since this +feature is mostly used by the customers of the providers. +Instead, the expected standard should enable the Kubernetes cluster to handle Anti Affinity +rules with a real physical separation as well as distributing the control plane over +multiple machines in order to provide fault-tolerance during system outages. +If the control plane survives an outage, a Kubernetes cluster can recover later on.

+

Design considerations

+

SCS plans to require a Hard Anti Affinity and/or Redundancy for the control plane and +a Soft Anti Affinity for workers. This means, that Anti Affinity would be required for +the control planes and their pods and only optional (but encouraged) for workers.

+

In order to achieve the goals for these components, meaning availability and fault tolerance +for the control plane, an outage resistant cluster, and the availability +promise given with Anti Affinity for pods on the worker nodes, a separation of nodes +on the hardware level would need to be achieved.

+

For the control plane, a reference to the "Kubernetes High Availability" [1] +can be useful, since it provides two ways to set up a highly available cluster. +Both approaches are very similar. The "Stacked Control Plane" [2] requires less infrastructure, +but also runs the risk of failed coupling, where if one node fails, the redundancy could be +compromised due to the loss of a complete control plane instance. +The "External ETCD" solves this problem, but also requires double the infrastructure, due +to the externally incorporated etcd clusters.

+

This also shows, that the wording "anti affinity" as used with Kubernetes pods is probably +slightly misleading in the context of a Kubernetes control plane. It may consist of multiple +pods with individual tasks, but distributing them over different nodes through Anti Affinity +would probably still cascade the whole control plane into a complete failure, if one of +the used nodes goes down. It could be possible to replicate specific important pods and +assign them to different nodes, but at this point, a redundant setup like presented in [1] could be used. +So Anti Affinity in this context probably means more like distribution over multiple +physical machines, which needs to be planned beforehand on the machine/server level.

+

Therefore would it be preferred for the control plane to use a redundant setup, which +is separated over different physical machines, meaning at least half of the control plane +nodes runs on a different physical machine as the rest. The currently used ClusterAPI +enables this by establishing the concept of "failure domains". These are used to control +the placement of k8s nodes and distribute them over multiple physical machines. +For example, a High Availability K8s cluster with three control plane nodes could be +distributed over three different availability zones (and therefore 3 different +physical machines) in order to survive the failure of one availability zone. [5]

+

For worker nodes, the whole idea of Anti Affinity is more of a preferable situation. +The nodes themselves should at best be distributed over different machines, but this +is not a requirement, especially since smaller providers wouldn't have the capacity to +provide enough machines for these distributed Kubernetes clusters. Since customers that +use the Affinity or Topology spread constraint [4] features would be especially interested +in the worker nodes that host their workloads, it should be ensured that a good labeling +system is provided for the nodes in order to see if two nodes are hosted on the same machine.

+

Decision

+

The future standard should define a few important things in order to provide a solid base +for the usage and advantages of workloads with Anti Affinity rules.

+

Control planes SHOULD be made redundant in order to provide fault-tolerance and security +against fatal errors on this layer, in the case of node failures. How this redundancy +is achieved SHOULD be left to the providers, but since failure must be avoided, it is +REQUIRED to at least duplicate control plane components. Half of every component SHOULD +be located on a different node on a different physical machine than the other half +of them. This should provide at least the minimum requirements for a fault-tolerant control plane. +For the standard, there is also a possibility to define multiple stages of distributed infrastructure +and only make sensible ones a requirement and the rest optional, e.g.

+
    +
  • non-distributed clusters
  • +
  • High-Availability clusters that are +
      +
    • distributed over multiple machines/availability zones
    • +
    • distributed over multiple clouds
    • +
    • distributed over multiple physical locations/datacenters
    • +
    +
  • +
+

The worker nodes are RECOMMENDED to be distributed over different machines. In order to +provide clear information to the users, the nodes should be labeled to reflect the +mapping to the underlying clusters. The labels can be obfuscated in order to not reveal +the underlying structures to customers and users. It should be noted, that it is NOT REQUIRED +to have this anti affinity for the worker nodes due to the requirements of infrastructure +and complexity associated with this.

+

Documents

+

Kubernetes High Availability Documentation 1 +Kubernetes High Availability - Stacked ETCD 2 +Affinity and Anti-Affinity 3 +Topology Spread Constraints 4 +SCS Multi AZ and Multi Cloud Environments 5

+ + \ No newline at end of file diff --git a/standards/scs-0214-v1-k8s-node-distribution/index.html b/standards/scs-0214-v1-k8s-node-distribution/index.html new file mode 100644 index 0000000000..7f84264094 --- /dev/null +++ b/standards/scs-0214-v1-k8s-node-distribution/index.html @@ -0,0 +1,86 @@ + + + + + +Kubernetes Node Distribution and Availability | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Kubernetes Node Distribution and Availability

Introduction

+

A Kubernetes instance is provided as a cluster, which consists of a set of machines, +so-called nodes. A cluster is composed of a control plane and at least one worker node. +The control plane manages the worker nodes and therefore the pods in the cluster by making +decisions about scheduling, event detection and rights management. Inside the control plane, +multiple components exist, which can be duplicated and distributed over multiple nodes +inside the cluster. Typically, no user workloads are run on these nodes in order to +separate the controller component from user workloads, which could pose a security risk.

+

Glossary

+

The following terms are used throughout this document:

+
TermMeaning
WorkerVirtual or bare-metal machine, which hosts workloads of customers
Control PlaneVirtual or bare-metal machine, which hosts the container orchestration layer that exposes the API and interfaces to define, deploy, and manage the lifecycle of containers.
MachineVirtual or bare-metal entity with computational capabilities
+

Motivation

+

In normal day-to-day operation, it is not unusual for some operational failures, either +due to wear and tear of hardware, software misconfigurations, external problems or +user errors. Whichever was the source of such an outage, it always means down-time for +operations and users and possible even data loss. +Therefore, a Kubernetes cluster in a productive environment should be distributed over +multiple "failure zones" in order to provide fault-tolerance and high availability. +This is especially important for the control plane of the cluster, since it contains the +state of the whole cluster. A failure of this component could mean an unrecoverable failure +of the whole cluster.

+

Design Considerations

+

Most design considerations of this standard follow the previously written Decision Record +Kubernetes Nodes Anti Affinity as well as the Kubernetes documents about +High Availability and Best practices for large clusters.

+

SCS wishes to prefer distributed, highly-available systems due to their obvious advantages +like fault-tolerance and data redundancy. But it also understands the costs and overhead +for the providers associated with this effort, since the infrastructure needs to have +hardware which will just be used to provide fail-over safety or duplication.

+

The document Best practices for large clusters describes the concept of a failure zone. +This term isn't defined any further, but can in this context be described as a number of +physical (computing) machines in such a vicinity to each other (either through physical +or logical interconnection in some way), that specific problems inside this zone would put +all these machines at risk of failure/shutdown. It is therefore necessary for important +data or services to not be present just on one failure zone. +How such a failure zone should be defined is dependent on the risk model of the service/data +and its owner as well as the capabilities of the provider. Zones could be set from things +like single machines or racks up to whole datacenters or even regions, which could be +coupled by things like electrical grids. They're therefore purely logical entities, which +shouldn't be defined further in this document.

+

Decision

+

This standard formulates the requirement for the distribution of Kubernetes nodes in order +to provide a fault-tolerant and available Kubernetes cluster infrastructure. +Since some providers only have small environments to work with and therefore couldn't +comply with this standard, it will be treated as a RECOMMENDED standard, where providers +can OPT OUT.

+

If the standard is used by a provider, the following decisions are binding and valid:

+
    +
  • The control plane nodes MUST be distributed over multiple physical machines. Kubernetes +provides best-practices on this topic, which are also RECOMMENDED by SCS.
  • +
  • At least one control plane instance MUST be run in each "failure zone", more are +RECOMMENDED in each "failure zone" to provide fault-tolerance for each zone.
  • +
  • Worker nodes are RECOMMENDED to be distributed over multiple zones. This policy makes +it OPTIONAL to provide a worker node in each "failure zone", meaning that worker nodes +can also be scaled vertically first before scaling horizontally.
  • +
  • Worker node distribution MUST be indicated to the user through some kind of labeling +in order to enable (anti)-affinity for workloads over "failure zones".
  • +
+

Conformance Tests

+

The script k8s-node-distribution-check.py checks the nodes available with a user-provided +kubeconfig file. It then determines based on the labels kubernetes.io/hostname, topology.kubernetes.io/zone, +topology.kubernetes.io/region and node-role.kubernetes.io/control-plane, if a distribution +of the available nodes is present. If this isn't the case, the script produces an error. +If also produces warnings and informational outputs, if e.g. labels don't seem to be set.

+ + \ No newline at end of file diff --git a/standards/scs-0215-v1-robustness-features/index.html b/standards/scs-0215-v1-robustness-features/index.html new file mode 100644 index 0000000000..22de9dc957 --- /dev/null +++ b/standards/scs-0215-v1-robustness-features/index.html @@ -0,0 +1,207 @@ + + + + + +Robustness features for Kubernetes clusters | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Robustness features for Kubernetes clusters

Introduction

+

Kubernetes clusters in a productive environment are under the assumption to always perform perfectly without any major +interruptions. But due to external or unforeseen influences, clusters can be disrupted in their normal workflow, which +could lead to slow responsiveness or even malfunctions. +In order to possibly mitigate some problems for the Kubernetes clusters, robustness features should be introduced into +the SCS standards. These would harden the cluster infrastructure against several problems, making failures less likely.

+

Glossary

+

The following special terms are used throughout this standard document:

+
TermAbbreviationMeaning
Certificate AuthorityCATrusted organization that issues digital certificates entities
Certificate Signing RequestCSRRequest in order to apply for a digital identity certificate
+

Motivation

+

A typical productive Kubernetes cluster could be hardened in many different ways, whereas probably many of these actions +would overlap and target similar weaknesses of a cluster. +For this version of the standard, the following points should be addressed:

+
    +
  • Kube-API rate limiting
  • +
  • etcd compaction/defragmentation
  • +
  • etcd backup
  • +
  • Certificate Authority (CA) expiration avoidance
  • +
+

These robustness features should mainly increase the up-time of the Kubernetes cluster by avoiding downtimes either +because of internal problems or external threads like "Denial of Service" attacks. +Additionally, the etcd database should be strengthened with these features in order to provide a secure and robust +backend for the Kubernetes cluster.

+

Design Considerations

+

In order to provide a conclusive standard, some design considerations need to be set beforehand:

+

Kube-API rate limiting

+

Rate limiting is the practice of preventing too many requests to the same server in some time frame. This can help prevent +service interruptions due to congestion and therefore slow responsiveness or even service shutdown. +Kubernetes suggests multiple ways to integrate such a Ratelimit for its API server, a few of which will be mentioned here. +In order to provide a useful Ratelimit for the Kubernetes cluster, combination of these methods should be considered.

+

API server flags

+

The Kubernetes API server has some flags available to limit the amount of incoming requests that will be accepted by +the server, which should prevent crashing of the API server. This nevertheless shouldn't be the only measure to +introduce a rate limit, since important requests could get blocked during high traffic periods (at least according to +the official documentation). +The following controls are available to tune the server:

+
    +
  • max-requests-inflight
  • +
  • max-mutating-requests-inflight
  • +
  • min-request-timeout
  • +
+

More details can be found in the following documents: +Flow Control

+

Ratelimit Admission Controller

+

From version 1.13 onwards, Kubernetes includes a EventRateLimit Admission Controller, which aims to mitigate Ratelimit +problems associated with the API server by providing limits for requests every second either to specific resources or +even the whole API server. If requests are denied due to this Admission Controller, they're either cached or denied +completely and need to be retried; this also depends on the EventRateLimit configuration. +More details can be found in the following documents: +Rancher rate limiting +EventRateLimit +It is important to note, that this only helps the API server against event overloads and not necessarily the network +in front of it, which could still be overwhelmed.

+

Flow control

+

Flow control for the Kubernetes API server can be provided by the API priority and fairness feature, which classifies +and isolates requests in a fine-grained way in order to prevent an overload of the API server. +The package introduces queues in order to not deny requests and dequeue them through Fair Queueing techniques. +Overall, the Flow control package introduces many different features like request queues, rule-based flow control, +different priority levels and rate limit maximums. +The concept documentation offers a more in-depth explanation of the feature: +Flow Control

+

etcd maintenance

+

etcd is a strongly consistent, distributed key-value store that provides a reliable way to store data that needs to be +accessed by a distributed system or cluster of machines. For these reasons, etcd was chosen as the default database +for Kubernetes. +In order to remain reliable, an etcd cluster needs periodic maintenance. This is necessary to maintain the etcd keyspace; +failure to do so could lead to a cluster-wide alarm, which would put the cluster into a limited-operation mode. +To mitigate this scenario, the etcd keyspace can be compacted. Additionally, an etcd cluster can be defragmented, which +gives back disk space to the underlying file system and can help bring the cluster back into an operable state, if it +ran out of space earlier.

+

etcd keyspace maintenance can be achieved by providing the necessary flags/parameters to etcd, either via the KubeadmControlPlane or in the +configuration file of the etcd cluster, if it is managed independent of the Kubernetes cluster. +Possible flags, that can be set for this feature, are:

+
    +
  • auto-compaction-mode
  • +
  • auto-compaction-retention
  • +
+

More information about compaction can be found in the respective etcd documentation +etcd maintenance

+

etcd backup

+

An etcd cluster should be regularly backed up in order to be able to restore the cluster to a known good state at an +earlier space in time if a failure or incorrect state happens. +The cluster should be backed up multiple times in order to have different possible states to go back to. This is especially +useful, if data in the newer backups was already corrupted in some way or important data was deleted in them. +For this reason, a backup strategy needs to be developed with a decreasing number of backups in an increasing period of time, +meaning that the previous year should only have 1 backup, but the current week should have multiple. +Information about the backup process can be found in the etcd documentation: +Upgrade etcd

+

Certificate rotation

+

In order to secure the communication of a Kubernetes cluster, (TLS) certificates signed by a controlled +Certificate Authority (CA) can be used. +Normally, these certificates expire after a set period of time. In order to avoid expiration and failure of a cluster, +these certificates need to be rotated regularly and at best automatically. +Certificates can either be rotated manually (a reference for manually working with certificates can be found +here) +or automatically, which requires other things to care about in a deployment.

+

Some tools or clusters provide possibilities to rotate certificates manually. +For example, kubeadm and k3s provides the following commands

+
# kubeadm
kubeadm certs renew all

# k3s
k3s certificate rotate
+

A CA might also expire. Unfortunately, not all Kubernetes tools have functionality to renew these certificates. +Instead, documentation is provided to manually rotating a CA ([Manual rotation of ca certificate]).

+

Automatic certificate rotation

+

kubelet can be configured to obtain properly signed certificates from the certificates.k8s.io API of Kubernetes. +To do this, set serverTLSBootstrap: true in the configuration file of kubelet, which enables both the certificate request +during bootstrapping and the rotation mechanism. Setting rotateCertificates: true only enables the certificate rotation [Kubeadm certs]. +--rotate-certificates or --rotate-server-certificates shouldn't be used as command line arguments to set these flags, +since both parameters are deprecated according to [Certificate rotation].

+

It is also important to note that some Kubernetes clusters or admin tools provide additional ways to rotate certificates. +For example, kubeadm automatically rotates certificates, if the cluster is updated with the tool (see [Automatic Certificate renewal]). +This would also mean, that at least kubeadm-based clusters can be assumed to rotate their certificates regularly, +since they would probably be updated within the time period described in the +standard SCS-0210-v2.

+

If an automatic certificate rotation happens, these certificates need to be approved either manually or by a third party +controller like the kubelet csr approver, which can be deployed on +a Kubernetes cluster to automate this process.

+

A manual approval of these CSRs could be done with the commands

+
kubectl get csr
kubectl certificate approve <CSR>
+

in order to complete a certificate rotation. +But it should be noted, that this is also most likely dependent on the Kubernetes cluster solution in use.

+

kubectl get csr allows to check, if a CSR needs to be approved; a Pending CSR would need to be approved.

+
NAME        AGE     SIGNERNAME                        REQUESTOR                      CONDITION
csr-9wvgt 112s kubernetes.io/kubelet-serving system:node:worker-1 Pending
+

Further information and examples can be found in the Kubernetes documentation: +Kubeadm certs +Kubelete TLS bootstrapping

+

Decision

+

Robustness features combine multiple aspects of increasing the security, hardness and +longevity of a Kubernetes cluster. The decisions will be separated into their respective +areas.

+

Kube-API rate limiting

+

The number of requests send to the kube-api or Kubernetes API server MUST be limited +in order to protect the server against outages, deceleration or malfunctions due to an +overload of requests. +In order to do so, at least the following parameters MUST be set on a Kubernetes cluster:

+
    +
  • max-requests-inflight
  • +
  • max-mutating-requests-inflight
  • +
  • min-request-timeout
  • +
+

Values for these flags/parameters SHOULD be adapted to the needs of the environment and +the expected load.

+

A cluster MUST also activate and configure a Ratelimit admission controller. +This requires an EventRateLimit resource to be deployed on the Kubernetes cluster. +The following settings are RECOMMENDED for a cluster-wide deployment, but more +fine-grained rate limiting can also be applied, if this is necessary.

+
kind: Configuration
apiVersion: eventratelimit.admission.k8s.io/v1alpha1
limits:
- burst: 20000
qps: 5000
type: Server
+

It is also RECOMMENDED to activate the Kubernetes API priority and fairness feature, +which also uses the aforementioned cluster parameters to better queue, schedule and +prioritize incoming requests.

+

etcd compaction

+

etcd MUST be cleaned up regularly, so that it functions correctly and doesn't take +up too much space, which happens because of its increase of the keyspace.

+

To compact the etcd keyspace, the following flags/parameters MUST be set for etcd:

+
    +
  • auto-compaction-mode = periodic
  • +
  • auto-compaction-retention = 8h
  • +
+

etcd backup

+

An etcd cluster MUST be backed up regularly. It is RECOMMENDED to adapt +a strategy of decreasing backups over longer time periods, e.g. keeping snapshots every +10 minutes for the last 120 minutes, then one hourly for 1 day, then one daily for 2 weeks, +then one weekly for 3 months, then one monthly for 2 years, and after that a yearly backup. +At the very least, a backup MUST be done once a week. +These numbers can be adapted to the security setup and concerns like storage or network +usage. It is also RECOMMENDED to encrypt the backups in order to secure them further. +How this is done is up to the operator.

+

Certificate rotation

+

It should be avoided, that certificates expire either on the whole cluster or for single components. +To avoid this scenario, certificates MUST be rotated regularly; in the +case of SCS, we REQUIRE at least a yearly certificate rotation.

+

It is also RECOMMENDED to renew the CA regularly to avoid an expiration of the CA. +This standard doesn't set an exact timeline for a renewal, since it is dependent on lifetime and +therefore expiration date of the CA in question.

+ +

Flow Control +Rate limiting +EventRateLimit +etcd maintenance +Upgrade etcd +Kubeadm certs +Kubelet TLS bootstrapping +Certificate rotation +Manual rotation of ca certificate +Automatic Certificate renewal

+

Conformance Tests

+

Conformance Tests, OPTIONAL

+ + \ No newline at end of file diff --git a/standards/scs-0216-v1-requirements-for-testing-cluster-stacks/index.html b/standards/scs-0216-v1-requirements-for-testing-cluster-stacks/index.html new file mode 100644 index 0000000000..4e50e1d18d --- /dev/null +++ b/standards/scs-0216-v1-requirements-for-testing-cluster-stacks/index.html @@ -0,0 +1,129 @@ + + + + + +Requirements for testing cluster-stacks | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Requirements for testing cluster-stacks

Introduction

+

In this proposal, we discuss the necessity and design considerations of a lightweight solution for testing cluster-stacks. The purpose is to address the challenges associated with testing on an Infrastructure as a Service (IaaS) provider and the limitations of using Docker as the primary containerization tool for testing. This proposal will elaborate on why we need to test in a local environment, specifically a laptop, and the benefits and drawbacks associated with it. We aim to make an informed decision for testing cluster stacks to cater to both the organizational and technical perspectives of our stakeholders.

+

Motivation

+

From an organization's point of view, it is crucial to lower the entry barrier for testing. This action will make it possible for anyone, including external contributors, to easily participate in the testing process without needing an account with the IaaS provider. It is also necessary to overcome the hurdles associated with maintaining a balance in the provider account and managing sponsorships to fund the testing.

+

From a technical standpoint, there are multiple reasons to favor a local environment for testing. Among them is the ability to test without internet, finish tests in a shorter timeframe, and incur no cost. The provider independence of Cluster Stacks makes it nonsensical to test with a specific provider due to the varied behaviors of different providers. There are also challenges in monitoring and debugging tests run on IaaS providers and dealing with their downtime and limitations on concurrent testing.

+

Design Considerations

+
    +
  1. +

    Lightweight Solution +The testing solution should be lightweight and easy to use in a local environment, such as a laptop. This lightweight solution should minimize dependencies and resource usage while maximizing speed and efficiency of the tests. It should be capable of handling the cluster-stack testing requirements without necessitating a bulky or resource-intensive setup.

    +
  2. +
  3. +

    Independence from Specific Providers +The solution should be generalized and not bound to any specific provider. This consideration ensures that the solution can be applied to any provider, guaranteeing its versatility and broad applicability.

    +
  4. +
  5. +

    Offline Testing +The testing solution should support testing without internet connection, which will enable more robust and flexible testing scenarios. It should be possible to run the tests even in cases of limited or disrupted internet access.

    +
  6. +
  7. +

    Fast Execution Time +The tests should execute within a reasonably short amount of time. The solution must be optimized to ensure quick testing cycles, which can help increase productivity and shorten development cycles.

    +
  8. +
  9. +

    No-Cost Solution +The solution should not impose any additional costs on the organization or individual testers. This characteristic is crucial to enable widespread adoption of the testing process and to lower the entry barrier for contributors.

    +
  10. +
  11. +

    Easy Monitoring and Debugging +The solution should provide easy monitoring and debugging capabilities. It should allow developers to quickly identify, diagnose, and fix issues that arise during testing, without requiring access to any external logs or monitoring tools.

    +
  12. +
  13. +

    Concurrent Testing +The solution should support the ability to run concurrent tests without causing any disruption or downtime. This ability can improve the efficiency and speed of the testing process.

    +
  14. +
+

Required Features

+

The proposed solution should meet the following feature requirements:

+
    +
  1. Local Environment: The solution should support a local testing environment that allows developers to test cluster stacks on their local machines, reducing dependencies on external providers.
  2. +
  3. Compatibility: The solution should be compatible with various operating systems and platforms, ensuring its usability across diverse environments.
  4. +
  5. Performance: The solution should offer high-performance testing capabilities, allowing fast execution of tests.
  6. +
  7. Offline Support: The solution should allow testing in offline mode, ensuring tests can be performed even without an internet connection.
  8. +
  9. Concurrency: The solution should support running multiple tests concurrently without causing disruptions or conflicts.
  10. +
  11. Monitoring & Debugging: The solution should provide easy-to-use tools for monitoring test progress and debugging issues.
  12. +
  13. Cost-effectiveness: The solution should not require any financial investment from the testers or the organization, promoting broad accessibility and usage.
  14. +
+

Pros and Cons of Different Approaches

+

Two potential approaches for testing cluster stacks are the use of an IaaS provider and the use of a local environment. Here we discuss the pros and cons of these two approaches.

+

IaaS Provider (OpenStack, Hetzner, AWS)

+

Pros

+
    +
  • Comprehensive testing environment with advanced capabilities.
  • +
  • Possibility to mimic real-world production environments closely.
  • +
+

Cons

+
    +
  • Requires signing up and account management, which can be a barrier for some testers.
  • +
  • Requires maintaining a balance in the provider account, which can pose financial burdens.
  • +
  • Internet dependency for testing.
  • +
  • Potential for prolonged testing time due to various dependencies.
  • +
  • Challenges with monitoring and debugging.
  • +
  • Potential downtime and difficulty in running concurrent tests.
  • +
+

Local Environment (Docker, Kubevirt)

+

Pros

+
    +
  • Faster test execution with no downtime.
  • +
  • Ability to test without internet.
  • +
  • Independent of any provider knowledge.
  • +
  • Cost-free testing.
  • +
  • Easier integration into CI/CD.
  • +
  • Simplified monitoring and debugging.
  • +
+

Cons

+
    +
  • Limited systemd support and containerd support for kubeadm in Docker.
  • +
  • Inability to mimic the exact real-world production environments.
  • +
+

Beyond Docker: Virtual Machine based Approach

+

While Docker provides significant benefits for local environment testing, it's important to recognize its limitations. Docker containers, by design, are lightweight and don't contain a full operating system which can lead to challenges when trying to mimic real-world production environments. Also, Docker containers lack some necessary features like systemd which is used in many production environments for initializing and managing services.

+

One major aspect that Docker lacks is the ability to mimic real-world production environments effectively. This is primarily due to its nature as a containerization tool, operating within the host OS, and sharing resources among its containers. This might create disparities in behavior when comparing to deployments on real, isolated systems, which could be problematic in some scenarios.

+

Furthermore, Docker utilizes a Union File System for its images, leading to the creation of layers. This approach can lead to some complexities when dealing with node-images which comprise a significant chunk of our layers. Handling such situations might require workarounds that could add additional complexity and potential points of failure. This creates a blind spot, as real providers won't require these workarounds, which might lead to disparities in results when comparing testing in local and actual production environments.

+

Therefore, to achieve a more accurate representation of real-world environments, we propose a solution that utilizes a virtual machine based approach for local testing. This approach could leverage tools like KubeVirt, Vagrant, or VirtualBox to create and manage virtual machines on the local environment. This strategy would provide a more robust and realistic environment for testing, as it can better emulate the behavior of a full-fledged operating system and thereby more closely mimic a real-world production environment.

+

Virtual Machine Based Approach

+

Pros

+
    +
  • Provides a more accurate representation of real-world production environments.
  • +
  • Allows for full operating system emulation, including features like systemd.
  • +
  • Can create isolated environments, thereby mimicking actual deployments better than containers.
  • +
+

Cons

+
    +
  • Potentially more resource-intensive than container-based solutions.
  • +
  • Increased complexity due to the need for managing full virtual machines rather than lightweight containers.
  • +
  • Initial setup might be more complicated compared to a Docker-based solution.
  • +
+

Proposed Path Forward

+

Given the limitations of Docker and the potential advantages of a virtual machine based approach, we propose to investigate further into this strategy. The exact tool or set of tools used can be determined based on a thorough evaluation of the available options.

+

Although there might be some initial complexity and potentially higher resource usage compared to Docker, we believe that the benefits of more accurate testing and better emulation of real-world environments outweigh these potential disadvantages.

+

The proposed solution should meet all the requirements mentioned in the previous sections of the proposal, in addition to providing the benefits of a virtual machine based approach. By doing so, we aim to establish a robust, reliable, and realistic testing environment for cluster stacks that mimics real-world production environments as closely as possible.

+

Conclusion

+

After thoroughly examining the organizational needs, technical requirements, and potential testing approaches, it is evident that testing cluster stacks in a local environment provides significant advantages over using an Infrastructure as a Service (IaaS) provider. A local environment minimizes financial constraints, reduces testing time, offers offline capabilities, and enables greater tester participation without the need for specialized IaaS knowledge.

+

While Docker stands out for its broad adoption, cost-effectiveness, and impressive containerization benefits, it also presents some limitations that cannot be overlooked. The lack of full operating system emulation and certain system features like systemd pose challenges to mimic real-world production environments accurately.

+

Given Docker's limitations and the need to reproduce realistic testing scenarios, we propose moving beyond Docker to a virtual machine-based approach. Even though this approach may introduce initial complexity and potentially higher resource usage, it promises a more accurate representation of real-world environments, thereby ensuring more reliable and robust test results.

+

Tools such as KubeVirt, Vagrant, or VirtualBox could potentially fulfill our requirements, offering benefits such as full operating system emulation and isolated environments. However, an in-depth evaluation of these and possibly other tools is necessary to determine the best path forward.

+

In conclusion, our goal is to design a robust, reliable, and realistic testing environment for cluster stacks that closely mimics real-world production environments, aligns with our organizational and technical perspectives, and ensures a low entry barrier for all testers. Embracing a virtual machine-based approach for local environment testing represents a promising strategy to achieve this objective, paving the way for more efficient and reliable cluster stack testing.

+ + \ No newline at end of file diff --git a/standards/scs-0217-v1-baseline-cluster-security/index.html b/standards/scs-0217-v1-baseline-cluster-security/index.html new file mode 100644 index 0000000000..6a528d2ff0 --- /dev/null +++ b/standards/scs-0217-v1-baseline-cluster-security/index.html @@ -0,0 +1,117 @@ + + + + + +Kubernetes cluster baseline security | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Kubernetes cluster baseline security

Introduction

+

Due to the regular changes and updates, there are always new security features to deploy and use in Kubernetes. +Nevertheless, a provider (or even a customer) needs to take action in order to achieve a +hardened, secure cluster due to the myriad of configurations possible. This is especially +the case since Kubernetes ships with insecure features and configurations out of the box, +which will need to be mitigated by an administrator with the proper knowledge. +Hardened, secure Kubernetes clusters are desirable regardless of the possible threat model, +since higher security doesn't necessarily mean higher complexity in this case.

+

Terminology

+
TermMeaning
TLSTransport Layer Security
CACertificate Authority
CSRCertificate Signing Request
+

Motivation

+

Kubernetes clusters are highly configurable, which also gives rise to different security +problems, if the configuration isn't done properly. +These security risks can potentially be exposed in many different parts of a cluster, e.g. +different APIs, authorization and authentication procedures or even Pod privilege mechanisms. +In order to mitigate these problems, different steps and mechanisms could be used to increase +the security of a Kubernetes setup.

+

Design Considerations

+

External CA

+

Kubernetes provides an API to provision TLS certificates that can be signed by a CA. +This CA can be controlled by the cluster provider, which enables much more tight control +over the clusters communication and therefore also better controllable security.

+

In order to do this, the CA certificate bundle needs to be added to the trusted certificates +of the server. +To provide a certificate, the following steps need to be undertaken:

+
    +
  1. Create a CSR
  2. +
  3. Send the CSR manifest to the k8s API
  4. +
  5. Approve the CSR
  6. +
  7. Sign CSR with your CA
  8. +
  9. Upload the signed certificate to the server
  10. +
+

This certificate could now be used by a user in a pod in order to provide a trusted certificate.

+

It is also possible for the Kubernetes controller manager to provide the signing functionality. +To enable this, --cluster-signing-cert-file and --cluster-signing-key-file need to be set with +a reference to the CA keypair, which was used in the previous example to sign a CSR.

+

Protected Kubernetes endpoints

+

In order to secure a Kubernetes cluster, the protection of endpoints is important. +To do this, different approaches can be taken.

+

TLS for all internal/API traffic

+

It is already expected by Kubernetes that all API communication internally is encrypted with TLS. +Nevertheless, some endpoints of internal components could be/will be exposed without the necessary +encryption, which could lead to weak points in the system. +A list of the default service endpoints can be seen in the following table

+
ProtocolPort RangePurposeNotes
TCP6443*Kubernetes API Server-
TCP2379-2380etcd server client API-
TCP10250Kubelet API-
TCP10251/10259kube-scheduler10251 could be insecure before 1.13, after that only the secure port 10259 is available
TCP10252/10257kube-controller-manager10252 could be insecure before 1.13, after that only the secure port 10257 is available
TCP30000-32767NodePort ServicesService endpoints, could be HTTP
+

The usage of readOnlyPort (enabling a read-only Kubelet API port on 10255) by design neither provides authentication nor authorization. Its usage is strongly discouraged!

+

Authentication and Authorization

+

All API clients should authenticate and authorize in order to be able to access an API or even +specific functions of this API. This is the case for users as well as internal components.

+

Most internal clients (like proxies or nodes) are typically authenticated via service accounts or +x509 certificates, which will normally be created automatically during the setup of a cluster. +External users can authenticate via an access pattern of choice, which is typically decided by +the cluster provider.

+

Authorization is (normally) done by the Role-Based Access Control (RBAC), which matches a request +by a user with a set of permissions, also called a role. Kubernetes deploys some roles out-of-the-box; +additional roles need to be carefully checked, since some permissions for specific resources allow +modification of other resources.

+

This whole process is especially important for the Kubelet, which allows anonymous requests in its +default configuration. This is obviously a security risk, since everybody with access to its endpoint +could manipulate resources that are managed with the Kubelet.

+

To disable anonymous requests, the Kubelet should be started with --anonymous-auth=false. +Authentication can be provided either through x509 client certificates or API bearer tokens. +How to set up both approaches can be found in the Kubelet Authentication and Authorization.

+

Kubelet authorization is set to AlwaysAllow as a default mode. This can be quite problematic, +since all authenticated users can do all actions. To mitigate this, it is possible to delegate +authorization to the API server by:

+
    +
  • enabling the authorization.k8s.io/v1beta1 API group
  • +
  • starting the Kubelet with the --authorization-mode=Webhook and the --kubeconfig flags
  • +
+

After that, the Kubelet calls the SubjectAccessReview API in order to determine the authorization of a request.

+

Decision

+

This standard tries to increase security for a Kubernetes cluster in order to provide a +solid baseline setup with regard to security. For this to work, multiple measures need to be undertaken.

+

A self-controlled CA SHOULD be used in order to be in control of the TLS certificates, which +enables operators to provide and revoke certificates according to their own requirements.

+

All internal endpoints found in the section [TLS for all internal/API traffic] MUST be +encrypted with TLS in order to secure internal traffic.

+

The Kubernetes API (kubeAPI) MUST be secured by authenticating and authorizing the users +trying to access its endpoints. How a user is authenticated is up to the provider of the +cluster and/or the wishes of the customer. Authorization MUST be done by providing fine-grained RBAC. +The authentication and authorization steps MUST also be applied to the Kubelet, which in its default configuration +doesn't enable them. A way to do this can be found in the section [Authentication and Authorization].

+ + +

Conformance Tests

+

Conformance Tests will be written in another issue

+ + \ No newline at end of file diff --git a/standards/scs-0218-v1-container-registry-for-scs-standard-implementation/index.html b/standards/scs-0218-v1-container-registry-for-scs-standard-implementation/index.html new file mode 100644 index 0000000000..cf8ea9f217 --- /dev/null +++ b/standards/scs-0218-v1-container-registry-for-scs-standard-implementation/index.html @@ -0,0 +1,335 @@ + + + + + +Container registry for SCS standard implementation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Container registry for SCS standard implementation

Introduction

+

A container registry is an infrastructure service to enable storing and accessing container +images. Images can be pushed to the registry by e.g. Continuous integration pipelines and +be pulled from by runtime environments like Kubernetes clusters.

+

In the standard document ["Requirements for container registries"], requirements for a +registry in the context of SCS were introduced. These are based on the principals, that +a usable project should be open source, active and feature-rich, especially with regard +to security.

+

Terminology

+

Cloud Service Provider (abbr. CSP) +Entity that provides scalable computing resources

+

Cloud Native Computing Foundation (abbr. CNCF) +Organization that hosts and develops open source projects for cloud native computing

+

Motivation

+

In order to provide a usable, complete experience for the SCS reference implementation, it must be decided +on a registry in accordance with requirements set by the ["Requirements for container registries"] standard +as well as other dependencies set by the SCS project, including the OSS requirements.

+

This document should finally lead to a decision about the container registry used as a reference implementation of the SCS container registry.

+

Evaluated projects

+

A few open source projects were evaluated for this document in order to find suitable candidates +for the SCS reference implementation. These projects can be found in the following list of +evaluated projects with their classified categories and comments. An initial assessment was +done with the checks for OSS healthiness +and a general overview of the features described in ["Requirements for container registries"], which enables +classifying the projects into one of three categories as follows:

+
    +
  • +

    ✔️ The project passed all OSS health checks and will be considered +further as a valid candidate.

    +
  • +
  • +

    The project passed almost all OSS health checks. +There is place for improvement, but the missing points are not crucial from the OSS +health check perspective. The project will be considered further as a valid candidate.

    +
  • +
  • +

    The project does not pass the OSS health checks. Some OSS health check +showstoppers have been found (e.g. open core software, not actively maintained). +The project is filtered at this stage and won't be considered further.

    +
  • +
+

The following list contains these projects with a small assessment listed below them:

+
    +
  • +

    ✔️ Harbor

    +
      +
    • Harbor project meets all "four opens" +
        +
      • Source code is open and available under the Apache 2 license
      • +
      • Community is open, structured and +well organized via workgroups and +various communications channels e.g. Slack, mailing lists, etc. +(#harbor Slack channel contains 3k+ members)
      • +
      • The development process is open via GitHub issues and well described in the +contributing +document
      • +
      • The design process is open via GitHub issues. Proposals are public. +The decision process is well described as well. The project's roadmap is +available in the roadmap document
      • +
      +
    • +
    • Maturity is on the CNCF graduation level. +CNCF graduated projects are considered to be stable, widely adopted and production-ready
    • +
    • Security +
        +
      • The security disclosure and response policy is well described in the project's +security document
      • +
      • The code is reviewed within a standard PR process
      • +
      +
    • +
    • Activity +
        +
      • 250+ contributors, 4k+ forks, 13k+ GitHub stars
      • +
      • The project has been adopted +by many companies that run Harbor in their production environments
      • +
      • The project collaborates with other communities and projects +(see Partners of Harbor section of the +project's website)
      • +
      • The project is visible and actively contributes to various conferences, e.g. +FOSDEM 22, +KubeCon Europe, etc.
      • +
      +
    • +
    • Lock-in risk assessment +
        +
      • The project's maintainers +document shows that there are a sufficient number of core +maintainers/contributors that differ over various companies, we therefore deem +the lock-in risk arising from a single point of failure to be low
      • +
      +
    • +
    +
  • +
  • +

    ✔️ Dragonfly

    +
      +
    • Dragonfly project meets all "four opens" +
        +
      • Source code is open and available under the Apache 2 license
      • +
      • Community is open +organized via multiple channels e.g. Slack, mailing lists, etc. +(#dragonfly Slack channel contains ~50 members)
      • +
      • The development process is open via GitHub issues and well described in the +contributing document
      • +
      • The design process is open via GitHub issues. The project's roadmap is available in +the project's webpage
      • +
      +
    • +
    • Maturity is on the CNCF incubating level +CNCF incubating project is considered stable and used in production by users with +the healthy pool of contributors
    • +
    • Security +
        +
      • The security disclosure is handled via a dedicated email address
      • +
      • The code is reviewed within a standard PR process
      • +
      +
    • +
    • Activity +
        +
      • 30+ contributors, 100+ forks, 1k+ GitHub stars
      • +
      • The project has been adopted +by many companies that run Harbor in their production environments
      • +
      • The project is visible and actively contributes to various conferences, +e.g. KubeCon North America, +KubeCon Europe, etc.
      • +
      +
    • +
    • Lock-in risk assessment + +
    • +
    +
  • +
  • +

    Project Quay

    +
      +
    • Project Quay meets all "four opens" +
        +
      • Source code is open and available under the Apache 2 license
      • +
      • Community is open organized via mailing +list and IRC
      • +
      • Development process is open via JBoss JIRA +issues and well described in the governance document
      • +
      • Design process is open via JBoss JIRA +issues. The project's roadmap is available on the project's webpage
      • +
      +
    • +
    • Maturity +
        +
      • Project Quay is an open-source project that started ~9 years ago. +It powers Red Hat enterprise products Red Hat Quay and Quay.io, which are used in +a productive way by many. Therefore, the project's maturity is at the good level
      • +
      +
    • +
    • Security +
        +
      • The security disclosure is handled via a dedicated email address
      • +
      • The code is reviewed within a standard PR process
      • +
      +
    • +
    • Activity +
        +
      • 50+ contributors, 200+ forks, 2k+ GitHub stars
      • +
      • The project has been used by many companies that +run Quay in their production environments
      • +
      +
    • +
    • Lock-in risk assessment +
        +
      • The project's owners/maintainers list is not publicly available and is stored in +the downstream repository. +Therefore, it is hard to distinguish the risk of project failure caused by low +diversity across the companies. This should be improved.
      • +
      +
    • +
    +
  • +
  • +

    Keppel

    +
      +
    • The project seems to be not widely used in a productive way and also the activity +around is currently not on a good level (5+ contributors). The development +process as well as the design process seem to be open, but neither of them are +documented yet.
    • +
    +
  • +
  • +

    Nexus

    +
      +
    • Nexus is an open core software that offers paid pro version with advanced features
    • +
    +
  • +
  • +

    JFrog

    +
      +
    • JFrog Artifactory is shipped as an open core software +with limited features. The software is primarily offered as a paid pro version
    • +
    +
  • +
  • +

    Kraken

    +
      +
    • It seems that the project is not actively maintained as is discussed in the related +project's issue
    • +
    +
  • +
  • +

    Portus

    +
      +
    • It seems that the project is not actively maintained as is discussed in the related +project's issue
    • +
    +
  • +
+

Deeper look into selected projects

+

In the previous section, a wide range of open-source container registry projects (Quay, Harbor, Dragonfly, +Keppel, Portus, Kraken, etc.) has been carefully evaluated based on the two main +factors: the open-source health and range of supported features.

+

The open-source software health is crucial and container registry implementation should +pass it. It evaluates several important metrics of an open source software like whether the code/community/development/design +is fully open or whether the project's maturity, security, and activity are on the desired +level. This check also evaluates the lock-in risk due to possible single points of +failure or internal project conflicts and several other aspects. +Overall, three projects passed the OSS health checks:

+ +

The above projects were then evaluated from the "supported features" perspective. +The document ["Requirements for container registries"] provides a "Required and desirable features check", which +provides desired feature sets for open-source container registry implementations according to +SCS requirements (and nice-to-haves). The list of required features is quite long and contains +features that are primarily focused on security (authentication, vulnerability scanning, content trust, and validation, etc.), +scalability (HA mode, registry replication, p2p integration, etc.) and visibility (monitoring). +These requirements should ensure that the selected container registry implementation +could be offered by CSPs as a secure and enterprise-ready solution.

+

The following section compares the selected projects Dragonfly, Quay, and Harbor.

+

Dragonfly is a healthy open-source project with a growing community +and CNCF incubating maturity level. It is considered stable, and widely used by many +companies in their production environments. We currently see that it is not as +feature-rich as Harbor or Quay, hence it is not considered the best choice here. +It seems, that its main aim (currently) is to offer (an efficient, stable, and secure) +container distribution solution based on p2p technology. This improves download +efficiency and saves bandwidth across CSPs. It also offers integration possibilities +that allow one to use it as a p2p distribution network via a "preheat" API. This +integration was implemented in the Harbor project via Dragonfly "preheat" adapter, and +both parties may benefit from the integration. Harbor profits from Dragonfly's p2p +distribution capabilities and on the other hand the Dragonfly project profits from +Harbor's feature-rich container registry "frontend".

+

Quay is an open-source project maintained by Red Hat. Its OSS health is +on a good level, the surrounding community is growing, and we consider it to be quite +mature as it powers enterprise solutions like Red Hat Quay and Quay.io. +Besides this, there is still a place for OSS health improvement. It is hard to +distinguish the risk of project failure caused by low diversity across the companies +because the project's owners/maintainers list is not publicly available and is stored in +the Red Hat private repository. +Its feature set is impressive and this project fulfills all must-haves defined in +this document. Quay gives you security over your repositories with image +vulnerability scanning (Clair integration), content validation (Cosign integration), +and access controls. Harbor stands out here as it allows users to use also project Trivy +for vulnerability scanning. Project Quay also provides a scalable open-source +platform to host container images across any size organization. One drawback in +comparison to Harbor is that the proxy cache feature is still marked as a +Technology Preview, +hence this feature may not be completely production-ready yet. On the other hand, +the project Quay supports building Dockerfiles +using a set of workers on e.g. Kubernetes. Build triggers, such as GitHub webhooks +can be configured to automatically build new versions of repositories when new code is +committed. This feature is not supported by the Harbor project.

+

Harbor is an outstanding open-source, community-led project with fully open and +well-documented processes. Its large and thriving community powers the fast-growing +feature set and attracts more and more developers and companies to active contributions. +Harbor's CNCF graduation in 2020 made it one of the best choices for enterprise +customers that want to operate container registries securely and in a large scale. +Its community size, landscape, and CNCF graduation make a significant difference in +comparison to Quay's open-source health capabilities. +The list of supported features is also impressive. This project fulfills all must-haves +defined in this document and overcome project Quay with a production-ready proxy cache +feature and more options that the user may use in case of image vulnerability scanning. +In addition, Harbor profits from p2p distribution capabilities via integration of p2p +solutions like Kraken and Dragonfly. It is worth mentioning that Harbor, by design, +operates on a single storage backend (e.g. S3). It means that the storage of container +images is shared even when the Harbor instance serves multiple tenants. The same +approach is used in Quay and Dragonfly projects, but e.g. Keppel uses multi-tenant-aware +storage drivers instead so that each customer gets their own separate storage backend. +CSP that considers offering container registry "as a service" solution based on Harbor +should be aware of this shared storage backend architecture.

+

In the following table, the feature sets of the evaluated projects that passed the OSS health state +are listed and matched against. This enables a better understanding of the decision-making for this document.

+
FeaturesHarborQuayDragonfly
Audit Logs
Authentication of system identities✓ Robot Accounts✓ Robot Accounts
Authentication of users✓ Local database, LDAP, OIDC, UAA✓ Local database, LDAP, Keystone, JWT✓ Local database
Authorization
Automation✓ Webhooks (HTTP, Slack)✓ Webhooks (HTTP, Slack, E-mail ...), building images
Vulnerability scanning✓ Trivy, Clair✓ Clair
Content Trust and Validation✓ Cosign✓ Cosign
Multi-tenancy✓ (not on the storage level)✓ (not on the storage level)✓ (not on the storage level)
Backup and restore
Monitoring✓ Prometheus metrics, Tracing✓ Prometheus metrics, Tracing (only for Clair)✓ Prometheus metrics, Tracing
HA mode
Registry replication
Proxy cache✓ Feature is in the technology preview stage (non production ready)
Quota management✓ Based on storage consumption✓ Based on storage consumption
Garbage collection✓ Non-blocking✓ Non-blocking
Retention policy✓ Multiple tag retention rules✓ Only tag expiration rules
Additional supported artifacts✗ (only OCI artifacts)✗ (only OCI artifacts)✓ Maven, YUM
Integration possibilities✓ Dragonfly (P2P), Kraken (P2P)✓ Harbor, Nydus, eStargz
Deployment capabilities✓ Docker-compose, Helm chart, Operator✓ Docker-compose, Operator✓ Docker-compose, Helm chart
Administration capabilities✓ Terraform, CRDs, Client libraries✓ Ansible, Client libraries✓ Client libraries
+

Notes:

+
    +
  • Automation: Harbor should support webhooks following CloudEvents spec in the next release
  • +
  • Content Trust and Validation: Harbor announced the deprecation of Notary +integration, hence it is not mentioned in the table
  • +
  • Multi-tenancy: Harbor, Quay, as well as Dragonfly, operates on a single storage +backend (e.g. S3), i.e. the storage of container images is shared between tenants
  • +
  • Additional supported artifacts: Harbor announced the deprecation of Chartmuseum +integration, hence it is not mentioned in the table
  • +
+

Decision

+

Based on the requirements laid out in ["Requirements for container registries"], the OSS health check +and the possible software solutions presented in this document, it was decided to use the Harbor project +as the container registry for the SCS reference implementation.

+ +

"Requirements for container registries" +harbor +dragonfly +projectquay

+ + \ No newline at end of file diff --git a/standards/scs-0300-v1-requirements-for-sso-identity-federation/index.html b/standards/scs-0300-v1-requirements-for-sso-identity-federation/index.html new file mode 100644 index 0000000000..20a93273b6 --- /dev/null +++ b/standards/scs-0300-v1-requirements-for-sso-identity-federation/index.html @@ -0,0 +1,231 @@ + + + + + +Requirements for SSO identity federation | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Requirements for SSO identity federation

Introduction

+

Our assumption is that there are use cases, where CSPs would like to be able to +let customers access their SCS based services by identifying themselves with +credentials that are stored and managed external to the CSP's SCS installation.

+

This is based on the observation that prospective customers of an SCS based CSP +sometimes already come equipped with an IAM solution of their choice, either on +premises or e.g. as an external 3rd party cloud service. To ease onboarding of +customer employees (or e.g. customer contracted 3rd party admin staff) as SCS +users, it would be good to be able to consume these external identities in SCS.

+

For customers this avoids the neccessity to explicitly maintain an additional +dedicated account in SCS and this also reduces what SCS needs to do with +respect to taking care of persisting user account information.

+

To put it in other words, in SCS we would like to be able to delegate +authentication to external identity providers and map those users to roles in +SCS that can be used for authorization decisions when users access SCS services.

+

In addition to user identities there we also see the necessity to support the +use of "machine identites" (aka "workload identities" or "service accounts"). +These will probably be SCS-local accounts and have for example the purpose +to grant CaaS workload access to storage resources served by the infrastructure +layer. Exact architectural details for this are still in active discussion, +but it is anticipated that the IdP component should be very useful in +facilitating the integration.

+

Motivation for this document

+

SCS has multiple service layers, like IaaS and CaaS, both of which running their +own technological stack with specific internal models of accounts and +authorization.

+

One thing these services have in common, is that they are able +to use SSO protocols like OAuth 2.0 or OpenID Connect (OIDC) on top of it to +delegate authentication. They are service providers (SAML terminology) and can +be relying parties (OIDC terminology) of a protocol compliant identity provider +(IdP).

+

So the idea is, to run an SSO IdP as part of SCS to provide a dedicated point +of entry for identites, which the SCS service layers can use as a common +interface to consume external user identities.

+

The purpose of this document is to specify what requirements a specific +technical IdP implementation (i.e. software solution) needs to fulfill +in the context of SCS.

+

Design Considerations

+

As a central service for identity handling, the IdP +service needs to be robust and reliable.

+

Customers shall be able to access self service, so that +they can make reasonable adjustments e.g. to role mapping. +At the time of writing this document it's still undecided +if SCS has the requirement of a dedicated "self service" service +that serves as a frontend to provision and re-configure +customer specific data, abstracting e.g. from IdP specific +user interface particularities.

+

Keycloak is currently being deployed as part of the IaaS reference implementation. +Technically this IdP component shall be shifted from the management +plane to be run on the basis of a "minimal" Kubernetes (e.g. K3S), +e.g. to make use of the "self healing" and scaling features achievable +with that.

+

So one of the considerations is if the solution will work well on a +K8S environment. The instances will need to share configuration +(probably via the shared backend database) as well as session state. +Maybe one is better prepared for horizontal scaling than the other.

+

Options considered

+

Keycloak

+

Keycloak is a commonly used IdP solution implemented in Java. +It is developed as an open source community project. +Red Hat uses it as upstream source for their Red Hat SSO product +and is also listed as sponsor of the project. +Starting with version 17 the default distribution is based on +Quarkus instead of WildFly/JBoss.

+

The project maintains several means of community contributions +as listed on the community section +of the project website. It uses Github issues +to track development.

+

It offers a REST API for administration and there's a separately maintained +3rd party python module as well as ansible support for it. Both of these are +downstream of Keycloak itself and may thus not always be feature complete and +suffer latency with respect to getting adjusted to upstream changes.

+

It offers support for commonly used SSO protocols and is "reasonably" fast +in adopting to protocol standard changes and extensions. This has been +observed in the case of logout support (backend and frontend variants) in OIDC.

+

It offers a concept of "Identity Brokering", where Keycloak is not just IdP +but also "client" to other IdPs. This allows daisy chaining of identity +federation. In this configuration it can work as a point of protocol +transition between different supported SSO protocols (SAML, OAuth 2.0, etc.).

+

Beyond this capability of using other IdPs as identity sources, it also supports +using classic LDAP based IAM services as backend (OpenLDAP and Active Directory, +e.g.).

+

Keycloak's implementation makes some design decisions, that are specific +to it and have consequences for clients of the service. E.g. Keycloak +has a concept of management "Realms", which have their own specific +set of HTTP API entrypoints, both for administration as well as for IdP +requests.

+

Commonly Keycloak realms can be used to map them 1:1 to user domains, +but since Keycloak supports configuring multiple backend IdPs in a +realm to be used for "Identity Brokering", there is always the +possibility to create a kind of "proxy" realm to provide a single +standard set of HTTP API endpoints for SSO clients (service providers) +to avoid the need to frequently extend/reduce client service configuration +whenever a new IdP federation needs to be added to Keycloak to onboard +a new customer. This is relevant for services like OpenStack Keystone, +which currently cannot be easily reconfigured for new SSO endpoints +without restarting the service, making the service unavailable for +a short span of time and increasing risk connected with service restarts.

+

Since version 17, Keycloak claims that it's capability for +"cloud native" deployments on Kubernetes has improved.

+

Keycloak is offering a documented REST API +for all aspects of its administration interface.

+

For storage of Keycloak configuration and local user metadata +(e.g. from which external IdP a user account originally came from) +Keycloak supports several SQL backends through JDBC. Thus +it can be hooked up to a Postgres Database or to a +MariaDB/Galera cluster e.g..

+

As of April 11, 2023, Keycloak joined the CNCF as an incubating project.

+

Zitadel

+

Zitadel is a newer implementation of an SSO IdP. +It is implemented in Go and under active development and maintained by ZITADEL.

+

The project is open for community contributions +to all parts of the eco system. +Feature requests and bugs being tracked on Github for development. +Community questions can be asked in the public chat or via Github Discussions. +ZITADEL offers support for the commonly used authentication and authorization protocols such as OIDC, OAuth2, SAML2. +It is a compliant and certified OpenID Connect provider with support for various Grant Types for both human users and machine users. +Compared to Keycloak SPIs, ZITADEL offers Actions to customize and integrate (eg, calling external APIs, Webhooks, customizing pre-built workflows, customizing tokens) +Actions are executed at runtime and can be maintained independently of platform. +Identity brokering (OIDC, SAML, JWT) can be configured system-wide or for each organization with templates. +Users will be created just in time for audit purposes and linked to the external identity provider. +Users can have multiple identity providers linked to their profile.

+

It came to attention of the SCS project because it offers a +fresh take of an organization focussed data model, which has +the potential to simplify IdP federation to SCS customer domains +in the following areas:

+
    +
  • For client services (single set of HTTP API endpoints).
  • +
  • For SCS operators for provisioning customer organizations +and robust configuraton by using templated client, role and mapping +configuration.
  • +
  • For SCS customers for a robust user experience for self servicing.
  • +
+

The concept for Delegated Access Management +reduces the management overhead compared to isolated realms. +Projects (Applications + Roles) can be maintained by one organization and delegated to be used by other Organizations. +Managers that receive granted Projects can assign users permissions to use the project.

+

Zitadel is offering REST APIs +for multiple areas of use and configuration.

+

It recently also added support for the Device Authorization Grant, +which, at time of writing, is a feauture that is relevant +for SCS to be able use OpenStack CLI and APIs with federated +identities (Device Authorization Grant).

+

Support for consumption of LDAP backends is available since Zitadel v2.23.0 +(see this guide).

+

ZITADEL supported backend databases are CockroachDB and PostgreSQL.

+

For production setups it is recommended +to use Kubernetes (or similar like Knative) and CockroachDB.

+

At time of writing a PoC "spike" is done to assess and verify the hopes +connected with Zitadel in the context of the SCS testbed.

+

Currently Zitadel is lacking the possibility to easily add custom claims. +It supports urn:zitadel:iam:user:metadata, but that is more suitable +towards Kubernetes and cannot be parsed with the OpenStack mapping mechanism. +There is work going on which +may be suitable to resolve this issue. +An approach based on Zitadel actions is also currently evaluated. +OpenStack currently makes use of custom claims to pass openstack-default-project +from the IdP to OpenStack. Combined with federation to external customer managed IdPs +this should allow customers to manage settings like these in their own IAM.

+

Open questions

+
    +
  • How would we implement testbed deployment support for Zitadel? +
      +
    • e.g. wsgi-keystone.conf would need to look different. One template covering both options?
    • +
    • e.g. steps like openstack federation protocol create would probably be different.
    • +
    +
  • +
  • Should we support both as options? +
      +
    • What's the benefit?
    • +
    • How would we allow SCS operators to choose?
    • +
    +
  • +
  • Do we need some kind of SWOT analysis to come to a decision?
  • +
+

Decision

+

SCS wants to make use of an IdP as part of the reference implementation. +To move forward with topics of configuration and mapping of roles in a +OAuth2 federation scenario as well as questions of token lifecycles etc. across +the federation stack it makes sense to focus on one IdP implementation at a +given time. Both considered options seem to be potentially viable, but ultimately, +a decision should be made, even if there are no strict/strong reasons for +dismissing either option in particular.

+

The project's current choice is Keycloak for the following reasons: +Keycloak currently supports the OAuth 2.0 grants that SCS wants to make +use of (e.g. Device Authorization Grant). It is the implementation for +which integration is currently documented in OpenStack and implemented +in kolla-ansible. SCS currently deploys Keycloak and the IAM team has +most hands on expecience with it, e.g. when it comes to colletaral questions +like how to make TLS and signing certificates available to the IdP that shall +be used in federation to external domains.

+ + +

Conformance Tests

+

Conformance Tests, OPTIONAL

+ + \ No newline at end of file diff --git a/standards/scs-0301-v1-naming-conventions/index.html b/standards/scs-0301-v1-naming-conventions/index.html new file mode 100644 index 0000000000..44c0951d3b --- /dev/null +++ b/standards/scs-0301-v1-naming-conventions/index.html @@ -0,0 +1,88 @@ + + + + + +Naming for domains/groups/roles/project when onboarding new customers | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Naming for domains/groups/roles/project when onboarding new customers

Introduction

+

When CSPs try to enroll a new customer they encounter themselves in +a situation where they have to choose names for the openstack domain, +project and user.

+

Motivation

+

Create a naming convention to use during the provisioning of the users and +groups through an openstack domain.

+

Design Considerations

+

OPTIONAL

+

Options considered

+

PS approach to naming

+

For naming the customers the suggestion from PS is the following:

+

A prefix will be use to differenciate domain, project and user in +the openstack environment. The project name is also added as a sufix.

+

So the onboaring tool will create the following structure for a new +customer onboarded in the system.

+
domain: d<customer_id>
project: p<customer_id>-<project_name>
user: u<customer_id>-<user_name>
+

For the customer also a domain admin group and a project admin group are +created. Please note that, at the time of writing, PCO is not making any +use of OpenStack domains to isolate customers. So, for the scope of this +document, the term "domain admin" is used in a conceptual way rather than +referring to the specific OpenStack implementation. For the scope of this +document "domain admins" can do things like creating projects, creating +users and granting users access to some projects (within the domain of +course). "Users" can create and view resources within the projects that +they have been granted access to by the "domain admin". +These groups use the prefix "gd" for domain group and "gp" for group project +and are build like the following:

+
domain admin group: gd<customer_id>-member
project admin group: gp<customer_id>-<project_name>-member
+

For the creation of a domain a new domain admin group is created.

+
openstack domain create d000001
openstack group create gd000001-member
+

When a project is created a new admin group for that project is created.

+
openstack project create p000001-scs_dev_project
openstack group create p000001-scs_dev_project-member
+

After the creation of a project it is necessary to assign roles to the +new groups.

+
openstack role add --group gd000001-member --project p000001-scs_dev_project $role
openstack role add --group gp000001-scs_dev_project-member --project p000001-scs_dev_project $role
+

For the creation of regular non admin users, the accounts will be added +to the "domain admin" group to give them access to all projects within +the domain.

+
openstack user created u000001-user1
openstack group add user gd000001-member u000001-user1
+

In the case of machine accounts, they are only added to the specific +"project admin" groups.

+
openstack user created u000001-svc_user_project
openstack group add user gp000001-scs_dev_project-member u000001-svc_user_project
+

In case of using federation, there are suggestions to the namings within Keycloak.

+

The realms in Keycloak for each customer would be the same as the customer. e.g. The Keycloak realm for "Customer A" +will be called "Customer A".

+

There should be an OIDC client in each customer realm to allow the federation to the Proxy realm. Currently called OSISM +on the testbed.

+

On the proxy realm, it's needed to add this new customer realm as an idenity provider. During the creation of the identity +provider for "Customer A", the field "Alias" should be set to <customer-id>. This will make that the users federated from +realm "Customer A" to the proxy realm to be prefixed to avoid naming colisions, e.g. d${ALIAS}-${CLAIM.preferred_username}.

+

Also, on the identity federation there should be configured to store the <customer-id> from that realm into the users. So it +can be send to Keystone mapping to use it as gd<customer-id>-member and gp<customer-id>-<project_name>-member. There is +also the necessity of a mapper to send the openstack-default-project.

+

Add the aditional mappings for roles and groups as necessary to get the attributes from the customer realm into the OIDC +userinfo that is put into the OIDC to the proxy realm and from there to Keystone.

+

Option 2

+

Option 2 description

+

Open questions

+

RECOMMENDED

+

Decision

+

Decision

+ +

Related Documents, OPTIONAL

+

Conformance Tests

+

Conformance Tests, OPTIONAL

+ + \ No newline at end of file diff --git a/standards/scs-0302-v1-domain-manager-role/index.html b/standards/scs-0302-v1-domain-manager-role/index.html new file mode 100644 index 0000000000..0b8edbdeb8 --- /dev/null +++ b/standards/scs-0302-v1-domain-manager-role/index.html @@ -0,0 +1,220 @@ + + + + + +Domain Manager configuration for Keystone | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Domain Manager configuration for Keystone

Introduction

+

SCS Clouds should provide a way to grant Domain Manager rights to SCS Customers which provides IAM self-service capabilities within an OpenStack domain. +This is not properly implemented in the default OpenStack configuration and requires specific adjustments to the Keystone identity management configuration. +To avoid conflict with the unscoped admin role in OpenStack we want to refer to this new persona as "Domain Manager", introducing the manager role in the API for domains.

+

Glossary

+

The following special terms are used throughout this standard document:

+
TermMeaning
RBACRole-Based Access Control1 established by OpenStack Keystone
projectOpenStack project as per Keystone RBAC
userOpenStack user as per Keystone RBAC
groupOpenStack group as per Keystone RBAC
roleOpenStack role as per Keystone RBAC
domainOpenStack domain as per Keystone RBAC
IAMidentity and access management
personaAbstract and conceptual role of a user in terms of IAM
IAM resourcesprojects, users, groups, roles, domains as managed by OpenStack Keystone
CSPCloud Service Provider, provider managing the OpenStack infrastructure
cloud adminOpenStack user belonging to the CSP that possesses the admin role
+

Impact

+

Applying this standard modifies the API policy configuration of Keystone and introduces a new persona to Keystone to enable IAM self-service for customers within a domain. +Once assigned, this persona allows special Domain Manager users within a domain to manage users, project, groups and role assignments as part of the IAM self-service.

+

However, the configuration change introduced by this standard does not automatically assign the Domain Manager persona to any users per default. +Assigning the new persona and granting customers the resulting self-service capabilities is a deliberate action to be taken by the CSP on a per-tenant (i.e. per domain) basis.

+

Omitting the provisioning of any Domain Manager users (i.e. not assigning the new persona to any user) will result in an OpenStack cloud that behaves identically to a configuration without the standard applied, making the actual usage of the functionality a CSP's choice and entirely optional.

+

Motivation

+

In the default configuration of Keystone, only users with the admin role may manage the IAM resources such as projects, groups and users and their relation through role assignments. +The admin role in OpenStack Keystone is not properly scoped when assigned within a domain or project only as due to hard-coded architectural limitations in OpenStack, a user with the admin role may escalate their privileges outside of their assigned project or domain boundaries. +Thus, it is not possible to properly give customers a self-service functionality in regards to project, group and user management with the default configuration.

+

To address this, this standard defines a new Domain Manager persona implemented using a domain-scoped manager role in conjunction with appropriate Keystone API policy adjustments to establish a standardized extension to the default Keystone configuration allowing for IAM self-service capabilities for customers within domains.

+

Desired Workflow

+
    +
  1. The cloud admin deploys the Domain Manager policy configuration for Keystone as per this standard if it is not already applied.
  2. +
  3. The cloud admin creates the desired domains for the customers for which IAM self-service capabilities are desired.
  4. +
  5. The cloud admin creates one or more users within each of the applicable domains and assigns the manager role for a certain domain to them. These users represent the Domain Managers of the corresponding domain.
  6. +
  7. The customer uses the Domain Manager users to manage (create, update, delete) users, projects, groups and corresponding role assignments within their domain.
  8. +
+

Design Considerations

+
    +
  • the Domain Manager persona MUST support managing projects, groups and users within a specific domain
  • +
  • the Domain Manager persona MUST be properly scoped to a domain, it MUST NOT gain access to resources outside of its owning domain
  • +
  • the Domain Manager persona MUST NOT be able to manipulate existing roles or create new roles
  • +
  • the Domain Manager persona MUST only be able to assign specific non-administrative* roles to their managed users where the applicable roles are defined by the CSP
  • +
  • Domain Managers MUST NOT be able to abuse the role assignment functionalities to escalate their own privileges or those of other users beyond the roles defined by the CSP
  • +
+

* "non-administrative" in this context means this excludes the role "admin" and any comparable role that grants permissions beyond domain and tenant scope. +Since the "manager" role as defined in this standard is domain-scoped for a Domain Manager, it does not count as administrative.

+

Options considered

+

Re-using the existing admin role

+

As role assignments can be scoped to project, groups and domains the most obvious option would be to assign the existing admin role to users representing Domain Managers in a scoped fashion.

+

However, due to architectural limitations2 of the existing OpenStack implementation of roles, the admin role has a special meaning reaching beyond the RBAC checks done by Keystone and other OpenStack components. +This results in special permissions being granted to users possessing the role which ignore the project or domain scope of the role assignment. +This poses severe security risks as the proper scoping of the admin role is impossible. +Due to this, this approach was discarded early.

+

Upstream (OpenStack) is in the process of addressing this across the services but it has not been fully implemented yet, especially for domains3.

+

Introducing a new persona and role with API policy changes

+

OpenStack Keystone allows for new roles to be created via its API by administrative users. +Additionally, each OpenStack API's RBAC can be adjusted through an API policy file (policy.yaml) through olso-policy4, Keystone included. +The possibility of managing users, projects, role assignments and so on is regulated through Keystone's RBAC configured by its API policy file.

+

This means that by creating a new role and extending Keystone's API policy configuration a new Domain Manager persona can be established that is limited to a specific subset of the Keystone API to be used to manage users, projects and role assignments within a domain.

+

Open questions

+

Limitations

+

The approach described in this standard imposes the following limitations:

+
    +
  1. as a result of the "identity:list_domains" rule (see below), Domain Managers are able to see all domains5 via "openstack domain list" and can inspect the metadata of other domains with "openstack domain show"
  2. +
  3. as a result of the "identity:list_roles" rule (see below), Domain Managers are able to see all roles via "openstack role list" and can inspect the metadata of other roles with "openstack role show"
  4. +
+

As a result of points 1 and 2, metadata of all domains and roles will be exposed to all Domain Managers!

+

If a CSP deems either of these points critical, they may abstain from granting the "manager" role to any user in a domain scope, effectively disabling the Domain Manager functionality. See Impact.

+

Decision

+

A role named "manager" is to be created via the Keystone API and the policy adjustments quoted below are to be applied.

+

Policy adjustments

+

The following policy has to be applied to Keystone in a verbatim fashion. +The only parts of the policy definitions that may be changed are:

+
    +
  1. The "base_*" definitions to align them to the correct OpenStack defaults matching the OpenStack release of the environment in case those differ from this template.
  2. +
  3. The "is_domain_managed_role" definition (see next section below).
  4. +
+
# SCS Domain Manager policy configuration

# Section A: OpenStack base definitons
# The entries beginning with "base_<rule>" should be exact copies of the
# default "identity:<rule>" definitions for the target OpenStack release.
# They will be extended upon for the manager role below this section.
"base_get_domain": "(role:reader and system_scope:all) or token.domain.id:%(target.domain.id)s or token.project.domain.id:%(target.domain.id)s"
"base_list_domains": "(role:reader and system_scope:all)"
"base_list_roles": "(role:reader and system_scope:all)"
"base_get_role": "(role:reader and system_scope:all)"
"base_list_users": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
"base_get_user": "(role:reader and system_scope:all) or (role:reader and token.domain.id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"
"base_create_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"
"base_update_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"
"base_delete_user": "(role:admin and system_scope:all) or (role:admin and token.domain.id:%(target.user.domain_id)s)"
"base_list_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
"base_get_project": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.project.domain_id)s) or project_id:%(target.project.id)s"
"base_create_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"
"base_update_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"
"base_delete_project": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.project.domain_id)s)"
"base_list_user_projects": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(target.user.id)s"
"base_check_grant": "(role:reader and system_scope:all) or ((role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"
"base_list_grants": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)"
"base_create_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"
"base_revoke_grant": "(role:admin and system_scope:all) or ((role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.user.domain_id)s and domain_id:%(target.domain.id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.project.domain_id)s) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.domain.id)s)) and (domain_id:%(target.role.domain_id)s or None:%(target.role.domain_id)s)"
"base_list_role_assignments": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
"base_list_groups": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"
"base_get_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"
"base_create_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"
"base_update_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"
"base_delete_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s)"
"base_list_groups_for_user": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.user.domain_id)s) or user_id:%(user_id)s"
"base_list_users_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)"
"base_remove_user_from_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"
"base_check_user_in_group": "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"
"base_add_user_to_group": "(role:admin and system_scope:all) or (role:admin and domain_id:%(target.group.domain_id)s and domain_id:%(target.user.domain_id)s)"

# Section B: Domain Manager Extensions

# classify domain managers with a special role
"is_domain_manager": "role:manager"

# specify a rule that whitelists roles which domain admins are permitted
# to assign and revoke within their domain
"is_domain_managed_role": "'member':%(target.role.name)s or 'load-balancer_member':%(target.role.name)s"

# allow domain admins to retrieve their own domain (does not need changes)
"identity:get_domain": "rule:base_get_domain or rule:admin_required"

# list_domains is needed for GET /v3/domains?name=... requests
# this is mandatory for things like
# `create user --domain $DOMAIN_NAME $USER_NAME` to correctly discover
# domains by name
"identity:list_domains": "rule:is_domain_manager or rule:base_list_domains or rule:admin_required"

# list_roles is needed for GET /v3/roles?name=... requests
# this is mandatory for things like `role add ... $ROLE_NAME`` to correctly
# discover roles by name
"identity:list_roles": "rule:is_domain_manager or rule:base_list_roles or rule:admin_required"

# get_role is needed for GET /v3/roles/{role_id} requests
# this is mandatory for the OpenStack SDK to properly process role assignments
# which are issued by role id instead of name
"identity:get_role": "(rule:is_domain_manager and rule:is_domain_managed_role) or rule:base_get_role or rule:admin_required"

# allow domain admins to manage users within their domain
"identity:list_users": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_users or rule:admin_required"
"identity:get_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_get_user or rule:admin_required"
"identity:create_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_create_user or rule:admin_required"
"identity:update_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_update_user or rule:admin_required"
"identity:delete_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_delete_user or rule:admin_required"

# allow domain admins to manage projects within their domain
"identity:list_projects": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_projects or rule:admin_required"
"identity:get_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_get_project or rule:admin_required"
"identity:create_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_create_project or rule:admin_required"
"identity:update_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_update_project or rule:admin_required"
"identity:delete_project": "(rule:is_domain_manager and token.domain.id:%(target.project.domain_id)s) or rule:base_delete_project or rule:admin_required"
"identity:list_user_projects": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_user_projects or rule:admin_required"

# allow domain managers to manage role assignments within their domain
# (restricted to specific roles by the 'is_domain_managed_role' rule)
#
# project-level role assignment to user within domain
"is_domain_user_project_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.project.domain_id)s"
# project-level role assignment to group within domain
"is_domain_group_project_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.project.domain_id)s"
# domain-level role assignment to group
"is_domain_level_group_grant": "token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.domain.id)s"
# domain-level role assignment to user
"is_domain_level_user_grant": "token.domain.id:%(target.user.domain_id)s and token.domain.id:%(target.domain.id)s"
"domain_manager_grant": "rule:is_domain_manager and (rule:is_domain_user_project_grant or rule:is_domain_group_project_grant or rule:is_domain_level_group_grant or rule:is_domain_level_user_grant)"
"identity:check_grant": "rule:domain_manager_grant or rule:base_check_grant or rule:admin_required"
"identity:list_grants": "rule:domain_manager_grant or rule:base_list_grants or rule:admin_required"
"identity:create_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_create_grant or rule:admin_required"
"identity:revoke_grant": "(rule:domain_manager_grant and rule:is_domain_managed_role) or rule:base_revoke_grant or rule:admin_required"
"identity:list_role_assignments": "(rule:is_domain_manager and token.domain.id:%(target.domain_id)s) or rule:base_list_role_assignments or rule:admin_required"


# allow domain managers to manage groups within their domain
"identity:list_groups": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_list_groups or rule:admin_required"
"identity:get_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or (role:reader and system_scope:all) or rule:base_get_group or rule:admin_required"
"identity:create_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_create_group or rule:admin_required"
"identity:update_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_update_group or rule:admin_required"
"identity:delete_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_delete_group or rule:admin_required"
"identity:list_groups_for_user": "(rule:is_domain_manager and token.domain.id:%(target.user.domain_id)s) or rule:base_list_groups_for_user or rule:admin_required"
"identity:list_users_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s) or rule:base_list_users_in_group or rule:admin_required"
"identity:remove_user_from_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_remove_user_from_group or rule:admin_required"
"identity:check_user_in_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_check_user_in_group or rule:admin_required"
"identity:add_user_to_group": "(rule:is_domain_manager and token.domain.id:%(target.group.domain_id)s and token.domain.id:%(target.user.domain_id)s) or rule:base_add_user_to_group or rule:admin_required"
+

Note that the policy file begins with a list of "base_*" rule definitions ("Section A"). +These mirror the default policies of recent OpenStack releases. +They are used as a basis for the domain-manager-specific changes which are implemented in "Section B" where they are referenced to via "or rule:base_*" accordingly. +The section of "base_*" rules is meant for easy maintenance/update of default rules while keeping the domain-manager-specific rules separate.

+
+

Note: +The "or rule:admin_required" appendix to the rule defintions in "Section B" is included for backwards compatibility with environments not yet fully configured for the new secure RBAC standard6.

+
+

Specifying manageable roles via "is_domain_managed_role"

+

The "is_domain_managed_role" rule of the above policy template may be adjusted according to the requirements of the CSP and infrastructure architecture to specify different or multiple roles as manageable by Domain Managers as long as the policy rule adheres to the following:

+
    +
  • the "is_domain_managed_role" rule MUST NOT contain the "admin" role, neither directly nor transitively
  • +
  • the "is_domain_managed_role" rule MUST define all applicable roles directly, it MUST NOT contain a "rule:" reference within itself
  • +
+
Example: permitting multiple roles
+

The following example permits the "reader" role to be assigned/revoked by a Domain Manager in addition to the default "member" and "load-balancer_member" roles. +Further roles can be appended using the logical or directive.

+
"is_domain_managed_role": "'member':%(target.role.name)s or 'load-balancer_member':%(target.role.name)s or 'reader':%(target.role.name)s"
+

Note regarding the manager role

+

When adjusting the "is_domain_managed_role" rule a CSP might opt to also include the "manager" role itself in the manageable roles, resulting in Domain Managers being able to propagate the Domain Manager capabilities to other users within their domain. +This increases the self-service capabilities of the customer but introduces risks of Domain Managers also being able to revoke this role from themselves or each other (within their domain) in an unintended fashion.

+

CSPs have to carefully evaluate whether Domain Manager designation authority should reside solely on their side or be part of the customer self-service scope and decide about adding "'manager':%(target.role.name)s" to the rule accordingly.

+ +

"admin"-ness not properly scoped

+

Description: Upstream bug report about the underlying architectural issue of the admin role not being properly scoped and giving system-level admin permissions regardless of whether the admin role assignment was scoped to project or domain level. +This is the main reason for the admin role being inappropriate to implement Domain Managers.

+

Link: Launchpad bug: "admin"-ness not properly scoped

+

Consistent and Secure Default RBAC

+

Description: Upstream rework of the default role definitions and hierarchy across all OpenStack services. +Aims to introduce support for a scoped manager role by 2024 but only focuses on project-level scoping for this role so far, not domain-level.

+

Link: OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC

+

Conformance Tests

+

There is a test suite in domain-manager-check.py. +The test suite connects to the OpenStack API using two sample domains and corresponding Domain Manager accounts. +It verifies the compliance to the standard and the proper domain-scoping as defined by the Keystone policy. +Please consult the associated README.md for detailed setup and testing instructions.

+

Appendix

+

Decision Record

+

Change the naming of the Domain Manager role to align with upstream

+

Decision Date: 2024-03-13

+

Decision Maker: Team IaaS

+

Decision:

+
    +
  • the Domain Manager role should be named "manager" not "domain-manager"
  • +
+

Rationale:

+
    +
  • upstream (OpenStack) will introduce a "manager" role with the upcoming RBAC rework
  • +
  • the "manager" role is intended to grant managing capabilities bound to the scope it is assigned for, e.g. projects; it would make sense to also integrate the Domain Manager approach here
  • +
  • during the process of contributing the Domain Manager functionality upstream we were asked to use the already defined "manager" role instead of introducing a new role; so the rename would then also be in line with the upstream contribution
  • +
+

Links / Comments / References:

+ +

Allow flexibility for the roles a Domain Manager can assign/revoke within domain

+

Decision Date: 2023-09-27

+

Decision Maker: Team IaaS, Team IAM

+

Decision:

+
    +
  • the standard should not strictly limit the roles a Domain Manager can assign/revoke to/from other users within a domain to the "member" role
  • +
  • the standard should allow CSPs to define one or more roles for Domain Managers to manage
  • +
  • whether or not this includes the Domain Manager role itself is not to be predefined by the standard and should be up to the CSP to decide instead
  • +
  • the standard should only strictly prohibit adding the "admin" role to the list of roles manageable by Domain Managers
  • +
+

Rationale:

+
    +
  • the available and configured roles might differ between CSPs and infrastructures
  • +
  • the Domain Manager standard should be flexible enough to adapt to different environments while still offering the intended functionality
  • +
  • there might be a tradeoff between self-service flexibility desired by customers and the security regulation a CSP wants to impose, thus allowing or prohibiting the designation of Domain Managers by customers themselves should be up to the CSP to decide
  • +
+

Links / Comments / References:

+ +

Extend domain management functionality to Keystone groups

+

Decision Date: 2023-08-04

+

Decision Maker: SIG IAM

+

Decision:

+
    +
  • the Domain Manager Standard configuration should cover the groups functionality of Keystone, allowing domain manager to manage groups in domains
  • +
+

Rationale:

+
    +
  • the groups functionality is a desired IAM feature for customers
  • +
+

Links / Comments / References:

+ +

Change the naming of the Domain Manager role

+

Decision Date: 2023-08-04

+

Decision Maker: SIG IAM

+

Decision:

+
    +
  • the Domain Manager role should be named "domain-manager" not "domain-admin".
  • +
+

Rationale:

+ +

Links / Comments / References:

+ + +

Footnotes

+
    +
  1. +

    OpenStack Documentation: Role-Based Access Control Overview

    +
  2. +
  3. +

    Launchpad bug: "admin"-ness not properly scoped

    +
  4. +
  5. +

    OpenStack Documentation: Keystone for Other Services - Domain Scope

    +
  6. +
  7. +

    OpenStack Documentation: Administering Applications that use oslo.policy

    +
  8. +
  9. +

    see the corresponding Launchpad bug at Keystone

    +
  10. +
  11. +

    OpenStack Technical Committee Governance Documents: Consistent and Secure Default RBAC

    +
  12. +
+
+ + \ No newline at end of file diff --git a/standards/scs-0400-v1-status-page-create-decision/index.html b/standards/scs-0400-v1-status-page-create-decision/index.html new file mode 100644 index 0000000000..60852c04fe --- /dev/null +++ b/standards/scs-0400-v1-status-page-create-decision/index.html @@ -0,0 +1,162 @@ + + + + + +Status Page create decision | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Status Page create decision

Introduction

+

Creating and maintaining IT infrastructure is a complex task. +Any kind of consumer (e.g. operators, cutsomers) can +be supported by presenting the status of all possible parts of the +serving infrastructure. Whether a service is not reachable or +the used hardware is having an outage we want the consumers to be easily informed +by using a "Status Page" application. The need for a "Status Page" +came up early in the SCS project and the requirements a "Status Page" application +has to fulfill were defined and written down on 2022-06-02 as a +MVP-0 epic. +The upcoming research on existing solutions came to the conclusion that we want to +create a new "Status Page" application.

+

Existing Applications

+

Since we want to use as much as possible from existing projects and contribute to +upstream projects to support the community with our efforts, it was a hard +decision to create a new "Status Page" application.

+

Before the decision was made some existing and known applications were tested +and analyzed if they would fit to our use case. An overview of this +comparison can be found below in this document +While this is not a complete list of all existing applications it did +capture the most promising ones from the awesome-status-page list +in order to have base to decide upon.

+

Work on an existing project only makes sense if the project is healthy OR can be +brought into a healthy state. If upstream does not accept patches a fork is needed. +The fork however only makes sense if the underlying technology is worth to be maintained. +The possible candidates did not fulfill these conditions - in the cases where +contribution seemed possible the candidates looked abandoned and long existing CVEs weren't +worked on.

+

Decision

+

Based on the results the decision was made, that the effort is likely to be the same if +we pick up an existing project and try to get it in shape for our use case. It was not +100% clear if this would even be possible or if we still would have to maintain our +own additional patches.

+

So there will be a reference implementation that will match the requirements we have. +In addition there will be an architecture design documentation. So if the reference +implementation may not fit to you, it will be possible to create your own application.

+

Status Page Requirements

+
    +
  • +

    The status page application should be simplistic in software design and should not depend on a large +variety of services

    +
      +
    • simplistic, yet existing user management for write access (oauth? OIDC?) +
        +
      • Simple RBAC (role based access control) is nice to have
      • +
      +
    • +
    • support that components are only visible to a subset of users +
        +
      • implies that there is a role that is read-only
      • +
      • On-Prem use case might be handled by having an authenticating reverse proxy in front
      • +
      +
    • +
    +
  • +
  • +

    The status page applicaton should allow for simple and easy theming

    +
      +
    • Page = (Possibly simple) Web-UI
    • +
    +
  • +
  • +

    As a CSP, I want to have a status page that allows to

    +
      +
    • define locations and similar grouping (AZs, ...)
    • +
    • define components globally or per location +_to ease maintenance I want to define per component where it belongs so that I only have +to define a component once, but have it visible in several locations +_ status per component should be allowed to be toggleable per location or overall * a component should allow for several statuses, that are defined by me
    • +
    +
  • +
  • +

    Status, Status Items should be easy to extract

    +
      +
    • REST(less)-API to interact with +_API should be versioned +_ this allows for embedding status information in other applications, such as cloud +dashboards +_this also allows for submitting items from other tooling +_ incoming webhooks (https POST) should be supported (e.g. for air-gapped setups) – +i.e. submitting a health beacon every x seconds +_web-UI wanted for posting updates as well +_ Token based Auth
    • +
    +
  • +
  • +

    Configuration should be manageable with YAML files (imho this annoys me using Uptime Kuma)

    +
  • +
  • +

    As a consumer of the status page, I'd like to subscribe to events on the status page via e-mail

    +
      +
    • for everything
    • +
    • for specific components
    • +
    +
  • +
  • +

    As a consumer of the status page, I'd like to subscribe to an RSS or atom feed

    +
  • +
  • +

    Allow for the ability to trigger webhooks upon certain events (to submit info to other systems via +webhooks, e.g. chat/messenger)

    +
  • +
  • +

    As a CSP Operator, I want to be able to flag a component with a new status quick and easy

    +
      +
    • to minimize the probability of making errors, updating the status of a component should not be +hard brainwork
    • +
    • updates can be both machine generated status changes (triggered e.g. by health monitoring) +as well as updates from human operators
    • +
    • updating a status should allow the CSP Operator to do that in a fashion that either pushes +infos to the subscribers or just updates the status on the status page
    • +
    • updating the status can either be toggling the status of the component or can be +accompanied by additional textual information.
    • +
    • When updating a status with textual information the status page application should make it +easy for me as the CSP Operator to do in a way that if different people submit infos over time +they are presented in a similar way (eg. the status page application should guide so that the +resulting infos are presented in a identical way. Example: when updating infos of an incident +over time the timeline should automatically be sorted by the status page application so that it +does not depend on the Operator whether the newest info is on top or at the bottom. This is +typical thing that varies if several people update items
    • +
    +
  • +
  • +

    Allow for templates for certain types of incidents

    +
  • +
  • +

    User-specific monitoring (how are MY instances, load-balancers, ... doing?) is OUT OF SCOPE for +the status page.

    +
      +
    • But having it would be useful and if we have something like this, link it from the status page +(and a link to horizon might be the default)
    • +
    +
  • +
  • +

    Sidenote: External hosting is desired to avoid status page going down with infra

    +
  • +
+

With those requirements in mind the projects that initially were found, were evaluated.

+

Comparison matrix

+
CachetHQClearStatusciaocStateGatusIssue Statusstatusfy
CSP VIEW
small dependency tree❌ Composer❌ ruby gems⁇ helm chart❌ npm/github/zapier❌ npm dependencies very huge
easy themable
grouping (by location...)
components definition ...
... local or global
... easy flagging with new status
... push notification on update
... updates with additional information
API Support ...❌ read only✅ GitHub API
... versioned
... web ui for posting updates
... token based auth✅ Auth managed by git provider❌ only basic auth❌ BUT OIDC!
manageable configuration❌ config depends on web server and initial install relies on env variables❌ based on hugo CMS❌ config by env variables❌ based on hugo CMS❌ no real config needed
templating support✅ twig❌ Hugo itself uses GO template libraries
CUSTOMER VIEW
subscription support ...❌ only by git provider
... send by eMail
watchdog for status page support
trigger webhook support❌ needs cachet-monitor
additional infos-basically a theme for hugo cms, depends on netlify cms-basically a theme for hugo cms, depends on netlify cms-It's highly optimized for github pagesSPA created with netlify
hidden components
user management✅ by OIDC⁇ through github?
different output format on notification
external hosting❌ looks like you are limited to github
project healthy❌ last commit 17 months❌ last commit 3 years❌ last commit 5 months✅ last commit 2 months✅ recent activities✅ recent activities❌ archived and abondend by the owner
documentation✅ API ❌ User Documentation⁇u❌ not reachable anymore
git based⁇ a netlify based installation is able to communicate with github
project pageproject pageproject pageproject pageproject pageproject pageproject pageproject page
+ + \ No newline at end of file diff --git a/standards/scs-0401-v1-status-page-reference-implementation-decision/index.html b/standards/scs-0401-v1-status-page-reference-implementation-decision/index.html new file mode 100644 index 0000000000..fd0f46e691 --- /dev/null +++ b/standards/scs-0401-v1-status-page-reference-implementation-decision/index.html @@ -0,0 +1,33 @@ + + + + + +Status page reference implementation decision | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Status page reference implementation decision

Introduction

+

For the reference implementation of the status page API defined by the OpenAPI spec some decision should be made to which technlogy to be used and why.

+

A reference implementation should be of use to most of the intended group, but is not necsessarily applicable for every use case.

+

Motivation

+

For a reference implementation to be of any use, some common and widely used technologies should be used, so it's useful to most of the intended user group.

+

Decision

+

Programming Language

+

The status page application consists of an api server as well as a frontend. For implementing the api server, which is generated from the OpenAPI spec, Go was chosen, because of maturity and wide spread usage as industry standard. Go, in particular, is a modern programming language and is commonly used in network and cloud computing environments.

+

Database

+

As database, PostgreSQL was chosen, since it is a mature, well-known database. PostgreSQL can be run in various environments from small setups to scaled setups. +Furthermore PostgreSQL is a very healthy project with an active community and a solid license. It easily passed the SCS OSS health check.

+ + \ No newline at end of file diff --git a/standards/scs-0402-v1-status-page-openapi-spec-decision/index.html b/standards/scs-0402-v1-status-page-openapi-spec-decision/index.html new file mode 100644 index 0000000000..3392366430 --- /dev/null +++ b/standards/scs-0402-v1-status-page-openapi-spec-decision/index.html @@ -0,0 +1,93 @@ + + + + + +Status page OpenAPI decision | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Status page OpenAPI decision

Introduction

+

While defining the OpenAPI spec some considerations and decisions are made and should be documented.

+

Requirements

+

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

+

In addition, "FORBIDDEN" is to be interpreted equivalent to "MUST NOT".

+

Motivation

+

The spec should be as minimal as possible, while being as understandable as possible, so some choices to the design of API objects, requests and responses are made.

+

Decision

+

Common definitions

+

Some defined schemas are used as common types. These common definitions help to simplify the actual object definitions by providing meaningful names, and reduce duplication. A change of ID type for example only needs one change in the common definition, and not in any of the object definitions which include an ID.

+

Special mentions:

+

Id

+

IDs are used for identification of resources, which can be retrieved by the API.

+

UUIDs are used, to ensure uniqueness. Also, they can be visually recognized as identifier.

+

Incremental

+

An Incremental is used in combination with other identifiers to identify a sub resource of any kind. Incrementals themselves are not globally unique, but unique for every sub resource of an unique resource.

+

Generation and order

+

Generation and Order are predefined objects which include a Incremental typed field for the common usages of the Incremental value.

+

SeverityValue

+

A SeverityValue is an unsiged integer ranging from 0 to 100 inclusively. It MUST be utilized by an Impact when referenced by a requested Component to gauge the severity of the impact on that component. It MUST be added to an Impact when refereced by an Incident, when its created. While being described as an unsiged integer, implementing this value MAY not require it to be an uint data type in any form, because its range even fits in a signed int8 (byte) data type.

+

API objects

+

All objects which are used as payload, either as request or response, are defined by schemas. This centralizes the maintanence of field names and types, for both requests and responses.

+

API object fields

+

Most fields of objects are not required. This allows usage as request and response payloads.

+

Responses of payload objects, which contain an ID or an Incremental typed field, MUST fill the ID or Incremental field to fully identify the (sub) resource.

+

Requests on a single resource MUST contain the ID in the path parameters. Request on sub resources MUST contain the ID and Incremental typed value as path parameters. The payload SHOULD NOT contain the ID or Incremental typed field. +If it contains these fields as payload, they SHALL NOT change them.

+

Requests to updating operations SHOULD contain the minimum of the changed fields, but MAY contain the full object. ID and Incremental typed fields MUST follow the same rules as stated above.

+

Endpoint naming

+

The endpoints are named in plural form, even when handeling single objects, to keep uniform paths.

+

Phase list

+

The list of phases that an incident can go through has a crucial order. So it MUST be handled as the given list.

+

Delete or update operations are FORBIDDEN.

+

To "change" a phase list, a new one must be created. The old one must be kept. For this mechanic the lists are structured in generations. All references to phases MUST include their generation to ensure correct references.

+

To reference a single phase a PhaseReference MUST include a generation and an order field. This MAY be used to reference a single generation too.

+

Labels

+

Labels are identifying metadata to components. They do not represent a resource or sub resource of any kind. They are designed as non system critical pieces of information, mainly intended for human consumption.

+

Labels are simple key/value pairs attached to components, categorizing them dynamically.

+

Impact

+

An impact defines the relation between an incident and a component. A component can be affected by multiple incidents and an incident can affect multiple components. Each of these impacts can have a different type depending on the incident and component, like for example connectivity or performance issues.

+

To reflect this, each component and incident can have a list of impacts, stating the type of impact and a reference to the incident or component, it refers to.

+

Furthermore, a SeverityValue MUST be supplied to the Impact when referenced by a Component, to gauge the impact's severity on that component.

+

Severity

+

A severity contains a name, that MUST be unique and will be used as identifier. The SeverityValue marks the upper boundary of the severity.

+

The severity's value range is calculated by taking the previous severity's (SeverityA) value and adding 1 to obtain the starting point and taking the current severity's (SeverityB) value as the end point. These limits are inclusive.

+
0, ... , SeverityA.value, SeverityA.value, + 1, ... , SeverityB.value - 1, SeverityB.value, SeverityB.value + 1, ... , 100
|<------------range of severity values for SeverityB------------->|
+

Example:

+
[
{
"displayName": "operational",
"value": 25
},
{
"displayName": "maintenance",
"value": 50
},
{
"displayName": "limited",
"value": 75
},
{
"displayName": "broken",
"value": 100
}
]
+

This means:

+
    +
  • operational from 0 to 25
  • +
  • maintenance from 26 to 50
  • +
  • limited from 51 to 75
  • +
  • broken from 76 to 100.
  • +
+

A value of 100 is the maximum of the severity value.

+

A severity with the value of 100 MUST always be supplied. This is the highest severity for the system. If no severity with a value of 100 exists, e.g. the highest severity value is set at 90, an Impact with a higher SeverityValue WILL be considered to be an unkown severity.

+

Component impacts

+

Components list their impacts, which they are affected by, as read only. Only an incident creates an impact on a component. Components MUST only list their currently active impacts.

+

Return of POST requests

+

Generally POST requests create new resources. These endpoints do not return the new resource, but a unique identifier to the resource e.g. an UUID.

+

In most cases the new resource won't be used directly after creation. Most often list calls are used. If the new resource is used directly, it can be retrieved by the returned identifier.

+

Payloads to POST requests SHALL NOT include ID or Incremental typed fields, it lies in the responsibility of the API server to assign IDs and Incrementals to objects.

+

Return of PATCH requestes

+

Most commonly PATCH requests are used to partially or fully change a resource. These requests do not respond with the changed resource, nor an identifier.

+

Both the old state as well as the new state are known on the client at that point in time and if they need to load the actual recent version from the server, the identifier is already known.

+

PATCH vs PUT for updating resources

+

The PUT requests is most commonly used to update full objects, whereas PATCH is used for partial updates.

+

PATCH is used as the default method for updating resources because it does not require the full object for an update, but does not discourage the use of the complete object.

+

Authentication and authorization

+

The API spec does not include either authentication (AuthN) nor authorization (AuthZ) of any kind. The API server MUST be secured by an reverse/auth proxy.

+ + \ No newline at end of file diff --git a/standards/scs-0403-v1-csp-kaas-observability-stack/index.html b/standards/scs-0403-v1-csp-kaas-observability-stack/index.html new file mode 100644 index 0000000000..91a5b7948c --- /dev/null +++ b/standards/scs-0403-v1-csp-kaas-observability-stack/index.html @@ -0,0 +1,210 @@ + + + + + +Architecture for the Cloud Service provider Observability System for the KaaS Layer | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Architecture for the Cloud Service provider Observability System for the KaaS Layer

Introduction

+

Cloud Service Providers offer a variety of products to a customer. Those can include compute resources like virtual machines, networking, and identity and access management. As customers of those services build their applications upon those offered services the service provider needs to ensure a certain quality level of their offerings. This is done by observing the infrastructure. Observability systems leverage different types of telemetry data which include:

+
    +
  1. Metrics: Usually time series data about different parameters of a system which can include e.g. CPU usage, number of active requests, health status, etc.
  2. +
  3. Logs: Messages of software events during runtime
  4. +
  5. Traces: A more developer-oriented form of logging to provide insights into an application or to analyze request flows in distributed systems.
  6. +
+

Based on those data, an alerting system can be used to send out notifications to an Operations Team if a system behaves abnormally. Based on the telemetry data the Operations Team can find the issue, work on it, and mitigate future incidents.

+

Motivation

+

Currently, only the IaaS Layer of the SCS Reference Implementation has an Observability Stack consisting of tools like Prometheus, Grafana, and Alertmanager as well as several Exporters to extract monitoring data from the several OpenStack components and additional software that is involved in the Reference Implementation. As the Kubernetes as a Service Layer becomes more and more important and the work on the Cluster API approach to create customer clusters progresses further, an observability solution for this layer is also needed. CSP should be able to watch over customer clusters and intervene if a cluster gets in a malfunctioning state. For this, a toolset and architecture are needed which is proposed in this ADR.

+

Requirements

+

A survey was conducted to gather the needs and requirements of a CSP when providing Kubernetes as a Service. The feedback of the survey led to the following requirement on a Kubernetes as a Service Observability System:

+
    +
  • Telemetry Data that MUST be fetched: +
      +
    • CPU, RAM, Disk, Network
    • +
    • HTTP Connectivity Metrics
    • +
    • Control Plane and Pod metrics (States, Ready, etc.)
    • +
    • K8s certs metrics
    • +
    • Metrics of underlying node
    • +
    • Logs of control plane, kubelet and containerd
    • +
    +
  • +
  • Telemetry Data that MAY be fetched: +
      +
    • K8s resources (exporters, kubestate metrics, cadvisor, parts of the kubelet)
    • +
    • Ingress controller exporter (http error rate, cert metrics like expiration date)
    • +
    +
  • +
  • Telemetry Data that SHOULD NOT BE fetched: +
      +
    • Any metrics or logs a CSP does not need to provide support with respect to their SLA with a Customer.
    • +
    +
  • +
  • Telemetry Data that MUST NOT be fetched: +
      +
    • Secrets
    • +
    • Customer Specific Workload Metrics
    • +
    +
  • +
  • The Alerting Mechanism MUST include a default ruleset
  • +
  • The Observability Stack MUST run on the CSP Infrastructure
  • +
  • The Observability Stack MUST be High Available
  • +
  • The Observability Stack MUST be able to observe itself
  • +
  • Observed Clusters SHOULD have a low resource impact on the used software to provide telemetry data for the Observability Stack
  • +
+

Options considered

+

Use of the dNation Observability Stack as a base

+

The dNation monitoring stack offers a lot of basic capabilities needed on an observability stack for Kubernetes like Prometheus Operator, Grafana, Alertmanager, Loki, Promtail and Thanos.

+

Pull-based Architecture

+

Each customer cluster has Thanos and Prometheus installed in addition to Thanos and Prometheus on the Observer Cluster. Metrics of a customer cluster are pulled from Thanos (Customer Cluster) for short term queries, as for long term queries the data of all Thanos instances is stored in an external Object Store of the CSP.

+

Push-based Archtitecture

+

Here, Thanos and Prometheus are only used on the CSP side to store and manage all observability data. For the customer clusters only the Prometheus Agent will be used. Prometheus Agent will push all metrics of a Customer Cluster to the central Thanos instance and is preserved in an external Object Store. This introduces less complexity and resource consumption on the customer workload clusters.

+

Scope of the Observability Architecture

+

The Observability Cluster and Architecture SHOULD be defined in a modular way so that it can be used to not only observe the Kubernetes Layer of an SCS Stack, but every aspect of an SCS Stack.

+

Observing the Observability Infrastructure

+

For usage in production, it needs to be possible to observe the Observability Cluster itself.

+

Alerting Rulesets

+

Use a mix of kubernetes-mixin alerts and dNation Alerts Ruleset, as they offer an extensive and well reviewed set of default Alerts covering the important Parts of a Kubernetes Deployment (Nodes, Controlplane, K8s Resources, etc.)

+

Decisions

+
    +
  1. Base the MVP-0 Implementation on the dNation Kubernetes Monitoring Stack.
  2. +
  3. The Push-based Architecture was chosen over the Pull-based Approach.
  4. +
  5. The Observability Stack will be created based on the dNation observability stack
  6. +
  7. The Observability Stack can be used as a standalone component to use with the Kubernetes Layer. It should be possible to observe other parts of an SCS Stack like the status of the OpenStack components, but this will not be mandatory.
  8. +
  9. The Observability Stack should be designed that it is possible to provision two observer clusters side by side, observing each other. To do this is only a recommendation for production usage.
  10. +
  11. The MVP-0 will consist of the following features: +
      +
    • Observability data from KaaS Clusters is scraped +
        +
      • K8s cluster that hosts observer deployment is deployed
      • +
      • S3 compatible bucket as a storage for long term metrics is configured
      • +
      • thanos query-frontend is deployed and configured
      • +
      • thanos query is deployed and configured
      • +
      • thanos reciever is deployed and configured (simple deployment, non HA, without router)
      • +
      • thanos ruler is deployed and configured
      • +
      • thanos compactor is deployed and configured
      • +
      • thanos bucket-web is deployed and configured
      • +
      • thanos storegateway is deployed and configured
      • +
      • prometheus server is deployed and configured
      • +
      • prometheus alertmanager is deployed and configured
      • +
      • prometheus black-box exporter is deployed and configured
      • +
      • kaas-metric-importer is deployed and configured (service aims to differentiate between intentional deletion of KaaS instances and failures in the KaaS monitoring agent)
      • +
      +
    • +
    • Alerts are defined on the KaaS Clusters metrics +
        +
      • all prometheus alerts are working as expected
      • +
      +
    • +
    • There exist Dashboards for KaaS Cluster Health +
        +
      • KaaS L0 dashboard counters are working correctly
      • +
      • Dedicated L0 dashboards are deployed for KaaS and for IaaS monitoring layers
      • +
      +
    • +
    • There exist Dashboards for SCS services endpoinds health (BlackBox exporter)
    • +
    • There exist Dashboards for IaaS layer health
    • +
    • Automatic Setup of Exporters for Observability of managed K8s clusters +
        +
      • KaaS service is mocked
      • +
      • VM that will host a mock of KaaS service is deployed
      • +
      • a script that deploys a multiple KinD clusters and register them in observer is created
      • +
      +
    • +
    • Automatic Setup of Thanos sidecar for Observability of IaaS layer (testbed) +
        +
      • IaaS service is mocked
      • +
      • OSISM testbed is deployed
      • +
      • implement an option to deploy thanos sidecar with some simple config in OSISM testbed
      • +
      +
    • +
    • There exist Dashboards for Harbor Registry Health
    • +
    • Alerts are defined on the Harbor Registry metrics
    • +
    +
  12. +
+

Reference

+

Outcome of the CSP Survey about Requirements for KaaS Observability

+

A survey was conducted to gather the needs and requirements of a CSP when providing Kubernetes as a Service. The results of the Survey (Questions with answers) were the following:

+
    +
  1. +

    What is your understanding of a managed Kubernetes Offering:

    +
      +
    • Hassle-Free Installation and Maintainance (customer viewpoint); Providing Controlplane and worker nodes and responsibility for correct function but agnostic to workload
    • +
    • Day0, 1 and 2 (~planning, provisioning, operations) full lifecyle management or let customer manages some parts of that, depending on customer contract
    • +
    +
  2. +
  3. +

    What Type and Depth of observability is needed

    +
      +
    • CPU, RAM, HDD and Network usage, Health and Function of Cluster Nodes, Controlplane and if desired Customer Workload
    • +
    +
  4. +
  5. +

    Do you have an observabiltiy infrastructure, if yes, how it is built

    + +
  6. +
  7. +

    Data Must haves

    +
      +
    • CPU, RAM, Disk, Network
    • +
    • HTTP Connectivity Metrics
    • +
    • Control Plane and Pod metrics (States, Ready, etc.)
    • +
    • Workload specific metrics
    • +
    • Node Stats
    • +
    • K8s resources (exporters, kubestate metrics, cadvisor, parts of the kubelet)
    • +
    • Ingress controller exporter (http error rate, cert metrics like expiration date)
    • +
    • K8s certs metrics
    • +
    • Metrics of underlying node
    • +
    • Logs of control plane, kubelet and containerd
    • +
    +
  8. +
  9. +

    Must Not haves

    +
      +
    • Secrets, otherwise as much as possible for anomaly detection over long time data
    • +
    +
  10. +
  11. +

    Must have Alerts

    + +
  12. +
  13. +

    Must NOT Alert on

    +
      +
    • Should not wake people, nothing that does not lead to Action items
    • +
    +
  14. +
  15. +

    Observability from Within Or Outside KaaS. How does the architecture look like?

    +
      +
    • Monitoring Infra on CSP Side
    • +
    • Data from Customer Clusters and Mon Infra on CSP and KaaS, get both data. KaaS Monitoring can also be used by customer
    • +
    +
  16. +
  17. +

    Special Constraints

    +
      +
    • HA Setup in different Clusters on Different Sites
    • +
    +
  18. +
+ + \ No newline at end of file diff --git a/standards/scs-0410-v1-gnocchi-as-metering-database/index.html b/standards/scs-0410-v1-gnocchi-as-metering-database/index.html new file mode 100644 index 0000000000..11a7b0dd2c --- /dev/null +++ b/standards/scs-0410-v1-gnocchi-as-metering-database/index.html @@ -0,0 +1,171 @@ + + + + + +Gnocchi as database for metering | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Gnocchi as database for metering

Introduction

+

In the past we noticed missing events in the telemetry stack of OpenStack. +This results in situations where the Cloud Service Provider (CSP) +may think that a resource is still in use while the owner shut it down, +or may not be aware of a resource which has been created.

+

Such inaccurate data is a problem, +when it is supposed to be used for billing purposes.

+

This document discusses how such metering data should be stored +within the SCS. +In partiuclar, +it provides rationale for the choice of Gnocchi +as time-series database for metering data +within SCS.

+

Definitions

+
    +
  • +

    TSDB, time-series database: +Database which is specialised for storing data which is keyed by a timestamp. +Popular examples are InfluxDB, Graphite, rrd, and Prometheus.

    +
  • +
  • +

    Metering: +Collection of usage data of a cloud, +for the specific purpose of creating invoices +to bill customers for the resources they have allocated.

    +
  • +
  • +

    backfilling: +The process of adding and modifying data in the past +within a time-series database.

    +
  • +
  • +

    Metric: +A single time-series vector. +Typically, a metric represents a single property of a resource, +such as CPU usage of an instance.

    +
  • +
  • +

    Resource metrics: +A group of metrics belonging to a single resource. +A compute instance, for instance, +may have a metric indicating the number of CPUs allocated, +another metric indicating the amount of RAM allocated, +etc.

    +
  • +
+

Motivation

+

Being able to hold users accountable +for the resources they use +is a prerequisite for commercially operating a cloud. +The SCS project wants to deliver a cloud stack +which can be used for that purpose, +hence providing reliable metering data is a requirement.

+

As metering data is inherently keyed by time, +a time-series database is required. +The choice of time-series database is an important one +as different databases come with different trade-offs. +Not all databases are suitable for the kind of data +which is collected in a metering context.

+

Design Considerations

+

The following requirements for a time-series database exist:

+
    +
  • +

    MUST support backfilling: +As we need to catch up on changes to resources +which may have happened during a brief network interruption, +we need to be able to modify data after it has been written to the TSDB.

    +
  • +
  • +

    MUST be able to handle lots of resources: +As billing should happen with a resource-level granularity, +we expect a lot of different metrics inside the TSDB.

    +
  • +
  • +

    MUST scale to different timescales: +We expect to have metrics which change frequently (e.g. object store usage) +and metrics which change rarely (e.g. cinder volume sizes). +The TSDB must be able to cope with both types of metrics efficiently.

    +
  • +
  • +

    SHOULD provide an efficient way to query all currently alive resources.

    +
  • +
  • +

    SHOULD allow truncation of storage to remove old data.

    +
  • +
  • +

    MUST be available under an appropriate Open Source license, +even for productive use cases.

    +
  • +
+

Options

+

Using Gnocchi

+

Gnocchi is a time-series database +which has its origins in the OpenStack ecosystem.

+

It supports all requirements except truncation, +which might have to be implemented.

+

Using Prometheus

+

Prometheus is a widely used time-series database +with its focus on monitoring and incident response. +While it is considered efficient for this use-case, +it has shortcomings which make it unsuitable for the metering use case:

+
    +
  • +

    Explicit recommendation against high-cardinality metrics: +As we would have to label metrics by resource IDs and project IDs, +we have to expect a very high cardinality, +also with a significant amount of metric churn.

    +
  • +
  • +

    Backfilling, albeit possible, is not well-supported.

    +
  • +
+

Using InfluxDB

+

InfluxDB is a widely used time-series database +with its focus on monitoring.

+

In contrast to Prometheus, it does support backfilling. +However, like Prometheus, +it seems to run into scalability issues in high-cardinality scenarios.

+

In addition, +clustering is only available in commercial licensing options.

+

Creating a custom TSDB implementation

+

A custom TSDB implementation +is a non-trivial project to pursue.

+

Decision

+

We use Gnocchi. +According to research, +it mostly fulfills the requirements. +While some small development efforts may be needed, +to make it fully usable, +the amount of work is anticipated much less +than making Prometheus or Influx fit the bill +(due to backfilling / cardinality scaling constraints), +let alone rolling a custom implementation.

+

Open questions

+
    +
  • +

    What will be the granularity of the events meta information?

    +

    If we decide to use resource metadata +as a place to store slow-changing information +(e.g. instance flavors, volume sizes), +we need to know what the granularity of that is.

    +
  • +
+ +
    +
  • SCS-0411-v1
  • +
+

Conformance Tests

+

None (this is a decision record).

+ + \ No newline at end of file diff --git a/standards/scs-0411-v1-publishing_method_for_metering_data/index.html b/standards/scs-0411-v1-publishing_method_for_metering_data/index.html new file mode 100644 index 0000000000..4da2b7e350 --- /dev/null +++ b/standards/scs-0411-v1-publishing_method_for_metering_data/index.html @@ -0,0 +1,107 @@ + + + + + +Push-based approach for providing usage data | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Push-based approach for providing usage data

Introduction

+

In the past we noticed missing events in the telemetry stack of OpenStack. +This results in situations where the Cloud Service Provider (CSP) +may think that a resource is still in use while the owner shut it down, +or may not be aware of a resource which has been created.

+

Such inaccurate data is a problem, +when it is supposed to be used for billing purposes.

+

This document discusses how such metering data should be made available +to the cloud service provider +for forwarding into their own billing solution.

+

Definitions

+
    +
  • +

    Push-based flow: +In a push-based flow, +the system generating data actively sends that data to a consumer.

    +
  • +
  • +

    Pull-based flow: +In a pull-based flow, +the system generating data waits for the system consuming the data +to ask for that data.

    +
  • +
  • +

    Metering: +Collection of usage data of a cloud, +for the specific purpose of creating invoices +to bill customers for the resources they have allocated.

    +
  • +
  • +

    Billing: +The entire process of creation, management and sending of invoices +generated from metering data.

    +
  • +
+

Motivation

+

Being able to bill users +for the resources they use +is a prerequisite for commercially operating a cloud. +The SCS project wants to deliver a cloud stack +which can be used for that purpose, +hence providing reliable metering data is a requirement.

+

We generally expect that cloud providers already have +some kind of customer-relation management or billing system in place. +Hence, it is important that the SCS is not too opinionated +on this implementation detail, +but provides a system which can easily interface with other systems.

+

This is similar to how the SCS specified the monitoring stack.

+

Design Considerations

+

The following requirements exist for the process for providing metrics to the cloud service provider:

+
    +
  • MUST scale to different timescales: +We expect to have metrics which change frequently (e.g. object store usage) +and metrics which change rarely (e.g. cinder volume sizes).
  • +
+

Options

+

Push-based flow

+

In a push-based flow, +the to-be-implemented metering system pushes events to the sink +as soon as it is reasonably confident +that the event can be used for billing purposes.

+

Poll-based flow

+

In the poll-based flow, +whichever system the CSP runs would be responsible for polling the metering API +in a frequency sufficient to capture all data with sufficient granularity.

+

Open questions

+
    +
  • What is necessary to extend the availability of sending to various sinks?
  • +
  • How does the configuration look like that is needed to push to a sink from the same type that will be already implemented?
  • +
+

Decision

+

As we need to support very different time scales of data, +the push-based flow is more suitable: +it allows the producer of the data, +which knows about the interval in which it changes, +when to provide new data to the consumer. +In contrast to that, +a poll-based flow would need the consumer to know about change intervals, +or alternatively poll in the highest change frequency ever expected.

+ +
    +
  • SCS-0410-v1
  • +
+

Conformance Tests

+

None (this is a decision record).

+ + \ No newline at end of file diff --git a/standards/scs-0412-v1-metering-json/index.html b/standards/scs-0412-v1-metering-json/index.html new file mode 100644 index 0000000000..4f0812233f --- /dev/null +++ b/standards/scs-0412-v1-metering-json/index.html @@ -0,0 +1,88 @@ + + + + + +Exposition of IaaS metering data as JSON | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Exposition of IaaS metering data as JSON

Introduction

+

The Sovereign Cloud Stack project intends to standardise an infrastructure-as-a-service (IaaS) layer. +In order to economically sustainably run a cloud, +it is generally useful to know which user or tenant consumes which amount of resources in which time frame.

+

Similarly to how the SCS provides an interface for connecting monitoring services to detect outages, +this standard aims for providing an interface for connecting systems which aggregate customer resource usage.

+

Motivation

+

In general, +users of the SCS (i.e. cloud operators) may already have different systems in place +for tracking customer relationships +as well as billing.

+

Those systems are unlikely to have a uniform interface across all possible implementations. +Likewise, those systems are unlikely to have a way to interface with OpenStack, +the reference IaaS layer in SCS.

+

In order to provide SCS operators with a way to integrate the SCS IaaS layer with their billing, +this document shall provide a standard format, +upon which shim conversion layers (to whichever billing system is in place) +can be built.

+

Design Considerations

+

In order to define a standard, +the various options for formats need to be considered. +However, all formats also come with different implementation costs.

+

These aspects are weighed in this section.

+

Options considered

+

Use Ceilometer HTTP hook format

+

The OpenStack Ceilometer project, +which serves as a hub for all things telemetry and metering, +provides an HTTP-based hook to extract metering data. +This hook receives JSON-formatted data.

+

Using this data has the advantage +that we do not need to implement another component to translate the format +which may in turn be a point of failure.

+

Use another format

+

In this option, +a format for metering data is researched and reused, or defined and specified by the SCS project.

+

This option was not explored deeply, for the reasons explained in the decision.

+

Open questions

+

None.

+

Decision

+

We chose the Ceilometer HTTP hook format, described below, for the following reasons:

+
    +
  • +

    Ceilometer is a component which needs to be there anyway for successful metering of OpenStack. Re-using the format makes sense.

    +
  • +
  • +

    Using any other format requires a translation layer. However, users will likely need their own translation layer anyway, to integrate the metering with their own infrastructure. Hence, it makes more sense to expose the data from Ceilometer directly.

    +

    A notable downside of this approach is that a change in Ceilometers format will inevitably cause issues in all downstream consumers.

    +
  • +
+ +
    +
  • SCS-0410-v1
  • +
  • SCS-0411-v1
  • +
+

Conformance Tests

+

None.

+ + \ No newline at end of file diff --git a/standards/scs-XXXX-vN-decision-record-template/index.html b/standards/scs-XXXX-vN-decision-record-template/index.html new file mode 100644 index 0000000000..420db77530 --- /dev/null +++ b/standards/scs-XXXX-vN-decision-record-template/index.html @@ -0,0 +1,36 @@ + + + + + +_Descriptive title_ | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

_Descriptive title_

Abstract

+

Very short introduction about the topic of this document.

+

Terminology

+

Example (abbr. Ex) +This is the description for an example terminology.

+

Context

+

What is the issue that we're seeing that is motivating this decision or change?

+

Decision

+

What is the decision that we're proposing and/or doing? +Should also include reasoning for this decision

+

Consequences

+

What becomes easier or more difficult to do because of this change?

+ +

Related Documents, OPTIONAL

+ + \ No newline at end of file diff --git a/standards/scs-XXXX-vN-standard-template/index.html b/standards/scs-XXXX-vN-standard-template/index.html new file mode 100644 index 0000000000..9b34e7c48c --- /dev/null +++ b/standards/scs-XXXX-vN-standard-template/index.html @@ -0,0 +1,44 @@ + + + + + +_Descriptive title_ | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

_Descriptive title_

Introduction

+

Introduction

+

Terminology

+

Example (abbr. Ex) +This is the description for an example terminology.

+

Motivation

+

Motivation

+

Design Considerations

+

OPTIONAL

+

Options considered

+

Option 1

+

Option 1 description

+

Option 2

+

Option 2 description

+

Open questions

+

RECOMMENDED

+

Standard

+

What is the essence of this standard? Adjust heading accordingly.

+ +

Related Documents, OPTIONAL

+

Conformance Tests

+

Conformance Tests, OPTIONAL

+ + \ No newline at end of file diff --git a/standards/scs-compatible-iaas/index.html b/standards/scs-compatible-iaas/index.html new file mode 100644 index 0000000000..545859ca7d --- /dev/null +++ b/standards/scs-compatible-iaas/index.html @@ -0,0 +1,25 @@ + + + + + +SCS Compatible IaaS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Compatible IaaS

+

Note that the state Stable is shown here if stabilized at is in the future, whereas Effective is shown here if stabilized at is in the past and deprecated at is unset or in the future.

+
Scope versions ->v3v4
StateDeprecatedEffective
Stabilized at2023-06-152024-02-28
Deprecated at2024-04-30
Standards
OpenStack Powered Computev2022.11v2022.11
scs-0100: Flavor namingv3v3
scs-0101: Entropyv1
scs-0102: Image metadatav1v1
scs-0103: Standard flavorsv1
scs-0104: Standard imagesv1
+ + \ No newline at end of file diff --git a/standards/scs-compatible-kaas/index.html b/standards/scs-compatible-kaas/index.html new file mode 100644 index 0000000000..c704e70c79 --- /dev/null +++ b/standards/scs-compatible-kaas/index.html @@ -0,0 +1,25 @@ + + + + + +SCS Compatible KaaS | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

SCS Compatible KaaS

+

Note that the state Stable is shown here if stabilized at is in the future, whereas Effective is shown here if stabilized at is in the past and deprecated at is unset or in the future.

+
Scope versions ->v1v2
StateDraftDraft
Stabilized at
Deprecated at
Standards
CNCF Kubernetes conformance
scs-0210: Kubernetes version policyv2v2
scs-0214: Kubernetes node distribution and availabilityv1v1
+ + \ No newline at end of file diff --git a/standards/standards/overview/index.html b/standards/standards/overview/index.html new file mode 100644 index 0000000000..f4f4a3ba51 --- /dev/null +++ b/standards/standards/overview/index.html @@ -0,0 +1,27 @@ + + + + + +Overview | One platform — standardized, built and operated by many. + + + + + + + + + + + + + + +

Overview

+

Standards are the core deliverable of SCS. By standardizing the open source software components of a cloud computing stack, their versions, how they are to be configured, deployed and utilized, SCS guarantees the reproducibility of a certain behavior of this technology.

+

SCS standards are discussed, developed and maintained in the community by the corresponding teams (see Track in the table below), which naturally include existing users of SCS.

+

*Legend to the column headings: Draft, Stable (but not effective), Effective, Deprecated (and no longer effective).

+
StandardTrackDescriptionDraftStable*EffectiveDeprecated*
scs-0001GlobalSovereign Cloud Standards--v1-
scs-0002GlobalStandards, Docs and Organisationv2-v1-
scs-0003GlobalSovereign Cloud Standards YAMLv1---
scs-0004GlobalRegulations for achieving SCS-compatible certificationv1---
scs-0112GlobalSONiC Support in SCSv1---
scs-0100IaaSSCS Flavor Naming Standard--v3v1, v2
Supplement: Implementation and Testing Notesw1---
scs-0101IaaSSCS Entropy--v1-
Supplement: Implementation and Testing Notesw1---
scs-0102IaaSSCS Image Metadata Standard--v1-
scs-0103IaaSSCS Standard Flavors and Properties--v1-
scs-0104IaaSSCS Standard Images--v1-
scs-0110IaaSSSD Flavors--v1-
scs-0111IaaSDecisions for the Volume Type Standardv1---
scs-0113IaaSSecurity Groups Decision Recordv1---
scs-0114IaaSVolume Type Standardv1---
scs-0115IaaSDefault Rules for Security Groupsv1---
scs-0200KaaSUsing Sonobuoy for KaaS conformance testsv1---
scs-0210KaaSSCS K8S Version Policy--v2v1
scs-0211KaaSSCS KaaS default storage class--v1-
scs-0212KaaSRequirements for container registriesv1---
scs-0213KaaSKubernetes Nodes Anti Affinityv1---
scs-0214KaaSKubernetes Node Distribution and Availability--v1-
scs-0215KaaSRobustness features for Kubernetes clustersv1---
scs-0216KaaSRequirements for testing cluster-stacksv1---
scs-0217KaaSKubernetes cluster baseline securityv1---
scs-0218KaaSContainer registry for SCS standard implementationv1---
scs-0300IAMRequirements for SSO identity federation--v1-
scs-0301IAMNaming for domains/groups/roles/project when onboarding new customersv1---
scs-0302IAMDomain Manager configuration for Keystonev1---
scs-0400OpsStatus Page create decisionv1---
scs-0401OpsStatus page reference implementation decisionv1---
scs-0402OpsStatus page OpenAPI decisionv1---
scs-0403OpsArchitecture for the Cloud Service provider Observability System for the KaaS Layerv1---
scs-0410OpsGnocchi as database for meteringv1---
scs-0411OpsPush-based approach for providing usage datav1---
scs-0412OpsExposition of IaaS metering data as JSONv1---
+ + \ No newline at end of file